LyogRmlsZTogYnV0dG9uLmMgLS0gQnV0dG9uIHR5cGUgd2lkZ2V0cwogKgogKiBDb3B5cmlnaHQgKEMpIDE5OTMgSm9oYW5uZXMgUnVzY2hlaW5za2kKICogQ29weXJpZ2h0IChDKSAxOTkzIERhdmlkIE1ldGNhbGZlCiAqIENvcHlyaWdodCAoQykgMTk5NCBBbGV4YW5kcmUgSnVsbGlhcmQKICovCgojaW5jbHVkZSA8c3RyaW5nLmg+CiNpbmNsdWRlICJ3aW4uaCIKI2luY2x1ZGUgImJ1dHRvbi5oIgojaW5jbHVkZSAid2luYmFzZS5oIgojaW5jbHVkZSAid2luZGVmLmgiCiNpbmNsdWRlICJ3aW5nZGkuaCIKI2luY2x1ZGUgIndpbmUvd2ludXNlcjE2LmgiCiNpbmNsdWRlICJ0d2Vhay5oIgoKc3RhdGljIHZvaWQgUGFpbnRHcmF5T25HcmF5KCBIREMgaERDLEhGT05UIGhGb250LFJFQ1QgKnJjLAoJCQkgICAgIGNoYXIgKnRleHQsIFVJTlQgZm9ybWF0ICk7CgpzdGF0aWMgdm9pZCBQQl9QYWludCggV05EICp3bmRQdHIsIEhEQyBoREMsIFdPUkQgYWN0aW9uICk7CnN0YXRpYyB2b2lkIENCX1BhaW50KCBXTkQgKnduZFB0ciwgSERDIGhEQywgV09SRCBhY3Rpb24gKTsKc3RhdGljIHZvaWQgR0JfUGFpbnQoIFdORCAqd25kUHRyLCBIREMgaERDLCBXT1JEIGFjdGlvbiApOwpzdGF0aWMgdm9pZCBVQl9QYWludCggV05EICp3bmRQdHIsIEhEQyBoREMsIFdPUkQgYWN0aW9uICk7CnN0YXRpYyB2b2lkIE9CX1BhaW50KCBXTkQgKnduZFB0ciwgSERDIGhEQywgV09SRCBhY3Rpb24gKTsKc3RhdGljIHZvaWQgQlVUVE9OX0NoZWNrQXV0b1JhZGlvQnV0dG9uKCBXTkQgKnduZFB0ciApOwpzdGF0aWMgdm9pZCBCVVRUT05fRHJhd1B1c2hCdXR0b24oIFdORCAqd25kUHRyLCBIREMgaERDLCBXT1JEIGFjdGlvbiwgQk9PTCBwdXNoZWRTdGF0ZSk7CgojZGVmaW5lIE1BWF9CVE5fVFlQRSAgMTIKCnN0YXRpYyBjb25zdCBXT1JEIG1heENoZWNrU3RhdGVbTUFYX0JUTl9UWVBFXSA9CnsKICAgIEJVVFRPTl9VTkNIRUNLRUQsICAgLyogQlNfUFVTSEJVVFRPTiAqLwogICAgQlVUVE9OX1VOQ0hFQ0tFRCwgICAvKiBCU19ERUZQVVNIQlVUVE9OICovCiAgICBCVVRUT05fQ0hFQ0tFRCwgICAgIC8qIEJTX0NIRUNLQk9YICovCiAgICBCVVRUT05fQ0hFQ0tFRCwgICAgIC8qIEJTX0FVVE9DSEVDS0JPWCAqLwogICAgQlVUVE9OX0NIRUNLRUQsICAgICAvKiBCU19SQURJT0JVVFRPTiAqLwogICAgQlVUVE9OXzNTVEFURSwgICAgICAvKiBCU18zU1RBVEUgKi8KICAgIEJVVFRPTl8zU1RBVEUsICAgICAgLyogQlNfQVVUTzNTVEFURSAqLwogICAgQlVUVE9OX1VOQ0hFQ0tFRCwgICAvKiBCU19HUk9VUEJPWCAqLwogICAgQlVUVE9OX1VOQ0hFQ0tFRCwgICAvKiBCU19VU0VSQlVUVE9OICovCiAgICBCVVRUT05fQ0hFQ0tFRCwgICAgIC8qIEJTX0FVVE9SQURJT0JVVFRPTiAqLwogICAgQlVUVE9OX1VOQ0hFQ0tFRCwgICAvKiBOb3QgZGVmaW5lZCAqLwogICAgQlVUVE9OX1VOQ0hFQ0tFRCAgICAvKiBCU19PV05FUkRSQVcgKi8KfTsKCnR5cGVkZWYgdm9pZCAoKnBmUGFpbnQpKCBXTkQgKnduZFB0ciwgSERDIGhkYywgV09SRCBhY3Rpb24gKTsKCnN0YXRpYyBjb25zdCBwZlBhaW50IGJ0blBhaW50RnVuY1tNQVhfQlROX1RZUEVdID0KewogICAgUEJfUGFpbnQsICAgIC8qIEJTX1BVU0hCVVRUT04gKi8KICAgIFBCX1BhaW50LCAgICAvKiBCU19ERUZQVVNIQlVUVE9OICovCiAgICBDQl9QYWludCwgICAgLyogQlNfQ0hFQ0tCT1ggKi8KICAgIENCX1BhaW50LCAgICAvKiBCU19BVVRPQ0hFQ0tCT1ggKi8KICAgIENCX1BhaW50LCAgICAvKiBCU19SQURJT0JVVFRPTiAqLwogICAgQ0JfUGFpbnQsICAgIC8qIEJTXzNTVEFURSAqLwogICAgQ0JfUGFpbnQsICAgIC8qIEJTX0FVVE8zU1RBVEUgKi8KICAgIEdCX1BhaW50LCAgICAvKiBCU19HUk9VUEJPWCAqLwogICAgVUJfUGFpbnQsICAgIC8qIEJTX1VTRVJCVVRUT04gKi8KICAgIENCX1BhaW50LCAgICAvKiBCU19BVVRPUkFESU9CVVRUT04gKi8KICAgIE5VTEwsICAgICAgICAvKiBOb3QgZGVmaW5lZCAqLwogICAgT0JfUGFpbnQgICAgIC8qIEJTX09XTkVSRFJBVyAqLwp9OwoKI2RlZmluZSBQQUlOVF9CVVRUT04od25kUHRyLHN0eWxlLGFjdGlvbikgXAogICAgIGlmIChidG5QYWludEZ1bmNbc3R5bGVdKSB7IFwKICAgICAgICAgSERDIGhkYyA9IEdldERDKCAod25kUHRyKS0+aHduZFNlbGYgKTsgXAogICAgICAgICAoYnRuUGFpbnRGdW5jW3N0eWxlXSkod25kUHRyLGhkYyxhY3Rpb24pOyBcCiAgICAgICAgIFJlbGVhc2VEQyggKHduZFB0ciktPmh3bmRTZWxmLCBoZGMgKTsgfQoKI2RlZmluZSBCVVRUT05fU0VORF9DVExDT0xPUih3bmRQdHIsaGRjKSBcCiAgICBTZW5kTWVzc2FnZUEoIEdldFBhcmVudCgod25kUHRyKS0+aHduZFNlbGYpLCBXTV9DVExDT0xPUkJUTiwgXAogICAgICAgICAgICAgICAgICAgIChoZGMpLCAod25kUHRyKS0+aHduZFNlbGYgKQoKc3RhdGljIEhCSVRNQVAgaGJpdG1hcENoZWNrQm94ZXMgPSAwOwpzdGF0aWMgV09SRCBjaGVja0JveFdpZHRoID0gMCwgY2hlY2tCb3hIZWlnaHQgPSAwOwoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgICAgICAgQnV0dG9uV25kUHJvY19sb2NrZWQKICogCiAqIENhbGxlZCB3aXRoIHdpbmRvdyBsb2NrIGhlbGQuCiAqLwpzdGF0aWMgaW5saW5lIExSRVNVTFQgV0lOQVBJIEJ1dHRvblduZFByb2NfbG9ja2VkKFdORCogd25kUHRyLCBVSU5UIHVNc2csCgkJCQkJICAgV1BBUkFNIHdQYXJhbSwgTFBBUkFNIGxQYXJhbSApCnsKICAgIFJFQ1QgcmVjdDsKICAgIEhXTkQJaFduZCA9IHduZFB0ci0+aHduZFNlbGY7CiAgICBQT0lOVCBwdDsKICAgIEJVVFRPTklORk8gKmluZm9QdHIgPSAoQlVUVE9OSU5GTyAqKXduZFB0ci0+d0V4dHJhOwogICAgTE9ORyBzdHlsZSA9IHduZFB0ci0+ZHdTdHlsZSAmIDB4MGY7CiAgICBIQU5ETEUgb2xkSGJpdG1hcDsKCiAgICBwdC54ID0gTE9XT1JEKGxQYXJhbSk7CiAgICBwdC55ID0gSElXT1JEKGxQYXJhbSk7CgogICAgc3dpdGNoICh1TXNnKQogICAgewogICAgY2FzZSBXTV9HRVRETEdDT0RFOgogICAgICAgIHN3aXRjaChzdHlsZSkKICAgICAgICB7CiAgICAgICAgY2FzZSBCU19QVVNIQlVUVE9OOiAgICAgIHJldHVybiBETEdDX0JVVFRPTiB8IERMR0NfVU5ERUZQVVNIQlVUVE9OOwogICAgICAgIGNhc2UgQlNfREVGUFVTSEJVVFRPTjogICByZXR1cm4gRExHQ19CVVRUT04gfCBETEdDX0RFRlBVU0hCVVRUT047CiAgICAgICAgY2FzZSBCU19SQURJT0JVVFRPTjoKICAgICAgICBjYXNlIEJTX0FVVE9SQURJT0JVVFRPTjogcmV0dXJuIERMR0NfQlVUVE9OIHwgRExHQ19SQURJT0JVVFRPTjsKICAgICAgICBkZWZhdWx0OiAgICAgICAgICAgICAgICAgcmV0dXJuIERMR0NfQlVUVE9OOwogICAgICAgIH0KCiAgICBjYXNlIFdNX0VOQUJMRToKICAgICAgICBQQUlOVF9CVVRUT04oIHduZFB0ciwgc3R5bGUsIE9EQV9EUkFXRU5USVJFICk7CiAgICAgICAgYnJlYWs7CgogICAgY2FzZSBXTV9DUkVBVEU6CiAgICAgICAgaWYgKCFoYml0bWFwQ2hlY2tCb3hlcykKICAgICAgICB7CiAgICAgICAgICAgIEJJVE1BUCBibXA7CiAgICAgICAgICAgIGhiaXRtYXBDaGVja0JveGVzID0gTG9hZEJpdG1hcEEoMCwgTUFLRUlOVFJFU09VUkNFQShPQk1fQ0hFQ0tCT1hFUykpOwogICAgICAgICAgICBHZXRPYmplY3RBKCBoYml0bWFwQ2hlY2tCb3hlcywgc2l6ZW9mKGJtcCksICZibXAgKTsKICAgICAgICAgICAgY2hlY2tCb3hXaWR0aCAgPSBibXAuYm1XaWR0aCAvIDQ7CiAgICAgICAgICAgIGNoZWNrQm94SGVpZ2h0ID0gYm1wLmJtSGVpZ2h0IC8gMzsKICAgICAgICB9CiAgICAgICAgaWYgKHN0eWxlIDwgMEwgfHwgc3R5bGUgPj0gTUFYX0JUTl9UWVBFKQogICAgICAgICAgICByZXR1cm4gLTE7IC8qIGFib3J0ICovCiAgICAgICAgaW5mb1B0ci0+c3RhdGUgPSBCVVRUT05fVU5DSEVDS0VEOwogICAgICAgIGluZm9QdHItPmhGb250ID0gMDsKICAgICAgICBpbmZvUHRyLT5oSW1hZ2UgPSAwOwogICAgICAgIHJldHVybiAwOwoKICAgIGNhc2UgV01fRVJBU0VCS0dORDoKICAgICAgICByZXR1cm4gMTsKCiAgICBjYXNlIFdNX1BBSU5UOgogICAgICAgIGlmIChidG5QYWludEZ1bmNbc3R5bGVdKQogICAgICAgIHsKICAgICAgICAgICAgUEFJTlRTVFJVQ1QgcHM7CiAgICAgICAgICAgIEhEQyBoZGMgPSB3UGFyYW0gPyAoSERDKXdQYXJhbSA6IEJlZ2luUGFpbnQoIGhXbmQsICZwcyApOwoJICAgIFNldEJrTW9kZSggaGRjLCBPUEFRVUUgKTsKICAgICAgICAgICAgKGJ0blBhaW50RnVuY1tzdHlsZV0pKCB3bmRQdHIsIGhkYywgT0RBX0RSQVdFTlRJUkUgKTsKICAgICAgICAgICAgaWYoICF3UGFyYW0gKSBFbmRQYWludCggaFduZCwgJnBzICk7CiAgICAgICAgfQogICAgICAgIGJyZWFrOwoKICAgIGNhc2UgV01fS0VZRE9XTjoKCWlmICh3UGFyYW0gPT0gVktfU1BBQ0UpCgl7CgkgICAgU2VuZE1lc3NhZ2VBKCBoV25kLCBCTV9TRVRTVEFURSwgVFJVRSwgMCApOwoJICAgIGluZm9QdHItPnN0YXRlIHw9IEJVVFRPTl9CVE5QUkVTU0VEOwoJfQoJYnJlYWs7CgkKICAgIGNhc2UgV01fTEJVVFRPTkRCTENMSzoKICAgICAgICBpZih3bmRQdHItPmR3U3R5bGUgJiBCU19OT1RJRlkgfHwgCiAgICAgICAgICAgICAgICBzdHlsZT09QlNfUkFESU9CVVRUT04gfHwKICAgICAgICAgICAgICAgIHN0eWxlPT1CU19VU0VSQlVUVE9OIHx8CiAgICAgICAgICAgICAgICBzdHlsZT09QlNfT1dORVJEUkFXKSB7CiAgICAgICAgICAgIFNlbmRNZXNzYWdlQSggR2V0UGFyZW50KGhXbmQpLCBXTV9DT01NQU5ELAogICAgICAgICAgICAgICAgICAgIE1BS0VXUEFSQU0oIHduZFB0ci0+d0lEbWVudSwgQk5fRE9VQkxFQ0xJQ0tFRCApLCBoV25kKTsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgfQogICAgICAgIC8qIGZhbGwgdGhyb3VnaCAqLwogICAgY2FzZSBXTV9MQlVUVE9ORE9XTjoKICAgICAgICBTZXRDYXB0dXJlKCBoV25kICk7CiAgICAgICAgU2V0Rm9jdXMoIGhXbmQgKTsKICAgICAgICBTZW5kTWVzc2FnZUEoIGhXbmQsIEJNX1NFVFNUQVRFLCBUUlVFLCAwICk7CiAgICAgICAgaW5mb1B0ci0+c3RhdGUgfD0gQlVUVE9OX0JUTlBSRVNTRUQ7CiAgICAgICAgYnJlYWs7CgogICAgY2FzZSBXTV9LRVlVUDoKCWlmICh3UGFyYW0gIT0gVktfU1BBQ0UpCgkgICAgYnJlYWs7CgkvKiBmYWxsIHRocm91Z2ggKi8KICAgIGNhc2UgV01fTEJVVFRPTlVQOgogICAgICAgIGlmICghKGluZm9QdHItPnN0YXRlICYgQlVUVE9OX0JUTlBSRVNTRUQpKSBicmVhazsKICAgICAgICBpbmZvUHRyLT5zdGF0ZSAmPSBCVVRUT05fTlNUQVRFUzsKICAgICAgICBpZiAoIShpbmZvUHRyLT5zdGF0ZSAmIEJVVFRPTl9ISUdITElHSFRFRCkpIHsKICAgICAgICAgICAgUmVsZWFzZUNhcHR1cmUoKTsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgfQogICAgICAgIFNlbmRNZXNzYWdlQSggaFduZCwgQk1fU0VUU1RBVEUsIEZBTFNFLCAwICk7CiAgICAgICAgUmVsZWFzZUNhcHR1cmUoKTsKICAgICAgICBHZXRDbGllbnRSZWN0KCBoV25kLCAmcmVjdCApOwoJaWYgKHVNc2cgPT0gV01fS0VZVVAgfHwgUHRJblJlY3QoICZyZWN0LCBwdCApKQogICAgICAgIHsKICAgICAgICAgICAgc3dpdGNoKHN0eWxlKQogICAgICAgICAgICB7CiAgICAgICAgICAgIGNhc2UgQlNfQVVUT0NIRUNLQk9YOgogICAgICAgICAgICAgICAgU2VuZE1lc3NhZ2VBKCBoV25kLCBCTV9TRVRDSEVDSywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAhKGluZm9QdHItPnN0YXRlICYgQlVUVE9OX0NIRUNLRUQpLCAwICk7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgY2FzZSBCU19BVVRPUkFESU9CVVRUT046CiAgICAgICAgICAgICAgICBTZW5kTWVzc2FnZUEoIGhXbmQsIEJNX1NFVENIRUNLLCBUUlVFLCAwICk7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgY2FzZSBCU19BVVRPM1NUQVRFOgogICAgICAgICAgICAgICAgU2VuZE1lc3NhZ2VBKCBoV25kLCBCTV9TRVRDSEVDSywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoaW5mb1B0ci0+c3RhdGUgJiBCVVRUT05fM1NUQVRFKSA/IDAgOgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICgoaW5mb1B0ci0+c3RhdGUgJiAzKSArIDEpLCAwICk7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgfQogICAgICAgICAgICBTZW5kTWVzc2FnZUEoIEdldFBhcmVudChoV25kKSwgV01fQ09NTUFORCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIE1BS0VXUEFSQU0oIHduZFB0ci0+d0lEbWVudSwgQk5fQ0xJQ0tFRCApLCBoV25kKTsKICAgICAgICB9CiAgICAgICAgYnJlYWs7CgogICAgY2FzZSBXTV9DQVBUVVJFQ0hBTkdFRDoKICAgICAgICBpZiAoaW5mb1B0ci0+c3RhdGUgJiBCVVRUT05fQlROUFJFU1NFRCkgewogICAgICAgICAgICBpbmZvUHRyLT5zdGF0ZSAmPSBCVVRUT05fTlNUQVRFUzsKICAgICAgICAgICAgaWYgKGluZm9QdHItPnN0YXRlICYgQlVUVE9OX0hJR0hMSUdIVEVEKSAKICAgICAgICAgICAgICAgIFNlbmRNZXNzYWdlQSggaFduZCwgQk1fU0VUU1RBVEUsIEZBTFNFLCAwICk7CiAgICAgICAgfQogICAgICAgIGJyZWFrOwoKICAgIGNhc2UgV01fTU9VU0VNT1ZFOgogICAgICAgIGlmIChHZXRDYXB0dXJlKCkgPT0gaFduZCkKICAgICAgICB7CiAgICAgICAgICAgIEdldENsaWVudFJlY3QoIGhXbmQsICZyZWN0ICk7CiAgICAgICAgICAgIFNlbmRNZXNzYWdlQSggaFduZCwgQk1fU0VUU1RBVEUsIFB0SW5SZWN0KCZyZWN0LCBwdCksIDAgKTsKICAgICAgICB9CiAgICAgICAgYnJlYWs7CgogICAgY2FzZSBXTV9OQ0hJVFRFU1Q6CiAgICAgICAgaWYoc3R5bGUgPT0gQlNfR1JPVVBCT1gpIHJldHVybiBIVFRSQU5TUEFSRU5UOwogICAgICAgIHJldHVybiBEZWZXaW5kb3dQcm9jQSggaFduZCwgdU1zZywgd1BhcmFtLCBsUGFyYW0gKTsKCiAgICBjYXNlIFdNX1NFVFRFWFQ6CiAgICAgICAgREVGV05EX1NldFRleHQoIHduZFB0ciwgKExQQ1NUUilsUGFyYW0gKTsKCWlmKCB3bmRQdHItPmR3U3R5bGUgJiBXU19WSVNJQkxFICkKICAgICAgICAgICAgUEFJTlRfQlVUVE9OKCB3bmRQdHIsIHN0eWxlLCBPREFfRFJBV0VOVElSRSApOwogICAgICAgIHJldHVybiAwOwoKICAgIGNhc2UgV01fU0VURk9OVDoKICAgICAgICBpbmZvUHRyLT5oRm9udCA9IChIRk9OVDE2KXdQYXJhbTsKICAgICAgICBpZiAobFBhcmFtICYmICh3bmRQdHItPmR3U3R5bGUgJiBXU19WSVNJQkxFKSkgCgkgICAgUEFJTlRfQlVUVE9OKCB3bmRQdHIsIHN0eWxlLCBPREFfRFJBV0VOVElSRSApOwogICAgICAgIGJyZWFrOwoKICAgIGNhc2UgV01fR0VURk9OVDoKICAgICAgICByZXR1cm4gaW5mb1B0ci0+aEZvbnQ7CgogICAgY2FzZSBXTV9TRVRGT0NVUzoKICAgICAgICBpZiAoKHN0eWxlID09IEJTX0FVVE9SQURJT0JVVFRPTikgJiYgKEdldENhcHR1cmUoKSAhPSBoV25kKSAmJgogICAgICAgICAgICAhKFNlbmRNZXNzYWdlQShoV25kLCBCTV9HRVRDSEVDSywgMCwgMCkgJiBCU1RfQ0hFQ0tFRCkpCgl7CiAgICAgICAgICAgIC8qIFRoZSBub3RpZmljYXRpb24gaXMgc2VudCB3aGVuIHRoZSBidXR0b24gKEJTX0FVVE9SQURJT0JVVFRPTikgCiAgICAgICAgICAgICAgIGlzIHVuY2tlY2tlZCBhbmQgdGhlIGZvY3VzIHdhcyBub3QgZ2l2ZW4gYnkgYSBtb3VzZSBjbGljay4gKi8KICAgICAgICAgICAgU2VuZE1lc3NhZ2VBKCBoV25kLCBCTV9TRVRDSEVDSywgVFJVRSwgMCApOwogICAgICAgICAgICBTZW5kTWVzc2FnZUEoIEdldFBhcmVudChoV25kKSwgV01fQ09NTUFORCwKICAgICAgICAgICAgICAgICAgICAgICAgICBNQUtFV1BBUkFNKCB3bmRQdHItPndJRG1lbnUsIEJOX0NMSUNLRUQgKSwgaFduZCk7CiAgICAgICAgfQogICAgICAgIGluZm9QdHItPnN0YXRlIHw9IEJVVFRPTl9IQVNGT0NVUzsKICAgICAgICBQQUlOVF9CVVRUT04oIHduZFB0ciwgc3R5bGUsIE9EQV9GT0NVUyApOwogICAgICAgIGJyZWFrOwoKICAgIGNhc2UgV01fS0lMTEZPQ1VTOgogICAgICAgIGluZm9QdHItPnN0YXRlICY9IH5CVVRUT05fSEFTRk9DVVM7CglQQUlOVF9CVVRUT04oIHduZFB0ciwgc3R5bGUsIE9EQV9GT0NVUyApOwoJSW52YWxpZGF0ZVJlY3QoIGhXbmQsIE5VTEwsIFRSVUUgKTsKICAgICAgICBicmVhazsKCiAgICBjYXNlIFdNX1NZU0NPTE9SQ0hBTkdFOgogICAgICAgIEludmFsaWRhdGVSZWN0KCBoV25kLCBOVUxMLCBGQUxTRSApOwogICAgICAgIGJyZWFrOwoKICAgIGNhc2UgQk1fU0VUU1RZTEUxNjoKICAgIGNhc2UgQk1fU0VUU1RZTEU6CiAgICAgICAgaWYgKCh3UGFyYW0gJiAweDBmKSA+PSBNQVhfQlROX1RZUEUpIGJyZWFrOwogICAgICAgIHduZFB0ci0+ZHdTdHlsZSA9ICh3bmRQdHItPmR3U3R5bGUgJiAweGZmZmZmZmYwKSAKICAgICAgICAgICAgICAgICAgICAgICAgICAgfCAod1BhcmFtICYgMHgwMDAwMDAwZik7CiAgICAgICAgc3R5bGUgPSB3bmRQdHItPmR3U3R5bGUgJiAweDAwMDAwMDBmOwogICAgICAgIFBBSU5UX0JVVFRPTiggd25kUHRyLCBzdHlsZSwgT0RBX0RSQVdFTlRJUkUgKTsKICAgICAgICBicmVhazsKCiAgICBjYXNlIEJNX0NMSUNLOgoJU2VuZE1lc3NhZ2VBKCBoV25kLCBXTV9MQlVUVE9ORE9XTiwgMCwgMCApOwoJU2VuZE1lc3NhZ2VBKCBoV25kLCBXTV9MQlVUVE9OVVAsIDAsIDAgKTsKCWJyZWFrOwoKICAgIGNhc2UgQk1fU0VUSU1BR0U6CglvbGRIYml0bWFwID0gaW5mb1B0ci0+aEltYWdlOwoJaWYgKCh3bmRQdHItPmR3U3R5bGUgJiBCU19CSVRNQVApIHx8ICh3bmRQdHItPmR3U3R5bGUgJiBCU19JQ09OKSkKCXsKCSAgICBpbmZvUHRyLT5oSW1hZ2UgPSAoSEFORExFKSBsUGFyYW07CgkgICAgSW52YWxpZGF0ZVJlY3QoIGhXbmQsIE5VTEwsIEZBTFNFICk7Cgl9CglyZXR1cm4gb2xkSGJpdG1hcDsKCiAgICBjYXNlIEJNX0dFVElNQUdFOgogICAgICAgIGlmICh3UGFyYW0gPT0gSU1BR0VfQklUTUFQKQoJICAgIHJldHVybiAoSEJJVE1BUClpbmZvUHRyLT5oSW1hZ2U7CgllbHNlIGlmICh3UGFyYW0gPT0gSU1BR0VfSUNPTikKCSAgICByZXR1cm4gKEhJQ09OKWluZm9QdHItPmhJbWFnZTsKCWVsc2UKCSAgICByZXR1cm4gKEhJQ09OKTA7CgogICAgY2FzZSBCTV9HRVRDSEVDSzE2OgogICAgY2FzZSBCTV9HRVRDSEVDSzoKICAgICAgICByZXR1cm4gaW5mb1B0ci0+c3RhdGUgJiAzOwoKICAgIGNhc2UgQk1fU0VUQ0hFQ0sxNjoKICAgIGNhc2UgQk1fU0VUQ0hFQ0s6CiAgICAgICAgaWYgKHdQYXJhbSA+IG1heENoZWNrU3RhdGVbc3R5bGVdKSB3UGFyYW0gPSBtYXhDaGVja1N0YXRlW3N0eWxlXTsKICAgICAgICBpZiAoKGluZm9QdHItPnN0YXRlICYgMykgIT0gd1BhcmFtKQogICAgICAgIHsKCSAgICBpZiAoKHN0eWxlID09IEJTX1JBRElPQlVUVE9OKSB8fCAoc3R5bGUgPT0gQlNfQVVUT1JBRElPQlVUVE9OKSkKCSAgICB7CgkJaWYgKHdQYXJhbSkKCQkgICAgd25kUHRyLT5kd1N0eWxlIHw9IFdTX1RBQlNUT1A7CgkJZWxzZQoJCSAgICB3bmRQdHItPmR3U3R5bGUgJj0gfldTX1RBQlNUT1A7CgkgICAgfQogICAgICAgICAgICBpbmZvUHRyLT5zdGF0ZSA9IChpbmZvUHRyLT5zdGF0ZSAmIH4zKSB8IHdQYXJhbTsKICAgICAgICAgICAgUEFJTlRfQlVUVE9OKCB3bmRQdHIsIHN0eWxlLCBPREFfU0VMRUNUICk7CiAgICAgICAgfQogICAgICAgIGlmICgoc3R5bGUgPT0gQlNfQVVUT1JBRElPQlVUVE9OKSAmJiAod1BhcmFtID09IEJVVFRPTl9DSEVDS0VEKSkKICAgICAgICAgICAgQlVUVE9OX0NoZWNrQXV0b1JhZGlvQnV0dG9uKCB3bmRQdHIgKTsKICAgICAgICBicmVhazsKCiAgICBjYXNlIEJNX0dFVFNUQVRFMTY6CiAgICBjYXNlIEJNX0dFVFNUQVRFOgogICAgICAgIHJldHVybiBpbmZvUHRyLT5zdGF0ZTsKCiAgICBjYXNlIEJNX1NFVFNUQVRFMTY6CiAgICBjYXNlIEJNX1NFVFNUQVRFOgogICAgICAgIGlmICh3UGFyYW0pCiAgICAgICAgewogICAgICAgICAgICBpZiAoaW5mb1B0ci0+c3RhdGUgJiBCVVRUT05fSElHSExJR0hURUQpIGJyZWFrOwogICAgICAgICAgICBpbmZvUHRyLT5zdGF0ZSB8PSBCVVRUT05fSElHSExJR0hURUQ7CiAgICAgICAgfQogICAgICAgIGVsc2UKICAgICAgICB7CiAgICAgICAgICAgIGlmICghKGluZm9QdHItPnN0YXRlICYgQlVUVE9OX0hJR0hMSUdIVEVEKSkgYnJlYWs7CiAgICAgICAgICAgIGluZm9QdHItPnN0YXRlICY9IH5CVVRUT05fSElHSExJR0hURUQ7CiAgICAgICAgfQogICAgICAgIFBBSU5UX0JVVFRPTiggd25kUHRyLCBzdHlsZSwgT0RBX1NFTEVDVCApOwogICAgICAgIGJyZWFrOwoKICAgIGRlZmF1bHQ6CiAgICAgICAgcmV0dXJuIERlZldpbmRvd1Byb2NBKGhXbmQsIHVNc2csIHdQYXJhbSwgbFBhcmFtKTsKICAgIH0KICAgIHJldHVybiAwOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICAgICAgIEJ1dHRvblduZFByb2MKICogVGhlIGJ1dHRvbiB3aW5kb3cgcHJvY2VkdXJlLiBUaGlzIGlzIGp1c3QgYSB3cmFwcGVyIHdoaWNoIGxvY2tzCiAqIHRoZSBwYXNzZWQgSFdORCBhbmQgY2FsbHMgdGhlIHJlYWwgd2luZG93IHByb2NlZHVyZSAod2l0aCBhIFdORCoKICogcG9pbnRlciBwb2ludGluZyB0byB0aGUgbG9ja2VkIHdpbmRvd3N0cnVjdHVyZSkuCiAqLwpMUkVTVUxUIFdJTkFQSSBCdXR0b25XbmRQcm9jKCBIV05EIGhXbmQsIFVJTlQgdU1zZywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgV1BBUkFNIHdQYXJhbSwgTFBBUkFNIGxQYXJhbSApCnsKICAgIExSRVNVTFQgcmVzOwogICAgV05EICp3bmRQdHIgPSBXSU5fRmluZFduZFB0cihoV25kKTsKCiAgICByZXMgPSBCdXR0b25XbmRQcm9jX2xvY2tlZCh3bmRQdHIsdU1zZyx3UGFyYW0sbFBhcmFtKTsKCiAgICBXSU5fUmVsZWFzZVduZFB0cih3bmRQdHIpOwogICAgcmV0dXJuIHJlczsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICAgUHVzaCBCdXR0b24gRnVuY3Rpb25zCiAqLwpzdGF0aWMgdm9pZCBQQl9QYWludCggV05EICp3bmRQdHIsIEhEQyBoREMsIFdPUkQgYWN0aW9uICkKewogICAgQlVUVE9OSU5GTyAqaW5mb1B0ciAgICAgID0gKEJVVFRPTklORk8gKil3bmRQdHItPndFeHRyYTsKICAgIEJPT0wgICAgICAgIGJIaWdoTGlnaHRlZCA9IChpbmZvUHRyLT5zdGF0ZSAmIEJVVFRPTl9ISUdITElHSFRFRCk7CgogICAgLyogCiAgICAgKiBEZWxlZ2F0ZSB0aGlzIHRvIHRoZSBtb3JlIGdlbmVyaWMgcHVzaGJ1dHRvbiBwYWludGluZwogICAgICogbWV0aG9kLgogICAgICovCiAgICBCVVRUT05fRHJhd1B1c2hCdXR0b24od25kUHRyLAoJCQkgIGhEQywKCQkJICBhY3Rpb24sCgkJCSAgYkhpZ2hMaWdodGVkKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogVGhpcyBtZXRob2Qgd2lsbCBhY3R1YWxseSBkbyB0aGUgZHJhd2luZyBvZiB0aGUgcHVzaGJ1dHRvbiAKICogZGVwZW5kaW5nIG9uIGl0J3Mgc3RhdGUgYW5kIHRoZSBwdXNoZWRTdGF0ZSBwYXJhbWV0ZXIuCiAqLwpzdGF0aWMgdm9pZCBCVVRUT05fRHJhd1B1c2hCdXR0b24oCiAgV05EKiB3bmRQdHIsCiAgSERDICBoREMsIAogIFdPUkQgYWN0aW9uLCAKICBCT09MIHB1c2hlZFN0YXRlICkKewogICAgUkVDVCByYywgZm9jdXNfcmVjdDsKICAgIEhQRU4gaE9sZFBlbjsKICAgIEhCUlVTSCBoT2xkQnJ1c2g7CiAgICBCVVRUT05JTkZPICppbmZvUHRyID0gKEJVVFRPTklORk8gKil3bmRQdHItPndFeHRyYTsKICAgIGludCB4Qm9yZGVyT2Zmc2V0LCB5Qm9yZGVyT2Zmc2V0OwogICAgeEJvcmRlck9mZnNldCA9IHlCb3JkZXJPZmZzZXQgPSAwOwoKICAgIEdldENsaWVudFJlY3QoIHduZFB0ci0+aHduZFNlbGYsICZyYyApOwoKICAgICAgLyogU2VuZCBXTV9DVExDT0xPUiB0byBhbGxvdyBjaGFuZ2luZyB0aGUgZm9udCAodGhlIGNvbG9ycyBhcmUgZml4ZWQpICovCiAgICBpZiAoaW5mb1B0ci0+aEZvbnQpIFNlbGVjdE9iamVjdCggaERDLCBpbmZvUHRyLT5oRm9udCApOwogICAgQlVUVE9OX1NFTkRfQ1RMQ09MT1IoIHduZFB0ciwgaERDICk7CiAgICBoT2xkUGVuID0gKEhQRU4pU2VsZWN0T2JqZWN0KGhEQywgR2V0U3lzQ29sb3JQZW4oQ09MT1JfV0lORE9XRlJBTUUpKTsKICAgIGhPbGRCcnVzaCA9KEhCUlVTSClTZWxlY3RPYmplY3QoaERDLEdldFN5c0NvbG9yQnJ1c2goQ09MT1JfQlRORkFDRSkpOwogICAgU2V0QmtNb2RlKGhEQywgVFJBTlNQQVJFTlQpOwoKICAgIGlmICggVFdFQUtfV2luZUxvb2sgPT0gV0lOMzFfTE9PSykKICAgIHsKICAgICAgICBSZWN0YW5nbGUoaERDLCByYy5sZWZ0LCByYy50b3AsIHJjLnJpZ2h0LCByYy5ib3R0b20pOwoKICAgICAgICBTZXRQaXhlbCggaERDLCByYy5sZWZ0LCByYy50b3AsIEdldFN5c0NvbG9yKENPTE9SX1dJTkRPVykgKTsKICAgICAgICBTZXRQaXhlbCggaERDLCByYy5sZWZ0LCByYy5ib3R0b20tMSwgR2V0U3lzQ29sb3IoQ09MT1JfV0lORE9XKSApOwogICAgICAgIFNldFBpeGVsKCBoREMsIHJjLnJpZ2h0LTEsIHJjLnRvcCwgR2V0U3lzQ29sb3IoQ09MT1JfV0lORE9XKSApOwogICAgICAgIFNldFBpeGVsKCBoREMsIHJjLnJpZ2h0LTEsIHJjLmJvdHRvbS0xLCBHZXRTeXNDb2xvcihDT0xPUl9XSU5ET1cpKTsKCUluZmxhdGVSZWN0KCAmcmMsIC0xLCAtMSApOwogICAgfQogICAgCiAgICBpZiAoKHduZFB0ci0+ZHdTdHlsZSAmIDB4MDAwZikgPT0gQlNfREVGUFVTSEJVVFRPTikKICAgIHsKICAgICAgICBSZWN0YW5nbGUoaERDLCByYy5sZWZ0LCByYy50b3AsIHJjLnJpZ2h0LCByYy5ib3R0b20pOwoJSW5mbGF0ZVJlY3QoICZyYywgLTEsIC0xICk7CiAgICB9CgogICAgaWYgKFRXRUFLX1dpbmVMb29rID09IFdJTjMxX0xPT0spCiAgICB7CiAgICAgICAgaWYgKHB1c2hlZFN0YXRlKQoJewoJICAgIC8qIGRyYXcgYnV0dG9uIHNoYWRvdzogKi8KCSAgICBTZWxlY3RPYmplY3QoaERDLCBHZXRTeXNDb2xvckJydXNoKENPTE9SX0JUTlNIQURPVykpOwoJICAgIFBhdEJsdChoREMsIHJjLmxlZnQsIHJjLnRvcCwgMSwgcmMuYm90dG9tLXJjLnRvcCwgUEFUQ09QWSApOwoJICAgIFBhdEJsdChoREMsIHJjLmxlZnQsIHJjLnRvcCwgcmMucmlnaHQtcmMubGVmdCwgMSwgUEFUQ09QWSApOwoJICAgIHJjLmxlZnQgKz0gMjsgIC8qIFRvIHBvc2l0aW9uIHRoZSB0ZXh0IGRvd24gYW5kIHJpZ2h0ICovCgkgICAgcmMudG9wICArPSAyOwoJfSBlbHNlIHsKCSAgIHJjLnJpZ2h0KyssIHJjLmJvdHRvbSsrOwoJICAgRHJhd0VkZ2UoIGhEQywgJnJjLCBFREdFX1JBSVNFRCwgQkZfUkVDVCApOwoKCSAgIC8qIFRvIHBsYWNlIGRlIGJpdG1hcCBjb3JyZWN0bHkgKi8KCSAgIHhCb3JkZXJPZmZzZXQgKz0gR2V0U3lzdGVtTWV0cmljcyhTTV9DWEVER0UpOwoJICAgeUJvcmRlck9mZnNldCArPSBHZXRTeXN0ZW1NZXRyaWNzKFNNX0NZRURHRSk7CgoJICAgcmMucmlnaHQtLSwgcmMuYm90dG9tLS07Cgl9CiAgICB9CiAgICBlbHNlCiAgICB7CiAgICAgICAgVUlOVCB1U3RhdGUgPSBERkNTX0JVVFRPTlBVU0g7CgogICAgICAgIGlmIChwdXNoZWRTdGF0ZSkKCXsKCSAgICBpZiAoICh3bmRQdHItPmR3U3R5bGUgJiAweDAwMGYpID09IEJTX0RFRlBVU0hCVVRUT04gKQoJICAgICAgICB1U3RhdGUgfD0gREZDU19GTEFUOwoJICAgIGVsc2UKCSAgICAgICAgdVN0YXRlIHw9IERGQ1NfUFVTSEVEOwoJfQoKCURyYXdGcmFtZUNvbnRyb2woIGhEQywgJnJjLCBERkNfQlVUVE9OLCB1U3RhdGUgKTsKCUluZmxhdGVSZWN0KCAmcmMsIC0yLCAtMiApOwoKCWZvY3VzX3JlY3QgPSByYzsKCiAgICAgICAgaWYgKHB1c2hlZFN0YXRlKQoJewoJICAgIHJjLmxlZnQgKz0gMjsgIC8qIFRvIHBvc2l0aW9uIHRoZSB0ZXh0IGRvd24gYW5kIHJpZ2h0ICovCgkgICAgcmMudG9wICArPSAyOwoJfQogICAgfQoKICAgIC8qIGRyYXcgYnV0dG9uIGxhYmVsLCBpZiBhbnk6CiAgICAgKgogICAgICogSW4gd2luOXggd2UgZG9uJ3Qgc2hvdyB0ZXh0IGlmIHRoZXJlIGlzIGEgYml0bWFwIG9yIGljb24uCiAgICAgKiBJIGRvbid0IGtub3cgYWJvdXQgd2luMzEgc28gSSBsZWF2ZSBpdCBhcyBpdCB3YXMgZm9yIHdpbjMxLgogICAgICogRGVubmlzIEJq9nJrbHVuZCAxMiBKdWwsIDk5CiAgICAgKi8KICAgIGlmICggd25kUHRyLT50ZXh0ICYmIHduZFB0ci0+dGV4dFswXQoJICYmIChUV0VBS19XaW5lTG9vayA9PSBXSU4zMV9MT09LIHx8ICEod25kUHRyLT5kd1N0eWxlICYgKEJTX0lDT058QlNfQklUTUFQKSkpICkKICAgIHsKICAgICAgICBMT0dCUlVTSCBsYjsKICAgICAgICBHZXRPYmplY3RBKCBHZXRTeXNDb2xvckJydXNoKENPTE9SX0JUTkZBQ0UpLCBzaXplb2YobGIpLCAmbGIgKTsKICAgICAgICBpZiAod25kUHRyLT5kd1N0eWxlICYgV1NfRElTQUJMRUQgJiYKICAgICAgICAgICAgR2V0U3lzQ29sb3IoQ09MT1JfR1JBWVRFWFQpPT1sYi5sYkNvbG9yKQogICAgICAgICAgICAvKiBkb24ndCB3cml0ZSBncmF5IHRleHQgb24gZ3JheSBiYWNrZ3JvdW5kICovCiAgICAgICAgICAgIFBhaW50R3JheU9uR3JheSggaERDLGluZm9QdHItPmhGb250LCZyYyx3bmRQdHItPnRleHQsCgkJCSAgICAgICBEVF9DRU5URVIgfCBEVF9WQ0VOVEVSICk7CiAgICAgICAgZWxzZQogICAgICAgIHsKICAgICAgICAgICAgU2V0VGV4dENvbG9yKCBoREMsICh3bmRQdHItPmR3U3R5bGUgJiBXU19ESVNBQkxFRCkgPwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBHZXRTeXNDb2xvcihDT0xPUl9HUkFZVEVYVCkgOgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBHZXRTeXNDb2xvcihDT0xPUl9CVE5URVhUKSApOwogICAgICAgICAgICBEcmF3VGV4dEEoIGhEQywgd25kUHRyLT50ZXh0LCAtMSwgJnJjLAogICAgICAgICAgICAgICAgICAgICAgICAgRFRfU0lOR0xFTElORSB8IERUX0NFTlRFUiB8IERUX1ZDRU5URVIgKTsKICAgICAgICAgICAgLyogZG8gd2UgaGF2ZSB0aGUgZm9jdXM/CgkgICAgICogV2luOXggZHJhd3MgZm9jdXMgbGFzdCB3aXRoIGEgc2l6ZSBwcm9wLiB0byB0aGUgYnV0dG9uCgkgICAgICovCiAgICAgICAgICAgIGlmIChUV0VBS19XaW5lTG9vayA9PSBXSU4zMV9MT09LCgkJJiYgaW5mb1B0ci0+c3RhdGUgJiBCVVRUT05fSEFTRk9DVVMpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIFJFQ1QgciA9IHsgMCwgMCwgMCwgMCB9OwogICAgICAgICAgICAgICAgSU5UIHhkZWx0YSwgeWRlbHRhOwoKICAgICAgICAgICAgICAgIERyYXdUZXh0QSggaERDLCB3bmRQdHItPnRleHQsIC0xLCAmciwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEVF9TSU5HTEVMSU5FIHwgRFRfQ0FMQ1JFQ1QgKTsKICAgICAgICAgICAgICAgIHhkZWx0YSA9ICgocmMucmlnaHQgLSByYy5sZWZ0KSAtIChyLnJpZ2h0IC0gci5sZWZ0KSAtIDEpIC8gMjsKICAgICAgICAgICAgICAgIHlkZWx0YSA9ICgocmMuYm90dG9tIC0gcmMudG9wKSAtIChyLmJvdHRvbSAtIHIudG9wKSAtIDEpIC8gMjsKICAgICAgICAgICAgICAgIGlmICh4ZGVsdGEgPCAwKSB4ZGVsdGEgPSAwOwogICAgICAgICAgICAgICAgaWYgKHlkZWx0YSA8IDApIHlkZWx0YSA9IDA7CiAgICAgICAgICAgICAgICBJbmZsYXRlUmVjdCggJnJjLCAteGRlbHRhLCAteWRlbHRhICk7CiAgICAgICAgICAgICAgICBEcmF3Rm9jdXNSZWN0KCBoREMsICZyYyApOwogICAgICAgICAgICB9CiAgICAgICAgfSAgIAogICAgfQogICAgaWYgKCAoKHduZFB0ci0+ZHdTdHlsZSAmIEJTX0lDT04pIHx8ICh3bmRQdHItPmR3U3R5bGUgJiBCU19CSVRNQVApICkgJiYKCSAoaW5mb1B0ci0+aEltYWdlICE9IDApICkKICAgIHsKCWludCB5T2Zmc2V0LCB4T2Zmc2V0OwoJaW50IGltYWdlV2lkdGgsIGltYWdlSGVpZ2h0OwoKCS8qCgkgKiBXZSBleHRyYWN0IHRoZSBzaXplIG9mIHRoZSBpbWFnZSBmcm9tIHRoZSBoYW5kbGUuCgkgKi8KCWlmICh3bmRQdHItPmR3U3R5bGUgJiBCU19JQ09OKQoJewoJICAgIElDT05JTkZPIGljb25JbmZvOwoJICAgIEJJVE1BUCAgIGJtOwoKCSAgICBHZXRJY29uSW5mbygoSElDT04paW5mb1B0ci0+aEltYWdlLCAmaWNvbkluZm8pOwoJICAgIEdldE9iamVjdEEgKGljb25JbmZvLmhibUNvbG9yLCBzaXplb2YoQklUTUFQKSwgJmJtKTsKCSAgICAKCSAgICBpbWFnZVdpZHRoICA9IGJtLmJtV2lkdGg7CgkgICAgaW1hZ2VIZWlnaHQgPSBibS5ibUhlaWdodDsKCiAgICAgICAgICAgIERlbGV0ZU9iamVjdChpY29uSW5mby5oYm1Db2xvcik7CiAgICAgICAgICAgIERlbGV0ZU9iamVjdChpY29uSW5mby5oYm1NYXNrKTsKCgl9CgllbHNlCgl7CgkgICAgQklUTUFQICAgYm07CgoJICAgIEdldE9iamVjdEEgKGluZm9QdHItPmhJbWFnZSwgc2l6ZW9mKEJJVE1BUCksICZibSk7CgkKCSAgICBpbWFnZVdpZHRoICA9IGJtLmJtV2lkdGg7CgkgICAgaW1hZ2VIZWlnaHQgPSBibS5ibUhlaWdodDsKCX0KCgkvKiBDZW50ZXIgdGhlIGJpdG1hcCAqLwoJeE9mZnNldCA9ICgoKHJjLnJpZ2h0IC0gcmMubGVmdCkgLSAyKnhCb3JkZXJPZmZzZXQpIC0gaW1hZ2VXaWR0aCApIC8gMjsKCXlPZmZzZXQgPSAoKChyYy5ib3R0b20gLSByYy50b3ApIC0gMip5Qm9yZGVyT2Zmc2V0KSAtIGltYWdlSGVpZ2h0KSAvIDI7CgoJLyogSWYgdGhlIGltYWdlIGlzIHRvbyBiaWcgZm9yIHRoZSBidXR0b24gdGhlbiBjcmVhdGUgYSByZWdpb24qLwogICAgICAgIGlmKHhPZmZzZXQgPCAwIHx8IHlPZmZzZXQgPCAwKQoJewogICAgICAgICAgICBIUkdOIGhCaXRtYXBSZ24gPSAwOwogICAgICAgICAgICBoQml0bWFwUmduID0gQ3JlYXRlUmVjdFJnbigKICAgICAgICAgICAgICAgIHJjLmxlZnQgKyB4Qm9yZGVyT2Zmc2V0LCByYy50b3AgK3lCb3JkZXJPZmZzZXQsIAogICAgICAgICAgICAgICAgcmMucmlnaHQgLSB4Qm9yZGVyT2Zmc2V0LCByYy5ib3R0b20gLSB5Qm9yZGVyT2Zmc2V0KTsKICAgICAgICAgICAgU2VsZWN0Q2xpcFJnbihoREMsIGhCaXRtYXBSZ24pOwogICAgICAgICAgICBEZWxldGVPYmplY3QoaEJpdG1hcFJnbik7Cgl9CgoJLyogTGV0IG1pbmltdW0gMSBzcGFjZSBmcm9tIGJvcmRlciAqLwoJeE9mZnNldCsrLCB5T2Zmc2V0Kys7CgoJLyoKCSAqIERyYXcgdGhlIGltYWdlIG5vdy4KCSAqLwoJaWYgKHduZFB0ci0+ZHdTdHlsZSAmIEJTX0lDT04pCgl7CiAgCSAgICBEcmF3SWNvbihoREMsCiAgICAgICAgICAgICAgICByYy5sZWZ0ICsgeE9mZnNldCwgcmMudG9wICsgeU9mZnNldCwKCQkgICAgIChISUNPTilpbmZvUHRyLT5oSW1hZ2UpOwoJfQoJZWxzZQogICAgICAgIHsKCSAgICBIREMgaGRjTWVtOwoKCSAgICBoZGNNZW0gPSBDcmVhdGVDb21wYXRpYmxlREMgKGhEQyk7CgkgICAgU2VsZWN0T2JqZWN0IChoZGNNZW0sIChIQklUTUFQKWluZm9QdHItPmhJbWFnZSk7CgkgICAgQml0Qmx0KGhEQywgCgkJICAgcmMubGVmdCArIHhPZmZzZXQsIAoJCSAgIHJjLnRvcCArIHlPZmZzZXQsIAoJCSAgIGltYWdlV2lkdGgsIGltYWdlSGVpZ2h0LAoJCSAgIGhkY01lbSwgMCwgMCwgU1JDQ09QWSk7CgkgICAgCgkgICAgRGVsZXRlREMgKGhkY01lbSk7Cgl9CgogICAgICAgIGlmKHhPZmZzZXQgPCAwIHx8IHlPZmZzZXQgPCAwKQogICAgICAgIHsKICAgICAgICAgICAgU2VsZWN0Q2xpcFJnbihoREMsIDApOwogICAgICAgIH0KICAgIH0KCiAgICBpZiAoVFdFQUtfV2luZUxvb2sgIT0gV0lOMzFfTE9PSwoJJiYgaW5mb1B0ci0+c3RhdGUgJiBCVVRUT05fSEFTRk9DVVMpCiAgICB7CiAgICAgICAgSW5mbGF0ZVJlY3QoICZmb2N1c19yZWN0LCAtMSwgLTEgKTsKICAgICAgICBEcmF3Rm9jdXNSZWN0KCBoREMsICZmb2N1c19yZWN0ICk7CiAgICB9CgogICAgCiAgICBTZWxlY3RPYmplY3QoIGhEQywgaE9sZFBlbiApOwogICAgU2VsZWN0T2JqZWN0KCBoREMsIGhPbGRCcnVzaCApOwp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICBQQl9QYWludCAmIENCX1BhaW50IHN1YiBmdW5jdGlvbiAgICAgICAgICAgICAgICAgICAgICAgIFtpbnRlcm5hbF0KICogICBQYWludCB0ZXh0IHVzaW5nIGEgcmFzdGVyIGJydXNoIHRvIGF2b2lkIGdyYXkgdGV4dCBvbiBncmF5IAogKiAgIGJhY2tncm91bmQuICdmb3JtYXQnIGNhbiBiZSBhIGNvbWJpbmF0aW9uIG9mIERUX0NFTlRFUiBhbmQgCiAqICAgRFRfVkNFTlRFUiB0byB1c2UgdGhpcyBmdW5jdGlvbiBpbiBib3RoIFBCX1BBSU5UIGFuZCAKICogICBDQl9QQUlOVC4gICAtIERpcmsgVGhpZXJiYWNoCiAqCiAqICAgRklYTUU6IFRoaXMgYW5kIFRFWFRfR3JheVN0cmluZyBzaG91bGQgYmUgZXZlbnR1YWxseSBjb21iaW5lZCwKICogICBzbyBjYWxsaW5nIG9uZSBjb21tb24gZnVuY3Rpb24gZnJvbSBQQl9QYWludCwgQ0JfUGFpbnQgYW5kCiAqICAgVEVYVF9HcmF5U3RyaW5nIHdpbGwgYmUgZW5vdWdoLiBBbHNvIG5vdGUgdGhhdCB0aGlzCiAqICAgZnVuY3Rpb24gaWdub3JlcyB0aGUgQ0FDSEVfR2V0UGF0dGVybiBmdW5jcy4KICovCgp2b2lkIFBhaW50R3JheU9uR3JheShIREMgaERDLEhGT05UIGhGb250LFJFQ1QgKnJjLGNoYXIgKnRleHQsCgkJCVVJTlQgZm9ybWF0KQp7Ci8qICBUaGlzIGlzIHRoZSBzdGFuZGFyZCBncmF5IG9uIGdyYXkgcGF0dGVybjoKICAgIHN0YXRpYyBjb25zdCBXT1JEIFBhdHRlcm5bXSA9IHsweEFBLDB4NTUsMHhBQSwweDU1LDB4QUEsMHg1NSwweEFBLDB4NTV9OyAKKi8KLyogIFRoaXMgcGF0dGVybiBnaXZlcyBiZXR0ZXIgcmVhZGFiaWxpdHkgd2l0aCBYIEZvbnRzLgogICAgRklYTUU6IE1heWJlIHRoZSB1c2VyIHNob3VsZCBiZSBhbGxvd2VkIHRvIGRlY2lkZSB3aGljaCBoZSB3YW50cy4gKi8KICAgIHN0YXRpYyBjb25zdCBXT1JEIFBhdHRlcm5bXSA9IHsweDU1LDB4RkYsMHhBQSwweEZGLDB4NTUsMHhGRiwweEFBLDB4RkZ9OyAKCiAgICBIQklUTUFQIGhibSAgPSBDcmVhdGVCaXRtYXAoIDgsIDgsIDEsIDEsIFBhdHRlcm4gKTsKICAgIEhEQyBoZGNNZW0gPSBDcmVhdGVDb21wYXRpYmxlREMoaERDKTsKICAgIEhCSVRNQVAgaGJtTWVtOwogICAgSEJSVVNIIGhCcjsKICAgIFJFQ1QgcmVjdCxyYzI7CgogICAgcmVjdD0qcmM7CiAgICBEcmF3VGV4dEEoIGhEQywgdGV4dCwgLTEsICZyZWN0LCBEVF9TSU5HTEVMSU5FIHwgRFRfQ0FMQ1JFQ1QpOwogICAgLyogbm93IHRleHQgd2lkdGggYW5kIGhlaWdodCBhcmUgaW4gcmVjdC5yaWdodCBhbmQgcmVjdC5ib3R0b20gKi8KICAgIHJjMj1yZWN0OwogICAgcmVjdC5sZWZ0ID0gcmVjdC50b3AgPSAwOyAvKiBkcmF3aW5nIHBvcyBpbiBoZGNNZW0gKi8KICAgIGlmIChmb3JtYXQgJiBEVF9DRU5URVIpIHJlY3QubGVmdD0ocmMtPnJpZ2h0LXJlY3QucmlnaHQpLzI7CiAgICBpZiAoZm9ybWF0ICYgRFRfVkNFTlRFUikgcmVjdC50b3A9KHJjLT5ib3R0b20tcmVjdC5ib3R0b20pLzI7CiAgICBoYm1NZW0gPSBDcmVhdGVDb21wYXRpYmxlQml0bWFwKCBoREMscmVjdC5yaWdodCxyZWN0LmJvdHRvbSApOwogICAgU2VsZWN0T2JqZWN0KCBoZGNNZW0sIGhibU1lbSk7CiAgICBQYXRCbHQoIGhkY01lbSwwLDAscmVjdC5yaWdodCxyZWN0LmJvdHRvbSxXSElURU5FU1MpOwogICAgICAvKiB3aWxsIGJlIG92ZXJ3cml0dGVuIGJ5IERyYXdUZXh0LCBidXQganVzdCBpbiBjYXNlICovCiAgICBpZiAoaEZvbnQpIFNlbGVjdE9iamVjdCggaGRjTWVtLCBoRm9udCk7CiAgICBEcmF3VGV4dEEoIGhkY01lbSwgdGV4dCwgLTEsICZyYzIsIERUX1NJTkdMRUxJTkUpOyAgCiAgICAgIC8qIEFmdGVyIGRyYXc6IGZvcmVncm91bmQgPSAwIGJpdHMsIGJhY2tncm91bmQgPSAxIGJpdHMgKi8KICAgIGhCciA9IFNlbGVjdE9iamVjdCggaGRjTWVtLCBDcmVhdGVQYXR0ZXJuQnJ1c2goaGJtKSApOwogICAgRGVsZXRlT2JqZWN0KCBoYm0gKTsKICAgIFBhdEJsdCggaGRjTWVtLDAsMCxyZWN0LnJpZ2h0LHJlY3QuYm90dG9tLDB4QUYwMjI5KTsgCiAgICAgIC8qIG9ubHkga2VlcCB0aGUgZm9yZWdyb3VuZCBiaXRzIHdoZXJlIHBhdHRlcm4gaXMgMSAqLwogICAgRGVsZXRlT2JqZWN0KCBTZWxlY3RPYmplY3QoIGhkY01lbSxoQnIpICk7CiAgICBCaXRCbHQoaERDLHJlY3QubGVmdCxyZWN0LnRvcCxyZWN0LnJpZ2h0LHJlY3QuYm90dG9tLGhkY01lbSwwLDAsU1JDQU5EKTsKICAgICAgLyoga2VlcCB0aGUgYmFja2dyb3VuZCBvZiB0aGUgZGVzdCAqLwogICAgRGVsZXRlREMoIGhkY01lbSk7CiAgICBEZWxldGVPYmplY3QoIGhibU1lbSApOwp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICAgQ2hlY2sgQm94ICYgUmFkaW8gQnV0dG9uIEZ1bmN0aW9ucwogKi8KCnN0YXRpYyB2b2lkIENCX1BhaW50KCBXTkQgKnduZFB0ciwgSERDIGhEQywgV09SRCBhY3Rpb24gKQp7CiAgICBSRUNUIHJib3gsIHJ0ZXh0LCBjbGllbnQ7CiAgICBIQlJVU0ggaEJydXNoOwogICAgaW50IHRleHRsZW4sIGRlbHRhOwogICAgQlVUVE9OSU5GTyAqaW5mb1B0ciA9IChCVVRUT05JTkZPICopd25kUHRyLT53RXh0cmE7CgogICAgLyogCiAgICAgKiBpZiB0aGUgYnV0dG9uIGhhcyBhIGJpdG1hcC9pY29uLCBkcmF3IGEgbm9ybWFsIHB1c2hidXR0b24KICAgICAqIGluc3RlYWQgb2YgYSByYWRpb24gYnV0dG9uLgogICAgICovCiAgICBpZiAoaW5mb1B0ci0+aEltYWdlICE9IDApCiAgICB7CiAgICAgICAgQk9PTCBiSGlnaExpZ2h0ZWQgPSAoKGluZm9QdHItPnN0YXRlICYgQlVUVE9OX0hJR0hMSUdIVEVEKSB8fAoJCQkgICAgIChpbmZvUHRyLT5zdGF0ZSAmIEJVVFRPTl9DSEVDS0VEKSk7CgogICAgICAgIEJVVFRPTl9EcmF3UHVzaEJ1dHRvbih3bmRQdHIsCgkJCSAgICAgIGhEQywKCQkJICAgICAgYWN0aW9uLAoJCQkgICAgICBiSGlnaExpZ2h0ZWQpOwoJcmV0dXJuOwogICAgfQoKICAgIHRleHRsZW4gPSAwOwogICAgR2V0Q2xpZW50UmVjdCh3bmRQdHItPmh3bmRTZWxmLCAmY2xpZW50KTsKICAgIHJib3ggPSBydGV4dCA9IGNsaWVudDsKCiAgICBpZiAoaW5mb1B0ci0+aEZvbnQpIFNlbGVjdE9iamVjdCggaERDLCBpbmZvUHRyLT5oRm9udCApOwoKICAgIC8qIFNvbWV0aGluZyBpcyBzdGlsbCBub3QgcmlnaHQsIGNoZWNrYm94ZXMgKGFuZCBlZGl0IGNvbnRyb2xzKQogICAgICogaW4gd3NwaW5nMzIgaGF2ZSB3aGl0ZSBiYWNrZ3JvdW5kcyBpbnN0ZWFkIG9mIGRhcmsgZ3JleS4KICAgICAqIEJVVFRPTl9TRU5EX0NUTENPTE9SKCkgaXMgZXZlbiB3b3JzZSBzaW5jZSBpdCByZXR1cm5zIDAgaW4gdGhpcwogICAgICogcGFydGljdWxhciBjYXNlIGFuZCB0aGUgYmFja2dyb3VuZCBpcyBub3QgcGFpbnRlZCBhdCBhbGwuCiAgICAgKi8KCiAgICBoQnJ1c2ggPSBHZXRDb250cm9sQnJ1c2gxNiggd25kUHRyLT5od25kU2VsZiwgaERDLCBDVExDT0xPUl9CVE4gKTsKCiAgICBpZiAod25kUHRyLT5kd1N0eWxlICYgQlNfTEVGVFRFWFQpIAogICAgewoJLyogbWFnaWMgKzQgaXMgd2hhdCBDVEwzRCBleHBlY3RzICovCgogICAgICAgIHJ0ZXh0LnJpZ2h0IC09IGNoZWNrQm94V2lkdGggKyA0OwogICAgICAgIHJib3gubGVmdCA9IHJib3gucmlnaHQgLSBjaGVja0JveFdpZHRoOwogICAgfQogICAgZWxzZSAKICAgIHsKICAgICAgICBydGV4dC5sZWZ0ICs9IGNoZWNrQm94V2lkdGggKyA0OwogICAgICAgIHJib3gucmlnaHQgPSBjaGVja0JveFdpZHRoOwogICAgfQoKICAgICAgLyogRHJhdyB0aGUgY2hlY2stYm94IGJpdG1hcCAqLwoKICAgIGlmICh3bmRQdHItPnRleHQpIHRleHRsZW4gPSBzdHJsZW4oIHduZFB0ci0+dGV4dCApOwogICAgaWYgKGFjdGlvbiA9PSBPREFfRFJBV0VOVElSRSB8fCBhY3Rpb24gPT0gT0RBX1NFTEVDVCkKICAgIHsgCiAgICAgICAgaWYoIFRXRUFLX1dpbmVMb29rID09IFdJTjMxX0xPT0sgKQogICAgICAgIHsKICAgICAgICBIREMgaE1lbURDID0gQ3JlYXRlQ29tcGF0aWJsZURDKCBoREMgKTsKICAgICAgICBpbnQgeCA9IDAsIHkgPSAwOwogICAgICAgIGRlbHRhID0gKHJib3guYm90dG9tIC0gcmJveC50b3AgLSBjaGVja0JveEhlaWdodCkgLyAyOwoKCS8qIENoZWNrIGluIGNhc2UgdGhlIGNsaWVudCBhcmVhIGlzIHNtYWxsZXIgdGhhbiB0aGUgY2hlY2tib3ggYml0bWFwICovCglpZiAoZGVsdGEgPCAwKSBkZWx0YSA9IDA7CgogICAgICAgIGlmIChhY3Rpb24gPT0gT0RBX1NFTEVDVCkgRmlsbFJlY3QoIGhEQywgJnJib3gsIGhCcnVzaCApOwogICAgICAgIGVsc2UgRmlsbFJlY3QoIGhEQywgJmNsaWVudCwgaEJydXNoICk7CgogICAgICAgIGlmIChpbmZvUHRyLT5zdGF0ZSAmIEJVVFRPTl9ISUdITElHSFRFRCkgeCArPSAyICogY2hlY2tCb3hXaWR0aDsKICAgICAgICBpZiAoaW5mb1B0ci0+c3RhdGUgJiAoQlVUVE9OX0NIRUNLRUQgfCBCVVRUT05fM1NUQVRFKSkgeCArPSBjaGVja0JveFdpZHRoOwogICAgICAgIGlmICgoKHduZFB0ci0+ZHdTdHlsZSAmIDB4MGYpID09IEJTX1JBRElPQlVUVE9OKSB8fAogICAgICAgICAgICAoKHduZFB0ci0+ZHdTdHlsZSAmIDB4MGYpID09IEJTX0FVVE9SQURJT0JVVFRPTikpIHkgKz0gY2hlY2tCb3hIZWlnaHQ7CiAgICAgICAgZWxzZSBpZiAoaW5mb1B0ci0+c3RhdGUgJiBCVVRUT05fM1NUQVRFKSB5ICs9IDIgKiBjaGVja0JveEhlaWdodDsKCgkvKiBUaGUgYml0bWFwIGZvciB0aGUgcmFkaW8gYnV0dG9uIGlzIG5vdCBhbGlnbmVkIHdpdGggdGhlCgkgKiBsZWZ0IG9mIHRoZSB3aW5kb3csIGl0IGlzIDEgcGl4ZWwgb2ZmLiAqLwogICAgICAgIGlmICgoKHduZFB0ci0+ZHdTdHlsZSAmIDB4MGYpID09IEJTX1JBRElPQlVUVE9OKSB8fAogICAgICAgICAgICAoKHduZFB0ci0+ZHdTdHlsZSAmIDB4MGYpID09IEJTX0FVVE9SQURJT0JVVFRPTikpCgkgIHJib3gubGVmdCArPSAxOwoKCVNlbGVjdE9iamVjdCggaE1lbURDLCBoYml0bWFwQ2hlY2tCb3hlcyApOwoJQml0Qmx0KCBoREMsIHJib3gubGVmdCwgcmJveC50b3AgKyBkZWx0YSwgY2hlY2tCb3hXaWR0aCwKCQkgIGNoZWNrQm94SGVpZ2h0LCBoTWVtREMsIHgsIHksIFNSQ0NPUFkgKTsKCURlbGV0ZURDKCBoTWVtREMgKTsKICAgICAgICB9CiAgICAgICAgZWxzZQogICAgICAgIHsKCSAgICBVSU5UIHN0YXRlOwoKICAgICAgICAgICAgaWYgKCgod25kUHRyLT5kd1N0eWxlICYgMHgwZikgPT0gQlNfUkFESU9CVVRUT04pIHx8CiAgICAgICAgICAgICAgICAoKHduZFB0ci0+ZHdTdHlsZSAmIDB4MGYpID09IEJTX0FVVE9SQURJT0JVVFRPTikpIHN0YXRlID0gREZDU19CVVRUT05SQURJTzsKICAgICAgICAgICAgZWxzZSBpZiAoaW5mb1B0ci0+c3RhdGUgJiBCVVRUT05fM1NUQVRFKSBzdGF0ZSA9IERGQ1NfQlVUVE9OM1NUQVRFOwoJICAgIGVsc2Ugc3RhdGUgPSBERkNTX0JVVFRPTkNIRUNLOwoKICAgICAgICAgICAgaWYgKGluZm9QdHItPnN0YXRlICYgKEJVVFRPTl9DSEVDS0VEIHwgQlVUVE9OXzNTVEFURSkpIHN0YXRlIHw9IERGQ1NfQ0hFQ0tFRDsKCSAgICAKCSAgICBpZiAoaW5mb1B0ci0+c3RhdGUgJiBCVVRUT05fSElHSExJR0hURUQpIHN0YXRlIHw9IERGQ1NfUFVTSEVEOwoKCSAgICBpZiAod25kUHRyLT5kd1N0eWxlICYgV1NfRElTQUJMRUQpIHN0YXRlIHw9IERGQ1NfSU5BQ1RJVkU7CgoJICAgIERyYXdGcmFtZUNvbnRyb2woIGhEQywgJnJib3gsIERGQ19CVVRUT04sIHN0YXRlICk7CiAgICAgICAgfQoKCiAgICAgICAgaWYoIHRleHRsZW4gJiYgYWN0aW9uICE9IE9EQV9TRUxFQ1QgKQogICAgICAgIHsKCSAgaWYgKHduZFB0ci0+ZHdTdHlsZSAmIFdTX0RJU0FCTEVEICYmCgkgICAgICBHZXRTeXNDb2xvcihDT0xPUl9HUkFZVEVYVCk9PUdldEJrQ29sb3IoaERDKSkgewogICAgICAgICAgICAvKiBkb24ndCB3cml0ZSBncmF5IHRleHQgb24gZ3JheSBiYWNrZ3JvdW5kICovCiAgICAgICAgICAgIFBhaW50R3JheU9uR3JheSggaERDLCBpbmZvUHRyLT5oRm9udCwgJnJ0ZXh0LCB3bmRQdHItPnRleHQsCgkJCSAgICAgRFRfVkNFTlRFUik7CgkgIH0gZWxzZSB7CiAgICAgICAgICAgIGlmICh3bmRQdHItPmR3U3R5bGUgJiBXU19ESVNBQkxFRCkKICAgICAgICAgICAgICAgIFNldFRleHRDb2xvciggaERDLCBHZXRTeXNDb2xvcihDT0xPUl9HUkFZVEVYVCkgKTsKICAgICAgICAgICAgRHJhd1RleHRBKCBoREMsIHduZFB0ci0+dGV4dCwgdGV4dGxlbiwgJnJ0ZXh0LAoJCQkgRFRfU0lOR0xFTElORSB8IERUX1ZDRU5URVIgKTsKCSAgfQogICAgICAgIH0KICAgIH0KCiAgICBpZiAoKGFjdGlvbiA9PSBPREFfRk9DVVMpIHx8CiAgICAgICAgKChhY3Rpb24gPT0gT0RBX0RSQVdFTlRJUkUpICYmIChpbmZvUHRyLT5zdGF0ZSAmIEJVVFRPTl9IQVNGT0NVUykpKQogICAgewoJLyogYWdhaW4sIHRoaXMgaXMgd2hhdCBDVEwzRCBleHBlY3RzICovCgogICAgICAgIFNldFJlY3RFbXB0eSgmcmJveCk7CiAgICAgICAgaWYoIHRleHRsZW4gKQogICAgICAgICAgICBEcmF3VGV4dEEoIGhEQywgd25kUHRyLT50ZXh0LCB0ZXh0bGVuLCAmcmJveCwKCQkJIERUX1NJTkdMRUxJTkUgfCBEVF9DQUxDUkVDVCApOwogICAgICAgIHRleHRsZW4gPSByYm94LmJvdHRvbSAtIHJib3gudG9wOwogICAgICAgIGRlbHRhID0gKChydGV4dC5ib3R0b20gLSBydGV4dC50b3ApIC0gdGV4dGxlbikvMjsKICAgICAgICByYm94LmJvdHRvbSA9IChyYm94LnRvcCA9IHJ0ZXh0LnRvcCArIGRlbHRhIC0gMSkgKyB0ZXh0bGVuICsgMjsKICAgICAgICB0ZXh0bGVuID0gcmJveC5yaWdodCAtIHJib3gubGVmdDsKICAgICAgICByYm94LnJpZ2h0ID0gKHJib3gubGVmdCArPSAtLXJ0ZXh0LmxlZnQpICsgdGV4dGxlbiArIDI7CiAgICAgICAgSW50ZXJzZWN0UmVjdCgmcmJveCwgJnJib3gsICZydGV4dCk7CiAgICAgICAgRHJhd0ZvY3VzUmVjdCggaERDLCAmcmJveCApOwogICAgfQp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICAgQlVUVE9OX0NoZWNrQXV0b1JhZGlvQnV0dG9uCiAqCiAqIHduZFB0ciBpcyBjaGVja2VkLCB1bmNoZWNrIGV2ZXJ5IG90aGVyIGF1dG8gcmFkaW8gYnV0dG9uIGluIGdyb3VwCiAqLwpzdGF0aWMgdm9pZCBCVVRUT05fQ2hlY2tBdXRvUmFkaW9CdXR0b24oIFdORCAqd25kUHRyICkKewogICAgSFdORCBwYXJlbnQsIHNpYmxpbmcsIHN0YXJ0OwogICAgaWYgKCEod25kUHRyLT5kd1N0eWxlICYgV1NfQ0hJTEQpKSByZXR1cm47CiAgICBwYXJlbnQgPSB3bmRQdHItPnBhcmVudC0+aHduZFNlbGY7CiAgICAvKiBhc3N1cmUgdGhhdCBzdGFydGluZyBjb250cm9sIGlzIG5vdCBkaXNhYmxlZCBvciBpbnZpc2libGUgKi8KICAgIHN0YXJ0ID0gc2libGluZyA9IEdldE5leHREbGdHcm91cEl0ZW0oIHBhcmVudCwgd25kUHRyLT5od25kU2VsZiwgVFJVRSApOwogICAgZG8KICAgIHsKICAgICAgICBXTkQgKnRtcFduZDsKICAgICAgICBpZiAoIXNpYmxpbmcpIGJyZWFrOwogICAgICAgIHRtcFduZCA9IFdJTl9GaW5kV25kUHRyKHNpYmxpbmcpOwogICAgICAgIGlmICgod25kUHRyLT5od25kU2VsZiAhPSBzaWJsaW5nKSAmJgogICAgICAgICAgICAoKHRtcFduZC0+ZHdTdHlsZSAmIDB4MGYpID09IEJTX0FVVE9SQURJT0JVVFRPTikpCiAgICAgICAgICAgIFNlbmRNZXNzYWdlQSggc2libGluZywgQk1fU0VUQ0hFQ0ssIEJVVFRPTl9VTkNIRUNLRUQsIDAgKTsKICAgICAgICBzaWJsaW5nID0gR2V0TmV4dERsZ0dyb3VwSXRlbSggcGFyZW50LCBzaWJsaW5nLCBGQUxTRSApOwogICAgICAgIFdJTl9SZWxlYXNlV25kUHRyKHRtcFduZCk7CiAgICB9IHdoaWxlIChzaWJsaW5nICE9IHN0YXJ0KTsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgIEdyb3VwIEJveCBGdW5jdGlvbnMKICovCgpzdGF0aWMgdm9pZCBHQl9QYWludCggV05EICp3bmRQdHIsIEhEQyBoREMsIFdPUkQgYWN0aW9uICkKewogICAgUkVDVCByYywgcmNGcmFtZTsKICAgIEJVVFRPTklORk8gKmluZm9QdHIgPSAoQlVUVE9OSU5GTyAqKXduZFB0ci0+d0V4dHJhOwoKICAgIGlmIChhY3Rpb24gIT0gT0RBX0RSQVdFTlRJUkUpIHJldHVybjsKCiAgICBCVVRUT05fU0VORF9DVExDT0xPUiggd25kUHRyLCBoREMgKTsKCiAgICBHZXRDbGllbnRSZWN0KCB3bmRQdHItPmh3bmRTZWxmLCAmcmMpOwogICAgaWYgKFRXRUFLX1dpbmVMb29rID09IFdJTjMxX0xPT0spIHsKICAgICAgICBIUEVOIGhQcmV2UGVuID0gU2VsZWN0T2JqZWN0KCBoREMsCgkJCQkJICBHZXRTeXNDb2xvclBlbihDT0xPUl9XSU5ET1dGUkFNRSkpOwoJSEJSVVNIIGhQcmV2QnJ1c2ggPSBTZWxlY3RPYmplY3QoIGhEQywKCQkJCQkgICAgICBHZXRTdG9ja09iamVjdChOVUxMX0JSVVNIKSApOwoKCVJlY3RhbmdsZSggaERDLCByYy5sZWZ0LCByYy50b3AgKyAyLCByYy5yaWdodCAtIDEsIHJjLmJvdHRvbSAtIDEgKTsKCVNlbGVjdE9iamVjdCggaERDLCBoUHJldkJydXNoICk7CglTZWxlY3RPYmplY3QoIGhEQywgaFByZXZQZW4gKTsKICAgIH0gZWxzZSB7CglURVhUTUVUUklDQSB0bTsKCXJjRnJhbWUgPSByYzsKCglpZiAoaW5mb1B0ci0+aEZvbnQpCgkgICAgU2VsZWN0T2JqZWN0IChoREMsIGluZm9QdHItPmhGb250KTsKCUdldFRleHRNZXRyaWNzQSAoaERDLCAmdG0pOwoJcmNGcmFtZS50b3AgKz0gKHRtLnRtSGVpZ2h0IC8gMikgLSAxOwoJRHJhd0VkZ2UgKGhEQywgJnJjRnJhbWUsIEVER0VfRVRDSEVELCBCRl9SRUNUKTsKICAgIH0KCiAgICBpZiAod25kUHRyLT50ZXh0KQogICAgewoJaWYgKGluZm9QdHItPmhGb250KSBTZWxlY3RPYmplY3QoIGhEQywgaW5mb1B0ci0+aEZvbnQgKTsKICAgICAgICBpZiAod25kUHRyLT5kd1N0eWxlICYgV1NfRElTQUJMRUQpCiAgICAgICAgICAgIFNldFRleHRDb2xvciggaERDLCBHZXRTeXNDb2xvcihDT0xPUl9HUkFZVEVYVCkgKTsKICAgICAgICByYy5sZWZ0ICs9IDEwOwogICAgICAgIERyYXdUZXh0QSggaERDLCB3bmRQdHItPnRleHQsIC0xLCAmcmMsIERUX1NJTkdMRUxJTkUgfCBEVF9OT0NMSVAgKTsKICAgIH0KfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgIFVzZXIgQnV0dG9uIEZ1bmN0aW9ucwogKi8KCnN0YXRpYyB2b2lkIFVCX1BhaW50KCBXTkQgKnduZFB0ciwgSERDIGhEQywgV09SRCBhY3Rpb24gKQp7CiAgICBSRUNUIHJjOwogICAgSEJSVVNIIGhCcnVzaDsKICAgIEJVVFRPTklORk8gKmluZm9QdHIgPSAoQlVUVE9OSU5GTyAqKXduZFB0ci0+d0V4dHJhOwoKICAgIGlmIChhY3Rpb24gPT0gT0RBX1NFTEVDVCkgcmV0dXJuOwoKICAgIEdldENsaWVudFJlY3QoIHduZFB0ci0+aHduZFNlbGYsICZyYyk7CgogICAgaWYgKGluZm9QdHItPmhGb250KSBTZWxlY3RPYmplY3QoIGhEQywgaW5mb1B0ci0+aEZvbnQgKTsKICAgIGhCcnVzaCA9IEdldENvbnRyb2xCcnVzaDE2KCB3bmRQdHItPmh3bmRTZWxmLCBoREMsIENUTENPTE9SX0JUTiApOwoKICAgIEZpbGxSZWN0KCBoREMsICZyYywgaEJydXNoICk7CiAgICBpZiAoKGFjdGlvbiA9PSBPREFfRk9DVVMpIHx8CiAgICAgICAgKChhY3Rpb24gPT0gT0RBX0RSQVdFTlRJUkUpICYmIChpbmZvUHRyLT5zdGF0ZSAmIEJVVFRPTl9IQVNGT0NVUykpKQogICAgICAgIERyYXdGb2N1c1JlY3QoIGhEQywgJnJjICk7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgICBPd25lcmRyYXduIEJ1dHRvbiBGdW5jdGlvbnMKICovCgpzdGF0aWMgdm9pZCBPQl9QYWludCggV05EICp3bmRQdHIsIEhEQyBoREMsIFdPUkQgYWN0aW9uICkKewogICAgQlVUVE9OSU5GTyAqaW5mb1B0ciA9IChCVVRUT05JTkZPICopd25kUHRyLT53RXh0cmE7CiAgICBEUkFXSVRFTVNUUlVDVCBkaXM7CgogICAgZGlzLkN0bFR5cGUgICAgPSBPRFRfQlVUVE9OOwogICAgZGlzLkN0bElEICAgICAgPSB3bmRQdHItPndJRG1lbnU7CiAgICBkaXMuaXRlbUlEICAgICA9IDA7CiAgICBkaXMuaXRlbUFjdGlvbiA9IGFjdGlvbjsKICAgIGRpcy5pdGVtU3RhdGUgID0gKChpbmZvUHRyLT5zdGF0ZSAmIEJVVFRPTl9IQVNGT0NVUykgPyBPRFNfRk9DVVMgOiAwKSB8CiAgICAgICAgICAgICAgICAgICAgICgoaW5mb1B0ci0+c3RhdGUgJiBCVVRUT05fSElHSExJR0hURUQpID8gT0RTX1NFTEVDVEVEIDogMCkgfAogICAgICAgICAgICAgICAgICAgICAoKHduZFB0ci0+ZHdTdHlsZSAmIFdTX0RJU0FCTEVEKSA/IE9EU19ESVNBQkxFRCA6IDApOwogICAgZGlzLmh3bmRJdGVtICAgPSB3bmRQdHItPmh3bmRTZWxmOwogICAgZGlzLmhEQyAgICAgICAgPSBoREM7CiAgICBkaXMuaXRlbURhdGEgICA9IDA7CiAgICBHZXRDbGllbnRSZWN0KCB3bmRQdHItPmh3bmRTZWxmLCAmZGlzLnJjSXRlbSApOwoKICAgIFNldEJrQ29sb3IoIGhEQywgR2V0U3lzQ29sb3IoIENPTE9SX0JUTkZBQ0UgKSApOwoKICAgIFNlbmRNZXNzYWdlQSggR2V0UGFyZW50KHduZFB0ci0+aHduZFNlbGYpLCBXTV9EUkFXSVRFTSwKICAgICAgICAgICAgICAgICAgICB3bmRQdHItPndJRG1lbnUsIChMUEFSQU0pJmRpcyApOwp9Cgo=