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.
- package/README.md +1 -2
- package/build/lib/appium-config.schema.json +278 -0
- package/build/lib/appium.js +62 -71
- package/build/lib/cli/args.js +31 -53
- package/build/lib/cli/driver-command.js +5 -9
- package/build/lib/cli/extension-command.js +73 -64
- package/build/lib/cli/extension.js +10 -23
- package/build/lib/cli/parser.js +10 -20
- package/build/lib/cli/plugin-command.js +5 -9
- package/build/lib/cli/utils.js +2 -4
- package/build/lib/config-file.js +5 -10
- package/build/lib/config.js +67 -30
- package/build/lib/constants.js +60 -0
- package/build/lib/extension/driver-config.js +190 -0
- package/build/lib/extension/extension-config.js +297 -0
- package/build/lib/extension/index.js +77 -0
- package/build/lib/extension/manifest.js +246 -0
- package/build/lib/extension/package-changed.js +68 -0
- package/build/lib/extension/plugin-config.js +87 -0
- package/build/lib/grid-register.js +2 -4
- package/build/lib/logger.js +2 -4
- package/build/lib/logsink.js +2 -4
- package/build/lib/main.js +64 -92
- package/build/lib/schema/appium-config-schema.js +2 -4
- package/build/lib/schema/arg-spec.js +14 -15
- package/build/lib/schema/cli-args.js +8 -16
- package/build/lib/schema/cli-transformers.js +2 -4
- package/build/lib/schema/index.js +2 -4
- package/build/lib/schema/keywords.js +2 -4
- package/build/lib/schema/schema.js +136 -41
- package/build/lib/utils.js +13 -64
- package/lib/appium.js +74 -55
- package/lib/cli/args.js +36 -37
- package/lib/cli/driver-command.js +10 -2
- package/lib/cli/extension-command.js +216 -135
- package/lib/cli/extension.js +7 -15
- package/lib/cli/parser.js +7 -15
- package/lib/cli/plugin-command.js +1 -2
- package/lib/config-file.js +12 -15
- package/lib/config.js +111 -36
- package/lib/constants.js +79 -0
- package/lib/extension/driver-config.js +230 -0
- package/lib/extension/extension-config.js +459 -0
- package/lib/extension/index.js +103 -0
- package/lib/extension/manifest.js +590 -0
- package/lib/extension/package-changed.js +64 -0
- package/lib/extension/plugin-config.js +111 -0
- package/lib/grid-register.js +4 -4
- package/lib/main.js +110 -96
- package/lib/schema/arg-spec.js +11 -5
- package/lib/schema/cli-args.js +7 -30
- package/lib/schema/keywords.js +1 -1
- package/lib/schema/schema.js +206 -48
- package/lib/utils.js +27 -58
- package/package.json +29 -21
- package/{postinstall.js → scripts/postinstall.js} +1 -1
- package/types/types.d.ts +72 -28
- package/bin/ios-webkit-debug-proxy-launcher.js +0 -71
- package/build/check-npm-pack-files.js +0 -23
- package/build/commands-yml/parse.js +0 -319
- package/build/commands-yml/validator.js +0 -130
- package/build/index.js +0 -19
- package/build/lib/cli/npm.js +0 -220
- package/build/lib/driver-config.js +0 -100
- package/build/lib/drivers.js +0 -100
- package/build/lib/ext-config-io.js +0 -165
- package/build/lib/extension-config.js +0 -320
- package/build/lib/plugin-config.js +0 -69
- package/build/lib/plugins.js +0 -16
- package/build/postinstall.js +0 -90
- package/build/test/cli/cli-e2e-specs.js +0 -221
- package/build/test/cli/cli-helpers.js +0 -86
- package/build/test/cli/cli-specs.js +0 -71
- package/build/test/cli/fixtures/test-driver/package.json +0 -27
- package/build/test/cli/schema-args-specs.js +0 -48
- package/build/test/cli/schema-e2e-specs.js +0 -47
- package/build/test/config-e2e-specs.js +0 -112
- package/build/test/config-file-e2e-specs.js +0 -209
- package/build/test/config-file-specs.js +0 -281
- package/build/test/config-specs.js +0 -159
- package/build/test/driver-e2e-specs.js +0 -435
- package/build/test/driver-specs.js +0 -321
- package/build/test/ext-config-io-specs.js +0 -181
- package/build/test/extension-config-specs.js +0 -365
- package/build/test/fixtures/allow-feat.txt +0 -5
- package/build/test/fixtures/caps.json +0 -3
- package/build/test/fixtures/config/allow-insecure.txt +0 -3
- package/build/test/fixtures/config/appium.config.bad-nodeconfig.json +0 -5
- package/build/test/fixtures/config/appium.config.bad.json +0 -32
- package/build/test/fixtures/config/appium.config.ext-good.json +0 -9
- package/build/test/fixtures/config/appium.config.ext-unknown-props.json +0 -10
- package/build/test/fixtures/config/appium.config.good.js +0 -40
- package/build/test/fixtures/config/appium.config.good.json +0 -33
- package/build/test/fixtures/config/appium.config.good.yaml +0 -30
- package/build/test/fixtures/config/appium.config.invalid.json +0 -31
- package/build/test/fixtures/config/appium.config.security-array.json +0 -5
- package/build/test/fixtures/config/appium.config.security-delimited.json +0 -5
- package/build/test/fixtures/config/appium.config.security-path.json +0 -5
- package/build/test/fixtures/config/driver-fake.config.json +0 -8
- package/build/test/fixtures/config/nodeconfig.json +0 -3
- package/build/test/fixtures/config/plugin-fake.config.json +0 -0
- package/build/test/fixtures/default-args.js +0 -35
- package/build/test/fixtures/deny-feat.txt +0 -5
- package/build/test/fixtures/driver.schema.js +0 -20
- package/build/test/fixtures/extensions.yaml +0 -27
- package/build/test/fixtures/flattened-schema.js +0 -504
- package/build/test/fixtures/plugin.schema.js +0 -20
- package/build/test/fixtures/schema-with-extensions.js +0 -28
- package/build/test/grid-register-specs.js +0 -74
- package/build/test/helpers.js +0 -75
- package/build/test/logger-specs.js +0 -76
- package/build/test/npm-specs.js +0 -20
- package/build/test/parser-specs.js +0 -314
- package/build/test/plugin-e2e-specs.js +0 -316
- package/build/test/schema/arg-spec-specs.js +0 -70
- package/build/test/schema/cli-args-specs.js +0 -431
- package/build/test/schema/schema-specs.js +0 -389
- package/build/test/utils-specs.js +0 -266
- package/lib/cli/npm.js +0 -251
- package/lib/driver-config.js +0 -101
- package/lib/drivers.js +0 -84
- package/lib/ext-config-io.js +0 -287
- package/lib/extension-config.js +0 -366
- package/lib/plugin-config.js +0 -63
- package/lib/plugins.js +0 -11
package/types/types.d.ts
CHANGED
|
@@ -1,10 +1,15 @@
|
|
|
1
|
-
import {transformers} from '../lib/schema/cli-transformers';
|
|
2
|
-
import {SERVER_SUBCOMMAND} from '../lib/cli/parser';
|
|
3
1
|
import {
|
|
4
2
|
DRIVER_TYPE as DRIVER_SUBCOMMAND,
|
|
3
|
+
EXT_SUBCOMMAND_INSTALL,
|
|
4
|
+
EXT_SUBCOMMAND_UPDATE,
|
|
5
|
+
EXT_SUBCOMMAND_RUN,
|
|
6
|
+
EXT_SUBCOMMAND_LIST,
|
|
7
|
+
EXT_SUBCOMMAND_UNINSTALL,
|
|
5
8
|
PLUGIN_TYPE as PLUGIN_SUBCOMMAND,
|
|
6
|
-
|
|
9
|
+
SERVER_SUBCOMMAND,
|
|
10
|
+
} from '../lib/constants';
|
|
7
11
|
import appiumConfigSchema from '../lib/schema/appium-config-schema';
|
|
12
|
+
import {transformers} from '../lib/schema/cli-transformers';
|
|
8
13
|
import {AppiumConfiguration, ServerConfig} from './appium-config';
|
|
9
14
|
|
|
10
15
|
/**
|
|
@@ -124,14 +129,14 @@ type DefaultForProp<Prop extends keyof ServerConfigMapping> =
|
|
|
124
129
|
/**
|
|
125
130
|
* The final shape of the parsed CLI arguments.
|
|
126
131
|
*/
|
|
127
|
-
type
|
|
132
|
+
type ArgsFromConfig = {
|
|
128
133
|
[Prop in keyof ServerConfigMapping as SetKeyForProp<Prop>]: DefaultForProp<Prop>;
|
|
129
134
|
};
|
|
130
135
|
|
|
131
136
|
/**
|
|
132
137
|
* Possible subcommands for the `appium` CLI.
|
|
133
138
|
*/
|
|
134
|
-
type
|
|
139
|
+
type CliSubcommand =
|
|
135
140
|
| typeof SERVER_SUBCOMMAND
|
|
136
141
|
| typeof DRIVER_SUBCOMMAND
|
|
137
142
|
| typeof PLUGIN_SUBCOMMAND;
|
|
@@ -140,12 +145,12 @@ type CliSubCommands =
|
|
|
140
145
|
* Possible subcommands of {@link DRIVER_SUBCOMMAND} or
|
|
141
146
|
* {@link PLUGIN_SUBCOMMAND}.
|
|
142
147
|
*/
|
|
143
|
-
type
|
|
144
|
-
|
|
|
145
|
-
|
|
|
146
|
-
|
|
|
147
|
-
|
|
|
148
|
-
|
|
|
148
|
+
export type CliExtensionSubcommand =
|
|
149
|
+
| typeof EXT_SUBCOMMAND_INSTALL
|
|
150
|
+
| typeof EXT_SUBCOMMAND_LIST
|
|
151
|
+
| typeof EXT_SUBCOMMAND_RUN
|
|
152
|
+
| typeof EXT_SUBCOMMAND_UPDATE
|
|
153
|
+
| typeof EXT_SUBCOMMAND_UNINSTALL;
|
|
149
154
|
|
|
150
155
|
/**
|
|
151
156
|
* Random stuff that may appear in the parsed args which has no equivalent in a
|
|
@@ -153,26 +158,64 @@ type CliExtensionSubcommands =
|
|
|
153
158
|
*/
|
|
154
159
|
interface MoreArgs {
|
|
155
160
|
/**
|
|
156
|
-
* Path to config file, if any
|
|
161
|
+
* Path to config file, if any. Does not make sense for this to be allowed in a config file!
|
|
157
162
|
*/
|
|
158
|
-
configFile
|
|
163
|
+
configFile?: string;
|
|
159
164
|
|
|
160
165
|
/**
|
|
161
|
-
* If true, show the
|
|
166
|
+
* If true, show the config and exit
|
|
162
167
|
*/
|
|
163
|
-
showConfig
|
|
168
|
+
showConfig?: boolean;
|
|
164
169
|
|
|
165
170
|
/**
|
|
166
171
|
* If true, open a REPL
|
|
167
172
|
*/
|
|
168
|
-
shell
|
|
173
|
+
shell?: boolean;
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
/**
|
|
177
|
+
* These arguments are _not_ supported by the CLI, but only via programmatic usage / tests.
|
|
178
|
+
*/
|
|
179
|
+
interface ProgrammaticArgs {
|
|
180
|
+
/**
|
|
181
|
+
* Subcommands of `driver` subcommand
|
|
182
|
+
*/
|
|
183
|
+
driverCommand?: CliExtensionSubcommand;
|
|
184
|
+
|
|
185
|
+
/**
|
|
186
|
+
* Subcommands of `plugin` subcommand
|
|
187
|
+
*/
|
|
188
|
+
pluginCommand?: CliExtensionSubcommand;
|
|
189
|
+
|
|
190
|
+
/**
|
|
191
|
+
* If true, throw on error instead of exit.
|
|
192
|
+
*/
|
|
193
|
+
throwInsteadOfExit?: boolean;
|
|
194
|
+
|
|
195
|
+
/**
|
|
196
|
+
* Seems to only be used in tests or standalone driver calls
|
|
197
|
+
*/
|
|
198
|
+
logHandler?: (...args: any[]) => void;
|
|
199
|
+
|
|
200
|
+
/**
|
|
201
|
+
* Alternate way to set `APPIUM_HOME` for tests. Since we don't want to muck about
|
|
202
|
+
* with the environment, we just set it here.
|
|
203
|
+
*/
|
|
204
|
+
appiumHome?: string;
|
|
169
205
|
|
|
170
206
|
/**
|
|
171
|
-
* If true,
|
|
172
|
-
* only programmatic usage.
|
|
207
|
+
* If true, show the build info and exit
|
|
173
208
|
*/
|
|
174
|
-
|
|
209
|
+
showBuildInfo: boolean;
|
|
175
210
|
|
|
211
|
+
/**
|
|
212
|
+
* If true, show config and exit
|
|
213
|
+
*/
|
|
214
|
+
showConfig: boolean;
|
|
215
|
+
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
interface SubcommandArgs {
|
|
176
219
|
/**
|
|
177
220
|
* Possible subcommands
|
|
178
221
|
*/
|
|
@@ -180,17 +223,15 @@ interface MoreArgs {
|
|
|
180
223
|
| typeof DRIVER_SUBCOMMAND
|
|
181
224
|
| typeof PLUGIN_SUBCOMMAND
|
|
182
225
|
| typeof SERVER_SUBCOMMAND;
|
|
226
|
+
}
|
|
183
227
|
|
|
184
228
|
/**
|
|
185
|
-
|
|
186
|
-
*/
|
|
187
|
-
driverCommand: CliExtensionSubcommands;
|
|
188
|
-
|
|
189
|
-
/**
|
|
190
|
-
* Subcommands of `plugin` subcommand
|
|
229
|
+
* The same as {@link ParsedArgs} but with a nullable `subcommand`.
|
|
191
230
|
*/
|
|
192
|
-
|
|
193
|
-
|
|
231
|
+
export type PartialArgs = ArgsFromConfig &
|
|
232
|
+
MoreArgs &
|
|
233
|
+
ProgrammaticArgs &
|
|
234
|
+
Partial<SubcommandArgs>;
|
|
194
235
|
|
|
195
236
|
/**
|
|
196
237
|
* The Appium configuration as a flattened object, parsed via CLI args _and_ any
|
|
@@ -198,4 +239,7 @@ interface MoreArgs {
|
|
|
198
239
|
* @todo Does not make any assumptions about property names derived from
|
|
199
240
|
* extensions.
|
|
200
241
|
*/
|
|
201
|
-
export type ParsedArgs =
|
|
242
|
+
export type ParsedArgs = ArgsFromConfig &
|
|
243
|
+
MoreArgs &
|
|
244
|
+
ProgrammaticArgs &
|
|
245
|
+
SubcommandArgs;
|
|
@@ -1,71 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
|
|
3
|
-
/* eslint no-console:0 */
|
|
4
|
-
|
|
5
|
-
/*
|
|
6
|
-
* Small tool, launching and monitoring ios-web-kit-proxy, and relaunching
|
|
7
|
-
* on predefined errors.
|
|
8
|
-
*
|
|
9
|
-
* Usage:
|
|
10
|
-
* ./bin/ios-webkit-debug-proxy-launcher.js [args]
|
|
11
|
-
* args: ios-webkit-debug-proxy args (they will be passed over)
|
|
12
|
-
*
|
|
13
|
-
* Example:
|
|
14
|
-
* ./bin/ios-webkit-debug-proxy-launcher.js -c <UDID>:27753 -d
|
|
15
|
-
*
|
|
16
|
-
* Note:
|
|
17
|
-
* For iOS8.1 try this first:
|
|
18
|
-
* brew install --HEAD ideviceinstaller
|
|
19
|
-
*/
|
|
20
|
-
|
|
21
|
-
'use strict';
|
|
22
|
-
|
|
23
|
-
const spawn = require('child_process').spawn;
|
|
24
|
-
const _ = require('lodash');
|
|
25
|
-
|
|
26
|
-
const args = process.argv.slice(2);
|
|
27
|
-
|
|
28
|
-
const RESTART_ON_MESSAGES = [
|
|
29
|
-
'Invalid message _rpc_applicationUpdated',
|
|
30
|
-
'Invalid message _rpc_applicationSentListing'];
|
|
31
|
-
|
|
32
|
-
const PROXY_CMD = 'ios_webkit_debug_proxy';
|
|
33
|
-
let proxy;
|
|
34
|
-
|
|
35
|
-
const handleKillProcess = function (exitCode) {
|
|
36
|
-
console.log('\nKilling proxy process!');
|
|
37
|
-
proxy.kill('SIGTERM');
|
|
38
|
-
process.exit((exitCode || 0));
|
|
39
|
-
};
|
|
40
|
-
|
|
41
|
-
const startProxy = function () {
|
|
42
|
-
console.log(`RUNNING: ${PROXY_CMD} ${args.join(' ')}`);
|
|
43
|
-
|
|
44
|
-
proxy = spawn(PROXY_CMD, args);
|
|
45
|
-
|
|
46
|
-
proxy.stdout.on('data', function onStdout (data) {
|
|
47
|
-
console.log(`stdout: ${data}`);
|
|
48
|
-
});
|
|
49
|
-
|
|
50
|
-
proxy.stderr.on('data', function onStderr (data) {
|
|
51
|
-
console.log(`stderr: ${data}`);
|
|
52
|
-
const restartMessage = _(RESTART_ON_MESSAGES).find(function findMessage (message) {
|
|
53
|
-
return ('' + data).indexOf(message) >= 0;
|
|
54
|
-
});
|
|
55
|
-
if (restartMessage) {
|
|
56
|
-
console.log(`Detected error message: ${restartMessage}`);
|
|
57
|
-
console.log('Killing proxy!');
|
|
58
|
-
proxy.kill('SIGTERM');
|
|
59
|
-
process.nextTick(startProxy);
|
|
60
|
-
}
|
|
61
|
-
});
|
|
62
|
-
|
|
63
|
-
proxy.on('close', function onClose (code) {
|
|
64
|
-
console.log(`Child process exited with code ${code}`);
|
|
65
|
-
});
|
|
66
|
-
};
|
|
67
|
-
|
|
68
|
-
process.on('SIGINT', handleKillProcess);
|
|
69
|
-
process.on('SIGTERM', handleKillProcess);
|
|
70
|
-
|
|
71
|
-
startProxy();
|
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
|
|
3
|
-
require("source-map-support/register");
|
|
4
|
-
|
|
5
|
-
const childProcess = require('child_process');
|
|
6
|
-
|
|
7
|
-
const _ = require('lodash');
|
|
8
|
-
|
|
9
|
-
const res = JSON.parse(childProcess.execSync('npm pack --dry-run --json --ignore-scripts', {
|
|
10
|
-
encoding: 'utf8'
|
|
11
|
-
}))[0];
|
|
12
|
-
const testFiles = ['LICENSE', 'build/lib/appium.js'];
|
|
13
|
-
|
|
14
|
-
const missingFiles = _.without(testFiles, ..._.map(res.files, 'path'));
|
|
15
|
-
|
|
16
|
-
if (!_.isEmpty(missingFiles)) {
|
|
17
|
-
throw new Error(`Files [${missingFiles.join(', ')}] are not included in package.json "files". ` + `Please make sure these files are included before publishing.`);
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
process.exit(0);require('source-map-support').install();
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
//# sourceMappingURL=data:application/json;charset=utf8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbImNoZWNrLW5wbS1wYWNrLWZpbGVzLmpzIl0sIm5hbWVzIjpbImNoaWxkUHJvY2VzcyIsInJlcXVpcmUiLCJfIiwicmVzIiwiSlNPTiIsInBhcnNlIiwiZXhlY1N5bmMiLCJlbmNvZGluZyIsInRlc3RGaWxlcyIsIm1pc3NpbmdGaWxlcyIsIndpdGhvdXQiLCJtYXAiLCJmaWxlcyIsImlzRW1wdHkiLCJFcnJvciIsImpvaW4iLCJwcm9jZXNzIiwiZXhpdCJdLCJtYXBwaW5ncyI6Ijs7OztBQUFBLE1BQU1BLFlBQVksR0FBR0MsT0FBTyxDQUFDLGVBQUQsQ0FBNUI7O0FBQ0EsTUFBTUMsQ0FBQyxHQUFHRCxPQUFPLENBQUMsUUFBRCxDQUFqQjs7QUFFQSxNQUFNRSxHQUFHLEdBQUdDLElBQUksQ0FBQ0MsS0FBTCxDQUFXTCxZQUFZLENBQUNNLFFBQWIsQ0FBc0IsNENBQXRCLEVBQW9FO0FBQUNDLEVBQUFBLFFBQVEsRUFBRTtBQUFYLENBQXBFLENBQVgsRUFBb0csQ0FBcEcsQ0FBWjtBQUdBLE1BQU1DLFNBQVMsR0FBRyxDQUNoQixTQURnQixFQUVoQixxQkFGZ0IsQ0FBbEI7O0FBTUEsTUFBTUMsWUFBWSxHQUFHUCxDQUFDLENBQUNRLE9BQUYsQ0FBVUYsU0FBVixFQUFxQixHQUFHTixDQUFDLENBQUNTLEdBQUYsQ0FBTVIsR0FBRyxDQUFDUyxLQUFWLEVBQWlCLE1BQWpCLENBQXhCLENBQXJCOztBQUVBLElBQUksQ0FBQ1YsQ0FBQyxDQUFDVyxPQUFGLENBQVVKLFlBQVYsQ0FBTCxFQUE4QjtBQUM1QixRQUFNLElBQUlLLEtBQUosQ0FBVyxVQUFTTCxZQUFZLENBQUNNLElBQWIsQ0FBa0IsSUFBbEIsQ0FBd0IsOENBQWxDLEdBQ2IsOERBREcsQ0FBTjtBQUVEOztBQUVEQyxPQUFPLENBQUNDLElBQVIsQ0FBYSxDQUFiIiwic291cmNlc0NvbnRlbnQiOlsiY29uc3QgY2hpbGRQcm9jZXNzID0gcmVxdWlyZSgnY2hpbGRfcHJvY2VzcycpO1xuY29uc3QgXyA9IHJlcXVpcmUoJ2xvZGFzaCcpO1xuXG5jb25zdCByZXMgPSBKU09OLnBhcnNlKGNoaWxkUHJvY2Vzcy5leGVjU3luYygnbnBtIHBhY2sgLS1kcnktcnVuIC0tanNvbiAtLWlnbm9yZS1zY3JpcHRzJywge2VuY29kaW5nOiAndXRmOCd9KSlbMF07XG5cbi8vIExpc3Qgb2YgZmlsZXMgd2UgYXJlIHRlc3RpbmcgdG8gbWFrZSBzdXJlIHRoZXkgYXJlIGluY2x1ZGVkIGluIHBhY2thZ2VcbmNvbnN0IHRlc3RGaWxlcyA9IFtcbiAgJ0xJQ0VOU0UnLCAvLyBDaGVjayB0aGF0IGxpY2Vuc2UgaXMgaW5jbHVkZWRcbiAgJ2J1aWxkL2xpYi9hcHBpdW0uanMnLCAvLyBTYW5pdHkgY2hlY2sgdGhhdCBidWlsZCBmaWxlcyBhcmUgYmVpbmcgaW5jbHVkZWQgYnkgdGVzdGluZyBqdXN0IG9uZSBmaWxlXG5dO1xuXG4vLyBHZXQgbGlzdCBvZiBmaWxlcyBpbiBgdGVzdEZpbGVzYCB0aGF0IGFyZW4ndCBpbiB0aGUgbGlzdCBvZiBwYWNrYWdlZCBmaWxlTmFtZXNcbmNvbnN0IG1pc3NpbmdGaWxlcyA9IF8ud2l0aG91dCh0ZXN0RmlsZXMsIC4uLl8ubWFwKHJlcy5maWxlcywgJ3BhdGgnKSk7XG5cbmlmICghXy5pc0VtcHR5KG1pc3NpbmdGaWxlcykpIHtcbiAgdGhyb3cgbmV3IEVycm9yKGBGaWxlcyBbJHttaXNzaW5nRmlsZXMuam9pbignLCAnKX1dIGFyZSBub3QgaW5jbHVkZWQgaW4gcGFja2FnZS5qc29uIFwiZmlsZXNcIi4gYCArXG4gICAgYFBsZWFzZSBtYWtlIHN1cmUgdGhlc2UgZmlsZXMgYXJlIGluY2x1ZGVkIGJlZm9yZSBwdWJsaXNoaW5nLmApO1xufVxuXG5wcm9jZXNzLmV4aXQoMCk7XG4iXSwiZmlsZSI6ImNoZWNrLW5wbS1wYWNrLWZpbGVzLmpzIiwic291cmNlUm9vdCI6Ii4uIn0=
|
|
@@ -1,319 +0,0 @@
|
|
|
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 _yamlJs = _interopRequireDefault(require("yaml-js"));
|
|
10
|
-
|
|
11
|
-
var _appiumSupport = require("appium-support");
|
|
12
|
-
|
|
13
|
-
var _validate = _interopRequireDefault(require("validate.js"));
|
|
14
|
-
|
|
15
|
-
var _handlebars = _interopRequireDefault(require("handlebars"));
|
|
16
|
-
|
|
17
|
-
var _lodash = _interopRequireDefault(require("lodash"));
|
|
18
|
-
|
|
19
|
-
var _asyncbox = require("asyncbox");
|
|
20
|
-
|
|
21
|
-
var _validator = require("./validator");
|
|
22
|
-
|
|
23
|
-
var _url = _interopRequireDefault(require("url"));
|
|
24
|
-
|
|
25
|
-
var _fancyLog = _interopRequireDefault(require("fancy-log"));
|
|
26
|
-
|
|
27
|
-
var _findRoot = _interopRequireDefault(require("find-root"));
|
|
28
|
-
|
|
29
|
-
const platformRanges = {
|
|
30
|
-
xcuitest: ['9.3'],
|
|
31
|
-
uiautomation: ['8.0', '9.3'],
|
|
32
|
-
espresso: ['?'],
|
|
33
|
-
uiautomator2: ['?'],
|
|
34
|
-
uiautomator: ['4.3'],
|
|
35
|
-
windows: ['10'],
|
|
36
|
-
mac: ['?']
|
|
37
|
-
};
|
|
38
|
-
const appiumRanges = {
|
|
39
|
-
xcuitest: ['1.6.0'],
|
|
40
|
-
uiautomator2: ['1.6.0'],
|
|
41
|
-
espresso: ['1.9.0'],
|
|
42
|
-
windows: ['1.6.0'],
|
|
43
|
-
mac: ['1.6.4']
|
|
44
|
-
};
|
|
45
|
-
const rootFolder = (0, _findRoot.default)(__dirname);
|
|
46
|
-
|
|
47
|
-
_handlebars.default.registerHelper('versions', function versionHelper(object, name, driverName) {
|
|
48
|
-
if (!object) {
|
|
49
|
-
return 'None';
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
if (!_lodash.default.isObject(object)) {
|
|
53
|
-
object = {};
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
let min = object[name ? `${name}_min` : 'min'];
|
|
57
|
-
let max = object[name ? `${name}_max` : 'max'];
|
|
58
|
-
|
|
59
|
-
if (!min) {
|
|
60
|
-
if (name === 'appium' && _lodash.default.isArray(appiumRanges[driverName])) {
|
|
61
|
-
min = appiumRanges[driverName][0];
|
|
62
|
-
} else if (name === 'platform' && _lodash.default.isArray(platformRanges[driverName])) {
|
|
63
|
-
min = platformRanges[driverName][0];
|
|
64
|
-
}
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
if (!max) {
|
|
68
|
-
if (name === 'appium' && appiumRanges[driverName]) {
|
|
69
|
-
max = appiumRanges[driverName][1];
|
|
70
|
-
} else if (name === 'platform' && platformRanges[driverName]) {
|
|
71
|
-
max = platformRanges[driverName][1];
|
|
72
|
-
}
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
if (!min && !max) {
|
|
76
|
-
return 'All';
|
|
77
|
-
} else if (!max) {
|
|
78
|
-
return `${min}+`;
|
|
79
|
-
} else if (!min) {
|
|
80
|
-
return `<= ${max}`;
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
return `${min} to ${max}`;
|
|
84
|
-
});
|
|
85
|
-
|
|
86
|
-
_handlebars.default.registerHelper('hyphenate', str => str.replace('_', '-'));
|
|
87
|
-
|
|
88
|
-
_handlebars.default.registerHelper('uppercase', str => str.toUpperCase());
|
|
89
|
-
|
|
90
|
-
_handlebars.default.registerHelper('capitalize', function capitalizeDriver(driverName) {
|
|
91
|
-
switch (driverName.toLowerCase()) {
|
|
92
|
-
case 'xcuitest':
|
|
93
|
-
return 'XCUITest';
|
|
94
|
-
|
|
95
|
-
case 'uiautomation':
|
|
96
|
-
return 'UIAutomation';
|
|
97
|
-
|
|
98
|
-
case 'uiautomator2':
|
|
99
|
-
return 'UiAutomator2';
|
|
100
|
-
|
|
101
|
-
case 'uiautomator':
|
|
102
|
-
return 'UiAutomator';
|
|
103
|
-
|
|
104
|
-
case 'espresso':
|
|
105
|
-
return 'Espresso';
|
|
106
|
-
|
|
107
|
-
default:
|
|
108
|
-
return driverName.length === 0 ? driverName : driverName[0].toUpperCase() + driverName.substr(1);
|
|
109
|
-
}
|
|
110
|
-
});
|
|
111
|
-
|
|
112
|
-
_handlebars.default.registerHelper('if_eq', function ifEq(a, b, opts) {
|
|
113
|
-
if (a === b) {
|
|
114
|
-
return opts.fn(this);
|
|
115
|
-
} else {
|
|
116
|
-
return opts.inverse(this);
|
|
117
|
-
}
|
|
118
|
-
});
|
|
119
|
-
|
|
120
|
-
function getBaseHostname(fullUrl) {
|
|
121
|
-
const baseUrl = _url.default.parse(fullUrl);
|
|
122
|
-
|
|
123
|
-
return baseUrl.hostname;
|
|
124
|
-
}
|
|
125
|
-
|
|
126
|
-
_handlebars.default.registerHelper('base_url', function baseUrl(fullUrl) {
|
|
127
|
-
return getBaseHostname(fullUrl);
|
|
128
|
-
});
|
|
129
|
-
|
|
130
|
-
_handlebars.default.registerHelper('client_url', function clientUrl(clientUrl) {
|
|
131
|
-
if (!clientUrl) {
|
|
132
|
-
return;
|
|
133
|
-
}
|
|
134
|
-
|
|
135
|
-
const createUrlString = function createUrlString(clientUrl, name = getBaseHostname(clientUrl)) {
|
|
136
|
-
return `[${name}](${clientUrl})`;
|
|
137
|
-
};
|
|
138
|
-
|
|
139
|
-
if (!_lodash.default.isArray(clientUrl)) {
|
|
140
|
-
return createUrlString(clientUrl);
|
|
141
|
-
}
|
|
142
|
-
|
|
143
|
-
let urlStrings = [];
|
|
144
|
-
|
|
145
|
-
for (const item of clientUrl) {
|
|
146
|
-
for (let [key, value] of _lodash.default.toPairs(item)) {
|
|
147
|
-
key = key.toLowerCase();
|
|
148
|
-
const urlStr = _validator.CLIENT_URL_TYPES[key] === 'hostname' ? createUrlString(value) : createUrlString(value, _validator.CLIENT_URL_TYPES[key]);
|
|
149
|
-
urlStrings.push(urlStr);
|
|
150
|
-
}
|
|
151
|
-
}
|
|
152
|
-
|
|
153
|
-
return urlStrings.join(' ');
|
|
154
|
-
});
|
|
155
|
-
|
|
156
|
-
async function registerSpecUrlHelper() {
|
|
157
|
-
const routesFile = await _appiumSupport.fs.readFile(_path.default.resolve(rootFolder, '..', 'base-driver', 'lib', 'protocol', 'routes.js'), 'utf8');
|
|
158
|
-
const routesFileLines = routesFile.split('\n');
|
|
159
|
-
|
|
160
|
-
_handlebars.default.registerHelper('spec_url', function specUrl(specUrl, endpoint) {
|
|
161
|
-
if (!specUrl.includes('routes.js')) {
|
|
162
|
-
return specUrl;
|
|
163
|
-
}
|
|
164
|
-
|
|
165
|
-
if (specUrl.startsWith('routes.js')) {
|
|
166
|
-
specUrl = `https://github.com/appium/appium-base-driver/blob/master/lib/protocol/${specUrl}`;
|
|
167
|
-
}
|
|
168
|
-
|
|
169
|
-
specUrl = specUrl.split('#L')[0];
|
|
170
|
-
endpoint = endpoint.replace('session_id', 'sessionId');
|
|
171
|
-
endpoint = endpoint.replace('element_id', 'elementId');
|
|
172
|
-
let index;
|
|
173
|
-
|
|
174
|
-
for (const i in routesFileLines) {
|
|
175
|
-
if (routesFileLines[i].includes(endpoint)) {
|
|
176
|
-
index = parseInt(i, 10) + 1;
|
|
177
|
-
break;
|
|
178
|
-
}
|
|
179
|
-
}
|
|
180
|
-
|
|
181
|
-
if (_lodash.default.isUndefined(index)) {
|
|
182
|
-
throw new Error(`Unable to find entry in 'appium-base-driver#routes' for endpoint '${endpoint}'`);
|
|
183
|
-
}
|
|
184
|
-
|
|
185
|
-
return `${specUrl}#L${index}`;
|
|
186
|
-
});
|
|
187
|
-
}
|
|
188
|
-
|
|
189
|
-
async function generateCommands() {
|
|
190
|
-
await registerSpecUrlHelper();
|
|
191
|
-
|
|
192
|
-
const commands = _path.default.resolve(rootFolder, 'commands-yml', 'commands/**/*.yml');
|
|
193
|
-
|
|
194
|
-
(0, _fancyLog.default)('Traversing YML files', commands);
|
|
195
|
-
await _appiumSupport.fs.rimraf(_path.default.resolve(rootFolder, 'docs', 'en', 'commands'));
|
|
196
|
-
|
|
197
|
-
const template = _handlebars.default.compile(await _appiumSupport.fs.readFile(_path.default.resolve(rootFolder, 'commands-yml', 'template.md'), 'utf8'), {
|
|
198
|
-
noEscape: true,
|
|
199
|
-
strict: true
|
|
200
|
-
});
|
|
201
|
-
|
|
202
|
-
let fileCount = 0;
|
|
203
|
-
|
|
204
|
-
for (const filename of await _appiumSupport.fs.glob(commands)) {
|
|
205
|
-
const relativeFilename = _path.default.relative(_path.default.resolve(rootFolder, 'commands-yml'), filename);
|
|
206
|
-
|
|
207
|
-
(0, _fancyLog.default)(`Rendering file: ${filename} ${relativeFilename}`);
|
|
208
|
-
const inputYML = await _appiumSupport.fs.readFile(filename, 'utf8');
|
|
209
|
-
|
|
210
|
-
const inputJSON = _yamlJs.default.load(inputYML);
|
|
211
|
-
|
|
212
|
-
inputJSON.ymlFileName = `/${_path.default.relative(rootFolder, filename)}`;
|
|
213
|
-
const validationErrors = (0, _validate.default)(inputJSON, _validator.validator);
|
|
214
|
-
|
|
215
|
-
if (validationErrors) {
|
|
216
|
-
throw new Error(`Data validation error for ${filename}: ${JSON.stringify(validationErrors)}`);
|
|
217
|
-
}
|
|
218
|
-
|
|
219
|
-
const markdown = template(inputJSON);
|
|
220
|
-
|
|
221
|
-
const ext = _path.default.extname(relativeFilename);
|
|
222
|
-
|
|
223
|
-
const markdownPath = `${relativeFilename.substring(0, relativeFilename.length - ext.length)}.md`;
|
|
224
|
-
|
|
225
|
-
const outfile = _path.default.resolve(rootFolder, 'docs', 'en', markdownPath);
|
|
226
|
-
|
|
227
|
-
(0, _fancyLog.default)(` Writing to: ${outfile}`);
|
|
228
|
-
await (0, _appiumSupport.mkdirp)(_path.default.dirname(outfile));
|
|
229
|
-
await _appiumSupport.fs.writeFile(outfile, markdown, 'utf8');
|
|
230
|
-
fileCount++;
|
|
231
|
-
}
|
|
232
|
-
|
|
233
|
-
(0, _fancyLog.default)(`Done writing ${fileCount} command documents`);
|
|
234
|
-
}
|
|
235
|
-
|
|
236
|
-
async function generateCommandIndex() {
|
|
237
|
-
function getTree(element, path) {
|
|
238
|
-
let node = {
|
|
239
|
-
name: element[0]
|
|
240
|
-
};
|
|
241
|
-
|
|
242
|
-
if (!_lodash.default.isArray(element[1])) {
|
|
243
|
-
node.path = `${path}/${element[1]}`;
|
|
244
|
-
} else {
|
|
245
|
-
node.path = `${path}/${element[1][0]}`;
|
|
246
|
-
const name = element[1].shift();
|
|
247
|
-
node.commands = [];
|
|
248
|
-
|
|
249
|
-
for (let subElement of element[1]) {
|
|
250
|
-
node.commands.push(getTree(subElement, `${path}/${name}`));
|
|
251
|
-
}
|
|
252
|
-
}
|
|
253
|
-
|
|
254
|
-
return node;
|
|
255
|
-
}
|
|
256
|
-
|
|
257
|
-
const toc = require(_path.default.resolve(rootFolder, '../..', 'docs', 'toc.js'));
|
|
258
|
-
|
|
259
|
-
const commandToc = _lodash.default.find(toc.en, value => value.indexOf('Commands') === 0);
|
|
260
|
-
|
|
261
|
-
const commands = [];
|
|
262
|
-
|
|
263
|
-
for (let el of commandToc[1].slice(1)) {
|
|
264
|
-
commands.push(getTree(el, '/docs/en/commands'));
|
|
265
|
-
}
|
|
266
|
-
|
|
267
|
-
const commandTemplate = _handlebars.default.compile(await _appiumSupport.fs.readFile(_path.default.resolve(rootFolder, 'commands-yml', 'api-template.md'), 'utf8'), {
|
|
268
|
-
noEscape: true,
|
|
269
|
-
strict: true
|
|
270
|
-
});
|
|
271
|
-
|
|
272
|
-
async function writeIndex(index, commands, indexPath) {
|
|
273
|
-
(0, _fancyLog.default)(`Creating API index '${index}'`);
|
|
274
|
-
const commandMarkdown = commandTemplate({
|
|
275
|
-
commands,
|
|
276
|
-
path: indexPath
|
|
277
|
-
});
|
|
278
|
-
await _appiumSupport.fs.writeFile(index, commandMarkdown, 'utf8');
|
|
279
|
-
}
|
|
280
|
-
|
|
281
|
-
const apiIndex = _path.default.resolve(rootFolder, '../..', 'docs', 'en', 'about-appium', 'api.md');
|
|
282
|
-
|
|
283
|
-
await writeIndex(apiIndex, commands);
|
|
284
|
-
(0, _fancyLog.default)(`Done writing main API index`);
|
|
285
|
-
|
|
286
|
-
async function writeIndividualIndexes(command) {
|
|
287
|
-
if (!_appiumSupport.util.hasValue(command.commands)) {
|
|
288
|
-
return;
|
|
289
|
-
}
|
|
290
|
-
|
|
291
|
-
const relPath = command.path.startsWith(_path.default.sep) ? command.path.substring(1) : command.path;
|
|
292
|
-
|
|
293
|
-
const index = _path.default.resolve(rootFolder, relPath, 'README.md');
|
|
294
|
-
|
|
295
|
-
await writeIndex(index, command.commands, command.path);
|
|
296
|
-
|
|
297
|
-
for (const el of command.commands) {
|
|
298
|
-
await writeIndividualIndexes(el);
|
|
299
|
-
}
|
|
300
|
-
}
|
|
301
|
-
|
|
302
|
-
const index = _path.default.resolve(rootFolder, '../..', 'docs', 'en', 'commands', 'README.md');
|
|
303
|
-
|
|
304
|
-
await writeIndex(index, commands);
|
|
305
|
-
|
|
306
|
-
for (const el of commands) {
|
|
307
|
-
await writeIndividualIndexes(el);
|
|
308
|
-
}
|
|
309
|
-
}
|
|
310
|
-
|
|
311
|
-
async function main() {
|
|
312
|
-
await generateCommands();
|
|
313
|
-
await generateCommandIndex();
|
|
314
|
-
}
|
|
315
|
-
|
|
316
|
-
(0, _asyncbox.asyncify)(main);require('source-map-support').install();
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
//# sourceMappingURL=data:application/json;charset=utf8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbImNvbW1hbmRzLXltbC9wYXJzZS5qcyJdLCJuYW1lcyI6WyJwbGF0Zm9ybVJhbmdlcyIsInhjdWl0ZXN0IiwidWlhdXRvbWF0aW9uIiwiZXNwcmVzc28iLCJ1aWF1dG9tYXRvcjIiLCJ1aWF1dG9tYXRvciIsIndpbmRvd3MiLCJtYWMiLCJhcHBpdW1SYW5nZXMiLCJyb290Rm9sZGVyIiwiX19kaXJuYW1lIiwiSGFuZGxlYmFycyIsInJlZ2lzdGVySGVscGVyIiwidmVyc2lvbkhlbHBlciIsIm9iamVjdCIsIm5hbWUiLCJkcml2ZXJOYW1lIiwiXyIsImlzT2JqZWN0IiwibWluIiwibWF4IiwiaXNBcnJheSIsInN0ciIsInJlcGxhY2UiLCJ0b1VwcGVyQ2FzZSIsImNhcGl0YWxpemVEcml2ZXIiLCJ0b0xvd2VyQ2FzZSIsImxlbmd0aCIsInN1YnN0ciIsImlmRXEiLCJhIiwiYiIsIm9wdHMiLCJmbiIsImludmVyc2UiLCJnZXRCYXNlSG9zdG5hbWUiLCJmdWxsVXJsIiwiYmFzZVVybCIsInVybCIsInBhcnNlIiwiaG9zdG5hbWUiLCJjbGllbnRVcmwiLCJjcmVhdGVVcmxTdHJpbmciLCJ1cmxTdHJpbmdzIiwiaXRlbSIsImtleSIsInZhbHVlIiwidG9QYWlycyIsInVybFN0ciIsIkNMSUVOVF9VUkxfVFlQRVMiLCJwdXNoIiwiam9pbiIsInJlZ2lzdGVyU3BlY1VybEhlbHBlciIsInJvdXRlc0ZpbGUiLCJmcyIsInJlYWRGaWxlIiwicGF0aCIsInJlc29sdmUiLCJyb3V0ZXNGaWxlTGluZXMiLCJzcGxpdCIsInNwZWNVcmwiLCJlbmRwb2ludCIsImluY2x1ZGVzIiwic3RhcnRzV2l0aCIsImluZGV4IiwiaSIsInBhcnNlSW50IiwiaXNVbmRlZmluZWQiLCJFcnJvciIsImdlbmVyYXRlQ29tbWFuZHMiLCJjb21tYW5kcyIsInJpbXJhZiIsInRlbXBsYXRlIiwiY29tcGlsZSIsIm5vRXNjYXBlIiwic3RyaWN0IiwiZmlsZUNvdW50IiwiZmlsZW5hbWUiLCJnbG9iIiwicmVsYXRpdmVGaWxlbmFtZSIsInJlbGF0aXZlIiwiaW5wdXRZTUwiLCJpbnB1dEpTT04iLCJ5YW1sIiwibG9hZCIsInltbEZpbGVOYW1lIiwidmFsaWRhdGlvbkVycm9ycyIsInZhbGlkYXRvciIsIkpTT04iLCJzdHJpbmdpZnkiLCJtYXJrZG93biIsImV4dCIsImV4dG5hbWUiLCJtYXJrZG93blBhdGgiLCJzdWJzdHJpbmciLCJvdXRmaWxlIiwiZGlybmFtZSIsIndyaXRlRmlsZSIsImdlbmVyYXRlQ29tbWFuZEluZGV4IiwiZ2V0VHJlZSIsImVsZW1lbnQiLCJub2RlIiwic2hpZnQiLCJzdWJFbGVtZW50IiwidG9jIiwicmVxdWlyZSIsImNvbW1hbmRUb2MiLCJmaW5kIiwiZW4iLCJpbmRleE9mIiwiZWwiLCJzbGljZSIsImNvbW1hbmRUZW1wbGF0ZSIsIndyaXRlSW5kZXgiLCJpbmRleFBhdGgiLCJjb21tYW5kTWFya2Rvd24iLCJhcGlJbmRleCIsIndyaXRlSW5kaXZpZHVhbEluZGV4ZXMiLCJjb21tYW5kIiwidXRpbCIsImhhc1ZhbHVlIiwicmVsUGF0aCIsInNlcCIsIm1haW4iXSwibWFwcGluZ3MiOiI7Ozs7OztBQUFBOztBQUNBOztBQUNBOztBQUNBOztBQUNBOztBQUNBOztBQUNBOztBQUNBOztBQUNBOztBQUNBOztBQUNBOztBQUlBLE1BQU1BLGNBQWMsR0FBRztBQUNyQkMsRUFBQUEsUUFBUSxFQUFFLENBQUMsS0FBRCxDQURXO0FBRXJCQyxFQUFBQSxZQUFZLEVBQUUsQ0FBQyxLQUFELEVBQVEsS0FBUixDQUZPO0FBR3JCQyxFQUFBQSxRQUFRLEVBQUUsQ0FBQyxHQUFELENBSFc7QUFJckJDLEVBQUFBLFlBQVksRUFBRSxDQUFDLEdBQUQsQ0FKTztBQUtyQkMsRUFBQUEsV0FBVyxFQUFFLENBQUMsS0FBRCxDQUxRO0FBTXJCQyxFQUFBQSxPQUFPLEVBQUUsQ0FBQyxJQUFELENBTlk7QUFPckJDLEVBQUFBLEdBQUcsRUFBRSxDQUFDLEdBQUQ7QUFQZ0IsQ0FBdkI7QUFXQSxNQUFN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LGNBQUtDLE9BQUwsQ0FBYWhELFVBQWIsRUFBeUJnSCxPQUF6QixFQUFrQyxXQUFsQyxDQUFkOztBQUNBLFVBQU1SLFVBQVUsQ0FBQ2pELEtBQUQsRUFBUXNELE9BQU8sQ0FBQ2hELFFBQWhCLEVBQTBCZ0QsT0FBTyxDQUFDOUQsSUFBbEMsQ0FBaEI7O0FBR0EsU0FBSyxNQUFNc0QsRUFBWCxJQUFpQlEsT0FBTyxDQUFDaEQsUUFBekIsRUFBbUM7QUFDakMsWUFBTStDLHNCQUFzQixDQUFDUCxFQUFELENBQTVCO0FBQ0Q7QUFDRjs7QUFHRCxRQUFNOUMsS0FBSyxHQUFHUixjQUFLQyxPQUFMLENBQWFoRCxVQUFiLEVBQXlCLE9BQXpCLEVBQWtDLE1BQWxDLEVBQTBDLElBQTFDLEVBQWdELFVBQWhELEVBQTRELFdBQTVELENBQWQ7O0FBQ0EsUUFBTXdHLFVBQVUsQ0FBQ2pELEtBQUQsRUFBUU0sUUFBUixDQUFoQjs7QUFDQSxPQUFLLE1BQU13QyxFQUFYLElBQWlCeEMsUUFBakIsRUFBMkI7QUFDekIsVUFBTStDLHNCQUFzQixDQUFDUCxFQUFELENBQTVCO0FBQ0Q7QUFDRjs7QUFFRCxlQUFlYSxJQUFmLEdBQXVCO0FBQ3JCLFFBQU10RCxnQkFBZ0IsRUFBdEI7QUFDQSxRQUFNNkIsb0JBQW9CLEVBQTFCO0FBQ0Q7O0FBRUQsd0JBQVN5QixJQUFUIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHBhdGggZnJvbSAncGF0aCc7XG5pbXBvcnQgeWFtbCBmcm9tICd5YW1sLWpzJztcbmltcG9ydCB7IGZzLCBta2RpcnAsIHV0aWwgfSBmcm9tICdhcHBpdW0tc3VwcG9ydCc7XG5pbXBvcnQgdmFsaWRhdGUgZnJvbSAndmFsaWRhdGUuanMnO1xuaW1wb3J0IEhhbmRsZWJhcnMgZnJvbSAnaGFuZGxlYmFycyc7XG5pbXBvcnQgXyBmcm9tICdsb2Rhc2gnO1xuaW1wb3J0IHsgYXN5bmNpZnkgfSBmcm9tICdhc3luY2JveCc7XG5pbXBvcnQgeyB2YWxpZGF0b3IsIENMSUVOVF9VUkxfVFlQRVMgfSBmcm9tICcuL3ZhbGlkYXRvcic7XG5pbXBvcnQgdXJsIGZyb20gJ3VybCc7XG5pbXBvcnQgbG9nIGZyb20gJ2ZhbmN5LWxvZyc7XG5pbXBvcnQgZmluZFJvb3QgZnJvbSAnZmluZC1yb290JztcblxuXG4vLyBXaGF0IHJhbmdlIG9mIHBsYXRmb3JtcyBkbyB0aGUgZHJpdmVyJ3Mgc3VwcG9ydFxuY29uc3QgcGxhdGZvcm1SYW5nZXMgPSB7XG4gIHhjdWl0ZXN0OiBbJzkuMyddLFxuICB1aWF1dG9tYXRpb246IFsnOC4wJywgJzkuMyddLFxuICBlc3ByZXNzbzogWyc/J10sXG4gIHVpYXV0b21hdG9yMjogWyc/J10sXG4gIHVpYXV0b21hdG9yOiBbJzQuMyddLFxuICB3aW5kb3dzOiBbJzEwJ10sXG4gIG1hYzogWyc/J10sIC8vIFRPRE9cbn07XG5cbi8vIFdoZW4gd2FzIHRoZSBkcml2ZXIgc3VwcG9ydGVkIGluIEFwcGl1bT9cbmNvbnN0IGFwcGl1bVJhbmdlcyA9IHtcbiAgeGN1aXRlc3Q6IFsnMS42LjAnXSxcbiAgdWlhdXRvbWF0b3IyOiBbJzEuNi4wJ10sXG4gIGVzcHJlc3NvOiBbJzEuOS4wJ10sXG4gIHdpbmRvd3M6IFsnMS42LjAnXSxcbiAgbWFjOiBbJzEuNi40J10sXG59O1xuXG5jb25zdCByb290Rm9sZGVyID0gZmluZFJvb3QoX19kaXJuYW1lKTtcblxuLy8gQ3JlYXRlIEhhbmRsZWJhcnMgaGVscGVyIHRoYXQgc2hvd3MgYSB2ZXJzaW9uIHJhbmdlXG5IYW5kbGViYXJzLnJlZ2lzdGVySGVscGVyKCd2ZXJzaW9ucycsIGZ1bmN0aW9uIHZlcnNpb25IZWxwZXIgKG9iamVjdCwgbmFtZSwgZHJpdmVyTmFtZSkge1xuICBpZiAoIW9iamVjdCkge1xuICAgIHJldHVybiAnTm9uZSc7XG4gIH1cblxuICBpZiAoIV8uaXNPYmplY3Qob2JqZWN0KSkge1xuICAgIG9iamVjdCA9IHt9O1xuICB9XG5cbiAgbGV0IG1pbiA9IG9iamVjdFtuYW1lID8gYCR7bmFtZX1fbWluYCA6ICdtaW4nXTtcbiAgbGV0IG1heCA9IG9iamVjdFtuYW1lID8gYCR7bmFtZX1fbWF4YCA6ICdtYXgnXTtcblxuICBpZiAoIW1pbikge1xuICAgIGlmIChuYW1lID09PSAnYXBwaXVtJyAmJiBfLmlzQXJyYXkoYXBwaXVtUmFuZ2VzW2RyaXZlck5hbWVdKSkge1xuICAgICAgbWluID0gYXBwaXVtUmFuZ2VzW2RyaXZlck5hbWVdWzBdO1xuICAgIH0gZWxzZSBpZiAobmFtZSA9PT0gJ3BsYXRmb3JtJyAmJiBfLmlzQXJyYXkocGxhdGZvcm1SYW5nZXNbZHJpdmVyTmFtZV0pKSB7XG4gICAgICBtaW4gPSBwbGF0Zm9ybVJhbmdlc1tkcml2ZXJOYW1lXVswXTtcbiAgICB9XG4gIH1cblxuICBpZiAoIW1heCkge1xuICAgIGlmIChuYW1lID09PSAnYXBwaXVtJyAmJiBhcHBpdW1SYW5nZXNbZHJpdmVyTmFtZV0pIHtcbiAgICAgIG1heCA9IGFwcGl1bVJhbmdlc1tkcml2ZXJOYW1lXVsxXTtcbiAgICB9IGVsc2UgaWYgKG5hbWUgPT09ICdwbGF0Zm9ybScgJiYgcGxhdGZvcm1SYW5nZXNbZHJpdmVyTmFtZV0pIHtcbiAgICAgIG1heCA9IHBsYXRmb3JtUmFuZ2VzW2RyaXZlck5hbWVdWzFdO1xuICAgIH1cbiAgfVxuXG4gIGlmICghbWluICYmICFtYXgpIHtcbiAgICByZXR1cm4gJ0FsbCc7XG4gIH0gZWxzZSBpZiAoIW1heCkge1xuICAgIHJldHVybiBgJHttaW59K2A7XG4gIH0gZWxzZSBpZiAoIW1pbikge1xuICAgIHJldHVybiBgPD0gJHttYXh9YDtcbiAgfVxuXG4gIHJldHVybiBgJHttaW59IHRvICR7bWF4fWA7XG59KTtcblxuSGFuZGxlYmFycy5yZWdpc3RlckhlbHBlcignaHlwaGVuYXRlJywgKHN0cikgPT4gc3RyLnJlcGxhY2UoJ18nLCAnLScpKTtcbkhhbmRsZWJhcnMucmVnaXN0ZXJIZWxwZXIoJ3VwcGVyY2FzZScsIChzdHIpID0+IHN0ci50b1VwcGVyQ2FzZSgpKTtcblxuSGFuZGxlYmFycy5yZWdpc3RlckhlbHBlcignY2FwaXRhbGl6ZScsIGZ1bmN0aW9uIGNhcGl0YWxpemVEcml2ZXIgKGRyaXZlck5hbWUpIHtcbiAgc3dpdGNoIChkcml2ZXJOYW1lLnRvTG93ZXJDYXNlKCkpIHtcbiAgICBjYXNlICd4Y3VpdGVzdCc6XG4gICAgICByZXR1cm4gJ1hDVUlUZXN0JztcbiAgICBjYXNlICd1aWF1dG9tYXRpb24nOlxuICAgICAgcmV0dXJuICdVSUF1dG9tYXRpb24nO1xuICAgIGNhc2UgJ3VpYXV0b21hdG9yMic6XG4gICAgICByZXR1cm4gJ1VpQXV0b21hdG9yMic7XG4gICAgY2FzZSAndWlhdXRvbWF0b3InOlxuICAgICAgcmV0dXJuICdVaUF1dG9tYXRvcic7XG4gICAgY2FzZSAnZXNwcmVzc28nOlxuICAgICAgcmV0dXJuICdFc3ByZXNzbyc7XG4gICAgZGVmYXVsdDpcbiAgICAgIHJldHVybiBkcml2ZXJOYW1lLmxlbmd0aCA9PT0gMCA/IGRyaXZlck5hbWUgOiBkcml2ZXJOYW1lWzBdLnRvVXBwZXJDYXNlKCkgKyBkcml2ZXJOYW1lLnN1YnN0cigxKTtcbiAgfVxufSk7XG5cbkhhbmRsZWJhcnMucmVnaXN0ZXJIZWxwZXIoJ2lmX2VxJywgZnVuY3Rpb24gaWZFcSAoYSwgYiwgb3B0cykge1xuICBpZiAoYSA9PT0gYikge1xuICAgIHJldHVybiBvcHRzLmZuKHRoaXMpO1xuICB9IGVsc2Uge1xuICAgIHJldHVybiBvcHRzLmludmVyc2UodGhpcyk7XG4gIH1cbn0pO1xuXG5mdW5jdGlvbiBnZXRCYXNlSG9zdG5hbWUgKGZ1bGxVcmwpIHtcbiAgY29uc3QgYmFzZVVybCA9IHVybC5wYXJzZShmdWxsVXJsKTtcbiAgcmV0dXJuIGJhc2VVcmwuaG9zdG5hbWU7XG59XG5cbkhhbmRsZWJhcnMucmVnaXN0ZXJIZWxwZXIoJ2Jhc2VfdXJsJywgZnVuY3Rpb24gYmFzZVVybCAoZnVsbFVybCkge1xuICByZXR1cm4gZ2V0QmFzZUhvc3RuYW1lKGZ1bGxVcmwpO1xufSk7XG5cbkhhbmRsZWJhcnMucmVnaXN0ZXJIZWxwZXIoJ2NsaWVudF91cmwnLCBmdW5jdGlvbiBjbGllbnRVcmwgKGNsaWVudFVybCkge1xuICBpZiAoIWNsaWVudFVybCkge1xuICAgIHJldHVybjtcbiAgfVxuXG4gIGNvbnN0IGNyZWF0ZVVybFN0cmluZyA9IGZ1bmN0aW9uIGNyZWF0ZVVybFN0cmluZyAoY2xpZW50VXJsLCBuYW1lID0gZ2V0QmFzZUhvc3RuYW1lKGNsaWVudFVybCkpIHtcbiAgICByZXR1cm4gYFske25hbWV9XSgke2NsaWVudFVybH0pYDtcbiAgfTtcblxuICBpZiAoIV8uaXNBcnJheShjbGllbnRVcmwpKSB7XG4gICAgcmV0dXJuIGNyZWF0ZVVybFN0cmluZyhjbGllbnRVcmwpO1xuICB9XG5cbiAgbGV0IHVybFN0cmluZ3MgPSBbXTtcbiAgZm9yIChjb25zdCBpdGVtIG9mIGNsaWVudFVybCkge1xuICAgIGZvciAobGV0IFtrZXksIHZhbHVlXSBvZiBfLnRvUGFpcnMoaXRlbSkpIHtcbiAgICAgIGtleSA9IGtleS50b0xvd2VyQ2FzZSgpO1xuICAgICAgY29uc3QgdXJsU3RyID0gQ0xJRU5UX1VSTF9UWVBFU1trZXldID09PSAnaG9zdG5hbWUnXG4gICAgICAgID8gY3JlYXRlVXJsU3RyaW5nKHZhbHVlKVxuICAgICAgICA6IGNyZWF0ZVVybFN0cmluZyh2YWx1ZSwgQ0xJRU5UX1VSTF9UWVBFU1trZXldKTtcbiAgICAgIHVybFN0cmluZ3MucHVzaCh1cmxTdHIpO1xuICAgIH1cbiAgfVxuICByZXR1cm4gdXJsU3RyaW5ncy5qb2luKCcgJyk7XG59KTtcblxuYXN5bmMgZnVuY3Rpb24gcmVnaXN0ZXJTcGVjVXJsSGVscGVyICgpIHtcbiAgY29uc3Qgcm91dGVzRmlsZSA9IGF3YWl0IGZzLnJlYWRGaWxlKHBhdGgucmVzb2x2ZShyb290Rm9sZGVyLCAnLi4nLCAnYmFzZS1kcml2ZXInLCAnbGliJywgJ3Byb3RvY29sJywgJ3JvdXRlcy5qcycpLCAndXRmOCcpO1xuICBjb25zdCByb3V0ZXNGaWxlTGluZXMgPSByb3V0ZXNGaWxlLnNwbGl0KCdcXG4nKTtcblxuICBIYW5kbGViYXJzLnJlZ2lzdGVySGVscGVyKCdzcGVjX3VybCcsIGZ1bmN0aW9uIHNwZWNVcmwgKHNwZWNVcmwsIGVuZHBvaW50KSB7XG4gICAgLy8gcmV0dXJuIHRoZSB1cmwgaWYgaXQgaXMgbm90IGEgbGluayB0byBvdXIgcm91dGVzIGRvY1xuICAgIGlmICghc3BlY1VybC5pbmNsdWRlcygncm91dGVzLmpzJykpIHtcbiAgICAgIHJldHVybiBzcGVjVXJsO1xuICAgIH1cbiAgICAvLyBtYWtlIHN1cmUgaXQgaXMgYSBmdWxsIHVybFxuICAgIGlmIChzcGVjVXJsLnN0YXJ0c1dpdGgoJ3JvdXRlcy5qcycpKSB7XG4gICAgICBzcGVjVXJsID0gYGh0dHBzOi8vZ2l0aHViLmNvbS9hcHBpdW0vYXBwaXVtLWJhc2UtZHJpdmVyL2Jsb2IvbWFzdGVyL2xpYi9wcm90b2NvbC8ke3NwZWNVcmx9YDtcbiAgICB9XG5cbiAgICAvLyBzdHJpcCBvZmYgYW55IGxpbmUgbnVtYmVyc1xuICAgIHNwZWNVcmwgPSBzcGVjVXJsLnNwbGl0KCcjTCcpWzBdO1xuXG4gICAgLy8gdGhlIGVuZHBvaW50IGhlcmUgaXMgb2Z0ZW4gYHNlc3Npb25faWRgIGFuZCB3ZSBuZWVkIGBzZXNzaW9uSWRgXG4gICAgZW5kcG9pbnQgPSBlbmRwb2ludC5yZXBsYWNlKCdzZXNzaW9uX2lkJywgJ3Nlc3Npb25JZCcpO1xuICAgIC8vIGFuZCBgZWxlbWVudF9pZGAgYW5kIHdlIG5lZWQgYGVsZW1lbnRJZGBcbiAgICBlbmRwb2ludCA9IGVuZHBvaW50LnJlcGxhY2UoJ2VsZW1lbnRfaWQnLCAnZWxlbWVudElkJyk7XG5cbiAgICAvLyBmaW5kIHRoZSBsaW5lIG51bWJlciBmb3IgdGhpcyBlbmRwb2ludFxuICAgIGxldCBpbmRleDtcbiAgICBmb3IgKGNvbnN0IGkgaW4gcm91dGVzRmlsZUxpbmVzKSB7XG4gICAgICBpZiAocm91dGVzRmlsZUxpbmVzW2ldLmluY2x1ZGVzKGVuZHBvaW50KSkge1xuICAgICAgICAvLyBsaW5lIG51bWJlcnMgYXJlIDEtaW5kZXhlZFxuICAgICAgICBpbmRleCA9IHBhcnNlSW50KGksIDEwKSArIDE7XG4gICAgICAgIGJyZWFrO1xuICAgICAgfVxuICAgIH1cbiAgICBpZiAoXy5pc1VuZGVmaW5lZChpbmRleCkpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihgVW5hYmxlIHRvIGZpbmQgZW50cnkgaW4gJ2FwcGl1bS1iYXNlLWRyaXZlciNyb3V0ZXMnIGZvciBlbmRwb2ludCAnJHtlbmRwb2ludH0nYCk7XG4gICAgfVxuXG4gICAgcmV0dXJuIGAke3NwZWNVcmx9I0wke2luZGV4fWA7XG4gIH0pO1xufVxuXG5hc3luYyBmdW5jdGlvbiBnZW5lcmF0ZUNvbW1hbmRzICgpIHtcbiAgYXdhaXQgcmVnaXN0ZXJTcGVjVXJsSGVscGVyKCk7XG5cbiAgY29uc3QgY29tbWFuZHMgPSBwYXRoLnJlc29sdmUocm9vdEZvbGRlciwgJ2NvbW1hbmRzLXltbCcsICdjb21tYW5kcy8qKi8qLnltbCcpO1xuICBsb2coJ1RyYXZlcnNpbmcgWU1MIGZpbGVzJywgY29tbWFuZHMpO1xuICBhd2FpdCBmcy5yaW1yYWYocGF0aC5yZXNvbHZlKHJvb3RGb2xkZXIsICdkb2NzJywgJ2VuJywgJ2NvbW1hbmRzJykpO1xuXG4gIC8vIGdldCB0aGUgdGVtcGxhdGUgZnJvbSB3aGljaCB0aGUgbWQgZmlsZXMgd2lsbCBiZSBjcmVhdGVkXG4gIGNvbnN0IHRlbXBsYXRlID0gSGFuZGxlYmFycy5jb21waWxlKGF3YWl0IGZzLnJlYWRGaWxlKHBhdGgucmVzb2x2ZShyb290Rm9sZGVyLCAnY29tbWFuZHMteW1sJywgJ3RlbXBsYXRlLm1kJyksICd1dGY4JyksIHtub0VzY2FwZTogdHJ1ZSwgc3RyaWN0OiB0cnVlfSk7XG5cbiAgbGV0IGZpbGVDb3VudCA9IDA7XG4gIGZvciAoY29uc3QgZmlsZW5hbWUgb2YgYXdhaXQgZnMuZ2xvYihjb21tYW5kcykpIHtcbiAgICBjb25zdCByZWxhdGl2ZUZpbGVuYW1lID0gcGF0aC5yZWxhdGl2ZShwYXRoLnJlc29sdmUocm9vdEZvbGRlciwgJ2NvbW1hbmRzLXltbCcpLCBmaWxlbmFtZSk7XG4gICAgbG9nKGBSZW5kZXJpbmcgZmlsZTogJHtmaWxlbmFtZX0gJHtyZWxhdGl2ZUZpbGVuYW1lfWApO1xuXG4gICAgLy8gVHJhbnNsYXRlIHRoZSBZTUwgc3BlY3MgdG8gSlNPTlxuICAgIGNvbnN0IGlucHV0WU1MID0gYXdhaXQgZnMucmVhZEZpbGUoZmlsZW5hbWUsICd1dGY4Jyk7XG4gICAgY29uc3QgaW5wdXRKU09OID0geWFtbC5sb2FkKGlucHV0WU1MKTtcbiAgICBpbnB1dEpTT04ueW1sRmlsZU5hbWUgPSBgLyR7cGF0aC5yZWxhdGl2ZShyb290Rm9sZGVyLCBmaWxlbmFtZSl9YDtcbiAgICBjb25zdCB2YWxpZGF0aW9uRXJyb3JzID0gdmFsaWRhdGUoaW5wdXRKU09OLCB2YWxpZGF0b3IpO1xuICAgIGlmICh2YWxpZGF0aW9uRXJyb3JzKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYERhdGEgdmFsaWRhdGlvbiBlcnJvciBmb3IgJHtmaWxlbmFtZX06ICR7SlNPTi5zdHJpbmdpZnkodmFsaWRhdGlvbkVycm9ycyl9YCk7XG4gICAgfVxuXG4gICAgLy8gUGFzcyB0aGUgaW5wdXRKUyBpbnRvIG91ciBIYW5kbGViYXJzIHRlbXBsYXRlXG4gICAgY29uc3QgbWFya2Rvd24gPSB0ZW1wbGF0ZShpbnB1dEpTT04pO1xuXG4gICAgLy8gV3JpdGUgdGhlIG1hcmtkb3duIHRvIGl0cyByaWdodCBwbGFjZVxuICAgIGNvbnN0IGV4dCA9IHBhdGguZXh0bmFtZShyZWxhdGl2ZUZpbGVuYW1lKTtcbiAgICBjb25zdCBtYXJrZG93blBhdGggPSBgJHtyZWxhdGl2ZUZpbGVuYW1lLnN1YnN0cmluZygwLCByZWxhdGl2ZUZpbGVuYW1lLmxlbmd0aCAtIGV4dC5sZW5ndGgpfS5tZGA7XG4gICAgY29uc3Qgb3V0ZmlsZSA9IHBhdGgucmVzb2x2ZShyb290Rm9sZGVyLCAnZG9jcycsICdlbicsIG1hcmtkb3duUGF0aCk7XG4gICAgbG9nKGAgICAgV3JpdGluZyB0bzogJHtvdXRmaWxlfWApO1xuICAgIGF3YWl0IG1rZGlycChwYXRoLmRpcm5hbWUob3V0ZmlsZSkpO1xuICAgIGF3YWl0IGZzLndyaXRlRmlsZShvdXRmaWxlLCBtYXJrZG93biwgJ3V0ZjgnKTtcblxuICAgIGZpbGVDb3VudCsrO1xuICB9XG4gIGxvZyhgRG9uZSB3cml0aW5nICR7ZmlsZUNvdW50fSBjb21tYW5kIGRvY3VtZW50c2ApO1xufVxuXG5hc3luYyBmdW5jdGlvbiBnZW5lcmF0ZUNvbW1hbmRJbmRleCAoKSB7XG4gIGZ1bmN0aW9uIGdldFRyZWUgKGVsZW1lbnQsIHBhdGgpIHtcbiAgICBsZXQgbm9kZSA9IHtcbiAgICAgIG5hbWU6IGVsZW1lbnRbMF0sXG4gICAgfTtcbiAgICBpZiAoIV8uaXNBcnJheShlbGVtZW50WzFdKSkge1xuICAgICAgbm9kZS5wYXRoID0gYCR7cGF0aH0vJHtlbGVtZW50WzFdfWA7XG4gICAgfSBlbHNlIHtcbiAgICAgIG5vZGUucGF0aCA9IGAke3BhdGh9LyR7ZWxlbWVudFsxXVswXX1gO1xuICAgICAgY29uc3QgbmFtZSA9IGVsZW1lbnRbMV0uc2hpZnQoKTtcbiAgICAgIG5vZGUuY29tbWFuZHMgPSBbXTtcbiAgICAgIGZvciAobGV0IHN1YkVsZW1lbnQgb2YgZWxlbWVudFsxXSkge1xuICAgICAgICBub2RlLmNvbW1hbmRzLnB1c2goZ2V0VHJlZShzdWJFbGVtZW50LCBgJHtwYXRofS8ke25hbWV9YCkpO1xuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gbm9kZTtcbiAgfVxuXG4gIC8vIHBhcnNlIHRoZSB0b2MuanMgZmlsZSBhbmQgZ2V0IHRoZSBjb21tYW5kcyBpbnRvIHRoZSBmb3JtIG9mXG4gIC8vICAge2NvbW1hbmRzOiBbe25hbWU6ICcnLCBwYXRoOiAnJ30sIHtuYW1lOiAnJywgY29tbWFuZHM6IFsuLi5dfV19XG4gIGNvbnN0IHRvYyA9IHJlcXVpcmUocGF0aC5yZXNvbHZlKHJvb3RGb2xkZXIsICcuLi8uLicsICdkb2NzJywgJ3RvYy5qcycpKTtcbiAgY29uc3QgY29tbWFuZFRvYyA9IF8uZmluZCh0b2MuZW4sICh2YWx1ZSkgPT4gdmFsdWUuaW5kZXhPZignQ29tbWFuZHMnKSA9PT0gMCk7XG4gIGNvbnN0IGNvbW1hbmRzID0gW107XG4gIGZvciAobGV0IGVsIG9mIGNvbW1hbmRUb2NbMV0uc2xpY2UoMSkpIHtcbiAgICBjb21tYW5kcy5wdXNoKGdldFRyZWUoZWwsICcvZG9jcy9lbi9jb21tYW5kcycpKTtcbiAgfVxuXG4gIGNvbnN0IGNvbW1hbmRUZW1wbGF0ZSA9IEhhbmRsZWJhcnMuY29tcGlsZShhd2FpdCBmcy5yZWFkRmlsZShwYXRoLnJlc29sdmUocm9vdEZvbGRlciwgJ2NvbW1hbmRzLXltbCcsICdhcGktdGVtcGxhdGUubWQnKSwgJ3V0ZjgnKSwge25vRXNjYXBlOiB0cnVlLCBzdHJpY3Q6IHRydWV9KTtcblxuICBhc3luYyBmdW5jdGlvbiB3cml0ZUluZGV4IChpbmRleCwgY29tbWFuZHMsIGluZGV4UGF0aCkge1xuICAgIGxvZyhgQ3JlYXRpbmcgQVBJIGluZGV4ICcke2luZGV4fSdgKTtcbiAgICBjb25zdCBjb21tYW5kTWFya2Rvd24gPSBjb21tYW5kVGVtcGxhdGUoe1xuICAgICAgY29tbWFuZHMsXG4gICAgICBwYXRoOiBpbmRleFBhdGgsXG4gICAgfSk7XG4gICAgYXdhaXQgZnMud3JpdGVGaWxlKGluZGV4LCBjb21tYW5kTWFya2Rvd24sICd1dGY4Jyk7XG4gIH1cblxuICBjb25zdCBhcGlJbmRleCA9IHBhdGgucmVzb2x2ZShyb290Rm9sZGVyLCAnLi4vLi4nLCAnZG9jcycsICdlbicsICdhYm91dC1hcHBpdW0nLCAnYXBpLm1kJyk7XG4gIGF3YWl0IHdyaXRlSW5kZXgoYXBpSW5kZXgsIGNvbW1hbmRzKTtcbiAgbG9nKGBEb25lIHdyaXRpbmcgbWFpbiBBUEkgaW5kZXhgKTtcblxuICBhc3luYyBmdW5jdGlvbiB3cml0ZUluZGl2aWR1YWxJbmRleGVzIChjb21tYW5kKSB7XG4gICAgaWYgKCF1dGlsLmhhc1ZhbHVlKGNvbW1hbmQuY29tbWFuZHMpKSB7XG4gICAgICAvLyB0aGlzIGlzIGEgbGVhZiwgc28gZW5kXG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgLy8gd3JpdGUgdGhpcyBub2RlXG4gICAgY29uc3QgcmVsUGF0aCA9IGNvbW1hbmQucGF0aC5zdGFydHNXaXRoKHBhdGguc2VwKSA/IGNvbW1hbmQucGF0aC5zdWJzdHJpbmcoMSkgOiBjb21tYW5kLnBhdGg7XG4gICAgY29uc3QgaW5kZXggPSBwYXRoLnJlc29sdmUocm9vdEZvbGRlciwgcmVsUGF0aCwgJ1JFQURNRS5tZCcpO1xuICAgIGF3YWl0IHdyaXRlSW5kZXgoaW5kZXgsIGNvbW1hbmQuY29tbWFuZHMsIGNvbW1hbmQucGF0aCk7XG5cbiAgICAvLyBnbyB0aHJvdWdoIGFsbCB0aGUgc3ViLWNvbW1hbmRzXG4gICAgZm9yIChjb25zdCBlbCBvZiBjb21tYW5kLmNvbW1hbmRzKSB7XG4gICAgICBhd2FpdCB3cml0ZUluZGl2aWR1YWxJbmRleGVzKGVsKTtcbiAgICB9XG4gIH1cblxuICAvLyBnbyB0aHJvdWdoIHRoZSBmdWxsIHRyZWUgYW5kIGdlbmVyYXRlIHJlYWRtZSBmaWxlc1xuICBjb25zdCBpbmRleCA9IHBhdGgucmVzb2x2ZShyb290Rm9sZGVyLCAnLi4vLi4nLCAnZG9jcycsICdlbicsICdjb21tYW5kcycsICdSRUFETUUubWQnKTtcbiAgYXdhaXQgd3JpdGVJbmRleChpbmRleCwgY29tbWFuZHMpO1xuICBmb3IgKGNvbnN0IGVsIG9mIGNvbW1hbmRzKSB7XG4gICAgYXdhaXQgd3JpdGVJbmRpdmlkdWFsSW5kZXhlcyhlbCk7XG4gIH1cbn1cblxuYXN5bmMgZnVuY3Rpb24gbWFpbiAoKSB7XG4gIGF3YWl0IGdlbmVyYXRlQ29tbWFuZHMoKTtcbiAgYXdhaXQgZ2VuZXJhdGVDb21tYW5kSW5kZXgoKTtcbn1cblxuYXN5bmNpZnkobWFpbik7XG4iXSwiZmlsZSI6ImNvbW1hbmRzLXltbC9wYXJzZS5qcyIsInNvdXJjZVJvb3QiOiIuLi8uLiJ9
|