HotUpdate.js 42.9 KB

                (function() {
                    var nodeEnv = typeof require !== 'undefined' && typeof process !== 'undefined';
                    var __module = nodeEnv ? module : {exports:{}};
                    var __filename = 'preview-scripts/assets/script/game/HotUpdate.js';
                    var __require = nodeEnv ? function (request) {
                        return cc.require(request);
                    } : function (request) {
                        return __quick_compile_project__.require(request, __filename);
                    };
                    function __define (exports, require, module) {
                        if (!nodeEnv) {__quick_compile_project__.registerModule(__filename, module);}"use strict";
cc._RF.push(module, '652b3iryalEoZXjTEltvgH1', 'HotUpdate');
// script/game/HotUpdate.js

"use strict";

// var md5 = require("md5")
var EventCenter = require("EventCenter");

var g_check = false;
cc.Class({
  "extends": cc.Component,
  properties: {
    _searchPath: "",
    //搜索路径
    manifestUrl: {
      type: cc.Asset,
      // use 'type:' to declare an object reference
      "default": null // object's default value is null

    },
    _checkUpdate: false,
    _checkUpdateNum: 5,
    //检查更新次数
    _updating: false,
    //正在检查更新或者更新中
    _isForceUpdate: false,
    _loadFiles: "yybs-remote-asset",
    byteProgress: cc.ProgressBar,
    //字节进度
    fileProgress: cc.ProgressBar,
    //文件进度
    info: cc.Label,
    //信息显示
    fileLabel: cc.Label,
    //文件个数
    byteLabel: cc.Label,
    //字节个数
    // retryBtn: cc.Button,//重置按钮
    // checkBtn: cc.Button,//检查更新按钮 目前是自动得
    // updateBtn: cc.Button,//更新按钮  目前是自动的
    forceUpdate: cc.Layout,
    //强更界面
    ensureBut: cc.Button,
    //确定按钮
    _forceHotUpdate: ""
  },
  start: function start() {
    // if (CC_DEBUG) {//发布debug模式apk跳过热更
    //     this.startGame();//隐藏当前ui//多场景时 这直接加载下一个场景
    // }
    if (!cc.sys.isNative) //web//跳过热更 
      {
        this.startGame(); //隐藏当前ui//多场景时 这直接加载下一个场景
      } else {
      this.hotUpdateInit();
      this.hotUpdateLogic(); //热更逻辑

      var delay = cc.delayTime(10);
      var finishedAll = cc.callFunc(this.overTimeStartGame, this);
      this.node.runAction(cc.sequence(delay, finishedAll));
    }
  },
  checkCb: function checkCb(event) {
    this._checkUpdate = false; //检测更新完毕

    this._updating = false; //更新中

    switch (event.getEventCode()) {
      case jsb.EventAssetsManager.ERROR_NO_LOCAL_MANIFEST:
        this.showUpDateInfo('检查更新失败');
        g_check = true;
        break;

      case jsb.EventAssetsManager.ERROR_DOWNLOAD_MANIFEST:
      case jsb.EventAssetsManager.ERROR_PARSE_MANIFEST:
        this.showUpDateInfo('检查更新失败');
        g_check = true;
        break;

      case jsb.EventAssetsManager.ALREADY_UP_TO_DATE:
        this.showUpDateInfo('已是最新版本');

        if (this._isForceUpdate == false) {
          this.startGame();
          return;
        }

        break;

      case jsb.EventAssetsManager.NEW_VERSION_FOUND:
        this.showUpDateInfo('发现新版本,正在更新...');
        g_check = false;
        break;

      default:
        return;
    }

    if (g_check == true) {
      this.checkUpdate();
    } else {
      this.hotUpdate();
    }
  },
  overTimeStartGame: function overTimeStartGame() {
    if (this.node.active == true && this._checkUpdate == true) {
      this.startGame();
    }
  },
  startGame: function startGame() //开始游戏
  {
    this.node.active = false;
    cc.log("开始游戏");
    EventCenter.EventCenter.GameStart.emit();
  },
  hotUpdateInit: function hotUpdateInit() {
    var self = this;
    this.ensureBut.node.on('click', function (event) {
      self.ensureButCallBack();
    }, this);
  },
  ensureButCallBack: function ensureButCallBack() //确定按钮回掉
  {
    // cc.sys.openURL('http://formal.share.idj66nm.com/down/link?gameId=200001&gameState=1');//强更下载地址
    cc.director.end();
  },
  hotUpdateLogic: function hotUpdateLogic() //热更逻辑
  {
    this.initAssetsManager();
    this.checkUpdate();
  },
  forceUpdateLogic: function forceUpdateLogic() //强更逻辑
  {
    this._isForceUpdate = true;
    this.forceUpdate.node.active = true;
  },
  initAssetsManager: function initAssetsManager() //初始化
  {
    this._searchPath = (jsb.fileUtils ? jsb.fileUtils.getWritablePath() : '/') + this._loadFiles; //获取热更时得搜索路径

    cc.log('hotUpdate searchPath =' + this._searchPath);
    var self = this;

    var versionCompareHandle = function versionCompareHandle(versionA, versionB) //版本对比函数(检查本地mainfest和远端mainfes时,如果返回值大于0 会自动更新)
    {
      cc.log("JS Custom Version Compare: version A is " + versionA + ', version B is ' + versionB);
      var vA = versionA.split('.');
      var vB = versionB.split('.');
      if (vA.length != vB.length || vA.length < 3) return 0;

      if (parseInt(vA[0]) != parseInt(vB[0])) //前两位控制大版本更新
        {
          //强制更新
          self.forceUpdateLogic();
          return 0;
        }

      self._forceHotUpdate = vA[0] + "" + vA[1];
      var forceUpdate = cc.sys.localStorage.getItem('forceupdateyybs');
      cc.log("initAssetsManager forceupdate " + forceUpdate);
      self._forceHotUpdate = vB[0] + "" + vB[1];

      for (var i = 0; i < vA.length; ++i) {
        var a = parseInt(vA[i]);
        var b = parseInt(vB[i] || 0);

        if (a === b) {
          continue;
        }

        return -1;
      }

      if (vB.length > vA.length) {
        return -1;
      }

      cc.sys.localStorage.setItem('forceupdateyybs', self._forceHotUpdate);
      return 0;
    };

    this._am = new jsb.AssetsManager(this.manifestUrl, this._searchPath, versionCompareHandle); //初始化 创建 AssetsManager
    // if (!cc.sys.ENABLE_GC_FOR_NATIVE_OBJECTS)
    // {
    //     this._am.retain();
    // }
    //用户文件校验接口 由于下载过程中仍然有小概率可能由于网络原因或其他网络库的问题导致下载的文件内容有问题,
    //在文件下载完成后热更新管理器会调用这个接口,如果返回 true 表示文件正常,返回 false 表示文件有问题

    this._am.setVerifyCallback(function (path, asset) {
      var compressed = asset.compressed; // 是压缩文件 不需要检查它的md5

      var expectedMD5 = asset.md5; //检索md5值。

      var relativePath = asset.path; // asset.path 是相对路径 path 绝对路径.

      var size = asset.size; //文件的大小,但是这个值可能不存在

      if (compressed) {
        return true;
      } else {
        return true; // //使用绝对路径来加载文件,之后计算md5值
        // var data = jsb.fileUtils.getDataFromFile(path);
        // var curMD5 = md5(data);
        // if (curMD5 == asset.md5) {
        //     //md5检验通过
        //     return true;
        // } else {
        //     //md5检验失败
        //     //this.info.string = relativePath + "文件MD5校验失败";
        //     cc.log("md5检验失败");
        //     return false;
        // }
      }
    });

    if (cc.sys.os === cc.sys.OS_ANDROID) {
      //控制下载并发数量的 API 有些Android设备可能会在并发任务太多时减慢下载速度。设置适合游戏的值。
      this._am.setMaxConcurrentTask(2);
    }
  },
  checkUpdate: function checkUpdate() //检查更新
  {
    this._checkUpdateNum = this._checkUpdateNum - 1;

    if (this._checkUpdateNum <= 0) {
      //直接登陆
      this.startGame();
      return;
    }

    if (this._updating) {
      this.showUpDateInfo('正在检测或者更新中,请耐心等待...');
      return;
    }

    this._am.setEventCallback(this.checkCb.bind(this));

    if (this._am.getState() === jsb.AssetsManager.State.UNINITED) {
      var url = this.manifestUrl.nativeUrl;

      if (cc.loader.md5Pipe) {
        url = cc.loader.md5Pipe.transformURL(url);
      }

      cc.log('加载本地Manifest', url);

      this._am.loadLocalManifest(url);
    }

    this._am.checkUpdate();

    this._checkUpdate = true; //正在检测更新

    this.showUpDateInfo('正在检测更新,请耐心等待...');
  },
  hotUpdate: function hotUpdate() {
    if (this._am == null) {
      return;
    }

    this._am.setEventCallback(this.updateCb.bind(this));

    if (this._am.getState() === jsb.AssetsManager.State.UNINITED) {
      this._am.loadLocalManifest(this.manifestUrl);
    }

    this._am.update();

    this._updating = true;
  },
  updateCb: function updateCb(event) {
    var needRestart = false;
    var failed = false;

    switch (event.getEventCode()) {
      case jsb.EventAssetsManager.ERROR_NO_LOCAL_MANIFEST:
        cc.log('错误:没找到本地manifest文件');
        failed = true;
        break;

      case jsb.EventAssetsManager.UPDATE_PROGRESSION:
        //更新进度
        this.byteProgress.progress = event.getPercent();
        this.fileProgress.progress = event.getPercentByFile();
        this.fileLabel.node.active = true;
        this.fileLabel.string = event.getDownloadedFiles() + ' / ' + event.getTotalFiles();
        this.byteLabel.string = event.getDownloadedBytes() / 1024 + ' / ' + event.getTotalBytes() / 1024;
        var msg = event.getMessage();

        if (msg) {// cc.log(event.getPercent()/100 + '% : ' + msg);
        }

        break;

      case jsb.EventAssetsManager.ERROR_DOWNLOAD_MANIFEST:
      case jsb.EventAssetsManager.ERROR_PARSE_MANIFEST:
        cc.log('错误:下载或解析MANIFEST文件失败');
        failed = true;
        break;

      case jsb.EventAssetsManager.ALREADY_UP_TO_DATE:
        this.showUpDateInfo('与服务器版本一致');
        if (this._isForceUpdate == false) this.startGame();
        break;

      case jsb.EventAssetsManager.UPDATE_FINISHED:
        this.showUpDateInfo('更新完成');
        this._updating = false;
        needRestart = true;
        break;

      case jsb.EventAssetsManager.UPDATE_FAILED:
        //更新失败
        this._updating = false;
        failed = true;
        break;

      case jsb.EventAssetsManager.ERROR_UPDATING:
        if (event.getMessage()) {
          this.info.string = '更新' + event.getAssetId() + '时发生错误.' + event.getMessage();
        } else {
          this.info.string = '更新' + event.getAssetId() + '时发生错误';
        }

        needRestart = true;
        break;

      case jsb.EventAssetsManager.ERROR_DECOMPRESS:
        this.showUpDateInfo('解压发生错误.' + event.getMessage());
        break;

      default:
        break;
    }

    if (needRestart) {
      this.restartGame();
      return;
    }

    if (failed) {
      this._updating = false;
      this.checkUpdate();
    }
  },
  onDestroy: function onDestroy() {
    if (this._am) this._am.setEventCallback(null);
  },
  restartGame: function restartGame() //重启游戏
  {
    this.fileProgress.progress = 1;
    this.byteProgress.progress = 1;
    var searchPaths = jsb.fileUtils.getSearchPaths();

    var newPaths = this._am.getLocalManifest().getSearchPaths();

    Array.prototype.unshift(searchPaths, newPaths);
    cc.sys.localStorage.setItem('HotUpdateSearchPaths', JSON.stringify(searchPaths));
    cc.sys.localStorage.setItem('forceupdateyybs', this._forceHotUpdate);
    jsb.fileUtils.setSearchPaths(searchPaths);
    cc.audioEngine.stopAll();
    cc.game.restart();
  },
  //显示更新信息
  showUpDateInfo: function showUpDateInfo(strInfo) {
    this.info.string = strInfo;
  }
});

cc._RF.pop();
                    }
                    if (nodeEnv) {
                        __define(__module.exports, __require, __module);
                    }
                    else {
                        __quick_compile_project__.registerModuleFunc(__filename, function () {
                            __define(__module.exports, __require, __module);
                        });
                    }
                })();
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbImFzc2V0cy9zY3JpcHQvZ2FtZS9Ib3RVcGRhdGUuanMiXSwibmFtZXMiOlsiRXZlbnRDZW50ZXIiLCJyZXF1aXJlIiwiZ19jaGVjayIsImNjIiwiQ2xhc3MiLCJDb21wb25lbnQiLCJwcm9wZXJ0aWVzIiwiX3NlYXJjaFBhdGgiLCJtYW5pZmVzdFVybCIsInR5cGUiLCJBc3NldCIsIl9jaGVja1VwZGF0ZSIsIl9jaGVja1VwZGF0ZU51bSIsIl91cGRhdGluZyIsIl9pc0ZvcmNlVXBkYXRlIiwiX2xvYWRGaWxlcyIsImJ5dGVQcm9ncmVzcyIsIlByb2dyZXNzQmFyIiwiZmlsZVByb2dyZXNzIiwiaW5mbyIsIkxhYmVsIiwiZmlsZUxhYmVsIiwiYnl0ZUxhYmVsIiwiZm9yY2VVcGRhdGUiLCJMYXlvdXQiLCJlbnN1cmVCdXQiLCJCdXR0b24iLCJfZm9yY2VIb3RVcGRhdGUiLCJzdGFydCIsInN5cyIsImlzTmF0aXZlIiwic3RhcnRHYW1lIiwiaG90VXBkYXRlSW5pdCIsImhvdFVwZGF0ZUxvZ2ljIiwiZGVsYXkiLCJkZWxheVRpbWUiLCJmaW5pc2hlZEFsbCIsImNhbGxGdW5jIiwib3ZlclRpbWVTdGFydEdhbWUiLCJub2RlIiwicnVuQWN0aW9uIiwic2VxdWVuY2UiLCJjaGVja0NiIiwiZXZlbnQiLCJnZXRFdmVudENvZGUiLCJqc2IiLCJFdmVudEFzc2V0c01hbmFnZXIiLCJFUlJPUl9OT19MT0NBTF9NQU5JRkVTVCIsInNob3dVcERhdGVJbmZvIiwiRVJST1JfRE9XTkxPQURfTUFOSUZFU1QiLCJFUlJPUl9QQVJTRV9NQU5JRkVTVCIsIkFMUkVBRFlfVVBfVE9fREFURSIsIk5FV19WRVJTSU9OX0ZPVU5EIiwiY2hlY2tVcGRhdGUiLCJob3RVcGRhdGUiLCJhY3RpdmUiLCJsb2ciLCJHYW1lU3RhcnQiLCJlbWl0Iiwic2VsZiIsIm9uIiwiZW5zdXJlQnV0Q2FsbEJhY2siLCJkaXJlY3RvciIsImVuZCIsImluaXRBc3NldHNNYW5hZ2VyIiwiZm9yY2VVcGRhdGVMb2dpYyIsImZpbGVVdGlscyIsImdldFdyaXRhYmxlUGF0aCIsInZlcnNpb25Db21wYXJlSGFuZGxlIiwidmVyc2lvbkEiLCJ2ZXJzaW9uQiIsInZBIiwic3BsaXQiLCJ2QiIsImxlbmd0aCIsInBhcnNlSW50IiwibG9jYWxTdG9yYWdlIiwiZ2V0SXRlbSIsImkiLCJhIiwiYiIsInNldEl0ZW0iLCJfYW0iLCJBc3NldHNNYW5hZ2VyIiwic2V0VmVyaWZ5Q2FsbGJhY2siLCJwYXRoIiwiYXNzZXQiLCJjb21wcmVzc2VkIiwiZXhwZWN0ZWRNRDUiLCJtZDUiLCJyZWxhdGl2ZVBhdGgiLCJzaXplIiwib3MiLCJPU19BTkRST0lEIiwic2V0TWF4Q29uY3VycmVudFRhc2siLCJzZXRFdmVudENhbGxiYWNrIiwiYmluZCIsImdldFN0YXRlIiwiU3RhdGUiLCJVTklOSVRFRCIsInVybCIsIm5hdGl2ZVVybCIsImxvYWRlciIsIm1kNVBpcGUiLCJ0cmFuc2Zvcm1VUkwiLCJsb2FkTG9jYWxNYW5pZmVzdCIsInVwZGF0ZUNiIiwidXBkYXRlIiwibmVlZFJlc3RhcnQiLCJmYWlsZWQiLCJVUERBVEVfUFJPR1JFU1NJT04iLCJwcm9ncmVzcyIsImdldFBlcmNlbnQiLCJnZXRQZXJjZW50QnlGaWxlIiwic3RyaW5nIiwiZ2V0RG93bmxvYWRlZEZpbGVzIiwiZ2V0VG90YWxGaWxlcyIsImdldERvd25sb2FkZWRCeXRlcyIsImdldFRvdGFsQnl0ZXMiLCJtc2ciLCJnZXRNZXNzYWdlIiwiVVBEQVRFX0ZJTklTSEVEIiwiVVBEQVRFX0ZBSUxFRCIsIkVSUk9SX1VQREFUSU5HIiwiZ2V0QXNzZXRJZCIsIkVSUk9SX0RFQ09NUFJFU1MiLCJyZXN0YXJ0R2FtZSIsIm9uRGVzdHJveSIsInNlYXJjaFBhdGhzIiwiZ2V0U2VhcmNoUGF0aHMiLCJuZXdQYXRocyIsImdldExvY2FsTWFuaWZlc3QiLCJBcnJheSIsInByb3RvdHlwZSIsInVuc2hpZnQiLCJKU09OIiwic3RyaW5naWZ5Iiwic2V0U2VhcmNoUGF0aHMiLCJhdWRp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QUEsRUFBRSxDQUFDeUksSUFBSCxDQUFRQyxPQUFSO0FBQ0gsR0F4VEk7QUF5VEw7QUFDQTdGLEVBQUFBLGNBQWMsRUFBRSx3QkFBVThGLE9BQVYsRUFBbUI7QUFDL0IsU0FBSzNILElBQUwsQ0FBVStGLE1BQVYsR0FBbUI0QixPQUFuQjtBQUNIO0FBNVRJLENBQVQiLCJzb3VyY2VSb290IjoiLyIsInNvdXJjZXNDb250ZW50IjpbIi8vIHZhciBtZDUgPSByZXF1aXJlKFwibWQ1XCIpXG5sZXQgIEV2ZW50Q2VudGVyID0gcmVxdWlyZShcIkV2ZW50Q2VudGVyXCIpXG52YXIgZ19jaGVjayA9IGZhbHNlO1xuY2MuQ2xhc3Moe1xuICAgIGV4dGVuZHM6IGNjLkNvbXBvbmVudCxcblxuICAgIHByb3BlcnRpZXM6IHtcbiAgICAgICAgX3NlYXJjaFBhdGg6IFwiXCIsLy/mkJzntKLot6/lvoRcbiAgICAgICAgbWFuaWZlc3RVcmw6IHtcbiAgICAgICAgICAgIHR5cGU6IGNjLkFzc2V0LCAgICAgLy8gdXNlICd0eXBlOicgdG8gZGVjbGFyZSBhbiBvYmplY3QgcmVmZXJlbmNlXG4gICAgICAgICAgICBkZWZhdWx0OiBudWxsLCAgICAgIC8vIG9iamVjdCdzIGRlZmF1bHQgdmFsdWUgaXMgbnVsbFxuICAgICAgICB9LFxuXG4gICAgICAgIF9jaGVja1VwZGF0ZTogZmFsc2UsXG4gICAgICAgIF9jaGVja1VwZGF0ZU51bTogNSwvL+ajgOafpeabtOaWsOasoeaVsFxuICAgICAgICBfdXBkYXRpbmc6IGZhbHNlLC8v5q2j5Zyo5qOA5p+l5pu05paw5oiW6ICF5pu05paw5LitXG4gICAgICAgIF9pc0ZvcmNlVXBkYXRlOiBmYWxzZSxcblxuICAgICAgICBfbG9hZEZpbGVzOiBcInl5YnMtcmVtb3RlLWFzc2V0XCIsXG5cbiAgICAgICAgYnl0ZVByb2dyZXNzOiBjYy5Qcm9ncmVzc0JhciwvL+Wtl+iKgui/m+W6plxuICAgICAgICBmaWxlUHJvZ3Jlc3M6IGNjLlByb2dyZXNzQmFyLC8v5paH5Lu26L+b5bqmXG4gICAgICAgIGluZm86IGNjLkxhYmVsLC8v5L+h5oGv5pi+56S6XG4gICAgICAgIGZpbGVMYWJlbDogY2MuTGFiZWwsLy/mlofku7bkuKrmlbBcbiAgICAgICAgYnl0ZUxhYmVsOiBjYy5MYWJlbCwvL+Wtl+iKguS4quaVsFxuXG4gICAgICAgIC8vIHJldHJ5QnRuOiBjYy5CdXR0b24sLy/ph43nva7mjInpkq5cbiAgICAgICAgLy8gY2hlY2tCdG46IGNjLkJ1dHRvbiwvL+ajgOafpeabtOaWsOaMiemSriDnm67liY3mmK/oh6rliqjlvpdcbiAgICAgICAgLy8gdXBkYXRlQnRuOiBjYy5CdXR0b24sLy/mm7TmlrDmjInpkq4gIOebruWJjeaYr+iHquWKqOeahFxuXG4gICAgICAgIGZvcmNlVXBkYXRlOiBjYy5MYXlvdXQsLy/lvLrmm7TnlYzpnaJcbiAgICAgICAgZW5zdXJlQnV0OiBjYy5CdXR0b24sLy/noa7lrprmjInpkq5cbiAgICAgICAgX2ZvcmNlSG90VXBkYXRlOiBcIlwiLFxuICAgIH0sXG4gICAgc3RhcnQoKSB7XG4gICAgICAgIC8vIGlmIChDQ19ERUJVRykgey8v5Y+R5biDZGVidWfmqKHlvI9hcGvot7Pov4fng63mm7RcblxuICAgICAgICAvLyAgICAgdGhpcy5zdGFydEdhbWUoKTsvL+makOiXj+W9k+WJjXVpLy/lpJrlnLrmma/ml7Yg6L+Z55u05o6l5Yqg6L295LiL5LiA5Liq5Zy65pmvXG4gICAgICAgIC8vIH1cbiAgICAgICAgaWYgKCFjYy5zeXMuaXNOYXRpdmUpLy93ZWIvL+i3s+i/h+eDreabtCBcbiAgICAgICAge1xuICAgICAgICAgICAgdGhpcy5zdGFydEdhbWUoKTsvL+makOiXj+W9k+WJjXVpLy/lpJrlnLrmma/ml7Yg6L+Z55u05o6l5Yqg6L295LiL5LiA5Liq5Zy65pmvXG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICB0aGlzLmhvdFVwZGF0ZUluaXQoKTtcbiAgICAgICAgICAgIHRoaXMuaG90VXBkYXRlTG9naWMoKTsvL+eDreabtOmAu+i+kVxuICAgICAgICAgICAgdmFyIGRlbGF5ID0gY2MuZGVsYXlUaW1lKDEwKTtcbiAgICAgICAgICAgIHZhciBmaW5pc2hlZEFsbCA9IGNjLmNhbGxGdW5jKHRoaXMub3ZlclRpbWVTdGFydEdhbWUsIHRoaXMpO1xuICAgICAgICAgICAgdGhpcy5ub2RlLnJ1bkFjdGlvbihjYy5zZXF1ZW5jZShkZWxheSwgZmluaXNoZWRBbGwpKTtcbiAgICAgICAgfVxuICAgIH0sXG5cbiAgICBjaGVja0NiOiBmdW5jdGlvbiAoZXZlbnQpIHtcbiAgICAgICAgdGhpcy5fY2hlY2tVcGRhdGUgPSBmYWxzZTsvL+ajgOa1i+abtOaWsOWujOavlVxuICAgICAgICB0aGlzLl91cGRhdGluZyA9IGZhbHNlOy8v5pu05paw5LitXG4gICAgICAgIHN3aXRjaCAoZXZlbnQuZ2V0RXZlbnRDb2RlKCkpIHtcbiAgICAgICAgICAgIGNhc2UganNiLkV2ZW50QXNzZXRzTWFuYWdlci5FUlJPUl9OT19MT0NBTF9NQU5JRkVTVDpcbiAgICAgICAgICAgICAgICB0aGlzLnNob3dVcERhdGVJbmZvKCfmo4Dmn6Xmm7TmlrDlpLHotKUnKTtcbiAgICAgICAgICAgICAgICBnX2NoZWNrID0gdHJ1ZTtcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIGNhc2UganNiLkV2ZW50QXNzZXRzTWFuYWdlci5FUlJPUl9ET1dOTE9BRF9NQU5JRkVTVDpcbiAgICAgICAgICAgIGNhc2UganNiLkV2ZW50QXNzZXRzTWFuYWdlci5FUlJPUl9QQVJTRV9NQU5JRkVTVDpcbiAgICAgICAgICAgICAgICB0aGlzLnNob3dVcERhdGVJbmZvKCfmo4Dmn6Xmm7TmlrDlpLHotKUnKTtcbiAgICAgICAgICAgICAgICBnX2NoZWNrID0gdHJ1ZTtcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIGNhc2UganNiLkV2ZW50QXNzZXRzTWFuYWdlci5BTFJFQURZX1VQX1RPX0RBVEU6XG4gICAgICAgICAgICAgICAgdGhpcy5zaG93VXBEYXRlSW5mbygn5bey5piv5pyA5paw54mI5pysJyk7XG4gICAgICAgICAgICAgICAgaWYgKHRoaXMuX2lzRm9yY2VVcGRhdGUgPT0gZmFsc2UpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5zdGFydEdhbWUoKTtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIGNhc2UganNiLkV2ZW50QXNzZXRzTWFuYWdlci5ORVdfVkVSU0lPTl9GT1VORDpcbiAgICAgICAgICAgICAgICB0aGlzLnNob3dVcERhdGVJbmZvKCflj5HnjrDmlrDniYjmnKzvvIzmraPlnKjmm7TmlrAuLi4nKTtcbiAgICAgICAgICAgICAgICBnX2NoZWNrID0gZmFsc2U7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICBpZiAoZ19jaGVjayA9PSB0cnVlKSB7XG4gICAgICAgICAgICB0aGlzLmNoZWNrVXBkYXRlKCk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICB0aGlzLmhvdFVwZGF0ZSgpO1xuICAgICAgICB9XG5cbiAgICB9LFxuXG4gICAgb3ZlclRpbWVTdGFydEdhbWU6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgaWYgKHRoaXMubm9kZS5hY3RpdmUgPT0gdHJ1ZSAmJiB0aGlzLl9jaGVja1VwZGF0ZSA9PSB0cnVlKSB7XG4gICAgICAgICAgICB0aGlzLnN0YXJ0R2FtZSgpO1xuICAgICAgICB9XG4gICAgfSxcbiAgICBzdGFydEdhbWU6IGZ1bmN0aW9uICgpLy/lvIDlp4vmuLjmiI9cbiAgICB7XG4gICAgICAgIHRoaXMubm9kZS5hY3RpdmUgPSBmYWxzZTtcbiAgICAgICAgY2MubG9nKFwi5byA5aeL5ri45oiPXCIpO1xuICAgICAgICBFdmVudENlbnRlci5FdmVudENlbnRlci5HYW1lU3RhcnQuZW1pdCgpO1xuICAgIH0sXG4gICAgaG90VXBkYXRlSW5pdDogZnVuY3Rpb24gKCkge1xuXG4gICAgICAgIHZhciBzZWxmID0gdGhpcztcbiAgICAgICAgdGhpcy5lbnN1cmVCdXQubm9kZS5vbignY2xpY2snLCBmdW5jdGlvbiAoZXZlbnQpIHtcbiAgICAgICAgICAgIHNlbGYuZW5zdXJlQnV0Q2FsbEJhY2soKTtcbiAgICAgICAgfSwgdGhpcyk7XG4gICAgfSxcbiAgICBlbnN1cmVCdXRDYWxsQmFjazogZnVuY3Rpb24gKCkvL+ehruWumuaMiemSruWbnuaOiVxuICAgIHtcbiAgICAgICAgLy8gY2Muc3lzLm9wZW5VUkwoJ2h0dHA6Ly9mb3JtYWwuc2hhcmUuaWRqNjZubS5jb20vZG93bi9saW5rP2dhbWVJZD0yMDAwMDEmZ2FtZVN0YXRlPTEnKTsvL+W8uuabtOS4i+i9veWcsOWdgFxuICAgICAgICBjYy5kaXJlY3Rvci5lbmQoKTtcbiAgICB9LFxuICAgIGhvdFVwZGF0ZUxvZ2ljOiBmdW5jdGlvbiAoKS8v54Ot5pu06YC76L6RXG4gICAge1xuICAgICAgICB0aGlzLmluaXRBc3NldHNNYW5hZ2VyKCk7XG4gICAgICAgIHRoaXMuY2hlY2tVcGRhdGUoKTtcbiAgICB9LFxuICAgIGZvcmNlVXBkYXRlTG9naWM6IGZ1bmN0aW9uICgpLy/lvLrmm7TpgLvovpFcbiAgICB7XG4gICAgICAgIHRoaXMuX2lzRm9yY2VVcGRhdGUgPSB0cnVlO1xuICAgICAgICB0aGlzLmZvcmNlVXBkYXRlLm5vZGUuYWN0aXZlID0gdHJ1ZTtcbiAgICB9LFxuICAgIGluaXRBc3NldHNNYW5hZ2VyOiBmdW5jdGlvbiAoKS8v5Yid5aeL5YyWXG4gICAge1xuICAgICAgICB0aGlzLl9zZWFyY2hQYXRoID0gKChqc2IuZmlsZVV0aWxzID8ganNiLmZpbGVVdGlscy5nZXRXcml0YWJsZVBhdGgoKSA6ICcvJykgKyB0aGlzLl9sb2FkRmlsZXMpOy8v6I635Y+W54Ot5pu05pe25b6X5pCc57Si6Lev5b6EXG4gICAgICAgIGNjLmxvZygnaG90VXBkYXRlIHNlYXJjaFBhdGggPScgKyB0aGlzLl9zZWFyY2hQYXRoKTtcbiAgICAgICAgdmFyIHNlbGYgPSB0aGlzO1xuICAgICAgICB2YXIgdmVyc2lvbkNvbXBhcmVIYW5kbGUgPSBmdW5jdGlvbiAodmVyc2lvbkEsIHZlcnNpb25CKSAvL+eJiOacrOWvueavlOWHveaVsCjmo4Dmn6XmnKzlnLBtYWluZmVzdOWSjOi/nOerr21haW5mZXPml7bvvIzlpoLmnpzov5Tlm57lgLzlpKfkuo4wIOS8muiHquWKqOabtOaWsClcbiAgICAgICAge1xuICAgICAgICAgICAgY2MubG9nKFwiSlMgQ3VzdG9tIFZlcnNpb24gQ29tcGFyZTogdmVyc2lvbiBBIGlzIFwiICsgdmVyc2lvbkEgKyAnLCB2ZXJzaW9uIEIgaXMgJyArIHZlcnNpb25CKTtcbiAgICAgICAgICAgIHZhciB2QSA9IHZlcnNpb25BLnNwbGl0KCcuJyk7XG4gICAgICAgICAgICB2YXIgdkIgPSB2ZXJzaW9uQi5zcGxpdCgnLicpO1xuICAgICAgICAgICAgaWYgKHZBLmxlbmd0aCAhPSB2Qi5sZW5ndGggfHwgdkEubGVuZ3RoIDwgMylcbiAgICAgICAgICAgICAgICByZXR1cm4gMDtcbiAgICAgICAgICAgIGlmICgocGFyc2VJbnQodkFbMF0pICE9IHBhcnNlSW50KHZCWzBdKSkpLy/liY3kuKTkvY3mjqfliLblpKfniYjmnKzmm7TmlrBcbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAvL+W8uuWItuabtOaWsFxuICAgICAgICAgICAgICAgIHNlbGYuZm9yY2VVcGRhdGVMb2dpYygpO1xuICAgICAgICAgICAgICAgIHJldHVybiAwO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgc2VsZi5fZm9yY2VIb3RVcGRhdGUgPSB2QVswXSArIFwiXCIgKyB2QVsxXTtcbiAgICAgICAgICAgIHZhciBmb3JjZVVwZGF0ZSA9IGNjLnN5cy5sb2NhbFN0b3JhZ2UuZ2V0SXRlbSgnZm9yY2V1cGRhdGV5eWJzJyk7XG4gICAgICAgICAgICBjYy5sb2coXCJpbml0QXNzZXRzTWFuYWdlciBmb3JjZXVwZGF0ZSBcIiArIGZvcmNlVXBkYXRlKTtcbiAgICAgICAgICAgIHNlbGYuX2ZvcmNlSG90VXBkYXRlID0gdkJbMF0gKyBcIlwiICsgdkJbMV07XG4gICAgICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IHZBLmxlbmd0aDsgKytpKSB7XG4gICAgICAgICAgICAgICAgdmFyIGEgPSBwYXJzZUludCh2QVtpXSk7XG4gICAgICAgICAgICAgICAgdmFyIGIgPSBwYXJzZUludCh2QltpXSB8fCAwKTtcbiAgICAgICAgICAgICAgICBpZiAoYSA9PT0gYikge1xuICAgICAgICAgICAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgcmV0dXJuIC0xO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKHZCLmxlbmd0aCA+IHZBLmxlbmd0aCkge1xuICAgICAgICAgICAgICAgIHJldHVybiAtMTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGNjLnN5cy5sb2NhbFN0b3JhZ2Uuc2V0SXRlbSgnZm9yY2V1cGRhdGV5eWJzJywgc2VsZi5fZm9yY2VIb3RVcGRhdGUpO1xuICAgICAgICAgICAgcmV0dXJuIDA7XG4gICAgICAgIH07XG4gICAgICAgIHRoaXMuX2FtID0gbmV3IGpzYi5Bc3NldHNNYW5hZ2VyKHRoaXMubWFuaWZlc3RVcmwsIHRoaXMuX3NlYXJjaFBhdGgsIHZlcnNpb25Db21wYXJlSGFuZGxlKTsvL+WIneWni+WMliDliJvlu7ogQXNzZXRzTWFuYWdlclxuICAgICAgICAvLyBpZiAoIWNjLnN5cy5FTkFCTEVfR0NfRk9SX05BVElWRV9PQkpFQ1RTKVxuICAgICAgICAvLyB7XG4gICAgICAgIC8vICAgICB0aGlzLl9hbS5yZXRhaW4oKTtcbiAgICAgICAgLy8gfVxuICAgICAgICAvL+eUqOaIt+aWh+S7tuagoemqjOaOpeWPoyDnlLHkuo7kuIvovb3ov4fnqIvkuK3ku43nhLbmnInlsI/mpoLnjoflj6/og73nlLHkuo7nvZHnu5zljp/lm6DmiJblhbbku5bnvZHnu5zlupPnmoTpl67popjlr7zoh7TkuIvovb3nmoTmlofku7blhoXlrrnmnInpl67popjvvIxcbiAgICAgICAgLy/lnKjmlofku7bkuIvovb3lrozmiJDlkI7ng63mm7TmlrDnrqHnkIblmajkvJrosIPnlKjov5nkuKrmjqXlj6PvvIzlpoLmnpzov5Tlm54gdHJ1ZSDooajnpLrmlofku7bmraPluLjvvIzov5Tlm54gZmFsc2Ug6KGo56S65paH5Lu25pyJ6Zeu6aKYXG4gICAgICAgIHRoaXMuX2FtLnNldFZlcmlmeUNhbGxiYWNrKGZ1bmN0aW9uIChwYXRoLCBhc3NldCkge1xuICAgICAgICAgICAgdmFyIGNvbXByZXNzZWQgPSBhc3NldC5jb21wcmVzc2VkOy8vIOaYr+WOi+e8qeaWh+S7tiDkuI3pnIDopoHmo4Dmn6XlroPnmoRtZDVcbiAgICAgICAgICAgIHZhciBleHBlY3RlZE1ENSA9IGFzc2V0Lm1kNTsvL+ajgOe0om1kNeWAvOOAglxuICAgICAgICAgICAgdmFyIHJlbGF0aXZlUGF0aCA9IGFzc2V0LnBhdGg7Ly8gYXNzZXQucGF0aCDmmK/nm7jlr7not6/lvoQgcGF0aCDnu53lr7not6/lvoQuXG4gICAgICAgICAgICB2YXIgc2l6ZSA9IGFzc2V0LnNpemU7Ly/mlofku7bnmoTlpKflsI/vvIzkvYbmmK/ov5nkuKrlgLzlj6/og73kuI3lrZjlnKhcbiAgICAgICAgICAgIGlmIChjb21wcmVzc2VkKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgICAgICAgICAvLyAvL+S9v+eUqOe7neWvuei3r+W+hOadpeWKoOi9veaWh+S7tizkuYvlkI7orqHnrpdtZDXlgLxcbiAgICAgICAgICAgICAgICAvLyB2YXIgZGF0YSA9IGpzYi5maWxlVXRpbHMuZ2V0RGF0YUZyb21GaWxlKHBhdGgpO1xuICAgICAgICAgICAgICAgIC8vIHZhciBjdXJNRDUgPSBtZDUoZGF0YSk7XG4gICAgICAgICAgICAgICAgLy8gaWYgKGN1ck1ENSA9PSBhc3NldC5tZDUpIHtcbiAgICAgICAgICAgICAgICAvLyAgICAgLy9tZDXmo4DpqozpgJrov4dcbiAgICAgICAgICAgICAgICAvLyAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgICAgICAgICAgLy8gfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAvLyAgICAgLy9tZDXmo4DpqozlpLHotKVcbiAgICAgICAgICAgICAgICAvLyAgICAgLy90aGlzLmluZm8uc3RyaW5nID0gcmVsYXRpdmVQYXRoICsgXCLmlofku7ZNRDXmoKHpqozlpLHotKVcIjtcbiAgICAgICAgICAgICAgICAvLyAgICAgY2MubG9nKFwibWQ15qOA6aqM5aSx6LSlXCIpO1xuICAgICAgICAgICAgICAgIC8vICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgICAgICAgICAgLy8gfVxuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICAgICAgaWYgKGNjLnN5cy5vcyA9PT0gY2Muc3lzLk9TX0FORFJPSUQpIHsvL+aOp+WItuS4i+i9veW5tuWPkeaVsOmHj+eahCBBUEkg5pyJ5LqbQW5kcm9pZOiuvuWkh+WPr+iDveS8muWcqOW5tuWPkeS7u+WKoeWkquWkmuaXtuWHj+aFouS4i+i9vemAn+W6puOAguiuvue9rumAguWQiOa4uOaIj+eahOWAvOOAglxuICAgICAgICAgICAgdGhpcy5fYW0uc2V0TWF4Q29uY3VycmVudFRhc2soMik7XG4gICAgICAgIH1cbiAgICB9LFxuXG5cblxuICAgIGNoZWNrVXBkYXRlOiBmdW5jdGlvbiAoKS8v5qOA5p+l5pu05pawXG4gICAge1xuICAgICAgICB0aGlzLl9jaGVja1VwZGF0ZU51bSA9IHRoaXMuX2NoZWNrVXBkYXRlTnVtIC0gMTtcbiAgICAgICAgaWYgKHRoaXMuX2NoZWNrVXBkYXRlTnVtIDw9IDApIHtcbiAgICAgICAgICAgIC8v55u05o6l55m76ZmGXG4gICAgICAgICAgICB0aGlzLnN0YXJ0R2FtZSgpO1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIGlmICh0aGlzLl91cGRhdGluZykge1xuICAgICAgICAgICAgdGhpcy5zaG93VXBEYXRlSW5mbygn5q2j5Zyo5qOA5rWL5oiW6ICF5pu05paw5LitLOivt+iAkOW/g+etieW+hS4uLicpO1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMuX2FtLnNldEV2ZW50Q2FsbGJhY2sodGhpcy5jaGVja0NiLmJpbmQodGhpcykpO1xuXG4gICAgICAgIGlmICh0aGlzLl9hbS5nZXRTdGF0ZSgpID09PSBqc2IuQXNzZXRzTWFuYWdlci5TdGF0ZS5VTklOSVRFRCkge1xuICAgICAgICAgICAgdmFyIHVybCA9IHRoaXMubWFuaWZlc3RVcmwubmF0aXZlVXJsO1xuICAgICAgICAgICAgaWYgKGNjLmxvYWRlci5tZDVQaXBlKSB7XG4gICAgICAgICAgICAgICAgdXJsID0gY2MubG9hZGVyLm1kNVBpcGUudHJhbnNmb3JtVVJMKHVybCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBjYy5sb2coJ+WKoOi9veacrOWcsE1hbmlmZXN0JywgdXJsKTtcbiAgICAgICAgICAgIHRoaXMuX2FtLmxvYWRMb2NhbE1hbmlmZXN0KHVybCk7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5fYW0uY2hlY2tVcGRhdGUoKTtcbiAgICAgICAgdGhpcy5fY2hlY2tVcGRhdGUgPSB0cnVlOy8v5q2j5Zyo5qOA5rWL5pu05pawXG4gICAgICAgIHRoaXMuc2hvd1VwRGF0ZUluZm8oJ+ato+WcqOajgOa1i+abtOaWsCzor7fogJDlv4PnrYnlvoUuLi4nKTtcbiAgICB9LFxuXG5cbiAgICBob3RVcGRhdGU6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgaWYgKHRoaXMuX2FtID09IG51bGwpIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIHRoaXMuX2FtLnNldEV2ZW50Q2FsbGJhY2sodGhpcy51cGRhdGVDYi5iaW5kKHRoaXMpKTtcblxuICAgICAgICBpZiAodGhpcy5fYW0uZ2V0U3RhdGUoKSA9PT0ganNiLkFzc2V0c01hbmFnZXIuU3RhdGUuVU5JTklURUQpIHtcbiAgICAgICAgICAgIHRoaXMuX2FtLmxvYWRMb2NhbE1hbmlmZXN0KHRoaXMubWFuaWZlc3RVcmwpO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMuX2FtLnVwZGF0ZSgpO1xuICAgICAgICB0aGlzLl91cGRhdGluZyA9IHRydWU7XG4gICAgfSxcbiAgICB1cGRhdGVDYjogZnVuY3Rpb24gKGV2ZW50KSB7XG4gICAgICAgIHZhciBuZWVkUmVzdGFydCA9IGZhbHNlO1xuICAgICAgICB2YXIgZmFpbGVkID0gZmFsc2U7XG4gICAgICAgIHN3aXRjaCAoZXZlbnQuZ2V0RXZlbnRDb2RlKCkpIHtcbiAgICAgICAgICAgIGNhc2UganNiLkV2ZW50QXNzZXRzTWFuYWdlci5FUlJPUl9OT19MT0NBTF9NQU5JRkVTVDpcbiAgICAgICAgICAgICAgICBjYy5sb2coJ+mUmeivrzrmsqHmib7liLDmnKzlnLBtYW5pZmVzdOaWh+S7ticpO1xuICAgICAgICAgICAgICAgIGZhaWxlZCA9IHRydWU7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICBjYXNlIGpzYi5FdmVudEFzc2V0c01hbmFnZXIuVVBEQVRFX1BST0dSRVNTSU9OOi8v5pu05paw6L+b5bqmXG4gICAgICAgICAgICAgICAgdGhpcy5ieXRlUHJvZ3Jlc3MucHJvZ3Jlc3MgPSBldmVudC5nZXRQZXJjZW50KCk7XG4gICAgICAgICAgICAgICAgdGhpcy5maWxlUHJvZ3Jlc3MucHJvZ3Jlc3MgPSBldmVudC5nZXRQZXJjZW50QnlGaWxlKCk7XG4gICAgICAgICAgICAgICAgdGhpcy5maWxlTGFiZWwubm9kZS5hY3RpdmUgPSB0cnVlO1xuICAgICAgICAgICAgICAgIHRoaXMuZmlsZUxhYmVsLnN0cmluZyA9IGV2ZW50LmdldERvd25sb2FkZWRGaWxlcygpICsgJyAvICcgKyBldmVudC5nZXRUb3RhbEZpbGVzKCk7XG4gICAgICAgICAgICAgICAgdGhpcy5ieXRlTGFiZWwuc3RyaW5nID0gZXZlbnQuZ2V0RG93bmxvYWRlZEJ5dGVzKCkgLyAxMDI0ICsgJyAvICcgKyBldmVudC5nZXRUb3RhbEJ5dGVzKCkgLyAxMDI0O1xuICAgICAgICAgICAgICAgIHZhciBtc2cgPSBldmVudC5nZXRNZXNzYWdlKCk7XG4gICAgICAgICAgICAgICAgaWYgKG1zZykge1xuICAgICAgICAgICAgICAgICAgICAvLyBjYy5sb2coZXZlbnQuZ2V0UGVyY2VudCgpLzEwMCArICclIDogJyArIG1zZyk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgY2FzZSBqc2IuRXZlbnRBc3NldHNNYW5hZ2VyLkVSUk9SX0RPV05MT0FEX01BTklGRVNUOlxuICAgICAgICAgICAgY2FzZSBqc2IuRXZlbnRBc3NldHNNYW5hZ2VyLkVSUk9SX1BBUlNFX01BTklGRVNUOlxuICAgICAgICAgICAgICAgIGNjLmxvZygn6ZSZ6K+vOuS4i+i9veaIluino+aekE1BTklGRVNU5paH5Lu25aSx6LSlJyk7XG4gICAgICAgICAgICAgICAgZmFpbGVkID0gdHJ1ZTtcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIGNhc2UganNiLkV2ZW50QXNzZXRzTWFuYWdlci5BTFJFQURZX1VQX1RPX0RBVEU6XG4gICAgICAgICAgICAgICAgdGhpcy5zaG93VXBEYXRlSW5mbygn5LiO5pyN5Yqh5Zmo54mI5pys5LiA6Ie0Jyk7XG4gICAgICAgICAgICAgICAgaWYgKHRoaXMuX2lzRm9yY2VVcGRhdGUgPT0gZmFsc2UpXG4gICAgICAgICAgICAgICAgICAgIHRoaXMuc3RhcnRHYW1lKCk7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICBjYXNlIGpzYi5FdmVudEFzc2V0c01hbmFnZXIuVVBEQVRFX0ZJTklTSEVEOlxuICAgICAgICAgICAgICAgIHRoaXMuc2hvd1VwRGF0ZUluZm8oJ+abtOaWsOWujOaIkCcpO1xuICAgICAgICAgICAgICAgIHRoaXMuX3VwZGF0aW5nID0gZmFsc2U7XG4gICAgICAgICAgICAgICAgbmVlZFJlc3RhcnQgPSB0cnVlO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgY2FzZSBqc2IuRXZlbnRBc3NldHNNYW5hZ2VyLlVQREFURV9GQUlMRUQ6Ly/mm7TmlrDlpLHotKVcbiAgICAgICAgICAgICAgICB0aGlzLl91cGRhdGluZyA9IGZhbHNlO1xuICAgICAgICAgICAgICAgIGZhaWxlZCA9IHRydWU7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICBjYXNlIGpzYi5FdmVudEFzc2V0c01hbmFnZXIuRVJST1JfVVBEQVRJTkc6XG4gICAgICAgICAgICAgICAgaWYgKGV2ZW50LmdldE1lc3NhZ2UoKSkge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLmluZm8uc3RyaW5nID0gJ+abtOaWsCcgKyBldmVudC5nZXRBc3NldElkKCkgKyAn5pe25Y+R55Sf6ZSZ6K+vLicgKyBldmVudC5nZXRNZXNzYWdlKCk7XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5pbmZvLnN0cmluZyA9ICfmm7TmlrAnICsgZXZlbnQuZ2V0QXNzZXRJZCgpICsgJ+aXtuWPkeeUn+mUmeivryc7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIG5lZWRSZXN0YXJ0ID0gdHJ1ZTtcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIGNhc2UganNiLkV2ZW50QXNzZXRzTWFuYWdlci5FUlJPUl9ERUNPTVBSRVNTOlxuICAgICAgICAgICAgICAgIHRoaXMuc2hvd1VwRGF0ZUluZm8oJ+ino+WOi+WPkeeUn+mUmeivry4nICsgZXZlbnQuZ2V0TWVzc2FnZSgpKTtcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKG5lZWRSZXN0YXJ0KSB7XG4gICAgICAgICAgICB0aGlzLnJlc3RhcnRHYW1lKCk7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGZhaWxlZCkge1xuXG4gICAgICAgICAgICB0aGlzLl91cGRhdGluZyA9IGZhbHNlO1xuICAgICAgICAgICAgdGhpcy5jaGVja1VwZGF0ZSgpO1xuICAgICAgICB9XG4gICAgfSxcbiAgICBvbkRlc3Ryb3k6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgaWYgKHRoaXMuX2FtKVxuICAgICAgICAgICAgdGhpcy5fYW0uc2V0RXZlbnRDYWxsYmFjayhudWxsKTtcbiAgICB9LFxuICAgIHJlc3RhcnRHYW1lOiBmdW5jdGlvbiAoKS8v6YeN5ZCv5ri45oiPXG4gICAge1xuXG4gICAgICAgIHRoaXMuZmlsZVByb2dyZXNzLnByb2dyZXNzID0gMTtcbiAgICAgICAgdGhpcy5ieXRlUHJvZ3Jlc3MucHJvZ3Jlc3MgPSAxXG4gICAgICAgIHZhciBzZWFyY2hQYXRocyA9IGpzYi5maWxlVXRpbHMuZ2V0U2VhcmNoUGF0aHMoKTtcbiAgICAgICAgdmFyIG5ld1BhdGhzID0gdGhpcy5fYW0uZ2V0TG9jYWxNYW5pZmVzdCgpLmdldFNlYXJjaFBhdGhzKCk7XG4gICAgICAgIEFycmF5LnByb3RvdHlwZS51bnNoaWZ0KHNlYXJjaFBhdGhzLCBuZXdQYXRocyk7XG4gICAgICAgIGNjLnN5cy5sb2NhbFN0b3JhZ2Uuc2V0SXRlbSgnSG90VXBkYXRlU2VhcmNoUGF0aHMnLCBKU09OLnN0cmluZ2lmeShzZWFyY2hQYXRocykpO1xuICAgICAgICBjYy5zeXMubG9jYWxTdG9yYWdlLnNldEl0ZW0oJ2ZvcmNldXBkYXRleXlicycsIHRoaXMuX2ZvcmNlSG90VXBkYXRlKTtcbiAgICAgICAganNiLmZpbGVVdGlscy5zZXRTZWFyY2hQYXRocyhzZWFyY2hQYXRocyk7XG4gICAgICAgIGNjLmF1ZGlvRW5naW5lLnN0b3BBbGwoKTtcbiAgICAgICAgY2MuZ2FtZS5yZXN0YXJ0KCk7XG4gICAgfSxcbiAgICAvL+aYvuekuuabtOaWsOS/oeaBr1xuICAgIHNob3dVcERhdGVJbmZvOiBmdW5jdGlvbiAoc3RySW5mbykge1xuICAgICAgICB0aGlzLmluZm8uc3RyaW5nID0gc3RySW5mbztcbiAgICB9XG59KTtcblxuIl19