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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (125) hide show
  1. package/README.md +1 -2
  2. package/build/lib/appium-config.schema.json +278 -0
  3. package/build/lib/appium.js +62 -71
  4. package/build/lib/cli/args.js +31 -53
  5. package/build/lib/cli/driver-command.js +5 -9
  6. package/build/lib/cli/extension-command.js +73 -64
  7. package/build/lib/cli/extension.js +10 -23
  8. package/build/lib/cli/parser.js +10 -20
  9. package/build/lib/cli/plugin-command.js +5 -9
  10. package/build/lib/cli/utils.js +2 -4
  11. package/build/lib/config-file.js +5 -10
  12. package/build/lib/config.js +67 -30
  13. package/build/lib/constants.js +60 -0
  14. package/build/lib/extension/driver-config.js +190 -0
  15. package/build/lib/extension/extension-config.js +297 -0
  16. package/build/lib/extension/index.js +77 -0
  17. package/build/lib/extension/manifest.js +246 -0
  18. package/build/lib/extension/package-changed.js +68 -0
  19. package/build/lib/extension/plugin-config.js +87 -0
  20. package/build/lib/grid-register.js +2 -4
  21. package/build/lib/logger.js +2 -4
  22. package/build/lib/logsink.js +2 -4
  23. package/build/lib/main.js +64 -92
  24. package/build/lib/schema/appium-config-schema.js +2 -4
  25. package/build/lib/schema/arg-spec.js +14 -15
  26. package/build/lib/schema/cli-args.js +8 -16
  27. package/build/lib/schema/cli-transformers.js +2 -4
  28. package/build/lib/schema/index.js +2 -4
  29. package/build/lib/schema/keywords.js +2 -4
  30. package/build/lib/schema/schema.js +136 -41
  31. package/build/lib/utils.js +13 -64
  32. package/lib/appium.js +74 -55
  33. package/lib/cli/args.js +36 -37
  34. package/lib/cli/driver-command.js +10 -2
  35. package/lib/cli/extension-command.js +216 -135
  36. package/lib/cli/extension.js +7 -15
  37. package/lib/cli/parser.js +7 -15
  38. package/lib/cli/plugin-command.js +1 -2
  39. package/lib/config-file.js +12 -15
  40. package/lib/config.js +111 -36
  41. package/lib/constants.js +79 -0
  42. package/lib/extension/driver-config.js +230 -0
  43. package/lib/extension/extension-config.js +459 -0
  44. package/lib/extension/index.js +103 -0
  45. package/lib/extension/manifest.js +590 -0
  46. package/lib/extension/package-changed.js +64 -0
  47. package/lib/extension/plugin-config.js +111 -0
  48. package/lib/grid-register.js +4 -4
  49. package/lib/main.js +110 -96
  50. package/lib/schema/arg-spec.js +11 -5
  51. package/lib/schema/cli-args.js +7 -30
  52. package/lib/schema/keywords.js +1 -1
  53. package/lib/schema/schema.js +206 -48
  54. package/lib/utils.js +27 -58
  55. package/package.json +29 -21
  56. package/{postinstall.js → scripts/postinstall.js} +1 -1
  57. package/types/types.d.ts +72 -28
  58. package/bin/ios-webkit-debug-proxy-launcher.js +0 -71
  59. package/build/check-npm-pack-files.js +0 -23
  60. package/build/commands-yml/parse.js +0 -319
  61. package/build/commands-yml/validator.js +0 -130
  62. package/build/index.js +0 -19
  63. package/build/lib/cli/npm.js +0 -220
  64. package/build/lib/driver-config.js +0 -100
  65. package/build/lib/drivers.js +0 -100
  66. package/build/lib/ext-config-io.js +0 -165
  67. package/build/lib/extension-config.js +0 -320
  68. package/build/lib/plugin-config.js +0 -69
  69. package/build/lib/plugins.js +0 -16
  70. package/build/postinstall.js +0 -90
  71. package/build/test/cli/cli-e2e-specs.js +0 -221
  72. package/build/test/cli/cli-helpers.js +0 -86
  73. package/build/test/cli/cli-specs.js +0 -71
  74. package/build/test/cli/fixtures/test-driver/package.json +0 -27
  75. package/build/test/cli/schema-args-specs.js +0 -48
  76. package/build/test/cli/schema-e2e-specs.js +0 -47
  77. package/build/test/config-e2e-specs.js +0 -112
  78. package/build/test/config-file-e2e-specs.js +0 -209
  79. package/build/test/config-file-specs.js +0 -281
  80. package/build/test/config-specs.js +0 -159
  81. package/build/test/driver-e2e-specs.js +0 -435
  82. package/build/test/driver-specs.js +0 -321
  83. package/build/test/ext-config-io-specs.js +0 -181
  84. package/build/test/extension-config-specs.js +0 -365
  85. package/build/test/fixtures/allow-feat.txt +0 -5
  86. package/build/test/fixtures/caps.json +0 -3
  87. package/build/test/fixtures/config/allow-insecure.txt +0 -3
  88. package/build/test/fixtures/config/appium.config.bad-nodeconfig.json +0 -5
  89. package/build/test/fixtures/config/appium.config.bad.json +0 -32
  90. package/build/test/fixtures/config/appium.config.ext-good.json +0 -9
  91. package/build/test/fixtures/config/appium.config.ext-unknown-props.json +0 -10
  92. package/build/test/fixtures/config/appium.config.good.js +0 -40
  93. package/build/test/fixtures/config/appium.config.good.json +0 -33
  94. package/build/test/fixtures/config/appium.config.good.yaml +0 -30
  95. package/build/test/fixtures/config/appium.config.invalid.json +0 -31
  96. package/build/test/fixtures/config/appium.config.security-array.json +0 -5
  97. package/build/test/fixtures/config/appium.config.security-delimited.json +0 -5
  98. package/build/test/fixtures/config/appium.config.security-path.json +0 -5
  99. package/build/test/fixtures/config/driver-fake.config.json +0 -8
  100. package/build/test/fixtures/config/nodeconfig.json +0 -3
  101. package/build/test/fixtures/config/plugin-fake.config.json +0 -0
  102. package/build/test/fixtures/default-args.js +0 -35
  103. package/build/test/fixtures/deny-feat.txt +0 -5
  104. package/build/test/fixtures/driver.schema.js +0 -20
  105. package/build/test/fixtures/extensions.yaml +0 -27
  106. package/build/test/fixtures/flattened-schema.js +0 -504
  107. package/build/test/fixtures/plugin.schema.js +0 -20
  108. package/build/test/fixtures/schema-with-extensions.js +0 -28
  109. package/build/test/grid-register-specs.js +0 -74
  110. package/build/test/helpers.js +0 -75
  111. package/build/test/logger-specs.js +0 -76
  112. package/build/test/npm-specs.js +0 -20
  113. package/build/test/parser-specs.js +0 -314
  114. package/build/test/plugin-e2e-specs.js +0 -316
  115. package/build/test/schema/arg-spec-specs.js +0 -70
  116. package/build/test/schema/cli-args-specs.js +0 -431
  117. package/build/test/schema/schema-specs.js +0 -389
  118. package/build/test/utils-specs.js +0 -266
  119. package/lib/cli/npm.js +0 -251
  120. package/lib/driver-config.js +0 -101
  121. package/lib/drivers.js +0 -84
  122. package/lib/ext-config-io.js +0 -287
  123. package/lib/extension-config.js +0 -366
  124. package/lib/plugin-config.js +0 -63
  125. package/lib/plugins.js +0 -11
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
- } from '../lib/ext-config-io';
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 ParsedArgsFromConfig = {
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 CliSubCommands =
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 CliExtensionSubcommands =
144
- | 'list'
145
- | 'install'
146
- | 'uninstall'
147
- | 'update'
148
- | 'run';
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: string;
163
+ configFile?: string;
159
164
 
160
165
  /**
161
- * If true, show the build info and exit
166
+ * If true, show the config and exit
162
167
  */
163
- showConfig: boolean;
168
+ showConfig?: boolean;
164
169
 
165
170
  /**
166
171
  * If true, open a REPL
167
172
  */
168
- shell: boolean;
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, throw on error instead of exit. Not supported via CLI, but rather
172
- * only programmatic usage.
207
+ * If true, show the build info and exit
173
208
  */
174
- throwInsteadOfExit: boolean;
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
- * Subcommands of `driver` subcommand
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
- pluginCommand: CliExtensionSubcommands;
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 = ParsedArgsFromConfig & Partial<MoreArgs>;
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