appium-android-driver 5.7.1 → 5.7.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 (58) hide show
  1. package/CHANGELOG.md +2 -0
  2. package/build/lib/android-helpers.js +2 -2
  3. package/build/lib/android-helpers.js.map +1 -1
  4. package/build/lib/bootstrap.js +2 -2
  5. package/build/lib/bootstrap.js.map +1 -1
  6. package/build/lib/commands/actions.js +2 -2
  7. package/build/lib/commands/actions.js.map +1 -1
  8. package/build/lib/commands/app-management.js +2 -2
  9. package/build/lib/commands/app-management.js.map +1 -1
  10. package/build/lib/commands/context.js +2 -2
  11. package/build/lib/commands/context.js.map +1 -1
  12. package/build/lib/commands/element.js +2 -2
  13. package/build/lib/commands/element.js.map +1 -1
  14. package/build/lib/commands/file-actions.js +2 -2
  15. package/build/lib/commands/file-actions.js.map +1 -1
  16. package/build/lib/commands/general.js +2 -2
  17. package/build/lib/commands/general.js.map +1 -1
  18. package/build/lib/commands/media-projection.js +2 -2
  19. package/build/lib/commands/media-projection.js.map +1 -1
  20. package/build/lib/commands/recordscreen.js +2 -2
  21. package/build/lib/commands/recordscreen.js.map +1 -1
  22. package/build/lib/commands/shell.js +2 -2
  23. package/build/lib/commands/shell.js.map +1 -1
  24. package/build/lib/commands/streamscreen.js +2 -2
  25. package/build/lib/commands/streamscreen.js.map +1 -1
  26. package/build/lib/commands/touch.js +2 -2
  27. package/build/lib/commands/touch.js.map +1 -1
  28. package/build/lib/desired-caps.js +2 -1
  29. package/build/lib/desired-caps.js.map +1 -1
  30. package/build/lib/driver.js +2 -2
  31. package/build/lib/driver.js.map +1 -1
  32. package/build/lib/logger.js +2 -2
  33. package/build/lib/logger.js.map +1 -1
  34. package/build/lib/uiautomator.js +2 -2
  35. package/build/lib/uiautomator.js.map +1 -1
  36. package/build/lib/unlock-helpers.js +2 -2
  37. package/build/lib/unlock-helpers.js.map +1 -1
  38. package/build/lib/webview-helpers.js +2 -2
  39. package/build/lib/webview-helpers.js.map +1 -1
  40. package/lib/android-helpers.js +1 -1
  41. package/lib/bootstrap.js +1 -1
  42. package/lib/commands/actions.js +1 -1
  43. package/lib/commands/app-management.js +1 -1
  44. package/lib/commands/context.js +1 -1
  45. package/lib/commands/element.js +1 -1
  46. package/lib/commands/file-actions.js +1 -1
  47. package/lib/commands/general.js +1 -1
  48. package/lib/commands/media-projection.js +1 -1
  49. package/lib/commands/recordscreen.js +1 -1
  50. package/lib/commands/shell.js +1 -1
  51. package/lib/commands/streamscreen.js +1 -1
  52. package/lib/commands/touch.js +1 -1
  53. package/lib/driver.js +1 -1
  54. package/lib/logger.js +1 -1
  55. package/lib/uiautomator.js +1 -1
  56. package/lib/unlock-helpers.js +1 -1
  57. package/lib/webview-helpers.js +1 -1
  58. package/package.json +2 -1
@@ -1 +1 @@
1
- {"version":3,"file":"recordscreen.js","names":["commands","RETRY_PAUSE","RETRY_TIMEOUT","MAX_RECORDING_TIME_SEC","MAX_TIME_SEC","DEFAULT_RECORDING_TIME_SEC","PROCESS_SHUTDOWN_TIMEOUT","SCREENRECORD_BINARY","DEFAULT_EXT","MIN_EMULATOR_API_LEVEL","FFMPEG_BINARY","system","isWindows","uploadRecordedMedia","localFile","remotePath","uploadOptions","_","isEmpty","util","toInMemoryBase64","toString","user","pass","method","headers","fileFieldName","formFields","options","auth","net","uploadFile","verifyScreenRecordIsSupported","adb","isEmulator","apiLevel","getApiLevel","Error","scheduleScreenRecord","recordingProperties","log","stopped","timer","videoSize","bitRate","timeLimit","bugReport","currentTimeLimit","hasValue","currentTimeLimitInt","parseInt","isNaN","pathOnDevice","uuidV4","substring","recordingProc","screenrecord","on","currentDuration","getDuration","asSeconds","toFixed","debug","timeLimitInt","chunkDuration","e","error","stack","start","waitForCondition","fileExists","waitMs","intervalMs","records","push","recordingProcess","mergeScreenRecords","mediaFiles","fs","which","configContent","map","x","join","configFile","path","resolve","dirname","writeFile","result","Math","floor","Date","args","info","exec","terminateBackgroundScreenRecording","force","pids","getPIDsByName","p","shell","err","message","startRecordingScreen","forceRestart","stopRecordingScreen","warn","_screenRecordingProperties","record","rimraf","timeout","parseFloat","timing","Timer","isRunning","stop","errorAndThrow","tmpRoot","tempDir","openDir","localRecords","posix","basename","pull","last","resultFilePath","length","size","stat","toReadableSizeString"],"sources":["../../../lib/commands/recordscreen.js"],"sourcesContent":["import _ from 'lodash';\nimport { waitForCondition } from 'asyncbox';\nimport { util, fs, net, tempDir, system, timing } from 'appium/support';\nimport { exec } from 'teen_process';\nimport path from 'path';\n\n\nconst commands = {};\n\nconst RETRY_PAUSE = 300;\nconst RETRY_TIMEOUT = 5000;\nconst MAX_RECORDING_TIME_SEC = 60 * 3;\nconst MAX_TIME_SEC = 60 * 30;\nconst DEFAULT_RECORDING_TIME_SEC = MAX_RECORDING_TIME_SEC;\nconst PROCESS_SHUTDOWN_TIMEOUT = 10 * 1000;\nconst SCREENRECORD_BINARY = 'screenrecord';\nconst DEFAULT_EXT = '.mp4';\nconst MIN_EMULATOR_API_LEVEL = 27;\nconst FFMPEG_BINARY = `ffmpeg${system.isWindows() ? '.exe' : ''}`;\n\nasync function uploadRecordedMedia (localFile, remotePath = null, uploadOptions = {}) {\n if (_.isEmpty(remotePath)) {\n return (await util.toInMemoryBase64(localFile)).toString();\n }\n\n const {user, pass, method, headers, fileFieldName, formFields} = uploadOptions;\n const options = {\n method: method || 'PUT',\n headers,\n fileFieldName,\n formFields,\n };\n if (user && pass) {\n options.auth = {user, pass};\n }\n await net.uploadFile(localFile, remotePath, options);\n return '';\n}\n\nasync function verifyScreenRecordIsSupported (adb, isEmulator) {\n const apiLevel = await adb.getApiLevel();\n if (isEmulator && apiLevel < MIN_EMULATOR_API_LEVEL) {\n throw new Error(`Screen recording does not work on emulators running Android API level less than ${MIN_EMULATOR_API_LEVEL}`);\n }\n if (apiLevel < 19) {\n throw new Error(`Screen recording not available on API Level ${apiLevel}. Minimum API Level is 19.`);\n }\n}\n\nasync function scheduleScreenRecord (adb, recordingProperties, log = null) {\n if (recordingProperties.stopped) {\n return;\n }\n\n const {\n timer,\n videoSize,\n bitRate,\n timeLimit,\n bugReport,\n } = recordingProperties;\n\n let currentTimeLimit = MAX_RECORDING_TIME_SEC;\n if (util.hasValue(recordingProperties.currentTimeLimit)) {\n const currentTimeLimitInt = parseInt(recordingProperties.currentTimeLimit, 10);\n if (!isNaN(currentTimeLimitInt) && currentTimeLimitInt < MAX_RECORDING_TIME_SEC) {\n currentTimeLimit = currentTimeLimitInt;\n }\n }\n const pathOnDevice = `/sdcard/${util.uuidV4().substring(0, 8)}${DEFAULT_EXT}`;\n const recordingProc = adb.screenrecord(pathOnDevice, {\n videoSize,\n bitRate,\n timeLimit: currentTimeLimit,\n bugReport,\n });\n\n recordingProc.on('end', () => {\n if (recordingProperties.stopped || !util.hasValue(timeLimit)) {\n return;\n }\n const currentDuration = timer.getDuration().asSeconds.toFixed(0);\n log?.debug(`The overall screen recording duration is ${currentDuration}s so far`);\n const timeLimitInt = parseInt(timeLimit, 10);\n if (isNaN(timeLimitInt) || currentDuration >= timeLimitInt) {\n log?.debug('There is no need to start the next recording chunk');\n return;\n }\n\n recordingProperties.currentTimeLimit = timeLimitInt - currentDuration;\n const chunkDuration = recordingProperties.currentTimeLimit < MAX_RECORDING_TIME_SEC\n ? recordingProperties.currentTimeLimit\n : MAX_RECORDING_TIME_SEC;\n log?.debug(`Starting the next ${chunkDuration}s-chunk ` +\n `of screen recording in order to achieve ${timeLimitInt}s total duration`);\n (async () => {\n try {\n await scheduleScreenRecord(adb, recordingProperties, log);\n } catch (e) {\n log?.error(e.stack);\n recordingProperties.stopped = true;\n }\n })();\n });\n\n await recordingProc.start(0);\n try {\n await waitForCondition(async () => await adb.fileExists(pathOnDevice),\n {waitMs: RETRY_TIMEOUT, intervalMs: RETRY_PAUSE});\n } catch (e) {\n throw new Error(`The expected screen record file '${pathOnDevice}' does not exist after ${RETRY_TIMEOUT}ms. ` +\n `Is ${SCREENRECORD_BINARY} utility available and operational on the device under test?`);\n }\n\n recordingProperties.records.push(pathOnDevice);\n recordingProperties.recordingProcess = recordingProc;\n}\n\nasync function mergeScreenRecords (mediaFiles, log = null) {\n try {\n await fs.which(FFMPEG_BINARY);\n } catch (e) {\n throw new Error(`${FFMPEG_BINARY} utility is not available in PATH. Please install it from https://www.ffmpeg.org/`);\n }\n const configContent = mediaFiles\n .map((x) => `file '${x}'`)\n .join('\\n');\n const configFile = path.resolve(path.dirname(mediaFiles[0]), 'config.txt');\n await fs.writeFile(configFile, configContent, 'utf8');\n log?.debug(`Generated ffmpeg merging config '${configFile}' with items:\\n${configContent}`);\n const result = path.resolve(path.dirname(mediaFiles[0]), `merge_${Math.floor(new Date())}${DEFAULT_EXT}`);\n const args = ['-safe', '0', '-f', 'concat', '-i', configFile, '-c', 'copy', result];\n log?.info(`Initiating screen records merging using the command '${FFMPEG_BINARY} ${args.join(' ')}'`);\n await exec(FFMPEG_BINARY, args);\n return result;\n}\n\nasync function terminateBackgroundScreenRecording (adb, force = true) {\n const pids = (await adb.getPIDsByName(SCREENRECORD_BINARY))\n .map((p) => `${p}`);\n if (_.isEmpty(pids)) {\n return false;\n }\n\n try {\n await adb.shell(['kill', force ? '-15' : '-2', ...pids]);\n await waitForCondition(async () => _.isEmpty(await adb.getPIDsByName(SCREENRECORD_BINARY)), {\n waitMs: PROCESS_SHUTDOWN_TIMEOUT,\n intervalMs: 500,\n });\n return true;\n } catch (err) {\n throw new Error(`Unable to stop the background screen recording: ${err.message}`);\n }\n}\n\n\n/**\n * @typedef {Object} StartRecordingOptions\n *\n * @property {?string} remotePath - The path to the remote location, where the captured 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 endpount 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 * This option only has an effect if there is screen recording process in progreess\n * and `forceRestart` parameter is not set to `true`.\n * @property {?string} user - The name of the user for the remote authentication. Only works if `remotePath` is provided.\n * @property {?string} pass - The password for the remote authentication. Only works if `remotePath` is provided.\n * @property {?string} method [PUT] - The http multipart upload method name. Only works if `remotePath` is provided.\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 {?string} videoSize - The format is widthxheight.\n * The default value is the device's native display resolution (if supported),\n * 1280x720 if not. For best results,\n * use a size supported by your device's Advanced Video Coding (AVC) encoder.\n * For example, \"1280x720\"\n * @property {?boolean} bugReport - Set it to `true` in order to display additional information on the video overlay,\n * such as a timestamp, that is helpful in videos captured to illustrate bugs.\n * This option is only supported since API level 27 (Android P).\n * @property {?string|number} timeLimit - The maximum recording time, in seconds. The default value is 180 (3 minutes).\n * The maximum value is 1800 (30 minutes). If the passed value is greater than 180 then\n * the algorithm will try to schedule multiple screen recording chunks and merge the\n * resulting videos into a single media file using `ffmpeg` utility.\n * If the utility is not available in PATH then the most recent screen recording chunk is\n * going to be returned.\n * @property {?string|number} bitRate - The video bit rate for the video, in bits per second.\n * The default value is 4000000 (4 Mbit/s). You can increase the bit rate to improve video quality,\n * but doing so results in larger movie files.\n * @property {?boolean} forceRestart - Whether to try to catch and upload/return the currently running screen recording\n * (`false`, the default setting) or ignore the result of it and start a new recording\n * immediately (`true`).\n */\n\n/**\n * Record the display of a real devices running Android 4.4 (API level 19) and higher.\n * Emulators are supported since API level 27 (Android P).\n * It records screen activity to an MPEG-4 file. Audio is not recorded with the video file.\n * If screen recording has been already started then the command will stop it forcefully and start a new one.\n * The previously recorded video file will be deleted.\n *\n * @param {?StartRecordingOptions} options - The available options.\n * @returns {string} Base64-encoded content of the recorded media file if\n * any screen recording is currently running or an empty string.\n * @throws {Error} If screen recording has failed to start or is not supported on the device under test.\n */\ncommands.startRecordingScreen = async function startRecordingScreen (options = {}) {\n await verifyScreenRecordIsSupported(this.adb, this.isEmulator());\n\n let result = '';\n const {videoSize, timeLimit = DEFAULT_RECORDING_TIME_SEC, bugReport, bitRate, forceRestart} = options;\n if (!forceRestart) {\n result = await this.stopRecordingScreen(options);\n }\n\n if (await terminateBackgroundScreenRecording(this.adb, true)) {\n this.log.warn(`There were some ${SCREENRECORD_BINARY} process leftovers running ` +\n `in the background. Make sure you stop screen recording each time after it is started, ` +\n `otherwise the recorded media might quickly exceed all the free space on the device under test.`);\n }\n\n if (!_.isEmpty(this._screenRecordingProperties)) {\n for (const record of (this._screenRecordingProperties.records || [])) {\n await this.adb.rimraf(record);\n }\n this._screenRecordingProperties = null;\n }\n\n const timeout = parseFloat(timeLimit);\n if (isNaN(timeout) || timeout > MAX_TIME_SEC || timeout <= 0) {\n throw new Error(`The timeLimit value must be in range [1, ${MAX_TIME_SEC}] seconds. ` +\n `The value of '${timeLimit}' has been passed instead.`);\n }\n\n this._screenRecordingProperties = {\n timer: new timing.Timer().start(),\n videoSize,\n timeLimit,\n currentTimeLimit: timeLimit,\n bitRate,\n bugReport,\n records: [],\n recordingProcess: null,\n stopped: false,\n };\n await scheduleScreenRecord(this.adb, this._screenRecordingProperties, this.log);\n return result;\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 endpount 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 */\n\n/**\n * Stop recording the screen.\n * If no screen recording has been started before then the method returns an empty string.\n *\n * @param {?StopRecordingOptions} options - The 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 getting the name of a media file\n * or the file content cannot be uploaded to the remote location\n * or screen recording is not supported on the device under test.\n */\ncommands.stopRecordingScreen = async function stopRecordingScreen (options = {}) {\n await verifyScreenRecordIsSupported(this.adb, this.isEmulator());\n\n if (!_.isEmpty(this._screenRecordingProperties)) {\n this._screenRecordingProperties.stopped = true;\n }\n\n try {\n await terminateBackgroundScreenRecording(this.adb, false);\n } catch (err) {\n this.log.warn(err.message);\n if (!_.isEmpty(this._screenRecordingProperties)) {\n this.log.warn('The resulting video might be corrupted');\n }\n }\n\n if (_.isEmpty(this._screenRecordingProperties)) {\n this.log.info(`Screen recording has not been previously started by Appium. There is nothing to stop`);\n return '';\n }\n\n if (this._screenRecordingProperties.recordingProcess && this._screenRecordingProperties.recordingProcess.isRunning) {\n try {\n await this._screenRecordingProperties.recordingProcess.stop('SIGINT', PROCESS_SHUTDOWN_TIMEOUT);\n } catch (e) {\n this.log.errorAndThrow(`Unable to stop screen recording within ${PROCESS_SHUTDOWN_TIMEOUT}ms`);\n }\n this._screenRecordingProperties.recordingProcess = null;\n }\n\n if (_.isEmpty(this._screenRecordingProperties.records)) {\n this.log.errorAndThrow(`No screen recordings have been stored on the device so far. ` +\n `Are you sure the ${SCREENRECORD_BINARY} utility works as expected?`);\n }\n\n const tmpRoot = await tempDir.openDir();\n try {\n const localRecords = [];\n for (const pathOnDevice of this._screenRecordingProperties.records) {\n localRecords.push(path.resolve(tmpRoot, path.posix.basename(pathOnDevice)));\n await this.adb.pull(pathOnDevice, _.last(localRecords));\n await this.adb.rimraf(pathOnDevice);\n }\n let resultFilePath = _.last(localRecords);\n if (localRecords.length > 1) {\n this.log.info(`Got ${localRecords.length} screen recordings. Trying to merge them`);\n try {\n resultFilePath = await mergeScreenRecords(localRecords, this.log);\n } catch (e) {\n this.log.warn(`Cannot merge the recorded files. The most recent screen recording is going to be returned as the result. ` +\n `Original error: ${e.message}`);\n }\n }\n if (_.isEmpty(options.remotePath)) {\n const {size} = await fs.stat(resultFilePath);\n this.log.debug(`The size of the resulting screen recording is ${util.toReadableSizeString(size)}`);\n }\n return await uploadRecordedMedia(resultFilePath, options.remotePath, options);\n } finally {\n await fs.rimraf(tmpRoot);\n this._screenRecordingProperties = null;\n }\n};\n\n\nexport { commands };\nexport default commands;\n"],"mappings":"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"}
1
+ {"version":3,"file":"recordscreen.js","names":["commands","RETRY_PAUSE","RETRY_TIMEOUT","MAX_RECORDING_TIME_SEC","MAX_TIME_SEC","DEFAULT_RECORDING_TIME_SEC","PROCESS_SHUTDOWN_TIMEOUT","SCREENRECORD_BINARY","DEFAULT_EXT","MIN_EMULATOR_API_LEVEL","FFMPEG_BINARY","system","isWindows","uploadRecordedMedia","localFile","remotePath","uploadOptions","_","isEmpty","util","toInMemoryBase64","toString","user","pass","method","headers","fileFieldName","formFields","options","auth","net","uploadFile","verifyScreenRecordIsSupported","adb","isEmulator","apiLevel","getApiLevel","Error","scheduleScreenRecord","recordingProperties","log","stopped","timer","videoSize","bitRate","timeLimit","bugReport","currentTimeLimit","hasValue","currentTimeLimitInt","parseInt","isNaN","pathOnDevice","uuidV4","substring","recordingProc","screenrecord","on","currentDuration","getDuration","asSeconds","toFixed","debug","timeLimitInt","chunkDuration","e","error","stack","start","waitForCondition","fileExists","waitMs","intervalMs","records","push","recordingProcess","mergeScreenRecords","mediaFiles","fs","which","configContent","map","x","join","configFile","path","resolve","dirname","writeFile","result","Math","floor","Date","args","info","exec","terminateBackgroundScreenRecording","force","pids","getPIDsByName","p","shell","err","message","startRecordingScreen","forceRestart","stopRecordingScreen","warn","_screenRecordingProperties","record","rimraf","timeout","parseFloat","timing","Timer","isRunning","stop","errorAndThrow","tmpRoot","tempDir","openDir","localRecords","posix","basename","pull","last","resultFilePath","length","size","stat","toReadableSizeString"],"sources":["../../../lib/commands/recordscreen.js"],"sourcesContent":["import _ from 'lodash';\nimport { waitForCondition } from 'asyncbox';\nimport { util, fs, net, tempDir, system, timing } from '@appium/support';\nimport { exec } from 'teen_process';\nimport path from 'path';\n\n\nconst commands = {};\n\nconst RETRY_PAUSE = 300;\nconst RETRY_TIMEOUT = 5000;\nconst MAX_RECORDING_TIME_SEC = 60 * 3;\nconst MAX_TIME_SEC = 60 * 30;\nconst DEFAULT_RECORDING_TIME_SEC = MAX_RECORDING_TIME_SEC;\nconst PROCESS_SHUTDOWN_TIMEOUT = 10 * 1000;\nconst SCREENRECORD_BINARY = 'screenrecord';\nconst DEFAULT_EXT = '.mp4';\nconst MIN_EMULATOR_API_LEVEL = 27;\nconst FFMPEG_BINARY = `ffmpeg${system.isWindows() ? '.exe' : ''}`;\n\nasync function uploadRecordedMedia (localFile, remotePath = null, uploadOptions = {}) {\n if (_.isEmpty(remotePath)) {\n return (await util.toInMemoryBase64(localFile)).toString();\n }\n\n const {user, pass, method, headers, fileFieldName, formFields} = uploadOptions;\n const options = {\n method: method || 'PUT',\n headers,\n fileFieldName,\n formFields,\n };\n if (user && pass) {\n options.auth = {user, pass};\n }\n await net.uploadFile(localFile, remotePath, options);\n return '';\n}\n\nasync function verifyScreenRecordIsSupported (adb, isEmulator) {\n const apiLevel = await adb.getApiLevel();\n if (isEmulator && apiLevel < MIN_EMULATOR_API_LEVEL) {\n throw new Error(`Screen recording does not work on emulators running Android API level less than ${MIN_EMULATOR_API_LEVEL}`);\n }\n if (apiLevel < 19) {\n throw new Error(`Screen recording not available on API Level ${apiLevel}. Minimum API Level is 19.`);\n }\n}\n\nasync function scheduleScreenRecord (adb, recordingProperties, log = null) {\n if (recordingProperties.stopped) {\n return;\n }\n\n const {\n timer,\n videoSize,\n bitRate,\n timeLimit,\n bugReport,\n } = recordingProperties;\n\n let currentTimeLimit = MAX_RECORDING_TIME_SEC;\n if (util.hasValue(recordingProperties.currentTimeLimit)) {\n const currentTimeLimitInt = parseInt(recordingProperties.currentTimeLimit, 10);\n if (!isNaN(currentTimeLimitInt) && currentTimeLimitInt < MAX_RECORDING_TIME_SEC) {\n currentTimeLimit = currentTimeLimitInt;\n }\n }\n const pathOnDevice = `/sdcard/${util.uuidV4().substring(0, 8)}${DEFAULT_EXT}`;\n const recordingProc = adb.screenrecord(pathOnDevice, {\n videoSize,\n bitRate,\n timeLimit: currentTimeLimit,\n bugReport,\n });\n\n recordingProc.on('end', () => {\n if (recordingProperties.stopped || !util.hasValue(timeLimit)) {\n return;\n }\n const currentDuration = timer.getDuration().asSeconds.toFixed(0);\n log?.debug(`The overall screen recording duration is ${currentDuration}s so far`);\n const timeLimitInt = parseInt(timeLimit, 10);\n if (isNaN(timeLimitInt) || currentDuration >= timeLimitInt) {\n log?.debug('There is no need to start the next recording chunk');\n return;\n }\n\n recordingProperties.currentTimeLimit = timeLimitInt - currentDuration;\n const chunkDuration = recordingProperties.currentTimeLimit < MAX_RECORDING_TIME_SEC\n ? recordingProperties.currentTimeLimit\n : MAX_RECORDING_TIME_SEC;\n log?.debug(`Starting the next ${chunkDuration}s-chunk ` +\n `of screen recording in order to achieve ${timeLimitInt}s total duration`);\n (async () => {\n try {\n await scheduleScreenRecord(adb, recordingProperties, log);\n } catch (e) {\n log?.error(e.stack);\n recordingProperties.stopped = true;\n }\n })();\n });\n\n await recordingProc.start(0);\n try {\n await waitForCondition(async () => await adb.fileExists(pathOnDevice),\n {waitMs: RETRY_TIMEOUT, intervalMs: RETRY_PAUSE});\n } catch (e) {\n throw new Error(`The expected screen record file '${pathOnDevice}' does not exist after ${RETRY_TIMEOUT}ms. ` +\n `Is ${SCREENRECORD_BINARY} utility available and operational on the device under test?`);\n }\n\n recordingProperties.records.push(pathOnDevice);\n recordingProperties.recordingProcess = recordingProc;\n}\n\nasync function mergeScreenRecords (mediaFiles, log = null) {\n try {\n await fs.which(FFMPEG_BINARY);\n } catch (e) {\n throw new Error(`${FFMPEG_BINARY} utility is not available in PATH. Please install it from https://www.ffmpeg.org/`);\n }\n const configContent = mediaFiles\n .map((x) => `file '${x}'`)\n .join('\\n');\n const configFile = path.resolve(path.dirname(mediaFiles[0]), 'config.txt');\n await fs.writeFile(configFile, configContent, 'utf8');\n log?.debug(`Generated ffmpeg merging config '${configFile}' with items:\\n${configContent}`);\n const result = path.resolve(path.dirname(mediaFiles[0]), `merge_${Math.floor(new Date())}${DEFAULT_EXT}`);\n const args = ['-safe', '0', '-f', 'concat', '-i', configFile, '-c', 'copy', result];\n log?.info(`Initiating screen records merging using the command '${FFMPEG_BINARY} ${args.join(' ')}'`);\n await exec(FFMPEG_BINARY, args);\n return result;\n}\n\nasync function terminateBackgroundScreenRecording (adb, force = true) {\n const pids = (await adb.getPIDsByName(SCREENRECORD_BINARY))\n .map((p) => `${p}`);\n if (_.isEmpty(pids)) {\n return false;\n }\n\n try {\n await adb.shell(['kill', force ? '-15' : '-2', ...pids]);\n await waitForCondition(async () => _.isEmpty(await adb.getPIDsByName(SCREENRECORD_BINARY)), {\n waitMs: PROCESS_SHUTDOWN_TIMEOUT,\n intervalMs: 500,\n });\n return true;\n } catch (err) {\n throw new Error(`Unable to stop the background screen recording: ${err.message}`);\n }\n}\n\n\n/**\n * @typedef {Object} StartRecordingOptions\n *\n * @property {?string} remotePath - The path to the remote location, where the captured 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 endpount 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 * This option only has an effect if there is screen recording process in progreess\n * and `forceRestart` parameter is not set to `true`.\n * @property {?string} user - The name of the user for the remote authentication. Only works if `remotePath` is provided.\n * @property {?string} pass - The password for the remote authentication. Only works if `remotePath` is provided.\n * @property {?string} method [PUT] - The http multipart upload method name. Only works if `remotePath` is provided.\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 {?string} videoSize - The format is widthxheight.\n * The default value is the device's native display resolution (if supported),\n * 1280x720 if not. For best results,\n * use a size supported by your device's Advanced Video Coding (AVC) encoder.\n * For example, \"1280x720\"\n * @property {?boolean} bugReport - Set it to `true` in order to display additional information on the video overlay,\n * such as a timestamp, that is helpful in videos captured to illustrate bugs.\n * This option is only supported since API level 27 (Android P).\n * @property {?string|number} timeLimit - The maximum recording time, in seconds. The default value is 180 (3 minutes).\n * The maximum value is 1800 (30 minutes). If the passed value is greater than 180 then\n * the algorithm will try to schedule multiple screen recording chunks and merge the\n * resulting videos into a single media file using `ffmpeg` utility.\n * If the utility is not available in PATH then the most recent screen recording chunk is\n * going to be returned.\n * @property {?string|number} bitRate - The video bit rate for the video, in bits per second.\n * The default value is 4000000 (4 Mbit/s). You can increase the bit rate to improve video quality,\n * but doing so results in larger movie files.\n * @property {?boolean} forceRestart - Whether to try to catch and upload/return the currently running screen recording\n * (`false`, the default setting) or ignore the result of it and start a new recording\n * immediately (`true`).\n */\n\n/**\n * Record the display of a real devices running Android 4.4 (API level 19) and higher.\n * Emulators are supported since API level 27 (Android P).\n * It records screen activity to an MPEG-4 file. Audio is not recorded with the video file.\n * If screen recording has been already started then the command will stop it forcefully and start a new one.\n * The previously recorded video file will be deleted.\n *\n * @param {?StartRecordingOptions} options - The available options.\n * @returns {string} Base64-encoded content of the recorded media file if\n * any screen recording is currently running or an empty string.\n * @throws {Error} If screen recording has failed to start or is not supported on the device under test.\n */\ncommands.startRecordingScreen = async function startRecordingScreen (options = {}) {\n await verifyScreenRecordIsSupported(this.adb, this.isEmulator());\n\n let result = '';\n const {videoSize, timeLimit = DEFAULT_RECORDING_TIME_SEC, bugReport, bitRate, forceRestart} = options;\n if (!forceRestart) {\n result = await this.stopRecordingScreen(options);\n }\n\n if (await terminateBackgroundScreenRecording(this.adb, true)) {\n this.log.warn(`There were some ${SCREENRECORD_BINARY} process leftovers running ` +\n `in the background. Make sure you stop screen recording each time after it is started, ` +\n `otherwise the recorded media might quickly exceed all the free space on the device under test.`);\n }\n\n if (!_.isEmpty(this._screenRecordingProperties)) {\n for (const record of (this._screenRecordingProperties.records || [])) {\n await this.adb.rimraf(record);\n }\n this._screenRecordingProperties = null;\n }\n\n const timeout = parseFloat(timeLimit);\n if (isNaN(timeout) || timeout > MAX_TIME_SEC || timeout <= 0) {\n throw new Error(`The timeLimit value must be in range [1, ${MAX_TIME_SEC}] seconds. ` +\n `The value of '${timeLimit}' has been passed instead.`);\n }\n\n this._screenRecordingProperties = {\n timer: new timing.Timer().start(),\n videoSize,\n timeLimit,\n currentTimeLimit: timeLimit,\n bitRate,\n bugReport,\n records: [],\n recordingProcess: null,\n stopped: false,\n };\n await scheduleScreenRecord(this.adb, this._screenRecordingProperties, this.log);\n return result;\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 endpount 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 */\n\n/**\n * Stop recording the screen.\n * If no screen recording has been started before then the method returns an empty string.\n *\n * @param {?StopRecordingOptions} options - The 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 getting the name of a media file\n * or the file content cannot be uploaded to the remote location\n * or screen recording is not supported on the device under test.\n */\ncommands.stopRecordingScreen = async function stopRecordingScreen (options = {}) {\n await verifyScreenRecordIsSupported(this.adb, this.isEmulator());\n\n if (!_.isEmpty(this._screenRecordingProperties)) {\n this._screenRecordingProperties.stopped = true;\n }\n\n try {\n await terminateBackgroundScreenRecording(this.adb, false);\n } catch (err) {\n this.log.warn(err.message);\n if (!_.isEmpty(this._screenRecordingProperties)) {\n this.log.warn('The resulting video might be corrupted');\n }\n }\n\n if (_.isEmpty(this._screenRecordingProperties)) {\n this.log.info(`Screen recording has not been previously started by Appium. There is nothing to stop`);\n return '';\n }\n\n if (this._screenRecordingProperties.recordingProcess && this._screenRecordingProperties.recordingProcess.isRunning) {\n try {\n await this._screenRecordingProperties.recordingProcess.stop('SIGINT', PROCESS_SHUTDOWN_TIMEOUT);\n } catch (e) {\n this.log.errorAndThrow(`Unable to stop screen recording within ${PROCESS_SHUTDOWN_TIMEOUT}ms`);\n }\n this._screenRecordingProperties.recordingProcess = null;\n }\n\n if (_.isEmpty(this._screenRecordingProperties.records)) {\n this.log.errorAndThrow(`No screen recordings have been stored on the device so far. ` +\n `Are you sure the ${SCREENRECORD_BINARY} utility works as expected?`);\n }\n\n const tmpRoot = await tempDir.openDir();\n try {\n const localRecords = [];\n for (const pathOnDevice of this._screenRecordingProperties.records) {\n localRecords.push(path.resolve(tmpRoot, path.posix.basename(pathOnDevice)));\n await this.adb.pull(pathOnDevice, _.last(localRecords));\n await this.adb.rimraf(pathOnDevice);\n }\n let resultFilePath = _.last(localRecords);\n if (localRecords.length > 1) {\n this.log.info(`Got ${localRecords.length} screen recordings. Trying to merge them`);\n try {\n resultFilePath = await mergeScreenRecords(localRecords, this.log);\n } catch (e) {\n this.log.warn(`Cannot merge the recorded files. The most recent screen recording is going to be returned as the result. ` +\n `Original error: ${e.message}`);\n }\n }\n if (_.isEmpty(options.remotePath)) {\n const {size} = await fs.stat(resultFilePath);\n this.log.debug(`The size of the resulting screen recording is ${util.toReadableSizeString(size)}`);\n }\n return await uploadRecordedMedia(resultFilePath, options.remotePath, options);\n } finally {\n await fs.rimraf(tmpRoot);\n this._screenRecordingProperties = null;\n }\n};\n\n\nexport { commands };\nexport default commands;\n"],"mappings":"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"}
@@ -8,7 +8,7 @@ exports.default = exports.commands = void 0;
8
8
  require("source-map-support/register");
9
9
  var _lodash = _interopRequireDefault(require("lodash"));
10
10
  var _teen_process = require("teen_process");
11
- var _support = require("appium/support");
11
+ var _support = require("@appium/support");
12
12
  var _driver = require("appium/driver");
13
13
  const ADB_SHELL_FEATURE = 'adb_shell';
14
14
  let commands = {};
@@ -46,4 +46,4 @@ commands.mobileShell = async function mobileShell(opts = {}) {
46
46
  };
47
47
  var _default = commands;
48
48
  exports.default = _default;
49
- //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJBREJfU0hFTExfRkVBVFVSRSIsImNvbW1hbmRzIiwibW9iaWxlU2hlbGwiLCJvcHRzIiwiZW5zdXJlRmVhdHVyZUVuYWJsZWQiLCJjb21tYW5kIiwiYXJncyIsInRpbWVvdXQiLCJpbmNsdWRlU3RkZXJyIiwiXyIsImlzU3RyaW5nIiwiZXJyb3JzIiwiSW52YWxpZEFyZ3VtZW50RXJyb3IiLCJhZGJBcmdzIiwiYWRiIiwiZXhlY3V0YWJsZSIsImRlZmF1bHRBcmdzIiwiaXNBcnJheSIsImxvZyIsImRlYnVnIiwicGF0aCIsInV0aWwiLCJxdW90ZSIsInN0ZG91dCIsInN0ZGVyciIsImV4ZWMiLCJlcnIiLCJlcnJvckFuZFRocm93IiwibWVzc2FnZSJdLCJzb3VyY2VzIjpbIi4uLy4uLy4uL2xpYi9jb21tYW5kcy9zaGVsbC5qcyJdLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgXyBmcm9tICdsb2Rhc2gnO1xuaW1wb3J0IHsgZXhlYyB9IGZyb20gJ3RlZW5fcHJvY2Vzcyc7XG5pbXBvcnQgeyB1dGlsIH0gZnJvbSAnYXBwaXVtL3N1cHBvcnQnO1xuaW1wb3J0IHsgZXJyb3JzIH0gZnJvbSAnYXBwaXVtL2RyaXZlcic7XG5cbmNvbnN0IEFEQl9TSEVMTF9GRUFUVVJFID0gJ2FkYl9zaGVsbCc7XG5cbmxldCBjb21tYW5kcyA9IHt9O1xuXG5jb21tYW5kcy5tb2JpbGVTaGVsbCA9IGFzeW5jIGZ1bmN0aW9uIG1vYmlsZVNoZWxsIChvcHRzID0ge30pIHtcbiAgdGhpcy5lbnN1cmVGZWF0dXJlRW5hYmxlZChBREJfU0hFTExfRkVBVFVSRSk7XG5cbiAgY29uc3Qge1xuICAgIGNvbW1hbmQsXG4gICAgYXJncyA9IFtdLFxuICAgIHRpbWVvdXQgPSAyMDAwMCxcbiAgICBpbmNsdWRlU3RkZXJyLFxuICB9ID0gb3B0cztcblxuICBpZiAoIV8uaXNTdHJpbmcoY29tbWFuZCkpIHtcbiAgICB0aHJvdyBuZXcgZXJyb3JzLkludmFsaWRBcmd1bWVudEVycm9yKGBUaGUgJ2NvbW1hbmQnIGFyZ3VtZW50IGlzIG1hbmRhdG9yeWApO1xuICB9XG5cbiAgY29uc3QgYWRiQXJncyA9IFtcbiAgICAuLi50aGlzLmFkYi5leGVjdXRhYmxlLmRlZmF1bHRBcmdzLFxuICAgICdzaGVsbCcsXG4gICAgY29tbWFuZCxcbiAgICAuLi4oXy5pc0FycmF5KGFyZ3MpID8gYXJncyA6IFthcmdzXSlcbiAgXTtcbiAgdGhpcy5sb2cuZGVidWcoYFJ1bm5pbmcgJyR7dGhpcy5hZGIuZXhlY3V0YWJsZS5wYXRofSAke3V0aWwucXVvdGUoYWRiQXJncyl9J2ApO1xuICB0cnkge1xuICAgIGNvbnN0IHtzdGRvdXQsIHN0ZGVycn0gPSBhd2FpdCBleGVjKHRoaXMuYWRiLmV4ZWN1dGFibGUucGF0aCwgYWRiQXJncywge3RpbWVvdXR9KTtcbiAgICBpZiAoaW5jbHVkZVN0ZGVycikge1xuICAgICAgcmV0dXJuIHtcbiAgICAgICAgc3Rkb3V0LFxuICAgICAgICBzdGRlcnJcbiAgICAgIH07XG4gICAgfVxuICAgIHJldHVybiBzdGRvdXQ7XG4gIH0gY2F0Y2ggKGVycikge1xuICAgIHRoaXMubG9nLmVycm9yQW5kVGhyb3coYENhbm5vdCBleGVjdXRlIHRoZSAnJHtjb21tYW5kfScgc2hlbGwgY29tbWFuZC4gYCArXG4gICAgICBgT3JpZ2luYWwgZXJyb3I6ICR7ZXJyLm1lc3NhZ2V9LiBgICtcbiAgICAgIGBTdGRPdXQ6ICR7ZXJyLnN0ZG91dH0uIFN0ZEVycjogJHtlcnIuc3RkZXJyfWApO1xuICB9XG59O1xuXG5leHBvcnQgeyBjb21tYW5kcyB9O1xuZXhwb3J0IGRlZmF1bHQgY29tbWFuZHM7XG4iXSwibWFwcGluZ3MiOiI7Ozs7Ozs7O0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFFQSxNQUFNQSxpQkFBaUIsR0FBRyxXQUFXO0FBRXJDLElBQUlDLFFBQVEsR0FBRyxDQUFDLENBQUM7QUFBQztBQUVsQkEsUUFBUSxDQUFDQyxXQUFXLEdBQUcsZUFBZUEsV0FBVyxDQUFFQyxJQUFJLEdBQUcsQ0FBQyxDQUFDLEVBQUU7RUFDNUQsSUFBSSxDQUFDQyxvQkFBb0IsQ0FBQ0osaUJBQWlCLENBQUM7RUFFNUMsTUFBTTtJQUNKSyxPQUFPO0lBQ1BDLElBQUksR0FBRyxFQUFFO0lBQ1RDLE9BQU8sR0FBRyxLQUFLO0lBQ2ZDO0VBQ0YsQ0FBQyxHQUFHTCxJQUFJO0VBRVIsSUFBSSxDQUFDTSxlQUFDLENBQUNDLFFBQVEsQ0FBQ0wsT0FBTyxDQUFDLEVBQUU7SUFDeEIsTUFBTSxJQUFJTSxjQUFNLENBQUNDLG9CQUFvQixDQUFFLHFDQUFvQyxDQUFDO0VBQzlFO0VBRUEsTUFBTUMsT0FBTyxHQUFHLENBQ2QsR0FBRyxJQUFJLENBQUNDLEdBQUcsQ0FBQ0MsVUFBVSxDQUFDQyxXQUFXLEVBQ2xDLE9BQU8sRUFDUFgsT0FBTyxFQUNQLElBQUlJLGVBQUMsQ0FBQ1EsT0FBTyxDQUFDWCxJQUFJLENBQUMsR0FBR0EsSUFBSSxHQUFHLENBQUNBLElBQUksQ0FBQyxDQUFDLENBQ3JDO0VBQ0QsSUFBSSxDQUFDWSxHQUFHLENBQUNDLEtBQUssQ0FBRSxZQUFXLElBQUksQ0FBQ0wsR0FBRyxDQUFDQyxVQUFVLENBQUNLLElBQUssSUFBR0MsYUFBSSxDQUFDQyxLQUFLLENBQUNULE9BQU8sQ0FBRSxHQUFFLENBQUM7RUFDOUUsSUFBSTtJQUNGLE1BQU07TUFBQ1UsTUFBTTtNQUFFQztJQUFNLENBQUMsR0FBRyxNQUFNLElBQUFDLGtCQUFJLEVBQUMsSUFBSSxDQUFDWCxHQUFHLENBQUNDLFVBQVUsQ0FBQ0ssSUFBSSxFQUFFUCxPQUFPLEVBQUU7TUFBQ047SUFBTyxDQUFDLENBQUM7SUFDakYsSUFBSUMsYUFBYSxFQUFFO01BQ2pCLE9BQU87UUFDTGUsTUFBTTtRQUNOQztNQUNGLENBQUM7SUFDSDtJQUNBLE9BQU9ELE1BQU07RUFDZixDQUFDLENBQUMsT0FBT0csR0FBRyxFQUFFO0lBQ1osSUFBSSxDQUFDUixHQUFHLENBQUNTLGFBQWEsQ0FBRSx1QkFBc0J0QixPQUFRLG1CQUFrQixHQUNyRSxtQkFBa0JxQixHQUFHLENBQUNFLE9BQVEsSUFBRyxHQUNqQyxXQUFVRixHQUFHLENBQUNILE1BQU8sYUFBWUcsR0FBRyxDQUFDRixNQUFPLEVBQUMsQ0FBQztFQUNuRDtBQUNGLENBQUM7QUFBQyxlQUdhdkIsUUFBUTtBQUFBIn0=
49
+ //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJBREJfU0hFTExfRkVBVFVSRSIsImNvbW1hbmRzIiwibW9iaWxlU2hlbGwiLCJvcHRzIiwiZW5zdXJlRmVhdHVyZUVuYWJsZWQiLCJjb21tYW5kIiwiYXJncyIsInRpbWVvdXQiLCJpbmNsdWRlU3RkZXJyIiwiXyIsImlzU3RyaW5nIiwiZXJyb3JzIiwiSW52YWxpZEFyZ3VtZW50RXJyb3IiLCJhZGJBcmdzIiwiYWRiIiwiZXhlY3V0YWJsZSIsImRlZmF1bHRBcmdzIiwiaXNBcnJheSIsImxvZyIsImRlYnVnIiwicGF0aCIsInV0aWwiLCJxdW90ZSIsInN0ZG91dCIsInN0ZGVyciIsImV4ZWMiLCJlcnIiLCJlcnJvckFuZFRocm93IiwibWVzc2FnZSJdLCJzb3VyY2VzIjpbIi4uLy4uLy4uL2xpYi9jb21tYW5kcy9zaGVsbC5qcyJdLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgXyBmcm9tICdsb2Rhc2gnO1xuaW1wb3J0IHsgZXhlYyB9IGZyb20gJ3RlZW5fcHJvY2Vzcyc7XG5pbXBvcnQgeyB1dGlsIH0gZnJvbSAnQGFwcGl1bS9zdXBwb3J0JztcbmltcG9ydCB7IGVycm9ycyB9IGZyb20gJ2FwcGl1bS9kcml2ZXInO1xuXG5jb25zdCBBREJfU0hFTExfRkVBVFVSRSA9ICdhZGJfc2hlbGwnO1xuXG5sZXQgY29tbWFuZHMgPSB7fTtcblxuY29tbWFuZHMubW9iaWxlU2hlbGwgPSBhc3luYyBmdW5jdGlvbiBtb2JpbGVTaGVsbCAob3B0cyA9IHt9KSB7XG4gIHRoaXMuZW5zdXJlRmVhdHVyZUVuYWJsZWQoQURCX1NIRUxMX0ZFQVRVUkUpO1xuXG4gIGNvbnN0IHtcbiAgICBjb21tYW5kLFxuICAgIGFyZ3MgPSBbXSxcbiAgICB0aW1lb3V0ID0gMjAwMDAsXG4gICAgaW5jbHVkZVN0ZGVycixcbiAgfSA9IG9wdHM7XG5cbiAgaWYgKCFfLmlzU3RyaW5nKGNvbW1hbmQpKSB7XG4gICAgdGhyb3cgbmV3IGVycm9ycy5JbnZhbGlkQXJndW1lbnRFcnJvcihgVGhlICdjb21tYW5kJyBhcmd1bWVudCBpcyBtYW5kYXRvcnlgKTtcbiAgfVxuXG4gIGNvbnN0IGFkYkFyZ3MgPSBbXG4gICAgLi4udGhpcy5hZGIuZXhlY3V0YWJsZS5kZWZhdWx0QXJncyxcbiAgICAnc2hlbGwnLFxuICAgIGNvbW1hbmQsXG4gICAgLi4uKF8uaXNBcnJheShhcmdzKSA/IGFyZ3MgOiBbYXJnc10pXG4gIF07XG4gIHRoaXMubG9nLmRlYnVnKGBSdW5uaW5nICcke3RoaXMuYWRiLmV4ZWN1dGFibGUucGF0aH0gJHt1dGlsLnF1b3RlKGFkYkFyZ3MpfSdgKTtcbiAgdHJ5IHtcbiAgICBjb25zdCB7c3Rkb3V0LCBzdGRlcnJ9ID0gYXdhaXQgZXhlYyh0aGlzLmFkYi5leGVjdXRhYmxlLnBhdGgsIGFkYkFyZ3MsIHt0aW1lb3V0fSk7XG4gICAgaWYgKGluY2x1ZGVTdGRlcnIpIHtcbiAgICAgIHJldHVybiB7XG4gICAgICAgIHN0ZG91dCxcbiAgICAgICAgc3RkZXJyXG4gICAgICB9O1xuICAgIH1cbiAgICByZXR1cm4gc3Rkb3V0O1xuICB9IGNhdGNoIChlcnIpIHtcbiAgICB0aGlzLmxvZy5lcnJvckFuZFRocm93KGBDYW5ub3QgZXhlY3V0ZSB0aGUgJyR7Y29tbWFuZH0nIHNoZWxsIGNvbW1hbmQuIGAgK1xuICAgICAgYE9yaWdpbmFsIGVycm9yOiAke2Vyci5tZXNzYWdlfS4gYCArXG4gICAgICBgU3RkT3V0OiAke2Vyci5zdGRvdXR9LiBTdGRFcnI6ICR7ZXJyLnN0ZGVycn1gKTtcbiAgfVxufTtcblxuZXhwb3J0IHsgY29tbWFuZHMgfTtcbmV4cG9ydCBkZWZhdWx0IGNvbW1hbmRzO1xuIl0sIm1hcHBpbmdzIjoiOzs7Ozs7OztBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBRUEsTUFBTUEsaUJBQWlCLEdBQUcsV0FBVztBQUVyQyxJQUFJQyxRQUFRLEdBQUcsQ0FBQyxDQUFDO0FBQUM7QUFFbEJBLFFBQVEsQ0FBQ0MsV0FBVyxHQUFHLGVBQWVBLFdBQVcsQ0FBRUMsSUFBSSxHQUFHLENBQUMsQ0FBQyxFQUFFO0VBQzVELElBQUksQ0FBQ0Msb0JBQW9CLENBQUNKLGlCQUFpQixDQUFDO0VBRTVDLE1BQU07SUFDSkssT0FBTztJQUNQQyxJQUFJLEdBQUcsRUFBRTtJQUNUQyxPQUFPLEdBQUcsS0FBSztJQUNmQztFQUNGLENBQUMsR0FBR0wsSUFBSTtFQUVSLElBQUksQ0FBQ00sZUFBQyxDQUFDQyxRQUFRLENBQUNMLE9BQU8sQ0FBQyxFQUFFO0lBQ3hCLE1BQU0sSUFBSU0sY0FBTSxDQUFDQyxvQkFBb0IsQ0FBRSxxQ0FBb0MsQ0FBQztFQUM5RTtFQUVBLE1BQU1DLE9BQU8sR0FBRyxDQUNkLEdBQUcsSUFBSSxDQUFDQyxHQUFHLENBQUNDLFVBQVUsQ0FBQ0MsV0FBVyxFQUNsQyxPQUFPLEVBQ1BYLE9BQU8sRUFDUCxJQUFJSSxlQUFDLENBQUNRLE9BQU8sQ0FBQ1gsSUFBSSxDQUFDLEdBQUdBLElBQUksR0FBRyxDQUFDQSxJQUFJLENBQUMsQ0FBQyxDQUNyQztFQUNELElBQUksQ0FBQ1ksR0FBRyxDQUFDQyxLQUFLLENBQUUsWUFBVyxJQUFJLENBQUNMLEdBQUcsQ0FBQ0MsVUFBVSxDQUFDSyxJQUFLLElBQUdDLGFBQUksQ0FBQ0MsS0FBSyxDQUFDVCxPQUFPLENBQUUsR0FBRSxDQUFDO0VBQzlFLElBQUk7SUFDRixNQUFNO01BQUNVLE1BQU07TUFBRUM7SUFBTSxDQUFDLEdBQUcsTUFBTSxJQUFBQyxrQkFBSSxFQUFDLElBQUksQ0FBQ1gsR0FBRyxDQUFDQyxVQUFVLENBQUNLLElBQUksRUFBRVAsT0FBTyxFQUFFO01BQUNOO0lBQU8sQ0FBQyxDQUFDO0lBQ2pGLElBQUlDLGFBQWEsRUFBRTtNQUNqQixPQUFPO1FBQ0xlLE1BQU07UUFDTkM7TUFDRixDQUFDO0lBQ0g7SUFDQSxPQUFPRCxNQUFNO0VBQ2YsQ0FBQyxDQUFDLE9BQU9HLEdBQUcsRUFBRTtJQUNaLElBQUksQ0FBQ1IsR0FBRyxDQUFDUyxhQUFhLENBQUUsdUJBQXNCdEIsT0FBUSxtQkFBa0IsR0FDckUsbUJBQWtCcUIsR0FBRyxDQUFDRSxPQUFRLElBQUcsR0FDakMsV0FBVUYsR0FBRyxDQUFDSCxNQUFPLGFBQVlHLEdBQUcsQ0FBQ0YsTUFBTyxFQUFDLENBQUM7RUFDbkQ7QUFDRixDQUFDO0FBQUMsZUFHYXZCLFFBQVE7QUFBQSJ9
@@ -1 +1 @@
1
- {"version":3,"file":"shell.js","names":["ADB_SHELL_FEATURE","commands","mobileShell","opts","ensureFeatureEnabled","command","args","timeout","includeStderr","_","isString","errors","InvalidArgumentError","adbArgs","adb","executable","defaultArgs","isArray","log","debug","path","util","quote","stdout","stderr","exec","err","errorAndThrow","message"],"sources":["../../../lib/commands/shell.js"],"sourcesContent":["import _ from 'lodash';\nimport { exec } from 'teen_process';\nimport { util } from 'appium/support';\nimport { errors } from 'appium/driver';\n\nconst ADB_SHELL_FEATURE = 'adb_shell';\n\nlet commands = {};\n\ncommands.mobileShell = async function mobileShell (opts = {}) {\n this.ensureFeatureEnabled(ADB_SHELL_FEATURE);\n\n const {\n command,\n args = [],\n timeout = 20000,\n includeStderr,\n } = opts;\n\n if (!_.isString(command)) {\n throw new errors.InvalidArgumentError(`The 'command' argument is mandatory`);\n }\n\n const adbArgs = [\n ...this.adb.executable.defaultArgs,\n 'shell',\n command,\n ...(_.isArray(args) ? args : [args])\n ];\n this.log.debug(`Running '${this.adb.executable.path} ${util.quote(adbArgs)}'`);\n try {\n const {stdout, stderr} = await exec(this.adb.executable.path, adbArgs, {timeout});\n if (includeStderr) {\n return {\n stdout,\n stderr\n };\n }\n return stdout;\n } catch (err) {\n this.log.errorAndThrow(`Cannot execute the '${command}' shell command. ` +\n `Original error: ${err.message}. ` +\n `StdOut: ${err.stdout}. StdErr: ${err.stderr}`);\n }\n};\n\nexport { commands };\nexport default commands;\n"],"mappings":";;;;;;;;AAAA;AACA;AACA;AACA;AAEA,MAAMA,iBAAiB,GAAG,WAAW;AAErC,IAAIC,QAAQ,GAAG,CAAC,CAAC;AAAC;AAElBA,QAAQ,CAACC,WAAW,GAAG,eAAeA,WAAW,CAAEC,IAAI,GAAG,CAAC,CAAC,EAAE;EAC5D,IAAI,CAACC,oBAAoB,CAACJ,iBAAiB,CAAC;EAE5C,MAAM;IACJK,OAAO;IACPC,IAAI,GAAG,EAAE;IACTC,OAAO,GAAG,KAAK;IACfC;EACF,CAAC,GAAGL,IAAI;EAER,IAAI,CAACM,eAAC,CAACC,QAAQ,CAACL,OAAO,CAAC,EAAE;IACxB,MAAM,IAAIM,cAAM,CAACC,oBAAoB,CAAE,qCAAoC,CAAC;EAC9E;EAEA,MAAMC,OAAO,GAAG,CACd,GAAG,IAAI,CAACC,GAAG,CAACC,UAAU,CAACC,WAAW,EAClC,OAAO,EACPX,OAAO,EACP,IAAII,eAAC,CAACQ,OAAO,CAACX,IAAI,CAAC,GAAGA,IAAI,GAAG,CAACA,IAAI,CAAC,CAAC,CACrC;EACD,IAAI,CAACY,GAAG,CAACC,KAAK,CAAE,YAAW,IAAI,CAACL,GAAG,CAACC,UAAU,CAACK,IAAK,IAAGC,aAAI,CAACC,KAAK,CAACT,OAAO,CAAE,GAAE,CAAC;EAC9E,IAAI;IACF,MAAM;MAACU,MAAM;MAAEC;IAAM,CAAC,GAAG,MAAM,IAAAC,kBAAI,EAAC,IAAI,CAACX,GAAG,CAACC,UAAU,CAACK,IAAI,EAAEP,OAAO,EAAE;MAACN;IAAO,CAAC,CAAC;IACjF,IAAIC,aAAa,EAAE;MACjB,OAAO;QACLe,MAAM;QACNC;MACF,CAAC;IACH;IACA,OAAOD,MAAM;EACf,CAAC,CAAC,OAAOG,GAAG,EAAE;IACZ,IAAI,CAACR,GAAG,CAACS,aAAa,CAAE,uBAAsBtB,OAAQ,mBAAkB,GACrE,mBAAkBqB,GAAG,CAACE,OAAQ,IAAG,GACjC,WAAUF,GAAG,CAACH,MAAO,aAAYG,GAAG,CAACF,MAAO,EAAC,CAAC;EACnD;AACF,CAAC;AAAC,eAGavB,QAAQ;AAAA"}
1
+ {"version":3,"file":"shell.js","names":["ADB_SHELL_FEATURE","commands","mobileShell","opts","ensureFeatureEnabled","command","args","timeout","includeStderr","_","isString","errors","InvalidArgumentError","adbArgs","adb","executable","defaultArgs","isArray","log","debug","path","util","quote","stdout","stderr","exec","err","errorAndThrow","message"],"sources":["../../../lib/commands/shell.js"],"sourcesContent":["import _ from 'lodash';\nimport { exec } from 'teen_process';\nimport { util } from '@appium/support';\nimport { errors } from 'appium/driver';\n\nconst ADB_SHELL_FEATURE = 'adb_shell';\n\nlet commands = {};\n\ncommands.mobileShell = async function mobileShell (opts = {}) {\n this.ensureFeatureEnabled(ADB_SHELL_FEATURE);\n\n const {\n command,\n args = [],\n timeout = 20000,\n includeStderr,\n } = opts;\n\n if (!_.isString(command)) {\n throw new errors.InvalidArgumentError(`The 'command' argument is mandatory`);\n }\n\n const adbArgs = [\n ...this.adb.executable.defaultArgs,\n 'shell',\n command,\n ...(_.isArray(args) ? args : [args])\n ];\n this.log.debug(`Running '${this.adb.executable.path} ${util.quote(adbArgs)}'`);\n try {\n const {stdout, stderr} = await exec(this.adb.executable.path, adbArgs, {timeout});\n if (includeStderr) {\n return {\n stdout,\n stderr\n };\n }\n return stdout;\n } catch (err) {\n this.log.errorAndThrow(`Cannot execute the '${command}' shell command. ` +\n `Original error: ${err.message}. ` +\n `StdOut: ${err.stdout}. StdErr: ${err.stderr}`);\n }\n};\n\nexport { commands };\nexport default commands;\n"],"mappings":";;;;;;;;AAAA;AACA;AACA;AACA;AAEA,MAAMA,iBAAiB,GAAG,WAAW;AAErC,IAAIC,QAAQ,GAAG,CAAC,CAAC;AAAC;AAElBA,QAAQ,CAACC,WAAW,GAAG,eAAeA,WAAW,CAAEC,IAAI,GAAG,CAAC,CAAC,EAAE;EAC5D,IAAI,CAACC,oBAAoB,CAACJ,iBAAiB,CAAC;EAE5C,MAAM;IACJK,OAAO;IACPC,IAAI,GAAG,EAAE;IACTC,OAAO,GAAG,KAAK;IACfC;EACF,CAAC,GAAGL,IAAI;EAER,IAAI,CAACM,eAAC,CAACC,QAAQ,CAACL,OAAO,CAAC,EAAE;IACxB,MAAM,IAAIM,cAAM,CAACC,oBAAoB,CAAE,qCAAoC,CAAC;EAC9E;EAEA,MAAMC,OAAO,GAAG,CACd,GAAG,IAAI,CAACC,GAAG,CAACC,UAAU,CAACC,WAAW,EAClC,OAAO,EACPX,OAAO,EACP,IAAII,eAAC,CAACQ,OAAO,CAACX,IAAI,CAAC,GAAGA,IAAI,GAAG,CAACA,IAAI,CAAC,CAAC,CACrC;EACD,IAAI,CAACY,GAAG,CAACC,KAAK,CAAE,YAAW,IAAI,CAACL,GAAG,CAACC,UAAU,CAACK,IAAK,IAAGC,aAAI,CAACC,KAAK,CAACT,OAAO,CAAE,GAAE,CAAC;EAC9E,IAAI;IACF,MAAM;MAACU,MAAM;MAAEC;IAAM,CAAC,GAAG,MAAM,IAAAC,kBAAI,EAAC,IAAI,CAACX,GAAG,CAACC,UAAU,CAACK,IAAI,EAAEP,OAAO,EAAE;MAACN;IAAO,CAAC,CAAC;IACjF,IAAIC,aAAa,EAAE;MACjB,OAAO;QACLe,MAAM;QACNC;MACF,CAAC;IACH;IACA,OAAOD,MAAM;EACf,CAAC,CAAC,OAAOG,GAAG,EAAE;IACZ,IAAI,CAACR,GAAG,CAACS,aAAa,CAAE,uBAAsBtB,OAAQ,mBAAkB,GACrE,mBAAkBqB,GAAG,CAACE,OAAQ,IAAG,GACjC,WAAUF,GAAG,CAACH,MAAO,aAAYG,GAAG,CAACF,MAAO,EAAC,CAAC;EACnD;AACF,CAAC;AAAC,eAGavB,QAAQ;AAAA"}
@@ -7,7 +7,7 @@ Object.defineProperty(exports, "__esModule", {
7
7
  exports.default = void 0;
8
8
  require("source-map-support/register");
9
9
  var _lodash = _interopRequireDefault(require("lodash"));
10
- var _support = require("appium/support");
10
+ var _support = require("@appium/support");
11
11
  var _teen_process = require("teen_process");
12
12
  var _portscanner = require("portscanner");
13
13
  var _http = _interopRequireDefault(require("http"));
@@ -351,4 +351,4 @@ commands.mobileStopScreenStreaming = async function mobileStopScreenStreaming(
351
351
  };
352
352
  var _default = commands;
353
353
  exports.default = _default;
354
- //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJjb21tYW5kcyIsIlJFQ09SRElOR19JTlRFUlZBTF9TRUMiLCJTVFJFQU1JTkdfU1RBUlRVUF9USU1FT1VUX01TIiwiR1NUUkVBTUVSX0JJTkFSWSIsInN5c3RlbSIsImlzV2luZG93cyIsIkdTVF9JTlNQRUNUX0JJTkFSWSIsIlJFUVVJUkVEX0dTVF9QTFVHSU5TIiwiYXZkZWNfaDI2NCIsImgyNjRwYXJzZSIsImpwZWdlbmMiLCJ0Y3BzZXJ2ZXJzaW5rIiwibXVsdGlwYXJ0bXV4IiwiU0NSRUVOUkVDT1JEX0JJTkFSWSIsIkdTVF9UVVRPUklBTF9VUkwiLCJERUZBVUxUX0hPU1QiLCJUQ1BfSE9TVCIsIkRFRkFVTFRfUE9SVCIsIkRFRkFVTFRfUVVBTElUWSIsIkRFRkFVTFRfQklUUkFURSIsIkJPVU5EQVJZX1NUUklORyIsIkFEQl9TQ1JFRU5fU1RSRUFNSU5HX0ZFQVRVUkUiLCJjcmVhdGVTdHJlYW1pbmdMb2dnZXIiLCJzdHJlYW1OYW1lIiwidWRpZCIsImxvZ2dlciIsImdldExvZ2dlciIsIl8iLCJ0cnVuY2F0ZSIsImxlbmd0aCIsIm9taXNzaW9uIiwidmVyaWZ5U3RyZWFtaW5nUmVxdWlyZW1lbnRzIiwiYWRiIiwidHJpbSIsInNoZWxsIiwiRXJyb3IiLCJnc3RyZWFtZXJDaGVja1Byb21pc2VzIiwiYmluYXJ5TmFtZSIsInB1c2giLCJmcyIsIndoaWNoIiwiZSIsIkIiLCJhbGwiLCJtb2R1bGVDaGVja1Byb21pc2VzIiwibmFtZSIsIm1vZE5hbWUiLCJ0b1BhaXJzIiwic3Rkb3V0IiwiZXhlYyIsImluY2x1ZGVzIiwiZ2V0RGV2aWNlSW5mbyIsImxvZyIsIm91dHB1dCIsInJlc3VsdCIsImtleSIsInBhdHRlcm4iLCJtYXRjaCIsImRlYnVnIiwicGFyc2VJbnQiLCJjdXJEZXZpY2VJZCIsImluaXREZXZpY2VTdHJlYW1pbmdQcm9jIiwiZGV2aWNlSW5mbyIsIm9wdHMiLCJ3aWR0aCIsImhlaWdodCIsImJpdFJhdGUiLCJhZGp1c3RlZFdpZHRoIiwiYWRqdXN0ZWRIZWlnaHQiLCJhZGp1c3RlZEJpdHJhdGUiLCJzY3JlZW5SZWNvcmRDbWQiLCJhZGJBcmdzIiwiZXhlY3V0YWJsZSIsImRlZmF1bHRBcmdzIiwiZGV2aWNlU3RyZWFtaW5nIiwic3Bhd24iLCJwYXRoIiwib24iLCJjb2RlIiwic2lnbmFsIiwiaXNTdGFydGVkIiwiZGV2aWNlU3RyZWFtaW5nTG9nZ2VyIiwiZXJyb3JzTGlzdGVuZXIiLCJjaHVuayIsInN0ZGVyciIsInRvU3RyaW5nIiwic3RhcnR1cExpc3RlbmVyIiwiaXNFbXB0eSIsImluZm8iLCJ1dGlsIiwicXVvdGUiLCJ3YWl0Rm9yQ29uZGl0aW9uIiwid2FpdE1zIiwiaW50ZXJ2YWxNcyIsImVycm9yQW5kVGhyb3ciLCJtZXNzYWdlIiwicmVtb3ZlTGlzdGVuZXIiLCJpbml0R3N0cmVhbWVyUGlwZWxpbmUiLCJkZXZpY2VTdHJlYW1pbmdQcm9jIiwicXVhbGl0eSIsInRjcFBvcnQiLCJjb25zaWRlclJvdGF0aW9uIiwibG9nUGlwZWxpbmVEZXRhaWxzIiwiZ3N0cmVhbWVyUGlwZWxpbmUiLCJTdWJQcm9jZXNzIiwiTWF0aCIsIm1heCIsImZwcyIsInN0ZGlvIiwiZ3N0cmVhbWVyTG9nZ2VyIiwiZ3N0T3V0cHV0TGlzdGVuZXIiLCJkaWRGYWlsIiwicmVwIiwic3RhcnQiLCJjaGVja1BvcnRTdGF0dXMiLCJpZ24iLCJleHRyYWN0UmVtb3RlQWRkcmVzcyIsInJlcSIsImhlYWRlcnMiLCJzb2NrZXQiLCJyZW1vdGVBZGRyZXNzIiwiY29ubmVjdGlvbiIsIm1vYmlsZVN0YXJ0U2NyZWVuU3RyZWFtaW5nIiwib3B0aW9ucyIsImVuc3VyZUZlYXR1cmVFbmFibGVkIiwiaG9zdCIsInBvcnQiLCJwYXRobmFtZSIsImlzVW5kZWZpbmVkIiwiX3NjcmVlblN0cmVhbWluZ1Byb3BzIiwia2lsbCIsIm1qcGVnU29ja2V0IiwibWpwZWdTZXJ2ZXIiLCJyZXNvbHZlIiwicmVqZWN0IiwibmV0IiwiY3JlYXRlQ29ubmVjdGlvbiIsImh0dHAiLCJjcmVhdGVTZXJ2ZXIiLCJyZXMiLCJjdXJyZW50UGF0aG5hbWUiLCJ1cmwiLCJwYXJzZSIsIndyaXRlSGVhZCIsIkNvbm5lY3Rpb24iLCJ3cml0ZSIsImVuZCIsIlByYWdtYSIsInBpcGUiLCJ3YXJuIiwibGlzdGVuIiwiZXJyb3IiLCJ0aW1lb3V0IiwiaXNSdW5uaW5nIiwic3RvcCIsImRlc3Ryb3kiLCJsaXN0ZW5pbmciLCJjbG9zZSIsIm1vYmlsZVN0b3BTY3JlZW5TdHJlYW1pbmciLCJlMSJdLCJzb3VyY2VzIjpbIi4uLy4uLy4uL2xpYi9jb21tYW5kcy9zdHJlYW1zY3JlZW4uanMiXSwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IF8gZnJvbSAnbG9kYXNoJztcbmltcG9ydCB7IGZzLCBzeXN0ZW0sIGxvZ2dlciwgdXRpbCB9IGZyb20gJ2FwcGl1bS9zdXBwb3J0JztcbmltcG9ydCB7IGV4ZWMsIFN1YlByb2Nlc3MgfSBmcm9tICd0ZWVuX3Byb2Nlc3MnO1xuaW1wb3J0IHsgY2hlY2tQb3J0U3RhdHVzIH0gZnJvbSAncG9ydHNjYW5uZXInO1xuaW1wb3J0IGh0dHAgZnJvbSAnaHR0cCc7XG5pbXBvcnQgbmV0IGZyb20gJ25ldCc7XG5pbXBvcnQgQiBmcm9tICdibHVlYmlyZCc7XG5pbXBvcnQgeyB3YWl0Rm9yQ29uZGl0aW9uIH0gZnJvbSAnYXN5bmNib3gnO1xuaW1wb3J0IHsgc3Bhd24gfSBmcm9tICdjaGlsZF9wcm9jZXNzJztcbmltcG9ydCB1cmwgZnJvbSAndXJsJztcblxuY29uc3QgY29tbWFuZHMgPSB7fTtcblxuY29uc3QgUkVDT1JESU5HX0lOVEVSVkFMX1NFQyA9IDU7XG5jb25zdCBTVFJFQU1JTkdfU1RBUlRVUF9USU1FT1VUX01TID0gNTAwMDtcbmNvbnN0IEdTVFJFQU1FUl9CSU5BUlkgPSBgZ3N0LWxhdW5jaC0xLjAke3N5c3RlbS5pc1dpbmRvd3MoKSA/ICcuZXhlJyA6ICcnfWA7XG5jb25zdCBHU1RfSU5TUEVDVF9CSU5BUlkgPSBgZ3N0LWluc3BlY3QtMS4wJHtzeXN0ZW0uaXNXaW5kb3dzKCkgPyAnLmV4ZScgOiAnJ31gO1xuY29uc3QgUkVRVUlSRURfR1NUX1BMVUdJTlMgPSB7XG4gIGF2ZGVjX2gyNjQ6ICdnc3QtbGliYXYnLFxuICBoMjY0cGFyc2U6ICdnc3QtcGx1Z2lucy1iYWQnLFxuICBqcGVnZW5jOiAnZ3N0LXBsdWdpbnMtZ29vZCcsXG4gIHRjcHNlcnZlcnNpbms6ICdnc3QtcGx1Z2lucy1iYXNlJyxcbiAgbXVsdGlwYXJ0bXV4OiAnZ3N0LXBsdWdpbnMtZ29vZCcsXG59O1xuY29uc3QgU0NSRUVOUkVDT1JEX0JJTkFSWSA9ICdzY3JlZW5yZWNvcmQnO1xuY29uc3QgR1NUX1RVVE9SSUFMX1VSTCA9ICdodHRwczovL2dzdHJlYW1lci5mcmVlZGVza3RvcC5vcmcvZG9jdW1lbnRhdGlvbi9pbnN0YWxsaW5nL2luZGV4Lmh0bWwnO1xuY29uc3QgREVGQVVMVF9IT1NUID0gJzEyNy4wLjAuMSc7XG5jb25zdCBUQ1BfSE9TVCA9ICcxMjcuMC4wLjEnO1xuY29uc3QgREVGQVVMVF9QT1JUID0gODA5MztcbmNvbnN0IERFRkFVTFRfUVVBTElUWSA9IDcwO1xuY29uc3QgREVGQVVMVF9CSVRSQVRFID0gNDAwMDAwMDsgLy8gNCBNYnBzXG5jb25zdCBCT1VOREFSWV9TVFJJTkcgPSAnLS0yYWU5NzQ2ODg3ZjE3MGI4Y2Y3YzI3MTA0N2NlMzE0Yyc7XG5cbmNvbnN0IEFEQl9TQ1JFRU5fU1RSRUFNSU5HX0ZFQVRVUkUgPSAnYWRiX3NjcmVlbl9zdHJlYW1pbmcnO1xuXG5mdW5jdGlvbiBjcmVhdGVTdHJlYW1pbmdMb2dnZXIgKHN0cmVhbU5hbWUsIHVkaWQpIHtcbiAgcmV0dXJuIGxvZ2dlci5nZXRMb2dnZXIoYCR7c3RyZWFtTmFtZX1AYCArIF8udHJ1bmNhdGUodWRpZCwge1xuICAgIGxlbmd0aDogOCxcbiAgICBvbWlzc2lvbjogJycsXG4gIH0pKTtcbn1cblxuYXN5bmMgZnVuY3Rpb24gdmVyaWZ5U3RyZWFtaW5nUmVxdWlyZW1lbnRzIChhZGIpIHtcbiAgaWYgKCFfLnRyaW0oYXdhaXQgYWRiLnNoZWxsKFsnd2hpY2gnLCBTQ1JFRU5SRUNPUkRfQklOQVJZXSkpKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKFxuICAgICAgYFRoZSByZXF1aXJlZCAnJHtTQ1JFRU5SRUNPUkRfQklOQVJZfScgYmluYXJ5IGlzIG5vdCBhdmFpbGFibGUgb24gdGhlIGRldmljZSB1bmRlciB0ZXN0YCk7XG4gIH1cblxuICBjb25zdCBnc3RyZWFtZXJDaGVja1Byb21pc2VzID0gW107XG4gIGZvciAoY29uc3QgYmluYXJ5TmFtZSBvZiBbR1NUUkVBTUVSX0JJTkFSWSwgR1NUX0lOU1BFQ1RfQklOQVJZXSkge1xuICAgIGdzdHJlYW1lckNoZWNrUHJvbWlzZXMucHVzaCgoYXN5bmMgKCkgPT4ge1xuICAgICAgdHJ5IHtcbiAgICAgICAgYXdhaXQgZnMud2hpY2goYmluYXJ5TmFtZSk7XG4gICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihgVGhlICcke2JpbmFyeU5hbWV9JyBiaW5hcnkgaXMgbm90IGF2YWlsYWJsZSBpbiB0aGUgUEFUSCBvbiB0aGUgaG9zdCBzeXN0ZW0uIGAgK1xuICAgICAgICAgIGBTZWUgJHtHU1RfVFVUT1JJQUxfVVJMfSBmb3IgbW9yZSBkZXRhaWxzIG9uIGhvdyB0byBpbnN0YWxsIGl0LmApO1xuICAgICAgfVxuICAgIH0pKCkpO1xuICB9XG4gIGF3YWl0IEIuYWxsKGdzdHJlYW1lckNoZWNrUHJvbWlzZXMpO1xuXG4gIGNvbnN0IG1vZHVsZUNoZWNrUHJvbWlzZXMgPSBbXTtcbiAgZm9yIChjb25zdCBbbmFtZSwgbW9kTmFtZV0gb2YgXy50b1BhaXJzKFJFUVVJUkVEX0dTVF9QTFVHSU5TKSkge1xuICAgIG1vZHVsZUNoZWNrUHJvbWlzZXMucHVzaCgoYXN5bmMgKCkgPT4ge1xuICAgICAgY29uc3Qge3N0ZG91dH0gPSBhd2FpdCBleGVjKEdTVF9JTlNQRUNUX0JJTkFSWSwgW25hbWVdKTtcbiAgICAgIGlmICghXy5pbmNsdWRlcyhzdGRvdXQsIG1vZE5hbWUpKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgICAgICBgVGhlIHJlcXVpcmVkIEdTdHJlYW1lciBwbHVnaW4gJyR7bmFtZX0nIGZyb20gJyR7bW9kTmFtZX0nIG1vZHVsZSBpcyBub3QgaW5zdGFsbGVkLiBgICtcbiAgICAgICAgICBgU2VlICR7R1NUX1RVVE9SSUFMX1VSTH0gZm9yIG1vcmUgZGV0YWlscyBvbiBob3cgdG8gaW5zdGFsbCBpdC5gKTtcbiAgICAgIH1cbiAgICB9KSgpKTtcbiAgfVxuICBhd2FpdCBCLmFsbChtb2R1bGVDaGVja1Byb21pc2VzKTtcbn1cblxuYXN5bmMgZnVuY3Rpb24gZ2V0RGV2aWNlSW5mbyAoYWRiLCBsb2cgPSBudWxsKSB7XG4gIGNvbnN0IG91dHB1dCA9IGF3YWl0IGFkYi5zaGVsbChbJ2R1bXBzeXMnLCAnZGlzcGxheSddKTtcbiAgY29uc3QgcmVzdWx0ID0ge307XG4gIGZvciAoY29uc3QgW2tleSwgcGF0dGVybl0gb2YgW1xuICAgIFsnd2lkdGgnLCAvXFxiZGV2aWNlV2lkdGg9KFxcZCspL10sXG4gICAgWydoZWlnaHQnLCAvXFxiZGV2aWNlSGVpZ2h0PShcXGQrKS9dLFxuICAgIFsnZnBzJywgL1xcYmZwcz0oXFxkKykvXSxcbiAgXSkge1xuICAgIGNvbnN0IG1hdGNoID0gcGF0dGVybi5leGVjKG91dHB1dCk7XG4gICAgaWYgKCFtYXRjaCkge1xuICAgICAgbG9nPy5kZWJ1ZyhvdXRwdXQpO1xuICAgICAgdGhyb3cgbmV3IEVycm9yKGBDYW5ub3QgcGFyc2UgdGhlIGRldmljZSAke2tleX0gZnJvbSB0aGUgYWRiIGNvbW1hbmQgb3V0cHV0LiBgICtcbiAgICAgICAgYENoZWNrIHRoZSBzZXJ2ZXIgbG9nIGZvciBtb3JlIGRldGFpbHMuYCk7XG4gICAgfVxuICAgIHJlc3VsdFtrZXldID0gcGFyc2VJbnQobWF0Y2hbMV0sIDEwKTtcbiAgfVxuICByZXN1bHQudWRpZCA9IGFkYi5jdXJEZXZpY2VJZDtcbiAgcmV0dXJuIHJlc3VsdDtcbn1cblxuYXN5bmMgZnVuY3Rpb24gaW5pdERldmljZVN0cmVhbWluZ1Byb2MgKGFkYiwgbG9nLCBkZXZpY2VJbmZvLCBvcHRzID0ge30pIHtcbiAgY29uc3Qge1xuICAgIHdpZHRoLFxuICAgIGhlaWdodCxcbiAgICBiaXRSYXRlLFxuICB9ID0gb3B0cztcbiAgY29uc3QgYWRqdXN0ZWRXaWR0aCA9IHBhcnNlSW50KHdpZHRoLCAxMCkgfHwgZGV2aWNlSW5mby53aWR0aDtcbiAgY29uc3QgYWRqdXN0ZWRIZWlnaHQgPSBwYXJzZUludChoZWlnaHQsIDEwKSB8fCBkZXZpY2VJbmZvLmhlaWdodDtcbiAgY29uc3QgYWRqdXN0ZWRCaXRyYXRlID0gcGFyc2VJbnQoYml0UmF0ZSwgMTApIHx8IERFRkFVTFRfQklUUkFURTtcbiAgbGV0IHNjcmVlblJlY29yZENtZCA9IFNDUkVFTlJFQ09SRF9CSU5BUlkgK1xuICAgIGAgLS1vdXRwdXQtZm9ybWF0PWgyNjRgICtcbiAgICAvLyA1IHNlY29uZHMgaXMgZmluZSB0byBkZXRlY3Qgcm90YXRpb24gY2hhbmdlc1xuICAgIGAgLS10aW1lLWxpbWl0PSR7UkVDT1JESU5HX0lOVEVSVkFMX1NFQ31gO1xuICBpZiAod2lkdGggfHwgaGVpZ2h0KSB7XG4gICAgc2NyZWVuUmVjb3JkQ21kICs9IGAgLS1zaXplPSR7YWRqdXN0ZWRXaWR0aH14JHthZGp1c3RlZEhlaWdodH1gO1xuICB9XG4gIGlmIChiaXRSYXRlKSB7XG4gICAgc2NyZWVuUmVjb3JkQ21kICs9IGAgLS1iaXQtcmF0ZT0ke2FkanVzdGVkQml0cmF0ZX1gO1xuICB9XG4gIGNvbnN0IGFkYkFyZ3MgPSBbXG4gICAgLi4uYWRiLmV4ZWN1dGFibGUuZGVmYXVsdEFyZ3MsXG4gICAgJ2V4ZWMtb3V0JyxcbiAgICAvLyBUaGUgbG9vcCBpcyByZXF1aXJlZCwgYmVjYXVzZSBieSBkZWZhdWx0IHRoZSBtYXhpbXVtIHJlY29yZCBkdXJhdGlvblxuICAgIC8vIGZvciBzY3JlZW5yZWNvcmQgaXMgYWx3YXlzIGxpbWl0ZWRcbiAgICBgd2hpbGUgdHJ1ZTsgZG8gJHtzY3JlZW5SZWNvcmRDbWR9IC07IGRvbmVgLFxuICBdO1xuICBjb25zdCBkZXZpY2VTdHJlYW1pbmcgPSBzcGF3bihhZGIuZXhlY3V0YWJsZS5wYXRoLCBhZGJBcmdzKTtcbiAgZGV2aWNlU3RyZWFtaW5nLm9uKCdleGl0JywgKGNvZGUsIHNpZ25hbCkgPT4ge1xuICAgIGxvZy5kZWJ1ZyhgRGV2aWNlIHN0cmVhbWluZyBwcm9jZXNzIGV4aXRlZCB3aXRoIGNvZGUgJHtjb2RlfSwgc2lnbmFsICR7c2lnbmFsfWApO1xuICB9KTtcblxuICBsZXQgaXNTdGFydGVkID0gZmFsc2U7XG4gIGNvbnN0IGRldmljZVN0cmVhbWluZ0xvZ2dlciA9IGNyZWF0ZVN0cmVhbWluZ0xvZ2dlcihTQ1JFRU5SRUNPUkRfQklOQVJZLCBkZXZpY2VJbmZvLnVkaWQpO1xuICBjb25zdCBlcnJvcnNMaXN0ZW5lciA9IChjaHVuaykgPT4ge1xuICAgIGNvbnN0IHN0ZGVyciA9IGNodW5rLnRvU3RyaW5nKCk7XG4gICAgaWYgKF8udHJpbShzdGRlcnIpKSB7XG4gICAgICBkZXZpY2VTdHJlYW1pbmdMb2dnZXIuZGVidWcoc3RkZXJyKTtcbiAgICB9XG4gIH07XG4gIGRldmljZVN0cmVhbWluZy5zdGRlcnIub24oJ2RhdGEnLCBlcnJvcnNMaXN0ZW5lcik7XG5cbiAgY29uc3Qgc3RhcnR1cExpc3RlbmVyID0gKGNodW5rKSA9PiB7XG4gICAgaWYgKCFpc1N0YXJ0ZWQpIHtcbiAgICAgIGlzU3RhcnRlZCA9ICFfLmlzRW1wdHkoY2h1bmspO1xuICAgIH1cbiAgfTtcbiAgZGV2aWNlU3RyZWFtaW5nLnN0ZG91dC5vbignZGF0YScsIHN0YXJ0dXBMaXN0ZW5lcik7XG5cbiAgdHJ5IHtcbiAgICBsb2cuaW5mbyhgU3RhcnRpbmcgZGV2aWNlIHN0cmVhbWluZzogJHt1dGlsLnF1b3RlKFthZGIuZXhlY3V0YWJsZS5wYXRoLCAuLi5hZGJBcmdzXSl9YCk7XG4gICAgYXdhaXQgd2FpdEZvckNvbmRpdGlvbigoKSA9PiBpc1N0YXJ0ZWQsIHtcbiAgICAgIHdhaXRNczogU1RSRUFNSU5HX1NUQVJUVVBfVElNRU9VVF9NUyxcbiAgICAgIGludGVydmFsTXM6IDMwMCxcbiAgICB9KTtcbiAgfSBjYXRjaCAoZSkge1xuICAgIGxvZy5lcnJvckFuZFRocm93KFxuICAgICAgYENhbm5vdCBzdGFydCB0aGUgc2NyZWVuIHN0cmVhbWluZyBwcm9jZXNzLiBPcmlnaW5hbCBlcnJvcjogJHtlLm1lc3NhZ2V9YCk7XG4gIH0gZmluYWxseSB7XG4gICAgZGV2aWNlU3RyZWFtaW5nLnN0ZGVyci5yZW1vdmVMaXN0ZW5lcignZGF0YScsIGVycm9yc0xpc3RlbmVyKTtcbiAgICBkZXZpY2VTdHJlYW1pbmcuc3Rkb3V0LnJlbW92ZUxpc3RlbmVyKCdkYXRhJywgc3RhcnR1cExpc3RlbmVyKTtcbiAgfVxuICByZXR1cm4gZGV2aWNlU3RyZWFtaW5nO1xufVxuXG5hc3luYyBmdW5jdGlvbiBpbml0R3N0cmVhbWVyUGlwZWxpbmUgKGRldmljZVN0cmVhbWluZ1Byb2MsIGRldmljZUluZm8sIGxvZywgb3B0cyA9IHt9KSB7XG4gIGNvbnN0IHtcbiAgICB3aWR0aCxcbiAgICBoZWlnaHQsXG4gICAgcXVhbGl0eSxcbiAgICB0Y3BQb3J0LFxuICAgIGNvbnNpZGVyUm90YXRpb24sXG4gICAgbG9nUGlwZWxpbmVEZXRhaWxzLFxuICB9ID0gb3B0cztcbiAgY29uc3QgYWRqdXN0ZWRXaWR0aCA9IHBhcnNlSW50KHdpZHRoLCAxMCkgfHwgZGV2aWNlSW5mby53aWR0aDtcbiAgY29uc3QgYWRqdXN0ZWRIZWlnaHQgPSBwYXJzZUludChoZWlnaHQsIDEwKSB8fCBkZXZpY2VJbmZvLmhlaWdodDtcbiAgY29uc3QgZ3N0cmVhbWVyUGlwZWxpbmUgPSBuZXcgU3ViUHJvY2VzcyhHU1RSRUFNRVJfQklOQVJZLCBbXG4gICAgJy12JyxcbiAgICAnZmRzcmMnLCAnZmQ9MCcsXG4gICAgJyEnLCAndmlkZW8veC1oMjY0LCcgK1xuICAgICAgYHdpZHRoPSR7Y29uc2lkZXJSb3RhdGlvbiA/IE1hdGgubWF4KGFkanVzdGVkV2lkdGgsIGFkanVzdGVkSGVpZ2h0KSA6IGFkanVzdGVkV2lkdGh9LGAgK1xuICAgICAgYGhlaWdodD0ke2NvbnNpZGVyUm90YXRpb24gPyBNYXRoLm1heChhZGp1c3RlZFdpZHRoLCBhZGp1c3RlZEhlaWdodCkgOiBhZGp1c3RlZEhlaWdodH0sYCArXG4gICAgICBgZnJhbWVyYXRlPSR7ZGV2aWNlSW5mby5mcHN9LzEsYCArXG4gICAgICAnYnl0ZS1zdHJlYW09dHJ1ZScsXG4gICAgJyEnLCAnaDI2NHBhcnNlJyxcbiAgICAnIScsICdxdWV1ZScsICdsZWFreT1kb3duc3RyZWFtJyxcbiAgICAnIScsICdhdmRlY19oMjY0JyxcbiAgICAnIScsICdxdWV1ZScsICdsZWFreT1kb3duc3RyZWFtJyxcbiAgICAnIScsICdqcGVnZW5jJywgYHF1YWxpdHk9JHtxdWFsaXR5fWAsXG4gICAgJyEnLCAnbXVsdGlwYXJ0bXV4JywgYGJvdW5kYXJ5PSR7Qk9VTkRBUllfU1RSSU5HfWAsXG4gICAgJyEnLCAndGNwc2VydmVyc2luaycsIGBob3N0PSR7VENQX0hPU1R9YCwgYHBvcnQ9JHt0Y3BQb3J0fWAsXG4gIF0sIHtcbiAgICBzdGRpbzogW2RldmljZVN0cmVhbWluZ1Byb2Muc3Rkb3V0LCAncGlwZScsICdwaXBlJ11cbiAgfSk7XG4gIGdzdHJlYW1lclBpcGVsaW5lLm9uKCdleGl0JywgKGNvZGUsIHNpZ25hbCkgPT4ge1xuICAgIGxvZy5kZWJ1ZyhgUGlwZWxpbmUgc3RyZWFtaW5nIHByb2Nlc3MgZXhpdGVkIHdpdGggY29kZSAke2NvZGV9LCBzaWduYWwgJHtzaWduYWx9YCk7XG4gIH0pO1xuICBjb25zdCBnc3RyZWFtZXJMb2dnZXIgPSBjcmVhdGVTdHJlYW1pbmdMb2dnZXIoJ2dzdCcsIGRldmljZUluZm8udWRpZCk7XG4gIGNvbnN0IGdzdE91dHB1dExpc3RlbmVyID0gKHN0ZG91dCwgc3RkZXJyKSA9PiB7XG4gICAgaWYgKF8udHJpbShzdGRlcnIgfHwgc3Rkb3V0KSkge1xuICAgICAgZ3N0cmVhbWVyTG9nZ2VyLmRlYnVnKHN0ZGVyciB8fCBzdGRvdXQpO1xuICAgIH1cbiAgfTtcbiAgZ3N0cmVhbWVyUGlwZWxpbmUub24oJ291dHB1dCcsIGdzdE91dHB1dExpc3RlbmVyKTtcbiAgbGV0IGRpZEZhaWwgPSBmYWxzZTtcbiAgdHJ5IHtcbiAgICBsb2cuaW5mbyhgU3RhcnRpbmcgR1N0cmVhbWVyIHBpcGVsaW5lOiAke2dzdHJlYW1lclBpcGVsaW5lLnJlcH1gKTtcbiAgICBhd2FpdCBnc3RyZWFtZXJQaXBlbGluZS5zdGFydCgwKTtcbiAgICBhd2FpdCB3YWl0Rm9yQ29uZGl0aW9uKGFzeW5jICgpID0+IHtcbiAgICAgIHRyeSB7XG4gICAgICAgIHJldHVybiAoYXdhaXQgY2hlY2tQb3J0U3RhdHVzKHRjcFBvcnQsIFRDUF9IT1NUKSkgPT09ICdvcGVuJztcbiAgICAgIH0gY2F0Y2ggKGlnbikge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICB9XG4gICAgfSwge1xuICAgICAgd2FpdE1zOiBTVFJFQU1JTkdfU1RBUlRVUF9USU1FT1VUX01TLFxuICAgICAgaW50ZXJ2YWxNczogMzAwLFxuICAgIH0pO1xuICB9IGNhdGNoIChlKSB7XG4gICAgZGlkRmFpbCA9IHRydWU7XG4gICAgbG9nLmVycm9yQW5kVGhyb3coXG4gICAgICBgQ2Fubm90IHN0YXJ0IHRoZSBzY3JlZW4gc3RyZWFtaW5nIHBpcGVsaW5lLiBPcmlnaW5hbCBlcnJvcjogJHtlLm1lc3NhZ2V9YCk7XG4gIH0gZmluYWxseSB7XG4gICAgaWYgKCFsb2dQaXBlbGluZURldGFpbHMgfHwgZGlkRmFpbCkge1xuICAgICAgZ3N0cmVhbWVyUGlwZWxpbmUucmVtb3ZlTGlzdGVuZXIoJ291dHB1dCcsIGdzdE91dHB1dExpc3RlbmVyKTtcbiAgICB9XG4gIH1cbiAgcmV0dXJuIGdzdHJlYW1lclBpcGVsaW5lO1xufVxuXG5mdW5jdGlvbiBleHRyYWN0UmVtb3RlQWRkcmVzcyAocmVxKSB7XG4gIHJldHVybiByZXEuaGVhZGVyc1sneC1mb3J3YXJkZWQtZm9yJ11cbiAgICB8fCByZXEuc29ja2V0LnJlbW90ZUFkZHJlc3NcbiAgICB8fCByZXEuY29ubmVjdGlvbi5yZW1vdGVBZGRyZXNzXG4gICAgfHwgcmVxLmNvbm5lY3Rpb24uc29ja2V0LnJlbW90ZUFkZHJlc3M7XG59XG5cblxuLyoqXG4gKiBAdHlwZWRlZiB7T2JqZWN0fSBTdGFydFNjcmVlblN0cmVhbWluZ09wdGlvbnNcbiAqXG4gKiBAcHJvcGVydHkgez9udW1iZXJ9IHdpZHRoIC0gVGhlIHNjYWxlZCB3aWR0aCBvZiB0aGUgZGV2aWNlJ3Mgc2NyZWVuLiBJZiB1bnNldCB0aGVuIHRoZSBzY3JpcHQgd2lsbCBhc3NpZ24gaXRcbiAqIHRvIHRoZSBhY3R1YWwgc2NyZWVuIHdpZHRoIG1lYXN1cmVkIGluIHBpeGVscy5cbiAqIEBwcm9wZXJ0eSB7P251bWJlcn0gaGVpZ2h0IC0gVGhlIHNjYWxlZCBoZWlnaHQgb2YgdGhlIGRldmljZSdzIHNjcmVlbi4gSWYgdW5zZXQgdGhlbiB0aGUgc2NyaXB0IHdpbGwgYXNzaWduIGl0XG4gKiB0byB0aGUgYWN0dWFsIHNjcmVlbiBoZWlnaHQgbWVhc3VyZWQgaW4gcGl4ZWxzLlxuICogQHByb3BlcnR5IHs/bnVtYmVyfSBiaXRSYXRlIC0gVGhlIHZpZGVvIGJpdCByYXRlIGZvciB0aGUgdmlkZW8sIGluIGJpdHMgcGVyIHNlY29uZC5cbiAqIFRoZSBkZWZhdWx0IHZhbHVlIGlzIDQwMDAwMDAgKDQgTWIvcykuIFlvdSBjYW4gaW5jcmVhc2UgdGhlIGJpdCByYXRlIHRvIGltcHJvdmUgdmlkZW8gcXVhbGl0eSxcbiAqIGJ1dCBkb2luZyBzbyByZXN1bHRzIGluIGxhcmdlciBtb3ZpZSBmaWxlcy5cbiAqIEBwcm9wZXJ0eSB7P3N0cmluZ30gaG9zdCBbMTI3LjAuMC4xXSAtIFRoZSBJUCBhZGRyZXNzL2hvc3QgbmFtZSB0byBzdGFydCB0aGUgTUpQRUcgc2VydmVyIG9uLlxuICogWW91IGNhbiBzZXQgaXQgdG8gYDAuMC4wLjBgIHRvIHRyaWdnZXIgdGhlIGJyb2FkY2FzdCBvbiBhbGwgYXZhaWxhYmxlIG5ldHdvcmsgaW50ZXJmYWNlcy5cbiAqIEBwcm9wZXJ0eSB7P3N0cmluZ30gcGF0aG5hbWUgLSBUaGUgSFRUUCByZXF1ZXN0IHBhdGggdGhlIE1KUEVHIHNlcnZlciBzaG91bGQgYmUgYXZhaWxhYmxlIG9uLlxuICogSWYgdW5zZXQgdGhlbiBhbnkgcGF0aG5hbWUgb24gdGhlIGdpdmVuIGBob3N0YC9gcG9ydGAgY29tYmluYXRpb24gd2lsbCB3b3JrLiBOb3RlIHRoYXQgdGhlIHZhbHVlXG4gKiBzaG91bGQgYWx3YXlzIHN0YXJ0IHdpdGggYSBzaW5nbGUgc2xhc2g6IGAvYFxuICogQHByb3BlcnR5IHs/bnVtYmVyfSB0Y3BQb3J0IFs4MDk0XSAtIFRoZSBwb3J0IG51bWJlciB0byBzdGFydCB0aGUgaW50ZXJuYWwgVENQIE1KUEVHIGJyb2FkY2FzdCBvbi5cbiAqIFRoaXMgdHlwZSBvZiBicm9hZGNhc3QgYWx3YXlzIHN0YXJ0cyBvbiB0aGUgbG9vcGJhY2sgaW50ZXJmYWNlIChgMTI3LjAuMC4xYCkuXG4gKiBAcHJvcGVydHkgez9udW1iZXJ9IHBvcnQgWzgwOTNdIC0gVGhlIHBvcnQgbnVtYmVyIHRvIHN0YXJ0IHRoZSBNSlBFRyBzZXJ2ZXIgb24uXG4gKiBAcHJvcGVydHkgez9udW1iZXJ9IHF1YWxpdHkgWzcwXSAtIFRoZSBxdWFsaXR5IHZhbHVlIGZvciB0aGUgc3RyZWFtZWQgSlBFRyBpbWFnZXMuXG4gKiBUaGlzIG51bWJlciBzaG91bGQgYmUgaW4gcmFuZ2UgWzEsIDEwMF0sIHdoZXJlIDEwMCBpcyB0aGUgYmVzdCBxdWFsaXR5LlxuICogQHByb3BlcnR5IHs/Ym9vbGVhbn0gY29uc2lkZXJSb3RhdGlvbiBbZmFsc2VdIC0gSWYgc2V0IHRvIGB0cnVlYCB0aGVuIEdTdHJlYW1lciBwaXBlbGluZSB3aWxsXG4gKiBpbmNyZWFzZSB0aGUgZGltZW5zaW9ucyBvZiB0aGUgcmVzdWx0aW5nIGltYWdlcyB0byBwcm9wZXJseSBmaXQgaW1hZ2VzIGluIGJvdGggbGFuZHNjYXBlIGFuZFxuICogcG9ydHJhaXQgb3JpZW50YXRpb25zLiBTZXQgaXQgdG8gYHRydWVgIGlmIHRoZSBkZXZpY2Ugcm90YXRpb24gaXMgbm90IGdvaW5nIHRvIGJlIHRoZSBzYW1lIGR1cmluZyB0aGVcbiAqIGJyb2FkY2FzdGluZyBzZXNzaW9uLlxuICogQHByb3BlcnR5IHs/Ym9vbGVhbn0gbG9nUGlwZWxpbmVEZXRhaWxzIFtmYWxzZV0gLSBXaGV0aGVyIHRvIGxvZyBHU3RyZWFtZXIgcGlwZWxpbmUgZXZlbnRzIGludG9cbiAqIHRoZSBzdGFuZGFyZCBsb2cgb3V0cHV0LiBNaWdodCBiZSB1c2VmdWwgZm9yIGRlYnVnZ2luZyBwdXJwb3Nlcy5cbiAqL1xuXG4vKipcbiAqIFN0YXJ0cyBkZXZpY2Ugc2NyZWVuIGJyb2FkY2FzdCBieSBjcmVhdGluZyBNSlBFRyBzZXJ2ZXIuXG4gKiBNdWx0aXBsZSBjYWxscyB0byB0aGlzIG1ldGhvZCBoYXZlIG5vIGVmZmVjdCB1bmxlc3MgdGhlIHByZXZpb3VzIHN0cmVhbWluZ1xuICogc2Vzc2lvbiBpcyBzdG9wcGVkLlxuICogVGhpcyBtZXRob2Qgb25seSB3b3JrcyBpZiB0aGUgYGFkYl9zY3JlZW5fc3RyZWFtaW5nYCBmZWF0dXJlIGlzXG4gKiBlbmFibGVkIG9uIHRoZSBzZXJ2ZXIgc2lkZS5cbiAqXG4gKiBAcGFyYW0gez9TdGFydFNjcmVlblN0cmVhbWluZ09wdGlvbnN9IG9wdGlvbnMgLSBUaGUgYXZhaWxhYmxlIG9wdGlvbnMuXG4gKiBAdGhyb3dzIHtFcnJvcn0gSWYgc2NyZWVuIHN0cmVhbWluZyBoYXMgZmFpbGVkIHRvIHN0YXJ0IG9yXG4gKiBpcyBub3Qgc3VwcG9ydGVkIG9uIHRoZSBob3N0IHN5c3RlbSBvclxuICogdGhlIGNvcnJlc3BvbmRpbmcgc2VydmVyIGZlYXR1cmUgaXMgbm90IGVuYWJsZWQuXG4gKi9cbmNvbW1hbmRzLm1vYmlsZVN0YXJ0U2NyZWVuU3RyZWFtaW5nID0gYXN5bmMgZnVuY3Rpb24gbW9iaWxlU3RhcnRTY3JlZW5TdHJlYW1pbmcgKG9wdGlvbnMgPSB7fSkge1xuICB0aGlzLmVuc3VyZUZlYXR1cmVFbmFibGVkKEFEQl9TQ1JFRU5fU1RSRUFNSU5HX0ZFQVRVUkUpO1xuXG4gIGNvbnN0IHtcbiAgICB3aWR0aCxcbiAgICBoZWlnaHQsXG4gICAgYml0UmF0ZSxcbiAgICBob3N0ID0gREVGQVVMVF9IT1NULFxuICAgIHBvcnQgPSBERUZBVUxUX1BPUlQsXG4gICAgcGF0aG5hbWUsXG4gICAgdGNwUG9ydCA9IERFRkFVTFRfUE9SVCArIDEsXG4gICAgcXVhbGl0eSA9IERFRkFVTFRfUVVBTElUWSxcbiAgICBjb25zaWRlclJvdGF0aW9uID0gZmFsc2UsXG4gICAgbG9nUGlwZWxpbmVEZXRhaWxzID0gZmFsc2UsXG4gIH0gPSBvcHRpb25zO1xuXG4gIGlmIChfLmlzVW5kZWZpbmVkKHRoaXMuX3NjcmVlblN0cmVhbWluZ1Byb3BzKSkge1xuICAgIGF3YWl0IHZlcmlmeVN0cmVhbWluZ1JlcXVpcmVtZW50cyh0aGlzLmFkYik7XG4gIH1cbiAgaWYgKCFfLmlzRW1wdHkodGhpcy5fc2NyZWVuU3RyZWFtaW5nUHJvcHMpKSB7XG4gICAgdGhpcy5sb2cuaW5mbyhgVGhlIHNjcmVlbiBzdHJlYW1pbmcgc2Vzc2lvbiBpcyBhbHJlYWR5IHJ1bm5pbmcuIGAgK1xuICAgICAgYFN0b3AgaXQgZmlyc3QgaW4gb3JkZXIgdG8gc3RhcnQgYSBuZXcgb25lLmApO1xuICAgIHJldHVybjtcbiAgfVxuICBpZiAoKGF3YWl0IGNoZWNrUG9ydFN0YXR1cyhwb3J0LCBob3N0KSkgPT09ICdvcGVuJykge1xuICAgIHRoaXMubG9nLmluZm8oYFRoZSBwb3J0ICMke3BvcnR9IGF0ICR7aG9zdH0gaXMgYnVzeS4gYCArXG4gICAgICBgQXNzdW1pbmcgdGhlIHNjcmVlbiBzdHJlYW1pbmcgaXMgYWxyZWFkeSBydW5uaW5nYCk7XG4gICAgcmV0dXJuO1xuICB9XG4gIGlmICgoYXdhaXQgY2hlY2tQb3J0U3RhdHVzKHRjcFBvcnQsIFRDUF9IT1NUKSkgPT09ICdvcGVuJykge1xuICAgIHRoaXMubG9nLmVycm9yQW5kVGhyb3coYFRoZSBwb3J0ICMke3RjcFBvcnR9IGF0ICR7VENQX0hPU1R9IGlzIGJ1c3kuIGAgK1xuICAgICAgYE1ha2Ugc3VyZSB0aGVyZSBhcmUgbm8gbGVmdG92ZXJzIGZyb20gcHJldmlvdXMgc2Vzc2lvbnMuYCk7XG4gIH1cbiAgdGhpcy5fc2NyZWVuU3RyZWFtaW5nUHJvcHMgPSBudWxsO1xuXG4gIGNvbnN0IGRldmljZUluZm8gPSBhd2FpdCBnZXREZXZpY2VJbmZvKHRoaXMuYWRiLCB0aGlzLmxvZyk7XG4gIGNvbnN0IGRldmljZVN0cmVhbWluZ1Byb2MgPSBhd2FpdCBpbml0RGV2aWNlU3RyZWFtaW5nUHJvYyh0aGlzLmFkYiwgdGhpcy5sb2csIGRldmljZUluZm8sIHtcbiAgICB3aWR0aCxcbiAgICBoZWlnaHQsXG4gICAgYml0UmF0ZSxcbiAgfSk7XG4gIGxldCBnc3RyZWFtZXJQaXBlbGluZTtcbiAgdHJ5IHtcbiAgICBnc3RyZWFtZXJQaXBlbGluZSA9IGF3YWl0IGluaXRHc3RyZWFtZXJQaXBlbGluZShkZXZpY2VTdHJlYW1pbmdQcm9jLCBkZXZpY2VJbmZvLCB0aGlzLmxvZywge1xuICAgICAgd2lkdGgsXG4gICAgICBoZWlnaHQsXG4gICAgICBxdWFsaXR5LFxuICAgICAgdGNwUG9ydCxcbiAgICAgIGNvbnNpZGVyUm90YXRpb24sXG4gICAgICBsb2dQaXBlbGluZURldGFpbHMsXG4gICAgfSk7XG4gIH0gY2F0Y2ggKGUpIHtcbiAgICBpZiAoZGV2aWNlU3RyZWFtaW5nUHJvYy5raWxsKDApKSB7XG4gICAgICBkZXZpY2VTdHJlYW1pbmdQcm9jLmtpbGwoKTtcbiAgICB9XG4gICAgdGhyb3cgZTtcbiAgfVxuXG4gIGxldCBtanBlZ1NvY2tldDtcbiAgbGV0IG1qcGVnU2VydmVyO1xuICB0cnkge1xuICAgIGF3YWl0IG5ldyBCKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgIG1qcGVnU29ja2V0ID0gbmV0LmNyZWF0ZUNvbm5lY3Rpb24odGNwUG9ydCwgVENQX0hPU1QsICgpID0+IHtcbiAgICAgICAgdGhpcy5sb2cuaW5mbyhgU3VjY2Vzc2Z1bGx5IGNvbm5lY3RlZCB0byBNSlBFRyBzdHJlYW0gYXQgdGNwOi8vJHtUQ1BfSE9TVH06JHt0Y3BQb3J0fWApO1xuICAgICAgICBtanBlZ1NlcnZlciA9IGh0dHAuY3JlYXRlU2VydmVyKChyZXEsIHJlcykgPT4ge1xuICAgICAgICAgIGNvbnN0IHJlbW90ZUFkZHJlc3MgPSBleHRyYWN0UmVtb3RlQWRkcmVzcyhyZXEpO1xuICAgICAgICAgIGNvbnN0IGN1cnJlbnRQYXRobmFtZSA9IHVybC5wYXJzZShyZXEudXJsKS5wYXRobmFtZTtcbiAgICAgICAgICB0aGlzLmxvZy5pbmZvKGBHb3QgYW4gaW5jb21pbmcgc2NyZWVuIGJyYWRjYXN0aW5nIHJlcXVlc3QgZnJvbSAke3JlbW90ZUFkZHJlc3N9IGAgK1xuICAgICAgICAgICAgYCgke3JlcS5oZWFkZXJzWyd1c2VyLWFnZW50J10gfHwgJ1VzZXIgQWdlbnQgdW5rbm93bid9KSBhdCAke2N1cnJlbnRQYXRobmFtZX1gKTtcblxuICAgICAgICAgIGlmIChwYXRobmFtZSAmJiBjdXJyZW50UGF0aG5hbWUgIT09IHBhdGhuYW1lKSB7XG4gICAgICAgICAgICB0aGlzLmxvZy5pbmZvKCdSZWplY3RpbmcgdGhlIGJyb2FkY2FzdCByZXF1ZXN0IHNpbmNlIGl0IGRvZXMgbm90IG1hdGNoIHRoZSBnaXZlbiBwYXRobmFtZScpO1xuICAgICAgICAgICAgcmVzLndyaXRlSGVhZCg0MDQsIHtcbiAgICAgICAgICAgICAgQ29ubmVjdGlvbjogJ2Nsb3NlJyxcbiAgICAgICAgICAgICAgJ0NvbnRlbnQtVHlwZSc6ICd0ZXh0L3BsYWluOyBjaGFyc2V0PXV0Zi04JyxcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgcmVzLndyaXRlKGAnJHtjdXJyZW50UGF0aG5hbWV9JyBkaWQgbm90IG1hdGNoIGFueSBrbm93biBlbmRwb2ludHNgKTtcbiAgICAgICAgICAgIHJlcy5lbmQoKTtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICB0aGlzLmxvZy5pbmZvKCdTdGFydGluZyBNSlBFRyBicm9hZGNhc3QnKTtcbiAgICAgICAgICByZXMud3JpdGVIZWFkKDIwMCwge1xuICAgICAgICAgICAgJ0NhY2hlLUNvbnRyb2wnOiAnbm8tc3RvcmUsIG5vLWNhY2hlLCBtdXN0LXJldmFsaWRhdGUsIHByZS1jaGVjaz0wLCBwb3N0LWNoZWNrPTAsIG1heC1hZ2U9MCcsXG4gICAgICAgICAgICBQcmFnbWE6ICduby1jYWNoZScsXG4gICAgICAgICAgICBDb25uZWN0aW9uOiAnY2xvc2UnLFxuICAgICAgICAgICAgJ0NvbnRlbnQtVHlwZSc6IGBtdWx0aXBhcnQveC1taXhlZC1yZXBsYWNlOyBib3VuZGFyeT0ke0JPVU5EQVJZX1NUUklOR31gXG4gICAgICAgICAgfSk7XG5cbiAgICAgICAgICBtanBlZ1NvY2tldC5waXBlKHJlcyk7XG4gICAgICAgIH0pO1xuICAgICAgICBtanBlZ1NlcnZlci5vbignZXJyb3InLCAoZSkgPT4ge1xuICAgICAgICAgIHRoaXMubG9nLndhcm4oZSk7XG4gICAgICAgICAgcmVqZWN0KGUpO1xuICAgICAgICB9KTtcbiAgICAgICAgbWpwZWdTZXJ2ZXIub24oJ2Nsb3NlJywgKCkgPT4ge1xuICAgICAgICAgIHRoaXMubG9nLmRlYnVnKGBNSlBFRyBzZXJ2ZXIgYXQgaHR0cDovLyR7aG9zdH06JHtwb3J0fSBoYXMgYmVlbiBjbG9zZWRgKTtcbiAgICAgICAgfSk7XG4gICAgICAgIG1qcGVnU2VydmVyLm9uKCdsaXN0ZW5pbmcnLCAoKSA9PiB7XG4gICAgICAgICAgdGhpcy5sb2cuaW5mbyhgU3VjY2Vzc2Z1bGx5IHN0YXJ0ZWQgTUpQRUcgc2VydmVyIGF0IGh0dHA6Ly8ke2hvc3R9OiR7cG9ydH1gKTtcbiAgICAgICAgICByZXNvbHZlKCk7XG4gICAgICAgIH0pO1xuICAgICAgICBtanBlZ1NlcnZlci5saXN0ZW4ocG9ydCwgaG9zdCk7XG4gICAgICB9KTtcbiAgICAgIG1qcGVnU29ja2V0Lm9uKCdlcnJvcicsIChlKSA9PiB7XG4gICAgICAgIHRoaXMubG9nLmVycm9yKGUpO1xuICAgICAgICByZWplY3QoZSk7XG4gICAgICB9KTtcbiAgICB9KS50aW1lb3V0KFNUUkVBTUlOR19TVEFSVFVQX1RJTUVPVVRfTVMsXG4gICAgICBgQ2Fubm90IGNvbm5lY3QgdG8gdGhlIHN0cmVhbWluZyBzZXJ2ZXIgd2l0aGluICR7U1RSRUFNSU5HX1NUQVJUVVBfVElNRU9VVF9NU31tc2ApO1xuICB9IGNhdGNoIChlKSB7XG4gICAgaWYgKGRldmljZVN0cmVhbWluZ1Byb2Mua2lsbCgwKSkge1xuICAgICAgZGV2aWNlU3RyZWFtaW5nUHJvYy5raWxsKCk7XG4gICAgfVxuICAgIGlmIChnc3RyZWFtZXJQaXBlbGluZS5pc1J1bm5pbmcpIHtcbiAgICAgIGF3YWl0IGdzdHJlYW1lclBpcGVsaW5lLnN0b3AoKTtcbiAgICB9XG4gICAgaWYgKG1qcGVnU29ja2V0KSB7XG4gICAgICBtanBlZ1NvY2tldC5kZXN0cm95KCk7XG4gICAgfVxuICAgIGlmIChtanBlZ1NlcnZlciAmJiBtanBlZ1NlcnZlci5saXN0ZW5pbmcpIHtcbiAgICAgIG1qcGVnU2VydmVyLmNsb3NlKCk7XG4gICAgfVxuICAgIHRocm93IGU7XG4gIH1cblxuICB0aGlzLl9zY3JlZW5TdHJlYW1pbmdQcm9wcyA9IHtcbiAgICBkZXZpY2VTdHJlYW1pbmdQcm9jLFxuICAgIGdzdHJlYW1lclBpcGVsaW5lLFxuICAgIG1qcGVnU29ja2V0LFxuICAgIG1qcGVnU2VydmVyLFxuICB9O1xufTtcblxuLyoqXG4gKiBTdG9wIHNjcmVlbiBzdHJlYW1pbmcuXG4gKiBJZiBubyBzY3JlZW4gc3RyZWFtaW5nIHNlcnZlciBoYXMgYmVlbiBzdGFydGVkIHRoZW4gbm90aGluZyBpcyBkb25lLlxuICovXG5jb21tYW5kcy5tb2JpbGVTdG9wU2NyZWVuU3RyZWFtaW5nID0gYXN5bmMgZnVuY3Rpb24gbW9iaWxlU3RvcFNjcmVlblN0cmVhbWluZyAoLyogb3B0aW9ucyA9IHt9ICovKSB7XG4gIGlmIChfLmlzRW1wdHkodGhpcy5fc2NyZWVuU3RyZWFtaW5nUHJvcHMpKSB7XG4gICAgaWYgKCFfLmlzVW5kZWZpbmVkKHRoaXMuX3NjcmVlblN0cmVhbWluZ1Byb3BzKSkge1xuICAgICAgdGhpcy5sb2cuZGVidWcoYFNjcmVlbiBzdHJlYW1pbmcgaXMgbm90IHJ1bm5pbmcuIFRoZXJlIGlzIG5vdGhpbmcgdG8gc3RvcGApO1xuICAgIH1cbiAgICByZXR1cm47XG4gIH1cblxuICBjb25zdCB7XG4gICAgZGV2aWNlU3RyZWFtaW5nUHJvYyxcbiAgICBnc3RyZWFtZXJQaXBlbGluZSxcbiAgICBtanBlZ1NvY2tldCxcbiAgICBtanBlZ1NlcnZlcixcbiAgfSA9IHRoaXMuX3NjcmVlblN0cmVhbWluZ1Byb3BzO1xuXG4gIHRyeSB7XG4gICAgbWpwZWdTb2NrZXQuZW5kKCk7XG4gICAgaWYgKG1qcGVnU2VydmVyLmxpc3RlbmluZykge1xuICAgICAgbWpwZWdTZXJ2ZXIuY2xvc2UoKTtcbiAgICB9XG4gICAgaWYgKGRldmljZVN0cmVhbWluZ1Byb2Mua2lsbCgwKSkge1xuICAgICAgZGV2aWNlU3RyZWFtaW5nUHJvYy5raWxsKCdTSUdJTlQnKTtcbiAgICB9XG4gICAgaWYgKGdzdHJlYW1lclBpcGVsaW5lLmlzUnVubmluZykge1xuICAgICAgdHJ5IHtcbiAgICAgICAgYXdhaXQgZ3N0cmVhbWVyUGlwZWxpbmUuc3RvcCgnU0lHSU5UJyk7XG4gICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgIHRoaXMubG9nLndhcm4oZSk7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgYXdhaXQgZ3N0cmVhbWVyUGlwZWxpbmUuc3RvcCgnU0lHS0lMTCcpO1xuICAgICAgICB9IGNhdGNoIChlMSkge1xuICAgICAgICAgIHRoaXMubG9nLmVycm9yKGUxKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgICB0aGlzLmxvZy5pbmZvKGBTdWNjZXNzZnVsbHkgdGVybWluYXRlZCB0aGUgc2NyZWVuIHN0cmVhbWluZyBNSlBFRyBzZXJ2ZXJgKTtcbiAgfSBmaW5hbGx5IHtcbiAgICB0aGlzLl9zY3JlZW5TdHJlYW1pbmdQcm9wcyA9IG51bGw7XG4gIH1cbn07XG5cblxuZXhwb3J0IGRlZmF1bHQgY29tbWFuZHM7XG4iXSwibWFwcGluZ3MiOiI7Ozs7Ozs7O0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQSxNQUFNQSxRQUFRLEdBQUcsQ0FBQyxDQUFDO0FBRW5CLE1BQU1DLHNCQUFzQixHQUFHLENBQUM7QUFDaEMsTUFBTUMsNEJBQTRCLEdBQUcsSUFBSTtBQUN6QyxNQUFNQyxnQkFBZ0IsR0FBSSxpQkFBZ0JDLGVBQU0sQ0FBQ0MsU0FBUyxFQUFFLEdBQUcsTUFBTSxHQUFHLEVBQUcsRUFBQztBQUM1RSxNQUFNQyxrQkFBa0IsR0FBSSxrQkFBaUJGLGVBQU0sQ0FBQ0MsU0FBUyxFQUFFLEdBQUcsTUFBTSxHQUFHLEVBQUcsRUFBQztBQUMvRSxNQUFNRSxvQkFBb0IsR0FBRztFQUMzQkMsVUFBVSxFQUFFLFdBQVc7RUFDdkJDLFNBQVMsRUFBRSxpQkFBaUI7RUFDNUJDLE9BQU8sRUFBRSxrQkFBa0I7RUFDM0JDLGFBQWEsRUFBRSxrQkFBa0I7RUFDakNDLFlBQVksRUFBRTtBQUNoQixDQUFDO0FBQ0QsTUFBTUMsbUJBQW1CLEdBQUcsY0FBYztBQUMxQyxNQUFNQyxnQkFBZ0IsR0FBRyx1RUFBdUU7QUFDaEcsTUFBTUMsWUFBWSxHQUFHLFdBQVc7QUFDaEMsTUFBTUMsUUFBUSxHQUFHLFdBQVc7QUFDNUIsTUFBTUMsWUFBWSxHQUFHLElBQUk7QUFDekIsTUFBTUMsZUFBZSxHQUFHLEVBQUU7QUFDMUIsTUFBTUMsZUFBZSxHQUFHLE9BQU87QUFDL0IsTUFBTUMsZUFBZSxHQUFHLG9DQUFvQztBQUU1RCxNQUFNQyw0QkFBNEIsR0FBRyxzQkFBc0I7QUFFM0QsU0FBU0MscUJBQXFCLENBQUVDLFVBQVUsRUFBRUMsSUFBSSxFQUFFO0VBQ2hELE9BQU9DLGVBQU0sQ0FBQ0MsU0FBUyxDQUFFLEdBQUVILFVBQVcsR0FBRSxHQUFHSSxlQUFDLENBQUNDLFFBQVEsQ0FBQ0osSUFBSSxFQUFFO0lBQzFESyxNQUFNLEVBQUUsQ0FBQztJQUNUQyxRQUFRLEVBQUU7RUFDWixDQUFDLENBQUMsQ0FBQztBQUNMO0FBRUEsZUFBZUMsMkJBQTJCLENBQUVDLEdBQUcsRUFBRTtFQUMvQyxJQUFJLENBQUNMLGVBQUMsQ0FBQ00sSUFBSSxDQUFDLE1BQU1ELEdBQUcsQ0FBQ0UsS0FBSyxDQUFDLENBQUMsT0FBTyxFQUFFckIsbUJBQW1CLENBQUMsQ0FBQyxDQUFDLEVBQUU7SUFDNUQsTUFBTSxJQUFJc0IsS0FBSyxDQUNaLGlCQUFnQnRCLG1CQUFvQixvREFBbUQsQ0FBQztFQUM3RjtFQUVBLE1BQU11QixzQkFBc0IsR0FBRyxFQUFFO0VBQ2pDLEtBQUssTUFBTUMsVUFBVSxJQUFJLENBQUNsQyxnQkFBZ0IsRUFBRUcsa0JBQWtCLENBQUMsRUFBRTtJQUMvRDhCLHNCQUFzQixDQUFDRSxJQUFJLENBQUMsQ0FBQyxZQUFZO01BQ3ZDLElBQUk7UUFDRixNQUFNQyxXQUFFLENBQUNDLEtBQUssQ0FBQ0gsVUFBVSxDQUFDO01BQzVCLENBQUMsQ0FBQyxPQUFPSSxDQUFDLEVBQUU7UUFDVixNQUFNLElBQUlOLEtBQUssQ0FBRSxRQUFPRSxVQUFXLDREQUEyRCxHQUMzRixPQUFNdkIsZ0JBQWlCLHlDQUF3QyxDQUFDO01BQ3JFO0lBQ0YsQ0FBQyxHQUFHLENBQUM7RUFDUDtFQUNBLE1BQU00QixpQkFBQyxDQUFDQyxHQUFHLENBQUNQLHNCQUFzQixDQUFDO0VBRW5DLE1BQU1RLG1CQUFtQixHQUFHLEVBQUU7RUFDOUIsS0FBSyxNQUFNLENBQUNDLElBQUksRUFBRUMsT0FBTyxDQUFDLElBQUluQixlQUFDLENBQUNvQixPQUFPLENBQUN4QyxvQkFBb0IsQ0FBQyxFQUFFO0lBQzdEcUMsbUJBQW1CLENBQUNOLElBQUksQ0FBQyxDQUFDLFlBQVk7TUFDcEMsTUFBTTtRQUFDVTtNQUFNLENBQUMsR0FBRyxNQUFNLElBQUFDLGtCQUFJLEVBQUMzQyxrQkFBa0IsRUFBRSxDQUFDdUMsSUFBSSxDQUFDLENBQUM7TUFDdkQsSUFBSSxDQUFDbEIsZUFBQyxDQUFDdUIsUUFBUSxDQUFDRixNQUFNLEVBQUVGLE9BQU8sQ0FBQyxFQUFFO1FBQ2hDLE1BQU0sSUFBSVgsS0FBSyxDQUNaLGtDQUFpQ1UsSUFBSyxXQUFVQyxPQUFRLDZCQUE0QixHQUNwRixPQUFNaEMsZ0JBQWlCLHlDQUF3QyxDQUFDO01BQ3JFO0lBQ0YsQ0FBQyxHQUFHLENBQUM7RUFDUDtFQUNBLE1BQU00QixpQkFBQyxDQUFDQyxHQUFHLENBQUNDLG1CQUFtQixDQUFDO0FBQ2xDO0FBRUEsZUFBZU8sYUFBYSxDQUFFbkIsR0FBRyxFQUFFb0IsR0FBRyxHQUFHLElBQUksRUFBRTtFQUM3QyxNQUFNQyxNQUFNLEdBQUcsTUFBTXJCLEdBQUcsQ0FBQ0UsS0FBSyxDQUFDLENBQUMsU0FBUyxFQUFFLFNBQVMsQ0FBQyxDQUFDO0VBQ3RELE1BQU1vQixNQUFNLEdBQUcsQ0FBQyxDQUFDO0VBQ2pCLEtBQUssTUFBTSxDQUFDQyxHQUFHLEVBQUVDLE9BQU8sQ0FBQyxJQUFJLENBQzNCLENBQUMsT0FBTyxFQUFFLHFCQUFxQixDQUFDLEVBQ2hDLENBQUMsUUFBUSxFQUFFLHNCQUFzQixDQUFDLEVBQ2xDLENBQUMsS0FBSyxFQUFFLGFBQWEsQ0FBQyxDQUN2QixFQUFFO0lBQ0QsTUFBTUMsS0FBSyxHQUFHRCxPQUFPLENBQUNQLElBQUksQ0FBQ0ksTUFBTSxDQUFDO0lBQ2xDLElBQUksQ0FBQ0ksS0FBSyxFQUFFO01BQ1ZMLEdBQUcsYUFBSEEsR0FBRyx1QkFBSEEsR0FBRyxDQUFFTSxLQUFLLENBQUNMLE1BQU0sQ0FBQztNQUNsQixNQUFNLElBQUlsQixLQUFLLENBQUUsMkJBQTBCb0IsR0FBSSxnQ0FBK0IsR0FDM0Usd0NBQXVDLENBQUM7SUFDN0M7SUFDQUQsTUFBTSxDQUFDQyxHQUFHLENBQUMsR0FBR0ksUUFBUSxDQUFDRixLQUFLLENBQUMsQ0FBQyxDQUFDLEVBQUUsRUFBRSxDQUFDO0VBQ3RDO0VBQ0FILE1BQU0sQ0FBQzlCLElBQUksR0FBR1EsR0FBRyxDQUFDNEIsV0FBVztFQUM3QixPQUFPTixNQUFNO0FBQ2Y7QUFFQSxlQUFlTyx1QkFBdUIsQ0FBRTdCLEdBQUcsRUFBRW9CLEdBQUcsRUFBRVUsVUFBVSxFQUFFQyxJQUFJLEdBQUcsQ0FBQyxDQUFDLEVBQUU7RUFDdkUsTUFBTTtJQUNKQyxLQUFLO0lBQ0xDLE1BQU07SUFDTkM7RUFDRixDQUFDLEdBQUdILElBQUk7RUFDUixNQUFNSSxhQUFhLEdBQUdSLFFBQVEsQ0FBQ0ssS0FBSyxFQUFFLEVBQUUsQ0FBQyxJQUFJRixVQUFVLENBQUNFLEtBQUs7RUFDN0QsTUFBTUksY0FBYyxHQUFHVCxRQUFRLENBQUNNLE1BQU0sRUFBRSxFQUFFLENBQUMsSUFBSUgsVUFBVSxDQUFDRyxNQUFNO0VBQ2hFLE1BQU1JLGVBQWUsR0FBR1YsUUFBUSxDQUFDTyxPQUFPLEVBQUUsRUFBRSxDQUFDLElBQUkvQyxlQUFlO0VBQ2hFLElBQUltRCxlQUFlLEdBQUd6RCxtQkFBbUIsR0FDdEMsdUJBQXNCO0VBRXRCLGlCQUFnQlosc0JBQXVCLEVBQUM7RUFDM0MsSUFBSStELEtBQUssSUFBSUMsTUFBTSxFQUFFO0lBQ25CSyxlQUFlLElBQUssV0FBVUgsYUFBYyxJQUFHQyxjQUFlLEVBQUM7RUFDakU7RUFDQSxJQUFJRixPQUFPLEVBQUU7SUFDWEksZUFBZSxJQUFLLGVBQWNELGVBQWdCLEVBQUM7RUFDckQ7RUFDQSxNQUFNRSxPQUFPLEdBQUcsQ0FDZCxHQUFHdkMsR0FBRyxDQUFDd0MsVUFBVSxDQUFDQyxXQUFXLEVBQzdCLFVBQVU7RUFHVCxrQkFBaUJILGVBQWdCLFVBQVMsQ0FDNUM7RUFDRCxNQUFNSSxlQUFlLEdBQUcsSUFBQUMsb0JBQUssRUFBQzNDLEdBQUcsQ0FBQ3dDLFVBQVUsQ0FBQ0ksSUFBSSxFQUFFTCxPQUFPLENBQUM7RUFDM0RHLGVBQWUsQ0FBQ0csRUFBRSxDQUFDLE1BQU0sRUFBRSxDQUFDQyxJQUFJLEVBQUVDLE1BQU0sS0FBSztJQUMzQzNCLEdBQUcsQ0FBQ00sS0FBSyxDQUFFLDZDQUE0Q29CLElBQUssWUFBV0MsTUFBTyxFQUFDLENBQUM7RUFDbEYsQ0FBQyxDQUFDO0VBRUYsSUFBSUMsU0FBUyxHQUFHLEtBQUs7RUFDckIsTUFBTUMscUJBQXFCLEdBQUczRCxxQkFBcUIsQ0FBQ1QsbUJBQW1CLEVBQUVpRCxVQUFVLENBQUN0QyxJQUFJLENBQUM7RUFDekYsTUFBTTBELGNBQWMsR0FBSUMsS0FBSyxJQUFLO0lBQ2hDLE1BQU1DLE1BQU0sR0FBR0QsS0FBSyxDQUFDRSxRQUFRLEVBQUU7SUFDL0IsSUFBSTFELGVBQUMsQ0FBQ00sSUFBSSxDQUFDbUQsTUFBTSxDQUFDLEVBQUU7TUFDbEJILHFCQUFxQixDQUFDdkIsS0FBSyxDQUFDMEIsTUFBTSxDQUFDO0lBQ3JDO0VBQ0YsQ0FBQztFQUNEVixlQUFlLENBQUNVLE1BQU0sQ0FBQ1AsRUFBRSxDQUFDLE1BQU0sRUFBRUssY0FBYyxDQUFDO0VBRWpELE1BQU1JLGVBQWUsR0FBSUgsS0FBSyxJQUFLO0lBQ2pDLElBQUksQ0FBQ0gsU0FBUyxFQUFFO01BQ2RBLFNBQVMsR0FBRyxDQUFDckQsZUFBQyxDQUFDNEQsT0FBTyxDQUFDSixLQUFLLENBQUM7SUFDL0I7RUFDRixDQUFDO0VBQ0RULGVBQWUsQ0FBQzFCLE1BQU0sQ0FBQzZCLEVBQUUsQ0FBQyxNQUFNLEVBQUVTLGVBQWUsQ0FBQztFQUVsRCxJQUFJO0lBQ0ZsQyxHQUFHLENBQUNvQyxJQUFJLENBQUUsOEJBQTZCQyxhQUFJLENBQUNDLEtBQUssQ0FBQyxDQUFDMUQsR0FBRyxDQUFDd0MsVUFBVSxDQUFDSSxJQUFJLEVBQUUsR0FBR0wsT0FBTyxDQUFDLENBQUUsRUFBQyxDQUFDO0lBQ3ZGLE1BQU0sSUFBQW9CLDBCQUFnQixFQUFDLE1BQU1YLFNBQVMsRUFBRTtNQUN0Q1ksTUFBTSxFQUFFMUYsNEJBQTRCO01BQ3BDMkYsVUFBVSxFQUFFO0lBQ2QsQ0FBQyxDQUFDO0VBQ0osQ0FBQyxDQUFDLE9BQU9wRCxDQUFDLEVBQUU7SUFDVlcsR0FBRyxDQUFDMEMsYUFBYSxDQUNkLDhEQUE2RHJELENBQUMsQ0FBQ3NELE9BQVEsRUFBQyxDQUFDO0VBQzlFLENBQUMsU0FBUztJQUNSckIsZUFBZSxDQUFDVSxNQUFNLENBQUNZLGNBQWMsQ0FBQyxNQUFNLEVBQUVkLGNBQWMsQ0FBQztJQUM3RFIsZUFBZSxDQUFDMUIsTUFBTSxDQUFDZ0QsY0FBYyxDQUFDLE1BQU0sRUFBRVYsZUFBZSxDQUFDO0VBQ2hFO0VBQ0EsT0FBT1osZUFBZTtBQUN4QjtBQUVBLGVBQWV1QixxQkFBcUIsQ0FBRUMsbUJBQW1CLEVBQUVwQyxVQUFVLEVBQUVWLEdBQUcsRUFBRVcsSUFBSSxHQUFHLENBQUMsQ0FBQyxFQUFFO0VBQ3JGLE1BQU07SUFDSkMsS0FBSztJQUNMQyxNQUFNO0lBQ05rQyxPQUFPO0lBQ1BDLE9BQU87SUFDUEMsZ0JBQWdCO0lBQ2hCQztFQUNGLENBQUMsR0FBR3ZDLElBQUk7RUFDUixNQUFNSSxhQUFhLEdBQUdSLFFBQVEsQ0FBQ0ssS0FBSyxFQUFFLEVBQUUsQ0FBQyxJQUFJRixVQUFVLENBQUNFLEtBQUs7RUFDN0QsTUFBTUksY0FBYyxHQUFHVCxRQUFRLENBQUNNLE1BQU0sRUFBRSxFQUFFLENBQUMsSUFBSUgsVUFBVSxDQUFDRyxNQUFNO0VBQ2hFLE1BQU1zQyxpQkFBaUIsR0FBRyxJQUFJQyx3QkFBVSxDQUFDckcsZ0JBQWdCLEVBQUUsQ0FDekQsSUFBSSxFQUNKLE9BQU8sRUFBRSxNQUFNLEVBQ2YsR0FBRyxFQUFFLGVBQWUsR0FDakIsU0FBUWtHLGdCQUFnQixHQUFHSSxJQUFJLENBQUNDLEdBQUcsQ0FBQ3ZDLGFBQWEsRUFBRUMsY0FBYyxDQUFDLEdBQUdELGFBQWMsR0FBRSxHQUNyRixVQUFTa0MsZ0JBQWdCLEdBQUdJLElBQUksQ0FBQ0MsR0FBRyxDQUFDdkMsYUFBYSxFQUFFQyxjQUFjLENBQUMsR0FBR0EsY0FBZSxHQUFFLEdBQ3ZGLGFBQVlOLFVBQVUsQ0FBQzZDLEdBQUksS0FBSSxHQUNoQyxrQkFBa0IsRUFDcEIsR0FBRyxFQUFFLFdBQVcsRUFDaEIsR0FBRyxFQUFFLE9BQU8sRUFBRSxrQkFBa0IsRUFDaEMsR0FBRyxFQUFFLFlBQVksRUFDakIsR0FBRyxFQUFFLE9BQU8sRUFBRSxrQkFBa0IsRUFDaEMsR0FBRyxFQUFFLFNBQVMsRUFBRyxXQUFVUixPQUFRLEVBQUMsRUFDcEMsR0FBRyxFQUFFLGNBQWMsRUFBRyxZQUFXL0UsZUFBZ0IsRUFBQyxFQUNsRCxHQUFHLEVBQUUsZUFBZSxFQUFHLFFBQU9KLFFBQVMsRUFBQyxFQUFHLFFBQU9vRixPQUFRLEVBQUMsQ0FDNUQsRUFBRTtJQUNEUSxLQUFLLEVBQUUsQ0FBQ1YsbUJBQW1CLENBQUNsRCxNQUFNLEVBQUUsTUFBTSxFQUFFLE1BQU07RUFDcEQsQ0FBQyxDQUFDO0VBQ0Z1RCxpQkFBaUIsQ0FBQzFCLEVBQUUsQ0FBQyxNQUFNLEVBQUUsQ0FBQ0MsSUFBSSxFQUFFQyxNQUFNLEtBQUs7SUFDN0MzQixHQUFHLENBQUNNLEtBQUssQ0FBRSwrQ0FBOENvQixJQUFLLFlBQVdDLE1BQU8sRUFBQyxDQUFDO0VBQ3BGLENBQUMsQ0FBQztFQUNGLE1BQU04QixlQUFlLEdBQUd2RixxQkFBcUIsQ0FBQyxLQUFLLEVBQUV3QyxVQUFVLENBQUN0QyxJQUFJLENBQUM7RUFDckUsTUFBTXNGLGlCQUFpQixHQUFHLENBQUM5RCxNQUFNLEVBQUVvQyxNQUFNLEtBQUs7SUFDNUMsSUFBSXpELGVBQUMsQ0FBQ00sSUFBSSxDQUFDbUQsTUFBTSxJQUFJcEMsTUFBTSxDQUFDLEVBQUU7TUFDNUI2RCxlQUFlLENBQUNuRCxLQUFLLENBQUMwQixNQUFNLElBQUlwQyxNQUFNLENBQUM7SUFDekM7RUFDRixDQUFDO0VBQ0R1RCxpQkFBaUIsQ0FBQzFCLEVBQUUsQ0FBQyxRQUFRLEVBQUVpQyxpQkFBaUIsQ0FBQztFQUNqRCxJQUFJQyxPQUFPLEdBQUcsS0FBSztFQUNuQixJQUFJO0lBQ0YzRCxHQUFHLENBQUNvQyxJQUFJLENBQUUsZ0NBQStCZSxpQkFBaUIsQ0FBQ1MsR0FBSSxFQUFDLENBQUM7SUFDakUsTUFBTVQsaUJBQWlCLENBQUNVLEtBQUssQ0FBQyxDQUFDLENBQUM7SUFDaEMsTUFBTSxJQUFBdEIsMEJBQWdCLEVBQUMsWUFBWTtNQUNqQyxJQUFJO1FBQ0YsT0FBTyxDQUFDLE1BQU0sSUFBQXVCLDRCQUFlLEVBQUNkLE9BQU8sRUFBRXBGLFFBQVEsQ0FBQyxNQUFNLE1BQU07TUFDOUQsQ0FBQyxDQUFDLE9BQU9tRyxHQUFHLEVBQUU7UUFDWixPQUFPLEtBQUs7TUFDZDtJQUNGLENBQUMsRUFBRTtNQUNEdkIsTUFBTSxFQUFFMUYsNEJBQTRCO01BQ3BDMkYsVUFBVSxFQUFFO0lBQ2QsQ0FBQyxDQUFDO0VBQ0osQ0FBQyxDQUFDLE9BQU9wRCxDQUFDLEVBQUU7SUFDVnNFLE9BQU8sR0FBRyxJQUFJO0lBQ2QzRCxHQUFHLENBQUMwQyxhQUFhLENBQ2QsK0RBQThEckQsQ0FBQyxDQUFDc0QsT0FBUSxFQUFDLENBQUM7RUFDL0UsQ0FBQyxTQUFTO0lBQ1IsSUFBSSxDQUFDTyxrQkFBa0IsSUFBSVMsT0FBTyxFQUFFO01BQ2xDUixpQkFBaUIsQ0FBQ1AsY0FBYyxDQUFDLFFBQVEsRUFBRWMsaUJBQWlCLENBQUM7SUFDL0Q7RUFDRjtFQUNBLE9BQU9QLGlCQUFpQjtBQUMxQjtBQUVBLFNBQVNhLG9CQUFvQixDQUFFQyxHQUFHLEVBQUU7RUFDbEMsT0FBT0EsR0FBRyxDQUFDQyxPQUFPLENBQUMsaUJBQWlCLENBQUMsSUFDaENELEdBQUcsQ0FBQ0UsTUFBTSxDQUFDQyxhQUFhLElBQ3hCSCxHQUFHLENBQUNJLFVBQVUsQ0FBQ0QsYUFBYSxJQUM1QkgsR0FBRyxDQUFDSSxVQUFVLENBQUNGLE1BQU0sQ0FBQ0MsYUFBYTtBQUMxQzs7QUEyQ0F4SCxRQUFRLENBQUMwSCwwQkFBMEIsR0FBRyxlQUFlQSwwQkFBMEIsQ0FBRUMsT0FBTyxHQUFHLENBQUMsQ0FBQyxFQUFFO0VBQzdGLElBQUksQ0FBQ0Msb0JBQW9CLENBQUN2Ryw0QkFBNEIsQ0FBQztFQUV2RCxNQUFNO0lBQ0oyQyxLQUFLO0lBQ0xDLE1BQU07SUFDTkMsT0FBTztJQUNQMkQsSUFBSSxHQUFHOUcsWUFBWTtJQUNuQitHLElBQUksR0FBRzdHLFlBQVk7SUFDbkI4RyxRQUFRO0lBQ1IzQixPQUFPLEdBQUduRixZQUFZLEdBQUcsQ0FBQztJQUMxQmtGLE9BQU8sR0FBR2pGLGVBQWU7SUFDekJtRixnQkFBZ0IsR0FBRyxLQUFLO0lBQ3hCQyxrQkFBa0IsR0FBRztFQUN2QixDQUFDLEdBQUdxQixPQUFPO0VBRVgsSUFBSWhHLGVBQUMsQ0FBQ3FHLFdBQVcsQ0FBQyxJQUFJLENBQUNDLHFCQUFxQixDQUFDLEVBQUU7SUFDN0MsTUFBTWxHLDJCQUEyQixDQUFDLElBQUksQ0FBQ0MsR0FBRyxDQUFDO0VBQzdDO0VBQ0EsSUFBSSxDQUFDTCxlQUFDLENBQUM0RCxPQUFPLENBQUMsSUFBSSxDQUFDMEMscUJBQXFCLENBQUMsRUFBRTtJQUMxQyxJQUFJLENBQUM3RSxHQUFHLENBQUNvQyxJQUFJLENBQUUsbURBQWtELEdBQzlELDRDQUEyQyxDQUFDO0lBQy9DO0VBQ0Y7RUFDQSxJQUFJLENBQUMsTUFBTSxJQUFBMEIsNEJBQWUsRUFBQ1ksSUFBSSxFQUFFRCxJQUFJLENBQUMsTUFBTSxNQUFNLEVBQUU7SUFDbEQsSUFBSSxDQUFDekUsR0FBRyxDQUFDb0MsSUFBSSxDQUFFLGFBQVlzQyxJQUFLLE9BQU1ELElBQUssWUFBVyxHQUNuRCxrREFBaUQsQ0FBQztJQUNyRDtFQUNGO0VBQ0EsSUFBSSxDQUFDLE1BQU0sSUFBQVgsNEJBQWUsRUFBQ2QsT0FBTyxFQUFFcEYsUUFBUSxDQUFDLE1BQU0sTUFBTSxFQUFFO0lBQ3pELElBQUksQ0FBQ29DLEdBQUcsQ0FBQzBDLGFBQWEsQ0FBRSxhQUFZTSxPQUFRLE9BQU1wRixRQUFTLFlBQVcsR0FDbkUsMERBQXlELENBQUM7RUFDL0Q7RUFDQSxJQUFJLENBQUNpSCxxQkFBcUIsR0FBRyxJQUFJO0VBRWpDLE1BQU1uRSxVQUFVLEdBQUcsTUFBTVgsYUFBYSxDQUFDLElBQUksQ0FBQ25CLEdBQUcsRUFBRSxJQUFJLENBQUNvQixHQUFHLENBQUM7RUFDMUQsTUFBTThDLG1CQUFtQixHQUFHLE1BQU1yQyx1QkFBdUIsQ0FBQyxJQUFJLENBQUM3QixHQUFHLEVBQUUsSUFBSSxDQUFDb0IsR0FBRyxFQUFFVSxVQUFVLEVBQUU7SUFDeEZFLEtBQUs7SUFDTEMsTUFBTTtJQUNOQztFQUNGLENBQUMsQ0FBQztFQUNGLElBQUlxQyxpQkFBaUI7RUFDckIsSUFBSTtJQUNGQSxpQkFBaUIsR0FBRyxNQUFNTixxQkFBcUIsQ0FBQ0MsbUJBQW1CLEVBQUVwQyxVQUFVLEVBQUUsSUFBSSxDQUFDVixHQUFHLEVBQUU7TUFDekZZLEtBQUs7TUFDTEMsTUFBTTtNQUNOa0MsT0FBTztNQUNQQyxPQUFPO01BQ1BDLGdCQUFnQjtNQUNoQkM7SUFDRixDQUFDLENBQUM7RUFDSixDQUFDLENBQUMsT0FBTzdELENBQUMsRUFBRTtJQUNWLElBQUl5RCxtQkFBbUIsQ0FBQ2dDLElBQUksQ0FBQyxDQUFDLENBQUMsRUFBRTtNQUMvQmhDLG1CQUFtQixDQUFDZ0MsSUFBSSxFQUFFO0lBQzVCO0lBQ0EsTUFBTXpGLENBQUM7RUFDVDtFQUVBLElBQUkwRixXQUFXO0VBQ2YsSUFBSUMsV0FBVztFQUNmLElBQUk7SUFDRixNQUFNLElBQUkxRixpQkFBQyxDQUFDLENBQUMyRixPQUFPLEVBQUVDLE1BQU0sS0FBSztNQUMvQkgsV0FBVyxHQUFHSSxZQUFHLENBQUNDLGdCQUFnQixDQUFDcEMsT0FBTyxFQUFFcEYsUUFBUSxFQUFFLE1BQU07UUFDMUQsSUFBSSxDQUFDb0MsR0FBRyxDQUFDb0MsSUFBSSxDQUFFLG1EQUFrRHhFLFFBQVMsSUFBR29GLE9BQVEsRUFBQyxDQUFDO1FBQ3ZGZ0MsV0FBVyxHQUFHSyxhQUFJLENBQUNDLFlBQVksQ0FBQyxDQUFDckIsR0FBRyxFQUFFc0IsR0FBRyxLQUFLO1VBQzVDLE1BQU1uQixhQUFhLEdBQUdKLG9CQUFvQixDQUFDQyxHQUFHLENBQUM7VUFDL0MsTUFBTXVCLGVBQWUsR0FBR0MsWUFBRyxDQUFDQyxLQUFLLENBQUN6QixHQUFHLENBQUN3QixHQUFHLENBQUMsQ0FBQ2QsUUFBUTtVQUNuRCxJQUFJLENBQUMzRSxHQUFHLENBQUNvQyxJQUFJLENBQUUsbURBQWtEZ0MsYUFBYyxHQUFFLEdBQzlFLElBQUdILEdBQUcsQ0FBQ0MsT0FBTyxDQUFDLFlBQVksQ0FBQyxJQUFJLG9CQUFxQixRQUFPc0IsZUFBZ0IsRUFBQyxDQUFDO1VBRWpGLElBQUliLFFBQVEsSUFBSWEsZUFBZSxLQUFLYixRQUFRLEVBQUU7WUFDNUMsSUFBSSxDQUFDM0UsR0FBRyxDQUFDb0MsSUFBSSxDQUFDLDRFQUE0RSxDQUFDO1lBQzNGbUQsR0FBRyxDQUFDSSxTQUFTLENBQUMsR0FBRyxFQUFFO2NBQ2pCQyxVQUFVLEVBQUUsT0FBTztjQUNuQixjQUFjLEVBQUU7WUFDbEIsQ0FBQyxDQUFDO1lBQ0ZMLEdBQUcsQ0FBQ00sS0FBSyxDQUFFLElBQUdMLGVBQWdCLHFDQUFvQyxDQUFDO1lBQ25FRCxHQUFHLENBQUNPLEdBQUcsRUFBRTtZQUNUO1VBQ0Y7VUFFQSxJQUFJLENBQUM5RixHQUFHLENBQUNvQyxJQUFJLENBQUMsMEJBQTBCLENBQUM7VUFDekNtRCxHQUFHLENBQUNJLFNBQVMsQ0FBQyxHQUFHLEVBQUU7WUFDakIsZUFBZSxFQUFFLDJFQUEyRTtZQUM1RkksTUFBTSxFQUFFLFVBQVU7WUFDbEJILFVBQVUsRUFBRSxPQUFPO1lBQ25CLGNBQWMsRUFBRyx1Q0FBc0M1SCxlQUFnQjtVQUN6RSxDQUFDLENBQUM7VUFFRitHLFdBQVcsQ0FBQ2lCLElBQUksQ0FBQ1QsR0FBRyxDQUFDO1FBQ3ZCLENBQUMsQ0FBQztRQUNGUCxXQUFXLENBQUN2RCxFQUFFLENBQUMsT0FBTyxFQUFHcEMsQ0FBQyxJQUFLO1VBQzdCLElBQUksQ0FBQ1csR0FBRyxDQUFDaUcsSUFBSSxDQUFDNUcsQ0FBQyxDQUFDO1VBQ2hCNkYsTUFBTSxDQUFDN0YsQ0FBQyxDQUFDO1FBQ1gsQ0FBQyxDQUFDO1FBQ0YyRixXQUFXLENBQUN2RCxFQUFFLENBQUMsT0FBTyxFQUFFLE1BQU07VUFDNUIsSUFBSSxDQUFDekIsR0FBRyxDQUFDTSxLQUFLLENBQUUsMEJBQXlCbUUsSUFBSyxJQUFHQyxJQUFLLGtCQUFpQixDQUFDO1FBQzFFLENBQUMsQ0FBQztRQUNGTSxXQUFXLENBQUN2RCxFQUFFLENBQUMsV0FBVyxFQUFFLE1BQU07VUFDaEMsSUFBSSxDQUFDekIsR0FBRyxDQUFDb0MsSUFBSSxDQUFFLCtDQUE4Q3FDLElBQUssSUFBR0MsSUFBSyxFQUFDLENBQUM7VUFDNUVPLE9BQU8sRUFBRTtRQUNYLENBQUMsQ0FBQztRQUNGRCxXQUFXLENBQUNrQixNQUFNLENBQUN4QixJQUFJLEVBQUVELElBQUksQ0FBQztNQUNoQyxDQUFDLENBQUM7TUFDRk0sV0FBVyxDQUFDdEQsRUFBRSxDQUFDLE9BQU8sRUFBR3BDLENBQUMsSUFBSztRQUM3QixJQUFJLENBQUNXLEdBQUcsQ0FBQ21HLEtBQUssQ0FBQzlHLENBQUMsQ0FBQztRQUNqQjZGLE1BQU0sQ0FBQzdGLENBQUMsQ0FBQztNQUNYLENBQUMsQ0FBQztJQUNKLENBQUMsQ0FBQyxDQUFDK0csT0FBTyxDQUFDdEosNEJBQTRCLEVBQ3BDLGlEQUFnREEsNEJBQTZCLElBQUcsQ0FBQztFQUN0RixDQUFDLENBQUMsT0FBT3VDLENBQUMsRUFBRTtJQUNWLElBQUl5RCxtQkFBbUIsQ0FBQ2dDLElBQUksQ0FBQyxDQUFDLENBQUMsRUFBRTtNQUMvQmhDLG1CQUFtQixDQUFDZ0MsSUFBSSxFQUFFO0lBQzVCO0lBQ0EsSUFBSTNCLGlCQUFpQixDQUFDa0QsU0FBUyxFQUFFO01BQy9CLE1BQU1sRCxpQkFBaUIsQ0FBQ21ELElBQUksRUFBRTtJQUNoQztJQUNBLElBQUl2QixXQUFXLEVBQUU7TUFDZkEsV0FBVyxDQUFDd0IsT0FBTyxFQUFFO0lBQ3ZCO0lBQ0EsSUFBSXZCLFdBQVcsSUFBSUEsV0FBVyxDQUFDd0IsU0FBUyxFQUFFO01BQ3hDeEIsV0FBVyxDQUFDeUIsS0FBSyxFQUFFO0lBQ3JCO0lBQ0EsTUFBTXBILENBQUM7RUFDVDtFQUVBLElBQUksQ0FBQ3dGLHFCQUFxQixHQUFHO0lBQzNCL0IsbUJBQW1CO0lBQ25CSyxpQkFBaUI7SUFDakI0QixXQUFXO0lBQ1hDO0VBQ0YsQ0FBQztBQUNILENBQUM7O0FBTURwSSxRQUFRLENBQUM4Six5QkFBeUIsR0FBRyxlQUFlQSx5QkFBeUI7QUFBQSxFQUFzQjtFQUNqRyxJQUFJbkksZUFBQyxDQUFDNEQsT0FBTyxDQUFDLElBQUksQ0FBQzBDLHFCQUFxQixDQUFDLEVBQUU7SUFDekMsSUFBSSxDQUFDdEcsZUFBQyxDQUFDcUcsV0FBVyxDQUFDLElBQUksQ0FBQ0MscUJBQXFCLENBQUMsRUFBRTtNQUM5QyxJQUFJLENBQUM3RSxHQUFHLENBQUNNLEtBQUssQ0FBRSwyREFBMEQsQ0FBQztJQUM3RTtJQUNBO0VBQ0Y7RUFFQSxNQUFNO0lBQ0p3QyxtQkFBbUI7SUFDbkJLLGlCQUFpQjtJQUNqQjRCLFdBQVc7SUFDWEM7RUFDRixDQUFDLEdBQUcsSUFBSSxDQUFDSCxxQkFBcUI7RUFFOUIsSUFBSTtJQUNGRSxXQUFXLENBQUNlLEdBQUcsRUFBRTtJQUNqQixJQUFJZCxXQUFXLENBQUN3QixTQUFTLEVBQUU7TUFDekJ4QixXQUFXLENBQUN5QixLQUFLLEVBQUU7SUFDckI7SUFDQSxJQUFJM0QsbUJBQW1CLENBQUNnQyxJQUFJLENBQUMsQ0FBQyxDQUFDLEVBQUU7TUFDL0JoQyxtQkFBbUIsQ0FBQ2dDLElBQUksQ0FBQyxRQUFRLENBQUM7SUFDcEM7SUFDQSxJQUFJM0IsaUJBQWlCLENBQUNrRCxTQUFTLEVBQUU7TUFDL0IsSUFBSTtRQUNGLE1BQU1sRCxpQkFBaUIsQ0FBQ21ELElBQUksQ0FBQyxRQUFRLENBQUM7TUFDeEMsQ0FBQyxDQUFDLE9BQU9qSCxDQUFDLEVBQUU7UUFDVixJQUFJLENBQUNXLEdBQUcsQ0FBQ2lHLElBQUksQ0FBQzVHLENBQUMsQ0FBQztRQUNoQixJQUFJO1VBQ0YsTUFBTThELGlCQUFpQixDQUFDbUQsSUFBSSxDQUFDLFNBQVMsQ0FBQztRQUN6QyxDQUFDLENBQUMsT0FBT0ssRUFBRSxFQUFFO1VBQ1gsSUFBSSxDQUFDM0csR0FBRyxDQUFDbUcsS0FBSyxDQUFDUSxFQUFFLENBQUM7UUFDcEI7TUFDRjtJQUNGO0lBQ0EsSUFBSSxDQUFDM0csR0FBRyxDQUFDb0MsSUFBSSxDQUFFLDJEQUEwRCxDQUFDO0VBQzVFLENBQUMsU0FBUztJQUNSLElBQUksQ0FBQ3lDLHFCQUFxQixHQUFHLElBQUk7RUFDbkM7QUFDRixDQUFDO0FBQUMsZUFHYWpJLFFBQVE7QUFBQSJ9
354
+ //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJjb21tYW5kcyIsIlJFQ09SRElOR19JTlRFUlZBTF9TRUMiLCJTVFJFQU1JTkdfU1RBUlRVUF9USU1FT1VUX01TIiwiR1NUUkVBTUVSX0JJTkFSWSIsInN5c3RlbSIsImlzV2luZG93cyIsIkdTVF9JTlNQRUNUX0JJTkFSWSIsIlJFUVVJUkVEX0dTVF9QTFVHSU5TIiwiYXZkZWNfaDI2NCIsImgyNjRwYXJzZSIsImpwZWdlbmMiLCJ0Y3BzZXJ2ZXJzaW5rIiwibXVsdGlwYXJ0bXV4IiwiU0NSRUVOUkVDT1JEX0JJTkFSWSIsIkdTVF9UVVRPUklBTF9VUkwiLCJERUZBVUxUX0hPU1QiLCJUQ1BfSE9TVCIsIkRFRkFVTFRfUE9SVCIsIkRFRkFVTFRfUVVBTElUWSIsIkRFRkFVTFRfQklUUkFURSIsIkJPVU5EQVJZX1NUUklORyIsIkFEQl9TQ1JFRU5fU1RSRUFNSU5HX0ZFQVRVUkUiLCJjcmVhdGVTdHJlYW1pbmdMb2dnZXIiLCJzdHJlYW1OYW1lIiwidWRpZCIsImxvZ2dlciIsImdldExvZ2dlciIsIl8iLCJ0cnVuY2F0ZSIsImxlbmd0aCIsIm9taXNzaW9uIiwidmVyaWZ5U3RyZWFtaW5nUmVxdWlyZW1lbnRzIiwiYWRiIiwidHJpbSIsInNoZWxsIiwiRXJyb3IiLCJnc3RyZWFtZXJDaGVja1Byb21pc2VzIiwiYmluYXJ5TmFtZSIsInB1c2giLCJmcyIsIndoaWNoIiwiZSIsIkIiLCJhbGwiLCJtb2R1bGVDaGVja1Byb21pc2VzIiwibmFtZSIsIm1vZE5hbWUiLCJ0b1BhaXJzIiwic3Rkb3V0IiwiZXhlYyIsImluY2x1ZGVzIiwiZ2V0RGV2aWNlSW5mbyIsImxvZyIsIm91dHB1dCIsInJlc3VsdCIsImtleSIsInBhdHRlcm4iLCJtYXRjaCIsImRlYnVnIiwicGFyc2VJbnQiLCJjdXJEZXZpY2VJZCIsImluaXREZXZpY2VTdHJlYW1pbmdQcm9jIiwiZGV2aWNlSW5mbyIsIm9wdHMiLCJ3aWR0aCIsImhlaWdodCIsImJpdFJhdGUiLCJhZGp1c3RlZFdpZHRoIiwiYWRqdXN0ZWRIZWlnaHQiLCJhZGp1c3RlZEJpdHJhdGUiLCJzY3JlZW5SZWNvcmRDbWQiLCJhZGJBcmdzIiwiZXhlY3V0YWJsZSIsImRlZmF1bHRBcmdzIiwiZGV2aWNlU3RyZWFtaW5nIiwic3Bhd24iLCJwYXRoIiwib24iLCJjb2RlIiwic2lnbmFsIiwiaXNTdGFydGVkIiwiZGV2aWNlU3RyZWFtaW5nTG9nZ2VyIiwiZXJyb3JzTGlzdGVuZXIiLCJjaHVuayIsInN0ZGVyciIsInRvU3RyaW5nIiwic3RhcnR1cExpc3RlbmVyIiwiaXNFbXB0eSIsImluZm8iLCJ1dGlsIiwicXVvdGUiLCJ3YWl0Rm9yQ29uZGl0aW9uIiwid2FpdE1zIiwiaW50ZXJ2YWxNcyIsImVycm9yQW5kVGhyb3ciLCJtZXNzYWdlIiwicmVtb3ZlTGlzdGVuZXIiLCJpbml0R3N0cmVhbWVyUGlwZWxpbmUiLCJkZXZpY2VTdHJlYW1pbmdQcm9jIiwicXVhbGl0eSIsInRjcFBvcnQiLCJjb25zaWRlclJvdGF0aW9uIiwibG9nUGlwZWxpbmVEZXRhaWxzIiwiZ3N0cmVhbWVyUGlwZWxpbmUiLCJTdWJQcm9jZXNzIiwiTWF0aCIsIm1heCIsImZwcyIsInN0ZGlvIiwiZ3N0cmVhbWVyTG9nZ2VyIiwiZ3N0T3V0cHV0TGlzdGVuZXIiLCJkaWRGYWlsIiwicmVwIiwic3RhcnQiLCJjaGVja1BvcnRTdGF0dXMiLCJpZ24iLCJleHRyYWN0UmVtb3RlQWRkcmVzcyIsInJlcSIsImhlYWRlcnMiLCJzb2NrZXQiLCJyZW1vdGVBZGRyZXNzIiwiY29ubmVjdGlvbiIsIm1vYmlsZVN0YXJ0U2NyZWVuU3RyZWFtaW5nIiwib3B0aW9ucyIsImVuc3VyZUZlYXR1cmVFbmFibGVkIiwiaG9zdCIsInBvcnQiLCJwYXRobmFtZSIsImlzVW5kZWZpbmVkIiwiX3NjcmVlblN0cmVhbWluZ1Byb3BzIiwia2lsbCIsIm1qcGVnU29ja2V0IiwibWpwZWdTZXJ2ZXIiLCJyZXNvbHZlIiwicmVqZWN0IiwibmV0IiwiY3JlYXRlQ29ubmVjdGlvbiIsImh0dHAiLCJjcmVhdGVTZXJ2ZXIiLCJyZXMiLCJjdXJyZW50UGF0aG5hbWUiLCJ1cmwiLCJwYXJzZSIsIndyaXRlSGVhZCIsIkNvbm5lY3Rpb24iLCJ3cml0ZSIsImVuZCIsIlByYWdtYSIsInBpcGUiLCJ3YXJuIiwibGlzdGVuIiwiZXJyb3IiLCJ0aW1lb3V0IiwiaXNSdW5uaW5nIiwic3RvcCIsImRlc3Ryb3kiLCJsaXN0ZW5pbmciLCJjbG9zZSIsIm1vYmlsZVN0b3BTY3JlZW5TdHJlYW1pbmciLCJlMSJdLCJzb3VyY2VzIjpbIi4uLy4uLy4uL2xpYi9jb21tYW5kcy9zdHJlYW1zY3JlZW4uanMiXSwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IF8gZnJvbSAnbG9kYXNoJztcbmltcG9ydCB7IGZzLCBzeXN0ZW0sIGxvZ2dlciwgdXRpbCB9IGZyb20gJ0BhcHBpdW0vc3VwcG9ydCc7XG5pbXBvcnQgeyBleGVjLCBTdWJQcm9jZXNzIH0gZnJvbSAndGVlbl9wcm9jZXNzJztcbmltcG9ydCB7IGNoZWNrUG9ydFN0YXR1cyB9IGZyb20gJ3BvcnRzY2FubmVyJztcbmltcG9ydCBodHRwIGZyb20gJ2h0dHAnO1xuaW1wb3J0IG5ldCBmcm9tICduZXQnO1xuaW1wb3J0IEIgZnJvbSAnYmx1ZWJpcmQnO1xuaW1wb3J0IHsgd2FpdEZvckNvbmRpdGlvbiB9IGZyb20gJ2FzeW5jYm94JztcbmltcG9ydCB7IHNwYXduIH0gZnJvbSAnY2hpbGRfcHJvY2Vzcyc7XG5pbXBvcnQgdXJsIGZyb20gJ3VybCc7XG5cbmNvbnN0IGNvbW1hbmRzID0ge307XG5cbmNvbnN0IFJFQ09SRElOR19JTlRFUlZBTF9TRUMgPSA1O1xuY29uc3QgU1RSRUFNSU5HX1NUQVJUVVBfVElNRU9VVF9NUyA9IDUwMDA7XG5jb25zdCBHU1RSRUFNRVJfQklOQVJZID0gYGdzdC1sYXVuY2gtMS4wJHtzeXN0ZW0uaXNXaW5kb3dzKCkgPyAnLmV4ZScgOiAnJ31gO1xuY29uc3QgR1NUX0lOU1BFQ1RfQklOQVJZID0gYGdzdC1pbnNwZWN0LTEuMCR7c3lzdGVtLmlzV2luZG93cygpID8gJy5leGUnIDogJyd9YDtcbmNvbnN0IFJFUVVJUkVEX0dTVF9QTFVHSU5TID0ge1xuICBhdmRlY19oMjY0OiAnZ3N0LWxpYmF2JyxcbiAgaDI2NHBhcnNlOiAnZ3N0LXBsdWdpbnMtYmFkJyxcbiAganBlZ2VuYzogJ2dzdC1wbHVnaW5zLWdvb2QnLFxuICB0Y3BzZXJ2ZXJzaW5rOiAnZ3N0LXBsdWdpbnMtYmFzZScsXG4gIG11bHRpcGFydG11eDogJ2dzdC1wbHVnaW5zLWdvb2QnLFxufTtcbmNvbnN0IFNDUkVFTlJFQ09SRF9CSU5BUlkgPSAnc2NyZWVucmVjb3JkJztcbmNvbnN0IEdTVF9UVVRPUklBTF9VUkwgPSAnaHR0cHM6Ly9nc3RyZWFtZXIuZnJlZWRlc2t0b3Aub3JnL2RvY3VtZW50YXRpb24vaW5zdGFsbGluZy9pbmRleC5odG1sJztcbmNvbnN0IERFRkFVTFRfSE9TVCA9ICcxMjcuMC4wLjEnO1xuY29uc3QgVENQX0hPU1QgPSAnMTI3LjAuMC4xJztcbmNvbnN0IERFRkFVTFRfUE9SVCA9IDgwOTM7XG5jb25zdCBERUZBVUxUX1FVQUxJVFkgPSA3MDtcbmNvbnN0IERFRkFVTFRfQklUUkFURSA9IDQwMDAwMDA7IC8vIDQgTWJwc1xuY29uc3QgQk9VTkRBUllfU1RSSU5HID0gJy0tMmFlOTc0Njg4N2YxNzBiOGNmN2MyNzEwNDdjZTMxNGMnO1xuXG5jb25zdCBBREJfU0NSRUVOX1NUUkVBTUlOR19GRUFUVVJFID0gJ2FkYl9zY3JlZW5fc3RyZWFtaW5nJztcblxuZnVuY3Rpb24gY3JlYXRlU3RyZWFtaW5nTG9nZ2VyIChzdHJlYW1OYW1lLCB1ZGlkKSB7XG4gIHJldHVybiBsb2dnZXIuZ2V0TG9nZ2VyKGAke3N0cmVhbU5hbWV9QGAgKyBfLnRydW5jYXRlKHVkaWQsIHtcbiAgICBsZW5ndGg6IDgsXG4gICAgb21pc3Npb246ICcnLFxuICB9KSk7XG59XG5cbmFzeW5jIGZ1bmN0aW9uIHZlcmlmeVN0cmVhbWluZ1JlcXVpcmVtZW50cyAoYWRiKSB7XG4gIGlmICghXy50cmltKGF3YWl0IGFkYi5zaGVsbChbJ3doaWNoJywgU0NSRUVOUkVDT1JEX0JJTkFSWV0pKSkge1xuICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgIGBUaGUgcmVxdWlyZWQgJyR7U0NSRUVOUkVDT1JEX0JJTkFSWX0nIGJpbmFyeSBpcyBub3QgYXZhaWxhYmxlIG9uIHRoZSBkZXZpY2UgdW5kZXIgdGVzdGApO1xuICB9XG5cbiAgY29uc3QgZ3N0cmVhbWVyQ2hlY2tQcm9taXNlcyA9IFtdO1xuICBmb3IgKGNvbnN0IGJpbmFyeU5hbWUgb2YgW0dTVFJFQU1FUl9CSU5BUlksIEdTVF9JTlNQRUNUX0JJTkFSWV0pIHtcbiAgICBnc3RyZWFtZXJDaGVja1Byb21pc2VzLnB1c2goKGFzeW5jICgpID0+IHtcbiAgICAgIHRyeSB7XG4gICAgICAgIGF3YWl0IGZzLndoaWNoKGJpbmFyeU5hbWUpO1xuICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYFRoZSAnJHtiaW5hcnlOYW1lfScgYmluYXJ5IGlzIG5vdCBhdmFpbGFibGUgaW4gdGhlIFBBVEggb24gdGhlIGhvc3Qgc3lzdGVtLiBgICtcbiAgICAgICAgICBgU2VlICR7R1NUX1RVVE9SSUFMX1VSTH0gZm9yIG1vcmUgZGV0YWlscyBvbiBob3cgdG8gaW5zdGFsbCBpdC5gKTtcbiAgICAgIH1cbiAgICB9KSgpKTtcbiAgfVxuICBhd2FpdCBCLmFsbChnc3RyZWFtZXJDaGVja1Byb21pc2VzKTtcblxuICBjb25zdCBtb2R1bGVDaGVja1Byb21pc2VzID0gW107XG4gIGZvciAoY29uc3QgW25hbWUsIG1vZE5hbWVdIG9mIF8udG9QYWlycyhSRVFVSVJFRF9HU1RfUExVR0lOUykpIHtcbiAgICBtb2R1bGVDaGVja1Byb21pc2VzLnB1c2goKGFzeW5jICgpID0+IHtcbiAgICAgIGNvbnN0IHtzdGRvdXR9ID0gYXdhaXQgZXhlYyhHU1RfSU5TUEVDVF9CSU5BUlksIFtuYW1lXSk7XG4gICAgICBpZiAoIV8uaW5jbHVkZXMoc3Rkb3V0LCBtb2ROYW1lKSkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICAgICAgYFRoZSByZXF1aXJlZCBHU3RyZWFtZXIgcGx1Z2luICcke25hbWV9JyBmcm9tICcke21vZE5hbWV9JyBtb2R1bGUgaXMgbm90IGluc3RhbGxlZC4gYCArXG4gICAgICAgICAgYFNlZSAke0dTVF9UVVRPUklBTF9VUkx9IGZvciBtb3JlIGRldGFpbHMgb24gaG93IHRvIGluc3RhbGwgaXQuYCk7XG4gICAgICB9XG4gICAgfSkoKSk7XG4gIH1cbiAgYXdhaXQgQi5hbGwobW9kdWxlQ2hlY2tQcm9taXNlcyk7XG59XG5cbmFzeW5jIGZ1bmN0aW9uIGdldERldmljZUluZm8gKGFkYiwgbG9nID0gbnVsbCkge1xuICBjb25zdCBvdXRwdXQgPSBhd2FpdCBhZGIuc2hlbGwoWydkdW1wc3lzJywgJ2Rpc3BsYXknXSk7XG4gIGNvbnN0IHJlc3VsdCA9IHt9O1xuICBmb3IgKGNvbnN0IFtrZXksIHBhdHRlcm5dIG9mIFtcbiAgICBbJ3dpZHRoJywgL1xcYmRldmljZVdpZHRoPShcXGQrKS9dLFxuICAgIFsnaGVpZ2h0JywgL1xcYmRldmljZUhlaWdodD0oXFxkKykvXSxcbiAgICBbJ2ZwcycsIC9cXGJmcHM9KFxcZCspL10sXG4gIF0pIHtcbiAgICBjb25zdCBtYXRjaCA9IHBhdHRlcm4uZXhlYyhvdXRwdXQpO1xuICAgIGlmICghbWF0Y2gpIHtcbiAgICAgIGxvZz8uZGVidWcob3V0cHV0KTtcbiAgICAgIHRocm93IG5ldyBFcnJvcihgQ2Fubm90IHBhcnNlIHRoZSBkZXZpY2UgJHtrZXl9IGZyb20gdGhlIGFkYiBjb21tYW5kIG91dHB1dC4gYCArXG4gICAgICAgIGBDaGVjayB0aGUgc2VydmVyIGxvZyBmb3IgbW9yZSBkZXRhaWxzLmApO1xuICAgIH1cbiAgICByZXN1bHRba2V5XSA9IHBhcnNlSW50KG1hdGNoWzFdLCAxMCk7XG4gIH1cbiAgcmVzdWx0LnVkaWQgPSBhZGIuY3VyRGV2aWNlSWQ7XG4gIHJldHVybiByZXN1bHQ7XG59XG5cbmFzeW5jIGZ1bmN0aW9uIGluaXREZXZpY2VTdHJlYW1pbmdQcm9jIChhZGIsIGxvZywgZGV2aWNlSW5mbywgb3B0cyA9IHt9KSB7XG4gIGNvbnN0IHtcbiAgICB3aWR0aCxcbiAgICBoZWlnaHQsXG4gICAgYml0UmF0ZSxcbiAgfSA9IG9wdHM7XG4gIGNvbnN0IGFkanVzdGVkV2lkdGggPSBwYXJzZUludCh3aWR0aCwgMTApIHx8IGRldmljZUluZm8ud2lkdGg7XG4gIGNvbnN0IGFkanVzdGVkSGVpZ2h0ID0gcGFyc2VJbnQoaGVpZ2h0LCAxMCkgfHwgZGV2aWNlSW5mby5oZWlnaHQ7XG4gIGNvbnN0IGFkanVzdGVkQml0cmF0ZSA9IHBhcnNlSW50KGJpdFJhdGUsIDEwKSB8fCBERUZBVUxUX0JJVFJBVEU7XG4gIGxldCBzY3JlZW5SZWNvcmRDbWQgPSBTQ1JFRU5SRUNPUkRfQklOQVJZICtcbiAgICBgIC0tb3V0cHV0LWZvcm1hdD1oMjY0YCArXG4gICAgLy8gNSBzZWNvbmRzIGlzIGZpbmUgdG8gZGV0ZWN0IHJvdGF0aW9uIGNoYW5nZXNcbiAgICBgIC0tdGltZS1saW1pdD0ke1JFQ09SRElOR19JTlRFUlZBTF9TRUN9YDtcbiAgaWYgKHdpZHRoIHx8IGhlaWdodCkge1xuICAgIHNjcmVlblJlY29yZENtZCArPSBgIC0tc2l6ZT0ke2FkanVzdGVkV2lkdGh9eCR7YWRqdXN0ZWRIZWlnaHR9YDtcbiAgfVxuICBpZiAoYml0UmF0ZSkge1xuICAgIHNjcmVlblJlY29yZENtZCArPSBgIC0tYml0LXJhdGU9JHthZGp1c3RlZEJpdHJhdGV9YDtcbiAgfVxuICBjb25zdCBhZGJBcmdzID0gW1xuICAgIC4uLmFkYi5leGVjdXRhYmxlLmRlZmF1bHRBcmdzLFxuICAgICdleGVjLW91dCcsXG4gICAgLy8gVGhlIGxvb3AgaXMgcmVxdWlyZWQsIGJlY2F1c2UgYnkgZGVmYXVsdCB0aGUgbWF4aW11bSByZWNvcmQgZHVyYXRpb25cbiAgICAvLyBmb3Igc2NyZWVucmVjb3JkIGlzIGFsd2F5cyBsaW1pdGVkXG4gICAgYHdoaWxlIHRydWU7IGRvICR7c2NyZWVuUmVjb3JkQ21kfSAtOyBkb25lYCxcbiAgXTtcbiAgY29uc3QgZGV2aWNlU3RyZWFtaW5nID0gc3Bhd24oYWRiLmV4ZWN1dGFibGUucGF0aCwgYWRiQXJncyk7XG4gIGRldmljZVN0cmVhbWluZy5vbignZXhpdCcsIChjb2RlLCBzaWduYWwpID0+IHtcbiAgICBsb2cuZGVidWcoYERldmljZSBzdHJlYW1pbmcgcHJvY2VzcyBleGl0ZWQgd2l0aCBjb2RlICR7Y29kZX0sIHNpZ25hbCAke3NpZ25hbH1gKTtcbiAgfSk7XG5cbiAgbGV0IGlzU3RhcnRlZCA9IGZhbHNlO1xuICBjb25zdCBkZXZpY2VTdHJlYW1pbmdMb2dnZXIgPSBjcmVhdGVTdHJlYW1pbmdMb2dnZXIoU0NSRUVOUkVDT1JEX0JJTkFSWSwgZGV2aWNlSW5mby51ZGlkKTtcbiAgY29uc3QgZXJyb3JzTGlzdGVuZXIgPSAoY2h1bmspID0+IHtcbiAgICBjb25zdCBzdGRlcnIgPSBjaHVuay50b1N0cmluZygpO1xuICAgIGlmIChfLnRyaW0oc3RkZXJyKSkge1xuICAgICAgZGV2aWNlU3RyZWFtaW5nTG9nZ2VyLmRlYnVnKHN0ZGVycik7XG4gICAgfVxuICB9O1xuICBkZXZpY2VTdHJlYW1pbmcuc3RkZXJyLm9uKCdkYXRhJywgZXJyb3JzTGlzdGVuZXIpO1xuXG4gIGNvbnN0IHN0YXJ0dXBMaXN0ZW5lciA9IChjaHVuaykgPT4ge1xuICAgIGlmICghaXNTdGFydGVkKSB7XG4gICAgICBpc1N0YXJ0ZWQgPSAhXy5pc0VtcHR5KGNodW5rKTtcbiAgICB9XG4gIH07XG4gIGRldmljZVN0cmVhbWluZy5zdGRvdXQub24oJ2RhdGEnLCBzdGFydHVwTGlzdGVuZXIpO1xuXG4gIHRyeSB7XG4gICAgbG9nLmluZm8oYFN0YXJ0aW5nIGRldmljZSBzdHJlYW1pbmc6ICR7dXRpbC5xdW90ZShbYWRiLmV4ZWN1dGFibGUucGF0aCwgLi4uYWRiQXJnc10pfWApO1xuICAgIGF3YWl0IHdhaXRGb3JDb25kaXRpb24oKCkgPT4gaXNTdGFydGVkLCB7XG4gICAgICB3YWl0TXM6IFNUUkVBTUlOR19TVEFSVFVQX1RJTUVPVVRfTVMsXG4gICAgICBpbnRlcnZhbE1zOiAzMDAsXG4gICAgfSk7XG4gIH0gY2F0Y2ggKGUpIHtcbiAgICBsb2cuZXJyb3JBbmRUaHJvdyhcbiAgICAgIGBDYW5ub3Qgc3RhcnQgdGhlIHNjcmVlbiBzdHJlYW1pbmcgcHJvY2Vzcy4gT3JpZ2luYWwgZXJyb3I6ICR7ZS5tZXNzYWdlfWApO1xuICB9IGZpbmFsbHkge1xuICAgIGRldmljZVN0cmVhbWluZy5zdGRlcnIucmVtb3ZlTGlzdGVuZXIoJ2RhdGEnLCBlcnJvcnNMaXN0ZW5lcik7XG4gICAgZGV2aWNlU3RyZWFtaW5nLnN0ZG91dC5yZW1vdmVMaXN0ZW5lcignZGF0YScsIHN0YXJ0dXBMaXN0ZW5lcik7XG4gIH1cbiAgcmV0dXJuIGRldmljZVN0cmVhbWluZztcbn1cblxuYXN5bmMgZnVuY3Rpb24gaW5pdEdzdHJlYW1lclBpcGVsaW5lIChkZXZpY2VTdHJlYW1pbmdQcm9jLCBkZXZpY2VJbmZvLCBsb2csIG9wdHMgPSB7fSkge1xuICBjb25zdCB7XG4gICAgd2lkdGgsXG4gICAgaGVpZ2h0LFxuICAgIHF1YWxpdHksXG4gICAgdGNwUG9ydCxcbiAgICBjb25zaWRlclJvdGF0aW9uLFxuICAgIGxvZ1BpcGVsaW5lRGV0YWlscyxcbiAgfSA9IG9wdHM7XG4gIGNvbnN0IGFkanVzdGVkV2lkdGggPSBwYXJzZUludCh3aWR0aCwgMTApIHx8IGRldmljZUluZm8ud2lkdGg7XG4gIGNvbnN0IGFkanVzdGVkSGVpZ2h0ID0gcGFyc2VJbnQoaGVpZ2h0LCAxMCkgfHwgZGV2aWNlSW5mby5oZWlnaHQ7XG4gIGNvbnN0IGdzdHJlYW1lclBpcGVsaW5lID0gbmV3IFN1YlByb2Nlc3MoR1NUUkVBTUVSX0JJTkFSWSwgW1xuICAgICctdicsXG4gICAgJ2Zkc3JjJywgJ2ZkPTAnLFxuICAgICchJywgJ3ZpZGVvL3gtaDI2NCwnICtcbiAgICAgIGB3aWR0aD0ke2NvbnNpZGVyUm90YXRpb24gPyBNYXRoLm1heChhZGp1c3RlZFdpZHRoLCBhZGp1c3RlZEhlaWdodCkgOiBhZGp1c3RlZFdpZHRofSxgICtcbiAgICAgIGBoZWlnaHQ9JHtjb25zaWRlclJvdGF0aW9uID8gTWF0aC5tYXgoYWRqdXN0ZWRXaWR0aCwgYWRqdXN0ZWRIZWlnaHQpIDogYWRqdXN0ZWRIZWlnaHR9LGAgK1xuICAgICAgYGZyYW1lcmF0ZT0ke2RldmljZUluZm8uZnBzfS8xLGAgK1xuICAgICAgJ2J5dGUtc3RyZWFtPXRydWUnLFxuICAgICchJywgJ2gyNjRwYXJzZScsXG4gICAgJyEnLCAncXVldWUnLCAnbGVha3k9ZG93bnN0cmVhbScsXG4gICAgJyEnLCAnYXZkZWNfaDI2NCcsXG4gICAgJyEnLCAncXVldWUnLCAnbGVha3k9ZG93bnN0cmVhbScsXG4gICAgJyEnLCAnanBlZ2VuYycsIGBxdWFsaXR5PSR7cXVhbGl0eX1gLFxuICAgICchJywgJ211bHRpcGFydG11eCcsIGBib3VuZGFyeT0ke0JPVU5EQVJZX1NUUklOR31gLFxuICAgICchJywgJ3RjcHNlcnZlcnNpbmsnLCBgaG9zdD0ke1RDUF9IT1NUfWAsIGBwb3J0PSR7dGNwUG9ydH1gLFxuICBdLCB7XG4gICAgc3RkaW86IFtkZXZpY2VTdHJlYW1pbmdQcm9jLnN0ZG91dCwgJ3BpcGUnLCAncGlwZSddXG4gIH0pO1xuICBnc3RyZWFtZXJQaXBlbGluZS5vbignZXhpdCcsIChjb2RlLCBzaWduYWwpID0+IHtcbiAgICBsb2cuZGVidWcoYFBpcGVsaW5lIHN0cmVhbWluZyBwcm9jZXNzIGV4aXRlZCB3aXRoIGNvZGUgJHtjb2RlfSwgc2lnbmFsICR7c2lnbmFsfWApO1xuICB9KTtcbiAgY29uc3QgZ3N0cmVhbWVyTG9nZ2VyID0gY3JlYXRlU3RyZWFtaW5nTG9nZ2VyKCdnc3QnLCBkZXZpY2VJbmZvLnVkaWQpO1xuICBjb25zdCBnc3RPdXRwdXRMaXN0ZW5lciA9IChzdGRvdXQsIHN0ZGVycikgPT4ge1xuICAgIGlmIChfLnRyaW0oc3RkZXJyIHx8IHN0ZG91dCkpIHtcbiAgICAgIGdzdHJlYW1lckxvZ2dlci5kZWJ1ZyhzdGRlcnIgfHwgc3Rkb3V0KTtcbiAgICB9XG4gIH07XG4gIGdzdHJlYW1lclBpcGVsaW5lLm9uKCdvdXRwdXQnLCBnc3RPdXRwdXRMaXN0ZW5lcik7XG4gIGxldCBkaWRGYWlsID0gZmFsc2U7XG4gIHRyeSB7XG4gICAgbG9nLmluZm8oYFN0YXJ0aW5nIEdTdHJlYW1lciBwaXBlbGluZTogJHtnc3RyZWFtZXJQaXBlbGluZS5yZXB9YCk7XG4gICAgYXdhaXQgZ3N0cmVhbWVyUGlwZWxpbmUuc3RhcnQoMCk7XG4gICAgYXdhaXQgd2FpdEZvckNvbmRpdGlvbihhc3luYyAoKSA9PiB7XG4gICAgICB0cnkge1xuICAgICAgICByZXR1cm4gKGF3YWl0IGNoZWNrUG9ydFN0YXR1cyh0Y3BQb3J0LCBUQ1BfSE9TVCkpID09PSAnb3Blbic7XG4gICAgICB9IGNhdGNoIChpZ24pIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgfVxuICAgIH0sIHtcbiAgICAgIHdhaXRNczogU1RSRUFNSU5HX1NUQVJUVVBfVElNRU9VVF9NUyxcbiAgICAgIGludGVydmFsTXM6IDMwMCxcbiAgICB9KTtcbiAgfSBjYXRjaCAoZSkge1xuICAgIGRpZEZhaWwgPSB0cnVlO1xuICAgIGxvZy5lcnJvckFuZFRocm93KFxuICAgICAgYENhbm5vdCBzdGFydCB0aGUgc2NyZWVuIHN0cmVhbWluZyBwaXBlbGluZS4gT3JpZ2luYWwgZXJyb3I6ICR7ZS5tZXNzYWdlfWApO1xuICB9IGZpbmFsbHkge1xuICAgIGlmICghbG9nUGlwZWxpbmVEZXRhaWxzIHx8IGRpZEZhaWwpIHtcbiAgICAgIGdzdHJlYW1lclBpcGVsaW5lLnJlbW92ZUxpc3RlbmVyKCdvdXRwdXQnLCBnc3RPdXRwdXRMaXN0ZW5lcik7XG4gICAgfVxuICB9XG4gIHJldHVybiBnc3RyZWFtZXJQaXBlbGluZTtcbn1cblxuZnVuY3Rpb24gZXh0cmFjdFJlbW90ZUFkZHJlc3MgKHJlcSkge1xuICByZXR1cm4gcmVxLmhlYWRlcnNbJ3gtZm9yd2FyZGVkLWZvciddXG4gICAgfHwgcmVxLnNvY2tldC5yZW1vdGVBZGRyZXNzXG4gICAgfHwgcmVxLmNvbm5lY3Rpb24ucmVtb3RlQWRkcmVzc1xuICAgIHx8IHJlcS5jb25uZWN0aW9uLnNvY2tldC5yZW1vdGVBZGRyZXNzO1xufVxuXG5cbi8qKlxuICogQHR5cGVkZWYge09iamVjdH0gU3RhcnRTY3JlZW5TdHJlYW1pbmdPcHRpb25zXG4gKlxuICogQHByb3BlcnR5IHs/bnVtYmVyfSB3aWR0aCAtIFRoZSBzY2FsZWQgd2lkdGggb2YgdGhlIGRldmljZSdzIHNjcmVlbi4gSWYgdW5zZXQgdGhlbiB0aGUgc2NyaXB0IHdpbGwgYXNzaWduIGl0XG4gKiB0byB0aGUgYWN0dWFsIHNjcmVlbiB3aWR0aCBtZWFzdXJlZCBpbiBwaXhlbHMuXG4gKiBAcHJvcGVydHkgez9udW1iZXJ9IGhlaWdodCAtIFRoZSBzY2FsZWQgaGVpZ2h0IG9mIHRoZSBkZXZpY2UncyBzY3JlZW4uIElmIHVuc2V0IHRoZW4gdGhlIHNjcmlwdCB3aWxsIGFzc2lnbiBpdFxuICogdG8gdGhlIGFjdHVhbCBzY3JlZW4gaGVpZ2h0IG1lYXN1cmVkIGluIHBpeGVscy5cbiAqIEBwcm9wZXJ0eSB7P251bWJlcn0gYml0UmF0ZSAtIFRoZSB2aWRlbyBiaXQgcmF0ZSBmb3IgdGhlIHZpZGVvLCBpbiBiaXRzIHBlciBzZWNvbmQuXG4gKiBUaGUgZGVmYXVsdCB2YWx1ZSBpcyA0MDAwMDAwICg0IE1iL3MpLiBZb3UgY2FuIGluY3JlYXNlIHRoZSBiaXQgcmF0ZSB0byBpbXByb3ZlIHZpZGVvIHF1YWxpdHksXG4gKiBidXQgZG9pbmcgc28gcmVzdWx0cyBpbiBsYXJnZXIgbW92aWUgZmlsZXMuXG4gKiBAcHJvcGVydHkgez9zdHJpbmd9IGhvc3QgWzEyNy4wLjAuMV0gLSBUaGUgSVAgYWRkcmVzcy9ob3N0IG5hbWUgdG8gc3RhcnQgdGhlIE1KUEVHIHNlcnZlciBvbi5cbiAqIFlvdSBjYW4gc2V0IGl0IHRvIGAwLjAuMC4wYCB0byB0cmlnZ2VyIHRoZSBicm9hZGNhc3Qgb24gYWxsIGF2YWlsYWJsZSBuZXR3b3JrIGludGVyZmFjZXMuXG4gKiBAcHJvcGVydHkgez9zdHJpbmd9IHBhdGhuYW1lIC0gVGhlIEhUVFAgcmVxdWVzdCBwYXRoIHRoZSBNSlBFRyBzZXJ2ZXIgc2hvdWxkIGJlIGF2YWlsYWJsZSBvbi5cbiAqIElmIHVuc2V0IHRoZW4gYW55IHBhdGhuYW1lIG9uIHRoZSBnaXZlbiBgaG9zdGAvYHBvcnRgIGNvbWJpbmF0aW9uIHdpbGwgd29yay4gTm90ZSB0aGF0IHRoZSB2YWx1ZVxuICogc2hvdWxkIGFsd2F5cyBzdGFydCB3aXRoIGEgc2luZ2xlIHNsYXNoOiBgL2BcbiAqIEBwcm9wZXJ0eSB7P251bWJlcn0gdGNwUG9ydCBbODA5NF0gLSBUaGUgcG9ydCBudW1iZXIgdG8gc3RhcnQgdGhlIGludGVybmFsIFRDUCBNSlBFRyBicm9hZGNhc3Qgb24uXG4gKiBUaGlzIHR5cGUgb2YgYnJvYWRjYXN0IGFsd2F5cyBzdGFydHMgb24gdGhlIGxvb3BiYWNrIGludGVyZmFjZSAoYDEyNy4wLjAuMWApLlxuICogQHByb3BlcnR5IHs/bnVtYmVyfSBwb3J0IFs4MDkzXSAtIFRoZSBwb3J0IG51bWJlciB0byBzdGFydCB0aGUgTUpQRUcgc2VydmVyIG9uLlxuICogQHByb3BlcnR5IHs/bnVtYmVyfSBxdWFsaXR5IFs3MF0gLSBUaGUgcXVhbGl0eSB2YWx1ZSBmb3IgdGhlIHN0cmVhbWVkIEpQRUcgaW1hZ2VzLlxuICogVGhpcyBudW1iZXIgc2hvdWxkIGJlIGluIHJhbmdlIFsxLCAxMDBdLCB3aGVyZSAxMDAgaXMgdGhlIGJlc3QgcXVhbGl0eS5cbiAqIEBwcm9wZXJ0eSB7P2Jvb2xlYW59IGNvbnNpZGVyUm90YXRpb24gW2ZhbHNlXSAtIElmIHNldCB0byBgdHJ1ZWAgdGhlbiBHU3RyZWFtZXIgcGlwZWxpbmUgd2lsbFxuICogaW5jcmVhc2UgdGhlIGRpbWVuc2lvbnMgb2YgdGhlIHJlc3VsdGluZyBpbWFnZXMgdG8gcHJvcGVybHkgZml0IGltYWdlcyBpbiBib3RoIGxhbmRzY2FwZSBhbmRcbiAqIHBvcnRyYWl0IG9yaWVudGF0aW9ucy4gU2V0IGl0IHRvIGB0cnVlYCBpZiB0aGUgZGV2aWNlIHJvdGF0aW9uIGlzIG5vdCBnb2luZyB0byBiZSB0aGUgc2FtZSBkdXJpbmcgdGhlXG4gKiBicm9hZGNhc3Rpbmcgc2Vzc2lvbi5cbiAqIEBwcm9wZXJ0eSB7P2Jvb2xlYW59IGxvZ1BpcGVsaW5lRGV0YWlscyBbZmFsc2VdIC0gV2hldGhlciB0byBsb2cgR1N0cmVhbWVyIHBpcGVsaW5lIGV2ZW50cyBpbnRvXG4gKiB0aGUgc3RhbmRhcmQgbG9nIG91dHB1dC4gTWlnaHQgYmUgdXNlZnVsIGZvciBkZWJ1Z2dpbmcgcHVycG9zZXMuXG4gKi9cblxuLyoqXG4gKiBTdGFydHMgZGV2aWNlIHNjcmVlbiBicm9hZGNhc3QgYnkgY3JlYXRpbmcgTUpQRUcgc2VydmVyLlxuICogTXVsdGlwbGUgY2FsbHMgdG8gdGhpcyBtZXRob2QgaGF2ZSBubyBlZmZlY3QgdW5sZXNzIHRoZSBwcmV2aW91cyBzdHJlYW1pbmdcbiAqIHNlc3Npb24gaXMgc3RvcHBlZC5cbiAqIFRoaXMgbWV0aG9kIG9ubHkgd29ya3MgaWYgdGhlIGBhZGJfc2NyZWVuX3N0cmVhbWluZ2AgZmVhdHVyZSBpc1xuICogZW5hYmxlZCBvbiB0aGUgc2VydmVyIHNpZGUuXG4gKlxuICogQHBhcmFtIHs/U3RhcnRTY3JlZW5TdHJlYW1pbmdPcHRpb25zfSBvcHRpb25zIC0gVGhlIGF2YWlsYWJsZSBvcHRpb25zLlxuICogQHRocm93cyB7RXJyb3J9IElmIHNjcmVlbiBzdHJlYW1pbmcgaGFzIGZhaWxlZCB0byBzdGFydCBvclxuICogaXMgbm90IHN1cHBvcnRlZCBvbiB0aGUgaG9zdCBzeXN0ZW0gb3JcbiAqIHRoZSBjb3JyZXNwb25kaW5nIHNlcnZlciBmZWF0dXJlIGlzIG5vdCBlbmFibGVkLlxuICovXG5jb21tYW5kcy5tb2JpbGVTdGFydFNjcmVlblN0cmVhbWluZyA9IGFzeW5jIGZ1bmN0aW9uIG1vYmlsZVN0YXJ0U2NyZWVuU3RyZWFtaW5nIChvcHRpb25zID0ge30pIHtcbiAgdGhpcy5lbnN1cmVGZWF0dXJlRW5hYmxlZChBREJfU0NSRUVOX1NUUkVBTUlOR19GRUFUVVJFKTtcblxuICBjb25zdCB7XG4gICAgd2lkdGgsXG4gICAgaGVpZ2h0LFxuICAgIGJpdFJhdGUsXG4gICAgaG9zdCA9IERFRkFVTFRfSE9TVCxcbiAgICBwb3J0ID0gREVGQVVMVF9QT1JULFxuICAgIHBhdGhuYW1lLFxuICAgIHRjcFBvcnQgPSBERUZBVUxUX1BPUlQgKyAxLFxuICAgIHF1YWxpdHkgPSBERUZBVUxUX1FVQUxJVFksXG4gICAgY29uc2lkZXJSb3RhdGlvbiA9IGZhbHNlLFxuICAgIGxvZ1BpcGVsaW5lRGV0YWlscyA9IGZhbHNlLFxuICB9ID0gb3B0aW9ucztcblxuICBpZiAoXy5pc1VuZGVmaW5lZCh0aGlzLl9zY3JlZW5TdHJlYW1pbmdQcm9wcykpIHtcbiAgICBhd2FpdCB2ZXJpZnlTdHJlYW1pbmdSZXF1aXJlbWVudHModGhpcy5hZGIpO1xuICB9XG4gIGlmICghXy5pc0VtcHR5KHRoaXMuX3NjcmVlblN0cmVhbWluZ1Byb3BzKSkge1xuICAgIHRoaXMubG9nLmluZm8oYFRoZSBzY3JlZW4gc3RyZWFtaW5nIHNlc3Npb24gaXMgYWxyZWFkeSBydW5uaW5nLiBgICtcbiAgICAgIGBTdG9wIGl0IGZpcnN0IGluIG9yZGVyIHRvIHN0YXJ0IGEgbmV3IG9uZS5gKTtcbiAgICByZXR1cm47XG4gIH1cbiAgaWYgKChhd2FpdCBjaGVja1BvcnRTdGF0dXMocG9ydCwgaG9zdCkpID09PSAnb3BlbicpIHtcbiAgICB0aGlzLmxvZy5pbmZvKGBUaGUgcG9ydCAjJHtwb3J0fSBhdCAke2hvc3R9IGlzIGJ1c3kuIGAgK1xuICAgICAgYEFzc3VtaW5nIHRoZSBzY3JlZW4gc3RyZWFtaW5nIGlzIGFscmVhZHkgcnVubmluZ2ApO1xuICAgIHJldHVybjtcbiAgfVxuICBpZiAoKGF3YWl0IGNoZWNrUG9ydFN0YXR1cyh0Y3BQb3J0LCBUQ1BfSE9TVCkpID09PSAnb3BlbicpIHtcbiAgICB0aGlzLmxvZy5lcnJvckFuZFRocm93KGBUaGUgcG9ydCAjJHt0Y3BQb3J0fSBhdCAke1RDUF9IT1NUfSBpcyBidXN5LiBgICtcbiAgICAgIGBNYWtlIHN1cmUgdGhlcmUgYXJlIG5vIGxlZnRvdmVycyBmcm9tIHByZXZpb3VzIHNlc3Npb25zLmApO1xuICB9XG4gIHRoaXMuX3NjcmVlblN0cmVhbWluZ1Byb3BzID0gbnVsbDtcblxuICBjb25zdCBkZXZpY2VJbmZvID0gYXdhaXQgZ2V0RGV2aWNlSW5mbyh0aGlzLmFkYiwgdGhpcy5sb2cpO1xuICBjb25zdCBkZXZpY2VTdHJlYW1pbmdQcm9jID0gYXdhaXQgaW5pdERldmljZVN0cmVhbWluZ1Byb2ModGhpcy5hZGIsIHRoaXMubG9nLCBkZXZpY2VJbmZvLCB7XG4gICAgd2lkdGgsXG4gICAgaGVpZ2h0LFxuICAgIGJpdFJhdGUsXG4gIH0pO1xuICBsZXQgZ3N0cmVhbWVyUGlwZWxpbmU7XG4gIHRyeSB7XG4gICAgZ3N0cmVhbWVyUGlwZWxpbmUgPSBhd2FpdCBpbml0R3N0cmVhbWVyUGlwZWxpbmUoZGV2aWNlU3RyZWFtaW5nUHJvYywgZGV2aWNlSW5mbywgdGhpcy5sb2csIHtcbiAgICAgIHdpZHRoLFxuICAgICAgaGVpZ2h0LFxuICAgICAgcXVhbGl0eSxcbiAgICAgIHRjcFBvcnQsXG4gICAgICBjb25zaWRlclJvdGF0aW9uLFxuICAgICAgbG9nUGlwZWxpbmVEZXRhaWxzLFxuICAgIH0pO1xuICB9IGNhdGNoIChlKSB7XG4gICAgaWYgKGRldmljZVN0cmVhbWluZ1Byb2Mua2lsbCgwKSkge1xuICAgICAgZGV2aWNlU3RyZWFtaW5nUHJvYy5raWxsKCk7XG4gICAgfVxuICAgIHRocm93IGU7XG4gIH1cblxuICBsZXQgbWpwZWdTb2NrZXQ7XG4gIGxldCBtanBlZ1NlcnZlcjtcbiAgdHJ5IHtcbiAgICBhd2FpdCBuZXcgQigocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICBtanBlZ1NvY2tldCA9IG5ldC5jcmVhdGVDb25uZWN0aW9uKHRjcFBvcnQsIFRDUF9IT1NULCAoKSA9PiB7XG4gICAgICAgIHRoaXMubG9nLmluZm8oYFN1Y2Nlc3NmdWxseSBjb25uZWN0ZWQgdG8gTUpQRUcgc3RyZWFtIGF0IHRjcDovLyR7VENQX0hPU1R9OiR7dGNwUG9ydH1gKTtcbiAgICAgICAgbWpwZWdTZXJ2ZXIgPSBodHRwLmNyZWF0ZVNlcnZlcigocmVxLCByZXMpID0+IHtcbiAgICAgICAgICBjb25zdCByZW1vdGVBZGRyZXNzID0gZXh0cmFjdFJlbW90ZUFkZHJlc3MocmVxKTtcbiAgICAgICAgICBjb25zdCBjdXJyZW50UGF0aG5hbWUgPSB1cmwucGFyc2UocmVxLnVybCkucGF0aG5hbWU7XG4gICAgICAgICAgdGhpcy5sb2cuaW5mbyhgR290IGFuIGluY29taW5nIHNjcmVlbiBicmFkY2FzdGluZyByZXF1ZXN0IGZyb20gJHtyZW1vdGVBZGRyZXNzfSBgICtcbiAgICAgICAgICAgIGAoJHtyZXEuaGVhZGVyc1sndXNlci1hZ2VudCddIHx8ICdVc2VyIEFnZW50IHVua25vd24nfSkgYXQgJHtjdXJyZW50UGF0aG5hbWV9YCk7XG5cbiAgICAgICAgICBpZiAocGF0aG5hbWUgJiYgY3VycmVudFBhdGhuYW1lICE9PSBwYXRobmFtZSkge1xuICAgICAgICAgICAgdGhpcy5sb2cuaW5mbygnUmVqZWN0aW5nIHRoZSBicm9hZGNhc3QgcmVxdWVzdCBzaW5jZSBpdCBkb2VzIG5vdCBtYXRjaCB0aGUgZ2l2ZW4gcGF0aG5hbWUnKTtcbiAgICAgICAgICAgIHJlcy53cml0ZUhlYWQoNDA0LCB7XG4gICAgICAgICAgICAgIENvbm5lY3Rpb246ICdjbG9zZScsXG4gICAgICAgICAgICAgICdDb250ZW50LVR5cGUnOiAndGV4dC9wbGFpbjsgY2hhcnNldD11dGYtOCcsXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIHJlcy53cml0ZShgJyR7Y3VycmVudFBhdGhuYW1lfScgZGlkIG5vdCBtYXRjaCBhbnkga25vd24gZW5kcG9pbnRzYCk7XG4gICAgICAgICAgICByZXMuZW5kKCk7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgdGhpcy5sb2cuaW5mbygnU3RhcnRpbmcgTUpQRUcgYnJvYWRjYXN0Jyk7XG4gICAgICAgICAgcmVzLndyaXRlSGVhZCgyMDAsIHtcbiAgICAgICAgICAgICdDYWNoZS1Db250cm9sJzogJ25vLXN0b3JlLCBuby1jYWNoZSwgbXVzdC1yZXZhbGlkYXRlLCBwcmUtY2hlY2s9MCwgcG9zdC1jaGVjaz0wLCBtYXgtYWdlPTAnLFxuICAgICAgICAgICAgUHJhZ21hOiAnbm8tY2FjaGUnLFxuICAgICAgICAgICAgQ29ubmVjdGlvbjogJ2Nsb3NlJyxcbiAgICAgICAgICAgICdDb250ZW50LVR5cGUnOiBgbXVsdGlwYXJ0L3gtbWl4ZWQtcmVwbGFjZTsgYm91bmRhcnk9JHtCT1VOREFSWV9TVFJJTkd9YFxuICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgbWpwZWdTb2NrZXQucGlwZShyZXMpO1xuICAgICAgICB9KTtcbiAgICAgICAgbWpwZWdTZXJ2ZXIub24oJ2Vycm9yJywgKGUpID0+IHtcbiAgICAgICAgICB0aGlzLmxvZy53YXJuKGUpO1xuICAgICAgICAgIHJlamVjdChlKTtcbiAgICAgICAgfSk7XG4gICAgICAgIG1qcGVnU2VydmVyLm9uKCdjbG9zZScsICgpID0+IHtcbiAgICAgICAgICB0aGlzLmxvZy5kZWJ1ZyhgTUpQRUcgc2VydmVyIGF0IGh0dHA6Ly8ke2hvc3R9OiR7cG9ydH0gaGFzIGJlZW4gY2xvc2VkYCk7XG4gICAgICAgIH0pO1xuICAgICAgICBtanBlZ1NlcnZlci5vbignbGlzdGVuaW5nJywgKCkgPT4ge1xuICAgICAgICAgIHRoaXMubG9nLmluZm8oYFN1Y2Nlc3NmdWxseSBzdGFydGVkIE1KUEVHIHNlcnZlciBhdCBodHRwOi8vJHtob3N0fToke3BvcnR9YCk7XG4gICAgICAgICAgcmVzb2x2ZSgpO1xuICAgICAgICB9KTtcbiAgICAgICAgbWpwZWdTZXJ2ZXIubGlzdGVuKHBvcnQsIGhvc3QpO1xuICAgICAgfSk7XG4gICAgICBtanBlZ1NvY2tldC5vbignZXJyb3InLCAoZSkgPT4ge1xuICAgICAgICB0aGlzLmxvZy5lcnJvcihlKTtcbiAgICAgICAgcmVqZWN0KGUpO1xuICAgICAgfSk7XG4gICAgfSkudGltZW91dChTVFJFQU1JTkdfU1RBUlRVUF9USU1FT1VUX01TLFxuICAgICAgYENhbm5vdCBjb25uZWN0IHRvIHRoZSBzdHJlYW1pbmcgc2VydmVyIHdpdGhpbiAke1NUUkVBTUlOR19TVEFSVFVQX1RJTUVPVVRfTVN9bXNgKTtcbiAgfSBjYXRjaCAoZSkge1xuICAgIGlmIChkZXZpY2VTdHJlYW1pbmdQcm9jLmtpbGwoMCkpIHtcbiAgICAgIGRldmljZVN0cmVhbWluZ1Byb2Mua2lsbCgpO1xuICAgIH1cbiAgICBpZiAoZ3N0cmVhbWVyUGlwZWxpbmUuaXNSdW5uaW5nKSB7XG4gICAgICBhd2FpdCBnc3RyZWFtZXJQaXBlbGluZS5zdG9wKCk7XG4gICAgfVxuICAgIGlmIChtanBlZ1NvY2tldCkge1xuICAgICAgbWpwZWdTb2NrZXQuZGVzdHJveSgpO1xuICAgIH1cbiAgICBpZiAobWpwZWdTZXJ2ZXIgJiYgbWpwZWdTZXJ2ZXIubGlzdGVuaW5nKSB7XG4gICAgICBtanBlZ1NlcnZlci5jbG9zZSgpO1xuICAgIH1cbiAgICB0aHJvdyBlO1xuICB9XG5cbiAgdGhpcy5fc2NyZWVuU3RyZWFtaW5nUHJvcHMgPSB7XG4gICAgZGV2aWNlU3RyZWFtaW5nUHJvYyxcbiAgICBnc3RyZWFtZXJQaXBlbGluZSxcbiAgICBtanBlZ1NvY2tldCxcbiAgICBtanBlZ1NlcnZlcixcbiAgfTtcbn07XG5cbi8qKlxuICogU3RvcCBzY3JlZW4gc3RyZWFtaW5nLlxuICogSWYgbm8gc2NyZWVuIHN0cmVhbWluZyBzZXJ2ZXIgaGFzIGJlZW4gc3RhcnRlZCB0aGVuIG5vdGhpbmcgaXMgZG9uZS5cbiAqL1xuY29tbWFuZHMubW9iaWxlU3RvcFNjcmVlblN0cmVhbWluZyA9IGFzeW5jIGZ1bmN0aW9uIG1vYmlsZVN0b3BTY3JlZW5TdHJlYW1pbmcgKC8qIG9wdGlvbnMgPSB7fSAqLykge1xuICBpZiAoXy5pc0VtcHR5KHRoaXMuX3NjcmVlblN0cmVhbWluZ1Byb3BzKSkge1xuICAgIGlmICghXy5pc1VuZGVmaW5lZCh0aGlzLl9zY3JlZW5TdHJlYW1pbmdQcm9wcykpIHtcbiAgICAgIHRoaXMubG9nLmRlYnVnKGBTY3JlZW4gc3RyZWFtaW5nIGlzIG5vdCBydW5uaW5nLiBUaGVyZSBpcyBub3RoaW5nIHRvIHN0b3BgKTtcbiAgICB9XG4gICAgcmV0dXJuO1xuICB9XG5cbiAgY29uc3Qge1xuICAgIGRldmljZVN0cmVhbWluZ1Byb2MsXG4gICAgZ3N0cmVhbWVyUGlwZWxpbmUsXG4gICAgbWpwZWdTb2NrZXQsXG4gICAgbWpwZWdTZXJ2ZXIsXG4gIH0gPSB0aGlzLl9zY3JlZW5TdHJlYW1pbmdQcm9wcztcblxuICB0cnkge1xuICAgIG1qcGVnU29ja2V0LmVuZCgpO1xuICAgIGlmIChtanBlZ1NlcnZlci5saXN0ZW5pbmcpIHtcbiAgICAgIG1qcGVnU2VydmVyLmNsb3NlKCk7XG4gICAgfVxuICAgIGlmIChkZXZpY2VTdHJlYW1pbmdQcm9jLmtpbGwoMCkpIHtcbiAgICAgIGRldmljZVN0cmVhbWluZ1Byb2Mua2lsbCgnU0lHSU5UJyk7XG4gICAgfVxuICAgIGlmIChnc3RyZWFtZXJQaXBlbGluZS5pc1J1bm5pbmcpIHtcbiAgICAgIHRyeSB7XG4gICAgICAgIGF3YWl0IGdzdHJlYW1lclBpcGVsaW5lLnN0b3AoJ1NJR0lOVCcpO1xuICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICB0aGlzLmxvZy53YXJuKGUpO1xuICAgICAgICB0cnkge1xuICAgICAgICAgIGF3YWl0IGdzdHJlYW1lclBpcGVsaW5lLnN0b3AoJ1NJR0tJTEwnKTtcbiAgICAgICAgfSBjYXRjaCAoZTEpIHtcbiAgICAgICAgICB0aGlzLmxvZy5lcnJvcihlMSk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gICAgdGhpcy5sb2cuaW5mbyhgU3VjY2Vzc2Z1bGx5IHRlcm1pbmF0ZWQgdGhlIHNjcmVlbiBzdHJlYW1pbmcgTUpQRUcgc2VydmVyYCk7XG4gIH0gZmluYWxseSB7XG4gICAgdGhpcy5fc2NyZWVuU3RyZWFtaW5nUHJvcHMgPSBudWxsO1xuICB9XG59O1xuXG5cbmV4cG9ydCBkZWZhdWx0IGNvbW1hbmRzO1xuIl0sIm1hcHBpbmdzIjoiOzs7Ozs7OztBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUEsTUFBTUEsUUFBUSxHQUFHLENBQUMsQ0FBQztBQUVuQixNQUFNQyxzQkFBc0IsR0FBRyxDQUFDO0FBQ2hDLE1BQU1DLDRCQUE0QixHQUFHLElBQUk7QUFDekMsTUFBTUMsZ0JBQWdCLEdBQUksaUJBQWdCQyxlQUFNLENBQUNDLFNBQVMsRUFBRSxHQUFHLE1BQU0sR0FBRyxFQUFHLEVBQUM7QUFDNUUsTUFBTUMsa0JBQWtCLEdBQUksa0JBQWlCRixlQUFNLENBQUNDLFNBQVMsRUFBRSxHQUFHLE1BQU0sR0FBRyxFQUFHLEVBQUM7QUFDL0UsTUFBTUUsb0JBQW9CLEdBQUc7RUFDM0JDLFVBQVUsRUFBRSxXQUFXO0VBQ3ZCQyxTQUFTLEVBQUUsaUJBQWlCO0VBQzVCQyxPQUFPLEVBQUUsa0JBQWtCO0VBQzNCQyxhQUFhLEVBQUUsa0JBQWtCO0VBQ2pDQyxZQUFZLEVBQUU7QUFDaEIsQ0FBQztBQUNELE1BQU1DLG1CQUFtQixHQUFHLGNBQWM7QUFDMUMsTUFBTUMsZ0JBQWdCLEdBQUcsdUVBQXVFO0FBQ2hHLE1BQU1DLFlBQVksR0FBRyxXQUFXO0FBQ2hDLE1BQU1DLFFBQVEsR0FBRyxXQUFXO0FBQzVCLE1BQU1DLFlBQVksR0FBRyxJQUFJO0FBQ3pCLE1BQU1DLGVBQWUsR0FBRyxFQUFFO0FBQzFC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
@@ -1 +1 @@
1
- {"version":3,"file":"streamscreen.js","names":["commands","RECORDING_INTERVAL_SEC","STREAMING_STARTUP_TIMEOUT_MS","GSTREAMER_BINARY","system","isWindows","GST_INSPECT_BINARY","REQUIRED_GST_PLUGINS","avdec_h264","h264parse","jpegenc","tcpserversink","multipartmux","SCREENRECORD_BINARY","GST_TUTORIAL_URL","DEFAULT_HOST","TCP_HOST","DEFAULT_PORT","DEFAULT_QUALITY","DEFAULT_BITRATE","BOUNDARY_STRING","ADB_SCREEN_STREAMING_FEATURE","createStreamingLogger","streamName","udid","logger","getLogger","_","truncate","length","omission","verifyStreamingRequirements","adb","trim","shell","Error","gstreamerCheckPromises","binaryName","push","fs","which","e","B","all","moduleCheckPromises","name","modName","toPairs","stdout","exec","includes","getDeviceInfo","log","output","result","key","pattern","match","debug","parseInt","curDeviceId","initDeviceStreamingProc","deviceInfo","opts","width","height","bitRate","adjustedWidth","adjustedHeight","adjustedBitrate","screenRecordCmd","adbArgs","executable","defaultArgs","deviceStreaming","spawn","path","on","code","signal","isStarted","deviceStreamingLogger","errorsListener","chunk","stderr","toString","startupListener","isEmpty","info","util","quote","waitForCondition","waitMs","intervalMs","errorAndThrow","message","removeListener","initGstreamerPipeline","deviceStreamingProc","quality","tcpPort","considerRotation","logPipelineDetails","gstreamerPipeline","SubProcess","Math","max","fps","stdio","gstreamerLogger","gstOutputListener","didFail","rep","start","checkPortStatus","ign","extractRemoteAddress","req","headers","socket","remoteAddress","connection","mobileStartScreenStreaming","options","ensureFeatureEnabled","host","port","pathname","isUndefined","_screenStreamingProps","kill","mjpegSocket","mjpegServer","resolve","reject","net","createConnection","http","createServer","res","currentPathname","url","parse","writeHead","Connection","write","end","Pragma","pipe","warn","listen","error","timeout","isRunning","stop","destroy","listening","close","mobileStopScreenStreaming","e1"],"sources":["../../../lib/commands/streamscreen.js"],"sourcesContent":["import _ from 'lodash';\nimport { fs, system, logger, util } from 'appium/support';\nimport { exec, SubProcess } from 'teen_process';\nimport { checkPortStatus } from 'portscanner';\nimport http from 'http';\nimport net from 'net';\nimport B from 'bluebird';\nimport { waitForCondition } from 'asyncbox';\nimport { spawn } from 'child_process';\nimport url from 'url';\n\nconst commands = {};\n\nconst RECORDING_INTERVAL_SEC = 5;\nconst STREAMING_STARTUP_TIMEOUT_MS = 5000;\nconst GSTREAMER_BINARY = `gst-launch-1.0${system.isWindows() ? '.exe' : ''}`;\nconst GST_INSPECT_BINARY = `gst-inspect-1.0${system.isWindows() ? '.exe' : ''}`;\nconst REQUIRED_GST_PLUGINS = {\n avdec_h264: 'gst-libav',\n h264parse: 'gst-plugins-bad',\n jpegenc: 'gst-plugins-good',\n tcpserversink: 'gst-plugins-base',\n multipartmux: 'gst-plugins-good',\n};\nconst SCREENRECORD_BINARY = 'screenrecord';\nconst GST_TUTORIAL_URL = 'https://gstreamer.freedesktop.org/documentation/installing/index.html';\nconst DEFAULT_HOST = '127.0.0.1';\nconst TCP_HOST = '127.0.0.1';\nconst DEFAULT_PORT = 8093;\nconst DEFAULT_QUALITY = 70;\nconst DEFAULT_BITRATE = 4000000; // 4 Mbps\nconst BOUNDARY_STRING = '--2ae9746887f170b8cf7c271047ce314c';\n\nconst ADB_SCREEN_STREAMING_FEATURE = 'adb_screen_streaming';\n\nfunction createStreamingLogger (streamName, udid) {\n return logger.getLogger(`${streamName}@` + _.truncate(udid, {\n length: 8,\n omission: '',\n }));\n}\n\nasync function verifyStreamingRequirements (adb) {\n if (!_.trim(await adb.shell(['which', SCREENRECORD_BINARY]))) {\n throw new Error(\n `The required '${SCREENRECORD_BINARY}' binary is not available on the device under test`);\n }\n\n const gstreamerCheckPromises = [];\n for (const binaryName of [GSTREAMER_BINARY, GST_INSPECT_BINARY]) {\n gstreamerCheckPromises.push((async () => {\n try {\n await fs.which(binaryName);\n } catch (e) {\n throw new Error(`The '${binaryName}' binary is not available in the PATH on the host system. ` +\n `See ${GST_TUTORIAL_URL} for more details on how to install it.`);\n }\n })());\n }\n await B.all(gstreamerCheckPromises);\n\n const moduleCheckPromises = [];\n for (const [name, modName] of _.toPairs(REQUIRED_GST_PLUGINS)) {\n moduleCheckPromises.push((async () => {\n const {stdout} = await exec(GST_INSPECT_BINARY, [name]);\n if (!_.includes(stdout, modName)) {\n throw new Error(\n `The required GStreamer plugin '${name}' from '${modName}' module is not installed. ` +\n `See ${GST_TUTORIAL_URL} for more details on how to install it.`);\n }\n })());\n }\n await B.all(moduleCheckPromises);\n}\n\nasync function getDeviceInfo (adb, log = null) {\n const output = await adb.shell(['dumpsys', 'display']);\n const result = {};\n for (const [key, pattern] of [\n ['width', /\\bdeviceWidth=(\\d+)/],\n ['height', /\\bdeviceHeight=(\\d+)/],\n ['fps', /\\bfps=(\\d+)/],\n ]) {\n const match = pattern.exec(output);\n if (!match) {\n log?.debug(output);\n throw new Error(`Cannot parse the device ${key} from the adb command output. ` +\n `Check the server log for more details.`);\n }\n result[key] = parseInt(match[1], 10);\n }\n result.udid = adb.curDeviceId;\n return result;\n}\n\nasync function initDeviceStreamingProc (adb, log, deviceInfo, opts = {}) {\n const {\n width,\n height,\n bitRate,\n } = opts;\n const adjustedWidth = parseInt(width, 10) || deviceInfo.width;\n const adjustedHeight = parseInt(height, 10) || deviceInfo.height;\n const adjustedBitrate = parseInt(bitRate, 10) || DEFAULT_BITRATE;\n let screenRecordCmd = SCREENRECORD_BINARY +\n ` --output-format=h264` +\n // 5 seconds is fine to detect rotation changes\n ` --time-limit=${RECORDING_INTERVAL_SEC}`;\n if (width || height) {\n screenRecordCmd += ` --size=${adjustedWidth}x${adjustedHeight}`;\n }\n if (bitRate) {\n screenRecordCmd += ` --bit-rate=${adjustedBitrate}`;\n }\n const adbArgs = [\n ...adb.executable.defaultArgs,\n 'exec-out',\n // The loop is required, because by default the maximum record duration\n // for screenrecord is always limited\n `while true; do ${screenRecordCmd} -; done`,\n ];\n const deviceStreaming = spawn(adb.executable.path, adbArgs);\n deviceStreaming.on('exit', (code, signal) => {\n log.debug(`Device streaming process exited with code ${code}, signal ${signal}`);\n });\n\n let isStarted = false;\n const deviceStreamingLogger = createStreamingLogger(SCREENRECORD_BINARY, deviceInfo.udid);\n const errorsListener = (chunk) => {\n const stderr = chunk.toString();\n if (_.trim(stderr)) {\n deviceStreamingLogger.debug(stderr);\n }\n };\n deviceStreaming.stderr.on('data', errorsListener);\n\n const startupListener = (chunk) => {\n if (!isStarted) {\n isStarted = !_.isEmpty(chunk);\n }\n };\n deviceStreaming.stdout.on('data', startupListener);\n\n try {\n log.info(`Starting device streaming: ${util.quote([adb.executable.path, ...adbArgs])}`);\n await waitForCondition(() => isStarted, {\n waitMs: STREAMING_STARTUP_TIMEOUT_MS,\n intervalMs: 300,\n });\n } catch (e) {\n log.errorAndThrow(\n `Cannot start the screen streaming process. Original error: ${e.message}`);\n } finally {\n deviceStreaming.stderr.removeListener('data', errorsListener);\n deviceStreaming.stdout.removeListener('data', startupListener);\n }\n return deviceStreaming;\n}\n\nasync function initGstreamerPipeline (deviceStreamingProc, deviceInfo, log, opts = {}) {\n const {\n width,\n height,\n quality,\n tcpPort,\n considerRotation,\n logPipelineDetails,\n } = opts;\n const adjustedWidth = parseInt(width, 10) || deviceInfo.width;\n const adjustedHeight = parseInt(height, 10) || deviceInfo.height;\n const gstreamerPipeline = new SubProcess(GSTREAMER_BINARY, [\n '-v',\n 'fdsrc', 'fd=0',\n '!', 'video/x-h264,' +\n `width=${considerRotation ? Math.max(adjustedWidth, adjustedHeight) : adjustedWidth},` +\n `height=${considerRotation ? Math.max(adjustedWidth, adjustedHeight) : adjustedHeight},` +\n `framerate=${deviceInfo.fps}/1,` +\n 'byte-stream=true',\n '!', 'h264parse',\n '!', 'queue', 'leaky=downstream',\n '!', 'avdec_h264',\n '!', 'queue', 'leaky=downstream',\n '!', 'jpegenc', `quality=${quality}`,\n '!', 'multipartmux', `boundary=${BOUNDARY_STRING}`,\n '!', 'tcpserversink', `host=${TCP_HOST}`, `port=${tcpPort}`,\n ], {\n stdio: [deviceStreamingProc.stdout, 'pipe', 'pipe']\n });\n gstreamerPipeline.on('exit', (code, signal) => {\n log.debug(`Pipeline streaming process exited with code ${code}, signal ${signal}`);\n });\n const gstreamerLogger = createStreamingLogger('gst', deviceInfo.udid);\n const gstOutputListener = (stdout, stderr) => {\n if (_.trim(stderr || stdout)) {\n gstreamerLogger.debug(stderr || stdout);\n }\n };\n gstreamerPipeline.on('output', gstOutputListener);\n let didFail = false;\n try {\n log.info(`Starting GStreamer pipeline: ${gstreamerPipeline.rep}`);\n await gstreamerPipeline.start(0);\n await waitForCondition(async () => {\n try {\n return (await checkPortStatus(tcpPort, TCP_HOST)) === 'open';\n } catch (ign) {\n return false;\n }\n }, {\n waitMs: STREAMING_STARTUP_TIMEOUT_MS,\n intervalMs: 300,\n });\n } catch (e) {\n didFail = true;\n log.errorAndThrow(\n `Cannot start the screen streaming pipeline. Original error: ${e.message}`);\n } finally {\n if (!logPipelineDetails || didFail) {\n gstreamerPipeline.removeListener('output', gstOutputListener);\n }\n }\n return gstreamerPipeline;\n}\n\nfunction extractRemoteAddress (req) {\n return req.headers['x-forwarded-for']\n || req.socket.remoteAddress\n || req.connection.remoteAddress\n || req.connection.socket.remoteAddress;\n}\n\n\n/**\n * @typedef {Object} StartScreenStreamingOptions\n *\n * @property {?number} width - The scaled width of the device's screen. If unset then the script will assign it\n * to the actual screen width measured in pixels.\n * @property {?number} height - The scaled height of the device's screen. If unset then the script will assign it\n * to the actual screen height measured in pixels.\n * @property {?number} bitRate - The video bit rate for the video, in bits per second.\n * The default value is 4000000 (4 Mb/s). You can increase the bit rate to improve video quality,\n * but doing so results in larger movie files.\n * @property {?string} host [127.0.0.1] - The IP address/host name to start the MJPEG server on.\n * You can set it to `0.0.0.0` to trigger the broadcast on all available network interfaces.\n * @property {?string} pathname - The HTTP request path the MJPEG server should be available on.\n * If unset then any pathname on the given `host`/`port` combination will work. Note that the value\n * should always start with a single slash: `/`\n * @property {?number} tcpPort [8094] - The port number to start the internal TCP MJPEG broadcast on.\n * This type of broadcast always starts on the loopback interface (`127.0.0.1`).\n * @property {?number} port [8093] - The port number to start the MJPEG server on.\n * @property {?number} quality [70] - The quality value for the streamed JPEG images.\n * This number should be in range [1, 100], where 100 is the best quality.\n * @property {?boolean} considerRotation [false] - If set to `true` then GStreamer pipeline will\n * increase the dimensions of the resulting images to properly fit images in both landscape and\n * portrait orientations. Set it to `true` if the device rotation is not going to be the same during the\n * broadcasting session.\n * @property {?boolean} logPipelineDetails [false] - Whether to log GStreamer pipeline events into\n * the standard log output. Might be useful for debugging purposes.\n */\n\n/**\n * Starts device screen broadcast by creating MJPEG server.\n * Multiple calls to this method have no effect unless the previous streaming\n * session is stopped.\n * This method only works if the `adb_screen_streaming` feature is\n * enabled on the server side.\n *\n * @param {?StartScreenStreamingOptions} options - The available options.\n * @throws {Error} If screen streaming has failed to start or\n * is not supported on the host system or\n * the corresponding server feature is not enabled.\n */\ncommands.mobileStartScreenStreaming = async function mobileStartScreenStreaming (options = {}) {\n this.ensureFeatureEnabled(ADB_SCREEN_STREAMING_FEATURE);\n\n const {\n width,\n height,\n bitRate,\n host = DEFAULT_HOST,\n port = DEFAULT_PORT,\n pathname,\n tcpPort = DEFAULT_PORT + 1,\n quality = DEFAULT_QUALITY,\n considerRotation = false,\n logPipelineDetails = false,\n } = options;\n\n if (_.isUndefined(this._screenStreamingProps)) {\n await verifyStreamingRequirements(this.adb);\n }\n if (!_.isEmpty(this._screenStreamingProps)) {\n this.log.info(`The screen streaming session is already running. ` +\n `Stop it first in order to start a new one.`);\n return;\n }\n if ((await checkPortStatus(port, host)) === 'open') {\n this.log.info(`The port #${port} at ${host} is busy. ` +\n `Assuming the screen streaming is already running`);\n return;\n }\n if ((await checkPortStatus(tcpPort, TCP_HOST)) === 'open') {\n this.log.errorAndThrow(`The port #${tcpPort} at ${TCP_HOST} is busy. ` +\n `Make sure there are no leftovers from previous sessions.`);\n }\n this._screenStreamingProps = null;\n\n const deviceInfo = await getDeviceInfo(this.adb, this.log);\n const deviceStreamingProc = await initDeviceStreamingProc(this.adb, this.log, deviceInfo, {\n width,\n height,\n bitRate,\n });\n let gstreamerPipeline;\n try {\n gstreamerPipeline = await initGstreamerPipeline(deviceStreamingProc, deviceInfo, this.log, {\n width,\n height,\n quality,\n tcpPort,\n considerRotation,\n logPipelineDetails,\n });\n } catch (e) {\n if (deviceStreamingProc.kill(0)) {\n deviceStreamingProc.kill();\n }\n throw e;\n }\n\n let mjpegSocket;\n let mjpegServer;\n try {\n await new B((resolve, reject) => {\n mjpegSocket = net.createConnection(tcpPort, TCP_HOST, () => {\n this.log.info(`Successfully connected to MJPEG stream at tcp://${TCP_HOST}:${tcpPort}`);\n mjpegServer = http.createServer((req, res) => {\n const remoteAddress = extractRemoteAddress(req);\n const currentPathname = url.parse(req.url).pathname;\n this.log.info(`Got an incoming screen bradcasting request from ${remoteAddress} ` +\n `(${req.headers['user-agent'] || 'User Agent unknown'}) at ${currentPathname}`);\n\n if (pathname && currentPathname !== pathname) {\n this.log.info('Rejecting the broadcast request since it does not match the given pathname');\n res.writeHead(404, {\n Connection: 'close',\n 'Content-Type': 'text/plain; charset=utf-8',\n });\n res.write(`'${currentPathname}' did not match any known endpoints`);\n res.end();\n return;\n }\n\n this.log.info('Starting MJPEG broadcast');\n res.writeHead(200, {\n 'Cache-Control': 'no-store, no-cache, must-revalidate, pre-check=0, post-check=0, max-age=0',\n Pragma: 'no-cache',\n Connection: 'close',\n 'Content-Type': `multipart/x-mixed-replace; boundary=${BOUNDARY_STRING}`\n });\n\n mjpegSocket.pipe(res);\n });\n mjpegServer.on('error', (e) => {\n this.log.warn(e);\n reject(e);\n });\n mjpegServer.on('close', () => {\n this.log.debug(`MJPEG server at http://${host}:${port} has been closed`);\n });\n mjpegServer.on('listening', () => {\n this.log.info(`Successfully started MJPEG server at http://${host}:${port}`);\n resolve();\n });\n mjpegServer.listen(port, host);\n });\n mjpegSocket.on('error', (e) => {\n this.log.error(e);\n reject(e);\n });\n }).timeout(STREAMING_STARTUP_TIMEOUT_MS,\n `Cannot connect to the streaming server within ${STREAMING_STARTUP_TIMEOUT_MS}ms`);\n } catch (e) {\n if (deviceStreamingProc.kill(0)) {\n deviceStreamingProc.kill();\n }\n if (gstreamerPipeline.isRunning) {\n await gstreamerPipeline.stop();\n }\n if (mjpegSocket) {\n mjpegSocket.destroy();\n }\n if (mjpegServer && mjpegServer.listening) {\n mjpegServer.close();\n }\n throw e;\n }\n\n this._screenStreamingProps = {\n deviceStreamingProc,\n gstreamerPipeline,\n mjpegSocket,\n mjpegServer,\n };\n};\n\n/**\n * Stop screen streaming.\n * If no screen streaming server has been started then nothing is done.\n */\ncommands.mobileStopScreenStreaming = async function mobileStopScreenStreaming (/* options = {} */) {\n if (_.isEmpty(this._screenStreamingProps)) {\n if (!_.isUndefined(this._screenStreamingProps)) {\n this.log.debug(`Screen streaming is not running. There is nothing to stop`);\n }\n return;\n }\n\n const {\n deviceStreamingProc,\n gstreamerPipeline,\n mjpegSocket,\n mjpegServer,\n } = this._screenStreamingProps;\n\n try {\n mjpegSocket.end();\n if (mjpegServer.listening) {\n mjpegServer.close();\n }\n if (deviceStreamingProc.kill(0)) {\n deviceStreamingProc.kill('SIGINT');\n }\n if (gstreamerPipeline.isRunning) {\n try {\n await gstreamerPipeline.stop('SIGINT');\n } catch (e) {\n this.log.warn(e);\n try {\n await gstreamerPipeline.stop('SIGKILL');\n } catch (e1) {\n this.log.error(e1);\n }\n }\n }\n this.log.info(`Successfully terminated the screen streaming MJPEG server`);\n } finally {\n this._screenStreamingProps = null;\n }\n};\n\n\nexport default commands;\n"],"mappings":"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"}
1
+ {"version":3,"file":"streamscreen.js","names":["commands","RECORDING_INTERVAL_SEC","STREAMING_STARTUP_TIMEOUT_MS","GSTREAMER_BINARY","system","isWindows","GST_INSPECT_BINARY","REQUIRED_GST_PLUGINS","avdec_h264","h264parse","jpegenc","tcpserversink","multipartmux","SCREENRECORD_BINARY","GST_TUTORIAL_URL","DEFAULT_HOST","TCP_HOST","DEFAULT_PORT","DEFAULT_QUALITY","DEFAULT_BITRATE","BOUNDARY_STRING","ADB_SCREEN_STREAMING_FEATURE","createStreamingLogger","streamName","udid","logger","getLogger","_","truncate","length","omission","verifyStreamingRequirements","adb","trim","shell","Error","gstreamerCheckPromises","binaryName","push","fs","which","e","B","all","moduleCheckPromises","name","modName","toPairs","stdout","exec","includes","getDeviceInfo","log","output","result","key","pattern","match","debug","parseInt","curDeviceId","initDeviceStreamingProc","deviceInfo","opts","width","height","bitRate","adjustedWidth","adjustedHeight","adjustedBitrate","screenRecordCmd","adbArgs","executable","defaultArgs","deviceStreaming","spawn","path","on","code","signal","isStarted","deviceStreamingLogger","errorsListener","chunk","stderr","toString","startupListener","isEmpty","info","util","quote","waitForCondition","waitMs","intervalMs","errorAndThrow","message","removeListener","initGstreamerPipeline","deviceStreamingProc","quality","tcpPort","considerRotation","logPipelineDetails","gstreamerPipeline","SubProcess","Math","max","fps","stdio","gstreamerLogger","gstOutputListener","didFail","rep","start","checkPortStatus","ign","extractRemoteAddress","req","headers","socket","remoteAddress","connection","mobileStartScreenStreaming","options","ensureFeatureEnabled","host","port","pathname","isUndefined","_screenStreamingProps","kill","mjpegSocket","mjpegServer","resolve","reject","net","createConnection","http","createServer","res","currentPathname","url","parse","writeHead","Connection","write","end","Pragma","pipe","warn","listen","error","timeout","isRunning","stop","destroy","listening","close","mobileStopScreenStreaming","e1"],"sources":["../../../lib/commands/streamscreen.js"],"sourcesContent":["import _ from 'lodash';\nimport { fs, system, logger, util } from '@appium/support';\nimport { exec, SubProcess } from 'teen_process';\nimport { checkPortStatus } from 'portscanner';\nimport http from 'http';\nimport net from 'net';\nimport B from 'bluebird';\nimport { waitForCondition } from 'asyncbox';\nimport { spawn } from 'child_process';\nimport url from 'url';\n\nconst commands = {};\n\nconst RECORDING_INTERVAL_SEC = 5;\nconst STREAMING_STARTUP_TIMEOUT_MS = 5000;\nconst GSTREAMER_BINARY = `gst-launch-1.0${system.isWindows() ? '.exe' : ''}`;\nconst GST_INSPECT_BINARY = `gst-inspect-1.0${system.isWindows() ? '.exe' : ''}`;\nconst REQUIRED_GST_PLUGINS = {\n avdec_h264: 'gst-libav',\n h264parse: 'gst-plugins-bad',\n jpegenc: 'gst-plugins-good',\n tcpserversink: 'gst-plugins-base',\n multipartmux: 'gst-plugins-good',\n};\nconst SCREENRECORD_BINARY = 'screenrecord';\nconst GST_TUTORIAL_URL = 'https://gstreamer.freedesktop.org/documentation/installing/index.html';\nconst DEFAULT_HOST = '127.0.0.1';\nconst TCP_HOST = '127.0.0.1';\nconst DEFAULT_PORT = 8093;\nconst DEFAULT_QUALITY = 70;\nconst DEFAULT_BITRATE = 4000000; // 4 Mbps\nconst BOUNDARY_STRING = '--2ae9746887f170b8cf7c271047ce314c';\n\nconst ADB_SCREEN_STREAMING_FEATURE = 'adb_screen_streaming';\n\nfunction createStreamingLogger (streamName, udid) {\n return logger.getLogger(`${streamName}@` + _.truncate(udid, {\n length: 8,\n omission: '',\n }));\n}\n\nasync function verifyStreamingRequirements (adb) {\n if (!_.trim(await adb.shell(['which', SCREENRECORD_BINARY]))) {\n throw new Error(\n `The required '${SCREENRECORD_BINARY}' binary is not available on the device under test`);\n }\n\n const gstreamerCheckPromises = [];\n for (const binaryName of [GSTREAMER_BINARY, GST_INSPECT_BINARY]) {\n gstreamerCheckPromises.push((async () => {\n try {\n await fs.which(binaryName);\n } catch (e) {\n throw new Error(`The '${binaryName}' binary is not available in the PATH on the host system. ` +\n `See ${GST_TUTORIAL_URL} for more details on how to install it.`);\n }\n })());\n }\n await B.all(gstreamerCheckPromises);\n\n const moduleCheckPromises = [];\n for (const [name, modName] of _.toPairs(REQUIRED_GST_PLUGINS)) {\n moduleCheckPromises.push((async () => {\n const {stdout} = await exec(GST_INSPECT_BINARY, [name]);\n if (!_.includes(stdout, modName)) {\n throw new Error(\n `The required GStreamer plugin '${name}' from '${modName}' module is not installed. ` +\n `See ${GST_TUTORIAL_URL} for more details on how to install it.`);\n }\n })());\n }\n await B.all(moduleCheckPromises);\n}\n\nasync function getDeviceInfo (adb, log = null) {\n const output = await adb.shell(['dumpsys', 'display']);\n const result = {};\n for (const [key, pattern] of [\n ['width', /\\bdeviceWidth=(\\d+)/],\n ['height', /\\bdeviceHeight=(\\d+)/],\n ['fps', /\\bfps=(\\d+)/],\n ]) {\n const match = pattern.exec(output);\n if (!match) {\n log?.debug(output);\n throw new Error(`Cannot parse the device ${key} from the adb command output. ` +\n `Check the server log for more details.`);\n }\n result[key] = parseInt(match[1], 10);\n }\n result.udid = adb.curDeviceId;\n return result;\n}\n\nasync function initDeviceStreamingProc (adb, log, deviceInfo, opts = {}) {\n const {\n width,\n height,\n bitRate,\n } = opts;\n const adjustedWidth = parseInt(width, 10) || deviceInfo.width;\n const adjustedHeight = parseInt(height, 10) || deviceInfo.height;\n const adjustedBitrate = parseInt(bitRate, 10) || DEFAULT_BITRATE;\n let screenRecordCmd = SCREENRECORD_BINARY +\n ` --output-format=h264` +\n // 5 seconds is fine to detect rotation changes\n ` --time-limit=${RECORDING_INTERVAL_SEC}`;\n if (width || height) {\n screenRecordCmd += ` --size=${adjustedWidth}x${adjustedHeight}`;\n }\n if (bitRate) {\n screenRecordCmd += ` --bit-rate=${adjustedBitrate}`;\n }\n const adbArgs = [\n ...adb.executable.defaultArgs,\n 'exec-out',\n // The loop is required, because by default the maximum record duration\n // for screenrecord is always limited\n `while true; do ${screenRecordCmd} -; done`,\n ];\n const deviceStreaming = spawn(adb.executable.path, adbArgs);\n deviceStreaming.on('exit', (code, signal) => {\n log.debug(`Device streaming process exited with code ${code}, signal ${signal}`);\n });\n\n let isStarted = false;\n const deviceStreamingLogger = createStreamingLogger(SCREENRECORD_BINARY, deviceInfo.udid);\n const errorsListener = (chunk) => {\n const stderr = chunk.toString();\n if (_.trim(stderr)) {\n deviceStreamingLogger.debug(stderr);\n }\n };\n deviceStreaming.stderr.on('data', errorsListener);\n\n const startupListener = (chunk) => {\n if (!isStarted) {\n isStarted = !_.isEmpty(chunk);\n }\n };\n deviceStreaming.stdout.on('data', startupListener);\n\n try {\n log.info(`Starting device streaming: ${util.quote([adb.executable.path, ...adbArgs])}`);\n await waitForCondition(() => isStarted, {\n waitMs: STREAMING_STARTUP_TIMEOUT_MS,\n intervalMs: 300,\n });\n } catch (e) {\n log.errorAndThrow(\n `Cannot start the screen streaming process. Original error: ${e.message}`);\n } finally {\n deviceStreaming.stderr.removeListener('data', errorsListener);\n deviceStreaming.stdout.removeListener('data', startupListener);\n }\n return deviceStreaming;\n}\n\nasync function initGstreamerPipeline (deviceStreamingProc, deviceInfo, log, opts = {}) {\n const {\n width,\n height,\n quality,\n tcpPort,\n considerRotation,\n logPipelineDetails,\n } = opts;\n const adjustedWidth = parseInt(width, 10) || deviceInfo.width;\n const adjustedHeight = parseInt(height, 10) || deviceInfo.height;\n const gstreamerPipeline = new SubProcess(GSTREAMER_BINARY, [\n '-v',\n 'fdsrc', 'fd=0',\n '!', 'video/x-h264,' +\n `width=${considerRotation ? Math.max(adjustedWidth, adjustedHeight) : adjustedWidth},` +\n `height=${considerRotation ? Math.max(adjustedWidth, adjustedHeight) : adjustedHeight},` +\n `framerate=${deviceInfo.fps}/1,` +\n 'byte-stream=true',\n '!', 'h264parse',\n '!', 'queue', 'leaky=downstream',\n '!', 'avdec_h264',\n '!', 'queue', 'leaky=downstream',\n '!', 'jpegenc', `quality=${quality}`,\n '!', 'multipartmux', `boundary=${BOUNDARY_STRING}`,\n '!', 'tcpserversink', `host=${TCP_HOST}`, `port=${tcpPort}`,\n ], {\n stdio: [deviceStreamingProc.stdout, 'pipe', 'pipe']\n });\n gstreamerPipeline.on('exit', (code, signal) => {\n log.debug(`Pipeline streaming process exited with code ${code}, signal ${signal}`);\n });\n const gstreamerLogger = createStreamingLogger('gst', deviceInfo.udid);\n const gstOutputListener = (stdout, stderr) => {\n if (_.trim(stderr || stdout)) {\n gstreamerLogger.debug(stderr || stdout);\n }\n };\n gstreamerPipeline.on('output', gstOutputListener);\n let didFail = false;\n try {\n log.info(`Starting GStreamer pipeline: ${gstreamerPipeline.rep}`);\n await gstreamerPipeline.start(0);\n await waitForCondition(async () => {\n try {\n return (await checkPortStatus(tcpPort, TCP_HOST)) === 'open';\n } catch (ign) {\n return false;\n }\n }, {\n waitMs: STREAMING_STARTUP_TIMEOUT_MS,\n intervalMs: 300,\n });\n } catch (e) {\n didFail = true;\n log.errorAndThrow(\n `Cannot start the screen streaming pipeline. Original error: ${e.message}`);\n } finally {\n if (!logPipelineDetails || didFail) {\n gstreamerPipeline.removeListener('output', gstOutputListener);\n }\n }\n return gstreamerPipeline;\n}\n\nfunction extractRemoteAddress (req) {\n return req.headers['x-forwarded-for']\n || req.socket.remoteAddress\n || req.connection.remoteAddress\n || req.connection.socket.remoteAddress;\n}\n\n\n/**\n * @typedef {Object} StartScreenStreamingOptions\n *\n * @property {?number} width - The scaled width of the device's screen. If unset then the script will assign it\n * to the actual screen width measured in pixels.\n * @property {?number} height - The scaled height of the device's screen. If unset then the script will assign it\n * to the actual screen height measured in pixels.\n * @property {?number} bitRate - The video bit rate for the video, in bits per second.\n * The default value is 4000000 (4 Mb/s). You can increase the bit rate to improve video quality,\n * but doing so results in larger movie files.\n * @property {?string} host [127.0.0.1] - The IP address/host name to start the MJPEG server on.\n * You can set it to `0.0.0.0` to trigger the broadcast on all available network interfaces.\n * @property {?string} pathname - The HTTP request path the MJPEG server should be available on.\n * If unset then any pathname on the given `host`/`port` combination will work. Note that the value\n * should always start with a single slash: `/`\n * @property {?number} tcpPort [8094] - The port number to start the internal TCP MJPEG broadcast on.\n * This type of broadcast always starts on the loopback interface (`127.0.0.1`).\n * @property {?number} port [8093] - The port number to start the MJPEG server on.\n * @property {?number} quality [70] - The quality value for the streamed JPEG images.\n * This number should be in range [1, 100], where 100 is the best quality.\n * @property {?boolean} considerRotation [false] - If set to `true` then GStreamer pipeline will\n * increase the dimensions of the resulting images to properly fit images in both landscape and\n * portrait orientations. Set it to `true` if the device rotation is not going to be the same during the\n * broadcasting session.\n * @property {?boolean} logPipelineDetails [false] - Whether to log GStreamer pipeline events into\n * the standard log output. Might be useful for debugging purposes.\n */\n\n/**\n * Starts device screen broadcast by creating MJPEG server.\n * Multiple calls to this method have no effect unless the previous streaming\n * session is stopped.\n * This method only works if the `adb_screen_streaming` feature is\n * enabled on the server side.\n *\n * @param {?StartScreenStreamingOptions} options - The available options.\n * @throws {Error} If screen streaming has failed to start or\n * is not supported on the host system or\n * the corresponding server feature is not enabled.\n */\ncommands.mobileStartScreenStreaming = async function mobileStartScreenStreaming (options = {}) {\n this.ensureFeatureEnabled(ADB_SCREEN_STREAMING_FEATURE);\n\n const {\n width,\n height,\n bitRate,\n host = DEFAULT_HOST,\n port = DEFAULT_PORT,\n pathname,\n tcpPort = DEFAULT_PORT + 1,\n quality = DEFAULT_QUALITY,\n considerRotation = false,\n logPipelineDetails = false,\n } = options;\n\n if (_.isUndefined(this._screenStreamingProps)) {\n await verifyStreamingRequirements(this.adb);\n }\n if (!_.isEmpty(this._screenStreamingProps)) {\n this.log.info(`The screen streaming session is already running. ` +\n `Stop it first in order to start a new one.`);\n return;\n }\n if ((await checkPortStatus(port, host)) === 'open') {\n this.log.info(`The port #${port} at ${host} is busy. ` +\n `Assuming the screen streaming is already running`);\n return;\n }\n if ((await checkPortStatus(tcpPort, TCP_HOST)) === 'open') {\n this.log.errorAndThrow(`The port #${tcpPort} at ${TCP_HOST} is busy. ` +\n `Make sure there are no leftovers from previous sessions.`);\n }\n this._screenStreamingProps = null;\n\n const deviceInfo = await getDeviceInfo(this.adb, this.log);\n const deviceStreamingProc = await initDeviceStreamingProc(this.adb, this.log, deviceInfo, {\n width,\n height,\n bitRate,\n });\n let gstreamerPipeline;\n try {\n gstreamerPipeline = await initGstreamerPipeline(deviceStreamingProc, deviceInfo, this.log, {\n width,\n height,\n quality,\n tcpPort,\n considerRotation,\n logPipelineDetails,\n });\n } catch (e) {\n if (deviceStreamingProc.kill(0)) {\n deviceStreamingProc.kill();\n }\n throw e;\n }\n\n let mjpegSocket;\n let mjpegServer;\n try {\n await new B((resolve, reject) => {\n mjpegSocket = net.createConnection(tcpPort, TCP_HOST, () => {\n this.log.info(`Successfully connected to MJPEG stream at tcp://${TCP_HOST}:${tcpPort}`);\n mjpegServer = http.createServer((req, res) => {\n const remoteAddress = extractRemoteAddress(req);\n const currentPathname = url.parse(req.url).pathname;\n this.log.info(`Got an incoming screen bradcasting request from ${remoteAddress} ` +\n `(${req.headers['user-agent'] || 'User Agent unknown'}) at ${currentPathname}`);\n\n if (pathname && currentPathname !== pathname) {\n this.log.info('Rejecting the broadcast request since it does not match the given pathname');\n res.writeHead(404, {\n Connection: 'close',\n 'Content-Type': 'text/plain; charset=utf-8',\n });\n res.write(`'${currentPathname}' did not match any known endpoints`);\n res.end();\n return;\n }\n\n this.log.info('Starting MJPEG broadcast');\n res.writeHead(200, {\n 'Cache-Control': 'no-store, no-cache, must-revalidate, pre-check=0, post-check=0, max-age=0',\n Pragma: 'no-cache',\n Connection: 'close',\n 'Content-Type': `multipart/x-mixed-replace; boundary=${BOUNDARY_STRING}`\n });\n\n mjpegSocket.pipe(res);\n });\n mjpegServer.on('error', (e) => {\n this.log.warn(e);\n reject(e);\n });\n mjpegServer.on('close', () => {\n this.log.debug(`MJPEG server at http://${host}:${port} has been closed`);\n });\n mjpegServer.on('listening', () => {\n this.log.info(`Successfully started MJPEG server at http://${host}:${port}`);\n resolve();\n });\n mjpegServer.listen(port, host);\n });\n mjpegSocket.on('error', (e) => {\n this.log.error(e);\n reject(e);\n });\n }).timeout(STREAMING_STARTUP_TIMEOUT_MS,\n `Cannot connect to the streaming server within ${STREAMING_STARTUP_TIMEOUT_MS}ms`);\n } catch (e) {\n if (deviceStreamingProc.kill(0)) {\n deviceStreamingProc.kill();\n }\n if (gstreamerPipeline.isRunning) {\n await gstreamerPipeline.stop();\n }\n if (mjpegSocket) {\n mjpegSocket.destroy();\n }\n if (mjpegServer && mjpegServer.listening) {\n mjpegServer.close();\n }\n throw e;\n }\n\n this._screenStreamingProps = {\n deviceStreamingProc,\n gstreamerPipeline,\n mjpegSocket,\n mjpegServer,\n };\n};\n\n/**\n * Stop screen streaming.\n * If no screen streaming server has been started then nothing is done.\n */\ncommands.mobileStopScreenStreaming = async function mobileStopScreenStreaming (/* options = {} */) {\n if (_.isEmpty(this._screenStreamingProps)) {\n if (!_.isUndefined(this._screenStreamingProps)) {\n this.log.debug(`Screen streaming is not running. There is nothing to stop`);\n }\n return;\n }\n\n const {\n deviceStreamingProc,\n gstreamerPipeline,\n mjpegSocket,\n mjpegServer,\n } = this._screenStreamingProps;\n\n try {\n mjpegSocket.end();\n if (mjpegServer.listening) {\n mjpegServer.close();\n }\n if (deviceStreamingProc.kill(0)) {\n deviceStreamingProc.kill('SIGINT');\n }\n if (gstreamerPipeline.isRunning) {\n try {\n await gstreamerPipeline.stop('SIGINT');\n } catch (e) {\n this.log.warn(e);\n try {\n await gstreamerPipeline.stop('SIGKILL');\n } catch (e1) {\n this.log.error(e1);\n }\n }\n }\n this.log.info(`Successfully terminated the screen streaming MJPEG server`);\n } finally {\n this._screenStreamingProps = null;\n }\n};\n\n\nexport default commands;\n"],"mappings":"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"}