appium 2.0.0-beta.2 → 2.0.0-beta.23

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 (122) hide show
  1. package/README.md +9 -9
  2. package/build/check-npm-pack-files.js +23 -0
  3. package/build/commands-yml/parse.js +319 -0
  4. package/build/commands-yml/validator.js +130 -0
  5. package/build/index.js +19 -0
  6. package/build/lib/appium-config.schema.json +0 -0
  7. package/build/lib/appium.js +160 -53
  8. package/build/lib/cli/args.js +115 -279
  9. package/build/lib/cli/driver-command.js +11 -1
  10. package/build/lib/cli/extension-command.js +60 -8
  11. package/build/lib/cli/extension.js +30 -7
  12. package/build/lib/cli/npm.js +43 -29
  13. package/build/lib/cli/parser.js +156 -89
  14. package/build/lib/cli/plugin-command.js +11 -1
  15. package/build/lib/cli/utils.js +29 -3
  16. package/build/lib/config-file.js +141 -0
  17. package/build/lib/config.js +53 -65
  18. package/build/lib/driver-config.js +42 -19
  19. package/build/lib/drivers.js +8 -4
  20. package/build/lib/ext-config-io.js +165 -0
  21. package/build/lib/extension-config.js +130 -61
  22. package/build/lib/grid-register.js +22 -24
  23. package/build/lib/logger.js +3 -3
  24. package/build/lib/logsink.js +11 -13
  25. package/build/lib/main.js +197 -77
  26. package/build/lib/plugin-config.js +21 -11
  27. package/build/lib/plugins.js +4 -2
  28. package/build/lib/schema/appium-config-schema.js +253 -0
  29. package/build/lib/schema/arg-spec.js +120 -0
  30. package/build/lib/schema/cli-args.js +188 -0
  31. package/build/lib/schema/cli-transformers.js +76 -0
  32. package/build/lib/schema/index.js +36 -0
  33. package/build/lib/schema/keywords.js +72 -0
  34. package/build/lib/schema/schema.js +357 -0
  35. package/build/lib/utils.js +44 -99
  36. package/build/postinstall.js +90 -0
  37. package/build/test/cli/cli-e2e-specs.js +221 -0
  38. package/build/test/cli/cli-helpers.js +86 -0
  39. package/build/test/cli/cli-specs.js +71 -0
  40. package/build/test/cli/fixtures/test-driver/package.json +27 -0
  41. package/build/test/cli/schema-args-specs.js +48 -0
  42. package/build/test/cli/schema-e2e-specs.js +47 -0
  43. package/build/test/config-e2e-specs.js +112 -0
  44. package/build/test/config-file-e2e-specs.js +209 -0
  45. package/build/test/config-file-specs.js +281 -0
  46. package/build/test/config-specs.js +159 -0
  47. package/build/test/driver-e2e-specs.js +435 -0
  48. package/build/test/driver-specs.js +321 -0
  49. package/build/test/ext-config-io-specs.js +181 -0
  50. package/build/test/extension-config-specs.js +365 -0
  51. package/build/test/fixtures/allow-feat.txt +5 -0
  52. package/build/test/fixtures/caps.json +3 -0
  53. package/build/test/fixtures/config/allow-insecure.txt +3 -0
  54. package/build/test/fixtures/config/appium.config.bad-nodeconfig.json +5 -0
  55. package/build/test/fixtures/config/appium.config.bad.json +32 -0
  56. package/build/test/fixtures/config/appium.config.ext-good.json +9 -0
  57. package/build/test/fixtures/config/appium.config.ext-unknown-props.json +10 -0
  58. package/build/test/fixtures/config/appium.config.good.js +40 -0
  59. package/build/test/fixtures/config/appium.config.good.json +33 -0
  60. package/build/test/fixtures/config/appium.config.good.yaml +30 -0
  61. package/build/test/fixtures/config/appium.config.invalid.json +31 -0
  62. package/build/test/fixtures/config/appium.config.security-array.json +5 -0
  63. package/build/test/fixtures/config/appium.config.security-delimited.json +5 -0
  64. package/build/test/fixtures/config/appium.config.security-path.json +5 -0
  65. package/build/test/fixtures/config/driver-fake.config.json +8 -0
  66. package/build/test/fixtures/config/nodeconfig.json +3 -0
  67. package/build/test/fixtures/config/plugin-fake.config.json +0 -0
  68. package/build/test/fixtures/default-args.js +35 -0
  69. package/build/test/fixtures/deny-feat.txt +5 -0
  70. package/build/test/fixtures/driver.schema.js +20 -0
  71. package/build/test/fixtures/extensions.yaml +27 -0
  72. package/build/test/fixtures/flattened-schema.js +504 -0
  73. package/build/test/fixtures/plugin.schema.js +20 -0
  74. package/build/test/fixtures/schema-with-extensions.js +28 -0
  75. package/build/test/grid-register-specs.js +74 -0
  76. package/build/test/helpers.js +75 -0
  77. package/build/test/logger-specs.js +76 -0
  78. package/build/test/npm-specs.js +20 -0
  79. package/build/test/parser-specs.js +314 -0
  80. package/build/test/plugin-e2e-specs.js +316 -0
  81. package/build/test/schema/arg-spec-specs.js +70 -0
  82. package/build/test/schema/cli-args-specs.js +431 -0
  83. package/build/test/schema/schema-specs.js +389 -0
  84. package/build/test/utils-specs.js +266 -0
  85. package/index.js +11 -0
  86. package/lib/appium-config.schema.json +278 -0
  87. package/lib/appium.js +207 -65
  88. package/lib/cli/args.js +174 -375
  89. package/lib/cli/driver-command.js +4 -0
  90. package/lib/cli/extension-command.js +70 -5
  91. package/lib/cli/extension.js +25 -5
  92. package/lib/cli/npm.js +86 -18
  93. package/lib/cli/parser.js +257 -79
  94. package/lib/cli/plugin-command.js +4 -0
  95. package/lib/cli/utils.js +21 -1
  96. package/lib/config-file.js +227 -0
  97. package/lib/config.js +84 -63
  98. package/lib/driver-config.js +66 -11
  99. package/lib/drivers.js +4 -1
  100. package/lib/ext-config-io.js +287 -0
  101. package/lib/extension-config.js +225 -67
  102. package/lib/grid-register.js +27 -24
  103. package/lib/logger.js +1 -1
  104. package/lib/logsink.js +10 -7
  105. package/lib/main.js +214 -77
  106. package/lib/plugin-config.js +35 -6
  107. package/lib/plugins.js +1 -0
  108. package/lib/schema/appium-config-schema.js +287 -0
  109. package/lib/schema/arg-spec.js +222 -0
  110. package/lib/schema/cli-args.js +285 -0
  111. package/lib/schema/cli-transformers.js +123 -0
  112. package/lib/schema/index.js +2 -0
  113. package/lib/schema/keywords.js +135 -0
  114. package/lib/schema/schema.js +577 -0
  115. package/lib/utils.js +42 -88
  116. package/package.json +55 -84
  117. package/postinstall.js +71 -0
  118. package/types/appium-config.d.ts +197 -0
  119. package/types/types.d.ts +201 -0
  120. package/CHANGELOG.md +0 -3515
  121. package/build/lib/cli/parser-helpers.js +0 -82
  122. package/lib/cli/parser-helpers.js +0 -79
@@ -0,0 +1,365 @@
1
+ "use strict";
2
+
3
+ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
4
+
5
+ require("source-map-support/register");
6
+
7
+ var _path = _interopRequireDefault(require("path"));
8
+
9
+ var _node = _interopRequireDefault(require("rewiremock/node"));
10
+
11
+ var _sinon = _interopRequireDefault(require("sinon"));
12
+
13
+ const expect = chai.expect;
14
+ describe('ExtensionConfig', function () {
15
+ describe('getGenericConfigProblems()', function () {
16
+ it('should have some tests');
17
+ });
18
+ describe('DriverConfig', function () {
19
+ let DriverConfig;
20
+ let mocks;
21
+ let sandbox;
22
+ beforeEach(function () {
23
+ mocks = {
24
+ 'resolve-from': _sinon.default.stub().callsFake((cwd, id) => _path.default.join(cwd, id))
25
+ };
26
+ DriverConfig = _node.default.proxy(() => require('../lib/driver-config'), mocks).default;
27
+ sandbox = _sinon.default.createSandbox();
28
+ });
29
+ afterEach(function () {
30
+ sandbox.restore();
31
+ });
32
+ describe('extensionDesc()', function () {
33
+ it('should return the description of the extension', function () {
34
+ const config = DriverConfig.getInstance('/tmp/');
35
+ config.extensionDesc('foo', {
36
+ version: '1.0',
37
+ automationName: 'bar'
38
+ }).should.equal(`foo@1.0 (automationName 'bar')`);
39
+ });
40
+ });
41
+ describe('getConfigProblems()', function () {
42
+ let driverConfig;
43
+ beforeEach(function () {
44
+ driverConfig = DriverConfig.getInstance('/tmp/');
45
+ });
46
+ describe('when provided no arguments', function () {
47
+ it('should throw', function () {
48
+ (() => driverConfig.getConfigProblems()).should.throw();
49
+ });
50
+ });
51
+ describe('property `platformNames`', function () {
52
+ describe('when provided an object with no `platformNames` property', function () {
53
+ it('should return an array with an associated problem', function () {
54
+ driverConfig.getConfigProblems({}, 'foo').should.deep.include({
55
+ err: 'Missing or incorrect supported platformNames list.',
56
+ val: undefined
57
+ });
58
+ });
59
+ });
60
+ describe('when provided an object with an empty `platformNames` property', function () {
61
+ it('should return an array with an associated problem', function () {
62
+ driverConfig.getConfigProblems({
63
+ platformNames: []
64
+ }, 'foo').should.deep.include({
65
+ err: 'Empty platformNames list.',
66
+ val: []
67
+ });
68
+ });
69
+ });
70
+ describe('when provided an object with a non-array `platformNames` property', function () {
71
+ it('should return an array with an associated problem', function () {
72
+ driverConfig.getConfigProblems({
73
+ platformNames: 'foo'
74
+ }, 'foo').should.deep.include({
75
+ err: 'Missing or incorrect supported platformNames list.',
76
+ val: 'foo'
77
+ });
78
+ });
79
+ });
80
+ describe('when provided a non-empty array containing a non-string item', function () {
81
+ it('should return an array with an associated problem', function () {
82
+ driverConfig.getConfigProblems({
83
+ platformNames: ['a', 1]
84
+ }, 'foo').should.deep.include({
85
+ err: 'Incorrectly formatted platformName.',
86
+ val: 1
87
+ });
88
+ });
89
+ });
90
+ });
91
+ describe('property `automationName`', function () {
92
+ describe('when provided an object with a missing `automationName` property', function () {
93
+ it('should return an array with an associated problem', function () {
94
+ driverConfig.getConfigProblems({}, 'foo').should.deep.include({
95
+ err: 'Missing or incorrect automationName',
96
+ val: undefined
97
+ });
98
+ });
99
+ });
100
+ describe('when provided a conflicting automationName', function () {
101
+ it('should return an array with an associated problem', function () {
102
+ driverConfig.getConfigProblems({
103
+ automationName: 'foo'
104
+ }, 'foo');
105
+ driverConfig.getConfigProblems({
106
+ automationName: 'foo'
107
+ }, 'foo').should.deep.include({
108
+ err: 'Multiple drivers claim support for the same automationName',
109
+ val: 'foo'
110
+ });
111
+ });
112
+ });
113
+ });
114
+ });
115
+ describe('getSchemaProblems()', function () {
116
+ let driverConfig;
117
+ beforeEach(function () {
118
+ driverConfig = DriverConfig.getInstance('/tmp/');
119
+ });
120
+ describe('when provided an object with a defined non-string `schema` property', function () {
121
+ it('should return an array with an associated problem', function () {
122
+ driverConfig.getSchemaProblems({
123
+ schema: []
124
+ }, 'foo').should.deep.include({
125
+ err: 'Incorrectly formatted schema field; must be a path to a schema file or a schema object.',
126
+ val: []
127
+ });
128
+ });
129
+ });
130
+ describe('when provided a string `schema` property', function () {
131
+ describe('when the property ends in an unsupported extension', function () {
132
+ it('should return an array with an associated problem', function () {
133
+ driverConfig.getSchemaProblems({
134
+ schema: 'selenium.java'
135
+ }, 'foo').should.deep.include({
136
+ err: 'Schema file has unsupported extension. Allowed: .json, .js, .cjs',
137
+ val: 'selenium.java'
138
+ });
139
+ });
140
+ });
141
+ describe('when the property contains a supported extension', function () {
142
+ describe('when the property as a path cannot be found', function () {
143
+ it('should return an array with an associated problem', function () {
144
+ const problems = driverConfig.getSchemaProblems({
145
+ installPath: '/usr/bin/derp',
146
+ pkgName: 'doop',
147
+ schema: 'herp.json'
148
+ }, 'foo');
149
+ problems[0].err.should.match(/Unable to register schema at path herp\.json/i);
150
+ });
151
+ });
152
+ describe('when the property as a path is found', function () {
153
+ it('should return an empty array', function () {
154
+ const problems = driverConfig.getSchemaProblems({
155
+ pkgName: 'fixtures',
156
+ installPath: __dirname,
157
+ schema: 'driver.schema.js'
158
+ }, 'foo');
159
+ problems.should.be.empty;
160
+ });
161
+ });
162
+ });
163
+ });
164
+ });
165
+ describe('read()', function () {
166
+ let driverConfig;
167
+ beforeEach(function () {
168
+ driverConfig = DriverConfig.getInstance('/tmp/');
169
+ sandbox.spy(driverConfig, 'validate');
170
+ });
171
+ it('should validate the extension', async function () {
172
+ await driverConfig.read();
173
+ driverConfig.validate.should.have.been.calledOnce;
174
+ });
175
+ });
176
+ describe('readExtensionSchema()', function () {
177
+ let driverConfig;
178
+ let extData;
179
+ const extName = 'stuff';
180
+ beforeEach(function () {
181
+ extData = {
182
+ installPath: 'fixtures',
183
+ pkgName: 'some-pkg',
184
+ schema: 'driver.schema.js'
185
+ };
186
+ mocks['resolve-from'].returns(require.resolve('./fixtures/driver.schema.js'));
187
+ driverConfig = DriverConfig.getInstance('/tmp/');
188
+ });
189
+ describe('when the extension data is missing `schema`', function () {
190
+ it('should throw', function () {
191
+ delete extData.schema;
192
+ expect(() => driverConfig.readExtensionSchema(extName, extData)).to.throw(TypeError, /why is this function being called/i);
193
+ });
194
+ });
195
+ describe('when the extension schema has already been registered (with the same schema)', function () {
196
+ it('should not throw', function () {
197
+ driverConfig.readExtensionSchema(extName, extData);
198
+ expect(() => driverConfig.readExtensionSchema(extName, extData)).not.to.throw();
199
+ });
200
+ });
201
+ describe('when the extension schema has not yet been registered', function () {
202
+ it('should resolve and load the extension schema file', function () {
203
+ driverConfig.readExtensionSchema(extName, extData);
204
+ expect(mocks['resolve-from']).to.have.been.calledOnce;
205
+ });
206
+ });
207
+ });
208
+ });
209
+ describe('PluginConfig', function () {
210
+ let PluginConfig;
211
+ let mocks;
212
+ let sandbox;
213
+ beforeEach(function () {
214
+ mocks = {
215
+ 'resolve-from': _sinon.default.stub().callsFake((cwd, id) => _path.default.join(cwd, id))
216
+ };
217
+ PluginConfig = _node.default.proxy(() => require('../lib/plugin-config'), mocks).default;
218
+ sandbox = _sinon.default.createSandbox();
219
+ });
220
+ afterEach(function () {
221
+ sandbox.restore();
222
+ });
223
+ describe('extensionDesc()', function () {
224
+ it('should return the description of the extension', function () {
225
+ const config = PluginConfig.getInstance('/tmp/');
226
+ config.extensionDesc('foo', {
227
+ version: '1.0'
228
+ }).should.equal(`foo@1.0`);
229
+ });
230
+ });
231
+ describe('getConfigProblems()', function () {
232
+ let pluginConfig;
233
+ beforeEach(function () {
234
+ pluginConfig = PluginConfig.getInstance('/tmp/');
235
+ });
236
+ describe('when provided no arguments', function () {
237
+ it('should not throw', function () {
238
+ (() => pluginConfig.getConfigProblems()).should.not.throw();
239
+ });
240
+ });
241
+ });
242
+ describe('getSchemaProblems()', function () {
243
+ let pluginConfig;
244
+ beforeEach(function () {
245
+ pluginConfig = PluginConfig.getInstance('/tmp/');
246
+ });
247
+ describe('when provided an object with a defined `schema` property of unsupported type', function () {
248
+ it('should return an array with an associated problem', function () {
249
+ pluginConfig.getSchemaProblems({
250
+ schema: []
251
+ }, 'foo').should.deep.include({
252
+ err: 'Incorrectly formatted schema field; must be a path to a schema file or a schema object.',
253
+ val: []
254
+ });
255
+ });
256
+ });
257
+ describe('when provided a string `schema` property', function () {
258
+ describe('when the property ends in an unsupported extension', function () {
259
+ it('should return an array with an associated problem', function () {
260
+ pluginConfig.getSchemaProblems({
261
+ schema: 'selenium.java'
262
+ }, 'foo').should.deep.include({
263
+ err: 'Schema file has unsupported extension. Allowed: .json, .js, .cjs',
264
+ val: 'selenium.java'
265
+ });
266
+ });
267
+ });
268
+ describe('when the property contains a supported extension', function () {
269
+ describe('when the property as a path cannot be found', function () {
270
+ it('should return an array with an associated problem', function () {
271
+ const problems = pluginConfig.getSchemaProblems({
272
+ installPath: '/usr/bin/derp',
273
+ pkgName: 'doop',
274
+ schema: 'herp.json'
275
+ }, 'foo');
276
+ problems[0].err.should.match(/Unable to register schema at path herp\.json/i);
277
+ });
278
+ });
279
+ describe('when the property as a path is found', function () {
280
+ it('should return an empty array', function () {
281
+ const problems = pluginConfig.getSchemaProblems({
282
+ pkgName: 'fixtures',
283
+ installPath: __dirname,
284
+ schema: 'plugin.schema.js'
285
+ }, 'foo');
286
+ problems.should.be.empty;
287
+ });
288
+ });
289
+ });
290
+ });
291
+ describe('when provided an object `schema` property', function () {
292
+ it('should return an empty array', function () {
293
+ const problems = pluginConfig.getSchemaProblems({
294
+ pkgName: 'fixtures',
295
+ installPath: __dirname,
296
+ schema: {
297
+ type: 'object',
298
+ properties: {
299
+ foo: {
300
+ type: 'string'
301
+ }
302
+ }
303
+ }
304
+ }, 'foo');
305
+ problems.should.be.empty;
306
+ });
307
+ });
308
+ });
309
+ describe('read()', function () {
310
+ let pluginConfig;
311
+ beforeEach(function () {
312
+ pluginConfig = PluginConfig.getInstance('/tmp/');
313
+ sandbox.spy(pluginConfig, 'validate');
314
+ });
315
+ it('should validate the extension', async function () {
316
+ await pluginConfig.read();
317
+ pluginConfig.validate.should.have.been.calledOnce;
318
+ });
319
+ });
320
+ describe('readExtensionSchema()', function () {
321
+ let pluginConfig;
322
+ let extData;
323
+ const extName = 'stuff';
324
+ beforeEach(function () {
325
+ extData = {
326
+ installPath: 'fixtures',
327
+ pkgName: 'some-pkg',
328
+ schema: 'plugin.schema.js'
329
+ };
330
+ mocks['resolve-from'].returns(require.resolve('./fixtures/plugin.schema.js'));
331
+ pluginConfig = PluginConfig.getInstance('/tmp/');
332
+ });
333
+ describe('when the extension data is missing `schema`', function () {
334
+ it('should throw', function () {
335
+ delete extData.schema;
336
+ expect(() => pluginConfig.readExtensionSchema(extName, extData)).to.throw(TypeError, /why is this function being called/i);
337
+ });
338
+ });
339
+ describe('when the extension schema has already been registered', function () {
340
+ describe('when the schema is identical (presumably the same extension)', function () {
341
+ it('should not throw', function () {
342
+ pluginConfig.readExtensionSchema(extName, extData);
343
+ expect(() => pluginConfig.readExtensionSchema(extName, extData)).not.to.throw();
344
+ });
345
+ });
346
+ describe('when the schema differs (presumably a different extension)', function () {
347
+ it('should throw', function () {
348
+ pluginConfig.readExtensionSchema(extName, extData);
349
+ mocks['resolve-from'].returns(require.resolve('./fixtures/driver.schema.js'));
350
+ expect(() => pluginConfig.readExtensionSchema(extName, extData)).to.throw(/conflicts with an existing schema/i);
351
+ });
352
+ });
353
+ });
354
+ describe('when the extension schema has not yet been registered', function () {
355
+ it('should resolve and load the extension schema file', function () {
356
+ pluginConfig.readExtensionSchema(extName, extData);
357
+ expect(mocks['resolve-from']).to.have.been.calledOnce;
358
+ });
359
+ });
360
+ });
361
+ });
362
+ });require('source-map-support').install();
363
+
364
+
365
+ //# sourceMappingURL=data:application/json;charset=utf8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbInRlc3QvZXh0ZW5zaW9uLWNvbmZpZy1zcGVjcy5qcyJdLCJuYW1lcyI6WyJleHBlY3QiLCJjaGFpIiwiZGVzY3JpYmUiLCJpdCIsIkRyaXZlckNvbmZpZyIsIm1vY2tzIiwic2FuZGJveCIsImJlZm9yZUVhY2giLCJzaW5vbiIsInN0dWIiLCJjYWxsc0Zha2UiLCJjd2QiLCJpZCIsInBhdGgiLCJqb2luIiwicmV3aXJlbW9jayIsInByb3h5IiwicmVxdWlyZSIsImRlZmF1bHQiLCJjcmVhdGVTYW5kYm94IiwiYWZ0ZXJFYWNoIiwicmVzdG9yZSIsImNvbmZpZyIsImdldEluc3RhbmNlIiwiZXh0ZW5zaW9uRGVzYyIsInZlcnNpb24iLCJhdXRvbWF0aW9uTmFtZSIsInNob3VsZCIsImVxdWFsIiwiZHJpdmVyQ29uZmlnIiwiZ2V0Q29uZmlnUHJvYmxlbXMiLCJ0aHJvdyIsImRlZXAiLCJpbmNsdWRlIiwiZXJyIiwidmFsIiwidW5kZWZpbmVkIiwicGxhdGZvcm1OYW1lcyIsImdldFNjaGVtYVByb2JsZW1zIiwic2NoZW1hIiwicHJvYmxlbXMiLCJpbnN0YWxsUGF0aCIsInBrZ05hbWUiLCJtYXRjaCIsIl9fZGlybmFtZSIsImJlIiwiZW1wdHkiLCJzcHkiLCJyZWFkIiwidmFsaWRhdGUiLCJoYXZlIiwiYmVlbiIsImNhbGxlZE9uY2UiLCJleHREYXRhIiwiZXh0TmFtZSIsInJldHVybnMiLCJyZXNvbHZlIiwicmVhZEV4dGVuc2lvblNjaGVtYSIsInRvIiwiVHlwZUVycm9yIiwibm90IiwiUGx1Z2luQ29uZmlnIiwicGx1Z2luQ29uZmlnIiwidHlwZSIsInByb3BlcnRpZXMiLCJmb28iXSwibWFwcGluZ3MiOiI7Ozs7OztBQUVBOztBQUNBOztBQUNBOztBQUVBLE1BQU1BLE1BQU0sR0FBR0MsSUFBSSxDQUFDRCxNQUFwQjtBQUVBRSxRQUFRLENBQUMsaUJBQUQsRUFBb0IsWUFBWTtBQUN0Q0EsRUFBQUEsUUFBUSxDQUFDLDRCQUFELEVBQStCLFlBQVk7QUFD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QUFyRSxDQUF3RTNCLEtBQXhFO0FBQ0QsV0FIQyxDQUFGO0FBSUQsU0FMTyxDQUFSO0FBT0E3QixRQUFBQSxRQUFRLENBQUMsNERBQUQsRUFBK0QsWUFBWTtBQUNqRkMsVUFBQUEsRUFBRSxDQUFDLGNBQUQsRUFBaUIsWUFBWTtBQUM3QjJELFlBQUFBLFlBQVksQ0FBQ0wsbUJBQWIsQ0FBaUNILE9BQWpDLEVBQTBDRCxPQUExQztBQUNBaEQsWUFBQUEsS0FBSyxDQUFDLGNBQUQsQ0FBTCxDQUFzQmtELE9BQXRCLENBQThCdEMsT0FBTyxDQUFDdUMsT0FBUixDQUFnQiw2QkFBaEIsQ0FBOUI7QUFDQXhELFlBQUFBLE1BQU0sQ0FBQyxNQUFNOEQsWUFBWSxDQUFDTCxtQkFBYixDQUFpQ0gsT0FBakMsRUFBMENELE9BQTFDLENBQVAsQ0FBTixDQUFpRUssRUFBakUsQ0FBb0UzQixLQUFwRSxDQUEwRSxvQ0FBMUU7QUFDRCxXQUpDLENBQUY7QUFLRCxTQU5PLENBQVI7QUFPRCxPQWZPLENBQVI7QUFpQkE3QixNQUFBQSxRQUFRLENBQUMsdURBQUQsRUFBMEQsWUFBWTtBQUM1RUMsUUFBQUEsRUFBRSxDQUFDLG1EQUFELEVBQXNELFlBQVk7QUFDbEUyRCxVQUFBQSxZQUFZLENBQUNMLG1CQUFiLENBQWlDSCxPQUFqQyxFQUEwQ0QsT0FBMUM7QUFHQXJELFVBQUFBLE1BQU0sQ0FBQ0ssS0FBSyxDQUFDLGNBQUQsQ0FBTixDQUFOLENBQThCcUQsRUFBOUIsQ0FBaUNSLElBQWpDLENBQXNDQyxJQUF0QyxDQUEyQ0MsVUFBM0M7QUFDRCxTQUxDLENBQUY7QUFNRCxPQVBPLENBQVI7QUFRRCxLQTFETyxDQUFSO0FBMkRELEdBL01PLENBQVI7QUFnTkQsQ0FsZE8sQ0FBUiIsInNvdXJjZXNDb250ZW50IjpbIi8vIEB0cy1jaGVja1xuXG5pbXBvcnQgcGF0aCBmcm9tICdwYXRoJztcbmltcG9ydCByZXdpcmVtb2NrIGZyb20gJ3Jld2lyZW1vY2svbm9kZSc7XG5pbXBvcnQgc2lub24gZnJvbSAnc2lub24nO1xuXG5jb25zdCBleHBlY3QgPSBjaGFpLmV4cGVjdDtcblxuZGVzY3JpYmUoJ0V4dGVuc2lvbkNvbmZpZycsIGZ1bmN0aW9uICgpIHtcbiAgZGVzY3JpYmUoJ2dldEdlbmVyaWNDb25maWdQcm9ibGVtcygpJywgZnVuY3Rpb24gKCkge1xuICAgIGl0KCdzaG91bGQgaGF2ZSBzb21lIHRlc3RzJyk7XG4gIH0pO1xuXG4gIGRlc2NyaWJlKCdEcml2ZXJDb25maWcnLCBmdW5jdGlvbiAoKSB7XG4gICAgLyoqXG4gICAgICogQHR5cGUge3R5cGVvZiBpbXBvcnQoJy4uL2xpYi9kcml2ZXItY29uZmlnJykuZGVmYXVsdH1cbiAgICAgKi9cbiAgICBsZXQgRHJpdmVyQ29uZmlnO1xuICAgIGxldCBtb2NrcztcbiAgICAvKiogQHR5cGUge2ltcG9ydCgnc2lub24nKS5TaW5vblNhbmRib3h9ICovXG4gICAgbGV0IHNhbmRib3g7XG4gICAgYmVmb3JlRWFjaChmdW5jdGlvbiAoKSB7XG4gICAgICBtb2NrcyA9IHtcbiAgICAgICAgJ3Jlc29sdmUtZnJvbSc6IHNpbm9uLnN0dWIoKS5jYWxsc0Zha2UoKGN3ZCwgaWQpID0+IHBhdGguam9pbihjd2QsIGlkKSksXG4gICAgICB9O1xuXG4gICAgICBEcml2ZXJDb25maWcgPSByZXdpcmVtb2NrLnByb3h5KFxuICAgICAgICAoKSA9PiByZXF1aXJlKCcuLi9saWIvZHJpdmVyLWNvbmZpZycpLFxuICAgICAgICBtb2NrcyxcbiAgICAgICkuZGVmYXVsdDtcblxuICAgICAgc2FuZGJveCA9IHNpbm9uLmNyZWF0ZVNhbmRib3goKTtcbiAgICB9KTtcblxuICAgIGFmdGVyRWFjaChmdW5jdGlvbiAoKSB7XG4gICAgICBzYW5kYm94LnJlc3RvcmUoKTtcbiAgICB9KTtcblxuICAgIGRlc2NyaWJlKCdleHRlbnNpb25EZXNjKCknLCBmdW5jdGlvbiAoKSB7XG4gICAgICBpdCgnc2hvdWxkIHJldHVybiB0aGUgZGVzY3JpcHRpb24gb2YgdGhlIGV4dGVuc2lvbicsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgY29uc3QgY29uZmlnID0gRHJpdmVyQ29uZmlnLmdldEluc3RhbmNlKCcvdG1wLycpO1xuICAgICAgICBjb25maWdcbiAgICAgICAgICAuZXh0ZW5zaW9uRGVzYygnZm9vJywge3ZlcnNpb246ICcxLjAnLCBhdXRvbWF0aW9uTmFtZTogJ2Jhcid9KVxuICAgICAgICAgIC5zaG91bGQuZXF1YWwoYGZvb0AxLjAgKGF1dG9tYXRpb25OYW1lICdiYXInKWApO1xuICAgICAgfSk7XG4gICAgfSk7XG5cbiAgICBkZXNjcmliZSgnZ2V0Q29uZmlnUHJvYmxlbXMoKScsIGZ1bmN0aW9uICgpIHtcbiAgICAgIC8qKlxuICAgICAgICogQHR5cGUge1JldHVyblR5cGU8RHJpdmVyQ29uZmlnWydnZXRJbnN0YW5jZSddPn1cbiAgICAgICAqL1xuICAgICAgbGV0IGRyaXZlckNvbmZpZztcblxuICAgICAgYmVmb3JlRWFjaChmdW5jdGlvbiAoKSB7XG4gICAgICAgIGRyaXZlckNvbmZpZyA9IERyaXZlckNvbmZpZy5nZXRJbnN0YW5jZSgnL3RtcC8nKTtcbiAgICAgIH0pO1xuXG4gICAgICBkZXNjcmliZSgnd2hlbiBwcm92aWRlZCBubyBhcmd1bWVudHMnLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGl0KCdzaG91bGQgdGhyb3cnLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgLy8gQHRzLWlnbm9yZVxuICAgICAgICAgICgoKSA9PiBkcml2ZXJDb25maWcuZ2V0Q29uZmlnUHJvYmxlbXMoKSkuc2hvdWxkLnRocm93KCk7XG4gICAgICAgIH0pO1xuICAgICAgfSk7XG5cbiAgICAgIGRlc2NyaWJlKCdwcm9wZXJ0eSBgcGxhdGZvcm1OYW1lc2AnLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGRlc2NyaWJlKCd3aGVuIHByb3ZpZGVkIGFuIG9iamVjdCB3aXRoIG5vIGBwbGF0Zm9ybU5hbWVzYCBwcm9wZXJ0eScsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICBpdCgnc2hvdWxkIHJldHVybiBhbiBhcnJheSB3aXRoIGFuIGFzc29jaWF0ZWQgcHJvYmxlbScsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIGRyaXZlckNvbmZpZy5nZXRDb25maWdQcm9ibGVtcyh7fSwgJ2ZvbycpLnNob3VsZC5kZWVwLmluY2x1ZGUoe1xuICAgICAgICAgICAgICBlcnI6ICdNaXNzaW5nIG9yIGluY29ycmVjdCBzdXBwb3J0ZWQgcGxhdGZvcm1OYW1lcyBsaXN0LicsXG4gICAgICAgICAgICAgIHZhbDogdW5kZWZpbmVkLFxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgfSk7XG4gICAgICAgIH0pO1xuXG4gICAgICAgIGRlc2NyaWJlKCd3aGVuIHByb3ZpZGVkIGFuIG9iamVjdCB3aXRoIGFuIGVtcHR5IGBwbGF0Zm9ybU5hbWVzYCBwcm9wZXJ0eScsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICBpdCgnc2hvdWxkIHJldHVybiBhbiBhcnJheSB3aXRoIGFuIGFzc29jaWF0ZWQgcHJvYmxlbScsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIGRyaXZlckNvbmZpZ1xuICAgICAgICAgICAgICAuZ2V0Q29uZmlnUHJvYmxlbXMoe3BsYXRmb3JtTmFtZXM6IFtdfSwgJ2ZvbycpXG4gICAgICAgICAgICAgIC5zaG91bGQuZGVlcC5pbmNsdWRlKHtcbiAgICAgICAgICAgICAgICBlcnI6ICdFbXB0eSBwbGF0Zm9ybU5hbWVzIGxpc3QuJyxcbiAgICAgICAgICAgICAgICB2YWw6IFtdLFxuICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICB9KTtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgZGVzY3JpYmUoJ3doZW4gcHJvdmlkZWQgYW4gb2JqZWN0IHdpdGggYSBub24tYXJyYXkgYHBsYXRmb3JtTmFtZXNgIHByb3BlcnR5JywgZnVuY3Rpb24gKCkge1xuICAgICAgICAgIGl0KCdzaG91bGQgcmV0dXJuIGFuIGFycmF5IHdpdGggYW4gYXNzb2NpYXRlZCBwcm9ibGVtJywgZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgZHJpdmVyQ29uZmlnXG4gICAgICAgICAgICAgIC5nZXRDb25maWdQcm9ibGVtcyh7cGxhdGZvcm1OYW1lczogJ2Zvbyd9LCAnZm9vJylcbiAgICAgICAgICAgICAgLnNob3VsZC5kZWVwLmluY2x1ZGUoe1xuICAgICAgICAgICAgICAgIGVycjogJ01pc3Npbmcgb3IgaW5jb3JyZWN0IHN1cHBvcnRlZCBwbGF0Zm9ybU5hbWVzIGxpc3QuJyxcbiAgICAgICAgICAgICAgICB2YWw6ICdmb28nLFxuICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICB9KTtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgZGVzY3JpYmUoJ3doZW4gcHJvdmlkZWQgYSBub24tZW1wdHkgYXJyYXkgY29udGFpbmluZyBhIG5vbi1zdHJpbmcgaXRlbScsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICBpdCgnc2hvdWxkIHJldHVybiBhbiBhcnJheSB3aXRoIGFuIGFzc29jaWF0ZWQgcHJvYmxlbScsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIGRyaXZlckNvbmZpZ1xuICAgICAgICAgICAgICAuZ2V0Q29uZmlnUHJvYmxlbXMoe3BsYXRmb3JtTmFtZXM6IFsnYScsIDFdfSwgJ2ZvbycpXG4gICAgICAgICAgICAgIC5zaG91bGQuZGVlcC5pbmNsdWRlKHtcbiAgICAgICAgICAgICAgICBlcnI6ICdJbmNvcnJlY3RseSBmb3JtYXR0ZWQgcGxhdGZvcm1OYW1lLicsXG4gICAgICAgICAgICAgICAgdmFsOiAxLFxuICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICB9KTtcbiAgICAgICAgfSk7XG4gICAgICB9KTtcblxuICAgICAgZGVzY3JpYmUoJ3Byb3BlcnR5IGBhdXRvbWF0aW9uTmFtZWAnLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGRlc2NyaWJlKCd3aGVuIHByb3ZpZGVkIGFuIG9iamVjdCB3aXRoIGEgbWlzc2luZyBgYXV0b21hdGlvbk5hbWVgIHByb3BlcnR5JywgZnVuY3Rpb24gKCkge1xuICAgICAgICAgIGl0KCdzaG91bGQgcmV0dXJuIGFuIGFycmF5IHdpdGggYW4gYXNzb2NpYXRlZCBwcm9ibGVtJywgZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgZHJpdmVyQ29uZmlnLmdldENvbmZpZ1Byb2JsZW1zKHt9LCAnZm9vJykuc2hvdWxkLmRlZXAuaW5jbHVkZSh7XG4gICAgICAgICAgICAgIGVycjogJ01pc3Npbmcgb3IgaW5jb3JyZWN0IGF1dG9tYXRpb25OYW1lJyxcbiAgICAgICAgICAgICAgdmFsOiB1bmRlZmluZWQsXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICB9KTtcbiAgICAgICAgfSk7XG4gICAgICAgIGRlc2NyaWJlKCd3aGVuIHByb3ZpZGVkIGEgY29uZmxpY3RpbmcgYXV0b21hdGlvbk5hbWUnLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgaXQoJ3Nob3VsZCByZXR1cm4gYW4gYXJyYXkgd2l0aCBhbiBhc3NvY2lhdGVkIHByb2JsZW0nLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICBkcml2ZXJDb25maWcuZ2V0Q29uZmlnUHJvYmxlbXMoe2F1dG9tYXRpb25OYW1lOiAnZm9vJ30sICdmb28nKTtcbiAgICAgICAgICAgIGRyaXZlckNvbmZpZ1xuICAgICAgICAgICAgICAuZ2V0Q29uZmlnUHJvYmxlbXMoe2F1dG9tYXRpb25OYW1lOiAnZm9vJ30sICdmb28nKVxuICAgICAgICAgICAgICAuc2hvdWxkLmRlZXAuaW5jbHVkZSh7XG4gICAgICAgICAgICAgICAgZXJyOiAnTXVsdGlwbGUgZHJpdmVycyBjbGFpbSBzdXBwb3J0IGZvciB0aGUgc2FtZSBhdXRvbWF0aW9uTmFtZScsXG4gICAgICAgICAgICAgICAgdmFsOiAnZm9vJyxcbiAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgfSk7XG4gICAgICAgIH0pO1xuICAgICAgfSk7XG4gICAgfSk7XG5cbiAgICBkZXNjcmliZSgnZ2V0U2NoZW1hUHJvYmxlbXMoKScsIGZ1bmN0aW9uICgpIHtcbiAgICAgIC8qKlxuICAgICAgICogQHR5cGUge1JldHVyblR5cGU8RHJpdmVyQ29uZmlnWydnZXRJbnN0YW5jZSddPn1cbiAgICAgICAqL1xuICAgICAgbGV0IGRyaXZlckNvbmZpZztcblxuICAgICAgYmVmb3JlRWFjaChmdW5jdGlvbiAoKSB7XG4gICAgICAgIGRyaXZlckNvbmZpZyA9IERyaXZlckNvbmZpZy5nZXRJbnN0YW5jZSgnL3RtcC8nKTtcbiAgICAgIH0pO1xuICAgICAgZGVzY3JpYmUoJ3doZW4gcHJvdmlkZWQgYW4gb2JqZWN0IHdpdGggYSBkZWZpbmVkIG5vbi1zdHJpbmcgYHNjaGVtYWAgcHJvcGVydHknLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGl0KCdzaG91bGQgcmV0dXJuIGFuIGFycmF5IHdpdGggYW4gYXNzb2NpYXRlZCBwcm9ibGVtJywgZnVuY3Rpb24gKCkge1xuICAgICAgICAgIGRyaXZlckNvbmZpZ1xuICAgICAgICAgICAgLmdldFNjaGVtYVByb2JsZW1zKHtzY2hlbWE6IFtdfSwgJ2ZvbycpXG4gICAgICAgICAgICAuc2hvdWxkLmRlZXAuaW5jbHVkZSh7XG4gICAgICAgICAgICAgIGVycjogJ0luY29ycmVjdGx5IGZvcm1hdHRlZCBzY2hlbWEgZmllbGQ7IG11c3QgYmUgYSBwYXRoIHRvIGEgc2NoZW1hIGZpbGUgb3IgYSBzY2hlbWEgb2JqZWN0LicsXG4gICAgICAgICAgICAgIHZhbDogW10sXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfSk7XG4gICAgICB9KTtcblxuICAgICAgZGVzY3JpYmUoJ3doZW4gcHJvdmlkZWQgYSBzdHJpbmcgYHNjaGVtYWAgcHJvcGVydHknLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGRlc2NyaWJlKCd3aGVuIHRoZSBwcm9wZXJ0eSBlbmRzIGluIGFuIHVuc3VwcG9ydGVkIGV4dGVuc2lvbicsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICBpdCgnc2hvdWxkIHJldHVybiBhbiBhcnJheSB3aXRoIGFuIGFzc29jaWF0ZWQgcHJvYmxlbScsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIGRyaXZlckNvbmZpZ1xuICAgICAgICAgICAgICAuZ2V0U2NoZW1hUHJvYmxlbXMoe3NjaGVtYTogJ3NlbGVuaXVtLmphdmEnfSwgJ2ZvbycpXG4gICAgICAgICAgICAgIC5zaG91bGQuZGVlcC5pbmNsdWRlKHtcbiAgICAgICAgICAgICAgICBlcnI6ICdTY2hlbWEgZmlsZSBoYXMgdW5zdXBwb3J0ZWQgZXh0ZW5zaW9uLiBBbGxvd2VkOiAuanNvbiwgLmpzLCAuY2pzJyxcbiAgICAgICAgICAgICAgICB2YWw6ICdzZWxlbml1bS5qYXZhJyxcbiAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgfSk7XG4gICAgICAgIH0pO1xuXG4gICAgICAgIGRlc2NyaWJlKCd3aGVuIHRoZSBwcm9wZXJ0eSBjb250YWlucyBhIHN1cHBvcnRlZCBleHRlbnNpb24nLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgZGVzY3JpYmUoJ3doZW4gdGhlIHByb3BlcnR5IGFzIGEgcGF0aCBjYW5ub3QgYmUgZm91bmQnLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICBpdCgnc2hvdWxkIHJldHVybiBhbiBhcnJheSB3aXRoIGFuIGFzc29jaWF0ZWQgcHJvYmxlbScsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgY29uc3QgcHJvYmxlbXMgPSBkcml2ZXJDb25maWcuZ2V0U2NoZW1hUHJvYmxlbXMoXG4gICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgaW5zdGFsbFBhdGg6ICcvdXNyL2Jpbi9kZXJwJyxcbiAgICAgICAgICAgICAgICAgIHBrZ05hbWU6ICdkb29wJyxcbiAgICAgICAgICAgICAgICAgIHNjaGVtYTogJ2hlcnAuanNvbicsXG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICAnZm9vJyxcbiAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgICAgcHJvYmxlbXNbMF0uZXJyLnNob3VsZC5tYXRjaCgvVW5hYmxlIHRvIHJlZ2lzdGVyIHNjaGVtYSBhdCBwYXRoIGhlcnBcXC5qc29uL2kpO1xuICAgICAgICAgICAgICAvLyBwcm9ibGVtcy5zaG91bGQuZGVlcC5pbmNsdWRlKHtcbiAgICAgICAgICAgICAgLy8gICBlcnI6IGBVbmFibGUgdG8gcmVnaXN0ZXIgc2NoZW1hIGF0IHBhdGggaGVycC5qc29uYCxcbiAgICAgICAgICAgICAgLy8gICB2YWw6ICdoZXJwLmpzb24nLFxuICAgICAgICAgICAgICAvLyB9KTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgZGVzY3JpYmUoJ3doZW4gdGhlIHByb3BlcnR5IGFzIGEgcGF0aCBpcyBmb3VuZCcsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIGl0KCdzaG91bGQgcmV0dXJuIGFuIGVtcHR5IGFycmF5JywgZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICBjb25zdCBwcm9ibGVtcyA9IGRyaXZlckNvbmZpZy5nZXRTY2hlbWFQcm9ibGVtcyhcbiAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICBwa2dOYW1lOiAnZml4dHVyZXMnLCAvLyBqdXN0IGNvcnJlc3BvbmRzIHRvIGEgZGlyZWN0b3J5IG5hbWUgcmVsYXRpdmUgdG8gYGluc3RhbGxQYXRoYCBgKF9fZGlybmFtZSlgXG4gICAgICAgICAgICAgICAgICBpbnN0YWxsUGF0aDogX19kaXJuYW1lLFxuICAgICAgICAgICAgICAgICAgc2NoZW1hOiAnZHJpdmVyLnNjaGVtYS5qcycsXG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICAnZm9vJyxcbiAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgICAgcHJvYmxlbXMuc2hvdWxkLmJlLmVtcHR5O1xuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgfSk7XG4gICAgICAgIH0pO1xuICAgICAgfSk7XG4gICAgfSk7XG5cbiAgICBkZXNjcmliZSgncmVhZCgpJywgZnVuY3Rpb24gKCkge1xuICAgICAgLyoqXG4gICAgICAgKiBAdHlwZSB7UmV0dXJuVHlwZTxEcml2ZXJDb25maWdbJ2dldEluc3RhbmNlJ10+fVxuICAgICAgICovXG4gICAgICBsZXQgZHJpdmVyQ29uZmlnO1xuXG4gICAgICBiZWZvcmVFYWNoKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgZHJpdmVyQ29uZmlnID0gRHJpdmVyQ29uZmlnLmdldEluc3RhbmNlKCcvdG1wLycpO1xuICAgICAgICBzYW5kYm94LnNweShkcml2ZXJDb25maWcsICd2YWxpZGF0ZScpO1xuICAgICAgfSk7XG5cbiAgICAgIGl0KCdzaG91bGQgdmFsaWRhdGUgdGhlIGV4dGVuc2lvbicsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgYXdhaXQgZHJpdmVyQ29uZmlnLnJlYWQoKTtcbiAgICAgICAgZHJpdmVyQ29uZmlnLnZhbGlkYXRlLnNob3VsZC5oYXZlLmJlZW4uY2FsbGVkT25jZTtcbiAgICAgIH0pO1xuICAgIH0pO1xuXG4gICAgZGVzY3JpYmUoJ3JlYWRFeHRlbnNpb25TY2hlbWEoKScsIGZ1bmN0aW9uICgpIHtcbiAgICAgIC8qKlxuICAgICAgICogQHR5cGUge1JldHVyblR5cGU8RHJpdmVyQ29uZmlnWydnZXRJbnN0YW5jZSddPn1cbiAgICAgICAqL1xuICAgICAgbGV0IGRyaXZlckNvbmZpZztcblxuICAgICAgLyoqIEB0eXBlIHtpbXBvcnQoJy4uL2xpYi9leHRlbnNpb24tY29uZmlnJykuRXh0RGF0YX0gKi9cbiAgICAgIGxldCBleHREYXRhO1xuXG4gICAgICBjb25zdCBleHROYW1lID0gJ3N0dWZmJztcblxuICAgICAgYmVmb3JlRWFjaChmdW5jdGlvbiAoKSB7XG4gICAgICAgIGV4dERhdGEgPSB7XG4gICAgICAgICAgaW5zdGFsbFBhdGg6ICdmaXh0dXJlcycsXG4gICAgICAgICAgcGtnTmFtZTogJ3NvbWUtcGtnJyxcbiAgICAgICAgICBzY2hlbWE6ICdkcml2ZXIuc2NoZW1hLmpzJyxcbiAgICAgICAgfTtcbiAgICAgICAgbW9ja3NbJ3Jlc29sdmUtZnJvbSddLnJldHVybnMoXG4gICAgICAgICAgcmVxdWlyZS5yZXNvbHZlKCcuL2ZpeHR1cmVzL2RyaXZlci5zY2hlbWEuanMnKSxcbiAgICAgICAgKTtcbiAgICAgICAgZHJpdmVyQ29uZmlnID0gRHJpdmVyQ29uZmlnLmdldEluc3RhbmNlKCcvdG1wLycpO1xuICAgICAgfSk7XG5cbiAgICAgIGRlc2NyaWJlKCd3aGVuIHRoZSBleHRlbnNpb24gZGF0YSBpcyBtaXNzaW5nIGBzY2hlbWFgJywgZnVuY3Rpb24gKCkge1xuICAgICAgICBpdCgnc2hvdWxkIHRocm93JywgZnVuY3Rpb24gKCkge1xuICAgICAgICAgIGRlbGV0ZSBleHREYXRhLnNjaGVtYTtcbiAgICAgICAgICBleHBlY3QoKCkgPT5cbiAgICAgICAgICAgIGRyaXZlckNvbmZpZy5yZWFkRXh0ZW5zaW9uU2NoZW1hKGV4dE5hbWUsIGV4dERhdGEpLFxuICAgICAgICAgICkudG8udGhyb3coVHlwZUVycm9yLCAvd2h5IGlzIHRoaXMgZnVuY3Rpb24gYmVpbmcgY2FsbGVkL2kpO1xuICAgICAgICB9KTtcbiAgICAgIH0pO1xuXG4gICAgICBkZXNjcmliZSgnd2hlbiB0aGUgZXh0ZW5zaW9uIHNjaGVtYSBoYXMgYWxyZWFkeSBiZWVuIHJlZ2lzdGVyZWQgKHdpdGggdGhlIHNhbWUgc2NoZW1hKScsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgaXQoJ3Nob3VsZCBub3QgdGhyb3cnLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgZHJpdmVyQ29uZmlnLnJlYWRFeHRlbnNpb25TY2hlbWEoZXh0TmFtZSwgZXh0RGF0YSk7XG4gICAgICAgICAgZXhwZWN0KCgpID0+IGRyaXZlckNvbmZpZy5yZWFkRXh0ZW5zaW9uU2NoZW1hKGV4dE5hbWUsIGV4dERhdGEpKS5ub3QudG8udGhyb3coKTtcbiAgICAgICAgfSk7XG4gICAgICB9KTtcblxuICAgICAgZGVzY3JpYmUoJ3doZW4gdGhlIGV4dGVuc2lvbiBzY2hlbWEgaGFzIG5vdCB5ZXQgYmVlbiByZWdpc3RlcmVkJywgZnVuY3Rpb24gKCkge1xuICAgICAgICBpdCgnc2hvdWxkIHJlc29sdmUgYW5kIGxvYWQgdGhlIGV4dGVuc2lvbiBzY2hlbWEgZmlsZScsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICBkcml2ZXJDb25maWcucmVhZEV4dGVuc2lvblNjaGVtYSAoZXh0TmFtZSwgZXh0RGF0YSk7XG5cbiAgICAgICAgICAvLyB3ZSBkb24ndCBoYXZlIGFjY2VzcyB0byB0aGUgc2NoZW1hIHJlZ2lzdHJhdGlvbiBjYWNoZSBkaXJlY3RseSwgc28gdGhpcyBpcyBhcyBjbG9zZSBhcyB3ZSBjYW4gZ2V0LlxuICAgICAgICAgIGV4cGVjdChtb2Nrc1sncmVzb2x2ZS1mcm9tJ10pLnRvLmhhdmUuYmVlbi5jYWxsZWRPbmNlO1xuICAgICAgICB9KTtcbiAgICAgIH0pO1xuICAgIH0pO1xuICB9KTtcblxuICBkZXNjcmliZSgnUGx1Z2luQ29uZmlnJywgZnVuY3Rpb24gKCkge1xuICAgIC8qKlxuICAgICAqIEB0eXBlIHt0eXBlb2YgaW1wb3J0KCcuLi9saWIvcGx1Z2luLWNvbmZpZycpLmRlZmF1bHR9XG4gICAgICovXG4gICAgbGV0IFBsdWdpbkNvbmZpZztcbiAgICBsZXQgbW9ja3M7XG4gICAgLyoqIEB0eXBlIHtpbXBvcnQoJ3Npbm9uJykuU2lub25TYW5kYm94fSAqL1xuICAgIGxldCBzYW5kYm94O1xuICAgIGJlZm9yZUVhY2goZnVuY3Rpb24gKCkge1xuICAgICAgbW9ja3MgPSB7XG4gICAgICAgICdyZXNvbHZlLWZyb20nOiBzaW5vbi5zdHViKCkuY2FsbHNGYWtlKChjd2QsIGlkKSA9PiBwYXRoLmpvaW4oY3dkLCBpZCkpLFxuICAgICAgfTtcblxuICAgICAgUGx1Z2luQ29uZmlnID0gcmV3aXJlbW9jay5wcm94eShcbiAgICAgICAgKCkgPT4gcmVxdWlyZSgnLi4vbGliL3BsdWdpbi1jb25maWcnKSxcbiAgICAgICAgbW9ja3MsXG4gICAgICApLmRlZmF1bHQ7XG5cbiAgICAgIHNhbmRib3ggPSBzaW5vbi5jcmVhdGVTYW5kYm94KCk7XG4gICAgfSk7XG5cbiAgICBhZnRlckVhY2goZnVuY3Rpb24gKCkge1xuICAgICAgc2FuZGJveC5yZXN0b3JlKCk7XG4gICAgfSk7XG5cbiAgICBkZXNjcmliZSgnZXh0ZW5zaW9uRGVzYygpJywgZnVuY3Rpb24gKCkge1xuICAgICAgaXQoJ3Nob3VsZCByZXR1cm4gdGhlIGRlc2NyaXB0aW9uIG9mIHRoZSBleHRlbnNpb24nLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGNvbnN0IGNvbmZpZyA9IFBsdWdpbkNvbmZpZy5nZXRJbnN0YW5jZSgnL3RtcC8nKTtcbiAgICAgICAgY29uZmlnXG4gICAgICAgICAgLmV4dGVuc2lvbkRlc2MoJ2ZvbycsIHt2ZXJzaW9uOiAnMS4wJ30pXG4gICAgICAgICAgLnNob3VsZC5lcXVhbChgZm9vQDEuMGApO1xuICAgICAgfSk7XG4gICAgfSk7XG5cbiAgICBkZXNjcmliZSgnZ2V0Q29uZmlnUHJvYmxlbXMoKScsIGZ1bmN0aW9uICgpIHtcbiAgICAgIC8qKlxuICAgICAgICogQHR5cGUge1JldHVyblR5cGU8UGx1Z2luQ29uZmlnWydnZXRJbnN0YW5jZSddPn1cbiAgICAgICAqL1xuICAgICAgbGV0IHBsdWdpbkNvbmZpZztcblxuICAgICAgYmVmb3JlRWFjaChmdW5jdGlvbiAoKSB7XG4gICAgICAgIHBsdWdpbkNvbmZpZyA9IFBsdWdpbkNvbmZpZy5nZXRJbnN0YW5jZSgnL3RtcC8nKTtcbiAgICAgIH0pO1xuXG4gICAgICBkZXNjcmliZSgnd2hlbiBwcm92aWRlZCBubyBhcmd1bWVudHMnLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGl0KCdzaG91bGQgbm90IHRocm93JywgZnVuY3Rpb24gKCkge1xuICAgICAgICAgIC8vIEB0cy1pZ25vcmVcbiAgICAgICAgICAoKCkgPT4gcGx1Z2luQ29uZmlnLmdldENvbmZpZ1Byb2JsZW1zKCkpLnNob3VsZC5ub3QudGhyb3coKTtcbiAgICAgICAgfSk7XG4gICAgICB9KTtcbiAgICB9KTtcblxuICAgIGRlc2NyaWJlKCdnZXRTY2hlbWFQcm9ibGVtcygpJywgZnVuY3Rpb24gKCkge1xuICAgICAgLyoqXG4gICAgICAgKiBAdHlwZSB7UmV0dXJuVHlwZTxQbHVnaW5Db25maWdbJ2dldEluc3RhbmNlJ10+fVxuICAgICAgICovXG4gICAgICBsZXQgcGx1Z2luQ29uZmlnO1xuXG4gICAgICBiZWZvcmVFYWNoKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgcGx1Z2luQ29uZmlnID0gUGx1Z2luQ29uZmlnLmdldEluc3RhbmNlKCcvdG1wLycpO1xuICAgICAgfSk7XG5cbiAgICAgIGRlc2NyaWJlKCd3aGVuIHByb3ZpZGVkIGFuIG9iamVjdCB3aXRoIGEgZGVmaW5lZCBgc2NoZW1hYCBwcm9wZXJ0eSBvZiB1bnN1cHBvcnRlZCB0eXBlJywgZnVuY3Rpb24gKCkge1xuICAgICAgICBpdCgnc2hvdWxkIHJldHVybiBhbiBhcnJheSB3aXRoIGFuIGFzc29jaWF0ZWQgcHJvYmxlbScsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICBwbHVnaW5Db25maWdcbiAgICAgICAgICAgIC5nZXRTY2hlbWFQcm9ibGVtcyh7c2NoZW1hOiBbXX0sICdmb28nKVxuICAgICAgICAgICAgLnNob3VsZC5kZWVwLmluY2x1ZGUoe1xuICAgICAgICAgICAgICBlcnI6ICdJbmNvcnJlY3RseSBmb3JtYXR0ZWQgc2NoZW1hIGZpZWxkOyBtdXN0IGJlIGEgcGF0aCB0byBhIHNjaGVtYSBmaWxlIG9yIGEgc2NoZW1hIG9iamVjdC4nLFxuICAgICAgICAgICAgICB2YWw6IFtdLFxuICAgICAgICAgICAgfSk7XG4gICAgICAgIH0pO1xuICAgICAgfSk7XG5cbiAgICAgIGRlc2NyaWJlKCd3aGVuIHByb3ZpZGVkIGEgc3RyaW5nIGBzY2hlbWFgIHByb3BlcnR5JywgZnVuY3Rpb24gKCkge1xuICAgICAgICBkZXNjcmliZSgnd2hlbiB0aGUgcHJvcGVydHkgZW5kcyBpbiBhbiB1bnN1cHBvcnRlZCBleHRlbnNpb24nLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgaXQoJ3Nob3VsZCByZXR1cm4gYW4gYXJyYXkgd2l0aCBhbiBhc3NvY2lhdGVkIHByb2JsZW0nLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICBwbHVnaW5Db25maWdcbiAgICAgICAgICAgICAgLmdldFNjaGVtYVByb2JsZW1zKHtzY2hlbWE6ICdzZWxlbml1bS5qYXZhJ30sICdmb28nKVxuICAgICAgICAgICAgICAuc2hvdWxkLmRlZXAuaW5jbHVkZSh7XG4gICAgICAgICAgICAgICAgZXJyOiAnU2NoZW1hIGZpbGUgaGFzIHVuc3VwcG9ydGVkIGV4dGVuc2lvbi4gQWxsb3dlZDogLmpzb24sIC5qcywgLmNqcycsXG4gICAgICAgICAgICAgICAgdmFsOiAnc2VsZW5pdW0uamF2YScsXG4gICAgICAgICAgICAgIH0pO1xuICAgICAgICAgIH0pO1xuICAgICAgICB9KTtcblxuICAgICAgICBkZXNjcmliZSgnd2hlbiB0aGUgcHJvcGVydHkgY29udGFpbnMgYSBzdXBwb3J0ZWQgZXh0ZW5zaW9uJywgZnVuY3Rpb24gKCkge1xuICAgICAgICAgIGRlc2NyaWJlKCd3aGVuIHRoZSBwcm9wZXJ0eSBhcyBhIHBhdGggY2Fubm90IGJlIGZvdW5kJywgZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgaXQoJ3Nob3VsZCByZXR1cm4gYW4gYXJyYXkgd2l0aCBhbiBhc3NvY2lhdGVkIHByb2JsZW0nLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgIGNvbnN0IHByb2JsZW1zID0gcGx1Z2luQ29uZmlnLmdldFNjaGVtYVByb2JsZW1zKFxuICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgIGluc3RhbGxQYXRoOiAnL3Vzci9iaW4vZGVycCcsXG4gICAgICAgICAgICAgICAgICBwa2dOYW1lOiAnZG9vcCcsXG4gICAgICAgICAgICAgICAgICBzY2hlbWE6ICdoZXJwLmpzb24nLFxuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgJ2ZvbycsXG4gICAgICAgICAgICAgICk7XG4gICAgICAgICAgICAgIHByb2JsZW1zWzBdLmVyci5zaG91bGQubWF0Y2goL1VuYWJsZSB0byByZWdpc3RlciBzY2hlbWEgYXQgcGF0aCBoZXJwXFwuanNvbi9pKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgZGVzY3JpYmUoJ3doZW4gdGhlIHByb3BlcnR5IGFzIGEgcGF0aCBpcyBmb3VuZCcsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIGl0KCdzaG91bGQgcmV0dXJuIGFuIGVtcHR5IGFycmF5JywgZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICBjb25zdCBwcm9ibGVtcyA9IHBsdWdpbkNvbmZpZy5nZXRTY2hlbWFQcm9ibGVtcyhcbiAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICBwa2dOYW1lOiAnZml4dHVyZXMnLCAvLyBqdXN0IGNvcnJlc3BvbmRzIHRvIGEgZGlyZWN0b3J5IG5hbWUgcmVsYXRpdmUgdG8gYGluc3RhbGxQYXRoYCBgKF9fZGlybmFtZSlgXG4gICAgICAgICAgICAgICAgICBpbnN0YWxsUGF0aDogX19kaXJuYW1lLFxuICAgICAgICAgICAgICAgICAgc2NoZW1hOiAncGx1Z2luLnNjaGVtYS5qcycsXG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICAnZm9vJyxcbiAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgICAgcHJvYmxlbXMuc2hvdWxkLmJlLmVtcHR5O1xuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgfSk7XG4gICAgICAgIH0pO1xuICAgICAgfSk7XG5cbiAgICAgIGRlc2NyaWJlKCd3aGVuIHByb3ZpZGVkIGFuIG9iamVjdCBgc2NoZW1hYCBwcm9wZXJ0eScsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgaXQoJ3Nob3VsZCByZXR1cm4gYW4gZW1wdHkgYXJyYXknLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgY29uc3QgcHJvYmxlbXMgPSBwbHVnaW5Db25maWcuZ2V0U2NoZW1hUHJvYmxlbXMoXG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgIHBrZ05hbWU6ICdmaXh0dXJlcycsIC8vIGp1c3QgY29ycmVzcG9uZHMgdG8gYSBkaXJlY3RvcnkgbmFtZSByZWxhdGl2ZSB0byBgaW5zdGFsbFBhdGhgIGAoX19kaXJuYW1lKWBcbiAgICAgICAgICAgICAgaW5zdGFsbFBhdGg6IF9fZGlybmFtZSxcbiAgICAgICAgICAgICAgc2NoZW1hOiB7dHlwZTogJ29iamVjdCcsIHByb3BlcnRpZXM6IHtmb286IHt0eXBlOiAnc3RyaW5nJ319fSxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAnZm9vJyxcbiAgICAgICAgICApO1xuICAgICAgICAgIHByb2JsZW1zLnNob3VsZC5iZS5lbXB0eTtcbiAgICAgICAgfSk7XG4gICAgICB9KTtcbiAgICB9KTtcblxuICAgIGRlc2NyaWJlKCdyZWFkKCknLCBmdW5jdGlvbiAoKSB7XG4gICAgICAvKipcbiAgICAgICAqIEB0eXBlIHtSZXR1cm5UeXBlPFBsdWdpbkNvbmZpZ1snZ2V0SW5zdGFuY2UnXT59XG4gICAgICAgKi9cbiAgICAgIGxldCBwbHVnaW5Db25maWc7XG5cbiAgICAgIGJlZm9yZUVhY2goZnVuY3Rpb24gKCkge1xuICAgICAgICBwbHVnaW5Db25maWcgPSBQbHVnaW5Db25maWcuZ2V0SW5zdGFuY2UoJy90bXAvJyk7XG4gICAgICAgIHNhbmRib3guc3B5KHBsdWdpbkNvbmZpZywgJ3ZhbGlkYXRlJyk7XG4gICAgICB9KTtcblxuICAgICAgaXQoJ3Nob3VsZCB2YWxpZGF0ZSB0aGUgZXh0ZW5zaW9uJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgICBhd2FpdCBwbHVnaW5Db25maWcucmVhZCgpO1xuICAgICAgICBwbHVnaW5Db25maWcudmFsaWRhdGUuc2hvdWxkLmhhdmUuYmVlbi5jYWxsZWRPbmNlO1xuICAgICAgfSk7XG4gICAgfSk7XG5cbiAgICBkZXNjcmliZSgncmVhZEV4dGVuc2lvblNjaGVtYSgpJywgZnVuY3Rpb24gKCkge1xuICAgICAgLyoqXG4gICAgICAgKiBAdHlwZSB7UmV0dXJuVHlwZTxQbHVnaW5Db25maWdbJ2dldEluc3RhbmNlJ10+fVxuICAgICAgICovXG4gICAgICBsZXQgcGx1Z2luQ29uZmlnO1xuXG4gICAgICAvKiogQHR5cGUge2ltcG9ydCgnLi4vbGliL2V4dGVuc2lvbi1jb25maWcnKS5FeHREYXRhfSAqL1xuICAgICAgbGV0IGV4dERhdGE7XG5cbiAgICAgIGNvbnN0IGV4dE5hbWUgPSAnc3R1ZmYnO1xuXG4gICAgICBiZWZvcmVFYWNoKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgZXh0RGF0YSA9IHtcbiAgICAgICAgICBpbnN0YWxsUGF0aDogJ2ZpeHR1cmVzJyxcbiAgICAgICAgICBwa2dOYW1lOiAnc29tZS1wa2cnLFxuICAgICAgICAgIHNjaGVtYTogJ3BsdWdpbi5zY2hlbWEuanMnLFxuICAgICAgICB9O1xuICAgICAgICBtb2Nrc1sncmVzb2x2ZS1mcm9tJ10ucmV0dXJucyhcbiAgICAgICAgICByZXF1aXJlLnJlc29sdmUoJy4vZml4dHVyZXMvcGx1Z2luLnNjaGVtYS5qcycpLFxuICAgICAgICApO1xuICAgICAgICBwbHVnaW5Db25maWcgPSBQbHVnaW5Db25maWcuZ2V0SW5zdGFuY2UoJy90bXAvJyk7XG5cbiAgICAgIH0pO1xuXG4gICAgICBkZXNjcmliZSgnd2hlbiB0aGUgZXh0ZW5zaW9uIGRhdGEgaXMgbWlzc2luZyBgc2NoZW1hYCcsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgaXQoJ3Nob3VsZCB0aHJvdycsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICBkZWxldGUgZXh0RGF0YS5zY2hlbWE7XG4gICAgICAgICAgZXhwZWN0KCgpID0+XG4gICAgICAgICAgICBwbHVnaW5Db25maWcucmVhZEV4dGVuc2lvblNjaGVtYShleHROYW1lLCBleHREYXRhKSxcbiAgICAgICAgICApLnRvLnRocm93KFR5cGVFcnJvciwgL3doeSBpcyB0aGlzIGZ1bmN0aW9uIGJlaW5nIGNhbGxlZC9pKTtcbiAgICAgICAgfSk7XG4gICAgICB9KTtcblxuICAgICAgZGVzY3JpYmUoJ3doZW4gdGhlIGV4dGVuc2lvbiBzY2hlbWEgaGFzIGFscmVhZHkgYmVlbiByZWdpc3RlcmVkJywgZnVuY3Rpb24gKCkge1xuICAgICAgICBkZXNjcmliZSgnd2hlbiB0aGUgc2NoZW1hIGlzIGlkZW50aWNhbCAocHJlc3VtYWJseSB0aGUgc2FtZSBleHRlbnNpb24pJywgZnVuY3Rpb24gKCkge1xuICAgICAgICAgIGl0KCdzaG91bGQgbm90IHRocm93JywgZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgcGx1Z2luQ29uZmlnLnJlYWRFeHRlbnNpb25TY2hlbWEoZXh0TmFtZSwgZXh0RGF0YSk7XG4gICAgICAgICAgICBleHBlY3QoKCkgPT4gcGx1Z2luQ29uZmlnLnJlYWRFeHRlbnNpb25TY2hlbWEoZXh0TmFtZSwgZXh0RGF0YSkpLm5vdC50by50aHJvdygpO1xuICAgICAgICAgIH0pO1xuICAgICAgICB9KTtcblxuICAgICAgICBkZXNjcmliZSgnd2hlbiB0aGUgc2NoZW1hIGRpZmZlcnMgKHByZXN1bWFibHkgYSBkaWZmZXJlbnQgZXh0ZW5zaW9uKScsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICBpdCgnc2hvdWxkIHRocm93JywgZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgcGx1Z2luQ29uZmlnLnJlYWRFeHRlbnNpb25TY2hlbWEoZXh0TmFtZSwgZXh0RGF0YSk7XG4gICAgICAgICAgICBtb2Nrc1sncmVzb2x2ZS1mcm9tJ10ucmV0dXJucyhyZXF1aXJlLnJlc29sdmUoJy4vZml4dHVyZXMvZHJpdmVyLnNjaGVtYS5qcycpKTtcbiAgICAgICAgICAgIGV4cGVjdCgoKSA9PiBwbHVnaW5Db25maWcucmVhZEV4dGVuc2lvblNjaGVtYShleHROYW1lLCBleHREYXRhKSkudG8udGhyb3coL2NvbmZsaWN0cyB3aXRoIGFuIGV4aXN0aW5nIHNjaGVtYS9pKTtcbiAgICAgICAgICB9KTtcbiAgICAgICAgfSk7XG4gICAgICB9KTtcblxuICAgICAgZGVzY3JpYmUoJ3doZW4gdGhlIGV4dGVuc2lvbiBzY2hlbWEgaGFzIG5vdCB5ZXQgYmVlbiByZWdpc3RlcmVkJywgZnVuY3Rpb24gKCkge1xuICAgICAgICBpdCgnc2hvdWxkIHJlc29sdmUgYW5kIGxvYWQgdGhlIGV4dGVuc2lvbiBzY2hlbWEgZmlsZScsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICBwbHVnaW5Db25maWcucmVhZEV4dGVuc2lvblNjaGVtYShleHROYW1lLCBleHREYXRhKTtcblxuICAgICAgICAgIC8vIHdlIGRvbid0IGhhdmUgYWNjZXNzIHRvIHRoZSBzY2hlbWEgcmVnaXN0cmF0aW9uIGNhY2hlIGRpcmVjdGx5LCBzbyB0aGlzIGlzIGFzIGNsb3NlIGFzIHdlIGNhbiBnZXQuXG4gICAgICAgICAgZXhwZWN0KG1vY2tzWydyZXNvbHZlLWZyb20nXSkudG8uaGF2ZS5iZWVuLmNhbGxlZE9uY2U7XG4gICAgICAgIH0pO1xuICAgICAgfSk7XG4gICAgfSk7XG4gIH0pO1xufSk7XG4iXSwiZmlsZSI6InRlc3QvZXh0ZW5zaW9uLWNvbmZpZy1zcGVjcy5qcyIsInNvdXJjZVJvb3QiOiIuLi8uLiJ9
@@ -0,0 +1,5 @@
1
+ feature1
2
+ feature2
3
+
4
+ feature3
5
+
@@ -0,0 +1,3 @@
1
+ {
2
+ "a": "b"
3
+ }
@@ -0,0 +1,3 @@
1
+ foo
2
+ bar
3
+ baz
@@ -0,0 +1,5 @@
1
+ {
2
+ "server": {
3
+ "nodeconfig": "./packages/appium/test/fixtures/config/nodeconfig.json"
4
+ }
5
+ }
@@ -0,0 +1,32 @@
1
+ {
2
+ "appium-home": "foo",
3
+ "server": {
4
+ "address": "0.0.0.0",
5
+ "allow-cors": 1,
6
+ "allow-insecure": {},
7
+ "base-path": "/",
8
+ "callback-address": "0.0.0.0",
9
+ "callback-port": 43243234,
10
+ "debug-log-spacing": false,
11
+ "default-capabilities": {},
12
+ "deny-insecure": [],
13
+ "keep-alive-timeout": 0,
14
+ "local-timezone": false,
15
+ "log": "/tmp/appium.log",
16
+ "log-level": "smoosh",
17
+ "log-no-colors": 1,
18
+ "log-timestamp": false,
19
+ "long-stacktrace": false,
20
+ "no-perms-check": false,
21
+ "nodeconfig": {},
22
+ "port": "31337",
23
+ "relaxed-security": false,
24
+ "session-override": false,
25
+ "strict-caps": false,
26
+ "tmp": "/tmp",
27
+ "trace-dir": "/tmp/appium-instruments",
28
+ "use-drivers": [],
29
+ "use-plugins": ["all"],
30
+ "webhook": "http://0.0.0.0/hook"
31
+ }
32
+ }
@@ -0,0 +1,9 @@
1
+ {
2
+ "server": {
3
+ "driver": {
4
+ "fake": {
5
+ "answer": 24
6
+ }
7
+ }
8
+ }
9
+ }
@@ -0,0 +1,10 @@
1
+ {
2
+ "server": {
3
+ "driver": {
4
+ "fake": {
5
+ "answer": 24,
6
+ "bubb": "rubb"
7
+ }
8
+ }
9
+ }
10
+ }
@@ -0,0 +1,40 @@
1
+ "use strict";
2
+
3
+ require("source-map-support/register");
4
+
5
+ module.exports = {
6
+ server: {
7
+ address: '0.0.0.0',
8
+ 'allow-cors': false,
9
+ 'allow-insecure': [],
10
+ 'base-path': '/',
11
+ 'callback-address': '0.0.0.0',
12
+ 'callback-port': 31337,
13
+ 'debug-log-spacing': false,
14
+ 'default-capabilities': {},
15
+ 'deny-insecure': [],
16
+ 'keep-alive-timeout': 600,
17
+ 'local-timezone': false,
18
+ log: '/tmp/appium.log',
19
+ 'log-level': 'info',
20
+ 'log-no-colors': false,
21
+ 'log-timestamp': false,
22
+ 'long-stacktrace': false,
23
+ 'no-perms-check': false,
24
+ nodeconfig: {
25
+ foo: 'bar'
26
+ },
27
+ port: 31337,
28
+ 'relaxed-security': false,
29
+ 'session-override': false,
30
+ 'strict-caps': false,
31
+ tmp: '/tmp',
32
+ 'trace-dir': '/tmp/appium-instruments',
33
+ 'use-drivers': [],
34
+ 'use-plugins': ['all'],
35
+ webhook: 'http://0.0.0.0/hook'
36
+ }
37
+ };require('source-map-support').install();
38
+
39
+
40
+ //# sourceMappingURL=data:application/json;charset=utf8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbInRlc3QvZml4dHVyZXMvY29uZmlnL2FwcGl1bS5jb25maWcuZ29vZC5qcyJdLCJuYW1lcyI6WyJtb2R1bGUiLCJleHBvcnRzIiwic2VydmVyIiwiYWRkcmVzcyIsImxvZyIsIm5vZGVjb25maWciLCJmb28iLCJwb3J0IiwidG1wIiwid2ViaG9vayJdLCJtYXBwaW5ncyI6Ijs7OztBQUFBQSxNQUFNLENBQUNDLE9BQVAsR0FBaUI7QUFDZkMsRUFBQUEsTUFBTSxFQUFFO0FBQ05DLElBQUFBLE9BQU8sRUFBRSxTQURIO0FBRU4sa0JBQWMsS0FGUjtBQUdOLHNCQUFrQixFQUhaO0FBSU4saUJBQWEsR0FKUDtBQUtOLHdCQUFvQixTQUxkO0FBTU4scUJBQWlCLEtBTlg7QUFPTix5QkFBcUIsS0FQZjtBQVFOLDRCQUF3QixFQVJsQjtBQVNOLHFCQUFpQixFQVRYO0FBVU4sMEJBQXNCLEdBVmhCO0FBV04sc0JBQWtCLEtBWFo7QUFZTkMsSUFBQUEsR0FBRyxFQUFFLGlCQVpDO0FBYU4saUJBQWEsTUFiUDtBQWNOLHFCQUFpQixLQWRYO0FBZU4scUJBQWlCLEtBZlg7QUFnQk4sdUJBQW1CLEtBaEJiO0FBaUJOLHNCQUFrQixLQWpCWjtBQWtCTkMsSUFBQUEsVUFBVSxFQUFFO0FBQ1ZDLE1BQUFBLEdBQUcsRUFBRTtBQURLLEtBbEJOO0FBcUJOQyxJQUFBQSxJQUFJLEVBQUUsS0FyQkE7QUFzQk4sd0JBQW9CLEtBdEJkO0FBdUJOLHdCQUFvQixLQXZCZDtBQXdCTixtQkFBZSxLQXhCVDtBQXlCTkMsSUFBQUEsR0FBRyxFQUFFLE1BekJDO0FBMEJOLGlCQUFhLHlCQTFCUDtBQTJCTixtQkFBZSxFQTNCVDtBQTRCTixtQkFBZSxDQUFDLEtBQUQsQ0E1QlQ7QUE2Qk5DLElBQUFBLE9BQU8sRUFBRTtBQTdCSDtBQURPLENBQWpCIiwic291cmNlc0NvbnRlbnQiOlsibW9kdWxlLmV4cG9ydHMgPSB7XG4gIHNlcnZlcjoge1xuICAgIGFkZHJlc3M6ICcwLjAuMC4wJyxcbiAgICAnYWxsb3ctY29ycyc6IGZhbHNlLFxuICAgICdhbGxvdy1pbnNlY3VyZSc6IFtdLFxuICAgICdiYXNlLXBhdGgnOiAnLycsXG4gICAgJ2NhbGxiYWNrLWFkZHJlc3MnOiAnMC4wLjAuMCcsXG4gICAgJ2NhbGxiYWNrLXBvcnQnOiAzMTMzNyxcbiAgICAnZGVidWctbG9nLXNwYWNpbmcnOiBmYWxzZSxcbiAgICAnZGVmYXVsdC1jYXBhYmlsaXRpZXMnOiB7fSxcbiAgICAnZGVueS1pbnNlY3VyZSc6IFtdLFxuICAgICdrZWVwLWFsaXZlLXRpbWVvdXQnOiA2MDAsXG4gICAgJ2xvY2FsLXRpbWV6b25lJzogZmFsc2UsXG4gICAgbG9nOiAnL3RtcC9hcHBpdW0ubG9nJyxcbiAgICAnbG9nLWxldmVsJzogJ2luZm8nLFxuICAgICdsb2ctbm8tY29sb3JzJzogZmFsc2UsXG4gICAgJ2xvZy10aW1lc3RhbXAnOiBmYWxzZSxcbiAgICAnbG9uZy1zdGFja3RyYWNlJzogZmFsc2UsXG4gICAgJ25vLXBlcm1zLWNoZWNrJzogZmFsc2UsXG4gICAgbm9kZWNvbmZpZzoge1xuICAgICAgZm9vOiAnYmFyJ1xuICAgIH0sXG4gICAgcG9ydDogMzEzMzcsXG4gICAgJ3JlbGF4ZWQtc2VjdXJpdHknOiBmYWxzZSxcbiAgICAnc2Vzc2lvbi1vdmVycmlkZSc6IGZhbHNlLFxuICAgICdzdHJpY3QtY2Fwcyc6IGZhbHNlLFxuICAgIHRtcDogJy90bXAnLFxuICAgICd0cmFjZS1kaXInOiAnL3RtcC9hcHBpdW0taW5zdHJ1bWVudHMnLFxuICAgICd1c2UtZHJpdmVycyc6IFtdLFxuICAgICd1c2UtcGx1Z2lucyc6IFsnYWxsJ10sXG4gICAgd2ViaG9vazogJ2h0dHA6Ly8wLjAuMC4wL2hvb2snXG4gIH0sXG59O1xuIl0sImZpbGUiOiJ0ZXN0L2ZpeHR1cmVzL2NvbmZpZy9hcHBpdW0uY29uZmlnLmdvb2QuanMiLCJzb3VyY2VSb290IjoiLi4vLi4vLi4vLi4ifQ==
@@ -0,0 +1,33 @@
1
+ {
2
+ "server": {
3
+ "address": "0.0.0.0",
4
+ "allow-cors": false,
5
+ "allow-insecure": [],
6
+ "base-path": "/",
7
+ "callback-address": "0.0.0.0",
8
+ "callback-port": 31337,
9
+ "debug-log-spacing": false,
10
+ "default-capabilities": {},
11
+ "deny-insecure": [],
12
+ "keep-alive-timeout": 600,
13
+ "local-timezone": false,
14
+ "log": "/tmp/appium.log",
15
+ "log-level": "info",
16
+ "log-no-colors": false,
17
+ "log-timestamp": false,
18
+ "long-stacktrace": false,
19
+ "no-perms-check": false,
20
+ "nodeconfig": {
21
+ "foo": "bar"
22
+ },
23
+ "port": 31337,
24
+ "relaxed-security": false,
25
+ "session-override": false,
26
+ "strict-caps": false,
27
+ "tmp": "/tmp",
28
+ "trace-dir": "/tmp/appium-instruments",
29
+ "use-drivers": [],
30
+ "use-plugins": ["all"],
31
+ "webhook": "http://0.0.0.0/hook"
32
+ }
33
+ }
@@ -0,0 +1,30 @@
1
+ server:
2
+ address: '0.0.0.0'
3
+ port: 31337
4
+ allow-cors: false
5
+ allow-insecure: []
6
+ base-path: /
7
+ callback-address: '0.0.0.0'
8
+ callback-port: 31337
9
+ log-level: info
10
+ log-timestamp: false
11
+ debug-log-spacing: false
12
+ default-capabilities: {}
13
+ deny-insecure: []
14
+ keep-alive-timeout: 600
15
+ local-timezone: false
16
+ log: /tmp/appium.log
17
+ log-no-colors: false
18
+ long-stacktrace: false
19
+ no-perms-check: false
20
+ nodeconfig:
21
+ foo: bar
22
+ relaxed-security: false
23
+ session-override: false
24
+ strict-caps: false
25
+ tmp: /tmp
26
+ trace-dir: /tmp/appium-instruments
27
+ use-drivers: []
28
+ use-plugins:
29
+ - all
30
+ webhook: 'http://0.0.0.0/hook'