LyoKICogRE9TIFZpcnR1YWwgTWFjaGluZQogKgogKiBDb3B5cmlnaHQgMTk5OCBPdmUgS+V2ZW4KICoKICogVGhpcyBjb2RlIGhhc24ndCBiZWVuIGNvbXBsZXRlbHkgY2xlYW5lZCB1cCB5ZXQuCiAqLwoKI2luY2x1ZGUgImNvbmZpZy5oIgoKI2luY2x1ZGUgPHN0ZGlvLmg+CiNpbmNsdWRlIDxzdGRsaWIuaD4KI2luY2x1ZGUgPHN0cmluZy5oPgojaW5jbHVkZSA8ZXJybm8uaD4KI2luY2x1ZGUgPGZjbnRsLmg+CiNpbmNsdWRlIDxzaWduYWwuaD4KI2luY2x1ZGUgPHVuaXN0ZC5oPgojaW5jbHVkZSA8c3lzL3RpbWUuaD4KI2luY2x1ZGUgPHN5cy90eXBlcy5oPgoKI2luY2x1ZGUgIndpbmUvd2luYmFzZTE2LmgiCiNpbmNsdWRlICJ3aW5lL2V4Y2VwdGlvbi5oIgojaW5jbHVkZSAid2luZGVmLmgiCiNpbmNsdWRlICJ3aW5iYXNlLmgiCiNpbmNsdWRlICJ3aW5nZGkuaCIKI2luY2x1ZGUgIndpbnVzZXIuaCIKI2luY2x1ZGUgIndpbm50LmgiCiNpbmNsdWRlICJ3aW5jb24uaCIKCiNpbmNsdWRlICJtc2Rvcy5oIgojaW5jbHVkZSAiZmlsZS5oIgojaW5jbHVkZSAibWlzY2VtdS5oIgojaW5jbHVkZSAiZG9zZXhlLmgiCiNpbmNsdWRlICJkb3N2bS5oIgojaW5jbHVkZSAic3RhY2tmcmFtZS5oIgojaW5jbHVkZSAiZGVidWd0b29scy5oIgojaW5jbHVkZSAibXN2Y3J0L2V4Y3B0LmgiCgpERUZBVUxUX0RFQlVHX0NIQU5ORUwoaW50KTsKREVDTEFSRV9ERUJVR19DSEFOTkVMKG1vZHVsZSk7CkRFQ0xBUkVfREVCVUdfQ0hBTk5FTChyZWxheSk7CgpXT1JEIERPU1ZNX3BzcCA9IDA7CldPUkQgRE9TVk1fcmV0dmFsID0gMDsKCiNpZmRlZiBNWl9TVVBQT1JURUQKCiNpZmRlZiBIQVZFX1NZU19WTTg2X0gKIyBpbmNsdWRlIDxzeXMvdm04Ni5oPgojZW5kaWYKI2lmZGVmIEhBVkVfU1lTX01NQU5fSAojIGluY2x1ZGUgPHN5cy9tbWFuLmg+CiNlbmRpZgoKI2RlZmluZSBJRl9DTFIoY3R4KSAgICAgKChjdHgpLT5FRmxhZ3MgJj0gflZJRl9NQVNLKQojZGVmaW5lIElGX1NFVChjdHgpICAgICAoKGN0eCktPkVGbGFncyB8PSBWSUZfTUFTSykKI2RlZmluZSBJRl9FTkFCTEVEKGN0eCkgKChjdHgpLT5FRmxhZ3MgJiBWSUZfTUFTSykKI2RlZmluZSBTRVRfUEVORChjdHgpICAgKChjdHgpLT5FRmxhZ3MgfD0gVklQX01BU0spCiNkZWZpbmUgQ0xSX1BFTkQoY3R4KSAgICgoY3R4KS0+RUZsYWdzICY9IH5WSVBfTUFTSykKI2RlZmluZSBJU19QRU5EKGN0eCkgICAgKChjdHgpLT5FRmxhZ3MgJiBWSVBfTUFTSykKCiN1bmRlZiBUUllfUElDUkVUVVJOCgp0eXBlZGVmIHN0cnVjdCBfRE9TRVZFTlQgewogIGludCBpcnEscHJpb3JpdHk7CiAgRE9TUkVMQVkgcmVsYXk7CiAgdm9pZCAqZGF0YTsKICBzdHJ1Y3QgX0RPU0VWRU5UICpuZXh0Owp9IERPU0VWRU5ULCAqTFBET1NFVkVOVDsKCnN0YXRpYyBDUklUSUNBTF9TRUNUSU9OIHFjcml0ID0gQ1JJVElDQUxfU0VDVElPTl9JTklUKCJET1NWTSIpOwpzdGF0aWMgc3RydWN0IF9ET1NFVkVOVCAqcGVuZGluZ19ldmVudCwgKmN1cnJlbnRfZXZlbnQ7CnN0YXRpYyBpbnQgc2lnX3NlbnQ7CnN0YXRpYyBDT05URVhUODYgKmN1cnJlbnRfY29udGV4dDsKCnN0YXRpYyBpbnQgRE9TVk1fU2ltdWxhdGVJbnQoIGludCB2ZWN0LCBDT05URVhUODYgKmNvbnRleHQsIEJPT0wgaW53aW5lICkKewogIEZBUlBST0MxNiBoYW5kbGVyPURPU1ZNX0dldFJNSGFuZGxlcih2ZWN0KTsKCiAgLyogY2hlY2sgZm9yIG91ciByZWFsLW1vZGUgaG9va3MgKi8KICBpZiAodmVjdD09MHgzMSkgewogICAgaWYgKGNvbnRleHQtPlNlZ0NzPT1ET1NNRU1fd3JhcF9zZWcpIHsKICAgICAgLyogZXhpdCBmcm9tIHJlYWwtbW9kZSB3cmFwcGVyICovCiAgICAgIHJldHVybiAtMTsKICAgIH0KICAgIC8qIHdlIGNvdWxkIHByb2JhYmx5IG1vdmUgc29tZSBvdGhlciBkb2RneSBzdHVmZiBoZXJlIHRvbyBmcm9tIGRwbWkuYyAqLwogIH0KICAvKiBjaGVjayBpZiB0aGUgY2FsbCBpcyBmcm9tIG91ciBmYWtlIEJJT1MgaW50ZXJydXB0IHN0dWJzICovCiAgaWYgKChjb250ZXh0LT5TZWdDcz09MHhmMDAwKSAmJiAhaW53aW5lKSB7CiAgICBpZiAodmVjdCAhPSAoY29udGV4dC0+RWlwLzQpKSB7CiAgICAgIFRSQUNFKCJzb21ldGhpbmcgZmlzaHkgZ29pbmcgb24gaGVyZSAoaW50ZXJydXB0IHN0dWIgaXMgJTAybHgpXG4iLCBjb250ZXh0LT5FaXAvNCk7CiAgICB9CiAgICBUUkFDRSgiYnVpbHRpbiBpbnRlcnJ1cHQgJTAyeCBoYXMgYmVlbiBicmFuY2hlZCB0b1xuIiwgdmVjdCk7CiAgICBET1NWTV9SZWFsTW9kZUludGVycnVwdCh2ZWN0LCBjb250ZXh0KTsKICB9CiAgLyogY2hlY2sgaWYgdGhlIGNhbGwgZ29lcyB0byBhbiB1bmhvb2tlZCBpbnRlcnJ1cHQgKi8KICBlbHNlIGlmIChTRUxFQ1RPUk9GKGhhbmRsZXIpPT0weGYwMDApIHsKICAgIC8qIGlmIHNvLCBjYWxsIGl0IGRpcmVjdGx5ICovCiAgICBUUkFDRSgiYnVpbHRpbiBpbnRlcnJ1cHQgJTAyeCBoYXMgYmVlbiBpbnZva2VkICh0aHJvdWdoIHZlY3RvciAlMDJ4KVxuIiwgT0ZGU0VUT0YoaGFuZGxlcikvNCwgdmVjdCk7CiAgICBET1NWTV9SZWFsTW9kZUludGVycnVwdChPRkZTRVRPRihoYW5kbGVyKS80LCBjb250ZXh0KTsKICB9CiAgLyogdGhlIGludGVycnVwdCBpcyBob29rZWQsIHNpbXVsYXRlIGludGVycnVwdCBpbiBET1Mgc3BhY2UgKi8KICBlbHNlIHsKICAgIFdPUkQqc3RhY2s9IFBUUl9SRUFMX1RPX0xJTiggY29udGV4dC0+U2VnU3MsIGNvbnRleHQtPkVzcCApOwogICAgV09SRCBmbGFnPUxPV09SRChjb250ZXh0LT5FRmxhZ3MpOwoKICAgIFRSQUNFXyhpbnQpKCJpbnZva2luZyBob29rZWQgaW50ZXJydXB0ICUwMnggYXQgJTA0eDolMDR4XG4iLCB2ZWN0LAoJCVNFTEVDVE9ST0YoaGFuZGxlciksIE9GRlNFVE9GKGhhbmRsZXIpKTsKICAgIGlmIChJRl9FTkFCTEVEKGNvbnRleHQpKSBmbGFnfD1JRl9NQVNLOwogICAgZWxzZSBmbGFnJj1+SUZfTUFTSzsKCiAgICAqKC0tc3RhY2spPWZsYWc7CiAgICAqKC0tc3RhY2spPWNvbnRleHQtPlNlZ0NzOwogICAgKigtLXN0YWNrKT1MT1dPUkQoY29udGV4dC0+RWlwKTsKICAgIGNvbnRleHQtPkVzcC09NjsKICAgIGNvbnRleHQtPlNlZ0NzPVNFTEVDVE9ST0YoaGFuZGxlcik7CiAgICBjb250ZXh0LT5FaXA9T0ZGU0VUT0YoaGFuZGxlcik7CiAgICBJRl9DTFIoY29udGV4dCk7CiAgfQogIHJldHVybiAwOwp9CgojZGVmaW5lIFNIT1VMRF9QRU5EKHgpIFwKICAoeCAmJiAoKCFjdXJyZW50X2V2ZW50KSB8fCAoeC0+cHJpb3JpdHkgPCBjdXJyZW50X2V2ZW50LT5wcmlvcml0eSkpKQoKc3RhdGljIHZvaWQgRE9TVk1fU2VuZFF1ZXVlZEV2ZW50KENPTlRFWFQ4NiAqY29udGV4dCkKewogIExQRE9TRVZFTlQgZXZlbnQgPSBwZW5kaW5nX2V2ZW50OwoKICBpZiAoU0hPVUxEX1BFTkQoZXZlbnQpKSB7CiAgICAvKiByZW1vdmUgZnJvbSAicGVuZGluZyIgbGlzdCAqLwogICAgcGVuZGluZ19ldmVudCA9IGV2ZW50LT5uZXh0OwogICAgLyogcHJvY2VzcyBldmVudCAqLwogICAgaWYgKGV2ZW50LT5pcnE+PTApIHsKICAgICAgLyogaXQncyBhbiBJUlEsIG1vdmUgaXQgdG8gImN1cnJlbnQiIGxpc3QgKi8KICAgICAgZXZlbnQtPm5leHQgPSBjdXJyZW50X2V2ZW50OwogICAgICBjdXJyZW50X2V2ZW50ID0gZXZlbnQ7CiAgICAgIFRSQUNFKCJkaXNwYXRjaGluZyBJUlEgJWRcbiIsZXZlbnQtPmlycSk7CiAgICAgIC8qIG5vdGUgdGhhdCBpZiBET1NWTV9TaW11bGF0ZUludCBjYWxscyBhbiBpbnRlcm5hbCBpbnRlcnJ1cHQgZGlyZWN0bHksCiAgICAgICAqIGN1cnJlbnRfZXZlbnQgbWlnaHQgYmUgY2xlYXJlZCAoYW5kIGV2ZW50IGZyZWVkKSBpbiB0aGlzIHZlcnkgY2FsbCEgKi8KICAgICAgRE9TVk1fU2ltdWxhdGVJbnQoKGV2ZW50LT5pcnE8OCk/KGV2ZW50LT5pcnErOCk6KGV2ZW50LT5pcnEtOCsweDcwKSxjb250ZXh0LFRSVUUpOwogICAgfSBlbHNlIHsKICAgICAgLyogY2FsbGJhY2sgZXZlbnQgKi8KICAgICAgVFJBQ0UoImRpc3BhdGNoaW5nIGNhbGxiYWNrIGV2ZW50XG4iKTsKICAgICAgKCpldmVudC0+cmVsYXkpKGNvbnRleHQsZXZlbnQtPmRhdGEpOwogICAgICBmcmVlKGV2ZW50KTsKICAgIH0KICB9CiAgaWYgKCFTSE9VTERfUEVORChwZW5kaW5nX2V2ZW50KSkgewogICAgVFJBQ0UoImNsZWFyaW5nIFBlbmRpbmcgZmxhZ1xuIik7CiAgICBDTFJfUEVORChjb250ZXh0KTsKICB9Cn0KCnN0YXRpYyB2b2lkIERPU1ZNX1NlbmRRdWV1ZWRFdmVudHMoQ09OVEVYVDg2ICpjb250ZXh0KQp7CiAgLyogd2Ugd2lsbCBzZW5kIGFsbCBxdWV1ZWQgZXZlbnRzIGFzIGxvbmcgYXMgaW50ZXJydXB0cyBhcmUgZW5hYmxlZCwKICAgKiBidXQgSVJRIGV2ZW50cyB3aWxsIGRpc2FibGUgaW50ZXJydXB0cyBhZ2FpbiAqLwogIHdoaWxlIChJU19QRU5EKGNvbnRleHQpICYmIElGX0VOQUJMRUQoY29udGV4dCkpCiAgICBET1NWTV9TZW5kUXVldWVkRXZlbnQoY29udGV4dCk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJUXVldWVFdmVudCAoV0lORURPUy5AKQogKi8Kdm9pZCBXSU5BUEkgRE9TVk1fUXVldWVFdmVudCggSU5UIGlycSwgSU5UIHByaW9yaXR5LCBET1NSRUxBWSByZWxheSwgTFBWT0lEIGRhdGEpCnsKICBMUERPU0VWRU5UIGV2ZW50LCBjdXIsIHByZXY7CgogIGlmIChjdXJyZW50X2NvbnRleHQpIHsKICAgIEVudGVyQ3JpdGljYWxTZWN0aW9uKCZxY3JpdCk7CiAgICBldmVudCA9IG1hbGxvYyhzaXplb2YoRE9TRVZFTlQpKTsKICAgIGlmICghZXZlbnQpIHsKICAgICAgRVJSKCJvdXQgb2YgbWVtb3J5IGFsbG9jYXRpbmcgZXZlbnQgZW50cnlcbiIpOwogICAgICByZXR1cm47CiAgICB9CiAgICBldmVudC0+aXJxID0gaXJxOyBldmVudC0+cHJpb3JpdHkgPSBwcmlvcml0eTsKICAgIGV2ZW50LT5yZWxheSA9IHJlbGF5OyBldmVudC0+ZGF0YSA9IGRhdGE7CgogICAgLyogaW5zZXJ0IGV2ZW50IGludG8gbGlua2VkIGxpc3QsIGluIG9yZGVyICphZnRlcioKICAgICAqIGFsbCBlYXJsaWVyIGV2ZW50cyBvZiBoaWdoZXIgb3IgZXF1YWwgcHJpb3JpdHkgKi8KICAgIGN1ciA9IHBlbmRpbmdfZXZlbnQ7IHByZXYgPSBOVUxMOwogICAgd2hpbGUgKGN1ciAmJiBjdXItPnByaW9yaXR5PD1wcmlvcml0eSkgewogICAgICBwcmV2ID0gY3VyOwogICAgICBjdXIgPSBjdXItPm5leHQ7CiAgICB9CiAgICBldmVudC0+bmV4dCA9IGN1cjsKICAgIGlmIChwcmV2KSBwcmV2LT5uZXh0ID0gZXZlbnQ7CiAgICBlbHNlIHBlbmRpbmdfZXZlbnQgPSBldmVudDsKCiAgICAvKiBhbGVydCB0aGUgdm04NiBhYm91dCB0aGUgbmV3IGV2ZW50ICovCiAgICBpZiAoIXNpZ19zZW50KSB7CiAgICAgIFRSQUNFKCJuZXcgZXZlbnQgcXVldWVkLCBzaWduYWxsaW5nICh0aW1lPSVsZClcbiIsIEdldFRpY2tDb3VudCgpKTsKICAgICAga2lsbChkb3N2bV9waWQsU0lHVVNSMik7CiAgICAgIHNpZ19zZW50Kys7CiAgICB9IGVsc2UgewogICAgICBUUkFDRSgibmV3IGV2ZW50IHF1ZXVlZCAodGltZT0lbGQpXG4iLCBHZXRUaWNrQ291bnQoKSk7CiAgICB9CiAgICBMZWF2ZUNyaXRpY2FsU2VjdGlvbigmcWNyaXQpOwogIH0gZWxzZSB7CiAgICAvKiBET1Mgc3Vic3lzdGVtIG5vdCBydW5uaW5nICovCiAgICAvKiAodGhpcyBwcm9iYWJseSBtZWFucyB0aGF0IHdlJ3JlIHJ1bm5pbmcgYSB3aW4xNiBhcHAKICAgICAqICB3aGljaCB1c2VzIERQTUkgdG8gdGh1bmsgZG93biB0byBET1Mgc2VydmljZXMpICovCiAgICBpZiAoaXJxPDApIHsKICAgICAgLyogY2FsbGJhY2sgZXZlbnQsIHBlcmZvcm0gaXQgd2l0aCBkdW1teSBjb250ZXh0ICovCiAgICAgIENPTlRFWFQ4NiBjb250ZXh0OwogICAgICBtZW1zZXQoJmNvbnRleHQsMCxzaXplb2YoY29udGV4dCkpOwogICAgICAoKnJlbGF5KSgmY29udGV4dCxkYXRhKTsKICAgIH0gZWxzZSB7CiAgICAgIEVSUigiSVJRIHdpdGhvdXQgRE9TIHRhc2s6IHNob3VsZCBub3QgaGFwcGVuIik7CiAgICB9CiAgfQp9CgpzdGF0aWMgdm9pZCBET1NWTV9Qcm9jZXNzQ29uc29sZSh2b2lkKQp7CiAgSU5QVVRfUkVDT1JEIG1zZzsKICBEV09SRCByZXM7CiAgQllURSBzY2FuOwoKICBpZiAoUmVhZENvbnNvbGVJbnB1dEEoR2V0U3RkSGFuZGxlKFNURF9JTlBVVF9IQU5ETEUpLCZtc2csMSwmcmVzKSkgewogICAgc3dpdGNoIChtc2cuRXZlbnRUeXBlKSB7CiAgICBjYXNlIEtFWV9FVkVOVDoKICAgICAgc2NhbiA9IG1zZy5FdmVudC5LZXlFdmVudC53VmlydHVhbFNjYW5Db2RlOwogICAgICBpZiAoIW1zZy5FdmVudC5LZXlFdmVudC5iS2V5RG93bikgc2NhbiB8PSAweDgwOwoKICAgICAgLyogY2hlY2sgd2hldGhlciBleHRlbmRlZCBiaXQgaXMgc2V0LAogICAgICAgKiBhbmQgaWYgc28sIHF1ZXVlIHRoZSBleHRlbnNpb24gcHJlZml4ICovCiAgICAgIGlmIChtc2cuRXZlbnQuS2V5RXZlbnQuZHdDb250cm9sS2V5U3RhdGUgJiBFTkhBTkNFRF9LRVkpIHsKICAgICAgICBET1NWTV9JbnQwOVNlbmRTY2FuKDB4RTAsMCk7CiAgICAgIH0KICAgICAgRE9TVk1fSW50MDlTZW5kU2NhbihzY2FuLG1zZy5FdmVudC5LZXlFdmVudC51Q2hhci5Bc2NpaUNoYXIpOwogICAgICBicmVhazsKICAgIGRlZmF1bHQ6CiAgICAgIEZJWE1FKCJ1bmhhbmRsZWQgY29uc29sZSBldmVudDogJWRcbiIsIG1zZy5FdmVudFR5cGUpOwogICAgfQogIH0KfQoKc3RhdGljIHZvaWQgRE9TVk1fUHJvY2Vzc01lc3NhZ2UoTVNHICptc2cpCnsKICBCWVRFIHNjYW4gPSAwOwoKICBUUkFDRSgiZ290IG1lc3NhZ2UgJTA0eCwgd3BhcmFtPSUwOHgsIGxwYXJhbT0lMDhseFxuIixtc2ctPm1lc3NhZ2UsbXNnLT53UGFyYW0sbXNnLT5sUGFyYW0pOwogIGlmICgobXNnLT5tZXNzYWdlPj1XTV9NT1VTRUZJUlNUKSYmCiAgICAgIChtc2ctPm1lc3NhZ2U8PVdNX01PVVNFTEFTVCkpIHsKICAgIERPU1ZNX0ludDMzTWVzc2FnZShtc2ctPm1lc3NhZ2UsbXNnLT53UGFyYW0sbXNnLT5sUGFyYW0pOwogIH0gZWxzZSB7CiAgICBzd2l0Y2ggKG1zZy0+bWVzc2FnZSkgewogICAgY2FzZSBXTV9LRVlVUDoKICAgICAgc2NhbiA9IDB4ODA7CiAgICBjYXNlIFdNX0tFWURPV046CiAgICAgIHNjYW4gfD0gKG1zZy0+bFBhcmFtID4+IDE2KSAmIDB4N2Y7CgogICAgICAvKiBjaGVjayB3aGV0aGVyIGV4dGVuZGVkIGJpdCBpcyBzZXQsCiAgICAgICAqIGFuZCBpZiBzbywgcXVldWUgdGhlIGV4dGVuc2lvbiBwcmVmaXggKi8KICAgICAgaWYgKG1zZy0+bFBhcmFtICYgMHgxMDAwMDAwKSB7CgkvKiBGSVhNRTogc29tZSBrZXlzIChmdW5jdGlvbiBrZXlzKSBoYXZlCgkgKiBleHRlbmRlZCBiaXQgc2V0IGV2ZW4gd2hlbiB0aGV5IHNob3VsZG4ndCwKCSAqIHNob3VsZCBjaGVjayBmb3IgdGhlbSAqLwoJRE9TVk1fSW50MDlTZW5kU2NhbigweEUwLDApOwogICAgICB9CiAgICAgIERPU1ZNX0ludDA5U2VuZFNjYW4oc2NhbiwwKTsKICAgICAgYnJlYWs7CiAgICB9CiAgfQp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCVdhaXQgKFdJTkVET1MuQCkKICovCnZvaWQgV0lOQVBJIERPU1ZNX1dhaXQoIElOVCByZWFkX3BpcGUsIEhBTkRMRSBoT2JqZWN0ICkKewogIE1TRyBtc2c7CiAgRFdPUkQgd2FpdHJldDsKICBIQU5ETEUgb2Jqc1syXTsKICBpbnQgb2JqYzsKICBCT09MIGdvdF9tc2cgPSBGQUxTRTsKCiAgb2Jqc1swXT1HZXRTdGRIYW5kbGUoU1REX0lOUFVUX0hBTkRMRSk7CiAgb2Jqc1sxXT1oT2JqZWN0OwogIG9iamM9aE9iamVjdD8yOjE7CiAgZG8gewogICAgLyogY2hlY2sgZm9yIG1lc3NhZ2VzICh3YXN0ZSB0aW1lIGJlZm9yZSB0aGUgcmVzcG9uc2UgY2hlY2sgYmVsb3cpICovCiAgICBpZiAoUGVla01lc3NhZ2VBKQogICAgewogICAgICAgIHdoaWxlIChQZWVrTWVzc2FnZUEoJm1zZywwLDAsMCxQTV9SRU1PVkV8UE1fTk9ZSUVMRCkpIHsKICAgICAgICAgICAgLyogZ290IGEgbWVzc2FnZSAqLwogICAgICAgICAgICBET1NWTV9Qcm9jZXNzTWVzc2FnZSgmbXNnKTsKICAgICAgICAgICAgLyogd2UgZG9uJ3QgbmVlZCBhIFRyYW5zbGF0ZU1lc3NhZ2UgaGVyZSAqLwogICAgICAgICAgICBEaXNwYXRjaE1lc3NhZ2VBKCZtc2cpOwogICAgICAgICAgICBnb3RfbXNnID0gVFJVRTsKICAgICAgICB9CiAgICB9CmNoa19jb25zb2xlX2lucHV0OgogICAgaWYgKCFnb3RfbXNnKSB7CiAgICAgIC8qIGNoZWNrIGZvciBjb25zb2xlIGlucHV0ICovCiAgICAgIElOUFVUX1JFQ09SRCBtc2c7CiAgICAgIERXT1JEIG51bTsKICAgICAgaWYgKFBlZWtDb25zb2xlSW5wdXRBKG9ianNbMF0sJm1zZywxLCZudW0pICYmIG51bSkgewogICAgICAgIERPU1ZNX1Byb2Nlc3NDb25zb2xlKCk7CiAgICAgICAgZ290X21zZyA9IFRSVUU7CiAgICAgIH0KICAgIH0KICAgIGlmIChyZWFkX3BpcGUgPT0gLTEpIHsKICAgICAgLyogZGlzcGF0Y2ggcGVuZGluZyBldmVudHMgKi8KICAgICAgaWYgKFNIT1VMRF9QRU5EKHBlbmRpbmdfZXZlbnQpKSB7CiAgICAgICAgQ09OVEVYVDg2IGNvbnRleHQgPSAqY3VycmVudF9jb250ZXh0OwogICAgICAgIElGX1NFVCgmY29udGV4dCk7CiAgICAgICAgU0VUX1BFTkQoJmNvbnRleHQpOwogICAgICAgIERPU1ZNX1NlbmRRdWV1ZWRFdmVudHMoJmNvbnRleHQpOwogICAgICB9CiAgICAgIGlmIChnb3RfbXNnKSBicmVhazsKICAgIH0gZWxzZSB7CiAgICAgIGZkX3NldCByZWFkZmRzOwogICAgICBzdHJ1Y3QgdGltZXZhbCB0aW1lb3V0PXswLDB9OwogICAgICAvKiBxdWljayBjaGVjayBmb3IgcmVzcG9uc2UgZnJvbSBkb3Ntb2QKICAgICAgICogKGZhc3RlciB0aGFuIGRvaW5nIHRoZSBmdWxsIGJsb2NraW5nIHdhaXQsIGlmIGRhdGEgYWxyZWFkeSBhdmFpbGFibGUpICovCiAgICAgIEZEX1pFUk8oJnJlYWRmZHMpOyBGRF9TRVQocmVhZF9waXBlLCZyZWFkZmRzKTsKICAgICAgaWYgKHNlbGVjdChyZWFkX3BpcGUrMSwmcmVhZGZkcyxOVUxMLE5VTEwsJnRpbWVvdXQpPjApCglicmVhazsKICAgIH0KICAgIC8qIG5vdGhpbmcgeWV0LCBibG9jayB3aGlsZSB3YWl0aW5nIGZvciBzb21ldGhpbmcgdG8gZG8gKi8KICAgIGlmIChNc2dXYWl0Rm9yTXVsdGlwbGVPYmplY3RzKQogICAgICAgIHdhaXRyZXQgPSBNc2dXYWl0Rm9yTXVsdGlwbGVPYmplY3RzKG9iamMsb2JqcyxGQUxTRSxJTkZJTklURSxRU19BTExJTlBVVCk7CiAgICBlbHNlCiAgICAgICAgd2FpdHJldCA9IFdhaXRGb3JNdWx0aXBsZU9iamVjdHMob2JqYyxvYmpzLEZBTFNFLElORklOSVRFKTsKCiAgICBpZiAod2FpdHJldD09KERXT1JEKS0xKSB7CiAgICAgIEVSUl8obW9kdWxlKSgiZG9zdm0gd2FpdCBlcnJvcj0lbGRcbiIsR2V0TGFzdEVycm9yKCkpOwogICAgfQogICAgaWYgKChyZWFkX3BpcGUgIT0gLTEpICYmIGhPYmplY3QpIHsKICAgICAgaWYgKHdhaXRyZXQ9PShXQUlUX09CSkVDVF8wKzEpKSBicmVhazsKICAgIH0KICAgIGlmICh3YWl0cmV0PT1XQUlUX09CSkVDVF8wKQogICAgICBnb3RvIGNoa19jb25zb2xlX2lucHV0OwogIH0gd2hpbGUgKFRSVUUpOwp9CgpEV09SRCBXSU5BUEkgRE9TVk1fTG9vcCggTFBWT0lEIGxwRXh0cmEgKQp7CiAgSEFORExFIG9iaiA9IEdldFN0ZEhhbmRsZShTVERfSU5QVVRfSEFORExFKTsKICBNU0cgbXNnOwogIERXT1JEIHdhaXRyZXQ7CgogIGZvcig7OykgewogICAgVFJBQ0VfKGludCkoIndhaXRpbmcgZm9yIGFjdGlvblxuIik7CiAgICB3YWl0cmV0ID0gTXNnV2FpdEZvck11bHRpcGxlT2JqZWN0cygxLCAmb2JqLCBGQUxTRSwgSU5GSU5JVEUsIFFTX0FMTElOUFVUKTsKICAgIGlmICh3YWl0cmV0ID09IFdBSVRfT0JKRUNUXzApIHsKICAgICAgRE9TVk1fUHJvY2Vzc0NvbnNvbGUoKTsKICAgIH0KICAgIGVsc2UgaWYgKHdhaXRyZXQgPT0gV0FJVF9PQkpFQ1RfMCArIDEpIHsKICAgICAgR2V0TWVzc2FnZUEoJm1zZywgMCwgMCwgMCk7CiAgICAgIGlmIChtc2cuaHduZCkgewoJLyogaXQncyBhIHdpbmRvdyBtZXNzYWdlICovCglET1NWTV9Qcm9jZXNzTWVzc2FnZSgmbXNnKTsKCURpc3BhdGNoTWVzc2FnZUEoJm1zZyk7CiAgICAgIH0gZWxzZSB7CgkvKiBpdCdzIGEgdGhyZWFkIG1lc3NhZ2UgKi8KCXN3aXRjaCAobXNnLm1lc3NhZ2UpIHsKCWNhc2UgV01fUVVJVDoKCSAgLyogc3RvcCB0aGlzIG1hZG5lc3MhISAqLwoJICByZXR1cm4gMDsKCWNhc2UgV01fVVNFUjoKCSAgLyogcnVuIHBhc3NlZCBwcm9jZWR1cmUgaW4gdGhpcyB0aHJlYWQgKi8KCSAgLyogKHNvcnQgb2YgbGlrZSBBUEMsIGJ1dCB3ZSBzaWduYWwgdGhlIGNvbXBsZXRpb24pICovCgkgIHsKCSAgICBET1NfU1BDICpzcGMgPSAoRE9TX1NQQyAqKW1zZy5sUGFyYW07CgkgICAgVFJBQ0VfKGludCkoImNhbGxpbmcgJXAgd2l0aCBhcmcgJTA4eFxuIiwgc3BjLT5wcm9jLCBzcGMtPmFyZyk7CgkgICAgKHNwYy0+cHJvYykoc3BjLT5hcmcpOwoJICAgIFRSQUNFXyhpbnQpKCJkb25lLCBzaWduYWxsaW5nIGV2ZW50ICVkXG4iLCBtc2cud1BhcmFtKTsKCSAgICBTZXRFdmVudChtc2cud1BhcmFtKTsKCSAgfQoJICBicmVhazsKCX0KICAgICAgfQogICAgfQogICAgZWxzZSBicmVhazsKICB9CiAgcmV0dXJuIDA7Cn0KCnN0YXRpYyBXSU5FX0VYQ0VQVElPTl9GSUxURVIoZXhjZXB0aW9uX2hhbmRsZXIpCnsKICBFWENFUFRJT05fUkVDT1JEICpyZWMgPSBHZXRFeGNlcHRpb25JbmZvcm1hdGlvbigpLT5FeGNlcHRpb25SZWNvcmQ7CiAgQ09OVEVYVCAqY29udGV4dCA9IEdldEV4Y2VwdGlvbkluZm9ybWF0aW9uKCktPkNvbnRleHRSZWNvcmQ7CiAgaW50IHJldCwgYXJnID0gcmVjLT5FeGNlcHRpb25JbmZvcm1hdGlvblswXTsKCiAgc3dpdGNoKHJlYy0+RXhjZXB0aW9uQ29kZSkgewogIGNhc2UgRVhDRVBUSU9OX1ZNODZfSU5UeDoKICAgIGlmIChUUkFDRV9PTihyZWxheSkpIHsKICAgICAgRFBSSU5URigiQ2FsbCBET1MgaW50IDB4JTAyeCByZXQ9JTA0bHg6JTA0bHhcbiIsCgkgICAgICBhcmcsIGNvbnRleHQtPlNlZ0NzLCBjb250ZXh0LT5FaXAgKTsKICAgICAgRFBSSU5URigiIGVheD0lMDhseCBlYng9JTA4bHggZWN4PSUwOGx4IGVkeD0lMDhseCBlc2k9JTA4bHggZWRpPSUwOGx4XG4iLAoJICAgICAgY29udGV4dC0+RWF4LCBjb250ZXh0LT5FYngsIGNvbnRleHQtPkVjeCwgY29udGV4dC0+RWR4LAoJICAgICAgY29udGV4dC0+RXNpLCBjb250ZXh0LT5FZGkgKTsKICAgICAgRFBSSU5URigiIGVicD0lMDhseCBlc3A9JTA4bHggZHM9JTA0bHggZXM9JTA0bHggZnM9JTA0bHggZ3M9JTA0bHggZmxhZ3M9JTA4bHhcbiIsCgkgICAgICBjb250ZXh0LT5FYnAsIGNvbnRleHQtPkVzcCwgY29udGV4dC0+U2VnRHMsIGNvbnRleHQtPlNlZ0VzLAoJICAgICAgY29udGV4dC0+U2VnRnMsIGNvbnRleHQtPlNlZ0dzLCBjb250ZXh0LT5FRmxhZ3MgKTsKICAgICAgfQogICAgcmV0ID0gRE9TVk1fU2ltdWxhdGVJbnQoYXJnLCBjb250ZXh0LCBGQUxTRSk7CiAgICBpZiAoVFJBQ0VfT04ocmVsYXkpKSB7CiAgICAgIERQUklOVEYoIlJldCAgRE9TIGludCAweCUwMnggcmV0PSUwNGx4OiUwNGx4XG4iLAoJICAgICAgYXJnLCBjb250ZXh0LT5TZWdDcywgY29udGV4dC0+RWlwICk7CiAgICAgIERQUklOVEYoIiBlYXg9JTA4bHggZWJ4PSUwOGx4IGVjeD0lMDhseCBlZHg9JTA4bHggZXNpPSUwOGx4IGVkaT0lMDhseFxuIiwKCSAgICAgIGNvbnRleHQtPkVheCwgY29udGV4dC0+RWJ4LCBjb250ZXh0LT5FY3gsIGNvbnRleHQtPkVkeCwKCSAgICAgIGNvbnRleHQtPkVzaSwgY29udGV4dC0+RWRpICk7CiAgICAgIERQUklOVEYoIiBlYnA9JTA4bHggZXNwPSUwOGx4IGRzPSUwNGx4IGVzPSUwNGx4IGZzPSUwNGx4IGdzPSUwNGx4IGZsYWdzPSUwOGx4XG4iLAoJICAgICAgY29udGV4dC0+RWJwLCBjb250ZXh0LT5Fc3AsIGNvbnRleHQtPlNlZ0RzLCBjb250ZXh0LT5TZWdFcywKCSAgICAgIGNvbnRleHQtPlNlZ0ZzLCBjb250ZXh0LT5TZWdHcywgY29udGV4dC0+RUZsYWdzICk7CiAgICB9CiAgICByZXR1cm4gcmV0ID8gRVhDRVBUSU9OX0VYRUNVVEVfSEFORExFUiA6IEVYQ0VQVElPTl9DT05USU5VRV9FWEVDVVRJT047CgogIGNhc2UgRVhDRVBUSU9OX1ZNODZfU1RJOgogIC8qIGNhc2UgRVhDRVBUSU9OX1ZNODZfUElDUkVUVVJOOiAqLwogICAgSUZfU0VUKGNvbnRleHQpOwogICAgRW50ZXJDcml0aWNhbFNlY3Rpb24oJnFjcml0KTsKICAgIHNpZ19zZW50Kys7CiAgICB3aGlsZSAoTnRDdXJyZW50VGViKCktPmFsYXJtcykgewogICAgICBET1NWTV9RdWV1ZUV2ZW50KDAsRE9TX1BSSU9SSVRZX1JFQUxUSU1FLE5VTEwsTlVMTCk7CiAgICAgIC8qIGhtbSwgaW5zdGVhZCBvZiByZWx5aW5nIG9uIHRoaXMgc2lnbmFsIGNvdW50ZXIsIHdlIHNob3VsZAogICAgICAgKiBwcm9iYWJseSBjaGVjayBob3cgbWFueSB0aWNrcyBoYXZlICpyZWFsbHkqIHBhc3NlZCwgcHJvYmFibHkgdXNpbmcKICAgICAgICogUXVlcnlQZXJmb3JtYW5jZUNvdW50ZXIoKSBvciBzb21ldGhpbmcgbGlrZSB0aGF0ICovCiAgICAgIEludGVybG9ja2VkRGVjcmVtZW50KCYoTnRDdXJyZW50VGViKCktPmFsYXJtcykpOwogICAgfQogICAgVFJBQ0VfKGludCkoImNvbnRleHQ9JXAsIGN1cnJlbnQ9JXBcbiIsIGNvbnRleHQsIGN1cnJlbnRfY29udGV4dCk7CiAgICBUUkFDRV8oaW50KSgiY3M6aXA9JTA0bHg6JTA0bHgsIHNzOnNwPSUwNGx4OiUwNGx4XG4iLCBjb250ZXh0LT5TZWdDcywgY29udGV4dC0+RWlwLCBjb250ZXh0LT5TZWdTcywgY29udGV4dC0+RXNwKTsKICAgIGlmICghSVNWODYoY29udGV4dCkpIHsKICAgICAgRVJSXyhpbnQpKCJAIyYqJSUsIHdpbmVkb3Mgc2lnbmFsIGhhbmRsaW5nIGlzICpzdGlsbCogbWVzc2VkIHVwXG4iKTsKICAgIH0KICAgIFRSQUNFXyhpbnQpKCJET1MgdGFzayBlbmFibGVkIGludGVycnVwdHMgJXMgZXZlbnRzIHBlbmRpbmcsIHNlbmRpbmcgZXZlbnRzICh0aW1lPSVsZClcbiIsIElTX1BFTkQoY29udGV4dCk/IndpdGgiOiJ3aXRob3V0IiwgR2V0VGlja0NvdW50KCkpOwogICAgRE9TVk1fU2VuZFF1ZXVlZEV2ZW50cyhjb250ZXh0KTsKICAgIHNpZ19zZW50PTA7CiAgICBMZWF2ZUNyaXRpY2FsU2VjdGlvbigmcWNyaXQpOwogICAgcmV0dXJuIEVYQ0VQVElPTl9DT05USU5VRV9FWEVDVVRJT047CiAgfQogIHJldHVybiBFWENFUFRJT05fQ09OVElOVUVfU0VBUkNIOwp9CgppbnQgV0lOQVBJIERPU1ZNX0VudGVyKCBDT05URVhUODYgKmNvbnRleHQgKQp7CiAgQ09OVEVYVDg2ICpvbGRfY29udGV4dCA9IGN1cnJlbnRfY29udGV4dDsKCiAgY3VycmVudF9jb250ZXh0ID0gY29udGV4dDsKICBfX1RSWQogIHsKICAgIF9fd2luZV9lbnRlcl92bTg2KCBjb250ZXh0ICk7CiAgICBUUkFDRV8obW9kdWxlKSggInZtODYgcmV0dXJuZWQ6ICVzXG4iLCBzdHJlcnJvcihlcnJubykgKTsKICB9CiAgX19FWENFUFQoZXhjZXB0aW9uX2hhbmRsZXIpCiAgewogICAgVFJBQ0VfKG1vZHVsZSkoICJsZWF2aW5nIHZtODYgbW9kZVxuIiApOwogIH0KICBfX0VORFRSWQogIGN1cnJlbnRfY29udGV4dCA9IG9sZF9jb250ZXh0OwogIHJldHVybiAwOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCU91dFBJQyAoV0lORURPUy5AKQogKi8Kdm9pZCBXSU5BUEkgRE9TVk1fUElDX2lvcG9ydF9vdXQoIFdPUkQgcG9ydCwgQllURSB2YWwpCnsKICAgIExQRE9TRVZFTlQgZXZlbnQ7CgogICAgaWYgKChwb3J0PT0weDIwKSAmJiAodmFsPT0weDIwKSkgewogICAgICBFbnRlckNyaXRpY2FsU2VjdGlvbigmcWNyaXQpOwogICAgICBpZiAoY3VycmVudF9ldmVudCkgewoJLyogRU9JIChFbmQgT2YgSW50ZXJydXB0KSAqLwoJVFJBQ0UoInJlY2VpdmVkIEVPSSBmb3IgY3VycmVudCBJUlEsIGNsZWFyaW5nXG4iKTsKCWV2ZW50ID0gY3VycmVudF9ldmVudDsKCWN1cnJlbnRfZXZlbnQgPSBldmVudC0+bmV4dDsKCWlmIChldmVudC0+cmVsYXkpCgkoKmV2ZW50LT5yZWxheSkoTlVMTCxldmVudC0+ZGF0YSk7CglmcmVlKGV2ZW50KTsKCglpZiAocGVuZGluZ19ldmVudCkgewoJICAvKiBhbm90aGVyIGV2ZW50IGlzIHBlbmRpbmcsIHdoaWNoIHdlIHNob3VsZCBwcm9iYWJseQoJICAgKiBiZSBhYmxlIHRvIHByb2Nlc3Mgbm93ICovCgkgIFRSQUNFKCJhbm90aGVyIGV2ZW50IHBlbmRpbmcsIHNldHRpbmcgZmxhZ1xuIik7CgkgIGN1cnJlbnRfY29udGV4dC0+RUZsYWdzIHw9IFZJUF9NQVNLOwoJfQogICAgICB9IGVsc2UgewoJV0FSTigiRU9JIHdpdGhvdXQgYWN0aXZlIElSUVxuIik7CiAgICAgIH0KICAgICAgTGVhdmVDcml0aWNhbFNlY3Rpb24oJnFjcml0KTsKICAgIH0gZWxzZSB7CiAgICAgIEZJWE1FKCJ1bnJlY29nbml6ZWQgUElDIGNvbW1hbmQgJTAyeFxuIix2YWwpOwogICAgfQp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCVNldFRpbWVyIChXSU5FRE9TLkApCiAqLwp2b2lkIFdJTkFQSSBET1NWTV9TZXRUaW1lciggVUlOVCB0aWNrcyApCnsKICBzdHJ1Y3QgaXRpbWVydmFsIHRpbTsKCiAgaWYgKGRvc3ZtX3BpZCkgewogICAgLyogdGhlIFBDIGNsb2NrcyB0aWNrcyBhdCAxMTkzMTgwIEh6ICovCiAgICB0aW0uaXRfaW50ZXJ2YWwudHZfc2VjPTA7CiAgICB0aW0uaXRfaW50ZXJ2YWwudHZfdXNlYz1NdWxEaXYodGlja3MsMTAwMDAwMCwxMTkzMTgwKTsKICAgIC8qIHNhbml0eSBjaGVjayAqLwogICAgaWYgKCF0aW0uaXRfaW50ZXJ2YWwudHZfdXNlYykgdGltLml0X2ludGVydmFsLnR2X3VzZWM9MTsKICAgIC8qIGZpcnN0IHRpY2sgdmFsdWUgKi8KICAgIHRpbS5pdF92YWx1ZSA9IHRpbS5pdF9pbnRlcnZhbDsKICAgIFRSQUNFXyhpbnQpKCJzZXR0aW5nIHRpbWVyIHRpY2sgZGVsYXkgdG8gJWxkIHVzXG4iLCB0aW0uaXRfaW50ZXJ2YWwudHZfdXNlYyk7CiAgICBzZXRpdGltZXIoSVRJTUVSX1JFQUwsICZ0aW0sIE5VTEwpOwogIH0KfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCQlHZXRUaW1lciAoV0lORURPUy5AKQogKi8KVUlOVCBXSU5BUEkgRE9TVk1fR2V0VGltZXIoIHZvaWQgKQp7CiAgc3RydWN0IGl0aW1lcnZhbCB0aW07CgogIGlmIChkb3N2bV9waWQpIHsKICAgIGdldGl0aW1lcihJVElNRVJfUkVBTCwgJnRpbSk7CiAgICByZXR1cm4gTXVsRGl2KHRpbS5pdF92YWx1ZS50dl91c2VjLDExOTMxODAsMTAwMDAwMCk7CiAgfQogIHJldHVybiAwOwp9CgojZWxzZSAvKiAhTVpfU1VQUE9SVEVEICovCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCUVudGVyIChXSU5FRE9TLkApCiAqLwpJTlQgV0lOQVBJIERPU1ZNX0VudGVyKCBDT05URVhUODYgKmNvbnRleHQgKQp7CiBFUlJfKG1vZHVsZSkoIkRPUyByZWFsbW9kZSBub3Qgc3VwcG9ydGVkIG9uIHRoaXMgYXJjaGl0ZWN0dXJlIVxuIik7CiByZXR1cm4gLTE7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJV2FpdCAoV0lORURPUy5AKQogKi8Kdm9pZCBXSU5BUEkgRE9TVk1fV2FpdCggSU5UIHJlYWRfcGlwZSwgSEFORExFIGhPYmplY3QpIHt9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCU91dFBJQyAoV0lORURPUy5AKQogKi8Kdm9pZCBXSU5BUEkgRE9TVk1fUElDX2lvcG9ydF9vdXQoIFdPUkQgcG9ydCwgQllURSB2YWwpIHt9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCVNldFRpbWVyIChXSU5FRE9TLkApCiAqLwp2b2lkIFdJTkFQSSBET1NWTV9TZXRUaW1lciggVUlOVCB0aWNrcyApIHt9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCUdldFRpbWVyIChXSU5FRE9TLkApCiAqLwpVSU5UIFdJTkFQSSBET1NWTV9HZXRUaW1lciggdm9pZCApIHsgcmV0dXJuIDA7IH0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJUXVldWVFdmVudCAoV0lORURPUy5AKQogKi8Kdm9pZCBXSU5BUEkgRE9TVk1fUXVldWVFdmVudCggSU5UIGlycSwgSU5UIHByaW9yaXR5LCBET1NSRUxBWSByZWxheSwgTFBWT0lEIGRhdGEpCnsKICBpZiAoaXJxPDApIHsKICAgIC8qIGNhbGxiYWNrIGV2ZW50LCBwZXJmb3JtIGl0IHdpdGggZHVtbXkgY29udGV4dCAqLwogICAgQ09OVEVYVDg2IGNvbnRleHQ7CiAgICBtZW1zZXQoJmNvbnRleHQsMCxzaXplb2YoY29udGV4dCkpOwogICAgKCpyZWxheSkoJmNvbnRleHQsZGF0YSk7CiAgfSBlbHNlIHsKICAgIEVSUigiSVJRIHdpdGhvdXQgRE9TIHRhc2s6IHNob3VsZCBub3QgaGFwcGVuIik7CiAgfQp9CgojZW5kaWYKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCSAgICBET1NWTV9HZXRSTUhhbmRsZXIKICoKICogUmV0dXJuIHRoZSByZWFsIG1vZGUgaW50ZXJydXB0IHZlY3RvciBmb3IgYSBnaXZlbiBpbnRlcnJ1cHQuCiAqLwpGQVJQUk9DMTYgRE9TVk1fR2V0Uk1IYW5kbGVyKCBCWVRFIGludG51bSApCnsKICAgIHJldHVybiAoKEZBUlBST0MxNiopRE9TTUVNX1N5c3RlbUJhc2UoKSlbaW50bnVtXTsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCSAgICBET1NWTV9TZXRSTUhhbmRsZXIKICoKICogU2V0IHRoZSByZWFsIG1vZGUgaW50ZXJydXB0IGhhbmRsZXIgZm9yIGEgZ2l2ZW4gaW50ZXJydXB0LgogKi8Kdm9pZCBET1NWTV9TZXRSTUhhbmRsZXIoIEJZVEUgaW50bnVtLCBGQVJQUk9DMTYgaGFuZGxlciApCnsKICAgIFRSQUNFKCJTZXQgcmVhbCBtb2RlIGludGVycnVwdCB2ZWN0b3IgJTAyeCA8LSAlMDR4OiUwNHhcbiIsCiAgICAgICAgICAgICAgICAgaW50bnVtLCBISVdPUkQoaGFuZGxlciksIExPV09SRChoYW5kbGVyKSApOwogICAgKChGQVJQUk9DMTYqKURPU01FTV9TeXN0ZW1CYXNlKCkpW2ludG51bV0gPSBoYW5kbGVyOwp9CgoKc3RhdGljIGNvbnN0IElOVFBST0MgcmVhbF9tb2RlX2hhbmRsZXJzW10gPQp7CiAgICAvKiAwMCAqLyAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLAogICAgLyogMDggKi8gMCwgRE9TVk1fSW50MDlIYW5kbGVyLCAwLCAwLCAwLCAwLCAwLCAwLAogICAgLyogMTAgKi8gRE9TVk1fSW50MTBIYW5kbGVyLCBJTlRfSW50MTFIYW5kbGVyLCBJTlRfSW50MTJIYW5kbGVyLCBJTlRfSW50MTNIYW5kbGVyLAogICAgICAgICAgICAgMCwgSU5UX0ludDE1SGFuZGxlciwgRE9TVk1fSW50MTZIYW5kbGVyLCBET1NWTV9JbnQxN0hhbmRsZXIsCiAgICAvKiAxOCAqLyAwLCAwLCBJTlRfSW50MWFIYW5kbGVyLCAwLCAwLCAwLCAwLCAwLAogICAgLyogMjAgKi8gRE9TVk1fSW50MjBIYW5kbGVyLCBET1NWTV9JbnQyMUhhbmRsZXIsIDAsIDAsIDAsIElOVF9JbnQyNUhhbmRsZXIsIDAsIDAsCiAgICAvKiAyOCAqLyAwLCBET1NWTV9JbnQyOUhhbmRsZXIsIElOVF9JbnQyYUhhbmRsZXIsIDAsIDAsIDAsIDAsIElOVF9JbnQyZkhhbmRsZXIsCiAgICAvKiAzMCAqLyAwLCBET1NWTV9JbnQzMUhhbmRsZXIsIDAsIERPU1ZNX0ludDMzSGFuZGxlciwgMCwgMCwgMCwgMCwKICAgIC8qIDM4ICovIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsCiAgICAvKiA0MCAqLyAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLAogICAgLyogNDggKi8gMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgCiAgICAvKiA1MCAqLyAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLAogICAgLyogNTggKi8gMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwKICAgIC8qIDYwICovIDAsIDAsIDAsIDAsIDAsIDAsIDAsIERPU1ZNX0ludDY3SGFuZGxlcgp9OwoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCSAgICBET1NWTV9SZWFsTW9kZUludGVycnVwdAogKgogKiBIYW5kbGUgcmVhbCBtb2RlIGludGVycnVwdHMKICovCnZvaWQgRE9TVk1fUmVhbE1vZGVJbnRlcnJ1cHQoIEJZVEUgaW50bnVtLCBDT05URVhUODYgKmNvbnRleHQgKQp7CiAgICBpZiAoaW50bnVtIDwgc2l6ZW9mKHJlYWxfbW9kZV9oYW5kbGVycykvc2l6ZW9mKElOVFBST0MpICYmIHJlYWxfbW9kZV9oYW5kbGVyc1tpbnRudW1dKQogICAgICAgICgqcmVhbF9tb2RlX2hhbmRsZXJzW2ludG51bV0pKGNvbnRleHQpOwogICAgZWxzZQogICAgewogICAgICAgIEZJWE1FKCJVbmtub3duIEludGVycnVwdCBpbiBET1MgbW9kZTogMHgleFxuIiwgaW50bnVtKTsKICAgICAgICBGSVhNRSgiICAgIGVheD0lMDhseCBlYng9JTA4bHggZWN4PSUwOGx4IGVkeD0lMDhseFxuIiwKICAgICAgICAgICAgICBjb250ZXh0LT5FYXgsIGNvbnRleHQtPkVieCwgY29udGV4dC0+RWN4LCBjb250ZXh0LT5FZHgpOwogICAgICAgIEZJWE1FKCIgICAgZXNpPSUwOGx4IGVkaT0lMDhseCBkcz0lMDRseCBlcz0lMDRseFxuIiwKICAgICAgICAgICAgICBjb250ZXh0LT5Fc2ksIGNvbnRleHQtPkVkaSwgY29udGV4dC0+U2VnRHMsIGNvbnRleHQtPlNlZ0VzICk7CiAgICB9Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkgICAgRE9TVk1fSW5pdAogKi8KQk9PTCBXSU5BUEkgRE9TVk1fSW5pdCggSElOU1RBTkNFIGhpbnN0RExMLCBEV09SRCBmZHdSZWFzb24sIExQVk9JRCBscHZSZXNlcnZlZCApCnsKICAgIFRSQUNFXyhtb2R1bGUpKCIoMHglMDh4LCVsZCwlcClcbiIsIGhpbnN0RExMLCBmZHdSZWFzb24sIGxwdlJlc2VydmVkKTsKCiAgICBpZiAoZmR3UmVhc29uID09IERMTF9QUk9DRVNTX0FUVEFDSCkKICAgIHsKICAgICAgICAvKiBpbml0aWFsaXplIHRoZSBtZW1vcnkgKi8KICAgICAgICBUUkFDRSgiSW5pdGlhbGl6aW5nIERPUyBtZW1vcnkgc3RydWN0dXJlc1xuIik7CiAgICAgICAgRE9TTUVNX0luaXQoIFRSVUUgKTsKICAgICAgICBET1NERVZfSW5zdGFsbERPU0RldmljZXMoKTsKICAgIH0KICAgIHJldHVybiBUUlVFOwp9Cg==