HttpRequest.js 57 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416
  1. (function() {
  2. var nodeEnv = typeof require !== 'undefined' && typeof process !== 'undefined';
  3. var __module = nodeEnv ? module : {exports:{}};
  4. var __filename = 'preview-scripts/assets/script/network/HttpRequest.js';
  5. var __require = nodeEnv ? function (request) {
  6. return cc.require(request);
  7. } : function (request) {
  8. return __quick_compile_project__.require(request, __filename);
  9. };
  10. function __define (exports, require, module) {
  11. if (!nodeEnv) {__quick_compile_project__.registerModule(__filename, module);}"use strict";
  12. cc._RF.push(module, '199d8DQmjZJqq3Vr/DZWAIY', 'HttpRequest');
  13. // script/network/HttpRequest.ts
  14. "use strict";
  15. var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
  16. function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
  17. return new (P || (P = Promise))(function (resolve, reject) {
  18. function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
  19. function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
  20. function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
  21. step((generator = generator.apply(thisArg, _arguments || [])).next());
  22. });
  23. };
  24. var __generator = (this && this.__generator) || function (thisArg, body) {
  25. var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
  26. return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
  27. function verb(n) { return function (v) { return step([n, v]); }; }
  28. function step(op) {
  29. if (f) throw new TypeError("Generator is already executing.");
  30. while (_) try {
  31. if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
  32. if (y = 0, t) op = [op[0] & 2, t.value];
  33. switch (op[0]) {
  34. case 0: case 1: t = op; break;
  35. case 4: _.label++; return { value: op[1], done: false };
  36. case 5: _.label++; y = op[1]; op = [0]; continue;
  37. case 7: op = _.ops.pop(); _.trys.pop(); continue;
  38. default:
  39. if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
  40. if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
  41. if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
  42. if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
  43. if (t[2]) _.ops.pop();
  44. _.trys.pop(); continue;
  45. }
  46. op = body.call(thisArg, _);
  47. } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
  48. if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
  49. }
  50. };
  51. Object.defineProperty(exports, "__esModule", { value: true });
  52. var StringMap_1 = require("../Collections/StringMap");
  53. var gameCfg_1 = require("../common/gameCfg");
  54. var gameMethod_1 = require("../common/gameMethod");
  55. var Config_1 = require("../Config");
  56. var EventConst_1 = require("../data/const/EventConst");
  57. var GameDataCenter_1 = require("../data/GameDataCenter");
  58. var GameController_1 = require("../GameController");
  59. var UIHelp_1 = require("../logic/ui/UIHelp");
  60. var EventMng_1 = require("../manager/EventMng");
  61. var I18nUtil_1 = require("../utils/I18nUtil");
  62. var NetConfig_1 = require("./NetConfig");
  63. var HttpRequest = /** @class */ (function () {
  64. function HttpRequest() {
  65. }
  66. HttpRequest.GET = function (path, callback) {
  67. if (callback === void 0) { callback = function () { }; }
  68. var isJiami = this.isJiamiPlatform();
  69. var r = new XMLHttpRequest();
  70. r.open("GET", path + ("?x=" + (isJiami ? 1 : 0)), true);
  71. r.timeout = this.timeoutMs;
  72. r.onerror = function () {
  73. console.log("发生错误,url=", path);
  74. callback({});
  75. };
  76. r.ontimeout = function () {
  77. console.log("超时了,url=", path);
  78. callback({});
  79. };
  80. r.onloadend = function () {
  81. var temp = {};
  82. if (r.status >= 200 && r.status <= 400 && r.readyState == 4) {
  83. var txt = gameMethod_1.gameMethod.xorEncrypt(r.response, isJiami);
  84. temp = JSON.parse(txt);
  85. }
  86. callback(temp);
  87. };
  88. r.send();
  89. };
  90. // 只发送,无需处理回调
  91. HttpRequest.POST_SIMPLE = function (url, body) {
  92. var r = new XMLHttpRequest();
  93. r.open("POST", url, true);
  94. r.setRequestHeader("Content-Type", "application/json");
  95. r.send(JSON.stringify(body));
  96. };
  97. // 发送业务外,需处理回调
  98. HttpRequest.POST_SIMPLE_2 = function (url, body, callback) {
  99. if (callback === void 0) { callback = function () { }; }
  100. var r = new XMLHttpRequest();
  101. r.open("POST", url, true);
  102. r.setRequestHeader("Content-Type", "application/json");
  103. r.onreadystatechange = function () {
  104. if (r.status >= 200 && r.status <= 400 && r.readyState == 4) {
  105. callback(r.response);
  106. }
  107. else {
  108. console.error("POST Faile:", r.status);
  109. }
  110. };
  111. r.send(JSON.stringify(body));
  112. };
  113. // 业务逻辑协议调用接口
  114. HttpRequest.POST = function (path, data, body, callback, isLogin) {
  115. var _this = this;
  116. if (callback === void 0) { callback = function () { }; }
  117. if (isLogin === void 0) { isLogin = false; }
  118. body = body || {};
  119. if (CC_JSB) {
  120. if (!gameMethod_1.gameMethod.isEmpty(GameDataCenter_1.default.sevBack) && !gameMethod_1.gameMethod.isEmpty(GameDataCenter_1.default.sevBack.switch) && !gameMethod_1.gameMethod.isEmpty(GameDataCenter_1.default.sevBack.switch.clientLog)) {
  121. console.warn("C->S:", path, JSON.stringify(body));
  122. }
  123. }
  124. else {
  125. if (!gameMethod_1.gameMethod.isEmpty(GameDataCenter_1.default.sevBack) && !gameMethod_1.gameMethod.isEmpty(GameDataCenter_1.default.sevBack.switch) && !gameMethod_1.gameMethod.isEmpty(GameDataCenter_1.default.sevBack.switch.clientLog)) {
  126. console.warn("C->S:", path, body);
  127. }
  128. }
  129. var delay = new Date().getTime();
  130. if (NetConfig_1.default.needWait(data.url, body)) {
  131. EventMng_1.default.emit(EventConst_1.NetworkEvent.WAIT, 1);
  132. }
  133. //淘宝需要通过云服务调用服务器
  134. if (cc.sys.platform == cc.sys.TAOBAO_MINIGAME) {
  135. this.taoBaoCloudRequest(data, body, callback, isLogin);
  136. return;
  137. }
  138. var r = new XMLHttpRequest();
  139. r.open("POST", path, true);
  140. r.timeout = this.timeoutMs;
  141. r.setRequestHeader("Content-Type", "application/json");
  142. var xor = this.isJiamiPlatform() ? 1 : 0; //原生端接收到加密数据会不全,所以就不加密了
  143. // r.onerror = () => {
  144. // // console.warn("=======https onerror", r.status, r.readyState)
  145. // callback({ type: 0 })
  146. // if (isLogin) {
  147. // EventMng.emit(NetworkEvent.LOGIN_FAILED)
  148. // return
  149. // }
  150. // this.onError(data.url)
  151. // }
  152. r.onerror = r.ontimeout = function () {
  153. // console.warn("=======https ontimeout", r.status, r.readyState)
  154. _this.netMs = r.timeout;
  155. // 超时的时候,先把waiting关掉
  156. if (NetConfig_1.default.needWait(data.url, body)) {
  157. EventMng_1.default.emit(EventConst_1.NetworkEvent.WAIT_CLOSE);
  158. }
  159. //请求失败时关闭强请求遮罩
  160. EventMng_1.default.emit(EventConst_1.NetworkEvent.NETWAIT_MASK, false);
  161. // 如果是登录过程中出错,特殊处理
  162. if (isLogin) {
  163. EventMng_1.default.emit(EventConst_1.NetworkEvent.LOGIN_FAILED);
  164. return;
  165. }
  166. _this.onTimeOut(data.url);
  167. };
  168. r.onreadystatechange = function () {
  169. // console.log("=======https onreadystatechange", r.status, r.readyState)
  170. if (r.readyState == 4) {
  171. _this.netMs = new Date().getTime() - delay;
  172. if (_this.netMs > 1000) {
  173. console.warn("服务器回调时间超过1秒:", path, JSON.stringify(body));
  174. }
  175. }
  176. var temp = {};
  177. if (r.status >= 200 && r.status <= 400 && r.readyState == 4) {
  178. _this.errCount = 0;
  179. if (r.response == null || r.response == "") {
  180. EventMng_1.default.emit(EventConst_1.NetworkEvent.ON_EXCEPTION);
  181. _this.showErrDialog(data.url, data.uuid, data.version, JSON.stringify(body), r.response == null ? "null" : r.response);
  182. return;
  183. }
  184. try {
  185. // temp = JSON.parse(r.response) // gameMethod.jiemi(r.response)
  186. // let jiemiTime = new Date().getTime()
  187. var txt = gameMethod_1.gameMethod.xorEncrypt(r.response, xor == 1);
  188. temp = JSON.parse(txt);
  189. // console.log("消息解密耗时:", new Date().getTime() - jiemiTime)
  190. }
  191. catch (error) {
  192. EventMng_1.default.emit(EventConst_1.NetworkEvent.ON_EXCEPTION);
  193. console.error("解析回调数据失败:", r.response);
  194. _this.showErrDialog(data.url, data.uuid, data.version, JSON.stringify(body), r.response == null ? "null" : r.response);
  195. }
  196. // try {
  197. if (temp && Object.keys(temp).length > 0) {
  198. if (CC_JSB) {
  199. if (!gameMethod_1.gameMethod.isEmpty(GameDataCenter_1.default.sevBack) && !gameMethod_1.gameMethod.isEmpty(GameDataCenter_1.default.sevBack.switch) && !gameMethod_1.gameMethod.isEmpty(GameDataCenter_1.default.sevBack.switch.clientLog)) {
  200. console.warn("S->C:", JSON.stringify(temp));
  201. }
  202. }
  203. else {
  204. if (!gameMethod_1.gameMethod.isEmpty(GameDataCenter_1.default.sevBack) && !gameMethod_1.gameMethod.isEmpty(GameDataCenter_1.default.sevBack.switch) && !gameMethod_1.gameMethod.isEmpty(GameDataCenter_1.default.sevBack.switch.clientLog)) {
  205. console.warn("S->C:", temp);
  206. }
  207. }
  208. //请求成功移除缓存的消息请求
  209. _this.errPostMap.Remove(data.url);
  210. _this.curPostMap.Remove(data.url);
  211. callback(temp);
  212. }
  213. // } catch (error) {
  214. // console.error("服务端回调数据处理时出现异常:", path, error)
  215. // }
  216. }
  217. if (r.readyState == 4 && NetConfig_1.default.needWait(data.url, body)) {
  218. EventMng_1.default.emit(EventConst_1.NetworkEvent.WAIT, -1);
  219. }
  220. if (r.status < 200 || r.status > 400) {
  221. // 异常情况
  222. if (isLogin) {
  223. EventMng_1.default.emit(EventConst_1.NetworkEvent.LOGIN_FAILED);
  224. }
  225. else {
  226. _this.onTimeOut(data.url);
  227. }
  228. }
  229. };
  230. // r.send(JSON.stringify({ cs: CodeMgr.jiami(body) }))
  231. r.send(JSON.stringify({ xor: gameMethod_1.gameMethod.xorEncrypt(JSON.stringify(body)), x: xor }));
  232. // r.send(JSON.stringify(body))
  233. };
  234. //淘宝云服请求
  235. HttpRequest.taoBaoCloudRequest = function (data, body, callback, isLogin) {
  236. if (callback === void 0) { callback = function () { }; }
  237. if (isLogin === void 0) { isLogin = false; }
  238. var path = data.url + "?uuid=" + GameDataCenter_1.default.user.uuid +
  239. "&token=" + GameDataCenter_1.default.user.token +
  240. "&version=" + Config_1.default.appVersion +
  241. "&time=" + GameDataCenter_1.default.time.sevTime;
  242. var self = this;
  243. function taoBaoCloud() {
  244. return __awaiter(this, void 0, void 0, function () {
  245. var result, error_1, temp;
  246. return __generator(this, function (_a) {
  247. switch (_a.label) {
  248. case 0:
  249. _a.trys.push([0, 2, , 3]);
  250. return [4 /*yield*/, window['cloud'].application.httpRequest({
  251. //不需要完整域名,只需要接口访问路径即可
  252. 'path': path,
  253. 'method': 'POST',
  254. 'headers': { "Content-Type": "application/json" },
  255. 'params': {},
  256. 'body': { xor: gameMethod_1.gameMethod.xorEncrypt(JSON.stringify(body)) },
  257. //cloudAppId 云应用的Id
  258. 'exts': {
  259. "cloudAppId": "55088",
  260. "timeout": 4000,
  261. //空应用调用需要填写该字段,包括协议头以及端口号(可省略),支持http、https
  262. "domain": gameCfg_1.default.packageInfo.getItem(Config_1.default.pid).wayhttp
  263. }
  264. })];
  265. case 1:
  266. result = _a.sent();
  267. return [3 /*break*/, 3];
  268. case 2:
  269. error_1 = _a.sent();
  270. console.log(error_1);
  271. return [3 /*break*/, 3];
  272. case 3:
  273. temp = {};
  274. try {
  275. // temp = JSON.parse(result) // gameMethod.jiemi(r.response)
  276. temp = JSON.parse(gameMethod_1.gameMethod.xorEncrypt(result));
  277. }
  278. catch (error) {
  279. EventMng_1.default.emit(EventConst_1.NetworkEvent.ON_EXCEPTION);
  280. console.error("解析回调数据失败:", result);
  281. // self.showErrDialog(data.url, data.uuid, data.version, JSON.stringify(body), result == null ? "null" : result)
  282. }
  283. try {
  284. if (temp && Object.keys(temp).length > 0) {
  285. if (CC_JSB) {
  286. if (!gameMethod_1.gameMethod.isEmpty(GameDataCenter_1.default.sevBack) && !gameMethod_1.gameMethod.isEmpty(GameDataCenter_1.default.sevBack.switch) && !gameMethod_1.gameMethod.isEmpty(GameDataCenter_1.default.sevBack.switch.clientLog)) {
  287. console.warn("S->C:", JSON.stringify(temp));
  288. }
  289. }
  290. else {
  291. if (!gameMethod_1.gameMethod.isEmpty(GameDataCenter_1.default.sevBack) && !gameMethod_1.gameMethod.isEmpty(GameDataCenter_1.default.sevBack.switch) && !gameMethod_1.gameMethod.isEmpty(GameDataCenter_1.default.sevBack.switch.clientLog)) {
  292. console.warn("S->C:", temp);
  293. }
  294. }
  295. //请求成功移除缓存的消息请求
  296. self.errPostMap.Remove(data.url);
  297. self.curPostMap.Remove(data.url);
  298. callback(temp);
  299. }
  300. }
  301. catch (error) {
  302. console.error("服务端回调数据处理时出现异常:", error);
  303. }
  304. if (NetConfig_1.default.needWait(data.url, body)) {
  305. EventMng_1.default.emit(EventConst_1.NetworkEvent.WAIT, -1);
  306. }
  307. return [2 /*return*/];
  308. }
  309. });
  310. });
  311. }
  312. this.errCount = 0;
  313. var delayTime = new Date().getTime();
  314. taoBaoCloud().then(function (res) {
  315. var _a, _b;
  316. if (!gameMethod_1.gameMethod.isEmpty((_b = (_a = GameDataCenter_1.default.sevBack) === null || _a === void 0 ? void 0 : _a.switch) === null || _b === void 0 ? void 0 : _b.clientLog)) {
  317. console.log("net delay time == " + (new Date().getTime() - delayTime));
  318. }
  319. });
  320. };
  321. // 发生服务器错误时,提示重试
  322. HttpRequest.onError = function (url) {
  323. var _this = this;
  324. var dialogParam = {
  325. content: I18nUtil_1.I18n.getI18nText("http_error", url),
  326. cbConfirm: function () {
  327. _this.errCount = 0;
  328. GameController_1.default.clear();
  329. cc.game.restart();
  330. },
  331. txtConfirm: I18nUtil_1.I18n.getI18nText("http_overtime_confirm_1"),
  332. onlyConfirm: true
  333. };
  334. UIHelp_1.default.ShowSystemDialog(dialogParam);
  335. };
  336. // 发生服务器错误时,提示重试
  337. HttpRequest.onTimeOut = function (url) {
  338. var _this = this;
  339. this.errCount++;
  340. if (this.errCount > 3) {
  341. // 超过三次重连失败,提示退出游戏
  342. GameController_1.default.network.stopRequest = true;
  343. var dialogParam = {
  344. content: I18nUtil_1.I18n.getI18nText("http_error", url),
  345. cbConfirm: function () {
  346. _this.errCount = 0;
  347. GameController_1.default.clear();
  348. cc.game.restart();
  349. },
  350. txtConfirm: I18nUtil_1.I18n.getI18nText("http_overtime_confirm_1"),
  351. onlyConfirm: true
  352. };
  353. UIHelp_1.default.ShowSystemDialog(dialogParam);
  354. }
  355. else {
  356. // 提示网络错误并引导重连
  357. var dialogParam = {
  358. content: I18nUtil_1.I18n.getI18nText("http_overtime"),
  359. cbConfirm: function () {
  360. GameDataCenter_1.default.user.sendPlayerReconnect(function () {
  361. GameController_1.default.network.stopRequest = false;
  362. //重连成功,重新发送失败请求
  363. _this.errPostMap.Foreach(function (key, value) {
  364. console.log("\u91CD\u65B0\u53D1\u9001:" + key);
  365. GameController_1.default.network.send(value.url, value.body, value.cb1, value.cb2, value.deal);
  366. });
  367. _this.errPostMap.Clear();
  368. _this.curPostMap.Clear();
  369. GameController_1.default.network.RemoveTimers();
  370. });
  371. },
  372. txtConfirm: I18nUtil_1.I18n.getI18nText("http_overtime_confirm_2"),
  373. onlyConfirm: true
  374. };
  375. UIHelp_1.default.ShowSystemDialog(dialogParam);
  376. }
  377. };
  378. HttpRequest.showErrDialog = function (url, uuid, version, body, response) {
  379. UIHelp_1.default.ShowDialog({
  380. content: "回调数据丢失,请将此界面截图给开发者\n"
  381. + ("url:" + url + " uuid:" + uuid + " version:" + version + "\n")
  382. + "body:" + JSON.stringify(body) + "\n"
  383. + ("response:" + response.slice(0, 200))
  384. });
  385. };
  386. HttpRequest.isJiamiPlatform = function () {
  387. return !cc.sys.isNative && cc.sys.platform != cc.sys.VIVO_GAME && cc.sys.platform != cc.sys.XIAOMI_GAME && cc.sys.platform != cc.sys.OPPO_GAME;
  388. };
  389. // 网络请求所需时间
  390. HttpRequest.netMs = 0;
  391. // 网络请求最长时间(超时时间)
  392. HttpRequest.timeoutMs = 15000;
  393. // 请求失败计数
  394. HttpRequest.errCount = 0;
  395. //请求失败的接口
  396. HttpRequest.errPostMap = new StringMap_1.StringMap();
  397. //当前请求的接口
  398. HttpRequest.curPostMap = new StringMap_1.StringMap();
  399. return HttpRequest;
  400. }());
  401. exports.default = HttpRequest;
  402. cc._RF.pop();
  403. }
  404. if (nodeEnv) {
  405. __define(__module.exports, __require, __module);
  406. }
  407. else {
  408. __quick_compile_project__.registerModuleFunc(__filename, function () {
  409. __define(__module.exports, __require, __module);
  410. });
  411. }
  412. })();
  413. //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbImFzc2V0cy9zY3JpcHQvbmV0d29yay9IdHRwUmVxdWVzdC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQUNBLHNEQUFvRDtBQUNwRCw2Q0FBdUM7QUFDdkMsbURBQWlEO0FBRWpELG9DQUE4QjtBQUM5Qix1REFBa0U7QUFDbEUseURBQW1EO0FBQ25ELG9EQUE4QztBQUM5Qyw2Q0FBeUQ7QUFDekQsZ0RBQTBDO0FBQzFDLDhDQUF3QztBQUN4Qyx5Q0FBbUM7QUFZbkM7SUFBQTtJQXNUQSxDQUFDO0lBM1NVLGVBQUcsR0FBVixVQUFXLElBQVksRUFBRSxRQUE4QjtRQUE5Qix5QkFBQSxFQUFBLHlCQUE2QixDQUFDO1FBQ25ELElBQUksT0FBTyxHQUFHLElBQUksQ0FBQyxlQUFlLEVBQUUsQ0FBQztRQUNyQyxJQUFJLENBQUMsR0FBRyxJQUFJLGNBQWMsRUFBRSxDQUFBO1FBQzVCLENBQUMsQ0FBQyxJQUFJLENBQUMsS0FBSyxFQUFFLElBQUksSUFBRyxTQUFNLE9BQU8sQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUUsQ0FBQSxFQUFFLElBQUksQ0FBQyxDQUFBO1FBQ25ELENBQUMsQ0FBQyxPQUFPLEdBQUcsSUFBSSxDQUFDLFNBQVMsQ0FBQTtRQUMxQixDQUFDLENBQUMsT0FBTyxHQUFHO1lBQ1IsT0FBTyxDQUFDLEdBQUcsQ0FBQyxXQUFXLEVBQUUsSUFBSSxDQUFDLENBQUE7WUFDOUIsUUFBUSxDQUFDLEVBQUUsQ0FBQyxDQUFBO1FBQ2hCLENBQUMsQ0FBQTtRQUNELENBQUMsQ0FBQyxTQUFTLEdBQUc7WUFDVixPQUFPLENBQUMsR0FBRyxDQUFDLFVBQVUsRUFBRSxJQUFJLENBQUMsQ0FBQTtZQUM3QixRQUFRLENBQUMsRUFBRSxDQUFDLENBQUE7UUFDaEIsQ0FBQyxDQUFBO1FBQ0QsQ0FBQyxDQUFDLFNBQVMsR0FBRztZ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LEdBQUcsQ0FBQyxRQUFRLElBQUksRUFBRSxDQUFDLEdBQUcsQ0FBQyxTQUFTLElBQUksRUFBRSxDQUFDLEdBQUcsQ0FBQyxRQUFRLElBQUksRUFBRSxDQUFDLEdBQUcsQ0FBQyxXQUFXLElBQUksRUFBRSxDQUFDLEdBQUcsQ0FBQyxRQUFRLElBQUksRUFBRSxDQUFDLEdBQUcsQ0FBQyxTQUFTLENBQUM7SUFDbkosQ0FBQztJQXBURCxXQUFXO0lBQ0osaUJBQUssR0FBVyxDQUFDLENBQUE7SUFDeEIsaUJBQWlCO0lBQ1YscUJBQVMsR0FBVyxLQUFLLENBQUE7SUFDaEMsU0FBUztJQUNGLG9CQUFRLEdBQVcsQ0FBQyxDQUFBO0lBQzNCLFNBQVM7SUFDRixzQkFBVSxHQUF5QixJQUFJLHFCQUFTLEVBQWEsQ0FBQztJQUNyRSxTQUFTO0lBQ0Ysc0JBQVUsR0FBeUIsSUFBSSxxQkFBUyxFQUFhLENBQUM7SUE0U3pFLGtCQUFDO0NBdFRELEFBc1RDLElBQUE7a0JBdFRvQixXQUFXIiwiZmlsZSI6IiIsInNvdXJjZVJvb3QiOiIvIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IENvZGVNZ3IgZnJvbSBcIi4uLy4uL3NjcmlwdE1haW4vQ29kZU1nclwiXG5pbXBvcnQgeyBTdHJpbmdNYXAgfSBmcm9tIFwiLi4vQ29sbGVjdGlvbnMvU3RyaW5nTWFwXCJcbmltcG9ydCBHYW1lY2ZnIGZyb20gXCIuLi9jb21tb24vZ2FtZUNmZ1wiXG5pbXBvcnQgeyBnYW1lTWV0aG9kIH0gZnJvbSBcIi4uL2NvbW1vbi9nYW1lTWV0aG9kXCJcbmltcG9ydCB7IFNldkJhY2sgfSBmcm9tIFwiLi4vY29tbW9uL1h5c1wiXG5pbXBvcnQgQ29uZmlnIGZyb20gXCIuLi9Db25maWdcIlxuaW1wb3J0IHsgR2FtZUV2ZW50LCBOZXR3b3JrRXZlbnQgfSBmcm9tIFwiLi4vZGF0YS9jb25zdC9FdmVudENvbnN0XCJcbmltcG9ydCBHYW1lRGF0YUNlbnRlciBmcm9tIFwiLi4vZGF0YS9HYW1lRGF0YUNlbnRlclwiXG5pbXBvcnQgR2FtZUNvbnRyb2xsZXIgZnJvbSBcIi4uL0dhbWVDb250cm9sbGVyXCJcbmltcG9ydCBVSUhlbHAsIHsgRGlhbG9nUGFyYW1zIH0gZnJvbSBcIi4uL2xvZ2ljL3VpL1VJSGVscFwiXG5pbXBvcnQgRXZlbnRNbmcgZnJvbSBcIi4uL21hbmFnZXIvRXZlbnRNbmdcIlxuaW1wb3J0IHsgSTE4biB9IGZyb20gXCIuLi91dGlscy9JMThuVXRpbFwiXG5pbXBvcnQgTmV0Q29uZmlnIGZyb20gXCIuL05ldENvbmZpZ1wiXG5cbmV4cG9ydCBpbnRlcmZhY2UgUE9TVF9EQVRBIHtcbiAgICBjbWRJZDogbnVtYmVyXG4gICAgdXJsOiBzdHJpbmcsXG4gICAgYm9keTogT2JqZWN0LFxuICAgIGNiMT86IChzZXY6IFNldkJhY2spID0+IHZvaWQsXG4gICAgY2IyPzogKHNldjogU2V2QmFjaykgPT4gdm9pZCxcbiAgICBkZWFsOiBudW1iZXJcbiAgICBwb3N0VGltZT86IG51bWJlclxufVxuXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBIdHRwUmVxdWVzdCB7XG4gICAgLy8g572R57uc6K+35rGC5omA6ZyA5pe26Ze0XG4gICAgc3RhdGljIG5ldE1zOiBudW1iZXIgPSAwXG4gICAgLy8g572R57uc6K+35rGC5pyA6ZW/5pe26Ze0KOi2heaXtuaXtumXtClcbiAgICBzdGF0aWMgdGltZW91dE1zOiBudW1iZXIgPSAxNTAwMFxuICAgIC8vIOivt+axguWksei0peiuoeaVsFxuICAgIHN0YXRpYyBlcnJDb3VudDogbnVtYmVyID0gMFxuICAgIC8v6K+35rGC5aSx6LSl55qE5o6l5Y+jXG4gICAgc3RhdGljIGVyclBvc3RNYXA6IFN0cmluZ01hcDxQT1NUX0RBVEE+ID0gbmV3IFN0cmluZ01hcDxQT1NUX0RBVEE+KCk7XG4gICAgLy/lvZPliY3or7fmsYLnmoTmjqXlj6NcbiAgICBzdGF0aWMgY3VyUG9zdE1hcDogU3RyaW5nTWFwPFBPU1RfREFUQT4gPSBuZXcgU3RyaW5nTWFwPFBPU1RfREFUQT4oKTtcbiAgICBzdGF0aWMgR0VUKHBhdGg6IHN0cmluZywgY2FsbGJhY2s6IEZ1bmN0aW9uID0gKCkgPT4geyB9KSB7XG4gICAgICAgIGxldCBpc0ppYW1pID0gdGhpcy5pc0ppYW1pUGxhdGZvcm0oKTtcbiAgICAgICAgbGV0IHIgPSBuZXcgWE1MSHR0cFJlcXVlc3QoKVxuICAgICAgICByLm9wZW4oXCJHRVRcIiwgcGF0aCArIGA/eD0ke2lzSmlhbWkgPyAxIDogMH1gLCB0cnVlKVxuICAgICAgICByLnRpbWVvdXQgPSB0aGlzLnRpbWVvdXRNc1xuICAgICAgICByLm9uZXJyb3IgPSAoKSA9PiB7XG4gICAgICAgICAgICBjb25zb2xlLmxvZyhcIuWPkeeUn+mUmeivryx1cmw9XCIsIHBhdGgpXG4gICAgICAgICAgICBjYWxsYmFjayh7fSlcbiAgICAgICAgfVxuICAgICAgICByLm9udGltZW91dCA9ICgpID0+IHtcbiAgICAgICAgICAgIGNvbnNvbGUubG9nKFwi6LaF5pe25LqGLHVybD1cIiwgcGF0aClcbiAgICAgICAgICAgIGNhbGxiYWNrKHt9KVxuICAgICAgICB9XG4gICAgICAgIHIub25sb2FkZW5kID0gZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgbGV0IHRlbXAgPSB7fVxuICAgICAgICAgICAgaWYgKHIuc3RhdHVzID49IDIwMCAmJiByLnN0YXR1cyA8PSA0MDAgJiYgci5yZWFkeVN0YXRlID09IDQpIHtcbiAgICAgICAgICAgICAgICBsZXQgdHh0ID0gZ2FtZU1ldGhvZC54b3JFbmNyeXB0KHIucmVzcG9uc2UsIGlzSmlhbWkpO1xuICAgICAgICAgICAgICAgIHRlbXAgPSBKU09OLnBhcnNlKHR4dClcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGNhbGxiYWNrKHRlbXApXG4gICAgICAgIH1cbiAgICAgICAgci5zZW5kKClcbiAgICB9XG4gICAgLy8g5Y+q5Y+R6YCBLOaXoOmcgOWkhOeQhuWbnuiwg1xuICAgIHN0YXRpYyBQT1NUX1NJTVBMRSh1cmw6IHN0cmluZywgYm9keTogT2JqZWN0KSB7XG4gICAgICAgIGxldCByID0gbmV3IFhNTEh0dHBSZXF1ZXN0KClcbiAgICAgICAgci5vcGVuKFwiUE9TVFwiLCB1cmwsIHRydWUpXG4gICAgICAgIHIuc2V0UmVxdWVzdEhlYWRlcihcIkNvbnRlbnQtVHlwZVwiLCBcImFwcGxpY2F0aW9uL2pzb25cIilcbiAgICAgICAgci5zZW5kKEpTT04uc3RyaW5naWZ5KGJvZHkpKVxuICAgIH1cbiAgICAvLyDlj5HpgIHkuJrliqHlpJYs6ZyA5aSE55CG5Zue6LCDXG4gICAgc3RhdGljIFBPU1RfU0lNUExFXzIodXJsOiBzdHJpbmcsIGJvZHk6IE9iamVjdCwgY2FsbGJhY2s6IEZ1bmN0aW9uID0gKCkgPT4geyB9KSB7XG4gICAgICAgIGxldCByID0gbmV3IFhNTEh0dHBSZXF1ZXN0KClcbiAgICAgICAgci5vcGVuKFwiUE9TVFwiLCB1cmwsIHRydWUpXG4gICAgICAgIHIuc2V0UmVxdWVzdEhlYWRlcihcIkNvbnRlbnQtVHlwZVwiLCBcImFwcGxpY2F0aW9uL2pzb25cIilcbiAgICAgICAgci5vbnJlYWR5c3RhdGVjaGFuZ2UgPSAoKSA9PiB7XG4gICAgICAgICAgICBpZiAoci5zdGF0dXMgPj0gMjAwICYmIHIuc3RhdHVzIDw9IDQwMCAmJiByLnJlYWR5U3RhdGUgPT0gNCkge1xuICAgICAgICAgICAgICAgIGNhbGxiYWNrKHIucmVzcG9uc2UpXG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoXCJQT1NUIEZhaWxlOlwiLCByLnN0YXR1cylcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByLnNlbmQoSlNPTi5zdHJpbmdpZnkoYm9keSkpXG4gICAgfVxuICAgIC8vIOS4muWKoemAu+i+keWNj+iuruiwg+eUqOaOpeWPo1xuICAgIHN0YXRpYyBQT1NUKHBhdGg6IHN0cmluZywgZGF0YTogeyBba2V5OiBzdHJpbmddOiBzdHJpbmcgfSwgYm9keTogT2JqZWN0LCBjYWxsYmFjazogRnVuY3Rpb24gPSAoKSA9PiB7IH0sIGlzTG9naW46IGJvb2xlYW4gPSBmYWxzZSkge1xuICAgICAgICBib2R5ID0gYm9keSB8fCB7fVxuICAgICAgICBpZiAoQ0NfSlNCKSB7XG4gICAgICAgICAgICBpZiAoIWdhbWVNZXRob2QuaXNFbXB0eShHYW1lRGF0YUNlbnRlci5zZXZCYWNrKSAmJiAhZ2FtZU1ldGhvZC5pc0VtcHR5KEdhbWVEYXRhQ2VudGVyLnNldkJhY2suc3dpdGNoKSAmJiAhZ2FtZU1ldGhvZC5pc0VtcHR5KEdhbWVEYXRhQ2VudGVyLnNldkJhY2suc3dpdGNoLmNsaWVudExvZykpIHtcbiAgICAgICAgICAgICAgICBjb25zb2xlLndhcm4oXCJDLT5TOlwiLCBwYXRoLCBKU09OLnN0cmluZ2lmeShib2R5KSlcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGlmICghZ2FtZU1ldGhvZC5pc0VtcHR5KEdhbWVEYXRhQ2VudGVyLnNldkJhY2spICYmICFnYW1lTWV0aG9kLmlzRW1wdHkoR2FtZURhdGFDZW50ZXIuc2V2QmFjay5zd2l0Y2gpICYmICFnYW1lTWV0aG9kLmlzRW1wdHkoR2FtZURhdGFDZW50ZXIuc2V2QmFjay5zd2l0Y2guY2xpZW50TG9nKSkge1xuICAgICAgICAgICAgICAgIGNvbnNvbGUud2FybihcIkMtPlM6XCIsIHBhdGgsIGJvZHkpXG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgbGV0IGRlbGF5ID0gbmV3IERhdGUoKS5nZXRUaW1lKClcbiAgICAgICAgaWYgKE5ldENvbmZpZy5uZWVkV2FpdChkYXRhLnVybCwgYm9keSkpIHtcbiAgICAgICAgICAgIEV2ZW50TW5nLmVtaXQoTmV0d29ya0V2ZW50LldBSVQsIDEpXG4gICAgICAgIH1cbiAgICAgICAgLy/mt5jlrp3pnIDopoHpgJrov4fkupHmnI3liqHosIPnlKjmnI3liqHlmahcbiAgICAgICAgaWYgKGNjLnN5cy5wbGF0Zm9ybSA9PSBjYy5zeXMuVEFPQkFPX01JTklHQU1FKSB7XG4gICAgICAgICAgICB0aGlzLnRhb0Jhb0Nsb3VkUmVxdWVzdChkYXRhLCBib2R5LCBjYWxsYmFjaywgaXNMb2dpbilcbiAgICAgICAgICAgIHJldHVyblxuICAgICAgICB9XG4gICAgICAgIGxldCByID0gbmV3IFhNTEh0dHBSZXF1ZXN0KClcbiAgICAgICAgci5vcGVuKFwiUE9TVFwiLCBwYXRoLCB0cnVlKVxuICAgICAgICByLnRpbWVvdXQgPSB0aGlzLnRpbWVvdXRNc1xuICAgICAgICByLnNldFJlcXVlc3RIZWFkZXIoXCJDb250ZW50LVR5cGVcIiwgXCJhcHBsaWNhdGlvbi9qc29uXCIpXG4gICAgICAgIGxldCB4b3I6IG51bWJlciA9IHRoaXMuaXNKaWFtaVBsYXRmb3JtKCkgPyAxIDogMDsvL+WOn+eUn+err+aOpeaUtuWIsOWKoOWvhuaVsOaNruS8muS4jeWFqO+8jOaJgOS7peWwseS4jeWKoOWvhuS6hlxuICAgICAgICAvLyByLm9uZXJyb3IgPSAoKSA9PiB7XG4gICAgICAgIC8vICAgICAvLyBjb25zb2xlLndhcm4oXCI9PT09PT09aHR0cHMgb25lcnJvclwiLCByLnN0YXR1cywgci5yZWFkeVN0YXRlKVxuICAgICAgICAvLyAgICAgY2FsbGJhY2soeyB0eXBlOiAwIH0pXG4gICAgICAgIC8vICAgICBpZiAoaXNMb2dpbikge1xuICAgICAgICAvLyAgICAgICAgIEV2ZW50TW5nLmVtaXQoTmV0d29ya0V2ZW50LkxPR0lOX0ZBSUxFRClcbiAgICAgICAgLy8gICAgICAgICByZXR1cm5cbiAgICAgICAgLy8gICAgIH1cbiAgICAgICAgLy8gICAgIHRoaXMub25FcnJvcihkYXRhLnVybClcbiAgICAgICAgLy8gfVxuICAgICAgICByLm9uZXJyb3IgPSByLm9udGltZW91dCA9ICgpID0+IHtcbiAgICAgICAgICAgIC8vIGNvbnNvbGUud2FybihcIj09PT09PT1odHRwcyBvbnRpbWVvdXRcIiwgci5zdGF0dXMsIHIucmVhZHlTdGF0ZSlcbiAgICAgICAgICAgIHRoaXMubmV0TXMgPSByLnRpbWVvdXRcbiAgICAgICAgICAgIC8vIOi2heaXtueahOaXtuWAmSzlhYjmiop3YWl0aW5n5YWz5o6JXG4gICAgICAgICAgICBpZiAoTmV0Q29uZmlnLm5lZWRXYWl0KGRhdGEudXJsLCBib2R5KSkge1xuICAgICAgICAgICAgICAgIEV2ZW50TW5nLmVtaXQoTmV0d29ya0V2ZW50LldBSVRfQ0xPU0UpXG4gICAgICAgICAgICB9XG4gICAgICAgICAgICAvL+ivt+axguWksei0peaXtuWFs+mXreW8uuivt+axgumBrue9qVxuICAgICAgICAgICAgRXZlbnRNbmcuZW1pdChOZXR3b3JrRXZlbnQuTkVUV0FJVF9NQVNLLCBmYWxzZSlcbiAgICAgICAgICAgIC8vIOWmguaenOaYr+eZu+W9lei/h+eoi+S4reWHuumUmSznibnmrorlpITnkIZcbiAgICAgICAgICAgIGlmIChpc0xvZ2luKSB7XG4gICAgICAgICAgICAgICAgRXZlbnRNbmcuZW1pdChOZXR3b3JrRXZlbnQuTE9HSU5fRkFJTEVEKVxuICAgICAgICAgICAgICAgIHJldHVyblxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdGhpcy5vblRpbWVPdXQoZGF0YS51cmwpXG4gICAgICAgIH1cbiAgICAgICAgci5vbnJlYWR5c3RhdGVjaGFuZ2UgPSAoKSA9PiB7XG4gICAgICAgICAgICAvLyBjb25zb2xlLmxvZyhcIj09PT09PT1odHRwcyBvbnJlYWR5c3RhdGVjaGFuZ2VcIiwgci5zdGF0dXMsIHIucmVhZHlTdGF0ZSlcbiAgICAgICAgICAgIGlmIChyLnJlYWR5U3RhdGUgPT0gNCkge1xuICAgICAgICAgICAgICAgIHRoaXMubmV0TXMgPSBuZXcgRGF0ZSgpLmdldFRpbWUoKSAtIGRlbGF5XG4gICAgICAgICAgICAgICAgaWYgKHRoaXMubmV0TXMgPiAxMDAwKSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnNvbGUud2FybihcIuacjeWKoeWZqOWbnuiwg+aXtumXtOi2hei/hzHnp5I6XCIsIHBhdGgsIEpTT04uc3RyaW5naWZ5KGJvZHkpKVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGxldCB0ZW1wID0ge31cbiAgICAgICAgICAgIGlmIChyLnN0YXR1cyA+PSAyMDAgJiYgci5zdGF0dXMgPD0gNDAwICYmIHIucmVhZHlTdGF0ZSA9PSA0KSB7XG4gICAgICAgICAgICAgICAgdGhpcy5lcnJDb3VudCA9IDBcbiAgICAgICAgICAgICAgICBpZiAoci5yZXNwb25zZSA9PSBudWxsIHx8IHIucmVzcG9uc2UgPT0gXCJcIikge1xuICAgICAgICAgICAgICAgICAgICBFdmVudE1uZy5lbWl0KE5ldHdvcmtFdmVudC5PTl9FWENFUFRJT04pXG4gICAgICAgICAgICAgICAgICAgIHRoaXMuc2hvd0VyckRpYWxvZyhkYXRhLnVybCwgZGF0YS51dWlkLCBkYXRhLnZlcnNpb24sIEpTT04uc3RyaW5naWZ5KGJvZHkpLCByLnJlc3BvbnNlID09IG51bGwgPyBcIm51bGxcIiA6IHIucmVzcG9uc2UpXG4gICAgICAgICAgICAgICAgICAgIHJldHVyblxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICAgICAgICAvLyB0ZW1wID0gSlNPTi5wYXJzZShyLnJlc3BvbnNlKSAvLyBnYW1lTWV0aG9kLmppZW1pKHIucmVzcG9uc2UpXG4gICAgICAgICAgICAgICAgICAgIC8vIGxldCBqaWVtaVRpbWUgPSBuZXcgRGF0ZSgpLmdldFRpbWUoKVxuICAgICAgICAgICAgICAgICAgICBsZXQgdHh0ID0gZ2FtZU1ldGhvZC54b3JFbmNyeXB0KHIucmVzcG9uc2UsIHhvciA9PSAxKTtcbiAgICAgICAgICAgICAgICAgICAgdGVtcCA9IEpTT04ucGFyc2UodHh0KVxuICAgICAgICAgICAgICAgICAgICAvLyBjb25zb2xlLmxvZyhcIua2iOaBr+ino+WvhuiAl+aXtu+8mlwiLCBuZXcgRGF0ZSgpLmdldFRpbWUoKSAtIGppZW1pVGltZSlcbiAgICAgICAgICAgICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICAgICAgICAgICAgICBFdmVudE1uZy5lbWl0KE5ldHdvcmtFdmVudC5PTl9FWENFUFRJT04pXG4gICAgICAgICAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoXCLop6PmnpDlm57osIPmlbDmja7lpLHotKU6XCIsIHIucmVzcG9uc2UpXG4gICAgICAgICAgICAgICAgICAgIHRoaXMuc2hvd0VyckRpYWxvZyhkYXRhLnVybCwgZGF0YS51dWlkLCBkYXRhLnZlcnNpb24sIEpTT04uc3RyaW5naWZ5KGJvZHkpLCByLnJlc3BvbnNlID09IG51bGwgPyBcIm51bGxcIiA6IHIucmVzcG9uc2UpXG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgLy8gdHJ5IHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKHRlbXAgJiYgT2JqZWN0LmtleXModGVtcCkubGVuZ3RoID4gMCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKENDX0pTQikge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICghZ2FtZU1ldGhvZC5pc0VtcHR5KEdhbWVEYXRhQ2VudGVyLnNldkJhY2spICYmICFnYW1lTWV0aG9kLmlzRW1wdHkoR2FtZURhdGFDZW50ZXIuc2V2QmFjay5zd2l0Y2gpICYmICFnYW1lTWV0aG9kLmlzRW1wdHkoR2FtZURhdGFDZW50ZXIuc2V2QmFjay5zd2l0Y2guY2xpZW50TG9nKSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zb2xlLndhcm4oXCJTLT5DOlwiLCBKU09OLnN0cmluZ2lmeSh0ZW1wKSlcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICghZ2FtZU1ldGhvZC5pc0VtcHR5KEdhbWVEYXRhQ2VudGVyLnNldkJhY2spICYmICFnYW1lTWV0aG9kLmlzRW1wdHkoR2FtZURhdGFDZW50ZXIuc2V2QmFjay5zd2l0Y2gpICYmICFnYW1lTWV0aG9kLmlzRW1wdHkoR2FtZURhdGFDZW50ZXIuc2V2QmFjay5zd2l0Y2guY2xpZW50TG9nKSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zb2xlLndhcm4oXCJTLT5DOlwiLCB0ZW1wKVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgIC8v6K+35rGC5oiQ5Yqf56e76Zmk57yT5a2Y55qE5raI5oGv6K+35rGCXG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmVyclBvc3RNYXAuUmVtb3ZlKGRhdGEudXJsKVxuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5jdXJQb3N0TWFwLlJlbW92ZShkYXRhLnVybClcbiAgICAgICAgICAgICAgICAgICAgICAgIGNhbGxiYWNrKHRlbXApXG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAvLyB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICAgICAgICAgIC8vICAgICBjb25zb2xlLmVycm9yKFwi5pyN5Yqh56uv5Zue6LCD5pWw5o2u5aSE55CG5pe25Ye6546w5byC5bi4OlwiLCBwYXRoLCBlcnJvcilcbiAgICAgICAgICAgICAgICAvLyB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAoci5yZWFkeVN0YXRlID09IDQgJiYgTmV0Q29uZmlnLm5lZWRXYWl0KGRhdGEudXJsLCBib2R5KSkge1xuICAgICAgICAgICAgICAgIEV2ZW50TW5nLmVtaXQoTmV0d29ya0V2ZW50LldBSVQsIC0xKVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKHIuc3RhdHVzIDwgMjAwIHx8IHIuc3RhdHVzID4gNDAwKSB7XG4gICAgICAgICAgICAgICAgLy8g5byC5bi45oOF5Ya1XG4gICAgICAgICAgICAgICAgaWYgKGlzTG9naW4pIHtcbiAgICAgICAgICAgICAgICAgICAgRXZlbnRNbmcuZW1pdChOZXR3b3JrRXZlbnQuTE9HSU5fRkFJTEVEKVxuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMub25UaW1lT3V0KGRhdGEudXJsKVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfTtcblxuICAgICAgICAvLyByLnNlbmQoSlNPTi5zdHJpbmdpZnkoeyBjczogQ29kZU1nci5qaWFtaShib2R5KSB9KSlcbiAgICAgICAgci5zZW5kKEpTT04uc3RyaW5naWZ5KHsgeG9yOiBnYW1lTWV0aG9kLnhvckVuY3J5cHQoSlNPTi5zdHJpbmdpZnkoYm9keSkpLCB4OiB4b3IgfSkpXG4gICAgICAgIC8vIHIuc2VuZChKU09OLnN0cmluZ2lmeShib2R5KSlcbiAgICB9XG5cbiAgICAvL+a3mOWuneS6keacjeivt+axglxuICAgIHN0YXRpYyB0YW9CYW9DbG91ZFJlcXVlc3QoZGF0YTogeyBba2V5OiBzdHJpbmddOiBzdHJpbmcgfSwgYm9keTogT2JqZWN0LCBjYWxsYmFjazogRnVuY3Rpb24gPSAoKSA9PiB7IH0sIGlzTG9naW46IGJvb2xlYW4gPSBmYWxzZSkge1xuICAgICAgICBsZXQgcGF0aCA9IGRhdGEudXJsICsgXCI/dXVpZD1cIiArIEdhbWVEYXRhQ2VudGVyLnVzZXIudXVpZCArXG4gICAgICAgICAgICBcIiZ0b2tlbj1cIiArIEdhbWVEYXRhQ2VudGVyLnVzZXIudG9rZW4gK1xuICAgICAgICAgICAgXCImdmVyc2lvbj1cIiArIENvbmZpZy5hcHBWZXJzaW9uICtcbiAgICAgICAgICAgIFwiJnRpbWU9XCIgKyBHYW1lRGF0YUNlbnRlci50aW1lLnNldlRpbWVcbiAgICAgICAgbGV0IHNlbGYgPSB0aGlzO1xuICAgICAgICBhc3luYyBmdW5jdGlvbiB0YW9CYW9DbG91ZCgpIHtcbiAgICAgICAgICAgIGxldCByZXN1bHRcbiAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgICAgcmVzdWx0ID0gYXdhaXQgd2luZG93WydjbG91ZCddLmFwcGxpY2F0aW9uLmh0dHBSZXF1ZXN0KHtcbiAgICAgICAgICAgICAgICAgICAgLy/kuI3pnIDopoHlrozmlbTln5/lkI3vvIzlj6rpnIDopoHmjqXlj6Porr/pl67ot6/lvoTljbPlj69cbiAgICAgICAgICAgICAgICAgICAgJ3BhdGgnOiBwYXRoLFxuICAgICAgICAgICAgICAgICAgICAnbWV0aG9kJzogJ1BPU1QnLFxuICAgICAgICAgICAgICAgICAgICAnaGVhZGVycyc6IHsgXCJDb250ZW50LVR5cGVcIjogXCJhcHBsaWNhdGlvbi9qc29uXCIgfSxcbiAgICAgICAgICAgICAgICAgICAgJ3BhcmFtcyc6IHt9LFxuICAgICAgICAgICAgICAgICAgICAnYm9keSc6IHsgeG9yOiBnYW1lTWV0aG9kLnhvckVuY3J5cHQoSlNPTi5zdHJpbmdpZnkoYm9keSkpIH0sXG4gICAgICAgICAgICAgICAgICAgIC8vY2xvdWRBcHBJZCDkupHlupTnlKjnmoRJZFxuICAgICAgICAgICAgICAgICAgICAnZXh0cyc6IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIFwiY2xvdWRBcHBJZFwiOiBcIjU1MDg4XCIsXG4gICAgICAgICAgICAgICAgICAgICAgICBcInRpbWVvdXRcIjogNDAwMCxcbiAgICAgICAgICAgICAgICAgICAgICAgIC8v56m65bqU55So6LCD55So6ZyA6KaB5aGr5YaZ6K+l5a2X5q6177yM5YyF5ous5Y2P6K6u5aS05Lul5Y+K56uv5Y+j5Y+377yI5Y+v55yB55Wl77yJ77yM5pSv5oyBaHR0cOOAgWh0dHBzXG4gICAgICAgICAgICAgICAgICAgICAgICBcImRvbWFpblwiOiBHYW1lY2ZnLnBhY2thZ2VJbmZvLmdldEl0ZW0oQ29uZmlnLnBpZCkud2F5aHR0cFxuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICAgICAgICAgIGNvbnNvbGUubG9nKGVycm9yKVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgLy8gY29uc29sZS5sb2coXCJyZXN1bHQ6XCIsIEpTT04uc3RyaW5naWZ5KGdhbWVNZXRob2QueG9yRW5jcnlwdChyZXN1bHQpKSk7XG4gICAgICAgICAgICBsZXQgdGVtcCA9IHt9XG4gICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICAgIC8vIHRlbXAgPSBKU09OLnBhcnNlKHJlc3VsdCkgLy8gZ2FtZU1ldGhvZC5qaWVtaShyLnJlc3BvbnNlKVxuICAgICAgICAgICAgICAgIHRlbXAgPSBKU09OLnBhcnNlKGdhbWVNZXRob2QueG9yRW5jcnlwdChyZXN1bHQpKVxuICAgICAgICAgICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgICAgICAgICAgICBFdmVudE1uZy5lbWl0KE5ldHdvcmtFdmVudC5PTl9FWENFUFRJT04pXG4gICAgICAgICAgICAgICAgY29uc29sZS5lcnJvcihcIuino+aekOWbnuiwg+aVsOaNruWksei0pTpcIiwgcmVzdWx0KVxuICAgICAgICAgICAgICAgIC8vIHNlbGYuc2hvd0VyckRpYWxvZyhkYXRhLnVybCwgZGF0YS51dWlkLCBkYXRhLnZlcnNpb24sIEpTT04uc3RyaW5naWZ5KGJvZHkpLCByZXN1bHQgPT0gbnVsbCA/IFwibnVsbFwiIDogcmVzdWx0KVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICBpZiAodGVtcCAmJiBPYmplY3Qua2V5cyh0ZW1wKS5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgICAgICAgICAgIGlmIChDQ19KU0IpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmICghZ2FtZU1ldGhvZC5pc0VtcHR5KEdhbWVEYXRhQ2VudGVyLnNldkJhY2spICYmICFnYW1lTWV0aG9kLmlzRW1wdHkoR2FtZURhdGFDZW50ZXIuc2V2QmFjay5zd2l0Y2gpICYmICFnYW1lTWV0aG9kLmlzRW1wdHkoR2FtZURhdGFDZW50ZXIuc2V2QmFjay5zd2l0Y2guY2xpZW50TG9nKSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnNvbGUud2FybihcIlMtPkM6XCIsIEpTT04uc3RyaW5naWZ5KHRlbXApKVxuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCFnYW1lTWV0aG9kLmlzRW1wdHkoR2FtZURhdGFDZW50ZXIuc2V2QmFjaykgJiYgIWdhbWVNZXRob2QuaXNFbXB0eShHYW1lRGF0YUNlbnRlci5zZXZCYWNrLnN3aXRjaCkgJiYgIWdhbWVNZXRob2QuaXNFbXB0eShHYW1lRGF0YUNlbnRlci5zZXZCYWNrLnN3aXRjaC5jbGllbnRMb2cpKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc29sZS53YXJuKFwiUy0+QzpcIiwgdGVtcClcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAvL+ivt+axguaIkOWKn+enu+mZpOe8k+WtmOeahOa2iOaBr+ivt+axglxuICAgICAgICAgICAgICAgICAgICBzZWxmLmVyclBvc3RNYXAuUmVtb3ZlKGRhdGEudXJsKTtcbiAgICAgICAgICAgICAgICAgICAgc2VsZi5jdXJQb3N0TWFwLlJlbW92ZShkYXRhLnVybCk7XG4gICAgICAgICAgICAgICAgICAgIGNhbGxiYWNrKHRlbXApXG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgICAgICAgICAgICBjb25zb2xlLmVycm9yKFwi5pyN5Yqh56uv5Zue6LCD5pWw5o2u5aSE55CG5pe25Ye6546w5byC5bi4OlwiLCBlcnJvcilcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmIChOZXRDb25maWcubmVlZFdhaXQoZGF0YS51cmwsIGJvZHkpKSB7XG4gICAgICAgICAgICAgICAgRXZlbnRNbmcuZW1pdChOZXR3b3JrRXZlbnQuV0FJVCwgLTEpXG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5lcnJDb3VudCA9IDBcbiAgICAgICAgbGV0IGRlbGF5VGltZSA9IG5ldyBEYXRlKCkuZ2V0VGltZSgpXG4gICAgICAgIHRhb0Jhb0Nsb3VkKCkudGhlbihyZXMgPT4ge1xuICAgICAgICAgICAgaWYgKCFnYW1lTWV0aG9kLmlzRW1wdHkoR2FtZURhdGFDZW50ZXIuc2V2QmFjaz8uc3dpdGNoPy5jbGllbnRMb2cpKSB7XG4gICAgICAgICAgICAgICAgY29uc29sZS5sb2coXCJuZXQgZGVsYXkgdGltZSA9PSBcIiArIChuZXcgRGF0ZSgpLmdldFRpbWUoKSAtIGRlbGF5VGltZSkpXG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIC8vIOWPkeeUn+acjeWKoeWZqOmUmeivr+aXtizmj5DnpLrph43or5VcbiAgICBwcml2YXRlIHN0YXRpYyBvbkVycm9yKHVybDogc3RyaW5nKSB7XG4gICAgICAgIGxldCBkaWFsb2dQYXJhbTogRGlhbG9nUGFyYW1zID0ge1xuICAgICAgICAgICAgY29udGVudDogSTE4bi5nZXRJMThuVGV4dChcImh0dHBfZXJyb3JcIiwgdXJsKSxcbiAgICAgICAgICAgIGNiQ29uZmlybTogKCkgPT4ge1xuICAgICAgICAgICAgICAgIHRoaXMuZXJyQ291bnQgPSAwXG4gICAgICAgICAgICAgICAgR2FtZUNvbnRyb2xsZXIuY2xlYXIoKVxuICAgICAgICAgICAgICAgIGNjLmdhbWUucmVzdGFydCgpXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgdHh0Q29uZmlybTogSTE4bi5nZXRJMThuVGV4dChcImh0dHBfb3ZlcnRpbWVfY29uZmlybV8xXCIpLFxuICAgICAgICAgICAgb25seUNvbmZpcm06IHRydWVcbiAgICAgICAgfVxuICAgICAgICBVSUhlbHAuU2hvd1N5c3RlbURpYWxvZyhkaWFsb2dQYXJhbSlcbiAgICB9XG5cbiAgICAvLyDlj5HnlJ/mnI3liqHlmajplJnor6/ml7Ys5o+Q56S66YeN6K+VXG4gICAgcHJpdmF0ZSBzdGF0aWMgb25UaW1lT3V0KHVybDogc3RyaW5nKSB7XG4gICAgICAgIHRoaXMuZXJyQ291bnQrK1xuICAgICAgICBpZiAodGhpcy5lcnJDb3VudCA+IDMpIHtcbiAgICAgICAgICAgIC8vIOi2hei/h+S4ieasoemHjei/nuWksei0pSzmj5DnpLrpgIDlh7rmuLjmiI9cbiAgICAgICAgICAgIEdhbWVDb250cm9sbGVyLm5ldHdvcmsuc3RvcFJlcXVlc3QgPSB0cnVlXG4gICAgICAgICAgICBsZXQgZGlhbG9nUGFyYW06IERpYWxvZ1BhcmFtcyA9IHtcbiAgICAgICAgICAgICAgICBjb250ZW50OiBJMThuLmdldEkxOG5UZXh0KFwiaHR0cF9lcnJvclwiLCB1cmwpLFxuICAgICAgICAgICAgICAgIGNiQ29uZmlybTogKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLmVyckNvdW50ID0gMFxuICAgICAgICAgICAgICAgICAgICBHYW1lQ29udHJvbGxlci5jbGVhcigpXG4gICAgICAgICAgICAgICAgICAgIGNjLmdhbWUucmVzdGFydCgpXG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICB0eHRDb25maXJtOiBJMThuLmdldEkxOG5UZXh0KFwiaHR0cF9vdmVydGltZV9jb25maXJtXzFcIiksXG4gICAgICAgICAgICAgICAgb25seUNvbmZpcm06IHRydWVcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIFVJSGVscC5TaG93U3lzdGVtRGlhbG9nKGRpYWxvZ1BhcmFtKVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgLy8g5o+Q56S6572R57uc6ZSZ6K+v5bm25byV5a+86YeN6L+eXG4gICAgICAgICAgICBsZXQgZGlhbG9nUGFyYW06IERpYWxvZ1BhcmFtcyA9IHtcbiAgICAgICAgICAgICAgICBjb250ZW50OiBJMThuLmdldEkxOG5UZXh0KFwiaHR0cF9vdmVydGltZVwiKSxcbiAgICAgICAgICAgICAgICBjYkNvbmZpcm06ICgpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgR2FtZURhdGFDZW50ZXIudXNlci5zZW5kUGxheWVyUmVjb25uZWN0KCgpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIEdhbWVDb250cm9sbGVyLm5ldHdvcmsuc3RvcFJlcXVlc3QgPSBmYWxzZVxuICAgICAgICAgICAgICAgICAgICAgICAgLy/ph43ov57miJDlip/vvIzph43mlrDlj5HpgIHlpLHotKXor7fmsYJcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuZXJyUG9zdE1hcC5Gb3JlYWNoKChrZXk6IHN0cmluZywgdmFsdWU6IFBPU1RfREFUQSkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnNvbGUubG9nKGDph43mlrDlj5HpgIE6JHtrZXl9YClcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBHYW1lQ29udHJvbGxlci5uZXR3b3JrLnNlbmQodmFsdWUudXJsLCB2YWx1ZS5ib2R5LCB2YWx1ZS5jYjEsIHZhbHVlLmNiMiwgdmFsdWUuZGVhbClcbiAgICAgICAgICAgICAgICAgICAgICAgIH0pXG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmVyclBvc3RNYXAuQ2xlYXIoKVxuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5jdXJQb3N0TWFwLkNsZWFyKClcbiAgICAgICAgICAgICAgICAgICAgICAgIEdhbWVDb250cm9sbGVyLm5ldHdvcmsuUmVtb3ZlVGltZXJzKClcbiAgICAgICAgICAgICAgICAgICAgfSlcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgIHR4dENvbmZpcm06IEkxOG4uZ2V0STE4blRleHQoXCJodHRwX292ZXJ0aW1lX2NvbmZpcm1fMlwiKSxcbiAgICAgICAgICAgICAgICBvbmx5Q29uZmlybTogdHJ1ZVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgVUlIZWxwLlNob3dTeXN0ZW1EaWFsb2coZGlhbG9nUGFyYW0pXG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBwcml2YXRlIHN0YXRpYyBzaG93RXJyRGlhbG9nKHVybDogc3RyaW5nLCB1dWlkOiBzdHJpbmcsIHZlcnNpb246IHN0cmluZywgYm9keTogc3RyaW5nLCByZXNwb25zZTogc3RyaW5nKSB7XG4gICAgICAgIFVJSGVscC5TaG93RGlhbG9nKHtcbiAgICAgICAgICAgIGNvbnRlbnQ6IFwi5Zue6LCD5pWw5o2u5Lii5aSxLOivt+WwhuatpOeVjOmdouaIquWbvue7meW8gOWPkeiAhVxcblwiXG4gICAgICAgICAgICAgICAgKyBgdXJsOiR7dXJsfSB1dWlkOiR7dXVpZH0gdmVyc2lvbjoke3ZlcnNpb259XFxuYFxuICAgICAgICAgICAgICAgICsgYGJvZHk6YCArIEpTT04uc3RyaW5naWZ5KGJvZHkpICsgXCJcXG5cIlxuICAgICAgICAgICAgICAgICsgYHJlc3BvbnNlOiR7cmVzcG9uc2Uuc2xpY2UoMCwgMjAwKX1gXG4gICAgICAgIH0pXG4gICAgfVxuXG4gICAgc3RhdGljIGlzSmlhbWlQbGF0Zm9ybSgpOiBib29sZWFuIHsvL+S7peS4i+W5s+WPsOS4jeWKoOWvhu+8jOWboOS4uuS7peS4i+WKoOWvhuaVsOaNruS8muaOpeWPl+S4jeWFqFxuICAgICAgICByZXR1cm4gIWNjLnN5cy5pc05hdGl2ZSAmJiBjYy5zeXMucGxhdGZvcm0gIT0gY2Muc3lzLlZJVk9fR0FNRSAmJiBjYy5zeXMucGxhdGZvcm0gIT0gY2Muc3lzLlhJQU9NSV9HQU1FICYmIGNjLnN5cy5wbGF0Zm9ybSAhPSBjYy5zeXMuT1BQT19HQU1FO1xuICAgIH1cbn0iXX0=