LyoqCiAqIAogKiBGaWxlIE5hbWU6ICBhcm1WQ000UDJfQmxvY2tNYXRjaF9JbnRlZ2VyLmMKICogT3Blbk1BWCBETDogdjEuMC4yCiAqIFJldmlzaW9uOiAgIDk2NDEKICogRGF0ZTogICAgICAgVGh1cnNkYXksIEZlYnJ1YXJ5IDcsIDIwMDgKICogCiAqIChjKSBDb3B5cmlnaHQgMjAwNy0yMDA4IEFSTSBMaW1pdGVkLiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiAKICogCiAqCiAqIERlc2NyaXB0aW9uOgogKiBDb250YWlucyBtb2R1bGVzIGZvciBCbG9jayBtYXRjaGluZywgYSBmdWxsIHNlYXJjaCBhbGdvcml0aG0KICogaXMgaW1wbGVtZW50ZWQKICogCiAqLwogCiNpbmNsdWRlICJvbXh0eXBlcy5oIgojaW5jbHVkZSAiYXJtT01YLmgiCiNpbmNsdWRlICJvbXhWQy5oIgoKI2luY2x1ZGUgImFybVZDLmgiCiNpbmNsdWRlICJhcm1DT01NLmgiCgovKioKICogRnVuY3Rpb246IGFybVZDTTRQMl9CbG9ja01hdGNoX0ludGVnZXIKICoKICogRGVzY3JpcHRpb246CiAqIFBlcmZvcm1zIGEgMTZ4MTYgYmxvY2sgc2VhcmNoOyBlc3RpbWF0ZXMgbW90aW9uIHZlY3RvciBhbmQgYXNzb2NpYXRlZCBtaW5pbXVtIFNBRC4gIAogKiBCb3RoIHRoZSBpbnB1dCBhbmQgb3V0cHV0IG1vdGlvbiB2ZWN0b3JzIGFyZSByZXByZXNlbnRlZCB1c2luZyBoYWxmLXBpeGVsIHVuaXRzLCBhbmQgCiAqIHRoZXJlZm9yZSBhIHNoaWZ0IGxlZnQgb3IgcmlnaHQgYnkgMSBiaXQgbWF5IGJlIHJlcXVpcmVkLCByZXNwZWN0aXZlbHksIHRvIG1hdGNoIHRoZSAKICogaW5wdXQgb3Igb3V0cHV0IE1WcyB3aXRoIG90aGVyIGZ1bmN0aW9ucyB0aGF0IGVpdGhlciBnZW5lcmF0ZSBvdXRwdXQgTVZzIG9yIGV4cGVjdCAKICogaW5wdXQgTVZzIHJlcHJlc2VudGVkIHVzaW5nIGludGVnZXIgcGl4ZWwgdW5pdHMuIAogKgogKiBSZW1hcmtzOgogKgogKiBQYXJhbWV0ZXJzOgogKiBbaW5dCXBTcmNSZWZCdWYJCXBvaW50ZXIgdG8gdGhlIHJlZmVyZW5jZSBZIHBsYW5lOyBwb2ludHMgdG8gdGhlIHJlZmVyZW5jZSBNQiB0aGF0IAogKiAgICAgICAgICAgICAgICAgICAgY29ycmVzcG9uZHMgdG8gdGhlIGxvY2F0aW9uIG9mIHRoZSBjdXJyZW50IG1hY3JvYmxvY2sgaW4gdGhlIGN1cnJlbnQgCiAqICAgICAgICAgICAgICAgICAgICBwbGFuZS4KICogW2luXQlyZWZXaWR0aAkJICB3aWR0aCBvZiB0aGUgcmVmZXJlbmNlIHBsYW5lCiAqIFtpbl0JcFJlZlJlY3QJCSAgcG9pbnRlciB0byB0aGUgdmFsaWQgcmVjdGFuZ3VsYXIgaW4gcmVmZXJlbmNlIHBsYW5lLiBSZWxhdGl2ZSB0byBpbWFnZSBvcmlnaW4uIAogKiAgICAgICAgICAgICAgICAgICAgSXQncyBub3QgbGltaXRlZCB0byB0aGUgaW1hZ2UgYm91bmRhcnksIGJ1dCBkZXBlbmRlZCBvbiB0aGUgcGFkZGluZy4gRm9yIGV4YW1wbGUsIAogKiAgICAgICAgICAgICAgICAgICAgaWYgeW91IHBhZCA0IHBpeGVscyBvdXRzaWRlIHRoZSBpbWFnZSBib3JkZXIsIHRoZW4gdGhlIHZhbHVlIGZvciBsZWZ0IGJvcmRlciAKICogICAgICAgICAgICAgICAgICAgIGNhbiBiZSAtNAogKiBbaW5dCXBTcmNDdXJyQnVmCQlwb2ludGVyIHRvIHRoZSBjdXJyZW50IG1hY3JvYmxvY2sgZXh0cmFjdGVkIGZyb20gb3JpZ2luYWwgcGxhbmUgKGxpbmVhciBhcnJheSwgCiAqICAgICAgICAgICAgICAgICAgICAyNTYgZW50cmllcyk7IG11c3QgYmUgYWxpZ25lZCBvbiBhbiA4LWJ5dGUgYm91bmRhcnkuCiAqIFtpbl0gcEN1cnJQb2ludFBvcwlwb3NpdGlvbiBvZiB0aGUgY3VycmVudCBtYWNyb2Jsb2NrIGluIHRoZSBjdXJyZW50IHBsYW5lCiAqIFtpbl0gcFNyY1ByZU1WCQkgIHBvaW50ZXIgdG8gcHJlZGljdGVkIG1vdGlvbiB2ZWN0b3I7IE5VTEwgaW5kaWNhdGVzIG5vIHByZWRpY3RlZCBNVgogKiBbaW5dIHBTcmNQcmVTQUQJCXBvaW50ZXIgdG8gU0FEIGFzc29jaWF0ZWQgd2l0aCB0aGUgcHJlZGljdGVkIE1WIChyZWZlcmVuY2VkIGJ5IHBTcmNQcmVNVikKICogW2luXSBzZWFyY2hSYW5nZQkJc2VhcmNoIHJhbmdlIGZvciAxNlgxNiBpbnRlZ2VyIGJsb2NrLHRoZSB1bml0cyBvZiBpdCBpcyBmdWxsIHBpeGVsLHRoZSBzZWFyY2ggcmFuZ2UgCiAqICAgICAgICAgICAgICAgICAgICBpcyB0aGUgc2FtZSBpbiBhbGwgZGlyZWN0aW9ucy5JdCBpcyBpbiBpbmNsdXNpdmUgb2YgdGhlIGJvdW5kYXJ5IGFuZCBzcGVjaWZpZWQgaW4gCiAqICAgICAgICAgICAgICAgICAgICB0ZXJtcyBvZiBpbnRlZ2VyIHBpeGVsIHVuaXRzLgogKiBbaW5dIHBNRVNwZWMJCQkgIHZlbmRvci1zcGVjaWZpYyBtb3Rpb24gZXN0aW1hdGlvbiBzcGVjaWZpY2F0aW9uIHN0cnVjdHVyZTsgbXVzdCBoYXZlIGJlZW4gYWxsb2NhdGVkIAogKiAgICAgICAgICAgICAgICAgICAgYW5kIHRoZW4gaW5pdGlhbGl6ZWQgdXNpbmcgb214VkNNNFAyX01FSW5pdCBwcmlvciB0byBjYWxsaW5nIHRoZSBibG9jayBtYXRjaGluZyAKICogICAgICAgICAgICAgICAgICAgIGZ1bmN0aW9uLgogKiBbb3V0XQlwRHN0TVYJCQlwb2ludGVyIHRvIGVzdGltYXRlZCBNVgogKiBbb3V0XQlwRHN0U0FECQkJcG9pbnRlciB0byBtaW5pbXVtIFNBRAogKgogKiBSZXR1cm4gVmFsdWU6CiAqIE9NWF9TdHNfTm9FcnIgqEMgbm8gZXJyb3IuCiAqIE9NWF9TdHNfQmFkQXJnRXJyIKhDIGJhZCBhcmd1bWVudHMKICoKICovCgpPTVhSZXN1bHQgYXJtVkNNNFAyX0Jsb2NrTWF0Y2hfSW50ZWdlcigKICAgICBjb25zdCBPTVhfVTggKnBTcmNSZWZCdWYsCiAgICAgT01YX0lOVCByZWZXaWR0aCwKICAgICBjb25zdCBPTVhSZWN0ICpwUmVmUmVjdCwKICAgICBjb25zdCBPTVhfVTggKnBTcmNDdXJyQnVmLAogICAgIGNvbnN0IE9NWFZDTTRQMkNvb3JkaW5hdGUgKnBDdXJyUG9pbnRQb3MsCiAgICAgY29uc3QgT01YVkNNb3Rpb25WZWN0b3IgKnBTcmNQcmVNViwKICAgICBjb25zdCBPTVhfSU5UICpwU3JjUHJlU0FELAogICAgIHZvaWQgKnBNRVNwZWMsCiAgICAgT01YVkNNb3Rpb25WZWN0b3IgKnBEc3RNViwKICAgICBPTVhfSU5UICpwRHN0U0FELAogICAgIE9NWF9VOCBCbG9ja1NpemUKKQp7CgogICAgLyogRGVmaW5pdGlvbnMgYW5kIEluaXRpYWxpemF0aW9ucyovCgogICAgT01YX0lOVCAgICAgb3V0ZXIsIGlubmVyLCBjb3VudCxpbmRleDsKICAgIE9NWF9JTlQgICAgIGNhbmRTQUQ7CiAgICAvKigyNTYqMjU2ICsxKSB0aGlzIGlzIHRvIG1ha2UgdGhlIFNBRCBtYXggaW5pdGlhbGx5Ki8KICAgIE9NWF9JTlQgICAgIG1pblNBRCA9IDB4MTAwMDEsIGZyb21YLCB0b1gsIGZyb21ZLCB0b1k7CiAgICAvKiBPZmZzZXQgdG8gdGhlIHJlZmVyZW5jZSBhdCB0aGUgYmVnaW5pbmcgb2YgdGhlIGJvdW5kaW5nIGJveCAqLwogICAgY29uc3QgT01YX1U4ICAgICAgKnBUZW1wU3JjUmVmQnVmOwogICAgT01YX1MxNiAgICAgeCwgeTsKICAgIE9NWF9JTlQgc2VhcmNoUmFuZ2U7CiAgIAogICAgLyogQXJndW1lbnQgZXJyb3IgY2hlY2tzICovCiAgICBhcm1SZXRBcmdFcnJJZihwU3JjUmVmQnVmID09IE5VTEwsIE9NWF9TdHNfQmFkQXJnRXJyKTsKICAgIGFybVJldEFyZ0VycklmKHBSZWZSZWN0ID09IE5VTEwsIE9NWF9TdHNfQmFkQXJnRXJyKTsKICAgIGFybVJldEFyZ0VycklmKHBTcmNDdXJyQnVmID09IE5VTEwsIE9NWF9TdHNfQmFkQXJnRXJyKTsKICAgIGFybVJldEFyZ0VycklmKHBDdXJyUG9pbnRQb3MgPT0gTlVMTCwgT01YX1N0c19CYWRBcmdFcnIpOwogICAgYXJtUmV0QXJnRXJySWYocE1FU3BlYyA9PSBOVUxMLCBPTVhfU3RzX0JhZEFyZ0Vycik7CiAgICBhcm1SZXRBcmdFcnJJZihwRHN0TVYgPT0gTlVMTCwgT01YX1N0c19CYWRBcmdFcnIpOwogICAgYXJtUmV0QXJnRXJySWYocERzdFNBRCA9PSBOVUxMLCBPTVhfU3RzX0JhZEFyZ0Vycik7CiAgICAgICAgCiAgICBzZWFyY2hSYW5nZSA9ICgoT01YVkNNNFAyTUVQYXJhbXMgKilwTUVTcGVjKS0+c2VhcmNoUmFuZ2U7CiAgICAvKiBDaGVjayBmb3IgdmFsaWQgcmVnaW9uICovCiAgICBmcm9tWCA9IHNlYXJjaFJhbmdlOwogICAgdG9YICAgPSBzZWFyY2hSYW5nZTsKICAgIGZyb21ZID0gc2VhcmNoUmFuZ2U7CiAgICB0b1kgICA9IHNlYXJjaFJhbmdlOwoKICAgIGlmICgocEN1cnJQb2ludFBvcy0+eCAtIHNlYXJjaFJhbmdlKSA8IHBSZWZSZWN0LT54KQogICAgewogICAgICAgIGZyb21YID0gIHBDdXJyUG9pbnRQb3MtPnggLSBwUmVmUmVjdC0+eDsKICAgIH0KCiAgICBpZiAoKHBDdXJyUG9pbnRQb3MtPnggKyBCbG9ja1NpemUgKyBzZWFyY2hSYW5nZSkgPiAocFJlZlJlY3QtPnggKyBwUmVmUmVjdC0+d2lkdGgpKQogICAgewogICAgICAgIHRvWCAgID0gcFJlZlJlY3QtPndpZHRoIC0gKHBDdXJyUG9pbnRQb3MtPnggLSBwUmVmUmVjdC0+eCkgLSBCbG9ja1NpemU7CiAgICB9CgogICAgaWYgKChwQ3VyclBvaW50UG9zLT55IC0gc2VhcmNoUmFuZ2UpIDwgcFJlZlJlY3QtPnkpCiAgICB7CiAgICAgICAgZnJvbVkgPSBwQ3VyclBvaW50UG9zLT55IC0gcFJlZlJlY3QtPnk7CiAgICB9CgogICAgaWYgKChwQ3VyclBvaW50UG9zLT55ICsgQmxvY2tTaXplICsgc2VhcmNoUmFuZ2UpID4gKHBSZWZSZWN0LT55ICsgcFJlZlJlY3QtPmhlaWdodCkpCiAgICB7CiAgICAgICAgdG9ZICAgPSBwUmVmUmVjdC0+d2lkdGggLSAocEN1cnJQb2ludFBvcy0+eSAtIHBSZWZSZWN0LT55KSAtIEJsb2NrU2l6ZTsKICAgIH0KCiAgICBwRHN0TVYtPmR4ID0gLWZyb21YOwogICAgcERzdE1WLT5keSA9IC1mcm9tWTsKICAgIC8qIExvb3Bpbmcgb24geS0gYXhpcyAqLwogICAgZm9yICh5ID0gLWZyb21ZOyB5IDw9IHRvWTsgeSsrKQogICAgewoKICAgICAgICAvKiBMb29waW5nIG9uIHgtIGF4aXMgKi8KICAgICAgICBmb3IgKHggPSAtZnJvbVg7IHggPD0gdG9YOyB4KyspCiAgICAgICAgewogICAgICAgICAgICAvKiBQb3NpdGlvbmluZyB0aGUgcG9pbnRlciAqLwogICAgICAgICAgICBwVGVtcFNyY1JlZkJ1ZiA9IHBTcmNSZWZCdWYgKyAocmVmV2lkdGggKiB5KSArIHg7CgogICAgICAgICAgICAvKiBDYWxjdWxhdGUgdGhlIFNBRCAqLwogICAgICAgICAgICBmb3IgKG91dGVyID0gMCwgY291bnQgPSAwLCBpbmRleCA9IDAsIGNhbmRTQUQgPSAwOwogICAgICAgICAgICAgICAgIG91dGVyIDwgQmxvY2tTaXplOwogICAgICAgICAgICAgICAgIG91dGVyKyssIGluZGV4ICs9IHJlZldpZHRoIC0gQmxvY2tTaXplKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBmb3IgKGlubmVyID0gMDsgaW5uZXIgPCBCbG9ja1NpemU7IGlubmVyKyssIGNvdW50KyssIGluZGV4KyspCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgY2FuZFNBRCArPSBhcm1BYnMgKHBUZW1wU3JjUmVmQnVmW2luZGV4XSAtIHBTcmNDdXJyQnVmW2NvdW50XSk7ICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQoKICAgICAgICAgICAgLyogUmVzdWx0IGNhbGN1bGF0aW9ucyAqLwogICAgICAgICAgICBpZiAoYXJtVkNNNFAyX0NvbXBhcmVNViAoeCwgeSwgY2FuZFNBRCwgcERzdE1WLT5keC8yLCBwRHN0TVYtPmR5LzIsIG1pblNBRCkpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICpwRHN0U0FEID0gY2FuZFNBRDsKICAgICAgICAgICAgICAgIG1pblNBRCAgID0gY2FuZFNBRDsKICAgICAgICAgICAgICAgIHBEc3RNVi0+ZHggPSB4KjI7CiAgICAgICAgICAgICAgICBwRHN0TVYtPmR5ID0geSoyOwogICAgICAgICAgICB9CgogICAgICAgIH0gLyogRW5kIG9mIHgtIGF4aXMgKi8KICAgIH0gLyogRW5kIG9mIHktYXhpcyAqLwoKICAgIHJldHVybiBPTVhfU3RzX05vRXJyOwoKfQoKLyogRW5kIG9mIGZpbGUgKi8K