LyoKICogTG9jYWxlIHN1cHBvcnQKICoKICogQ29weXJpZ2h0IDE5OTUgTWFydGluIHZvbiBMb2V3aXMKICogQ29weXJpZ2h0IDE5OTggRGF2aWQgTGVlIExhbWJlcnQKICogQ29weXJpZ2h0IDIwMDAgSnVsaW8gQ+lzYXIgR+F6cXVlegogKiBDb3B5cmlnaHQgMjAwMiBBbGV4YW5kcmUgSnVsbGlhcmQgZm9yIENvZGVXZWF2ZXJzCiAqCiAqIFRoaXMgbGlicmFyeSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IKICogbW9kaWZ5IGl0IHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpYwogKiBMaWNlbnNlIGFzIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uOyBlaXRoZXIKICogdmVyc2lvbiAyLjEgb2YgdGhlIExpY2Vuc2UsIG9yIChhdCB5b3VyIG9wdGlvbikgYW55IGxhdGVyIHZlcnNpb24uCiAqCiAqIFRoaXMgbGlicmFyeSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLAogKiBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZgogKiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVQogKiBMZXNzZXIgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBmb3IgbW9yZSBkZXRhaWxzLgogKgogKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljCiAqIExpY2Vuc2UgYWxvbmcgd2l0aCB0aGlzIGxpYnJhcnk7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUKICogRm91bmRhdGlvbiwgSW5jLiwgNTkgVGVtcGxlIFBsYWNlLCBTdWl0ZSAzMzAsIEJvc3RvbiwgTUEgIDAyMTExLTEzMDcgIFVTQQogKi8KCiNpbmNsdWRlICJjb25maWcuaCIKI2luY2x1ZGUgIndpbmUvcG9ydC5oIgoKI2luY2x1ZGUgPGFzc2VydC5oPgojaW5jbHVkZSA8c3RyaW5nLmg+CiNpbmNsdWRlIDxzdGRhcmcuaD4KI2luY2x1ZGUgPHN0ZGlvLmg+CiNpbmNsdWRlIDxjdHlwZS5oPgojaW5jbHVkZSA8c3RkbGliLmg+CgojaW5jbHVkZSAibnRzdGF0dXMuaCIKI2luY2x1ZGUgIndpbmRlZi5oIgojaW5jbHVkZSAid2luYmFzZS5oIgojaW5jbHVkZSAid2ludXNlci5oIiAgLyogZm9yIFJUX1NUUklOR1cgKi8KI2luY2x1ZGUgIndpbnJlZy5oIgojaW5jbHVkZSAid2ludGVybmwuaCIKI2luY2x1ZGUgIndpbmUvdW5pY29kZS5oIgojaW5jbHVkZSAid2lubmxzLmgiCiNpbmNsdWRlICJ3aW5lcnJvci5oIgojaW5jbHVkZSAid2ludmVyLmgiCiNpbmNsdWRlICJ0aHJlYWQuaCIKI2luY2x1ZGUgImtlcm5lbF9wcml2YXRlLmgiCiNpbmNsdWRlICJ3aW5lL2RlYnVnLmgiCgpXSU5FX0RFRkFVTFRfREVCVUdfQ0hBTk5FTChubHMpOwoKI2RlZmluZSBMT0NBTEVfTE9DQUxFSU5GT0ZMQUdTTUFTSyAoTE9DQUxFX05PVVNFUk9WRVJSSURFfExPQ0FMRV9VU0VfQ1BfQUNQfExPQ0FMRV9SRVRVUk5fTlVNQkVSKQoKLyogY3VycmVudCBjb2RlIHBhZ2VzICovCnN0YXRpYyBjb25zdCB1bmlvbiBjcHRhYmxlICphbnNpX2NwdGFibGU7CnN0YXRpYyBjb25zdCB1bmlvbiBjcHRhYmxlICpvZW1fY3B0YWJsZTsKc3RhdGljIGNvbnN0IHVuaW9uIGNwdGFibGUgKm1hY19jcHRhYmxlOwpzdGF0aWMgY29uc3QgdW5pb24gY3B0YWJsZSAqdW5peF9jcHRhYmxlOyAgLyogTlVMTCBpZiBVVEY4ICovCgpzdGF0aWMgSEtFWSBOTFNfUmVnT3BlbktleShIS0VZIGhSb290S2V5LCBMUENXU1RSIHN6S2V5TmFtZSk7CnN0YXRpYyBIS0VZIE5MU19SZWdPcGVuU3ViS2V5KEhLRVkgaFJvb3RLZXksIExQQ1dTVFIgc3pLZXlOYW1lKTsKCnN0YXRpYyBjb25zdCBXQ0hBUiBzek5sc0tleU5hbWVbXSA9IHsKICAgICdNJywnYScsJ2MnLCdoJywnaScsJ24nLCdlJywnXFwnLCdTJywneScsJ3MnLCd0JywnZScsJ20nLCdcXCcsCiAgICAnQycsJ3UnLCdyJywncicsJ2UnLCduJywndCcsJ0MnLCdvJywnbicsJ3QnLCdyJywnbycsJ2wnLCdTJywnZScsJ3QnLCdcXCcsCiAgICAnQycsJ28nLCduJywndCcsJ3InLCdvJywnbCcsJ1xcJywnTicsJ2wnLCdzJywnXDAnCn07CgovKiBDaGFyc2V0IHRvIGNvZGVwYWdlIG1hcCwgc29ydGVkIGJ5IG5hbWUuICovCnN0YXRpYyBjb25zdCBzdHJ1Y3QgY2hhcnNldF9lbnRyeQp7CiAgICBjb25zdCBjaGFyICpjaGFyc2V0X25hbWU7CiAgICBVSU5UICAgICAgICBjb2RlcGFnZTsKfSBjaGFyc2V0X25hbWVzW10gPQp7CiAgICB7ICJCSUc1IiwgOTUwIH0sCiAgICB7ICJDUDEyNTAiLCAxMjUwIH0sCiAgICB7ICJDUDEyNTEiLCAxMjUxIH0sCiAgICB7ICJDUDEyNTIiLCAxMjUyIH0sCiAgICB7ICJDUDEyNTMiLCAxMjUzIH0sCiAgICB7ICJDUDEyNTQiLCAxMjU0IH0sCiAgICB7ICJDUDEyNTUiLCAxMjU1IH0sCiAgICB7ICJDUDEyNTYiLCAxMjU2IH0sCiAgICB7ICJDUDEyNTciLCAxMjU3IH0sCiAgICB7ICJDUDEyNTgiLCAxMjU4IH0sCiAgICB7ICJDUDkzMiIsIDkzMiB9LAogICAgeyAiQ1A5MzYiLCA5MzYgfSwKICAgIHsgIkNQOTQ5IiwgOTQ5IH0sCiAgICB7ICJDUDk1MCIsIDk1MCB9LAogICAgeyAiRVVDSlAiLCAyMDkzMiB9LAogICAgeyAiR0IyMzEyIiwgOTM2IH0sCiAgICB7ICJJQk0wMzciLCAzNyB9LAogICAgeyAiSUJNMTAyNiIsIDEwMjYgfSwKICAgIHsgIklCTTQyNCIsIDQyNCB9LAogICAgeyAiSUJNNDM3IiwgNDM3IH0sCiAgICB7ICJJQk01MDAiLCA1MDAgfSwKICAgIHsgIklCTTg1MCIsIDg1MCB9LAogICAgeyAiSUJNODUyIiwgODUyIH0sCiAgICB7ICJJQk04NTUiLCA4NTUgfSwKICAgIHsgIklCTTg1NyIsIDg1NyB9LAogICAgeyAiSUJNODYwIiwgODYwIH0sCiAgICB7ICJJQk04NjEiLCA4NjEgfSwKICAgIHsgIklCTTg2MiIsIDg2MiB9LAogICAgeyAiSUJNODYzIiwgODYzIH0sCiAgICB7ICJJQk04NjQiLCA4NjQgfSwKICAgIHsgIklCTTg2NSIsIDg2NSB9LAogICAgeyAiSUJNODY2IiwgODY2IH0sCiAgICB7ICJJQk04NjkiLCA4NjkgfSwKICAgIHsgIklCTTg3NCIsIDg3NCB9LAogICAgeyAiSUJNODc1IiwgODc1IH0sCiAgICB7ICJJU084ODU5MSIsIDI4NTkxIH0sCiAgICB7ICJJU084ODU5MTAiLCAyODYwMCB9LAogICAgeyAiSVNPODg1OTEzIiwgMjg2MDMgfSwKICAgIHsgIklTTzg4NTkxNCIsIDI4NjA0IH0sCiAgICB7ICJJU084ODU5MTUiLCAyODYwNSB9LAogICAgeyAiSVNPODg1OTE2IiwgMjg2MDYgfSwKICAgIHsgIklTTzg4NTkyIiwgMjg1OTIgfSwKICAgIHsgIklTTzg4NTkzIiwgMjg1OTMgfSwKICAgIHsgIklTTzg4NTk0IiwgMjg1OTQgfSwKICAgIHsgIklTTzg4NTk1IiwgMjg1OTUgfSwKICAgIHsgIklTTzg4NTk2IiwgMjg1OTYgfSwKICAgIHsgIklTTzg4NTk3IiwgMjg1OTcgfSwKICAgIHsgIklTTzg4NTk4IiwgMjg1OTggfSwKICAgIHsgIklTTzg4NTk5IiwgMjg1OTkgfSwKICAgIHsgIktPSThSIiwgMjA4NjYgfSwKICAgIHsgIktPSThVIiwgMjE4NjYgfSwKICAgIHsgIlVURjgiLCBDUF9VVEY4IH0KfTsKCiNkZWZpbmUgTkxTX01BWF9MQU5HVUFHRVMgMjAKdHlwZWRlZiBzdHJ1Y3QgewogICAgV0NIQVIgbGFuZ1sxMjhdOwogICAgV0NIQVIgY291bnRyeVs0XTsKICAgIExBTkdJRCBmb3VuZF9sYW5nX2lkW05MU19NQVhfTEFOR1VBR0VTXTsKICAgIFdDSEFSIGZvdW5kX2xhbmd1YWdlW05MU19NQVhfTEFOR1VBR0VTXVszXTsKICAgIFdDSEFSIGZvdW5kX2NvdW50cnlbTkxTX01BWF9MQU5HVUFHRVNdWzNdOwogICAgaW50IG5fZm91bmQ7Cn0gTEFOR19GSU5EX0RBVEE7CgoKLyogY29weSBVbmljb2RlIHN0cmluZyB0byBBc2NpaSB3aXRob3V0IHVzaW5nIGNvZGVwYWdlcyAqLwpzdGF0aWMgaW5saW5lIHZvaWQgc3RyY3B5V3RvQSggY2hhciAqZHN0LCBjb25zdCBXQ0hBUiAqc3JjICkKewogICAgd2hpbGUgKCgqZHN0KysgPSAqc3JjKyspKTsKfQoKLyogQ29weSBBc2NpaSBzdHJpbmcgdG8gVW5pY29kZSB3aXRob3V0IHVzaW5nIGNvZGVwYWdlcyAqLwpzdGF0aWMgaW5saW5lIHZvaWQgc3RyY3B5bkF0b1coIFdDSEFSICpkc3QsIGNvbnN0IGNoYXIgKnNyYywgc2l6ZV90IG4gKQp7CiAgICB3aGlsZSAobiA+IDEgJiYgKnNyYykKICAgIHsKICAgICAgICAqZHN0KysgPSAodW5zaWduZWQgY2hhcikqc3JjKys7CiAgICAgICAgbi0tOwogICAgfQogICAgaWYgKG4pICpkc3QgPSAwOwp9CgovKiByZXR1cm4gYSBwcmludGFibGUgc3RyaW5nIGZvciBhIGxhbmd1YWdlIGlkICovCnN0YXRpYyBjb25zdCBjaGFyICpkZWJ1Z3N0cl9sYW5nKCBMQU5HSUQgbGFuZyApCnsKICAgIFdDSEFSIGxhbmdXWzRdLCBjb3VudHJ5V1s0XTsKICAgIGNoYXIgYnVmZmVyWzhdOwogICAgTENJRCBsY2lkID0gTUFLRUxDSUQoIGxhbmcsIFNPUlRfREVGQVVMVCApOwoKICAgIEdldExvY2FsZUluZm9XKGxjaWQsIExPQ0FMRV9TSVNPNjM5TEFOR05BTUV8TE9DQUxFX05PVVNFUk9WRVJSSURFLCBsYW5nVywgc2l6ZW9mKGxhbmdXKS9zaXplb2YoV0NIQVIpKTsKICAgIEdldExvY2FsZUluZm9XKGxjaWQsIExPQ0FMRV9TSVNPMzE2NkNUUllOQU1FfExPQ0FMRV9OT1VTRVJPVkVSUklERSwgY291bnRyeVcsIHNpemVvZihjb3VudHJ5Vykvc2l6ZW9mKFdDSEFSKSk7CiAgICBzdHJjcHlXdG9BKCBidWZmZXIsIGxhbmdXICk7CiAgICBzdHJjYXQoIGJ1ZmZlciwgIl8iICk7CiAgICBzdHJjcHlXdG9BKCBidWZmZXIgKyBzdHJsZW4oYnVmZmVyKSwgY291bnRyeVcgKTsKICAgIHJldHVybiB3aW5lX2RiZ19zcHJpbnRmKCAiJXMiLCBidWZmZXIgKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCQlnZXRfbGNpZF9jb2RlcGFnZQogKgogKiBSZXRyaWV2ZSB0aGUgQU5TSSBjb2RlcGFnZSBmb3IgYSBnaXZlbiBsb2NhbGUuCiAqLwppbmxpbmUgc3RhdGljIFVJTlQgZ2V0X2xjaWRfY29kZXBhZ2UoIExDSUQgbGNpZCApCnsKICAgIFVJTlQgcmV0OwogICAgaWYgKCFHZXRMb2NhbGVJbmZvVyggbGNpZCwgTE9DQUxFX0lERUZBVUxUQU5TSUNPREVQQUdFfExPQ0FMRV9SRVRVUk5fTlVNQkVSLCAoV0NIQVIgKikmcmV0LAogICAgICAgICAgICAgICAgICAgICAgICAgc2l6ZW9mKHJldCkvc2l6ZW9mKFdDSEFSKSApKSByZXQgPSAwOwogICAgcmV0dXJuIHJldDsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJZ2V0X2NvZGVwYWdlX3RhYmxlCiAqCiAqIEZpbmQgdGhlIHRhYmxlIGZvciBhIGdpdmVuIGNvZGVwYWdlLCBoYW5kbGluZyBDUF9BQ1AgZXRjLiBwc2V1ZG8tY29kZXBhZ2VzCiAqLwpzdGF0aWMgY29uc3QgdW5pb24gY3B0YWJsZSAqZ2V0X2NvZGVwYWdlX3RhYmxlKCB1bnNpZ25lZCBpbnQgY29kZXBhZ2UgKQp7CiAgICBjb25zdCB1bmlvbiBjcHRhYmxlICpyZXQgPSBOVUxMOwoKICAgIGFzc2VydCggYW5zaV9jcHRhYmxlICk7ICAvKiBpbml0IG11c3QgaGF2ZSBiZWVuIGRvbmUgYWxyZWFkeSAqLwoKICAgIHN3aXRjaChjb2RlcGFnZSkKICAgIHsKICAgIGNhc2UgQ1BfQUNQOgogICAgICAgIHJldHVybiBhbnNpX2NwdGFibGU7CiAgICBjYXNlIENQX09FTUNQOgogICAgICAgIHJldHVybiBvZW1fY3B0YWJsZTsKICAgIGNhc2UgQ1BfTUFDQ1A6CiAgICAgICAgcmV0dXJuIG1hY19jcHRhYmxlOwogICAgY2FzZSBDUF9VVEY3OgogICAgY2FzZSBDUF9VVEY4OgogICAgICAgIGJyZWFrOwogICAgY2FzZSBDUF9USFJFQURfQUNQOgogICAgICAgIGlmICghKGNvZGVwYWdlID0gTnRDdXJyZW50VGViKCktPmNvZGVfcGFnZSkpIHJldHVybiBhbnNpX2NwdGFibGU7CiAgICAgICAgLyogZmFsbCB0aHJvdWdoICovCiAgICBkZWZhdWx0OgogICAgICAgIGlmIChjb2RlcGFnZSA9PSBhbnNpX2NwdGFibGUtPmluZm8uY29kZXBhZ2UpIHJldHVybiBhbnNpX2NwdGFibGU7CiAgICAgICAgaWYgKGNvZGVwYWdlID09IG9lbV9jcHRhYmxlLT5pbmZvLmNvZGVwYWdlKSByZXR1cm4gb2VtX2NwdGFibGU7CiAgICAgICAgaWYgKGNvZGVwYWdlID09IG1hY19jcHRhYmxlLT5pbmZvLmNvZGVwYWdlKSByZXR1cm4gbWFjX2NwdGFibGU7CiAgICAgICAgcmV0ID0gd2luZV9jcF9nZXRfdGFibGUoIGNvZGVwYWdlICk7CiAgICAgICAgYnJlYWs7CiAgICB9CiAgICByZXR1cm4gcmV0Owp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCWNyZWF0ZV9yZWdpc3RyeV9rZXkKICoKICogQ3JlYXRlIHRoZSBDb250cm9sIFBhbmVsXFxJbnRlcm5hdGlvbmFsIHJlZ2lzdHJ5IGtleS4KICovCmlubGluZSBzdGF0aWMgSEtFWSBjcmVhdGVfcmVnaXN0cnlfa2V5KHZvaWQpCnsKICAgIHN0YXRpYyBjb25zdCBXQ0hBUiBpbnRsV1tdID0geydDJywnbycsJ24nLCd0JywncicsJ28nLCdsJywnICcsJ1AnLCdhJywnbicsJ2UnLCdsJywnXFwnLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ0knLCduJywndCcsJ2UnLCdyJywnbicsJ2EnLCd0JywnaScsJ28nLCduJywnYScsJ2wnLDB9OwogICAgT0JKRUNUX0FUVFJJQlVURVMgYXR0cjsKICAgIFVOSUNPREVfU1RSSU5HIG5hbWVXOwogICAgSEtFWSBoa2V5OwoKICAgIGlmIChSdGxPcGVuQ3VycmVudFVzZXIoIEtFWV9BTExfQUNDRVNTLCAmaGtleSApICE9IFNUQVRVU19TVUNDRVNTKSByZXR1cm4gMDsKCiAgICBhdHRyLkxlbmd0aCA9IHNpemVvZihhdHRyKTsKICAgIGF0dHIuUm9vdERpcmVjdG9yeSA9IGhrZXk7CiAgICBhdHRyLk9iamVjdE5hbWUgPSAmbmFtZVc7CiAgICBhdHRyLkF0dHJpYnV0ZXMgPSAwOwogICAgYXR0ci5TZWN1cml0eURlc2NyaXB0b3IgPSBOVUxMOwogICAgYXR0ci5TZWN1cml0eVF1YWxpdHlPZlNlcnZpY2UgPSBOVUxMOwogICAgUnRsSW5pdFVuaWNvZGVTdHJpbmcoICZuYW1lVywgaW50bFcgKTsKCiAgICBpZiAoTnRDcmVhdGVLZXkoICZoa2V5LCBLRVlfQUxMX0FDQ0VTUywgJmF0dHIsIDAsIE5VTEwsIDAsIE5VTEwgKSAhPSBTVEFUVVNfU1VDQ0VTUykgaGtleSA9IDA7CiAgICBOdENsb3NlKCBhdHRyLlJvb3REaXJlY3RvcnkgKTsKICAgIHJldHVybiBoa2V5Owp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCQlMT0NBTEVfSW5pdFJlZ2lzdHJ5CiAqCiAqIFVwZGF0ZSByZWdpc3RyeSBjb250ZW50cyBvbiBzdGFydHVwIGlmIHRoZSB1c2VyIGxvY2FsZSBoYXMgY2hhbmdlZC4KICogVGhpcyBzaW11bGF0ZXMgdGhlIGFjdGlvbiBvZiB0aGUgV2luZG93cyBjb250cm9sIHBhbmVsLgogKi8Kdm9pZCBMT0NBTEVfSW5pdFJlZ2lzdHJ5KHZvaWQpCnsKICAgIHN0YXRpYyBjb25zdCBXQ0hBUiBDb2RlcGFnZVdbXSA9IHsnQycsJ28nLCdkJywnZScsJ3AnLCdhJywnZycsJ2UnLDB9OwogICAgc3RhdGljIGNvbnN0IFdDSEFSIGFjcFdbXSA9IHsnQScsJ0MnLCdQJywwfTsKICAgIHN0YXRpYyBjb25zdCBXQ0hBUiBvZW1jcFdbXSA9IHsnTycsJ0UnLCdNJywnQycsJ1AnLDB9OwogICAgc3RhdGljIGNvbnN0IFdDSEFSIG1hY2NwV1tdID0geydNJywnQScsJ0MnLCdDJywnUCcsMH07CiAgICBzdGF0aWMgY29uc3Qgc3RydWN0CiAgICB7CiAgICAgICAgTFBDV1NUUiBuYW1lOwogICAgICAgIFVTSE9SVCB2YWx1ZTsKICAgIH0gdXBkYXRlX2NwX3ZhbHVlc1tdID0gewogICAgICAgIHsgYWNwVywgTE9DQUxFX0lERUZBVUxUQU5TSUNPREVQQUdFIH0sCiAgICAgICAgeyBvZW1jcFcsIExPQ0FMRV9JREVGQVVMVENPREVQQUdFIH0sCiAgICAgICAgeyBtYWNjcFcsIExPQ0FMRV9JREVGQVVMVE1BQ0NPREVQQUdFIH0KICAgIH07CiAgICBzdGF0aWMgY29uc3QgVVNIT1JUIHVwZGF0ZVZhbHVlc1tdID0gewogICAgICBMT0NBTEVfU0xBTkdVQUdFLAogICAgICBMT0NBTEVfU0NPVU5UUlksIExPQ0FMRV9JQ09VTlRSWSwKICAgICAgTE9DQUxFX1MxMTU5LCBMT0NBTEVfUzIzNTksCiAgICAgIExPQ0FMRV9TVElNRSwgTE9DQUxFX0lUSU1FLAogICAgICBMT0NBTEVfSVRMWkVSTywKICAgICAgTE9DQUxFX1NTSE9SVERBVEUsCiAgICAgIExPQ0FMRV9TTE9OR0RBVEUsCiAgICAgIExPQ0FMRV9TREFURSwKICAgICAgTE9DQUxFX1NDVVJSRU5DWSwgTE9DQUxFX0lDVVJSRU5DWSwKICAgICAgTE9DQUxFX0lORUdDVVJSLAogICAgICBMT0NBTEVfSUNVUlJESUdJVFMsCiAgICAgIExPQ0FMRV9TREVDSU1BTCwKICAgICAgTE9DQUxFX1NMSVNULAogICAgICBMT0NBTEVfU1RIT1VTQU5ELAogICAgICBMT0NBTEVfSURJR0lUUywKICAgICAgTE9DQUxFX0lESUdJVFNVQlNUSVRVVElPTiwKICAgICAgTE9DQUxFX1NOQVRJVkVESUdJVFMsCiAgICAgIExPQ0FMRV9JVElNRU1BUktQT1NOLAogICAgICBMT0NBTEVfSUNBTEVOREFSVFlQRSwKICAgICAgTE9DQUxFX0lMWkVSTywKICAgICAgTE9DQUxFX0lNRUFTVVJFCiAgICB9OwogICAgc3RhdGljIGNvbnN0IFdDSEFSIExvY2FsZVdbXSA9IHsnTCcsJ28nLCdjJywnYScsJ2wnLCdlJywwfTsKICAgIFVOSUNPREVfU1RSSU5HIG5hbWVXOwogICAgY2hhciBidWZmZXJbMjBdOwogICAgV0NIQVIgYnVmZmVyV1s4MF07CiAgICBEV09SRCBjb3VudCwgaTsKICAgIEhLRVkgaGtleTsKICAgIExDSUQgbGNpZCA9IEdldFVzZXJEZWZhdWx0TENJRCgpOwoKICAgIGlmICghKGhrZXkgPSBjcmVhdGVfcmVnaXN0cnlfa2V5KCkpKQogICAgICAgIHJldHVybjsgIC8qIGRvbid0IGRvIGFueXRoaW5nIGlmIHdlIGNhbid0IGNyZWF0ZSB0aGUgcmVnaXN0cnkga2V5ICovCgogICAgUnRsSW5pdFVuaWNvZGVTdHJpbmcoICZuYW1lVywgTG9jYWxlVyApOwogICAgY291bnQgPSBzaXplb2YoYnVmZmVyVyk7CiAgICBpZiAoIU50UXVlcnlWYWx1ZUtleShoa2V5LCAmbmFtZVcsIEtleVZhbHVlUGFydGlhbEluZm9ybWF0aW9uLCAoTFBCWVRFKWJ1ZmZlclcsIGNvdW50LCAmY291bnQpKQogICAgewogICAgICAgIGNvbnN0IEtFWV9WQUxVRV9QQVJUSUFMX0lORk9STUFUSU9OICppbmZvID0gKEtFWV9WQUxVRV9QQVJUSUFMX0lORk9STUFUSU9OICopYnVmZmVyVzsKICAgICAgICBMUENXU1RSIHN6VmFsdWVUZXh0ID0gKExQQ1dTVFIpaW5mby0+RGF0YTsKCiAgICAgICAgaWYgKHN0cnRvdWxXKCBzelZhbHVlVGV4dCwgTlVMTCwgMTYgKSA9PSBsY2lkKSAgLyogYWxyZWFkeSBzZXQgY29ycmVjdGx5ICovCiAgICAgICAgewogICAgICAgICAgICBOdENsb3NlKCBoa2V5ICk7CiAgICAgICAgICAgIHJldHVybjsKICAgICAgICB9CiAgICAgICAgVFJBQ0UoICJ1cGRhdGluZyByZWdpc3RyeSwgbG9jYWxlIGNoYW5nZWQgJXMgLT4gJTA4bHhcbiIsIGRlYnVnc3RyX3coc3pWYWx1ZVRleHQpLCBsY2lkICk7CiAgICB9CiAgICBlbHNlIFRSQUNFKCAidXBkYXRpbmcgcmVnaXN0cnksIGxvY2FsZSBjaGFuZ2VkIG5vbmUgLT4gJTA4bHhcbiIsIGxjaWQgKTsKCiAgICBzcHJpbnRmKCBidWZmZXIsICIlMDhseCIsIGxjaWQgKTsKICAgIC8qIE5vdGU6ICc5JyBjb25zdGFudCBiZWxvdyBpcyBzdHJsZW4oYnVmZmVyKSArIDEgKi8KICAgIFJ0bE11bHRpQnl0ZVRvVW5pY29kZU4oIGJ1ZmZlclcsIHNpemVvZihidWZmZXJXKSwgTlVMTCwgYnVmZmVyLCA5ICk7CiAgICBOdFNldFZhbHVlS2V5KCBoa2V5LCAmbmFtZVcsIDAsIFJFR19TWiwgYnVmZmVyVywgOSAqIHNpemVvZihXQ0hBUikgKTsKICAgIE50Q2xvc2UoIGhrZXkgKTsKCiAgICBmb3IgKGkgPSAwOyBpIDwgc2l6ZW9mKHVwZGF0ZVZhbHVlcykvc2l6ZW9mKHVwZGF0ZVZhbHVlc1swXSk7IGkrKykKICAgIHsKICAgICAgICBHZXRMb2NhbGVJbmZvVyggbGNpZCwgdXBkYXRlVmFsdWVzW2ldIHwgTE9DQUxFX05PVVNFUk9WRVJSSURFLCBidWZmZXJXLAogICAgICAgICAgICAgICAgICAgICAgICBzaXplb2YoYnVmZmVyVykvc2l6ZW9mKFdDSEFSKSApOwogICAgICAgIFNldExvY2FsZUluZm9XKCBsY2lkLCB1cGRhdGVWYWx1ZXNbaV0sIGJ1ZmZlclcgKTsKICAgIH0KCiAgICBoa2V5ID0gTkxTX1JlZ09wZW5TdWJLZXkoIE5MU19SZWdPcGVuS2V5KCAwLCBzek5sc0tleU5hbWUgKSwgQ29kZXBhZ2VXICk7CgogICAgZm9yIChpID0gMDsgaSA8IHNpemVvZih1cGRhdGVfY3BfdmFsdWVzKS9zaXplb2YodXBkYXRlX2NwX3ZhbHVlc1swXSk7IGkrKykKICAgIHsKICAgICAgICBjb3VudCA9IEdldExvY2FsZUluZm9XKCBsY2lkLCB1cGRhdGVfY3BfdmFsdWVzW2ldLnZhbHVlIHwgTE9DQUxFX05PVVNFUk9WRVJSSURFLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJ1ZmZlclcsIHNpemVvZihidWZmZXJXKS9zaXplb2YoV0NIQVIpICk7CiAgICAgICAgUnRsSW5pdFVuaWNvZGVTdHJpbmcoICZuYW1lVywgdXBkYXRlX2NwX3ZhbHVlc1tpXS5uYW1lICk7CiAgICAgICAgTnRTZXRWYWx1ZUtleSggaGtleSwgJm5hbWVXLCAwLCBSRUdfU1osIGJ1ZmZlclcsIGNvdW50ICogc2l6ZW9mKFdDSEFSKSApOwogICAgfQoKICAgIE50Q2xvc2UoIGhrZXkgKTsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgICAgICAgZmluZF9sYW5ndWFnZV9pZF9wcm9jCiAqLwpzdGF0aWMgQk9PTCBDQUxMQkFDSyBmaW5kX2xhbmd1YWdlX2lkX3Byb2MoIEhNT0RVTEUgaE1vZHVsZSwgTFBDV1NUUiB0eXBlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIExQQ1dTVFIgbmFtZSwgV09SRCBMYW5nSUQsIExQQVJBTSBsUGFyYW0gKQp7CiAgICBMQU5HX0ZJTkRfREFUQSAqbF9kYXRhID0gKExBTkdfRklORF9EQVRBICopbFBhcmFtOwogICAgTENJRCBsY2lkID0gTUFLRUxDSUQoTGFuZ0lELCBTT1JUX0RFRkFVTFQpOwogICAgV0NIQVIgYnVmX2xhbmd1YWdlWzEyOF07CiAgICBXQ0hBUiBidWZfY291bnRyeVsxMjhdOwogICAgV0NIQVIgYnVmX2VuX2xhbmd1YWdlWzEyOF07CgogICAgaWYoUFJJTUFSWUxBTkdJRChMYW5nSUQpID09IExBTkdfTkVVVFJBTCkKICAgICAgICByZXR1cm4gVFJVRTsgLyogY29udGludWUgc2VhcmNoICovCgogICAgYnVmX2xhbmd1YWdlWzBdID0gMDsKICAgIGJ1Zl9jb3VudHJ5WzBdID0gMDsKCiAgICBHZXRMb2NhbGVJbmZvVyhsY2lkLCBMT0NBTEVfU0lTTzYzOUxBTkdOQU1FfExPQ0FMRV9OT1VTRVJPVkVSUklERSwKICAgICAgICAgICAgICAgICAgIGJ1Zl9sYW5ndWFnZSwgc2l6ZW9mKGJ1Zl9sYW5ndWFnZSkvc2l6ZW9mKFdDSEFSKSk7CiAgICBHZXRMb2NhbGVJbmZvVyhsY2lkLCBMT0NBTEVfU0lTTzMxNjZDVFJZTkFNRXxMT0NBTEVfTk9VU0VST1ZFUlJJREUsCiAgICAgICAgICAgICAgICAgICBidWZfY291bnRyeSwgc2l6ZW9mKGJ1Zl9jb3VudHJ5KS9zaXplb2YoV0NIQVIpKTsKCiAgICBpZihsX2RhdGEtPmxhbmdbMF0gJiYgIXN0cmNtcGlXKGxfZGF0YS0+bGFuZywgYnVmX2xhbmd1YWdlKSkKICAgIHsKICAgICAgICBpZihsX2RhdGEtPmNvdW50cnlbMF0pCiAgICAgICAgewogICAgICAgICAgICBpZighc3RyY21waVcobF9kYXRhLT5jb3VudHJ5LCBidWZfY291bnRyeSkpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGxfZGF0YS0+Zm91bmRfbGFuZ19pZFswXSA9IExhbmdJRDsKICAgICAgICAgICAgICAgIGxfZGF0YS0+bl9mb3VuZCA9IDE7CiAgICAgICAgICAgICAgICBUUkFDRSgiRm91bmQgaWQgJTA0WCBmb3IgbGFuZyAlcyBjb3VudHJ5ICVzXG4iLAogICAgICAgICAgICAgICAgICAgICAgTGFuZ0lELCBkZWJ1Z3N0cl93KGxfZGF0YS0+bGFuZyksIGRlYnVnc3RyX3cobF9kYXRhLT5jb3VudHJ5KSk7CiAgICAgICAgICAgICAgICByZXR1cm4gRkFMU0U7IC8qIHN0b3AgZW51bWVyYXRpb24gKi8KICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBlbHNlIGdvdG8gZm91bmQ7IC8qIGxfZGF0YS0+Y291bnRyeSBub3Qgc3BlY2lmaWVkICovCiAgICB9CgogICAgLyogSnVzdCBpbiBjYXNlLCBjaGVjayBMT0NBTEVfU0VOR0xBTkdVQUdFIHRvbywKICAgICAqIGluIGhvcGUgdGhhdCBwb3NzaWJsZSBhbGlhcyBuYW1lIG1pZ2h0IGhhdmUgdGhhdCB2YWx1ZS4KICAgICAqLwogICAgYnVmX2VuX2xhbmd1YWdlWzBdID0gMDsKICAgIEdldExvY2FsZUluZm9XKGxjaWQsIExPQ0FMRV9TRU5HTEFOR1VBR0V8TE9DQUxFX05PVVNFUk9WRVJSSURFLAogICAgICAgICAgICAgICAgICAgYnVmX2VuX2xhbmd1YWdlLCBzaXplb2YoYnVmX2VuX2xhbmd1YWdlKS9zaXplb2YoV0NIQVIpKTsKCiAgICBpZihsX2RhdGEtPmxhbmdbMF0gJiYgIXN0cmNtcGlXKGxfZGF0YS0+bGFuZywgYnVmX2VuX2xhbmd1YWdlKSkgZ290byBmb3VuZDsKICAgIHJldHVybiBUUlVFOyAgLyogbm90IGZvdW5kLCBjb250aW51ZSBzZWFyY2ggKi8KCmZvdW5kOgogICAgbF9kYXRhLT5mb3VuZF9sYW5nX2lkW2xfZGF0YS0+bl9mb3VuZF0gPSBMYW5nSUQ7CiAgICBzdHJuY3B5VyhsX2RhdGEtPmZvdW5kX2NvdW50cnlbbF9kYXRhLT5uX2ZvdW5kXSwgYnVmX2NvdW50cnksIDMpOwogICAgc3RybmNweVcobF9kYXRhLT5mb3VuZF9sYW5ndWFnZVtsX2RhdGEtPm5fZm91bmRdLCBidWZfbGFuZ3VhZ2UsIDMpOwogICAgbF9kYXRhLT5uX2ZvdW5kKys7CiAgICBUUkFDRSgiRm91bmQgaWQgJTA0WCBmb3IgbGFuZyAlc1xuIiwgTGFuZ0lELCBkZWJ1Z3N0cl93KGxfZGF0YS0+bGFuZykpOwogICAgcmV0dXJuIChsX2RhdGEtPm5fZm91bmQgPCBOTFNfTUFYX0xBTkdVQUdFUyk7IC8qIGNvbnRpbnVlIHNlYXJjaCwgdW5sZXNzIHdlIGhhdmUgZW5vdWdoICovCn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICAgICAgIGdldF9sYW5ndWFnZV9pZAogKgogKiBJTlBVVDoKICoJTGFuZzogYSBzdHJpbmcgd2hvc2UgdHdvIGZpcnN0IGNoYXJzIGFyZSB0aGUgaXNvIG5hbWUgb2YgYSBsYW5ndWFnZS4KICoJQ291bnRyeTogYSBzdHJpbmcgd2hvc2UgdHdvIGZpcnN0IGNoYXJzIGFyZSB0aGUgaXNvIG5hbWUgb2YgY291bnRyeQogKglDaGFyc2V0OiBhIHN0cmluZyBkZWZpbmluZyB0aGUgY2hvc2VuIGNoYXJzZXQgZW5jb2RpbmcKICoJRGlhbGVjdDogYSBzdHJpbmcgZGVmaW5pbmcgYSB2YXJpYXRpb24gb2YgdGhlIGxvY2FsZQogKgogKglhbGwgdGhvc2UgdmFsdWVzIGFyZSBmcm9tIHRoZSBzdGFuZGFyZGl6ZWQgZm9ybWF0IG9mIGxvY2FsZQogKgluYW1lIGluIHVuaXggd2hpY2ggaXM6IExhbmdbX0NvdW50cnldWy5DaGFyc2V0XVtARGlhbGVjdF0KICoKICogUkVUVVJOUzoKICoJdGhlIG51bWVyaWMgY29kZSBvZiB0aGUgbGFuZ3VhZ2UgdXNlZCBieSBXaW5kb3dzCiAqCiAqIEZJWE1FOiBDaGFyc2V0IGFuZCBEaWFsZWN0IGFyZSBub3QgaGFuZGxlZAogKi8Kc3RhdGljIExBTkdJRCBnZXRfbGFuZ3VhZ2VfaWQoTFBDU1RSIExhbmcsIExQQ1NUUiBDb3VudHJ5LCBMUENTVFIgQ2hhcnNldCwgTFBDU1RSIERpYWxlY3QpCnsKICAgIExBTkdfRklORF9EQVRBIGxfZGF0YTsKCiAgICBpZighTGFuZykKICAgIHsKICAgICAgICBsX2RhdGEuZm91bmRfbGFuZ19pZFswXSA9IE1BS0VMQU5HSUQoTEFOR19FTkdMSVNILCBTVUJMQU5HX0RFRkFVTFQpOwogICAgICAgIGdvdG8gRU5EOwogICAgfQoKICAgIGxfZGF0YS5uX2ZvdW5kID0gMDsKICAgIHN0cmNweW5BdG9XKGxfZGF0YS5sYW5nLCBMYW5nLCBzaXplb2YobF9kYXRhLmxhbmcpKTsKCiAgICBpZiAoQ291bnRyeSkgc3RyY3B5bkF0b1cobF9kYXRhLmNvdW50cnksIENvdW50cnksIHNpemVvZihsX2RhdGEuY291bnRyeSkpOwogICAgZWxzZSBsX2RhdGEuY291bnRyeVswXSA9IDA7CgogICAgRW51bVJlc291cmNlTGFuZ3VhZ2VzVyhrZXJuZWwzMl9oYW5kbGUsIChMUENXU1RSKVJUX1NUUklORywgKExQQ1dTVFIpTE9DQUxFX0lMQU5HVUFHRSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluZF9sYW5ndWFnZV9pZF9wcm9jLCAoTFBBUkFNKSZsX2RhdGEpOwoKICAgIGlmIChsX2RhdGEubl9mb3VuZCA9PSAxKSBnb3RvIEVORDsKCiAgICBpZighbF9kYXRhLm5fZm91bmQpCiAgICB7CiAgICAgICAgaWYobF9kYXRhLmNvdW50cnlbMF0pCiAgICAgICAgewogICAgICAgICAgICAvKiByZXRyeSB3aXRob3V0IGNvdW50cnkgbmFtZSAqLwogICAgICAgICAgICBsX2RhdGEuY291bnRyeVswXSA9IDA7CiAgICAgICAgICAgIEVudW1SZXNvdXJjZUxhbmd1YWdlc1coa2VybmVsMzJfaGFuZGxlLCAoTFBDV1NUUilSVF9TVFJJTkcsIChMUENXU1RSKUxPQ0FMRV9JTEFOR1VBR0UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluZF9sYW5ndWFnZV9pZF9wcm9jLCAoTE9ORykmbF9kYXRhKTsKICAgICAgICAgICAgaWYgKCFsX2RhdGEubl9mb3VuZCkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgTUVTU0FHRSgiV2FybmluZzogTGFuZ3VhZ2UgJyVzXyVzJyB3YXMgbm90IHJlY29nbml6ZWQsIGRlZmF1bHRpbmcgdG8gRW5nbGlzaC5cbiIsCiAgICAgICAgICAgICAgICAgICAgICAgIExhbmcsIENvdW50cnkpOwogICAgICAgICAgICAgICAgbF9kYXRhLmZvdW5kX2xhbmdfaWRbMF0gPSBNQUtFTEFOR0lEKExBTkdfRU5HTElTSCwgU1VCTEFOR19ERUZBVUxUKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBlbHNlIE1FU1NBR0UoIldhcm5pbmc6IExhbmd1YWdlICclc18lcycgd2FzIG5vdCByZWNvZ25pemVkLCBkZWZhdWx0aW5nIHRvICclcycuXG4iLAogICAgICAgICAgICAgICAgICAgICAgICAgTGFuZywgQ291bnRyeSwgZGVidWdzdHJfbGFuZyhsX2RhdGEuZm91bmRfbGFuZ19pZFswXSkgKTsKICAgICAgICB9CiAgICAgICAgZWxzZQogICAgICAgIHsKICAgICAgICAgICAgTUVTU0FHRSgiV2FybmluZzogTGFuZ3VhZ2UgJyVzJyB3YXMgbm90IHJlY29nbml6ZWQsIGRlZmF1bHRpbmcgdG8gRW5nbGlzaC5cbiIsIExhbmcpOwogICAgICAgICAgICBsX2RhdGEuZm91bmRfbGFuZ19pZFswXSA9IE1BS0VMQU5HSUQoTEFOR19FTkdMSVNILCBTVUJMQU5HX0RFRkFVTFQpOwogICAgICAgIH0KICAgIH0KICAgIGVsc2UKICAgIHsKICAgICAgICBpbnQgaTsKCiAgICAgICAgaWYgKENvdW50cnkgJiYgQ291bnRyeVswXSkKICAgICAgICAgICAgTUVTU0FHRSgiRm9yIGxhbmd1YWdlICclc18lcycgc2V2ZXJhbCBsYW5ndWFnZSBpZHMgd2VyZSBmb3VuZDpcbiIsIExhbmcsIENvdW50cnkpOwogICAgICAgIGVsc2UKICAgICAgICAgICAgTUVTU0FHRSgiRm9yIGxhbmd1YWdlICclcycgc2V2ZXJhbCBsYW5ndWFnZSBpZHMgd2VyZSBmb3VuZDpcbiIsIExhbmcpOwoKICAgICAgICAvKiBwcmludCBhIGxpc3Qgb2YgbGFuZ3VhZ2VzIHdpdGggdGhlaXIgZGVzY3JpcHRpb24gKi8KICAgICAgICBmb3IgKGkgPSAwOyBpIDwgbF9kYXRhLm5fZm91bmQ7IGkrKykKICAgICAgICB7CiAgICAgICAgICAgIFdDSEFSIGJ1ZmZXWzEyOF07CiAgICAgICAgICAgIGNoYXIgYnVmZkFbMTI4XTsKICAgICAgICAgICAgR2V0TG9jYWxlSW5mb1coIE1BS0VMQ0lEKCBsX2RhdGEuZm91bmRfbGFuZ19pZFtpXSwgU09SVF9ERUZBVUxUICksCiAgICAgICAgICAgICAgICAgICAgICAgICAgIExPQ0FMRV9TTEFOR1VBR0V8TE9DQUxFX05PVVNFUk9WRVJSSURFLCBidWZmVywgc2l6ZW9mKGJ1ZmZXKS9zaXplb2YoV0NIQVIpKTsKICAgICAgICAgICAgc3RyY3B5V3RvQSggYnVmZkEsIGJ1ZmZXICk7CiAgICAgICAgICAgIE1FU1NBR0UoICIgICAlcyAoJTA0WCkgLSAlc1xuIiwgZGVidWdzdHJfbGFuZyhsX2RhdGEuZm91bmRfbGFuZ19pZFtpXSksCiAgICAgICAgICAgICAgICAgICAgIGxfZGF0YS5mb3VuZF9sYW5nX2lkW2ldLCBidWZmQSApOwogICAgICAgIH0KICAgICAgICBNRVNTQUdFKCJEZWZhdWx0aW5nIHRvICclcycuIFlvdSBzaG91bGQgc3BlY2lmeSB0aGUgZXhhY3QgbGFuZ3VhZ2UgeW91IHdhbnRcbiIKICAgICAgICAgICAgICAgICJieSBkZWZpbmluZyB5b3VyIExBTkcgZW52aXJvbm1lbnQgdmFyaWFibGUgbGlrZSB0aGlzOiBMQU5HPSVzXG4iLAogICAgICAgICAgICAgICAgZGVidWdzdHJfbGFuZyhsX2RhdGEuZm91bmRfbGFuZ19pZFswXSksIGRlYnVnc3RyX2xhbmcobF9kYXRhLmZvdW5kX2xhbmdfaWRbMF0pICk7CiAgICB9CkVORDoKICAgIFRSQUNFKCJSZXR1cm5pbmcgJTA0WCAoJXMpXG4iLCBsX2RhdGEuZm91bmRfbGFuZ19pZFswXSwgZGVidWdzdHJfbGFuZyhsX2RhdGEuZm91bmRfbGFuZ19pZFswXSkpOwogICAgcmV0dXJuIGxfZGF0YS5mb3VuZF9sYW5nX2lkWzBdOwp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgICAgICAgICBjaGFyc2V0X2NtcCAoaW50ZXJuYWwpCiAqLwpzdGF0aWMgaW50IGNoYXJzZXRfY21wKCBjb25zdCB2b2lkICpuYW1lLCBjb25zdCB2b2lkICplbnRyeSApCnsKICAgIGNvbnN0IHN0cnVjdCBjaGFyc2V0X2VudHJ5ICpjaGFyc2V0ID0gKGNvbnN0IHN0cnVjdCBjaGFyc2V0X2VudHJ5ICopZW50cnk7CiAgICByZXR1cm4gc3RyY2FzZWNtcCggKGNvbnN0IGNoYXIgKiluYW1lLCBjaGFyc2V0LT5jaGFyc2V0X25hbWUgKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCQlnZXRfZW52X2xjaWQKICovCnN0YXRpYyBMQ0lEIGdldF9lbnZfbGNpZCggVUlOVCAqdW5peF9jcCwgY29uc3QgY2hhciAqZW52X3N0ciApCnsKICAgIGNoYXIgKmJ1ZiwgKmxhbmcsKmNvdW50cnksKmNoYXJzZXQsKmRpYWxlY3QsKm5leHQ7CiAgICBMQ0lEIHJldCA9IDA7CgogICAgaWYgKChsYW5nID0gZ2V0ZW52KCAiTENfQUxMIiApKSB8fAogICAgICAgIChlbnZfc3RyICYmIChsYW5nID0gZ2V0ZW52KCBlbnZfc3RyICkpKSB8fAogICAgICAgIChsYW5nID0gZ2V0ZW52KCAiTEFORyIgKSkpCiAgICB7CiAgICAgICAgaWYgKCFzdHJjbXAobGFuZywiUE9TSVgiKSB8fCAhc3RyY21wKGxhbmcsIkMiKSkgZ290byBkb25lOwoKICAgICAgICBidWYgPSBSdGxBbGxvY2F0ZUhlYXAoIEdldFByb2Nlc3NIZWFwKCksIDAsIHN0cmxlbihsYW5nKSArIDEgKTsKICAgICAgICBzdHJjcHkoIGJ1ZiwgbGFuZyApOwogICAgICAgIGxhbmc9YnVmOwoKICAgICAgICBkbyB7CiAgICAgICAgICAgIG5leHQ9c3RyY2hyKGxhbmcsJzonKTsgaWYgKG5leHQpICpuZXh0Kys9J1wwJzsKICAgICAgICAgICAgZGlhbGVjdD1zdHJjaHIobGFuZywnQCcpOyBpZiAoZGlhbGVjdCkgKmRpYWxlY3QrKz0nXDAnOwogICAgICAgICAgICBjaGFyc2V0PXN0cmNocihsYW5nLCcuJyk7IGlmIChjaGFyc2V0KSAqY2hhcnNldCsrPSdcMCc7CiAgICAgICAgICAgIGNvdW50cnk9c3RyY2hyKGxhbmcsJ18nKTsgaWYgKGNvdW50cnkpICpjb3VudHJ5Kys9J1wwJzsKCiAgICAgICAgICAgIHJldCA9IGdldF9sYW5ndWFnZV9pZChsYW5nLCBjb3VudHJ5LCBjaGFyc2V0LCBkaWFsZWN0KTsKICAgICAgICAgICAgaWYgKHJldCAmJiBjaGFyc2V0ICYmIHVuaXhfY3ApCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGNvbnN0IHN0cnVjdCBjaGFyc2V0X2VudHJ5ICplbnRyeTsKICAgICAgICAgICAgICAgIGNoYXIgY2hhcnNldF9uYW1lWzE2XTsKICAgICAgICAgICAgICAgIHNpemVfdCBpLCBqOwoKICAgICAgICAgICAgICAgIC8qIHJlbW92ZSBwdW5jdHVhdGlvbiBjaGFyYWN0ZXJzIGZyb20gY2hhcnNldCBuYW1lICovCiAgICAgICAgICAgICAgICBmb3IgKGkgPSBqID0gMDsgY2hhcnNldFtpXSAmJiBqIDwgc2l6ZW9mKGNoYXJzZXRfbmFtZSktMTsgaSsrKQogICAgICAgICAgICAgICAgICAgIGlmIChpc2FsbnVtKGNoYXJzZXRbaV0pKSBjaGFyc2V0X25hbWVbaisrXSA9IGNoYXJzZXRbaV07CiAgICAgICAgICAgICAgICBjaGFyc2V0X25hbWVbal0gPSAwOwoKICAgICAgICAgICAgICAgIGVudHJ5ID0gYnNlYXJjaCggY2hhcnNldF9uYW1lLCBjaGFyc2V0X25hbWVzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzaXplb2YoY2hhcnNldF9uYW1lcykvc2l6ZW9mKGNoYXJzZXRfbmFtZXNbMF0pLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzaXplb2YoY2hhcnNldF9uYW1lc1swXSksIGNoYXJzZXRfY21wICk7CiAgICAgICAgICAgICAgICBpZiAoZW50cnkpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgKnVuaXhfY3AgPSBlbnRyeS0+Y29kZXBhZ2U7CiAgICAgICAgICAgICAgICAgICAgVFJBQ0UoImNoYXJzZXQgJXMgd2FzIG1hcHBlZCB0byBjcCAldVxuIiwgY2hhcnNldCwgKnVuaXhfY3ApOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgICAgIEZJWE1FKCJjaGFyc2V0ICVzIHdhcyBub3QgcmVjb2duaXplZFxuIiwgY2hhcnNldCk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGxhbmc9bmV4dDsKICAgICAgICB9IHdoaWxlIChsYW5nICYmICFyZXQpOwoKICAgICAgICBpZiAoIXJldCkgTUVTU0FHRSgiV2FybmluZzogbGFuZ3VhZ2UgJyVzJyBub3QgcmVjb2duaXplZCwgZGVmYXVsdGluZyB0byBFbmdsaXNoXG4iLCBidWYpOwogICAgICAgIFJ0bEZyZWVIZWFwKCBHZXRQcm9jZXNzSGVhcCgpLCAwLCBidWYgKTsKICAgIH0KCiBkb25lOgogICAgaWYgKCFyZXQpIHJldCA9IE1BS0VMQ0lEKCBNQUtFTEFOR0lEKExBTkdfRU5HTElTSCxTVUJMQU5HX0RFRkFVTFQpLCBTT1JUX0RFRkFVTFQpIDsKICAgIHJldHVybiByZXQ7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCUdldFVzZXJEZWZhdWx0TGFuZ0lEIChLRVJORUwzMi5AKQogKgogKiBHZXQgdGhlIGRlZmF1bHQgbGFuZ3VhZ2UgSWQgZm9yIHRoZSBjdXJyZW50IHVzZXIuCiAqCiAqIFBBUkFNUwogKiAgTm9uZS4KICoKICogUkVUVVJOUwogKiAgVGhlIGN1cnJlbnQgTEFOR0lEIG9mIHRoZSBkZWZhdWx0IGxhbmd1YWdlIGZvciB0aGUgY3VycmVudCB1c2VyLgogKi8KTEFOR0lEIFdJTkFQSSBHZXRVc2VyRGVmYXVsdExhbmdJRCh2b2lkKQp7CiAgICByZXR1cm4gTEFOR0lERlJPTUxDSUQoR2V0VXNlckRlZmF1bHRMQ0lEKCkpOwp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCQlHZXRTeXN0ZW1EZWZhdWx0TGFuZ0lEIChLRVJORUwzMi5AKQogKgogKiBHZXQgdGhlIGRlZmF1bHQgbGFuZ3VhZ2UgSWQgZm9yIHRoZSBzeXN0ZW0uCiAqCiAqIFBBUkFNUwogKiAgTm9uZS4KICoKICogUkVUVVJOUwogKiAgVGhlIGN1cnJlbnQgTEFOR0lEIG9mIHRoZSBkZWZhdWx0IGxhbmd1YWdlIGZvciB0aGUgc3lzdGVtLgogKi8KTEFOR0lEIFdJTkFQSSBHZXRTeXN0ZW1EZWZhdWx0TGFuZ0lEKHZvaWQpCnsKICAgIHJldHVybiBMQU5HSURGUk9NTENJRChHZXRTeXN0ZW1EZWZhdWx0TENJRCgpKTsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJR2V0VXNlckRlZmF1bHRMQ0lEIChLRVJORUwzMi5AKQogKgogKiBHZXQgdGhlIGRlZmF1bHQgbG9jYWxlIElkIGZvciB0aGUgY3VycmVudCB1c2VyLgogKgogKiBQQVJBTVMKICogIE5vbmUuCiAqCiAqIFJFVFVSTlMKICogIFRoZSBjdXJyZW50IExDSUQgb2YgdGhlIGRlZmF1bHQgbG9jYWxlIGZvciB0aGUgY3VycmVudCB1c2VyLgogKi8KTENJRCBXSU5BUEkgR2V0VXNlckRlZmF1bHRMQ0lEKHZvaWQpCnsKICAgIExDSUQgbGNpZDsKICAgIE50UXVlcnlEZWZhdWx0TG9jYWxlKCBUUlVFLCAmbGNpZCApOwogICAgcmV0dXJuIGxjaWQ7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCUdldFN5c3RlbURlZmF1bHRMQ0lEIChLRVJORUwzMi5AKQogKgogKiBHZXQgdGhlIGRlZmF1bHQgbG9jYWxlIElkIGZvciB0aGUgc3lzdGVtLgogKgogKiBQQVJBTVMKICogIE5vbmUuCiAqCiAqIFJFVFVSTlMKICogIFRoZSBjdXJyZW50IExDSUQgb2YgdGhlIGRlZmF1bHQgbG9jYWxlIGZvciB0aGUgc3lzdGVtLgogKi8KTENJRCBXSU5BUEkgR2V0U3lzdGVtRGVmYXVsdExDSUQodm9pZCkKewogICAgTENJRCBsY2lkOwogICAgTnRRdWVyeURlZmF1bHRMb2NhbGUoIEZBTFNFLCAmbGNpZCApOwogICAgcmV0dXJuIGxjaWQ7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCUdldFVzZXJEZWZhdWx0VUlMYW5ndWFnZSAoS0VSTkVMMzIuQCkKICoKICogR2V0IHRoZSBkZWZhdWx0IHVzZXIgaW50ZXJmYWNlIGxhbmd1YWdlIElkIGZvciB0aGUgY3VycmVudCB1c2VyLgogKgogKiBQQVJBTVMKICogIE5vbmUuCiAqCiAqIFJFVFVSTlMKICogIFRoZSBjdXJyZW50IExBTkdJRCBvZiB0aGUgZGVmYXVsdCBVSSBsYW5ndWFnZSBmb3IgdGhlIGN1cnJlbnQgdXNlci4KICovCkxBTkdJRCBXSU5BUEkgR2V0VXNlckRlZmF1bHRVSUxhbmd1YWdlKHZvaWQpCnsKICAgIExBTkdJRCBsYW5nOwogICAgTnRRdWVyeURlZmF1bHRVSUxhbmd1YWdlKCAmbGFuZyApOwogICAgcmV0dXJuIGxhbmc7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCUdldFN5c3RlbURlZmF1bHRVSUxhbmd1YWdlIChLRVJORUwzMi5AKQogKgogKiBHZXQgdGhlIGRlZmF1bHQgdXNlciBpbnRlcmZhY2UgbGFuZ3VhZ2UgSWQgZm9yIHRoZSBzeXN0ZW0uCiAqCiAqIFBBUkFNUwogKiAgTm9uZS4KICoKICogUkVUVVJOUwogKiAgVGhlIGN1cnJlbnQgTEFOR0lEIG9mIHRoZSBkZWZhdWx0IFVJIGxhbmd1YWdlIGZvciB0aGUgc3lzdGVtLiBUaGlzIGlzCiAqICB0eXBpY2FsbHkgdGhlIHNhbWUgbGFuZ3VhZ2UgdXNlZCBkdXJpbmcgdGhlIGluc3RhbGxhdGlvbiBwcm9jZXNzLgogKi8KTEFOR0lEIFdJTkFQSSBHZXRTeXN0ZW1EZWZhdWx0VUlMYW5ndWFnZSh2b2lkKQp7CiAgICBMQU5HSUQgbGFuZzsKICAgIE50UXVlcnlJbnN0YWxsVUlMYW5ndWFnZSggJmxhbmcgKTsKICAgIHJldHVybiBsYW5nOwp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJZ2V0X2xvY2FsZV92YWx1ZV9uYW1lCiAqCiAqIEdldHMgdGhlIHJlZ2lzdHJ5IHZhbHVlIG5hbWUgZm9yIGEgZ2l2ZW4gbGN0eXBlLgogKi8Kc3RhdGljIGNvbnN0IFdDSEFSICpnZXRfbG9jYWxlX3ZhbHVlX25hbWUoIERXT1JEIGxjdHlwZSApCnsKICAgIHN0YXRpYyBjb25zdCBXQ0hBUiBpQ2FsZW5kYXJUeXBlV1tdID0geydpJywnQycsJ2EnLCdsJywnZScsJ24nLCdkJywnYScsJ3InLCdUJywneScsJ3AnLCdlJywwfTsKICAgIHN0YXRpYyBjb25zdCBXQ0hBUiBpQ291bnRyeVdbXSA9IHsnaScsJ0MnLCdvJywndScsJ24nLCd0JywncicsJ3knLDB9OwogICAgc3RhdGljIGNvbnN0IFdDSEFSIGlDdXJyRGlnaXRzV1tdID0geydpJywnQycsJ3UnLCdyJywncicsJ0QnLCdpJywnZycsJ2knLCd0JywncycsMH07CiAgICBzdGF0aWMgY29uc3QgV0NIQVIgaUN1cnJlbmN5V1tdID0geydpJywnQycsJ3UnLCdyJywncicsJ2UnLCduJywnYycsJ3knLDB9OwogICAgc3RhdGljIGNvbnN0IFdDSEFSIGlEYXRlV1tdID0geydpJywnRCcsJ2EnLCd0JywnZScsMH07CiAgICBzdGF0aWMgY29uc3QgV0NIQVIgaURpZ2l0c1dbXSA9IHsnaScsJ0QnLCdpJywnZycsJ2knLCd0JywncycsMH07CiAgICBzdGF0aWMgY29uc3QgV0NIQVIgaUZpcnN0RGF5T2ZXZWVrV1tdID0geydpJywnRicsJ2knLCdyJywncycsJ3QnLCdEJywnYScsJ3knLCdPJywnZicsJ1cnLCdlJywnZScsJ2snLDB9OwogICAgc3RhdGljIGNvbnN0IFdDSEFSIGlGaXJzdFdlZWtPZlllYXJXW10gPSB7J2knLCdGJywnaScsJ3InLCdzJywndCcsJ1cnLCdlJywnZScsJ2snLCdPJywnZicsJ1knLCdlJywnYScsJ3InLDB9OwogICAgc3RhdGljIGNvbnN0IFdDSEFSIGlMRGF0ZVdbXSA9IHsnaScsJ0wnLCdEJywnYScsJ3QnLCdlJywwfTsKICAgIHN0YXRpYyBjb25zdCBXQ0hBUiBpTFplcm9XW10gPSB7J2knLCdMJywnWicsJ2UnLCdyJywnbycsMH07CiAgICBzdGF0aWMgY29uc3QgV0NIQVIgaU1lYXN1cmVXW10gPSB7J2knLCdNJywnZScsJ2EnLCdzJywndScsJ3InLCdlJywwfTsKICAgIHN0YXRpYyBjb25zdCBXQ0hBUiBpTmVnQ3VycldbXSA9IHsnaScsJ04nLCdlJywnZycsJ0MnLCd1JywncicsJ3InLDB9OwogICAgc3RhdGljIGNvbnN0IFdDSEFSIGlOZWdOdW1iZXJXW10gPSB7J2knLCdOJywnZScsJ2cnLCdOJywndScsJ20nLCdiJywnZScsJ3InLDB9OwogICAgc3RhdGljIGNvbnN0IFdDSEFSIGlQYXBlclNpemVXW10gPSB7J2knLCdQJywnYScsJ3AnLCdlJywncicsJ1MnLCdpJywneicsJ2UnLDB9OwogICAgc3RhdGljIGNvbnN0IFdDSEFSIGlUTFplcm9XW10gPSB7J2knLCdUJywnTCcsJ1onLCdlJywncicsJ28nLDB9OwogICAgc3RhdGljIGNvbnN0IFdDSEFSIGlUaW1lUHJlZml4V1tdID0geydpJywnVCcsJ2knLCdtJywnZScsJ1AnLCdyJywnZScsJ2YnLCdpJywneCcsMH07CiAgICBzdGF0aWMgY29uc3QgV0NIQVIgaVRpbWVXW10gPSB7J2knLCdUJywnaScsJ20nLCdlJywwfTsKICAgIHN0YXRpYyBjb25zdCBXQ0hBUiBzMTE1OVdbXSA9IHsncycsJzEnLCcxJywnNScsJzknLDB9OwogICAgc3RhdGljIGNvbnN0IFdDSEFSIHMyMzU5V1tdID0geydzJywnMicsJzMnLCc1JywnOScsMH07CiAgICBzdGF0aWMgY29uc3QgV0NIQVIgc0NvdW50cnlXW10gPSB7J3MnLCdDJywnbycsJ3UnLCduJywndCcsJ3InLCd5JywwfTsKICAgIHN0YXRpYyBjb25zdCBXQ0hBUiBzQ3VycmVuY3lXW10gPSB7J3MnLCdDJywndScsJ3InLCdyJywnZScsJ24nLCdjJywneScsMH07CiAgICBzdGF0aWMgY29uc3QgV0NIQVIgc0RhdGVXW10gPSB7J3MnLCdEJywnYScsJ3QnLCdlJywwfTsKICAgIHN0YXRpYyBjb25zdCBXQ0hBUiBzRGVjaW1hbFdbXSA9IHsncycsJ0QnLCdlJywnYycsJ2knLCdtJywnYScsJ2wnLDB9OwogICAgc3RhdGljIGNvbnN0IFdDSEFSIHNHcm91cGluZ1dbXSA9IHsncycsJ0cnLCdyJywnbycsJ3UnLCdwJywnaScsJ24nLCdnJywwfTsKICAgIHN0YXRpYyBjb25zdCBXQ0hBUiBzTGFuZ3VhZ2VXW10gPSB7J3MnLCdMJywnYScsJ24nLCdnJywndScsJ2EnLCdnJywnZScsMH07CiAgICBzdGF0aWMgY29uc3QgV0NIQVIgc0xpc3RXW10gPSB7J3MnLCdMJywnaScsJ3MnLCd0JywwfTsKICAgIHN0YXRpYyBjb25zdCBXQ0hBUiBzTG9uZ0RhdGVXW10gPSB7J3MnLCdMJywnbycsJ24nLCdnJywnRCcsJ2EnLCd0JywnZScsMH07CiAgICBzdGF0aWMgY29uc3QgV0NIQVIgc01vbkRlY2ltYWxTZXBXW10gPSB7J3MnLCdNJywnbycsJ24nLCdEJywnZScsJ2MnLCdpJywnbScsJ2EnLCdsJywnUycsJ2UnLCdwJywwfTsKICAgIHN0YXRpYyBjb25zdCBXQ0hBUiBzTW9uR3JvdXBpbmdXW10gPSB7J3MnLCdNJywnbycsJ24nLCdHJywncicsJ28nLCd1JywncCcsJ2knLCduJywnZycsMH07CiAgICBzdGF0aWMgY29uc3QgV0NIQVIgc01vblRob3VzYW5kU2VwV1tdID0geydzJywnTScsJ28nLCduJywnVCcsJ2gnLCdvJywndScsJ3MnLCdhJywnbicsJ2QnLCdTJywnZScsJ3AnLDB9OwogICAgc3RhdGljIGNvbnN0IFdDSEFSIHNOYXRpdmVEaWdpdHNXW10gPSB7J3MnLCdOJywnYScsJ3QnLCdpJywndicsJ2UnLCdEJywnaScsJ2cnLCdpJywndCcsJ3MnLDB9OwogICAgc3RhdGljIGNvbnN0IFdDSEFSIHNOZWdhdGl2ZVNpZ25XW10gPSB7J3MnLCdOJywnZScsJ2cnLCdhJywndCcsJ2knLCd2JywnZScsJ1MnLCdpJywnZycsJ24nLDB9OwogICAgc3RhdGljIGNvbnN0IFdDSEFSIHNQb3NpdGl2ZVNpZ25XW10gPSB7J3MnLCdQJywnbycsJ3MnLCdpJywndCcsJ2knLCd2JywnZScsJ1MnLCdpJywnZycsJ24nLDB9OwogICAgc3RhdGljIGNvbnN0IFdDSEFSIHNTaG9ydERhdGVXW10gPSB7J3MnLCdTJywnaCcsJ28nLCdyJywndCcsJ0QnLCdhJywndCcsJ2UnLDB9OwogICAgc3RhdGljIGNvbnN0IFdDSEFSIHNUaG91c2FuZFdbXSA9IHsncycsJ1QnLCdoJywnbycsJ3UnLCdzJywnYScsJ24nLCdkJywwfTsKICAgIHN0YXRpYyBjb25zdCBXQ0hBUiBzVGltZUZvcm1hdFdbXSA9IHsncycsJ1QnLCdpJywnbScsJ2UnLCdGJywnbycsJ3InLCdtJywnYScsJ3QnLDB9OwogICAgc3RhdGljIGNvbnN0IFdDSEFSIHNUaW1lV1tdID0geydzJywnVCcsJ2knLCdtJywnZScsMH07CiAgICBzdGF0aWMgY29uc3QgV0NIQVIgc1llYXJNb250aFdbXSA9IHsncycsJ1knLCdlJywnYScsJ3InLCdNJywnbycsJ24nLCd0JywnaCcsMH07CiAgICBzdGF0aWMgY29uc3QgV0NIQVIgTnVtU2hhcGVXW10gPSB7J04nLCd1JywnbScsJ3MnLCdoJywnYScsJ3AnLCdlJywwfTsKCiAgICBzd2l0Y2ggKGxjdHlwZSkKICAgIHsKICAgIC8qIFRoZXNlIHZhbHVlcyBhcmUgdXNlZCBieSBTZXRMb2NhbGVJbmZvIGFuZCBHZXRMb2NhbGVJbmZvLCBhbmQKICAgICAqIHRoZSB2YWx1ZXMgYXJlIHN0b3JlZCBpbiB0aGUgcmVnaXN0cnksIGNvbmZpcm1lZCB1bmRlciBXaW5kb3dzLgogICAgICovCiAgICBjYXNlIExPQ0FMRV9JQ0FMRU5EQVJUWVBFOiAgICByZXR1cm4gaUNhbGVuZGFyVHlwZVc7CiAgICBjYXNlIExPQ0FMRV9JQ1VSUkRJR0lUUzogICAgICByZXR1cm4gaUN1cnJEaWdpdHNXOwogICAgY2FzZSBMT0NBTEVfSUNVUlJFTkNZOiAgICAgICAgcmV0dXJuIGlDdXJyZW5jeVc7CiAgICBjYXNlIExPQ0FMRV9JRElHSVRTOiAgICAgICAgICByZXR1cm4gaURpZ2l0c1c7CiAgICBjYXNlIExPQ0FMRV9JRklSU1REQVlPRldFRUs6ICByZXR1cm4gaUZpcnN0RGF5T2ZXZWVrVzsKICAgIGNhc2UgTE9DQUxFX0lGSVJTVFdFRUtPRllFQVI6IHJldHVybiBpRmlyc3RXZWVrT2ZZZWFyVzsKICAgIGNhc2UgTE9DQUxFX0lMWkVSTzogICAgICAgICAgIHJldHVybiBpTFplcm9XOwogICAgY2FzZSBMT0NBTEVfSU1FQVNVUkU6ICAgICAgICAgcmV0dXJuIGlNZWFzdXJlVzsKICAgIGNhc2UgTE9DQUxFX0lORUdDVVJSOiAgICAgICAgIHJldHVybiBpTmVnQ3Vyclc7CiAgICBjYXNlIExPQ0FMRV9JTkVHTlVNQkVSOiAgICAgICByZXR1cm4gaU5lZ051bWJlclc7CiAgICBjYXNlIExPQ0FMRV9JUEFQRVJTSVpFOiAgICAgICByZXR1cm4gaVBhcGVyU2l6ZVc7CiAgICBjYXNlIExPQ0FMRV9JVElNRTogICAgICAgICAgICByZXR1cm4gaVRpbWVXOwogICAgY2FzZSBMT0NBTEVfUzExNTk6ICAgICAgICAgICAgcmV0dXJuIHMxMTU5VzsKICAgIGNhc2UgTE9DQUxFX1MyMzU5OiAgICAgICAgICAgIHJldHVybiBzMjM1OVc7CiAgICBjYXNlIExPQ0FMRV9TQ1VSUkVOQ1k6ICAgICAgICByZXR1cm4gc0N1cnJlbmN5VzsKICAgIGNhc2UgTE9DQUxFX1NEQVRFOiAgICAgICAgICAgIHJldHVybiBzRGF0ZVc7CiAgICBjYXNlIExPQ0FMRV9TREVDSU1BTDogICAgICAgICByZXR1cm4gc0RlY2ltYWxXOwogICAgY2FzZSBMT0NBTEVfU0dST1VQSU5HOiAgICAgICAgcmV0dXJuIHNHcm91cGluZ1c7CiAgICBjYXNlIExPQ0FMRV9TTElTVDogICAgICAgICAgICByZXR1cm4gc0xpc3RXOwogICAgY2FzZSBMT0NBTEVfU0xPTkdEQVRFOiAgICAgICAgcmV0dXJuIHNMb25nRGF0ZVc7CiAgICBjYXNlIExPQ0FMRV9TTU9OREVDSU1BTFNFUDogICByZXR1cm4gc01vbkRlY2ltYWxTZXBXOwogICAgY2FzZSBMT0NBTEVfU01PTkdST1VQSU5HOiAgICAgcmV0dXJuIHNNb25Hcm91cGluZ1c7CiAgICBjYXNlIExPQ0FMRV9TTU9OVEhPVVNBTkRTRVA6ICByZXR1cm4gc01vblRob3VzYW5kU2VwVzsKICAgIGNhc2UgTE9DQUxFX1NORUdBVElWRVNJR046ICAgIHJldHVybiBzTmVnYXRpdmVTaWduVzsKICAgIGNhc2UgTE9DQUxFX1NQT1NJVElWRVNJR046ICAgIHJldHVybiBzUG9zaXRpdmVTaWduVzsKICAgIGNhc2UgTE9DQUxFX1NTSE9SVERBVEU6ICAgICAgIHJldHVybiBzU2hvcnREYXRlVzsKICAgIGNhc2UgTE9DQUxFX1NUSE9VU0FORDogICAgICAgIHJldHVybiBzVGhvdXNhbmRXOwogICAgY2FzZSBMT0NBTEVfU1RJTUU6ICAgICAgICAgICAgcmV0dXJuIHNUaW1lVzsKICAgIGNhc2UgTE9DQUxFX1NUSU1FRk9STUFUOiAgICAgIHJldHVybiBzVGltZUZvcm1hdFc7CiAgICBjYXNlIExPQ0FMRV9TWUVBUk1PTlRIOiAgICAgICByZXR1cm4gc1llYXJNb250aFc7CgogICAgLyogVGhlIGZvbGxvd2luZyBhcmUgbm90IGxpc3RlZCB1bmRlciBNU0ROIGFzIHN1cHBvcnRlZCwKICAgICAqIGJ1dCBzZWVtIHRvIGJlIHVzZWQgYW5kIGFsc28gc3RvcmVkIGluIHRoZSByZWdpc3RyeS4KICAgICAqLwogICAgY2FzZSBMT0NBTEVfSUNPVU5UUlk6ICAgICAgICAgcmV0dXJuIGlDb3VudHJ5VzsKICAgIGNhc2UgTE9DQUxFX0lEQVRFOiAgICAgICAgICAgIHJldHVybiBpRGF0ZVc7CiAgICBjYXNlIExPQ0FMRV9JTERBVEU6ICAgICAgICAgICByZXR1cm4gaUxEYXRlVzsKICAgIGNhc2UgTE9DQUxFX0lUTFpFUk86ICAgICAgICAgIHJldHVybiBpVExaZXJvVzsKICAgIGNhc2UgTE9DQUxFX1NDT1VOVFJZOiAgICAgICAgIHJldHVybiBzQ291bnRyeVc7CiAgICBjYXNlIExPQ0FMRV9TTEFOR1VBR0U6ICAgICAgICByZXR1cm4gc0xhbmd1YWdlVzsKCiAgICAvKiBUaGUgZm9sbG93aW5nIGFyZSB1c2VkIGluIFhQIGFuZCBsYXRlciAqLwogICAgY2FzZSBMT0NBTEVfSURJR0lUU1VCU1RJVFVUSU9OOiByZXR1cm4gTnVtU2hhcGVXOwogICAgY2FzZSBMT0NBTEVfU05BVElWRURJR0lUUzogICAgICByZXR1cm4gc05hdGl2ZURpZ2l0c1c7CiAgICBjYXNlIExPQ0FMRV9JVElNRU1BUktQT1NOOiAgICAgIHJldHVybiBpVGltZVByZWZpeFc7CiAgICB9CiAgICByZXR1cm4gTlVMTDsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCWdldF9yZWdpc3RyeV9sb2NhbGVfaW5mbwogKgogKiBSZXRyaWV2ZSB1c2VyLW1vZGlmaWVkIGxvY2FsZSBpbmZvIGZyb20gdGhlIHJlZ2lzdHJ5LgogKiBSZXR1cm4gbGVuZ3RoLCAwIG9uIGVycm9yLCAtMSBpZiBub3QgZm91bmQuCiAqLwpzdGF0aWMgSU5UIGdldF9yZWdpc3RyeV9sb2NhbGVfaW5mbyggTFBDV1NUUiB2YWx1ZSwgTFBXU1RSIGJ1ZmZlciwgSU5UIGxlbiApCnsKICAgIERXT1JEIHNpemU7CiAgICBJTlQgcmV0OwogICAgSEtFWSBoa2V5OwogICAgTlRTVEFUVVMgc3RhdHVzOwogICAgVU5JQ09ERV9TVFJJTkcgbmFtZVc7CiAgICBLRVlfVkFMVUVfUEFSVElBTF9JTkZPUk1BVElPTiAqaW5mbzsKICAgIHN0YXRpYyBjb25zdCBpbnQgaW5mb19zaXplID0gRklFTERfT0ZGU0VUKEtFWV9WQUxVRV9QQVJUSUFMX0lORk9STUFUSU9OLCBEYXRhKTsKCiAgICBpZiAoIShoa2V5ID0gY3JlYXRlX3JlZ2lzdHJ5X2tleSgpKSkgcmV0dXJuIC0xOwoKICAgIFJ0bEluaXRVbmljb2RlU3RyaW5nKCAmbmFtZVcsIHZhbHVlICk7CiAgICBzaXplID0gaW5mb19zaXplICsgbGVuICogc2l6ZW9mKFdDSEFSKTsKCiAgICBpZiAoIShpbmZvID0gSGVhcEFsbG9jKCBHZXRQcm9jZXNzSGVhcCgpLCAwLCBzaXplICkpKQogICAgewogICAgICAgIE50Q2xvc2UoIGhrZXkgKTsKICAgICAgICBTZXRMYXN0RXJyb3IoIEVSUk9SX05PVF9FTk9VR0hfTUVNT1JZICk7CiAgICAgICAgcmV0dXJuIDA7CiAgICB9CgogICAgc3RhdHVzID0gTnRRdWVyeVZhbHVlS2V5KCBoa2V5LCAmbmFtZVcsIEtleVZhbHVlUGFydGlhbEluZm9ybWF0aW9uLCBpbmZvLCBzaXplLCAmc2l6ZSApOwogICAgaWYgKHN0YXR1cyA9PSBTVEFUVVNfQlVGRkVSX09WRVJGTE9XICYmICFidWZmZXIpIHN0YXR1cyA9IDA7CgogICAgaWYgKCFzdGF0dXMpCiAgICB7CiAgICAgICAgcmV0ID0gKHNpemUgLSBpbmZvX3NpemUpIC8gc2l6ZW9mKFdDSEFSKTsKICAgICAgICAvKiBhcHBlbmQgdGVybWluYXRpbmcgbnVsbCBpZiBuZWVkZWQgKi8KICAgICAgICBpZiAoIXJldCB8fCAoKFdDSEFSICopaW5mby0+RGF0YSlbcmV0LTFdKQogICAgICAgIHsKICAgICAgICAgICAgaWYgKHJldCA8IGxlbiB8fCAhYnVmZmVyKSByZXQrKzsKICAgICAgICAgICAgZWxzZQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBTZXRMYXN0RXJyb3IoIEVSUk9SX0lOU1VGRklDSUVOVF9CVUZGRVIgKTsKICAgICAgICAgICAgICAgIHJldCA9IDA7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgaWYgKHJldCAmJiBidWZmZXIpCiAgICAgICAgewogICAgICAgICAgICBtZW1jcHkoIGJ1ZmZlciwgaW5mby0+RGF0YSwgKHJldC0xKSAqIHNpemVvZihXQ0hBUikgKTsKICAgICAgICAgICAgYnVmZmVyW3JldC0xXSA9IDA7CiAgICAgICAgfQogICAgfQogICAgZWxzZQogICAgewogICAgICAgIGlmIChzdGF0dXMgPT0gU1RBVFVTX09CSkVDVF9OQU1FX05PVF9GT1VORCkgcmV0ID0gLTE7CiAgICAgICAgZWxzZQogICAgICAgIHsKICAgICAgICAgICAgU2V0TGFzdEVycm9yKCBSdGxOdFN0YXR1c1RvRG9zRXJyb3Ioc3RhdHVzKSApOwogICAgICAgICAgICByZXQgPSAwOwogICAgICAgIH0KICAgIH0KICAgIE50Q2xvc2UoIGhrZXkgKTsKICAgIEhlYXBGcmVlKCBHZXRQcm9jZXNzSGVhcCgpLCAwLCBpbmZvICk7CiAgICByZXR1cm4gcmV0Owp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJR2V0TG9jYWxlSW5mb0EgKEtFUk5FTDMyLkApCiAqCiAqIEdldCBpbmZvcm1hdGlvbiBhYm91dCBhbiBhc3BlY3Qgb2YgYSBsb2NhbGUuCiAqCiAqIFBBUkFNUwogKiAgbGNpZCAgIFtJXSBMQ0lEIG9mIHRoZSBsb2NhbGUKICogIGxjdHlwZSBbSV0gTENUWVBFXyBmbGFncyBmcm9tICJ3aW5ubHMuaCIKICogIGJ1ZmZlciBbT10gRGVzdGluYXRpb24gZm9yIHRoZSBpbmZvcm1hdGlvbgogKiAgbGVuICAgIFtJXSBMZW5ndGggb2YgYnVmZmVyIGluIGNoYXJhY3RlcnMKICoKICogUkVUVVJOUwogKiAgU3VjY2VzczogVGhlIHNpemUgb2YgdGhlIGRhdGEgcmVxdWVzdGVkLiBJZiBidWZmZXIgaXMgbm9uLU5VTEwsIGl0IGlzIGZpbGxlZAogKiAgICAgICAgICAgd2l0aCB0aGUgaW5mb3JtYXRpb24uCiAqICBGYWlsdXJlOiAwLiBVc2UgR2V0TGFzdEVycm9yKCkgdG8gZGV0ZXJtaW5lIHRoZSBjYXVzZS4KICoKICogTk9URVMKICogIC0gTE9DQUxFX05FVVRSQUwgaXMgZXF1YWwgdG8gTE9DQUxFX1NZU1RFTV9ERUZBVUxUCiAqICAtIFRoZSBzdHJpbmcgcmV0dXJuZWQgaXMgTlVMIHRlcm1pbmF0ZWQsIGV4Y2VwdCBmb3IgTE9DQUxFX0ZPTlRTSUdOQVRVUkUsCiAqICAgIHdoaWNoIGlzIGEgYml0IHN0cmluZy4KICovCklOVCBXSU5BUEkgR2V0TG9jYWxlSW5mb0EoIExDSUQgbGNpZCwgTENUWVBFIGxjdHlwZSwgTFBTVFIgYnVmZmVyLCBJTlQgbGVuICkKewogICAgV0NIQVIgKmJ1ZmZlclc7CiAgICBJTlQgbGVuVywgcmV0OwoKICAgIFRSQUNFKCAiKGxjaWQ9MHglbHgsbGN0eXBlPTB4JWx4LCVwLCVkKVxuIiwgbGNpZCwgbGN0eXBlLCBidWZmZXIsIGxlbiApOwoKICAgIGlmIChsZW4gPCAwIHx8IChsZW4gJiYgIWJ1ZmZlcikpCiAgICB7CiAgICAgICAgU2V0TGFzdEVycm9yKCBFUlJPUl9JTlZBTElEX1BBUkFNRVRFUiApOwogICAgICAgIHJldHVybiAwOwogICAgfQogICAgaWYgKCFsZW4pIGJ1ZmZlciA9IE5VTEw7CgogICAgaWYgKCEobGVuVyA9IEdldExvY2FsZUluZm9XKCBsY2lkLCBsY3R5cGUsIE5VTEwsIDAgKSkpIHJldHVybiAwOwoKICAgIGlmICghKGJ1ZmZlclcgPSBIZWFwQWxsb2MoIEdldFByb2Nlc3NIZWFwKCksIDAsIGxlblcgKiBzaXplb2YoV0NIQVIpICkpKQogICAgewogICAgICAgIFNldExhc3RFcnJvciggRVJST1JfTk9UX0VOT1VHSF9NRU1PUlkgKTsKICAgICAgICByZXR1cm4gMDsKICAgIH0KICAgIGlmICgocmV0ID0gR2V0TG9jYWxlSW5mb1coIGxjaWQsIGxjdHlwZSwgYnVmZmVyVywgbGVuVyApKSkKICAgIHsKICAgICAgICBpZiAoKGxjdHlwZSAmIExPQ0FMRV9SRVRVUk5fTlVNQkVSKSB8fAogICAgICAgICAgICAoKGxjdHlwZSAmIH5MT0NBTEVfTE9DQUxFSU5GT0ZMQUdTTUFTSykgPT0gTE9DQUxFX0ZPTlRTSUdOQVRVUkUpKQogICAgICAgIHsKICAgICAgICAgICAgLyogaXQncyBub3QgYW4gQVNDSUkgc3RyaW5nLCBqdXN0IGJ5dGVzICovCiAgICAgICAgICAgIHJldCAqPSBzaXplb2YoV0NIQVIpOwogICAgICAgICAgICBpZiAoYnVmZmVyKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBpZiAocmV0IDw9IGxlbikgbWVtY3B5KCBidWZmZXIsIGJ1ZmZlclcsIHJldCApOwogICAgICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIFNldExhc3RFcnJvciggRVJST1JfSU5TVUZGSUNJRU5UX0JVRkZFUiApOwogICAgICAgICAgICAgICAgICAgIHJldCA9IDA7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgZWxzZQogICAgICAgIHsKICAgICAgICAgICAgVUlOVCBjb2RlcGFnZSA9IENQX0FDUDsKICAgICAgICAgICAgaWYgKCEobGN0eXBlICYgTE9DQUxFX1VTRV9DUF9BQ1ApKSBjb2RlcGFnZSA9IGdldF9sY2lkX2NvZGVwYWdlKCBsY2lkICk7CiAgICAgICAgICAgIHJldCA9IFdpZGVDaGFyVG9NdWx0aUJ5dGUoIGNvZGVwYWdlLCAwLCBidWZmZXJXLCByZXQsIGJ1ZmZlciwgbGVuLCBOVUxMLCBOVUxMICk7CiAgICAgICAgfQogICAgfQogICAgSGVhcEZyZWUoIEdldFByb2Nlc3NIZWFwKCksIDAsIGJ1ZmZlclcgKTsKICAgIHJldHVybiByZXQ7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCQlHZXRMb2NhbGVJbmZvVyAoS0VSTkVMMzIuQCkKICoKICogU2VlIEdldExvY2FsZUluZm9BLgogKi8KSU5UIFdJTkFQSSBHZXRMb2NhbGVJbmZvVyggTENJRCBsY2lkLCBMQ1RZUEUgbGN0eXBlLCBMUFdTVFIgYnVmZmVyLCBJTlQgbGVuICkKewogICAgTEFOR0lEIGxhbmdfaWQ7CiAgICBIUlNSQyBocnNyYzsKICAgIEhHTE9CQUwgaG1lbTsKICAgIElOVCByZXQ7CiAgICBVSU5UIGxjZmxhZ3M7CiAgICBjb25zdCBXQ0hBUiAqcDsKICAgIHVuc2lnbmVkIGludCBpOwoKICAgIGlmIChsZW4gPCAwIHx8IChsZW4gJiYgIWJ1ZmZlcikpCiAgICB7CiAgICAgICAgU2V0TGFzdEVycm9yKCBFUlJPUl9JTlZBTElEX1BBUkFNRVRFUiApOwogICAgICAgIHJldHVybiAwOwogICAgfQogICAgaWYgKCFsZW4pIGJ1ZmZlciA9IE5VTEw7CgogICAgbGNpZCA9IENvbnZlcnREZWZhdWx0TG9jYWxlKGxjaWQpOwoKICAgIGxjZmxhZ3MgPSBsY3R5cGUgJiBMT0NBTEVfTE9DQUxFSU5GT0ZMQUdTTUFTSzsKICAgIGxjdHlwZSAmPSAweGZmZmY7CgogICAgVFJBQ0UoICIobGNpZD0weCVseCxsY3R5cGU9MHglbHgsJXAsJWQpXG4iLCBsY2lkLCBsY3R5cGUsIGJ1ZmZlciwgbGVuICk7CgogICAgLyogZmlyc3QgY2hlY2sgZm9yIG92ZXJyaWRlcyBpbiB0aGUgcmVnaXN0cnkgKi8KCiAgICBpZiAoIShsY2ZsYWdzICYgTE9DQUxFX05PVVNFUk9WRVJSSURFKSAmJiBsY2lkID09IEdldFVzZXJEZWZhdWx0TENJRCgpKQogICAgewogICAgICAgIGNvbnN0IFdDSEFSICp2YWx1ZSA9IGdldF9sb2NhbGVfdmFsdWVfbmFtZShsY3R5cGUpOwoKICAgICAgICBpZiAodmFsdWUpCiAgICAgICAgewogICAgICAgICAgICBpZiAobGNmbGFncyAmIExPQ0FMRV9SRVRVUk5fTlVNQkVSKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBXQ0hBUiB0bXBbMTZdOwogICAgICAgICAgICAgICAgcmV0ID0gZ2V0X3JlZ2lzdHJ5X2xvY2FsZV9pbmZvKCB2YWx1ZSwgdG1wLCBzaXplb2YodG1wKS9zaXplb2YoV0NIQVIpICk7CiAgICAgICAgICAgICAgICBpZiAocmV0ID4gMCkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBXQ0hBUiAqZW5kOwogICAgICAgICAgICAgICAgICAgIFVJTlQgbnVtYmVyID0gc3RydG9sVyggdG1wLCAmZW5kLCAxMCApOwogICAgICAgICAgICAgICAgICAgIGlmICgqZW5kKSAgLyogaW52YWxpZCBudW1iZXIgKi8KICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIFNldExhc3RFcnJvciggRVJST1JfSU5WQUxJRF9GTEFHUyApOwogICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gMDsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgcmV0ID0gc2l6ZW9mKFVJTlQpL3NpemVvZihXQ0hBUik7CiAgICAgICAgICAgICAgICAgICAgaWYgKCFidWZmZXIpIHJldHVybiByZXQ7CiAgICAgICAgICAgICAgICAgICAgaWYgKHJldCA+IGxlbikKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIFNldExhc3RFcnJvciggRVJST1JfSU5TVUZGSUNJRU5UX0JVRkZFUiApOwogICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gMDsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgbWVtY3B5KCBidWZmZXIsICZudW1iZXIsIHNpemVvZihudW1iZXIpICk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZWxzZSByZXQgPSBnZXRfcmVnaXN0cnlfbG9jYWxlX2luZm8oIHZhbHVlLCBidWZmZXIsIGxlbiApOwoKICAgICAgICAgICAgaWYgKHJldCAhPSAtMSkgcmV0dXJuIHJldDsKICAgICAgICB9CiAgICB9CgogICAgLyogbm93IGxvYWQgaXQgZnJvbSBrZXJuZWwgcmVzb3VyY2VzICovCgogICAgbGFuZ19pZCA9IExBTkdJREZST01MQ0lEKCBsY2lkICk7CgogICAgLyogcmVwbGFjZSBTVUJMQU5HX05FVVRSQUwgYnkgU1VCTEFOR19ERUZBVUxUICovCiAgICBpZiAoU1VCTEFOR0lEKGxhbmdfaWQpID09IFNVQkxBTkdfTkVVVFJBTCkKICAgICAgICBsYW5nX2lkID0gTUFLRUxBTkdJRChQUklNQVJZTEFOR0lEKGxhbmdfaWQpLCBTVUJMQU5HX0RFRkFVTFQpOwoKICAgIGlmICghKGhyc3JjID0gRmluZFJlc291cmNlRXhXKCBrZXJuZWwzMl9oYW5kbGUsIChMUFdTVFIpUlRfU1RSSU5HLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChMUENXU1RSKSgobGN0eXBlID4+IDQpICsgMSksIGxhbmdfaWQgKSkpCiAgICB7CiAgICAgICAgU2V0TGFzdEVycm9yKCBFUlJPUl9JTlZBTElEX0ZMQUdTICk7ICAvKiBubyBzdWNoIGxjdHlwZSAqLwogICAgICAgIHJldHVybiAwOwogICAgfQogICAgaWYgKCEoaG1lbSA9IExvYWRSZXNvdXJjZSgga2VybmVsMzJfaGFuZGxlLCBocnNyYyApKSkKICAgICAgICByZXR1cm4gMDsKCiAgICBwID0gTG9ja1Jlc291cmNlKCBobWVtICk7CiAgICBmb3IgKGkgPSAwOyBpIDwgKGxjdHlwZSAmIDB4MGYpOyBpKyspIHAgKz0gKnAgKyAxOwoKICAgIGlmIChsY2ZsYWdzICYgTE9DQUxFX1JFVFVSTl9OVU1CRVIpIHJldCA9IHNpemVvZihVSU5UKS9zaXplb2YoV0NIQVIpOwogICAgZWxzZSByZXQgPSAobGN0eXBlID09IExPQ0FMRV9GT05UU0lHTkFUVVJFKSA/ICpwIDogKnAgKyAxOwoKICAgIGlmICghYnVmZmVyKSByZXR1cm4gcmV0OwoKICAgIGlmIChyZXQgPiBsZW4pCiAgICB7CiAgICAgICAgU2V0TGFzdEVycm9yKCBFUlJPUl9JTlNVRkZJQ0lFTlRfQlVGRkVSICk7CiAgICAgICAgcmV0dXJuIDA7CiAgICB9CgogICAgaWYgKGxjZmxhZ3MgJiBMT0NBTEVfUkVUVVJOX05VTUJFUikKICAgIHsKICAgICAgICBVSU5UIG51bWJlcjsKICAgICAgICBXQ0hBUiAqZW5kLCAqdG1wID0gSGVhcEFsbG9jKCBHZXRQcm9jZXNzSGVhcCgpLCAwLCAoKnAgKyAxKSAqIHNpemVvZihXQ0hBUikgKTsKICAgICAgICBpZiAoIXRtcCkgcmV0dXJuIDA7CiAgICAgICAgbWVtY3B5KCB0bXAsIHAgKyAxLCAqcCAqIHNpemVvZihXQ0hBUikgKTsKICAgICAgICB0bXBbKnBdID0gMDsKICAgICAgICBudW1iZXIgPSBzdHJ0b2xXKCB0bXAsICZlbmQsIDEwICk7CiAgICAgICAgaWYgKCEqZW5kKQogICAgICAgICAgICBtZW1jcHkoIGJ1ZmZlciwgJm51bWJlciwgc2l6ZW9mKG51bWJlcikgKTsKICAgICAgICBlbHNlICAvKiBpbnZhbGlkIG51bWJlciAqLwogICAgICAgIHsKICAgICAgICAgICAgU2V0TGFzdEVycm9yKCBFUlJPUl9JTlZBTElEX0ZMQUdTICk7CiAgICAgICAgICAgIHJldCA9IDA7CiAgICAgICAgfQogICAgICAgIEhlYXBGcmVlKCBHZXRQcm9jZXNzSGVhcCgpLCAwLCB0bXAgKTsKCiAgICAgICAgVFJBQ0UoICIobGNpZD0weCVseCxsY3R5cGU9MHglbHgsJXAsJWQpIHJldHVybmluZyBudW1iZXIgJWRcbiIsCiAgICAgICAgICAgICAgIGxjaWQsIGxjdHlwZSwgYnVmZmVyLCBsZW4sIG51bWJlciApOwogICAgfQogICAgZWxzZQogICAgewogICAgICAgIG1lbWNweSggYnVmZmVyLCBwICsgMSwgKnAgKiBzaXplb2YoV0NIQVIpICk7CiAgICAgICAgaWYgKGxjdHlwZSAhPSBMT0NBTEVfRk9OVFNJR05BVFVSRSkgYnVmZmVyW3JldC0xXSA9IDA7CgogICAgICAgIFRSQUNFKCAiKGxjaWQ9MHglbHgsbGN0eXBlPTB4JWx4LCVwLCVkKSByZXR1cm5pbmcgJWQgJXNcbiIsCiAgICAgICAgICAgICAgIGxjaWQsIGxjdHlwZSwgYnVmZmVyLCBsZW4sIHJldCwgZGVidWdzdHJfdyhidWZmZXIpICk7CiAgICB9CiAgICByZXR1cm4gcmV0Owp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJU2V0TG9jYWxlSW5mb0EJW0tFUk5FTDMyLkBdCiAqCiAqIFNldCBpbmZvcm1hdGlvbiBhYm91dCBhbiBhc3BlY3Qgb2YgYSBsb2NhbGUuCiAqCiAqIFBBUkFNUwogKiAgbGNpZCAgIFtJXSBMQ0lEIG9mIHRoZSBsb2NhbGUKICogIGxjdHlwZSBbSV0gTENUWVBFXyBmbGFncyBmcm9tICJ3aW5ubHMuaCIKICogIGRhdGEgICBbSV0gSW5mb3JtYXRpb24gdG8gc2V0CiAqCiAqIFJFVFVSTlMKICogIFN1Y2Nlc3M6IFRSVUUuIFRoZSBpbmZvcm1hdGlvbiBnaXZlbiB3aWxsIGJlIHJldHVybmVkIGJ5IEdldExvY2FsZUluZm9BKCkKICogICAgICAgICAgIHdoZW5ldmVyIGl0IGlzIGNhbGxlZCB3aXRob3V0IExPQ0FMRV9OT1VTRVJPVkVSUklERS4KICogIEZhaWx1cmU6IEZBTFNFLiBVc2UgR2V0TGFzdEVycm9yKCkgdG8gZGV0ZXJtaW5lIHRoZSBjYXVzZS4KICoKICogTk9URVMKICogIC0gVmFsdWVzIGFyZSBvbmx5IGJlIHNldCBmb3IgdGhlIGN1cnJlbnQgdXNlciBsb2NhbGU7IHRoZSBzeXN0ZW0gbG9jYWxlCiAqICBzZXR0aW5ncyBjYW5ub3QgYmUgY2hhbmdlZC4KICogIC0gQW55IHNldHRpbmdzIGNoYW5nZWQgYnkgdGhpcyBjYWxsIGFyZSBsb3N0IHdoZW4gdGhlIGxvY2FsZSBpcyBjaGFuZ2VkIGJ5CiAqICB0aGUgY29udHJvbCBwYW5lbCAoaW4gV2luZSwgdGhpcyBoYXBwZW5zIGV2ZXJ5IHRpbWUgeW91IGNoYW5nZSBMQU5HKS4KICogIC0gVGhlIG5hdGl2ZSBpbXBsZW1lbnRhdGlvbiBvZiB0aGlzIGZ1bmN0aW9uIGRvZXMgbm90IGNoZWNrIHRoYXQgbGNpZCBtYXRjaGVzCiAqICB0aGUgY3VycmVudCB1c2VyIGxvY2FsZSwgYW5kIHNpbXBseSBzZXRzIHRoZSBuZXcgdmFsdWVzLiBXaW5lIHdhcm5zIHlvdSBpbgogKiAgdGhpcyBjYXNlLCBidXQgYmVoYXZlcyB0aGUgc2FtZS4KICovCkJPT0wgV0lOQVBJIFNldExvY2FsZUluZm9BKExDSUQgbGNpZCwgTENUWVBFIGxjdHlwZSwgTFBDU1RSIGRhdGEpCnsKICAgIFVJTlQgY29kZXBhZ2UgPSBDUF9BQ1A7CiAgICBXQ0hBUiAqc3RyVzsKICAgIERXT1JEIGxlbjsKICAgIEJPT0wgcmV0OwoKICAgIGxjaWQgPSBDb252ZXJ0RGVmYXVsdExvY2FsZShsY2lkKTsKCiAgICBpZiAoIShsY3R5cGUgJiBMT0NBTEVfVVNFX0NQX0FDUCkpIGNvZGVwYWdlID0gZ2V0X2xjaWRfY29kZXBhZ2UoIGxjaWQgKTsKCiAgICBpZiAoIWRhdGEpCiAgICB7CiAgICAgICAgU2V0TGFzdEVycm9yKCBFUlJPUl9JTlZBTElEX1BBUkFNRVRFUiApOwogICAgICAgIHJldHVybiBGQUxTRTsKICAgIH0KICAgIGxlbiA9IE11bHRpQnl0ZVRvV2lkZUNoYXIoIGNvZGVwYWdlLCAwLCBkYXRhLCAtMSwgTlVMTCwgMCApOwogICAgaWYgKCEoc3RyVyA9IEhlYXBBbGxvYyggR2V0UHJvY2Vzc0hlYXAoKSwgMCwgbGVuICogc2l6ZW9mKFdDSEFSKSApKSkKICAgIHsKICAgICAgICBTZXRMYXN0RXJyb3IoIEVSUk9SX05PVF9FTk9VR0hfTUVNT1JZICk7CiAgICAgICAgcmV0dXJuIEZBTFNFOwogICAgfQogICAgTXVsdGlCeXRlVG9XaWRlQ2hhciggY29kZXBhZ2UsIDAsIGRhdGEsIC0xLCBzdHJXLCBsZW4gKTsKICAgIHJldCA9IFNldExvY2FsZUluZm9XKCBsY2lkLCBsY3R5cGUsIHN0clcgKTsKICAgIEhlYXBGcmVlKCBHZXRQcm9jZXNzSGVhcCgpLCAwLCBzdHJXICk7CiAgICByZXR1cm4gcmV0Owp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJU2V0TG9jYWxlSW5mb1cJKEtFUk5FTDMyLkApCiAqCiAqIFNlZSBTZXRMb2NhbGVJbmZvQS4KICovCkJPT0wgV0lOQVBJIFNldExvY2FsZUluZm9XKCBMQ0lEIGxjaWQsIExDVFlQRSBsY3R5cGUsIExQQ1dTVFIgZGF0YSApCnsKICAgIGNvbnN0IFdDSEFSICp2YWx1ZTsKICAgIHN0YXRpYyBjb25zdCBXQ0hBUiBpbnRsV1tdID0geydpJywnbicsJ3QnLCdsJywwIH07CiAgICBVTklDT0RFX1NUUklORyB2YWx1ZVc7CiAgICBOVFNUQVRVUyBzdGF0dXM7CiAgICBIS0VZIGhrZXk7CgogICAgbGNpZCA9IENvbnZlcnREZWZhdWx0TG9jYWxlKGxjaWQpOwoKICAgIGxjdHlwZSAmPSAweGZmZmY7CiAgICB2YWx1ZSA9IGdldF9sb2NhbGVfdmFsdWVfbmFtZSggbGN0eXBlICk7CgogICAgaWYgKCFkYXRhIHx8ICF2YWx1ZSkKICAgIHsKICAgICAgICBTZXRMYXN0RXJyb3IoIEVSUk9SX0lOVkFMSURfUEFSQU1FVEVSICk7CiAgICAgICAgcmV0dXJuIEZBTFNFOwogICAgfQoKICAgIGlmIChsY3R5cGUgPT0gTE9DQUxFX0lEQVRFIHx8IGxjdHlwZSA9PSBMT0NBTEVfSUxEQVRFKQogICAgewogICAgICAgIFNldExhc3RFcnJvciggRVJST1JfSU5WQUxJRF9GTEFHUyApOwogICAgICAgIHJldHVybiBGQUxTRTsKICAgIH0KCiAgICBpZiAobGNpZCAhPSBHZXRVc2VyRGVmYXVsdExDSUQoKSkKICAgIHsKICAgICAgICAvKiBXaW5kb3dzIGRvZXMgbm90IGNoZWNrIHRoYXQgdGhlIGxjaWQgbWF0Y2hlcyB0aGUgY3VycmVudCBsY2lkICovCiAgICAgICAgV0FSTigibG9jYWxlIDB4JTA4bHggaXNuJ3QgdGhlIGN1cnJlbnQgbG9jYWxlICgweCUwOGx4KSwgc2V0dGluZyBhbnl3YXkhXG4iLAogICAgICAgICAgICAgbGNpZCwgR2V0VXNlckRlZmF1bHRMQ0lEKCkpOwogICAgfQoKICAgIFRSQUNFKCJzZXR0aW5nICVseCAoJXMpIHRvICVzXG4iLCBsY3R5cGUsIGRlYnVnc3RyX3codmFsdWUpLCBkZWJ1Z3N0cl93KGRhdGEpICk7CgogICAgLyogRklYTUU6IHNob3VsZCBjaGVjayB0aGF0IGRhdGEgdG8gc2V0IGlzIHNhbmUgKi8KCiAgICAvKiBGSVhNRTogcHJvZmlsZSBmdW5jdGlvbnMgc2hvdWxkIG1hcCB0byByZWdpc3RyeSAqLwogICAgV3JpdGVQcm9maWxlU3RyaW5nVyggaW50bFcsIHZhbHVlLCBkYXRhICk7CgogICAgaWYgKCEoaGtleSA9IGNyZWF0ZV9yZWdpc3RyeV9rZXkoKSkpIHJldHVybiBGQUxTRTsKICAgIFJ0bEluaXRVbmljb2RlU3RyaW5nKCAmdmFsdWVXLCB2YWx1ZSApOwogICAgc3RhdHVzID0gTnRTZXRWYWx1ZUtleSggaGtleSwgJnZhbHVlVywgMCwgUkVHX1NaLCBkYXRhLCAoc3RybGVuVyhkYXRhKSsxKSpzaXplb2YoV0NIQVIpICk7CgogICAgaWYgKGxjdHlwZSA9PSBMT0NBTEVfU1NIT1JUREFURSB8fCBsY3R5cGUgPT0gTE9DQUxFX1NMT05HREFURSkKICAgIHsKICAgICAgLyogU2V0IEktdmFsdWUgZnJvbSBTIHZhbHVlICovCiAgICAgIFdDSEFSICpscEQsICpscE0sICpscFk7CiAgICAgIFdDSEFSIHN6QnVmZlsyXTsKCiAgICAgIGxwRCA9IHN0cnJjaHJXKGRhdGEsICdkJyk7CiAgICAgIGxwTSA9IHN0cnJjaHJXKGRhdGEsICdNJyk7CiAgICAgIGxwWSA9IHN0cnJjaHJXKGRhdGEsICd5Jyk7CgogICAgICBpZiAobHBEIDw9IGxwTSkKICAgICAgewogICAgICAgIHN6QnVmZlswXSA9ICcxJzsgLyogRC1NLVkgKi8KICAgICAgfQogICAgICBlbHNlCiAgICAgIHsKICAgICAgICBpZiAobHBZIDw9IGxwTSkKICAgICAgICAgIHN6QnVmZlswXSA9ICcyJzsgLyogWS1NLUQgKi8KICAgICAgICBlbHNlCiAgICAgICAgICBzekJ1ZmZbMF0gPSAnMCc7IC8qIE0tRC1ZICovCiAgICAgIH0KCiAgICAgIHN6QnVmZlsxXSA9ICdcMCc7CgogICAgICBpZiAobGN0eXBlID09IExPQ0FMRV9TU0hPUlREQVRFKQogICAgICAgIGxjdHlwZSA9IExPQ0FMRV9JREFURTsKICAgICAgZWxzZQogICAgICAgIGxjdHlwZSA9IExPQ0FMRV9JTERBVEU7CgogICAgICB2YWx1ZSA9IGdldF9sb2NhbGVfdmFsdWVfbmFtZSggbGN0eXBlICk7CgogICAgICBXcml0ZVByb2ZpbGVTdHJpbmdXKCBpbnRsVywgdmFsdWUsIHN6QnVmZiApOwoKICAgICAgUnRsSW5pdFVuaWNvZGVTdHJpbmcoICZ2YWx1ZVcsIHZhbHVlICk7CiAgICAgIHN0YXR1cyA9IE50U2V0VmFsdWVLZXkoIGhrZXksICZ2YWx1ZVcsIDAsIFJFR19TWiwgc3pCdWZmLCBzaXplb2Yoc3pCdWZmKSApOwogICAgfQoKICAgIE50Q2xvc2UoIGhrZXkgKTsKCiAgICBpZiAoc3RhdHVzKSBTZXRMYXN0RXJyb3IoIFJ0bE50U3RhdHVzVG9Eb3NFcnJvcihzdGF0dXMpICk7CiAgICByZXR1cm4gIXN0YXR1czsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICAgICAgICAgIEdldEFDUCAgIChLRVJORUwzMi5AKQogKgogKiBHZXQgdGhlIGN1cnJlbnQgQW5zaSBjb2RlIHBhZ2UgSWQgZm9yIHRoZSBzeXN0ZW0uCiAqCiAqIFBBUkFNUwogKiAgTm9uZS4KICoKICogUkVUVVJOUwogKiAgICBUaGUgY3VycmVudCBBbnNpIGNvZGUgcGFnZSBpZGVudGlmaWVyIGZvciB0aGUgc3lzdGVtLgogKi8KVUlOVCBXSU5BUEkgR2V0QUNQKHZvaWQpCnsKICAgIGFzc2VydCggYW5zaV9jcHRhYmxlICk7CiAgICByZXR1cm4gYW5zaV9jcHRhYmxlLT5pbmZvLmNvZGVwYWdlOwp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgICAgICAgICBHZXRPRU1DUCAgIChLRVJORUwzMi5AKQogKgogKiBHZXQgdGhlIGN1cnJlbnQgT0VNIGNvZGUgcGFnZSBJZCBmb3IgdGhlIHN5c3RlbS4KICoKICogUEFSQU1TCiAqICBOb25lLgogKgogKiBSRVRVUk5TCiAqICAgIFRoZSBjdXJyZW50IE9FTSBjb2RlIHBhZ2UgaWRlbnRpZmllciBmb3IgdGhlIHN5c3RlbS4KICovClVJTlQgV0lOQVBJIEdldE9FTUNQKHZvaWQpCnsKICAgIGFzc2VydCggb2VtX2NwdGFibGUgKTsKICAgIHJldHVybiBvZW1fY3B0YWJsZS0+aW5mby5jb2RlcGFnZTsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgICAgICAgSXNWYWxpZENvZGVQYWdlICAgKEtFUk5FTDMyLkApCiAqCiAqIERldGVybWluZSBpZiBhIGdpdmVuIGNvZGUgcGFnZSBpZGVudGlmaWVyIGlzIHZhbGlkLgogKgogKiBQQVJBTVMKICogIGNvZGVwYWdlIFtJXSBDb2RlIHBhZ2UgSWQgdG8gdmVyaWZ5LgogKgogKiBSRVRVUk5TCiAqICBUUlVFLCBJZiBjb2RlcGFnZSBpcyB2YWxpZCBhbmQgYXZhaWxhYmxlIG9uIHRoZSBzeXN0ZW0sCiAqICBGQUxTRSBvdGhlcndpc2UuCiAqLwpCT09MIFdJTkFQSSBJc1ZhbGlkQ29kZVBhZ2UoIFVJTlQgY29kZXBhZ2UgKQp7CiAgICBzd2l0Y2goY29kZXBhZ2UpIHsKICAgIGNhc2UgQ1BfVVRGNzoKICAgIGNhc2UgQ1BfVVRGODoKICAgICAgICByZXR1cm4gVFJVRTsKICAgIGRlZmF1bHQ6CiAgICAgICAgcmV0dXJuIHdpbmVfY3BfZ2V0X3RhYmxlKCBjb2RlcGFnZSApICE9IE5VTEw7CiAgICB9Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICAgICAgIElzREJDU0xlYWRCeXRlRXggICAoS0VSTkVMMzIuQCkKICoKICogRGV0ZXJtaW5lIGlmIGEgY2hhcmFjdGVyIGlzIGEgbGVhZCBieXRlIGluIGEgZ2l2ZW4gY29kZSBwYWdlLgogKgogKiBQQVJBTVMKICogIGNvZGVwYWdlIFtJXSBDb2RlIHBhZ2UgZm9yIHRoZSB0ZXN0LgogKiAgdGVzdGNoYXIgW0ldIENoYXJhY3RlciB0byB0ZXN0CiAqCiAqIFJFVFVSTlMKICogIFRSVUUsIGlmIHRlc3RjaGFyIGlzIGEgbGVhZCBieXRlIGluIGNvZGVwYWdlLAogKiAgRkFMU0Ugb3RoZXJ3aXNlLgogKi8KQk9PTCBXSU5BUEkgSXNEQkNTTGVhZEJ5dGVFeCggVUlOVCBjb2RlcGFnZSwgQllURSB0ZXN0Y2hhciApCnsKICAgIGNvbnN0IHVuaW9uIGNwdGFibGUgKnRhYmxlID0gZ2V0X2NvZGVwYWdlX3RhYmxlKCBjb2RlcGFnZSApOwogICAgcmV0dXJuIHRhYmxlICYmIGlzX2RiY3NfbGVhZGJ5dGUoIHRhYmxlLCB0ZXN0Y2hhciApOwp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgICAgICBJc0RCQ1NMZWFkQnl0ZSAgIChLRVJORUwzMi5AKQogKiAgICAgICAgICAgSXNEQkNTTGVhZEJ5dGUgICAoS0VSTkVMLjIwNykKICoKICogRGV0ZXJtaW5lIGlmIGEgY2hhcmFjdGVyIGlzIGEgbGVhZCBieXRlLgogKgogKiBQQVJBTVMKICogIHRlc3RjaGFyIFtJXSBDaGFyYWN0ZXIgdG8gdGVzdAogKgogKiBSRVRVUk5TCiAqICBUUlVFLCBpZiB0ZXN0Y2hhciBpcyBhIGxlYWQgYnl0ZSBpbiB0aGUgQW5zaWkgY29kZSBwYWdlLAogKiAgRkFMU0Ugb3RoZXJ3aXNlLgogKi8KQk9PTCBXSU5BUEkgSXNEQkNTTGVhZEJ5dGUoIEJZVEUgdGVzdGNoYXIgKQp7CiAgICBpZiAoIWFuc2lfY3B0YWJsZSkgcmV0dXJuIEZBTFNFOwogICAgcmV0dXJuIGlzX2RiY3NfbGVhZGJ5dGUoIGFuc2lfY3B0YWJsZSwgdGVzdGNoYXIgKTsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgICAgICAgR2V0Q1BJbmZvICAgKEtFUk5FTDMyLkApCiAqCiAqIEdldCBpbmZvcm1hdGlvbiBhYm91dCBhIGNvZGUgcGFnZS4KICoKICogUEFSQU1TCiAqICBjb2RlcGFnZSBbSV0gQ29kZSBwYWdlIG51bWJlcgogKiAgY3BpbmZvICAgW09dIERlc3RpbmF0aW9uIGZvciBjb2RlIHBhZ2UgaW5mb3JtYXRpb24KICoKICogUkVUVVJOUwogKiAgU3VjY2VzczogVFJVRS4gY3BpbmZvIGlzIHVwZGF0ZWQgd2l0aCB0aGUgaW5mb3JtYXRpb24gYWJvdXQgY29kZXBhZ2UuCiAqICBGYWlsdXJlOiBGQUxTRSwgaWYgY29kZXBhZ2UgaXMgaW52YWxpZCBvciBjcGluZm8gaXMgTlVMTC4KICovCkJPT0wgV0lOQVBJIEdldENQSW5mbyggVUlOVCBjb2RlcGFnZSwgTFBDUElORk8gY3BpbmZvICkKewogICAgY29uc3QgdW5pb24gY3B0YWJsZSAqdGFibGU7CgogICAgaWYgKCFjcGluZm8pCiAgICB7CiAgICAgICAgU2V0TGFzdEVycm9yKCBFUlJPUl9JTlZBTElEX1BBUkFNRVRFUiApOwogICAgICAgIHJldHVybiBGQUxTRTsKICAgIH0KCiAgICBpZiAoISh0YWJsZSA9IGdldF9jb2RlcGFnZV90YWJsZSggY29kZXBhZ2UgKSkpCiAgICB7CiAgICAgICAgc3dpdGNoKGNvZGVwYWdlKQogICAgICAgIHsKICAgICAgICAgICAgY2FzZSBDUF9VVEY3OgogICAgICAgICAgICBjYXNlIENQX1VURjg6CiAgICAgICAgICAgICAgICBjcGluZm8tPkRlZmF1bHRDaGFyWzBdID0gMHgzZjsKICAgICAgICAgICAgICAgIGNwaW5mby0+RGVmYXVsdENoYXJbMV0gPSAwOwogICAgICAgICAgICAgICAgY3BpbmZvLT5MZWFkQnl0ZVswXSA9IGNwaW5mby0+TGVhZEJ5dGVbMV0gPSAwOwogICAgICAgICAgICAgICAgY3BpbmZvLT5NYXhDaGFyU2l6ZSA9IChjb2RlcGFnZSA9PSBDUF9VVEY3KSA/IDUgOiA0OwogICAgICAgICAgICAgICAgcmV0dXJuIFRSVUU7CiAgICAgICAgfQoKICAgICAgICBTZXRMYXN0RXJyb3IoIEVSUk9SX0lOVkFMSURfUEFSQU1FVEVSICk7CiAgICAgICAgcmV0dXJuIEZBTFNFOwogICAgfQogICAgaWYgKHRhYmxlLT5pbmZvLmRlZl9jaGFyICYgMHhmZjAwKQogICAgewogICAgICAgIGNwaW5mby0+RGVmYXVsdENoYXJbMF0gPSB0YWJsZS0+aW5mby5kZWZfY2hhciAmIDB4ZmYwMDsKICAgICAgICBjcGluZm8tPkRlZmF1bHRDaGFyWzFdID0gdGFibGUtPmluZm8uZGVmX2NoYXIgJiAweDAwZmY7CiAgICB9CiAgICBlbHNlCiAgICB7CiAgICAgICAgY3BpbmZvLT5EZWZhdWx0Q2hhclswXSA9IHRhYmxlLT5pbmZvLmRlZl9jaGFyICYgMHhmZjsKICAgICAgICBjcGluZm8tPkRlZmF1bHRDaGFyWzFdID0gMDsKICAgIH0KICAgIGlmICgoY3BpbmZvLT5NYXhDaGFyU2l6ZSA9IHRhYmxlLT5pbmZvLmNoYXJfc2l6ZSkgPT0gMikKICAgICAgICBtZW1jcHkoIGNwaW5mby0+TGVhZEJ5dGUsIHRhYmxlLT5kYmNzLmxlYWRfYnl0ZXMsIHNpemVvZihjcGluZm8tPkxlYWRCeXRlKSApOwogICAgZWxzZQogICAgICAgIGNwaW5mby0+TGVhZEJ5dGVbMF0gPSBjcGluZm8tPkxlYWRCeXRlWzFdID0gMDsKCiAgICByZXR1cm4gVFJVRTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgICAgICBHZXRDUEluZm9FeEEgICAoS0VSTkVMMzIuQCkKICoKICogR2V0IGV4dGVuZGVkIGluZm9ybWF0aW9uIGFib3V0IGEgY29kZSBwYWdlLgogKgogKiBQQVJBTVMKICogIGNvZGVwYWdlIFtJXSBDb2RlIHBhZ2UgbnVtYmVyCiAqICBkd0ZsYWdzICBbSV0gUmVzZXJ2ZWQsIG11c3QgdG8gMC4KICogIGNwaW5mbyAgIFtPXSBEZXN0aW5hdGlvbiBmb3IgY29kZSBwYWdlIGluZm9ybWF0aW9uCiAqCiAqIFJFVFVSTlMKICogIFN1Y2Nlc3M6IFRSVUUuIGNwaW5mbyBpcyB1cGRhdGVkIHdpdGggdGhlIGluZm9ybWF0aW9uIGFib3V0IGNvZGVwYWdlLgogKiAgRmFpbHVyZTogRkFMU0UsIGlmIGNvZGVwYWdlIGlzIGludmFsaWQgb3IgY3BpbmZvIGlzIE5VTEwuCiAqLwpCT09MIFdJTkFQSSBHZXRDUEluZm9FeEEoIFVJTlQgY29kZXBhZ2UsIERXT1JEIGR3RmxhZ3MsIExQQ1BJTkZPRVhBIGNwaW5mbyApCnsKICAgIENQSU5GT0VYVyBjcGluZm9XOwoKICAgIGlmICghR2V0Q1BJbmZvRXhXKCBjb2RlcGFnZSwgZHdGbGFncywgJmNwaW5mb1cgKSkKICAgICAgcmV0dXJuIEZBTFNFOwoKICAgIC8qIHRoZSBsYXlvdXQgaXMgdGhlIHNhbWUgZXhjZXB0IGZvciBDb2RlUGFnZU5hbWUgKi8KICAgIG1lbWNweShjcGluZm8sICZjcGluZm9XLCBzaXplb2YoQ1BJTkZPRVhBKSk7CiAgICBXaWRlQ2hhclRvTXVsdGlCeXRlKENQX0FDUCwgMCwgY3BpbmZvVy5Db2RlUGFnZU5hbWUsIC0xLCBjcGluZm8tPkNvZGVQYWdlTmFtZSwgc2l6ZW9mKGNwaW5mby0+Q29kZVBhZ2VOYW1lKSwgTlVMTCwgTlVMTCk7CiAgICByZXR1cm4gVFJVRTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgICAgICBHZXRDUEluZm9FeFcgICAoS0VSTkVMMzIuQCkKICoKICogVW5pY29kZSB2ZXJzaW9uIG9mIEdldENQSW5mb0V4QS4KICovCkJPT0wgV0lOQVBJIEdldENQSW5mb0V4VyggVUlOVCBjb2RlcGFnZSwgRFdPUkQgZHdGbGFncywgTFBDUElORk9FWFcgY3BpbmZvICkKewogICAgaWYgKCFHZXRDUEluZm8oIGNvZGVwYWdlLCAoTFBDUElORk8pY3BpbmZvICkpCiAgICAgIHJldHVybiBGQUxTRTsKCiAgICBzd2l0Y2goY29kZXBhZ2UpCiAgICB7CiAgICAgICAgY2FzZSBDUF9VVEY3OgogICAgICAgIHsKICAgICAgICAgICAgc3RhdGljIGNvbnN0IFdDSEFSIHV0ZjdbXSA9IHsnVScsJ24nLCdpJywnYycsJ28nLCdkJywnZScsJyAnLCcoJywnVScsJ1QnLCdGJywnLScsJzcnLCcpJywwfTsKCiAgICAgICAgICAgIGNwaW5mby0+Q29kZVBhZ2UgPSBDUF9VVEY3OwogICAgICAgICAgICBjcGluZm8tPlVuaWNvZGVEZWZhdWx0Q2hhciA9IDB4M2Y7CiAgICAgICAgICAgIHN0cmNweVcoY3BpbmZvLT5Db2RlUGFnZU5hbWUsIHV0ZjcpOwogICAgICAgICAgICBicmVhazsKICAgICAgICB9CgogICAgICAgIGNhc2UgQ1BfVVRGODoKICAgICAgICB7CiAgICAgICAgICAgIHN0YXRpYyBjb25zdCBXQ0hBUiB1dGY4W10gPSB7J1UnLCduJywnaScsJ2MnLCdvJywnZCcsJ2UnLCcgJywnKCcsJ1UnLCdUJywnRicsJy0nLCc4JywnKScsMH07CgogICAgICAgICAgICBjcGluZm8tPkNvZGVQYWdlID0gQ1BfVVRGODsKICAgICAgICAgICAgY3BpbmZvLT5Vbmljb2RlRGVmYXVsdENoYXIgPSAweDNmOwogICAgICAgICAgICBzdHJjcHlXKGNwaW5mby0+Q29kZVBhZ2VOYW1lLCB1dGY4KTsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgfQoKICAgICAgICBkZWZhdWx0OgogICAgICAgIHsKICAgICAgICAgICAgY29uc3QgdW5pb24gY3B0YWJsZSAqdGFibGUgPSBnZXRfY29kZXBhZ2VfdGFibGUoIGNvZGVwYWdlICk7CgogICAgICAgICAgICBjcGluZm8tPkNvZGVQYWdlID0gdGFibGUtPmluZm8uY29kZXBhZ2U7CiAgICAgICAgICAgIGNwaW5mby0+VW5pY29kZURlZmF1bHRDaGFyID0gdGFibGUtPmluZm8uZGVmX3VuaWNvZGVfY2hhcjsKICAgICAgICAgICAgTXVsdGlCeXRlVG9XaWRlQ2hhciggQ1BfQUNQLCAwLCB0YWJsZS0+aW5mby5uYW1lLCAtMSwgY3BpbmZvLT5Db2RlUGFnZU5hbWUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNpemVvZihjcGluZm8tPkNvZGVQYWdlTmFtZSkvc2l6ZW9mKFdDSEFSKSk7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIH0KICAgIH0KICAgIHJldHVybiBUUlVFOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICAgICAgICAgIEVudW1TeXN0ZW1Db2RlUGFnZXNBICAgKEtFUk5FTDMyLkApCiAqCiAqIENhbGwgYSB1c2VyIGRlZmluZWQgZnVuY3Rpb24gZm9yIGV2ZXJ5IGNvZGUgcGFnZSBpbnN0YWxsZWQgb24gdGhlIHN5c3RlbS4KICoKICogUEFSQU1TCiAqICAgbHBmbkNvZGVQYWdlRW51bSBbSV0gVXNlciBDT0RFUEFHRV9FTlVNUFJPQyB0byBjYWxsIHdpdGggZWFjaCBmb3VuZCBjb2RlIHBhZ2UKICogICBmbGFncyAgICAgICAgICAgIFtJXSBSZXNlcnZlZCwgc2V0IHRvIDAuCiAqCiAqIFJFVFVSTlMKICogIFRSVUUsIElmIGFsbCBjb2RlIHBhZ2VzIGhhdmUgYmVlbiBlbnVtZXJhdGVkLCBvcgogKiAgRkFMU0UgaWYgbHBmbkNvZGVQYWdlRW51bSByZXR1cm5lZCBGQUxTRSB0byBzdG9wIHRoZSBlbnVtZXJhdGlvbi4KICovCkJPT0wgV0lOQVBJIEVudW1TeXN0ZW1Db2RlUGFnZXNBKCBDT0RFUEFHRV9FTlVNUFJPQ0EgbHBmbkNvZGVQYWdlRW51bSwgRFdPUkQgZmxhZ3MgKQp7CiAgICBjb25zdCB1bmlvbiBjcHRhYmxlICp0YWJsZTsKICAgIGNoYXIgYnVmZmVyWzEwXTsKICAgIGludCBpbmRleCA9IDA7CgogICAgZm9yICg7OykKICAgIHsKICAgICAgICBpZiAoISh0YWJsZSA9IHdpbmVfY3BfZW51bV90YWJsZSggaW5kZXgrKyApKSkgYnJlYWs7CiAgICAgICAgc3ByaW50ZiggYnVmZmVyLCAiJWQiLCB0YWJsZS0+aW5mby5jb2RlcGFnZSApOwogICAgICAgIGlmICghbHBmbkNvZGVQYWdlRW51bSggYnVmZmVyICkpIGJyZWFrOwogICAgfQogICAgcmV0dXJuIFRSVUU7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICAgICAgICAgIEVudW1TeXN0ZW1Db2RlUGFnZXNXICAgKEtFUk5FTDMyLkApCiAqCiAqIFNlZSBFbnVtU3lzdGVtQ29kZVBhZ2VzQS4KICovCkJPT0wgV0lOQVBJIEVudW1TeXN0ZW1Db2RlUGFnZXNXKCBDT0RFUEFHRV9FTlVNUFJPQ1cgbHBmbkNvZGVQYWdlRW51bSwgRFdPUkQgZmxhZ3MgKQp7CiAgICBjb25zdCB1bmlvbiBjcHRhYmxlICp0YWJsZTsKICAgIFdDSEFSIGJ1ZmZlclsxMF0sICpwOwogICAgaW50IHBhZ2UsIGluZGV4ID0gMDsKCiAgICBmb3IgKDs7KQogICAgewogICAgICAgIGlmICghKHRhYmxlID0gd2luZV9jcF9lbnVtX3RhYmxlKCBpbmRleCsrICkpKSBicmVhazsKICAgICAgICBwID0gYnVmZmVyICsgc2l6ZW9mKGJ1ZmZlcikvc2l6ZW9mKFdDSEFSKTsKICAgICAgICAqLS1wID0gMDsKICAgICAgICBwYWdlID0gdGFibGUtPmluZm8uY29kZXBhZ2U7CiAgICAgICAgZG8KICAgICAgICB7CiAgICAgICAgICAgICotLXAgPSAnMCcgKyAocGFnZSAlIDEwKTsKICAgICAgICAgICAgcGFnZSAvPSAxMDsKICAgICAgICB9IHdoaWxlKCBwYWdlICk7CiAgICAgICAgaWYgKCFscGZuQ29kZVBhZ2VFbnVtKCBwICkpIGJyZWFrOwogICAgfQogICAgcmV0dXJuIFRSVUU7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICAgICAgICAgIE11bHRpQnl0ZVRvV2lkZUNoYXIgICAoS0VSTkVMMzIuQCkKICoKICogQ29udmVydCBhIG11bHRpYnl0ZSBjaGFyYWN0ZXIgc3RyaW5nIGludG8gYSBVbmljb2RlIHN0cmluZy4KICoKICogUEFSQU1TCiAqICAgcGFnZSAgIFtJXSBDb2RlcGFnZSBjaGFyYWN0ZXIgc2V0IHRvIGNvbnZlcnQgZnJvbQogKiAgIGZsYWdzICBbSV0gQ2hhcmFjdGVyIG1hcHBpbmcgZmxhZ3MKICogICBzcmMgICAgW0ldIFNvdXJjZSBzdHJpbmcgYnVmZmVyCiAqICAgc3JjbGVuIFtJXSBMZW5ndGggb2Ygc3JjLCBvciAtMSBpZiBzcmMgaXMgTlVMIHRlcm1pbmF0ZWQKICogICBkc3QgICAgW09dIERlc3RpbmF0aW9uIGJ1ZmZlcgogKiAgIGRzdGxlbiBbSV0gTGVuZ3RoIG9mIGRzdCwgb3IgMCB0byBjb21wdXRlIHRoZSByZXF1aXJlZCBsZW5ndGgKICoKICogUkVUVVJOUwogKiAgIFN1Y2Nlc3M6IElmIGRzdGxlbiA+IDAsIHRoZSBudW1iZXIgb2YgY2hhcmFjdGVycyB3cml0dGVuIHRvIGRzdC4KICogICAgICAgICAgICBJZiBkc3RsZW4gPT0gMCwgdGhlIG51bWJlciBvZiBjaGFyYWN0ZXJzIG5lZWRlZCB0byBwZXJmb3JtIHRoZQogKiAgICAgICAgICAgIGNvbnZlcnNpb24uIEluIGJvdGggY2FzZXMgdGhlIGNvdW50IGluY2x1ZGVzIHRoZSB0ZXJtaW5hdGluZyBOVUwuCiAqICAgRmFpbHVyZTogMC4gVXNlIEdldExhc3RFcnJvcigpIHRvIGRldGVybWluZSB0aGUgY2F1c2UuIFBvc3NpYmxlIGVycm9ycyBhcmUKICogICAgICAgICAgICBFUlJPUl9JTlNVRkZJQ0lFTlRfQlVGRkVSLCBpZiBub3QgZW5vdWdoIHNwYWNlIGlzIGF2YWlsYWJsZSBpbiBkc3QKICogICAgICAgICAgICBhbmQgZHN0bGVuICE9IDA7IEVSUk9SX0lOVkFMSURfUEFSQU1FVEVSLCAgaWYgYW4gaW52YWxpZCBwYXJhbWV0ZXIKICogICAgICAgICAgICBpcyBwYXNzZWQsIGFuZCBFUlJPUl9OT19VTklDT0RFX1RSQU5TTEFUSU9OIGlmIG5vIHRyYW5zbGF0aW9uIGlzCiAqICAgICAgICAgICAgcG9zc2libGUgZm9yIHNyYy4KICovCklOVCBXSU5BUEkgTXVsdGlCeXRlVG9XaWRlQ2hhciggVUlOVCBwYWdlLCBEV09SRCBmbGFncywgTFBDU1RSIHNyYywgSU5UIHNyY2xlbiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMUFdTVFIgZHN0LCBJTlQgZHN0bGVuICkKewogICAgY29uc3QgdW5pb24gY3B0YWJsZSAqdGFibGU7CiAgICBpbnQgcmV0OwoKICAgIGlmICghc3JjIHx8ICghZHN0ICYmIGRzdGxlbikpCiAgICB7CiAgICAgICAgU2V0TGFzdEVycm9yKCBFUlJPUl9JTlZBTElEX1BBUkFNRVRFUiApOwogICAgICAgIHJldHVybiAwOwogICAgfQoKICAgIGlmIChzcmNsZW4gPCAwKSBzcmNsZW4gPSBzdHJsZW4oc3JjKSArIDE7CgogICAgaWYgKGZsYWdzICYgTUJfVVNFR0xZUEhDSEFSUykgRklYTUUoIk1CX1VTRUdMWVBIQ0hBUlMgbm90IHN1cHBvcnRlZFxuIik7CgogICAgc3dpdGNoKHBhZ2UpCiAgICB7CiAgICBjYXNlIENQX1NZTUJPTDoKICAgICAgICBpZiggZmxhZ3MpCiAgICAgICAgewogICAgICAgICAgICBTZXRMYXN0RXJyb3IoIEVSUk9SX0lOVkFMSURfUEFSQU1FVEVSICk7CiAgICAgICAgICAgIHJldHVybiAwOwogICAgICAgIH0KICAgICAgICByZXQgPSB3aW5lX2Nwc3ltYm9sX21ic3Rvd2NzKCBzcmMsIHNyY2xlbiwgZHN0LCBkc3RsZW4gKTsKICAgICAgICBicmVhazsKICAgIGNhc2UgQ1BfVVRGNzoKICAgICAgICBGSVhNRSgiVVRGLTcgbm90IHN1cHBvcnRlZFxuIik7CiAgICAgICAgU2V0TGFzdEVycm9yKCBFUlJPUl9DQUxMX05PVF9JTVBMRU1FTlRFRCApOwogICAgICAgIHJldHVybiAwOwogICAgY2FzZSBDUF9VTklYQ1A6CiAgICAgICAgaWYgKHVuaXhfY3B0YWJsZSkKICAgICAgICB7CiAgICAgICAgICAgIHJldCA9IHdpbmVfY3BfbWJzdG93Y3MoIHVuaXhfY3B0YWJsZSwgZmxhZ3MsIHNyYywgc3JjbGVuLCBkc3QsIGRzdGxlbiApOwogICAgICAgICAgICBicmVhazsKICAgICAgICB9CiAgICAgICAgLyogZmFsbCB0aHJvdWdoICovCiAgICBjYXNlIENQX1VURjg6CiAgICAgICAgcmV0ID0gd2luZV91dGY4X21ic3Rvd2NzKCBmbGFncywgc3JjLCBzcmNsZW4sIGRzdCwgZHN0bGVuICk7CiAgICAgICAgYnJlYWs7CiAgICBkZWZhdWx0OgogICAgICAgIGlmICghKHRhYmxlID0gZ2V0X2NvZGVwYWdlX3RhYmxlKCBwYWdlICkpKQogICAgICAgIHsKICAgICAgICAgICAgU2V0TGFzdEVycm9yKCBFUlJPUl9JTlZBTElEX1BBUkFNRVRFUiApOwogICAgICAgICAgICByZXR1cm4gMDsKICAgICAgICB9CiAgICAgICAgcmV0ID0gd2luZV9jcF9tYnN0b3djcyggdGFibGUsIGZsYWdzLCBzcmMsIHNyY2xlbiwgZHN0LCBkc3RsZW4gKTsKICAgICAgICBicmVhazsKICAgIH0KCiAgICBpZiAocmV0IDwgMCkKICAgIHsKICAgICAgICBzd2l0Y2gocmV0KQogICAgICAgIHsKICAgICAgICBjYXNlIC0xOiBTZXRMYXN0RXJyb3IoIEVSUk9SX0lOU1VGRklDSUVOVF9CVUZGRVIgKTsgYnJlYWs7CiAgICAgICAgY2FzZSAtMjogU2V0TGFzdEVycm9yKCBFUlJPUl9OT19VTklDT0RFX1RSQU5TTEFUSU9OICk7IGJyZWFrOwogICAgICAgIH0KICAgICAgICByZXQgPSAwOwogICAgfQogICAgcmV0dXJuIHJldDsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgICAgICAgICAgV2lkZUNoYXJUb011bHRpQnl0ZSAgIChLRVJORUwzMi5AKQogKgogKiBDb252ZXJ0IGEgVW5pY29kZSBjaGFyYWN0ZXIgc3RyaW5nIGludG8gYSBtdWx0aWJ5dGUgc3RyaW5nLgogKgogKiBQQVJBTVMKICogICBwYWdlICAgIFtJXSBDb2RlIHBhZ2UgY2hhcmFjdGVyIHNldCB0byBjb252ZXJ0IHRvCiAqICAgZmxhZ3MgICBbSV0gTWFwcGluZyBGbGFncyAoTUJfIGNvbnN0YW50cyBmcm9tICJ3aW5ubHMuaCIpLgogKiAgIHNyYyAgICAgW0ldIFNvdXJjZSBzdHJpbmcgYnVmZmVyCiAqICAgc3JjbGVuICBbSV0gTGVuZ3RoIG9mIHNyYywgb3IgLTEgaWYgc3JjIGlzIE5VTCB0ZXJtaW5hdGVkCiAqICAgZHN0ICAgICBbT10gRGVzdGluYXRpb24gYnVmZmVyCiAqICAgZHN0bGVuICBbSV0gTGVuZ3RoIG9mIGRzdCwgb3IgMCB0byBjb21wdXRlIHRoZSByZXF1aXJlZCBsZW5ndGgKICogICBkZWZjaGFyIFtJXSBEZWZhdWx0IGNoYXJhY3RlciB0byB1c2UgZm9yIGNvbnZlcnNpb24gaWYgbm8gZXhhY3QKICoJCSAgICBjb252ZXJzaW9uIGNhbiBiZSBtYWRlCiAqICAgdXNlZCAgICBbT10gU2V0IGlmIGRlZmF1bHQgY2hhcmFjdGVyIHdhcyB1c2VkIGluIHRoZSBjb252ZXJzaW9uCiAqCiAqIFJFVFVSTlMKICogICBTdWNjZXNzOiBJZiBkc3RsZW4gPiAwLCB0aGUgbnVtYmVyIG9mIGNoYXJhY3RlcnMgd3JpdHRlbiB0byBkc3QuCiAqICAgICAgICAgICAgSWYgZHN0bGVuID09IDAsIG51bWJlciBvZiBjaGFyYWN0ZXJzIG5lZWRlZCB0byBwZXJmb3JtIHRoZQogKiAgICAgICAgICAgIGNvbnZlcnNpb24uIEluIGJvdGggY2FzZXMgdGhlIGNvdW50IGluY2x1ZGVzIHRoZSB0ZXJtaW5hdGluZyBOVUwuCiAqICAgRmFpbHVyZTogMC4gVXNlIEdldExhc3RFcnJvcigpIHRvIGRldGVybWluZSB0aGUgY2F1c2UuIFBvc3NpYmxlIGVycm9ycyBhcmUKICogICAgICAgICAgICBFUlJPUl9JTlNVRkZJQ0lFTlRfQlVGRkVSLCBpZiBub3QgZW5vdWdoIHNwYWNlIGlzIGF2YWlsYWJsZSBpbiBkc3QKICogICAgICAgICAgICBhbmQgZHN0bGVuICE9IDAsIGFuZCBFUlJPUl9JTlZBTElEX1BBUkFNRVRFUiwgaWYgYW4gaW52YWxpZAogKiAgICAgICAgICAgIHBhcmFtZXRlciB3YXMgZ2l2ZW4uCiAqLwpJTlQgV0lOQVBJIFdpZGVDaGFyVG9NdWx0aUJ5dGUoIFVJTlQgcGFnZSwgRFdPUkQgZmxhZ3MsIExQQ1dTVFIgc3JjLCBJTlQgc3JjbGVuLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIExQU1RSIGRzdCwgSU5UIGRzdGxlbiwgTFBDU1RSIGRlZmNoYXIsIEJPT0wgKnVzZWQgKQp7CiAgICBjb25zdCB1bmlvbiBjcHRhYmxlICp0YWJsZTsKICAgIGludCByZXQsIHVzZWRfdG1wOwoKICAgIGlmICghc3JjIHx8ICghZHN0ICYmIGRzdGxlbikpCiAgICB7CiAgICAgICAgU2V0TGFzdEVycm9yKCBFUlJPUl9JTlZBTElEX1BBUkFNRVRFUiApOwogICAgICAgIHJldHVybiAwOwogICAgfQoKICAgIGlmIChzcmNsZW4gPCAwKSBzcmNsZW4gPSBzdHJsZW5XKHNyYykgKyAxOwoKICAgIHN3aXRjaChwYWdlKQogICAgewogICAgY2FzZSBDUF9TWU1CT0w6CiAgICAgICAgaWYoIGZsYWdzIHx8IGRlZmNoYXIgfHwgdXNlZCkKICAgICAgICB7CiAgICAgICAgICAgIFNldExhc3RFcnJvciggRVJST1JfSU5WQUxJRF9QQVJBTUVURVIgKTsKICAgICAgICAgICAgcmV0dXJuIDA7CiAgICAgICAgfQogICAgICAgIHJldCA9IHdpbmVfY3BzeW1ib2xfd2NzdG9tYnMoIHNyYywgc3JjbGVuLCBkc3QsIGRzdGxlbiApOwogICAgICAgIGJyZWFrOwogICAgY2FzZSBDUF9VVEY3OgogICAgICAgIEZJWE1FKCJVVEYtNyBub3Qgc3VwcG9ydGVkXG4iKTsKICAgICAgICBTZXRMYXN0RXJyb3IoIEVSUk9SX0NBTExfTk9UX0lNUExFTUVOVEVEICk7CiAgICAgICAgcmV0dXJuIDA7CiAgICBjYXNlIENQX1VOSVhDUDoKICAgICAgICBpZiAodW5peF9jcHRhYmxlKQogICAgICAgIHsKICAgICAgICAgICAgcmV0ID0gd2luZV9jcF93Y3N0b21icyggdW5peF9jcHRhYmxlLCBmbGFncywgc3JjLCBzcmNsZW4sIGRzdCwgZHN0bGVuLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkZWZjaGFyLCB1c2VkID8gJnVzZWRfdG1wIDogTlVMTCApOwogICAgICAgICAgICBicmVhazsKICAgICAgICB9CiAgICAgICAgLyogZmFsbCB0aHJvdWdoICovCiAgICBjYXNlIENQX1VURjg6CiAgICAgICAgaWYgKHVzZWQpICp1c2VkID0gRkFMU0U7ICAvKiBhbGwgY2hhcnMgYXJlIHZhbGlkIGZvciBVVEYtOCAqLwogICAgICAgIHJldCA9IHdpbmVfdXRmOF93Y3N0b21icyggc3JjLCBzcmNsZW4sIGRzdCwgZHN0bGVuICk7CiAgICAgICAgYnJlYWs7CiAgICBkZWZhdWx0OgogICAgICAgIGlmICghKHRhYmxlID0gZ2V0X2NvZGVwYWdlX3RhYmxlKCBwYWdlICkpKQogICAgICAgIHsKICAgICAgICAgICAgU2V0TGFzdEVycm9yKCBFUlJPUl9JTlZBTElEX1BBUkFNRVRFUiApOwogICAgICAgICAgICByZXR1cm4gMDsKICAgICAgICB9CiAgICAgICAgcmV0ID0gd2luZV9jcF93Y3N0b21icyggdGFibGUsIGZsYWdzLCBzcmMsIHNyY2xlbiwgZHN0LCBkc3RsZW4sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGVmY2hhciwgdXNlZCA/ICZ1c2VkX3RtcCA6IE5VTEwgKTsKICAgICAgICBpZiAodXNlZCkgKnVzZWQgPSB1c2VkX3RtcDsKICAgICAgICBicmVhazsKICAgIH0KCiAgICBpZiAocmV0IDwgMCkKICAgIHsKICAgICAgICBzd2l0Y2gocmV0KQogICAgICAgIHsKICAgICAgICBjYXNlIC0xOiBTZXRMYXN0RXJyb3IoIEVSUk9SX0lOU1VGRklDSUVOVF9CVUZGRVIgKTsgYnJlYWs7CiAgICAgICAgY2FzZSAtMjogU2V0TGFzdEVycm9yKCBFUlJPUl9OT19VTklDT0RFX1RSQU5TTEFUSU9OICk7IGJyZWFrOwogICAgICAgIH0KICAgICAgICByZXQgPSAwOwogICAgfQogICAgVFJBQ0UoImNwICVkICVzIC0+ICVzXG4iLCBwYWdlLCBkZWJ1Z3N0cl93KHNyYyksIGRlYnVnc3RyX2EoZHN0KSk7CiAgICByZXR1cm4gcmV0Owp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgICAgICBHZXRUaHJlYWRMb2NhbGUgICAgKEtFUk5FTDMyLkApCiAqCiAqIEdldCB0aGUgY3VycmVudCB0aHJlYWRzIGxvY2FsZS4KICoKICogUEFSQU1TCiAqICBOb25lLgogKgogKiBSRVRVUk5TCiAqICBUaGUgTENJRCBjdXJyZW50bHkgYXNzb2NhdGVkIHdpdGggdGhlIGNhbGxpbmcgdGhyZWFkLgogKi8KTENJRCBXSU5BUEkgR2V0VGhyZWFkTG9jYWxlKHZvaWQpCnsKICAgIExDSUQgcmV0ID0gTnRDdXJyZW50VGViKCktPkN1cnJlbnRMb2NhbGU7CiAgICBpZiAoIXJldCkgTnRDdXJyZW50VGViKCktPkN1cnJlbnRMb2NhbGUgPSByZXQgPSBHZXRVc2VyRGVmYXVsdExDSUQoKTsKICAgIHJldHVybiByZXQ7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgICAgICBTZXRUaHJlYWRMb2NhbGUgICAgKEtFUk5FTDMyLkApCiAqCiAqIFNldCB0aGUgY3VycmVudCB0aHJlYWRzIGxvY2FsZS4KICoKICogUEFSQU1TCiAqICBsY2lkIFtJXSBMQ0lEIG9mIHRoZSBsb2NhbGUgdG8gc2V0CiAqCiAqIFJFVFVSTlMKICogIFN1Y2Nlc3M6IFRSVUUuIFRoZSB0aHJlYWRzIGxvY2FsZSBpcyBzZXQgdG8gbGNpZC4KICogIEZhaWx1cmU6IEZBTFNFLiBVc2UgR2V0TGFzdEVycm9yKCkgdG8gZGV0ZXJtaW5lIHRoZSBjYXVzZS4KICovCkJPT0wgV0lOQVBJIFNldFRocmVhZExvY2FsZSggTENJRCBsY2lkICkKewogICAgVFJBQ0UoIigweCUwNGxYKVxuIiwgbGNpZCk7CgogICAgbGNpZCA9IENvbnZlcnREZWZhdWx0TG9jYWxlKGxjaWQpOwoKICAgIGlmIChsY2lkICE9IEdldFRocmVhZExvY2FsZSgpKQogICAgewogICAgICAgIGlmICghSXNWYWxpZExvY2FsZShsY2lkLCBMQ0lEX1NVUFBPUlRFRCkpCiAgICAgICAgewogICAgICAgICAgICBTZXRMYXN0RXJyb3IoRVJST1JfSU5WQUxJRF9QQVJBTUVURVIpOwogICAgICAgICAgICByZXR1cm4gRkFMU0U7CiAgICAgICAgfQoKICAgICAgICBOdEN1cnJlbnRUZWIoKS0+Q3VycmVudExvY2FsZSA9IGxjaWQ7CiAgICAgICAgTnRDdXJyZW50VGViKCktPmNvZGVfcGFnZSA9IGdldF9sY2lkX2NvZGVwYWdlKCBsY2lkICk7CiAgICB9CiAgICByZXR1cm4gVFJVRTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJQ29udmVydERlZmF1bHRMb2NhbGUgKEtFUk5FTDMyLkApCiAqCiAqIENvbnZlcnQgYSBkZWZhdWx0IGxvY2FsZSBpZGVudGlmaWVyIGludG8gYSByZWFsIGlkZW50aWZpZXIuCiAqCiAqIFBBUkFNUwogKiAgbGNpZCBbSV0gTENJRCBpZGVudGlmaWVyIG9mIHRoZSBsb2NhbGUgdG8gY29udmVydAogKgogKiBSRVRVUk5TCiAqICBsY2lkIHVuY2hhbmdlZCwgaWYgbm90IGEgZGVmYXVsdCBsb2NhbGUgb3IgaXRzIHN1Ymxhbmd1YWdlIGlzCiAqICAgbm90IFNVQkxBTkdfTkVVVFJBTC4KICogIEdldFN5c3RlbURlZmF1bHRMQ0lEKCksIGlmIGxjaWQgPT0gTE9DQUxFX1NZU1RFTV9ERUZBVUxULgogKiAgR2V0VXNlckRlZmF1bHRMQ0lEKCksIGlmIGxjaWQgPT0gTE9DQUxFX1VTRVJfREVGQVVMVCBvciBMT0NBTEVfTkVVVFJBTC4KICogIE90aGVyd2lzZSwgbGNpZCB3aXRoIHN1Ymxhbmd1YWdlIGNoYW5nZWQgdG8gU1VCTEFOR19ERUZBVUxULgogKi8KTENJRCBXSU5BUEkgQ29udmVydERlZmF1bHRMb2NhbGUoIExDSUQgbGNpZCApCnsKICAgIExBTkdJRCBsYW5naWQ7CgogICAgc3dpdGNoIChsY2lkKQogICAgewogICAgY2FzZSBMT0NBTEVfU1lTVEVNX0RFRkFVTFQ6CiAgICAgICAgbGNpZCA9IEdldFN5c3RlbURlZmF1bHRMQ0lEKCk7CiAgICAgICAgYnJlYWs7CiAgICBjYXNlIExPQ0FMRV9VU0VSX0RFRkFVTFQ6CiAgICBjYXNlIExPQ0FMRV9ORVVUUkFMOgogICAgICAgIGxjaWQgPSBHZXRVc2VyRGVmYXVsdExDSUQoKTsKICAgICAgICBicmVhazsKICAgIGRlZmF1bHQ6CiAgICAgICAgLyogUmVwbGFjZSBTVUJMQU5HX05FVVRSQUwgd2l0aCBTVUJMQU5HX0RFRkFVTFQgKi8KICAgICAgICBsYW5naWQgPSBMQU5HSURGUk9NTENJRChsY2lkKTsKICAgICAgICBpZiAoU1VCTEFOR0lEKGxhbmdpZCkgPT0gU1VCTEFOR19ORVVUUkFMKQogICAgICAgIHsKICAgICAgICAgIGxhbmdpZCA9IE1BS0VMQU5HSUQoUFJJTUFSWUxBTkdJRChsYW5naWQpLCBTVUJMQU5HX0RFRkFVTFQpOwogICAgICAgICAgbGNpZCA9IE1BS0VMQ0lEKGxhbmdpZCwgU09SVElERlJPTUxDSUQobGNpZCkpOwogICAgICAgIH0KICAgIH0KICAgIHJldHVybiBsY2lkOwp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgICAgICAgSXNWYWxpZExvY2FsZSAgIChLRVJORUwzMi5AKQogKgogKiBEZXRlcm1pbmUgaWYgYSBsb2NhbGUgaXMgdmFsaWQuCiAqCiAqIFBBUkFNUwogKiAgbGNpZCAgW0ldIExDSUQgb2YgdGhlIGxvY2FsZSB0byBjaGVjawogKiAgZmxhZ3MgW0ldIExDSURfU1VQUE9SVEVEID0gVmFsaWQsIExDSURfSU5TVEFMTEVEID0gVmFsaWQgYW5kIGluc3RhbGxlZCBvbiB0aGUgc3lzdGVtCiAqCiAqIFJFVFVSTgogKiAgVFJVRSwgIGlmIGxjaWQgaXMgdmFsaWQsCiAqICBGQUxTRSwgb3RoZXJ3aXNlLgogKgogKiBOT1RFUwogKiAgV2luZSBkb2VzIG5vdCBjdXJyZW50bHkgbWFrZSB0aGUgZGlzdGluY3Rpb24gYmV0d2VlbiBzdXBwb3J0ZWQgYW5kIGluc3RhbGxlZC4gQWxsCiAqICBsYW5ndWFnZXMgc3VwcG9ydGVkIGFyZSBpbnN0YWxsZWQgYnkgZGVmYXVsdC4KICovCkJPT0wgV0lOQVBJIElzVmFsaWRMb2NhbGUoIExDSUQgbGNpZCwgRFdPUkQgZmxhZ3MgKQp7CiAgICAvKiBjaGVjayBpZiBsYW5ndWFnZSBpcyByZWdpc3RlcmVkIGluIHRoZSBrZXJuZWwzMiByZXNvdXJjZXMgKi8KICAgIHJldHVybiBGaW5kUmVzb3VyY2VFeFcoIGtlcm5lbDMyX2hhbmRsZSwgKExQV1NUUilSVF9TVFJJTkcsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAoTFBDV1NUUilMT0NBTEVfSUxBTkdVQUdFLCBMQU5HSURGUk9NTENJRChsY2lkKSkgIT0gMDsKfQoKCnN0YXRpYyBCT09MIENBTExCQUNLIGVudW1fbGFuZ19wcm9jX2EoIEhNT0RVTEUgaE1vZHVsZSwgTFBDU1RSIHR5cGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIExQQ1NUUiBuYW1lLCBXT1JEIExhbmdJRCwgTE9ORyBsUGFyYW0gKQp7CiAgICBMT0NBTEVfRU5VTVBST0NBIGxwZm5Mb2NhbGVFbnVtID0gKExPQ0FMRV9FTlVNUFJPQ0EpbFBhcmFtOwogICAgY2hhciBidWZbMjBdOwoKICAgIHNwcmludGYoYnVmLCAiJTA4eCIsIChVSU5UKUxhbmdJRCk7CiAgICByZXR1cm4gbHBmbkxvY2FsZUVudW0oIGJ1ZiApOwp9CgpzdGF0aWMgQk9PTCBDQUxMQkFDSyBlbnVtX2xhbmdfcHJvY193KCBITU9EVUxFIGhNb2R1bGUsIExQQ1dTVFIgdHlwZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTFBDV1NUUiBuYW1lLCBXT1JEIExhbmdJRCwgTE9ORyBsUGFyYW0gKQp7CiAgICBzdGF0aWMgY29uc3QgV0NIQVIgZm9ybWF0V1tdID0geyclJywnMCcsJzgnLCd4JywwfTsKICAgIExPQ0FMRV9FTlVNUFJPQ1cgbHBmbkxvY2FsZUVudW0gPSAoTE9DQUxFX0VOVU1QUk9DVylsUGFyYW07CiAgICBXQ0hBUiBidWZbMjBdOwogICAgc3ByaW50ZlcoIGJ1ZiwgZm9ybWF0VywgKFVJTlQpTGFuZ0lEICk7CiAgICByZXR1cm4gbHBmbkxvY2FsZUVudW0oIGJ1ZiApOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgICAgICBFbnVtU3lzdGVtTG9jYWxlc0EgIChLRVJORUwzMi5AKQogKgogKiBDYWxsIGEgdXNlcnMgZnVuY3Rpb24gZm9yIGVhY2ggbG9jYWxlIGF2YWlsYWJsZSBvbiB0aGUgc3lzdGVtLgogKgogKiBQQVJBTVMKICogIGxwZm5Mb2NhbGVFbnVtIFtJXSBDYWxsYmFjayBmdW5jdGlvbiB0byBjYWxsIGZvciBlYWNoIGxvY2FsZQogKiAgZHdGbGFncyAgICAgICAgW0ldIExPQ0FMRV9TVVBQT1JURUQ9QWxsIHN1cHBvcnRlZCwgTE9DQUxFX0lOU1RBTExFRD1JbnN0YWxsZWQgb25seQogKgogKiBSRVRVUk5TCiAqICBTdWNjZXNzOiBUUlVFLgogKiAgRmFpbHVyZTogRkFMU0UuIFVzZSBHZXRMYXN0RXJyb3IoKSB0byBkZXRlcm1pbmUgdGhlIGNhdXNlLgogKi8KQk9PTCBXSU5BUEkgRW51bVN5c3RlbUxvY2FsZXNBKCBMT0NBTEVfRU5VTVBST0NBIGxwZm5Mb2NhbGVFbnVtLCBEV09SRCBkd0ZsYWdzICkKewogICAgVFJBQ0UoIiglcCwlMDhseClcbiIsIGxwZm5Mb2NhbGVFbnVtLCBkd0ZsYWdzKTsKICAgIEVudW1SZXNvdXJjZUxhbmd1YWdlc0EoIGtlcm5lbDMyX2hhbmRsZSwgKExQU1RSKVJUX1NUUklORywKICAgICAgICAgICAgICAgICAgICAgICAgICAgIChMUENTVFIpTE9DQUxFX0lMQU5HVUFHRSwgZW51bV9sYW5nX3Byb2NfYSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIChMT05HKWxwZm5Mb2NhbGVFbnVtKTsKICAgIHJldHVybiBUUlVFOwp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgICAgICAgRW51bVN5c3RlbUxvY2FsZXNXICAoS0VSTkVMMzIuQCkKICoKICogU2VlIEVudW1TeXN0ZW1Mb2NhbGVzQS4KICovCkJPT0wgV0lOQVBJIEVudW1TeXN0ZW1Mb2NhbGVzVyggTE9DQUxFX0VOVU1QUk9DVyBscGZuTG9jYWxlRW51bSwgRFdPUkQgZHdGbGFncyApCnsKICAgIFRSQUNFKCIoJXAsJTA4bHgpXG4iLCBscGZuTG9jYWxlRW51bSwgZHdGbGFncyk7CiAgICBFbnVtUmVzb3VyY2VMYW5ndWFnZXNXKCBrZXJuZWwzMl9oYW5kbGUsIChMUFdTVFIpUlRfU1RSSU5HLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgKExQQ1dTVFIpTE9DQUxFX0lMQU5HVUFHRSwgZW51bV9sYW5nX3Byb2NfdywKICAgICAgICAgICAgICAgICAgICAgICAgICAgIChMT05HKWxwZm5Mb2NhbGVFbnVtKTsKICAgIHJldHVybiBUUlVFOwp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgICAgICBWZXJMYW5ndWFnZU5hbWVBICAoS0VSTkVMMzIuQCkKICoKICogR2V0IHRoZSBuYW1lIG9mIGEgbGFuZ3VhZ2UuCiAqCiAqIFBBUkFNUwogKiAgd0xhbmcgIFtJXSBMQU5HSUQgb2YgdGhlIGxhbmd1YWdlCiAqICBzekxhbmcgW09dIERlc3RpbmF0aW9uIGZvciB0aGUgbGFuZ3VhZ2UgbmFtZQogKgogKiBSRVRVUk5TCiAqICBTdWNjZXNzOiBUaGUgc2l6ZSBvZiB0aGUgbGFuZ3VhZ2UgbmFtZS4gSWYgc3pMYW5nIGlzIG5vbi1OVUxMLCBpdCBpcyBmaWxsZWQKICogICAgICAgICAgIHdpdGggdGhlIG5hbWUuCiAqICBGYWlsdXJlOiAwLiBVc2UgR2V0TGFzdEVycm9yKCkgdG8gZGV0ZXJtaW5lIHRoZSBjYXVzZS4KICoKICovCkRXT1JEIFdJTkFQSSBWZXJMYW5ndWFnZU5hbWVBKCBVSU5UIHdMYW5nLCBMUFNUUiBzekxhbmcsIFVJTlQgblNpemUgKQp7CiAgICByZXR1cm4gR2V0TG9jYWxlSW5mb0EoIE1BS0VMQ0lEKHdMYW5nLCBTT1JUX0RFRkFVTFQpLCBMT0NBTEVfU0VOR0xBTkdVQUdFLCBzekxhbmcsIG5TaXplICk7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICAgICAgIFZlckxhbmd1YWdlTmFtZVcgIChLRVJORUwzMi5AKQogKgogKiBTZWUgVmVyTGFuZ3VhZ2VOYW1lQS4KICovCkRXT1JEIFdJTkFQSSBWZXJMYW5ndWFnZU5hbWVXKCBVSU5UIHdMYW5nLCBMUFdTVFIgc3pMYW5nLCBVSU5UIG5TaXplICkKewogICAgcmV0dXJuIEdldExvY2FsZUluZm9XKCBNQUtFTENJRCh3TGFuZywgU09SVF9ERUZBVUxUKSwgTE9DQUxFX1NFTkdMQU5HVUFHRSwgc3pMYW5nLCBuU2l6ZSApOwp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgICAgICAgR2V0U3RyaW5nVHlwZVcgICAgKEtFUk5FTDMyLkApCiAqCiAqIFNlZSBHZXRTdHJpbmdUeXBlQS4KICovCkJPT0wgV0lOQVBJIEdldFN0cmluZ1R5cGVXKCBEV09SRCB0eXBlLCBMUENXU1RSIHNyYywgSU5UIGNvdW50LCBMUFdPUkQgY2hhcnR5cGUgKQp7CiAgICBpZiAoY291bnQgPT0gLTEpIGNvdW50ID0gc3RybGVuVyhzcmMpICsgMTsKICAgIHN3aXRjaCh0eXBlKQogICAgewogICAgY2FzZSBDVF9DVFlQRTE6CiAgICAgICAgd2hpbGUgKGNvdW50LS0pICpjaGFydHlwZSsrID0gZ2V0X2NoYXJfdHlwZVcoICpzcmMrKyApICYgMHhmZmY7CiAgICAgICAgYnJlYWs7CiAgICBjYXNlIENUX0NUWVBFMjoKICAgICAgICB3aGlsZSAoY291bnQtLSkgKmNoYXJ0eXBlKysgPSBnZXRfY2hhcl90eXBlVyggKnNyYysrICkgPj4gMTI7CiAgICAgICAgYnJlYWs7CiAgICBjYXNlIENUX0NUWVBFMzoKICAgIHsKICAgICAgICBXQVJOKCJDVF9DVFlQRTM6IHNlbWktc3R1Yi5cbiIpOwogICAgICAgIHdoaWxlIChjb3VudC0tKQogICAgICAgIHsKICAgICAgICAgICAgaW50IGMgPSAqc3JjOwogICAgICAgICAgICBXT1JEIHR5cGUxLCB0eXBlMyA9IDA7IC8qIEMzX05PVEFQUExJQ0FCTEUgKi8KCiAgICAgICAgICAgIHR5cGUxID0gZ2V0X2NoYXJfdHlwZVcoICpzcmMrKyApICYgMHhmZmY7CiAgICAgICAgICAgIC8qIHRyeSB0byBjb25zdHJ1Y3QgdHlwZTMgZnJvbSB0eXBlMSAqLwogICAgICAgICAgICBpZih0eXBlMSAmIEMxX1NQQUNFKSB0eXBlMyB8PSBDM19TWU1CT0w7CiAgICAgICAgICAgIGlmKHR5cGUxICYgQzFfQUxQSEEpIHR5cGUzIHw9IEMzX0FMUEhBOwogICAgICAgICAgICBpZiAoKGM+PTB4MzBBMCkmJihjPD0weDMwRkYpKSB0eXBlMyB8PSBDM19LQVRBS0FOQTsKICAgICAgICAgICAgaWYgKChjPj0weDMwNDApJiYoYzw9MHgzMDlGKSkgdHlwZTMgfD0gQzNfSElSQUdBTkE7CiAgICAgICAgICAgIGlmICgoYz49MHg0RTAwKSYmKGM8PTB4OUZBRikpIHR5cGUzIHw9IEMzX0lERU9HUkFQSDsKICAgICAgICAgICAgaWYgKChjPj0weDA2MDApJiYoYzw9MHgwNkZGKSkgdHlwZTMgfD0gQzNfS0FTSElEQTsKICAgICAgICAgICAgaWYgKChjPj0weDMwMDApJiYoYzw9MHgzMDNGKSkgdHlwZTMgfD0gQzNfU1lNQk9MOwoKICAgICAgICAgICAgaWYgKChjPj0weEZGMDApJiYoYzw9MHhGRjYwKSkgdHlwZTMgfD0gQzNfRlVMTFdJRFRIOwogICAgICAgICAgICBpZiAoKGM+PTB4RkYwMCkmJihjPD0weEZGMjApKSB0eXBlMyB8PSBDM19TWU1CT0w7CiAgICAgICAgICAgIGlmICgoYz49MHhGRjNCKSYmKGM8PTB4RkY0MCkpIHR5cGUzIHw9IEMzX1NZTUJPTDsKICAgICAgICAgICAgaWYgKChjPj0weEZGNUIpJiYoYzw9MHhGRjYwKSkgdHlwZTMgfD0gQzNfU1lNQk9MOwogICAgICAgICAgICBpZiAoKGM+PTB4RkYyMSkmJihjPD0weEZGM0EpKSB0eXBlMyB8PSBDM19BTFBIQTsKICAgICAgICAgICAgaWYgKChjPj0weEZGNDEpJiYoYzw9MHhGRjVBKSkgdHlwZTMgfD0gQzNfQUxQSEE7CiAgICAgICAgICAgIGlmICgoYz49MHhGRkUwKSYmKGM8PTB4RkZFNikpIHR5cGUzIHw9IEMzX0ZVTExXSURUSDsKICAgICAgICAgICAgaWYgKChjPj0weEZGRTApJiYoYzw9MHhGRkU2KSkgdHlwZTMgfD0gQzNfU1lNQk9MOwoKICAgICAgICAgICAgaWYgKChjPj0weEZGNjEpJiYoYzw9MHhGRkRDKSkgdHlwZTMgfD0gQzNfSEFMRldJRFRIOwogICAgICAgICAgICBpZiAoKGM+PTB4RkY2MSkmJihjPD0weEZGNjQpKSB0eXBlMyB8PSBDM19TWU1CT0w7CiAgICAgICAgICAgIGlmICgoYz49MHhGRjY1KSYmKGM8PTB4RkY5RikpIHR5cGUzIHw9IEMzX0tBVEFLQU5BOwogICAgICAgICAgICBpZiAoKGM+PTB4RkY2NSkmJihjPD0weEZGOUYpKSB0eXBlMyB8PSBDM19BTFBIQTsKICAgICAgICAgICAgaWYgKChjPj0weEZGRTgpJiYoYzw9MHhGRkVFKSkgdHlwZTMgfD0gQzNfSEFMRldJRFRIOwogICAgICAgICAgICBpZiAoKGM+PTB4RkZFOCkmJihjPD0weEZGRUUpKSB0eXBlMyB8PSBDM19TWU1CT0w7CiAgICAgICAgICAgICpjaGFydHlwZSsrID0gdHlwZTM7CiAgICAgICAgfQogICAgICAgIGJyZWFrOwogICAgfQogICAgZGVmYXVsdDoKICAgICAgICBTZXRMYXN0RXJyb3IoIEVSUk9SX0lOVkFMSURfUEFSQU1FVEVSICk7CiAgICAgICAgcmV0dXJuIEZBTFNFOwogICAgfQogICAgcmV0dXJuIFRSVUU7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgICAgICBHZXRTdHJpbmdUeXBlRXhXICAgIChLRVJORUwzMi5AKQogKgogKiBTZWUgR2V0U3RyaW5nVHlwZUV4QS4KICovCkJPT0wgV0lOQVBJIEdldFN0cmluZ1R5cGVFeFcoIExDSUQgbG9jYWxlLCBEV09SRCB0eXBlLCBMUENXU1RSIHNyYywgSU5UIGNvdW50LCBMUFdPUkQgY2hhcnR5cGUgKQp7CiAgICAvKiBsb2NhbGUgaXMgaWdub3JlZCBmb3IgVW5pY29kZSAqLwogICAgcmV0dXJuIEdldFN0cmluZ1R5cGVXKCB0eXBlLCBzcmMsIGNvdW50LCBjaGFydHlwZSApOwp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgICAgICAgR2V0U3RyaW5nVHlwZUEgICAgKEtFUk5FTDMyLkApCiAqCiAqIEdldCBjaGFyYWN0ZXJpc3RpY3Mgb2YgdGhlIGNoYXJhY3RlcnMgbWFraW5nIHVwIGEgc3RyaW5nLgogKgogKiBQQVJBTVMKICogIGxvY2FsZSAgIFtJXSBMb2NhbGUgSWQgZm9yIHRoZSBzdHJpbmcKICogIHR5cGUgICAgIFtJXSBDVF9DVFlQRTEgPSBjbGFzc2lmaWNhdGlvbiwgQ1RfQ1RZUEUyID0gZGlyZWN0aW9uYWxpdHksIENUX0NUWVBFMyA9IHR5cG9ncmFwaGljIGluZm8KICogIHNyYyAgICAgIFtJXSBTdHJpbmcgdG8gYW5hbHlzZQogKiAgY291bnQgICAgW0ldIExlbmd0aCBvZiBzcmMgaW4gY2hhcnMsIG9yIC0xIGlmIHNyYyBpcyBOVUwgdGVybWluYXRlZAogKiAgY2hhcnR5cGUgW09dIERlc3RpbmF0aW9uIGZvciB0aGUgY2FsY3VsYXRlZCBjaGFyYWN0ZXJpc3RpY3MKICoKICogUkVUVVJOUwogKiAgU3VjY2VzczogVFJVRS4gY2hhcnR5cGUgaXMgZmlsbGVkIHdpdGggdGhlIHJlcXVlc3RlZCBjaGFyYWN0ZXJpc3RpY3Mgb2YgZWFjaCBjaGFyCiAqICAgICAgICAgICBpbiBzcmMuCiAqICBGYWlsdXJlOiBGQUxTRS4gVXNlIEdldExhc3RFcnJvcigpIHRvIGRldGVybWluZSB0aGUgY2F1c2UuCiAqLwpCT09MIFdJTkFQSSBHZXRTdHJpbmdUeXBlQSggTENJRCBsb2NhbGUsIERXT1JEIHR5cGUsIExQQ1NUUiBzcmMsIElOVCBjb3VudCwgTFBXT1JEIGNoYXJ0eXBlICkKewogICAgVUlOVCBjcDsKICAgIElOVCBjb3VudFc7CiAgICBMUFdTVFIgc3JjVzsKICAgIEJPT0wgcmV0ID0gRkFMU0U7CgogICAgaWYoY291bnQgPT0gLTEpIGNvdW50ID0gc3RybGVuKHNyYykgKyAxOwoKICAgIGlmICghKGNwID0gZ2V0X2xjaWRfY29kZXBhZ2UoIGxvY2FsZSApKSkKICAgIHsKICAgICAgICBGSVhNRSgiRm9yIGxvY2FsZSAlMDRseCB1c2luZyBjdXJyZW50IEFOU0kgY29kZSBwYWdlXG4iLCBsb2NhbGUpOwogICAgICAgIGNwID0gR2V0QUNQKCk7CiAgICB9CgogICAgY291bnRXID0gTXVsdGlCeXRlVG9XaWRlQ2hhcihjcCwgMCwgc3JjLCBjb3VudCwgTlVMTCwgMCk7CiAgICBpZigoc3JjVyA9IEhlYXBBbGxvYyhHZXRQcm9jZXNzSGVhcCgpLCAwLCBjb3VudFcgKiBzaXplb2YoV0NIQVIpKSkpCiAgICB7CiAgICAgICAgTXVsdGlCeXRlVG9XaWRlQ2hhcihjcCwgMCwgc3JjLCBjb3VudCwgc3JjVywgY291bnRXKTsKICAgIC8qCiAgICAgKiBOT1RFOiB0aGUgdGFyZ2V0IGJ1ZmZlciBoYXMgMSB3b3JkIGZvciBlYWNoIENIQVJBQ1RFUiBpbiB0aGUgc291cmNlCiAgICAgKiBzdHJpbmcsIHdpdGggbXVsdGlieXRlIGNoYXJhY3RlcnMgdGhlcmUgbWF5YmUgYmUgbW9yZSBieXRlcyBpbiBjb3VudAogICAgICogdGhhbiBjaGFyYWN0ZXIgc3BhY2UgaW4gdGhlIGJ1ZmZlciEKICAgICAqLwogICAgICAgIHJldCA9IEdldFN0cmluZ1R5cGVXKHR5cGUsIHNyY1csIGNvdW50VywgY2hhcnR5cGUpOwogICAgICAgIEhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksIDAsIHNyY1cpOwogICAgfQogICAgcmV0dXJuIHJldDsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgICAgICAgR2V0U3RyaW5nVHlwZUV4QSAgICAoS0VSTkVMMzIuQCkKICoKICogR2V0IGNoYXJhY3RlcmlzdGljcyBvZiB0aGUgY2hhcmFjdGVycyBtYWtpbmcgdXAgYSBzdHJpbmcuCiAqCiAqIFBBUkFNUwogKiAgbG9jYWxlICAgW0ldIExvY2FsZSBJZCBmb3IgdGhlIHN0cmluZwogKiAgdHlwZSAgICAgW0ldIENUX0NUWVBFMSA9IGNsYXNzaWZpY2F0aW9uLCBDVF9DVFlQRTIgPSBkaXJlY3Rpb25hbGl0eSwgQ1RfQ1RZUEUzID0gdHlwb2dyYXBoaWMgaW5mbwogKiAgc3JjICAgICAgW0ldIFN0cmluZyB0byBhbmFseXNlCiAqICBjb3VudCAgICBbSV0gTGVuZ3RoIG9mIHNyYyBpbiBjaGFycywgb3IgLTEgaWYgc3JjIGlzIE5VTCB0ZXJtaW5hdGVkCiAqICBjaGFydHlwZSBbT10gRGVzdGluYXRpb24gZm9yIHRoZSBjYWxjdWxhdGVkIGNoYXJhY3RlcmlzdGljcwogKgogKiBSRVRVUk5TCiAqICBTdWNjZXNzOiBUUlVFLiBjaGFydHlwZSBpcyBmaWxsZWQgd2l0aCB0aGUgcmVxdWVzdGVkIGNoYXJhY3RlcmlzdGljcyBvZiBlYWNoIGNoYXIKICogICAgICAgICAgIGluIHNyYy4KICogIEZhaWx1cmU6IEZBTFNFLiBVc2UgR2V0TGFzdEVycm9yKCkgdG8gZGV0ZXJtaW5lIHRoZSBjYXVzZS4KICovCkJPT0wgV0lOQVBJIEdldFN0cmluZ1R5cGVFeEEoIExDSUQgbG9jYWxlLCBEV09SRCB0eXBlLCBMUENTVFIgc3JjLCBJTlQgY291bnQsIExQV09SRCBjaGFydHlwZSApCnsKICAgIHJldHVybiBHZXRTdHJpbmdUeXBlQShsb2NhbGUsIHR5cGUsIHNyYywgY291bnQsIGNoYXJ0eXBlKTsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgICAgICBMQ01hcFN0cmluZ1cgICAgKEtFUk5FTDMyLkApCiAqCiAqIFNlZSBMQ01hcFN0cmluZ0EuCiAqLwpJTlQgV0lOQVBJIExDTWFwU3RyaW5nVyhMQ0lEIGxjaWQsIERXT1JEIGZsYWdzLCBMUENXU1RSIHNyYywgSU5UIHNyY2xlbiwKICAgICAgICAgICAgICAgICAgICAgICAgTFBXU1RSIGRzdCwgSU5UIGRzdGxlbikKewogICAgTFBXU1RSIGRzdF9wdHI7CgogICAgaWYgKCFzcmMgfHwgIXNyY2xlbiB8fCBkc3RsZW4gPCAwKQogICAgewogICAgICAgIFNldExhc3RFcnJvcihFUlJPUl9JTlZBTElEX1BBUkFNRVRFUik7CiAgICAgICAgcmV0dXJuIDA7CiAgICB9CgogICAgLyogbXV0dWFsbHkgZXhjbHVzaXZlIGZsYWdzICovCiAgICBpZiAoKGZsYWdzICYgKExDTUFQX0xPV0VSQ0FTRSB8IExDTUFQX1VQUEVSQ0FTRSkpID09IChMQ01BUF9MT1dFUkNBU0UgfCBMQ01BUF9VUFBFUkNBU0UpIHx8CiAgICAgICAgKGZsYWdzICYgKExDTUFQX0hJUkFHQU5BIHwgTENNQVBfS0FUQUtBTkEpKSA9PSAoTENNQVBfSElSQUdBTkEgfCBMQ01BUF9LQVRBS0FOQSkgfHwKICAgICAgICAoZmxhZ3MgJiAoTENNQVBfSEFMRldJRFRIIHwgTENNQVBfRlVMTFdJRFRIKSkgPT0gKExDTUFQX0hBTEZXSURUSCB8IExDTUFQX0ZVTExXSURUSCkgfHwKICAgICAgICAoZmxhZ3MgJiAoTENNQVBfVFJBRElUSU9OQUxfQ0hJTkVTRSB8IExDTUFQX1NJTVBMSUZJRURfQ0hJTkVTRSkpID09IChMQ01BUF9UUkFESVRJT05BTF9DSElORVNFIHwgTENNQVBfU0lNUExJRklFRF9DSElORVNFKSkKICAgIHsKICAgICAgICBTZXRMYXN0RXJyb3IoRVJST1JfSU5WQUxJRF9GTEFHUyk7CiAgICAgICAgcmV0dXJuIDA7CiAgICB9CgogICAgaWYgKCFkc3RsZW4pIGRzdCA9IE5VTEw7CgogICAgbGNpZCA9IENvbnZlcnREZWZhdWx0TG9jYWxlKGxjaWQpOwoKICAgIGlmIChmbGFncyAmIExDTUFQX1NPUlRLRVkpCiAgICB7CiAgICAgICAgaWYgKHNyYyA9PSBkc3QpCiAgICAgICAgewogICAgICAgICAgICBTZXRMYXN0RXJyb3IoRVJST1JfSU5WQUxJRF9GTEFHUyk7CiAgICAgICAgICAgIHJldHVybiAwOwogICAgICAgIH0KCiAgICAgICAgaWYgKHNyY2xlbiA8IDApIHNyY2xlbiA9IHN0cmxlblcoc3JjKTsKCiAgICAgICAgVFJBQ0UoIigweCUwNGx4LDB4JTA4bHgsJXMsJWQsJXAsJWQpXG4iLAogICAgICAgICAgICAgIGxjaWQsIGZsYWdzLCBkZWJ1Z3N0cl93bihzcmMsIHNyY2xlbiksIHNyY2xlbiwgZHN0LCBkc3RsZW4pOwoKICAgICAgICByZXR1cm4gd2luZV9nZXRfc29ydGtleShmbGFncywgc3JjLCBzcmNsZW4sIChjaGFyICopZHN0LCBkc3RsZW4pOwogICAgfQoKICAgIC8qIFNPUlRfU1RSSU5HU09SVCBtdXN0IGJlIHVzZWQgZXhjbHVzaXZlbHkgd2l0aCBMQ01BUF9TT1JUS0VZICovCiAgICBpZiAoZmxhZ3MgJiBTT1JUX1NUUklOR1NPUlQpCiAgICB7CiAgICAgICAgU2V0TGFzdEVycm9yKEVSUk9SX0lOVkFMSURfRkxBR1MpOwogICAgICAgIHJldHVybiAwOwogICAgfQoKICAgIGlmIChzcmNsZW4gPCAwKSBzcmNsZW4gPSBzdHJsZW5XKHNyYykgKyAxOwoKICAgIFRSQUNFKCIoMHglMDRseCwweCUwOGx4LCVzLCVkLCVwLCVkKVxuIiwKICAgICAgICAgIGxjaWQsIGZsYWdzLCBkZWJ1Z3N0cl93bihzcmMsIHNyY2xlbiksIHNyY2xlbiwgZHN0LCBkc3RsZW4pOwoKICAgIGlmICghZHN0KSAvKiByZXR1cm4gcmVxdWlyZWQgc3RyaW5nIGxlbmd0aCAqLwogICAgewogICAgICAgIElOVCBsZW47CgogICAgICAgIGZvciAobGVuID0gMDsgc3JjbGVuOyBzcmMrKywgc3JjbGVuLS0pCiAgICAgICAgewogICAgICAgICAgICBXQ0hBUiB3Y2ggPSAqc3JjOwogICAgICAgICAgICAvKiB0ZXN0cyBzaG93IHRoYXQgd2luMmsganVzdCBpZ25vcmVzIE5PUk1fSUdOT1JFTk9OU1BBQ0UsCiAgICAgICAgICAgICAqIGFuZCBza2lwcyB3aGl0ZSBzcGFjZSBhbmQgcHVuY3R1YXRpb24gY2hhcmFjdGVycyBmb3IKICAgICAgICAgICAgICogTk9STV9JR05PUkVTWU1CT0xTLgogICAgICAgICAgICAgKi8KICAgICAgICAgICAgaWYgKChmbGFncyAmIE5PUk1fSUdOT1JFU1lNQk9MUykgJiYgKGdldF9jaGFyX3R5cGVXKHdjaCkgJiAoQzFfUFVOQ1QgfCBDMV9TUEFDRSkpKQogICAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgIGxlbisrOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbGVuOwogICAgfQoKICAgIGlmIChmbGFncyAmIExDTUFQX1VQUEVSQ0FTRSkKICAgIHsKICAgICAgICBmb3IgKGRzdF9wdHIgPSBkc3Q7IHNyY2xlbiAmJiBkc3RsZW47IHNyYysrLCBzcmNsZW4tLSkKICAgICAgICB7CiAgICAgICAgICAgIFdDSEFSIHdjaCA9ICpzcmM7CiAgICAgICAgICAgIGlmICgoZmxhZ3MgJiBOT1JNX0lHTk9SRVNZTUJPTFMpICYmIChnZXRfY2hhcl90eXBlVyh3Y2gpICYgKEMxX1BVTkNUIHwgQzFfU1BBQ0UpKSkKICAgICAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgICAqZHN0X3B0cisrID0gdG91cHBlclcod2NoKTsKICAgICAgICAgICAgZHN0bGVuLS07CiAgICAgICAgfQogICAgfQogICAgZWxzZSBpZiAoZmxhZ3MgJiBMQ01BUF9MT1dFUkNBU0UpCiAgICB7CiAgICAgICAgZm9yIChkc3RfcHRyID0gZHN0OyBzcmNsZW4gJiYgZHN0bGVuOyBzcmMrKywgc3JjbGVuLS0pCiAgICAgICAgewogICAgICAgICAgICBXQ0hBUiB3Y2ggPSAqc3JjOwogICAgICAgICAgICBpZiAoKGZsYWdzICYgTk9STV9JR05PUkVTWU1CT0xTKSAmJiAoZ2V0X2NoYXJfdHlwZVcod2NoKSAmIChDMV9QVU5DVCB8IEMxX1NQQUNFKSkpCiAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgKmRzdF9wdHIrKyA9IHRvbG93ZXJXKHdjaCk7CiAgICAgICAgICAgIGRzdGxlbi0tOwogICAgICAgIH0KICAgIH0KICAgIGVsc2UKICAgIHsKICAgICAgICBpZiAoc3JjID09IGRzdCkKICAgICAgICB7CiAgICAgICAgICAgIFNldExhc3RFcnJvcihFUlJPUl9JTlZBTElEX0ZMQUdTKTsKICAgICAgICAgICAgcmV0dXJuIDA7CiAgICAgICAgfQogICAgICAgIGZvciAoZHN0X3B0ciA9IGRzdDsgc3JjbGVuICYmIGRzdGxlbjsgc3JjKyssIHNyY2xlbi0tKQogICAgICAgIHsKICAgICAgICAgICAgV0NIQVIgd2NoID0gKnNyYzsKICAgICAgICAgICAgaWYgKChmbGFncyAmIE5PUk1fSUdOT1JFU1lNQk9MUykgJiYgKGdldF9jaGFyX3R5cGVXKHdjaCkgJiAoQzFfUFVOQ1QgfCBDMV9TUEFDRSkpKQogICAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgICpkc3RfcHRyKysgPSB3Y2g7CiAgICAgICAgICAgIGRzdGxlbi0tOwogICAgICAgIH0KICAgIH0KCiAgICBpZiAoc3JjbGVuKQogICAgewogICAgICAgIFNldExhc3RFcnJvcihFUlJPUl9JTlNVRkZJQ0lFTlRfQlVGRkVSKTsKICAgICAgICByZXR1cm4gMDsKICAgIH0KCiAgICByZXR1cm4gZHN0X3B0ciAtIGRzdDsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICAgICAgIExDTWFwU3RyaW5nQSAgICAoS0VSTkVMMzIuQCkKICoKICogTWFwIGNoYXJhY3RlcnMgaW4gYSBsb2NhbGUgc2Vuc2l0aXZlIHN0cmluZy4KICoKICogUEFSQU1TCiAqICBsY2lkICAgW0ldIExDSUQgZm9yIHRoZSBjb252ZXJzaW9uLgogKiAgZmxhZ3MgIFtJXSBGbGFncyBjb250cm9sbGluZyB0aGUgbWFwcGluZyAoTENNQVBfIGNvbnN0YW50cyBmcm9tICJ3aW5ubHMuaCIpLgogKiAgc3JjICAgIFtJXSBTdHJpbmcgdG8gbWFwCiAqICBzcmNsZW4gW0ldIExlbmd0aCBvZiBzcmMgaW4gY2hhcnMsIG9yIC0xIGlmIHNyYyBpcyBOVUwgdGVybWluYXRlZAogKiAgZHN0ICAgIFtPXSBEZXN0aW5hdGlvbiBmb3IgbWFwcGVkIHN0cmluZwogKiAgZHN0bGVuIFtJXSBMZW5ndGggb2YgZHN0IGluIGNoYXJhY3RlcnMKICoKICogUkVUVVJOUwogKiAgU3VjY2VzczogVGhlIGxlbmd0aCBvZiB0aGUgbWFwcGVkIHN0cmluZyBpbiBkc3QsIGluY2x1ZGluZyB0aGUgTlVMIHRlcm1pbmF0b3IuCiAqICBGYWlsdXJlOiAwLiBVc2UgR2V0TGFzdEVycm9yKCkgdG8gZGV0ZXJtaW5lIHRoZSBjYXVzZS4KICovCklOVCBXSU5BUEkgTENNYXBTdHJpbmdBKExDSUQgbGNpZCwgRFdPUkQgZmxhZ3MsIExQQ1NUUiBzcmMsIElOVCBzcmNsZW4sCiAgICAgICAgICAgICAgICAgICAgICAgIExQU1RSIGRzdCwgSU5UIGRzdGxlbikKewogICAgV0NIQVIgKmJ1ZlcgPSBOdEN1cnJlbnRUZWIoKS0+U3RhdGljVW5pY29kZUJ1ZmZlcjsKICAgIExQV1NUUiBzcmNXLCBkc3RXOwogICAgSU5UIHJldCA9IDAsIHNyY2xlblcsIGRzdGxlblc7CiAgICBVSU5UIGxvY2FsZV9jcCA9IENQX0FDUDsKCiAgICBpZiAoIXNyYyB8fCAhc3JjbGVuIHx8IGRzdGxlbiA8IDApCiAgICB7CiAgICAgICAgU2V0TGFzdEVycm9yKEVSUk9SX0lOVkFMSURfUEFSQU1FVEVSKTsKICAgICAgICByZXR1cm4gMDsKICAgIH0KCiAgICBpZiAoIShmbGFncyAmIExPQ0FMRV9VU0VfQ1BfQUNQKSkgbG9jYWxlX2NwID0gZ2V0X2xjaWRfY29kZXBhZ2UoIGxjaWQgKTsKCiAgICBzcmNsZW5XID0gTXVsdGlCeXRlVG9XaWRlQ2hhcihsb2NhbGVfY3AsIDAsIHNyYywgc3JjbGVuLCBidWZXLCAyNjApOwogICAgaWYgKHNyY2xlblcpCiAgICAgICAgc3JjVyA9IGJ1Zlc7CiAgICBlbHNlCiAgICB7CiAgICAgICAgc3JjbGVuVyA9IE11bHRpQnl0ZVRvV2lkZUNoYXIobG9jYWxlX2NwLCAwLCBzcmMsIHNyY2xlbiwgTlVMTCwgMCk7CiAgICAgICAgc3JjVyA9IEhlYXBBbGxvYyhHZXRQcm9jZXNzSGVhcCgpLCAwLCBzcmNsZW5XICogc2l6ZW9mKFdDSEFSKSk7CiAgICAgICAgaWYgKCFzcmNXKQogICAgICAgIHsKICAgICAgICAgICAgU2V0TGFzdEVycm9yKEVSUk9SX05PVF9FTk9VR0hfTUVNT1JZKTsKICAgICAgICAgICAgcmV0dXJuIDA7CiAgICAgICAgfQogICAgICAgIE11bHRpQnl0ZVRvV2lkZUNoYXIobG9jYWxlX2NwLCAwLCBzcmMsIHNyY2xlbiwgc3JjVywgc3JjbGVuVyk7CiAgICB9CgogICAgaWYgKGZsYWdzICYgTENNQVBfU09SVEtFWSkKICAgIHsKICAgICAgICBpZiAoc3JjID09IGRzdCkKICAgICAgICB7CiAgICAgICAgICAgIFNldExhc3RFcnJvcihFUlJPUl9JTlZBTElEX0ZMQUdTKTsKICAgICAgICAgICAgZ290byBtYXBfc3RyaW5nX2V4aXQ7CiAgICAgICAgfQogICAgICAgIHJldCA9IHdpbmVfZ2V0X3NvcnRrZXkoZmxhZ3MsIHNyY1csIHNyY2xlblcsIGRzdCwgZHN0bGVuKTsKICAgICAgICBnb3RvIG1hcF9zdHJpbmdfZXhpdDsKICAgIH0KCiAgICBpZiAoZmxhZ3MgJiBTT1JUX1NUUklOR1NPUlQpCiAgICB7CiAgICAgICAgU2V0TGFzdEVycm9yKEVSUk9SX0lOVkFMSURfRkxBR1MpOwogICAgICAgIGdvdG8gbWFwX3N0cmluZ19leGl0OwogICAgfQoKICAgIGRzdGxlblcgPSBMQ01hcFN0cmluZ1cobGNpZCwgZmxhZ3MsIHNyY1csIHNyY2xlblcsIE5VTEwsIDApOwogICAgaWYgKCFkc3RsZW5XKQogICAgICAgIGdvdG8gbWFwX3N0cmluZ19leGl0OwoKICAgIGRzdFcgPSBIZWFwQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgZHN0bGVuVyAqIHNpemVvZihXQ0hBUikpOwogICAgaWYgKCFkc3RXKQogICAgewogICAgICAgIFNldExhc3RFcnJvcihFUlJPUl9OT1RfRU5PVUdIX01FTU9SWSk7CiAgICAgICAgZ290byBtYXBfc3RyaW5nX2V4aXQ7CiAgICB9CgogICAgTENNYXBTdHJpbmdXKGxjaWQsIGZsYWdzLCBzcmNXLCBzcmNsZW5XLCBkc3RXLCBkc3RsZW5XKTsKICAgIHJldCA9IFdpZGVDaGFyVG9NdWx0aUJ5dGUobG9jYWxlX2NwLCAwLCBkc3RXLCBkc3RsZW5XLCBkc3QsIGRzdGxlbiwgTlVMTCwgTlVMTCk7CiAgICBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLCAwLCBkc3RXKTsKCm1hcF9zdHJpbmdfZXhpdDoKICAgIGlmIChzcmNXICE9IGJ1ZlcpIEhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksIDAsIHNyY1cpOwogICAgcmV0dXJuIHJldDsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICAgICAgIEZvbGRTdHJpbmdBICAgIChLRVJORUwzMi5AKQogKgogKiBNYXAgY2hhcmFjdGVycyBpbiBhIHN0cmluZy4KICoKICogUEFSQU1TCiAqICBkd0ZsYWdzIFtJXSBGbGFncyBjb250cm9sbGluZyBjaGFycyB0byBtYXAgKE1BUF8gY29uc3RhbnRzIGZyb20gIndpbm5scy5oIikKICogIHNyYyAgICAgW0ldIFN0cmluZyB0byBtYXAKICogIHNyY2xlbiAgW0ldIExlbmd0aCBvZiBzcmMsIG9yIC0xIGlmIHNyYyBpcyBOVUwgdGVybWluYXRlZAogKiAgZHN0ICAgICBbT10gRGVzdGluYXRpb24gZm9yIG1hcHBlZCBzdHJpbmcKICogIGRzdGxlbiAgW0ldIExlbmd0aCBvZiBkc3QsIG9yIDAgdG8gZmluZCB0aGUgcmVxdWlyZWQgbGVuZ3RoIGZvciB0aGUgbWFwcGVkIHN0cmluZwogKgogKiBSRVRVUk5TCiAqICBTdWNjZXNzOiBUaGUgbGVuZ3RoIG9mIHRoZSBzdHJpbmcgd3JpdHRlbiB0byBkc3QsIGluY2x1ZGluZyB0aGUgdGVybWluYXRpbmcgTlVMLiBJZgogKiAgICAgICAgICAgZHN0bGVuIGlzIDAsIHRoZSB2YWx1ZSByZXR1cm5lZCBpcyB0aGUgc2FtZSwgYnV0IG5vdGhpbmcgaXMgd3JpdHRlbiB0byBkc3QsCiAqICAgICAgICAgICBhbmQgZHN0IG1heSBiZSBOVUxMLgogKiAgRmFpbHVyZTogMC4gVXNlIEdldExhc3RFcnJvcigpIHRvIGRldGVybWluZSB0aGUgY2F1c2UuCiAqLwpJTlQgV0lOQVBJIEZvbGRTdHJpbmdBKERXT1JEIGR3RmxhZ3MsIExQQ1NUUiBzcmMsIElOVCBzcmNsZW4sCiAgICAgICAgICAgICAgICAgICAgICAgTFBTVFIgZHN0LCBJTlQgZHN0bGVuKQp7CiAgICBJTlQgcmV0ID0gMCwgc3JjbGVuVyA9IDA7CiAgICBXQ0hBUiAqc3JjVyA9IE5VTEwsICpkc3RXID0gTlVMTDsKCiAgICBpZiAoIXNyYyB8fCAhc3JjbGVuIHx8IGRzdGxlbiA8IDAgfHwgKGRzdGxlbiAmJiAhZHN0KSB8fCBzcmMgPT0gZHN0KQogICAgewogICAgICAgIFNldExhc3RFcnJvcihFUlJPUl9JTlZBTElEX1BBUkFNRVRFUik7CiAgICAgICAgcmV0dXJuIDA7CiAgICB9CgogICAgc3JjbGVuVyA9IE11bHRpQnl0ZVRvV2lkZUNoYXIoQ1BfQUNQLCBkd0ZsYWdzICYgTUFQX0NPTVBPU0lURSA/IE1CX0NPTVBPU0lURSA6IDAsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzcmMsIHNyY2xlbiwgTlVMTCwgMCk7CiAgICBzcmNXID0gSGVhcEFsbG9jKEdldFByb2Nlc3NIZWFwKCksIDAsIHNyY2xlblcgKiBzaXplb2YoV0NIQVIpKTsKCiAgICBpZiAoIXNyY1cpCiAgICB7CiAgICAgICAgU2V0TGFzdEVycm9yKEVSUk9SX05PVF9FTk9VR0hfTUVNT1JZKTsKICAgICAgICBnb3RvIEZvbGRTdHJpbmdBX2V4aXQ7CiAgICB9CgogICAgTXVsdGlCeXRlVG9XaWRlQ2hhcihDUF9BQ1AsIGR3RmxhZ3MgJiBNQVBfQ09NUE9TSVRFID8gTUJfQ09NUE9TSVRFIDogMCwKICAgICAgICAgICAgICAgICAgICAgICAgc3JjLCBzcmNsZW4sIHNyY1csIHNyY2xlblcpOwoKICAgIGR3RmxhZ3MgPSAoZHdGbGFncyAmIH5NQVBfUFJFQ09NUE9TRUQpIHwgTUFQX0ZPTERDWk9ORTsKCiAgICByZXQgPSBGb2xkU3RyaW5nVyhkd0ZsYWdzLCBzcmNXLCBzcmNsZW5XLCBOVUxMLCAwKTsKICAgIGlmIChyZXQgJiYgZHN0bGVuKQogICAgewogICAgICAgIGRzdFcgPSBIZWFwQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgcmV0ICogc2l6ZW9mKFdDSEFSKSk7CgogICAgICAgIGlmICghZHN0VykKICAgICAgICB7CiAgICAgICAgICAgIFNldExhc3RFcnJvcihFUlJPUl9OT1RfRU5PVUdIX01FTU9SWSk7CiAgICAgICAgICAgIGdvdG8gRm9sZFN0cmluZ0FfZXhpdDsKICAgICAgICB9CgogICAgICAgIHJldCA9IEZvbGRTdHJpbmdXKGR3RmxhZ3MsIHNyY1csIHNyY2xlblcsIGRzdFcsIHJldCk7CiAgICAgICAgaWYgKCFXaWRlQ2hhclRvTXVsdGlCeXRlKENQX0FDUCwgMCwgZHN0VywgcmV0LCBkc3QsIGRzdGxlbiwgTlVMTCwgTlVMTCkpCiAgICAgICAgewogICAgICAgICAgICByZXQgPSAwOwogICAgICAgICAgICBTZXRMYXN0RXJyb3IoRVJST1JfSU5TVUZGSUNJRU5UX0JVRkZFUik7CiAgICAgICAgfQogICAgfQoKICAgIEhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksIDAsIGRzdFcpOwoKRm9sZFN0cmluZ0FfZXhpdDoKICAgIEhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksIDAsIHNyY1cpOwogICAgcmV0dXJuIHJldDsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICAgICAgIEZvbGRTdHJpbmdXICAgIChLRVJORUwzMi5AKQogKgogKiBTZWUgRm9sZFN0cmluZ0EuCiAqLwpJTlQgV0lOQVBJIEZvbGRTdHJpbmdXKERXT1JEIGR3RmxhZ3MsIExQQ1dTVFIgc3JjLCBJTlQgc3JjbGVuLAogICAgICAgICAgICAgICAgICAgICAgIExQV1NUUiBkc3QsIElOVCBkc3RsZW4pCnsKICAgIGludCByZXQ7CgogICAgc3dpdGNoIChkd0ZsYWdzICYgKE1BUF9DT01QT1NJVEV8TUFQX1BSRUNPTVBPU0VEfE1BUF9FWFBBTkRfTElHQVRVUkVTKSkKICAgIHsKICAgIGNhc2UgMDoKICAgICAgICBpZiAoZHdGbGFncykKICAgICAgICAgIGJyZWFrOwogICAgICAgIC8qIEZhbGwgdGhyb3VnaCBmb3IgZHdGbGFncyA9PSAwICovCiAgICBjYXNlIE1BUF9QUkVDT01QT1NFRHxNQVBfQ09NUE9TSVRFOgogICAgY2FzZSBNQVBfUFJFQ09NUE9TRUR8TUFQX0VYUEFORF9MSUdBVFVSRVM6CiAgICBjYXNlIE1BUF9DT01QT1NJVEV8TUFQX0VYUEFORF9MSUdBVFVSRVM6CiAgICAgICAgU2V0TGFzdEVycm9yKEVSUk9SX0lOVkFMSURfRkxBR1MpOwogICAgICAgIHJldHVybiAwOwogICAgfQoKICAgIGlmICghc3JjIHx8ICFzcmNsZW4gfHwgZHN0bGVuIDwgMCB8fCAoZHN0bGVuICYmICFkc3QpIHx8IHNyYyA9PSBkc3QpCiAgICB7CiAgICAgICAgU2V0TGFzdEVycm9yKEVSUk9SX0lOVkFMSURfUEFSQU1FVEVSKTsKICAgICAgICByZXR1cm4gMDsKICAgIH0KCiAgICByZXQgPSB3aW5lX2ZvbGRfc3RyaW5nKGR3RmxhZ3MsIHNyYywgc3JjbGVuLCBkc3QsIGRzdGxlbik7CiAgICBpZiAoIXJldCkKICAgICAgICBTZXRMYXN0RXJyb3IoRVJST1JfSU5TVUZGSUNJRU5UX0JVRkZFUik7CiAgICByZXR1cm4gcmV0Owp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgICAgICBDb21wYXJlU3RyaW5nVyAgICAoS0VSTkVMMzIuQCkKICoKICogU2VlIENvbXBhcmVTdHJpbmdBLgogKi8KSU5UIFdJTkFQSSBDb21wYXJlU3RyaW5nVyhMQ0lEIGxjaWQsIERXT1JEIHN0eWxlLAogICAgICAgICAgICAgICAgICAgICAgICAgIExQQ1dTVFIgc3RyMSwgSU5UIGxlbjEsIExQQ1dTVFIgc3RyMiwgSU5UIGxlbjIpCnsKICAgIElOVCByZXQ7CgogICAgaWYgKCFzdHIxIHx8ICFzdHIyKQogICAgewogICAgICAgIFNldExhc3RFcnJvcihFUlJPUl9JTlZBTElEX1BBUkFNRVRFUik7CiAgICAgICAgcmV0dXJuIDA7CiAgICB9CgogICAgaWYoIHN0eWxlICYgfihOT1JNX0lHTk9SRUNBU0V8Tk9STV9JR05PUkVOT05TUEFDRXxOT1JNX0lHTk9SRVNZTUJPTFN8CiAgICAgICAgU09SVF9TVFJJTkdTT1JUfE5PUk1fSUdOT1JFS0FOQVRZUEV8Tk9STV9JR05PUkVXSURUSHxMT0NBTEVfVVNFX0NQX0FDUHwweDEwMDAwMDAwKSApCiAgICB7CiAgICAgICAgU2V0TGFzdEVycm9yKEVSUk9SX0lOVkFMSURfRkxBR1MpOwogICAgICAgIHJldHVybiAwOwogICAgfQoKICAgIGlmIChzdHlsZSAmIDB4MTAwMDAwMDApCiAgICAgICAgRklYTUUoIklnbm9yaW5nIHVua25vd24gc3R5bGUgMHgxMDAwMDAwMFxuIik7CgogICAgaWYgKGxlbjEgPCAwKSBsZW4xID0gc3RybGVuVyhzdHIxKTsKICAgIGlmIChsZW4yIDwgMCkgbGVuMiA9IHN0cmxlblcoc3RyMik7CgogICAgcmV0ID0gd2luZV9jb21wYXJlX3N0cmluZyhzdHlsZSwgc3RyMSwgbGVuMSwgc3RyMiwgbGVuMik7CgogICAgaWYgKHJldCkgLyogbmVlZCB0byB0cmFuc2xhdGUgcmVzdWx0ICovCiAgICAgICAgcmV0dXJuIChyZXQgPCAwKSA/IENTVFJfTEVTU19USEFOIDogQ1NUUl9HUkVBVEVSX1RIQU47CiAgICByZXR1cm4gQ1NUUl9FUVVBTDsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgICAgICAgQ29tcGFyZVN0cmluZ0EgICAgKEtFUk5FTDMyLkApCiAqCiAqIENvbXBhcmUgdHdvIGxvY2FsZSBzZW5zaXRpdmUgc3RyaW5ncy4KICoKICogUEFSQU1TCiAqICBsY2lkICBbSV0gTENJRCBmb3IgdGhlIGNvbXBhcmlzb24KICogIHN0eWxlIFtJXSBGbGFncyBmb3IgdGhlIGNvbXBhcmlzb24gKE5PUk1fIGNvbnN0YW50cyBmcm9tICJ3aW5ubHMuaCIpLgogKiAgc3RyMSAgW0ldIEZpcnN0IHN0cmluZyB0byBjb21wYXJlCiAqICBsZW4xICBbSV0gTGVuZ3RoIG9mIHN0cjEsIG9yIC0xIGlmIHN0cjEgaXMgTlVMIHRlcm1pbmF0ZWQKICogIHN0cjIgIFtJXSBTZWNvbmQgc3RyaW5nIHRvIGNvbXBhcmUKICogIGxlbjIgIFtJXSBMZW5ndGggb2Ygc3RyMiwgb3IgLTEgaWYgc3RyMiBpcyBOVUwgdGVybWluYXRlZAogKgogKiBSRVRVUk5TCiAqICBTdWNjZXNzOiBDU1RSX0xFU1NfVEhBTiwgQ1NUUl9FUVVBTCBvciBDU1RSX0dSRUFURVJfVEhBTiBkZXBlbmRpbmcgb24gd2hldGhlcgogKiAgICAgICAgICAgc3RyMiBpcyBsZXNzIHRoYW4sIGVxdWFsIHRvIG9yIGdyZWF0ZXIgdGhhbiBzdHIxIHJlc3BlY3RpdmVseS4KICogIEZhaWx1cmU6IEZBTFNFLiBVc2UgR2V0TGFzdEVycm9yKCkgdG8gZGV0ZXJtaW5lIHRoZSBjYXVzZS4KICovCklOVCBXSU5BUEkgQ29tcGFyZVN0cmluZ0EoTENJRCBsY2lkLCBEV09SRCBzdHlsZSwKICAgICAgICAgICAgICAgICAgICAgICAgICBMUENTVFIgc3RyMSwgSU5UIGxlbjEsIExQQ1NUUiBzdHIyLCBJTlQgbGVuMikKewogICAgV0NIQVIgKmJ1ZjFXID0gTnRDdXJyZW50VGViKCktPlN0YXRpY1VuaWNvZGVCdWZmZXI7CiAgICBXQ0hBUiAqYnVmMlcgPSBidWYxVyArIDEzMDsKICAgIExQV1NUUiBzdHIxVywgc3RyMlc7CiAgICBJTlQgbGVuMVcsIGxlbjJXLCByZXQ7CiAgICBVSU5UIGxvY2FsZV9jcCA9IENQX0FDUDsKCiAgICBpZiAoIXN0cjEgfHwgIXN0cjIpCiAgICB7CiAgICAgICAgU2V0TGFzdEVycm9yKEVSUk9SX0lOVkFMSURfUEFSQU1FVEVSKTsKICAgICAgICByZXR1cm4gMDsKICAgIH0KICAgIGlmIChsZW4xIDwgMCkgbGVuMSA9IHN0cmxlbihzdHIxKTsKICAgIGlmIChsZW4yIDwgMCkgbGVuMiA9IHN0cmxlbihzdHIyKTsKCiAgICBpZiAoIShzdHlsZSAmIExPQ0FMRV9VU0VfQ1BfQUNQKSkgbG9jYWxlX2NwID0gZ2V0X2xjaWRfY29kZXBhZ2UoIGxjaWQgKTsKCiAgICBsZW4xVyA9IE11bHRpQnl0ZVRvV2lkZUNoYXIobG9jYWxlX2NwLCAwLCBzdHIxLCBsZW4xLCBidWYxVywgMTMwKTsKICAgIGlmIChsZW4xVykKICAgICAgICBzdHIxVyA9IGJ1ZjFXOwogICAgZWxzZQogICAgewogICAgICAgIGxlbjFXID0gTXVsdGlCeXRlVG9XaWRlQ2hhcihsb2NhbGVfY3AsIDAsIHN0cjEsIGxlbjEsIE5VTEwsIDApOwogICAgICAgIHN0cjFXID0gSGVhcEFsbG9jKEdldFByb2Nlc3NIZWFwKCksIDAsIGxlbjFXICogc2l6ZW9mKFdDSEFSKSk7CiAgICAgICAgaWYgKCFzdHIxVykKICAgICAgICB7CiAgICAgICAgICAgIFNldExhc3RFcnJvcihFUlJPUl9OT1RfRU5PVUdIX01FTU9SWSk7CiAgICAgICAgICAgIHJldHVybiAwOwogICAgICAgIH0KICAgICAgICBNdWx0aUJ5dGVUb1dpZGVDaGFyKGxvY2FsZV9jcCwgMCwgc3RyMSwgbGVuMSwgc3RyMVcsIGxlbjFXKTsKICAgIH0KICAgIGxlbjJXID0gTXVsdGlCeXRlVG9XaWRlQ2hhcihsb2NhbGVfY3AsIDAsIHN0cjIsIGxlbjIsIGJ1ZjJXLCAxMzApOwogICAgaWYgKGxlbjJXKQogICAgICAgIHN0cjJXID0gYnVmMlc7CiAgICBlbHNlCiAgICB7CiAgICAgICAgbGVuMlcgPSBNdWx0aUJ5dGVUb1dpZGVDaGFyKGxvY2FsZV9jcCwgMCwgc3RyMiwgbGVuMiwgTlVMTCwgMCk7CiAgICAgICAgc3RyMlcgPSBIZWFwQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgbGVuMlcgKiBzaXplb2YoV0NIQVIpKTsKICAgICAgICBpZiAoIXN0cjJXKQogICAgICAgIHsKICAgICAgICAgICAgaWYgKHN0cjFXICE9IGJ1ZjFXKSBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLCAwLCBzdHIxVyk7CiAgICAgICAgICAgIFNldExhc3RFcnJvcihFUlJPUl9OT1RfRU5PVUdIX01FTU9SWSk7CiAgICAgICAgICAgIHJldHVybiAwOwogICAgICAgIH0KICAgICAgICBNdWx0aUJ5dGVUb1dpZGVDaGFyKGxvY2FsZV9jcCwgMCwgc3RyMiwgbGVuMiwgc3RyMlcsIGxlbjJXKTsKICAgIH0KCiAgICByZXQgPSBDb21wYXJlU3RyaW5nVyhsY2lkLCBzdHlsZSwgc3RyMVcsIGxlbjFXLCBzdHIyVywgbGVuMlcpOwoKICAgIGlmIChzdHIxVyAhPSBidWYxVykgSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgc3RyMVcpOwogICAgaWYgKHN0cjJXICE9IGJ1ZjJXKSBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLCAwLCBzdHIyVyk7CiAgICByZXR1cm4gcmV0Owp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgICAgICAgbHN0cmNtcCAgICAgKEtFUk5FTDMyLkApCiAqICAgICAgICAgICBsc3RyY21wQSAgICAoS0VSTkVMMzIuQCkKICoKICogQ29tcGFyZSB0d28gc3RyaW5ncyB1c2luZyB0aGUgY3VycmVudCB0aHJlYWQgbG9jYWxlLgogKgogKiBQQVJBTVMKICogIHN0cjEgIFtJXSBGaXJzdCBzdHJpbmcgdG8gY29tcGFyZQogKiAgc3RyMiAgW0ldIFNlY29uZCBzdHJpbmcgdG8gY29tcGFyZQogKgogKiBSRVRVUk5TCiAqICBTdWNjZXNzOiBBIG51bWJlciBsZXNzIHRoYW4sIGVxdWFsIHRvIG9yIGdyZWF0ZXIgdGhhbiAwIGRlcGVuZGluZyBvbiB3aGV0aGVyCiAqICAgICAgICAgICBzdHIyIGlzIGxlc3MgdGhhbiwgZXF1YWwgdG8gb3IgZ3JlYXRlciB0aGFuIHN0cjEgcmVzcGVjdGl2ZWx5LgogKiAgRmFpbHVyZTogRkFMU0UuIFVzZSBHZXRMYXN0RXJyb3IoKSB0byBkZXRlcm1pbmUgdGhlIGNhdXNlLgogKi8KaW50IFdJTkFQSSBsc3RyY21wQShMUENTVFIgc3RyMSwgTFBDU1RSIHN0cjIpCnsKICAgIGludCByZXQ7CiAgICAKICAgIGlmICgoc3RyMSA9PSBOVUxMKSAmJiAoc3RyMiA9PSBOVUxMKSkgcmV0dXJuIDA7CiAgICBpZiAoc3RyMSA9PSBOVUxMKSByZXR1cm4gLTE7CiAgICBpZiAoc3RyMiA9PSBOVUxMKSByZXR1cm4gMTsKCiAgICByZXQgPSBDb21wYXJlU3RyaW5nQShHZXRUaHJlYWRMb2NhbGUoKSwgTE9DQUxFX1VTRV9DUF9BQ1AsIHN0cjEsIC0xLCBzdHIyLCAtMSk7CiAgICBpZiAocmV0KSByZXQgLT0gMjsKICAgIAogICAgcmV0dXJuIHJldDsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICAgICAgIGxzdHJjbXBpICAgICAoS0VSTkVMMzIuQCkKICogICAgICAgICAgIGxzdHJjbXBpQSAgICAoS0VSTkVMMzIuQCkKICoKICogQ29tcGFyZSB0d28gc3RyaW5ncyB1c2luZyB0aGUgY3VycmVudCB0aHJlYWQgbG9jYWxlLCBpZ25vcmluZyBjYXNlLgogKgogKiBQQVJBTVMKICogIHN0cjEgIFtJXSBGaXJzdCBzdHJpbmcgdG8gY29tcGFyZQogKiAgc3RyMiAgW0ldIFNlY29uZCBzdHJpbmcgdG8gY29tcGFyZQogKgogKiBSRVRVUk5TCiAqICBTdWNjZXNzOiBBIG51bWJlciBsZXNzIHRoYW4sIGVxdWFsIHRvIG9yIGdyZWF0ZXIgdGhhbiAwIGRlcGVuZGluZyBvbiB3aGV0aGVyCiAqICAgICAgICAgICBzdHIyIGlzIGxlc3MgdGhhbiwgZXF1YWwgdG8gb3IgZ3JlYXRlciB0aGFuIHN0cjEgcmVzcGVjdGl2ZWx5LgogKiAgRmFpbHVyZTogRkFMU0UuIFVzZSBHZXRMYXN0RXJyb3IoKSB0byBkZXRlcm1pbmUgdGhlIGNhdXNlLgogKi8KaW50IFdJTkFQSSBsc3RyY21waUEoTFBDU1RSIHN0cjEsIExQQ1NUUiBzdHIyKQp7CiAgICBpbnQgcmV0OwogICAgCiAgICBpZiAoKHN0cjEgPT0gTlVMTCkgJiYgKHN0cjIgPT0gTlVMTCkpIHJldHVybiAwOwogICAgaWYgKHN0cjEgPT0gTlVMTCkgcmV0dXJuIC0xOwogICAgaWYgKHN0cjIgPT0gTlVMTCkgcmV0dXJuIDE7CgogICAgcmV0ID0gQ29tcGFyZVN0cmluZ0EoR2V0VGhyZWFkTG9jYWxlKCksIE5PUk1fSUdOT1JFQ0FTRXxMT0NBTEVfVVNFX0NQX0FDUCwgc3RyMSwgLTEsIHN0cjIsIC0xKTsKICAgIGlmIChyZXQpIHJldCAtPSAyOwogICAgCiAgICByZXR1cm4gcmV0Owp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgICAgICAgbHN0cmNtcFcgICAgKEtFUk5FTDMyLkApCiAqCiAqIFNlZSBsc3RyY21wQS4KICovCmludCBXSU5BUEkgbHN0cmNtcFcoTFBDV1NUUiBzdHIxLCBMUENXU1RSIHN0cjIpCnsKICAgIGludCByZXQ7CgogICAgaWYgKChzdHIxID09IE5VTEwpICYmIChzdHIyID09IE5VTEwpKSByZXR1cm4gMDsKICAgIGlmIChzdHIxID09IE5VTEwpIHJldHVybiAtMTsKICAgIGlmIChzdHIyID09IE5VTEwpIHJldHVybiAxOwoKICAgIHJldCA9IENvbXBhcmVTdHJpbmdXKEdldFRocmVhZExvY2FsZSgpLCAwLCBzdHIxLCAtMSwgc3RyMiwgLTEpOwogICAgaWYgKHJldCkgcmV0IC09IDI7CiAgICAKICAgIHJldHVybiByZXQ7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgICAgICBsc3RyY21waVcgICAgKEtFUk5FTDMyLkApCiAqCiAqIFNlZSBsc3RyY21waUEuCiAqLwppbnQgV0lOQVBJIGxzdHJjbXBpVyhMUENXU1RSIHN0cjEsIExQQ1dTVFIgc3RyMikKewogICAgaW50IHJldDsKICAgIAogICAgaWYgKChzdHIxID09IE5VTEwpICYmIChzdHIyID09IE5VTEwpKSByZXR1cm4gMDsKICAgIGlmIChzdHIxID09IE5VTEwpIHJldHVybiAtMTsKICAgIGlmIChzdHIyID09IE5VTEwpIHJldHVybiAxOwoKICAgIHJldCA9IENvbXBhcmVTdHJpbmdXKEdldFRocmVhZExvY2FsZSgpLCBOT1JNX0lHTk9SRUNBU0UsIHN0cjEsIC0xLCBzdHIyLCAtMSk7CiAgICBpZiAocmV0KSByZXQgLT0gMjsKICAgIAogICAgcmV0dXJuIHJldDsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJTE9DQUxFX0luaXQKICovCnZvaWQgTE9DQUxFX0luaXQodm9pZCkKewogICAgZXh0ZXJuIHZvaWQgX193aW5lX2luaXRfY29kZXBhZ2VzKCBjb25zdCB1bmlvbiBjcHRhYmxlICphbnNpX2NwLCBjb25zdCB1bmlvbiBjcHRhYmxlICpvZW1fY3AsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHVuaW9uIGNwdGFibGUgKnVuaXhfY3AgKTsKCiAgICBVSU5UIGFuc2lfY3AgPSAxMjUyLCBvZW1fY3AgPSA0MzcsIG1hY19jcCA9IDEwMDAwLCB1bml4X2NwID0gfjBVOwogICAgTENJRCBsY2lkOwoKICAgIGxjaWQgPSBnZXRfZW52X2xjaWQoIE5VTEwsIE5VTEwgKTsKICAgIE50U2V0RGVmYXVsdExvY2FsZSggVFJVRSwgbGNpZCApOwoKICAgIGxjaWQgPSBnZXRfZW52X2xjaWQoIE5VTEwsICJMQ19NRVNTQUdFUyIgKTsKICAgIE50U2V0RGVmYXVsdFVJTGFuZ3VhZ2UoIExBTkdJREZST01MQ0lEKGxjaWQpICk7CgogICAgbGNpZCA9IGdldF9lbnZfbGNpZCggJnVuaXhfY3AsICJMQ19DVFlQRSIgKTsKICAgIE50U2V0RGVmYXVsdExvY2FsZSggRkFMU0UsIGxjaWQgKTsKCiAgICBhbnNpX2NwID0gZ2V0X2xjaWRfY29kZXBhZ2UobGNpZCk7CiAgICBHZXRMb2NhbGVJbmZvVyggbGNpZCwgTE9DQUxFX0lERUZBVUxUTUFDQ09ERVBBR0UgfCBMT0NBTEVfUkVUVVJOX05VTUJFUiwKICAgICAgICAgICAgICAgICAgICAoTFBXU1RSKSZtYWNfY3AsIHNpemVvZihtYWNfY3ApL3NpemVvZihXQ0hBUikgKTsKICAgIEdldExvY2FsZUluZm9XKCBsY2lkLCBMT0NBTEVfSURFRkFVTFRDT0RFUEFHRSB8IExPQ0FMRV9SRVRVUk5fTlVNQkVSLAogICAgICAgICAgICAgICAgICAgIChMUFdTVFIpJm9lbV9jcCwgc2l6ZW9mKG9lbV9jcCkvc2l6ZW9mKFdDSEFSKSApOwogICAgaWYgKHVuaXhfY3AgPT0gfjBVKQogICAgICAgIEdldExvY2FsZUluZm9XKCBsY2lkLCBMT0NBTEVfSURFRkFVTFRVTklYQ09ERVBBR0UgfCBMT0NBTEVfUkVUVVJOX05VTUJFUiwKICAgICAgICAgICAgICAgICAgICAoTFBXU1RSKSZ1bml4X2NwLCBzaXplb2YodW5peF9jcCkvc2l6ZW9mKFdDSEFSKSApOwoKICAgIGlmICghKGFuc2lfY3B0YWJsZSA9IHdpbmVfY3BfZ2V0X3RhYmxlKCBhbnNpX2NwICkpKQogICAgICAgIGFuc2lfY3B0YWJsZSA9IHdpbmVfY3BfZ2V0X3RhYmxlKCAxMjUyICk7CiAgICBpZiAoIShvZW1fY3B0YWJsZSA9IHdpbmVfY3BfZ2V0X3RhYmxlKCBvZW1fY3AgKSkpCiAgICAgICAgb2VtX2NwdGFibGUgID0gd2luZV9jcF9nZXRfdGFibGUoIDQzNyApOwogICAgaWYgKCEobWFjX2NwdGFibGUgPSB3aW5lX2NwX2dldF90YWJsZSggbWFjX2NwICkpKQogICAgICAgIG1hY19jcHRhYmxlICA9IHdpbmVfY3BfZ2V0X3RhYmxlKCAxMDAwMCApOwogICAgaWYgKHVuaXhfY3AgIT0gQ1BfVVRGOCkKICAgIHsKICAgICAgICBpZiAoISh1bml4X2NwdGFibGUgPSB3aW5lX2NwX2dldF90YWJsZSggdW5peF9jcCApKSkKICAgICAgICAgICAgdW5peF9jcHRhYmxlICA9IHdpbmVfY3BfZ2V0X3RhYmxlKCAyODU5MSApOwogICAgfQoKICAgIF9fd2luZV9pbml0X2NvZGVwYWdlcyggYW5zaV9jcHRhYmxlLCBvZW1fY3B0YWJsZSwgdW5peF9jcHRhYmxlICk7CgogICAgVFJBQ0UoICJhbnNpPSUwM2Qgb2VtPSUwM2QgbWFjPSUwM2QgdW5peD0lMDNkXG4iLAogICAgICAgICAgIGFuc2lfY3B0YWJsZS0+aW5mby5jb2RlcGFnZSwgb2VtX2NwdGFibGUtPmluZm8uY29kZXBhZ2UsCiAgICAgICAgICAgbWFjX2NwdGFibGUtPmluZm8uY29kZXBhZ2UsIHVuaXhfY3AgKTsKfQoKc3RhdGljIEhLRVkgTkxTX1JlZ09wZW5LZXkoSEtFWSBoUm9vdEtleSwgTFBDV1NUUiBzektleU5hbWUpCnsKICAgIFVOSUNPREVfU1RSSU5HIGtleU5hbWU7CiAgICBPQkpFQ1RfQVRUUklCVVRFUyBhdHRyOwogICAgSEtFWSBoa2V5OwoKICAgIFJ0bEluaXRVbmljb2RlU3RyaW5nKCAma2V5TmFtZSwgc3pLZXlOYW1lICk7CiAgICBJbml0aWFsaXplT2JqZWN0QXR0cmlidXRlcygmYXR0ciwgJmtleU5hbWUsIDAsIGhSb290S2V5LCBOVUxMKTsKCiAgICBpZiAoTnRPcGVuS2V5KCAmaGtleSwgS0VZX0FMTF9BQ0NFU1MsICZhdHRyICkgIT0gU1RBVFVTX1NVQ0NFU1MpCiAgICAgICAgaGtleSA9IDA7CgogICAgcmV0dXJuIGhrZXk7Cn0KCnN0YXRpYyBIS0VZIE5MU19SZWdPcGVuU3ViS2V5KEhLRVkgaFJvb3RLZXksIExQQ1dTVFIgc3pLZXlOYW1lKQp7CiAgICBIS0VZIGhLZXkgPSBOTFNfUmVnT3BlbktleShoUm9vdEtleSwgc3pLZXlOYW1lKTsKCiAgICBpZiAoaFJvb3RLZXkpCiAgICAgICAgTnRDbG9zZSggaFJvb3RLZXkgKTsKCiAgICByZXR1cm4gaEtleTsKfQoKc3RhdGljIEJPT0wgTkxTX1JlZ0VudW1TdWJLZXkoSEtFWSBoS2V5LCBVSU5UIHVsSW5kZXgsIExQV1NUUiBzektleU5hbWUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFVMT05HIGtleU5hbWVTaXplKQp7CiAgICBCWVRFIGJ1ZmZlcls4MF07CiAgICBLRVlfQkFTSUNfSU5GT1JNQVRJT04gKmluZm8gPSAoS0VZX0JBU0lDX0lORk9STUFUSU9OICopYnVmZmVyOwogICAgRFdPUkQgZHdMZW47CgogICAgaWYgKE50RW51bWVyYXRlS2V5KCBoS2V5LCB1bEluZGV4LCBLZXlCYXNpY0luZm9ybWF0aW9uLCBidWZmZXIsCiAgICAgICAgICAgICAgICAgICAgICAgIHNpemVvZihidWZmZXIpLCAmZHdMZW4pICE9IFNUQVRVU19TVUNDRVNTIHx8CiAgICAgICAgaW5mby0+TmFtZUxlbmd0aCA+IGtleU5hbWVTaXplKQogICAgewogICAgICAgIHJldHVybiBGQUxTRTsKICAgIH0KCiAgICBUUkFDRSgiaW5mby0+TmFtZSAlcyBpbmZvLT5OYW1lTGVuZ3RoICVsZFxuIiwgZGVidWdzdHJfdyhpbmZvLT5OYW1lKSwgaW5mby0+TmFtZUxlbmd0aCk7CgogICAgbWVtY3B5KCBzektleU5hbWUsIGluZm8tPk5hbWUsIGluZm8tPk5hbWVMZW5ndGgpOwogICAgc3pLZXlOYW1lW2luZm8tPk5hbWVMZW5ndGggLyBzaXplb2YoV0NIQVIpXSA9ICdcMCc7CgogICAgVFJBQ0UoInJldHVybmluZyAlc1xuIiwgZGVidWdzdHJfdyhzektleU5hbWUpKTsKICAgIHJldHVybiBUUlVFOwp9CgpzdGF0aWMgQk9PTCBOTFNfUmVnRW51bVZhbHVlKEhLRVkgaEtleSwgVUlOVCB1bEluZGV4LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIExQV1NUUiBzelZhbHVlTmFtZSwgVUxPTkcgdmFsdWVOYW1lU2l6ZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMUFdTVFIgc3pWYWx1ZURhdGEsIFVMT05HIHZhbHVlRGF0YVNpemUpCnsKICAgIEJZVEUgYnVmZmVyWzgwXTsKICAgIEtFWV9WQUxVRV9GVUxMX0lORk9STUFUSU9OICppbmZvID0gKEtFWV9WQUxVRV9GVUxMX0lORk9STUFUSU9OICopYnVmZmVyOwogICAgRFdPUkQgZHdMZW47CgogICAgaWYgKE50RW51bWVyYXRlVmFsdWVLZXkoIGhLZXksIHVsSW5kZXgsIEtleVZhbHVlRnVsbEluZm9ybWF0aW9uLAogICAgICAgIGJ1ZmZlciwgc2l6ZW9mKGJ1ZmZlciksICZkd0xlbiApICE9IFNUQVRVU19TVUNDRVNTIHx8CiAgICAgICAgaW5mby0+TmFtZUxlbmd0aCA+IHZhbHVlTmFtZVNpemUgfHwKICAgICAgICBpbmZvLT5EYXRhTGVuZ3RoID4gdmFsdWVEYXRhU2l6ZSkKICAgIHsKICAgICAgICByZXR1cm4gRkFMU0U7CiAgICB9CgogICAgVFJBQ0UoImluZm8tPk5hbWUgJXMgaW5mby0+RGF0YUxlbmd0aCAlbGRcbiIsIGRlYnVnc3RyX3coaW5mby0+TmFtZSksIGluZm8tPkRhdGFMZW5ndGgpOwoKICAgIG1lbWNweSggc3pWYWx1ZU5hbWUsIGluZm8tPk5hbWUsIGluZm8tPk5hbWVMZW5ndGgpOwogICAgc3pWYWx1ZU5hbWVbaW5mby0+TmFtZUxlbmd0aCAvIHNpemVvZihXQ0hBUildID0gJ1wwJzsKICAgIG1lbWNweSggc3pWYWx1ZURhdGEsIGJ1ZmZlciArIGluZm8tPkRhdGFPZmZzZXQsIGluZm8tPkRhdGFMZW5ndGggKTsKICAgIHN6VmFsdWVEYXRhW2luZm8tPkRhdGFMZW5ndGggLyBzaXplb2YoV0NIQVIpXSA9ICdcMCc7CgogICAgVFJBQ0UoInJldHVybmluZyAlcyAlc1xuIiwgZGVidWdzdHJfdyhzelZhbHVlTmFtZSksIGRlYnVnc3RyX3coc3pWYWx1ZURhdGEpKTsKICAgIHJldHVybiBUUlVFOwp9CgpzdGF0aWMgQk9PTCBOTFNfUmVnR2V0RHdvcmQoSEtFWSBoS2V5LCBMUENXU1RSIHN6VmFsdWVOYW1lLCBEV09SRCAqbHBWYWwpCnsKICAgIEJZVEUgYnVmZmVyWzEyOF07CiAgICBjb25zdCBLRVlfVkFMVUVfUEFSVElBTF9JTkZPUk1BVElPTiAqaW5mbyA9IChLRVlfVkFMVUVfUEFSVElBTF9JTkZPUk1BVElPTiAqKWJ1ZmZlcjsKICAgIERXT1JEIGR3U2l6ZSA9IHNpemVvZihidWZmZXIpOwogICAgVU5JQ09ERV9TVFJJTkcgdmFsdWVOYW1lOwoKICAgIFJ0bEluaXRVbmljb2RlU3RyaW5nKCAmdmFsdWVOYW1lLCBzelZhbHVlTmFtZSApOwoKICAgIFRSQUNFKCIlcCwgJXNcbiIsIGhLZXksIGRlYnVnc3RyX3coc3pWYWx1ZU5hbWUpKTsKICAgIGlmIChOdFF1ZXJ5VmFsdWVLZXkoIGhLZXksICZ2YWx1ZU5hbWUsIEtleVZhbHVlUGFydGlhbEluZm9ybWF0aW9uLAogICAgICAgICAgICAgICAgICAgICAgICAgYnVmZmVyLCBkd1NpemUsICZkd1NpemUgKSA9PSBTVEFUVVNfU1VDQ0VTUyAmJgogICAgICAgIGluZm8tPkRhdGFMZW5ndGggPT0gc2l6ZW9mKERXT1JEKSkKICAgIHsKICAgICAgICBtZW1jcHkobHBWYWwsIGluZm8tPkRhdGEsIHNpemVvZihEV09SRCkpOwogICAgICAgIHJldHVybiBUUlVFOwogICAgfQoKICAgIHJldHVybiBGQUxTRTsKfQoKc3RhdGljIEJPT0wgTkxTX0dldExhbmd1YWdlR3JvdXBOYW1lKExHUlBJRCBsZ3JwaWQsIExQV1NUUiBzek5hbWUsIFVMT05HIG5hbWVTaXplKQp7CiAgICBMQU5HSUQgIGxhbmdJZDsKICAgIExQQ1dTVFIgc3pSZXNvdXJjZU5hbWUgPSAoTFBDV1NUUikoKChsZ3JwaWQgKyAweDIwMDApID4+IDQpICsgMSk7CiAgICBIUlNSQyAgIGhSZXNvdXJjZTsKICAgIEJPT0wgICAgYlJldCA9IEZBTFNFOwoKICAgIC8qIEZJWE1FOiBJcyBpdCBjb3JyZWN0IHRvIHVzZSB0aGUgc3lzdGVtIGRlZmF1bHQgbGFuZ2lkPyAqLwogICAgbGFuZ0lkID0gR2V0U3lzdGVtRGVmYXVsdExhbmdJRCgpOwoKICAgIGlmIChTVUJMQU5HSUQobGFuZ0lkKSA9PSBTVUJMQU5HX05FVVRSQUwpCiAgICAgICAgbGFuZ0lkID0gTUFLRUxBTkdJRCggUFJJTUFSWUxBTkdJRChsYW5nSWQpLCBTVUJMQU5HX0RFRkFVTFQgKTsKCiAgICBoUmVzb3VyY2UgPSBGaW5kUmVzb3VyY2VFeFcoIGtlcm5lbDMyX2hhbmRsZSwgKExQV1NUUilSVF9TVFJJTkcsIHN6UmVzb3VyY2VOYW1lLCBsYW5nSWQgKTsKCiAgICBpZiAoaFJlc291cmNlKQogICAgewogICAgICAgIEhHTE9CQUwgaFJlc0RpciA9IExvYWRSZXNvdXJjZSgga2VybmVsMzJfaGFuZGxlLCBoUmVzb3VyY2UgKTsKCiAgICAgICAgaWYgKGhSZXNEaXIpCiAgICAgICAgewogICAgICAgICAgICBVTE9ORyAgIGlSZXNvdXJjZUluZGV4ID0gbGdycGlkICYgMHhmOwogICAgICAgICAgICBMUENXU1RSIGxwUmVzRW50cnkgPSBMb2NrUmVzb3VyY2UoIGhSZXNEaXIgKTsKICAgICAgICAgICAgVUxPTkcgICBpOwoKICAgICAgICAgICAgZm9yIChpID0gMDsgaSA8IGlSZXNvdXJjZUluZGV4OyBpKyspCiAgICAgICAgICAgICAgICBscFJlc0VudHJ5ICs9ICpscFJlc0VudHJ5ICsgMTsKCiAgICAgICAgICAgIGlmICgqbHBSZXNFbnRyeSA8IG5hbWVTaXplKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBtZW1jcHkoIHN6TmFtZSwgbHBSZXNFbnRyeSArIDEsICpscFJlc0VudHJ5ICogc2l6ZW9mKFdDSEFSKSApOwogICAgICAgICAgICAgICAgc3pOYW1lWypscFJlc0VudHJ5XSA9ICdcMCc7CiAgICAgICAgICAgICAgICBiUmV0ID0gVFJVRTsKICAgICAgICAgICAgfQoKICAgICAgICB9CiAgICAgICAgRnJlZVJlc291cmNlKCBoUmVzb3VyY2UgKTsKICAgIH0KICAgIHJldHVybiBiUmV0Owp9CgovKiBSZWdpc3RyeSBrZXlzIGZvciBOTFMgcmVsYXRlZCBpbmZvcm1hdGlvbiAqLwpzdGF0aWMgY29uc3QgV0NIQVIgc3pMYW5nR3JvdXBzS2V5TmFtZVtdID0gewogICAgJ0wnLCdhJywnbicsJ2cnLCd1JywnYScsJ2cnLCdlJywnICcsJ0cnLCdyJywnbycsJ3UnLCdwJywncycsJ1wwJwp9OwoKc3RhdGljIGNvbnN0IFdDSEFSIHN6Q291bnRyeUxpc3ROYW1lW10gPSB7CiAgICAnTScsJ2EnLCdjJywnaCcsJ2knLCduJywnZScsJ1xcJywnUycsJ28nLCdmJywndCcsJ3cnLCdhJywncicsJ2UnLCdcXCcsCiAgICAnTScsJ2knLCdjJywncicsJ28nLCdzJywnbycsJ2YnLCd0JywnXFwnLCdXJywnaScsJ24nLCdkJywnbycsJ3cnLCdzJywnXFwnLAogICAgJ0MnLCd1JywncicsJ3InLCdlJywnbicsJ3QnLCdWJywnZScsJ3InLCdzJywnaScsJ28nLCduJywnXFwnLAogICAgJ1QnLCdlJywnbCcsJ2UnLCdwJywnaCcsJ28nLCduJywneScsJ1xcJywKICAgICdDJywnbycsJ3UnLCduJywndCcsJ3InLCd5JywnICcsJ0wnLCdpJywncycsJ3QnLCdcMCcKfTsKCgovKiBDYWxsYmFjayBmdW5jdGlvbiBwdHJzIGZvciBFbnVtU3lzdGVtTGFuZ3VhZ2VHcm91cHNBL1cgKi8KdHlwZWRlZiBzdHJ1Y3QKewogIExBTkdVQUdFR1JPVVBfRU5VTVBST0NBIHByb2NBOwogIExBTkdVQUdFR1JPVVBfRU5VTVBST0NXIHByb2NXOwogIERXT1JEICAgIGR3RmxhZ3M7CiAgTE9OR19QVFIgbFBhcmFtOwp9IEVOVU1MQU5HVUFHRUdST1VQX0NBTExCQUNLUzsKCi8qIEludGVybmFsIGltcGxlbWVudGF0aW9uIG9mIEVudW1TeXN0ZW1MYW5ndWFnZUdyb3Vwc0EvVyAqLwpzdGF0aWMgQk9PTCBOTFNfRW51bVN5c3RlbUxhbmd1YWdlR3JvdXBzKEVOVU1MQU5HVUFHRUdST1VQX0NBTExCQUNLUyAqbHBQcm9jcykKewogICAgV0NIQVIgc3pOdW1iZXJbMTBdLCBzelZhbHVlWzRdOwogICAgSEtFWSBoS2V5OwogICAgQk9PTCBiQ29udGludWUgPSBUUlVFOwogICAgVUxPTkcgdWxJbmRleCA9IDA7CgogICAgaWYgKCFscFByb2NzKQogICAgewogICAgICAgIFNldExhc3RFcnJvcihFUlJPUl9JTlZBTElEX1BBUkFNRVRFUik7CiAgICAgICAgcmV0dXJuIEZBTFNFOwogICAgfQoKICAgIHN3aXRjaCAobHBQcm9jcy0+ZHdGbGFncykKICAgIHsKICAgIGNhc2UgMDoKICAgICAgICAvKiBEZWZhdWx0IHRvIExHUlBJRF9JTlNUQUxMRUQgKi8KICAgICAgICBscFByb2NzLT5kd0ZsYWdzID0gTEdSUElEX0lOU1RBTExFRDsKICAgICAgICAvKiBGYWxsIHRocm91Z2guLi4gKi8KICAgIGNhc2UgTEdSUElEX0lOU1RBTExFRDoKICAgIGNhc2UgTEdSUElEX1NVUFBPUlRFRDoKICAgICAgICBicmVhazsKICAgIGRlZmF1bHQ6CiAgICAgICAgU2V0TGFzdEVycm9yKEVSUk9SX0lOVkFMSURfRkxBR1MpOwogICAgICAgIHJldHVybiBGQUxTRTsKICAgIH0KCiAgICBoS2V5ID0gTkxTX1JlZ09wZW5TdWJLZXkoIE5MU19SZWdPcGVuS2V5KCAwLCBzek5sc0tleU5hbWUgKSwgc3pMYW5nR3JvdXBzS2V5TmFtZSApOwoKICAgIGlmICghaEtleSkKICAgICAgICBGSVhNRSgiTkxTIHJlZ2lzdHJ5IGtleSBub3QgZm91bmQuIFBsZWFzZSBhcHBseSB0aGUgZGVmYXVsdCByZWdpc3RyeSBmaWxlICd3aW5lLmluZidcbiIpOwoKICAgIHdoaWxlIChiQ29udGludWUpCiAgICB7CiAgICAgICAgaWYgKE5MU19SZWdFbnVtVmFsdWUoIGhLZXksIHVsSW5kZXgsIHN6TnVtYmVyLCBzaXplb2Yoc3pOdW1iZXIpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzelZhbHVlLCBzaXplb2Yoc3pWYWx1ZSkgKSkKICAgICAgICB7CiAgICAgICAgICAgIEJPT0wgYkluc3RhbGxlZCA9IHN6VmFsdWVbMF0gPT0gJzEnID8gVFJVRSA6IEZBTFNFOwogICAgICAgICAgICBMR1JQSUQgbGdycGlkID0gc3RydG91bFcoIHN6TnVtYmVyLCBOVUxMLCAxNiApOwoKICAgICAgICAgICAgVFJBQ0UoImdycGlkICVzICglc2luc3RhbGxlZClcbiIsIGRlYnVnc3RyX3coc3pOdW1iZXIpLAogICAgICAgICAgICAgICAgICAgYkluc3RhbGxlZCA/ICIiIDogIm5vdCAiKTsKCiAgICAgICAgICAgIGlmIChscFByb2NzLT5kd0ZsYWdzID09IExHUlBJRF9TVVBQT1JURUQgfHwgYkluc3RhbGxlZCkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgV0NIQVIgc3pHcnBOYW1lWzQ4XTsKCiAgICAgICAgICAgICAgICBpZiAoIU5MU19HZXRMYW5ndWFnZUdyb3VwTmFtZSggbGdycGlkLCBzekdycE5hbWUsIHNpemVvZihzekdycE5hbWUpIC8gc2l6ZW9mKFdDSEFSKSApKQogICAgICAgICAgICAgICAgICAgIHN6R3JwTmFtZVswXSA9ICdcMCc7CgogICAgICAgICAgICAgICAgaWYgKGxwUHJvY3MtPnByb2NXKQogICAgICAgICAgICAgICAgICAgIGJDb250aW51ZSA9IGxwUHJvY3MtPnByb2NXKCBsZ3JwaWQsIHN6TnVtYmVyLCBzekdycE5hbWUsIGxwUHJvY3MtPmR3RmxhZ3MsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxwUHJvY3MtPmxQYXJhbSApOwogICAgICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIGNoYXIgc3pOdW1iZXJBW3NpemVvZihzek51bWJlcikvc2l6ZW9mKFdDSEFSKV07CiAgICAgICAgICAgICAgICAgICAgY2hhciBzekdycE5hbWVBWzQ4XTsKCiAgICAgICAgICAgICAgICAgICAgLyogRklYTUU6IE1TRE4gZG9lc24ndCBzYXkgd2hpY2ggY29kZSBwYWdlIHRoZSBXLT5BIHRyYW5zbGF0aW9uIHVzZXMsCiAgICAgICAgICAgICAgICAgICAgICogICAgICAgIG9yIHdoZXRoZXIgdGhlIGxhbmd1YWdlIG5hbWVzIGFyZSBldmVyIGxvY2FsaXNlZC4gQXNzdW1lIENQX0FDUC4KICAgICAgICAgICAgICAgICAgICAgKi8KCiAgICAgICAgICAgICAgICAgICAgV2lkZUNoYXJUb011bHRpQnl0ZShDUF9BQ1AsIDAsIHN6TnVtYmVyLCAtMSwgc3pOdW1iZXJBLCBzaXplb2Yoc3pOdW1iZXJBKSwgMCwgMCk7CiAgICAgICAgICAgICAgICAgICAgV2lkZUNoYXJUb011bHRpQnl0ZShDUF9BQ1AsIDAsIHN6R3JwTmFtZSwgLTEsIHN6R3JwTmFtZUEsIHNpemVvZihzekdycE5hbWVBKSwgMCwgMCk7CgogICAgICAgICAgICAgICAgICAgIGJDb250aW51ZSA9IGxwUHJvY3MtPnByb2NBKCBsZ3JwaWQsIHN6TnVtYmVyQSwgc3pHcnBOYW1lQSwgbHBQcm9jcy0+ZHdGbGFncywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbHBQcm9jcy0+bFBhcmFtICk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHVsSW5kZXgrKzsKICAgICAgICB9CiAgICAgICAgZWxzZQogICAgICAgICAgICBiQ29udGludWUgPSBGQUxTRTsKCiAgICAgICAgaWYgKCFiQ29udGludWUpCiAgICAgICAgICAgIGJyZWFrOwogICAgfQoKICAgIGlmIChoS2V5KQogICAgICAgIE50Q2xvc2UoIGhLZXkgKTsKCiAgICByZXR1cm4gVFJVRTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgICAgICAgRW51bVN5c3RlbUxhbmd1YWdlR3JvdXBzQSAgICAoS0VSTkVMMzIuQCkKICoKICogQ2FsbCBhIHVzZXJzIGZ1bmN0aW9uIGZvciBlYWNoIGxhbmd1YWdlIGdyb3VwIGF2YWlsYWJsZSBvbiB0aGUgc3lzdGVtLgogKgogKiBQQVJBTVMKICogIHBMYW5nR3JwRW51bVByb2MgW0ldIENhbGxiYWNrIGZ1bmN0aW9uIHRvIGNhbGwgZm9yIGVhY2ggbGFuZ3VhZ2UgZ3JvdXAKICogIGR3RmxhZ3MgICAgICAgICAgW0ldIExHUlBJRF9TVVBQT1JURUQ9QWxsIFN1cHBvcnRlZCwgTEdSUElEX0lOU1RBTExFRD1JbnN0YWxsZWQgb25seQogKiAgbFBhcmFtICAgICAgICAgICBbSV0gVXNlciBwYXJhbWV0ZXIgdG8gcGFzcyB0byBwTGFuZ0dycEVudW1Qcm9jCiAqCiAqIFJFVFVSTlMKICogIFN1Y2Nlc3M6IFRSVUUuCiAqICBGYWlsdXJlOiBGQUxTRS4gVXNlIEdldExhc3RFcnJvcigpIHRvIGRldGVybWluZSB0aGUgY2F1c2UuCiAqLwpCT09MIFdJTkFQSSBFbnVtU3lzdGVtTGFuZ3VhZ2VHcm91cHNBKExBTkdVQUdFR1JPVVBfRU5VTVBST0NBIHBMYW5nR3JwRW51bVByb2MsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRFdPUkQgZHdGbGFncywgTE9OR19QVFIgbFBhcmFtKQp7CiAgICBFTlVNTEFOR1VBR0VHUk9VUF9DQUxMQkFDS1MgcHJvY3M7CgogICAgVFJBQ0UoIiglcCwweCUwOGxYLDB4JTA4bFgpXG4iLCBwTGFuZ0dycEVudW1Qcm9jLCBkd0ZsYWdzLCBsUGFyYW0pOwoKICAgIHByb2NzLnByb2NBID0gcExhbmdHcnBFbnVtUHJvYzsKICAgIHByb2NzLnByb2NXID0gTlVMTDsKICAgIHByb2NzLmR3RmxhZ3MgPSBkd0ZsYWdzOwogICAgcHJvY3MubFBhcmFtID0gbFBhcmFtOwoKICAgIHJldHVybiBOTFNfRW51bVN5c3RlbUxhbmd1YWdlR3JvdXBzKCBwTGFuZ0dycEVudW1Qcm9jID8gJnByb2NzIDogTlVMTCk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICAgICAgIEVudW1TeXN0ZW1MYW5ndWFnZUdyb3Vwc1cgICAgKEtFUk5FTDMyLkApCiAqCiAqIFNlZSBFbnVtU3lzdGVtTGFuZ3VhZ2VHcm91cHNBLgogKi8KQk9PTCBXSU5BUEkgRW51bVN5c3RlbUxhbmd1YWdlR3JvdXBzVyhMQU5HVUFHRUdST1VQX0VOVU1QUk9DVyBwTGFuZ0dycEVudW1Qcm9jLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIERXT1JEIGR3RmxhZ3MsIExPTkdfUFRSIGxQYXJhbSkKewogICAgRU5VTUxBTkdVQUdFR1JPVVBfQ0FMTEJBQ0tTIHByb2NzOwoKICAgIFRSQUNFKCIoJXAsMHglMDhsWCwweCUwOGxYKVxuIiwgcExhbmdHcnBFbnVtUHJvYywgZHdGbGFncywgbFBhcmFtKTsKCiAgICBwcm9jcy5wcm9jQSA9IE5VTEw7CiAgICBwcm9jcy5wcm9jVyA9IHBMYW5nR3JwRW51bVByb2M7CiAgICBwcm9jcy5kd0ZsYWdzID0gZHdGbGFnczsKICAgIHByb2NzLmxQYXJhbSA9IGxQYXJhbTsKCiAgICByZXR1cm4gTkxTX0VudW1TeXN0ZW1MYW5ndWFnZUdyb3VwcyggcExhbmdHcnBFbnVtUHJvYyA/ICZwcm9jcyA6IE5VTEwpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgICAgICBJc1ZhbGlkTGFuZ3VhZ2VHcm91cCAgICAoS0VSTkVMMzIuQCkKICoKICogRGV0ZXJtaW5lIGlmIGEgbGFuZ3VhZ2UgZ3JvdXAgaXMgc3VwcG9ydGVkIGFuZC9vciBpbnN0YWxsZWQuCiAqCiAqIFBBUkFNUwogKiAgbGdycGlkICBbSV0gTGFuZ3VhZ2UgR3JvdXAgSWQgKExHUlBJRF8gdmFsdWVzIGZyb20gIndpbm5scy5oIikKICogIGR3RmxhZ3MgW0ldIExHUlBJRF9TVVBQT1JURUQ9U3VwcG9ydGVkLCBMR1JQSURfSU5TVEFMTEVEPUluc3RhbGxlZAogKgogKiBSRVRVUk5TCiAqICBUUlVFLCBpZiBsZ3JwaWQgaXMgc3VwcG9ydGVkIGFuZC9vciBpbnN0YWxsZWQsIGFjY29yZGluZyB0byBkd0ZsYWdzLgogKiAgRkFMU0Ugb3RoZXJ3aXNlLgogKi8KQk9PTCBXSU5BUEkgSXNWYWxpZExhbmd1YWdlR3JvdXAoTEdSUElEIGxncnBpZCwgRFdPUkQgZHdGbGFncykKewogICAgc3RhdGljIGNvbnN0IFdDSEFSIHN6Rm9ybWF0W10gPSB7ICclJywneCcsJ1wwJyB9OwogICAgV0NIQVIgc3pWYWx1ZU5hbWVbMTZdLCBzelZhbHVlWzJdOwogICAgQk9PTCBiU3VwcG9ydGVkID0gRkFMU0UsIGJJbnN0YWxsZWQgPSBGQUxTRTsKICAgIEhLRVkgaEtleTsKCgogICAgc3dpdGNoIChkd0ZsYWdzKQogICAgewogICAgY2FzZSBMR1JQSURfSU5TVEFMTEVEOgogICAgY2FzZSBMR1JQSURfU1VQUE9SVEVEOgoKICAgICAgICBoS2V5ID0gTkxTX1JlZ09wZW5TdWJLZXkoIE5MU19SZWdPcGVuS2V5KCAwLCBzek5sc0tleU5hbWUgKSwgc3pMYW5nR3JvdXBzS2V5TmFtZSApOwoKICAgICAgICBzcHJpbnRmVyggc3pWYWx1ZU5hbWUsIHN6Rm9ybWF0LCBsZ3JwaWQgKTsKCiAgICAgICAgaWYgKE5MU19SZWdHZXREd29yZCggaEtleSwgc3pWYWx1ZU5hbWUsIChMUERXT1JEKSZzelZhbHVlICkpCiAgICAgICAgewogICAgICAgICAgICBiU3VwcG9ydGVkID0gVFJVRTsKCiAgICAgICAgICAgIGlmIChzelZhbHVlWzBdID09ICcxJykKICAgICAgICAgICAgICAgIGJJbnN0YWxsZWQgPSBUUlVFOwogICAgICAgIH0KCiAgICAgICAgaWYgKGhLZXkpCiAgICAgICAgICAgIE50Q2xvc2UoIGhLZXkgKTsKCiAgICAgICAgYnJlYWs7CiAgICB9CgogICAgaWYgKChkd0ZsYWdzID09IExHUlBJRF9TVVBQT1JURUQgJiYgYlN1cHBvcnRlZCkgfHwKICAgICAgICAoZHdGbGFncyA9PSBMR1JQSURfSU5TVEFMTEVEICYmIGJJbnN0YWxsZWQpKQogICAgICAgIHJldHVybiBUUlVFOwoKICAgIHJldHVybiBGQUxTRTsKfQoKLyogQ2FsbGJhY2sgZnVuY3Rpb24gcHRycyBmb3IgRW51bUxhbmd1YWdlR3JvdXBsb2NhbGVzQS9XICovCnR5cGVkZWYgc3RydWN0CnsKICBMQU5HR1JPVVBMT0NBTEVfRU5VTVBST0NBIHByb2NBOwogIExBTkdHUk9VUExPQ0FMRV9FTlVNUFJPQ1cgcHJvY1c7CiAgRFdPUkQgICAgZHdGbGFnczsKICBMR1JQSUQgICBsZ3JwaWQ7CiAgTE9OR19QVFIgbFBhcmFtOwp9IEVOVU1MQU5HVUFHRUdST1VQTE9DQUxFX0NBTExCQUNLUzsKCi8qIEludGVybmFsIGltcGxlbWVudGF0aW9uIG9mIEVudW1MYW5ndWFnZUdyb3VwbG9jYWxlc0EvVyAqLwpzdGF0aWMgQk9PTCBOTFNfRW51bUxhbmd1YWdlR3JvdXBMb2NhbGVzKEVOVU1MQU5HVUFHRUdST1VQTE9DQUxFX0NBTExCQUNLUyAqbHBQcm9jcykKewogICAgc3RhdGljIGNvbnN0IFdDSEFSIHN6TG9jYWxlS2V5TmFtZVtdID0gewogICAgICAnTCcsJ28nLCdjJywnYScsJ2wnLCdlJywnXDAnCiAgICB9OwogICAgc3RhdGljIGNvbnN0IFdDSEFSIHN6QWx0ZXJuYXRlU29ydHNLZXlOYW1lW10gPSB7CiAgICAgICdBJywnbCcsJ3QnLCdlJywncicsJ24nLCdhJywndCcsJ2UnLCcgJywnUycsJ28nLCdyJywndCcsJ3MnLCdcMCcKICAgIH07CiAgICBXQ0hBUiBzek51bWJlclsxMF0sIHN6VmFsdWVbNF07CiAgICBIS0VZIGhLZXk7CiAgICBCT09MIGJDb250aW51ZSA9IFRSVUUsIGJBbHRlcm5hdGUgPSBGQUxTRTsKICAgIExHUlBJRCBsZ3JwaWQ7CiAgICBVTE9ORyB1bEluZGV4ID0gMTsgIC8qIElnbm9yZSBkZWZhdWx0IGVudHJ5IG9mIDFzdCBrZXkgKi8KCiAgICBpZiAoIWxwUHJvY3MgfHwgIWxwUHJvY3MtPmxncnBpZCB8fCBscFByb2NzLT5sZ3JwaWQgPiBMR1JQSURfQVJNRU5JQU4pCiAgICB7CiAgICAgICAgU2V0TGFzdEVycm9yKEVSUk9SX0lOVkFMSURfUEFSQU1FVEVSKTsKICAgICAgICByZXR1cm4gRkFMU0U7CiAgICB9CgogICAgaWYgKGxwUHJvY3MtPmR3RmxhZ3MpCiAgICB7CiAgICAgICAgU2V0TGFzdEVycm9yKEVSUk9SX0lOVkFMSURfRkxBR1MpOwogICAgICAgIHJldHVybiBGQUxTRTsKICAgIH0KCiAgICBoS2V5ID0gTkxTX1JlZ09wZW5TdWJLZXkoIE5MU19SZWdPcGVuS2V5KCAwLCBzek5sc0tleU5hbWUgKSwgc3pMb2NhbGVLZXlOYW1lICk7CgogICAgaWYgKCFoS2V5KQogICAgICAgIFdBUk4oIk5MUyByZWdpc3RyeSBrZXkgbm90IGZvdW5kLiBQbGVhc2UgYXBwbHkgdGhlIGRlZmF1bHQgcmVnaXN0cnkgZmlsZSAnd2luZS5pbmYnXG4iKTsKCiAgICB3aGlsZSAoYkNvbnRpbnVlKQogICAgewogICAgICAgIGlmIChOTFNfUmVnRW51bVZhbHVlKCBoS2V5LCB1bEluZGV4LCBzek51bWJlciwgc2l6ZW9mKHN6TnVtYmVyKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3pWYWx1ZSwgc2l6ZW9mKHN6VmFsdWUpICkpCiAgICAgICAgewogICAgICAgICAgICBsZ3JwaWQgPSBzdHJ0b3VsVyggc3pWYWx1ZSwgTlVMTCwgMTYgKTsKCiAgICAgICAgICAgIFRSQUNFKCJsY2lkICVzLCBncnBpZCAlbGQgKCVzbWF0Y2hlZClcbiIsIGRlYnVnc3RyX3coc3pOdW1iZXIpLAogICAgICAgICAgICAgICAgICAgbGdycGlkLCBsZ3JwaWQgPT0gbHBQcm9jcy0+bGdycGlkID8gIiIgOiAibm90ICIpOwoKICAgICAgICAgICAgaWYgKGxncnBpZCA9PSBscFByb2NzLT5sZ3JwaWQpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIExDSUQgbGNpZDsKCiAgICAgICAgICAgICAgICBsY2lkID0gc3RydG91bFcoIHN6TnVtYmVyLCBOVUxMLCAxNiApOwoKICAgICAgICAgICAgICAgIC8qIEZJWE1FOiBuYXRpdmUgcmV0dXJucyBleHRyYSB0ZXh0IGZvciBhIGZldyAoMTcvMTUwKSBsb2NhbGVzLCBlLmc6CiAgICAgICAgICAgICAgICAgKiAnMDAwMDA0MzcgICAgICAgICAgO0dlb3JnaWFuJwogICAgICAgICAgICAgICAgICogQXQgcHJlc2VudCB3ZSBvbmx5IHBhc3MgdGhlIExDSUQgc3RyaW5nLgogICAgICAgICAgICAgICAgICovCgogICAgICAgICAgICAgICAgaWYgKGxwUHJvY3MtPnByb2NXKQogICAgICAgICAgICAgICAgICAgIGJDb250aW51ZSA9IGxwUHJvY3MtPnByb2NXKCBsZ3JwaWQsIGxjaWQsIHN6TnVtYmVyLCBscFByb2NzLT5sUGFyYW0gKTsKICAgICAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBjaGFyIHN6TnVtYmVyQVtzaXplb2Yoc3pOdW1iZXIpL3NpemVvZihXQ0hBUildOwoKICAgICAgICAgICAgICAgICAgICBXaWRlQ2hhclRvTXVsdGlCeXRlKENQX0FDUCwgMCwgc3pOdW1iZXIsIC0xLCBzek51bWJlckEsIHNpemVvZihzek51bWJlckEpLCAwLCAwKTsKCiAgICAgICAgICAgICAgICAgICAgYkNvbnRpbnVlID0gbHBQcm9jcy0+cHJvY0EoIGxncnBpZCwgbGNpZCwgc3pOdW1iZXJBLCBscFByb2NzLT5sUGFyYW0gKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQoKICAgICAgICAgICAgdWxJbmRleCsrOwogICAgICAgIH0KICAgICAgICBlbHNlCiAgICAgICAgewogICAgICAgICAgICAvKiBGaW5pc2hlZCBlbnVtZXJhdGluZyB0aGlzIGtleSAqLwogICAgICAgICAgICBpZiAoIWJBbHRlcm5hdGUpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIC8qIEVudW1lcmF0ZSBhbHRlcm5hdGUgc29ydHMgYWxzbyAqLwogICAgICAgICAgICAgICAgaEtleSA9IE5MU19SZWdPcGVuS2V5KCBoS2V5LCBzekFsdGVybmF0ZVNvcnRzS2V5TmFtZSApOwogICAgICAgICAgICAgICAgYkFsdGVybmF0ZSA9IFRSVUU7CiAgICAgICAgICAgICAgICB1bEluZGV4ID0gMDsKICAgICAgICAgICAgfQogICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICBiQ29udGludWUgPSBGQUxTRTsgLyogRmluaXNoZWQgYm90aCBrZXlzICovCiAgICAgICAgfQoKICAgICAgICBpZiAoIWJDb250aW51ZSkKICAgICAgICAgICAgYnJlYWs7CiAgICB9CgogICAgaWYgKGhLZXkpCiAgICAgICAgTnRDbG9zZSggaEtleSApOwoKICAgIHJldHVybiBUUlVFOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgICAgICBFbnVtTGFuZ3VhZ2VHcm91cExvY2FsZXNBICAgIChLRVJORUwzMi5AKQogKgogKiBDYWxsIGEgdXNlcnMgZnVuY3Rpb24gZm9yIGV2ZXJ5IGxvY2FsZSBpbiBhIGxhbmd1YWdlIGdyb3VwIGF2YWlsYWJsZSBvbiB0aGUgc3lzdGVtLgogKgogKiBQQVJBTVMKICogIHBMYW5nR3JwTGNFbnVtUHJvYyBbSV0gQ2FsbGJhY2sgZnVuY3Rpb24gdG8gY2FsbCBmb3IgZWFjaCBsb2NhbGUKICogIGxncnBpZCAgICAgICAgICAgICBbSV0gTGFuZ3VhZ2UgZ3JvdXAgKExHUlBJRF8gdmFsdWVzIGZyb20gIndpbm5scy5oIikKICogIGR3RmxhZ3MgICAgICAgICAgICBbSV0gUmVzZXJ2ZWQsIHNldCB0byAwCiAqICBsUGFyYW0gICAgICAgICAgICAgW0ldIFVzZXIgcGFyYW1ldGVyIHRvIHBhc3MgdG8gcExhbmdHcnBMY0VudW1Qcm9jCiAqCiAqIFJFVFVSTlMKICogIFN1Y2Nlc3M6IFRSVUUuCiAqICBGYWlsdXJlOiBGQUxTRS4gVXNlIEdldExhc3RFcnJvcigpIHRvIGRldGVybWluZSB0aGUgY2F1c2UuCiAqLwpCT09MIFdJTkFQSSBFbnVtTGFuZ3VhZ2VHcm91cExvY2FsZXNBKExBTkdHUk9VUExPQ0FMRV9FTlVNUFJPQ0EgcExhbmdHcnBMY0VudW1Qcm9jLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIExHUlBJRCBsZ3JwaWQsIERXT1JEIGR3RmxhZ3MsIExPTkdfUFRSIGxQYXJhbSkKewogICAgRU5VTUxBTkdVQUdFR1JPVVBMT0NBTEVfQ0FMTEJBQ0tTIGNhbGxiYWNrczsKCiAgICBUUkFDRSgiKCVwLDB4JTA4bFgsMHglMDhsWCwweCUwOGxYKVxuIiwgcExhbmdHcnBMY0VudW1Qcm9jLCBsZ3JwaWQsIGR3RmxhZ3MsIGxQYXJhbSk7CgogICAgY2FsbGJhY2tzLnByb2NBICAgPSBwTGFuZ0dycExjRW51bVByb2M7CiAgICBjYWxsYmFja3MucHJvY1cgICA9IE5VTEw7CiAgICBjYWxsYmFja3MuZHdGbGFncyA9IGR3RmxhZ3M7CiAgICBjYWxsYmFja3MubGdycGlkICA9IGxncnBpZDsKICAgIGNhbGxiYWNrcy5sUGFyYW0gID0gbFBhcmFtOwoKICAgIHJldHVybiBOTFNfRW51bUxhbmd1YWdlR3JvdXBMb2NhbGVzKCBwTGFuZ0dycExjRW51bVByb2MgPyAmY2FsbGJhY2tzIDogTlVMTCApOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgICAgICBFbnVtTGFuZ3VhZ2VHcm91cExvY2FsZXNXICAgIChLRVJORUwzMi5AKQogKgogKiBTZWUgRW51bUxhbmd1YWdlR3JvdXBMb2NhbGVzQS4KICovCkJPT0wgV0lOQVBJIEVudW1MYW5ndWFnZUdyb3VwTG9jYWxlc1coTEFOR0dST1VQTE9DQUxFX0VOVU1QUk9DVyBwTGFuZ0dycExjRW51bVByb2MsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTEdSUElEIGxncnBpZCwgRFdPUkQgZHdGbGFncywgTE9OR19QVFIgbFBhcmFtKQp7CiAgICBFTlVNTEFOR1VBR0VHUk9VUExPQ0FMRV9DQUxMQkFDS1MgY2FsbGJhY2tzOwoKICAgIFRSQUNFKCIoJXAsMHglMDhsWCwweCUwOGxYLDB4JTA4bFgpXG4iLCBwTGFuZ0dycExjRW51bVByb2MsIGxncnBpZCwgZHdGbGFncywgbFBhcmFtKTsKCiAgICBjYWxsYmFja3MucHJvY0EgICA9IE5VTEw7CiAgICBjYWxsYmFja3MucHJvY1cgICA9IHBMYW5nR3JwTGNFbnVtUHJvYzsKICAgIGNhbGxiYWNrcy5kd0ZsYWdzID0gZHdGbGFnczsKICAgIGNhbGxiYWNrcy5sZ3JwaWQgID0gbGdycGlkOwogICAgY2FsbGJhY2tzLmxQYXJhbSAgPSBsUGFyYW07CgogICAgcmV0dXJuIE5MU19FbnVtTGFuZ3VhZ2VHcm91cExvY2FsZXMoIHBMYW5nR3JwTGNFbnVtUHJvYyA/ICZjYWxsYmFja3MgOiBOVUxMICk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICAgICAgIEVudW1TeXN0ZW1HZW9JRCAgICAoS0VSTkVMMzIuQCkKICoKICogQ2FsbCBhIHVzZXJzIGZ1bmN0aW9uIGZvciBldmVyeSBsb2NhdGlvbiBhdmFpbGFibGUgb24gdGhlIHN5c3RlbS4KICoKICogUEFSQU1TCiAqICBnZW9jbGFzcyAgICAgW0ldIFR5cGUgb2YgaW5mb3JtYXRpb24gZGVzaXJlZCAoU1lTR0VPVFlQRSBlbnVtIGZyb20gIndpbm5scy5oIikKICogIHJlc2VydmVkICAgICBbSV0gUmVzZXJ2ZWQsIHNldCB0byAwCiAqICBwR2VvRW51bVByb2MgW0ldIENhbGxiYWNrIGZ1bmN0aW9uIHRvIGNhbGwgZm9yIGVhY2ggbG9jYXRpb24KICoKICogUkVUVVJOUwogKiAgU3VjY2VzczogVFJVRS4KICogIEZhaWx1cmU6IEZBTFNFLiBVc2UgR2V0TGFzdEVycm9yKCkgdG8gZGV0ZXJtaW5lIHRoZSBjYXVzZS4KICovCkJPT0wgV0lOQVBJIEVudW1TeXN0ZW1HZW9JRChHRU9DTEFTUyBnZW9jbGFzcywgR0VPSUQgcmVzZXJ2ZWQsIEdFT19FTlVNUFJPQyBwR2VvRW51bVByb2MpCnsKICAgIHN0YXRpYyBjb25zdCBXQ0hBUiBzekNvdW50cnlDb2RlVmFsdWVOYW1lW10gPSB7CiAgICAgICdDJywnbycsJ3UnLCduJywndCcsJ3InLCd5JywnQycsJ28nLCdkJywnZScsJ1wwJwogICAgfTsKICAgIFdDSEFSIHN6TnVtYmVyWzEwXTsKICAgIEhLRVkgaEtleTsKICAgIFVMT05HIHVsSW5kZXggPSAwOwoKICAgIFRSQUNFKCIoMHglMDhsWCwweCUwOGxYLCVwKVxuIiwgZ2VvY2xhc3MsIHJlc2VydmVkLCBwR2VvRW51bVByb2MpOwoKICAgIGlmIChnZW9jbGFzcyAhPSBHRU9DTEFTU19OQVRJT04gfHwgcmVzZXJ2ZWQgfHwgIXBHZW9FbnVtUHJvYykKICAgIHsKICAgICAgICBTZXRMYXN0RXJyb3IoRVJST1JfSU5WQUxJRF9QQVJBTUVURVIpOwogICAgICAgIHJldHVybiBGQUxTRTsKICAgIH0KCiAgICBoS2V5ID0gTkxTX1JlZ09wZW5LZXkoIDAsIHN6Q291bnRyeUxpc3ROYW1lICk7CgogICAgd2hpbGUgKE5MU19SZWdFbnVtU3ViS2V5KCBoS2V5LCB1bEluZGV4LCBzek51bWJlciwgc2l6ZW9mKHN6TnVtYmVyKSApKQogICAgewogICAgICAgIEJPT0wgYkNvbnRpbnVlID0gVFJVRTsKICAgICAgICBEV09SRCBkd0dlb0lkOwogICAgICAgIEhLRVkgaFN1YktleSA9IE5MU19SZWdPcGVuS2V5KCBoS2V5LCBzek51bWJlciApOwoKICAgICAgICBpZiAoaFN1YktleSkKICAgICAgICB7CiAgICAgICAgICAgIGlmIChOTFNfUmVnR2V0RHdvcmQoIGhTdWJLZXksIHN6Q291bnRyeUNvZGVWYWx1ZU5hbWUsICZkd0dlb0lkICkpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIFRSQUNFKCJHb3QgZ2VvaWQgJWxkXG4iLCBkd0dlb0lkKTsKCiAgICAgICAgICAgICAgICBpZiAoIXBHZW9FbnVtUHJvYyggZHdHZW9JZCApKQogICAgICAgICAgICAgICAgICAgIGJDb250aW51ZSA9IEZBTFNFOwogICAgICAgICAgICB9CgogICAgICAgICAgICBOdENsb3NlKCBoU3ViS2V5ICk7CiAgICAgICAgfQoKICAgICAgICBpZiAoIWJDb250aW51ZSkKICAgICAgICAgICAgYnJlYWs7CgogICAgICAgIHVsSW5kZXgrKzsKICAgIH0KCiAgICBpZiAoaEtleSkKICAgICAgICBOdENsb3NlKCBoS2V5ICk7CgogICAgcmV0dXJuIFRSVUU7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICAgICAgIEludmFsaWRhdGVOTFNDYWNoZSAgICAgICAgICAgKEtFUk5FTDMyLkApCiAqCiAqIEludmFsaWRhdGUgdGhlIGNhY2hlIG9mIE5MUyB2YWx1ZXMuCiAqCiAqIFBBUkFNUwogKiAgTm9uZS4KICoKICogUkVUVVJOUwogKiAgU3VjY2VzczogVFJVRS4KICogIEZhaWx1cmU6IEZBTFNFLgogKi8KQk9PTCBXSU5BUEkgSW52YWxpZGF0ZU5MU0NhY2hlKHZvaWQpCnsKICBGSVhNRSgiKCkgc3R1YlxuIik7CiAgcmV0dXJuIEZBTFNFOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgICAgICBHZXRVc2VyR2VvSUQgKEtFUk5FTDMyLkApCiAqLwpHRU9JRCBXSU5BUEkgR2V0VXNlckdlb0lEKCBHRU9DTEFTUyBHZW9DbGFzcyApCnsKICAgIEZJWE1FKCIlbGRcbiIsR2VvQ2xhc3MpOwogICAgcmV0dXJuIEdFT0lEX05PVF9BVkFJTEFCTEU7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICAgICAgIFNldFVzZXJHZW9JRCAoS0VSTkVMMzIuQCkKICovCkJPT0wgV0lOQVBJIFNldFVzZXJHZW9JRCggR0VPSUQgR2VvSUQgKQp7CiAgICBGSVhNRSgiJWxkXG4iLEdlb0lEKTsKICAgIHJldHVybiBGQUxTRTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgICAgICAgRW51bVVJTGFuZ3VhZ2VzQSAoS0VSTkVMMzIuQCkKICovCkJPT0wgV0lOQVBJIEVudW1VSUxhbmd1YWdlc0EoVUlMQU5HVUFHRV9FTlVNUFJPQ0EgcFVJTGFuZ0VudW1Qcm9jLCBEV09SRCBkd0ZsYWdzLCBMT05HX1BUUiBsUGFyYW0pCnsKICAgIHN0YXRpYyBjaGFyIHZhbHVlW10gPSAiMDQwOSI7CgogICAgaWYoIXBVSUxhbmdFbnVtUHJvYykgewoJU2V0TGFzdEVycm9yKEVSUk9SX0lOVkFMSURfUEFSQU1FVEVSKTsKCXJldHVybiBGQUxTRTsKICAgIH0KICAgIGlmKGR3RmxhZ3MpIHsKCVNldExhc3RFcnJvcihFUlJPUl9JTlZBTElEX0ZMQUdTKTsKCXJldHVybiBGQUxTRTsKICAgIH0KCiAgICBGSVhNRSgiJXAsICVseCwgJWx4IGNhbGxpbmcgcFVJTGFuZ0VudW1Qcm9jIHdpdGggJXNcbiIsCiAgICAgICAgICBwVUlMYW5nRW51bVByb2MsIGR3RmxhZ3MsIGxQYXJhbSwgZGVidWdzdHJfYSh2YWx1ZSkpOwoKICAgIHBVSUxhbmdFbnVtUHJvYyggdmFsdWUsIGxQYXJhbSApOwogICAgcmV0dXJuKFRSVUUpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgICAgICBFbnVtVUlMYW5ndWFnZXNXIChLRVJORUwzMi5AKQogKi8KQk9PTCBXSU5BUEkgRW51bVVJTGFuZ3VhZ2VzVyhVSUxBTkdVQUdFX0VOVU1QUk9DVyBwVUlMYW5nRW51bVByb2MsIERXT1JEIGR3RmxhZ3MsIExPTkdfUFRSIGxQYXJhbSkKewogICAgc3RhdGljIFdDSEFSIHZhbHVlW10gPSB7JzAnLCc0JywnMCcsJzknLDB9OwoKICAgIGlmKCFwVUlMYW5nRW51bVByb2MpIHsKCVNldExhc3RFcnJvcihFUlJPUl9JTlZBTElEX1BBUkFNRVRFUik7CglyZXR1cm4gRkFMU0U7CiAgICB9CiAgICBpZihkd0ZsYWdzKSB7CglTZXRMYXN0RXJyb3IoRVJST1JfSU5WQUxJRF9GTEFHUyk7CglyZXR1cm4gRkFMU0U7CiAgICB9CgogICAgRklYTUUoIiVwLCAlbHgsICVseCBjYWxsaW5nIHBVSUxhbmdFbnVtUHJvYyB3aXRoICVzXG4iLAogICAgICAgICAgcFVJTGFuZ0VudW1Qcm9jLCBkd0ZsYWdzLCBsUGFyYW0sIGRlYnVnc3RyX3codmFsdWUpKTsKCiAgICBwVUlMYW5nRW51bVByb2MoIHZhbHVlLCBsUGFyYW0gKTsKICAgIHJldHVybihUUlVFKTsKfQo=