appium-android-driver 5.13.0 → 5.13.2

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 (151) hide show
  1. package/CHANGELOG.md +14 -0
  2. package/build/index.js +43 -40
  3. package/build/lib/android-helpers.d.ts +136 -0
  4. package/build/lib/android-helpers.d.ts.map +1 -0
  5. package/build/lib/android-helpers.js +760 -679
  6. package/build/lib/android-helpers.js.map +1 -1
  7. package/build/lib/bootstrap.d.ts +29 -0
  8. package/build/lib/bootstrap.d.ts.map +1 -0
  9. package/build/lib/bootstrap.js +192 -179
  10. package/build/lib/bootstrap.js.map +1 -1
  11. package/build/lib/commands/actions.d.ts +209 -0
  12. package/build/lib/commands/actions.d.ts.map +1 -0
  13. package/build/lib/commands/actions.js +327 -265
  14. package/build/lib/commands/actions.js.map +1 -1
  15. package/build/lib/commands/alert.d.ts +10 -0
  16. package/build/lib/commands/alert.d.ts.map +1 -0
  17. package/build/lib/commands/alert.js +12 -18
  18. package/build/lib/commands/alert.js.map +1 -1
  19. package/build/lib/commands/app-management.d.ts +314 -0
  20. package/build/lib/commands/app-management.d.ts.map +1 -0
  21. package/build/lib/commands/app-management.js +278 -110
  22. package/build/lib/commands/app-management.js.map +1 -1
  23. package/build/lib/commands/context.d.ts +94 -0
  24. package/build/lib/commands/context.d.ts.map +1 -0
  25. package/build/lib/commands/context.js +412 -260
  26. package/build/lib/commands/context.js.map +1 -1
  27. package/build/lib/commands/coverage.d.ts +5 -0
  28. package/build/lib/commands/coverage.d.ts.map +1 -0
  29. package/build/lib/commands/coverage.js +14 -17
  30. package/build/lib/commands/coverage.js.map +1 -1
  31. package/build/lib/commands/element.d.ts +36 -0
  32. package/build/lib/commands/element.d.ts.map +1 -0
  33. package/build/lib/commands/element.js +97 -127
  34. package/build/lib/commands/element.js.map +1 -1
  35. package/build/lib/commands/emu-console.d.ts +49 -0
  36. package/build/lib/commands/emu-console.d.ts.map +1 -0
  37. package/build/lib/commands/emu-console.js +36 -25
  38. package/build/lib/commands/emu-console.js.map +1 -1
  39. package/build/lib/commands/execute.d.ts +6 -0
  40. package/build/lib/commands/execute.d.ts.map +1 -0
  41. package/build/lib/commands/execute.js +68 -69
  42. package/build/lib/commands/execute.js.map +1 -1
  43. package/build/lib/commands/file-actions.d.ts +129 -0
  44. package/build/lib/commands/file-actions.d.ts.map +1 -0
  45. package/build/lib/commands/file-actions.js +321 -178
  46. package/build/lib/commands/file-actions.js.map +1 -1
  47. package/build/lib/commands/find.d.ts +13 -0
  48. package/build/lib/commands/find.d.ts.map +1 -0
  49. package/build/lib/commands/find.js +69 -51
  50. package/build/lib/commands/find.js.map +1 -1
  51. package/build/lib/commands/general.d.ts +133 -0
  52. package/build/lib/commands/general.d.ts.map +1 -0
  53. package/build/lib/commands/general.js +275 -216
  54. package/build/lib/commands/general.js.map +1 -1
  55. package/build/lib/commands/ime.d.ts +11 -0
  56. package/build/lib/commands/ime.d.ts.map +1 -0
  57. package/build/lib/commands/ime.js +27 -33
  58. package/build/lib/commands/ime.js.map +1 -1
  59. package/build/lib/commands/index.d.ts +3 -0
  60. package/build/lib/commands/index.d.ts.map +1 -0
  61. package/build/lib/commands/index.js +32 -35
  62. package/build/lib/commands/index.js.map +1 -1
  63. package/build/lib/commands/intent.d.ts +418 -0
  64. package/build/lib/commands/intent.d.ts.map +1 -0
  65. package/build/lib/commands/intent.js +281 -151
  66. package/build/lib/commands/intent.js.map +1 -1
  67. package/build/lib/commands/keyboard.d.ts +6 -0
  68. package/build/lib/commands/keyboard.d.ts.map +1 -0
  69. package/build/lib/commands/keyboard.js +6 -14
  70. package/build/lib/commands/keyboard.js.map +1 -1
  71. package/build/lib/commands/log.d.ts +45 -0
  72. package/build/lib/commands/log.d.ts.map +1 -0
  73. package/build/lib/commands/log.js +117 -103
  74. package/build/lib/commands/log.js.map +1 -1
  75. package/build/lib/commands/media-projection.d.ts +144 -0
  76. package/build/lib/commands/media-projection.d.ts.map +1 -0
  77. package/build/lib/commands/media-projection.js +228 -171
  78. package/build/lib/commands/media-projection.js.map +1 -1
  79. package/build/lib/commands/network.d.ts +139 -0
  80. package/build/lib/commands/network.d.ts.map +1 -0
  81. package/build/lib/commands/network.js +249 -181
  82. package/build/lib/commands/network.js.map +1 -1
  83. package/build/lib/commands/performance.d.ts +101 -0
  84. package/build/lib/commands/performance.d.ts.map +1 -0
  85. package/build/lib/commands/performance.js +390 -236
  86. package/build/lib/commands/performance.js.map +1 -1
  87. package/build/lib/commands/permissions.d.ts +93 -0
  88. package/build/lib/commands/permissions.d.ts.map +1 -0
  89. package/build/lib/commands/permissions.js +133 -93
  90. package/build/lib/commands/permissions.js.map +1 -1
  91. package/build/lib/commands/recordscreen.d.ts +194 -0
  92. package/build/lib/commands/recordscreen.d.ts.map +1 -0
  93. package/build/lib/commands/recordscreen.js +293 -224
  94. package/build/lib/commands/recordscreen.js.map +1 -1
  95. package/build/lib/commands/shell.d.ts +8 -0
  96. package/build/lib/commands/shell.d.ts.map +1 -0
  97. package/build/lib/commands/shell.js +38 -43
  98. package/build/lib/commands/shell.js.map +1 -1
  99. package/build/lib/commands/streamscreen.d.ts +104 -0
  100. package/build/lib/commands/streamscreen.d.ts.map +1 -0
  101. package/build/lib/commands/streamscreen.js +364 -305
  102. package/build/lib/commands/streamscreen.js.map +1 -1
  103. package/build/lib/commands/system-bars.d.ts +100 -0
  104. package/build/lib/commands/system-bars.d.ts.map +1 -0
  105. package/build/lib/commands/system-bars.js +148 -90
  106. package/build/lib/commands/system-bars.js.map +1 -1
  107. package/build/lib/commands/touch.d.ts +30 -0
  108. package/build/lib/commands/touch.d.ts.map +1 -0
  109. package/build/lib/commands/touch.js +311 -287
  110. package/build/lib/commands/touch.js.map +1 -1
  111. package/build/lib/desired-caps.d.ts +353 -0
  112. package/build/lib/desired-caps.d.ts.map +1 -0
  113. package/build/lib/desired-caps.js +291 -292
  114. package/build/lib/desired-caps.js.map +1 -1
  115. package/build/lib/driver.d.ts +430 -0
  116. package/build/lib/driver.d.ts.map +1 -0
  117. package/build/lib/driver.js +449 -384
  118. package/build/lib/driver.js.map +1 -1
  119. package/build/lib/logger.d.ts +3 -0
  120. package/build/lib/logger.d.ts.map +1 -0
  121. package/build/lib/logger.js +5 -11
  122. package/build/lib/logger.js.map +1 -1
  123. package/build/lib/method-map.d.ts +389 -0
  124. package/build/lib/method-map.d.ts.map +1 -0
  125. package/build/lib/method-map.js +220 -394
  126. package/build/lib/method-map.js.map +1 -1
  127. package/build/lib/stubs.d.ts +8 -0
  128. package/build/lib/stubs.d.ts.map +1 -0
  129. package/build/lib/stubs.js +5 -0
  130. package/build/lib/stubs.js.map +1 -0
  131. package/build/lib/uiautomator.d.ts +24 -0
  132. package/build/lib/uiautomator.d.ts.map +1 -0
  133. package/build/lib/uiautomator.js +86 -82
  134. package/build/lib/uiautomator.js.map +1 -1
  135. package/build/lib/unlock-helpers.d.ts +38 -0
  136. package/build/lib/unlock-helpers.d.ts.map +1 -0
  137. package/build/lib/unlock-helpers.js +228 -204
  138. package/build/lib/unlock-helpers.js.map +1 -1
  139. package/build/lib/utils.d.ts +11 -0
  140. package/build/lib/utils.d.ts.map +1 -0
  141. package/build/lib/utils.js +23 -18
  142. package/build/lib/utils.js.map +1 -1
  143. package/build/lib/webview-helpers.d.ts +223 -0
  144. package/build/lib/webview-helpers.d.ts.map +1 -0
  145. package/build/lib/webview-helpers.js +476 -298
  146. package/build/lib/webview-helpers.js.map +1 -1
  147. package/index.js +3 -1
  148. package/lib/android-helpers.js +2 -1
  149. package/lib/stubs.ts +8 -0
  150. package/lib/unlock-helpers.js +2 -2
  151. package/package.json +23 -14
@@ -1,196 +1,253 @@
1
1
  "use strict";
2
-
3
- var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
4
- Object.defineProperty(exports, "__esModule", {
5
- value: true
6
- });
7
- exports.default = exports.commands = void 0;
8
- require("source-map-support/register");
9
- var _lodash = _interopRequireDefault(require("lodash"));
10
- var _asyncbox = require("asyncbox");
11
- var _support = require("@appium/support");
12
- var _path = _interopRequireDefault(require("path"));
13
- var _bluebird = _interopRequireDefault(require("bluebird"));
14
- var _androidHelpers = require("../android-helpers");
15
- var _moment = _interopRequireDefault(require("moment"));
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.commands = void 0;
7
+ const lodash_1 = __importDefault(require("lodash"));
8
+ const asyncbox_1 = require("asyncbox");
9
+ const support_1 = require("@appium/support");
10
+ const path_1 = __importDefault(require("path"));
11
+ const bluebird_1 = __importDefault(require("bluebird"));
12
+ const android_helpers_1 = require("../android-helpers");
13
+ const moment_1 = __importDefault(require("moment"));
16
14
  const commands = {};
17
15
  exports.commands = commands;
16
+ // https://github.com/appium/io.appium.settings#internal-audio--video-recording
18
17
  const DEFAULT_EXT = '.mp4';
19
18
  const RECORDING_STARTUP_TIMEOUT_MS = 3 * 1000;
20
19
  const RECORDING_STOP_TIMEOUT_MS = 3 * 1000;
21
20
  const MIN_API_LEVEL = 29;
22
- const RECORDING_SERVICE_NAME = `${_androidHelpers.SETTINGS_HELPER_PKG_ID}/.recorder.RecorderService`;
23
- const RECORDING_ACTIVITY_NAME = `${_androidHelpers.SETTINGS_HELPER_PKG_ID}/io.appium.settings.Settings`;
24
- const RECORDING_ACTION_START = `${_androidHelpers.SETTINGS_HELPER_PKG_ID}.recording.ACTION_START`;
25
- const RECORDING_ACTION_STOP = `${_androidHelpers.SETTINGS_HELPER_PKG_ID}.recording.ACTION_STOP`;
26
- const RECORDINGS_ROOT = `/storage/emulated/0/Android/data/${_androidHelpers.SETTINGS_HELPER_PKG_ID}/files`;
21
+ const RECORDING_SERVICE_NAME = `${android_helpers_1.SETTINGS_HELPER_PKG_ID}/.recorder.RecorderService`;
22
+ const RECORDING_ACTIVITY_NAME = `${android_helpers_1.SETTINGS_HELPER_PKG_ID}/io.appium.settings.Settings`;
23
+ const RECORDING_ACTION_START = `${android_helpers_1.SETTINGS_HELPER_PKG_ID}.recording.ACTION_START`;
24
+ const RECORDING_ACTION_STOP = `${android_helpers_1.SETTINGS_HELPER_PKG_ID}.recording.ACTION_STOP`;
25
+ const RECORDINGS_ROOT = `/storage/emulated/0/Android/data/${android_helpers_1.SETTINGS_HELPER_PKG_ID}/files`;
27
26
  const DEFAULT_FILENAME_FORMAT = 'YYYY-MM-DDTHH-mm-ss';
28
27
  async function uploadRecordedMedia(localFile, remotePath = null, uploadOptions = {}) {
29
- if (_lodash.default.isEmpty(remotePath)) {
30
- return (await _support.util.toInMemoryBase64(localFile)).toString();
31
- }
32
- const {
33
- user,
34
- pass,
35
- method,
36
- headers,
37
- fileFieldName,
38
- formFields,
39
- uploadTimeout: timeout
40
- } = uploadOptions;
41
- const options = {
42
- method: method || 'PUT',
43
- headers,
44
- fileFieldName,
45
- formFields,
46
- timeout
47
- };
48
- if (user && pass) {
49
- options.auth = {
50
- user,
51
- pass
28
+ if (lodash_1.default.isEmpty(remotePath)) {
29
+ return (await support_1.util.toInMemoryBase64(localFile)).toString();
30
+ }
31
+ const { user, pass, method, headers, fileFieldName, formFields, uploadTimeout: timeout, } = uploadOptions;
32
+ const options = {
33
+ method: method || 'PUT',
34
+ headers,
35
+ fileFieldName,
36
+ formFields,
37
+ timeout,
52
38
  };
53
- }
54
- await _support.net.uploadFile(localFile, remotePath, options);
55
- return '';
39
+ if (user && pass) {
40
+ options.auth = { user, pass };
41
+ }
42
+ await support_1.net.uploadFile(localFile, remotePath, options);
43
+ return '';
56
44
  }
57
45
  function adjustMediaExtension(name) {
58
- return _lodash.default.toLower(name).endsWith(DEFAULT_EXT) ? name : `${name}${DEFAULT_EXT}`;
46
+ return lodash_1.default.toLower(name).endsWith(DEFAULT_EXT) ? name : `${name}${DEFAULT_EXT}`;
59
47
  }
60
48
  async function verifyMediaProjectionRecordingIsSupported(adb) {
61
- const apiLevel = await adb.getApiLevel();
62
- if (apiLevel < MIN_API_LEVEL) {
63
- throw new Error(`Media projection-based recording is not available on API Level ${apiLevel}. ` + `Minimum required API Level is ${MIN_API_LEVEL}.`);
64
- }
49
+ const apiLevel = await adb.getApiLevel();
50
+ if (apiLevel < MIN_API_LEVEL) {
51
+ throw new Error(`Media projection-based recording is not available on API Level ${apiLevel}. ` +
52
+ `Minimum required API Level is ${MIN_API_LEVEL}.`);
53
+ }
65
54
  }
66
55
  class MediaProjectionRecorder {
67
- constructor(adb) {
68
- this.adb = adb;
69
- }
70
- async isRunning() {
71
- const stdout = await this.adb.shell(['dumpsys', 'activity', 'services', RECORDING_SERVICE_NAME]);
72
- return stdout.includes(RECORDING_SERVICE_NAME);
73
- }
74
- async start(opts = {}) {
75
- if (await this.isRunning()) {
76
- return false;
77
- }
78
- await this.cleanup();
79
- const {
80
- filename,
81
- maxDurationSec,
82
- priority,
83
- resolution
84
- } = opts;
85
- const args = ['am', 'start', '-n', RECORDING_ACTIVITY_NAME, '-a', RECORDING_ACTION_START];
86
- if (filename) {
87
- args.push('--es', 'filename', filename);
88
- }
89
- if (maxDurationSec) {
90
- args.push('--es', 'max_duration_sec', `${maxDurationSec}`);
91
- }
92
- if (priority) {
93
- args.push('--es', 'priority', priority);
94
- }
95
- if (resolution) {
96
- args.push('--es', 'resolution', resolution);
97
- }
98
- await this.adb.shell(args);
99
- await new _bluebird.default((resolve, reject) => {
100
- setTimeout(async () => {
101
- if (!(await this.isRunning())) {
102
- return reject(new Error(`The media projection recording is not running after ${RECORDING_STARTUP_TIMEOUT_MS}ms. ` + `Please check the logcat output for more details.`));
56
+ constructor(adb) {
57
+ this.adb = adb;
58
+ }
59
+ async isRunning() {
60
+ const stdout = await this.adb.shell([
61
+ 'dumpsys', 'activity', 'services', RECORDING_SERVICE_NAME
62
+ ]);
63
+ return stdout.includes(RECORDING_SERVICE_NAME);
64
+ }
65
+ async start(opts = {}) {
66
+ if (await this.isRunning()) {
67
+ return false;
103
68
  }
104
- resolve();
105
- }, RECORDING_STARTUP_TIMEOUT_MS);
106
- });
107
- return true;
108
- }
109
- async cleanup() {
110
- await this.adb.shell([`rm -f ${RECORDINGS_ROOT}/*`]);
111
- }
112
- async pullRecent() {
113
- const recordings = await this.adb.ls(RECORDINGS_ROOT, ['-tr']);
114
- if (_lodash.default.isEmpty(recordings)) {
115
- return null;
116
- }
117
- const dstPath = _path.default.join(await _support.tempDir.openDir(), recordings[0]);
118
- await this.adb.pull(`${RECORDINGS_ROOT}/${recordings[0]}`, dstPath, {
119
- timeout: 300000
120
- });
121
- return dstPath;
122
- }
123
- async stop() {
124
- if (!(await this.isRunning())) {
125
- return false;
69
+ await this.cleanup();
70
+ const { filename, maxDurationSec, priority, resolution, } = opts;
71
+ const args = [
72
+ 'am', 'start',
73
+ '-n', RECORDING_ACTIVITY_NAME,
74
+ '-a', RECORDING_ACTION_START,
75
+ ];
76
+ if (filename) {
77
+ args.push('--es', 'filename', filename);
78
+ }
79
+ if (maxDurationSec) {
80
+ args.push('--es', 'max_duration_sec', `${maxDurationSec}`);
81
+ }
82
+ if (priority) {
83
+ args.push('--es', 'priority', priority);
84
+ }
85
+ if (resolution) {
86
+ args.push('--es', 'resolution', resolution);
87
+ }
88
+ await this.adb.shell(args);
89
+ await new bluebird_1.default((resolve, reject) => {
90
+ setTimeout(async () => {
91
+ if (!await this.isRunning()) {
92
+ return reject(new Error(`The media projection recording is not running after ${RECORDING_STARTUP_TIMEOUT_MS}ms. ` +
93
+ `Please check the logcat output for more details.`));
94
+ }
95
+ resolve();
96
+ }, RECORDING_STARTUP_TIMEOUT_MS);
97
+ });
98
+ return true;
99
+ }
100
+ async cleanup() {
101
+ await this.adb.shell([`rm -f ${RECORDINGS_ROOT}/*`]);
102
+ }
103
+ async pullRecent() {
104
+ const recordings = await this.adb.ls(RECORDINGS_ROOT, ['-tr']);
105
+ if (lodash_1.default.isEmpty(recordings)) {
106
+ return null;
107
+ }
108
+ const dstPath = path_1.default.join(await support_1.tempDir.openDir(), recordings[0]);
109
+ // increase timeout to 5 minutes because it might take a while to pull a large video file
110
+ await this.adb.pull(`${RECORDINGS_ROOT}/${recordings[0]}`, dstPath, { timeout: 300000 });
111
+ return dstPath;
112
+ }
113
+ async stop() {
114
+ if (!await this.isRunning()) {
115
+ return false;
116
+ }
117
+ await this.adb.shell([
118
+ 'am', 'start',
119
+ '-n', RECORDING_ACTIVITY_NAME,
120
+ '-a', RECORDING_ACTION_STOP,
121
+ ]);
122
+ try {
123
+ await (0, asyncbox_1.waitForCondition)(async () => !(await this.isRunning()), {
124
+ waitMs: RECORDING_STOP_TIMEOUT_MS,
125
+ intervalMs: 500,
126
+ });
127
+ }
128
+ catch (e) {
129
+ throw new Error(`The attempt to stop the current media projection recording timed out after ` +
130
+ `${RECORDING_STOP_TIMEOUT_MS}ms`);
131
+ }
132
+ return true;
126
133
  }
127
- await this.adb.shell(['am', 'start', '-n', RECORDING_ACTIVITY_NAME, '-a', RECORDING_ACTION_STOP]);
128
- try {
129
- await (0, _asyncbox.waitForCondition)(async () => !(await this.isRunning()), {
130
- waitMs: RECORDING_STOP_TIMEOUT_MS,
131
- intervalMs: 500
132
- });
133
- } catch (e) {
134
- throw new Error(`The attempt to stop the current media projection recording timed out after ` + `${RECORDING_STOP_TIMEOUT_MS}ms`);
135
- }
136
- return true;
137
- }
138
134
  }
135
+ /**
136
+ * @typedef {Object} StartRecordingOptions
137
+ *
138
+ * @property {string?} resolution Maximum supported resolution on-device (Detected
139
+ * automatically by the app itself), which usually equals to Full HD 1920x1080 on most
140
+ * phones however you can change it to following supported resolutions
141
+ * as well: "1920x1080", "1280x720", "720x480", "320x240", "176x144".
142
+ * @property {number?} maxDurationSec [900] Default value: 900 seconds which means
143
+ * maximum allowed duration is 15 minute, you can increase it if your test takes
144
+ * longer than that.
145
+ * @property {string?} priority [high] Means recording thread priority is maximum
146
+ * however if you face performance drops during testing with recording enabled, you
147
+ * can reduce recording priority to "normal" or "low".
148
+ * @property {string?} filename You can type recording video file name as you want,
149
+ * but recording currently supports only "mp4" format so your filename must end with ".mp4".
150
+ * An invalid file name will fail to start the recording.
151
+ * If not provided then the current timestamp will be used as file name.
152
+ */
153
+ /**
154
+ * Record the display of a real devices running Android 10 (API level 29) and higher.
155
+ * The screen activity is recorded to a MPEG-4 file. Audio is also recorded by default
156
+ * (only for apps that allow it in their manifests).
157
+ * If another recording has been already started then the command will exit silently.
158
+ * The previously recorded video file is deleted when a new recording session is started.
159
+ * Recording continues it is stopped explicitly or until the timeout happens.
160
+ *
161
+ * @param {?StartRecordingOptions} options Available options.
162
+ * @returns {boolean} True if a new recording has successfully started.
163
+ * @throws {Error} If recording has failed to start or is not supported on the device under test.
164
+ */
139
165
  commands.mobileStartMediaProjectionRecording = async function mobileStartMediaProjectionRecording(options = {}) {
140
- await verifyMediaProjectionRecordingIsSupported(this.adb);
141
- const {
142
- resolution,
143
- priority,
144
- maxDurationSec,
145
- filename
146
- } = options;
147
- const recorder = new MediaProjectionRecorder(this.adb);
148
- const fname = adjustMediaExtension(filename || (0, _moment.default)().format(DEFAULT_FILENAME_FORMAT));
149
- const didStart = await recorder.start({
150
- resolution,
151
- priority,
152
- maxDurationSec,
153
- filename: fname
154
- });
155
- if (didStart) {
156
- this.log.info(`A new media projection recording '${fname}' has been successfully started`);
157
- } else {
158
- this.log.info('Another media projection recording is already in progress. There is nothing to start');
159
- }
160
- return didStart;
166
+ await verifyMediaProjectionRecordingIsSupported(this.adb);
167
+ const { resolution, priority, maxDurationSec, filename } = options;
168
+ const recorder = new MediaProjectionRecorder(this.adb);
169
+ const fname = adjustMediaExtension(filename || (0, moment_1.default)().format(DEFAULT_FILENAME_FORMAT));
170
+ const didStart = await recorder.start({
171
+ resolution,
172
+ priority,
173
+ maxDurationSec,
174
+ filename: fname,
175
+ });
176
+ if (didStart) {
177
+ this.log.info(`A new media projection recording '${fname}' has been successfully started`);
178
+ }
179
+ else {
180
+ this.log.info('Another media projection recording is already in progress. There is nothing to start');
181
+ }
182
+ return didStart;
161
183
  };
184
+ /**
185
+ * Checks if a media projection-based recording is currently running.
186
+ *
187
+ * @returns {boolean} True if a recording is in progress.
188
+ * @throws {Error} If a recording is not supported on the device under test.
189
+ */
162
190
  commands.mobileIsMediaProjectionRecordingRunning = async function mobileIsMediaProjectionRecordingRunning() {
163
- await verifyMediaProjectionRecordingIsSupported(this.adb);
164
- const recorder = new MediaProjectionRecorder(this.adb);
165
- return await recorder.isRunning();
191
+ await verifyMediaProjectionRecordingIsSupported(this.adb);
192
+ const recorder = new MediaProjectionRecorder(this.adb);
193
+ return await recorder.isRunning();
166
194
  };
195
+ /**
196
+ * @typedef {Object} StopRecordingOptions
197
+ *
198
+ * @property {string?} remotePath The path to the remote location, where the resulting video should be uploaded.
199
+ * The following protocols are supported: http/https, ftp.
200
+ * Null or empty string value (the default setting) means the content of resulting
201
+ * file should be encoded as Base64 and passed as the endpoont response value.
202
+ * An exception will be thrown if the generated media file is too big to
203
+ * fit into the available process memory.
204
+ * @property {string?} user The name of the user for the remote authentication.
205
+ * @property {string?} pass The password for the remote authentication.
206
+ * @property {string?} method The http multipart upload method name. The 'PUT' one is used by default.
207
+ * @property {Object?} headers Additional headers mapping for multipart http(s) uploads
208
+ * @property {string?} fileFieldName [file] The name of the form field, where the file content BLOB should be stored for
209
+ * http(s) uploads
210
+ * @property {Object|Array<Pair>?} formFields Additional form fields for multipart http(s) uploads
211
+ * @property {number?} uploadTimeout - The actual media upload request timeout in milliseconds;
212
+ * defaults to @appium/support net DEFAULT_TIMEOUT_MS
213
+ */
214
+ /**
215
+ * Stop a media projection-based recording.
216
+ * If no recording has been started before then an error is thrown.
217
+ * If the recording has been already finished before this API has been called
218
+ * then the most recent recorded file is returned.
219
+ *
220
+ * @param {?StopRecordingOptions} options Available options.
221
+ * @returns {string} Base64-encoded content of the recorded media file if 'remotePath'
222
+ * parameter is falsy or an empty string.
223
+ * @throws {Error} If there was an error while stopping a recording,
224
+ * fetching the content of the remote media file,
225
+ * or if a recording is not supported on the device under test.
226
+ */
167
227
  commands.mobileStopMediaProjectionRecording = async function mobileStopMediaProjectionRecording(options = {}) {
168
- await verifyMediaProjectionRecordingIsSupported(this.adb);
169
- const recorder = new MediaProjectionRecorder(this.adb);
170
- if (await recorder.stop()) {
171
- this.log.info('Successfully stopped a media projection recording. Pulling the recorded media');
172
- } else {
173
- this.log.info('Media projection recording is not running. There is nothing to stop');
174
- }
175
- const recentRecordingPath = await recorder.pullRecent();
176
- if (!recentRecordingPath) {
177
- throw new Error(`No recent media projection recording have been found. Did you start any?`);
178
- }
179
- const {
180
- remotePath
181
- } = options;
182
- if (_lodash.default.isEmpty(remotePath)) {
183
- const {
184
- size
185
- } = await _support.fs.stat(recentRecordingPath);
186
- this.log.debug(`The size of the resulting media projection recording is ${_support.util.toReadableSizeString(size)}`);
187
- }
188
- try {
189
- return await uploadRecordedMedia(recentRecordingPath, remotePath, options);
190
- } finally {
191
- await _support.fs.rimraf(_path.default.dirname(recentRecordingPath));
192
- }
228
+ await verifyMediaProjectionRecordingIsSupported(this.adb);
229
+ const recorder = new MediaProjectionRecorder(this.adb);
230
+ if (await recorder.stop()) {
231
+ this.log.info('Successfully stopped a media projection recording. Pulling the recorded media');
232
+ }
233
+ else {
234
+ this.log.info('Media projection recording is not running. There is nothing to stop');
235
+ }
236
+ const recentRecordingPath = await recorder.pullRecent();
237
+ if (!recentRecordingPath) {
238
+ throw new Error(`No recent media projection recording have been found. Did you start any?`);
239
+ }
240
+ const { remotePath } = options;
241
+ if (lodash_1.default.isEmpty(remotePath)) {
242
+ const { size } = await support_1.fs.stat(recentRecordingPath);
243
+ this.log.debug(`The size of the resulting media projection recording is ${support_1.util.toReadableSizeString(size)}`);
244
+ }
245
+ try {
246
+ return await uploadRecordedMedia(recentRecordingPath, remotePath, options);
247
+ }
248
+ finally {
249
+ await support_1.fs.rimraf(path_1.default.dirname(recentRecordingPath));
250
+ }
193
251
  };
194
- var _default = commands;
195
- exports.default = _default;
196
- //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJfbG9kYXNoIiwiX2ludGVyb3BSZXF1aXJlRGVmYXVsdCIsInJlcXVpcmUiLCJfYXN5bmNib3giLCJfc3VwcG9ydCIsIl9wYXRoIiwiX2JsdWViaXJkIiwiX2FuZHJvaWRIZWxwZXJzIiwiX21vbWVudCIsImNvbW1hbmRzIiwiZXhwb3J0cyIsIkRFRkFVTFRfRVhUIiwiUkVDT1JESU5HX1NUQVJUVVBfVElNRU9VVF9NUyIsIlJFQ09SRElOR19TVE9QX1RJTUVPVVRfTVMiLCJNSU5fQVBJX0xFVkVMIiwiUkVDT1JESU5HX1NFUlZJQ0VfTkFNRSIsIlNFVFRJTkdTX0hFTFBFUl9QS0dfSUQiLCJSRUNPUkRJTkdfQUNUSVZJVFlfTkFNRSIsIlJFQ09SRElOR19BQ1RJT05fU1RBUlQiLCJSRUNPUkRJTkdfQUNUSU9OX1NUT1AiLCJSRUNPUkRJTkdTX1JPT1QiLCJERUZBVUxUX0ZJTEVOQU1FX0ZPUk1BVCIsInVwbG9hZFJlY29yZGVkTWVkaWEiLCJsb2NhbEZpbGUiLCJyZW1vdGVQYXRoIiwidXBsb2FkT3B0aW9ucyIsIl8iLCJpc0VtcHR5IiwidXRpbCIsInRvSW5NZW1vcnlCYXNlNjQiLCJ0b1N0cmluZyIsInVzZXIiLCJwYXNzIiwibWV0aG9kIiwiaGVhZGVycyIsImZpbGVGaWVsZE5hbWUiLCJmb3JtRmllbGRzIiwidXBsb2FkVGltZW91dCIsInRpbWVvdXQiLCJvcHRpb25zIiwiYXV0aCIsIm5ldCIsInVwbG9hZEZpbGUiLCJhZGp1c3RNZWRpYUV4dGVuc2lvbiIsIm5hbWUiLCJ0b0xvd2VyIiwiZW5kc1dpdGgiLCJ2ZXJpZnlNZWRpYVByb2plY3Rpb25SZWNvcmRpbmdJc1N1cHBvcnRlZCIsImFkYiIsImFwaUxldmVsIiwiZ2V0QXBpTGV2ZWwiLCJFcnJvciIsIk1lZGlhUHJvamVjdGlvblJlY29yZGVyIiwiY29uc3RydWN0b3IiLCJpc1J1bm5pbmciLCJzdGRvdXQiLCJzaGVsbCIsImluY2x1ZGVzIiwic3RhcnQiLCJvcHRzIiwiY2xlYW51cCIsImZpbGVuYW1lIiwibWF4RHVyYXRpb25TZWMiLCJwcmlvcml0eSIsInJlc29sdXRpb24iLCJhcmdzIiwicHVzaCIsIkIiLCJyZXNvbHZlIiwicmVqZWN0Iiwic2V0VGltZW91dCIsInB1bGxSZWNlbnQiLCJyZWNvcmRpbmdzIiwibHMiLCJkc3RQYXRoIiwicGF0aCIsImpvaW4iLCJ0ZW1wRGlyIiwib3BlbkRpciIsInB1bGwiLCJzdG9wIiwid2FpdEZvckNvbmRpdGlvbiIsIndhaXRNcyIsImludGVydmFsTXMiLCJlIiwibW9iaWxlU3RhcnRNZWRpYVByb2plY3Rpb25SZWNvcmRpbmciLCJyZWNvcmRlciIsImZuYW1lIiwibW9tZW50IiwiZm9ybWF0IiwiZGlkU3RhcnQiLCJsb2ciLCJpbmZvIiwibW9iaWxlSXNNZWRpYVByb2plY3Rpb25SZWNvcmRpbmdSdW5uaW5nIiwibW9iaWxlU3RvcE1lZGlhUHJvamVjdGlvblJlY29yZGluZyIsInJlY2VudFJlY29yZGluZ1BhdGgiLCJzaXplIiwiZnMiLCJzdGF0IiwiZGVidWciLCJ0b1JlYWRhYmxlU2l6ZVN0cmluZyIsInJpbXJhZiIsImRpcm5hbWUiLCJfZGVmYXVsdCIsImRlZmF1bHQiXSwic291cmNlcyI6WyIuLi8uLi8uLi9saWIvY29tbWFuZHMvbWVkaWEtcHJvamVjdGlvbi5qcyJdLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgXyBmcm9tICdsb2Rhc2gnO1xuaW1wb3J0IHsgd2FpdEZvckNvbmRpdGlvbiB9IGZyb20gJ2FzeW5jYm94JztcbmltcG9ydCB7IHV0aWwsIGZzLCBuZXQsIHRlbXBEaXIgfSBmcm9tICdAYXBwaXVtL3N1cHBvcnQnO1xuaW1wb3J0IHBhdGggZnJvbSAncGF0aCc7XG5pbXBvcnQgQiBmcm9tICdibHVlYmlyZCc7XG5pbXBvcnQgeyBTRVRUSU5HU19IRUxQRVJfUEtHX0lEIH0gZnJvbSAnLi4vYW5kcm9pZC1oZWxwZXJzJztcbmltcG9ydCBtb21lbnQgZnJvbSAnbW9tZW50JztcblxuXG5jb25zdCBjb21tYW5kcyA9IHt9O1xuXG4vLyBodHRwczovL2dpdGh1Yi5jb20vYXBwaXVtL2lvLmFwcGl1bS5zZXR0aW5ncyNpbnRlcm5hbC1hdWRpby0tdmlkZW8tcmVjb3JkaW5nXG5jb25zdCBERUZBVUxUX0VYVCA9ICcubXA0JztcbmNvbnN0IFJFQ09SRElOR19TVEFSVFVQX1RJTUVPVVRfTVMgPSAzICogMTAwMDtcbmNvbnN0IFJFQ09SRElOR19TVE9QX1RJTUVPVVRfTVMgPSAzICogMTAwMDtcbmNvbnN0IE1JTl9BUElfTEVWRUwgPSAyOTtcbmNvbnN0IFJFQ09SRElOR19TRVJWSUNFX05BTUUgPSBgJHtTRVRUSU5HU19IRUxQRVJfUEtHX0lEfS8ucmVjb3JkZXIuUmVjb3JkZXJTZXJ2aWNlYDtcbmNvbnN0IFJFQ09SRElOR19BQ1RJVklUWV9OQU1FID0gYCR7U0VUVElOR1NfSEVMUEVSX1BLR19JRH0vaW8uYXBwaXVtLnNldHRpbmdzLlNldHRpbmdzYDtcbmNvbnN0IFJFQ09SRElOR19BQ1RJT05fU1RBUlQgPSBgJHtTRVRUSU5HU19IRUxQRVJfUEtHX0lEfS5yZWNvcmRpbmcuQUNUSU9OX1NUQVJUYDtcbmNvbnN0IFJFQ09SRElOR19BQ1RJT05fU1RPUCA9IGAke1NFVFRJTkdTX0hFTFBFUl9QS0dfSUR9LnJlY29yZGluZy5BQ1RJT05fU1RPUGA7XG5jb25zdCBSRUNPUkRJTkdTX1JPT1QgPSBgL3N0b3JhZ2UvZW11bGF0ZWQvMC9BbmRyb2lkL2RhdGEvJHtTRVRUSU5HU19IRUxQRVJfUEtHX0lEfS9maWxlc2A7XG5jb25zdCBERUZBVUxUX0ZJTEVOQU1FX0ZPUk1BVCA9ICdZWVlZLU1NLUREVEhILW1tLXNzJztcblxuXG5hc3luYyBmdW5jdGlvbiB1cGxvYWRSZWNvcmRlZE1lZGlhIChsb2NhbEZpbGUsIHJlbW90ZVBhdGggPSBudWxsLCB1cGxvYWRPcHRpb25zID0ge30pIHtcbiAgaWYgKF8uaXNFbXB0eShyZW1vdGVQYXRoKSkge1xuICAgIHJldHVybiAoYXdhaXQgdXRpbC50b0luTWVtb3J5QmFzZTY0KGxvY2FsRmlsZSkpLnRvU3RyaW5nKCk7XG4gIH1cblxuICBjb25zdCB7XG4gICAgdXNlcixcbiAgICBwYXNzLFxuICAgIG1ldGhvZCxcbiAgICBoZWFkZXJzLFxuICAgIGZpbGVGaWVsZE5hbWUsXG4gICAgZm9ybUZpZWxkcyxcbiAgICB1cGxvYWRUaW1lb3V0OiB0aW1lb3V0LFxuICB9ID0gdXBsb2FkT3B0aW9ucztcbiAgY29uc3Qgb3B0aW9ucyA9IHtcbiAgICBtZXRob2Q6IG1ldGhvZCB8fCAnUFVUJyxcbiAgICBoZWFkZXJzLFxuICAgIGZpbGVGaWVsZE5hbWUsXG4gICAgZm9ybUZpZWxkcyxcbiAgICB0aW1lb3V0LFxuICB9O1xuICBpZiAodXNlciAmJiBwYXNzKSB7XG4gICAgb3B0aW9ucy5hdXRoID0ge3VzZXIsIHBhc3N9O1xuICB9XG4gIGF3YWl0IG5ldC51cGxvYWRGaWxlKGxvY2FsRmlsZSwgcmVtb3RlUGF0aCwgb3B0aW9ucyk7XG4gIHJldHVybiAnJztcbn1cblxuZnVuY3Rpb24gYWRqdXN0TWVkaWFFeHRlbnNpb24gKG5hbWUpIHtcbiAgcmV0dXJuIF8udG9Mb3dlcihuYW1lKS5lbmRzV2l0aChERUZBVUxUX0VYVCkgPyBuYW1lIDogYCR7bmFtZX0ke0RFRkFVTFRfRVhUfWA7XG59XG5cbmFzeW5jIGZ1bmN0aW9uIHZlcmlmeU1lZGlhUHJvamVjdGlvblJlY29yZGluZ0lzU3VwcG9ydGVkIChhZGIpIHtcbiAgY29uc3QgYXBpTGV2ZWwgPSBhd2FpdCBhZGIuZ2V0QXBpTGV2ZWwoKTtcbiAgaWYgKGFwaUxldmVsIDwgTUlOX0FQSV9MRVZFTCkge1xuICAgIHRocm93IG5ldyBFcnJvcihgTWVkaWEgcHJvamVjdGlvbi1iYXNlZCByZWNvcmRpbmcgaXMgbm90IGF2YWlsYWJsZSBvbiBBUEkgTGV2ZWwgJHthcGlMZXZlbH0uIGAgK1xuICAgICAgYE1pbmltdW0gcmVxdWlyZWQgQVBJIExldmVsIGlzICR7TUlOX0FQSV9MRVZFTH0uYCk7XG4gIH1cbn1cblxuXG5jbGFzcyBNZWRpYVByb2plY3Rpb25SZWNvcmRlciB7XG4gIGNvbnN0cnVjdG9yIChhZGIpIHtcbiAgICB0aGlzLmFkYiA9IGFkYjtcbiAgfVxuXG4gIGFzeW5jIGlzUnVubmluZyAoKSB7XG4gICAgY29uc3Qgc3Rkb3V0ID0gYXdhaXQgdGhpcy5hZGIuc2hlbGwoW1xuICAgICAgJ2R1bXBzeXMnLCAnYWN0aXZpdHknLCAnc2VydmljZXMnLCBSRUNPUkRJTkdfU0VSVklDRV9OQU1FXG4gICAgXSk7XG4gICAgcmV0dXJuIHN0ZG91dC5pbmNsdWRlcyhSRUNPUkRJTkdfU0VSVklDRV9OQU1FKTtcbiAgfVxuXG4gIGFzeW5jIHN0YXJ0IChvcHRzID0ge30pIHtcbiAgICBpZiAoYXdhaXQgdGhpcy5pc1J1bm5pbmcoKSkge1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cblxuICAgIGF3YWl0IHRoaXMuY2xlYW51cCgpO1xuICAgIGNvbnN0IHtcbiAgICAgIGZpbGVuYW1lLFxuICAgICAgbWF4RHVyYXRpb25TZWMsXG4gICAgICBwcmlvcml0eSxcbiAgICAgIHJlc29sdXRpb24sXG4gICAgfSA9IG9wdHM7XG4gICAgY29uc3QgYXJncyA9IFtcbiAgICAgICdhbScsICdzdGFydCcsXG4gICAgICAnLW4nLCBSRUNPUkRJTkdfQUNUSVZJVFlfTkFNRSxcbiAgICAgICctYScsIFJFQ09SRElOR19BQ1RJT05fU1RBUlQsXG4gICAgXTtcbiAgICBpZiAoZmlsZW5hbWUpIHtcbiAgICAgIGFyZ3MucHVzaCgnLS1lcycsICdmaWxlbmFtZScsIGZpbGVuYW1lKTtcbiAgICB9XG4gICAgaWYgKG1heER1cmF0aW9uU2VjKSB7XG4gICAgICBhcmdzLnB1c2goJy0tZXMnLCAnbWF4X2R1cmF0aW9uX3NlYycsIGAke21heER1cmF0aW9uU2VjfWApO1xuICAgIH1cbiAgICBpZiAocHJpb3JpdHkpIHtcbiAgICAgIGFyZ3MucHVzaCgnLS1lcycsICdwcmlvcml0eScsIHByaW9yaXR5KTtcbiAgICB9XG4gICAgaWYgKHJlc29sdXRpb24pIHtcbiAgICAgIGFyZ3MucHVzaCgnLS1lcycsICdyZXNvbHV0aW9uJywgcmVzb2x1dGlvbik7XG4gICAgfVxuICAgIGF3YWl0IHRoaXMuYWRiLnNoZWxsKGFyZ3MpO1xuICAgIGF3YWl0IG5ldyBCKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgIHNldFRpbWVvdXQoYXN5bmMgKCkgPT4ge1xuICAgICAgICBpZiAoIWF3YWl0IHRoaXMuaXNSdW5uaW5nKCkpIHtcbiAgICAgICAgICByZXR1cm4gcmVqZWN0KG5ldyBFcnJvcihcbiAgICAgICAgICAgIGBUaGUgbWVkaWEgcHJvamVjdGlvbiByZWNvcmRpbmcgaXMgbm90IHJ1bm5pbmcgYWZ0ZXIgJHtSRUNPUkRJTkdfU1RBUlRVUF9USU1FT1VUX01TfW1zLiBgICtcbiAgICAgICAgICAgIGBQbGVhc2UgY2hlY2sgdGhlIGxvZ2NhdCBvdXRwdXQgZm9yIG1vcmUgZGV0YWlscy5gXG4gICAgICAgICAgKSk7XG4gICAgICAgIH1cbiAgICAgICAgcmVzb2x2ZSgpO1xuICAgICAgfSwgUkVDT1JESU5HX1NUQVJUVVBfVElNRU9VVF9NUyk7XG4gICAgfSk7XG4gICAgcmV0dXJuIHRydWU7XG4gIH1cblxuICBhc3luYyBjbGVhbnVwICgpIHtcbiAgICBhd2FpdCB0aGlzLmFkYi5zaGVsbChbYHJtIC1mICR7UkVDT1JESU5HU19ST09UfS8qYF0pO1xuICB9XG5cbiAgYXN5bmMgcHVsbFJlY2VudCAoKSB7XG4gICAgY29uc3QgcmVjb3JkaW5ncyA9IGF3YWl0IHRoaXMuYWRiLmxzKFJFQ09SRElOR1NfUk9PVCwgWyctdHInXSk7XG4gICAgaWYgKF8uaXNFbXB0eShyZWNvcmRpbmdzKSkge1xuICAgICAgcmV0dXJuIG51bGw7XG4gICAgfVxuXG4gICAgY29uc3QgZHN0UGF0aCA9IHBhdGguam9pbihhd2FpdCB0ZW1wRGlyLm9wZW5EaXIoKSwgcmVjb3JkaW5nc1swXSk7XG4gICAgLy8gaW5jcmVhc2UgdGltZW91dCB0byA1IG1pbnV0ZXMgYmVjYXVzZSBpdCBtaWdodCB0YWtlIGEgd2hpbGUgdG8gcHVsbCBhIGxhcmdlIHZpZGVvIGZpbGVcbiAgICBhd2FpdCB0aGlzLmFkYi5wdWxsKGAke1JFQ09SRElOR1NfUk9PVH0vJHtyZWNvcmRpbmdzWzBdfWAsIGRzdFBhdGgsIHt0aW1lb3V0OiAzMDAwMDB9KTtcbiAgICByZXR1cm4gZHN0UGF0aDtcbiAgfVxuXG4gIGFzeW5jIHN0b3AgKCkge1xuICAgIGlmICghYXdhaXQgdGhpcy5pc1J1bm5pbmcoKSkge1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cblxuICAgIGF3YWl0IHRoaXMuYWRiLnNoZWxsKFtcbiAgICAgICdhbScsICdzdGFydCcsXG4gICAgICAnLW4nLCBSRUNPUkRJTkdfQUNUSVZJVFlfTkFNRSxcbiAgICAgICctYScsIFJFQ09SRElOR19BQ1RJT05fU1RPUCxcbiAgICBdKTtcbiAgICB0cnkge1xuICAgICAgYXdhaXQgd2FpdEZvckNvbmRpdGlvbihhc3luYyAoKSA9PiAhKGF3YWl0IHRoaXMuaXNSdW5uaW5nKCkpLCB7XG4gICAgICAgIHdhaXRNczogUkVDT1JESU5HX1NUT1BfVElNRU9VVF9NUyxcbiAgICAgICAgaW50ZXJ2YWxNczogNTAwLFxuICAgICAgfSk7XG4gICAgfSBjYXRjaCAoZSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFxuICAgICAgICBgVGhlIGF0dGVtcHQgdG8gc3RvcCB0aGUgY3VycmVudCBtZWRpYSBwcm9qZWN0aW9uIHJlY29yZGluZyB0aW1lZCBvdXQgYWZ0ZXIgYCArXG4gICAgICAgIGAke1JFQ09SRElOR19TVE9QX1RJTUVPVVRfTVN9bXNgXG4gICAgICApO1xuICAgIH1cbiAgICByZXR1cm4gdHJ1ZTtcbiAgfVxufVxuXG5cbi8qKlxuICogQHR5cGVkZWYge09iamVjdH0gU3RhcnRSZWNvcmRpbmdPcHRpb25zXG4gKlxuICogQHByb3BlcnR5IHtzdHJpbmc/fSByZXNvbHV0aW9uIE1heGltdW0gc3VwcG9ydGVkIHJlc29sdXRpb24gb24tZGV2aWNlIChEZXRlY3RlZFxuICogYXV0b21hdGljYWxseSBieSB0aGUgYXBwIGl0c2VsZiksIHdoaWNoIHVzdWFsbHkgZXF1YWxzIHRvIEZ1bGwgSEQgMTkyMHgxMDgwIG9uIG1vc3RcbiAqIHBob25lcyBob3dldmVyIHlvdSBjYW4gY2hhbmdlIGl0IHRvIGZvbGxvd2luZyBzdXBwb3J0ZWQgcmVzb2x1dGlvbnNcbiAqIGFzIHdlbGw6IFwiMTkyMHgxMDgwXCIsIFwiMTI4MHg3MjBcIiwgXCI3MjB4NDgwXCIsIFwiMzIweDI0MFwiLCBcIjE3NngxNDRcIi5cbiAqIEBwcm9wZXJ0eSB7bnVtYmVyP30gbWF4RHVyYXRpb25TZWMgWzkwMF0gRGVmYXVsdCB2YWx1ZTogOTAwIHNlY29uZHMgd2hpY2ggbWVhbnNcbiAqIG1heGltdW0gYWxsb3dlZCBkdXJhdGlvbiBpcyAxNSBtaW51dGUsIHlvdSBjYW4gaW5jcmVhc2UgaXQgaWYgeW91ciB0ZXN0IHRha2VzXG4gKiBsb25nZXIgdGhhbiB0aGF0LlxuICogQHByb3BlcnR5IHtzdHJpbmc/fSBwcmlvcml0eSBbaGlnaF0gTWVhbnMgcmVjb3JkaW5nIHRocmVhZCBwcmlvcml0eSBpcyBtYXhpbXVtXG4gKiBob3dldmVyIGlmIHlvdSBmYWNlIHBlcmZvcm1hbmNlIGRyb3BzIGR1cmluZyB0ZXN0aW5nIHdpdGggcmVjb3JkaW5nIGVuYWJsZWQsIHlvdVxuICogY2FuIHJlZHVjZSByZWNvcmRpbmcgcHJpb3JpdHkgdG8gXCJub3JtYWxcIiBvciBcImxvd1wiLlxuICogQHByb3BlcnR5IHtzdHJpbmc/fSBmaWxlbmFtZSBZb3UgY2FuIHR5cGUgcmVjb3JkaW5nIHZpZGVvIGZpbGUgbmFtZSBhcyB5b3Ugd2FudCxcbiAqIGJ1dCByZWNvcmRpbmcgY3VycmVudGx5IHN1cHBvcnRzIG9ubHkgXCJtcDRcIiBmb3JtYXQgc28geW91ciBmaWxlbmFtZSBtdXN0IGVuZCB3aXRoIFwiLm1wNFwiLlxuICogQW4gaW52YWxpZCBmaWxlIG5hbWUgd2lsbCBmYWlsIHRvIHN0YXJ0IHRoZSByZWNvcmRpbmcuXG4gKiBJZiBub3QgcHJvdmlkZWQgdGhlbiB0aGUgY3VycmVudCB0aW1lc3RhbXAgd2lsbCBiZSB1c2VkIGFzIGZpbGUgbmFtZS5cbiAqL1xuXG4vKipcbiAqIFJlY29yZCB0aGUgZGlzcGxheSBvZiBhIHJlYWwgZGV2aWNlcyBydW5uaW5nIEFuZHJvaWQgMTAgKEFQSSBsZXZlbCAyOSkgYW5kIGhpZ2hlci5cbiAqIFRoZSBzY3JlZW4gYWN0aXZpdHkgaXMgcmVjb3JkZWQgdG8gYSBNUEVHLTQgZmlsZS4gQXVkaW8gaXMgYWxzbyByZWNvcmRlZCBieSBkZWZhdWx0XG4gKiAob25seSBmb3IgYXBwcyB0aGF0IGFsbG93IGl0IGluIHRoZWlyIG1hbmlmZXN0cykuXG4gKiBJZiBhbm90aGVyIHJlY29yZGluZyBoYXMgYmVlbiBhbHJlYWR5IHN0YXJ0ZWQgdGhlbiB0aGUgY29tbWFuZCB3aWxsIGV4aXQgc2lsZW50bHkuXG4gKiBUaGUgcHJldmlvdXNseSByZWNvcmRlZCB2aWRlbyBmaWxlIGlzIGRlbGV0ZWQgd2hlbiBhIG5ldyByZWNvcmRpbmcgc2Vzc2lvbiBpcyBzdGFydGVkLlxuICogUmVjb3JkaW5nIGNvbnRpbnVlcyBpdCBpcyBzdG9wcGVkIGV4cGxpY2l0bHkgb3IgdW50aWwgdGhlIHRpbWVvdXQgaGFwcGVucy5cbiAqXG4gKiBAcGFyYW0gez9TdGFydFJlY29yZGluZ09wdGlvbnN9IG9wdGlvbnMgQXZhaWxhYmxlIG9wdGlvbnMuXG4gKiBAcmV0dXJucyB7Ym9vbGVhbn0gVHJ1ZSBpZiBhIG5ldyByZWNvcmRpbmcgaGFzIHN1Y2Nlc3NmdWxseSBzdGFydGVkLlxuICogQHRocm93cyB7RXJyb3J9IElmIHJlY29yZGluZyBoYXMgZmFpbGVkIHRvIHN0YXJ0IG9yIGlzIG5vdCBzdXBwb3J0ZWQgb24gdGhlIGRldmljZSB1bmRlciB0ZXN0LlxuICovXG5jb21tYW5kcy5tb2JpbGVTdGFydE1lZGlhUHJvamVjdGlvblJlY29yZGluZyA9IGFzeW5jIGZ1bmN0aW9uIG1vYmlsZVN0YXJ0TWVkaWFQcm9qZWN0aW9uUmVjb3JkaW5nIChvcHRpb25zID0ge30pIHtcbiAgYXdhaXQgdmVyaWZ5TWVkaWFQcm9qZWN0aW9uUmVjb3JkaW5nSXNTdXBwb3J0ZWQodGhpcy5hZGIpO1xuXG4gIGNvbnN0IHtyZXNvbHV0aW9uLCBwcmlvcml0eSwgbWF4RHVyYXRpb25TZWMsIGZpbGVuYW1lfSA9IG9wdGlvbnM7XG4gIGNvbnN0IHJlY29yZGVyID0gbmV3IE1lZGlhUHJvamVjdGlvblJlY29yZGVyKHRoaXMuYWRiKTtcbiAgY29uc3QgZm5hbWUgPSBhZGp1c3RNZWRpYUV4dGVuc2lvbihmaWxlbmFtZSB8fCBtb21lbnQoKS5mb3JtYXQoREVGQVVMVF9GSUxFTkFNRV9GT1JNQVQpKTtcbiAgY29uc3QgZGlkU3RhcnQgPSBhd2FpdCByZWNvcmRlci5zdGFydCh7XG4gICAgcmVzb2x1dGlvbixcbiAgICBwcmlvcml0eSxcbiAgICBtYXhEdXJhdGlvblNlYyxcbiAgICBmaWxlbmFtZTogZm5hbWUsXG4gIH0pO1xuICBpZiAoZGlkU3RhcnQpIHtcbiAgICB0aGlzLmxvZy5pbmZvKGBBIG5ldyBtZWRpYSBwcm9qZWN0aW9uIHJlY29yZGluZyAnJHtmbmFtZX0nIGhhcyBiZWVuIHN1Y2Nlc3NmdWxseSBzdGFydGVkYCk7XG4gIH0gZWxzZSB7XG4gICAgdGhpcy5sb2cuaW5mbygnQW5vdGhlciBtZWRpYSBwcm9qZWN0aW9uIHJlY29yZGluZyBpcyBhbHJlYWR5IGluIHByb2dyZXNzLiBUaGVyZSBpcyBub3RoaW5nIHRvIHN0YXJ0Jyk7XG4gIH1cbiAgcmV0dXJuIGRpZFN0YXJ0O1xufTtcblxuLyoqXG4gKiBDaGVja3MgaWYgYSBtZWRpYSBwcm9qZWN0aW9uLWJhc2VkIHJlY29yZGluZyBpcyBjdXJyZW50bHkgcnVubmluZy5cbiAqXG4gKiBAcmV0dXJucyB7Ym9vbGVhbn0gVHJ1ZSBpZiBhIHJlY29yZGluZyBpcyBpbiBwcm9ncmVzcy5cbiAqIEB0aHJvd3Mge0Vycm9yfSBJZiBhIHJlY29yZGluZyBpcyBub3Qgc3VwcG9ydGVkIG9uIHRoZSBkZXZpY2UgdW5kZXIgdGVzdC5cbiAqL1xuY29tbWFuZHMubW9iaWxlSXNNZWRpYVByb2plY3Rpb25SZWNvcmRpbmdSdW5uaW5nID0gYXN5bmMgZnVuY3Rpb24gbW9iaWxlSXNNZWRpYVByb2plY3Rpb25SZWNvcmRpbmdSdW5uaW5nICgpIHtcbiAgYXdhaXQgdmVyaWZ5TWVkaWFQcm9qZWN0aW9uUmVjb3JkaW5nSXNTdXBwb3J0ZWQodGhpcy5hZGIpO1xuXG4gIGNvbnN0IHJlY29yZGVyID0gbmV3IE1lZGlhUHJvamVjdGlvblJlY29yZGVyKHRoaXMuYWRiKTtcbiAgcmV0dXJuIGF3YWl0IHJlY29yZGVyLmlzUnVubmluZygpO1xufTtcblxuLyoqXG4gKiBAdHlwZWRlZiB7T2JqZWN0fSBTdG9wUmVjb3JkaW5nT3B0aW9uc1xuICpcbiAqIEBwcm9wZXJ0eSB7c3RyaW5nP30gcmVtb3RlUGF0aCBUaGUgcGF0aCB0byB0aGUgcmVtb3RlIGxvY2F0aW9uLCB3aGVyZSB0aGUgcmVzdWx0aW5nIHZpZGVvIHNob3VsZCBiZSB1cGxvYWRlZC5cbiAqIFRoZSBmb2xsb3dpbmcgcHJvdG9jb2xzIGFyZSBzdXBwb3J0ZWQ6IGh0dHAvaHR0cHMsIGZ0cC5cbiAqIE51bGwgb3IgZW1wdHkgc3RyaW5nIHZhbHVlICh0aGUgZGVmYXVsdCBzZXR0aW5nKSBtZWFucyB0aGUgY29udGVudCBvZiByZXN1bHRpbmdcbiAqIGZpbGUgc2hvdWxkIGJlIGVuY29kZWQgYXMgQmFzZTY0IGFuZCBwYXNzZWQgYXMgdGhlIGVuZHBvb250IHJlc3BvbnNlIHZhbHVlLlxuICogQW4gZXhjZXB0aW9uIHdpbGwgYmUgdGhyb3duIGlmIHRoZSBnZW5lcmF0ZWQgbWVkaWEgZmlsZSBpcyB0b28gYmlnIHRvXG4gKiBmaXQgaW50byB0aGUgYXZhaWxhYmxlIHByb2Nlc3MgbWVtb3J5LlxuICogQHByb3BlcnR5IHtzdHJpbmc/fSB1c2VyIFRoZSBuYW1lIG9mIHRoZSB1c2VyIGZvciB0aGUgcmVtb3RlIGF1dGhlbnRpY2F0aW9uLlxuICogQHByb3BlcnR5IHtzdHJpbmc/fSBwYXNzIFRoZSBwYXNzd29yZCBmb3IgdGhlIHJlbW90ZSBhdXRoZW50aWNhdGlvbi5cbiAqIEBwcm9wZXJ0eSB7c3RyaW5nP30gbWV0aG9kIFRoZSBodHRwIG11bHRpcGFydCB1cGxvYWQgbWV0aG9kIG5hbWUuIFRoZSAnUFVUJyBvbmUgaXMgdXNlZCBieSBkZWZhdWx0LlxuICogQHByb3BlcnR5IHtPYmplY3Q/fSBoZWFkZXJzIEFkZGl0aW9uYWwgaGVhZGVycyBtYXBwaW5nIGZvciBtdWx0aXBhcnQgaHR0cChzKSB1cGxvYWRzXG4gKiBAcHJvcGVydHkge3N0cmluZz99IGZpbGVGaWVsZE5hbWUgW2ZpbGVdIFRoZSBuYW1lIG9mIHRoZSBmb3JtIGZpZWxkLCB3aGVyZSB0aGUgZmlsZSBjb250ZW50IEJMT0Igc2hvdWxkIGJlIHN0b3JlZCBmb3JcbiAqIGh0dHAocykgdXBsb2Fkc1xuICogQHByb3BlcnR5IHtPYmplY3R8QXJyYXk8UGFpcj4/fSBmb3JtRmllbGRzIEFkZGl0aW9uYWwgZm9ybSBmaWVsZHMgZm9yIG11bHRpcGFydCBodHRwKHMpIHVwbG9hZHNcbiAqIEBwcm9wZXJ0eSB7bnVtYmVyP30gdXBsb2FkVGltZW91dCAtIFRoZSBhY3R1YWwgbWVkaWEgdXBsb2FkIHJlcXVlc3QgdGltZW91dCBpbiBtaWxsaXNlY29uZHM7XG4gKiBkZWZhdWx0cyB0byBAYXBwaXVtL3N1cHBvcnQgbmV0IERFRkFVTFRfVElNRU9VVF9NU1xuICovXG5cbi8qKlxuICogU3RvcCBhIG1lZGlhIHByb2plY3Rpb24tYmFzZWQgcmVjb3JkaW5nLlxuICogSWYgbm8gcmVjb3JkaW5nIGhhcyBiZWVuIHN0YXJ0ZWQgYmVmb3JlIHRoZW4gYW4gZXJyb3IgaXMgdGhyb3duLlxuICogSWYgdGhlIHJlY29yZGluZyBoYXMgYmVlbiBhbHJlYWR5IGZpbmlzaGVkIGJlZm9yZSB0aGlzIEFQSSBoYXMgYmVlbiBjYWxsZWRcbiAqIHRoZW4gdGhlIG1vc3QgcmVjZW50IHJlY29yZGVkIGZpbGUgaXMgcmV0dXJuZWQuXG4gKlxuICogQHBhcmFtIHs/U3RvcFJlY29yZGluZ09wdGlvbnN9IG9wdGlvbnMgQXZhaWxhYmxlIG9wdGlvbnMuXG4gKiBAcmV0dXJucyB7c3RyaW5nfSBCYXNlNjQtZW5jb2RlZCBjb250ZW50IG9mIHRoZSByZWNvcmRlZCBtZWRpYSBmaWxlIGlmICdyZW1vdGVQYXRoJ1xuICogcGFyYW1ldGVyIGlzIGZhbHN5IG9yIGFuIGVtcHR5IHN0cmluZy5cbiAqIEB0aHJvd3Mge0Vycm9yfSBJZiB0aGVyZSB3YXMgYW4gZXJyb3Igd2hpbGUgc3RvcHBpbmcgYSByZWNvcmRpbmcsXG4gKiBmZXRjaGluZyB0aGUgY29udGVudCBvZiB0aGUgcmVtb3RlIG1lZGlhIGZpbGUsXG4gKiBvciBpZiBhIHJlY29yZGluZyBpcyBub3Qgc3VwcG9ydGVkIG9uIHRoZSBkZXZpY2UgdW5kZXIgdGVzdC5cbiAqL1xuY29tbWFuZHMubW9iaWxlU3RvcE1lZGlhUHJvamVjdGlvblJlY29yZGluZyA9IGFzeW5jIGZ1bmN0aW9uIG1vYmlsZVN0b3BNZWRpYVByb2plY3Rpb25SZWNvcmRpbmcgKG9wdGlvbnMgPSB7fSkge1xuICBhd2FpdCB2ZXJpZnlNZWRpYVByb2plY3Rpb25SZWNvcmRpbmdJc1N1cHBvcnRlZCh0aGlzLmFkYik7XG5cbiAgY29uc3QgcmVjb3JkZXIgPSBuZXcgTWVkaWFQcm9qZWN0aW9uUmVjb3JkZXIodGhpcy5hZGIpO1xuICBpZiAoYXdhaXQgcmVjb3JkZXIuc3RvcCgpKSB7XG4gICAgdGhpcy5sb2cuaW5mbygnU3VjY2Vzc2Z1bGx5IHN0b3BwZWQgYSBtZWRpYSBwcm9qZWN0aW9uIHJlY29yZGluZy4gUHVsbGluZyB0aGUgcmVjb3JkZWQgbWVkaWEnKTtcbiAgfSBlbHNlIHtcbiAgICB0aGlzLmxvZy5pbmZvKCdNZWRpYSBwcm9qZWN0aW9uIHJlY29yZGluZyBpcyBub3QgcnVubmluZy4gVGhlcmUgaXMgbm90aGluZyB0byBzdG9wJyk7XG4gIH1cbiAgY29uc3QgcmVjZW50UmVjb3JkaW5nUGF0aCA9IGF3YWl0IHJlY29yZGVyLnB1bGxSZWNlbnQoKTtcbiAgaWYgKCFyZWNlbnRSZWNvcmRpbmdQYXRoKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKGBObyByZWNlbnQgbWVkaWEgcHJvamVjdGlvbiByZWNvcmRpbmcgaGF2ZSBiZWVuIGZvdW5kLiBEaWQgeW91IHN0YXJ0IGFueT9gKTtcbiAgfVxuXG4gIGNvbnN0IHtyZW1vdGVQYXRofSA9IG9wdGlvbnM7XG4gIGlmIChfLmlzRW1wdHkocmVtb3RlUGF0aCkpIHtcbiAgICBjb25zdCB7c2l6ZX0gPSBhd2FpdCBmcy5zdGF0KHJlY2VudFJlY29yZGluZ1BhdGgpO1xuICAgIHRoaXMubG9nLmRlYnVnKGBUaGUgc2l6ZSBvZiB0aGUgcmVzdWx0aW5nIG1lZGlhIHByb2plY3Rpb24gcmVjb3JkaW5nIGlzICR7dXRpbC50b1JlYWRhYmxlU2l6ZVN0cmluZyhzaXplKX1gKTtcbiAgfVxuICB0cnkge1xuICAgIHJldHVybiBhd2FpdCB1cGxvYWRSZWNvcmRlZE1lZGlhKHJlY2VudFJlY29yZGluZ1BhdGgsIHJlbW90ZVBhdGgsIG9wdGlvbnMpO1xuICB9IGZpbmFsbHkge1xuICAgIGF3YWl0IGZzLnJpbXJhZihwYXRoLmRpcm5hbWUocmVjZW50UmVjb3JkaW5nUGF0aCkpO1xuICB9XG59O1xuXG5cbmV4cG9ydCB7IGNvbW1hbmRzIH07XG5leHBvcnQgZGVmYXVsdCBjb21tYW5kcztcbiJdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7QUFBQSxJQUFBQSxPQUFBLEdBQUFDLHNCQUFBLENBQUFDLE9BQUE7QUFDQSxJQUFBQyxTQUFBLEdBQUFELE9BQUE7QUFDQSxJQUFBRSxRQUFBLEdBQUFGLE9BQUE7QUFDQSxJQUFBRyxLQUFBLEdBQUFKLHNCQUFBLENBQUFDLE9BQUE7QUFDQSxJQUFBSSxTQUFBLEdBQUFMLHNCQUFBLENBQUFDLE9BQUE7QUFDQSxJQUFBSyxlQUFBLEdBQUFMLE9BQUE7QUFDQSxJQUFBTSxPQUFBLEdBQUFQLHNCQUFBLENBQUFDLE9BQUE7QUFHQSxNQUFNTyxRQUFRLEdBQUcsQ0FBQyxDQUFDO0FBQUNDLE9BQUEsQ0FBQUQsUUFBQSxHQUFBQSxRQUFBO0FBR3BCLE1BQU1FLFdBQVcsR0FBRyxNQUFNO0FBQzFCLE1BQU1DLDRCQUE0QixHQUFHLENBQUMsR0FBRyxJQUFJO0FBQzdDLE1BQU1DLHlCQUF5QixHQUFHLENBQUMsR0FBRyxJQUFJO0FBQzFDLE1BQU1DLGFBQWEsR0FBRyxFQUFFO0FBQ3hCLE1BQU1DLHNCQUFzQixHQUFJLEdBQUVDLHNDQUF1Qiw0QkFBMkI7QUFDcEYsTUFBTUMsdUJBQXVCLEdBQUksR0FBRUQsc0NBQXVCLDhCQUE2QjtBQUN2RixNQUFNRSxzQkFBc0IsR0FBSSxHQUFFRixzQ0FBdUIseUJBQXdCO0FBQ2pGLE1BQU1HLHFCQUFxQixHQUFJLEdBQUVILHNDQUF1Qix3QkFBdUI7QUFDL0UsTUFBTUksZUFBZSxHQUFJLG9DQUFtQ0osc0NBQXVCLFFBQU87QUFDMUYsTUFBTUssdUJBQXVCLEdBQUcscUJBQXFCO0FBR3JELGVBQWVDLG1CQUFtQkEsQ0FBRUMsU0FBUyxFQUFFQyxVQUFVLEdBQUcsSUFBSSxFQUFFQyxhQUFhLEdBQUcsQ0FBQyxDQUFDLEVBQUU7RUFDcEYsSUFBSUMsZUFBQyxDQUFDQyxPQUFPLENBQUNILFVBQVUsQ0FBQyxFQUFFO0lBQ3pCLE9BQU8sQ0FBQyxNQUFNSSxhQUFJLENBQUNDLGdCQUFnQixDQUFDTixTQUFTLENBQUMsRUFBRU8sUUFBUSxDQUFDLENBQUM7RUFDNUQ7RUFFQSxNQUFNO0lBQ0pDLElBQUk7SUFDSkMsSUFBSTtJQUNKQyxNQUFNO0lBQ05DLE9BQU87SUFDUEMsYUFBYTtJQUNiQyxVQUFVO0lBQ1ZDLGFBQWEsRUFBRUM7RUFDakIsQ0FBQyxHQUFHYixhQUFhO0VBQ2pCLE1BQU1jLE9BQU8sR0FBRztJQUNkTixNQUFNLEVBQUVBLE1BQU0sSUFBSSxLQUFLO0lBQ3ZCQyxPQUFPO0lBQ1BDLGFBQWE7SUFDYkMsVUFBVTtJQUNWRTtFQUNGLENBQUM7RUFDRCxJQUFJUCxJQUFJLElBQUlDLElBQUksRUFBRTtJQUNoQk8sT0FBTyxDQUFDQyxJQUFJLEdBQUc7TUFBQ1QsSUFBSTtNQUFFQztJQUFJLENBQUM7RUFDN0I7RUFDQSxNQUFNUyxZQUFHLENBQUNDLFVBQVUsQ0FBQ25CLFNBQVMsRUFBRUMsVUFBVSxFQUFFZSxPQUFPLENBQUM7RUFDcEQsT0FBTyxFQUFFO0FBQ1g7QUFFQSxTQUFTSSxvQkFBb0JBLENBQUVDLElBQUksRUFBRTtFQUNuQyxPQUFPbEIsZUFBQyxDQUFDbUIsT0FBTyxDQUFDRCxJQUFJLENBQUMsQ0FBQ0UsUUFBUSxDQUFDbkMsV0FBVyxDQUFDLEdBQUdpQyxJQUFJLEdBQUksR0FBRUEsSUFBSyxHQUFFakMsV0FBWSxFQUFDO0FBQy9FO0FBRUEsZUFBZW9DLHlDQUF5Q0EsQ0FBRUMsR0FBRyxFQUFFO0VBQzdELE1BQU1DLFFBQVEsR0FBRyxNQUFNRCxHQUFHLENBQUNFLFdBQVcsQ0FBQyxDQUFDO0VBQ3hDLElBQUlELFFBQVEsR0FBR25DLGFBQWEsRUFBRTtJQUM1QixNQUFNLElBQUlxQyxLQUFLLENBQUUsa0VBQWlFRixRQUFTLElBQUcsR0FDM0YsaUNBQWdDbkMsYUFBYyxHQUFFLENBQUM7RUFDdEQ7QUFDRjtBQUdBLE1BQU1zQyx1QkFBdUIsQ0FBQztFQUM1QkMsV0FBV0EsQ0FBRUwsR0FBRyxFQUFFO0lBQ2hCLElBQUksQ0FBQ0EsR0FBRyxHQUFHQSxHQUFHO0VBQ2hCO0VBRUEsTUFBTU0sU0FBU0EsQ0FBQSxFQUFJO0lBQ2pCLE1BQU1DLE1BQU0sR0FBRyxNQUFNLElBQUksQ0FBQ1AsR0FBRyxDQUFDUSxLQUFLLENBQUMsQ0FDbEMsU0FBUyxFQUFFLFVBQVUsRUFBRSxVQUFVLEVBQUV6QyxzQkFBc0IsQ0FDMUQsQ0FBQztJQUNGLE9BQU93QyxNQUFNLENBQUNFLFFBQVEsQ0FBQzFDLHNCQUFzQixDQUFDO0VBQ2hEO0VBRUEsTUFBTTJDLEtBQUtBLENBQUVDLElBQUksR0FBRyxDQUFDLENBQUMsRUFBRTtJQUN0QixJQUFJLE1BQU0sSUFBSSxDQUFDTCxTQUFTLENBQUMsQ0FBQyxFQUFFO01BQzFCLE9BQU8sS0FBSztJQUNkO0lBRUEsTUFBTSxJQUFJLENBQUNNLE9BQU8sQ0FBQyxDQUFDO0lBQ3BCLE1BQU07TUFDSkMsUUFBUTtNQUNSQyxjQUFjO01BQ2RDLFFBQVE7TUFDUkM7SUFDRixDQUFDLEdBQUdMLElBQUk7SUFDUixNQUFNTSxJQUFJLEdBQUcsQ0FDWCxJQUFJLEVBQUUsT0FBTyxFQUNiLElBQUksRUFBRWhELHVCQUF1QixFQUM3QixJQUFJLEVBQUVDLHNCQUFzQixDQUM3QjtJQUNELElBQUkyQyxRQUFRLEVBQUU7TUFDWkksSUFBSSxDQUFDQyxJQUFJLENBQUMsTUFBTSxFQUFFLFVBQVUsRUFBRUwsUUFBUSxDQUFDO0lBQ3pDO0lBQ0EsSUFBSUMsY0FBYyxFQUFFO01BQ2xCRyxJQUFJLENBQUNDLElBQUksQ0FBQyxNQUFNLEVBQUUsa0JBQWtCLEVBQUcsR0FBRUosY0FBZSxFQUFDLENBQUM7SUFDNUQ7SUFDQSxJQUFJQyxRQUFRLEVBQUU7TUFDWkUsSUFBSSxDQUFDQyxJQUFJLENBQUMsTUFBTSxFQUFFLFVBQVUsRUFBRUgsUUFBUSxDQUFDO0lBQ3pDO0lBQ0EsSUFBSUMsVUFBVSxFQUFFO01BQ2RDLElBQUksQ0FBQ0MsSUFBSSxDQUFDLE1BQU0sRUFBRSxZQUFZLEVBQUVGLFVBQVUsQ0FBQztJQUM3QztJQUNBLE1BQU0sSUFBSSxDQUFDaEIsR0FBRyxDQUFDUSxLQUFLLENBQUNTLElBQUksQ0FBQztJQUMxQixNQUFNLElBQUlFLGlCQUFDLENBQUMsQ0FBQ0MsT0FBTyxFQUFFQyxNQUFNLEtBQUs7TUFDL0JDLFVBQVUsQ0FBQyxZQUFZO1FBQ3JCLElBQUksRUFBQyxNQUFNLElBQUksQ0FBQ2hCLFNBQVMsQ0FBQyxDQUFDLEdBQUU7VUFDM0IsT0FBT2UsTUFBTSxDQUFDLElBQUlsQixLQUFLLENBQ3BCLHVEQUFzRHZDLDRCQUE2QixNQUFLLEdBQ3hGLGtEQUNILENBQUMsQ0FBQztRQUNKO1FBQ0F3RCxPQUFPLENBQUMsQ0FBQztNQUNYLENBQUMsRUFBRXhELDRCQUE0QixDQUFDO0lBQ2xDLENBQUMsQ0FBQztJQUNGLE9BQU8sSUFBSTtFQUNiO0VBRUEsTUFBTWdELE9BQU9BLENBQUEsRUFBSTtJQUNmLE1BQU0sSUFBSSxDQUFDWixHQUFHLENBQUNRLEtBQUssQ0FBQyxDQUFFLFNBQVFwQyxlQUFnQixJQUFHLENBQUMsQ0FBQztFQUN0RDtFQUVBLE1BQU1tRCxVQUFVQSxDQUFBLEVBQUk7SUFDbEIsTUFBTUMsVUFBVSxHQUFHLE1BQU0sSUFBSSxDQUFDeEIsR0FBRyxDQUFDeUIsRUFBRSxDQUFDckQsZUFBZSxFQUFFLENBQUMsS0FBSyxDQUFDLENBQUM7SUFDOUQsSUFBSU0sZUFBQyxDQUFDQyxPQUFPLENBQUM2QyxVQUFVLENBQUMsRUFBRTtNQUN6QixPQUFPLElBQUk7SUFDYjtJQUVBLE1BQU1FLE9BQU8sR0FBR0MsYUFBSSxDQUFDQyxJQUFJLENBQUMsTUFBTUMsZ0JBQU8sQ0FBQ0MsT0FBTyxDQUFDLENBQUMsRUFBRU4sVUFBVSxDQUFDLENBQUMsQ0FBQyxDQUFDO0lBRWpFLE1BQU0sSUFBSSxDQUFDeEIsR0FBRyxDQUFDK0IsSUFBSSxDQUFFLEdBQUUzRCxlQUFnQixJQUFHb0QsVUFBVSxDQUFDLENBQUMsQ0FBRSxFQUFDLEVBQUVFLE9BQU8sRUFBRTtNQUFDcEMsT0FBTyxFQUFFO0lBQU0sQ0FBQyxDQUFDO0lBQ3RGLE9BQU9vQyxPQUFPO0VBQ2hCO0VBRUEsTUFBTU0sSUFBSUEsQ0FBQSxFQUFJO0lBQ1osSUFBSSxFQUFDLE1BQU0sSUFBSSxDQUFDMUIsU0FBUyxDQUFDLENBQUMsR0FBRTtNQUMzQixPQUFPLEtBQUs7SUFDZDtJQUVBLE1BQU0sSUFBSSxDQUFDTixHQUFHLENBQUNRLEtBQUssQ0FBQyxDQUNuQixJQUFJLEVBQUUsT0FBTyxFQUNiLElBQUksRUFBRXZDLHVCQUF1QixFQUM3QixJQUFJLEVBQUVFLHFCQUFxQixDQUM1QixDQUFDO0lBQ0YsSUFBSTtNQUNGLE1BQU0sSUFBQThELDBCQUFnQixFQUFDLFlBQVksRUFBRSxNQUFNLElBQUksQ0FBQzNCLFNBQVMsQ0FBQyxDQUFDLENBQUMsRUFBRTtRQUM1RDRCLE1BQU0sRUFBRXJFLHlCQUF5QjtRQUNqQ3NFLFVBQVUsRUFBRTtNQUNkLENBQUMsQ0FBQztJQUNKLENBQUMsQ0FBQyxPQUFPQyxDQUFDLEVBQUU7TUFDVixNQUFNLElBQUlqQyxLQUFLLENBQ1osNkVBQTRFLEdBQzVFLEdBQUV0Qyx5QkFBMEIsSUFDL0IsQ0FBQztJQUNIO0lBQ0EsT0FBTyxJQUFJO0VBQ2I7QUFDRjtBQWtDQUosUUFBUSxDQUFDNEUsbUNBQW1DLEdBQUcsZUFBZUEsbUNBQW1DQSxDQUFFOUMsT0FBTyxHQUFHLENBQUMsQ0FBQyxFQUFFO0VBQy9HLE1BQU1RLHlDQUF5QyxDQUFDLElBQUksQ0FBQ0MsR0FBRyxDQUFDO0VBRXpELE1BQU07SUFBQ2dCLFVBQVU7SUFBRUQsUUFBUTtJQUFFRCxjQUFjO0lBQUVEO0VBQVEsQ0FBQyxHQUFHdEIsT0FBTztFQUNoRSxNQUFNK0MsUUFBUSxHQUFHLElBQUlsQyx1QkFBdUIsQ0FBQyxJQUFJLENBQUNKLEdBQUcsQ0FBQztFQUN0RCxNQUFNdUMsS0FBSyxHQUFHNUMsb0JBQW9CLENBQUNrQixRQUFRLElBQUksSUFBQTJCLGVBQU0sRUFBQyxDQUFDLENBQUNDLE1BQU0sQ0FBQ3BFLHVCQUF1QixDQUFDLENBQUM7RUFDeEYsTUFBTXFFLFFBQVEsR0FBRyxNQUFNSixRQUFRLENBQUM1QixLQUFLLENBQUM7SUFDcENNLFVBQVU7SUFDVkQsUUFBUTtJQUNSRCxjQUFjO0lBQ2RELFFBQVEsRUFBRTBCO0VBQ1osQ0FBQyxDQUFDO0VBQ0YsSUFBSUcsUUFBUSxFQUFFO0lBQ1osSUFBSSxDQUFDQyxHQUFHLENBQUNDLElBQUksQ0FBRSxxQ0FBb0NMLEtBQU0saUNBQWdDLENBQUM7RUFDNUYsQ0FBQyxNQUFNO0lBQ0wsSUFBSSxDQUFDSSxHQUFHLENBQUNDLElBQUksQ0FBQyxzRkFBc0YsQ0FBQztFQUN2RztFQUNBLE9BQU9GLFFBQVE7QUFDakIsQ0FBQztBQVFEakYsUUFBUSxDQUFDb0YsdUNBQXVDLEdBQUcsZUFBZUEsdUNBQXVDQSxDQUFBLEVBQUk7RUFDM0csTUFBTTlDLHlDQUF5QyxDQUFDLElBQUksQ0FBQ0MsR0FBRyxDQUFDO0VBRXpELE1BQU1zQyxRQUFRLEdBQUcsSUFBSWxDLHVCQUF1QixDQUFDLElBQUksQ0FBQ0osR0FBRyxDQUFDO0VBQ3RELE9BQU8sTUFBTXNDLFFBQVEsQ0FBQ2hDLFNBQVMsQ0FBQyxDQUFDO0FBQ25DLENBQUM7QUFtQ0Q3QyxRQUFRLENBQUNxRixrQ0FBa0MsR0FBRyxlQUFlQSxrQ0FBa0NBLENBQUV2RCxPQUFPLEdBQUcsQ0FBQyxDQUFDLEVBQUU7RUFDN0csTUFBTVEseUNBQXlDLENBQUMsSUFBSSxDQUFDQyxHQUFHLENBQUM7RUFFekQsTUFBTXNDLFFBQVEsR0FBRyxJQUFJbEMsdUJBQXVCLENBQUMsSUFBSSxDQUFDSixHQUFHLENBQUM7RUFDdEQsSUFBSSxNQUFNc0MsUUFBUSxDQUFDTixJQUFJLENBQUMsQ0FBQyxFQUFFO0lBQ3pCLElBQUksQ0FBQ1csR0FBRyxDQUFDQyxJQUFJLENBQUMsK0VBQStFLENBQUM7RUFDaEcsQ0FBQyxNQUFNO0lBQ0wsSUFBSSxDQUFDRCxHQUFHLENBQUNDLElBQUksQ0FBQyxxRUFBcUUsQ0FBQztFQUN0RjtFQUNBLE1BQU1HLG1CQUFtQixHQUFHLE1BQU1ULFFBQVEsQ0FBQ2YsVUFBVSxDQUFDLENBQUM7RUFDdkQsSUFBSSxDQUFDd0IsbUJBQW1CLEVBQUU7SUFDeEIsTUFBTSxJQUFJNUMsS0FBSyxDQUFFLDBFQUF5RSxDQUFDO0VBQzdGO0VBRUEsTUFBTTtJQUFDM0I7RUFBVSxDQUFDLEdBQUdlLE9BQU87RUFDNUIsSUFBSWIsZUFBQyxDQUFDQyxPQUFPLENBQUNILFVBQVUsQ0FBQyxFQUFFO0lBQ3pCLE1BQU07TUFBQ3dFO0lBQUksQ0FBQyxHQUFHLE1BQU1DLFdBQUUsQ0FBQ0MsSUFBSSxDQUFDSCxtQkFBbUIsQ0FBQztJQUNqRCxJQUFJLENBQUNKLEdBQUcsQ0FBQ1EsS0FBSyxDQUFFLDJEQUEwRHZFLGFBQUksQ0FBQ3dFLG9CQUFvQixDQUFDSixJQUFJLENBQUUsRUFBQyxDQUFDO0VBQzlHO0VBQ0EsSUFBSTtJQUNGLE9BQU8sTUFBTTFFLG1CQUFtQixDQUFDeUUsbUJBQW1CLEVBQUV2RSxVQUFVLEVBQUVlLE9BQU8sQ0FBQztFQUM1RSxDQUFDLFNBQVM7SUFDUixNQUFNMEQsV0FBRSxDQUFDSSxNQUFNLENBQUMxQixhQUFJLENBQUMyQixPQUFPLENBQUNQLG1CQUFtQixDQUFDLENBQUM7RUFDcEQ7QUFDRixDQUFDO0FBQUMsSUFBQVEsUUFBQSxHQUlhOUYsUUFBUTtBQUFBQyxPQUFBLENBQUE4RixPQUFBLEdBQUFELFFBQUEifQ==
252
+ exports.default = commands;
253
+ //# sourceMappingURL=media-projection.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"media-projection.js","names":["_lodash","_interopRequireDefault","require","_asyncbox","_support","_path","_bluebird","_androidHelpers","_moment","commands","exports","DEFAULT_EXT","RECORDING_STARTUP_TIMEOUT_MS","RECORDING_STOP_TIMEOUT_MS","MIN_API_LEVEL","RECORDING_SERVICE_NAME","SETTINGS_HELPER_PKG_ID","RECORDING_ACTIVITY_NAME","RECORDING_ACTION_START","RECORDING_ACTION_STOP","RECORDINGS_ROOT","DEFAULT_FILENAME_FORMAT","uploadRecordedMedia","localFile","remotePath","uploadOptions","_","isEmpty","util","toInMemoryBase64","toString","user","pass","method","headers","fileFieldName","formFields","uploadTimeout","timeout","options","auth","net","uploadFile","adjustMediaExtension","name","toLower","endsWith","verifyMediaProjectionRecordingIsSupported","adb","apiLevel","getApiLevel","Error","MediaProjectionRecorder","constructor","isRunning","stdout","shell","includes","start","opts","cleanup","filename","maxDurationSec","priority","resolution","args","push","B","resolve","reject","setTimeout","pullRecent","recordings","ls","dstPath","path","join","tempDir","openDir","pull","stop","waitForCondition","waitMs","intervalMs","e","mobileStartMediaProjectionRecording","recorder","fname","moment","format","didStart","log","info","mobileIsMediaProjectionRecordingRunning","mobileStopMediaProjectionRecording","recentRecordingPath","size","fs","stat","debug","toReadableSizeString","rimraf","dirname","_default","default"],"sources":["../../../lib/commands/media-projection.js"],"sourcesContent":["import _ from 'lodash';\nimport { waitForCondition } from 'asyncbox';\nimport { util, fs, net, tempDir } from '@appium/support';\nimport path from 'path';\nimport B from 'bluebird';\nimport { SETTINGS_HELPER_PKG_ID } from '../android-helpers';\nimport moment from 'moment';\n\n\nconst commands = {};\n\n// https://github.com/appium/io.appium.settings#internal-audio--video-recording\nconst DEFAULT_EXT = '.mp4';\nconst RECORDING_STARTUP_TIMEOUT_MS = 3 * 1000;\nconst RECORDING_STOP_TIMEOUT_MS = 3 * 1000;\nconst MIN_API_LEVEL = 29;\nconst RECORDING_SERVICE_NAME = `${SETTINGS_HELPER_PKG_ID}/.recorder.RecorderService`;\nconst RECORDING_ACTIVITY_NAME = `${SETTINGS_HELPER_PKG_ID}/io.appium.settings.Settings`;\nconst RECORDING_ACTION_START = `${SETTINGS_HELPER_PKG_ID}.recording.ACTION_START`;\nconst RECORDING_ACTION_STOP = `${SETTINGS_HELPER_PKG_ID}.recording.ACTION_STOP`;\nconst RECORDINGS_ROOT = `/storage/emulated/0/Android/data/${SETTINGS_HELPER_PKG_ID}/files`;\nconst DEFAULT_FILENAME_FORMAT = 'YYYY-MM-DDTHH-mm-ss';\n\n\nasync function uploadRecordedMedia (localFile, remotePath = null, uploadOptions = {}) {\n if (_.isEmpty(remotePath)) {\n return (await util.toInMemoryBase64(localFile)).toString();\n }\n\n const {\n user,\n pass,\n method,\n headers,\n fileFieldName,\n formFields,\n uploadTimeout: timeout,\n } = uploadOptions;\n const options = {\n method: method || 'PUT',\n headers,\n fileFieldName,\n formFields,\n timeout,\n };\n if (user && pass) {\n options.auth = {user, pass};\n }\n await net.uploadFile(localFile, remotePath, options);\n return '';\n}\n\nfunction adjustMediaExtension (name) {\n return _.toLower(name).endsWith(DEFAULT_EXT) ? name : `${name}${DEFAULT_EXT}`;\n}\n\nasync function verifyMediaProjectionRecordingIsSupported (adb) {\n const apiLevel = await adb.getApiLevel();\n if (apiLevel < MIN_API_LEVEL) {\n throw new Error(`Media projection-based recording is not available on API Level ${apiLevel}. ` +\n `Minimum required API Level is ${MIN_API_LEVEL}.`);\n }\n}\n\n\nclass MediaProjectionRecorder {\n constructor (adb) {\n this.adb = adb;\n }\n\n async isRunning () {\n const stdout = await this.adb.shell([\n 'dumpsys', 'activity', 'services', RECORDING_SERVICE_NAME\n ]);\n return stdout.includes(RECORDING_SERVICE_NAME);\n }\n\n async start (opts = {}) {\n if (await this.isRunning()) {\n return false;\n }\n\n await this.cleanup();\n const {\n filename,\n maxDurationSec,\n priority,\n resolution,\n } = opts;\n const args = [\n 'am', 'start',\n '-n', RECORDING_ACTIVITY_NAME,\n '-a', RECORDING_ACTION_START,\n ];\n if (filename) {\n args.push('--es', 'filename', filename);\n }\n if (maxDurationSec) {\n args.push('--es', 'max_duration_sec', `${maxDurationSec}`);\n }\n if (priority) {\n args.push('--es', 'priority', priority);\n }\n if (resolution) {\n args.push('--es', 'resolution', resolution);\n }\n await this.adb.shell(args);\n await new B((resolve, reject) => {\n setTimeout(async () => {\n if (!await this.isRunning()) {\n return reject(new Error(\n `The media projection recording is not running after ${RECORDING_STARTUP_TIMEOUT_MS}ms. ` +\n `Please check the logcat output for more details.`\n ));\n }\n resolve();\n }, RECORDING_STARTUP_TIMEOUT_MS);\n });\n return true;\n }\n\n async cleanup () {\n await this.adb.shell([`rm -f ${RECORDINGS_ROOT}/*`]);\n }\n\n async pullRecent () {\n const recordings = await this.adb.ls(RECORDINGS_ROOT, ['-tr']);\n if (_.isEmpty(recordings)) {\n return null;\n }\n\n const dstPath = path.join(await tempDir.openDir(), recordings[0]);\n // increase timeout to 5 minutes because it might take a while to pull a large video file\n await this.adb.pull(`${RECORDINGS_ROOT}/${recordings[0]}`, dstPath, {timeout: 300000});\n return dstPath;\n }\n\n async stop () {\n if (!await this.isRunning()) {\n return false;\n }\n\n await this.adb.shell([\n 'am', 'start',\n '-n', RECORDING_ACTIVITY_NAME,\n '-a', RECORDING_ACTION_STOP,\n ]);\n try {\n await waitForCondition(async () => !(await this.isRunning()), {\n waitMs: RECORDING_STOP_TIMEOUT_MS,\n intervalMs: 500,\n });\n } catch (e) {\n throw new Error(\n `The attempt to stop the current media projection recording timed out after ` +\n `${RECORDING_STOP_TIMEOUT_MS}ms`\n );\n }\n return true;\n }\n}\n\n\n/**\n * @typedef {Object} StartRecordingOptions\n *\n * @property {string?} resolution Maximum supported resolution on-device (Detected\n * automatically by the app itself), which usually equals to Full HD 1920x1080 on most\n * phones however you can change it to following supported resolutions\n * as well: \"1920x1080\", \"1280x720\", \"720x480\", \"320x240\", \"176x144\".\n * @property {number?} maxDurationSec [900] Default value: 900 seconds which means\n * maximum allowed duration is 15 minute, you can increase it if your test takes\n * longer than that.\n * @property {string?} priority [high] Means recording thread priority is maximum\n * however if you face performance drops during testing with recording enabled, you\n * can reduce recording priority to \"normal\" or \"low\".\n * @property {string?} filename You can type recording video file name as you want,\n * but recording currently supports only \"mp4\" format so your filename must end with \".mp4\".\n * An invalid file name will fail to start the recording.\n * If not provided then the current timestamp will be used as file name.\n */\n\n/**\n * Record the display of a real devices running Android 10 (API level 29) and higher.\n * The screen activity is recorded to a MPEG-4 file. Audio is also recorded by default\n * (only for apps that allow it in their manifests).\n * If another recording has been already started then the command will exit silently.\n * The previously recorded video file is deleted when a new recording session is started.\n * Recording continues it is stopped explicitly or until the timeout happens.\n *\n * @param {?StartRecordingOptions} options Available options.\n * @returns {boolean} True if a new recording has successfully started.\n * @throws {Error} If recording has failed to start or is not supported on the device under test.\n */\ncommands.mobileStartMediaProjectionRecording = async function mobileStartMediaProjectionRecording (options = {}) {\n await verifyMediaProjectionRecordingIsSupported(this.adb);\n\n const {resolution, priority, maxDurationSec, filename} = options;\n const recorder = new MediaProjectionRecorder(this.adb);\n const fname = adjustMediaExtension(filename || moment().format(DEFAULT_FILENAME_FORMAT));\n const didStart = await recorder.start({\n resolution,\n priority,\n maxDurationSec,\n filename: fname,\n });\n if (didStart) {\n this.log.info(`A new media projection recording '${fname}' has been successfully started`);\n } else {\n this.log.info('Another media projection recording is already in progress. There is nothing to start');\n }\n return didStart;\n};\n\n/**\n * Checks if a media projection-based recording is currently running.\n *\n * @returns {boolean} True if a recording is in progress.\n * @throws {Error} If a recording is not supported on the device under test.\n */\ncommands.mobileIsMediaProjectionRecordingRunning = async function mobileIsMediaProjectionRecordingRunning () {\n await verifyMediaProjectionRecordingIsSupported(this.adb);\n\n const recorder = new MediaProjectionRecorder(this.adb);\n return await recorder.isRunning();\n};\n\n/**\n * @typedef {Object} StopRecordingOptions\n *\n * @property {string?} remotePath The path to the remote location, where the resulting video should be uploaded.\n * The following protocols are supported: http/https, ftp.\n * Null or empty string value (the default setting) means the content of resulting\n * file should be encoded as Base64 and passed as the endpoont response value.\n * An exception will be thrown if the generated media file is too big to\n * fit into the available process memory.\n * @property {string?} user The name of the user for the remote authentication.\n * @property {string?} pass The password for the remote authentication.\n * @property {string?} method The http multipart upload method name. The 'PUT' one is used by default.\n * @property {Object?} headers Additional headers mapping for multipart http(s) uploads\n * @property {string?} fileFieldName [file] The name of the form field, where the file content BLOB should be stored for\n * http(s) uploads\n * @property {Object|Array<Pair>?} formFields Additional form fields for multipart http(s) uploads\n * @property {number?} uploadTimeout - The actual media upload request timeout in milliseconds;\n * defaults to @appium/support net DEFAULT_TIMEOUT_MS\n */\n\n/**\n * Stop a media projection-based recording.\n * If no recording has been started before then an error is thrown.\n * If the recording has been already finished before this API has been called\n * then the most recent recorded file is returned.\n *\n * @param {?StopRecordingOptions} options Available options.\n * @returns {string} Base64-encoded content of the recorded media file if 'remotePath'\n * parameter is falsy or an empty string.\n * @throws {Error} If there was an error while stopping a recording,\n * fetching the content of the remote media file,\n * or if a recording is not supported on the device under test.\n */\ncommands.mobileStopMediaProjectionRecording = async function mobileStopMediaProjectionRecording (options = {}) {\n await verifyMediaProjectionRecordingIsSupported(this.adb);\n\n const recorder = new MediaProjectionRecorder(this.adb);\n if (await recorder.stop()) {\n this.log.info('Successfully stopped a media projection recording. Pulling the recorded media');\n } else {\n this.log.info('Media projection recording is not running. There is nothing to stop');\n }\n const recentRecordingPath = await recorder.pullRecent();\n if (!recentRecordingPath) {\n throw new Error(`No recent media projection recording have been found. Did you start any?`);\n }\n\n const {remotePath} = options;\n if (_.isEmpty(remotePath)) {\n const {size} = await fs.stat(recentRecordingPath);\n this.log.debug(`The size of the resulting media projection recording is ${util.toReadableSizeString(size)}`);\n }\n try {\n return await uploadRecordedMedia(recentRecordingPath, remotePath, options);\n } finally {\n await fs.rimraf(path.dirname(recentRecordingPath));\n }\n};\n\n\nexport { commands };\nexport default commands;\n"],"mappings":"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"}
1
+ {"version":3,"file":"media-projection.js","sourceRoot":"","sources":["../../../lib/commands/media-projection.js"],"names":[],"mappings":"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"}