ZGlmZiAtLWdpdCBhL3N0ZC9saXZpbmcvbGlmZS5jIGIvc3RkL2xpdmluZy9saWZlLmMKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZjNhNzJmNQotLS0gL2Rldi9udWxsCisrKyBiL3N0ZC9saXZpbmcvbGlmZS5jCkBAIC0wLDAgKzEsMTU3MiBAQAorLy8gTW9yZ2VuR3JhdWVuIE1VRGxpYgorLy8KKy8vIGxpdmluZy9saWZlLmMgLS0gbGlmZSB2YXJpYWJsZXMKKy8vCisvLyAkSWQ6IGxpZmUuYyA5NDI2IDIwMTYtMDEtMDMgMTA6MDI6NTdaIFplc3N0cmEgJAorCisvLyBsaXZpbmcgb2JqZWN0IGxpZmUgdmFyaWFibGVzCisvLworLy8gIFBfQUxJR04gICAgICAgICAtLSBhbGlnbm1lbnQgdmFsdWUKKy8vICBQX05QQyAgICAgICAgICAgLS0gaWYgbGl2aW5nIGlzIGFuIE5QQworLy8gIFBfSFAgICAgICAgICAgICAtLSBIaXRQb2ludHMKKy8vICBQX1NQICAgICAgICAgICAgLS0gU3BlbGxQb2ludHMKKy8vICBQX0FMQ09IT0wgICAgICAgLS0gdmFsdWUgb2YgaW50b3hpY2F0aW9uCisvLyAgUF9EUklOSyAgICAgICAgIC0tIHZhbHVlIG9mIHNvYWtuZXNzCisvLyAgUF9GT09EICAgICAgICAgIC0tIHZhbHVlIG9mIHN0dWZmbmVzcworLy8gIFBfWFAgICAgICAgICAgICAtLSBleHBlcmllbmNlCisvLyAgUF9QT0lTT04gICAgICAgIC0tIGxldmVsIG9mIHBvaXNvbgorLy8gIFBfQ09SUFNFICAgICAgICAtLSBjb3Jwc2Utb2JqZWN0CisvLyAgUF9ERUFGICAgICAgICAgIC0tIGlmIGxpdmluZyBpcyBkZWFmCisjcHJhZ21hIHN0cm9uZ190eXBlcyxzYXZlX3R5cGVzLHJ0dF9jaGVja3MKKyNwcmFnbWEgcmFuZ2VfY2hlY2sKKyNwcmFnbWEgbm9fY2xvbmUKKyNwcmFnbWEgcGVkYW50aWMKKworI2RlZmluZSBORUVEX1BST1RPVFlQRVMKKyNpbmNsdWRlIDxob29rLmg+CisjaW5jbHVkZSA8bGl2aW5nL3NraWxscy5oPgorI2luY2x1ZGUgPHRoaW5nL3Byb3BlcnRpZXMuaD4KKyNpbmNsdWRlIDxsaXZpbmcvbGlmZS5oPgorI2luY2x1ZGUgPGxpdmluZy9tb3ZpbmcuaD4KKyNpbmNsdWRlIDxsaXZpbmcvY29tYmF0Lmg+CisjaW5jbHVkZSA8bGl2aW5nL2F0dHJpYnV0ZXMuaD4KKyNpbmNsdWRlIDx0aGluZy9kZXNjcmlwdGlvbi5oPgorI2luY2x1ZGUgPHRoaW5nL2xhbmd1YWdlLmg+CisjdW5kZWYgTkVFRF9QUk9UT1RZUEVTCisjaW5jbHVkZSA8aGVhbHRoLmg+CisjaW5jbHVkZSA8ZGVmaW5lcy5oPgorI2luY2x1ZGUgPG5ld19za2lsbHMuaD4KKyNpbmNsdWRlIDxzY29yZW1hc3Rlci5oPgorI2luY2x1ZGUgPGRlZnVlbC5oPgorI2luY2x1ZGUgPHByb3BlcnRpZXMuaD4KKyNpbmNsdWRlIDxldmVudHMuaD4KKyNpbmNsdWRlIDx3aXpsZXZlbHMuaD4KKworI2RlZmluZSBBTENPSE9MX1ZBTFVFKG4pIG4KKworI2luY2x1ZGUgPGRlYnVnX2luZm8uaD4gLy92b3J1ZWJlcmdlaGVuZAorCisKKy8vICdwcml2YXRlJy1Qcm90b3R5cGVuCitwcml2YXRlIHZvaWQgRGlzdHJpYnV0ZUV4cChvYmplY3QgZW5lbXksIGludCBleHBfdG9fZ2l2ZSk7CisKKy8vIFZhcmlhYmxlbgorbm9zYXZlIGludCBkZWxheV9hbGNvaG9sOyAvKiB0aW1lIHVudGlsIG5leHQgYWxjb2hvbCBlZmZlY3QgKi8KK25vc2F2ZSBpbnQgZGVsYXlfZHJpbms7ICAgLyogdGltZSB1bnRpbCBuZXh0IGRyaW5rIGVmZmVjdCAqLworbm9zYXZlIGludCBkZWxheV9mb29kOyAgICAvKiB0aW1lIHVudGlsIG5leHQgZm9vZCBlZmZlY3QgKi8KK25vc2F2ZSBpbnQgZGVsYXlfaGVhbDsgICAgLyogdGltZSB1bnRpbCBuZXh0IGhlYWwgZWZmZWN0ICovCitub3NhdmUgaW50IGRlbGF5X3NwOyAgICAgIC8qIHRpbWUgdW50aWwgbmV4dCBzcCByZWdlbmVyYXRpb24gKi8KK25vc2F2ZSBpbnQgZGVsYXlfcG9pc29uOyAgLyogdGltZSB1bnRpbCBuZXh0IHBvaXNvbiBlZmZlY3QgKi8KK25vc2F2ZSBpbnQgZHJvcF9wb2lzb247Citub3NhdmUgbWFwcGluZyBlbmVteV9kYW1hZ2U7Citub3NhdmUgbWFwcGluZyBocF9idWZmZXI7Citub3NhdmUgbWFwcGluZyBzcF9idWZmZXI7Citub3NhdmUgaW50IHJlbW92ZV9tZTsKK2ludCBuZXh0ZGVmdWVsdGltZWZvb2Q7CitpbnQgbmV4dGRlZnVlbHRpbWVkcmluazsKKworCitwcm90ZWN0ZWQgdm9pZCBjcmVhdGUoKQoreworICBTZXQoUF9HSE9TVCwgU0FWRSwgRl9NT0RFKTsKKyAgU2V0KFBfRlJPRywgU0FWRSwgRl9NT0RFKTsKKyAgU2V0KFBfQUxJR04sIFNBVkUsIEZfTU9ERSk7CisgIFNldChQX0hQLCBTQVZFLCBGX01PREUpOworICBTZXQoUF9TUCwgU0FWRSwgRl9NT0RFKTsKKyAgU2V0KFBfWFAsIFNBVkUsIEZfTU9ERSk7CisgIFNldCggUF9MQVNUX1hQLCAoeyAiIiwgMCB9KSApOworICBTZXQoIFBfTEFTVF9YUCwgUFJPVEVDVEVELCBGX01PREVfQVMgKTsKKworICBTZXQoUF9BTENPSE9MLCBTQVZFLCBGX01PREUpOworICBTZXQoUF9EUklOSywgU0FWRSwgRl9NT0RFKTsKKyAgU2V0KFBfRk9PRCwgU0FWRSwgRl9NT0RFKTsKKyAgU2V0KFBfUE9JU09OLCBTQVZFLCBGX01PREUpOworICBTZXQoUF9ERUFGLCBTQVZFLCBGX01PREUpOworCisgIFNldFByb3AoUF9GT09EX0RFTEFZLCBGT09EX0RFTEFZKTsKKyAgU2V0UHJvcChQX0RSSU5LX0RFTEFZLCBEUklOS19ERUxBWSk7CisgIFNldFByb3AoUF9BTENPSE9MX0RFTEFZLCBBTENPSE9MX0RFTEFZKTsKKyAgU2V0UHJvcChQX0hQX0RFTEFZLEhFQUxfREVMQVkpOworICBTZXRQcm9wKFBfU1BfREVMQVksSEVBTF9ERUxBWSk7CisgIFNldFByb3AoUF9QT0lTT05fREVMQVksUE9JU09OX0RFTEFZKTsKKyAgLy8gZGVmYXVsdCBmdWVyIGFsbGUgTGViZXdlc2VuIChOUEMgKyBTcGllbGVyKToKKyAgU2V0UHJvcChQX01BWF9QT0lTT04sIDEwKTsKKyAgU2V0UHJvcChQX0NPUlBTRSwgIi9zdGQvY29ycHNlIik7CisKKyAgbmV4dGRlZnVlbHRpbWVmb29kPXRpbWUoKStRdWVyeVByb3AoUF9ERUZVRUxfVElNRV9GT09EKTsKKyAgbmV4dGRlZnVlbHRpbWVkcmluaz10aW1lKCkrUXVlcnlQcm9wKFBfREVGVUVMX1RJTUVfRFJJTkspOworCisgIGVuZW15X2RhbWFnZT0oWzoyIF0pOworICBocF9idWZmZXI9KFtdKTsKKyAgc3BfYnVmZmVyPShbXSk7CisKKyAgU2V0UHJvcChQX0RFRlVFTF9MSU1JVF9GT09ELDEpOworICBTZXRQcm9wKFBfREVGVUVMX0xJTUlUX0RSSU5LLDEpOworICBTZXRQcm9wKFBfREVGVUVMX1RJTUVfRk9PRCwxKTsKKyAgU2V0UHJvcChQX0RFRlVFTF9USU1FX0RSSU5LLDEpOworICBTZXRQcm9wKFBfREVGVUVMX0FNT1VOVF9GT09ELDEpOworICBTZXRQcm9wKFBfREVGVUVMX0FNT1VOVF9EUklOSywxKTsKKworICBvZmZlckhvb2soSF9IT09LX0RJRSwxKTsKKworICBvZmZlckhvb2soSF9IT09LX0ZPT0QsMSk7CisgIG9mZmVySG9vayhIX0hPT0tfRFJJTkssMSk7CisgIG9mZmVySG9vayhIX0hPT0tfQUxDT0hPTCwxKTsKKyAgb2ZmZXJIb29rKEhfSE9PS19QT0lTT04sMSk7CisgIG9mZmVySG9vayhIX0hPT0tfQ09OU1VNRSwxKTsKK30KKworLy8gV2VubiBkZXIgbGV0enRlIEthbXBmIGxhbmcgaGVyIGlzdCB1bmQgZGFzIExlYmV3ZXNlbiB3aWVkZXIgdm9sbGdlaGVpbHQKKy8vIGlzdCwgd2lyZCBQX0VORU1ZX0RBTUFHRSB6dXJ1ZWNrZ2VzZXR6dC4KK3Byb3RlY3RlZCB2b2lkIFJlc2V0RW5lbXlEYW1hZ2UoKSB7CisgIGlmICh0aW1lKCkgPiBRdWVyeVByb3AoUF9MQVNUX0NPTUJBVF9USU1FKSArIF9fUkVTRVRfVElNRV9fICogNAorICAgICAgJiYgUXVlcnlQcm9wKFBfSFApID09IFF1ZXJ5UHJvcChQX01BWF9IUCkpCisgICAgZW5lbXlfZGFtYWdlPShbOjIgXSk7Cit9CisKK3ByaXZhdGUgdm9pZCBEaXN0cmlidXRlRXhwKG9iamVjdCBlbmVteSwgaW50IGV4cF90b19naXZlKSB7CisgIGludCB0b3RhbF9kYW1hZ2UsIHRtcCwgZXg7CisgIG1hcHBpbmcgcHJlc2VudF9lbmVtaWVzOworCisgIGlmICggZXhwX3RvX2dpdmU8PTAgKQorICAgIHJldHVybjsKKworICBtYXBwaW5nIGVuZG1nPWRlZXBfY29weShlbmVteV9kYW1hZ2UpOworCisgIC8vIE1pdGdsaWVkZXIgaW0gVGVhbSBkZXMgS2lsbGVycyBiZWtvbW1lbjoKKyAgLy8KKyAgLy8gICAgICAgICAgICAgICAgICBHZXNhbXRhbnRlaWwgZGVzIFRlYW1zCisgIC8vIEVpZ2VuZW4gQW50ZWlsICsgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorICAvLyAgICAgICAgICAgICAgICAgIEFuemFobCAgVGVhbW1pdGdsaWVkZXIKKyAgLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisgIC8vICAgICAgICAgICAgICAgIDIKKyAgLy8KKyAgb2JqZWN0ICppbnYgPSBlbmVteS0+VGVhbU1lbWJlcnMoKTsKKyAgaWYgKCBwb2ludGVycChpbnYpICkKKyAgeworICAgIHByZXNlbnRfZW5lbWllcz1tX2FsbG9jYXRlKHNpemVvZihpbnYpLCAxKTsKKyAgICBmb3JlYWNoKG9iamVjdCBvYjogaW52KQorICAgIHsKKyAgICAgIGlmICggb2JqZWN0cChvYikgJiYgKGVudmlyb25tZW50KG9iKT09ZW52aXJvbm1lbnQoKSkgKQorICAgICAgeworICAgICAgICB0bXA9ZW5kbWdbb2JqZWN0X25hbWUob2IpXTsKKyAgICAgICAgdG90YWxfZGFtYWdlKz10bXA7CisgICAgICAgIHByZXNlbnRfZW5lbWllc1tvYl0gPSB0bXAvMjsKKyAgICAgICAgbV9kZWxldGUoZW5kbWcsb2JqZWN0X25hbWUob2IpKTsgLy9zLnUuCisgICAgICB9CisgICAgfQorICAgIGludCBtaXRnbGllZGVyID0gc2l6ZW9mKHByZXNlbnRfZW5lbWllcyk7CisgICAgaWYgKCBtaXRnbGllZGVyICkKKyAgICB7CisgICAgICB0bXA9dG90YWxfZGFtYWdlLygyKm1pdGdsaWVkZXIpOworICAgICAgZm9yZWFjaChvYmplY3Qgb2IsIGludCBwdW5rdGU6ICZwcmVzZW50X2VuZW1pZXMpCisgICAgICAgIHB1bmt0ZSArPSB0bXA7CisgICAgfQorICB9CisgIGVsc2UgeworICAgIC8vIG9obmUgVGVhbSB3aXJkIHRyb3R6ZGVtIGVpbiBNYXBwaW5nIGdlYnJhdWNodC4gRGEgR3JvZXNzZW52ZXJhZW5kZXJ1bmcKKyAgICAvLyByZWwuIHRldWVyIHNpbmQsIGthbm4gZWluZmFjaCBtYWwgZnVlciAzIEVpbnRyYWVnZSBQbGF0eiByZXNlcnZpZXJlbi4KKyAgICBwcmVzZW50X2VuZW1pZXM9bV9hbGxvY2F0ZSgzLCAxKTsKKyAgfQorICAvLyBVbmQgbm9jaCBkaWUgTGViZXdlc2VuIGltIFJhdW0gb2huZSBUZWFtLgorICBmb3JlYWNoKG9iamVjdCBvYjogYWxsX2ludmVudG9yeShlbnZpcm9ubWVudCgpKSkKKyAgeworICAgIGlmICggdG1wPWVuZG1nW29iamVjdF9uYW1lKG9iKV0gKQorICAgIHsKKyAgICAgIHRvdGFsX2RhbWFnZSArPSB0bXA7CisgICAgICBwcmVzZW50X2VuZW1pZXNbb2JdID0gdG1wOworICAgICAgbV9kZWxldGUoZW5kbWcsb2JqZWN0X25hbWUob2IpKTsgLy8gTnVyIGVpbm1hbCBwcm8gTGViZW4gUHVua3RlIDopCisgICAgfQorICB9CisgIGlmICggIXRvdGFsX2RhbWFnZSApCisgIHsKKyAgICBlbmVteS0+QWRkRXhwKGV4cF90b19naXZlKTsKKyAgfQorICBlbHNlCisgIHsKKyAgICBmb3JlYWNoKG9iamVjdCBvYiwgaW50IGRhbWFnZTogcHJlc2VudF9lbmVtaWVzKQorICAgIHsKKyAgICAgIGlmICggIW9iamVjdHAob2IpICkKKyAgICAgICAgY29udGludWU7CisgICAgICBpZiAoIHF1ZXJ5X29uY2VfaW50ZXJhY3RpdmUob2IpICYmICggIWludGVyYWN0aXZlKG9iKQorICAgICAgICAgICAgICB8fCAocXVlcnlfaWRsZShvYik+NjAwKSApICkKKyAgICAgICAgY29udGludWU7CisgICAgICAvL2V4cF90b19naXZlKnByZXNlbnRfZW5lbWllc1tpXVsxXS90b3RhbF9kYW1hZ2UgZ2lidCBiZWkgdmllbCBTY2hhZGVuCisgICAgICAvL2VpbmVuIG51bWVyaWNhbCBvdmVyZmxvdy4gRGFoZXIgbXVlc3NlbiB3aXIgaGllciB3b2hsIGRvY2gKKyAgICAgIC8vendpc2NoZW56ZWl0bGljaCBtaXQgZmxvYXRzIHJlY2huZW4sIGF1Y2ggd2VubiBkYXMgMC0xIFhQIFZlcmx1c3QKKyAgICAgIC8vZHVyY2ggZmxvYXQtPmludC1Lb252ZXJzaW9uIGdpYnQuIChjZWlsKCkgbG9obnQgc2ljaCBJTUhPIG5pY2h0LikKKyAgICAgIGV4ID0gKGludCkoZXhwX3RvX2dpdmUqKChmbG9hdClkYW1hZ2UvKGZsb2F0KXRvdGFsX2RhbWFnZSkpOworICAgICAgb2ItPkFkZEV4cChleCk7CisgICAgfQorICB9Cit9CisKKy8qCisgKiBUaGlzIGZ1bmN0aW9uIGlzIGNhbGxlZCBmcm9tIG90aGVyIHBsYXllcnMgd2hlbiB0aGV5IHdhbnQgdG8gbWFrZQorICogZGFtYWdlIHRvIHVzLiBCdXQgaXQgd2lsbCBvbmx5IGJlIGNhbGxlZCBpbmRpcmVjdGx5LgorICogV2UgcmV0dXJuIGhvdyBtdWNoIGRhbWFnZSB3ZSByZWNlaXZlZCwgd2hpY2ggd2lsbAorICogY2hhbmdlIHRoZSBhdHRhY2tlcnMgc2NvcmUuIFRoaXMgcm91dGluZSBpcyBwcm9iYWJseSBjYWxsZWQgZnJvbQorICogaGVhcnRfYmVhdCgpIGZyb20gYW5vdGhlciBwbGF5ZXIuCisgKiBDb21wYXJlIHRoaXMgZnVuY3Rpb24gdG8gcmVkdWNlX2hpdF9wb2ludHMoZGFtKS4KKyAqLworcHVibGljIGludCBkb19kYW1hZ2UoaW50IGRhbSwgb2JqZWN0IGVuZW15KQoreyBpbnQgaGl0X3BvaW50LGFsLGFsMjsKKworICBpZiAoIGV4dGVybl9jYWxsKCkKKyAgICAgICYmIG9iamVjdHAoZW5lbXkpCisgICAgICAmJiBsaXZpbmcoZW5lbXkpCisgICAgICAmJiAhUXVlcnlQcm9wKFBfRU5BQkxFX0lOX0FUVEFDS19PVVQpKQorICB7CisgICAgYWw9dGltZSgpLWVuZW15LT5RdWVyeVByb3AoUF9MQVNUX01PVkUpOworICAgIGlmIChhbDwzKSAgICAgIC8vIEVyc3RlIEthbXBmcnVuZGUgbmFjaCBCZXRyZXRlbiBkZXMgUmF1bWVzPworICAgICAgZGFtLz0oNC1hbCk7IC8vIEdlZ2VuIFJlaW4tRmV1ZXJiYWxsLVJhdXMtVGFrdGlrCisgIH0KKworICBpZiAoIFF1ZXJ5UHJvcChQX0dIT1NUKSB8fCBRdWVyeVByb3AoUF9OT19BVFRBQ0spIHx8IChkYW08PTApCisgICAgICB8fCAoIG9iamVjdHAoZW5lbXkpCisgICAgICAgICAgJiYgKCBlbmVteS0+UXVlcnlQcm9wKFBfR0hPU1QpCisgICAgICAgICAgICAgIHx8IGVuZW15LT5RdWVyeVByb3AoUF9OT19BVFRBQ0spICkgKSApCisgICAgcmV0dXJuIDA7CisKKyAgaGl0X3BvaW50ID0gUXVlcnlQcm9wKFBfSFApLWRhbTsKKworICBpZiAoIFF1ZXJ5UHJvcChQX1hQKSAmJiBvYmplY3RwKGVuZW15KSApCisgIHsKKyAgICBpZiAoICFRdWVyeVByb3AoUF9OT19YUCkgKQorICAgICAgZW5lbXktPkFkZEV4cChkYW0qKGludClRdWVyeVByb3AoUF9UT1RBTF9XQykvMTApOworICB9CisKKyAgaWYgKGxpdmluZyhlbmVteSkpIHsKKyAgICAgIHN0cmluZyBlbm5hbWUgPSBvYmplY3RfbmFtZShlbmVteSk7CisgICAgICAvLyBIbXBmLiBCbHVlcHJpbnRzIHNpbmQgZG9vZi4gRGllIENoYW5jZSBpc3QgendhciBnZXJpbmcsIGFiZXIga29lbm50ZQorICAgICAgLy8gc2VpbiwgZGFzcyBlaW4gVW5pcXVlLU5QQyBtaXQgendlaSB2ZXJzY2hpZWRlbmVuIFNwaWVsZXJuIGFtIGdsZWljaGVuCisgICAgICAvLyBOUEMgbWV0emVsdC4KKyAgICAgIC8vIFRPRE86IE1IbW0uIHdpZSBncm9zcyBpc3QgZGFzIFJpc2lrbyB3aXJrbGljaD8KKyAgICAgIC8vaWYgKCFjbG9uZXAoZW5lbXkpKQorICAgICAgLy8gICAgZW5uYW1lID0gZW5uYW1lICsgIl8iICsgdG9fc3RyaW5nKG9iamVjdF90aW1lKGVuZW15KSk7CisgICAgICAvLyBudXIgd2VubiBnZWduZXIgTlBDIGlzdCB1bmQgbm9jaCBuaWNodCBkcmluc3RlaHQ6IERhdGVuIGF1cworICAgICAgLy8gUF9IRUxQRVJfTlBDIGF1c3dlcnRlbgorICAgICAgaWYgKCFtZW1iZXIoZW5lbXlfZGFtYWdlLGVuZW15KSAmJiAhcXVlcnlfb25jZV9pbnRlcmFjdGl2ZShlbmVteSkpIHsKKyAgICAgICAgICBtaXhlZCBoZWxwZXIgPSBlbmVteS0+UXVlcnlQcm9wKFBfSEVMUEVSX05QQyk7CisgICAgICAgICAgaWYgKHBvaW50ZXJwKGhlbHBlcikgJiYgb2JqZWN0cChoZWxwZXJbMF0pKQorICAgICAgICAgICAgICBlbmVteV9kYW1hZ2VbZW5uYW1lLDFdID0gaGVscGVyWzBdOworICAgICAgfQorICAgICAgZW5lbXlfZGFtYWdlW2VubmFtZSwwXSs9ZGFtOworICB9CisKKyAgU2V0UHJvcChQX0hQLCBoaXRfcG9pbnQpOworCisgIGlmICggaGl0X3BvaW50PDAgKQorICB7CisgICAgLy9UT0RPOiBXYXJ1bSBuaWNodCBkYXMgZ2FuemUgWmV1ZyBpbnMgZGllKCkgdmVybGVnZW4/CisgICAgaWYgKCBlbmVteSApCisgICAgeworICAgICAgZW5lbXktPlN0b3BIdW50Rm9yKE1FLDEpOworICAgICAgaWYgKCAhUXVlcnlQcm9wKFBfTk9fWFApICkKKyAgICAgICAgRGlzdHJpYnV0ZUV4cChlbmVteSxRdWVyeVByb3AoUF9YUCkvMTAwKTsKKyAgICAgIGlmICggIXF1ZXJ5X29uY2VfaW50ZXJhY3RpdmUoTUUpICkKKyAgICAgICAgbG9nX2ZpbGUgKCJOUENfWFAiLCBzcHJpbnRmKAorCSAgICAiWyVzXSAlcywgWFA6ICVkLCBIUCpXQzogJWQsIEtpbGxlcjogJXNcbiIsCisJICAgIGR0aW1lKHRpbWUoKSksIG9iamVjdF9uYW1lKE1FKSwgKFF1ZXJ5UHJvcChQX1hQKS8xMDApLAorICAgICAgICAgICAgICAgICAgUXVlcnlQcm9wKFBfVE9UQUxfV0MpKlF1ZXJ5UHJvcChQX01BWF9IUCkvMTAsCisgICAgICAgICAgICAgICAgICBlbmVteS0+bmFtZSgpfHwiTm9OYW1lIiApKTsKKyAgICAgIGFsID0gUXVlcnlQcm9wKFBfQUxJR04pLzUwICsgZW5lbXktPlF1ZXJ5UHJvcChQX0FMSUdOKS8yMDA7CisgICAgICBpZiAoYWw+MjApCisgICAgICAgIGFsPTIwOworICAgICAgZWxzZSBpZihhbDwtMjApCisgICAgICAgIGFsPS0yMDsKKyAgICAgIGVuZW15LT5TZXRQcm9wKFBfQUxJR04sZW5lbXktPlF1ZXJ5UHJvcChQX0FMSUdOKS1hbCk7CisgICAgfQorICAgIFNldFByb3AoUF9LSUxMRVIsIGVuZW15KTsKKyAgICAKKyAgICBkaWUoKTsKKyAgfQorICByZXR1cm4gZGFtOworfQorCisKK3ByaXZhdGUgdm9pZCBfdHJhbnNmZXIoIG9iamVjdCAqb2JzLCBzdHJpbmd8b2JqZWN0IGRlc3QsIGludCBmbGFnICkKK3sgICBpbnQgaTsKKworICAgIGkgPSBzaXplb2Yob2JzKTsKKworICAgIC8vIEVpbmUgU2NobGVpZmUgaXN0IHp3YXIgbGFuZ3NhbWVyIGFscyBmaWx0ZXIoKSBvLmFlLiwgYWJlcgorICAgIC8vIHNlbGJzdCBtaXQgZWluZXIgbm9jaCBzbyBzY2huZWxsZW4gTG9lc3VuZyBrYW5uIGxlaWRlciBuaWNodAorICAgIC8vIGF1c2dlc2NobG9zc2VuIHdlcmRlbiwgZGFzcyBpcmdlbmR3byBlaW4gdG9vLWxvbmctZXZhbC1CdWcgZGF6d2lzY2hlbgorICAgIC8vIGtvbW10LiBEYXp1IHNpbmQgZGllIEthZW1wZmUgbWl0IEdpbGRlbi1OUENzIGV0Yy4gZWluZmFjaCB6dSB0ZXVlciAuLi4KKyAgICAvLyBQcnVlZnVuZyBhdWYgemVyc3RvZXJ0ZSBPYmpla3RlLCBkYSBlaW5pZ2Ugc2ljaCBldnRsLiBpbSBOb3RpZnlQbGF5ZXJEZWF0aCgpIAorICAgIC8vIHplcnN0b2VyZW4uCisgICB3aGlsZSAoIGkgJiYgZ2V0X2V2YWxfY29zdCgpID4gMzAwMDAwICkKKyAgICAgICAgaWYgKCBvYmplY3RwKG9ic1stLWldKSAmJiAhb2JzW2ldLT5RdWVyeVByb3AoUF9ORVZFUkRST1ApICkKKyAgICAgICAgLy8gSmV0enQgd2lyZCdzIG5vY2ggZXR3YXMgdGV1cmVyIG1pdCBjYXRjaCgpIC0gYWJlciBtYW5jaGUgU2FjaGVuCisgICAgICAgIC8vIGR1ZXJmZW4gZWluZmFjaCBuaWNodCBidWdnZW4KKyAgICAgICAgICAgIGNhdGNoKCBvYnNbaV0tPm1vdmUoIGRlc3QsIGZsYWcgKTtwdWJsaXNoICk7CisKKyAgICBpZiAoIGkgPiAwICkKKyAgICAgICAgLy8gWnV2aWVsIFJlY2hlbnplaXQgdmVyYnJhdGVuLCBlcyBtdWVzc2VuIG5vY2ggT2JqZWt0ZSBiZXdlZ3Qgd2VyZGVuCisgICAgICAgIGNhbGxfb3V0KCAjJ190cmFuc2ZlciwgMCwgb2JzWzAuLmktMV0sIGRlc3QsIGZsYWcgKTsKKyAgICBlbHNlIHsKKyAgICAgICAgaWYgKCByZW1vdmVfbWUgKQorICAgICAgICAgICAgcmVtb3ZlKCk7CisgICAgfQorfQorCisKK3B1YmxpYyB2YXJhcmdzIHZvaWQgdHJhbnNmZXJfYWxsX3RvKCBzdHJpbmd8b2JqZWN0IGRlc3QsIGludCBpc25wYyApIHsKKyAgICBpbnQgZmxhZ3M7CisgICAgb2JqZWN0ICpvYnM7CisKKyAgICBpZiAoICFvYmplY3RwKE1FKSApCisgICAgICAgIHJldHVybjsKKworICAgIC8vIERhcyBGbGFnICJpc25wYyIgaXN0IGZ1ZXIgTlBDcyBnZWRhY2h0LiBEZXJlbiBBdXNydWVzdHVuZyBkYXJmIG5pY2h0CisgICAgLy8gbWl0IE1fTk9DSEVDSyBiZXdlZ3Qgd2VyZGVuLCBkYSBTcGllbGVyIGRhcyBiZWkgTmljaHQtU3RhbmRhcmQtTGVpY2hlbgorICAgIC8vIHNvbnN0IHUuVS4gYXVzbnV0emVuIGtvZW5udGVuLgorICAgIGlmICggaXNucGMgKQorICAgICAgICBmbGFncyA9IE1fU0lMRU5UOworICAgIGVsc2UKKyAgICAgICAgZmxhZ3MgPSBNX1NJTEVOVHxNX05PQ0hFQ0s7CisKKyAgICBvYnMgPSBhbGxfaW52ZW50b3J5KE1FKSB8fCAoe30pOworCisgICAgLy8gdW5ub2V0aWcsIHdlaWwgX3RyYW5zZmVyKCkgYXVjaCBhdWYgUF9ORVZFUkRST1AgcHJ1ZWZ0LiBaZXNzdHJhCisgICAgLy9vYnMgLT0gZmlsdGVyX29iamVjdHMoIG9icywgIlF1ZXJ5UHJvcCIsIFBfTkVWRVJEUk9QICk7CisKKyAgICBfdHJhbnNmZXIoIG9icywgZGVzdCwgZmxhZ3MgKTsKK30KKworCitwcm90ZWN0ZWQgdmFyYXJncyB2b2lkIGNyZWF0ZV9raWxsX2xvZ19lbnRyeShzdHJpbmcga2lsbGVyLCBvYmplY3QgZW5lbXkpIHsKKyAgaW50IGxldmVsLGxvc3RfZXhwOworCisgIGlmICggKGxldmVsPVF1ZXJ5UHJvcChQX0xFVkVMKSk8MjAgfHwgIUlTX1NFRVIoTUUpICkKKyAgICBsb3N0X2V4cCA9IFF1ZXJ5UHJvcChQX1hQKS8zOworICBlbHNlCisgICAgbG9zdF9leHAgPSBRdWVyeVByb3AoUF9YUCkvKGxldmVsLTE3KTsKKyAgCisgIGxvZ19maWxlKCJLSUxMUyIsc3ByaW50ZigiJXMgJXMgKCVkLCVkKSAlc1xuIiwgc3RyZnRpbWUoIiVlICViICVIOiVNIiksCisgICAgICAgICAgICAgICBjYXBpdGFsaXplKFJFQUxfVUlEKE1FKSksIGxldmVsLCBsb3N0X2V4cC8xMDAwLCBraWxsZXIpKTsgCit9CisKKy8vIExpZWZlcnQgaW0gVG9kIChuYWNoIGRlbSB0b2V0ZW5kZW4gZG9fZGFtYWdlKCkpIGRhcyBTcGllbGVyb2JqZWt0LCB3YXMgZGVuCisvLyBUb2Qgd29obCB6dSB2ZXJhbnR3b3J0ZW4gaGF0LCBmYWxscyBlcyBlcm1pdHRlbHQgd2VyZGVuIGthbm4uIEVzIHdlcmRlbiB2b3IKKy8vIGFsbGVtIHJlZ2lzdHJpZXJ0ZSBIZWxmZXItTlBDIHVuZCBlaW5pZ2UgU29uZGVyb2JqZWt0ZSBiZXJ1ZWNrc2ljaHRpZ3QuCitwcm90ZWN0ZWQgb2JqZWN0IGdldF9raWxsaW5nX3BsYXllcigpCit7CisgIG9iamVjdCBraWxsZXI9UXVlcnlQcm9wKFBfS0lMTEVSKTsKKyAgLy8ga29lbm50ZSBzZWluLCB3ZW5uIGF1c3NlcmhhbGIgZGVzIFRvZGVzIGdlcnVmZW4gb2RlciBlaW5lIFZlcmdpZnR1bmcgdW5zCisgIC8vIHVtZ2VicmFjaHQgaGF0LgorICBpZiAoIW9iamVjdHAoa2lsbGVyKSkKKyAgICByZXR1cm4gMDsKKworICB3aGlsZSAoa2lsbGVyICYmICFxdWVyeV9vbmNlX2ludGVyYWN0aXZlKGtpbGxlcikpCisgICAga2lsbGVyID0ga2lsbGVyLT5RdWVyeVVzZXIoKTsKKworICByZXR1cm4ga2lsbGVyOworfQorCitwcm90ZWN0ZWQgb2JqZWN0IEdpdmVLaWxsU2NvcmUob2JqZWN0IHBsLCBpbnQgbnBjbnVtKQoreworICAvLyBTdHVmZW5wdW5rdCBmdWVyIGRlbiBLaWxsIHZlcmdlYmVuLgorICAvLyBGYWxscyBkZXIgS2lsbGVyIGRlbiBQdW5rdCBzY2hvbiBoYXQsIHdpcmQKKyAgLy8genVmYWVsbGlnIGVpbiBNaXRnbGllZCBzZWluZXMgVGVhbXMgYXVzZ2V3YWVobHQKKyAgLy8gdW5kIGRpZXNlbSBkZXIgUHVua3QgZ2VnZWJlbi4KKyAgb2JqZWN0ICpvYnMsb2I7CisgIG1peGVkICpmcjsKKyAgaW50IGksaixzejsKKworICBpZiAoIHBvaW50ZXJwKG9icz1wbC0+VGVhbU1lbWJlcnMoKSkgJiYgKG1lbWJlcihvYnMscGwpPj0wKSApCisgIHsKKyAgICBpZiAoICFwb2ludGVycChmcj1wbC0+UHJlc2VudFRlYW1Sb3dzKCkpCisgICAgICAgIHx8ICFzaXplb2YoZnIpCisgICAgICAgIHx8ICFwb2ludGVycChmcj1mclswXSkpIC8vIEVyc3RlIFJlaWhlIGRlcyBUZWFtcworICAgICAgZnI9KHt9KTsKKyAgICBmci09KHtwbCwwfSk7CisgICAgb2JzLT0oe3BsLDB9KTsKKyAgICBvYnMtPWZyOworICAgIGk9c3o9c2l6ZW9mKG9icyk7IC8vIHJlc3RsaWNoZSBUZWFtbWl0Z2xpZWRlciBpbiB6dWZhZWxsaWdlciBSZWloZW5mb2xnZToKKyAgICBmb3IgKCAtLWkgOyBpPj0wIDsgaS0tICkKKyAgICB7CisgICAgICBqPXJhbmRvbShzeik7CisgICAgICBvYj1vYnNbal07CisgICAgICBvYnNbal09b2JzWzBdOworICAgICAgb2JzWzBdPW9iOworICAgIH0KKyAgICBpPXN6PXNpemVvZihmcik7ICAvLyBFcnN0ZSBSZWloZSBpbiB6dWZhZWxsaWdlciBSZWloZW5mb2xnZToKKyAgICBmb3IgKCAtLWkgOyBpPj0wIDsgaS0tICkKKyAgICB7CisgICAgICBqPXJhbmRvbShzeik7CisgICAgICBvYj1mcltqXTsKKyAgICAgIGZyW2pdPWZyWzBdOworICAgICAgZnJbMF09b2I7CisgICAgfQorCisgICAgb2JzKz1mcjsgICAgIC8vIEVyc3RlIFJlaWhlIHdpcmQgdm9yIFJlc3QgZ2V0ZXN0ZXQKKyAgICBvYnMrPSh7cGx9KTsgLy8gS2lsbGVyIHdpcmQgYWxzIGVyc3RlcyBnZXRlc3RldAorICB9CisgIGVsc2UKKyAgeworICAgIG9icz0oe3BsfSk7CisgIH0KKyAgZm9yICggaT1zaXplb2Yob2JzKS0xIDsgaT49MCA7IGktLSApCisgICAgaWYgKCBvYmplY3RwKG9iPW9ic1tpXSApCisgICAgICAgICYmIGludGVyYWN0aXZlKG9iKSAgICAgLy8gTnVyIG5ldHp0b3QgZGFiZWkgc3RlaGVuIGdpbHQgbmljaHQgOikKKyAgICAgICAgJiYgcXVlcnlfaWRsZShvYik8NjAwICAvLyBnZWdlbiBMZXV0ZSBkaWUgc2ljaCBudXIgbWl0c2NobGVwcGVuIGxhc3NlbgorICAgICAgICAmJiBlbnZpcm9ubWVudChvYik9PWVudmlyb25tZW50KHBsKSAvLyBOdXIgYW53ZXNlbmRlIFRlYW1taXRnbGllZGVyCisgICAgICAgICYmICFJU19MRUFSTkVSKG9iKQorLy8gICAgICAgICYmICFvYi0+UXVlcnlQcm9wKFBfVEVTVFBMQVlFUikKKyAgICAgICAgJiYgIShTQ09SRU1BU1RFUi0+SGFzS2lsbChvYixNRSkpICkKKyAgICAgIHJldHVybiBTQ09SRU1BU1RFUi0+R2l2ZUtpbGwob2IsbnBjbnVtKSxvYjsKKworICByZXR1cm4gU0NPUkVNQVNURVItPkdpdmVLaWxsKHBsLG5wY251bSkscGw7Cit9CisKKy8vIHp1bSB1ZWJlcnNjaHJlaWJlbiBpbiBTcGllbGVybgorcHVibGljIGludCBkZWF0aF9zdWZmZXJpbmcoKSB7CisgIHJldHVybiAwOyAvLyBOUEMgaGFiZW4ga2VpbmUgVG9kZXNmb2xnZW4KK30KKworLy8ga2VpbiAyLiBMZWJlbiBmdWVyIE5pY2h0LVNwaWVsZXIuIDstKQordmFyYXJncyBwcm90ZWN0ZWQgaW50IHNlY29uZF9saWZlKCBvYmplY3QgY29ycHNlICkgeworICAgIHJldHVybiAwOworfQorCitwdWJsaWMgdmFyYXJncyB2b2lkIGRpZSggaW50IHBvaXNvbmRlYXRoLCBpbnQgZXh0ZXJuICkKK3sgICBvYmplY3QgY29ycHNlOworICAgIHN0cmluZyBkaWVfbXNnLCB0bXA7CisgICAgbWl4ZWQgcmVzOworICAgIG1peGVkIGhvb2tEYXRhOworICAgIG1peGVkIGhvb2tSZXM7CisKKyAgICBpZiAoICFvYmplY3RwKHRoaXNfb2JqZWN0KCkpIHx8IFF1ZXJ5UHJvcChQX0dIT1NUKSApCisgICAgICAgIHJldHVybjsgLy8gR2hvc3RzIGRvbnQgZGllIC4uLgorCisgICAgLy8gZGlyZWt0IHZvbiBleHRlcm4gYXVmZ2VydWZlbiB1bmQgbmljaHQgdWViZXIgaGVhcnRfYmVhdCgpIG9kZXIKKyAgICAvLyBkb19kYW1hZ2UoKSBoaWVyaGVyIGdlbGFuZ3Q/CisgICAgaWYgKGV4dGVybl9jYWxsKCkgJiYgcHJldmlvdXNfb2JqZWN0KCkgIT0gdGhpc19vYmplY3QoKSkgeworICAgICAgZXh0ZXJuPTE7CisgICAgICBTZXRQcm9wKFBfS0lMTEVSLCBwcmV2aW91c19vYmplY3QoKSk7CisgICAgfQorCisgICAgaWYgKCByZXMgPSBRdWVyeVByb3AoUF9UTVBfRElFX0hPT0spICl7CisgICAgICAgIGlmICggcG9pbnRlcnAocmVzKSAmJiBzaXplb2YocmVzKT49MworICAgICAgICAgICAgJiYgaW50cChyZXNbMF0pICYmIHRpbWUoKTxyZXNbMF0KKyAgICAgICAgICAgICYmIG9iamVjdHAocmVzWzFdKSAmJiBzdHJpbmdwKHJlc1syXSkgKQorICAgICAgICB7CisgICAgICAgICAgICBpZiAoIHJlcyA9IGNhbGxfb3RoZXIoIHJlc1sxXSwgcmVzWzJdLCBwb2lzb25kZWF0aCApICkgeworICAgICAgICAgICAgICBTZXRQcm9wKFBfS0lMTEVSLDApOworICAgICAgICAgICAgICByZXR1cm47CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgZWxzZQorICAgICAgICAgICAgU2V0UHJvcChQX1RNUF9ESUVfSE9PSywwKTsKKyAgICB9CisKKyAgICAvLyB0cmlnZ2VyIGRpZSBob29rCisgICAgaG9va0RhdGE9cG9pc29uZGVhdGg7CisgICAgaG9va1Jlcz1Ib29rRmxvdyhIX0hPT0tfRElFLGhvb2tEYXRhKTsKKyAgICBpZiAocG9pbnRlcnAoaG9va1JlcykgJiYgc2l6ZW9mKGhvb2tSZXMpPkhfUkVUREFUQSl7CisgICAgICBpZihob29rUmVzW0hfUkVUQ09ERV09PUhfQ0FOQ0VMTEVEKSB7CisgICAgICAgIFNldFByb3AoUF9LSUxMRVIsMCk7CisgICAgICAgIHJldHVybjsKKyAgICAgIH0KKyAgICAgIGVsc2UgaWYgKGhvb2tSZXNbSF9SRVRDT0RFXT09SF9BTFRFUkVEKQorICAgICAgICAgIHBvaXNvbmRlYXRoID0gaG9va1Jlc1tIX1JFVERBVEFdOworICAgIH0KKworICAgIGlmICggSVNfTEVBUk5JTkcoTUUpICYmIHF1ZXJ5X29uY2VfaW50ZXJhY3RpdmUoTUUpICl7CisgICAgICAgdGVsbF9vYmplY3QoIE1FLCAiU2VpIGZyb2ggZGFzcyBEdSB1bnN0ZXJibGljaCBiaXN0LCBzb25zdCB3YWVyZSBlcyAiCisgICAgICAgICAgICAgICAgICAgICAgICAiZWJlbiBEZWluIEVuZGUgZ2V3ZXNlbi5cbiIpOworICAgICAgIFNldFByb3AoUF9LSUxMRVIsMCk7CisgICAgICAgcmV0dXJuOworICAgIH0KKworICAgIC8vIEdlZ25lciBiZWZyaWVkZW4uCisgICAgbWFwX29iamVjdHMoIFF1ZXJ5RW5lbWllcygpWzBdLCAiU3RvcEh1bnRGb3IiLCBNRSwgMSApOworICAgIFN0b3BIdW50aW5nTW9kZSgxKTsKKworICAgIC8vIEZhbGxzIGRpZSgpIGRpcmVrdCBhdWZnZXJ1ZmVuIHd1cmRlIHVuZCBkaWVzIGVpbiBTcGllbGVyIGlzdCwgbXVzcyBkYXMKKyAgICAvLyBkaWUoKSBub2NoIEVpbnRyYWVnZSBpbiAvbG9nL0tJTExTIHZpYSBjcmVhdGVfa2lsbF9sb2dfZW50cnkgYnp3LiBpbgorICAgIC8vIC9sb2cvS0lMTEVSIGVyc3RlbGxlbi4KKyAgICBpZiAoIHF1ZXJ5X29uY2VfaW50ZXJhY3RpdmUoTUUpICYmIGV4dGVybiApCisgICAgeworICAgICAgb2JqZWN0IGtpbGxlciA9IFF1ZXJ5UHJvcChQX0tJTExFUikgCisgICAgICAgICAgICAgICAgICAgICB8fCBwcmV2aW91c19vYmplY3QoKSB8fCB0aGlzX2ludGVyYWN0aXZlKCkgfHwgdGhpc19wbGF5ZXIoKTsKKyAgICAgIGlmICgga2lsbGVyICYmICFxdWVyeV9vbmNlX2ludGVyYWN0aXZlKGtpbGxlcikgKQorICAgICAgeworICAgICAgICAgIHRtcCA9IGV4cGxvZGUoIG9iamVjdF9uYW1lKGtpbGxlciksICIjIilbMF0gKyAiIChkaXJla3QgISkiOworCisgICAgICAgICAgY3JlYXRlX2tpbGxfbG9nX2VudHJ5KCB0bXAgKyAiICgiICsgUkVBTF9VSUQoa2lsbGVyKSArICIpIiwga2lsbGVyICk7CisgICAgICB9CisgICAgICBlbHNlIGlmICgga2lsbGVyICYmICFRdWVyeVByb3AoUF9URVNUUExBWUVSKSAmJiAhSVNfTEVBUk5FUihNRSkgKQorICAgICAgeworICAgICAgICAgIGxvZ19maWxlKCAiS0lMTEVSIiwgc3ByaW50ZiggIiVzICVzICglZC8lZCkgdG9ldGV0ZSAlcyAoJWQvJWQpXG4iLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY3RpbWUodGltZSgpKSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhcGl0YWxpemUoZ2V0dWlkKGtpbGxlcikpLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcXVlcnlfd2l6X2xldmVsKGtpbGxlciksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBraWxsZXItPlF1ZXJ5UHJvcChQX0xFVkVMKSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhcGl0YWxpemUoZ2V0dWlkKE1FKSksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBxdWVyeV93aXpfbGV2ZWwoTUUpLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUXVlcnlQcm9wKFBfTEVWRUwpICkgKTsKKworICAgICAgICAgIGtpbGxlci0+U2V0UHJvcCggUF9LSUxMUywgLTEgKTsKKyAgICAgIH0KKyAgICB9CisKKyAgLy8gQmVpIE5QQyBFS3MgdmVyZ2ViZW4gdW5kIGdnZi4gaW4gZGVyIEdpbGRlIGRlcyBLaWxsZXJzIHVuZCBpbSBSYXVtCisgIC8vIE5QQ19LaWxsZWRfQnkoKSBydWZlbi4KKyAgaWYgKCAhcXVlcnlfb25jZV9pbnRlcmFjdGl2ZShNRSkgKQorICB7CisgICAgb2JqZWN0IGtpbGxlciA9ICgob2JqZWN0KSBRdWVyeVByb3AoUF9LSUxMRVIpKSB8fCBwcmV2aW91c19vYmplY3QoKSB8fAorICAgICAgdGhpc19pbnRlcmFjdGl2ZSgpIHx8IHRoaXNfcGxheWVyKCk7CisKKyAgICBpZiAoIGtpbGxlciAmJiBxdWVyeV9vbmNlX2ludGVyYWN0aXZlKGtpbGxlcikgKQorICAgIHsKKyAgICAgIGlmIChzdHJpbmdwKHJlcz1raWxsZXItPlF1ZXJ5UHJvcChQX0dVSUxEKSkKKyAgICAgICAgICAmJiBvYmplY3RwKHJlcz1maW5kX29iamVjdCgiL2dpbGRlbi8iK3JlcykpKQorICAgICAgICByZXMtPk5QQ19LaWxsZWRfQnkoa2lsbGVyKTsKKworICAgICAgaWYgKGVudmlyb25tZW50KCkpCisgICAgICAgICAgZW52aXJvbm1lbnQoKS0+TlBDX0tpbGxlZF9CeShraWxsZXIpOworCisgICAgICByZXMgPSBRdWVyeVByb3AoUF9YUCk7CisgICAgICByZXMgPSAocmVzIDwgU0NPUkVfTE9XX01BUkspID8gMCA6ICgocmVzID4gU0NPUkVfSElHSF9NQVJLKSA/IDIgOiAxKTsKKyAgICAgIGlmICggIVF1ZXJ5UHJvcChQX05PX1NDT1JFKSAmJiAhSVNfTEVBUk5FUihraWxsZXIpICYmCisgICAgICAgICAgIC8vICFraWxsZXItPlF1ZXJ5UHJvcChQX1RFU1RQTEFZRVIpICYmCisgICAgICAgICAgIHBvaW50ZXJwKCByZXMgPSBTQ09SRU1BU1RFUi0+UXVlcnlOUEMocmVzKSkgKQorICAgICAgICBHaXZlS2lsbFNjb3JlKCBraWxsZXIsIHJlc1swXSApOworICAgIH0KKyAgfQorCisgIGlmKCAhKGRpZV9tc2cgPSBRdWVyeVByb3AoUF9ESUVfTVNHKSkgKQorICAgIGlmIChRdWVyeVByb3AoUF9QTFVSQUwpKQorICAgICAgZGllX21zZyA9ICIgZmFsbGVuIHRvdCB6dSBCb2Rlbi5cbiI7CisgICAgZWxzZQorICAgICAgZGllX21zZyA9ICIgZmFlbGx0IHRvdCB6dSBCb2Rlbi5cbiI7CisKKyAgaWYgKCBwb2lzb25kZWF0aCApCisgIHsKKyAgICAgIFNldCggUF9MQVNUX0RBTVRZUEVTLCAoeyBEVF9QT0lTT04gfSkgKTsKKyAgICAgIFNldCggUF9MQVNUX0RBTVRJTUUsIHRpbWUoKSApOworICAgICAgU2V0KCBQX0xBU1RfREFNQUdFLCAxICk7CisgICAgICBkaWVfbXNnID0gIiB3aXJkIHZvbiBHaWZ0IGhpbndlZ2dlcmFmZnQgdW5kIGtpcHB0IHVtLlxuIjsKKyAgfQorCisgIHNheSggY2FwaXRhbGl6ZShuYW1lKFdFUiwxKSkgKyBkaWVfbXNnICk7CisKKyAgLy8gV2VubiBrZWluZSBMZWljaGUsIGRhbm4gS3JhbSBpbnMgRW52IGxlZ2VuLgorICBpZiAoIFF1ZXJ5UHJvcChQX05PQ09SUFNFKSB8fCAhKHRtcCA9IFF1ZXJ5UHJvcChQX0NPUlBTRSkpCisgICAgICB8fCBjYXRjaChjb3Jwc2UgPSBjbG9uZV9vYmplY3QodG1wKTtwdWJsaXNoKSAKKyAgICAgIHx8ICFvYmplY3RwKGNvcnBzZSkgKQorICB7CisgICAgICAvLyBNYWdpZXIgb2RlciBUZXN0c3BpZWxlciBiZWhhbHRlbiBpaHJlIEF1c3J1ZXN0dW5nLgorICAgICAgLy8gU29uc3Qga2FlbWVuIHUuVS4gU3BpZWxlciBhbiBNYWdpZXJ0b29scyBldGMuIGhlcmFuCisgICAgICBpZiAoICEoSVNfTEVBUk5FUihNRSkgfHwgKHRtcCA9IFF1ZXJ5KFBfVEVTVFBMQVlFUikpICYmCisgICAgICAgICAgICAgKCFzdHJpbmdwKHRtcCkgfHwgSVNfTEVBUk5FUiggbG93ZXJfY2FzZSh0bXApICkpKSApCisgICAgICAgICAgdHJhbnNmZXJfYWxsX3RvKCBlbnZpcm9ubWVudCgpLCAwICk7CisgICAgICBlbHNlCisgICAgICAgICAgLy8gQWJlciBzaWUgemllaGVuIHNpY2ggYXVzLgorICAgICAgICAgIGZpbHRlcl9vYmplY3RzKFF1ZXJ5UHJvcChQX0FSTU9VUlMpLCJEb1Vud2VhciIsTV9OT0NIRUNLLDApOworICB9CisgIGVsc2UKKyAgLy8gc29uc3QgaW4gZGllIExlaWNoZSBsZWdlbi4KKyAgeworICAgICAgY29ycHNlLT5JZGVudGlmeShNRSk7CisgICAgICBjb3Jwc2UtPm1vdmUoIGVudmlyb25tZW50KCksIE1fTk9DSEVDS3xNX1NJTEVOVCApOworICAgICAgLy8gTWFnaWVyIG9kZXIgVGVzdHNwaWVsZXIgYmVoYWx0ZW4gaWhyZSBBdXNydWVzdHVuZy4KKyAgICAgIC8vIFNvbnN0IGthZW1lbiB1LlUuIFNwaWVsZXIgYW4gTWFnaWVydG9vbHMgZXRjLiBoZXJhbgorICAgICAgaWYgKCAhKElTX0xFQVJORVIoTUUpIHx8ICh0bXAgPSBRdWVyeShQX1RFU1RQTEFZRVIpKSAmJgorICAgICAgICAgICAgICghc3RyaW5ncCh0bXApIHx8IElTX0xFQVJORVIoIGxvd2VyX2Nhc2UodG1wKSApKSkgKQorICAgICAgICAgIHRyYW5zZmVyX2FsbF90byggY29ycHNlLCAhcXVlcnlfb25jZV9pbnRlcmFjdGl2ZShNRSkgKTsKKyAgICAgIGVsc2UKKyAgICAgICAgICAvLyBBYmVyIHNpZSB6aWVoZW4gc2ljaCBhdXMuCisgICAgICAgICAgZmlsdGVyX29iamVjdHMoUXVlcnlQcm9wKFBfQVJNT1VSUyksIkRvVW53ZWFyIixNX05PQ0hFQ0ssMCk7CisgIH0KKworICBpZiAoIHF1ZXJ5X29uY2VfaW50ZXJhY3RpdmUoTUUpICkgeworICAgICAgU2V0KCBQX0RFQURTLCBRdWVyeShQX0RFQURTKSArIDEgKTsKKyAgICAgIC8vIFNwaWVsZXItVG9kLWV2ZW50IGF1c2xvZXNlbgorICAgICAgRVZFTlRELT5UcmlnZ2VyRXZlbnQoRVZUX0xJQl9QTEFZRVJfREVBVEgsIChbCisgICAgICBFX09CSkVDVDogTUUsIEVfUExOQU1FOiBnZXR1aWQoTUUpLAorICAgICAgRV9FTlZJUk9OTUVOVDogZW52aXJvbm1lbnQoKSwgRV9USU1FOiB0aW1lKCksCisgICAgICBQX0tJTExFUjogUXVlcnlQcm9wKFBfS0lMTEVSKSwKKyAgICAgIFBfTEFTVF9EQU1BR0U6IFF1ZXJ5UHJvcChQX0xBU1RfREFNQUdFKSwKKyAgICAgIFBfTEFTVF9EQU1UWVBFUzogY29weShRdWVyeVByb3AoUF9MQVNUX0RBTVRZUEVTKSksCisgICAgICBFX0VYVEVSTkFMX0RFQVRIOiBleHRlcm4sCisgICAgICBFX1BPSVNPTl9ERUFUSDogcG9pc29uZGVhdGgsIAorICAgICAgRV9DT1JQU0U6IChvYmplY3RwKGNvcnBzZSk/Y29ycHNlOjApIF0pICk7CisgIH0KKyAgZWxzZSB7CisgICAgICAvLyBOUEMtVG9kZXMtRXZlbnQgYXVzbG9lc2VuLiBEaXYuIE1hcHBpbmdzL0FycmF5cyB3ZXJkZW4gbmljaHQga29waWVydCwKKyAgICAgIC8vIHdlaWwgZGVyIE5QQyBqYSBqZXR6dCBlaCB6ZXJzdG9lcnQgd2lyZC4KKyAgICAgIG1hcHBpbmcgZGF0YSA9IChbCisgICAgICAgICAgICBFX09CTkFNRTogb2JqZWN0X25hbWUoTUUpLAorICAgICAgICAgICAgRV9FTlZJUk9OTUVOVDogZW52aXJvbm1lbnQoKSwgRV9USU1FOiB0aW1lKCksCisgICAgICAgICAgICBQX05BTUU6IFF1ZXJ5UHJvcChQX05BTUUpLAorICAgICAgICAgICAgUF9LSUxMRVI6IFF1ZXJ5UHJvcChQX0tJTExFUiksCisgICAgICAgICAgICBQX0VORU1ZX0RBTUFHRTogUXVlcnlQcm9wKFBfRU5FTVlfREFNQUdFKSwKKyAgICAgICAgICAgIFBfTEFTVF9EQU1BR0U6IFF1ZXJ5UHJvcChQX0xBU1RfREFNQUdFKSwKKyAgICAgICAgICAgIFBfTEFTVF9EQU1UWVBFUzogUXVlcnlQcm9wKFBfTEFTVF9EQU1UWVBFUyksCisgICAgICAgICAgICBFX0VYVEVSTkFMX0RFQVRIOiBleHRlcm4sCisgICAgICAgICAgICBFX1BPSVNPTl9ERUFUSDogcG9pc29uZGVhdGgsCisgICAgICAgICAgICBFX0NPUlBTRTogKG9iamVjdHAoY29ycHNlKT9jb3Jwc2U6MCksCisgICAgICAgICAgICBQX1hQOiBRdWVyeVByb3AoUF9YUCksCisgICAgICAgICAgICBQX0FUVFJJQlVURVM6IFF1ZXJ5UHJvcChQX0FUVFJJQlVURVMpLAorICAgICAgICAgICAgUF9NQVhfSFA6IFF1ZXJ5UHJvcChQX01BWF9IUCksCisgICAgICAgICAgICBQX0hBTkRTOiBRdWVyeVByb3AoUF9IQU5EUyksCisgICAgICAgICAgICBQX0FMSUdOOiBRdWVyeVByb3AoUF9BTElHTiksCisgICAgICAgICAgICBQX1JBQ0U6IFF1ZXJ5UHJvcChQX1JBQ0UpLAorICAgICAgICAgICAgUF9DTEFTUzogUXVlcnlQcm9wKFBfQ0xBU1MpLAorICAgICAgICAgICAgXSk7CisgICAgICBFVkVOVEQtPlRyaWdnZXJFdmVudChFVlRfTElCX05QQ19ERUFUSCgiIiksIGRhdGEpOworICAgICAgRVZFTlRELT5UcmlnZ2VyRXZlbnQoCisgICAgICAgICAgRVZUX0xJQl9OUENfREVBVEgobG9hZF9uYW1lKE1FKSksIGRhdGEpOworICB9CisKKyAgLy8gdHJhbnNmZXJfYWxsX3RvKCkgaXN0IGV2dGwuICh3ZW5uIHp1dmllbGUgT2JqZWt0ZSBiZXdlZ3Qgd2VyZGVuIG11c3N0ZW4pCisgIC8vIG5vY2ggbmljaHQgZ2FueiBmZXJ0aWcgdW5kIHdpcmQgcGVyIGNhbGxfb3V0KCkgZGVuIFJlc3QgZXJsZWRpZ2VuLgorICAvLyBTb2xsdGUgZGllIExlaWNoZSBkYW5uIG5pY2h0IG1laHIgZXhpc3RpZXJlbiwgdmVyYmxlaWJlbiBkaWUgcmVzdGxpY2hlbgorICAvLyBPYmpla3RlIGltIFNwaWVsZXIuCisgIC8vIEVzIGJsZWliZW4gYWJlciBhdWYgamVkZW4gRmFsbCBub2NoIHJ1bmQgMzAwayBFdmFsLVRpY2tzIHVlYmVyLCBkYW1pdAorICAvLyBrZWluIFNwaWVsZXIgZGFuayAiZXZhbGNvc3QgdG9vIGhpZ2giIHVuZ2VzY2hvcmVuIGRhdm9uIGtvbW10LgorICBpZiAoICEoc2Vjb25kX2xpZmUoY29ycHNlKSkgKQorICB7CisgICAgICBTZXQoIFBfR0hPU1QsIDEgKTsgLy8gRnVlciBrb3JyZWt0ZSBBdXNnYWJlIGF1ZiBUZWFta2FuYWwuCisKKyAgICAgIGlmICggZmluZF9jYWxsX291dCgjJ190cmFuc2ZlcikgPT0gLTEgKQorICAgICAgICAgIC8vIEZhbGxzIGtlaW4gY2FsbF9vdXQoKSBtZWhyIGxhZXVmdCwgc29mb3J0IGRlc3RydWN0ZW4gLi4uCisgICAgICAgICAgcmVtb3ZlKCk7CisgICAgICBlbHNlCisgICAgICAgICAgLy8gLi4uIGFuc29uc3RlbiB2b3JtZXJrZW4KKyAgICAgICAgICByZW1vdmVfbWUgPSAxOworICB9Cit9CisKK3B1YmxpYyB2b2lkIGhlYWxfc2VsZihpbnQgaCkKK3sKKyAgaWYgKCBoPD0wICkKKyAgICByZXR1cm47CisgIFNldFByb3AoUF9IUCwgUXVlcnlQcm9wKFBfSFApK2gpOworICBTZXRQcm9wKFBfU1AsIFF1ZXJ5UHJvcChQX1NQKStoKTsKK30KKworCisvLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisvLworLy8gICBpbnQgZGVmdWVsX2Zvb2QoIC8qIHZvaWQgKi8gKQorLy8KKy8vICAgRW50dGFua3QgZGVuIFNwaWVsZXIgdW0gZWluZW4gZ2V3aXNzZW4gRXNzZW5zLVdlcnQuCisvLyAgIFNvbGx0ZSBudXIgdm9uIFRvaWxldHRlbiBhdWZnZXJ1ZmVuIHdlcmRlbi4KKy8vCisvLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCitwdWJsaWMgaW50IGRlZnVlbF9mb29kKCkKK3sKKyAgaW50IGZvb2Q7CisKKyAgZm9vZD1RdWVyeVByb3AoUF9GT09EKTsKKworLy8gd2VubiBzcGllbGVyIGtlaW4gZm9vZCBoYXQ6IHJldHVybiAwCisgIGlmICggIWZvb2QgKQorICAgcmV0dXJuIE5PX0RFRlVFTDsKKworLy8gd2VubiBzcGllbGVyIHVudGVyIGVudHRhbmstZ3JlbnplOiByZXR1cm4gLTEKKyAgaWYgKCBmb29kIDwgUXVlcnlQcm9wKFBfREVGVUVMX0xJTUlUX0ZPT0QpICkKKyAgIHJldHVybiBERUZVRUxfVE9PX0xPVzsKKworLy8gd2VubiBsZXR6dGVzIGVudHRhbmtlbiBuaWNodCBsYW5nZSBnZW51ZyB6dXJ1ZWNrbGllZ3Q6IHJldHVybiAtMgorICBpZiAoIHRpbWUoKSA8IG5leHRkZWZ1ZWx0aW1lZm9vZCApCisgICByZXR1cm4gREVGVUVMX1RPT19TT09OOworCisgIGZvb2Q9dG9faW50KCgoZm9vZCpRdWVyeVByb3AoUF9ERUZVRUxfQU1PVU5UX0ZPT0QpKS8yKSk7CisgIGZvb2QrPXJhbmRvbShmb29kKTsKKworLy8gc2ljaGVyaGVpdHNoYWxiZXIKKyAgaWYgKCBmb29kID4gUXVlcnlQcm9wKFBfRk9PRCkgKQorICAgZm9vZD1RdWVyeVByb3AoUF9GT09EKTsKKworICBTZXRQcm9wKFBfRk9PRCwoUXVlcnlQcm9wKFBfRk9PRCktZm9vZCkpOworCisgIG5leHRkZWZ1ZWx0aW1lZm9vZD10aW1lKCkrUXVlcnlQcm9wKFBfREVGVUVMX1RJTUVfRk9PRCk7CisKKyAgcmV0dXJuIGZvb2Q7Cit9CisKKworLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorLy8KKy8vICAgaW50IGRlZnVlbF9kcmluayggLyogdm9pZCAqLyApCisvLworLy8gICBFbnR0YW5rdCBkZW4gU3BpZWxlciB1bSBlaW5lbiBnZXdpc3NlbiBGbHVlc3NpZ2tlaXRzLVdlcnQuCisvLyAgIEdsZWljaHplaXRpZyB3aXJkIGVpbmUgZ2V3aXNzZSBNZW5nZSBBbGtvaG9sIHJlZHV6aWVydC4KKy8vICAgU29sbHRlIG51ciB2b24gVG9pbGV0dGVuIGF1ZmdlcnVmZW4gd2VyZGVuLgorLy8KKy8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KK3B1YmxpYyBpbnQgZGVmdWVsX2RyaW5rKCkKK3sKKyAgaW50IGFsYywgZHJpbms7CisKKyAgZHJpbms9UXVlcnlQcm9wKFBfRFJJTkspOworCisvLyB3ZW5uIHNwaWVsZXIga2VpbiBkcmluayBoYXQ6IHJldHVybiAwCisgIGlmICggIWRyaW5rICkKKyAgIHJldHVybiBOT19ERUZVRUw7CisKKy8vIHdlbm4gc3BpZWxlciB1bnRlciBlbnR0YW5rLWdyZW56ZTogcmV0dXJuIC0xCisgIGlmICggZHJpbmsgPCBRdWVyeVByb3AoUF9ERUZVRUxfTElNSVRfRFJJTkspICkKKyAgIHJldHVybiBERUZVRUxfVE9PX0xPVzsKKworLy8gd2VubiBsZXR6dGVzIGVudHRhbmtlbiBuaWNodCBsYW5nZSBnZW51ZyB6dXJ1ZWNrbGllZ3Q6IHJldHVybiAtMgorICBpZiAoIHRpbWUoKSA8IG5leHRkZWZ1ZWx0aW1lZHJpbmsgKQorICAgcmV0dXJuIERFRlVFTF9UT09fU09PTjsKKyAgICAKKyAgZHJpbms9dG9faW50KCgoZHJpbmsqUXVlcnlQcm9wKFBfREVGVUVMX0FNT1VOVF9EUklOSykpLzIpKTsKKyAgZHJpbmsrPXJhbmRvbShkcmluayk7CisKKy8vIHNpY2hlcmhlaXRzaGFsYmVyCisgIGlmICggZHJpbmsgPiBRdWVyeVByb3AoUF9EUklOSykgKQorICAgZHJpbms9UXVlcnlQcm9wKFBfRFJJTkspOworCisgIFNldFByb3AoUF9EUklOSywoUXVlcnlQcm9wKFBfRFJJTkspLWRyaW5rKSk7CisKKy8vIGplZGVzIGZsdWVzc2lnZSBFbnR0YW5rZW4gbWFjaHQgYXVjaCBldHdhcyBudWVjaHRlcm5lciA6XikKKy8vIGJlaSBzZWhyIGtsZWluZW4gTWVuZ2VuIGVudHRhbmt0IG1hbiBrZWluZW4gQWxrb2hvbAorLy8gYW5zb25zdGVuIGluIEFiaGFlbmdpZ2tlaXQgdm9uIGVudHRhbmt0ZXIgTWVuZ2UsIFBfQUxDT0hPTCB1bmQgUF9XRUlHSFQKKworICBpZiAoIGRyaW5rID4gOSAmJiBRdWVyeVByb3AoUF9BTENPSE9MKSA+IDAgKQorICAgeworICAgIGFsYz0odG9faW50KGV4cChsb2coMS4xKSooZHJpbmspKSkqCisgICAgICAgICB0b19pbnQoZXhwKGxvZygwLjY3KSooUXVlcnlQcm9wKFBfQUxDT0hPTCkpKSkpLworICAgICAgICAgKFF1ZXJ5UHJvcChQX01BWF9EUklOSykqUXVlcnlQcm9wKFBfTUFYX0FMQ09IT0wpKSoKKyAgICAgICAgICh0b19pbnQoUXVlcnlQcm9wKFBfV0VJR0hUKS8xMDAwKSk7CisKKyAgICAgU2V0UHJvcChQX0FMQ09IT0wsUXVlcnlQcm9wKFBfQUxDT0hPTCktKGFsYytyYW5kb20oYWxjKSkpOworICAgfQorCisgIG5leHRkZWZ1ZWx0aW1lZHJpbms9dGltZSgpK1F1ZXJ5UHJvcChQX0RFRlVFTF9USU1FX0RSSU5LKTsKKyAKKyAgcmV0dXJuIGRyaW5rOworfQorCisKK3B1YmxpYyB2b2lkIHJlZHVjZV9zcGVsbF9wb2ludHMoaW50IGgpCit7CisgIFNldFByb3AoUF9TUCwgUXVlcnlQcm9wKFBfU1ApLWgpOworfQorCitwdWJsaWMgdm9pZCByZXN0b3JlX3NwZWxsX3BvaW50cyhpbnQgaCkKK3sKKyAgU2V0UHJvcChQX1NQLCBRdWVyeVByb3AoUF9TUCkraCk7Cit9CisKKy8qIFJlZHVjZSBoaXRwb2ludHMuIExvZyB3aG8gaXMgZG9pbmcgaXQuICovCitwdWJsaWMgaW50IHJlZHVjZV9oaXRfcG9pbnRzKGludCBkYW0pCit7IG9iamVjdCBvOworICBpbnQgaTsKKworI2lmZGVmIExPR19SRURVQ0VfSFAKKyAgaWYgKHRoaXNfcGxheWVyKCkhPU1FKQorICB7CisgICAgbG9nX2ZpbGUoIlJFRFVDRV9IUCIsIG5hbWUoKSsiIGJ5ICIpOworICAgIGlmKCF0aGlzX3BsYXllcigpKSBsb2dfZmlsZSgiUkVEVUNFX0hQIiwiP1xuIik7CisgICAgZWxzZSB7CisgICAgICBsb2dfZmlsZSgiUkVEVUNFX0hQIix0aGlzX3BsYXllcigpLT5uYW1lKCkpOworICAgICAgbz1wcmV2aW91c19vYmplY3QoKTsKKyAgICAgIGlmIChvKQorICAgICAgICBsb2dfZmlsZSgiUkVEVUNFX0hQIiwgIiAiICsgb2JqZWN0X25hbWUobykgKyAiLCAiICsKKyAgICAgICAgICAgICAgICAgby0+bmFtZShXRVIsMCkgKyAiICgiICsgY3JlYXRvcihvKSArICIpXG4iKTsKKyAgICAgIGVsc2UKKyAgICAgICAgbG9nX2ZpbGUoIlJFRFVDRV9IUCIsICIgPz9cbiIpOworICAgIH0KKyAgfQorI2VuZGlmCisgIGlmICgoaT1RdWVyeVByb3AoUF9IUCkpIDw9IGRhbSkKKyAgICByZXR1cm4gU2V0UHJvcChQX0hQLDEpOworICByZXR1cm4gU2V0UHJvcChQX0hQLCBpIC0gZGFtKTsKK30KKworcHVibGljIGludCByZXN0b3JlX2hpdF9wb2ludHMoaW50IGhlYWwpCit7CisgIHJldHVybiByZWR1Y2VfaGl0X3BvaW50cygtaGVhbCk7Cit9CisKK3B1YmxpYyB2YXJhcmdzIGludCBkcmlua19hbGNvaG9sKGludCBzdHJlbmd0aCxpbnQgdGVzdG9ubHksIHN0cmluZyBteXRleHQpCit7IGludCBhbGMsYWRkLHJlczsKKworICBhZGQ9QUxDT0hPTF9WQUxVRShzdHJlbmd0aCk7CisgIHJlcz1Vc2VTa2lsbChTS19CT09aRSwoWworICAgICAgU0lfU0tJTExBUkcgOiBhZGQsCisgICAgICBTSV9URVNURkxBRyA6IDFdKSk7IC8vIEthbm4gZGVyIFNwaWVsZXIgZ3V0IHNhdWZlbj8KKyAgaWYgKGludHAocmVzKSAmJiByZXM+MCkgYWRkPXJlczsKKyAgYWxjPVF1ZXJ5UHJvcChQX0FMQ09IT0wpK2FkZDsKKyAgaWYgKChhbGMgPj0gUXVlcnlQcm9wKFBfTUFYX0FMQ09IT0wpKSAmJiAhSVNfTEVBUk5JTkcodGhpc19vYmplY3QoKSkpeworICAgIGlmKCF0ZXN0b25seSkKKyAgICAgIHRlbGxfb2JqZWN0KE1FLG15dGV4dHx8IlNvIGVpbiBQZWNoLCBEdSBoYXN0IGFsbGVzIHZlcnNjaHVldHRldC5cbiIpOworICAgIHJldHVybiAwOworICB9CisgIGlmKHRlc3Rvbmx5KXJldHVybiAxOworICBVc2VTa2lsbChTS19CT09aRSwoWyBTSV9TS0lMTEFSRyA6IEFMQ09IT0xfVkFMVUUoc3RyZW5ndGgpIF0pKTsKKyAgaWYoYWxjIDwgMCkgYWxjID0gMDsKKyAgaWYoIWFsYykgdGVsbF9vYmplY3QoTUUsICJEdSBiaXN0IHN0b2NrbnVlY2h0ZXJuLlxuIik7CisgIFNldFByb3AoUF9BTENPSE9MLCBhbGMpOworICByZXR1cm4gMTsKK30KKworcHVibGljIHZhcmFyZ3MgaW50IGRyaW5rX3NvZnQoaW50IHN0cmVuZ3RoLCBpbnQgdGVzdG9ubHksIHN0cmluZyBteXRleHQpCit7IGludCBzb2FrZWQ7CisKKyAgc29ha2VkID0gUXVlcnlQcm9wKFBfRFJJTkspOworICBpZigoc29ha2VkICsgc3RyZW5ndGggPiBRdWVyeVByb3AoUF9NQVhfRFJJTkspKSAmJgorICAgICAhSVNfTEVBUk5JTkcodGhpc19vYmplY3QoKSkpeworICAgIGlmKCF0ZXN0b25seSkKKyAgICAgdGVsbF9vYmplY3QoTUUsIG15dGV4dHx8CisgICAgICAgIk5lZSwgc28gdmllbCBrYW5uc3QgRHUgbW9tZW50YW4gZWNodCBuaWNodCB0cmlua2VuLlxuIiApOworICAgIHJldHVybiAwOworICB9CisgIGlmKHRlc3Rvbmx5KXJldHVybiAxOworICBpZigoc29ha2VkICs9IERSSU5LX1ZBTFVFKHN0cmVuZ3RoKSkgPCAwKSBzb2FrZWQgPSAwOworICBpZighc29ha2VkKSB0ZWxsX29iamVjdChNRSwgIkRpciBrbGVidCBkaWUgWnVuZ2UgYW0gR2F1bWVuLlxuIik7CisgIFNldFByb3AoUF9EUklOSywgc29ha2VkKTsKKyAgcmV0dXJuIDE7Cit9CisKK3B1YmxpYyB2YXJhcmdzIGludCBlYXRfZm9vZChpbnQgc3RyZW5ndGgsIGludCB0ZXN0b25seSwgc3RyaW5nIG15dGV4dCkKK3sgaW50IHN0dWZmZWQ7CisKKyAgc3R1ZmZlZCA9IFF1ZXJ5UHJvcChQX0ZPT0QpOworICBpZiAoKHN0dWZmZWQgKyBzdHJlbmd0aCA+IFF1ZXJ5UHJvcChQX01BWF9GT09EKSkgJiYKKyAgICAgICFJU19MRUFSTklORyh0aGlzX29iamVjdCgpKSkKKyAgeworICAgIGlmKCF0ZXN0b25seSkKKyAgICAgICAgdGVsbF9vYmplY3QoTUUsCisgICAgICAgICAgICBteXRleHQgfHwgIkRhcyBpc3QgdmllbCB6dSB2aWVsIGZ1ZXIgRGljaCEgV2llIHdhZXJzIG1pdCBldHdhcyAiCisgICAgICAgICAgICAibGVpY2h0ZXJlbT9cbiIpOworICAgIHJldHVybiAwOworICB9CisgIGlmKHRlc3Rvbmx5KXJldHVybiAxOworICBzdHVmZmVkICs9IEZPT0RfVkFMVUUoc3RyZW5ndGgpOworICBpZihzdHVmZmVkIDwgMCkgc3R1ZmZlZCA9IDA7CisgIGlmKCFzdHVmZmVkKSB0ZWxsX29iamVjdChNRSwgIldhcyBydW1wZWx0IGRlbm4gZGEgaW4gRGVpbmVtIEJhdWNoP1xuIik7CisgIFNldFByb3AoUF9GT09ELCBzdHVmZmVkKTsKKyAgcmV0dXJuIDE7Cit9CisKK3B1YmxpYyBpbnQgYnVmZmVyX2hwKGludCB2YWwsaW50IHJhdGUpCit7CisgIGludCBkaWY7CisKKyAgaWYodmFsPD0wIHx8IHJhdGU8PTApcmV0dXJuIDA7CisgIGlmKHZhbCA8IHJhdGUpcmF0ZSA9IHZhbDsKKyAgaWYocmF0ZT4yMCkgcmF0ZT0yMDsKKworICAvKiBDaGVjayBmb3IgQnVmZmVyT3ZlcmZsb3cgKi8KKyAgaWYoKGRpZj0oaHBfYnVmZmVyWzBdK3ZhbCktUXVlcnlQcm9wKFBfTUFYX0hQKSkgPiAwKXZhbC09ZGlmOworICBpZih2YWw8PTApcmV0dXJuIDA7CisKKyAgaHBfYnVmZmVyWzBdICs9IHZhbDsKKyAgaHBfYnVmZmVyWzErcmF0ZV0gKz0gdmFsOworICBpZihyYXRlID4gaHBfYnVmZmVyWzFdKWhwX2J1ZmZlclsxXSA9IHJhdGU7CisKKyAgcmV0dXJuIGhwX2J1ZmZlclswXTsKK30KKworcHVibGljIGludCBidWZmZXJfc3AoaW50IHZhbCxpbnQgcmF0ZSkKK3sKKyAgaW50IGRpZjsKKworICBpZih2YWw8PTAgfHwgcmF0ZTw9MClyZXR1cm4gMDsKKyAgaWYodmFsIDwgcmF0ZSlyYXRlID0gdmFsOworICBpZihyYXRlPjIwKSByYXRlPTIwOworCisgIC8qIENoZWNrIGZvciBCdWZmZXJPdmVyZmxvdyAqLworICBpZigoZGlmPShzcF9idWZmZXJbMF0rdmFsKS1RdWVyeVByb3AoUF9NQVhfU1ApKSA+IDApdmFsLT1kaWY7CisgIGlmKHZhbDw9MClyZXR1cm4gMDsKKworICBzcF9idWZmZXJbMF0gKz0gdmFsOworICBzcF9idWZmZXJbMStyYXRlXSArPSB2YWw7CisgIGlmKHJhdGUgPiBzcF9idWZmZXJbMV0pc3BfYnVmZmVyWzFdID0gcmF0ZTsKKworICByZXR1cm4gc3BfYnVmZmVyWzBdOworfQorCitwcm90ZWN0ZWQgdm9pZCB1cGRhdGVfYnVmZmVycygpCit7IGludCBpLCByYXRlLCBtYXg7CisKKyAgcmF0ZT0wOworICBtYXg9MDsKKyAgZm9yKGk9MTtpPD0yMDtpKyspeworICAgIGlmKG1lbWJlcihocF9idWZmZXIsIGkrMSkpCisgICAgICBpZihocF9idWZmZXJbaSsxXTw9MCkKKyAgICAgICAgaHBfYnVmZmVyID0gbV9kZWxldGUoaHBfYnVmZmVyLGkrMSk7CisgICAgICBlbHNleworICAgICAgICBtYXgrPWhwX2J1ZmZlcltpKzFdOworICAgICAgICByYXRlPWk7CisgICAgICB9CisgIH0KKworICBocF9idWZmZXJbMF09bWF4OworICBocF9idWZmZXJbMV09cmF0ZTsKKyAgcmF0ZT0wOworICBtYXg9MDsKKyAgZm9yKGk9MTtpPD0yMDtpKyspeworICAgIGlmKG1lbWJlcihzcF9idWZmZXIsIGkrMSkpCisgICAgICBpZihzcF9idWZmZXJbaSsxXTw9MCkKKyAgICAgICAgc3BfYnVmZmVyID0gbV9kZWxldGUoc3BfYnVmZmVyLGkrMSk7CisgICAgICBlbHNleworICAgICAgICBtYXgrPXNwX2J1ZmZlcltpKzFdOworICAgICAgICByYXRlPWk7CisgICAgICB9CisgIH0KKyAgc3BfYnVmZmVyWzBdPW1heDsKKyAgc3BfYnVmZmVyWzFdPXJhdGU7Cit9CisKK3B1YmxpYyBpbnQgY2hlY2tfdGltZWRfa2V5KHN0cmluZyBrZXkpIHsKKworICAvLyBrZWluZSAwIGFscyBrZXkgKFR5cCB3aXJkIHBlciBSVFRDIGdlcHJ1ZWZ0KQorICBpZiAoIWtleSkKKyAgICByZXR1cm4gMDsKKyAgbWFwcGluZyB0bWFwPVF1ZXJ5KFBfVElNSU5HX01BUCwgRl9WQUxVRSk7CisgIGlmICghbWFwcGluZ3AodG1hcCkpIHsKKyAgICB0bWFwPShbXSk7CisgICAgU2V0KFBfVElNSU5HX01BUCwgdG1hcCwgRl9WQUxVRSk7CisgIH0KKyAgLy8gV2VubiBrZXkgbm9jaCBuaWNodCBhYmdlbGF1ZmVuLCBBYmxhdWZ6ZWl0cHVua3QgenVydWVja2dlYmVuLgorICAvLyBTb25zdCAwIChrZXkgZnJlaSkKKyAgcmV0dXJuICh0aW1lKCkgPCB0bWFwW2tleV0pICYmIHRtYXBba2V5XTsKK30KKworcHVibGljIGludCBjaGVja19hbmRfdXBkYXRlX3RpbWVkX2tleShpbnQgZHVyYXRpb24sc3RyaW5nIGtleSkgeworCisgIC8vIHdlbm4ga2V5IG5vY2ggZ2VzcGVycnQsIGRpZSB6ZWl0IGRlciBuYWVjaHN0ZW4gVmVyZnVlZ2JhcmtlaXQKKyAgLy8genVydWVja2dlYmVuLgorICBpbnQgcmVzID0gY2hlY2tfdGltZWRfa2V5KGtleSk7CisgIGlmIChyZXMpIHsKKyAgICByZXR1cm4gcmVzOworICB9CisKKyAgLy8gZHVyYXRpb24gPD0gMCBpc3QgdW5zaW5uaWcuIEFiZXIga2V5IGlzdCBuaWNodCBtZWhyIGdlc3BlcnJ0LCBkLmguIHRpbWUoKQorICAvLyBpc3QgZWluIHNpbm52b2xsZXIgUnVlY2tnYWJld2VydC4KKyAgaWYgKGR1cmF0aW9uIDw9IDApCisgICAgcmV0dXJuIHRpbWUoKTsKKyAKKyAgbWFwcGluZyB0bWFwID0gUXVlcnkoUF9USU1JTkdfTUFQLEZfVkFMVUUpOworICB0bWFwW2tleV09dGltZSgpK2R1cmF0aW9uOworICAKKyAgLy8gc3BlaWNoZXJuIHBlciBTZXRQcm9wKCkgdW5ub2V0aWcsIGRhIG1hbiBkYXMgTWFwcGluZyBkaXJla3QgYWVuZGVydCwKKyAgLy8ga2VpbmUgS29waWUuCisgIC8vU2V0UHJvcChQX1RJTUlOR19NQVAsIHRtYXApOworICAKKyAgcmV0dXJuIC0xOyAvLyBFcmZvbGcuCit9CisKK3Byb3RlY3RlZCB2b2lkIGV4cGlyZV90aW1pbmdfbWFwKCkgeworICAKKyAgbWFwcGluZyB0bWFwID0gUXVlcnkoUF9USU1JTkdfTUFQLCBGX1ZBTFVFKTsKKyAgaWYgKCFtYXBwaW5ncCh0bWFwKSB8fCAhc2l6ZW9mKHRtYXApKQorICAgIHJldHVybjsKKyAgZm9yZWFjaChzdHJpbmcga2V5LCBpbnQgZW5kdGltZTogdG1hcCkgeworICAgIGlmIChlbmR0aW1lIDwgdGltZSgpKQorICAgICAgbV9kZWxldGUodG1hcCwga2V5KTsKKyAgfQorICAvLyBzcGVpY2hlcm4gcGVyIFNldFByb3AoKSB1bm5vZXRpZywgZGEgbWFuIGRhcyBNYXBwaW5nIGRpcmVrdCBhZW5kZXJ0LAorICAvLyBrZWluZSBLb3BpZS4KK30KKworcHJvdGVjdGVkIHZvaWQgaGVhcnRfYmVhdCgpCit7CisgICAgaWYgKCAhdGhpc19vYmplY3QoKSApCisgICAgICAgIHJldHVybjsKKworICAgIGF0dHJpYnV0ZV9oYigpOworCisgICAgLy8gQWxzIEdlaXN0IGxlaWRldCBtYW4gbmljaHQgdW50ZXIgc28gd2VsdGxpY2hlbiBEaW5nZW4gd2llCisgICAgLy8gQWxrb2hvbCwgR2lmdCZDbyAuLi4KKyAgICBpZiAoIFF1ZXJ5UHJvcChQX0dIT1NUKSApCisgICAgICAgIHJldHVybjsKKworICAgIGludCBocG9pc29uID0gUXVlcnlQcm9wKFBfUE9JU09OKTsKKyAgICBpbnQgcmxvY2sgPSBRdWVyeVByb3AoUF9OT19SRUdFTkVSQVRJT04pOworICAgIGludCBocCA9IFF1ZXJ5UHJvcChQX0hQKTsKKyAgICBpbnQgc3AgPSBRdWVyeVByb3AoUF9TUCk7CisgICAgaW50IGFsYzsKKworICAgIC8vIFdlbm4gQWxrb2hvbCBnZXRydW5rZW46IEFsa29ob2xhdXN3aXJrdW5nZW4/CisgICAgaWYgKCAoYWxjID0gUXVlcnlQcm9wKFBfQUxDT0hPTCkpICYmICFyYW5kb20oNDApICl7CisgICAgICAgIGludCBuOworICAgICAgICBzdHJpbmcgZ2lsZGU7CisgICAgICAgIG9iamVjdCBvYjsKKworICAgICAgICBuID0gcmFuZG9tKCA1ICogKGFsYyAtIDEpL1F1ZXJ5UHJvcChQX01BWF9BTENPSE9MKSApOworCisgICAgICAgIHN3aXRjaCAobil7CisgICAgICAgIGNhc2UgQUxDX0VGRkVDVF9ISUNLOgorICAgICAgICAgICAgc2F5KCBjYXBpdGFsaXplKG5hbWUoIFdFUiwgMSApKSArICIgc2FndDogPEhpY2s+IVxuIiApOworICAgICAgICAgICAgd3JpdGUoICI8SGljaz4hIE9oLCBUc2NodWxkaWd1bmcuXG4iICk7CisgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgIAorICAgICAgICBjYXNlIEFMQ19FRkZFQ1RfU1RVTUJMRToKKyAgICAgICAgICAgIHNheSggY2FwaXRhbGl6ZShuYW1lKCBXRVIsIDEgKSkgKyAiIHN0b2xwZXJ0IHVlYmVyICIgKworICAgICAgICAgICAgICAgICBRdWVyeVBvc3NQcm9ub3VuKCBGRU1BTEUsIFdFTiApICsgIiBGdWVzc2UuXG4iICk7CisgICAgICAgICAgICB3cml0ZSggIkR1IHN0b2xwZXJzdC5cbiIgKTsKKyAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgCisgICAgICAgIGNhc2UgQUxDX0VGRkVDVF9MT09LRFJVTks6CisgICAgICAgICAgICBzYXkoIGNhcGl0YWxpemUobmFtZSggV0VSLCAxICkpICsgIiBzaWVodCBiZXRydW5rZW4gYXVzLlxuIiApOworICAgICAgICAgICAgd3JpdGUoICJEdSBmdWVobHN0IERpY2ggYmVub21tZW4uXG4iICk7CisgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgIAorICAgICAgICBjYXNlIEFMQ19FRkZFQ1RfUlVFTFBTOgorICAgICAgICAgICAgc2F5KCBjYXBpdGFsaXplKG5hbWUoIFdFUiwgMSApKSArICIgcnVlbHBzdC5cbiIgKTsKKyAgICAgICAgICAgIHdyaXRlKCAiRHUgcnVlbHBzdC5cbiIgKTsKKyAgICAgICAgICAgIGJyZWFrOworICAgICAgICB9CisgICAgICAgCisgICAgICAgIC8vIEdpbGRlIHVuZCBFbnZpcm9ubWVudCBpbmZvcm1pZXJlbiB1ZWJlciBBbGtvaG9sYXVzd2lya3VuZy4KKyAgICAgICAgaWYgKCBzdHJpbmdwKGdpbGRlID0gUXVlcnlQcm9wKFBfR1VJTEQpKQorICAgICAgICAgICAgICYmIG9iamVjdHAob2IgPSBmaW5kX29iamVjdCggIi9naWxkZW4vIiArIGdpbGRlICkpICkKKyAgICAgICAgICAgIG9iLT5JbmZvcm1BbGNvaG9sRWZmZWN0KCBNRSwgbiwgQUxDX0VGRkVDVF9BUkVBX0dVSUxEICk7CisgICAgICAgIAorICAgICAgICBpZiAoIGVudmlyb25tZW50KCkgKQorICAgICAgICAgICAgZW52aXJvbm1lbnQoKS0+SW5mb3JtQWxjb2hvbEVmZmVjdCggTUUsIG4sIEFMQ19FRkZFQ1RfQVJFQV9FTlYgKTsKKyAgICB9CisgICAgCisgICAgLy8gQWxrb2hvbCBhYmJhdWVuIHVuZCBldHdhcyBleHRyYSBoZWlsZW4sIGZhbGxzIGVybGF1YnQuCisgICAgaWYgKCBhbGMgJiYgKC0tZGVsYXlfYWxjb2hvbCA8IDApCisgICAgICAgICAmJiAhKHJsb2NrICYgTk9fUkVHX0FMQ09IT0wpICl7CisKKyAgICAgICAgU2V0UHJvcCggUF9BTENPSE9MLCBhbGMgLSAxICk7CisgICAgICAgIAorICAgICAgICBpZiAoICFocG9pc29uICl7CisgICAgICAgICAgICBocCsrOworICAgICAgICAgICAgc3ArKzsKKyAgICAgICAgfQorICAgICAgICAKKyAgICAgICAgZGVsYXlfYWxjb2hvbCA9IFF1ZXJ5UHJvcChQX0FMQ09IT0xfREVMQVkpOworICAgIH0KKworICAgIC8vIFBfRFJJTksgcmVkdXppZXJlbiwgZmFsbHMgZXJsYXVidC4KKyAgICBpZiAoICgtLWRlbGF5X2RyaW5rIDwgMCkgJiYgIShybG9jayAmIE5PX1JFR19EUklOSykgKXsKKyAgICAgICAgZGVsYXlfZHJpbmsgPSBRdWVyeVByb3AoUF9EUklOS19ERUxBWSk7CisgICAgICAgIFNldFByb3AoIFBfRFJJTkssIFF1ZXJ5UHJvcChQX0RSSU5LKSAtIDEgKTsKKyAgICB9CisKKyAgICAvLyBQX0ZPT0QgcmVkdXppZXJlbiwgZmFsbHMgZXJsYXVidC4KKyAgICBpZiAoICgtLWRlbGF5X2Zvb2QgPCAwKSAmJiAhKHJsb2NrICYgTk9fUkVHX0ZPT0QpICl7CisgICAgICAgIGRlbGF5X2Zvb2QgPSBRdWVyeVByb3AoUF9GT09EX0RFTEFZKTsKKyAgICAgICAgU2V0UHJvcCggUF9GT09ELCBRdWVyeVByb3AoUF9GT09EKSAtIDEgKTsKKyAgICB9CisKKyAgICAvLyBSZWdlbmVyYXRpb24gYXVzIGRlbSBIUC1QdWZmZXIKKyAgICAvLyBIaWVyYmVpIHdpcmQgendhciBudXIgZ2VoZWlsdCwgd2VubiBkYXMgZXJsYXVidCBpc3QsIGFiZXIgZGVyIFB1ZmZlcgorICAgIC8vIG11c3MgdHJvdHpkZW0gYWJnZWFyYmVpdGV0L3JlZHV6aWVydCB3ZXJkZW4sIGRhIERlbGZlbiBzb25zdCBlaW5lCisgICAgLy8gbW9iaWxlIFRhbmtlIGtyaWVnZW4uIChLZWluZSBIZWlsdW5nIGltIEhlbGxlbiwgUHVmZmVyIGJsZWlidCBzb25zdAorICAgIC8vIGtvbnN0YW50IHVuZCBrYW5uIGJlaSBCZWRhcmYgdWViZXIgZHVua2VsbWFjaGVuZGUgSXRlbXMgYWJnZXJ1ZmVuCisgICAgLy8gd2VyZGVuLikKKyAgICBpbnQgdmFsOworICAgIGlmIChocF9idWZmZXJbMF0pIHsKKyAgICAgICAgaW50IHJhdGUgPSBocF9idWZmZXJbMV07CisgICAgICAgIHZhbCA9IGhwX2J1ZmZlcltyYXRlICsgMV07CisgICAgCisgICAgICAgIGlmICggdmFsID4gcmF0ZSApCisgICAgICAgICAgICB2YWwgPSByYXRlOworICAgICAgICBocF9idWZmZXJbMF0gLT0gdmFsOworICAgICAgICBocF9idWZmZXJbcmF0ZSArIDFdIC09IHZhbDsKKyAgICAgICAgaWYgKCBocF9idWZmZXJbcmF0ZSArIDFdIDw9IDAgKQorICAgICAgICAgICAgdXBkYXRlX2J1ZmZlcnMoKTsKKyAgICB9CisgICAgLy8gSmV0enQgUmVnZW5lcmF0aW9uIGF1cyBkZW0gUHVmZmVyIGR1cmNoZnVlaHJlbiwgYWJlciBudXIgd2VubiBlcmxhdWJ0LgorICAgIGlmICggdmFsICYmICEocmxvY2sgJiBOT19SRUdfQlVGRkVSX0hQKSApCisgICAgICAgIGhwICs9IHZhbDsgCisgICAgLy8gbm9ybWFsZXMgSGVpbGVuLCBmYWxscyBrZWluZSBSZWdlbmVyYXRpb24gYXVzIGRlbSBQdWZmZXIgZXJmb2xndGUgdW5kCisgICAgLy8gZXMgZXJsYXVidCBpc3QuCisgICAgZWxzZSBpZiAoICgtLWRlbGF5X2hlYWwgPCAwKSAmJiAhKHJsb2NrICYgTk9fUkVHX0hQKSApeworICAgICAgICBkZWxheV9oZWFsID0gUXVlcnlQcm9wKFBfSFBfREVMQVkpOworICAgICAgICBpZiAoICFocG9pc29uICkKKyAgICAgICAgICAgIGhwKys7CisgICAgfQorCisgICAgLy8gR2xlaWNoZXMgU3BpZWwgamV0enQgZnVlciBkZW4gU1AtUHVmZmVyIChzLm8uKQorICAgIHZhbD0wOworICAgIGlmICggc3BfYnVmZmVyWzBdICkgeworICAgICAgICBpbnQgcmF0ZSA9IHNwX2J1ZmZlclsxXTsKKyAgICAgICAgdmFsID0gc3BfYnVmZmVyW3JhdGUgKyAxXTsKKyAgICAgICAgCisgICAgICAgIGlmICggdmFsID4gcmF0ZSApCisgICAgICAgICAgICB2YWwgPSByYXRlOworICAgICAgICAKKyAgICAgICAgc3BfYnVmZmVyWzBdIC09IHZhbDsKKyAgICAgICAgc3BfYnVmZmVyW3JhdGUgKyAxXSAtPSB2YWw7CisgCisgICAgICAgIGlmICggc3BfYnVmZmVyW3JhdGUgKyAxXSA8PSAwICkKKyAgICAgICAgICAgIHVwZGF0ZV9idWZmZXJzKCk7CisgICAgfQorICAgIC8vIFJlZ2VuZXJhdGlvbiBlcmxhdWJ0PworICAgIGlmICggdmFsICYmICEocmxvY2sgJiBOT19SRUdfQlVGRkVSX1NQKSApCisgICAgICAgICBzcCArPSB2YWw7CisgICAgLy8gV2VubiBuaWNodCwgbm9ybWFsZXMgSG9jaGlkZWxuIHZlcnN1Y2hlbi4KKyAgICBlbHNlIGlmICggKC0tZGVsYXlfc3AgPCAwKSAmJiAhKHJsb2NrICYgTk9fUkVHX1NQKSApeworICAgICAgICBkZWxheV9zcCA9IFF1ZXJ5UHJvcChQX1NQX0RFTEFZKTsKKyAgICAgICAgaWYgKCAhaHBvaXNvbiApCisgICAgICAgICAgICBzcCsrOworICAgIH0KKworICAgIGlmICggaHBvaXNvbiAmJiAoaW50ZXJhY3RpdmUoTUUpIHx8ICFxdWVyeV9vbmNlX2ludGVyYWN0aXZlKE1FKSkgKXsKKyAgICAgICAgLy8gVmFuaW9uLCAyNi4xMC4wMworICAgICAgICAvLyBXZW5uIF9zZXRfcG9pc29uKCkgcGVyIFNFVF9NRVRIT0QgdWViZXJzY2hyaWViZW4gd2lyZCwga2FubgorICAgICAgICAvLyBuaWNodCBzaWNoZXJnZXN0ZWxsdCB3ZXJkZW4sIGRhc3MgcG9pc29uIGltbWVyIGdyb2Vzc2VyIDAgaXN0CisgICAgICAgIC8vIERhaGVyIG11c3MgaGllciBlaW4gVGVzdCByZWluLCBzbyB0ZXVlciBkYXMgYXVjaCBpc3QgOigKKyAgICAgICAgaWYgKC0taHBvaXNvbiA8IDApCisgICAgICAgICAgaHBvaXNvbj0wOworICAgICAgICAKKyAgICAgICAgaWYgKCAtLWRlbGF5X3BvaXNvbiA8IDAgKXsKKyAgICAgICAgICAgIGRlbGF5X3BvaXNvbiA9IFF1ZXJ5UHJvcChQX1BPSVNPTl9ERUxBWSkKKyAgICAgICAgICAgICAgICArIHJhbmRvbShQT0lTT05fTUVSQ1lfREVMQVkpOworICAgICAgICAgICAgaHAgLT0gaHBvaXNvbjsKKworICAgICAgICAgICAgaWYgKCBocCA8IDAgKXsKKyAgICAgICAgICAgICAgICB0ZWxsX29iamVjdCggTUUsICJPaCB3ZWggLSBkYXMgR2lmdCB3YXIgenV2aWVsIGZ1ZXIgRGljaCFcbiIKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKyAiRHUgc3RpcmJzdC5cbiIgKTsKKyAgICAgICAgICAgICAgICAKKyAgICAgICAgICAgICAgICBpZiAoIHF1ZXJ5X29uY2VfaW50ZXJhY3RpdmUoTUUpICl7CisgICAgICAgICAgICAgICAgICAgIGNyZWF0ZV9raWxsX2xvZ19lbnRyeSggIlZlcmdpZnR1bmciLCAwICk7CisgICAgICAgICAgICAgICAgICAgIAorICAgICAgICAgICAgICAgICAgICAvLyBCZWltIEdpZnR0b2QgZ2lidCBlcyBrZWluZW4gS2lsbGVyLiBBYmVyIGF1ZiBkaWVzZSBBcnQKKyAgICAgICAgICAgICAgICAgICAgLy8gZXJrZW5udCBkZXIgVG9kZXNyYXVtIGRpZSBVcnNhY2hlIGtvcnJla3QgdW5kIGdpYnQgZGllCisgICAgICAgICAgICAgICAgICAgIC8vIHJpY2h0aWdlIE1lbGR1bmcgYXVzLgorICAgICAgICAgICAgICAgICAgICBTZXRQcm9wKCBQX0tJTExFUiwgImdpZnQiICk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIAorICAgICAgICAgICAgICAgIGRpZSgxKTsKKyAgICAgICAgICAgICAgICByZXR1cm47CisgICAgICAgICAgICB9CisgICAgICAgICAgICAKKyAgICAgICAgICAgIGlmICggKGhwb2lzb24gPCAzIHx8ICFxdWVyeV9vbmNlX2ludGVyYWN0aXZlKE1FKSApCisgICAgICAgICAgICAgICAgICYmIC0tZHJvcF9wb2lzb24gPCAwKQorICAgICAgICAgICAgeworICAgICAgICAgICAgICAgIC8vIEdpZnRsZXZlbCBlaW5zIHJlZHV6aWVyZW4uIGhwb2lzb24gd3VyZGUgb2JlbiBzY2hvbgorICAgICAgICAgICAgICAgIC8vIHJlZHV6aWVydCwgZC5oLiBlaW5mYWNoIGhwb2lzb24gaW4gUF9QT0lTT04gc2NocmVpYmVuLgorICAgICAgICAgICAgICAgIC8vIGRhYmVpIHdpcmQgZGFubiBhdWNoIGdnZi4gZHJvcF9wb2lzb24gcmljaHRpZyBnZXNldHp0LgorICAgICAgICAgICAgICAgIFNldFByb3AoIFBfUE9JU09OLCBocG9pc29uICk7CisgICAgICAgICAgICAgICAgaWYgKCAhaHBvaXNvbiApCisgICAgICAgICAgICAgICAgICAgIHRlbGxfb2JqZWN0KCBNRSwgIkR1IHNjaGVpbnN0IGRpZSBWZXJnaWZ0dW5nICIKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAidWViZXJ3dW5kZW4genUgaGFiZW4uXG4iICk7ICAKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICAKKyAgICAgICAgaWYgKCBocG9pc29uICYmICFyYW5kb20oMTUpICkKKyAgICAgICAgICAgIHN3aXRjaCAoIGhwKjEwMC9RdWVyeVByb3AoUF9NQVhfSFApICl7CisgICAgICAgICAgICBjYXNlIDcxLi4xMDAgOgorICAgICAgICAgICAgICAgIHdyaXRlKCAiRHUgZnVlaGxzdCBEaWNoIG5pY2h0IGd1dC5cbiIgKTsKKyAgICAgICAgICAgICAgICBzYXkoIGNhcGl0YWxpemUobmFtZShXRVIpKSArCisgICAgICAgICAgICAgICAgICAgICAiIHNpZWh0IGV0d2FzIGJlbm9tbWVuIGF1cy5cbiIgKTsKKyAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgICAgICAKKyAgICAgICAgICAgIGNhc2UgNDYuLjcwIDoKKyAgICAgICAgICAgICAgICB3cml0ZSggIkRpciBpc3Qgc2Nod2luZGxpZyB1bmQgRGVpbiBNYWdlbiByZXZvbHRpZXJ0LlxuIiApOworICAgICAgICAgICAgICAgIHNheSggY2FwaXRhbGl6ZShuYW1lKFdFUikpICsgIiB0YXVtZWx0IGVpbiB3ZW5pZy5cbiIgKTsKKyAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgICAgICAKKyAgICAgICAgICAgIGNhc2UgMjYuLjQ1IDoKKyAgICAgICAgICAgICAgICB3cml0ZSggIkRpciBpc3QgaGVpc3MuIER1IGZ1ZWhsc3QgRGljaCBzY2h3YWNoLiBLb3Bmd2VoICIKKyAgICAgICAgICAgICAgICAgICAgICAgImhhc3QgRHUgYXVjaC5cbiIgKTsKKyAgICAgICAgICAgICAgICBzYXkoIGNhcGl0YWxpemUobmFtZShXRVIpKSArICIgZ2x1ZWh0IGRpcmVrdCB1bmQgc2NoZWludCAiCisgICAgICAgICAgICAgICAgICAgICAiZ3Jvc3NlIFNjaHdpZXJpZ2tlaXRlbiB6dSBoYWJlbi5cbiIgKTsKKyAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgICAgICAKKyAgICAgICAgICAgIGNhc2UgMTEuLjI1IDoKKyAgICAgICAgICAgICAgICB3cml0ZSggIkR1IGZ1ZWhsc3QgRGljaCBiZXNjaGlzc2VuLiBBbGxlcyB0dXQgd2VoLCB1bmQgRHUgIgorICAgICAgICAgICAgICAgICAgICAgICAic2llaHN0IG51ciBub2NoIHVuc2NoYXJmLlxuIiApOworICAgICAgICAgICAgICAgIHNheSggY2FwaXRhbGl6ZShuYW1lKFdFUikpICsgIiB0YXVtZWx0IHVuZCBzdG9laG50IHVuZCAiCisgICAgICAgICAgICAgICAgICAgICAia2FubiBnZXJhZGUgbm9jaCB2ZXJtZWlkZW4sIGhpbnp1ZmFsbGVuLlxuIiApOworICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgICAgIAorICAgICAgICAgICAgY2FzZSAwLi4xMCA6CisgICAgICAgICAgICAgICAgd3JpdGUoIGJyZWFrX3N0cmluZyggIkR1IHNpZWhzdCBmYXN0IG5pY2h0cyBtZWhyIHVuZCBrYW5uc3QgIgorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJEaWNoIG51ciBub2NoIHVudGVyIGdyb2Vzc3RlbiBTY2htZXJ6ZW4gIgorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJiZXdlZ2VuLiBBYmVyIGJhbGQgdHV0IG5pY2h0cyBtZWhyIHdlaCIKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiLi4uIiwgNzggKSApOworICAgICAgICAgICAgICAgIHNheSggYnJlYWtfc3RyaW5nKCBjYXBpdGFsaXplKG5hbWUoV0VSKSkgKyAiIGdsdWVodCB3aWUgIgorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiaW0gRmllYmVyLCBrYW5uIHNpY2gga2F1bSBub2NoIHJ1ZWhyZW4gIgorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAidW5kIGhhdCBlaW4gc2NobWVyenZlcnplcnJ0ZXMgR2VzaWNodC5cbiIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDc4ICkgKTsKKyAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgIH0KKyAgICB9CisKKyAgICBTZXRQcm9wKCBQX0hQLCBocCApOworICAgIFNldFByb3AoIFBfU1AsIHNwICk7Cit9CisKK3B1YmxpYyBpbnQgQWRkRXhwKCBpbnQgZSApCit7CisgIGludCBleHBlcmllbmNlOworICBzdHJpbmcgZm47CisgIG1peGVkIGxhc3Q7CisKKyAgZXhwZXJpZW5jZSA9IFF1ZXJ5UHJvcChQX1hQKTsKKworICBpZiAoIFF1ZXJ5UHJvcChQX0tJTExTKSA+IDEgJiYgZSA+IDAgKQorICAgICAgcmV0dXJuIGV4cGVyaWVuY2U7CisKKyAgZm4gPSBpbXBsb2RlKCBleHBsb2RlKCBvYmplY3RfbmFtZSggZW52aXJvbm1lbnQoKSB8fCB0aGlzX29iamVjdCgpICksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIi8iIClbMC4uPDJdLCAiLyIgKTsKKworICBpZiAoIHBvaW50ZXJwKGxhc3QgPSBRdWVyeShQX0xBU1RfWFApKSAmJiBzaXplb2YobGFzdCkgPT0gMiAmJiBsYXN0WzBdID09IGZuICkKKyAgICAgIFNldCggUF9MQVNUX1hQLCAoeyBmbiwgbGFzdFsxXStlIH0pICk7CisgIGVsc2UKKyAgICAgIFNldCggUF9MQVNUX1hQLCAoeyBmbiwgZSB9KSApOworCisgIGlmICggKGV4cGVyaWVuY2UgKz0gZSkgPCAwICkKKyAgICAgIGV4cGVyaWVuY2UgPSAwOworCisgIHJldHVybiBTZXRQcm9wKCBQX1hQLCBleHBlcmllbmNlICk7Cit9CisKK3N0YXRpYyA8c3RyaW5nfGludD4qIF9zZXRfbGFzdF94cCggPGludHxzdHJpbmc+KiBsYXN0ICkKK3sKKyAgICBpZiAoICFwb2ludGVycChsYXN0KSB8fCBzaXplb2YobGFzdCkgIT0gMiB8fCAhc3RyaW5ncChsYXN0WzBdKSB8fAorICAgICAgICAgIWludHAobGFzdFsxXSkgKQorICAgICAgICByZXR1cm4gUXVlcnkoUF9MQVNUX1hQKTsKKyAgICBlbHNlCisgICAgICAgIHJldHVybiBTZXQoIFBfTEFTVF9YUCwgbGFzdCApOworfQorCisKK3N0YXRpYyBpbnQgX3NldF9hbGlnbihpbnQgYSkKK3sKKyAgaWYgKGE8LTEwMDApIGEgPSAtMTAwMDsKKyAgaWYgKGE+MTAwMCkgYSA9IDEwMDA7CisgIHJldHVybiBTZXQoUF9BTElHTiwgYSk7Cit9CisKKworc3RhdGljIGludCBfc2V0X2hwKCBpbnQgaHAgKQoreworICAgIGlmICggUXVlcnlQcm9wKFBfR0hPU1QpICkKKyAgICAgICAgcmV0dXJuIFF1ZXJ5UHJvcChQX0hQKTsKKworICAgIGlmICggaHAgPCAwICkKKyAgICAgICAgcmV0dXJuIFNldCggUF9IUCwgMCApOworCisgICAgaWYgKCBocCA+IFF1ZXJ5UHJvcChQX01BWF9IUCkgKQorICAgICAgICByZXR1cm4gU2V0KCBQX0hQLCBRdWVyeVByb3AoUF9NQVhfSFApLCBGX1ZBTFVFICk7CisKKyAgICByZXR1cm4gU2V0KCBQX0hQLCBocCwgRl9WQUxVRSApOworfQorCitzdGF0aWMgaW50IF9zZXRfc3AoIGludCBzcCApCit7CisgICAgLy9laW5pZ2UgTGV1dGUgc2NocmVpYmVuIGZsb2F0cyBpbiBkaWUgUF9IUC4gOi0oCisgICAgaWYgKCFpbnRwKHNwKSkgeworCXNwPXRvX2ludChzcCk7CisJLy9qYSwgZXMgaXN0IHRldWVyLiBBYmVyIGljaCB3aWxsIHdpc3Nlbiwgd2VycyBpc3QuIEthbm4gdm9yCisJLy9uYWVjaHN0ZW0gUmVib290IHdpZWRlciByYXVzLgorCWxvZ19maWxlKCJJTExFR0FMX1RZUEUubG9nIixzcHJpbnRmKAorCSAgICAgICJWZXJzdWNoLCBlaW5lbiBuaWNodC1pbnQgaW4gUF9TUCBpbiAlTyB6dSBzY2hyZWliZW46IFxuJU9cbiIsCisJICAgICAgdGhpc19vYmplY3QoKSwKKwkgICAgICBkZWJ1Z19pbmZvKERJTkZPX1RSQUNFLERJVF9TVFJfQ1VSUkVOVCkpKTsKKyAgICB9CisKKyAgICBpZiAoIFF1ZXJ5UHJvcChQX0dIT1NUKSApCisgICAgICAgIFF1ZXJ5UHJvcChQX1NQKTsKKworICAgIGlmICggc3AgPCAwICkKKyAgICAgICAgcmV0dXJuIFNldCggUF9TUCwgMCApOworCisgICAgaWYgKCBzcCA+IFF1ZXJ5UHJvcChQX01BWF9TUCkgKQorICAgICAgICByZXR1cm4gU2V0KCBQX1NQLCBRdWVyeVByb3AoUF9NQVhfU1ApLCBGX1ZBTFVFICk7CisKKyAgICByZXR1cm4gU2V0KCBQX1NQLCBzcCwgRl9WQUxVRSApOworfQorCitzdGF0aWMgaW50IF9zZXRfYWxjb2hvbChpbnQgbikKK3sKKyAgaWYoIWludHAobikpCisgICAgICByYWlzZV9lcnJvcihzcHJpbnRmKAorICAgICAgICAiX3NldF9hbGNvaG9sKCk6IGV4cGVjdGVkIDxpbnQ+LCBnb3QgJS41ME9cbiIsIG4pKTsKKworICBpZiAoUXVlcnlQcm9wKFBfR0hPU1QpKQorICAgIHJldHVybiBRdWVyeShQX0FMQ09IT0wsIEZfVkFMVUUpOworCisgIC8vIG51ciDEbmRlcnVuZ2VuIHVuZCBXZXJ0ZSA+PTAgd2VyZGVuIGdlc2V0enQuLi4KKyAgbiA9IG4gPCAwID8gMCA6IG47CisgIGludCBvbGQgPSBRdWVyeShQX0FMQ09IT0wsIEZfVkFMVUUpOworICBpZiAoIG9sZCA9PSBuKQorICAgIHJldHVybiBvbGQ7CisKKyAgLy8gSG9va3MgYXVmcnVmZW4KKyAgaW50ICpyZXQgPSBIb29rRmxvdyhIX0hPT0tfQUxDT0hPTCwgbik7CisgIC8vIEJlaSBBYmJydWNoIGFsdGVuIFdlcnQgenVydWVja2dlYmVuCisgIHN3aXRjaCAocmV0W0hfUkVUQ09ERV0pIHsKKyAgICBjYXNlIEhfQ0FOQ0VMTEVEOgorICAgICAgcmV0dXJuIG9sZDsKKyAgICBjYXNlIEhfQUxURVJFRDoKKyAgICAgIC8vIHNvbnN0IG5ldWVuIFdlcnQgc2V0emVuCisgICAgICBpZighaW50cChyZXRbSF9SRVREQVRBXSkpCisgICAgICAgICAgcmFpc2VfZXJyb3Ioc3ByaW50ZigKKyAgICAgICAgICAgICJfc2V0X2FsY29ob2woKTogZGF0YSBmcm9tIEhvb2tGbG93KCkgIT0gPGludD46ICUuNTBPXG4iLAorICAgICAgICAgICAgcmV0W0hfUkVUREFUQV0pKTsKKyAgICAgIG4gPSByZXRbSF9SRVREQVRBXTsKKyAgICAgIG4gPSBuIDwgMCA/IDAgOiBuOworCisgICAgLy8gSF9OT19NT0QgaXMgZmFsbHRocm91Z2gKKyAgfQorCisgIHJldHVybiBTZXQoUF9BTENPSE9MLCBuLCBGX1ZBTFVFKTsKK30KKworc3RhdGljIGludCBfc2V0X2RyaW5rKGludCBuKQoreworICBpZighaW50cChuKSkKKyAgICAgIHJhaXNlX2Vycm9yKHNwcmludGYoCisgICAgICAgICJfc2V0X2RyaW5rKCk6IGV4cGVjdGVkIDxpbnQ+LCBnb3QgJS41ME9cbiIsIG4pKTsKKworICBpZiAoUXVlcnlQcm9wKFBfR0hPU1QpKQorICAgIHJldHVybiBRdWVyeShQX0RSSU5LLCBGX1ZBTFVFKTsKKworICAvLyBudXIgxG5kZXJ1bmdlbiB1bmQgV2VydGUgPj0wIHdlcmRlbiBnZXNldHp0Li4uCisgIG4gPSBuIDwgMCA/IDAgOiBuOworICBpbnQgb2xkID0gUXVlcnkoUF9EUklOSywgRl9WQUxVRSk7CisgIGlmICggb2xkID09IG4pCisgICAgcmV0dXJuIG9sZDsKKworICAvLyBIb29rcyBhdWZydWZlbgorICBpbnQgKnJldCA9IEhvb2tGbG93KEhfSE9PS19EUklOSywgbik7CisgIC8vIEJlaSBBYmJydWNoIGFsdGVuIFdlcnQgenVydWVja2dlYmVuCisgIHN3aXRjaCAocmV0W0hfUkVUQ09ERV0pIHsKKyAgICBjYXNlIEhfQ0FOQ0VMTEVEOgorICAgICAgcmV0dXJuIG9sZDsKKyAgICBjYXNlIEhfQUxURVJFRDoKKyAgICAgIC8vIHNvbnN0IG5ldWVuIFdlcnQgc2V0emVuCisgICAgICBpZighaW50cChyZXRbSF9SRVREQVRBXSkpCisgICAgICAgICAgcmFpc2VfZXJyb3Ioc3ByaW50ZigKKyAgICAgICAgICAgICJfc2V0X2RyaW5rKCk6IGRhdGEgZnJvbSBIb29rRmxvdygpICE9IDxpbnQ+OiAlLjUwT1xuIiwKKyAgICAgICAgICAgIHJldFtIX1JFVERBVEFdKSk7CisgICAgICBuID0gcmV0W0hfUkVUREFUQV07CisgICAgICBuID0gbiA8IDAgPyAwIDogbjsKKworICAgIC8vIEhfTk9fTU9EIGlzIGZhbGx0aHJvdWdoCisgIH0KKworICByZXR1cm4gU2V0KFBfRFJJTkssIG4sIEZfVkFMVUUpOworfQorCitzdGF0aWMgaW50IF9zZXRfZm9vZChpbnQgbikKK3sKKyAgaWYoIWludHAobikpCisgICAgICByYWlzZV9lcnJvcihzcHJpbnRmKAorICAgICAgICAiX3NldF9mb29kKCk6IGV4cGVjdGVkIDxpbnQ+LCBnb3QgJS41ME9cbiIsIG4pKTsKKworICBpZiAoUXVlcnlQcm9wKFBfR0hPU1QpKQorICAgIHJldHVybiBRdWVyeShQX0ZPT0QsIEZfVkFMVUUpOworCisgIC8vIG51ciDEbmRlcnVuZ2VuIHVuZCBXZXJ0ZSA+PTAgd2VyZGVuIGdlc2V0enQuLi4KKyAgbiA9IG4gPCAwID8gMCA6IG47CisgIGludCBvbGQgPSBRdWVyeShQX0ZPT0QsIEZfVkFMVUUpOworICBpZiAoIG9sZCA9PSBuKQorICAgIHJldHVybiBvbGQ7CisKKyAgLy8gSG9va3MgYXVmcnVmZW4KKyAgaW50ICpyZXQgPSBIb29rRmxvdyhIX0hPT0tfRk9PRCwgbik7CisgIC8vIEJlaSBBYmJydWNoIGFsdGVuIFdlcnQgenVydWVja2dlYmVuCisgIHN3aXRjaCAocmV0W0hfUkVUQ09ERV0pIHsKKyAgICBjYXNlIEhfQ0FOQ0VMTEVEOgorICAgICAgcmV0dXJuIG9sZDsKKyAgICBjYXNlIEhfQUxURVJFRDoKKyAgICAgIC8vIHNvbnN0IG5ldWVuIFdlcnQgc2V0emVuCisgICAgICBpZighaW50cChyZXRbSF9SRVREQVRBXSkpCisgICAgICAgICAgcmFpc2VfZXJyb3Ioc3ByaW50ZigKKyAgICAgICAgICAgICJfc2V0X2Zvb2QoKTogZGF0YSBmcm9tIEhvb2tGbG93KCkgIT0gPGludD46ICUuNTBPXG4iLAorICAgICAgICAgICAgcmV0W0hfUkVUREFUQV0pKTsKKyAgICAgIG4gPSByZXRbSF9SRVREQVRBXTsKKyAgICAgIG4gPSBuIDwgMCA/IDAgOiBuOworCisgICAgLy8gSF9OT19NT0QgaXMgZmFsbHRocm91Z2gKKyAgfQorCisgIHJldHVybiBTZXQoUF9GT09ELCBuLCBGX1ZBTFVFKTsKK30KKworc3RhdGljIGludCBfc2V0X3BvaXNvbihpbnQgbikKK3sKKyAgICBpZighaW50cChuKSkKKyAgICAgIHJhaXNlX2Vycm9yKHNwcmludGYoCisgICAgICAgICJfc2V0X3BvaXNvbigpOiBleHBlY3RlZCA8aW50PiwgZ290ICUuNTBPXG4iLCBuKSk7CisKKyAgaWYgKFF1ZXJ5UHJvcChQX0dIT1NUKSkKKyAgICByZXR1cm4gUXVlcnkoUF9QT0lTT04sIEZfVkFMVUUpOworCisgIGludCBtcCA9IFF1ZXJ5UHJvcChQX01BWF9QT0lTT04pOworICBuID0gKG48MCA/IDAgOiAobj5tcCA/IG1wIDogbikpOworCisgIC8vIG51ciA+PTAgenVsYXNzZW4uCisgIG4gPSBuIDwgMCA/IDAgOiBuOworCisgIGludCBvbGQgPSBRdWVyeShQX1BPSVNPTiwgRl9WQUxVRSk7CisgIGlmICggb2xkID09IDAgJiYgbiA9PSAwKQorICAgIHJldHVybiBvbGQ7CisKKyAgLy8gSG9va3MgYXVmcnVmZW4KKyAgaW50ICpyZXQgPSBIb29rRmxvdyhIX0hPT0tfUE9JU09OLCBuKTsKKyAgLy8gQmVpIEFiYnJ1Y2ggYWx0ZW4gV2VydCB6dXJ1ZWNrZ2ViZW4KKyAgc3dpdGNoIChyZXRbSF9SRVRDT0RFXSkgeworICAgIGNhc2UgSF9DQU5DRUxMRUQ6CisgICAgICByZXR1cm4gb2xkOworICAgIGNhc2UgSF9BTFRFUkVEOgorICAgICAgLy8gc29uc3QgbmV1ZW4gV2VydCBzZXR6ZW4KKyAgICAgIGlmKCFpbnRwKHJldFtIX1JFVERBVEFdKSkKKyAgICAgICAgICByYWlzZV9lcnJvcihzcHJpbnRmKAorICAgICAgICAgICAgIl9zZXRfcG9pc29uKCk6IGRhdGEgZnJvbSBIb29rRmxvdygpICE9IDxpbnQ+OiAlLjUwT1xuIiwKKyAgICAgICAgICAgIHJldFtIX1JFVERBVEFdKSk7CisgICAgICBuID0gcmV0W0hfUkVUREFUQV07CisgICAgICBuID0gbiA8IDAgPyAwIDogbjsKKworICAgIC8vIEhfTk9fTU9EIGlzIGZhbGx0aHJvdWdoCisgIH0KKworICAvLyBGdWVyIGRpZSBTZWxic3RoZWlsdW5nLgorICBzd2l0Y2gobikgeworICBjYXNlIDE6CisgICAgZHJvcF9wb2lzb24gPSA0MCtyYW5kb20oMTYpOworICAgIGJyZWFrOworICBjYXNlIDI6CisgICAgZHJvcF9wb2lzb24gPSAyNStyYW5kb20oOCk7CisgICAgYnJlYWs7CisgIGNhc2UgMzoKKyAgICBkcm9wX3BvaXNvbiA9IDE4K3JhbmRvbSg0KTsKKyAgICBicmVhazsKKyAgZGVmYXVsdDoKKyAgICAvLyBudXIgcmVsZXZhbnQgZnVlciBOUEMsIGRhIFNwaWVsZXIgYmVpID4zIEdpZnQgbmljaHQgbWVociByZWdlZ2VuaWVyZW4uCisgICAgZHJvcF9wb2lzb24gPSAyMiAtIDIqbiArIHJhbmRvbSg0MyAtIDMqbik7CisgICAgYnJlYWs7CisgIH0KKworICAvLyBmdWVyIFNldHplbiBkZXIgUHJvcCB2b24gYXVzc2VuIGVpbiBMb2cgc2NocmVpYmVuCisgIGlmIChwcmV2aW91c19vYmplY3QoMSkgIT0gTUUpCisgICAgbG9nX2ZpbGUoIlBPSVNPTiIsIHNwcmludGYoIiVzIC0gJXM6ICVkIHZvbiAlTyAoJXMpXG4iLAorICAgICAgICAgICBkdGltZSh0aW1lKCkpWzUuLl0sCisgICAgICAgICAgIChxdWVyeV9vbmNlX2ludGVyYWN0aXZlKHRoaXNfb2JqZWN0KCkpID8KKyAgICAgICAgICAgICBjYXBpdGFsaXplKGdldGV1aWQodGhpc19vYmplY3QoKSkpIDoKKyAgICAgICAgICAgICBjYXBpdGFsaXplKG5hbWUoV0VSKSkpLAorICAgICAgICAgICBuLAorICAgICAgICAgICAocHJldmlvdXNfb2JqZWN0KDIpID8gcHJldmlvdXNfb2JqZWN0KDIpIDogcHJldmlvdXNfb2JqZWN0KDEpKSwKKyAgICAgICAgICAgKHRoaXNfcGxheWVyKCkgPyBjYXBpdGFsaXplKGdldGV1aWQodGhpc19wbGF5ZXIoKSkpIDogIj8/PyIpKSk7CisKKyAgcmV0dXJuIFNldChQX1BPSVNPTiwgbiwgRl9WQUxVRSk7Cit9CisKK3N0YXRpYyBpbnQgX3NldF94cChpbnQgeHApIHsgcmV0dXJuIFNldChQX1hQLCB4cCA8IDAgPyAwIDogeHAsIEZfVkFMVUUpOyB9CisKK3N0YXRpYyBtaXhlZCBfc2V0X2RpZV9ob29rKG1peGVkIGhvb2spCit7CisgIGlmKGhvb2sgJiYgcXVlcnlfb25jZV9pbnRlcmFjdGl2ZSh0aGlzX29iamVjdCgpKSkKKyAgICBsb2dfZmlsZSgiRElFX0hPT0siLAorICAgICAgICAgICAgIHNwcmludGYoIiVzIDogRElFX0hPT0sgZ2VzZXR6dCB2b24gJU8gaW4gJU8gKCVzKVxuIiwKKyAgICAgICAgICAgICAgICAgICAgIGR0aW1lKHRpbWUoKSlbNS4uXSwKKyAgICAgICAgICAgICAgICAgICAgIChwcmV2aW91c19vYmplY3QoMikgPyBwcmV2aW91c19vYmplY3QoMik6cHJldmlvdXNfb2JqZWN0KDEpKSwKKyAgICAgICAgICAgICAgICAgICAgIHRoaXNfb2JqZWN0KCksZ2V0dWlkKHRoaXNfb2JqZWN0KCkpKSk7CisgIHJldHVybiBTZXQoUF9UTVBfRElFX0hPT0ssaG9vaywgRl9WQUxVRSk7Cit9CisKK3N0YXRpYyBtYXBwaW5nIF9xdWVyeV9lbmVteV9kYW1hZ2UoKQoreworICByZXR1cm4gY29weShlbmVteV9kYW1hZ2UpOworfQorCisvLyBudXIgbmUgS29waWUgbGllZmVybiwgc29uc3Qga2FubiBkYXMgamVkZXIgdm9uIGF1c3NlbiBhZW5kZXJuLgorc3RhdGljIG1hcHBpbmcgX3F1ZXJ5X3RpbWluZ19tYXAoKSB7CisgIHJldHVybiBjb3B5KFF1ZXJ5KFBfVElNSU5HX01BUCkpOworfQorCisvKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgorICogQ29uc3VtZS1GdW5rdGlvbiwgdW0gemVudHJhbCBkdXJjaCBrb25zdW1pZXJiYXJlIERpbmdlIGF1c2dlbG9lc3RlCisgKiBBZW5kZXJ1bmdlbiBkZXMgR2VzdW5kaGVpdHN6dXN0YW5kZXMgaGVyYmVpenVmdWVocmVuLgorICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KKworLyogS29uc3VtaWVydCBldHdhcworICoKKyAqIFJ1ZWNrZ2FiZXdlcnQKKyAqICAgICAgMSAgICAgICBlcmZvbGdyZWljaCBrb25zdW1pZXJ0CisgKiAgICAgIDAgICAgICAgZmVobGVuZGUgb2RlciBmYWxzY2hlIFBhcmFtZXRlcgorICogICAgIDwwICAgICAgIEJlZGluZ3VuZyBmdWVyIGtvbnN1bWllcmVuIG5pY2h0IGVyZnVlbGx0LCBCaXRzZXQgYXVzOgorICogICAgICAxICAgICAgIEthbm4gbmljaHRzIG1laHIgZXNzZW4KKyAqICAgICAgMiAgICAgICBLYW5uIG5pY2h0cyBtZWhyIHRyaW5rZW4KKyAqICAgICAgNCAgICAgICBLYW5uIG5pY2h0cyBtZWhyIHNhdWZlbgorICogICAgICA4ICAgICAgIEFiZ2Vicm9jaGVuIGR1cmNoIEhvb2sgSF9IT09LX0NPTlNVTUUKKyAqLworcHVibGljIHZhcmFyZ3MgaW50IGNvbnN1bWUobWFwcGluZyBjaW5mbywgaW50IHRlc3Rvbmx5KQoreworICBpbnQgcmV0dmFsID0gMDsKKyAgLy8gbnVyIHdhcyB0dW4sIHdlbm4gYXVjaCBJbmZvcyByZWlua29tbWVuCisgIGlmIChtYXBwaW5ncChjaW5mbykgJiYgc2l6ZW9mKGNpbmZvKSkgeworICAgIC8vIEhvb2tzIGF1ZnJ1ZmVuLCBzaWUgYWVuZGVybiBnZ2YuIG5vY2ggd2FzIGluIGNpbmZvLgorICAgIG1peGVkICpocmV0ID0gSG9va0Zsb3coSF9IT09LX0NPTlNVTUUsICh7Y2luZm8sIHRlc3Rvbmx5fSkgKTsKKyAgICBzd2l0Y2goaHJldFtIX1JFVENPREVdKQorICAgIHsKKyAgICAgICAgY2FzZSBIX0NBTkNFTExFRDoKKyAgICAgICAgICByZXR1cm4gLUhDX0hPT0tfQ0FOQ0VMTEFUSU9OOworICAgICAgICBjYXNlIEhfQUxURVJFRDoKKyAgICAgICAgICAvLyB0ZXN0b25seSBrYW5uIG5pY2h0IGdlYWVuZGVydCB3ZXJkZW4uCisgICAgICAgICAgY2luZm8gPSBocmV0W0hfUkVUREFUQV1bMF07CisgICAgfQorICAgIC8vIExlZ2FjeS1NYXBwaW5ncyAoZmxhY2hlKSBuZWJlbiBzdHJ1a3R1cmllcnRlbiBNYXBwaW5ncyB6dWxhc3NlbgorICAgIC8vIGZsYWNoZSBLb3BpZW4gZXJ6ZXVnZW4gKFRPRE8/OiB1bmQgZnVlciBUZWlsbWFwcGluZ3MgbmljaHQgcmVsZXZhbnRlCisgICAgLy8gRWludHJhZWdlIGxvZXNjaGVuKQorICAgIG1hcHBpbmcgY29uZGl0aW9uczsKKyAgICBpZiAobWFwcGluZ3AoY2luZm9bSF9DT05ESVRJT05TXSkpIHsKKyAgICAgIGNvbmRpdGlvbnMgPSBjb3B5KGNpbmZvW0hfQ09ORElUSU9OU10pOworICAgIH0gZWxzZSB7CisgICAgICBjb25kaXRpb25zID0gY29weShjaW5mbyk7CisgICAgfQorICAgIG1hcHBpbmcgZWZmZWN0czsKKyAgICBpZiAobWFwcGluZ3AoY2luZm9bSF9FRkZFQ1RTXSkpIHsKKyAgICAgIGVmZmVjdHMgPSBmaWx0ZXIoY2luZm9bSF9FRkZFQ1RTXSwgKDogbWVtYmVyKEhfQUxMT1dFRF9FRkZFQ1RTLCAkMSkgPiAtMSA6KSk7CisgICAgfSBlbHNlIHsKKyAgICAgIGVmZmVjdHMgPSBmaWx0ZXIoY2luZm8sICg6IG1lbWJlcihIX0FMTE9XRURfRUZGRUNUUywgJDEpID4gLTEgOikpOworICAgIH0KKworICAgIC8vIEJlZGluZ3VuZ2VuIHBydWVmZW4KKyAgICBpZiAobWFwcGluZ3AoY29uZGl0aW9ucykgJiYgc2l6ZW9mKGNvbmRpdGlvbnMpKSB7CisgICAgICAvLyBCZWRpbmd1bmdlbiBmdWVyIEtvbnN1bSBhdXN3ZXJ0ZW4KKyAgICAgIGlmIChjb25kaXRpb25zW1BfRk9PRF0gJiYgIWVhdF9mb29kKGNvbmRpdGlvbnNbUF9GT09EXSwgMSkpCisgICAgICAgIHJldHZhbCB8PSBIQ19NQVhfRk9PRF9SRUFDSEVEOworICAgICAgZWxzZSBpZiAoY29uZGl0aW9uc1tQX0RSSU5LXSAmJiAhZHJpbmtfc29mdChjb25kaXRpb25zW1BfRFJJTktdLCAxKSkKKyAgICAgICAgcmV0dmFsIHw9IEhDX01BWF9EUklOS19SRUFDSEVEOworICAgICAgZWxzZSBpZiAoY29uZGl0aW9uc1tQX0FMQ09IT0xdICYmICFkcmlua19hbGNvaG9sKGNvbmRpdGlvbnNbUF9BTENPSE9MXSwgMSkpCisgICAgICAgIHJldHZhbCB8PSBIQ19NQVhfQUxDT0hPTF9SRUFDSEVEOworICAgICAgLy8gcmV0dmFsIG5lZ2F0aXYgbWFjaGVuLCBkYW1pdCBGZWhsZXIgbGVpY2h0IGVya2VubmJhciBpc3QKKyAgICAgIHJldHZhbCA9IC1yZXR2YWw7CisgICAgfQorICAgIC8vIEJlZGluZ3VuZ2VuIHd1cmRlbiBhYmdlYXJiZWl0ZXQsIGpldHp0IGRpZSBIZWlsdW5nIGR1cmNoZnVlaHJlbgorICAgIGlmICghcmV0dmFsKSB7CisgICAgICBpZiAoIXRlc3Rvbmx5KSB7CisgICAgICAgIC8vIEJlZGluZ3VuZ2VuIGVyZnVlbGxlbiwgd2VubiBhbGxlcyBwYXNzdCB1bmQga2VpbiBUZXN0CisgICAgICAgIGlmIChjb25kaXRpb25zW1BfQUxDT0hPTF0pCisgICAgICAgICAgZHJpbmtfYWxjb2hvbChjb25kaXRpb25zW1BfQUxDT0hPTF0pOworICAgICAgICBpZiAoY29uZGl0aW9uc1tQX0RSSU5LXSkKKyAgICAgICAgICBkcmlua19zb2Z0KGNvbmRpdGlvbnNbUF9EUklOS10pOworICAgICAgICBpZiAoY29uZGl0aW9uc1tQX0ZPT0RdKQorICAgICAgICAgIGVhdF9mb29kKGNvbmRpdGlvbnNbUF9GT09EXSk7CisgICAgICAgIC8vIFVuZCBqZXR6dCBkaWUgV2lya3VuZ2VuCisgICAgICAgIGlmIChlZmZlY3RzW1BfUE9JU09OXSkKKyAgICAgICAgICBTZXRQcm9wKFBfUE9JU09OLCBRdWVyeVByb3AoUF9QT0lTT04pICsgZWZmZWN0c1tQX1BPSVNPTl0pOworICAgICAgICAvLyBVbmQgbnVuIHdpcmtsaWNoIGhlaWxlbgorICAgICAgICBzd2l0Y2ggKGNpbmZvW0hfRElTVFJJQlVUSU9OXSkgeworICAgICAgICBjYXNlIEhEX0lOU1RBTlQ6CisgICAgICAgICAgbWFwKGVmZmVjdHMsICg6IFNldFByb3AoJDEsIFF1ZXJ5UHJvcCgkMSkgKyAkMikgOikpOworICAgICAgICAgIGJyZWFrOworICAgICAgICBjYXNlIDEuLjUwOgorICAgICAgICAgIGJ1ZmZlcl9ocChlZmZlY3RzW1BfSFBdLCBjaW5mb1tIX0RJU1RSSUJVVElPTl0pOworICAgICAgICAgIGJ1ZmZlcl9zcChlZmZlY3RzW1BfU1BdLCBjaW5mb1tIX0RJU1RSSUJVVElPTl0pOworICAgICAgICAgIGJyZWFrOworICAgICAgICBkZWZhdWx0OgorICAgICAgICAgIGJ1ZmZlcl9ocChlZmZlY3RzW1BfSFBdLCBIRF9TVEFOREFSRCk7CisgICAgICAgICAgYnVmZmVyX3NwKGVmZmVjdHNbUF9TUF0sIEhEX1NUQU5EQVJEKTsKKyAgICAgICAgICBicmVhazsKKyAgICAgICAgfQorICAgICAgfQorICAgICAgcmV0dmFsID0gMTsKKyAgICB9CisgIH0KKyAgcmV0dXJuIHJldHZhbDsKK30K