I2luY2x1ZGUgPENvcHlyaWdodC5oPgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKKiBndE1pc2MuYwoqCiogREVTQ1JJUFRJT046CiogICAgICAgQVBJIGRlZmluaXRpb25zIGZvciBJcCBNYXBwaW5nIFRhYmxlCioJCQkJCQkJRUVQUk9NIGFjY2VzcwoqCQkJCQkJCVNjcmF0Y2ggYW5kIE1pc2MgQ29udHJvbAoqIERFUEVOREVOQ0lFUzoKKgoqIEZJTEUgUkVWSVNJT04gTlVNQkVSOgoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwoKI2luY2x1ZGUgPG1zQXBpLmg+CiNpbmNsdWRlIDxndFNlbS5oPgojaW5jbHVkZSA8Z3RId0NudGwuaD4KI2luY2x1ZGUgPGd0RHJ2U3dSZWdzLmg+CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKKiBnc3lzU2V0VXNlSXBNYXBwaW5nVGFibGUKKgoqIERFU0NSSVBUSU9OOgoqICAgICAgIFRoaXMgQVBJIHNldCB0byB1c2UgSVAgRnJhbWUgUHJpb3JpdGllcyBmcm9tIHRoaXMgdGFibGUuIAoqCQlTZXQgR1RfVFJVRTogIFRoZSBJUF9GUFJJIGRhdGEgaW4gdGhpcyB0YWJsZSBpcyB1c2VkIGFzIHRoZSBmcmFtZZJzIAoqCQkJaW5pdGlhbCBJUF9GUFJJIHVzZSBJcCBNYXBwaW5nZyB0YWJsZSBwcmlvcml0aWVzLgoqCQlTZXQgR1RfRkFMU0U6IFRoZSBJUF9GUFJJIGRhdGEgaW4gdGhpcyB0YWJsZSBpcyBpZ25vcmVkLiBJbnN0ZWFkIHRoZSAKKgkJCWZyYW1lknMgaW5pdGlhbCBJUF9GUFJJIGlzIGdlbmVyYXRlZCBieSB1c2luZyB0aGUgZnJhbWWScyBJUF9RUFJJCioJCQlhcyB0aGUgSVBfRlBSSZJzIHVwcGVyIHR3byBiaXRzLCBhbmQgdGhlIElQX0ZQUkmScyBsb3dlc3QgYml0IGNvbWVzIAoqCQkJZnJvbSBiaXQgMCBvZiB0aGUgZnJhbWWScyBzb3VyY2UgcG9ydJJzIERlZmF1bHQgUFJJIChQb3J0IG9mZnNldCAweDA3KS4KKgoqIElOUFVUUzoKKgkJZW4JLSBbR1RfVFJVRV0gLyBbR1RfRkFMU0VdCioKKiBPVVRQVVRTOgoqICAgICAgIE5vbmUuCioKKiBSRVRVUk5TOgoqICAgICAgIEdUX09LICAgICAgLSBvbiBzdWNjZXNzCiogICAgICAgR1RfRkFJTCAgICAtIG9uIGVycm9yCioJCUdUX05PVF9TVVBQT1JURUQgLSBpZiBjdXJyZW50IGRldmljZSBkb2VzIG5vdCBzdXBwb3J0IHRoaXMgZmVhdHVyZS4KKgoqIENPTU1FTlRTOgoqICAgICAgIE5vbmUKKgoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwpHVF9TVEFUVVMgZ3N5c1NldFVzZUlwTWFwcGluZ1RhYmxlCigKICAgIElOICBHVF9RRF9ERVYgCQkqZGV2LAogICAgSU4gIEdUX0JPT0wJCQllbgopCnsKICAgIEdUX1NUQVRVUwlyZXRWYWw7ICAgICAgICAgLyogRnVuY3Rpb25zIHJldHVybiB2YWx1ZS4gICAgICAqLwoJR1RfVTE2CQlkYXRhOwoKICAgIERCR19JTkZPKCgiZ3N5c1NldFVzZUlwTWFwcGluZ1RhYmxlIENhbGxlZC5cbiIpKTsKCgkvKiBDaGVjayBpZiBTd2l0Y2ggc3VwcG9ydHMgdGhpcyBmZWF0dXJlLiAqLwoJaWYgKCFJU19JTl9ERVZfR1JPVVAoZGV2LERFVl9JUF9NQVBQSU5HX1RBQkxFKSkKICAgIHsKICAgICAgICBEQkdfSU5GTygoIkdUX05PVF9TVVBQT1JURURcbiIpKTsKCQlyZXR1cm4gR1RfTk9UX1NVUFBPUlRFRDsKICAgIH0KCglkYXRhID0gKGVuPT1HVF9UUlVFKT8xOjA7CgogICAgcmV0VmFsID0gaHdTZXRHbG9iYWxSZWdGaWVsZChkZXYsUURfUkVHX0lQX01BUFBJTkdfVEFCTEUsMTQsMSxkYXRhKTsKICAgIGlmKHJldFZhbCAhPSBHVF9PSykKICAgCXsKICAgCSAgICBEQkdfSU5GTygoIkZhaWxlZC5cbiIpKTsKICAgCSAgICByZXR1cm4gcmV0VmFsOwogICAgfQoKCXJldHVybiBHVF9PSzsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKKiBnc3lzR2V0VXNlSXBNYXBwaW5nVGFibGUKKgoqIERFU0NSSVBUSU9OOgoqICAgICAgIFRoaXMgQVBJIGdldCB0byB1c2UgSVAgRnJhbWUgUHJpb3JpdGllcyBmcm9tIHRoaXMgdGFibGUuIAoqCQlTZXQgR1RfVFJVRTogIFRoZSBJUF9GUFJJIGRhdGEgaW4gdGhpcyB0YWJsZSBpcyB1c2VkIGFzIHRoZSBmcmFtZZJzIAoqCQkJaW5pdGlhbCBJUF9GUFJJIHVzZSBJcCBNYXBwaW5nZyB0YWJsZSBwcmlvcml0aWVzLgoqCQlTZXQgR1RfRkFMU0U6IFRoZSBJUF9GUFJJIGRhdGEgaW4gdGhpcyB0YWJsZSBpcyBpZ25vcmVkLiBJbnN0ZWFkIHRoZSAKKgkJCWZyYW1lknMgaW5pdGlhbCBJUF9GUFJJIGlzIGdlbmVyYXRlZCBieSB1c2luZyB0aGUgZnJhbWWScyBJUF9RUFJJCioJCQlhcyB0aGUgSVBfRlBSSZJzIHVwcGVyIHR3byBiaXRzLCBhbmQgdGhlIElQX0ZQUkmScyBsb3dlc3QgYml0IGNvbWVzIAoqCQkJZnJvbSBiaXQgMCBvZiB0aGUgZnJhbWWScyBzb3VyY2UgcG9ydJJzIERlZmF1bHQgUFJJIChQb3J0IG9mZnNldCAweDA3KS4KKgoqIElOUFVUUzoKKiAgICAgICBOb25lLgoqCiogT1VUUFVUUzoKKgkJZW4JLSBbR1RfVFJVRV0gLyBbR1RfRkFMU0VdCioKKiBSRVRVUk5TOgoqICAgICAgIEdUX09LICAgICAgLSBvbiBzdWNjZXNzCiogICAgICAgR1RfRkFJTCAgICAtIG9uIGVycm9yCioJCUdUX05PVF9TVVBQT1JURUQgLSBpZiBjdXJyZW50IGRldmljZSBkb2VzIG5vdCBzdXBwb3J0IHRoaXMgZmVhdHVyZS4KKgoqIENPTU1FTlRTOgoqICAgICAgIE5vbmUKKgoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwpHVF9TVEFUVVMgZ3N5c0dldFVzZUlwTWFwcGluZ1RhYmxlCigKICAgIElOICBHVF9RRF9ERVYgCQkqZGV2LAogICAgSU4gIEdUX0JPT0wJCQkqZW4KKQp7CiAgICBHVF9TVEFUVVMJcmV0VmFsOyAgICAgICAgIC8qIEZ1bmN0aW9ucyByZXR1cm4gdmFsdWUuICAgICAgKi8KCUdUX1UxNgkJZGF0YTsKCiAgICBEQkdfSU5GTygoImdzeXNHZXRVc2VJcE1hcHBpbmdUYWJsZSBDYWxsZWQuXG4iKSk7CgoJLyogQ2hlY2sgaWYgU3dpdGNoIHN1cHBvcnRzIHRoaXMgZmVhdHVyZS4gKi8KCWlmICghSVNfSU5fREVWX0dST1VQKGRldixERVZfSVBfTUFQUElOR19UQUJMRSkpCiAgICB7CiAgICAgICAgREJHX0lORk8oKCJHVF9OT1RfU1VQUE9SVEVEXG4iKSk7CgkJcmV0dXJuIEdUX05PVF9TVVBQT1JURUQ7CiAgICB9CgoKICAgIHJldFZhbCA9IGh3R2V0R2xvYmFsUmVnRmllbGQoZGV2LFFEX1JFR19JUF9NQVBQSU5HX1RBQkxFLDE0LDEsJmRhdGEpOwogICAgaWYocmV0VmFsICE9IEdUX09LKQogICAJewogICAJICAgIERCR19JTkZPKCgiRmFpbGVkLlxuIikpOwogICAJICAgIHJldHVybiByZXRWYWw7CiAgICB9CgoJKmVuPSAoZGF0YT09MSk/R1RfVFJVRTpHVF9GQUxTRTsKCglyZXR1cm4gR1RfT0s7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiogZ3N5c1NldElwTWFwcGluZ1ByaW8KKgoqIERFU0NSSVBUSU9OOgoqICAgICAgIFNldCBJUHY0IGFuZCBJUHY2IEZyYW1lIFByaW9yaXR5IE1hcHBpbmcsIGFuZCAKKgkJCUlQdjQgYW5kIElQdjYgUXVldWUgUHJpb3JpdHkgTWFwcGluZy4KKiAgICAgICAgICAgVGhlIGlwRnByaSB2YWx1ZSBpcyB1c2VkIGFzIHRoZSBmcmFtZXMgaW5pdGlhbCBGUFJJIHdoZW4gdGhlIGZyYW1lIGlzIAoqCQkJYW4gSVB2NCBvciBhbiBJUHY2IGZyYW1lLCBhbmQgdGhlIHBvcnSScyBJbml0aWFsUHJpIChQb3J0IG9mZnNldCAweDA0KSAKKgkJCWlzIGNvbmZpZ3VyZWQgdG8gdXNlIElQIEZQcmmScy4KKiAgICAgICAgICAgVGhlIGlwUXByaSB2YWx1ZSBpcyB1c2VkIGFzIHRoZSBmcmFtZZJzIGluaXRpYWwgUVBSSSB3aGVuIHRoZSBmcmFtZSBpcyAKKgkJCWFuIElQdjQgb3IgYW4gSVB2NiBmcmFtZSwgYW5kIHRoZSBwb3J0knMgSW5pdGlhbFByaSBhbmQgVGFnSWZCb3RoIAoqCQkJcmVnaXN0ZXJzIChQb3J0IG9mZnNldCAweDA0KSBhcmUgY29uZmlndXJlZCB0byB1c2UgSVAgUVByaZJzLgoqCiogSU5QVVRTOgoqICAgICAgIHBvaW50IC0gUG9pbnRlciB0byB0aGUgSXAgTWFwcGluZyBUYWJsZS4KKgkJCQkgIDAgLSAweDNmOwoqICAgICAgIGlwRnByaSAtICBUaGUgdmFsdWUgaXMgMCAtIDcKKiAgICAgICBpcFFwcmkgLSAgVGhlIHZhbHVlIGlzIDAgLSAzLgoqCiogT1VUUFVUUzoKKiAgICAgICBOb25lLgoqCiogUkVUVVJOUzoKKiAgICAgICBHVF9PSyAgICAgIC0gb24gc3VjY2VzcwoqICAgICAgIEdUX0ZBSUwgICAgLSBvbiBlcnJvcgoqICAgICAgIEdUX0JBRF9QQVJBTSAtIGlmIGlucHV0IHBhcmFtZXRlcnMgYXJlIGJleW9uZCByYW5nZS4KKgkJR1RfTk9UX1NVUFBPUlRFRCAtIGlmIGN1cnJlbnQgZGV2aWNlIGRvZXMgbm90IHN1cHBvcnQgdGhpcyBmZWF0dXJlLgoqCiogQ09NTUVOVFM6CiogICAgICAgTm9uZQoqCioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCkdUX1NUQVRVUyBnc3lzU2V0SXBNYXBwaW5nUHJpbwooCiAgICBJTiAgR1RfUURfREVWIAkJKmRldiwKICAgIElOICBHVF9VMzIJCQlwb2ludCwKICAgIElOICBHVF9VOAkJCWlwRnByaSwKICAgIElOICBHVF9VOAkJCWlwUXByaQopCnsKICAgIEdUX1NUQVRVUwlyZXRWYWw7ICAgICAgICAgLyogRnVuY3Rpb25zIHJldHVybiB2YWx1ZS4gICAgICAqLwoJR1RfVTE2CQlkYXRhOwoKICAgIERCR19JTkZPKCgiZ3N5c1NldElwTWFwcGluZ1ByaW8gQ2FsbGVkLlxuIikpOwoKCS8qIENoZWNrIGlmIFN3aXRjaCBzdXBwb3J0cyB0aGlzIGZlYXR1cmUuICovCglpZiAoIUlTX0lOX0RFVl9HUk9VUChkZXYsREVWX0lQX01BUFBJTkdfVEFCTEUpKQogICAgewogICAgICAgIERCR19JTkZPKCgiR1RfTk9UX1NVUFBPUlRFRFxuIikpOwoJCXJldHVybiBHVF9OT1RfU1VQUE9SVEVEOwogICAgfQoKCWlmICgocG9pbnQ+MHgzZil8fChpcEZwcmk+Nyl8fChpcFFwcmk+MykpCgl7CiAgICAgICAgREJHX0lORk8oKCJHVF9CQURfUEFSQU1cbiIpKTsKCQlyZXR1cm4gR1RfQkFEX1BBUkFNOwoJfQoKCWd0U2VtVGFrZShkZXYsZGV2LT50YmxSZWdzU2VtLE9TX1dBSVRfRk9SRVZFUik7CgogICAgLyogV2FpdCB1bnRpbCB0aGUgU2NyYXRjaCBhbmQgTWlzYyBjb250cm9sIGlzIHJlYWR5LiAqLwogICAJZGF0YSA9IDE7CiAgICB3aGlsZShkYXRhID09IDEpCiAgIAl7CiAgICAgICAgcmV0VmFsID0gaHdHZXRHbG9iYWxSZWdGaWVsZChkZXYsUURfUkVHX0lQX01BUFBJTkdfVEFCTEUsMTUsMSwmZGF0YSk7CiAgIAkgICAgaWYocmV0VmFsICE9IEdUX09LKQogICAgICAgCXsKCQkJZ3RTZW1HaXZlKGRldixkZXYtPnRibFJlZ3NTZW0pOwogICAJICAgICAgICByZXR1cm4gcmV0VmFsOwogICAgICAgCX0KICAgIH0KCglkYXRhID0gKCgoaXBGcHJpJjcpPDw0KSB8IChpcFFwcmkmMykpOwoJZGF0YSB8PSAgKChHVF9VMTYpKCgxIDw8IDE1KSB8IChwb2ludCA8PCA4KSkpOwoKCXJldFZhbCA9IGh3V3JpdGVHbG9iYWxSZWcoZGV2LCBRRF9SRUdfSVBfTUFQUElOR19UQUJMRSwgZGF0YSk7CiAgICBpZihyZXRWYWwgIT0gR1RfT0spCiAgIAl7CiAgIAkgICAgREJHX0lORk8oKCJGYWlsZWQuXG4iKSk7CiAgICAgICAgZ3RTZW1HaXZlKGRldixkZXYtPnRibFJlZ3NTZW0pOwogICAJICAgIHJldHVybiByZXRWYWw7CiAgICB9CgoKCglndFNlbUdpdmUoZGV2LGRldi0+dGJsUmVnc1NlbSk7CgogICAgaWYocmV0VmFsICE9IEdUX09LKQogICAJewogICAJICAgIERCR19JTkZPKCgiRmFpbGVkLlxuIikpOwogICAJICAgIHJldHVybiByZXRWYWw7CiAgICB9CgoJcmV0dXJuIEdUX09LOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgoqIGdzeXNHZXRJcE1hcHBpbmdQcmlvCioKKiBERVNDUklQVElPTjoKKiAgICAgICBnZXQgSVB2NCBhbmQgSVB2NiBGcmFtZSBQcmlvcml0eSBNYXBwaW5nLCBhbmQgCioJCQlJUHY0IGFuZCBJUHY2IFF1ZXVlIFByaW9yaXR5IE1hcHBpbmcuCiogICAgICAgICAgIFRoZSBpcEZwcmkgdmFsdWUgaXMgdXNlZCBhcyB0aGUgZnJhbWVzIGluaXRpYWwgRlBSSSB3aGVuIHRoZSBmcmFtZSBpcyAKKgkJCWFuIElQdjQgb3IgYW4gSVB2NiBmcmFtZSwgYW5kIHRoZSBwb3J0knMgSW5pdGlhbFByaSAoUG9ydCBvZmZzZXQgMHgwNCkgCioJCQlpcyBjb25maWd1cmVkIHRvIHVzZSBJUCBGUHJpknMuCiogICAgICAgICAgIFRoZSBpcFFwcmkgdmFsdWUgaXMgdXNlZCBhcyB0aGUgZnJhbWWScyBpbml0aWFsIFFQUkkgd2hlbiB0aGUgZnJhbWUgaXMgCioJCQlhbiBJUHY0IG9yIGFuIElQdjYgZnJhbWUsIGFuZCB0aGUgcG9ydJJzIEluaXRpYWxQcmkgYW5kIFRhZ0lmQm90aCAKKgkJCXJlZ2lzdGVycyAoUG9ydCBvZmZzZXQgMHgwNCkgYXJlIGNvbmZpZ3VyZWQgdG8gdXNlIElQIFFQcmmScy4KKgoqIElOUFVUUzoKKiAgICAgICBwb2ludCAtIFBvaW50ZXIgdG8gdGhlIElwIE1hcHBpbmcgVGFibGUuCioJCQkJICAwIC0gMHgzZjsKKgoqIE9VVFBVVFM6CiogICAgICAgaXBGcHJpIC0gIFRoZSB2YWx1ZSBpcyAwIC0gNwoqICAgICAgIGlwUXByaSAtICBUaGUgdmFsdWUgaXMgMCAtIDMuCioKKiBSRVRVUk5TOgoqICAgICAgIEdUX09LICAgICAgLSBvbiBzdWNjZXNzCiogICAgICAgR1RfRkFJTCAgICAtIG9uIGVycm9yCiogICAgICAgR1RfQkFEX1BBUkFNIC0gaWYgaW5wdXQgcGFyYW1ldGVycyBhcmUgYmV5b25kIHJhbmdlLgoqCQlHVF9OT1RfU1VQUE9SVEVEIC0gaWYgY3VycmVudCBkZXZpY2UgZG9lcyBub3Qgc3VwcG9ydCB0aGlzIGZlYXR1cmUuCioKKiBDT01NRU5UUzoKKiAgICAgICBOb25lCioKKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KR1RfU1RBVFVTIGdzeXNHZXRJcE1hcHBpbmdQcmlvCigKICAgIElOICBHVF9RRF9ERVYgCQkqZGV2LAogICAgSU4gIEdUX1UzMgkJCXBvaW50LAogICAgT1VUICBHVF9VOAkJCSppcEZwcmksCiAgICBPVVQgIEdUX1U4CQkJKmlwUXByaQopCnsKICAgIEdUX1NUQVRVUwlyZXRWYWw7ICAgICAgICAgLyogRnVuY3Rpb25zIHJldHVybiB2YWx1ZS4gICAgICAqLwoJR1RfVTE2CQlkYXRhOwoKICAgIERCR19JTkZPKCgiZ3N5c0dldElwTWFwcGluZ1ByaW8gQ2FsbGVkLlxuIikpOwoKCS8qIENoZWNrIGlmIFN3aXRjaCBzdXBwb3J0cyB0aGlzIGZlYXR1cmUuICovCglpZiAoIUlTX0lOX0RFVl9HUk9VUChkZXYsREVWX0lQX01BUFBJTkdfVEFCTEUpKQogICAgewogICAgICAgIERCR19JTkZPKCgiR1RfTk9UX1NVUFBPUlRFRFxuIikpOwoJCXJldHVybiBHVF9OT1RfU1VQUE9SVEVEOwogICAgfQoKCWlmIChwb2ludCA+IDB4M2YpCgl7CiAgICAgICAgREJHX0lORk8oKCJHVF9CQURfUEFSQU1cbiIpKTsKCQlyZXR1cm4gR1RfQkFEX1BBUkFNOwoJfQoKCWd0U2VtVGFrZShkZXYsZGV2LT50YmxSZWdzU2VtLE9TX1dBSVRfRk9SRVZFUik7CgoJZG8gewoJCXJldFZhbCA9IGh3UmVhZEdsb2JhbFJlZyhkZXYsIFFEX1JFR19JUF9NQVBQSU5HX1RBQkxFLCAmZGF0YSk7CgkJaWYocmV0VmFsICE9IEdUX09LKQogICAJCXsKICAgCQkJREJHX0lORk8oKCJGYWlsZWQuXG4iKSk7CgkJCWd0U2VtR2l2ZShkZXYsZGV2LT50YmxSZWdzU2VtKTsKICAgCQkJcmV0dXJuIHJldFZhbDsKCQl9Cgl9IHdoaWxlIChkYXRhJjB4ODAwMCk7CgoKCSppcEZwcmkgPSAoZGF0YSA+PiA0KSAmIDc7CgkqaXBRcHJpID0gKGRhdGEpICYgMzsKCglndFNlbUdpdmUoZGV2LGRldi0+dGJsUmVnc1NlbSk7CgogICAgaWYocmV0VmFsICE9IEdUX09LKQogICAJewogICAJICAgIERCR19JTkZPKCgiRmFpbGVkLlxuIikpOwogICAJICAgIHJldHVybiByZXRWYWw7CiAgICB9CgoJcmV0dXJuIEdUX09LOwp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKKiBlZXByb21PcGVyYXRpb25QZXJmb3JtCioKKiBERVNDUklQVElPTjoKKiAgICAgICBUaGlzIGZ1bmN0aW9uIGFjY2Vzc2VzIEVFUFJPTSBDb21tYW5kIFJlZ2lzdGVyIGFuZCBEYXRhIFJlZ2lzdGVyLgoqICAgICAgIFRoZSBkZXZpY2Ugc3VwcG9ydHMgdGhlIGZvbGxvd2luZyBFRVBST00gCioJCQlvcGVyYXRpb25zCioJCQlHVF9FRVBST01fTk9fT1AgPSBObyBPcGVyYXRpb24KKgkJCUdUX0VFUFJPTV9XUklURV9EQVRBID0gV3JpdGUgRUVQUk9NIGF0IEFkZHIuCioJCQlHVF9FRVBST01fUkVBRF9EQVRBID0gUmVhZCBFRVBST00gZnJvbSBBZGRyLgoqCQkJR1RfRUVQUk9NX1JFU1RBUlQgPSBSZXN0YXJ0IFJlZ2lzdGVyIExvYWRlciBleGVjdXRpb24gYXQgQWRkciAKKgkJCQkoZWVwcm9tRGF0YSA9IGRvbpJ0IGNhcmUgaW4gdGhpcyBjYXNlKQoqCQkJR1RfRUVQUk9NX0hBTFQgPSBIYWx0IChzdG9wIGV4ZWN1dGluZyB0aGUgRUVQUk9NIGlmIGl0cyBub3QgYWxyZWFkeSAKKgkJCQlzdG9wcGVkKQoqCiogSU5QVVRTOgoqICAgICAgIGVlcHJvbU9wICAgICAgLSBFRVBST00gT3Bjb2RlLgoqICAgICAgIGVlcHJvbURhdGEgICAgLSBEYXRhIHRvIGJlIHdyaXR0ZW4gdG8gdGhlIEVFUFJPTSAKKgoqIE9VVFBVVFM6CiogICAgICAgZWVwcm9tRGF0YSAgICAtIERhdGEgdGhhdCB3YXMgcmVhZCBiYWNrIGZyb20gdGhlIEVFUFJPTS4gCioKQ29tbWFuZCByZWdpc3RlciBhYm92ZS4KKgoqIFJFVFVSTlM6CiogICAgICAgR1RfT0sgb24gc3VjY2VzcywKKiAgICAgICBHVF9GQUlMIG90aGVyd2lzZS4KKiAgICAgICBHVF9CQURfUEFSQU0gLSBpZiBpbnB1dCBwYXJhbWV0ZXJzIGFyZSBiZXlvbmQgcmFuZ2UuCioKKiBDT01NRU5UUzoKKgoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwpzdGF0aWMgR1RfU1RBVFVTIGVlcHJvbU9wZXJhdGlvblBlcmZvcm0KKAogICAgSU4gICAgR1RfUURfREVWIAkJCSpkZXYsCiAgICBJTiAgICBHVF9FRVBST01fT1BFUkFUSU9OCWVlcHJvbU9wLAogICAgSU5PVVQgR1RfRUVQUk9NX09QX0RBVEEJCSpvcERhdGEKKQp7CiAgICBHVF9TVEFUVVMgICAgICAgcmV0VmFsOwkvKiBGdW5jdGlvbnMgcmV0dXJuIHZhbHVlICovCiAgICBHVF9VMTYgICAgICAgICAgZGF0YTsgCS8qIHRlbXBvcmFyeSBEYXRhIHN0b3JhZ2UgKi8KICAgIERCR19JTkZPKCgiZWVwcm9tT3BlcmF0aW9uUGVyZm9ybSBDYWxsZWQuXG4iKSk7CgoJLyogQ2hlY2sgaWYgU3dpdGNoIHN1cHBvcnRzIHRoaXMgZmVhdHVyZS4gKi8KCWlmICghSVNfSU5fREVWX0dST1VQKGRldixERVZfRUVQUk9NKSkKICAgIHsKICAgICAgICBEQkdfSU5GTygoIkdUX05PVF9TVVBQT1JURURcbiIpKTsKCQlyZXR1cm4gR1RfTk9UX1NVUFBPUlRFRDsKICAgIH0KCglpZiAoZWVwcm9tT3A+R1RfRUVQUk9NX0hBTFQpCgl7CiAgICAgICAgREJHX0lORk8oKCJHVF9CQURfUEFSQU1cbiIpKTsKCQlyZXR1cm4gR1RfQkFEX1BBUkFNOwoJfQoKICAgIGd0U2VtVGFrZShkZXYsZGV2LT5lZXByb21SZWdzU2VtLE9TX1dBSVRfRk9SRVZFUik7CgoKICAgIC8qIFdhaXQgdW50aWwgdGhlIGVlcHJvbSBpbiByZWFkeS4gKi8KICAgIGRhdGEgPSAxOwogICAgd2hpbGUoZGF0YSA9PSAxKQogICAgewogICAgICAgIHJldFZhbCA9IGh3R2V0R2xvYmFsMlJlZ0ZpZWxkKGRldixRRF9SRUdfRUVQUk9NX0NPTU1BTkQsMTUsMSwmZGF0YSk7CiAgICAgICAgaWYocmV0VmFsICE9IEdUX09LKQogICAgICAgIHsKICAgICAgICAgICAgZ3RTZW1HaXZlKGRldixkZXYtPmVlcHJvbVJlZ3NTZW0pOwogICAgICAgICAgICByZXR1cm4gcmV0VmFsOwogICAgICAgIH0KICAgIH0KCgogICAgLyogU2V0IHRoZSBFRVBST00gT3BlcmF0aW9uIHJlZ2lzdGVyICovCglzd2l0Y2ggKGVlcHJvbU9wKQoJewoJCWNhc2UgR1RfRUVQUk9NX1dSSVRFX0RBVEE6CgkJICAgIHJldFZhbCA9IGh3R2V0R2xvYmFsMlJlZ0ZpZWxkKGRldixRRF9SRUdfRUVQUk9NX0NPTU1BTkQsMTAsMSwmZGF0YSk7CgkJICAgIGlmKHJldFZhbCAhPSBHVF9PSykKCQkgICAgewoJCSAgICAgICAgZ3RTZW1HaXZlKGRldixkZXYtPmVlcHJvbVJlZ3NTZW0pOwoJCSAgICAgICAgcmV0dXJuIHJldFZhbDsKCQkJfQoJCQlpZiAoZGF0YT09MCkKCQkgICAgewoJCSAgICAgICAgZ3RTZW1HaXZlKGRldixkZXYtPmVlcHJvbVJlZ3NTZW0pOwoJCQkJREJHX0lORk8oKCJFRVBST00gaXMgbm90IHdyaXRhYmxlbiIpKTsKCQkgICAgICAgIHJldHVybiBHVF9GQUlMOwoJCQl9CgoJCSAgICByZXRWYWwgPSBod0dldEdsb2JhbDJSZWdGaWVsZChkZXYsUURfUkVHX0VFUFJPTV9DT01NQU5ELDExLDEsJmRhdGEpOwoJCSAgICBpZihyZXRWYWwgIT0gR1RfT0spCgkJICAgIHsKCQkgICAgICAgIGd0U2VtR2l2ZShkZXYsZGV2LT5lZXByb21SZWdzU2VtKTsKCQkgICAgICAgIHJldHVybiByZXRWYWw7CgkJCX0KCQkJaWYgKGRhdGE9PTEpCgkJICAgIHsKCQkgICAgICAgIGd0U2VtR2l2ZShkZXYsZGV2LT5lZXByb21SZWdzU2VtKTsKCQkJCURCR19JTkZPKCgiRUVQUk9NIExvYWRlciBpcyBydW5uaW5nIikpOwoJCSAgICAgICAgcmV0dXJuIEdUX0ZBSUw7CgkJCX0KCgkJCWRhdGEgPSAoR1RfVTE2KW9wRGF0YS0+ZWVwcm9tRGF0YTsKCQkJcmV0VmFsID0gaHdXcml0ZUdsb2JhbDJSZWcoZGV2LFFEX1JFR19FRVBST01fREFUQSxkYXRhKTsKCSAgICAgICAgaWYocmV0VmFsICE9IEdUX09LKQogICAgCSAgICB7CiAgICAgICAgCSAgICBndFNlbUdpdmUoZGV2LGRldi0+ZWVwcm9tUmVnc1NlbSk7CiAgICAgICAgICAgIAlyZXR1cm4gcmV0VmFsOwoJICAgICAgICB9CgoJCQlkYXRhID0gKEdUX1UxNikoKDEgPDwgMTUpIHwgKEdUX0VFUFJPTV9XUklURV9EQVRBIDw8IDEyKSB8IAoJCQkJCShvcERhdGEtPmVlcHJvbUFkZHIgJiAweEZGKSk7CgkJCXJldFZhbCA9IGh3V3JpdGVHbG9iYWwyUmVnKGRldixRRF9SRUdfRUVQUk9NX0NPTU1BTkQsZGF0YSk7CgkgICAgICAgIGlmKHJldFZhbCAhPSBHVF9PSykKICAgIAkgICAgewogICAgICAgIAkgICAgZ3RTZW1HaXZlKGRldixkZXYtPmVlcHJvbVJlZ3NTZW0pOwogICAgICAgICAgICAJcmV0dXJuIHJldFZhbDsKCSAgICAgICAgfQoJCQlicmVhazsKCgkJY2FzZSBHVF9FRVBST01fUkVBRF9EQVRBOgoJCSAgICByZXRWYWwgPSBod0dldEdsb2JhbDJSZWdGaWVsZChkZXYsUURfUkVHX0VFUFJPTV9DT01NQU5ELDExLDEsJmRhdGEpOwoJCSAgICBpZihyZXRWYWwgIT0gR1RfT0spCgkJICAgIHsKCQkgICAgICAgIGd0U2VtR2l2ZShkZXYsZGV2LT5lZXByb21SZWdzU2VtKTsKCQkgICAgICAgIHJldHVybiByZXRWYWw7CgkJCX0KCQkJaWYgKGRhdGE9PTEpCgkJICAgIHsKCQkgICAgICAgIGd0U2VtR2l2ZShkZXYsZGV2LT5lZXByb21SZWdzU2VtKTsKCQkJCURCR19JTkZPKCgiRUVQUk9NIExvYWRlciBpcyBydW5uaW5nIikpOwoJCSAgICAgICAgcmV0dXJuIEdUX0ZBSUw7CgkJCX0KCgkJCWRhdGEgPSAoR1RfVTE2KSgoMSA8PCAxNSkgfCAoR1RfRUVQUk9NX1JFQURfREFUQSA8PCAxMikgfCAKCQkJCQkob3BEYXRhLT5lZXByb21BZGRyICYgMHhGRikpOwoJCQlyZXRWYWwgPSBod1dyaXRlR2xvYmFsMlJlZyhkZXYsUURfUkVHX0VFUFJPTV9DT01NQU5ELGRhdGEpOwoJICAgICAgICBpZihyZXRWYWwgIT0gR1RfT0spCiAgICAJICAgIHsKICAgICAgICAJICAgIGd0U2VtR2l2ZShkZXYsZGV2LT5lZXByb21SZWdzU2VtKTsKICAgICAgICAgICAgCXJldHVybiByZXRWYWw7CgkgICAgICAgIH0KCgkJCQoJCSAgICBkYXRhID0gMTsKCQkgICAgd2hpbGUoZGF0YSA9PSAxKQoJCSAgICB7CgkJICAgICAgICByZXRWYWwgPSBod0dldEdsb2JhbDJSZWdGaWVsZChkZXYsUURfUkVHX0VFUFJPTV9DT01NQU5ELDE1LDEsJmRhdGEpOwoJCSAgICAgICAgaWYocmV0VmFsICE9IEdUX09LKQoJCSAgICAgICAgewoJCSAgICAgICAgICAgIGd0U2VtR2l2ZShkZXYsZGV2LT5lZXByb21SZWdzU2VtKTsKCQkgICAgICAgICAgICByZXR1cm4gcmV0VmFsOwogICAgICAgIAkJfQoJCSAgICB9CgkJCQoKCQkJcmV0VmFsID0gaHdSZWFkR2xvYmFsMlJlZyhkZXYsUURfUkVHX0VFUFJPTV9EQVRBLCZkYXRhKTsKCQkJb3BEYXRhLT5lZXByb21EYXRhID0gKEdUX1UzMilkYXRhOwoKCQkJYnJlYWs7CgoJCWNhc2UgR1RfRUVQUk9NX1JFU1RBUlQ6CgkJCWRhdGEgPSAoR1RfVTE2KSgoMSA8PCAxNSkgfCAoR1RfRUVQUk9NX1JFU1RBUlQgPDwgMTIpIHwgCgkJCQkJKG9wRGF0YS0+ZWVwcm9tQWRkciAmIDB4RkYpKTsKCQkJcmV0VmFsID0gaHdXcml0ZUdsb2JhbDJSZWcoZGV2LFFEX1JFR19FRVBST01fQ09NTUFORCxkYXRhKTsKCSAgICAgICAgaWYocmV0VmFsICE9IEdUX09LKQogICAgCSAgICB7CiAgICAgICAgCSAgICBndFNlbUdpdmUoZGV2LGRldi0+ZWVwcm9tUmVnc1NlbSk7CiAgICAgICAgICAgIAlyZXR1cm4gcmV0VmFsOwoJICAgICAgICB9CgoKCQkJYnJlYWs7CgoJCWNhc2UgR1RfRUVQUk9NX0hBTFQ6CgkJCWRhdGEgPSAoR1RfVTE2KSgoMSA8PCAxNSkgfCAoR1RfRUVQUk9NX0hBTFQgPDwgMTIpIHwgCgkJCQkJKG9wRGF0YS0+ZWVwcm9tQWRkciAmIDB4RkYpKTsKCQkJcmV0VmFsID0gaHdXcml0ZUdsb2JhbDJSZWcoZGV2LFFEX1JFR19FRVBST01fQ09NTUFORCxkYXRhKTsKCSAgICAgICAgaWYocmV0VmFsICE9IEdUX09LKQogICAgCSAgICB7CiAgICAgICAgCSAgICBndFNlbUdpdmUoZGV2LGRldi0+ZWVwcm9tUmVnc1NlbSk7CiAgICAgICAgICAgIAlyZXR1cm4gcmV0VmFsOwoJICAgICAgICB9CgoJCQlicmVhazsKCQlkZWZhdWx0OgoJCQlndFNlbUdpdmUoZGV2LGRldi0+ZWVwcm9tUmVnc1NlbSk7CgkJCXJldHVybiBHVF9GQUlMOwoJfQoKCWd0U2VtR2l2ZShkZXYsZGV2LT5lZXByb21SZWdzU2VtKTsKICAgIHJldHVybiBHVF9PSzsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiogZ3N5c1JlYWRFZXByb20KKgoqIERFU0NSSVBUSU9OOgoqICAgICAgIFJlYWQgRUVQUk9NIGZyb20gRUVQUk9NknMgYWRkcmVzcyB3aGVyZSB0aGUgRUVPcCBpcyBwZXJmb3JtZWQuCioKKiBJTlBVVFM6CiogICAgICAgYWRkciAtIEVFUFJPTSBBZGRyZXNzLiAKKgoqIE9VVFBVVFM6CiogICAgICAgZGF0YSAtICBEYXRhIHRoYXQgd2FzIHJlYWQgYmFjayBmcm9tIHRoZSBFRVBST00uCioKKiBSRVRVUk5TOgoqICAgICAgIEdUX09LICAgICAgLSBvbiBzdWNjZXNzCiogICAgICAgR1RfRkFJTCAgICAtIG9uIGVycm9yCiogICAgICAgR1RfQkFEX1BBUkFNIC0gaWYgaW5wdXQgcGFyYW1ldGVycyBhcmUgYmV5b25kIHJhbmdlLgoqCQlHVF9OT1RfU1VQUE9SVEVEIC0gaWYgY3VycmVudCBkZXZpY2UgZG9lcyBub3Qgc3VwcG9ydCB0aGlzIGZlYXR1cmUuCioKKiBDT01NRU5UUzoKKiAgICAgICBOb25lCioKKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KR1RfU1RBVFVTIGdzeXNSZWFkRWVwcm9tCigKICAgIElOICBHVF9RRF9ERVYgCQkqZGV2LAogICAgSU4gIEdUX1UzMgkJCWFkZHIsCiAgICBPVVQgIEdUX1U4CQkJKmRhdGEKKQp7CiAgICBHVF9TVEFUVVMJcmV0VmFsOyAgICAgICAgIC8qIEZ1bmN0aW9ucyByZXR1cm4gdmFsdWUuICAgICAgKi8KICAgIEdUX0VFUFJPTV9PUEVSQVRJT04JZWVwcm9tT3A7CiAgICBHVF9FRVBST01fT1BfREFUQQlvcERhdGE7CiAKCWVlcHJvbU9wID0gR1RfRUVQUk9NX1JFQURfREFUQTsKCW9wRGF0YS5lZXByb21BZGRyID0gYWRkcjsKCglyZXRWYWwgPSBlZXByb21PcGVyYXRpb25QZXJmb3JtKGRldixlZXByb21PcCwmb3BEYXRhKTsKICAgIGlmKHJldFZhbCAhPSBHVF9PSykKICAgIHsKICAgICAgcmV0dXJuIHJldFZhbDsKICAgIH0KCSpkYXRhID0gKEdUX1U4KW9wRGF0YS5lZXByb21EYXRhOwoJcmV0dXJuIEdUX09LOwoKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKKiBnc3lzV3JpdGVFZXByb20KKgoqIERFU0NSSVBUSU9OOgoqICAgICAgIFdyaXRlIEVFUFJPTSBhdCB0aGUgRUVQUk9NknMgYWRkcmVzcyB3aGVyZSB0aGUgRUVPcCBpcyBwZXJmb3JtZWQuCgoqCiogSU5QVVRTOgoqICAgICAgIGFkZHIgLSBFRVBST00gQWRkcmVzcy4gCiogICAgICAgZGF0YSAtIERhdGEgdG8gYmUgd3JpdHRlbiB0byB0aGUgRUVQUk9NCioKKiBPVVRQVVRTOgoqCQlOb25lCioKKiBSRVRVUk5TOgoqICAgICAgIEdUX09LICAgICAgLSBvbiBzdWNjZXNzCiogICAgICAgR1RfRkFJTCAgICAtIG9uIGVycm9yCiogICAgICAgR1RfQkFEX1BBUkFNIC0gaWYgaW5wdXQgcGFyYW1ldGVycyBhcmUgYmV5b25kIHJhbmdlLgoqCQlHVF9OT1RfU1VQUE9SVEVEIC0gaWYgY3VycmVudCBkZXZpY2UgZG9lcyBub3Qgc3VwcG9ydCB0aGlzIGZlYXR1cmUuCioKKiBDT01NRU5UUzoKKiAgICAgICBOb25lCioKKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KR1RfU1RBVFVTIGdzeXNXcml0ZUVlcHJvbQooCiAgICBJTiAgR1RfUURfREVWIAkJKmRldiwKICAgIElOICBHVF9VMzIJCQlhZGRyLAogICAgSU4gIEdUX1U4CQkJZGF0YQopCnsKICAgIEdUX1NUQVRVUwlyZXRWYWw7ICAgICAgICAgLyogRnVuY3Rpb25zIHJldHVybiB2YWx1ZS4gICAgICAqLwogICAgR1RfRUVQUk9NX09QRVJBVElPTgllZXByb21PcDsKICAgIEdUX0VFUFJPTV9PUF9EQVRBCW9wRGF0YTsKIAoJZWVwcm9tT3AgPSBHVF9FRVBST01fV1JJVEVfREFUQTsKCW9wRGF0YS5lZXByb21BZGRyID0gYWRkcjsKCW9wRGF0YS5lZXByb21EYXRhID0gZGF0YTsKCglyZXRWYWwgPSBlZXByb21PcGVyYXRpb25QZXJmb3JtKGRldixlZXByb21PcCwmb3BEYXRhKTsKICAgIGlmKHJldFZhbCAhPSBHVF9PSykKICAgIHsKICAgICAgcmV0dXJuIHJldFZhbDsKICAgIH0KCXJldHVybiBHVF9PSzsKCn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiogZ3N5c1Jlc3RhcnRFZXByb20KKgoqIERFU0NSSVBUSU9OOgoqICAgICAgIFJlc3RhcnQgUmVnaXN0ZXIgTG9hZGVyIGV4ZWN1dGlvbiBhdCB0aGUgRUVQUk9NknMgYWRkcmVzcyB3aGVyZSB0aGUgRUVPcCAKKgkJaXMgcGVyZm9ybWVkCioKKiBJTlBVVFM6CiogICAgICAgYWRkciAtIEVFUFJPTSBBZGRyZXNzLiAuCioKKiBPVVRQVVRTOgoqICAgICAgIG5vbmUgICAKKgoqIFJFVFVSTlM6CiogICAgICAgR1RfT0sgICAgICAtIG9uIHN1Y2Nlc3MKKiAgICAgICBHVF9GQUlMICAgIC0gb24gZXJyb3IKKiAgICAgICBHVF9CQURfUEFSQU0gLSBpZiBpbnB1dCBwYXJhbWV0ZXJzIGFyZSBiZXlvbmQgcmFuZ2UuCioJCUdUX05PVF9TVVBQT1JURUQgLSBpZiBjdXJyZW50IGRldmljZSBkb2VzIG5vdCBzdXBwb3J0IHRoaXMgZmVhdHVyZS4KKgoqIENPTU1FTlRTOgoqICAgICAgIE5vbmUKKgoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwpHVF9TVEFUVVMgZ3N5c1Jlc3RhcnRFZXByb20KKAogICAgSU4gIEdUX1FEX0RFViAJCSpkZXYsCiAgICBJTiAgR1RfVTMyCQkJYWRkcgopCnsKICAgIEdUX1NUQVRVUwlyZXRWYWw7ICAgICAgICAgLyogRnVuY3Rpb25zIHJldHVybiB2YWx1ZS4gICAgICAqLwogICAgR1RfRUVQUk9NX09QRVJBVElPTgllZXByb21PcDsKICAgIEdUX0VFUFJPTV9PUF9EQVRBCW9wRGF0YTsKIAoJZWVwcm9tT3AgPSBHVF9FRVBST01fUkVTVEFSVDsKCW9wRGF0YS5lZXByb21BZGRyID0gYWRkcjsKCglyZXRWYWwgPSBlZXByb21PcGVyYXRpb25QZXJmb3JtKGRldixlZXByb21PcCwmb3BEYXRhKTsKICAgIGlmKHJldFZhbCAhPSBHVF9PSykKICAgIHsKICAgICAgcmV0dXJuIHJldFZhbDsKICAgIH0KCXJldHVybiBHVF9PSzsKCn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiogZ3N5c0hhbHRFZXByb20KKgoqIERFU0NSSVBUSU9OOgoqICAgICAgIEhhbHQgKHN0b3AgZXhlY3V0aW5nIHRoZSBFRVBST00gaWYgaXRzIG5vdCBhbHJlYWR5IHN0b3BwZWQpCgoqCiogSU5QVVRTOgoqICAgICAgIG5vbmUgIC4KKgoqIE9VVFBVVFM6CiogICAgICAgbm9uZSAgIAoqCiogUkVUVVJOUzoKKiAgICAgICBHVF9PSyAgICAgIC0gb24gc3VjY2VzcwoqICAgICAgIEdUX0ZBSUwgICAgLSBvbiBlcnJvcgoqCQlHVF9OT1RfU1VQUE9SVEVEIC0gaWYgY3VycmVudCBkZXZpY2UgZG9lcyBub3Qgc3VwcG9ydCB0aGlzIGZlYXR1cmUuCioKKiBDT01NRU5UUzoKKiAgICAgICBOb25lCioKKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KR1RfU1RBVFVTIGdzeXNIYWx0RWVwcm9tCigKICAgIElOICBHVF9RRF9ERVYgCQkqZGV2CikKewogICAgR1RfU1RBVFVTCXJldFZhbDsgICAgICAgICAvKiBGdW5jdGlvbnMgcmV0dXJuIHZhbHVlLiAgICAgICovCiAgICBHVF9FRVBST01fT1BFUkFUSU9OCWVlcHJvbU9wOwogICAgR1RfRUVQUk9NX09QX0RBVEEJb3BEYXRhOwogCgllZXByb21PcCA9IEdUX0VFUFJPTV9IQUxUOwoKCXJldFZhbCA9IGVlcHJvbU9wZXJhdGlvblBlcmZvcm0oZGV2LGVlcHJvbU9wLCAgJm9wRGF0YSk7CiAgICBpZihyZXRWYWwgIT0gR1RfT0spCiAgICB7CiAgICAgIHJldHVybiByZXRWYWw7CiAgICB9CglyZXR1cm4gR1RfT0s7Cgp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgoqIGdzeXNHZXRTdEVlcHJvbQoqCiogREVTQ1JJUFRJT046CiogICAgICAgR2V0IEVFUFJPTSBzdGF0dXMuIFRoZXkgYXJlIFJlZ2lzdGVyIExvYWRlciBSdW5uaW5nIHN0YXR1cyBhbmQgRUVQUk9NIAoqCQlXcml0ZSBFbmFibGUgc3RhdHVzCiogICAgICAgcnVuU3QgaXMgR1RfVFJVRTogUmVnaXN0ZXIgTG9hZGVyIFJ1bm5pbmcsIHdoZW5ldmVyIHRoZSByZWdpc3RlciBsb2FkZXIgCioJCQlpcyBidXN5IGV4ZWN1dGluZyB0aGUgaW5zdHJ1Y3Rpb25zIGNvbnRhaW5lZCBpbiB0aGUgRUVQUk9NLgoqICAgICAgIHdyaXRlRW4gaXMgR1RfVFJVRTogRUVQUk9NIFdyaXRlIEVuYWJsZSwgdGhhdCBpbmRpY2F0ZXMgdGhhdCB3cml0aW5nIHRvIAoqCQkJdGhlIEVFUFJPTSBpcyBwb3NzaWJsZS4gCioJCXdyaXRlRW4gaXMgR1RfRkFMU0U6IHRoZSBXcml0ZSBFRVBST00gRUVPcCBhYm92ZSB3aWxsIG5vdCBkbyBhbnl0aGluZy4KKgkJCVRoaXMgcmVmbGVjdHMgdGhlIHZhbHVlIG9mIHRoZSBFRV9XRSBjb25maWd1cmF0aW9uIHBpbiBhZnRlciBSZXNldC4KKgoqIElOUFVUUzoKKiAgICAgICBub25lICAuCioKKiBPVVRQVVRTOgoqICAgICAgIHJ1blN0ICAgLSAgIFtHVF9UUlVFXSAvIFtHVF9GQUxTRSkKKiAgICAgICB3cml0ZUVuIC0gICBbR1RfVFJVRV0gLyBbR1RfRkFMU0UpCioKKiBSRVRVUk5TOgoqICAgICAgIEdUX09LICAgICAgLSBvbiBzdWNjZXNzCiogICAgICAgR1RfRkFJTCAgICAtIG9uIGVycm9yCiogICAgICAgR1RfQkFEX1BBUkFNIC0gaWYgaW5wdXQgcGFyYW1ldGVycyBhcmUgYmV5b25kIHJhbmdlLgoqCQlHVF9OT1RfU1VQUE9SVEVEIC0gaWYgY3VycmVudCBkZXZpY2UgZG9lcyBub3Qgc3VwcG9ydCB0aGlzIGZlYXR1cmUuCioKKiBDT01NRU5UUzoKKiAgICAgICBOb25lCioKKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KR1RfU1RBVFVTIGdzeXNHZXRTdEVlcHJvbQooCiAgICBJTiAgR1RfUURfREVWIAkJKmRldiwKCU9VVCBHVF9CT09MCQkJKndyaXRlRW4sCglPVVQgR1RfQk9PTAkJCSpydW5TdAopCnsKICAgIEdUX1NUQVRVUwlyZXRWYWw7ICAgICAgICAgLyogRnVuY3Rpb25zIHJldHVybiB2YWx1ZS4gICAgICAqLwogICAgR1RfVTE2ICAgICAgZGF0YTsgCQkJLyogdGVtcG9yYXJ5IERhdGEgc3RvcmFnZSAqLwogCgkvKiBDaGVjayBpZiBTd2l0Y2ggc3VwcG9ydHMgdGhpcyBmZWF0dXJlLiAqLwoJaWYgKCFJU19JTl9ERVZfR1JPVVAoZGV2LERFVl9FRVBST00pKQogICAgewogICAgICAgIERCR19JTkZPKCgiR1RfTk9UX1NVUFBPUlRFRFxuIikpOwoJCXJldHVybiBHVF9OT1RfU1VQUE9SVEVEOwogICAgfQoKCXJldFZhbCA9IGh3UmVhZEdsb2JhbDJSZWcoZGV2LFFEX1JFR19FRVBST01fQ09NTUFORCwgJmRhdGEpOwogICAgaWYocmV0VmFsICE9IEdUX09LKQogICAgewogICAgICAgCXJldHVybiByZXRWYWw7CiAgICB9CgoKCSpydW5TdCAgID0gKGRhdGEmR1RfRUVQUk9NX09QX1NUX1JVTk5JTkdfTUFTSyk/R1RfVFJVRTpHVF9GQUxTRTsKCSp3cml0ZUVuID0gKGRhdGEmR1RfRUVQUk9NX09QX1NUX1dSSVRFX0VOX01BU0spP0dUX1RSVUU6R1RfRkFMU0U7CgoJcmV0dXJuIEdUX09LOwoKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKKiBnc3lzU2V0U2NyYXRjaE1pc2NDdHJsCioKKiBERVNDUklQVElPTjoKKiAgICAgICBTZXQgU2NyYXRjaCBhbmQgTWlzYyBjb250cm9sIGRhdGEgdG8gdGhlIFBvaW50ZXIgdG8gdGhlIFNjcmF0Y2ggYW5kIE1pc2MuIAoqCQlDb250cm9sIHJlZ2lzdGVyLgoqCQkJCVNjcmF0Y2ggQnl0ZSAwCioJCQkJU2NyYXRjaCBCeXRlIDEKKgkJCQlHUElPIENvbmZpZ3VyYXRpb24KKgkJCQlSZXNlcnZlZCBmb3IgZnV0dXJlIHVzZQoqCQkJCUdQSU8gRGlyZWN0aW9uCioJCQkJR1BJTyBEYXRhCioJCQkJQ09ORklHIERhdGEgMAoqCQkJCUNPTkZJRyBEYXRhIDEKKgkJCQlDT05GSUcgRGF0YSAyCioJCQkJQ09ORklHIERhdGEgMwoqCQkJCVN5bmNFICYgVEFJQ0xLMTI1knMgRHJpdmUKKgkJCQlQNZJzICYgQ0xLMTI1knMgQ2xvY2sgRHJpdmUKKgkJCQlQNpJzIENsb2NrIERyaXZlCioJCQkJRUVQUk9NIFBhZCBkcml2ZQoqCiogSU5QVVRTOgoqICAgICAgIHBvaW50IC0gUG9pbnRlciB0byB0aGUgU2NyYXRjaCBhbmQgTWlzYy4gQ29udHJvbCByZWdpc3Rlci4KKiAgICAgICBkYXRhIC0gU2NyYXRjaCBhbmQgTWlzYy4gQ29udHJvbCBkYXRhIHdyaXR0ZW4gdG8gdGhlIHJlZ2lzdGVyIAoqCQkJCXBvaW50ZWQgdG8gYnkgdGhlIHBvaW50IGFib3ZlLgoqCiogT1VUUFVUUzoKKiAgICAgICBOb25lLgoqCiogUkVUVVJOUzoKKiAgICAgICBHVF9PSyAgICAgIC0gb24gc3VjY2VzcwoqICAgICAgIEdUX0ZBSUwgICAgLSBvbiBlcnJvcgoqICAgICAgIEdUX0JBRF9QQVJBTSAtIGlmIGlucHV0IHBhcmFtZXRlcnMgYXJlIGJleW9uZCByYW5nZS4KKgkJR1RfTk9UX1NVUFBPUlRFRCAtIGlmIGN1cnJlbnQgZGV2aWNlIGRvZXMgbm90IHN1cHBvcnQgdGhpcyBmZWF0dXJlLgoqCiogQ09NTUVOVFM6CiogICAgICAgTm9uZQoqCioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCkdUX1NUQVRVUyBnc3lzU2V0U2NyYXRjaE1pc2NDdHJsCigKICAgIElOICBHVF9RRF9ERVYgCQkqZGV2LAogICAgSU4gIEdUX1UzMgkJCXBvaW50LAogICAgSU4gIEdUX1U4CQkJZGF0YQopCnsKICAgIEdUX1NUQVRVUwlyZXRWYWw7ICAgICAgICAgLyogRnVuY3Rpb25zIHJldHVybiB2YWx1ZS4gICAgICAqLwogICAgSU4gIEdUX1UxNgkJCXRtcERhdGE7CgoJaWYgKHBvaW50ID4gR1RfU0NSQVRfTUlTQ19SRUdfTUFYKQoJewogICAgICAgIERCR19JTkZPKCgiR1RfQkFEX1BBUkFNXG4iKSk7CgkJcmV0dXJuIEdUX0JBRF9QQVJBTTsKCX0KCglpZiAoKHBvaW50PjB4N2YpfHwoZGF0YT4weGZmKSkKCXsKICAgICAgICBEQkdfSU5GTygoIkdUX0JBRF9QQVJBTVxuIikpOwoJCXJldHVybiBHVF9CQURfUEFSQU07Cgl9CgoJZ3RTZW1UYWtlKGRldixkZXYtPnRibFJlZ3NTZW0sT1NfV0FJVF9GT1JFVkVSKTsKCgkvKiBwcm9ncmFtIFFvUyBXZWlnaHQgVGFibGUsIDQgc2VxdWVuY2VzIGF0IGEgdGltZSAqLwoKICAgIC8qIFdhaXQgdW50aWwgdGhlIFNjcmF0Y2ggYW5kIE1pc2MgY29udHJvbCBpcyByZWFkeS4gKi8KICAgCXRtcERhdGEgPSAxOwogICAgd2hpbGUodG1wRGF0YSA9PSAxKQogICAJewogICAgICAgIHJldFZhbCA9IGh3R2V0R2xvYmFsMlJlZ0ZpZWxkKGRldixRRF9SRUdfU0NSQVRDSF9NSVNDLDE1LDEsJnRtcERhdGEpOwogICAJICAgIGlmKHJldFZhbCAhPSBHVF9PSykKICAgICAgIAl7CgkJCWd0U2VtR2l2ZShkZXYsZGV2LT50YmxSZWdzU2VtKTsKICAgCSAgICAgICAgcmV0dXJuIHJldFZhbDsKICAgICAgIAl9CiAgICB9CgoJdG1wRGF0YSA9ICAoR1RfVTE2KSgoMSA8PCAxNSkgfCAocG9pbnQgPDwgOCkgfCBkYXRhKTsKCglyZXRWYWwgPSBod1dyaXRlR2xvYmFsMlJlZyhkZXYsIFFEX1JFR19TQ1JBVENIX01JU0MsIHRtcERhdGEpOwogICAgaWYocmV0VmFsICE9IEdUX09LKQogICAJewogICAJICAgIERCR19JTkZPKCgiRmFpbGVkLlxuIikpOwogICAgICAgICAgIGd0U2VtR2l2ZShkZXYsZGV2LT50YmxSZWdzU2VtKTsKICAgCSAgICByZXR1cm4gcmV0VmFsOwogICAgfQoKCgoJZ3RTZW1HaXZlKGRldixkZXYtPnRibFJlZ3NTZW0pOwoKICAgCXJldHVybiByZXRWYWw7Cgp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKKiBnc3lzR2V0U2NyYXRjaE1pc2NDdHJsCioKKiBERVNDUklQVElPTjoKKiAgICAgICBHZXQgU2NyYXRjaCBhbmQgTWlzYyBjb250cm9sIGRhdGEgdG8gdGhlIFBvaW50ZXIgdG8gdGhlIFNjcmF0Y2ggYW5kIE1pc2MuIAoqCQlDb250cm9sIHJlZ2lzdGVyLgoqCQkJCVNjcmF0Y2ggQnl0ZSAwCioJCQkJU2NyYXRjaCBCeXRlIDEKKgkJCQlHUElPIENvbmZpZ3VyYXRpb24KKgkJCQlSZXNlcnZlZCBmb3IgZnV0dXJlIHVzZQoqCQkJCUdQSU8gRGlyZWN0aW9uCioJCQkJR1BJTyBEYXRhCioJCQkJQ09ORklHIERhdGEgMAoqCQkJCUNPTkZJRyBEYXRhIDEKKgkJCQlDT05GSUcgRGF0YSAyCioJCQkJQ09ORklHIERhdGEgMwoqCQkJCVN5bmNFICYgVEFJQ0xLMTI1knMgRHJpdmUKKgkJCQlQNZJzICYgQ0xLMTI1knMgQ2xvY2sgRHJpdmUKKgkJCQlQNpJzIENsb2NrIERyaXZlCioJCQkJRUVQUk9NIFBhZCBkcml2ZQoKKgoqIElOUFVUUzoKKiAgICAgICBwb2ludCAtIFBvaW50ZXIgdG8gdGhlIFNjcmF0Y2ggYW5kIE1pc2MuIENvbnRyb2wgcmVnaXN0ZXIuCioKKiBPVVRQVVRTOgoqICAgICAgIGRhdGEgLSBTY3JhdGNoIGFuZCBNaXNjLiBDb250cm9sIGRhdGEgcmVhZCBmcm9tIHRoZSByZWdpc3RlciAKKgkJCQlwb2ludGVkIHRvIGJ5IHRoZSBwb2ludCBhYm92ZS4KKgoqIFJFVFVSTlM6CiogICAgICAgR1RfT0sgICAgICAtIG9uIHN1Y2Nlc3MKKiAgICAgICBHVF9GQUlMICAgIC0gb24gZXJyb3IKKiAgICAgICBHVF9CQURfUEFSQU0gLSBpZiBpbnB1dCBwYXJhbWV0ZXJzIGFyZSBiZXlvbmQgcmFuZ2UuCioJCUdUX05PVF9TVVBQT1JURUQgLSBpZiBjdXJyZW50IGRldmljZSBkb2VzIG5vdCBzdXBwb3J0IHRoaXMgZmVhdHVyZS4KKgoqIENPTU1FTlRTOgoqICAgICAgIE5vbmUKKgoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwpHVF9TVEFUVVMgZ3N5c0dldFNjcmF0Y2hNaXNjQ3RybAooCiAgICBJTiAgR1RfUURfREVWIAkJKmRldiwKICAgIElOICBHVF9VMzIJCQlwb2ludCwKICAgIE9VVCAgR1RfVTgJCQkqZGF0YQopCnsKICAgIEdUX1NUQVRVUwlyZXRWYWw7ICAgICAgICAgLyogRnVuY3Rpb25zIHJldHVybiB2YWx1ZS4gICAgICAqLwogICAgT1VUICBHVF9VMTYJCQl0bXBEYXRhOwoKCWlmIChwb2ludCA+IEdUX1NDUkFUX01JU0NfUkVHX01BWCkKCXsKICAgICAgICBEQkdfSU5GTygoIkdUX0JBRF9QQVJBTVxuIikpOwoJCXJldHVybiBHVF9CQURfUEFSQU07Cgl9CgoJaWYgKHBvaW50PjB4N2YpCgl7CiAgICAgICAgREJHX0lORk8oKCJHVF9CQURfUEFSQU1cbiIpKTsKCQlyZXR1cm4gR1RfQkFEX1BBUkFNOwoJfQoKCWd0U2VtVGFrZShkZXYsZGV2LT50YmxSZWdzU2VtLE9TX1dBSVRfRk9SRVZFUik7CgoJLyogcHJvZ3JhbSBRb1MgV2VpZ2h0IFRhYmxlLCA0IHNlcXVlbmNlcyBhdCBhIHRpbWUgKi8KCglkbyB7CgkJcmV0VmFsID0gaHdSZWFkR2xvYmFsMlJlZyhkZXYsIFFEX1JFR19TQ1JBVENIX01JU0MsICZ0bXBEYXRhKTsKCQlpZihyZXRWYWwgIT0gR1RfT0spCiAgIAkJewogICAJCQlEQkdfSU5GTygoIkZhaWxlZC5cbiIpKTsKCQkJZ3RTZW1HaXZlKGRldixkZXYtPnRibFJlZ3NTZW0pOwogICAJCQlyZXR1cm4gcmV0VmFsOwoJCX0KCX0gd2hpbGUgKHRtcERhdGEmMHg4MDAwKTsKCiAgICAqZGF0YSA9IHRtcERhdGEmMHhmZjsKCglndFNlbUdpdmUoZGV2LGRldi0+dGJsUmVnc1NlbSk7CgoKCXJldHVybiByZXRWYWw7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgoqIGdzeXNTZXRTY3JhdGNoQml0cwoqCiogREVTQ1JJUFRJT046CiogICAgICAgU2V0IHRoZSBTY3JhdGNoIGFuZCBNaXNjLiBDb250cm9sIHJlZ2lzdGVyIDxzY3JhdGNoIGJ5dGUgMCBhbmQgMT4gYml0cy4KKgkJU2NyYXRjaCBiaXRzLiBUaGVzZSBiaXRzIGFyZSAxMDAlIGF2YWlsYWJsZSB0byBzb2Z0d2FyZSBmb3Igd2hhdGV2ZXIgCioJCXB1cnBvc2UgZGVzaXJlZC4gVGhlc2UgYml0cyBkbyBub3QgY29ubmVjdCB0byBhbnkgaGFyZHdhcmUgZnVuY3Rpb24uCioKKiBJTlBVVFM6CiogICAgICAgc2NyaXRjaCAtIHdyaXR0ZW4gYml0cy4KKgoqIE9VVFBVVFM6CiogICAgICAgTm9uZS4KKgoqIFJFVFVSTlM6CiogICAgICAgR1RfT0sgICAgICAtIG9uIHN1Y2Nlc3MKKiAgICAgICBHVF9GQUlMICAgIC0gb24gZXJyb3IKKiAgICAgICBHVF9CQURfUEFSQU0gLSBpZiBpbnB1dCBwYXJhbWV0ZXJzIGFyZSBiZXlvbmQgcmFuZ2UuCioJCUdUX05PVF9TVVBQT1JURUQgLSBpZiBjdXJyZW50IGRldmljZSBkb2VzIG5vdCBzdXBwb3J0IHRoaXMgZmVhdHVyZS4KKgoqIENPTU1FTlRTOgoqICAgICAgIE5vbmUKKgoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwpHVF9TVEFUVVMgZ3N5c1NldFNjcmF0Y2hCaXRzCigKICAgIElOICBHVF9RRF9ERVYgCQkqZGV2LAogICAgSU4gIEdUX1UxNgkJCXNjcmF0Y2gKKQp7CiAgICBHVF9TVEFUVVMJcmV0VmFsOyAgICAgICAgIC8qIEZ1bmN0aW9ucyByZXR1cm4gdmFsdWUuICAgICAgKi8KCiAgICBEQkdfSU5GTygoImdzeXNTZXRTY3JhdGNoQml0cyBDYWxsZWQuXG4iKSk7CgoJLyogQ2hlY2sgaWYgU3dpdGNoIHN1cHBvcnRzIHRoaXMgZmVhdHVyZS4gKi8KCWlmICghSVNfSU5fREVWX0dST1VQKGRldixERVZfU0NSQVRDSF9NSVNDX0NUUkwpKQogICAgewogICAgICAgIERCR19JTkZPKCgiR1RfTk9UX1NVUFBPUlRFRFxuIikpOwoJCXJldHVybiBHVF9OT1RfU1VQUE9SVEVEOwogICAgfQoKCXJldFZhbCA9IGdzeXNTZXRTY3JhdGNoTWlzY0N0cmwoZGV2LCBHVF9TQ1JBVF9NSVNDX1JFR19TQ1JBVF8wLCAoR1RfVTgpKHNjcmF0Y2gmMHhmZikpOwogICAgaWYocmV0VmFsICE9IEdUX09LKQogICAJewogICAJICAgIERCR19JTkZPKCgiRmFpbGVkLlxuIikpOwogICAJICAgIHJldHVybiByZXRWYWw7CiAgICB9CgoJcmV0VmFsID0gZ3N5c1NldFNjcmF0Y2hNaXNjQ3RybChkZXYsIEdUX1NDUkFUX01JU0NfUkVHX1NDUkFUXzEsIChHVF9VOCkoKHNjcmF0Y2g+PjgpJjB4ZmYpKTsKICAgIGlmKHJldFZhbCAhPSBHVF9PSykKICAgCXsKICAgCSAgICBEQkdfSU5GTygoIkZhaWxlZC5cbiIpKTsKICAgCSAgICByZXR1cm4gcmV0VmFsOwogICAgfQoKCXJldHVybiBHVF9PSzsKCn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiogZ3N5c0dldFNjcmF0Y2hCaXRzCioKKiBERVNDUklQVElPTjoKKiAgICAgICBHZXQgdGhlIFNjcmF0Y2ggYW5kIE1pc2MuIENvbnRyb2wgcmVnaXN0ZXIgPHNjcmF0Y2ggYnl0ZSAwIGFuZCAxPiBiaXRzLgoqCQlTY3JhdGNoIGJpdHMuIFRoZXNlIGJpdHMgYXJlIDEwMCUgYXZhaWxhYmxlIHRvIHNvZnR3YXJlIGZvciB3aGF0ZXZlciAKKgkJcHVycG9zZSBkZXNpcmVkLiBUaGVzZSBiaXRzIGRvIG5vdCBjb25uZWN0IHRvIGFueSBoYXJkd2FyZSBmdW5jdGlvbi4KKgoqIElOUFVUUzoKKiAgICAgICBOb25lLgoqCiogT1VUUFVUUzoKKiAgICAgICBzY3JpdGNoIC0gcmVhZCBiaXRzLgoqCiogUkVUVVJOUzoKKiAgICAgICBHVF9PSyAgICAgIC0gb24gc3VjY2VzcwoqICAgICAgIEdUX0ZBSUwgICAgLSBvbiBlcnJvcgoqCQlHVF9OT1RfU1VQUE9SVEVEIC0gaWYgY3VycmVudCBkZXZpY2UgZG9lcyBub3Qgc3VwcG9ydCB0aGlzIGZlYXR1cmUuCioKKiBDT01NRU5UUzoKKiAgICAgICBOb25lCioKKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KR1RfU1RBVFVTIGdzeXNHZXRTY3JhdGNoQml0cwooCiAgICBJTiAgR1RfUURfREVWIAkJKmRldiwKICAgIE9VVCAgR1RfVTE2CQkJKnNjcmF0Y2gKKQp7CiAgICBHVF9TVEFUVVMJcmV0VmFsOyAgICAgICAgIC8qIEZ1bmN0aW9ucyByZXR1cm4gdmFsdWUuICAgICAgKi8KCUdUX1U4CQlkYXRhOwoKICAgIERCR19JTkZPKCgiZ3N5c0dldFNjcmF0Y2hCaXRzIENhbGxlZC5cbiIpKTsKCgkvKiBDaGVjayBpZiBTd2l0Y2ggc3VwcG9ydHMgdGhpcyBmZWF0dXJlLiAqLwoJaWYgKCFJU19JTl9ERVZfR1JPVVAoZGV2LERFVl9TQ1JBVENIX01JU0NfQ1RSTCkpCiAgICB7CiAgICAgICAgREJHX0lORk8oKCJHVF9OT1RfU1VQUE9SVEVEXG4iKSk7CgkJcmV0dXJuIEdUX05PVF9TVVBQT1JURUQ7CiAgICB9CgoJcmV0VmFsID0gZ3N5c0dldFNjcmF0Y2hNaXNjQ3RybChkZXYsIEdUX1NDUkFUX01JU0NfUkVHX1NDUkFUXzEsICZkYXRhKTsKICAgIGlmKHJldFZhbCAhPSBHVF9PSykKICAgCXsKICAgCSAgICBEQkdfSU5GTygoIkZhaWxlZC5cbiIpKTsKICAgCSAgICByZXR1cm4gcmV0VmFsOwogICAgfQoJKnNjcmF0Y2ggPSBkYXRhOwoJKnNjcmF0Y2ggPSAqc2NyYXRjaDw8ODsKCXJldFZhbCA9IGdzeXNHZXRTY3JhdGNoTWlzY0N0cmwoZGV2LCBHVF9TQ1JBVF9NSVNDX1JFR19TQ1JBVF8wLCAmZGF0YSk7CiAgICBpZihyZXRWYWwgIT0gR1RfT0spCiAgIAl7CiAgIAkgICAgREJHX0lORk8oKCJGYWlsZWQuXG4iKSk7CiAgIAkgICAgcmV0dXJuIHJldFZhbDsKICAgIH0KCQoJKnNjcmF0Y2ggfD0gZGF0YTsKCglyZXR1cm4gR1RfT0s7Cgp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgoqIGdzeXNTZXRHcGlvQ29uZmlnTW9kCioKKiBERVNDUklQVElPTjoKKiAgICAgICBTZXQgdGhlIFNjcmF0Y2ggYW5kIE1pc2MuIENvbnRyb2wgcmVnaXN0ZXIgPEdQSU8gQ29uZmlndXJhdGlvbj4uCioJCUdlbmVyYWwgUHVycG9zZSBJbnB1dCBPdXRwdXQgQml0czoKKgkJQml0IDYgLSBHVF9HUElPX0JJVF82OgkxOkdQSU9bNl0JMDpTRV9SQ0xLMQoqCQlCaXQgNSAtIEdUX0dQSU9fQklUXzU6CTE6R1BJT1s1XQkwOlNFX1JDTEswCioJCU5vdywgZm9sbG9pbmcgYml0cyBhcmUgcmVhZCBvbmx5LiAKKgkJQml0IDQgLSBHVF9HUElPX0JJVF80OgkxOkdQSU9bNF0JMDoKKgkJQml0IDMgLSBHVF9HUElPX0JJVF8zOgkxOkdQSU9bM10JMDoKKgkJQml0IDIgLSBHVF9HUElPX0JJVF8yOgkxOkdQSU9bMl0JMDoKKgkJQml0IDEgLSBHVF9HUElPX0JJVF8xOgkxOkdQSU9bMV0JMDpQNl9DT0wKKgkJQml0IDAgLSBHVF9HUElPX0JJVF8wOgkxOkdQSU9bMF0JMDpQNl9DUlMKCioKKiBJTlBVVFM6CiogICAgICAgbW9kZSAtIE9SIFtHVF9HUElPX0JJVF94XQoqCiogT1VUUFVUUzoKKiAgICAgICBOb25lLgoqCiogUkVUVVJOUzoKKiAgICAgICBHVF9PSyAgICAgIC0gb24gc3VjY2VzcwoqICAgICAgIEdUX0ZBSUwgICAgLSBvbiBlcnJvcgoqICAgICAgIEdUX0JBRF9QQVJBTSAtIGlmIGlucHV0IHBhcmFtZXRlcnMgYXJlIGJleW9uZCByYW5nZS4KKgkJR1RfTk9UX1NVUFBPUlRFRCAtIGlmIGN1cnJlbnQgZGV2aWNlIGRvZXMgbm90IHN1cHBvcnQgdGhpcyBmZWF0dXJlLgoqCiogQ09NTUVOVFM6CiogICAgICAgTm9uZQoqCioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCkdUX1NUQVRVUyBnc3lzU2V0R3Bpb0NvbmZpZ01vZAooCiAgICBJTiAgR1RfUURfREVWIAkJKmRldiwKICAgIElOICBHVF9VMzIJCQltb2RlCikKewogICAgR1RfU1RBVFVTCXJldFZhbDsgICAgICAgICAvKiBGdW5jdGlvbnMgcmV0dXJuIHZhbHVlLiAgICAgICovCgogICAgREJHX0lORk8oKCJnc3lzU2V0R3Bpb0NvbmZpZ01vZCBDYWxsZWQuXG4iKSk7CgoJLyogQ2hlY2sgaWYgU3dpdGNoIHN1cHBvcnRzIHRoaXMgZmVhdHVyZS4gKi8KCWlmICghSVNfSU5fREVWX0dST1VQKGRldixERVZfU0NSQVRDSF9NSVNDX0NUUkwpKQogICAgewogICAgICAgIERCR19JTkZPKCgiR1RfTk9UX1NVUFBPUlRFRFxuIikpOwoJCXJldHVybiBHVF9OT1RfU1VQUE9SVEVEOwogICAgfQoKCXJldFZhbCA9IGdzeXNTZXRTY3JhdGNoTWlzY0N0cmwoZGV2LCBHVF9TQ1JBVF9NSVNDX1JFR19HUElPX0NGRywgKEdUX1U4KShtb2RlJjB4N2YpKTsKICAgIGlmKHJldFZhbCAhPSBHVF9PSykKICAgCXsKICAgCSAgICBEQkdfSU5GTygoIkZhaWxlZC5cbiIpKTsKICAgCSAgICByZXR1cm4gcmV0VmFsOwogICAgfQoKCglyZXR1cm4gR1RfT0s7Cgp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgoqIGdzeXNHZXRHcGlvQ29uZmlnTW9kCioKKiBERVNDUklQVElPTjoKKiAgICAgICBHZXQgdGhlIFNjcmF0Y2ggYW5kIE1pc2MuIENvbnRyb2wgcmVnaXN0ZXIgPEdQSU8gQ29uZmlndXJhdGlvbj4uCioJCUdlbmVyYWwgUHVycG9zZSBJbnB1dCBPdXRwdXQgQml0czoKKgkJQml0IDYgLSBHVF9HUElPX0JJVF82OgkxOkdQSU9bNl0JMDpTRV9SQ0xLMQoqCQlCaXQgNSAtIEdUX0dQSU9fQklUXzU6CTE6R1BJT1s1XQkwOlNFX1JDTEswCioJCU5vdywgZm9sbG9pbmcgYml0cyBhcmUgcmVhZCBvbmx5LiAKKgkJQml0IDQgLSBHVF9HUElPX0JJVF80OgkxOkdQSU9bNF0JMDoKKgkJQml0IDMgLSBHVF9HUElPX0JJVF8zOgkxOkdQSU9bM10JMDoKKgkJQml0IDIgLSBHVF9HUElPX0JJVF8yOgkxOkdQSU9bMl0JMDoKKgkJQml0IDEgLSBHVF9HUElPX0JJVF8xOgkxOkdQSU9bMV0JMDpQNl9DT0wKKgkJQml0IDAgLSBHVF9HUElPX0JJVF8wOgkxOkdQSU9bMF0JMDpQNl9DUlMKCioKKiBJTlBVVFM6CiogICAgICAgTm9uZS4KKgoqIE9VVFBVVFM6CiogICAgICAgbW9kZSAtIE9SIFtHVF9HUElPX0JJVF94XQoqCiogUkVUVVJOUzoKKiAgICAgICBHVF9PSyAgICAgIC0gb24gc3VjY2VzcwoqICAgICAgIEdUX0ZBSUwgICAgLSBvbiBlcnJvcgoqCQlHVF9OT1RfU1VQUE9SVEVEIC0gaWYgY3VycmVudCBkZXZpY2UgZG9lcyBub3Qgc3VwcG9ydCB0aGlzIGZlYXR1cmUuCioKKiBDT01NRU5UUzoKKiAgICAgICBOb25lCioKKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KR1RfU1RBVFVTIGdzeXNHZXRHcGlvQ29uZmlnTW9kCigKICAgIElOICBHVF9RRF9ERVYgCQkqZGV2LAogICAgSU4gIEdUX1UzMgkJCSptb2RlCikKewogICAgR1RfU1RBVFVTCXJldFZhbDsgICAgICAgICAvKiBGdW5jdGlvbnMgcmV0dXJuIHZhbHVlLiAgICAgICovCglHVF9VOAkJZGF0YTsKCiAgICBEQkdfSU5GTygoImdzeXNHZXRHcGlvQ29uZmlnTW9kIENhbGxlZC5cbiIpKTsKCgkvKiBDaGVjayBpZiBTd2l0Y2ggc3VwcG9ydHMgdGhpcyBmZWF0dXJlLiAqLwoJaWYgKCFJU19JTl9ERVZfR1JPVVAoZGV2LERFVl9TQ1JBVENIX01JU0NfQ1RSTCkpCiAgICB7CiAgICAgICAgREJHX0lORk8oKCJHVF9OT1RfU1VQUE9SVEVEXG4iKSk7CgkJcmV0dXJuIEdUX05PVF9TVVBQT1JURUQ7CiAgICB9CgoJcmV0VmFsID0gZ3N5c0dldFNjcmF0Y2hNaXNjQ3RybChkZXYsIEdUX1NDUkFUX01JU0NfUkVHX0dQSU9fQ0ZHLCAmZGF0YSk7CiAgICBpZihyZXRWYWwgIT0gR1RfT0spCiAgIAl7CiAgIAkgICAgREJHX0lORk8oKCJGYWlsZWQuXG4iKSk7CiAgIAkgICAgcmV0dXJuIHJldFZhbDsKICAgIH0KCQoJKm1vZGUgPSAweDdmJmRhdGE7CgoJcmV0dXJuIEdUX09LOwoKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKKiBnc3lzU2V0R3Bpb0RpcmVjdGlvbgoqCiogREVTQ1JJUFRJT046CiogICAgICAgU2V0IHRoZSBTY3JhdGNoIGFuZCBNaXNjLiBDb250cm9sIHJlZ2lzdGVyIDxHUElPIERpcmVjdGlvbj4uCioJCUdlbmVyYWwgUHVycG9zZSBJbnB1dCBPdXRwdXQgQml0czoKKgkJQml0IDYgLSBHVF9HUElPX0JJVF82OgkxOkdQSU9bNl0JMDpTRV9SQ0xLMQoqCQlCaXQgNSAtIEdUX0dQSU9fQklUXzU6CTE6R1BJT1s1XQkwOlNFX1JDTEswCioJCU5vdywgZm9sbG9pbmcgYml0cyBhcmUgcmVhZCBvbmx5LiAKKgkJQml0IDQgLSBHVF9HUElPX0JJVF80OgkxOkdQSU9bNF0JMDoKKgkJQml0IDMgLSBHVF9HUElPX0JJVF8zOgkxOkdQSU9bM10JMDoKKgkJQml0IDIgLSBHVF9HUElPX0JJVF8yOgkxOkdQSU9bMl0JMDoKKgkJQml0IDEgLSBHVF9HUElPX0JJVF8xOgkxOkdQSU9bMV0JMDpQNl9DT0wKKgkJQml0IDAgLSBHVF9HUElPX0JJVF8wOgkxOkdQSU9bMF0JMDpQNl9DUlMKKgoqIElOUFVUUzoKKiAgICAgICBkaXIgLSBPUiBbR1RfR1BJT19CSVRfeF0KKgoqIE9VVFBVVFM6CiogICAgICAgTm9uZS4KKgoqIFJFVFVSTlM6CiogICAgICAgR1RfT0sgICAgICAtIG9uIHN1Y2Nlc3MKKiAgICAgICBHVF9GQUlMICAgIC0gb24gZXJyb3IKKiAgICAgICBHVF9CQURfUEFSQU0gLSBpZiBpbnB1dCBwYXJhbWV0ZXJzIGFyZSBiZXlvbmQgcmFuZ2UuCioJCUdUX05PVF9TVVBQT1JURUQgLSBpZiBjdXJyZW50IGRldmljZSBkb2VzIG5vdCBzdXBwb3J0IHRoaXMgZmVhdHVyZS4KKgoqIENPTU1FTlRTOgoqICAgICAgIE5vbmUKKgoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwpHVF9TVEFUVVMgZ3N5c1NldEdwaW9EaXJlY3Rpb24KKAogICAgSU4gIEdUX1FEX0RFViAJCSpkZXYsCiAgICBJTiAgR1RfVTMyCQkJZGlyCikKewogICAgR1RfU1RBVFVTCXJldFZhbDsgICAgICAgICAvKiBGdW5jdGlvbnMgcmV0dXJuIHZhbHVlLiAgICAgICovCgogICAgREJHX0lORk8oKCJnc3lzU2V0R3Bpb0RpcmVjdGlvbiBDYWxsZWQuXG4iKSk7CgoJLyogQ2hlY2sgaWYgU3dpdGNoIHN1cHBvcnRzIHRoaXMgZmVhdHVyZS4gKi8KCWlmICghSVNfSU5fREVWX0dST1VQKGRldixERVZfU0NSQVRDSF9NSVNDX0NUUkwpKQogICAgewogICAgICAgIERCR19JTkZPKCgiR1RfTk9UX1NVUFBPUlRFRFxuIikpOwoJCXJldHVybiBHVF9OT1RfU1VQUE9SVEVEOwogICAgfQoKCXJldFZhbCA9IGdzeXNTZXRTY3JhdGNoTWlzY0N0cmwoZGV2LCBHVF9TQ1JBVF9NSVNDX1JFR19HUElPX0RJUiwgKEdUX1U4KShkaXImMHg3ZikpOwogICAgaWYocmV0VmFsICE9IEdUX09LKQogICAJewogICAJICAgIERCR19JTkZPKCgiRmFpbGVkLlxuIikpOwogICAJICAgIHJldHVybiByZXRWYWw7CiAgICB9CgoKCXJldHVybiBHVF9PSzsKCn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiogZ3N5c0dldEdwaW9EaXJlY3Rpb24KKgoqIERFU0NSSVBUSU9OOgoqICAgICAgIEdldCB0aGUgU2NyYXRjaCBhbmQgTWlzYy4gQ29udHJvbCByZWdpc3RlciA8R1BJTyBEaXJlY3Rpb24+LgoqCQlHZW5lcmFsIFB1cnBvc2UgSW5wdXQgT3V0cHV0IEJpdHM6CioJCUJpdCA2IC0gR1RfR1BJT19CSVRfNjoJMTpHUElPWzZdCTA6U0VfUkNMSzEKKgkJQml0IDUgLSBHVF9HUElPX0JJVF81OgkxOkdQSU9bNV0JMDpTRV9SQ0xLMAoqCQlOb3csIGZvbGxvaW5nIGJpdHMgYXJlIHJlYWQgb25seS4gCioJCUJpdCA0IC0gR1RfR1BJT19CSVRfNDoJMTpHUElPWzRdCTA6CioJCUJpdCAzIC0gR1RfR1BJT19CSVRfMzoJMTpHUElPWzNdCTA6CioJCUJpdCAyIC0gR1RfR1BJT19CSVRfMjoJMTpHUElPWzJdCTA6CioJCUJpdCAxIC0gR1RfR1BJT19CSVRfMToJMTpHUElPWzFdCTA6UDZfQ09MCioJCUJpdCAwIC0gR1RfR1BJT19CSVRfMDoJMTpHUElPWzBdCTA6UDZfQ1JTCioKKiBJTlBVVFM6CiogICAgICAgTm9uZS4KKgoqIE9VVFBVVFM6CiogICAgICAgZGlyIC0gT1IgW0dUX0dQSU9fQklUX3hdCioKKiBSRVRVUk5TOgoqICAgICAgIEdUX09LICAgICAgLSBvbiBzdWNjZXNzCiogICAgICAgR1RfRkFJTCAgICAtIG9uIGVycm9yCioJCUdUX05PVF9TVVBQT1JURUQgLSBpZiBjdXJyZW50IGRldmljZSBkb2VzIG5vdCBzdXBwb3J0IHRoaXMgZmVhdHVyZS4KKgoqIENPTU1FTlRTOgoqICAgICAgIE5vbmUKKgoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwpHVF9TVEFUVVMgZ3N5c0dldEdwaW9EaXJlY3Rpb24KKAogICAgSU4gIEdUX1FEX0RFViAJCSpkZXYsCiAgICBPVVQgIEdUX1UzMgkJCSpkaXIKKQp7CiAgICBHVF9TVEFUVVMJcmV0VmFsOyAgICAgICAgIC8qIEZ1bmN0aW9ucyByZXR1cm4gdmFsdWUuICAgICAgKi8KCUdUX1U4CQlkYXRhOwoKICAgIERCR19JTkZPKCgiZ3N5c0dldEdwaW9EaXJlY3Rpb24gQ2FsbGVkLlxuIikpOwoKCS8qIENoZWNrIGlmIFN3aXRjaCBzdXBwb3J0cyB0aGlzIGZlYXR1cmUuICovCglpZiAoIUlTX0lOX0RFVl9HUk9VUChkZXYsREVWX1NDUkFUQ0hfTUlTQ19DVFJMKSkKICAgIHsKICAgICAgICBEQkdfSU5GTygoIkdUX05PVF9TVVBQT1JURURcbiIpKTsKCQlyZXR1cm4gR1RfTk9UX1NVUFBPUlRFRDsKICAgIH0KCglyZXRWYWwgPSBnc3lzR2V0U2NyYXRjaE1pc2NDdHJsKGRldiwgR1RfU0NSQVRfTUlTQ19SRUdfR1BJT19ESVIsICZkYXRhKTsKICAgIGlmKHJldFZhbCAhPSBHVF9PSykKICAgCXsKICAgCSAgICBEQkdfSU5GTygoIkZhaWxlZC5cbiIpKTsKICAgCSAgICByZXR1cm4gcmV0VmFsOwogICAgfQoKCSpkaXIgPSBkYXRhOwoKCXJldHVybiBHVF9PSzsKCn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgoqIGdzeXNTZXRHcGlvRGF0YQoqCiogREVTQ1JJUFRJT046CiogICAgICAgU2V0IHRoZSBTY3JhdGNoIGFuZCBNaXNjLiBDb250cm9sIHJlZ2lzdGVyIDxHUElPIGRhdGE+LgoqCQlHZW5lcmFsIFB1cnBvc2UgSW5wdXQgT3V0cHV0IEJpdHM6CioJCUJpdCA2IC0gR1RfR1BJT19CSVRfNjoJMTpHUElPWzZdCTA6U0VfUkNMSzEKKgkJQml0IDUgLSBHVF9HUElPX0JJVF81OgkxOkdQSU9bNV0JMDpTRV9SQ0xLMAoqCQlOb3csIGZvbGxvaW5nIGJpdHMgYXJlIHJlYWQgb25seS4gCioJCUJpdCA0IC0gR1RfR1BJT19CSVRfNDoJMTpHUElPWzRdCTA6CioJCUJpdCAzIC0gR1RfR1BJT19CSVRfMzoJMTpHUElPWzNdCTA6CioJCUJpdCAyIC0gR1RfR1BJT19CSVRfMjoJMTpHUElPWzJdCTA6CioJCUJpdCAxIC0gR1RfR1BJT19CSVRfMToJMTpHUElPWzFdCTA6UDZfQ09MCioJCUJpdCAwIC0gR1RfR1BJT19CSVRfMDoJMTpHUElPWzBdCTA6UDZfQ1JTCioKKiBJTlBVVFM6CiogICAgICAgZGF0YSAtIE9SIFtHVF9HUElPX0JJVF94XQoqCiogT1VUUFVUUzoKKiAgICAgICBOb25lLgoqCiogUkVUVVJOUzoKKiAgICAgICBHVF9PSyAgICAgIC0gb24gc3VjY2VzcwoqICAgICAgIEdUX0ZBSUwgICAgLSBvbiBlcnJvcgoqICAgICAgIEdUX0JBRF9QQVJBTSAtIGlmIGlucHV0IHBhcmFtZXRlcnMgYXJlIGJleW9uZCByYW5nZS4KKgkJR1RfTk9UX1NVUFBPUlRFRCAtIGlmIGN1cnJlbnQgZGV2aWNlIGRvZXMgbm90IHN1cHBvcnQgdGhpcyBmZWF0dXJlLgoqCiogQ09NTUVOVFM6CiogICAgICAgTm9uZQoqCioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCkdUX1NUQVRVUyBnc3lzU2V0R3Bpb0RhdGEKKAogICAgSU4gIEdUX1FEX0RFViAJCSpkZXYsCiAgICBJTiAgR1RfVTMyCQkJZGF0YQopCnsKICAgIEdUX1NUQVRVUwlyZXRWYWw7ICAgICAgICAgLyogRnVuY3Rpb25zIHJldHVybiB2YWx1ZS4gICAgICAqLwoKICAgIERCR19JTkZPKCgiZ3N5c1NldEdwaW9EYXRhIENhbGxlZC5cbiIpKTsKCgkvKiBDaGVjayBpZiBTd2l0Y2ggc3VwcG9ydHMgdGhpcyBmZWF0dXJlLiAqLwoJaWYgKCFJU19JTl9ERVZfR1JPVVAoZGV2LERFVl9TQ1JBVENIX01JU0NfQ1RSTCkpCiAgICB7CiAgICAgICAgREJHX0lORk8oKCJHVF9OT1RfU1VQUE9SVEVEXG4iKSk7CgkJcmV0dXJuIEdUX05PVF9TVVBQT1JURUQ7CiAgICB9CgoJcmV0VmFsID0gZ3N5c1NldFNjcmF0Y2hNaXNjQ3RybChkZXYsIEdUX1NDUkFUX01JU0NfUkVHX0dQSU9fREFULCAoR1RfVTgpKGRhdGEmMHg3ZikpOwogICAgaWYocmV0VmFsICE9IEdUX09LKQogICAJewogICAJICAgIERCR19JTkZPKCgiRmFpbGVkLlxuIikpOwogICAJICAgIHJldHVybiByZXRWYWw7CiAgICB9CgoKCXJldHVybiBHVF9PSzsKCn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiogZ3N5c0dldEdwaW9EYXRhCioKKiBERVNDUklQVElPTjoKKiAgICAgICBHZXQgdGhlIFNjcmF0Y2ggYW5kIE1pc2MuIENvbnRyb2wgcmVnaXN0ZXIgPEdQSU8gZGF0YT4uCioJCUdlbmVyYWwgUHVycG9zZSBJbnB1dCBPdXRwdXQgQml0czoKKgkJQml0IDYgLSBHVF9HUElPX0JJVF82OgkxOkdQSU9bNl0JMDpTRV9SQ0xLMQoqCQlCaXQgNSAtIEdUX0dQSU9fQklUXzU6CTE6R1BJT1s1XQkwOlNFX1JDTEswCioJCU5vdywgZm9sbG9pbmcgYml0cyBhcmUgcmVhZCBvbmx5LiAKKgkJQml0IDQgLSBHVF9HUElPX0JJVF80OgkxOkdQSU9bNF0JMDoKKgkJQml0IDMgLSBHVF9HUElPX0JJVF8zOgkxOkdQSU9bM10JMDoKKgkJQml0IDIgLSBHVF9HUElPX0JJVF8yOgkxOkdQSU9bMl0JMDoKKgkJQml0IDEgLSBHVF9HUElPX0JJVF8xOgkxOkdQSU9bMV0JMDpQNl9DT0wKKgkJQml0IDAgLSBHVF9HUElPX0JJVF8wOgkxOkdQSU9bMF0JMDpQNl9DUlMKKgoqIElOUFVUUzoKKiAgICAgICBOb25lLgoqCiogT1VUUFVUUzoKKiAgICAgICBkYXRhIC0gT1IgW0dUX0dQSU9fQklUX3hdCioKKiBSRVRVUk5TOgoqICAgICAgIEdUX09LICAgICAgLSBvbiBzdWNjZXNzCiogICAgICAgR1RfRkFJTCAgICAtIG9uIGVycm9yCioJCUdUX05PVF9TVVBQT1JURUQgLSBpZiBjdXJyZW50IGRldmljZSBkb2VzIG5vdCBzdXBwb3J0IHRoaXMgZmVhdHVyZS4KKgoqIENPTU1FTlRTOgoqICAgICAgIE5vbmUKKgoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwpHVF9TVEFUVVMgZ3N5c0dldEdwaW9EYXRhCigKICAgIElOICBHVF9RRF9ERVYgCQkqZGV2LAogICAgSU4gIEdUX1UzMgkJCSpkYXRhCikKewogICAgR1RfU1RBVFVTCXJldFZhbDsgICAgICAgICAvKiBGdW5jdGlvbnMgcmV0dXJuIHZhbHVlLiAgICAgICovCglHVF9VOAkJdG1wRGF0YTsKCiAgICBEQkdfSU5GTygoImdzeXNHZXRHcGlvRGF0YSBDYWxsZWQuXG4iKSk7CgoJLyogQ2hlY2sgaWYgU3dpdGNoIHN1cHBvcnRzIHRoaXMgZmVhdHVyZS4gKi8KCWlmICghSVNfSU5fREVWX0dST1VQKGRldixERVZfU0NSQVRDSF9NSVNDX0NUUkwpKQogICAgewogICAgICAgIERCR19JTkZPKCgiR1RfTk9UX1NVUFBPUlRFRFxuIikpOwoJCXJldHVybiBHVF9OT1RfU1VQUE9SVEVEOwogICAgfQoKCXJldFZhbCA9IGdzeXNHZXRTY3JhdGNoTWlzY0N0cmwoZGV2LCBHVF9TQ1JBVF9NSVNDX1JFR19HUElPX0RBVCwgJnRtcERhdGEpOwogICAgaWYocmV0VmFsICE9IEdUX09LKQogICAJewogICAJICAgIERCR19JTkZPKCgiRmFpbGVkLlxuIikpOwogICAJICAgIHJldHVybiByZXRWYWw7CiAgICB9CgoJKmRhdGEgPSB0bXBEYXRhOwoKCXJldHVybiBHVF9PSzsKCn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiogZ3N5c0dldENvbmZpZ0RhdGEKKgoqIERFU0NSSVBUSU9OOgoqICAgICAgIEdldCBSZXNldCBDb25maWd1cmF0aW9uIHBpbiBkYXRhIDAtMy4gCioJCVRoZXNlIHJlZ2lzdGVycyByZXR1cm4gdGhlIHZhbHVlcyBvYnNlcnZlZCBhZnRlciBhIGhhcmR3YXJlIFJlc2V0IG9uIHRoZSAKKgkJbGlzdGVkIENPTkZJRyBkYXRhIGxpc3RlZCBiZWxvdy4KKgkJCUNvbmZpZyBkYXRhIDA6CioJCQkJMCBVU0VSWzBdIFA2X09VVERbNV0KKgkJCQkxIFVTRVJbMV0gUDZfT1VURFs2XQoqCQkJCTIgVVNFUlsyXSBQNl9PVVREWzddCioJCQkJMyBBRERSWzBdIFA1X09VVERbMF0KKgkJCQk0IEFERFJbMV0gUDVfT1VURFs1XQoqCQkJCTUgQUREUlsyXSBQNV9PVVREWzZdCioJCQkJNiBBRERSXTNdIFA1X09VVERbN10KKgkJCQk3IEFERFJbNF0gUDVfT1VURFsxXQoqCQkJQ29uZmlnIGRhdGEgMToKKgkJCQkwIExFRF9TRUxbMF0gUDFfTEVECioJCQkJMSBMRURfU0VMWzFdIFAyX0xFRAoqCQkJCTIgNENPTCBQM19MRUQKKgkJCQkzIE5vcm1DeCBQNF9MRUQKKgkJCQk0IEp1bWJvIFAwX0xFRAoqCQkJCTUgRUVfV0UgRUVfQ1MvQzJfTEVECioJCQkJNiBGRF9GTE9XIEVFX0NMSy9DMV9MRUQKKgkJCQk3IEhEX0ZMT1cgRUVfRElOL0MwX0xFRAoqCQkJQ29uZmlnIGRhdGEgMjoKKgkJCQkwIFA1X01PREVbMF0gUDVfT1VURFsyXQoqCQkJCTEgUDVfTU9ERVsxXSBQNV9PVVREWzNdCioJCQkJMiBQNV9NT0RFWzJdIFA1X09VVERbNF0KKgkJCQkzIFJlc2VydmVkIGZvciBmdXR1cmUgdXNlUDVfSEFMRkRQWCBQNV9PVVRFTgoqCQkJCTQgUDZfTU9ERVswXSBQNl9PVVREWzJdCioJCQkJNSBQNl9NT0RFWzFdIFA2X09VVERbM10KKgkJCQk2IFA2X01PREVbMl0gUDZfT1VURFs0XQoqCQkJCTcgUmVzZXJ2ZWQgZm9yIGZ1dHVyZSB1c2VQNl9IQUxGRFBYIFA2X09VVEVOCioJCQlDb25maWcgZGF0YSAyOgoqCQkJCTAgUk1VX01PREVbMF0gUDZfT1VURFswXQoqCQkJCTEgUk1VX01PREVbMV0gUDZfT1VURFsxXQoqCQkJCTIgCioJCQkJMwoqCQkJCTQKKgkJCQk1CioJCQkJNgoqCQkJCTcKCiogSU5QVVRTOgoqICAgICAgIG5vbmUuCioKKiBPVVRQVVRTOgoqICAgICAgIGNmZ0RhdCAtIEdUX0NPTkZJR19EVFRBCioKKiBSRVRVUk5TOgoqICAgICAgIEdUX09LICAgICAgLSBvbiBzdWNjZXNzCiogICAgICAgR1RfRkFJTCAgICAtIG9uIGVycm9yCioJCUdUX05PVF9TVVBQT1JURUQgLSBpZiBjdXJyZW50IGRldmljZSBkb2VzIG5vdCBzdXBwb3J0IHRoaXMgZmVhdHVyZS4KKgoqIENPTU1FTlRTOgoqICAgICAgIE5vbmUKKgoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwpHVF9TVEFUVVMgZ3N5c0dldENvbmZpZ0RhdGEKKAogICAgSU4gIEdUX1FEX0RFViAJCQkqZGV2LAogICAgT1VUICBHVF9DT05GSUdfREFUQQkJKmNmZ0RhdGEKKQp7CiAgICBHVF9TVEFUVVMJcmV0VmFsOyAgICAgICAgIC8qIEZ1bmN0aW9ucyByZXR1cm4gdmFsdWUuICAgICAgKi8KCUdUX1U4CQl0bXBEYXRhOwoKICAgIERCR19JTkZPKCgiZ3N5c0dldENvbmZpZ0RhdGEgQ2FsbGVkLlxuIikpOwoKCS8qIENoZWNrIGlmIFN3aXRjaCBzdXBwb3J0cyB0aGlzIGZlYXR1cmUuICovCglpZiAoIUlTX0lOX0RFVl9HUk9VUChkZXYsREVWX1NDUkFUQ0hfTUlTQ19DVFJMKSkKICAgIHsKICAgICAgICBEQkdfSU5GTygoIkdUX05PVF9TVVBQT1JURURcbiIpKTsKCQlyZXR1cm4gR1RfTk9UX1NVUFBPUlRFRDsKICAgIH0KCglyZXRWYWwgPSBnc3lzR2V0U2NyYXRjaE1pc2NDdHJsKGRldiwgR1RfU0NSQVRfTUlTQ19SRUdfQ0ZHX0RBVDAsICZ0bXBEYXRhKTsKICAgIGlmKHJldFZhbCAhPSBHVF9PSykKICAgCXsKICAgCSAgICBEQkdfSU5GTygoIkZhaWxlZC5cbiIpKTsKICAgCSAgICByZXR1cm4gcmV0VmFsOwogICAgfQoKCWNmZ0RhdGEtPmNmZ0RhdGEwLkJ5dGUgPSB0bXBEYXRhOwoKCXJldFZhbCA9IGdzeXNHZXRTY3JhdGNoTWlzY0N0cmwoZGV2LCBHVF9TQ1JBVF9NSVNDX1JFR19DRkdfREFUMSwgJnRtcERhdGEpOwogICAgaWYocmV0VmFsICE9IEdUX09LKQogICAJewogICAJICAgIERCR19JTkZPKCgiRmFpbGVkLlxuIikpOwogICAJICAgIHJldHVybiByZXRWYWw7CiAgICB9CgoJY2ZnRGF0YS0+Y2ZnRGF0YTEuQnl0ZSA9IHRtcERhdGE7CgoJcmV0VmFsID0gZ3N5c0dldFNjcmF0Y2hNaXNjQ3RybChkZXYsIEdUX1NDUkFUX01JU0NfUkVHX0NGR19EQVQyLCAmdG1wRGF0YSk7CiAgICBpZihyZXRWYWwgIT0gR1RfT0spCiAgIAl7CiAgIAkgICAgREJHX0lORk8oKCJGYWlsZWQuXG4iKSk7CiAgIAkgICAgcmV0dXJuIHJldFZhbDsKICAgIH0KCgljZmdEYXRhLT5jZmdEYXRhMi5CeXRlID0gdG1wRGF0YTsKCglyZXRWYWwgPSBnc3lzR2V0U2NyYXRjaE1pc2NDdHJsKGRldiwgR1RfU0NSQVRfTUlTQ19SRUdfQ0ZHX0RBVDMsICZ0bXBEYXRhKTsKICAgIGlmKHJldFZhbCAhPSBHVF9PSykKICAgCXsKICAgCSAgICBEQkdfSU5GTygoIkZhaWxlZC5cbiIpKTsKICAgCSAgICByZXR1cm4gcmV0VmFsOwogICAgfQoKCWNmZ0RhdGEtPmNmZ0RhdGEzLkJ5dGUgPSB0bXBEYXRhOwoKCXJldHVybiBHVF9PSzsKCn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgoqIGdzeXNTZXRTeW5jRVRhaQoqCiogREVTQ1JJUFRJT046CiogICAgICAgU2V0IHRoZSBTY3JhdGNoIGFuZCBNaXNjLiBDb250cm9sIHJlZ2lzdGVyIDxTeW5jRSBhbmQgVEFJIHBhZD4uCioKKiBJTlBVVFM6CiogICAgICAgenByIC0gWlBSIGZvciBTeW5jRSBhbmQgVEFJCiogICAgICAgem5yIC0gWk5SIGZvciBTeW5jRSBhbmQgVEFJCioKKiBPVVRQVVRTOgoqICAgICAgIE5vbmUuCioKKiBSRVRVUk5TOgoqICAgICAgIEdUX09LICAgICAgLSBvbiBzdWNjZXNzCiogICAgICAgR1RfRkFJTCAgICAtIG9uIGVycm9yCiogICAgICAgR1RfQkFEX1BBUkFNIC0gaWYgaW5wdXQgcGFyYW1ldGVycyBhcmUgYmV5b25kIHJhbmdlLgoqCQlHVF9OT1RfU1VQUE9SVEVEIC0gaWYgY3VycmVudCBkZXZpY2UgZG9lcyBub3Qgc3VwcG9ydCB0aGlzIGZlYXR1cmUuCioKKiBDT01NRU5UUzoKKiAgICAgICBOb25lCioKKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KR1RfU1RBVFVTIGdzeXNTZXRTeW5jRVRhaQooCiAgICBJTiAgR1RfUURfREVWIAkJKmRldiwKICAgIElOICBHVF9VOAkJCXpwciwKICAgIElOICBHVF9VOAkJCXpucgopCnsKICAgIEdUX1NUQVRVUwlyZXRWYWw7ICAgICAgICAgLyogRnVuY3Rpb25zIHJldHVybiB2YWx1ZS4gICAgICAqLwoJR1RfVTgJCWRhdGE7CgogICAgREJHX0lORk8oKCJnc3lzU2V0U3luY0VUYWkgQ2FsbGVkLlxuIikpOwoKCS8qIENoZWNrIGlmIFN3aXRjaCBzdXBwb3J0cyB0aGlzIGZlYXR1cmUuICovCglpZiAoIUlTX0lOX0RFVl9HUk9VUChkZXYsREVWX1NDUkFUQ0hfTUlTQ19DVFJMKSkKICAgIHsKICAgICAgICBEQkdfSU5GTygoIkdUX05PVF9TVVBQT1JURURcbiIpKTsKCQlyZXR1cm4gR1RfTk9UX1NVUFBPUlRFRDsKICAgIH0KCglpZiAoKHpwcj4weDcpIHx8ICh6bnI+MHg3KSkKCXsKICAgICAgICBEQkdfSU5GTygoIkdUX0JBRF9QQVJBTVxuIikpOwoJCXJldHVybiBHVF9CQURfUEFSQU07Cgl9CgoJZGF0YSA9ICgoenByJjB4Nyk8PDMpIHwgKHpuciYweDcpOwoKCXJldFZhbCA9IGdzeXNTZXRTY3JhdGNoTWlzY0N0cmwoZGV2LCBHVF9TQ1JBVF9NSVNDX1JFR19TWU5DRSwgZGF0YSk7CiAgICBpZihyZXRWYWwgIT0gR1RfT0spCiAgIAl7CiAgIAkgICAgREJHX0lORk8oKCJGYWlsZWQuXG4iKSk7CiAgIAkgICAgcmV0dXJuIHJldFZhbDsKICAgIH0KCglyZXR1cm4gR1RfT0s7Cgp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgoqIGdzeXNHZXRTeW5jRVRhaQoqCiogREVTQ1JJUFRJT046CiogICAgICAgR2V0IHRoZSBTY3JhdGNoIGFuZCBNaXNjLiBDb250cm9sIHJlZ2lzdGVyIDxTeW5jRSBhbmQgVEFJIHBhZD4uCioKKiBJTlBVVFM6CiogICAgICAgTm9uZS4KKgoqIE9VVFBVVFM6CiogICAgICAgenByIC0gWlBSIGZvciBTeW5jRSBhbmQgVEFJCiogICAgICAgem5yIC0gWk5SIGZvciBTeW5jRSBhbmQgVEFJKgoqCiogUkVUVVJOUzoKKiAgICAgICBHVF9PSyAgICAgIC0gb24gc3VjY2VzcwoqICAgICAgIEdUX0ZBSUwgICAgLSBvbiBlcnJvcgoqCQlHVF9OT1RfU1VQUE9SVEVEIC0gaWYgY3VycmVudCBkZXZpY2UgZG9lcyBub3Qgc3VwcG9ydCB0aGlzIGZlYXR1cmUuCioKKiBDT01NRU5UUzoKKiAgICAgICBOb25lCioKKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KR1RfU1RBVFVTIGdzeXNHZXRTeW5jRVRhaQooCiAgICBJTiAgR1RfUURfREVWIAkJKmRldiwKICAgIE9VVCAgR1RfVTgJCQkqenByLAogICAgT1VUICBHVF9VOAkJCSp6bnIKKQp7CiAgICBHVF9TVEFUVVMJcmV0VmFsOyAgICAgICAgIC8qIEZ1bmN0aW9ucyByZXR1cm4gdmFsdWUuICAgICAgKi8KCUdUX1U4CQlkYXRhOwoKICAgIERCR19JTkZPKCgiZ3N5c0dldFN5bmNFVGFpIENhbGxlZC5cbiIpKTsKCgkvKiBDaGVjayBpZiBTd2l0Y2ggc3VwcG9ydHMgdGhpcyBmZWF0dXJlLiAqLwoJaWYgKCFJU19JTl9ERVZfR1JPVVAoZGV2LERFVl9TQ1JBVENIX01JU0NfQ1RSTCkpCiAgICB7CiAgICAgICAgREJHX0lORk8oKCJHVF9OT1RfU1VQUE9SVEVEXG4iKSk7CgkJcmV0dXJuIEdUX05PVF9TVVBQT1JURUQ7CiAgICB9CgoJcmV0VmFsID0gZ3N5c0dldFNjcmF0Y2hNaXNjQ3RybChkZXYsIEdUX1NDUkFUX01JU0NfUkVHX1NZTkNFLCAmZGF0YSk7CiAgICBpZihyZXRWYWwgIT0gR1RfT0spCiAgIAl7CiAgIAkgICAgREJHX0lORk8oKCJGYWlsZWQuXG4iKSk7CiAgIAkgICAgcmV0dXJuIHJldFZhbDsKICAgIH0KCQoJKnpwciA9IDB4NyAmKGRhdGE+PjMpOwoJKnpuciA9IDB4NyAmKGRhdGEpOwoKCXJldHVybiBHVF9PSzsKCn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgoqIGdzeXNTZXRQNl9DbG9jawoqCiogREVTQ1JJUFRJT046CiogICAgICAgU2V0IHRoZSBTY3JhdGNoIGFuZCBNaXNjLiBDb250cm9sIHJlZ2lzdGVyIDxQNl9DbG9jayBwYWQ+LgoqCiogSU5QVVRTOgoqICAgICAgIHpwciAtIFpQUiBmb3IgUDZfQ2xvY2sKKiAgICAgICB6bnIgLSBaTlIgZm9yIFA2X0Nsb2NrCioKKiBPVVRQVVRTOgoqICAgICAgIE5vbmUuCioKKiBSRVRVUk5TOgoqICAgICAgIEdUX09LICAgICAgLSBvbiBzdWNjZXNzCiogICAgICAgR1RfRkFJTCAgICAtIG9uIGVycm9yCiogICAgICAgR1RfQkFEX1BBUkFNIC0gaWYgaW5wdXQgcGFyYW1ldGVycyBhcmUgYmV5b25kIHJhbmdlLgoqCQlHVF9OT1RfU1VQUE9SVEVEIC0gaWYgY3VycmVudCBkZXZpY2UgZG9lcyBub3Qgc3VwcG9ydCB0aGlzIGZlYXR1cmUuCioKKiBDT01NRU5UUzoKKiAgICAgICBOb25lCioKKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KR1RfU1RBVFVTIGdzeXNTZXRQNl9DbG9jawooCiAgICBJTiAgR1RfUURfREVWIAkJKmRldiwKICAgIElOICBHVF9VOAkJCXpwciwKICAgIElOICBHVF9VOAkJCXpucgopCnsKICAgIEdUX1NUQVRVUwlyZXRWYWw7ICAgICAgICAgLyogRnVuY3Rpb25zIHJldHVybiB2YWx1ZS4gICAgICAqLwoJR1RfVTgJCWRhdGE7CgogICAgREJHX0lORk8oKCJnc3lzU2V0UDZfQ2xvY2sgQ2FsbGVkLlxuIikpOwoKCS8qIENoZWNrIGlmIFN3aXRjaCBzdXBwb3J0cyB0aGlzIGZlYXR1cmUuICovCglpZiAoIUlTX0lOX0RFVl9HUk9VUChkZXYsREVWX1NDUkFUQ0hfTUlTQ19DVFJMKSkKICAgIHsKICAgICAgICBEQkdfSU5GTygoIkdUX05PVF9TVVBQT1JURURcbiIpKTsKCQlyZXR1cm4gR1RfTk9UX1NVUFBPUlRFRDsKICAgIH0KCglpZiAoKHpwcj4weDcpIHx8ICh6bnI+MHg3KSkKCXsKICAgICAgICBEQkdfSU5GTygoIkdUX0JBRF9QQVJBTVxuIikpOwoJCXJldHVybiBHVF9CQURfUEFSQU07Cgl9CgoJZGF0YSA9ICgoenByJjB4Nyk8PDMpIHwgKHpuciYweDcpOwoKCXJldFZhbCA9IGdzeXNTZXRTY3JhdGNoTWlzY0N0cmwoZGV2LCBHVF9TQ1JBVF9NSVNDX1JFR19QNl9DTEssIGRhdGEpOwogICAgaWYocmV0VmFsICE9IEdUX09LKQogICAJewogICAJICAgIERCR19JTkZPKCgiRmFpbGVkLlxuIikpOwogICAJICAgIHJldHVybiByZXRWYWw7CiAgICB9CgoJcmV0dXJuIEdUX09LOwoKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKKiBnc3lzR2V0UDZfQ2xvY2sKKgoqICAgICAgIEdldCB0aGUgU2NyYXRjaCBhbmQgTWlzYy4gQ29udHJvbCByZWdpc3RlciA8UDZfQ2xvY2sgcGFkPi4KKgoqIElOUFVUUzoKKiAgICAgICBOb25lLgoqCiogT1VUUFVUUzoKKiAgICAgICB6cHIgLSBaUFIgZm9yIFA2X0Nsb2NrCiogICAgICAgem5yIC0gWk5SIGZvciBQNl9DbG9jayoKKgoqIFJFVFVSTlM6CiogICAgICAgR1RfT0sgICAgICAtIG9uIHN1Y2Nlc3MKKiAgICAgICBHVF9GQUlMICAgIC0gb24gZXJyb3IKKgkJR1RfTk9UX1NVUFBPUlRFRCAtIGlmIGN1cnJlbnQgZGV2aWNlIGRvZXMgbm90IHN1cHBvcnQgdGhpcyBmZWF0dXJlLgoqCiogQ09NTUVOVFM6CiogICAgICAgTm9uZQoqCioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCkdUX1NUQVRVUyBnc3lzR2V0UDZfQ2xvY2sKKAogICAgSU4gIEdUX1FEX0RFViAJCSpkZXYsCiAgICBPVVQgIEdUX1U4CQkJKnpwciwKICAgIE9VVCAgR1RfVTgJCQkqem5yCikKewogICAgR1RfU1RBVFVTCXJldFZhbDsgICAgICAgICAvKiBGdW5jdGlvbnMgcmV0dXJuIHZhbHVlLiAgICAgICovCglHVF9VOAkJZGF0YTsKCiAgICBEQkdfSU5GTygoImdzeXNHZXRQNl9DbG9jayBDYWxsZWQuXG4iKSk7CgoJLyogQ2hlY2sgaWYgU3dpdGNoIHN1cHBvcnRzIHRoaXMgZmVhdHVyZS4gKi8KCWlmICghSVNfSU5fREVWX0dST1VQKGRldixERVZfU0NSQVRDSF9NSVNDX0NUUkwpKQogICAgewogICAgICAgIERCR19JTkZPKCgiR1RfTk9UX1NVUFBPUlRFRFxuIikpOwoJCXJldHVybiBHVF9OT1RfU1VQUE9SVEVEOwogICAgfQoKCXJldFZhbCA9IGdzeXNHZXRTY3JhdGNoTWlzY0N0cmwoZGV2LCBHVF9TQ1JBVF9NSVNDX1JFR19QNl9DTEssICZkYXRhKTsKICAgIGlmKHJldFZhbCAhPSBHVF9PSykKICAgCXsKICAgCSAgICBEQkdfSU5GTygoIkZhaWxlZC5cbiIpKTsKICAgCSAgICByZXR1cm4gcmV0VmFsOwogICAgfQoJCgkqenByID0gMHg3ICYoZGF0YT4+Myk7Cgkqem5yID0gMHg3ICYoZGF0YSk7CgoJcmV0dXJuIEdUX09LOwoKfQoKCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgoqIGdzeXNTZXRQNV9DbG9jawoqCiogREVTQ1JJUFRJT046CiogICAgICAgU2V0IHRoZSBTY3JhdGNoIGFuZCBNaXNjLiBDb250cm9sIHJlZ2lzdGVyIDxQNV9DbG9jayBwYWQ+LgoqCiogSU5QVVRTOgoqICAgICAgIHpwciAtIFpQUiBmb3IgUDVfQ2xvY2sKKiAgICAgICB6bnIgLSBaTlIgZm9yIFA1X0Nsb2NrCioKKiBPVVRQVVRTOgoqICAgICAgIE5vbmUuCioKKiBSRVRVUk5TOgoqICAgICAgIEdUX09LICAgICAgLSBvbiBzdWNjZXNzCiogICAgICAgR1RfRkFJTCAgICAtIG9uIGVycm9yCiogICAgICAgR1RfQkFEX1BBUkFNIC0gaWYgaW5wdXQgcGFyYW1ldGVycyBhcmUgYmV5b25kIHJhbmdlLgoqCQlHVF9OT1RfU1VQUE9SVEVEIC0gaWYgY3VycmVudCBkZXZpY2UgZG9lcyBub3Qgc3VwcG9ydCB0aGlzIGZlYXR1cmUuCioKKiBDT01NRU5UUzoKKiAgICAgICBOb25lCioKKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KR1RfU1RBVFVTIGdzeXNTZXRQNV9DbG9jawooCiAgICBJTiAgR1RfUURfREVWIAkJKmRldiwKICAgIElOICBHVF9VOAkJCXpwciwKICAgIElOICBHVF9VOAkJCXpucgopCnsKICAgIEdUX1NUQVRVUwlyZXRWYWw7ICAgICAgICAgLyogRnVuY3Rpb25zIHJldHVybiB2YWx1ZS4gICAgICAqLwoJR1RfVTgJCWRhdGE7CgogICAgREJHX0lORk8oKCJnc3lzU2V0UDVfQ2xvY2sgQ2FsbGVkLlxuIikpOwoKCS8qIENoZWNrIGlmIFN3aXRjaCBzdXBwb3J0cyB0aGlzIGZlYXR1cmUuICovCglpZiAoIUlTX0lOX0RFVl9HUk9VUChkZXYsREVWX1NDUkFUQ0hfTUlTQ19DVFJMKSkKICAgIHsKICAgICAgICBEQkdfSU5GTygoIkdUX05PVF9TVVBQT1JURURcbiIpKTsKCQlyZXR1cm4gR1RfTk9UX1NVUFBPUlRFRDsKICAgIH0KCglpZiAoKHpwcj4weDcpIHx8ICh6bnI+MHg3KSkKCXsKICAgICAgICBEQkdfSU5GTygoIkdUX0JBRF9QQVJBTVxuIikpOwoJCXJldHVybiBHVF9CQURfUEFSQU07Cgl9CgoJZGF0YSA9ICgoenByJjB4Nyk8PDMpIHwgKHpuciYweDcpOwoKCXJldFZhbCA9IGdzeXNTZXRTY3JhdGNoTWlzY0N0cmwoZGV2LCBHVF9TQ1JBVF9NSVNDX1JFR19QNV9DTEssIGRhdGEpOwogICAgaWYocmV0VmFsICE9IEdUX09LKQogICAJewogICAJICAgIERCR19JTkZPKCgiRmFpbGVkLlxuIikpOwogICAJICAgIHJldHVybiByZXRWYWw7CiAgICB9CgoJcmV0dXJuIEdUX09LOwoKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKKiBnc3lzR2V0UDVfQ2xvY2sKKgoqIERFU0NSSVBUSU9OOgoqICAgICAgIEdldCB0aGUgU2NyYXRjaCBhbmQgTWlzYy4gQ29udHJvbCByZWdpc3RlciA8UDVfQ2xvY2sgcGFkPi4KKgoqIElOUFVUUzoKKiAgICAgICBOb25lLgoqCiogT1VUUFVUUzoKKiAgICAgICB6cHIgLSBaUFIgZm9yIFA1X0Nsb2NrCiogICAgICAgem5yIC0gWk5SIGZvciBQNV9DbG9jawoqCiogUkVUVVJOUzoKKiAgICAgICBHVF9PSyAgICAgIC0gb24gc3VjY2VzcwoqICAgICAgIEdUX0ZBSUwgICAgLSBvbiBlcnJvcgoqCQlHVF9OT1RfU1VQUE9SVEVEIC0gaWYgY3VycmVudCBkZXZpY2UgZG9lcyBub3Qgc3VwcG9ydCB0aGlzIGZlYXR1cmUuCioKKiBDT01NRU5UUzoKKiAgICAgICBOb25lCioKKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KR1RfU1RBVFVTIGdzeXNHZXRQNV9DbG9jawooCiAgICBJTiAgR1RfUURfREVWIAkJKmRldiwKICAgIE9VVCAgR1RfVTgJCQkqenByLAogICAgT1VUICBHVF9VOAkJCSp6bnIKKQp7CiAgICBHVF9TVEFUVVMJcmV0VmFsOyAgICAgICAgIC8qIEZ1bmN0aW9ucyByZXR1cm4gdmFsdWUuICAgICAgKi8KCUdUX1U4CQlkYXRhOwoKICAgIERCR19JTkZPKCgiZ3N5c0dldFA2X0Nsb2NrIENhbGxlZC5cbiIpKTsKCgkvKiBDaGVjayBpZiBTd2l0Y2ggc3VwcG9ydHMgdGhpcyBmZWF0dXJlLiAqLwoJaWYgKCFJU19JTl9ERVZfR1JPVVAoZGV2LERFVl9TQ1JBVENIX01JU0NfQ1RSTCkpCiAgICB7CiAgICAgICAgREJHX0lORk8oKCJHVF9OT1RfU1VQUE9SVEVEXG4iKSk7CgkJcmV0dXJuIEdUX05PVF9TVVBQT1JURUQ7CiAgICB9CgoJcmV0VmFsID0gZ3N5c0dldFNjcmF0Y2hNaXNjQ3RybChkZXYsIEdUX1NDUkFUX01JU0NfUkVHX1A1X0NMSywgJmRhdGEpOwogICAgaWYocmV0VmFsICE9IEdUX09LKQogICAJewogICAJICAgIERCR19JTkZPKCgiRmFpbGVkLlxuIikpOwogICAJICAgIHJldHVybiByZXRWYWw7CiAgICB9CgkKCSp6cHIgPSAweDcgJihkYXRhPj4zKTsKCSp6bnIgPSAweDcgJihkYXRhKTsKCglyZXR1cm4gR1RfT0s7Cgp9CgoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiogZ3N5c1NldEVFUFJPTQoqCiogREVTQ1JJUFRJT046CiogICAgICAgU2V0IHRoZSBTY3JhdGNoIGFuZCBNaXNjLiBDb250cm9sIHJlZ2lzdGVyIDxFRVBST00gcGFkPi4KKgoqIElOUFVUUzoKKiAgICAgICBkc20gLSBEU00gZm9yIEVFUFJPTQoqICAgICAgIHpwciAtIFpQUiBmb3IgRUVQUk9NCiogICAgICAgem5yIC0gWk5SIGZvciBFRVBST00KKgoqIE9VVFBVVFM6CiogICAgICAgTm9uZS4KKgoqIFJFVFVSTlM6CiogICAgICAgR1RfT0sgICAgICAtIG9uIHN1Y2Nlc3MKKiAgICAgICBHVF9GQUlMICAgIC0gb24gZXJyb3IKKiAgICAgICBHVF9CQURfUEFSQU0gLSBpZiBpbnB1dCBwYXJhbWV0ZXJzIGFyZSBiZXlvbmQgcmFuZ2UuCioJCUdUX05PVF9TVVBQT1JURUQgLSBpZiBjdXJyZW50IGRldmljZSBkb2VzIG5vdCBzdXBwb3J0IHRoaXMgZmVhdHVyZS4KKgoqIENPTU1FTlRTOgoqICAgICAgIE5vbmUKKgoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwpHVF9TVEFUVVMgZ3N5c1NldEVFUFJPTQooCiAgICBJTiAgR1RfUURfREVWIAkJKmRldiwKICAgIElOICBHVF9VOAkJCWRzbSwKICAgIElOICBHVF9VOAkJCXpwciwKICAgIElOICBHVF9VOAkJCXpucgopCnsKICAgIEdUX1NUQVRVUwlyZXRWYWw7ICAgICAgICAgLyogRnVuY3Rpb25zIHJldHVybiB2YWx1ZS4gICAgICAqLwoJR1RfVTgJCWRhdGE7CgogICAgREJHX0lORk8oKCJnc3lzU2V0RUVQUk9NIENhbGxlZC5cbiIpKTsKCgkvKiBDaGVjayBpZiBTd2l0Y2ggc3VwcG9ydHMgdGhpcyBmZWF0dXJlLiAqLwoJaWYgKCFJU19JTl9ERVZfR1JPVVAoZGV2LERFVl9TQ1JBVENIX01JU0NfQ1RSTCkpCiAgICB7CiAgICAgICAgREJHX0lORk8oKCJHVF9OT1RfU1VQUE9SVEVEXG4iKSk7CgkJcmV0dXJuIEdUX05PVF9TVVBQT1JURUQ7CiAgICB9CgoJaWYgKCh6cHI+MHg3KSB8fCAoem5yPjB4NykpCgl7CiAgICAgICAgREJHX0lORk8oKCJHVF9CQURfUEFSQU1cbiIpKTsKCQlyZXR1cm4gR1RfQkFEX1BBUkFNOwoJfQoKCWRhdGEgPSAoKGRzbSYweDMpPDw2KSB8ICgoenByJjB4Nyk8PDMpIHwgKHpuciYweDcpOwoKCXJldFZhbCA9IGdzeXNTZXRTY3JhdGNoTWlzY0N0cmwoZGV2LCBHVF9TQ1JBVF9NSVNDX1JFR19FRVBST00sIGRhdGEpOwogICAgaWYocmV0VmFsICE9IEdUX09LKQogICAJewogICAJICAgIERCR19JTkZPKCgiRmFpbGVkLlxuIikpOwogICAJICAgIHJldHVybiByZXRWYWw7CiAgICB9CgoJcmV0dXJuIEdUX09LOwoKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKKiBnc3lzR2V0RUVQUk9NCioKKiBERVNDUklQVElPTjoKKiAgICAgICBHZXQgdGhlIFNjcmF0Y2ggYW5kIE1pc2MuIENvbnRyb2wgcmVnaXN0ZXIgPEVFUFJPTSBwYWQ+LgoqCiogSU5QVVRTOgoqICAgICAgIE5vbmUuCioKKiBPVVRQVVRTOgoqICAgICAgIGRzbSAtIERTTSBmb3IgRUVQUk9NCiogICAgICAgenByIC0gWlBSIGZvciBFRVBST00KKiAgICAgICB6bnIgLSBaTlIgZm9yIEVFUFJPTQoqCiogUkVUVVJOUzoKKiAgICAgICBHVF9PSyAgICAgIC0gb24gc3VjY2VzcwoqICAgICAgIEdUX0ZBSUwgICAgLSBvbiBlcnJvcgoqCQlHVF9OT1RfU1VQUE9SVEVEIC0gaWYgY3VycmVudCBkZXZpY2UgZG9lcyBub3Qgc3VwcG9ydCB0aGlzIGZlYXR1cmUuCioKKiBDT01NRU5UUzoKKiAgICAgICBOb25lCioKKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KR1RfU1RBVFVTIGdzeXNHZXRFRVBST00KKAogICAgSU4gIEdUX1FEX0RFViAJCSpkZXYsCiAgICBPVVQgIEdUX1U4CQkJKmRzbSwKICAgIE9VVCAgR1RfVTgJCQkqenByLAogICAgT1VUICBHVF9VOAkJCSp6bnIKKQp7CiAgICBHVF9TVEFUVVMJcmV0VmFsOyAgICAgICAgIC8qIEZ1bmN0aW9ucyByZXR1cm4gdmFsdWUuICAgICAgKi8KCUdUX1U4CQlkYXRhOwoKICAgIERCR19JTkZPKCgiZ3N5c0dldEVFUFJPTSBDYWxsZWQuXG4iKSk7CgoJLyogQ2hlY2sgaWYgU3dpdGNoIHN1cHBvcnRzIHRoaXMgZmVhdHVyZS4gKi8KCWlmICghSVNfSU5fREVWX0dST1VQKGRldixERVZfU0NSQVRDSF9NSVNDX0NUUkwpKQogICAgewogICAgICAgIERCR19JTkZPKCgiR1RfTk9UX1NVUFBPUlRFRFxuIikpOwoJCXJldHVybiBHVF9OT1RfU1VQUE9SVEVEOwogICAgfQoKCXJldFZhbCA9IGdzeXNHZXRTY3JhdGNoTWlzY0N0cmwoZGV2LCBHVF9TQ1JBVF9NSVNDX1JFR19FRVBST00sICZkYXRhKTsKICAgIGlmKHJldFZhbCAhPSBHVF9PSykKICAgCXsKICAgCSAgICBEQkdfSU5GTygoIkZhaWxlZC5cbiIpKTsKICAgCSAgICByZXR1cm4gcmV0VmFsOwogICAgfQoJCgkqZHNtID0gMHgzICYoZGF0YT4+Nik7CgkqenByID0gMHg3ICYoZGF0YT4+Myk7Cgkqem5yID0gMHg3ICYoZGF0YSk7CgoJcmV0dXJuIEdUX09LOwoKfQoKCgoKCgoKCgoKCgoKCgoKCg==