adb-emu-commands.js 37.2 KB
"use strict";

var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = void 0;

require("source-map-support/register");

var _logger = _interopRequireDefault(require("../logger.js"));

var _lodash = _interopRequireDefault(require("lodash"));

var _net = _interopRequireDefault(require("net"));

var _appiumSupport = require("appium-support");

var _bluebird = _interopRequireDefault(require("bluebird"));

const PHONE_NUMBER_PATTERN = /^[+]?[(]?[0-9]*[)]?[-\s.]?[0-9]*[-\s.]?[0-9]{2,}$/im;
let emuMethods = {};
emuMethods.POWER_AC_STATES = {
  POWER_AC_ON: 'on',
  POWER_AC_OFF: 'off'
};
emuMethods.GSM_CALL_ACTIONS = {
  GSM_CALL: 'call',
  GSM_ACCEPT: 'accept',
  GSM_CANCEL: 'cancel',
  GSM_HOLD: 'hold'
};
emuMethods.GSM_VOICE_STATES = {
  GSM_VOICE_UNREGISTERED: 'unregistered',
  GSM_VOICE_HOME: 'home',
  GSM_VOICE_ROAMING: 'roaming',
  GSM_VOICE_SEARCHING: 'searching',
  GSM_VOICE_DENIED: 'denied',
  GSM_VOICE_OFF: 'off',
  GSM_VOICE_ON: 'on'
};
emuMethods.GSM_SIGNAL_STRENGTHS = [0, 1, 2, 3, 4];
emuMethods.NETWORK_SPEED = {
  GSM: 'gsm',
  SCSD: 'scsd',
  GPRS: 'gprs',
  EDGE: 'edge',
  UMTS: 'umts',
  HSDPA: 'hsdpa',
  LTE: 'lte',
  EVDO: 'evdo',
  FULL: 'full'
};
emuMethods.SENSORS = {
  ACCELERATION: 'acceleration',
  LIGHT: 'light',
  PROXIMITY: 'proximity',
  TEMPERATURE: 'temperature',
  PRESSURE: 'pressure',
  HUMIDITY: 'humidity'
};

emuMethods.isEmulatorConnected = async function isEmulatorConnected() {
  let emulators = await this.getConnectedEmulators();
  return !!_lodash.default.find(emulators, x => x && x.udid === this.curDeviceId);
};

emuMethods.verifyEmulatorConnected = async function verifyEmulatorConnected() {
  if (!(await this.isEmulatorConnected())) {
    throw new Error(`The emulator "${this.curDeviceId}" was unexpectedly disconnected`);
  }
};

emuMethods.fingerprint = async function fingerprint(fingerprintId) {
  if (!fingerprintId) {
    throw new Error('Fingerprint id parameter must be defined');
  }

  let level = await this.getApiLevel();

  if (level < 23) {
    throw new Error(`Device API Level must be >= 23. Current Api level '${level}'`);
  }

  await this.adbExecEmu(['finger', 'touch', fingerprintId]);
};

emuMethods.rotate = async function rotate() {
  await this.adbExecEmu(['rotate']);
};

emuMethods.powerAC = async function powerAC(state = 'on') {
  if (_lodash.default.values(emuMethods.POWER_AC_STATES).indexOf(state) === -1) {
    throw new Error(`Wrong power AC state sent '${state}'. Supported values: ${_lodash.default.values(emuMethods.POWER_AC_STATES)}]`);
  }

  await this.adbExecEmu(['power', 'ac', state]);
};

emuMethods.sensorSet = async function sensorSet(sensor, value) {
  if (!_lodash.default.includes(emuMethods.SENSORS, sensor)) {
    throw new Error(`Unsupported sensor sent '${sensor}'. Supported values: ${_lodash.default.values(emuMethods.SENSORS)}]`);
  }

  value = parseFloat(value);

  if (isNaN(value)) {
    throw new Error(`Missing sensor value argument. You need to provide a valid number to set to the sensor.`);
  }

  await this.adbExecEmu(['sensor', 'set', sensor, value]);
};

emuMethods.powerCapacity = async function powerCapacity(percent = 100) {
  percent = parseInt(percent, 10);

  if (isNaN(percent) || percent < 0 || percent > 100) {
    throw new Error(`The percentage value should be valid integer between 0 and 100`);
  }

  await this.adbExecEmu(['power', 'capacity', percent]);
};

emuMethods.powerOFF = async function powerOFF() {
  await this.powerAC(emuMethods.POWER_AC_STATES.POWER_AC_OFF);
  await this.powerCapacity(0);
};

emuMethods.sendSMS = async function sendSMS(phoneNumber, message = '') {
  message = message.trim();

  if (message === '') {
    throw new Error('Sending an SMS requires a message');
  }

  phoneNumber = `${phoneNumber}`.replace(/\s*/, '');

  if (!PHONE_NUMBER_PATTERN.test(phoneNumber)) {
    throw new Error(`Invalid sendSMS phoneNumber param ${phoneNumber}`);
  }

  await this.adbExecEmu(['sms', 'send', phoneNumber, message]);
};

emuMethods.gsmCall = async function gsmCall(phoneNumber, action = '') {
  if (_lodash.default.values(emuMethods.GSM_CALL_ACTIONS).indexOf(action) === -1) {
    throw new Error(`Invalid gsm action param ${action}. Supported values: ${_lodash.default.values(emuMethods.GSM_CALL_ACTIONS)}`);
  }

  phoneNumber = `${phoneNumber}`.replace(/\s*/, '');

  if (!PHONE_NUMBER_PATTERN.test(phoneNumber)) {
    throw new Error(`Invalid gsmCall phoneNumber param ${phoneNumber}`);
  }

  await this.adbExecEmu(['gsm', action, phoneNumber]);
};

emuMethods.gsmSignal = async function gsmSignal(strength = 4) {
  strength = parseInt(strength, 10);

  if (emuMethods.GSM_SIGNAL_STRENGTHS.indexOf(strength) === -1) {
    throw new Error(`Invalid signal strength param ${strength}. Supported values: ${_lodash.default.values(emuMethods.GSM_SIGNAL_STRENGTHS)}`);
  }

  _logger.default.info('gsm signal-profile <strength> changes the reported strength on next (15s) update.');

  await this.adbExecEmu(['gsm', 'signal-profile', strength]);
};

emuMethods.gsmVoice = async function gsmVoice(state = 'on') {
  if (_lodash.default.values(emuMethods.GSM_VOICE_STATES).indexOf(state) === -1) {
    throw new Error(`Invalid gsm voice state param ${state}. Supported values: ${_lodash.default.values(emuMethods.GSM_VOICE_STATES)}`);
  }

  await this.adbExecEmu(['gsm', 'voice', state]);
};

emuMethods.networkSpeed = async function networkSpeed(speed = 'full') {
  if (_lodash.default.values(emuMethods.NETWORK_SPEED).indexOf(speed) === -1) {
    throw new Error(`Invalid network speed param ${speed}. Supported values: ${_lodash.default.values(emuMethods.NETWORK_SPEED)}`);
  }

  await this.adbExecEmu(['network', 'speed', speed]);
};

emuMethods.execEmuConsoleCommand = async function execTelnet(cmd, opts = {}) {
  const portMatch = /emulator-(\d+)/i.exec(this.curDeviceId);

  if (!portMatch) {
    throw new Error(`Cannot parse the console port number from the device identifier '${this.curDeviceId}'. ` + `Is it an emulator?`);
  }

  const host = '127.0.0.1';
  const port = parseInt(portMatch[1], 10);
  const {
    execTimeout = 60000,
    connTimeout = 5000,
    initTimeout = 5000
  } = opts;
  await this.resetTelnetAuthToken();
  const okFlag = /^OK$/m;
  const nokFlag = /^KO\b/m;
  const eol = '\r\n';

  const client = _net.default.connect({
    host,
    port
  });

  return await new _bluebird.default((resolve, reject) => {
    const connTimeoutObj = setTimeout(() => reject(new Error(`Cannot connect to the Emulator console at ${host}:${port} ` + `after ${connTimeout}ms`)), connTimeout);
    let execTimeoutObj;
    let initTimeoutObj;
    let isCommandSent = false;
    let serverResponse = [];
    client.once('error', e => {
      clearTimeout(connTimeoutObj);
      reject(new Error(`Cannot connect to the Emulator console at ${host}:${port}. ` + `Original error: ${e.message}`));
    });
    client.once('connect', () => {
      clearTimeout(connTimeoutObj);
      initTimeoutObj = setTimeout(() => reject(new Error(`Did not get the initial response from the Emulator console at ${host}:${port} ` + `after ${initTimeout}ms`)), initTimeout);
    });
    client.on('data', chunk => {
      serverResponse.push(chunk);
      const output = Buffer.concat(serverResponse).toString('utf8').trim();

      if (okFlag.test(output)) {
        if (!isCommandSent) {
          clearTimeout(initTimeoutObj);
          serverResponse = [];

          _logger.default.debug(`Executing Emulator console command: ${cmd}`);

          client.write(_lodash.default.isArray(cmd) ? _appiumSupport.util.quote(cmd) : cmd);
          client.write(eol);
          isCommandSent = true;
          execTimeoutObj = setTimeout(() => reject(new Error(`Did not get any response from the Emulator console at ${host}:${port} ` + `to '${cmd}' command after ${execTimeout}ms`)), execTimeout);
          return;
        }

        clearTimeout(execTimeoutObj);
        client.end();
        const outputArr = output.split(eol);
        return resolve(outputArr.slice(0, outputArr.length - 1).join('\n').trim());
      } else if (nokFlag.test(output)) {
        clearTimeout(initTimeoutObj);
        clearTimeout(execTimeoutObj);
        client.end();
        const outputArr = output.split(eol);
        return reject(_lodash.default.trim(_lodash.default.last(outputArr)));
      }
    });
  });
};

var _default = emuMethods;
exports.default = _default;require('source-map-support').install();


//# sourceMappingURL=data:application/json;charset=utf8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbImxpYi90b29scy9hZGItZW11LWNvbW1hbmRzLmpzIl0sIm5hbWVzIjpbIlBIT05FX05VTUJFUl9QQVRURVJOIiwiZW11TWV0aG9kcyIsIlBPV0VSX0FDX1NUQVRFUyIsIlBPV0VSX0FDX09OIiwiUE9XRVJfQUNfT0ZGIiwiR1NNX0NBTExfQUNUSU9OUyIsIkdTTV9DQUxMIiwiR1NNX0FDQ0VQVCIsIkdTTV9DQU5DRUwiLCJHU01fSE9MRCIsIkdTTV9WT0lDRV9TVEFURVMiLCJHU01fVk9JQ0VfVU5SRUdJU1RFUkVEIiwiR1NNX1ZPSUNFX0hPTUUiLCJHU01fVk9JQ0VfUk9BTUlORyIsIkdTTV9WT0lDRV9TRUFSQ0hJTkciLCJHU01fVk9JQ0VfREVOSUVEIiwiR1NNX1ZPSUNFX09GRiIsIkdTTV9WT0lDRV9PTiIsIkdTTV9TSUdOQUxfU1RSRU5HVEhTIiwiTkVUV09SS19TUEVFRCIsIkdTTSIsIlNDU0QiLCJHUFJTIiwiRURHRSIsIlVNVFMiLCJIU0RQQSIsIkxURSIsIkVWRE8iLCJGVUxMIiwiU0VOU09SUyIsIkFDQ0VMRVJBVElPTiIsIkxJR0hUIiwiUFJPWElNSVRZIiwiVEVNUEVSQVRVUkUiLCJQUkVTU1VSRSIsIkhVTUlESVRZIiwiaXNFbXVsYXRvckNvbm5lY3RlZCIsImVtdWxhdG9ycyIsImdldENvbm5lY3RlZEVtdWxhdG9ycyIsIl8iLCJmaW5kIiwieCIsInVkaWQiLCJjdXJEZXZpY2VJZCIsInZlcmlmeUVtdWxhdG9yQ29ubmVjdGVkIiwiRXJyb3IiLCJmaW5nZXJwcmludCIsImZpbmdlcnByaW50SWQiLCJsZXZlbCIsImdldEFwaUxldmVsIiwiYWRiRXhlY0VtdSIsInJvdGF0ZSIsInBvd2VyQUMiLCJzdGF0ZSIsInZhbHVlcyIsImluZGV4T2YiLCJzZW5zb3JTZXQiLCJzZW5zb3IiLCJ2YWx1ZSIsImluY2x1ZGVzIiwicGFyc2VGbG9hdCIsImlzTmFOIiwicG93ZXJDYXBhY2l0eSIsInBlcmNlbnQiLCJwYXJzZUludCIsInBvd2VyT0ZGIiwic2VuZFNNUyIsInBob25lTnVtYmVyIiwibWVzc2FnZSIsInRyaW0iLCJyZXBsYWNlIiwidGVzdCIsImdzbUNhbGwiLCJhY3Rpb24iLCJnc21TaWduYWwiLCJzdHJlbmd0aCIsImxvZyIsImluZm8iLCJnc21Wb2ljZSIsIm5ldHdvcmtTcGVlZCIsInNwZWVkIiwiZXhlY0VtdUNvbnNvbGVDb21tYW5kIiwiZXhlY1RlbG5ldCIsImNtZCIsIm9wdHMiLCJwb3J0TWF0Y2giLCJleGVjIiwiaG9zdCIsInBvcnQiLCJleGVjVGltZW91dCIsImNvbm5UaW1lb3V0IiwiaW5pdFRpbWVvdXQiLCJyZXNldFRlbG5ldEF1dGhUb2tlbiIsIm9rRmxhZyIsIm5va0ZsYWciLCJlb2wiLCJjbGllbnQiLCJuZXQiLCJjb25uZWN0IiwiQiIsInJlc29sdmUiLCJyZWplY3QiLCJjb25uVGltZW91dE9iaiIsInNldFRpbWVvdXQiLCJleGVjVGltZW91dE9iaiIsImluaXRUaW1lb3V0T2JqIiwiaXNDb21tYW5kU2VudCIsInNlcnZlclJlc3BvbnNlIiwib25jZSIsImUiLCJjbGVhclRpbWVvdXQiLCJvbiIsImNodW5rIiwicHVzaCIsIm91dHB1dCIsIkJ1ZmZlciIsImNvbmNhdCIsInRvU3RyaW5nIiwiZGVidWciLCJ3cml0ZSIsImlzQXJyYXkiLCJ1dGlsIiwicXVvdGUiLCJlbmQiLCJvdXRwdXRBcnIiLCJzcGxpdCIsInNsaWNlIiwibGVuZ3RoIiwiam9pbiIsImxhc3QiXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7O0FBQUE7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBRUEsTUFBTUEsb0JBQW9CLEdBQUcscURBQTdCO0FBRUEsSUFBSUMsVUFBVSxHQUFHLEVBQWpCO0FBQ0FBLFVBQVUsQ0FBQ0MsZUFBWCxHQUE2QjtBQUMzQkMsRUFBQUEsV0FBVyxFQUFFLElBRGM7QUFFM0JDLEVBQUFBLFlBQVksRUFBRTtBQUZhLENBQTdCO0FBSUFILFVBQVUsQ0FBQ0ksZ0JBQVgsR0FBOEI7QUFDNUJDLEVBQUFBLFFBQVEsRUFBRSxN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LCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgbG9nIGZyb20gJy4uL2xvZ2dlci5qcyc7XG5pbXBvcnQgXyBmcm9tICdsb2Rhc2gnO1xuaW1wb3J0IG5ldCBmcm9tICduZXQnO1xuaW1wb3J0IHsgdXRpbCB9IGZyb20gJ2FwcGl1bS1zdXBwb3J0JztcbmltcG9ydCBCIGZyb20gJ2JsdWViaXJkJztcblxuY29uc3QgUEhPTkVfTlVNQkVSX1BBVFRFUk4gPSAvXlsrXT9bKF0/WzAtOV0qWyldP1stXFxzLl0/WzAtOV0qWy1cXHMuXT9bMC05XXsyLH0kL2ltO1xuXG5sZXQgZW11TWV0aG9kcyA9IHt9O1xuZW11TWV0aG9kcy5QT1dFUl9BQ19TVEFURVMgPSB7XG4gIFBPV0VSX0FDX09OOiAnb24nLFxuICBQT1dFUl9BQ19PRkY6ICdvZmYnXG59O1xuZW11TWV0aG9kcy5HU01fQ0FMTF9BQ1RJT05TID0ge1xuICBHU01fQ0FMTDogJ2NhbGwnLFxuICBHU01fQUNDRVBUOiAnYWNjZXB0JyxcbiAgR1NNX0NBTkNFTDogJ2NhbmNlbCcsXG4gIEdTTV9IT0xEOiAnaG9sZCdcbn07XG5lbXVNZXRob2RzLkdTTV9WT0lDRV9TVEFURVMgPSB7XG4gIEdTTV9WT0lDRV9VTlJFR0lTVEVSRUQ6ICd1bnJlZ2lzdGVyZWQnLFxuICBHU01fVk9JQ0VfSE9NRTogJ2hvbWUnLFxuICBHU01fVk9JQ0VfUk9BTUlORzogJ3JvYW1pbmcnLFxuICBHU01fVk9JQ0VfU0VBUkNISU5HOiAnc2VhcmNoaW5nJyxcbiAgR1NNX1ZPSUNFX0RFTklFRDogJ2RlbmllZCcsXG4gIEdTTV9WT0lDRV9PRkY6ICdvZmYnLFxuICBHU01fVk9JQ0VfT046ICdvbidcbn07XG5lbXVNZXRob2RzLkdTTV9TSUdOQUxfU1RSRU5HVEhTID0gWzAsIDEsIDIsIDMsIDRdO1xuXG5lbXVNZXRob2RzLk5FVFdPUktfU1BFRUQgPSB7XG4gIEdTTTogJ2dzbScsIC8vIEdTTS9DU0QgKHVwOiAxNC40LCBkb3duOiAxNC40KS5cbiAgU0NTRDogJ3Njc2QnLCAvLyBIU0NTRCAodXA6IDE0LjQsIGRvd246IDU3LjYpLlxuICBHUFJTOiAnZ3BycycsIC8vIEdQUlMgKHVwOiAyOC44LCBkb3duOiA1Ny42KS5cbiAgRURHRTogJ2VkZ2UnLCAvLyBFREdFL0VHUFJTICh1cDogNDczLjYsIGRvd246IDQ3My42KS5cbiAgVU1UUzogJ3VtdHMnLCAvLyBVTVRTLzNHICh1cDogMzg0LjAsIGRvd246IDM4NC4wKS5cbiAgSFNEUEE6ICdoc2RwYScsIC8vIEhTRFBBICh1cDogNTc2MC4wLCBkb3duOiAxMyw5ODAuMCkuXG4gIExURTogJ2x0ZScsIC8vIExURSAodXA6IDU4LDAwMCwgZG93bjogMTczLDAwMCkuXG4gIEVWRE86ICdldmRvJywgLy8gRVZETyAodXA6IDc1LDAwMCwgZG93bjogMjgwLDAwMCkuXG4gIEZVTEw6ICdmdWxsJyAvLyBObyBsaW1pdCwgdGhlIGRlZmF1bHQgKHVwOiAwLjAsIGRvd246IDAuMCkuXG59O1xuXG5lbXVNZXRob2RzLlNFTlNPUlMgPSB7XG4gIEFDQ0VMRVJBVElPTjogJ2FjY2VsZXJhdGlvbicsXG4gIExJR0hUOiAnbGlnaHQnLFxuICBQUk9YSU1JVFk6ICdwcm94aW1pdHknLFxuICBURU1QRVJBVFVSRTogJ3RlbXBlcmF0dXJlJyxcbiAgUFJFU1NVUkU6ICdwcmVzc3VyZScsXG4gIEhVTUlESVRZOiAnaHVtaWRpdHknXG59O1xuXG4vKipcbiAqIENoZWNrIHRoZSBlbXVsYXRvciBzdGF0ZS5cbiAqXG4gKiBAcmV0dXJuIHtib29sZWFufSBUcnVlIGlmIEVtdWxhdG9yIGlzIHZpc2libGUgdG8gYWRiLlxuICovXG5lbXVNZXRob2RzLmlzRW11bGF0b3JDb25uZWN0ZWQgPSBhc3luYyBmdW5jdGlvbiBpc0VtdWxhdG9yQ29ubmVjdGVkICgpIHtcbiAgbGV0IGVtdWxhdG9ycyA9IGF3YWl0IHRoaXMuZ2V0Q29ubmVjdGVkRW11bGF0b3JzKCk7XG4gIHJldHVybiAhIV8uZmluZChlbXVsYXRvcnMsICh4KSA9PiB4ICYmIHgudWRpZCA9PT0gdGhpcy5jdXJEZXZpY2VJZCk7XG59O1xuXG4vKipcbiAqIFZlcmlmeSB0aGUgZW11bGF0b3IgaXMgY29ubmVjdGVkLlxuICpcbiAqIEB0aHJvd3Mge2Vycm9yfSBJZiBFbXVsYXRvciBpcyBub3QgdmlzaWJsZSB0byBhZGIuXG4gKi9cbmVtdU1ldGhvZHMudmVyaWZ5RW11bGF0b3JDb25uZWN0ZWQgPSBhc3luYyBmdW5jdGlvbiB2ZXJpZnlFbXVsYXRvckNvbm5lY3RlZCAoKSB7XG4gIGlmICghKGF3YWl0IHRoaXMuaXNFbXVsYXRvckNvbm5lY3RlZCgpKSkge1xuICAgIHRocm93IG5ldyBFcnJvcihgVGhlIGVtdWxhdG9yIFwiJHt0aGlzLmN1ckRldmljZUlkfVwiIHdhcyB1bmV4cGVjdGVkbHkgZGlzY29ubmVjdGVkYCk7XG4gIH1cbn07XG5cbi8qKlxuICogRW11bGF0ZSBmaW5nZXJwcmludCB0b3VjaCBldmVudCBvbiB0aGUgY29ubmVjdGVkIGVtdWxhdG9yLlxuICpcbiAqIEBwYXJhbSB7c3RyaW5nfSBmaW5nZXJwcmludElkIC0gVGhlIElEIG9mIHRoZSBmaW5nZXJwcmludC5cbiAqL1xuZW11TWV0aG9kcy5maW5nZXJwcmludCA9IGFzeW5jIGZ1bmN0aW9uIGZpbmdlcnByaW50IChmaW5nZXJwcmludElkKSB7XG4gIGlmICghZmluZ2VycHJpbnRJZCkge1xuICAgIHRocm93IG5ldyBFcnJvcignRmluZ2VycHJpbnQgaWQgcGFyYW1ldGVyIG11c3QgYmUgZGVmaW5lZCcpO1xuICB9XG4gIC8vIHRoZSBtZXRob2QgdXNlZCBvbmx5IHdvcmtzIGZvciBBUEkgbGV2ZWwgMjMgYW5kIGFib3ZlXG4gIGxldCBsZXZlbCA9IGF3YWl0IHRoaXMuZ2V0QXBpTGV2ZWwoKTtcbiAgaWYgKGxldmVsIDwgMjMpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoYERldmljZSBBUEkgTGV2ZWwgbXVzdCBiZSA+PSAyMy4gQ3VycmVudCBBcGkgbGV2ZWwgJyR7bGV2ZWx9J2ApO1xuICB9XG4gIGF3YWl0IHRoaXMuYWRiRXhlY0VtdShbJ2ZpbmdlcicsICd0b3VjaCcsIGZpbmdlcnByaW50SWRdKTtcbn07XG5cbi8qKlxuICogQ2hhbmdlIHRoZSBkaXNwbGF5IG9yaWVudGF0aW9uIG9uIHRoZSBjb25uZWN0ZWQgZW11bGF0b3IuXG4gKiBUaGUgb3JpZW50YXRpb24gaXMgY2hhbmdlZCAoUEkvMiBpcyBhZGRlZCkgZXZlcnkgdGltZVxuICogdGhpcyBtZXRob2QgaXMgY2FsbGVkLlxuICovXG5lbXVNZXRob2RzLnJvdGF0ZSA9IGFzeW5jIGZ1bmN0aW9uIHJvdGF0ZSAoKSB7XG4gIGF3YWl0IHRoaXMuYWRiRXhlY0VtdShbJ3JvdGF0ZSddKTtcbn07XG5cbi8qKlxuICogRW11bGF0ZSBwb3dlciBzdGF0ZSBjaGFuZ2Ugb24gdGhlIGNvbm5lY3RlZCBlbXVsYXRvci5cbiAqXG4gKiBAcGFyYW0ge3N0cmluZ30gc3RhdGUgWydvbiddIC0gRWl0aGVyICdvbicgb3IgJ29mZicuXG4gKi9cbmVtdU1ldGhvZHMucG93ZXJBQyA9IGFzeW5jIGZ1bmN0aW9uIHBvd2VyQUMgKHN0YXRlID0gJ29uJykge1xuICBpZiAoXy52YWx1ZXMoZW11TWV0aG9kcy5QT1dFUl9BQ19TVEFURVMpLmluZGV4T2Yoc3RhdGUpID09PSAtMSkge1xuICAgIHRocm93IG5ldyBFcnJvcihgV3JvbmcgcG93ZXIgQUMgc3RhdGUgc2VudCAnJHtzdGF0ZX0nLiBTdXBwb3J0ZWQgdmFsdWVzOiAke18udmFsdWVzKGVtdU1ldGhvZHMuUE9XRVJfQUNfU1RBVEVTKX1dYCk7XG4gIH1cbiAgYXdhaXQgdGhpcy5hZGJFeGVjRW11KFsncG93ZXInLCAnYWMnLCBzdGF0ZV0pO1xufTtcblxuLyoqXG4gKiBFbXVsYXRlIHNlbnNvcnMgdmFsdWVzIG9uIHRoZSBjb25uZWN0ZWQgZW11bGF0b3IuXG4gKlxuICogQHBhcmFtIHtzdHJpbmd9IHNlbnNvciAtIFNlbnNvciB0eXBlIGRlY2xhcmVkIGluIFNFTlNPUlMgaXRlbXMuXG4gKiBAcGFyYW0ge251bWJlcnxzdHJpbmd9IHZhbHVlICAtIE51bWJlciB0byBzZXQgYXMgdGhlIHNlbnNvciB2YWx1ZS5cbiAqIEB0aHJvd3Mge0Vycm9yfSAtIElmIHNlbnNvciB0eXBlIG9yIHNlbnNvciB2YWx1ZSBpcyBub3QgZGVmaW5lZFxuICovXG5lbXVNZXRob2RzLnNlbnNvclNldCA9IGFzeW5jIGZ1bmN0aW9uIHNlbnNvclNldCAoc2Vuc29yLCB2YWx1ZSkge1xuICBpZiAoIV8uaW5jbHVkZXMoZW11TWV0aG9kcy5TRU5TT1JTLCBzZW5zb3IpKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKGBVbnN1cHBvcnRlZCBzZW5zb3Igc2VudCAnJHtzZW5zb3J9Jy4gU3VwcG9ydGVkIHZhbHVlczogJHtfLnZhbHVlcyhlbXVNZXRob2RzLlNFTlNPUlMpfV1gKTtcbiAgfVxuICB2YWx1ZSA9IHBhcnNlRmxvYXQodmFsdWUpO1xuICBpZiAoaXNOYU4odmFsdWUpKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKGBNaXNzaW5nIHNlbnNvciB2YWx1ZSBhcmd1bWVudC4gWW91IG5lZWQgdG8gcHJvdmlkZSBhIHZhbGlkIG51bWJlciB0byBzZXQgdG8gdGhlIHNlbnNvci5gKTtcbiAgfVxuICBhd2FpdCB0aGlzLmFkYkV4ZWNFbXUoWydzZW5zb3InLCAnc2V0Jywgc2Vuc29yLCB2YWx1ZV0pO1xufTtcblxuLyoqXG4gKiBFbXVsYXRlIHBvd2VyIGNhcGFjaXR5IGNoYW5nZSBvbiB0aGUgY29ubmVjdGVkIGVtdWxhdG9yLlxuICpcbiAqIEBwYXJhbSB7c3RyaW5nfG51bWJlcn0gcGVyY2VudCBbMTAwXSAtIFBlcmNlbnRhZ2UgdmFsdWUgaW4gcmFuZ2UgWzAsIDEwMF0uXG4gKi9cbmVtdU1ldGhvZHMucG93ZXJDYXBhY2l0eSA9IGFzeW5jIGZ1bmN0aW9uIHBvd2VyQ2FwYWNpdHkgKHBlcmNlbnQgPSAxMDApIHtcbiAgcGVyY2VudCA9IHBhcnNlSW50KHBlcmNlbnQsIDEwKTtcbiAgaWYgKGlzTmFOKHBlcmNlbnQpIHx8IHBlcmNlbnQgPCAwIHx8IHBlcmNlbnQgPiAxMDApIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoYFRoZSBwZXJjZW50YWdlIHZhbHVlIHNob3VsZCBiZSB2YWxpZCBpbnRlZ2VyIGJldHdlZW4gMCBhbmQgMTAwYCk7XG4gIH1cbiAgYXdhaXQgdGhpcy5hZGJFeGVjRW11KFsncG93ZXInLCAnY2FwYWNpdHknLCBwZXJjZW50XSk7XG59O1xuXG4vKipcbiAqIEVtdWxhdGUgcG93ZXIgb2ZmIGV2ZW50IG9uIHRoZSBjb25uZWN0ZWQgZW11bGF0b3IuXG4gKi9cbmVtdU1ldGhvZHMucG93ZXJPRkYgPSBhc3luYyBmdW5jdGlvbiBwb3dlck9GRiAoKSB7XG4gIGF3YWl0IHRoaXMucG93ZXJBQyhlbXVNZXRob2RzLlBPV0VSX0FDX1NUQVRFUy5QT1dFUl9BQ19PRkYpO1xuICBhd2FpdCB0aGlzLnBvd2VyQ2FwYWNpdHkoMCk7XG59O1xuXG4vKipcbiAqIEVtdWxhdGUgc2VuZCBTTVMgZXZlbnQgb24gdGhlIGNvbm5lY3RlZCBlbXVsYXRvci5cbiAqXG4gKiBAcGFyYW0ge3N0cmluZ3xudW1iZXJ9IHBob25lTnVtYmVyIC0gVGhlIHBob25lIG51bWJlciBvZiBtZXNzYWdlIHNlbmRlci5cbiAqIEBwYXJhbSB7c3RyaW5nfSBtZXNzYWdlIFsnJ10gLSBUaGUgbWVzc2FnZSBjb250ZW50LlxuICogQHRocm93cyB7ZXJyb3J9IElmIHBob25lIG51bWJlciBoYXMgaW52YWxpZCBmb3JtYXQuXG4gKi9cbmVtdU1ldGhvZHMuc2VuZFNNUyA9IGFzeW5jIGZ1bmN0aW9uIHNlbmRTTVMgKHBob25lTnVtYmVyLCBtZXNzYWdlID0gJycpIHtcbiAgbWVzc2FnZSA9IG1lc3NhZ2UudHJpbSgpO1xuICBpZiAobWVzc2FnZSA9PT0gJycpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ1NlbmRpbmcgYW4gU01TIHJlcXVpcmVzIGEgbWVzc2FnZScpO1xuICB9XG4gIHBob25lTnVtYmVyID0gYCR7cGhvbmVOdW1iZXJ9YC5yZXBsYWNlKC9cXHMqLywgJycpO1xuICBpZiAoIVBIT05FX05VTUJFUl9QQVRURVJOLnRlc3QocGhvbmVOdW1iZXIpKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKGBJbnZhbGlkIHNlbmRTTVMgcGhvbmVOdW1iZXIgcGFyYW0gJHtwaG9uZU51bWJlcn1gKTtcbiAgfVxuICBhd2FpdCB0aGlzLmFkYkV4ZWNFbXUoWydzbXMnLCAnc2VuZCcsIHBob25lTnVtYmVyLCBtZXNzYWdlXSk7XG59O1xuXG4vKipcbiAqIEVtdWxhdGUgR1NNIGNhbGwgZXZlbnQgb24gdGhlIGNvbm5lY3RlZCBlbXVsYXRvci5cbiAqXG4gKiBAcGFyYW0ge3N0cmluZ3xudW1iZXJ9IHBob25lTnVtYmVyIC0gVGhlIHBob25lIG51bWJlciBvZiB0aGUgY2FsbGVyLlxuICogQHBhcmFtIHtzdHJpbmd9IGFjdGlvbiBbJyddIC0gT25lIG9mIGF2YWlsYWJsZSBHU00gY2FsbCBhY3Rpb25zLlxuICogQHRocm93cyB7ZXJyb3J9IElmIHBob25lIG51bWJlciBoYXMgaW52YWxpZCBmb3JtYXQuXG4gKiBAdGhyb3dzIHtlcnJvcn0gSWYgX2FjdGlvbl8gdmFsdWUgaXMgaW52YWxpZC5cbiAqL1xuZW11TWV0aG9kcy5nc21DYWxsID0gYXN5bmMgZnVuY3Rpb24gZ3NtQ2FsbCAocGhvbmVOdW1iZXIsIGFjdGlvbiA9ICcnKSB7XG4gIGlmIChfLnZhbHVlcyhlbXVNZXRob2RzLkdTTV9DQUxMX0FDVElPTlMpLmluZGV4T2YoYWN0aW9uKSA9PT0gLTEpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoYEludmFsaWQgZ3NtIGFjdGlvbiBwYXJhbSAke2FjdGlvbn0uIFN1cHBvcnRlZCB2YWx1ZXM6ICR7Xy52YWx1ZXMoZW11TWV0aG9kcy5HU01fQ0FMTF9BQ1RJT05TKX1gKTtcbiAgfVxuICBwaG9uZU51bWJlciA9IGAke3Bob25lTnVtYmVyfWAucmVwbGFjZSgvXFxzKi8sICcnKTtcbiAgaWYgKCFQSE9ORV9OVU1CRVJfUEFUVEVSTi50ZXN0KHBob25lTnVtYmVyKSkge1xuICAgIHRocm93IG5ldyBFcnJvcihgSW52YWxpZCBnc21DYWxsIHBob25lTnVtYmVyIHBhcmFtICR7cGhvbmVOdW1iZXJ9YCk7XG4gIH1cbiAgYXdhaXQgdGhpcy5hZGJFeGVjRW11KFsnZ3NtJywgYWN0aW9uLCBwaG9uZU51bWJlcl0pO1xufTtcblxuLyoqXG4gKiBFbXVsYXRlIEdTTSBzaWduYWwgc3RyZW5ndGggY2hhbmdlIGV2ZW50IG9uIHRoZSBjb25uZWN0ZWQgZW11bGF0b3IuXG4gKlxuICogQHBhcmFtIHtzdHJpbmd8bnVtYmVyfSBzdHJlbmd0aCBbNF0gLSBBIG51bWJlciBpbiByYW5nZSBbMCwgNF07XG4gKiBAdGhyb3dzIHtlcnJvcn0gSWYgX3N0cmVuZ3RoXyB2YWx1ZSBpcyBpbnZhbGlkLlxuICovXG5lbXVNZXRob2RzLmdzbVNpZ25hbCA9IGFzeW5jIGZ1bmN0aW9uIGdzbVNpZ25hbCAoc3RyZW5ndGggPSA0KSB7XG4gIHN0cmVuZ3RoID0gcGFyc2VJbnQoc3RyZW5ndGgsIDEwKTtcbiAgaWYgKGVtdU1ldGhvZHMuR1NNX1NJR05BTF9TVFJFTkdUSFMuaW5kZXhPZihzdHJlbmd0aCkgPT09IC0xKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKGBJbnZhbGlkIHNpZ25hbCBzdHJlbmd0aCBwYXJhbSAke3N0cmVuZ3RofS4gU3VwcG9ydGVkIHZhbHVlczogJHtfLnZhbHVlcyhlbXVNZXRob2RzLkdTTV9TSUdOQUxfU1RSRU5HVEhTKX1gKTtcbiAgfVxuICBsb2cuaW5mbygnZ3NtIHNpZ25hbC1wcm9maWxlIDxzdHJlbmd0aD4gY2hhbmdlcyB0aGUgcmVwb3J0ZWQgc3RyZW5ndGggb24gbmV4dCAoMTVzKSB1cGRhdGUuJyk7XG4gIGF3YWl0IHRoaXMuYWRiRXhlY0VtdShbJ2dzbScsICdzaWduYWwtcHJvZmlsZScsIHN0cmVuZ3RoXSk7XG59O1xuXG4vKipcbiAqIEVtdWxhdGUgR1NNIHZvaWNlIGV2ZW50IG9uIHRoZSBjb25uZWN0ZWQgZW11bGF0b3IuXG4gKlxuICogQHBhcmFtIHtzdHJpbmd9IHN0YXRlIFsnb24nXSAtIEVpdGhlciAnb24nIG9yICdvZmYnLlxuICogQHRocm93cyB7ZXJyb3J9IElmIF9zdGF0ZV8gdmFsdWUgaXMgaW52YWxpZC5cbiAqL1xuZW11TWV0aG9kcy5nc21Wb2ljZSA9IGFzeW5jIGZ1bmN0aW9uIGdzbVZvaWNlIChzdGF0ZSA9ICdvbicpIHtcbiAgLy8gZ3NtIHZvaWNlIDxzdGF0ZT4gYWxsb3dzIHlvdSB0byBjaGFuZ2UgdGhlIHN0YXRlIG9mIHlvdXIgR1BSUyBjb25uZWN0aW9uXG4gIGlmIChfLnZhbHVlcyhlbXVNZXRob2RzLkdTTV9WT0lDRV9TVEFURVMpLmluZGV4T2Yoc3RhdGUpID09PSAtMSkge1xuICAgIHRocm93IG5ldyBFcnJvcihgSW52YWxpZCBnc20gdm9pY2Ugc3RhdGUgcGFyYW0gJHtzdGF0ZX0uIFN1cHBvcnRlZCB2YWx1ZXM6ICR7Xy52YWx1ZXMoZW11TWV0aG9kcy5HU01fVk9JQ0VfU1RBVEVTKX1gKTtcbiAgfVxuICBhd2FpdCB0aGlzLmFkYkV4ZWNFbXUoWydnc20nLCAndm9pY2UnLCBzdGF0ZV0pO1xufTtcblxuLyoqXG4gKiBFbXVsYXRlIG5ldHdvcmsgc3BlZWQgY2hhbmdlIGV2ZW50IG9uIHRoZSBjb25uZWN0ZWQgZW11bGF0b3IuXG4gKlxuICogQHBhcmFtIHtzdHJpbmd9IHNwZWVkIFsnZnVsbCddIC0gT25lIG9mIHBvc3NpYmxlIE5FVFdPUktfU1BFRUQgdmFsdWVzLlxuICogQHRocm93cyB7ZXJyb3J9IElmIF9zcGVlZF8gdmFsdWUgaXMgaW52YWxpZC5cbiAqL1xuZW11TWV0aG9kcy5uZXR3b3JrU3BlZWQgPSBhc3luYyBmdW5jdGlvbiBuZXR3b3JrU3BlZWQgKHNwZWVkID0gJ2Z1bGwnKSB7XG4gIC8vIG5ldHdvcmsgc3BlZWQgPHNwZWVkPiBhbGxvd3MgeW91IHRvIHNldCB0aGUgbmV0d29yayBzcGVlZCBlbXVsYXRpb24uXG4gIGlmIChfLnZhbHVlcyhlbXVNZXRob2RzLk5FVFdPUktfU1BFRUQpLmluZGV4T2Yoc3BlZWQpID09PSAtMSkge1xuICAgIHRocm93IG5ldyBFcnJvcihgSW52YWxpZCBuZXR3b3JrIHNwZWVkIHBhcmFtICR7c3BlZWR9LiBTdXBwb3J0ZWQgdmFsdWVzOiAke18udmFsdWVzKGVtdU1ldGhvZHMuTkVUV09SS19TUEVFRCl9YCk7XG4gIH1cbiAgYXdhaXQgdGhpcy5hZGJFeGVjRW11KFsnbmV0d29yaycsICdzcGVlZCcsIHNwZWVkXSk7XG59O1xuXG4vKipcbiAqIEB0eXBlZGVmIHtPYmplY3R9IEV4ZWNUZWxuZXRPcHRpb25zXG4gKiBAcHJvcGVydHkge251bWJlcn0gZXhlY1RpbWVvdXQgWzYwMDAwXSBBIHRpbWVvdXQgdXNlZCB0byB3YWl0IGZvciBhIHNlcnZlclxuICogcmVwbHkgdG8gdGhlIGdpdmVuIGNvbW1hbmRcbiAqIEBwcm9wZXJ0eSB7bnVtYmVyfSBjb25uVGltZW91dCBbNTAwMF0gQ29uc29sZSBjb25uZWN0aW9uIHRpbWVvdXQgaW4gbWlsbGlzZWNvbmRzXG4gKiBAcHJvcGVydHkge251bWJlcn0gaW5pdFRpbWVvdXQgWzUwMDBdIFRlbG5ldCBjb25zb2xlIGluaXRpYWxpemF0aW9uIHRpbWVvdXRcbiAqIGluIG1pbGxpc2Vjb25kcyAodGhlIHRpbWUgYmV0d2VlbiBjb25uZWN0aW9uIGhhcHBlbnMgYW5kIHRoZSBjb21tYW5kIHByb21wdFxuICogaXMgYXZhaWxhYmxlKVxuICovXG5cbi8qKlxuICogRXhlY3V0ZXMgYSBjb21tYW5kIHRocm91Z2ggZW11bGF0b3IgdGVsbmV0IGNvbnNvbGUgaW50ZXJmYWNlIGFuZCByZXR1cm5zIGl0cyBvdXRwdXRcbiAqXG4gKiBAcGFyYW0ge0FycmF5PHN0cmluZz58c3RyaW5nfSBjbWQgLSBUaGUgYWN0dWFsIGNvbW1hbmQgdG8gZXhlY3V0ZS4gU2VlXG4gKiBodHRwczovL2RldmVsb3Blci5hbmRyb2lkLmNvbS9zdHVkaW8vcnVuL2VtdWxhdG9yLWNvbnNvbGUgZm9yIG1vcmUgZGV0YWlsc1xuICogb24gYXZhaWxhYmxlIGNvbW1hbmRzXG4gKiBAcGFyYW0ge0V4ZWNUZWxuZXRPcHRpb25zfSBvcHRzXG4gKiBAcmV0dXJucyB7c3RyaW5nfSBUaGUgY29tbWFuZCBvdXRwdXRcbiAqIEB0aHJvd3Mge0Vycm9yfSBJZiB0aGVyZSB3YXMgYW4gZXJyb3Igd2hpbGUgY29ubmVjdGluZyB0byB0aGUgVGVsbmV0IGNvbnNvbGVcbiAqIG9yIGlmIHRoZSBnaXZlbiBjb21tYW5kIHJldHVybmVkIG5vbi1PSyByZXNwb25zZVxuICovXG5lbXVNZXRob2RzLmV4ZWNFbXVDb25zb2xlQ29tbWFuZCA9IGFzeW5jIGZ1bmN0aW9uIGV4ZWNUZWxuZXQgKGNtZCwgb3B0cyA9IHt9KSB7XG4gIGNvbnN0IHBvcnRNYXRjaCA9IC9lbXVsYXRvci0oXFxkKykvaS5leGVjKHRoaXMuY3VyRGV2aWNlSWQpO1xuICBpZiAoIXBvcnRNYXRjaCkge1xuICAgIHRocm93IG5ldyBFcnJvcihgQ2Fubm90IHBhcnNlIHRoZSBjb25zb2xlIHBvcnQgbnVtYmVyIGZyb20gdGhlIGRldmljZSBpZGVudGlmaWVyICcke3RoaXMuY3VyRGV2aWNlSWR9Jy4gYCArXG4gICAgICBgSXMgaXQgYW4gZW11bGF0b3I/YCk7XG4gIH1cbiAgY29uc3QgaG9zdCA9ICcxMjcuMC4wLjEnO1xuICBjb25zdCBwb3J0ID0gcGFyc2VJbnQocG9ydE1hdGNoWzFdLCAxMCk7XG4gIGNvbnN0IHtcbiAgICBleGVjVGltZW91dCA9IDYwMDAwLFxuICAgIGNvbm5UaW1lb3V0ID0gNTAwMCxcbiAgICBpbml0VGltZW91dCA9IDUwMDAsXG4gIH0gPSBvcHRzO1xuICBhd2FpdCB0aGlzLnJlc2V0VGVsbmV0QXV0aFRva2VuKCk7XG5cbiAgY29uc3Qgb2tGbGFnID0gL15PSyQvbTtcbiAgY29uc3Qgbm9rRmxhZyA9IC9eS09cXGIvbTtcbiAgY29uc3QgZW9sID0gJ1xcclxcbic7XG4gIGNvbnN0IGNsaWVudCA9IG5ldC5jb25uZWN0KHtcbiAgICBob3N0LFxuICAgIHBvcnQsXG4gIH0pO1xuXG4gIHJldHVybiBhd2FpdCBuZXcgQigocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgY29uc3QgY29ublRpbWVvdXRPYmogPSBzZXRUaW1lb3V0KFxuICAgICAgKCkgPT4gcmVqZWN0KG5ldyBFcnJvcihgQ2Fubm90IGNvbm5lY3QgdG8gdGhlIEVtdWxhdG9yIGNvbnNvbGUgYXQgJHtob3N0fToke3BvcnR9IGAgK1xuICAgICAgICBgYWZ0ZXIgJHtjb25uVGltZW91dH1tc2ApKSwgY29ublRpbWVvdXQpO1xuICAgIGxldCBleGVjVGltZW91dE9iajtcbiAgICBsZXQgaW5pdFRpbWVvdXRPYmo7XG4gICAgbGV0IGlzQ29tbWFuZFNlbnQgPSBmYWxzZTtcbiAgICBsZXQgc2VydmVyUmVzcG9uc2UgPSBbXTtcblxuICAgIGNsaWVudC5vbmNlKCdlcnJvcicsIChlKSA9PiB7XG4gICAgICBjbGVhclRpbWVvdXQoY29ublRpbWVvdXRPYmopO1xuICAgICAgcmVqZWN0KG5ldyBFcnJvcihgQ2Fubm90IGNvbm5lY3QgdG8gdGhlIEVtdWxhdG9yIGNvbnNvbGUgYXQgJHtob3N0fToke3BvcnR9LiBgICtcbiAgICAgICAgYE9yaWdpbmFsIGVycm9yOiAke2UubWVzc2FnZX1gKSk7XG4gICAgfSk7XG5cbiAgICBjbGllbnQub25jZSgnY29ubmVjdCcsICgpID0+IHtcbiAgICAgIGNsZWFyVGltZW91dChjb25uVGltZW91dE9iaik7XG4gICAgICBpbml0VGltZW91dE9iaiA9IHNldFRpbWVvdXQoXG4gICAgICAgICgpID0+IHJlamVjdChuZXcgRXJyb3IoYERpZCBub3QgZ2V0IHRoZSBpbml0aWFsIHJlc3BvbnNlIGZyb20gdGhlIEVtdWxhdG9yIGNvbnNvbGUgYXQgJHtob3N0fToke3BvcnR9IGAgK1xuICAgICAgICAgIGBhZnRlciAke2luaXRUaW1lb3V0fW1zYCkpLCBpbml0VGltZW91dCk7XG4gICAgfSk7XG5cbiAgICBjbGllbnQub24oJ2RhdGEnLCAoY2h1bmspID0+IHtcbiAgICAgIHNlcnZlclJlc3BvbnNlLnB1c2goY2h1bmspO1xuICAgICAgY29uc3Qgb3V0cHV0ID0gQnVmZmVyLmNvbmNhdChzZXJ2ZXJSZXNwb25zZSkudG9TdHJpbmcoJ3V0ZjgnKS50cmltKCk7XG4gICAgICBpZiAob2tGbGFnLnRlc3Qob3V0cHV0KSkge1xuICAgICAgICAvLyBUaGUgaW5pdGlhbCBpbmNvbWluZyBkYXRhIGNodW5rIGNvbmZpcm1zIHRoZSBpbnRlcmZhY2UgaXMgcmVhZHkgZm9yIGlucHV0XG4gICAgICAgIGlmICghaXNDb21tYW5kU2VudCkge1xuICAgICAgICAgIGNsZWFyVGltZW91dChpbml0VGltZW91dE9iaik7XG4gICAgICAgICAgc2VydmVyUmVzcG9uc2UgPSBbXTtcbiAgICAgICAgICBsb2cuZGVidWcoYEV4ZWN1dGluZyBFbXVsYXRvciBjb25zb2xlIGNvbW1hbmQ6ICR7Y21kfWApO1xuICAgICAgICAgIGNsaWVudC53cml0ZShfLmlzQXJyYXkoY21kKSA/IHV0aWwucXVvdGUoY21kKSA6IGNtZCk7XG4gICAgICAgICAgY2xpZW50LndyaXRlKGVvbCk7XG4gICAgICAgICAgaXNDb21tYW5kU2VudCA9IHRydWU7XG4gICAgICAgICAgZXhlY1RpbWVvdXRPYmogPSBzZXRUaW1lb3V0KFxuICAgICAgICAgICAgKCkgPT4gcmVqZWN0KG5ldyBFcnJvcihgRGlkIG5vdCBnZXQgYW55IHJlc3BvbnNlIGZyb20gdGhlIEVtdWxhdG9yIGNvbnNvbGUgYXQgJHtob3N0fToke3BvcnR9IGAgK1xuICAgICAgICAgICAgICBgdG8gJyR7Y21kfScgY29tbWFuZCBhZnRlciAke2V4ZWNUaW1lb3V0fW1zYCkpLCBleGVjVGltZW91dCk7XG4gICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIGNsZWFyVGltZW91dChleGVjVGltZW91dE9iaik7XG4gICAgICAgIGNsaWVudC5lbmQoKTtcbiAgICAgICAgY29uc3Qgb3V0cHV0QXJyID0gb3V0cHV0LnNwbGl0KGVvbCk7XG4gICAgICAgIC8vIHJlbW92ZSB0aGUgcmVkdW5kYW50IE9LIGZsYWcgZnJvbSB0aGUgcmVzdWx0aW5nIGNvbW1hbmQgb3V0cHV0XG4gICAgICAgIHJldHVybiByZXNvbHZlKG91dHB1dEFyci5zbGljZSgwLCBvdXRwdXRBcnIubGVuZ3RoIC0gMSkuam9pbignXFxuJykudHJpbSgpKTtcbiAgICAgIH0gZWxzZSBpZiAobm9rRmxhZy50ZXN0KG91dHB1dCkpIHtcbiAgICAgICAgY2xlYXJUaW1lb3V0KGluaXRUaW1lb3V0T2JqKTtcbiAgICAgICAgY2xlYXJUaW1lb3V0KGV4ZWNUaW1lb3V0T2JqKTtcbiAgICAgICAgY2xpZW50LmVuZCgpO1xuICAgICAgICBjb25zdCBvdXRwdXRBcnIgPSBvdXRwdXQuc3BsaXQoZW9sKTtcbiAgICAgICAgcmV0dXJuIHJlamVjdChfLnRyaW0oXy5sYXN0KG91dHB1dEFycikpKTtcbiAgICAgIH1cbiAgICB9KTtcbiAgfSk7XG59O1xuXG5leHBvcnQgZGVmYXVsdCBlbXVNZXRob2RzO1xuIl0sImZpbGUiOiJsaWIvdG9vbHMvYWRiLWVtdS1jb21tYW5kcy5qcyIsInNvdXJjZVJvb3QiOiIuLi8uLi8uLiJ9