LyoKICogVGhlIHBhcmFtZXRlcnMgb2YgbWFueSBmdW5jdGlvbnMgY2hhbmdlcyBiZXR3ZWVuIGRpZmZlcmVudCBPUyB2ZXJzaW9ucwogKiAoTlQgdXNlcyBVbmljb2RlIHN0cmluZ3MsIDk1IHVzZXMgQVNDSUkgc3RyaW5ncykKICogCiAqIENvcHlyaWdodCAxOTk3IE1hcmN1cyBNZWlzc25lcgogKiAgICAgICAgICAgMTk5OCBK/HJnZW4gU2NobWllZAogKi8KI2luY2x1ZGUgPHN0cmluZy5oPgojaW5jbHVkZSAid2luZXJyb3IuaCIKI2luY2x1ZGUgIndpbnJlZy5oIgojaW5jbHVkZSAiZGVidWd0b29scy5oIgojaW5jbHVkZSAid2lubmxzLmgiCiNpbmNsdWRlICJ3aW52ZXJzaW9uLmgiCiNpbmNsdWRlICJoZWFwLmgiCgojaW5jbHVkZSAic2hlbGxhcGkuaCIKI2luY2x1ZGUgInNobG9iai5oIgojaW5jbHVkZSAic2hlbGwzMl9tYWluLmgiCiNpbmNsdWRlICJ3aW5lL3VuZG9jc2hlbGwuaCIKI2luY2x1ZGUgInNocG9saWN5LmgiCgpERUZBVUxUX0RFQlVHX0NIQU5ORUwoc2hlbGwpCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBTSENoYW5nZU5vdGlmeVJlZ2lzdGVyCQkJW1NIRUxMMzIuMl0KICoKICogTk9URVMKICogICBJZGxpc3QgaXMgYW4gYXJyYXkgb2Ygc3RydWN0dXJlcyBhbmQgQ291bnQgc3BlY2lmaWVzIGhvdyBtYW55IGl0ZW1zIGluIHRoZSBhcnJheQogKiAgICh1c3VhbGx5IGp1c3Qgb25lIEkgdGhpbmspLgogKi8KRFdPUkQgV0lOQVBJClNIQ2hhbmdlTm90aWZ5UmVnaXN0ZXIoCiAgICBIV05EIGh3bmQsCiAgICBMT05HIGV2ZW50czEsCiAgICBMT05HIGV2ZW50czIsCiAgICBEV09SRCBtc2csCiAgICBpbnQgY291bnQsCiAgICBJRFNUUlVDVCAqaWRsaXN0KQp7CUZJWE1FKCIoMHglMDR4LDB4JTA4bHgsMHglMDhseCwweCUwOGx4LDB4JTA4eCwlcCk6c3R1Yi5cbiIsCgkJaHduZCxldmVudHMxLGV2ZW50czIsbXNnLGNvdW50LGlkbGlzdCk7CglyZXR1cm4gMDsKfQovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBTSENoYW5nZU5vdGlmeURlcmVnaXN0ZXIJCQlbU0hFTEwzMi40XQogKi8KRFdPUkQgV0lOQVBJClNIQ2hhbmdlTm90aWZ5RGVyZWdpc3RlcihMT05HIHgxKQp7CUZJWE1FKCIoMHglMDhseCk6c3R1Yi5cbiIseDEpOwoJcmV0dXJuIDA7Cn0KLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogTlRTSENoYW5nZU5vdGlmeVJlZ2lzdGVyCQkJW1NIRUxMMzIuNjQwXQogKiBOT1RFUwogKiAgIElkbGlzdCBpcyBhbiBhcnJheSBvZiBzdHJ1Y3R1cmVzIGFuZCBDb3VudCBzcGVjaWZpZXMgaG93IG1hbnkgaXRlbXMgaW4gdGhlIGFycmF5CiAqICAgKHVzdWFsbHkganVzdCBvbmUgSSB0aGluaykuCiAqLwpEV09SRCBXSU5BUEkgTlRTSENoYW5nZU5vdGlmeVJlZ2lzdGVyKAogICAgSFdORCBod25kLAogICAgTE9ORyBldmVudHMxLAogICAgTE9ORyBldmVudHMyLAogICAgRFdPUkQgbXNnLAogICAgaW50IGNvdW50LAogICAgSURTVFJVQ1QgKmlkbGlzdCkKewlGSVhNRSgiKDB4JTA0eCwweCUwOGx4LDB4JTA4bHgsMHglMDhseCwweCUwOHgsJXApOnN0dWIuXG4iLAoJCWh3bmQsZXZlbnRzMSxldmVudHMyLG1zZyxjb3VudCxpZGxpc3QpOwoJcmV0dXJuIDA7Cn0KLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogTlRTSENoYW5nZU5vdGlmeURlcmVnaXN0ZXIJCQlbU0hFTEwzMi42NDFdCiAqLwpEV09SRCBXSU5BUEkgTlRTSENoYW5nZU5vdGlmeURlcmVnaXN0ZXIoTE9ORyB4MSkKewlGSVhNRSgiKDB4JTA4bHgpOnN0dWIuXG4iLHgxKTsKCXJldHVybiAwOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBQYXJzZUZpZWxkCQkJCQlbU0hFTEwzMi41OF0KICoKICovCkRXT1JEIFdJTkFQSSBQYXJzZUZpZWxkQShMUENTVFIgc3JjLCBEV09SRCBmaWVsZCwgTFBTVFIgZHN0LCBEV09SRCBsZW4pIAp7CVdBUk4oIignJXMnLDB4JTA4bHgsJXAsJWxkKSBzZW1pLXN0dWIuXG4iLHNyYyxmaWVsZCxkc3QsbGVuKTsKCglpZiAoIXNyYyB8fCAhc3JjWzBdIHx8ICFkc3QgfHwgIWxlbikKCSAgcmV0dXJuIDA7CgoJaWYgKGZpZWxkID4xKQoJeyBmaWVsZC0tOwkKCSAgd2hpbGUgKGZpZWxkKQoJICB7IGlmICgqc3JjPT0weDApIHJldHVybiBGQUxTRTsKCSAgICBpZiAoKnNyYz09JywnKSBmaWVsZC0tOwoJICAgIHNyYysrOwoJICB9Cgl9CgoJd2hpbGUgKCpzcmMhPTB4MDAgJiYgKnNyYyE9JywnICYmIGxlbj4wKSAKCXsgKmRzdD0qc3JjOyBkc3QrKywgc3JjKys7IGxlbi0tOwoJfQoJKmRzdD0weDA7CgkKCXJldHVybiBUUlVFOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBQaWNrSWNvbkRsZwkJCQkJW1NIRUxMMzIuNjJdCiAqIAogKi8KRFdPUkQgV0lOQVBJIFBpY2tJY29uRGxnKERXT1JEIHgsRFdPUkQgeSxEV09SRCB6LERXT1JEIGEpIAp7CUZJWE1FKCIoJTA4bHgsJTA4bHgsJTA4bHgsJTA4bHgpOnN0dWIuXG4iLHgseSx6LGEpOwoJcmV0dXJuIDB4ZmZmZmZmZmY7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIEdldEZpbGVOYW1lRnJvbUJyb3dzZQkJCVtTSEVMTDMyLjYzXQogKiAKICovCkRXT1JEIFdJTkFQSSBHZXRGaWxlTmFtZUZyb21Ccm93c2UoSFdORCBob3duZXIsIExQU1RSIHRhcmdldGJ1ZiwgRFdPUkQgbGVuLCBEV09SRCB4LCBMUENTVFIgc3VmZml4LCBMUENTVFIgeSwgTFBDU1RSIGNtZCkgCnsJRklYTUUoIiglMDR4LCVwLCVsZCwlMDhseCwlcywlcywlcyk6c3R1Yi5cbiIsCgkgICAgaG93bmVyLHRhcmdldGJ1ZixsZW4seCxzdWZmaXgseSxjbWQpOwogICAgLyogcHV0cyB1cCBhIE9wZW4gRGlhbG9nIGFuZCByZXF1ZXN0cyBpbnB1dCBpbnRvIHRhcmdldGJ1ZiAqLwogICAgLyogT0ZOX0hJREVSRUFET05MWXxPRk5fTk9DSEFOR0VESVJ8T0ZOX0ZJTEVNVVNURVhJU1R8T0ZOX3Vua25vd24gKi8KICAgIGxzdHJjcHlBKHRhcmdldGJ1ZiwieDpcXGR1bW15LmV4ZSIpOwogICAgcmV0dXJuIDE7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFNIR2V0U2V0dGluZ3MJCQkJW1NIRUxMMzIuNjhdCiAqIAogKiBOT1RFUwogKiAgdGhlIHJlZ2lzdHJ5IHBhdGggYXJlIGZvciB3aW45OCAodGVzdGVkKQogKiAgYW5kIHBvc3NpYmx5IGFyZSB0aGUgc2FtZSBpbiBudDQwCiAqLwp2b2lkIFdJTkFQSSBTSEdldFNldHRpbmdzKExQU0hFTExGTEFHU1RBVEUgbHBzZnMsIERXT1JEIGR3TWFzaywgRFdPUkQgZHd4KQp7CglIS0VZCWhLZXk7CglEV09SRAlkd0RhdGE7CglEV09SRAlkd0RhdGFTaXplID0gc2l6ZW9mIChEV09SRCk7CgoJVFJBQ0UoIiglcCAweCUwOGx4IDB4JTA4bHgpXG4iLGxwc2ZzLGR3TWFzaywgZHd4KTsKCQoJaWYgKFJlZ0NyZWF0ZUtleUV4QShIS0VZX0NVUlJFTlRfVVNFUiwgIlNvZnR3YXJlXFxNaWNyb3NvZnRcXFdpbmRvd3NcXEN1cnJlbnRWZXJzaW9uXFxFeHBsb3JlclxcQWR2YW5jZWQiLAoJCQkJIDAsIDAsIDAsIEtFWV9BTExfQUNDRVNTLCAwLCAmaEtleSwgMCkpCgkgIHJldHVybjsKCQoJaWYgKCAoU1NGX1NIT1dFWFRFTlNJT05TICYgZHdNYXNrKSAmJiAhUmVnUXVlcnlWYWx1ZUV4QShoS2V5LCAiSGlkZUZpbGVFeHQiLCAwLCAwLCAoTFBCWVRFKSZkd0RhdGEsICZkd0RhdGFTaXplKSkKCSAgbHBzZnMtPmZTaG93RXh0ZW5zaW9ucyAgPSAoKGR3RGF0YSA9PSAwKSA/ICAwIDogMSk7CgoJaWYgKCAoU1NGX1NIT1dJTkZPVElQICYgZHdNYXNrKSAmJiAhUmVnUXVlcnlWYWx1ZUV4QShoS2V5LCAiU2hvd0luZm9UaXAiLCAwLCAwLCAoTFBCWVRFKSZkd0RhdGEsICZkd0RhdGFTaXplKSkKCSAgbHBzZnMtPmZTaG93SW5mb1RpcCAgPSAoKGR3RGF0YSA9PSAwKSA/ICAwIDogMSk7CgoJaWYgKCAoU1NGX0RPTlRQUkVUVFlQQVRIICYgZHdNYXNrKSAmJiAhUmVnUXVlcnlWYWx1ZUV4QShoS2V5LCAiRG9udFByZXR0eVBhdGgiLCAwLCAwLCAoTFBCWVRFKSZkd0RhdGEsICZkd0RhdGFTaXplKSkKCSAgbHBzZnMtPmZEb250UHJldHR5UGF0aCAgPSAoKGR3RGF0YSA9PSAwKSA/ICAwIDogMSk7CgoJaWYgKCAoU1NGX0hJREVJQ09OUyAmIGR3TWFzaykgJiYgIVJlZ1F1ZXJ5VmFsdWVFeEEoaEtleSwgIkhpZGVJY29ucyIsIDAsIDAsIChMUEJZVEUpJmR3RGF0YSwgJmR3RGF0YVNpemUpKQoJICBscHNmcy0+ZkhpZGVJY29ucyAgPSAoKGR3RGF0YSA9PSAwKSA/ICAwIDogMSk7CgoJaWYgKCAoU1NGX01BUE5FVERSVkJVVFRPTiAmIGR3TWFzaykgJiYgIVJlZ1F1ZXJ5VmFsdWVFeEEoaEtleSwgIk1hcE5ldERydkJ0biIsIDAsIDAsIChMUEJZVEUpJmR3RGF0YSwgJmR3RGF0YVNpemUpKQoJICBscHNmcy0+Zk1hcE5ldERydkJ0biAgPSAoKGR3RGF0YSA9PSAwKSA/ICAwIDogMSk7CgoJaWYgKCAoU1NGX1NIT1dBVFRSSUJDT0wgJiBkd01hc2spICYmICFSZWdRdWVyeVZhbHVlRXhBKGhLZXksICJTaG93QXR0cmliQ29sIiwgMCwgMCwgKExQQllURSkmZHdEYXRhLCAmZHdEYXRhU2l6ZSkpCgkgIGxwc2ZzLT5mU2hvd0F0dHJpYkNvbCAgPSAoKGR3RGF0YSA9PSAwKSA/ICAwIDogMSk7CgoJaWYgKCgoU1NGX1NIT1dBTExPQkpFQ1RTIHwgU1NGX1NIT1dTWVNGSUxFUykgJiBkd01hc2spICYmICFSZWdRdWVyeVZhbHVlRXhBKGhLZXksICJIaWRkZW4iLCAwLCAwLCAoTFBCWVRFKSZkd0RhdGEsICZkd0RhdGFTaXplKSkKCXsgaWYgKGR3RGF0YSA9PSAwKQoJICB7IGlmIChTU0ZfU0hPV0FMTE9CSkVDVFMgJiBkd01hc2spCWxwc2ZzLT5mU2hvd0FsbE9iamVjdHMgID0gMDsKCSAgICBpZiAoU1NGX1NIT1dTWVNGSUxFUyAmIGR3TWFzaykJbHBzZnMtPmZTaG93U3lzRmlsZXMgID0gMDsKCSAgfQoJICBlbHNlIGlmIChkd0RhdGEgPT0gMSkKCSAgeyBpZiAoU1NGX1NIT1dBTExPQkpFQ1RTICYgZHdNYXNrKQlscHNmcy0+ZlNob3dBbGxPYmplY3RzICA9IDE7CgkgICAgaWYgKFNTRl9TSE9XU1lTRklMRVMgJiBkd01hc2spCWxwc2ZzLT5mU2hvd1N5c0ZpbGVzICA9IDA7CgkgIH0KCSAgZWxzZSBpZiAoZHdEYXRhID09IDIpCgkgIHsgaWYgKFNTRl9TSE9XQUxMT0JKRUNUUyAmIGR3TWFzaykJbHBzZnMtPmZTaG93QWxsT2JqZWN0cyAgPSAwOwoJICAgIGlmIChTU0ZfU0hPV1NZU0ZJTEVTICYgZHdNYXNrKQlscHNmcy0+ZlNob3dTeXNGaWxlcyAgPSAxOwoJICB9Cgl9CglSZWdDbG9zZUtleSAoaEtleSk7CgoJVFJBQ0UoIi0tIDB4JTA0eFxuIiwgKihXT1JEKilscHNmcyk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFNIU2hlbGxGb2xkZXJWaWV3X01lc3NhZ2UJCQlbU0hFTEwzMi43M10KICoKICogUEFSQU1FVEVSUwogKiAgaHduZENhYmluZXQgZGVmaW5lcyB0aGUgZXhwbG9yZXIgY2FiaW5ldCB3aW5kb3cgdGhhdCBjb250YWlucyB0aGUgCiAqICAgICAgICAgICAgICBzaGVsbHZpZXcgeW91IG5lZWQgdG8gY29tbXVuaWNhdGUgd2l0aAogKiAgdU1zZyAgICAgICAgaWRlbnRpZnlpbmcgdGhlIFNGVk0gZW51bSB0byBwZXJmb3JtCiAqICBsUGFyYW0KICoKICogTk9URVMKICogIE1lc3NhZ2UgU0ZWTV9SRUFSUkFOR0UgPSAxCiAqICAgIFRoaXMgbWVzc2FnZSBnZXRzIHNlbnQgd2hlbiBhIGNvbHVtbiBnZXRzIGNsaWNrZWQgdG8gaW5zdHJ1Y3QgdGhlCiAqICAgIHNoZWxsIHZpZXcgdG8gcmUtc29ydCB0aGUgaXRlbSBsaXN0LiBsUGFyYW0gaWRlbnRpZmllcyB0aGUgY29sdW1uCiAqICAgIHRoYXQgd2FzIGNsaWNrZWQuCiAqLwppbnQgV0lOQVBJIFNIU2hlbGxGb2xkZXJWaWV3X01lc3NhZ2UoSFdORCBod25kQ2FiaW5ldCxVSU5UIHVNc2csTFBBUkFNIGxQYXJhbSkKeyBGSVhNRSgiJTA0eCAlMDh1eCAlMDhseCBzdHViXG4iLGh3bmRDYWJpbmV0LHVNc2csbFBhcmFtKTsKICByZXR1cm4gMDsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogT2xlU3RyVG9TdHJOCQkJCQlbU0hFTEwzMi43OF0KICovCkJPT0wgV0lOQVBJIE9sZVN0clRvU3RyTkEgKExQU1RSIGxwU3RyLCBJTlQgblN0ciwgTFBDV1NUUiBscE9sZSwgSU5UIG5PbGUpIAp7CglUUkFDRSgiKCVwLCAleCwgJXMsICV4KVxuIiwgbHBTdHIsIG5TdHIsIGRlYnVnc3RyX3duKGxwT2xlLG5PbGUpLCBuT2xlKTsKCXJldHVybiBXaWRlQ2hhclRvTXVsdGlCeXRlICgwLCAwLCBscE9sZSwgbk9sZSwgbHBTdHIsIG5TdHIsIE5VTEwsIE5VTEwpOwp9CgpCT09MIFdJTkFQSSBPbGVTdHJUb1N0ck5XIChMUFdTVFIgbHB3U3RyLCBJTlQgbndTdHIsIExQQ1dTVFIgbHBPbGUsIElOVCBuT2xlKSAKewoJVFJBQ0UoIiglcCwgJXgsICVzLCAleClcbiIsIGxwd1N0ciwgbndTdHIsIGRlYnVnc3RyX3duKGxwT2xlLG5PbGUpLCBuT2xlKTsKCglpZiAobHN0cmNweW5XICggbHB3U3RyLCBscE9sZSwgbndTdHIpKQoJeyByZXR1cm4gbHN0cmxlblcgKGxwd1N0cik7Cgl9CglyZXR1cm4gMDsKfQoKQk9PTCBXSU5BUEkgT2xlU3RyVG9TdHJOQVcgKExQVk9JRCBscE91dCwgSU5UIG5PdXQsIExQQ1ZPSUQgbHBJbiwgSU5UIG5JbikgCnsKCWlmIChWRVJTSU9OX09zSXNVbmljb2RlKCkpCgkgIHJldHVybiBPbGVTdHJUb1N0ck5XIChscE91dCwgbk91dCwgbHBJbiwgbkluKTsKCXJldHVybiBPbGVTdHJUb1N0ck5BIChscE91dCwgbk91dCwgbHBJbiwgbkluKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogU3RyVG9PbGVTdHJOCQkJCQlbU0hFTEwzMi43OV0KICogIGxwTXVsdGksIG5NdWx0aSwgbldpZGUgW0lOXQogKiAgbHBXaWRlIFtPVVRdCiAqLwpCT09MIFdJTkFQSSBTdHJUb09sZVN0ck5BIChMUFdTVFIgbHBXaWRlLCBJTlQgbldpZGUsIExQQ1NUUiBscFN0ckEsIElOVCBuU3RyKSAKewoJVFJBQ0UoIiglcCwgJXgsICVzLCAleClcbiIsIGxwV2lkZSwgbldpZGUsIGRlYnVnc3RyX2FuKGxwU3RyQSxuU3RyKSwgblN0cik7CglyZXR1cm4gTXVsdGlCeXRlVG9XaWRlQ2hhciAoMCwgMCwgbHBTdHJBLCBuU3RyLCBscFdpZGUsIG5XaWRlKTsKfQpCT09MIFdJTkFQSSBTdHJUb09sZVN0ck5XIChMUFdTVFIgbHBXaWRlLCBJTlQgbldpZGUsIExQQ1dTVFIgbHBTdHJXLCBJTlQgblN0cikgCnsKCVRSQUNFKCIoJXAsICV4LCAlcywgJXgpXG4iLCBscFdpZGUsIG5XaWRlLCBkZWJ1Z3N0cl93bihscFN0clcsIG5TdHIpLCBuU3RyKTsKCglpZiAobHN0cmNweW5XIChscFdpZGUsIGxwU3RyVywgbldpZGUpKQoJeyByZXR1cm4gbHN0cmxlblcgKGxwV2lkZSk7Cgl9CglyZXR1cm4gMDsKfQoKQk9PTCBXSU5BUEkgU3RyVG9PbGVTdHJOQVcgKExQV1NUUiBscFdpZGUsIElOVCBuV2lkZSwgTFBDVk9JRCBscFN0ciwgSU5UIG5TdHIpIAp7CglpZiAoVkVSU0lPTl9Pc0lzVW5pY29kZSgpKQoJICByZXR1cm4gU3RyVG9PbGVTdHJOVyAobHBXaWRlLCBuV2lkZSwgbHBTdHIsIG5TdHIpOwoJcmV0dXJuIFN0clRvT2xlU3RyTkEgKGxwV2lkZSwgbldpZGUsIGxwU3RyLCBuU3RyKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogUmVnaXN0ZXJTaGVsbEhvb2sJCQkJW1NIRUxMMzIuMTgxXQogKgogKiBQQVJBTVMKICogICAgICBod25kIFtJXSAgd2luZG93IGhhbmRsZQogKiAgICAgIHkgICAgW0ldICBmbGFnID8/Pz8KICogCiAqIE5PVEVTCiAqICAgICBleHBvcnRlZCBieSBvcmRpbmFsCiAqLwp2b2lkIFdJTkFQSSBSZWdpc3RlclNoZWxsSG9vayhIV05EIGh3bmQsIERXT1JEIHkpIHsKICAgIEZJWE1FKCIoMHglMDh4LDB4JTA4bHgpOnN0dWIuXG4iLGh3bmQseSk7Cn0KLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogU2hlbGxNZXNzYWdlQm94VwkJCQlbU0hFTEwzMi4xODJdCiAqCiAqIEZvcm1hdCBhbmQgb3V0cHV0IGVycm9ybWVzc2FnZS4KICoKICogaWRUZXh0CXJlc291cmNlIElEIG9mIHRpdGxlIG9yIExQU1RSCiAqIGlkVGl0bGUJcmVzb3VyY2UgSUQgb2YgdGl0bGUgb3IgTFBTVFIKICoKICogTk9URVMKICogICAgIGV4cG9ydGVkIGJ5IG9yZGluYWwKICovCklOVCBfX2NkZWNsClNoZWxsTWVzc2FnZUJveFcoSE1PRFVMRSBobW9kLEhXTkQgaHduZCxEV09SRCBpZFRleHQsRFdPUkQgaWRUaXRsZSxEV09SRCB1VHlwZSxMUENWT0lEIGFyZ2xpc3QpIAp7CVdDSEFSCXN6VGV4dFsxMDBdLHN6VGl0bGVbMTAwXSxzelRlbXBbMjU2XTsKCUxQV1NUUiAgIHBzelRleHQgPSAmc3pUZXh0WzBdLCBwc3pUaXRsZSA9ICZzelRpdGxlWzBdOwoJTFBWT0lECWFyZ3MgPSAmYXJnbGlzdDsKCglUUkFDRSgiKCUwOGx4LCUwOGx4LCUwOGx4LCUwOGx4LCUwOGx4LCVwKVxuIiwoRFdPUkQpaG1vZCwoRFdPUkQpaHduZCxpZFRleHQsaWRUaXRsZSx1VHlwZSxhcmdsaXN0KTsKCglpZiAoIUhJV09SRCAoaWRUaXRsZSkpCgkgIExvYWRTdHJpbmdXKGhtb2QsaWRUaXRsZSxwc3pUaXRsZSwxMDApOwoJZWxzZQoJICBwc3pUaXRsZSA9IChMUFdTVFIpaWRUaXRsZTsKCglpZiAoISBISVdPUkQgKGlkVGV4dCkpCgkgIExvYWRTdHJpbmdXKGhtb2QsaWRUZXh0LHBzelRleHQsMTAwKTsKCWVsc2UKCSAgcHN6VGV4dCA9IChMUFdTVFIpaWRUZXh0OwoKCUZvcm1hdE1lc3NhZ2VXKEZPUk1BVF9NRVNTQUdFX0ZST01fU1RSSU5HIHwgRk9STUFUX01FU1NBR0VfQVJHVU1FTlRfQVJSQVkgLHN6VGV4dCwwLDAsc3pUZW1wLDI1NixhcmdzKTsKCXJldHVybiBNZXNzYWdlQm94Vyhod25kLHN6VGVtcCxzelRpdGxlLHVUeXBlKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogU2hlbGxNZXNzYWdlQm94QQkJCQlbU0hFTEwzMi4xODNdCiAqLwpJTlQgX19jZGVjbApTaGVsbE1lc3NhZ2VCb3hBKEhNT0RVTEUgaG1vZCxIV05EIGh3bmQsRFdPUkQgaWRUZXh0LERXT1JEIGlkVGl0bGUsRFdPUkQgdVR5cGUsTFBDVk9JRCBhcmdsaXN0KSAKewljaGFyCXN6VGV4dFsxMDBdLHN6VGl0bGVbMTAwXSxzelRlbXBbMjU2XTsKCUxQU1RSICAgcHN6VGV4dCA9ICZzelRleHRbMF0sIHBzelRpdGxlID0gJnN6VGl0bGVbMF07CglMUFZPSUQJYXJncyA9ICZhcmdsaXN0OwoKCVRSQUNFKCIoJTA4bHgsJTA4bHgsJTA4bHgsJTA4bHgsJTA4bHgsJXApXG4iLCAoRFdPUkQpaG1vZCwoRFdPUkQpaHduZCxpZFRleHQsaWRUaXRsZSx1VHlwZSxhcmdsaXN0KTsKCglpZiAoIUhJV09SRCAoaWRUaXRsZSkpCgkgIExvYWRTdHJpbmdBKGhtb2QsaWRUaXRsZSxwc3pUaXRsZSwxMDApOwoJZWxzZQoJICBwc3pUaXRsZSA9IChMUFNUUilpZFRpdGxlOwoKCWlmICghIEhJV09SRCAoaWRUZXh0KSkKCSAgTG9hZFN0cmluZ0EoaG1vZCxpZFRleHQscHN6VGV4dCwxMDApOwoJZWxzZQoJICBwc3pUZXh0ID0gKExQU1RSKWlkVGV4dDsKCglGb3JtYXRNZXNzYWdlQShGT1JNQVRfTUVTU0FHRV9GUk9NX1NUUklORyB8IEZPUk1BVF9NRVNTQUdFX0FSR1VNRU5UX0FSUkFZICxwc3pUZXh0LDAsMCxzelRlbXAsMjU2LGFyZ3MpOwoJcmV0dXJuIE1lc3NhZ2VCb3hBKGh3bmQsc3pUZW1wLHBzelRpdGxlLHVUeXBlKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogU0hSZXN0cmljdGVkCQkJCVtTSEVMTDMyLjEwMF0KICoKICogd2Fsa3MgdGhyb3VnaCBwb2xpY3kgdGFibGUsIHF1ZXJpZXMgPGFwcD4ga2V5LCA8dHlwZT4gdmFsdWUsIHJldHVybnMgCiAqIHF1ZXJpZWQgKERXT1JEKSB2YWx1ZSwgYW5kIGNhY2hlcyBpdCBiZXR3ZWVuIGNhbGxlZCB0byBTSEluaXRSZXN0cmljdGVkCiAqIHRvIHByZXZlbnQgdW5uZWNlc3NhcnkgcmVnaXN0cnkgYWNjZXNzLgogKgogKiBOT1RFUwogKiAgICAgZXhwb3J0ZWQgYnkgb3JkaW5hbAogKgogKiBSRUZFUkVOQ0VTOiAKICogICAgIE1TIFN5c3RlbSBQb2xpY3kgRWRpdG9yCiAqICAgICA5OExpdGUgMi4wICh3aGljaCB1c2VzIG1hbnkgb2YgdGhlc2UgcG9saWN5IGtleXMpIGh0dHA6Ly93d3cuOThsaXRlLm5ldC8KICogICAgICJUaGUgV2luZG93cyA5NSBSZWdpc3RyeSIsIGJ5IEpvaG4gV29yYW0sIDE5OTYgTUlTOiBQcmVzcwogKi8KRFdPUkQgV0lOQVBJIFNIUmVzdHJpY3RlZCAoRFdPUkQgcG9sKSB7CiAgICAgICAgY2hhciByZWdzdHJbMjU2XTsKCUhLRVkJeGhrZXk7CglEV09SRCAgIHJldHZhbCwgcG9saWR4LCBpLCBkYXRzaXplID0gNDsKCglUUkFDRSgiKCUwOGx4KVxuIixwb2wpOwoKCXBvbGlkeCA9IC0xOwoKCS8qIHNjYW4gdG8gc2VlIGlmIHdlIGtub3cgdGhpcyBwb2xpY3kgSUQgKi8KCWZvciAoaSA9IDA7IGkgPCBTSEVMTF9NQVhfUE9MSUNJRVM7IGkrKykKCXsKCSAgICAgaWYgKHBvbCA9PSBzaDMyX3BvbGljeV90YWJsZVtpXS5wb2xmbGFncykKCSAgICAgewoJICAgICAgICAgcG9saWR4ID0gaTsKCQkgYnJlYWs7CgkgICAgIH0KCX0KCglpZiAocG9saWR4ID09IC0xKQoJewoJICAgIC8qIHdlIGRvbid0IGtub3cgdGhpcyBwb2xpY3ksIHJldHVybiAwICovCgkgICAgVFJBQ0UoInVua25vd24gcG9saWN5OiAoJTA4bHgpXG4iLCBwb2wpOwoJCXJldHVybiAwOwoJfQoKCS8qIHdlIGhhdmUgYSBrbm93biBwb2xpY3kgKi8KICAgICAgCWxzdHJjcHlBKHJlZ3N0ciwgIlNvZnR3YXJlXFxNaWNyb3NvZnRcXFdpbmRvd3NcXEN1cnJlbnRWZXJzaW9uXFxQb2xpY2llc1xcIik7Cglsc3RyY2F0QShyZWdzdHIsIHNoMzJfcG9saWN5X3RhYmxlW3BvbGlkeF0uYXBwc3RyKTsKCgkvKiBmaXJzdCBjaGVjayBpZiB0aGlzIHBvbGljeSBoYXMgYmVlbiBjYWNoZWQsIHJldHVybiBpdCBpZiBzbyAqLwoJaWYgKHNoMzJfcG9saWN5X3RhYmxlW3BvbGlkeF0uY2FjaGUgIT0gU0hFTExfTk9fUE9MSUNZKQoJewoJICAgIHJldHVybiBzaDMyX3BvbGljeV90YWJsZVtwb2xpZHhdLmNhY2hlOwoJfQoKCS8qIHJldHVybiAwIGFuZCBkb24ndCBzZXQgdGhlIGNhY2hlIGlmIGFueSByZWdpc3RyeSBlcnJvcnMgb2NjdXIgKi8KCXJldHZhbCA9IDA7CglpZiAoUmVnT3BlbktleUEoSEtFWV9DVVJSRU5UX1VTRVIsIHJlZ3N0ciwgJnhoa2V5KSA9PSBFUlJPUl9TVUNDRVNTKQoJewoJICAgIGlmIChSZWdRdWVyeVZhbHVlRXhBKHhoa2V5LCBzaDMyX3BvbGljeV90YWJsZVtwb2xpZHhdLmtleXN0ciwgTlVMTCwgTlVMTCwgKExQQllURSkmcmV0dmFsLCAmZGF0c2l6ZSkgPT0gRVJST1JfU1VDQ0VTUykKCSAgICB7CgkgICAgICAgIHNoMzJfcG9saWN5X3RhYmxlW3BvbGlkeF0uY2FjaGUgPSByZXR2YWw7CgkgICAgfQoKCVJlZ0Nsb3NlS2V5KHhoa2V5KTsKfQoKCXJldHVybiByZXR2YWw7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgU0hJbml0UmVzdHJpY3RlZCAgICAgICAgICAgICAgICAgICAgICAgICBbU0hFTEwzMi4yNDRdCiAqCiAqIFdpbjk4KyBieS1vcmRpbmFsIG9ubHkgcm91dGluZSBjYWxsZWQgYnkgRXhwbG9yZXIgYW5kIE1TSUUgNCBhbmQgNS4KICogSW5pdHMgdGhlIHBvbGljeSBjYWNoZSB1c2VkIGJ5IFNIUmVzdHJpY3RlZCB0byBhdm9pZCBleGNlc3MKICogcmVnaXN0cnkgYWNjZXNzLgogKgogKiBJTlBVVFMKICogVHdvIGlucHV0czogb25lIGlzIGEgc3RyaW5nIG9yIE5VTEwuICBJZiBub24tTlVMTCB0aGUgcG9pbnRlcgogKiBzaG91bGQgcG9pbnQgdG8gYSBzdHJpbmcgY29udGFpbmluZyB0aGUgZm9sbG93aW5nIGV4YWN0IHRleHQ6CiAqICJTb2Z0d2FyZVxNaWNyb3NvZnRcV2luZG93c1xDdXJyZW50VmVyc2lvblxQb2xpY2llcyIuCiAqIFRoZSBvdGhlciBpbnB1dCBpcyB1bnVzZWQuCiAqCiAqIE5PVEVTCiAqIElmIHRoZSBpbnB1dCBpcyBub24tTlVMTCBhbmQgZG9lcyBub3QgcG9pbnQgdG8gYSBzdHJpbmcgY29udGFpbmluZwogKiB0aGF0IGV4YWN0IHRleHQgdGhlIHJvdXRpbmUgd2lsbCBkbyBub3RoaW5nLgogKgogKiBJZiB0aGUgdGV4dCBkb2VzIG1hdGNoIG9yIHRoZSBwb2ludGVyIGlzIE5VTEwsIHRoZW4gdGhlIHJvdXRpbmUKICogd2lsbCBpbml0IFNIUmVzdHJpY3RlZCgpJ3MgcG9saWN5IGNhY2hlIHRvIGFsbCAweGZmZmZmZmZmIGFuZAogKiByZXR1cm5zIDB4ZmZmZmZmZmYgYXMgd2VsbC4KICoKICogSSBoYXZlbid0IHlldCBydW4gaW50byBhbnl0aGluZyBjYWxsaW5nIHRoaXMgd2l0aCBpbnB1dHMgb3RoZXIgdGhhbgogKiAoTlVMTCwgTlVMTCksIHNvIEkgbWF5IGhhdmUgdGhlIGlucHV0cyByZXZlcnNlZC4KICovCgpCT09MIFdJTkFQSSBTSEluaXRSZXN0cmljdGVkKExQU1RSIGlucFJlZ0tleSwgTFBTVFIgcGFybTIpCnsKICAgICBpbnQgaTsKCiAgICAgVFJBQ0UoIiglcCwgJXApXG4iLCBpbnBSZWdLZXksIHBhcm0yKTsKCiAgICAgLyogZmlyc3QgY2hlY2sgLSBpZiBpbnB1dCBpcyBub24tTlVMTCBhbmQgcG9pbnRzIHRvIHRoZSBzZWNyZXQKICAgICAgICBrZXkgc3RyaW5nLCB0aGVuIHBhc3MuICBPdGhlcndpc2UgcmV0dXJuIDAuCiAgICAgKi8KCiAgICAgaWYgKGlucFJlZ0tleSAhPSAoTFBTVFIpTlVMTCkKICAgICB7CiAgICAgICAgIGlmIChsc3RyY21waUEoaW5wUmVnS2V5LCAiU29mdHdhcmVcXE1pY3Jvc29mdFxcV2luZG93c1xcQ3VycmVudFZlcnNpb25cXFBvbGljaWVzIikpCgkgewoJICAgICAvKiBkb2Vzbid0IG1hdGNoLCBmYWlsICovCgkgICAgIHJldHVybiAwOwoJIH0KICAgICB9ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAoKICAgICAvKiBjaGVjayBwYXNzZWQsIGluaXQgYWxsIHBvbGljeSBjYWNoZSBlbnRyaWVzIHdpdGggU0hFTExfTk9fUE9MSUNZICovCiAgICAgZm9yIChpID0gMDsgaSA8IFNIRUxMX01BWF9QT0xJQ0lFUzsgaSsrKQogICAgIHsKICAgICAgICAgIHNoMzJfcG9saWN5X3RhYmxlW2ldLmNhY2hlID0gU0hFTExfTk9fUE9MSUNZOwogICAgIH0KCiAgICAgcmV0dXJuIFNIRUxMX05PX1BPTElDWTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogU0hDcmVhdGVEaXJlY3RvcnkJCQkJW1NIRUxMMzIuMTY1XQogKgogKiBOT1RFUwogKiAgZXhwb3J0ZWQgYnkgb3JkaW5hbAogKiAgbm90IHN1cmUgYWJvdXQgTFBTRUNVUklUWV9BVFRSSUJVVEVTCiAqLwpEV09SRCBXSU5BUEkgU0hDcmVhdGVEaXJlY3RvcnkoTFBTRUNVUklUWV9BVFRSSUJVVEVTIHNlYyxMUENTVFIgcGF0aCkgewoJVFJBQ0UoIiglcCwlcyk6c3R1Yi5cbiIsc2VjLHBhdGgpOwoJaWYgKENyZWF0ZURpcmVjdG9yeUEocGF0aCxzZWMpKQoJCXJldHVybiBUUlVFOwoJLyogU0hDaGFuZ2VOb3RpZnkoOCwxLHBhdGgsMCk7ICovCglyZXR1cm4gRkFMU0U7CiNpZiAwCglpZiAoU0hFTEwzMl83OShwYXRoLChMUFZPSUQpeCkpCgkJcmV0dXJuIDA7CglGSVhNRSgiKCUwOGx4LCVzKTpzdHViLlxuIix4LHBhdGgpOwoJcmV0dXJuIDA7CiNlbmRpZgp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBTSEZyZWUJCQkJCVtTSEVMTDMyLjE5NV0KICoKICogTk9URVMKICogICAgIGZyZWVfcHRyKCkgLSBmcmVlcyBtZW1vcnkgdXNpbmcgSU1hbGxvYwogKiAgICAgZXhwb3J0ZWQgYnkgb3JkaW5hbAogKi8KI2RlZmluZSBNRU1fREVCVUcgMApEV09SRCBXSU5BUEkgU0hGcmVlKExQVk9JRCB4KSAKewojaWYgTUVNX0RFQlVHCglXT1JEIGxlbiA9ICooTFBXT1JEKSh4LTIpOwoKCWlmICggKihMUFdPUkQpKHgrbGVuKSAhPSAweDczODQpCgkgIEVSUigiTUFHSUMyIVxuIik7CgoJaWYgKCAoKihMUFdPUkQpKHgtNCkpICE9IDB4ODI3MSkKCSAgRVJSKCJNQUdJQzEhXG4iKTsKCWVsc2UKCSAgbWVtc2V0KHgtNCwgMHhkZSwgbGVuKzYpOwoKCVRSQUNFKCIlcCBsZW49JXVcbiIseCwgbGVuKTsKCgl4IC09IDQ7CiNlbHNlCglUUkFDRSgiJXBcbiIseCk7CiNlbmRpZgoJcmV0dXJuIEhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksIDAsIHgpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBTSEFsbG9jCQkJCQlbU0hFTEwzMi4xOTZdCiAqCiAqIE5PVEVTCiAqICAgICB2b2lkICp0YXNrX2FsbG9jKERXT1JEIGxlbiksIHVzZXMgU0hNYWxsb2MgYWxsb2NhdG9yCiAqICAgICBleHBvcnRlZCBieSBvcmRpbmFsCiAqLwpMUFZPSUQgV0lOQVBJIFNIQWxsb2MoRFdPUkQgbGVuKSAKewoJTFBCWVRFIHJldDsKCiNpZiBNRU1fREVCVUcKCXJldCA9IChMUFZPSUQpIEhlYXBBbGxvYyhHZXRQcm9jZXNzSGVhcCgpLDAsbGVuKzYpOwojZWxzZQoJcmV0ID0gKExQVk9JRCkgSGVhcEFsbG9jKEdldFByb2Nlc3NIZWFwKCksMCxsZW4pOwojZW5kaWYKCiNpZiBNRU1fREVCVUcKCSooTFBXT1JEKShyZXQpID0gMHg4MjcxOwoJKihMUFdPUkQpKHJldCsyKSA9IChXT1JEKWxlbjsKCSooTFBXT1JEKShyZXQrNCtsZW4pID0gMHg3Mzg0OwoJcmV0ICs9IDQ7CgltZW1zZXQocmV0LCAweGRmLCBsZW4pOwojZW5kaWYKCVRSQUNFKCIlbHUgYnl0ZXMgYXQgJXBcbiIsbGVuLCByZXQpOwoJcmV0dXJuIChMUFZPSUQpcmV0Owp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBTSFJlZ2lzdGVyRHJhZ0Ryb3AJCQkJW1NIRUxMMzIuODZdCiAqCiAqIE5PVEVTCiAqICAgICBleHBvcnRlZCBieSBvcmRpbmFsCiAqLwpEV09SRCBXSU5BUEkgU0hSZWdpc3RlckRyYWdEcm9wKEhXTkQgaFduZCxJRHJvcFRhcmdldCAqIHBEcm9wVGFyZ2V0KSAKewoJRklYTUUoIigweCUwOHgsJXApOnN0dWIuXG4iLCBoV25kLCBwRHJvcFRhcmdldCk7CglyZXR1cm4gICAgIFJlZ2lzdGVyRHJhZ0Ryb3AoaFduZCwgcERyb3BUYXJnZXQpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBTSFJldm9rZURyYWdEcm9wCQkJCVtTSEVMTDMyLjg3XQogKgogKiBOT1RFUwogKiAgICAgZXhwb3J0ZWQgYnkgb3JkaW5hbAogKi8KRFdPUkQgV0lOQVBJIFNIUmV2b2tlRHJhZ0Ryb3AoRFdPUkQgeCkgewogICAgRklYTUUoIigweCUwOGx4KTpzdHViLlxuIix4KTsKICAgIHJldHVybiAwOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBTSERvRHJhZ0Ryb3AJCQkJCVtTSEVMTDMyLjg4XQogKgogKiBOT1RFUwogKiAgICAgZXhwb3J0ZWQgYnkgb3JkaW5hbAogKi8KRFdPUkQgV0lOQVBJIFNIRG9EcmFnRHJvcChEV09SRCB1LCBEV09SRCB2LCBEV09SRCB3LCBEV09SRCB4LCBEV09SRCB5LCBEV09SRCB6KSB7CiAgICBGSVhNRSgiKDB4JTA4bHggMHglMDhseCAweCUwOGx4IDB4JTA4bHggMHglMDhseCAweCUwOGx4KTpzdHViLlxuIix1LHYsdyx4LHkseik7CiAgICByZXR1cm4gMDsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogUnVuRmlsZURsZwkJCQkJW1NIRUxMMzIuNjFdCiAqCiAqIE5PVEVTCiAqICAgICBPcmlnaW5hbCBuYW1lOiBSdW5GaWxlRGxnIChleHBvcnRlZCBieSBvcmRpbmFsKQogKi8KRFdPUkQgV0lOQVBJClJ1bkZpbGVEbGcgKEhXTkQgaHduZE93bmVyLCBEV09SRCBkd1BhcmFtMSwgRFdPUkQgZHdQYXJhbTIsCgkgICAgTFBTVFIgbHBzelRpdGxlLCBMUFNUUiBscHN6UHJvbXB0LCBVSU5UIHVGbGFncykKewogICAgRklYTUUoIigweCUwOHggMHglbHggMHglbHggXCIlc1wiIFwiJXNcIiAweCV4KTpzdHViLlxuIiwKCSAgIGh3bmRPd25lciwgZHdQYXJhbTEsIGR3UGFyYW0yLCBscHN6VGl0bGUsIGxwc3pQcm9tcHQsIHVGbGFncyk7CiAgICByZXR1cm4gMDsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogRXhpdFdpbmRvd3NEaWFsb2cJCQkJW1NIRUxMMzIuNjBdCiAqCiAqIE5PVEVTCiAqICAgICBleHBvcnRlZCBieSBvcmRpbmFsCiAqLwp2b2lkIFdJTkFQSSBFeGl0V2luZG93c0RpYWxvZyAoSFdORCBoV25kT3duZXIpCnsKCVRSQUNFKCIoMHglMDh4KVxuIiwgaFduZE93bmVyKTsKCWlmIChNZXNzYWdlQm94QSggaFduZE93bmVyLCAiRG8geW91IHdhbnQgdG8gZXhpdCBXSU5FPyIsICJTaHV0ZG93biIsIE1CX1lFU05PfE1CX0lDT05RVUVTVElPTikgPT0gSURPSykKCXsgU2VuZE1lc3NhZ2VBICggaFduZE93bmVyLCBXTV9RVUlULCAwLCAwKTsKCX0KfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogQXJyYW5nZVdpbmRvd3MJCQkJW1NIRUxMMzIuMTg0XQogKiAKICovCkRXT1JEIFdJTkFQSQpBcnJhbmdlV2luZG93cyAoRFdPUkQgZHdQYXJhbTEsIERXT1JEIGR3UGFyYW0yLCBEV09SRCBkd1BhcmFtMywKCQlEV09SRCBkd1BhcmFtNCwgRFdPUkQgZHdQYXJhbTUpCnsKICAgIEZJWE1FKCIoMHglbHggMHglbHggMHglbHggMHglbHggMHglbHgpOnN0dWIuXG4iLAoJICAgZHdQYXJhbTEsIGR3UGFyYW0yLCBkd1BhcmFtMywgZHdQYXJhbTQsIGR3UGFyYW01KTsKICAgIHJldHVybiAwOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBTaWduYWxGaWxlT3BlbgkJCQlbU0hFTEwzMi4xMDNdCiAqCiAqIE5PVEVTCiAqICAgICBleHBvcnRlZCBieSBvcmRpbmFsCiAqLwpEV09SRCBXSU5BUEkKU2lnbmFsRmlsZU9wZW4gKERXT1JEIGR3UGFyYW0xKQp7CiAgICBGSVhNRSgiKDB4JTA4bHgpOnN0dWIuXG4iLCBkd1BhcmFtMSk7CgogICAgcmV0dXJuIDA7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFNIQWRkVG9SZWNlbnREb2NzCQkJCVtTSEVMTDMyLjIzNF0KICoKICogUEFSQU1FVEVSUwogKiAgIHVGbGFncyAgW0lOXSBTSEFSRF9QQVRIIG9yIFNIQVJEX1BJREwKICogICBwdiAgICAgIFtJTl0gc3RyaW5nIG9yIHBpZGwsIE5VTEwgY2xlYXJzIHRoZSBsaXN0CiAqCiAqIE5PVEVTCiAqICAgICBleHBvcnRlZCBieSBuYW1lCiAqLwpEV09SRCBXSU5BUEkgU0hBZGRUb1JlY2VudERvY3MgKFVJTlQgdUZsYWdzLExQQ1ZPSUQgcHYpICAgCnsgaWYgKFNIQVJEX1BJREw9PXVGbGFncykKICB7IEZJWE1FKCIoMHglMDh4LHBpZGw9JXApOnN0dWIuXG4iLCB1RmxhZ3MscHYpOwoJfQoJZWxzZQoJeyBGSVhNRSgiKDB4JTA4eCwlcyk6c3R1Yi5cbiIsIHVGbGFncywoY2hhciopcHYpOwoJfQogIHJldHVybiAwOwp9Ci8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFNIRmlsZU9wZXJhdGlvbgkJCQlbU0hFTEwzMi4yNDJdCiAqCiAqLwpEV09SRCBXSU5BUEkgU0hGaWxlT3BlcmF0aW9uQVcoRFdPUkQgeCkKewlGSVhNRSgiMHglMDhseCBzdHViXG4iLHgpOwoJcmV0dXJuIDA7Cgp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBTSEZpbGVPcGVyYXRpb25BCQkJCVtTSEVMTDMyLjI0M10KICoKICogTk9URVMKICogICAgIGV4cG9ydGVkIGJ5IG5hbWUKICovCkRXT1JEIFdJTkFQSSBTSEZpbGVPcGVyYXRpb25BIChMUFNIRklMRU9QU1RSVUNUQSBscEZpbGVPcCkgICAKeyBGSVhNRSgiKCVwKTpzdHViLlxuIiwgbHBGaWxlT3ApOwogIHJldHVybiAxOwp9Ci8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFNIRmlsZU9wZXJhdGlvblcJCQkJW1NIRUxMMzIuMjQ0XQogKgogKiBOT1RFUwogKiAgICAgZXhwb3J0ZWQgYnkgbmFtZQogKi8KRFdPUkQgV0lOQVBJIFNIRmlsZU9wZXJhdGlvblcgKExQU0hGSUxFT1BTVFJVQ1RXIGxwRmlsZU9wKSAgIAp7IEZJWE1FKCIoJXApOnN0dWIuXG4iLCBscEZpbGVPcCk7CiAgcmV0dXJuIDE7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFNIQ2hhbmdlTm90aWZ5CQkJCVtTSEVMTDMyLjIzOV0KICoKICogTk9URVMKICogICAgIGV4cG9ydGVkIGJ5IG5hbWUKICovCkRXT1JEIFdJTkFQSSBTSENoYW5nZU5vdGlmeSAoCiAgICBJTlQgICB3RXZlbnRJZCwgIC8qIFtJTl0gZmxhZ3MgdGhhdCBzcGVjaWZpZXMgdGhlIGV2ZW50Ki8KICAgIFVJTlQgIHVGbGFncywgICAvKiBbSU5dIHRoZSBtZWFuaW5nIG9mIGR3SXRlbVsxfDJdKi8KCQlMUENWT0lEIGR3SXRlbTEsCgkJTFBDVk9JRCBkd0l0ZW0yKQp7IEZJWE1FKCIoMHglMDh4LDB4JTA4dXgsJXAsJXApOnN0dWIuXG4iLCB3RXZlbnRJZCx1RmxhZ3MsZHdJdGVtMSxkd0l0ZW0yKTsKICByZXR1cm4gMDsKfQovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBTSENyZWF0ZVNoZWxsRm9sZGVyVmlld0V4CQkJW1NIRUxMMzIuMTc0XQogKgogKiBOT1RFUwogKiAgc2VlIElTaGVsbEZvbGRlcjo6Q3JlYXRlVmlld09iamVjdAogKi8KSFJFU1VMVCBXSU5BUEkgU0hDcmVhdGVTaGVsbEZvbGRlclZpZXdFeCgKICBMUFNIRUxMVklFV0RBVEEgcHN2Y2JpLCAvKltpbiBdIHNoZWxsdGVtcGxhdGUgc3RydWN0Ki8KICBMUFZPSUQqIHBwdikgICAgICAgICAgICAvKltvdXRdIElTaGVsbFZpZXcgcG9pbnRlciovCnsKCUlTaGVsbFZpZXcgKiBwc2Y7CglIUkVTVUxUIGhSZXM7CgkKCVRSQUNFKCJzZj0lcCBwaWRsPSVwIGNiPSVwIG1vZGU9MHglMDhseCBwYXJtPTB4JTA4bHhcbiIsIAoJICBwc3ZjYmktPnBTaGVsbEZvbGRlciwgcHN2Y2JpLT5waWRsLCBwc3ZjYmktPnBDYWxsQmFjaywgcHN2Y2JpLT52aWV3bW9kZSwgcHN2Y2JpLT5kd1VzZXJQYXJhbSk7CgoJcHNmID0gSVNoZWxsVmlld19Db25zdHJ1Y3Rvcihwc3ZjYmktPnBTaGVsbEZvbGRlcik7CgkKCWlmICghcHNmKQoJICByZXR1cm4gRV9PVVRPRk1FTU9SWTsKCglJU2hlbGxWaWV3X0FkZFJlZihwc2YpOwoJaFJlcyA9IElTaGVsbFZpZXdfUXVlcnlJbnRlcmZhY2UocHNmLCAmSUlEX0lTaGVsbFZpZXcsIChMUFZPSUQgKilwcHYpOwoJSVNoZWxsVmlld19SZWxlYXNlKHBzZik7CgoJcmV0dXJuIGhSZXM7Cn0KLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogIFNIV2luSGVscAkJCQkJW1NIRUxMMzIuMTI3XQogKgogKi8KSFJFU1VMVCBXSU5BUEkgU0hXaW5IZWxwIChEV09SRCB2LCBEV09SRCB3LCBEV09SRCB4LCBEV09SRCB6KQp7CUZJWE1FKCIweCUwOGx4IDB4JTA4bHggMHglMDhseCAweCUwOGx4IHN0dWJcbiIsdix3LHgseik7CglyZXR1cm4gMDsKfQovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgU0hSdW5Db250cm9sUGFuZWwgW1NIRUxMMzIuMTYxXQogKgogKi8KSFJFU1VMVCBXSU5BUEkgU0hSdW5Db250cm9sUGFuZWwgKERXT1JEIHgsIERXT1JEIHopCnsJRklYTUUoIjB4JTA4bHggMHglMDhseCBzdHViXG4iLHgseik7CglyZXR1cm4gMDsKfQovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBTaGVsbEV4ZWN1dGVFeAkJCQlbU0hFTEwzMi4yOTFdCiAqCiAqLwpCT09MIFdJTkFQSSBTaGVsbEV4ZWN1dGVFeEFXIChMUFZPSUQgc2VpKQp7CWlmIChWRVJTSU9OX09zSXNVbmljb2RlKCkpCgkgIHJldHVybiBTaGVsbEV4ZWN1dGVFeFcgKHNlaSk7CglyZXR1cm4gU2hlbGxFeGVjdXRlRXhBIChzZWkpOwp9Ci8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFNoZWxsRXhlY3V0ZUV4QQkJCQlbU0hFTEwzMi4yOTJdCiAqCiAqLwpCT09MIFdJTkFQSSBTaGVsbEV4ZWN1dGVFeEEgKExQU0hFTExFWEVDVVRFSU5GT0Egc2VpKQp7IAlDSEFSIHN6QXBwbGljYXRpb25OYW1lW01BWF9QQVRIXSxzekNvbW1hbmRsaW5lW01BWF9QQVRIXSxzelBpZGxbMjBdOwoJTFBTVFIgcG9zOwoJaW50IGdhcCwgbGVuOwoJU1RBUlRVUElORk9BICBzdGFydHVwaW5mbzsKCVBST0NFU1NfSU5GT1JNQVRJT04gcHJvY2Vzc2luZm9ybWF0aW9uOwoJCQkKCVdBUk4oIm1hc2s9MHglMDhseCBod25kPTB4JTA0eCB2ZXJiPSVzIGZpbGU9JXMgcGFybT0lcyBkaXI9JXMgc2hvdz0weCUwOHggY2xhc3M9JXMgaW5jb21wbGV0ZVxuIiwKCQlzZWktPmZNYXNrLCBzZWktPmh3bmQsIHNlaS0+bHBWZXJiLCBzZWktPmxwRmlsZSwKCQlzZWktPmxwUGFyYW1ldGVycywgc2VpLT5scERpcmVjdG9yeSwgc2VpLT5uU2hvdywgCgkJKHNlaS0+Zk1hc2sgJiBTRUVfTUFTS19DTEFTU05BTUUpID8gc2VpLT5scENsYXNzIDogIm5vdCB1c2VkIik7CgoJWmVyb01lbW9yeShzekFwcGxpY2F0aW9uTmFtZSxNQVhfUEFUSCk7CglpZiAoc2VpLT5scEZpbGUpCgkgIHN0cmNweShzekFwcGxpY2F0aW9uTmFtZSwgc2VpLT5scEZpbGUpOwoJCglaZXJvTWVtb3J5KHN6Q29tbWFuZGxpbmUsTUFYX1BBVEgpOwoJaWYgKHNlaS0+bHBQYXJhbWV0ZXJzKQoJICBzdHJjcHkoc3pDb21tYW5kbGluZSwgc2VpLT5scFBhcmFtZXRlcnMpOwoJCQkKCWlmIChzZWktPmZNYXNrICYgKFNFRV9NQVNLX0NMQVNTS0VZIHwgU0VFX01BU0tfSU5WT0tFSURMSVNUIHwgU0VFX01BU0tfSUNPTiB8IFNFRV9NQVNLX0hPVEtFWSB8CgkJCSAgU0VFX01BU0tfTk9DTE9TRVBST0NFU1MgfCBTRUVfTUFTS19DT05ORUNUTkVURFJWIHwgU0VFX01BU0tfRkxBR19EREVXQUlUIHwKCQkJICBTRUVfTUFTS19ET0VOVlNVQlNUIHwgU0VFX01BU0tfRkxBR19OT19VSSB8IFNFRV9NQVNLX1VOSUNPREUgfCAKCQkJICBTRUVfTUFTS19OT19DT05TT0xFIHwgU0VFX01BU0tfQVNZTkNPSyB8IFNFRV9NQVNLX0hNT05JVE9SICkpCgl7IEZJWE1FKCJmbGFncyBpZ25vcmVkOiAweCUwOGx4XG4iLCBzZWktPmZNYXNrKTsKCX0KCglpZiAoc2VpLT5mTWFzayAmIFNFRV9NQVNLX0NMQVNTTkFNRSkKCXsgSENSX0dldEV4ZWN1dGVDb21tYW5kKHNlaS0+bHBDbGFzcywgKHNlaS0+bHBWZXJiKSA/IHNlaS0+bHBWZXJiIDogIm9wZW4iLCBzekNvbW1hbmRsaW5lLCAyNTYpOwkgICAgCgl9CgoJLyogcHJvY2VzcyB0aGUgSURMaXN0ICovCglpZiAoIChzZWktPmZNYXNrICYgU0VFX01BU0tfSU5WT0tFSURMSVNUKSA9PSBTRUVfTUFTS19JTlZPS0VJRExJU1QpIC8qMHgwYyovCgl7IFNIR2V0UGF0aEZyb21JRExpc3RBIChzZWktPmxwSURMaXN0LHN6QXBwbGljYXRpb25OYW1lKTsKCSAgVFJBQ0UoIi0tIGlkbGlzdD0lcCAoJXMpXG4iLCBzZWktPmxwSURMaXN0LCBzekFwcGxpY2F0aW9uTmFtZSk7Cgl9CgllbHNlCgl7IGlmIChzZWktPmZNYXNrICYgU0VFX01BU0tfSURMSVNUICkKCSAgeyAvKiAlSSBpcyB0aGUgYWRyZXNzIG9mIGEgZ2xvYmFsIGl0ZW0gSUQqLwoJICAgIHBvcyA9IHN0cnN0cihzekNvbW1hbmRsaW5lLCAiJUkiKTsKCSAgICBpZiAocG9zKQoJICAgIHsgSEdMT0JBTCBobWVtID0gU0hBbGxvY1NoYXJlZCAoIHNlaS0+bHBJRExpc3QsIElMR2V0U2l6ZShzZWktPmxwSURMaXN0KSwgMCk7CgkgICAgICBzcHJpbnRmKHN6UGlkbCwiOiVsaSIsKERXT1JEKVNITG9ja1NoYXJlZChobWVtLDApICk7CgkgICAgICBTSFVubG9ja1NoYXJlZChobWVtKTsKCSAgICAKCSAgICAgIGdhcCA9IHN0cmxlbihzelBpZGwpOwoJICAgICAgbGVuID0gc3RybGVuKHBvcyktMjsKCSAgICAgIG1lbW1vdmUocG9zK2dhcCxwb3MrMixsZW4pOwoJICAgICAgbWVtY3B5KHBvcyxzelBpZGwsZ2FwKTsKCgkgICAgfQoJICB9Cgl9CgoJcG9zID0gc3Ryc3RyKHN6Q29tbWFuZGxpbmUsICIsJUwiKTsJLyogZHVubm8gd2hhdCBpdCBtZWFuczoga2lsbCBpdCovCglpZiAocG9zKQoJeyBsZW4gPSBzdHJsZW4ocG9zKS0yOwoJICAqcG9zPTB4MDsKCSAgbWVtbW92ZShwb3MscG9zKzMsbGVuKTsKCX0KCglUUkFDRSgiZXhlY3V0ZTogJXMgJXNcbiIsc3pBcHBsaWNhdGlvbk5hbWUsIHN6Q29tbWFuZGxpbmUpOwoKCVplcm9NZW1vcnkoJnN0YXJ0dXBpbmZvLHNpemVvZihTVEFSVFVQSU5GT0EpKTsKCXN0YXJ0dXBpbmZvLmNiID0gc2l6ZW9mKFNUQVJUVVBJTkZPQSk7CgoJcmV0dXJuIENyZWF0ZVByb2Nlc3NBKHN6QXBwbGljYXRpb25OYW1lWzBdID8gc3pBcHBsaWNhdGlvbk5hbWU6TlVMTCwKCQkJIHN6Q29tbWFuZGxpbmVbMF0gPyBzekNvbW1hbmRsaW5lIDogTlVMTCwKCQkJIE5VTEwsIE5VTEwsIEZBTFNFLCAwLCAKCQkJIE5VTEwsIE5VTEwsICZzdGFydHVwaW5mbywgJnByb2Nlc3NpbmZvcm1hdGlvbik7CgkgIAoJCn0KLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogU2hlbGxFeGVjdXRlRXhXCQkJCVtTSEVMTDMyLjI5M10KICoKICovCkJPT0wgV0lOQVBJIFNoZWxsRXhlY3V0ZUV4VyAoTFBTSEVMTEVYRUNVVEVJTkZPVyBzZWkpCnsJU0hFTExFWEVDVVRFSU5GT0Egc2VpQTsKCURXT1JEIHJldDsKCglUUkFDRSgiJXBcbiIsIHNlaSk7CgoJbWVtY3B5KCZzZWlBLCBzZWksIHNpemVvZihTSEVMTEVYRUNVVEVJTkZPQSkpOwoJCiAgICAgICAgaWYgKHNlaS0+bHBWZXJiKQoJICBzZWlBLmxwVmVyYiA9IEhFQVBfc3RyZHVwV3RvQSggR2V0UHJvY2Vzc0hlYXAoKSwgMCwgc2VpLT5scFZlcmIpOwoKICAgICAgICBpZiAoc2VpLT5scEZpbGUpCgkgIHNlaUEubHBGaWxlID0gSEVBUF9zdHJkdXBXdG9BKCBHZXRQcm9jZXNzSGVhcCgpLCAwLCBzZWktPmxwRmlsZSk7CgogICAgICAgIGlmIChzZWktPmxwUGFyYW1ldGVycykKCSAgc2VpQS5scFBhcmFtZXRlcnMgPSBIRUFQX3N0cmR1cFd0b0EoIEdldFByb2Nlc3NIZWFwKCksIDAsIHNlaS0+bHBQYXJhbWV0ZXJzKTsKCglpZiAoc2VpLT5scERpcmVjdG9yeSkKCSAgc2VpQS5scERpcmVjdG9yeSA9IEhFQVBfc3RyZHVwV3RvQSggR2V0UHJvY2Vzc0hlYXAoKSwgMCwgc2VpLT5scERpcmVjdG9yeSk7CgogICAgICAgIGlmICgoc2VpLT5mTWFzayAmIFNFRV9NQVNLX0NMQVNTTkFNRSkgJiYgc2VpLT5scENsYXNzKQoJICBzZWlBLmxwQ2xhc3MgPSBIRUFQX3N0cmR1cFd0b0EoIEdldFByb2Nlc3NIZWFwKCksIDAsIHNlaS0+bHBDbGFzcyk7CgllbHNlCgkgIHNlaUEubHBDbGFzcyA9IE5VTEw7CgkgIAkgIAoJcmV0ID0gU2hlbGxFeGVjdXRlRXhBKCZzZWlBKTsKCiAgICAgICAgaWYgKHNlaUEubHBWZXJiKQlIZWFwRnJlZSggR2V0UHJvY2Vzc0hlYXAoKSwgMCwgKExQU1RSKSBzZWlBLmxwVmVyYiApOwoJaWYgKHNlaUEubHBGaWxlKQlIZWFwRnJlZSggR2V0UHJvY2Vzc0hlYXAoKSwgMCwgKExQU1RSKSBzZWlBLmxwRmlsZSApOwoJaWYgKHNlaUEubHBQYXJhbWV0ZXJzKQlIZWFwRnJlZSggR2V0UHJvY2Vzc0hlYXAoKSwgMCwgKExQU1RSKSBzZWlBLmxwUGFyYW1ldGVycyApOwoJaWYgKHNlaUEubHBEaXJlY3RvcnkpCUhlYXBGcmVlKCBHZXRQcm9jZXNzSGVhcCgpLCAwLCAoTFBTVFIpIHNlaUEubHBEaXJlY3RvcnkgKTsKCWlmIChzZWlBLmxwQ2xhc3MpCUhlYXBGcmVlKCBHZXRQcm9jZXNzSGVhcCgpLCAwLCAoTFBTVFIpIHNlaUEubHBDbGFzcyApOwoKIAlyZXR1cm4gcmV0Owp9CgpzdGF0aWMgTFBVTktOT1dOIFNIRUxMMzJfSUV4cGxvcmVySW50ZXJmYWNlPTA7Ci8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFNIU2V0SW5zdGFuY2VFeHBsb3JlcgkJCVtTSEVMTDMyLjE3Nl0KICoKICogTk9URVMKICogIFNldHMgdGhlIGludGVyZmFjZQogKi8KSFJFU1VMVCBXSU5BUEkgU0hTZXRJbnN0YW5jZUV4cGxvcmVyIChMUFVOS05PV04gbHBVbmtub3duKQp7CVRSQUNFKCIlcFxuIiwgbHBVbmtub3duKTsKCVNIRUxMMzJfSUV4cGxvcmVySW50ZXJmYWNlID0gbHBVbmtub3duOwoJcmV0dXJuIChIUkVTVUxUKSBscFVua25vd247Cn0KLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogU0hHZXRJbnN0YW5jZUV4cGxvcmVyCQkJW1NIRUxMMzIuMjU2XQogKgogKiBOT1RFUwogKiAgZ2V0cyB0aGUgaW50ZXJmYWNlIHBvaW50ZXIgb2YgdGhlIGV4cGxvcmVyIGFuZCBhIHJlZmVyZW5jZQogKi8KSFJFU1VMVCBXSU5BUEkgU0hHZXRJbnN0YW5jZUV4cGxvcmVyIChMUFVOS05PV04gKiBscFVua25vd24pCnsJVFJBQ0UoIiVwXG4iLCBscFVua25vd24pOwoKCSpscFVua25vd24gPSBTSEVMTDMyX0lFeHBsb3JlckludGVyZmFjZTsKCglpZiAoIVNIRUxMMzJfSUV4cGxvcmVySW50ZXJmYWNlKQoJICByZXR1cm4gRV9GQUlMOwoKCUlVbmtub3duX0FkZFJlZihTSEVMTDMyX0lFeHBsb3JlckludGVyZmFjZSk7CglyZXR1cm4gTk9FUlJPUjsKfQovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBTSEZyZWVVbnVzZWRMaWJyYXJpZXMJCQlbU0hFTEwzMi4xMjNdCiAqCiAqIE5PVEVTCiAqICBleHBvcnRlZCBieSBuYW1lCiAqLwpIUkVTVUxUIFdJTkFQSSBTSEZyZWVVbnVzZWRMaWJyYXJpZXMgKHZvaWQpCnsJRklYTUUoInN0dWJcbiIpOwoJcmV0dXJuIFRSVUU7Cn0KLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogREFEX1NldERyYWdJbWFnZQkJCQlbU0hFTEwzMi4xMzZdCiAqCiAqIE5PVEVTCiAqICBleHBvcnRlZCBieSBuYW1lCiAqLwpIUkVTVUxUIFdJTkFQSSBEQURfU2V0RHJhZ0ltYWdlIChEV09SRCB1LCBEV09SRCB2KQp7IEZJWE1FKCIweCUwOGx4IDB4JTA4bHggc3R1YlxuIix1LCB2KTsKICByZXR1cm4gMDsKfQovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBEQURfU2hvd0RyYWdJbWFnZQkJCQlbU0hFTEwzMi4xMzddCiAqCiAqIE5PVEVTCiAqICBleHBvcnRlZCBieSBuYW1lCiAqLwpIUkVTVUxUIFdJTkFQSSBEQURfU2hvd0RyYWdJbWFnZSAoRFdPUkQgdSkKeyBGSVhNRSgiMHglMDhseCBzdHViXG4iLHUpOwogIHJldHVybiAwOwp9Ci8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFNIUmVnQ2xvc2VLZXkJCQlbTlQ0LjA6U0hFTEwzMi41MDVdCiAqCiAqLwpIUkVTVUxUIFdJTkFQSSBTSFJlZ0Nsb3NlS2V5IChIS0VZIGhrZXkpCnsJVFJBQ0UoIjB4JTA0eFxuIixoa2V5KTsKCXJldHVybiBSZWdDbG9zZUtleSggaGtleSApOwp9Ci8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFNIUmVnT3BlbktleUEJCQkJW1NIRUxMMzIuNTA2XQogKgogKi8KSFJFU1VMVCBXSU5BUEkgU0hSZWdPcGVuS2V5QShIS0VZIGhLZXksIExQU1RSIGxwU3ViS2V5LCBMUEhLRVkgcGhrUmVzdWx0KQp7CglUUkFDRSgiKDB4JTA4eCwgJXMsICVwKVxuIiwgaEtleSwgZGVidWdzdHJfYShscFN1YktleSksIHBoa1Jlc3VsdCk7CglyZXR1cm4gUmVnT3BlbktleUEoaEtleSwgbHBTdWJLZXksIHBoa1Jlc3VsdCk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFNIUmVnT3BlbktleVcJCQkJW05UNC4wOlNIRUxMMzIuNTA3XQogKgogKi8KSFJFU1VMVCBXSU5BUEkgU0hSZWdPcGVuS2V5VyAoSEtFWSBoa2V5LCBMUENXU1RSIGxwc3pTdWJLZXksIExQSEtFWSByZXRrZXkpCnsJV0FSTigiMHglMDR4ICVzICVwXG4iLGhrZXksZGVidWdzdHJfdyhscHN6U3ViS2V5KSxyZXRrZXkpOwoJcmV0dXJuIFJlZ09wZW5LZXlXKCBoa2V5LCBscHN6U3ViS2V5LCByZXRrZXkgKTsKfQovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBTSFJlZ1F1ZXJ5VmFsdWVFeEEJCQkJW1NIRUxMMzIuNTA5XQogKgogKi8KSFJFU1VMVCBXSU5BUEkgU0hSZWdRdWVyeVZhbHVlRXhBKAoJSEtFWSBoa2V5LAoJTFBTVFIgbHBWYWx1ZU5hbWUsCglMUERXT1JEIGxwUmVzZXJ2ZWQsCglMUERXT1JEIGxwVHlwZSwKCUxQQllURSBscERhdGEsCglMUERXT1JEIGxwY2JEYXRhKQp7CglUUkFDRSgiMHglMDR4ICVzICVwICVwICVwICVwXG4iLCBoa2V5LCBscFZhbHVlTmFtZSwgbHBSZXNlcnZlZCwgbHBUeXBlLCBscERhdGEsIGxwY2JEYXRhKTsKCXJldHVybiBSZWdRdWVyeVZhbHVlRXhBIChoa2V5LCBscFZhbHVlTmFtZSwgbHBSZXNlcnZlZCwgbHBUeXBlLCBscERhdGEsIGxwY2JEYXRhKTsKfQovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBTSFJlZ1F1ZXJ5VmFsdWVXCQkJCVtOVDQuMDpTSEVMTDMyLjUxMF0KICoKICovCkhSRVNVTFQgV0lOQVBJIFNIUmVnUXVlcnlWYWx1ZVcgKEhLRVkgaGtleSwgTFBXU1RSIGxwc3pTdWJLZXksCgkJCQkgTFBXU1RSIGxwc3pEYXRhLCBMUERXT1JEIGxwY2JEYXRhICkKewlXQVJOKCIweCUwNHggJXMgJXAgJXAgc2VtaS1zdHViXG4iLAoJCWhrZXksIGRlYnVnc3RyX3cobHBzelN1YktleSksIGxwc3pEYXRhLCBscGNiRGF0YSk7CglyZXR1cm4gUmVnUXVlcnlWYWx1ZVcoIGhrZXksIGxwc3pTdWJLZXksIGxwc3pEYXRhLCBscGNiRGF0YSApOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBTSFJlZ1F1ZXJ5VmFsdWVFeFcJCQkJW05UNC4wOlNIRUxMMzIuNTExXQogKgogKiBGSVhNRSAKICogIGlmIHRoZSBkYXRhdHlwZSBSRUdfRVhQQU5EX1NaIHRoZW4gZXhwYW5kIHRoZSBzdHJpbmcgYW5kIGNoYW5nZQogKiAgKnBkd1R5cGUgdG8gUkVHX1NaLiAKICovCkhSRVNVTFQgV0lOQVBJIFNIUmVnUXVlcnlWYWx1ZUV4VyAoSEtFWSBoa2V5LCBMUFdTVFIgcHN6VmFsdWUsIExQRFdPUkQgcGR3UmVzZXJ2ZWQsCgkJIExQRFdPUkQgcGR3VHlwZSwgTFBWT0lEIHB2RGF0YSwgTFBEV09SRCBwY2JEYXRhKQp7CURXT1JEIHJldDsKCVdBUk4oIjB4JTA0eCAlcyAlcCAlcCAlcCAlcCBzZW1pLXN0dWJcbiIsCgkJaGtleSwgZGVidWdzdHJfdyhwc3pWYWx1ZSksIHBkd1Jlc2VydmVkLCBwZHdUeXBlLCBwdkRhdGEsIHBjYkRhdGEpOwoJcmV0ID0gUmVnUXVlcnlWYWx1ZUV4VyAoIGhrZXksIHBzelZhbHVlLCBwZHdSZXNlcnZlZCwgcGR3VHlwZSwgcHZEYXRhLCBwY2JEYXRhKTsKCXJldHVybiByZXQ7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFJlYWRDYWJpbmV0U3RhdGUJCQkJW05UIDQuMDpTSEVMTDMyLjY1MV0KICoKICovCkhSRVNVTFQgV0lOQVBJIFJlYWRDYWJpbmV0U3RhdGUoRFdPUkQgdSwgRFdPUkQgdikKewlGSVhNRSgiMHglMDRseCAweCUwNGx4IHN0dWJcbiIsdSx2KTsKCXJldHVybiAwOwp9Ci8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFdyaXRlQ2FiaW5ldFN0YXRlCQkJCVtOVCA0LjA6U0hFTEwzMi42NTJdCiAqCiAqLwpIUkVTVUxUIFdJTkFQSSBXcml0ZUNhYmluZXRTdGF0ZShEV09SRCB1KQp7CUZJWE1FKCIweCUwNGx4IHN0dWJcbiIsdSk7CglyZXR1cm4gMDsKfQovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBGaWxlSWNvbkluaXQgCQkJCVtTSEVMTDMyLjY2MF0KICoKICovCkJPT0wgV0lOQVBJIEZpbGVJY29uSW5pdChCT09MIGJGdWxsSW5pdCkKewlGSVhNRSgiKCVzKVxuIiwgYkZ1bGxJbml0ID8gInRydWUiIDogImZhbHNlIik7CglyZXR1cm4gMDsKfQovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBJc1VzZXJBZG1pbgkJCQkJW05UIDQuMDpTSEVMTDMyLjY4MF0KICoKICovCkhSRVNVTFQgV0lOQVBJIElzVXNlckFkbWluKHZvaWQpCnsJRklYTUUoInN0dWJcbiIpOwoJcmV0dXJuIFRSVUU7Cn0KLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogU3RyUmV0VG9TdHJOCQkJCQlbU0hFTEwzMi45Nl0KICogCiAqIGNvbnZlcnRzIGEgU1RSUkVUIHRvIGEgbm9ybWFsIHN0cmluZwogKgogKiBOT1RFUwogKiAgdGhlIHBpZGwgaXMgZm9yIFNUUlJFVCBPRkZTRVQKICovCkhSRVNVTFQgV0lOQVBJIFN0clJldFRvQnVmQSAoTFBTVFJSRVQgc3JjLCBMUElURU1JRExJU1QgcGlkbCwgTFBTVFIgZGVzdCwgRFdPUkQgbGVuKQp7CglyZXR1cm4gU3RyUmV0VG9TdHJOQShkZXN0LCBsZW4sIHNyYywgcGlkbCk7Cn0KCkhSRVNVTFQgV0lOQVBJIFN0clJldFRvU3RyTkEgKExQVk9JRCBkZXN0LCBEV09SRCBsZW4sIExQU1RSUkVUIHNyYywgTFBJVEVNSURMSVNUIHBpZGwpCnsKCVRSQUNFKCJkZXN0PTB4JXAgbGVuPTB4JWx4IHN0cnJldD0weCVwIHBpZGw9JXAgc3R1YlxuIixkZXN0LGxlbixzcmMscGlkbCk7CgoJc3dpdGNoIChzcmMtPnVUeXBlKQoJewoJICBjYXNlIFNUUlJFVF9XU1RSOgoJICAgIFdpZGVDaGFyVG9NdWx0aUJ5dGUoQ1BfQUNQLCAwLCBzcmMtPnUucE9sZVN0ciwgLTEsIChMUFNUUilkZXN0LCBsZW4sIE5VTEwsIE5VTEwpOwoJICAgIFNIRnJlZShzcmMtPnUucE9sZVN0cik7CgkgICAgYnJlYWs7CgoJICBjYXNlIFNUUlJFVF9DU1RSQToKCSAgICBsc3RyY3B5bkEoKExQU1RSKWRlc3QsIHNyYy0+dS5jU3RyLCBsZW4pOwoJICAgIGJyZWFrOwoKCSAgY2FzZSBTVFJSRVRfT0ZGU0VUQToKCSAgICBsc3RyY3B5bkEoKExQU1RSKWRlc3QsICgoTFBDU1RSKSZwaWRsLT5ta2lkKStzcmMtPnUudU9mZnNldCwgbGVuKTsKCSAgICBicmVhazsKCgkgIGRlZmF1bHQ6CgkgICAgRklYTUUoInVua25vd24gdHlwZSFcbiIpOwoJICAgIGlmIChsZW4pCgkgICAgewoJICAgICAgKihMUFNUUilkZXN0ID0gJ1wwJzsKCSAgICB9CgkgICAgcmV0dXJuKEZBTFNFKTsKCX0KCXJldHVybiBTX09LOwp9CgpIUkVTVUxUIFdJTkFQSSBTdHJSZXRUb0J1ZlcgKExQU1RSUkVUIHNyYywgTFBJVEVNSURMSVNUIHBpZGwsIExQV1NUUiBkZXN0LCBEV09SRCBsZW4pCnsKCXJldHVybiBTdHJSZXRUb1N0ck5XKGRlc3QsIGxlbiwgc3JjLCBwaWRsKTsKfQoKSFJFU1VMVCBXSU5BUEkgU3RyUmV0VG9TdHJOVyAoTFBWT0lEIGRlc3QsIERXT1JEIGxlbiwgTFBTVFJSRVQgc3JjLCBMUElURU1JRExJU1QgcGlkbCkKewoJVFJBQ0UoImRlc3Q9MHglcCBsZW49MHglbHggc3RycmV0PTB4JXAgcGlkbD0lcCBzdHViXG4iLGRlc3QsbGVuLHNyYyxwaWRsKTsKCglzd2l0Y2ggKHNyYy0+dVR5cGUpCgl7CgkgIGNhc2UgU1RSUkVUX1dTVFI6CgkgICAgbHN0cmNweW5XKChMUFdTVFIpZGVzdCwgc3JjLT51LnBPbGVTdHIsIGxlbik7CgkgICAgU0hGcmVlKHNyYy0+dS5wT2xlU3RyKTsKCSAgICBicmVhazsKCgkgIGNhc2UgU1RSUkVUX0NTVFJBOgoJICAgIGxzdHJjcHluQXRvVygoTFBXU1RSKWRlc3QsIHNyYy0+dS5jU3RyLCBsZW4pOwoJICAgIGJyZWFrOwoKCSAgY2FzZSBTVFJSRVRfT0ZGU0VUQToKCSAgICBpZiAocGlkbCkKCSAgICB7CgkgICAgICBsc3RyY3B5bkF0b1coKExQV1NUUilkZXN0LCAoKExQQ1NUUikmcGlkbC0+bWtpZCkrc3JjLT51LnVPZmZzZXQsIGxlbik7CgkgICAgfQoJICAgIGJyZWFrOwoKCSAgZGVmYXVsdDoKCSAgICBGSVhNRSgidW5rbm93biB0eXBlIVxuIik7CgkgICAgaWYgKGxlbikKCSAgICB7ICooTFBTVFIpZGVzdCA9ICdcMCc7CgkgICAgfQoJICAgIHJldHVybihGQUxTRSk7Cgl9CglyZXR1cm4gU19PSzsKfQpIUkVTVUxUIFdJTkFQSSBTdHJSZXRUb1N0ck5BVyAoTFBWT0lEIGRlc3QsIERXT1JEIGxlbiwgTFBTVFJSRVQgc3JjLCBMUElURU1JRExJU1QgcGlkbCkKewoJaWYoVkVSU0lPTl9Pc0lzVW5pY29kZSgpKQoJICByZXR1cm4gU3RyUmV0VG9TdHJOVyAoZGVzdCwgbGVuLCBzcmMsIHBpZGwpOwoJcmV0dXJuIFN0clJldFRvU3RyTkEgKGRlc3QsIGxlbiwgc3JjLCBwaWRsKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogU3RyQ2hyVwkJCQkJW05UIDQuMDpTSEVMTDMyLjY1MV0KICoKICovCkxQV1NUUiBXSU5BUEkgU3RyQ2hyVyAoTFBXU1RSIHN0ciwgV0NIQVIgeCApCnsJTFBXU1RSIHB0cj1zdHI7CgkKCVRSQUNFKCIlcyAweCUwNHhcbiIsZGVidWdzdHJfdyhzdHIpLHgpOwoJZG8gCgl7ICBpZiAoKnB0cj09eCkKCSAgIHsgcmV0dXJuIHB0cjsKCSAgIH0KCSAgIHB0cisrOwoJfSB3aGlsZSAoKnB0cik7CglyZXR1cm4gTlVMTDsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogU3RyQ21wTklXCQkJCQlbTlQgNC4wOlNIRUxMMzIuKl0KICoKICovCklOVCBXSU5BUEkgU3RyQ21wTklXICggTFBXU1RSIHdzdHIxLCBMUFdTVFIgd3N0cjIsIElOVCBsZW4pCnsJRklYTUUoIiVzICVzICVpIHN0dWJcbiIsIGRlYnVnc3RyX3cod3N0cjEpLGRlYnVnc3RyX3cod3N0cjIpLGxlbik7CglyZXR1cm4gMDsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogU0hBbGxvY1NoYXJlZAkJCQlbU0hFTEwzMi41MjBdCiAqCiAqIE5PVEVTCiAqICBwYXJhbWV0ZXIxIGlzIHJldHVybiB2YWx1ZSBmcm9tIEhlYXBBbGxvYwogKiAgcGFyYW1ldGVyMiBpcyBlcXVhbCB0byB0aGUgc2l6ZSBhbGxvY2F0ZWQgd2l0aCBIZWFwQWxsb2MKICogIHBhcmFtZXRlcjMgaXMgcmV0dXJuIHZhbHVlIGZyb20gR2V0Q3VycmVudFByb2Nlc3NJZAogKgogKiAgdGhlIHJldHVybiB2YWx1ZSBpcyBwb3N0ZWQgYXMgbFBhcmFtIHdpdGggMHg0MDIgKFdNX1VTRVIrMikgdG8gc29tZXdoZXJlCiAqICBXTV9VU0VSKzIgY291bGQgYmUgdGhlIHVuZG9jdW1lbnRlZCBDV01fU0VUUEFUSAogKiAgdGhlIGFsbG9jYXRlZCBtZW1vcnkgY29udGFpbnMgYSBwaWRsCiAqLwpIR0xPQkFMIFdJTkFQSSBTSEFsbG9jU2hhcmVkKExQVk9JRCBwc3JjLCBEV09SRCBzaXplLCBEV09SRCBwcm9jSUQpCnsJSEdMT0JBTCBobWVtOwoJTFBWT0lEIHBtZW07CgkKCVRSQUNFKCJwdHI9JXAgc2l6ZT0weCUwNGx4IHByb2NJRD0weCUwNGx4XG4iLHBzcmMsc2l6ZSxwcm9jSUQpOwoJaG1lbSA9IEdsb2JhbEFsbG9jKEdNRU1fRklYRUQsIHNpemUpOwoJaWYgKCFobWVtKQoJICByZXR1cm4gMDsKCQoJcG1lbSA9ICBHbG9iYWxMb2NrIChobWVtKTsKCglpZiAoISBwbWVtKQoJICByZXR1cm4gMDsKCSAgCgltZW1jcHkgKHBtZW0sIHBzcmMsIHNpemUpOwoJR2xvYmFsVW5sb2NrKGhtZW0pOyAKCXJldHVybiBobWVtOwp9Ci8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFNITG9ja1NoYXJlZAkJCQkJW1NIRUxMMzIuNTIxXQogKgogKiBOT1RFUwogKiAgcGFyYW1ldGVyMSBpcyByZXR1cm4gdmFsdWUgZnJvbSBTSEFsbG9jU2hhcmVkCiAqICBwYXJhbWV0ZXIyIGlzIHJldHVybiB2YWx1ZSBmcm9tIEdldEN1cnJlbnRQcm9jZXNzSWQKICogIHRoZSByZWNlaXZlciBvZiAoV01fVVNFUisyKSB0cnlzIHRvIGxvY2sgdGhlIEhBTkRMRSAoPykgCiAqICB0aGUgcmV0dXJudmFsdWUgc2VlbXMgdG8gYmUgYSBtZW1vcnlhZHJlc3MKICovCkxQVk9JRCBXSU5BUEkgU0hMb2NrU2hhcmVkKEhBTkRMRSBobWVtLCBEV09SRCBwcm9jSUQpCnsJVFJBQ0UoImhhbmRsZT0weCUwNHggcHJvY0lEPTB4JTA0bHhcbiIsaG1lbSxwcm9jSUQpOwoJcmV0dXJuIEdsb2JhbExvY2soaG1lbSk7Cn0KLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogU0hVbmxvY2tTaGFyZWQJCQkJW1NIRUxMMzIuNTIyXQogKgogKiBOT1RFUwogKiAgcGFyYW1ldGVyMSBpcyByZXR1cm4gdmFsdWUgZnJvbSBTSExvY2tTaGFyZWQKICovCkJPT0wgV0lOQVBJIFNIVW5sb2NrU2hhcmVkKEhBTkRMRSBwbWVtKQp7CVRSQUNFKCJoYW5kbGU9MHglMDR4XG4iLHBtZW0pOwoJcmV0dXJuIEdsb2JhbFVubG9jayhwbWVtKTsgCn0KLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogU0hGcmVlU2hhcmVkCQkJCQlbU0hFTEwzMi41MjNdCiAqCiAqIE5PVEVTCiAqICBwYXJhbWV0ZXIxIGlzIHJldHVybiB2YWx1ZSBmcm9tIFNIQWxsb2NTaGFyZWQKICogIHBhcmFtZXRlcjIgaXMgcmV0dXJuIHZhbHVlIGZyb20gR2V0Q3VycmVudFByb2Nlc3NJZAogKi8KSEFORExFIFdJTkFQSSBTSEZyZWVTaGFyZWQoSEFORExFIGhtZW0sIERXT1JEIHByb2NJRCkKewlUUkFDRSgiaGFuZGxlPTB4JTA0eCAweCUwNGx4XG4iLGhtZW0scHJvY0lEKTsKCXJldHVybiBHbG9iYWxGcmVlKGhtZW0pOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBTZXRBcHBTdGFydGluZ0N1cnNvcgkJCQlbU0hFTEwzMi45OV0KICoKICovCkhSRVNVTFQgV0lOQVBJIFNldEFwcFN0YXJ0aW5nQ3Vyc29yKEhXTkQgdSwgRFdPUkQgdikKewlGSVhNRSgiaHduZD0weCUwNHggMHglMDRseCBzdHViXG4iLHUsdiApOwoJcmV0dXJuIDA7Cn0KLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogU0hMb2FkT0xFCQkJCQlbU0hFTEwzMi4xNTFdCiAqCiAqLwpIUkVTVUxUIFdJTkFQSSBTSExvYWRPTEUoRFdPUkQgdSkKewlGSVhNRSgiMHglMDRseCBzdHViXG4iLHUpOwoJcmV0dXJuIFNfT0s7Cn0KLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogRHJpdmVUeXBlCQkJCQlbU0hFTEwzMi42NF0KICoKICovCkhSRVNVTFQgV0lOQVBJIERyaXZlVHlwZShEV09SRCB1KQp7CUZJWE1FKCIweCUwNGx4IHN0dWJcbiIsdSk7CglyZXR1cm4gMDsKfQovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBTSEFib3J0SW52b2tlQ29tbWFuZAkJCQlbU0hFTEwzMi4xOThdCiAqCiAqLwpIUkVTVUxUIFdJTkFQSSBTSEFib3J0SW52b2tlQ29tbWFuZCh2b2lkKQp7CUZJWE1FKCJzdHViXG4iKTsKCXJldHVybiAxOwp9Ci8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFNIT3V0T2ZNZW1vcnlNZXNzYWdlQm94CQkJW1NIRUxMMzIuMTI2XQogKgogKi8KSFJFU1VMVCBXSU5BUEkgU0hPdXRPZk1lbW9yeU1lc3NhZ2VCb3goRFdPUkQgdSwgRFdPUkQgdiwgRFdPUkQgdykKewlGSVhNRSgiMHglMDRseCAweCUwNGx4IDB4JTA0bHggc3R1YlxuIix1LHYsdyk7CglyZXR1cm4gMDsKfQovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBTSEZsdXNoQ2xpcGJvYXJkCQkJCVtTSEVMTDMyLjEyMV0KICoKICovCkhSRVNVTFQgV0lOQVBJIFNIRmx1c2hDbGlwYm9hcmQodm9pZCkKewlGSVhNRSgic3R1YlxuIik7CglyZXR1cm4gMTsKfQovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBTdHJSQ2hyQQkJCQkJW1NIRUxMMzIuMzQ2XQogKgogKi8KTFBTVFIgV0lOQVBJIFN0clJDaHJBKExQQ1NUUiBscFN0YXJ0LCBMUENTVFIgbHBFbmQsIERXT1JEIHdNYXRjaCkKewogICAgCWlmICghbHBTdGFydCkKCSAgICByZXR1cm4gTlVMTDsKCgkvKiBpZiB0aGUgZW5kIG5vdCBnaXZlbiwgc2VhcmNoKi8KCWlmICghbHBFbmQpCgl7IGxwRW5kPWxwU3RhcnQ7CgkgIHdoaWxlICgqbHBFbmQpIAoJICAgIGxwRW5kKys7Cgl9CgoJZm9yICgtLWxwRW5kO2xwU3RhcnQgPD0gbHBFbmQ7IGxwRW5kLS0pCgkgICAgaWYgKCpscEVuZD09KGNoYXIpd01hdGNoKQoJCXJldHVybiAoTFBTVFIpbHBFbmQ7CgoJcmV0dXJuIE5VTEw7Cn0KLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogU3RyUkNoclcJCQkJCVtTSEVMTDMyLjMyMF0KICoKICovCkxQV1NUUiBXSU5BUEkgU3RyUkNoclcoTFBXU1RSIGxwU3RhcnQsIExQV1NUUiBscEVuZCwgRFdPUkQgd01hdGNoKQp7CUxQV1NUUiB3cHRyPU5VTEw7CglUUkFDRSgiJXMgJXMgMHglMDR4XG4iLGRlYnVnc3RyX3cobHBTdGFydCksZGVidWdzdHJfdyhscEVuZCksIChXQ0hBUil3TWF0Y2ggKTsKCgkvKiBpZiB0aGUgZW5kIG5vdCBnaXZlbiwgc2VhcmNoKi8KCWlmICghbHBFbmQpCgl7IGxwRW5kPWxwU3RhcnQ7CgkgIHdoaWxlICgqbHBFbmQpIAoJICAgIGxwRW5kKys7Cgl9CgoJZG8gCgl7IGlmICgqbHBTdGFydD09KFdDSEFSKXdNYXRjaCkKCSAgICB3cHRyID0gbHBTdGFydDsKCSAgbHBTdGFydCsrOyAgCgl9IHdoaWxlICggbHBTdGFydDw9bHBFbmQgKTsgCglyZXR1cm4gd3B0cjsKfQovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgoqIFN0ckZvcm1hdEJ5dGVTaXplCQkJCVtTSExXQVBJXQoqLwpMUFNUUiBXSU5BUEkgU3RyRm9ybWF0Qnl0ZVNpemVBICggRFdPUkQgZHcsIExQU1RSIHBzekJ1ZiwgVUlOVCBjY2hCdWYgKQp7CWNoYXIgYnVmWzY0XTsKCVRSQUNFKCIlbHggJXAgJWlcbiIsIGR3LCBwc3pCdWYsIGNjaEJ1Zik7CglpZiAoIGR3PDEwMjRMICkKCXsgc3ByaW50ZiAoYnVmLCIlMy4xZiBieXRlcyIsIChGTE9BVClkdyk7Cgl9CgllbHNlIGlmICggZHc8MTA0ODU3NkwpCgl7IHNwcmludGYgKGJ1ZiwiJTMuMWYgS0IiLCAoRkxPQVQpZHcvMTAyNCk7Cgl9CgllbHNlIGlmICggZHcgPCAxMDczNzQxODI0TCkKCXsgc3ByaW50ZiAoYnVmLCIlMy4xZiBNQiIsIChGTE9BVClkdy8xMDQ4NTc2TCk7Cgl9CgllbHNlCgl7IHNwcmludGYgKGJ1ZiwiJTMuMWYgR0IiLCAoRkxPQVQpZHcvMTA3Mzc0MTgyNEwpOwoJfQoJbHN0cmNweW5BIChwc3pCdWYsIGJ1ZiwgY2NoQnVmKTsKCXJldHVybiBwc3pCdWY7CQp9CkxQV1NUUiBXSU5BUEkgU3RyRm9ybWF0Qnl0ZVNpemVXICggRFdPUkQgZHcsIExQV1NUUiBwc3pCdWYsIFVJTlQgY2NoQnVmICkKewljaGFyIGJ1Zls2NF07CglUUkFDRSgiJWx4ICVwICVpXG4iLCBkdywgcHN6QnVmLCBjY2hCdWYpOwoJaWYgKCBkdzwxMDI0TCApCgl7IHNwcmludGYgKGJ1ZiwiJTMuMWYgYnl0ZXMiLCAoRkxPQVQpZHcpOwoJfQoJZWxzZSBpZiAoIGR3PDEwNDg1NzZMKQoJeyBzcHJpbnRmIChidWYsIiUzLjFmIEtCIiwgKEZMT0FUKWR3LzEwMjQpOwoJfQoJZWxzZSBpZiAoIGR3IDwgMTA3Mzc0MTgyNEwpCgl7IHNwcmludGYgKGJ1ZiwiJTMuMWYgTUIiLCAoRkxPQVQpZHcvMTA0ODU3NkwpOwoJfQoJZWxzZQoJeyBzcHJpbnRmIChidWYsIiUzLjFmIEdCIiwgKEZMT0FUKWR3LzEwNzM3NDE4MjRMKTsKCX0KCWxzdHJjcHluQXRvVyAocHN6QnVmLCBidWYsIGNjaEJ1Zik7CglyZXR1cm4gcHN6QnVmOwkKfQovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBTSFdhaXRGb3JGaWxlVG9PcGVuCQkJCVtTSEVMTDMyLjk3XQogKgogKi8KSFJFU1VMVCBXSU5BUEkgU0hXYWl0Rm9yRmlsZVRvT3BlbihEV09SRCB1LCBEV09SRCB2LCBEV09SRCB3KQp7CUZJWE1FKCIweCUwNGx4IDB4JTA0bHggMHglMDRseCBzdHViXG4iLHUsdix3KTsKCXJldHVybiAwOwp9Ci8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIENvbnRyb2xfRmlsbENhY2hlX1J1bkRMTAkJCVtTSEVMTDMyLjhdCiAqCiAqLwpIUkVTVUxUIFdJTkFQSSBDb250cm9sX0ZpbGxDYWNoZV9SdW5ETEwoSFdORCBoV25kLCBIQU5ETEUgaE1vZHVsZSwgRFdPUkQgdywgRFdPUkQgeCkKewlGSVhNRSgiMHglMDR4IDB4JTA0eCAweCUwNGx4IDB4JTA0bHggc3R1YlxuIixoV25kLCBoTW9kdWxlLHcseCk7CglyZXR1cm4gMDsKfQovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBSdW5ETExfQ2FsbEVudHJ5MTYJCQkJW1NIRUxMMzIuMTIyXQogKiB0aGUgbmFtZSBpcyBwcm9wYWJseSB3cm9uZwogKi8KSFJFU1VMVCBXSU5BUEkgUnVuRExMX0NhbGxFbnRyeTE2KERXT1JEIHYsIERXT1JEIHcsIERXT1JEIHgsIERXT1JEIHksIERXT1JEIHopCnsJRklYTUUoIjB4JTA0bHggMHglMDRseCAweCUwNGx4IDB4JTA0bHggMHglMDRseCBzdHViXG4iLHYsdyx4LHkseik7CglyZXR1cm4gMDsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKglzaGVsbDMyXzY1NAkJCQlbU0hFTEwzMi42NTRdCiAqCiAqIE5PVEVTOiBmaXJzdCBwYXJhbWV0ZXIgc2VlbXMgdG8gYmUgYSBwb2ludGVyIChzYW1lIGFzIHBhc3NlZCB0byBXcml0ZUNhYmluZXRTdGF0ZSkKICogc2Vjb25kIG9uZSBjb3VsZCBiZSBhIHNpemUgKDB4MGMpLiBUaGUgc2l6ZSBpcyB0aGUgc2FtZSBhcyB0aGUgc3RydWN0dXJlIHNhdmVkIHRvCiAqIEhDVVxTb2Z0d2FyZVxNaWNyb3NvZnRcV2luZG93c1xDdXJyZW50VmVyc2lvblxFeHBsb3JlclxDYWJpbmV0U3RhdGUKICogSSdtIChqcykgZ3Vlc3Npbmc6IHRoaXMgb25lIGlzIGp1c3QgUmVhZENhYmluZXRTdGF0ZSA7LSkKICovCkhSRVNVTFQgV0lOQVBJIHNoZWxsMzJfNjU0IChEV09SRCB4LCBEV09SRCB5KQp7CUZJWE1FKCIweCUwOGx4IDB4JTA4bHggc3R1YlxuIix4LHkpOwoJcmV0dXJuIDA7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJUkxCdWlsZExpc3RPZlBhdGhzCQkJW1NIRUxMMzIuMTQ2XQogKgogKiBOT1RFUwogKiAgIGJ1aWxkcyBhIERQQQogKi8KRFdPUkQgV0lOQVBJIFJMQnVpbGRMaXN0T2ZQYXRocyAodm9pZCkKewlGSVhNRSgic3R1YlxuIik7CglyZXR1cm4gMDsKfQovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCVN0clRvT2xlU3RyCQkJW1NIRUxMMzIuMTYzXQogKgogKi8KaW50IFdJTkFQSSBTdHJUb09sZVN0ckEgKExQV1NUUiBscFdpZGVDaGFyU3RyLCBMUENTVFIgbHBNdWx0aUJ5dGVTdHJpbmcpCnsKCVRSQUNFKCIoJXAsICVwICVzKVxuIiwKCWxwV2lkZUNoYXJTdHIsIGxwTXVsdGlCeXRlU3RyaW5nLCBkZWJ1Z3N0cl9hKGxwTXVsdGlCeXRlU3RyaW5nKSk7CgoJcmV0dXJuIE11bHRpQnl0ZVRvV2lkZUNoYXIoMCwgMCwgbHBNdWx0aUJ5dGVTdHJpbmcsIC0xLCBscFdpZGVDaGFyU3RyLCBNQVhfUEFUSCk7Cgp9CmludCBXSU5BUEkgU3RyVG9PbGVTdHJXIChMUFdTVFIgbHBXaWRlQ2hhclN0ciwgTFBDV1NUUiBscFdTdHJpbmcpCnsKCVRSQUNFKCIoJXAsICVwICVzKVxuIiwKCWxwV2lkZUNoYXJTdHIsIGxwV1N0cmluZywgZGVidWdzdHJfdyhscFdTdHJpbmcpKTsKCglpZiAobHN0cmNweVcgKGxwV2lkZUNoYXJTdHIsIGxwV1N0cmluZyApKQoJeyByZXR1cm4gbHN0cmxlblcgKGxwV2lkZUNoYXJTdHIpOwoJfQoJcmV0dXJuIDA7Cn0KCkJPT0wgV0lOQVBJIFN0clRvT2xlU3RyQVcgKExQV1NUUiBscFdpZGVDaGFyU3RyLCBMUENWT0lEIGxwU3RyaW5nKQp7CglpZiAoVkVSU0lPTl9Pc0lzVW5pY29kZSgpKQoJICByZXR1cm4gU3RyVG9PbGVTdHJXIChscFdpZGVDaGFyU3RyLCBscFN0cmluZyk7CglyZXR1cm4gU3RyVG9PbGVTdHJBIChscFdpZGVDaGFyU3RyLCBscFN0cmluZyk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJU0hWYWxpZGF0ZVVOQwkJCQlbU0hFTEwzMi4xNzNdCiAqCiAqLwpIUkVTVUxUIFdJTkFQSSBTSFZhbGlkYXRlVU5DIChEV09SRCB4LCBEV09SRCB5LCBEV09SRCB6KQp7CglGSVhNRSgiMHglMDhseCAweCUwOGx4IDB4JTA4bHggc3R1YlxuIix4LHkseik7CglyZXR1cm4gMDsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKglEb0Vudmlyb25tZW50U3Vic3RXCQkJW1NIRUxMMzIuNTNdCiAqCiAqLwpIUkVTVUxUIFdJTkFQSSBEb0Vudmlyb25tZW50U3Vic3RBKExQU1RSIHgsIExQU1RSIHkpCnsKCUZJWE1FKCIoJXAgJXMsICVwICVzKSBzdHViXG4iLCB4LCBkZWJ1Z3N0cl9hKHgpLCB5LCBkZWJ1Z3N0cl9hKHkpKTsKCXJldHVybiAwOwp9CgpIUkVTVUxUIFdJTkFQSSBEb0Vudmlyb25tZW50U3Vic3RXKExQV1NUUiB4LCBMUFdTVFIgeSkKewoJRklYTUUoIiglcCAlcywgJXAgJXMpIHN0dWJcbiIsIHgsIGRlYnVnc3RyX3coeCksIHksIGRlYnVnc3RyX3coeSkpOwoJcmV0dXJuIDA7Cn0KCkhSRVNVTFQgV0lOQVBJIERvRW52aXJvbm1lbnRTdWJzdEFXKExQVk9JRCB4LCBMUFZPSUQgeSkKewoJaWYgKFZFUlNJT05fT3NJc1VuaWNvZGUoKSkKCSAgcmV0dXJuIERvRW52aXJvbm1lbnRTdWJzdFcoeCwgeSk7CglyZXR1cm4gRG9FbnZpcm9ubWVudFN1YnN0QSh4LCB5KTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICBzaGVsbDMyXzI0MyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW1NIRUxMMzIuMjQzXQogKiAKICogV2luOTgrIGJ5LW9yZGluYWwgcm91dGluZS4gIEluIFdpbjk4IHRoaXMgcm91dGluZSByZXR1cm5zIHplcm8gYW5kCiAqIGRvZXMgbm90aGluZyBlbHNlLiAgUG9zc2libHkgdGhpcyBkb2VzIHNvbWV0aGluZyBpbiBOVCBvciBTSEVMTDMyIDUuMD8KICoKICovCgpCT09MIFdJTkFQSSBzaGVsbDMyXzI0MyhEV09SRCBhLCBEV09SRCBiKSAKeyAKICByZXR1cm4gRkFMU0U7IAp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgV2luMzJEZWxldGVGaWxlICAgICAgICAgICAgICAgICAgICAgICAgIFtTSEVMTDMyLjE2NF0gIAogKgogKiBEZWxldGVzIGEgZmlsZS4gIEFsc28gdHJpZ2dlcnMgYSBjaGFuZ2Ugbm90aWZ5IGlmIG9uZSBleGlzdHMsIGJ1dAogKiB0aGF0IG1lY2hhbmlzbSBkb2Vzbid0IHlldCBleGlzdCBpbiBXaW5lJ3MgU0hFTEwzMi4KICoKICogRklYTUU6CiAqIFZlcmlmaWVkIG9uIFdpbjk4IC8gSUUgNSAoU0hFTEwzMiA0LjcyLCBNYXJjaCAxOTk5IGJ1aWxkKSB0byBiZQogKiBBTlNJLiAgSXMgdGhpcyBVbmljb2RlIG9uIE5UPwogKgogKi8gCgpCT09MIFdJTkFQSSBXaW4zMkRlbGV0ZUZpbGUoTFBTVFIgZk5hbWUpCnsKICBGSVhNRSgiJXAoJXMpOiBwYXJ0aWFsIHN0dWJcbiIsIGZOYW1lLCBmTmFtZSk7CgogIERlbGV0ZUZpbGVBKGZOYW1lKTsKCiAgcmV0dXJuIFRSVUU7Cn0KLyoKTFBTVFIgV0lOQVBJIFN0ckNweU5BKExQU1RSIHBzejEsIExQQ1NUUiBwc3oyLCBpbnQgY2NoTWF4KQp7CglyZXR1cm4gbHN0cmNweW5BKHBzejEsIHBzejIsIGNjaE1heCk7Cn0KCkxQV1NUUiBXSU5BUEkgU3RyQ3B5TlcoTFBXU1RSIHBzejEsIExQQ1dTVFIgcHN6MiwgaW50IGNjaE1heCkKewoJcmV0dXJuIGxzdHJjcHluVyhwc3oxLCBwc3oyLCBjY2hNYXgpOwp9CiovCg==