LyoKICogTm9uLWNsaWVudCBhcmVhIHdpbmRvdyBmdW5jdGlvbnMKICoKICogQ29weXJpZ2h0IDE5OTQgQWxleGFuZHJlIEp1bGxpYXJkCiAqCiAqLwoKI2luY2x1ZGUgIndpbmRlZi5oIgojaW5jbHVkZSAid2luZ2RpLmgiCiNpbmNsdWRlICJ3aW5lL3dpbnVzZXIxNi5oIgojaW5jbHVkZSAidmVyc2lvbi5oIgojaW5jbHVkZSAid2luLmgiCiNpbmNsdWRlICJtZXNzYWdlLmgiCiNpbmNsdWRlICJ1c2VyLmgiCiNpbmNsdWRlICJoZWFwLmgiCiNpbmNsdWRlICJkY2UuaCIKI2luY2x1ZGUgImNvbnRyb2xzLmgiCiNpbmNsdWRlICJjdXJzb3JpY29uLmgiCiNpbmNsdWRlICJ3aW5wb3MuaCIKI2luY2x1ZGUgImhvb2suaCIKI2luY2x1ZGUgIm5vbmNsaWVudC5oIgojaW5jbHVkZSAicXVldWUuaCIKI2luY2x1ZGUgInR3ZWFrLmgiCiNpbmNsdWRlICJkZWJ1Z3Rvb2xzLmgiCiNpbmNsdWRlICJvcHRpb25zLmgiCiNpbmNsdWRlICJzaGVsbGFwaS5oIgojaW5jbHVkZSAiY2FjaGUuaCIKI2luY2x1ZGUgImJpdG1hcC5oIgoKREVGQVVMVF9ERUJVR19DSEFOTkVMKG5vbmNsaWVudCk7CkRFQ0xBUkVfREVCVUdfQ0hBTk5FTChzaGVsbCk7CgpCT09MIE5DX0RyYXdHcmF5QnV0dG9uKEhEQyBoZGMsIGludCB4LCBpbnQgeSk7CgpzdGF0aWMgSEJJVE1BUDE2IGhiaXRtYXBDbG9zZSA9IDA7CnN0YXRpYyBIQklUTUFQMTYgaGJpdG1hcENsb3NlRCA9IDA7CnN0YXRpYyBIQklUTUFQMTYgaGJpdG1hcE1pbmltaXplID0gMDsKc3RhdGljIEhCSVRNQVAxNiBoYml0bWFwTWluaW1pemVEID0gMDsKc3RhdGljIEhCSVRNQVAxNiBoYml0bWFwTWF4aW1pemUgPSAwOwpzdGF0aWMgSEJJVE1BUDE2IGhiaXRtYXBNYXhpbWl6ZUQgPSAwOwpzdGF0aWMgSEJJVE1BUDE2IGhiaXRtYXBSZXN0b3JlID0gMDsKc3RhdGljIEhCSVRNQVAxNiBoYml0bWFwUmVzdG9yZUQgPSAwOwoKQllURSBscEdyYXlNYXNrW10gPSB7IDB4QUEsIDB4QTAsCgkJICAgICAgMHg1NSwgMHg1MCwgIAoJCSAgICAgIDB4QUEsIDB4QTAsCgkJICAgICAgMHg1NSwgMHg1MCwgIAoJCSAgICAgIDB4QUEsIDB4QTAsCgkJICAgICAgMHg1NSwgMHg1MCwgIAoJCSAgICAgIDB4QUEsIDB4QTAsCgkJICAgICAgMHg1NSwgMHg1MCwgIAoJCSAgICAgIDB4QUEsIDB4QTAsCgkJICAgICAgMHg1NSwgMHg1MH07CgojZGVmaW5lIFNDX0FCT1VUV0lORSAgICAJKFNDX1NDUkVFTlNBVkUrMSkKI2RlZmluZSBTQ19QVVRNQVJLICAgICAJCShTQ19TQ1JFRU5TQVZFKzIpCgogIC8qIFNvbWUgdXNlZnVsIG1hY3JvcyAqLwojZGVmaW5lIEhBU19ETEdGUkFNRShzdHlsZSxleFN0eWxlKSBcCiAgICAoKChleFN0eWxlKSAmIFdTX0VYX0RMR01PREFMRlJBTUUpIHx8IFwKICAgICAoKChzdHlsZSkgJiBXU19ETEdGUkFNRSkgJiYgISgoc3R5bGUpICYgV1NfVEhJQ0tGUkFNRSkpKQoKI2RlZmluZSBIQVNfVEhJQ0tGUkFNRShzdHlsZSxleFN0eWxlKSBcCiAgICAoKChzdHlsZSkgJiBXU19USElDS0ZSQU1FKSAmJiBcCiAgICAgISgoKHN0eWxlKSAmIChXU19ETEdGUkFNRXxXU19CT1JERVIpKSA9PSBXU19ETEdGUkFNRSkpCgojZGVmaW5lIEhBU19USElORlJBTUUoc3R5bGUpIFwKICAgICgoKHN0eWxlKSAmIFdTX0JPUkRFUikgfHwgISgoc3R5bGUpICYgKFdTX0NISUxEIHwgV1NfUE9QVVApKSkKCiNkZWZpbmUgSEFTX0JJR0ZSQU1FKHN0eWxlLGV4U3R5bGUpIFwKICAgICgoKHN0eWxlKSAmIChXU19USElDS0ZSQU1FIHwgV1NfRExHRlJBTUUpKSB8fCBcCiAgICAgKChleFN0eWxlKSAmIFdTX0VYX0RMR01PREFMRlJBTUUpKQoKI2RlZmluZSBIQVNfQU5ZRlJBTUUoc3R5bGUsZXhTdHlsZSkgXAogICAgKCgoc3R5bGUpICYgKFdTX1RISUNLRlJBTUUgfCBXU19ETEdGUkFNRSB8IFdTX0JPUkRFUikpIHx8IFwKICAgICAoKGV4U3R5bGUpICYgV1NfRVhfRExHTU9EQUxGUkFNRSkgfHwgXAogICAgICEoKHN0eWxlKSAmIChXU19DSElMRCB8IFdTX1BPUFVQKSkpCgojZGVmaW5lIEhBU19NRU5VKHcpICAoISgodyktPmR3U3R5bGUgJiBXU19DSElMRCkgJiYgKCh3KS0+d0lEbWVudSAhPSAwKSkKCiNkZWZpbmUgT05fTEVGVF9CT1JERVIoaGl0KSBcCiAoKChoaXQpID09IEhUTEVGVCkgfHwgKChoaXQpID09IEhUVE9QTEVGVCkgfHwgKChoaXQpID09IEhUQk9UVE9NTEVGVCkpCiNkZWZpbmUgT05fUklHSFRfQk9SREVSKGhpdCkgXAogKCgoaGl0KSA9PSBIVFJJR0hUKSB8fCAoKGhpdCkgPT0gSFRUT1BSSUdIVCkgfHwgKChoaXQpID09IEhUQk9UVE9NUklHSFQpKQojZGVmaW5lIE9OX1RPUF9CT1JERVIoaGl0KSBcCiAoKChoaXQpID09IEhUVE9QKSB8fCAoKGhpdCkgPT0gSFRUT1BMRUZUKSB8fCAoKGhpdCkgPT0gSFRUT1BSSUdIVCkpCiNkZWZpbmUgT05fQk9UVE9NX0JPUkRFUihoaXQpIFwKICgoKGhpdCkgPT0gSFRCT1RUT00pIHx8ICgoaGl0KSA9PSBIVEJPVFRPTUxFRlQpIHx8ICgoaGl0KSA9PSBIVEJPVFRPTVJJR0hUKSkKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgICAgICAgV0lOX1dpbmRvd05lZWRzV01Cb3JkZXIKICoKICogVGhpcyBtZXRob2QgZGVmaW5lcyB0aGUgcnVsZXMgZm9yIGEgd2luZG93IHRvIGhhdmUgYSBXTSBib3JkZXIsCiAqIGNhcHRpb24uLi4gIEl0IGlzIHVzZWQgZm9yIGNvbnNpdGVuY3kgcHVycG9zZXMuCiAqLwpCT09MIFdJTl9XaW5kb3dOZWVkc1dNQm9yZGVyKCBEV09SRCBzdHlsZSwgRFdPUkQgZXhTdHlsZSApCnsKICAgIGlmICghKHN0eWxlICYgV1NfQ0hJTEQpICYmIAoJT3B0aW9ucy5tYW5hZ2VkICAmJgoJIShleFN0eWxlICYgV1NfRVhfVE9PTFdJTkRPVykgJiYKICAgICAgICAoICgoc3R5bGUgJiBXU19DQVBUSU9OKSA9PSBXU19DQVBUSU9OKSB8fAoJICAoc3R5bGUgJiBXU19USElDS0ZSQU1FKSkpCiAgICAgICAgcmV0dXJuIFRSVUU7CiAgICBpZiAoZXhTdHlsZSAmIFdTX0VYX1RSQVlXSU5ET1cpCglyZXR1cm4gVFJVRTsKICAgIHJldHVybiBGQUxTRTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgICAgICBOQ19BZGp1c3RSZWN0CiAqCiAqIENvbXB1dGUgdGhlIHNpemUgb2YgdGhlIHdpbmRvdyByZWN0YW5nbGUgZnJvbSB0aGUgc2l6ZSBvZiB0aGUKICogY2xpZW50IHJlY3RhbmdsZS4KICovCnN0YXRpYyB2b2lkIE5DX0FkanVzdFJlY3QoIExQUkVDVDE2IHJlY3QsIERXT1JEIHN0eWxlLCBCT09MIG1lbnUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgIERXT1JEIGV4U3R5bGUgKQp7CiAgICBpZiAoVFdFQUtfV2luZUxvb2sgPiBXSU4zMV9MT09LKQoJRVJSKCJDYWxsZWQgaW4gV2luOTUgbW9kZS4gQWllZSEgUGxlYXNlIHJlcG9ydCB0aGlzLlxuIiApOwoKICAgIGlmKHN0eWxlICYgV1NfSUNPTklDKSByZXR1cm47CiAgICAvKiBEZWNpZGUgaWYgdGhlIHdpbmRvdyB3aWxsIGJlIG1hbmFnZWQgKHNlZSBDcmVhdGVXaW5kb3dFeCkgKi8KICAgIGlmICghV0lOX1dpbmRvd05lZWRzV01Cb3JkZXIoc3R5bGUsIGV4U3R5bGUpKQogICAgewogICAgICAgIGlmIChIQVNfVEhJQ0tGUkFNRSggc3R5bGUsIGV4U3R5bGUgKSkKICAgICAgICAgICAgSW5mbGF0ZVJlY3QxNiggcmVjdCwgR2V0U3lzdGVtTWV0cmljcyhTTV9DWEZSQU1FKSwgR2V0U3lzdGVtTWV0cmljcyhTTV9DWUZSQU1FKSApOwogICAgICAgIGVsc2UKICAgICAgICBpZiAoSEFTX0RMR0ZSQU1FKCBzdHlsZSwgZXhTdHlsZSApKQogICAgICAgICAgICBJbmZsYXRlUmVjdDE2KCByZWN0LCBHZXRTeXN0ZW1NZXRyaWNzKFNNX0NYRExHRlJBTUUpLCBHZXRTeXN0ZW1NZXRyaWNzKFNNX0NZRExHRlJBTUUpICk7CiAgICAgICAgZWxzZQogICAgICAgIGlmIChIQVNfVEhJTkZSQU1FKCBzdHlsZSApKQogICAgICAgICAgICBJbmZsYXRlUmVjdDE2KCByZWN0LCBHZXRTeXN0ZW1NZXRyaWNzKFNNX0NYQk9SREVSKSwgR2V0U3lzdGVtTWV0cmljcyhTTV9DWUJPUkRFUikpOwoKICAgICAgICBpZiAoKHN0eWxlICYgV1NfQ0FQVElPTikgPT0gV1NfQ0FQVElPTikKICAgICAgICAgICAgcmVjdC0+dG9wIC09IEdldFN5c3RlbU1ldHJpY3MoU01fQ1lDQVBUSU9OKSAtIEdldFN5c3RlbU1ldHJpY3MoU01fQ1lCT1JERVIpOwogICAgfQogICAgaWYgKG1lbnUpIHJlY3QtPnRvcCAtPSBHZXRTeXN0ZW1NZXRyaWNzKFNNX0NZTUVOVSkgKyBHZXRTeXN0ZW1NZXRyaWNzKFNNX0NZQk9SREVSKTsKCiAgICBpZiAoc3R5bGUgJiBXU19WU0NST0xMKSB7CiAgICAgIHJlY3QtPnJpZ2h0ICArPSBHZXRTeXN0ZW1NZXRyaWNzKFNNX0NYVlNDUk9MTCkgLSAxOwogICAgICBpZighSEFTX0FOWUZSQU1FKCBzdHlsZSwgZXhTdHlsZSApKQoJIHJlY3QtPnJpZ2h0Kys7CiAgICB9CgogICAgaWYgKHN0eWxlICYgV1NfSFNDUk9MTCkgewogICAgICByZWN0LT5ib3R0b20gKz0gR2V0U3lzdGVtTWV0cmljcyhTTV9DWUhTQ1JPTEwpIC0gMTsKICAgICAgaWYoIUhBU19BTllGUkFNRSggc3R5bGUsIGV4U3R5bGUgKSkKCSByZWN0LT5ib3R0b20rKzsKICAgIH0KfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogTkNfQWRqdXN0UmVjdE91dGVyOTUKICoKICogQ29tcHV0ZXMgdGhlIHNpemUgb2YgdGhlICJvdXRzaWRlIiBwYXJ0cyBvZiB0aGUgd2luZG93IGJhc2VkIG9uIHRoZQogKiBwYXJhbWV0ZXJzIG9mIHRoZSBjbGllbnQgYXJlYS4KICoKICsgUEFSQU1TCiAqICAgICBMUFJFQ1QxNiAgcmVjdAogKiAgICAgRFdPUkQgIHN0eWxlCiAqICAgICBCT09MICBtZW51CiAqICAgICBEV09SRCAgZXhTdHlsZQogKgogKiBOT1RFUwogKiAgICAgIk91dGVyIiBwYXJ0cyBvZiBhIHdpbmRvdyBtZWFucyB0aGUgd2hvbGUgd2luZG93IGZyYW1lLCBjYXB0aW9uIGFuZAogKiAgICAgbWVudSBiYXIuIEl0IGRvZXMgbm90IGluY2x1ZGUgImlubmVyIiBwYXJ0cyBvZiB0aGUgZnJhbWUgbGlrZSBjbGllbnQKICogICAgIGVkZ2UsIHN0YXRpYyBlZGdlIG9yIHNjcm9sbCBiYXJzLgogKgogKiBSZXZpc2lvbiBoaXN0b3J5CiAqICAgICAwNS1KdWwtMTk5NyBEYXZlIEN1dGhiZXJ0IChkYWN1dEBlY2UuY211LmVkdSkKICogICAgICAgIE9yaWdpbmFsIChOQ19BZGp1c3RSZWN0OTUpIGN1dCAmIHBhc3RlIGZyb20gTkNfQWRqdXN0UmVjdAogKgogKiAgICAgMjAtSnVuLTE5OTggRXJpYyBLb2hsIChla29obEBhYm8ucmhlaW4temVpdHVuZy5kZSkKICogICAgICAgIFNwbGl0IE5DX0FkanVzdFJlY3Q5NSBpbnRvIE5DX0FkanVzdFJlY3RPdXRlcjk1IGFuZAogKiAgICAgICAgTkNfQWRqdXN0UmVjdElubmVyOTUgYW5kIGFkZGVkIGhhbmRsaW5nIG9mIFdpbjk1IHN0eWxlcy4KICoKICogICAgIDI4LUp1bC0xOTk5IE92ZSBL5XZlbiAob3Zla0BhcmN0aWNuZXQubm8pCiAqICAgICAgICBTdHJlYW1saW5lZCB3aW5kb3cgc3R5bGUgY2hlY2tzLgogKgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCgpzdGF0aWMgdm9pZApOQ19BZGp1c3RSZWN0T3V0ZXI5NSAoTFBSRUNUMTYgcmVjdCwgRFdPUkQgc3R5bGUsIEJPT0wgbWVudSwgRFdPUkQgZXhTdHlsZSkKewogICAgaWYoc3R5bGUgJiBXU19JQ09OSUMpIHJldHVybjsKCiAgICAvKiBEZWNpZGUgaWYgdGhlIHdpbmRvdyB3aWxsIGJlIG1hbmFnZWQgKHNlZSBDcmVhdGVXaW5kb3dFeCkgKi8KICAgIGlmICghV0lOX1dpbmRvd05lZWRzV01Cb3JkZXIoc3R5bGUsIGV4U3R5bGUpKQogICAgewogICAgICAgIGlmIChIQVNfVEhJQ0tGUkFNRSggc3R5bGUsIGV4U3R5bGUgKSkKICAgICAgICAgICAgSW5mbGF0ZVJlY3QxNiggcmVjdCwgR2V0U3lzdGVtTWV0cmljcyhTTV9DWEZSQU1FKSwgR2V0U3lzdGVtTWV0cmljcyhTTV9DWUZSQU1FKSApOwogICAgICAgIGVsc2UKICAgICAgICBpZiAoSEFTX0RMR0ZSQU1FKCBzdHlsZSwgZXhTdHlsZSApKQogICAgICAgICAgICBJbmZsYXRlUmVjdDE2KHJlY3QsIEdldFN5c3RlbU1ldHJpY3MoU01fQ1hETEdGUkFNRSksIEdldFN5c3RlbU1ldHJpY3MoU01fQ1lETEdGUkFNRSkgKTsKICAgICAgICBlbHNlCiAgICAgICAgaWYgKEhBU19USElORlJBTUUoIHN0eWxlICkpCiAgICAgICAgICAgIEluZmxhdGVSZWN0MTYoIHJlY3QsIEdldFN5c3RlbU1ldHJpY3MoU01fQ1hCT1JERVIpLCBHZXRTeXN0ZW1NZXRyaWNzKFNNX0NZQk9SREVSKSk7CgogICAgICAgIGlmICgoc3R5bGUgJiBXU19DQVBUSU9OKSA9PSBXU19DQVBUSU9OKQogICAgICAgIHsKCSAgICBpZiAoZXhTdHlsZSAmIFdTX0VYX1RPT0xXSU5ET1cpCgkJcmVjdC0+dG9wIC09IEdldFN5c3RlbU1ldHJpY3MoU01fQ1lTTUNBUFRJT04pOwoJICAgIGVsc2UKCQlyZWN0LT50b3AgLT0gR2V0U3lzdGVtTWV0cmljcyhTTV9DWUNBUFRJT04pOwogICAgICAgIH0KICAgIH0KCiAgICBpZiAobWVudSkKCXJlY3QtPnRvcCAtPSBHZXRTeXN0ZW1NZXRyaWNzKFNNX0NZTUVOVSk7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIE5DX0FkanVzdFJlY3RJbm5lcjk1CiAqCiAqIENvbXB1dGVzIHRoZSBzaXplIG9mIHRoZSAiaW5zaWRlIiBwYXJ0IG9mIHRoZSB3aW5kb3cgYmFzZWQgb24gdGhlCiAqIHBhcmFtZXRlcnMgb2YgdGhlIGNsaWVudCBhcmVhLgogKgogKyBQQVJBTVMKICogICAgIExQUkVDVDE2IHJlY3QKICogICAgIERXT1JEICAgIHN0eWxlCiAqICAgICBEV09SRCAgICBleFN0eWxlCiAqCiAqIE5PVEVTCiAqICAgICAiSW5uZXIiIHBhcnQgb2YgYSB3aW5kb3cgbWVhbnMgdGhlIHdpbmRvdyBmcmFtZSBpbnNpZGUgb2YgdGhlIGZsYXQKICogICAgIHdpbmRvdyBmcmFtZS4gSXQgaW5jbHVkZXMgdGhlIGNsaWVudCBlZGdlLCB0aGUgc3RhdGljIGVkZ2UgYW5kIHRoZQogKiAgICAgc2Nyb2xsIGJhcnMuCiAqCiAqIFJldmlzaW9uIGhpc3RvcnkKICogICAgIDA1LUp1bC0xOTk3IERhdmUgQ3V0aGJlcnQgKGRhY3V0QGVjZS5jbXUuZWR1KQogKiAgICAgICAgT3JpZ2luYWwgKE5DX0FkanVzdFJlY3Q5NSkgY3V0ICYgcGFzdGUgZnJvbSBOQ19BZGp1c3RSZWN0CiAqCiAqICAgICAyMC1KdW4tMTk5OCBFcmljIEtvaGwgKGVrb2hsQGFiby5yaGVpbi16ZWl0dW5nLmRlKQogKiAgICAgICAgU3BsaXQgTkNfQWRqdXN0UmVjdDk1IGludG8gTkNfQWRqdXN0UmVjdE91dGVyOTUgYW5kCiAqICAgICAgICBOQ19BZGp1c3RSZWN0SW5uZXI5NSBhbmQgYWRkZWQgaGFuZGxpbmcgb2YgV2luOTUgc3R5bGVzLgogKgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCgpzdGF0aWMgdm9pZApOQ19BZGp1c3RSZWN0SW5uZXI5NSAoTFBSRUNUMTYgcmVjdCwgRFdPUkQgc3R5bGUsIERXT1JEIGV4U3R5bGUpCnsKICAgIGlmKHN0eWxlICYgV1NfSUNPTklDKSByZXR1cm47CgogICAgaWYgKGV4U3R5bGUgJiBXU19FWF9DTElFTlRFREdFKQoJSW5mbGF0ZVJlY3QxNiAocmVjdCwgR2V0U3lzdGVtTWV0cmljcyhTTV9DWEVER0UpLCBHZXRTeXN0ZW1NZXRyaWNzKFNNX0NZRURHRSkpOwoKICAgIGlmIChleFN0eWxlICYgV1NfRVhfU1RBVElDRURHRSkKCUluZmxhdGVSZWN0MTYgKHJlY3QsIEdldFN5c3RlbU1ldHJpY3MoU01fQ1hCT1JERVIpLCBHZXRTeXN0ZW1NZXRyaWNzKFNNX0NZQk9SREVSKSk7CgogICAgaWYgKHN0eWxlICYgV1NfVlNDUk9MTCkgcmVjdC0+cmlnaHQgICs9IEdldFN5c3RlbU1ldHJpY3MoU01fQ1hWU0NST0xMKTsKICAgIGlmIChzdHlsZSAmIFdTX0hTQ1JPTEwpIHJlY3QtPmJvdHRvbSArPSBHZXRTeXN0ZW1NZXRyaWNzKFNNX0NZSFNDUk9MTCk7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCURyYXdDYXB0aW9uIChVU0VSLjY2MCkgRHJhd3MgYSBjYXB0aW9uIGJhcgogKgogKiBQQVJBTVMKICogICAgIGh3bmQgICBbSV0KICogICAgIGhkYyAgICBbSV0KICogICAgIGxwUmVjdCBbSV0KICogICAgIHVGbGFncyBbSV0KICoKICogUkVUVVJOUwogKiAgICAgU3VjY2VzczoKICogICAgIEZhaWx1cmU6CiAqLwoKQk9PTDE2IFdJTkFQSQpEcmF3Q2FwdGlvbjE2IChIV05EMTYgaHduZCwgSERDMTYgaGRjLCBjb25zdCBSRUNUMTYgKnJlY3QsIFVJTlQxNiB1RmxhZ3MpCnsKICAgIFJFQ1QgcmVjdDMyOwoKICAgIGlmIChyZWN0KQoJQ09OVl9SRUNUMTZUTzMyIChyZWN0LCAmcmVjdDMyKTsKCiAgICByZXR1cm4gKEJPT0wxNilEcmF3Q2FwdGlvblRlbXBBIChod25kLCBoZGMsIHJlY3QgPyAmcmVjdDMyIDogTlVMTCwKCQkJCSAgICAgICAwLCAwLCBOVUxMLCB1RmxhZ3MgJiAweDFGKTsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJRHJhd0NhcHRpb24gKFVTRVIzMi5AKSBEcmF3cyBhIGNhcHRpb24gYmFyCiAqCiAqIFBBUkFNUwogKiAgICAgaHduZCAgIFtJXQogKiAgICAgaGRjICAgIFtJXQogKiAgICAgbHBSZWN0IFtJXQogKiAgICAgdUZsYWdzIFtJXQogKgogKiBSRVRVUk5TCiAqICAgICBTdWNjZXNzOgogKiAgICAgRmFpbHVyZToKICovCgpCT09MIFdJTkFQSQpEcmF3Q2FwdGlvbiAoSFdORCBod25kLCBIREMgaGRjLCBjb25zdCBSRUNUICpscFJlY3QsIFVJTlQgdUZsYWdzKQp7CiAgICByZXR1cm4gRHJhd0NhcHRpb25UZW1wQSAoaHduZCwgaGRjLCBscFJlY3QsIDAsIDAsIE5VTEwsIHVGbGFncyAmIDB4MUYpOwp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCQlEcmF3Q2FwdGlvblRlbXAgKFVTRVIuNjU3KQogKgogKiBQQVJBTVMKICoKICogUkVUVVJOUwogKiAgICAgU3VjY2VzczoKICogICAgIEZhaWx1cmU6CiAqLwoKQk9PTDE2IFdJTkFQSQpEcmF3Q2FwdGlvblRlbXAxNiAoSFdORDE2IGh3bmQsIEhEQzE2IGhkYywgY29uc3QgUkVDVDE2ICpyZWN0LCBIRk9OVDE2IGhGb250LAoJCSAgIEhJQ09OMTYgaEljb24sIExQQ1NUUiBzdHIsIFVJTlQxNiB1RmxhZ3MpCnsKICAgIFJFQ1QgcmVjdDMyOwoKICAgIGlmIChyZWN0KQoJQ09OVl9SRUNUMTZUTzMyKHJlY3QsJnJlY3QzMik7CgogICAgcmV0dXJuIChCT09MMTYpRHJhd0NhcHRpb25UZW1wQSAoaHduZCwgaGRjLCByZWN0PyZyZWN0MzI6TlVMTCwgaEZvbnQsCgkJCQkgICAgICAgaEljb24sIHN0ciwgdUZsYWdzICYgMHgxRik7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCURyYXdDYXB0aW9uVGVtcEEgKFVTRVIzMi5AKQogKgogKiBQQVJBTVMKICoKICogUkVUVVJOUwogKiAgICAgU3VjY2VzczoKICogICAgIEZhaWx1cmU6CiAqLwoKQk9PTCBXSU5BUEkKRHJhd0NhcHRpb25UZW1wQSAoSFdORCBod25kLCBIREMgaGRjLCBjb25zdCBSRUNUICpyZWN0LCBIRk9OVCBoRm9udCwKCQkgICAgSElDT04gaEljb24sIExQQ1NUUiBzdHIsIFVJTlQgdUZsYWdzKQp7CiAgICBSRUNUICAgcmMgPSAqcmVjdDsKCiAgICBUUkFDRSgiKCUwOHgsJTA4eCwlcCwlMDh4LCUwOHgsXCIlc1wiLCUwOHgpXG4iLAogICAgICAgICAgaHduZCwgaGRjLCByZWN0LCBoRm9udCwgaEljb24sIHN0ciwgdUZsYWdzKTsKCiAgICAvKiBkcmF3aW5nIGJhY2tncm91bmQgKi8KICAgIGlmICh1RmxhZ3MgJiBEQ19JTkJVVFRPTikgewoJRmlsbFJlY3QgKGhkYywgJnJjLCBHZXRTeXNDb2xvckJydXNoIChDT0xPUl8zREZBQ0UpKTsKCglpZiAodUZsYWdzICYgRENfQUNUSVZFKSB7CgkgICAgSEJSVVNIIGhiciA9IFNlbGVjdE9iamVjdCAoaGRjLCBDQUNIRV9HZXRQYXR0ZXJuNTVBQUJydXNoICgpKTsKCSAgICBQYXRCbHQgKGhkYywgcmMubGVmdCwgcmMudG9wLAoJCSAgICAgIHJjLnJpZ2h0LXJjLmxlZnQsIHJjLmJvdHRvbS1yYy50b3AsIDB4RkEwMDg5KTsKCSAgICBTZWxlY3RPYmplY3QgKGhkYywgaGJyKTsKCX0KICAgIH0KICAgIGVsc2UgewoJRmlsbFJlY3QgKGhkYywgJnJjLCBHZXRTeXNDb2xvckJydXNoICgodUZsYWdzICYgRENfQUNUSVZFKSA/CgkJICAgIENPTE9SX0FDVElWRUNBUFRJT04gOiBDT0xPUl9JTkFDVElWRUNBUFRJT04pKTsKICAgIH0KCgogICAgLyogZHJhd2luZyBpY29uICovCiAgICBpZiAoKHVGbGFncyAmIERDX0lDT04pICYmICEodUZsYWdzICYgRENfU01BTExDQVApKSB7CglQT0lOVCBwdDsKCglwdC54ID0gcmMubGVmdCArIDI7CglwdC55ID0gKHJjLmJvdHRvbSArIHJjLnRvcCAtIEdldFN5c3RlbU1ldHJpY3MoU01fQ1lTTUlDT04pKSAvIDI7CgoJaWYgKGhJY29uKSB7CgkgICAgRHJhd0ljb25FeCAoaGRjLCBwdC54LCBwdC55LCBoSWNvbiwgR2V0U3lzdGVtTWV0cmljcyhTTV9DWFNNSUNPTiksCgkJCSAgR2V0U3lzdGVtTWV0cmljcyhTTV9DWVNNSUNPTiksIDAsIDAsIERJX05PUk1BTCk7Cgl9CgllbHNlIHsKCSAgICBXTkQqIHduZFB0ciA9IFdJTl9GaW5kV25kUHRyKGh3bmQpOwoJICAgIEhJQ09OIGhBcHBJY29uID0gKEhJQ09OKSBOQ19JY29uRm9yV2luZG93KHduZFB0cik7CgkgICAgRHJhd0ljb25FeCAoaGRjLCBwdC54LCBwdC55LCBoQXBwSWNvbiwgR2V0U3lzdGVtTWV0cmljcyhTTV9DWFNNSUNPTiksCgkJCSAgR2V0U3lzdGVtTWV0cmljcyhTTV9DWVNNSUNPTiksIDAsIDAsIERJX05PUk1BTCk7CiAgICAgICAgICAgIFdJTl9SZWxlYXNlV25kUHRyKHduZFB0cik7Cgl9CgoJcmMubGVmdCArPSAocmMuYm90dG9tIC0gcmMudG9wKTsKICAgIH0KCiAgICAvKiBkcmF3aW5nIHRleHQgKi8KICAgIGlmICh1RmxhZ3MgJiBEQ19URVhUKSB7CglIRk9OVCBoT2xkRm9udDsKCglpZiAodUZsYWdzICYgRENfSU5CVVRUT04pCgkgICAgU2V0VGV4dENvbG9yIChoZGMsIEdldFN5c0NvbG9yIChDT0xPUl9CVE5URVhUKSk7CgllbHNlIGlmICh1RmxhZ3MgJiBEQ19BQ1RJVkUpCgkgICAgU2V0VGV4dENvbG9yIChoZGMsIEdldFN5c0NvbG9yIChDT0xPUl9DQVBUSU9OVEVYVCkpOwoJZWxzZQoJICAgIFNldFRleHRDb2xvciAoaGRjLCBHZXRTeXNDb2xvciAoQ09MT1JfSU5BQ1RJVkVDQVBUSU9OVEVYVCkpOwoKCVNldEJrTW9kZSAoaGRjLCBUUkFOU1BBUkVOVCk7CgoJaWYgKGhGb250KQoJICAgIGhPbGRGb250ID0gU2VsZWN0T2JqZWN0IChoZGMsIGhGb250KTsKCWVsc2UgewoJICAgIE5PTkNMSUVOVE1FVFJJQ1NBIG5jbG07CgkgICAgSEZPTlQgaE5ld0ZvbnQ7CgkgICAgbmNsbS5jYlNpemUgPSBzaXplb2YoTk9OQ0xJRU5UTUVUUklDU0EpOwoJICAgIFN5c3RlbVBhcmFtZXRlcnNJbmZvQSAoU1BJX0dFVE5PTkNMSUVOVE1FVFJJQ1MsIDAsICZuY2xtLCAwKTsKCSAgICBoTmV3Rm9udCA9IENyZWF0ZUZvbnRJbmRpcmVjdEEgKCh1RmxhZ3MgJiBEQ19TTUFMTENBUCkgPwoJCSZuY2xtLmxmU21DYXB0aW9uRm9udCA6ICZuY2xtLmxmQ2FwdGlvbkZvbnQpOwoJICAgIGhPbGRGb250ID0gU2VsZWN0T2JqZWN0IChoZGMsIGhOZXdGb250KTsKCX0KCglpZiAoc3RyKQoJICAgIERyYXdUZXh0QSAoaGRjLCBzdHIsIC0xLCAmcmMsCgkJCSBEVF9TSU5HTEVMSU5FIHwgRFRfVkNFTlRFUiB8IERUX05PUFJFRklYIHwgRFRfTEVGVCk7CgllbHNlIHsKCSAgICBDSEFSIHN6VGV4dFsxMjhdOwoJICAgIElOVCBuTGVuOwoJICAgIG5MZW4gPSBHZXRXaW5kb3dUZXh0QSAoaHduZCwgc3pUZXh0LCAxMjgpOwoJICAgIERyYXdUZXh0QSAoaGRjLCBzelRleHQsIG5MZW4sICZyYywKCQkJIERUX1NJTkdMRUxJTkUgfCBEVF9WQ0VOVEVSIHwgRFRfTk9QUkVGSVggfCBEVF9MRUZUKTsKCX0KCglpZiAoaEZvbnQpCgkgICAgU2VsZWN0T2JqZWN0IChoZGMsIGhPbGRGb250KTsKCWVsc2UKCSAgICBEZWxldGVPYmplY3QgKFNlbGVjdE9iamVjdCAoaGRjLCBoT2xkRm9udCkpOwogICAgfQoKICAgIC8qIGRyYXdpbmcgZm9jdXMgPz8/ICovCiAgICBpZiAodUZsYWdzICYgMHgyMDAwKQoJRklYTUUoInVuZG9jdW1lbnRlZCBmbGFnICgweDIwMDApIVxuIik7CgogICAgcmV0dXJuIDA7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCURyYXdDYXB0aW9uVGVtcFcgKFVTRVIzMi5AKQogKgogKiBQQVJBTVMKICoKICogUkVUVVJOUwogKiAgICAgU3VjY2VzczoKICogICAgIEZhaWx1cmU6CiAqLwoKQk9PTCBXSU5BUEkKRHJhd0NhcHRpb25UZW1wVyAoSFdORCBod25kLCBIREMgaGRjLCBjb25zdCBSRUNUICpyZWN0LCBIRk9OVCBoRm9udCwKCQkgICAgSElDT04gaEljb24sIExQQ1dTVFIgc3RyLCBVSU5UIHVGbGFncykKewogICAgTFBTVFIgcCA9IEhFQVBfc3RyZHVwV3RvQSAoR2V0UHJvY2Vzc0hlYXAgKCksIDAsIHN0cik7CiAgICBCT09MIHJlcyA9IERyYXdDYXB0aW9uVGVtcEEgKGh3bmQsIGhkYywgcmVjdCwgaEZvbnQsIGhJY29uLCBwLCB1RmxhZ3MpOwogICAgSGVhcEZyZWUgKEdldFByb2Nlc3NIZWFwICgpLCAwLCBwKTsKICAgIHJldHVybiByZXM7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCUFkanVzdFdpbmRvd1JlY3QgKFVTRVIuMTAyKQogKi8KQk9PTDE2IFdJTkFQSSBBZGp1c3RXaW5kb3dSZWN0MTYoIExQUkVDVDE2IHJlY3QsIERXT1JEIHN0eWxlLCBCT09MMTYgbWVudSApCnsKICAgIHJldHVybiBBZGp1c3RXaW5kb3dSZWN0RXgxNiggcmVjdCwgc3R5bGUsIG1lbnUsIDAgKTsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJQWRqdXN0V2luZG93UmVjdCAoVVNFUjMyLkApCiAqLwpCT09MIFdJTkFQSSBBZGp1c3RXaW5kb3dSZWN0KCBMUFJFQ1QgcmVjdCwgRFdPUkQgc3R5bGUsIEJPT0wgbWVudSApCnsKICAgIHJldHVybiBBZGp1c3RXaW5kb3dSZWN0RXgoIHJlY3QsIHN0eWxlLCBtZW51LCAwICk7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCUFkanVzdFdpbmRvd1JlY3RFeCAoVVNFUi40NTQpCiAqLwpCT09MMTYgV0lOQVBJIEFkanVzdFdpbmRvd1JlY3RFeDE2KCBMUFJFQ1QxNiByZWN0LCBEV09SRCBzdHlsZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQk9PTDE2IG1lbnUsIERXT1JEIGV4U3R5bGUgKQp7CiAgICAgIC8qIENvcnJlY3QgdGhlIHdpbmRvdyBzdHlsZSAqLwoKICAgIGlmICghKHN0eWxlICYgKFdTX1BPUFVQIHwgV1NfQ0hJTEQpKSkgIC8qIE92ZXJsYXBwZWQgd2luZG93ICovCglzdHlsZSB8PSBXU19DQVBUSU9OOwogICAgc3R5bGUgJj0gKFdTX0RMR0ZSQU1FIHwgV1NfQk9SREVSIHwgV1NfVEhJQ0tGUkFNRSB8IFdTX0NISUxEKTsKICAgIGV4U3R5bGUgJj0gKFdTX0VYX0RMR01PREFMRlJBTUUgfCBXU19FWF9DTElFTlRFREdFIHwKCQlXU19FWF9TVEFUSUNFREdFIHwgV1NfRVhfVE9PTFdJTkRPVyk7CiAgICBpZiAoZXhTdHlsZSAmIFdTX0VYX0RMR01PREFMRlJBTUUpIHN0eWxlICY9IH5XU19USElDS0ZSQU1FOwoKICAgIFRSQUNFKCIoJWQsJWQpLSglZCwlZCkgJTA4bHggJWQgJTA4bHhcbiIsCiAgICAgICAgICByZWN0LT5sZWZ0LCByZWN0LT50b3AsIHJlY3QtPnJpZ2h0LCByZWN0LT5ib3R0b20sCiAgICAgICAgICBzdHlsZSwgbWVudSwgZXhTdHlsZSApOwoKICAgIGlmIChUV0VBS19XaW5lTG9vayA9PSBXSU4zMV9MT09LKQoJTkNfQWRqdXN0UmVjdCggcmVjdCwgc3R5bGUsIG1lbnUsIGV4U3R5bGUgKTsKICAgIGVsc2UgewoJTkNfQWRqdXN0UmVjdE91dGVyOTUoIHJlY3QsIHN0eWxlLCBtZW51LCBleFN0eWxlICk7CglOQ19BZGp1c3RSZWN0SW5uZXI5NSggcmVjdCwgc3R5bGUsIGV4U3R5bGUgKTsKICAgIH0KCiAgICByZXR1cm4gVFJVRTsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJQWRqdXN0V2luZG93UmVjdEV4IChVU0VSMzIuQCkKICovCkJPT0wgV0lOQVBJIEFkanVzdFdpbmRvd1JlY3RFeCggTFBSRUNUIHJlY3QsIERXT1JEIHN0eWxlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBCT09MIG1lbnUsIERXT1JEIGV4U3R5bGUgKQp7CiAgICBSRUNUMTYgcmVjdDE2OwogICAgQk9PTCByZXQ7CgogICAgQ09OVl9SRUNUMzJUTzE2KCByZWN0LCAmcmVjdDE2ICk7CiAgICByZXQgPSBBZGp1c3RXaW5kb3dSZWN0RXgxNiggJnJlY3QxNiwgc3R5bGUsIChCT09MMTYpbWVudSwgZXhTdHlsZSApOwogICAgQ09OVl9SRUNUMTZUTzMyKCAmcmVjdDE2LCByZWN0ICk7CiAgICByZXR1cm4gcmV0Owp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgICAgICBOQ19IYW5kbGVOQ0NhbGNTaXplCiAqCiAqIEhhbmRsZSBhIFdNX05DQ0FMQ1NJWkUgbWVzc2FnZS4gQ2FsbGVkIGZyb20gRGVmV2luZG93UHJvYygpLgogKi8KTE9ORyBOQ19IYW5kbGVOQ0NhbGNTaXplKCBXTkQgKnBXbmQsIFJFQ1QgKndpblJlY3QgKQp7CiAgICBSRUNUMTYgdG1wUmVjdCA9IHsgMCwgMCwgMCwgMCB9OwogICAgTE9ORyByZXN1bHQgPSAwOwogICAgVUlOVCBzdHlsZSA9IChVSU5UKSBHZXRDbGFzc0xvbmdBKHBXbmQtPmh3bmRTZWxmLCBHQ0xfU1RZTEUpOwoKICAgIGlmIChzdHlsZSAmIENTX1ZSRURSQVcpIHJlc3VsdCB8PSBXVlJfVlJFRFJBVzsKICAgIGlmIChzdHlsZSAmIENTX0hSRURSQVcpIHJlc3VsdCB8PSBXVlJfSFJFRFJBVzsKCiAgICBpZiggISggcFduZC0+ZHdTdHlsZSAmIFdTX01JTklNSVpFICkgKSB7CglpZiAoVFdFQUtfV2luZUxvb2sgPT0gV0lOMzFfTE9PSykKCSAgICBOQ19BZGp1c3RSZWN0KCAmdG1wUmVjdCwgcFduZC0+ZHdTdHlsZSwgRkFMU0UsIHBXbmQtPmR3RXhTdHlsZSApOwoJZWxzZQoJICAgIE5DX0FkanVzdFJlY3RPdXRlcjk1KCAmdG1wUmVjdCwgcFduZC0+ZHdTdHlsZSwgRkFMU0UsIHBXbmQtPmR3RXhTdHlsZSApOwoKCXdpblJlY3QtPmxlZnQgICAtPSB0bXBSZWN0LmxlZnQ7Cgl3aW5SZWN0LT50b3AgICAgLT0gdG1wUmVjdC50b3A7Cgl3aW5SZWN0LT5yaWdodCAgLT0gdG1wUmVjdC5yaWdodDsKCXdpblJlY3QtPmJvdHRvbSAtPSB0bXBSZWN0LmJvdHRvbTsKCglpZiAoSEFTX01FTlUocFduZCkpIHsKCSAgICBUUkFDRSgiQ2FsbGluZyBHZXRNZW51QmFySGVpZ2h0IHdpdGggSFdORCAweCV4LCB3aWR0aCAlZCwgIgogICAgICAgICAgICAgICAgICAiYXQgKCVkLCAlZCkuXG4iLCBwV25kLT5od25kU2VsZiwKICAgICAgICAgICAgICAgICAgd2luUmVjdC0+cmlnaHQgLSB3aW5SZWN0LT5sZWZ0LAogICAgICAgICAgICAgICAgICAtdG1wUmVjdC5sZWZ0LCAtdG1wUmVjdC50b3AgKTsKCgkgICAgd2luUmVjdC0+dG9wICs9CgkJTUVOVV9HZXRNZW51QmFySGVpZ2h0KCBwV25kLT5od25kU2VsZiwKCQkJCSAgICAgICB3aW5SZWN0LT5yaWdodCAtIHdpblJlY3QtPmxlZnQsCgkJCQkgICAgICAgLXRtcFJlY3QubGVmdCwgLXRtcFJlY3QudG9wICkgKyAxOwoJfQoKCWlmIChUV0VBS19XaW5lTG9vayA+IFdJTjMxX0xPT0spIHsKCSAgICBTZXRSZWN0MTYgKCZ0bXBSZWN0LCAwLCAwLCAwLCAwKTsKCSAgICBOQ19BZGp1c3RSZWN0SW5uZXI5NSAoJnRtcFJlY3QsIHBXbmQtPmR3U3R5bGUsIHBXbmQtPmR3RXhTdHlsZSk7CgkgICAgd2luUmVjdC0+bGVmdCAgIC09IHRtcFJlY3QubGVmdDsKCSAgICB3aW5SZWN0LT50b3AgICAgLT0gdG1wUmVjdC50b3A7CgkgICAgd2luUmVjdC0+cmlnaHQgIC09IHRtcFJlY3QucmlnaHQ7CgkgICAgd2luUmVjdC0+Ym90dG9tIC09IHRtcFJlY3QuYm90dG9tOwoJfQoKICAgICAgICBpZiAod2luUmVjdC0+dG9wID4gd2luUmVjdC0+Ym90dG9tKQogICAgICAgICAgICB3aW5SZWN0LT5ib3R0b20gPSB3aW5SZWN0LT50b3A7CgogICAgICAgIGlmICh3aW5SZWN0LT5sZWZ0ID4gd2luUmVjdC0+cmlnaHQpCiAgICAgICAgICAgIHdpblJlY3QtPnJpZ2h0ID0gd2luUmVjdC0+bGVmdDsKICAgIH0KICAgIHJldHVybiByZXN1bHQ7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICAgICAgIE5DX0dldEluc2lkZVJlY3QKICoKICogR2V0IHRoZSAnaW5zaWRlJyByZWN0YW5nbGUgb2YgYSB3aW5kb3csIGkuZS4gdGhlIHdob2xlIHdpbmRvdyByZWN0YW5nbGUKICogYnV0IHdpdGhvdXQgdGhlIGJvcmRlcnMgKGlmIGFueSkuCiAqIFRoZSByZWN0YW5nbGUgaXMgaW4gd2luZG93IGNvb3JkaW5hdGVzIChmb3IgZHJhd2luZyB3aXRoIEdldFdpbmRvd0RDKCkpLgogKi8Kc3RhdGljIHZvaWQgTkNfR2V0SW5zaWRlUmVjdCggSFdORCBod25kLCBSRUNUICpyZWN0ICkKewogICAgV05EICogd25kUHRyID0gV0lOX0ZpbmRXbmRQdHIoIGh3bmQgKTsKCiAgICByZWN0LT50b3AgICAgPSByZWN0LT5sZWZ0ID0gMDsKICAgIHJlY3QtPnJpZ2h0ICA9IHduZFB0ci0+cmVjdFdpbmRvdy5yaWdodCAtIHduZFB0ci0+cmVjdFdpbmRvdy5sZWZ0OwogICAgcmVjdC0+Ym90dG9tID0gd25kUHRyLT5yZWN0V2luZG93LmJvdHRvbSAtIHduZFB0ci0+cmVjdFdpbmRvdy50b3A7CgogICAgaWYgKCh3bmRQdHItPmR3U3R5bGUgJiBXU19JQ09OSUMpIHx8ICh3bmRQdHItPmR3RXhTdHlsZSAmIFdTX0VYX01BTkFHRUQpKSBnb3RvIEVORDsKCiAgICAvKiBSZW1vdmUgZnJhbWUgZnJvbSByZWN0YW5nbGUgKi8KICAgIGlmIChIQVNfVEhJQ0tGUkFNRSggd25kUHRyLT5kd1N0eWxlLCB3bmRQdHItPmR3RXhTdHlsZSApKQoJSW5mbGF0ZVJlY3QoIHJlY3QsIC1HZXRTeXN0ZW1NZXRyaWNzKFNNX0NYRlJBTUUpLCAtR2V0U3lzdGVtTWV0cmljcyhTTV9DWUZSQU1FKSApOwogICAgZWxzZQogICAgaWYgKEhBU19ETEdGUkFNRSggd25kUHRyLT5kd1N0eWxlLCB3bmRQdHItPmR3RXhTdHlsZSApKQogICAgewoJSW5mbGF0ZVJlY3QoIHJlY3QsIC1HZXRTeXN0ZW1NZXRyaWNzKFNNX0NYRExHRlJBTUUpLCAtR2V0U3lzdGVtTWV0cmljcyhTTV9DWURMR0ZSQU1FKSk7CgkvKiBGSVhNRTogdGhpcyBpc24ndCBpbiBOQ19BZGp1c3RSZWN0PyB3aHkgbm90PyAqLwoJaWYgKHduZFB0ci0+ZHdFeFN0eWxlICYgV1NfRVhfRExHTU9EQUxGUkFNRSkKICAgICAgICAgICAgSW5mbGF0ZVJlY3QoIHJlY3QsIC0xLCAwICk7CiAgICB9CiAgICBlbHNlCiAgICBpZiAoSEFTX1RISU5GUkFNRSggd25kUHRyLT5kd1N0eWxlICkpCglJbmZsYXRlUmVjdCggcmVjdCwgLUdldFN5c3RlbU1ldHJpY3MoU01fQ1hCT1JERVIpLCAtR2V0U3lzdGVtTWV0cmljcyhTTV9DWUJPUkRFUikgKTsKRU5EOgogICAgV0lOX1JlbGVhc2VXbmRQdHIod25kUHRyKTsKICAgIHJldHVybjsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgICAgICAgTkNfR2V0SW5zaWRlUmVjdDk1CiAqCiAqIEdldCB0aGUgJ2luc2lkZScgcmVjdGFuZ2xlIG9mIGEgd2luZG93LCBpLmUuIHRoZSB3aG9sZSB3aW5kb3cgcmVjdGFuZ2xlCiAqIGJ1dCB3aXRob3V0IHRoZSBib3JkZXJzIChpZiBhbnkpLgogKiBUaGUgcmVjdGFuZ2xlIGlzIGluIHdpbmRvdyBjb29yZGluYXRlcyAoZm9yIGRyYXdpbmcgd2l0aCBHZXRXaW5kb3dEQygpKS4KICovCgpzdGF0aWMgdm9pZApOQ19HZXRJbnNpZGVSZWN0OTUgKEhXTkQgaHduZCwgUkVDVCAqcmVjdCkKewogICAgV05EICogd25kUHRyID0gV0lOX0ZpbmRXbmRQdHIoIGh3bmQgKTsKCiAgICByZWN0LT50b3AgICAgPSByZWN0LT5sZWZ0ID0gMDsKICAgIHJlY3QtPnJpZ2h0ICA9IHduZFB0ci0+cmVjdFdpbmRvdy5yaWdodCAtIHduZFB0ci0+cmVjdFdpbmRvdy5sZWZ0OwogICAgcmVjdC0+Ym90dG9tID0gd25kUHRyLT5yZWN0V2luZG93LmJvdHRvbSAtIHduZFB0ci0+cmVjdFdpbmRvdy50b3A7CgogICAgaWYgKCh3bmRQdHItPmR3U3R5bGUgJiBXU19JQ09OSUMpIHx8ICh3bmRQdHItPmR3RXhTdHlsZSAmIFdTX0VYX01BTkFHRUQpKSBnb3RvIEVORDsKCiAgICAvKiBSZW1vdmUgZnJhbWUgZnJvbSByZWN0YW5nbGUgKi8KICAgIGlmIChIQVNfVEhJQ0tGUkFNRSAod25kUHRyLT5kd1N0eWxlLCB3bmRQdHItPmR3RXhTdHlsZSkpCiAgICB7CglJbmZsYXRlUmVjdCggcmVjdCwgLUdldFN5c3RlbU1ldHJpY3MoU01fQ1hTSVpFRlJBTUUpLCAtR2V0U3lzdGVtTWV0cmljcyhTTV9DWVNJWkVGUkFNRSkgKTsKICAgIH0KICAgIGVsc2UgaWYgKEhBU19ETEdGUkFNRSAod25kUHRyLT5kd1N0eWxlLCB3bmRQdHItPmR3RXhTdHlsZSApKQogICAgewoJSW5mbGF0ZVJlY3QoIHJlY3QsIC1HZXRTeXN0ZW1NZXRyaWNzKFNNX0NYRklYRURGUkFNRSksIC1HZXRTeXN0ZW1NZXRyaWNzKFNNX0NZRklYRURGUkFNRSkpOwogICAgfQogICAgZWxzZSBpZiAoSEFTX1RISU5GUkFNRSAod25kUHRyLT5kd1N0eWxlKSkKICAgIHsKICAgICAgICBJbmZsYXRlUmVjdCggcmVjdCwgLUdldFN5c3RlbU1ldHJpY3MoU01fQ1hCT1JERVIpLCAtR2V0U3lzdGVtTWV0cmljcyhTTV9DWUJPUkRFUikgKTsKICAgIH0KCiAgICAvKiBXZSBoYXZlIGFkZGl0aW9uYWwgYm9yZGVyIGluZm9ybWF0aW9uIGlmIHRoZSB3aW5kb3cKICAgICAqIGlzIGEgY2hpbGQgKGJ1dCBub3QgYW4gTURJIGNoaWxkKSAqLwogICAgaWYgKCAod25kUHRyLT5kd1N0eWxlICYgV1NfQ0hJTEQpICAmJgoJICggKHduZFB0ci0+ZHdFeFN0eWxlICYgV1NfRVhfTURJQ0hJTEQpID09IDAgKSApCiAgICB7IAoJaWYgKHduZFB0ci0+ZHdFeFN0eWxlICYgV1NfRVhfQ0xJRU5URURHRSkKCSAgICBJbmZsYXRlUmVjdCAocmVjdCwgLUdldFN5c3RlbU1ldHJpY3MoU01fQ1hFREdFKSwgLUdldFN5c3RlbU1ldHJpY3MoU01fQ1lFREdFKSk7CgoJaWYgKHduZFB0ci0+ZHdFeFN0eWxlICYgV1NfRVhfU1RBVElDRURHRSkKCSAgICBJbmZsYXRlUmVjdCAocmVjdCwgLUdldFN5c3RlbU1ldHJpY3MoU01fQ1hCT1JERVIpLCAtR2V0U3lzdGVtTWV0cmljcyhTTV9DWUJPUkRFUikpOwogICAgfQpFTkQ6CiAgICBXSU5fUmVsZWFzZVduZFB0cih3bmRQdHIpOwogICAgcmV0dXJuOwp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIE5DX0RvTkNIaXRUZXN0CiAqCiAqIEhhbmRsZSBhIFdNX05DSElUVEVTVCBtZXNzYWdlLiBDYWxsZWQgZnJvbSBOQ19IYW5kbGVOQ0hpdFRlc3QoKS4KICovCgpzdGF0aWMgTE9ORyBOQ19Eb05DSGl0VGVzdCAoV05EICp3bmRQdHIsIFBPSU5UIHB0ICkKewogICAgUkVDVCByZWN0OwoKICAgIFRSQUNFKCJod25kPSUwNHggcHQ9JWxkLCVsZFxuIiwgd25kUHRyLT5od25kU2VsZiwgcHQueCwgcHQueSApOwoKICAgIEdldFdpbmRvd1JlY3Qod25kUHRyLT5od25kU2VsZiwgJnJlY3QgKTsKICAgIGlmICghUHRJblJlY3QoICZyZWN0LCBwdCApKSByZXR1cm4gSFROT1dIRVJFOwoKICAgIGlmICh3bmRQdHItPmR3U3R5bGUgJiBXU19NSU5JTUlaRSkgcmV0dXJuIEhUQ0FQVElPTjsKCiAgICBpZiAoISh3bmRQdHItPmR3RXhTdHlsZSAmIFdTX0VYX01BTkFHRUQpKQogICAgewogICAgICAgIC8qIENoZWNrIGJvcmRlcnMgKi8KICAgICAgICBpZiAoSEFTX1RISUNLRlJBTUUoIHduZFB0ci0+ZHdTdHlsZSwgd25kUHRyLT5kd0V4U3R5bGUgKSkKICAgICAgICB7CiAgICAgICAgICAgIEluZmxhdGVSZWN0KCAmcmVjdCwgLUdldFN5c3RlbU1ldHJpY3MoU01fQ1hGUkFNRSksIC1HZXRTeXN0ZW1NZXRyaWNzKFNNX0NZRlJBTUUpICk7CiAgICAgICAgICAgIGlmICghUHRJblJlY3QoICZyZWN0LCBwdCApKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAvKiBDaGVjayB0b3Agc2l6aW5nIGJvcmRlciAqLwogICAgICAgICAgICAgICAgaWYgKHB0LnkgPCByZWN0LnRvcCkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBpZiAocHQueCA8IHJlY3QubGVmdCtHZXRTeXN0ZW1NZXRyaWNzKFNNX0NYU0laRSkpIHJldHVybiBIVFRPUExFRlQ7CiAgICAgICAgICAgICAgICAgICAgaWYgKHB0LnggPj0gcmVjdC5yaWdodC1HZXRTeXN0ZW1NZXRyaWNzKFNNX0NYU0laRSkpIHJldHVybiBIVFRPUFJJR0hUOwogICAgICAgICAgICAgICAgICAgIHJldHVybiBIVFRPUDsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIC8qIENoZWNrIGJvdHRvbSBzaXppbmcgYm9yZGVyICovCiAgICAgICAgICAgICAgICBpZiAocHQueSA+PSByZWN0LmJvdHRvbSkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBpZiAocHQueCA8IHJlY3QubGVmdCtHZXRTeXN0ZW1NZXRyaWNzKFNNX0NYU0laRSkpIHJldHVybiBIVEJPVFRPTUxFRlQ7CiAgICAgICAgICAgICAgICAgICAgaWYgKHB0LnggPj0gcmVjdC5yaWdodC1HZXRTeXN0ZW1NZXRyaWNzKFNNX0NYU0laRSkpIHJldHVybiBIVEJPVFRPTVJJR0hUOwogICAgICAgICAgICAgICAgICAgIHJldHVybiBIVEJPVFRPTTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIC8qIENoZWNrIGxlZnQgc2l6aW5nIGJvcmRlciAqLwogICAgICAgICAgICAgICAgaWYgKHB0LnggPCByZWN0LmxlZnQpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgaWYgKHB0LnkgPCByZWN0LnRvcCtHZXRTeXN0ZW1NZXRyaWNzKFNNX0NZU0laRSkpIHJldHVybiBIVFRPUExFRlQ7CiAgICAgICAgICAgICAgICAgICAgaWYgKHB0LnkgPj0gcmVjdC5ib3R0b20tR2V0U3lzdGVtTWV0cmljcyhTTV9DWVNJWkUpKSByZXR1cm4gSFRCT1RUT01MRUZUOwogICAgICAgICAgICAgICAgICAgIHJldHVybiBIVExFRlQ7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAvKiBDaGVjayByaWdodCBzaXppbmcgYm9yZGVyICovCiAgICAgICAgICAgICAgICBpZiAocHQueCA+PSByZWN0LnJpZ2h0KQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIGlmIChwdC55IDwgcmVjdC50b3ArR2V0U3lzdGVtTWV0cmljcyhTTV9DWVNJWkUpKSByZXR1cm4gSFRUT1BSSUdIVDsKICAgICAgICAgICAgICAgICAgICBpZiAocHQueSA+PSByZWN0LmJvdHRvbS1HZXRTeXN0ZW1NZXRyaWNzKFNNX0NZU0laRSkpIHJldHVybiBIVEJPVFRPTVJJR0hUOwogICAgICAgICAgICAgICAgICAgIHJldHVybiBIVFJJR0hUOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIGVsc2UgIC8qIE5vIHRoaWNrIGZyYW1lICovCiAgICAgICAgewogICAgICAgICAgICBpZiAoSEFTX0RMR0ZSQU1FKCB3bmRQdHItPmR3U3R5bGUsIHduZFB0ci0+ZHdFeFN0eWxlICkpCiAgICAgICAgICAgICAgICBJbmZsYXRlUmVjdCgmcmVjdCwgLUdldFN5c3RlbU1ldHJpY3MoU01fQ1hETEdGUkFNRSksIC1HZXRTeXN0ZW1NZXRyaWNzKFNNX0NZRExHRlJBTUUpKTsKICAgICAgICAgICAgZWxzZSBpZiAoSEFTX1RISU5GUkFNRSggd25kUHRyLT5kd1N0eWxlICkpCiAgICAgICAgICAgICAgICBJbmZsYXRlUmVjdCgmcmVjdCwgLUdldFN5c3RlbU1ldHJpY3MoU01fQ1hCT1JERVIpLCAtR2V0U3lzdGVtTWV0cmljcyhTTV9DWUJPUkRFUikpOwogICAgICAgICAgICBpZiAoIVB0SW5SZWN0KCAmcmVjdCwgcHQgKSkgcmV0dXJuIEhUQk9SREVSOwogICAgICAgIH0KCiAgICAgICAgLyogQ2hlY2sgY2FwdGlvbiAqLwoKICAgICAgICBpZiAoKHduZFB0ci0+ZHdTdHlsZSAmIFdTX0NBUFRJT04pID09IFdTX0NBUFRJT04pCiAgICAgICAgewogICAgICAgICAgICByZWN0LnRvcCArPSBHZXRTeXN0ZW1NZXRyaWNzKFNNX0NZQ0FQVElPTikgLSBHZXRTeXN0ZW1NZXRyaWNzKFNNX0NZQk9SREVSKTsKICAgICAgICAgICAgaWYgKCFQdEluUmVjdCggJnJlY3QsIHB0ICkpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIC8qIENoZWNrIHN5c3RlbSBtZW51ICovCiAgICAgICAgICAgICAgICBpZiAoKHduZFB0ci0+ZHdTdHlsZSAmIFdTX1NZU01FTlUpICYmICEod25kUHRyLT5kd0V4U3R5bGUgJiBXU19FWF9UT09MV0lORE9XKSkKICAgICAgICAgICAgICAgICAgICByZWN0LmxlZnQgKz0gR2V0U3lzdGVtTWV0cmljcyhTTV9DWFNJWkUpOwogICAgICAgICAgICAgICAgaWYgKHB0LnggPD0gcmVjdC5sZWZ0KSByZXR1cm4gSFRTWVNNRU5VOwoKICAgICAgICAgICAgICAgIC8qIENoZWNrIG1heGltaXplIGJveCAqLwogICAgICAgICAgICAgICAgaWYgKHduZFB0ci0+ZHdTdHlsZSAmIFdTX01BWElNSVpFQk9YKQogICAgICAgICAgICAgICAgICAgIHJlY3QucmlnaHQgLT0gR2V0U3lzdGVtTWV0cmljcyhTTV9DWFNJWkUpICsgMTsKCiAgICAgICAgICAgICAgICBpZiAocHQueCA+PSByZWN0LnJpZ2h0KSByZXR1cm4gSFRNQVhCVVRUT047CiAgICAgICAgICAgICAgICAvKiBDaGVjayBtaW5pbWl6ZSBib3ggKi8KICAgICAgICAgICAgICAgIGlmICh3bmRQdHItPmR3U3R5bGUgJiBXU19NSU5JTUlaRUJPWCkKICAgICAgICAgICAgICAgICAgICByZWN0LnJpZ2h0IC09IEdldFN5c3RlbU1ldHJpY3MoU01fQ1hTSVpFKSArIDE7CiAgICAgICAgICAgICAgICBpZiAocHQueCA+PSByZWN0LnJpZ2h0KSByZXR1cm4gSFRNSU5CVVRUT047CiAgICAgICAgICAgICAgICByZXR1cm4gSFRDQVBUSU9OOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfQoKICAgICAgLyogQ2hlY2sgY2xpZW50IGFyZWEgKi8KCiAgICBTY3JlZW5Ub0NsaWVudCggd25kUHRyLT5od25kU2VsZiwgJnB0ICk7CiAgICBHZXRDbGllbnRSZWN0KCB3bmRQdHItPmh3bmRTZWxmLCAmcmVjdCApOwogICAgaWYgKFB0SW5SZWN0KCAmcmVjdCwgcHQgKSkgcmV0dXJuIEhUQ0xJRU5UOwoKICAgICAgLyogQ2hlY2sgdmVydGljYWwgc2Nyb2xsIGJhciAqLwoKICAgIGlmICh3bmRQdHItPmR3U3R5bGUgJiBXU19WU0NST0xMKQogICAgewoJcmVjdC5yaWdodCArPSBHZXRTeXN0ZW1NZXRyaWNzKFNNX0NYVlNDUk9MTCk7CglpZiAoUHRJblJlY3QoICZyZWN0LCBwdCApKSByZXR1cm4gSFRWU0NST0xMOwogICAgfQoKICAgICAgLyogQ2hlY2sgaG9yaXpvbnRhbCBzY3JvbGwgYmFyICovCgogICAgaWYgKHduZFB0ci0+ZHdTdHlsZSAmIFdTX0hTQ1JPTEwpCiAgICB7CglyZWN0LmJvdHRvbSArPSBHZXRTeXN0ZW1NZXRyaWNzKFNNX0NZSFNDUk9MTCk7CglpZiAoUHRJblJlY3QoICZyZWN0LCBwdCApKQoJewoJICAgICAgLyogQ2hlY2sgc2l6ZSBib3ggKi8KCSAgICBpZiAoKHduZFB0ci0+ZHdTdHlsZSAmIFdTX1ZTQ1JPTEwpICYmCgkJKHB0LnggPj0gcmVjdC5yaWdodCAtIEdldFN5c3RlbU1ldHJpY3MoU01fQ1hWU0NST0xMKSkpCgkJcmV0dXJuIEhUU0laRTsKCSAgICByZXR1cm4gSFRIU0NST0xMOwoJfQogICAgfQoKICAgICAgLyogQ2hlY2sgbWVudSBiYXIgKi8KCiAgICBpZiAoSEFTX01FTlUod25kUHRyKSkKICAgIHsKCWlmICgocHQueSA8IDApICYmIChwdC54ID49IDApICYmIChwdC54IDwgcmVjdC5yaWdodCkpCgkgICAgcmV0dXJuIEhUTUVOVTsKICAgIH0KCiAgICAvKiBIYXMgdG8gcmV0dXJuIEhUTk9XSEVSRSBpZiBub3RoaW5nIHdhcyBmb3VuZCAgCiAgICAgICBDb3VsZCBoYXBwZW4gd2hlbiBhIHdpbmRvdyBoYXMgYSBjdXN0b21pemVkIG5vbiBjbGllbnQgYXJlYSAqLwogICAgcmV0dXJuIEhUTk9XSEVSRTsgIAp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIE5DX0RvTkNIaXRUZXN0OTUKICoKICogSGFuZGxlIGEgV01fTkNISVRURVNUIG1lc3NhZ2UuIENhbGxlZCBmcm9tIE5DX0hhbmRsZU5DSGl0VGVzdCgpLgogKgogKiBGSVhNRTogIEp1c3QgYSBtb2RpZmllZCBjb3B5IG9mIHRoZSBXaW4gMy4xIHZlcnNpb24uCiAqLwoKc3RhdGljIExPTkcgTkNfRG9OQ0hpdFRlc3Q5NSAoV05EICp3bmRQdHIsIFBPSU5UIHB0ICkKewogICAgUkVDVCByZWN0OwoKICAgIFRSQUNFKCJod25kPSUwNHggcHQ9JWxkLCVsZFxuIiwgd25kUHRyLT5od25kU2VsZiwgcHQueCwgcHQueSApOwoKICAgIEdldFdpbmRvd1JlY3Qod25kUHRyLT5od25kU2VsZiwgJnJlY3QgKTsKICAgIGlmICghUHRJblJlY3QoICZyZWN0LCBwdCApKSByZXR1cm4gSFROT1dIRVJFOwoKICAgIGlmICh3bmRQdHItPmR3U3R5bGUgJiBXU19NSU5JTUlaRSkgcmV0dXJuIEhUQ0FQVElPTjsKCiAgICBpZiAoISh3bmRQdHItPmR3RXhTdHlsZSAmIFdTX0VYX01BTkFHRUQpKQogICAgewogICAgICAgIC8qIENoZWNrIGJvcmRlcnMgKi8KICAgICAgICBpZiAoSEFTX1RISUNLRlJBTUUoIHduZFB0ci0+ZHdTdHlsZSwgd25kUHRyLT5kd0V4U3R5bGUgKSkKICAgICAgICB7CiAgICAgICAgICAgIEluZmxhdGVSZWN0KCAmcmVjdCwgLUdldFN5c3RlbU1ldHJpY3MoU01fQ1hGUkFNRSksIC1HZXRTeXN0ZW1NZXRyaWNzKFNNX0NZRlJBTUUpICk7CiAgICAgICAgICAgIGlmICghUHRJblJlY3QoICZyZWN0LCBwdCApKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAvKiBDaGVjayB0b3Agc2l6aW5nIGJvcmRlciAqLwogICAgICAgICAgICAgICAgaWYgKHB0LnkgPCByZWN0LnRvcCkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBpZiAocHQueCA8IHJlY3QubGVmdCtHZXRTeXN0ZW1NZXRyaWNzKFNNX0NYU0laRSkpIHJldHVybiBIVFRPUExFRlQ7CiAgICAgICAgICAgICAgICAgICAgaWYgKHB0LnggPj0gcmVjdC5yaWdodC1HZXRTeXN0ZW1NZXRyaWNzKFNNX0NYU0laRSkpIHJldHVybiBIVFRPUFJJR0hUOwogICAgICAgICAgICAgICAgICAgIHJldHVybiBIVFRPUDsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIC8qIENoZWNrIGJvdHRvbSBzaXppbmcgYm9yZGVyICovCiAgICAgICAgICAgICAgICBpZiAocHQueSA+PSByZWN0LmJvdHRvbSkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBpZiAocHQueCA8IHJlY3QubGVmdCtHZXRTeXN0ZW1NZXRyaWNzKFNNX0NYU0laRSkpIHJldHVybiBIVEJPVFRPTUxFRlQ7CiAgICAgICAgICAgICAgICAgICAgaWYgKHB0LnggPj0gcmVjdC5yaWdodC1HZXRTeXN0ZW1NZXRyaWNzKFNNX0NYU0laRSkpIHJldHVybiBIVEJPVFRPTVJJR0hUOwogICAgICAgICAgICAgICAgICAgIHJldHVybiBIVEJPVFRPTTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIC8qIENoZWNrIGxlZnQgc2l6aW5nIGJvcmRlciAqLwogICAgICAgICAgICAgICAgaWYgKHB0LnggPCByZWN0LmxlZnQpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgaWYgKHB0LnkgPCByZWN0LnRvcCtHZXRTeXN0ZW1NZXRyaWNzKFNNX0NZU0laRSkpIHJldHVybiBIVFRPUExFRlQ7CiAgICAgICAgICAgICAgICAgICAgaWYgKHB0LnkgPj0gcmVjdC5ib3R0b20tR2V0U3lzdGVtTWV0cmljcyhTTV9DWVNJWkUpKSByZXR1cm4gSFRCT1RUT01MRUZUOwogICAgICAgICAgICAgICAgICAgIHJldHVybiBIVExFRlQ7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAvKiBDaGVjayByaWdodCBzaXppbmcgYm9yZGVyICovCiAgICAgICAgICAgICAgICBpZiAocHQueCA+PSByZWN0LnJpZ2h0KQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIGlmIChwdC55IDwgcmVjdC50b3ArR2V0U3lzdGVtTWV0cmljcyhTTV9DWVNJWkUpKSByZXR1cm4gSFRUT1BSSUdIVDsKICAgICAgICAgICAgICAgICAgICBpZiAocHQueSA+PSByZWN0LmJvdHRvbS1HZXRTeXN0ZW1NZXRyaWNzKFNNX0NZU0laRSkpIHJldHVybiBIVEJPVFRPTVJJR0hUOwogICAgICAgICAgICAgICAgICAgIHJldHVybiBIVFJJR0hUOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIGVsc2UgIC8qIE5vIHRoaWNrIGZyYW1lICovCiAgICAgICAgewogICAgICAgICAgICBpZiAoSEFTX0RMR0ZSQU1FKCB3bmRQdHItPmR3U3R5bGUsIHduZFB0ci0+ZHdFeFN0eWxlICkpCiAgICAgICAgICAgICAgICBJbmZsYXRlUmVjdCgmcmVjdCwgLUdldFN5c3RlbU1ldHJpY3MoU01fQ1hETEdGUkFNRSksIC1HZXRTeXN0ZW1NZXRyaWNzKFNNX0NZRExHRlJBTUUpKTsKICAgICAgICAgICAgZWxzZSBpZiAoSEFTX1RISU5GUkFNRSggd25kUHRyLT5kd1N0eWxlICkpCiAgICAgICAgICAgICAgICBJbmZsYXRlUmVjdCgmcmVjdCwgLUdldFN5c3RlbU1ldHJpY3MoU01fQ1hCT1JERVIpLCAtR2V0U3lzdGVtTWV0cmljcyhTTV9DWUJPUkRFUikpOwogICAgICAgICAgICBpZiAoIVB0SW5SZWN0KCAmcmVjdCwgcHQgKSkgcmV0dXJuIEhUQk9SREVSOwogICAgICAgIH0KCiAgICAgICAgLyogQ2hlY2sgY2FwdGlvbiAqLwoKICAgICAgICBpZiAoKHduZFB0ci0+ZHdTdHlsZSAmIFdTX0NBUFRJT04pID09IFdTX0NBUFRJT04pCiAgICAgICAgewoJICAgIGlmICh3bmRQdHItPmR3RXhTdHlsZSAmIFdTX0VYX1RPT0xXSU5ET1cpCgkgICAgICAgIHJlY3QudG9wICs9IEdldFN5c3RlbU1ldHJpY3MoU01fQ1lTTUNBUFRJT04pIC0gMTsKCSAgICBlbHNlCgkgICAgICAgIHJlY3QudG9wICs9IEdldFN5c3RlbU1ldHJpY3MoU01fQ1lDQVBUSU9OKSAtIDE7CiAgICAgICAgICAgIGlmICghUHRJblJlY3QoICZyZWN0LCBwdCApKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAvKiBDaGVjayBzeXN0ZW0gbWVudSAqLwogICAgICAgICAgICAgICAgaWYgKCh3bmRQdHItPmR3U3R5bGUgJiBXU19TWVNNRU5VKSAmJiAhKHduZFB0ci0+ZHdFeFN0eWxlICYgV1NfRVhfVE9PTFdJTkRPVykpCgkJewoJCSAgICBpZiAoTkNfSWNvbkZvcldpbmRvdyh3bmRQdHIpKQoJCQlyZWN0LmxlZnQgKz0gR2V0U3lzdGVtTWV0cmljcyhTTV9DWUNBUFRJT04pIC0gMTsKCQl9CiAgICAgICAgICAgICAgICBpZiAocHQueCA8IHJlY3QubGVmdCkgcmV0dXJuIEhUU1lTTUVOVTsKCiAgICAgICAgICAgICAgICAvKiBDaGVjayBjbG9zZSBidXR0b24gKi8KICAgICAgICAgICAgICAgIGlmICh3bmRQdHItPmR3U3R5bGUgJiBXU19TWVNNRU5VKQogICAgICAgICAgICAgICAgICAgIHJlY3QucmlnaHQgLT0gR2V0U3lzdGVtTWV0cmljcyhTTV9DWUNBUFRJT04pIC0gMTsKICAgICAgICAgICAgICAgIGlmIChwdC54ID4gcmVjdC5yaWdodCkgcmV0dXJuIEhUQ0xPU0U7CgogICAgICAgICAgICAgICAgLyogQ2hlY2sgbWF4aW1pemUgYm94ICovCgkJLyogSW4gd2luOTUgdGhlcmUgaXMgYXV0b21hdGljYWxseSBhIE1heGltaXplIGJ1dHRvbiB3aGVuIHRoZXJlIGlzIGEgbWluaW1pemUgb25lKi8KICAgICAgICAgICAgICAgIGlmICgod25kUHRyLT5kd1N0eWxlICYgV1NfTUFYSU1JWkVCT1gpfHwgKHduZFB0ci0+ZHdTdHlsZSAmIFdTX01JTklNSVpFQk9YKSkKICAgICAgICAgICAgICAgICAgICByZWN0LnJpZ2h0IC09IEdldFN5c3RlbU1ldHJpY3MoU01fQ1hTSVpFKSArIDE7CiAgICAgICAgICAgICAgICBpZiAocHQueCA+IHJlY3QucmlnaHQpIHJldHVybiBIVE1BWEJVVFRPTjsKCiAgICAgICAgICAgICAgICAvKiBDaGVjayBtaW5pbWl6ZSBib3ggKi8KCQkvKiBJbiB3aW45NSB0aGVyZSBpcyBhdXRvbWF0aWNhbGx5IGEgTWF4aW1pemUgYnV0dG9uIHdoZW4gdGhlcmUgaXMgYSBNYXhpbWl6ZSBvbmUqLwogICAgICAgICAgICAgICAgaWYgKCh3bmRQdHItPmR3U3R5bGUgJiBXU19NSU5JTUlaRUJPWCl8fCh3bmRQdHItPmR3U3R5bGUgJiBXU19NQVhJTUlaRUJPWCkpCiAgICAgICAgICAgICAgICAgICAgcmVjdC5yaWdodCAtPSBHZXRTeXN0ZW1NZXRyaWNzKFNNX0NYU0laRSkgKyAxOwoKICAgICAgICAgICAgICAgIGlmIChwdC54ID4gcmVjdC5yaWdodCkgcmV0dXJuIEhUTUlOQlVUVE9OOwogICAgICAgICAgICAgICAgcmV0dXJuIEhUQ0FQVElPTjsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0KCiAgICAgIC8qIENoZWNrIGNsaWVudCBhcmVhICovCgogICAgU2NyZWVuVG9DbGllbnQoIHduZFB0ci0+aHduZFNlbGYsICZwdCApOwogICAgR2V0Q2xpZW50UmVjdCggd25kUHRyLT5od25kU2VsZiwgJnJlY3QgKTsKICAgIGlmIChQdEluUmVjdCggJnJlY3QsIHB0ICkpIHJldHVybiBIVENMSUVOVDsKCiAgICAgIC8qIENoZWNrIHZlcnRpY2FsIHNjcm9sbCBiYXIgKi8KCiAgICBpZiAod25kUHRyLT5kd1N0eWxlICYgV1NfVlNDUk9MTCkKICAgIHsKCXJlY3QucmlnaHQgKz0gR2V0U3lzdGVtTWV0cmljcyhTTV9DWFZTQ1JPTEwpOwoJaWYgKFB0SW5SZWN0KCAmcmVjdCwgcHQgKSkgcmV0dXJuIEhUVlNDUk9MTDsKICAgIH0KCiAgICAgIC8qIENoZWNrIGhvcml6b250YWwgc2Nyb2xsIGJhciAqLwoKICAgIGlmICh3bmRQdHItPmR3U3R5bGUgJiBXU19IU0NST0xMKQogICAgewoJcmVjdC5ib3R0b20gKz0gR2V0U3lzdGVtTWV0cmljcyhTTV9DWUhTQ1JPTEwpOwoJaWYgKFB0SW5SZWN0KCAmcmVjdCwgcHQgKSkKCXsKCSAgICAgIC8qIENoZWNrIHNpemUgYm94ICovCgkgICAgaWYgKCh3bmRQdHItPmR3U3R5bGUgJiBXU19WU0NST0xMKSAmJgoJCShwdC54ID49IHJlY3QucmlnaHQgLSBHZXRTeXN0ZW1NZXRyaWNzKFNNX0NYVlNDUk9MTCkpKQoJCXJldHVybiBIVFNJWkU7CgkgICAgcmV0dXJuIEhUSFNDUk9MTDsKCX0KICAgIH0KCiAgICAgIC8qIENoZWNrIG1lbnUgYmFyICovCgogICAgaWYgKEhBU19NRU5VKHduZFB0cikpCiAgICB7CglpZiAoKHB0LnkgPCAwKSAmJiAocHQueCA+PSAwKSAmJiAocHQueCA8IHJlY3QucmlnaHQpKQoJICAgIHJldHVybiBIVE1FTlU7CiAgICB9CgogICAgLyogSGFzIHRvIHJldHVybiBIVE5PV0hFUkUgaWYgbm90aGluZyB3YXMgZm91bmQgIAogICAgICAgQ291bGQgaGFwcGVuIHdoZW4gYSB3aW5kb3cgaGFzIGEgY3VzdG9taXplZCBub24gY2xpZW50IGFyZWEgKi8KICAgIHJldHVybiBIVE5PV0hFUkU7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogTkNfSGFuZGxlTkNIaXRUZXN0CiAqCiAqIEhhbmRsZSBhIFdNX05DSElUVEVTVCBtZXNzYWdlLiBDYWxsZWQgZnJvbSBEZWZXaW5kb3dQcm9jKCkuCiAqLwpMT05HIE5DX0hhbmRsZU5DSGl0VGVzdCAoSFdORCBod25kICwgUE9JTlQgcHQpCnsKICAgIExPTkcgcmV0dmFsdWU7CiAgICBXTkQgKnduZFB0ciA9IFdJTl9GaW5kV25kUHRyIChod25kKTsKCiAgICBpZiAoIXduZFB0cikKCXJldHVybiBIVEVSUk9SOwoKICAgIGlmIChUV0VBS19XaW5lTG9vayA9PSBXSU4zMV9MT09LKQogICAgICAgIHJldHZhbHVlID0gTkNfRG9OQ0hpdFRlc3QgKHduZFB0ciwgcHQpOwogICAgZWxzZQogICAgICAgIHJldHZhbHVlID0gTkNfRG9OQ0hpdFRlc3Q5NSAod25kUHRyLCBwdCk7CiAgICBXSU5fUmVsZWFzZVduZFB0cih3bmRQdHIpOwogICAgcmV0dXJuIHJldHZhbHVlOwp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgICAgICBOQ19EcmF3U3lzQnV0dG9uCiAqLwp2b2lkIE5DX0RyYXdTeXNCdXR0b24oIEhXTkQgaHduZCwgSERDIGhkYywgQk9PTCBkb3duICkKewogICAgUkVDVCByZWN0OwogICAgSERDIGhkY01lbTsKICAgIEhCSVRNQVAgaGJpdG1hcDsKICAgIFdORCAqd25kUHRyID0gV0lOX0ZpbmRXbmRQdHIoIGh3bmQgKTsKCiAgICBpZiggISh3bmRQdHItPmR3RXhTdHlsZSAmIFdTX0VYX01BTkFHRUQpICkKICAgIHsKICAgICAgTkNfR2V0SW5zaWRlUmVjdCggaHduZCwgJnJlY3QgKTsKICAgICAgaGRjTWVtID0gQ3JlYXRlQ29tcGF0aWJsZURDKCBoZGMgKTsKICAgICAgaGJpdG1hcCA9IFNlbGVjdE9iamVjdCggaGRjTWVtLCBoYml0bWFwQ2xvc2UgKTsKICAgICAgQml0Qmx0KGhkYywgcmVjdC5sZWZ0LCByZWN0LnRvcCwgR2V0U3lzdGVtTWV0cmljcyhTTV9DWFNJWkUpLCBHZXRTeXN0ZW1NZXRyaWNzKFNNX0NZU0laRSksCiAgICAgICAgICAgICAgIGhkY01lbSwgKHduZFB0ci0+ZHdTdHlsZSAmIFdTX0NISUxEKSA/IEdldFN5c3RlbU1ldHJpY3MoU01fQ1hTSVpFKSA6IDAsIDAsCiAgICAgICAgICAgICAgIGRvd24gPyBOT1RTUkNDT1BZIDogU1JDQ09QWSApOwogICAgICBTZWxlY3RPYmplY3QoIGhkY01lbSwgaGJpdG1hcCApOwogICAgICBEZWxldGVEQyggaGRjTWVtICk7CiAgICB9CiAgICBXSU5fUmVsZWFzZVduZFB0cih3bmRQdHIpOwp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgICAgICBOQ19EcmF3TWF4QnV0dG9uCiAqLwpzdGF0aWMgdm9pZCBOQ19EcmF3TWF4QnV0dG9uKCBIV05EIGh3bmQsIEhEQzE2IGhkYywgQk9PTCBkb3duICkKewogICAgUkVDVCByZWN0OwogICAgV05EICp3bmRQdHIgPSBXSU5fRmluZFduZFB0ciggaHduZCApOwogICAgSERDIGhkY01lbTsKCiAgICBpZiggISh3bmRQdHItPmR3RXhTdHlsZSAmIFdTX0VYX01BTkFHRUQpICkKICAgIHsKICAgICAgTkNfR2V0SW5zaWRlUmVjdCggaHduZCwgJnJlY3QgKTsKICAgICAgaGRjTWVtID0gQ3JlYXRlQ29tcGF0aWJsZURDKCBoZGMgKTsKICAgICAgU2VsZWN0T2JqZWN0KCBoZGNNZW0sICAoSXNab29tZWQoaHduZCkgCgkJCSAgICAgPyAoZG93biA/IGhiaXRtYXBSZXN0b3JlRCA6IGhiaXRtYXBSZXN0b3JlKQoJCQkgICAgIDogKGRvd24gPyBoYml0bWFwTWF4aW1pemVEIDogaGJpdG1hcE1heGltaXplKSkgKTsKICAgICAgQml0Qmx0KCBoZGMsIHJlY3QucmlnaHQgLSBHZXRTeXN0ZW1NZXRyaWNzKFNNX0NYU0laRSkgLSAxLCByZWN0LnRvcCwKCQlHZXRTeXN0ZW1NZXRyaWNzKFNNX0NYU0laRSkgKyAxLCBHZXRTeXN0ZW1NZXRyaWNzKFNNX0NZU0laRSksIGhkY01lbSwgMCwgMCwKCQlTUkNDT1BZICk7CiAgICAgIERlbGV0ZURDKCBoZGNNZW0gKTsKICAgIH0KICAgIFdJTl9SZWxlYXNlV25kUHRyKHduZFB0cik7Cgp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgICAgICBOQ19EcmF3TWluQnV0dG9uCiAqLwpzdGF0aWMgdm9pZCBOQ19EcmF3TWluQnV0dG9uKCBIV05EIGh3bmQsIEhEQzE2IGhkYywgQk9PTCBkb3duICkKewogICAgUkVDVCByZWN0OwogICAgV05EICp3bmRQdHIgPSBXSU5fRmluZFduZFB0ciggaHduZCApOwogICAgSERDIGhkY01lbTsKCiAgICBpZiggISh3bmRQdHItPmR3RXhTdHlsZSAmIFdTX0VYX01BTkFHRUQpICkKICAgIHsKICAgICAgTkNfR2V0SW5zaWRlUmVjdCggaHduZCwgJnJlY3QgKTsKICAgICAgaGRjTWVtID0gQ3JlYXRlQ29tcGF0aWJsZURDKCBoZGMgKTsKICAgICAgU2VsZWN0T2JqZWN0KCBoZGNNZW0sIChkb3duID8gaGJpdG1hcE1pbmltaXplRCA6IGhiaXRtYXBNaW5pbWl6ZSkgKTsKICAgICAgaWYgKHduZFB0ci0+ZHdTdHlsZSAmIFdTX01BWElNSVpFQk9YKSByZWN0LnJpZ2h0IC09IEdldFN5c3RlbU1ldHJpY3MoU01fQ1hTSVpFKSsxOwogICAgICBCaXRCbHQoIGhkYywgcmVjdC5yaWdodCAtIEdldFN5c3RlbU1ldHJpY3MoU01fQ1hTSVpFKSAtIDEsIHJlY3QudG9wLAoJCUdldFN5c3RlbU1ldHJpY3MoU01fQ1hTSVpFKSArIDEsIEdldFN5c3RlbU1ldHJpY3MoU01fQ1lTSVpFKSwgaGRjTWVtLCAwLCAwLAoJCVNSQ0NPUFkgKTsKICAgICAgRGVsZXRlREMoIGhkY01lbSApOwogICAgfQogICAgV0lOX1JlbGVhc2VXbmRQdHIod25kUHRyKTsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoKICogICB2b2lkICBOQ19EcmF3U3lzQnV0dG9uOTUoCiAqICAgICAgSFdORCAgaHduZCwKICogICAgICBIREMgIGhkYywKICogICAgICBCT09MICBkb3duICkKICoKICogICBEcmF3cyB0aGUgV2luOTUgc3lzdGVtIGljb24uCiAqCiAqICAgUmV2aXNpb24gaGlzdG9yeQogKiAgICAgICAgMDUtSnVsLTE5OTcgRGF2ZSBDdXRoYmVydCAoZGFjdXRAZWNlLmNtdS5lZHUpCiAqICAgICAgICAgICAgIE9yaWdpbmFsIGltcGxlbWVudGF0aW9uIGZyb20gTkNfRHJhd1N5c0J1dHRvbiBzb3VyY2UuCiAqICAgICAgICAxMS1KdW4tMTk5OCBFcmljIEtvaGwgKGVrb2hsQGFiby5yaGVpbi16ZWl0dW5nLmRlKQogKiAgICAgICAgICAgICBGaXhlZCBtb3N0IGJ1Z3MuCiAqCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KCkJPT0wKTkNfRHJhd1N5c0J1dHRvbjk1IChIV05EIGh3bmQsIEhEQyBoZGMsIEJPT0wgZG93bikKewogICAgV05EICp3bmRQdHIgPSBXSU5fRmluZFduZFB0ciggaHduZCApOwoKICAgIGlmKCAhKHduZFB0ci0+ZHdFeFN0eWxlICYgV1NfRVhfTUFOQUdFRCkgKQogICAgewoJSElDT04gIGhJY29uOwoJUkVDVCByZWN0OwoKCU5DX0dldEluc2lkZVJlY3Q5NSggaHduZCwgJnJlY3QgKTsKCgloSWNvbiA9IE5DX0ljb25Gb3JXaW5kb3coIHduZFB0ciApOwoKCWlmIChoSWNvbikKCSAgICBEcmF3SWNvbkV4IChoZGMsIHJlY3QubGVmdCArIDIsIHJlY3QudG9wICsgMiwgaEljb24sCgkJCSAgR2V0U3lzdGVtTWV0cmljcyhTTV9DWFNNSUNPTiksCgkJCSAgR2V0U3lzdGVtTWV0cmljcyhTTV9DWVNNSUNPTiksCgkJCSAgMCwgMCwgRElfTk9STUFMKTsKCiAgICAgICAgV0lOX1JlbGVhc2VXbmRQdHIod25kUHRyKTsKCXJldHVybiAoaEljb24gIT0gMCk7CiAgICB9CiAgICBXSU5fUmVsZWFzZVduZFB0cih3bmRQdHIpOwogICAgcmV0dXJuIEZBTFNFOwp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgogKiAgIHZvaWQgIE5DX0RyYXdDbG9zZUJ1dHRvbjk1KAogKiAgICAgIEhXTkQgIGh3bmQsCiAqICAgICAgSERDICBoZGMsCiAqICAgICAgQk9PTCAgZG93biwKICogICAgICBCT09MICAgIGJHcmF5ZWQgKQogKgogKiAgIERyYXdzIHRoZSBXaW45NSBjbG9zZSBidXR0b24uCiAqCiAqICAgSWYgYkdyYXllZCBpcyB0cnVlLCB0aGVuIGRyYXcgYSBkaXNhYmxlZCBDbG9zZSBidXR0b24KICoKICogICBSZXZpc2lvbiBoaXN0b3J5CiAqICAgICAgICAxMS1KdW4tMTk5OCBFcmljIEtvaGwgKGVrb2hsQGFiby5yaGVpbi16ZWl0dW5nLmRlKQogKiAgICAgICAgICAgICBPcmlnaW5hbCBpbXBsZW1lbnRhdGlvbiBmcm9tIE5DX0RyYXdTeXNCdXR0b245NSBzb3VyY2UuCiAqCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KCnN0YXRpYyB2b2lkIE5DX0RyYXdDbG9zZUJ1dHRvbjk1IChIV05EIGh3bmQsIEhEQyBoZGMsIEJPT0wgZG93biwgQk9PTCBiR3JheWVkKQp7CiAgICBSRUNUIHJlY3Q7CiAgICBIREMgaGRjTWVtOwogICAgV05EICp3bmRQdHIgPSBXSU5fRmluZFduZFB0ciggaHduZCApOwoKICAgIGlmKCAhKHduZFB0ci0+ZHdFeFN0eWxlICYgV1NfRVhfTUFOQUdFRCkgKQogICAgewoJQklUTUFQIGJtcDsKCUhCSVRNQVAgaEJtcCwgaE9sZEJtcDsKCglOQ19HZXRJbnNpZGVSZWN0OTUoIGh3bmQsICZyZWN0ICk7CgoJLyogQSB0b29sIHdpbmRvdyBoYXMgYSBzbWFsbGVyIENsb3NlIGJ1dHRvbiAqLwoJaWYod25kUHRyLT5kd0V4U3R5bGUgJiBXU19FWF9UT09MV0lORE9XKQoJewogICAgICAgICAgICBSRUNUIHRvb2xSZWN0OwkgICAgIAogICAgICAgICAgICBJTlQgaUJtcEhlaWdodCA9IDExOyAvKiBXaW5kb3dzIGRvZXMgbm90IHVzZSBTTV9DWFNNU0laRSBhbmQgU01fQ1lTTVNJWkUgICAqLwogICAgICAgICAgICBJTlQgaUJtcFdpZHRoID0gMTE7ICAvKiBpdCB1c2VzIDExeDExIGZvciAgdGhlIGNsb3NlIGJ1dHRvbiBpbiB0b29sIHdpbmRvdyAqLyAJICAJIAogICAgICAgICAgICBJTlQgaUNhcHRpb25IZWlnaHQgPSBHZXRTeXN0ZW1NZXRyaWNzKFNNX0NZU01DQVBUSU9OKTsKCiAgICAgICAgICAgIHRvb2xSZWN0LnRvcCA9IHJlY3QudG9wICsgKGlDYXB0aW9uSGVpZ2h0IC0gMSAtIGlCbXBIZWlnaHQpIC8gMjsKICAgICAgICAgICAgdG9vbFJlY3QubGVmdCA9IHJlY3QucmlnaHQgLSAoaUNhcHRpb25IZWlnaHQgKyAxICsgaUJtcFdpZHRoKSAvIDI7CiAgICAgICAgICAgIHRvb2xSZWN0LmJvdHRvbSA9IHRvb2xSZWN0LnRvcCArIGlCbXBIZWlnaHQ7CiAgICAgICAgICAgIHRvb2xSZWN0LnJpZ2h0ID0gdG9vbFJlY3QubGVmdCArIGlCbXBXaWR0aDsKICAgICAgICAgICAgRHJhd0ZyYW1lQ29udHJvbChoZGMsJnRvb2xSZWN0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIERGQ19DQVBUSU9OLERGQ1NfQ0FQVElPTkNMT1NFIHwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZG93biA/IERGQ1NfUFVTSEVEIDogMCB8IAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJHcmF5ZWQgPyBERkNTX0lOQUNUSVZFIDogMCk7Cgl9CgllbHNlCgl7CiAgICAgICAgICAgIGhkY01lbSA9IENyZWF0ZUNvbXBhdGlibGVEQyggaGRjICk7CiAgICAgICAgICAgIGhCbXAgPSBkb3duID8gaGJpdG1hcENsb3NlRCA6IGhiaXRtYXBDbG9zZTsKICAgICAgICAgICAgaE9sZEJtcCA9IFNlbGVjdE9iamVjdCAoaGRjTWVtLCBoQm1wKTsKICAgICAgICAgICAgR2V0T2JqZWN0QSAoaEJtcCwgc2l6ZW9mKEJJVE1BUCksICZibXApOwoKICAgICAgICAgICAgQml0Qmx0IChoZGMsIHJlY3QucmlnaHQgLSAoR2V0U3lzdGVtTWV0cmljcyhTTV9DWUNBUFRJT04pICsgMSArIGJtcC5ibVdpZHRoKSAvIDIsCiAgICAgICAgICAgICAgICAgICAgcmVjdC50b3AgKyAoR2V0U3lzdGVtTWV0cmljcyhTTV9DWUNBUFRJT04pIC0gMSAtIGJtcC5ibUhlaWdodCkgLyAyLAogICAgICAgICAgICAgICAgICAgIGJtcC5ibVdpZHRoLCBibXAuYm1IZWlnaHQsIGhkY01lbSwgMCwgMCwgU1JDQ09QWSk7CgogICAgICAgICAgICBpZihiR3JheWVkKQogICAgICAgICAgICAgICAgTkNfRHJhd0dyYXlCdXR0b24oaGRjLHJlY3QucmlnaHQgLSAoR2V0U3lzdGVtTWV0cmljcyhTTV9DWUNBUFRJT04pICsgMSArIGJtcC5ibVdpZHRoKSAvIDIgKyAyLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVjdC50b3AgKyAoR2V0U3lzdGVtTWV0cmljcyhTTV9DWUNBUFRJT04pIC0gMSAtIGJtcC5ibUhlaWdodCkgLyAyICsgMik7CgogICAgICAgICAgICBTZWxlY3RPYmplY3QgKGhkY01lbSwgaE9sZEJtcCk7CiAgICAgICAgICAgIERlbGV0ZURDIChoZGNNZW0pOwoJfQogICAgfQogICAgV0lOX1JlbGVhc2VXbmRQdHIod25kUHRyKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgogKiAgIE5DX0RyYXdNYXhCdXR0b245NSgKICogICAgICBIV05EICBod25kLAogKiAgICAgIEhEQzE2ICBoZGMsCiAqICAgICAgQk9PTCAgZG93biAKICogICAgICBCT09MICAgIGJHcmF5ZWQgKQogKgogKiAgIERyYXdzIHRoZSBtYXhpbWl6ZSBidXR0b24gZm9yIFdpbjk1IHN0eWxlIHdpbmRvd3MuCiAqCiAqICAgSWYgYkdyYXllZCBpcyB0cnVlLCB0aGVuIGRyYXcgYSBkaXNhYmxlZCBNYXhpbWl6ZSBidXR0b24KICoKICogICBCdWdzCiAqICAgICAgICBNYW55LiAgU3BhY2luZyBtaWdodCBzdGlsbCBiZSBpbmNvcnJlY3QuICBOZWVkIHRvIGZpdCBhIGNsb3NlCiAqICAgICAgICBidXR0b24gYmV0d2VlbiB0aGUgbWF4IGJ1dHRvbiBhbmQgdGhlIGVkZ2UuCiAqICAgICAgICBTaG91bGQgc2NhbGUgdGhlIGltYWdlIHdpdGggdGhlIHRpdGxlIGJhci4gIEFuZCBtb3JlLi4uCiAqCiAqICAgUmV2aXNpb24gaGlzdG9yeQogKiAgICAgICAgMDUtSnVsLTE5OTcgRGF2ZSBDdXRoYmVydCAoZGFjdXRAZWNlLmNtdS5lZHUpCiAqICAgICAgICAgICAgIE9yaWdpbmFsIGltcGxlbWVudGF0aW9uLgogKgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCgpzdGF0aWMgdm9pZCBOQ19EcmF3TWF4QnV0dG9uOTUoSFdORCBod25kLEhEQzE2IGhkYyxCT09MIGRvd24sIEJPT0wgYkdyYXllZCkKewogICAgUkVDVCByZWN0OwogICAgSERDIGhkY01lbTsKICAgIFdORCAqd25kUHRyID0gV0lOX0ZpbmRXbmRQdHIoIGh3bmQgKTsKCiAgICBpZiggISh3bmRQdHItPmR3RXhTdHlsZSAmIFdTX0VYX01BTkFHRUQpKQogICAgewogICAgICAgIEJJVE1BUCAgYm1wOwogICAgICAgIEhCSVRNQVAgIGhCbXAsaE9sZEJtcDsKCglOQ19HZXRJbnNpZGVSZWN0OTUoIGh3bmQsICZyZWN0ICk7CgloZGNNZW0gPSBDcmVhdGVDb21wYXRpYmxlREMoIGhkYyApOwoJaEJtcCA9IElzWm9vbWVkKGh3bmQpID8KCSAgICAoZG93biA/IGhiaXRtYXBSZXN0b3JlRCA6IGhiaXRtYXBSZXN0b3JlICkgOgoJICAgIChkb3duID8gaGJpdG1hcE1heGltaXplRDogaGJpdG1hcE1heGltaXplKTsKCWhPbGRCbXA9U2VsZWN0T2JqZWN0KCBoZGNNZW0sIGhCbXAgKTsKCUdldE9iamVjdEEgKGhCbXAsIHNpemVvZihCSVRNQVApLCAmYm1wKTsKCQoJaWYgKHduZFB0ci0+ZHdTdHlsZSAmIFdTX1NZU01FTlUpCgkgICAgcmVjdC5yaWdodCAtPSBHZXRTeXN0ZW1NZXRyaWNzKFNNX0NZQ0FQVElPTikgKyAxOwoJCglCaXRCbHQoIGhkYywgcmVjdC5yaWdodCAtIChHZXRTeXN0ZW1NZXRyaWNzKFNNX0NYU0laRSkgKyBibXAuYm1XaWR0aCkgLyAyLAoJCSAgcmVjdC50b3AgKyAoR2V0U3lzdGVtTWV0cmljcyhTTV9DWUNBUFRJT04pIC0gMSAtIGJtcC5ibUhlaWdodCkgLyAyLAoJCSAgYm1wLmJtV2lkdGgsIGJtcC5ibUhlaWdodCwgaGRjTWVtLCAwLCAwLCBTUkNDT1BZICk7CgkKCWlmKGJHcmF5ZWQpCgkgICAgTkNfRHJhd0dyYXlCdXR0b24oaGRjLCByZWN0LnJpZ2h0IC0gKEdldFN5c3RlbU1ldHJpY3MoU01fQ1hTSVpFKSArIGJtcC5ibVdpZHRoKSAvIDIgKyAyLAoJCQkgICAgICByZWN0LnRvcCArIChHZXRTeXN0ZW1NZXRyaWNzKFNNX0NZQ0FQVElPTikgLSAxIC0gYm1wLmJtSGVpZ2h0KSAvIDIgKyAyKTsKCSAgICAKCQoJU2VsZWN0T2JqZWN0IChoZGNNZW0sIGhPbGRCbXApOwoJRGVsZXRlREMoIGhkY01lbSApOwogICAgfQogICAgV0lOX1JlbGVhc2VXbmRQdHIod25kUHRyKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgogKiAgIE5DX0RyYXdNaW5CdXR0b245NSgKICogICAgICBIV05EICBod25kLAogKiAgICAgIEhEQzE2ICBoZGMsCiAqICAgICAgQk9PTCAgZG93biwKICogICAgICBCT09MICAgIGJHcmF5ZWQgKQogKgogKiAgIERyYXdzIHRoZSBtaW5pbWl6ZSBidXR0b24gZm9yIFdpbjk1IHN0eWxlIHdpbmRvd3MuCiAqCiAqICAgSWYgYkdyYXllZCBpcyB0cnVlLCB0aGVuIGRyYXcgYSBkaXNhYmxlZCBNaW5pbWl6ZSBidXR0b24KICoKICogICBCdWdzCiAqICAgICAgICBNYW55LiAgU3BhY2luZyBpcyBzdGlsbCBpbmNvcnJlY3QuICBTaG91bGQgc2NhbGUgdGhlIGltYWdlIHdpdGggdGhlCiAqICAgICAgICB0aXRsZSBiYXIuICBBbmQgbW9yZS4uLgogKgogKiAgIFJldmlzaW9uIGhpc3RvcnkKICogICAgICAgIDA1LUp1bC0xOTk3IERhdmUgQ3V0aGJlcnQgKGRhY3V0QGVjZS5jbXUuZWR1KQogKiAgICAgICAgICAgICBPcmlnaW5hbCBpbXBsZW1lbnRhdGlvbi4KICoKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwoKc3RhdGljIHZvaWQgIE5DX0RyYXdNaW5CdXR0b245NShIV05EIGh3bmQsSERDMTYgaGRjLEJPT0wgZG93biwgQk9PTCBiR3JheWVkKQp7CiAgICBSRUNUIHJlY3Q7CiAgICBIREMgaGRjTWVtOwogICAgV05EICp3bmRQdHIgPSBXSU5fRmluZFduZFB0ciggaHduZCApOwoKICAgIGlmKCAhKHduZFB0ci0+ZHdFeFN0eWxlICYgV1NfRVhfTUFOQUdFRCkpCiAgICAgICAgCiAgICB7CiAgICAgICBCSVRNQVAgIGJtcDsKICAgICAgIEhCSVRNQVAgIGhCbXAsaE9sZEJtcDsKCQoJTkNfR2V0SW5zaWRlUmVjdDk1KCBod25kLCAmcmVjdCApOwoKICAgICAgIGhkY01lbSA9IENyZWF0ZUNvbXBhdGlibGVEQyggaGRjICk7CiAgICAgICBoQm1wID0gZG93biA/IGhiaXRtYXBNaW5pbWl6ZUQgOiBoYml0bWFwTWluaW1pemU7CiAgICAgICBoT2xkQm1wPSBTZWxlY3RPYmplY3QoIGhkY01lbSwgaEJtcCApOwoJR2V0T2JqZWN0QSAoaEJtcCwgc2l6ZW9mKEJJVE1BUCksICZibXApOwoKCWlmICh3bmRQdHItPmR3U3R5bGUgJiBXU19TWVNNRU5VKQoJICAgIHJlY3QucmlnaHQgLT0gR2V0U3lzdGVtTWV0cmljcyhTTV9DWUNBUFRJT04pICsgMTsKCgkvKiBJbiB3aW4gOTUgdGhlcmUgaXMgYWx3YXlzIGEgTWF4aW1pemUgYm94IHdoZW4gdGhlcmUgaXMgYSBNaW5pbWl6ZSBvbmUgKi8KCWlmICgod25kUHRyLT5kd1N0eWxlICYgV1NfTUFYSU1JWkVCT1gpIHx8ICh3bmRQdHItPmR3U3R5bGUgJiBXU19NSU5JTUlaRUJPWCkpIAoJICAgIHJlY3QucmlnaHQgKz0gLTEgLSAoR2V0U3lzdGVtTWV0cmljcyhTTV9DWFNJWkUpICsgYm1wLmJtV2lkdGgpIC8gMjsKCglCaXRCbHQoIGhkYywgcmVjdC5yaWdodCAtIChHZXRTeXN0ZW1NZXRyaWNzKFNNX0NYU0laRSkgKyBibXAuYm1XaWR0aCkgLyAyLAoJCSAgcmVjdC50b3AgKyAoR2V0U3lzdGVtTWV0cmljcyhTTV9DWUNBUFRJT04pIC0gMSAtIGJtcC5ibUhlaWdodCkgLyAyLAoJCSAgYm1wLmJtV2lkdGgsIGJtcC5ibUhlaWdodCwgaGRjTWVtLCAwLCAwLCBTUkNDT1BZICk7CgoJaWYoYkdyYXllZCkKCSAgICBOQ19EcmF3R3JheUJ1dHRvbihoZGMsIHJlY3QucmlnaHQgLSAoR2V0U3lzdGVtTWV0cmljcyhTTV9DWFNJWkUpICsgYm1wLmJtV2lkdGgpIC8gMiArIDIsCgkJCSAgICAgIHJlY3QudG9wICsgKEdldFN5c3RlbU1ldHJpY3MoU01fQ1lDQVBUSU9OKSAtIDEgLSBibXAuYm1IZWlnaHQpIC8gMiArIDIpOwoJCQkgIAoJCiAgICAgICBTZWxlY3RPYmplY3QgKGhkY01lbSwgaE9sZEJtcCk7CiAgICAgICBEZWxldGVEQyggaGRjTWVtICk7CiAgICB9CiAgICBXSU5fUmVsZWFzZVduZFB0cih3bmRQdHIpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICAgICAgIE5DX0RyYXdGcmFtZQogKgogKiBEcmF3IGEgd2luZG93IGZyYW1lIGluc2lkZSB0aGUgZ2l2ZW4gcmVjdGFuZ2xlLCBhbmQgdXBkYXRlIHRoZSByZWN0YW5nbGUuCiAqIFRoZSBjb3JyZWN0IHBlbiBmb3IgdGhlIGZyYW1lIG11c3QgYmUgc2VsZWN0ZWQgaW4gdGhlIERDLgogKi8Kc3RhdGljIHZvaWQgTkNfRHJhd0ZyYW1lKCBIREMgaGRjLCBSRUNUICpyZWN0LCBCT09MIGRsZ0ZyYW1lLAogICAgICAgICAgICAgICAgICAgICAgICAgIEJPT0wgYWN0aXZlICkKewogICAgSU5UIHdpZHRoLCBoZWlnaHQ7CgogICAgaWYgKFRXRUFLX1dpbmVMb29rICE9IFdJTjMxX0xPT0spCglFUlIoIkNhbGxlZCBpbiBXaW45NSBtb2RlLiBBaWVlISBQbGVhc2UgcmVwb3J0IHRoaXMuXG4iICk7CgogICAgaWYgKGRsZ0ZyYW1lKQogICAgewoJd2lkdGggPSBHZXRTeXN0ZW1NZXRyaWNzKFNNX0NYRExHRlJBTUUpIC0gMTsKCWhlaWdodCA9IEdldFN5c3RlbU1ldHJpY3MoU01fQ1lETEdGUkFNRSkgLSAxOwogICAgICAgIFNlbGVjdE9iamVjdCggaGRjLCBHZXRTeXNDb2xvckJydXNoKGFjdGl2ZSA/IENPTE9SX0FDVElWRUNBUFRJT04gOgoJCQkJCQlDT0xPUl9JTkFDVElWRUNBUFRJT04pICk7CiAgICB9CiAgICBlbHNlCiAgICB7Cgl3aWR0aCA9IEdldFN5c3RlbU1ldHJpY3MoU01fQ1hGUkFNRSkgLSAyOwoJaGVpZ2h0ID0gR2V0U3lzdGVtTWV0cmljcyhTTV9DWUZSQU1FKSAtIDI7CiAgICAgICAgU2VsZWN0T2JqZWN0KCBoZGMsIEdldFN5c0NvbG9yQnJ1c2goYWN0aXZlID8gQ09MT1JfQUNUSVZFQk9SREVSIDoKCQkJCQkJQ09MT1JfSU5BQ1RJVkVCT1JERVIpICk7CiAgICB9CgogICAgICAvKiBEcmF3IGZyYW1lICovCiAgICBQYXRCbHQoIGhkYywgcmVjdC0+bGVmdCwgcmVjdC0+dG9wLAogICAgICAgICAgICAgIHJlY3QtPnJpZ2h0IC0gcmVjdC0+bGVmdCwgaGVpZ2h0LCBQQVRDT1BZICk7CiAgICBQYXRCbHQoIGhkYywgcmVjdC0+bGVmdCwgcmVjdC0+dG9wLAogICAgICAgICAgICAgIHdpZHRoLCByZWN0LT5ib3R0b20gLSByZWN0LT50b3AsIFBBVENPUFkgKTsKICAgIFBhdEJsdCggaGRjLCByZWN0LT5sZWZ0LCByZWN0LT5ib3R0b20gLSAxLAogICAgICAgICAgICAgIHJlY3QtPnJpZ2h0IC0gcmVjdC0+bGVmdCwgLWhlaWdodCwgUEFUQ09QWSApOwogICAgUGF0Qmx0KCBoZGMsIHJlY3QtPnJpZ2h0IC0gMSwgcmVjdC0+dG9wLAogICAgICAgICAgICAgIC13aWR0aCwgcmVjdC0+Ym90dG9tIC0gcmVjdC0+dG9wLCBQQVRDT1BZICk7CgogICAgaWYgKGRsZ0ZyYW1lKQogICAgewoJSW5mbGF0ZVJlY3QoIHJlY3QsIC13aWR0aCwgLWhlaWdodCApOwogICAgfSAKICAgIGVsc2UKICAgIHsKICAgICAgICBJTlQgZGVjWU9mZiA9IEdldFN5c3RlbU1ldHJpY3MoU01fQ1hGUkFNRSkgKyBHZXRTeXN0ZW1NZXRyaWNzKFNNX0NYU0laRSkgLSAxOwoJSU5UIGRlY1hPZmYgPSBHZXRTeXN0ZW1NZXRyaWNzKFNNX0NZRlJBTUUpICsgR2V0U3lzdGVtTWV0cmljcyhTTV9DWVNJWkUpIC0gMTsKCiAgICAgIC8qIERyYXcgaW5uZXIgcmVjdGFuZ2xlICovCgoJU2VsZWN0T2JqZWN0KCBoZGMsIEdldFN0b2NrT2JqZWN0KE5VTExfQlJVU0gpICk7CglSZWN0YW5nbGUoIGhkYywgcmVjdC0+bGVmdCArIHdpZHRoLCByZWN0LT50b3AgKyBoZWlnaHQsCgkJICAgICByZWN0LT5yaWdodCAtIHdpZHRoICwgcmVjdC0+Ym90dG9tIC0gaGVpZ2h0ICk7CgogICAgICAvKiBEcmF3IHRoZSBkZWNvcmF0aW9ucyAqLwoKCU1vdmVUb0V4KCBoZGMsIHJlY3QtPmxlZnQsIHJlY3QtPnRvcCArIGRlY1lPZmYsIE5VTEwgKTsKCUxpbmVUbyggaGRjLCByZWN0LT5sZWZ0ICsgd2lkdGgsIHJlY3QtPnRvcCArIGRlY1lPZmYgKTsKCU1vdmVUb0V4KCBoZGMsIHJlY3QtPnJpZ2h0IC0gMSwgcmVjdC0+dG9wICsgZGVjWU9mZiwgTlVMTCApOwoJTGluZVRvKCBoZGMsIHJlY3QtPnJpZ2h0IC0gd2lkdGggLSAxLCByZWN0LT50b3AgKyBkZWNZT2ZmICk7CglNb3ZlVG9FeCggaGRjLCByZWN0LT5sZWZ0LCByZWN0LT5ib3R0b20gLSBkZWNZT2ZmLCBOVUxMICk7CglMaW5lVG8oIGhkYywgcmVjdC0+bGVmdCArIHdpZHRoLCByZWN0LT5ib3R0b20gLSBkZWNZT2ZmICk7CglNb3ZlVG9FeCggaGRjLCByZWN0LT5yaWdodCAtIDEsIHJlY3QtPmJvdHRvbSAtIGRlY1lPZmYsIE5VTEwgKTsKCUxpbmVUbyggaGRjLCByZWN0LT5yaWdodCAtIHdpZHRoIC0gMSwgcmVjdC0+Ym90dG9tIC0gZGVjWU9mZiApOwoKCU1vdmVUb0V4KCBoZGMsIHJlY3QtPmxlZnQgKyBkZWNYT2ZmLCByZWN0LT50b3AsIE5VTEwgKTsKCUxpbmVUbyggaGRjLCByZWN0LT5sZWZ0ICsgZGVjWE9mZiwgcmVjdC0+dG9wICsgaGVpZ2h0KTsKCU1vdmVUb0V4KCBoZGMsIHJlY3QtPmxlZnQgKyBkZWNYT2ZmLCByZWN0LT5ib3R0b20gLSAxLCBOVUxMICk7CglMaW5lVG8oIGhkYywgcmVjdC0+bGVmdCArIGRlY1hPZmYsIHJlY3QtPmJvdHRvbSAtIGhlaWdodCAtIDEgKTsKCU1vdmVUb0V4KCBoZGMsIHJlY3QtPnJpZ2h0IC0gZGVjWE9mZiwgcmVjdC0+dG9wLCBOVUxMICk7CglMaW5lVG8oIGhkYywgcmVjdC0+cmlnaHQgLSBkZWNYT2ZmLCByZWN0LT50b3AgKyBoZWlnaHQgKTsKCU1vdmVUb0V4KCBoZGMsIHJlY3QtPnJpZ2h0IC0gZGVjWE9mZiwgcmVjdC0+Ym90dG9tIC0gMSwgTlVMTCApOwoJTGluZVRvKCBoZGMsIHJlY3QtPnJpZ2h0IC0gZGVjWE9mZiwgcmVjdC0+Ym90dG9tIC0gaGVpZ2h0IC0gMSApOwoKCUluZmxhdGVSZWN0KCByZWN0LCAtd2lkdGggLSAxLCAtaGVpZ2h0IC0gMSApOwogICAgfQp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgogKiAgIHZvaWQgIE5DX0RyYXdGcmFtZTk1KAogKiAgICAgIEhEQyAgaGRjLAogKiAgICAgIFJFQ1QgICpyZWN0LAogKiAgICAgIEJPT0wgIGRsZ0ZyYW1lLAogKiAgICAgIEJPT0wgIGFjdGl2ZSApCiAqCiAqICAgRHJhdyBhIHdpbmRvdyBmcmFtZSBpbnNpZGUgdGhlIGdpdmVuIHJlY3RhbmdsZSwgYW5kIHVwZGF0ZSB0aGUgcmVjdGFuZ2xlLgogKiAgIFRoZSBjb3JyZWN0IHBlbiBmb3IgdGhlIGZyYW1lIG11c3QgYmUgc2VsZWN0ZWQgaW4gdGhlIERDLgogKgogKiAgIEJ1Z3MKICogICAgICAgIE1hbnkuICBGaXJzdCwganVzdCB3aGF0IElTIGEgZnJhbWUgaW4gV2luOTU/ICBOb3RlIHRoYXQgdGhlIDNEIGxvb2sKICogICAgICAgIG9uIHRoZSBvdXRlciBlZGdlIGlzIGhhbmRsZWQgYnkgTkNfRG9OQ1BhaW50OTUuICBBcyBpcyB0aGUgaW5uZXIKICogICAgICAgIGVkZ2UuICBUaGUgaW5uZXIgcmVjdGFuZ2xlIGp1c3QgaW5zaWRlIHRoZSBmcmFtZSBpcyBoYW5kbGVkIGJ5IHRoZQogKiAgICAgICAgQ2FwdGlvbiBjb2RlLgogKgogKiAgICAgICAgSW4gc2hvcnQsIGZvciBtb3N0IHBlb3BsZSwgdGhpcyBmdW5jdGlvbiBzaG91bGQgYmUgYSBub3AgKHVubGVzcwogKiAgICAgICAgeW91IExJS0UgdGhpY2sgYm9yZGVycyBpbiBXaW45NS9OVDQuMCAtLSBJJ3ZlIGJlZW4gd29ya2luZyB3aXRoCiAqICAgICAgICB0aGVtIGxhdGVseSwgYnV0IGp1c3QgdG8gZ2V0IHRoaXMgY29kZSByaWdodCkuICBFdmVuIHNvLCBpdCBkb2Vzbid0CiAqICAgICAgICBhcHBlYXIgdG8gYmUgc28uICBJdCdzIGJlaW5nIHdvcmtlZCBvbi4uLgogKiAKICogICBSZXZpc2lvbiBoaXN0b3J5CiAqICAgICAgICAwNi1KdWwtMTk5NyBEYXZlIEN1dGhiZXJ0IChkYWN1dEBlY2UuY211LmVkdSkKICogICAgICAgICAgICAgT3JpZ2luYWwgaW1wbGVtZW50YXRpb24gKGJhc2VkIG9uIE5DX0RyYXdGcmFtZSkKICogICAgICAgIDAyLUp1bi0xOTk4IEVyaWMgS29obCAoZWtvaGxAYWJvLnJoZWluLXplaXR1bmcuZGUpCiAqICAgICAgICAgICAgIFNvbWUgbWlub3IgZml4ZXMuCiAqICAgICAgICAyOS1KdW4tMTk5OSBPdmUgS+V2ZW4gKG92ZWtAYXJjdGljbmV0Lm5vKQogKiAgICAgICAgICAgICBGaXhlZCBhIGZpeCBvciBzb21ldGhpbmcuCiAqCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KCnN0YXRpYyB2b2lkICBOQ19EcmF3RnJhbWU5NSgKICAgIEhEQyAgaGRjLAogICAgUkVDVCAgKnJlY3QsCiAgICBCT09MICBkbGdGcmFtZSwKICAgIEJPT0wgIGFjdGl2ZSApCnsKICAgIElOVCB3aWR0aCwgaGVpZ2h0OwoKICAgIGlmIChkbGdGcmFtZSkKICAgIHsKCXdpZHRoID0gR2V0U3lzdGVtTWV0cmljcyhTTV9DWERMR0ZSQU1FKSAtIEdldFN5c3RlbU1ldHJpY3MoU01fQ1hFREdFKTsKCWhlaWdodCA9IEdldFN5c3RlbU1ldHJpY3MoU01fQ1lETEdGUkFNRSkgLSBHZXRTeXN0ZW1NZXRyaWNzKFNNX0NZRURHRSk7CiAgICB9CiAgICBlbHNlCiAgICB7Cgl3aWR0aCA9IEdldFN5c3RlbU1ldHJpY3MoU01fQ1hGUkFNRSkgLSBHZXRTeXN0ZW1NZXRyaWNzKFNNX0NYRURHRSk7CgloZWlnaHQgPSBHZXRTeXN0ZW1NZXRyaWNzKFNNX0NZRlJBTUUpIC0gR2V0U3lzdGVtTWV0cmljcyhTTV9DWUVER0UpOwogICAgfQoKICAgIFNlbGVjdE9iamVjdCggaGRjLCBHZXRTeXNDb2xvckJydXNoKGFjdGl2ZSA/IENPTE9SX0FDVElWRUJPUkRFUiA6CgkJQ09MT1JfSU5BQ1RJVkVCT1JERVIpICk7CgogICAgLyogRHJhdyBmcmFtZSAqLwogICAgUGF0Qmx0KCBoZGMsIHJlY3QtPmxlZnQsIHJlY3QtPnRvcCwKICAgICAgICAgICAgICByZWN0LT5yaWdodCAtIHJlY3QtPmxlZnQsIGhlaWdodCwgUEFUQ09QWSApOwogICAgUGF0Qmx0KCBoZGMsIHJlY3QtPmxlZnQsIHJlY3QtPnRvcCwKICAgICAgICAgICAgICB3aWR0aCwgcmVjdC0+Ym90dG9tIC0gcmVjdC0+dG9wLCBQQVRDT1BZICk7CiAgICBQYXRCbHQoIGhkYywgcmVjdC0+bGVmdCwgcmVjdC0+Ym90dG9tIC0gMSwKICAgICAgICAgICAgICByZWN0LT5yaWdodCAtIHJlY3QtPmxlZnQsIC1oZWlnaHQsIFBBVENPUFkgKTsKICAgIFBhdEJsdCggaGRjLCByZWN0LT5yaWdodCAtIDEsIHJlY3QtPnRvcCwKICAgICAgICAgICAgICAtd2lkdGgsIHJlY3QtPmJvdHRvbSAtIHJlY3QtPnRvcCwgUEFUQ09QWSApOwoKICAgIEluZmxhdGVSZWN0KCByZWN0LCAtd2lkdGgsIC1oZWlnaHQgKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgICAgICBOQ19EcmF3TW92aW5nRnJhbWUKICoKICogRHJhdyB0aGUgZnJhbWUgdXNlZCB3aGVuIG1vdmluZyBvciByZXNpemluZyB3aW5kb3cuCiAqCiAqIEZJWE1FOiAgVGhpcyBjYXVzZXMgcHJvYmxlbXMgaW4gV2luOTUgbW9kZS4gICh3aHk/KQogKi8Kc3RhdGljIHZvaWQgTkNfRHJhd01vdmluZ0ZyYW1lKCBIREMgaGRjLCBSRUNUICpyZWN0LCBCT09MIHRoaWNrZnJhbWUgKQp7CiAgICBpZiAodGhpY2tmcmFtZSkKICAgIHsKICAgICAgICBSRUNUMTYgcjE2OwogICAgICAgIENPTlZfUkVDVDMyVE8xNiggcmVjdCwgJnIxNiApOwogICAgICAgIEZhc3RXaW5kb3dGcmFtZTE2KCBoZGMsICZyMTYsIEdldFN5c3RlbU1ldHJpY3MoU01fQ1hGUkFNRSksCiAgICAgICAgICAgICAgICAgICAgICAgICBHZXRTeXN0ZW1NZXRyaWNzKFNNX0NZRlJBTUUpLCBQQVRJTlZFUlQgKTsKICAgIH0KICAgIGVsc2UgRHJhd0ZvY3VzUmVjdCggaGRjLCByZWN0ICk7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICAgICAgIE5DX0RyYXdDYXB0aW9uCiAqCiAqIERyYXcgdGhlIHdpbmRvdyBjYXB0aW9uLgogKiBUaGUgY29ycmVjdCBwZW4gZm9yIHRoZSB3aW5kb3cgZnJhbWUgbXVzdCBiZSBzZWxlY3RlZCBpbiB0aGUgREMuCiAqLwpzdGF0aWMgdm9pZCBOQ19EcmF3Q2FwdGlvbiggSERDIGhkYywgUkVDVCAqcmVjdCwgSFdORCBod25kLAoJCQkgICAgRFdPUkQgc3R5bGUsIEJPT0wgYWN0aXZlICkKewogICAgUkVDVCByID0gKnJlY3Q7CiAgICBXTkQgKiB3bmRQdHIgPSBXSU5fRmluZFduZFB0ciggaHduZCApOwogICAgY2hhciBidWZmZXJbMjU2XTsKCiAgICBpZiAod25kUHRyLT5kd0V4U3R5bGUgJiBXU19FWF9NQU5BR0VEKQogICAgewogICAgICAgIFdJTl9SZWxlYXNlV25kUHRyKHduZFB0cik7CiAgICAgICAgcmV0dXJuOwogICAgfQoKICAgIGlmICghaGJpdG1hcENsb3NlKQogICAgewoJaWYgKCEoaGJpdG1hcENsb3NlID0gTG9hZEJpdG1hcEEoIDAsIE1BS0VJTlRSRVNPVVJDRUEoT0JNX0NMT1NFKSApKSkKICAgICAgICB7CiAgICAgICAgICAgIFdJTl9SZWxlYXNlV25kUHRyKHduZFB0cik7CgkgICAgcmV0dXJuOwogICAgICAgIH0KCWhiaXRtYXBDbG9zZUQgICAgPSBMb2FkQml0bWFwQSggMCwgTUFLRUlOVFJFU09VUkNFQShPQk1fQ0xPU0VEKSApOwoJaGJpdG1hcE1pbmltaXplICA9IExvYWRCaXRtYXBBKCAwLCBNQUtFSU5UUkVTT1VSQ0VBKE9CTV9SRURVQ0UpICk7CgloYml0bWFwTWluaW1pemVEID0gTG9hZEJpdG1hcEEoIDAsIE1BS0VJTlRSRVNPVVJDRUEoT0JNX1JFRFVDRUQpICk7CgloYml0bWFwTWF4aW1pemUgID0gTG9hZEJpdG1hcEEoIDAsIE1BS0VJTlRSRVNPVVJDRUEoT0JNX1pPT00pICk7CgloYml0bWFwTWF4aW1pemVEID0gTG9hZEJpdG1hcEEoIDAsIE1BS0VJTlRSRVNPVVJDRUEoT0JNX1pPT01EKSApOwoJaGJpdG1hcFJlc3RvcmUgICA9IExvYWRCaXRtYXBBKCAwLCBNQUtFSU5UUkVTT1VSQ0VBKE9CTV9SRVNUT1JFKSApOwoJaGJpdG1hcFJlc3RvcmVEICA9IExvYWRCaXRtYXBBKCAwLCBNQUtFSU5UUkVTT1VSQ0VBKE9CTV9SRVNUT1JFRCkgKTsKICAgIH0KICAgIAogICAgaWYgKHduZFB0ci0+ZHdFeFN0eWxlICYgV1NfRVhfRExHTU9EQUxGUkFNRSkKICAgIHsKICAgICAgICBIQlJVU0ggaGJydXNoT2xkID0gU2VsZWN0T2JqZWN0KGhkYywgR2V0U3lzQ29sb3JCcnVzaChDT0xPUl9XSU5ET1cpICk7CglQYXRCbHQoIGhkYywgci5sZWZ0LCByLnRvcCwgMSwgci5ib3R0b20tci50b3ArMSxQQVRDT1BZICk7CglQYXRCbHQoIGhkYywgci5yaWdodC0xLCByLnRvcCwgMSwgci5ib3R0b20tci50b3ArMSwgUEFUQ09QWSApOwoJUGF0Qmx0KCBoZGMsIHIubGVmdCwgci50b3AtMSwgci5yaWdodC1yLmxlZnQsIDEsIFBBVENPUFkgKTsKCXIubGVmdCsrOwoJci5yaWdodC0tOwoJU2VsZWN0T2JqZWN0KCBoZGMsIGhicnVzaE9sZCApOwogICAgfQogICAgV0lOX1JlbGVhc2VXbmRQdHIod25kUHRyKTsKICAgIE1vdmVUb0V4KCBoZGMsIHIubGVmdCwgci5ib3R0b20sIE5VTEwgKTsKICAgIExpbmVUbyggaGRjLCByLnJpZ2h0LCByLmJvdHRvbSApOwoKICAgIGlmIChzdHlsZSAmIFdTX1NZU01FTlUpCiAgICB7CglOQ19EcmF3U3lzQnV0dG9uKCBod25kLCBoZGMsIEZBTFNFICk7CglyLmxlZnQgKz0gR2V0U3lzdGVtTWV0cmljcyhTTV9DWFNJWkUpICsgMTsKCU1vdmVUb0V4KCBoZGMsIHIubGVmdCAtIDEsIHIudG9wLCBOVUxMICk7CglMaW5lVG8oIGhkYywgci5sZWZ0IC0gMSwgci5ib3R0b20gKTsKICAgIH0KICAgIGlmIChzdHlsZSAmIFdTX01BWElNSVpFQk9YKQogICAgewoJTkNfRHJhd01heEJ1dHRvbiggaHduZCwgaGRjLCBGQUxTRSApOwoJci5yaWdodCAtPSBHZXRTeXN0ZW1NZXRyaWNzKFNNX0NYU0laRSkgKyAxOwogICAgfQogICAgaWYgKHN0eWxlICYgV1NfTUlOSU1JWkVCT1gpCiAgICB7CglOQ19EcmF3TWluQnV0dG9uKCBod25kLCBoZGMsIEZBTFNFICk7CglyLnJpZ2h0IC09IEdldFN5c3RlbU1ldHJpY3MoU01fQ1hTSVpFKSArIDE7CiAgICB9CgogICAgRmlsbFJlY3QoIGhkYywgJnIsIEdldFN5c0NvbG9yQnJ1c2goYWN0aXZlID8gQ09MT1JfQUNUSVZFQ0FQVElPTiA6CgkJCQkJICAgIENPTE9SX0lOQUNUSVZFQ0FQVElPTikgKTsKCiAgICBpZiAoR2V0V2luZG93VGV4dEEoIGh3bmQsIGJ1ZmZlciwgc2l6ZW9mKGJ1ZmZlcikgKSkKICAgIHsKCWlmIChhY3RpdmUpIFNldFRleHRDb2xvciggaGRjLCBHZXRTeXNDb2xvciggQ09MT1JfQ0FQVElPTlRFWFQgKSApOwoJZWxzZSBTZXRUZXh0Q29sb3IoIGhkYywgR2V0U3lzQ29sb3IoIENPTE9SX0lOQUNUSVZFQ0FQVElPTlRFWFQgKSApOwoJU2V0QmtNb2RlKCBoZGMsIFRSQU5TUEFSRU5UICk7CglEcmF3VGV4dEEoIGhkYywgYnVmZmVyLCAtMSwgJnIsCiAgICAgICAgICAgICAgICAgICAgIERUX1NJTkdMRUxJTkUgfCBEVF9DRU5URVIgfCBEVF9WQ0VOVEVSIHwgRFRfTk9QUkVGSVggKTsKICAgIH0KfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoKICogICBOQ19EcmF3Q2FwdGlvbjk1KAogKiAgICAgIEhEQyAgaGRjLAogKiAgICAgIFJFQ1QgKnJlY3QsCiAqICAgICAgSFdORCBod25kLAogKiAgICAgIERXT1JEICBzdHlsZSwKICogICAgICBCT09MIGFjdGl2ZSApCiAqCiAqICAgRHJhdyB0aGUgd2luZG93IGNhcHRpb24gZm9yIFdpbjk1IHN0eWxlIHdpbmRvd3MuCiAqICAgVGhlIGNvcnJlY3QgcGVuIGZvciB0aGUgd2luZG93IGZyYW1lIG11c3QgYmUgc2VsZWN0ZWQgaW4gdGhlIERDLgogKgogKiAgIEJ1Z3MKICogICAgICAgIEhleSwgYSBmdW5jdGlvbiB0aGF0IGZpbmFsbHkgd29ya3MhICBXZWxsLCBhbG1vc3QuCiAqICAgICAgICBJdCdzIGJlaW5nIHdvcmtlZCBvbi4KICoKICogICBSZXZpc2lvbiBoaXN0b3J5CiAqICAgICAgICAwNS1KdWwtMTk5NyBEYXZlIEN1dGhiZXJ0IChkYWN1dEBlY2UuY211LmVkdSkKICogICAgICAgICAgICAgT3JpZ2luYWwgaW1wbGVtZW50YXRpb24uCiAqICAgICAgICAwMi1KdW4tMTk5OCBFcmljIEtvaGwgKGVrb2hsQGFiby5yaGVpbi16ZWl0dW5nLmRlKQogKiAgICAgICAgICAgICBTb21lIG1pbm9yIGZpeGVzLgogKgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCgpzdGF0aWMgdm9pZCAgTkNfRHJhd0NhcHRpb245NSgKICAgIEhEQyAgaGRjLAogICAgUkVDVCAqcmVjdCwKICAgIEhXTkQgaHduZCwKICAgIERXT1JEICBzdHlsZSwKICAgIERXT1JEICBleFN0eWxlLAogICAgQk9PTCBhY3RpdmUgKQp7CiAgICBSRUNUICByID0gKnJlY3Q7CiAgICBXTkQgICAgICp3bmRQdHIgPSBXSU5fRmluZFduZFB0ciggaHduZCApOwogICAgY2hhciAgICBidWZmZXJbMjU2XTsKICAgIEhQRU4gIGhQcmV2UGVuOwogICAgSE1FTlUgaFN5c01lbnU7CgogICAgaWYgKHduZFB0ci0+ZHdFeFN0eWxlICYgV1NfRVhfTUFOQUdFRCkKICAgIHsKICAgICAgICBXSU5fUmVsZWFzZVduZFB0cih3bmRQdHIpOwogICAgICAgIHJldHVybjsKICAgIH0KICAgIFdJTl9SZWxlYXNlV25kUHRyKHduZFB0cik7CgogICAgaFByZXZQZW4gPSBTZWxlY3RPYmplY3QoIGhkYywgR2V0U3lzQ29sb3JQZW4oQ09MT1JfM0RGQUNFKSApOwogICAgTW92ZVRvRXgoIGhkYywgci5sZWZ0LCByLmJvdHRvbSAtIDEsIE5VTEwgKTsKICAgIExpbmVUbyggaGRjLCByLnJpZ2h0LCByLmJvdHRvbSAtIDEgKTsKICAgIFNlbGVjdE9iamVjdCggaGRjLCBoUHJldlBlbiApOwogICAgci5ib3R0b20tLTsKCiAgICBGaWxsUmVjdCggaGRjLCAmciwgR2V0U3lzQ29sb3JCcnVzaChhY3RpdmUgPyBDT0xPUl9BQ1RJVkVDQVBUSU9OIDoKCQkJCQkgICAgQ09MT1JfSU5BQ1RJVkVDQVBUSU9OKSApOwoKICAgIGlmICghaGJpdG1hcENsb3NlKSB7CglpZiAoIShoYml0bWFwQ2xvc2UgPSBMb2FkQml0bWFwQSggMCwgTUFLRUlOVFJFU09VUkNFQShPQk1fQ0xPU0UpICkpKQoJICAgIHJldHVybjsKICAgICAgICBoYml0bWFwQ2xvc2VEID0gTG9hZEJpdG1hcEEoIDAsIE1BS0VJTlRSRVNPVVJDRUEoT0JNX0NMT1NFRCkpOwoJaGJpdG1hcE1pbmltaXplICA9IExvYWRCaXRtYXBBKCAwLCBNQUtFSU5UUkVTT1VSQ0VBKE9CTV9SRURVQ0UpICk7CgloYml0bWFwTWluaW1pemVEID0gTG9hZEJpdG1hcEEoIDAsIE1BS0VJTlRSRVNPVVJDRUEoT0JNX1JFRFVDRUQpICk7CgloYml0bWFwTWF4aW1pemUgID0gTG9hZEJpdG1hcEEoIDAsIE1BS0VJTlRSRVNPVVJDRUEoT0JNX1pPT00pICk7CgloYml0bWFwTWF4aW1pemVEID0gTG9hZEJpdG1hcEEoIDAsIE1BS0VJTlRSRVNPVVJDRUEoT0JNX1pPT01EKSApOwoJaGJpdG1hcFJlc3RvcmUgICA9IExvYWRCaXRtYXBBKCAwLCBNQUtFSU5UUkVTT1VSQ0VBKE9CTV9SRVNUT1JFKSApOwoJaGJpdG1hcFJlc3RvcmVEICA9IExvYWRCaXRtYXBBKCAwLCBNQUtFSU5UUkVTT1VSQ0VBKE9CTV9SRVNUT1JFRCkgKTsKICAgIH0KICAgIAogICAgaWYgKChzdHlsZSAmIFdTX1NZU01FTlUpICYmICEoZXhTdHlsZSAmIFdTX0VYX1RPT0xXSU5ET1cpKSB7CglpZiAoTkNfRHJhd1N5c0J1dHRvbjk1IChod25kLCBoZGMsIEZBTFNFKSkKCSAgICByLmxlZnQgKz0gR2V0U3lzdGVtTWV0cmljcyhTTV9DWUNBUFRJT04pIC0gMTsKICAgIH0KCiAgICBpZiAoc3R5bGUgJiBXU19TWVNNRU5VKSAKICAgIHsKCVVJTlQgc3RhdGU7CgoJLyogR28gZ2V0IHRoZSBzeXNtZW51ICovCgloU3lzTWVudSA9IEdldFN5c3RlbU1lbnUoaHduZCwgRkFMU0UpOwoJc3RhdGUgPSBHZXRNZW51U3RhdGUoaFN5c01lbnUsIFNDX0NMT1NFLCBNRl9CWUNPTU1BTkQpOwoKCS8qIERyYXcgYSBncmF5ZWQgY2xvc2UgYnV0dG9uIGlmIGRpc2FibGVkIGFuZCBhIG5vcm1hbCBvbmUgaWYgU0NfQ0xPU0UgaXMgbm90IHRoZXJlICovCglOQ19EcmF3Q2xvc2VCdXR0b245NSAoaHduZCwgaGRjLCBGQUxTRSwgCgkJCSAgICAgICgoKChzdGF0ZSAmIE1GX0RJU0FCTEVEKSB8fCAoc3RhdGUgJiBNRl9HUkFZRUQpKSkgJiYgKHN0YXRlICE9IDB4RkZGRkZGRkYpKSk7CglyLnJpZ2h0IC09IEdldFN5c3RlbU1ldHJpY3MoU01fQ1lDQVBUSU9OKSAtIDE7CgoJaWYgKChzdHlsZSAmIFdTX01BWElNSVpFQk9YKSB8fCAoc3R5bGUgJiBXU19NSU5JTUlaRUJPWCkpCgl7CgkgICAgLyogSW4gd2luOTUgdGhlIHR3byBidXR0b25zIGFyZSBhbHdheXMgdGhlcmUgKi8KCSAgICAvKiBCdXQgaWYgdGhlIG1lbnUgaXRlbSBpcyBub3QgaW4gdGhlIG1lbnUgdGhleSdyZSBkaXNhYmxlZCovCgoJICAgIE5DX0RyYXdNYXhCdXR0b245NSggaHduZCwgaGRjLCBGQUxTRSwgKCEoc3R5bGUgJiBXU19NQVhJTUlaRUJPWCkpKTsKCSAgICByLnJpZ2h0IC09IEdldFN5c3RlbU1ldHJpY3MoU01fQ1hTSVpFKSArIDE7CgkgICAgCgkgICAgTkNfRHJhd01pbkJ1dHRvbjk1KCBod25kLCBoZGMsIEZBTFNFLCAgKCEoc3R5bGUgJiBXU19NSU5JTUlaRUJPWCkpKTsKCSAgICByLnJpZ2h0IC09IEdldFN5c3RlbU1ldHJpY3MoU01fQ1hTSVpFKSArIDE7Cgl9CiAgICB9CgogICAgaWYgKEdldFdpbmRvd1RleHRBKCBod25kLCBidWZmZXIsIHNpemVvZihidWZmZXIpICkpIHsKCU5PTkNMSUVOVE1FVFJJQ1NBIG5jbG07CglIRk9OVCBoRm9udCwgaE9sZEZvbnQ7CgluY2xtLmNiU2l6ZSA9IHNpemVvZihOT05DTElFTlRNRVRSSUNTQSk7CglTeXN0ZW1QYXJhbWV0ZXJzSW5mb0EgKFNQSV9HRVROT05DTElFTlRNRVRSSUNTLCAwLCAmbmNsbSwgMCk7CglpZiAoZXhTdHlsZSAmIFdTX0VYX1RPT0xXSU5ET1cpCgkgICAgaEZvbnQgPSBDcmVhdGVGb250SW5kaXJlY3RBICgmbmNsbS5sZlNtQ2FwdGlvbkZvbnQpOwoJZWxzZQoJICAgIGhGb250ID0gQ3JlYXRlRm9udEluZGlyZWN0QSAoJm5jbG0ubGZDYXB0aW9uRm9udCk7CgloT2xkRm9udCA9IFNlbGVjdE9iamVjdCAoaGRjLCBoRm9udCk7CglpZiAoYWN0aXZlKSBTZXRUZXh0Q29sb3IoIGhkYywgR2V0U3lzQ29sb3IoIENPTE9SX0NBUFRJT05URVhUICkgKTsKCWVsc2UgU2V0VGV4dENvbG9yKCBoZGMsIEdldFN5c0NvbG9yKCBDT0xPUl9JTkFDVElWRUNBUFRJT05URVhUICkgKTsKCVNldEJrTW9kZSggaGRjLCBUUkFOU1BBUkVOVCApOwoJci5sZWZ0ICs9IDI7CglEcmF3VGV4dEEoIGhkYywgYnVmZmVyLCAtMSwgJnIsCgkJICAgICBEVF9TSU5HTEVMSU5FIHwgRFRfVkNFTlRFUiB8IERUX05PUFJFRklYIHwgRFRfTEVGVCApOwoJRGVsZXRlT2JqZWN0IChTZWxlY3RPYmplY3QgKGhkYywgaE9sZEZvbnQpKTsKICAgIH0KfQoKCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICAgICAgIE5DX0RvTkNQYWludAogKgogKiBQYWludCB0aGUgbm9uLWNsaWVudCBhcmVhLiBjbGlwIGlzIGN1cnJlbnRseSB1bnVzZWQuCiAqLwpzdGF0aWMgdm9pZCBOQ19Eb05DUGFpbnQoIFdORCogd25kUHRyLCBIUkdOIGNsaXAsIEJPT0wgc3VwcHJlc3NfbWVudXBhaW50ICkKewogICAgSERDIGhkYzsKICAgIFJFQ1QgcmVjdDsKICAgIEJPT0wgYWN0aXZlOwogICAgSFdORCBod25kID0gd25kUHRyLT5od25kU2VsZjsKCiAgICBpZiAoIHduZFB0ci0+ZHdTdHlsZSAmIFdTX01JTklNSVpFIHx8CgkhV0lOX0lzV2luZG93RHJhd2FibGUoIHduZFB0ciwgMCApKSByZXR1cm47IC8qIE5vdGhpbmcgdG8gZG8gKi8KCiAgICBhY3RpdmUgID0gd25kUHRyLT5mbGFncyAmIFdJTl9OQ0FDVElWQVRFRDsKCiAgICBUUkFDRSgiJTA0eCAlZFxuIiwgaHduZCwgYWN0aXZlICk7CgogICAgaWYgKCEoaGRjID0gR2V0RENFeCggaHduZCwgKGNsaXAgPiAxKSA/IGNsaXAgOiAwLCBEQ1hfVVNFU1RZTEUgfCBEQ1hfV0lORE9XIHwKCQkJICAgICAgKChjbGlwID4gMSkgPyAoRENYX0lOVEVSU0VDVFJHTiB8IERDWF9LRUVQQ0xJUFJHTik6IDApICkpKSByZXR1cm47CgogICAgaWYgKEV4Y2x1ZGVWaXNSZWN0MTYoIGhkYywgd25kUHRyLT5yZWN0Q2xpZW50LmxlZnQtd25kUHRyLT5yZWN0V2luZG93LmxlZnQsCgkJICAgICAgICB3bmRQdHItPnJlY3RDbGllbnQudG9wLXduZFB0ci0+cmVjdFdpbmRvdy50b3AsCgkJICAgICAgICB3bmRQdHItPnJlY3RDbGllbnQucmlnaHQtd25kUHRyLT5yZWN0V2luZG93LmxlZnQsCgkJICAgICAgICB3bmRQdHItPnJlY3RDbGllbnQuYm90dG9tLXduZFB0ci0+cmVjdFdpbmRvdy50b3AgKQoJPT0gTlVMTFJFR0lPTikKICAgIHsKCVJlbGVhc2VEQyggaHduZCwgaGRjICk7CglyZXR1cm47CiAgICB9CgogICAgcmVjdC50b3AgPSByZWN0LmxlZnQgPSAwOwogICAgcmVjdC5yaWdodCAgPSB3bmRQdHItPnJlY3RXaW5kb3cucmlnaHQgLSB3bmRQdHItPnJlY3RXaW5kb3cubGVmdDsKICAgIHJlY3QuYm90dG9tID0gd25kUHRyLT5yZWN0V2luZG93LmJvdHRvbSAtIHduZFB0ci0+cmVjdFdpbmRvdy50b3A7CgogICAgU2VsZWN0T2JqZWN0KCBoZGMsIEdldFN5c0NvbG9yUGVuKENPTE9SX1dJTkRPV0ZSQU1FKSApOwoKICAgIGlmICghKHduZFB0ci0+ZHdFeFN0eWxlICYgV1NfRVhfTUFOQUdFRCkpCiAgICB7CiAgICAgICAgaWYgKEhBU19BTllGUkFNRSggd25kUHRyLT5kd1N0eWxlLCB3bmRQdHItPmR3RXhTdHlsZSApKQoJewoJICAgIFNlbGVjdE9iamVjdCggaGRjLCBHZXRTdG9ja09iamVjdChOVUxMX0JSVVNIKSApOwogICAgICAgICAgICBSZWN0YW5nbGUoIGhkYywgMCwgMCwgcmVjdC5yaWdodCwgcmVjdC5ib3R0b20gKTsKICAgICAgICAgICAgSW5mbGF0ZVJlY3QoICZyZWN0LCAtMSwgLTEgKTsKICAgICAgICB9CgoJaWYgKEhBU19USElDS0ZSQU1FKCB3bmRQdHItPmR3U3R5bGUsIHduZFB0ci0+ZHdFeFN0eWxlICkpCiAgICAgICAgICAgIE5DX0RyYXdGcmFtZShoZGMsICZyZWN0LCBGQUxTRSwgYWN0aXZlICk7CgllbHNlIGlmIChIQVNfRExHRlJBTUUoIHduZFB0ci0+ZHdTdHlsZSwgd25kUHRyLT5kd0V4U3R5bGUgKSkgCiAgICAgICAgICAgIE5DX0RyYXdGcmFtZSggaGRjLCAmcmVjdCwgVFJVRSwgYWN0aXZlICk7CgogICAgICAgIGlmICgod25kUHRyLT5kd1N0eWxlICYgV1NfQ0FQVElPTikgPT0gV1NfQ0FQVElPTikKICAgICAgICB7CiAgICAgICAgICAgIFJFQ1QgciA9IHJlY3Q7CiAgICAgICAgICAgIHIuYm90dG9tID0gcmVjdC50b3AgKyBHZXRTeXN0ZW1NZXRyaWNzKFNNX0NZU0laRSk7CiAgICAgICAgICAgIHJlY3QudG9wICs9IEdldFN5c3RlbU1ldHJpY3MoU01fQ1lTSVpFKSArIEdldFN5c3RlbU1ldHJpY3MoU01fQ1lCT1JERVIpOwogICAgICAgICAgICBOQ19EcmF3Q2FwdGlvbiggaGRjLCAmciwgaHduZCwgd25kUHRyLT5kd1N0eWxlLCBhY3RpdmUgKTsKICAgICAgICB9CiAgICB9CgogICAgaWYgKEhBU19NRU5VKHduZFB0cikpCiAgICB7CglSRUNUIHIgPSByZWN0OwoJci5ib3R0b20gPSByZWN0LnRvcCArIEdldFN5c3RlbU1ldHJpY3MoU01fQ1lNRU5VKTsgIC8qIGRlZmF1bHQgaGVpZ2h0ICovCglyZWN0LnRvcCArPSBNRU5VX0RyYXdNZW51QmFyKCBoZGMsICZyLCBod25kLCBzdXBwcmVzc19tZW51cGFpbnQgKTsKICAgIH0KCiAgICAgIC8qIERyYXcgdGhlIHNjcm9sbC1iYXJzICovCgogICAgaWYgKHduZFB0ci0+ZHdTdHlsZSAmIFdTX1ZTQ1JPTEwpCiAgICAgICAgU0NST0xMX0RyYXdTY3JvbGxCYXIoIGh3bmQsIGhkYywgU0JfVkVSVCwgVFJVRSwgVFJVRSApOwogICAgaWYgKHduZFB0ci0+ZHdTdHlsZSAmIFdTX0hTQ1JPTEwpCiAgICAgICAgU0NST0xMX0RyYXdTY3JvbGxCYXIoIGh3bmQsIGhkYywgU0JfSE9SWiwgVFJVRSwgVFJVRSApOwoKICAgICAgLyogRHJhdyB0aGUgInNpemUtYm94IiAqLwoKICAgIGlmICgod25kUHRyLT5kd1N0eWxlICYgV1NfVlNDUk9MTCkgJiYgKHduZFB0ci0+ZHdTdHlsZSAmIFdTX0hTQ1JPTEwpKQogICAgewogICAgICAgIFJFQ1QgciA9IHJlY3Q7CiAgICAgICAgci5sZWZ0ID0gci5yaWdodCAtIEdldFN5c3RlbU1ldHJpY3MoU01fQ1hWU0NST0xMKSArIDE7CiAgICAgICAgci50b3AgID0gci5ib3R0b20gLSBHZXRTeXN0ZW1NZXRyaWNzKFNNX0NZSFNDUk9MTCkgKyAxOwoJaWYod25kUHRyLT5kd1N0eWxlICYgV1NfQk9SREVSKSB7CgkgIHIubGVmdCsrOwoJICByLnRvcCsrOwoJfQogICAgICAgIEZpbGxSZWN0KCBoZGMsICZyLCBHZXRTeXNDb2xvckJydXNoKENPTE9SX1NDUk9MTEJBUikgKTsKICAgIH0gICAgCgogICAgUmVsZWFzZURDKCBod25kLCBoZGMgKTsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoKICogICB2b2lkICBOQ19Eb05DUGFpbnQ5NSgKICogICAgICBXTkQgICp3bmRQdHIsCiAqICAgICAgSFJHTiAgY2xpcCwKICogICAgICBCT09MICBzdXBwcmVzc19tZW51cGFpbnQgKQogKgogKiAgIFBhaW50IHRoZSBub24tY2xpZW50IGFyZWEgZm9yIFdpbjk1IHdpbmRvd3MuICBUaGUgY2xpcCByZWdpb24gaXMKICogICBjdXJyZW50bHkgaWdub3JlZC4KICoKICogICBCdWdzCiAqICAgICAgICBncmVwIC1FIC1BMTAgLUI1IFwoOTVcKVx8XChCdWdzXClcfFwoRklYTUVcKSB3aW5kb3dzL25vbmNsaWVudC5jIFwKICogICAgICAgICAgIG1pc2MvdHdlYWsuYyBjb250cm9scy9tZW51LmMgICMgOi0pCiAqCiAqICAgUmV2aXNpb24gaGlzdG9yeQogKiAgICAgICAgMDMtSnVsLTE5OTcgRGF2ZSBDdXRoYmVydCAoZGFjdXRAZWNlLmNtdS5lZHUpCiAqICAgICAgICAgICAgIE9yaWdpbmFsIGltcGxlbWVudGF0aW9uCiAqICAgICAgICAxMC1KdW4tMTk5OCBFcmljIEtvaGwgKGVrb2hsQGFiby5yaGVpbi16ZWl0dW5nLmRlKQogKiAgICAgICAgICAgICBGaXhlZCBzb21lIGJ1Z3MuCiAqICAgICAgICAyOS1KdW4tMTk5OSBPdmUgS+V2ZW4gKG92ZWtAYXJjdGljbmV0Lm5vKQogKiAgICAgICAgICAgICBTdHJlYW1saW5lZCB3aW5kb3cgc3R5bGUgY2hlY2tzLgogKgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCgpzdGF0aWMgdm9pZCAgTkNfRG9OQ1BhaW50OTUoCiAgICBXTkQgICp3bmRQdHIsCiAgICBIUkdOICBjbGlwLAogICAgQk9PTCAgc3VwcHJlc3NfbWVudXBhaW50ICkKewogICAgSERDIGhkYzsKICAgIFJFQ1QgcmZ1enosIHJlY3QsIHJlY3RDbGlwOwogICAgQk9PTCBhY3RpdmU7CiAgICBIV05EIGh3bmQgPSB3bmRQdHItPmh3bmRTZWxmOwoKICAgIGlmICggd25kUHRyLT5kd1N0eWxlICYgV1NfTUlOSU1JWkUgfHwKCSFXSU5fSXNXaW5kb3dEcmF3YWJsZSggd25kUHRyLCAwICkpIHJldHVybjsgLyogTm90aGluZyB0byBkbyAqLwoKICAgIGFjdGl2ZSAgPSB3bmRQdHItPmZsYWdzICYgV0lOX05DQUNUSVZBVEVEOwoKICAgIFRSQUNFKCIlMDR4ICVkXG4iLCBod25kLCBhY3RpdmUgKTsKCiAgICAvKiBNU0ROIGRvY3MgYXJlIHByZXR0eSBpZGlvdGljIGhlcmUsIHRoZXkgc2F5IGFwcCBDQU4gdXNlIGNsaXBSZ24gaW4KICAgICAgIHRoZSBjYWxsIHRvIEdldERDRXggaW1wbHlpbmcgdGhhdCBpdCBpcyBhbGxvd2VkIG5vdCB0byB1c2UgaXQgZWl0aGVyLgogICAgICAgSG93ZXZlciwgdGhlIHN1Z2dlc3RlZCBHZXREQ0V4KCAgICAsIERDWF9XSU5ET1cgfCBEQ1hfSU5URVJTRUNUUkdOKQogICAgICAgd2lsbCBjYXVzZSBjbGlwUmduIHRvIGJlIGRlbGV0ZWQgYWZ0ZXIgUmVsZWFzZURDKCkuCiAgICAgICBOb3csIGhvdyBpcyB0aGUgInN5c3RlbSIgc3VwcG9zZWQgdG8gdGVsbCB3aGF0IGhhcHBlbmVkPwogICAgICovCgogICAgaWYgKCEoaGRjID0gR2V0RENFeCggaHduZCwgKGNsaXAgPiAxKSA/IGNsaXAgOiAwLCBEQ1hfVVNFU1RZTEUgfCBEQ1hfV0lORE9XIHwKCQkJICAgICAgKChjbGlwID4gMSkgPyhEQ1hfSU5URVJTRUNUUkdOIHwgRENYX0tFRVBDTElQUkdOKSA6IDApICkpKSByZXR1cm47CgoKICAgIGlmIChFeGNsdWRlVmlzUmVjdDE2KCBoZGMsIHduZFB0ci0+cmVjdENsaWVudC5sZWZ0LXduZFB0ci0+cmVjdFdpbmRvdy5sZWZ0LAoJCSAgICAgICAgd25kUHRyLT5yZWN0Q2xpZW50LnRvcC13bmRQdHItPnJlY3RXaW5kb3cudG9wLAoJCSAgICAgICAgd25kUHRyLT5yZWN0Q2xpZW50LnJpZ2h0LXduZFB0ci0+cmVjdFdpbmRvdy5sZWZ0LAoJCSAgICAgICAgd25kUHRyLT5yZWN0Q2xpZW50LmJvdHRvbS13bmRQdHItPnJlY3RXaW5kb3cudG9wICkKCT09IE5VTExSRUdJT04pCiAgICB7CglSZWxlYXNlREMoIGh3bmQsIGhkYyApOwoJcmV0dXJuOwogICAgfQoKICAgIHJlY3QudG9wID0gcmVjdC5sZWZ0ID0gMDsKICAgIHJlY3QucmlnaHQgID0gd25kUHRyLT5yZWN0V2luZG93LnJpZ2h0IC0gd25kUHRyLT5yZWN0V2luZG93LmxlZnQ7CiAgICByZWN0LmJvdHRvbSA9IHduZFB0ci0+cmVjdFdpbmRvdy5ib3R0b20gLSB3bmRQdHItPnJlY3RXaW5kb3cudG9wOwoKICAgIGlmKCBjbGlwID4gMSApCglHZXRSZ25Cb3goIGNsaXAsICZyZWN0Q2xpcCApOwogICAgZWxzZQogICAgewoJY2xpcCA9IDA7CglyZWN0Q2xpcCA9IHJlY3Q7CiAgICB9CgogICAgU2VsZWN0T2JqZWN0KCBoZGMsIEdldFN5c0NvbG9yUGVuKENPTE9SX1dJTkRPV0ZSQU1FKSApOwoKICAgIGlmKCEod25kUHRyLT5kd0V4U3R5bGUgJiBXU19FWF9NQU5BR0VEKSkgewogICAgICAgIGlmIChIQVNfQklHRlJBTUUoIHduZFB0ci0+ZHdTdHlsZSwgd25kUHRyLT5kd0V4U3R5bGUpKSB7CiAgICAgICAgICAgIERyYXdFZGdlIChoZGMsICZyZWN0LCBFREdFX1JBSVNFRCwgQkZfUkVDVCB8IEJGX0FESlVTVCk7CiAgICAgICAgfQoJaWYgKEhBU19USElDS0ZSQU1FKCB3bmRQdHItPmR3U3R5bGUsIHduZFB0ci0+ZHdFeFN0eWxlICkpCiAgICAgICAgICAgIE5DX0RyYXdGcmFtZTk1KGhkYywgJnJlY3QsIEZBTFNFLCBhY3RpdmUgKTsKICAgICAgICBlbHNlIGlmIChIQVNfRExHRlJBTUUoIHduZFB0ci0+ZHdTdHlsZSwgd25kUHRyLT5kd0V4U3R5bGUgKSkgCiAgICAgICAgICAgIE5DX0RyYXdGcmFtZTk1KCBoZGMsICZyZWN0LCBUUlVFLCBhY3RpdmUgKTsKCWVsc2UgaWYgKEhBU19USElORlJBTUUoIHduZFB0ci0+ZHdTdHlsZSApKSB7CiAgICAgICAgICAgIFNlbGVjdE9iamVjdCggaGRjLCBHZXRTdG9ja09iamVjdChOVUxMX0JSVVNIKSApOwogICAgICAgICAgICBSZWN0YW5nbGUoIGhkYywgMCwgMCwgcmVjdC5yaWdodCwgcmVjdC5ib3R0b20gKTsKCX0KCiAgICAgICAgaWYgKCh3bmRQdHItPmR3U3R5bGUgJiBXU19DQVBUSU9OKSA9PSBXU19DQVBUSU9OKQogICAgICAgIHsKICAgICAgICAgICAgUkVDVCAgciA9IHJlY3Q7CgkgICAgaWYgKHduZFB0ci0+ZHdFeFN0eWxlICYgV1NfRVhfVE9PTFdJTkRPVykgewoJCXIuYm90dG9tID0gcmVjdC50b3AgKyBHZXRTeXN0ZW1NZXRyaWNzKFNNX0NZU01DQVBUSU9OKTsKCQlyZWN0LnRvcCArPSBHZXRTeXN0ZW1NZXRyaWNzKFNNX0NZU01DQVBUSU9OKTsKCSAgICB9CgkgICAgZWxzZSB7CgkJci5ib3R0b20gPSByZWN0LnRvcCArIEdldFN5c3RlbU1ldHJpY3MoU01fQ1lDQVBUSU9OKTsKCQlyZWN0LnRvcCArPSBHZXRTeXN0ZW1NZXRyaWNzKFNNX0NZQ0FQVElPTik7CgkgICAgfQoJICAgIGlmKCAhY2xpcCB8fCBJbnRlcnNlY3RSZWN0KCAmcmZ1enosICZyLCAmcmVjdENsaXAgKSApCiAgICAgICAgICAgICAgICBOQ19EcmF3Q2FwdGlvbjk1IChoZGMsICZyLCBod25kLCB3bmRQdHItPmR3U3R5bGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB3bmRQdHItPmR3RXhTdHlsZSwgYWN0aXZlKTsKICAgICAgICB9CiAgICB9CgogICAgaWYgKEhBU19NRU5VKHduZFB0cikpCiAgICB7CglSRUNUIHIgPSByZWN0OwoJci5ib3R0b20gPSByZWN0LnRvcCArIEdldFN5c3RlbU1ldHJpY3MoU01fQ1lNRU5VKTsKCQoJVFJBQ0UoIkNhbGxpbmcgRHJhd01lbnVCYXIgd2l0aCByZWN0ICglZCwgJWQpLSglZCwgJWQpXG4iLAogICAgICAgICAgICAgIHIubGVmdCwgci50b3AsIHIucmlnaHQsIHIuYm90dG9tKTsKCglyZWN0LnRvcCArPSBNRU5VX0RyYXdNZW51QmFyKCBoZGMsICZyLCBod25kLCBzdXBwcmVzc19tZW51cGFpbnQgKSArIDE7CiAgICB9CgogICAgVFJBQ0UoIkFmdGVyIE1lbnVCYXIsIHJlY3QgaXMgKCVkLCAlZCktKCVkLCAlZCkuXG4iLAogICAgICAgICAgcmVjdC5sZWZ0LCByZWN0LnRvcCwgcmVjdC5yaWdodCwgcmVjdC5ib3R0b20gKTsKCiAgICBpZiAod25kUHRyLT5kd0V4U3R5bGUgJiBXU19FWF9DTElFTlRFREdFKQoJRHJhd0VkZ2UgKGhkYywgJnJlY3QsIEVER0VfU1VOS0VOLCBCRl9SRUNUIHwgQkZfQURKVVNUKTsKCiAgICBpZiAod25kUHRyLT5kd0V4U3R5bGUgJiBXU19FWF9TVEFUSUNFREdFKQoJRHJhd0VkZ2UgKGhkYywgJnJlY3QsIEJEUl9TVU5LRU5PVVRFUiwgQkZfUkVDVCB8IEJGX0FESlVTVCk7CgogICAgLyogRHJhdyB0aGUgc2Nyb2xsLWJhcnMgKi8KCiAgICBpZiAod25kUHRyLT5kd1N0eWxlICYgV1NfVlNDUk9MTCkKICAgICAgICBTQ1JPTExfRHJhd1Njcm9sbEJhciggaHduZCwgaGRjLCBTQl9WRVJULCBUUlVFLCBUUlVFICk7CiAgICBpZiAod25kUHRyLT5kd1N0eWxlICYgV1NfSFNDUk9MTCkKICAgICAgICBTQ1JPTExfRHJhd1Njcm9sbEJhciggaHduZCwgaGRjLCBTQl9IT1JaLCBUUlVFLCBUUlVFICk7CgogICAgLyogRHJhdyB0aGUgInNpemUtYm94IiAqLwogICAgaWYgKCh3bmRQdHItPmR3U3R5bGUgJiBXU19WU0NST0xMKSAmJiAod25kUHRyLT5kd1N0eWxlICYgV1NfSFNDUk9MTCkpCiAgICB7CiAgICAgICAgUkVDVCByID0gcmVjdDsKICAgICAgICByLmxlZnQgPSByLnJpZ2h0IC0gR2V0U3lzdGVtTWV0cmljcyhTTV9DWFZTQ1JPTEwpICsgMTsKICAgICAgICByLnRvcCAgPSByLmJvdHRvbSAtIEdldFN5c3RlbU1ldHJpY3MoU01fQ1lIU0NST0xMKSArIDE7CiAgICAgICAgRmlsbFJlY3QoIGhkYywgJnIsICBHZXRTeXNDb2xvckJydXNoKENPTE9SX1NDUk9MTEJBUikgKTsKICAgIH0gICAgCgogICAgUmVsZWFzZURDKCBod25kLCBoZGMgKTsKfQoKCgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgICAgICBOQ19IYW5kbGVOQ1BhaW50CiAqCiAqIEhhbmRsZSBhIFdNX05DUEFJTlQgbWVzc2FnZS4gQ2FsbGVkIGZyb20gRGVmV2luZG93UHJvYygpLgogKi8KTE9ORyBOQ19IYW5kbGVOQ1BhaW50KCBIV05EIGh3bmQgLCBIUkdOIGNsaXApCnsKICAgIFdORCogd25kUHRyID0gV0lOX0ZpbmRXbmRQdHIoIGh3bmQgKTsKCiAgICBpZiggd25kUHRyICYmIHduZFB0ci0+ZHdTdHlsZSAmIFdTX1ZJU0lCTEUgKQogICAgewoJaWYoIHduZFB0ci0+ZHdTdHlsZSAmIFdTX01JTklNSVpFICkKCSAgICBXSU5QT1NfUmVkcmF3SWNvblRpdGxlKCBod25kICk7CgllbHNlIGlmIChUV0VBS19XaW5lTG9vayA9PSBXSU4zMV9MT09LKQoJICAgIE5DX0RvTkNQYWludCggd25kUHRyLCBjbGlwLCBGQUxTRSApOwoJZWxzZQoJICAgIE5DX0RvTkNQYWludDk1KCB3bmRQdHIsIGNsaXAsIEZBTFNFICk7CiAgICB9CiAgICBXSU5fUmVsZWFzZVduZFB0cih3bmRQdHIpOwogICAgcmV0dXJuIDA7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICAgICAgIE5DX0hhbmRsZU5DQWN0aXZhdGUKICoKICogSGFuZGxlIGEgV01fTkNBQ1RJVkFURSBtZXNzYWdlLiBDYWxsZWQgZnJvbSBEZWZXaW5kb3dQcm9jKCkuCiAqLwpMT05HIE5DX0hhbmRsZU5DQWN0aXZhdGUoIFdORCAqd25kUHRyLCBXUEFSQU0xNiB3UGFyYW0gKQp7CiAgICBXT1JEIHdTdGF0ZUNoYW5nZTsKCiAgICBpZiggd1BhcmFtICkgd1N0YXRlQ2hhbmdlID0gISh3bmRQdHItPmZsYWdzICYgV0lOX05DQUNUSVZBVEVEKTsKICAgIGVsc2Ugd1N0YXRlQ2hhbmdlID0gd25kUHRyLT5mbGFncyAmIFdJTl9OQ0FDVElWQVRFRDsKCiAgICBpZiggd1N0YXRlQ2hhbmdlICkKICAgIHsKCWlmICh3UGFyYW0pIHduZFB0ci0+ZmxhZ3MgfD0gV0lOX05DQUNUSVZBVEVEOwoJZWxzZSB3bmRQdHItPmZsYWdzICY9IH5XSU5fTkNBQ1RJVkFURUQ7CgoJaWYoIHduZFB0ci0+ZHdTdHlsZSAmIFdTX01JTklNSVpFICkgCgkgICAgV0lOUE9TX1JlZHJhd0ljb25UaXRsZSggd25kUHRyLT5od25kU2VsZiApOwoJZWxzZSBpZiAoVFdFQUtfV2luZUxvb2sgPT0gV0lOMzFfTE9PSykKCSAgICBOQ19Eb05DUGFpbnQoIHduZFB0ciwgKEhSR04pMSwgRkFMU0UgKTsKCWVsc2UKCSAgICBOQ19Eb05DUGFpbnQ5NSggd25kUHRyLCAoSFJHTikxLCBGQUxTRSApOwogICAgfQogICAgcmV0dXJuIFRSVUU7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICAgICAgIE5DX0hhbmRsZVNldEN1cnNvcgogKgogKiBIYW5kbGUgYSBXTV9TRVRDVVJTT1IgbWVzc2FnZS4gQ2FsbGVkIGZyb20gRGVmV2luZG93UHJvYygpLgogKi8KTE9ORyBOQ19IYW5kbGVTZXRDdXJzb3IoIEhXTkQgaHduZCwgV1BBUkFNMTYgd1BhcmFtLCBMUEFSQU0gbFBhcmFtICkKewogICAgaWYgKGh3bmQgIT0gKEhXTkQpd1BhcmFtKSByZXR1cm4gMDsgIC8qIERvbid0IHNldCB0aGUgY3Vyc29yIGZvciBjaGlsZCB3aW5kb3dzICovCgogICAgc3dpdGNoKExPV09SRChsUGFyYW0pKQogICAgewogICAgY2FzZSBIVEVSUk9SOgoJewoJICAgIFdPUkQgbXNnID0gSElXT1JEKCBsUGFyYW0gKTsKCSAgICBpZiAoKG1zZyA9PSBXTV9MQlVUVE9ORE9XTikgfHwgKG1zZyA9PSBXTV9NQlVUVE9ORE9XTikgfHwKCQkobXNnID09IFdNX1JCVVRUT05ET1dOKSkKCQlNZXNzYWdlQmVlcCgwKTsKCX0KCWJyZWFrOwoKICAgIGNhc2UgSFRDTElFTlQ6Cgl7CgkgICAgSElDT04xNiBoQ3Vyc29yID0gKEhJQ09OMTYpIEdldENsYXNzV29yZChod25kLCBHQ1dfSENVUlNPUik7CgkgICAgaWYoaEN1cnNvcikgewoJCVNldEN1cnNvcjE2KGhDdXJzb3IpOwoJCXJldHVybiBUUlVFOwoJICAgIH0KICAgICAgICAgICAgcmV0dXJuIEZBTFNFOwoJfQoKICAgIGNhc2UgSFRMRUZUOgogICAgY2FzZSBIVFJJR0hUOgoJcmV0dXJuIChMT05HKVNldEN1cnNvciggTG9hZEN1cnNvckEoIDAsIElEQ19TSVpFV0VBICkgKTsKCiAgICBjYXNlIEhUVE9QOgogICAgY2FzZSBIVEJPVFRPTToKCXJldHVybiAoTE9ORylTZXRDdXJzb3IoIExvYWRDdXJzb3JBKCAwLCBJRENfU0laRU5TQSApICk7CgogICAgY2FzZSBIVFRPUExFRlQ6CiAgICBjYXNlIEhUQk9UVE9NUklHSFQ6CQoJcmV0dXJuIChMT05HKVNldEN1cnNvciggTG9hZEN1cnNvckEoIDAsIElEQ19TSVpFTldTRUEgKSApOwoKICAgIGNhc2UgSFRUT1BSSUdIVDoKICAgIGNhc2UgSFRCT1RUT01MRUZUOgoJcmV0dXJuIChMT05HKVNldEN1cnNvciggTG9hZEN1cnNvckEoIDAsIElEQ19TSVpFTkVTV0EgKSApOwogICAgfQoKICAgIC8qIERlZmF1bHQgY3Vyc29yOiBhcnJvdyAqLwogICAgcmV0dXJuIChMT05HKVNldEN1cnNvciggTG9hZEN1cnNvckEoIDAsIElEQ19BUlJPV0EgKSApOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICAgICAgIE5DX0dldFN5c1BvcHVwUG9zCiAqLwpCT09MIE5DX0dldFN5c1BvcHVwUG9zKCBXTkQqIHduZFB0ciwgUkVDVCogcmVjdCApCnsKICBpZiggd25kUHRyLT5oU3lzTWVudSApCiAgewogICAgICBpZiggd25kUHRyLT5kd1N0eWxlICYgV1NfTUlOSU1JWkUgKQoJICBHZXRXaW5kb3dSZWN0KCB3bmRQdHItPmh3bmRTZWxmLCByZWN0ICk7CiAgICAgIGVsc2UKICAgICAgewogICAgICAgICAgaWYgKFRXRUFLX1dpbmVMb29rID09IFdJTjMxX0xPT0spCiAgICAgICAgICAgICAgTkNfR2V0SW5zaWRlUmVjdCggd25kUHRyLT5od25kU2VsZiwgcmVjdCApOwogICAgICAgICAgZWxzZQogICAgICAgICAgICAgIE5DX0dldEluc2lkZVJlY3Q5NSggd25kUHRyLT5od25kU2VsZiwgcmVjdCApOwogIAkgIE9mZnNldFJlY3QoIHJlY3QsIHduZFB0ci0+cmVjdFdpbmRvdy5sZWZ0LCB3bmRQdHItPnJlY3RXaW5kb3cudG9wKTsKICAJICBpZiAod25kUHRyLT5kd1N0eWxlICYgV1NfQ0hJTEQpCiAgICAgCSAgICAgIENsaWVudFRvU2NyZWVuKCB3bmRQdHItPnBhcmVudC0+aHduZFNlbGYsIChQT0lOVCAqKXJlY3QgKTsKICAgICAgICAgIGlmIChUV0VBS19XaW5lTG9vayA9PSBXSU4zMV9MT09LKSB7CiAgICAgICAgICAgIHJlY3QtPnJpZ2h0ID0gcmVjdC0+bGVmdCArIEdldFN5c3RlbU1ldHJpY3MoU01fQ1hTSVpFKTsKICAgICAgICAgICAgcmVjdC0+Ym90dG9tID0gcmVjdC0+dG9wICsgR2V0U3lzdGVtTWV0cmljcyhTTV9DWVNJWkUpOwoJICB9CgkgIGVsc2UgewogICAgICAgICAgICByZWN0LT5yaWdodCA9IHJlY3QtPmxlZnQgKyBHZXRTeXN0ZW1NZXRyaWNzKFNNX0NZQ0FQVElPTikgLSAxOwogICAgICAgICAgICByZWN0LT5ib3R0b20gPSByZWN0LT50b3AgKyBHZXRTeXN0ZW1NZXRyaWNzKFNNX0NZQ0FQVElPTikgLSAxOwoJICB9CiAgICAgIH0KICAgICAgcmV0dXJuIFRSVUU7CiAgfQogIHJldHVybiBGQUxTRTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgICAgICBOQ19TdGFydFNpemVNb3ZlCiAqCiAqIEluaXRpYWxpc2F0aW9uIG9mIGEgbW92ZSBvciByZXNpemUsIHdoZW4gaW5pdGlhdGllZCBmcm9tIGEgbWVudSBjaG9pY2UuCiAqIFJldHVybiBoaXQgdGVzdCBjb2RlIGZvciBjYXB0aW9uIG9yIHNpemluZyBib3JkZXIuCiAqLwpzdGF0aWMgTE9ORyBOQ19TdGFydFNpemVNb3ZlKCBXTkQqIHduZFB0ciwgV1BBUkFNMTYgd1BhcmFtLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBQT0lOVCAqY2FwdHVyZVBvaW50ICkKewogICAgTE9ORyBoaXR0ZXN0ID0gMDsKICAgIFBPSU5UIHB0OwogICAgTVNHIG1zZzsKICAgIFJFQ1QgcmVjdFdpbmRvdzsKCiAgICBHZXRXaW5kb3dSZWN0KHduZFB0ci0+aHduZFNlbGYsJnJlY3RXaW5kb3cpOwoKICAgIGlmICgod1BhcmFtICYgMHhmZmYwKSA9PSBTQ19NT1ZFKQogICAgewoJICAvKiBNb3ZlIHBvaW50ZXIgYXQgdGhlIGNlbnRlciBvZiB0aGUgY2FwdGlvbiAqLwoJUkVDVCByZWN0OwogICAgICAgIGlmIChUV0VBS19XaW5lTG9vayA9PSBXSU4zMV9MT09LKQogICAgICAgICAgICBOQ19HZXRJbnNpZGVSZWN0KCB3bmRQdHItPmh3bmRTZWxmLCAmcmVjdCApOwogICAgICAgIGVsc2UKICAgICAgICAgICAgTkNfR2V0SW5zaWRlUmVjdDk1KCB3bmRQdHItPmh3bmRTZWxmLCAmcmVjdCApOwoJaWYgKHduZFB0ci0+ZHdTdHlsZSAmIFdTX1NZU01FTlUpCgkgICAgcmVjdC5sZWZ0ICs9IEdldFN5c3RlbU1ldHJpY3MoU01fQ1hTSVpFKSArIDE7CglpZiAod25kUHRyLT5kd1N0eWxlICYgV1NfTUlOSU1JWkVCT1gpCgkgICAgcmVjdC5yaWdodCAtPSBHZXRTeXN0ZW1NZXRyaWNzKFNNX0NYU0laRSkgKyAxOwoJaWYgKHduZFB0ci0+ZHdTdHlsZSAmIFdTX01BWElNSVpFQk9YKQoJICAgIHJlY3QucmlnaHQgLT0gR2V0U3lzdGVtTWV0cmljcyhTTV9DWFNJWkUpICsgMTsKCXB0LnggPSByZWN0V2luZG93LmxlZnQgKyAocmVjdC5yaWdodCAtIHJlY3QubGVmdCkgLyAyOwoJcHQueSA9IHJlY3RXaW5kb3cudG9wICsgcmVjdC50b3AgKyBHZXRTeXN0ZW1NZXRyaWNzKFNNX0NZU0laRSkvMjsKCWhpdHRlc3QgPSBIVENBUFRJT047CgkqY2FwdHVyZVBvaW50ID0gcHQ7CiAgICB9CiAgICBlbHNlICAvKiBTQ19TSVpFICovCiAgICB7Cgl3aGlsZSghaGl0dGVzdCkKCXsKICAgICAgICAgICAgTVNHX0ludGVybmFsR2V0TWVzc2FnZSggUU1TR19XSU4zMkEsICZtc2csIDAsIDAsIE1TR0ZfU0laRSwgUE1fUkVNT1ZFLCBGQUxTRSwgTlVMTCApOwoJICAgIHN3aXRjaChtc2cubWVzc2FnZSkKCSAgICB7CgkgICAgY2FzZSBXTV9NT1VTRU1PVkU6CiAgICAgICAgICAgICAgICBoaXR0ZXN0ID0gTkNfSGFuZGxlTkNIaXRUZXN0KCB3bmRQdHItPmh3bmRTZWxmLCBtc2cucHQgKTsKCQlpZiAoKGhpdHRlc3QgPCBIVExFRlQpIHx8IChoaXR0ZXN0ID4gSFRCT1RUT01SSUdIVCkpCgkJICAgIGhpdHRlc3QgPSAwOwoJCWJyZWFrOwoKCSAgICBjYXNlIFdNX0xCVVRUT05VUDoKCQlyZXR1cm4gMDsKCgkgICAgY2FzZSBXTV9LRVlET1dOOgoJCXN3aXRjaChtc2cud1BhcmFtKQoJCXsKCQljYXNlIFZLX1VQOgoJCSAgICBoaXR0ZXN0ID0gSFRUT1A7CgkJICAgIHB0LnggPShyZWN0V2luZG93LmxlZnQrcmVjdFdpbmRvdy5yaWdodCkvMjsKCQkgICAgcHQueSA9IHJlY3RXaW5kb3cudG9wICsgR2V0U3lzdGVtTWV0cmljcyhTTV9DWUZSQU1FKSAvIDI7CgkJICAgIGJyZWFrOwoJCWNhc2UgVktfRE9XTjoKCQkgICAgaGl0dGVzdCA9IEhUQk9UVE9NOwoJCSAgICBwdC54ID0ocmVjdFdpbmRvdy5sZWZ0K3JlY3RXaW5kb3cucmlnaHQpLzI7CgkJICAgIHB0LnkgPSByZWN0V2luZG93LmJvdHRvbSAtIEdldFN5c3RlbU1ldHJpY3MoU01fQ1lGUkFNRSkgLyAyOwoJCSAgICBicmVhazsKCQljYXNlIFZLX0xFRlQ6CgkJICAgIGhpdHRlc3QgPSBIVExFRlQ7CgkJICAgIHB0LnggPSByZWN0V2luZG93LmxlZnQgKyBHZXRTeXN0ZW1NZXRyaWNzKFNNX0NYRlJBTUUpIC8gMjsKCQkgICAgcHQueSA9KHJlY3RXaW5kb3cudG9wK3JlY3RXaW5kb3cuYm90dG9tKS8yOwoJCSAgICBicmVhazsKCQljYXNlIFZLX1JJR0hUOgoJCSAgICBoaXR0ZXN0ID0gSFRSSUdIVDsKCQkgICAgcHQueCA9IHJlY3RXaW5kb3cucmlnaHQgLSBHZXRTeXN0ZW1NZXRyaWNzKFNNX0NYRlJBTUUpIC8gMjsKCQkgICAgcHQueSA9KHJlY3RXaW5kb3cudG9wK3JlY3RXaW5kb3cuYm90dG9tKS8yOwoJCSAgICBicmVhazsKCQljYXNlIFZLX1JFVFVSTjoKCQljYXNlIFZLX0VTQ0FQRTogcmV0dXJuIDA7CgkJfQoJICAgIH0KCX0KCSpjYXB0dXJlUG9pbnQgPSBwdDsKICAgIH0KICAgIFNldEN1cnNvclBvcyggcHQueCwgcHQueSApOwogICAgTkNfSGFuZGxlU2V0Q3Vyc29yKCB3bmRQdHItPmh3bmRTZWxmLCAKCQkJd25kUHRyLT5od25kU2VsZiwgTUFLRUxPTkcoIGhpdHRlc3QsIFdNX01PVVNFTU9WRSApKTsKICAgIHJldHVybiBoaXR0ZXN0Owp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgICAgICBOQ19Eb1NpemVNb3ZlCiAqCiAqIFBlcmZvcm0gU0NfTU9WRSBhbmQgU0NfU0laRSBjb21tYW5kcy4gICAgICAgICAgICAgICBgCiAqLwpzdGF0aWMgdm9pZCBOQ19Eb1NpemVNb3ZlKCBIV05EIGh3bmQsIFdPUkQgd1BhcmFtICkKewogICAgTVNHIG1zZzsKICAgIFJFQ1Qgc2l6aW5nUmVjdCwgbW91c2VSZWN0LCBvcmlnUmVjdDsKICAgIEhEQyBoZGM7CiAgICBMT05HIGhpdHRlc3QgPSAoTE9ORykod1BhcmFtICYgMHgwZik7CiAgICBIQ1VSU09SMTYgaERyYWdDdXJzb3IgPSAwLCBoT2xkQ3Vyc29yID0gMDsKICAgIFBPSU5UIG1pblRyYWNrLCBtYXhUcmFjazsKICAgIFBPSU5UIGNhcHR1cmVQb2ludCwgcHQ7CiAgICBXTkQgKiAgICAgd25kUHRyID0gV0lOX0ZpbmRXbmRQdHIoIGh3bmQgKTsKICAgIEJPT0wgICAgdGhpY2tmcmFtZSA9IEhBU19USElDS0ZSQU1FKCB3bmRQdHItPmR3U3R5bGUsIHduZFB0ci0+ZHdFeFN0eWxlICk7CiAgICBCT09MICAgIGljb25pYyA9IHduZFB0ci0+ZHdTdHlsZSAmIFdTX01JTklNSVpFOwogICAgQk9PTCAgICBtb3ZlZCA9IEZBTFNFOwogICAgRFdPUkQgICAgIGR3UG9pbnQgPSBHZXRNZXNzYWdlUG9zICgpOwogICAgQk9PTCBEcmFnRnVsbFdpbmRvd3MgPSBGQUxTRTsKICAgIGludCBpV25kc0xvY2tzOwogICAgCiAgICBTeXN0ZW1QYXJhbWV0ZXJzSW5mb0EoU1BJX0dFVERSQUdGVUxMV0lORE9XUywgMCwgJkRyYWdGdWxsV2luZG93cywgMCk7CgogICAgcHQueCA9IFNMT1dPUkQoZHdQb2ludCk7CiAgICBwdC55ID0gU0hJV09SRChkd1BvaW50KTsKICAgIGNhcHR1cmVQb2ludCA9IHB0OwoKICAgIGlmIChJc1pvb21lZChod25kKSB8fCAhSXNXaW5kb3dWaXNpYmxlKGh3bmQpIHx8CiAgICAgICAgKHduZFB0ci0+ZHdFeFN0eWxlICYgV1NfRVhfTUFOQUdFRCkpIGdvdG8gRU5EOwoKICAgIGlmICgod1BhcmFtICYgMHhmZmYwKSA9PSBTQ19NT1ZFKQogICAgewoJaWYgKCFoaXR0ZXN0KSAKCSAgICAgaGl0dGVzdCA9IE5DX1N0YXJ0U2l6ZU1vdmUoIHduZFB0ciwgd1BhcmFtLCAmY2FwdHVyZVBvaW50ICk7CglpZiAoIWhpdHRlc3QpIGdvdG8gRU5EOwogICAgfQogICAgZWxzZSAgLyogU0NfU0laRSAqLwogICAgewoJaWYgKCF0aGlja2ZyYW1lKSBnb3RvIEVORDsKCWlmICggaGl0dGVzdCAmJiBoaXR0ZXN0ICE9IEhUU1lTTUVOVSApIGhpdHRlc3QgKz0gMjsKCWVsc2UKCXsKCSAgICBTZXRDYXB0dXJlKGh3bmQpOwoJICAgIGhpdHRlc3QgPSBOQ19TdGFydFNpemVNb3ZlKCB3bmRQdHIsIHdQYXJhbSwgJmNhcHR1cmVQb2ludCApOwoJICAgIGlmICghaGl0dGVzdCkKCSAgICB7CgkJUmVsZWFzZUNhcHR1cmUoKTsKCQlnb3RvIEVORDsKCSAgICB9Cgl9CiAgICB9CgogICAgICAvKiBHZXQgbWluL21heCBpbmZvICovCgogICAgV0lOUE9TX0dldE1pbk1heEluZm8oIHduZFB0ciwgTlVMTCwgTlVMTCwgJm1pblRyYWNrLCAmbWF4VHJhY2sgKTsKICAgIHNpemluZ1JlY3QgPSB3bmRQdHItPnJlY3RXaW5kb3c7CiAgICBvcmlnUmVjdCA9IHNpemluZ1JlY3Q7CiAgICBpZiAod25kUHRyLT5kd1N0eWxlICYgV1NfQ0hJTEQpCglHZXRDbGllbnRSZWN0KCB3bmRQdHItPnBhcmVudC0+aHduZFNlbGYsICZtb3VzZVJlY3QgKTsKICAgIGVsc2UgCiAgICAgICAgU2V0UmVjdCgmbW91c2VSZWN0LCAwLCAwLCBHZXRTeXN0ZW1NZXRyaWNzKFNNX0NYU0NSRUVOKSwgR2V0U3lzdGVtTWV0cmljcyhTTV9DWVNDUkVFTikpOwogICAgaWYgKE9OX0xFRlRfQk9SREVSKGhpdHRlc3QpKQogICAgewoJbW91c2VSZWN0LmxlZnQgID0gbWF4KCBtb3VzZVJlY3QubGVmdCwgc2l6aW5nUmVjdC5yaWdodC1tYXhUcmFjay54ICk7Cgltb3VzZVJlY3QucmlnaHQgPSBtaW4oIG1vdXNlUmVjdC5yaWdodCwgc2l6aW5nUmVjdC5yaWdodC1taW5UcmFjay54ICk7CiAgICB9CiAgICBlbHNlIGlmIChPTl9SSUdIVF9CT1JERVIoaGl0dGVzdCkpCiAgICB7Cgltb3VzZVJlY3QubGVmdCAgPSBtYXgoIG1vdXNlUmVjdC5sZWZ0LCBzaXppbmdSZWN0LmxlZnQrbWluVHJhY2sueCApOwoJbW91c2VSZWN0LnJpZ2h0ID0gbWluKCBtb3VzZVJlY3QucmlnaHQsIHNpemluZ1JlY3QubGVmdCttYXhUcmFjay54ICk7CiAgICB9CiAgICBpZiAoT05fVE9QX0JPUkRFUihoaXR0ZXN0KSkKICAgIHsKCW1vdXNlUmVjdC50b3AgICAgPSBtYXgoIG1vdXNlUmVjdC50b3AsIHNpemluZ1JlY3QuYm90dG9tLW1heFRyYWNrLnkgKTsKCW1vdXNlUmVjdC5ib3R0b20gPSBtaW4oIG1vdXNlUmVjdC5ib3R0b20sc2l6aW5nUmVjdC5ib3R0b20tbWluVHJhY2sueSk7CiAgICB9CiAgICBlbHNlIGlmIChPTl9CT1RUT01fQk9SREVSKGhpdHRlc3QpKQogICAgewoJbW91c2VSZWN0LnRvcCAgICA9IG1heCggbW91c2VSZWN0LnRvcCwgc2l6aW5nUmVjdC50b3ArbWluVHJhY2sueSApOwoJbW91c2VSZWN0LmJvdHRvbSA9IG1pbiggbW91c2VSZWN0LmJvdHRvbSwgc2l6aW5nUmVjdC50b3ArbWF4VHJhY2sueSApOwogICAgfQogICAgaWYgKHduZFB0ci0+ZHdTdHlsZSAmIFdTX0NISUxEKQogICAgewoJTWFwV2luZG93UG9pbnRzKCB3bmRQdHItPnBhcmVudC0+aHduZFNlbGYsIDAsIAoJCShMUFBPSU5UKSZtb3VzZVJlY3QsIDIgKTsKICAgIH0KICAgIFNlbmRNZXNzYWdlQSggaHduZCwgV01fRU5URVJTSVpFTU9WRSwgMCwgMCApOwoKICAgIGlmIChHZXRDYXB0dXJlKCkgIT0gaHduZCkgU2V0Q2FwdHVyZSggaHduZCApOyAgICAKCiAgICBpZiAod25kUHRyLT5kd1N0eWxlICYgV1NfQ0hJTEQpCiAgICB7CiAgICAgICAgICAvKiBSZXRyaWV2ZSBhIGRlZmF1bHQgY2FjaGUgREMgKHdpdGhvdXQgdXNpbmcgdGhlIHdpbmRvdyBzdHlsZSkgKi8KICAgICAgICBoZGMgPSBHZXREQ0V4KCB3bmRQdHItPnBhcmVudC0+aHduZFNlbGYsIDAsIERDWF9DQUNIRSApOwogICAgfQogICAgZWxzZQogICAgeyAgLyogR3JhYiB0aGUgc2VydmVyIG9ubHkgd2hlbiBtb3ZpbmcgdG9wLWxldmVsIHdpbmRvd3Mgd2l0aG91dCBkZXNrdG9wICovCgloZGMgPSBHZXREQyggMCApOwogICAgfQoKICAgIHduZFB0ci0+cERyaXZlci0+cFByZVNpemVNb3ZlKHduZFB0cik7CgogICAgaWYoIGljb25pYyApIC8qIGNyZWF0ZSBhIGN1cnNvciBmb3IgZHJhZ2dpbmcgKi8KICAgIHsKCUhJQ09OMTYgaEljb24gPSBHZXRDbGFzc1dvcmQod25kUHRyLT5od25kU2VsZiwgR0NXX0hJQ09OKTsKCWlmKCFoSWNvbikgaEljb24gPSAoSElDT04xNikgU2VuZE1lc3NhZ2UxNiggaHduZCwgV01fUVVFUllEUkFHSUNPTiwgMCwgMEwpOwoJaWYoIGhJY29uICkgaERyYWdDdXJzb3IgPSAgQ1VSU09SSUNPTl9JY29uVG9DdXJzb3IoIGhJY29uLCBUUlVFICk7CglpZiggIWhEcmFnQ3Vyc29yICkgaWNvbmljID0gRkFMU0U7CiAgICB9CgogICAgLyogaW52ZXJ0IGZyYW1lIGlmIFdJTjMxX0xPT0sgdG8gaW5kaWNhdGUgbW91c2UgY2xpY2sgb24gY2FwdGlvbiAqLwogICAgaWYoICFpY29uaWMgJiYgVFdFQUtfV2luZUxvb2sgPT0gV0lOMzFfTE9PSyApCglpZighRHJhZ0Z1bGxXaW5kb3dzKQoJTkNfRHJhd01vdmluZ0ZyYW1lKCBoZGMsICZzaXppbmdSZWN0LCB0aGlja2ZyYW1lICk7CgogICAgd2hpbGUoMSkKICAgIHsKICAgICAgICBpbnQgZHggPSAwLCBkeSA9IDA7CgogICAgICAgIE1TR19JbnRlcm5hbEdldE1lc3NhZ2UoIFFNU0dfV0lOMzJBLCAmbXNnLCAwLCAwLCBNU0dGX1NJWkUsIFBNX1JFTU9WRSwgRkFMU0UsIE5VTEwgKTsKCgkgIC8qIEV4aXQgb24gYnV0dG9uLXVwLCBSZXR1cm4sIG9yIEVzYyAqLwoJaWYgKChtc2cubWVzc2FnZSA9PSBXTV9MQlVUVE9OVVApIHx8CgkgICAgKChtc2cubWVzc2FnZSA9PSBXTV9LRVlET1dOKSAmJiAKCSAgICAgKChtc2cud1BhcmFtID09IFZLX1JFVFVSTikgfHwgKG1zZy53UGFyYW0gPT0gVktfRVNDQVBFKSkpKSBicmVhazsKCiAgICAgICAgaWYgKG1zZy5tZXNzYWdlID09IFdNX1BBSU5UKQogICAgICAgIHsKICAgICAgICAgICAgaWYoIWljb25pYyAmJiAhRHJhZ0Z1bGxXaW5kb3dzKSBOQ19EcmF3TW92aW5nRnJhbWUoIGhkYywgJnNpemluZ1JlY3QsIHRoaWNrZnJhbWUgKTsKICAgICAgICAgICAgVXBkYXRlV2luZG93KCBtc2cuaHduZCApOwogICAgICAgICAgICBpZighaWNvbmljICYmICFEcmFnRnVsbFdpbmRvd3MpIE5DX0RyYXdNb3ZpbmdGcmFtZSggaGRjLCAmc2l6aW5nUmVjdCwgdGhpY2tmcmFtZSApOwogICAgICAgICAgICBjb250aW51ZTsKICAgICAgICB9CgoJaWYgKChtc2cubWVzc2FnZSAhPSBXTV9LRVlET1dOKSAmJiAobXNnLm1lc3NhZ2UgIT0gV01fTU9VU0VNT1ZFKSkKCSAgICBjb250aW51ZTsgIC8qIFdlIGFyZSBub3QgaW50ZXJlc3RlZCBpbiBvdGhlciBtZXNzYWdlcyAqLwoKICAgICAgICBwdCA9IG1zZy5wdDsKCQoJaWYgKG1zZy5tZXNzYWdlID09IFdNX0tFWURPV04pIHN3aXRjaChtc2cud1BhcmFtKQoJewoJICAgIGNhc2UgVktfVVA6ICAgIHB0LnkgLT0gODsgYnJlYWs7CgkgICAgY2FzZSBWS19ET1dOOiAgcHQueSArPSA4OyBicmVhazsKCSAgICBjYXNlIFZLX0xFRlQ6ICBwdC54IC09IDg7IGJyZWFrOwoJICAgIGNhc2UgVktfUklHSFQ6IHB0LnggKz0gODsgYnJlYWs7CQkKCX0KCglwdC54ID0gbWF4KCBwdC54LCBtb3VzZVJlY3QubGVmdCApOwoJcHQueCA9IG1pbiggcHQueCwgbW91c2VSZWN0LnJpZ2h0ICk7CglwdC55ID0gbWF4KCBwdC55LCBtb3VzZVJlY3QudG9wICk7CglwdC55ID0gbWluKCBwdC55LCBtb3VzZVJlY3QuYm90dG9tICk7CgoJZHggPSBwdC54IC0gY2FwdHVyZVBvaW50Lng7CglkeSA9IHB0LnkgLSBjYXB0dXJlUG9pbnQueTsKCglpZiAoZHggfHwgZHkpCgl7CgkgICAgaWYoICFtb3ZlZCApCgkgICAgewoJCW1vdmVkID0gVFJVRTsKCgkJaWYoIGljb25pYyApIC8qIG9rLCBubyBzeXN0ZW0gcG9wdXAgdHJhY2tpbmcgKi8KCQl7CgkJICAgIGhPbGRDdXJzb3IgPSBTZXRDdXJzb3IoaERyYWdDdXJzb3IpOwoJCSAgICBTaG93Q3Vyc29yKCBUUlVFICk7CgkJICAgIFdJTlBPU19TaG93SWNvblRpdGxlKCB3bmRQdHIsIEZBTFNFICk7CgkJfSBlbHNlIGlmKFRXRUFLX1dpbmVMb29rICE9IFdJTjMxX0xPT0spCiAgICAgICAgICAgICAgICB7CgkJICAgIGlmKCFEcmFnRnVsbFdpbmRvd3MpCgkJICAgIE5DX0RyYXdNb3ZpbmdGcmFtZSggaGRjLCAmc2l6aW5nUmVjdCwgdGhpY2tmcmFtZSApOwogICAgICAgICAgICAgICAgfQoJICAgIH0KCgkgICAgaWYgKG1zZy5tZXNzYWdlID09IFdNX0tFWURPV04pIFNldEN1cnNvclBvcyggcHQueCwgcHQueSApOwoJICAgIGVsc2UKCSAgICB7CgkJUkVDVCBuZXdSZWN0ID0gc2l6aW5nUmVjdDsKICAgICAgICAgICAgICAgIFdQQVJBTSB3cFNpemluZ0hpdCA9IDA7CgoJCWlmIChoaXR0ZXN0ID09IEhUQ0FQVElPTikgT2Zmc2V0UmVjdCggJm5ld1JlY3QsIGR4LCBkeSApOwoJCWlmIChPTl9MRUZUX0JPUkRFUihoaXR0ZXN0KSkgbmV3UmVjdC5sZWZ0ICs9IGR4OwoJCWVsc2UgaWYgKE9OX1JJR0hUX0JPUkRFUihoaXR0ZXN0KSkgbmV3UmVjdC5yaWdodCArPSBkeDsKCQlpZiAoT05fVE9QX0JPUkRFUihoaXR0ZXN0KSkgbmV3UmVjdC50b3AgKz0gZHk7CgkJZWxzZSBpZiAoT05fQk9UVE9NX0JPUkRFUihoaXR0ZXN0KSkgbmV3UmVjdC5ib3R0b20gKz0gZHk7CgkJaWYoIWljb25pYyAmJiAhRHJhZ0Z1bGxXaW5kb3dzKSBOQ19EcmF3TW92aW5nRnJhbWUoIGhkYywgJnNpemluZ1JlY3QsIHRoaWNrZnJhbWUgKTsKCQljYXB0dXJlUG9pbnQgPSBwdDsKICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgLyogZGV0ZXJtaW5lIHRoZSBoaXQgbG9jYXRpb24gKi8KICAgICAgICAgICAgICAgIGlmIChoaXR0ZXN0ID49IEhUTEVGVCAmJiBoaXR0ZXN0IDw9IEhUQk9UVE9NUklHSFQpCiAgICAgICAgICAgICAgICAgICAgd3BTaXppbmdIaXQgPSBXTVNaX0xFRlQgKyAoaGl0dGVzdCAtIEhUTEVGVCk7CgkJU2VuZE1lc3NhZ2VBKCBod25kLCBXTV9TSVpJTkcsIHdwU2l6aW5nSGl0LCAoTFBBUkFNKSZuZXdSZWN0ICk7CgoJCWlmICghaWNvbmljKQoJCXsKCQkgICAgaWYoIURyYWdGdWxsV2luZG93cykKCQkJTkNfRHJhd01vdmluZ0ZyYW1lKCBoZGMsICZuZXdSZWN0LCB0aGlja2ZyYW1lICk7CgkJICAgIGVsc2UgewoJCQkvKiBUbyBhdm9pZCBhbnkgZGVhZGxvY2tzLCBhbGwgdGhlIGxvY2tzIG9uIHRoZSB3aW5kb3dzCgkJCSAgIHN0cnVjdHVyZXMgbXVzdCBiZSBzdXNwZW5kZWQgYmVmb3JlIHRoZSBTZXRXaW5kb3dQb3MgKi8KCQkJaVduZHNMb2NrcyA9IFdJTl9TdXNwZW5kV25kc0xvY2soKTsKCQkJU2V0V2luZG93UG9zKCBod25kLCAwLCBuZXdSZWN0LmxlZnQsIG5ld1JlY3QudG9wLAoJCQkgICAgbmV3UmVjdC5yaWdodCAtIG5ld1JlY3QubGVmdCwKCQkJICAgIG5ld1JlY3QuYm90dG9tIC0gbmV3UmVjdC50b3AsCgkJCSAgICAoIGhpdHRlc3QgPT0gSFRDQVBUSU9OICkgPyBTV1BfTk9TSVpFIDogMCApOwoJCQlXSU5fUmVzdG9yZVduZHNMb2NrKGlXbmRzTG9ja3MpOwoJCSAgICB9CgkJfQoJCXNpemluZ1JlY3QgPSBuZXdSZWN0OwoJICAgIH0KCX0KICAgIH0KCiAgICBSZWxlYXNlQ2FwdHVyZSgpOwogICAgaWYoIGljb25pYyApCiAgICB7CglpZiggbW92ZWQgKSAvKiByZXN0b3JlIGN1cnNvcnMsIHNob3cgaWNvbiB0aXRsZSBsYXRlciBvbiAqLwoJewoJICAgIFNob3dDdXJzb3IoIEZBTFNFICk7CgkgICAgU2V0Q3Vyc29yKCBoT2xkQ3Vyc29yICk7Cgl9CiAgICAgICAgRGVzdHJveUN1cnNvciggaERyYWdDdXJzb3IgKTsKICAgIH0KICAgIGVsc2UgaWYobW92ZWQgfHwgVFdFQUtfV2luZUxvb2sgPT0gV0lOMzFfTE9PSykKCWlmKCFEcmFnRnVsbFdpbmRvd3MpCiAgICAgICAgTkNfRHJhd01vdmluZ0ZyYW1lKCBoZGMsICZzaXppbmdSZWN0LCB0aGlja2ZyYW1lICk7CgogICAgaWYgKHduZFB0ci0+ZHdTdHlsZSAmIFdTX0NISUxEKQogICAgICAgIFJlbGVhc2VEQyggd25kUHRyLT5wYXJlbnQtPmh3bmRTZWxmLCBoZGMgKTsKICAgIGVsc2UKICAgICAgICBSZWxlYXNlREMoIDAsIGhkYyApOwoKICAgIHduZFB0ci0+cERyaXZlci0+cFBvc3RTaXplTW92ZSh3bmRQdHIpOwoKICAgIGlmIChIT09LX0lzSG9va2VkKCBXSF9DQlQgKSkKICAgIHsKCVJFQ1QxNiogcHIgPSBTRUdQVFJfTkVXKFJFQ1QxNik7CglpZiggcHIgKQoJewogICAgICAgICAgICBDT05WX1JFQ1QzMlRPMTYoICZzaXppbmdSZWN0LCBwciApOwoJICAgIGlmKCBIT09LX0NhbGxIb29rczE2KCBXSF9DQlQsIEhDQlRfTU9WRVNJWkUsIGh3bmQsCgkJCSAgICAgICAgKExQQVJBTSlTRUdQVFJfR0VUKHByKSkgKQoJCXNpemluZ1JlY3QgPSB3bmRQdHItPnJlY3RXaW5kb3c7CgkgICAgZWxzZQoJCUNPTlZfUkVDVDE2VE8zMiggcHIsICZzaXppbmdSZWN0ICk7CgkgICAgU0VHUFRSX0ZSRUUocHIpOwoJfQogICAgfQogICAgU2VuZE1lc3NhZ2VBKCBod25kLCBXTV9FWElUU0laRU1PVkUsIDAsIDAgKTsKICAgIFNlbmRNZXNzYWdlQSggaHduZCwgV01fU0VUVklTSUJMRSwgIUlzSWNvbmljMTYoaHduZCksIDBMKTsKCiAgICAvKiB3aW5kb3cgbW92ZWQgb3IgcmVzaXplZCAqLwogICAgaWYgKG1vdmVkKQogICAgewoJLyogVG8gYXZvaWQgYW55IGRlYWRsb2NrcywgYWxsIHRoZSBsb2NrcyBvbiB0aGUgd2luZG93cwoJICAgc3RydWN0dXJlcyBtdXN0IGJlIHN1c3BlbmRlZCBiZWZvcmUgdGhlIFNldFdpbmRvd1BvcyAqLwoJaVduZHNMb2NrcyA9IFdJTl9TdXNwZW5kV25kc0xvY2soKTsKCiAgICAgICAgLyogaWYgdGhlIG1vdmluZy9yZXNpemluZyBpc24ndCBjYW5jZWxlZCBjYWxsIFNldFdpbmRvd1BvcwogICAgICAgICAqIHdpdGggdGhlIG5ldyBwb3NpdGlvbiBvciB0aGUgbmV3IHNpemUgb2YgdGhlIHdpbmRvdwogICAgICAgICAqLwogICAgICAgIGlmICghKChtc2cubWVzc2FnZSA9PSBXTV9LRVlET1dOKSAmJiAobXNnLndQYXJhbSA9PSBWS19FU0NBUEUpKSApCiAgICAgICAgewoJLyogTk9URTogU1dQX05PQUNUSVZBVEUgcHJldmVudHMgZG9jdW1lbnQgd2luZG93IGFjdGl2YXRpb24gaW4gV29yZCA2ICovCglpZighRHJhZ0Z1bGxXaW5kb3dzKQoJU2V0V2luZG93UG9zKCBod25kLCAwLCBzaXppbmdSZWN0LmxlZnQsIHNpemluZ1JlY3QudG9wLAoJCQlzaXppbmdSZWN0LnJpZ2h0IC0gc2l6aW5nUmVjdC5sZWZ0LAoJCQlzaXppbmdSZWN0LmJvdHRvbSAtIHNpemluZ1JlY3QudG9wLAoJCSAgICAgICggaGl0dGVzdCA9PSBIVENBUFRJT04gKSA/IFNXUF9OT1NJWkUgOiAwICk7CiAgICAgICAgfQoJZWxzZSB7IC8qIHJlc3RvcmUgcHJldmlvdXMgc2l6ZS9wb3NpdGlvbiAqLwoJICAgIGlmKERyYWdGdWxsV2luZG93cykKCQlTZXRXaW5kb3dQb3MoIGh3bmQsIDAsIG9yaWdSZWN0LmxlZnQsIG9yaWdSZWN0LnRvcCwKCQkJb3JpZ1JlY3QucmlnaHQgLSBvcmlnUmVjdC5sZWZ0LAoJCQlvcmlnUmVjdC5ib3R0b20gLSBvcmlnUmVjdC50b3AsCgkJCSggaGl0dGVzdCA9PSBIVENBUFRJT04gKSA/IFNXUF9OT1NJWkUgOiAwICk7Cgl9CgoJV0lOX1Jlc3RvcmVXbmRzTG9jayhpV25kc0xvY2tzKTsKICAgIH0KCiAgICBpZiggSXNXaW5kb3coaHduZCkgKQoJaWYoIHduZFB0ci0+ZHdTdHlsZSAmIFdTX01JTklNSVpFICkKCXsKCSAgICAvKiBTaW5nbGUgY2xpY2sgYnJpbmdzIHVwIHRoZSBzeXN0ZW0gbWVudSB3aGVuIGljb25pemVkICovCgoJICAgIGlmKCAhbW92ZWQgKSAKCSAgICB7CgkJIGlmKCB3bmRQdHItPmR3U3R5bGUgJiBXU19TWVNNRU5VICkgCiAgICAgICAgICAgICAgICAgICAgIFNlbmRNZXNzYWdlQSggaHduZCwgV01fU1lTQ09NTUFORCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTQ19NT1VTRU1FTlUgKyBIVFNZU01FTlUsIE1BS0VMT05HKHB0LngscHQueSkpOwoJICAgIH0KCSAgICBlbHNlIFdJTlBPU19TaG93SWNvblRpdGxlKCB3bmRQdHIsIFRSVUUgKTsKCX0KCkVORDoKICAgIFdJTl9SZWxlYXNlV25kUHRyKHduZFB0cik7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICAgICAgIE5DX1RyYWNrTWluTWF4Qm94OTUKICoKICogVHJhY2sgYSBtb3VzZSBidXR0b24gcHJlc3Mgb24gdGhlIG1pbmltaXplIG9yIG1heGltaXplIGJveC4KICoKICogVGhlIGJpZyBkaWZmZXJlbmNlIGJldHdlZW4gMy4xIGFuZCA5NSBpcyB0aGUgZGlzYWJsZWQgYnV0dG9uIHN0YXRlLgogKiBJbiB3aW45NSB0aGUgc3lzdGVtIGJ1dHRvbiBjYW4gYmUgZGlzYWJsZWQsIHNvIGl0IGNhbiBpZ25vcmUgdGhlIG1vdXNlCiAqIGV2ZW50LgogKgogKi8Kc3RhdGljIHZvaWQgTkNfVHJhY2tNaW5NYXhCb3g5NSggSFdORCBod25kLCBXT1JEIHdQYXJhbSApCnsKICAgIE1TRyBtc2c7CiAgICBIREMgaGRjID0gR2V0V2luZG93REMoIGh3bmQgKTsKICAgIEJPT0wgcHJlc3NlZCA9IFRSVUU7CiAgICBVSU5UIHN0YXRlOwogICAgRFdPUkQgd25kU3R5bGUgPSBHZXRXaW5kb3dMb25nQSggaHduZCwgR1dMX1NUWUxFKTsKICAgIEhNRU5VIGhTeXNNZW51ID0gR2V0U3lzdGVtTWVudShod25kLCBGQUxTRSk7CgogICAgdm9pZCAgKCpwYWludEJ1dHRvbikoSFdORCwgSERDMTYsIEJPT0wsIEJPT0wpOwoKICAgIGlmICh3UGFyYW0gPT0gSFRNSU5CVVRUT04pCiAgICB7CgkvKiBJZiB0aGUgc3R5bGUgaXMgbm90IHByZXNlbnQsIGRvIG5vdGhpbmcgKi8KCWlmICghKHduZFN0eWxlICYgV1NfTUlOSU1JWkVCT1gpKQoJICAgIHJldHVybjsKCgkvKiBDaGVjayBpZiB0aGUgc3lzbWVudSBpdGVtIGZvciBtaW5pbWl6ZSBpcyB0aGVyZSAgKi8KCXN0YXRlID0gR2V0TWVudVN0YXRlKGhTeXNNZW51LCBTQ19NSU5JTUlaRSwgTUZfQllDT01NQU5EKTsKCQoJcGFpbnRCdXR0b24gPSAmTkNfRHJhd01pbkJ1dHRvbjk1OwogICAgfQogICAgZWxzZQogICAgewoJLyogSWYgdGhlIHN0eWxlIGlzIG5vdCBwcmVzZW50LCBkbyBub3RoaW5nICovCglpZiAoISh3bmRTdHlsZSAmIFdTX01BWElNSVpFQk9YKSkKCSAgICByZXR1cm47CgoJLyogQ2hlY2sgaWYgdGhlIHN5c21lbnUgaXRlbSBmb3IgbWF4aW1pemUgaXMgdGhlcmUgICovCglzdGF0ZSA9IEdldE1lbnVTdGF0ZShoU3lzTWVudSwgU0NfTUFYSU1JWkUsIE1GX0JZQ09NTUFORCk7CgkKCXBhaW50QnV0dG9uID0gJk5DX0RyYXdNYXhCdXR0b245NTsKICAgIH0KCiAgICBTZXRDYXB0dXJlKCBod25kICk7CgogICAgKCpwYWludEJ1dHRvbikoIGh3bmQsIGhkYywgVFJVRSwgRkFMU0UpOwoKICAgIHdoaWxlKDEpCiAgICB7CglCT09MIG9sZHN0YXRlID0gcHJlc3NlZDsKICAgICAgICBNU0dfSW50ZXJuYWxHZXRNZXNzYWdlKCBRTVNHX1dJTjMyQSwgJm1zZywgMCwgMCwgMCwgUE1fUkVNT1ZFLCBGQUxTRSwgTlVMTCApOwoKCWlmKG1zZy5tZXNzYWdlID09IFdNX0xCVVRUT05VUCkKCSAgICBicmVhazsKCglpZihtc2cubWVzc2FnZSAhPSBXTV9NT1VTRU1PVkUpCgkgICAgY29udGludWU7CgoJcHJlc3NlZCA9IChOQ19IYW5kbGVOQ0hpdFRlc3QoIGh3bmQsIG1zZy5wdCApID09IHdQYXJhbSk7CglpZiAocHJlc3NlZCAhPSBvbGRzdGF0ZSkKCSAgICgqcGFpbnRCdXR0b24pKCBod25kLCBoZGMsIHByZXNzZWQsIEZBTFNFKTsKICAgIH0KCiAgICBpZihwcmVzc2VkKQoJKCpwYWludEJ1dHRvbikoaHduZCwgaGRjLCBGQUxTRSwgRkFMU0UpOwoKICAgIFJlbGVhc2VDYXB0dXJlKCk7CiAgICBSZWxlYXNlREMoIGh3bmQsIGhkYyApOwoKICAgIC8qIElmIHRoZSBpdGVtIG1pbmltaXplIG9yIG1heGltaXplIG9mIHRoZSBzeXNtZW51IGFyZSBub3QgdGhlcmUgKi8KICAgIC8qIG9yIGlmIHRoZSBzdHlsZSBpcyBub3QgcHJlc2VudCwgZG8gbm90aGluZyAqLwogICAgaWYgKCghcHJlc3NlZCkgfHwgKHN0YXRlID09IDB4RkZGRkZGRkYpKQoJcmV0dXJuOwoKICAgIGlmICh3UGFyYW0gPT0gSFRNSU5CVVRUT04pIAogICAgICAgIFNlbmRNZXNzYWdlQSggaHduZCwgV01fU1lTQ09NTUFORCwgU0NfTUlOSU1JWkUsIE1BS0VMT05HKG1zZy5wdC54LG1zZy5wdC55KSApOwogICAgZWxzZQogICAgICAgIFNlbmRNZXNzYWdlQSggaHduZCwgV01fU1lTQ09NTUFORCwKICAgICAgICAgICAgICAgICAgICAgIElzWm9vbWVkKGh3bmQpID8gU0NfUkVTVE9SRTpTQ19NQVhJTUlaRSwgTUFLRUxPTkcobXNnLnB0LngsbXNnLnB0LnkpICk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgICAgICAgTkNfVHJhY2tNaW5NYXhCb3gKICoKICogVHJhY2sgYSBtb3VzZSBidXR0b24gcHJlc3Mgb24gdGhlIG1pbmltaXplIG9yIG1heGltaXplIGJveC4KICovCnN0YXRpYyB2b2lkIE5DX1RyYWNrTWluTWF4Qm94KCBIV05EIGh3bmQsIFdPUkQgd1BhcmFtICkKewogICAgTVNHIG1zZzsKICAgIEhEQyBoZGMgPSBHZXRXaW5kb3dEQyggaHduZCApOwogICAgQk9PTCBwcmVzc2VkID0gVFJVRTsKICAgIHZvaWQgICgqcGFpbnRCdXR0b24pKEhXTkQsIEhEQzE2LCBCT09MKTsKCiAgICBTZXRDYXB0dXJlKCBod25kICk7CgogICAgaWYgKHdQYXJhbSA9PSBIVE1JTkJVVFRPTikKCXBhaW50QnV0dG9uID0gJk5DX0RyYXdNaW5CdXR0b247CiAgICBlbHNlCglwYWludEJ1dHRvbiA9ICZOQ19EcmF3TWF4QnV0dG9uOwoKICAgICgqcGFpbnRCdXR0b24pKCBod25kLCBoZGMsIFRSVUUpOwoKICAgIHdoaWxlKDEpCiAgICB7CglCT09MIG9sZHN0YXRlID0gcHJlc3NlZDsKICAgICAgICBNU0dfSW50ZXJuYWxHZXRNZXNzYWdlKCBRTVNHX1dJTjMyQSwgJm1zZywgMCwgMCwgMCwgUE1fUkVNT1ZFLCBGQUxTRSwgTlVMTCApOwoKCWlmKG1zZy5tZXNzYWdlID09IFdNX0xCVVRUT05VUCkKCSAgICBicmVhazsKCglpZihtc2cubWVzc2FnZSAhPSBXTV9NT1VTRU1PVkUpCgkgICAgY29udGludWU7CgoJcHJlc3NlZCA9IChOQ19IYW5kbGVOQ0hpdFRlc3QoIGh3bmQsIG1zZy5wdCApID09IHdQYXJhbSk7CglpZiAocHJlc3NlZCAhPSBvbGRzdGF0ZSkKCSAgICgqcGFpbnRCdXR0b24pKCBod25kLCBoZGMsIHByZXNzZWQpOwogICAgfQoKICAgIGlmKHByZXNzZWQpCgkoKnBhaW50QnV0dG9uKSggaHduZCwgaGRjLCBGQUxTRSk7CgogICAgUmVsZWFzZUNhcHR1cmUoKTsKICAgIFJlbGVhc2VEQyggaHduZCwgaGRjICk7CgogICAgaWYgKCFwcmVzc2VkKSByZXR1cm47CgogICAgaWYgKHdQYXJhbSA9PSBIVE1JTkJVVFRPTikgCiAgICAgICAgU2VuZE1lc3NhZ2VBKCBod25kLCBXTV9TWVNDT01NQU5ELCBTQ19NSU5JTUlaRSwgTUFLRUxPTkcobXNnLnB0LngsbXNnLnB0LnkpICk7CiAgICBlbHNlCiAgICAgICAgU2VuZE1lc3NhZ2VBKCBod25kLCBXTV9TWVNDT01NQU5ELAogICAgICAgICAgICAgICAgICAgICAgSXNab29tZWQoaHduZCkgPyBTQ19SRVNUT1JFOlNDX01BWElNSVpFLCBNQUtFTE9ORyhtc2cucHQueCxtc2cucHQueSkgKTsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBOQ19UcmFja0Nsb3NlQnV0dG9uOTUKICoKICogVHJhY2sgYSBtb3VzZSBidXR0b24gcHJlc3Mgb24gdGhlIFdpbjk1IGNsb3NlIGJ1dHRvbi4KICovCnN0YXRpYyB2b2lkCk5DX1RyYWNrQ2xvc2VCdXR0b245NSAoSFdORCBod25kLCBXT1JEIHdQYXJhbSkKewogICAgTVNHIG1zZzsKICAgIEhEQyBoZGM7CiAgICBCT09MIHByZXNzZWQgPSBUUlVFOwogICAgSE1FTlUgaFN5c01lbnUgPSBHZXRTeXN0ZW1NZW51KGh3bmQsIEZBTFNFKTsKICAgIFVJTlQgc3RhdGU7CgogICAgaWYoaFN5c01lbnUgPT0gMCkKCXJldHVybjsKCiAgICBzdGF0ZSA9IEdldE1lbnVTdGF0ZShoU3lzTWVudSwgU0NfQ0xPU0UsIE1GX0JZQ09NTUFORCk7CgkgICAgCiAgICAvKiBJZiB0aGUgaXRlbSBjbG9zZSBvZiB0aGUgc3lzbWVudSBpcyBkaXNhYmxlZCBvciBub3QgdGhlcmUgZG8gbm90aGluZyAqLwogICAgaWYoKHN0YXRlICYgTUZfRElTQUJMRUQpIHx8IChzdGF0ZSAmIE1GX0dSQVlFRCkgfHwgKHN0YXRlID09IDB4RkZGRkZGRkYpKQoJcmV0dXJuOwoKICAgIGhkYyA9IEdldFdpbmRvd0RDKCBod25kICk7CgogICAgU2V0Q2FwdHVyZSggaHduZCApOwoKICAgIE5DX0RyYXdDbG9zZUJ1dHRvbjk1IChod25kLCBoZGMsIFRSVUUsIEZBTFNFKTsKCiAgICB3aGlsZSgxKQogICAgewoJQk9PTCBvbGRzdGF0ZSA9IHByZXNzZWQ7CiAgICAgICAgTVNHX0ludGVybmFsR2V0TWVzc2FnZSggUU1TR19XSU4zMkEsICZtc2csIDAsIDAsIDAsIFBNX1JFTU9WRSwgRkFMU0UsIE5VTEwgKTsKCglpZihtc2cubWVzc2FnZSA9PSBXTV9MQlVUVE9OVVApCgkgICAgYnJlYWs7CgoJaWYobXNnLm1lc3NhZ2UgIT0gV01fTU9VU0VNT1ZFKQoJICAgIGNvbnRpbnVlOwoKCXByZXNzZWQgPSAoTkNfSGFuZGxlTkNIaXRUZXN0KCBod25kLCBtc2cucHQgKSA9PSB3UGFyYW0pOwoJaWYgKHByZXNzZWQgIT0gb2xkc3RhdGUpCgkgICBOQ19EcmF3Q2xvc2VCdXR0b245NSAoaHduZCwgaGRjLCBwcmVzc2VkLCBGQUxTRSk7CiAgICB9CgogICAgaWYocHJlc3NlZCkKCU5DX0RyYXdDbG9zZUJ1dHRvbjk1IChod25kLCBoZGMsIEZBTFNFLCBGQUxTRSk7CgogICAgUmVsZWFzZUNhcHR1cmUoKTsKICAgIFJlbGVhc2VEQyggaHduZCwgaGRjICk7CiAgICBpZiAoIXByZXNzZWQpIHJldHVybjsKCiAgICBTZW5kTWVzc2FnZUEoIGh3bmQsIFdNX1NZU0NPTU1BTkQsIFNDX0NMT1NFLCBNQUtFTE9ORyhtc2cucHQueCxtc2cucHQueSkgKTsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgICAgICAgTkNfVHJhY2tTY3JvbGxCYXIKICoKICogVHJhY2sgYSBtb3VzZSBidXR0b24gcHJlc3Mgb24gdGhlIGhvcml6b250YWwgb3IgdmVydGljYWwgc2Nyb2xsLWJhci4KICovCnN0YXRpYyB2b2lkIE5DX1RyYWNrU2Nyb2xsQmFyKCBIV05EIGh3bmQsIFdQQVJBTSB3UGFyYW0sIFBPSU5UIHB0ICkKewogICAgTVNHMTYgKm1zZzsKICAgIElOVCBzY3JvbGxiYXI7CiAgICBXTkQgKnduZFB0ciA9IFdJTl9GaW5kV25kUHRyKCBod25kICk7CgogICAgaWYgKCh3UGFyYW0gJiAweGZmZjApID09IFNDX0hTQ1JPTEwpCiAgICB7CglpZiAoKHdQYXJhbSAmIDB4MGYpICE9IEhUSFNDUk9MTCkgZ290byBFTkQ7CglzY3JvbGxiYXIgPSBTQl9IT1JaOwogICAgfQogICAgZWxzZSAgLyogU0NfVlNDUk9MTCAqLwogICAgewoJaWYgKCh3UGFyYW0gJiAweDBmKSAhPSBIVFZTQ1JPTEwpIGdvdG8gRU5EOwoJc2Nyb2xsYmFyID0gU0JfVkVSVDsKICAgIH0KCiAgICBpZiAoIShtc2cgPSBTRUdQVFJfTkVXKE1TRzE2KSkpIGdvdG8gRU5EOwogICAgcHQueCAtPSB3bmRQdHItPnJlY3RXaW5kb3cubGVmdDsKICAgIHB0LnkgLT0gd25kUHRyLT5yZWN0V2luZG93LnRvcDsKICAgIFNldENhcHR1cmUoIGh3bmQgKTsKICAgIFNDUk9MTF9IYW5kbGVTY3JvbGxFdmVudCggaHduZCwgc2Nyb2xsYmFyLCBXTV9MQlVUVE9ORE9XTiwgcHQgKTsKCiAgICBkbwogICAgewogICAgICAgIEdldE1lc3NhZ2UxNiggU0VHUFRSX0dFVChtc2cpLCAwLCAwLCAwICk7Cglzd2l0Y2gobXNnLT5tZXNzYWdlKQoJewoJY2FzZSBXTV9MQlVUVE9OVVA6CgljYXNlIFdNX01PVVNFTU9WRToKICAgICAgICBjYXNlIFdNX1NZU1RJTUVSOgogICAgICAgICAgICBwdC54ID0gTE9XT1JEKG1zZy0+bFBhcmFtKSArIHduZFB0ci0+cmVjdENsaWVudC5sZWZ0IC0gCgkgICAgICB3bmRQdHItPnJlY3RXaW5kb3cubGVmdDsKICAgICAgICAgICAgcHQueSA9IEhJV09SRChtc2ctPmxQYXJhbSkgKyB3bmRQdHItPnJlY3RDbGllbnQudG9wIC0gCgkgICAgICB3bmRQdHItPnJlY3RXaW5kb3cudG9wOwogICAgICAgICAgICBTQ1JPTExfSGFuZGxlU2Nyb2xsRXZlbnQoIGh3bmQsIHNjcm9sbGJhciwgbXNnLT5tZXNzYWdlLCBwdCApOwoJICAgIGJyZWFrOwogICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgIFRyYW5zbGF0ZU1lc3NhZ2UxNiggbXNnICk7CiAgICAgICAgICAgIERpc3BhdGNoTWVzc2FnZTE2KCBtc2cgKTsKICAgICAgICAgICAgYnJlYWs7Cgl9CiAgICAgICAgaWYgKCFJc1dpbmRvdyggaHduZCApKQogICAgICAgIHsKICAgICAgICAgICAgUmVsZWFzZUNhcHR1cmUoKTsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgfQogICAgfSB3aGlsZSAobXNnLT5tZXNzYWdlICE9IFdNX0xCVVRUT05VUCk7CiAgICBTRUdQVFJfRlJFRShtc2cpOwpFTkQ6CiAgICBXSU5fUmVsZWFzZVduZFB0cih3bmRQdHIpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICAgICAgIE5DX0hhbmRsZU5DTEJ1dHRvbkRvd24KICoKICogSGFuZGxlIGEgV01fTkNMQlVUVE9ORE9XTiBtZXNzYWdlLiBDYWxsZWQgZnJvbSBEZWZXaW5kb3dQcm9jKCkuCiAqLwpMT05HIE5DX0hhbmRsZU5DTEJ1dHRvbkRvd24oIFdORCogcFduZCwgV1BBUkFNMTYgd1BhcmFtLCBMUEFSQU0gbFBhcmFtICkKewogICAgSFdORCBod25kID0gcFduZC0+aHduZFNlbGY7CgogICAgc3dpdGNoKHdQYXJhbSkgIC8qIEhpdCB0ZXN0ICovCiAgICB7CiAgICBjYXNlIEhUQ0FQVElPTjoKCSBod25kID0gV0lOX0dldFRvcFBhcmVudChod25kKTsKCgkgaWYoIFdJTlBPU19TZXRBY3RpdmVXaW5kb3coaHduZCwgVFJVRSwgVFJVRSkgfHwgKEdldEFjdGl2ZVdpbmRvdygpID09IGh3bmQpICkKCQlTZW5kTWVzc2FnZTE2KCBwV25kLT5od25kU2VsZiwgV01fU1lTQ09NTUFORCwgU0NfTU9WRSArIEhUQ0FQVElPTiwgbFBhcmFtICk7CgkgYnJlYWs7CgogICAgY2FzZSBIVFNZU01FTlU6CgkgaWYoIHBXbmQtPmR3U3R5bGUgJiBXU19TWVNNRU5VICkKCSB7CgkgICAgIGlmKCAhKHBXbmQtPmR3U3R5bGUgJiBXU19NSU5JTUlaRSkgKQoJICAgICB7CgkJSERDIGhEQyA9IEdldFdpbmRvd0RDKGh3bmQpOwoJCWlmIChUV0VBS19XaW5lTG9vayA9PSBXSU4zMV9MT09LKQoJCSAgICBOQ19EcmF3U3lzQnV0dG9uKCBod25kLCBoREMsIFRSVUUgKTsKCQllbHNlCgkJICAgIE5DX0RyYXdTeXNCdXR0b245NSggaHduZCwgaERDLCBUUlVFICk7CgkJUmVsZWFzZURDKCBod25kLCBoREMgKTsKCSAgICAgfQoJICAgICBTZW5kTWVzc2FnZTE2KCBod25kLCBXTV9TWVNDT01NQU5ELCBTQ19NT1VTRU1FTlUgKyBIVFNZU01FTlUsIGxQYXJhbSApOwoJIH0KCSBicmVhazsKCiAgICBjYXNlIEhUTUVOVToKCVNlbmRNZXNzYWdlMTYoIGh3bmQsIFdNX1NZU0NPTU1BTkQsIFNDX01PVVNFTUVOVSwgbFBhcmFtICk7CglicmVhazsKCiAgICBjYXNlIEhUSFNDUk9MTDoKCVNlbmRNZXNzYWdlMTYoIGh3bmQsIFdNX1NZU0NPTU1BTkQsIFNDX0hTQ1JPTEwgKyBIVEhTQ1JPTEwsIGxQYXJhbSApOwoJYnJlYWs7CgogICAgY2FzZSBIVFZTQ1JPTEw6CglTZW5kTWVzc2FnZTE2KCBod25kLCBXTV9TWVNDT01NQU5ELCBTQ19WU0NST0xMICsgSFRWU0NST0xMLCBsUGFyYW0gKTsKCWJyZWFrOwoKICAgIGNhc2UgSFRNSU5CVVRUT046CiAgICBjYXNlIEhUTUFYQlVUVE9OOgoJaWYgKFRXRUFLX1dpbmVMb29rID09IFdJTjMxX0xPT0spCgkgICAgTkNfVHJhY2tNaW5NYXhCb3goIGh3bmQsIHdQYXJhbSApOwoJZWxzZQoJICAgIE5DX1RyYWNrTWluTWF4Qm94OTUoIGh3bmQsIHdQYXJhbSApOwkgICAgCglicmVhazsKCiAgICBjYXNlIEhUQ0xPU0U6CglpZiAoVFdFQUtfV2luZUxvb2sgPj0gV0lOOTVfTE9PSykKCSAgICBOQ19UcmFja0Nsb3NlQnV0dG9uOTUgKGh3bmQsIHdQYXJhbSk7CglicmVhazsKCQogICAgY2FzZSBIVExFRlQ6CiAgICBjYXNlIEhUUklHSFQ6CiAgICBjYXNlIEhUVE9QOgogICAgY2FzZSBIVFRPUExFRlQ6CiAgICBjYXNlIEhUVE9QUklHSFQ6CiAgICBjYXNlIEhUQk9UVE9NOgogICAgY2FzZSBIVEJPVFRPTUxFRlQ6CiAgICBjYXNlIEhUQk9UVE9NUklHSFQ6CgkvKiBtYWtlIHN1cmUgaGl0dGVzdCBmaXRzIGludG8gMHhmIGFuZCBkb2Vzbid0IG92ZXJsYXAgd2l0aCBIVFNZU01FTlUgKi8KCVNlbmRNZXNzYWdlMTYoIGh3bmQsIFdNX1NZU0NPTU1BTkQsIFNDX1NJWkUgKyB3UGFyYW0gLSAyLCBsUGFyYW0pOwoJYnJlYWs7CgogICAgY2FzZSBIVEJPUkRFUjoKCWJyZWFrOwogICAgfQogICAgcmV0dXJuIDA7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICAgICAgIE5DX0hhbmRsZU5DTEJ1dHRvbkRibENsawogKgogKiBIYW5kbGUgYSBXTV9OQ0xCVVRUT05EQkxDTEsgbWVzc2FnZS4gQ2FsbGVkIGZyb20gRGVmV2luZG93UHJvYygpLgogKi8KTE9ORyBOQ19IYW5kbGVOQ0xCdXR0b25EYmxDbGsoIFdORCAqcFduZCwgV1BBUkFNMTYgd1BhcmFtLCBMUEFSQU0gbFBhcmFtICkKewogICAgLyoKICAgICAqIGlmIHRoaXMgaXMgYW4gaWNvbiwgc2VuZCBhIHJlc3RvcmUgc2luY2Ugd2UgYXJlIGhhbmRsaW5nCiAgICAgKiBhIGRvdWJsZSBjbGljawogICAgICovCiAgICBpZiAocFduZC0+ZHdTdHlsZSAmIFdTX01JTklNSVpFKQogICAgewogICAgICAgIFNlbmRNZXNzYWdlMTYoIHBXbmQtPmh3bmRTZWxmLCBXTV9TWVNDT01NQU5ELCBTQ19SRVNUT1JFLCBsUGFyYW0gKTsKICAgICAgICByZXR1cm4gMDsKICAgIH0gCgogICAgc3dpdGNoKHdQYXJhbSkgIC8qIEhpdCB0ZXN0ICovCiAgICB7CiAgICBjYXNlIEhUQ0FQVElPTjoKICAgICAgICAvKiBzdG9wIHByb2Nlc3NpbmcgaWYgV1NfTUFYSU1JWkVCT1ggaXMgbWlzc2luZyAqLwogICAgICAgIGlmIChwV25kLT5kd1N0eWxlICYgV1NfTUFYSU1JWkVCT1gpCiAgICAgICAgICAgIFNlbmRNZXNzYWdlMTYoIHBXbmQtPmh3bmRTZWxmLCBXTV9TWVNDT01NQU5ELAogICAgICAgICAgICAgICAgICAgICAgKHBXbmQtPmR3U3R5bGUgJiBXU19NQVhJTUlaRSkgPyBTQ19SRVNUT1JFIDogU0NfTUFYSU1JWkUsCiAgICAgICAgICAgICAgICAgICAgICBsUGFyYW0gKTsKCWJyZWFrOwoKICAgIGNhc2UgSFRTWVNNRU5VOgogICAgICAgIGlmICghKEdldENsYXNzV29yZChwV25kLT5od25kU2VsZiwgR0NXX1NUWUxFKSAmIENTX05PQ0xPU0UpKQogICAgICAgICAgICBTZW5kTWVzc2FnZTE2KCBwV25kLT5od25kU2VsZiwgV01fU1lTQ09NTUFORCwgU0NfQ0xPU0UsIGxQYXJhbSApOwoJYnJlYWs7CgogICAgY2FzZSBIVEhTQ1JPTEw6CglTZW5kTWVzc2FnZTE2KCBwV25kLT5od25kU2VsZiwgV01fU1lTQ09NTUFORCwgU0NfSFNDUk9MTCArIEhUSFNDUk9MTCwKCQkgICAgICAgbFBhcmFtICk7CglicmVhazsKCiAgICBjYXNlIEhUVlNDUk9MTDoKCVNlbmRNZXNzYWdlMTYoIHBXbmQtPmh3bmRTZWxmLCBXTV9TWVNDT01NQU5ELCBTQ19WU0NST0xMICsgSFRWU0NST0xMLAoJCSAgICAgICBsUGFyYW0gKTsKCWJyZWFrOwogICAgfQogICAgcmV0dXJuIDA7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICAgICAgIE5DX0hhbmRsZVN5c0NvbW1hbmQKICoKICogSGFuZGxlIGEgV01fU1lTQ09NTUFORCBtZXNzYWdlLiBDYWxsZWQgZnJvbSBEZWZXaW5kb3dQcm9jKCkuCiAqLwpMT05HIE5DX0hhbmRsZVN5c0NvbW1hbmQoIEhXTkQgaHduZCwgV1BBUkFNIHdQYXJhbSwgUE9JTlQgcHQgKQp7CiAgICBXTkQgKnduZFB0ciA9IFdJTl9GaW5kV25kUHRyKCBod25kICk7CiAgICBVSU5UMTYgdUNvbW1hbmQgPSB3UGFyYW0gJiAweEZGRjA7CgogICAgVFJBQ0UoIkhhbmRsaW5nIFdNX1NZU0NPTU1BTkQgJXggJWxkLCVsZFxuIiwgd1BhcmFtLCBwdC54LCBwdC55ICk7CgogICAgaWYgKHduZFB0ci0+ZHdTdHlsZSAmIFdTX0NISUxEICYmIHVDb21tYW5kICE9IFNDX0tFWU1FTlUgKQogICAgICAgIFNjcmVlblRvQ2xpZW50KCB3bmRQdHItPnBhcmVudC0+aHduZFNlbGYsICZwdCApOwoKICAgIHN3aXRjaCAodUNvbW1hbmQpCiAgICB7CiAgICBjYXNlIFNDX1NJWkU6CiAgICBjYXNlIFNDX01PVkU6CglOQ19Eb1NpemVNb3ZlKCBod25kLCB3UGFyYW0gKTsKCWJyZWFrOwoKICAgIGNhc2UgU0NfTUlOSU1JWkU6CiAgICAgICAgaWYgKGh3bmQgPT0gR2V0Rm9yZWdyb3VuZFdpbmRvdygpKQogICAgICAgICAgICBTaG93T3duZWRQb3B1cHMoaHduZCxGQUxTRSk7CglTaG93V2luZG93KCBod25kLCBTV19NSU5JTUlaRSApOyAKCWJyZWFrOwoKICAgIGNhc2UgU0NfTUFYSU1JWkU6CiAgICAgICAgaWYgKElzSWNvbmljKGh3bmQpICYmIGh3bmQgPT0gR2V0Rm9yZWdyb3VuZFdpbmRvdygpKQogICAgICAgICAgICBTaG93T3duZWRQb3B1cHMoaHduZCxUUlVFKTsKCVNob3dXaW5kb3coIGh3bmQsIFNXX01BWElNSVpFICk7CglicmVhazsKCiAgICBjYXNlIFNDX1JFU1RPUkU6CiAgICAgICAgaWYgKElzSWNvbmljKGh3bmQpICYmIGh3bmQgPT0gR2V0Rm9yZWdyb3VuZFdpbmRvdygpKQogICAgICAgICAgICBTaG93T3duZWRQb3B1cHMoaHduZCxUUlVFKTsKCVNob3dXaW5kb3coIGh3bmQsIFNXX1JFU1RPUkUgKTsKCWJyZWFrOwoKICAgIGNhc2UgU0NfQ0xPU0U6CiAgICAgICAgV0lOX1JlbGVhc2VXbmRQdHIod25kUHRyKTsKCXJldHVybiBTZW5kTWVzc2FnZUEoIGh3bmQsIFdNX0NMT1NFLCAwLCAwICk7CgogICAgY2FzZSBTQ19WU0NST0xMOgogICAgY2FzZSBTQ19IU0NST0xMOgoJTkNfVHJhY2tTY3JvbGxCYXIoIGh3bmQsIHdQYXJhbSwgcHQgKTsKCWJyZWFrOwoKICAgIGNhc2UgU0NfTU9VU0VNRU5VOgogICAgICAgIE1FTlVfVHJhY2tNb3VzZU1lbnVCYXIoIHduZFB0ciwgd1BhcmFtICYgMHgwMDBGLCBwdCApOwoJYnJlYWs7CgogICAgY2FzZSBTQ19LRVlNRU5VOgoJTUVOVV9UcmFja0tiZE1lbnVCYXIoIHduZFB0ciAsIHdQYXJhbSAsIHB0LnggKTsKCWJyZWFrOwoJCiAgICBjYXNlIFNDX1RBU0tMSVNUOgoJV2luRXhlYyggInRhc2ttYW4uZXhlIiwgU1dfU0hPV05PUk1BTCApOyAKCWJyZWFrOwoKICAgIGNhc2UgU0NfU0NSRUVOU0FWRToKCWlmICh3UGFyYW0gPT0gU0NfQUJPVVRXSU5FKQogICAgICAgIHsKICAgICAgICAgICAgSE1PRFVMRSBobW9kdWxlID0gTG9hZExpYnJhcnlBKCAic2hlbGwzMi5kbGwiICk7CiAgICAgICAgICAgIGlmIChobW9kdWxlKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBGQVJQUk9DIGFib3V0cHJvYyA9IEdldFByb2NBZGRyZXNzKCBobW9kdWxlLCAiU2hlbGxBYm91dEEiICk7CiAgICAgICAgICAgICAgICBpZiAoYWJvdXRwcm9jKSBhYm91dHByb2MoIGh3bmQsICJXaW5lIiwgV0lORV9SRUxFQVNFX0lORk8sIDAgKTsKICAgICAgICAgICAgICAgIEZyZWVMaWJyYXJ5KCBobW9kdWxlICk7CiAgICAgICAgICAgIH0KICAgICAgICB9CgllbHNlIAoJICBpZiAod1BhcmFtID09IFNDX1BVVE1BUkspCiAgICAgICAgICAgIFRSQUNFXyhzaGVsbCkoIk1hcmsgcmVxdWVzdGVkIGJ5IHVzZXJcbiIpOwoJYnJlYWs7CiAgCiAgICBjYXNlIFNDX0hPVEtFWToKICAgIGNhc2UgU0NfQVJSQU5HRToKICAgIGNhc2UgU0NfTkVYVFdJTkRPVzoKICAgIGNhc2UgU0NfUFJFVldJTkRPVzoKIAlGSVhNRSgidW5pbXBsZW1lbnRlZCFcbiIpOwogICAgICAgIGJyZWFrOwogICAgfQogICAgV0lOX1JlbGVhc2VXbmRQdHIod25kUHRyKTsKICAgIHJldHVybiAwOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgoqICBOQ19EcmF3R3JheUJ1dHRvbgoqCiogU3R1YiBmb3IgdGhlIGdyYXllZCBidXR0b24gb2YgdGhlIGNhcHRpb24KKgoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwoKQk9PTCBOQ19EcmF3R3JheUJ1dHRvbihIREMgaGRjLCBpbnQgeCwgaW50IHkpCnsKICAgIEhCSVRNQVAgaE1hc2tCbXA7CiAgICBIREMgaGRjTWFzayA9IENyZWF0ZUNvbXBhdGlibGVEQyAoMCk7CiAgICBIQlJVU0ggaE9sZEJydXNoOwoKICAgIGhNYXNrQm1wID0gQ3JlYXRlQml0bWFwICgxMiwgMTAsIDEsIDEsIGxwR3JheU1hc2spOwogICAgCiAgICBpZihoTWFza0JtcCA9PSAwKQoJcmV0dXJuIEZBTFNFOwogICAgCiAgICBTZWxlY3RPYmplY3QgKGhkY01hc2ssIGhNYXNrQm1wKTsKICAgIAogICAgLyogRHJhdyB0aGUgZ3JheWVkIGJpdG1hcCB1c2luZyB0aGUgbWFzayAqLwogICAgaE9sZEJydXNoID0gU2VsZWN0T2JqZWN0IChoZGMsIFJHQigxMjgsIDEyOCwgMTI4KSk7CiAgICBCaXRCbHQgKGhkYywgeCwgeSwgMTIsIDEwLAoJICAgIGhkY01hc2ssIDAsIDAsIDB4QjgwNzRBKTsKICAgIAogICAgLyogQ2xlYW4gdXAgKi8KICAgIFNlbGVjdE9iamVjdCAoaGRjLCBoT2xkQnJ1c2gpOwogICAgRGVsZXRlT2JqZWN0KGhNYXNrQm1wKTsKICAgIERlbGV0ZURDIChoZGNNYXNrKTsKICAgIAogICAgcmV0dXJuIFRSVUU7Cn0KCkhJQ09OMTYgTkNfSWNvbkZvcldpbmRvdyhXTkQgKnduZFB0cikKewoJSElDT04xNiBoSWNvbiA9IChISUNPTikgR2V0Q2xhc3NMb25nQSh3bmRQdHItPmh3bmRTZWxmLCBHQ0xfSElDT05TTSk7CglpZighaEljb24pIGhJY29uID0gKEhJQ09OKSBHZXRDbGFzc0xvbmdBKHduZFB0ci0+aHduZFNlbGYsIEdDTF9ISUNPTik7CgoJLyogSWYgdGhlcmUgaXMgbm8gaEljb24gc3BlY2lmaWVkIGFuZCB0aGlzIGlzIGEgbW9kYWwgZGlhbG9nLCAqLyAKICAgICAgICAvKiBnZXQgdGhlIGRlZmF1bHQgb25lLiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICovCglpZiAoIWhJY29uICYmICh3bmRQdHItPmR3U3R5bGUgJiBEU19NT0RBTEZSQU1FKSkKCQloSWNvbiA9IExvYWRJbWFnZUEoMCwgTUFLRUlOVFJFU09VUkNFQShPSUNfV0lORUlDT04pLCBJTUFHRV9JQ09OLCAwLCAwLCBMUl9ERUZBVUxUQ09MT1IpOwoKCXJldHVybiBoSWNvbjsKfQo=