LyoKICogTm9uLWNsaWVudCBhcmVhIHdpbmRvdyBmdW5jdGlvbnMKICoKICogQ29weXJpZ2h0IDE5OTQgQWxleGFuZHJlIEp1bGxpYXJkCiAqCiAqIFRoaXMgbGlicmFyeSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IKICogbW9kaWZ5IGl0IHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpYwogKiBMaWNlbnNlIGFzIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uOyBlaXRoZXIKICogdmVyc2lvbiAyLjEgb2YgdGhlIExpY2Vuc2UsIG9yIChhdCB5b3VyIG9wdGlvbikgYW55IGxhdGVyIHZlcnNpb24uCiAqCiAqIFRoaXMgbGlicmFyeSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLAogKiBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZgogKiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVQogKiBMZXNzZXIgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBmb3IgbW9yZSBkZXRhaWxzLgogKgogKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljCiAqIExpY2Vuc2UgYWxvbmcgd2l0aCB0aGlzIGxpYnJhcnk7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUKICogRm91bmRhdGlvbiwgSW5jLiwgNTkgVGVtcGxlIFBsYWNlLCBTdWl0ZSAzMzAsIEJvc3RvbiwgTUEgIDAyMTExLTEzMDcgIFVTQQogKi8KCiNpbmNsdWRlICJjb25maWcuaCIKCiNpbmNsdWRlIDxzdGRhcmcuaD4KCiNpbmNsdWRlICJ3aW5kZWYuaCIKI2luY2x1ZGUgIndpbmJhc2UuaCIKI2luY2x1ZGUgIndpbmdkaS5oIgojaW5jbHVkZSAid2luZS93aW51c2VyMTYuaCIKI2luY2x1ZGUgIndvd250MzIuaCIKI2luY2x1ZGUgIndpbi5oIgojaW5jbHVkZSAidXNlci5oIgojaW5jbHVkZSAiZGNlLmgiCiNpbmNsdWRlICJjb250cm9scy5oIgojaW5jbHVkZSAiY3Vyc29yaWNvbi5oIgojaW5jbHVkZSAid2lucG9zLmgiCiNpbmNsdWRlICJub25jbGllbnQuaCIKI2luY2x1ZGUgInNoZWxsYXBpLmgiCiNpbmNsdWRlICJiaXRtYXAuaCIKI2luY2x1ZGUgIndpbmUvZGVidWcuaCIKCldJTkVfREVGQVVMVF9ERUJVR19DSEFOTkVMKG5vbmNsaWVudCk7CldJTkVfREVDTEFSRV9ERUJVR19DSEFOTkVMKHNoZWxsKTsKCkJPT0wgTkNfRHJhd0dyYXlCdXR0b24oSERDIGhkYywgaW50IHgsIGludCB5KTsKCnN0YXRpYyBIQklUTUFQIGhiaXRtYXBDbG9zZTsKCnN0YXRpYyBjb25zdCBCWVRFIGxwR3JheU1hc2tbXSA9IHsgMHhBQSwgMHhBMCwKCQkgICAgICAweDU1LCAweDUwLAoJCSAgICAgIDB4QUEsIDB4QTAsCgkJICAgICAgMHg1NSwgMHg1MCwKCQkgICAgICAweEFBLCAweEEwLAoJCSAgICAgIDB4NTUsIDB4NTAsCgkJICAgICAgMHhBQSwgMHhBMCwKCQkgICAgICAweDU1LCAweDUwLAoJCSAgICAgIDB4QUEsIDB4QTAsCgkJICAgICAgMHg1NSwgMHg1MH07CgojZGVmaW5lIFNDX0FCT1VUV0lORSAgICAJKFNDX1NDUkVFTlNBVkUrMSkKI2RlZmluZSBTQ19QVVRNQVJLICAgICAJCShTQ19TQ1JFRU5TQVZFKzIpCgogIC8qIFNvbWUgdXNlZnVsIG1hY3JvcyAqLwojZGVmaW5lIEhBU19ETEdGUkFNRShzdHlsZSxleFN0eWxlKSBcCiAgICAoKChleFN0eWxlKSAmIFdTX0VYX0RMR01PREFMRlJBTUUpIHx8IFwKICAgICAoKChzdHlsZSkgJiBXU19ETEdGUkFNRSkgJiYgISgoc3R5bGUpICYgV1NfVEhJQ0tGUkFNRSkpKQoKI2RlZmluZSBIQVNfVEhJQ0tGUkFNRShzdHlsZSxleFN0eWxlKSBcCiAgICAoKChzdHlsZSkgJiBXU19USElDS0ZSQU1FKSAmJiBcCiAgICAgISgoKHN0eWxlKSAmIChXU19ETEdGUkFNRXxXU19CT1JERVIpKSA9PSBXU19ETEdGUkFNRSkpCgojZGVmaW5lIEhBU19USElORlJBTUUoc3R5bGUpIFwKICAgICgoKHN0eWxlKSAmIFdTX0JPUkRFUikgfHwgISgoc3R5bGUpICYgKFdTX0NISUxEIHwgV1NfUE9QVVApKSkKCiNkZWZpbmUgSEFTX0JJR0ZSQU1FKHN0eWxlLGV4U3R5bGUpIFwKICAgICgoKHN0eWxlKSAmIChXU19USElDS0ZSQU1FIHwgV1NfRExHRlJBTUUpKSB8fCBcCiAgICAgKChleFN0eWxlKSAmIFdTX0VYX0RMR01PREFMRlJBTUUpKQoKI2RlZmluZSBIQVNfU1RBVElDT1VURVJGUkFNRShzdHlsZSxleFN0eWxlKSBcCiAgICAoKChleFN0eWxlKSAmIChXU19FWF9TVEFUSUNFREdFfFdTX0VYX0RMR01PREFMRlJBTUUpKSA9PSBcCiAgICAgV1NfRVhfU1RBVElDRURHRSkKCiNkZWZpbmUgSEFTX0FOWUZSQU1FKHN0eWxlLGV4U3R5bGUpIFwKICAgICgoKHN0eWxlKSAmIChXU19USElDS0ZSQU1FIHwgV1NfRExHRlJBTUUgfCBXU19CT1JERVIpKSB8fCBcCiAgICAgKChleFN0eWxlKSAmIFdTX0VYX0RMR01PREFMRlJBTUUpIHx8IFwKICAgICAhKChzdHlsZSkgJiAoV1NfQ0hJTEQgfCBXU19QT1BVUCkpKQoKI2RlZmluZSBIQVNfTUVOVSh3KSAgKCEoKHcpLT5kd1N0eWxlICYgV1NfQ0hJTEQpICYmICgodyktPndJRG1lbnUgIT0gMCkpCgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgICAgICBOQ19BZGp1c3RSZWN0CiAqCiAqIENvbXB1dGUgdGhlIHNpemUgb2YgdGhlIHdpbmRvdyByZWN0YW5nbGUgZnJvbSB0aGUgc2l6ZSBvZiB0aGUKICogY2xpZW50IHJlY3RhbmdsZS4KICovCnN0YXRpYyB2b2lkIE5DX0FkanVzdFJlY3QoIExQUkVDVCByZWN0LCBEV09SRCBzdHlsZSwgQk9PTCBtZW51LCBEV09SRCBleFN0eWxlICkKewogICAgaWYgKFRXRUFLX1dpbmVMb29rID4gV0lOMzFfTE9PSykKCUVSUigiQ2FsbGVkIGluIFdpbjk1IG1vZGUuIEFpZWUhIFBsZWFzZSByZXBvcnQgdGhpcy5cbiIgKTsKCiAgICBpZihzdHlsZSAmIFdTX0lDT05JQykgcmV0dXJuOwoKICAgIGlmIChIQVNfVEhJQ0tGUkFNRSggc3R5bGUsIGV4U3R5bGUgKSkKICAgICAgICBJbmZsYXRlUmVjdCggcmVjdCwgR2V0U3lzdGVtTWV0cmljcyhTTV9DWEZSQU1FKSwgR2V0U3lzdGVtTWV0cmljcyhTTV9DWUZSQU1FKSApOwogICAgZWxzZSBpZiAoSEFTX0RMR0ZSQU1FKCBzdHlsZSwgZXhTdHlsZSApKQogICAgICAgIEluZmxhdGVSZWN0KCByZWN0LCBHZXRTeXN0ZW1NZXRyaWNzKFNNX0NYRExHRlJBTUUpLCBHZXRTeXN0ZW1NZXRyaWNzKFNNX0NZRExHRlJBTUUpICk7CiAgICBlbHNlIGlmIChIQVNfVEhJTkZSQU1FKCBzdHlsZSApKQogICAgICAgIEluZmxhdGVSZWN0KCByZWN0LCBHZXRTeXN0ZW1NZXRyaWNzKFNNX0NYQk9SREVSKSwgR2V0U3lzdGVtTWV0cmljcyhTTV9DWUJPUkRFUikpOwoKICAgIGlmICgoc3R5bGUgJiBXU19DQVBUSU9OKSA9PSBXU19DQVBUSU9OKQogICAgICAgIHJlY3QtPnRvcCAtPSBHZXRTeXN0ZW1NZXRyaWNzKFNNX0NZQ0FQVElPTikgLSBHZXRTeXN0ZW1NZXRyaWNzKFNNX0NZQk9SREVSKTsKCiAgICBpZiAobWVudSkgcmVjdC0+dG9wIC09IEdldFN5c3RlbU1ldHJpY3MoU01fQ1lNRU5VKSArIEdldFN5c3RlbU1ldHJpY3MoU01fQ1lCT1JERVIpOwoKICAgIGlmIChzdHlsZSAmIFdTX1ZTQ1JPTEwpIHsKICAgICAgcmVjdC0+cmlnaHQgICs9IEdldFN5c3RlbU1ldHJpY3MoU01fQ1hWU0NST0xMKSAtIDE7CiAgICAgIGlmKCFIQVNfQU5ZRlJBTUUoIHN0eWxlLCBleFN0eWxlICkpCgkgcmVjdC0+cmlnaHQrKzsKICAgIH0KCiAgICBpZiAoc3R5bGUgJiBXU19IU0NST0xMKSB7CiAgICAgIHJlY3QtPmJvdHRvbSArPSBHZXRTeXN0ZW1NZXRyaWNzKFNNX0NZSFNDUk9MTCkgLSAxOwogICAgICBpZighSEFTX0FOWUZSQU1FKCBzdHlsZSwgZXhTdHlsZSApKQoJIHJlY3QtPmJvdHRvbSsrOwogICAgfQp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBOQ19BZGp1c3RSZWN0T3V0ZXI5NQogKgogKiBDb21wdXRlcyB0aGUgc2l6ZSBvZiB0aGUgIm91dHNpZGUiIHBhcnRzIG9mIHRoZSB3aW5kb3cgYmFzZWQgb24gdGhlCiAqIHBhcmFtZXRlcnMgb2YgdGhlIGNsaWVudCBhcmVhLgogKgogKyBQQVJBTVMKICogICAgIExQUkVDVDE2ICByZWN0CiAqICAgICBEV09SRCAgc3R5bGUKICogICAgIEJPT0wgIG1lbnUKICogICAgIERXT1JEICBleFN0eWxlCiAqCiAqIE5PVEVTCiAqICAgICAiT3V0ZXIiIHBhcnRzIG9mIGEgd2luZG93IG1lYW5zIHRoZSB3aG9sZSB3aW5kb3cgZnJhbWUsIGNhcHRpb24gYW5kCiAqICAgICBtZW51IGJhci4gSXQgZG9lcyBub3QgaW5jbHVkZSAiaW5uZXIiIHBhcnRzIG9mIHRoZSBmcmFtZSBsaWtlIGNsaWVudAogKiAgICAgZWRnZSwgc3RhdGljIGVkZ2Ugb3Igc2Nyb2xsIGJhcnMuCiAqCiAqIFJldmlzaW9uIGhpc3RvcnkKICogICAgIDA1LUp1bC0xOTk3IERhdmUgQ3V0aGJlcnQgKGRhY3V0QGVjZS5jbXUuZWR1KQogKiAgICAgICAgT3JpZ2luYWwgKE5DX0FkanVzdFJlY3Q5NSkgY3V0ICYgcGFzdGUgZnJvbSBOQ19BZGp1c3RSZWN0CiAqCiAqICAgICAyMC1KdW4tMTk5OCBFcmljIEtvaGwgKGVrb2hsQGFiby5yaGVpbi16ZWl0dW5nLmRlKQogKiAgICAgICAgU3BsaXQgTkNfQWRqdXN0UmVjdDk1IGludG8gTkNfQWRqdXN0UmVjdE91dGVyOTUgYW5kCiAqICAgICAgICBOQ19BZGp1c3RSZWN0SW5uZXI5NSBhbmQgYWRkZWQgaGFuZGxpbmcgb2YgV2luOTUgc3R5bGVzLgogKgogKiAgICAgMjgtSnVsLTE5OTkgT3ZlIEvldmVuIChvdmVrQGFyY3RpY25ldC5ubykKICogICAgICAgIFN0cmVhbWxpbmVkIHdpbmRvdyBzdHlsZSBjaGVja3MuCiAqCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KCnN0YXRpYyB2b2lkCk5DX0FkanVzdFJlY3RPdXRlcjk1IChMUFJFQ1QgcmVjdCwgRFdPUkQgc3R5bGUsIEJPT0wgbWVudSwgRFdPUkQgZXhTdHlsZSkKewogICAgaW50IGFkanVzdDsKICAgIGlmKHN0eWxlICYgV1NfSUNPTklDKSByZXR1cm47CgogICAgaWYgKChleFN0eWxlICYgKFdTX0VYX1NUQVRJQ0VER0V8V1NfRVhfRExHTU9EQUxGUkFNRSkpID09CiAgICAgICAgV1NfRVhfU1RBVElDRURHRSkKICAgIHsKICAgICAgICBhZGp1c3QgPSAxOyAvKiBmb3IgdGhlIG91dGVyIGZyYW1lIGFsd2F5cyBwcmVzZW50ICovCiAgICB9CiAgICBlbHNlCiAgICB7CiAgICAgICAgYWRqdXN0ID0gMDsKICAgICAgICBpZiAoKGV4U3R5bGUgJiBXU19FWF9ETEdNT0RBTEZSQU1FKSB8fAogICAgICAgICAgICAoc3R5bGUgJiAoV1NfVEhJQ0tGUkFNRXxXU19ETEdGUkFNRSkpKSBhZGp1c3QgPSAyOyAvKiBvdXRlciAqLwogICAgfQogICAgaWYgKHN0eWxlICYgV1NfVEhJQ0tGUkFNRSkKICAgICAgICBhZGp1c3QgKz0gICggR2V0U3lzdGVtTWV0cmljcyAoU01fQ1hGUkFNRSkKICAgICAgICAgICAgICAgICAgIC0gR2V0U3lzdGVtTWV0cmljcyAoU01fQ1hETEdGUkFNRSkpOyAvKiBUaGUgcmVzaXplIGJvcmRlciAqLwogICAgaWYgKChzdHlsZSAmIChXU19CT1JERVJ8V1NfRExHRlJBTUUpKSB8fAogICAgICAgIChleFN0eWxlICYgV1NfRVhfRExHTU9EQUxGUkFNRSkpCiAgICAgICAgYWRqdXN0Kys7IC8qIFRoZSBvdGhlciBib3JkZXIgKi8KCiAgICBJbmZsYXRlUmVjdCAocmVjdCwgYWRqdXN0LCBhZGp1c3QpOwoKICAgIGlmICgoc3R5bGUgJiBXU19DQVBUSU9OKSA9PSBXU19DQVBUSU9OKQogICAgewogICAgICAgIGlmIChleFN0eWxlICYgV1NfRVhfVE9PTFdJTkRPVykKICAgICAgICAgICAgcmVjdC0+dG9wIC09IEdldFN5c3RlbU1ldHJpY3MoU01fQ1lTTUNBUFRJT04pOwogICAgICAgIGVsc2UKICAgICAgICAgICAgcmVjdC0+dG9wIC09IEdldFN5c3RlbU1ldHJpY3MoU01fQ1lDQVBUSU9OKTsKICAgIH0KICAgIGlmIChtZW51KSByZWN0LT50b3AgLT0gR2V0U3lzdGVtTWV0cmljcyhTTV9DWU1FTlUpOwp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBOQ19BZGp1c3RSZWN0SW5uZXI5NQogKgogKiBDb21wdXRlcyB0aGUgc2l6ZSBvZiB0aGUgImluc2lkZSIgcGFydCBvZiB0aGUgd2luZG93IGJhc2VkIG9uIHRoZQogKiBwYXJhbWV0ZXJzIG9mIHRoZSBjbGllbnQgYXJlYS4KICoKICsgUEFSQU1TCiAqICAgICBMUFJFQ1QxNiByZWN0CiAqICAgICBEV09SRCAgICBzdHlsZQogKiAgICAgRFdPUkQgICAgZXhTdHlsZQogKgogKiBOT1RFUwogKiAgICAgIklubmVyIiBwYXJ0IG9mIGEgd2luZG93IG1lYW5zIHRoZSB3aW5kb3cgZnJhbWUgaW5zaWRlIG9mIHRoZSBmbGF0CiAqICAgICB3aW5kb3cgZnJhbWUuIEl0IGluY2x1ZGVzIHRoZSBjbGllbnQgZWRnZSwgdGhlIHN0YXRpYyBlZGdlIGFuZCB0aGUKICogICAgIHNjcm9sbCBiYXJzLgogKgogKiBSZXZpc2lvbiBoaXN0b3J5CiAqICAgICAwNS1KdWwtMTk5NyBEYXZlIEN1dGhiZXJ0IChkYWN1dEBlY2UuY211LmVkdSkKICogICAgICAgIE9yaWdpbmFsIChOQ19BZGp1c3RSZWN0OTUpIGN1dCAmIHBhc3RlIGZyb20gTkNfQWRqdXN0UmVjdAogKgogKiAgICAgMjAtSnVuLTE5OTggRXJpYyBLb2hsIChla29obEBhYm8ucmhlaW4temVpdHVuZy5kZSkKICogICAgICAgIFNwbGl0IE5DX0FkanVzdFJlY3Q5NSBpbnRvIE5DX0FkanVzdFJlY3RPdXRlcjk1IGFuZAogKiAgICAgICAgTkNfQWRqdXN0UmVjdElubmVyOTUgYW5kIGFkZGVkIGhhbmRsaW5nIG9mIFdpbjk1IHN0eWxlcy4KICoKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwoKc3RhdGljIHZvaWQKTkNfQWRqdXN0UmVjdElubmVyOTUgKExQUkVDVCByZWN0LCBEV09SRCBzdHlsZSwgRFdPUkQgZXhTdHlsZSkKewogICAgaWYoc3R5bGUgJiBXU19JQ09OSUMpIHJldHVybjsKCiAgICBpZiAoZXhTdHlsZSAmIFdTX0VYX0NMSUVOVEVER0UpCiAgICAgICAgSW5mbGF0ZVJlY3QocmVjdCwgR2V0U3lzdGVtTWV0cmljcyhTTV9DWEVER0UpLCBHZXRTeXN0ZW1NZXRyaWNzKFNNX0NZRURHRSkpOwoKICAgIGlmIChzdHlsZSAmIFdTX1ZTQ1JPTEwpCiAgICB7CiAgICAgICAgaWYoKGV4U3R5bGUgJiBXU19FWF9MRUZUU0NST0xMQkFSKSAhPSAwKQogICAgICAgICAgICByZWN0LT5sZWZ0ICAtPSBHZXRTeXN0ZW1NZXRyaWNzKFNNX0NYVlNDUk9MTCk7CiAgICAgICAgZWxzZQogICAgICAgICAgICByZWN0LT5yaWdodCArPSBHZXRTeXN0ZW1NZXRyaWNzKFNNX0NYVlNDUk9MTCk7CiAgICB9CiAgICBpZiAoc3R5bGUgJiBXU19IU0NST0xMKSByZWN0LT5ib3R0b20gKz0gR2V0U3lzdGVtTWV0cmljcyhTTV9DWUhTQ1JPTEwpOwp9CgoKCnN0YXRpYyBISUNPTiBOQ19JY29uRm9yV2luZG93KCBIV05EIGh3bmQgKQp7CiAgICBISUNPTiBoSWNvbiA9IDA7CiAgICBXTkQgKnduZFB0ciA9IFdJTl9HZXRQdHIoIGh3bmQgKTsKCiAgICBpZiAod25kUHRyICYmIHduZFB0ciAhPSBXTkRfT1RIRVJfUFJPQ0VTUykKICAgIHsKICAgICAgICBoSWNvbiA9IHduZFB0ci0+aEljb25TbWFsbDsKICAgICAgICBpZiAoIWhJY29uKSBoSWNvbiA9IHduZFB0ci0+aEljb247CiAgICAgICAgV0lOX1JlbGVhc2VQdHIoIHduZFB0ciApOwogICAgfQogICAgaWYgKCFoSWNvbikgaEljb24gPSAoSElDT04pIEdldENsYXNzTG9uZ0EoIGh3bmQsIEdDTF9ISUNPTlNNICk7CiAgICBpZiAoIWhJY29uKSBoSWNvbiA9IChISUNPTikgR2V0Q2xhc3NMb25nQSggaHduZCwgR0NMX0hJQ09OICk7CgogICAgLyogSWYgdGhlcmUgaXMgbm8gaEljb24gc3BlY2lmaWVkIGFuZCB0aGlzIGlzIGEgbW9kYWwgZGlhbG9nLAogICAgICogZ2V0IHRoZSBkZWZhdWx0IG9uZS4KICAgICAqLwogICAgaWYgKCFoSWNvbiAmJiAoR2V0V2luZG93TG9uZ0EoIGh3bmQsIEdXTF9TVFlMRSApICYgRFNfTU9EQUxGUkFNRSkpCiAgICAgICAgaEljb24gPSBMb2FkSW1hZ2VBKDAsIChMUFNUUilJRElfV0lOTE9HTywgSU1BR0VfSUNPTiwgMCwgMCwgTFJfREVGQVVMVENPTE9SKTsKICAgIHJldHVybiBoSWNvbjsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCQlEcmF3Q2FwdGlvbiAoVVNFUjMyLkApIERyYXdzIGEgY2FwdGlvbiBiYXIKICoKICogUEFSQU1TCiAqICAgICBod25kICAgW0ldCiAqICAgICBoZGMgICAgW0ldCiAqICAgICBscFJlY3QgW0ldCiAqICAgICB1RmxhZ3MgW0ldCiAqCiAqIFJFVFVSTlMKICogICAgIFN1Y2Nlc3M6CiAqICAgICBGYWlsdXJlOgogKi8KCkJPT0wgV0lOQVBJCkRyYXdDYXB0aW9uIChIV05EIGh3bmQsIEhEQyBoZGMsIGNvbnN0IFJFQ1QgKmxwUmVjdCwgVUlOVCB1RmxhZ3MpCnsKICAgIHJldHVybiBEcmF3Q2FwdGlvblRlbXBBIChod25kLCBoZGMsIGxwUmVjdCwgMCwgMCwgTlVMTCwgdUZsYWdzICYgMHgxRik7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCURyYXdDYXB0aW9uVGVtcEEgKFVTRVIzMi5AKQogKi8KQk9PTCBXSU5BUEkgRHJhd0NhcHRpb25UZW1wQSAoSFdORCBod25kLCBIREMgaGRjLCBjb25zdCBSRUNUICpyZWN0LCBIRk9OVCBoRm9udCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSElDT04gaEljb24sIExQQ1NUUiBzdHIsIFVJTlQgdUZsYWdzKQp7CiAgICBMUFdTVFIgc3RyVzsKICAgIElOVCBsZW47CiAgICBCT09MIHJldCA9IEZBTFNFOwoKICAgIGlmICghKHVGbGFncyAmIERDX1RFWFQpIHx8ICFzdHIpCiAgICAgICAgcmV0dXJuIERyYXdDYXB0aW9uVGVtcFcoIGh3bmQsIGhkYywgcmVjdCwgaEZvbnQsIGhJY29uLCBOVUxMLCB1RmxhZ3MgKTsKCiAgICBsZW4gPSBNdWx0aUJ5dGVUb1dpZGVDaGFyKCBDUF9BQ1AsIDAsIHN0ciwgLTEsIE5VTEwsIDAgKTsKICAgIGlmICgoc3RyVyA9IEhlYXBBbGxvYyggR2V0UHJvY2Vzc0hlYXAoKSwgMCwgbGVuICogc2l6ZW9mKFdDSEFSKSApKSkKICAgIHsKICAgICAgICBNdWx0aUJ5dGVUb1dpZGVDaGFyKCBDUF9BQ1AsIDAsIHN0ciwgLTEsIHN0clcsIGxlbiApOwogICAgICAgIHJldCA9IERyYXdDYXB0aW9uVGVtcFcgKGh3bmQsIGhkYywgcmVjdCwgaEZvbnQsIGhJY29uLCBzdHJXLCB1RmxhZ3MpOwogICAgICAgIEhlYXBGcmVlKCBHZXRQcm9jZXNzSGVhcCAoKSwgMCwgc3RyVyApOwogICAgfQogICAgcmV0dXJuIHJldDsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJRHJhd0NhcHRpb25UZW1wVyAoVVNFUjMyLkApCiAqLwpCT09MIFdJTkFQSSBEcmF3Q2FwdGlvblRlbXBXIChIV05EIGh3bmQsIEhEQyBoZGMsIGNvbnN0IFJFQ1QgKnJlY3QsIEhGT05UIGhGb250LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBISUNPTiBoSWNvbiwgTFBDV1NUUiBzdHIsIFVJTlQgdUZsYWdzKQp7CiAgICBSRUNUICAgcmMgPSAqcmVjdDsKCiAgICBUUkFDRSgiKCVwLCVwLCVwLCVwLCVwLCVzLCUwOHgpXG4iLAogICAgICAgICAgaHduZCwgaGRjLCByZWN0LCBoRm9udCwgaEljb24sIGRlYnVnc3RyX3coc3RyKSwgdUZsYWdzKTsKCiAgICAvKiBkcmF3aW5nIGJhY2tncm91bmQgKi8KICAgIGlmICh1RmxhZ3MgJiBEQ19JTkJVVFRPTikgewoJRmlsbFJlY3QgKGhkYywgJnJjLCBHZXRTeXNDb2xvckJydXNoIChDT0xPUl8zREZBQ0UpKTsKCglpZiAodUZsYWdzICYgRENfQUNUSVZFKSB7CgkgICAgSEJSVVNIIGhiciA9IFNlbGVjdE9iamVjdCAoaGRjLCBDQUNIRV9HZXRQYXR0ZXJuNTVBQUJydXNoICgpKTsKCSAgICBQYXRCbHQgKGhkYywgcmMubGVmdCwgcmMudG9wLAoJCSAgICAgIHJjLnJpZ2h0LXJjLmxlZnQsIHJjLmJvdHRvbS1yYy50b3AsIDB4RkEwMDg5KTsKCSAgICBTZWxlY3RPYmplY3QgKGhkYywgaGJyKTsKCX0KICAgIH0KICAgIGVsc2UgewoJRmlsbFJlY3QgKGhkYywgJnJjLCBHZXRTeXNDb2xvckJydXNoICgodUZsYWdzICYgRENfQUNUSVZFKSA/CgkJICAgIENPTE9SX0FDVElWRUNBUFRJT04gOiBDT0xPUl9JTkFDVElWRUNBUFRJT04pKTsKICAgIH0KCgogICAgLyogZHJhd2luZyBpY29uICovCiAgICBpZiAoKHVGbGFncyAmIERDX0lDT04pICYmICEodUZsYWdzICYgRENfU01BTExDQVApKSB7CglQT0lOVCBwdDsKCglwdC54ID0gcmMubGVmdCArIDI7CglwdC55ID0gKHJjLmJvdHRvbSArIHJjLnRvcCAtIEdldFN5c3RlbU1ldHJpY3MoU01fQ1lTTUlDT04pKSAvIDI7CgogICAgICAgIGlmICghaEljb24pIGhJY29uID0gTkNfSWNvbkZvcldpbmRvdyhod25kKTsKICAgICAgICBEcmF3SWNvbkV4IChoZGMsIHB0LngsIHB0LnksIGhJY29uLCBHZXRTeXN0ZW1NZXRyaWNzKFNNX0NYU01JQ09OKSwKICAgICAgICAgICAgICAgICAgICBHZXRTeXN0ZW1NZXRyaWNzKFNNX0NZU01JQ09OKSwgMCwgMCwgRElfTk9STUFMKTsKCXJjLmxlZnQgKz0gKHJjLmJvdHRvbSAtIHJjLnRvcCk7CiAgICB9CgogICAgLyogZHJhd2luZyB0ZXh0ICovCiAgICBpZiAodUZsYWdzICYgRENfVEVYVCkgewoJSEZPTlQgaE9sZEZvbnQ7CgoJaWYgKHVGbGFncyAmIERDX0lOQlVUVE9OKQoJICAgIFNldFRleHRDb2xvciAoaGRjLCBHZXRTeXNDb2xvciAoQ09MT1JfQlROVEVYVCkpOwoJZWxzZSBpZiAodUZsYWdzICYgRENfQUNUSVZFKQoJICAgIFNldFRleHRDb2xvciAoaGRjLCBHZXRTeXNDb2xvciAoQ09MT1JfQ0FQVElPTlRFWFQpKTsKCWVsc2UKCSAgICBTZXRUZXh0Q29sb3IgKGhkYywgR2V0U3lzQ29sb3IgKENPTE9SX0lOQUNUSVZFQ0FQVElPTlRFWFQpKTsKCglTZXRCa01vZGUgKGhkYywgVFJBTlNQQVJFTlQpOwoKCWlmIChoRm9udCkKCSAgICBoT2xkRm9udCA9IFNlbGVjdE9iamVjdCAoaGRjLCBoRm9udCk7CgllbHNlIHsKCSAgICBOT05DTElFTlRNRVRSSUNTVyBuY2xtOwoJICAgIEhGT05UIGhOZXdGb250OwoJICAgIG5jbG0uY2JTaXplID0gc2l6ZW9mKE5PTkNMSUVOVE1FVFJJQ1NXKTsKCSAgICBTeXN0ZW1QYXJhbWV0ZXJzSW5mb1cgKFNQSV9HRVROT05DTElFTlRNRVRSSUNTLCAwLCAmbmNsbSwgMCk7CgkgICAgaE5ld0ZvbnQgPSBDcmVhdGVGb250SW5kaXJlY3RXICgodUZsYWdzICYgRENfU01BTExDQVApID8KCQkmbmNsbS5sZlNtQ2FwdGlvbkZvbnQgOiAmbmNsbS5sZkNhcHRpb25Gb250KTsKCSAgICBoT2xkRm9udCA9IFNlbGVjdE9iamVjdCAoaGRjLCBoTmV3Rm9udCk7Cgl9CgoJaWYgKHN0cikKCSAgICBEcmF3VGV4dFcgKGhkYywgc3RyLCAtMSwgJnJjLAoJCQkgRFRfU0lOR0xFTElORSB8IERUX1ZDRU5URVIgfCBEVF9OT1BSRUZJWCB8IERUX0xFRlQpOwoJZWxzZSB7CgkgICAgV0NIQVIgc3pUZXh0WzEyOF07CgkgICAgSU5UIG5MZW47CgkgICAgbkxlbiA9IEdldFdpbmRvd1RleHRXIChod25kLCBzelRleHQsIDEyOCk7CgkgICAgRHJhd1RleHRXIChoZGMsIHN6VGV4dCwgbkxlbiwgJnJjLAoJCQkgRFRfU0lOR0xFTElORSB8IERUX1ZDRU5URVIgfCBEVF9OT1BSRUZJWCB8IERUX0xFRlQpOwoJfQoKCWlmIChoRm9udCkKCSAgICBTZWxlY3RPYmplY3QgKGhkYywgaE9sZEZvbnQpOwoJZWxzZQoJICAgIERlbGV0ZU9iamVjdCAoU2VsZWN0T2JqZWN0IChoZGMsIGhPbGRGb250KSk7CiAgICB9CgogICAgLyogZHJhd2luZyBmb2N1cyA/Pz8gKi8KICAgIGlmICh1RmxhZ3MgJiAweDIwMDApCglGSVhNRSgidW5kb2N1bWVudGVkIGZsYWcgKDB4MjAwMCkhXG4iKTsKCiAgICByZXR1cm4gMDsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJQWRqdXN0V2luZG93UmVjdCAoVVNFUi4xMDIpCiAqLwpCT09MMTYgV0lOQVBJIEFkanVzdFdpbmRvd1JlY3QxNiggTFBSRUNUMTYgcmVjdCwgRFdPUkQgc3R5bGUsIEJPT0wxNiBtZW51ICkKewogICAgcmV0dXJuIEFkanVzdFdpbmRvd1JlY3RFeDE2KCByZWN0LCBzdHlsZSwgbWVudSwgMCApOwp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCQlBZGp1c3RXaW5kb3dSZWN0IChVU0VSMzIuQCkKICovCkJPT0wgV0lOQVBJIEFkanVzdFdpbmRvd1JlY3QoIExQUkVDVCByZWN0LCBEV09SRCBzdHlsZSwgQk9PTCBtZW51ICkKewogICAgcmV0dXJuIEFkanVzdFdpbmRvd1JlY3RFeCggcmVjdCwgc3R5bGUsIG1lbnUsIDAgKTsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJQWRqdXN0V2luZG93UmVjdEV4IChVU0VSLjQ1NCkKICovCkJPT0wxNiBXSU5BUEkgQWRqdXN0V2luZG93UmVjdEV4MTYoIExQUkVDVDE2IHJlY3QsIERXT1JEIHN0eWxlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBCT09MMTYgbWVudSwgRFdPUkQgZXhTdHlsZSApCnsKICAgIFJFQ1QgcmVjdDMyOwogICAgQk9PTCByZXQ7CgogICAgQ09OVl9SRUNUMTZUTzMyKCByZWN0LCAmcmVjdDMyICk7CiAgICByZXQgPSBBZGp1c3RXaW5kb3dSZWN0RXgoICZyZWN0MzIsIHN0eWxlLCBtZW51LCBleFN0eWxlICk7CiAgICBDT05WX1JFQ1QzMlRPMTYoICZyZWN0MzIsIHJlY3QgKTsKICAgIHJldHVybiByZXQ7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCUFkanVzdFdpbmRvd1JlY3RFeCAoVVNFUjMyLkApCiAqLwpCT09MIFdJTkFQSSBBZGp1c3RXaW5kb3dSZWN0RXgoIExQUkVDVCByZWN0LCBEV09SRCBzdHlsZSwgQk9PTCBtZW51LCBEV09SRCBleFN0eWxlICkKewogICAgLyogQ29ycmVjdCB0aGUgd2luZG93IHN0eWxlICovCiAgICBzdHlsZSAmPSAoV1NfRExHRlJBTUUgfCBXU19CT1JERVIgfCBXU19USElDS0ZSQU1FIHwgV1NfQ0hJTEQpOwogICAgZXhTdHlsZSAmPSAoV1NfRVhfRExHTU9EQUxGUkFNRSB8IFdTX0VYX0NMSUVOVEVER0UgfAogICAgICAgICAgICAgICAgV1NfRVhfU1RBVElDRURHRSB8IFdTX0VYX1RPT0xXSU5ET1cpOwogICAgaWYgKGV4U3R5bGUgJiBXU19FWF9ETEdNT0RBTEZSQU1FKSBzdHlsZSAmPSB+V1NfVEhJQ0tGUkFNRTsKCiAgICBUUkFDRSgiKCVsZCwlbGQpLSglbGQsJWxkKSAlMDhseCAlZCAlMDhseFxuIiwKICAgICAgICAgIHJlY3QtPmxlZnQsIHJlY3QtPnRvcCwgcmVjdC0+cmlnaHQsIHJlY3QtPmJvdHRvbSwKICAgICAgICAgIHN0eWxlLCBtZW51LCBleFN0eWxlICk7CgogICAgaWYgKFRXRUFLX1dpbmVMb29rID09IFdJTjMxX0xPT0spCiAgICAgICAgTkNfQWRqdXN0UmVjdCggcmVjdCwgc3R5bGUsIG1lbnUsIGV4U3R5bGUgKTsKICAgIGVsc2UKICAgIHsKICAgICAgICBOQ19BZGp1c3RSZWN0T3V0ZXI5NSggcmVjdCwgc3R5bGUsIG1lbnUsIGV4U3R5bGUgKTsKICAgICAgICBOQ19BZGp1c3RSZWN0SW5uZXI5NSggcmVjdCwgc3R5bGUsIGV4U3R5bGUgKTsKICAgIH0KICAgIHJldHVybiBUUlVFOwp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgICAgICBOQ19IYW5kbGVOQ0NhbGNTaXplCiAqCiAqIEhhbmRsZSBhIFdNX05DQ0FMQ1NJWkUgbWVzc2FnZS4gQ2FsbGVkIGZyb20gRGVmV2luZG93UHJvYygpLgogKi8KTE9ORyBOQ19IYW5kbGVOQ0NhbGNTaXplKCBIV05EIGh3bmQsIFJFQ1QgKndpblJlY3QgKQp7CiAgICBSRUNUIHRtcFJlY3QgPSB7IDAsIDAsIDAsIDAgfTsKICAgIExPTkcgcmVzdWx0ID0gMDsKICAgIExPTkcgY2xzX3N0eWxlID0gR2V0Q2xhc3NMb25nQShod25kLCBHQ0xfU1RZTEUpOwogICAgTE9ORyBzdHlsZSA9IEdldFdpbmRvd0xvbmdBKCBod25kLCBHV0xfU1RZTEUgKTsKICAgIExPTkcgZXhTdHlsZSA9IEdldFdpbmRvd0xvbmdBKCBod25kLCBHV0xfRVhTVFlMRSApOwoKICAgIGlmIChjbHNfc3R5bGUgJiBDU19WUkVEUkFXKSByZXN1bHQgfD0gV1ZSX1ZSRURSQVc7CiAgICBpZiAoY2xzX3N0eWxlICYgQ1NfSFJFRFJBVykgcmVzdWx0IHw9IFdWUl9IUkVEUkFXOwoKICAgIGlmICghSXNJY29uaWMoaHduZCkpCiAgICB7CglpZiAoVFdFQUtfV2luZUxvb2sgPT0gV0lOMzFfTE9PSykKCSAgICBOQ19BZGp1c3RSZWN0KCAmdG1wUmVjdCwgc3R5bGUsIEZBTFNFLCBleFN0eWxlICk7CgllbHNlCgkgICAgTkNfQWRqdXN0UmVjdE91dGVyOTUoICZ0bXBSZWN0LCBzdHlsZSwgRkFMU0UsIGV4U3R5bGUgKTsKCgl3aW5SZWN0LT5sZWZ0ICAgLT0gdG1wUmVjdC5sZWZ0OwoJd2luUmVjdC0+dG9wICAgIC09IHRtcFJlY3QudG9wOwoJd2luUmVjdC0+cmlnaHQgIC09IHRtcFJlY3QucmlnaHQ7Cgl3aW5SZWN0LT5ib3R0b20gLT0gdG1wUmVjdC5ib3R0b207CgogICAgICAgIGlmICghKHN0eWxlICYgV1NfQ0hJTEQpICYmIEdldE1lbnUoaHduZCkpCiAgICAgICAgewogICAgICAgICAgICBUUkFDRSgiQ2FsbGluZyBHZXRNZW51QmFySGVpZ2h0IHdpdGggaHduZCAlcCwgd2lkdGggJWxkLCBhdCAoJWxkLCAlbGQpLlxuIiwKICAgICAgICAgICAgICAgICAgaHduZCwgd2luUmVjdC0+cmlnaHQgLSB3aW5SZWN0LT5sZWZ0LCAtdG1wUmVjdC5sZWZ0LCAtdG1wUmVjdC50b3AgKTsKCgkgICAgd2luUmVjdC0+dG9wICs9CgkJTUVOVV9HZXRNZW51QmFySGVpZ2h0KCBod25kLAoJCQkJICAgICAgIHdpblJlY3QtPnJpZ2h0IC0gd2luUmVjdC0+bGVmdCwKCQkJCSAgICAgICAtdG1wUmVjdC5sZWZ0LCAtdG1wUmVjdC50b3AgKSArIDE7Cgl9CgoJaWYgKFRXRUFLX1dpbmVMb29rID4gV0lOMzFfTE9PSykgewoJICAgIFNldFJlY3QoJnRtcFJlY3QsIDAsIDAsIDAsIDApOwoJICAgIE5DX0FkanVzdFJlY3RJbm5lcjk1ICgmdG1wUmVjdCwgc3R5bGUsIGV4U3R5bGUpOwoJICAgIHdpblJlY3QtPmxlZnQgICAtPSB0bXBSZWN0LmxlZnQ7CgkgICAgd2luUmVjdC0+dG9wICAgIC09IHRtcFJlY3QudG9wOwoJICAgIHdpblJlY3QtPnJpZ2h0ICAtPSB0bXBSZWN0LnJpZ2h0OwoJICAgIHdpblJlY3QtPmJvdHRvbSAtPSB0bXBSZWN0LmJvdHRvbTsKCX0KCiAgICAgICAgaWYgKHdpblJlY3QtPnRvcCA+IHdpblJlY3QtPmJvdHRvbSkKICAgICAgICAgICAgd2luUmVjdC0+Ym90dG9tID0gd2luUmVjdC0+dG9wOwoKICAgICAgICBpZiAod2luUmVjdC0+bGVmdCA+IHdpblJlY3QtPnJpZ2h0KQogICAgICAgICAgICB3aW5SZWN0LT5yaWdodCA9IHdpblJlY3QtPmxlZnQ7CiAgICB9CiAgICByZXR1cm4gcmVzdWx0Owp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgICAgICBOQ19HZXRJbnNpZGVSZWN0CiAqCiAqIEdldCB0aGUgJ2luc2lkZScgcmVjdGFuZ2xlIG9mIGEgd2luZG93LCBpLmUuIHRoZSB3aG9sZSB3aW5kb3cgcmVjdGFuZ2xlCiAqIGJ1dCB3aXRob3V0IHRoZSBib3JkZXJzIChpZiBhbnkpLgogKiBUaGUgcmVjdGFuZ2xlIGlzIGluIHdpbmRvdyBjb29yZGluYXRlcyAoZm9yIGRyYXdpbmcgd2l0aCBHZXRXaW5kb3dEQygpKS4KICovCnZvaWQgTkNfR2V0SW5zaWRlUmVjdCggSFdORCBod25kLCBSRUNUICpyZWN0ICkKewogICAgV05EICogd25kUHRyID0gV0lOX0ZpbmRXbmRQdHIoIGh3bmQgKTsKCiAgICByZWN0LT50b3AgICAgPSByZWN0LT5sZWZ0ID0gMDsKICAgIHJlY3QtPnJpZ2h0ICA9IHduZFB0ci0+cmVjdFdpbmRvdy5yaWdodCAtIHduZFB0ci0+cmVjdFdpbmRvdy5sZWZ0OwogICAgcmVjdC0+Ym90dG9tID0gd25kUHRyLT5yZWN0V2luZG93LmJvdHRvbSAtIHduZFB0ci0+cmVjdFdpbmRvdy50b3A7CgogICAgaWYgKHduZFB0ci0+ZHdTdHlsZSAmIFdTX0lDT05JQykgZ290byBFTkQ7CgogICAgLyogUmVtb3ZlIGZyYW1lIGZyb20gcmVjdGFuZ2xlICovCiAgICBpZiAoSEFTX1RISUNLRlJBTUUoIHduZFB0ci0+ZHdTdHlsZSwgd25kUHRyLT5kd0V4U3R5bGUgKSkKICAgIHsKICAgICAgICBJbmZsYXRlUmVjdCggcmVjdCwgLUdldFN5c3RlbU1ldHJpY3MoU01fQ1hGUkFNRSksIC1HZXRTeXN0ZW1NZXRyaWNzKFNNX0NZRlJBTUUpICk7CiAgICB9CiAgICBlbHNlIGlmIChIQVNfRExHRlJBTUUoIHduZFB0ci0+ZHdTdHlsZSwgd25kUHRyLT5kd0V4U3R5bGUgKSkKICAgIHsKICAgICAgICBJbmZsYXRlUmVjdCggcmVjdCwgLUdldFN5c3RlbU1ldHJpY3MoU01fQ1hETEdGUkFNRSksIC1HZXRTeXN0ZW1NZXRyaWNzKFNNX0NZRExHRlJBTUUpKTsKICAgICAgICAvKiBGSVhNRTogdGhpcyBpc24ndCBpbiBOQ19BZGp1c3RSZWN0PyB3aHkgbm90PyAqLwogICAgICAgIGlmICgoVFdFQUtfV2luZUxvb2sgPT0gV0lOMzFfTE9PSykgJiYgKHduZFB0ci0+ZHdFeFN0eWxlICYgV1NfRVhfRExHTU9EQUxGUkFNRSkpCiAgICAgICAgICAgIEluZmxhdGVSZWN0KCByZWN0LCAtMSwgMCApOwogICAgfQogICAgZWxzZSBpZiAoSEFTX1RISU5GUkFNRSggd25kUHRyLT5kd1N0eWxlICkpCiAgICB7CiAgICAgICAgSW5mbGF0ZVJlY3QoIHJlY3QsIC1HZXRTeXN0ZW1NZXRyaWNzKFNNX0NYQk9SREVSKSwgLUdldFN5c3RlbU1ldHJpY3MoU01fQ1lCT1JERVIpICk7CiAgICB9CgogICAgLyogV2UgaGF2ZSBhZGRpdGlvbmFsIGJvcmRlciBpbmZvcm1hdGlvbiBpZiB0aGUgd2luZG93CiAgICAgKiBpcyBhIGNoaWxkIChidXQgbm90IGFuIE1ESSBjaGlsZCkgKi8KICAgIGlmIChUV0VBS19XaW5lTG9vayAhPSBXSU4zMV9MT09LKQogICAgewogICAgICAgIGlmICggKHduZFB0ci0+ZHdTdHlsZSAmIFdTX0NISUxEKSAgJiYKICAgICAgICAgICAgICggKHduZFB0ci0+ZHdFeFN0eWxlICYgV1NfRVhfTURJQ0hJTEQpID09IDAgKSApCiAgICAgICAgewogICAgICAgICAgICBpZiAod25kUHRyLT5kd0V4U3R5bGUgJiBXU19FWF9DTElFTlRFREdFKQogICAgICAgICAgICAgICAgSW5mbGF0ZVJlY3QgKHJlY3QsIC1HZXRTeXN0ZW1NZXRyaWNzKFNNX0NYRURHRSksIC1HZXRTeXN0ZW1NZXRyaWNzKFNNX0NZRURHRSkpOwogICAgICAgICAgICBpZiAod25kUHRyLT5kd0V4U3R5bGUgJiBXU19FWF9TVEFUSUNFREdFKQogICAgICAgICAgICAgICAgSW5mbGF0ZVJlY3QgKHJlY3QsIC1HZXRTeXN0ZW1NZXRyaWNzKFNNX0NYQk9SREVSKSwgLUdldFN5c3RlbU1ldHJpY3MoU01fQ1lCT1JERVIpKTsKICAgICAgICB9CiAgICB9CgpFTkQ6CiAgICBXSU5fUmVsZWFzZVduZFB0cih3bmRQdHIpOwogICAgcmV0dXJuOwp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIE5DX0RvTkNIaXRUZXN0CiAqCiAqIEhhbmRsZSBhIFdNX05DSElUVEVTVCBtZXNzYWdlLiBDYWxsZWQgZnJvbSBOQ19IYW5kbGVOQ0hpdFRlc3QoKS4KICovCgpzdGF0aWMgTE9ORyBOQ19Eb05DSGl0VGVzdCAoV05EICp3bmRQdHIsIFBPSU5UIHB0ICkKewogICAgUkVDVCByZWN0OwoKICAgIFRSQUNFKCJod25kPSVwIHB0PSVsZCwlbGRcbiIsIHduZFB0ci0+aHduZFNlbGYsIHB0LngsIHB0LnkgKTsKCiAgICBHZXRXaW5kb3dSZWN0KHduZFB0ci0+aHduZFNlbGYsICZyZWN0ICk7CiAgICBpZiAoIVB0SW5SZWN0KCAmcmVjdCwgcHQgKSkgcmV0dXJuIEhUTk9XSEVSRTsKCiAgICBpZiAod25kUHRyLT5kd1N0eWxlICYgV1NfTUlOSU1JWkUpIHJldHVybiBIVENBUFRJT047CgogICAgLyogQ2hlY2sgYm9yZGVycyAqLwogICAgaWYgKEhBU19USElDS0ZSQU1FKCB3bmRQdHItPmR3U3R5bGUsIHduZFB0ci0+ZHdFeFN0eWxlICkpCiAgICB7CiAgICAgICAgSW5mbGF0ZVJlY3QoICZyZWN0LCAtR2V0U3lzdGVtTWV0cmljcyhTTV9DWEZSQU1FKSwgLUdldFN5c3RlbU1ldHJpY3MoU01fQ1lGUkFNRSkgKTsKICAgICAgICBpZiAoIVB0SW5SZWN0KCAmcmVjdCwgcHQgKSkKICAgICAgICB7CiAgICAgICAgICAgIC8qIENoZWNrIHRvcCBzaXppbmcgYm9yZGVyICovCiAgICAgICAgICAgIGlmIChwdC55IDwgcmVjdC50b3ApCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGlmIChwdC54IDwgcmVjdC5sZWZ0K0dldFN5c3RlbU1ldHJpY3MoU01fQ1hTSVpFKSkgcmV0dXJuIEhUVE9QTEVGVDsKICAgICAgICAgICAgICAgIGlmIChwdC54ID49IHJlY3QucmlnaHQtR2V0U3lzdGVtTWV0cmljcyhTTV9DWFNJWkUpKSByZXR1cm4gSFRUT1BSSUdIVDsKICAgICAgICAgICAgICAgIHJldHVybiBIVFRPUDsKICAgICAgICAgICAgfQogICAgICAgICAgICAvKiBDaGVjayBib3R0b20gc2l6aW5nIGJvcmRlciAqLwogICAgICAgICAgICBpZiAocHQueSA+PSByZWN0LmJvdHRvbSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgaWYgKHB0LnggPCByZWN0LmxlZnQrR2V0U3lzdGVtTWV0cmljcyhTTV9DWFNJWkUpKSByZXR1cm4gSFRCT1RUT01MRUZUOwogICAgICAgICAgICAgICAgaWYgKHB0LnggPj0gcmVjdC5yaWdodC1HZXRTeXN0ZW1NZXRyaWNzKFNNX0NYU0laRSkpIHJldHVybiBIVEJPVFRPTVJJR0hUOwogICAgICAgICAgICAgICAgcmV0dXJuIEhUQk9UVE9NOwogICAgICAgICAgICB9CiAgICAgICAgICAgIC8qIENoZWNrIGxlZnQgc2l6aW5nIGJvcmRlciAqLwogICAgICAgICAgICBpZiAocHQueCA8IHJlY3QubGVmdCkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgaWYgKHB0LnkgPCByZWN0LnRvcCtHZXRTeXN0ZW1NZXRyaWNzKFNNX0NZU0laRSkpIHJldHVybiBIVFRPUExFRlQ7CiAgICAgICAgICAgICAgICBpZiAocHQueSA+PSByZWN0LmJvdHRvbS1HZXRTeXN0ZW1NZXRyaWNzKFNNX0NZU0laRSkpIHJldHVybiBIVEJPVFRPTUxFRlQ7CiAgICAgICAgICAgICAgICByZXR1cm4gSFRMRUZUOwogICAgICAgICAgICB9CiAgICAgICAgICAgIC8qIENoZWNrIHJpZ2h0IHNpemluZyBib3JkZXIgKi8KICAgICAgICAgICAgaWYgKHB0LnggPj0gcmVjdC5yaWdodCkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgaWYgKHB0LnkgPCByZWN0LnRvcCtHZXRTeXN0ZW1NZXRyaWNzKFNNX0NZU0laRSkpIHJldHVybiBIVFRPUFJJR0hUOwogICAgICAgICAgICAgICAgaWYgKHB0LnkgPj0gcmVjdC5ib3R0b20tR2V0U3lzdGVtTWV0cmljcyhTTV9DWVNJWkUpKSByZXR1cm4gSFRCT1RUT01SSUdIVDsKICAgICAgICAgICAgICAgIHJldHVybiBIVFJJR0hUOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfQogICAgZWxzZSAgLyogTm8gdGhpY2sgZnJhbWUgKi8KICAgIHsKICAgICAgICBpZiAoSEFTX0RMR0ZSQU1FKCB3bmRQdHItPmR3U3R5bGUsIHduZFB0ci0+ZHdFeFN0eWxlICkpCiAgICAgICAgICAgIEluZmxhdGVSZWN0KCZyZWN0LCAtR2V0U3lzdGVtTWV0cmljcyhTTV9DWERMR0ZSQU1FKSwgLUdldFN5c3RlbU1ldHJpY3MoU01fQ1lETEdGUkFNRSkpOwogICAgICAgIGVsc2UgaWYgKEhBU19USElORlJBTUUoIHduZFB0ci0+ZHdTdHlsZSApKQogICAgICAgICAgICBJbmZsYXRlUmVjdCgmcmVjdCwgLUdldFN5c3RlbU1ldHJpY3MoU01fQ1hCT1JERVIpLCAtR2V0U3lzdGVtTWV0cmljcyhTTV9DWUJPUkRFUikpOwogICAgICAgIGlmICghUHRJblJlY3QoICZyZWN0LCBwdCApKSByZXR1cm4gSFRCT1JERVI7CiAgICB9CgogICAgLyogQ2hlY2sgY2FwdGlvbiAqLwoKICAgIGlmICgod25kUHRyLT5kd1N0eWxlICYgV1NfQ0FQVElPTikgPT0gV1NfQ0FQVElPTikKICAgIHsKICAgICAgICByZWN0LnRvcCArPSBHZXRTeXN0ZW1NZXRyaWNzKFNNX0NZQ0FQVElPTikgLSBHZXRTeXN0ZW1NZXRyaWNzKFNNX0NZQk9SREVSKTsKICAgICAgICBpZiAoIVB0SW5SZWN0KCAmcmVjdCwgcHQgKSkKICAgICAgICB7CiAgICAgICAgICAgIC8qIENoZWNrIHN5c3RlbSBtZW51ICovCiAgICAgICAgICAgIGlmICgod25kUHRyLT5kd1N0eWxlICYgV1NfU1lTTUVOVSkgJiYgISh3bmRQdHItPmR3RXhTdHlsZSAmIFdTX0VYX1RPT0xXSU5ET1cpKQogICAgICAgICAgICAgICAgcmVjdC5sZWZ0ICs9IEdldFN5c3RlbU1ldHJpY3MoU01fQ1hTSVpFKTsKICAgICAgICAgICAgaWYgKHB0LnggPD0gcmVjdC5sZWZ0KSByZXR1cm4gSFRTWVNNRU5VOwoKICAgICAgICAgICAgLyogQ2hlY2sgbWF4aW1pemUgYm94ICovCiAgICAgICAgICAgIGlmICh3bmRQdHItPmR3U3R5bGUgJiBXU19NQVhJTUlaRUJPWCkKICAgICAgICAgICAgICAgIHJlY3QucmlnaHQgLT0gR2V0U3lzdGVtTWV0cmljcyhTTV9DWFNJWkUpICsgMTsKCiAgICAgICAgICAgIGlmIChwdC54ID49IHJlY3QucmlnaHQpIHJldHVybiBIVE1BWEJVVFRPTjsKICAgICAgICAgICAgLyogQ2hlY2sgbWluaW1pemUgYm94ICovCiAgICAgICAgICAgIGlmICh3bmRQdHItPmR3U3R5bGUgJiBXU19NSU5JTUlaRUJPWCkKICAgICAgICAgICAgICAgIHJlY3QucmlnaHQgLT0gR2V0U3lzdGVtTWV0cmljcyhTTV9DWFNJWkUpICsgMTsKICAgICAgICAgICAgaWYgKHB0LnggPj0gcmVjdC5yaWdodCkgcmV0dXJuIEhUTUlOQlVUVE9OOwogICAgICAgICAgICByZXR1cm4gSFRDQVBUSU9OOwogICAgICAgIH0KICAgIH0KCiAgICAgIC8qIENoZWNrIGNsaWVudCBhcmVhICovCgogICAgU2NyZWVuVG9DbGllbnQoIHduZFB0ci0+aHduZFNlbGYsICZwdCApOwogICAgR2V0Q2xpZW50UmVjdCggd25kUHRyLT5od25kU2VsZiwgJnJlY3QgKTsKICAgIGlmIChQdEluUmVjdCggJnJlY3QsIHB0ICkpIHJldHVybiBIVENMSUVOVDsKCiAgICAgIC8qIENoZWNrIHZlcnRpY2FsIHNjcm9sbCBiYXIgKi8KCiAgICBpZiAod25kUHRyLT5kd1N0eWxlICYgV1NfVlNDUk9MTCkKICAgIHsKICAgICAgICBpZigod25kUHRyLT5kd0V4U3R5bGUgJiBXU19FWF9MRUZUU0NST0xMQkFSKSAhPSAwKQogICAgICAgICAgICByZWN0LmxlZnQgLT0gR2V0U3lzdGVtTWV0cmljcyhTTV9DWFZTQ1JPTEwpOwogICAgICAgIGVsc2UKICAgICAgICAgICAgcmVjdC5yaWdodCArPSBHZXRTeXN0ZW1NZXRyaWNzKFNNX0NYVlNDUk9MTCk7CiAgICAgICAgaWYgKFB0SW5SZWN0KCAmcmVjdCwgcHQgKSkgcmV0dXJuIEhUVlNDUk9MTDsKICAgIH0KCiAgICAgIC8qIENoZWNrIGhvcml6b250YWwgc2Nyb2xsIGJhciAqLwoKICAgIGlmICh3bmRQdHItPmR3U3R5bGUgJiBXU19IU0NST0xMKQogICAgewoJcmVjdC5ib3R0b20gKz0gR2V0U3lzdGVtTWV0cmljcyhTTV9DWUhTQ1JPTEwpOwoJaWYgKFB0SW5SZWN0KCAmcmVjdCwgcHQgKSkKCXsKCSAgICAgIC8qIENoZWNrIHNpemUgYm94ICovCgkgICAgaWYgKCh3bmRQdHItPmR3U3R5bGUgJiBXU19WU0NST0xMKSAmJgoJCSgoKCh3bmRQdHItPmR3RXhTdHlsZSAmIFdTX0VYX0xFRlRTQ1JPTExCQVIpICE9IDApICYmIChwdC54IDw9IHJlY3QubGVmdCArIEdldFN5c3RlbU1ldHJpY3MoU01fQ1hWU0NST0xMKSkpIHx8CgkJKCgod25kUHRyLT5kd0V4U3R5bGUgJiBXU19FWF9MRUZUU0NST0xMQkFSKSA9PSAwKSAmJiAocHQueCA+PSByZWN0LnJpZ2h0IC0gR2V0U3lzdGVtTWV0cmljcyhTTV9DWFZTQ1JPTEwpKSkpKQoJCXJldHVybiBIVFNJWkU7CgkgICAgcmV0dXJuIEhUSFNDUk9MTDsKCX0KICAgIH0KCiAgICAgIC8qIENoZWNrIG1lbnUgYmFyICovCgogICAgaWYgKEhBU19NRU5VKHduZFB0cikpCiAgICB7CglpZiAoKHB0LnkgPCAwKSAmJiAocHQueCA+PSAwKSAmJiAocHQueCA8IHJlY3QucmlnaHQpKQoJICAgIHJldHVybiBIVE1FTlU7CiAgICB9CgogICAgLyogSGFzIHRvIHJldHVybiBIVE5PV0hFUkUgaWYgbm90aGluZyB3YXMgZm91bmQKICAgICAgIENvdWxkIGhhcHBlbiB3aGVuIGEgd2luZG93IGhhcyBhIGN1c3RvbWl6ZWQgbm9uIGNsaWVudCBhcmVhICovCiAgICByZXR1cm4gSFROT1dIRVJFOwp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIE5DX0RvTkNIaXRUZXN0OTUKICoKICogSGFuZGxlIGEgV01fTkNISVRURVNUIG1lc3NhZ2UuIENhbGxlZCBmcm9tIE5DX0hhbmRsZU5DSGl0VGVzdCgpLgogKgogKiBGSVhNRTogIEp1c3QgYSBtb2RpZmllZCBjb3B5IG9mIHRoZSBXaW4gMy4xIHZlcnNpb24uCiAqLwoKc3RhdGljIExPTkcgTkNfRG9OQ0hpdFRlc3Q5NSAoV05EICp3bmRQdHIsIFBPSU5UIHB0ICkKewogICAgUkVDVCByZWN0OwoKICAgIFRSQUNFKCJod25kPSVwIHB0PSVsZCwlbGRcbiIsIHduZFB0ci0+aHduZFNlbGYsIHB0LngsIHB0LnkgKTsKCiAgICBHZXRXaW5kb3dSZWN0KHduZFB0ci0+aHduZFNlbGYsICZyZWN0ICk7CiAgICBpZiAoIVB0SW5SZWN0KCAmcmVjdCwgcHQgKSkgcmV0dXJuIEhUTk9XSEVSRTsKCiAgICBpZiAod25kUHRyLT5kd1N0eWxlICYgV1NfTUlOSU1JWkUpIHJldHVybiBIVENBUFRJT047CgogICAgLyogQ2hlY2sgYm9yZGVycyAqLwogICAgaWYgKEhBU19USElDS0ZSQU1FKCB3bmRQdHItPmR3U3R5bGUsIHduZFB0ci0+ZHdFeFN0eWxlICkpCiAgICB7CiAgICAgICAgSW5mbGF0ZVJlY3QoICZyZWN0LCAtR2V0U3lzdGVtTWV0cmljcyhTTV9DWEZSQU1FKSwgLUdldFN5c3RlbU1ldHJpY3MoU01fQ1lGUkFNRSkgKTsKICAgICAgICBpZiAoIVB0SW5SZWN0KCAmcmVjdCwgcHQgKSkKICAgICAgICB7CiAgICAgICAgICAgIC8qIENoZWNrIHRvcCBzaXppbmcgYm9yZGVyICovCiAgICAgICAgICAgIGlmIChwdC55IDwgcmVjdC50b3ApCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGlmIChwdC54IDwgcmVjdC5sZWZ0K0dldFN5c3RlbU1ldHJpY3MoU01fQ1hTSVpFKSkgcmV0dXJuIEhUVE9QTEVGVDsKICAgICAgICAgICAgICAgIGlmIChwdC54ID49IHJlY3QucmlnaHQtR2V0U3lzdGVtTWV0cmljcyhTTV9DWFNJWkUpKSByZXR1cm4gSFRUT1BSSUdIVDsKICAgICAgICAgICAgICAgIHJldHVybiBIVFRPUDsKICAgICAgICAgICAgfQogICAgICAgICAgICAvKiBDaGVjayBib3R0b20gc2l6aW5nIGJvcmRlciAqLwogICAgICAgICAgICBpZiAocHQueSA+PSByZWN0LmJvdHRvbSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgaWYgKHB0LnggPCByZWN0LmxlZnQrR2V0U3lzdGVtTWV0cmljcyhTTV9DWFNJWkUpKSByZXR1cm4gSFRCT1RUT01MRUZUOwogICAgICAgICAgICAgICAgaWYgKHB0LnggPj0gcmVjdC5yaWdodC1HZXRTeXN0ZW1NZXRyaWNzKFNNX0NYU0laRSkpIHJldHVybiBIVEJPVFRPTVJJR0hUOwogICAgICAgICAgICAgICAgcmV0dXJuIEhUQk9UVE9NOwogICAgICAgICAgICB9CiAgICAgICAgICAgIC8qIENoZWNrIGxlZnQgc2l6aW5nIGJvcmRlciAqLwogICAgICAgICAgICBpZiAocHQueCA8IHJlY3QubGVmdCkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgaWYgKHB0LnkgPCByZWN0LnRvcCtHZXRTeXN0ZW1NZXRyaWNzKFNNX0NZU0laRSkpIHJldHVybiBIVFRPUExFRlQ7CiAgICAgICAgICAgICAgICBpZiAocHQueSA+PSByZWN0LmJvdHRvbS1HZXRTeXN0ZW1NZXRyaWNzKFNNX0NZU0laRSkpIHJldHVybiBIVEJPVFRPTUxFRlQ7CiAgICAgICAgICAgICAgICByZXR1cm4gSFRMRUZUOwogICAgICAgICAgICB9CiAgICAgICAgICAgIC8qIENoZWNrIHJpZ2h0IHNpemluZyBib3JkZXIgKi8KICAgICAgICAgICAgaWYgKHB0LnggPj0gcmVjdC5yaWdodCkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgaWYgKHB0LnkgPCByZWN0LnRvcCtHZXRTeXN0ZW1NZXRyaWNzKFNNX0NZU0laRSkpIHJldHVybiBIVFRPUFJJR0hUOwogICAgICAgICAgICAgICAgaWYgKHB0LnkgPj0gcmVjdC5ib3R0b20tR2V0U3lzdGVtTWV0cmljcyhTTV9DWVNJWkUpKSByZXR1cm4gSFRCT1RUT01SSUdIVDsKICAgICAgICAgICAgICAgIHJldHVybiBIVFJJR0hUOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfQogICAgZWxzZSAgLyogTm8gdGhpY2sgZnJhbWUgKi8KICAgIHsKICAgICAgICBpZiAoSEFTX0RMR0ZSQU1FKCB3bmRQdHItPmR3U3R5bGUsIHduZFB0ci0+ZHdFeFN0eWxlICkpCiAgICAgICAgICAgIEluZmxhdGVSZWN0KCZyZWN0LCAtR2V0U3lzdGVtTWV0cmljcyhTTV9DWERMR0ZSQU1FKSwgLUdldFN5c3RlbU1ldHJpY3MoU01fQ1lETEdGUkFNRSkpOwogICAgICAgIGVsc2UgaWYgKEhBU19USElORlJBTUUoIHduZFB0ci0+ZHdTdHlsZSApKQogICAgICAgICAgICBJbmZsYXRlUmVjdCgmcmVjdCwgLUdldFN5c3RlbU1ldHJpY3MoU01fQ1hCT1JERVIpLCAtR2V0U3lzdGVtTWV0cmljcyhTTV9DWUJPUkRFUikpOwogICAgICAgIGlmICghUHRJblJlY3QoICZyZWN0LCBwdCApKSByZXR1cm4gSFRCT1JERVI7CiAgICB9CgogICAgLyogQ2hlY2sgY2FwdGlvbiAqLwoKICAgIGlmICgod25kUHRyLT5kd1N0eWxlICYgV1NfQ0FQVElPTikgPT0gV1NfQ0FQVElPTikKICAgIHsKICAgICAgICBpZiAod25kUHRyLT5kd0V4U3R5bGUgJiBXU19FWF9UT09MV0lORE9XKQogICAgICAgICAgICByZWN0LnRvcCArPSBHZXRTeXN0ZW1NZXRyaWNzKFNNX0NZU01DQVBUSU9OKSAtIDE7CiAgICAgICAgZWxzZQogICAgICAgICAgICByZWN0LnRvcCArPSBHZXRTeXN0ZW1NZXRyaWNzKFNNX0NZQ0FQVElPTikgLSAxOwogICAgICAgIGlmICghUHRJblJlY3QoICZyZWN0LCBwdCApKQogICAgICAgIHsKICAgICAgICAgICAgLyogQ2hlY2sgc3lzdGVtIG1lbnUgKi8KICAgICAgICAgICAgaWYgKCh3bmRQdHItPmR3U3R5bGUgJiBXU19TWVNNRU5VKSAmJiAhKHduZFB0ci0+ZHdFeFN0eWxlICYgV1NfRVhfVE9PTFdJTkRPVykpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGlmIChOQ19JY29uRm9yV2luZG93KHduZFB0ci0+aHduZFNlbGYpKQogICAgICAgICAgICAgICAgICAgIHJlY3QubGVmdCArPSBHZXRTeXN0ZW1NZXRyaWNzKFNNX0NZQ0FQVElPTikgLSAxOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGlmIChwdC54IDwgcmVjdC5sZWZ0KSByZXR1cm4gSFRTWVNNRU5VOwoKICAgICAgICAgICAgLyogQ2hlY2sgY2xvc2UgYnV0dG9uICovCiAgICAgICAgICAgIGlmICh3bmRQdHItPmR3U3R5bGUgJiBXU19TWVNNRU5VKQogICAgICAgICAgICAgICAgcmVjdC5yaWdodCAtPSBHZXRTeXN0ZW1NZXRyaWNzKFNNX0NZQ0FQVElPTikgLSAxOwogICAgICAgICAgICBpZiAocHQueCA+IHJlY3QucmlnaHQpIHJldHVybiBIVENMT1NFOwoKICAgICAgICAgICAgLyogQ2hlY2sgbWF4aW1pemUgYm94ICovCiAgICAgICAgICAgIC8qIEluIHdpbjk1IHRoZXJlIGlzIGF1dG9tYXRpY2FsbHkgYSBNYXhpbWl6ZSBidXR0b24gd2hlbiB0aGVyZSBpcyBhIG1pbmltaXplIG9uZSovCiAgICAgICAgICAgIGlmICgod25kUHRyLT5kd1N0eWxlICYgV1NfTUFYSU1JWkVCT1gpfHwgKHduZFB0ci0+ZHdTdHlsZSAmIFdTX01JTklNSVpFQk9YKSkKICAgICAgICAgICAgICAgIHJlY3QucmlnaHQgLT0gR2V0U3lzdGVtTWV0cmljcyhTTV9DWFNJWkUpICsgMTsKICAgICAgICAgICAgaWYgKHB0LnggPiByZWN0LnJpZ2h0KSByZXR1cm4gSFRNQVhCVVRUT047CgogICAgICAgICAgICAvKiBDaGVjayBtaW5pbWl6ZSBib3ggKi8KICAgICAgICAgICAgLyogSW4gd2luOTUgdGhlcmUgaXMgYXV0b21hdGljYWxseSBhIE1heGltaXplIGJ1dHRvbiB3aGVuIHRoZXJlIGlzIGEgTWF4aW1pemUgb25lKi8KICAgICAgICAgICAgaWYgKCh3bmRQdHItPmR3U3R5bGUgJiBXU19NSU5JTUlaRUJPWCl8fCh3bmRQdHItPmR3U3R5bGUgJiBXU19NQVhJTUlaRUJPWCkpCiAgICAgICAgICAgICAgICByZWN0LnJpZ2h0IC09IEdldFN5c3RlbU1ldHJpY3MoU01fQ1hTSVpFKSArIDE7CgogICAgICAgICAgICBpZiAocHQueCA+IHJlY3QucmlnaHQpIHJldHVybiBIVE1JTkJVVFRPTjsKICAgICAgICAgICAgcmV0dXJuIEhUQ0FQVElPTjsKICAgICAgICB9CiAgICB9CgogICAgICAvKiBDaGVjayBjbGllbnQgYXJlYSAqLwoKICAgIFNjcmVlblRvQ2xpZW50KCB3bmRQdHItPmh3bmRTZWxmLCAmcHQgKTsKICAgIEdldENsaWVudFJlY3QoIHduZFB0ci0+aHduZFNlbGYsICZyZWN0ICk7CiAgICBpZiAoUHRJblJlY3QoICZyZWN0LCBwdCApKSByZXR1cm4gSFRDTElFTlQ7CgogICAgICAvKiBDaGVjayB2ZXJ0aWNhbCBzY3JvbGwgYmFyICovCgogICAgaWYgKHduZFB0ci0+ZHdTdHlsZSAmIFdTX1ZTQ1JPTEwpCiAgICB7CiAgICAgICAgaWYoKHduZFB0ci0+ZHdFeFN0eWxlICYgV1NfRVhfTEVGVFNDUk9MTEJBUikgIT0gMCkKICAgICAgICAgICAgcmVjdC5sZWZ0IC09IEdldFN5c3RlbU1ldHJpY3MoU01fQ1hWU0NST0xMKTsKICAgICAgICBlbHNlCiAgICAgICAgICAgIHJlY3QucmlnaHQgKz0gR2V0U3lzdGVtTWV0cmljcyhTTV9DWFZTQ1JPTEwpOwogICAgICAgIGlmIChQdEluUmVjdCggJnJlY3QsIHB0ICkpIHJldHVybiBIVFZTQ1JPTEw7CiAgICB9CgogICAgICAvKiBDaGVjayBob3Jpem9udGFsIHNjcm9sbCBiYXIgKi8KCiAgICBpZiAod25kUHRyLT5kd1N0eWxlICYgV1NfSFNDUk9MTCkKICAgIHsKCXJlY3QuYm90dG9tICs9IEdldFN5c3RlbU1ldHJpY3MoU01fQ1lIU0NST0xMKTsKCWlmIChQdEluUmVjdCggJnJlY3QsIHB0ICkpCgl7CgkgICAgICAvKiBDaGVjayBzaXplIGJveCAqLwoJICAgIGlmICgod25kUHRyLT5kd1N0eWxlICYgV1NfVlNDUk9MTCkgJiYKCQkoKCgod25kUHRyLT5kd0V4U3R5bGUgJiBXU19FWF9MRUZUU0NST0xMQkFSKSAhPSAwKSAmJiAocHQueCA8PSByZWN0LmxlZnQgKyBHZXRTeXN0ZW1NZXRyaWNzKFNNX0NYVlNDUk9MTCkpKSB8fAoJCSgoKHduZFB0ci0+ZHdFeFN0eWxlICYgV1NfRVhfTEVGVFNDUk9MTEJBUikgPT0gMCkgJiYgKHB0LnggPj0gcmVjdC5yaWdodCAtIEdldFN5c3RlbU1ldHJpY3MoU01fQ1hWU0NST0xMKSkpKSkKCQlyZXR1cm4gSFRTSVpFOwoJICAgIHJldHVybiBIVEhTQ1JPTEw7Cgl9CiAgICB9CgogICAgICAvKiBDaGVjayBtZW51IGJhciAqLwoKICAgIGlmIChIQVNfTUVOVSh3bmRQdHIpKQogICAgewoJaWYgKChwdC55IDwgMCkgJiYgKHB0LnggPj0gMCkgJiYgKHB0LnggPCByZWN0LnJpZ2h0KSkKCSAgICByZXR1cm4gSFRNRU5VOwogICAgfQoKICAgIC8qIEhhcyB0byByZXR1cm4gSFROT1dIRVJFIGlmIG5vdGhpbmcgd2FzIGZvdW5kCiAgICAgICBDb3VsZCBoYXBwZW4gd2hlbiBhIHdpbmRvdyBoYXMgYSBjdXN0b21pemVkIG5vbiBjbGllbnQgYXJlYSAqLwogICAgcmV0dXJuIEhUTk9XSEVSRTsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBOQ19IYW5kbGVOQ0hpdFRlc3QKICoKICogSGFuZGxlIGEgV01fTkNISVRURVNUIG1lc3NhZ2UuIENhbGxlZCBmcm9tIERlZldpbmRvd1Byb2MoKS4KICovCkxPTkcgTkNfSGFuZGxlTkNIaXRUZXN0IChIV05EIGh3bmQgLCBQT0lOVCBwdCkKewogICAgTE9ORyByZXR2YWx1ZTsKICAgIFdORCAqd25kUHRyID0gV0lOX0ZpbmRXbmRQdHIgKGh3bmQpOwoKICAgIGlmICghd25kUHRyKQoJcmV0dXJuIEhURVJST1I7CgogICAgaWYgKFRXRUFLX1dpbmVMb29rID09IFdJTjMxX0xPT0spCiAgICAgICAgcmV0dmFsdWUgPSBOQ19Eb05DSGl0VGVzdCAod25kUHRyLCBwdCk7CiAgICBlbHNlCiAgICAgICAgcmV0dmFsdWUgPSBOQ19Eb05DSGl0VGVzdDk1ICh3bmRQdHIsIHB0KTsKICAgIFdJTl9SZWxlYXNlV25kUHRyKHduZFB0cik7CiAgICByZXR1cm4gcmV0dmFsdWU7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICAgICAgIE5DX0RyYXdTeXNCdXR0b24KICovCnZvaWQgTkNfRHJhd1N5c0J1dHRvbiggSFdORCBod25kLCBIREMgaGRjLCBCT09MIGRvd24gKQp7CiAgICBSRUNUIHJlY3Q7CiAgICBIREMgaGRjTWVtOwogICAgSEJJVE1BUCBoYml0bWFwOwoKICAgIE5DX0dldEluc2lkZVJlY3QoIGh3bmQsICZyZWN0ICk7CiAgICBoZGNNZW0gPSBDcmVhdGVDb21wYXRpYmxlREMoIGhkYyApOwogICAgaGJpdG1hcCA9IFNlbGVjdE9iamVjdCggaGRjTWVtLCBoYml0bWFwQ2xvc2UgKTsKICAgIEJpdEJsdChoZGMsIHJlY3QubGVmdCwgcmVjdC50b3AsIEdldFN5c3RlbU1ldHJpY3MoU01fQ1hTSVpFKSwgR2V0U3lzdGVtTWV0cmljcyhTTV9DWVNJWkUpLAogICAgICAgICAgIGhkY01lbSwgKEdldFdpbmRvd0xvbmdBKGh3bmQsR1dMX1NUWUxFKSAmIFdTX0NISUxEKSA/IEdldFN5c3RlbU1ldHJpY3MoU01fQ1hTSVpFKSA6IDAsIDAsCiAgICAgICAgICAgZG93biA/IE5PVFNSQ0NPUFkgOiBTUkNDT1BZICk7CiAgICBTZWxlY3RPYmplY3QoIGhkY01lbSwgaGJpdG1hcCApOwogICAgRGVsZXRlREMoIGhkY01lbSApOwp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgICAgICBOQ19EcmF3TWF4QnV0dG9uCiAqLwpzdGF0aWMgdm9pZCBOQ19EcmF3TWF4QnV0dG9uKCBIV05EIGh3bmQsIEhEQyBoZGMsIEJPT0wgZG93biApCnsKICAgIFJFQ1QgcmVjdDsKICAgIFVJTlQgZmxhZ3MgPSBJc1pvb21lZChod25kKSA/IERGQ1NfQ0FQVElPTlJFU1RPUkUgOiBERkNTX0NBUFRJT05NQVg7CgogICAgTkNfR2V0SW5zaWRlUmVjdCggaHduZCwgJnJlY3QgKTsKICAgIHJlY3QubGVmdCA9IHJlY3QucmlnaHQgLSBHZXRTeXN0ZW1NZXRyaWNzKFNNX0NYU0laRSkgKyAxOwogICAgcmVjdC5ib3R0b20gPSByZWN0LnRvcCArIEdldFN5c3RlbU1ldHJpY3MoU01fQ1lTSVpFKSAtIDE7CiAgICByZWN0LnRvcCArPSAxOwogICAgcmVjdC5yaWdodCAtPSAxOwogICAgaWYgKGRvd24pIGZsYWdzIHw9IERGQ1NfUFVTSEVEOwogICAgRHJhd0ZyYW1lQ29udHJvbCggaGRjLCAmcmVjdCwgREZDX0NBUFRJT04sIGZsYWdzICk7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICAgICAgIE5DX0RyYXdNaW5CdXR0b24KICovCnN0YXRpYyB2b2lkIE5DX0RyYXdNaW5CdXR0b24oIEhXTkQgaHduZCwgSERDIGhkYywgQk9PTCBkb3duICkKewogICAgUkVDVCByZWN0OwogICAgVUlOVCBmbGFncyA9IERGQ1NfQ0FQVElPTk1JTjsKICAgIERXT1JEIHN0eWxlID0gR2V0V2luZG93TG9uZ0EoIGh3bmQsIEdXTF9TVFlMRSApOwoKICAgIE5DX0dldEluc2lkZVJlY3QoIGh3bmQsICZyZWN0ICk7CiAgICBpZiAoc3R5bGUgJiAoV1NfTUFYSU1JWkVCT1h8V1NfTUlOSU1JWkVCT1gpKQogICAgICAgIHJlY3QucmlnaHQgLT0gR2V0U3lzdGVtTWV0cmljcyhTTV9DWFNJWkUpIC0gMjsKICAgIHJlY3QubGVmdCA9IHJlY3QucmlnaHQgLSBHZXRTeXN0ZW1NZXRyaWNzKFNNX0NYU0laRSkgKyAxOwogICAgcmVjdC5ib3R0b20gPSByZWN0LnRvcCArIEdldFN5c3RlbU1ldHJpY3MoU01fQ1lTSVpFKSAtIDE7CiAgICByZWN0LnRvcCArPSAxOwogICAgcmVjdC5yaWdodCAtPSAxOwogICAgaWYgKGRvd24pIGZsYWdzIHw9IERGQ1NfUFVTSEVEOwogICAgRHJhd0ZyYW1lQ29udHJvbCggaGRjLCAmcmVjdCwgREZDX0NBUFRJT04sIGZsYWdzICk7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCiAqICAgdm9pZCAgTkNfRHJhd1N5c0J1dHRvbjk1KAogKiAgICAgIEhXTkQgIGh3bmQsCiAqICAgICAgSERDICBoZGMsCiAqICAgICAgQk9PTCAgZG93biApCiAqCiAqICAgRHJhd3MgdGhlIFdpbjk1IHN5c3RlbSBpY29uLgogKgogKiAgIFJldmlzaW9uIGhpc3RvcnkKICogICAgICAgIDA1LUp1bC0xOTk3IERhdmUgQ3V0aGJlcnQgKGRhY3V0QGVjZS5jbXUuZWR1KQogKiAgICAgICAgICAgICBPcmlnaW5hbCBpbXBsZW1lbnRhdGlvbiBmcm9tIE5DX0RyYXdTeXNCdXR0b24gc291cmNlLgogKiAgICAgICAgMTEtSnVuLTE5OTggRXJpYyBLb2hsIChla29obEBhYm8ucmhlaW4temVpdHVuZy5kZSkKICogICAgICAgICAgICAgRml4ZWQgbW9zdCBidWdzLgogKgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCgpCT09MCk5DX0RyYXdTeXNCdXR0b245NSAoSFdORCBod25kLCBIREMgaGRjLCBCT09MIGRvd24pCnsKICAgIEhJQ09OIGhJY29uID0gTkNfSWNvbkZvcldpbmRvdyggaHduZCApOwoKICAgIGlmIChoSWNvbikKICAgIHsKICAgICAgICBSRUNUIHJlY3Q7CiAgICAgICAgTkNfR2V0SW5zaWRlUmVjdCggaHduZCwgJnJlY3QgKTsKICAgICAgICBEcmF3SWNvbkV4IChoZGMsIHJlY3QubGVmdCArIDEsIHJlY3QudG9wICsgMSwgaEljb24sCiAgICAgICAgICAgICAgICAgICAgR2V0U3lzdGVtTWV0cmljcyhTTV9DWFNJWkUpIC0gMSwKICAgICAgICAgICAgICAgICAgICBHZXRTeXN0ZW1NZXRyaWNzKFNNX0NZU0laRSkgLSAxLCAwLCAwLCBESV9OT1JNQUwpOwogICAgfQogICAgcmV0dXJuIChoSWNvbiAhPSAwKTsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoKICogICB2b2lkICBOQ19EcmF3Q2xvc2VCdXR0b245NSgKICogICAgICBIV05EICBod25kLAogKiAgICAgIEhEQyAgaGRjLAogKiAgICAgIEJPT0wgIGRvd24sCiAqICAgICAgQk9PTCAgICBiR3JheWVkICkKICoKICogICBEcmF3cyB0aGUgV2luOTUgY2xvc2UgYnV0dG9uLgogKgogKiAgIElmIGJHcmF5ZWQgaXMgdHJ1ZSwgdGhlbiBkcmF3IGEgZGlzYWJsZWQgQ2xvc2UgYnV0dG9uCiAqCiAqICAgUmV2aXNpb24gaGlzdG9yeQogKiAgICAgICAgMTEtSnVuLTE5OTggRXJpYyBLb2hsIChla29obEBhYm8ucmhlaW4temVpdHVuZy5kZSkKICogICAgICAgICAgICAgT3JpZ2luYWwgaW1wbGVtZW50YXRpb24gZnJvbSBOQ19EcmF3U3lzQnV0dG9uOTUgc291cmNlLgogKgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCgpzdGF0aWMgdm9pZCBOQ19EcmF3Q2xvc2VCdXR0b245NSAoSFdORCBod25kLCBIREMgaGRjLCBCT09MIGRvd24sIEJPT0wgYkdyYXllZCkKewogICAgUkVDVCByZWN0OwoKICAgIE5DX0dldEluc2lkZVJlY3QoIGh3bmQsICZyZWN0ICk7CgogICAgLyogQSB0b29sIHdpbmRvdyBoYXMgYSBzbWFsbGVyIENsb3NlIGJ1dHRvbiAqLwogICAgaWYgKEdldFdpbmRvd0xvbmdBKCBod25kLCBHV0xfRVhTVFlMRSApICYgV1NfRVhfVE9PTFdJTkRPVykKICAgIHsKICAgICAgICBJTlQgaUJtcEhlaWdodCA9IDExOyAvKiBXaW5kb3dzIGRvZXMgbm90IHVzZSBTTV9DWFNNU0laRSBhbmQgU01fQ1lTTVNJWkUgICAqLwogICAgICAgIElOVCBpQm1wV2lkdGggPSAxMTsgIC8qIGl0IHVzZXMgMTF4MTEgZm9yICB0aGUgY2xvc2UgYnV0dG9uIGluIHRvb2wgd2luZG93ICovCiAgICAgICAgSU5UIGlDYXB0aW9uSGVpZ2h0ID0gR2V0U3lzdGVtTWV0cmljcyhTTV9DWVNNQ0FQVElPTik7CgogICAgICAgIHJlY3QudG9wID0gcmVjdC50b3AgKyAoaUNhcHRpb25IZWlnaHQgLSAxIC0gaUJtcEhlaWdodCkgLyAyOwogICAgICAgIHJlY3QubGVmdCA9IHJlY3QucmlnaHQgLSAoaUNhcHRpb25IZWlnaHQgKyAxICsgaUJtcFdpZHRoKSAvIDI7CiAgICAgICAgcmVjdC5ib3R0b20gPSByZWN0LnRvcCArIGlCbXBIZWlnaHQ7CiAgICAgICAgcmVjdC5yaWdodCA9IHJlY3QubGVmdCArIGlCbXBXaWR0aDsKICAgIH0KICAgIGVsc2UKICAgIHsKICAgICAgICByZWN0LmxlZnQgPSByZWN0LnJpZ2h0IC0gR2V0U3lzdGVtTWV0cmljcyhTTV9DWFNJWkUpIC0gMTsKICAgICAgICByZWN0LmJvdHRvbSA9IHJlY3QudG9wICsgR2V0U3lzdGVtTWV0cmljcyhTTV9DWVNJWkUpIC0gMTsKICAgICAgICByZWN0LnRvcCArPSAyOwogICAgICAgIHJlY3QucmlnaHQgLT0gMjsKICAgIH0KICAgIERyYXdGcmFtZUNvbnRyb2woIGhkYywgJnJlY3QsIERGQ19DQVBUSU9OLAogICAgICAgICAgICAgICAgICAgICAgKERGQ1NfQ0FQVElPTkNMT1NFIHwKICAgICAgICAgICAgICAgICAgICAgICAoZG93biA/IERGQ1NfUFVTSEVEIDogMCkgfAogICAgICAgICAgICAgICAgICAgICAgIChiR3JheWVkID8gREZDU19JTkFDVElWRSA6IDApKSApOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgTkNfRHJhd01heEJ1dHRvbjk1CiAqCiAqICAgRHJhd3MgdGhlIG1heGltaXplIGJ1dHRvbiBmb3IgV2luOTUgc3R5bGUgd2luZG93cy4KICogICBJZiBiR3JheWVkIGlzIHRydWUsIHRoZW4gZHJhdyBhIGRpc2FibGVkIE1heGltaXplIGJ1dHRvbgogKi8Kc3RhdGljIHZvaWQgTkNfRHJhd01heEJ1dHRvbjk1KEhXTkQgaHduZCxIREMgaGRjLEJPT0wgZG93biwgQk9PTCBiR3JheWVkKQp7CiAgICBSRUNUIHJlY3Q7CiAgICBVSU5UIGZsYWdzID0gSXNab29tZWQoaHduZCkgPyBERkNTX0NBUFRJT05SRVNUT1JFIDogREZDU19DQVBUSU9OTUFYOwoKICAgIE5DX0dldEluc2lkZVJlY3QoIGh3bmQsICZyZWN0ICk7CiAgICBpZiAoR2V0V2luZG93TG9uZ0EoIGh3bmQsIEdXTF9TVFlMRSkgJiBXU19TWVNNRU5VKQogICAgICAgIHJlY3QucmlnaHQgLT0gR2V0U3lzdGVtTWV0cmljcyhTTV9DWFNJWkUpICsgMTsKICAgIHJlY3QubGVmdCA9IHJlY3QucmlnaHQgLSBHZXRTeXN0ZW1NZXRyaWNzKFNNX0NYU0laRSk7CiAgICByZWN0LmJvdHRvbSA9IHJlY3QudG9wICsgR2V0U3lzdGVtTWV0cmljcyhTTV9DWVNJWkUpIC0gMTsKICAgIHJlY3QudG9wICs9IDI7CiAgICByZWN0LnJpZ2h0IC09IDI7CiAgICBpZiAoZG93bikgZmxhZ3MgfD0gREZDU19QVVNIRUQ7CiAgICBpZiAoYkdyYXllZCkgZmxhZ3MgfD0gREZDU19JTkFDVElWRTsKICAgIERyYXdGcmFtZUNvbnRyb2woIGhkYywgJnJlY3QsIERGQ19DQVBUSU9OLCBmbGFncyApOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgTkNfRHJhd01pbkJ1dHRvbjk1CiAqCiAqICAgRHJhd3MgdGhlIG1pbmltaXplIGJ1dHRvbiBmb3IgV2luOTUgc3R5bGUgd2luZG93cy4KICogICBJZiBiR3JheWVkIGlzIHRydWUsIHRoZW4gZHJhdyBhIGRpc2FibGVkIE1pbmltaXplIGJ1dHRvbgogKi8Kc3RhdGljIHZvaWQgIE5DX0RyYXdNaW5CdXR0b245NShIV05EIGh3bmQsSERDIGhkYyxCT09MIGRvd24sIEJPT0wgYkdyYXllZCkKewogICAgUkVDVCByZWN0OwogICAgVUlOVCBmbGFncyA9IERGQ1NfQ0FQVElPTk1JTjsKICAgIERXT1JEIHN0eWxlID0gR2V0V2luZG93TG9uZ0EoIGh3bmQsIEdXTF9TVFlMRSApOwoKICAgIE5DX0dldEluc2lkZVJlY3QoIGh3bmQsICZyZWN0ICk7CiAgICBpZiAoc3R5bGUgJiBXU19TWVNNRU5VKQogICAgICAgIHJlY3QucmlnaHQgLT0gR2V0U3lzdGVtTWV0cmljcyhTTV9DWFNJWkUpICsgMTsKICAgIGlmIChzdHlsZSAmIChXU19NQVhJTUlaRUJPWHxXU19NSU5JTUlaRUJPWCkpCiAgICAgICAgcmVjdC5yaWdodCAtPSBHZXRTeXN0ZW1NZXRyaWNzKFNNX0NYU0laRSkgLSAyOwogICAgcmVjdC5sZWZ0ID0gcmVjdC5yaWdodCAtIEdldFN5c3RlbU1ldHJpY3MoU01fQ1hTSVpFKTsKICAgIHJlY3QuYm90dG9tID0gcmVjdC50b3AgKyBHZXRTeXN0ZW1NZXRyaWNzKFNNX0NZU0laRSkgLSAxOwogICAgcmVjdC50b3AgKz0gMjsKICAgIHJlY3QucmlnaHQgLT0gMjsKICAgIGlmIChkb3duKSBmbGFncyB8PSBERkNTX1BVU0hFRDsKICAgIGlmIChiR3JheWVkKSBmbGFncyB8PSBERkNTX0lOQUNUSVZFOwogICAgRHJhd0ZyYW1lQ29udHJvbCggaGRjLCAmcmVjdCwgREZDX0NBUFRJT04sIGZsYWdzICk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgICAgICAgTkNfRHJhd0ZyYW1lCiAqCiAqIERyYXcgYSB3aW5kb3cgZnJhbWUgaW5zaWRlIHRoZSBnaXZlbiByZWN0YW5nbGUsIGFuZCB1cGRhdGUgdGhlIHJlY3RhbmdsZS4KICogVGhlIGNvcnJlY3QgcGVuIGZvciB0aGUgZnJhbWUgbXVzdCBiZSBzZWxlY3RlZCBpbiB0aGUgREMuCiAqLwpzdGF0aWMgdm9pZCBOQ19EcmF3RnJhbWUoIEhEQyBoZGMsIFJFQ1QgKnJlY3QsIEJPT0wgZGxnRnJhbWUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgQk9PTCBhY3RpdmUgKQp7CiAgICBJTlQgd2lkdGgsIGhlaWdodDsKCiAgICBpZiAoVFdFQUtfV2luZUxvb2sgIT0gV0lOMzFfTE9PSykKCUVSUigiQ2FsbGVkIGluIFdpbjk1IG1vZGUuIEFpZWUhIFBsZWFzZSByZXBvcnQgdGhpcy5cbiIgKTsKCiAgICBpZiAoZGxnRnJhbWUpCiAgICB7Cgl3aWR0aCA9IEdldFN5c3RlbU1ldHJpY3MoU01fQ1hETEdGUkFNRSkgLSAxOwoJaGVpZ2h0ID0gR2V0U3lzdGVtTWV0cmljcyhTTV9DWURMR0ZSQU1FKSAtIDE7CiAgICAgICAgU2VsZWN0T2JqZWN0KCBoZGMsIEdldFN5c0NvbG9yQnJ1c2goYWN0aXZlID8gQ09MT1JfQUNUSVZFQ0FQVElPTiA6CgkJCQkJCUNPTE9SX0lOQUNUSVZFQ0FQVElPTikgKTsKICAgIH0KICAgIGVsc2UKICAgIHsKCXdpZHRoID0gR2V0U3lzdGVtTWV0cmljcyhTTV9DWEZSQU1FKSAtIDI7CgloZWlnaHQgPSBHZXRTeXN0ZW1NZXRyaWNzKFNNX0NZRlJBTUUpIC0gMjsKICAgICAgICBTZWxlY3RPYmplY3QoIGhkYywgR2V0U3lzQ29sb3JCcnVzaChhY3RpdmUgPyBDT0xPUl9BQ1RJVkVCT1JERVIgOgoJCQkJCQlDT0xPUl9JTkFDVElWRUJPUkRFUikgKTsKICAgIH0KCiAgICAgIC8qIERyYXcgZnJhbWUgKi8KICAgIFBhdEJsdCggaGRjLCByZWN0LT5sZWZ0LCByZWN0LT50b3AsCiAgICAgICAgICAgICAgcmVjdC0+cmlnaHQgLSByZWN0LT5sZWZ0LCBoZWlnaHQsIFBBVENPUFkgKTsKICAgIFBhdEJsdCggaGRjLCByZWN0LT5sZWZ0LCByZWN0LT50b3AsCiAgICAgICAgICAgICAgd2lkdGgsIHJlY3QtPmJvdHRvbSAtIHJlY3QtPnRvcCwgUEFUQ09QWSApOwogICAgUGF0Qmx0KCBoZGMsIHJlY3QtPmxlZnQsIHJlY3QtPmJvdHRvbSAtIDEsCiAgICAgICAgICAgICAgcmVjdC0+cmlnaHQgLSByZWN0LT5sZWZ0LCAtaGVpZ2h0LCBQQVRDT1BZICk7CiAgICBQYXRCbHQoIGhkYywgcmVjdC0+cmlnaHQgLSAxLCByZWN0LT50b3AsCiAgICAgICAgICAgICAgLXdpZHRoLCByZWN0LT5ib3R0b20gLSByZWN0LT50b3AsIFBBVENPUFkgKTsKCiAgICBpZiAoZGxnRnJhbWUpCiAgICB7CglJbmZsYXRlUmVjdCggcmVjdCwgLXdpZHRoLCAtaGVpZ2h0ICk7CiAgICB9CiAgICBlbHNlCiAgICB7CiAgICAgICAgSU5UIGRlY1lPZmYgPSBHZXRTeXN0ZW1NZXRyaWNzKFNNX0NYRlJBTUUpICsgR2V0U3lzdGVtTWV0cmljcyhTTV9DWFNJWkUpIC0gMTsKCUlOVCBkZWNYT2ZmID0gR2V0U3lzdGVtTWV0cmljcyhTTV9DWUZSQU1FKSArIEdldFN5c3RlbU1ldHJpY3MoU01fQ1lTSVpFKSAtIDE7CgogICAgICAvKiBEcmF3IGlubmVyIHJlY3RhbmdsZSAqLwoKCVNlbGVjdE9iamVjdCggaGRjLCBHZXRTdG9ja09iamVjdChOVUxMX0JSVVNIKSApOwoJUmVjdGFuZ2xlKCBoZGMsIHJlY3QtPmxlZnQgKyB3aWR0aCwgcmVjdC0+dG9wICsgaGVpZ2h0LAoJCSAgICAgcmVjdC0+cmlnaHQgLSB3aWR0aCAsIHJlY3QtPmJvdHRvbSAtIGhlaWdodCApOwoKICAgICAgLyogRHJhdyB0aGUgZGVjb3JhdGlvbnMgKi8KCglNb3ZlVG9FeCggaGRjLCByZWN0LT5sZWZ0LCByZWN0LT50b3AgKyBkZWNZT2ZmLCBOVUxMICk7CglMaW5lVG8oIGhkYywgcmVjdC0+bGVmdCArIHdpZHRoLCByZWN0LT50b3AgKyBkZWNZT2ZmICk7CglNb3ZlVG9FeCggaGRjLCByZWN0LT5yaWdodCAtIDEsIHJlY3QtPnRvcCArIGRlY1lPZmYsIE5VTEwgKTsKCUxpbmVUbyggaGRjLCByZWN0LT5yaWdodCAtIHdpZHRoIC0gMSwgcmVjdC0+dG9wICsgZGVjWU9mZiApOwoJTW92ZVRvRXgoIGhkYywgcmVjdC0+bGVmdCwgcmVjdC0+Ym90dG9tIC0gZGVjWU9mZiwgTlVMTCApOwoJTGluZVRvKCBoZGMsIHJlY3QtPmxlZnQgKyB3aWR0aCwgcmVjdC0+Ym90dG9tIC0gZGVjWU9mZiApOwoJTW92ZVRvRXgoIGhkYywgcmVjdC0+cmlnaHQgLSAxLCByZWN0LT5ib3R0b20gLSBkZWNZT2ZmLCBOVUxMICk7CglMaW5lVG8oIGhkYywgcmVjdC0+cmlnaHQgLSB3aWR0aCAtIDEsIHJlY3QtPmJvdHRvbSAtIGRlY1lPZmYgKTsKCglNb3ZlVG9FeCggaGRjLCByZWN0LT5sZWZ0ICsgZGVjWE9mZiwgcmVjdC0+dG9wLCBOVUxMICk7CglMaW5lVG8oIGhkYywgcmVjdC0+bGVmdCArIGRlY1hPZmYsIHJlY3QtPnRvcCArIGhlaWdodCk7CglNb3ZlVG9FeCggaGRjLCByZWN0LT5sZWZ0ICsgZGVjWE9mZiwgcmVjdC0+Ym90dG9tIC0gMSwgTlVMTCApOwoJTGluZVRvKCBoZGMsIHJlY3QtPmxlZnQgKyBkZWNYT2ZmLCByZWN0LT5ib3R0b20gLSBoZWlnaHQgLSAxICk7CglNb3ZlVG9FeCggaGRjLCByZWN0LT5yaWdodCAtIGRlY1hPZmYsIHJlY3QtPnRvcCwgTlVMTCApOwoJTGluZVRvKCBoZGMsIHJlY3QtPnJpZ2h0IC0gZGVjWE9mZiwgcmVjdC0+dG9wICsgaGVpZ2h0ICk7CglNb3ZlVG9FeCggaGRjLCByZWN0LT5yaWdodCAtIGRlY1hPZmYsIHJlY3QtPmJvdHRvbSAtIDEsIE5VTEwgKTsKCUxpbmVUbyggaGRjLCByZWN0LT5yaWdodCAtIGRlY1hPZmYsIHJlY3QtPmJvdHRvbSAtIGhlaWdodCAtIDEgKTsKCglJbmZsYXRlUmVjdCggcmVjdCwgLXdpZHRoIC0gMSwgLWhlaWdodCAtIDEgKTsKICAgIH0KfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoKICogICB2b2lkICBOQ19EcmF3RnJhbWU5NSgKICogICAgICBIREMgIGhkYywKICogICAgICBSRUNUICAqcmVjdCwKICogICAgICBCT09MICBhY3RpdmUsCiAqICAgICAgRFdPUkQgc3R5bGUsCiAqICAgICAgRFdPUkQgZXhTdHlsZSApCiAqCiAqICAgRHJhdyBhIHdpbmRvdyBmcmFtZSBpbnNpZGUgdGhlIGdpdmVuIHJlY3RhbmdsZSwgYW5kIHVwZGF0ZSB0aGUgcmVjdGFuZ2xlLgogKgogKiAgIEJ1Z3MKICogICAgICAgIE1hbnkuICBGaXJzdCwganVzdCB3aGF0IElTIGEgZnJhbWUgaW4gV2luOTU/ICBOb3RlIHRoYXQgdGhlIDNEIGxvb2sKICogICAgICAgIG9uIHRoZSBvdXRlciBlZGdlIGlzIGhhbmRsZWQgYnkgTkNfRG9OQ1BhaW50OTUuICBBcyBpcyB0aGUgaW5uZXIKICogICAgICAgIGVkZ2UuICBUaGUgaW5uZXIgcmVjdGFuZ2xlIGp1c3QgaW5zaWRlIHRoZSBmcmFtZSBpcyBoYW5kbGVkIGJ5IHRoZQogKiAgICAgICAgQ2FwdGlvbiBjb2RlLgogKgogKiAgICAgICAgSW4gc2hvcnQsIGZvciBtb3N0IHBlb3BsZSwgdGhpcyBmdW5jdGlvbiBzaG91bGQgYmUgYSBub3AgKHVubGVzcwogKiAgICAgICAgeW91IExJS0UgdGhpY2sgYm9yZGVycyBpbiBXaW45NS9OVDQuMCAtLSBJJ3ZlIGJlZW4gd29ya2luZyB3aXRoCiAqICAgICAgICB0aGVtIGxhdGVseSwgYnV0IGp1c3QgdG8gZ2V0IHRoaXMgY29kZSByaWdodCkuICBFdmVuIHNvLCBpdCBkb2Vzbid0CiAqICAgICAgICBhcHBlYXIgdG8gYmUgc28uICBJdCdzIGJlaW5nIHdvcmtlZCBvbi4uLgogKgogKiAgIFJldmlzaW9uIGhpc3RvcnkKICogICAgICAgIDA2LUp1bC0xOTk3IERhdmUgQ3V0aGJlcnQgKGRhY3V0QGVjZS5jbXUuZWR1KQogKiAgICAgICAgICAgICBPcmlnaW5hbCBpbXBsZW1lbnRhdGlvbiAoYmFzZWQgb24gTkNfRHJhd0ZyYW1lKQogKiAgICAgICAgMDItSnVuLTE5OTggRXJpYyBLb2hsIChla29obEBhYm8ucmhlaW4temVpdHVuZy5kZSkKICogICAgICAgICAgICAgU29tZSBtaW5vciBmaXhlcy4KICogICAgICAgIDI5LUp1bi0xOTk5IE92ZSBL5XZlbiAob3Zla0BhcmN0aWNuZXQubm8pCiAqICAgICAgICAgICAgIEZpeGVkIGEgZml4IG9yIHNvbWV0aGluZy4KICoKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwoKc3RhdGljIHZvaWQgIE5DX0RyYXdGcmFtZTk1KAogICAgSERDICBoZGMsCiAgICBSRUNUICAqcmVjdCwKICAgIEJPT0wgIGFjdGl2ZSwKICAgIERXT1JEIHN0eWxlLAogICAgRFdPUkQgZXhTdHlsZSkKewogICAgSU5UIHdpZHRoLCBoZWlnaHQ7CgogICAgLyogRmlyc3RseSB0aGUgInRoaWNrIiBmcmFtZSAqLwogICAgaWYgKHN0eWxlICYgV1NfVEhJQ0tGUkFNRSkKICAgIHsKCXdpZHRoID0gR2V0U3lzdGVtTWV0cmljcyhTTV9DWEZSQU1FKSAtIEdldFN5c3RlbU1ldHJpY3MoU01fQ1hETEdGUkFNRSk7CgloZWlnaHQgPSBHZXRTeXN0ZW1NZXRyaWNzKFNNX0NZRlJBTUUpIC0gR2V0U3lzdGVtTWV0cmljcyhTTV9DWURMR0ZSQU1FKTsKCiAgICAgICAgU2VsZWN0T2JqZWN0KCBoZGMsIEdldFN5c0NvbG9yQnJ1c2goYWN0aXZlID8gQ09MT1JfQUNUSVZFQk9SREVSIDoKCQkgICAgICBDT0xPUl9JTkFDVElWRUJPUkRFUikgKTsKICAgICAgICAvKiBEcmF3IGZyYW1lICovCiAgICAgICAgUGF0Qmx0KCBoZGMsIHJlY3QtPmxlZnQsIHJlY3QtPnRvcCwKICAgICAgICAgICAgICAgICAgcmVjdC0+cmlnaHQgLSByZWN0LT5sZWZ0LCBoZWlnaHQsIFBBVENPUFkgKTsKICAgICAgICBQYXRCbHQoIGhkYywgcmVjdC0+bGVmdCwgcmVjdC0+dG9wLAogICAgICAgICAgICAgICAgICB3aWR0aCwgcmVjdC0+Ym90dG9tIC0gcmVjdC0+dG9wLCBQQVRDT1BZICk7CiAgICAgICAgUGF0Qmx0KCBoZGMsIHJlY3QtPmxlZnQsIHJlY3QtPmJvdHRvbSAtIDEsCiAgICAgICAgICAgICAgICAgIHJlY3QtPnJpZ2h0IC0gcmVjdC0+bGVmdCwgLWhlaWdodCwgUEFUQ09QWSApOwogICAgICAgIFBhdEJsdCggaGRjLCByZWN0LT5yaWdodCAtIDEsIHJlY3QtPnRvcCwKICAgICAgICAgICAgICAgICAgLXdpZHRoLCByZWN0LT5ib3R0b20gLSByZWN0LT50b3AsIFBBVENPUFkgKTsKCiAgICAgICAgSW5mbGF0ZVJlY3QoIHJlY3QsIC13aWR0aCwgLWhlaWdodCApOwogICAgfQoKICAgIC8qIE5vdyB0aGUgb3RoZXIgYml0IG9mIHRoZSBmcmFtZSAqLwogICAgaWYgKChzdHlsZSAmIChXU19CT1JERVJ8V1NfRExHRlJBTUUpKSB8fAogICAgICAgIChleFN0eWxlICYgV1NfRVhfRExHTU9EQUxGUkFNRSkpCiAgICB7CiAgICAgICAgd2lkdGggPSBHZXRTeXN0ZW1NZXRyaWNzKFNNX0NYRExHRlJBTUUpIC0gR2V0U3lzdGVtTWV0cmljcyhTTV9DWEVER0UpOwogICAgICAgIGhlaWdodCA9IEdldFN5c3RlbU1ldHJpY3MoU01fQ1lETEdGUkFNRSkgLSBHZXRTeXN0ZW1NZXRyaWNzKFNNX0NZRURHRSk7CiAgICAgICAgLyogVGhpcyBzaG91bGQgZ2l2ZSBhIHZhbHVlIG9mIDEgdGhhdCBzaG91bGQgYWxzbyB3b3JrIGZvciBhIGJvcmRlciAqLwoKICAgICAgICBTZWxlY3RPYmplY3QoIGhkYywgR2V0U3lzQ29sb3JCcnVzaCgKICAgICAgICAgICAgICAgICAgICAgIChleFN0eWxlICYgKFdTX0VYX0RMR01PREFMRlJBTUV8V1NfRVhfQ0xJRU5URURHRSkpID8KICAgICAgICAgICAgICAgICAgICAgICAgICBDT0xPUl8zREZBQ0UgOgogICAgICAgICAgICAgICAgICAgICAgKGV4U3R5bGUgJiBXU19FWF9TVEFUSUNFREdFKSA/CiAgICAgICAgICAgICAgICAgICAgICAgICAgQ09MT1JfV0lORE9XRlJBTUUgOgogICAgICAgICAgICAgICAgICAgICAgKHN0eWxlICYgKFdTX0RMR0ZSQU1FfFdTX1RISUNLRlJBTUUpKSA/CiAgICAgICAgICAgICAgICAgICAgICAgICAgQ09MT1JfM0RGQUNFIDoKICAgICAgICAgICAgICAgICAgICAgIC8qIGVsc2UgKi8KICAgICAgICAgICAgICAgICAgICAgICAgICBDT0xPUl9XSU5ET1dGUkFNRSkpOwoKICAgICAgICAvKiBEcmF3IGZyYW1lICovCiAgICAgICAgUGF0Qmx0KCBoZGMsIHJlY3QtPmxlZnQsIHJlY3QtPnRvcCwKICAgICAgICAgICAgICAgICAgcmVjdC0+cmlnaHQgLSByZWN0LT5sZWZ0LCBoZWlnaHQsIFBBVENPUFkgKTsKICAgICAgICBQYXRCbHQoIGhkYywgcmVjdC0+bGVmdCwgcmVjdC0+dG9wLAogICAgICAgICAgICAgICAgICB3aWR0aCwgcmVjdC0+Ym90dG9tIC0gcmVjdC0+dG9wLCBQQVRDT1BZICk7CiAgICAgICAgUGF0Qmx0KCBoZGMsIHJlY3QtPmxlZnQsIHJlY3QtPmJvdHRvbSAtIDEsCiAgICAgICAgICAgICAgICAgIHJlY3QtPnJpZ2h0IC0gcmVjdC0+bGVmdCwgLWhlaWdodCwgUEFUQ09QWSApOwogICAgICAgIFBhdEJsdCggaGRjLCByZWN0LT5yaWdodCAtIDEsIHJlY3QtPnRvcCwKICAgICAgICAgICAgICAgICAgLXdpZHRoLCByZWN0LT5ib3R0b20gLSByZWN0LT50b3AsIFBBVENPUFkgKTsKCiAgICAgICAgSW5mbGF0ZVJlY3QoIHJlY3QsIC13aWR0aCwgLWhlaWdodCApOwogICAgfQp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgICAgICBOQ19EcmF3Q2FwdGlvbgogKgogKiBEcmF3IHRoZSB3aW5kb3cgY2FwdGlvbi4KICogVGhlIGNvcnJlY3QgcGVuIGZvciB0aGUgd2luZG93IGZyYW1lIG11c3QgYmUgc2VsZWN0ZWQgaW4gdGhlIERDLgogKi8Kc3RhdGljIHZvaWQgTkNfRHJhd0NhcHRpb24oIEhEQyBoZGMsIFJFQ1QgKnJlY3QsIEhXTkQgaHduZCwKCQkJICAgIERXT1JEIHN0eWxlLCBCT09MIGFjdGl2ZSApCnsKICAgIFJFQ1QgciA9ICpyZWN0OwogICAgY2hhciBidWZmZXJbMjU2XTsKCiAgICBpZiAoIWhiaXRtYXBDbG9zZSkKICAgIHsKCWlmICghKGhiaXRtYXBDbG9zZSA9IExvYWRCaXRtYXBBKCAwLCBNQUtFSU5UUkVTT1VSQ0VBKE9CTV9PTERfQ0xPU0UpICkpKSByZXR1cm47CiAgICB9CgogICAgaWYgKEdldFdpbmRvd0xvbmdBKCBod25kLCBHV0xfRVhTVFlMRSkgJiBXU19FWF9ETEdNT0RBTEZSQU1FKQogICAgewogICAgICAgIEhCUlVTSCBoYnJ1c2hPbGQgPSBTZWxlY3RPYmplY3QoaGRjLCBHZXRTeXNDb2xvckJydXNoKENPTE9SX1dJTkRPVykgKTsKCVBhdEJsdCggaGRjLCByLmxlZnQsIHIudG9wLCAxLCByLmJvdHRvbS1yLnRvcCsxLFBBVENPUFkgKTsKCVBhdEJsdCggaGRjLCByLnJpZ2h0LTEsIHIudG9wLCAxLCByLmJvdHRvbS1yLnRvcCsxLCBQQVRDT1BZICk7CglQYXRCbHQoIGhkYywgci5sZWZ0LCByLnRvcC0xLCByLnJpZ2h0LXIubGVmdCwgMSwgUEFUQ09QWSApOwoJci5sZWZ0Kys7CglyLnJpZ2h0LS07CglTZWxlY3RPYmplY3QoIGhkYywgaGJydXNoT2xkICk7CiAgICB9CiAgICBNb3ZlVG9FeCggaGRjLCByLmxlZnQsIHIuYm90dG9tLCBOVUxMICk7CiAgICBMaW5lVG8oIGhkYywgci5yaWdodCwgci5ib3R0b20gKTsKCiAgICBpZiAoc3R5bGUgJiBXU19TWVNNRU5VKQogICAgewoJTkNfRHJhd1N5c0J1dHRvbiggaHduZCwgaGRjLCBGQUxTRSApOwoJci5sZWZ0ICs9IEdldFN5c3RlbU1ldHJpY3MoU01fQ1hTSVpFKSArIDE7CglNb3ZlVG9FeCggaGRjLCByLmxlZnQgLSAxLCByLnRvcCwgTlVMTCApOwoJTGluZVRvKCBoZGMsIHIubGVmdCAtIDEsIHIuYm90dG9tICk7CiAgICB9CiAgICBGaWxsUmVjdCggaGRjLCAmciwgR2V0U3lzQ29sb3JCcnVzaChhY3RpdmUgPyBDT0xPUl9BQ1RJVkVDQVBUSU9OIDogQ09MT1JfSU5BQ1RJVkVDQVBUSU9OKSApOwogICAgaWYgKHN0eWxlICYgV1NfTUFYSU1JWkVCT1gpCiAgICB7CglOQ19EcmF3TWF4QnV0dG9uKCBod25kLCBoZGMsIEZBTFNFICk7CglyLnJpZ2h0IC09IEdldFN5c3RlbU1ldHJpY3MoU01fQ1hTSVpFKSArIDE7CiAgICB9CiAgICBpZiAoc3R5bGUgJiBXU19NSU5JTUlaRUJPWCkKICAgIHsKCU5DX0RyYXdNaW5CdXR0b24oIGh3bmQsIGhkYywgRkFMU0UgKTsKCXIucmlnaHQgLT0gR2V0U3lzdGVtTWV0cmljcyhTTV9DWFNJWkUpICsgMTsKICAgIH0KCiAgICBpZiAoR2V0V2luZG93VGV4dEEoIGh3bmQsIGJ1ZmZlciwgc2l6ZW9mKGJ1ZmZlcikgKSkKICAgIHsKCWlmIChhY3RpdmUpIFNldFRleHRDb2xvciggaGRjLCBHZXRTeXNDb2xvciggQ09MT1JfQ0FQVElPTlRFWFQgKSApOwoJZWxzZSBTZXRUZXh0Q29sb3IoIGhkYywgR2V0U3lzQ29sb3IoIENPTE9SX0lOQUNUSVZFQ0FQVElPTlRFWFQgKSApOwoJU2V0QmtNb2RlKCBoZGMsIFRSQU5TUEFSRU5UICk7CglEcmF3VGV4dEEoIGhkYywgYnVmZmVyLCAtMSwgJnIsCiAgICAgICAgICAgICAgICAgICAgIERUX1NJTkdMRUxJTkUgfCBEVF9DRU5URVIgfCBEVF9WQ0VOVEVSIHwgRFRfTk9QUkVGSVggKTsKICAgIH0KfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoKICogICBOQ19EcmF3Q2FwdGlvbjk1KAogKiAgICAgIEhEQyAgaGRjLAogKiAgICAgIFJFQ1QgKnJlY3QsCiAqICAgICAgSFdORCBod25kLAogKiAgICAgIERXT1JEICBzdHlsZSwKICogICAgICBCT09MIGFjdGl2ZSApCiAqCiAqICAgRHJhdyB0aGUgd2luZG93IGNhcHRpb24gZm9yIFdpbjk1IHN0eWxlIHdpbmRvd3MuCiAqICAgVGhlIGNvcnJlY3QgcGVuIGZvciB0aGUgd2luZG93IGZyYW1lIG11c3QgYmUgc2VsZWN0ZWQgaW4gdGhlIERDLgogKgogKiAgIEJ1Z3MKICogICAgICAgIEhleSwgYSBmdW5jdGlvbiB0aGF0IGZpbmFsbHkgd29ya3MhICBXZWxsLCBhbG1vc3QuCiAqICAgICAgICBJdCdzIGJlaW5nIHdvcmtlZCBvbi4KICoKICogICBSZXZpc2lvbiBoaXN0b3J5CiAqICAgICAgICAwNS1KdWwtMTk5NyBEYXZlIEN1dGhiZXJ0IChkYWN1dEBlY2UuY211LmVkdSkKICogICAgICAgICAgICAgT3JpZ2luYWwgaW1wbGVtZW50YXRpb24uCiAqICAgICAgICAwMi1KdW4tMTk5OCBFcmljIEtvaGwgKGVrb2hsQGFiby5yaGVpbi16ZWl0dW5nLmRlKQogKiAgICAgICAgICAgICBTb21lIG1pbm9yIGZpeGVzLgogKgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCgpzdGF0aWMgdm9pZCAgTkNfRHJhd0NhcHRpb245NSgKICAgIEhEQyAgaGRjLAogICAgUkVDVCAqcmVjdCwKICAgIEhXTkQgaHduZCwKICAgIERXT1JEICBzdHlsZSwKICAgIERXT1JEICBleFN0eWxlLAogICAgQk9PTCBhY3RpdmUgKQp7CiAgICBSRUNUICByID0gKnJlY3Q7CiAgICBjaGFyICAgIGJ1ZmZlclsyNTZdOwogICAgSFBFTiAgaFByZXZQZW47CiAgICBITUVOVSBoU3lzTWVudTsKCiAgICBoUHJldlBlbiA9IFNlbGVjdE9iamVjdCggaGRjLCBTWVNDT0xPUl9HZXRQZW4oCiAgICAgICAgICAgICAgICAgICAgICgoZXhTdHlsZSAmIChXU19FWF9TVEFUSUNFREdFfFdTX0VYX0NMSUVOVEVER0V8CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFdTX0VYX0RMR01PREFMRlJBTUUpKSA9PSBXU19FWF9TVEFUSUNFREdFKSA/CiAgICAgICAgICAgICAgICAgICAgICBDT0xPUl9XSU5ET1dGUkFNRSA6IENPTE9SXzNERkFDRSkgKTsKICAgIE1vdmVUb0V4KCBoZGMsIHIubGVmdCwgci5ib3R0b20gLSAxLCBOVUxMICk7CiAgICBMaW5lVG8oIGhkYywgci5yaWdodCwgci5ib3R0b20gLSAxICk7CiAgICBTZWxlY3RPYmplY3QoIGhkYywgaFByZXZQZW4gKTsKICAgIHIuYm90dG9tLS07CgogICAgRmlsbFJlY3QoIGhkYywgJnIsIEdldFN5c0NvbG9yQnJ1c2goYWN0aXZlID8gQ09MT1JfQUNUSVZFQ0FQVElPTiA6CgkJCQkJICAgIENPTE9SX0lOQUNUSVZFQ0FQVElPTikgKTsKCiAgICBpZiAoKHN0eWxlICYgV1NfU1lTTUVOVSkgJiYgIShleFN0eWxlICYgV1NfRVhfVE9PTFdJTkRPVykpIHsKCWlmIChOQ19EcmF3U3lzQnV0dG9uOTUgKGh3bmQsIGhkYywgRkFMU0UpKQoJICAgIHIubGVmdCArPSBHZXRTeXN0ZW1NZXRyaWNzKFNNX0NZQ0FQVElPTikgLSAxOwogICAgfQoKICAgIGlmIChzdHlsZSAmIFdTX1NZU01FTlUpCiAgICB7CglVSU5UIHN0YXRlOwoKCS8qIEdvIGdldCB0aGUgc3lzbWVudSAqLwoJaFN5c01lbnUgPSBHZXRTeXN0ZW1NZW51KGh3bmQsIEZBTFNFKTsKCXN0YXRlID0gR2V0TWVudVN0YXRlKGhTeXNNZW51LCBTQ19DTE9TRSwgTUZfQllDT01NQU5EKTsKCgkvKiBEcmF3IGEgZ3JheWVkIGNsb3NlIGJ1dHRvbiBpZiBkaXNhYmxlZCBhbmQgYSBub3JtYWwgb25lIGlmIFNDX0NMT1NFIGlzIG5vdCB0aGVyZSAqLwoJTkNfRHJhd0Nsb3NlQnV0dG9uOTUgKGh3bmQsIGhkYywgRkFMU0UsCgkJCSAgICAgICgoKChzdGF0ZSAmIE1GX0RJU0FCTEVEKSB8fCAoc3RhdGUgJiBNRl9HUkFZRUQpKSkgJiYgKHN0YXRlICE9IDB4RkZGRkZGRkYpKSk7CglyLnJpZ2h0IC09IEdldFN5c3RlbU1ldHJpY3MoU01fQ1lDQVBUSU9OKSAtIDE7CgoJaWYgKChzdHlsZSAmIFdTX01BWElNSVpFQk9YKSB8fCAoc3R5bGUgJiBXU19NSU5JTUlaRUJPWCkpCgl7CgkgICAgLyogSW4gd2luOTUgdGhlIHR3byBidXR0b25zIGFyZSBhbHdheXMgdGhlcmUgKi8KCSAgICAvKiBCdXQgaWYgdGhlIG1lbnUgaXRlbSBpcyBub3QgaW4gdGhlIG1lbnUgdGhleSdyZSBkaXNhYmxlZCovCgoJICAgIE5DX0RyYXdNYXhCdXR0b245NSggaHduZCwgaGRjLCBGQUxTRSwgKCEoc3R5bGUgJiBXU19NQVhJTUlaRUJPWCkpKTsKCSAgICByLnJpZ2h0IC09IEdldFN5c3RlbU1ldHJpY3MoU01fQ1hTSVpFKSArIDE7CgoJICAgIE5DX0RyYXdNaW5CdXR0b245NSggaHduZCwgaGRjLCBGQUxTRSwgICghKHN0eWxlICYgV1NfTUlOSU1JWkVCT1gpKSk7CgkgICAgci5yaWdodCAtPSBHZXRTeXN0ZW1NZXRyaWNzKFNNX0NYU0laRSkgKyAxOwoJfQogICAgfQoKICAgIGlmIChHZXRXaW5kb3dUZXh0QSggaHduZCwgYnVmZmVyLCBzaXplb2YoYnVmZmVyKSApKSB7CglOT05DTElFTlRNRVRSSUNTQSBuY2xtOwoJSEZPTlQgaEZvbnQsIGhPbGRGb250OwoJbmNsbS5jYlNpemUgPSBzaXplb2YoTk9OQ0xJRU5UTUVUUklDU0EpOwoJU3lzdGVtUGFyYW1ldGVyc0luZm9BIChTUElfR0VUTk9OQ0xJRU5UTUVUUklDUywgMCwgJm5jbG0sIDApOwoJaWYgKGV4U3R5bGUgJiBXU19FWF9UT09MV0lORE9XKQoJICAgIGhGb250ID0gQ3JlYXRlRm9udEluZGlyZWN0QSAoJm5jbG0ubGZTbUNhcHRpb25Gb250KTsKCWVsc2UKCSAgICBoRm9udCA9IENyZWF0ZUZvbnRJbmRpcmVjdEEgKCZuY2xtLmxmQ2FwdGlvbkZvbnQpOwoJaE9sZEZvbnQgPSBTZWxlY3RPYmplY3QgKGhkYywgaEZvbnQpOwoJaWYgKGFjdGl2ZSkgU2V0VGV4dENvbG9yKCBoZGMsIEdldFN5c0NvbG9yKCBDT0xPUl9DQVBUSU9OVEVYVCApICk7CgllbHNlIFNldFRleHRDb2xvciggaGRjLCBHZXRTeXNDb2xvciggQ09MT1JfSU5BQ1RJVkVDQVBUSU9OVEVYVCApICk7CglTZXRCa01vZGUoIGhkYywgVFJBTlNQQVJFTlQgKTsKCXIubGVmdCArPSAyOwoJRHJhd1RleHRBKCBoZGMsIGJ1ZmZlciwgLTEsICZyLAoJCSAgICAgRFRfU0lOR0xFTElORSB8IERUX1ZDRU5URVIgfCBEVF9OT1BSRUZJWCB8IERUX0xFRlQgKTsKCURlbGV0ZU9iamVjdCAoU2VsZWN0T2JqZWN0IChoZGMsIGhPbGRGb250KSk7CiAgICB9Cn0KCgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgICAgICBOQ19Eb05DUGFpbnQKICoKICogUGFpbnQgdGhlIG5vbi1jbGllbnQgYXJlYS4gY2xpcCBpcyBjdXJyZW50bHkgdW51c2VkLgogKi8Kc3RhdGljIHZvaWQgTkNfRG9OQ1BhaW50KCBIV05EIGh3bmQsIEhSR04gY2xpcCwgQk9PTCBzdXBwcmVzc19tZW51cGFpbnQgKQp7CiAgICBIREMgaGRjOwogICAgUkVDVCByZWN0OwogICAgQk9PTCBhY3RpdmU7CiAgICBXTkQgKnduZFB0cjsKICAgIERXT1JEIGR3U3R5bGUsIGR3RXhTdHlsZTsKICAgIFdPUkQgZmxhZ3M7CiAgICBSRUNUIHJlY3RDbGllbnQsIHJlY3RXaW5kb3c7CiAgICBpbnQgaGFzX21lbnU7CgogICAgaWYgKCEod25kUHRyID0gV0lOX0dldFB0ciggaHduZCApKSB8fCB3bmRQdHIgPT0gV05EX09USEVSX1BST0NFU1MpIHJldHVybjsKICAgIGhhc19tZW51ID0gSEFTX01FTlUod25kUHRyKTsKICAgIGR3U3R5bGUgPSB3bmRQdHItPmR3U3R5bGU7CiAgICBkd0V4U3R5bGUgPSB3bmRQdHItPmR3RXhTdHlsZTsKICAgIGZsYWdzID0gd25kUHRyLT5mbGFnczsKICAgIHJlY3RDbGllbnQgPSB3bmRQdHItPnJlY3RDbGllbnQ7CiAgICByZWN0V2luZG93ID0gd25kUHRyLT5yZWN0V2luZG93OwogICAgV0lOX1JlbGVhc2VQdHIoIHduZFB0ciApOwoKICAgIGlmICggZHdTdHlsZSAmIFdTX01JTklNSVpFIHx8CiAgICAgICAgICFXSU5fSXNXaW5kb3dEcmF3YWJsZSggaHduZCwgMCApKSByZXR1cm47IC8qIE5vdGhpbmcgdG8gZG8gKi8KCiAgICBhY3RpdmUgID0gZmxhZ3MgJiBXSU5fTkNBQ1RJVkFURUQ7CgogICAgVFJBQ0UoIiVwICVkXG4iLCBod25kLCBhY3RpdmUgKTsKCiAgICBpZiAoIShoZGMgPSBHZXREQ0V4KCBod25kLCAoY2xpcCA+IChIUkdOKTEpID8gY2xpcCA6IDAsIERDWF9VU0VTVFlMRSB8IERDWF9XSU5ET1cgfAoJCQkgICAgICAoKGNsaXAgPiAoSFJHTikxKSA/IChEQ1hfSU5URVJTRUNUUkdOIHwgRENYX0tFRVBDTElQUkdOKTogMCkgKSkpIHJldHVybjsKCiAgICBpZiAoRXhjbHVkZVZpc1JlY3QxNiggSERDXzE2KGhkYyksIHJlY3RDbGllbnQubGVmdC1yZWN0V2luZG93LmxlZnQsCgkJICAgICAgICByZWN0Q2xpZW50LnRvcC1yZWN0V2luZG93LnRvcCwKCQkgICAgICAgIHJlY3RDbGllbnQucmlnaHQtcmVjdFdpbmRvdy5sZWZ0LAoJCSAgICAgICAgcmVjdENsaWVudC5ib3R0b20tcmVjdFdpbmRvdy50b3AgKQoJPT0gTlVMTFJFR0lPTikKICAgIHsKCVJlbGVhc2VEQyggaHduZCwgaGRjICk7CglyZXR1cm47CiAgICB9CgogICAgcmVjdC50b3AgPSByZWN0LmxlZnQgPSAwOwogICAgcmVjdC5yaWdodCAgPSByZWN0V2luZG93LnJpZ2h0IC0gcmVjdFdpbmRvdy5sZWZ0OwogICAgcmVjdC5ib3R0b20gPSByZWN0V2luZG93LmJvdHRvbSAtIHJlY3RXaW5kb3cudG9wOwoKICAgIFNlbGVjdE9iamVjdCggaGRjLCBTWVNDT0xPUl9HZXRQZW4oQ09MT1JfV0lORE9XRlJBTUUpICk7CgogICAgaWYgKEhBU19BTllGUkFNRSggZHdTdHlsZSwgZHdFeFN0eWxlICkpCiAgICB7CiAgICAgICAgU2VsZWN0T2JqZWN0KCBoZGMsIEdldFN0b2NrT2JqZWN0KE5VTExfQlJVU0gpICk7CiAgICAgICAgUmVjdGFuZ2xlKCBoZGMsIDAsIDAsIHJlY3QucmlnaHQsIHJlY3QuYm90dG9tICk7CiAgICAgICAgSW5mbGF0ZVJlY3QoICZyZWN0LCAtMSwgLTEgKTsKICAgIH0KCiAgICBpZiAoSEFTX1RISUNLRlJBTUUoIGR3U3R5bGUsIGR3RXhTdHlsZSApKQogICAgICAgIE5DX0RyYXdGcmFtZShoZGMsICZyZWN0LCBGQUxTRSwgYWN0aXZlICk7CiAgICBlbHNlIGlmIChIQVNfRExHRlJBTUUoIGR3U3R5bGUsIGR3RXhTdHlsZSApKQogICAgICAgIE5DX0RyYXdGcmFtZSggaGRjLCAmcmVjdCwgVFJVRSwgYWN0aXZlICk7CgogICAgaWYgKChkd1N0eWxlICYgV1NfQ0FQVElPTikgPT0gV1NfQ0FQVElPTikKICAgIHsKICAgICAgICBSRUNUIHIgPSByZWN0OwogICAgICAgIHIuYm90dG9tID0gcmVjdC50b3AgKyBHZXRTeXN0ZW1NZXRyaWNzKFNNX0NZU0laRSk7CiAgICAgICAgcmVjdC50b3AgKz0gR2V0U3lzdGVtTWV0cmljcyhTTV9DWVNJWkUpICsgR2V0U3lzdGVtTWV0cmljcyhTTV9DWUJPUkRFUik7CiAgICAgICAgTkNfRHJhd0NhcHRpb24oIGhkYywgJnIsIGh3bmQsIGR3U3R5bGUsIGFjdGl2ZSApOwogICAgfQoKICAgIGlmIChoYXNfbWVudSkKICAgIHsKCVJFQ1QgciA9IHJlY3Q7CglyLmJvdHRvbSA9IHJlY3QudG9wICsgR2V0U3lzdGVtTWV0cmljcyhTTV9DWU1FTlUpOyAgLyogZGVmYXVsdCBoZWlnaHQgKi8KCXJlY3QudG9wICs9IE1FTlVfRHJhd01lbnVCYXIoIGhkYywgJnIsIGh3bmQsIHN1cHByZXNzX21lbnVwYWludCApOwogICAgfQoKICAgICAgLyogRHJhdyB0aGUgc2Nyb2xsLWJhcnMgKi8KCiAgICBpZiAoZHdTdHlsZSAmIFdTX1ZTQ1JPTEwpCiAgICAgICAgU0NST0xMX0RyYXdTY3JvbGxCYXIoIGh3bmQsIGhkYywgU0JfVkVSVCwgVFJVRSwgVFJVRSApOwogICAgaWYgKGR3U3R5bGUgJiBXU19IU0NST0xMKQogICAgICAgIFNDUk9MTF9EcmF3U2Nyb2xsQmFyKCBod25kLCBoZGMsIFNCX0hPUlosIFRSVUUsIFRSVUUgKTsKCiAgICAgIC8qIERyYXcgdGhlICJzaXplLWJveCIgKi8KCiAgICBpZiAoKGR3U3R5bGUgJiBXU19WU0NST0xMKSAmJiAoZHdTdHlsZSAmIFdTX0hTQ1JPTEwpKQogICAgewogICAgICAgIFJFQ1QgciA9IHJlY3Q7CiAgICAgICAgaWYoKGR3RXhTdHlsZSAmIFdTX0VYX0xFRlRTQ1JPTExCQVIpICE9IDApCiAgICAgICAgICAgIHIucmlnaHQgPSByLmxlZnQgKyBHZXRTeXN0ZW1NZXRyaWNzKFNNX0NYVlNDUk9MTCkgKyAxOwogICAgICAgIGVsc2UKICAgICAgICAgICAgci5sZWZ0ID0gci5yaWdodCAtIEdldFN5c3RlbU1ldHJpY3MoU01fQ1hWU0NST0xMKSArIDE7CiAgICAgICAgci50b3AgID0gci5ib3R0b20gLSBHZXRTeXN0ZW1NZXRyaWNzKFNNX0NZSFNDUk9MTCkgKyAxOwoJaWYod25kUHRyLT5kd1N0eWxlICYgV1NfQk9SREVSKSB7CgkgIHIubGVmdCsrOwoJICByLnRvcCsrOwoJfQogICAgICAgIEZpbGxSZWN0KCBoZGMsICZyLCBHZXRTeXNDb2xvckJydXNoKENPTE9SX1NDUk9MTEJBUikgKTsKICAgIH0KCiAgICBSZWxlYXNlREMoIGh3bmQsIGhkYyApOwp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgogKiAgIHZvaWQgIE5DX0RvTkNQYWludDk1KAogKiAgICAgIEhXTkQgIGh3bmQsCiAqICAgICAgSFJHTiAgY2xpcCwKICogICAgICBCT09MICBzdXBwcmVzc19tZW51cGFpbnQgKQogKgogKiAgIFBhaW50IHRoZSBub24tY2xpZW50IGFyZWEgZm9yIFdpbjk1IHdpbmRvd3MuICBUaGUgY2xpcCByZWdpb24gaXMKICogICBjdXJyZW50bHkgaWdub3JlZC4KICoKICogICBCdWdzCiAqICAgICAgICBncmVwIC1FIC1BMTAgLUI1IFwoOTVcKVx8XChCdWdzXClcfFwoRklYTUVcKSB3aW5kb3dzL25vbmNsaWVudC5jIFwKICogICAgICAgICAgIG1pc2MvdHdlYWsuYyBjb250cm9scy9tZW51LmMgICMgOi0pCiAqCiAqICAgUmV2aXNpb24gaGlzdG9yeQogKiAgICAgICAgMDMtSnVsLTE5OTcgRGF2ZSBDdXRoYmVydCAoZGFjdXRAZWNlLmNtdS5lZHUpCiAqICAgICAgICAgICAgIE9yaWdpbmFsIGltcGxlbWVudGF0aW9uCiAqICAgICAgICAxMC1KdW4tMTk5OCBFcmljIEtvaGwgKGVrb2hsQGFiby5yaGVpbi16ZWl0dW5nLmRlKQogKiAgICAgICAgICAgICBGaXhlZCBzb21lIGJ1Z3MuCiAqICAgICAgICAyOS1KdW4tMTk5OSBPdmUgS+V2ZW4gKG92ZWtAYXJjdGljbmV0Lm5vKQogKiAgICAgICAgICAgICBTdHJlYW1saW5lZCB3aW5kb3cgc3R5bGUgY2hlY2tzLgogKgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCgpzdGF0aWMgdm9pZCAgTkNfRG9OQ1BhaW50OTUoCiAgICBIV05EICBod25kLAogICAgSFJHTiAgY2xpcCwKICAgIEJPT0wgIHN1cHByZXNzX21lbnVwYWludCApCnsKICAgIEhEQyBoZGM7CiAgICBSRUNUIHJmdXp6LCByZWN0LCByZWN0Q2xpcDsKICAgIEJPT0wgYWN0aXZlOwogICAgV05EICp3bmRQdHI7CiAgICBEV09SRCBkd1N0eWxlLCBkd0V4U3R5bGU7CiAgICBXT1JEIGZsYWdzOwogICAgUkVDVCByZWN0Q2xpZW50LCByZWN0V2luZG93OwogICAgaW50IGhhc19tZW51OwoKICAgIGlmICghKHduZFB0ciA9IFdJTl9HZXRQdHIoIGh3bmQgKSkgfHwgd25kUHRyID09IFdORF9PVEhFUl9QUk9DRVNTKSByZXR1cm47CiAgICBoYXNfbWVudSA9IEhBU19NRU5VKHduZFB0cik7CiAgICBkd1N0eWxlID0gd25kUHRyLT5kd1N0eWxlOwogICAgZHdFeFN0eWxlID0gd25kUHRyLT5kd0V4U3R5bGU7CiAgICBmbGFncyA9IHduZFB0ci0+ZmxhZ3M7CiAgICByZWN0Q2xpZW50ID0gd25kUHRyLT5yZWN0Q2xpZW50OwogICAgcmVjdFdpbmRvdyA9IHduZFB0ci0+cmVjdFdpbmRvdzsKICAgIFdJTl9SZWxlYXNlUHRyKCB3bmRQdHIgKTsKCiAgICBpZiAoIGR3U3R5bGUgJiBXU19NSU5JTUlaRSB8fAogICAgICAgICAhV0lOX0lzV2luZG93RHJhd2FibGUoIGh3bmQsIDAgKSkgcmV0dXJuOyAvKiBOb3RoaW5nIHRvIGRvICovCgogICAgYWN0aXZlICA9IGZsYWdzICYgV0lOX05DQUNUSVZBVEVEOwoKICAgIFRSQUNFKCIlcCAlZFxuIiwgaHduZCwgYWN0aXZlICk7CgogICAgLyogTVNETiBkb2NzIGFyZSBwcmV0dHkgaWRpb3RpYyBoZXJlLCB0aGV5IHNheSBhcHAgQ0FOIHVzZSBjbGlwUmduIGluCiAgICAgICB0aGUgY2FsbCB0byBHZXREQ0V4IGltcGx5aW5nIHRoYXQgaXQgaXMgYWxsb3dlZCBub3QgdG8gdXNlIGl0IGVpdGhlci4KICAgICAgIEhvd2V2ZXIsIHRoZSBzdWdnZXN0ZWQgR2V0RENFeCggICAgLCBEQ1hfV0lORE9XIHwgRENYX0lOVEVSU0VDVFJHTikKICAgICAgIHdpbGwgY2F1c2UgY2xpcFJnbiB0byBiZSBkZWxldGVkIGFmdGVyIFJlbGVhc2VEQygpLgogICAgICAgTm93LCBob3cgaXMgdGhlICJzeXN0ZW0iIHN1cHBvc2VkIHRvIHRlbGwgd2hhdCBoYXBwZW5lZD8KICAgICAqLwoKICAgIGlmICghKGhkYyA9IEdldERDRXgoIGh3bmQsIChjbGlwID4gKEhSR04pMSkgPyBjbGlwIDogMCwgRENYX1VTRVNUWUxFIHwgRENYX1dJTkRPVyB8CgkJCSAgICAgICgoY2xpcCA+IChIUkdOKTEpID8oRENYX0lOVEVSU0VDVFJHTiB8IERDWF9LRUVQQ0xJUFJHTikgOiAwKSApKSkgcmV0dXJuOwoKCiAgICBpZiAoRXhjbHVkZVZpc1JlY3QxNiggSERDXzE2KGhkYyksIHJlY3RDbGllbnQubGVmdC1yZWN0V2luZG93LmxlZnQsCgkJICAgICAgICByZWN0Q2xpZW50LnRvcC1yZWN0V2luZG93LnRvcCwKCQkgICAgICAgIHJlY3RDbGllbnQucmlnaHQtcmVjdFdpbmRvdy5sZWZ0LAoJCSAgICAgICAgcmVjdENsaWVudC5ib3R0b20tcmVjdFdpbmRvdy50b3AgKQoJPT0gTlVMTFJFR0lPTikKICAgIHsKCVJlbGVhc2VEQyggaHduZCwgaGRjICk7CglyZXR1cm47CiAgICB9CgogICAgcmVjdC50b3AgPSByZWN0LmxlZnQgPSAwOwogICAgcmVjdC5yaWdodCAgPSByZWN0V2luZG93LnJpZ2h0IC0gcmVjdFdpbmRvdy5sZWZ0OwogICAgcmVjdC5ib3R0b20gPSByZWN0V2luZG93LmJvdHRvbSAtIHJlY3RXaW5kb3cudG9wOwoKICAgIGlmKCBjbGlwID4gKEhSR04pMSApCglHZXRSZ25Cb3goIGNsaXAsICZyZWN0Q2xpcCApOwogICAgZWxzZQogICAgewoJY2xpcCA9IDA7CglyZWN0Q2xpcCA9IHJlY3Q7CiAgICB9CgogICAgU2VsZWN0T2JqZWN0KCBoZGMsIFNZU0NPTE9SX0dldFBlbihDT0xPUl9XSU5ET1dGUkFNRSkgKTsKCiAgICBpZiAoSEFTX1NUQVRJQ09VVEVSRlJBTUUoZHdTdHlsZSwgZHdFeFN0eWxlKSkgewogICAgICAgIERyYXdFZGdlIChoZGMsICZyZWN0LCBCRFJfU1VOS0VOT1VURVIsIEJGX1JFQ1QgfCBCRl9BREpVU1QpOwogICAgfQogICAgZWxzZSBpZiAoSEFTX0JJR0ZSQU1FKCBkd1N0eWxlLCBkd0V4U3R5bGUpKSB7CiAgICAgICAgRHJhd0VkZ2UgKGhkYywgJnJlY3QsIEVER0VfUkFJU0VELCBCRl9SRUNUIHwgQkZfQURKVVNUKTsKICAgIH0KCiAgICBOQ19EcmF3RnJhbWU5NShoZGMsICZyZWN0LCBhY3RpdmUsIGR3U3R5bGUsIGR3RXhTdHlsZSApOwoKICAgIGlmICgoZHdTdHlsZSAmIFdTX0NBUFRJT04pID09IFdTX0NBUFRJT04pCiAgICB7CiAgICAgICAgUkVDVCAgciA9IHJlY3Q7CiAgICAgICAgaWYgKGR3RXhTdHlsZSAmIFdTX0VYX1RPT0xXSU5ET1cpIHsKICAgICAgICAgICAgci5ib3R0b20gPSByZWN0LnRvcCArIEdldFN5c3RlbU1ldHJpY3MoU01fQ1lTTUNBUFRJT04pOwogICAgICAgICAgICByZWN0LnRvcCArPSBHZXRTeXN0ZW1NZXRyaWNzKFNNX0NZU01DQVBUSU9OKTsKICAgICAgICB9CiAgICAgICAgZWxzZSB7CiAgICAgICAgICAgIHIuYm90dG9tID0gcmVjdC50b3AgKyBHZXRTeXN0ZW1NZXRyaWNzKFNNX0NZQ0FQVElPTik7CiAgICAgICAgICAgIHJlY3QudG9wICs9IEdldFN5c3RlbU1ldHJpY3MoU01fQ1lDQVBUSU9OKTsKICAgICAgICB9CiAgICAgICAgaWYoICFjbGlwIHx8IEludGVyc2VjdFJlY3QoICZyZnV6eiwgJnIsICZyZWN0Q2xpcCApICkKICAgICAgICAgICAgTkNfRHJhd0NhcHRpb245NSAoaGRjLCAmciwgaHduZCwgZHdTdHlsZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZHdFeFN0eWxlLCBhY3RpdmUpOwogICAgfQoKICAgIGlmIChoYXNfbWVudSkKICAgIHsKCVJFQ1QgciA9IHJlY3Q7CglyLmJvdHRvbSA9IHJlY3QudG9wICsgR2V0U3lzdGVtTWV0cmljcyhTTV9DWU1FTlUpOwoKCVRSQUNFKCJDYWxsaW5nIERyYXdNZW51QmFyIHdpdGggcmVjdCAoJWxkLCAlbGQpLSglbGQsICVsZClcbiIsCiAgICAgICAgICAgICAgci5sZWZ0LCByLnRvcCwgci5yaWdodCwgci5ib3R0b20pOwoKCXJlY3QudG9wICs9IE1FTlVfRHJhd01lbnVCYXIoIGhkYywgJnIsIGh3bmQsIHN1cHByZXNzX21lbnVwYWludCApICsgMTsKICAgIH0KCiAgICBUUkFDRSgiQWZ0ZXIgTWVudUJhciwgcmVjdCBpcyAoJWxkLCAlbGQpLSglbGQsICVsZCkuXG4iLAogICAgICAgICAgcmVjdC5sZWZ0LCByZWN0LnRvcCwgcmVjdC5yaWdodCwgcmVjdC5ib3R0b20gKTsKCiAgICBpZiAoZHdFeFN0eWxlICYgV1NfRVhfQ0xJRU5URURHRSkKCURyYXdFZGdlIChoZGMsICZyZWN0LCBFREdFX1NVTktFTiwgQkZfUkVDVCB8IEJGX0FESlVTVCk7CgogICAgLyogRHJhdyB0aGUgc2Nyb2xsLWJhcnMgKi8KCiAgICBpZiAoZHdTdHlsZSAmIFdTX1ZTQ1JPTEwpCiAgICAgICAgU0NST0xMX0RyYXdTY3JvbGxCYXIoIGh3bmQsIGhkYywgU0JfVkVSVCwgVFJVRSwgVFJVRSApOwogICAgaWYgKGR3U3R5bGUgJiBXU19IU0NST0xMKQogICAgICAgIFNDUk9MTF9EcmF3U2Nyb2xsQmFyKCBod25kLCBoZGMsIFNCX0hPUlosIFRSVUUsIFRSVUUgKTsKCiAgICAvKiBEcmF3IHRoZSAic2l6ZS1ib3giICovCiAgICBpZiAoKGR3U3R5bGUgJiBXU19WU0NST0xMKSAmJiAoZHdTdHlsZSAmIFdTX0hTQ1JPTEwpKQogICAgewogICAgICAgIFJFQ1QgciA9IHJlY3Q7CiAgICAgICAgaWYoKGR3RXhTdHlsZSAmIFdTX0VYX0xFRlRTQ1JPTExCQVIpICE9IDApCiAgICAgICAgICAgIHIucmlnaHQgPSByLmxlZnQgKyBHZXRTeXN0ZW1NZXRyaWNzKFNNX0NYVlNDUk9MTCkgKyAxOwogICAgICAgIGVsc2UKICAgICAgICAgICAgci5sZWZ0ID0gci5yaWdodCAtIEdldFN5c3RlbU1ldHJpY3MoU01fQ1hWU0NST0xMKSArIDE7CiAgICAgICAgci50b3AgID0gci5ib3R0b20gLSBHZXRTeXN0ZW1NZXRyaWNzKFNNX0NZSFNDUk9MTCkgKyAxOwogICAgICAgIEZpbGxSZWN0KCBoZGMsICZyLCAgR2V0U3lzQ29sb3JCcnVzaChDT0xPUl9TQ1JPTExCQVIpICk7CiAgICB9CgogICAgUmVsZWFzZURDKCBod25kLCBoZGMgKTsKfQoKCgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgICAgICBOQ19IYW5kbGVOQ1BhaW50CiAqCiAqIEhhbmRsZSBhIFdNX05DUEFJTlQgbWVzc2FnZS4gQ2FsbGVkIGZyb20gRGVmV2luZG93UHJvYygpLgogKi8KTE9ORyBOQ19IYW5kbGVOQ1BhaW50KCBIV05EIGh3bmQgLCBIUkdOIGNsaXApCnsKICAgIERXT1JEIGR3U3R5bGUgPSBHZXRXaW5kb3dMb25nVyggaHduZCwgR1dMX1NUWUxFICk7CgogICAgaWYoIGR3U3R5bGUgJiBXU19WSVNJQkxFICkKICAgIHsKCWlmKCBkd1N0eWxlICYgV1NfTUlOSU1JWkUgKQoJICAgIFdJTlBPU19SZWRyYXdJY29uVGl0bGUoIGh3bmQgKTsKCWVsc2UgaWYgKFRXRUFLX1dpbmVMb29rID09IFdJTjMxX0xPT0spCgkgICAgTkNfRG9OQ1BhaW50KCBod25kLCBjbGlwLCBGQUxTRSApOwoJZWxzZQoJICAgIE5DX0RvTkNQYWludDk1KCBod25kLCBjbGlwLCBGQUxTRSApOwogICAgfQogICAgcmV0dXJuIDA7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICAgICAgIE5DX0hhbmRsZU5DQWN0aXZhdGUKICoKICogSGFuZGxlIGEgV01fTkNBQ1RJVkFURSBtZXNzYWdlLiBDYWxsZWQgZnJvbSBEZWZXaW5kb3dQcm9jKCkuCiAqLwpMT05HIE5DX0hhbmRsZU5DQWN0aXZhdGUoIEhXTkQgaHduZCwgV1BBUkFNIHdQYXJhbSApCnsKICAgIFdORCogd25kUHRyID0gV0lOX0ZpbmRXbmRQdHIoIGh3bmQgKTsKCiAgICAvKiBMb3R1cyBOb3RlcyBkcmF3cyBtZW51IGRlc2NyaXB0aW9ucyBpbiB0aGUgY2FwdGlvbiBvZiBpdHMgbWFpbgogICAgICogd2luZG93LiBXaGVuIGl0IHdhbnRzIHRvIHJlc3RvcmUgb3JpZ2luYWwgInN5c3RlbSIgdmlldywgaXQganVzdAogICAgICogc2VuZHMgV01fTkNBQ1RJVkFURSBtZXNzYWdlIHRvIGl0c2VsZi4gQW55IG9wdGltaXphdGlvbnMgaGVyZSBpbgogICAgICogYXR0ZW1wdCB0byBtaW5pbWl6ZSByZWRyYXdpbmdzIGxlYWQgdG8gYSBub3QgcmVzdG9yZWQgY2FwdGlvbi4KICAgICAqLwogICAgaWYgKHduZFB0cikKICAgIHsKCWlmICh3UGFyYW0pIHduZFB0ci0+ZmxhZ3MgfD0gV0lOX05DQUNUSVZBVEVEOwoJZWxzZSB3bmRQdHItPmZsYWdzICY9IH5XSU5fTkNBQ1RJVkFURUQ7CiAgICAgICAgV0lOX1JlbGVhc2VXbmRQdHIod25kUHRyKTsKCglpZiAoSXNJY29uaWMoaHduZCkpIFdJTlBPU19SZWRyYXdJY29uVGl0bGUoIGh3bmQgKTsKCWVsc2UgaWYgKFRXRUFLX1dpbmVMb29rID09IFdJTjMxX0xPT0spCgkgICAgTkNfRG9OQ1BhaW50KCBod25kLCAoSFJHTikxLCBGQUxTRSApOwoJZWxzZQoJICAgIE5DX0RvTkNQYWludDk1KCBod25kLCAoSFJHTikxLCBGQUxTRSApOwogICAgfQogICAgcmV0dXJuIFRSVUU7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICAgICAgIE5DX0hhbmRsZVNldEN1cnNvcgogKgogKiBIYW5kbGUgYSBXTV9TRVRDVVJTT1IgbWVzc2FnZS4gQ2FsbGVkIGZyb20gRGVmV2luZG93UHJvYygpLgogKi8KTE9ORyBOQ19IYW5kbGVTZXRDdXJzb3IoIEhXTkQgaHduZCwgV1BBUkFNIHdQYXJhbSwgTFBBUkFNIGxQYXJhbSApCnsKICAgIGh3bmQgPSBXSU5fR2V0RnVsbEhhbmRsZSggKEhXTkQpd1BhcmFtICk7CgogICAgc3dpdGNoKExPV09SRChsUGFyYW0pKQogICAgewogICAgY2FzZSBIVEVSUk9SOgoJewoJICAgIFdPUkQgbXNnID0gSElXT1JEKCBsUGFyYW0gKTsKCSAgICBpZiAoKG1zZyA9PSBXTV9MQlVUVE9ORE9XTikgfHwgKG1zZyA9PSBXTV9NQlVUVE9ORE9XTikgfHwKCQkobXNnID09IFdNX1JCVVRUT05ET1dOKSkKCQlNZXNzYWdlQmVlcCgwKTsKCX0KCWJyZWFrOwoKICAgIGNhc2UgSFRDTElFTlQ6Cgl7CgkgICAgSENVUlNPUiBoQ3Vyc29yID0gKEhDVVJTT1IpR2V0Q2xhc3NMb25nQShod25kLCBHQ0xfSENVUlNPUik7CgkgICAgaWYoaEN1cnNvcikgewoJCVNldEN1cnNvcihoQ3Vyc29yKTsKCQlyZXR1cm4gVFJVRTsKCSAgICB9CiAgICAgICAgICAgIHJldHVybiBGQUxTRTsKCX0KCiAgICBjYXNlIEhUTEVGVDoKICAgIGNhc2UgSFRSSUdIVDoKCXJldHVybiAoTE9ORylTZXRDdXJzb3IoIExvYWRDdXJzb3JBKCAwLCAoTFBTVFIpSURDX1NJWkVXRSApICk7CgogICAgY2FzZSBIVFRPUDoKICAgIGNhc2UgSFRCT1RUT006CglyZXR1cm4gKExPTkcpU2V0Q3Vyc29yKCBMb2FkQ3Vyc29yQSggMCwgKExQU1RSKUlEQ19TSVpFTlMgKSApOwoKICAgIGNhc2UgSFRUT1BMRUZUOgogICAgY2FzZSBIVEJPVFRPTVJJR0hUOgoJcmV0dXJuIChMT05HKVNldEN1cnNvciggTG9hZEN1cnNvckEoIDAsIChMUFNUUilJRENfU0laRU5XU0UgKSApOwoKICAgIGNhc2UgSFRUT1BSSUdIVDoKICAgIGNhc2UgSFRCT1RUT01MRUZUOgoJcmV0dXJuIChMT05HKVNldEN1cnNvciggTG9hZEN1cnNvckEoIDAsIChMUFNUUilJRENfU0laRU5FU1cgKSApOwogICAgfQoKICAgIC8qIERlZmF1bHQgY3Vyc29yOiBhcnJvdyAqLwogICAgcmV0dXJuIChMT05HKVNldEN1cnNvciggTG9hZEN1cnNvckEoIDAsIChMUFNUUilJRENfQVJST1cgKSApOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICAgICAgIE5DX0dldFN5c1BvcHVwUG9zCiAqLwp2b2lkIE5DX0dldFN5c1BvcHVwUG9zKCBIV05EIGh3bmQsIFJFQ1QqIHJlY3QgKQp7CiAgICBpZiAoSXNJY29uaWMoaHduZCkpIEdldFdpbmRvd1JlY3QoIGh3bmQsIHJlY3QgKTsKICAgIGVsc2UKICAgIHsKICAgICAgICBXTkQgKnduZFB0ciA9IFdJTl9GaW5kV25kUHRyKCBod25kICk7CiAgICAgICAgaWYgKCF3bmRQdHIpIHJldHVybjsKCiAgICAgICAgTkNfR2V0SW5zaWRlUmVjdCggaHduZCwgcmVjdCApOwogICAgICAgIE9mZnNldFJlY3QoIHJlY3QsIHduZFB0ci0+cmVjdFdpbmRvdy5sZWZ0LCB3bmRQdHItPnJlY3RXaW5kb3cudG9wKTsKICAgICAgICBpZiAod25kUHRyLT5kd1N0eWxlICYgV1NfQ0hJTEQpCiAgICAgICAgICAgIENsaWVudFRvU2NyZWVuKCBHZXRQYXJlbnQoaHduZCksIChQT0lOVCAqKXJlY3QgKTsKICAgICAgICBpZiAoVFdFQUtfV2luZUxvb2sgPT0gV0lOMzFfTE9PSykgewogICAgICAgICAgICByZWN0LT5yaWdodCA9IHJlY3QtPmxlZnQgKyBHZXRTeXN0ZW1NZXRyaWNzKFNNX0NYU0laRSk7CiAgICAgICAgICAgIHJlY3QtPmJvdHRvbSA9IHJlY3QtPnRvcCArIEdldFN5c3RlbU1ldHJpY3MoU01fQ1lTSVpFKTsKICAgICAgICB9CiAgICAgICAgZWxzZSB7CiAgICAgICAgICAgIHJlY3QtPnJpZ2h0ID0gcmVjdC0+bGVmdCArIEdldFN5c3RlbU1ldHJpY3MoU01fQ1lDQVBUSU9OKSAtIDE7CiAgICAgICAgICAgIHJlY3QtPmJvdHRvbSA9IHJlY3QtPnRvcCArIEdldFN5c3RlbU1ldHJpY3MoU01fQ1lDQVBUSU9OKSAtIDE7CiAgICAgICAgfQogICAgICAgIFdJTl9SZWxlYXNlV25kUHRyKCB3bmRQdHIgKTsKICAgIH0KfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgICAgICBOQ19UcmFja01pbk1heEJveDk1CiAqCiAqIFRyYWNrIGEgbW91c2UgYnV0dG9uIHByZXNzIG9uIHRoZSBtaW5pbWl6ZSBvciBtYXhpbWl6ZSBib3guCiAqCiAqIFRoZSBiaWcgZGlmZmVyZW5jZSBiZXR3ZWVuIDMuMSBhbmQgOTUgaXMgdGhlIGRpc2FibGVkIGJ1dHRvbiBzdGF0ZS4KICogSW4gd2luOTUgdGhlIHN5c3RlbSBidXR0b24gY2FuIGJlIGRpc2FibGVkLCBzbyBpdCBjYW4gaWdub3JlIHRoZSBtb3VzZQogKiBldmVudC4KICoKICovCnN0YXRpYyB2b2lkIE5DX1RyYWNrTWluTWF4Qm94OTUoIEhXTkQgaHduZCwgV09SRCB3UGFyYW0gKQp7CiAgICBNU0cgbXNnOwogICAgSERDIGhkYyA9IEdldFdpbmRvd0RDKCBod25kICk7CiAgICBCT09MIHByZXNzZWQgPSBUUlVFOwogICAgVUlOVCBzdGF0ZTsKICAgIERXT1JEIHduZFN0eWxlID0gR2V0V2luZG93TG9uZ0EoIGh3bmQsIEdXTF9TVFlMRSk7CiAgICBITUVOVSBoU3lzTWVudSA9IEdldFN5c3RlbU1lbnUoaHduZCwgRkFMU0UpOwoKICAgIHZvaWQgICgqcGFpbnRCdXR0b24pKEhXTkQsIEhEQywgQk9PTCwgQk9PTCk7CgogICAgaWYgKHdQYXJhbSA9PSBIVE1JTkJVVFRPTikKICAgIHsKCS8qIElmIHRoZSBzdHlsZSBpcyBub3QgcHJlc2VudCwgZG8gbm90aGluZyAqLwoJaWYgKCEod25kU3R5bGUgJiBXU19NSU5JTUlaRUJPWCkpCgkgICAgcmV0dXJuOwoKCS8qIENoZWNrIGlmIHRoZSBzeXNtZW51IGl0ZW0gZm9yIG1pbmltaXplIGlzIHRoZXJlICAqLwoJc3RhdGUgPSBHZXRNZW51U3RhdGUoaFN5c01lbnUsIFNDX01JTklNSVpFLCBNRl9CWUNPTU1BTkQpOwoKCXBhaW50QnV0dG9uID0gJk5DX0RyYXdNaW5CdXR0b245NTsKICAgIH0KICAgIGVsc2UKICAgIHsKCS8qIElmIHRoZSBzdHlsZSBpcyBub3QgcHJlc2VudCwgZG8gbm90aGluZyAqLwoJaWYgKCEod25kU3R5bGUgJiBXU19NQVhJTUlaRUJPWCkpCgkgICAgcmV0dXJuOwoKCS8qIENoZWNrIGlmIHRoZSBzeXNtZW51IGl0ZW0gZm9yIG1heGltaXplIGlzIHRoZXJlICAqLwoJc3RhdGUgPSBHZXRNZW51U3RhdGUoaFN5c01lbnUsIFNDX01BWElNSVpFLCBNRl9CWUNPTU1BTkQpOwoKCXBhaW50QnV0dG9uID0gJk5DX0RyYXdNYXhCdXR0b245NTsKICAgIH0KCiAgICBTZXRDYXB0dXJlKCBod25kICk7CgogICAgKCpwYWludEJ1dHRvbikoIGh3bmQsIGhkYywgVFJVRSwgRkFMU0UpOwoKICAgIHdoaWxlKDEpCiAgICB7CglCT09MIG9sZHN0YXRlID0gcHJlc3NlZDsKCiAgICAgICAgaWYgKCFHZXRNZXNzYWdlVyggJm1zZywgMCwgV01fTU9VU0VGSVJTVCwgV01fTU9VU0VMQVNUICkpIGJyZWFrOwogICAgICAgIGlmIChDYWxsTXNnRmlsdGVyVyggJm1zZywgTVNHRl9NQVggKSkgY29udGludWU7CgoJaWYobXNnLm1lc3NhZ2UgPT0gV01fTEJVVFRPTlVQKQoJICAgIGJyZWFrOwoKCWlmKG1zZy5tZXNzYWdlICE9IFdNX01PVVNFTU9WRSkKCSAgICBjb250aW51ZTsKCglwcmVzc2VkID0gKE5DX0hhbmRsZU5DSGl0VGVzdCggaHduZCwgbXNnLnB0ICkgPT0gd1BhcmFtKTsKCWlmIChwcmVzc2VkICE9IG9sZHN0YXRlKQoJICAgKCpwYWludEJ1dHRvbikoIGh3bmQsIGhkYywgcHJlc3NlZCwgRkFMU0UpOwogICAgfQoKICAgIGlmKHByZXNzZWQpCgkoKnBhaW50QnV0dG9uKShod25kLCBoZGMsIEZBTFNFLCBGQUxTRSk7CgogICAgUmVsZWFzZUNhcHR1cmUoKTsKICAgIFJlbGVhc2VEQyggaHduZCwgaGRjICk7CgogICAgLyogSWYgdGhlIGl0ZW0gbWluaW1pemUgb3IgbWF4aW1pemUgb2YgdGhlIHN5c21lbnUgYXJlIG5vdCB0aGVyZSAqLwogICAgLyogb3IgaWYgdGhlIHN0eWxlIGlzIG5vdCBwcmVzZW50LCBkbyBub3RoaW5nICovCiAgICBpZiAoKCFwcmVzc2VkKSB8fCAoc3RhdGUgPT0gMHhGRkZGRkZGRikpCglyZXR1cm47CgogICAgaWYgKHdQYXJhbSA9PSBIVE1JTkJVVFRPTikKICAgICAgICBTZW5kTWVzc2FnZUEoIGh3bmQsIFdNX1NZU0NPTU1BTkQsIFNDX01JTklNSVpFLCBNQUtFTE9ORyhtc2cucHQueCxtc2cucHQueSkgKTsKICAgIGVsc2UKICAgICAgICBTZW5kTWVzc2FnZUEoIGh3bmQsIFdNX1NZU0NPTU1BTkQsCiAgICAgICAgICAgICAgICAgICAgICBJc1pvb21lZChod25kKSA/IFNDX1JFU1RPUkU6U0NfTUFYSU1JWkUsIE1BS0VMT05HKG1zZy5wdC54LG1zZy5wdC55KSApOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICAgICAgIE5DX1RyYWNrTWluTWF4Qm94CiAqCiAqIFRyYWNrIGEgbW91c2UgYnV0dG9uIHByZXNzIG9uIHRoZSBtaW5pbWl6ZSBvciBtYXhpbWl6ZSBib3guCiAqLwpzdGF0aWMgdm9pZCBOQ19UcmFja01pbk1heEJveCggSFdORCBod25kLCBXT1JEIHdQYXJhbSApCnsKICAgIE1TRyBtc2c7CiAgICBIREMgaGRjID0gR2V0V2luZG93REMoIGh3bmQgKTsKICAgIEJPT0wgcHJlc3NlZCA9IFRSVUU7CiAgICB2b2lkICAoKnBhaW50QnV0dG9uKShIV05ELCBIREMsIEJPT0wpOwoKICAgIFNldENhcHR1cmUoIGh3bmQgKTsKCiAgICBpZiAod1BhcmFtID09IEhUTUlOQlVUVE9OKQoJcGFpbnRCdXR0b24gPSAmTkNfRHJhd01pbkJ1dHRvbjsKICAgIGVsc2UKCXBhaW50QnV0dG9uID0gJk5DX0RyYXdNYXhCdXR0b247CgogICAgKCpwYWludEJ1dHRvbikoIGh3bmQsIGhkYywgVFJVRSk7CgogICAgd2hpbGUoMSkKICAgIHsKCUJPT0wgb2xkc3RhdGUgPSBwcmVzc2VkOwoKICAgICAgICBpZiAoIUdldE1lc3NhZ2VXKCAmbXNnLCAwLCBXTV9NT1VTRUZJUlNULCBXTV9NT1VTRUxBU1QgKSkgYnJlYWs7CiAgICAgICAgaWYgKENhbGxNc2dGaWx0ZXJXKCAmbXNnLCBNU0dGX01BWCApKSBjb250aW51ZTsKCglpZihtc2cubWVzc2FnZSA9PSBXTV9MQlVUVE9OVVApCgkgICAgYnJlYWs7CgoJaWYobXNnLm1lc3NhZ2UgIT0gV01fTU9VU0VNT1ZFKQoJICAgIGNvbnRpbnVlOwoKCXByZXNzZWQgPSAoTkNfSGFuZGxlTkNIaXRUZXN0KCBod25kLCBtc2cucHQgKSA9PSB3UGFyYW0pOwoJaWYgKHByZXNzZWQgIT0gb2xkc3RhdGUpCgkgICAoKnBhaW50QnV0dG9uKSggaHduZCwgaGRjLCBwcmVzc2VkKTsKICAgIH0KCiAgICBpZihwcmVzc2VkKQoJKCpwYWludEJ1dHRvbikoIGh3bmQsIGhkYywgRkFMU0UpOwoKICAgIFJlbGVhc2VDYXB0dXJlKCk7CiAgICBSZWxlYXNlREMoIGh3bmQsIGhkYyApOwoKICAgIGlmICghcHJlc3NlZCkgcmV0dXJuOwoKICAgIGlmICh3UGFyYW0gPT0gSFRNSU5CVVRUT04pCiAgICAgICAgU2VuZE1lc3NhZ2VBKCBod25kLCBXTV9TWVNDT01NQU5ELCBTQ19NSU5JTUlaRSwgTUFLRUxPTkcobXNnLnB0LngsbXNnLnB0LnkpICk7CiAgICBlbHNlCiAgICAgICAgU2VuZE1lc3NhZ2VBKCBod25kLCBXTV9TWVNDT01NQU5ELAogICAgICAgICAgICAgICAgICAgICAgSXNab29tZWQoaHduZCkgPyBTQ19SRVNUT1JFOlNDX01BWElNSVpFLCBNQUtFTE9ORyhtc2cucHQueCxtc2cucHQueSkgKTsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBOQ19UcmFja0Nsb3NlQnV0dG9uOTUKICoKICogVHJhY2sgYSBtb3VzZSBidXR0b24gcHJlc3Mgb24gdGhlIFdpbjk1IGNsb3NlIGJ1dHRvbi4KICovCnN0YXRpYyB2b2lkCk5DX1RyYWNrQ2xvc2VCdXR0b245NSAoSFdORCBod25kLCBXT1JEIHdQYXJhbSkKewogICAgTVNHIG1zZzsKICAgIEhEQyBoZGM7CiAgICBCT09MIHByZXNzZWQgPSBUUlVFOwogICAgSE1FTlUgaFN5c01lbnUgPSBHZXRTeXN0ZW1NZW51KGh3bmQsIEZBTFNFKTsKICAgIFVJTlQgc3RhdGU7CgogICAgaWYoaFN5c01lbnUgPT0gMCkKCXJldHVybjsKCiAgICBzdGF0ZSA9IEdldE1lbnVTdGF0ZShoU3lzTWVudSwgU0NfQ0xPU0UsIE1GX0JZQ09NTUFORCk7CgogICAgLyogSWYgdGhlIGl0ZW0gY2xvc2Ugb2YgdGhlIHN5c21lbnUgaXMgZGlzYWJsZWQgb3Igbm90IHRoZXJlIGRvIG5vdGhpbmcgKi8KICAgIGlmKChzdGF0ZSAmIE1GX0RJU0FCTEVEKSB8fCAoc3RhdGUgJiBNRl9HUkFZRUQpIHx8IChzdGF0ZSA9PSAweEZGRkZGRkZGKSkKCXJldHVybjsKCiAgICBoZGMgPSBHZXRXaW5kb3dEQyggaHduZCApOwoKICAgIFNldENhcHR1cmUoIGh3bmQgKTsKCiAgICBOQ19EcmF3Q2xvc2VCdXR0b245NSAoaHduZCwgaGRjLCBUUlVFLCBGQUxTRSk7CgogICAgd2hpbGUoMSkKICAgIHsKCUJPT0wgb2xkc3RhdGUgPSBwcmVzc2VkOwoKICAgICAgICBpZiAoIUdldE1lc3NhZ2VXKCAmbXNnLCAwLCBXTV9NT1VTRUZJUlNULCBXTV9NT1VTRUxBU1QgKSkgYnJlYWs7CiAgICAgICAgaWYgKENhbGxNc2dGaWx0ZXJXKCAmbXNnLCBNU0dGX01BWCApKSBjb250aW51ZTsKCglpZihtc2cubWVzc2FnZSA9PSBXTV9MQlVUVE9OVVApCgkgICAgYnJlYWs7CgoJaWYobXNnLm1lc3NhZ2UgIT0gV01fTU9VU0VNT1ZFKQoJICAgIGNvbnRpbnVlOwoKCXByZXNzZWQgPSAoTkNfSGFuZGxlTkNIaXRUZXN0KCBod25kLCBtc2cucHQgKSA9PSB3UGFyYW0pOwoJaWYgKHByZXNzZWQgIT0gb2xkc3RhdGUpCgkgICBOQ19EcmF3Q2xvc2VCdXR0b245NSAoaHduZCwgaGRjLCBwcmVzc2VkLCBGQUxTRSk7CiAgICB9CgogICAgaWYocHJlc3NlZCkKCU5DX0RyYXdDbG9zZUJ1dHRvbjk1IChod25kLCBoZGMsIEZBTFNFLCBGQUxTRSk7CgogICAgUmVsZWFzZUNhcHR1cmUoKTsKICAgIFJlbGVhc2VEQyggaHduZCwgaGRjICk7CiAgICBpZiAoIXByZXNzZWQpIHJldHVybjsKCiAgICBTZW5kTWVzc2FnZUEoIGh3bmQsIFdNX1NZU0NPTU1BTkQsIFNDX0NMT1NFLCBNQUtFTE9ORyhtc2cucHQueCxtc2cucHQueSkgKTsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgICAgICAgTkNfVHJhY2tTY3JvbGxCYXIKICoKICogVHJhY2sgYSBtb3VzZSBidXR0b24gcHJlc3Mgb24gdGhlIGhvcml6b250YWwgb3IgdmVydGljYWwgc2Nyb2xsLWJhci4KICovCnN0YXRpYyB2b2lkIE5DX1RyYWNrU2Nyb2xsQmFyKCBIV05EIGh3bmQsIFdQQVJBTSB3UGFyYW0sIFBPSU5UIHB0ICkKewogICAgSU5UIHNjcm9sbGJhcjsKCiAgICBpZiAoKHdQYXJhbSAmIDB4ZmZmMCkgPT0gU0NfSFNDUk9MTCkKICAgIHsKICAgICAgICBpZiAoKHdQYXJhbSAmIDB4MGYpICE9IEhUSFNDUk9MTCkgcmV0dXJuOwoJc2Nyb2xsYmFyID0gU0JfSE9SWjsKICAgIH0KICAgIGVsc2UgIC8qIFNDX1ZTQ1JPTEwgKi8KICAgIHsKICAgICAgICBpZiAoKHdQYXJhbSAmIDB4MGYpICE9IEhUVlNDUk9MTCkgcmV0dXJuOwoJc2Nyb2xsYmFyID0gU0JfVkVSVDsKICAgIH0KICAgIFNDUk9MTF9UcmFja1Njcm9sbEJhciggaHduZCwgc2Nyb2xsYmFyLCBwdCApOwp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgICAgICBOQ19IYW5kbGVOQ0xCdXR0b25Eb3duCiAqCiAqIEhhbmRsZSBhIFdNX05DTEJVVFRPTkRPV04gbWVzc2FnZS4gQ2FsbGVkIGZyb20gRGVmV2luZG93UHJvYygpLgogKi8KTE9ORyBOQ19IYW5kbGVOQ0xCdXR0b25Eb3duKCBIV05EIGh3bmQsIFdQQVJBTSB3UGFyYW0sIExQQVJBTSBsUGFyYW0gKQp7CiAgICBMT05HIHN0eWxlID0gR2V0V2luZG93TG9uZ0EoIGh3bmQsIEdXTF9TVFlMRSApOwoKICAgIHN3aXRjaCh3UGFyYW0pICAvKiBIaXQgdGVzdCAqLwogICAgewogICAgY2FzZSBIVENBUFRJT046CiAgICAgICAgewogICAgICAgICAgICBIV05EIHRvcCA9IEdldEFuY2VzdG9yKCBod25kLCBHQV9ST09UICk7CgogICAgICAgICAgICBpZiAoRk9DVVNfTW91c2VBY3RpdmF0ZSggdG9wICkgfHwgKEdldEFjdGl2ZVdpbmRvdygpID09IHRvcCkpCiAgICAgICAgICAgICAgICBTZW5kTWVzc2FnZVcoIGh3bmQsIFdNX1NZU0NPTU1BTkQsIFNDX01PVkUgKyBIVENBUFRJT04sIGxQYXJhbSApOwogICAgICAgICAgICBicmVhazsKICAgICAgICB9CgogICAgY2FzZSBIVFNZU01FTlU6CgkgaWYoIHN0eWxlICYgV1NfU1lTTUVOVSApCgkgewoJICAgICBpZiggIShzdHlsZSAmIFdTX01JTklNSVpFKSApCgkgICAgIHsKCQlIREMgaERDID0gR2V0V2luZG93REMoaHduZCk7CgkJaWYgKFRXRUFLX1dpbmVMb29rID09IFdJTjMxX0xPT0spCgkJICAgIE5DX0RyYXdTeXNCdXR0b24oIGh3bmQsIGhEQywgVFJVRSApOwoJCWVsc2UKCQkgICAgTkNfRHJhd1N5c0J1dHRvbjk1KCBod25kLCBoREMsIFRSVUUgKTsKCQlSZWxlYXNlREMoIGh3bmQsIGhEQyApOwoJICAgICB9CgkgICAgIFNlbmRNZXNzYWdlVyggaHduZCwgV01fU1lTQ09NTUFORCwgU0NfTU9VU0VNRU5VICsgSFRTWVNNRU5VLCBsUGFyYW0gKTsKCSB9CgkgYnJlYWs7CgogICAgY2FzZSBIVE1FTlU6CglTZW5kTWVzc2FnZVcoIGh3bmQsIFdNX1NZU0NPTU1BTkQsIFNDX01PVVNFTUVOVSwgbFBhcmFtICk7CglicmVhazsKCiAgICBjYXNlIEhUSFNDUk9MTDoKCVNlbmRNZXNzYWdlVyggaHduZCwgV01fU1lTQ09NTUFORCwgU0NfSFNDUk9MTCArIEhUSFNDUk9MTCwgbFBhcmFtICk7CglicmVhazsKCiAgICBjYXNlIEhUVlNDUk9MTDoKCVNlbmRNZXNzYWdlVyggaHduZCwgV01fU1lTQ09NTUFORCwgU0NfVlNDUk9MTCArIEhUVlNDUk9MTCwgbFBhcmFtICk7CglicmVhazsKCiAgICBjYXNlIEhUTUlOQlVUVE9OOgogICAgY2FzZSBIVE1BWEJVVFRPTjoKCWlmIChUV0VBS19XaW5lTG9vayA9PSBXSU4zMV9MT09LKQoJICAgIE5DX1RyYWNrTWluTWF4Qm94KCBod25kLCB3UGFyYW0gKTsKCWVsc2UKCSAgICBOQ19UcmFja01pbk1heEJveDk1KCBod25kLCB3UGFyYW0gKTsKCWJyZWFrOwoKICAgIGNhc2UgSFRDTE9TRToKCWlmIChUV0VBS19XaW5lTG9vayA+PSBXSU45NV9MT09LKQoJICAgIE5DX1RyYWNrQ2xvc2VCdXR0b245NSAoaHduZCwgd1BhcmFtKTsKCWJyZWFrOwoKICAgIGNhc2UgSFRMRUZUOgogICAgY2FzZSBIVFJJR0hUOgogICAgY2FzZSBIVFRPUDoKICAgIGNhc2UgSFRUT1BMRUZUOgogICAgY2FzZSBIVFRPUFJJR0hUOgogICAgY2FzZSBIVEJPVFRPTToKICAgIGNhc2UgSFRCT1RUT01MRUZUOgogICAgY2FzZSBIVEJPVFRPTVJJR0hUOgogICAgICAgIC8qIE9sZCBjb21tZW50OgogICAgICAgICAqICJtYWtlIHN1cmUgaGl0dGVzdCBmaXRzIGludG8gMHhmIGFuZCBkb2Vzbid0IG92ZXJsYXAgd2l0aCBIVFNZU01FTlUiCiAgICAgICAgICogVGhpcyB3YXMgcHJldmlvdXNseSBkb25lIGJ5IHNldHRpbmcgd1BhcmFtPVNDX1NJWkUgKyB3UGFyYW0gLSAyCiAgICAgICAgICovCiAgICAgICAgLyogQnV0IHRoYXQgaXMgbm90IHdoYXQgV2luTlQgZG9lcy4gSW5zdGVhZCBpdCBzZW5kcyB0aGlzLiBUaGlzCiAgICAgICAgICogaXMgZWFzeSB0byBkaWZmZXJlbnRpYXRlIGZyb20gSFRTWVNNRU5VLCBiZWNhdXNlIEhUU1lTTUVOVSBhZGRzCiAgICAgICAgICogU0NfTU9VU0VNRU5VIGludG8gd1BhcmFtLgogICAgICAgICAqLwogICAgICAgIFNlbmRNZXNzYWdlVyggaHduZCwgV01fU1lTQ09NTUFORCwgU0NfU0laRSArIHdQYXJhbSAtIChIVExFRlQtV01TWl9MRUZUKSwgbFBhcmFtKTsKCWJyZWFrOwoKICAgIGNhc2UgSFRCT1JERVI6CglicmVhazsKICAgIH0KICAgIHJldHVybiAwOwp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgICAgICBOQ19IYW5kbGVOQ0xCdXR0b25EYmxDbGsKICoKICogSGFuZGxlIGEgV01fTkNMQlVUVE9OREJMQ0xLIG1lc3NhZ2UuIENhbGxlZCBmcm9tIERlZldpbmRvd1Byb2MoKS4KICovCkxPTkcgTkNfSGFuZGxlTkNMQnV0dG9uRGJsQ2xrKCBIV05EIGh3bmQsIFdQQVJBTSB3UGFyYW0sIExQQVJBTSBsUGFyYW0gKQp7CiAgICAvKgogICAgICogaWYgdGhpcyBpcyBhbiBpY29uLCBzZW5kIGEgcmVzdG9yZSBzaW5jZSB3ZSBhcmUgaGFuZGxpbmcKICAgICAqIGEgZG91YmxlIGNsaWNrCiAgICAgKi8KICAgIGlmIChJc0ljb25pYyhod25kKSkKICAgIHsKICAgICAgICBTZW5kTWVzc2FnZVcoIGh3bmQsIFdNX1NZU0NPTU1BTkQsIFNDX1JFU1RPUkUsIGxQYXJhbSApOwogICAgICAgIHJldHVybiAwOwogICAgfQoKICAgIHN3aXRjaCh3UGFyYW0pICAvKiBIaXQgdGVzdCAqLwogICAgewogICAgY2FzZSBIVENBUFRJT046CiAgICAgICAgLyogc3RvcCBwcm9jZXNzaW5nIGlmIFdTX01BWElNSVpFQk9YIGlzIG1pc3NpbmcgKi8KICAgICAgICBpZiAoR2V0V2luZG93TG9uZ0EoIGh3bmQsIEdXTF9TVFlMRSApICYgV1NfTUFYSU1JWkVCT1gpCiAgICAgICAgICAgIFNlbmRNZXNzYWdlVyggaHduZCwgV01fU1lTQ09NTUFORCwKICAgICAgICAgICAgICAgICAgICAgICAgICBJc1pvb21lZChod25kKSA/IFNDX1JFU1RPUkUgOiBTQ19NQVhJTUlaRSwgbFBhcmFtICk7CglicmVhazsKCiAgICBjYXNlIEhUU1lTTUVOVToKICAgICAgICBpZiAoIShHZXRDbGFzc0xvbmdXKGh3bmQsIEdDTF9TVFlMRSkgJiBDU19OT0NMT1NFKSkKICAgICAgICAgICAgU2VuZE1lc3NhZ2VXKCBod25kLCBXTV9TWVNDT01NQU5ELCBTQ19DTE9TRSwgbFBhcmFtICk7CglicmVhazsKCiAgICBjYXNlIEhUSFNDUk9MTDoKICAgICAgICBTZW5kTWVzc2FnZVcoIGh3bmQsIFdNX1NZU0NPTU1BTkQsIFNDX0hTQ1JPTEwgKyBIVEhTQ1JPTEwsIGxQYXJhbSApOwoJYnJlYWs7CgogICAgY2FzZSBIVFZTQ1JPTEw6CiAgICAgICAgU2VuZE1lc3NhZ2VXKCBod25kLCBXTV9TWVNDT01NQU5ELCBTQ19WU0NST0xMICsgSFRWU0NST0xMLCBsUGFyYW0gKTsKCWJyZWFrOwogICAgfQogICAgcmV0dXJuIDA7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICAgICAgIE5DX0hhbmRsZVN5c0NvbW1hbmQKICoKICogSGFuZGxlIGEgV01fU1lTQ09NTUFORCBtZXNzYWdlLiBDYWxsZWQgZnJvbSBEZWZXaW5kb3dQcm9jKCkuCiAqLwpMT05HIE5DX0hhbmRsZVN5c0NvbW1hbmQoIEhXTkQgaHduZCwgV1BBUkFNIHdQYXJhbSwgTFBBUkFNIGxQYXJhbSApCnsKICAgIFRSQUNFKCJIYW5kbGluZyBXTV9TWVNDT01NQU5EICV4ICVseFxuIiwgd1BhcmFtLCBsUGFyYW0gKTsKCiAgICBzd2l0Y2ggKHdQYXJhbSAmIDB4ZmZmMCkKICAgIHsKICAgIGNhc2UgU0NfU0laRToKICAgIGNhc2UgU0NfTU9WRToKICAgICAgICBpZiAoVVNFUl9Ecml2ZXIucFN5c0NvbW1hbmRTaXplTW92ZSkKICAgICAgICAgICAgVVNFUl9Ecml2ZXIucFN5c0NvbW1hbmRTaXplTW92ZSggaHduZCwgd1BhcmFtICk7CglicmVhazsKCiAgICBjYXNlIFNDX01JTklNSVpFOgogICAgICAgIGlmIChod25kID09IEdldEZvcmVncm91bmRXaW5kb3coKSkKICAgICAgICAgICAgU2hvd093bmVkUG9wdXBzKGh3bmQsRkFMU0UpOwoJU2hvd1dpbmRvdyggaHduZCwgU1dfTUlOSU1JWkUgKTsKCWJyZWFrOwoKICAgIGNhc2UgU0NfTUFYSU1JWkU6CiAgICAgICAgaWYgKElzSWNvbmljKGh3bmQpICYmIGh3bmQgPT0gR2V0Rm9yZWdyb3VuZFdpbmRvdygpKQogICAgICAgICAgICBTaG93T3duZWRQb3B1cHMoaHduZCxUUlVFKTsKCVNob3dXaW5kb3coIGh3bmQsIFNXX01BWElNSVpFICk7CglicmVhazsKCiAgICBjYXNlIFNDX1JFU1RPUkU6CiAgICAgICAgaWYgKElzSWNvbmljKGh3bmQpICYmIGh3bmQgPT0gR2V0Rm9yZWdyb3VuZFdpbmRvdygpKQogICAgICAgICAgICBTaG93T3duZWRQb3B1cHMoaHduZCxUUlVFKTsKCVNob3dXaW5kb3coIGh3bmQsIFNXX1JFU1RPUkUgKTsKCWJyZWFrOwoKICAgIGNhc2UgU0NfQ0xPU0U6CglyZXR1cm4gU2VuZE1lc3NhZ2VBKCBod25kLCBXTV9DTE9TRSwgMCwgMCApOwoKICAgIGNhc2UgU0NfVlNDUk9MTDoKICAgIGNhc2UgU0NfSFNDUk9MTDoKICAgICAgICB7CiAgICAgICAgICAgIFBPSU5UIHB0OwogICAgICAgICAgICBwdC54ID0gKHNob3J0KUxPV09SRChsUGFyYW0pOwogICAgICAgICAgICBwdC55ID0gKHNob3J0KUhJV09SRChsUGFyYW0pOwogICAgICAgICAgICBOQ19UcmFja1Njcm9sbEJhciggaHduZCwgd1BhcmFtLCBwdCApOwogICAgICAgIH0KCWJyZWFrOwoKICAgIGNhc2UgU0NfTU9VU0VNRU5VOgogICAgICAgIHsKICAgICAgICAgICAgUE9JTlQgcHQ7CiAgICAgICAgICAgIHB0LnggPSAoc2hvcnQpTE9XT1JEKGxQYXJhbSk7CiAgICAgICAgICAgIHB0LnkgPSAoc2hvcnQpSElXT1JEKGxQYXJhbSk7CiAgICAgICAgICAgIE1FTlVfVHJhY2tNb3VzZU1lbnVCYXIoIGh3bmQsIHdQYXJhbSAmIDB4MDAwRiwgcHQgKTsKICAgICAgICB9CglicmVhazsKCiAgICBjYXNlIFNDX0tFWU1FTlU6CiAgICAgICAgTUVOVV9UcmFja0tiZE1lbnVCYXIoIGh3bmQsIHdQYXJhbSwgKFdDSEFSKWxQYXJhbSApOwoJYnJlYWs7CgogICAgY2FzZSBTQ19UQVNLTElTVDoKCVdpbkV4ZWMoICJ0YXNrbWFuLmV4ZSIsIFNXX1NIT1dOT1JNQUwgKTsKCWJyZWFrOwoKICAgIGNhc2UgU0NfU0NSRUVOU0FWRToKCWlmICh3UGFyYW0gPT0gU0NfQUJPVVRXSU5FKQogICAgICAgIHsKICAgICAgICAgICAgSE1PRFVMRSBobW9kdWxlID0gTG9hZExpYnJhcnlBKCAic2hlbGwzMi5kbGwiICk7CiAgICAgICAgICAgIGlmIChobW9kdWxlKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBGQVJQUk9DIGFib3V0cHJvYyA9IEdldFByb2NBZGRyZXNzKCBobW9kdWxlLCAiU2hlbGxBYm91dEEiICk7CiAgICAgICAgICAgICAgICBpZiAoYWJvdXRwcm9jKSBhYm91dHByb2MoIGh3bmQsIFBBQ0tBR0VfTkFNRSwgUEFDS0FHRV9TVFJJTkcsIDAgKTsKICAgICAgICAgICAgICAgIEZyZWVMaWJyYXJ5KCBobW9kdWxlICk7CiAgICAgICAgICAgIH0KICAgICAgICB9CgllbHNlCgkgIGlmICh3UGFyYW0gPT0gU0NfUFVUTUFSSykKICAgICAgICAgICAgRFBSSU5URigiRGVidWcgbWFyayByZXF1ZXN0ZWQgYnkgdXNlclxuIik7CglicmVhazsKCiAgICBjYXNlIFNDX0hPVEtFWToKICAgIGNhc2UgU0NfQVJSQU5HRToKICAgIGNhc2UgU0NfTkVYVFdJTkRPVzoKICAgIGNhc2UgU0NfUFJFVldJTkRPVzoKIAlGSVhNRSgidW5pbXBsZW1lbnRlZCFcbiIpOwogICAgICAgIGJyZWFrOwogICAgfQogICAgcmV0dXJuIDA7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiogIE5DX0RyYXdHcmF5QnV0dG9uCioKKiBTdHViIGZvciB0aGUgZ3JheWVkIGJ1dHRvbiBvZiB0aGUgY2FwdGlvbgoqCioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCgpCT09MIE5DX0RyYXdHcmF5QnV0dG9uKEhEQyBoZGMsIGludCB4LCBpbnQgeSkKewogICAgSEJJVE1BUCBoTWFza0JtcDsKICAgIEhEQyBoZGNNYXNrOwogICAgSEJSVVNIIGhPbGRCcnVzaDsKCiAgICBoTWFza0JtcCA9IENyZWF0ZUJpdG1hcCAoMTIsIDEwLCAxLCAxLCBscEdyYXlNYXNrKTsKCiAgICBpZihoTWFza0JtcCA9PSAwKQoJcmV0dXJuIEZBTFNFOwoKICAgIGhkY01hc2sgPSBDcmVhdGVDb21wYXRpYmxlREMgKDApOwogICAgU2VsZWN0T2JqZWN0IChoZGNNYXNrLCBoTWFza0JtcCk7CgogICAgLyogRHJhdyB0aGUgZ3JheWVkIGJpdG1hcCB1c2luZyB0aGUgbWFzayAqLwogICAgaE9sZEJydXNoID0gU2VsZWN0T2JqZWN0IChoZGMsIChIR0RJT0JKKVJHQigxMjgsIDEyOCwgMTI4KSk7CiAgICBCaXRCbHQgKGhkYywgeCwgeSwgMTIsIDEwLAoJICAgIGhkY01hc2ssIDAsIDAsIDB4QjgwNzRBKTsKCiAgICAvKiBDbGVhbiB1cCAqLwogICAgU2VsZWN0T2JqZWN0IChoZGMsIGhPbGRCcnVzaCk7CiAgICBEZWxldGVPYmplY3QoaE1hc2tCbXApOwogICAgRGVsZXRlREMgKGhkY01hc2spOwoKICAgIHJldHVybiBUUlVFOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCUdldFRpdGxlQmFySW5mbyAoVVNFUjMyLkApCiAqIFRPRE86IEhhbmRsZSBTVEFURV9TWVNURU1fUFJFU1NFRAogKi8KQk9PTCBXSU5BUEkgR2V0VGl0bGVCYXJJbmZvKEhXTkQgaHduZCwgUFRJVExFQkFSSU5GTyB0YmkpIHsKICAgIERXT1JEIGR3U3R5bGU7CiAgICBEV09SRCBkd0V4U3R5bGU7CiAgICBSRUNUIHduZFJlY3Q7CgogICAgVFJBQ0UoIiglcCAlcClcbiIsIGh3bmQsIHRiaSk7CgogICAgaWYodGJpLT5jYlNpemUgIT0gc2l6ZW9mKFRJVExFQkFSSU5GTykpIHsKICAgICAgICBUUkFDRSgiSW52YWxpZCBUSVRMRUJBUklORk8gc2l6ZTogJWxkXG4iLCB0YmktPmNiU2l6ZSk7CiAgICAgICAgU2V0TGFzdEVycm9yKEVSUk9SX0lOVkFMSURfUEFSQU1FVEVSKTsKICAgICAgICByZXR1cm4gRkFMU0U7CiAgICB9CiAgICBkd1N0eWxlID0gR2V0V2luZG93TG9uZ1coaHduZCwgR1dMX1NUWUxFKTsKICAgIGR3RXhTdHlsZSA9IEdldFdpbmRvd0xvbmdXKGh3bmQsIEdXTF9FWFNUWUxFKTsKICAgIE5DX0dldEluc2lkZVJlY3QoaHduZCwgJnRiaS0+cmNUaXRsZUJhcik7CgogICAgR2V0V2luZG93UmVjdChod25kLCAmd25kUmVjdCk7CgogICAgdGJpLT5yY1RpdGxlQmFyLnRvcCArPSB3bmRSZWN0LnRvcDsKICAgIHRiaS0+cmNUaXRsZUJhci5sZWZ0ICs9IHduZFJlY3QubGVmdDsKICAgIHRiaS0+cmNUaXRsZUJhci5yaWdodCArPSB3bmRSZWN0LmxlZnQ7CgogICAgdGJpLT5yY1RpdGxlQmFyLmJvdHRvbSA9IHRiaS0+cmNUaXRsZUJhci50b3A7CiAgICBpZihkd0V4U3R5bGUgJiBXU19FWF9UT09MV0lORE9XKQogICAgICAgIHRiaS0+cmNUaXRsZUJhci5ib3R0b20gKz0gR2V0U3lzdGVtTWV0cmljcyhTTV9DWVNNQ0FQVElPTik7CiAgICBlbHNlIHsKICAgICAgICB0YmktPnJjVGl0bGVCYXIuYm90dG9tICs9IEdldFN5c3RlbU1ldHJpY3MoU01fQ1lDQVBUSU9OKTsKICAgICAgICB0YmktPnJjVGl0bGVCYXIubGVmdCArPSBHZXRTeXN0ZW1NZXRyaWNzKFNNX0NYU0laRSk7CiAgICB9CgogICAgWmVyb01lbW9yeSgmdGJpLT5yZ3N0YXRlLCBzaXplb2YodGJpLT5yZ3N0YXRlKSk7CiAgICAvKiBEb2VzIHRoZSB0aXRsZSBiYXIgYWx3YXlzIGhhdmUgU1RBVEVfU1lTVEVNX0ZPQ1VTQUJMRT8KICAgICAqIFVuZGVyIFhQIGl0IHNlZW1zIHRvCiAgICAgKi8KICAgIHRiaS0+cmdzdGF0ZVswXSA9IFNUQVRFX1NZU1RFTV9GT0NVU0FCTEU7CiAgICBpZihkd1N0eWxlICYgV1NfQ0FQVElPTikgewogICAgICAgIHRiaS0+cmdzdGF0ZVsxXSA9IFNUQVRFX1NZU1RFTV9JTlZJU0lCTEU7CiAgICAgICAgaWYoZHdTdHlsZSAmIFdTX1NZU01FTlUpIHsKICAgICAgICAgICAgaWYoIShkd1N0eWxlICYgKFdTX01JTklNSVpFQk9YfFdTX01BWElNSVpFQk9YKSkpIHsKICAgICAgICAgICAgICAgIHRiaS0+cmdzdGF0ZVsyXSA9IFNUQVRFX1NZU1RFTV9JTlZJU0lCTEU7CiAgICAgICAgICAgICAgICB0YmktPnJnc3RhdGVbM10gPSBTVEFURV9TWVNURU1fSU5WSVNJQkxFOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGVsc2UgewogICAgICAgICAgICAgICAgaWYoIShkd1N0eWxlICYgV1NfTUlOSU1JWkVCT1gpKQogICAgICAgICAgICAgICAgICAgIHRiaS0+cmdzdGF0ZVsyXSA9IFNUQVRFX1NZU1RFTV9VTkFWQUlMQUJMRTsKICAgICAgICAgICAgICAgIGlmKCEoZHdTdHlsZSAmIFdTX01BWElNSVpFQk9YKSkKICAgICAgICAgICAgICAgICAgICB0YmktPnJnc3RhdGVbM10gPSBTVEFURV9TWVNURU1fVU5BVkFJTEFCTEU7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYoIShkd0V4U3R5bGUgJiBXU19FWF9DT05URVhUSEVMUCkpCiAgICAgICAgICAgICAgICB0YmktPnJnc3RhdGVbNF0gPSBTVEFURV9TWVNURU1fSU5WSVNJQkxFOwogICAgICAgICAgICBpZihHZXRDbGFzc0xvbmdXKGh3bmQsIEdDTF9TVFlMRSkgJiBDU19OT0NMT1NFKQogICAgICAgICAgICAgICAgdGJpLT5yZ3N0YXRlWzVdID0gU1RBVEVfU1lTVEVNX1VOQVZBSUxBQkxFOwogICAgICAgIH0KICAgICAgICBlbHNlIHsKICAgICAgICAgICAgdGJpLT5yZ3N0YXRlWzJdID0gU1RBVEVfU1lTVEVNX0lOVklTSUJMRTsKICAgICAgICAgICAgdGJpLT5yZ3N0YXRlWzNdID0gU1RBVEVfU1lTVEVNX0lOVklTSUJMRTsKICAgICAgICAgICAgdGJpLT5yZ3N0YXRlWzRdID0gU1RBVEVfU1lTVEVNX0lOVklTSUJMRTsKICAgICAgICAgICAgdGJpLT5yZ3N0YXRlWzVdID0gU1RBVEVfU1lTVEVNX0lOVklTSUJMRTsKICAgICAgICB9CiAgICB9CiAgICBlbHNlCiAgICAgICAgdGJpLT5yZ3N0YXRlWzBdIHw9IFNUQVRFX1NZU1RFTV9JTlZJU0lCTEU7CiAgICByZXR1cm4gVFJVRTsKfQo=