LyoKICoJaGFuZGxpbmcgb2YgU0hFTEwzMi5ETEwgT0xFLU9iamVjdHMKICoKICoJQ29weXJpZ2h0IDE5OTcJTWFyY3VzIE1laXNzbmVyCiAqCUNvcHlyaWdodCAxOTk4CUp1ZXJnZW4gU2NobWllZCAgPGp1ZXJnZW4uc2NobWllZEBtZXRyb25ldC5kZT4KICoKICovCgojaW5jbHVkZSA8c3RkbGliLmg+CiNpbmNsdWRlIDxzdHJpbmcuaD4KCiNpbmNsdWRlICJ3aW5lL29ial9iYXNlLmgiCiNpbmNsdWRlICJ3aW5lL29ial9zaGVsbGxpbmsuaCIKI2luY2x1ZGUgIndpbmUvb2JqX3NoZWxsZm9sZGVyLmgiCiNpbmNsdWRlICJ3aW5lL29ial9zaGVsbGJyb3dzZXIuaCIKI2luY2x1ZGUgIndpbmUvb2JqX2NvbnRleHRtZW51LmgiCiNpbmNsdWRlICJ3aW5lL29ial9zaGVsbGV4dGluaXQuaCIKI2luY2x1ZGUgIndpbmUvb2JqX2V4dHJhY3RpY29uLmgiCgojaW5jbHVkZSAic2hsZ3VpZC5oIgojaW5jbHVkZSAid2ludmVyc2lvbi5oIgojaW5jbHVkZSAid2lucmVnLmgiCiNpbmNsdWRlICJ3aW5lcnJvci5oIgojaW5jbHVkZSAiZGVidWd0b29scy5oIgoKI2luY2x1ZGUgInNoZWxsMzJfbWFpbi5oIgoKREVGQVVMVF9ERUJVR19DSEFOTkVMKHNoZWxsKQoKRFdPUkQgV0lOQVBJIFNIQ0xTSURGcm9tU3RyaW5nQSAoTFBTVFIgY2xzaWQsIENMU0lEICppZCk7CmV4dGVybiBJU2hlbGxGb2xkZXIgKiBJU2hlbGxGb2xkZXJfQ29uc3RydWN0b3IoCglJU2hlbGxGb2xkZXIgKiBwc2YsCglMUElURU1JRExJU1QgcGlkbCk7CmV4dGVybiBIUkVTVUxUIElGU0ZvbGRlcl9Db25zdHJ1Y3RvcigKCUlVbmtub3duICogcFVua091dGVyLAoJUkVGSUlEIHJpaWQsCglMUFZPSUQgKiBwcHYpOwoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogU0hDb0NyZWF0ZUluc3RhbmNlIFtTSEVMTDMyLjEwMl0KICogCiAqIE5PVEVTCiAqICAgICBleHBvcnRlZCBieSBvcmRpbmFsCiAqLwpMUkVTVUxUIFdJTkFQSSBTSENvQ3JlYXRlSW5zdGFuY2UoCglMUFNUUiBhY2xzaWQsCglSRUZDTFNJRCBjbHNpZCwKCUlVbmtub3duICogdW5rbm93bm91dGVyLAoJUkVGSUlEIHJlZmlpZCwKCUxQVk9JRCAqcHB2KQp7CglEV09SRAlocmVzOwoJSUlECWlpZDsKCUNMU0lEICogbXljbHNpZCA9IChDTFNJRCopY2xzaWQ7CgkKCWlmICghY2xzaWQpCgl7CgkgIGlmICghYWNsc2lkKSByZXR1cm4gUkVHREJfRV9DTEFTU05PVFJFRzsKCSAgU0hDTFNJREZyb21TdHJpbmdBKGFjbHNpZCwgJmlpZCk7CgkgIG15Y2xzaWQgPSAmaWlkOwoJfQoKCVRSQUNFKCIoJXAsXG5cdENMU0lEOlx0JXMsIHVuazolcFxuXHRJSUQ6XHQlcywlcClcbiIsCgkJYWNsc2lkLGRlYnVnc3RyX2d1aWQobXljbHNpZCksdW5rbm93bm91dGVyLGRlYnVnc3RyX2d1aWQocmVmaWlkKSxwcHYpOwoKCWlmIElzRXF1YWxDTFNJRChteWNsc2lkLCAmQ0xTSURfU2hlbGxGU0ZvbGRlcikKCXsKCSAgaHJlcyA9IElGU0ZvbGRlcl9Db25zdHJ1Y3Rvcih1bmtub3dub3V0ZXIsIHJlZmlpZCwgcHB2KTsKCX0KCWVsc2UKCXsKCSAgaHJlcyA9IENvQ3JlYXRlSW5zdGFuY2UobXljbHNpZCwgdW5rbm93bm91dGVyLCBDTFNDVFhfSU5QUk9DX1NFUlZFUiwgcmVmaWlkLCBwcHYpOwoJfQoJCglpZihocmVzIT1TX09LKQoJewoJICBFUlIoImZhaWxlZCAoMHglMDhseCkgdG8gY3JlYXRlIFxuXHRDTFNJRDpcdCVzXG5cdElJRDpcdCVzXG4iLAogICAgICAgICAgICAgIGhyZXMsIGRlYnVnc3RyX2d1aWQobXljbHNpZCksIGRlYnVnc3RyX2d1aWQocmVmaWlkKSk7CgkgIEVSUigiY2xhc3Mgbm90IGZvdW5kIGluIHJlZ2lzdHJ5XG4iKTsKCX0KCglUUkFDRSgiLS0gaW5zdGFuY2U6ICVwXG4iLCpwcHYpOwoJcmV0dXJuIGhyZXM7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFNIRUxMMzJfRGxsR2V0Q2xhc3NPYmplY3QgICBbU0hFTEwzMi4xMjhdCiAqLwpIUkVTVUxUIFdJTkFQSSBTSEVMTDMyX0RsbEdldENsYXNzT2JqZWN0KFJFRkNMU0lEIHJjbHNpZCwgUkVGSUlEIGlpZCxMUFZPSUQgKnBwdikKewlIUkVTVUxUCWhyZXMgPSBFX09VVE9GTUVNT1JZOwoJTFBDTEFTU0ZBQ1RPUlkgbHBjbGY7CgoJVFJBQ0UoIlxuXHRDTFNJRDpcdCVzLFxuXHRJSUQ6XHQlc1xuIixkZWJ1Z3N0cl9ndWlkKHJjbHNpZCksZGVidWdzdHJfZ3VpZChpaWQpKTsKCQoJKnBwdiA9IE5VTEw7CgoJaWYoSXNFcXVhbENMU0lEKHJjbHNpZCwgJkNMU0lEX1NoZWxsRGVza3RvcCl8fCAKCSAgIElzRXF1YWxDTFNJRChyY2xzaWQsICZDTFNJRF9TaGVsbExpbmspKQoJewoJICBscGNsZiA9IElDbGFzc0ZhY3RvcnlfQ29uc3RydWN0b3IoIHJjbHNpZCApOwoKCSAgaWYobHBjbGYpIAoJICB7CgkgICAgaHJlcyA9IElDbGFzc0ZhY3RvcnlfUXVlcnlJbnRlcmZhY2UobHBjbGYsaWlkLCBwcHYpOwoJICAgIElDbGFzc0ZhY3RvcnlfUmVsZWFzZShscGNsZik7CgkgIH0KCX0KCWVsc2UKCXsKCSAgV0FSTigiLS0gQ0xTSUQgbm90IGZvdW5kXG4iKTsKCSAgaHJlcyA9IENMQVNTX0VfQ0xBU1NOT1RBVkFJTEFCTEU7Cgl9CglUUkFDRSgiLS0gcG9pbnRlciB0byBjbGFzcyBmYWN0b3J5OiAlcFxuIiwqcHB2KTsKCXJldHVybiBocmVzOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBTSENMU0lERnJvbVN0cmluZwkJCQlbU0hFTEwzMi4xNDddCiAqCiAqIE5PVEVTCiAqICAgICBleHBvcnRlZCBieSBvcmRpbmFsCiAqLwpEV09SRCBXSU5BUEkgU0hDTFNJREZyb21TdHJpbmdBIChMUFNUUiBjbHNpZCwgQ0xTSUQgKmlkKQp7CglUUkFDRSgiKCVwKCVzKSAlcClcbiIsIGNsc2lkLCBjbHNpZCwgaWQpOwoJcmV0dXJuIENMU0lERnJvbVN0cmluZzE2KGNsc2lkLCBpZCk7IAp9CkRXT1JEIFdJTkFQSSBTSENMU0lERnJvbVN0cmluZ1cgKExQV1NUUiBjbHNpZCwgQ0xTSUQgKmlkKQp7CglUUkFDRSgiKCVwKCVzKSAlcClcbiIsIGNsc2lkLCBkZWJ1Z3N0cl93KGNsc2lkKSwgaWQpOwoJcmV0dXJuIENMU0lERnJvbVN0cmluZyhjbHNpZCwgaWQpOyAKfQpEV09SRCBXSU5BUEkgU0hDTFNJREZyb21TdHJpbmdBVyAoTFBWT0lEIGNsc2lkLCBDTFNJRCAqaWQpCnsKCWlmIChWRVJTSU9OX09zSXNVbmljb2RlKCkpCgkgIHJldHVybiBTSENMU0lERnJvbVN0cmluZ1cgKGNsc2lkLCBpZCk7CglyZXR1cm4gU0hDTFNJREZyb21TdHJpbmdBIChjbHNpZCwgaWQpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJCSBTSEdldE1hbGxvYwkJCVtTSEVMTDMyLjIyMF0KICogcmV0dXJucyB0aGUgaW50ZXJmYWNlIHRvIHNoZWxsIG1hbGxvYy4KICoKICogW1NESyBoZWFkZXIgd2luOTUvc2hsb2JqLmg6CiAqIGVxdWl2YWxlbnQgdG86ICAjZGVmaW5lIFNIR2V0TWFsbG9jKHBwbWVtKSAgIENvR2V0TWFsbG9jKE1FTUNUWF9UQVNLLCBwcG1lbSkKICogXQogKiBXaGF0IHdlIGFyZSBjdXJyZW50bHkgZG9pbmcgaXMgbm90IHZlcnkgd3JvbmcsIHNpbmNlIHdlIGFsd2F5cyB1c2UgdGhlIHNhbWUKICogaGVhcCAoUHJvY2Vzc0hlYXApLgogKi8KRFdPUkQgV0lOQVBJIFNIR2V0TWFsbG9jKExQTUFMTE9DICpscG1hbCkgCnsKCVRSQUNFKCIoJXApXG4iLCBscG1hbCk7CglyZXR1cm4gQ29HZXRNYWxsb2MoMCxscG1hbCk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFNIR2V0RGVza3RvcEZvbGRlcgkJCVtTSEVMTDMyLjIxNl0KICovCkxQU0hFTExGT0xERVIgcGRlc2t0b3Bmb2xkZXI9TlVMTDsKCkRXT1JEIFdJTkFQSSBTSEdldERlc2t0b3BGb2xkZXIoSVNoZWxsRm9sZGVyICoqcHNmKQp7CglIUkVTVUxUCWhyZXMgPSBTX09LOwoJTFBDTEFTU0ZBQ1RPUlkgbHBjbGY7CglUUkFDRSgiJXAtPiglcClcbiIscHNmLCpwc2YpOwoKCSpwc2Y9TlVMTDsKCglpZiAoIXBkZXNrdG9wZm9sZGVyKSAKCXsKCSAgbHBjbGYgPSBJQ2xhc3NGYWN0b3J5X0NvbnN0cnVjdG9yKCZDTFNJRF9TaGVsbERlc2t0b3ApOwoJICBpZihscGNsZikgCgkgIHsKCSAgICBocmVzID0gSUNsYXNzRmFjdG9yeV9DcmVhdGVJbnN0YW5jZShscGNsZixOVUxMLChSRUZJSUQpJklJRF9JU2hlbGxGb2xkZXIsICh2b2lkKikmcGRlc2t0b3Bmb2xkZXIpOwoJICAgIElDbGFzc0ZhY3RvcnlfUmVsZWFzZShscGNsZik7CgkgIH0gIAoJfQoJCglpZiAocGRlc2t0b3Bmb2xkZXIpIAoJewoJICAvKiBldmVuIGlmIHdlIGNyZWF0ZSB0aGUgZm9sZGVyLCBhZGQgYSByZWYgc28gdGhlIGFwcGxpY2F0aW9uIGNhbrR0IGRlc3Ryb3kgdGhlIGZvbGRlciovCgkgIElTaGVsbEZvbGRlcl9BZGRSZWYocGRlc2t0b3Bmb2xkZXIpOwoJICAqcHNmID0gcGRlc2t0b3Bmb2xkZXI7Cgl9CgoJVFJBQ0UoIi0tICVwLT4oJXApXG4iLHBzZiwgKnBzZik7CglyZXR1cm4gaHJlczsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiogIElDbGFzc0ZhY3RvcnkgSW1wbGVtZW50YXRpb24KKi8KCnR5cGVkZWYgc3RydWN0CnsKICAgIC8qIElVbmtub3duIGZpZWxkcyAqLwogICAgSUNPTV9WRklFTEQoSUNsYXNzRmFjdG9yeSk7CiAgICBEV09SRCAgICAgICAgICAgICAgICAgICAgICAgcmVmOwogICAgQ0xTSUQJCQkqcmNsc2lkOwp9IElDbGFzc0ZhY3RvcnlJbXBsOwoKc3RhdGljIElDT01fVlRBQkxFKElDbGFzc0ZhY3RvcnkpIGNsZnZ0OwoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICBJQ2xhc3NGYWN0b3J5X0NvbnN0cnVjdG9yCiAqLwoKTFBDTEFTU0ZBQ1RPUlkgSUNsYXNzRmFjdG9yeV9Db25zdHJ1Y3RvcihSRUZDTFNJRCByY2xzaWQpCnsKCUlDbGFzc0ZhY3RvcnlJbXBsKiBscGNsZjsKCglscGNsZj0gKElDbGFzc0ZhY3RvcnlJbXBsKilIZWFwQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwwLHNpemVvZihJQ2xhc3NGYWN0b3J5SW1wbCkpOwoJbHBjbGYtPnJlZiA9IDE7CglJQ09NX1ZUQkwobHBjbGYpID0gJmNsZnZ0OwoJbHBjbGYtPnJjbHNpZCA9IChDTFNJRCopcmNsc2lkOwoKCVRSQUNFKCIoJXApLT4oKVxuIixscGNsZik7CglzaGVsbDMyX09iakNvdW50Kys7CglyZXR1cm4gKExQQ0xBU1NGQUNUT1JZKWxwY2xmOwp9Ci8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgSUNsYXNzRmFjdG9yeV9RdWVyeUludGVyZmFjZQogKi8Kc3RhdGljIEhSRVNVTFQgV0lOQVBJIElDbGFzc0ZhY3RvcnlfZm5RdWVyeUludGVyZmFjZSgKICBMUENMQVNTRkFDVE9SWSBpZmFjZSwgUkVGSUlEIHJpaWQsIExQVk9JRCAqcHB2T2JqKQp7CglJQ09NX1RISVMoSUNsYXNzRmFjdG9yeUltcGwsaWZhY2UpOwoJVFJBQ0UoIiglcCktPihcblx0SUlEOlx0JXMpXG4iLFRoaXMsZGVidWdzdHJfZ3VpZChyaWlkKSk7CgoJKnBwdk9iaiA9IE5VTEw7CgoJaWYoSXNFcXVhbElJRChyaWlkLCAmSUlEX0lVbmtub3duKSkgICAgICAgICAgLypJVW5rbm93biovCgl7ICpwcHZPYmogPSBUaGlzOyAKCX0KCWVsc2UgaWYoSXNFcXVhbElJRChyaWlkLCAmSUlEX0lDbGFzc0ZhY3RvcnkpKSAgLypJQ2xhc3NGYWN0b3J5Ki8KCXsgKnBwdk9iaiA9IChJQ2xhc3NGYWN0b3J5KilUaGlzOwoJfSAgIAoKCWlmKCpwcHZPYmopCgl7IElVbmtub3duX0FkZFJlZigoTFBVTktOT1dOKSpwcHZPYmopOyAgCQoJICBUUkFDRSgiLS0gSW50ZXJmYWNlOiAoJXApLT4oJXApXG4iLHBwdk9iaiwqcHB2T2JqKTsKCSAgcmV0dXJuIFNfT0s7Cgl9CglUUkFDRSgiLS0gSW50ZXJmYWNlOiAlcyBFX05PSU5URVJGQUNFXG4iLCBkZWJ1Z3N0cl9ndWlkKHJpaWQpKTsKCXJldHVybiBFX05PSU5URVJGQUNFOwp9ICAKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBJQ2xhc3NGYWN0b3J5X0FkZFJlZgogKi8Kc3RhdGljIFVMT05HIFdJTkFQSSBJQ2xhc3NGYWN0b3J5X2ZuQWRkUmVmKExQQ0xBU1NGQUNUT1JZIGlmYWNlKQp7CglJQ09NX1RISVMoSUNsYXNzRmFjdG9yeUltcGwsaWZhY2UpOwoJVFJBQ0UoIiglcCktPihjb3VudD0lbHUpXG4iLFRoaXMsVGhpcy0+cmVmKTsKCglzaGVsbDMyX09iakNvdW50Kys7CglyZXR1cm4gKysoVGhpcy0+cmVmKTsKfQovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIElDbGFzc0ZhY3RvcnlfUmVsZWFzZQogKi8Kc3RhdGljIFVMT05HIFdJTkFQSSBJQ2xhc3NGYWN0b3J5X2ZuUmVsZWFzZShMUENMQVNTRkFDVE9SWSBpZmFjZSkKewoJSUNPTV9USElTKElDbGFzc0ZhY3RvcnlJbXBsLGlmYWNlKTsKCVRSQUNFKCIoJXApLT4oY291bnQ9JWx1KVxuIixUaGlzLFRoaXMtPnJlZik7CgoJc2hlbGwzMl9PYmpDb3VudC0tOwoJaWYgKCEtLShUaGlzLT5yZWYpKSAKCXsgVFJBQ0UoIi0tIGRlc3Ryb3lpbmcgSUNsYXNzRmFjdG9yeSglcClcbiIsVGhpcyk7CgkJSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwwLFRoaXMpOwoJCXJldHVybiAwOwoJfQoJcmV0dXJuIFRoaXMtPnJlZjsKfQovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIElDbGFzc0ZhY3RvcnlfQ3JlYXRlSW5zdGFuY2UKICovCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJQ2xhc3NGYWN0b3J5X2ZuQ3JlYXRlSW5zdGFuY2UoCiAgTFBDTEFTU0ZBQ1RPUlkgaWZhY2UsIExQVU5LTk9XTiBwVW5rbm93biwgUkVGSUlEIHJpaWQsIExQVk9JRCAqcHBPYmplY3QpCnsKCUlDT01fVEhJUyhJQ2xhc3NGYWN0b3J5SW1wbCxpZmFjZSk7CglJVW5rbm93biAqcE9iaiA9IE5VTEw7CglIUkVTVUxUIGhyZXM7CgoJVFJBQ0UoIiVwLT4oJXAsXG5cdElJRDpcdCVzLCVwKVxuIixUaGlzLHBVbmtub3duLGRlYnVnc3RyX2d1aWQocmlpZCkscHBPYmplY3QpOwoKCSpwcE9iamVjdCA9IE5VTEw7CgkJCglpZihwVW5rbm93bikKCXsKCSAgcmV0dXJuKENMQVNTX0VfTk9BR0dSRUdBVElPTik7Cgl9CgoJaWYgKElzRXF1YWxDTFNJRChUaGlzLT5yY2xzaWQsICZDTFNJRF9TaGVsbERlc2t0b3ApKQoJewoJICBwT2JqID0gKElVbmtub3duICopSVNGX0Rlc2t0b3BfQ29uc3RydWN0b3IoKTsKCX0KCWVsc2UgaWYgKElzRXF1YWxDTFNJRChUaGlzLT5yY2xzaWQsICZDTFNJRF9TaGVsbExpbmspKQoJewoJICBwT2JqID0gKElVbmtub3duICopSVNoZWxsTGlua19Db25zdHJ1Y3RvcihGQUxTRSk7Cgl9IAoJZWxzZQoJewoJICBFUlIoInVua25vd24gSUlEIHJlcXVlc3RlZFxuXHRJSUQ6XHQlc1xuIixkZWJ1Z3N0cl9ndWlkKHJpaWQpKTsKCSAgcmV0dXJuKEVfTk9JTlRFUkZBQ0UpOwoJfQoJCglpZiAoIXBPYmopCgl7CgkgIHJldHVybihFX09VVE9GTUVNT1JZKTsKCX0KCSAKCWhyZXMgPSBJVW5rbm93bl9RdWVyeUludGVyZmFjZShwT2JqLHJpaWQsIHBwT2JqZWN0KTsKCUlVbmtub3duX1JlbGVhc2UocE9iaik7CgoJVFJBQ0UoIi0tIE9iamVjdCBjcmVhdGVkOiAoJXApLT4lcFxuIixUaGlzLCpwcE9iamVjdCk7CgoJcmV0dXJuIGhyZXM7Cn0KLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBJQ2xhc3NGYWN0b3J5X0xvY2tTZXJ2ZXIKICovCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJQ2xhc3NGYWN0b3J5X2ZuTG9ja1NlcnZlcihMUENMQVNTRkFDVE9SWSBpZmFjZSwgQk9PTCBmTG9jaykKewoJSUNPTV9USElTKElDbGFzc0ZhY3RvcnlJbXBsLGlmYWNlKTsKCVRSQUNFKCIlcC0+KDB4JXgpLCBub3QgaW1wbGVtZW50ZWRcbiIsVGhpcywgZkxvY2spOwoJcmV0dXJuIEVfTk9USU1QTDsKfQoKc3RhdGljIElDT01fVlRBQkxFKElDbGFzc0ZhY3RvcnkpIGNsZnZ0ID0gCnsKICAgIElDT01fTVNWVEFCTEVfQ09NUEFUX0R1bW15UlRUSVZBTFVFCiAgICBJQ2xhc3NGYWN0b3J5X2ZuUXVlcnlJbnRlcmZhY2UsCiAgICBJQ2xhc3NGYWN0b3J5X2ZuQWRkUmVmLAogIElDbGFzc0ZhY3RvcnlfZm5SZWxlYXNlLAogIElDbGFzc0ZhY3RvcnlfZm5DcmVhdGVJbnN0YW5jZSwKICBJQ2xhc3NGYWN0b3J5X2ZuTG9ja1NlcnZlcgp9OwoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIERlZmF1bHQgQ2xhc3NGYWN0b3J5IEltcGxlbWVudGF0aW9uCiAqCiAqIFNIQ3JlYXRlRGVmQ2xhc3NPYmplY3QKICoKICogTk9URVMKICogIGhlbHBlciBmdW5jdGlvbiBmb3IgZGxsJ3Mgd2l0aG91dCBhIG93biBjbGFzc2ZhY3RvcnkKICogIGEgZ2VuZXJpYyBjbGFzc2ZhY3RvcnkgaXMgcmV0dXJuZWQKICogIHdoZW4gdGhlIENyZWF0ZUluc3RhbmNlIG9mIHRoZSBjZiBpcyBjYWxsZWQgdGhlIGNhbGxiYWNrIGlzIGV4ZWN1dGVkCiAqLwp0eXBlZGVmIEhSRVNVTFQgKENBTExCQUNLICogTFBGTkNSRUFURUlOU1RBTkNFKShJVW5rbm93biogcFVua091dGVyLCBSRUZJSUQgcmlpZCwgTFBWT0lEKiBwcHZPYmplY3QpOwoKdHlwZWRlZiBzdHJ1Y3QKewogICAgSUNPTV9WRklFTEQoSUNsYXNzRmFjdG9yeSk7CiAgICBEV09SRCAgICAgICAgICAgICAgICAgICAgICAgcmVmOwogICAgQ0xTSUQJCQkqcmNsc2lkOwogICAgTFBGTkNSRUFURUlOU1RBTkNFCQlscGZuQ0k7CiAgICBjb25zdCBJSUQgKgkJCXJpaWRJbnN0OwogICAgVUlOVCAqCQkJcGNSZWZEbGw7IC8qIHBvaW50ZXIgdG8gcmVmY291bnRlciBpbiBleHRlcm5hbCBkbGwgKHVncnJyLi4uKSAqLwp9IElEZWZDbEZJbXBsOwoKc3RhdGljIElDT01fVlRBQkxFKElDbGFzc0ZhY3RvcnkpIGRjbGZ2dDsKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgSURlZkNsRl9mbkNvbnN0cnVjdG9yCiAqLwoKSUNsYXNzRmFjdG9yeSAqIElEZWZDbEZfZm5Db25zdHJ1Y3RvcihMUEZOQ1JFQVRFSU5TVEFOQ0UgbHBmbkNJLCBVSU5UICogcGNSZWZEbGwsIFJFRklJRCByaWlkSW5zdCkKewoJSURlZkNsRkltcGwqIGxwY2xmOwoKCWxwY2xmID0gKElEZWZDbEZJbXBsKilIZWFwQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwwLHNpemVvZihJRGVmQ2xGSW1wbCkpOwoJbHBjbGYtPnJlZiA9IDE7CglJQ09NX1ZUQkwobHBjbGYpID0gJmRjbGZ2dDsKCWxwY2xmLT5scGZuQ0kgPSBscGZuQ0k7CglscGNsZi0+cGNSZWZEbGwgPSBwY1JlZkRsbDsKCglpZiAocGNSZWZEbGwpIAoJICAoKnBjUmVmRGxsKSsrOwoKCWxwY2xmLT5yaWlkSW5zdCA9IHJpaWRJbnN0OwoKCVRSQUNFKCIoJXApXG5cdElJRDpcdCVzXG4iLGxwY2xmLCBkZWJ1Z3N0cl9ndWlkKHJpaWRJbnN0KSk7CglzaGVsbDMyX09iakNvdW50Kys7CglyZXR1cm4gKExQQ0xBU1NGQUNUT1JZKWxwY2xmOwp9Ci8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgSURlZkNsRl9mblF1ZXJ5SW50ZXJmYWNlCiAqLwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSURlZkNsRl9mblF1ZXJ5SW50ZXJmYWNlKAogIExQQ0xBU1NGQUNUT1JZIGlmYWNlLCBSRUZJSUQgcmlpZCwgTFBWT0lEICpwcHZPYmopCnsKCUlDT01fVEhJUyhJRGVmQ2xGSW1wbCxpZmFjZSk7CgoJVFJBQ0UoIiglcCktPihcblx0SUlEOlx0JXMpXG4iLFRoaXMsZGVidWdzdHJfZ3VpZChyaWlkKSk7CgoJKnBwdk9iaiA9IE5VTEw7CgoJaWYoSXNFcXVhbElJRChyaWlkLCAmSUlEX0lVbmtub3duKSkgICAgICAgICAgLypJVW5rbm93biovCgl7ICpwcHZPYmogPSBUaGlzOyAKCX0KCWVsc2UgaWYoSXNFcXVhbElJRChyaWlkLCAmSUlEX0lDbGFzc0ZhY3RvcnkpKSAgLypJQ2xhc3NGYWN0b3J5Ki8KCXsgKnBwdk9iaiA9IChJQ2xhc3NGYWN0b3J5KilUaGlzOwoJfSAgIAoKCWlmKCpwcHZPYmopCgl7IElVbmtub3duX0FkZFJlZigoTFBVTktOT1dOKSpwcHZPYmopOyAgCQoJICBUUkFDRSgiLS0gSW50ZXJmYWNlOiAoJXApLT4oJXApXG4iLHBwdk9iaiwqcHB2T2JqKTsKCSAgcmV0dXJuIFNfT0s7Cgl9CglUUkFDRSgiLS0gSW50ZXJmYWNlOiAlcyBFX05PSU5URVJGQUNFXG4iLCBkZWJ1Z3N0cl9ndWlkKHJpaWQpKTsKCXJldHVybiBFX05PSU5URVJGQUNFOwp9ICAKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBJRGVmQ2xGX2ZuQWRkUmVmCiAqLwpzdGF0aWMgVUxPTkcgV0lOQVBJIElEZWZDbEZfZm5BZGRSZWYoTFBDTEFTU0ZBQ1RPUlkgaWZhY2UpCnsKCUlDT01fVEhJUyhJRGVmQ2xGSW1wbCxpZmFjZSk7CglUUkFDRSgiKCVwKS0+KGNvdW50PSVsdSlcbiIsVGhpcyxUaGlzLT5yZWYpOwoKCXNoZWxsMzJfT2JqQ291bnQrKzsKCglyZXR1cm4gKysoVGhpcy0+cmVmKTsKfQovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIElEZWZDbEZfZm5SZWxlYXNlCiAqLwpzdGF0aWMgVUxPTkcgV0lOQVBJIElEZWZDbEZfZm5SZWxlYXNlKExQQ0xBU1NGQUNUT1JZIGlmYWNlKQp7CglJQ09NX1RISVMoSURlZkNsRkltcGwsaWZhY2UpOwoJVFJBQ0UoIiglcCktPihjb3VudD0lbHUpXG4iLFRoaXMsVGhpcy0+cmVmKTsKCglzaGVsbDMyX09iakNvdW50LS07CgoJaWYgKCEtLShUaGlzLT5yZWYpKSAKCXsgCgkgIGlmIChUaGlzLT5wY1JlZkRsbCkgCgkgICAgKCpUaGlzLT5wY1JlZkRsbCktLTsKCgkgIFRSQUNFKCItLSBkZXN0cm95aW5nIElDbGFzc0ZhY3RvcnkoJXApXG4iLFRoaXMpOwoJICBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLDAsVGhpcyk7CgkgIHJldHVybiAwOwoJfQoJcmV0dXJuIFRoaXMtPnJlZjsKfQovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIElEZWZDbEZfZm5DcmVhdGVJbnN0YW5jZQogKi8Kc3RhdGljIEhSRVNVTFQgV0lOQVBJIElEZWZDbEZfZm5DcmVhdGVJbnN0YW5jZSgKICBMUENMQVNTRkFDVE9SWSBpZmFjZSwgTFBVTktOT1dOIHBVbmtPdXRlciwgUkVGSUlEIHJpaWQsIExQVk9JRCAqcHB2T2JqZWN0KQp7CglJQ09NX1RISVMoSURlZkNsRkltcGwsaWZhY2UpOwoKCVRSQUNFKCIlcC0+KCVwLFxuXHRJSUQ6XHQlcywlcClcbiIsVGhpcyxwVW5rT3V0ZXIsZGVidWdzdHJfZ3VpZChyaWlkKSxwcHZPYmplY3QpOwoKCSpwcHZPYmplY3QgPSBOVUxMOwoJCQoJaWYocFVua091dGVyKQoJICByZXR1cm4oQ0xBU1NfRV9OT0FHR1JFR0FUSU9OKTsKCglpZiAoIFRoaXMtPnJpaWRJbnN0PT1OVUxMIHx8CgkgICAgIElzRXF1YWxDTFNJRChyaWlkLCBUaGlzLT5yaWlkSW5zdCkgfHwKCSAgICAgSXNFcXVhbENMU0lEKHJpaWQsICZJSURfSVVua25vd24pICkKCXsKCSAgcmV0dXJuIFRoaXMtPmxwZm5DSShwVW5rT3V0ZXIsIHJpaWQsIHBwdk9iamVjdCk7Cgl9CgoJRVJSKCJ1bmtub3duIElJRCByZXF1ZXN0ZWRcblx0SUlEOlx0JXNcbiIsZGVidWdzdHJfZ3VpZChyaWlkKSk7CglyZXR1cm4gRV9OT0lOVEVSRkFDRTsKfQovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIElEZWZDbEZfZm5Mb2NrU2VydmVyCiAqLwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSURlZkNsRl9mbkxvY2tTZXJ2ZXIoTFBDTEFTU0ZBQ1RPUlkgaWZhY2UsIEJPT0wgZkxvY2spCnsKCUlDT01fVEhJUyhJRGVmQ2xGSW1wbCxpZmFjZSk7CglUUkFDRSgiJXAtPigweCV4KSwgbm90IGltcGxlbWVudGVkXG4iLFRoaXMsIGZMb2NrKTsKCXJldHVybiBFX05PVElNUEw7Cn0KCnN0YXRpYyBJQ09NX1ZUQUJMRShJQ2xhc3NGYWN0b3J5KSBkY2xmdnQgPSAKewogICAgSUNPTV9NU1ZUQUJMRV9DT01QQVRfRHVtbXlSVFRJVkFMVUUKICAgIElEZWZDbEZfZm5RdWVyeUludGVyZmFjZSwKICAgIElEZWZDbEZfZm5BZGRSZWYsCiAgSURlZkNsRl9mblJlbGVhc2UsCiAgSURlZkNsRl9mbkNyZWF0ZUluc3RhbmNlLAogIElEZWZDbEZfZm5Mb2NrU2VydmVyCn07CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFNIQ3JlYXRlRGVmQ2xhc3NPYmplY3QJCQlbU0hFTEwzMi43MF0KICovCkhSRVNVTFQgV0lOQVBJIFNIQ3JlYXRlRGVmQ2xhc3NPYmplY3QoCglSRUZJSUQJcmlpZCwJCQkJCglMUFZPSUQqCXBwdiwJCglMUEZOQ1JFQVRFSU5TVEFOQ0UgbHBmbkNJLAkvKiBjcmVhdGUgaW5zdGFuY2UgY2FsbGJhY2sgZW50cnkgKi8KCVVJTlQJKnBjUmVmRGxsLAkJLyogcmVmIGNvdW50IG9mIHRoZSBkbGwgKi8KCVJFRklJRAlyaWlkSW5zdCkJCS8qIG9wdGlvbmFsIGludGVyZmFjZSB0byB0aGUgaW5zdGFuY2UgKi8KewoJVFJBQ0UoIlxuXHRJSUQ6XHQlcyAlcCAlcCAlcCBcblx0SUlESW5zOlx0JXNcbiIsCiAgICAgICAgICAgICAgZGVidWdzdHJfZ3VpZChyaWlkKSwgcHB2LCBscGZuQ0ksIHBjUmVmRGxsLCBkZWJ1Z3N0cl9ndWlkKHJpaWRJbnN0KSk7CgoJaWYgKCBJc0VxdWFsQ0xTSUQocmlpZCwgJklJRF9JQ2xhc3NGYWN0b3J5KSApCgl7CgkgIElDbGFzc0ZhY3RvcnkgKiBwY2YgPSBJRGVmQ2xGX2ZuQ29uc3RydWN0b3IobHBmbkNJLCBwY1JlZkRsbCwgcmlpZEluc3QpOwoJICBpZiAocGNmKQoJICB7CgkgICAgKnBwdiA9IHBjZjsKCSAgICByZXR1cm4gTk9FUlJPUjsKCSAgfQoJICByZXR1cm4gRV9PVVRPRk1FTU9SWTsKCX0KCXJldHVybiBFX05PSU5URVJGQUNFOwp9Cgo=