SaveDataManager.js 49.3 KB

                (function() {
                    var nodeEnv = typeof require !== 'undefined' && typeof process !== 'undefined';
                    var __module = nodeEnv ? module : {exports:{}};
                    var __filename = 'preview-scripts/assets/scripts/component/SaveDataManager.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, '03ebbo8/N5DpYzmRjteJU3E', 'SaveDataManager');
// scripts/component/SaveDataManager.ts

"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.SaveDataManager = void 0;
var Global_1 = require("../Global");
var BattleConst_1 = require("../kernel/battle/BattleConst");
var GlobalNode_1 = require("../kernel/GlobalNode");
var TableDefine_1 = require("../kernel/table/TableDefine");
var UIManager_1 = require("../ui/UIManager");
var SoundManager_1 = require("./SoundManager");
var SaveDataManager = /** @class */ (function () {
    function SaveDataManager() {
        this.runtimeData = null;
        /**回到主场景后待添加的星星 */
        this.mainSceneAddStar = 0;
        // private _saveTimeFrq: number = 5;
        // private _saveTimeCount: number = 0;
        // private _coinDirty: number = 0;
        this.devDay = 0;
    }
    Object.defineProperty(SaveDataManager, "ins", {
        get: function () {
            if (this._ins == null) {
                this._ins = new SaveDataManager();
            }
            return this._ins;
        },
        enumerable: false,
        configurable: true
    });
    SaveDataManager.prototype.getNowTime = function () {
        if (CC_DEV) {
            return this.devDay * 3600000 * 24 + Date.now();
        }
        else {
            return Date.now();
        }
    };
    SaveDataManager.prototype.init = function () {
        this.resetData();
        var userDataText = cc.sys.localStorage.getItem('USERDATA_PLAYERDATA' + '_' + SaveDataManager.PKG_NAME);
        if (userDataText == null || userDataText.length == 0) {
            console.log('[Data][本地没有数据,使用初始数据]');
            this.saveData();
        }
        else {
            var userData = JSON.parse(userDataText);
            if (userData.curDataVersion == SaveDataManager.DATA_VERSION) {
                this.runtimeData = this.getDataObj(this.runtimeData, userData);
            }
            else {
                console.log('[Data][数据版本不同,使用初始数据]');
                this.saveData();
            }
            // this.runtimeData = JSON.parse(userDataText);
            // console.log('[Data][读取结束]结果为:')
            // console.log(this.runtimeData);
        }
        // 重新计算每日任务
        // this.Action_RefreshDailyMission();
        // 保存数据
        // this.saveData();
        // DataManager.inited = true;
        // if (_finishCallback != null) {
        //     _finishCallback();
        // }
        // this._coinDirty = this.runtimeData.curCoin;
        cc.game.on(cc.game.EVENT_HIDE, this.onGameHideOrClose, this);
    };
    SaveDataManager.prototype.onGameHideOrClose = function () {
        cc.log('game hide');
        this.saveData();
    };
    SaveDataManager.prototype.getDataObj = function (originalObj, newObj) {
        if (typeof (originalObj) == 'string') {
            return newObj;
        }
        var keys_runtimeData = Object.keys(originalObj);
        var keys_loaded = Object.keys(newObj);
        for (var i = 0; i < keys_runtimeData.length; i++) {
            var key = keys_runtimeData[i];
            // if (key == 'unlockSkinList') {
            //     log();
            // }
            // 找到储存的数据一致的key,赋值给本地
            for (var j = 0; j < keys_loaded.length; j++) {
                if (keys_loaded[j] == key) {
                    if (originalObj[key] instanceof Array) {
                        originalObj[key] = newObj[key];
                    }
                    else {
                        var tempKeys = Object.keys(originalObj[key]);
                        if (tempKeys.length > 0) {
                            originalObj[key] = this.getDataObj(originalObj[key], newObj[key]);
                        }
                        else {
                            originalObj[key] = newObj[key];
                        }
                    }
                    break;
                }
            }
        }
        return originalObj;
    };
    SaveDataManager.prototype.resetData = function () {
        this.runtimeData = {
            curDataVersion: SaveDataManager.DATA_VERSION,
            star: 0,
            diamond: 0,
            curGameScene: 1,
            unlockObj: [],
            userSkillNum: { 1: 0, 2: 0, 3: 0, 4: 0 },
            curLevel: 0,
            gender: -1,
            freeWheelNum: 3,
            loginRewardData: {
                step: 0,
                freshTime: 0,
            },
            musicMute: false,
            SEMute: false,
            vibration: true,
            goldenAimEndTime: 0,
            goldenAimTry: false,
            ballSkinUnlocked: [4],
            ballSkinCurrent: 4,
            shopDailyPackRefreshTime: 0,
            ballSkinTry: 0,
            guideStep: 0,
            levelScoreMap: {}
        };
    };
    SaveDataManager.prototype.saveData = function () {
        // console.log("[Data][保存数据成功]")
        // console.log(DataManager.RuntimeData)
        cc.sys.localStorage.setItem('USERDATA_PLAYERDATA' + '_' + SaveDataManager.PKG_NAME, JSON.stringify(this.runtimeData));
        // this._coinDirty = this.runtimeData.curCoin;
    };
    /**
     *
     * @param delta
     * @param useAni
     * @param wPos 星星动画的目标点,世界坐标,当useAni为true时且delta小于0时需要传入
     * @returns 是否成功,当delta小于0时,会检测当前钱是否足够
     */
    SaveDataManager.prototype.adjustStar = function (delta, useAni, wPos) {
        var _this = this;
        if (useAni === void 0) { useAni = false; }
        if (delta < 0 && this.runtimeData.star < Math.abs(delta)) {
            return false;
        }
        if (useAni) {
            if (delta < 0) {
                UIManager_1.UIManager.ins.widgetLayer.convertToNodeSpaceAR(wPos, wPos); //扣钱时使用传入的位置
            }
            else {
                var widgetNode = UIManager_1.UIManager.ins.getWidgetNode(Global_1.ResType.STAR);
                wPos = cc.v3(widgetNode.position.x - widgetNode.width / 2, widgetNode.y, widgetNode.z); //加钱时使用widget位置
            }
            BattleConst_1.getGlobalNode().getComponent(GlobalNode_1.default).schedule(function (dt) {
                _this.makeStar(wPos, delta / Math.abs(delta));
            }, 0.1, Math.abs(delta) - 1, 0);
        }
        else {
            this.runtimeData.star += delta;
            this.saveData();
            BattleConst_1.getGlobalNode().emit(Global_1.GlobalEvent.CHANGE_EVENT_STAR, delta);
        }
        return true;
    };
    /**
     *
     * @param delta
     * @returns 是否成功,当delta小于0时,会检测当前钱是否足够
     */
    SaveDataManager.prototype.adjustDiamond = function (delta, useAni, wPos) {
        var _this = this;
        if (useAni === void 0) { useAni = false; }
        if (delta < 0 && this.runtimeData.diamond < Math.abs(delta)) {
            UIManager_1.UIManager.ins.openWindow(Global_1.WindowName.FREE_DIAMOND);
            return false;
        }
        if (useAni) {
            if (delta < 0) {
                UIManager_1.UIManager.ins.widgetLayer.convertToNodeSpaceAR(wPos, wPos); //扣钱时使用传入的位置
            }
            else {
                var widgetNode = UIManager_1.UIManager.ins.getWidgetNode(Global_1.ResType.DIAMOND);
                wPos = cc.v3(widgetNode.position.x - widgetNode.width / 2, widgetNode.y, widgetNode.z); //加钱时使用widget位置
            }
            if (Math.abs(delta) < 5) {
                this.makeDiamond(wPos, delta); //小于5只播一次
            }
            else {
                var step_1 = Math.ceil(delta / 5);
                var lastStep_1 = delta - step_1 * 4;
                //console.log('step', step, 'last step', lastStep);
                BattleConst_1.getGlobalNode().getComponent(GlobalNode_1.default).schedule(function () {
                    _this.makeDiamond(wPos, step_1);
                }, 0.1, 3, 0);
                if (lastStep_1 != 0) {
                    BattleConst_1.getGlobalNode().getComponent(GlobalNode_1.default).scheduleOnce(function () {
                        _this.makeDiamond(wPos, lastStep_1);
                    }, 0.5);
                }
            }
            // getGlobalNode().getComponent(GlobalNode).schedule((dt) => {
            //     this.makeDiamond(wPos, delta / Math.abs(delta));
            // }, 0.1, Math.abs(delta) - 1, 0);
        }
        else {
            this.runtimeData.diamond += delta;
            this.saveData();
            BattleConst_1.getGlobalNode().emit(Global_1.GlobalEvent.CHANGE_EVENT_DIAMOND, delta);
        }
        return true;
    };
    SaveDataManager.prototype.unlockGameSceneObj = function (ID) {
        if (!this.runtimeData.unlockObj.includes(ID)) {
            var config = Global_1.tMgr.getConfig(TableDefine_1.TableName.GAME_SCENE_OBJ, ID);
            if (config) {
                this.runtimeData.unlockObj.push(ID);
                BattleConst_1.getGlobalNode().emit(Global_1.GlobalEvent.OBJ_UNLOCK, ID);
                SoundManager_1.SoundManager.ins.playEffect(Global_1.SoundName.BUILD);
            }
        }
    };
    SaveDataManager.prototype.setUserSkillNumDelta = function (skillId, delta) {
        if (!this.runtimeData.userSkillNum[skillId]) {
            this.runtimeData.userSkillNum[skillId] = delta;
        }
        else {
            this.runtimeData.userSkillNum[skillId] += delta;
        }
        if (this.runtimeData.userSkillNum[skillId] < 0) {
            this.runtimeData.userSkillNum[skillId] = 0;
        }
        BattleConst_1.getGlobalNode().emit(Global_1.GlobalEvent.SKILL_NUM_CHANGE, skillId);
    };
    SaveDataManager.prototype.getUserSkillNum = function (skillId) {
        if (!this.runtimeData.userSkillNum[skillId]) {
            return 0;
        }
        else {
            return this.runtimeData.userSkillNum[skillId];
        }
    };
    SaveDataManager.prototype.setMusicMute = function (value) {
        this.runtimeData.musicMute = value;
        this.saveData();
        BattleConst_1.getGlobalNode().emit(Global_1.GlobalEvent.SOUND_MUSIC_CONFIG_CHANGE, this.runtimeData.musicMute);
    };
    SaveDataManager.prototype.setSoundEffectMute = function (value) {
        this.runtimeData.SEMute = value;
        this.saveData();
        BattleConst_1.getGlobalNode().emit(Global_1.GlobalEvent.SOUND_EFFECT_CONFIG_CHANGE, this.runtimeData.SEMute);
    };
    SaveDataManager.prototype.unlockBallSkin = function (id) {
        if (!this.runtimeData.ballSkinUnlocked.includes(id)) {
            this.runtimeData.ballSkinUnlocked.push(id);
            this.saveData();
            BattleConst_1.getGlobalNode().emit(Global_1.GlobalEvent.BALL_SKIN_UNLOCK);
        }
    };
    SaveDataManager.prototype.useBallSkin = function (id) {
        if (id != SaveDataManager.ins.runtimeData.ballSkinCurrent) {
            SaveDataManager.ins.runtimeData.ballSkinCurrent = id;
            this.saveData();
            BattleConst_1.getGlobalNode().emit(Global_1.GlobalEvent.BALL_SKIN_USE);
        }
    };
    SaveDataManager.prototype.update = function (dt) {
        // if (this._addStarNum > 0) {
        //     this._addStarCount += dt;
        //     if (this._addStarCount > 0.1) {
        //         this._addStarCount = 0;
        // this.makeStar();
        // }
        // }
        // this._saveTimeCount += dt;
        // if (this._saveTimeCount >= this._saveTimeFrq) {
        //     this._saveTimeCount = 0;
        //     if (this.runtimeData.curCoin != this._coinDirty) { //有脏数据时才保存
        //         // this._coinDirty = this.runtimeData.curCoin;
        //         this.saveData();
        //     }
        // }
    };
    SaveDataManager.prototype.makeStar = function (wPos, delta) {
        var _this = this;
        var node = new cc.Node();
        var sp = node.addComponent(cc.Sprite);
        sp.spriteFrame = cc.resources.get('ui/general/UI_Title_star', cc.SpriteFrame);
        UIManager_1.UIManager.ins.widgetLayer.addChild(node);
        if (delta < 0) {
            //如果扣钱,起点设在widget上
            var widgetNode = UIManager_1.UIManager.ins.getWidgetNode(Global_1.ResType.STAR);
            node.setPosition(widgetNode.position.x - widgetNode.width / 2, widgetNode.y, widgetNode.z);
        }
        cc.tween(node).to(0.2, { position: wPos }, { easing: 'sineOut' }).call(function () {
            node.destroy();
            _this.adjustStar(delta, false);
        }).start();
        SoundManager_1.SoundManager.ins.playEffect(Global_1.SoundName.USE_STAR);
    };
    SaveDataManager.prototype.makeDiamond = function (wPos, delta) {
        var _this = this;
        var node = new cc.Node();
        var sp = node.addComponent(cc.Sprite);
        sp.spriteFrame = cc.resources.get('ui/general/UI_Title_diamond', cc.SpriteFrame);
        UIManager_1.UIManager.ins.widgetLayer.addChild(node);
        if (delta < 0) {
            //如果扣钱,起点设在widget上
            var widgetNode = UIManager_1.UIManager.ins.getWidgetNode(Global_1.ResType.DIAMOND);
            node.setPosition(widgetNode.position.x - widgetNode.width / 2, widgetNode.y, widgetNode.z);
        }
        else {
            SoundManager_1.SoundManager.ins.playEffect(Global_1.SoundName.DIAMOND);
        }
        cc.tween(node).to(0.2, { position: wPos }, { easing: 'sineOut' }).call(function () {
            node.destroy();
            _this.adjustDiamond(delta, false);
        }).start();
    };
    /**设置某一关的过关成绩(星星数) */
    SaveDataManager.prototype.setLevelStarNum = function (level, star) {
        if (star < 0 || star > 3) {
            return;
        }
        if (this.runtimeData.levelScoreMap[level]) {
            //已有数据,只有在取得更好成绩时才更改
            if (star > this.runtimeData.levelScoreMap[level]) {
                this.runtimeData.levelScoreMap[level] = star;
                BattleConst_1.getGlobalNode().emit(Global_1.GlobalEvent.LEVEL_STAR_CHANGE, level);
                this.saveData();
            }
        }
        else {
            this.runtimeData.levelScoreMap[level] = star;
            BattleConst_1.getGlobalNode().emit(Global_1.GlobalEvent.LEVEL_STAR_CHANGE, level);
            this.saveData();
        }
    };
    SaveDataManager.prototype.getLevelStarNum = function (levelId) {
        if (this.runtimeData.levelScoreMap[levelId]) {
            return this.runtimeData.levelScoreMap[levelId];
        }
        return 0;
    };
    SaveDataManager._ins = null;
    SaveDataManager.DATA_VERSION = "1.0.1";
    SaveDataManager.PKG_NAME = 'com.BaiYing.Marbles';
    return SaveDataManager;
}());
exports.SaveDataManager = SaveDataManager;

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,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbImFzc2V0c1xcc2NyaXB0c1xcY29tcG9uZW50XFxTYXZlRGF0YU1hbmFnZXIudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FBQUEsb0NBQThFO0FBQzlFLDREQUE2RDtBQUM3RCxtREFBOEM7QUFDOUMsMkRBQTJFO0FBQzNFLDZDQUE0QztBQUM1QywrQ0FBOEM7QUFHOUM7SUFBQTtRQWNJLGdCQUFXLEdBQW9CLElBQUksQ0FBQztRQUVwQyxrQkFBa0I7UUFDbEIscUJBQWdCLEdBQVcsQ0FBQyxDQUFDO1FBRTdCLG9DQUFvQztRQUNwQyxzQ0FBc0M7UUFDdEMsa0NBQWtDO1FBRWxDLFdBQU0sR0FBVyxDQUFDLENBQUM7SUEwWXZCLENBQUM7SUE5Wkcsc0JBQVcsc0JBQUc7YUFBZDtZQUNJLElBQUksSUFBSSxDQUFDLElBQUksSUFBSSxJQUFJLEVBQUU7Z0JBQ25CLElBQUksQ0FBQyxJQUFJLEdBQUcsSUFBSSxlQUFlLEVBQUUsQ0FBQzthQUNyQztZQUVELE9BQU8sSUFBSSxDQUFDLElBQUksQ0FBQztRQUNyQixDQUFDOzs7T0FBQTtJQWdCRCxvQ0FBVSxHQUFWO1FBQ0ksSUFBSSxNQUFNLEVBQUU7WUFDUixPQUFPLElBQUksQ0FBQyxNQUFNLEdBQUcsT0FBTyxHQUFHLEVBQUUsR0FBRyxJQUFJLENBQUMsR0FBRyxFQUFFLENBQUM7U0FDbEQ7YUFDSTtZQUNELE9BQU8sSUFBSSxDQUFDLEdBQUcsRUFBRSxDQUFDO1NBQ3JCO0lBQ0wsQ0FBQztJQUVELDhCQUFJLEdBQUo7UUFDSSxJQUFJLENBQUMsU0FBUyxFQUFFLENBQUM7UUFFakIsSUFBSSxZQUFZLEdBQUcsRUFBRSxDQUFDLEdBQUcsQ0FBQyxZQUFZLENBQUMsT0FBTyxDQUFDLHFCQUFxQixHQUFHLEdBQUcsR0FBRyxlQUFlLENBQUMsUUFBUSxDQUFDLENBQUM7UUFDdkcsSUFBSSxZQUFZLElBQUksSUFBSSxJQUFJLFlBQVksQ0FBQyxNQUFNLElBQUksQ0FBQyxFQUFF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Q2xEO1FBQ0QsT0FBTyxDQUFDLENBQUM7SUFDYixDQUFDO0lBOVpjLG9CQUFJLEdBQW9CLElBQUksQ0FBQztJQVNyQyw0QkFBWSxHQUFHLE9BQU8sQ0FBQztJQUN2Qix3QkFBUSxHQUFHLHFCQUFxQixDQUFDO0lBcVo1QyxzQkFBQztDQWphRCxBQWlhQyxJQUFBO0FBamFZLDBDQUFlIiwiZmlsZSI6IiIsInNvdXJjZVJvb3QiOiIvIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgR2xvYmFsRXZlbnQsIFJlc1R5cGUsIFNvdW5kTmFtZSwgdE1nciwgV2luZG93TmFtZSB9IGZyb20gXCIuLi9HbG9iYWxcIjtcbmltcG9ydCB7IGdldEdsb2JhbE5vZGUgfSBmcm9tIFwiLi4va2VybmVsL2JhdHRsZS9CYXR0bGVDb25zdFwiO1xuaW1wb3J0IEdsb2JhbE5vZGUgZnJvbSBcIi4uL2tlcm5lbC9HbG9iYWxOb2RlXCI7XG5pbXBvcnQgeyBHYW1lU2NlbmVPYmpUYWJsZSwgVGFibGVOYW1lIH0gZnJvbSBcIi4uL2tlcm5lbC90YWJsZS9UYWJsZURlZmluZVwiO1xuaW1wb3J0IHsgVUlNYW5hZ2VyIH0gZnJvbSBcIi4uL3VpL1VJTWFuYWdlclwiO1xuaW1wb3J0IHsgU291bmRNYW5hZ2VyIH0gZnJvbSBcIi4vU291bmRNYW5hZ2VyXCI7XG5cblxuZXhwb3J0IGNsYXNzIFNhdmVEYXRhTWFuYWdlciB7XG5cbiAgICBwcml2YXRlIHN0YXRpYyBfaW5zOiBTYXZlRGF0YU1hbmFnZXIgPSBudWxsO1xuICAgIHN0YXRpYyBnZXQgaW5zKCk6IFNhdmVEYXRhTWFuYWdlciB7XG4gICAgICAgIGlmICh0aGlzLl9pbnMgPT0gbnVsbCkge1xuICAgICAgICAgICAgdGhpcy5faW5zID0gbmV3IFNhdmVEYXRhTWFuYWdlcigpO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIHRoaXMuX2lucztcbiAgICB9XG5cbiAgICBzdGF0aWMgREFUQV9WRVJTSU9OID0gXCIxLjAuMVwiO1xuICAgIHN0YXRpYyBQS0dfTkFNRSA9ICdjb20uQmFpWWluZy5NYXJibGVzJztcblxuICAgIHJ1bnRpbWVEYXRhOiBSdW50aW1lRGF0YV9BbGwgPSBudWxsO1xuXG4gICAgLyoq5Zue5Yiw5Li75Zy65pmv5ZCO5b6F5re75Yqg55qE5pif5pifICovXG4gICAgbWFpblNjZW5lQWRkU3RhcjogbnVtYmVyID0gMDtcblxuICAgIC8vIHByaXZhdGUgX3NhdmVUaW1lRnJxOiBudW1iZXIgPSA1O1xuICAgIC8vIHByaXZhdGUgX3NhdmVUaW1lQ291bnQ6IG51bWJlciA9IDA7XG4gICAgLy8gcHJpdmF0ZSBfY29pbkRpcnR5OiBudW1iZXIgPSAwO1xuXG4gICAgZGV2RGF5OiBudW1iZXIgPSAwO1xuXG4gICAgZ2V0Tm93VGltZSgpOiBudW1iZXIge1xuICAgICAgICBpZiAoQ0NfREVWKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5kZXZEYXkgKiAzNjAwMDAwICogMjQgKyBEYXRlLm5vdygpO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgcmV0dXJuIERhdGUubm93KCk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBpbml0KCk6IHZvaWQge1xuICAgICAgICB0aGlzLnJlc2V0RGF0YSgpO1xuXG4gICAgICAgIGxldCB1c2VyRGF0YVRleHQgPSBjYy5zeXMubG9jYWxTdG9yYWdlLmdldEl0ZW0oJ1VTRVJEQVRBX1BMQVlFUkRBVEEnICsgJ18nICsgU2F2ZURhdGFNYW5hZ2VyLlBLR19OQU1FKTtcbiAgICAgICAgaWYgKHVzZXJEYXRhVGV4dCA9PSBudWxsIHx8IHVzZXJEYXRhVGV4dC5sZW5ndGggPT0gMCkge1xuICAgICAgICAgICAgY29uc29sZS5sb2coJ1tEYXRhXVvmnKzlnLDmsqHmnInmlbDmja7vvIzkvb/nlKjliJ3lp4vmlbDmja5dJyk7XG4gICAgICAgICAgICB0aGlzLnNhdmVEYXRhKCk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBsZXQgdXNlckRhdGEgPSBKU09OLnBhcnNlKHVzZXJEYXRhVGV4dCk7XG4gICAgICAgICAgICBpZiAodXNlckRhdGEuY3VyRGF0YVZlcnNpb24gPT0gU2F2ZURhdGFNYW5hZ2VyLkRBVEFfVkVSU0lPTikge1xuICAgICAgICAgICAgICAgIHRoaXMucnVudGltZURhdGEgPSB0aGlzLmdldERhdGFPYmoodGhpcy5ydW50aW1lRGF0YSwgdXNlckRhdGEpO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBjb25zb2xlLmxvZygnW0RhdGFdW+aVsOaNrueJiOacrOS4jeWQjO+8jOS9v+eUqOWIneWni+aVsOaNrl0nKTtcbiAgICAgICAgICAgICAgICB0aGlzLnNhdmVEYXRhKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICAvLyB0aGlzLnJ1bnRpbWVEYXRhID0gSlNPTi5wYXJzZSh1c2VyRGF0YVRleHQpO1xuXG4gICAgICAgICAgICAvLyBjb25zb2xlLmxvZygnW0RhdGFdW+ivu+WPlue7k+adn13nu5PmnpzkuLrvvJonKVxuICAgICAgICAgICAgLy8gY29uc29sZS5sb2codGhpcy5ydW50aW1lRGF0YSk7XG4gICAgICAgIH1cblxuICAgICAgICAvLyDph43mlrDorqHnrpfmr4/ml6Xku7vliqFcbiAgICAgICAgLy8gdGhpcy5BY3Rpb25fUmVmcmVzaERhaWx5TWlzc2lvbigpO1xuXG4gICAgICAgIC8vIOS/neWtmOaVsOaNrlxuICAgICAgICAvLyB0aGlzLnNhdmVEYXRhKCk7XG4gICAgICAgIC8vIERhdGFNYW5hZ2VyLmluaXRlZCA9IHRydWU7XG5cbiAgICAgICAgLy8gaWYgKF9maW5pc2hDYWxsYmFjayAhPSBudWxsKSB7XG4gICAgICAgIC8vICAgICBfZmluaXNoQ2FsbGJhY2soKTtcbiAgICAgICAgLy8gfVxuXG4gICAgICAgIC8vIHRoaXMuX2NvaW5EaXJ0eSA9IHRoaXMucnVudGltZURhdGEuY3VyQ29pbjtcblxuICAgICAgICBjYy5nYW1lLm9uKGNjLmdhbWUuRVZFTlRfSElERSwgdGhpcy5vbkdhbWVIaWRlT3JDbG9zZSwgdGhpcyk7XG5cbiAgICB9XG5cbiAgICBwcml2YXRlIG9uR2FtZUhpZGVPckNsb3NlKCkge1xuICAgICAgICBjYy5sb2coJ2dhbWUgaGlkZScpO1xuICAgICAgICB0aGlzLnNhdmVEYXRhKCk7XG4gICAgfVxuXG4gICAgZ2V0RGF0YU9iaihvcmlnaW5hbE9iaiwgbmV3T2JqKSB7XG4gICAgICAgIGlmICh0eXBlb2YgKG9yaWdpbmFsT2JqKSA9PSAnc3RyaW5nJykge1xuICAgICAgICAgICAgcmV0dXJuIG5ld09iajtcbiAgICAgICAgfVxuICAgICAgICBsZXQga2V5c19ydW50aW1lRGF0YSA9IE9iamVjdC5rZXlzKG9yaWdpbmFsT2JqKVxuICAgICAgICBsZXQga2V5c19sb2FkZWQgPSBPYmplY3Qua2V5cyhuZXdPYmopO1xuICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IGtleXNfcnVudGltZURhdGEubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgIGxldCBrZXkgPSBrZXlzX3J1bnRpbWVEYXRhW2ldO1xuXG4gICAgICAgICAgICAvLyBpZiAoa2V5ID09ICd1bmxvY2tTa2luTGlzdCcpIHtcbiAgICAgICAgICAgIC8vICAgICBsb2coKTtcbiAgICAgICAgICAgIC8vIH1cblxuICAgICAgICAgICAgLy8g5om+5Yiw5YKo5a2Y55qE5pWw5o2u5LiA6Ie055qEa2V577yM6LWL5YC857uZ5pys5ZywXG4gICAgICAgICAgICBmb3IgKGxldCBqID0gMDsgaiA8IGtleXNfbG9hZGVkLmxlbmd0aDsgaisrKSB7XG5cbiAgICAgICAgICAgICAgICBpZiAoa2V5c19sb2FkZWRbal0gPT0ga2V5KSB7XG5cbiAgICAgICAgICAgICAgICAgICAgaWYgKG9yaWdpbmFsT2JqW2tleV0gaW5zdGFuY2VvZiBBcnJheSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgb3JpZ2luYWxPYmpba2V5XSA9IG5ld09ialtrZXldO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgbGV0IHRlbXBLZXlzID0gT2JqZWN0LmtleXMob3JpZ2luYWxPYmpba2V5XSk7XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAodGVtcEtleXMubGVuZ3RoID4gMCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9yaWdpbmFsT2JqW2tleV0gPSB0aGlzLmdldERhdGFPYmoob3JpZ2luYWxPYmpba2V5XSwgbmV3T2JqW2tleV0pO1xuICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBvcmlnaW5hbE9ialtrZXldID0gbmV3T2JqW2tleV07XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gb3JpZ2luYWxPYmo7XG4gICAgfVxuXG4gICAgcmVzZXREYXRhKCkge1xuICAgICAgICB0aGlzLnJ1bnRpbWVEYXRhID0ge1xuICAgICAgICAgICAgY3VyRGF0YVZlcnNpb246IFNhdmVEYXRhTWFuYWdlci5EQVRBX1ZFUlNJT04sXG4gICAgICAgICAgICBzdGFyOiAwLFxuICAgICAgICAgICAgZGlhbW9uZDogMCxcbiAgICAgICAgICAgIGN1ckdhbWVTY2VuZTogMSxcbiAgICAgICAgICAgIHVubG9ja09iajogW10sXG4gICAgICAgICAgICB1c2VyU2tpbGxOdW06IHsgMTogMCwgMjogMCwgMzogMCwgNDogMCB9LFxuICAgICAgICAgICAgY3VyTGV2ZWw6IDAsXG4gICAgICAgICAgICBnZW5kZXI6IC0xLFxuICAgICAgICAgICAgZnJlZVdoZWVsTnVtOiAzLFxuICAgICAgICAgICAgbG9naW5SZXdhcmREYXRhOiB7XG4gICAgICAgICAgICAgICAgc3RlcDogMCxcbiAgICAgICAgICAgICAgICBmcmVzaFRpbWU6IDAsXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgbXVzaWNNdXRlOiBmYWxzZSxcbiAgICAgICAgICAgIFNFTXV0ZTogZmFsc2UsXG4gICAgICAgICAgICB2aWJyYXRpb246IHRydWUsXG4gICAgICAgICAgICBnb2xkZW5BaW1FbmRUaW1lOiAwLFxuICAgICAgICAgICAgZ29sZGVuQWltVHJ5OiBmYWxzZSxcbiAgICAgICAgICAgIGJhbGxTa2luVW5sb2NrZWQ6IFs0XSxcbiAgICAgICAgICAgIGJhbGxTa2luQ3VycmVudDogNCxcbiAgICAgICAgICAgIHNob3BEYWlseVBhY2tSZWZyZXNoVGltZTogMCxcbiAgICAgICAgICAgIGJhbGxTa2luVHJ5OiAwLFxuICAgICAgICAgICAgZ3VpZGVTdGVwOiAwLFxuICAgICAgICAgICAgbGV2ZWxTY29yZU1hcDoge31cbiAgICAgICAgfVxuICAgIH1cblxuICAgIHNhdmVEYXRhKCkge1xuICAgICAgICAvLyBjb25zb2xlLmxvZyhcIltEYXRhXVvkv53lrZjmlbDmja7miJDlip9dXCIpXG4gICAgICAgIC8vIGNvbnNvbGUubG9nKERhdGFNYW5hZ2VyLlJ1bnRpbWVEYXRhKVxuICAgICAgICBjYy5zeXMubG9jYWxTdG9yYWdlLnNldEl0ZW0oJ1VTRVJEQVRBX1BMQVlFUkRBVEEnICsgJ18nICsgU2F2ZURhdGFNYW5hZ2VyLlBLR19OQU1FLCBKU09OLnN0cmluZ2lmeSh0aGlzLnJ1bnRpbWVEYXRhKSk7XG4gICAgICAgIC8vIHRoaXMuX2NvaW5EaXJ0eSA9IHRoaXMucnVudGltZURhdGEuY3VyQ29pbjtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBcbiAgICAgKiBAcGFyYW0gZGVsdGEgXG4gICAgICogQHBhcmFtIHVzZUFuaSBcbiAgICAgKiBAcGFyYW0gd1BvcyDmmJ/mmJ/liqjnlLvnmoTnm67moIfngrnvvIzkuJbnlYzlnZDmoIfvvIzlvZN1c2VBbmnkuLp0cnVl5pe25LiUZGVsdGHlsI/kuo4w5pe26ZyA6KaB5Lyg5YWlXG4gICAgICogQHJldHVybnMg5piv5ZCm5oiQ5Yqf77yM5b2TZGVsdGHlsI/kuo4w5pe277yM5Lya5qOA5rWL5b2T5YmN6ZKx5piv5ZCm6Laz5aSfXG4gICAgICovXG4gICAgYWRqdXN0U3RhcihkZWx0YTogbnVtYmVyLCB1c2VBbmk6IGJvb2xlYW4gPSBmYWxzZSwgd1Bvcz86IGNjLlZlYzMpOiBib29sZWFuIHtcblxuICAgICAgICBpZiAoZGVsdGEgPCAwICYmIHRoaXMucnVudGltZURhdGEuc3RhciA8IE1hdGguYWJzKGRlbHRhKSkge1xuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHVzZUFuaSkge1xuXG4gICAgICAgICAgICBpZiAoZGVsdGEgPCAwKSB7XG4gICAgICAgICAgICAgICAgVUlNYW5hZ2VyLmlucy53aWRnZXRMYXllci5jb252ZXJ0VG9Ob2RlU3BhY2VBUih3UG9zLCB3UG9zKTsgLy/miaPpkrHml7bkvb/nlKjkvKDlhaXnmoTkvY3nva5cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgIGxldCB3aWRnZXROb2RlID0gVUlNYW5hZ2VyLmlucy5nZXRXaWRnZXROb2RlKFJlc1R5cGUuU1RBUik7XG4gICAgICAgICAgICAgICAgd1BvcyA9IGNjLnYzKHdpZGdldE5vZGUucG9zaXRpb24ueCAtIHdpZGdldE5vZGUud2lkdGggLyAyLCB3aWRnZXROb2RlLnksIHdpZGdldE5vZGUueik7IC8v5Yqg6ZKx5pe25L2/55Sod2lkZ2V05L2N572uXG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGdldEdsb2JhbE5vZGUoKS5nZXRDb21wb25lbnQoR2xvYmFsTm9kZSkuc2NoZWR1bGUoKGR0KSA9PiB7XG5cbiAgICAgICAgICAgICAgICB0aGlzLm1ha2VTdGFyKHdQb3MsIGRlbHRhIC8gTWF0aC5hYnMoZGVsdGEpKTtcblxuICAgICAgICAgICAgfSwgMC4xLCBNYXRoLmFicyhkZWx0YSkgLSAxLCAwKTtcblxuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgdGhpcy5ydW50aW1lRGF0YS5zdGFyICs9IGRlbHRhO1xuICAgICAgICAgICAgdGhpcy5zYXZlRGF0YSgpO1xuICAgICAgICAgICAgZ2V0R2xvYmFsTm9kZSgpLmVtaXQoR2xvYmFsRXZlbnQuQ0hBTkdFX0VWRU5UX1NUQVIsIGRlbHRhKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFxuICAgICAqIEBwYXJhbSBkZWx0YSBcbiAgICAgKiBAcmV0dXJucyDmmK/lkKbmiJDlip/vvIzlvZNkZWx0YeWwj+S6jjDml7bvvIzkvJrmo4DmtYvlvZPliY3pkrHmmK/lkKbotrPlpJ9cbiAgICAgKi9cbiAgICBhZGp1c3REaWFtb25kKGRlbHRhOiBudW1iZXIsIHVzZUFuaTogYm9vbGVhbiA9IGZhbHNlLCB3UG9zPzogY2MuVmVjMyk6IGJvb2xlYW4ge1xuXG4gICAgICAgIGlmIChkZWx0YSA8IDAgJiYgdGhpcy5ydW50aW1lRGF0YS5kaWFtb25kIDwgTWF0aC5hYnMoZGVsdGEpKSB7XG4gICAgICAgICAgICBVSU1hbmFnZXIuaW5zLm9wZW5XaW5kb3coV2luZG93TmFtZS5GUkVFX0RJQU1PTkQpO1xuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHVzZUFuaSkge1xuXG4gICAgICAgICAgICBpZiAoZGVsdGEgPCAwKSB7XG4gICAgICAgICAgICAgICAgVUlNYW5hZ2VyLmlucy53aWRnZXRMYXllci5jb252ZXJ0VG9Ob2RlU3BhY2VBUih3UG9zLCB3UG9zKTsgLy/miaPpkrHml7bkvb/nlKjkvKDlhaXnmoTkvY3nva5cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgIGxldCB3aWRnZXROb2RlID0gVUlNYW5hZ2VyLmlucy5nZXRXaWRnZXROb2RlKFJlc1R5cGUuRElBTU9ORCk7XG4gICAgICAgICAgICAgICAgd1BvcyA9IGNjLnYzKHdpZGdldE5vZGUucG9zaXRpb24ueCAtIHdpZGdldE5vZGUud2lkdGggLyAyLCB3aWRnZXROb2RlLnksIHdpZGdldE5vZGUueik7IC8v5Yqg6ZKx5pe25L2/55Sod2lkZ2V05L2N572uXG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGlmIChNYXRoLmFicyhkZWx0YSkgPCA1KSB7XG4gICAgICAgICAgICAgICAgdGhpcy5tYWtlRGlhbW9uZCh3UG9zLCBkZWx0YSk7IC8v5bCP5LqONeWPquaSreS4gOasoVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgbGV0IHN0ZXAgPSBNYXRoLmNlaWwoZGVsdGEgLyA1KTtcbiAgICAgICAgICAgICAgICBsZXQgbGFzdFN0ZXAgPSBkZWx0YSAtIHN0ZXAgKiA0O1xuXG4gICAgICAgICAgICAgICAgLy9jb25zb2xlLmxvZygnc3RlcCcsIHN0ZXAsICdsYXN0IHN0ZXAnLCBsYXN0U3RlcCk7XG5cbiAgICAgICAgICAgICAgICBnZXRHbG9iYWxOb2RlKCkuZ2V0Q29tcG9uZW50KEdsb2JhbE5vZGUpLnNjaGVkdWxlKCgpID0+IHtcblxuICAgICAgICAgICAgICAgICAgICB0aGlzLm1ha2VEaWFtb25kKHdQb3MsIHN0ZXApO1xuXG4gICAgICAgICAgICAgICAgfSwgMC4xLCAzLCAwKTtcblxuICAgICAgICAgICAgICAgIGlmIChsYXN0U3RlcCAhPSAwKSB7XG4gICAgICAgICAgICAgICAgICAgIGdldEdsb2JhbE5vZGUoKS5nZXRDb21wb25lbnQoR2xvYmFsTm9kZSkuc2NoZWR1bGVPbmNlKCgpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMubWFrZURpYW1vbmQod1BvcywgbGFzdFN0ZXApO1xuICAgICAgICAgICAgICAgICAgICB9LCAwLjUpXG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIC8vIGdldEdsb2JhbE5vZGUoKS5nZXRDb21wb25lbnQoR2xvYmFsTm9kZSkuc2NoZWR1bGUoKGR0KSA9PiB7XG5cbiAgICAgICAgICAgIC8vICAgICB0aGlzLm1ha2VEaWFtb25kKHdQb3MsIGRlbHRhIC8gTWF0aC5hYnMoZGVsdGEpKTtcblxuICAgICAgICAgICAgLy8gfSwgMC4xLCBNYXRoLmFicyhkZWx0YSkgLSAxLCAwKTtcblxuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgdGhpcy5ydW50aW1lRGF0YS5kaWFtb25kICs9IGRlbHRhO1xuICAgICAgICAgICAgdGhpcy5zYXZlRGF0YSgpO1xuICAgICAgICAgICAgZ2V0R2xvYmFsTm9kZSgpLmVtaXQoR2xvYmFsRXZlbnQuQ0hBTkdFX0VWRU5UX0RJQU1PTkQsIGRlbHRhKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cblxuICAgIHVubG9ja0dhbWVTY2VuZU9iaihJRDogbnVtYmVyKSB7XG5cbiAgICAgICAgaWYgKCF0aGlzLnJ1bnRpbWVEYXRhLnVubG9ja09iai5pbmNsdWRlcyhJRCkpIHtcblxuICAgICAgICAgICAgbGV0IGNvbmZpZyA9IHRNZ3IuZ2V0Q29uZmlnKFRhYmxlTmFtZS5HQU1FX1NDRU5FX09CSiwgSUQpIGFzIEdhbWVTY2VuZU9ialRhYmxlO1xuXG4gICAgICAgICAgICBpZiAoY29uZmlnKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5ydW50aW1lRGF0YS51bmxvY2tPYmoucHVzaChJRCk7XG4gICAgICAgICAgICAgICAgZ2V0R2xvYmFsTm9kZSgpLmVtaXQoR2xvYmFsRXZlbnQuT0JKX1VOTE9DSywgSUQpO1xuXG4gICAgICAgICAgICAgICAgU291bmRNYW5hZ2VyLmlucy5wbGF5RWZmZWN0KFNvdW5kTmFtZS5CVUlMRCk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgfVxuICAgIH1cblxuICAgIHNldFVzZXJTa2lsbE51bURlbHRhKHNraWxsSWQ6IG51bWJlciwgZGVsdGE6IG51bWJlcikge1xuICAgICAgICBpZiAoIXRoaXMucnVudGltZURhdGEudXNlclNraWxsTnVtW3NraWxsSWRdKSB7XG4gICAgICAgICAgICB0aGlzLnJ1bnRpbWVEYXRhLnVzZXJTa2lsbE51bVtza2lsbElkXSA9IGRlbHRhO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgdGhpcy5ydW50aW1lRGF0YS51c2VyU2tpbGxOdW1bc2tpbGxJZF0gKz0gZGVsdGE7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAodGhpcy5ydW50aW1lRGF0YS51c2VyU2tpbGxOdW1bc2tpbGxJZF0gPCAwKSB7XG4gICAgICAgICAgICB0aGlzLnJ1bnRpbWVEYXRhLnVzZXJTa2lsbE51bVtza2lsbElkXSA9IDA7XG4gICAgICAgIH1cblxuICAgICAgICBnZXRHbG9iYWxOb2RlKCkuZW1pdChHbG9iYWxFdmVudC5TS0lMTF9OVU1fQ0hBTkdFLCBza2lsbElkKTtcbiAgICB9XG5cbiAgICBnZXRVc2VyU2tpbGxOdW0oc2tpbGxJZDogbnVtYmVyKTogbnVtYmVyIHtcbiAgICAgICAgaWYgKCF0aGlzLnJ1bnRpbWVEYXRhLnVzZXJTa2lsbE51bVtza2lsbElkXSkge1xuICAgICAgICAgICAgcmV0dXJuIDA7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5ydW50aW1lRGF0YS51c2VyU2tpbGxOdW1bc2tpbGxJZF07XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBzZXRNdXNpY011dGUodmFsdWU6IGJvb2xlYW4pIHtcbiAgICAgICAgdGhpcy5ydW50aW1lRGF0YS5tdXNpY011dGUgPSB2YWx1ZTtcbiAgICAgICAgdGhpcy5zYXZlRGF0YSgpO1xuICAgICAgICBnZXRHbG9iYWxOb2RlKCkuZW1pdChHbG9iYWxFdmVudC5TT1VORF9NVVNJQ19DT05GSUdfQ0hBTkdFLCB0aGlzLnJ1bnRpbWVEYXRhLm11c2ljTXV0ZSk7XG4gICAgfVxuXG4gICAgc2V0U291bmRFZmZlY3RNdXRlKHZhbHVlOiBib29sZWFuKSB7XG4gICAgICAgIHRoaXMucnVudGltZURhdGEuU0VNdXRlID0gdmFsdWU7XG4gICAgICAgIHRoaXMuc2F2ZURhdGEoKTtcbiAgICAgICAgZ2V0R2xvYmFsTm9kZSgpLmVtaXQoR2xvYmFsRXZlbnQuU09VTkRfRUZGRUNUX0NPTkZJR19DSEFOR0UsIHRoaXMucnVudGltZURhdGEuU0VNdXRlKTtcbiAgICB9XG5cbiAgICB1bmxvY2tCYWxsU2tpbihpZDogbnVtYmVyKSB7XG5cbiAgICAgICAgaWYgKCF0aGlzLnJ1bnRpbWVEYXRhLmJhbGxTa2luVW5sb2NrZWQuaW5jbHVkZXMoaWQpKSB7XG4gICAgICAgICAgICB0aGlzLnJ1bnRpbWVEYXRhLmJhbGxTa2luVW5sb2NrZWQucHVzaChpZCk7XG4gICAgICAgICAgICB0aGlzLnNhdmVEYXRhKCk7XG4gICAgICAgICAgICBnZXRHbG9iYWxOb2RlKCkuZW1pdChHbG9iYWxFdmVudC5CQUxMX1NLSU5fVU5MT0NLKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHVzZUJhbGxTa2luKGlkOiBudW1iZXIpIHtcblxuICAgICAgICBpZiAoaWQgIT0gU2F2ZURhdGFNYW5hZ2VyLmlucy5ydW50aW1lRGF0YS5iYWxsU2tpbkN1cnJlbnQpIHtcbiAgICAgICAgICAgIFNhdmVEYXRhTWFuYWdlci5pbnMucnVudGltZURhdGEuYmFsbFNraW5DdXJyZW50ID0gaWQ7XG4gICAgICAgICAgICB0aGlzLnNhdmVEYXRhKCk7XG4gICAgICAgICAgICBnZXRHbG9iYWxOb2RlKCkuZW1pdChHbG9iYWxFdmVudC5CQUxMX1NLSU5fVVNFKTtcbiAgICAgICAgfVxuXG4gICAgfVxuXG5cbiAgICB1cGRhdGUoZHQ6IG51bWJlcik6IHZvaWQge1xuXG4gICAgICAgIC8vIGlmICh0aGlzLl9hZGRTdGFyTnVtID4gMCkge1xuXG4gICAgICAgIC8vICAgICB0aGlzLl9hZGRTdGFyQ291bnQgKz0gZHQ7XG5cbiAgICAgICAgLy8gICAgIGlmICh0aGlzLl9hZGRTdGFyQ291bnQgPiAwLjEpIHtcbiAgICAgICAgLy8gICAgICAgICB0aGlzLl9hZGRTdGFyQ291bnQgPSAwO1xuXG4gICAgICAgIC8vIHRoaXMubWFrZVN0YXIoKTtcbiAgICAgICAgLy8gfVxuICAgICAgICAvLyB9XG4gICAgICAgIC8vIHRoaXMuX3NhdmVUaW1lQ291bnQgKz0gZHQ7XG5cbiAgICAgICAgLy8gaWYgKHRoaXMuX3NhdmVUaW1lQ291bnQgPj0gdGhpcy5fc2F2ZVRpbWVGcnEpIHtcbiAgICAgICAgLy8gICAgIHRoaXMuX3NhdmVUaW1lQ291bnQgPSAwO1xuXG4gICAgICAgIC8vICAgICBpZiAodGhpcy5ydW50aW1lRGF0YS5jdXJDb2luICE9IHRoaXMuX2NvaW5EaXJ0eSkgeyAvL+acieiEj+aVsOaNruaXtuaJjeS/neWtmFxuICAgICAgICAvLyAgICAgICAgIC8vIHRoaXMuX2NvaW5EaXJ0eSA9IHRoaXMucnVudGltZURhdGEuY3VyQ29pbjtcbiAgICAgICAgLy8gICAgICAgICB0aGlzLnNhdmVEYXRhKCk7XG4gICAgICAgIC8vICAgICB9XG5cbiAgICAgICAgLy8gfVxuICAgIH1cblxuICAgIHByaXZhdGUgbWFrZVN0YXIod1BvczogY2MuVmVjMywgZGVsdGE6IG51bWJlcikge1xuICAgICAgICBsZXQgbm9kZSA9IG5ldyBjYy5Ob2RlKCk7XG4gICAgICAgIGxldCBzcCA9IG5vZGUuYWRkQ29tcG9uZW50KGNjLlNwcml0ZSk7XG4gICAgICAgIHNwLnNwcml0ZUZyYW1lID0gY2MucmVzb3VyY2VzLmdldDxjYy5TcHJpdGVGcmFtZT4oJ3VpL2dlbmVyYWwvVUlfVGl0bGVfc3RhcicsIGNjLlNwcml0ZUZyYW1lKTtcbiAgICAgICAgVUlNYW5hZ2VyLmlucy53aWRnZXRMYXllci5hZGRDaGlsZChub2RlKTtcblxuICAgICAgICBpZiAoZGVsdGEgPCAwKSB7XG4gICAgICAgICAgICAvL+WmguaenOaJo+mSse+8jOi1t+eCueiuvuWcqHdpZGdldOS4ilxuICAgICAgICAgICAgbGV0IHdpZGdldE5vZGUgPSBVSU1hbmFnZXIuaW5zLmdldFdpZGdldE5vZGUoUmVzVHlwZS5TVEFSKTtcbiAgICAgICAgICAgIG5vZGUuc2V0UG9zaXRpb24od2lkZ2V0Tm9kZS5wb3NpdGlvbi54IC0gd2lkZ2V0Tm9kZS53aWR0aCAvIDIsIHdpZGdldE5vZGUueSwgd2lkZ2V0Tm9kZS56KTtcbiAgICAgICAgfVxuXG4gICAgICAgIGNjLnR3ZWVuKG5vZGUpLnRvKDAuMiwgeyBwb3NpdGlvbjogd1BvcyB9LCB7IGVhc2luZzogJ3NpbmVPdXQnIH0pLmNhbGwoKCkgPT4ge1xuICAgICAgICAgICAgbm9kZS5kZXN0cm95KCk7XG4gICAgICAgICAgICB0aGlzLmFkanVzdFN0YXIoZGVsdGEsIGZhbHNlKTtcbiAgICAgICAgfSkuc3RhcnQoKTtcblxuICAgICAgICBTb3VuZE1hbmFnZXIuaW5zLnBsYXlFZmZlY3QoU291bmROYW1lLlVTRV9TVEFSKTtcbiAgICB9XG5cbiAgICBwcml2YXRlIG1ha2VEaWFtb25kKHdQb3M6IGNjLlZlYzMsIGRlbHRhOiBudW1iZXIpIHtcbiAgICAgICAgbGV0IG5vZGUgPSBuZXcgY2MuTm9kZSgpO1xuICAgICAgICBsZXQgc3AgPSBub2RlLmFkZENvbXBvbmVudChjYy5TcHJpdGUpO1xuICAgICAgICBzcC5zcHJpdGVGcmFtZSA9IGNjLnJlc291cmNlcy5nZXQ8Y2MuU3ByaXRlRnJhbWU+KCd1aS9nZW5lcmFsL1VJX1RpdGxlX2RpYW1vbmQnLCBjYy5TcHJpdGVGcmFtZSk7XG4gICAgICAgIFVJTWFuYWdlci5pbnMud2lkZ2V0TGF5ZXIuYWRkQ2hpbGQobm9kZSk7XG5cbiAgICAgICAgaWYgKGRlbHRhIDwgMCkge1xuICAgICAgICAgICAgLy/lpoLmnpzmiaPpkrHvvIzotbfngrnorr7lnKh3aWRnZXTkuIpcbiAgICAgICAgICAgIGxldCB3aWRnZXROb2RlID0gVUlNYW5hZ2VyLmlucy5nZXRXaWRnZXROb2RlKFJlc1R5cGUuRElBTU9ORCk7XG4gICAgICAgICAgICBub2RlLnNldFBvc2l0aW9uKHdpZGdldE5vZGUucG9zaXRpb24ueCAtIHdpZGdldE5vZGUud2lkdGggLyAyLCB3aWRnZXROb2RlLnksIHdpZGdldE5vZGUueik7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICBTb3VuZE1hbmFnZXIuaW5zLnBsYXlFZmZlY3QoU291bmROYW1lLkRJQU1PTkQpO1xuICAgICAgICB9XG5cbiAgICAgICAgY2MudHdlZW4obm9kZSkudG8oMC4yLCB7IHBvc2l0aW9uOiB3UG9zIH0sIHsgZWFzaW5nOiAnc2luZU91dCcgfSkuY2FsbCgoKSA9PiB7XG4gICAgICAgICAgICBub2RlLmRlc3Ryb3koKTtcbiAgICAgICAgICAgIHRoaXMuYWRqdXN0RGlhbW9uZChkZWx0YSwgZmFsc2UpO1xuICAgICAgICB9KS5zdGFydCgpO1xuICAgIH1cblxuICAgIC8qKuiuvue9ruafkOS4gOWFs+eahOi/h+WFs+aIkOe7qe+8iOaYn+aYn+aVsO+8iSAqL1xuICAgIHNldExldmVsU3Rhck51bShsZXZlbDogbnVtYmVyLCBzdGFyOiBudW1iZXIpIHtcblxuICAgICAgICBpZiAoc3RhciA8IDAgfHwgc3RhciA+IDMpIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmICh0aGlzLnJ1bnRpbWVEYXRhLmxldmVsU2NvcmVNYXBbbGV2ZWxdKSB7XG4gICAgICAgICAgICAvL+W3suacieaVsOaNru+8jOWPquacieWcqOWPluW+l+abtOWlveaIkOe7qeaXtuaJjeabtOaUuVxuICAgICAgICAgICAgaWYgKHN0YXIgPiB0aGlzLnJ1bnRpbWVEYXRhLmxldmVsU2NvcmVNYXBbbGV2ZWxdKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5ydW50aW1lRGF0YS5sZXZlbFNjb3JlTWFwW2xldmVsXSA9IHN0YXI7XG4gICAgICAgICAgICAgICAgZ2V0R2xvYmFsTm9kZSgpLmVtaXQoR2xvYmFsRXZlbnQuTEVWRUxfU1RBUl9DSEFOR0UsIGxldmVsKTtcbiAgICAgICAgICAgICAgICB0aGlzLnNhdmVEYXRhKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICB0aGlzLnJ1bnRpbWVEYXRhLmxldmVsU2NvcmVNYXBbbGV2ZWxdID0gc3RhcjtcbiAgICAgICAgICAgIGdldEdsb2JhbE5vZGUoKS5lbWl0KEdsb2JhbEV2ZW50LkxFVkVMX1NUQVJfQ0hBTkdFLCBsZXZlbCk7XG4gICAgICAgICAgICB0aGlzLnNhdmVEYXRhKCk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBnZXRMZXZlbFN0YXJOdW0obGV2ZWxJZDogbnVtYmVyKTogbnVtYmVyIHtcbiAgICAgICAgaWYgKHRoaXMucnVudGltZURhdGEubGV2ZWxTY29yZU1hcFtsZXZlbElkXSkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMucnVudGltZURhdGEubGV2ZWxTY29yZU1hcFtsZXZlbElkXTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gMDtcbiAgICB9XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgUnVudGltZURhdGFfQWxsIHtcbiAgICBjdXJEYXRhVmVyc2lvbjogc3RyaW5nLFxuICAgIHN0YXI6IG51bWJlcixcbiAgICBkaWFtb25kOiBudW1iZXIsXG4gICAgY3VyR2FtZVNjZW5lOiBudW1iZXIsXG4gICAgLyoq5bey6Kej6ZSB54mp5Lu2SUQgKi9cbiAgICB1bmxvY2tPYmo6IG51bWJlcltdLFxuICAgIHVzZXJTa2lsbE51bTogb2JqZWN0LFxuICAgIC8qKuW9k+WJjeW3sumAmuWFs+eahOWFs+WNoUlEICovXG4gICAgY3VyTGV2ZWw6IG51bWJlcixcbiAgICBnZW5kZXI6IG51bWJlcixcbiAgICAvKirmr4/ml6XlhY3otLnovaznm5jmrKHmlbAgKi9cbiAgICBmcmVlV2hlZWxOdW06IG51bWJlcixcbiAgICBsb2dpblJld2FyZERhdGE6IHtcbiAgICAgICAgc3RlcDogbnVtYmVyLFxuICAgICAgICBmcmVzaFRpbWU6IG51bWJlcixcbiAgICB9LFxuICAgIC8qKumfs+S5kOmdmemfsyAqL1xuICAgIG11c2ljTXV0ZTogYm9vbGVhbixcbiAgICAvKirpn7PmlYjpnZnpn7MgKi9cbiAgICBTRU11dGU6IGJvb2xlYW4sXG4gICAgLyoq6ZyH5Yqo5byA5YWzICovXG4gICAgdmlicmF0aW9uOiBib29sZWFuLFxuICAgIGdvbGRlbkFpbUVuZFRpbWU6IG51bWJlcjtcbiAgICBnb2xkZW5BaW1Ucnk6IGJvb2xlYW4sXG4gICAgYmFsbFNraW5VbmxvY2tlZDogbnVtYmVyW10sXG4gICAgYmFsbFNraW5DdXJyZW50OiBudW1iZXIsXG4gICAgLyoq6K+V55So55qu6IKkICovXG4gICAgYmFsbFNraW5Ucnk6IG51bWJlcixcbiAgICAvKirmr4/ml6XnpLzljIXliLfmlrDml7bpl7QgKi9cbiAgICBzaG9wRGFpbHlQYWNrUmVmcmVzaFRpbWU6IG51bWJlcixcbiAgICAvKirmlrDmiYvlvJXlr7zov5vluqYgKi9cbiAgICBndWlkZVN0ZXA6IG51bWJlcixcbiAgICBsZXZlbFNjb3JlTWFwOiBvYmplY3Rcbn0iXX0=