HotUpdate.js
42.9 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
(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