LyogRmlsZTogYnV0dG9uLmMgLS0gQnV0dG9uIHR5cGUgd2lkZ2V0cwogKgogKiBDb3B5cmlnaHQgKEMpIDE5OTMgSm9oYW5uZXMgUnVzY2hlaW5za2kKICogQ29weXJpZ2h0IChDKSAxOTkzIERhdmlkIE1ldGNhbGZlCiAqIENvcHlyaWdodCAoQykgMTk5NCBBbGV4YW5kcmUgSnVsbGlhcmQKICovCgojaW5jbHVkZSA8c3RyaW5nLmg+CiNpbmNsdWRlICJ3aW4uaCIKI2luY2x1ZGUgImJ1dHRvbi5oIgojaW5jbHVkZSAid2luZS93aW51c2VyMTYuaCIKI2luY2x1ZGUgInR3ZWFrLmgiCgpzdGF0aWMgdm9pZCBQYWludEdyYXlPbkdyYXkoIEhEQyBoREMsSEZPTlQgaEZvbnQsUkVDVCAqcmMsCgkJCSAgICAgY2hhciAqdGV4dCwgVUlOVCBmb3JtYXQgKTsKCnN0YXRpYyB2b2lkIFBCX1BhaW50KCBXTkQgKnduZFB0ciwgSERDIGhEQywgV09SRCBhY3Rpb24gKTsKc3RhdGljIHZvaWQgQ0JfUGFpbnQoIFdORCAqd25kUHRyLCBIREMgaERDLCBXT1JEIGFjdGlvbiApOwpzdGF0aWMgdm9pZCBHQl9QYWludCggV05EICp3bmRQdHIsIEhEQyBoREMsIFdPUkQgYWN0aW9uICk7CnN0YXRpYyB2b2lkIFVCX1BhaW50KCBXTkQgKnduZFB0ciwgSERDIGhEQywgV09SRCBhY3Rpb24gKTsKc3RhdGljIHZvaWQgT0JfUGFpbnQoIFdORCAqd25kUHRyLCBIREMgaERDLCBXT1JEIGFjdGlvbiApOwpzdGF0aWMgdm9pZCBCVVRUT05fQ2hlY2tBdXRvUmFkaW9CdXR0b24oIFdORCAqd25kUHRyICk7CnN0YXRpYyB2b2lkIEJVVFRPTl9EcmF3UHVzaEJ1dHRvbiggV05EICp3bmRQdHIsIEhEQyBoREMsIFdPUkQgYWN0aW9uLCBCT09MIHB1c2hlZFN0YXRlKTsKCiNkZWZpbmUgTUFYX0JUTl9UWVBFICAxMgoKc3RhdGljIGNvbnN0IFdPUkQgbWF4Q2hlY2tTdGF0ZVtNQVhfQlROX1RZUEVdID0KewogICAgQlVUVE9OX1VOQ0hFQ0tFRCwgICAvKiBCU19QVVNIQlVUVE9OICovCiAgICBCVVRUT05fVU5DSEVDS0VELCAgIC8qIEJTX0RFRlBVU0hCVVRUT04gKi8KICAgIEJVVFRPTl9DSEVDS0VELCAgICAgLyogQlNfQ0hFQ0tCT1ggKi8KICAgIEJVVFRPTl9DSEVDS0VELCAgICAgLyogQlNfQVVUT0NIRUNLQk9YICovCiAgICBCVVRUT05fQ0hFQ0tFRCwgICAgIC8qIEJTX1JBRElPQlVUVE9OICovCiAgICBCVVRUT05fM1NUQVRFLCAgICAgIC8qIEJTXzNTVEFURSAqLwogICAgQlVUVE9OXzNTVEFURSwgICAgICAvKiBCU19BVVRPM1NUQVRFICovCiAgICBCVVRUT05fVU5DSEVDS0VELCAgIC8qIEJTX0dST1VQQk9YICovCiAgICBCVVRUT05fVU5DSEVDS0VELCAgIC8qIEJTX1VTRVJCVVRUT04gKi8KICAgIEJVVFRPTl9DSEVDS0VELCAgICAgLyogQlNfQVVUT1JBRElPQlVUVE9OICovCiAgICBCVVRUT05fVU5DSEVDS0VELCAgIC8qIE5vdCBkZWZpbmVkICovCiAgICBCVVRUT05fVU5DSEVDS0VEICAgIC8qIEJTX09XTkVSRFJBVyAqLwp9OwoKdHlwZWRlZiB2b2lkICgqcGZQYWludCkoIFdORCAqd25kUHRyLCBIREMgaGRjLCBXT1JEIGFjdGlvbiApOwoKc3RhdGljIGNvbnN0IHBmUGFpbnQgYnRuUGFpbnRGdW5jW01BWF9CVE5fVFlQRV0gPQp7CiAgICBQQl9QYWludCwgICAgLyogQlNfUFVTSEJVVFRPTiAqLwogICAgUEJfUGFpbnQsICAgIC8qIEJTX0RFRlBVU0hCVVRUT04gKi8KICAgIENCX1BhaW50LCAgICAvKiBCU19DSEVDS0JPWCAqLwogICAgQ0JfUGFpbnQsICAgIC8qIEJTX0FVVE9DSEVDS0JPWCAqLwogICAgQ0JfUGFpbnQsICAgIC8qIEJTX1JBRElPQlVUVE9OICovCiAgICBDQl9QYWludCwgICAgLyogQlNfM1NUQVRFICovCiAgICBDQl9QYWludCwgICAgLyogQlNfQVVUTzNTVEFURSAqLwogICAgR0JfUGFpbnQsICAgIC8qIEJTX0dST1VQQk9YICovCiAgICBVQl9QYWludCwgICAgLyogQlNfVVNFUkJVVFRPTiAqLwogICAgQ0JfUGFpbnQsICAgIC8qIEJTX0FVVE9SQURJT0JVVFRPTiAqLwogICAgTlVMTCwgICAgICAgIC8qIE5vdCBkZWZpbmVkICovCiAgICBPQl9QYWludCAgICAgLyogQlNfT1dORVJEUkFXICovCn07CgojZGVmaW5lIFBBSU5UX0JVVFRPTih3bmRQdHIsc3R5bGUsYWN0aW9uKSBcCiAgICAgaWYgKGJ0blBhaW50RnVuY1tzdHlsZV0pIHsgXAogICAgICAgICBIREMgaGRjID0gR2V0REMoICh3bmRQdHIpLT5od25kU2VsZiApOyBcCiAgICAgICAgIChidG5QYWludEZ1bmNbc3R5bGVdKSh3bmRQdHIsaGRjLGFjdGlvbik7IFwKICAgICAgICAgUmVsZWFzZURDKCAod25kUHRyKS0+aHduZFNlbGYsIGhkYyApOyB9CgojZGVmaW5lIEJVVFRPTl9TRU5EX0NUTENPTE9SKHduZFB0cixoZGMpIFwKICAgIFNlbmRNZXNzYWdlQSggR2V0UGFyZW50KCh3bmRQdHIpLT5od25kU2VsZiksIFdNX0NUTENPTE9SQlROLCBcCiAgICAgICAgICAgICAgICAgICAgKGhkYyksICh3bmRQdHIpLT5od25kU2VsZiApCgpzdGF0aWMgSEJJVE1BUCBoYml0bWFwQ2hlY2tCb3hlcyA9IDA7CnN0YXRpYyBXT1JEIGNoZWNrQm94V2lkdGggPSAwLCBjaGVja0JveEhlaWdodCA9IDA7CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgICAgICBCdXR0b25XbmRQcm9jX2xvY2tlZAogKiAKICogQ2FsbGVkIHdpdGggd2luZG93IGxvY2sgaGVsZC4KICovCnN0YXRpYyBpbmxpbmUgTFJFU1VMVCBXSU5BUEkgQnV0dG9uV25kUHJvY19sb2NrZWQoV05EKiB3bmRQdHIsIFVJTlQgdU1zZywKCQkJCQkgICBXUEFSQU0gd1BhcmFtLCBMUEFSQU0gbFBhcmFtICkKewogICAgUkVDVCByZWN0OwogICAgSFdORAloV25kID0gd25kUHRyLT5od25kU2VsZjsKICAgIFBPSU5UIHB0OwogICAgQlVUVE9OSU5GTyAqaW5mb1B0ciA9IChCVVRUT05JTkZPICopd25kUHRyLT53RXh0cmE7CiAgICBMT05HIHN0eWxlID0gd25kUHRyLT5kd1N0eWxlICYgMHgwZjsKICAgIEhBTkRMRSBvbGRIYml0bWFwOwoKICAgIHB0LnggPSBMT1dPUkQobFBhcmFtKTsKICAgIHB0LnkgPSBISVdPUkQobFBhcmFtKTsKCiAgICBzd2l0Y2ggKHVNc2cpCiAgICB7CiAgICBjYXNlIFdNX0dFVERMR0NPREU6CiAgICAgICAgc3dpdGNoKHN0eWxlKQogICAgICAgIHsKICAgICAgICBjYXNlIEJTX1BVU0hCVVRUT046ICAgICAgcmV0dXJuIERMR0NfQlVUVE9OIHwgRExHQ19VTkRFRlBVU0hCVVRUT047CiAgICAgICAgY2FzZSBCU19ERUZQVVNIQlVUVE9OOiAgIHJldHVybiBETEdDX0JVVFRPTiB8IERMR0NfREVGUFVTSEJVVFRPTjsKICAgICAgICBjYXNlIEJTX1JBRElPQlVUVE9OOgogICAgICAgIGNhc2UgQlNfQVVUT1JBRElPQlVUVE9OOiByZXR1cm4gRExHQ19CVVRUT04gfCBETEdDX1JBRElPQlVUVE9OOwogICAgICAgIGRlZmF1bHQ6ICAgICAgICAgICAgICAgICByZXR1cm4gRExHQ19CVVRUT047CiAgICAgICAgfQoKICAgIGNhc2UgV01fRU5BQkxFOgogICAgICAgIFBBSU5UX0JVVFRPTiggd25kUHRyLCBzdHlsZSwgT0RBX0RSQVdFTlRJUkUgKTsKICAgICAgICBicmVhazsKCiAgICBjYXNlIFdNX0NSRUFURToKICAgICAgICBpZiAoIWhiaXRtYXBDaGVja0JveGVzKQogICAgICAgIHsKICAgICAgICAgICAgQklUTUFQIGJtcDsKICAgICAgICAgICAgaGJpdG1hcENoZWNrQm94ZXMgPSBMb2FkQml0bWFwQSgwLCBNQUtFSU5UUkVTT1VSQ0VBKE9CTV9DSEVDS0JPWEVTKSk7CiAgICAgICAgICAgIEdldE9iamVjdEEoIGhiaXRtYXBDaGVja0JveGVzLCBzaXplb2YoYm1wKSwgJmJtcCApOwogICAgICAgICAgICBjaGVja0JveFdpZHRoICA9IGJtcC5ibVdpZHRoIC8gNDsKICAgICAgICAgICAgY2hlY2tCb3hIZWlnaHQgPSBibXAuYm1IZWlnaHQgLyAzOwogICAgICAgIH0KICAgICAgICBpZiAoc3R5bGUgPCAwTCB8fCBzdHlsZSA+PSBNQVhfQlROX1RZUEUpCiAgICAgICAgICAgIHJldHVybiAtMTsgLyogYWJvcnQgKi8KICAgICAgICBpbmZvUHRyLT5zdGF0ZSA9IEJVVFRPTl9VTkNIRUNLRUQ7CiAgICAgICAgaW5mb1B0ci0+aEZvbnQgPSAwOwogICAgICAgIGluZm9QdHItPmhJbWFnZSA9IE5VTEw7CiAgICAgICAgcmV0dXJuIDA7CgogICAgY2FzZSBXTV9FUkFTRUJLR05EOgogICAgICAgIHJldHVybiAxOwoKICAgIGNhc2UgV01fUEFJTlQ6CiAgICAgICAgaWYgKGJ0blBhaW50RnVuY1tzdHlsZV0pCiAgICAgICAgewogICAgICAgICAgICBQQUlOVFNUUlVDVCBwczsKICAgICAgICAgICAgSERDIGhkYyA9IHdQYXJhbSA/IChIREMpd1BhcmFtIDogQmVnaW5QYWludCggaFduZCwgJnBzICk7CgkgICAgU2V0QmtNb2RlKCBoZGMsIE9QQVFVRSApOwogICAgICAgICAgICAoYnRuUGFpbnRGdW5jW3N0eWxlXSkoIHduZFB0ciwgaGRjLCBPREFfRFJBV0VOVElSRSApOwogICAgICAgICAgICBpZiggIXdQYXJhbSApIEVuZFBhaW50KCBoV25kLCAmcHMgKTsKICAgICAgICB9CiAgICAgICAgYnJlYWs7CgogICAgY2FzZSBXTV9MQlVUVE9OREJMQ0xLOgoJaWYod25kUHRyLT5kd1N0eWxlICYgQlNfTk9USUZZIHx8IAoJCXN0eWxlPT1CU19SQURJT0JVVFRPTiB8fAoJCXN0eWxlPT1CU19VU0VSQlVUVE9OIHx8CgkJc3R5bGU9PUJTX09XTkVSRFJBVyl7CgkgICAgU2VuZE1lc3NhZ2VBKCBHZXRQYXJlbnQoaFduZCksIFdNX0NPTU1BTkQsCgkJICAgIE1BS0VXUEFSQU0oIHduZFB0ci0+d0lEbWVudSwgQk5fRE9VQkxFQ0xJQ0tFRCApLCBoV25kKTsKCSAgICBicmVhazsKCX0KCS8qIGZhbGwgdGhyb3VnaCAqLwogICAgY2FzZSBXTV9MQlVUVE9ORE9XTjoKICAgICAgICBTZXRDYXB0dXJlKCBoV25kICk7CiAgICAgICAgU2V0Rm9jdXMoIGhXbmQgKTsKICAgICAgICBTZW5kTWVzc2FnZUEoIGhXbmQsIEJNX1NFVFNUQVRFLCBUUlVFLCAwICk7CiAgICAgICAgYnJlYWs7CgogICAgY2FzZSBXTV9MQlVUVE9OVVA6CgkvKiBGSVhNRTogcmVhbCB3aW5kb3dzIHVzZXMgZXh0cmEgZmxhZ3MgaW4gdGhlIHN0YXR1cyBmb3IgdGhpcyAqLwogICAgICAgIGlmIChHZXRDYXB0dXJlKCkgIT0gaFduZCkgYnJlYWs7CiAgICAgICAgUmVsZWFzZUNhcHR1cmUoKTsKICAgICAgICBpZiAoIShpbmZvUHRyLT5zdGF0ZSAmIEJVVFRPTl9ISUdITElHSFRFRCkpIGJyZWFrOwogICAgICAgIFNlbmRNZXNzYWdlQSggaFduZCwgQk1fU0VUU1RBVEUsIEZBTFNFLCAwICk7CiAgICAgICAgR2V0Q2xpZW50UmVjdCggaFduZCwgJnJlY3QgKTsKICAgICAgICBpZiAoUHRJblJlY3QoICZyZWN0LCBwdCApKQogICAgICAgIHsKICAgICAgICAgICAgc3dpdGNoKHN0eWxlKQogICAgICAgICAgICB7CiAgICAgICAgICAgIGNhc2UgQlNfQVVUT0NIRUNLQk9YOgogICAgICAgICAgICAgICAgU2VuZE1lc3NhZ2VBKCBoV25kLCBCTV9TRVRDSEVDSywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAhKGluZm9QdHItPnN0YXRlICYgQlVUVE9OX0NIRUNLRUQpLCAwICk7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgY2FzZSBCU19BVVRPUkFESU9CVVRUT046CiAgICAgICAgICAgICAgICBTZW5kTWVzc2FnZUEoIGhXbmQsIEJNX1NFVENIRUNLLCBUUlVFLCAwICk7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgY2FzZSBCU19BVVRPM1NUQVRFOgogICAgICAgICAgICAgICAgU2VuZE1lc3NhZ2VBKCBoV25kLCBCTV9TRVRDSEVDSywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoaW5mb1B0ci0+c3RhdGUgJiBCVVRUT05fM1NUQVRFKSA/IDAgOgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICgoaW5mb1B0ci0+c3RhdGUgJiAzKSArIDEpLCAwICk7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgfQogICAgICAgICAgICBTZW5kTWVzc2FnZUEoIEdldFBhcmVudChoV25kKSwgV01fQ09NTUFORCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIE1BS0VXUEFSQU0oIHduZFB0ci0+d0lEbWVudSwgQk5fQ0xJQ0tFRCApLCBoV25kKTsKICAgICAgICB9CiAgICAgICAgYnJlYWs7CgogICAgY2FzZSBXTV9NT1VTRU1PVkU6CiAgICAgICAgaWYgKEdldENhcHR1cmUoKSA9PSBoV25kKQogICAgICAgIHsKICAgICAgICAgICAgR2V0Q2xpZW50UmVjdCggaFduZCwgJnJlY3QgKTsKICAgICAgICAgICAgU2VuZE1lc3NhZ2VBKCBoV25kLCBCTV9TRVRTVEFURSwgUHRJblJlY3QoJnJlY3QsIHB0KSwgMCApOwogICAgICAgIH0KICAgICAgICBicmVhazsKCiAgICBjYXNlIFdNX05DSElUVEVTVDoKICAgICAgICBpZihzdHlsZSA9PSBCU19HUk9VUEJPWCkgcmV0dXJuIEhUVFJBTlNQQVJFTlQ7CiAgICAgICAgcmV0dXJuIERlZldpbmRvd1Byb2NBKCBoV25kLCB1TXNnLCB3UGFyYW0sIGxQYXJhbSApOwoKICAgIGNhc2UgV01fU0VUVEVYVDoKICAgICAgICBERUZXTkRfU2V0VGV4dCggd25kUHRyLCAoTFBDU1RSKWxQYXJhbSApOwoJaWYoIHduZFB0ci0+ZHdTdHlsZSAmIFdTX1ZJU0lCTEUgKQogICAgICAgICAgICBQQUlOVF9CVVRUT04oIHduZFB0ciwgc3R5bGUsIE9EQV9EUkFXRU5USVJFICk7CiAgICAgICAgcmV0dXJuIDA7CgogICAgY2FzZSBXTV9TRVRGT05UOgogICAgICAgIGluZm9QdHItPmhGb250ID0gKEhGT05UMTYpd1BhcmFtOwogICAgICAgIGlmIChsUGFyYW0gJiYgKHduZFB0ci0+ZHdTdHlsZSAmIFdTX1ZJU0lCTEUpKSAKCSAgICBQQUlOVF9CVVRUT04oIHduZFB0ciwgc3R5bGUsIE9EQV9EUkFXRU5USVJFICk7CiAgICAgICAgYnJlYWs7CgogICAgY2FzZSBXTV9HRVRGT05UOgogICAgICAgIHJldHVybiBpbmZvUHRyLT5oRm9udDsKCiAgICBjYXNlIFdNX1NFVEZPQ1VTOgogICAgICAgIGlmICgoc3R5bGUgPT0gQlNfQVVUT1JBRElPQlVUVE9OKSAmJiAoR2V0Q2FwdHVyZSgpICE9IGhXbmQpICYmCiAgICAgICAgICAgICEoU2VuZE1lc3NhZ2VBKGhXbmQsIEJNX0dFVENIRUNLLCAwLCAwKSAmIEJTVF9DSEVDS0VEKSkKCXsKICAgICAgICAgICAgLyogVGhlIG5vdGlmaWNhdGlvbiBpcyBzZW50IHdoZW4gdGhlIGJ1dHRvbiAoQlNfQVVUT1JBRElPQlVUVE9OKSAKICAgICAgICAgICAgICAgaXMgdW5ja2Vja2VkIGFuZCB0aGUgZm9jdXMgd2FzIG5vdCBnaXZlbiBieSBhIG1vdXNlIGNsaWNrLiAqLwogICAgICAgICAgICBTZW5kTWVzc2FnZUEoIGhXbmQsIEJNX1NFVENIRUNLLCBUUlVFLCAwICk7CiAgICAgICAgICAgIFNlbmRNZXNzYWdlQSggR2V0UGFyZW50KGhXbmQpLCBXTV9DT01NQU5ELAogICAgICAgICAgICAgICAgICAgICAgICAgIE1BS0VXUEFSQU0oIHduZFB0ci0+d0lEbWVudSwgQk5fQ0xJQ0tFRCApLCBoV25kKTsKICAgICAgICB9CiAgICAgICAgaW5mb1B0ci0+c3RhdGUgfD0gQlVUVE9OX0hBU0ZPQ1VTOwogICAgICAgIFBBSU5UX0JVVFRPTiggd25kUHRyLCBzdHlsZSwgT0RBX0ZPQ1VTICk7CiAgICAgICAgYnJlYWs7CgogICAgY2FzZSBXTV9LSUxMRk9DVVM6CiAgICAgICAgaW5mb1B0ci0+c3RhdGUgJj0gfkJVVFRPTl9IQVNGT0NVUzsKCVBBSU5UX0JVVFRPTiggd25kUHRyLCBzdHlsZSwgT0RBX0ZPQ1VTICk7CglJbnZhbGlkYXRlUmVjdCggaFduZCwgTlVMTCwgVFJVRSApOwogICAgICAgIGJyZWFrOwoKICAgIGNhc2UgV01fU1lTQ09MT1JDSEFOR0U6CiAgICAgICAgSW52YWxpZGF0ZVJlY3QoIGhXbmQsIE5VTEwsIEZBTFNFICk7CiAgICAgICAgYnJlYWs7CgogICAgY2FzZSBCTV9TRVRTVFlMRTE2OgogICAgY2FzZSBCTV9TRVRTVFlMRToKICAgICAgICBpZiAoKHdQYXJhbSAmIDB4MGYpID49IE1BWF9CVE5fVFlQRSkgYnJlYWs7CiAgICAgICAgd25kUHRyLT5kd1N0eWxlID0gKHduZFB0ci0+ZHdTdHlsZSAmIDB4ZmZmZmZmZjApIAogICAgICAgICAgICAgICAgICAgICAgICAgICB8ICh3UGFyYW0gJiAweDAwMDAwMDBmKTsKICAgICAgICBzdHlsZSA9IHduZFB0ci0+ZHdTdHlsZSAmIDB4MDAwMDAwMGY7CiAgICAgICAgUEFJTlRfQlVUVE9OKCB3bmRQdHIsIHN0eWxlLCBPREFfRFJBV0VOVElSRSApOwogICAgICAgIGJyZWFrOwoKICAgIGNhc2UgQk1fU0VUSU1BR0U6CglvbGRIYml0bWFwID0gaW5mb1B0ci0+aEltYWdlOwoJaWYgKCh3bmRQdHItPmR3U3R5bGUgJiBCU19CSVRNQVApIHx8ICh3bmRQdHItPmR3U3R5bGUgJiBCU19JQ09OKSkKCSAgICBpbmZvUHRyLT5oSW1hZ2UgPSAoSEFORExFKSBsUGFyYW07CglyZXR1cm4gb2xkSGJpdG1hcDsKCiAgICBjYXNlIEJNX0dFVElNQUdFOgogICAgICAgIGlmICh3UGFyYW0gPT0gSU1BR0VfQklUTUFQKQoJICAgIHJldHVybiAoSEJJVE1BUClpbmZvUHRyLT5oSW1hZ2U7CgllbHNlIGlmICh3UGFyYW0gPT0gSU1BR0VfSUNPTikKCSAgICByZXR1cm4gKEhJQ09OKWluZm9QdHItPmhJbWFnZTsKCWVsc2UKCSAgICByZXR1cm4gTlVMTDsKCiAgICBjYXNlIEJNX0dFVENIRUNLMTY6CiAgICBjYXNlIEJNX0dFVENIRUNLOgogICAgICAgIHJldHVybiBpbmZvUHRyLT5zdGF0ZSAmIDM7CgogICAgY2FzZSBCTV9TRVRDSEVDSzE2OgogICAgY2FzZSBCTV9TRVRDSEVDSzoKICAgICAgICBpZiAod1BhcmFtID4gbWF4Q2hlY2tTdGF0ZVtzdHlsZV0pIHdQYXJhbSA9IG1heENoZWNrU3RhdGVbc3R5bGVdOwogICAgICAgIGlmICgoaW5mb1B0ci0+c3RhdGUgJiAzKSAhPSB3UGFyYW0pCiAgICAgICAgewoJICAgIGlmICgoc3R5bGUgPT0gQlNfUkFESU9CVVRUT04pIHx8IChzdHlsZSA9PSBCU19BVVRPUkFESU9CVVRUT04pKQoJICAgIHsKCQlpZiAod1BhcmFtKQoJCSAgICB3bmRQdHItPmR3U3R5bGUgfD0gV1NfVEFCU1RPUDsKCQllbHNlCgkJICAgIHduZFB0ci0+ZHdTdHlsZSAmPSB+V1NfVEFCU1RPUDsKCSAgICB9CiAgICAgICAgICAgIGluZm9QdHItPnN0YXRlID0gKGluZm9QdHItPnN0YXRlICYgfjMpIHwgd1BhcmFtOwogICAgICAgICAgICBQQUlOVF9CVVRUT04oIHduZFB0ciwgc3R5bGUsIE9EQV9TRUxFQ1QgKTsKICAgICAgICB9CiAgICAgICAgaWYgKChzdHlsZSA9PSBCU19BVVRPUkFESU9CVVRUT04pICYmICh3UGFyYW0gPT0gQlVUVE9OX0NIRUNLRUQpKQogICAgICAgICAgICBCVVRUT05fQ2hlY2tBdXRvUmFkaW9CdXR0b24oIHduZFB0ciApOwogICAgICAgIGJyZWFrOwoKICAgIGNhc2UgQk1fR0VUU1RBVEUxNjoKICAgIGNhc2UgQk1fR0VUU1RBVEU6CiAgICAgICAgcmV0dXJuIGluZm9QdHItPnN0YXRlOwoKICAgIGNhc2UgQk1fU0VUU1RBVEUxNjoKICAgIGNhc2UgQk1fU0VUU1RBVEU6CiAgICAgICAgaWYgKHdQYXJhbSkKICAgICAgICB7CiAgICAgICAgICAgIGlmIChpbmZvUHRyLT5zdGF0ZSAmIEJVVFRPTl9ISUdITElHSFRFRCkgYnJlYWs7CiAgICAgICAgICAgIGluZm9QdHItPnN0YXRlIHw9IEJVVFRPTl9ISUdITElHSFRFRDsKICAgICAgICB9CiAgICAgICAgZWxzZQogICAgICAgIHsKICAgICAgICAgICAgaWYgKCEoaW5mb1B0ci0+c3RhdGUgJiBCVVRUT05fSElHSExJR0hURUQpKSBicmVhazsKICAgICAgICAgICAgaW5mb1B0ci0+c3RhdGUgJj0gfkJVVFRPTl9ISUdITElHSFRFRDsKICAgICAgICB9CiAgICAgICAgUEFJTlRfQlVUVE9OKCB3bmRQdHIsIHN0eWxlLCBPREFfU0VMRUNUICk7CiAgICAgICAgYnJlYWs7CgogICAgZGVmYXVsdDoKICAgICAgICByZXR1cm4gRGVmV2luZG93UHJvY0EoaFduZCwgdU1zZywgd1BhcmFtLCBsUGFyYW0pOwogICAgfQogICAgcmV0dXJuIDA7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgICAgICAgQnV0dG9uV25kUHJvYwogKiBUaGUgYnV0dG9uIHdpbmRvdyBwcm9jZWR1cmUuIFRoaXMgaXMganVzdCBhIHdyYXBwZXIgd2hpY2ggbG9ja3MKICogdGhlIHBhc3NlZCBIV05EIGFuZCBjYWxscyB0aGUgcmVhbCB3aW5kb3cgcHJvY2VkdXJlICh3aXRoIGEgV05EKgogKiBwb2ludGVyIHBvaW50aW5nIHRvIHRoZSBsb2NrZWQgd2luZG93c3RydWN0dXJlKS4KICovCkxSRVNVTFQgV0lOQVBJIEJ1dHRvblduZFByb2MoIEhXTkQgaFduZCwgVUlOVCB1TXNnLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBXUEFSQU0gd1BhcmFtLCBMUEFSQU0gbFBhcmFtICkKewogICAgTFJFU1VMVCByZXM7CiAgICBXTkQgKnduZFB0ciA9IFdJTl9GaW5kV25kUHRyKGhXbmQpOwoKICAgIHJlcyA9IEJ1dHRvblduZFByb2NfbG9ja2VkKHduZFB0cix1TXNnLHdQYXJhbSxsUGFyYW0pOwoKICAgIFdJTl9SZWxlYXNlV25kUHRyKHduZFB0cik7CiAgICByZXR1cm4gcmVzOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgICBQdXNoIEJ1dHRvbiBGdW5jdGlvbnMKICovCnN0YXRpYyB2b2lkIFBCX1BhaW50KCBXTkQgKnduZFB0ciwgSERDIGhEQywgV09SRCBhY3Rpb24gKQp7CiAgICBCVVRUT05JTkZPICppbmZvUHRyICAgICAgPSAoQlVUVE9OSU5GTyAqKXduZFB0ci0+d0V4dHJhOwogICAgQk9PTCAgICAgICAgYkhpZ2hMaWdodGVkID0gKGluZm9QdHItPnN0YXRlICYgQlVUVE9OX0hJR0hMSUdIVEVEKTsKCiAgICAvKiAKICAgICAqIERlbGVnYXRlIHRoaXMgdG8gdGhlIG1vcmUgZ2VuZXJpYyBwdXNoYnV0dG9uIHBhaW50aW5nCiAgICAgKiBtZXRob2QuCiAgICAgKi8KICAgIEJVVFRPTl9EcmF3UHVzaEJ1dHRvbih3bmRQdHIsCgkJCSAgaERDLAoJCQkgIGFjdGlvbiwKCQkJICBiSGlnaExpZ2h0ZWQpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBUaGlzIG1ldGhvZCB3aWxsIGFjdHVhbGx5IGRvIHRoZSBkcmF3aW5nIG9mIHRoZSBwdXNoYnV0dG9uIAogKiBkZXBlbmRpbmcgb24gaXQncyBzdGF0ZSBhbmQgdGhlIHB1c2hlZFN0YXRlIHBhcmFtZXRlci4KICovCnN0YXRpYyB2b2lkIEJVVFRPTl9EcmF3UHVzaEJ1dHRvbigKICBXTkQqIHduZFB0ciwKICBIREMgIGhEQywgCiAgV09SRCBhY3Rpb24sIAogIEJPT0wgcHVzaGVkU3RhdGUgKQp7CiAgICBSRUNUIHJjLCBmb2N1c19yZWN0OwogICAgSFBFTiBoT2xkUGVuOwogICAgSEJSVVNIIGhPbGRCcnVzaDsKICAgIEJVVFRPTklORk8gKmluZm9QdHIgPSAoQlVUVE9OSU5GTyAqKXduZFB0ci0+d0V4dHJhOwogICAgaW50IHhCb3JkZXJPZmZzZXQsIHlCb3JkZXJPZmZzZXQ7CiAgICB4Qm9yZGVyT2Zmc2V0ID0geUJvcmRlck9mZnNldCA9IDA7CgogICAgR2V0Q2xpZW50UmVjdCggd25kUHRyLT5od25kU2VsZiwgJnJjICk7CgogICAgICAvKiBTZW5kIFdNX0NUTENPTE9SIHRvIGFsbG93IGNoYW5naW5nIHRoZSBmb250ICh0aGUgY29sb3JzIGFyZSBmaXhlZCkgKi8KICAgIGlmIChpbmZvUHRyLT5oRm9udCkgU2VsZWN0T2JqZWN0KCBoREMsIGluZm9QdHItPmhGb250ICk7CiAgICBCVVRUT05fU0VORF9DVExDT0xPUiggd25kUHRyLCBoREMgKTsKICAgIGhPbGRQZW4gPSAoSFBFTilTZWxlY3RPYmplY3QoaERDLCBHZXRTeXNDb2xvclBlbihDT0xPUl9XSU5ET1dGUkFNRSkpOwogICAgaE9sZEJydXNoID0oSEJSVVNIKVNlbGVjdE9iamVjdChoREMsR2V0U3lzQ29sb3JCcnVzaChDT0xPUl9CVE5GQUNFKSk7CiAgICBTZXRCa01vZGUoaERDLCBUUkFOU1BBUkVOVCk7CgogICAgaWYgKCBUV0VBS19XaW5lTG9vayA9PSBXSU4zMV9MT09LKQogICAgewogICAgICAgIFJlY3RhbmdsZShoREMsIHJjLmxlZnQsIHJjLnRvcCwgcmMucmlnaHQsIHJjLmJvdHRvbSk7CgogICAgICAgIFNldFBpeGVsKCBoREMsIHJjLmxlZnQsIHJjLnRvcCwgR2V0U3lzQ29sb3IoQ09MT1JfV0lORE9XKSApOwogICAgICAgIFNldFBpeGVsKCBoREMsIHJjLmxlZnQsIHJjLmJvdHRvbS0xLCBHZXRTeXNDb2xvcihDT0xPUl9XSU5ET1cpICk7CiAgICAgICAgU2V0UGl4ZWwoIGhEQywgcmMucmlnaHQtMSwgcmMudG9wLCBHZXRTeXNDb2xvcihDT0xPUl9XSU5ET1cpICk7CiAgICAgICAgU2V0UGl4ZWwoIGhEQywgcmMucmlnaHQtMSwgcmMuYm90dG9tLTEsIEdldFN5c0NvbG9yKENPTE9SX1dJTkRPVykpOwoJSW5mbGF0ZVJlY3QoICZyYywgLTEsIC0xICk7CiAgICB9CiAgICAKICAgIGlmICgod25kUHRyLT5kd1N0eWxlICYgMHgwMDBmKSA9PSBCU19ERUZQVVNIQlVUVE9OKQogICAgewogICAgICAgIFJlY3RhbmdsZShoREMsIHJjLmxlZnQsIHJjLnRvcCwgcmMucmlnaHQsIHJjLmJvdHRvbSk7CglJbmZsYXRlUmVjdCggJnJjLCAtMSwgLTEgKTsKICAgIH0KCiAgICBpZiAoVFdFQUtfV2luZUxvb2sgPT0gV0lOMzFfTE9PSykKICAgIHsKICAgICAgICBpZiAocHVzaGVkU3RhdGUpCgl7CgkgICAgLyogZHJhdyBidXR0b24gc2hhZG93OiAqLwoJICAgIFNlbGVjdE9iamVjdChoREMsIEdldFN5c0NvbG9yQnJ1c2goQ09MT1JfQlROU0hBRE9XKSk7CgkgICAgUGF0Qmx0KGhEQywgcmMubGVmdCwgcmMudG9wLCAxLCByYy5ib3R0b20tcmMudG9wLCBQQVRDT1BZICk7CgkgICAgUGF0Qmx0KGhEQywgcmMubGVmdCwgcmMudG9wLCByYy5yaWdodC1yYy5sZWZ0LCAxLCBQQVRDT1BZICk7CgkgICAgcmMubGVmdCArPSAyOyAgLyogVG8gcG9zaXRpb24gdGhlIHRleHQgZG93biBhbmQgcmlnaHQgKi8KCSAgICByYy50b3AgICs9IDI7Cgl9IGVsc2UgewoJICAgcmMucmlnaHQrKywgcmMuYm90dG9tKys7CgkgICBEcmF3RWRnZSggaERDLCAmcmMsIEVER0VfUkFJU0VELCBCRl9SRUNUICk7CgoJICAgLyogVG8gcGxhY2UgZGUgYml0bWFwIGNvcnJlY3RseSAqLwoJICAgeEJvcmRlck9mZnNldCArPSBHZXRTeXN0ZW1NZXRyaWNzKFNNX0NYRURHRSk7CgkgICB5Qm9yZGVyT2Zmc2V0ICs9IEdldFN5c3RlbU1ldHJpY3MoU01fQ1lFREdFKTsKCgkgICByYy5yaWdodC0tLCByYy5ib3R0b20tLTsKCX0KICAgIH0KICAgIGVsc2UKICAgIHsKICAgICAgICBVSU5UIHVTdGF0ZSA9IERGQ1NfQlVUVE9OUFVTSDsKCiAgICAgICAgaWYgKHB1c2hlZFN0YXRlKQoJewoJICAgIGlmICggKHduZFB0ci0+ZHdTdHlsZSAmIDB4MDAwZikgPT0gQlNfREVGUFVTSEJVVFRPTiApCgkgICAgICAgIHVTdGF0ZSB8PSBERkNTX0ZMQVQ7CgkgICAgZWxzZQoJICAgICAgICB1U3RhdGUgfD0gREZDU19QVVNIRUQ7Cgl9CgoJRHJhd0ZyYW1lQ29udHJvbCggaERDLCAmcmMsIERGQ19CVVRUT04sIHVTdGF0ZSApOwoJSW5mbGF0ZVJlY3QoICZyYywgLTIsIC0yICk7CgoJZm9jdXNfcmVjdCA9IHJjOwoKICAgICAgICBpZiAocHVzaGVkU3RhdGUpCgl7CgkgICAgcmMubGVmdCArPSAyOyAgLyogVG8gcG9zaXRpb24gdGhlIHRleHQgZG93biBhbmQgcmlnaHQgKi8KCSAgICByYy50b3AgICs9IDI7Cgl9CiAgICB9CgogICAgLyogZHJhdyBidXR0b24gbGFiZWwsIGlmIGFueToKICAgICAqCiAgICAgKiBJbiB3aW45eCB3ZSBkb24ndCBzaG93IHRleHQgaWYgdGhlcmUgaXMgYSBiaXRtYXAgb3IgaWNvbi4KICAgICAqIEkgZG9uJ3Qga25vdyBhYm91dCB3aW4zMSBzbyBJIGxlYXZlIGl0IGFzIGl0IHdhcyBmb3Igd2luMzEuCiAgICAgKiBEZW5uaXMgQmr2cmtsdW5kIDEyIEp1bCwgOTkKICAgICAqLwogICAgaWYgKCB3bmRQdHItPnRleHQgJiYgd25kUHRyLT50ZXh0WzBdCgkgJiYgKFRXRUFLX1dpbmVMb29rID09IFdJTjMxX0xPT0sgfHwgISh3bmRQdHItPmR3U3R5bGUgJiAoQlNfSUNPTnxCU19CSVRNQVApKSkgKQogICAgewogICAgICAgIExPR0JSVVNIIGxiOwogICAgICAgIEdldE9iamVjdEEoIEdldFN5c0NvbG9yQnJ1c2goQ09MT1JfQlRORkFDRSksIHNpemVvZihsYiksICZsYiApOwogICAgICAgIGlmICh3bmRQdHItPmR3U3R5bGUgJiBXU19ESVNBQkxFRCAmJgogICAgICAgICAgICBHZXRTeXNDb2xvcihDT0xPUl9HUkFZVEVYVCk9PWxiLmxiQ29sb3IpCiAgICAgICAgICAgIC8qIGRvbid0IHdyaXRlIGdyYXkgdGV4dCBvbiBncmF5IGJhY2tncm91bmQgKi8KICAgICAgICAgICAgUGFpbnRHcmF5T25HcmF5KCBoREMsaW5mb1B0ci0+aEZvbnQsJnJjLHduZFB0ci0+dGV4dCwKCQkJICAgICAgIERUX0NFTlRFUiB8IERUX1ZDRU5URVIgKTsKICAgICAgICBlbHNlCiAgICAgICAgewogICAgICAgICAgICBTZXRUZXh0Q29sb3IoIGhEQywgKHduZFB0ci0+ZHdTdHlsZSAmIFdTX0RJU0FCTEVEKSA/CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEdldFN5c0NvbG9yKENPTE9SX0dSQVlURVhUKSA6CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEdldFN5c0NvbG9yKENPTE9SX0JUTlRFWFQpICk7CiAgICAgICAgICAgIERyYXdUZXh0QSggaERDLCB3bmRQdHItPnRleHQsIC0xLCAmcmMsCiAgICAgICAgICAgICAgICAgICAgICAgICBEVF9TSU5HTEVMSU5FIHwgRFRfQ0VOVEVSIHwgRFRfVkNFTlRFUiApOwogICAgICAgICAgICAvKiBkbyB3ZSBoYXZlIHRoZSBmb2N1cz8KCSAgICAgKiBXaW45eCBkcmF3cyBmb2N1cyBsYXN0IHdpdGggYSBzaXplIHByb3AuIHRvIHRoZSBidXR0b24KCSAgICAgKi8KICAgICAgICAgICAgaWYgKFRXRUFLX1dpbmVMb29rID09IFdJTjMxX0xPT0sKCQkmJiBpbmZvUHRyLT5zdGF0ZSAmIEJVVFRPTl9IQVNGT0NVUykKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgUkVDVCByID0geyAwLCAwLCAwLCAwIH07CiAgICAgICAgICAgICAgICBJTlQgeGRlbHRhLCB5ZGVsdGE7CgogICAgICAgICAgICAgICAgRHJhd1RleHRBKCBoREMsIHduZFB0ci0+dGV4dCwgLTEsICZyLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIERUX1NJTkdMRUxJTkUgfCBEVF9DQUxDUkVDVCApOwogICAgICAgICAgICAgICAgeGRlbHRhID0gKChyYy5yaWdodCAtIHJjLmxlZnQpIC0gKHIucmlnaHQgLSByLmxlZnQpIC0gMSkgLyAyOwogICAgICAgICAgICAgICAgeWRlbHRhID0gKChyYy5ib3R0b20gLSByYy50b3ApIC0gKHIuYm90dG9tIC0gci50b3ApIC0gMSkgLyAyOwogICAgICAgICAgICAgICAgaWYgKHhkZWx0YSA8IDApIHhkZWx0YSA9IDA7CiAgICAgICAgICAgICAgICBpZiAoeWRlbHRhIDwgMCkgeWRlbHRhID0gMDsKICAgICAgICAgICAgICAgIEluZmxhdGVSZWN0KCAmcmMsIC14ZGVsdGEsIC15ZGVsdGEgKTsKICAgICAgICAgICAgICAgIERyYXdGb2N1c1JlY3QoIGhEQywgJnJjICk7CiAgICAgICAgICAgIH0KICAgICAgICB9ICAgCiAgICB9CiAgICBpZiAoICgod25kUHRyLT5kd1N0eWxlICYgQlNfSUNPTikgfHwgKHduZFB0ci0+ZHdTdHlsZSAmIEJTX0JJVE1BUCkgKSAmJgoJIChpbmZvUHRyLT5oSW1hZ2UgIT0gTlVMTCkgKQogICAgewoJaW50IHlPZmZzZXQsIHhPZmZzZXQ7CglpbnQgaW1hZ2VXaWR0aCwgaW1hZ2VIZWlnaHQ7CgoJLyoKCSAqIFdlIGV4dHJhY3QgdGhlIHNpemUgb2YgdGhlIGltYWdlIGZyb20gdGhlIGhhbmRsZS4KCSAqLwoJaWYgKHduZFB0ci0+ZHdTdHlsZSAmIEJTX0lDT04pCgl7CgkgICAgSUNPTklORk8gaWNvbkluZm87CgkgICAgQklUTUFQICAgYm07CgoJICAgIEdldEljb25JbmZvKChISUNPTilpbmZvUHRyLT5oSW1hZ2UsICZpY29uSW5mbyk7CgkgICAgR2V0T2JqZWN0QSAoaWNvbkluZm8uaGJtQ29sb3IsIHNpemVvZihCSVRNQVApLCAmYm0pOwoJICAgIAoJICAgIGltYWdlV2lkdGggID0gYm0uYm1XaWR0aDsKCSAgICBpbWFnZUhlaWdodCA9IGJtLmJtSGVpZ2h0OwoKICAgICAgICAgICAgRGVsZXRlT2JqZWN0KGljb25JbmZvLmhibUNvbG9yKTsKICAgICAgICAgICAgRGVsZXRlT2JqZWN0KGljb25JbmZvLmhibU1hc2spOwoKCX0KCWVsc2UKCXsKCSAgICBCSVRNQVAgICBibTsKCgkgICAgR2V0T2JqZWN0QSAoaW5mb1B0ci0+aEltYWdlLCBzaXplb2YoQklUTUFQKSwgJmJtKTsKCQoJICAgIGltYWdlV2lkdGggID0gYm0uYm1XaWR0aDsKCSAgICBpbWFnZUhlaWdodCA9IGJtLmJtSGVpZ2h0OwoJfQoKCS8qIENlbnRlciB0aGUgYml0bWFwICovCgl4T2Zmc2V0ID0gKCgocmMucmlnaHQgLSByYy5sZWZ0KSAtIDIqeEJvcmRlck9mZnNldCkgLSBpbWFnZVdpZHRoICkgLyAyOwoJeU9mZnNldCA9ICgoKHJjLmJvdHRvbSAtIHJjLnRvcCkgLSAyKnlCb3JkZXJPZmZzZXQpIC0gaW1hZ2VIZWlnaHQpIC8gMjsKCgkvKiBJZiB0aGUgaW1hZ2UgaXMgdG9vIGJpZyBmb3IgdGhlIGJ1dHRvbiB0aGVuIGNyZWF0ZSBhIHJlZ2lvbiovCiAgICAgICAgaWYoeE9mZnNldCA8IDAgfHwgeU9mZnNldCA8IDApCgl7CiAgICAgICAgICAgIEhSR04gaEJpdG1hcFJnbiA9IE5VTEw7CiAgICAgICAgICAgIGhCaXRtYXBSZ24gPSBDcmVhdGVSZWN0UmduKAogICAgICAgICAgICAgICAgcmMubGVmdCArIHhCb3JkZXJPZmZzZXQsIHJjLnRvcCAreUJvcmRlck9mZnNldCwgCiAgICAgICAgICAgICAgICByYy5yaWdodCAtIHhCb3JkZXJPZmZzZXQsIHJjLmJvdHRvbSAtIHlCb3JkZXJPZmZzZXQpOwogICAgICAgICAgICBTZWxlY3RDbGlwUmduKGhEQywgaEJpdG1hcFJnbik7CiAgICAgICAgICAgIERlbGV0ZU9iamVjdChoQml0bWFwUmduKTsKCX0KCgkvKiBMZXQgbWluaW11bSAxIHNwYWNlIGZyb20gYm9yZGVyICovCgl4T2Zmc2V0KyssIHlPZmZzZXQrKzsKCgkvKgoJICogRHJhdyB0aGUgaW1hZ2Ugbm93LgoJICovCglpZiAod25kUHRyLT5kd1N0eWxlICYgQlNfSUNPTikKCXsKICAJICAgIERyYXdJY29uKGhEQywKICAgICAgICAgICAgICAgIHJjLmxlZnQgKyB4T2Zmc2V0LCByYy50b3AgKyB5T2Zmc2V0LAoJCSAgICAgKEhJQ09OKWluZm9QdHItPmhJbWFnZSk7Cgl9CgllbHNlCiAgICAgICAgewoJICAgIEhEQyBoZGNNZW07CgoJICAgIGhkY01lbSA9IENyZWF0ZUNvbXBhdGlibGVEQyAoaERDKTsKCSAgICBTZWxlY3RPYmplY3QgKGhkY01lbSwgKEhCSVRNQVApaW5mb1B0ci0+aEltYWdlKTsKCSAgICBCaXRCbHQoaERDLCAKCQkgICByYy5sZWZ0ICsgeE9mZnNldCwgCgkJICAgcmMudG9wICsgeU9mZnNldCwgCgkJICAgaW1hZ2VXaWR0aCwgaW1hZ2VIZWlnaHQsCgkJICAgaGRjTWVtLCAwLCAwLCBTUkNDT1BZKTsKCSAgICAKCSAgICBEZWxldGVEQyAoaGRjTWVtKTsKCX0KCiAgICAgICAgaWYoeE9mZnNldCA8IDAgfHwgeU9mZnNldCA8IDApCiAgICAgICAgewogICAgICAgICAgICBTZWxlY3RDbGlwUmduKGhEQywgTlVMTCk7CiAgICAgICAgfQogICAgfQoKICAgIGlmIChUV0VBS19XaW5lTG9vayAhPSBXSU4zMV9MT09LCgkmJiBpbmZvUHRyLT5zdGF0ZSAmIEJVVFRPTl9IQVNGT0NVUykKICAgIHsKICAgICAgICBJbmZsYXRlUmVjdCggJmZvY3VzX3JlY3QsIC0xLCAtMSApOwogICAgICAgIERyYXdGb2N1c1JlY3QoIGhEQywgJmZvY3VzX3JlY3QgKTsKICAgIH0KCiAgICAKICAgIFNlbGVjdE9iamVjdCggaERDLCBoT2xkUGVuICk7CiAgICBTZWxlY3RPYmplY3QoIGhEQywgaE9sZEJydXNoICk7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgIFBCX1BhaW50ICYgQ0JfUGFpbnQgc3ViIGZ1bmN0aW9uICAgICAgICAgICAgICAgICAgICAgICAgW2ludGVybmFsXQogKiAgIFBhaW50IHRleHQgdXNpbmcgYSByYXN0ZXIgYnJ1c2ggdG8gYXZvaWQgZ3JheSB0ZXh0IG9uIGdyYXkgCiAqICAgYmFja2dyb3VuZC4gJ2Zvcm1hdCcgY2FuIGJlIGEgY29tYmluYXRpb24gb2YgRFRfQ0VOVEVSIGFuZCAKICogICBEVF9WQ0VOVEVSIHRvIHVzZSB0aGlzIGZ1bmN0aW9uIGluIGJvdGggUEJfUEFJTlQgYW5kIAogKiAgIENCX1BBSU5ULiAgIC0gRGlyayBUaGllcmJhY2gKICoKICogICBGSVhNRTogVGhpcyBhbmQgVEVYVF9HcmF5U3RyaW5nIHNob3VsZCBiZSBldmVudHVhbGx5IGNvbWJpbmVkLAogKiAgIHNvIGNhbGxpbmcgb25lIGNvbW1vbiBmdW5jdGlvbiBmcm9tIFBCX1BhaW50LCBDQl9QYWludCBhbmQKICogICBURVhUX0dyYXlTdHJpbmcgd2lsbCBiZSBlbm91Z2guIEFsc28gbm90ZSB0aGF0IHRoaXMKICogICBmdW5jdGlvbiBpZ25vcmVzIHRoZSBDQUNIRV9HZXRQYXR0ZXJuIGZ1bmNzLgogKi8KCnZvaWQgUGFpbnRHcmF5T25HcmF5KEhEQyBoREMsSEZPTlQgaEZvbnQsUkVDVCAqcmMsY2hhciAqdGV4dCwKCQkJVUlOVCBmb3JtYXQpCnsKLyogIFRoaXMgaXMgdGhlIHN0YW5kYXJkIGdyYXkgb24gZ3JheSBwYXR0ZXJuOgogICAgc3RhdGljIGNvbnN0IFdPUkQgUGF0dGVybltdID0gezB4QUEsMHg1NSwweEFBLDB4NTUsMHhBQSwweDU1LDB4QUEsMHg1NX07IAoqLwovKiAgVGhpcyBwYXR0ZXJuIGdpdmVzIGJldHRlciByZWFkYWJpbGl0eSB3aXRoIFggRm9udHMuCiAgICBGSVhNRTogTWF5YmUgdGhlIHVzZXIgc2hvdWxkIGJlIGFsbG93ZWQgdG8gZGVjaWRlIHdoaWNoIGhlIHdhbnRzLiAqLwogICAgc3RhdGljIGNvbnN0IFdPUkQgUGF0dGVybltdID0gezB4NTUsMHhGRiwweEFBLDB4RkYsMHg1NSwweEZGLDB4QUEsMHhGRn07IAoKICAgIEhCSVRNQVAgaGJtICA9IENyZWF0ZUJpdG1hcCggOCwgOCwgMSwgMSwgUGF0dGVybiApOwogICAgSERDIGhkY01lbSA9IENyZWF0ZUNvbXBhdGlibGVEQyhoREMpOwogICAgSEJJVE1BUCBoYm1NZW07CiAgICBIQlJVU0ggaEJyOwogICAgUkVDVCByZWN0LHJjMjsKCiAgICByZWN0PSpyYzsKICAgIERyYXdUZXh0QSggaERDLCB0ZXh0LCAtMSwgJnJlY3QsIERUX1NJTkdMRUxJTkUgfCBEVF9DQUxDUkVDVCk7CiAgICAvKiBub3cgdGV4dCB3aWR0aCBhbmQgaGVpZ2h0IGFyZSBpbiByZWN0LnJpZ2h0IGFuZCByZWN0LmJvdHRvbSAqLwogICAgcmMyPXJlY3Q7CiAgICByZWN0LmxlZnQgPSByZWN0LnRvcCA9IDA7IC8qIGRyYXdpbmcgcG9zIGluIGhkY01lbSAqLwogICAgaWYgKGZvcm1hdCAmIERUX0NFTlRFUikgcmVjdC5sZWZ0PShyYy0+cmlnaHQtcmVjdC5yaWdodCkvMjsKICAgIGlmIChmb3JtYXQgJiBEVF9WQ0VOVEVSKSByZWN0LnRvcD0ocmMtPmJvdHRvbS1yZWN0LmJvdHRvbSkvMjsKICAgIGhibU1lbSA9IENyZWF0ZUNvbXBhdGlibGVCaXRtYXAoIGhEQyxyZWN0LnJpZ2h0LHJlY3QuYm90dG9tICk7CiAgICBTZWxlY3RPYmplY3QoIGhkY01lbSwgaGJtTWVtKTsKICAgIFBhdEJsdCggaGRjTWVtLDAsMCxyZWN0LnJpZ2h0LHJlY3QuYm90dG9tLFdISVRFTkVTUyk7CiAgICAgIC8qIHdpbGwgYmUgb3ZlcndyaXR0ZW4gYnkgRHJhd1RleHQsIGJ1dCBqdXN0IGluIGNhc2UgKi8KICAgIGlmIChoRm9udCkgU2VsZWN0T2JqZWN0KCBoZGNNZW0sIGhGb250KTsKICAgIERyYXdUZXh0QSggaGRjTWVtLCB0ZXh0LCAtMSwgJnJjMiwgRFRfU0lOR0xFTElORSk7ICAKICAgICAgLyogQWZ0ZXIgZHJhdzogZm9yZWdyb3VuZCA9IDAgYml0cywgYmFja2dyb3VuZCA9IDEgYml0cyAqLwogICAgaEJyID0gU2VsZWN0T2JqZWN0KCBoZGNNZW0sIENyZWF0ZVBhdHRlcm5CcnVzaChoYm0pICk7CiAgICBEZWxldGVPYmplY3QoIGhibSApOwogICAgUGF0Qmx0KCBoZGNNZW0sMCwwLHJlY3QucmlnaHQscmVjdC5ib3R0b20sMHhBRjAyMjkpOyAKICAgICAgLyogb25seSBrZWVwIHRoZSBmb3JlZ3JvdW5kIGJpdHMgd2hlcmUgcGF0dGVybiBpcyAxICovCiAgICBEZWxldGVPYmplY3QoIFNlbGVjdE9iamVjdCggaGRjTWVtLGhCcikgKTsKICAgIEJpdEJsdChoREMscmVjdC5sZWZ0LHJlY3QudG9wLHJlY3QucmlnaHQscmVjdC5ib3R0b20saGRjTWVtLDAsMCxTUkNBTkQpOwogICAgICAvKiBrZWVwIHRoZSBiYWNrZ3JvdW5kIG9mIHRoZSBkZXN0ICovCiAgICBEZWxldGVEQyggaGRjTWVtKTsKICAgIERlbGV0ZU9iamVjdCggaGJtTWVtICk7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgICBDaGVjayBCb3ggJiBSYWRpbyBCdXR0b24gRnVuY3Rpb25zCiAqLwoKc3RhdGljIHZvaWQgQ0JfUGFpbnQoIFdORCAqd25kUHRyLCBIREMgaERDLCBXT1JEIGFjdGlvbiApCnsKICAgIFJFQ1QgcmJveCwgcnRleHQsIGNsaWVudDsKICAgIEhCUlVTSCBoQnJ1c2g7CiAgICBpbnQgdGV4dGxlbiwgZGVsdGE7CiAgICBCVVRUT05JTkZPICppbmZvUHRyID0gKEJVVFRPTklORk8gKil3bmRQdHItPndFeHRyYTsKCiAgICAvKiAKICAgICAqIGlmIHRoZSBidXR0b24gaGFzIGEgYml0bWFwL2ljb24sIGRyYXcgYSBub3JtYWwgcHVzaGJ1dHRvbgogICAgICogaW5zdGVhZCBvZiBhIHJhZGlvbiBidXR0b24uCiAgICAgKi8KICAgIGlmIChpbmZvUHRyLT5oSW1hZ2UhPU5VTEwpCiAgICB7CiAgICAgICAgQk9PTCBiSGlnaExpZ2h0ZWQgPSAoKGluZm9QdHItPnN0YXRlICYgQlVUVE9OX0hJR0hMSUdIVEVEKSB8fAoJCQkgICAgIChpbmZvUHRyLT5zdGF0ZSAmIEJVVFRPTl9DSEVDS0VEKSk7CgogICAgICAgIEJVVFRPTl9EcmF3UHVzaEJ1dHRvbih3bmRQdHIsCgkJCSAgICAgIGhEQywKCQkJICAgICAgYWN0aW9uLAoJCQkgICAgICBiSGlnaExpZ2h0ZWQpOwoJcmV0dXJuOwogICAgfQoKICAgIHRleHRsZW4gPSAwOwogICAgR2V0Q2xpZW50UmVjdCh3bmRQdHItPmh3bmRTZWxmLCAmY2xpZW50KTsKICAgIHJib3ggPSBydGV4dCA9IGNsaWVudDsKCiAgICBpZiAoaW5mb1B0ci0+aEZvbnQpIFNlbGVjdE9iamVjdCggaERDLCBpbmZvUHRyLT5oRm9udCApOwoKICAgIC8qIFNvbWV0aGluZyBpcyBzdGlsbCBub3QgcmlnaHQsIGNoZWNrYm94ZXMgKGFuZCBlZGl0IGNvbnRyb2xzKQogICAgICogaW4gd3NwaW5nMzIgaGF2ZSB3aGl0ZSBiYWNrZ3JvdW5kcyBpbnN0ZWFkIG9mIGRhcmsgZ3JleS4KICAgICAqIEJVVFRPTl9TRU5EX0NUTENPTE9SKCkgaXMgZXZlbiB3b3JzZSBzaW5jZSBpdCByZXR1cm5zIDAgaW4gdGhpcwogICAgICogcGFydGljdWxhciBjYXNlIGFuZCB0aGUgYmFja2dyb3VuZCBpcyBub3QgcGFpbnRlZCBhdCBhbGwuCiAgICAgKi8KCiAgICBoQnJ1c2ggPSBHZXRDb250cm9sQnJ1c2gxNiggd25kUHRyLT5od25kU2VsZiwgaERDLCBDVExDT0xPUl9CVE4gKTsKCiAgICBpZiAod25kUHRyLT5kd1N0eWxlICYgQlNfTEVGVFRFWFQpIAogICAgewoJLyogbWFnaWMgKzQgaXMgd2hhdCBDVEwzRCBleHBlY3RzICovCgogICAgICAgIHJ0ZXh0LnJpZ2h0IC09IGNoZWNrQm94V2lkdGggKyA0OwogICAgICAgIHJib3gubGVmdCA9IHJib3gucmlnaHQgLSBjaGVja0JveFdpZHRoOwogICAgfQogICAgZWxzZSAKICAgIHsKICAgICAgICBydGV4dC5sZWZ0ICs9IGNoZWNrQm94V2lkdGggKyA0OwogICAgICAgIHJib3gucmlnaHQgPSBjaGVja0JveFdpZHRoOwogICAgfQoKICAgICAgLyogRHJhdyB0aGUgY2hlY2stYm94IGJpdG1hcCAqLwoKICAgIGlmICh3bmRQdHItPnRleHQpIHRleHRsZW4gPSBzdHJsZW4oIHduZFB0ci0+dGV4dCApOwogICAgaWYgKGFjdGlvbiA9PSBPREFfRFJBV0VOVElSRSB8fCBhY3Rpb24gPT0gT0RBX1NFTEVDVCkKICAgIHsgCiAgICAgICAgaWYoIFRXRUFLX1dpbmVMb29rID09IFdJTjMxX0xPT0sgKQogICAgICAgIHsKICAgICAgICBIREMgaE1lbURDID0gQ3JlYXRlQ29tcGF0aWJsZURDKCBoREMgKTsKICAgICAgICBpbnQgeCA9IDAsIHkgPSAwOwogICAgICAgIGRlbHRhID0gKHJib3guYm90dG9tIC0gcmJveC50b3AgLSBjaGVja0JveEhlaWdodCkgLyAyOwoKCS8qIENoZWNrIGluIGNhc2UgdGhlIGNsaWVudCBhcmVhIGlzIHNtYWxsZXIgdGhhbiB0aGUgY2hlY2tib3ggYml0bWFwICovCglpZiAoZGVsdGEgPCAwKSBkZWx0YSA9IDA7CgogICAgICAgIGlmIChhY3Rpb24gPT0gT0RBX1NFTEVDVCkgRmlsbFJlY3QoIGhEQywgJnJib3gsIGhCcnVzaCApOwogICAgICAgIGVsc2UgRmlsbFJlY3QoIGhEQywgJmNsaWVudCwgaEJydXNoICk7CgogICAgICAgIGlmIChpbmZvUHRyLT5zdGF0ZSAmIEJVVFRPTl9ISUdITElHSFRFRCkgeCArPSAyICogY2hlY2tCb3hXaWR0aDsKICAgICAgICBpZiAoaW5mb1B0ci0+c3RhdGUgJiAoQlVUVE9OX0NIRUNLRUQgfCBCVVRUT05fM1NUQVRFKSkgeCArPSBjaGVja0JveFdpZHRoOwogICAgICAgIGlmICgoKHduZFB0ci0+ZHdTdHlsZSAmIDB4MGYpID09IEJTX1JBRElPQlVUVE9OKSB8fAogICAgICAgICAgICAoKHduZFB0ci0+ZHdTdHlsZSAmIDB4MGYpID09IEJTX0FVVE9SQURJT0JVVFRPTikpIHkgKz0gY2hlY2tCb3hIZWlnaHQ7CiAgICAgICAgZWxzZSBpZiAoaW5mb1B0ci0+c3RhdGUgJiBCVVRUT05fM1NUQVRFKSB5ICs9IDIgKiBjaGVja0JveEhlaWdodDsKCgkvKiBUaGUgYml0bWFwIGZvciB0aGUgcmFkaW8gYnV0dG9uIGlzIG5vdCBhbGlnbmVkIHdpdGggdGhlCgkgKiBsZWZ0IG9mIHRoZSB3aW5kb3csIGl0IGlzIDEgcGl4ZWwgb2ZmLiAqLwogICAgICAgIGlmICgoKHduZFB0ci0+ZHdTdHlsZSAmIDB4MGYpID09IEJTX1JBRElPQlVUVE9OKSB8fAogICAgICAgICAgICAoKHduZFB0ci0+ZHdTdHlsZSAmIDB4MGYpID09IEJTX0FVVE9SQURJT0JVVFRPTikpCgkgIHJib3gubGVmdCArPSAxOwoKCVNlbGVjdE9iamVjdCggaE1lbURDLCBoYml0bWFwQ2hlY2tCb3hlcyApOwoJQml0Qmx0KCBoREMsIHJib3gubGVmdCwgcmJveC50b3AgKyBkZWx0YSwgY2hlY2tCb3hXaWR0aCwKCQkgIGNoZWNrQm94SGVpZ2h0LCBoTWVtREMsIHgsIHksIFNSQ0NPUFkgKTsKCURlbGV0ZURDKCBoTWVtREMgKTsKICAgICAgICB9CiAgICAgICAgZWxzZQogICAgICAgIHsKCSAgICBVSU5UIHN0YXRlOwoKICAgICAgICAgICAgaWYgKCgod25kUHRyLT5kd1N0eWxlICYgMHgwZikgPT0gQlNfUkFESU9CVVRUT04pIHx8CiAgICAgICAgICAgICAgICAoKHduZFB0ci0+ZHdTdHlsZSAmIDB4MGYpID09IEJTX0FVVE9SQURJT0JVVFRPTikpIHN0YXRlID0gREZDU19CVVRUT05SQURJTzsKICAgICAgICAgICAgZWxzZSBpZiAoaW5mb1B0ci0+c3RhdGUgJiBCVVRUT05fM1NUQVRFKSBzdGF0ZSA9IERGQ1NfQlVUVE9OM1NUQVRFOwoJICAgIGVsc2Ugc3RhdGUgPSBERkNTX0JVVFRPTkNIRUNLOwoKICAgICAgICAgICAgaWYgKGluZm9QdHItPnN0YXRlICYgKEJVVFRPTl9DSEVDS0VEIHwgQlVUVE9OXzNTVEFURSkpIHN0YXRlIHw9IERGQ1NfQ0hFQ0tFRDsKCSAgICAKCSAgICBpZiAoaW5mb1B0ci0+c3RhdGUgJiBCVVRUT05fSElHSExJR0hURUQpIHN0YXRlIHw9IERGQ1NfUFVTSEVEOwoKCSAgICBpZiAod25kUHRyLT5kd1N0eWxlICYgV1NfRElTQUJMRUQpIHN0YXRlIHw9IERGQ1NfSU5BQ1RJVkU7CgoJICAgIERyYXdGcmFtZUNvbnRyb2woIGhEQywgJnJib3gsIERGQ19CVVRUT04sIHN0YXRlICk7CiAgICAgICAgfQoKCiAgICAgICAgaWYoIHRleHRsZW4gJiYgYWN0aW9uICE9IE9EQV9TRUxFQ1QgKQogICAgICAgIHsKCSAgaWYgKHduZFB0ci0+ZHdTdHlsZSAmIFdTX0RJU0FCTEVEICYmCgkgICAgICBHZXRTeXNDb2xvcihDT0xPUl9HUkFZVEVYVCk9PUdldEJrQ29sb3IoaERDKSkgewogICAgICAgICAgICAvKiBkb24ndCB3cml0ZSBncmF5IHRleHQgb24gZ3JheSBiYWNrZ3JvdW5kICovCiAgICAgICAgICAgIFBhaW50R3JheU9uR3JheSggaERDLCBpbmZvUHRyLT5oRm9udCwgJnJ0ZXh0LCB3bmRQdHItPnRleHQsCgkJCSAgICAgRFRfVkNFTlRFUik7CgkgIH0gZWxzZSB7CiAgICAgICAgICAgIGlmICh3bmRQdHItPmR3U3R5bGUgJiBXU19ESVNBQkxFRCkKICAgICAgICAgICAgICAgIFNldFRleHRDb2xvciggaERDLCBHZXRTeXNDb2xvcihDT0xPUl9HUkFZVEVYVCkgKTsKICAgICAgICAgICAgRHJhd1RleHRBKCBoREMsIHduZFB0ci0+dGV4dCwgdGV4dGxlbiwgJnJ0ZXh0LAoJCQkgRFRfU0lOR0xFTElORSB8IERUX1ZDRU5URVIgKTsKCSAgfQogICAgICAgIH0KICAgIH0KCiAgICBpZiAoKGFjdGlvbiA9PSBPREFfRk9DVVMpIHx8CiAgICAgICAgKChhY3Rpb24gPT0gT0RBX0RSQVdFTlRJUkUpICYmIChpbmZvUHRyLT5zdGF0ZSAmIEJVVFRPTl9IQVNGT0NVUykpKQogICAgewoJLyogYWdhaW4sIHRoaXMgaXMgd2hhdCBDVEwzRCBleHBlY3RzICovCgogICAgICAgIFNldFJlY3RFbXB0eSgmcmJveCk7CiAgICAgICAgaWYoIHRleHRsZW4gKQogICAgICAgICAgICBEcmF3VGV4dEEoIGhEQywgd25kUHRyLT50ZXh0LCB0ZXh0bGVuLCAmcmJveCwKCQkJIERUX1NJTkdMRUxJTkUgfCBEVF9DQUxDUkVDVCApOwogICAgICAgIHRleHRsZW4gPSByYm94LmJvdHRvbSAtIHJib3gudG9wOwogICAgICAgIGRlbHRhID0gKChydGV4dC5ib3R0b20gLSBydGV4dC50b3ApIC0gdGV4dGxlbikvMjsKICAgICAgICByYm94LmJvdHRvbSA9IChyYm94LnRvcCA9IHJ0ZXh0LnRvcCArIGRlbHRhIC0gMSkgKyB0ZXh0bGVuICsgMjsKICAgICAgICB0ZXh0bGVuID0gcmJveC5yaWdodCAtIHJib3gubGVmdDsKICAgICAgICByYm94LnJpZ2h0ID0gKHJib3gubGVmdCArPSAtLXJ0ZXh0LmxlZnQpICsgdGV4dGxlbiArIDI7CiAgICAgICAgSW50ZXJzZWN0UmVjdCgmcmJveCwgJnJib3gsICZydGV4dCk7CiAgICAgICAgRHJhd0ZvY3VzUmVjdCggaERDLCAmcmJveCApOwogICAgfQp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICAgQlVUVE9OX0NoZWNrQXV0b1JhZGlvQnV0dG9uCiAqCiAqIHduZFB0ciBpcyBjaGVja2VkLCB1bmNoZWNrIGV2ZXJ5IG90aGVyIGF1dG8gcmFkaW8gYnV0dG9uIGluIGdyb3VwCiAqLwpzdGF0aWMgdm9pZCBCVVRUT05fQ2hlY2tBdXRvUmFkaW9CdXR0b24oIFdORCAqd25kUHRyICkKewogICAgSFdORCBwYXJlbnQsIHNpYmxpbmcsIHN0YXJ0OwogICAgaWYgKCEod25kUHRyLT5kd1N0eWxlICYgV1NfQ0hJTEQpKSByZXR1cm47CiAgICBwYXJlbnQgPSB3bmRQdHItPnBhcmVudC0+aHduZFNlbGY7CiAgICAvKiBhc3N1cmUgdGhhdCBzdGFydGluZyBjb250cm9sIGlzIG5vdCBkaXNhYmxlZCBvciBpbnZpc2libGUgKi8KICAgIHN0YXJ0ID0gc2libGluZyA9IEdldE5leHREbGdHcm91cEl0ZW0oIHBhcmVudCwgd25kUHRyLT5od25kU2VsZiwgVFJVRSApOwogICAgZG8KICAgIHsKICAgICAgICBXTkQgKnRtcFduZDsKICAgICAgICBpZiAoIXNpYmxpbmcpIGJyZWFrOwogICAgICAgIHRtcFduZCA9IFdJTl9GaW5kV25kUHRyKHNpYmxpbmcpOwogICAgICAgIGlmICgod25kUHRyLT5od25kU2VsZiAhPSBzaWJsaW5nKSAmJgogICAgICAgICAgICAoKHRtcFduZC0+ZHdTdHlsZSAmIDB4MGYpID09IEJTX0FVVE9SQURJT0JVVFRPTikpCiAgICAgICAgICAgIFNlbmRNZXNzYWdlQSggc2libGluZywgQk1fU0VUQ0hFQ0ssIEJVVFRPTl9VTkNIRUNLRUQsIDAgKTsKICAgICAgICBzaWJsaW5nID0gR2V0TmV4dERsZ0dyb3VwSXRlbSggcGFyZW50LCBzaWJsaW5nLCBGQUxTRSApOwogICAgICAgIFdJTl9SZWxlYXNlV25kUHRyKHRtcFduZCk7CiAgICB9IHdoaWxlIChzaWJsaW5nICE9IHN0YXJ0KTsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgIEdyb3VwIEJveCBGdW5jdGlvbnMKICovCgpzdGF0aWMgdm9pZCBHQl9QYWludCggV05EICp3bmRQdHIsIEhEQyBoREMsIFdPUkQgYWN0aW9uICkKewogICAgUkVDVCByYywgcmNGcmFtZTsKICAgIEJVVFRPTklORk8gKmluZm9QdHIgPSAoQlVUVE9OSU5GTyAqKXduZFB0ci0+d0V4dHJhOwoKICAgIGlmIChhY3Rpb24gIT0gT0RBX0RSQVdFTlRJUkUpIHJldHVybjsKCiAgICBCVVRUT05fU0VORF9DVExDT0xPUiggd25kUHRyLCBoREMgKTsKCiAgICBHZXRDbGllbnRSZWN0KCB3bmRQdHItPmh3bmRTZWxmLCAmcmMpOwogICAgaWYgKFRXRUFLX1dpbmVMb29rID09IFdJTjMxX0xPT0spIHsKICAgICAgICBIUEVOIGhQcmV2UGVuID0gU2VsZWN0T2JqZWN0KCBoREMsCgkJCQkJICBHZXRTeXNDb2xvclBlbihDT0xPUl9XSU5ET1dGUkFNRSkpOwoJSEJSVVNIIGhQcmV2QnJ1c2ggPSBTZWxlY3RPYmplY3QoIGhEQywKCQkJCQkgICAgICBHZXRTdG9ja09iamVjdChOVUxMX0JSVVNIKSApOwoKCVJlY3RhbmdsZSggaERDLCByYy5sZWZ0LCByYy50b3AgKyAyLCByYy5yaWdodCAtIDEsIHJjLmJvdHRvbSAtIDEgKTsKCVNlbGVjdE9iamVjdCggaERDLCBoUHJldkJydXNoICk7CglTZWxlY3RPYmplY3QoIGhEQywgaFByZXZQZW4gKTsKICAgIH0gZWxzZSB7CglURVhUTUVUUklDQSB0bTsKCXJjRnJhbWUgPSByYzsKCglpZiAoaW5mb1B0ci0+aEZvbnQpCgkgICAgU2VsZWN0T2JqZWN0IChoREMsIGluZm9QdHItPmhGb250KTsKCUdldFRleHRNZXRyaWNzQSAoaERDLCAmdG0pOwoJcmNGcmFtZS50b3AgKz0gKHRtLnRtSGVpZ2h0IC8gMikgLSAxOwoJRHJhd0VkZ2UgKGhEQywgJnJjRnJhbWUsIEVER0VfRVRDSEVELCBCRl9SRUNUKTsKICAgIH0KCiAgICBpZiAod25kUHRyLT50ZXh0KQogICAgewoJaWYgKGluZm9QdHItPmhGb250KSBTZWxlY3RPYmplY3QoIGhEQywgaW5mb1B0ci0+aEZvbnQgKTsKICAgICAgICBpZiAod25kUHRyLT5kd1N0eWxlICYgV1NfRElTQUJMRUQpCiAgICAgICAgICAgIFNldFRleHRDb2xvciggaERDLCBHZXRTeXNDb2xvcihDT0xPUl9HUkFZVEVYVCkgKTsKICAgICAgICByYy5sZWZ0ICs9IDEwOwogICAgICAgIERyYXdUZXh0QSggaERDLCB3bmRQdHItPnRleHQsIC0xLCAmcmMsIERUX1NJTkdMRUxJTkUgfCBEVF9OT0NMSVAgKTsKICAgIH0KfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgIFVzZXIgQnV0dG9uIEZ1bmN0aW9ucwogKi8KCnN0YXRpYyB2b2lkIFVCX1BhaW50KCBXTkQgKnduZFB0ciwgSERDIGhEQywgV09SRCBhY3Rpb24gKQp7CiAgICBSRUNUIHJjOwogICAgSEJSVVNIIGhCcnVzaDsKICAgIEJVVFRPTklORk8gKmluZm9QdHIgPSAoQlVUVE9OSU5GTyAqKXduZFB0ci0+d0V4dHJhOwoKICAgIGlmIChhY3Rpb24gPT0gT0RBX1NFTEVDVCkgcmV0dXJuOwoKICAgIEdldENsaWVudFJlY3QoIHduZFB0ci0+aHduZFNlbGYsICZyYyk7CgogICAgaWYgKGluZm9QdHItPmhGb250KSBTZWxlY3RPYmplY3QoIGhEQywgaW5mb1B0ci0+aEZvbnQgKTsKICAgIGhCcnVzaCA9IEdldENvbnRyb2xCcnVzaDE2KCB3bmRQdHItPmh3bmRTZWxmLCBoREMsIENUTENPTE9SX0JUTiApOwoKICAgIEZpbGxSZWN0KCBoREMsICZyYywgaEJydXNoICk7CiAgICBpZiAoKGFjdGlvbiA9PSBPREFfRk9DVVMpIHx8CiAgICAgICAgKChhY3Rpb24gPT0gT0RBX0RSQVdFTlRJUkUpICYmIChpbmZvUHRyLT5zdGF0ZSAmIEJVVFRPTl9IQVNGT0NVUykpKQogICAgICAgIERyYXdGb2N1c1JlY3QoIGhEQywgJnJjICk7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgICBPd25lcmRyYXduIEJ1dHRvbiBGdW5jdGlvbnMKICovCgpzdGF0aWMgdm9pZCBPQl9QYWludCggV05EICp3bmRQdHIsIEhEQyBoREMsIFdPUkQgYWN0aW9uICkKewogICAgQlVUVE9OSU5GTyAqaW5mb1B0ciA9IChCVVRUT05JTkZPICopd25kUHRyLT53RXh0cmE7CiAgICBEUkFXSVRFTVNUUlVDVCBkaXM7CgogICAgZGlzLkN0bFR5cGUgICAgPSBPRFRfQlVUVE9OOwogICAgZGlzLkN0bElEICAgICAgPSB3bmRQdHItPndJRG1lbnU7CiAgICBkaXMuaXRlbUlEICAgICA9IDA7CiAgICBkaXMuaXRlbUFjdGlvbiA9IGFjdGlvbjsKICAgIGRpcy5pdGVtU3RhdGUgID0gKChpbmZvUHRyLT5zdGF0ZSAmIEJVVFRPTl9IQVNGT0NVUykgPyBPRFNfRk9DVVMgOiAwKSB8CiAgICAgICAgICAgICAgICAgICAgICgoaW5mb1B0ci0+c3RhdGUgJiBCVVRUT05fSElHSExJR0hURUQpID8gT0RTX1NFTEVDVEVEIDogMCkgfAogICAgICAgICAgICAgICAgICAgICAoKHduZFB0ci0+ZHdTdHlsZSAmIFdTX0RJU0FCTEVEKSA/IE9EU19ESVNBQkxFRCA6IDApOwogICAgZGlzLmh3bmRJdGVtICAgPSB3bmRQdHItPmh3bmRTZWxmOwogICAgZGlzLmhEQyAgICAgICAgPSBoREM7CiAgICBkaXMuaXRlbURhdGEgICA9IDA7CiAgICBHZXRDbGllbnRSZWN0KCB3bmRQdHItPmh3bmRTZWxmLCAmZGlzLnJjSXRlbSApOwoKICAgIFNldEJrQ29sb3IoIGhEQywgR2V0U3lzQ29sb3IoIENPTE9SX0JUTkZBQ0UgKSApOwogICAgRmlsbFJlY3QoIGhEQywgICZkaXMucmNJdGVtLCBHZXRTeXNDb2xvckJydXNoKCBDT0xPUl9CVE5GQUNFICkgKTsKCiAgICBTZW5kTWVzc2FnZUEoIEdldFBhcmVudCh3bmRQdHItPmh3bmRTZWxmKSwgV01fRFJBV0lURU0sCiAgICAgICAgICAgICAgICAgICAgd25kUHRyLT53SURtZW51LCAoTFBBUkFNKSZkaXMgKTsKfQoK