LyoKICogTG9jYWxlIHN1cHBvcnQKICoKICogQ29weXJpZ2h0IDE5OTUgTWFydGluIHZvbiBMb2V3aXMKICogQ29weXJpZ2h0IDE5OTggRGF2aWQgTGVlIExhbWJlcnQKICogQ29weXJpZ2h0IDIwMDAgSnVsaW8gQ+lzYXIgR+F6cXVlegogKiBDb3B5cmlnaHQgMjAwMiBBbGV4YW5kcmUgSnVsbGlhcmQgZm9yIENvZGVXZWF2ZXJzCiAqCiAqIFRoaXMgbGlicmFyeSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IKICogbW9kaWZ5IGl0IHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpYwogKiBMaWNlbnNlIGFzIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uOyBlaXRoZXIKICogdmVyc2lvbiAyLjEgb2YgdGhlIExpY2Vuc2UsIG9yIChhdCB5b3VyIG9wdGlvbikgYW55IGxhdGVyIHZlcnNpb24uCiAqCiAqIFRoaXMgbGlicmFyeSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLAogKiBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZgogKiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVQogKiBMZXNzZXIgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBmb3IgbW9yZSBkZXRhaWxzLgogKgogKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljCiAqIExpY2Vuc2UgYWxvbmcgd2l0aCB0aGlzIGxpYnJhcnk7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUKICogRm91bmRhdGlvbiwgSW5jLiwgNTEgRnJhbmtsaW4gU3QsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BIDAyMTEwLTEzMDEsIFVTQQogKi8KCiNpbmNsdWRlICJjb25maWcuaCIKI2luY2x1ZGUgIndpbmUvcG9ydC5oIgoKI2luY2x1ZGUgPGFzc2VydC5oPgojaW5jbHVkZSA8bG9jYWxlLmg+CiNpbmNsdWRlIDxzdHJpbmcuaD4KI2luY2x1ZGUgPHN0ZGFyZy5oPgojaW5jbHVkZSA8c3RkaW8uaD4KI2luY2x1ZGUgPGN0eXBlLmg+CiNpbmNsdWRlIDxzdGRsaWIuaD4KCiNpZmRlZiBfX0FQUExFX18KIyBpbmNsdWRlIDxDb3JlRm91bmRhdGlvbi9DRkJ1bmRsZS5oPgojIGluY2x1ZGUgPENvcmVGb3VuZGF0aW9uL0NGTG9jYWxlLmg+CiMgaW5jbHVkZSA8Q29yZUZvdW5kYXRpb24vQ0ZTdHJpbmcuaD4KI2VuZGlmCgojaW5jbHVkZSAibnRzdGF0dXMuaCIKI2RlZmluZSBXSU4zMl9OT19TVEFUVVMKI2luY2x1ZGUgIndpbmRlZi5oIgojaW5jbHVkZSAid2luYmFzZS5oIgojaW5jbHVkZSAid2ludXNlci5oIiAgLyogZm9yIFJUX1NUUklOR1cgKi8KI2luY2x1ZGUgIndpbnRlcm5sLmgiCiNpbmNsdWRlICJ3aW5lL3VuaWNvZGUuaCIKI2luY2x1ZGUgIndpbm5scy5oIgojaW5jbHVkZSAid2luZXJyb3IuaCIKI2luY2x1ZGUgIndpbnZlci5oIgojaW5jbHVkZSAia2VybmVsX3ByaXZhdGUuaCIKI2luY2x1ZGUgIndpbmUvZGVidWcuaCIKCldJTkVfREVGQVVMVF9ERUJVR19DSEFOTkVMKG5scyk7CgojZGVmaW5lIExPQ0FMRV9MT0NBTEVJTkZPRkxBR1NNQVNLIChMT0NBTEVfTk9VU0VST1ZFUlJJREV8TE9DQUxFX1VTRV9DUF9BQ1B8TE9DQUxFX1JFVFVSTl9OVU1CRVIpCgovKiBjdXJyZW50IGNvZGUgcGFnZXMgKi8Kc3RhdGljIGNvbnN0IHVuaW9uIGNwdGFibGUgKmFuc2lfY3B0YWJsZTsKc3RhdGljIGNvbnN0IHVuaW9uIGNwdGFibGUgKm9lbV9jcHRhYmxlOwpzdGF0aWMgY29uc3QgdW5pb24gY3B0YWJsZSAqbWFjX2NwdGFibGU7CnN0YXRpYyBjb25zdCB1bmlvbiBjcHRhYmxlICp1bml4X2NwdGFibGU7ICAvKiBOVUxMIGlmIFVURjggKi8KCnN0YXRpYyBIQU5ETEUgTkxTX1JlZ09wZW5LZXkoSEFORExFIGhSb290S2V5LCBMUENXU1RSIHN6S2V5TmFtZSk7CnN0YXRpYyBIQU5ETEUgTkxTX1JlZ09wZW5TdWJLZXkoSEFORExFIGhSb290S2V5LCBMUENXU1RSIHN6S2V5TmFtZSk7CgpzdGF0aWMgY29uc3QgV0NIQVIgc3pObHNLZXlOYW1lW10gPSB7CiAgICAnTScsJ2EnLCdjJywnaCcsJ2knLCduJywnZScsJ1xcJywnUycsJ3knLCdzJywndCcsJ2UnLCdtJywnXFwnLAogICAgJ0MnLCd1JywncicsJ3InLCdlJywnbicsJ3QnLCdDJywnbycsJ24nLCd0JywncicsJ28nLCdsJywnUycsJ2UnLCd0JywnXFwnLAogICAgJ0MnLCdvJywnbicsJ3QnLCdyJywnbycsJ2wnLCdcXCcsJ04nLCdsJywncycsJ1wwJwp9OwoKLyogQ2hhcnNldCB0byBjb2RlcGFnZSBtYXAsIHNvcnRlZCBieSBuYW1lLiAqLwpzdGF0aWMgY29uc3Qgc3RydWN0IGNoYXJzZXRfZW50cnkKewogICAgY29uc3QgY2hhciAqY2hhcnNldF9uYW1lOwogICAgVUlOVCAgICAgICAgY29kZXBhZ2U7Cn0gY2hhcnNldF9uYW1lc1tdID0KewogICAgeyAiQklHNSIsIDk1MCB9LAogICAgeyAiQ1AxMjUwIiwgMTI1MCB9LAogICAgeyAiQ1AxMjUxIiwgMTI1MSB9LAogICAgeyAiQ1AxMjUyIiwgMTI1MiB9LAogICAgeyAiQ1AxMjUzIiwgMTI1MyB9LAogICAgeyAiQ1AxMjU0IiwgMTI1NCB9LAogICAgeyAiQ1AxMjU1IiwgMTI1NSB9LAogICAgeyAiQ1AxMjU2IiwgMTI1NiB9LAogICAgeyAiQ1AxMjU3IiwgMTI1NyB9LAogICAgeyAiQ1AxMjU4IiwgMTI1OCB9LAogICAgeyAiQ1A5MzIiLCA5MzIgfSwKICAgIHsgIkNQOTM2IiwgOTM2IH0sCiAgICB7ICJDUDk0OSIsIDk0OSB9LAogICAgeyAiQ1A5NTAiLCA5NTAgfSwKICAgIHsgIkVVQ0pQIiwgMjA5MzIgfSwKICAgIHsgIkdCMjMxMiIsIDkzNiB9LAogICAgeyAiSUJNMDM3IiwgMzcgfSwKICAgIHsgIklCTTEwMjYiLCAxMDI2IH0sCiAgICB7ICJJQk00MjQiLCA0MjQgfSwKICAgIHsgIklCTTQzNyIsIDQzNyB9LAogICAgeyAiSUJNNTAwIiwgNTAwIH0sCiAgICB7ICJJQk04NTAiLCA4NTAgfSwKICAgIHsgIklCTTg1MiIsIDg1MiB9LAogICAgeyAiSUJNODU1IiwgODU1IH0sCiAgICB7ICJJQk04NTciLCA4NTcgfSwKICAgIHsgIklCTTg2MCIsIDg2MCB9LAogICAgeyAiSUJNODYxIiwgODYxIH0sCiAgICB7ICJJQk04NjIiLCA4NjIgfSwKICAgIHsgIklCTTg2MyIsIDg2MyB9LAogICAgeyAiSUJNODY0IiwgODY0IH0sCiAgICB7ICJJQk04NjUiLCA4NjUgfSwKICAgIHsgIklCTTg2NiIsIDg2NiB9LAogICAgeyAiSUJNODY5IiwgODY5IH0sCiAgICB7ICJJQk04NzQiLCA4NzQgfSwKICAgIHsgIklCTTg3NSIsIDg3NSB9LAogICAgeyAiSVNPODg1OTEiLCAyODU5MSB9LAogICAgeyAiSVNPODg1OTEwIiwgMjg2MDAgfSwKICAgIHsgIklTTzg4NTkxMyIsIDI4NjAzIH0sCiAgICB7ICJJU084ODU5MTQiLCAyODYwNCB9LAogICAgeyAiSVNPODg1OTE1IiwgMjg2MDUgfSwKICAgIHsgIklTTzg4NTkxNiIsIDI4NjA2IH0sCiAgICB7ICJJU084ODU5MiIsIDI4NTkyIH0sCiAgICB7ICJJU084ODU5MyIsIDI4NTkzIH0sCiAgICB7ICJJU084ODU5NCIsIDI4NTk0IH0sCiAgICB7ICJJU084ODU5NSIsIDI4NTk1IH0sCiAgICB7ICJJU084ODU5NiIsIDI4NTk2IH0sCiAgICB7ICJJU084ODU5NyIsIDI4NTk3IH0sCiAgICB7ICJJU084ODU5OCIsIDI4NTk4IH0sCiAgICB7ICJJU084ODU5OSIsIDI4NTk5IH0sCiAgICB7ICJLT0k4UiIsIDIwODY2IH0sCiAgICB7ICJLT0k4VSIsIDIxODY2IH0sCiAgICB7ICJVVEY4IiwgQ1BfVVRGOCB9Cn07CgoKc3RydWN0IGxvY2FsZV9uYW1lCnsKICAgIFdDSEFSICB3aW5fbmFtZVsxMjhdOyAgIC8qIFdpbmRvd3MgbmFtZSAoImVuLVVTIikgKi8KICAgIFdDSEFSICBsYW5nWzEyOF07ICAgICAgIC8qIGxhbmd1YWdlICgiZW4iKSAobm90ZTogYnVmZmVyIGNvbnRhaW5zIHRoZSBvdGhlciBzdHJpbmdzIHRvbykgKi8KICAgIFdDSEFSICpjb3VudHJ5OyAgICAgICAgIC8qIGNvdW50cnkgKCJVUyIpICovCiAgICBXQ0hBUiAqY2hhcnNldDsgICAgICAgICAvKiBjaGFyc2V0ICgiVVRGLTgiKSBmb3IgVW5peCBmb3JtYXQgb25seSAqLwogICAgV0NIQVIgKnNjcmlwdDsgICAgICAgICAgLyogc2NyaXB0ICgiTGF0biIpIGZvciBXaW5kb3dzIGZvcm1hdCBvbmx5ICovCiAgICBXQ0hBUiAqbW9kaWZpZXI7ICAgICAgICAvKiBtb2RpZmllciBvciBzb3J0IG9yZGVyICovCiAgICBMQ0lEICAgbGNpZDsgICAgICAgICAgICAvKiBjb3JyZXNwb25kaW5nIExDSUQgKi8KICAgIGludCAgICBtYXRjaGVzOyAgICAgICAgIC8qIG51bWJlciBvZiBlbGVtZW50cyBtYXRjaGluZyBMQ0lEICgwLi40KSAqLwogICAgVUlOVCAgIGNvZGVwYWdlOyAgICAgICAgLyogY29kZXBhZ2UgY29ycmVzcG9uZGluZyB0byBjaGFyc2V0ICovCn07CgovKiBsb2NhbGUgaWRzIGNvcnJlc3BvbmRpbmcgdG8gdGhlIHZhcmlvdXMgVW5peCBsb2NhbGUgcGFyYW1ldGVycyAqLwpzdGF0aWMgTENJRCBsY2lkX0xDX0NPTExBVEU7CnN0YXRpYyBMQ0lEIGxjaWRfTENfQ1RZUEU7CnN0YXRpYyBMQ0lEIGxjaWRfTENfTUVTU0FHRVM7CnN0YXRpYyBMQ0lEIGxjaWRfTENfTU9ORVRBUlk7CnN0YXRpYyBMQ0lEIGxjaWRfTENfTlVNRVJJQzsKc3RhdGljIExDSUQgbGNpZF9MQ19USU1FOwpzdGF0aWMgTENJRCBsY2lkX0xDX1BBUEVSOwpzdGF0aWMgTENJRCBsY2lkX0xDX01FQVNVUkVNRU5UOwpzdGF0aWMgTENJRCBsY2lkX0xDX1RFTEVQSE9ORTsKCi8qIENvcHkgQXNjaWkgc3RyaW5nIHRvIFVuaWNvZGUgd2l0aG91dCB1c2luZyBjb2RlcGFnZXMgKi8Kc3RhdGljIGlubGluZSB2b2lkIHN0cmNweW5BdG9XKCBXQ0hBUiAqZHN0LCBjb25zdCBjaGFyICpzcmMsIHNpemVfdCBuICkKewogICAgd2hpbGUgKG4gPiAxICYmICpzcmMpCiAgICB7CiAgICAgICAgKmRzdCsrID0gKHVuc2lnbmVkIGNoYXIpKnNyYysrOwogICAgICAgIG4tLTsKICAgIH0KICAgIGlmIChuKSAqZHN0ID0gMDsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJZ2V0X2xjaWRfY29kZXBhZ2UKICoKICogUmV0cmlldmUgdGhlIEFOU0kgY29kZXBhZ2UgZm9yIGEgZ2l2ZW4gbG9jYWxlLgogKi8Kc3RhdGljIGlubGluZSBVSU5UIGdldF9sY2lkX2NvZGVwYWdlKCBMQ0lEIGxjaWQgKQp7CiAgICBVSU5UIHJldDsKICAgIGlmICghR2V0TG9jYWxlSW5mb1coIGxjaWQsIExPQ0FMRV9JREVGQVVMVEFOU0lDT0RFUEFHRXxMT0NBTEVfUkVUVVJOX05VTUJFUiwgKFdDSEFSICopJnJldCwKICAgICAgICAgICAgICAgICAgICAgICAgIHNpemVvZihyZXQpL3NpemVvZihXQ0hBUikgKSkgcmV0ID0gMDsKICAgIHJldHVybiByZXQ7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCWdldF9jb2RlcGFnZV90YWJsZQogKgogKiBGaW5kIHRoZSB0YWJsZSBmb3IgYSBnaXZlbiBjb2RlcGFnZSwgaGFuZGxpbmcgQ1BfQUNQIGV0Yy4gcHNldWRvLWNvZGVwYWdlcwogKi8Kc3RhdGljIGNvbnN0IHVuaW9uIGNwdGFibGUgKmdldF9jb2RlcGFnZV90YWJsZSggdW5zaWduZWQgaW50IGNvZGVwYWdlICkKewogICAgY29uc3QgdW5pb24gY3B0YWJsZSAqcmV0ID0gTlVMTDsKCiAgICBhc3NlcnQoIGFuc2lfY3B0YWJsZSApOyAgLyogaW5pdCBtdXN0IGhhdmUgYmVlbiBkb25lIGFscmVhZHkgKi8KCiAgICBzd2l0Y2goY29kZXBhZ2UpCiAgICB7CiAgICBjYXNlIENQX0FDUDoKICAgICAgICByZXR1cm4gYW5zaV9jcHRhYmxlOwogICAgY2FzZSBDUF9PRU1DUDoKICAgICAgICByZXR1cm4gb2VtX2NwdGFibGU7CiAgICBjYXNlIENQX01BQ0NQOgogICAgICAgIHJldHVybiBtYWNfY3B0YWJsZTsKICAgIGNhc2UgQ1BfVVRGNzoKICAgIGNhc2UgQ1BfVVRGODoKICAgICAgICBicmVhazsKICAgIGNhc2UgQ1BfVEhSRUFEX0FDUDoKICAgICAgICBpZiAoIShjb2RlcGFnZSA9IGtlcm5lbF9nZXRfdGhyZWFkX2RhdGEoKS0+Y29kZV9wYWdlKSkgcmV0dXJuIGFuc2lfY3B0YWJsZTsKICAgICAgICAvKiBmYWxsIHRocm91Z2ggKi8KICAgIGRlZmF1bHQ6CiAgICAgICAgaWYgKGNvZGVwYWdlID09IGFuc2lfY3B0YWJsZS0+aW5mby5jb2RlcGFnZSkgcmV0dXJuIGFuc2lfY3B0YWJsZTsKICAgICAgICBpZiAoY29kZXBhZ2UgPT0gb2VtX2NwdGFibGUtPmluZm8uY29kZXBhZ2UpIHJldHVybiBvZW1fY3B0YWJsZTsKICAgICAgICBpZiAoY29kZXBhZ2UgPT0gbWFjX2NwdGFibGUtPmluZm8uY29kZXBhZ2UpIHJldHVybiBtYWNfY3B0YWJsZTsKICAgICAgICByZXQgPSB3aW5lX2NwX2dldF90YWJsZSggY29kZXBhZ2UgKTsKICAgICAgICBicmVhazsKICAgIH0KICAgIHJldHVybiByZXQ7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICAgICAgICAgIGNoYXJzZXRfY21wIChpbnRlcm5hbCkKICovCnN0YXRpYyBpbnQgY2hhcnNldF9jbXAoIGNvbnN0IHZvaWQgKm5hbWUsIGNvbnN0IHZvaWQgKmVudHJ5ICkKewogICAgY29uc3Qgc3RydWN0IGNoYXJzZXRfZW50cnkgKmNoYXJzZXQgPSAoY29uc3Qgc3RydWN0IGNoYXJzZXRfZW50cnkgKillbnRyeTsKICAgIHJldHVybiBzdHJjYXNlY21wKCAoY29uc3QgY2hhciAqKW5hbWUsIGNoYXJzZXQtPmNoYXJzZXRfbmFtZSApOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCWZpbmRfY2hhcnNldAogKi8Kc3RhdGljIFVJTlQgZmluZF9jaGFyc2V0KCBjb25zdCBXQ0hBUiAqbmFtZSApCnsKICAgIGNvbnN0IHN0cnVjdCBjaGFyc2V0X2VudHJ5ICplbnRyeTsKICAgIGNoYXIgY2hhcnNldF9uYW1lWzE2XTsKICAgIHNpemVfdCBpLCBqOwoKICAgIC8qIHJlbW92ZSBwdW5jdHVhdGlvbiBjaGFyYWN0ZXJzIGZyb20gY2hhcnNldCBuYW1lICovCiAgICBmb3IgKGkgPSBqID0gMDsgbmFtZVtpXSAmJiBqIDwgc2l6ZW9mKGNoYXJzZXRfbmFtZSktMTsgaSsrKQogICAgICAgIGlmIChpc2FsbnVtKCh1bnNpZ25lZCBjaGFyKW5hbWVbaV0pKSBjaGFyc2V0X25hbWVbaisrXSA9IG5hbWVbaV07CiAgICBjaGFyc2V0X25hbWVbal0gPSAwOwoKICAgIGVudHJ5ID0gYnNlYXJjaCggY2hhcnNldF9uYW1lLCBjaGFyc2V0X25hbWVzLAogICAgICAgICAgICAgICAgICAgICBzaXplb2YoY2hhcnNldF9uYW1lcykvc2l6ZW9mKGNoYXJzZXRfbmFtZXNbMF0pLAogICAgICAgICAgICAgICAgICAgICBzaXplb2YoY2hhcnNldF9uYW1lc1swXSksIGNoYXJzZXRfY21wICk7CiAgICBpZiAoZW50cnkpIHJldHVybiBlbnRyeS0+Y29kZXBhZ2U7CiAgICByZXR1cm4gMDsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgICAgICAgZmluZF9sb2NhbGVfaWRfY2FsbGJhY2sKICovCnN0YXRpYyBCT09MIENBTExCQUNLIGZpbmRfbG9jYWxlX2lkX2NhbGxiYWNrKCBITU9EVUxFIGhNb2R1bGUsIExQQ1dTVFIgdHlwZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIExQQ1dTVFIgbmFtZSwgV09SRCBMYW5nSUQsIExQQVJBTSBsUGFyYW0gKQp7CiAgICBzdHJ1Y3QgbG9jYWxlX25hbWUgKmRhdGEgPSAoc3RydWN0IGxvY2FsZV9uYW1lICopbFBhcmFtOwogICAgV0NIQVIgYnVmZmVyWzEyOF07CiAgICBpbnQgbWF0Y2hlcyA9IDA7CiAgICBMQ0lEIGxjaWQgPSBNQUtFTENJRCggTGFuZ0lELCBTT1JUX0RFRkFVTFQgKTsgIC8qIEZJWE1FOiBoYW5kbGUgc29ydCBvcmRlciAqLwoKICAgIGlmIChQUklNQVJZTEFOR0lEKExhbmdJRCkgPT0gTEFOR19ORVVUUkFMKSByZXR1cm4gVFJVRTsgLyogY29udGludWUgc2VhcmNoICovCgogICAgLyogZmlyc3QgY2hlY2sgZXhhY3QgbmFtZSAqLwogICAgaWYgKGRhdGEtPndpbl9uYW1lWzBdICYmCiAgICAgICAgR2V0TG9jYWxlSW5mb1coIGxjaWQsIExPQ0FMRV9TTkFNRSB8IExPQ0FMRV9OT1VTRVJPVkVSUklERSwKICAgICAgICAgICAgICAgICAgICAgICAgYnVmZmVyLCBzaXplb2YoYnVmZmVyKS9zaXplb2YoV0NIQVIpICkpCiAgICB7CiAgICAgICAgaWYgKCFzdHJjbXBXKCBkYXRhLT53aW5fbmFtZSwgYnVmZmVyICkpCiAgICAgICAgewogICAgICAgICAgICBtYXRjaGVzID0gNDsgIC8qIGV2ZXJ5dGhpbmcgbWF0Y2hlcyAqLwogICAgICAgICAgICBnb3RvIGRvbmU7CiAgICAgICAgfQogICAgfQoKICAgIGlmICghR2V0TG9jYWxlSW5mb1coIGxjaWQsIExPQ0FMRV9TSVNPNjM5TEFOR05BTUUgfCBMT0NBTEVfTk9VU0VST1ZFUlJJREUsCiAgICAgICAgICAgICAgICAgICAgICAgICBidWZmZXIsIHNpemVvZihidWZmZXIpL3NpemVvZihXQ0hBUikgKSkKICAgICAgICByZXR1cm4gVFJVRTsKICAgIGlmIChzdHJjbXBXKCBidWZmZXIsIGRhdGEtPmxhbmcgKSkgcmV0dXJuIFRSVUU7CiAgICBtYXRjaGVzKys7ICAvKiBsYW5ndWFnZSBuYW1lIG1hdGNoZWQgKi8KCiAgICBpZiAoZGF0YS0+Y291bnRyeSkKICAgIHsKICAgICAgICBpZiAoR2V0TG9jYWxlSW5mb1coIGxjaWQsIExPQ0FMRV9TSVNPMzE2NkNUUllOQU1FfExPQ0FMRV9OT1VTRVJPVkVSUklERSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJ1ZmZlciwgc2l6ZW9mKGJ1ZmZlcikvc2l6ZW9mKFdDSEFSKSApKQogICAgICAgIHsKICAgICAgICAgICAgaWYgKHN0cmNtcFcoIGJ1ZmZlciwgZGF0YS0+Y291bnRyeSApKSBnb3RvIGRvbmU7CiAgICAgICAgICAgIG1hdGNoZXMrKzsgIC8qIGNvdW50cnkgbmFtZSBtYXRjaGVkICovCiAgICAgICAgfQogICAgfQogICAgZWxzZSAgLyogbWF0Y2ggZGVmYXVsdCBsYW5ndWFnZSAqLwogICAgewogICAgICAgIGlmIChTVUJMQU5HSUQoTGFuZ0lEKSA9PSBTVUJMQU5HX0RFRkFVTFQpIG1hdGNoZXMrKzsKICAgIH0KCiAgICBpZiAoZGF0YS0+Y29kZXBhZ2UpCiAgICB7CiAgICAgICAgVUlOVCB1bml4X2NwOwogICAgICAgIGlmIChHZXRMb2NhbGVJbmZvVyggbGNpZCwgTE9DQUxFX0lERUZBVUxUVU5JWENPREVQQUdFIHwgTE9DQUxFX1JFVFVSTl9OVU1CRVIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAoTFBXU1RSKSZ1bml4X2NwLCBzaXplb2YodW5peF9jcCkvc2l6ZW9mKFdDSEFSKSApKQogICAgICAgIHsKICAgICAgICAgICAgaWYgKHVuaXhfY3AgPT0gZGF0YS0+Y29kZXBhZ2UpIG1hdGNoZXMrKzsKICAgICAgICB9CiAgICB9CgogICAgLyogRklYTUU6IGNoZWNrIHNvcnQgb3JkZXIgKi8KCmRvbmU6CiAgICBpZiAobWF0Y2hlcyA+IGRhdGEtPm1hdGNoZXMpCiAgICB7CiAgICAgICAgZGF0YS0+bGNpZCA9IGxjaWQ7CiAgICAgICAgZGF0YS0+bWF0Y2hlcyA9IG1hdGNoZXM7CiAgICB9CiAgICByZXR1cm4gKGRhdGEtPm1hdGNoZXMgPCA0KTsgIC8qIG5vIG5lZWQgdG8gY29udGludWUgZm9yIHBlcmZlY3QgbWF0Y2ggKi8KfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJcGFyc2VfbG9jYWxlX25hbWUKICoKICogUGFyc2UgYSBsb2NhbGUgbmFtZSBpbnRvIGEgc3RydWN0IGxvY2FsZV9uYW1lLCBoYW5kbGluZyBib3RoIFdpbmRvd3MgYW5kIFVuaXggZm9ybWF0cy4KICogVW5peCBmb3JtYXQgaXM6IGxhbmdbX2NvdW50cnldWy5jaGFyc2V0XVtAbW9kaWZpZXJdCiAqIFdpbmRvd3MgZm9ybWF0IGlzOiBsYW5nWy1zY3JpcHRdWy1jb3VudHJ5XVtfbW9kaWZpZXJdCiAqLwpzdGF0aWMgdm9pZCBwYXJzZV9sb2NhbGVfbmFtZSggY29uc3QgV0NIQVIgKnN0ciwgc3RydWN0IGxvY2FsZV9uYW1lICpuYW1lICkKewogICAgc3RhdGljIGNvbnN0IFdDSEFSIHNlcFdbXSA9IHsnLScsJ18nLCcuJywnQCcsMH07CiAgICBzdGF0aWMgY29uc3QgV0NIQVIgd2luc2VwV1tdID0geyctJywnXycsMH07CiAgICBzdGF0aWMgY29uc3QgV0NIQVIgcG9zaXhXW10gPSB7J1AnLCdPJywnUycsJ0knLCdYJywwfTsKICAgIHN0YXRpYyBjb25zdCBXQ0hBUiBjV1tdID0geydDJywwfTsKICAgIHN0YXRpYyBjb25zdCBXQ0hBUiBsYXRpbldbXSA9IHsnbCcsJ2EnLCd0JywnaScsJ24nLDB9OwogICAgc3RhdGljIGNvbnN0IFdDSEFSIGxhdG5XW10gPSB7Jy0nLCdMJywnYScsJ3QnLCduJywwfTsKICAgIFdDSEFSICpwOwoKICAgIG5hbWUtPmNvdW50cnkgPSBuYW1lLT5jaGFyc2V0ID0gbmFtZS0+c2NyaXB0ID0gbmFtZS0+bW9kaWZpZXIgPSBOVUxMOwogICAgbmFtZS0+bGNpZCA9IE1BS0VMQ0lEKCBNQUtFTEFOR0lEKExBTkdfRU5HTElTSCxTVUJMQU5HX0RFRkFVTFQpLCBTT1JUX0RFRkFVTFQgKTsKICAgIG5hbWUtPm1hdGNoZXMgPSAwOwogICAgbmFtZS0+Y29kZXBhZ2UgPSAwOwogICAgbmFtZS0+d2luX25hbWVbMF0gPSAwOwogICAgbHN0cmNweW5XKCBuYW1lLT5sYW5nLCBzdHIsIHNpemVvZihuYW1lLT5sYW5nKS9zaXplb2YoV0NIQVIpICk7CgogICAgaWYgKCEocCA9IHN0cnBicmtXKCBuYW1lLT5sYW5nLCBzZXBXICkpKQogICAgewogICAgICAgIGlmICghc3RyY21wVyggbmFtZS0+bGFuZywgcG9zaXhXICkgfHwgIXN0cmNtcFcoIG5hbWUtPmxhbmcsIGNXICkpCiAgICAgICAgewogICAgICAgICAgICBuYW1lLT5tYXRjaGVzID0gNDsgIC8qIHBlcmZlY3QgbWF0Y2ggZm9yIGRlZmF1bHQgRW5nbGlzaCBsY2lkICovCiAgICAgICAgICAgIHJldHVybjsKICAgICAgICB9CiAgICAgICAgc3RyY3B5VyggbmFtZS0+d2luX25hbWUsIG5hbWUtPmxhbmcgKTsKICAgIH0KICAgIGVsc2UgaWYgKCpwID09ICctJykgIC8qIFdpbmRvd3MgZm9ybWF0ICovCiAgICB7CiAgICAgICAgc3RyY3B5VyggbmFtZS0+d2luX25hbWUsIG5hbWUtPmxhbmcgKTsKICAgICAgICAqcCsrID0gMDsKICAgICAgICBuYW1lLT5jb3VudHJ5ID0gcDsKICAgICAgICBpZiAoIShwID0gc3RycGJya1coIHAsIHdpbnNlcFcgKSkpIGdvdG8gZG9uZTsKICAgICAgICBpZiAoKnAgPT0gJy0nKQogICAgICAgIHsKICAgICAgICAgICAgKnArKyA9IDA7CiAgICAgICAgICAgIG5hbWUtPnNjcmlwdCA9IG5hbWUtPmNvdW50cnk7CiAgICAgICAgICAgIG5hbWUtPmNvdW50cnkgPSBwOwogICAgICAgICAgICBpZiAoIShwID0gc3RycGJya1coIHAsIHdpbnNlcFcgKSkpIGdvdG8gZG9uZTsKICAgICAgICB9CiAgICAgICAgKnArKyA9IDA7CiAgICAgICAgbmFtZS0+bW9kaWZpZXIgPSBwOwogICAgfQogICAgZWxzZSAgLyogVW5peCBmb3JtYXQgKi8KICAgIHsKICAgICAgICBpZiAoKnAgPT0gJ18nKQogICAgICAgIHsKICAgICAgICAgICAgKnArKyA9IDA7CiAgICAgICAgICAgIG5hbWUtPmNvdW50cnkgPSBwOwogICAgICAgICAgICBwID0gc3RycGJya1coIHAsIHNlcFcgKyAyICk7CiAgICAgICAgfQogICAgICAgIGlmIChwICYmICpwID09ICcuJykKICAgICAgICB7CiAgICAgICAgICAgICpwKysgPSAwOwogICAgICAgICAgICBuYW1lLT5jaGFyc2V0ID0gcDsKICAgICAgICAgICAgbmFtZS0+Y29kZXBhZ2UgPSBmaW5kX2NoYXJzZXQoIG5hbWUtPmNoYXJzZXQgKTsKICAgICAgICAgICAgcCA9IHN0cmNoclcoIHAsICdAJyApOwogICAgICAgIH0KICAgICAgICBpZiAocCkKICAgICAgICB7CiAgICAgICAgICAgICpwKysgPSAwOwogICAgICAgICAgICBuYW1lLT5tb2RpZmllciA9IHA7CiAgICAgICAgfQoKICAgICAgICAvKiByZWJ1aWxkIGEgV2luZG93cyBuYW1lIGlmIHBvc3NpYmxlICovCgogICAgICAgIGlmIChuYW1lLT5jaGFyc2V0KSBnb3RvIGRvbmU7ICAvKiBjYW4ndCBzcGVjaWZ5IGNoYXJzZXQgaW4gV2luZG93cyBmb3JtYXQgKi8KICAgICAgICBpZiAobmFtZS0+bW9kaWZpZXIgJiYgc3RyY21wVyggbmFtZS0+bW9kaWZpZXIsIGxhdGluVyApKQogICAgICAgICAgICBnb3RvIGRvbmU7ICAvKiBvbmx5IExhdG4gc2NyaXB0IHN1cHBvcnRlZCBmb3Igbm93ICovCiAgICAgICAgc3RyY3B5VyggbmFtZS0+d2luX25hbWUsIG5hbWUtPmxhbmcgKTsKICAgICAgICBpZiAobmFtZS0+bW9kaWZpZXIpIHN0cmNhdFcoIG5hbWUtPndpbl9uYW1lLCBsYXRuVyApOwogICAgICAgIGlmIChuYW1lLT5jb3VudHJ5KQogICAgICAgIHsKICAgICAgICAgICAgcCA9IG5hbWUtPndpbl9uYW1lICsgc3RybGVuVyhuYW1lLT53aW5fbmFtZSk7CiAgICAgICAgICAgICpwKysgPSAnLSc7CiAgICAgICAgICAgIHN0cmNweVcoIHAsIG5hbWUtPmNvdW50cnkgKTsKICAgICAgICB9CiAgICB9CmRvbmU6CiAgICBFbnVtUmVzb3VyY2VMYW5ndWFnZXNXKCBrZXJuZWwzMl9oYW5kbGUsIChMUENXU1RSKVJUX1NUUklORywgKExQQ1dTVFIpTE9DQUxFX0lMQU5HVUFHRSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmRfbG9jYWxlX2lkX2NhbGxiYWNrLCAoTFBBUkFNKW5hbWUgKTsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgICAgICAgY29udmVydF9kZWZhdWx0X2xjaWQKICoKICogR2V0IHRoZSBkZWZhdWx0IExDSUQgdG8gdXNlIGZvciBhIGdpdmVuIGxjdHlwZSBpbiBHZXRMb2NhbGVJbmZvLgogKi8Kc3RhdGljIExDSUQgY29udmVydF9kZWZhdWx0X2xjaWQoIExDSUQgbGNpZCwgTENUWVBFIGxjdHlwZSApCnsKICAgIGlmIChsY2lkID09IExPQ0FMRV9TWVNURU1fREVGQVVMVCB8fAogICAgICAgIGxjaWQgPT0gTE9DQUxFX1VTRVJfREVGQVVMVCB8fAogICAgICAgIGxjaWQgPT0gTE9DQUxFX05FVVRSQUwpCiAgICB7CiAgICAgICAgTENJRCBkZWZhdWx0X2lkID0gMDsKCiAgICAgICAgc3dpdGNoKGxjdHlwZSAmIDB4ZmZmZikKICAgICAgICB7CiAgICAgICAgY2FzZSBMT0NBTEVfU1NPUlROQU1FOgogICAgICAgICAgICBkZWZhdWx0X2lkID0gbGNpZF9MQ19DT0xMQVRFOwogICAgICAgICAgICBicmVhazsKCiAgICAgICAgY2FzZSBMT0NBTEVfRk9OVFNJR05BVFVSRToKICAgICAgICBjYXNlIExPQ0FMRV9JREVGQVVMVEFOU0lDT0RFUEFHRToKICAgICAgICBjYXNlIExPQ0FMRV9JREVGQVVMVENPREVQQUdFOgogICAgICAgIGNhc2UgTE9DQUxFX0lERUZBVUxURUJDRElDQ09ERVBBR0U6CiAgICAgICAgY2FzZSBMT0NBTEVfSURFRkFVTFRNQUNDT0RFUEFHRToKICAgICAgICBjYXNlIExPQ0FMRV9JREVGQVVMVFVOSVhDT0RFUEFHRToKICAgICAgICAgICAgZGVmYXVsdF9pZCA9IGxjaWRfTENfQ1RZUEU7CiAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICBjYXNlIExPQ0FMRV9JQ1VSUkRJR0lUUzoKICAgICAgICBjYXNlIExPQ0FMRV9JQ1VSUkVOQ1k6CiAgICAgICAgY2FzZSBMT0NBTEVfSUlOVExDVVJSRElHSVRTOgogICAgICAgIGNhc2UgTE9DQUxFX0lORUdDVVJSOgogICAgICAgIGNhc2UgTE9DQUxFX0lORUdTRVBCWVNQQUNFOgogICAgICAgIGNhc2UgTE9DQUxFX0lORUdTSUdOUE9TTjoKICAgICAgICBjYXNlIExPQ0FMRV9JTkVHU1lNUFJFQ0VERVM6CiAgICAgICAgY2FzZSBMT0NBTEVfSVBPU1NFUEJZU1BBQ0U6CiAgICAgICAgY2FzZSBMT0NBTEVfSVBPU1NJR05QT1NOOgogICAgICAgIGNhc2UgTE9DQUxFX0lQT1NTWU1QUkVDRURFUzoKICAgICAgICBjYXNlIExPQ0FMRV9TQ1VSUkVOQ1k6CiAgICAgICAgY2FzZSBMT0NBTEVfU0lOVExTWU1CT0w6CiAgICAgICAgY2FzZSBMT0NBTEVfU01PTkRFQ0lNQUxTRVA6CiAgICAgICAgY2FzZSBMT0NBTEVfU01PTkdST1VQSU5HOgogICAgICAgIGNhc2UgTE9DQUxFX1NNT05USE9VU0FORFNFUDoKICAgICAgICBjYXNlIExPQ0FMRV9TTkFUSVZFQ1VSUk5BTUU6CiAgICAgICAgICAgIGRlZmF1bHRfaWQgPSBsY2lkX0xDX01PTkVUQVJZOwogICAgICAgICAgICBicmVhazsKCiAgICAgICAgY2FzZSBMT0NBTEVfSURJR0lUUzoKICAgICAgICBjYXNlIExPQ0FMRV9JRElHSVRTVUJTVElUVVRJT046CiAgICAgICAgY2FzZSBMT0NBTEVfSUxaRVJPOgogICAgICAgIGNhc2UgTE9DQUxFX0lORUdOVU1CRVI6CiAgICAgICAgY2FzZSBMT0NBTEVfU0RFQ0lNQUw6CiAgICAgICAgY2FzZSBMT0NBTEVfU0dST1VQSU5HOgogICAgICAgIGNhc2UgTE9DQUxFX1NOQU46CiAgICAgICAgY2FzZSBMT0NBTEVfU05BVElWRURJR0lUUzoKICAgICAgICBjYXNlIExPQ0FMRV9TTkVHQVRJVkVTSUdOOgogICAgICAgIGNhc2UgTE9DQUxFX1NORUdJTkZJTklUWToKICAgICAgICBjYXNlIExPQ0FMRV9TUE9TSU5GSU5JVFk6CiAgICAgICAgY2FzZSBMT0NBTEVfU1BPU0lUSVZFU0lHTjoKICAgICAgICBjYXNlIExPQ0FMRV9TVEhPVVNBTkQ6CiAgICAgICAgICAgIGRlZmF1bHRfaWQgPSBsY2lkX0xDX05VTUVSSUM7CiAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICBjYXNlIExPQ0FMRV9JQ0FMRU5EQVJUWVBFOgogICAgICAgIGNhc2UgTE9DQUxFX0lDRU5UVVJZOgogICAgICAgIGNhc2UgTE9DQUxFX0lEQVRFOgogICAgICAgIGNhc2UgTE9DQUxFX0lEQVlMWkVSTzoKICAgICAgICBjYXNlIExPQ0FMRV9JRklSU1REQVlPRldFRUs6CiAgICAgICAgY2FzZSBMT0NBTEVfSUZJUlNUV0VFS09GWUVBUjoKICAgICAgICBjYXNlIExPQ0FMRV9JTERBVEU6CiAgICAgICAgY2FzZSBMT0NBTEVfSU1PTkxaRVJPOgogICAgICAgIGNhc2UgTE9DQUxFX0lPUFRJT05BTENBTEVOREFSOgogICAgICAgIGNhc2UgTE9DQUxFX0lUSU1FOgogICAgICAgIGNhc2UgTE9DQUxFX0lUSU1FTUFSS1BPU046CiAgICAgICAgY2FzZSBMT0NBTEVfSVRMWkVSTzoKICAgICAgICBjYXNlIExPQ0FMRV9TMTE1OToKICAgICAgICBjYXNlIExPQ0FMRV9TMjM1OToKICAgICAgICBjYXNlIExPQ0FMRV9TQUJCUkVWREFZTkFNRTE6CiAgICAgICAgY2FzZSBMT0NBTEVfU0FCQlJFVkRBWU5BTUUyOgogICAgICAgIGNhc2UgTE9DQUxFX1NBQkJSRVZEQVlOQU1FMzoKICAgICAgICBjYXNlIExPQ0FMRV9TQUJCUkVWREFZTkFNRTQ6CiAgICAgICAgY2FzZSBMT0NBTEVfU0FCQlJFVkRBWU5BTUU1OgogICAgICAgIGNhc2UgTE9DQUxFX1NBQkJSRVZEQVlOQU1FNjoKICAgICAgICBjYXNlIExPQ0FMRV9TQUJCUkVWREFZTkFNRTc6CiAgICAgICAgY2FzZSBMT0NBTEVfU0FCQlJFVk1PTlRITkFNRTE6CiAgICAgICAgY2FzZSBMT0NBTEVfU0FCQlJFVk1PTlRITkFNRTI6CiAgICAgICAgY2FzZSBMT0NBTEVfU0FCQlJFVk1PTlRITkFNRTM6CiAgICAgICAgY2FzZSBMT0NBTEVfU0FCQlJFVk1PTlRITkFNRTQ6CiAgICAgICAgY2FzZSBMT0NBTEVfU0FCQlJFVk1PTlRITkFNRTU6CiAgICAgICAgY2FzZSBMT0NBTEVfU0FCQlJFVk1PTlRITkFNRTY6CiAgICAgICAgY2FzZSBMT0NBTEVfU0FCQlJFVk1PTlRITkFNRTc6CiAgICAgICAgY2FzZSBMT0NBTEVfU0FCQlJFVk1PTlRITkFNRTg6CiAgICAgICAgY2FzZSBMT0NBTEVfU0FCQlJFVk1PTlRITkFNRTk6CiAgICAgICAgY2FzZSBMT0NBTEVfU0FCQlJFVk1PTlRITkFNRTEwOgogICAgICAgIGNhc2UgTE9DQUxFX1NBQkJSRVZNT05USE5BTUUxMToKICAgICAgICBjYXNlIExPQ0FMRV9TQUJCUkVWTU9OVEhOQU1FMTI6CiAgICAgICAgY2FzZSBMT0NBTEVfU0FCQlJFVk1PTlRITkFNRTEzOgogICAgICAgIGNhc2UgTE9DQUxFX1NEQVRFOgogICAgICAgIGNhc2UgTE9DQUxFX1NEQVlOQU1FMToKICAgICAgICBjYXNlIExPQ0FMRV9TREFZTkFNRTI6CiAgICAgICAgY2FzZSBMT0NBTEVfU0RBWU5BTUUzOgogICAgICAgIGNhc2UgTE9DQUxFX1NEQVlOQU1FNDoKICAgICAgICBjYXNlIExPQ0FMRV9TREFZTkFNRTU6CiAgICAgICAgY2FzZSBMT0NBTEVfU0RBWU5BTUU2OgogICAgICAgIGNhc2UgTE9DQUxFX1NEQVlOQU1FNzoKICAgICAgICBjYXNlIExPQ0FMRV9TRFVSQVRJT046CiAgICAgICAgY2FzZSBMT0NBTEVfU0xPTkdEQVRFOgogICAgICAgIGNhc2UgTE9DQUxFX1NNT05USE5BTUUxOgogICAgICAgIGNhc2UgTE9DQUxFX1NNT05USE5BTUUyOgogICAgICAgIGNhc2UgTE9DQUxFX1NNT05USE5BTUUzOgogICAgICAgIGNhc2UgTE9DQUxFX1NNT05USE5BTUU0OgogICAgICAgIGNhc2UgTE9DQUxFX1NNT05USE5BTUU1OgogICAgICAgIGNhc2UgTE9DQUxFX1NNT05USE5BTUU2OgogICAgICAgIGNhc2UgTE9DQUxFX1NNT05USE5BTUU3OgogICAgICAgIGNhc2UgTE9DQUxFX1NNT05USE5BTUU4OgogICAgICAgIGNhc2UgTE9DQUxFX1NNT05USE5BTUU5OgogICAgICAgIGNhc2UgTE9DQUxFX1NNT05USE5BTUUxMDoKICAgICAgICBjYXNlIExPQ0FMRV9TTU9OVEhOQU1FMTE6CiAgICAgICAgY2FzZSBMT0NBTEVfU01PTlRITkFNRTEyOgogICAgICAgIGNhc2UgTE9DQUxFX1NNT05USE5BTUUxMzoKICAgICAgICBjYXNlIExPQ0FMRV9TU0hPUlREQVRFOgogICAgICAgIGNhc2UgTE9DQUxFX1NTSE9SVEVTVERBWU5BTUUxOgogICAgICAgIGNhc2UgTE9DQUxFX1NTSE9SVEVTVERBWU5BTUUyOgogICAgICAgIGNhc2UgTE9DQUxFX1NTSE9SVEVTVERBWU5BTUUzOgogICAgICAgIGNhc2UgTE9DQUxFX1NTSE9SVEVTVERBWU5BTUU0OgogICAgICAgIGNhc2UgTE9DQUxFX1NTSE9SVEVTVERBWU5BTUU1OgogICAgICAgIGNhc2UgTE9DQUxFX1NTSE9SVEVTVERBWU5BTUU2OgogICAgICAgIGNhc2UgTE9DQUxFX1NTSE9SVEVTVERBWU5BTUU3OgogICAgICAgIGNhc2UgTE9DQUxFX1NUSU1FOgogICAgICAgIGNhc2UgTE9DQUxFX1NUSU1FRk9STUFUOgogICAgICAgIGNhc2UgTE9DQUxFX1NZRUFSTU9OVEg6CiAgICAgICAgICAgIGRlZmF1bHRfaWQgPSBsY2lkX0xDX1RJTUU7CiAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICBjYXNlIExPQ0FMRV9JUEFQRVJTSVpFOgogICAgICAgICAgICBkZWZhdWx0X2lkID0gbGNpZF9MQ19QQVBFUjsKICAgICAgICAgICAgYnJlYWs7CgogICAgICAgIGNhc2UgTE9DQUxFX0lNRUFTVVJFOgogICAgICAgICAgICBkZWZhdWx0X2lkID0gbGNpZF9MQ19NRUFTVVJFTUVOVDsKICAgICAgICAgICAgYnJlYWs7CgogICAgICAgIGNhc2UgTE9DQUxFX0lDT1VOVFJZOgogICAgICAgICAgICBkZWZhdWx0X2lkID0gbGNpZF9MQ19URUxFUEhPTkU7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIH0KICAgICAgICBpZiAoZGVmYXVsdF9pZCkgbGNpZCA9IGRlZmF1bHRfaWQ7CiAgICB9CiAgICByZXR1cm4gQ29udmVydERlZmF1bHRMb2NhbGUoIGxjaWQgKTsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJY3JlYXRlX3JlZ2lzdHJ5X2tleQogKgogKiBDcmVhdGUgdGhlIENvbnRyb2wgUGFuZWxcXEludGVybmF0aW9uYWwgcmVnaXN0cnkga2V5LgogKi8Kc3RhdGljIGlubGluZSBIQU5ETEUgY3JlYXRlX3JlZ2lzdHJ5X2tleSh2b2lkKQp7CiAgICBzdGF0aWMgY29uc3QgV0NIQVIgaW50bFdbXSA9IHsnQycsJ28nLCduJywndCcsJ3InLCdvJywnbCcsJyAnLCdQJywnYScsJ24nLCdlJywnbCcsJ1xcJywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICdJJywnbicsJ3QnLCdlJywncicsJ24nLCdhJywndCcsJ2knLCdvJywnbicsJ2EnLCdsJywwfTsKICAgIE9CSkVDVF9BVFRSSUJVVEVTIGF0dHI7CiAgICBVTklDT0RFX1NUUklORyBuYW1lVzsKICAgIEhBTkRMRSBoa2V5OwoKICAgIGlmIChSdGxPcGVuQ3VycmVudFVzZXIoIEtFWV9BTExfQUNDRVNTLCAmaGtleSApICE9IFNUQVRVU19TVUNDRVNTKSByZXR1cm4gMDsKCiAgICBhdHRyLkxlbmd0aCA9IHNpemVvZihhdHRyKTsKICAgIGF0dHIuUm9vdERpcmVjdG9yeSA9IGhrZXk7CiAgICBhdHRyLk9iamVjdE5hbWUgPSAmbmFtZVc7CiAgICBhdHRyLkF0dHJpYnV0ZXMgPSAwOwogICAgYXR0ci5TZWN1cml0eURlc2NyaXB0b3IgPSBOVUxMOwogICAgYXR0ci5TZWN1cml0eVF1YWxpdHlPZlNlcnZpY2UgPSBOVUxMOwogICAgUnRsSW5pdFVuaWNvZGVTdHJpbmcoICZuYW1lVywgaW50bFcgKTsKCiAgICBpZiAoTnRDcmVhdGVLZXkoICZoa2V5LCBLRVlfQUxMX0FDQ0VTUywgJmF0dHIsIDAsIE5VTEwsIDAsIE5VTEwgKSAhPSBTVEFUVVNfU1VDQ0VTUykgaGtleSA9IDA7CiAgICBOdENsb3NlKCBhdHRyLlJvb3REaXJlY3RvcnkgKTsKICAgIHJldHVybiBoa2V5Owp9CgoKLyogdXBkYXRlIHRoZSByZWdpc3RyeSBzZXR0aW5ncyBmb3IgYSBnaXZlbiBsb2NhbGUgcGFyYW1ldGVyICovCi8qIHJldHVybiBUUlVFIGlmIGFuIHVwZGF0ZSB3YXMgbmVlZGVkICovCnN0YXRpYyBCT09MIGxvY2FsZV91cGRhdGVfcmVnaXN0cnkoIEhLRVkgaGtleSwgY29uc3QgV0NIQVIgKm5hbWUsIExDSUQgbGNpZCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgTENUWVBFICp2YWx1ZXMsIFVJTlQgbmJfdmFsdWVzICkKewogICAgc3RhdGljIGNvbnN0IFdDSEFSIGZvcm1hdFdbXSA9IHsgJyUnLCcwJywnOCcsJ3gnLDAgfTsKICAgIFdDSEFSIGJ1ZmZlcldbNDBdOwogICAgVU5JQ09ERV9TVFJJTkcgbmFtZVc7CiAgICBEV09SRCBjb3VudCwgaTsKCiAgICBSdGxJbml0VW5pY29kZVN0cmluZyggJm5hbWVXLCBuYW1lICk7CiAgICBjb3VudCA9IHNpemVvZihidWZmZXJXKTsKICAgIGlmICghTnRRdWVyeVZhbHVlS2V5KGhrZXksICZuYW1lVywgS2V5VmFsdWVQYXJ0aWFsSW5mb3JtYXRpb24sIChMUEJZVEUpYnVmZmVyVywgY291bnQsICZjb3VudCkpCiAgICB7CiAgICAgICAgY29uc3QgS0VZX1ZBTFVFX1BBUlRJQUxfSU5GT1JNQVRJT04gKmluZm8gPSAoS0VZX1ZBTFVFX1BBUlRJQUxfSU5GT1JNQVRJT04gKilidWZmZXJXOwogICAgICAgIExQQ1dTVFIgdGV4dCA9IChMUENXU1RSKWluZm8tPkRhdGE7CgogICAgICAgIGlmIChzdHJ0b3VsVyggdGV4dCwgTlVMTCwgMTYgKSA9PSBsY2lkKSByZXR1cm4gRkFMU0U7IC8qIGFscmVhZHkgc2V0IGNvcnJlY3RseSAqLwogICAgICAgIFRSQUNFKCAidXBkYXRpbmcgcmVnaXN0cnksIGxvY2FsZSAlcyBjaGFuZ2VkICVzIC0+ICUwOHhcbiIsCiAgICAgICAgICAgICAgIGRlYnVnc3RyX3cobmFtZSksIGRlYnVnc3RyX3codGV4dCksIGxjaWQgKTsKICAgIH0KICAgIGVsc2UgVFJBQ0UoICJ1cGRhdGluZyByZWdpc3RyeSwgbG9jYWxlICVzIGNoYW5nZWQgbm9uZSAtPiAlMDh4XG4iLCBkZWJ1Z3N0cl93KG5hbWUpLCBsY2lkICk7CiAgICBzcHJpbnRmVyggYnVmZmVyVywgZm9ybWF0VywgbGNpZCApOwogICAgTnRTZXRWYWx1ZUtleSggaGtleSwgJm5hbWVXLCAwLCBSRUdfU1osIGJ1ZmZlclcsIChzdHJsZW5XKGJ1ZmZlclcpICsgMSkgKiBzaXplb2YoV0NIQVIpICk7CgogICAgZm9yIChpID0gMDsgaSA8IG5iX3ZhbHVlczsgaSsrKQogICAgewogICAgICAgIEdldExvY2FsZUluZm9XKCBsY2lkLCB2YWx1ZXNbaV0gfCBMT0NBTEVfTk9VU0VST1ZFUlJJREUsIGJ1ZmZlclcsCiAgICAgICAgICAgICAgICAgICAgICAgIHNpemVvZihidWZmZXJXKS9zaXplb2YoV0NIQVIpICk7CiAgICAgICAgU2V0TG9jYWxlSW5mb1coIGxjaWQsIHZhbHVlc1tpXSwgYnVmZmVyVyApOwogICAgfQogICAgcmV0dXJuIFRSVUU7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCUxPQ0FMRV9Jbml0UmVnaXN0cnkKICoKICogVXBkYXRlIHJlZ2lzdHJ5IGNvbnRlbnRzIG9uIHN0YXJ0dXAgaWYgdGhlIHVzZXIgbG9jYWxlIGhhcyBjaGFuZ2VkLgogKiBUaGlzIHNpbXVsYXRlcyB0aGUgYWN0aW9uIG9mIHRoZSBXaW5kb3dzIGNvbnRyb2wgcGFuZWwuCiAqLwp2b2lkIExPQ0FMRV9Jbml0UmVnaXN0cnkodm9pZCkKewogICAgc3RhdGljIGNvbnN0IFdDSEFSIENvZGVwYWdlV1tdID0geydDJywnbycsJ2QnLCdlJywncCcsJ2EnLCdnJywnZScsMH07CiAgICBzdGF0aWMgY29uc3QgV0NIQVIgYWNwV1tdID0geydBJywnQycsJ1AnLDB9OwogICAgc3RhdGljIGNvbnN0IFdDSEFSIG9lbWNwV1tdID0geydPJywnRScsJ00nLCdDJywnUCcsMH07CiAgICBzdGF0aWMgY29uc3QgV0NIQVIgbWFjY3BXW10gPSB7J00nLCdBJywnQycsJ0MnLCdQJywwfTsKICAgIHN0YXRpYyBjb25zdCBXQ0hBUiBsb2NhbGVXW10gPSB7J0wnLCdvJywnYycsJ2EnLCdsJywnZScsMH07CiAgICBzdGF0aWMgY29uc3QgV0NIQVIgbGNfY3R5cGVXW10gPSB7ICdMJywnQycsJ18nLCdDJywnVCcsJ1knLCdQJywnRScsMCB9OwogICAgc3RhdGljIGNvbnN0IFdDSEFSIGxjX21vbmV0YXJ5V1tdID0geyAnTCcsJ0MnLCdfJywnTScsJ08nLCdOJywnRScsJ1QnLCdBJywnUicsJ1knLDAgfTsKICAgIHN0YXRpYyBjb25zdCBXQ0hBUiBsY19udW1lcmljV1tdID0geyAnTCcsJ0MnLCdfJywnTicsJ1UnLCdNJywnRScsJ1InLCdJJywnQycsMCB9OwogICAgc3RhdGljIGNvbnN0IFdDSEFSIGxjX3RpbWVXW10gPSB7ICdMJywnQycsJ18nLCdUJywnSScsJ00nLCdFJywwIH07CiAgICBzdGF0aWMgY29uc3QgV0NIQVIgbGNfbWVhc3VyZW1lbnRXW10gPSB7ICdMJywnQycsJ18nLCdNJywnRScsJ0EnLCdTJywnVScsJ1InLCdFJywnTScsJ0UnLCdOJywnVCcsMCB9OwogICAgc3RhdGljIGNvbnN0IFdDSEFSIGxjX3RlbGVwaG9uZVdbXSA9IHsgJ0wnLCdDJywnXycsJ1QnLCdFJywnTCcsJ0UnLCdQJywnSCcsJ08nLCdOJywnRScsMCB9OwogICAgc3RhdGljIGNvbnN0IFdDSEFSIGxjX3BhcGVyV1tdID0geyAnTCcsJ0MnLCdfJywnUCcsJ0EnLCdQJywnRScsJ1InLDB9OwogICAgc3RhdGljIGNvbnN0IHN0cnVjdAogICAgewogICAgICAgIExQQ1dTVFIgbmFtZTsKICAgICAgICBVU0hPUlQgdmFsdWU7CiAgICB9IHVwZGF0ZV9jcF92YWx1ZXNbXSA9IHsKICAgICAgICB7IGFjcFcsIExPQ0FMRV9JREVGQVVMVEFOU0lDT0RFUEFHRSB9LAogICAgICAgIHsgb2VtY3BXLCBMT0NBTEVfSURFRkFVTFRDT0RFUEFHRSB9LAogICAgICAgIHsgbWFjY3BXLCBMT0NBTEVfSURFRkFVTFRNQUNDT0RFUEFHRSB9CiAgICB9OwogICAgc3RhdGljIGNvbnN0IExDVFlQRSBsY19tZXNzYWdlc192YWx1ZXNbXSA9IHsKICAgICAgTE9DQUxFX1NMQU5HVUFHRSwKICAgICAgTE9DQUxFX1NDT1VOVFJZLAogICAgICBMT0NBTEVfU0xJU1QgfTsKICAgIHN0YXRpYyBjb25zdCBMQ1RZUEUgbGNfbW9uZXRhcnlfdmFsdWVzW10gPSB7CiAgICAgIExPQ0FMRV9TQ1VSUkVOQ1ksCiAgICAgIExPQ0FMRV9JQ1VSUkVOQ1ksCiAgICAgIExPQ0FMRV9JTkVHQ1VSUiwKICAgICAgTE9DQUxFX0lDVVJSRElHSVRTLAogICAgICBMT0NBTEVfSUxaRVJPLAogICAgICBMT0NBTEVfU01PTkRFQ0lNQUxTRVAsCiAgICAgIExPQ0FMRV9TTU9OR1JPVVBJTkcsCiAgICAgIExPQ0FMRV9TTU9OVEhPVVNBTkRTRVAgfTsKICAgIHN0YXRpYyBjb25zdCBMQ1RZUEUgbGNfbnVtZXJpY192YWx1ZXNbXSA9IHsKICAgICAgTE9DQUxFX1NERUNJTUFMLAogICAgICBMT0NBTEVfU1RIT1VTQU5ELAogICAgICBMT0NBTEVfSURJR0lUUywKICAgICAgTE9DQUxFX0lESUdJVFNVQlNUSVRVVElPTiwKICAgICAgTE9DQUxFX1NOQVRJVkVESUdJVFMsCiAgICAgIExPQ0FMRV9JTkVHTlVNQkVSLAogICAgICBMT0NBTEVfU05FR0FUSVZFU0lHTiwKICAgICAgTE9DQUxFX1NQT1NJVElWRVNJR04sCiAgICAgIExPQ0FMRV9TR1JPVVBJTkcgfTsKICAgIHN0YXRpYyBjb25zdCBMQ1RZUEUgbGNfdGltZV92YWx1ZXNbXSA9IHsKICAgICAgTE9DQUxFX1MxMTU5LAogICAgICBMT0NBTEVfUzIzNTksCiAgICAgIExPQ0FMRV9TVElNRSwKICAgICAgTE9DQUxFX0lUSU1FLAogICAgICBMT0NBTEVfSVRMWkVSTywKICAgICAgTE9DQUxFX1NTSE9SVERBVEUsCiAgICAgIExPQ0FMRV9TTE9OR0RBVEUsCiAgICAgIExPQ0FMRV9TREFURSwKICAgICAgTE9DQUxFX0lUSU1FTUFSS1BPU04sCiAgICAgIExPQ0FMRV9JQ0FMRU5EQVJUWVBFLAogICAgICBMT0NBTEVfSUZJUlNUREFZT0ZXRUVLLAogICAgICBMT0NBTEVfSUZJUlNUV0VFS09GWUVBUiwKICAgICAgTE9DQUxFX1NUSU1FRk9STUFULAogICAgICBMT0NBTEVfU1lFQVJNT05USCwKICAgICAgTE9DQUxFX0lEQVRFIH07CiAgICBzdGF0aWMgY29uc3QgTENUWVBFIGxjX21lYXN1cmVtZW50X3ZhbHVlc1tdID0geyBMT0NBTEVfSU1FQVNVUkUgfTsKICAgIHN0YXRpYyBjb25zdCBMQ1RZUEUgbGNfdGVsZXBob25lX3ZhbHVlc1tdID0geyBMT0NBTEVfSUNPVU5UUlkgfTsKICAgIHN0YXRpYyBjb25zdCBMQ1RZUEUgbGNfcGFwZXJfdmFsdWVzW10gPSB7IExPQ0FMRV9JUEFQRVJTSVpFIH07CgogICAgVU5JQ09ERV9TVFJJTkcgbmFtZVc7CiAgICBXQ0hBUiBidWZmZXJXWzgwXTsKICAgIERXT1JEIGNvdW50LCBpOwogICAgSEFORExFIGhrZXk7CiAgICBMQ0lEIGxjaWQgPSBHZXRVc2VyRGVmYXVsdExDSUQoKTsKCiAgICBpZiAoIShoa2V5ID0gY3JlYXRlX3JlZ2lzdHJ5X2tleSgpKSkKICAgICAgICByZXR1cm47ICAvKiBkb24ndCBkbyBhbnl0aGluZyBpZiB3ZSBjYW4ndCBjcmVhdGUgdGhlIHJlZ2lzdHJ5IGtleSAqLwoKICAgIGxvY2FsZV91cGRhdGVfcmVnaXN0cnkoIGhrZXksIGxvY2FsZVcsIGxjaWRfTENfTUVTU0FHRVMsIGxjX21lc3NhZ2VzX3ZhbHVlcywKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNpemVvZihsY19tZXNzYWdlc192YWx1ZXMpL3NpemVvZihsY19tZXNzYWdlc192YWx1ZXNbMF0pICk7CiAgICBsb2NhbGVfdXBkYXRlX3JlZ2lzdHJ5KCBoa2V5LCBsY19tb25ldGFyeVcsIGxjaWRfTENfTU9ORVRBUlksIGxjX21vbmV0YXJ5X3ZhbHVlcywKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNpemVvZihsY19tb25ldGFyeV92YWx1ZXMpL3NpemVvZihsY19tb25ldGFyeV92YWx1ZXNbMF0pICk7CiAgICBsb2NhbGVfdXBkYXRlX3JlZ2lzdHJ5KCBoa2V5LCBsY19udW1lcmljVywgbGNpZF9MQ19OVU1FUklDLCBsY19udW1lcmljX3ZhbHVlcywKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNpemVvZihsY19udW1lcmljX3ZhbHVlcykvc2l6ZW9mKGxjX251bWVyaWNfdmFsdWVzWzBdKSApOwogICAgbG9jYWxlX3VwZGF0ZV9yZWdpc3RyeSggaGtleSwgbGNfdGltZVcsIGxjaWRfTENfVElNRSwgbGNfdGltZV92YWx1ZXMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzaXplb2YobGNfdGltZV92YWx1ZXMpL3NpemVvZihsY190aW1lX3ZhbHVlc1swXSkgKTsKICAgIGxvY2FsZV91cGRhdGVfcmVnaXN0cnkoIGhrZXksIGxjX21lYXN1cmVtZW50VywgbGNpZF9MQ19NRUFTVVJFTUVOVCwgbGNfbWVhc3VyZW1lbnRfdmFsdWVzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgc2l6ZW9mKGxjX21lYXN1cmVtZW50X3ZhbHVlcykvc2l6ZW9mKGxjX21lYXN1cmVtZW50X3ZhbHVlc1swXSkgKTsKICAgIGxvY2FsZV91cGRhdGVfcmVnaXN0cnkoIGhrZXksIGxjX3RlbGVwaG9uZVcsIGxjaWRfTENfVEVMRVBIT05FLCBsY190ZWxlcGhvbmVfdmFsdWVzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgc2l6ZW9mKGxjX3RlbGVwaG9uZV92YWx1ZXMpL3NpemVvZihsY190ZWxlcGhvbmVfdmFsdWVzWzBdKSApOwogICAgbG9jYWxlX3VwZGF0ZV9yZWdpc3RyeSggaGtleSwgbGNfcGFwZXJXLCBsY2lkX0xDX1BBUEVSLCBsY19wYXBlcl92YWx1ZXMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzaXplb2YobGNfcGFwZXJfdmFsdWVzKS9zaXplb2YobGNfcGFwZXJfdmFsdWVzWzBdKSApOwoKICAgIGlmIChsb2NhbGVfdXBkYXRlX3JlZ2lzdHJ5KCBoa2V5LCBsY19jdHlwZVcsIGxjaWRfTENfQ1RZUEUsIE5VTEwsIDAgKSkKICAgIHsKICAgICAgICBIS0VZIG5sc19rZXkgPSBOTFNfUmVnT3BlblN1YktleSggTkxTX1JlZ09wZW5LZXkoIDAsIHN6TmxzS2V5TmFtZSApLCBDb2RlcGFnZVcgKTsKCiAgICAgICAgZm9yIChpID0gMDsgaSA8IHNpemVvZih1cGRhdGVfY3BfdmFsdWVzKS9zaXplb2YodXBkYXRlX2NwX3ZhbHVlc1swXSk7IGkrKykKICAgICAgICB7CiAgICAgICAgICAgIGNvdW50ID0gR2V0TG9jYWxlSW5mb1coIGxjaWQsIHVwZGF0ZV9jcF92YWx1ZXNbaV0udmFsdWUgfCBMT0NBTEVfTk9VU0VST1ZFUlJJREUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJ1ZmZlclcsIHNpemVvZihidWZmZXJXKS9zaXplb2YoV0NIQVIpICk7CiAgICAgICAgICAgIFJ0bEluaXRVbmljb2RlU3RyaW5nKCAmbmFtZVcsIHVwZGF0ZV9jcF92YWx1ZXNbaV0ubmFtZSApOwogICAgICAgICAgICBOdFNldFZhbHVlS2V5KCBubHNfa2V5LCAmbmFtZVcsIDAsIFJFR19TWiwgYnVmZmVyVywgY291bnQgKiBzaXplb2YoV0NIQVIpICk7CiAgICAgICAgfQogICAgICAgIE50Q2xvc2UoIG5sc19rZXkgKTsKICAgIH0KCiAgICBOdENsb3NlKCBoa2V5ICk7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICAgICAgIHNldHVwX3VuaXhfbG9jYWxlcwogKi8Kc3RhdGljIFVJTlQgc2V0dXBfdW5peF9sb2NhbGVzKHZvaWQpCnsKICAgIHN0cnVjdCBsb2NhbGVfbmFtZSBsb2NhbGVfbmFtZTsKICAgIFdDSEFSIGJ1ZmZlclsxMjhdLCBjdHlwZV9idWZmWzEyOF07CiAgICBjaGFyICpsb2NhbGU7CiAgICBVSU5UIHVuaXhfY3AgPSAwOwoKICAgIGlmICgobG9jYWxlID0gc2V0bG9jYWxlKCBMQ19DVFlQRSwgTlVMTCApKSkKICAgIHsKICAgICAgICBzdHJjcHluQXRvVyggY3R5cGVfYnVmZiwgbG9jYWxlLCBzaXplb2YoY3R5cGVfYnVmZikvc2l6ZW9mKFdDSEFSKSApOwogICAgICAgIHBhcnNlX2xvY2FsZV9uYW1lKCBjdHlwZV9idWZmLCAmbG9jYWxlX25hbWUgKTsKICAgICAgICBsY2lkX0xDX0NUWVBFID0gbG9jYWxlX25hbWUubGNpZDsKICAgICAgICB1bml4X2NwID0gbG9jYWxlX25hbWUuY29kZXBhZ2U7CiAgICB9CiAgICBpZiAoIWxjaWRfTENfQ1RZUEUpICAvKiB0aGlzIG9uZSBuZWVkcyBhIGRlZmF1bHQgdmFsdWUgKi8KICAgICAgICBsY2lkX0xDX0NUWVBFID0gTUFLRUxDSUQoIE1BS0VMQU5HSUQoTEFOR19FTkdMSVNILFNVQkxBTkdfREVGQVVMVCksIFNPUlRfREVGQVVMVCApOwoKICAgIFRSQUNFKCAiZ290IGxjaWQgJTA0eCAoJWQgbWF0Y2hlcykgZm9yIExDX0NUWVBFPSVzXG4iLAogICAgICAgICAgIGxvY2FsZV9uYW1lLmxjaWQsIGxvY2FsZV9uYW1lLm1hdGNoZXMsIGRlYnVnc3RyX2EobG9jYWxlKSApOwoKI2RlZmluZSBHRVRfVU5JWF9MT0NBTEUoY2F0KSBkbyBcCiAgICBpZiAoKGxvY2FsZSA9IHNldGxvY2FsZSggY2F0LCBOVUxMICkpKSBcCiAgICB7IFwKICAgICAgICBzdHJjcHluQXRvVyggYnVmZmVyLCBsb2NhbGUsIHNpemVvZihidWZmZXIpL3NpemVvZihXQ0hBUikgKTsgXAogICAgICAgIGlmICghc3RyY21wVyggYnVmZmVyLCBjdHlwZV9idWZmICkpIGxjaWRfIyNjYXQgPSBsY2lkX0xDX0NUWVBFOyBcCiAgICAgICAgZWxzZSB7IFwKICAgICAgICAgICAgcGFyc2VfbG9jYWxlX25hbWUoIGJ1ZmZlciwgJmxvY2FsZV9uYW1lICk7ICBcCiAgICAgICAgICAgIGxjaWRfIyNjYXQgPSBsb2NhbGVfbmFtZS5sY2lkOyBcCiAgICAgICAgICAgIFRSQUNFKCAiZ290IGxjaWQgJTA0eCAoJWQgbWF0Y2hlcykgZm9yICIgI2NhdCAiPSVzXG4iLCAgICAgICAgXAogICAgICAgICAgICAgICAgICAgbG9jYWxlX25hbWUubGNpZCwgbG9jYWxlX25hbWUubWF0Y2hlcywgZGVidWdzdHJfYShsb2NhbGUpICk7IFwKICAgICAgICB9IFwKICAgIH0gd2hpbGUgKDApCgogICAgR0VUX1VOSVhfTE9DQUxFKCBMQ19DT0xMQVRFICk7CiAgICBHRVRfVU5JWF9MT0NBTEUoIExDX01FU1NBR0VTICk7CiAgICBHRVRfVU5JWF9MT0NBTEUoIExDX01PTkVUQVJZICk7CiAgICBHRVRfVU5JWF9MT0NBTEUoIExDX05VTUVSSUMgKTsKICAgIEdFVF9VTklYX0xPQ0FMRSggTENfVElNRSApOwojaWZkZWYgTENfUEFQRVIKICAgIEdFVF9VTklYX0xPQ0FMRSggTENfUEFQRVIgKTsKI2VuZGlmCiNpZmRlZiBMQ19NRUFTVVJFTUVOVAogICAgR0VUX1VOSVhfTE9DQUxFKCBMQ19NRUFTVVJFTUVOVCApOwojZW5kaWYKI2lmZGVmIExDX1RFTEVQSE9ORQogICAgR0VUX1VOSVhfTE9DQUxFKCBMQ19URUxFUEhPTkUgKTsKI2VuZGlmCgojdW5kZWYgR0VUX1VOSVhfTE9DQUxFCgogICAgcmV0dXJuIHVuaXhfY3A7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCUdldFVzZXJEZWZhdWx0TGFuZ0lEIChLRVJORUwzMi5AKQogKgogKiBHZXQgdGhlIGRlZmF1bHQgbGFuZ3VhZ2UgSWQgZm9yIHRoZSBjdXJyZW50IHVzZXIuCiAqCiAqIFBBUkFNUwogKiAgTm9uZS4KICoKICogUkVUVVJOUwogKiAgVGhlIGN1cnJlbnQgTEFOR0lEIG9mIHRoZSBkZWZhdWx0IGxhbmd1YWdlIGZvciB0aGUgY3VycmVudCB1c2VyLgogKi8KTEFOR0lEIFdJTkFQSSBHZXRVc2VyRGVmYXVsdExhbmdJRCh2b2lkKQp7CiAgICByZXR1cm4gTEFOR0lERlJPTUxDSUQoR2V0VXNlckRlZmF1bHRMQ0lEKCkpOwp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCQlHZXRTeXN0ZW1EZWZhdWx0TGFuZ0lEIChLRVJORUwzMi5AKQogKgogKiBHZXQgdGhlIGRlZmF1bHQgbGFuZ3VhZ2UgSWQgZm9yIHRoZSBzeXN0ZW0uCiAqCiAqIFBBUkFNUwogKiAgTm9uZS4KICoKICogUkVUVVJOUwogKiAgVGhlIGN1cnJlbnQgTEFOR0lEIG9mIHRoZSBkZWZhdWx0IGxhbmd1YWdlIGZvciB0aGUgc3lzdGVtLgogKi8KTEFOR0lEIFdJTkFQSSBHZXRTeXN0ZW1EZWZhdWx0TGFuZ0lEKHZvaWQpCnsKICAgIHJldHVybiBMQU5HSURGUk9NTENJRChHZXRTeXN0ZW1EZWZhdWx0TENJRCgpKTsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJR2V0VXNlckRlZmF1bHRMQ0lEIChLRVJORUwzMi5AKQogKgogKiBHZXQgdGhlIGRlZmF1bHQgbG9jYWxlIElkIGZvciB0aGUgY3VycmVudCB1c2VyLgogKgogKiBQQVJBTVMKICogIE5vbmUuCiAqCiAqIFJFVFVSTlMKICogIFRoZSBjdXJyZW50IExDSUQgb2YgdGhlIGRlZmF1bHQgbG9jYWxlIGZvciB0aGUgY3VycmVudCB1c2VyLgogKi8KTENJRCBXSU5BUEkgR2V0VXNlckRlZmF1bHRMQ0lEKHZvaWQpCnsKICAgIExDSUQgbGNpZDsKICAgIE50UXVlcnlEZWZhdWx0TG9jYWxlKCBUUlVFLCAmbGNpZCApOwogICAgcmV0dXJuIGxjaWQ7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCUdldFN5c3RlbURlZmF1bHRMQ0lEIChLRVJORUwzMi5AKQogKgogKiBHZXQgdGhlIGRlZmF1bHQgbG9jYWxlIElkIGZvciB0aGUgc3lzdGVtLgogKgogKiBQQVJBTVMKICogIE5vbmUuCiAqCiAqIFJFVFVSTlMKICogIFRoZSBjdXJyZW50IExDSUQgb2YgdGhlIGRlZmF1bHQgbG9jYWxlIGZvciB0aGUgc3lzdGVtLgogKi8KTENJRCBXSU5BUEkgR2V0U3lzdGVtRGVmYXVsdExDSUQodm9pZCkKewogICAgTENJRCBsY2lkOwogICAgTnRRdWVyeURlZmF1bHRMb2NhbGUoIEZBTFNFLCAmbGNpZCApOwogICAgcmV0dXJuIGxjaWQ7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCUdldFVzZXJEZWZhdWx0VUlMYW5ndWFnZSAoS0VSTkVMMzIuQCkKICoKICogR2V0IHRoZSBkZWZhdWx0IHVzZXIgaW50ZXJmYWNlIGxhbmd1YWdlIElkIGZvciB0aGUgY3VycmVudCB1c2VyLgogKgogKiBQQVJBTVMKICogIE5vbmUuCiAqCiAqIFJFVFVSTlMKICogIFRoZSBjdXJyZW50IExBTkdJRCBvZiB0aGUgZGVmYXVsdCBVSSBsYW5ndWFnZSBmb3IgdGhlIGN1cnJlbnQgdXNlci4KICovCkxBTkdJRCBXSU5BUEkgR2V0VXNlckRlZmF1bHRVSUxhbmd1YWdlKHZvaWQpCnsKICAgIExBTkdJRCBsYW5nOwogICAgTnRRdWVyeURlZmF1bHRVSUxhbmd1YWdlKCAmbGFuZyApOwogICAgcmV0dXJuIGxhbmc7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCUdldFN5c3RlbURlZmF1bHRVSUxhbmd1YWdlIChLRVJORUwzMi5AKQogKgogKiBHZXQgdGhlIGRlZmF1bHQgdXNlciBpbnRlcmZhY2UgbGFuZ3VhZ2UgSWQgZm9yIHRoZSBzeXN0ZW0uCiAqCiAqIFBBUkFNUwogKiAgTm9uZS4KICoKICogUkVUVVJOUwogKiAgVGhlIGN1cnJlbnQgTEFOR0lEIG9mIHRoZSBkZWZhdWx0IFVJIGxhbmd1YWdlIGZvciB0aGUgc3lzdGVtLiBUaGlzIGlzCiAqICB0eXBpY2FsbHkgdGhlIHNhbWUgbGFuZ3VhZ2UgdXNlZCBkdXJpbmcgdGhlIGluc3RhbGxhdGlvbiBwcm9jZXNzLgogKi8KTEFOR0lEIFdJTkFQSSBHZXRTeXN0ZW1EZWZhdWx0VUlMYW5ndWFnZSh2b2lkKQp7CiAgICBMQU5HSUQgbGFuZzsKICAgIE50UXVlcnlJbnN0YWxsVUlMYW5ndWFnZSggJmxhbmcgKTsKICAgIHJldHVybiBsYW5nOwp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgICAgICBMb2NhbGVOYW1lVG9MQ0lEICAoS0VSTkVMMzIuQCkKICovCkxDSUQgV0lOQVBJIExvY2FsZU5hbWVUb0xDSUQoIExQQ1dTVFIgbmFtZSwgRFdPUkQgZmxhZ3MgKQp7CiAgICBzdHJ1Y3QgbG9jYWxlX25hbWUgbG9jYWxlX25hbWU7CgogICAgaWYgKGZsYWdzKSBGSVhNRSggInVuc3VwcG9ydGVkIGZsYWdzICV4XG4iLCBmbGFncyApOwoKICAgIHBhcnNlX2xvY2FsZV9uYW1lKCBuYW1lLCAmbG9jYWxlX25hbWUgKTsKCiAgICBUUkFDRSggImZvdW5kIGxjaWQgJXggZm9yICVzLCBtYXRjaGVzICVkXG4iLAogICAgICAgICAgIGxvY2FsZV9uYW1lLmxjaWQsIGRlYnVnc3RyX3cobmFtZSksIGxvY2FsZV9uYW1lLm1hdGNoZXMgKTsKCiAgICBpZiAoIWxvY2FsZV9uYW1lLm1hdGNoZXMpCiAgICAgICAgV0FSTiggImxvY2FsZSAlcyBub3QgcmVjb2duaXplZCwgZGVmYXVsdGluZyB0byBFbmdsaXNoXG4iLCBkZWJ1Z3N0cl93KG5hbWUpICk7CiAgICBlbHNlIGlmIChsb2NhbGVfbmFtZS5tYXRjaGVzID09IDEpCiAgICAgICAgV0FSTiggImxvY2FsZSAlcyBub3QgcmVjb2duaXplZCwgZGVmYXVsdGluZyB0byAlc1xuIiwKICAgICAgICAgICAgICBkZWJ1Z3N0cl93KG5hbWUpLCBkZWJ1Z3N0cl93KGxvY2FsZV9uYW1lLmxhbmcpICk7CgogICAgcmV0dXJuIGxvY2FsZV9uYW1lLmxjaWQ7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICAgICAgIExDSURUb0xvY2FsZU5hbWUgIChLRVJORUwzMi5AKQogKi8KSU5UIFdJTkFQSSBMQ0lEVG9Mb2NhbGVOYW1lKCBMQ0lEIGxjaWQsIExQV1NUUiBuYW1lLCBJTlQgY291bnQsIERXT1JEIGZsYWdzICkKewogICAgaWYgKGZsYWdzKSBGSVhNRSggInVuc3VwcG9ydGVkIGZsYWdzICV4XG4iLCBmbGFncyApOwoKICAgIHJldHVybiBHZXRMb2NhbGVJbmZvVyggbGNpZCwgTE9DQUxFX1NOQU1FIHwgTE9DQUxFX05PVVNFUk9WRVJSSURFLCBuYW1lLCBjb3VudCApOwp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJZ2V0X2xvY2FsZV92YWx1ZV9uYW1lCiAqCiAqIEdldHMgdGhlIHJlZ2lzdHJ5IHZhbHVlIG5hbWUgZm9yIGEgZ2l2ZW4gbGN0eXBlLgogKi8Kc3RhdGljIGNvbnN0IFdDSEFSICpnZXRfbG9jYWxlX3ZhbHVlX25hbWUoIERXT1JEIGxjdHlwZSApCnsKICAgIHN0YXRpYyBjb25zdCBXQ0hBUiBpQ2FsZW5kYXJUeXBlV1tdID0geydpJywnQycsJ2EnLCdsJywnZScsJ24nLCdkJywnYScsJ3InLCdUJywneScsJ3AnLCdlJywwfTsKICAgIHN0YXRpYyBjb25zdCBXQ0hBUiBpQ291bnRyeVdbXSA9IHsnaScsJ0MnLCdvJywndScsJ24nLCd0JywncicsJ3knLDB9OwogICAgc3RhdGljIGNvbnN0IFdDSEFSIGlDdXJyRGlnaXRzV1tdID0geydpJywnQycsJ3UnLCdyJywncicsJ0QnLCdpJywnZycsJ2knLCd0JywncycsMH07CiAgICBzdGF0aWMgY29uc3QgV0NIQVIgaUN1cnJlbmN5V1tdID0geydpJywnQycsJ3UnLCdyJywncicsJ2UnLCduJywnYycsJ3knLDB9OwogICAgc3RhdGljIGNvbnN0IFdDSEFSIGlEYXRlV1tdID0geydpJywnRCcsJ2EnLCd0JywnZScsMH07CiAgICBzdGF0aWMgY29uc3QgV0NIQVIgaURpZ2l0c1dbXSA9IHsnaScsJ0QnLCdpJywnZycsJ2knLCd0JywncycsMH07CiAgICBzdGF0aWMgY29uc3QgV0NIQVIgaUZpcnN0RGF5T2ZXZWVrV1tdID0geydpJywnRicsJ2knLCdyJywncycsJ3QnLCdEJywnYScsJ3knLCdPJywnZicsJ1cnLCdlJywnZScsJ2snLDB9OwogICAgc3RhdGljIGNvbnN0IFdDSEFSIGlGaXJzdFdlZWtPZlllYXJXW10gPSB7J2knLCdGJywnaScsJ3InLCdzJywndCcsJ1cnLCdlJywnZScsJ2snLCdPJywnZicsJ1knLCdlJywnYScsJ3InLDB9OwogICAgc3RhdGljIGNvbnN0IFdDSEFSIGlMRGF0ZVdbXSA9IHsnaScsJ0wnLCdEJywnYScsJ3QnLCdlJywwfTsKICAgIHN0YXRpYyBjb25zdCBXQ0hBUiBpTFplcm9XW10gPSB7J2knLCdMJywnWicsJ2UnLCdyJywnbycsMH07CiAgICBzdGF0aWMgY29uc3QgV0NIQVIgaU1lYXN1cmVXW10gPSB7J2knLCdNJywnZScsJ2EnLCdzJywndScsJ3InLCdlJywwfTsKICAgIHN0YXRpYyBjb25zdCBXQ0hBUiBpTmVnQ3VycldbXSA9IHsnaScsJ04nLCdlJywnZycsJ0MnLCd1JywncicsJ3InLDB9OwogICAgc3RhdGljIGNvbnN0IFdDSEFSIGlOZWdOdW1iZXJXW10gPSB7J2knLCdOJywnZScsJ2cnLCdOJywndScsJ20nLCdiJywnZScsJ3InLDB9OwogICAgc3RhdGljIGNvbnN0IFdDSEFSIGlQYXBlclNpemVXW10gPSB7J2knLCdQJywnYScsJ3AnLCdlJywncicsJ1MnLCdpJywneicsJ2UnLDB9OwogICAgc3RhdGljIGNvbnN0IFdDSEFSIGlUTFplcm9XW10gPSB7J2knLCdUJywnTCcsJ1onLCdlJywncicsJ28nLDB9OwogICAgc3RhdGljIGNvbnN0IFdDSEFSIGlUaW1lUHJlZml4V1tdID0geydpJywnVCcsJ2knLCdtJywnZScsJ1AnLCdyJywnZScsJ2YnLCdpJywneCcsMH07CiAgICBzdGF0aWMgY29uc3QgV0NIQVIgaVRpbWVXW10gPSB7J2knLCdUJywnaScsJ20nLCdlJywwfTsKICAgIHN0YXRpYyBjb25zdCBXQ0hBUiBzMTE1OVdbXSA9IHsncycsJzEnLCcxJywnNScsJzknLDB9OwogICAgc3RhdGljIGNvbnN0IFdDSEFSIHMyMzU5V1tdID0geydzJywnMicsJzMnLCc1JywnOScsMH07CiAgICBzdGF0aWMgY29uc3QgV0NIQVIgc0NvdW50cnlXW10gPSB7J3MnLCdDJywnbycsJ3UnLCduJywndCcsJ3InLCd5JywwfTsKICAgIHN0YXRpYyBjb25zdCBXQ0hBUiBzQ3VycmVuY3lXW10gPSB7J3MnLCdDJywndScsJ3InLCdyJywnZScsJ24nLCdjJywneScsMH07CiAgICBzdGF0aWMgY29uc3QgV0NIQVIgc0RhdGVXW10gPSB7J3MnLCdEJywnYScsJ3QnLCdlJywwfTsKICAgIHN0YXRpYyBjb25zdCBXQ0hBUiBzRGVjaW1hbFdbXSA9IHsncycsJ0QnLCdlJywnYycsJ2knLCdtJywnYScsJ2wnLDB9OwogICAgc3RhdGljIGNvbnN0IFdDSEFSIHNHcm91cGluZ1dbXSA9IHsncycsJ0cnLCdyJywnbycsJ3UnLCdwJywnaScsJ24nLCdnJywwfTsKICAgIHN0YXRpYyBjb25zdCBXQ0hBUiBzTGFuZ3VhZ2VXW10gPSB7J3MnLCdMJywnYScsJ24nLCdnJywndScsJ2EnLCdnJywnZScsMH07CiAgICBzdGF0aWMgY29uc3QgV0NIQVIgc0xpc3RXW10gPSB7J3MnLCdMJywnaScsJ3MnLCd0JywwfTsKICAgIHN0YXRpYyBjb25zdCBXQ0hBUiBzTG9uZ0RhdGVXW10gPSB7J3MnLCdMJywnbycsJ24nLCdnJywnRCcsJ2EnLCd0JywnZScsMH07CiAgICBzdGF0aWMgY29uc3QgV0NIQVIgc01vbkRlY2ltYWxTZXBXW10gPSB7J3MnLCdNJywnbycsJ24nLCdEJywnZScsJ2MnLCdpJywnbScsJ2EnLCdsJywnUycsJ2UnLCdwJywwfTsKICAgIHN0YXRpYyBjb25zdCBXQ0hBUiBzTW9uR3JvdXBpbmdXW10gPSB7J3MnLCdNJywnbycsJ24nLCdHJywncicsJ28nLCd1JywncCcsJ2knLCduJywnZycsMH07CiAgICBzdGF0aWMgY29uc3QgV0NIQVIgc01vblRob3VzYW5kU2VwV1tdID0geydzJywnTScsJ28nLCduJywnVCcsJ2gnLCdvJywndScsJ3MnLCdhJywnbicsJ2QnLCdTJywnZScsJ3AnLDB9OwogICAgc3RhdGljIGNvbnN0IFdDSEFSIHNOYXRpdmVEaWdpdHNXW10gPSB7J3MnLCdOJywnYScsJ3QnLCdpJywndicsJ2UnLCdEJywnaScsJ2cnLCdpJywndCcsJ3MnLDB9OwogICAgc3RhdGljIGNvbnN0IFdDSEFSIHNOZWdhdGl2ZVNpZ25XW10gPSB7J3MnLCdOJywnZScsJ2cnLCdhJywndCcsJ2knLCd2JywnZScsJ1MnLCdpJywnZycsJ24nLDB9OwogICAgc3RhdGljIGNvbnN0IFdDSEFSIHNQb3NpdGl2ZVNpZ25XW10gPSB7J3MnLCdQJywnbycsJ3MnLCdpJywndCcsJ2knLCd2JywnZScsJ1MnLCdpJywnZycsJ24nLDB9OwogICAgc3RhdGljIGNvbnN0IFdDSEFSIHNTaG9ydERhdGVXW10gPSB7J3MnLCdTJywnaCcsJ28nLCdyJywndCcsJ0QnLCdhJywndCcsJ2UnLDB9OwogICAgc3RhdGljIGNvbnN0IFdDSEFSIHNUaG91c2FuZFdbXSA9IHsncycsJ1QnLCdoJywnbycsJ3UnLCdzJywnYScsJ24nLCdkJywwfTsKICAgIHN0YXRpYyBjb25zdCBXQ0hBUiBzVGltZUZvcm1hdFdbXSA9IHsncycsJ1QnLCdpJywnbScsJ2UnLCdGJywnbycsJ3InLCdtJywnYScsJ3QnLDB9OwogICAgc3RhdGljIGNvbnN0IFdDSEFSIHNUaW1lV1tdID0geydzJywnVCcsJ2knLCdtJywnZScsMH07CiAgICBzdGF0aWMgY29uc3QgV0NIQVIgc1llYXJNb250aFdbXSA9IHsncycsJ1knLCdlJywnYScsJ3InLCdNJywnbycsJ24nLCd0JywnaCcsMH07CiAgICBzdGF0aWMgY29uc3QgV0NIQVIgTnVtU2hhcGVXW10gPSB7J04nLCd1JywnbScsJ3MnLCdoJywnYScsJ3AnLCdlJywwfTsKCiAgICBzd2l0Y2ggKGxjdHlwZSkKICAgIHsKICAgIC8qIFRoZXNlIHZhbHVlcyBhcmUgdXNlZCBieSBTZXRMb2NhbGVJbmZvIGFuZCBHZXRMb2NhbGVJbmZvLCBhbmQKICAgICAqIHRoZSB2YWx1ZXMgYXJlIHN0b3JlZCBpbiB0aGUgcmVnaXN0cnksIGNvbmZpcm1lZCB1bmRlciBXaW5kb3dzLgogICAgICovCiAgICBjYXNlIExPQ0FMRV9JQ0FMRU5EQVJUWVBFOiAgICByZXR1cm4gaUNhbGVuZGFyVHlwZVc7CiAgICBjYXNlIExPQ0FMRV9JQ1VSUkRJR0lUUzogICAgICByZXR1cm4gaUN1cnJEaWdpdHNXOwogICAgY2FzZSBMT0NBTEVfSUNVUlJFTkNZOiAgICAgICAgcmV0dXJuIGlDdXJyZW5jeVc7CiAgICBjYXNlIExPQ0FMRV9JRElHSVRTOiAgICAgICAgICByZXR1cm4gaURpZ2l0c1c7CiAgICBjYXNlIExPQ0FMRV9JRklSU1REQVlPRldFRUs6ICByZXR1cm4gaUZpcnN0RGF5T2ZXZWVrVzsKICAgIGNhc2UgTE9DQUxFX0lGSVJTVFdFRUtPRllFQVI6IHJldHVybiBpRmlyc3RXZWVrT2ZZZWFyVzsKICAgIGNhc2UgTE9DQUxFX0lMWkVSTzogICAgICAgICAgIHJldHVybiBpTFplcm9XOwogICAgY2FzZSBMT0NBTEVfSU1FQVNVUkU6ICAgICAgICAgcmV0dXJuIGlNZWFzdXJlVzsKICAgIGNhc2UgTE9DQUxFX0lORUdDVVJSOiAgICAgICAgIHJldHVybiBpTmVnQ3Vyclc7CiAgICBjYXNlIExPQ0FMRV9JTkVHTlVNQkVSOiAgICAgICByZXR1cm4gaU5lZ051bWJlclc7CiAgICBjYXNlIExPQ0FMRV9JUEFQRVJTSVpFOiAgICAgICByZXR1cm4gaVBhcGVyU2l6ZVc7CiAgICBjYXNlIExPQ0FMRV9JVElNRTogICAgICAgICAgICByZXR1cm4gaVRpbWVXOwogICAgY2FzZSBMT0NBTEVfUzExNTk6ICAgICAgICAgICAgcmV0dXJuIHMxMTU5VzsKICAgIGNhc2UgTE9DQUxFX1MyMzU5OiAgICAgICAgICAgIHJldHVybiBzMjM1OVc7CiAgICBjYXNlIExPQ0FMRV9TQ1VSUkVOQ1k6ICAgICAgICByZXR1cm4gc0N1cnJlbmN5VzsKICAgIGNhc2UgTE9DQUxFX1NEQVRFOiAgICAgICAgICAgIHJldHVybiBzRGF0ZVc7CiAgICBjYXNlIExPQ0FMRV9TREVDSU1BTDogICAgICAgICByZXR1cm4gc0RlY2ltYWxXOwogICAgY2FzZSBMT0NBTEVfU0dST1VQSU5HOiAgICAgICAgcmV0dXJuIHNHcm91cGluZ1c7CiAgICBjYXNlIExPQ0FMRV9TTElTVDogICAgICAgICAgICByZXR1cm4gc0xpc3RXOwogICAgY2FzZSBMT0NBTEVfU0xPTkdEQVRFOiAgICAgICAgcmV0dXJuIHNMb25nRGF0ZVc7CiAgICBjYXNlIExPQ0FMRV9TTU9OREVDSU1BTFNFUDogICByZXR1cm4gc01vbkRlY2ltYWxTZXBXOwogICAgY2FzZSBMT0NBTEVfU01PTkdST1VQSU5HOiAgICAgcmV0dXJuIHNNb25Hcm91cGluZ1c7CiAgICBjYXNlIExPQ0FMRV9TTU9OVEhPVVNBTkRTRVA6ICByZXR1cm4gc01vblRob3VzYW5kU2VwVzsKICAgIGNhc2UgTE9DQUxFX1NORUdBVElWRVNJR046ICAgIHJldHVybiBzTmVnYXRpdmVTaWduVzsKICAgIGNhc2UgTE9DQUxFX1NQT1NJVElWRVNJR046ICAgIHJldHVybiBzUG9zaXRpdmVTaWduVzsKICAgIGNhc2UgTE9DQUxFX1NTSE9SVERBVEU6ICAgICAgIHJldHVybiBzU2hvcnREYXRlVzsKICAgIGNhc2UgTE9DQUxFX1NUSE9VU0FORDogICAgICAgIHJldHVybiBzVGhvdXNhbmRXOwogICAgY2FzZSBMT0NBTEVfU1RJTUU6ICAgICAgICAgICAgcmV0dXJuIHNUaW1lVzsKICAgIGNhc2UgTE9DQUxFX1NUSU1FRk9STUFUOiAgICAgIHJldHVybiBzVGltZUZvcm1hdFc7CiAgICBjYXNlIExPQ0FMRV9TWUVBUk1PTlRIOiAgICAgICByZXR1cm4gc1llYXJNb250aFc7CgogICAgLyogVGhlIGZvbGxvd2luZyBhcmUgbm90IGxpc3RlZCB1bmRlciBNU0ROIGFzIHN1cHBvcnRlZCwKICAgICAqIGJ1dCBzZWVtIHRvIGJlIHVzZWQgYW5kIGFsc28gc3RvcmVkIGluIHRoZSByZWdpc3RyeS4KICAgICAqLwogICAgY2FzZSBMT0NBTEVfSUNPVU5UUlk6ICAgICAgICAgcmV0dXJuIGlDb3VudHJ5VzsKICAgIGNhc2UgTE9DQUxFX0lEQVRFOiAgICAgICAgICAgIHJldHVybiBpRGF0ZVc7CiAgICBjYXNlIExPQ0FMRV9JTERBVEU6ICAgICAgICAgICByZXR1cm4gaUxEYXRlVzsKICAgIGNhc2UgTE9DQUxFX0lUTFpFUk86ICAgICAgICAgIHJldHVybiBpVExaZXJvVzsKICAgIGNhc2UgTE9DQUxFX1NDT1VOVFJZOiAgICAgICAgIHJldHVybiBzQ291bnRyeVc7CiAgICBjYXNlIExPQ0FMRV9TTEFOR1VBR0U6ICAgICAgICByZXR1cm4gc0xhbmd1YWdlVzsKCiAgICAvKiBUaGUgZm9sbG93aW5nIGFyZSB1c2VkIGluIFhQIGFuZCBsYXRlciAqLwogICAgY2FzZSBMT0NBTEVfSURJR0lUU1VCU1RJVFVUSU9OOiByZXR1cm4gTnVtU2hhcGVXOwogICAgY2FzZSBMT0NBTEVfU05BVElWRURJR0lUUzogICAgICByZXR1cm4gc05hdGl2ZURpZ2l0c1c7CiAgICBjYXNlIExPQ0FMRV9JVElNRU1BUktQT1NOOiAgICAgIHJldHVybiBpVGltZVByZWZpeFc7CiAgICB9CiAgICByZXR1cm4gTlVMTDsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCWdldF9yZWdpc3RyeV9sb2NhbGVfaW5mbwogKgogKiBSZXRyaWV2ZSB1c2VyLW1vZGlmaWVkIGxvY2FsZSBpbmZvIGZyb20gdGhlIHJlZ2lzdHJ5LgogKiBSZXR1cm4gbGVuZ3RoLCAwIG9uIGVycm9yLCAtMSBpZiBub3QgZm91bmQuCiAqLwpzdGF0aWMgSU5UIGdldF9yZWdpc3RyeV9sb2NhbGVfaW5mbyggTFBDV1NUUiB2YWx1ZSwgTFBXU1RSIGJ1ZmZlciwgSU5UIGxlbiApCnsKICAgIERXT1JEIHNpemU7CiAgICBJTlQgcmV0OwogICAgSEFORExFIGhrZXk7CiAgICBOVFNUQVRVUyBzdGF0dXM7CiAgICBVTklDT0RFX1NUUklORyBuYW1lVzsKICAgIEtFWV9WQUxVRV9QQVJUSUFMX0lORk9STUFUSU9OICppbmZvOwogICAgc3RhdGljIGNvbnN0IGludCBpbmZvX3NpemUgPSBGSUVMRF9PRkZTRVQoS0VZX1ZBTFVFX1BBUlRJQUxfSU5GT1JNQVRJT04sIERhdGEpOwoKICAgIGlmICghKGhrZXkgPSBjcmVhdGVfcmVnaXN0cnlfa2V5KCkpKSByZXR1cm4gLTE7CgogICAgUnRsSW5pdFVuaWNvZGVTdHJpbmcoICZuYW1lVywgdmFsdWUgKTsKICAgIHNpemUgPSBpbmZvX3NpemUgKyBsZW4gKiBzaXplb2YoV0NIQVIpOwoKICAgIGlmICghKGluZm8gPSBIZWFwQWxsb2MoIEdldFByb2Nlc3NIZWFwKCksIDAsIHNpemUgKSkpCiAgICB7CiAgICAgICAgTnRDbG9zZSggaGtleSApOwogICAgICAgIFNldExhc3RFcnJvciggRVJST1JfTk9UX0VOT1VHSF9NRU1PUlkgKTsKICAgICAgICByZXR1cm4gMDsKICAgIH0KCiAgICBzdGF0dXMgPSBOdFF1ZXJ5VmFsdWVLZXkoIGhrZXksICZuYW1lVywgS2V5VmFsdWVQYXJ0aWFsSW5mb3JtYXRpb24sIGluZm8sIHNpemUsICZzaXplICk7CgogICAgaWYgKCFzdGF0dXMpCiAgICB7CiAgICAgICAgcmV0ID0gKHNpemUgLSBpbmZvX3NpemUpIC8gc2l6ZW9mKFdDSEFSKTsKICAgICAgICAvKiBhcHBlbmQgdGVybWluYXRpbmcgbnVsbCBpZiBuZWVkZWQgKi8KICAgICAgICBpZiAoIXJldCB8fCAoKFdDSEFSICopaW5mby0+RGF0YSlbcmV0LTFdKQogICAgICAgIHsKICAgICAgICAgICAgaWYgKHJldCA8IGxlbiB8fCAhYnVmZmVyKSByZXQrKzsKICAgICAgICAgICAgZWxzZQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBTZXRMYXN0RXJyb3IoIEVSUk9SX0lOU1VGRklDSUVOVF9CVUZGRVIgKTsKICAgICAgICAgICAgICAgIHJldCA9IDA7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgaWYgKHJldCAmJiBidWZmZXIpCiAgICAgICAgewogICAgICAgICAgICBtZW1jcHkoIGJ1ZmZlciwgaW5mby0+RGF0YSwgKHJldC0xKSAqIHNpemVvZihXQ0hBUikgKTsKICAgICAgICAgICAgYnVmZmVyW3JldC0xXSA9IDA7CiAgICAgICAgfQogICAgfQogICAgZWxzZSBpZiAoc3RhdHVzID09IFNUQVRVU19CVUZGRVJfT1ZFUkZMT1cgJiYgIWJ1ZmZlcikKICAgIHsKICAgICAgICByZXQgPSAoc2l6ZSAtIGluZm9fc2l6ZSkgLyBzaXplb2YoV0NIQVIpICsgMTsKICAgIH0KICAgIGVsc2UgaWYgKHN0YXR1cyA9PSBTVEFUVVNfT0JKRUNUX05BTUVfTk9UX0ZPVU5EKQogICAgewogICAgICAgIHJldCA9IC0xOwogICAgfQogICAgZWxzZQogICAgewogICAgICAgIFNldExhc3RFcnJvciggUnRsTnRTdGF0dXNUb0Rvc0Vycm9yKHN0YXR1cykgKTsKICAgICAgICByZXQgPSAwOwogICAgfQogICAgTnRDbG9zZSggaGtleSApOwogICAgSGVhcEZyZWUoIEdldFByb2Nlc3NIZWFwKCksIDAsIGluZm8gKTsKICAgIHJldHVybiByZXQ7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCQlHZXRMb2NhbGVJbmZvQSAoS0VSTkVMMzIuQCkKICoKICogR2V0IGluZm9ybWF0aW9uIGFib3V0IGFuIGFzcGVjdCBvZiBhIGxvY2FsZS4KICoKICogUEFSQU1TCiAqICBsY2lkICAgW0ldIExDSUQgb2YgdGhlIGxvY2FsZQogKiAgbGN0eXBlIFtJXSBMQ1RZUEVfIGZsYWdzIGZyb20gIndpbm5scy5oIgogKiAgYnVmZmVyIFtPXSBEZXN0aW5hdGlvbiBmb3IgdGhlIGluZm9ybWF0aW9uCiAqICBsZW4gICAgW0ldIExlbmd0aCBvZiBidWZmZXIgaW4gY2hhcmFjdGVycwogKgogKiBSRVRVUk5TCiAqICBTdWNjZXNzOiBUaGUgc2l6ZSBvZiB0aGUgZGF0YSByZXF1ZXN0ZWQuIElmIGJ1ZmZlciBpcyBub24tTlVMTCwgaXQgaXMgZmlsbGVkCiAqICAgICAgICAgICB3aXRoIHRoZSBpbmZvcm1hdGlvbi4KICogIEZhaWx1cmU6IDAuIFVzZSBHZXRMYXN0RXJyb3IoKSB0byBkZXRlcm1pbmUgdGhlIGNhdXNlLgogKgogKiBOT1RFUwogKiAgLSBMT0NBTEVfTkVVVFJBTCBpcyBlcXVhbCB0byBMT0NBTEVfU1lTVEVNX0RFRkFVTFQKICogIC0gVGhlIHN0cmluZyByZXR1cm5lZCBpcyBOVUwgdGVybWluYXRlZCwgZXhjZXB0IGZvciBMT0NBTEVfRk9OVFNJR05BVFVSRSwKICogICAgd2hpY2ggaXMgYSBiaXQgc3RyaW5nLgogKi8KSU5UIFdJTkFQSSBHZXRMb2NhbGVJbmZvQSggTENJRCBsY2lkLCBMQ1RZUEUgbGN0eXBlLCBMUFNUUiBidWZmZXIsIElOVCBsZW4gKQp7CiAgICBXQ0hBUiAqYnVmZmVyVzsKICAgIElOVCBsZW5XLCByZXQ7CgogICAgVFJBQ0UoICIobGNpZD0weCV4LGxjdHlwZT0weCV4LCVwLCVkKVxuIiwgbGNpZCwgbGN0eXBlLCBidWZmZXIsIGxlbiApOwoKICAgIGlmIChsZW4gPCAwIHx8IChsZW4gJiYgIWJ1ZmZlcikpCiAgICB7CiAgICAgICAgU2V0TGFzdEVycm9yKCBFUlJPUl9JTlZBTElEX1BBUkFNRVRFUiApOwogICAgICAgIHJldHVybiAwOwogICAgfQogICAgaWYgKCFsZW4pIGJ1ZmZlciA9IE5VTEw7CgogICAgaWYgKCEobGVuVyA9IEdldExvY2FsZUluZm9XKCBsY2lkLCBsY3R5cGUsIE5VTEwsIDAgKSkpIHJldHVybiAwOwoKICAgIGlmICghKGJ1ZmZlclcgPSBIZWFwQWxsb2MoIEdldFByb2Nlc3NIZWFwKCksIDAsIGxlblcgKiBzaXplb2YoV0NIQVIpICkpKQogICAgewogICAgICAgIFNldExhc3RFcnJvciggRVJST1JfTk9UX0VOT1VHSF9NRU1PUlkgKTsKICAgICAgICByZXR1cm4gMDsKICAgIH0KICAgIGlmICgocmV0ID0gR2V0TG9jYWxlSW5mb1coIGxjaWQsIGxjdHlwZSwgYnVmZmVyVywgbGVuVyApKSkKICAgIHsKICAgICAgICBpZiAoKGxjdHlwZSAmIExPQ0FMRV9SRVRVUk5fTlVNQkVSKSB8fAogICAgICAgICAgICAoKGxjdHlwZSAmIH5MT0NBTEVfTE9DQUxFSU5GT0ZMQUdTTUFTSykgPT0gTE9DQUxFX0ZPTlRTSUdOQVRVUkUpKQogICAgICAgIHsKICAgICAgICAgICAgLyogaXQncyBub3QgYW4gQVNDSUkgc3RyaW5nLCBqdXN0IGJ5dGVzICovCiAgICAgICAgICAgIHJldCAqPSBzaXplb2YoV0NIQVIpOwogICAgICAgICAgICBpZiAoYnVmZmVyKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBpZiAocmV0IDw9IGxlbikgbWVtY3B5KCBidWZmZXIsIGJ1ZmZlclcsIHJldCApOwogICAgICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIFNldExhc3RFcnJvciggRVJST1JfSU5TVUZGSUNJRU5UX0JVRkZFUiApOwogICAgICAgICAgICAgICAgICAgIHJldCA9IDA7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgZWxzZQogICAgICAgIHsKICAgICAgICAgICAgVUlOVCBjb2RlcGFnZSA9IENQX0FDUDsKICAgICAgICAgICAgaWYgKCEobGN0eXBlICYgTE9DQUxFX1VTRV9DUF9BQ1ApKSBjb2RlcGFnZSA9IGdldF9sY2lkX2NvZGVwYWdlKCBsY2lkICk7CiAgICAgICAgICAgIHJldCA9IFdpZGVDaGFyVG9NdWx0aUJ5dGUoIGNvZGVwYWdlLCAwLCBidWZmZXJXLCByZXQsIGJ1ZmZlciwgbGVuLCBOVUxMLCBOVUxMICk7CiAgICAgICAgfQogICAgfQogICAgSGVhcEZyZWUoIEdldFByb2Nlc3NIZWFwKCksIDAsIGJ1ZmZlclcgKTsKICAgIHJldHVybiByZXQ7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCQlHZXRMb2NhbGVJbmZvVyAoS0VSTkVMMzIuQCkKICoKICogU2VlIEdldExvY2FsZUluZm9BLgogKi8KSU5UIFdJTkFQSSBHZXRMb2NhbGVJbmZvVyggTENJRCBsY2lkLCBMQ1RZUEUgbGN0eXBlLCBMUFdTVFIgYnVmZmVyLCBJTlQgbGVuICkKewogICAgTEFOR0lEIGxhbmdfaWQ7CiAgICBIUlNSQyBocnNyYzsKICAgIEhHTE9CQUwgaG1lbTsKICAgIElOVCByZXQ7CiAgICBVSU5UIGxjZmxhZ3M7CiAgICBjb25zdCBXQ0hBUiAqcDsKICAgIHVuc2lnbmVkIGludCBpOwoKICAgIGlmIChsZW4gPCAwIHx8IChsZW4gJiYgIWJ1ZmZlcikpCiAgICB7CiAgICAgICAgU2V0TGFzdEVycm9yKCBFUlJPUl9JTlZBTElEX1BBUkFNRVRFUiApOwogICAgICAgIHJldHVybiAwOwogICAgfQogICAgaWYgKCFsZW4pIGJ1ZmZlciA9IE5VTEw7CgogICAgbGNpZCA9IGNvbnZlcnRfZGVmYXVsdF9sY2lkKCBsY2lkLCBsY3R5cGUgKTsKCiAgICBsY2ZsYWdzID0gbGN0eXBlICYgTE9DQUxFX0xPQ0FMRUlORk9GTEFHU01BU0s7CiAgICBsY3R5cGUgJj0gMHhmZmZmOwoKICAgIFRSQUNFKCAiKGxjaWQ9MHgleCxsY3R5cGU9MHgleCwlcCwlZClcbiIsIGxjaWQsIGxjdHlwZSwgYnVmZmVyLCBsZW4gKTsKCiAgICAvKiBmaXJzdCBjaGVjayBmb3Igb3ZlcnJpZGVzIGluIHRoZSByZWdpc3RyeSAqLwoKICAgIGlmICghKGxjZmxhZ3MgJiBMT0NBTEVfTk9VU0VST1ZFUlJJREUpICYmCiAgICAgICAgbGNpZCA9PSBjb252ZXJ0X2RlZmF1bHRfbGNpZCggTE9DQUxFX1VTRVJfREVGQVVMVCwgbGN0eXBlICkpCiAgICB7CiAgICAgICAgY29uc3QgV0NIQVIgKnZhbHVlID0gZ2V0X2xvY2FsZV92YWx1ZV9uYW1lKGxjdHlwZSk7CgogICAgICAgIGlmICh2YWx1ZSkKICAgICAgICB7CiAgICAgICAgICAgIGlmIChsY2ZsYWdzICYgTE9DQUxFX1JFVFVSTl9OVU1CRVIpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIFdDSEFSIHRtcFsxNl07CiAgICAgICAgICAgICAgICByZXQgPSBnZXRfcmVnaXN0cnlfbG9jYWxlX2luZm8oIHZhbHVlLCB0bXAsIHNpemVvZih0bXApL3NpemVvZihXQ0hBUikgKTsKICAgICAgICAgICAgICAgIGlmIChyZXQgPiAwKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIFdDSEFSICplbmQ7CiAgICAgICAgICAgICAgICAgICAgVUlOVCBudW1iZXIgPSBzdHJ0b2xXKCB0bXAsICZlbmQsIDEwICk7CiAgICAgICAgICAgICAgICAgICAgaWYgKCplbmQpICAvKiBpbnZhbGlkIG51bWJlciAqLwogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgU2V0TGFzdEVycm9yKCBFUlJPUl9JTlZBTElEX0ZMQUdTICk7CiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiAwOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICByZXQgPSBzaXplb2YoVUlOVCkvc2l6ZW9mKFdDSEFSKTsKICAgICAgICAgICAgICAgICAgICBpZiAoIWJ1ZmZlcikgcmV0dXJuIHJldDsKICAgICAgICAgICAgICAgICAgICBpZiAocmV0ID4gbGVuKQogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgU2V0TGFzdEVycm9yKCBFUlJPUl9JTlNVRkZJQ0lFTlRfQlVGRkVSICk7CiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiAwOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBtZW1jcHkoIGJ1ZmZlciwgJm51bWJlciwgc2l6ZW9mKG51bWJlcikgKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICBlbHNlIHJldCA9IGdldF9yZWdpc3RyeV9sb2NhbGVfaW5mbyggdmFsdWUsIGJ1ZmZlciwgbGVuICk7CgogICAgICAgICAgICBpZiAocmV0ICE9IC0xKSByZXR1cm4gcmV0OwogICAgICAgIH0KICAgIH0KCiAgICAvKiBub3cgbG9hZCBpdCBmcm9tIGtlcm5lbCByZXNvdXJjZXMgKi8KCiAgICBsYW5nX2lkID0gTEFOR0lERlJPTUxDSUQoIGxjaWQgKTsKCiAgICAvKiByZXBsYWNlIFNVQkxBTkdfTkVVVFJBTCBieSBTVUJMQU5HX0RFRkFVTFQgKi8KICAgIGlmIChTVUJMQU5HSUQobGFuZ19pZCkgPT0gU1VCTEFOR19ORVVUUkFMKQogICAgICAgIGxhbmdfaWQgPSBNQUtFTEFOR0lEKFBSSU1BUllMQU5HSUQobGFuZ19pZCksIFNVQkxBTkdfREVGQVVMVCk7CgogICAgaWYgKCEoaHJzcmMgPSBGaW5kUmVzb3VyY2VFeFcoIGtlcm5lbDMyX2hhbmRsZSwgKExQV1NUUilSVF9TVFJJTkcsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVUxvbmdUb1B0cigobGN0eXBlID4+IDQpICsgMSksIGxhbmdfaWQgKSkpCiAgICB7CiAgICAgICAgU2V0TGFzdEVycm9yKCBFUlJPUl9JTlZBTElEX0ZMQUdTICk7ICAvKiBubyBzdWNoIGxjdHlwZSAqLwogICAgICAgIHJldHVybiAwOwogICAgfQogICAgaWYgKCEoaG1lbSA9IExvYWRSZXNvdXJjZSgga2VybmVsMzJfaGFuZGxlLCBocnNyYyApKSkKICAgICAgICByZXR1cm4gMDsKCiAgICBwID0gTG9ja1Jlc291cmNlKCBobWVtICk7CiAgICBmb3IgKGkgPSAwOyBpIDwgKGxjdHlwZSAmIDB4MGYpOyBpKyspIHAgKz0gKnAgKyAxOwoKICAgIGlmIChsY2ZsYWdzICYgTE9DQUxFX1JFVFVSTl9OVU1CRVIpIHJldCA9IHNpemVvZihVSU5UKS9zaXplb2YoV0NIQVIpOwogICAgZWxzZSByZXQgPSAobGN0eXBlID09IExPQ0FMRV9GT05UU0lHTkFUVVJFKSA/ICpwIDogKnAgKyAxOwoKICAgIGlmICghYnVmZmVyKSByZXR1cm4gcmV0OwoKICAgIGlmIChyZXQgPiBsZW4pCiAgICB7CiAgICAgICAgU2V0TGFzdEVycm9yKCBFUlJPUl9JTlNVRkZJQ0lFTlRfQlVGRkVSICk7CiAgICAgICAgcmV0dXJuIDA7CiAgICB9CgogICAgaWYgKGxjZmxhZ3MgJiBMT0NBTEVfUkVUVVJOX05VTUJFUikKICAgIHsKICAgICAgICBVSU5UIG51bWJlcjsKICAgICAgICBXQ0hBUiAqZW5kLCAqdG1wID0gSGVhcEFsbG9jKCBHZXRQcm9jZXNzSGVhcCgpLCAwLCAoKnAgKyAxKSAqIHNpemVvZihXQ0hBUikgKTsKICAgICAgICBpZiAoIXRtcCkgcmV0dXJuIDA7CiAgICAgICAgbWVtY3B5KCB0bXAsIHAgKyAxLCAqcCAqIHNpemVvZihXQ0hBUikgKTsKICAgICAgICB0bXBbKnBdID0gMDsKICAgICAgICBudW1iZXIgPSBzdHJ0b2xXKCB0bXAsICZlbmQsIDEwICk7CiAgICAgICAgaWYgKCEqZW5kKQogICAgICAgICAgICBtZW1jcHkoIGJ1ZmZlciwgJm51bWJlciwgc2l6ZW9mKG51bWJlcikgKTsKICAgICAgICBlbHNlICAvKiBpbnZhbGlkIG51bWJlciAqLwogICAgICAgIHsKICAgICAgICAgICAgU2V0TGFzdEVycm9yKCBFUlJPUl9JTlZBTElEX0ZMQUdTICk7CiAgICAgICAgICAgIHJldCA9IDA7CiAgICAgICAgfQogICAgICAgIEhlYXBGcmVlKCBHZXRQcm9jZXNzSGVhcCgpLCAwLCB0bXAgKTsKCiAgICAgICAgVFJBQ0UoICIobGNpZD0weCV4LGxjdHlwZT0weCV4LCVwLCVkKSByZXR1cm5pbmcgbnVtYmVyICVkXG4iLAogICAgICAgICAgICAgICBsY2lkLCBsY3R5cGUsIGJ1ZmZlciwgbGVuLCBudW1iZXIgKTsKICAgIH0KICAgIGVsc2UKICAgIHsKICAgICAgICBtZW1jcHkoIGJ1ZmZlciwgcCArIDEsICpwICogc2l6ZW9mKFdDSEFSKSApOwogICAgICAgIGlmIChsY3R5cGUgIT0gTE9DQUxFX0ZPTlRTSUdOQVRVUkUpIGJ1ZmZlcltyZXQtMV0gPSAwOwoKICAgICAgICBUUkFDRSggIihsY2lkPTB4JXgsbGN0eXBlPTB4JXgsJXAsJWQpIHJldHVybmluZyAlZCAlc1xuIiwKICAgICAgICAgICAgICAgbGNpZCwgbGN0eXBlLCBidWZmZXIsIGxlbiwgcmV0LCBkZWJ1Z3N0cl93KGJ1ZmZlcikgKTsKICAgIH0KICAgIHJldHVybiByZXQ7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCQlTZXRMb2NhbGVJbmZvQQlbS0VSTkVMMzIuQF0KICoKICogU2V0IGluZm9ybWF0aW9uIGFib3V0IGFuIGFzcGVjdCBvZiBhIGxvY2FsZS4KICoKICogUEFSQU1TCiAqICBsY2lkICAgW0ldIExDSUQgb2YgdGhlIGxvY2FsZQogKiAgbGN0eXBlIFtJXSBMQ1RZUEVfIGZsYWdzIGZyb20gIndpbm5scy5oIgogKiAgZGF0YSAgIFtJXSBJbmZvcm1hdGlvbiB0byBzZXQKICoKICogUkVUVVJOUwogKiAgU3VjY2VzczogVFJVRS4gVGhlIGluZm9ybWF0aW9uIGdpdmVuIHdpbGwgYmUgcmV0dXJuZWQgYnkgR2V0TG9jYWxlSW5mb0EoKQogKiAgICAgICAgICAgd2hlbmV2ZXIgaXQgaXMgY2FsbGVkIHdpdGhvdXQgTE9DQUxFX05PVVNFUk9WRVJSSURFLgogKiAgRmFpbHVyZTogRkFMU0UuIFVzZSBHZXRMYXN0RXJyb3IoKSB0byBkZXRlcm1pbmUgdGhlIGNhdXNlLgogKgogKiBOT1RFUwogKiAgLSBWYWx1ZXMgYXJlIG9ubHkgYmUgc2V0IGZvciB0aGUgY3VycmVudCB1c2VyIGxvY2FsZTsgdGhlIHN5c3RlbSBsb2NhbGUKICogIHNldHRpbmdzIGNhbm5vdCBiZSBjaGFuZ2VkLgogKiAgLSBBbnkgc2V0dGluZ3MgY2hhbmdlZCBieSB0aGlzIGNhbGwgYXJlIGxvc3Qgd2hlbiB0aGUgbG9jYWxlIGlzIGNoYW5nZWQgYnkKICogIHRoZSBjb250cm9sIHBhbmVsIChpbiBXaW5lLCB0aGlzIGhhcHBlbnMgZXZlcnkgdGltZSB5b3UgY2hhbmdlIExBTkcpLgogKiAgLSBUaGUgbmF0aXZlIGltcGxlbWVudGF0aW9uIG9mIHRoaXMgZnVuY3Rpb24gZG9lcyBub3QgY2hlY2sgdGhhdCBsY2lkIG1hdGNoZXMKICogIHRoZSBjdXJyZW50IHVzZXIgbG9jYWxlLCBhbmQgc2ltcGx5IHNldHMgdGhlIG5ldyB2YWx1ZXMuIFdpbmUgd2FybnMgeW91IGluCiAqICB0aGlzIGNhc2UsIGJ1dCBiZWhhdmVzIHRoZSBzYW1lLgogKi8KQk9PTCBXSU5BUEkgU2V0TG9jYWxlSW5mb0EoTENJRCBsY2lkLCBMQ1RZUEUgbGN0eXBlLCBMUENTVFIgZGF0YSkKewogICAgVUlOVCBjb2RlcGFnZSA9IENQX0FDUDsKICAgIFdDSEFSICpzdHJXOwogICAgRFdPUkQgbGVuOwogICAgQk9PTCByZXQ7CgogICAgaWYgKCEobGN0eXBlICYgTE9DQUxFX1VTRV9DUF9BQ1ApKSBjb2RlcGFnZSA9IGdldF9sY2lkX2NvZGVwYWdlKCBsY2lkICk7CgogICAgaWYgKCFkYXRhKQogICAgewogICAgICAgIFNldExhc3RFcnJvciggRVJST1JfSU5WQUxJRF9QQVJBTUVURVIgKTsKICAgICAgICByZXR1cm4gRkFMU0U7CiAgICB9CiAgICBsZW4gPSBNdWx0aUJ5dGVUb1dpZGVDaGFyKCBjb2RlcGFnZSwgMCwgZGF0YSwgLTEsIE5VTEwsIDAgKTsKICAgIGlmICghKHN0clcgPSBIZWFwQWxsb2MoIEdldFByb2Nlc3NIZWFwKCksIDAsIGxlbiAqIHNpemVvZihXQ0hBUikgKSkpCiAgICB7CiAgICAgICAgU2V0TGFzdEVycm9yKCBFUlJPUl9OT1RfRU5PVUdIX01FTU9SWSApOwogICAgICAgIHJldHVybiBGQUxTRTsKICAgIH0KICAgIE11bHRpQnl0ZVRvV2lkZUNoYXIoIGNvZGVwYWdlLCAwLCBkYXRhLCAtMSwgc3RyVywgbGVuICk7CiAgICByZXQgPSBTZXRMb2NhbGVJbmZvVyggbGNpZCwgbGN0eXBlLCBzdHJXICk7CiAgICBIZWFwRnJlZSggR2V0UHJvY2Vzc0hlYXAoKSwgMCwgc3RyVyApOwogICAgcmV0dXJuIHJldDsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCVNldExvY2FsZUluZm9XCShLRVJORUwzMi5AKQogKgogKiBTZWUgU2V0TG9jYWxlSW5mb0EuCiAqLwpCT09MIFdJTkFQSSBTZXRMb2NhbGVJbmZvVyggTENJRCBsY2lkLCBMQ1RZUEUgbGN0eXBlLCBMUENXU1RSIGRhdGEgKQp7CiAgICBjb25zdCBXQ0hBUiAqdmFsdWU7CiAgICBzdGF0aWMgY29uc3QgV0NIQVIgaW50bFdbXSA9IHsnaScsJ24nLCd0JywnbCcsMCB9OwogICAgVU5JQ09ERV9TVFJJTkcgdmFsdWVXOwogICAgTlRTVEFUVVMgc3RhdHVzOwogICAgSEFORExFIGhrZXk7CgogICAgbGN0eXBlICY9IDB4ZmZmZjsKICAgIHZhbHVlID0gZ2V0X2xvY2FsZV92YWx1ZV9uYW1lKCBsY3R5cGUgKTsKCiAgICBpZiAoIWRhdGEgfHwgIXZhbHVlKQogICAgewogICAgICAgIFNldExhc3RFcnJvciggRVJST1JfSU5WQUxJRF9QQVJBTUVURVIgKTsKICAgICAgICByZXR1cm4gRkFMU0U7CiAgICB9CgogICAgaWYgKGxjdHlwZSA9PSBMT0NBTEVfSURBVEUgfHwgbGN0eXBlID09IExPQ0FMRV9JTERBVEUpCiAgICB7CiAgICAgICAgU2V0TGFzdEVycm9yKCBFUlJPUl9JTlZBTElEX0ZMQUdTICk7CiAgICAgICAgcmV0dXJuIEZBTFNFOwogICAgfQoKICAgIFRSQUNFKCJzZXR0aW5nICV4ICglcykgdG8gJXNcbiIsIGxjdHlwZSwgZGVidWdzdHJfdyh2YWx1ZSksIGRlYnVnc3RyX3coZGF0YSkgKTsKCiAgICAvKiBGSVhNRTogc2hvdWxkIGNoZWNrIHRoYXQgZGF0YSB0byBzZXQgaXMgc2FuZSAqLwoKICAgIC8qIEZJWE1FOiBwcm9maWxlIGZ1bmN0aW9ucyBzaG91bGQgbWFwIHRvIHJlZ2lzdHJ5ICovCiAgICBXcml0ZVByb2ZpbGVTdHJpbmdXKCBpbnRsVywgdmFsdWUsIGRhdGEgKTsKCiAgICBpZiAoIShoa2V5ID0gY3JlYXRlX3JlZ2lzdHJ5X2tleSgpKSkgcmV0dXJuIEZBTFNFOwogICAgUnRsSW5pdFVuaWNvZGVTdHJpbmcoICZ2YWx1ZVcsIHZhbHVlICk7CiAgICBzdGF0dXMgPSBOdFNldFZhbHVlS2V5KCBoa2V5LCAmdmFsdWVXLCAwLCBSRUdfU1osIGRhdGEsIChzdHJsZW5XKGRhdGEpKzEpKnNpemVvZihXQ0hBUikgKTsKCiAgICBpZiAobGN0eXBlID09IExPQ0FMRV9TU0hPUlREQVRFIHx8IGxjdHlwZSA9PSBMT0NBTEVfU0xPTkdEQVRFKQogICAgewogICAgICAvKiBTZXQgSS12YWx1ZSBmcm9tIFMgdmFsdWUgKi8KICAgICAgV0NIQVIgKmxwRCwgKmxwTSwgKmxwWTsKICAgICAgV0NIQVIgc3pCdWZmWzJdOwoKICAgICAgbHBEID0gc3RycmNoclcoZGF0YSwgJ2QnKTsKICAgICAgbHBNID0gc3RycmNoclcoZGF0YSwgJ00nKTsKICAgICAgbHBZID0gc3RycmNoclcoZGF0YSwgJ3knKTsKCiAgICAgIGlmIChscEQgPD0gbHBNKQogICAgICB7CiAgICAgICAgc3pCdWZmWzBdID0gJzEnOyAvKiBELU0tWSAqLwogICAgICB9CiAgICAgIGVsc2UKICAgICAgewogICAgICAgIGlmIChscFkgPD0gbHBNKQogICAgICAgICAgc3pCdWZmWzBdID0gJzInOyAvKiBZLU0tRCAqLwogICAgICAgIGVsc2UKICAgICAgICAgIHN6QnVmZlswXSA9ICcwJzsgLyogTS1ELVkgKi8KICAgICAgfQoKICAgICAgc3pCdWZmWzFdID0gJ1wwJzsKCiAgICAgIGlmIChsY3R5cGUgPT0gTE9DQUxFX1NTSE9SVERBVEUpCiAgICAgICAgbGN0eXBlID0gTE9DQUxFX0lEQVRFOwogICAgICBlbHNlCiAgICAgICAgbGN0eXBlID0gTE9DQUxFX0lMREFURTsKCiAgICAgIHZhbHVlID0gZ2V0X2xvY2FsZV92YWx1ZV9uYW1lKCBsY3R5cGUgKTsKCiAgICAgIFdyaXRlUHJvZmlsZVN0cmluZ1coIGludGxXLCB2YWx1ZSwgc3pCdWZmICk7CgogICAgICBSdGxJbml0VW5pY29kZVN0cmluZyggJnZhbHVlVywgdmFsdWUgKTsKICAgICAgc3RhdHVzID0gTnRTZXRWYWx1ZUtleSggaGtleSwgJnZhbHVlVywgMCwgUkVHX1NaLCBzekJ1ZmYsIHNpemVvZihzekJ1ZmYpICk7CiAgICB9CgogICAgTnRDbG9zZSggaGtleSApOwoKICAgIGlmIChzdGF0dXMpIFNldExhc3RFcnJvciggUnRsTnRTdGF0dXNUb0Rvc0Vycm9yKHN0YXR1cykgKTsKICAgIHJldHVybiAhc3RhdHVzOwp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgICAgICAgICAgR2V0QUNQICAgKEtFUk5FTDMyLkApCiAqCiAqIEdldCB0aGUgY3VycmVudCBBbnNpIGNvZGUgcGFnZSBJZCBmb3IgdGhlIHN5c3RlbS4KICoKICogUEFSQU1TCiAqICBOb25lLgogKgogKiBSRVRVUk5TCiAqICAgIFRoZSBjdXJyZW50IEFuc2kgY29kZSBwYWdlIGlkZW50aWZpZXIgZm9yIHRoZSBzeXN0ZW0uCiAqLwpVSU5UIFdJTkFQSSBHZXRBQ1Aodm9pZCkKewogICAgYXNzZXJ0KCBhbnNpX2NwdGFibGUgKTsKICAgIHJldHVybiBhbnNpX2NwdGFibGUtPmluZm8uY29kZXBhZ2U7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgICAgICAgICBTZXRDUEdsb2JhbCAgIChLRVJORUwzMi5AKQogKgogKiBTZXQgdGhlIGN1cnJlbnQgQW5zaSBjb2RlIHBhZ2UgSWQgZm9yIHRoZSBzeXN0ZW0uCiAqCiAqIFBBUkFNUwogKiAgICBhY3AgW0ldIGNvZGUgcGFnZSBJRCB0byBiZSB0aGUgbmV3IEFDUC4KICoKICogUkVUVVJOUwogKiAgICBUaGUgcHJldmlvdXMgQUNQLgogKi8KVUlOVCBXSU5BUEkgU2V0Q1BHbG9iYWwoIFVJTlQgYWNwICkKewogICAgVUlOVCByZXQgPSBHZXRBQ1AoKTsKICAgIGNvbnN0IHVuaW9uIGNwdGFibGUgKm5ld19jcHRhYmxlID0gd2luZV9jcF9nZXRfdGFibGUoIGFjcCApOwoKICAgIGlmIChuZXdfY3B0YWJsZSkgYW5zaV9jcHRhYmxlID0gbmV3X2NwdGFibGU7CiAgICByZXR1cm4gcmV0Owp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgICAgICAgICBHZXRPRU1DUCAgIChLRVJORUwzMi5AKQogKgogKiBHZXQgdGhlIGN1cnJlbnQgT0VNIGNvZGUgcGFnZSBJZCBmb3IgdGhlIHN5c3RlbS4KICoKICogUEFSQU1TCiAqICBOb25lLgogKgogKiBSRVRVUk5TCiAqICAgIFRoZSBjdXJyZW50IE9FTSBjb2RlIHBhZ2UgaWRlbnRpZmllciBmb3IgdGhlIHN5c3RlbS4KICovClVJTlQgV0lOQVBJIEdldE9FTUNQKHZvaWQpCnsKICAgIGFzc2VydCggb2VtX2NwdGFibGUgKTsKICAgIHJldHVybiBvZW1fY3B0YWJsZS0+aW5mby5jb2RlcGFnZTsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgICAgICAgSXNWYWxpZENvZGVQYWdlICAgKEtFUk5FTDMyLkApCiAqCiAqIERldGVybWluZSBpZiBhIGdpdmVuIGNvZGUgcGFnZSBpZGVudGlmaWVyIGlzIHZhbGlkLgogKgogKiBQQVJBTVMKICogIGNvZGVwYWdlIFtJXSBDb2RlIHBhZ2UgSWQgdG8gdmVyaWZ5LgogKgogKiBSRVRVUk5TCiAqICBUUlVFLCBJZiBjb2RlcGFnZSBpcyB2YWxpZCBhbmQgYXZhaWxhYmxlIG9uIHRoZSBzeXN0ZW0sCiAqICBGQUxTRSBvdGhlcndpc2UuCiAqLwpCT09MIFdJTkFQSSBJc1ZhbGlkQ29kZVBhZ2UoIFVJTlQgY29kZXBhZ2UgKQp7CiAgICBzd2l0Y2goY29kZXBhZ2UpIHsKICAgIGNhc2UgQ1BfVVRGNzoKICAgIGNhc2UgQ1BfVVRGODoKICAgICAgICByZXR1cm4gVFJVRTsKICAgIGRlZmF1bHQ6CiAgICAgICAgcmV0dXJuIHdpbmVfY3BfZ2V0X3RhYmxlKCBjb2RlcGFnZSApICE9IE5VTEw7CiAgICB9Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICAgICAgIElzREJDU0xlYWRCeXRlRXggICAoS0VSTkVMMzIuQCkKICoKICogRGV0ZXJtaW5lIGlmIGEgY2hhcmFjdGVyIGlzIGEgbGVhZCBieXRlIGluIGEgZ2l2ZW4gY29kZSBwYWdlLgogKgogKiBQQVJBTVMKICogIGNvZGVwYWdlIFtJXSBDb2RlIHBhZ2UgZm9yIHRoZSB0ZXN0LgogKiAgdGVzdGNoYXIgW0ldIENoYXJhY3RlciB0byB0ZXN0CiAqCiAqIFJFVFVSTlMKICogIFRSVUUsIGlmIHRlc3RjaGFyIGlzIGEgbGVhZCBieXRlIGluIGNvZGVwYWdlLAogKiAgRkFMU0Ugb3RoZXJ3aXNlLgogKi8KQk9PTCBXSU5BUEkgSXNEQkNTTGVhZEJ5dGVFeCggVUlOVCBjb2RlcGFnZSwgQllURSB0ZXN0Y2hhciApCnsKICAgIGNvbnN0IHVuaW9uIGNwdGFibGUgKnRhYmxlID0gZ2V0X2NvZGVwYWdlX3RhYmxlKCBjb2RlcGFnZSApOwogICAgcmV0dXJuIHRhYmxlICYmIHdpbmVfaXNfZGJjc19sZWFkYnl0ZSggdGFibGUsIHRlc3RjaGFyICk7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICAgICAgIElzREJDU0xlYWRCeXRlICAgKEtFUk5FTDMyLkApCiAqICAgICAgICAgICBJc0RCQ1NMZWFkQnl0ZSAgIChLRVJORUwuMjA3KQogKgogKiBEZXRlcm1pbmUgaWYgYSBjaGFyYWN0ZXIgaXMgYSBsZWFkIGJ5dGUuCiAqCiAqIFBBUkFNUwogKiAgdGVzdGNoYXIgW0ldIENoYXJhY3RlciB0byB0ZXN0CiAqCiAqIFJFVFVSTlMKICogIFRSVUUsIGlmIHRlc3RjaGFyIGlzIGEgbGVhZCBieXRlIGluIHRoZSBBbnNpaSBjb2RlIHBhZ2UsCiAqICBGQUxTRSBvdGhlcndpc2UuCiAqLwpCT09MIFdJTkFQSSBJc0RCQ1NMZWFkQnl0ZSggQllURSB0ZXN0Y2hhciApCnsKICAgIGlmICghYW5zaV9jcHRhYmxlKSByZXR1cm4gRkFMU0U7CiAgICByZXR1cm4gd2luZV9pc19kYmNzX2xlYWRieXRlKCBhbnNpX2NwdGFibGUsIHRlc3RjaGFyICk7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICAgICAgIEdldENQSW5mbyAgIChLRVJORUwzMi5AKQogKgogKiBHZXQgaW5mb3JtYXRpb24gYWJvdXQgYSBjb2RlIHBhZ2UuCiAqCiAqIFBBUkFNUwogKiAgY29kZXBhZ2UgW0ldIENvZGUgcGFnZSBudW1iZXIKICogIGNwaW5mbyAgIFtPXSBEZXN0aW5hdGlvbiBmb3IgY29kZSBwYWdlIGluZm9ybWF0aW9uCiAqCiAqIFJFVFVSTlMKICogIFN1Y2Nlc3M6IFRSVUUuIGNwaW5mbyBpcyB1cGRhdGVkIHdpdGggdGhlIGluZm9ybWF0aW9uIGFib3V0IGNvZGVwYWdlLgogKiAgRmFpbHVyZTogRkFMU0UsIGlmIGNvZGVwYWdlIGlzIGludmFsaWQgb3IgY3BpbmZvIGlzIE5VTEwuCiAqLwpCT09MIFdJTkFQSSBHZXRDUEluZm8oIFVJTlQgY29kZXBhZ2UsIExQQ1BJTkZPIGNwaW5mbyApCnsKICAgIGNvbnN0IHVuaW9uIGNwdGFibGUgKnRhYmxlOwoKICAgIGlmICghY3BpbmZvKQogICAgewogICAgICAgIFNldExhc3RFcnJvciggRVJST1JfSU5WQUxJRF9QQVJBTUVURVIgKTsKICAgICAgICByZXR1cm4gRkFMU0U7CiAgICB9CgogICAgaWYgKCEodGFibGUgPSBnZXRfY29kZXBhZ2VfdGFibGUoIGNvZGVwYWdlICkpKQogICAgewogICAgICAgIHN3aXRjaChjb2RlcGFnZSkKICAgICAgICB7CiAgICAgICAgICAgIGNhc2UgQ1BfVVRGNzoKICAgICAgICAgICAgY2FzZSBDUF9VVEY4OgogICAgICAgICAgICAgICAgY3BpbmZvLT5EZWZhdWx0Q2hhclswXSA9IDB4M2Y7CiAgICAgICAgICAgICAgICBjcGluZm8tPkRlZmF1bHRDaGFyWzFdID0gMDsKICAgICAgICAgICAgICAgIGNwaW5mby0+TGVhZEJ5dGVbMF0gPSBjcGluZm8tPkxlYWRCeXRlWzFdID0gMDsKICAgICAgICAgICAgICAgIGNwaW5mby0+TWF4Q2hhclNpemUgPSAoY29kZXBhZ2UgPT0gQ1BfVVRGNykgPyA1IDogNDsKICAgICAgICAgICAgICAgIHJldHVybiBUUlVFOwogICAgICAgIH0KCiAgICAgICAgU2V0TGFzdEVycm9yKCBFUlJPUl9JTlZBTElEX1BBUkFNRVRFUiApOwogICAgICAgIHJldHVybiBGQUxTRTsKICAgIH0KICAgIGlmICh0YWJsZS0+aW5mby5kZWZfY2hhciAmIDB4ZmYwMCkKICAgIHsKICAgICAgICBjcGluZm8tPkRlZmF1bHRDaGFyWzBdID0gKHRhYmxlLT5pbmZvLmRlZl9jaGFyICYgMHhmZjAwKSA+PiA4OwogICAgICAgIGNwaW5mby0+RGVmYXVsdENoYXJbMV0gPSB0YWJsZS0+aW5mby5kZWZfY2hhciAmIDB4MDBmZjsKICAgIH0KICAgIGVsc2UKICAgIHsKICAgICAgICBjcGluZm8tPkRlZmF1bHRDaGFyWzBdID0gdGFibGUtPmluZm8uZGVmX2NoYXIgJiAweGZmOwogICAgICAgIGNwaW5mby0+RGVmYXVsdENoYXJbMV0gPSAwOwogICAgfQogICAgaWYgKChjcGluZm8tPk1heENoYXJTaXplID0gdGFibGUtPmluZm8uY2hhcl9zaXplKSA9PSAyKQogICAgICAgIG1lbWNweSggY3BpbmZvLT5MZWFkQnl0ZSwgdGFibGUtPmRiY3MubGVhZF9ieXRlcywgc2l6ZW9mKGNwaW5mby0+TGVhZEJ5dGUpICk7CiAgICBlbHNlCiAgICAgICAgY3BpbmZvLT5MZWFkQnl0ZVswXSA9IGNwaW5mby0+TGVhZEJ5dGVbMV0gPSAwOwoKICAgIHJldHVybiBUUlVFOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICAgICAgIEdldENQSW5mb0V4QSAgIChLRVJORUwzMi5AKQogKgogKiBHZXQgZXh0ZW5kZWQgaW5mb3JtYXRpb24gYWJvdXQgYSBjb2RlIHBhZ2UuCiAqCiAqIFBBUkFNUwogKiAgY29kZXBhZ2UgW0ldIENvZGUgcGFnZSBudW1iZXIKICogIGR3RmxhZ3MgIFtJXSBSZXNlcnZlZCwgbXVzdCB0byAwLgogKiAgY3BpbmZvICAgW09dIERlc3RpbmF0aW9uIGZvciBjb2RlIHBhZ2UgaW5mb3JtYXRpb24KICoKICogUkVUVVJOUwogKiAgU3VjY2VzczogVFJVRS4gY3BpbmZvIGlzIHVwZGF0ZWQgd2l0aCB0aGUgaW5mb3JtYXRpb24gYWJvdXQgY29kZXBhZ2UuCiAqICBGYWlsdXJlOiBGQUxTRSwgaWYgY29kZXBhZ2UgaXMgaW52YWxpZCBvciBjcGluZm8gaXMgTlVMTC4KICovCkJPT0wgV0lOQVBJIEdldENQSW5mb0V4QSggVUlOVCBjb2RlcGFnZSwgRFdPUkQgZHdGbGFncywgTFBDUElORk9FWEEgY3BpbmZvICkKewogICAgQ1BJTkZPRVhXIGNwaW5mb1c7CgogICAgaWYgKCFHZXRDUEluZm9FeFcoIGNvZGVwYWdlLCBkd0ZsYWdzLCAmY3BpbmZvVyApKQogICAgICByZXR1cm4gRkFMU0U7CgogICAgLyogdGhlIGxheW91dCBpcyB0aGUgc2FtZSBleGNlcHQgZm9yIENvZGVQYWdlTmFtZSAqLwogICAgbWVtY3B5KGNwaW5mbywgJmNwaW5mb1csIHNpemVvZihDUElORk9FWEEpKTsKICAgIFdpZGVDaGFyVG9NdWx0aUJ5dGUoQ1BfQUNQLCAwLCBjcGluZm9XLkNvZGVQYWdlTmFtZSwgLTEsIGNwaW5mby0+Q29kZVBhZ2VOYW1lLCBzaXplb2YoY3BpbmZvLT5Db2RlUGFnZU5hbWUpLCBOVUxMLCBOVUxMKTsKICAgIHJldHVybiBUUlVFOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICAgICAgIEdldENQSW5mb0V4VyAgIChLRVJORUwzMi5AKQogKgogKiBVbmljb2RlIHZlcnNpb24gb2YgR2V0Q1BJbmZvRXhBLgogKi8KQk9PTCBXSU5BUEkgR2V0Q1BJbmZvRXhXKCBVSU5UIGNvZGVwYWdlLCBEV09SRCBkd0ZsYWdzLCBMUENQSU5GT0VYVyBjcGluZm8gKQp7CiAgICBpZiAoIUdldENQSW5mbyggY29kZXBhZ2UsIChMUENQSU5GTyljcGluZm8gKSkKICAgICAgcmV0dXJuIEZBTFNFOwoKICAgIHN3aXRjaChjb2RlcGFnZSkKICAgIHsKICAgICAgICBjYXNlIENQX1VURjc6CiAgICAgICAgewogICAgICAgICAgICBzdGF0aWMgY29uc3QgV0NIQVIgdXRmN1tdID0geydVJywnbicsJ2knLCdjJywnbycsJ2QnLCdlJywnICcsJygnLCdVJywnVCcsJ0YnLCctJywnNycsJyknLDB9OwoKICAgICAgICAgICAgY3BpbmZvLT5Db2RlUGFnZSA9IENQX1VURjc7CiAgICAgICAgICAgIGNwaW5mby0+VW5pY29kZURlZmF1bHRDaGFyID0gMHgzZjsKICAgICAgICAgICAgc3RyY3B5VyhjcGluZm8tPkNvZGVQYWdlTmFtZSwgdXRmNyk7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIH0KCiAgICAgICAgY2FzZSBDUF9VVEY4OgogICAgICAgIHsKICAgICAgICAgICAgc3RhdGljIGNvbnN0IFdDSEFSIHV0ZjhbXSA9IHsnVScsJ24nLCdpJywnYycsJ28nLCdkJywnZScsJyAnLCcoJywnVScsJ1QnLCdGJywnLScsJzgnLCcpJywwfTsKCiAgICAgICAgICAgIGNwaW5mby0+Q29kZVBhZ2UgPSBDUF9VVEY4OwogICAgICAgICAgICBjcGluZm8tPlVuaWNvZGVEZWZhdWx0Q2hhciA9IDB4M2Y7CiAgICAgICAgICAgIHN0cmNweVcoY3BpbmZvLT5Db2RlUGFnZU5hbWUsIHV0ZjgpOwogICAgICAgICAgICBicmVhazsKICAgICAgICB9CgogICAgICAgIGRlZmF1bHQ6CiAgICAgICAgewogICAgICAgICAgICBjb25zdCB1bmlvbiBjcHRhYmxlICp0YWJsZSA9IGdldF9jb2RlcGFnZV90YWJsZSggY29kZXBhZ2UgKTsKCiAgICAgICAgICAgIGNwaW5mby0+Q29kZVBhZ2UgPSB0YWJsZS0+aW5mby5jb2RlcGFnZTsKICAgICAgICAgICAgY3BpbmZvLT5Vbmljb2RlRGVmYXVsdENoYXIgPSB0YWJsZS0+aW5mby5kZWZfdW5pY29kZV9jaGFyOwogICAgICAgICAgICBNdWx0aUJ5dGVUb1dpZGVDaGFyKCBDUF9BQ1AsIDAsIHRhYmxlLT5pbmZvLm5hbWUsIC0xLCBjcGluZm8tPkNvZGVQYWdlTmFtZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2l6ZW9mKGNwaW5mby0+Q29kZVBhZ2VOYW1lKS9zaXplb2YoV0NIQVIpKTsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgfQogICAgfQogICAgcmV0dXJuIFRSVUU7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgICAgICAgICAgRW51bVN5c3RlbUNvZGVQYWdlc0EgICAoS0VSTkVMMzIuQCkKICoKICogQ2FsbCBhIHVzZXIgZGVmaW5lZCBmdW5jdGlvbiBmb3IgZXZlcnkgY29kZSBwYWdlIGluc3RhbGxlZCBvbiB0aGUgc3lzdGVtLgogKgogKiBQQVJBTVMKICogICBscGZuQ29kZVBhZ2VFbnVtIFtJXSBVc2VyIENPREVQQUdFX0VOVU1QUk9DIHRvIGNhbGwgd2l0aCBlYWNoIGZvdW5kIGNvZGUgcGFnZQogKiAgIGZsYWdzICAgICAgICAgICAgW0ldIFJlc2VydmVkLCBzZXQgdG8gMC4KICoKICogUkVUVVJOUwogKiAgVFJVRSwgSWYgYWxsIGNvZGUgcGFnZXMgaGF2ZSBiZWVuIGVudW1lcmF0ZWQsIG9yCiAqICBGQUxTRSBpZiBscGZuQ29kZVBhZ2VFbnVtIHJldHVybmVkIEZBTFNFIHRvIHN0b3AgdGhlIGVudW1lcmF0aW9uLgogKi8KQk9PTCBXSU5BUEkgRW51bVN5c3RlbUNvZGVQYWdlc0EoIENPREVQQUdFX0VOVU1QUk9DQSBscGZuQ29kZVBhZ2VFbnVtLCBEV09SRCBmbGFncyApCnsKICAgIGNvbnN0IHVuaW9uIGNwdGFibGUgKnRhYmxlOwogICAgY2hhciBidWZmZXJbMTBdOwogICAgaW50IGluZGV4ID0gMDsKCiAgICBmb3IgKDs7KQogICAgewogICAgICAgIGlmICghKHRhYmxlID0gd2luZV9jcF9lbnVtX3RhYmxlKCBpbmRleCsrICkpKSBicmVhazsKICAgICAgICBzcHJpbnRmKCBidWZmZXIsICIlZCIsIHRhYmxlLT5pbmZvLmNvZGVwYWdlICk7CiAgICAgICAgaWYgKCFscGZuQ29kZVBhZ2VFbnVtKCBidWZmZXIgKSkgYnJlYWs7CiAgICB9CiAgICByZXR1cm4gVFJVRTsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgICAgICAgICAgRW51bVN5c3RlbUNvZGVQYWdlc1cgICAoS0VSTkVMMzIuQCkKICoKICogU2VlIEVudW1TeXN0ZW1Db2RlUGFnZXNBLgogKi8KQk9PTCBXSU5BUEkgRW51bVN5c3RlbUNvZGVQYWdlc1coIENPREVQQUdFX0VOVU1QUk9DVyBscGZuQ29kZVBhZ2VFbnVtLCBEV09SRCBmbGFncyApCnsKICAgIGNvbnN0IHVuaW9uIGNwdGFibGUgKnRhYmxlOwogICAgV0NIQVIgYnVmZmVyWzEwXSwgKnA7CiAgICBpbnQgcGFnZSwgaW5kZXggPSAwOwoKICAgIGZvciAoOzspCiAgICB7CiAgICAgICAgaWYgKCEodGFibGUgPSB3aW5lX2NwX2VudW1fdGFibGUoIGluZGV4KysgKSkpIGJyZWFrOwogICAgICAgIHAgPSBidWZmZXIgKyBzaXplb2YoYnVmZmVyKS9zaXplb2YoV0NIQVIpOwogICAgICAgICotLXAgPSAwOwogICAgICAgIHBhZ2UgPSB0YWJsZS0+aW5mby5jb2RlcGFnZTsKICAgICAgICBkbwogICAgICAgIHsKICAgICAgICAgICAgKi0tcCA9ICcwJyArIChwYWdlICUgMTApOwogICAgICAgICAgICBwYWdlIC89IDEwOwogICAgICAgIH0gd2hpbGUoIHBhZ2UgKTsKICAgICAgICBpZiAoIWxwZm5Db2RlUGFnZUVudW0oIHAgKSkgYnJlYWs7CiAgICB9CiAgICByZXR1cm4gVFJVRTsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgICAgICAgICAgTXVsdGlCeXRlVG9XaWRlQ2hhciAgIChLRVJORUwzMi5AKQogKgogKiBDb252ZXJ0IGEgbXVsdGlieXRlIGNoYXJhY3RlciBzdHJpbmcgaW50byBhIFVuaWNvZGUgc3RyaW5nLgogKgogKiBQQVJBTVMKICogICBwYWdlICAgW0ldIENvZGVwYWdlIGNoYXJhY3RlciBzZXQgdG8gY29udmVydCBmcm9tCiAqICAgZmxhZ3MgIFtJXSBDaGFyYWN0ZXIgbWFwcGluZyBmbGFncwogKiAgIHNyYyAgICBbSV0gU291cmNlIHN0cmluZyBidWZmZXIKICogICBzcmNsZW4gW0ldIExlbmd0aCBvZiBzcmMgKGluIGJ5dGVzKSwgb3IgLTEgaWYgc3JjIGlzIE5VTCB0ZXJtaW5hdGVkCiAqICAgZHN0ICAgIFtPXSBEZXN0aW5hdGlvbiBidWZmZXIKICogICBkc3RsZW4gW0ldIExlbmd0aCBvZiBkc3QgKGluIFdDSEFScyksIG9yIDAgdG8gY29tcHV0ZSB0aGUgcmVxdWlyZWQgbGVuZ3RoCiAqCiAqIFJFVFVSTlMKICogICBTdWNjZXNzOiBJZiBkc3RsZW4gPiAwLCB0aGUgbnVtYmVyIG9mIGNoYXJhY3RlcnMgd3JpdHRlbiB0byBkc3QuCiAqICAgICAgICAgICAgSWYgZHN0bGVuID09IDAsIHRoZSBudW1iZXIgb2YgY2hhcmFjdGVycyBuZWVkZWQgdG8gcGVyZm9ybSB0aGUKICogICAgICAgICAgICBjb252ZXJzaW9uLiBJbiBib3RoIGNhc2VzIHRoZSBjb3VudCBpbmNsdWRlcyB0aGUgdGVybWluYXRpbmcgTlVMLgogKiAgIEZhaWx1cmU6IDAuIFVzZSBHZXRMYXN0RXJyb3IoKSB0byBkZXRlcm1pbmUgdGhlIGNhdXNlLiBQb3NzaWJsZSBlcnJvcnMgYXJlCiAqICAgICAgICAgICAgRVJST1JfSU5TVUZGSUNJRU5UX0JVRkZFUiwgaWYgbm90IGVub3VnaCBzcGFjZSBpcyBhdmFpbGFibGUgaW4gZHN0CiAqICAgICAgICAgICAgYW5kIGRzdGxlbiAhPSAwOyBFUlJPUl9JTlZBTElEX1BBUkFNRVRFUiwgIGlmIGFuIGludmFsaWQgcGFyYW1ldGVyCiAqICAgICAgICAgICAgaXMgcGFzc2VkLCBhbmQgRVJST1JfTk9fVU5JQ09ERV9UUkFOU0xBVElPTiBpZiBubyB0cmFuc2xhdGlvbiBpcwogKiAgICAgICAgICAgIHBvc3NpYmxlIGZvciBzcmMuCiAqLwpJTlQgV0lOQVBJIE11bHRpQnl0ZVRvV2lkZUNoYXIoIFVJTlQgcGFnZSwgRFdPUkQgZmxhZ3MsIExQQ1NUUiBzcmMsIElOVCBzcmNsZW4sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTFBXU1RSIGRzdCwgSU5UIGRzdGxlbiApCnsKICAgIGNvbnN0IHVuaW9uIGNwdGFibGUgKnRhYmxlOwogICAgaW50IHJldDsKCiAgICBpZiAoIXNyYyB8fCAoIWRzdCAmJiBkc3RsZW4pKQogICAgewogICAgICAgIFNldExhc3RFcnJvciggRVJST1JfSU5WQUxJRF9QQVJBTUVURVIgKTsKICAgICAgICByZXR1cm4gMDsKICAgIH0KCiAgICBpZiAoc3JjbGVuIDwgMCkgc3JjbGVuID0gc3RybGVuKHNyYykgKyAxOwoKICAgIHN3aXRjaChwYWdlKQogICAgewogICAgY2FzZSBDUF9TWU1CT0w6CiAgICAgICAgaWYoIGZsYWdzKQogICAgICAgIHsKICAgICAgICAgICAgU2V0TGFzdEVycm9yKCBFUlJPUl9JTlZBTElEX1BBUkFNRVRFUiApOwogICAgICAgICAgICByZXR1cm4gMDsKICAgICAgICB9CiAgICAgICAgcmV0ID0gd2luZV9jcHN5bWJvbF9tYnN0b3djcyggc3JjLCBzcmNsZW4sIGRzdCwgZHN0bGVuICk7CiAgICAgICAgYnJlYWs7CiAgICBjYXNlIENQX1VURjc6CiAgICAgICAgRklYTUUoIlVURi03IG5vdCBzdXBwb3J0ZWRcbiIpOwogICAgICAgIFNldExhc3RFcnJvciggRVJST1JfQ0FMTF9OT1RfSU1QTEVNRU5URUQgKTsKICAgICAgICByZXR1cm4gMDsKICAgIGNhc2UgQ1BfVU5JWENQOgogICAgICAgIGlmICh1bml4X2NwdGFibGUpCiAgICAgICAgewogICAgICAgICAgICByZXQgPSB3aW5lX2NwX21ic3Rvd2NzKCB1bml4X2NwdGFibGUsIGZsYWdzLCBzcmMsIHNyY2xlbiwgZHN0LCBkc3RsZW4gKTsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgfQogICAgICAgIC8qIGZhbGwgdGhyb3VnaCAqLwogICAgY2FzZSBDUF9VVEY4OgogICAgICAgIHJldCA9IHdpbmVfdXRmOF9tYnN0b3djcyggZmxhZ3MsIHNyYywgc3JjbGVuLCBkc3QsIGRzdGxlbiApOwogICAgICAgIGJyZWFrOwogICAgZGVmYXVsdDoKICAgICAgICBpZiAoISh0YWJsZSA9IGdldF9jb2RlcGFnZV90YWJsZSggcGFnZSApKSkKICAgICAgICB7CiAgICAgICAgICAgIFNldExhc3RFcnJvciggRVJST1JfSU5WQUxJRF9QQVJBTUVURVIgKTsKICAgICAgICAgICAgcmV0dXJuIDA7CiAgICAgICAgfQogICAgICAgIHJldCA9IHdpbmVfY3BfbWJzdG93Y3MoIHRhYmxlLCBmbGFncywgc3JjLCBzcmNsZW4sIGRzdCwgZHN0bGVuICk7CiAgICAgICAgYnJlYWs7CiAgICB9CgogICAgaWYgKHJldCA8IDApCiAgICB7CiAgICAgICAgc3dpdGNoKHJldCkKICAgICAgICB7CiAgICAgICAgY2FzZSAtMTogU2V0TGFzdEVycm9yKCBFUlJPUl9JTlNVRkZJQ0lFTlRfQlVGRkVSICk7IGJyZWFrOwogICAgICAgIGNhc2UgLTI6IFNldExhc3RFcnJvciggRVJST1JfTk9fVU5JQ09ERV9UUkFOU0xBVElPTiApOyBicmVhazsKICAgICAgICB9CiAgICAgICAgcmV0ID0gMDsKICAgIH0KICAgIFRSQUNFKCJjcCAlZCAlcyAtPiAlcywgcmV0ID0gJWRcbiIsCiAgICAgICAgICBwYWdlLCBkZWJ1Z3N0cl9hbihzcmMsIHNyY2xlbiksIGRlYnVnc3RyX3duKGRzdCwgcmV0KSwgcmV0KTsKICAgIHJldHVybiByZXQ7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICAgICAgICAgIFdpZGVDaGFyVG9NdWx0aUJ5dGUgICAoS0VSTkVMMzIuQCkKICoKICogQ29udmVydCBhIFVuaWNvZGUgY2hhcmFjdGVyIHN0cmluZyBpbnRvIGEgbXVsdGlieXRlIHN0cmluZy4KICoKICogUEFSQU1TCiAqICAgcGFnZSAgICBbSV0gQ29kZSBwYWdlIGNoYXJhY3RlciBzZXQgdG8gY29udmVydCB0bwogKiAgIGZsYWdzICAgW0ldIE1hcHBpbmcgRmxhZ3MgKE1CXyBjb25zdGFudHMgZnJvbSAid2lubmxzLmgiKS4KICogICBzcmMgICAgIFtJXSBTb3VyY2Ugc3RyaW5nIGJ1ZmZlcgogKiAgIHNyY2xlbiAgW0ldIExlbmd0aCBvZiBzcmMgKGluIFdDSEFScyksIG9yIC0xIGlmIHNyYyBpcyBOVUwgdGVybWluYXRlZAogKiAgIGRzdCAgICAgW09dIERlc3RpbmF0aW9uIGJ1ZmZlcgogKiAgIGRzdGxlbiAgW0ldIExlbmd0aCBvZiBkc3QgKGluIGJ5dGVzKSwgb3IgMCB0byBjb21wdXRlIHRoZSByZXF1aXJlZCBsZW5ndGgKICogICBkZWZjaGFyIFtJXSBEZWZhdWx0IGNoYXJhY3RlciB0byB1c2UgZm9yIGNvbnZlcnNpb24gaWYgbm8gZXhhY3QKICoJCSAgICBjb252ZXJzaW9uIGNhbiBiZSBtYWRlCiAqICAgdXNlZCAgICBbT10gU2V0IGlmIGRlZmF1bHQgY2hhcmFjdGVyIHdhcyB1c2VkIGluIHRoZSBjb252ZXJzaW9uCiAqCiAqIFJFVFVSTlMKICogICBTdWNjZXNzOiBJZiBkc3RsZW4gPiAwLCB0aGUgbnVtYmVyIG9mIGNoYXJhY3RlcnMgd3JpdHRlbiB0byBkc3QuCiAqICAgICAgICAgICAgSWYgZHN0bGVuID09IDAsIG51bWJlciBvZiBjaGFyYWN0ZXJzIG5lZWRlZCB0byBwZXJmb3JtIHRoZQogKiAgICAgICAgICAgIGNvbnZlcnNpb24uIEluIGJvdGggY2FzZXMgdGhlIGNvdW50IGluY2x1ZGVzIHRoZSB0ZXJtaW5hdGluZyBOVUwuCiAqICAgRmFpbHVyZTogMC4gVXNlIEdldExhc3RFcnJvcigpIHRvIGRldGVybWluZSB0aGUgY2F1c2UuIFBvc3NpYmxlIGVycm9ycyBhcmUKICogICAgICAgICAgICBFUlJPUl9JTlNVRkZJQ0lFTlRfQlVGRkVSLCBpZiBub3QgZW5vdWdoIHNwYWNlIGlzIGF2YWlsYWJsZSBpbiBkc3QKICogICAgICAgICAgICBhbmQgZHN0bGVuICE9IDAsIGFuZCBFUlJPUl9JTlZBTElEX1BBUkFNRVRFUiwgaWYgYW4gaW52YWxpZAogKiAgICAgICAgICAgIHBhcmFtZXRlciB3YXMgZ2l2ZW4uCiAqLwpJTlQgV0lOQVBJIFdpZGVDaGFyVG9NdWx0aUJ5dGUoIFVJTlQgcGFnZSwgRFdPUkQgZmxhZ3MsIExQQ1dTVFIgc3JjLCBJTlQgc3JjbGVuLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIExQU1RSIGRzdCwgSU5UIGRzdGxlbiwgTFBDU1RSIGRlZmNoYXIsIEJPT0wgKnVzZWQgKQp7CiAgICBjb25zdCB1bmlvbiBjcHRhYmxlICp0YWJsZTsKICAgIGludCByZXQsIHVzZWRfdG1wOwoKICAgIGlmICghc3JjIHx8ICghZHN0ICYmIGRzdGxlbikpCiAgICB7CiAgICAgICAgU2V0TGFzdEVycm9yKCBFUlJPUl9JTlZBTElEX1BBUkFNRVRFUiApOwogICAgICAgIHJldHVybiAwOwogICAgfQoKICAgIGlmIChzcmNsZW4gPCAwKSBzcmNsZW4gPSBzdHJsZW5XKHNyYykgKyAxOwoKICAgIHN3aXRjaChwYWdlKQogICAgewogICAgY2FzZSBDUF9TWU1CT0w6CiAgICAgICAgaWYoIGZsYWdzIHx8IGRlZmNoYXIgfHwgdXNlZCkKICAgICAgICB7CiAgICAgICAgICAgIFNldExhc3RFcnJvciggRVJST1JfSU5WQUxJRF9QQVJBTUVURVIgKTsKICAgICAgICAgICAgcmV0dXJuIDA7CiAgICAgICAgfQogICAgICAgIHJldCA9IHdpbmVfY3BzeW1ib2xfd2NzdG9tYnMoIHNyYywgc3JjbGVuLCBkc3QsIGRzdGxlbiApOwogICAgICAgIGJyZWFrOwogICAgY2FzZSBDUF9VVEY3OgogICAgICAgIEZJWE1FKCJVVEYtNyBub3Qgc3VwcG9ydGVkXG4iKTsKICAgICAgICBTZXRMYXN0RXJyb3IoIEVSUk9SX0NBTExfTk9UX0lNUExFTUVOVEVEICk7CiAgICAgICAgcmV0dXJuIDA7CiAgICBjYXNlIENQX1VOSVhDUDoKICAgICAgICBpZiAodW5peF9jcHRhYmxlKQogICAgICAgIHsKICAgICAgICAgICAgcmV0ID0gd2luZV9jcF93Y3N0b21icyggdW5peF9jcHRhYmxlLCBmbGFncywgc3JjLCBzcmNsZW4sIGRzdCwgZHN0bGVuLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkZWZjaGFyLCB1c2VkID8gJnVzZWRfdG1wIDogTlVMTCApOwogICAgICAgICAgICBicmVhazsKICAgICAgICB9CiAgICAgICAgLyogZmFsbCB0aHJvdWdoICovCiAgICBjYXNlIENQX1VURjg6CiAgICAgICAgaWYgKHVzZWQpICp1c2VkID0gRkFMU0U7ICAvKiBhbGwgY2hhcnMgYXJlIHZhbGlkIGZvciBVVEYtOCAqLwogICAgICAgIHJldCA9IHdpbmVfdXRmOF93Y3N0b21icyggZmxhZ3MsIHNyYywgc3JjbGVuLCBkc3QsIGRzdGxlbiApOwogICAgICAgIGJyZWFrOwogICAgZGVmYXVsdDoKICAgICAgICBpZiAoISh0YWJsZSA9IGdldF9jb2RlcGFnZV90YWJsZSggcGFnZSApKSkKICAgICAgICB7CiAgICAgICAgICAgIFNldExhc3RFcnJvciggRVJST1JfSU5WQUxJRF9QQVJBTUVURVIgKTsKICAgICAgICAgICAgcmV0dXJuIDA7CiAgICAgICAgfQogICAgICAgIHJldCA9IHdpbmVfY3Bfd2NzdG9tYnMoIHRhYmxlLCBmbGFncywgc3JjLCBzcmNsZW4sIGRzdCwgZHN0bGVuLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRlZmNoYXIsIHVzZWQgPyAmdXNlZF90bXAgOiBOVUxMICk7CiAgICAgICAgaWYgKHVzZWQpICp1c2VkID0gdXNlZF90bXA7CiAgICAgICAgYnJlYWs7CiAgICB9CgogICAgaWYgKHJldCA8IDApCiAgICB7CiAgICAgICAgc3dpdGNoKHJldCkKICAgICAgICB7CiAgICAgICAgY2FzZSAtMTogU2V0TGFzdEVycm9yKCBFUlJPUl9JTlNVRkZJQ0lFTlRfQlVGRkVSICk7IGJyZWFrOwogICAgICAgIGNhc2UgLTI6IFNldExhc3RFcnJvciggRVJST1JfTk9fVU5JQ09ERV9UUkFOU0xBVElPTiApOyBicmVhazsKICAgICAgICB9CiAgICAgICAgcmV0ID0gMDsKICAgIH0KICAgIFRSQUNFKCJjcCAlZCAlcyAtPiAlcywgcmV0ID0gJWRcbiIsCiAgICAgICAgICBwYWdlLCBkZWJ1Z3N0cl93bihzcmMsIHNyY2xlbiksIGRlYnVnc3RyX2FuKGRzdCwgcmV0KSwgcmV0KTsKICAgIHJldHVybiByZXQ7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICAgICAgIEdldFRocmVhZExvY2FsZSAgICAoS0VSTkVMMzIuQCkKICoKICogR2V0IHRoZSBjdXJyZW50IHRocmVhZHMgbG9jYWxlLgogKgogKiBQQVJBTVMKICogIE5vbmUuCiAqCiAqIFJFVFVSTlMKICogIFRoZSBMQ0lEIGN1cnJlbnRseSBhc3NvY2F0ZWQgd2l0aCB0aGUgY2FsbGluZyB0aHJlYWQuCiAqLwpMQ0lEIFdJTkFQSSBHZXRUaHJlYWRMb2NhbGUodm9pZCkKewogICAgTENJRCByZXQgPSBOdEN1cnJlbnRUZWIoKS0+Q3VycmVudExvY2FsZTsKICAgIGlmICghcmV0KSBOdEN1cnJlbnRUZWIoKS0+Q3VycmVudExvY2FsZSA9IHJldCA9IEdldFVzZXJEZWZhdWx0TENJRCgpOwogICAgcmV0dXJuIHJldDsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICAgICAgIFNldFRocmVhZExvY2FsZSAgICAoS0VSTkVMMzIuQCkKICoKICogU2V0IHRoZSBjdXJyZW50IHRocmVhZHMgbG9jYWxlLgogKgogKiBQQVJBTVMKICogIGxjaWQgW0ldIExDSUQgb2YgdGhlIGxvY2FsZSB0byBzZXQKICoKICogUkVUVVJOUwogKiAgU3VjY2VzczogVFJVRS4gVGhlIHRocmVhZHMgbG9jYWxlIGlzIHNldCB0byBsY2lkLgogKiAgRmFpbHVyZTogRkFMU0UuIFVzZSBHZXRMYXN0RXJyb3IoKSB0byBkZXRlcm1pbmUgdGhlIGNhdXNlLgogKi8KQk9PTCBXSU5BUEkgU2V0VGhyZWFkTG9jYWxlKCBMQ0lEIGxjaWQgKQp7CiAgICBUUkFDRSgiKDB4JTA0WClcbiIsIGxjaWQpOwoKICAgIGxjaWQgPSBDb252ZXJ0RGVmYXVsdExvY2FsZShsY2lkKTsKCiAgICBpZiAobGNpZCAhPSBHZXRUaHJlYWRMb2NhbGUoKSkKICAgIHsKICAgICAgICBpZiAoIUlzVmFsaWRMb2NhbGUobGNpZCwgTENJRF9TVVBQT1JURUQpKQogICAgICAgIHsKICAgICAgICAgICAgU2V0TGFzdEVycm9yKEVSUk9SX0lOVkFMSURfUEFSQU1FVEVSKTsKICAgICAgICAgICAgcmV0dXJuIEZBTFNFOwogICAgICAgIH0KCiAgICAgICAgTnRDdXJyZW50VGViKCktPkN1cnJlbnRMb2NhbGUgPSBsY2lkOwogICAgICAgIGtlcm5lbF9nZXRfdGhyZWFkX2RhdGEoKS0+Y29kZV9wYWdlID0gZ2V0X2xjaWRfY29kZXBhZ2UoIGxjaWQgKTsKICAgIH0KICAgIHJldHVybiBUUlVFOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgICAgICAgU2V0VGhyZWFkVUlMYW5ndWFnZSAgICAoS0VSTkVMMzIuQCkKICoKICogU2V0IHRoZSBjdXJyZW50IHRocmVhZHMgVUkgbGFuZ3VhZ2UuCiAqCiAqIFBBUkFNUwogKiAgbGFuZ2lkIFtJXSBMQU5HSUQgb2YgdGhlIGxhbmd1YWdlIHRvIHNldCwgb3IgMCB0byB1c2UKICogICAgICAgICAgICAgdGhlIGF2YWlsYWJsZSBsYW5ndWFnZSB3aGljaCBpcyBiZXN0IHN1cHBvcnRlZAogKiAgICAgICAgICAgICBmb3IgY29uc29sZSBhcHBsaWNhdGlvbnMKICoKICogUkVUVVJOUwogKiAgU3VjY2VzczogVGhlIHJldHVybiB2YWx1ZSBpcyB0aGUgc2FtZSBhcyB0aGUgaW5wdXQgdmFsdWUuCiAqICBGYWlsdXJlOiBUaGUgcmV0dXJuIHZhbHVlIGRpZmZlcnMgZnJvbSB0aGUgaW5wdXQgdmFsdWUuCiAqICAgICAgICAgICBVc2UgR2V0TGFzdEVycm9yKCkgdG8gZGV0ZXJtaW5lIHRoZSBjYXVzZS4KICovCkxBTkdJRCBXSU5BUEkgU2V0VGhyZWFkVUlMYW5ndWFnZSggTEFOR0lEIGxhbmdpZCApCnsKICAgIFRSQUNFKCIoMHglMDR4KSBzdHViIC0gcmV0dXJuaW5nIHN1Y2Nlc3NcbiIsIGxhbmdpZCk7CiAgICByZXR1cm4gbGFuZ2lkOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCQlDb252ZXJ0RGVmYXVsdExvY2FsZSAoS0VSTkVMMzIuQCkKICoKICogQ29udmVydCBhIGRlZmF1bHQgbG9jYWxlIGlkZW50aWZpZXIgaW50byBhIHJlYWwgaWRlbnRpZmllci4KICoKICogUEFSQU1TCiAqICBsY2lkIFtJXSBMQ0lEIGlkZW50aWZpZXIgb2YgdGhlIGxvY2FsZSB0byBjb252ZXJ0CiAqCiAqIFJFVFVSTlMKICogIGxjaWQgdW5jaGFuZ2VkLCBpZiBub3QgYSBkZWZhdWx0IGxvY2FsZSBvciBpdHMgc3VibGFuZ3VhZ2UgaXMKICogICBub3QgU1VCTEFOR19ORVVUUkFMLgogKiAgR2V0U3lzdGVtRGVmYXVsdExDSUQoKSwgaWYgbGNpZCA9PSBMT0NBTEVfU1lTVEVNX0RFRkFVTFQuCiAqICBHZXRVc2VyRGVmYXVsdExDSUQoKSwgaWYgbGNpZCA9PSBMT0NBTEVfVVNFUl9ERUZBVUxUIG9yIExPQ0FMRV9ORVVUUkFMLgogKiAgT3RoZXJ3aXNlLCBsY2lkIHdpdGggc3VibGFuZ3VhZ2UgY2hhbmdlZCB0byBTVUJMQU5HX0RFRkFVTFQuCiAqLwpMQ0lEIFdJTkFQSSBDb252ZXJ0RGVmYXVsdExvY2FsZSggTENJRCBsY2lkICkKewogICAgTEFOR0lEIGxhbmdpZDsKCiAgICBzd2l0Y2ggKGxjaWQpCiAgICB7CiAgICBjYXNlIExPQ0FMRV9TWVNURU1fREVGQVVMVDoKICAgICAgICBsY2lkID0gR2V0U3lzdGVtRGVmYXVsdExDSUQoKTsKICAgICAgICBicmVhazsKICAgIGNhc2UgTE9DQUxFX1VTRVJfREVGQVVMVDoKICAgIGNhc2UgTE9DQUxFX05FVVRSQUw6CiAgICAgICAgbGNpZCA9IEdldFVzZXJEZWZhdWx0TENJRCgpOwogICAgICAgIGJyZWFrOwogICAgZGVmYXVsdDoKICAgICAgICAvKiBSZXBsYWNlIFNVQkxBTkdfTkVVVFJBTCB3aXRoIFNVQkxBTkdfREVGQVVMVCAqLwogICAgICAgIGxhbmdpZCA9IExBTkdJREZST01MQ0lEKGxjaWQpOwogICAgICAgIGlmIChTVUJMQU5HSUQobGFuZ2lkKSA9PSBTVUJMQU5HX05FVVRSQUwpCiAgICAgICAgewogICAgICAgICAgbGFuZ2lkID0gTUFLRUxBTkdJRChQUklNQVJZTEFOR0lEKGxhbmdpZCksIFNVQkxBTkdfREVGQVVMVCk7CiAgICAgICAgICBsY2lkID0gTUFLRUxDSUQobGFuZ2lkLCBTT1JUSURGUk9NTENJRChsY2lkKSk7CiAgICAgICAgfQogICAgfQogICAgcmV0dXJuIGxjaWQ7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgICAgICBJc1ZhbGlkTG9jYWxlICAgKEtFUk5FTDMyLkApCiAqCiAqIERldGVybWluZSBpZiBhIGxvY2FsZSBpcyB2YWxpZC4KICoKICogUEFSQU1TCiAqICBsY2lkICBbSV0gTENJRCBvZiB0aGUgbG9jYWxlIHRvIGNoZWNrCiAqICBmbGFncyBbSV0gTENJRF9TVVBQT1JURUQgPSBWYWxpZCwgTENJRF9JTlNUQUxMRUQgPSBWYWxpZCBhbmQgaW5zdGFsbGVkIG9uIHRoZSBzeXN0ZW0KICoKICogUkVUVVJOUwogKiAgVFJVRSwgIGlmIGxjaWQgaXMgdmFsaWQsCiAqICBGQUxTRSwgb3RoZXJ3aXNlLgogKgogKiBOT1RFUwogKiAgV2luZSBkb2VzIG5vdCBjdXJyZW50bHkgbWFrZSB0aGUgZGlzdGluY3Rpb24gYmV0d2VlbiBzdXBwb3J0ZWQgYW5kIGluc3RhbGxlZC4gQWxsCiAqICBsYW5ndWFnZXMgc3VwcG9ydGVkIGFyZSBpbnN0YWxsZWQgYnkgZGVmYXVsdC4KICovCkJPT0wgV0lOQVBJIElzVmFsaWRMb2NhbGUoIExDSUQgbGNpZCwgRFdPUkQgZmxhZ3MgKQp7CiAgICAvKiBjaGVjayBpZiBsYW5ndWFnZSBpcyByZWdpc3RlcmVkIGluIHRoZSBrZXJuZWwzMiByZXNvdXJjZXMgKi8KICAgIHJldHVybiBGaW5kUmVzb3VyY2VFeFcoIGtlcm5lbDMyX2hhbmRsZSwgKExQV1NUUilSVF9TVFJJTkcsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAoTFBDV1NUUilMT0NBTEVfSUxBTkdVQUdFLCBMQU5HSURGUk9NTENJRChsY2lkKSkgIT0gMDsKfQoKCnN0YXRpYyBCT09MIENBTExCQUNLIGVudW1fbGFuZ19wcm9jX2EoIEhNT0RVTEUgaE1vZHVsZSwgTFBDU1RSIHR5cGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIExQQ1NUUiBuYW1lLCBXT1JEIExhbmdJRCwgTE9OR19QVFIgbFBhcmFtICkKewogICAgTE9DQUxFX0VOVU1QUk9DQSBscGZuTG9jYWxlRW51bSA9IChMT0NBTEVfRU5VTVBST0NBKWxQYXJhbTsKICAgIGNoYXIgYnVmWzIwXTsKCiAgICBzcHJpbnRmKGJ1ZiwgIiUwOHgiLCAoVUlOVClMYW5nSUQpOwogICAgcmV0dXJuIGxwZm5Mb2NhbGVFbnVtKCBidWYgKTsKfQoKc3RhdGljIEJPT0wgQ0FMTEJBQ0sgZW51bV9sYW5nX3Byb2NfdyggSE1PRFVMRSBoTW9kdWxlLCBMUENXU1RSIHR5cGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIExQQ1dTVFIgbmFtZSwgV09SRCBMYW5nSUQsIExPTkdfUFRSIGxQYXJhbSApCnsKICAgIHN0YXRpYyBjb25zdCBXQ0hBUiBmb3JtYXRXW10gPSB7JyUnLCcwJywnOCcsJ3gnLDB9OwogICAgTE9DQUxFX0VOVU1QUk9DVyBscGZuTG9jYWxlRW51bSA9IChMT0NBTEVfRU5VTVBST0NXKWxQYXJhbTsKICAgIFdDSEFSIGJ1ZlsyMF07CiAgICBzcHJpbnRmVyggYnVmLCBmb3JtYXRXLCAoVUlOVClMYW5nSUQgKTsKICAgIHJldHVybiBscGZuTG9jYWxlRW51bSggYnVmICk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICAgICAgIEVudW1TeXN0ZW1Mb2NhbGVzQSAgKEtFUk5FTDMyLkApCiAqCiAqIENhbGwgYSB1c2VycyBmdW5jdGlvbiBmb3IgZWFjaCBsb2NhbGUgYXZhaWxhYmxlIG9uIHRoZSBzeXN0ZW0uCiAqCiAqIFBBUkFNUwogKiAgbHBmbkxvY2FsZUVudW0gW0ldIENhbGxiYWNrIGZ1bmN0aW9uIHRvIGNhbGwgZm9yIGVhY2ggbG9jYWxlCiAqICBkd0ZsYWdzICAgICAgICBbSV0gTE9DQUxFX1NVUFBPUlRFRD1BbGwgc3VwcG9ydGVkLCBMT0NBTEVfSU5TVEFMTEVEPUluc3RhbGxlZCBvbmx5CiAqCiAqIFJFVFVSTlMKICogIFN1Y2Nlc3M6IFRSVUUuCiAqICBGYWlsdXJlOiBGQUxTRS4gVXNlIEdldExhc3RFcnJvcigpIHRvIGRldGVybWluZSB0aGUgY2F1c2UuCiAqLwpCT09MIFdJTkFQSSBFbnVtU3lzdGVtTG9jYWxlc0EoIExPQ0FMRV9FTlVNUFJPQ0EgbHBmbkxvY2FsZUVudW0sIERXT1JEIGR3RmxhZ3MgKQp7CiAgICBUUkFDRSgiKCVwLCUwOHgpXG4iLCBscGZuTG9jYWxlRW51bSwgZHdGbGFncyk7CiAgICBFbnVtUmVzb3VyY2VMYW5ndWFnZXNBKCBrZXJuZWwzMl9oYW5kbGUsIChMUFNUUilSVF9TVFJJTkcsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAoTFBDU1RSKUxPQ0FMRV9JTEFOR1VBR0UsIGVudW1fbGFuZ19wcm9jX2EsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAoTE9OR19QVFIpbHBmbkxvY2FsZUVudW0pOwogICAgcmV0dXJuIFRSVUU7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgICAgICBFbnVtU3lzdGVtTG9jYWxlc1cgIChLRVJORUwzMi5AKQogKgogKiBTZWUgRW51bVN5c3RlbUxvY2FsZXNBLgogKi8KQk9PTCBXSU5BUEkgRW51bVN5c3RlbUxvY2FsZXNXKCBMT0NBTEVfRU5VTVBST0NXIGxwZm5Mb2NhbGVFbnVtLCBEV09SRCBkd0ZsYWdzICkKewogICAgVFJBQ0UoIiglcCwlMDh4KVxuIiwgbHBmbkxvY2FsZUVudW0sIGR3RmxhZ3MpOwogICAgRW51bVJlc291cmNlTGFuZ3VhZ2VzVygga2VybmVsMzJfaGFuZGxlLCAoTFBXU1RSKVJUX1NUUklORywKICAgICAgICAgICAgICAgICAgICAgICAgICAgIChMUENXU1RSKUxPQ0FMRV9JTEFOR1VBR0UsIGVudW1fbGFuZ19wcm9jX3csCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAoTE9OR19QVFIpbHBmbkxvY2FsZUVudW0pOwogICAgcmV0dXJuIFRSVUU7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICAgICAgIFZlckxhbmd1YWdlTmFtZUEgIChLRVJORUwzMi5AKQogKgogKiBHZXQgdGhlIG5hbWUgb2YgYSBsYW5ndWFnZS4KICoKICogUEFSQU1TCiAqICB3TGFuZyAgW0ldIExBTkdJRCBvZiB0aGUgbGFuZ3VhZ2UKICogIHN6TGFuZyBbT10gRGVzdGluYXRpb24gZm9yIHRoZSBsYW5ndWFnZSBuYW1lCiAqCiAqIFJFVFVSTlMKICogIFN1Y2Nlc3M6IFRoZSBzaXplIG9mIHRoZSBsYW5ndWFnZSBuYW1lLiBJZiBzekxhbmcgaXMgbm9uLU5VTEwsIGl0IGlzIGZpbGxlZAogKiAgICAgICAgICAgd2l0aCB0aGUgbmFtZS4KICogIEZhaWx1cmU6IDAuIFVzZSBHZXRMYXN0RXJyb3IoKSB0byBkZXRlcm1pbmUgdGhlIGNhdXNlLgogKgogKi8KRFdPUkQgV0lOQVBJIFZlckxhbmd1YWdlTmFtZUEoIERXT1JEIHdMYW5nLCBMUFNUUiBzekxhbmcsIERXT1JEIG5TaXplICkKewogICAgcmV0dXJuIEdldExvY2FsZUluZm9BKCBNQUtFTENJRCh3TGFuZywgU09SVF9ERUZBVUxUKSwgTE9DQUxFX1NFTkdMQU5HVUFHRSwgc3pMYW5nLCBuU2l6ZSApOwp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgICAgICBWZXJMYW5ndWFnZU5hbWVXICAoS0VSTkVMMzIuQCkKICoKICogU2VlIFZlckxhbmd1YWdlTmFtZUEuCiAqLwpEV09SRCBXSU5BUEkgVmVyTGFuZ3VhZ2VOYW1lVyggRFdPUkQgd0xhbmcsIExQV1NUUiBzekxhbmcsIERXT1JEIG5TaXplICkKewogICAgcmV0dXJuIEdldExvY2FsZUluZm9XKCBNQUtFTENJRCh3TGFuZywgU09SVF9ERUZBVUxUKSwgTE9DQUxFX1NFTkdMQU5HVUFHRSwgc3pMYW5nLCBuU2l6ZSApOwp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgICAgICAgR2V0U3RyaW5nVHlwZVcgICAgKEtFUk5FTDMyLkApCiAqCiAqIFNlZSBHZXRTdHJpbmdUeXBlQS4KICovCkJPT0wgV0lOQVBJIEdldFN0cmluZ1R5cGVXKCBEV09SRCB0eXBlLCBMUENXU1RSIHNyYywgSU5UIGNvdW50LCBMUFdPUkQgY2hhcnR5cGUgKQp7CiAgICBpZiAoY291bnQgPT0gLTEpIGNvdW50ID0gc3RybGVuVyhzcmMpICsgMTsKICAgIHN3aXRjaCh0eXBlKQogICAgewogICAgY2FzZSBDVF9DVFlQRTE6CiAgICAgICAgd2hpbGUgKGNvdW50LS0pICpjaGFydHlwZSsrID0gZ2V0X2NoYXJfdHlwZVcoICpzcmMrKyApICYgMHhmZmY7CiAgICAgICAgYnJlYWs7CiAgICBjYXNlIENUX0NUWVBFMjoKICAgICAgICB3aGlsZSAoY291bnQtLSkgKmNoYXJ0eXBlKysgPSBnZXRfY2hhcl90eXBlVyggKnNyYysrICkgPj4gMTI7CiAgICAgICAgYnJlYWs7CiAgICBjYXNlIENUX0NUWVBFMzoKICAgIHsKICAgICAgICBXQVJOKCJDVF9DVFlQRTM6IHNlbWktc3R1Yi5cbiIpOwogICAgICAgIHdoaWxlIChjb3VudC0tKQogICAgICAgIHsKICAgICAgICAgICAgaW50IGMgPSAqc3JjOwogICAgICAgICAgICBXT1JEIHR5cGUxLCB0eXBlMyA9IDA7IC8qIEMzX05PVEFQUExJQ0FCTEUgKi8KCiAgICAgICAgICAgIHR5cGUxID0gZ2V0X2NoYXJfdHlwZVcoICpzcmMrKyApICYgMHhmZmY7CiAgICAgICAgICAgIC8qIHRyeSB0byBjb25zdHJ1Y3QgdHlwZTMgZnJvbSB0eXBlMSAqLwogICAgICAgICAgICBpZih0eXBlMSAmIEMxX1NQQUNFKSB0eXBlMyB8PSBDM19TWU1CT0w7CiAgICAgICAgICAgIGlmKHR5cGUxICYgQzFfQUxQSEEpIHR5cGUzIHw9IEMzX0FMUEhBOwogICAgICAgICAgICBpZiAoKGM+PTB4MzBBMCkmJihjPD0weDMwRkYpKSB0eXBlMyB8PSBDM19LQVRBS0FOQTsKICAgICAgICAgICAgaWYgKChjPj0weDMwNDApJiYoYzw9MHgzMDlGKSkgdHlwZTMgfD0gQzNfSElSQUdBTkE7CiAgICAgICAgICAgIGlmICgoYz49MHg0RTAwKSYmKGM8PTB4OUZBRikpIHR5cGUzIHw9IEMzX0lERU9HUkFQSDsKICAgICAgICAgICAgaWYgKChjPj0weDA2MDApJiYoYzw9MHgwNkZGKSkgdHlwZTMgfD0gQzNfS0FTSElEQTsKICAgICAgICAgICAgaWYgKChjPj0weDMwMDApJiYoYzw9MHgzMDNGKSkgdHlwZTMgfD0gQzNfU1lNQk9MOwoKICAgICAgICAgICAgaWYgKChjPj0weEZGMDApJiYoYzw9MHhGRjYwKSkgdHlwZTMgfD0gQzNfRlVMTFdJRFRIOwogICAgICAgICAgICBpZiAoKGM+PTB4RkYwMCkmJihjPD0weEZGMjApKSB0eXBlMyB8PSBDM19TWU1CT0w7CiAgICAgICAgICAgIGlmICgoYz49MHhGRjNCKSYmKGM8PTB4RkY0MCkpIHR5cGUzIHw9IEMzX1NZTUJPTDsKICAgICAgICAgICAgaWYgKChjPj0weEZGNUIpJiYoYzw9MHhGRjYwKSkgdHlwZTMgfD0gQzNfU1lNQk9MOwogICAgICAgICAgICBpZiAoKGM+PTB4RkYyMSkmJihjPD0weEZGM0EpKSB0eXBlMyB8PSBDM19BTFBIQTsKICAgICAgICAgICAgaWYgKChjPj0weEZGNDEpJiYoYzw9MHhGRjVBKSkgdHlwZTMgfD0gQzNfQUxQSEE7CiAgICAgICAgICAgIGlmICgoYz49MHhGRkUwKSYmKGM8PTB4RkZFNikpIHR5cGUzIHw9IEMzX0ZVTExXSURUSDsKICAgICAgICAgICAgaWYgKChjPj0weEZGRTApJiYoYzw9MHhGRkU2KSkgdHlwZTMgfD0gQzNfU1lNQk9MOwoKICAgICAgICAgICAgaWYgKChjPj0weEZGNjEpJiYoYzw9MHhGRkRDKSkgdHlwZTMgfD0gQzNfSEFMRldJRFRIOwogICAgICAgICAgICBpZiAoKGM+PTB4RkY2MSkmJihjPD0weEZGNjQpKSB0eXBlMyB8PSBDM19TWU1CT0w7CiAgICAgICAgICAgIGlmICgoYz49MHhGRjY1KSYmKGM8PTB4RkY5RikpIHR5cGUzIHw9IEMzX0tBVEFLQU5BOwogICAgICAgICAgICBpZiAoKGM+PTB4RkY2NSkmJihjPD0weEZGOUYpKSB0eXBlMyB8PSBDM19BTFBIQTsKICAgICAgICAgICAgaWYgKChjPj0weEZGRTgpJiYoYzw9MHhGRkVFKSkgdHlwZTMgfD0gQzNfSEFMRldJRFRIOwogICAgICAgICAgICBpZiAoKGM+PTB4RkZFOCkmJihjPD0weEZGRUUpKSB0eXBlMyB8PSBDM19TWU1CT0w7CiAgICAgICAgICAgICpjaGFydHlwZSsrID0gdHlwZTM7CiAgICAgICAgfQogICAgICAgIGJyZWFrOwogICAgfQogICAgZGVmYXVsdDoKICAgICAgICBTZXRMYXN0RXJyb3IoIEVSUk9SX0lOVkFMSURfUEFSQU1FVEVSICk7CiAgICAgICAgcmV0dXJuIEZBTFNFOwogICAgfQogICAgcmV0dXJuIFRSVUU7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgICAgICBHZXRTdHJpbmdUeXBlRXhXICAgIChLRVJORUwzMi5AKQogKgogKiBTZWUgR2V0U3RyaW5nVHlwZUV4QS4KICovCkJPT0wgV0lOQVBJIEdldFN0cmluZ1R5cGVFeFcoIExDSUQgbG9jYWxlLCBEV09SRCB0eXBlLCBMUENXU1RSIHNyYywgSU5UIGNvdW50LCBMUFdPUkQgY2hhcnR5cGUgKQp7CiAgICAvKiBsb2NhbGUgaXMgaWdub3JlZCBmb3IgVW5pY29kZSAqLwogICAgcmV0dXJuIEdldFN0cmluZ1R5cGVXKCB0eXBlLCBzcmMsIGNvdW50LCBjaGFydHlwZSApOwp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgICAgICAgR2V0U3RyaW5nVHlwZUEgICAgKEtFUk5FTDMyLkApCiAqCiAqIEdldCBjaGFyYWN0ZXJpc3RpY3Mgb2YgdGhlIGNoYXJhY3RlcnMgbWFraW5nIHVwIGEgc3RyaW5nLgogKgogKiBQQVJBTVMKICogIGxvY2FsZSAgIFtJXSBMb2NhbGUgSWQgZm9yIHRoZSBzdHJpbmcKICogIHR5cGUgICAgIFtJXSBDVF9DVFlQRTEgPSBjbGFzc2lmaWNhdGlvbiwgQ1RfQ1RZUEUyID0gZGlyZWN0aW9uYWxpdHksIENUX0NUWVBFMyA9IHR5cG9ncmFwaGljIGluZm8KICogIHNyYyAgICAgIFtJXSBTdHJpbmcgdG8gYW5hbHlzZQogKiAgY291bnQgICAgW0ldIExlbmd0aCBvZiBzcmMgaW4gY2hhcnMsIG9yIC0xIGlmIHNyYyBpcyBOVUwgdGVybWluYXRlZAogKiAgY2hhcnR5cGUgW09dIERlc3RpbmF0aW9uIGZvciB0aGUgY2FsY3VsYXRlZCBjaGFyYWN0ZXJpc3RpY3MKICoKICogUkVUVVJOUwogKiAgU3VjY2VzczogVFJVRS4gY2hhcnR5cGUgaXMgZmlsbGVkIHdpdGggdGhlIHJlcXVlc3RlZCBjaGFyYWN0ZXJpc3RpY3Mgb2YgZWFjaCBjaGFyCiAqICAgICAgICAgICBpbiBzcmMuCiAqICBGYWlsdXJlOiBGQUxTRS4gVXNlIEdldExhc3RFcnJvcigpIHRvIGRldGVybWluZSB0aGUgY2F1c2UuCiAqLwpCT09MIFdJTkFQSSBHZXRTdHJpbmdUeXBlQSggTENJRCBsb2NhbGUsIERXT1JEIHR5cGUsIExQQ1NUUiBzcmMsIElOVCBjb3VudCwgTFBXT1JEIGNoYXJ0eXBlICkKewogICAgVUlOVCBjcDsKICAgIElOVCBjb3VudFc7CiAgICBMUFdTVFIgc3JjVzsKICAgIEJPT0wgcmV0ID0gRkFMU0U7CgogICAgaWYoY291bnQgPT0gLTEpIGNvdW50ID0gc3RybGVuKHNyYykgKyAxOwoKICAgIGlmICghKGNwID0gZ2V0X2xjaWRfY29kZXBhZ2UoIGxvY2FsZSApKSkKICAgIHsKICAgICAgICBGSVhNRSgiRm9yIGxvY2FsZSAlMDR4IHVzaW5nIGN1cnJlbnQgQU5TSSBjb2RlIHBhZ2VcbiIsIGxvY2FsZSk7CiAgICAgICAgY3AgPSBHZXRBQ1AoKTsKICAgIH0KCiAgICBjb3VudFcgPSBNdWx0aUJ5dGVUb1dpZGVDaGFyKGNwLCAwLCBzcmMsIGNvdW50LCBOVUxMLCAwKTsKICAgIGlmKChzcmNXID0gSGVhcEFsbG9jKEdldFByb2Nlc3NIZWFwKCksIDAsIGNvdW50VyAqIHNpemVvZihXQ0hBUikpKSkKICAgIHsKICAgICAgICBNdWx0aUJ5dGVUb1dpZGVDaGFyKGNwLCAwLCBzcmMsIGNvdW50LCBzcmNXLCBjb3VudFcpOwogICAgLyoKICAgICAqIE5PVEU6IHRoZSB0YXJnZXQgYnVmZmVyIGhhcyAxIHdvcmQgZm9yIGVhY2ggQ0hBUkFDVEVSIGluIHRoZSBzb3VyY2UKICAgICAqIHN0cmluZywgd2l0aCBtdWx0aWJ5dGUgY2hhcmFjdGVycyB0aGVyZSBtYXliZSBiZSBtb3JlIGJ5dGVzIGluIGNvdW50CiAgICAgKiB0aGFuIGNoYXJhY3RlciBzcGFjZSBpbiB0aGUgYnVmZmVyIQogICAgICovCiAgICAgICAgcmV0ID0gR2V0U3RyaW5nVHlwZVcodHlwZSwgc3JjVywgY291bnRXLCBjaGFydHlwZSk7CiAgICAgICAgSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgc3JjVyk7CiAgICB9CiAgICByZXR1cm4gcmV0Owp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgICAgICBHZXRTdHJpbmdUeXBlRXhBICAgIChLRVJORUwzMi5AKQogKgogKiBHZXQgY2hhcmFjdGVyaXN0aWNzIG9mIHRoZSBjaGFyYWN0ZXJzIG1ha2luZyB1cCBhIHN0cmluZy4KICoKICogUEFSQU1TCiAqICBsb2NhbGUgICBbSV0gTG9jYWxlIElkIGZvciB0aGUgc3RyaW5nCiAqICB0eXBlICAgICBbSV0gQ1RfQ1RZUEUxID0gY2xhc3NpZmljYXRpb24sIENUX0NUWVBFMiA9IGRpcmVjdGlvbmFsaXR5LCBDVF9DVFlQRTMgPSB0eXBvZ3JhcGhpYyBpbmZvCiAqICBzcmMgICAgICBbSV0gU3RyaW5nIHRvIGFuYWx5c2UKICogIGNvdW50ICAgIFtJXSBMZW5ndGggb2Ygc3JjIGluIGNoYXJzLCBvciAtMSBpZiBzcmMgaXMgTlVMIHRlcm1pbmF0ZWQKICogIGNoYXJ0eXBlIFtPXSBEZXN0aW5hdGlvbiBmb3IgdGhlIGNhbGN1bGF0ZWQgY2hhcmFjdGVyaXN0aWNzCiAqCiAqIFJFVFVSTlMKICogIFN1Y2Nlc3M6IFRSVUUuIGNoYXJ0eXBlIGlzIGZpbGxlZCB3aXRoIHRoZSByZXF1ZXN0ZWQgY2hhcmFjdGVyaXN0aWNzIG9mIGVhY2ggY2hhcgogKiAgICAgICAgICAgaW4gc3JjLgogKiAgRmFpbHVyZTogRkFMU0UuIFVzZSBHZXRMYXN0RXJyb3IoKSB0byBkZXRlcm1pbmUgdGhlIGNhdXNlLgogKi8KQk9PTCBXSU5BUEkgR2V0U3RyaW5nVHlwZUV4QSggTENJRCBsb2NhbGUsIERXT1JEIHR5cGUsIExQQ1NUUiBzcmMsIElOVCBjb3VudCwgTFBXT1JEIGNoYXJ0eXBlICkKewogICAgcmV0dXJuIEdldFN0cmluZ1R5cGVBKGxvY2FsZSwgdHlwZSwgc3JjLCBjb3VudCwgY2hhcnR5cGUpOwp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICAgICAgIExDTWFwU3RyaW5nVyAgICAoS0VSTkVMMzIuQCkKICoKICogU2VlIExDTWFwU3RyaW5nQS4KICovCklOVCBXSU5BUEkgTENNYXBTdHJpbmdXKExDSUQgbGNpZCwgRFdPUkQgZmxhZ3MsIExQQ1dTVFIgc3JjLCBJTlQgc3JjbGVuLAogICAgICAgICAgICAgICAgICAgICAgICBMUFdTVFIgZHN0LCBJTlQgZHN0bGVuKQp7CiAgICBMUFdTVFIgZHN0X3B0cjsKCiAgICBpZiAoIXNyYyB8fCAhc3JjbGVuIHx8IGRzdGxlbiA8IDApCiAgICB7CiAgICAgICAgU2V0TGFzdEVycm9yKEVSUk9SX0lOVkFMSURfUEFSQU1FVEVSKTsKICAgICAgICByZXR1cm4gMDsKICAgIH0KCiAgICAvKiBtdXR1YWxseSBleGNsdXNpdmUgZmxhZ3MgKi8KICAgIGlmICgoZmxhZ3MgJiAoTENNQVBfTE9XRVJDQVNFIHwgTENNQVBfVVBQRVJDQVNFKSkgPT0gKExDTUFQX0xPV0VSQ0FTRSB8IExDTUFQX1VQUEVSQ0FTRSkgfHwKICAgICAgICAoZmxhZ3MgJiAoTENNQVBfSElSQUdBTkEgfCBMQ01BUF9LQVRBS0FOQSkpID09IChMQ01BUF9ISVJBR0FOQSB8IExDTUFQX0tBVEFLQU5BKSB8fAogICAgICAgIChmbGFncyAmIChMQ01BUF9IQUxGV0lEVEggfCBMQ01BUF9GVUxMV0lEVEgpKSA9PSAoTENNQVBfSEFMRldJRFRIIHwgTENNQVBfRlVMTFdJRFRIKSB8fAogICAgICAgIChmbGFncyAmIChMQ01BUF9UUkFESVRJT05BTF9DSElORVNFIHwgTENNQVBfU0lNUExJRklFRF9DSElORVNFKSkgPT0gKExDTUFQX1RSQURJVElPTkFMX0NISU5FU0UgfCBMQ01BUF9TSU1QTElGSUVEX0NISU5FU0UpKQogICAgewogICAgICAgIFNldExhc3RFcnJvcihFUlJPUl9JTlZBTElEX0ZMQUdTKTsKICAgICAgICByZXR1cm4gMDsKICAgIH0KCiAgICBpZiAoIWRzdGxlbikgZHN0ID0gTlVMTDsKCiAgICBsY2lkID0gQ29udmVydERlZmF1bHRMb2NhbGUobGNpZCk7CgogICAgaWYgKGZsYWdzICYgTENNQVBfU09SVEtFWSkKICAgIHsKICAgICAgICBpZiAoc3JjID09IGRzdCkKICAgICAgICB7CiAgICAgICAgICAgIFNldExhc3RFcnJvcihFUlJPUl9JTlZBTElEX0ZMQUdTKTsKICAgICAgICAgICAgcmV0dXJuIDA7CiAgICAgICAgfQoKICAgICAgICBpZiAoc3JjbGVuIDwgMCkgc3JjbGVuID0gc3RybGVuVyhzcmMpOwoKICAgICAgICBUUkFDRSgiKDB4JTA0eCwweCUwOHgsJXMsJWQsJXAsJWQpXG4iLAogICAgICAgICAgICAgIGxjaWQsIGZsYWdzLCBkZWJ1Z3N0cl93bihzcmMsIHNyY2xlbiksIHNyY2xlbiwgZHN0LCBkc3RsZW4pOwoKICAgICAgICByZXR1cm4gd2luZV9nZXRfc29ydGtleShmbGFncywgc3JjLCBzcmNsZW4sIChjaGFyICopZHN0LCBkc3RsZW4pOwogICAgfQoKICAgIC8qIFNPUlRfU1RSSU5HU09SVCBtdXN0IGJlIHVzZWQgZXhjbHVzaXZlbHkgd2l0aCBMQ01BUF9TT1JUS0VZICovCiAgICBpZiAoZmxhZ3MgJiBTT1JUX1NUUklOR1NPUlQpCiAgICB7CiAgICAgICAgU2V0TGFzdEVycm9yKEVSUk9SX0lOVkFMSURfRkxBR1MpOwogICAgICAgIHJldHVybiAwOwogICAgfQoKICAgIGlmIChzcmNsZW4gPCAwKSBzcmNsZW4gPSBzdHJsZW5XKHNyYykgKyAxOwoKICAgIFRSQUNFKCIoMHglMDR4LDB4JTA4eCwlcywlZCwlcCwlZClcbiIsCiAgICAgICAgICBsY2lkLCBmbGFncywgZGVidWdzdHJfd24oc3JjLCBzcmNsZW4pLCBzcmNsZW4sIGRzdCwgZHN0bGVuKTsKCiAgICBpZiAoIWRzdCkgLyogcmV0dXJuIHJlcXVpcmVkIHN0cmluZyBsZW5ndGggKi8KICAgIHsKICAgICAgICBJTlQgbGVuOwoKICAgICAgICBmb3IgKGxlbiA9IDA7IHNyY2xlbjsgc3JjKyssIHNyY2xlbi0tKQogICAgICAgIHsKICAgICAgICAgICAgV0NIQVIgd2NoID0gKnNyYzsKICAgICAgICAgICAgLyogdGVzdHMgc2hvdyB0aGF0IHdpbjJrIGp1c3QgaWdub3JlcyBOT1JNX0lHTk9SRU5PTlNQQUNFLAogICAgICAgICAgICAgKiBhbmQgc2tpcHMgd2hpdGUgc3BhY2UgYW5kIHB1bmN0dWF0aW9uIGNoYXJhY3RlcnMgZm9yCiAgICAgICAgICAgICAqIE5PUk1fSUdOT1JFU1lNQk9MUy4KICAgICAgICAgICAgICovCiAgICAgICAgICAgIGlmICgoZmxhZ3MgJiBOT1JNX0lHTk9SRVNZTUJPTFMpICYmIChnZXRfY2hhcl90eXBlVyh3Y2gpICYgKEMxX1BVTkNUIHwgQzFfU1BBQ0UpKSkKICAgICAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgICBsZW4rKzsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGxlbjsKICAgIH0KCiAgICBpZiAoZmxhZ3MgJiBMQ01BUF9VUFBFUkNBU0UpCiAgICB7CiAgICAgICAgZm9yIChkc3RfcHRyID0gZHN0OyBzcmNsZW4gJiYgZHN0bGVuOyBzcmMrKywgc3JjbGVuLS0pCiAgICAgICAgewogICAgICAgICAgICBXQ0hBUiB3Y2ggPSAqc3JjOwogICAgICAgICAgICBpZiAoKGZsYWdzICYgTk9STV9JR05PUkVTWU1CT0xTKSAmJiAoZ2V0X2NoYXJfdHlwZVcod2NoKSAmIChDMV9QVU5DVCB8IEMxX1NQQUNFKSkpCiAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgKmRzdF9wdHIrKyA9IHRvdXBwZXJXKHdjaCk7CiAgICAgICAgICAgIGRzdGxlbi0tOwogICAgICAgIH0KICAgIH0KICAgIGVsc2UgaWYgKGZsYWdzICYgTENNQVBfTE9XRVJDQVNFKQogICAgewogICAgICAgIGZvciAoZHN0X3B0ciA9IGRzdDsgc3JjbGVuICYmIGRzdGxlbjsgc3JjKyssIHNyY2xlbi0tKQogICAgICAgIHsKICAgICAgICAgICAgV0NIQVIgd2NoID0gKnNyYzsKICAgICAgICAgICAgaWYgKChmbGFncyAmIE5PUk1fSUdOT1JFU1lNQk9MUykgJiYgKGdldF9jaGFyX3R5cGVXKHdjaCkgJiAoQzFfUFVOQ1QgfCBDMV9TUEFDRSkpKQogICAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgICpkc3RfcHRyKysgPSB0b2xvd2VyVyh3Y2gpOwogICAgICAgICAgICBkc3RsZW4tLTsKICAgICAgICB9CiAgICB9CiAgICBlbHNlCiAgICB7CiAgICAgICAgaWYgKHNyYyA9PSBkc3QpCiAgICAgICAgewogICAgICAgICAgICBTZXRMYXN0RXJyb3IoRVJST1JfSU5WQUxJRF9GTEFHUyk7CiAgICAgICAgICAgIHJldHVybiAwOwogICAgICAgIH0KICAgICAgICBmb3IgKGRzdF9wdHIgPSBkc3Q7IHNyY2xlbiAmJiBkc3RsZW47IHNyYysrLCBzcmNsZW4tLSkKICAgICAgICB7CiAgICAgICAgICAgIFdDSEFSIHdjaCA9ICpzcmM7CiAgICAgICAgICAgIGlmICgoZmxhZ3MgJiBOT1JNX0lHTk9SRVNZTUJPTFMpICYmIChnZXRfY2hhcl90eXBlVyh3Y2gpICYgKEMxX1BVTkNUIHwgQzFfU1BBQ0UpKSkKICAgICAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgICAqZHN0X3B0cisrID0gd2NoOwogICAgICAgICAgICBkc3RsZW4tLTsKICAgICAgICB9CiAgICB9CgogICAgaWYgKHNyY2xlbikKICAgIHsKICAgICAgICBTZXRMYXN0RXJyb3IoRVJST1JfSU5TVUZGSUNJRU5UX0JVRkZFUik7CiAgICAgICAgcmV0dXJuIDA7CiAgICB9CgogICAgcmV0dXJuIGRzdF9wdHIgLSBkc3Q7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgICAgICBMQ01hcFN0cmluZ0EgICAgKEtFUk5FTDMyLkApCiAqCiAqIE1hcCBjaGFyYWN0ZXJzIGluIGEgbG9jYWxlIHNlbnNpdGl2ZSBzdHJpbmcuCiAqCiAqIFBBUkFNUwogKiAgbGNpZCAgIFtJXSBMQ0lEIGZvciB0aGUgY29udmVyc2lvbi4KICogIGZsYWdzICBbSV0gRmxhZ3MgY29udHJvbGxpbmcgdGhlIG1hcHBpbmcgKExDTUFQXyBjb25zdGFudHMgZnJvbSAid2lubmxzLmgiKS4KICogIHNyYyAgICBbSV0gU3RyaW5nIHRvIG1hcAogKiAgc3JjbGVuIFtJXSBMZW5ndGggb2Ygc3JjIGluIGNoYXJzLCBvciAtMSBpZiBzcmMgaXMgTlVMIHRlcm1pbmF0ZWQKICogIGRzdCAgICBbT10gRGVzdGluYXRpb24gZm9yIG1hcHBlZCBzdHJpbmcKICogIGRzdGxlbiBbSV0gTGVuZ3RoIG9mIGRzdCBpbiBjaGFyYWN0ZXJzCiAqCiAqIFJFVFVSTlMKICogIFN1Y2Nlc3M6IFRoZSBsZW5ndGggb2YgdGhlIG1hcHBlZCBzdHJpbmcgaW4gZHN0LCBpbmNsdWRpbmcgdGhlIE5VTCB0ZXJtaW5hdG9yLgogKiAgRmFpbHVyZTogMC4gVXNlIEdldExhc3RFcnJvcigpIHRvIGRldGVybWluZSB0aGUgY2F1c2UuCiAqLwpJTlQgV0lOQVBJIExDTWFwU3RyaW5nQShMQ0lEIGxjaWQsIERXT1JEIGZsYWdzLCBMUENTVFIgc3JjLCBJTlQgc3JjbGVuLAogICAgICAgICAgICAgICAgICAgICAgICBMUFNUUiBkc3QsIElOVCBkc3RsZW4pCnsKICAgIFdDSEFSICpidWZXID0gTnRDdXJyZW50VGViKCktPlN0YXRpY1VuaWNvZGVCdWZmZXI7CiAgICBMUFdTVFIgc3JjVywgZHN0VzsKICAgIElOVCByZXQgPSAwLCBzcmNsZW5XLCBkc3RsZW5XOwogICAgVUlOVCBsb2NhbGVfY3AgPSBDUF9BQ1A7CgogICAgaWYgKCFzcmMgfHwgIXNyY2xlbiB8fCBkc3RsZW4gPCAwKQogICAgewogICAgICAgIFNldExhc3RFcnJvcihFUlJPUl9JTlZBTElEX1BBUkFNRVRFUik7CiAgICAgICAgcmV0dXJuIDA7CiAgICB9CgogICAgaWYgKCEoZmxhZ3MgJiBMT0NBTEVfVVNFX0NQX0FDUCkpIGxvY2FsZV9jcCA9IGdldF9sY2lkX2NvZGVwYWdlKCBsY2lkICk7CgogICAgc3JjbGVuVyA9IE11bHRpQnl0ZVRvV2lkZUNoYXIobG9jYWxlX2NwLCAwLCBzcmMsIHNyY2xlbiwgYnVmVywgMjYwKTsKICAgIGlmIChzcmNsZW5XKQogICAgICAgIHNyY1cgPSBidWZXOwogICAgZWxzZQogICAgewogICAgICAgIHNyY2xlblcgPSBNdWx0aUJ5dGVUb1dpZGVDaGFyKGxvY2FsZV9jcCwgMCwgc3JjLCBzcmNsZW4sIE5VTEwsIDApOwogICAgICAgIHNyY1cgPSBIZWFwQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgc3JjbGVuVyAqIHNpemVvZihXQ0hBUikpOwogICAgICAgIGlmICghc3JjVykKICAgICAgICB7CiAgICAgICAgICAgIFNldExhc3RFcnJvcihFUlJPUl9OT1RfRU5PVUdIX01FTU9SWSk7CiAgICAgICAgICAgIHJldHVybiAwOwogICAgICAgIH0KICAgICAgICBNdWx0aUJ5dGVUb1dpZGVDaGFyKGxvY2FsZV9jcCwgMCwgc3JjLCBzcmNsZW4sIHNyY1csIHNyY2xlblcpOwogICAgfQoKICAgIGlmIChmbGFncyAmIExDTUFQX1NPUlRLRVkpCiAgICB7CiAgICAgICAgaWYgKHNyYyA9PSBkc3QpCiAgICAgICAgewogICAgICAgICAgICBTZXRMYXN0RXJyb3IoRVJST1JfSU5WQUxJRF9GTEFHUyk7CiAgICAgICAgICAgIGdvdG8gbWFwX3N0cmluZ19leGl0OwogICAgICAgIH0KICAgICAgICByZXQgPSB3aW5lX2dldF9zb3J0a2V5KGZsYWdzLCBzcmNXLCBzcmNsZW5XLCBkc3QsIGRzdGxlbik7CiAgICAgICAgZ290byBtYXBfc3RyaW5nX2V4aXQ7CiAgICB9CgogICAgaWYgKGZsYWdzICYgU09SVF9TVFJJTkdTT1JUKQogICAgewogICAgICAgIFNldExhc3RFcnJvcihFUlJPUl9JTlZBTElEX0ZMQUdTKTsKICAgICAgICBnb3RvIG1hcF9zdHJpbmdfZXhpdDsKICAgIH0KCiAgICBkc3RsZW5XID0gTENNYXBTdHJpbmdXKGxjaWQsIGZsYWdzLCBzcmNXLCBzcmNsZW5XLCBOVUxMLCAwKTsKICAgIGlmICghZHN0bGVuVykKICAgICAgICBnb3RvIG1hcF9zdHJpbmdfZXhpdDsKCiAgICBkc3RXID0gSGVhcEFsbG9jKEdldFByb2Nlc3NIZWFwKCksIDAsIGRzdGxlblcgKiBzaXplb2YoV0NIQVIpKTsKICAgIGlmICghZHN0VykKICAgIHsKICAgICAgICBTZXRMYXN0RXJyb3IoRVJST1JfTk9UX0VOT1VHSF9NRU1PUlkpOwogICAgICAgIGdvdG8gbWFwX3N0cmluZ19leGl0OwogICAgfQoKICAgIExDTWFwU3RyaW5nVyhsY2lkLCBmbGFncywgc3JjVywgc3JjbGVuVywgZHN0VywgZHN0bGVuVyk7CiAgICByZXQgPSBXaWRlQ2hhclRvTXVsdGlCeXRlKGxvY2FsZV9jcCwgMCwgZHN0VywgZHN0bGVuVywgZHN0LCBkc3RsZW4sIE5VTEwsIE5VTEwpOwogICAgSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgZHN0Vyk7CgptYXBfc3RyaW5nX2V4aXQ6CiAgICBpZiAoc3JjVyAhPSBidWZXKSBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLCAwLCBzcmNXKTsKICAgIHJldHVybiByZXQ7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgICAgICBGb2xkU3RyaW5nQSAgICAoS0VSTkVMMzIuQCkKICoKICogTWFwIGNoYXJhY3RlcnMgaW4gYSBzdHJpbmcuCiAqCiAqIFBBUkFNUwogKiAgZHdGbGFncyBbSV0gRmxhZ3MgY29udHJvbGxpbmcgY2hhcnMgdG8gbWFwIChNQVBfIGNvbnN0YW50cyBmcm9tICJ3aW5ubHMuaCIpCiAqICBzcmMgICAgIFtJXSBTdHJpbmcgdG8gbWFwCiAqICBzcmNsZW4gIFtJXSBMZW5ndGggb2Ygc3JjLCBvciAtMSBpZiBzcmMgaXMgTlVMIHRlcm1pbmF0ZWQKICogIGRzdCAgICAgW09dIERlc3RpbmF0aW9uIGZvciBtYXBwZWQgc3RyaW5nCiAqICBkc3RsZW4gIFtJXSBMZW5ndGggb2YgZHN0LCBvciAwIHRvIGZpbmQgdGhlIHJlcXVpcmVkIGxlbmd0aCBmb3IgdGhlIG1hcHBlZCBzdHJpbmcKICoKICogUkVUVVJOUwogKiAgU3VjY2VzczogVGhlIGxlbmd0aCBvZiB0aGUgc3RyaW5nIHdyaXR0ZW4gdG8gZHN0LCBpbmNsdWRpbmcgdGhlIHRlcm1pbmF0aW5nIE5VTC4gSWYKICogICAgICAgICAgIGRzdGxlbiBpcyAwLCB0aGUgdmFsdWUgcmV0dXJuZWQgaXMgdGhlIHNhbWUsIGJ1dCBub3RoaW5nIGlzIHdyaXR0ZW4gdG8gZHN0LAogKiAgICAgICAgICAgYW5kIGRzdCBtYXkgYmUgTlVMTC4KICogIEZhaWx1cmU6IDAuIFVzZSBHZXRMYXN0RXJyb3IoKSB0byBkZXRlcm1pbmUgdGhlIGNhdXNlLgogKi8KSU5UIFdJTkFQSSBGb2xkU3RyaW5nQShEV09SRCBkd0ZsYWdzLCBMUENTVFIgc3JjLCBJTlQgc3JjbGVuLAogICAgICAgICAgICAgICAgICAgICAgIExQU1RSIGRzdCwgSU5UIGRzdGxlbikKewogICAgSU5UIHJldCA9IDAsIHNyY2xlblcgPSAwOwogICAgV0NIQVIgKnNyY1cgPSBOVUxMLCAqZHN0VyA9IE5VTEw7CgogICAgaWYgKCFzcmMgfHwgIXNyY2xlbiB8fCBkc3RsZW4gPCAwIHx8IChkc3RsZW4gJiYgIWRzdCkgfHwgc3JjID09IGRzdCkKICAgIHsKICAgICAgICBTZXRMYXN0RXJyb3IoRVJST1JfSU5WQUxJRF9QQVJBTUVURVIpOwogICAgICAgIHJldHVybiAwOwogICAgfQoKICAgIHNyY2xlblcgPSBNdWx0aUJ5dGVUb1dpZGVDaGFyKENQX0FDUCwgZHdGbGFncyAmIE1BUF9DT01QT1NJVEUgPyBNQl9DT01QT1NJVEUgOiAwLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3JjLCBzcmNsZW4sIE5VTEwsIDApOwogICAgc3JjVyA9IEhlYXBBbGxvYyhHZXRQcm9jZXNzSGVhcCgpLCAwLCBzcmNsZW5XICogc2l6ZW9mKFdDSEFSKSk7CgogICAgaWYgKCFzcmNXKQogICAgewogICAgICAgIFNldExhc3RFcnJvcihFUlJPUl9OT1RfRU5PVUdIX01FTU9SWSk7CiAgICAgICAgZ290byBGb2xkU3RyaW5nQV9leGl0OwogICAgfQoKICAgIE11bHRpQnl0ZVRvV2lkZUNoYXIoQ1BfQUNQLCBkd0ZsYWdzICYgTUFQX0NPTVBPU0lURSA/IE1CX0NPTVBPU0lURSA6IDAsCiAgICAgICAgICAgICAgICAgICAgICAgIHNyYywgc3JjbGVuLCBzcmNXLCBzcmNsZW5XKTsKCiAgICBkd0ZsYWdzID0gKGR3RmxhZ3MgJiB+TUFQX1BSRUNPTVBPU0VEKSB8IE1BUF9GT0xEQ1pPTkU7CgogICAgcmV0ID0gRm9sZFN0cmluZ1coZHdGbGFncywgc3JjVywgc3JjbGVuVywgTlVMTCwgMCk7CiAgICBpZiAocmV0ICYmIGRzdGxlbikKICAgIHsKICAgICAgICBkc3RXID0gSGVhcEFsbG9jKEdldFByb2Nlc3NIZWFwKCksIDAsIHJldCAqIHNpemVvZihXQ0hBUikpOwoKICAgICAgICBpZiAoIWRzdFcpCiAgICAgICAgewogICAgICAgICAgICBTZXRMYXN0RXJyb3IoRVJST1JfTk9UX0VOT1VHSF9NRU1PUlkpOwogICAgICAgICAgICBnb3RvIEZvbGRTdHJpbmdBX2V4aXQ7CiAgICAgICAgfQoKICAgICAgICByZXQgPSBGb2xkU3RyaW5nVyhkd0ZsYWdzLCBzcmNXLCBzcmNsZW5XLCBkc3RXLCByZXQpOwogICAgICAgIGlmICghV2lkZUNoYXJUb011bHRpQnl0ZShDUF9BQ1AsIDAsIGRzdFcsIHJldCwgZHN0LCBkc3RsZW4sIE5VTEwsIE5VTEwpKQogICAgICAgIHsKICAgICAgICAgICAgcmV0ID0gMDsKICAgICAgICAgICAgU2V0TGFzdEVycm9yKEVSUk9SX0lOU1VGRklDSUVOVF9CVUZGRVIpOwogICAgICAgIH0KICAgIH0KCiAgICBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLCAwLCBkc3RXKTsKCkZvbGRTdHJpbmdBX2V4aXQ6CiAgICBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLCAwLCBzcmNXKTsKICAgIHJldHVybiByZXQ7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgICAgICBGb2xkU3RyaW5nVyAgICAoS0VSTkVMMzIuQCkKICoKICogU2VlIEZvbGRTdHJpbmdBLgogKi8KSU5UIFdJTkFQSSBGb2xkU3RyaW5nVyhEV09SRCBkd0ZsYWdzLCBMUENXU1RSIHNyYywgSU5UIHNyY2xlbiwKICAgICAgICAgICAgICAgICAgICAgICBMUFdTVFIgZHN0LCBJTlQgZHN0bGVuKQp7CiAgICBpbnQgcmV0OwoKICAgIHN3aXRjaCAoZHdGbGFncyAmIChNQVBfQ09NUE9TSVRFfE1BUF9QUkVDT01QT1NFRHxNQVBfRVhQQU5EX0xJR0FUVVJFUykpCiAgICB7CiAgICBjYXNlIDA6CiAgICAgICAgaWYgKGR3RmxhZ3MpCiAgICAgICAgICBicmVhazsKICAgICAgICAvKiBGYWxsIHRocm91Z2ggZm9yIGR3RmxhZ3MgPT0gMCAqLwogICAgY2FzZSBNQVBfUFJFQ09NUE9TRUR8TUFQX0NPTVBPU0lURToKICAgIGNhc2UgTUFQX1BSRUNPTVBPU0VEfE1BUF9FWFBBTkRfTElHQVRVUkVTOgogICAgY2FzZSBNQVBfQ09NUE9TSVRFfE1BUF9FWFBBTkRfTElHQVRVUkVTOgogICAgICAgIFNldExhc3RFcnJvcihFUlJPUl9JTlZBTElEX0ZMQUdTKTsKICAgICAgICByZXR1cm4gMDsKICAgIH0KCiAgICBpZiAoIXNyYyB8fCAhc3JjbGVuIHx8IGRzdGxlbiA8IDAgfHwgKGRzdGxlbiAmJiAhZHN0KSB8fCBzcmMgPT0gZHN0KQogICAgewogICAgICAgIFNldExhc3RFcnJvcihFUlJPUl9JTlZBTElEX1BBUkFNRVRFUik7CiAgICAgICAgcmV0dXJuIDA7CiAgICB9CgogICAgcmV0ID0gd2luZV9mb2xkX3N0cmluZyhkd0ZsYWdzLCBzcmMsIHNyY2xlbiwgZHN0LCBkc3RsZW4pOwogICAgaWYgKCFyZXQpCiAgICAgICAgU2V0TGFzdEVycm9yKEVSUk9SX0lOU1VGRklDSUVOVF9CVUZGRVIpOwogICAgcmV0dXJuIHJldDsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgICAgICAgQ29tcGFyZVN0cmluZ1cgICAgKEtFUk5FTDMyLkApCiAqCiAqIFNlZSBDb21wYXJlU3RyaW5nQS4KICovCklOVCBXSU5BUEkgQ29tcGFyZVN0cmluZ1coTENJRCBsY2lkLCBEV09SRCBzdHlsZSwKICAgICAgICAgICAgICAgICAgICAgICAgICBMUENXU1RSIHN0cjEsIElOVCBsZW4xLCBMUENXU1RSIHN0cjIsIElOVCBsZW4yKQp7CiAgICBJTlQgcmV0OwoKICAgIGlmICghc3RyMSB8fCAhc3RyMikKICAgIHsKICAgICAgICBTZXRMYXN0RXJyb3IoRVJST1JfSU5WQUxJRF9QQVJBTUVURVIpOwogICAgICAgIHJldHVybiAwOwogICAgfQoKICAgIGlmKCBzdHlsZSAmIH4oTk9STV9JR05PUkVDQVNFfE5PUk1fSUdOT1JFTk9OU1BBQ0V8Tk9STV9JR05PUkVTWU1CT0xTfAogICAgICAgIFNPUlRfU1RSSU5HU09SVHxOT1JNX0lHTk9SRUtBTkFUWVBFfE5PUk1fSUdOT1JFV0lEVEh8TE9DQUxFX1VTRV9DUF9BQ1B8MHgxMDAwMDAwMCkgKQogICAgewogICAgICAgIFNldExhc3RFcnJvcihFUlJPUl9JTlZBTElEX0ZMQUdTKTsKICAgICAgICByZXR1cm4gMDsKICAgIH0KCiAgICAvKiB0aGlzIHN0eWxlIGlzIHJlbGF0ZWQgdG8gZGlhY3JpdGljcyBpbiBBcmFiaWMsIEphcGFuZXNlLCBhbmQgSGVicmV3ICovCiAgICBpZiAoc3R5bGUgJiAweDEwMDAwMDAwKQogICAgICAgIFdBUk4oIklnbm9yaW5nIHVua25vd24gc3R5bGUgMHgxMDAwMDAwMFxuIik7CgogICAgaWYgKGxlbjEgPCAwKSBsZW4xID0gc3RybGVuVyhzdHIxKTsKICAgIGlmIChsZW4yIDwgMCkgbGVuMiA9IHN0cmxlblcoc3RyMik7CgogICAgcmV0ID0gd2luZV9jb21wYXJlX3N0cmluZyhzdHlsZSwgc3RyMSwgbGVuMSwgc3RyMiwgbGVuMik7CgogICAgaWYgKHJldCkgLyogbmVlZCB0byB0cmFuc2xhdGUgcmVzdWx0ICovCiAgICAgICAgcmV0dXJuIChyZXQgPCAwKSA/IENTVFJfTEVTU19USEFOIDogQ1NUUl9HUkVBVEVSX1RIQU47CiAgICByZXR1cm4gQ1NUUl9FUVVBTDsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgICAgICAgQ29tcGFyZVN0cmluZ0EgICAgKEtFUk5FTDMyLkApCiAqCiAqIENvbXBhcmUgdHdvIGxvY2FsZSBzZW5zaXRpdmUgc3RyaW5ncy4KICoKICogUEFSQU1TCiAqICBsY2lkICBbSV0gTENJRCBmb3IgdGhlIGNvbXBhcmlzb24KICogIHN0eWxlIFtJXSBGbGFncyBmb3IgdGhlIGNvbXBhcmlzb24gKE5PUk1fIGNvbnN0YW50cyBmcm9tICJ3aW5ubHMuaCIpLgogKiAgc3RyMSAgW0ldIEZpcnN0IHN0cmluZyB0byBjb21wYXJlCiAqICBsZW4xICBbSV0gTGVuZ3RoIG9mIHN0cjEsIG9yIC0xIGlmIHN0cjEgaXMgTlVMIHRlcm1pbmF0ZWQKICogIHN0cjIgIFtJXSBTZWNvbmQgc3RyaW5nIHRvIGNvbXBhcmUKICogIGxlbjIgIFtJXSBMZW5ndGggb2Ygc3RyMiwgb3IgLTEgaWYgc3RyMiBpcyBOVUwgdGVybWluYXRlZAogKgogKiBSRVRVUk5TCiAqICBTdWNjZXNzOiBDU1RSX0xFU1NfVEhBTiwgQ1NUUl9FUVVBTCBvciBDU1RSX0dSRUFURVJfVEhBTiBkZXBlbmRpbmcgb24gd2hldGhlcgogKiAgICAgICAgICAgc3RyMiBpcyBsZXNzIHRoYW4sIGVxdWFsIHRvIG9yIGdyZWF0ZXIgdGhhbiBzdHIxIHJlc3BlY3RpdmVseS4KICogIEZhaWx1cmU6IEZBTFNFLiBVc2UgR2V0TGFzdEVycm9yKCkgdG8gZGV0ZXJtaW5lIHRoZSBjYXVzZS4KICovCklOVCBXSU5BUEkgQ29tcGFyZVN0cmluZ0EoTENJRCBsY2lkLCBEV09SRCBzdHlsZSwKICAgICAgICAgICAgICAgICAgICAgICAgICBMUENTVFIgc3RyMSwgSU5UIGxlbjEsIExQQ1NUUiBzdHIyLCBJTlQgbGVuMikKewogICAgV0NIQVIgKmJ1ZjFXID0gTnRDdXJyZW50VGViKCktPlN0YXRpY1VuaWNvZGVCdWZmZXI7CiAgICBXQ0hBUiAqYnVmMlcgPSBidWYxVyArIDEzMDsKICAgIExQV1NUUiBzdHIxVywgc3RyMlc7CiAgICBJTlQgbGVuMVcsIGxlbjJXLCByZXQ7CiAgICBVSU5UIGxvY2FsZV9jcCA9IENQX0FDUDsKCiAgICBpZiAoIXN0cjEgfHwgIXN0cjIpCiAgICB7CiAgICAgICAgU2V0TGFzdEVycm9yKEVSUk9SX0lOVkFMSURfUEFSQU1FVEVSKTsKICAgICAgICByZXR1cm4gMDsKICAgIH0KICAgIGlmIChsZW4xIDwgMCkgbGVuMSA9IHN0cmxlbihzdHIxKTsKICAgIGlmIChsZW4yIDwgMCkgbGVuMiA9IHN0cmxlbihzdHIyKTsKCiAgICBpZiAoIShzdHlsZSAmIExPQ0FMRV9VU0VfQ1BfQUNQKSkgbG9jYWxlX2NwID0gZ2V0X2xjaWRfY29kZXBhZ2UoIGxjaWQgKTsKCiAgICBsZW4xVyA9IE11bHRpQnl0ZVRvV2lkZUNoYXIobG9jYWxlX2NwLCAwLCBzdHIxLCBsZW4xLCBidWYxVywgMTMwKTsKICAgIGlmIChsZW4xVykKICAgICAgICBzdHIxVyA9IGJ1ZjFXOwogICAgZWxzZQogICAgewogICAgICAgIGxlbjFXID0gTXVsdGlCeXRlVG9XaWRlQ2hhcihsb2NhbGVfY3AsIDAsIHN0cjEsIGxlbjEsIE5VTEwsIDApOwogICAgICAgIHN0cjFXID0gSGVhcEFsbG9jKEdldFByb2Nlc3NIZWFwKCksIDAsIGxlbjFXICogc2l6ZW9mKFdDSEFSKSk7CiAgICAgICAgaWYgKCFzdHIxVykKICAgICAgICB7CiAgICAgICAgICAgIFNldExhc3RFcnJvcihFUlJPUl9OT1RfRU5PVUdIX01FTU9SWSk7CiAgICAgICAgICAgIHJldHVybiAwOwogICAgICAgIH0KICAgICAgICBNdWx0aUJ5dGVUb1dpZGVDaGFyKGxvY2FsZV9jcCwgMCwgc3RyMSwgbGVuMSwgc3RyMVcsIGxlbjFXKTsKICAgIH0KICAgIGxlbjJXID0gTXVsdGlCeXRlVG9XaWRlQ2hhcihsb2NhbGVfY3AsIDAsIHN0cjIsIGxlbjIsIGJ1ZjJXLCAxMzApOwogICAgaWYgKGxlbjJXKQogICAgICAgIHN0cjJXID0gYnVmMlc7CiAgICBlbHNlCiAgICB7CiAgICAgICAgbGVuMlcgPSBNdWx0aUJ5dGVUb1dpZGVDaGFyKGxvY2FsZV9jcCwgMCwgc3RyMiwgbGVuMiwgTlVMTCwgMCk7CiAgICAgICAgc3RyMlcgPSBIZWFwQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgbGVuMlcgKiBzaXplb2YoV0NIQVIpKTsKICAgICAgICBpZiAoIXN0cjJXKQogICAgICAgIHsKICAgICAgICAgICAgaWYgKHN0cjFXICE9IGJ1ZjFXKSBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLCAwLCBzdHIxVyk7CiAgICAgICAgICAgIFNldExhc3RFcnJvcihFUlJPUl9OT1RfRU5PVUdIX01FTU9SWSk7CiAgICAgICAgICAgIHJldHVybiAwOwogICAgICAgIH0KICAgICAgICBNdWx0aUJ5dGVUb1dpZGVDaGFyKGxvY2FsZV9jcCwgMCwgc3RyMiwgbGVuMiwgc3RyMlcsIGxlbjJXKTsKICAgIH0KCiAgICByZXQgPSBDb21wYXJlU3RyaW5nVyhsY2lkLCBzdHlsZSwgc3RyMVcsIGxlbjFXLCBzdHIyVywgbGVuMlcpOwoKICAgIGlmIChzdHIxVyAhPSBidWYxVykgSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgc3RyMVcpOwogICAgaWYgKHN0cjJXICE9IGJ1ZjJXKSBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLCAwLCBzdHIyVyk7CiAgICByZXR1cm4gcmV0Owp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgICAgICAgbHN0cmNtcCAgICAgKEtFUk5FTDMyLkApCiAqICAgICAgICAgICBsc3RyY21wQSAgICAoS0VSTkVMMzIuQCkKICoKICogQ29tcGFyZSB0d28gc3RyaW5ncyB1c2luZyB0aGUgY3VycmVudCB0aHJlYWQgbG9jYWxlLgogKgogKiBQQVJBTVMKICogIHN0cjEgIFtJXSBGaXJzdCBzdHJpbmcgdG8gY29tcGFyZQogKiAgc3RyMiAgW0ldIFNlY29uZCBzdHJpbmcgdG8gY29tcGFyZQogKgogKiBSRVRVUk5TCiAqICBTdWNjZXNzOiBBIG51bWJlciBsZXNzIHRoYW4sIGVxdWFsIHRvIG9yIGdyZWF0ZXIgdGhhbiAwIGRlcGVuZGluZyBvbiB3aGV0aGVyCiAqICAgICAgICAgICBzdHIyIGlzIGxlc3MgdGhhbiwgZXF1YWwgdG8gb3IgZ3JlYXRlciB0aGFuIHN0cjEgcmVzcGVjdGl2ZWx5LgogKiAgRmFpbHVyZTogRkFMU0UuIFVzZSBHZXRMYXN0RXJyb3IoKSB0byBkZXRlcm1pbmUgdGhlIGNhdXNlLgogKi8KaW50IFdJTkFQSSBsc3RyY21wQShMUENTVFIgc3RyMSwgTFBDU1RSIHN0cjIpCnsKICAgIGludCByZXQ7CiAgICAKICAgIGlmICgoc3RyMSA9PSBOVUxMKSAmJiAoc3RyMiA9PSBOVUxMKSkgcmV0dXJuIDA7CiAgICBpZiAoc3RyMSA9PSBOVUxMKSByZXR1cm4gLTE7CiAgICBpZiAoc3RyMiA9PSBOVUxMKSByZXR1cm4gMTsKCiAgICByZXQgPSBDb21wYXJlU3RyaW5nQShHZXRUaHJlYWRMb2NhbGUoKSwgTE9DQUxFX1VTRV9DUF9BQ1AsIHN0cjEsIC0xLCBzdHIyLCAtMSk7CiAgICBpZiAocmV0KSByZXQgLT0gMjsKICAgIAogICAgcmV0dXJuIHJldDsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICAgICAgIGxzdHJjbXBpICAgICAoS0VSTkVMMzIuQCkKICogICAgICAgICAgIGxzdHJjbXBpQSAgICAoS0VSTkVMMzIuQCkKICoKICogQ29tcGFyZSB0d28gc3RyaW5ncyB1c2luZyB0aGUgY3VycmVudCB0aHJlYWQgbG9jYWxlLCBpZ25vcmluZyBjYXNlLgogKgogKiBQQVJBTVMKICogIHN0cjEgIFtJXSBGaXJzdCBzdHJpbmcgdG8gY29tcGFyZQogKiAgc3RyMiAgW0ldIFNlY29uZCBzdHJpbmcgdG8gY29tcGFyZQogKgogKiBSRVRVUk5TCiAqICBTdWNjZXNzOiBBIG51bWJlciBsZXNzIHRoYW4sIGVxdWFsIHRvIG9yIGdyZWF0ZXIgdGhhbiAwIGRlcGVuZGluZyBvbiB3aGV0aGVyCiAqICAgICAgICAgICBzdHIyIGlzIGxlc3MgdGhhbiwgZXF1YWwgdG8gb3IgZ3JlYXRlciB0aGFuIHN0cjEgcmVzcGVjdGl2ZWx5LgogKiAgRmFpbHVyZTogRkFMU0UuIFVzZSBHZXRMYXN0RXJyb3IoKSB0byBkZXRlcm1pbmUgdGhlIGNhdXNlLgogKi8KaW50IFdJTkFQSSBsc3RyY21waUEoTFBDU1RSIHN0cjEsIExQQ1NUUiBzdHIyKQp7CiAgICBpbnQgcmV0OwogICAgCiAgICBpZiAoKHN0cjEgPT0gTlVMTCkgJiYgKHN0cjIgPT0gTlVMTCkpIHJldHVybiAwOwogICAgaWYgKHN0cjEgPT0gTlVMTCkgcmV0dXJuIC0xOwogICAgaWYgKHN0cjIgPT0gTlVMTCkgcmV0dXJuIDE7CgogICAgcmV0ID0gQ29tcGFyZVN0cmluZ0EoR2V0VGhyZWFkTG9jYWxlKCksIE5PUk1fSUdOT1JFQ0FTRXxMT0NBTEVfVVNFX0NQX0FDUCwgc3RyMSwgLTEsIHN0cjIsIC0xKTsKICAgIGlmIChyZXQpIHJldCAtPSAyOwogICAgCiAgICByZXR1cm4gcmV0Owp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgICAgICAgbHN0cmNtcFcgICAgKEtFUk5FTDMyLkApCiAqCiAqIFNlZSBsc3RyY21wQS4KICovCmludCBXSU5BUEkgbHN0cmNtcFcoTFBDV1NUUiBzdHIxLCBMUENXU1RSIHN0cjIpCnsKICAgIGludCByZXQ7CgogICAgaWYgKChzdHIxID09IE5VTEwpICYmIChzdHIyID09IE5VTEwpKSByZXR1cm4gMDsKICAgIGlmIChzdHIxID09IE5VTEwpIHJldHVybiAtMTsKICAgIGlmIChzdHIyID09IE5VTEwpIHJldHVybiAxOwoKICAgIHJldCA9IENvbXBhcmVTdHJpbmdXKEdldFRocmVhZExvY2FsZSgpLCAwLCBzdHIxLCAtMSwgc3RyMiwgLTEpOwogICAgaWYgKHJldCkgcmV0IC09IDI7CiAgICAKICAgIHJldHVybiByZXQ7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgICAgICBsc3RyY21waVcgICAgKEtFUk5FTDMyLkApCiAqCiAqIFNlZSBsc3RyY21waUEuCiAqLwppbnQgV0lOQVBJIGxzdHJjbXBpVyhMUENXU1RSIHN0cjEsIExQQ1dTVFIgc3RyMikKewogICAgaW50IHJldDsKICAgIAogICAgaWYgKChzdHIxID09IE5VTEwpICYmIChzdHIyID09IE5VTEwpKSByZXR1cm4gMDsKICAgIGlmIChzdHIxID09IE5VTEwpIHJldHVybiAtMTsKICAgIGlmIChzdHIyID09IE5VTEwpIHJldHVybiAxOwoKICAgIHJldCA9IENvbXBhcmVTdHJpbmdXKEdldFRocmVhZExvY2FsZSgpLCBOT1JNX0lHTk9SRUNBU0UsIHN0cjEsIC0xLCBzdHIyLCAtMSk7CiAgICBpZiAocmV0KSByZXQgLT0gMjsKICAgIAogICAgcmV0dXJuIHJldDsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJTE9DQUxFX0luaXQKICovCnZvaWQgTE9DQUxFX0luaXQodm9pZCkKewogICAgZXh0ZXJuIHZvaWQgX193aW5lX2luaXRfY29kZXBhZ2VzKCBjb25zdCB1bmlvbiBjcHRhYmxlICphbnNpX2NwLCBjb25zdCB1bmlvbiBjcHRhYmxlICpvZW1fY3AsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHVuaW9uIGNwdGFibGUgKnVuaXhfY3AgKTsKCiAgICBVSU5UIGFuc2lfY3AgPSAxMjUyLCBvZW1fY3AgPSA0MzcsIG1hY19jcCA9IDEwMDAwLCB1bml4X2NwOwoKI2lmZGVmIF9fQVBQTEVfXwogICAgLyogTWFjT1MgZG9lc24ndCBzZXQgdGhlIGxvY2FsZSBlbnZpcm9ubWVudCB2YXJpYWJsZXMgc28gd2UgaGF2ZSB0byBkbyBpdCBvdXJzZWx2ZXMgKi8KICAgIENGQXJyYXlSZWYgcHJlZmVycmVkX2xvY2FsZXMsIGFsbF9sb2NhbGVzOwogICAgQ0ZTdHJpbmdSZWYgdXNlcl9sYW5ndWFnZV9zdHJpbmdfcmVmID0gTlVMTDsKICAgIGNoYXIgdXNlcl9sb2NhbGVbNTBdOwoKICAgIENGTG9jYWxlUmVmIHVzZXJfbG9jYWxlX3JlZiA9IENGTG9jYWxlQ29weUN1cnJlbnQoKTsKICAgIENGU3RyaW5nUmVmIHVzZXJfbG9jYWxlX3N0cmluZ19yZWYgPSBDRkxvY2FsZUdldElkZW50aWZpZXIoIHVzZXJfbG9jYWxlX3JlZiApOwoKICAgIENGU3RyaW5nR2V0Q1N0cmluZyggdXNlcl9sb2NhbGVfc3RyaW5nX3JlZiwgdXNlcl9sb2NhbGUsIHNpemVvZih1c2VyX2xvY2FsZSksIGtDRlN0cmluZ0VuY29kaW5nVVRGOCApOwogICAgQ0ZSZWxlYXNlKCB1c2VyX2xvY2FsZV9yZWYgKTsKICAgIGlmICghc3RyY2hyKCB1c2VyX2xvY2FsZSwgJy4nICkpIHN0cmNhdCggdXNlcl9sb2NhbGUsICIuVVRGLTgiICk7CiAgICB1bml4X2NwID0gQ1BfVVRGODsgIC8qIGRlZmF1bHQgdG8gdXRmLTggZXZlbiBpZiB3ZSBkb24ndCBnZXQgYSB2YWxpZCBsb2NhbGUgKi8KICAgIHNldGVudiggIkxBTkciLCB1c2VyX2xvY2FsZSwgMCApOwogICAgVFJBQ0UoICJzZXR0aW5nIGxvY2FsZSB0byAnJXMnXG4iLCB1c2VyX2xvY2FsZSApOwoKICAgIC8qIFdlIHN0aWxsIHdhbnQgdG8gc2V0IHRoZSByZXRyaWV2ZSB0aGUgcHJlZmVycmVkIGxhbmd1YWdlIGFzIGNob3NlbiBpbgogICAgICAgU3lzdGVtIFByZWZlcmVuY2VzLmFwcCwgYmVjYXVzZSBpdCBjYW4gZGlmZmVyIGZyb20gQ0ZMb2NhbGVDb3B5Q3VycmVudCgpLgogICAgKi8KICAgIGFsbF9sb2NhbGVzID0gQ0ZMb2NhbGVDb3B5QXZhaWxhYmxlTG9jYWxlSWRlbnRpZmllcnMoKTsKICAgIHByZWZlcnJlZF9sb2NhbGVzID0gQ0ZCdW5kbGVDb3B5TG9jYWxpemF0aW9uc0ZvclByZWZlcmVuY2VzKCBhbGxfbG9jYWxlcywgTlVMTCApOwogICAgaWYgKHByZWZlcnJlZF9sb2NhbGVzICYmIENGQXJyYXlHZXRDb3VudCggcHJlZmVycmVkX2xvY2FsZXMgKSkKICAgICAgICB1c2VyX2xhbmd1YWdlX3N0cmluZ19yZWYgPSBDRkFycmF5R2V0VmFsdWVBdEluZGV4KCBwcmVmZXJyZWRfbG9jYWxlcywgMCApOwogICAgQ0ZSZWxlYXNlKCBhbGxfbG9jYWxlcyApOwojZW5kaWYgLyogX19BUFBMRV9fICovCgogICAgc2V0bG9jYWxlKCBMQ19BTEwsICIiICk7CgogICAgdW5peF9jcCA9IHNldHVwX3VuaXhfbG9jYWxlcygpOwogICAgaWYgKCFsY2lkX0xDX01FU1NBR0VTKSBsY2lkX0xDX01FU1NBR0VTID0gbGNpZF9MQ19DVFlQRTsKCiNpZmRlZiBfX0FQUExFX18KICAgIC8qIE92ZXJyaWRlIGxjaWRfTENfTUVTU0FHRVMgd2l0aCB1c2VyX2xhbmd1YWdlIGlmIExDX01FU1NBR0VTIGlzIHNldCB0byBkZWZhdWx0ICovCiAgICBpZiAobGNpZF9MQ19NRVNTQUdFUyA9PSBsY2lkX0xDX0NUWVBFICYmIHVzZXJfbGFuZ3VhZ2Vfc3RyaW5nX3JlZikKICAgIHsKICAgICAgICBzdHJ1Y3QgbG9jYWxlX25hbWUgbG9jYWxlX25hbWU7CiAgICAgICAgV0NIQVIgYnVmZmVyWzEyOF07CiAgICAgICAgQ0ZTdHJpbmdHZXRDU3RyaW5nKCB1c2VyX2xhbmd1YWdlX3N0cmluZ19yZWYsIHVzZXJfbG9jYWxlLCBzaXplb2YodXNlcl9sb2NhbGUpLCBrQ0ZTdHJpbmdFbmNvZGluZ1VURjggKTsKICAgICAgICBzdHJjcHluQXRvVyggYnVmZmVyLCB1c2VyX2xvY2FsZSwgc2l6ZW9mKGJ1ZmZlcikvc2l6ZW9mKFdDSEFSKSApOwogICAgICAgIHBhcnNlX2xvY2FsZV9uYW1lKCBidWZmZXIsICZsb2NhbGVfbmFtZSApOwogICAgICAgIGxjaWRfTENfTUVTU0FHRVMgPSBsb2NhbGVfbmFtZS5sY2lkOwogICAgICAgIFRSQUNFKCAic2V0dGluZyBsY2lkX0xDX01FU1NBR0VTIHRvICclcydcbiIsIHVzZXJfbG9jYWxlICk7CiAgICB9CiAgICBpZiAocHJlZmVycmVkX2xvY2FsZXMpCiAgICAgICAgQ0ZSZWxlYXNlKCBwcmVmZXJyZWRfbG9jYWxlcyApOwojZW5kaWYKCiAgICBOdFNldERlZmF1bHRVSUxhbmd1YWdlKCBMQU5HSURGUk9NTENJRChsY2lkX0xDX01FU1NBR0VTKSApOwogICAgTnRTZXREZWZhdWx0TG9jYWxlKCBUUlVFLCBsY2lkX0xDX01FU1NBR0VTICk7CiAgICBOdFNldERlZmF1bHRMb2NhbGUoIEZBTFNFLCBsY2lkX0xDX0NUWVBFICk7CgogICAgYW5zaV9jcCA9IGdldF9sY2lkX2NvZGVwYWdlKCBMT0NBTEVfVVNFUl9ERUZBVUxUICk7CiAgICBHZXRMb2NhbGVJbmZvVyggTE9DQUxFX1VTRVJfREVGQVVMVCwgTE9DQUxFX0lERUZBVUxUTUFDQ09ERVBBR0UgfCBMT0NBTEVfUkVUVVJOX05VTUJFUiwKICAgICAgICAgICAgICAgICAgICAoTFBXU1RSKSZtYWNfY3AsIHNpemVvZihtYWNfY3ApL3NpemVvZihXQ0hBUikgKTsKICAgIEdldExvY2FsZUluZm9XKCBMT0NBTEVfVVNFUl9ERUZBVUxULCBMT0NBTEVfSURFRkFVTFRDT0RFUEFHRSB8IExPQ0FMRV9SRVRVUk5fTlVNQkVSLAogICAgICAgICAgICAgICAgICAgIChMUFdTVFIpJm9lbV9jcCwgc2l6ZW9mKG9lbV9jcCkvc2l6ZW9mKFdDSEFSKSApOwogICAgaWYgKCF1bml4X2NwKQogICAgICAgIEdldExvY2FsZUluZm9XKCBMT0NBTEVfVVNFUl9ERUZBVUxULCBMT0NBTEVfSURFRkFVTFRVTklYQ09ERVBBR0UgfCBMT0NBTEVfUkVUVVJOX05VTUJFUiwKICAgICAgICAgICAgICAgICAgICAgICAgKExQV1NUUikmdW5peF9jcCwgc2l6ZW9mKHVuaXhfY3ApL3NpemVvZihXQ0hBUikgKTsKCiAgICBpZiAoIShhbnNpX2NwdGFibGUgPSB3aW5lX2NwX2dldF90YWJsZSggYW5zaV9jcCApKSkKICAgICAgICBhbnNpX2NwdGFibGUgPSB3aW5lX2NwX2dldF90YWJsZSggMTI1MiApOwogICAgaWYgKCEob2VtX2NwdGFibGUgPSB3aW5lX2NwX2dldF90YWJsZSggb2VtX2NwICkpKQogICAgICAgIG9lbV9jcHRhYmxlICA9IHdpbmVfY3BfZ2V0X3RhYmxlKCA0MzcgKTsKICAgIGlmICghKG1hY19jcHRhYmxlID0gd2luZV9jcF9nZXRfdGFibGUoIG1hY19jcCApKSkKICAgICAgICBtYWNfY3B0YWJsZSAgPSB3aW5lX2NwX2dldF90YWJsZSggMTAwMDAgKTsKICAgIGlmICh1bml4X2NwICE9IENQX1VURjgpCiAgICB7CiAgICAgICAgaWYgKCEodW5peF9jcHRhYmxlID0gd2luZV9jcF9nZXRfdGFibGUoIHVuaXhfY3AgKSkpCiAgICAgICAgICAgIHVuaXhfY3B0YWJsZSAgPSB3aW5lX2NwX2dldF90YWJsZSggMjg1OTEgKTsKICAgIH0KCiAgICBfX3dpbmVfaW5pdF9jb2RlcGFnZXMoIGFuc2lfY3B0YWJsZSwgb2VtX2NwdGFibGUsIHVuaXhfY3B0YWJsZSApOwoKICAgIFRSQUNFKCAiYW5zaT0lMDNkIG9lbT0lMDNkIG1hYz0lMDNkIHVuaXg9JTAzZFxuIiwKICAgICAgICAgICBhbnNpX2NwdGFibGUtPmluZm8uY29kZXBhZ2UsIG9lbV9jcHRhYmxlLT5pbmZvLmNvZGVwYWdlLAogICAgICAgICAgIG1hY19jcHRhYmxlLT5pbmZvLmNvZGVwYWdlLCB1bml4X2NwICk7CgogICAgc2V0bG9jYWxlKExDX05VTUVSSUMsICJDIik7ICAvKiBGSVhNRTogb2xlYXV0MzIgZGVwZW5kcyBvbiB0aGlzICovCn0KCnN0YXRpYyBIQU5ETEUgTkxTX1JlZ09wZW5LZXkoSEFORExFIGhSb290S2V5LCBMUENXU1RSIHN6S2V5TmFtZSkKewogICAgVU5JQ09ERV9TVFJJTkcga2V5TmFtZTsKICAgIE9CSkVDVF9BVFRSSUJVVEVTIGF0dHI7CiAgICBIQU5ETEUgaGtleTsKCiAgICBSdGxJbml0VW5pY29kZVN0cmluZyggJmtleU5hbWUsIHN6S2V5TmFtZSApOwogICAgSW5pdGlhbGl6ZU9iamVjdEF0dHJpYnV0ZXMoJmF0dHIsICZrZXlOYW1lLCAwLCBoUm9vdEtleSwgTlVMTCk7CgogICAgaWYgKE50T3BlbktleSggJmhrZXksIEtFWV9BTExfQUNDRVNTLCAmYXR0ciApICE9IFNUQVRVU19TVUNDRVNTKQogICAgICAgIGhrZXkgPSAwOwoKICAgIHJldHVybiBoa2V5Owp9CgpzdGF0aWMgSEFORExFIE5MU19SZWdPcGVuU3ViS2V5KEhBTkRMRSBoUm9vdEtleSwgTFBDV1NUUiBzektleU5hbWUpCnsKICAgIEhBTkRMRSBoS2V5ID0gTkxTX1JlZ09wZW5LZXkoaFJvb3RLZXksIHN6S2V5TmFtZSk7CgogICAgaWYgKGhSb290S2V5KQogICAgICAgIE50Q2xvc2UoIGhSb290S2V5ICk7CgogICAgcmV0dXJuIGhLZXk7Cn0KCnN0YXRpYyBCT09MIE5MU19SZWdFbnVtU3ViS2V5KEhBTkRMRSBoS2V5LCBVSU5UIHVsSW5kZXgsIExQV1NUUiBzektleU5hbWUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFVMT05HIGtleU5hbWVTaXplKQp7CiAgICBCWVRFIGJ1ZmZlcls4MF07CiAgICBLRVlfQkFTSUNfSU5GT1JNQVRJT04gKmluZm8gPSAoS0VZX0JBU0lDX0lORk9STUFUSU9OICopYnVmZmVyOwogICAgRFdPUkQgZHdMZW47CgogICAgaWYgKE50RW51bWVyYXRlS2V5KCBoS2V5LCB1bEluZGV4LCBLZXlCYXNpY0luZm9ybWF0aW9uLCBidWZmZXIsCiAgICAgICAgICAgICAgICAgICAgICAgIHNpemVvZihidWZmZXIpLCAmZHdMZW4pICE9IFNUQVRVU19TVUNDRVNTIHx8CiAgICAgICAgaW5mby0+TmFtZUxlbmd0aCA+IGtleU5hbWVTaXplKQogICAgewogICAgICAgIHJldHVybiBGQUxTRTsKICAgIH0KCiAgICBUUkFDRSgiaW5mby0+TmFtZSAlcyBpbmZvLT5OYW1lTGVuZ3RoICVkXG4iLCBkZWJ1Z3N0cl93KGluZm8tPk5hbWUpLCBpbmZvLT5OYW1lTGVuZ3RoKTsKCiAgICBtZW1jcHkoIHN6S2V5TmFtZSwgaW5mby0+TmFtZSwgaW5mby0+TmFtZUxlbmd0aCk7CiAgICBzektleU5hbWVbaW5mby0+TmFtZUxlbmd0aCAvIHNpemVvZihXQ0hBUildID0gJ1wwJzsKCiAgICBUUkFDRSgicmV0dXJuaW5nICVzXG4iLCBkZWJ1Z3N0cl93KHN6S2V5TmFtZSkpOwogICAgcmV0dXJuIFRSVUU7Cn0KCnN0YXRpYyBCT09MIE5MU19SZWdFbnVtVmFsdWUoSEFORExFIGhLZXksIFVJTlQgdWxJbmRleCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMUFdTVFIgc3pWYWx1ZU5hbWUsIFVMT05HIHZhbHVlTmFtZVNpemUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTFBXU1RSIHN6VmFsdWVEYXRhLCBVTE9ORyB2YWx1ZURhdGFTaXplKQp7CiAgICBCWVRFIGJ1ZmZlcls4MF07CiAgICBLRVlfVkFMVUVfRlVMTF9JTkZPUk1BVElPTiAqaW5mbyA9IChLRVlfVkFMVUVfRlVMTF9JTkZPUk1BVElPTiAqKWJ1ZmZlcjsKICAgIERXT1JEIGR3TGVuOwoKICAgIGlmIChOdEVudW1lcmF0ZVZhbHVlS2V5KCBoS2V5LCB1bEluZGV4LCBLZXlWYWx1ZUZ1bGxJbmZvcm1hdGlvbiwKICAgICAgICBidWZmZXIsIHNpemVvZihidWZmZXIpLCAmZHdMZW4gKSAhPSBTVEFUVVNfU1VDQ0VTUyB8fAogICAgICAgIGluZm8tPk5hbWVMZW5ndGggPiB2YWx1ZU5hbWVTaXplIHx8CiAgICAgICAgaW5mby0+RGF0YUxlbmd0aCA+IHZhbHVlRGF0YVNpemUpCiAgICB7CiAgICAgICAgcmV0dXJuIEZBTFNFOwogICAgfQoKICAgIFRSQUNFKCJpbmZvLT5OYW1lICVzIGluZm8tPkRhdGFMZW5ndGggJWRcbiIsIGRlYnVnc3RyX3coaW5mby0+TmFtZSksIGluZm8tPkRhdGFMZW5ndGgpOwoKICAgIG1lbWNweSggc3pWYWx1ZU5hbWUsIGluZm8tPk5hbWUsIGluZm8tPk5hbWVMZW5ndGgpOwogICAgc3pWYWx1ZU5hbWVbaW5mby0+TmFtZUxlbmd0aCAvIHNpemVvZihXQ0hBUildID0gJ1wwJzsKICAgIG1lbWNweSggc3pWYWx1ZURhdGEsIGJ1ZmZlciArIGluZm8tPkRhdGFPZmZzZXQsIGluZm8tPkRhdGFMZW5ndGggKTsKICAgIHN6VmFsdWVEYXRhW2luZm8tPkRhdGFMZW5ndGggLyBzaXplb2YoV0NIQVIpXSA9ICdcMCc7CgogICAgVFJBQ0UoInJldHVybmluZyAlcyAlc1xuIiwgZGVidWdzdHJfdyhzelZhbHVlTmFtZSksIGRlYnVnc3RyX3coc3pWYWx1ZURhdGEpKTsKICAgIHJldHVybiBUUlVFOwp9CgpzdGF0aWMgQk9PTCBOTFNfUmVnR2V0RHdvcmQoSEFORExFIGhLZXksIExQQ1dTVFIgc3pWYWx1ZU5hbWUsIERXT1JEICpscFZhbCkKewogICAgQllURSBidWZmZXJbMTI4XTsKICAgIGNvbnN0IEtFWV9WQUxVRV9QQVJUSUFMX0lORk9STUFUSU9OICppbmZvID0gKEtFWV9WQUxVRV9QQVJUSUFMX0lORk9STUFUSU9OICopYnVmZmVyOwogICAgRFdPUkQgZHdTaXplID0gc2l6ZW9mKGJ1ZmZlcik7CiAgICBVTklDT0RFX1NUUklORyB2YWx1ZU5hbWU7CgogICAgUnRsSW5pdFVuaWNvZGVTdHJpbmcoICZ2YWx1ZU5hbWUsIHN6VmFsdWVOYW1lICk7CgogICAgVFJBQ0UoIiVwLCAlc1xuIiwgaEtleSwgZGVidWdzdHJfdyhzelZhbHVlTmFtZSkpOwogICAgaWYgKE50UXVlcnlWYWx1ZUtleSggaEtleSwgJnZhbHVlTmFtZSwgS2V5VmFsdWVQYXJ0aWFsSW5mb3JtYXRpb24sCiAgICAgICAgICAgICAgICAgICAgICAgICBidWZmZXIsIGR3U2l6ZSwgJmR3U2l6ZSApID09IFNUQVRVU19TVUNDRVNTICYmCiAgICAgICAgaW5mby0+RGF0YUxlbmd0aCA9PSBzaXplb2YoRFdPUkQpKQogICAgewogICAgICAgIG1lbWNweShscFZhbCwgaW5mby0+RGF0YSwgc2l6ZW9mKERXT1JEKSk7CiAgICAgICAgcmV0dXJuIFRSVUU7CiAgICB9CgogICAgcmV0dXJuIEZBTFNFOwp9CgpzdGF0aWMgQk9PTCBOTFNfR2V0TGFuZ3VhZ2VHcm91cE5hbWUoTEdSUElEIGxncnBpZCwgTFBXU1RSIHN6TmFtZSwgVUxPTkcgbmFtZVNpemUpCnsKICAgIExBTkdJRCAgbGFuZ0lkOwogICAgTFBDV1NUUiBzelJlc291cmNlTmFtZSA9IE1BS0VJTlRSRVNPVVJDRVcoKChsZ3JwaWQgKyAweDIwMDApID4+IDQpICsgMSk7CiAgICBIUlNSQyAgIGhSZXNvdXJjZTsKICAgIEJPT0wgICAgYlJldCA9IEZBTFNFOwoKICAgIC8qIEZJWE1FOiBJcyBpdCBjb3JyZWN0IHRvIHVzZSB0aGUgc3lzdGVtIGRlZmF1bHQgbGFuZ2lkPyAqLwogICAgbGFuZ0lkID0gR2V0U3lzdGVtRGVmYXVsdExhbmdJRCgpOwoKICAgIGlmIChTVUJMQU5HSUQobGFuZ0lkKSA9PSBTVUJMQU5HX05FVVRSQUwpCiAgICAgICAgbGFuZ0lkID0gTUFLRUxBTkdJRCggUFJJTUFSWUxBTkdJRChsYW5nSWQpLCBTVUJMQU5HX0RFRkFVTFQgKTsKCiAgICBoUmVzb3VyY2UgPSBGaW5kUmVzb3VyY2VFeFcoIGtlcm5lbDMyX2hhbmRsZSwgKExQV1NUUilSVF9TVFJJTkcsIHN6UmVzb3VyY2VOYW1lLCBsYW5nSWQgKTsKCiAgICBpZiAoaFJlc291cmNlKQogICAgewogICAgICAgIEhHTE9CQUwgaFJlc0RpciA9IExvYWRSZXNvdXJjZSgga2VybmVsMzJfaGFuZGxlLCBoUmVzb3VyY2UgKTsKCiAgICAgICAgaWYgKGhSZXNEaXIpCiAgICAgICAgewogICAgICAgICAgICBVTE9ORyAgIGlSZXNvdXJjZUluZGV4ID0gbGdycGlkICYgMHhmOwogICAgICAgICAgICBMUENXU1RSIGxwUmVzRW50cnkgPSBMb2NrUmVzb3VyY2UoIGhSZXNEaXIgKTsKICAgICAgICAgICAgVUxPTkcgICBpOwoKICAgICAgICAgICAgZm9yIChpID0gMDsgaSA8IGlSZXNvdXJjZUluZGV4OyBpKyspCiAgICAgICAgICAgICAgICBscFJlc0VudHJ5ICs9ICpscFJlc0VudHJ5ICsgMTsKCiAgICAgICAgICAgIGlmICgqbHBSZXNFbnRyeSA8IG5hbWVTaXplKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBtZW1jcHkoIHN6TmFtZSwgbHBSZXNFbnRyeSArIDEsICpscFJlc0VudHJ5ICogc2l6ZW9mKFdDSEFSKSApOwogICAgICAgICAgICAgICAgc3pOYW1lWypscFJlc0VudHJ5XSA9ICdcMCc7CiAgICAgICAgICAgICAgICBiUmV0ID0gVFJVRTsKICAgICAgICAgICAgfQoKICAgICAgICB9CiAgICAgICAgRnJlZVJlc291cmNlKCBoUmVzb3VyY2UgKTsKICAgIH0KICAgIHJldHVybiBiUmV0Owp9CgovKiBSZWdpc3RyeSBrZXlzIGZvciBOTFMgcmVsYXRlZCBpbmZvcm1hdGlvbiAqLwpzdGF0aWMgY29uc3QgV0NIQVIgc3pMYW5nR3JvdXBzS2V5TmFtZVtdID0gewogICAgJ0wnLCdhJywnbicsJ2cnLCd1JywnYScsJ2cnLCdlJywnICcsJ0cnLCdyJywnbycsJ3UnLCdwJywncycsJ1wwJwp9OwoKc3RhdGljIGNvbnN0IFdDSEFSIHN6Q291bnRyeUxpc3ROYW1lW10gPSB7CiAgICAnTScsJ2EnLCdjJywnaCcsJ2knLCduJywnZScsJ1xcJywnUycsJ28nLCdmJywndCcsJ3cnLCdhJywncicsJ2UnLCdcXCcsCiAgICAnTScsJ2knLCdjJywncicsJ28nLCdzJywnbycsJ2YnLCd0JywnXFwnLCdXJywnaScsJ24nLCdkJywnbycsJ3cnLCdzJywnXFwnLAogICAgJ0MnLCd1JywncicsJ3InLCdlJywnbicsJ3QnLCdWJywnZScsJ3InLCdzJywnaScsJ28nLCduJywnXFwnLAogICAgJ1QnLCdlJywnbCcsJ2UnLCdwJywnaCcsJ28nLCduJywneScsJ1xcJywKICAgICdDJywnbycsJ3UnLCduJywndCcsJ3InLCd5JywnICcsJ0wnLCdpJywncycsJ3QnLCdcMCcKfTsKCgovKiBDYWxsYmFjayBmdW5jdGlvbiBwdHJzIGZvciBFbnVtU3lzdGVtTGFuZ3VhZ2VHcm91cHNBL1cgKi8KdHlwZWRlZiBzdHJ1Y3QKewogIExBTkdVQUdFR1JPVVBfRU5VTVBST0NBIHByb2NBOwogIExBTkdVQUdFR1JPVVBfRU5VTVBST0NXIHByb2NXOwogIERXT1JEICAgIGR3RmxhZ3M7CiAgTE9OR19QVFIgbFBhcmFtOwp9IEVOVU1MQU5HVUFHRUdST1VQX0NBTExCQUNLUzsKCi8qIEludGVybmFsIGltcGxlbWVudGF0aW9uIG9mIEVudW1TeXN0ZW1MYW5ndWFnZUdyb3Vwc0EvVyAqLwpzdGF0aWMgQk9PTCBOTFNfRW51bVN5c3RlbUxhbmd1YWdlR3JvdXBzKEVOVU1MQU5HVUFHRUdST1VQX0NBTExCQUNLUyAqbHBQcm9jcykKewogICAgV0NIQVIgc3pOdW1iZXJbMTBdLCBzelZhbHVlWzRdOwogICAgSEFORExFIGhLZXk7CiAgICBCT09MIGJDb250aW51ZSA9IFRSVUU7CiAgICBVTE9ORyB1bEluZGV4ID0gMDsKCiAgICBpZiAoIWxwUHJvY3MpCiAgICB7CiAgICAgICAgU2V0TGFzdEVycm9yKEVSUk9SX0lOVkFMSURfUEFSQU1FVEVSKTsKICAgICAgICByZXR1cm4gRkFMU0U7CiAgICB9CgogICAgc3dpdGNoIChscFByb2NzLT5kd0ZsYWdzKQogICAgewogICAgY2FzZSAwOgogICAgICAgIC8qIERlZmF1bHQgdG8gTEdSUElEX0lOU1RBTExFRCAqLwogICAgICAgIGxwUHJvY3MtPmR3RmxhZ3MgPSBMR1JQSURfSU5TVEFMTEVEOwogICAgICAgIC8qIEZhbGwgdGhyb3VnaC4uLiAqLwogICAgY2FzZSBMR1JQSURfSU5TVEFMTEVEOgogICAgY2FzZSBMR1JQSURfU1VQUE9SVEVEOgogICAgICAgIGJyZWFrOwogICAgZGVmYXVsdDoKICAgICAgICBTZXRMYXN0RXJyb3IoRVJST1JfSU5WQUxJRF9GTEFHUyk7CiAgICAgICAgcmV0dXJuIEZBTFNFOwogICAgfQoKICAgIGhLZXkgPSBOTFNfUmVnT3BlblN1YktleSggTkxTX1JlZ09wZW5LZXkoIDAsIHN6TmxzS2V5TmFtZSApLCBzekxhbmdHcm91cHNLZXlOYW1lICk7CgogICAgaWYgKCFoS2V5KQogICAgICAgIEZJWE1FKCJOTFMgcmVnaXN0cnkga2V5IG5vdCBmb3VuZC4gUGxlYXNlIGFwcGx5IHRoZSBkZWZhdWx0IHJlZ2lzdHJ5IGZpbGUgJ3dpbmUuaW5mJ1xuIik7CgogICAgd2hpbGUgKGJDb250aW51ZSkKICAgIHsKICAgICAgICBpZiAoTkxTX1JlZ0VudW1WYWx1ZSggaEtleSwgdWxJbmRleCwgc3pOdW1iZXIsIHNpemVvZihzek51bWJlciksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN6VmFsdWUsIHNpemVvZihzelZhbHVlKSApKQogICAgICAgIHsKICAgICAgICAgICAgQk9PTCBiSW5zdGFsbGVkID0gc3pWYWx1ZVswXSA9PSAnMScgPyBUUlVFIDogRkFMU0U7CiAgICAgICAgICAgIExHUlBJRCBsZ3JwaWQgPSBzdHJ0b3VsVyggc3pOdW1iZXIsIE5VTEwsIDE2ICk7CgogICAgICAgICAgICBUUkFDRSgiZ3JwaWQgJXMgKCVzaW5zdGFsbGVkKVxuIiwgZGVidWdzdHJfdyhzek51bWJlciksCiAgICAgICAgICAgICAgICAgICBiSW5zdGFsbGVkID8gIiIgOiAibm90ICIpOwoKICAgICAgICAgICAgaWYgKGxwUHJvY3MtPmR3RmxhZ3MgPT0gTEdSUElEX1NVUFBPUlRFRCB8fCBiSW5zdGFsbGVkKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBXQ0hBUiBzekdycE5hbWVbNDhdOwoKICAgICAgICAgICAgICAgIGlmICghTkxTX0dldExhbmd1YWdlR3JvdXBOYW1lKCBsZ3JwaWQsIHN6R3JwTmFtZSwgc2l6ZW9mKHN6R3JwTmFtZSkgLyBzaXplb2YoV0NIQVIpICkpCiAgICAgICAgICAgICAgICAgICAgc3pHcnBOYW1lWzBdID0gJ1wwJzsKCiAgICAgICAgICAgICAgICBpZiAobHBQcm9jcy0+cHJvY1cpCiAgICAgICAgICAgICAgICAgICAgYkNvbnRpbnVlID0gbHBQcm9jcy0+cHJvY1coIGxncnBpZCwgc3pOdW1iZXIsIHN6R3JwTmFtZSwgbHBQcm9jcy0+ZHdGbGFncywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbHBQcm9jcy0+bFBhcmFtICk7CiAgICAgICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgY2hhciBzek51bWJlckFbc2l6ZW9mKHN6TnVtYmVyKS9zaXplb2YoV0NIQVIpXTsKICAgICAgICAgICAgICAgICAgICBjaGFyIHN6R3JwTmFtZUFbNDhdOwoKICAgICAgICAgICAgICAgICAgICAvKiBGSVhNRTogTVNETiBkb2Vzbid0IHNheSB3aGljaCBjb2RlIHBhZ2UgdGhlIFctPkEgdHJhbnNsYXRpb24gdXNlcywKICAgICAgICAgICAgICAgICAgICAgKiAgICAgICAgb3Igd2hldGhlciB0aGUgbGFuZ3VhZ2UgbmFtZXMgYXJlIGV2ZXIgbG9jYWxpc2VkLiBBc3N1bWUgQ1BfQUNQLgogICAgICAgICAgICAgICAgICAgICAqLwoKICAgICAgICAgICAgICAgICAgICBXaWRlQ2hhclRvTXVsdGlCeXRlKENQX0FDUCwgMCwgc3pOdW1iZXIsIC0xLCBzek51bWJlckEsIHNpemVvZihzek51bWJlckEpLCAwLCAwKTsKICAgICAgICAgICAgICAgICAgICBXaWRlQ2hhclRvTXVsdGlCeXRlKENQX0FDUCwgMCwgc3pHcnBOYW1lLCAtMSwgc3pHcnBOYW1lQSwgc2l6ZW9mKHN6R3JwTmFtZUEpLCAwLCAwKTsKCiAgICAgICAgICAgICAgICAgICAgYkNvbnRpbnVlID0gbHBQcm9jcy0+cHJvY0EoIGxncnBpZCwgc3pOdW1iZXJBLCBzekdycE5hbWVBLCBscFByb2NzLT5kd0ZsYWdzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBscFByb2NzLT5sUGFyYW0gKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQoKICAgICAgICAgICAgdWxJbmRleCsrOwogICAgICAgIH0KICAgICAgICBlbHNlCiAgICAgICAgICAgIGJDb250aW51ZSA9IEZBTFNFOwoKICAgICAgICBpZiAoIWJDb250aW51ZSkKICAgICAgICAgICAgYnJlYWs7CiAgICB9CgogICAgaWYgKGhLZXkpCiAgICAgICAgTnRDbG9zZSggaEtleSApOwoKICAgIHJldHVybiBUUlVFOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgICAgICBFbnVtU3lzdGVtTGFuZ3VhZ2VHcm91cHNBICAgIChLRVJORUwzMi5AKQogKgogKiBDYWxsIGEgdXNlcnMgZnVuY3Rpb24gZm9yIGVhY2ggbGFuZ3VhZ2UgZ3JvdXAgYXZhaWxhYmxlIG9uIHRoZSBzeXN0ZW0uCiAqCiAqIFBBUkFNUwogKiAgcExhbmdHcnBFbnVtUHJvYyBbSV0gQ2FsbGJhY2sgZnVuY3Rpb24gdG8gY2FsbCBmb3IgZWFjaCBsYW5ndWFnZSBncm91cAogKiAgZHdGbGFncyAgICAgICAgICBbSV0gTEdSUElEX1NVUFBPUlRFRD1BbGwgU3VwcG9ydGVkLCBMR1JQSURfSU5TVEFMTEVEPUluc3RhbGxlZCBvbmx5CiAqICBsUGFyYW0gICAgICAgICAgIFtJXSBVc2VyIHBhcmFtZXRlciB0byBwYXNzIHRvIHBMYW5nR3JwRW51bVByb2MKICoKICogUkVUVVJOUwogKiAgU3VjY2VzczogVFJVRS4KICogIEZhaWx1cmU6IEZBTFNFLiBVc2UgR2V0TGFzdEVycm9yKCkgdG8gZGV0ZXJtaW5lIHRoZSBjYXVzZS4KICovCkJPT0wgV0lOQVBJIEVudW1TeXN0ZW1MYW5ndWFnZUdyb3Vwc0EoTEFOR1VBR0VHUk9VUF9FTlVNUFJPQ0EgcExhbmdHcnBFbnVtUHJvYywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEV09SRCBkd0ZsYWdzLCBMT05HX1BUUiBsUGFyYW0pCnsKICAgIEVOVU1MQU5HVUFHRUdST1VQX0NBTExCQUNLUyBwcm9jczsKCiAgICBUUkFDRSgiKCVwLDB4JTA4WCwweCUwOGxYKVxuIiwgcExhbmdHcnBFbnVtUHJvYywgZHdGbGFncywgbFBhcmFtKTsKCiAgICBwcm9jcy5wcm9jQSA9IHBMYW5nR3JwRW51bVByb2M7CiAgICBwcm9jcy5wcm9jVyA9IE5VTEw7CiAgICBwcm9jcy5kd0ZsYWdzID0gZHdGbGFnczsKICAgIHByb2NzLmxQYXJhbSA9IGxQYXJhbTsKCiAgICByZXR1cm4gTkxTX0VudW1TeXN0ZW1MYW5ndWFnZUdyb3VwcyggcExhbmdHcnBFbnVtUHJvYyA/ICZwcm9jcyA6IE5VTEwpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgICAgICBFbnVtU3lzdGVtTGFuZ3VhZ2VHcm91cHNXICAgIChLRVJORUwzMi5AKQogKgogKiBTZWUgRW51bVN5c3RlbUxhbmd1YWdlR3JvdXBzQS4KICovCkJPT0wgV0lOQVBJIEVudW1TeXN0ZW1MYW5ndWFnZUdyb3Vwc1coTEFOR1VBR0VHUk9VUF9FTlVNUFJPQ1cgcExhbmdHcnBFbnVtUHJvYywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEV09SRCBkd0ZsYWdzLCBMT05HX1BUUiBsUGFyYW0pCnsKICAgIEVOVU1MQU5HVUFHRUdST1VQX0NBTExCQUNLUyBwcm9jczsKCiAgICBUUkFDRSgiKCVwLDB4JTA4WCwweCUwOGxYKVxuIiwgcExhbmdHcnBFbnVtUHJvYywgZHdGbGFncywgbFBhcmFtKTsKCiAgICBwcm9jcy5wcm9jQSA9IE5VTEw7CiAgICBwcm9jcy5wcm9jVyA9IHBMYW5nR3JwRW51bVByb2M7CiAgICBwcm9jcy5kd0ZsYWdzID0gZHdGbGFnczsKICAgIHByb2NzLmxQYXJhbSA9IGxQYXJhbTsKCiAgICByZXR1cm4gTkxTX0VudW1TeXN0ZW1MYW5ndWFnZUdyb3VwcyggcExhbmdHcnBFbnVtUHJvYyA/ICZwcm9jcyA6IE5VTEwpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgICAgICBJc1ZhbGlkTGFuZ3VhZ2VHcm91cCAgICAoS0VSTkVMMzIuQCkKICoKICogRGV0ZXJtaW5lIGlmIGEgbGFuZ3VhZ2UgZ3JvdXAgaXMgc3VwcG9ydGVkIGFuZC9vciBpbnN0YWxsZWQuCiAqCiAqIFBBUkFNUwogKiAgbGdycGlkICBbSV0gTGFuZ3VhZ2UgR3JvdXAgSWQgKExHUlBJRF8gdmFsdWVzIGZyb20gIndpbm5scy5oIikKICogIGR3RmxhZ3MgW0ldIExHUlBJRF9TVVBQT1JURUQ9U3VwcG9ydGVkLCBMR1JQSURfSU5TVEFMTEVEPUluc3RhbGxlZAogKgogKiBSRVRVUk5TCiAqICBUUlVFLCBpZiBsZ3JwaWQgaXMgc3VwcG9ydGVkIGFuZC9vciBpbnN0YWxsZWQsIGFjY29yZGluZyB0byBkd0ZsYWdzLgogKiAgRkFMU0Ugb3RoZXJ3aXNlLgogKi8KQk9PTCBXSU5BUEkgSXNWYWxpZExhbmd1YWdlR3JvdXAoTEdSUElEIGxncnBpZCwgRFdPUkQgZHdGbGFncykKewogICAgc3RhdGljIGNvbnN0IFdDSEFSIHN6Rm9ybWF0W10gPSB7ICclJywneCcsJ1wwJyB9OwogICAgV0NIQVIgc3pWYWx1ZU5hbWVbMTZdLCBzelZhbHVlWzJdOwogICAgQk9PTCBiU3VwcG9ydGVkID0gRkFMU0UsIGJJbnN0YWxsZWQgPSBGQUxTRTsKICAgIEhBTkRMRSBoS2V5OwoKCiAgICBzd2l0Y2ggKGR3RmxhZ3MpCiAgICB7CiAgICBjYXNlIExHUlBJRF9JTlNUQUxMRUQ6CiAgICBjYXNlIExHUlBJRF9TVVBQT1JURUQ6CgogICAgICAgIGhLZXkgPSBOTFNfUmVnT3BlblN1YktleSggTkxTX1JlZ09wZW5LZXkoIDAsIHN6TmxzS2V5TmFtZSApLCBzekxhbmdHcm91cHNLZXlOYW1lICk7CgogICAgICAgIHNwcmludGZXKCBzelZhbHVlTmFtZSwgc3pGb3JtYXQsIGxncnBpZCApOwoKICAgICAgICBpZiAoTkxTX1JlZ0dldER3b3JkKCBoS2V5LCBzelZhbHVlTmFtZSwgKExQRFdPUkQpJnN6VmFsdWUgKSkKICAgICAgICB7CiAgICAgICAgICAgIGJTdXBwb3J0ZWQgPSBUUlVFOwoKICAgICAgICAgICAgaWYgKHN6VmFsdWVbMF0gPT0gJzEnKQogICAgICAgICAgICAgICAgYkluc3RhbGxlZCA9IFRSVUU7CiAgICAgICAgfQoKICAgICAgICBpZiAoaEtleSkKICAgICAgICAgICAgTnRDbG9zZSggaEtleSApOwoKICAgICAgICBicmVhazsKICAgIH0KCiAgICBpZiAoKGR3RmxhZ3MgPT0gTEdSUElEX1NVUFBPUlRFRCAmJiBiU3VwcG9ydGVkKSB8fAogICAgICAgIChkd0ZsYWdzID09IExHUlBJRF9JTlNUQUxMRUQgJiYgYkluc3RhbGxlZCkpCiAgICAgICAgcmV0dXJuIFRSVUU7CgogICAgcmV0dXJuIEZBTFNFOwp9CgovKiBDYWxsYmFjayBmdW5jdGlvbiBwdHJzIGZvciBFbnVtTGFuZ3VhZ2VHcm91cGxvY2FsZXNBL1cgKi8KdHlwZWRlZiBzdHJ1Y3QKewogIExBTkdHUk9VUExPQ0FMRV9FTlVNUFJPQ0EgcHJvY0E7CiAgTEFOR0dST1VQTE9DQUxFX0VOVU1QUk9DVyBwcm9jVzsKICBEV09SRCAgICBkd0ZsYWdzOwogIExHUlBJRCAgIGxncnBpZDsKICBMT05HX1BUUiBsUGFyYW07Cn0gRU5VTUxBTkdVQUdFR1JPVVBMT0NBTEVfQ0FMTEJBQ0tTOwoKLyogSW50ZXJuYWwgaW1wbGVtZW50YXRpb24gb2YgRW51bUxhbmd1YWdlR3JvdXBsb2NhbGVzQS9XICovCnN0YXRpYyBCT09MIE5MU19FbnVtTGFuZ3VhZ2VHcm91cExvY2FsZXMoRU5VTUxBTkdVQUdFR1JPVVBMT0NBTEVfQ0FMTEJBQ0tTICpscFByb2NzKQp7CiAgICBzdGF0aWMgY29uc3QgV0NIQVIgc3pMb2NhbGVLZXlOYW1lW10gPSB7CiAgICAgICdMJywnbycsJ2MnLCdhJywnbCcsJ2UnLCdcMCcKICAgIH07CiAgICBzdGF0aWMgY29uc3QgV0NIQVIgc3pBbHRlcm5hdGVTb3J0c0tleU5hbWVbXSA9IHsKICAgICAgJ0EnLCdsJywndCcsJ2UnLCdyJywnbicsJ2EnLCd0JywnZScsJyAnLCdTJywnbycsJ3InLCd0JywncycsJ1wwJwogICAgfTsKICAgIFdDSEFSIHN6TnVtYmVyWzEwXSwgc3pWYWx1ZVs0XTsKICAgIEhBTkRMRSBoS2V5OwogICAgQk9PTCBiQ29udGludWUgPSBUUlVFLCBiQWx0ZXJuYXRlID0gRkFMU0U7CiAgICBMR1JQSUQgbGdycGlkOwogICAgVUxPTkcgdWxJbmRleCA9IDE7ICAvKiBJZ25vcmUgZGVmYXVsdCBlbnRyeSBvZiAxc3Qga2V5ICovCgogICAgaWYgKCFscFByb2NzIHx8ICFscFByb2NzLT5sZ3JwaWQgfHwgbHBQcm9jcy0+bGdycGlkID4gTEdSUElEX0FSTUVOSUFOKQogICAgewogICAgICAgIFNldExhc3RFcnJvcihFUlJPUl9JTlZBTElEX1BBUkFNRVRFUik7CiAgICAgICAgcmV0dXJuIEZBTFNFOwogICAgfQoKICAgIGlmIChscFByb2NzLT5kd0ZsYWdzKQogICAgewogICAgICAgIFNldExhc3RFcnJvcihFUlJPUl9JTlZBTElEX0ZMQUdTKTsKICAgICAgICByZXR1cm4gRkFMU0U7CiAgICB9CgogICAgaEtleSA9IE5MU19SZWdPcGVuU3ViS2V5KCBOTFNfUmVnT3BlbktleSggMCwgc3pObHNLZXlOYW1lICksIHN6TG9jYWxlS2V5TmFtZSApOwoKICAgIGlmICghaEtleSkKICAgICAgICBXQVJOKCJOTFMgcmVnaXN0cnkga2V5IG5vdCBmb3VuZC4gUGxlYXNlIGFwcGx5IHRoZSBkZWZhdWx0IHJlZ2lzdHJ5IGZpbGUgJ3dpbmUuaW5mJ1xuIik7CgogICAgd2hpbGUgKGJDb250aW51ZSkKICAgIHsKICAgICAgICBpZiAoTkxTX1JlZ0VudW1WYWx1ZSggaEtleSwgdWxJbmRleCwgc3pOdW1iZXIsIHNpemVvZihzek51bWJlciksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN6VmFsdWUsIHNpemVvZihzelZhbHVlKSApKQogICAgICAgIHsKICAgICAgICAgICAgbGdycGlkID0gc3RydG91bFcoIHN6VmFsdWUsIE5VTEwsIDE2ICk7CgogICAgICAgICAgICBUUkFDRSgibGNpZCAlcywgZ3JwaWQgJWQgKCVzbWF0Y2hlZClcbiIsIGRlYnVnc3RyX3coc3pOdW1iZXIpLAogICAgICAgICAgICAgICAgICAgbGdycGlkLCBsZ3JwaWQgPT0gbHBQcm9jcy0+bGdycGlkID8gIiIgOiAibm90ICIpOwoKICAgICAgICAgICAgaWYgKGxncnBpZCA9PSBscFByb2NzLT5sZ3JwaWQpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIExDSUQgbGNpZDsKCiAgICAgICAgICAgICAgICBsY2lkID0gc3RydG91bFcoIHN6TnVtYmVyLCBOVUxMLCAxNiApOwoKICAgICAgICAgICAgICAgIC8qIEZJWE1FOiBuYXRpdmUgcmV0dXJucyBleHRyYSB0ZXh0IGZvciBhIGZldyAoMTcvMTUwKSBsb2NhbGVzLCBlLmc6CiAgICAgICAgICAgICAgICAgKiAnMDAwMDA0MzcgICAgICAgICAgO0dlb3JnaWFuJwogICAgICAgICAgICAgICAgICogQXQgcHJlc2VudCB3ZSBvbmx5IHBhc3MgdGhlIExDSUQgc3RyaW5nLgogICAgICAgICAgICAgICAgICovCgogICAgICAgICAgICAgICAgaWYgKGxwUHJvY3MtPnByb2NXKQogICAgICAgICAgICAgICAgICAgIGJDb250aW51ZSA9IGxwUHJvY3MtPnByb2NXKCBsZ3JwaWQsIGxjaWQsIHN6TnVtYmVyLCBscFByb2NzLT5sUGFyYW0gKTsKICAgICAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBjaGFyIHN6TnVtYmVyQVtzaXplb2Yoc3pOdW1iZXIpL3NpemVvZihXQ0hBUildOwoKICAgICAgICAgICAgICAgICAgICBXaWRlQ2hhclRvTXVsdGlCeXRlKENQX0FDUCwgMCwgc3pOdW1iZXIsIC0xLCBzek51bWJlckEsIHNpemVvZihzek51bWJlckEpLCAwLCAwKTsKCiAgICAgICAgICAgICAgICAgICAgYkNvbnRpbnVlID0gbHBQcm9jcy0+cHJvY0EoIGxncnBpZCwgbGNpZCwgc3pOdW1iZXJBLCBscFByb2NzLT5sUGFyYW0gKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQoKICAgICAgICAgICAgdWxJbmRleCsrOwogICAgICAgIH0KICAgICAgICBlbHNlCiAgICAgICAgewogICAgICAgICAgICAvKiBGaW5pc2hlZCBlbnVtZXJhdGluZyB0aGlzIGtleSAqLwogICAgICAgICAgICBpZiAoIWJBbHRlcm5hdGUpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIC8qIEVudW1lcmF0ZSBhbHRlcm5hdGUgc29ydHMgYWxzbyAqLwogICAgICAgICAgICAgICAgaEtleSA9IE5MU19SZWdPcGVuS2V5KCBoS2V5LCBzekFsdGVybmF0ZVNvcnRzS2V5TmFtZSApOwogICAgICAgICAgICAgICAgYkFsdGVybmF0ZSA9IFRSVUU7CiAgICAgICAgICAgICAgICB1bEluZGV4ID0gMDsKICAgICAgICAgICAgfQogICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICBiQ29udGludWUgPSBGQUxTRTsgLyogRmluaXNoZWQgYm90aCBrZXlzICovCiAgICAgICAgfQoKICAgICAgICBpZiAoIWJDb250aW51ZSkKICAgICAgICAgICAgYnJlYWs7CiAgICB9CgogICAgaWYgKGhLZXkpCiAgICAgICAgTnRDbG9zZSggaEtleSApOwoKICAgIHJldHVybiBUUlVFOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgICAgICBFbnVtTGFuZ3VhZ2VHcm91cExvY2FsZXNBICAgIChLRVJORUwzMi5AKQogKgogKiBDYWxsIGEgdXNlcnMgZnVuY3Rpb24gZm9yIGV2ZXJ5IGxvY2FsZSBpbiBhIGxhbmd1YWdlIGdyb3VwIGF2YWlsYWJsZSBvbiB0aGUgc3lzdGVtLgogKgogKiBQQVJBTVMKICogIHBMYW5nR3JwTGNFbnVtUHJvYyBbSV0gQ2FsbGJhY2sgZnVuY3Rpb24gdG8gY2FsbCBmb3IgZWFjaCBsb2NhbGUKICogIGxncnBpZCAgICAgICAgICAgICBbSV0gTGFuZ3VhZ2UgZ3JvdXAgKExHUlBJRF8gdmFsdWVzIGZyb20gIndpbm5scy5oIikKICogIGR3RmxhZ3MgICAgICAgICAgICBbSV0gUmVzZXJ2ZWQsIHNldCB0byAwCiAqICBsUGFyYW0gICAgICAgICAgICAgW0ldIFVzZXIgcGFyYW1ldGVyIHRvIHBhc3MgdG8gcExhbmdHcnBMY0VudW1Qcm9jCiAqCiAqIFJFVFVSTlMKICogIFN1Y2Nlc3M6IFRSVUUuCiAqICBGYWlsdXJlOiBGQUxTRS4gVXNlIEdldExhc3RFcnJvcigpIHRvIGRldGVybWluZSB0aGUgY2F1c2UuCiAqLwpCT09MIFdJTkFQSSBFbnVtTGFuZ3VhZ2VHcm91cExvY2FsZXNBKExBTkdHUk9VUExPQ0FMRV9FTlVNUFJPQ0EgcExhbmdHcnBMY0VudW1Qcm9jLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIExHUlBJRCBsZ3JwaWQsIERXT1JEIGR3RmxhZ3MsIExPTkdfUFRSIGxQYXJhbSkKewogICAgRU5VTUxBTkdVQUdFR1JPVVBMT0NBTEVfQ0FMTEJBQ0tTIGNhbGxiYWNrczsKCiAgICBUUkFDRSgiKCVwLDB4JTA4WCwweCUwOFgsMHglMDhsWClcbiIsIHBMYW5nR3JwTGNFbnVtUHJvYywgbGdycGlkLCBkd0ZsYWdzLCBsUGFyYW0pOwoKICAgIGNhbGxiYWNrcy5wcm9jQSAgID0gcExhbmdHcnBMY0VudW1Qcm9jOwogICAgY2FsbGJhY2tzLnByb2NXICAgPSBOVUxMOwogICAgY2FsbGJhY2tzLmR3RmxhZ3MgPSBkd0ZsYWdzOwogICAgY2FsbGJhY2tzLmxncnBpZCAgPSBsZ3JwaWQ7CiAgICBjYWxsYmFja3MubFBhcmFtICA9IGxQYXJhbTsKCiAgICByZXR1cm4gTkxTX0VudW1MYW5ndWFnZUdyb3VwTG9jYWxlcyggcExhbmdHcnBMY0VudW1Qcm9jID8gJmNhbGxiYWNrcyA6IE5VTEwgKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgICAgICAgRW51bUxhbmd1YWdlR3JvdXBMb2NhbGVzVyAgICAoS0VSTkVMMzIuQCkKICoKICogU2VlIEVudW1MYW5ndWFnZUdyb3VwTG9jYWxlc0EuCiAqLwpCT09MIFdJTkFQSSBFbnVtTGFuZ3VhZ2VHcm91cExvY2FsZXNXKExBTkdHUk9VUExPQ0FMRV9FTlVNUFJPQ1cgcExhbmdHcnBMY0VudW1Qcm9jLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIExHUlBJRCBsZ3JwaWQsIERXT1JEIGR3RmxhZ3MsIExPTkdfUFRSIGxQYXJhbSkKewogICAgRU5VTUxBTkdVQUdFR1JPVVBMT0NBTEVfQ0FMTEJBQ0tTIGNhbGxiYWNrczsKCiAgICBUUkFDRSgiKCVwLDB4JTA4WCwweCUwOFgsMHglMDhsWClcbiIsIHBMYW5nR3JwTGNFbnVtUHJvYywgbGdycGlkLCBkd0ZsYWdzLCBsUGFyYW0pOwoKICAgIGNhbGxiYWNrcy5wcm9jQSAgID0gTlVMTDsKICAgIGNhbGxiYWNrcy5wcm9jVyAgID0gcExhbmdHcnBMY0VudW1Qcm9jOwogICAgY2FsbGJhY2tzLmR3RmxhZ3MgPSBkd0ZsYWdzOwogICAgY2FsbGJhY2tzLmxncnBpZCAgPSBsZ3JwaWQ7CiAgICBjYWxsYmFja3MubFBhcmFtICA9IGxQYXJhbTsKCiAgICByZXR1cm4gTkxTX0VudW1MYW5ndWFnZUdyb3VwTG9jYWxlcyggcExhbmdHcnBMY0VudW1Qcm9jID8gJmNhbGxiYWNrcyA6IE5VTEwgKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgICAgICAgRW51bVN5c3RlbUdlb0lEICAgIChLRVJORUwzMi5AKQogKgogKiBDYWxsIGEgdXNlcnMgZnVuY3Rpb24gZm9yIGV2ZXJ5IGxvY2F0aW9uIGF2YWlsYWJsZSBvbiB0aGUgc3lzdGVtLgogKgogKiBQQVJBTVMKICogIGdlb2NsYXNzICAgICBbSV0gVHlwZSBvZiBpbmZvcm1hdGlvbiBkZXNpcmVkIChTWVNHRU9UWVBFIGVudW0gZnJvbSAid2lubmxzLmgiKQogKiAgcmVzZXJ2ZWQgICAgIFtJXSBSZXNlcnZlZCwgc2V0IHRvIDAKICogIHBHZW9FbnVtUHJvYyBbSV0gQ2FsbGJhY2sgZnVuY3Rpb24gdG8gY2FsbCBmb3IgZWFjaCBsb2NhdGlvbgogKgogKiBSRVRVUk5TCiAqICBTdWNjZXNzOiBUUlVFLgogKiAgRmFpbHVyZTogRkFMU0UuIFVzZSBHZXRMYXN0RXJyb3IoKSB0byBkZXRlcm1pbmUgdGhlIGNhdXNlLgogKi8KQk9PTCBXSU5BUEkgRW51bVN5c3RlbUdlb0lEKEdFT0NMQVNTIGdlb2NsYXNzLCBHRU9JRCByZXNlcnZlZCwgR0VPX0VOVU1QUk9DIHBHZW9FbnVtUHJvYykKewogICAgc3RhdGljIGNvbnN0IFdDSEFSIHN6Q291bnRyeUNvZGVWYWx1ZU5hbWVbXSA9IHsKICAgICAgJ0MnLCdvJywndScsJ24nLCd0JywncicsJ3knLCdDJywnbycsJ2QnLCdlJywnXDAnCiAgICB9OwogICAgV0NIQVIgc3pOdW1iZXJbMTBdOwogICAgSEFORExFIGhLZXk7CiAgICBVTE9ORyB1bEluZGV4ID0gMDsKCiAgICBUUkFDRSgiKDB4JTA4WCwweCUwOFgsJXApXG4iLCBnZW9jbGFzcywgcmVzZXJ2ZWQsIHBHZW9FbnVtUHJvYyk7CgogICAgaWYgKGdlb2NsYXNzICE9IEdFT0NMQVNTX05BVElPTiB8fCByZXNlcnZlZCB8fCAhcEdlb0VudW1Qcm9jKQogICAgewogICAgICAgIFNldExhc3RFcnJvcihFUlJPUl9JTlZBTElEX1BBUkFNRVRFUik7CiAgICAgICAgcmV0dXJuIEZBTFNFOwogICAgfQoKICAgIGhLZXkgPSBOTFNfUmVnT3BlbktleSggMCwgc3pDb3VudHJ5TGlzdE5hbWUgKTsKCiAgICB3aGlsZSAoTkxTX1JlZ0VudW1TdWJLZXkoIGhLZXksIHVsSW5kZXgsIHN6TnVtYmVyLCBzaXplb2Yoc3pOdW1iZXIpICkpCiAgICB7CiAgICAgICAgQk9PTCBiQ29udGludWUgPSBUUlVFOwogICAgICAgIERXT1JEIGR3R2VvSWQ7CiAgICAgICAgSEFORExFIGhTdWJLZXkgPSBOTFNfUmVnT3BlbktleSggaEtleSwgc3pOdW1iZXIgKTsKCiAgICAgICAgaWYgKGhTdWJLZXkpCiAgICAgICAgewogICAgICAgICAgICBpZiAoTkxTX1JlZ0dldER3b3JkKCBoU3ViS2V5LCBzekNvdW50cnlDb2RlVmFsdWVOYW1lLCAmZHdHZW9JZCApKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBUUkFDRSgiR290IGdlb2lkICVkXG4iLCBkd0dlb0lkKTsKCiAgICAgICAgICAgICAgICBpZiAoIXBHZW9FbnVtUHJvYyggZHdHZW9JZCApKQogICAgICAgICAgICAgICAgICAgIGJDb250aW51ZSA9IEZBTFNFOwogICAgICAgICAgICB9CgogICAgICAgICAgICBOdENsb3NlKCBoU3ViS2V5ICk7CiAgICAgICAgfQoKICAgICAgICBpZiAoIWJDb250aW51ZSkKICAgICAgICAgICAgYnJlYWs7CgogICAgICAgIHVsSW5kZXgrKzsKICAgIH0KCiAgICBpZiAoaEtleSkKICAgICAgICBOdENsb3NlKCBoS2V5ICk7CgogICAgcmV0dXJuIFRSVUU7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICAgICAgIEludmFsaWRhdGVOTFNDYWNoZSAgICAgICAgICAgKEtFUk5FTDMyLkApCiAqCiAqIEludmFsaWRhdGUgdGhlIGNhY2hlIG9mIE5MUyB2YWx1ZXMuCiAqCiAqIFBBUkFNUwogKiAgTm9uZS4KICoKICogUkVUVVJOUwogKiAgU3VjY2VzczogVFJVRS4KICogIEZhaWx1cmU6IEZBTFNFLgogKi8KQk9PTCBXSU5BUEkgSW52YWxpZGF0ZU5MU0NhY2hlKHZvaWQpCnsKICBGSVhNRSgiKCkgc3R1YlxuIik7CiAgcmV0dXJuIEZBTFNFOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgICAgICBHZXRVc2VyR2VvSUQgKEtFUk5FTDMyLkApCiAqLwpHRU9JRCBXSU5BUEkgR2V0VXNlckdlb0lEKCBHRU9DTEFTUyBHZW9DbGFzcyApCnsKICAgIEZJWE1FKCIlZFxuIixHZW9DbGFzcyk7CiAgICByZXR1cm4gR0VPSURfTk9UX0FWQUlMQUJMRTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgICAgICAgU2V0VXNlckdlb0lEIChLRVJORUwzMi5AKQogKi8KQk9PTCBXSU5BUEkgU2V0VXNlckdlb0lEKCBHRU9JRCBHZW9JRCApCnsKICAgIEZJWE1FKCIlZFxuIixHZW9JRCk7CiAgICByZXR1cm4gRkFMU0U7Cn0KCnR5cGVkZWYgc3RydWN0CnsKICAgIHVuaW9uCiAgICB7CiAgICAgICAgVUlMQU5HVUFHRV9FTlVNUFJPQ0EgcHJvY0E7CiAgICAgICAgVUlMQU5HVUFHRV9FTlVNUFJPQ1cgcHJvY1c7CiAgICB9IHU7CiAgICBEV09SRCBmbGFnczsKICAgIExPTkdfUFRSIHBhcmFtOwp9IEVOVU1fVUlMQU5HX0NBTExCQUNLOwoKc3RhdGljIEJPT0wgQ0FMTEJBQ0sgZW51bV91aWxhbmdfcHJvY19hKCBITU9EVUxFIGhNb2R1bGUsIExQQ1NUUiB0eXBlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIExQQ1NUUiBuYW1lLCBXT1JEIExhbmdJRCwgTE9OR19QVFIgbFBhcmFtICkKewogICAgRU5VTV9VSUxBTkdfQ0FMTEJBQ0sgKmVudW1fdWlsYW5nID0gKEVOVU1fVUlMQU5HX0NBTExCQUNLICopbFBhcmFtOwogICAgY2hhciBidWZbMjBdOwoKICAgIHNwcmludGYoYnVmLCAiJTA4eCIsIChVSU5UKUxhbmdJRCk7CiAgICByZXR1cm4gZW51bV91aWxhbmctPnUucHJvY0EoIGJ1ZiwgZW51bV91aWxhbmctPnBhcmFtICk7Cn0KCnN0YXRpYyBCT09MIENBTExCQUNLIGVudW1fdWlsYW5nX3Byb2NfdyggSE1PRFVMRSBoTW9kdWxlLCBMUENXU1RSIHR5cGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTFBDV1NUUiBuYW1lLCBXT1JEIExhbmdJRCwgTE9OR19QVFIgbFBhcmFtICkKewogICAgc3RhdGljIGNvbnN0IFdDSEFSIGZvcm1hdFdbXSA9IHsnJScsJzAnLCc4JywneCcsMH07CiAgICBFTlVNX1VJTEFOR19DQUxMQkFDSyAqZW51bV91aWxhbmcgPSAoRU5VTV9VSUxBTkdfQ0FMTEJBQ0sgKilsUGFyYW07CiAgICBXQ0hBUiBidWZbMjBdOwoKICAgIHNwcmludGZXKCBidWYsIGZvcm1hdFcsIChVSU5UKUxhbmdJRCApOwogICAgcmV0dXJuIGVudW1fdWlsYW5nLT51LnByb2NXKCBidWYsIGVudW1fdWlsYW5nLT5wYXJhbSApOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgICAgICBFbnVtVUlMYW5ndWFnZXNBIChLRVJORUwzMi5AKQogKi8KQk9PTCBXSU5BUEkgRW51bVVJTGFuZ3VhZ2VzQShVSUxBTkdVQUdFX0VOVU1QUk9DQSBwVUlMYW5nRW51bVByb2MsIERXT1JEIGR3RmxhZ3MsIExPTkdfUFRSIGxQYXJhbSkKewogICAgRU5VTV9VSUxBTkdfQ0FMTEJBQ0sgZW51bV91aWxhbmc7CgogICAgVFJBQ0UoIiVwLCAleCwgJWx4XG4iLCBwVUlMYW5nRW51bVByb2MsIGR3RmxhZ3MsIGxQYXJhbSk7CgogICAgaWYoIXBVSUxhbmdFbnVtUHJvYykgewoJU2V0TGFzdEVycm9yKEVSUk9SX0lOVkFMSURfUEFSQU1FVEVSKTsKCXJldHVybiBGQUxTRTsKICAgIH0KICAgIGlmKGR3RmxhZ3MpIHsKCVNldExhc3RFcnJvcihFUlJPUl9JTlZBTElEX0ZMQUdTKTsKCXJldHVybiBGQUxTRTsKICAgIH0KCiAgICBlbnVtX3VpbGFuZy51LnByb2NBID0gcFVJTGFuZ0VudW1Qcm9jOwogICAgZW51bV91aWxhbmcuZmxhZ3MgPSBkd0ZsYWdzOwogICAgZW51bV91aWxhbmcucGFyYW0gPSBsUGFyYW07CgogICAgRW51bVJlc291cmNlTGFuZ3VhZ2VzQSgga2VybmVsMzJfaGFuZGxlLCAoTFBDU1RSKVJUX1NUUklORywKICAgICAgICAgICAgICAgICAgICAgICAgICAgIChMUENTVFIpTE9DQUxFX0lMQU5HVUFHRSwgZW51bV91aWxhbmdfcHJvY19hLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgKExPTkdfUFRSKSZlbnVtX3VpbGFuZyk7CiAgICByZXR1cm4gVFJVRTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgICAgICAgRW51bVVJTGFuZ3VhZ2VzVyAoS0VSTkVMMzIuQCkKICovCkJPT0wgV0lOQVBJIEVudW1VSUxhbmd1YWdlc1coVUlMQU5HVUFHRV9FTlVNUFJPQ1cgcFVJTGFuZ0VudW1Qcm9jLCBEV09SRCBkd0ZsYWdzLCBMT05HX1BUUiBsUGFyYW0pCnsKICAgIEVOVU1fVUlMQU5HX0NBTExCQUNLIGVudW1fdWlsYW5nOwoKICAgIFRSQUNFKCIlcCwgJXgsICVseFxuIiwgcFVJTGFuZ0VudW1Qcm9jLCBkd0ZsYWdzLCBsUGFyYW0pOwoKCiAgICBpZighcFVJTGFuZ0VudW1Qcm9jKSB7CglTZXRMYXN0RXJyb3IoRVJST1JfSU5WQUxJRF9QQVJBTUVURVIpOwoJcmV0dXJuIEZBTFNFOwogICAgfQogICAgaWYoZHdGbGFncykgewoJU2V0TGFzdEVycm9yKEVSUk9SX0lOVkFMSURfRkxBR1MpOwoJcmV0dXJuIEZBTFNFOwogICAgfQoKICAgIGVudW1fdWlsYW5nLnUucHJvY1cgPSBwVUlMYW5nRW51bVByb2M7CiAgICBlbnVtX3VpbGFuZy5mbGFncyA9IGR3RmxhZ3M7CiAgICBlbnVtX3VpbGFuZy5wYXJhbSA9IGxQYXJhbTsKCiAgICBFbnVtUmVzb3VyY2VMYW5ndWFnZXNXKCBrZXJuZWwzMl9oYW5kbGUsIChMUENXU1RSKVJUX1NUUklORywKICAgICAgICAgICAgICAgICAgICAgICAgICAgIChMUENXU1RSKUxPQ0FMRV9JTEFOR1VBR0UsIGVudW1fdWlsYW5nX3Byb2NfdywKICAgICAgICAgICAgICAgICAgICAgICAgICAgIChMT05HX1BUUikmZW51bV91aWxhbmcpOwogICAgcmV0dXJuIFRSVUU7Cn0KCklOVCBXSU5BUEkgR2V0R2VvSW5mb1coR0VPSUQgR2VvSWQsIEdFT1RZUEUgR2VvVHlwZSwgTFBXU1RSIGxwR2VvRGF0YSwgCiAgICAgICAgICAgICAgICBpbnQgY2NoRGF0YSwgTEFOR0lEIGxhbmd1YWdlKQp7CiAgICBGSVhNRSgiJWQgJWQgJXAgJWQgJWRcbiIsIEdlb0lkLCBHZW9UeXBlLCBscEdlb0RhdGEsIGNjaERhdGEsIGxhbmd1YWdlKTsKICAgIHJldHVybiAwOwp9CgpJTlQgV0lOQVBJIEdldEdlb0luZm9BKEdFT0lEIEdlb0lkLCBHRU9UWVBFIEdlb1R5cGUsIExQU1RSIGxwR2VvRGF0YSwgCiAgICAgICAgICAgICAgICBpbnQgY2NoRGF0YSwgTEFOR0lEIGxhbmd1YWdlKQp7CiAgICBGSVhNRSgiJWQgJWQgJXAgJWQgJWRcbiIsIEdlb0lkLCBHZW9UeXBlLCBscEdlb0RhdGEsIGNjaERhdGEsIGxhbmd1YWdlKTsKICAgIHJldHVybiAwOwp9Cg==