appium 2.0.0-beta.21 → 2.0.0-beta.25
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +201 -0
- package/README.md +1 -2
- package/build/check-npm-pack-files.js +23 -0
- package/build/commands-yml/parse.js +319 -0
- package/build/commands-yml/validator.js +130 -0
- package/build/index.js +19 -0
- package/build/lib/appium.js +22 -7
- package/build/lib/cli/args.js +13 -15
- package/build/lib/cli/npm.js +27 -16
- package/build/lib/cli/parser.js +7 -3
- package/build/lib/config-file.js +4 -7
- package/build/lib/config.js +57 -48
- package/build/lib/extension-config.js +1 -1
- package/build/lib/main.js +28 -28
- package/build/lib/plugin-config.js +2 -2
- package/build/lib/plugins.js +4 -2
- package/build/lib/schema/appium-config-schema.js +3 -2
- package/build/lib/schema/arg-spec.js +5 -3
- package/build/lib/schema/cli-args.js +25 -16
- package/build/lib/schema/keywords.js +14 -4
- package/build/lib/schema/schema.js +86 -9
- package/build/lib/utils.js +16 -36
- package/build/postinstall.js +90 -0
- package/build/test/cli/cli-e2e-specs.js +221 -0
- package/build/test/cli/cli-helpers.js +86 -0
- package/build/test/cli/cli-specs.js +71 -0
- package/build/test/cli/fixtures/test-driver/package.json +27 -0
- package/build/test/cli/schema-args-specs.js +48 -0
- package/build/test/cli/schema-e2e-specs.js +47 -0
- package/build/test/config-e2e-specs.js +112 -0
- package/build/test/config-file-e2e-specs.js +191 -0
- package/build/test/config-file-specs.js +281 -0
- package/build/test/config-specs.js +258 -0
- package/build/test/driver-e2e-specs.js +435 -0
- package/build/test/driver-specs.js +386 -0
- package/build/test/ext-config-io-specs.js +181 -0
- package/build/test/extension-config-specs.js +365 -0
- package/build/test/fixtures/allow-feat.txt +5 -0
- package/build/test/fixtures/caps.json +3 -0
- package/build/test/fixtures/config/allow-insecure.txt +3 -0
- package/build/test/fixtures/config/appium.config.bad-nodeconfig.json +5 -0
- package/build/test/fixtures/config/appium.config.bad.json +32 -0
- package/build/test/fixtures/config/appium.config.ext-good.json +9 -0
- package/build/test/fixtures/config/appium.config.ext-unknown-props.json +10 -0
- package/build/test/fixtures/config/appium.config.good.js +40 -0
- package/build/test/fixtures/config/appium.config.good.json +33 -0
- package/build/test/fixtures/config/appium.config.good.yaml +30 -0
- package/build/test/fixtures/config/appium.config.invalid.json +31 -0
- package/build/test/fixtures/config/appium.config.security-array.json +5 -0
- package/build/test/fixtures/config/appium.config.security-delimited.json +5 -0
- package/build/test/fixtures/config/appium.config.security-path.json +5 -0
- package/build/test/fixtures/config/driver-fake.config.json +8 -0
- package/build/test/fixtures/config/nodeconfig.json +3 -0
- package/build/test/fixtures/config/plugin-fake.config.json +0 -0
- package/build/test/fixtures/default-args.js +35 -0
- package/build/test/fixtures/deny-feat.txt +5 -0
- package/build/test/fixtures/driver.schema.js +20 -0
- package/build/test/fixtures/extensions.yaml +27 -0
- package/build/test/fixtures/flattened-schema.js +532 -0
- package/build/test/fixtures/plugin.schema.js +20 -0
- package/build/test/fixtures/schema-with-extensions.js +28 -0
- package/build/test/grid-register-specs.js +74 -0
- package/build/test/helpers.js +75 -0
- package/build/test/logger-specs.js +76 -0
- package/build/test/npm-specs.js +20 -0
- package/build/test/parser-specs.js +319 -0
- package/build/test/plugin-e2e-specs.js +316 -0
- package/build/test/schema/arg-spec-specs.js +70 -0
- package/build/test/schema/cli-args-specs.js +408 -0
- package/build/test/schema/schema-specs.js +407 -0
- package/build/test/utils-specs.js +288 -0
- package/index.js +11 -0
- package/lib/appium-config.schema.json +2 -1
- package/lib/appium.js +51 -8
- package/lib/cli/args.js +17 -14
- package/lib/cli/npm.js +68 -6
- package/lib/cli/parser.js +5 -2
- package/lib/config-file.js +9 -12
- package/lib/config.js +104 -56
- package/lib/extension-config.js +1 -1
- package/lib/main.js +94 -40
- package/lib/plugin-config.js +1 -1
- package/lib/plugins.js +2 -0
- package/lib/schema/appium-config-schema.js +1 -0
- package/lib/schema/arg-spec.js +13 -3
- package/lib/schema/cli-args.js +22 -34
- package/lib/schema/keywords.js +20 -4
- package/lib/schema/schema.js +150 -24
- package/lib/utils.js +28 -29
- package/package.json +9 -14
- package/types/types.d.ts +5 -0
- package/build/lib/cli/argparse-actions.js +0 -104
- package/lib/cli/argparse-actions.js +0 -77
|
@@ -0,0 +1,258 @@
|
|
|
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 _sinon = _interopRequireDefault(require("sinon"));
|
|
10
|
+
|
|
11
|
+
var _parser = _interopRequireDefault(require("../lib/cli/parser"));
|
|
12
|
+
|
|
13
|
+
var _config = require("../lib/config");
|
|
14
|
+
|
|
15
|
+
var _logger = _interopRequireDefault(require("../lib/logger"));
|
|
16
|
+
|
|
17
|
+
var _schema = require("../lib/schema/schema");
|
|
18
|
+
|
|
19
|
+
describe('Config', function () {
|
|
20
|
+
let sandbox;
|
|
21
|
+
beforeEach(function () {
|
|
22
|
+
sandbox = _sinon.default.createSandbox();
|
|
23
|
+
});
|
|
24
|
+
afterEach(function () {
|
|
25
|
+
sandbox.restore();
|
|
26
|
+
});
|
|
27
|
+
describe('Appium config', function () {
|
|
28
|
+
let log;
|
|
29
|
+
let dir;
|
|
30
|
+
beforeEach(function () {
|
|
31
|
+
log = sandbox.spy(console, 'log');
|
|
32
|
+
dir = sandbox.spy(console, 'dir');
|
|
33
|
+
});
|
|
34
|
+
describe('showBuildInfo()', function () {
|
|
35
|
+
it('should log build info to console', async function () {
|
|
36
|
+
const config = (0, _config.getBuildInfo)();
|
|
37
|
+
await (0, _config.showBuildInfo)();
|
|
38
|
+
log.should.have.been.calledOnce;
|
|
39
|
+
log.firstCall.args.should.contain(JSON.stringify(config));
|
|
40
|
+
});
|
|
41
|
+
});
|
|
42
|
+
describe('showConfig()', function () {
|
|
43
|
+
describe('when a config file is present', function () {
|
|
44
|
+
it('should dump the current Appium config', function () {
|
|
45
|
+
(0, _config.showConfig)({
|
|
46
|
+
address: 'bar'
|
|
47
|
+
}, {
|
|
48
|
+
config: {
|
|
49
|
+
server: {
|
|
50
|
+
callbackAddress: 'quux'
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
}, {
|
|
54
|
+
port: 1234
|
|
55
|
+
}, {
|
|
56
|
+
allowCors: false
|
|
57
|
+
});
|
|
58
|
+
log.should.have.been.calledWith('Appium Configuration\n');
|
|
59
|
+
});
|
|
60
|
+
it('should skip empty objects', function () {
|
|
61
|
+
(0, _config.showConfig)({
|
|
62
|
+
foo: 'bar',
|
|
63
|
+
cows: {},
|
|
64
|
+
pigs: [],
|
|
65
|
+
sheep: 0,
|
|
66
|
+
ducks: false
|
|
67
|
+
}, {
|
|
68
|
+
config: {
|
|
69
|
+
server: {
|
|
70
|
+
address: 'quux'
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
}, {
|
|
74
|
+
spam: 'food'
|
|
75
|
+
}, {});
|
|
76
|
+
dir.should.have.been.calledWith({
|
|
77
|
+
foo: 'bar',
|
|
78
|
+
sheep: 0,
|
|
79
|
+
ducks: false
|
|
80
|
+
});
|
|
81
|
+
});
|
|
82
|
+
});
|
|
83
|
+
describe('when a config file is not present', function () {
|
|
84
|
+
it('should dump the current Appium config (sans config file contents)', function () {
|
|
85
|
+
(0, _config.showConfig)({
|
|
86
|
+
foo: 'bar',
|
|
87
|
+
cows: {},
|
|
88
|
+
pigs: [],
|
|
89
|
+
sheep: 0,
|
|
90
|
+
ducks: false
|
|
91
|
+
}, {}, {
|
|
92
|
+
spam: 'food'
|
|
93
|
+
}, {});
|
|
94
|
+
log.should.have.been.calledWith('\n(no configuration file loaded)');
|
|
95
|
+
});
|
|
96
|
+
});
|
|
97
|
+
describe('when no CLI arguments (other than --show-config) provided', function () {
|
|
98
|
+
it('should not dump CLI args', function () {
|
|
99
|
+
(0, _config.showConfig)({}, {}, {}, {});
|
|
100
|
+
log.should.have.been.calledWith('\n(no CLI parameters provided)');
|
|
101
|
+
});
|
|
102
|
+
});
|
|
103
|
+
});
|
|
104
|
+
});
|
|
105
|
+
describe('node.js config', function () {
|
|
106
|
+
let _process = process;
|
|
107
|
+
before(function () {
|
|
108
|
+
process = { ...process
|
|
109
|
+
};
|
|
110
|
+
});
|
|
111
|
+
after(function () {
|
|
112
|
+
process = _process;
|
|
113
|
+
});
|
|
114
|
+
describe('checkNodeOk', function () {
|
|
115
|
+
describe('unsupported nodes', function () {
|
|
116
|
+
const unsupportedVersions = ['v0.1', 'v0.9.12', 'v0.10.36', 'v0.12.14', 'v4.4.7', 'v5.7.0', 'v6.3.1', 'v7.1.1', 'v8.0.0', 'v9.2.3', 'v10.1.0'];
|
|
117
|
+
|
|
118
|
+
for (const version of unsupportedVersions) {
|
|
119
|
+
it(`should fail if node is ${version}`, function () {
|
|
120
|
+
process.version = version;
|
|
121
|
+
|
|
122
|
+
_config.checkNodeOk.should.throw();
|
|
123
|
+
});
|
|
124
|
+
}
|
|
125
|
+
});
|
|
126
|
+
describe('supported nodes', function () {
|
|
127
|
+
it('should succeed if node is 12+', function () {
|
|
128
|
+
process.version = 'v12.0.1';
|
|
129
|
+
|
|
130
|
+
_config.checkNodeOk.should.not.throw();
|
|
131
|
+
});
|
|
132
|
+
it('should succeed if node is 13+', function () {
|
|
133
|
+
process.version = 'v13.6.0';
|
|
134
|
+
|
|
135
|
+
_config.checkNodeOk.should.not.throw();
|
|
136
|
+
});
|
|
137
|
+
it('should succeed if node is 14+', function () {
|
|
138
|
+
process.version = 'v14.0.0';
|
|
139
|
+
|
|
140
|
+
_config.checkNodeOk.should.not.throw();
|
|
141
|
+
});
|
|
142
|
+
});
|
|
143
|
+
});
|
|
144
|
+
describe('warnNodeDeprecations', function () {
|
|
145
|
+
let spy;
|
|
146
|
+
before(function () {
|
|
147
|
+
spy = sandbox.spy(_logger.default, 'warn');
|
|
148
|
+
});
|
|
149
|
+
beforeEach(function () {
|
|
150
|
+
spy.resetHistory();
|
|
151
|
+
});
|
|
152
|
+
it('should not log a warning if node is 8+', function () {
|
|
153
|
+
process.version = 'v8.0.0';
|
|
154
|
+
(0, _config.warnNodeDeprecations)();
|
|
155
|
+
|
|
156
|
+
_logger.default.warn.callCount.should.equal(0);
|
|
157
|
+
});
|
|
158
|
+
it('should not log a warning if node is 9+', function () {
|
|
159
|
+
process.version = 'v9.0.0';
|
|
160
|
+
(0, _config.warnNodeDeprecations)();
|
|
161
|
+
|
|
162
|
+
_logger.default.warn.callCount.should.equal(0);
|
|
163
|
+
});
|
|
164
|
+
});
|
|
165
|
+
});
|
|
166
|
+
describe('server arguments', function () {
|
|
167
|
+
let args;
|
|
168
|
+
describe('getNonDefaultServerArgs', function () {
|
|
169
|
+
describe('without extension schemas', function () {
|
|
170
|
+
beforeEach(async function () {
|
|
171
|
+
await (0, _parser.default)(true);
|
|
172
|
+
args = (0, _schema.getDefaultsForSchema)();
|
|
173
|
+
});
|
|
174
|
+
it('should show none if we have all the defaults', function () {
|
|
175
|
+
let nonDefaultArgs = (0, _config.getNonDefaultServerArgs)(args);
|
|
176
|
+
nonDefaultArgs.should.be.empty;
|
|
177
|
+
});
|
|
178
|
+
it('should catch a non-default argument', function () {
|
|
179
|
+
args.allowCors = true;
|
|
180
|
+
let nonDefaultArgs = (0, _config.getNonDefaultServerArgs)(args);
|
|
181
|
+
nonDefaultArgs.should.eql({
|
|
182
|
+
allowCors: true
|
|
183
|
+
});
|
|
184
|
+
});
|
|
185
|
+
describe('when arg is an array', function () {
|
|
186
|
+
it('should return the arg as an array', function () {
|
|
187
|
+
args.usePlugins = ['all'];
|
|
188
|
+
(0, _config.getNonDefaultServerArgs)(args).should.eql({
|
|
189
|
+
usePlugins: ['all']
|
|
190
|
+
});
|
|
191
|
+
});
|
|
192
|
+
});
|
|
193
|
+
});
|
|
194
|
+
describe('with extension schemas', function () {
|
|
195
|
+
beforeEach(async function () {
|
|
196
|
+
(0, _schema.resetSchema)();
|
|
197
|
+
(0, _schema.registerSchema)('plugin', 'crypto-fiend', {
|
|
198
|
+
type: 'object',
|
|
199
|
+
properties: {
|
|
200
|
+
elite: {
|
|
201
|
+
type: 'boolean',
|
|
202
|
+
default: true
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
});
|
|
206
|
+
(0, _schema.finalizeSchema)();
|
|
207
|
+
await (0, _parser.default)(true);
|
|
208
|
+
args = (0, _schema.getDefaultsForSchema)();
|
|
209
|
+
});
|
|
210
|
+
it('should take extension schemas into account', function () {
|
|
211
|
+
const nonDefaultArgs = (0, _config.getNonDefaultServerArgs)(args);
|
|
212
|
+
nonDefaultArgs.should.be.empty;
|
|
213
|
+
});
|
|
214
|
+
it('should catch a non-default argument', function () {
|
|
215
|
+
args['plugin.crypto-fiend.elite'] = false;
|
|
216
|
+
const nonDefaultArgs = (0, _config.getNonDefaultServerArgs)(args);
|
|
217
|
+
nonDefaultArgs.should.eql(_lodash.default.set({}, 'plugin.crypto-fiend.elite', false));
|
|
218
|
+
});
|
|
219
|
+
});
|
|
220
|
+
});
|
|
221
|
+
});
|
|
222
|
+
describe('validateTmpDir', function () {
|
|
223
|
+
it('should fail to use a tmp dir with incorrect permissions', function () {
|
|
224
|
+
(0, _config.validateTmpDir)('/private/if_you_run_with_sudo_this_wont_fail').should.be.rejectedWith(/could not ensure/);
|
|
225
|
+
});
|
|
226
|
+
it('should fail to use an undefined tmp dir', function () {
|
|
227
|
+
(0, _config.validateTmpDir)().should.be.rejectedWith(/could not ensure/);
|
|
228
|
+
});
|
|
229
|
+
it('should be able to use a tmp dir with correct permissions', function () {
|
|
230
|
+
(0, _config.validateTmpDir)('/tmp/test_tmp_dir/with/any/number/of/levels').should.not.be.rejected;
|
|
231
|
+
});
|
|
232
|
+
});
|
|
233
|
+
describe('parsing args with empty argv[1]', function () {
|
|
234
|
+
let argv1;
|
|
235
|
+
before(function () {
|
|
236
|
+
argv1 = process.argv[1];
|
|
237
|
+
});
|
|
238
|
+
beforeEach(function () {
|
|
239
|
+
(0, _schema.resetSchema)();
|
|
240
|
+
});
|
|
241
|
+
after(function () {
|
|
242
|
+
process.argv[1] = argv1;
|
|
243
|
+
});
|
|
244
|
+
it('should not fail if process.argv[1] is undefined', async function () {
|
|
245
|
+
delete process.argv[1];
|
|
246
|
+
let args = await (0, _parser.default)();
|
|
247
|
+
args.prog.should.be.equal('appium');
|
|
248
|
+
});
|
|
249
|
+
it('should set "prog" to process.argv[1]', async function () {
|
|
250
|
+
process.argv[1] = 'Hello World';
|
|
251
|
+
let args = await (0, _parser.default)();
|
|
252
|
+
args.prog.should.be.equal('Hello World');
|
|
253
|
+
});
|
|
254
|
+
});
|
|
255
|
+
});require('source-map-support').install();
|
|
256
|
+
|
|
257
|
+
|
|
258
|
+
//# sourceMappingURL=data:application/json;charset=utf8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbInRlc3QvY29uZmlnLXNwZWNzLmpzIl0sIm5hbWVzIjpbImRlc2NyaWJlIiwic2FuZGJveCIsImJlZm9yZUVhY2giLCJzaW5vbiIsImNyZWF0ZVNhbmRib3giLCJhZnRlckVhY2giLCJyZXN0b3JlIiwibG9nIiwiZGlyIiwic3B5IiwiY29uc29sZSIsIml0IiwiY29uZmlnIiwic2hvdWxkIiwiaGF2ZSIsImJlZW4iLCJjYWxsZWRPbmNlIiwiZmlyc3RDYWxsIiwiYXJncyIsImNvbnRhaW4iLCJKU09OIiwic3RyaW5naWZ5IiwiYWRkcmVzcyIsInNlcnZlciIsImNhbGxiYWNrQWRkcmVzcyIsInBvcnQiLCJhbGxvd0NvcnMiLCJjYWxsZWRXaXRoIiwiZm9vIiwiY293cyIsInBpZ3MiLCJzaGVlcCIsImR1Y2tzIiwic3BhbSIsIl9wcm9jZXNzIiwicHJvY2VzcyIsImJlZm9yZSIsImFmdGVyIiwidW5zdXBwb3J0ZWRWZXJzaW9ucyIsInZlcnNpb24iLCJjaGVja05vZGVPayIsInRocm93Iiwibm90IiwibG9nZ2VyIiwicmVzZXRIaXN0b3J5Iiwid2FybiIsImNhbGxDb3VudCIsImVxdWFsIiwibm9uRGVmYXVsdEFyZ3MiLCJiZSIsImVtcHR5IiwiZXFsIiwidXNlUGx1Z2lucyIsInR5cGUiLCJwcm9wZXJ0aWVzIiwiZWxpdGUiLCJkZWZhdWx0IiwiXyIsInNldCIsInJlamVjdGVkV2l0aCIsInJlamVjdGVkIiwiYXJndjEiLCJhcmd2IiwicHJvZyJdLCJtYXBwaW5ncyI6Ijs7Ozs7O0FBR0E7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBRUFBLFFBQVEsQ0FBQyxRQUFELEVBQVcsWUFBWTtBQUU3QixNQUFJQyxPQUFKO0FBRUFDLEVBQUFBLFVBQVUsQ0FBQyxZQUFZO0FBQ3JCRCxJQUFBQSxPQUFPLEdBQUdFLGVBQU1DLGFBQU4sRUFBVjtBQUNELEdBRlMsQ0FBVjtBQUlBQyxFQUFBQSxTQUFTLENBQUMsWUFBWTtBQUNwQkosSUFBQUEsT0FBTyxD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QSxVQUFVLENBQUMsWUFBWTtBQUNyQjtBQUNELEtBRlMsQ0FBVjtBQUlBbUMsSUFBQUEsS0FBSyxDQUFDLFlBQVk7QUFDaEJGLE1BQUFBLE9BQU8sQ0FBQzJCLElBQVIsQ0FBYSxDQUFiLElBQWtCRCxLQUFsQjtBQUNELEtBRkksQ0FBTDtBQUlBbEQsSUFBQUEsRUFBRSxDQUFDLGlEQUFELEVBQW9ELGtCQUFrQjtBQUN0RSxhQUFPd0IsT0FBTyxDQUFDMkIsSUFBUixDQUFhLENBQWIsQ0FBUDtBQUNBLFVBQUk1QyxJQUFJLEdBQUcsTUFBTSxzQkFBakI7QUFDQUEsTUFBQUEsSUFBSSxDQUFDNkMsSUFBTCxDQUFVbEQsTUFBVixDQUFpQm9DLEVBQWpCLENBQW9CRixLQUFwQixDQUEwQixRQUExQjtBQUNELEtBSkMsQ0FBRjtBQU1BcEMsSUFBQUEsRUFBRSxDQUFDLHNDQUFELEVBQXlDLGtCQUFrQjtBQUMzRHdCLE1BQUFBLE9BQU8sQ0FBQzJCLElBQVIsQ0FBYSxDQUFiLElBQWtCLGFBQWxCO0FBQ0EsVUFBSTVDLElBQUksR0FBRyxNQUFNLHNCQUFqQjtBQUNBQSxNQUFBQSxJQUFJLENBQUM2QyxJQUFMLENBQVVsRCxNQUFWLENBQWlCb0MsRUFBakIsQ0FBb0JGLEtBQXBCLENBQTBCLGFBQTFCO0FBQ0QsS0FKQyxDQUFGO0FBS0QsR0ExQk8sQ0FBUjtBQTRCRCxDQWhQTyxDQUFSIiwic291cmNlc0NvbnRlbnQiOlsiLy8gQHRzLWNoZWNrXG5cbi8vIHRyYW5zcGlsZTptb2NoYVxuaW1wb3J0IF8gZnJvbSAnbG9kYXNoJztcbmltcG9ydCBzaW5vbiBmcm9tICdzaW5vbic7XG5pbXBvcnQgZ2V0UGFyc2VyIGZyb20gJy4uL2xpYi9jbGkvcGFyc2VyJztcbmltcG9ydCB7IGNoZWNrTm9kZU9rLCBnZXRCdWlsZEluZm8sIGdldE5vbkRlZmF1bHRTZXJ2ZXJBcmdzLCBzaG93QnVpbGRJbmZvLCBzaG93Q29uZmlnLCB2YWxpZGF0ZVRtcERpciwgd2Fybk5vZGVEZXByZWNhdGlvbnMgfSBmcm9tICcuLi9saWIvY29uZmlnJztcbmltcG9ydCBsb2dnZXIgZnJvbSAnLi4vbGliL2xvZ2dlcic7XG5pbXBvcnQgeyBnZXREZWZhdWx0c0ZvclNjaGVtYSwgcmVzZXRTY2hlbWEsIHJlZ2lzdGVyU2NoZW1hLCBmaW5hbGl6ZVNjaGVtYSB9IGZyb20gJy4uL2xpYi9zY2hlbWEvc2NoZW1hJztcblxuZGVzY3JpYmUoJ0NvbmZpZycsIGZ1bmN0aW9uICgpIHtcbiAgLyoqIEB0eXBlIHtpbXBvcnQoJ3Npbm9uJykuU2lub25TYW5kYm94fSAqL1xuICBsZXQgc2FuZGJveDtcblxuICBiZWZvcmVFYWNoKGZ1bmN0aW9uICgpIHtcbiAgICBzYW5kYm94ID0gc2lub24uY3JlYXRlU2FuZGJveCgpO1xuICB9KTtcblxuICBhZnRlckVhY2goZnVuY3Rpb24gKCkge1xuICAgIHNhbmRib3gucmVzdG9yZSgpO1xuICB9KTtcblxuICBkZXNjcmliZSgnQXBwaXVtIGNvbmZpZycsIGZ1bmN0aW9uICgpIHtcbiAgICAvKiogQHR5cGUge2ltcG9ydCgnc2lub24nKS5TaW5vblNweTxbbWVzc2FnZT86IGFueSwgLi4uZXh0cmE6IGFueVtdXSx2b2lkPn0gKi9cbiAgICBsZXQgbG9nO1xuICAgIC8qKiBAdHlwZSB7aW1wb3J0KCdzaW5vbicpLlNpbm9uU3B5PFttZXNzYWdlPzogYW55LCAuLi5leHRyYTogYW55W11dLHZvaWQ+fSAqL1xuICAgIGxldCBkaXI7XG4gICAgYmVmb3JlRWFjaChmdW5jdGlvbiAoKSB7XG4gICAgICBsb2cgPSBzYW5kYm94LnNweShjb25zb2xlLCAnbG9nJyk7XG4gICAgICBkaXIgPSBzYW5kYm94LnNweShjb25zb2xlLCAnZGlyJyk7XG4gICAgfSk7XG5cbiAgICBkZXNjcmliZSgnc2hvd0J1aWxkSW5mbygpJywgZnVuY3Rpb24gKCkge1xuICAgICAgaXQoJ3Nob3VsZCBsb2cgYnVpbGQgaW5mbyB0byBjb25zb2xlJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgICBjb25zdCBjb25maWcgPSBnZXRCdWlsZEluZm8oKTtcbiAgICAgICAgYXdhaXQgc2hvd0J1aWxkSW5mbygpO1xuICAgICAgICBsb2cuc2hvdWxkLmhhdmUuYmVlbi5jYWxsZWRPbmNlO1xuICAgICAgICBsb2cuZmlyc3RDYWxsLmFyZ3Muc2hvdWxkLmNvbnRhaW4oSlNPTi5zdHJpbmdpZnkoY29uZmlnKSk7XG4gICAgICB9KTtcbiAgICB9KTtcblxuICAgIGRlc2NyaWJlKCdzaG93Q29uZmlnKCknLCBmdW5jdGlvbiAoKSB7XG4gICAgICBkZXNjcmliZSgnd2hlbiBhIGNvbmZpZyBmaWxlIGlzIHByZXNlbnQnLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGl0KCdzaG91bGQgZHVtcCB0aGUgY3VycmVudCBBcHBpdW0gY29uZmlnJywgZnVuY3Rpb24gKCkge1xuICAgICAgICAgIHNob3dDb25maWcoXG4gICAgICAgICAgICB7YWRkcmVzczogJ2Jhcid9LFxuICAgICAgICAgICAge2NvbmZpZzoge1xuICAgICAgICAgICAgICAvLyBAdHMtZXhwZWN0LWVycm9yXG4gICAgICAgICAgICAgIHNlcnZlcjoge2NhbGxiYWNrQWRkcmVzczogJ3F1dXgnfX1cbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICB7cG9ydDogMTIzNH0sXG4gICAgICAgICAgICB7YWxsb3dDb3JzOiBmYWxzZX1cbiAgICAgICAgICApO1xuICAgICAgICAgIGxvZy5zaG91bGQuaGF2ZS5iZWVuLmNhbGxlZFdpdGgoJ0FwcGl1bSBDb25maWd1cmF0aW9uXFxuJyk7XG4gICAgICAgIH0pO1xuXG4gICAgICAgIGl0KCdzaG91bGQgc2tpcCBlbXB0eSBvYmplY3RzJywgZnVuY3Rpb24gKCkge1xuICAgICAgICAgIHNob3dDb25maWcoXG4gICAgICAgICAgICAvLyBAdHMtZXhwZWN0LWVycm9yXG4gICAgICAgICAgICB7Zm9vOiAnYmFyJywgY293czoge30sIHBpZ3M6IFtdLCBzaGVlcDogMCwgZHVja3M6IGZhbHNlfSxcbiAgICAgICAgICAgIHtjb25maWc6IHtzZXJ2ZXI6IHthZGRyZXNzOiAncXV1eCd9fX0sXG4gICAgICAgICAgICB7c3BhbTogJ2Zvb2QnfSxcbiAgICAgICAgICAgIHt9XG4gICAgICAgICAgKTtcbiAgICAgICAgICBkaXIuc2hvdWxkLmhhdmUuYmVlbi5jYWxsZWRXaXRoKHtmb286ICdiYXInLCBzaGVlcDogMCwgZHVja3M6IGZhbHNlfSk7XG4gICAgICAgIH0pO1xuICAgICAgfSk7XG5cbiAgICAgIGRlc2NyaWJlKCd3aGVuIGEgY29uZmlnIGZpbGUgaXMgbm90IHByZXNlbnQnLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGl0KCdzaG91bGQgZHVtcCB0aGUgY3VycmVudCBBcHBpdW0gY29uZmlnIChzYW5zIGNvbmZpZyBmaWxlIGNvbnRlbnRzKScsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICBzaG93Q29uZmlnKFxuICAgICAgICAgICAgLy8gQHRzLWV4cGVjdC1lcnJvclxuICAgICAgICAgICAge2ZvbzogJ2JhcicsIGNvd3M6IHt9LCBwaWdzOiBbXSwgc2hlZXA6IDAsIGR1Y2tzOiBmYWxzZX0sXG4gICAgICAgICAgICB7fSxcbiAgICAgICAgICAgIHtzcGFtOiAnZm9vZCd9LFxuICAgICAgICAgICAge31cbiAgICAgICAgICApO1xuICAgICAgICAgIGxvZy5zaG91bGQuaGF2ZS5iZWVuLmNhbGxlZFdpdGgoJ1xcbihubyBjb25maWd1cmF0aW9uIGZpbGUgbG9hZGVkKScpO1xuICAgICAgICB9KTtcbiAgICAgIH0pO1xuXG4gICAgICBkZXNjcmliZSgnd2hlbiBubyBDTEkgYXJndW1lbnRzIChvdGhlciB0aGFuIC0tc2hvdy1jb25maWcpIHByb3ZpZGVkJywgZnVuY3Rpb24gKCkge1xuICAgICAgICBpdCgnc2hvdWxkIG5vdCBkdW1wIENMSSBhcmdzJywgZnVuY3Rpb24gKCkge1xuICAgICAgICAgIC8vIEB0cy1leHBlY3QtZXJyb3JcbiAgICAgICAgICBzaG93Q29uZmlnKHt9LCB7fSwge30sIHt9KTtcbiAgICAgICAgICBsb2cuc2hvdWxkLmhhdmUuYmVlbi5jYWxsZWRXaXRoKCdcXG4obm8gQ0xJIHBhcmFtZXRlcnMgcHJvdmlkZWQpJyk7XG4gICAgICAgIH0pO1xuICAgICAgfSk7XG4gICAgfSk7XG4gIH0pO1xuXG4gIGRlc2NyaWJlKCdub2RlLmpzIGNvbmZpZycsIGZ1bmN0aW9uICgpIHtcbiAgICBsZXQgX3Byb2Nlc3MgPSBwcm9jZXNzO1xuICAgIGJlZm9yZShmdW5jdGlvbiAoKSB7XG4gICAgICAvLyBuZWVkIHRvIGJlIGFibGUgdG8gd3JpdGUgdG8gcHJvY2Vzcy52ZXJzaW9uXG4gICAgICAvLyBidXQgYWxzbyB0byBoYXZlIGFjY2VzcyB0byBwcm9jZXNzIG1ldGhvZHNcbiAgICAgIC8vIHNvIGNvcHkgdGhlbSBvdmVyIHRvIGEgd3JpdGFibGUgb2JqZWN0XG4gICAgICBwcm9jZXNzID0gey4uLnByb2Nlc3N9OyAvLyBlc2xpbnQtZGlzYWJsZS1saW5lIG5vLWdsb2JhbC1hc3NpZ25cbiAgICB9KTtcbiAgICBhZnRlcihmdW5jdGlvbiAoKSB7XG4gICAgICBwcm9jZXNzID0gX3Byb2Nlc3M7IC8vIGVzbGludC1kaXNhYmxlLWxpbmUgbm8tZ2xvYmFsLWFzc2lnblxuICAgIH0pO1xuICAgIGRlc2NyaWJlKCdjaGVja05vZGVPaycsIGZ1bmN0aW9uICgpIHtcbiAgICAgIGRlc2NyaWJlKCd1bnN1cHBvcnRlZCBub2RlcycsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgY29uc3QgdW5zdXBwb3J0ZWRWZXJzaW9ucyA9IFtcbiAgICAgICAgICAndjAuMScsICd2MC45LjEyJywgJ3YwLjEwLjM2JywgJ3YwLjEyLjE0JyxcbiAgICAgICAgICAndjQuNC43JywgJ3Y1LjcuMCcsICd2Ni4zLjEnLCAndjcuMS4xJyxcbiAgICAgICAgICAndjguMC4wJywgJ3Y5LjIuMycsICd2MTAuMS4wJyxcbiAgICAgICAgXTtcbiAgICAgICAgZm9yIChjb25zdCB2ZXJzaW9uIG9mIHVuc3VwcG9ydGVkVmVyc2lvbnMpIHtcbiAgICAgICAgICBpdChgc2hvdWxkIGZhaWwgaWYgbm9kZSBpcyAke3ZlcnNpb259YCwgZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgLy8gQHRzLWV4cGVjdC1lcnJvclxuICAgICAgICAgICAgcHJvY2Vzcy52ZXJzaW9uID0gdmVyc2lvbjtcbiAgICAgICAgICAgIGNoZWNrTm9kZU9rLnNob3VsZC50aHJvdygpO1xuICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgICB9KTtcblxuICAgICAgZGVzY3JpYmUoJ3N1cHBvcnRlZCBub2RlcycsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgaXQoJ3Nob3VsZCBzdWNjZWVkIGlmIG5vZGUgaXMgMTIrJywgZnVuY3Rpb24gKCkge1xuICAgICAgICAgIC8vIEB0cy1leHBlY3QtZXJyb3JcbiAgICAgICAgICBwcm9jZXNzLnZlcnNpb24gPSAndjEyLjAuMSc7XG4gICAgICAgICAgY2hlY2tOb2RlT2suc2hvdWxkLm5vdC50aHJvdygpO1xuICAgICAgICB9KTtcbiAgICAgICAgaXQoJ3Nob3VsZCBzdWNjZWVkIGlmIG5vZGUgaXMgMTMrJywgZnVuY3Rpb24gKCkge1xuICAgICAgICAgIC8vIEB0cy1leHBlY3QtZXJyb3JcbiAgICAgICAgICBwcm9jZXNzLnZlcnNpb24gPSAndjEzLjYuMCc7XG4gICAgICAgICAgY2hlY2tOb2RlT2suc2hvdWxkLm5vdC50aHJvdygpO1xuICAgICAgICB9KTtcbiAgICAgICAgaXQoJ3Nob3VsZCBzdWNjZWVkIGlmIG5vZGUgaXMgMTQrJywgZnVuY3Rpb24gKCkge1xuICAgICAgICAgIC8vIEB0cy1leHBlY3QtZXJyb3JcbiAgICAgICAgICBwcm9jZXNzLnZlcnNpb24gPSAndjE0LjAuMCc7XG4gICAgICAgICAgY2hlY2tOb2RlT2suc2hvdWxkLm5vdC50aHJvdygpO1xuICAgICAgICB9KTtcbiAgICAgIH0pO1xuICAgIH0pO1xuXG4gICAgZGVzY3JpYmUoJ3dhcm5Ob2RlRGVwcmVjYXRpb25zJywgZnVuY3Rpb24gKCkge1xuICAgICAgbGV0IHNweTtcbiAgICAgIGJlZm9yZShmdW5jdGlvbiAoKSB7XG4gICAgICAgIHNweSA9IHNhbmRib3guc3B5KGxvZ2dlciwgJ3dhcm4nKTtcbiAgICAgIH0pO1xuICAgICAgYmVmb3JlRWFjaChmdW5jdGlvbiAoKSB7XG4gICAgICAgIHNweS5yZXNldEhpc3RvcnkoKTtcbiAgICAgIH0pO1xuICAgICAgaXQoJ3Nob3VsZCBub3QgbG9nIGEgd2FybmluZyBpZiBub2RlIGlzIDgrJywgZnVuY3Rpb24gKCkge1xuICAgICAgICAvLyBAdHMtZXhwZWN0LWVycm9yXG4gICAgICAgIHByb2Nlc3MudmVyc2lvbiA9ICd2OC4wLjAnO1xuICAgICAgICB3YXJuTm9kZURlcHJlY2F0aW9ucygpO1xuICAgICAgICBsb2dnZXIud2Fybi5jYWxsQ291bnQuc2hvdWxkLmVxdWFsKDApO1xuICAgICAgfSk7XG4gICAgICBpdCgnc2hvdWxkIG5vdCBsb2cgYSB3YXJuaW5nIGlmIG5vZGUgaXMgOSsnLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgIC8vIEB0cy1leHBlY3QtZXJyb3JcbiAgICAgICAgcHJvY2Vzcy52ZXJzaW9uID0gJ3Y5LjAuMCc7XG4gICAgICAgIHdhcm5Ob2RlRGVwcmVjYXRpb25zKCk7XG4gICAgICAgIGxvZ2dlci53YXJuLmNhbGxDb3VudC5zaG91bGQuZXF1YWwoMCk7XG4gICAgICB9KTtcbiAgICB9KTtcbiAgfSk7XG5cbiAgZGVzY3JpYmUoJ3NlcnZlciBhcmd1bWVudHMnLCBmdW5jdGlvbiAoKSB7XG4gICAgbGV0IGFyZ3M7XG5cbiAgICBkZXNjcmliZSgnZ2V0Tm9uRGVmYXVsdFNlcnZlckFyZ3MnLCBmdW5jdGlvbiAoKSB7XG4gICAgICBkZXNjcmliZSgnd2l0aG91dCBleHRlbnNpb24gc2NoZW1hcycsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgYmVmb3JlRWFjaChhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgYXdhaXQgZ2V0UGFyc2VyKHRydWUpO1xuICAgICAgICAgIC8vIGdldCBhbGwgdGhlIGRlZmF1bHRzXG4gICAgICAgICAgYXJncyA9IGdldERlZmF1bHRzRm9yU2NoZW1hKCk7XG4gICAgICAgIH0pO1xuICAgICAgICBpdCgnc2hvdWxkIHNob3cgbm9uZSBpZiB3ZSBoYXZlIGFsbCB0aGUgZGVmYXVsdHMnLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgbGV0IG5vbkRlZmF1bHRBcmdzID0gZ2V0Tm9uRGVmYXVsdFNlcnZlckFyZ3MoYXJncyk7XG4gICAgICAgICAgbm9uRGVmYXVsdEFyZ3Muc2hvdWxkLmJlLmVtcHR5O1xuICAgICAgICB9KTtcbiAgICAgICAgaXQoJ3Nob3VsZCBjYXRjaCBhIG5vbi1kZWZhdWx0IGFyZ3VtZW50JywgZnVuY3Rpb24gKCkge1xuICAgICAgICAgIGFyZ3MuYWxsb3dDb3JzID0gdHJ1ZTtcbiAgICAgICAgICBsZXQgbm9uRGVmYXVsdEFyZ3MgPSBnZXROb25EZWZhdWx0U2VydmVyQXJncyhhcmdzKTtcbiAgICAgICAgICBub25EZWZhdWx0QXJncy5zaG91bGQuZXFsKHthbGxvd0NvcnM6IHRydWV9KTtcbiAgICAgICAgfSk7XG4gICAgICAgIGRlc2NyaWJlKCd3aGVuIGFyZyBpcyBhbiBhcnJheScsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICBpdCgnc2hvdWxkIHJldHVybiB0aGUgYXJnIGFzIGFuIGFycmF5JywgZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgYXJncy51c2VQbHVnaW5zID0gWydhbGwnXTtcbiAgICAgICAgICAgIGdldE5vbkRlZmF1bHRTZXJ2ZXJBcmdzKGFyZ3MpLnNob3VsZC5lcWwoe3VzZVBsdWdpbnM6IFsnYWxsJ119KTtcbiAgICAgICAgICB9KTtcbiAgICAgICAgfSk7XG4gICAgICB9KTtcbiAgICAgIGRlc2NyaWJlKCd3aXRoIGV4dGVuc2lvbiBzY2hlbWFzJywgZnVuY3Rpb24gKCkge1xuICAgICAgICBiZWZvcmVFYWNoKGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICByZXNldFNjaGVtYSgpO1xuICAgICAgICAgIHJlZ2lzdGVyU2NoZW1hKCdwbHVnaW4nLCAnY3J5cHRvLWZpZW5kJywge3R5cGU6ICdvYmplY3QnLCBwcm9wZXJ0aWVzOiB7ZWxpdGU6IHt0eXBlOiAnYm9vbGVhbicsIGRlZmF1bHQ6IHRydWV9fX0pO1xuICAgICAgICAgIGZpbmFsaXplU2NoZW1hKCk7XG4gICAgICAgICAgYXdhaXQgZ2V0UGFyc2VyKHRydWUpO1xuICAgICAgICAgIGFyZ3MgPSBnZXREZWZhdWx0c0ZvclNjaGVtYSgpO1xuICAgICAgICB9KTtcblxuICAgICAgICBpdCgnc2hvdWxkIHRha2UgZXh0ZW5zaW9uIHNjaGVtYXMgaW50byBhY2NvdW50JywgZnVuY3Rpb24gKCkge1xuICAgICAgICAgIGNvbnN0IG5vbkRlZmF1bHRBcmdzID0gZ2V0Tm9uRGVmYXVsdFNlcnZlckFyZ3MoYXJncyk7XG4gICAgICAgICAgbm9uRGVmYXVsdEFyZ3Muc2hvdWxkLmJlLmVtcHR5O1xuICAgICAgICB9KTtcblxuICAgICAgICBpdCgnc2hvdWxkIGNhdGNoIGEgbm9uLWRlZmF1bHQgYXJndW1lbnQnLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgYXJnc1sncGx1Z2luLmNyeXB0by1maWVuZC5lbGl0ZSddID0gZmFsc2U7XG4gICAgICAgICAgY29uc3Qgbm9uRGVmYXVsdEFyZ3MgPSBnZXROb25EZWZhdWx0U2VydmVyQXJncyhhcmdzKTtcbiAgICAgICAgICBub25EZWZhdWx0QXJncy5zaG91bGQuZXFsKF8uc2V0KHt9LCAncGx1Z2luLmNyeXB0by1maWVuZC5lbGl0ZScsIGZhbHNlKSk7XG4gICAgICAgIH0pO1xuICAgICAgfSk7XG4gICAgfSk7XG4gIH0pO1xuXG4gIGRlc2NyaWJlKCd2YWxpZGF0ZVRtcERpcicsIGZ1bmN0aW9uICgpIHtcbiAgICBpdCgnc2hvdWxkIGZhaWwgdG8gdXNlIGEgdG1wIGRpciB3aXRoIGluY29ycmVjdCBwZXJtaXNzaW9ucycsIGZ1bmN0aW9uICgpIHtcbiAgICAgIHZhbGlkYXRlVG1wRGlyKCcvcHJpdmF0ZS9pZl95b3VfcnVuX3dpdGhfc3Vkb190aGlzX3dvbnRfZmFpbCcpLnNob3VsZC5iZS5yZWplY3RlZFdpdGgoL2NvdWxkIG5vdCBlbnN1cmUvKTtcbiAgICB9KTtcbiAgICBpdCgnc2hvdWxkIGZhaWwgdG8gdXNlIGFuIHVuZGVmaW5lZCB0bXAgZGlyJywgZnVuY3Rpb24gKCkge1xuICAgICAgLy8gQHRzLWV4cGVjdC1lcnJvclxuICAgICAgdmFsaWRhdGVUbXBEaXIoKS5zaG91bGQuYmUucmVqZWN0ZWRXaXRoKC9jb3VsZCBub3QgZW5zdXJlLyk7XG4gICAgfSk7XG4gICAgaXQoJ3Nob3VsZCBiZSBhYmxlIHRvIHVzZSBhIHRtcCBkaXIgd2l0aCBjb3JyZWN0IHBlcm1pc3Npb25zJywgZnVuY3Rpb24gKCkge1xuICAgICAgdmFsaWRhdGVUbXBEaXIoJy90bXAvdGVzdF90bXBfZGlyL3dpdGgvYW55L251bWJlci9vZi9sZXZlbHMnKS5zaG91bGQubm90LmJlLnJlamVjdGVkO1xuICAgIH0pO1xuICB9KTtcblxuICBkZXNjcmliZSgncGFyc2luZyBhcmdzIHdpdGggZW1wdHkgYXJndlsxXScsIGZ1bmN0aW9uICgpIHtcbiAgICBsZXQgYXJndjE7XG5cbiAgICBiZWZvcmUoZnVuY3Rpb24gKCkge1xuICAgICAgYXJndjEgPSBwcm9jZXNzLmFyZ3ZbMV07XG4gICAgfSk7XG5cbiAgICBiZWZvcmVFYWNoKGZ1bmN0aW9uICgpIHtcbiAgICAgIHJlc2V0U2NoZW1hKCk7XG4gICAgfSk7XG5cbiAgICBhZnRlcihmdW5jdGlvbiAoKSB7XG4gICAgICBwcm9jZXNzLmFyZ3ZbMV0gPSBhcmd2MTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgbm90IGZhaWwgaWYgcHJvY2Vzcy5hcmd2WzFdIGlzIHVuZGVmaW5lZCcsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGRlbGV0ZSBwcm9jZXNzLmFyZ3ZbMV07XG4gICAgICBsZXQgYXJncyA9IGF3YWl0IGdldFBhcnNlcigpO1xuICAgICAgYXJncy5wcm9nLnNob3VsZC5iZS5lcXVhbCgnYXBwaXVtJyk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHNldCBcInByb2dcIiB0byBwcm9jZXNzLmFyZ3ZbMV0nLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBwcm9jZXNzLmFyZ3ZbMV0gPSAnSGVsbG8gV29ybGQnO1xuICAgICAgbGV0IGFyZ3MgPSBhd2FpdCBnZXRQYXJzZXIoKTtcbiAgICAgIGFyZ3MucHJvZy5zaG91bGQuYmUuZXF1YWwoJ0hlbGxvIFdvcmxkJyk7XG4gICAgfSk7XG4gIH0pO1xuXG59KTtcbiJdLCJmaWxlIjoidGVzdC9jb25maWctc3BlY3MuanMiLCJzb3VyY2VSb290IjoiLi4vLi4ifQ==
|