LyoKICogTG9jYWxlIHN1cHBvcnQKICoKICogQ29weXJpZ2h0IDE5OTUgTWFydGluIHZvbiBMb2V3aXMKICogQ29weXJpZ2h0IDE5OTggRGF2aWQgTGVlIExhbWJlcnQKICogQ29weXJpZ2h0IDIwMDAgSnVsaW8gQ+lzYXIgR+F6cXVlegogKiBDb3B5cmlnaHQgMjAwMiBBbGV4YW5kcmUgSnVsbGlhcmQgZm9yIENvZGVXZWF2ZXJzCiAqCiAqIFRoaXMgbGlicmFyeSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IKICogbW9kaWZ5IGl0IHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpYwogKiBMaWNlbnNlIGFzIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uOyBlaXRoZXIKICogdmVyc2lvbiAyLjEgb2YgdGhlIExpY2Vuc2UsIG9yIChhdCB5b3VyIG9wdGlvbikgYW55IGxhdGVyIHZlcnNpb24uCiAqCiAqIFRoaXMgbGlicmFyeSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLAogKiBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZgogKiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVQogKiBMZXNzZXIgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBmb3IgbW9yZSBkZXRhaWxzLgogKgogKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljCiAqIExpY2Vuc2UgYWxvbmcgd2l0aCB0aGlzIGxpYnJhcnk7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUKICogRm91bmRhdGlvbiwgSW5jLiwgNTkgVGVtcGxlIFBsYWNlLCBTdWl0ZSAzMzAsIEJvc3RvbiwgTUEgIDAyMTExLTEzMDcgIFVTQQogKi8KCiNpbmNsdWRlICJjb25maWcuaCIKI2luY2x1ZGUgIndpbmUvcG9ydC5oIgoKI2luY2x1ZGUgPGFzc2VydC5oPgojaW5jbHVkZSA8c3RyaW5nLmg+CiNpbmNsdWRlIDxzdGRhcmcuaD4KI2luY2x1ZGUgPHN0ZGlvLmg+CiNpbmNsdWRlIDxjdHlwZS5oPgojaW5jbHVkZSA8c3RkbGliLmg+CgojaW5jbHVkZSAibnRzdGF0dXMuaCIKI2luY2x1ZGUgIndpbmRlZi5oIgojaW5jbHVkZSAid2luYmFzZS5oIgojaW5jbHVkZSAid2ludXNlci5oIiAgLyogZm9yIFJUX1NUUklOR1cgKi8KI2luY2x1ZGUgIndpbnRlcm5sLmgiCiNpbmNsdWRlICJ3aW5lL3VuaWNvZGUuaCIKI2luY2x1ZGUgIndpbm5scy5oIgojaW5jbHVkZSAid2luZXJyb3IuaCIKI2luY2x1ZGUgIndpbnZlci5oIgojaW5jbHVkZSAia2VybmVsX3ByaXZhdGUuaCIKI2luY2x1ZGUgIndpbmUvZGVidWcuaCIKCldJTkVfREVGQVVMVF9ERUJVR19DSEFOTkVMKG5scyk7CgojZGVmaW5lIExPQ0FMRV9MT0NBTEVJTkZPRkxBR1NNQVNLIChMT0NBTEVfTk9VU0VST1ZFUlJJREV8TE9DQUxFX1VTRV9DUF9BQ1B8TE9DQUxFX1JFVFVSTl9OVU1CRVIpCgovKiBjdXJyZW50IGNvZGUgcGFnZXMgKi8Kc3RhdGljIGNvbnN0IHVuaW9uIGNwdGFibGUgKmFuc2lfY3B0YWJsZTsKc3RhdGljIGNvbnN0IHVuaW9uIGNwdGFibGUgKm9lbV9jcHRhYmxlOwpzdGF0aWMgY29uc3QgdW5pb24gY3B0YWJsZSAqbWFjX2NwdGFibGU7CnN0YXRpYyBjb25zdCB1bmlvbiBjcHRhYmxlICp1bml4X2NwdGFibGU7ICAvKiBOVUxMIGlmIFVURjggKi8KCnN0YXRpYyBIQU5ETEUgTkxTX1JlZ09wZW5LZXkoSEFORExFIGhSb290S2V5LCBMUENXU1RSIHN6S2V5TmFtZSk7CnN0YXRpYyBIQU5ETEUgTkxTX1JlZ09wZW5TdWJLZXkoSEFORExFIGhSb290S2V5LCBMUENXU1RSIHN6S2V5TmFtZSk7CgpzdGF0aWMgY29uc3QgV0NIQVIgc3pObHNLZXlOYW1lW10gPSB7CiAgICAnTScsJ2EnLCdjJywnaCcsJ2knLCduJywnZScsJ1xcJywnUycsJ3knLCdzJywndCcsJ2UnLCdtJywnXFwnLAogICAgJ0MnLCd1JywncicsJ3InLCdlJywnbicsJ3QnLCdDJywnbycsJ24nLCd0JywncicsJ28nLCdsJywnUycsJ2UnLCd0JywnXFwnLAogICAgJ0MnLCdvJywnbicsJ3QnLCdyJywnbycsJ2wnLCdcXCcsJ04nLCdsJywncycsJ1wwJwp9OwoKLyogQ2hhcnNldCB0byBjb2RlcGFnZSBtYXAsIHNvcnRlZCBieSBuYW1lLiAqLwpzdGF0aWMgY29uc3Qgc3RydWN0IGNoYXJzZXRfZW50cnkKewogICAgY29uc3QgY2hhciAqY2hhcnNldF9uYW1lOwogICAgVUlOVCAgICAgICAgY29kZXBhZ2U7Cn0gY2hhcnNldF9uYW1lc1tdID0KewogICAgeyAiQklHNSIsIDk1MCB9LAogICAgeyAiQ1AxMjUwIiwgMTI1MCB9LAogICAgeyAiQ1AxMjUxIiwgMTI1MSB9LAogICAgeyAiQ1AxMjUyIiwgMTI1MiB9LAogICAgeyAiQ1AxMjUzIiwgMTI1MyB9LAogICAgeyAiQ1AxMjU0IiwgMTI1NCB9LAogICAgeyAiQ1AxMjU1IiwgMTI1NSB9LAogICAgeyAiQ1AxMjU2IiwgMTI1NiB9LAogICAgeyAiQ1AxMjU3IiwgMTI1NyB9LAogICAgeyAiQ1AxMjU4IiwgMTI1OCB9LAogICAgeyAiQ1A5MzIiLCA5MzIgfSwKICAgIHsgIkNQOTM2IiwgOTM2IH0sCiAgICB7ICJDUDk0OSIsIDk0OSB9LAogICAgeyAiQ1A5NTAiLCA5NTAgfSwKICAgIHsgIkVVQ0pQIiwgMjA5MzIgfSwKICAgIHsgIkdCMjMxMiIsIDkzNiB9LAogICAgeyAiSUJNMDM3IiwgMzcgfSwKICAgIHsgIklCTTEwMjYiLCAxMDI2IH0sCiAgICB7ICJJQk00MjQiLCA0MjQgfSwKICAgIHsgIklCTTQzNyIsIDQzNyB9LAogICAgeyAiSUJNNTAwIiwgNTAwIH0sCiAgICB7ICJJQk04NTAiLCA4NTAgfSwKICAgIHsgIklCTTg1MiIsIDg1MiB9LAogICAgeyAiSUJNODU1IiwgODU1IH0sCiAgICB7ICJJQk04NTciLCA4NTcgfSwKICAgIHsgIklCTTg2MCIsIDg2MCB9LAogICAgeyAiSUJNODYxIiwgODYxIH0sCiAgICB7ICJJQk04NjIiLCA4NjIgfSwKICAgIHsgIklCTTg2MyIsIDg2MyB9LAogICAgeyAiSUJNODY0IiwgODY0IH0sCiAgICB7ICJJQk04NjUiLCA4NjUgfSwKICAgIHsgIklCTTg2NiIsIDg2NiB9LAogICAgeyAiSUJNODY5IiwgODY5IH0sCiAgICB7ICJJQk04NzQiLCA4NzQgfSwKICAgIHsgIklCTTg3NSIsIDg3NSB9LAogICAgeyAiSVNPODg1OTEiLCAyODU5MSB9LAogICAgeyAiSVNPODg1OTEwIiwgMjg2MDAgfSwKICAgIHsgIklTTzg4NTkxMyIsIDI4NjAzIH0sCiAgICB7ICJJU084ODU5MTQiLCAyODYwNCB9LAogICAgeyAiSVNPODg1OTE1IiwgMjg2MDUgfSwKICAgIHsgIklTTzg4NTkxNiIsIDI4NjA2IH0sCiAgICB7ICJJU084ODU5MiIsIDI4NTkyIH0sCiAgICB7ICJJU084ODU5MyIsIDI4NTkzIH0sCiAgICB7ICJJU084ODU5NCIsIDI4NTk0IH0sCiAgICB7ICJJU084ODU5NSIsIDI4NTk1IH0sCiAgICB7ICJJU084ODU5NiIsIDI4NTk2IH0sCiAgICB7ICJJU084ODU5NyIsIDI4NTk3IH0sCiAgICB7ICJJU084ODU5OCIsIDI4NTk4IH0sCiAgICB7ICJJU084ODU5OSIsIDI4NTk5IH0sCiAgICB7ICJLT0k4UiIsIDIwODY2IH0sCiAgICB7ICJLT0k4VSIsIDIxODY2IH0sCiAgICB7ICJVVEY4IiwgQ1BfVVRGOCB9Cn07CgojZGVmaW5lIE5MU19NQVhfTEFOR1VBR0VTIDIwCnR5cGVkZWYgc3RydWN0IHsKICAgIFdDSEFSIGxhbmdbMTI4XTsKICAgIFdDSEFSIGNvdW50cnlbNF07CiAgICBMQU5HSUQgZm91bmRfbGFuZ19pZFtOTFNfTUFYX0xBTkdVQUdFU107CiAgICBpbnQgbl9mb3VuZDsKfSBMQU5HX0ZJTkRfREFUQTsKCgovKiBjb3B5IFVuaWNvZGUgc3RyaW5nIHRvIEFzY2lpIHdpdGhvdXQgdXNpbmcgY29kZXBhZ2VzICovCnN0YXRpYyBpbmxpbmUgdm9pZCBzdHJjcHlXdG9BKCBjaGFyICpkc3QsIGNvbnN0IFdDSEFSICpzcmMgKQp7CiAgICB3aGlsZSAoKCpkc3QrKyA9ICpzcmMrKykpOwp9CgovKiBDb3B5IEFzY2lpIHN0cmluZyB0byBVbmljb2RlIHdpdGhvdXQgdXNpbmcgY29kZXBhZ2VzICovCnN0YXRpYyBpbmxpbmUgdm9pZCBzdHJjcHluQXRvVyggV0NIQVIgKmRzdCwgY29uc3QgY2hhciAqc3JjLCBzaXplX3QgbiApCnsKICAgIHdoaWxlIChuID4gMSAmJiAqc3JjKQogICAgewogICAgICAgICpkc3QrKyA9ICh1bnNpZ25lZCBjaGFyKSpzcmMrKzsKICAgICAgICBuLS07CiAgICB9CiAgICBpZiAobikgKmRzdCA9IDA7Cn0KCi8qIHJldHVybiBhIHByaW50YWJsZSBzdHJpbmcgZm9yIGEgbGFuZ3VhZ2UgaWQgKi8Kc3RhdGljIGNvbnN0IGNoYXIgKmRlYnVnc3RyX2xhbmcoIExBTkdJRCBsYW5nICkKewogICAgV0NIQVIgbGFuZ1dbNF0sIGNvdW50cnlXWzRdOwogICAgY2hhciBidWZmZXJbOF07CiAgICBMQ0lEIGxjaWQgPSBNQUtFTENJRCggbGFuZywgU09SVF9ERUZBVUxUICk7CgogICAgR2V0TG9jYWxlSW5mb1cobGNpZCwgTE9DQUxFX1NJU082MzlMQU5HTkFNRXxMT0NBTEVfTk9VU0VST1ZFUlJJREUsIGxhbmdXLCBzaXplb2YobGFuZ1cpL3NpemVvZihXQ0hBUikpOwogICAgR2V0TG9jYWxlSW5mb1cobGNpZCwgTE9DQUxFX1NJU08zMTY2Q1RSWU5BTUV8TE9DQUxFX05PVVNFUk9WRVJSSURFLCBjb3VudHJ5Vywgc2l6ZW9mKGNvdW50cnlXKS9zaXplb2YoV0NIQVIpKTsKICAgIHN0cmNweVd0b0EoIGJ1ZmZlciwgbGFuZ1cgKTsKICAgIHN0cmNhdCggYnVmZmVyLCAiXyIgKTsKICAgIHN0cmNweVd0b0EoIGJ1ZmZlciArIHN0cmxlbihidWZmZXIpLCBjb3VudHJ5VyApOwogICAgcmV0dXJuIHdpbmVfZGJnX3NwcmludGYoICIlcyIsIGJ1ZmZlciApOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCWdldF9sY2lkX2NvZGVwYWdlCiAqCiAqIFJldHJpZXZlIHRoZSBBTlNJIGNvZGVwYWdlIGZvciBhIGdpdmVuIGxvY2FsZS4KICovCmlubGluZSBzdGF0aWMgVUlOVCBnZXRfbGNpZF9jb2RlcGFnZSggTENJRCBsY2lkICkKewogICAgVUlOVCByZXQ7CiAgICBpZiAoIUdldExvY2FsZUluZm9XKCBsY2lkLCBMT0NBTEVfSURFRkFVTFRBTlNJQ09ERVBBR0V8TE9DQUxFX1JFVFVSTl9OVU1CRVIsIChXQ0hBUiAqKSZyZXQsCiAgICAgICAgICAgICAgICAgICAgICAgICBzaXplb2YocmV0KS9zaXplb2YoV0NIQVIpICkpIHJldCA9IDA7CiAgICByZXR1cm4gcmV0Owp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCQlnZXRfY29kZXBhZ2VfdGFibGUKICoKICogRmluZCB0aGUgdGFibGUgZm9yIGEgZ2l2ZW4gY29kZXBhZ2UsIGhhbmRsaW5nIENQX0FDUCBldGMuIHBzZXVkby1jb2RlcGFnZXMKICovCnN0YXRpYyBjb25zdCB1bmlvbiBjcHRhYmxlICpnZXRfY29kZXBhZ2VfdGFibGUoIHVuc2lnbmVkIGludCBjb2RlcGFnZSApCnsKICAgIGNvbnN0IHVuaW9uIGNwdGFibGUgKnJldCA9IE5VTEw7CgogICAgYXNzZXJ0KCBhbnNpX2NwdGFibGUgKTsgIC8qIGluaXQgbXVzdCBoYXZlIGJlZW4gZG9uZSBhbHJlYWR5ICovCgogICAgc3dpdGNoKGNvZGVwYWdlKQogICAgewogICAgY2FzZSBDUF9BQ1A6CiAgICAgICAgcmV0dXJuIGFuc2lfY3B0YWJsZTsKICAgIGNhc2UgQ1BfT0VNQ1A6CiAgICAgICAgcmV0dXJuIG9lbV9jcHRhYmxlOwogICAgY2FzZSBDUF9NQUNDUDoKICAgICAgICByZXR1cm4gbWFjX2NwdGFibGU7CiAgICBjYXNlIENQX1VURjc6CiAgICBjYXNlIENQX1VURjg6CiAgICAgICAgYnJlYWs7CiAgICBjYXNlIENQX1RIUkVBRF9BQ1A6CiAgICAgICAgaWYgKCEoY29kZXBhZ2UgPSBrZXJuZWxfZ2V0X3RocmVhZF9kYXRhKCktPmNvZGVfcGFnZSkpIHJldHVybiBhbnNpX2NwdGFibGU7CiAgICAgICAgLyogZmFsbCB0aHJvdWdoICovCiAgICBkZWZhdWx0OgogICAgICAgIGlmIChjb2RlcGFnZSA9PSBhbnNpX2NwdGFibGUtPmluZm8uY29kZXBhZ2UpIHJldHVybiBhbnNpX2NwdGFibGU7CiAgICAgICAgaWYgKGNvZGVwYWdlID09IG9lbV9jcHRhYmxlLT5pbmZvLmNvZGVwYWdlKSByZXR1cm4gb2VtX2NwdGFibGU7CiAgICAgICAgaWYgKGNvZGVwYWdlID09IG1hY19jcHRhYmxlLT5pbmZvLmNvZGVwYWdlKSByZXR1cm4gbWFjX2NwdGFibGU7CiAgICAgICAgcmV0ID0gd2luZV9jcF9nZXRfdGFibGUoIGNvZGVwYWdlICk7CiAgICAgICAgYnJlYWs7CiAgICB9CiAgICByZXR1cm4gcmV0Owp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCWNyZWF0ZV9yZWdpc3RyeV9rZXkKICoKICogQ3JlYXRlIHRoZSBDb250cm9sIFBhbmVsXFxJbnRlcm5hdGlvbmFsIHJlZ2lzdHJ5IGtleS4KICovCmlubGluZSBzdGF0aWMgSEFORExFIGNyZWF0ZV9yZWdpc3RyeV9rZXkodm9pZCkKewogICAgc3RhdGljIGNvbnN0IFdDSEFSIGludGxXW10gPSB7J0MnLCdvJywnbicsJ3QnLCdyJywnbycsJ2wnLCcgJywnUCcsJ2EnLCduJywnZScsJ2wnLCdcXCcsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnSScsJ24nLCd0JywnZScsJ3InLCduJywnYScsJ3QnLCdpJywnbycsJ24nLCdhJywnbCcsMH07CiAgICBPQkpFQ1RfQVRUUklCVVRFUyBhdHRyOwogICAgVU5JQ09ERV9TVFJJTkcgbmFtZVc7CiAgICBIQU5ETEUgaGtleTsKCiAgICBpZiAoUnRsT3BlbkN1cnJlbnRVc2VyKCBLRVlfQUxMX0FDQ0VTUywgJmhrZXkgKSAhPSBTVEFUVVNfU1VDQ0VTUykgcmV0dXJuIDA7CgogICAgYXR0ci5MZW5ndGggPSBzaXplb2YoYXR0cik7CiAgICBhdHRyLlJvb3REaXJlY3RvcnkgPSBoa2V5OwogICAgYXR0ci5PYmplY3ROYW1lID0gJm5hbWVXOwogICAgYXR0ci5BdHRyaWJ1dGVzID0gMDsKICAgIGF0dHIuU2VjdXJpdHlEZXNjcmlwdG9yID0gTlVMTDsKICAgIGF0dHIuU2VjdXJpdHlRdWFsaXR5T2ZTZXJ2aWNlID0gTlVMTDsKICAgIFJ0bEluaXRVbmljb2RlU3RyaW5nKCAmbmFtZVcsIGludGxXICk7CgogICAgaWYgKE50Q3JlYXRlS2V5KCAmaGtleSwgS0VZX0FMTF9BQ0NFU1MsICZhdHRyLCAwLCBOVUxMLCAwLCBOVUxMICkgIT0gU1RBVFVTX1NVQ0NFU1MpIGhrZXkgPSAwOwogICAgTnRDbG9zZSggYXR0ci5Sb290RGlyZWN0b3J5ICk7CiAgICByZXR1cm4gaGtleTsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJTE9DQUxFX0luaXRSZWdpc3RyeQogKgogKiBVcGRhdGUgcmVnaXN0cnkgY29udGVudHMgb24gc3RhcnR1cCBpZiB0aGUgdXNlciBsb2NhbGUgaGFzIGNoYW5nZWQuCiAqIFRoaXMgc2ltdWxhdGVzIHRoZSBhY3Rpb24gb2YgdGhlIFdpbmRvd3MgY29udHJvbCBwYW5lbC4KICovCnZvaWQgTE9DQUxFX0luaXRSZWdpc3RyeSh2b2lkKQp7CiAgICBzdGF0aWMgY29uc3QgV0NIQVIgQ29kZXBhZ2VXW10gPSB7J0MnLCdvJywnZCcsJ2UnLCdwJywnYScsJ2cnLCdlJywwfTsKICAgIHN0YXRpYyBjb25zdCBXQ0hBUiBhY3BXW10gPSB7J0EnLCdDJywnUCcsMH07CiAgICBzdGF0aWMgY29uc3QgV0NIQVIgb2VtY3BXW10gPSB7J08nLCdFJywnTScsJ0MnLCdQJywwfTsKICAgIHN0YXRpYyBjb25zdCBXQ0hBUiBtYWNjcFdbXSA9IHsnTScsJ0EnLCdDJywnQycsJ1AnLDB9OwogICAgc3RhdGljIGNvbnN0IHN0cnVjdAogICAgewogICAgICAgIExQQ1dTVFIgbmFtZTsKICAgICAgICBVU0hPUlQgdmFsdWU7CiAgICB9IHVwZGF0ZV9jcF92YWx1ZXNbXSA9IHsKICAgICAgICB7IGFjcFcsIExPQ0FMRV9JREVGQVVMVEFOU0lDT0RFUEFHRSB9LAogICAgICAgIHsgb2VtY3BXLCBMT0NBTEVfSURFRkFVTFRDT0RFUEFHRSB9LAogICAgICAgIHsgbWFjY3BXLCBMT0NBTEVfSURFRkFVTFRNQUNDT0RFUEFHRSB9CiAgICB9OwogICAgc3RhdGljIGNvbnN0IFVTSE9SVCB1cGRhdGVWYWx1ZXNbXSA9IHsKICAgICAgTE9DQUxFX1NMQU5HVUFHRSwKICAgICAgTE9DQUxFX1NDT1VOVFJZLCBMT0NBTEVfSUNPVU5UUlksCiAgICAgIExPQ0FMRV9TMTE1OSwgTE9DQUxFX1MyMzU5LAogICAgICBMT0NBTEVfU1RJTUUsIExPQ0FMRV9JVElNRSwKICAgICAgTE9DQUxFX0lUTFpFUk8sCiAgICAgIExPQ0FMRV9TU0hPUlREQVRFLAogICAgICBMT0NBTEVfU0xPTkdEQVRFLAogICAgICBMT0NBTEVfU0RBVEUsCiAgICAgIExPQ0FMRV9TQ1VSUkVOQ1ksIExPQ0FMRV9JQ1VSUkVOQ1ksCiAgICAgIExPQ0FMRV9JTkVHQ1VSUiwKICAgICAgTE9DQUxFX0lDVVJSRElHSVRTLAogICAgICBMT0NBTEVfU0RFQ0lNQUwsCiAgICAgIExPQ0FMRV9TTElTVCwKICAgICAgTE9DQUxFX1NUSE9VU0FORCwKICAgICAgTE9DQUxFX0lESUdJVFMsCiAgICAgIExPQ0FMRV9JRElHSVRTVUJTVElUVVRJT04sCiAgICAgIExPQ0FMRV9TTkFUSVZFRElHSVRTLAogICAgICBMT0NBTEVfSVRJTUVNQVJLUE9TTiwKICAgICAgTE9DQUxFX0lDQUxFTkRBUlRZUEUsCiAgICAgIExPQ0FMRV9JTFpFUk8sCiAgICAgIExPQ0FMRV9JTUVBU1VSRQogICAgfTsKICAgIHN0YXRpYyBjb25zdCBXQ0hBUiBMb2NhbGVXW10gPSB7J0wnLCdvJywnYycsJ2EnLCdsJywnZScsMH07CiAgICBVTklDT0RFX1NUUklORyBuYW1lVzsKICAgIGNoYXIgYnVmZmVyWzIwXTsKICAgIFdDSEFSIGJ1ZmZlcldbODBdOwogICAgRFdPUkQgY291bnQsIGk7CiAgICBIQU5ETEUgaGtleTsKICAgIExDSUQgbGNpZCA9IEdldFVzZXJEZWZhdWx0TENJRCgpOwoKICAgIGlmICghKGhrZXkgPSBjcmVhdGVfcmVnaXN0cnlfa2V5KCkpKQogICAgICAgIHJldHVybjsgIC8qIGRvbid0IGRvIGFueXRoaW5nIGlmIHdlIGNhbid0IGNyZWF0ZSB0aGUgcmVnaXN0cnkga2V5ICovCgogICAgUnRsSW5pdFVuaWNvZGVTdHJpbmcoICZuYW1lVywgTG9jYWxlVyApOwogICAgY291bnQgPSBzaXplb2YoYnVmZmVyVyk7CiAgICBpZiAoIU50UXVlcnlWYWx1ZUtleShoa2V5LCAmbmFtZVcsIEtleVZhbHVlUGFydGlhbEluZm9ybWF0aW9uLCAoTFBCWVRFKWJ1ZmZlclcsIGNvdW50LCAmY291bnQpKQogICAgewogICAgICAgIGNvbnN0IEtFWV9WQUxVRV9QQVJUSUFMX0lORk9STUFUSU9OICppbmZvID0gKEtFWV9WQUxVRV9QQVJUSUFMX0lORk9STUFUSU9OICopYnVmZmVyVzsKICAgICAgICBMUENXU1RSIHN6VmFsdWVUZXh0ID0gKExQQ1dTVFIpaW5mby0+RGF0YTsKCiAgICAgICAgaWYgKHN0cnRvdWxXKCBzelZhbHVlVGV4dCwgTlVMTCwgMTYgKSA9PSBsY2lkKSAgLyogYWxyZWFkeSBzZXQgY29ycmVjdGx5ICovCiAgICAgICAgewogICAgICAgICAgICBOdENsb3NlKCBoa2V5ICk7CiAgICAgICAgICAgIHJldHVybjsKICAgICAgICB9CiAgICAgICAgVFJBQ0UoICJ1cGRhdGluZyByZWdpc3RyeSwgbG9jYWxlIGNoYW5nZWQgJXMgLT4gJTA4bHhcbiIsIGRlYnVnc3RyX3coc3pWYWx1ZVRleHQpLCBsY2lkICk7CiAgICB9CiAgICBlbHNlIFRSQUNFKCAidXBkYXRpbmcgcmVnaXN0cnksIGxvY2FsZSBjaGFuZ2VkIG5vbmUgLT4gJTA4bHhcbiIsIGxjaWQgKTsKCiAgICBzcHJpbnRmKCBidWZmZXIsICIlMDhseCIsIGxjaWQgKTsKICAgIC8qIE5vdGU6ICc5JyBjb25zdGFudCBiZWxvdyBpcyBzdHJsZW4oYnVmZmVyKSArIDEgKi8KICAgIFJ0bE11bHRpQnl0ZVRvVW5pY29kZU4oIGJ1ZmZlclcsIHNpemVvZihidWZmZXJXKSwgTlVMTCwgYnVmZmVyLCA5ICk7CiAgICBOdFNldFZhbHVlS2V5KCBoa2V5LCAmbmFtZVcsIDAsIFJFR19TWiwgYnVmZmVyVywgOSAqIHNpemVvZihXQ0hBUikgKTsKICAgIE50Q2xvc2UoIGhrZXkgKTsKCiAgICBmb3IgKGkgPSAwOyBpIDwgc2l6ZW9mKHVwZGF0ZVZhbHVlcykvc2l6ZW9mKHVwZGF0ZVZhbHVlc1swXSk7IGkrKykKICAgIHsKICAgICAgICBHZXRMb2NhbGVJbmZvVyggbGNpZCwgdXBkYXRlVmFsdWVzW2ldIHwgTE9DQUxFX05PVVNFUk9WRVJSSURFLCBidWZmZXJXLAogICAgICAgICAgICAgICAgICAgICAgICBzaXplb2YoYnVmZmVyVykvc2l6ZW9mKFdDSEFSKSApOwogICAgICAgIFNldExvY2FsZUluZm9XKCBsY2lkLCB1cGRhdGVWYWx1ZXNbaV0sIGJ1ZmZlclcgKTsKICAgIH0KCiAgICBoa2V5ID0gTkxTX1JlZ09wZW5TdWJLZXkoIE5MU19SZWdPcGVuS2V5KCAwLCBzek5sc0tleU5hbWUgKSwgQ29kZXBhZ2VXICk7CgogICAgZm9yIChpID0gMDsgaSA8IHNpemVvZih1cGRhdGVfY3BfdmFsdWVzKS9zaXplb2YodXBkYXRlX2NwX3ZhbHVlc1swXSk7IGkrKykKICAgIHsKICAgICAgICBjb3VudCA9IEdldExvY2FsZUluZm9XKCBsY2lkLCB1cGRhdGVfY3BfdmFsdWVzW2ldLnZhbHVlIHwgTE9DQUxFX05PVVNFUk9WRVJSSURFLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJ1ZmZlclcsIHNpemVvZihidWZmZXJXKS9zaXplb2YoV0NIQVIpICk7CiAgICAgICAgUnRsSW5pdFVuaWNvZGVTdHJpbmcoICZuYW1lVywgdXBkYXRlX2NwX3ZhbHVlc1tpXS5uYW1lICk7CiAgICAgICAgTnRTZXRWYWx1ZUtleSggaGtleSwgJm5hbWVXLCAwLCBSRUdfU1osIGJ1ZmZlclcsIGNvdW50ICogc2l6ZW9mKFdDSEFSKSApOwogICAgfQoKICAgIE50Q2xvc2UoIGhrZXkgKTsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgICAgICAgZmluZF9sYW5ndWFnZV9pZF9wcm9jCiAqLwpzdGF0aWMgQk9PTCBDQUxMQkFDSyBmaW5kX2xhbmd1YWdlX2lkX3Byb2MoIEhNT0RVTEUgaE1vZHVsZSwgTFBDV1NUUiB0eXBlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIExQQ1dTVFIgbmFtZSwgV09SRCBMYW5nSUQsIExQQVJBTSBsUGFyYW0gKQp7CiAgICBMQU5HX0ZJTkRfREFUQSAqbF9kYXRhID0gKExBTkdfRklORF9EQVRBICopbFBhcmFtOwogICAgTENJRCBsY2lkID0gTUFLRUxDSUQoTGFuZ0lELCBTT1JUX0RFRkFVTFQpOwogICAgV0NIQVIgYnVmX2xhbmd1YWdlWzEyOF07CiAgICBXQ0hBUiBidWZfY291bnRyeVsxMjhdOwogICAgV0NIQVIgYnVmX2VuX2xhbmd1YWdlWzEyOF07CgogICAgaWYoUFJJTUFSWUxBTkdJRChMYW5nSUQpID09IExBTkdfTkVVVFJBTCkKICAgICAgICByZXR1cm4gVFJVRTsgLyogY29udGludWUgc2VhcmNoICovCgogICAgYnVmX2xhbmd1YWdlWzBdID0gMDsKICAgIGJ1Zl9jb3VudHJ5WzBdID0gMDsKCiAgICBHZXRMb2NhbGVJbmZvVyhsY2lkLCBMT0NBTEVfU0lTTzYzOUxBTkdOQU1FfExPQ0FMRV9OT1VTRVJPVkVSUklERSwKICAgICAgICAgICAgICAgICAgIGJ1Zl9sYW5ndWFnZSwgc2l6ZW9mKGJ1Zl9sYW5ndWFnZSkvc2l6ZW9mKFdDSEFSKSk7CiAgICBHZXRMb2NhbGVJbmZvVyhsY2lkLCBMT0NBTEVfU0lTTzMxNjZDVFJZTkFNRXxMT0NBTEVfTk9VU0VST1ZFUlJJREUsCiAgICAgICAgICAgICAgICAgICBidWZfY291bnRyeSwgc2l6ZW9mKGJ1Zl9jb3VudHJ5KS9zaXplb2YoV0NIQVIpKTsKCiAgICBpZihsX2RhdGEtPmxhbmdbMF0gJiYgIXN0cmNtcGlXKGxfZGF0YS0+bGFuZywgYnVmX2xhbmd1YWdlKSkKICAgIHsKICAgICAgICBpZihsX2RhdGEtPmNvdW50cnlbMF0pCiAgICAgICAgewogICAgICAgICAgICBpZighc3RyY21waVcobF9kYXRhLT5jb3VudHJ5LCBidWZfY291bnRyeSkpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGxfZGF0YS0+Zm91bmRfbGFuZ19pZFswXSA9IExhbmdJRDsKICAgICAgICAgICAgICAgIGxfZGF0YS0+bl9mb3VuZCA9IDE7CiAgICAgICAgICAgICAgICBUUkFDRSgiRm91bmQgaWQgJTA0WCBmb3IgbGFuZyAlcyBjb3VudHJ5ICVzXG4iLAogICAgICAgICAgICAgICAgICAgICAgTGFuZ0lELCBkZWJ1Z3N0cl93KGxfZGF0YS0+bGFuZyksIGRlYnVnc3RyX3cobF9kYXRhLT5jb3VudHJ5KSk7CiAgICAgICAgICAgICAgICByZXR1cm4gRkFMU0U7IC8qIHN0b3AgZW51bWVyYXRpb24gKi8KICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBlbHNlIGdvdG8gZm91bmQ7IC8qIGxfZGF0YS0+Y291bnRyeSBub3Qgc3BlY2lmaWVkICovCiAgICB9CgogICAgLyogSnVzdCBpbiBjYXNlLCBjaGVjayBMT0NBTEVfU0VOR0xBTkdVQUdFIHRvbywKICAgICAqIGluIGhvcGUgdGhhdCBwb3NzaWJsZSBhbGlhcyBuYW1lIG1pZ2h0IGhhdmUgdGhhdCB2YWx1ZS4KICAgICAqLwogICAgYnVmX2VuX2xhbmd1YWdlWzBdID0gMDsKICAgIEdldExvY2FsZUluZm9XKGxjaWQsIExPQ0FMRV9TRU5HTEFOR1VBR0V8TE9DQUxFX05PVVNFUk9WRVJSSURFLAogICAgICAgICAgICAgICAgICAgYnVmX2VuX2xhbmd1YWdlLCBzaXplb2YoYnVmX2VuX2xhbmd1YWdlKS9zaXplb2YoV0NIQVIpKTsKCiAgICBpZihsX2RhdGEtPmxhbmdbMF0gJiYgIXN0cmNtcGlXKGxfZGF0YS0+bGFuZywgYnVmX2VuX2xhbmd1YWdlKSkgZ290byBmb3VuZDsKICAgIHJldHVybiBUUlVFOyAgLyogbm90IGZvdW5kLCBjb250aW51ZSBzZWFyY2ggKi8KCmZvdW5kOgogICAgbF9kYXRhLT5mb3VuZF9sYW5nX2lkW2xfZGF0YS0+bl9mb3VuZF0gPSBMYW5nSUQ7CiAgICBsX2RhdGEtPm5fZm91bmQrKzsKICAgIFRSQUNFKCJGb3VuZCBpZCAlMDRYIGZvciBsYW5nICVzXG4iLCBMYW5nSUQsIGRlYnVnc3RyX3cobF9kYXRhLT5sYW5nKSk7CiAgICByZXR1cm4gKGxfZGF0YS0+bl9mb3VuZCA8IE5MU19NQVhfTEFOR1VBR0VTKTsgLyogY29udGludWUgc2VhcmNoLCB1bmxlc3Mgd2UgaGF2ZSBlbm91Z2ggKi8KfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgICAgICAgZ2V0X2xhbmd1YWdlX2lkCiAqCiAqIElOUFVUOgogKglMYW5nOiBhIHN0cmluZyB3aG9zZSB0d28gZmlyc3QgY2hhcnMgYXJlIHRoZSBpc28gbmFtZSBvZiBhIGxhbmd1YWdlLgogKglDb3VudHJ5OiBhIHN0cmluZyB3aG9zZSB0d28gZmlyc3QgY2hhcnMgYXJlIHRoZSBpc28gbmFtZSBvZiBjb3VudHJ5CiAqCUNoYXJzZXQ6IGEgc3RyaW5nIGRlZmluaW5nIHRoZSBjaG9zZW4gY2hhcnNldCBlbmNvZGluZwogKglEaWFsZWN0OiBhIHN0cmluZyBkZWZpbmluZyBhIHZhcmlhdGlvbiBvZiB0aGUgbG9jYWxlCiAqCiAqCWFsbCB0aG9zZSB2YWx1ZXMgYXJlIGZyb20gdGhlIHN0YW5kYXJkaXplZCBmb3JtYXQgb2YgbG9jYWxlCiAqCW5hbWUgaW4gdW5peCB3aGljaCBpczogTGFuZ1tfQ291bnRyeV1bLkNoYXJzZXRdW0BEaWFsZWN0XQogKgogKiBSRVRVUk5TOgogKgl0aGUgbnVtZXJpYyBjb2RlIG9mIHRoZSBsYW5ndWFnZSB1c2VkIGJ5IFdpbmRvd3MKICoKICogRklYTUU6IENoYXJzZXQgYW5kIERpYWxlY3QgYXJlIG5vdCBoYW5kbGVkCiAqLwpzdGF0aWMgTEFOR0lEIGdldF9sYW5ndWFnZV9pZChMUENTVFIgTGFuZywgTFBDU1RSIENvdW50cnksIExQQ1NUUiBDaGFyc2V0LCBMUENTVFIgRGlhbGVjdCkKewogICAgTEFOR19GSU5EX0RBVEEgbF9kYXRhOwoKICAgIGlmKCFMYW5nKQogICAgewogICAgICAgIGxfZGF0YS5mb3VuZF9sYW5nX2lkWzBdID0gTUFLRUxBTkdJRChMQU5HX0VOR0xJU0gsIFNVQkxBTkdfREVGQVVMVCk7CiAgICAgICAgZ290byBFTkQ7CiAgICB9CgogICAgbF9kYXRhLm5fZm91bmQgPSAwOwogICAgc3RyY3B5bkF0b1cobF9kYXRhLmxhbmcsIExhbmcsIHNpemVvZihsX2RhdGEubGFuZykpOwoKICAgIGlmIChDb3VudHJ5KSBzdHJjcHluQXRvVyhsX2RhdGEuY291bnRyeSwgQ291bnRyeSwgc2l6ZW9mKGxfZGF0YS5jb3VudHJ5KSk7CiAgICBlbHNlIGxfZGF0YS5jb3VudHJ5WzBdID0gMDsKCiAgICBFbnVtUmVzb3VyY2VMYW5ndWFnZXNXKGtlcm5lbDMyX2hhbmRsZSwgKExQQ1dTVFIpUlRfU1RSSU5HLCAoTFBDV1NUUilMT0NBTEVfSUxBTkdVQUdFLAogICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5kX2xhbmd1YWdlX2lkX3Byb2MsIChMUEFSQU0pJmxfZGF0YSk7CgogICAgaWYgKGxfZGF0YS5uX2ZvdW5kID09IDEpIGdvdG8gRU5EOwoKICAgIGlmKCFsX2RhdGEubl9mb3VuZCkKICAgIHsKICAgICAgICBpZihsX2RhdGEuY291bnRyeVswXSkKICAgICAgICB7CiAgICAgICAgICAgIC8qIHJldHJ5IHdpdGhvdXQgY291bnRyeSBuYW1lICovCiAgICAgICAgICAgIGxfZGF0YS5jb3VudHJ5WzBdID0gMDsKICAgICAgICAgICAgRW51bVJlc291cmNlTGFuZ3VhZ2VzVyhrZXJuZWwzMl9oYW5kbGUsIChMUENXU1RSKVJUX1NUUklORywgKExQQ1dTVFIpTE9DQUxFX0lMQU5HVUFHRSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5kX2xhbmd1YWdlX2lkX3Byb2MsIChMT05HKSZsX2RhdGEpOwogICAgICAgICAgICBpZiAoIWxfZGF0YS5uX2ZvdW5kKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBNRVNTQUdFKCJXYXJuaW5nOiBMYW5ndWFnZSAnJXNfJXMnIHdhcyBub3QgcmVjb2duaXplZCwgZGVmYXVsdGluZyB0byBFbmdsaXNoLlxuIiwKICAgICAgICAgICAgICAgICAgICAgICAgTGFuZywgQ291bnRyeSk7CiAgICAgICAgICAgICAgICBsX2RhdGEuZm91bmRfbGFuZ19pZFswXSA9IE1BS0VMQU5HSUQoTEFOR19FTkdMSVNILCBTVUJMQU5HX0RFRkFVTFQpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGVsc2UgTUVTU0FHRSgiV2FybmluZzogTGFuZ3VhZ2UgJyVzXyVzJyB3YXMgbm90IHJlY29nbml6ZWQsIGRlZmF1bHRpbmcgdG8gJyVzJy5cbiIsCiAgICAgICAgICAgICAgICAgICAgICAgICBMYW5nLCBDb3VudHJ5LCBkZWJ1Z3N0cl9sYW5nKGxfZGF0YS5mb3VuZF9sYW5nX2lkWzBdKSApOwogICAgICAgIH0KICAgICAgICBlbHNlCiAgICAgICAgewogICAgICAgICAgICBNRVNTQUdFKCJXYXJuaW5nOiBMYW5ndWFnZSAnJXMnIHdhcyBub3QgcmVjb2duaXplZCwgZGVmYXVsdGluZyB0byBFbmdsaXNoLlxuIiwgTGFuZyk7CiAgICAgICAgICAgIGxfZGF0YS5mb3VuZF9sYW5nX2lkWzBdID0gTUFLRUxBTkdJRChMQU5HX0VOR0xJU0gsIFNVQkxBTkdfREVGQVVMVCk7CiAgICAgICAgfQogICAgfQogICAgZWxzZQogICAgewogICAgICAgIGludCBpOwoKICAgICAgICBpZiAoQ291bnRyeSAmJiBDb3VudHJ5WzBdKQogICAgICAgICAgICBNRVNTQUdFKCJGb3IgbGFuZ3VhZ2UgJyVzXyVzJyBzZXZlcmFsIGxhbmd1YWdlIGlkcyB3ZXJlIGZvdW5kOlxuIiwgTGFuZywgQ291bnRyeSk7CiAgICAgICAgZWxzZQogICAgICAgICAgICBNRVNTQUdFKCJGb3IgbGFuZ3VhZ2UgJyVzJyBzZXZlcmFsIGxhbmd1YWdlIGlkcyB3ZXJlIGZvdW5kOlxuIiwgTGFuZyk7CgogICAgICAgIC8qIHByaW50IGEgbGlzdCBvZiBsYW5ndWFnZXMgd2l0aCB0aGVpciBkZXNjcmlwdGlvbiAqLwogICAgICAgIGZvciAoaSA9IDA7IGkgPCBsX2RhdGEubl9mb3VuZDsgaSsrKQogICAgICAgIHsKICAgICAgICAgICAgV0NIQVIgYnVmZldbMTI4XTsKICAgICAgICAgICAgY2hhciBidWZmQVsxMjhdOwogICAgICAgICAgICBHZXRMb2NhbGVJbmZvVyggTUFLRUxDSUQoIGxfZGF0YS5mb3VuZF9sYW5nX2lkW2ldLCBTT1JUX0RFRkFVTFQgKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgTE9DQUxFX1NMQU5HVUFHRXxMT0NBTEVfTk9VU0VST1ZFUlJJREUsIGJ1ZmZXLCBzaXplb2YoYnVmZlcpL3NpemVvZihXQ0hBUikpOwogICAgICAgICAgICBzdHJjcHlXdG9BKCBidWZmQSwgYnVmZlcgKTsKICAgICAgICAgICAgTUVTU0FHRSggIiAgICVzICglMDRYKSAtICVzXG4iLCBkZWJ1Z3N0cl9sYW5nKGxfZGF0YS5mb3VuZF9sYW5nX2lkW2ldKSwKICAgICAgICAgICAgICAgICAgICAgbF9kYXRhLmZvdW5kX2xhbmdfaWRbaV0sIGJ1ZmZBICk7CiAgICAgICAgfQogICAgICAgIE1FU1NBR0UoIkRlZmF1bHRpbmcgdG8gJyVzJy4gWW91IHNob3VsZCBzcGVjaWZ5IHRoZSBleGFjdCBsYW5ndWFnZSB5b3Ugd2FudFxuIgogICAgICAgICAgICAgICAgImJ5IGRlZmluaW5nIHlvdXIgTEFORyBlbnZpcm9ubWVudCB2YXJpYWJsZSBsaWtlIHRoaXM6IExBTkc9JXNcbiIsCiAgICAgICAgICAgICAgICBkZWJ1Z3N0cl9sYW5nKGxfZGF0YS5mb3VuZF9sYW5nX2lkWzBdKSwgZGVidWdzdHJfbGFuZyhsX2RhdGEuZm91bmRfbGFuZ19pZFswXSkgKTsKICAgIH0KRU5EOgogICAgVFJBQ0UoIlJldHVybmluZyAlMDRYICglcylcbiIsIGxfZGF0YS5mb3VuZF9sYW5nX2lkWzBdLCBkZWJ1Z3N0cl9sYW5nKGxfZGF0YS5mb3VuZF9sYW5nX2lkWzBdKSk7CiAgICByZXR1cm4gbF9kYXRhLmZvdW5kX2xhbmdfaWRbMF07Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICAgICAgICAgIGNoYXJzZXRfY21wIChpbnRlcm5hbCkKICovCnN0YXRpYyBpbnQgY2hhcnNldF9jbXAoIGNvbnN0IHZvaWQgKm5hbWUsIGNvbnN0IHZvaWQgKmVudHJ5ICkKewogICAgY29uc3Qgc3RydWN0IGNoYXJzZXRfZW50cnkgKmNoYXJzZXQgPSAoY29uc3Qgc3RydWN0IGNoYXJzZXRfZW50cnkgKillbnRyeTsKICAgIHJldHVybiBzdHJjYXNlY21wKCAoY29uc3QgY2hhciAqKW5hbWUsIGNoYXJzZXQtPmNoYXJzZXRfbmFtZSApOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCWdldF9lbnZfbGNpZAogKi8Kc3RhdGljIExDSUQgZ2V0X2Vudl9sY2lkKCBVSU5UICp1bml4X2NwLCBjb25zdCBjaGFyICplbnZfc3RyICkKewogICAgY2hhciAqYnVmLCAqbGFuZywqY291bnRyeSwqY2hhcnNldCwqZGlhbGVjdCwqbmV4dDsKICAgIExDSUQgcmV0ID0gMDsKCiAgICBpZiAoKGxhbmcgPSBnZXRlbnYoICJMQ19BTEwiICkpIHx8CiAgICAgICAgKGVudl9zdHIgJiYgKGxhbmcgPSBnZXRlbnYoIGVudl9zdHIgKSkpIHx8CiAgICAgICAgKGxhbmcgPSBnZXRlbnYoICJMQU5HIiApKSkKICAgIHsKICAgICAgICBpZiAoIXN0cmNtcChsYW5nLCJQT1NJWCIpIHx8ICFzdHJjbXAobGFuZywiQyIpKSBnb3RvIGRvbmU7CgogICAgICAgIGJ1ZiA9IFJ0bEFsbG9jYXRlSGVhcCggR2V0UHJvY2Vzc0hlYXAoKSwgMCwgc3RybGVuKGxhbmcpICsgMSApOwogICAgICAgIHN0cmNweSggYnVmLCBsYW5nICk7CiAgICAgICAgbGFuZz1idWY7CgogICAgICAgIGRvIHsKICAgICAgICAgICAgbmV4dD1zdHJjaHIobGFuZywnOicpOyBpZiAobmV4dCkgKm5leHQrKz0nXDAnOwogICAgICAgICAgICBkaWFsZWN0PXN0cmNocihsYW5nLCdAJyk7IGlmIChkaWFsZWN0KSAqZGlhbGVjdCsrPSdcMCc7CiAgICAgICAgICAgIGNoYXJzZXQ9c3RyY2hyKGxhbmcsJy4nKTsgaWYgKGNoYXJzZXQpICpjaGFyc2V0Kys9J1wwJzsKICAgICAgICAgICAgY291bnRyeT1zdHJjaHIobGFuZywnXycpOyBpZiAoY291bnRyeSkgKmNvdW50cnkrKz0nXDAnOwoKICAgICAgICAgICAgcmV0ID0gZ2V0X2xhbmd1YWdlX2lkKGxhbmcsIGNvdW50cnksIGNoYXJzZXQsIGRpYWxlY3QpOwogICAgICAgICAgICBpZiAocmV0ICYmIGNoYXJzZXQgJiYgdW5peF9jcCkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgY29uc3Qgc3RydWN0IGNoYXJzZXRfZW50cnkgKmVudHJ5OwogICAgICAgICAgICAgICAgY2hhciBjaGFyc2V0X25hbWVbMTZdOwogICAgICAgICAgICAgICAgc2l6ZV90IGksIGo7CgogICAgICAgICAgICAgICAgLyogcmVtb3ZlIHB1bmN0dWF0aW9uIGNoYXJhY3RlcnMgZnJvbSBjaGFyc2V0IG5hbWUgKi8KICAgICAgICAgICAgICAgIGZvciAoaSA9IGogPSAwOyBjaGFyc2V0W2ldICYmIGogPCBzaXplb2YoY2hhcnNldF9uYW1lKS0xOyBpKyspCiAgICAgICAgICAgICAgICAgICAgaWYgKGlzYWxudW0oY2hhcnNldFtpXSkpIGNoYXJzZXRfbmFtZVtqKytdID0gY2hhcnNldFtpXTsKICAgICAgICAgICAgICAgIGNoYXJzZXRfbmFtZVtqXSA9IDA7CgogICAgICAgICAgICAgICAgZW50cnkgPSBic2VhcmNoKCBjaGFyc2V0X25hbWUsIGNoYXJzZXRfbmFtZXMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNpemVvZihjaGFyc2V0X25hbWVzKS9zaXplb2YoY2hhcnNldF9uYW1lc1swXSksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNpemVvZihjaGFyc2V0X25hbWVzWzBdKSwgY2hhcnNldF9jbXAgKTsKICAgICAgICAgICAgICAgIGlmIChlbnRyeSkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAqdW5peF9jcCA9IGVudHJ5LT5jb2RlcGFnZTsKICAgICAgICAgICAgICAgICAgICBUUkFDRSgiY2hhcnNldCAlcyB3YXMgbWFwcGVkIHRvIGNwICV1XG4iLCBjaGFyc2V0LCAqdW5peF9jcCk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICAgICAgRklYTUUoImNoYXJzZXQgJXMgd2FzIG5vdCByZWNvZ25pemVkXG4iLCBjaGFyc2V0KTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgbGFuZz1uZXh0OwogICAgICAgIH0gd2hpbGUgKGxhbmcgJiYgIXJldCk7CgogICAgICAgIGlmICghcmV0KSBNRVNTQUdFKCJXYXJuaW5nOiBsYW5ndWFnZSAnJXMnIG5vdCByZWNvZ25pemVkLCBkZWZhdWx0aW5nIHRvIEVuZ2xpc2hcbiIsIGJ1Zik7CiAgICAgICAgUnRsRnJlZUhlYXAoIEdldFByb2Nlc3NIZWFwKCksIDAsIGJ1ZiApOwogICAgfQoKIGRvbmU6CiAgICBpZiAoIXJldCkgcmV0ID0gTUFLRUxDSUQoIE1BS0VMQU5HSUQoTEFOR19FTkdMSVNILFNVQkxBTkdfREVGQVVMVCksIFNPUlRfREVGQVVMVCkgOwogICAgcmV0dXJuIHJldDsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJR2V0VXNlckRlZmF1bHRMYW5nSUQgKEtFUk5FTDMyLkApCiAqCiAqIEdldCB0aGUgZGVmYXVsdCBsYW5ndWFnZSBJZCBmb3IgdGhlIGN1cnJlbnQgdXNlci4KICoKICogUEFSQU1TCiAqICBOb25lLgogKgogKiBSRVRVUk5TCiAqICBUaGUgY3VycmVudCBMQU5HSUQgb2YgdGhlIGRlZmF1bHQgbGFuZ3VhZ2UgZm9yIHRoZSBjdXJyZW50IHVzZXIuCiAqLwpMQU5HSUQgV0lOQVBJIEdldFVzZXJEZWZhdWx0TGFuZ0lEKHZvaWQpCnsKICAgIHJldHVybiBMQU5HSURGUk9NTENJRChHZXRVc2VyRGVmYXVsdExDSUQoKSk7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCUdldFN5c3RlbURlZmF1bHRMYW5nSUQgKEtFUk5FTDMyLkApCiAqCiAqIEdldCB0aGUgZGVmYXVsdCBsYW5ndWFnZSBJZCBmb3IgdGhlIHN5c3RlbS4KICoKICogUEFSQU1TCiAqICBOb25lLgogKgogKiBSRVRVUk5TCiAqICBUaGUgY3VycmVudCBMQU5HSUQgb2YgdGhlIGRlZmF1bHQgbGFuZ3VhZ2UgZm9yIHRoZSBzeXN0ZW0uCiAqLwpMQU5HSUQgV0lOQVBJIEdldFN5c3RlbURlZmF1bHRMYW5nSUQodm9pZCkKewogICAgcmV0dXJuIExBTkdJREZST01MQ0lEKEdldFN5c3RlbURlZmF1bHRMQ0lEKCkpOwp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCQlHZXRVc2VyRGVmYXVsdExDSUQgKEtFUk5FTDMyLkApCiAqCiAqIEdldCB0aGUgZGVmYXVsdCBsb2NhbGUgSWQgZm9yIHRoZSBjdXJyZW50IHVzZXIuCiAqCiAqIFBBUkFNUwogKiAgTm9uZS4KICoKICogUkVUVVJOUwogKiAgVGhlIGN1cnJlbnQgTENJRCBvZiB0aGUgZGVmYXVsdCBsb2NhbGUgZm9yIHRoZSBjdXJyZW50IHVzZXIuCiAqLwpMQ0lEIFdJTkFQSSBHZXRVc2VyRGVmYXVsdExDSUQodm9pZCkKewogICAgTENJRCBsY2lkOwogICAgTnRRdWVyeURlZmF1bHRMb2NhbGUoIFRSVUUsICZsY2lkICk7CiAgICByZXR1cm4gbGNpZDsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJR2V0U3lzdGVtRGVmYXVsdExDSUQgKEtFUk5FTDMyLkApCiAqCiAqIEdldCB0aGUgZGVmYXVsdCBsb2NhbGUgSWQgZm9yIHRoZSBzeXN0ZW0uCiAqCiAqIFBBUkFNUwogKiAgTm9uZS4KICoKICogUkVUVVJOUwogKiAgVGhlIGN1cnJlbnQgTENJRCBvZiB0aGUgZGVmYXVsdCBsb2NhbGUgZm9yIHRoZSBzeXN0ZW0uCiAqLwpMQ0lEIFdJTkFQSSBHZXRTeXN0ZW1EZWZhdWx0TENJRCh2b2lkKQp7CiAgICBMQ0lEIGxjaWQ7CiAgICBOdFF1ZXJ5RGVmYXVsdExvY2FsZSggRkFMU0UsICZsY2lkICk7CiAgICByZXR1cm4gbGNpZDsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJR2V0VXNlckRlZmF1bHRVSUxhbmd1YWdlIChLRVJORUwzMi5AKQogKgogKiBHZXQgdGhlIGRlZmF1bHQgdXNlciBpbnRlcmZhY2UgbGFuZ3VhZ2UgSWQgZm9yIHRoZSBjdXJyZW50IHVzZXIuCiAqCiAqIFBBUkFNUwogKiAgTm9uZS4KICoKICogUkVUVVJOUwogKiAgVGhlIGN1cnJlbnQgTEFOR0lEIG9mIHRoZSBkZWZhdWx0IFVJIGxhbmd1YWdlIGZvciB0aGUgY3VycmVudCB1c2VyLgogKi8KTEFOR0lEIFdJTkFQSSBHZXRVc2VyRGVmYXVsdFVJTGFuZ3VhZ2Uodm9pZCkKewogICAgTEFOR0lEIGxhbmc7CiAgICBOdFF1ZXJ5RGVmYXVsdFVJTGFuZ3VhZ2UoICZsYW5nICk7CiAgICByZXR1cm4gbGFuZzsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJR2V0U3lzdGVtRGVmYXVsdFVJTGFuZ3VhZ2UgKEtFUk5FTDMyLkApCiAqCiAqIEdldCB0aGUgZGVmYXVsdCB1c2VyIGludGVyZmFjZSBsYW5ndWFnZSBJZCBmb3IgdGhlIHN5c3RlbS4KICoKICogUEFSQU1TCiAqICBOb25lLgogKgogKiBSRVRVUk5TCiAqICBUaGUgY3VycmVudCBMQU5HSUQgb2YgdGhlIGRlZmF1bHQgVUkgbGFuZ3VhZ2UgZm9yIHRoZSBzeXN0ZW0uIFRoaXMgaXMKICogIHR5cGljYWxseSB0aGUgc2FtZSBsYW5ndWFnZSB1c2VkIGR1cmluZyB0aGUgaW5zdGFsbGF0aW9uIHByb2Nlc3MuCiAqLwpMQU5HSUQgV0lOQVBJIEdldFN5c3RlbURlZmF1bHRVSUxhbmd1YWdlKHZvaWQpCnsKICAgIExBTkdJRCBsYW5nOwogICAgTnRRdWVyeUluc3RhbGxVSUxhbmd1YWdlKCAmbGFuZyApOwogICAgcmV0dXJuIGxhbmc7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCQlnZXRfbG9jYWxlX3ZhbHVlX25hbWUKICoKICogR2V0cyB0aGUgcmVnaXN0cnkgdmFsdWUgbmFtZSBmb3IgYSBnaXZlbiBsY3R5cGUuCiAqLwpzdGF0aWMgY29uc3QgV0NIQVIgKmdldF9sb2NhbGVfdmFsdWVfbmFtZSggRFdPUkQgbGN0eXBlICkKewogICAgc3RhdGljIGNvbnN0IFdDSEFSIGlDYWxlbmRhclR5cGVXW10gPSB7J2knLCdDJywnYScsJ2wnLCdlJywnbicsJ2QnLCdhJywncicsJ1QnLCd5JywncCcsJ2UnLDB9OwogICAgc3RhdGljIGNvbnN0IFdDSEFSIGlDb3VudHJ5V1tdID0geydpJywnQycsJ28nLCd1JywnbicsJ3QnLCdyJywneScsMH07CiAgICBzdGF0aWMgY29uc3QgV0NIQVIgaUN1cnJEaWdpdHNXW10gPSB7J2knLCdDJywndScsJ3InLCdyJywnRCcsJ2knLCdnJywnaScsJ3QnLCdzJywwfTsKICAgIHN0YXRpYyBjb25zdCBXQ0hBUiBpQ3VycmVuY3lXW10gPSB7J2knLCdDJywndScsJ3InLCdyJywnZScsJ24nLCdjJywneScsMH07CiAgICBzdGF0aWMgY29uc3QgV0NIQVIgaURhdGVXW10gPSB7J2knLCdEJywnYScsJ3QnLCdlJywwfTsKICAgIHN0YXRpYyBjb25zdCBXQ0hBUiBpRGlnaXRzV1tdID0geydpJywnRCcsJ2knLCdnJywnaScsJ3QnLCdzJywwfTsKICAgIHN0YXRpYyBjb25zdCBXQ0hBUiBpRmlyc3REYXlPZldlZWtXW10gPSB7J2knLCdGJywnaScsJ3InLCdzJywndCcsJ0QnLCdhJywneScsJ08nLCdmJywnVycsJ2UnLCdlJywnaycsMH07CiAgICBzdGF0aWMgY29uc3QgV0NIQVIgaUZpcnN0V2Vla09mWWVhcldbXSA9IHsnaScsJ0YnLCdpJywncicsJ3MnLCd0JywnVycsJ2UnLCdlJywnaycsJ08nLCdmJywnWScsJ2UnLCdhJywncicsMH07CiAgICBzdGF0aWMgY29uc3QgV0NIQVIgaUxEYXRlV1tdID0geydpJywnTCcsJ0QnLCdhJywndCcsJ2UnLDB9OwogICAgc3RhdGljIGNvbnN0IFdDSEFSIGlMWmVyb1dbXSA9IHsnaScsJ0wnLCdaJywnZScsJ3InLCdvJywwfTsKICAgIHN0YXRpYyBjb25zdCBXQ0hBUiBpTWVhc3VyZVdbXSA9IHsnaScsJ00nLCdlJywnYScsJ3MnLCd1JywncicsJ2UnLDB9OwogICAgc3RhdGljIGNvbnN0IFdDSEFSIGlOZWdDdXJyV1tdID0geydpJywnTicsJ2UnLCdnJywnQycsJ3UnLCdyJywncicsMH07CiAgICBzdGF0aWMgY29uc3QgV0NIQVIgaU5lZ051bWJlcldbXSA9IHsnaScsJ04nLCdlJywnZycsJ04nLCd1JywnbScsJ2InLCdlJywncicsMH07CiAgICBzdGF0aWMgY29uc3QgV0NIQVIgaVBhcGVyU2l6ZVdbXSA9IHsnaScsJ1AnLCdhJywncCcsJ2UnLCdyJywnUycsJ2knLCd6JywnZScsMH07CiAgICBzdGF0aWMgY29uc3QgV0NIQVIgaVRMWmVyb1dbXSA9IHsnaScsJ1QnLCdMJywnWicsJ2UnLCdyJywnbycsMH07CiAgICBzdGF0aWMgY29uc3QgV0NIQVIgaVRpbWVQcmVmaXhXW10gPSB7J2knLCdUJywnaScsJ20nLCdlJywnUCcsJ3InLCdlJywnZicsJ2knLCd4JywwfTsKICAgIHN0YXRpYyBjb25zdCBXQ0hBUiBpVGltZVdbXSA9IHsnaScsJ1QnLCdpJywnbScsJ2UnLDB9OwogICAgc3RhdGljIGNvbnN0IFdDSEFSIHMxMTU5V1tdID0geydzJywnMScsJzEnLCc1JywnOScsMH07CiAgICBzdGF0aWMgY29uc3QgV0NIQVIgczIzNTlXW10gPSB7J3MnLCcyJywnMycsJzUnLCc5JywwfTsKICAgIHN0YXRpYyBjb25zdCBXQ0hBUiBzQ291bnRyeVdbXSA9IHsncycsJ0MnLCdvJywndScsJ24nLCd0JywncicsJ3knLDB9OwogICAgc3RhdGljIGNvbnN0IFdDSEFSIHNDdXJyZW5jeVdbXSA9IHsncycsJ0MnLCd1JywncicsJ3InLCdlJywnbicsJ2MnLCd5JywwfTsKICAgIHN0YXRpYyBjb25zdCBXQ0hBUiBzRGF0ZVdbXSA9IHsncycsJ0QnLCdhJywndCcsJ2UnLDB9OwogICAgc3RhdGljIGNvbnN0IFdDSEFSIHNEZWNpbWFsV1tdID0geydzJywnRCcsJ2UnLCdjJywnaScsJ20nLCdhJywnbCcsMH07CiAgICBzdGF0aWMgY29uc3QgV0NIQVIgc0dyb3VwaW5nV1tdID0geydzJywnRycsJ3InLCdvJywndScsJ3AnLCdpJywnbicsJ2cnLDB9OwogICAgc3RhdGljIGNvbnN0IFdDSEFSIHNMYW5ndWFnZVdbXSA9IHsncycsJ0wnLCdhJywnbicsJ2cnLCd1JywnYScsJ2cnLCdlJywwfTsKICAgIHN0YXRpYyBjb25zdCBXQ0hBUiBzTGlzdFdbXSA9IHsncycsJ0wnLCdpJywncycsJ3QnLDB9OwogICAgc3RhdGljIGNvbnN0IFdDSEFSIHNMb25nRGF0ZVdbXSA9IHsncycsJ0wnLCdvJywnbicsJ2cnLCdEJywnYScsJ3QnLCdlJywwfTsKICAgIHN0YXRpYyBjb25zdCBXQ0hBUiBzTW9uRGVjaW1hbFNlcFdbXSA9IHsncycsJ00nLCdvJywnbicsJ0QnLCdlJywnYycsJ2knLCdtJywnYScsJ2wnLCdTJywnZScsJ3AnLDB9OwogICAgc3RhdGljIGNvbnN0IFdDSEFSIHNNb25Hcm91cGluZ1dbXSA9IHsncycsJ00nLCdvJywnbicsJ0cnLCdyJywnbycsJ3UnLCdwJywnaScsJ24nLCdnJywwfTsKICAgIHN0YXRpYyBjb25zdCBXQ0hBUiBzTW9uVGhvdXNhbmRTZXBXW10gPSB7J3MnLCdNJywnbycsJ24nLCdUJywnaCcsJ28nLCd1JywncycsJ2EnLCduJywnZCcsJ1MnLCdlJywncCcsMH07CiAgICBzdGF0aWMgY29uc3QgV0NIQVIgc05hdGl2ZURpZ2l0c1dbXSA9IHsncycsJ04nLCdhJywndCcsJ2knLCd2JywnZScsJ0QnLCdpJywnZycsJ2knLCd0JywncycsMH07CiAgICBzdGF0aWMgY29uc3QgV0NIQVIgc05lZ2F0aXZlU2lnbldbXSA9IHsncycsJ04nLCdlJywnZycsJ2EnLCd0JywnaScsJ3YnLCdlJywnUycsJ2knLCdnJywnbicsMH07CiAgICBzdGF0aWMgY29uc3QgV0NIQVIgc1Bvc2l0aXZlU2lnbldbXSA9IHsncycsJ1AnLCdvJywncycsJ2knLCd0JywnaScsJ3YnLCdlJywnUycsJ2knLCdnJywnbicsMH07CiAgICBzdGF0aWMgY29uc3QgV0NIQVIgc1Nob3J0RGF0ZVdbXSA9IHsncycsJ1MnLCdoJywnbycsJ3InLCd0JywnRCcsJ2EnLCd0JywnZScsMH07CiAgICBzdGF0aWMgY29uc3QgV0NIQVIgc1Rob3VzYW5kV1tdID0geydzJywnVCcsJ2gnLCdvJywndScsJ3MnLCdhJywnbicsJ2QnLDB9OwogICAgc3RhdGljIGNvbnN0IFdDSEFSIHNUaW1lRm9ybWF0V1tdID0geydzJywnVCcsJ2knLCdtJywnZScsJ0YnLCdvJywncicsJ20nLCdhJywndCcsMH07CiAgICBzdGF0aWMgY29uc3QgV0NIQVIgc1RpbWVXW10gPSB7J3MnLCdUJywnaScsJ20nLCdlJywwfTsKICAgIHN0YXRpYyBjb25zdCBXQ0hBUiBzWWVhck1vbnRoV1tdID0geydzJywnWScsJ2UnLCdhJywncicsJ00nLCdvJywnbicsJ3QnLCdoJywwfTsKICAgIHN0YXRpYyBjb25zdCBXQ0hBUiBOdW1TaGFwZVdbXSA9IHsnTicsJ3UnLCdtJywncycsJ2gnLCdhJywncCcsJ2UnLDB9OwoKICAgIHN3aXRjaCAobGN0eXBlKQogICAgewogICAgLyogVGhlc2UgdmFsdWVzIGFyZSB1c2VkIGJ5IFNldExvY2FsZUluZm8gYW5kIEdldExvY2FsZUluZm8sIGFuZAogICAgICogdGhlIHZhbHVlcyBhcmUgc3RvcmVkIGluIHRoZSByZWdpc3RyeSwgY29uZmlybWVkIHVuZGVyIFdpbmRvd3MuCiAgICAgKi8KICAgIGNhc2UgTE9DQUxFX0lDQUxFTkRBUlRZUEU6ICAgIHJldHVybiBpQ2FsZW5kYXJUeXBlVzsKICAgIGNhc2UgTE9DQUxFX0lDVVJSRElHSVRTOiAgICAgIHJldHVybiBpQ3VyckRpZ2l0c1c7CiAgICBjYXNlIExPQ0FMRV9JQ1VSUkVOQ1k6ICAgICAgICByZXR1cm4gaUN1cnJlbmN5VzsKICAgIGNhc2UgTE9DQUxFX0lESUdJVFM6ICAgICAgICAgIHJldHVybiBpRGlnaXRzVzsKICAgIGNhc2UgTE9DQUxFX0lGSVJTVERBWU9GV0VFSzogIHJldHVybiBpRmlyc3REYXlPZldlZWtXOwogICAgY2FzZSBMT0NBTEVfSUZJUlNUV0VFS09GWUVBUjogcmV0dXJuIGlGaXJzdFdlZWtPZlllYXJXOwogICAgY2FzZSBMT0NBTEVfSUxaRVJPOiAgICAgICAgICAgcmV0dXJuIGlMWmVyb1c7CiAgICBjYXNlIExPQ0FMRV9JTUVBU1VSRTogICAgICAgICByZXR1cm4gaU1lYXN1cmVXOwogICAgY2FzZSBMT0NBTEVfSU5FR0NVUlI6ICAgICAgICAgcmV0dXJuIGlOZWdDdXJyVzsKICAgIGNhc2UgTE9DQUxFX0lORUdOVU1CRVI6ICAgICAgIHJldHVybiBpTmVnTnVtYmVyVzsKICAgIGNhc2UgTE9DQUxFX0lQQVBFUlNJWkU6ICAgICAgIHJldHVybiBpUGFwZXJTaXplVzsKICAgIGNhc2UgTE9DQUxFX0lUSU1FOiAgICAgICAgICAgIHJldHVybiBpVGltZVc7CiAgICBjYXNlIExPQ0FMRV9TMTE1OTogICAgICAgICAgICByZXR1cm4gczExNTlXOwogICAgY2FzZSBMT0NBTEVfUzIzNTk6ICAgICAgICAgICAgcmV0dXJuIHMyMzU5VzsKICAgIGNhc2UgTE9DQUxFX1NDVVJSRU5DWTogICAgICAgIHJldHVybiBzQ3VycmVuY3lXOwogICAgY2FzZSBMT0NBTEVfU0RBVEU6ICAgICAgICAgICAgcmV0dXJuIHNEYXRlVzsKICAgIGNhc2UgTE9DQUxFX1NERUNJTUFMOiAgICAgICAgIHJldHVybiBzRGVjaW1hbFc7CiAgICBjYXNlIExPQ0FMRV9TR1JPVVBJTkc6ICAgICAgICByZXR1cm4gc0dyb3VwaW5nVzsKICAgIGNhc2UgTE9DQUxFX1NMSVNUOiAgICAgICAgICAgIHJldHVybiBzTGlzdFc7CiAgICBjYXNlIExPQ0FMRV9TTE9OR0RBVEU6ICAgICAgICByZXR1cm4gc0xvbmdEYXRlVzsKICAgIGNhc2UgTE9DQUxFX1NNT05ERUNJTUFMU0VQOiAgIHJldHVybiBzTW9uRGVjaW1hbFNlcFc7CiAgICBjYXNlIExPQ0FMRV9TTU9OR1JPVVBJTkc6ICAgICByZXR1cm4gc01vbkdyb3VwaW5nVzsKICAgIGNhc2UgTE9DQUxFX1NNT05USE9VU0FORFNFUDogIHJldHVybiBzTW9uVGhvdXNhbmRTZXBXOwogICAgY2FzZSBMT0NBTEVfU05FR0FUSVZFU0lHTjogICAgcmV0dXJuIHNOZWdhdGl2ZVNpZ25XOwogICAgY2FzZSBMT0NBTEVfU1BPU0lUSVZFU0lHTjogICAgcmV0dXJuIHNQb3NpdGl2ZVNpZ25XOwogICAgY2FzZSBMT0NBTEVfU1NIT1JUREFURTogICAgICAgcmV0dXJuIHNTaG9ydERhdGVXOwogICAgY2FzZSBMT0NBTEVfU1RIT1VTQU5EOiAgICAgICAgcmV0dXJuIHNUaG91c2FuZFc7CiAgICBjYXNlIExPQ0FMRV9TVElNRTogICAgICAgICAgICByZXR1cm4gc1RpbWVXOwogICAgY2FzZSBMT0NBTEVfU1RJTUVGT1JNQVQ6ICAgICAgcmV0dXJuIHNUaW1lRm9ybWF0VzsKICAgIGNhc2UgTE9DQUxFX1NZRUFSTU9OVEg6ICAgICAgIHJldHVybiBzWWVhck1vbnRoVzsKCiAgICAvKiBUaGUgZm9sbG93aW5nIGFyZSBub3QgbGlzdGVkIHVuZGVyIE1TRE4gYXMgc3VwcG9ydGVkLAogICAgICogYnV0IHNlZW0gdG8gYmUgdXNlZCBhbmQgYWxzbyBzdG9yZWQgaW4gdGhlIHJlZ2lzdHJ5LgogICAgICovCiAgICBjYXNlIExPQ0FMRV9JQ09VTlRSWTogICAgICAgICByZXR1cm4gaUNvdW50cnlXOwogICAgY2FzZSBMT0NBTEVfSURBVEU6ICAgICAgICAgICAgcmV0dXJuIGlEYXRlVzsKICAgIGNhc2UgTE9DQUxFX0lMREFURTogICAgICAgICAgIHJldHVybiBpTERhdGVXOwogICAgY2FzZSBMT0NBTEVfSVRMWkVSTzogICAgICAgICAgcmV0dXJuIGlUTFplcm9XOwogICAgY2FzZSBMT0NBTEVfU0NPVU5UUlk6ICAgICAgICAgcmV0dXJuIHNDb3VudHJ5VzsKICAgIGNhc2UgTE9DQUxFX1NMQU5HVUFHRTogICAgICAgIHJldHVybiBzTGFuZ3VhZ2VXOwoKICAgIC8qIFRoZSBmb2xsb3dpbmcgYXJlIHVzZWQgaW4gWFAgYW5kIGxhdGVyICovCiAgICBjYXNlIExPQ0FMRV9JRElHSVRTVUJTVElUVVRJT046IHJldHVybiBOdW1TaGFwZVc7CiAgICBjYXNlIExPQ0FMRV9TTkFUSVZFRElHSVRTOiAgICAgIHJldHVybiBzTmF0aXZlRGlnaXRzVzsKICAgIGNhc2UgTE9DQUxFX0lUSU1FTUFSS1BPU046ICAgICAgcmV0dXJuIGlUaW1lUHJlZml4VzsKICAgIH0KICAgIHJldHVybiBOVUxMOwp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJZ2V0X3JlZ2lzdHJ5X2xvY2FsZV9pbmZvCiAqCiAqIFJldHJpZXZlIHVzZXItbW9kaWZpZWQgbG9jYWxlIGluZm8gZnJvbSB0aGUgcmVnaXN0cnkuCiAqIFJldHVybiBsZW5ndGgsIDAgb24gZXJyb3IsIC0xIGlmIG5vdCBmb3VuZC4KICovCnN0YXRpYyBJTlQgZ2V0X3JlZ2lzdHJ5X2xvY2FsZV9pbmZvKCBMUENXU1RSIHZhbHVlLCBMUFdTVFIgYnVmZmVyLCBJTlQgbGVuICkKewogICAgRFdPUkQgc2l6ZTsKICAgIElOVCByZXQ7CiAgICBIQU5ETEUgaGtleTsKICAgIE5UU1RBVFVTIHN0YXR1czsKICAgIFVOSUNPREVfU1RSSU5HIG5hbWVXOwogICAgS0VZX1ZBTFVFX1BBUlRJQUxfSU5GT1JNQVRJT04gKmluZm87CiAgICBzdGF0aWMgY29uc3QgaW50IGluZm9fc2l6ZSA9IEZJRUxEX09GRlNFVChLRVlfVkFMVUVfUEFSVElBTF9JTkZPUk1BVElPTiwgRGF0YSk7CgogICAgaWYgKCEoaGtleSA9IGNyZWF0ZV9yZWdpc3RyeV9rZXkoKSkpIHJldHVybiAtMTsKCiAgICBSdGxJbml0VW5pY29kZVN0cmluZyggJm5hbWVXLCB2YWx1ZSApOwogICAgc2l6ZSA9IGluZm9fc2l6ZSArIGxlbiAqIHNpemVvZihXQ0hBUik7CgogICAgaWYgKCEoaW5mbyA9IEhlYXBBbGxvYyggR2V0UHJvY2Vzc0hlYXAoKSwgMCwgc2l6ZSApKSkKICAgIHsKICAgICAgICBOdENsb3NlKCBoa2V5ICk7CiAgICAgICAgU2V0TGFzdEVycm9yKCBFUlJPUl9OT1RfRU5PVUdIX01FTU9SWSApOwogICAgICAgIHJldHVybiAwOwogICAgfQoKICAgIHN0YXR1cyA9IE50UXVlcnlWYWx1ZUtleSggaGtleSwgJm5hbWVXLCBLZXlWYWx1ZVBhcnRpYWxJbmZvcm1hdGlvbiwgaW5mbywgc2l6ZSwgJnNpemUgKTsKICAgIGlmIChzdGF0dXMgPT0gU1RBVFVTX0JVRkZFUl9PVkVSRkxPVyAmJiAhYnVmZmVyKSBzdGF0dXMgPSAwOwoKICAgIGlmICghc3RhdHVzKQogICAgewogICAgICAgIHJldCA9IChzaXplIC0gaW5mb19zaXplKSAvIHNpemVvZihXQ0hBUik7CiAgICAgICAgLyogYXBwZW5kIHRlcm1pbmF0aW5nIG51bGwgaWYgbmVlZGVkICovCiAgICAgICAgaWYgKCFyZXQgfHwgKChXQ0hBUiAqKWluZm8tPkRhdGEpW3JldC0xXSkKICAgICAgICB7CiAgICAgICAgICAgIGlmIChyZXQgPCBsZW4gfHwgIWJ1ZmZlcikgcmV0Kys7CiAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgU2V0TGFzdEVycm9yKCBFUlJPUl9JTlNVRkZJQ0lFTlRfQlVGRkVSICk7CiAgICAgICAgICAgICAgICByZXQgPSAwOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIGlmIChyZXQgJiYgYnVmZmVyKQogICAgICAgIHsKICAgICAgICAgICAgbWVtY3B5KCBidWZmZXIsIGluZm8tPkRhdGEsIChyZXQtMSkgKiBzaXplb2YoV0NIQVIpICk7CiAgICAgICAgICAgIGJ1ZmZlcltyZXQtMV0gPSAwOwogICAgICAgIH0KICAgIH0KICAgIGVsc2UKICAgIHsKICAgICAgICBpZiAoc3RhdHVzID09IFNUQVRVU19PQkpFQ1RfTkFNRV9OT1RfRk9VTkQpIHJldCA9IC0xOwogICAgICAgIGVsc2UKICAgICAgICB7CiAgICAgICAgICAgIFNldExhc3RFcnJvciggUnRsTnRTdGF0dXNUb0Rvc0Vycm9yKHN0YXR1cykgKTsKICAgICAgICAgICAgcmV0ID0gMDsKICAgICAgICB9CiAgICB9CiAgICBOdENsb3NlKCBoa2V5ICk7CiAgICBIZWFwRnJlZSggR2V0UHJvY2Vzc0hlYXAoKSwgMCwgaW5mbyApOwogICAgcmV0dXJuIHJldDsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCUdldExvY2FsZUluZm9BIChLRVJORUwzMi5AKQogKgogKiBHZXQgaW5mb3JtYXRpb24gYWJvdXQgYW4gYXNwZWN0IG9mIGEgbG9jYWxlLgogKgogKiBQQVJBTVMKICogIGxjaWQgICBbSV0gTENJRCBvZiB0aGUgbG9jYWxlCiAqICBsY3R5cGUgW0ldIExDVFlQRV8gZmxhZ3MgZnJvbSAid2lubmxzLmgiCiAqICBidWZmZXIgW09dIERlc3RpbmF0aW9uIGZvciB0aGUgaW5mb3JtYXRpb24KICogIGxlbiAgICBbSV0gTGVuZ3RoIG9mIGJ1ZmZlciBpbiBjaGFyYWN0ZXJzCiAqCiAqIFJFVFVSTlMKICogIFN1Y2Nlc3M6IFRoZSBzaXplIG9mIHRoZSBkYXRhIHJlcXVlc3RlZC4gSWYgYnVmZmVyIGlzIG5vbi1OVUxMLCBpdCBpcyBmaWxsZWQKICogICAgICAgICAgIHdpdGggdGhlIGluZm9ybWF0aW9uLgogKiAgRmFpbHVyZTogMC4gVXNlIEdldExhc3RFcnJvcigpIHRvIGRldGVybWluZSB0aGUgY2F1c2UuCiAqCiAqIE5PVEVTCiAqICAtIExPQ0FMRV9ORVVUUkFMIGlzIGVxdWFsIHRvIExPQ0FMRV9TWVNURU1fREVGQVVMVAogKiAgLSBUaGUgc3RyaW5nIHJldHVybmVkIGlzIE5VTCB0ZXJtaW5hdGVkLCBleGNlcHQgZm9yIExPQ0FMRV9GT05UU0lHTkFUVVJFLAogKiAgICB3aGljaCBpcyBhIGJpdCBzdHJpbmcuCiAqLwpJTlQgV0lOQVBJIEdldExvY2FsZUluZm9BKCBMQ0lEIGxjaWQsIExDVFlQRSBsY3R5cGUsIExQU1RSIGJ1ZmZlciwgSU5UIGxlbiApCnsKICAgIFdDSEFSICpidWZmZXJXOwogICAgSU5UIGxlblcsIHJldDsKCiAgICBUUkFDRSggIihsY2lkPTB4JWx4LGxjdHlwZT0weCVseCwlcCwlZClcbiIsIGxjaWQsIGxjdHlwZSwgYnVmZmVyLCBsZW4gKTsKCiAgICBpZiAobGVuIDwgMCB8fCAobGVuICYmICFidWZmZXIpKQogICAgewogICAgICAgIFNldExhc3RFcnJvciggRVJST1JfSU5WQUxJRF9QQVJBTUVURVIgKTsKICAgICAgICByZXR1cm4gMDsKICAgIH0KICAgIGlmICghbGVuKSBidWZmZXIgPSBOVUxMOwoKICAgIGlmICghKGxlblcgPSBHZXRMb2NhbGVJbmZvVyggbGNpZCwgbGN0eXBlLCBOVUxMLCAwICkpKSByZXR1cm4gMDsKCiAgICBpZiAoIShidWZmZXJXID0gSGVhcEFsbG9jKCBHZXRQcm9jZXNzSGVhcCgpLCAwLCBsZW5XICogc2l6ZW9mKFdDSEFSKSApKSkKICAgIHsKICAgICAgICBTZXRMYXN0RXJyb3IoIEVSUk9SX05PVF9FTk9VR0hfTUVNT1JZICk7CiAgICAgICAgcmV0dXJuIDA7CiAgICB9CiAgICBpZiAoKHJldCA9IEdldExvY2FsZUluZm9XKCBsY2lkLCBsY3R5cGUsIGJ1ZmZlclcsIGxlblcgKSkpCiAgICB7CiAgICAgICAgaWYgKChsY3R5cGUgJiBMT0NBTEVfUkVUVVJOX05VTUJFUikgfHwKICAgICAgICAgICAgKChsY3R5cGUgJiB+TE9DQUxFX0xPQ0FMRUlORk9GTEFHU01BU0spID09IExPQ0FMRV9GT05UU0lHTkFUVVJFKSkKICAgICAgICB7CiAgICAgICAgICAgIC8qIGl0J3Mgbm90IGFuIEFTQ0lJIHN0cmluZywganVzdCBieXRlcyAqLwogICAgICAgICAgICByZXQgKj0gc2l6ZW9mKFdDSEFSKTsKICAgICAgICAgICAgaWYgKGJ1ZmZlcikKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgaWYgKHJldCA8PSBsZW4pIG1lbWNweSggYnVmZmVyLCBidWZmZXJXLCByZXQgKTsKICAgICAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBTZXRMYXN0RXJyb3IoIEVSUk9SX0lOU1VGRklDSUVOVF9CVUZGRVIgKTsKICAgICAgICAgICAgICAgICAgICByZXQgPSAwOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIGVsc2UKICAgICAgICB7CiAgICAgICAgICAgIFVJTlQgY29kZXBhZ2UgPSBDUF9BQ1A7CiAgICAgICAgICAgIGlmICghKGxjdHlwZSAmIExPQ0FMRV9VU0VfQ1BfQUNQKSkgY29kZXBhZ2UgPSBnZXRfbGNpZF9jb2RlcGFnZSggbGNpZCApOwogICAgICAgICAgICByZXQgPSBXaWRlQ2hhclRvTXVsdGlCeXRlKCBjb2RlcGFnZSwgMCwgYnVmZmVyVywgcmV0LCBidWZmZXIsIGxlbiwgTlVMTCwgTlVMTCApOwogICAgICAgIH0KICAgIH0KICAgIEhlYXBGcmVlKCBHZXRQcm9jZXNzSGVhcCgpLCAwLCBidWZmZXJXICk7CiAgICByZXR1cm4gcmV0Owp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJR2V0TG9jYWxlSW5mb1cgKEtFUk5FTDMyLkApCiAqCiAqIFNlZSBHZXRMb2NhbGVJbmZvQS4KICovCklOVCBXSU5BUEkgR2V0TG9jYWxlSW5mb1coIExDSUQgbGNpZCwgTENUWVBFIGxjdHlwZSwgTFBXU1RSIGJ1ZmZlciwgSU5UIGxlbiApCnsKICAgIExBTkdJRCBsYW5nX2lkOwogICAgSFJTUkMgaHJzcmM7CiAgICBIR0xPQkFMIGhtZW07CiAgICBJTlQgcmV0OwogICAgVUlOVCBsY2ZsYWdzOwogICAgY29uc3QgV0NIQVIgKnA7CiAgICB1bnNpZ25lZCBpbnQgaTsKCiAgICBpZiAobGVuIDwgMCB8fCAobGVuICYmICFidWZmZXIpKQogICAgewogICAgICAgIFNldExhc3RFcnJvciggRVJST1JfSU5WQUxJRF9QQVJBTUVURVIgKTsKICAgICAgICByZXR1cm4gMDsKICAgIH0KICAgIGlmICghbGVuKSBidWZmZXIgPSBOVUxMOwoKICAgIGxjaWQgPSBDb252ZXJ0RGVmYXVsdExvY2FsZShsY2lkKTsKCiAgICBsY2ZsYWdzID0gbGN0eXBlICYgTE9DQUxFX0xPQ0FMRUlORk9GTEFHU01BU0s7CiAgICBsY3R5cGUgJj0gMHhmZmZmOwoKICAgIFRSQUNFKCAiKGxjaWQ9MHglbHgsbGN0eXBlPTB4JWx4LCVwLCVkKVxuIiwgbGNpZCwgbGN0eXBlLCBidWZmZXIsIGxlbiApOwoKICAgIC8qIGZpcnN0IGNoZWNrIGZvciBvdmVycmlkZXMgaW4gdGhlIHJlZ2lzdHJ5ICovCgogICAgaWYgKCEobGNmbGFncyAmIExPQ0FMRV9OT1VTRVJPVkVSUklERSkgJiYgbGNpZCA9PSBHZXRVc2VyRGVmYXVsdExDSUQoKSkKICAgIHsKICAgICAgICBjb25zdCBXQ0hBUiAqdmFsdWUgPSBnZXRfbG9jYWxlX3ZhbHVlX25hbWUobGN0eXBlKTsKCiAgICAgICAgaWYgKHZhbHVlKQogICAgICAgIHsKICAgICAgICAgICAgaWYgKGxjZmxhZ3MgJiBMT0NBTEVfUkVUVVJOX05VTUJFUikKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgV0NIQVIgdG1wWzE2XTsKICAgICAgICAgICAgICAgIHJldCA9IGdldF9yZWdpc3RyeV9sb2NhbGVfaW5mbyggdmFsdWUsIHRtcCwgc2l6ZW9mKHRtcCkvc2l6ZW9mKFdDSEFSKSApOwogICAgICAgICAgICAgICAgaWYgKHJldCA+IDApCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgV0NIQVIgKmVuZDsKICAgICAgICAgICAgICAgICAgICBVSU5UIG51bWJlciA9IHN0cnRvbFcoIHRtcCwgJmVuZCwgMTAgKTsKICAgICAgICAgICAgICAgICAgICBpZiAoKmVuZCkgIC8qIGludmFsaWQgbnVtYmVyICovCiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICBTZXRMYXN0RXJyb3IoIEVSUk9SX0lOVkFMSURfRkxBR1MgKTsKICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIDA7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIHJldCA9IHNpemVvZihVSU5UKS9zaXplb2YoV0NIQVIpOwogICAgICAgICAgICAgICAgICAgIGlmICghYnVmZmVyKSByZXR1cm4gcmV0OwogICAgICAgICAgICAgICAgICAgIGlmIChyZXQgPiBsZW4pCiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICBTZXRMYXN0RXJyb3IoIEVSUk9SX0lOU1VGRklDSUVOVF9CVUZGRVIgKTsKICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIDA7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIG1lbWNweSggYnVmZmVyLCAmbnVtYmVyLCBzaXplb2YobnVtYmVyKSApOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIGVsc2UgcmV0ID0gZ2V0X3JlZ2lzdHJ5X2xvY2FsZV9pbmZvKCB2YWx1ZSwgYnVmZmVyLCBsZW4gKTsKCiAgICAgICAgICAgIGlmIChyZXQgIT0gLTEpIHJldHVybiByZXQ7CiAgICAgICAgfQogICAgfQoKICAgIC8qIG5vdyBsb2FkIGl0IGZyb20ga2VybmVsIHJlc291cmNlcyAqLwoKICAgIGxhbmdfaWQgPSBMQU5HSURGUk9NTENJRCggbGNpZCApOwoKICAgIC8qIHJlcGxhY2UgU1VCTEFOR19ORVVUUkFMIGJ5IFNVQkxBTkdfREVGQVVMVCAqLwogICAgaWYgKFNVQkxBTkdJRChsYW5nX2lkKSA9PSBTVUJMQU5HX05FVVRSQUwpCiAgICAgICAgbGFuZ19pZCA9IE1BS0VMQU5HSUQoUFJJTUFSWUxBTkdJRChsYW5nX2lkKSwgU1VCTEFOR19ERUZBVUxUKTsKCiAgICBpZiAoIShocnNyYyA9IEZpbmRSZXNvdXJjZUV4Vygga2VybmVsMzJfaGFuZGxlLCAoTFBXU1RSKVJUX1NUUklORywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoTFBDV1NUUikoKGxjdHlwZSA+PiA0KSArIDEpLCBsYW5nX2lkICkpKQogICAgewogICAgICAgIFNldExhc3RFcnJvciggRVJST1JfSU5WQUxJRF9GTEFHUyApOyAgLyogbm8gc3VjaCBsY3R5cGUgKi8KICAgICAgICByZXR1cm4gMDsKICAgIH0KICAgIGlmICghKGhtZW0gPSBMb2FkUmVzb3VyY2UoIGtlcm5lbDMyX2hhbmRsZSwgaHJzcmMgKSkpCiAgICAgICAgcmV0dXJuIDA7CgogICAgcCA9IExvY2tSZXNvdXJjZSggaG1lbSApOwogICAgZm9yIChpID0gMDsgaSA8IChsY3R5cGUgJiAweDBmKTsgaSsrKSBwICs9ICpwICsgMTsKCiAgICBpZiAobGNmbGFncyAmIExPQ0FMRV9SRVRVUk5fTlVNQkVSKSByZXQgPSBzaXplb2YoVUlOVCkvc2l6ZW9mKFdDSEFSKTsKICAgIGVsc2UgcmV0ID0gKGxjdHlwZSA9PSBMT0NBTEVfRk9OVFNJR05BVFVSRSkgPyAqcCA6ICpwICsgMTsKCiAgICBpZiAoIWJ1ZmZlcikgcmV0dXJuIHJldDsKCiAgICBpZiAocmV0ID4gbGVuKQogICAgewogICAgICAgIFNldExhc3RFcnJvciggRVJST1JfSU5TVUZGSUNJRU5UX0JVRkZFUiApOwogICAgICAgIHJldHVybiAwOwogICAgfQoKICAgIGlmIChsY2ZsYWdzICYgTE9DQUxFX1JFVFVSTl9OVU1CRVIpCiAgICB7CiAgICAgICAgVUlOVCBudW1iZXI7CiAgICAgICAgV0NIQVIgKmVuZCwgKnRtcCA9IEhlYXBBbGxvYyggR2V0UHJvY2Vzc0hlYXAoKSwgMCwgKCpwICsgMSkgKiBzaXplb2YoV0NIQVIpICk7CiAgICAgICAgaWYgKCF0bXApIHJldHVybiAwOwogICAgICAgIG1lbWNweSggdG1wLCBwICsgMSwgKnAgKiBzaXplb2YoV0NIQVIpICk7CiAgICAgICAgdG1wWypwXSA9IDA7CiAgICAgICAgbnVtYmVyID0gc3RydG9sVyggdG1wLCAmZW5kLCAxMCApOwogICAgICAgIGlmICghKmVuZCkKICAgICAgICAgICAgbWVtY3B5KCBidWZmZXIsICZudW1iZXIsIHNpemVvZihudW1iZXIpICk7CiAgICAgICAgZWxzZSAgLyogaW52YWxpZCBudW1iZXIgKi8KICAgICAgICB7CiAgICAgICAgICAgIFNldExhc3RFcnJvciggRVJST1JfSU5WQUxJRF9GTEFHUyApOwogICAgICAgICAgICByZXQgPSAwOwogICAgICAgIH0KICAgICAgICBIZWFwRnJlZSggR2V0UHJvY2Vzc0hlYXAoKSwgMCwgdG1wICk7CgogICAgICAgIFRSQUNFKCAiKGxjaWQ9MHglbHgsbGN0eXBlPTB4JWx4LCVwLCVkKSByZXR1cm5pbmcgbnVtYmVyICVkXG4iLAogICAgICAgICAgICAgICBsY2lkLCBsY3R5cGUsIGJ1ZmZlciwgbGVuLCBudW1iZXIgKTsKICAgIH0KICAgIGVsc2UKICAgIHsKICAgICAgICBtZW1jcHkoIGJ1ZmZlciwgcCArIDEsICpwICogc2l6ZW9mKFdDSEFSKSApOwogICAgICAgIGlmIChsY3R5cGUgIT0gTE9DQUxFX0ZPTlRTSUdOQVRVUkUpIGJ1ZmZlcltyZXQtMV0gPSAwOwoKICAgICAgICBUUkFDRSggIihsY2lkPTB4JWx4LGxjdHlwZT0weCVseCwlcCwlZCkgcmV0dXJuaW5nICVkICVzXG4iLAogICAgICAgICAgICAgICBsY2lkLCBsY3R5cGUsIGJ1ZmZlciwgbGVuLCByZXQsIGRlYnVnc3RyX3coYnVmZmVyKSApOwogICAgfQogICAgcmV0dXJuIHJldDsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCVNldExvY2FsZUluZm9BCVtLRVJORUwzMi5AXQogKgogKiBTZXQgaW5mb3JtYXRpb24gYWJvdXQgYW4gYXNwZWN0IG9mIGEgbG9jYWxlLgogKgogKiBQQVJBTVMKICogIGxjaWQgICBbSV0gTENJRCBvZiB0aGUgbG9jYWxlCiAqICBsY3R5cGUgW0ldIExDVFlQRV8gZmxhZ3MgZnJvbSAid2lubmxzLmgiCiAqICBkYXRhICAgW0ldIEluZm9ybWF0aW9uIHRvIHNldAogKgogKiBSRVRVUk5TCiAqICBTdWNjZXNzOiBUUlVFLiBUaGUgaW5mb3JtYXRpb24gZ2l2ZW4gd2lsbCBiZSByZXR1cm5lZCBieSBHZXRMb2NhbGVJbmZvQSgpCiAqICAgICAgICAgICB3aGVuZXZlciBpdCBpcyBjYWxsZWQgd2l0aG91dCBMT0NBTEVfTk9VU0VST1ZFUlJJREUuCiAqICBGYWlsdXJlOiBGQUxTRS4gVXNlIEdldExhc3RFcnJvcigpIHRvIGRldGVybWluZSB0aGUgY2F1c2UuCiAqCiAqIE5PVEVTCiAqICAtIFZhbHVlcyBhcmUgb25seSBiZSBzZXQgZm9yIHRoZSBjdXJyZW50IHVzZXIgbG9jYWxlOyB0aGUgc3lzdGVtIGxvY2FsZQogKiAgc2V0dGluZ3MgY2Fubm90IGJlIGNoYW5nZWQuCiAqICAtIEFueSBzZXR0aW5ncyBjaGFuZ2VkIGJ5IHRoaXMgY2FsbCBhcmUgbG9zdCB3aGVuIHRoZSBsb2NhbGUgaXMgY2hhbmdlZCBieQogKiAgdGhlIGNvbnRyb2wgcGFuZWwgKGluIFdpbmUsIHRoaXMgaGFwcGVucyBldmVyeSB0aW1lIHlvdSBjaGFuZ2UgTEFORykuCiAqICAtIFRoZSBuYXRpdmUgaW1wbGVtZW50YXRpb24gb2YgdGhpcyBmdW5jdGlvbiBkb2VzIG5vdCBjaGVjayB0aGF0IGxjaWQgbWF0Y2hlcwogKiAgdGhlIGN1cnJlbnQgdXNlciBsb2NhbGUsIGFuZCBzaW1wbHkgc2V0cyB0aGUgbmV3IHZhbHVlcy4gV2luZSB3YXJucyB5b3UgaW4KICogIHRoaXMgY2FzZSwgYnV0IGJlaGF2ZXMgdGhlIHNhbWUuCiAqLwpCT09MIFdJTkFQSSBTZXRMb2NhbGVJbmZvQShMQ0lEIGxjaWQsIExDVFlQRSBsY3R5cGUsIExQQ1NUUiBkYXRhKQp7CiAgICBVSU5UIGNvZGVwYWdlID0gQ1BfQUNQOwogICAgV0NIQVIgKnN0clc7CiAgICBEV09SRCBsZW47CiAgICBCT09MIHJldDsKCiAgICBsY2lkID0gQ29udmVydERlZmF1bHRMb2NhbGUobGNpZCk7CgogICAgaWYgKCEobGN0eXBlICYgTE9DQUxFX1VTRV9DUF9BQ1ApKSBjb2RlcGFnZSA9IGdldF9sY2lkX2NvZGVwYWdlKCBsY2lkICk7CgogICAgaWYgKCFkYXRhKQogICAgewogICAgICAgIFNldExhc3RFcnJvciggRVJST1JfSU5WQUxJRF9QQVJBTUVURVIgKTsKICAgICAgICByZXR1cm4gRkFMU0U7CiAgICB9CiAgICBsZW4gPSBNdWx0aUJ5dGVUb1dpZGVDaGFyKCBjb2RlcGFnZSwgMCwgZGF0YSwgLTEsIE5VTEwsIDAgKTsKICAgIGlmICghKHN0clcgPSBIZWFwQWxsb2MoIEdldFByb2Nlc3NIZWFwKCksIDAsIGxlbiAqIHNpemVvZihXQ0hBUikgKSkpCiAgICB7CiAgICAgICAgU2V0TGFzdEVycm9yKCBFUlJPUl9OT1RfRU5PVUdIX01FTU9SWSApOwogICAgICAgIHJldHVybiBGQUxTRTsKICAgIH0KICAgIE11bHRpQnl0ZVRvV2lkZUNoYXIoIGNvZGVwYWdlLCAwLCBkYXRhLCAtMSwgc3RyVywgbGVuICk7CiAgICByZXQgPSBTZXRMb2NhbGVJbmZvVyggbGNpZCwgbGN0eXBlLCBzdHJXICk7CiAgICBIZWFwRnJlZSggR2V0UHJvY2Vzc0hlYXAoKSwgMCwgc3RyVyApOwogICAgcmV0dXJuIHJldDsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCVNldExvY2FsZUluZm9XCShLRVJORUwzMi5AKQogKgogKiBTZWUgU2V0TG9jYWxlSW5mb0EuCiAqLwpCT09MIFdJTkFQSSBTZXRMb2NhbGVJbmZvVyggTENJRCBsY2lkLCBMQ1RZUEUgbGN0eXBlLCBMUENXU1RSIGRhdGEgKQp7CiAgICBjb25zdCBXQ0hBUiAqdmFsdWU7CiAgICBzdGF0aWMgY29uc3QgV0NIQVIgaW50bFdbXSA9IHsnaScsJ24nLCd0JywnbCcsMCB9OwogICAgVU5JQ09ERV9TVFJJTkcgdmFsdWVXOwogICAgTlRTVEFUVVMgc3RhdHVzOwogICAgSEFORExFIGhrZXk7CgogICAgbGNpZCA9IENvbnZlcnREZWZhdWx0TG9jYWxlKGxjaWQpOwoKICAgIGxjdHlwZSAmPSAweGZmZmY7CiAgICB2YWx1ZSA9IGdldF9sb2NhbGVfdmFsdWVfbmFtZSggbGN0eXBlICk7CgogICAgaWYgKCFkYXRhIHx8ICF2YWx1ZSkKICAgIHsKICAgICAgICBTZXRMYXN0RXJyb3IoIEVSUk9SX0lOVkFMSURfUEFSQU1FVEVSICk7CiAgICAgICAgcmV0dXJuIEZBTFNFOwogICAgfQoKICAgIGlmIChsY3R5cGUgPT0gTE9DQUxFX0lEQVRFIHx8IGxjdHlwZSA9PSBMT0NBTEVfSUxEQVRFKQogICAgewogICAgICAgIFNldExhc3RFcnJvciggRVJST1JfSU5WQUxJRF9GTEFHUyApOwogICAgICAgIHJldHVybiBGQUxTRTsKICAgIH0KCiAgICBpZiAobGNpZCAhPSBHZXRVc2VyRGVmYXVsdExDSUQoKSkKICAgIHsKICAgICAgICAvKiBXaW5kb3dzIGRvZXMgbm90IGNoZWNrIHRoYXQgdGhlIGxjaWQgbWF0Y2hlcyB0aGUgY3VycmVudCBsY2lkICovCiAgICAgICAgV0FSTigibG9jYWxlIDB4JTA4bHggaXNuJ3QgdGhlIGN1cnJlbnQgbG9jYWxlICgweCUwOGx4KSwgc2V0dGluZyBhbnl3YXkhXG4iLAogICAgICAgICAgICAgbGNpZCwgR2V0VXNlckRlZmF1bHRMQ0lEKCkpOwogICAgfQoKICAgIFRSQUNFKCJzZXR0aW5nICVseCAoJXMpIHRvICVzXG4iLCBsY3R5cGUsIGRlYnVnc3RyX3codmFsdWUpLCBkZWJ1Z3N0cl93KGRhdGEpICk7CgogICAgLyogRklYTUU6IHNob3VsZCBjaGVjayB0aGF0IGRhdGEgdG8gc2V0IGlzIHNhbmUgKi8KCiAgICAvKiBGSVhNRTogcHJvZmlsZSBmdW5jdGlvbnMgc2hvdWxkIG1hcCB0byByZWdpc3RyeSAqLwogICAgV3JpdGVQcm9maWxlU3RyaW5nVyggaW50bFcsIHZhbHVlLCBkYXRhICk7CgogICAgaWYgKCEoaGtleSA9IGNyZWF0ZV9yZWdpc3RyeV9rZXkoKSkpIHJldHVybiBGQUxTRTsKICAgIFJ0bEluaXRVbmljb2RlU3RyaW5nKCAmdmFsdWVXLCB2YWx1ZSApOwogICAgc3RhdHVzID0gTnRTZXRWYWx1ZUtleSggaGtleSwgJnZhbHVlVywgMCwgUkVHX1NaLCBkYXRhLCAoc3RybGVuVyhkYXRhKSsxKSpzaXplb2YoV0NIQVIpICk7CgogICAgaWYgKGxjdHlwZSA9PSBMT0NBTEVfU1NIT1JUREFURSB8fCBsY3R5cGUgPT0gTE9DQUxFX1NMT05HREFURSkKICAgIHsKICAgICAgLyogU2V0IEktdmFsdWUgZnJvbSBTIHZhbHVlICovCiAgICAgIFdDSEFSICpscEQsICpscE0sICpscFk7CiAgICAgIFdDSEFSIHN6QnVmZlsyXTsKCiAgICAgIGxwRCA9IHN0cnJjaHJXKGRhdGEsICdkJyk7CiAgICAgIGxwTSA9IHN0cnJjaHJXKGRhdGEsICdNJyk7CiAgICAgIGxwWSA9IHN0cnJjaHJXKGRhdGEsICd5Jyk7CgogICAgICBpZiAobHBEIDw9IGxwTSkKICAgICAgewogICAgICAgIHN6QnVmZlswXSA9ICcxJzsgLyogRC1NLVkgKi8KICAgICAgfQogICAgICBlbHNlCiAgICAgIHsKICAgICAgICBpZiAobHBZIDw9IGxwTSkKICAgICAgICAgIHN6QnVmZlswXSA9ICcyJzsgLyogWS1NLUQgKi8KICAgICAgICBlbHNlCiAgICAgICAgICBzekJ1ZmZbMF0gPSAnMCc7IC8qIE0tRC1ZICovCiAgICAgIH0KCiAgICAgIHN6QnVmZlsxXSA9ICdcMCc7CgogICAgICBpZiAobGN0eXBlID09IExPQ0FMRV9TU0hPUlREQVRFKQogICAgICAgIGxjdHlwZSA9IExPQ0FMRV9JREFURTsKICAgICAgZWxzZQogICAgICAgIGxjdHlwZSA9IExPQ0FMRV9JTERBVEU7CgogICAgICB2YWx1ZSA9IGdldF9sb2NhbGVfdmFsdWVfbmFtZSggbGN0eXBlICk7CgogICAgICBXcml0ZVByb2ZpbGVTdHJpbmdXKCBpbnRsVywgdmFsdWUsIHN6QnVmZiApOwoKICAgICAgUnRsSW5pdFVuaWNvZGVTdHJpbmcoICZ2YWx1ZVcsIHZhbHVlICk7CiAgICAgIHN0YXR1cyA9IE50U2V0VmFsdWVLZXkoIGhrZXksICZ2YWx1ZVcsIDAsIFJFR19TWiwgc3pCdWZmLCBzaXplb2Yoc3pCdWZmKSApOwogICAgfQoKICAgIE50Q2xvc2UoIGhrZXkgKTsKCiAgICBpZiAoc3RhdHVzKSBTZXRMYXN0RXJyb3IoIFJ0bE50U3RhdHVzVG9Eb3NFcnJvcihzdGF0dXMpICk7CiAgICByZXR1cm4gIXN0YXR1czsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICAgICAgICAgIEdldEFDUCAgIChLRVJORUwzMi5AKQogKgogKiBHZXQgdGhlIGN1cnJlbnQgQW5zaSBjb2RlIHBhZ2UgSWQgZm9yIHRoZSBzeXN0ZW0uCiAqCiAqIFBBUkFNUwogKiAgTm9uZS4KICoKICogUkVUVVJOUwogKiAgICBUaGUgY3VycmVudCBBbnNpIGNvZGUgcGFnZSBpZGVudGlmaWVyIGZvciB0aGUgc3lzdGVtLgogKi8KVUlOVCBXSU5BUEkgR2V0QUNQKHZvaWQpCnsKICAgIGFzc2VydCggYW5zaV9jcHRhYmxlICk7CiAgICByZXR1cm4gYW5zaV9jcHRhYmxlLT5pbmZvLmNvZGVwYWdlOwp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgICAgICAgICAgU2V0Q1BHbG9iYWwgICAoS0VSTkVMMzIuQCkKICoKICogU2V0IHRoZSBjdXJyZW50IEFuc2kgY29kZSBwYWdlIElkIGZvciB0aGUgc3lzdGVtLgogKgogKiBQQVJBTVMKICogICAgYWNwIFtJXSBjb2RlIHBhZ2UgSUQgdG8gYmUgdGhlIG5ldyBBQ1AuCiAqCiAqIFJFVFVSTlMKICogICAgVGhlIHByZXZpb3VzIEFDUC4KICovClVJTlQgV0lOQVBJIFNldENQR2xvYmFsKCBVSU5UIGFjcCApCnsKICAgIFVJTlQgcmV0ID0gR2V0QUNQKCk7CiAgICBjb25zdCB1bmlvbiBjcHRhYmxlICpuZXdfY3B0YWJsZSA9IHdpbmVfY3BfZ2V0X3RhYmxlKCBhY3AgKTsKCiAgICBpZiAobmV3X2NwdGFibGUpIGFuc2lfY3B0YWJsZSA9IG5ld19jcHRhYmxlOwogICAgcmV0dXJuIHJldDsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgICAgICAgICAgR2V0T0VNQ1AgICAoS0VSTkVMMzIuQCkKICoKICogR2V0IHRoZSBjdXJyZW50IE9FTSBjb2RlIHBhZ2UgSWQgZm9yIHRoZSBzeXN0ZW0uCiAqCiAqIFBBUkFNUwogKiAgTm9uZS4KICoKICogUkVUVVJOUwogKiAgICBUaGUgY3VycmVudCBPRU0gY29kZSBwYWdlIGlkZW50aWZpZXIgZm9yIHRoZSBzeXN0ZW0uCiAqLwpVSU5UIFdJTkFQSSBHZXRPRU1DUCh2b2lkKQp7CiAgICBhc3NlcnQoIG9lbV9jcHRhYmxlICk7CiAgICByZXR1cm4gb2VtX2NwdGFibGUtPmluZm8uY29kZXBhZ2U7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICAgICAgIElzVmFsaWRDb2RlUGFnZSAgIChLRVJORUwzMi5AKQogKgogKiBEZXRlcm1pbmUgaWYgYSBnaXZlbiBjb2RlIHBhZ2UgaWRlbnRpZmllciBpcyB2YWxpZC4KICoKICogUEFSQU1TCiAqICBjb2RlcGFnZSBbSV0gQ29kZSBwYWdlIElkIHRvIHZlcmlmeS4KICoKICogUkVUVVJOUwogKiAgVFJVRSwgSWYgY29kZXBhZ2UgaXMgdmFsaWQgYW5kIGF2YWlsYWJsZSBvbiB0aGUgc3lzdGVtLAogKiAgRkFMU0Ugb3RoZXJ3aXNlLgogKi8KQk9PTCBXSU5BUEkgSXNWYWxpZENvZGVQYWdlKCBVSU5UIGNvZGVwYWdlICkKewogICAgc3dpdGNoKGNvZGVwYWdlKSB7CiAgICBjYXNlIENQX1VURjc6CiAgICBjYXNlIENQX1VURjg6CiAgICAgICAgcmV0dXJuIFRSVUU7CiAgICBkZWZhdWx0OgogICAgICAgIHJldHVybiB3aW5lX2NwX2dldF90YWJsZSggY29kZXBhZ2UgKSAhPSBOVUxMOwogICAgfQp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgICAgICBJc0RCQ1NMZWFkQnl0ZUV4ICAgKEtFUk5FTDMyLkApCiAqCiAqIERldGVybWluZSBpZiBhIGNoYXJhY3RlciBpcyBhIGxlYWQgYnl0ZSBpbiBhIGdpdmVuIGNvZGUgcGFnZS4KICoKICogUEFSQU1TCiAqICBjb2RlcGFnZSBbSV0gQ29kZSBwYWdlIGZvciB0aGUgdGVzdC4KICogIHRlc3RjaGFyIFtJXSBDaGFyYWN0ZXIgdG8gdGVzdAogKgogKiBSRVRVUk5TCiAqICBUUlVFLCBpZiB0ZXN0Y2hhciBpcyBhIGxlYWQgYnl0ZSBpbiBjb2RlcGFnZSwKICogIEZBTFNFIG90aGVyd2lzZS4KICovCkJPT0wgV0lOQVBJIElzREJDU0xlYWRCeXRlRXgoIFVJTlQgY29kZXBhZ2UsIEJZVEUgdGVzdGNoYXIgKQp7CiAgICBjb25zdCB1bmlvbiBjcHRhYmxlICp0YWJsZSA9IGdldF9jb2RlcGFnZV90YWJsZSggY29kZXBhZ2UgKTsKICAgIHJldHVybiB0YWJsZSAmJiBpc19kYmNzX2xlYWRieXRlKCB0YWJsZSwgdGVzdGNoYXIgKTsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgICAgICAgSXNEQkNTTGVhZEJ5dGUgICAoS0VSTkVMMzIuQCkKICogICAgICAgICAgIElzREJDU0xlYWRCeXRlICAgKEtFUk5FTC4yMDcpCiAqCiAqIERldGVybWluZSBpZiBhIGNoYXJhY3RlciBpcyBhIGxlYWQgYnl0ZS4KICoKICogUEFSQU1TCiAqICB0ZXN0Y2hhciBbSV0gQ2hhcmFjdGVyIHRvIHRlc3QKICoKICogUkVUVVJOUwogKiAgVFJVRSwgaWYgdGVzdGNoYXIgaXMgYSBsZWFkIGJ5dGUgaW4gdGhlIEFuc2lpIGNvZGUgcGFnZSwKICogIEZBTFNFIG90aGVyd2lzZS4KICovCkJPT0wgV0lOQVBJIElzREJDU0xlYWRCeXRlKCBCWVRFIHRlc3RjaGFyICkKewogICAgaWYgKCFhbnNpX2NwdGFibGUpIHJldHVybiBGQUxTRTsKICAgIHJldHVybiBpc19kYmNzX2xlYWRieXRlKCBhbnNpX2NwdGFibGUsIHRlc3RjaGFyICk7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICAgICAgIEdldENQSW5mbyAgIChLRVJORUwzMi5AKQogKgogKiBHZXQgaW5mb3JtYXRpb24gYWJvdXQgYSBjb2RlIHBhZ2UuCiAqCiAqIFBBUkFNUwogKiAgY29kZXBhZ2UgW0ldIENvZGUgcGFnZSBudW1iZXIKICogIGNwaW5mbyAgIFtPXSBEZXN0aW5hdGlvbiBmb3IgY29kZSBwYWdlIGluZm9ybWF0aW9uCiAqCiAqIFJFVFVSTlMKICogIFN1Y2Nlc3M6IFRSVUUuIGNwaW5mbyBpcyB1cGRhdGVkIHdpdGggdGhlIGluZm9ybWF0aW9uIGFib3V0IGNvZGVwYWdlLgogKiAgRmFpbHVyZTogRkFMU0UsIGlmIGNvZGVwYWdlIGlzIGludmFsaWQgb3IgY3BpbmZvIGlzIE5VTEwuCiAqLwpCT09MIFdJTkFQSSBHZXRDUEluZm8oIFVJTlQgY29kZXBhZ2UsIExQQ1BJTkZPIGNwaW5mbyApCnsKICAgIGNvbnN0IHVuaW9uIGNwdGFibGUgKnRhYmxlOwoKICAgIGlmICghY3BpbmZvKQogICAgewogICAgICAgIFNldExhc3RFcnJvciggRVJST1JfSU5WQUxJRF9QQVJBTUVURVIgKTsKICAgICAgICByZXR1cm4gRkFMU0U7CiAgICB9CgogICAgaWYgKCEodGFibGUgPSBnZXRfY29kZXBhZ2VfdGFibGUoIGNvZGVwYWdlICkpKQogICAgewogICAgICAgIHN3aXRjaChjb2RlcGFnZSkKICAgICAgICB7CiAgICAgICAgICAgIGNhc2UgQ1BfVVRGNzoKICAgICAgICAgICAgY2FzZSBDUF9VVEY4OgogICAgICAgICAgICAgICAgY3BpbmZvLT5EZWZhdWx0Q2hhclswXSA9IDB4M2Y7CiAgICAgICAgICAgICAgICBjcGluZm8tPkRlZmF1bHRDaGFyWzFdID0gMDsKICAgICAgICAgICAgICAgIGNwaW5mby0+TGVhZEJ5dGVbMF0gPSBjcGluZm8tPkxlYWRCeXRlWzFdID0gMDsKICAgICAgICAgICAgICAgIGNwaW5mby0+TWF4Q2hhclNpemUgPSAoY29kZXBhZ2UgPT0gQ1BfVVRGNykgPyA1IDogNDsKICAgICAgICAgICAgICAgIHJldHVybiBUUlVFOwogICAgICAgIH0KCiAgICAgICAgU2V0TGFzdEVycm9yKCBFUlJPUl9JTlZBTElEX1BBUkFNRVRFUiApOwogICAgICAgIHJldHVybiBGQUxTRTsKICAgIH0KICAgIGlmICh0YWJsZS0+aW5mby5kZWZfY2hhciAmIDB4ZmYwMCkKICAgIHsKICAgICAgICBjcGluZm8tPkRlZmF1bHRDaGFyWzBdID0gdGFibGUtPmluZm8uZGVmX2NoYXIgJiAweGZmMDA7CiAgICAgICAgY3BpbmZvLT5EZWZhdWx0Q2hhclsxXSA9IHRhYmxlLT5pbmZvLmRlZl9jaGFyICYgMHgwMGZmOwogICAgfQogICAgZWxzZQogICAgewogICAgICAgIGNwaW5mby0+RGVmYXVsdENoYXJbMF0gPSB0YWJsZS0+aW5mby5kZWZfY2hhciAmIDB4ZmY7CiAgICAgICAgY3BpbmZvLT5EZWZhdWx0Q2hhclsxXSA9IDA7CiAgICB9CiAgICBpZiAoKGNwaW5mby0+TWF4Q2hhclNpemUgPSB0YWJsZS0+aW5mby5jaGFyX3NpemUpID09IDIpCiAgICAgICAgbWVtY3B5KCBjcGluZm8tPkxlYWRCeXRlLCB0YWJsZS0+ZGJjcy5sZWFkX2J5dGVzLCBzaXplb2YoY3BpbmZvLT5MZWFkQnl0ZSkgKTsKICAgIGVsc2UKICAgICAgICBjcGluZm8tPkxlYWRCeXRlWzBdID0gY3BpbmZvLT5MZWFkQnl0ZVsxXSA9IDA7CgogICAgcmV0dXJuIFRSVUU7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgICAgICAgR2V0Q1BJbmZvRXhBICAgKEtFUk5FTDMyLkApCiAqCiAqIEdldCBleHRlbmRlZCBpbmZvcm1hdGlvbiBhYm91dCBhIGNvZGUgcGFnZS4KICoKICogUEFSQU1TCiAqICBjb2RlcGFnZSBbSV0gQ29kZSBwYWdlIG51bWJlcgogKiAgZHdGbGFncyAgW0ldIFJlc2VydmVkLCBtdXN0IHRvIDAuCiAqICBjcGluZm8gICBbT10gRGVzdGluYXRpb24gZm9yIGNvZGUgcGFnZSBpbmZvcm1hdGlvbgogKgogKiBSRVRVUk5TCiAqICBTdWNjZXNzOiBUUlVFLiBjcGluZm8gaXMgdXBkYXRlZCB3aXRoIHRoZSBpbmZvcm1hdGlvbiBhYm91dCBjb2RlcGFnZS4KICogIEZhaWx1cmU6IEZBTFNFLCBpZiBjb2RlcGFnZSBpcyBpbnZhbGlkIG9yIGNwaW5mbyBpcyBOVUxMLgogKi8KQk9PTCBXSU5BUEkgR2V0Q1BJbmZvRXhBKCBVSU5UIGNvZGVwYWdlLCBEV09SRCBkd0ZsYWdzLCBMUENQSU5GT0VYQSBjcGluZm8gKQp7CiAgICBDUElORk9FWFcgY3BpbmZvVzsKCiAgICBpZiAoIUdldENQSW5mb0V4VyggY29kZXBhZ2UsIGR3RmxhZ3MsICZjcGluZm9XICkpCiAgICAgIHJldHVybiBGQUxTRTsKCiAgICAvKiB0aGUgbGF5b3V0IGlzIHRoZSBzYW1lIGV4Y2VwdCBmb3IgQ29kZVBhZ2VOYW1lICovCiAgICBtZW1jcHkoY3BpbmZvLCAmY3BpbmZvVywgc2l6ZW9mKENQSU5GT0VYQSkpOwogICAgV2lkZUNoYXJUb011bHRpQnl0ZShDUF9BQ1AsIDAsIGNwaW5mb1cuQ29kZVBhZ2VOYW1lLCAtMSwgY3BpbmZvLT5Db2RlUGFnZU5hbWUsIHNpemVvZihjcGluZm8tPkNvZGVQYWdlTmFtZSksIE5VTEwsIE5VTEwpOwogICAgcmV0dXJuIFRSVUU7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgICAgICAgR2V0Q1BJbmZvRXhXICAgKEtFUk5FTDMyLkApCiAqCiAqIFVuaWNvZGUgdmVyc2lvbiBvZiBHZXRDUEluZm9FeEEuCiAqLwpCT09MIFdJTkFQSSBHZXRDUEluZm9FeFcoIFVJTlQgY29kZXBhZ2UsIERXT1JEIGR3RmxhZ3MsIExQQ1BJTkZPRVhXIGNwaW5mbyApCnsKICAgIGlmICghR2V0Q1BJbmZvKCBjb2RlcGFnZSwgKExQQ1BJTkZPKWNwaW5mbyApKQogICAgICByZXR1cm4gRkFMU0U7CgogICAgc3dpdGNoKGNvZGVwYWdlKQogICAgewogICAgICAgIGNhc2UgQ1BfVVRGNzoKICAgICAgICB7CiAgICAgICAgICAgIHN0YXRpYyBjb25zdCBXQ0hBUiB1dGY3W10gPSB7J1UnLCduJywnaScsJ2MnLCdvJywnZCcsJ2UnLCcgJywnKCcsJ1UnLCdUJywnRicsJy0nLCc3JywnKScsMH07CgogICAgICAgICAgICBjcGluZm8tPkNvZGVQYWdlID0gQ1BfVVRGNzsKICAgICAgICAgICAgY3BpbmZvLT5Vbmljb2RlRGVmYXVsdENoYXIgPSAweDNmOwogICAgICAgICAgICBzdHJjcHlXKGNwaW5mby0+Q29kZVBhZ2VOYW1lLCB1dGY3KTsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgfQoKICAgICAgICBjYXNlIENQX1VURjg6CiAgICAgICAgewogICAgICAgICAgICBzdGF0aWMgY29uc3QgV0NIQVIgdXRmOFtdID0geydVJywnbicsJ2knLCdjJywnbycsJ2QnLCdlJywnICcsJygnLCdVJywnVCcsJ0YnLCctJywnOCcsJyknLDB9OwoKICAgICAgICAgICAgY3BpbmZvLT5Db2RlUGFnZSA9IENQX1VURjg7CiAgICAgICAgICAgIGNwaW5mby0+VW5pY29kZURlZmF1bHRDaGFyID0gMHgzZjsKICAgICAgICAgICAgc3RyY3B5VyhjcGluZm8tPkNvZGVQYWdlTmFtZSwgdXRmOCk7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIH0KCiAgICAgICAgZGVmYXVsdDoKICAgICAgICB7CiAgICAgICAgICAgIGNvbnN0IHVuaW9uIGNwdGFibGUgKnRhYmxlID0gZ2V0X2NvZGVwYWdlX3RhYmxlKCBjb2RlcGFnZSApOwoKICAgICAgICAgICAgY3BpbmZvLT5Db2RlUGFnZSA9IHRhYmxlLT5pbmZvLmNvZGVwYWdlOwogICAgICAgICAgICBjcGluZm8tPlVuaWNvZGVEZWZhdWx0Q2hhciA9IHRhYmxlLT5pbmZvLmRlZl91bmljb2RlX2NoYXI7CiAgICAgICAgICAgIE11bHRpQnl0ZVRvV2lkZUNoYXIoIENQX0FDUCwgMCwgdGFibGUtPmluZm8ubmFtZSwgLTEsIGNwaW5mby0+Q29kZVBhZ2VOYW1lLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzaXplb2YoY3BpbmZvLT5Db2RlUGFnZU5hbWUpL3NpemVvZihXQ0hBUikpOwogICAgICAgICAgICBicmVhazsKICAgICAgICB9CiAgICB9CiAgICByZXR1cm4gVFJVRTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgICAgICAgICBFbnVtU3lzdGVtQ29kZVBhZ2VzQSAgIChLRVJORUwzMi5AKQogKgogKiBDYWxsIGEgdXNlciBkZWZpbmVkIGZ1bmN0aW9uIGZvciBldmVyeSBjb2RlIHBhZ2UgaW5zdGFsbGVkIG9uIHRoZSBzeXN0ZW0uCiAqCiAqIFBBUkFNUwogKiAgIGxwZm5Db2RlUGFnZUVudW0gW0ldIFVzZXIgQ09ERVBBR0VfRU5VTVBST0MgdG8gY2FsbCB3aXRoIGVhY2ggZm91bmQgY29kZSBwYWdlCiAqICAgZmxhZ3MgICAgICAgICAgICBbSV0gUmVzZXJ2ZWQsIHNldCB0byAwLgogKgogKiBSRVRVUk5TCiAqICBUUlVFLCBJZiBhbGwgY29kZSBwYWdlcyBoYXZlIGJlZW4gZW51bWVyYXRlZCwgb3IKICogIEZBTFNFIGlmIGxwZm5Db2RlUGFnZUVudW0gcmV0dXJuZWQgRkFMU0UgdG8gc3RvcCB0aGUgZW51bWVyYXRpb24uCiAqLwpCT09MIFdJTkFQSSBFbnVtU3lzdGVtQ29kZVBhZ2VzQSggQ09ERVBBR0VfRU5VTVBST0NBIGxwZm5Db2RlUGFnZUVudW0sIERXT1JEIGZsYWdzICkKewogICAgY29uc3QgdW5pb24gY3B0YWJsZSAqdGFibGU7CiAgICBjaGFyIGJ1ZmZlclsxMF07CiAgICBpbnQgaW5kZXggPSAwOwoKICAgIGZvciAoOzspCiAgICB7CiAgICAgICAgaWYgKCEodGFibGUgPSB3aW5lX2NwX2VudW1fdGFibGUoIGluZGV4KysgKSkpIGJyZWFrOwogICAgICAgIHNwcmludGYoIGJ1ZmZlciwgIiVkIiwgdGFibGUtPmluZm8uY29kZXBhZ2UgKTsKICAgICAgICBpZiAoIWxwZm5Db2RlUGFnZUVudW0oIGJ1ZmZlciApKSBicmVhazsKICAgIH0KICAgIHJldHVybiBUUlVFOwp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgICAgICAgICBFbnVtU3lzdGVtQ29kZVBhZ2VzVyAgIChLRVJORUwzMi5AKQogKgogKiBTZWUgRW51bVN5c3RlbUNvZGVQYWdlc0EuCiAqLwpCT09MIFdJTkFQSSBFbnVtU3lzdGVtQ29kZVBhZ2VzVyggQ09ERVBBR0VfRU5VTVBST0NXIGxwZm5Db2RlUGFnZUVudW0sIERXT1JEIGZsYWdzICkKewogICAgY29uc3QgdW5pb24gY3B0YWJsZSAqdGFibGU7CiAgICBXQ0hBUiBidWZmZXJbMTBdLCAqcDsKICAgIGludCBwYWdlLCBpbmRleCA9IDA7CgogICAgZm9yICg7OykKICAgIHsKICAgICAgICBpZiAoISh0YWJsZSA9IHdpbmVfY3BfZW51bV90YWJsZSggaW5kZXgrKyApKSkgYnJlYWs7CiAgICAgICAgcCA9IGJ1ZmZlciArIHNpemVvZihidWZmZXIpL3NpemVvZihXQ0hBUik7CiAgICAgICAgKi0tcCA9IDA7CiAgICAgICAgcGFnZSA9IHRhYmxlLT5pbmZvLmNvZGVwYWdlOwogICAgICAgIGRvCiAgICAgICAgewogICAgICAgICAgICAqLS1wID0gJzAnICsgKHBhZ2UgJSAxMCk7CiAgICAgICAgICAgIHBhZ2UgLz0gMTA7CiAgICAgICAgfSB3aGlsZSggcGFnZSApOwogICAgICAgIGlmICghbHBmbkNvZGVQYWdlRW51bSggcCApKSBicmVhazsKICAgIH0KICAgIHJldHVybiBUUlVFOwp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgICAgICAgICBNdWx0aUJ5dGVUb1dpZGVDaGFyICAgKEtFUk5FTDMyLkApCiAqCiAqIENvbnZlcnQgYSBtdWx0aWJ5dGUgY2hhcmFjdGVyIHN0cmluZyBpbnRvIGEgVW5pY29kZSBzdHJpbmcuCiAqCiAqIFBBUkFNUwogKiAgIHBhZ2UgICBbSV0gQ29kZXBhZ2UgY2hhcmFjdGVyIHNldCB0byBjb252ZXJ0IGZyb20KICogICBmbGFncyAgW0ldIENoYXJhY3RlciBtYXBwaW5nIGZsYWdzCiAqICAgc3JjICAgIFtJXSBTb3VyY2Ugc3RyaW5nIGJ1ZmZlcgogKiAgIHNyY2xlbiBbSV0gTGVuZ3RoIG9mIHNyYywgb3IgLTEgaWYgc3JjIGlzIE5VTCB0ZXJtaW5hdGVkCiAqICAgZHN0ICAgIFtPXSBEZXN0aW5hdGlvbiBidWZmZXIKICogICBkc3RsZW4gW0ldIExlbmd0aCBvZiBkc3QsIG9yIDAgdG8gY29tcHV0ZSB0aGUgcmVxdWlyZWQgbGVuZ3RoCiAqCiAqIFJFVFVSTlMKICogICBTdWNjZXNzOiBJZiBkc3RsZW4gPiAwLCB0aGUgbnVtYmVyIG9mIGNoYXJhY3RlcnMgd3JpdHRlbiB0byBkc3QuCiAqICAgICAgICAgICAgSWYgZHN0bGVuID09IDAsIHRoZSBudW1iZXIgb2YgY2hhcmFjdGVycyBuZWVkZWQgdG8gcGVyZm9ybSB0aGUKICogICAgICAgICAgICBjb252ZXJzaW9uLiBJbiBib3RoIGNhc2VzIHRoZSBjb3VudCBpbmNsdWRlcyB0aGUgdGVybWluYXRpbmcgTlVMLgogKiAgIEZhaWx1cmU6IDAuIFVzZSBHZXRMYXN0RXJyb3IoKSB0byBkZXRlcm1pbmUgdGhlIGNhdXNlLiBQb3NzaWJsZSBlcnJvcnMgYXJlCiAqICAgICAgICAgICAgRVJST1JfSU5TVUZGSUNJRU5UX0JVRkZFUiwgaWYgbm90IGVub3VnaCBzcGFjZSBpcyBhdmFpbGFibGUgaW4gZHN0CiAqICAgICAgICAgICAgYW5kIGRzdGxlbiAhPSAwOyBFUlJPUl9JTlZBTElEX1BBUkFNRVRFUiwgIGlmIGFuIGludmFsaWQgcGFyYW1ldGVyCiAqICAgICAgICAgICAgaXMgcGFzc2VkLCBhbmQgRVJST1JfTk9fVU5JQ09ERV9UUkFOU0xBVElPTiBpZiBubyB0cmFuc2xhdGlvbiBpcwogKiAgICAgICAgICAgIHBvc3NpYmxlIGZvciBzcmMuCiAqLwpJTlQgV0lOQVBJIE11bHRpQnl0ZVRvV2lkZUNoYXIoIFVJTlQgcGFnZSwgRFdPUkQgZmxhZ3MsIExQQ1NUUiBzcmMsIElOVCBzcmNsZW4sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTFBXU1RSIGRzdCwgSU5UIGRzdGxlbiApCnsKICAgIGNvbnN0IHVuaW9uIGNwdGFibGUgKnRhYmxlOwogICAgaW50IHJldDsKCiAgICBpZiAoIXNyYyB8fCAoIWRzdCAmJiBkc3RsZW4pKQogICAgewogICAgICAgIFNldExhc3RFcnJvciggRVJST1JfSU5WQUxJRF9QQVJBTUVURVIgKTsKICAgICAgICByZXR1cm4gMDsKICAgIH0KCiAgICBpZiAoc3JjbGVuIDwgMCkgc3JjbGVuID0gc3RybGVuKHNyYykgKyAxOwoKICAgIGlmIChmbGFncyAmIE1CX1VTRUdMWVBIQ0hBUlMpIEZJWE1FKCJNQl9VU0VHTFlQSENIQVJTIG5vdCBzdXBwb3J0ZWRcbiIpOwoKICAgIHN3aXRjaChwYWdlKQogICAgewogICAgY2FzZSBDUF9TWU1CT0w6CiAgICAgICAgaWYoIGZsYWdzKQogICAgICAgIHsKICAgICAgICAgICAgU2V0TGFzdEVycm9yKCBFUlJPUl9JTlZBTElEX1BBUkFNRVRFUiApOwogICAgICAgICAgICByZXR1cm4gMDsKICAgICAgICB9CiAgICAgICAgcmV0ID0gd2luZV9jcHN5bWJvbF9tYnN0b3djcyggc3JjLCBzcmNsZW4sIGRzdCwgZHN0bGVuICk7CiAgICAgICAgYnJlYWs7CiAgICBjYXNlIENQX1VURjc6CiAgICAgICAgRklYTUUoIlVURi03IG5vdCBzdXBwb3J0ZWRcbiIpOwogICAgICAgIFNldExhc3RFcnJvciggRVJST1JfQ0FMTF9OT1RfSU1QTEVNRU5URUQgKTsKICAgICAgICByZXR1cm4gMDsKICAgIGNhc2UgQ1BfVU5JWENQOgogICAgICAgIGlmICh1bml4X2NwdGFibGUpCiAgICAgICAgewogICAgICAgICAgICByZXQgPSB3aW5lX2NwX21ic3Rvd2NzKCB1bml4X2NwdGFibGUsIGZsYWdzLCBzcmMsIHNyY2xlbiwgZHN0LCBkc3RsZW4gKTsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgfQogICAgICAgIC8qIGZhbGwgdGhyb3VnaCAqLwogICAgY2FzZSBDUF9VVEY4OgogICAgICAgIHJldCA9IHdpbmVfdXRmOF9tYnN0b3djcyggZmxhZ3MsIHNyYywgc3JjbGVuLCBkc3QsIGRzdGxlbiApOwogICAgICAgIGJyZWFrOwogICAgZGVmYXVsdDoKICAgICAgICBpZiAoISh0YWJsZSA9IGdldF9jb2RlcGFnZV90YWJsZSggcGFnZSApKSkKICAgICAgICB7CiAgICAgICAgICAgIFNldExhc3RFcnJvciggRVJST1JfSU5WQUxJRF9QQVJBTUVURVIgKTsKICAgICAgICAgICAgcmV0dXJuIDA7CiAgICAgICAgfQogICAgICAgIHJldCA9IHdpbmVfY3BfbWJzdG93Y3MoIHRhYmxlLCBmbGFncywgc3JjLCBzcmNsZW4sIGRzdCwgZHN0bGVuICk7CiAgICAgICAgYnJlYWs7CiAgICB9CgogICAgaWYgKHJldCA8IDApCiAgICB7CiAgICAgICAgc3dpdGNoKHJldCkKICAgICAgICB7CiAgICAgICAgY2FzZSAtMTogU2V0TGFzdEVycm9yKCBFUlJPUl9JTlNVRkZJQ0lFTlRfQlVGRkVSICk7IGJyZWFrOwogICAgICAgIGNhc2UgLTI6IFNldExhc3RFcnJvciggRVJST1JfTk9fVU5JQ09ERV9UUkFOU0xBVElPTiApOyBicmVhazsKICAgICAgICB9CiAgICAgICAgcmV0ID0gMDsKICAgIH0KICAgIHJldHVybiByZXQ7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICAgICAgICAgIFdpZGVDaGFyVG9NdWx0aUJ5dGUgICAoS0VSTkVMMzIuQCkKICoKICogQ29udmVydCBhIFVuaWNvZGUgY2hhcmFjdGVyIHN0cmluZyBpbnRvIGEgbXVsdGlieXRlIHN0cmluZy4KICoKICogUEFSQU1TCiAqICAgcGFnZSAgICBbSV0gQ29kZSBwYWdlIGNoYXJhY3RlciBzZXQgdG8gY29udmVydCB0bwogKiAgIGZsYWdzICAgW0ldIE1hcHBpbmcgRmxhZ3MgKE1CXyBjb25zdGFudHMgZnJvbSAid2lubmxzLmgiKS4KICogICBzcmMgICAgIFtJXSBTb3VyY2Ugc3RyaW5nIGJ1ZmZlcgogKiAgIHNyY2xlbiAgW0ldIExlbmd0aCBvZiBzcmMsIG9yIC0xIGlmIHNyYyBpcyBOVUwgdGVybWluYXRlZAogKiAgIGRzdCAgICAgW09dIERlc3RpbmF0aW9uIGJ1ZmZlcgogKiAgIGRzdGxlbiAgW0ldIExlbmd0aCBvZiBkc3QsIG9yIDAgdG8gY29tcHV0ZSB0aGUgcmVxdWlyZWQgbGVuZ3RoCiAqICAgZGVmY2hhciBbSV0gRGVmYXVsdCBjaGFyYWN0ZXIgdG8gdXNlIGZvciBjb252ZXJzaW9uIGlmIG5vIGV4YWN0CiAqCQkgICAgY29udmVyc2lvbiBjYW4gYmUgbWFkZQogKiAgIHVzZWQgICAgW09dIFNldCBpZiBkZWZhdWx0IGNoYXJhY3RlciB3YXMgdXNlZCBpbiB0aGUgY29udmVyc2lvbgogKgogKiBSRVRVUk5TCiAqICAgU3VjY2VzczogSWYgZHN0bGVuID4gMCwgdGhlIG51bWJlciBvZiBjaGFyYWN0ZXJzIHdyaXR0ZW4gdG8gZHN0LgogKiAgICAgICAgICAgIElmIGRzdGxlbiA9PSAwLCBudW1iZXIgb2YgY2hhcmFjdGVycyBuZWVkZWQgdG8gcGVyZm9ybSB0aGUKICogICAgICAgICAgICBjb252ZXJzaW9uLiBJbiBib3RoIGNhc2VzIHRoZSBjb3VudCBpbmNsdWRlcyB0aGUgdGVybWluYXRpbmcgTlVMLgogKiAgIEZhaWx1cmU6IDAuIFVzZSBHZXRMYXN0RXJyb3IoKSB0byBkZXRlcm1pbmUgdGhlIGNhdXNlLiBQb3NzaWJsZSBlcnJvcnMgYXJlCiAqICAgICAgICAgICAgRVJST1JfSU5TVUZGSUNJRU5UX0JVRkZFUiwgaWYgbm90IGVub3VnaCBzcGFjZSBpcyBhdmFpbGFibGUgaW4gZHN0CiAqICAgICAgICAgICAgYW5kIGRzdGxlbiAhPSAwLCBhbmQgRVJST1JfSU5WQUxJRF9QQVJBTUVURVIsIGlmIGFuIGludmFsaWQKICogICAgICAgICAgICBwYXJhbWV0ZXIgd2FzIGdpdmVuLgogKi8KSU5UIFdJTkFQSSBXaWRlQ2hhclRvTXVsdGlCeXRlKCBVSU5UIHBhZ2UsIERXT1JEIGZsYWdzLCBMUENXU1RSIHNyYywgSU5UIHNyY2xlbiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMUFNUUiBkc3QsIElOVCBkc3RsZW4sIExQQ1NUUiBkZWZjaGFyLCBCT09MICp1c2VkICkKewogICAgY29uc3QgdW5pb24gY3B0YWJsZSAqdGFibGU7CiAgICBpbnQgcmV0LCB1c2VkX3RtcDsKCiAgICBpZiAoIXNyYyB8fCAoIWRzdCAmJiBkc3RsZW4pKQogICAgewogICAgICAgIFNldExhc3RFcnJvciggRVJST1JfSU5WQUxJRF9QQVJBTUVURVIgKTsKICAgICAgICByZXR1cm4gMDsKICAgIH0KCiAgICBpZiAoc3JjbGVuIDwgMCkgc3JjbGVuID0gc3RybGVuVyhzcmMpICsgMTsKCiAgICBzd2l0Y2gocGFnZSkKICAgIHsKICAgIGNhc2UgQ1BfU1lNQk9MOgogICAgICAgIGlmKCBmbGFncyB8fCBkZWZjaGFyIHx8IHVzZWQpCiAgICAgICAgewogICAgICAgICAgICBTZXRMYXN0RXJyb3IoIEVSUk9SX0lOVkFMSURfUEFSQU1FVEVSICk7CiAgICAgICAgICAgIHJldHVybiAwOwogICAgICAgIH0KICAgICAgICByZXQgPSB3aW5lX2Nwc3ltYm9sX3djc3RvbWJzKCBzcmMsIHNyY2xlbiwgZHN0LCBkc3RsZW4gKTsKICAgICAgICBicmVhazsKICAgIGNhc2UgQ1BfVVRGNzoKICAgICAgICBGSVhNRSgiVVRGLTcgbm90IHN1cHBvcnRlZFxuIik7CiAgICAgICAgU2V0TGFzdEVycm9yKCBFUlJPUl9DQUxMX05PVF9JTVBMRU1FTlRFRCApOwogICAgICAgIHJldHVybiAwOwogICAgY2FzZSBDUF9VTklYQ1A6CiAgICAgICAgaWYgKHVuaXhfY3B0YWJsZSkKICAgICAgICB7CiAgICAgICAgICAgIHJldCA9IHdpbmVfY3Bfd2NzdG9tYnMoIHVuaXhfY3B0YWJsZSwgZmxhZ3MsIHNyYywgc3JjbGVuLCBkc3QsIGRzdGxlbiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGVmY2hhciwgdXNlZCA/ICZ1c2VkX3RtcCA6IE5VTEwgKTsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgfQogICAgICAgIC8qIGZhbGwgdGhyb3VnaCAqLwogICAgY2FzZSBDUF9VVEY4OgogICAgICAgIGlmICh1c2VkKSAqdXNlZCA9IEZBTFNFOyAgLyogYWxsIGNoYXJzIGFyZSB2YWxpZCBmb3IgVVRGLTggKi8KICAgICAgICByZXQgPSB3aW5lX3V0Zjhfd2NzdG9tYnMoIHNyYywgc3JjbGVuLCBkc3QsIGRzdGxlbiApOwogICAgICAgIGJyZWFrOwogICAgZGVmYXVsdDoKICAgICAgICBpZiAoISh0YWJsZSA9IGdldF9jb2RlcGFnZV90YWJsZSggcGFnZSApKSkKICAgICAgICB7CiAgICAgICAgICAgIFNldExhc3RFcnJvciggRVJST1JfSU5WQUxJRF9QQVJBTUVURVIgKTsKICAgICAgICAgICAgcmV0dXJuIDA7CiAgICAgICAgfQogICAgICAgIHJldCA9IHdpbmVfY3Bfd2NzdG9tYnMoIHRhYmxlLCBmbGFncywgc3JjLCBzcmNsZW4sIGRzdCwgZHN0bGVuLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRlZmNoYXIsIHVzZWQgPyAmdXNlZF90bXAgOiBOVUxMICk7CiAgICAgICAgaWYgKHVzZWQpICp1c2VkID0gdXNlZF90bXA7CiAgICAgICAgYnJlYWs7CiAgICB9CgogICAgaWYgKHJldCA8IDApCiAgICB7CiAgICAgICAgc3dpdGNoKHJldCkKICAgICAgICB7CiAgICAgICAgY2FzZSAtMTogU2V0TGFzdEVycm9yKCBFUlJPUl9JTlNVRkZJQ0lFTlRfQlVGRkVSICk7IGJyZWFrOwogICAgICAgIGNhc2UgLTI6IFNldExhc3RFcnJvciggRVJST1JfTk9fVU5JQ09ERV9UUkFOU0xBVElPTiApOyBicmVhazsKICAgICAgICB9CiAgICAgICAgcmV0ID0gMDsKICAgIH0KICAgIFRSQUNFKCJjcCAlZCAlcyAtPiAlc1xuIiwgcGFnZSwgZGVidWdzdHJfdyhzcmMpLCBkZWJ1Z3N0cl9hKGRzdCkpOwogICAgcmV0dXJuIHJldDsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgICAgICAgR2V0VGhyZWFkTG9jYWxlICAgIChLRVJORUwzMi5AKQogKgogKiBHZXQgdGhlIGN1cnJlbnQgdGhyZWFkcyBsb2NhbGUuCiAqCiAqIFBBUkFNUwogKiAgTm9uZS4KICoKICogUkVUVVJOUwogKiAgVGhlIExDSUQgY3VycmVudGx5IGFzc29jYXRlZCB3aXRoIHRoZSBjYWxsaW5nIHRocmVhZC4KICovCkxDSUQgV0lOQVBJIEdldFRocmVhZExvY2FsZSh2b2lkKQp7CiAgICBMQ0lEIHJldCA9IE50Q3VycmVudFRlYigpLT5DdXJyZW50TG9jYWxlOwogICAgaWYgKCFyZXQpIE50Q3VycmVudFRlYigpLT5DdXJyZW50TG9jYWxlID0gcmV0ID0gR2V0VXNlckRlZmF1bHRMQ0lEKCk7CiAgICByZXR1cm4gcmV0Owp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgICAgICAgU2V0VGhyZWFkTG9jYWxlICAgIChLRVJORUwzMi5AKQogKgogKiBTZXQgdGhlIGN1cnJlbnQgdGhyZWFkcyBsb2NhbGUuCiAqCiAqIFBBUkFNUwogKiAgbGNpZCBbSV0gTENJRCBvZiB0aGUgbG9jYWxlIHRvIHNldAogKgogKiBSRVRVUk5TCiAqICBTdWNjZXNzOiBUUlVFLiBUaGUgdGhyZWFkcyBsb2NhbGUgaXMgc2V0IHRvIGxjaWQuCiAqICBGYWlsdXJlOiBGQUxTRS4gVXNlIEdldExhc3RFcnJvcigpIHRvIGRldGVybWluZSB0aGUgY2F1c2UuCiAqLwpCT09MIFdJTkFQSSBTZXRUaHJlYWRMb2NhbGUoIExDSUQgbGNpZCApCnsKICAgIFRSQUNFKCIoMHglMDRsWClcbiIsIGxjaWQpOwoKICAgIGxjaWQgPSBDb252ZXJ0RGVmYXVsdExvY2FsZShsY2lkKTsKCiAgICBpZiAobGNpZCAhPSBHZXRUaHJlYWRMb2NhbGUoKSkKICAgIHsKICAgICAgICBpZiAoIUlzVmFsaWRMb2NhbGUobGNpZCwgTENJRF9TVVBQT1JURUQpKQogICAgICAgIHsKICAgICAgICAgICAgU2V0TGFzdEVycm9yKEVSUk9SX0lOVkFMSURfUEFSQU1FVEVSKTsKICAgICAgICAgICAgcmV0dXJuIEZBTFNFOwogICAgICAgIH0KCiAgICAgICAgTnRDdXJyZW50VGViKCktPkN1cnJlbnRMb2NhbGUgPSBsY2lkOwogICAgICAgIGtlcm5lbF9nZXRfdGhyZWFkX2RhdGEoKS0+Y29kZV9wYWdlID0gZ2V0X2xjaWRfY29kZXBhZ2UoIGxjaWQgKTsKICAgIH0KICAgIHJldHVybiBUUlVFOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCQlDb252ZXJ0RGVmYXVsdExvY2FsZSAoS0VSTkVMMzIuQCkKICoKICogQ29udmVydCBhIGRlZmF1bHQgbG9jYWxlIGlkZW50aWZpZXIgaW50byBhIHJlYWwgaWRlbnRpZmllci4KICoKICogUEFSQU1TCiAqICBsY2lkIFtJXSBMQ0lEIGlkZW50aWZpZXIgb2YgdGhlIGxvY2FsZSB0byBjb252ZXJ0CiAqCiAqIFJFVFVSTlMKICogIGxjaWQgdW5jaGFuZ2VkLCBpZiBub3QgYSBkZWZhdWx0IGxvY2FsZSBvciBpdHMgc3VibGFuZ3VhZ2UgaXMKICogICBub3QgU1VCTEFOR19ORVVUUkFMLgogKiAgR2V0U3lzdGVtRGVmYXVsdExDSUQoKSwgaWYgbGNpZCA9PSBMT0NBTEVfU1lTVEVNX0RFRkFVTFQuCiAqICBHZXRVc2VyRGVmYXVsdExDSUQoKSwgaWYgbGNpZCA9PSBMT0NBTEVfVVNFUl9ERUZBVUxUIG9yIExPQ0FMRV9ORVVUUkFMLgogKiAgT3RoZXJ3aXNlLCBsY2lkIHdpdGggc3VibGFuZ3VhZ2UgY2hhbmdlZCB0byBTVUJMQU5HX0RFRkFVTFQuCiAqLwpMQ0lEIFdJTkFQSSBDb252ZXJ0RGVmYXVsdExvY2FsZSggTENJRCBsY2lkICkKewogICAgTEFOR0lEIGxhbmdpZDsKCiAgICBzd2l0Y2ggKGxjaWQpCiAgICB7CiAgICBjYXNlIExPQ0FMRV9TWVNURU1fREVGQVVMVDoKICAgICAgICBsY2lkID0gR2V0U3lzdGVtRGVmYXVsdExDSUQoKTsKICAgICAgICBicmVhazsKICAgIGNhc2UgTE9DQUxFX1VTRVJfREVGQVVMVDoKICAgIGNhc2UgTE9DQUxFX05FVVRSQUw6CiAgICAgICAgbGNpZCA9IEdldFVzZXJEZWZhdWx0TENJRCgpOwogICAgICAgIGJyZWFrOwogICAgZGVmYXVsdDoKICAgICAgICAvKiBSZXBsYWNlIFNVQkxBTkdfTkVVVFJBTCB3aXRoIFNVQkxBTkdfREVGQVVMVCAqLwogICAgICAgIGxhbmdpZCA9IExBTkdJREZST01MQ0lEKGxjaWQpOwogICAgICAgIGlmIChTVUJMQU5HSUQobGFuZ2lkKSA9PSBTVUJMQU5HX05FVVRSQUwpCiAgICAgICAgewogICAgICAgICAgbGFuZ2lkID0gTUFLRUxBTkdJRChQUklNQVJZTEFOR0lEKGxhbmdpZCksIFNVQkxBTkdfREVGQVVMVCk7CiAgICAgICAgICBsY2lkID0gTUFLRUxDSUQobGFuZ2lkLCBTT1JUSURGUk9NTENJRChsY2lkKSk7CiAgICAgICAgfQogICAgfQogICAgcmV0dXJuIGxjaWQ7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgICAgICBJc1ZhbGlkTG9jYWxlICAgKEtFUk5FTDMyLkApCiAqCiAqIERldGVybWluZSBpZiBhIGxvY2FsZSBpcyB2YWxpZC4KICoKICogUEFSQU1TCiAqICBsY2lkICBbSV0gTENJRCBvZiB0aGUgbG9jYWxlIHRvIGNoZWNrCiAqICBmbGFncyBbSV0gTENJRF9TVVBQT1JURUQgPSBWYWxpZCwgTENJRF9JTlNUQUxMRUQgPSBWYWxpZCBhbmQgaW5zdGFsbGVkIG9uIHRoZSBzeXN0ZW0KICoKICogUkVUVVJOCiAqICBUUlVFLCAgaWYgbGNpZCBpcyB2YWxpZCwKICogIEZBTFNFLCBvdGhlcndpc2UuCiAqCiAqIE5PVEVTCiAqICBXaW5lIGRvZXMgbm90IGN1cnJlbnRseSBtYWtlIHRoZSBkaXN0aW5jdGlvbiBiZXR3ZWVuIHN1cHBvcnRlZCBhbmQgaW5zdGFsbGVkLiBBbGwKICogIGxhbmd1YWdlcyBzdXBwb3J0ZWQgYXJlIGluc3RhbGxlZCBieSBkZWZhdWx0LgogKi8KQk9PTCBXSU5BUEkgSXNWYWxpZExvY2FsZSggTENJRCBsY2lkLCBEV09SRCBmbGFncyApCnsKICAgIC8qIGNoZWNrIGlmIGxhbmd1YWdlIGlzIHJlZ2lzdGVyZWQgaW4gdGhlIGtlcm5lbDMyIHJlc291cmNlcyAqLwogICAgcmV0dXJuIEZpbmRSZXNvdXJjZUV4Vygga2VybmVsMzJfaGFuZGxlLCAoTFBXU1RSKVJUX1NUUklORywKICAgICAgICAgICAgICAgICAgICAgICAgICAgIChMUENXU1RSKUxPQ0FMRV9JTEFOR1VBR0UsIExBTkdJREZST01MQ0lEKGxjaWQpKSAhPSAwOwp9CgoKc3RhdGljIEJPT0wgQ0FMTEJBQ0sgZW51bV9sYW5nX3Byb2NfYSggSE1PRFVMRSBoTW9kdWxlLCBMUENTVFIgdHlwZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTFBDU1RSIG5hbWUsIFdPUkQgTGFuZ0lELCBMT05HIGxQYXJhbSApCnsKICAgIExPQ0FMRV9FTlVNUFJPQ0EgbHBmbkxvY2FsZUVudW0gPSAoTE9DQUxFX0VOVU1QUk9DQSlsUGFyYW07CiAgICBjaGFyIGJ1ZlsyMF07CgogICAgc3ByaW50ZihidWYsICIlMDh4IiwgKFVJTlQpTGFuZ0lEKTsKICAgIHJldHVybiBscGZuTG9jYWxlRW51bSggYnVmICk7Cn0KCnN0YXRpYyBCT09MIENBTExCQUNLIGVudW1fbGFuZ19wcm9jX3coIEhNT0RVTEUgaE1vZHVsZSwgTFBDV1NUUiB0eXBlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMUENXU1RSIG5hbWUsIFdPUkQgTGFuZ0lELCBMT05HIGxQYXJhbSApCnsKICAgIHN0YXRpYyBjb25zdCBXQ0hBUiBmb3JtYXRXW10gPSB7JyUnLCcwJywnOCcsJ3gnLDB9OwogICAgTE9DQUxFX0VOVU1QUk9DVyBscGZuTG9jYWxlRW51bSA9IChMT0NBTEVfRU5VTVBST0NXKWxQYXJhbTsKICAgIFdDSEFSIGJ1ZlsyMF07CiAgICBzcHJpbnRmVyggYnVmLCBmb3JtYXRXLCAoVUlOVClMYW5nSUQgKTsKICAgIHJldHVybiBscGZuTG9jYWxlRW51bSggYnVmICk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICAgICAgIEVudW1TeXN0ZW1Mb2NhbGVzQSAgKEtFUk5FTDMyLkApCiAqCiAqIENhbGwgYSB1c2VycyBmdW5jdGlvbiBmb3IgZWFjaCBsb2NhbGUgYXZhaWxhYmxlIG9uIHRoZSBzeXN0ZW0uCiAqCiAqIFBBUkFNUwogKiAgbHBmbkxvY2FsZUVudW0gW0ldIENhbGxiYWNrIGZ1bmN0aW9uIHRvIGNhbGwgZm9yIGVhY2ggbG9jYWxlCiAqICBkd0ZsYWdzICAgICAgICBbSV0gTE9DQUxFX1NVUFBPUlRFRD1BbGwgc3VwcG9ydGVkLCBMT0NBTEVfSU5TVEFMTEVEPUluc3RhbGxlZCBvbmx5CiAqCiAqIFJFVFVSTlMKICogIFN1Y2Nlc3M6IFRSVUUuCiAqICBGYWlsdXJlOiBGQUxTRS4gVXNlIEdldExhc3RFcnJvcigpIHRvIGRldGVybWluZSB0aGUgY2F1c2UuCiAqLwpCT09MIFdJTkFQSSBFbnVtU3lzdGVtTG9jYWxlc0EoIExPQ0FMRV9FTlVNUFJPQ0EgbHBmbkxvY2FsZUVudW0sIERXT1JEIGR3RmxhZ3MgKQp7CiAgICBUUkFDRSgiKCVwLCUwOGx4KVxuIiwgbHBmbkxvY2FsZUVudW0sIGR3RmxhZ3MpOwogICAgRW51bVJlc291cmNlTGFuZ3VhZ2VzQSgga2VybmVsMzJfaGFuZGxlLCAoTFBTVFIpUlRfU1RSSU5HLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgKExQQ1NUUilMT0NBTEVfSUxBTkdVQUdFLCBlbnVtX2xhbmdfcHJvY19hLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgKExPTkcpbHBmbkxvY2FsZUVudW0pOwogICAgcmV0dXJuIFRSVUU7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgICAgICBFbnVtU3lzdGVtTG9jYWxlc1cgIChLRVJORUwzMi5AKQogKgogKiBTZWUgRW51bVN5c3RlbUxvY2FsZXNBLgogKi8KQk9PTCBXSU5BUEkgRW51bVN5c3RlbUxvY2FsZXNXKCBMT0NBTEVfRU5VTVBST0NXIGxwZm5Mb2NhbGVFbnVtLCBEV09SRCBkd0ZsYWdzICkKewogICAgVFJBQ0UoIiglcCwlMDhseClcbiIsIGxwZm5Mb2NhbGVFbnVtLCBkd0ZsYWdzKTsKICAgIEVudW1SZXNvdXJjZUxhbmd1YWdlc1coIGtlcm5lbDMyX2hhbmRsZSwgKExQV1NUUilSVF9TVFJJTkcsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAoTFBDV1NUUilMT0NBTEVfSUxBTkdVQUdFLCBlbnVtX2xhbmdfcHJvY193LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgKExPTkcpbHBmbkxvY2FsZUVudW0pOwogICAgcmV0dXJuIFRSVUU7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICAgICAgIFZlckxhbmd1YWdlTmFtZUEgIChLRVJORUwzMi5AKQogKgogKiBHZXQgdGhlIG5hbWUgb2YgYSBsYW5ndWFnZS4KICoKICogUEFSQU1TCiAqICB3TGFuZyAgW0ldIExBTkdJRCBvZiB0aGUgbGFuZ3VhZ2UKICogIHN6TGFuZyBbT10gRGVzdGluYXRpb24gZm9yIHRoZSBsYW5ndWFnZSBuYW1lCiAqCiAqIFJFVFVSTlMKICogIFN1Y2Nlc3M6IFRoZSBzaXplIG9mIHRoZSBsYW5ndWFnZSBuYW1lLiBJZiBzekxhbmcgaXMgbm9uLU5VTEwsIGl0IGlzIGZpbGxlZAogKiAgICAgICAgICAgd2l0aCB0aGUgbmFtZS4KICogIEZhaWx1cmU6IDAuIFVzZSBHZXRMYXN0RXJyb3IoKSB0byBkZXRlcm1pbmUgdGhlIGNhdXNlLgogKgogKi8KRFdPUkQgV0lOQVBJIFZlckxhbmd1YWdlTmFtZUEoIFVJTlQgd0xhbmcsIExQU1RSIHN6TGFuZywgVUlOVCBuU2l6ZSApCnsKICAgIHJldHVybiBHZXRMb2NhbGVJbmZvQSggTUFLRUxDSUQod0xhbmcsIFNPUlRfREVGQVVMVCksIExPQ0FMRV9TRU5HTEFOR1VBR0UsIHN6TGFuZywgblNpemUgKTsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgICAgICAgVmVyTGFuZ3VhZ2VOYW1lVyAgKEtFUk5FTDMyLkApCiAqCiAqIFNlZSBWZXJMYW5ndWFnZU5hbWVBLgogKi8KRFdPUkQgV0lOQVBJIFZlckxhbmd1YWdlTmFtZVcoIFVJTlQgd0xhbmcsIExQV1NUUiBzekxhbmcsIFVJTlQgblNpemUgKQp7CiAgICByZXR1cm4gR2V0TG9jYWxlSW5mb1coIE1BS0VMQ0lEKHdMYW5nLCBTT1JUX0RFRkFVTFQpLCBMT0NBTEVfU0VOR0xBTkdVQUdFLCBzekxhbmcsIG5TaXplICk7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgICAgICBHZXRTdHJpbmdUeXBlVyAgICAoS0VSTkVMMzIuQCkKICoKICogU2VlIEdldFN0cmluZ1R5cGVBLgogKi8KQk9PTCBXSU5BUEkgR2V0U3RyaW5nVHlwZVcoIERXT1JEIHR5cGUsIExQQ1dTVFIgc3JjLCBJTlQgY291bnQsIExQV09SRCBjaGFydHlwZSApCnsKICAgIGlmIChjb3VudCA9PSAtMSkgY291bnQgPSBzdHJsZW5XKHNyYykgKyAxOwogICAgc3dpdGNoKHR5cGUpCiAgICB7CiAgICBjYXNlIENUX0NUWVBFMToKICAgICAgICB3aGlsZSAoY291bnQtLSkgKmNoYXJ0eXBlKysgPSBnZXRfY2hhcl90eXBlVyggKnNyYysrICkgJiAweGZmZjsKICAgICAgICBicmVhazsKICAgIGNhc2UgQ1RfQ1RZUEUyOgogICAgICAgIHdoaWxlIChjb3VudC0tKSAqY2hhcnR5cGUrKyA9IGdldF9jaGFyX3R5cGVXKCAqc3JjKysgKSA+PiAxMjsKICAgICAgICBicmVhazsKICAgIGNhc2UgQ1RfQ1RZUEUzOgogICAgewogICAgICAgIFdBUk4oIkNUX0NUWVBFMzogc2VtaS1zdHViLlxuIik7CiAgICAgICAgd2hpbGUgKGNvdW50LS0pCiAgICAgICAgewogICAgICAgICAgICBpbnQgYyA9ICpzcmM7CiAgICAgICAgICAgIFdPUkQgdHlwZTEsIHR5cGUzID0gMDsgLyogQzNfTk9UQVBQTElDQUJMRSAqLwoKICAgICAgICAgICAgdHlwZTEgPSBnZXRfY2hhcl90eXBlVyggKnNyYysrICkgJiAweGZmZjsKICAgICAgICAgICAgLyogdHJ5IHRvIGNvbnN0cnVjdCB0eXBlMyBmcm9tIHR5cGUxICovCiAgICAgICAgICAgIGlmKHR5cGUxICYgQzFfU1BBQ0UpIHR5cGUzIHw9IEMzX1NZTUJPTDsKICAgICAgICAgICAgaWYodHlwZTEgJiBDMV9BTFBIQSkgdHlwZTMgfD0gQzNfQUxQSEE7CiAgICAgICAgICAgIGlmICgoYz49MHgzMEEwKSYmKGM8PTB4MzBGRikpIHR5cGUzIHw9IEMzX0tBVEFLQU5BOwogICAgICAgICAgICBpZiAoKGM+PTB4MzA0MCkmJihjPD0weDMwOUYpKSB0eXBlMyB8PSBDM19ISVJBR0FOQTsKICAgICAgICAgICAgaWYgKChjPj0weDRFMDApJiYoYzw9MHg5RkFGKSkgdHlwZTMgfD0gQzNfSURFT0dSQVBIOwogICAgICAgICAgICBpZiAoKGM+PTB4MDYwMCkmJihjPD0weDA2RkYpKSB0eXBlMyB8PSBDM19LQVNISURBOwogICAgICAgICAgICBpZiAoKGM+PTB4MzAwMCkmJihjPD0weDMwM0YpKSB0eXBlMyB8PSBDM19TWU1CT0w7CgogICAgICAgICAgICBpZiAoKGM+PTB4RkYwMCkmJihjPD0weEZGNjApKSB0eXBlMyB8PSBDM19GVUxMV0lEVEg7CiAgICAgICAgICAgIGlmICgoYz49MHhGRjAwKSYmKGM8PTB4RkYyMCkpIHR5cGUzIHw9IEMzX1NZTUJPTDsKICAgICAgICAgICAgaWYgKChjPj0weEZGM0IpJiYoYzw9MHhGRjQwKSkgdHlwZTMgfD0gQzNfU1lNQk9MOwogICAgICAgICAgICBpZiAoKGM+PTB4RkY1QikmJihjPD0weEZGNjApKSB0eXBlMyB8PSBDM19TWU1CT0w7CiAgICAgICAgICAgIGlmICgoYz49MHhGRjIxKSYmKGM8PTB4RkYzQSkpIHR5cGUzIHw9IEMzX0FMUEhBOwogICAgICAgICAgICBpZiAoKGM+PTB4RkY0MSkmJihjPD0weEZGNUEpKSB0eXBlMyB8PSBDM19BTFBIQTsKICAgICAgICAgICAgaWYgKChjPj0weEZGRTApJiYoYzw9MHhGRkU2KSkgdHlwZTMgfD0gQzNfRlVMTFdJRFRIOwogICAgICAgICAgICBpZiAoKGM+PTB4RkZFMCkmJihjPD0weEZGRTYpKSB0eXBlMyB8PSBDM19TWU1CT0w7CgogICAgICAgICAgICBpZiAoKGM+PTB4RkY2MSkmJihjPD0weEZGREMpKSB0eXBlMyB8PSBDM19IQUxGV0lEVEg7CiAgICAgICAgICAgIGlmICgoYz49MHhGRjYxKSYmKGM8PTB4RkY2NCkpIHR5cGUzIHw9IEMzX1NZTUJPTDsKICAgICAgICAgICAgaWYgKChjPj0weEZGNjUpJiYoYzw9MHhGRjlGKSkgdHlwZTMgfD0gQzNfS0FUQUtBTkE7CiAgICAgICAgICAgIGlmICgoYz49MHhGRjY1KSYmKGM8PTB4RkY5RikpIHR5cGUzIHw9IEMzX0FMUEhBOwogICAgICAgICAgICBpZiAoKGM+PTB4RkZFOCkmJihjPD0weEZGRUUpKSB0eXBlMyB8PSBDM19IQUxGV0lEVEg7CiAgICAgICAgICAgIGlmICgoYz49MHhGRkU4KSYmKGM8PTB4RkZFRSkpIHR5cGUzIHw9IEMzX1NZTUJPTDsKICAgICAgICAgICAgKmNoYXJ0eXBlKysgPSB0eXBlMzsKICAgICAgICB9CiAgICAgICAgYnJlYWs7CiAgICB9CiAgICBkZWZhdWx0OgogICAgICAgIFNldExhc3RFcnJvciggRVJST1JfSU5WQUxJRF9QQVJBTUVURVIgKTsKICAgICAgICByZXR1cm4gRkFMU0U7CiAgICB9CiAgICByZXR1cm4gVFJVRTsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICAgICAgIEdldFN0cmluZ1R5cGVFeFcgICAgKEtFUk5FTDMyLkApCiAqCiAqIFNlZSBHZXRTdHJpbmdUeXBlRXhBLgogKi8KQk9PTCBXSU5BUEkgR2V0U3RyaW5nVHlwZUV4VyggTENJRCBsb2NhbGUsIERXT1JEIHR5cGUsIExQQ1dTVFIgc3JjLCBJTlQgY291bnQsIExQV09SRCBjaGFydHlwZSApCnsKICAgIC8qIGxvY2FsZSBpcyBpZ25vcmVkIGZvciBVbmljb2RlICovCiAgICByZXR1cm4gR2V0U3RyaW5nVHlwZVcoIHR5cGUsIHNyYywgY291bnQsIGNoYXJ0eXBlICk7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgICAgICBHZXRTdHJpbmdUeXBlQSAgICAoS0VSTkVMMzIuQCkKICoKICogR2V0IGNoYXJhY3RlcmlzdGljcyBvZiB0aGUgY2hhcmFjdGVycyBtYWtpbmcgdXAgYSBzdHJpbmcuCiAqCiAqIFBBUkFNUwogKiAgbG9jYWxlICAgW0ldIExvY2FsZSBJZCBmb3IgdGhlIHN0cmluZwogKiAgdHlwZSAgICAgW0ldIENUX0NUWVBFMSA9IGNsYXNzaWZpY2F0aW9uLCBDVF9DVFlQRTIgPSBkaXJlY3Rpb25hbGl0eSwgQ1RfQ1RZUEUzID0gdHlwb2dyYXBoaWMgaW5mbwogKiAgc3JjICAgICAgW0ldIFN0cmluZyB0byBhbmFseXNlCiAqICBjb3VudCAgICBbSV0gTGVuZ3RoIG9mIHNyYyBpbiBjaGFycywgb3IgLTEgaWYgc3JjIGlzIE5VTCB0ZXJtaW5hdGVkCiAqICBjaGFydHlwZSBbT10gRGVzdGluYXRpb24gZm9yIHRoZSBjYWxjdWxhdGVkIGNoYXJhY3RlcmlzdGljcwogKgogKiBSRVRVUk5TCiAqICBTdWNjZXNzOiBUUlVFLiBjaGFydHlwZSBpcyBmaWxsZWQgd2l0aCB0aGUgcmVxdWVzdGVkIGNoYXJhY3RlcmlzdGljcyBvZiBlYWNoIGNoYXIKICogICAgICAgICAgIGluIHNyYy4KICogIEZhaWx1cmU6IEZBTFNFLiBVc2UgR2V0TGFzdEVycm9yKCkgdG8gZGV0ZXJtaW5lIHRoZSBjYXVzZS4KICovCkJPT0wgV0lOQVBJIEdldFN0cmluZ1R5cGVBKCBMQ0lEIGxvY2FsZSwgRFdPUkQgdHlwZSwgTFBDU1RSIHNyYywgSU5UIGNvdW50LCBMUFdPUkQgY2hhcnR5cGUgKQp7CiAgICBVSU5UIGNwOwogICAgSU5UIGNvdW50VzsKICAgIExQV1NUUiBzcmNXOwogICAgQk9PTCByZXQgPSBGQUxTRTsKCiAgICBpZihjb3VudCA9PSAtMSkgY291bnQgPSBzdHJsZW4oc3JjKSArIDE7CgogICAgaWYgKCEoY3AgPSBnZXRfbGNpZF9jb2RlcGFnZSggbG9jYWxlICkpKQogICAgewogICAgICAgIEZJWE1FKCJGb3IgbG9jYWxlICUwNGx4IHVzaW5nIGN1cnJlbnQgQU5TSSBjb2RlIHBhZ2VcbiIsIGxvY2FsZSk7CiAgICAgICAgY3AgPSBHZXRBQ1AoKTsKICAgIH0KCiAgICBjb3VudFcgPSBNdWx0aUJ5dGVUb1dpZGVDaGFyKGNwLCAwLCBzcmMsIGNvdW50LCBOVUxMLCAwKTsKICAgIGlmKChzcmNXID0gSGVhcEFsbG9jKEdldFByb2Nlc3NIZWFwKCksIDAsIGNvdW50VyAqIHNpemVvZihXQ0hBUikpKSkKICAgIHsKICAgICAgICBNdWx0aUJ5dGVUb1dpZGVDaGFyKGNwLCAwLCBzcmMsIGNvdW50LCBzcmNXLCBjb3VudFcpOwogICAgLyoKICAgICAqIE5PVEU6IHRoZSB0YXJnZXQgYnVmZmVyIGhhcyAxIHdvcmQgZm9yIGVhY2ggQ0hBUkFDVEVSIGluIHRoZSBzb3VyY2UKICAgICAqIHN0cmluZywgd2l0aCBtdWx0aWJ5dGUgY2hhcmFjdGVycyB0aGVyZSBtYXliZSBiZSBtb3JlIGJ5dGVzIGluIGNvdW50CiAgICAgKiB0aGFuIGNoYXJhY3RlciBzcGFjZSBpbiB0aGUgYnVmZmVyIQogICAgICovCiAgICAgICAgcmV0ID0gR2V0U3RyaW5nVHlwZVcodHlwZSwgc3JjVywgY291bnRXLCBjaGFydHlwZSk7CiAgICAgICAgSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgc3JjVyk7CiAgICB9CiAgICByZXR1cm4gcmV0Owp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgICAgICBHZXRTdHJpbmdUeXBlRXhBICAgIChLRVJORUwzMi5AKQogKgogKiBHZXQgY2hhcmFjdGVyaXN0aWNzIG9mIHRoZSBjaGFyYWN0ZXJzIG1ha2luZyB1cCBhIHN0cmluZy4KICoKICogUEFSQU1TCiAqICBsb2NhbGUgICBbSV0gTG9jYWxlIElkIGZvciB0aGUgc3RyaW5nCiAqICB0eXBlICAgICBbSV0gQ1RfQ1RZUEUxID0gY2xhc3NpZmljYXRpb24sIENUX0NUWVBFMiA9IGRpcmVjdGlvbmFsaXR5LCBDVF9DVFlQRTMgPSB0eXBvZ3JhcGhpYyBpbmZvCiAqICBzcmMgICAgICBbSV0gU3RyaW5nIHRvIGFuYWx5c2UKICogIGNvdW50ICAgIFtJXSBMZW5ndGggb2Ygc3JjIGluIGNoYXJzLCBvciAtMSBpZiBzcmMgaXMgTlVMIHRlcm1pbmF0ZWQKICogIGNoYXJ0eXBlIFtPXSBEZXN0aW5hdGlvbiBmb3IgdGhlIGNhbGN1bGF0ZWQgY2hhcmFjdGVyaXN0aWNzCiAqCiAqIFJFVFVSTlMKICogIFN1Y2Nlc3M6IFRSVUUuIGNoYXJ0eXBlIGlzIGZpbGxlZCB3aXRoIHRoZSByZXF1ZXN0ZWQgY2hhcmFjdGVyaXN0aWNzIG9mIGVhY2ggY2hhcgogKiAgICAgICAgICAgaW4gc3JjLgogKiAgRmFpbHVyZTogRkFMU0UuIFVzZSBHZXRMYXN0RXJyb3IoKSB0byBkZXRlcm1pbmUgdGhlIGNhdXNlLgogKi8KQk9PTCBXSU5BUEkgR2V0U3RyaW5nVHlwZUV4QSggTENJRCBsb2NhbGUsIERXT1JEIHR5cGUsIExQQ1NUUiBzcmMsIElOVCBjb3VudCwgTFBXT1JEIGNoYXJ0eXBlICkKewogICAgcmV0dXJuIEdldFN0cmluZ1R5cGVBKGxvY2FsZSwgdHlwZSwgc3JjLCBjb3VudCwgY2hhcnR5cGUpOwp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICAgICAgIExDTWFwU3RyaW5nVyAgICAoS0VSTkVMMzIuQCkKICoKICogU2VlIExDTWFwU3RyaW5nQS4KICovCklOVCBXSU5BUEkgTENNYXBTdHJpbmdXKExDSUQgbGNpZCwgRFdPUkQgZmxhZ3MsIExQQ1dTVFIgc3JjLCBJTlQgc3JjbGVuLAogICAgICAgICAgICAgICAgICAgICAgICBMUFdTVFIgZHN0LCBJTlQgZHN0bGVuKQp7CiAgICBMUFdTVFIgZHN0X3B0cjsKCiAgICBpZiAoIXNyYyB8fCAhc3JjbGVuIHx8IGRzdGxlbiA8IDApCiAgICB7CiAgICAgICAgU2V0TGFzdEVycm9yKEVSUk9SX0lOVkFMSURfUEFSQU1FVEVSKTsKICAgICAgICByZXR1cm4gMDsKICAgIH0KCiAgICAvKiBtdXR1YWxseSBleGNsdXNpdmUgZmxhZ3MgKi8KICAgIGlmICgoZmxhZ3MgJiAoTENNQVBfTE9XRVJDQVNFIHwgTENNQVBfVVBQRVJDQVNFKSkgPT0gKExDTUFQX0xPV0VSQ0FTRSB8IExDTUFQX1VQUEVSQ0FTRSkgfHwKICAgICAgICAoZmxhZ3MgJiAoTENNQVBfSElSQUdBTkEgfCBMQ01BUF9LQVRBS0FOQSkpID09IChMQ01BUF9ISVJBR0FOQSB8IExDTUFQX0tBVEFLQU5BKSB8fAogICAgICAgIChmbGFncyAmIChMQ01BUF9IQUxGV0lEVEggfCBMQ01BUF9GVUxMV0lEVEgpKSA9PSAoTENNQVBfSEFMRldJRFRIIHwgTENNQVBfRlVMTFdJRFRIKSB8fAogICAgICAgIChmbGFncyAmIChMQ01BUF9UUkFESVRJT05BTF9DSElORVNFIHwgTENNQVBfU0lNUExJRklFRF9DSElORVNFKSkgPT0gKExDTUFQX1RSQURJVElPTkFMX0NISU5FU0UgfCBMQ01BUF9TSU1QTElGSUVEX0NISU5FU0UpKQogICAgewogICAgICAgIFNldExhc3RFcnJvcihFUlJPUl9JTlZBTElEX0ZMQUdTKTsKICAgICAgICByZXR1cm4gMDsKICAgIH0KCiAgICBpZiAoIWRzdGxlbikgZHN0ID0gTlVMTDsKCiAgICBsY2lkID0gQ29udmVydERlZmF1bHRMb2NhbGUobGNpZCk7CgogICAgaWYgKGZsYWdzICYgTENNQVBfU09SVEtFWSkKICAgIHsKICAgICAgICBpZiAoc3JjID09IGRzdCkKICAgICAgICB7CiAgICAgICAgICAgIFNldExhc3RFcnJvcihFUlJPUl9JTlZBTElEX0ZMQUdTKTsKICAgICAgICAgICAgcmV0dXJuIDA7CiAgICAgICAgfQoKICAgICAgICBpZiAoc3JjbGVuIDwgMCkgc3JjbGVuID0gc3RybGVuVyhzcmMpOwoKICAgICAgICBUUkFDRSgiKDB4JTA0bHgsMHglMDhseCwlcywlZCwlcCwlZClcbiIsCiAgICAgICAgICAgICAgbGNpZCwgZmxhZ3MsIGRlYnVnc3RyX3duKHNyYywgc3JjbGVuKSwgc3JjbGVuLCBkc3QsIGRzdGxlbik7CgogICAgICAgIHJldHVybiB3aW5lX2dldF9zb3J0a2V5KGZsYWdzLCBzcmMsIHNyY2xlbiwgKGNoYXIgKilkc3QsIGRzdGxlbik7CiAgICB9CgogICAgLyogU09SVF9TVFJJTkdTT1JUIG11c3QgYmUgdXNlZCBleGNsdXNpdmVseSB3aXRoIExDTUFQX1NPUlRLRVkgKi8KICAgIGlmIChmbGFncyAmIFNPUlRfU1RSSU5HU09SVCkKICAgIHsKICAgICAgICBTZXRMYXN0RXJyb3IoRVJST1JfSU5WQUxJRF9GTEFHUyk7CiAgICAgICAgcmV0dXJuIDA7CiAgICB9CgogICAgaWYgKHNyY2xlbiA8IDApIHNyY2xlbiA9IHN0cmxlblcoc3JjKSArIDE7CgogICAgVFJBQ0UoIigweCUwNGx4LDB4JTA4bHgsJXMsJWQsJXAsJWQpXG4iLAogICAgICAgICAgbGNpZCwgZmxhZ3MsIGRlYnVnc3RyX3duKHNyYywgc3JjbGVuKSwgc3JjbGVuLCBkc3QsIGRzdGxlbik7CgogICAgaWYgKCFkc3QpIC8qIHJldHVybiByZXF1aXJlZCBzdHJpbmcgbGVuZ3RoICovCiAgICB7CiAgICAgICAgSU5UIGxlbjsKCiAgICAgICAgZm9yIChsZW4gPSAwOyBzcmNsZW47IHNyYysrLCBzcmNsZW4tLSkKICAgICAgICB7CiAgICAgICAgICAgIFdDSEFSIHdjaCA9ICpzcmM7CiAgICAgICAgICAgIC8qIHRlc3RzIHNob3cgdGhhdCB3aW4yayBqdXN0IGlnbm9yZXMgTk9STV9JR05PUkVOT05TUEFDRSwKICAgICAgICAgICAgICogYW5kIHNraXBzIHdoaXRlIHNwYWNlIGFuZCBwdW5jdHVhdGlvbiBjaGFyYWN0ZXJzIGZvcgogICAgICAgICAgICAgKiBOT1JNX0lHTk9SRVNZTUJPTFMuCiAgICAgICAgICAgICAqLwogICAgICAgICAgICBpZiAoKGZsYWdzICYgTk9STV9JR05PUkVTWU1CT0xTKSAmJiAoZ2V0X2NoYXJfdHlwZVcod2NoKSAmIChDMV9QVU5DVCB8IEMxX1NQQUNFKSkpCiAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgbGVuKys7CiAgICAgICAgfQogICAgICAgIHJldHVybiBsZW47CiAgICB9CgogICAgaWYgKGZsYWdzICYgTENNQVBfVVBQRVJDQVNFKQogICAgewogICAgICAgIGZvciAoZHN0X3B0ciA9IGRzdDsgc3JjbGVuICYmIGRzdGxlbjsgc3JjKyssIHNyY2xlbi0tKQogICAgICAgIHsKICAgICAgICAgICAgV0NIQVIgd2NoID0gKnNyYzsKICAgICAgICAgICAgaWYgKChmbGFncyAmIE5PUk1fSUdOT1JFU1lNQk9MUykgJiYgKGdldF9jaGFyX3R5cGVXKHdjaCkgJiAoQzFfUFVOQ1QgfCBDMV9TUEFDRSkpKQogICAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgICpkc3RfcHRyKysgPSB0b3VwcGVyVyh3Y2gpOwogICAgICAgICAgICBkc3RsZW4tLTsKICAgICAgICB9CiAgICB9CiAgICBlbHNlIGlmIChmbGFncyAmIExDTUFQX0xPV0VSQ0FTRSkKICAgIHsKICAgICAgICBmb3IgKGRzdF9wdHIgPSBkc3Q7IHNyY2xlbiAmJiBkc3RsZW47IHNyYysrLCBzcmNsZW4tLSkKICAgICAgICB7CiAgICAgICAgICAgIFdDSEFSIHdjaCA9ICpzcmM7CiAgICAgICAgICAgIGlmICgoZmxhZ3MgJiBOT1JNX0lHTk9SRVNZTUJPTFMpICYmIChnZXRfY2hhcl90eXBlVyh3Y2gpICYgKEMxX1BVTkNUIHwgQzFfU1BBQ0UpKSkKICAgICAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgICAqZHN0X3B0cisrID0gdG9sb3dlclcod2NoKTsKICAgICAgICAgICAgZHN0bGVuLS07CiAgICAgICAgfQogICAgfQogICAgZWxzZQogICAgewogICAgICAgIGlmIChzcmMgPT0gZHN0KQogICAgICAgIHsKICAgICAgICAgICAgU2V0TGFzdEVycm9yKEVSUk9SX0lOVkFMSURfRkxBR1MpOwogICAgICAgICAgICByZXR1cm4gMDsKICAgICAgICB9CiAgICAgICAgZm9yIChkc3RfcHRyID0gZHN0OyBzcmNsZW4gJiYgZHN0bGVuOyBzcmMrKywgc3JjbGVuLS0pCiAgICAgICAgewogICAgICAgICAgICBXQ0hBUiB3Y2ggPSAqc3JjOwogICAgICAgICAgICBpZiAoKGZsYWdzICYgTk9STV9JR05PUkVTWU1CT0xTKSAmJiAoZ2V0X2NoYXJfdHlwZVcod2NoKSAmIChDMV9QVU5DVCB8IEMxX1NQQUNFKSkpCiAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgKmRzdF9wdHIrKyA9IHdjaDsKICAgICAgICAgICAgZHN0bGVuLS07CiAgICAgICAgfQogICAgfQoKICAgIGlmIChzcmNsZW4pCiAgICB7CiAgICAgICAgU2V0TGFzdEVycm9yKEVSUk9SX0lOU1VGRklDSUVOVF9CVUZGRVIpOwogICAgICAgIHJldHVybiAwOwogICAgfQoKICAgIHJldHVybiBkc3RfcHRyIC0gZHN0Owp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgICAgICAgTENNYXBTdHJpbmdBICAgIChLRVJORUwzMi5AKQogKgogKiBNYXAgY2hhcmFjdGVycyBpbiBhIGxvY2FsZSBzZW5zaXRpdmUgc3RyaW5nLgogKgogKiBQQVJBTVMKICogIGxjaWQgICBbSV0gTENJRCBmb3IgdGhlIGNvbnZlcnNpb24uCiAqICBmbGFncyAgW0ldIEZsYWdzIGNvbnRyb2xsaW5nIHRoZSBtYXBwaW5nIChMQ01BUF8gY29uc3RhbnRzIGZyb20gIndpbm5scy5oIikuCiAqICBzcmMgICAgW0ldIFN0cmluZyB0byBtYXAKICogIHNyY2xlbiBbSV0gTGVuZ3RoIG9mIHNyYyBpbiBjaGFycywgb3IgLTEgaWYgc3JjIGlzIE5VTCB0ZXJtaW5hdGVkCiAqICBkc3QgICAgW09dIERlc3RpbmF0aW9uIGZvciBtYXBwZWQgc3RyaW5nCiAqICBkc3RsZW4gW0ldIExlbmd0aCBvZiBkc3QgaW4gY2hhcmFjdGVycwogKgogKiBSRVRVUk5TCiAqICBTdWNjZXNzOiBUaGUgbGVuZ3RoIG9mIHRoZSBtYXBwZWQgc3RyaW5nIGluIGRzdCwgaW5jbHVkaW5nIHRoZSBOVUwgdGVybWluYXRvci4KICogIEZhaWx1cmU6IDAuIFVzZSBHZXRMYXN0RXJyb3IoKSB0byBkZXRlcm1pbmUgdGhlIGNhdXNlLgogKi8KSU5UIFdJTkFQSSBMQ01hcFN0cmluZ0EoTENJRCBsY2lkLCBEV09SRCBmbGFncywgTFBDU1RSIHNyYywgSU5UIHNyY2xlbiwKICAgICAgICAgICAgICAgICAgICAgICAgTFBTVFIgZHN0LCBJTlQgZHN0bGVuKQp7CiAgICBXQ0hBUiAqYnVmVyA9IE50Q3VycmVudFRlYigpLT5TdGF0aWNVbmljb2RlQnVmZmVyOwogICAgTFBXU1RSIHNyY1csIGRzdFc7CiAgICBJTlQgcmV0ID0gMCwgc3JjbGVuVywgZHN0bGVuVzsKICAgIFVJTlQgbG9jYWxlX2NwID0gQ1BfQUNQOwoKICAgIGlmICghc3JjIHx8ICFzcmNsZW4gfHwgZHN0bGVuIDwgMCkKICAgIHsKICAgICAgICBTZXRMYXN0RXJyb3IoRVJST1JfSU5WQUxJRF9QQVJBTUVURVIpOwogICAgICAgIHJldHVybiAwOwogICAgfQoKICAgIGlmICghKGZsYWdzICYgTE9DQUxFX1VTRV9DUF9BQ1ApKSBsb2NhbGVfY3AgPSBnZXRfbGNpZF9jb2RlcGFnZSggbGNpZCApOwoKICAgIHNyY2xlblcgPSBNdWx0aUJ5dGVUb1dpZGVDaGFyKGxvY2FsZV9jcCwgMCwgc3JjLCBzcmNsZW4sIGJ1ZlcsIDI2MCk7CiAgICBpZiAoc3JjbGVuVykKICAgICAgICBzcmNXID0gYnVmVzsKICAgIGVsc2UKICAgIHsKICAgICAgICBzcmNsZW5XID0gTXVsdGlCeXRlVG9XaWRlQ2hhcihsb2NhbGVfY3AsIDAsIHNyYywgc3JjbGVuLCBOVUxMLCAwKTsKICAgICAgICBzcmNXID0gSGVhcEFsbG9jKEdldFByb2Nlc3NIZWFwKCksIDAsIHNyY2xlblcgKiBzaXplb2YoV0NIQVIpKTsKICAgICAgICBpZiAoIXNyY1cpCiAgICAgICAgewogICAgICAgICAgICBTZXRMYXN0RXJyb3IoRVJST1JfTk9UX0VOT1VHSF9NRU1PUlkpOwogICAgICAgICAgICByZXR1cm4gMDsKICAgICAgICB9CiAgICAgICAgTXVsdGlCeXRlVG9XaWRlQ2hhcihsb2NhbGVfY3AsIDAsIHNyYywgc3JjbGVuLCBzcmNXLCBzcmNsZW5XKTsKICAgIH0KCiAgICBpZiAoZmxhZ3MgJiBMQ01BUF9TT1JUS0VZKQogICAgewogICAgICAgIGlmIChzcmMgPT0gZHN0KQogICAgICAgIHsKICAgICAgICAgICAgU2V0TGFzdEVycm9yKEVSUk9SX0lOVkFMSURfRkxBR1MpOwogICAgICAgICAgICBnb3RvIG1hcF9zdHJpbmdfZXhpdDsKICAgICAgICB9CiAgICAgICAgcmV0ID0gd2luZV9nZXRfc29ydGtleShmbGFncywgc3JjVywgc3JjbGVuVywgZHN0LCBkc3RsZW4pOwogICAgICAgIGdvdG8gbWFwX3N0cmluZ19leGl0OwogICAgfQoKICAgIGlmIChmbGFncyAmIFNPUlRfU1RSSU5HU09SVCkKICAgIHsKICAgICAgICBTZXRMYXN0RXJyb3IoRVJST1JfSU5WQUxJRF9GTEFHUyk7CiAgICAgICAgZ290byBtYXBfc3RyaW5nX2V4aXQ7CiAgICB9CgogICAgZHN0bGVuVyA9IExDTWFwU3RyaW5nVyhsY2lkLCBmbGFncywgc3JjVywgc3JjbGVuVywgTlVMTCwgMCk7CiAgICBpZiAoIWRzdGxlblcpCiAgICAgICAgZ290byBtYXBfc3RyaW5nX2V4aXQ7CgogICAgZHN0VyA9IEhlYXBBbGxvYyhHZXRQcm9jZXNzSGVhcCgpLCAwLCBkc3RsZW5XICogc2l6ZW9mKFdDSEFSKSk7CiAgICBpZiAoIWRzdFcpCiAgICB7CiAgICAgICAgU2V0TGFzdEVycm9yKEVSUk9SX05PVF9FTk9VR0hfTUVNT1JZKTsKICAgICAgICBnb3RvIG1hcF9zdHJpbmdfZXhpdDsKICAgIH0KCiAgICBMQ01hcFN0cmluZ1cobGNpZCwgZmxhZ3MsIHNyY1csIHNyY2xlblcsIGRzdFcsIGRzdGxlblcpOwogICAgcmV0ID0gV2lkZUNoYXJUb011bHRpQnl0ZShsb2NhbGVfY3AsIDAsIGRzdFcsIGRzdGxlblcsIGRzdCwgZHN0bGVuLCBOVUxMLCBOVUxMKTsKICAgIEhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksIDAsIGRzdFcpOwoKbWFwX3N0cmluZ19leGl0OgogICAgaWYgKHNyY1cgIT0gYnVmVykgSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgc3JjVyk7CiAgICByZXR1cm4gcmV0Owp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgICAgICAgRm9sZFN0cmluZ0EgICAgKEtFUk5FTDMyLkApCiAqCiAqIE1hcCBjaGFyYWN0ZXJzIGluIGEgc3RyaW5nLgogKgogKiBQQVJBTVMKICogIGR3RmxhZ3MgW0ldIEZsYWdzIGNvbnRyb2xsaW5nIGNoYXJzIHRvIG1hcCAoTUFQXyBjb25zdGFudHMgZnJvbSAid2lubmxzLmgiKQogKiAgc3JjICAgICBbSV0gU3RyaW5nIHRvIG1hcAogKiAgc3JjbGVuICBbSV0gTGVuZ3RoIG9mIHNyYywgb3IgLTEgaWYgc3JjIGlzIE5VTCB0ZXJtaW5hdGVkCiAqICBkc3QgICAgIFtPXSBEZXN0aW5hdGlvbiBmb3IgbWFwcGVkIHN0cmluZwogKiAgZHN0bGVuICBbSV0gTGVuZ3RoIG9mIGRzdCwgb3IgMCB0byBmaW5kIHRoZSByZXF1aXJlZCBsZW5ndGggZm9yIHRoZSBtYXBwZWQgc3RyaW5nCiAqCiAqIFJFVFVSTlMKICogIFN1Y2Nlc3M6IFRoZSBsZW5ndGggb2YgdGhlIHN0cmluZyB3cml0dGVuIHRvIGRzdCwgaW5jbHVkaW5nIHRoZSB0ZXJtaW5hdGluZyBOVUwuIElmCiAqICAgICAgICAgICBkc3RsZW4gaXMgMCwgdGhlIHZhbHVlIHJldHVybmVkIGlzIHRoZSBzYW1lLCBidXQgbm90aGluZyBpcyB3cml0dGVuIHRvIGRzdCwKICogICAgICAgICAgIGFuZCBkc3QgbWF5IGJlIE5VTEwuCiAqICBGYWlsdXJlOiAwLiBVc2UgR2V0TGFzdEVycm9yKCkgdG8gZGV0ZXJtaW5lIHRoZSBjYXVzZS4KICovCklOVCBXSU5BUEkgRm9sZFN0cmluZ0EoRFdPUkQgZHdGbGFncywgTFBDU1RSIHNyYywgSU5UIHNyY2xlbiwKICAgICAgICAgICAgICAgICAgICAgICBMUFNUUiBkc3QsIElOVCBkc3RsZW4pCnsKICAgIElOVCByZXQgPSAwLCBzcmNsZW5XID0gMDsKICAgIFdDSEFSICpzcmNXID0gTlVMTCwgKmRzdFcgPSBOVUxMOwoKICAgIGlmICghc3JjIHx8ICFzcmNsZW4gfHwgZHN0bGVuIDwgMCB8fCAoZHN0bGVuICYmICFkc3QpIHx8IHNyYyA9PSBkc3QpCiAgICB7CiAgICAgICAgU2V0TGFzdEVycm9yKEVSUk9SX0lOVkFMSURfUEFSQU1FVEVSKTsKICAgICAgICByZXR1cm4gMDsKICAgIH0KCiAgICBzcmNsZW5XID0gTXVsdGlCeXRlVG9XaWRlQ2hhcihDUF9BQ1AsIGR3RmxhZ3MgJiBNQVBfQ09NUE9TSVRFID8gTUJfQ09NUE9TSVRFIDogMCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNyYywgc3JjbGVuLCBOVUxMLCAwKTsKICAgIHNyY1cgPSBIZWFwQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgc3JjbGVuVyAqIHNpemVvZihXQ0hBUikpOwoKICAgIGlmICghc3JjVykKICAgIHsKICAgICAgICBTZXRMYXN0RXJyb3IoRVJST1JfTk9UX0VOT1VHSF9NRU1PUlkpOwogICAgICAgIGdvdG8gRm9sZFN0cmluZ0FfZXhpdDsKICAgIH0KCiAgICBNdWx0aUJ5dGVUb1dpZGVDaGFyKENQX0FDUCwgZHdGbGFncyAmIE1BUF9DT01QT1NJVEUgPyBNQl9DT01QT1NJVEUgOiAwLAogICAgICAgICAgICAgICAgICAgICAgICBzcmMsIHNyY2xlbiwgc3JjVywgc3JjbGVuVyk7CgogICAgZHdGbGFncyA9IChkd0ZsYWdzICYgfk1BUF9QUkVDT01QT1NFRCkgfCBNQVBfRk9MRENaT05FOwoKICAgIHJldCA9IEZvbGRTdHJpbmdXKGR3RmxhZ3MsIHNyY1csIHNyY2xlblcsIE5VTEwsIDApOwogICAgaWYgKHJldCAmJiBkc3RsZW4pCiAgICB7CiAgICAgICAgZHN0VyA9IEhlYXBBbGxvYyhHZXRQcm9jZXNzSGVhcCgpLCAwLCByZXQgKiBzaXplb2YoV0NIQVIpKTsKCiAgICAgICAgaWYgKCFkc3RXKQogICAgICAgIHsKICAgICAgICAgICAgU2V0TGFzdEVycm9yKEVSUk9SX05PVF9FTk9VR0hfTUVNT1JZKTsKICAgICAgICAgICAgZ290byBGb2xkU3RyaW5nQV9leGl0OwogICAgICAgIH0KCiAgICAgICAgcmV0ID0gRm9sZFN0cmluZ1coZHdGbGFncywgc3JjVywgc3JjbGVuVywgZHN0VywgcmV0KTsKICAgICAgICBpZiAoIVdpZGVDaGFyVG9NdWx0aUJ5dGUoQ1BfQUNQLCAwLCBkc3RXLCByZXQsIGRzdCwgZHN0bGVuLCBOVUxMLCBOVUxMKSkKICAgICAgICB7CiAgICAgICAgICAgIHJldCA9IDA7CiAgICAgICAgICAgIFNldExhc3RFcnJvcihFUlJPUl9JTlNVRkZJQ0lFTlRfQlVGRkVSKTsKICAgICAgICB9CiAgICB9CgogICAgSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgZHN0Vyk7CgpGb2xkU3RyaW5nQV9leGl0OgogICAgSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgc3JjVyk7CiAgICByZXR1cm4gcmV0Owp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgICAgICAgRm9sZFN0cmluZ1cgICAgKEtFUk5FTDMyLkApCiAqCiAqIFNlZSBGb2xkU3RyaW5nQS4KICovCklOVCBXSU5BUEkgRm9sZFN0cmluZ1coRFdPUkQgZHdGbGFncywgTFBDV1NUUiBzcmMsIElOVCBzcmNsZW4sCiAgICAgICAgICAgICAgICAgICAgICAgTFBXU1RSIGRzdCwgSU5UIGRzdGxlbikKewogICAgaW50IHJldDsKCiAgICBzd2l0Y2ggKGR3RmxhZ3MgJiAoTUFQX0NPTVBPU0lURXxNQVBfUFJFQ09NUE9TRUR8TUFQX0VYUEFORF9MSUdBVFVSRVMpKQogICAgewogICAgY2FzZSAwOgogICAgICAgIGlmIChkd0ZsYWdzKQogICAgICAgICAgYnJlYWs7CiAgICAgICAgLyogRmFsbCB0aHJvdWdoIGZvciBkd0ZsYWdzID09IDAgKi8KICAgIGNhc2UgTUFQX1BSRUNPTVBPU0VEfE1BUF9DT01QT1NJVEU6CiAgICBjYXNlIE1BUF9QUkVDT01QT1NFRHxNQVBfRVhQQU5EX0xJR0FUVVJFUzoKICAgIGNhc2UgTUFQX0NPTVBPU0lURXxNQVBfRVhQQU5EX0xJR0FUVVJFUzoKICAgICAgICBTZXRMYXN0RXJyb3IoRVJST1JfSU5WQUxJRF9GTEFHUyk7CiAgICAgICAgcmV0dXJuIDA7CiAgICB9CgogICAgaWYgKCFzcmMgfHwgIXNyY2xlbiB8fCBkc3RsZW4gPCAwIHx8IChkc3RsZW4gJiYgIWRzdCkgfHwgc3JjID09IGRzdCkKICAgIHsKICAgICAgICBTZXRMYXN0RXJyb3IoRVJST1JfSU5WQUxJRF9QQVJBTUVURVIpOwogICAgICAgIHJldHVybiAwOwogICAgfQoKICAgIHJldCA9IHdpbmVfZm9sZF9zdHJpbmcoZHdGbGFncywgc3JjLCBzcmNsZW4sIGRzdCwgZHN0bGVuKTsKICAgIGlmICghcmV0KQogICAgICAgIFNldExhc3RFcnJvcihFUlJPUl9JTlNVRkZJQ0lFTlRfQlVGRkVSKTsKICAgIHJldHVybiByZXQ7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICAgICAgIENvbXBhcmVTdHJpbmdXICAgIChLRVJORUwzMi5AKQogKgogKiBTZWUgQ29tcGFyZVN0cmluZ0EuCiAqLwpJTlQgV0lOQVBJIENvbXBhcmVTdHJpbmdXKExDSUQgbGNpZCwgRFdPUkQgc3R5bGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgTFBDV1NUUiBzdHIxLCBJTlQgbGVuMSwgTFBDV1NUUiBzdHIyLCBJTlQgbGVuMikKewogICAgSU5UIHJldDsKCiAgICBpZiAoIXN0cjEgfHwgIXN0cjIpCiAgICB7CiAgICAgICAgU2V0TGFzdEVycm9yKEVSUk9SX0lOVkFMSURfUEFSQU1FVEVSKTsKICAgICAgICByZXR1cm4gMDsKICAgIH0KCiAgICBpZiggc3R5bGUgJiB+KE5PUk1fSUdOT1JFQ0FTRXxOT1JNX0lHTk9SRU5PTlNQQUNFfE5PUk1fSUdOT1JFU1lNQk9MU3wKICAgICAgICBTT1JUX1NUUklOR1NPUlR8Tk9STV9JR05PUkVLQU5BVFlQRXxOT1JNX0lHTk9SRVdJRFRIfExPQ0FMRV9VU0VfQ1BfQUNQfDB4MTAwMDAwMDApICkKICAgIHsKICAgICAgICBTZXRMYXN0RXJyb3IoRVJST1JfSU5WQUxJRF9GTEFHUyk7CiAgICAgICAgcmV0dXJuIDA7CiAgICB9CgogICAgaWYgKHN0eWxlICYgMHgxMDAwMDAwMCkKICAgICAgICBGSVhNRSgiSWdub3JpbmcgdW5rbm93biBzdHlsZSAweDEwMDAwMDAwXG4iKTsKCiAgICBpZiAobGVuMSA8IDApIGxlbjEgPSBzdHJsZW5XKHN0cjEpOwogICAgaWYgKGxlbjIgPCAwKSBsZW4yID0gc3RybGVuVyhzdHIyKTsKCiAgICByZXQgPSB3aW5lX2NvbXBhcmVfc3RyaW5nKHN0eWxlLCBzdHIxLCBsZW4xLCBzdHIyLCBsZW4yKTsKCiAgICBpZiAocmV0KSAvKiBuZWVkIHRvIHRyYW5zbGF0ZSByZXN1bHQgKi8KICAgICAgICByZXR1cm4gKHJldCA8IDApID8gQ1NUUl9MRVNTX1RIQU4gOiBDU1RSX0dSRUFURVJfVEhBTjsKICAgIHJldHVybiBDU1RSX0VRVUFMOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgICAgICBDb21wYXJlU3RyaW5nQSAgICAoS0VSTkVMMzIuQCkKICoKICogQ29tcGFyZSB0d28gbG9jYWxlIHNlbnNpdGl2ZSBzdHJpbmdzLgogKgogKiBQQVJBTVMKICogIGxjaWQgIFtJXSBMQ0lEIGZvciB0aGUgY29tcGFyaXNvbgogKiAgc3R5bGUgW0ldIEZsYWdzIGZvciB0aGUgY29tcGFyaXNvbiAoTk9STV8gY29uc3RhbnRzIGZyb20gIndpbm5scy5oIikuCiAqICBzdHIxICBbSV0gRmlyc3Qgc3RyaW5nIHRvIGNvbXBhcmUKICogIGxlbjEgIFtJXSBMZW5ndGggb2Ygc3RyMSwgb3IgLTEgaWYgc3RyMSBpcyBOVUwgdGVybWluYXRlZAogKiAgc3RyMiAgW0ldIFNlY29uZCBzdHJpbmcgdG8gY29tcGFyZQogKiAgbGVuMiAgW0ldIExlbmd0aCBvZiBzdHIyLCBvciAtMSBpZiBzdHIyIGlzIE5VTCB0ZXJtaW5hdGVkCiAqCiAqIFJFVFVSTlMKICogIFN1Y2Nlc3M6IENTVFJfTEVTU19USEFOLCBDU1RSX0VRVUFMIG9yIENTVFJfR1JFQVRFUl9USEFOIGRlcGVuZGluZyBvbiB3aGV0aGVyCiAqICAgICAgICAgICBzdHIyIGlzIGxlc3MgdGhhbiwgZXF1YWwgdG8gb3IgZ3JlYXRlciB0aGFuIHN0cjEgcmVzcGVjdGl2ZWx5LgogKiAgRmFpbHVyZTogRkFMU0UuIFVzZSBHZXRMYXN0RXJyb3IoKSB0byBkZXRlcm1pbmUgdGhlIGNhdXNlLgogKi8KSU5UIFdJTkFQSSBDb21wYXJlU3RyaW5nQShMQ0lEIGxjaWQsIERXT1JEIHN0eWxlLAogICAgICAgICAgICAgICAgICAgICAgICAgIExQQ1NUUiBzdHIxLCBJTlQgbGVuMSwgTFBDU1RSIHN0cjIsIElOVCBsZW4yKQp7CiAgICBXQ0hBUiAqYnVmMVcgPSBOdEN1cnJlbnRUZWIoKS0+U3RhdGljVW5pY29kZUJ1ZmZlcjsKICAgIFdDSEFSICpidWYyVyA9IGJ1ZjFXICsgMTMwOwogICAgTFBXU1RSIHN0cjFXLCBzdHIyVzsKICAgIElOVCBsZW4xVywgbGVuMlcsIHJldDsKICAgIFVJTlQgbG9jYWxlX2NwID0gQ1BfQUNQOwoKICAgIGlmICghc3RyMSB8fCAhc3RyMikKICAgIHsKICAgICAgICBTZXRMYXN0RXJyb3IoRVJST1JfSU5WQUxJRF9QQVJBTUVURVIpOwogICAgICAgIHJldHVybiAwOwogICAgfQogICAgaWYgKGxlbjEgPCAwKSBsZW4xID0gc3RybGVuKHN0cjEpOwogICAgaWYgKGxlbjIgPCAwKSBsZW4yID0gc3RybGVuKHN0cjIpOwoKICAgIGlmICghKHN0eWxlICYgTE9DQUxFX1VTRV9DUF9BQ1ApKSBsb2NhbGVfY3AgPSBnZXRfbGNpZF9jb2RlcGFnZSggbGNpZCApOwoKICAgIGxlbjFXID0gTXVsdGlCeXRlVG9XaWRlQ2hhcihsb2NhbGVfY3AsIDAsIHN0cjEsIGxlbjEsIGJ1ZjFXLCAxMzApOwogICAgaWYgKGxlbjFXKQogICAgICAgIHN0cjFXID0gYnVmMVc7CiAgICBlbHNlCiAgICB7CiAgICAgICAgbGVuMVcgPSBNdWx0aUJ5dGVUb1dpZGVDaGFyKGxvY2FsZV9jcCwgMCwgc3RyMSwgbGVuMSwgTlVMTCwgMCk7CiAgICAgICAgc3RyMVcgPSBIZWFwQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgbGVuMVcgKiBzaXplb2YoV0NIQVIpKTsKICAgICAgICBpZiAoIXN0cjFXKQogICAgICAgIHsKICAgICAgICAgICAgU2V0TGFzdEVycm9yKEVSUk9SX05PVF9FTk9VR0hfTUVNT1JZKTsKICAgICAgICAgICAgcmV0dXJuIDA7CiAgICAgICAgfQogICAgICAgIE11bHRpQnl0ZVRvV2lkZUNoYXIobG9jYWxlX2NwLCAwLCBzdHIxLCBsZW4xLCBzdHIxVywgbGVuMVcpOwogICAgfQogICAgbGVuMlcgPSBNdWx0aUJ5dGVUb1dpZGVDaGFyKGxvY2FsZV9jcCwgMCwgc3RyMiwgbGVuMiwgYnVmMlcsIDEzMCk7CiAgICBpZiAobGVuMlcpCiAgICAgICAgc3RyMlcgPSBidWYyVzsKICAgIGVsc2UKICAgIHsKICAgICAgICBsZW4yVyA9IE11bHRpQnl0ZVRvV2lkZUNoYXIobG9jYWxlX2NwLCAwLCBzdHIyLCBsZW4yLCBOVUxMLCAwKTsKICAgICAgICBzdHIyVyA9IEhlYXBBbGxvYyhHZXRQcm9jZXNzSGVhcCgpLCAwLCBsZW4yVyAqIHNpemVvZihXQ0hBUikpOwogICAgICAgIGlmICghc3RyMlcpCiAgICAgICAgewogICAgICAgICAgICBpZiAoc3RyMVcgIT0gYnVmMVcpIEhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksIDAsIHN0cjFXKTsKICAgICAgICAgICAgU2V0TGFzdEVycm9yKEVSUk9SX05PVF9FTk9VR0hfTUVNT1JZKTsKICAgICAgICAgICAgcmV0dXJuIDA7CiAgICAgICAgfQogICAgICAgIE11bHRpQnl0ZVRvV2lkZUNoYXIobG9jYWxlX2NwLCAwLCBzdHIyLCBsZW4yLCBzdHIyVywgbGVuMlcpOwogICAgfQoKICAgIHJldCA9IENvbXBhcmVTdHJpbmdXKGxjaWQsIHN0eWxlLCBzdHIxVywgbGVuMVcsIHN0cjJXLCBsZW4yVyk7CgogICAgaWYgKHN0cjFXICE9IGJ1ZjFXKSBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLCAwLCBzdHIxVyk7CiAgICBpZiAoc3RyMlcgIT0gYnVmMlcpIEhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksIDAsIHN0cjJXKTsKICAgIHJldHVybiByZXQ7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgICAgICBsc3RyY21wICAgICAoS0VSTkVMMzIuQCkKICogICAgICAgICAgIGxzdHJjbXBBICAgIChLRVJORUwzMi5AKQogKgogKiBDb21wYXJlIHR3byBzdHJpbmdzIHVzaW5nIHRoZSBjdXJyZW50IHRocmVhZCBsb2NhbGUuCiAqCiAqIFBBUkFNUwogKiAgc3RyMSAgW0ldIEZpcnN0IHN0cmluZyB0byBjb21wYXJlCiAqICBzdHIyICBbSV0gU2Vjb25kIHN0cmluZyB0byBjb21wYXJlCiAqCiAqIFJFVFVSTlMKICogIFN1Y2Nlc3M6IEEgbnVtYmVyIGxlc3MgdGhhbiwgZXF1YWwgdG8gb3IgZ3JlYXRlciB0aGFuIDAgZGVwZW5kaW5nIG9uIHdoZXRoZXIKICogICAgICAgICAgIHN0cjIgaXMgbGVzcyB0aGFuLCBlcXVhbCB0byBvciBncmVhdGVyIHRoYW4gc3RyMSByZXNwZWN0aXZlbHkuCiAqICBGYWlsdXJlOiBGQUxTRS4gVXNlIEdldExhc3RFcnJvcigpIHRvIGRldGVybWluZSB0aGUgY2F1c2UuCiAqLwppbnQgV0lOQVBJIGxzdHJjbXBBKExQQ1NUUiBzdHIxLCBMUENTVFIgc3RyMikKewogICAgaW50IHJldDsKICAgIAogICAgaWYgKChzdHIxID09IE5VTEwpICYmIChzdHIyID09IE5VTEwpKSByZXR1cm4gMDsKICAgIGlmIChzdHIxID09IE5VTEwpIHJldHVybiAtMTsKICAgIGlmIChzdHIyID09IE5VTEwpIHJldHVybiAxOwoKICAgIHJldCA9IENvbXBhcmVTdHJpbmdBKEdldFRocmVhZExvY2FsZSgpLCBMT0NBTEVfVVNFX0NQX0FDUCwgc3RyMSwgLTEsIHN0cjIsIC0xKTsKICAgIGlmIChyZXQpIHJldCAtPSAyOwogICAgCiAgICByZXR1cm4gcmV0Owp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgICAgICAgbHN0cmNtcGkgICAgIChLRVJORUwzMi5AKQogKiAgICAgICAgICAgbHN0cmNtcGlBICAgIChLRVJORUwzMi5AKQogKgogKiBDb21wYXJlIHR3byBzdHJpbmdzIHVzaW5nIHRoZSBjdXJyZW50IHRocmVhZCBsb2NhbGUsIGlnbm9yaW5nIGNhc2UuCiAqCiAqIFBBUkFNUwogKiAgc3RyMSAgW0ldIEZpcnN0IHN0cmluZyB0byBjb21wYXJlCiAqICBzdHIyICBbSV0gU2Vjb25kIHN0cmluZyB0byBjb21wYXJlCiAqCiAqIFJFVFVSTlMKICogIFN1Y2Nlc3M6IEEgbnVtYmVyIGxlc3MgdGhhbiwgZXF1YWwgdG8gb3IgZ3JlYXRlciB0aGFuIDAgZGVwZW5kaW5nIG9uIHdoZXRoZXIKICogICAgICAgICAgIHN0cjIgaXMgbGVzcyB0aGFuLCBlcXVhbCB0byBvciBncmVhdGVyIHRoYW4gc3RyMSByZXNwZWN0aXZlbHkuCiAqICBGYWlsdXJlOiBGQUxTRS4gVXNlIEdldExhc3RFcnJvcigpIHRvIGRldGVybWluZSB0aGUgY2F1c2UuCiAqLwppbnQgV0lOQVBJIGxzdHJjbXBpQShMUENTVFIgc3RyMSwgTFBDU1RSIHN0cjIpCnsKICAgIGludCByZXQ7CiAgICAKICAgIGlmICgoc3RyMSA9PSBOVUxMKSAmJiAoc3RyMiA9PSBOVUxMKSkgcmV0dXJuIDA7CiAgICBpZiAoc3RyMSA9PSBOVUxMKSByZXR1cm4gLTE7CiAgICBpZiAoc3RyMiA9PSBOVUxMKSByZXR1cm4gMTsKCiAgICByZXQgPSBDb21wYXJlU3RyaW5nQShHZXRUaHJlYWRMb2NhbGUoKSwgTk9STV9JR05PUkVDQVNFfExPQ0FMRV9VU0VfQ1BfQUNQLCBzdHIxLCAtMSwgc3RyMiwgLTEpOwogICAgaWYgKHJldCkgcmV0IC09IDI7CiAgICAKICAgIHJldHVybiByZXQ7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgICAgICBsc3RyY21wVyAgICAoS0VSTkVMMzIuQCkKICoKICogU2VlIGxzdHJjbXBBLgogKi8KaW50IFdJTkFQSSBsc3RyY21wVyhMUENXU1RSIHN0cjEsIExQQ1dTVFIgc3RyMikKewogICAgaW50IHJldDsKCiAgICBpZiAoKHN0cjEgPT0gTlVMTCkgJiYgKHN0cjIgPT0gTlVMTCkpIHJldHVybiAwOwogICAgaWYgKHN0cjEgPT0gTlVMTCkgcmV0dXJuIC0xOwogICAgaWYgKHN0cjIgPT0gTlVMTCkgcmV0dXJuIDE7CgogICAgcmV0ID0gQ29tcGFyZVN0cmluZ1coR2V0VGhyZWFkTG9jYWxlKCksIDAsIHN0cjEsIC0xLCBzdHIyLCAtMSk7CiAgICBpZiAocmV0KSByZXQgLT0gMjsKICAgIAogICAgcmV0dXJuIHJldDsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICAgICAgIGxzdHJjbXBpVyAgICAoS0VSTkVMMzIuQCkKICoKICogU2VlIGxzdHJjbXBpQS4KICovCmludCBXSU5BUEkgbHN0cmNtcGlXKExQQ1dTVFIgc3RyMSwgTFBDV1NUUiBzdHIyKQp7CiAgICBpbnQgcmV0OwogICAgCiAgICBpZiAoKHN0cjEgPT0gTlVMTCkgJiYgKHN0cjIgPT0gTlVMTCkpIHJldHVybiAwOwogICAgaWYgKHN0cjEgPT0gTlVMTCkgcmV0dXJuIC0xOwogICAgaWYgKHN0cjIgPT0gTlVMTCkgcmV0dXJuIDE7CgogICAgcmV0ID0gQ29tcGFyZVN0cmluZ1coR2V0VGhyZWFkTG9jYWxlKCksIE5PUk1fSUdOT1JFQ0FTRSwgc3RyMSwgLTEsIHN0cjIsIC0xKTsKICAgIGlmIChyZXQpIHJldCAtPSAyOwogICAgCiAgICByZXR1cm4gcmV0Owp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCQlMT0NBTEVfSW5pdAogKi8Kdm9pZCBMT0NBTEVfSW5pdCh2b2lkKQp7CiAgICBleHRlcm4gdm9pZCBfX3dpbmVfaW5pdF9jb2RlcGFnZXMoIGNvbnN0IHVuaW9uIGNwdGFibGUgKmFuc2lfY3AsIGNvbnN0IHVuaW9uIGNwdGFibGUgKm9lbV9jcCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgdW5pb24gY3B0YWJsZSAqdW5peF9jcCApOwoKICAgIFVJTlQgYW5zaV9jcCA9IDEyNTIsIG9lbV9jcCA9IDQzNywgbWFjX2NwID0gMTAwMDAsIHVuaXhfY3AgPSB+MFU7CiAgICBMQ0lEIGxjaWQ7CgogICAgbGNpZCA9IGdldF9lbnZfbGNpZCggTlVMTCwgTlVMTCApOwogICAgTnRTZXREZWZhdWx0TG9jYWxlKCBUUlVFLCBsY2lkICk7CgogICAgbGNpZCA9IGdldF9lbnZfbGNpZCggTlVMTCwgIkxDX01FU1NBR0VTIiApOwogICAgTnRTZXREZWZhdWx0VUlMYW5ndWFnZSggTEFOR0lERlJPTUxDSUQobGNpZCkgKTsKCiAgICBsY2lkID0gZ2V0X2Vudl9sY2lkKCAmdW5peF9jcCwgIkxDX0NUWVBFIiApOwogICAgTnRTZXREZWZhdWx0TG9jYWxlKCBGQUxTRSwgbGNpZCApOwoKICAgIGFuc2lfY3AgPSBnZXRfbGNpZF9jb2RlcGFnZShsY2lkKTsKICAgIEdldExvY2FsZUluZm9XKCBsY2lkLCBMT0NBTEVfSURFRkFVTFRNQUNDT0RFUEFHRSB8IExPQ0FMRV9SRVRVUk5fTlVNQkVSLAogICAgICAgICAgICAgICAgICAgIChMUFdTVFIpJm1hY19jcCwgc2l6ZW9mKG1hY19jcCkvc2l6ZW9mKFdDSEFSKSApOwogICAgR2V0TG9jYWxlSW5mb1coIGxjaWQsIExPQ0FMRV9JREVGQVVMVENPREVQQUdFIHwgTE9DQUxFX1JFVFVSTl9OVU1CRVIsCiAgICAgICAgICAgICAgICAgICAgKExQV1NUUikmb2VtX2NwLCBzaXplb2Yob2VtX2NwKS9zaXplb2YoV0NIQVIpICk7CiAgICBpZiAodW5peF9jcCA9PSB+MFUpCiAgICAgICAgR2V0TG9jYWxlSW5mb1coIGxjaWQsIExPQ0FMRV9JREVGQVVMVFVOSVhDT0RFUEFHRSB8IExPQ0FMRV9SRVRVUk5fTlVNQkVSLAogICAgICAgICAgICAgICAgICAgIChMUFdTVFIpJnVuaXhfY3AsIHNpemVvZih1bml4X2NwKS9zaXplb2YoV0NIQVIpICk7CgogICAgaWYgKCEoYW5zaV9jcHRhYmxlID0gd2luZV9jcF9nZXRfdGFibGUoIGFuc2lfY3AgKSkpCiAgICAgICAgYW5zaV9jcHRhYmxlID0gd2luZV9jcF9nZXRfdGFibGUoIDEyNTIgKTsKICAgIGlmICghKG9lbV9jcHRhYmxlID0gd2luZV9jcF9nZXRfdGFibGUoIG9lbV9jcCApKSkKICAgICAgICBvZW1fY3B0YWJsZSAgPSB3aW5lX2NwX2dldF90YWJsZSggNDM3ICk7CiAgICBpZiAoIShtYWNfY3B0YWJsZSA9IHdpbmVfY3BfZ2V0X3RhYmxlKCBtYWNfY3AgKSkpCiAgICAgICAgbWFjX2NwdGFibGUgID0gd2luZV9jcF9nZXRfdGFibGUoIDEwMDAwICk7CiAgICBpZiAodW5peF9jcCAhPSBDUF9VVEY4KQogICAgewogICAgICAgIGlmICghKHVuaXhfY3B0YWJsZSA9IHdpbmVfY3BfZ2V0X3RhYmxlKCB1bml4X2NwICkpKQogICAgICAgICAgICB1bml4X2NwdGFibGUgID0gd2luZV9jcF9nZXRfdGFibGUoIDI4NTkxICk7CiAgICB9CgogICAgX193aW5lX2luaXRfY29kZXBhZ2VzKCBhbnNpX2NwdGFibGUsIG9lbV9jcHRhYmxlLCB1bml4X2NwdGFibGUgKTsKCiAgICBUUkFDRSggImFuc2k9JTAzZCBvZW09JTAzZCBtYWM9JTAzZCB1bml4PSUwM2RcbiIsCiAgICAgICAgICAgYW5zaV9jcHRhYmxlLT5pbmZvLmNvZGVwYWdlLCBvZW1fY3B0YWJsZS0+aW5mby5jb2RlcGFnZSwKICAgICAgICAgICBtYWNfY3B0YWJsZS0+aW5mby5jb2RlcGFnZSwgdW5peF9jcCApOwp9CgpzdGF0aWMgSEFORExFIE5MU19SZWdPcGVuS2V5KEhBTkRMRSBoUm9vdEtleSwgTFBDV1NUUiBzektleU5hbWUpCnsKICAgIFVOSUNPREVfU1RSSU5HIGtleU5hbWU7CiAgICBPQkpFQ1RfQVRUUklCVVRFUyBhdHRyOwogICAgSEFORExFIGhrZXk7CgogICAgUnRsSW5pdFVuaWNvZGVTdHJpbmcoICZrZXlOYW1lLCBzektleU5hbWUgKTsKICAgIEluaXRpYWxpemVPYmplY3RBdHRyaWJ1dGVzKCZhdHRyLCAma2V5TmFtZSwgMCwgaFJvb3RLZXksIE5VTEwpOwoKICAgIGlmIChOdE9wZW5LZXkoICZoa2V5LCBLRVlfQUxMX0FDQ0VTUywgJmF0dHIgKSAhPSBTVEFUVVNfU1VDQ0VTUykKICAgICAgICBoa2V5ID0gMDsKCiAgICByZXR1cm4gaGtleTsKfQoKc3RhdGljIEhBTkRMRSBOTFNfUmVnT3BlblN1YktleShIQU5ETEUgaFJvb3RLZXksIExQQ1dTVFIgc3pLZXlOYW1lKQp7CiAgICBIQU5ETEUgaEtleSA9IE5MU19SZWdPcGVuS2V5KGhSb290S2V5LCBzektleU5hbWUpOwoKICAgIGlmIChoUm9vdEtleSkKICAgICAgICBOdENsb3NlKCBoUm9vdEtleSApOwoKICAgIHJldHVybiBoS2V5Owp9CgpzdGF0aWMgQk9PTCBOTFNfUmVnRW51bVN1YktleShIQU5ETEUgaEtleSwgVUlOVCB1bEluZGV4LCBMUFdTVFIgc3pLZXlOYW1lLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBVTE9ORyBrZXlOYW1lU2l6ZSkKewogICAgQllURSBidWZmZXJbODBdOwogICAgS0VZX0JBU0lDX0lORk9STUFUSU9OICppbmZvID0gKEtFWV9CQVNJQ19JTkZPUk1BVElPTiAqKWJ1ZmZlcjsKICAgIERXT1JEIGR3TGVuOwoKICAgIGlmIChOdEVudW1lcmF0ZUtleSggaEtleSwgdWxJbmRleCwgS2V5QmFzaWNJbmZvcm1hdGlvbiwgYnVmZmVyLAogICAgICAgICAgICAgICAgICAgICAgICBzaXplb2YoYnVmZmVyKSwgJmR3TGVuKSAhPSBTVEFUVVNfU1VDQ0VTUyB8fAogICAgICAgIGluZm8tPk5hbWVMZW5ndGggPiBrZXlOYW1lU2l6ZSkKICAgIHsKICAgICAgICByZXR1cm4gRkFMU0U7CiAgICB9CgogICAgVFJBQ0UoImluZm8tPk5hbWUgJXMgaW5mby0+TmFtZUxlbmd0aCAlbGRcbiIsIGRlYnVnc3RyX3coaW5mby0+TmFtZSksIGluZm8tPk5hbWVMZW5ndGgpOwoKICAgIG1lbWNweSggc3pLZXlOYW1lLCBpbmZvLT5OYW1lLCBpbmZvLT5OYW1lTGVuZ3RoKTsKICAgIHN6S2V5TmFtZVtpbmZvLT5OYW1lTGVuZ3RoIC8gc2l6ZW9mKFdDSEFSKV0gPSAnXDAnOwoKICAgIFRSQUNFKCJyZXR1cm5pbmcgJXNcbiIsIGRlYnVnc3RyX3coc3pLZXlOYW1lKSk7CiAgICByZXR1cm4gVFJVRTsKfQoKc3RhdGljIEJPT0wgTkxTX1JlZ0VudW1WYWx1ZShIQU5ETEUgaEtleSwgVUlOVCB1bEluZGV4LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIExQV1NUUiBzelZhbHVlTmFtZSwgVUxPTkcgdmFsdWVOYW1lU2l6ZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMUFdTVFIgc3pWYWx1ZURhdGEsIFVMT05HIHZhbHVlRGF0YVNpemUpCnsKICAgIEJZVEUgYnVmZmVyWzgwXTsKICAgIEtFWV9WQUxVRV9GVUxMX0lORk9STUFUSU9OICppbmZvID0gKEtFWV9WQUxVRV9GVUxMX0lORk9STUFUSU9OICopYnVmZmVyOwogICAgRFdPUkQgZHdMZW47CgogICAgaWYgKE50RW51bWVyYXRlVmFsdWVLZXkoIGhLZXksIHVsSW5kZXgsIEtleVZhbHVlRnVsbEluZm9ybWF0aW9uLAogICAgICAgIGJ1ZmZlciwgc2l6ZW9mKGJ1ZmZlciksICZkd0xlbiApICE9IFNUQVRVU19TVUNDRVNTIHx8CiAgICAgICAgaW5mby0+TmFtZUxlbmd0aCA+IHZhbHVlTmFtZVNpemUgfHwKICAgICAgICBpbmZvLT5EYXRhTGVuZ3RoID4gdmFsdWVEYXRhU2l6ZSkKICAgIHsKICAgICAgICByZXR1cm4gRkFMU0U7CiAgICB9CgogICAgVFJBQ0UoImluZm8tPk5hbWUgJXMgaW5mby0+RGF0YUxlbmd0aCAlbGRcbiIsIGRlYnVnc3RyX3coaW5mby0+TmFtZSksIGluZm8tPkRhdGFMZW5ndGgpOwoKICAgIG1lbWNweSggc3pWYWx1ZU5hbWUsIGluZm8tPk5hbWUsIGluZm8tPk5hbWVMZW5ndGgpOwogICAgc3pWYWx1ZU5hbWVbaW5mby0+TmFtZUxlbmd0aCAvIHNpemVvZihXQ0hBUildID0gJ1wwJzsKICAgIG1lbWNweSggc3pWYWx1ZURhdGEsIGJ1ZmZlciArIGluZm8tPkRhdGFPZmZzZXQsIGluZm8tPkRhdGFMZW5ndGggKTsKICAgIHN6VmFsdWVEYXRhW2luZm8tPkRhdGFMZW5ndGggLyBzaXplb2YoV0NIQVIpXSA9ICdcMCc7CgogICAgVFJBQ0UoInJldHVybmluZyAlcyAlc1xuIiwgZGVidWdzdHJfdyhzelZhbHVlTmFtZSksIGRlYnVnc3RyX3coc3pWYWx1ZURhdGEpKTsKICAgIHJldHVybiBUUlVFOwp9CgpzdGF0aWMgQk9PTCBOTFNfUmVnR2V0RHdvcmQoSEFORExFIGhLZXksIExQQ1dTVFIgc3pWYWx1ZU5hbWUsIERXT1JEICpscFZhbCkKewogICAgQllURSBidWZmZXJbMTI4XTsKICAgIGNvbnN0IEtFWV9WQUxVRV9QQVJUSUFMX0lORk9STUFUSU9OICppbmZvID0gKEtFWV9WQUxVRV9QQVJUSUFMX0lORk9STUFUSU9OICopYnVmZmVyOwogICAgRFdPUkQgZHdTaXplID0gc2l6ZW9mKGJ1ZmZlcik7CiAgICBVTklDT0RFX1NUUklORyB2YWx1ZU5hbWU7CgogICAgUnRsSW5pdFVuaWNvZGVTdHJpbmcoICZ2YWx1ZU5hbWUsIHN6VmFsdWVOYW1lICk7CgogICAgVFJBQ0UoIiVwLCAlc1xuIiwgaEtleSwgZGVidWdzdHJfdyhzelZhbHVlTmFtZSkpOwogICAgaWYgKE50UXVlcnlWYWx1ZUtleSggaEtleSwgJnZhbHVlTmFtZSwgS2V5VmFsdWVQYXJ0aWFsSW5mb3JtYXRpb24sCiAgICAgICAgICAgICAgICAgICAgICAgICBidWZmZXIsIGR3U2l6ZSwgJmR3U2l6ZSApID09IFNUQVRVU19TVUNDRVNTICYmCiAgICAgICAgaW5mby0+RGF0YUxlbmd0aCA9PSBzaXplb2YoRFdPUkQpKQogICAgewogICAgICAgIG1lbWNweShscFZhbCwgaW5mby0+RGF0YSwgc2l6ZW9mKERXT1JEKSk7CiAgICAgICAgcmV0dXJuIFRSVUU7CiAgICB9CgogICAgcmV0dXJuIEZBTFNFOwp9CgpzdGF0aWMgQk9PTCBOTFNfR2V0TGFuZ3VhZ2VHcm91cE5hbWUoTEdSUElEIGxncnBpZCwgTFBXU1RSIHN6TmFtZSwgVUxPTkcgbmFtZVNpemUpCnsKICAgIExBTkdJRCAgbGFuZ0lkOwogICAgTFBDV1NUUiBzelJlc291cmNlTmFtZSA9IChMUENXU1RSKSgoKGxncnBpZCArIDB4MjAwMCkgPj4gNCkgKyAxKTsKICAgIEhSU1JDICAgaFJlc291cmNlOwogICAgQk9PTCAgICBiUmV0ID0gRkFMU0U7CgogICAgLyogRklYTUU6IElzIGl0IGNvcnJlY3QgdG8gdXNlIHRoZSBzeXN0ZW0gZGVmYXVsdCBsYW5naWQ/ICovCiAgICBsYW5nSWQgPSBHZXRTeXN0ZW1EZWZhdWx0TGFuZ0lEKCk7CgogICAgaWYgKFNVQkxBTkdJRChsYW5nSWQpID09IFNVQkxBTkdfTkVVVFJBTCkKICAgICAgICBsYW5nSWQgPSBNQUtFTEFOR0lEKCBQUklNQVJZTEFOR0lEKGxhbmdJZCksIFNVQkxBTkdfREVGQVVMVCApOwoKICAgIGhSZXNvdXJjZSA9IEZpbmRSZXNvdXJjZUV4Vygga2VybmVsMzJfaGFuZGxlLCAoTFBXU1RSKVJUX1NUUklORywgc3pSZXNvdXJjZU5hbWUsIGxhbmdJZCApOwoKICAgIGlmIChoUmVzb3VyY2UpCiAgICB7CiAgICAgICAgSEdMT0JBTCBoUmVzRGlyID0gTG9hZFJlc291cmNlKCBrZXJuZWwzMl9oYW5kbGUsIGhSZXNvdXJjZSApOwoKICAgICAgICBpZiAoaFJlc0RpcikKICAgICAgICB7CiAgICAgICAgICAgIFVMT05HICAgaVJlc291cmNlSW5kZXggPSBsZ3JwaWQgJiAweGY7CiAgICAgICAgICAgIExQQ1dTVFIgbHBSZXNFbnRyeSA9IExvY2tSZXNvdXJjZSggaFJlc0RpciApOwogICAgICAgICAgICBVTE9ORyAgIGk7CgogICAgICAgICAgICBmb3IgKGkgPSAwOyBpIDwgaVJlc291cmNlSW5kZXg7IGkrKykKICAgICAgICAgICAgICAgIGxwUmVzRW50cnkgKz0gKmxwUmVzRW50cnkgKyAxOwoKICAgICAgICAgICAgaWYgKCpscFJlc0VudHJ5IDwgbmFtZVNpemUpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIG1lbWNweSggc3pOYW1lLCBscFJlc0VudHJ5ICsgMSwgKmxwUmVzRW50cnkgKiBzaXplb2YoV0NIQVIpICk7CiAgICAgICAgICAgICAgICBzek5hbWVbKmxwUmVzRW50cnldID0gJ1wwJzsKICAgICAgICAgICAgICAgIGJSZXQgPSBUUlVFOwogICAgICAgICAgICB9CgogICAgICAgIH0KICAgICAgICBGcmVlUmVzb3VyY2UoIGhSZXNvdXJjZSApOwogICAgfQogICAgcmV0dXJuIGJSZXQ7Cn0KCi8qIFJlZ2lzdHJ5IGtleXMgZm9yIE5MUyByZWxhdGVkIGluZm9ybWF0aW9uICovCnN0YXRpYyBjb25zdCBXQ0hBUiBzekxhbmdHcm91cHNLZXlOYW1lW10gPSB7CiAgICAnTCcsJ2EnLCduJywnZycsJ3UnLCdhJywnZycsJ2UnLCcgJywnRycsJ3InLCdvJywndScsJ3AnLCdzJywnXDAnCn07CgpzdGF0aWMgY29uc3QgV0NIQVIgc3pDb3VudHJ5TGlzdE5hbWVbXSA9IHsKICAgICdNJywnYScsJ2MnLCdoJywnaScsJ24nLCdlJywnXFwnLCdTJywnbycsJ2YnLCd0JywndycsJ2EnLCdyJywnZScsJ1xcJywKICAgICdNJywnaScsJ2MnLCdyJywnbycsJ3MnLCdvJywnZicsJ3QnLCdcXCcsJ1cnLCdpJywnbicsJ2QnLCdvJywndycsJ3MnLCdcXCcsCiAgICAnQycsJ3UnLCdyJywncicsJ2UnLCduJywndCcsJ1YnLCdlJywncicsJ3MnLCdpJywnbycsJ24nLCdcXCcsCiAgICAnVCcsJ2UnLCdsJywnZScsJ3AnLCdoJywnbycsJ24nLCd5JywnXFwnLAogICAgJ0MnLCdvJywndScsJ24nLCd0JywncicsJ3knLCcgJywnTCcsJ2knLCdzJywndCcsJ1wwJwp9OwoKCi8qIENhbGxiYWNrIGZ1bmN0aW9uIHB0cnMgZm9yIEVudW1TeXN0ZW1MYW5ndWFnZUdyb3Vwc0EvVyAqLwp0eXBlZGVmIHN0cnVjdAp7CiAgTEFOR1VBR0VHUk9VUF9FTlVNUFJPQ0EgcHJvY0E7CiAgTEFOR1VBR0VHUk9VUF9FTlVNUFJPQ1cgcHJvY1c7CiAgRFdPUkQgICAgZHdGbGFnczsKICBMT05HX1BUUiBsUGFyYW07Cn0gRU5VTUxBTkdVQUdFR1JPVVBfQ0FMTEJBQ0tTOwoKLyogSW50ZXJuYWwgaW1wbGVtZW50YXRpb24gb2YgRW51bVN5c3RlbUxhbmd1YWdlR3JvdXBzQS9XICovCnN0YXRpYyBCT09MIE5MU19FbnVtU3lzdGVtTGFuZ3VhZ2VHcm91cHMoRU5VTUxBTkdVQUdFR1JPVVBfQ0FMTEJBQ0tTICpscFByb2NzKQp7CiAgICBXQ0hBUiBzek51bWJlclsxMF0sIHN6VmFsdWVbNF07CiAgICBIQU5ETEUgaEtleTsKICAgIEJPT0wgYkNvbnRpbnVlID0gVFJVRTsKICAgIFVMT05HIHVsSW5kZXggPSAwOwoKICAgIGlmICghbHBQcm9jcykKICAgIHsKICAgICAgICBTZXRMYXN0RXJyb3IoRVJST1JfSU5WQUxJRF9QQVJBTUVURVIpOwogICAgICAgIHJldHVybiBGQUxTRTsKICAgIH0KCiAgICBzd2l0Y2ggKGxwUHJvY3MtPmR3RmxhZ3MpCiAgICB7CiAgICBjYXNlIDA6CiAgICAgICAgLyogRGVmYXVsdCB0byBMR1JQSURfSU5TVEFMTEVEICovCiAgICAgICAgbHBQcm9jcy0+ZHdGbGFncyA9IExHUlBJRF9JTlNUQUxMRUQ7CiAgICAgICAgLyogRmFsbCB0aHJvdWdoLi4uICovCiAgICBjYXNlIExHUlBJRF9JTlNUQUxMRUQ6CiAgICBjYXNlIExHUlBJRF9TVVBQT1JURUQ6CiAgICAgICAgYnJlYWs7CiAgICBkZWZhdWx0OgogICAgICAgIFNldExhc3RFcnJvcihFUlJPUl9JTlZBTElEX0ZMQUdTKTsKICAgICAgICByZXR1cm4gRkFMU0U7CiAgICB9CgogICAgaEtleSA9IE5MU19SZWdPcGVuU3ViS2V5KCBOTFNfUmVnT3BlbktleSggMCwgc3pObHNLZXlOYW1lICksIHN6TGFuZ0dyb3Vwc0tleU5hbWUgKTsKCiAgICBpZiAoIWhLZXkpCiAgICAgICAgRklYTUUoIk5MUyByZWdpc3RyeSBrZXkgbm90IGZvdW5kLiBQbGVhc2UgYXBwbHkgdGhlIGRlZmF1bHQgcmVnaXN0cnkgZmlsZSAnd2luZS5pbmYnXG4iKTsKCiAgICB3aGlsZSAoYkNvbnRpbnVlKQogICAgewogICAgICAgIGlmIChOTFNfUmVnRW51bVZhbHVlKCBoS2V5LCB1bEluZGV4LCBzek51bWJlciwgc2l6ZW9mKHN6TnVtYmVyKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3pWYWx1ZSwgc2l6ZW9mKHN6VmFsdWUpICkpCiAgICAgICAgewogICAgICAgICAgICBCT09MIGJJbnN0YWxsZWQgPSBzelZhbHVlWzBdID09ICcxJyA/IFRSVUUgOiBGQUxTRTsKICAgICAgICAgICAgTEdSUElEIGxncnBpZCA9IHN0cnRvdWxXKCBzek51bWJlciwgTlVMTCwgMTYgKTsKCiAgICAgICAgICAgIFRSQUNFKCJncnBpZCAlcyAoJXNpbnN0YWxsZWQpXG4iLCBkZWJ1Z3N0cl93KHN6TnVtYmVyKSwKICAgICAgICAgICAgICAgICAgIGJJbnN0YWxsZWQgPyAiIiA6ICJub3QgIik7CgogICAgICAgICAgICBpZiAobHBQcm9jcy0+ZHdGbGFncyA9PSBMR1JQSURfU1VQUE9SVEVEIHx8IGJJbnN0YWxsZWQpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIFdDSEFSIHN6R3JwTmFtZVs0OF07CgogICAgICAgICAgICAgICAgaWYgKCFOTFNfR2V0TGFuZ3VhZ2VHcm91cE5hbWUoIGxncnBpZCwgc3pHcnBOYW1lLCBzaXplb2Yoc3pHcnBOYW1lKSAvIHNpemVvZihXQ0hBUikgKSkKICAgICAgICAgICAgICAgICAgICBzekdycE5hbWVbMF0gPSAnXDAnOwoKICAgICAgICAgICAgICAgIGlmIChscFByb2NzLT5wcm9jVykKICAgICAgICAgICAgICAgICAgICBiQ29udGludWUgPSBscFByb2NzLT5wcm9jVyggbGdycGlkLCBzek51bWJlciwgc3pHcnBOYW1lLCBscFByb2NzLT5kd0ZsYWdzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBscFByb2NzLT5sUGFyYW0gKTsKICAgICAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBjaGFyIHN6TnVtYmVyQVtzaXplb2Yoc3pOdW1iZXIpL3NpemVvZihXQ0hBUildOwogICAgICAgICAgICAgICAgICAgIGNoYXIgc3pHcnBOYW1lQVs0OF07CgogICAgICAgICAgICAgICAgICAgIC8qIEZJWE1FOiBNU0ROIGRvZXNuJ3Qgc2F5IHdoaWNoIGNvZGUgcGFnZSB0aGUgVy0+QSB0cmFuc2xhdGlvbiB1c2VzLAogICAgICAgICAgICAgICAgICAgICAqICAgICAgICBvciB3aGV0aGVyIHRoZSBsYW5ndWFnZSBuYW1lcyBhcmUgZXZlciBsb2NhbGlzZWQuIEFzc3VtZSBDUF9BQ1AuCiAgICAgICAgICAgICAgICAgICAgICovCgogICAgICAgICAgICAgICAgICAgIFdpZGVDaGFyVG9NdWx0aUJ5dGUoQ1BfQUNQLCAwLCBzek51bWJlciwgLTEsIHN6TnVtYmVyQSwgc2l6ZW9mKHN6TnVtYmVyQSksIDAsIDApOwogICAgICAgICAgICAgICAgICAgIFdpZGVDaGFyVG9NdWx0aUJ5dGUoQ1BfQUNQLCAwLCBzekdycE5hbWUsIC0xLCBzekdycE5hbWVBLCBzaXplb2Yoc3pHcnBOYW1lQSksIDAsIDApOwoKICAgICAgICAgICAgICAgICAgICBiQ29udGludWUgPSBscFByb2NzLT5wcm9jQSggbGdycGlkLCBzek51bWJlckEsIHN6R3JwTmFtZUEsIGxwUHJvY3MtPmR3RmxhZ3MsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxwUHJvY3MtPmxQYXJhbSApOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CgogICAgICAgICAgICB1bEluZGV4Kys7CiAgICAgICAgfQogICAgICAgIGVsc2UKICAgICAgICAgICAgYkNvbnRpbnVlID0gRkFMU0U7CgogICAgICAgIGlmICghYkNvbnRpbnVlKQogICAgICAgICAgICBicmVhazsKICAgIH0KCiAgICBpZiAoaEtleSkKICAgICAgICBOdENsb3NlKCBoS2V5ICk7CgogICAgcmV0dXJuIFRSVUU7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICAgICAgIEVudW1TeXN0ZW1MYW5ndWFnZUdyb3Vwc0EgICAgKEtFUk5FTDMyLkApCiAqCiAqIENhbGwgYSB1c2VycyBmdW5jdGlvbiBmb3IgZWFjaCBsYW5ndWFnZSBncm91cCBhdmFpbGFibGUgb24gdGhlIHN5c3RlbS4KICoKICogUEFSQU1TCiAqICBwTGFuZ0dycEVudW1Qcm9jIFtJXSBDYWxsYmFjayBmdW5jdGlvbiB0byBjYWxsIGZvciBlYWNoIGxhbmd1YWdlIGdyb3VwCiAqICBkd0ZsYWdzICAgICAgICAgIFtJXSBMR1JQSURfU1VQUE9SVEVEPUFsbCBTdXBwb3J0ZWQsIExHUlBJRF9JTlNUQUxMRUQ9SW5zdGFsbGVkIG9ubHkKICogIGxQYXJhbSAgICAgICAgICAgW0ldIFVzZXIgcGFyYW1ldGVyIHRvIHBhc3MgdG8gcExhbmdHcnBFbnVtUHJvYwogKgogKiBSRVRVUk5TCiAqICBTdWNjZXNzOiBUUlVFLgogKiAgRmFpbHVyZTogRkFMU0UuIFVzZSBHZXRMYXN0RXJyb3IoKSB0byBkZXRlcm1pbmUgdGhlIGNhdXNlLgogKi8KQk9PTCBXSU5BUEkgRW51bVN5c3RlbUxhbmd1YWdlR3JvdXBzQShMQU5HVUFHRUdST1VQX0VOVU1QUk9DQSBwTGFuZ0dycEVudW1Qcm9jLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIERXT1JEIGR3RmxhZ3MsIExPTkdfUFRSIGxQYXJhbSkKewogICAgRU5VTUxBTkdVQUdFR1JPVVBfQ0FMTEJBQ0tTIHByb2NzOwoKICAgIFRSQUNFKCIoJXAsMHglMDhsWCwweCUwOGxYKVxuIiwgcExhbmdHcnBFbnVtUHJvYywgZHdGbGFncywgbFBhcmFtKTsKCiAgICBwcm9jcy5wcm9jQSA9IHBMYW5nR3JwRW51bVByb2M7CiAgICBwcm9jcy5wcm9jVyA9IE5VTEw7CiAgICBwcm9jcy5kd0ZsYWdzID0gZHdGbGFnczsKICAgIHByb2NzLmxQYXJhbSA9IGxQYXJhbTsKCiAgICByZXR1cm4gTkxTX0VudW1TeXN0ZW1MYW5ndWFnZUdyb3VwcyggcExhbmdHcnBFbnVtUHJvYyA/ICZwcm9jcyA6IE5VTEwpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgICAgICBFbnVtU3lzdGVtTGFuZ3VhZ2VHcm91cHNXICAgIChLRVJORUwzMi5AKQogKgogKiBTZWUgRW51bVN5c3RlbUxhbmd1YWdlR3JvdXBzQS4KICovCkJPT0wgV0lOQVBJIEVudW1TeXN0ZW1MYW5ndWFnZUdyb3Vwc1coTEFOR1VBR0VHUk9VUF9FTlVNUFJPQ1cgcExhbmdHcnBFbnVtUHJvYywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEV09SRCBkd0ZsYWdzLCBMT05HX1BUUiBsUGFyYW0pCnsKICAgIEVOVU1MQU5HVUFHRUdST1VQX0NBTExCQUNLUyBwcm9jczsKCiAgICBUUkFDRSgiKCVwLDB4JTA4bFgsMHglMDhsWClcbiIsIHBMYW5nR3JwRW51bVByb2MsIGR3RmxhZ3MsIGxQYXJhbSk7CgogICAgcHJvY3MucHJvY0EgPSBOVUxMOwogICAgcHJvY3MucHJvY1cgPSBwTGFuZ0dycEVudW1Qcm9jOwogICAgcHJvY3MuZHdGbGFncyA9IGR3RmxhZ3M7CiAgICBwcm9jcy5sUGFyYW0gPSBsUGFyYW07CgogICAgcmV0dXJuIE5MU19FbnVtU3lzdGVtTGFuZ3VhZ2VHcm91cHMoIHBMYW5nR3JwRW51bVByb2MgPyAmcHJvY3MgOiBOVUxMKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgICAgICAgSXNWYWxpZExhbmd1YWdlR3JvdXAgICAgKEtFUk5FTDMyLkApCiAqCiAqIERldGVybWluZSBpZiBhIGxhbmd1YWdlIGdyb3VwIGlzIHN1cHBvcnRlZCBhbmQvb3IgaW5zdGFsbGVkLgogKgogKiBQQVJBTVMKICogIGxncnBpZCAgW0ldIExhbmd1YWdlIEdyb3VwIElkIChMR1JQSURfIHZhbHVlcyBmcm9tICJ3aW5ubHMuaCIpCiAqICBkd0ZsYWdzIFtJXSBMR1JQSURfU1VQUE9SVEVEPVN1cHBvcnRlZCwgTEdSUElEX0lOU1RBTExFRD1JbnN0YWxsZWQKICoKICogUkVUVVJOUwogKiAgVFJVRSwgaWYgbGdycGlkIGlzIHN1cHBvcnRlZCBhbmQvb3IgaW5zdGFsbGVkLCBhY2NvcmRpbmcgdG8gZHdGbGFncy4KICogIEZBTFNFIG90aGVyd2lzZS4KICovCkJPT0wgV0lOQVBJIElzVmFsaWRMYW5ndWFnZUdyb3VwKExHUlBJRCBsZ3JwaWQsIERXT1JEIGR3RmxhZ3MpCnsKICAgIHN0YXRpYyBjb25zdCBXQ0hBUiBzekZvcm1hdFtdID0geyAnJScsJ3gnLCdcMCcgfTsKICAgIFdDSEFSIHN6VmFsdWVOYW1lWzE2XSwgc3pWYWx1ZVsyXTsKICAgIEJPT0wgYlN1cHBvcnRlZCA9IEZBTFNFLCBiSW5zdGFsbGVkID0gRkFMU0U7CiAgICBIQU5ETEUgaEtleTsKCgogICAgc3dpdGNoIChkd0ZsYWdzKQogICAgewogICAgY2FzZSBMR1JQSURfSU5TVEFMTEVEOgogICAgY2FzZSBMR1JQSURfU1VQUE9SVEVEOgoKICAgICAgICBoS2V5ID0gTkxTX1JlZ09wZW5TdWJLZXkoIE5MU19SZWdPcGVuS2V5KCAwLCBzek5sc0tleU5hbWUgKSwgc3pMYW5nR3JvdXBzS2V5TmFtZSApOwoKICAgICAgICBzcHJpbnRmVyggc3pWYWx1ZU5hbWUsIHN6Rm9ybWF0LCBsZ3JwaWQgKTsKCiAgICAgICAgaWYgKE5MU19SZWdHZXREd29yZCggaEtleSwgc3pWYWx1ZU5hbWUsIChMUERXT1JEKSZzelZhbHVlICkpCiAgICAgICAgewogICAgICAgICAgICBiU3VwcG9ydGVkID0gVFJVRTsKCiAgICAgICAgICAgIGlmIChzelZhbHVlWzBdID09ICcxJykKICAgICAgICAgICAgICAgIGJJbnN0YWxsZWQgPSBUUlVFOwogICAgICAgIH0KCiAgICAgICAgaWYgKGhLZXkpCiAgICAgICAgICAgIE50Q2xvc2UoIGhLZXkgKTsKCiAgICAgICAgYnJlYWs7CiAgICB9CgogICAgaWYgKChkd0ZsYWdzID09IExHUlBJRF9TVVBQT1JURUQgJiYgYlN1cHBvcnRlZCkgfHwKICAgICAgICAoZHdGbGFncyA9PSBMR1JQSURfSU5TVEFMTEVEICYmIGJJbnN0YWxsZWQpKQogICAgICAgIHJldHVybiBUUlVFOwoKICAgIHJldHVybiBGQUxTRTsKfQoKLyogQ2FsbGJhY2sgZnVuY3Rpb24gcHRycyBmb3IgRW51bUxhbmd1YWdlR3JvdXBsb2NhbGVzQS9XICovCnR5cGVkZWYgc3RydWN0CnsKICBMQU5HR1JPVVBMT0NBTEVfRU5VTVBST0NBIHByb2NBOwogIExBTkdHUk9VUExPQ0FMRV9FTlVNUFJPQ1cgcHJvY1c7CiAgRFdPUkQgICAgZHdGbGFnczsKICBMR1JQSUQgICBsZ3JwaWQ7CiAgTE9OR19QVFIgbFBhcmFtOwp9IEVOVU1MQU5HVUFHRUdST1VQTE9DQUxFX0NBTExCQUNLUzsKCi8qIEludGVybmFsIGltcGxlbWVudGF0aW9uIG9mIEVudW1MYW5ndWFnZUdyb3VwbG9jYWxlc0EvVyAqLwpzdGF0aWMgQk9PTCBOTFNfRW51bUxhbmd1YWdlR3JvdXBMb2NhbGVzKEVOVU1MQU5HVUFHRUdST1VQTE9DQUxFX0NBTExCQUNLUyAqbHBQcm9jcykKewogICAgc3RhdGljIGNvbnN0IFdDSEFSIHN6TG9jYWxlS2V5TmFtZVtdID0gewogICAgICAnTCcsJ28nLCdjJywnYScsJ2wnLCdlJywnXDAnCiAgICB9OwogICAgc3RhdGljIGNvbnN0IFdDSEFSIHN6QWx0ZXJuYXRlU29ydHNLZXlOYW1lW10gPSB7CiAgICAgICdBJywnbCcsJ3QnLCdlJywncicsJ24nLCdhJywndCcsJ2UnLCcgJywnUycsJ28nLCdyJywndCcsJ3MnLCdcMCcKICAgIH07CiAgICBXQ0hBUiBzek51bWJlclsxMF0sIHN6VmFsdWVbNF07CiAgICBIQU5ETEUgaEtleTsKICAgIEJPT0wgYkNvbnRpbnVlID0gVFJVRSwgYkFsdGVybmF0ZSA9IEZBTFNFOwogICAgTEdSUElEIGxncnBpZDsKICAgIFVMT05HIHVsSW5kZXggPSAxOyAgLyogSWdub3JlIGRlZmF1bHQgZW50cnkgb2YgMXN0IGtleSAqLwoKICAgIGlmICghbHBQcm9jcyB8fCAhbHBQcm9jcy0+bGdycGlkIHx8IGxwUHJvY3MtPmxncnBpZCA+IExHUlBJRF9BUk1FTklBTikKICAgIHsKICAgICAgICBTZXRMYXN0RXJyb3IoRVJST1JfSU5WQUxJRF9QQVJBTUVURVIpOwogICAgICAgIHJldHVybiBGQUxTRTsKICAgIH0KCiAgICBpZiAobHBQcm9jcy0+ZHdGbGFncykKICAgIHsKICAgICAgICBTZXRMYXN0RXJyb3IoRVJST1JfSU5WQUxJRF9GTEFHUyk7CiAgICAgICAgcmV0dXJuIEZBTFNFOwogICAgfQoKICAgIGhLZXkgPSBOTFNfUmVnT3BlblN1YktleSggTkxTX1JlZ09wZW5LZXkoIDAsIHN6TmxzS2V5TmFtZSApLCBzekxvY2FsZUtleU5hbWUgKTsKCiAgICBpZiAoIWhLZXkpCiAgICAgICAgV0FSTigiTkxTIHJlZ2lzdHJ5IGtleSBub3QgZm91bmQuIFBsZWFzZSBhcHBseSB0aGUgZGVmYXVsdCByZWdpc3RyeSBmaWxlICd3aW5lLmluZidcbiIpOwoKICAgIHdoaWxlIChiQ29udGludWUpCiAgICB7CiAgICAgICAgaWYgKE5MU19SZWdFbnVtVmFsdWUoIGhLZXksIHVsSW5kZXgsIHN6TnVtYmVyLCBzaXplb2Yoc3pOdW1iZXIpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzelZhbHVlLCBzaXplb2Yoc3pWYWx1ZSkgKSkKICAgICAgICB7CiAgICAgICAgICAgIGxncnBpZCA9IHN0cnRvdWxXKCBzelZhbHVlLCBOVUxMLCAxNiApOwoKICAgICAgICAgICAgVFJBQ0UoImxjaWQgJXMsIGdycGlkICVsZCAoJXNtYXRjaGVkKVxuIiwgZGVidWdzdHJfdyhzek51bWJlciksCiAgICAgICAgICAgICAgICAgICBsZ3JwaWQsIGxncnBpZCA9PSBscFByb2NzLT5sZ3JwaWQgPyAiIiA6ICJub3QgIik7CgogICAgICAgICAgICBpZiAobGdycGlkID09IGxwUHJvY3MtPmxncnBpZCkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgTENJRCBsY2lkOwoKICAgICAgICAgICAgICAgIGxjaWQgPSBzdHJ0b3VsVyggc3pOdW1iZXIsIE5VTEwsIDE2ICk7CgogICAgICAgICAgICAgICAgLyogRklYTUU6IG5hdGl2ZSByZXR1cm5zIGV4dHJhIHRleHQgZm9yIGEgZmV3ICgxNy8xNTApIGxvY2FsZXMsIGUuZzoKICAgICAgICAgICAgICAgICAqICcwMDAwMDQzNyAgICAgICAgICA7R2VvcmdpYW4nCiAgICAgICAgICAgICAgICAgKiBBdCBwcmVzZW50IHdlIG9ubHkgcGFzcyB0aGUgTENJRCBzdHJpbmcuCiAgICAgICAgICAgICAgICAgKi8KCiAgICAgICAgICAgICAgICBpZiAobHBQcm9jcy0+cHJvY1cpCiAgICAgICAgICAgICAgICAgICAgYkNvbnRpbnVlID0gbHBQcm9jcy0+cHJvY1coIGxncnBpZCwgbGNpZCwgc3pOdW1iZXIsIGxwUHJvY3MtPmxQYXJhbSApOwogICAgICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIGNoYXIgc3pOdW1iZXJBW3NpemVvZihzek51bWJlcikvc2l6ZW9mKFdDSEFSKV07CgogICAgICAgICAgICAgICAgICAgIFdpZGVDaGFyVG9NdWx0aUJ5dGUoQ1BfQUNQLCAwLCBzek51bWJlciwgLTEsIHN6TnVtYmVyQSwgc2l6ZW9mKHN6TnVtYmVyQSksIDAsIDApOwoKICAgICAgICAgICAgICAgICAgICBiQ29udGludWUgPSBscFByb2NzLT5wcm9jQSggbGdycGlkLCBsY2lkLCBzek51bWJlckEsIGxwUHJvY3MtPmxQYXJhbSApOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CgogICAgICAgICAgICB1bEluZGV4Kys7CiAgICAgICAgfQogICAgICAgIGVsc2UKICAgICAgICB7CiAgICAgICAgICAgIC8qIEZpbmlzaGVkIGVudW1lcmF0aW5nIHRoaXMga2V5ICovCiAgICAgICAgICAgIGlmICghYkFsdGVybmF0ZSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgLyogRW51bWVyYXRlIGFsdGVybmF0ZSBzb3J0cyBhbHNvICovCiAgICAgICAgICAgICAgICBoS2V5ID0gTkxTX1JlZ09wZW5LZXkoIGhLZXksIHN6QWx0ZXJuYXRlU29ydHNLZXlOYW1lICk7CiAgICAgICAgICAgICAgICBiQWx0ZXJuYXRlID0gVFJVRTsKICAgICAgICAgICAgICAgIHVsSW5kZXggPSAwOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgIGJDb250aW51ZSA9IEZBTFNFOyAvKiBGaW5pc2hlZCBib3RoIGtleXMgKi8KICAgICAgICB9CgogICAgICAgIGlmICghYkNvbnRpbnVlKQogICAgICAgICAgICBicmVhazsKICAgIH0KCiAgICBpZiAoaEtleSkKICAgICAgICBOdENsb3NlKCBoS2V5ICk7CgogICAgcmV0dXJuIFRSVUU7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICAgICAgIEVudW1MYW5ndWFnZUdyb3VwTG9jYWxlc0EgICAgKEtFUk5FTDMyLkApCiAqCiAqIENhbGwgYSB1c2VycyBmdW5jdGlvbiBmb3IgZXZlcnkgbG9jYWxlIGluIGEgbGFuZ3VhZ2UgZ3JvdXAgYXZhaWxhYmxlIG9uIHRoZSBzeXN0ZW0uCiAqCiAqIFBBUkFNUwogKiAgcExhbmdHcnBMY0VudW1Qcm9jIFtJXSBDYWxsYmFjayBmdW5jdGlvbiB0byBjYWxsIGZvciBlYWNoIGxvY2FsZQogKiAgbGdycGlkICAgICAgICAgICAgIFtJXSBMYW5ndWFnZSBncm91cCAoTEdSUElEXyB2YWx1ZXMgZnJvbSAid2lubmxzLmgiKQogKiAgZHdGbGFncyAgICAgICAgICAgIFtJXSBSZXNlcnZlZCwgc2V0IHRvIDAKICogIGxQYXJhbSAgICAgICAgICAgICBbSV0gVXNlciBwYXJhbWV0ZXIgdG8gcGFzcyB0byBwTGFuZ0dycExjRW51bVByb2MKICoKICogUkVUVVJOUwogKiAgU3VjY2VzczogVFJVRS4KICogIEZhaWx1cmU6IEZBTFNFLiBVc2UgR2V0TGFzdEVycm9yKCkgdG8gZGV0ZXJtaW5lIHRoZSBjYXVzZS4KICovCkJPT0wgV0lOQVBJIEVudW1MYW5ndWFnZUdyb3VwTG9jYWxlc0EoTEFOR0dST1VQTE9DQUxFX0VOVU1QUk9DQSBwTGFuZ0dycExjRW51bVByb2MsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTEdSUElEIGxncnBpZCwgRFdPUkQgZHdGbGFncywgTE9OR19QVFIgbFBhcmFtKQp7CiAgICBFTlVNTEFOR1VBR0VHUk9VUExPQ0FMRV9DQUxMQkFDS1MgY2FsbGJhY2tzOwoKICAgIFRSQUNFKCIoJXAsMHglMDhsWCwweCUwOGxYLDB4JTA4bFgpXG4iLCBwTGFuZ0dycExjRW51bVByb2MsIGxncnBpZCwgZHdGbGFncywgbFBhcmFtKTsKCiAgICBjYWxsYmFja3MucHJvY0EgICA9IHBMYW5nR3JwTGNFbnVtUHJvYzsKICAgIGNhbGxiYWNrcy5wcm9jVyAgID0gTlVMTDsKICAgIGNhbGxiYWNrcy5kd0ZsYWdzID0gZHdGbGFnczsKICAgIGNhbGxiYWNrcy5sZ3JwaWQgID0gbGdycGlkOwogICAgY2FsbGJhY2tzLmxQYXJhbSAgPSBsUGFyYW07CgogICAgcmV0dXJuIE5MU19FbnVtTGFuZ3VhZ2VHcm91cExvY2FsZXMoIHBMYW5nR3JwTGNFbnVtUHJvYyA/ICZjYWxsYmFja3MgOiBOVUxMICk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICAgICAgIEVudW1MYW5ndWFnZUdyb3VwTG9jYWxlc1cgICAgKEtFUk5FTDMyLkApCiAqCiAqIFNlZSBFbnVtTGFuZ3VhZ2VHcm91cExvY2FsZXNBLgogKi8KQk9PTCBXSU5BUEkgRW51bUxhbmd1YWdlR3JvdXBMb2NhbGVzVyhMQU5HR1JPVVBMT0NBTEVfRU5VTVBST0NXIHBMYW5nR3JwTGNFbnVtUHJvYywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMR1JQSUQgbGdycGlkLCBEV09SRCBkd0ZsYWdzLCBMT05HX1BUUiBsUGFyYW0pCnsKICAgIEVOVU1MQU5HVUFHRUdST1VQTE9DQUxFX0NBTExCQUNLUyBjYWxsYmFja3M7CgogICAgVFJBQ0UoIiglcCwweCUwOGxYLDB4JTA4bFgsMHglMDhsWClcbiIsIHBMYW5nR3JwTGNFbnVtUHJvYywgbGdycGlkLCBkd0ZsYWdzLCBsUGFyYW0pOwoKICAgIGNhbGxiYWNrcy5wcm9jQSAgID0gTlVMTDsKICAgIGNhbGxiYWNrcy5wcm9jVyAgID0gcExhbmdHcnBMY0VudW1Qcm9jOwogICAgY2FsbGJhY2tzLmR3RmxhZ3MgPSBkd0ZsYWdzOwogICAgY2FsbGJhY2tzLmxncnBpZCAgPSBsZ3JwaWQ7CiAgICBjYWxsYmFja3MubFBhcmFtICA9IGxQYXJhbTsKCiAgICByZXR1cm4gTkxTX0VudW1MYW5ndWFnZUdyb3VwTG9jYWxlcyggcExhbmdHcnBMY0VudW1Qcm9jID8gJmNhbGxiYWNrcyA6IE5VTEwgKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgICAgICAgRW51bVN5c3RlbUdlb0lEICAgIChLRVJORUwzMi5AKQogKgogKiBDYWxsIGEgdXNlcnMgZnVuY3Rpb24gZm9yIGV2ZXJ5IGxvY2F0aW9uIGF2YWlsYWJsZSBvbiB0aGUgc3lzdGVtLgogKgogKiBQQVJBTVMKICogIGdlb2NsYXNzICAgICBbSV0gVHlwZSBvZiBpbmZvcm1hdGlvbiBkZXNpcmVkIChTWVNHRU9UWVBFIGVudW0gZnJvbSAid2lubmxzLmgiKQogKiAgcmVzZXJ2ZWQgICAgIFtJXSBSZXNlcnZlZCwgc2V0IHRvIDAKICogIHBHZW9FbnVtUHJvYyBbSV0gQ2FsbGJhY2sgZnVuY3Rpb24gdG8gY2FsbCBmb3IgZWFjaCBsb2NhdGlvbgogKgogKiBSRVRVUk5TCiAqICBTdWNjZXNzOiBUUlVFLgogKiAgRmFpbHVyZTogRkFMU0UuIFVzZSBHZXRMYXN0RXJyb3IoKSB0byBkZXRlcm1pbmUgdGhlIGNhdXNlLgogKi8KQk9PTCBXSU5BUEkgRW51bVN5c3RlbUdlb0lEKEdFT0NMQVNTIGdlb2NsYXNzLCBHRU9JRCByZXNlcnZlZCwgR0VPX0VOVU1QUk9DIHBHZW9FbnVtUHJvYykKewogICAgc3RhdGljIGNvbnN0IFdDSEFSIHN6Q291bnRyeUNvZGVWYWx1ZU5hbWVbXSA9IHsKICAgICAgJ0MnLCdvJywndScsJ24nLCd0JywncicsJ3knLCdDJywnbycsJ2QnLCdlJywnXDAnCiAgICB9OwogICAgV0NIQVIgc3pOdW1iZXJbMTBdOwogICAgSEFORExFIGhLZXk7CiAgICBVTE9ORyB1bEluZGV4ID0gMDsKCiAgICBUUkFDRSgiKDB4JTA4bFgsMHglMDhsWCwlcClcbiIsIGdlb2NsYXNzLCByZXNlcnZlZCwgcEdlb0VudW1Qcm9jKTsKCiAgICBpZiAoZ2VvY2xhc3MgIT0gR0VPQ0xBU1NfTkFUSU9OIHx8IHJlc2VydmVkIHx8ICFwR2VvRW51bVByb2MpCiAgICB7CiAgICAgICAgU2V0TGFzdEVycm9yKEVSUk9SX0lOVkFMSURfUEFSQU1FVEVSKTsKICAgICAgICByZXR1cm4gRkFMU0U7CiAgICB9CgogICAgaEtleSA9IE5MU19SZWdPcGVuS2V5KCAwLCBzekNvdW50cnlMaXN0TmFtZSApOwoKICAgIHdoaWxlIChOTFNfUmVnRW51bVN1YktleSggaEtleSwgdWxJbmRleCwgc3pOdW1iZXIsIHNpemVvZihzek51bWJlcikgKSkKICAgIHsKICAgICAgICBCT09MIGJDb250aW51ZSA9IFRSVUU7CiAgICAgICAgRFdPUkQgZHdHZW9JZDsKICAgICAgICBIQU5ETEUgaFN1YktleSA9IE5MU19SZWdPcGVuS2V5KCBoS2V5LCBzek51bWJlciApOwoKICAgICAgICBpZiAoaFN1YktleSkKICAgICAgICB7CiAgICAgICAgICAgIGlmIChOTFNfUmVnR2V0RHdvcmQoIGhTdWJLZXksIHN6Q291bnRyeUNvZGVWYWx1ZU5hbWUsICZkd0dlb0lkICkpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIFRSQUNFKCJHb3QgZ2VvaWQgJWxkXG4iLCBkd0dlb0lkKTsKCiAgICAgICAgICAgICAgICBpZiAoIXBHZW9FbnVtUHJvYyggZHdHZW9JZCApKQogICAgICAgICAgICAgICAgICAgIGJDb250aW51ZSA9IEZBTFNFOwogICAgICAgICAgICB9CgogICAgICAgICAgICBOdENsb3NlKCBoU3ViS2V5ICk7CiAgICAgICAgfQoKICAgICAgICBpZiAoIWJDb250aW51ZSkKICAgICAgICAgICAgYnJlYWs7CgogICAgICAgIHVsSW5kZXgrKzsKICAgIH0KCiAgICBpZiAoaEtleSkKICAgICAgICBOdENsb3NlKCBoS2V5ICk7CgogICAgcmV0dXJuIFRSVUU7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICAgICAgIEludmFsaWRhdGVOTFNDYWNoZSAgICAgICAgICAgKEtFUk5FTDMyLkApCiAqCiAqIEludmFsaWRhdGUgdGhlIGNhY2hlIG9mIE5MUyB2YWx1ZXMuCiAqCiAqIFBBUkFNUwogKiAgTm9uZS4KICoKICogUkVUVVJOUwogKiAgU3VjY2VzczogVFJVRS4KICogIEZhaWx1cmU6IEZBTFNFLgogKi8KQk9PTCBXSU5BUEkgSW52YWxpZGF0ZU5MU0NhY2hlKHZvaWQpCnsKICBGSVhNRSgiKCkgc3R1YlxuIik7CiAgcmV0dXJuIEZBTFNFOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgICAgICBHZXRVc2VyR2VvSUQgKEtFUk5FTDMyLkApCiAqLwpHRU9JRCBXSU5BUEkgR2V0VXNlckdlb0lEKCBHRU9DTEFTUyBHZW9DbGFzcyApCnsKICAgIEZJWE1FKCIlbGRcbiIsR2VvQ2xhc3MpOwogICAgcmV0dXJuIEdFT0lEX05PVF9BVkFJTEFCTEU7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICAgICAgIFNldFVzZXJHZW9JRCAoS0VSTkVMMzIuQCkKICovCkJPT0wgV0lOQVBJIFNldFVzZXJHZW9JRCggR0VPSUQgR2VvSUQgKQp7CiAgICBGSVhNRSgiJWxkXG4iLEdlb0lEKTsKICAgIHJldHVybiBGQUxTRTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgICAgICAgRW51bVVJTGFuZ3VhZ2VzQSAoS0VSTkVMMzIuQCkKICovCkJPT0wgV0lOQVBJIEVudW1VSUxhbmd1YWdlc0EoVUlMQU5HVUFHRV9FTlVNUFJPQ0EgcFVJTGFuZ0VudW1Qcm9jLCBEV09SRCBkd0ZsYWdzLCBMT05HX1BUUiBsUGFyYW0pCnsKICAgIHN0YXRpYyBjaGFyIHZhbHVlW10gPSAiMDQwOSI7CgogICAgaWYoIXBVSUxhbmdFbnVtUHJvYykgewoJU2V0TGFzdEVycm9yKEVSUk9SX0lOVkFMSURfUEFSQU1FVEVSKTsKCXJldHVybiBGQUxTRTsKICAgIH0KICAgIGlmKGR3RmxhZ3MpIHsKCVNldExhc3RFcnJvcihFUlJPUl9JTlZBTElEX0ZMQUdTKTsKCXJldHVybiBGQUxTRTsKICAgIH0KCiAgICBGSVhNRSgiJXAsICVseCwgJWx4IGNhbGxpbmcgcFVJTGFuZ0VudW1Qcm9jIHdpdGggJXNcbiIsCiAgICAgICAgICBwVUlMYW5nRW51bVByb2MsIGR3RmxhZ3MsIGxQYXJhbSwgZGVidWdzdHJfYSh2YWx1ZSkpOwoKICAgIHBVSUxhbmdFbnVtUHJvYyggdmFsdWUsIGxQYXJhbSApOwogICAgcmV0dXJuKFRSVUUpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgICAgICBFbnVtVUlMYW5ndWFnZXNXIChLRVJORUwzMi5AKQogKi8KQk9PTCBXSU5BUEkgRW51bVVJTGFuZ3VhZ2VzVyhVSUxBTkdVQUdFX0VOVU1QUk9DVyBwVUlMYW5nRW51bVByb2MsIERXT1JEIGR3RmxhZ3MsIExPTkdfUFRSIGxQYXJhbSkKewogICAgc3RhdGljIFdDSEFSIHZhbHVlW10gPSB7JzAnLCc0JywnMCcsJzknLDB9OwoKICAgIGlmKCFwVUlMYW5nRW51bVByb2MpIHsKCVNldExhc3RFcnJvcihFUlJPUl9JTlZBTElEX1BBUkFNRVRFUik7CglyZXR1cm4gRkFMU0U7CiAgICB9CiAgICBpZihkd0ZsYWdzKSB7CglTZXRMYXN0RXJyb3IoRVJST1JfSU5WQUxJRF9GTEFHUyk7CglyZXR1cm4gRkFMU0U7CiAgICB9CgogICAgRklYTUUoIiVwLCAlbHgsICVseCBjYWxsaW5nIHBVSUxhbmdFbnVtUHJvYyB3aXRoICVzXG4iLAogICAgICAgICAgcFVJTGFuZ0VudW1Qcm9jLCBkd0ZsYWdzLCBsUGFyYW0sIGRlYnVnc3RyX3codmFsdWUpKTsKCiAgICBwVUlMYW5nRW51bVByb2MoIHZhbHVlLCBsUGFyYW0gKTsKICAgIHJldHVybihUUlVFKTsKfQoKSU5UIFdJTkFQSSBHZXRHZW9JbmZvVyhHRU9JRCBHZW9JZCwgR0VPVFlQRSBHZW9UeXBlLCBMUFdTVFIgbHBHZW9EYXRhLCAKICAgICAgICAgICAgICAgIGludCBjY2hEYXRhLCBMQU5HSUQgbGFuZ3VhZ2UpCnsKICAgIEZJWE1FKCIlbGQgJWxkICVwICVkICVkXG4iLCBHZW9JZCwgR2VvVHlwZSwgbHBHZW9EYXRhLCBjY2hEYXRhLCBsYW5ndWFnZSk7CiAgICByZXR1cm4gMDsKfQoKSU5UIFdJTkFQSSBHZXRHZW9JbmZvQShHRU9JRCBHZW9JZCwgR0VPVFlQRSBHZW9UeXBlLCBMUFNUUiBscEdlb0RhdGEsIAogICAgICAgICAgICAgICAgaW50IGNjaERhdGEsIExBTkdJRCBsYW5ndWFnZSkKewogICAgRklYTUUoIiVsZCAlbGQgJXAgJWQgJWRcbiIsIEdlb0lkLCBHZW9UeXBlLCBscEdlb0RhdGEsIGNjaERhdGEsIGxhbmd1YWdlKTsKICAgIHJldHVybiAwOwp9Cg==