I2luY2x1ZGUgPENvcHlyaWdodC5oPgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKKiBndE1pc2MuYwoqCiogREVTQ1JJUFRJT046CiogICAgICAgQVBJIGRlZmluaXRpb25zIGZvciBJcCBNYXBwaW5nIFRhYmxlCiogICAgICAgICAgICAgICAgICAgICAgICAgICAgRUVQUk9NIGFjY2VzcwoqICAgICAgICAgICAgICAgICAgICAgICAgICAgIFNjcmF0Y2ggYW5kIE1pc2MgQ29udHJvbAoqIERFUEVOREVOQ0lFUzoKKgoqIEZJTEUgUkVWSVNJT04gTlVNQkVSOgoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwoKI2luY2x1ZGUgPG1zQXBpLmg+CiNpbmNsdWRlIDxndFNlbS5oPgojaW5jbHVkZSA8Z3RId0NudGwuaD4KI2luY2x1ZGUgPGd0RHJ2U3dSZWdzLmg+CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKKiBnc3lzU2V0VXNlSXBNYXBwaW5nVGFibGUKKgoqIERFU0NSSVBUSU9OOgoqICAgICAgICBUaGlzIEFQSSBzZXQgdG8gdXNlIElQIEZyYW1lIFByaW9yaXRpZXMgZnJvbSB0aGlzIHRhYmxlLgoqICAgICAgICBTZXQgR1RfVFJVRTogIFRoZSBJUF9GUFJJIGRhdGEgaW4gdGhpcyB0YWJsZSBpcyB1c2VkIGFzIHRoZSBmcmFtZZJzCiogICAgICAgICAgICBpbml0aWFsIElQX0ZQUkkuCiogICAgICAgIFNldCBHVF9GQUxTRTogVGhlIElQX0ZQUkkgZGF0YSBpbiB0aGlzIHRhYmxlIGlzIGlnbm9yZWQuIEluc3RlYWQgdGhlCiogICAgICAgICAgICBmcmFtZZJzIGluaXRpYWwgSVBfRlBSSSBpcyBnZW5lcmF0ZWQgYnkgdXNpbmcgdGhlIGZyYW1lknMgSVBfUVBSSQoqICAgICAgICAgICAgYXMgdGhlIElQX0ZQUkmScyB1cHBlciB0d28gYml0cywgYW5kIHRoZSBJUF9GUFJJknMgbG93ZXN0IGJpdCBjb21lcwoqICAgICAgICAgICAgZnJvbSBiaXQgMCBvZiB0aGUgZnJhbWWScyBzb3VyY2UgcG9ydJJzIERlZmF1bHQgUFJJIChQb3J0IG9mZnNldCAweDA3KS4KKgoqIElOUFVUUzoKKiAgICAgICAgZW4gICAgLSBbR1RfVFJVRV0gLyBbR1RfRkFMU0VdCioKKiBPVVRQVVRTOgoqICAgICAgICBOb25lLgoqCiogUkVUVVJOUzoKKiAgICAgICAgR1RfT0sgICAgICAtIG9uIHN1Y2Nlc3MKKiAgICAgICAgR1RfRkFJTCAgICAtIG9uIGVycm9yCiogICAgICAgIEdUX0JBRF9QQVJBTSAtIGlmIGlucHV0IHBhcmFtZXRlcnMgYXJlIGJleW9uZCByYW5nZS4KKiAgICAgICAgR1RfTk9UX1NVUFBPUlRFRCAtIGlmIGN1cnJlbnQgZGV2aWNlIGRvZXMgbm90IHN1cHBvcnQgdGhpcyBmZWF0dXJlLgoqCiogQ09NTUVOVFM6CiogICAgICAgIE5vbmUKKgoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwpHVF9TVEFUVVMgZ3N5c1NldFVzZUlwTWFwcGluZ1RhYmxlCigKICAgIElOICBHVF9RRF9ERVYgICAgICAgICAqZGV2LAogICAgSU4gIEdUX0JPT0wgICAgICAgICAgICBlbgopCnsKICAgIEdUX1NUQVRVUyAgICByZXRWYWw7ICAgICAgICAgLyogRnVuY3Rpb25zIHJldHVybiB2YWx1ZS4gICAgICAqLwogICAgR1RfVTE2ICAgICAgICBkYXRhOwoKICAgIERCR19JTkZPKCgiZ3N5c1NldFVzZUlwTWFwcGluZ1RhYmxlIENhbGxlZC5cbiIpKTsKCiAgICAvKiBDaGVjayBpZiBTd2l0Y2ggc3VwcG9ydHMgdGhpcyBmZWF0dXJlLiAqLwogICAgaWYgKCFJU19JTl9ERVZfR1JPVVAoZGV2LERFVl9JUF9NQVBQSU5HX1RBQkxFKSkKICAgIHsKICAgICAgICBEQkdfSU5GTygoIkdUX05PVF9TVVBQT1JURURcbiIpKTsKICAgICAgICByZXR1cm4gR1RfTk9UX1NVUFBPUlRFRDsKICAgIH0KCiAgICBkYXRhID0gKGVuPT1HVF9UUlVFKT8xOjA7CgogICAgcmV0VmFsID0gaHdTZXRHbG9iYWxSZWdGaWVsZChkZXYsUURfUkVHX0lQX01BUFBJTkdfVEFCTEUsMTQsMSxkYXRhKTsKICAgIGlmKHJldFZhbCAhPSBHVF9PSykKICAgICAgIHsKICAgICAgICAgICBEQkdfSU5GTygoIkZhaWxlZC5cbiIpKTsKICAgICAgICAgICByZXR1cm4gcmV0VmFsOwogICAgfQoKICAgIHJldHVybiBHVF9PSzsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiogZ3N5c0dldFVzZUlwTWFwcGluZ1RhYmxlCioKKiBERVNDUklQVElPTjoKKiAgICAgICAgVGhpcyBBUEkgZ2V0IHRvIHVzZSBJUCBGcmFtZSBQcmlvcml0aWVzIGZyb20gdGhpcyB0YWJsZS4KKiAgICAgICAgU2V0IEdUX1RSVUU6ICBUaGUgSVBfRlBSSSBkYXRhIGluIHRoaXMgdGFibGUgaXMgdXNlZCBhcyB0aGUgZnJhbWWScwoqICAgICAgICAgICAgaW5pdGlhbCBJUF9GUFJJLgoqICAgICAgICBTZXQgR1RfRkFMU0U6IFRoZSBJUF9GUFJJIGRhdGEgaW4gdGhpcyB0YWJsZSBpcyBpZ25vcmVkLiBJbnN0ZWFkIHRoZQoqICAgICAgICAgICAgZnJhbWWScyBpbml0aWFsIElQX0ZQUkkgaXMgZ2VuZXJhdGVkIGJ5IHVzaW5nIHRoZSBmcmFtZZJzIElQX1FQUkkKKiAgICAgICAgICAgIGFzIHRoZSBJUF9GUFJJknMgdXBwZXIgdHdvIGJpdHMsIGFuZCB0aGUgSVBfRlBSSZJzIGxvd2VzdCBiaXQgY29tZXMKKiAgICAgICAgICAgIGZyb20gYml0IDAgb2YgdGhlIGZyYW1lknMgc291cmNlIHBvcnSScyBEZWZhdWx0IFBSSSAoUG9ydCBvZmZzZXQgMHgwNykuCioKKiBJTlBVVFM6CiogICAgICAgIE5vbmUuCioKKiBPVVRQVVRTOgoqICAgICAgICBlbiAgICAtIFtHVF9UUlVFXSAvIFtHVF9GQUxTRV0KKgoqIFJFVFVSTlM6CiogICAgICAgIEdUX09LICAgICAgLSBvbiBzdWNjZXNzCiogICAgICAgIEdUX0ZBSUwgICAgLSBvbiBlcnJvcgoqICAgICAgICBHVF9CQURfUEFSQU0gLSBpZiBpbnB1dCBwYXJhbWV0ZXJzIGFyZSBiZXlvbmQgcmFuZ2UuCiogICAgICAgIEdUX05PVF9TVVBQT1JURUQgLSBpZiBjdXJyZW50IGRldmljZSBkb2VzIG5vdCBzdXBwb3J0IHRoaXMgZmVhdHVyZS4KKgoqIENPTU1FTlRTOgoqICAgICAgICBOb25lCioKKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KR1RfU1RBVFVTIGdzeXNHZXRVc2VJcE1hcHBpbmdUYWJsZQooCiAgICBJTiAgR1RfUURfREVWICAgICAgICAgKmRldiwKICAgIElOICBHVF9CT09MICAgICAgICAgICAgKmVuCikKewogICAgR1RfU1RBVFVTICAgIHJldFZhbDsgICAgICAgICAvKiBGdW5jdGlvbnMgcmV0dXJuIHZhbHVlLiAgICAgICovCiAgICBHVF9VMTYgICAgICAgIGRhdGE7CgogICAgREJHX0lORk8oKCJnc3lzR2V0VXNlSXBNYXBwaW5nVGFibGUgQ2FsbGVkLlxuIikpOwoKICAgIC8qIENoZWNrIGlmIFN3aXRjaCBzdXBwb3J0cyB0aGlzIGZlYXR1cmUuICovCiAgICBpZiAoIUlTX0lOX0RFVl9HUk9VUChkZXYsREVWX0lQX01BUFBJTkdfVEFCTEUpKQogICAgewogICAgICAgIERCR19JTkZPKCgiR1RfTk9UX1NVUFBPUlRFRFxuIikpOwogICAgICAgIHJldHVybiBHVF9OT1RfU1VQUE9SVEVEOwogICAgfQoKCiAgICByZXRWYWwgPSBod0dldEdsb2JhbFJlZ0ZpZWxkKGRldixRRF9SRUdfSVBfTUFQUElOR19UQUJMRSwxNCwxLCZkYXRhKTsKICAgIGlmKHJldFZhbCAhPSBHVF9PSykKICAgICAgIHsKICAgICAgICAgICBEQkdfSU5GTygoIkZhaWxlZC5cbiIpKTsKICAgICAgICAgICByZXR1cm4gcmV0VmFsOwogICAgfQoKICAgICplbj0gKGRhdGE9PTEpP0dUX1RSVUU6R1RfRkFMU0U7CgogICAgcmV0dXJuIEdUX09LOwp9CgoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiogZ3N5c1NldElwTWFwcGluZ1ByaW8KKgoqIERFU0NSSVBUSU9OOgoqICAgICAgICBTZXQgSVB2NCBhbmQgSVB2NiBGcmFtZSBQcmlvcml0eSBNYXBwaW5nLCBhbmQKKiAgICAgICAgSVB2NCBhbmQgSVB2NiBRdWV1ZSBQcmlvcml0eSBNYXBwaW5nLgoqICAgICAgIFRoZSBpcEZwcmkgdmFsdWUgaXMgdXNlZCBhcyB0aGUgZnJhbWUncyBpbml0aWFsIEZQUkkgd2hlbiB0aGUgZnJhbWUgaXMKKiAgICAgICAgYW4gSVB2NCBvciBhbiBJUHY2IGZyYW1lLCBhbmQgdGhlIHBvcnSScyBJbml0aWFsUHJpIChQb3J0IG9mZnNldCAweDA0KQoqICAgICAgICBpcyBjb25maWd1cmVkIHRvIHVzZSBJUCBGUHJpknMuCiogICAgICAgVGhlIGlwUXByaSB2YWx1ZSBpcyB1c2VkIGFzIHRoZSBmcmFtZZJzIGluaXRpYWwgUVBSSSB3aGVuIHRoZSBmcmFtZSBpcwoqICAgICAgICBhbiBJUHY0IG9yIGFuIElQdjYgZnJhbWUsIGFuZCB0aGUgcG9ydJJzIEluaXRpYWxQcmkgYW5kIFRhZ0lmQm90aAoqICAgICAgICByZWdpc3RlcnMgKFBvcnQgb2Zmc2V0IDB4MDQpIGFyZSBjb25maWd1cmVkIHRvIHVzZSBJUCBRUHJpknMuCioKKiBJTlBVVFM6CiogICAgICAgIHBvaW50IC0gUG9pbnRlciB0byB0aGUgSXAgTWFwcGluZyBUYWJsZS4KKiAgICAgICAgICAgICAgICAwIC0gMHgzZjsKKiAgICAgICAgaXBGcHJpIC0gIFRoZSB2YWx1ZSBpcyAwIC0gNwoqICAgICAgICBpcFFwcmkgLSAgVGhlIHZhbHVlIGlzIDAgLSAzLgoqCiogT1VUUFVUUzoKKiAgICAgICAgTm9uZS4KKgoqIFJFVFVSTlM6CiogICAgICAgIEdUX09LICAgICAgLSBvbiBzdWNjZXNzCiogICAgICAgIEdUX0ZBSUwgICAgLSBvbiBlcnJvcgoqICAgICAgICBHVF9CQURfUEFSQU0gLSBpZiBpbnB1dCBwYXJhbWV0ZXJzIGFyZSBiZXlvbmQgcmFuZ2UuCiogICAgICAgIEdUX05PVF9TVVBQT1JURUQgLSBpZiBjdXJyZW50IGRldmljZSBkb2VzIG5vdCBzdXBwb3J0IHRoaXMgZmVhdHVyZS4KKgoqIENPTU1FTlRTOgoqICAgICAgICBOb25lCioKKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KR1RfU1RBVFVTIGdzeXNTZXRJcE1hcHBpbmdQcmlvCigKICAgIElOICBHVF9RRF9ERVYgICAgICAgICAqZGV2LAogICAgSU4gIEdUX1UzMiAgICAgICAgICAgIHBvaW50LAogICAgSU4gIEdUX1U4ICAgICAgICAgICAgaXBGcHJpLAogICAgSU4gIEdUX1U4ICAgICAgICAgICAgaXBRcHJpCikKewogICAgR1RfU1RBVFVTICAgIHJldFZhbDsgICAgICAgICAvKiBGdW5jdGlvbnMgcmV0dXJuIHZhbHVlLiAgICAgICovCiAgICBHVF9VMTYgICAgICAgIGRhdGE7CgogICAgREJHX0lORk8oKCJnc3lzU2V0SXBNYXBwaW5nUHJpbyBDYWxsZWQuXG4iKSk7CgogICAgLyogQ2hlY2sgaWYgU3dpdGNoIHN1cHBvcnRzIHRoaXMgZmVhdHVyZS4gKi8KICAgIGlmICghSVNfSU5fREVWX0dST1VQKGRldixERVZfSVBfTUFQUElOR19UQUJMRSkpCiAgICB7CiAgICAgICAgREJHX0lORk8oKCJHVF9OT1RfU1VQUE9SVEVEXG4iKSk7CiAgICAgICAgcmV0dXJuIEdUX05PVF9TVVBQT1JURUQ7CiAgICB9CgogICAgaWYgKChwb2ludD4weDNmKXx8KGlwRnByaT43KXx8KGlwUXByaT4zKSkKICAgIHsKICAgICAgICBEQkdfSU5GTygoIkdUX0JBRF9QQVJBTVxuIikpOwogICAgICAgIHJldHVybiBHVF9CQURfUEFSQU07CiAgICB9CgogICAgZ3RTZW1UYWtlKGRldixkZXYtPnRibFJlZ3NTZW0sT1NfV0FJVF9GT1JFVkVSKTsKCiAgICAvKiBXYWl0IHVudGlsIHRoZSBTY3JhdGNoIGFuZCBNaXNjIGNvbnRyb2wgaXMgcmVhZHkuICovCiNpZmRlZiBHVF9STUdNVF9BQ0NFU1MKICAgIHsKICAgICAgSFdfREVWX1JFR19BQ0NFU1MgcmVnQWNjZXNzOwoKICAgICAgcmVnQWNjZXNzLmVudHJpZXMgPSAxOwoKICAgICAgcmVnQWNjZXNzLnJ3X3JlZ19saXN0WzBdLmNtZCA9IEhXX1JFR19XQUlUX1RJTExfMDsKICAgICAgcmVnQWNjZXNzLnJ3X3JlZ19saXN0WzBdLmFkZHIgPSBDQUxDX1NNSV9ERVZfQUREUihkZXYsIDAsIEdMT0JBTF9SRUdfQUNDRVNTKTsKICAgICAgcmVnQWNjZXNzLnJ3X3JlZ19saXN0WzBdLnJlZyA9IFFEX1JFR19JUF9NQVBQSU5HX1RBQkxFOwogICAgICByZWdBY2Nlc3MucndfcmVnX2xpc3RbMF0uZGF0YSA9IDE1OwogICAgICByZXRWYWwgPSBod0FjY2Vzc011bHRpUmVncyhkZXYsICZyZWdBY2Nlc3MpOwogICAgICBpZihyZXRWYWwgIT0gR1RfT0spCiAgICAgIHsKICAgICAgICBndFNlbUdpdmUoZGV2LGRldi0+dnR1UmVnc1NlbSk7CiAgICAgICAgcmV0dXJuIHJldFZhbDsKICAgICAgfQogICAgfQojZWxzZQogICAgICAgZGF0YSA9IDE7CiAgICB3aGlsZShkYXRhID09IDEpCiAgICAgICB7CiAgICAgICAgcmV0VmFsID0gaHdHZXRHbG9iYWxSZWdGaWVsZChkZXYsUURfUkVHX0lQX01BUFBJTkdfVEFCTEUsMTUsMSwmZGF0YSk7CiAgICAgICAgICAgaWYocmV0VmFsICE9IEdUX09LKQogICAgICAgICAgIHsKICAgICAgICAgICAgZ3RTZW1HaXZlKGRldixkZXYtPnRibFJlZ3NTZW0pOwogICAgICAgICAgICAgICByZXR1cm4gcmV0VmFsOwogICAgICAgICAgIH0KICAgIH0KI2VuZGlmCgogICAgZGF0YSA9ICgoKGlwRnByaSY3KTw8NCkgfCAoaXBRcHJpJjMpKTsKICAgIGRhdGEgfD0gICgoR1RfVTE2KSgoMSA8PCAxNSkgfCAocG9pbnQgPDwgOCkpKTsKCiAgICByZXRWYWwgPSBod1dyaXRlR2xvYmFsUmVnKGRldiwgUURfUkVHX0lQX01BUFBJTkdfVEFCTEUsIGRhdGEpOwogICAgaWYocmV0VmFsICE9IEdUX09LKQogICAgICAgewogICAgICAgICAgIERCR19JTkZPKCgiRmFpbGVkLlxuIikpOwogICAgICAgIGd0U2VtR2l2ZShkZXYsZGV2LT50YmxSZWdzU2VtKTsKICAgICAgICAgICByZXR1cm4gcmV0VmFsOwogICAgfQoKCgogICAgZ3RTZW1HaXZlKGRldixkZXYtPnRibFJlZ3NTZW0pOwoKICAgIGlmKHJldFZhbCAhPSBHVF9PSykKICAgICAgIHsKICAgICAgICAgICBEQkdfSU5GTygoIkZhaWxlZC5cbiIpKTsKICAgICAgICAgICByZXR1cm4gcmV0VmFsOwogICAgfQoKICAgIHJldHVybiBHVF9PSzsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiogZ3N5c0dldElwTWFwcGluZ1ByaW8KKgoqIERFU0NSSVBUSU9OOgoqICAgICAgICBHZXQgSVB2NCBhbmQgSVB2NiBGcmFtZSBQcmlvcml0eSBNYXBwaW5nLCBhbmQKKiAgICAgICAgSVB2NCBhbmQgSVB2NiBRdWV1ZSBQcmlvcml0eSBNYXBwaW5nLgoqICAgICAgIFRoZSBpcEZwcmkgdmFsdWUgaXMgdXNlZCBhcyB0aGUgZnJhbWUncyBpbml0aWFsIEZQUkkgd2hlbiB0aGUgZnJhbWUgaXMKKiAgICAgICAgYW4gSVB2NCBvciBhbiBJUHY2IGZyYW1lLCBhbmQgdGhlIHBvcnSScyBJbml0aWFsUHJpIChQb3J0IG9mZnNldCAweDA0KQoqICAgICAgICBpcyBjb25maWd1cmVkIHRvIHVzZSBJUCBGUHJpknMuCiogICAgICAgIFRoZSBpcFFwcmkgdmFsdWUgaXMgdXNlZCBhcyB0aGUgZnJhbWWScyBpbml0aWFsIFFQUkkgd2hlbiB0aGUgZnJhbWUgaXMKKiAgICAgICAgYW4gSVB2NCBvciBhbiBJUHY2IGZyYW1lLCBhbmQgdGhlIHBvcnSScyBJbml0aWFsUHJpIGFuZCBUYWdJZkJvdGgKKiAgICAgICAgcmVnaXN0ZXJzIChQb3J0IG9mZnNldCAweDA0KSBhcmUgY29uZmlndXJlZCB0byB1c2UgSVAgUVByaZJzLgoqCiogSU5QVVRTOgoqICAgICAgICBwb2ludCAtIFBvaW50ZXIgdG8gdGhlIElwIE1hcHBpbmcgVGFibGUuCiogICAgICAgICAgICAgICAgMCAtIDB4M2Y7CioKKiBPVVRQVVRTOgoqICAgICAgICBpcEZwcmkgLSAgVGhlIHZhbHVlIGlzIDAgLSA3CiogICAgICAgIGlwUXByaSAtICBUaGUgdmFsdWUgaXMgMCAtIDMuCioKKiBSRVRVUk5TOgoqICAgICAgICBHVF9PSyAgICAgIC0gb24gc3VjY2VzcwoqICAgICAgICBHVF9GQUlMICAgIC0gb24gZXJyb3IKKiAgICAgICAgR1RfQkFEX1BBUkFNIC0gaWYgaW5wdXQgcGFyYW1ldGVycyBhcmUgYmV5b25kIHJhbmdlLgoqICAgICAgICBHVF9OT1RfU1VQUE9SVEVEIC0gaWYgY3VycmVudCBkZXZpY2UgZG9lcyBub3Qgc3VwcG9ydCB0aGlzIGZlYXR1cmUuCioKKiBDT01NRU5UUzoKKiAgICAgICAgTm9uZS4KKgoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwpHVF9TVEFUVVMgZ3N5c0dldElwTWFwcGluZ1ByaW8KKAogICAgSU4gIEdUX1FEX0RFViAgICAgICAgICpkZXYsCiAgICBJTiAgR1RfVTMyICAgICAgICAgICAgcG9pbnQsCiAgICBPVVQgIEdUX1U4ICAgICAgICAgICAgKmlwRnByaSwKICAgIE9VVCAgR1RfVTggICAgICAgICAgICAqaXBRcHJpCikKewogICAgR1RfU1RBVFVTICAgIHJldFZhbDsgICAgICAgICAvKiBGdW5jdGlvbnMgcmV0dXJuIHZhbHVlLiAgICAgICovCiAgICBHVF9VMTYgICAgICAgIGRhdGE7CgogICAgREJHX0lORk8oKCJnc3lzR2V0SXBNYXBwaW5nUHJpbyBDYWxsZWQuXG4iKSk7CgogICAgLyogQ2hlY2sgaWYgU3dpdGNoIHN1cHBvcnRzIHRoaXMgZmVhdHVyZS4gKi8KICAgIGlmICghSVNfSU5fREVWX0dST1VQKGRldixERVZfSVBfTUFQUElOR19UQUJMRSkpCiAgICB7CiAgICAgICAgREJHX0lORk8oKCJHVF9OT1RfU1VQUE9SVEVEXG4iKSk7CiAgICAgICAgcmV0dXJuIEdUX05PVF9TVVBQT1JURUQ7CiAgICB9CgogICAgaWYgKHBvaW50ID4gMHgzZikKICAgIHsKICAgICAgICBEQkdfSU5GTygoIkdUX0JBRF9QQVJBTVxuIikpOwogICAgICAgIHJldHVybiBHVF9CQURfUEFSQU07CiAgICB9CgogICAgZ3RTZW1UYWtlKGRldixkZXYtPnRibFJlZ3NTZW0sT1NfV0FJVF9GT1JFVkVSKTsKCiNpZmRlZiBHVF9STUdNVF9BQ0NFU1MKICAgIHsKICAgICAgSFdfREVWX1JFR19BQ0NFU1MgcmVnQWNjZXNzOwoKICAgICAgcmVnQWNjZXNzLmVudHJpZXMgPSAyOwoKICAgICAgcmVnQWNjZXNzLnJ3X3JlZ19saXN0WzBdLmNtZCA9IEhXX1JFR19XQUlUX1RJTExfMDsKICAgICAgcmVnQWNjZXNzLnJ3X3JlZ19saXN0WzBdLmFkZHIgPSBDQUxDX1NNSV9ERVZfQUREUihkZXYsIDAsIEdMT0JBTF9SRUdfQUNDRVNTKTsKICAgICAgcmVnQWNjZXNzLnJ3X3JlZ19saXN0WzBdLnJlZyA9IFFEX1JFR19JUF9NQVBQSU5HX1RBQkxFOwogICAgICByZWdBY2Nlc3MucndfcmVnX2xpc3RbMF0uZGF0YSA9IDE1OwogICAgICByZWdBY2Nlc3MucndfcmVnX2xpc3RbMV0uY21kID0gSFdfUkVHX1JFQUQ7CiAgICAgIHJlZ0FjY2Vzcy5yd19yZWdfbGlzdFsxXS5hZGRyID0gQ0FMQ19TTUlfREVWX0FERFIoZGV2LCAwLCBHTE9CQUxfUkVHX0FDQ0VTUyk7CiAgICAgIHJlZ0FjY2Vzcy5yd19yZWdfbGlzdFsxXS5yZWcgPSBRRF9SRUdfSVBfTUFQUElOR19UQUJMRTsKICAgICAgcmVnQWNjZXNzLnJ3X3JlZ19saXN0WzFdLmRhdGEgPSAwOwogICAgICByZXRWYWwgPSBod0FjY2Vzc011bHRpUmVncyhkZXYsICZyZWdBY2Nlc3MpOwogICAgICBpZihyZXRWYWwgIT0gR1RfT0spCiAgICAgIHsKICAgICAgICBndFNlbUdpdmUoZGV2LGRldi0+dnR1UmVnc1NlbSk7CiAgICAgICAgcmV0dXJuIHJldFZhbDsKICAgICAgfQogICAgICBkYXRhID0gcWRMb25nMlNob3J0KHJlZ0FjY2Vzcy5yd19yZWdfbGlzdFsxXS5kYXRhKTsKICAgIH0KI2Vsc2UKICAgIGRvIHsKICAgICAgICByZXRWYWwgPSBod1JlYWRHbG9iYWxSZWcoZGV2LCBRRF9SRUdfSVBfTUFQUElOR19UQUJMRSwgJmRhdGEpOwogICAgICAgIGlmKHJldFZhbCAhPSBHVF9PSykKICAgICAgICAgICB7CiAgICAgICAgICAgICAgIERCR19JTkZPKCgiRmFpbGVkLlxuIikpOwogICAgICAgICAgICBndFNlbUdpdmUoZGV2LGRldi0+dGJsUmVnc1NlbSk7CiAgICAgICAgICAgICAgIHJldHVybiByZXRWYWw7CiAgICAgICAgfQogICAgfSB3aGlsZSAoZGF0YSYweDgwMDApOwojZW5kaWYKCgogICAgKmlwRnByaSA9IChkYXRhID4+IDQpICYgNzsKICAgICppcFFwcmkgPSAoZGF0YSkgJiAzOwoKICAgIGd0U2VtR2l2ZShkZXYsZGV2LT50YmxSZWdzU2VtKTsKCiAgICBpZihyZXRWYWwgIT0gR1RfT0spCiAgICAgICB7CiAgICAgICAgICAgREJHX0lORk8oKCJGYWlsZWQuXG4iKSk7CiAgICAgICAgICAgcmV0dXJuIHJldFZhbDsKICAgIH0KCiAgICByZXR1cm4gR1RfT0s7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgoqIGVlcHJvbU9wZXJhdGlvblBlcmZvcm0KKgoqIERFU0NSSVBUSU9OOgoqICAgICAgIFRoaXMgZnVuY3Rpb24gYWNjZXNzZXMgRUVQUk9NIENvbW1hbmQgUmVnaXN0ZXIgYW5kIERhdGEgUmVnaXN0ZXIuCiogICAgICAgVGhlIGRldmljZSBzdXBwb3J0cyB0aGUgZm9sbG93aW5nIEVFUFJPTQoqICAgICAgICAgICAgb3BlcmF0aW9ucwoqICAgICAgICAgICAgR1RfRUVQUk9NX05PX09QID0gTm8gT3BlcmF0aW9uCiogICAgICAgICAgICBHVF9FRVBST01fV1JJVEVfREFUQSA9IFdyaXRlIEVFUFJPTSBhdCBBZGRyLgoqICAgICAgICAgICAgR1RfRUVQUk9NX1JFQURfREFUQSA9IFJlYWQgRUVQUk9NIGZyb20gQWRkci4KKiAgICAgICAgICAgIEdUX0VFUFJPTV9SRVNUQVJUID0gUmVzdGFydCBSZWdpc3RlciBMb2FkZXIgZXhlY3V0aW9uIGF0IEFkZHIKKiAgICAgICAgICAgICAgICAoZWVwcm9tRGF0YSA9IGRvbpJ0IGNhcmUgaW4gdGhpcyBjYXNlKQoqICAgICAgICAgICAgR1RfRUVQUk9NX0hBTFQgPSBIYWx0IChzdG9wIGV4ZWN1dGluZyB0aGUgRUVQUk9NIGlmIGl0cyBub3QgYWxyZWFkeQoqICAgICAgICAgICAgICAgIHN0b3BwZWQpCioKKiBJTlBVVFM6CiogICAgICAgZWVwcm9tT3AgICAgICAtIEVFUFJPTSBPcGNvZGUuCiogICAgICAgZWVwcm9tRGF0YSAgICAtIERhdGEgdG8gYmUgd3JpdHRlbiB0byB0aGUgRUVQUk9NCioKKiBPVVRQVVRTOgoqICAgICAgIGVlcHJvbURhdGEgICAgLSBEYXRhIHRoYXQgd2FzIHJlYWQgYmFjayBmcm9tIHRoZSBFRVBST00uCioKQ29tbWFuZCByZWdpc3RlciBhYm92ZS4KKgoqIFJFVFVSTlM6CiogICAgICAgR1RfT0sgb24gc3VjY2VzcywKKiAgICAgICBHVF9GQUlMIG90aGVyd2lzZS4KKiAgICAgICBHVF9CQURfUEFSQU0gLSBpZiBpbnB1dCBwYXJhbWV0ZXJzIGFyZSBiZXlvbmQgcmFuZ2UuCioKKiBDT01NRU5UUzoKKgoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwpzdGF0aWMgR1RfU1RBVFVTIGVlcHJvbU9wZXJhdGlvblBlcmZvcm0KKAogICAgSU4gICAgR1RfUURfREVWICAgICAgICAgICAgICpkZXYsCiAgICBJTiAgICBHVF9FRVBST01fT1BFUkFUSU9OICAgIGVlcHJvbU9wLAogICAgSU5PVVQgR1RfRUVQUk9NX09QX0RBVEEgICAgICAgICpvcERhdGEKKQp7CiAgICBHVF9TVEFUVVMgICAgICAgcmV0VmFsOyAgICAvKiBGdW5jdGlvbnMgcmV0dXJuIHZhbHVlICovCiAgICBHVF9VMTYgICAgICAgICAgZGF0YTsgICAgIC8qIHRlbXBvcmFyeSBEYXRhIHN0b3JhZ2UgKi8KICAgIERCR19JTkZPKCgiZWVwcm9tT3BlcmF0aW9uUGVyZm9ybSBDYWxsZWQuXG4iKSk7CgogICAgLyogQ2hlY2sgaWYgU3dpdGNoIHN1cHBvcnRzIHRoaXMgZmVhdHVyZS4gKi8KICAgIGlmICghSVNfSU5fREVWX0dST1VQKGRldixERVZfRUVQUk9NKSkKICAgIHsKICAgICAgICBEQkdfSU5GTygoIkdUX05PVF9TVVBQT1JURURcbiIpKTsKICAgICAgICByZXR1cm4gR1RfTk9UX1NVUFBPUlRFRDsKICAgIH0KCiAgICBpZiAoZWVwcm9tT3A+R1RfRUVQUk9NX0hBTFQpCiAgICB7CiAgICAgICAgREJHX0lORk8oKCJHVF9CQURfUEFSQU1cbiIpKTsKICAgICAgICByZXR1cm4gR1RfQkFEX1BBUkFNOwogICAgfQoKICAgIGd0U2VtVGFrZShkZXYsZGV2LT5lZXByb21SZWdzU2VtLE9TX1dBSVRfRk9SRVZFUik7CgoKICAgIC8qIFdhaXQgdW50aWwgdGhlIGVlcHJvbSBpbiByZWFkeS4gKi8KI2lmZGVmIEdUX1JNR01UX0FDQ0VTUwogICAgewogICAgICBIV19ERVZfUkVHX0FDQ0VTUyByZWdBY2Nlc3M7CgogICAgICByZWdBY2Nlc3MuZW50cmllcyA9IDE7CgogICAgICByZWdBY2Nlc3MucndfcmVnX2xpc3RbMF0uY21kID0gSFdfUkVHX1dBSVRfVElMTF8wOwogICAgICByZWdBY2Nlc3MucndfcmVnX2xpc3RbMF0uYWRkciA9IENBTENfU01JX0RFVl9BRERSKGRldiwgMCwgR0xPQkFMMl9SRUdfQUNDRVNTKTsKICAgICAgcmVnQWNjZXNzLnJ3X3JlZ19saXN0WzBdLnJlZyA9IFFEX1JFR19FRVBST01fQ09NTUFORDsKICAgICAgcmVnQWNjZXNzLnJ3X3JlZ19saXN0WzBdLmRhdGEgPSAxNTsKICAgICAgcmV0VmFsID0gaHdBY2Nlc3NNdWx0aVJlZ3MoZGV2LCAmcmVnQWNjZXNzKTsKICAgICAgaWYocmV0VmFsICE9IEdUX09LKQogICAgICB7CiAgICAgICAgZ3RTZW1HaXZlKGRldixkZXYtPnZ0dVJlZ3NTZW0pOwogICAgICAgIHJldHVybiByZXRWYWw7CiAgICAgIH0KICAgIH0KI2Vsc2UKICAgIGRhdGEgPSAxOwogICAgd2hpbGUoZGF0YSA9PSAxKQogICAgewogICAgICAgIHJldFZhbCA9IGh3R2V0R2xvYmFsMlJlZ0ZpZWxkKGRldixRRF9SRUdfRUVQUk9NX0NPTU1BTkQsMTUsMSwmZGF0YSk7CiAgICAgICAgaWYocmV0VmFsICE9IEdUX09LKQogICAgICAgIHsKICAgICAgICAgICAgZ3RTZW1HaXZlKGRldixkZXYtPmVlcHJvbVJlZ3NTZW0pOwogICAgICAgICAgICByZXR1cm4gcmV0VmFsOwogICAgICAgIH0KICAgIH0KI2VuZGlmCgoKICAgIC8qIFNldCB0aGUgRUVQUk9NIE9wZXJhdGlvbiByZWdpc3RlciAqLwogICAgc3dpdGNoIChlZXByb21PcCkKICAgIHsKICAgICAgICBjYXNlIEdUX0VFUFJPTV9XUklURV9EQVRBOgogICAgICAgICAgICByZXRWYWwgPSBod0dldEdsb2JhbDJSZWdGaWVsZChkZXYsUURfUkVHX0VFUFJPTV9DT01NQU5ELDEwLDEsJmRhdGEpOwogICAgICAgICAgICBpZihyZXRWYWwgIT0gR1RfT0spCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGd0U2VtR2l2ZShkZXYsZGV2LT5lZXByb21SZWdzU2VtKTsKICAgICAgICAgICAgICAgIHJldHVybiByZXRWYWw7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYgKGRhdGE9PTApCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGd0U2VtR2l2ZShkZXYsZGV2LT5lZXByb21SZWdzU2VtKTsKICAgICAgICAgICAgICAgIERCR19JTkZPKCgiRUVQUk9NIGlzIG5vdCB3cml0YWJsZW4iKSk7CiAgICAgICAgICAgICAgICByZXR1cm4gR1RfRkFJTDsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgcmV0VmFsID0gaHdHZXRHbG9iYWwyUmVnRmllbGQoZGV2LFFEX1JFR19FRVBST01fQ09NTUFORCwxMSwxLCZkYXRhKTsKICAgICAgICAgICAgaWYocmV0VmFsICE9IEdUX09LKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBndFNlbUdpdmUoZGV2LGRldi0+ZWVwcm9tUmVnc1NlbSk7CiAgICAgICAgICAgICAgICByZXR1cm4gcmV0VmFsOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGlmIChkYXRhPT0xKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBndFNlbUdpdmUoZGV2LGRldi0+ZWVwcm9tUmVnc1NlbSk7CiAgICAgICAgICAgICAgICBEQkdfSU5GTygoIkVFUFJPTSBMb2FkZXIgaXMgcnVubmluZyIpKTsKICAgICAgICAgICAgICAgIHJldHVybiBHVF9GQUlMOwogICAgICAgICAgICB9CgogICAgICAgICAgICBkYXRhID0gKEdUX1UxNilvcERhdGEtPmVlcHJvbURhdGE7CiAgICAgICAgICAgIHJldFZhbCA9IGh3V3JpdGVHbG9iYWwyUmVnKGRldixRRF9SRUdfRUVQUk9NX0RBVEEsZGF0YSk7CiAgICAgICAgICAgIGlmKHJldFZhbCAhPSBHVF9PSykKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgZ3RTZW1HaXZlKGRldixkZXYtPmVlcHJvbVJlZ3NTZW0pOwogICAgICAgICAgICAgICAgcmV0dXJuIHJldFZhbDsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgZGF0YSA9IChHVF9VMTYpKCgxIDw8IDE1KSB8IChHVF9FRVBST01fV1JJVEVfREFUQSA8PCAxMikgfAogICAgICAgICAgICAgICAgICAgIChvcERhdGEtPmVlcHJvbUFkZHIgJiAweEZGKSk7CiAgICAgICAgICAgIHJldFZhbCA9IGh3V3JpdGVHbG9iYWwyUmVnKGRldixRRF9SRUdfRUVQUk9NX0NPTU1BTkQsZGF0YSk7CiAgICAgICAgICAgIGlmKHJldFZhbCAhPSBHVF9PSykKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgZ3RTZW1HaXZlKGRldixkZXYtPmVlcHJvbVJlZ3NTZW0pOwogICAgICAgICAgICAgICAgcmV0dXJuIHJldFZhbDsKICAgICAgICAgICAgfQogICAgICAgICAgICBicmVhazsKCiAgICAgICAgY2FzZSBHVF9FRVBST01fUkVBRF9EQVRBOgogICAgICAgICAgICByZXRWYWwgPSBod0dldEdsb2JhbDJSZWdGaWVsZChkZXYsUURfUkVHX0VFUFJPTV9DT01NQU5ELDExLDEsJmRhdGEpOwogICAgICAgICAgICBpZihyZXRWYWwgIT0gR1RfT0spCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGd0U2VtR2l2ZShkZXYsZGV2LT5lZXByb21SZWdzU2VtKTsKICAgICAgICAgICAgICAgIHJldHVybiByZXRWYWw7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYgKGRhdGE9PTEpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGd0U2VtR2l2ZShkZXYsZGV2LT5lZXByb21SZWdzU2VtKTsKICAgICAgICAgICAgICAgIERCR19JTkZPKCgiRUVQUk9NIExvYWRlciBpcyBydW5uaW5nIikpOwogICAgICAgICAgICAgICAgcmV0dXJuIEdUX0ZBSUw7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGRhdGEgPSAoR1RfVTE2KSgoMSA8PCAxNSkgfCAoR1RfRUVQUk9NX1JFQURfREFUQSA8PCAxMikgfAogICAgICAgICAgICAgICAgICAgIChvcERhdGEtPmVlcHJvbUFkZHIgJiAweEZGKSk7CiAgICAgICAgICAgIHJldFZhbCA9IGh3V3JpdGVHbG9iYWwyUmVnKGRldixRRF9SRUdfRUVQUk9NX0NPTU1BTkQsZGF0YSk7CiAgICAgICAgICAgIGlmKHJldFZhbCAhPSBHVF9PSykKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgZ3RTZW1HaXZlKGRldixkZXYtPmVlcHJvbVJlZ3NTZW0pOwogICAgICAgICAgICAgICAgcmV0dXJuIHJldFZhbDsKICAgICAgICAgICAgfQoKCiNpZmRlZiBHVF9STUdNVF9BQ0NFU1MKICAgICAgICAgICAgewogICAgICAgICAgICAgIEhXX0RFVl9SRUdfQUNDRVNTIHJlZ0FjY2VzczsKCiAgICAgICAgICAgICAgcmVnQWNjZXNzLmVudHJpZXMgPSAxOwoKICAgICAgICAgICAgICByZWdBY2Nlc3MucndfcmVnX2xpc3RbMF0uY21kID0gSFdfUkVHX1dBSVRfVElMTF8wOwogICAgICAgICAgICAgIHJlZ0FjY2Vzcy5yd19yZWdfbGlzdFswXS5hZGRyID0gQ0FMQ19TTUlfREVWX0FERFIoZGV2LCAwLCBHTE9CQUwyX1JFR19BQ0NFU1MpOwogICAgICAgICAgICAgIHJlZ0FjY2Vzcy5yd19yZWdfbGlzdFswXS5yZWcgPSBRRF9SRUdfRUVQUk9NX0NPTU1BTkQ7CiAgICAgICAgICAgICAgcmVnQWNjZXNzLnJ3X3JlZ19saXN0WzBdLmRhdGEgPSAxNTsKICAgICAgICAgICAgICByZXRWYWwgPSBod0FjY2Vzc011bHRpUmVncyhkZXYsICZyZWdBY2Nlc3MpOwogICAgICAgICAgICAgIGlmKHJldFZhbCAhPSBHVF9PSykKICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBndFNlbUdpdmUoZGV2LGRldi0+dnR1UmVnc1NlbSk7CiAgICAgICAgICAgICAgICByZXR1cm4gcmV0VmFsOwogICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQojZWxzZQogICAgICAgICAgICBkYXRhID0gMTsKICAgICAgICAgICAgd2hpbGUoZGF0YSA9PSAxKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICByZXRWYWwgPSBod0dldEdsb2JhbDJSZWdGaWVsZChkZXYsUURfUkVHX0VFUFJPTV9DT01NQU5ELDE1LDEsJmRhdGEpOwogICAgICAgICAgICAgICAgaWYocmV0VmFsICE9IEdUX09LKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIGd0U2VtR2l2ZShkZXYsZGV2LT5lZXByb21SZWdzU2VtKTsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gcmV0VmFsOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiNlbmRpZgoKCiAgICAgICAgICAgIHJldFZhbCA9IGh3UmVhZEdsb2JhbDJSZWcoZGV2LFFEX1JFR19FRVBST01fREFUQSwmZGF0YSk7CiAgICAgICAgICAgIG9wRGF0YS0+ZWVwcm9tRGF0YSA9IChHVF9VMzIpZGF0YTsKCiAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICBjYXNlIEdUX0VFUFJPTV9SRVNUQVJUOgogICAgICAgICAgICBkYXRhID0gKEdUX1UxNikoKDEgPDwgMTUpIHwgKEdUX0VFUFJPTV9SRVNUQVJUIDw8IDEyKSB8CiAgICAgICAgICAgICAgICAgICAgKG9wRGF0YS0+ZWVwcm9tQWRkciAmIDB4RkYpKTsKICAgICAgICAgICAgcmV0VmFsID0gaHdXcml0ZUdsb2JhbDJSZWcoZGV2LFFEX1JFR19FRVBST01fQ09NTUFORCxkYXRhKTsKICAgICAgICAgICAgaWYocmV0VmFsICE9IEdUX09LKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBndFNlbUdpdmUoZGV2LGRldi0+ZWVwcm9tUmVnc1NlbSk7CiAgICAgICAgICAgICAgICByZXR1cm4gcmV0VmFsOwogICAgICAgICAgICB9CgoKICAgICAgICAgICAgYnJlYWs7CgogICAgICAgIGNhc2UgR1RfRUVQUk9NX0hBTFQ6CiAgICAgICAgICAgIGRhdGEgPSAoR1RfVTE2KSgoMSA8PCAxNSkgfCAoR1RfRUVQUk9NX0hBTFQgPDwgMTIpIHwKICAgICAgICAgICAgICAgICAgICAob3BEYXRhLT5lZXByb21BZGRyICYgMHhGRikpOwogICAgICAgICAgICByZXRWYWwgPSBod1dyaXRlR2xvYmFsMlJlZyhkZXYsUURfUkVHX0VFUFJPTV9DT01NQU5ELGRhdGEpOwogICAgICAgICAgICBpZihyZXRWYWwgIT0gR1RfT0spCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGd0U2VtR2l2ZShkZXYsZGV2LT5lZXByb21SZWdzU2VtKTsKICAgICAgICAgICAgICAgIHJldHVybiByZXRWYWw7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgIGd0U2VtR2l2ZShkZXYsZGV2LT5lZXByb21SZWdzU2VtKTsKICAgICAgICAgICAgcmV0dXJuIEdUX0ZBSUw7CiAgICB9CgogICAgZ3RTZW1HaXZlKGRldixkZXYtPmVlcHJvbVJlZ3NTZW0pOwogICAgcmV0dXJuIEdUX09LOwp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKKiBnc3lzUmVhZEVlcHJvbQoqCiogREVTQ1JJUFRJT046CiogICAgICAgIFJlYWQgRUVQUk9NIGZyb20gRUVQUk9NknMgYWRkcmVzcyB3aGVyZSB0aGUgRUVPcCBpcyBwZXJmb3JtZWQuCioKKiBJTlBVVFM6CiogICAgICAgIGFkZHIgLSBFRVBST00gQWRkcmVzcy4KKgoqIE9VVFBVVFM6CiogICAgICAgIGRhdGEgLSAgRGF0YSB0aGF0IHdhcyByZWFkIGJhY2sgZnJvbSB0aGUgRUVQUk9NLgoqCiogUkVUVVJOUzoKKiAgICAgICAgR1RfT0sgICAgICAtIG9uIHN1Y2Nlc3MKKiAgICAgICAgR1RfRkFJTCAgICAtIG9uIGVycm9yCiogICAgICAgIEdUX0JBRF9QQVJBTSAtIGlmIGlucHV0IHBhcmFtZXRlcnMgYXJlIGJleW9uZCByYW5nZS4KKiAgICAgICAgR1RfTk9UX1NVUFBPUlRFRCAtIGlmIGN1cnJlbnQgZGV2aWNlIGRvZXMgbm90IHN1cHBvcnQgdGhpcyBmZWF0dXJlLgoqCiogQ09NTUVOVFM6CiogICAgICAgIE5vbmUKKgoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwpHVF9TVEFUVVMgZ3N5c1JlYWRFZXByb20KKAogICAgSU4gIEdUX1FEX0RFViAgICAgICAgICpkZXYsCiAgICBJTiAgR1RfVTMyICAgICAgICAgICAgYWRkciwKICAgIE9VVCAgR1RfVTggICAgICAgICAgICAqZGF0YQopCnsKICAgIEdUX1NUQVRVUyAgICByZXRWYWw7ICAgICAgICAgLyogRnVuY3Rpb25zIHJldHVybiB2YWx1ZS4gICAgICAqLwogICAgR1RfRUVQUk9NX09QRVJBVElPTiAgICBlZXByb21PcDsKICAgIEdUX0VFUFJPTV9PUF9EQVRBICAgIG9wRGF0YTsKCiAgICBlZXByb21PcCA9IEdUX0VFUFJPTV9SRUFEX0RBVEE7CiAgICBvcERhdGEuZWVwcm9tQWRkciA9IGFkZHI7CgogICAgcmV0VmFsID0gZWVwcm9tT3BlcmF0aW9uUGVyZm9ybShkZXYsZWVwcm9tT3AsJm9wRGF0YSk7CiAgICBpZihyZXRWYWwgIT0gR1RfT0spCiAgICB7CiAgICAgIHJldHVybiByZXRWYWw7CiAgICB9CiAgICAqZGF0YSA9IChHVF9VOClvcERhdGEuZWVwcm9tRGF0YTsKICAgIHJldHVybiBHVF9PSzsKCn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiogZ3N5c1dyaXRlRWVwcm9tCioKKiBERVNDUklQVElPTjoKKiAgICAgICAgV3JpdGUgRUVQUk9NIGF0IHRoZSBFRVBST02ScyBhZGRyZXNzIHdoZXJlIHRoZSBFRU9wIGlzIHBlcmZvcm1lZC4KKgoqIElOUFVUUzoKKiAgICAgICAgYWRkciAtIEVFUFJPTSBBZGRyZXNzLgoqICAgICAgICBkYXRhIC0gRGF0YSB0byBiZSB3cml0dGVuIHRvIHRoZSBFRVBST00KKgoqIE9VVFBVVFM6CiogICAgICAgIE5vbmUuCioKKiBSRVRVUk5TOgoqICAgICAgICBHVF9PSyAgICAgIC0gb24gc3VjY2VzcwoqICAgICAgICBHVF9GQUlMICAgIC0gb24gZXJyb3IKKiAgICAgICAgR1RfQkFEX1BBUkFNIC0gaWYgaW5wdXQgcGFyYW1ldGVycyBhcmUgYmV5b25kIHJhbmdlLgoqICAgICAgICBHVF9OT1RfU1VQUE9SVEVEIC0gaWYgY3VycmVudCBkZXZpY2UgZG9lcyBub3Qgc3VwcG9ydCB0aGlzIGZlYXR1cmUuCioKKiBDT01NRU5UUzoKKiAgICAgICAgTm9uZQoqCioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCkdUX1NUQVRVUyBnc3lzV3JpdGVFZXByb20KKAogICAgSU4gIEdUX1FEX0RFViAgICAgICAgICpkZXYsCiAgICBJTiAgR1RfVTMyICAgICAgICAgICAgYWRkciwKICAgIElOICBHVF9VOCAgICAgICAgICAgIGRhdGEKKQp7CiAgICBHVF9TVEFUVVMgICAgcmV0VmFsOyAgICAgICAgIC8qIEZ1bmN0aW9ucyByZXR1cm4gdmFsdWUuICAgICAgKi8KICAgIEdUX0VFUFJPTV9PUEVSQVRJT04gICAgZWVwcm9tT3A7CiAgICBHVF9FRVBST01fT1BfREFUQSAgICBvcERhdGE7CgogICAgZWVwcm9tT3AgPSBHVF9FRVBST01fV1JJVEVfREFUQTsKICAgIG9wRGF0YS5lZXByb21BZGRyID0gYWRkcjsKICAgIG9wRGF0YS5lZXByb21EYXRhID0gZGF0YTsKCiAgICByZXRWYWwgPSBlZXByb21PcGVyYXRpb25QZXJmb3JtKGRldixlZXByb21PcCwmb3BEYXRhKTsKICAgIGlmKHJldFZhbCAhPSBHVF9PSykKICAgIHsKICAgICAgcmV0dXJuIHJldFZhbDsKICAgIH0KICAgIHJldHVybiBHVF9PSzsKCn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgoqIGdzeXNSZXN0YXJ0RWVwcm9tCioKKiBERVNDUklQVElPTjoKKiAgICAgICAgUmVzdGFydCBSZWdpc3RlciBMb2FkZXIgZXhlY3V0aW9uIGF0IHRoZSBFRVBST02ScyBhZGRyZXNzIHdoZXJlIHRoZSBFRU9wCiogICAgICAgIGlzIHBlcmZvcm1lZAoqCiogSU5QVVRTOgoqICAgICAgICBhZGRyIC0gRUVQUk9NIEFkZHJlc3MuIC4KKgoqIE9VVFBVVFM6CiogICAgICAgIE5vbmUuCioKKiBSRVRVUk5TOgoqICAgICAgICBHVF9PSyAgICAgIC0gb24gc3VjY2VzcwoqICAgICAgICBHVF9GQUlMICAgIC0gb24gZXJyb3IKKiAgICAgICAgR1RfQkFEX1BBUkFNIC0gaWYgaW5wdXQgcGFyYW1ldGVycyBhcmUgYmV5b25kIHJhbmdlLgoqICAgICAgICBHVF9OT1RfU1VQUE9SVEVEIC0gaWYgY3VycmVudCBkZXZpY2UgZG9lcyBub3Qgc3VwcG9ydCB0aGlzIGZlYXR1cmUuCioKKiBDT01NRU5UUzoKKiAgICAgICAgTm9uZQoqCioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCkdUX1NUQVRVUyBnc3lzUmVzdGFydEVlcHJvbQooCiAgICBJTiAgR1RfUURfREVWICAgICAgICAgKmRldiwKICAgIElOICBHVF9VMzIgICAgICAgICAgICBhZGRyCikKewogICAgR1RfU1RBVFVTICAgIHJldFZhbDsgICAgICAgICAvKiBGdW5jdGlvbnMgcmV0dXJuIHZhbHVlLiAgICAgICovCiAgICBHVF9FRVBST01fT1BFUkFUSU9OICAgIGVlcHJvbU9wOwogICAgR1RfRUVQUk9NX09QX0RBVEEgICAgb3BEYXRhOwoKICAgIGVlcHJvbU9wID0gR1RfRUVQUk9NX1JFU1RBUlQ7CiAgICBvcERhdGEuZWVwcm9tQWRkciA9IGFkZHI7CgogICAgcmV0VmFsID0gZWVwcm9tT3BlcmF0aW9uUGVyZm9ybShkZXYsZWVwcm9tT3AsJm9wRGF0YSk7CiAgICBpZihyZXRWYWwgIT0gR1RfT0spCiAgICB7CiAgICAgIHJldHVybiByZXRWYWw7CiAgICB9CiAgICByZXR1cm4gR1RfT0s7Cgp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKKiBnc3lzSGFsdEVlcHJvbQoqCiogREVTQ1JJUFRJT046CiogICAgICAgIEhhbHQgKHN0b3AgZXhlY3V0aW5nIHRoZSBFRVBST00gaWYgaXRzIG5vdCBhbHJlYWR5IHN0b3BwZWQpCioKKiBJTlBVVFM6CiogICAgICAgIE5vbmUuCioKKiBPVVRQVVRTOgoqICAgICAgICBOb25lLgoqCiogUkVUVVJOUzoKKiAgICAgICAgR1RfT0sgICAgICAtIG9uIHN1Y2Nlc3MKKiAgICAgICAgR1RfRkFJTCAgICAtIG9uIGVycm9yCiogICAgICAgIEdUX0JBRF9QQVJBTSAtIGlmIGlucHV0IHBhcmFtZXRlcnMgYXJlIGJleW9uZCByYW5nZS4KKiAgICAgICAgR1RfTk9UX1NVUFBPUlRFRCAtIGlmIGN1cnJlbnQgZGV2aWNlIGRvZXMgbm90IHN1cHBvcnQgdGhpcyBmZWF0dXJlLgoqCiogQ09NTUVOVFM6CiogICAgICAgIE5vbmUKKgoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwpHVF9TVEFUVVMgZ3N5c0hhbHRFZXByb20KKAogICAgSU4gIEdUX1FEX0RFViAgICAgICAgICpkZXYKKQp7CiAgICBHVF9TVEFUVVMgICAgcmV0VmFsOyAgICAgICAgIC8qIEZ1bmN0aW9ucyByZXR1cm4gdmFsdWUuICAgICAgKi8KICAgIEdUX0VFUFJPTV9PUEVSQVRJT04gICAgZWVwcm9tT3A7CiAgICBHVF9FRVBST01fT1BfREFUQSAgICBvcERhdGE7CgogICAgZWVwcm9tT3AgPSBHVF9FRVBST01fSEFMVDsKCiAgICByZXRWYWwgPSBlZXByb21PcGVyYXRpb25QZXJmb3JtKGRldixlZXByb21PcCwgICZvcERhdGEpOwogICAgaWYocmV0VmFsICE9IEdUX09LKQogICAgewogICAgICByZXR1cm4gcmV0VmFsOwogICAgfQogICAgcmV0dXJuIEdUX09LOwoKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiogZ3N5c0dldFN0RWVwcm9tCioKKiBERVNDUklQVElPTjoKKiAgICAgICAgR2V0IEVFUFJPTSBzdGF0dXMuIFRoZXkgYXJlIFJlZ2lzdGVyIExvYWRlciBSdW5uaW5nIHN0YXR1cyBhbmQgRUVQUk9NCiogICAgICAgIFdyaXRlIEVuYWJsZSBzdGF0dXMKKiAgICAgICAgcnVuU3QgaXMgR1RfVFJVRTogUmVnaXN0ZXIgTG9hZGVyIFJ1bm5pbmcsIHdoZW5ldmVyIHRoZSByZWdpc3RlciBsb2FkZXIKKiAgICAgICAgICAgIGlzIGJ1c3kgZXhlY3V0aW5nIHRoZSBpbnN0cnVjdGlvbnMgY29udGFpbmVkIGluIHRoZSBFRVBST00uCiogICAgICAgIHdyaXRlRW4gaXMgR1RfVFJVRTogRUVQUk9NIFdyaXRlIEVuYWJsZSwgdGhhdCBpbmRpY2F0ZXMgdGhhdCB3cml0aW5nIHRvCiogICAgICAgICAgICB0aGUgRUVQUk9NIGlzIHBvc3NpYmxlLgoqICAgICAgICB3cml0ZUVuIGlzIEdUX0ZBTFNFOiB0aGUgV3JpdGUgRUVQUk9NIEVFT3AgYWJvdmUgd2lsbCBub3QgZG8gYW55dGhpbmcuCiogICAgICAgICAgICBUaGlzIHJlZmxlY3RzIHRoZSB2YWx1ZSBvZiB0aGUgRUVfV0UgY29uZmlndXJhdGlvbiBwaW4gYWZ0ZXIgUmVzZXQuCioKKiBJTlBVVFM6CiogICAgICAgIE5vbmUuCioKKiBPVVRQVVRTOgoqICAgICAgICBydW5TdCAgIC0gICBbR1RfVFJVRV0gLyBbR1RfRkFMU0UpCiogICAgICAgIHdyaXRlRW4gLSAgIFtHVF9UUlVFXSAvIFtHVF9GQUxTRSkKKgoqIFJFVFVSTlM6CiogICAgICAgIEdUX09LICAgICAgLSBvbiBzdWNjZXNzCiogICAgICAgIEdUX0ZBSUwgICAgLSBvbiBlcnJvcgoqICAgICAgICBHVF9CQURfUEFSQU0gLSBpZiBpbnB1dCBwYXJhbWV0ZXJzIGFyZSBiZXlvbmQgcmFuZ2UuCiogICAgICAgIEdUX05PVF9TVVBQT1JURUQgLSBpZiBjdXJyZW50IGRldmljZSBkb2VzIG5vdCBzdXBwb3J0IHRoaXMgZmVhdHVyZS4KKgoqIENPTU1FTlRTOgoqICAgICAgICBOb25lCioKKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KR1RfU1RBVFVTIGdzeXNHZXRTdEVlcHJvbQooCiAgICBJTiAgR1RfUURfREVWICAgICAgICAgKmRldiwKICAgIE9VVCBHVF9CT09MICAgICAgICAgICAgKndyaXRlRW4sCiAgICBPVVQgR1RfQk9PTCAgICAgICAgICAgICpydW5TdAopCnsKICAgIEdUX1NUQVRVUyAgICByZXRWYWw7ICAgICAgICAgLyogRnVuY3Rpb25zIHJldHVybiB2YWx1ZS4gICAgICAqLwogICAgR1RfVTE2ICAgICAgZGF0YTsgICAgICAgICAgICAgLyogdGVtcG9yYXJ5IERhdGEgc3RvcmFnZSAqLwoKICAgIC8qIENoZWNrIGlmIFN3aXRjaCBzdXBwb3J0cyB0aGlzIGZlYXR1cmUuICovCiAgICBpZiAoIUlTX0lOX0RFVl9HUk9VUChkZXYsREVWX0VFUFJPTSkpCiAgICB7CiAgICAgICAgREJHX0lORk8oKCJHVF9OT1RfU1VQUE9SVEVEXG4iKSk7CiAgICAgICAgcmV0dXJuIEdUX05PVF9TVVBQT1JURUQ7CiAgICB9CgogICAgcmV0VmFsID0gaHdSZWFkR2xvYmFsMlJlZyhkZXYsUURfUkVHX0VFUFJPTV9DT01NQU5ELCAmZGF0YSk7CiAgICBpZihyZXRWYWwgIT0gR1RfT0spCiAgICB7CiAgICAgICAgICAgcmV0dXJuIHJldFZhbDsKICAgIH0KCgogICAgKnJ1blN0ICAgPSAoZGF0YSZHVF9FRVBST01fT1BfU1RfUlVOTklOR19NQVNLKT9HVF9UUlVFOkdUX0ZBTFNFOwogICAgKndyaXRlRW4gPSAoZGF0YSZHVF9FRVBST01fT1BfU1RfV1JJVEVfRU5fTUFTSyk/R1RfVFJVRTpHVF9GQUxTRTsKCiAgICByZXR1cm4gR1RfT0s7Cgp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKKiBnc3lzU2V0U2NyYXRjaE1pc2NDdHJsCioKKiBERVNDUklQVElPTjoKKiAgICAgICAgU2V0IFNjcmF0Y2ggYW5kIE1pc2MgY29udHJvbCBkYXRhIHRvIHRoZSBTY3JhdGNoIGFuZCBNaXNjIENvbnRyb2wgcmVnaXN0ZXIuCiogICAgICAgIFRoZSByZWdpc3RlcnMgb2YgU2NyYXRjaCBhbmQgTWlzYyBjb250cm9sIGFyZS4KKiAgICAgICAgICAgICAgICBTY3JhdGNoIEJ5dGUgMAoqICAgICAgICAgICAgICAgIFNjcmF0Y2ggQnl0ZSAxCiogICAgICAgICAgICAgICAgR1BJTyBDb25maWd1cmF0aW9uCiogICAgICAgICAgICAgICAgUmVzZXJ2ZWQgZm9yIGZ1dHVyZSB1c2UKKiAgICAgICAgICAgICAgICBHUElPIERpcmVjdGlvbgoqICAgICAgICAgICAgICAgIEdQSU8gRGF0YQoqICAgICAgICAgICAgICAgIENPTkZJRyBEYXRhIDAKKiAgICAgICAgICAgICAgICBDT05GSUcgRGF0YSAxCiogICAgICAgICAgICAgICAgQ09ORklHIERhdGEgMgoqICAgICAgICAgICAgICAgIENPTkZJRyBEYXRhIDMKKiAgICAgICAgICAgICAgICBTeW5jRSAmIFRBSUNMSzEyNZJzIERyaXZlCiogICAgICAgICAgICAgICAgUDWScyAmIENMSzEyNZJzIENsb2NrIERyaXZlCiogICAgICAgICAgICAgICAgUDaScyBDbG9jayBEcml2ZQoqICAgICAgICAgICAgICAgIEVFUFJPTSBQYWQgZHJpdmUKKgoqIElOUFVUUzoKKiAgICAgICAgcG9pbnQgLSBQb2ludGVyIHRvIHRoZSBTY3JhdGNoIGFuZCBNaXNjLiBDb250cm9sIHJlZ2lzdGVyLgoqICAgICAgICBkYXRhICAtIFNjcmF0Y2ggYW5kIE1pc2MuIENvbnRyb2wgZGF0YSB3cml0dGVuIHRvIHRoZSByZWdpc3RlcgoqICAgICAgICAgICAgICAgIHBvaW50ZWQgdG8gYnkgdGhlIHBvaW50IGFib3ZlLgoqCiogT1VUUFVUUzoKKiAgICAgICAgTm9uZS4KKgoqIFJFVFVSTlM6CiogICAgICAgIEdUX09LICAgICAgLSBvbiBzdWNjZXNzCiogICAgICAgIEdUX0ZBSUwgICAgLSBvbiBlcnJvcgoqICAgICAgICBHVF9CQURfUEFSQU0gLSBpZiBpbnB1dCBwYXJhbWV0ZXJzIGFyZSBiZXlvbmQgcmFuZ2UuCiogICAgICAgIEdUX05PVF9TVVBQT1JURUQgLSBpZiBjdXJyZW50IGRldmljZSBkb2VzIG5vdCBzdXBwb3J0IHRoaXMgZmVhdHVyZS4KKgoqIENPTU1FTlRTOgoqICAgICAgICBOb25lCioKKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KR1RfU1RBVFVTIGdzeXNTZXRTY3JhdGNoTWlzY0N0cmwKKAogICAgSU4gIEdUX1FEX0RFViAgICAgICAgICpkZXYsCiAgICBJTiAgR1RfVTMyICAgICAgICAgICAgcG9pbnQsCiAgICBJTiAgR1RfVTggICAgICAgICAgICBkYXRhCikKewogICAgR1RfU1RBVFVTICAgIHJldFZhbDsgICAgICAgICAvKiBGdW5jdGlvbnMgcmV0dXJuIHZhbHVlLiAgICAgICovCiAgICBJTiAgR1RfVTE2ICAgICAgICAgICAgdG1wRGF0YTsKCiAgICBpZiAocG9pbnQgPiBHVF9TQ1JBVF9NSVNDX1JFR19NQVgpCiAgICB7CiAgICAgICAgREJHX0lORk8oKCJHVF9CQURfUEFSQU1cbiIpKTsKICAgICAgICByZXR1cm4gR1RfQkFEX1BBUkFNOwogICAgfQoKICAgIGlmIChkYXRhICYweGZmZmZmZjAwKQogICAgewogICAgICAgIERCR19JTkZPKCgiR1RfQkFEX1BBUkFNXG4iKSk7CiAgICAgICAgcmV0dXJuIEdUX0JBRF9QQVJBTTsKICAgIH0KCiAgICBndFNlbVRha2UoZGV2LGRldi0+dGJsUmVnc1NlbSxPU19XQUlUX0ZPUkVWRVIpOwoKICAgIC8qIHByb2dyYW0gUW9TIFdlaWdodCBUYWJsZSwgNCBzZXF1ZW5jZXMgYXQgYSB0aW1lICovCgogICAgLyogV2FpdCB1bnRpbCB0aGUgU2NyYXRjaCBhbmQgTWlzYyBjb250cm9sIGlzIHJlYWR5LiAqLwojaWZkZWYgR1RfUk1HTVRfQUNDRVNTCiAgICB7CiAgICAgIEhXX0RFVl9SRUdfQUNDRVNTIHJlZ0FjY2VzczsKCiAgICAgIHJlZ0FjY2Vzcy5lbnRyaWVzID0gMTsKCiAgICAgIHJlZ0FjY2Vzcy5yd19yZWdfbGlzdFswXS5jbWQgPSBIV19SRUdfV0FJVF9USUxMXzA7CiAgICAgIHJlZ0FjY2Vzcy5yd19yZWdfbGlzdFswXS5hZGRyID0gQ0FMQ19TTUlfREVWX0FERFIoZGV2LCAwLCBHTE9CQUwyX1JFR19BQ0NFU1MpOwogICAgICByZWdBY2Nlc3MucndfcmVnX2xpc3RbMF0ucmVnID0gUURfUkVHX1NDUkFUQ0hfTUlTQzsKICAgICAgcmVnQWNjZXNzLnJ3X3JlZ19saXN0WzBdLmRhdGEgPSAxNTsKICAgICAgcmV0VmFsID0gaHdBY2Nlc3NNdWx0aVJlZ3MoZGV2LCAmcmVnQWNjZXNzKTsKICAgICAgaWYocmV0VmFsICE9IEdUX09LKQogICAgICB7CiAgICAgICAgZ3RTZW1HaXZlKGRldixkZXYtPnZ0dVJlZ3NTZW0pOwogICAgICAgIHJldHVybiByZXRWYWw7CiAgICAgIH0KICAgIH0KI2Vsc2UKICAgICAgIHRtcERhdGEgPSAxOwogICAgd2hpbGUodG1wRGF0YSA9PSAxKQogICAgICAgewogICAgICAgIHJldFZhbCA9IGh3R2V0R2xvYmFsMlJlZ0ZpZWxkKGRldixRRF9SRUdfU0NSQVRDSF9NSVNDLDE1LDEsJnRtcERhdGEpOwogICAgICAgICAgIGlmKHJldFZhbCAhPSBHVF9PSykKICAgICAgICAgICB7CiAgICAgICAgICAgIGd0U2VtR2l2ZShkZXYsZGV2LT50YmxSZWdzU2VtKTsKICAgICAgICAgICAgICAgcmV0dXJuIHJldFZhbDsKICAgICAgICAgICB9CiAgICB9CiNlbmRpZgoKICAgIHRtcERhdGEgPSAgKEdUX1UxNikoKDEgPDwgMTUpIHwgKHBvaW50IDw8IDgpIHwgZGF0YSk7CgogICAgcmV0VmFsID0gaHdXcml0ZUdsb2JhbDJSZWcoZGV2LCBRRF9SRUdfU0NSQVRDSF9NSVNDLCB0bXBEYXRhKTsKICAgIGlmKHJldFZhbCAhPSBHVF9PSykKICAgICAgIHsKICAgICAgICAgICBEQkdfSU5GTygoIkZhaWxlZC5cbiIpKTsKICAgICAgICAgICBndFNlbUdpdmUoZGV2LGRldi0+dGJsUmVnc1NlbSk7CiAgICAgICAgICAgcmV0dXJuIHJldFZhbDsKICAgIH0KCgoKICAgIGd0U2VtR2l2ZShkZXYsZGV2LT50YmxSZWdzU2VtKTsKCiAgICAgICByZXR1cm4gcmV0VmFsOwoKfQoKCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgoqIGdzeXNHZXRTY3JhdGNoTWlzY0N0cmwKKgoqIERFU0NSSVBUSU9OOgoqICAgICAgICBHZXQgU2NyYXRjaCBhbmQgTWlzYyBjb250cm9sIGRhdGEgZnJvbSB0aGUgU2NyYXRjaCBhbmQgTWlzYyBDb250cm9sIHJlZ2lzdGVyLgoqICAgICAgICBUaGUgcmVnaXN0ZXIgb2YgU2NyYXRjaCBhbmQgTWlzYyBjb250cm9sIGFyZS4KKiAgICAgICAgICAgICAgICBTY3JhdGNoIEJ5dGUgMAoqICAgICAgICAgICAgICAgIFNjcmF0Y2ggQnl0ZSAxCiogICAgICAgICAgICAgICAgR1BJTyBDb25maWd1cmF0aW9uCiogICAgICAgICAgICAgICAgUmVzZXJ2ZWQgZm9yIGZ1dHVyZSB1c2UKKiAgICAgICAgICAgICAgICBHUElPIERpcmVjdGlvbgoqICAgICAgICAgICAgICAgIEdQSU8gRGF0YQoqICAgICAgICAgICAgICAgIENPTkZJRyBEYXRhIDAKKiAgICAgICAgICAgICAgICBDT05GSUcgRGF0YSAxCiogICAgICAgICAgICAgICAgQ09ORklHIERhdGEgMgoqICAgICAgICAgICAgICAgIENPTkZJRyBEYXRhIDMKKiAgICAgICAgICAgICAgICBTeW5jRSAmIFRBSUNMSzEyNZJzIERyaXZlCiogICAgICAgICAgICAgICAgUDWScyAmIENMSzEyNZJzIENsb2NrIERyaXZlCiogICAgICAgICAgICAgICAgUDaScyBDbG9jayBEcml2ZQoqICAgICAgICAgICAgICAgIEVFUFJPTSBQYWQgZHJpdmUKCioKKiBJTlBVVFM6CiogICAgICAgIHBvaW50IC0gUG9pbnRlciB0byB0aGUgU2NyYXRjaCBhbmQgTWlzYy4gQ29udHJvbCByZWdpc3Rlci4KKgoqIE9VVFBVVFM6CiogICAgICAgIGRhdGEgLSBTY3JhdGNoIGFuZCBNaXNjLiBDb250cm9sIGRhdGEgcmVhZCBmcm9tIHRoZSByZWdpc3RlcgoqICAgICAgICAgICAgICAgIHBvaW50ZWQgdG8gYnkgdGhlIHBvaW50IGFib3ZlLgoqCiogUkVUVVJOUzoKKiAgICAgICAgR1RfT0sgICAgICAtIG9uIHN1Y2Nlc3MKKiAgICAgICAgR1RfRkFJTCAgICAtIG9uIGVycm9yCiogICAgICAgIEdUX0JBRF9QQVJBTSAtIGlmIGlucHV0IHBhcmFtZXRlcnMgYXJlIGJleW9uZCByYW5nZS4KKiAgICAgICAgR1RfTk9UX1NVUFBPUlRFRCAtIGlmIGN1cnJlbnQgZGV2aWNlIGRvZXMgbm90IHN1cHBvcnQgdGhpcyBmZWF0dXJlLgoqCiogQ09NTUVOVFM6CiogICAgICAgIE5vbmUKKgoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwpHVF9TVEFUVVMgZ3N5c0dldFNjcmF0Y2hNaXNjQ3RybAooCiAgICBJTiAgR1RfUURfREVWICAgICAgICAgKmRldiwKICAgIElOICBHVF9VMzIgICAgICAgICAgICBwb2ludCwKICAgIE9VVCAgR1RfVTggICAgICAgICAgICAqZGF0YQopCnsKICAgIEdUX1NUQVRVUyAgICByZXRWYWw7ICAgICAgICAgLyogRnVuY3Rpb25zIHJldHVybiB2YWx1ZS4gICAgICAqLwogICAgT1VUICBHVF9VMTYgICAgICAgICAgICB0bXBEYXRhOwoKICAgIGlmIChwb2ludCA+IEdUX1NDUkFUX01JU0NfUkVHX01BWCkKICAgIHsKICAgICAgICBEQkdfSU5GTygoIkdUX0JBRF9QQVJBTVxuIikpOwogICAgICAgIHJldHVybiBHVF9CQURfUEFSQU07CiAgICB9CgogICAgaWYgKHBvaW50PjB4N2YpCiAgICB7CiAgICAgICAgREJHX0lORk8oKCJHVF9CQURfUEFSQU1cbiIpKTsKICAgICAgICByZXR1cm4gR1RfQkFEX1BBUkFNOwogICAgfQoKICAgIGd0U2VtVGFrZShkZXYsZGV2LT50YmxSZWdzU2VtLE9TX1dBSVRfRk9SRVZFUik7CgogICAgLyogcHJvZ3JhbSBRb1MgV2VpZ2h0IFRhYmxlLCA0IHNlcXVlbmNlcyBhdCBhIHRpbWUgKi8KCiNpZmRlZiBHVF9STUdNVF9BQ0NFU1MKICAgIHsKICAgICAgSFdfREVWX1JFR19BQ0NFU1MgcmVnQWNjZXNzOwoKICAgICAgcmVnQWNjZXNzLmVudHJpZXMgPSAyOwoKICAgICAgcmVnQWNjZXNzLnJ3X3JlZ19saXN0WzBdLmNtZCA9IEhXX1JFR19XQUlUX1RJTExfMDsKICAgICAgcmVnQWNjZXNzLnJ3X3JlZ19saXN0WzBdLmFkZHIgPSBDQUxDX1NNSV9ERVZfQUREUihkZXYsIDAsIEdMT0JBTDJfUkVHX0FDQ0VTUyk7CiAgICAgIHJlZ0FjY2Vzcy5yd19yZWdfbGlzdFswXS5yZWcgPSBRRF9SRUdfU0NSQVRDSF9NSVNDOwogICAgICByZWdBY2Nlc3MucndfcmVnX2xpc3RbMF0uZGF0YSA9IDE1OwogICAgICByZWdBY2Nlc3MucndfcmVnX2xpc3RbMV0uY21kID0gSFdfUkVHX1JFQUQ7CiAgICAgIHJlZ0FjY2Vzcy5yd19yZWdfbGlzdFsxXS5hZGRyID0gQ0FMQ19TTUlfREVWX0FERFIoZGV2LCAwLCBHTE9CQUwyX1JFR19BQ0NFU1MpOwogICAgICByZWdBY2Nlc3MucndfcmVnX2xpc3RbMV0ucmVnID0gUURfUkVHX1NDUkFUQ0hfTUlTQzsKICAgICAgcmVnQWNjZXNzLnJ3X3JlZ19saXN0WzFdLmRhdGEgPSAwOwogICAgICByZXRWYWwgPSBod0FjY2Vzc011bHRpUmVncyhkZXYsICZyZWdBY2Nlc3MpOwogICAgICBpZihyZXRWYWwgIT0gR1RfT0spCiAgICAgIHsKICAgICAgICBndFNlbUdpdmUoZGV2LGRldi0+dnR1UmVnc1NlbSk7CiAgICAgICAgcmV0dXJuIHJldFZhbDsKICAgICB9CiAgICAgdG1wRGF0YSA9IHFkTG9uZzJTaG9ydChyZWdBY2Nlc3MucndfcmVnX2xpc3RbMV0uZGF0YSk7CiAgICB9CiNlbHNlCiAgICBkbyB7CiAgICAgICAgcmV0VmFsID0gaHdSZWFkR2xvYmFsMlJlZyhkZXYsIFFEX1JFR19TQ1JBVENIX01JU0MsICZ0bXBEYXRhKTsKICAgICAgICBpZihyZXRWYWwgIT0gR1RfT0spCiAgICAgICAgICAgewogICAgICAgICAgICAgICBEQkdfSU5GTygoIkZhaWxlZC5cbiIpKTsKICAgICAgICAgICAgZ3RTZW1HaXZlKGRldixkZXYtPnRibFJlZ3NTZW0pOwogICAgICAgICAgICAgICByZXR1cm4gcmV0VmFsOwogICAgICAgIH0KICAgIH0gd2hpbGUgKHRtcERhdGEmMHg4MDAwKTsKI2VuZGlmCgogICAgKmRhdGEgPSB0bXBEYXRhJjB4ZmY7CgogICAgZ3RTZW1HaXZlKGRldixkZXYtPnRibFJlZ3NTZW0pOwoKCiAgICByZXR1cm4gcmV0VmFsOwp9CgoKCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgoqIGdzeXNTZXRTY3JhdGNoQml0cwoqCiogREVTQ1JJUFRJT046CiogICAgICAgIFNldCBiaXRzIHRvIHRoZSBTY3JhdGNoIGFuZCBNaXNjIENvbnRyb2wgcmVnaXN0ZXIgPHNjcmF0Y2ggYnl0ZSAwIGFuZCAxPi4KKiAgICAgICAgVGhlc2UgYml0cyBhcmUgMTAwJSBhdmFpbGFibGUgdG8gc29mdHdhcmUgZm9yIHdoYXRldmVyIHB1cnBvc2UgZGVzaXJlZC4KKiAgICAgICAgVGhlc2UgYml0cyBkbyBub3QgY29ubmVjdCB0byBhbnkgaGFyZHdhcmUgZnVuY3Rpb24uCioKKiBJTlBVVFM6CiogICAgICAgIHNjcml0Y2ggLSB3cml0dGVuIGJpdHMuCioKKiBPVVRQVVRTOgoqICAgICAgICBOb25lLgoqCiogUkVUVVJOUzoKKiAgICAgICAgR1RfT0sgICAgICAtIG9uIHN1Y2Nlc3MKKiAgICAgICAgR1RfRkFJTCAgICAtIG9uIGVycm9yCiogICAgICAgIEdUX0JBRF9QQVJBTSAtIGlmIGlucHV0IHBhcmFtZXRlcnMgYXJlIGJleW9uZCByYW5nZS4KKiAgICAgICAgR1RfTk9UX1NVUFBPUlRFRCAtIGlmIGN1cnJlbnQgZGV2aWNlIGRvZXMgbm90IHN1cHBvcnQgdGhpcyBmZWF0dXJlLgoqCiogQ09NTUVOVFM6CiogICAgICAgIE5vbmUKKgoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwpHVF9TVEFUVVMgZ3N5c1NldFNjcmF0Y2hCaXRzCigKICAgIElOICBHVF9RRF9ERVYgICAgICAgICAqZGV2LAogICAgSU4gIEdUX1UxNiAgICAgICAgICAgIHNjcmF0Y2gKKQp7CiAgICBHVF9TVEFUVVMgICAgcmV0VmFsOyAgICAgICAgIC8qIEZ1bmN0aW9ucyByZXR1cm4gdmFsdWUuICAgICAgKi8KCiAgICBEQkdfSU5GTygoImdzeXNTZXRTY3JhdGNoQml0cyBDYWxsZWQuXG4iKSk7CgogICAgLyogQ2hlY2sgaWYgU3dpdGNoIHN1cHBvcnRzIHRoaXMgZmVhdHVyZS4gKi8KICAgIGlmICghSVNfSU5fREVWX0dST1VQKGRldixERVZfU0NSQVRDSF9NSVNDX0NUUkwpKQogICAgewogICAgICAgIERCR19JTkZPKCgiR1RfTk9UX1NVUFBPUlRFRFxuIikpOwogICAgICAgIHJldHVybiBHVF9OT1RfU1VQUE9SVEVEOwogICAgfQoKICAgIHJldFZhbCA9IGdzeXNTZXRTY3JhdGNoTWlzY0N0cmwoZGV2LCBHVF9TQ1JBVF9NSVNDX1JFR19TQ1JBVF8wLCAoR1RfVTgpKHNjcmF0Y2gmMHhmZikpOwogICAgaWYocmV0VmFsICE9IEdUX09LKQogICAgICAgewogICAgICAgICAgIERCR19JTkZPKCgiRmFpbGVkLlxuIikpOwogICAgICAgICAgIHJldHVybiByZXRWYWw7CiAgICB9CgogICAgcmV0VmFsID0gZ3N5c1NldFNjcmF0Y2hNaXNjQ3RybChkZXYsIEdUX1NDUkFUX01JU0NfUkVHX1NDUkFUXzEsIChHVF9VOCkoKHNjcmF0Y2g+PjgpJjB4ZmYpKTsKICAgIGlmKHJldFZhbCAhPSBHVF9PSykKICAgICAgIHsKICAgICAgICAgICBEQkdfSU5GTygoIkZhaWxlZC5cbiIpKTsKICAgICAgICAgICByZXR1cm4gcmV0VmFsOwogICAgfQoKICAgIHJldHVybiBHVF9PSzsKCn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiogZ3N5c0dldFNjcmF0Y2hCaXRzCioKKiBERVNDUklQVElPTjoKKiAgICAgICAgR2V0IGJpdHMgZnJvbSB0aGUgU2NyYXRjaCBhbmQgTWlzYyBDb250cm9sIHJlZ2lzdGVyIDxzY3JhdGNoIGJ5dGUgMCBhbmQgMT4uCiogICAgICAgIFRoZXNlIGJpdHMgYXJlIDEwMCUgYXZhaWxhYmxlIHRvIHNvZnR3YXJlIGZvciB3aGF0ZXZlciBwdXJwb3NlIGRlc2lyZWQuCiogICAgICAgIFRoZXNlIGJpdHMgZG8gbm90IGNvbm5lY3QgdG8gYW55IGhhcmR3YXJlIGZ1bmN0aW9uLgoqCiogSU5QVVRTOgoqICAgICAgICBOb25lLgoqCiogT1VUUFVUUzoKKiAgICAgICAgc2NyaXRjaCAtIHJlYWQgYml0cy4KKgoqIFJFVFVSTlM6CiogICAgICAgIEdUX09LICAgICAgLSBvbiBzdWNjZXNzCiogICAgICAgIEdUX0ZBSUwgICAgLSBvbiBlcnJvcgoqICAgICAgICBHVF9CQURfUEFSQU0gLSBpZiBpbnB1dCBwYXJhbWV0ZXJzIGFyZSBiZXlvbmQgcmFuZ2UuCiogICAgICAgIEdUX05PVF9TVVBQT1JURUQgLSBpZiBjdXJyZW50IGRldmljZSBkb2VzIG5vdCBzdXBwb3J0IHRoaXMgZmVhdHVyZS4KKgoqIENPTU1FTlRTOgoqICAgICAgICBOb25lCioKKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KR1RfU1RBVFVTIGdzeXNHZXRTY3JhdGNoQml0cwooCiAgICBJTiAgR1RfUURfREVWICAgICAgICAgKmRldiwKICAgIE9VVCAgR1RfVTE2ICAgICAgICAgICAgKnNjcmF0Y2gKKQp7CiAgICBHVF9TVEFUVVMgICAgcmV0VmFsOyAgICAgICAgIC8qIEZ1bmN0aW9ucyByZXR1cm4gdmFsdWUuICAgICAgKi8KICAgIEdUX1U4ICAgICAgICBkYXRhOwoKICAgIERCR19JTkZPKCgiZ3N5c0dldFNjcmF0Y2hCaXRzIENhbGxlZC5cbiIpKTsKCiAgICAvKiBDaGVjayBpZiBTd2l0Y2ggc3VwcG9ydHMgdGhpcyBmZWF0dXJlLiAqLwogICAgaWYgKCFJU19JTl9ERVZfR1JPVVAoZGV2LERFVl9TQ1JBVENIX01JU0NfQ1RSTCkpCiAgICB7CiAgICAgICAgREJHX0lORk8oKCJHVF9OT1RfU1VQUE9SVEVEXG4iKSk7CiAgICAgICAgcmV0dXJuIEdUX05PVF9TVVBQT1JURUQ7CiAgICB9CgogICAgcmV0VmFsID0gZ3N5c0dldFNjcmF0Y2hNaXNjQ3RybChkZXYsIEdUX1NDUkFUX01JU0NfUkVHX1NDUkFUXzEsICZkYXRhKTsKICAgIGlmKHJldFZhbCAhPSBHVF9PSykKICAgICAgIHsKICAgICAgICAgICBEQkdfSU5GTygoIkZhaWxlZC5cbiIpKTsKICAgICAgICAgICByZXR1cm4gcmV0VmFsOwogICAgfQogICAgKnNjcmF0Y2ggPSBkYXRhOwogICAgKnNjcmF0Y2ggPSAqc2NyYXRjaDw8ODsKICAgIHJldFZhbCA9IGdzeXNHZXRTY3JhdGNoTWlzY0N0cmwoZGV2LCBHVF9TQ1JBVF9NSVNDX1JFR19TQ1JBVF8wLCAmZGF0YSk7CiAgICBpZihyZXRWYWwgIT0gR1RfT0spCiAgICAgICB7CiAgICAgICAgICAgREJHX0lORk8oKCJGYWlsZWQuXG4iKSk7CiAgICAgICAgICAgcmV0dXJuIHJldFZhbDsKICAgIH0KCiAgICAqc2NyYXRjaCB8PSBkYXRhOwoKICAgIHJldHVybiBHVF9PSzsKCn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgoqIGdzeXNTZXRHcGlvQ29uZmlnTW9kCioKKiBERVNDUklQVElPTjoKKiAgICAgICAgU2V0IGJpdHMgdG8gdGhlIFNjcmF0Y2ggYW5kIE1pc2MgQ29udHJvbCByZWdpc3RlciA8R1BJTyBDb25maWd1cmF0aW9uPgoqICAgICAgICB0byBjb25maWd1cmUgR1BJTyBtb2RlLgoqICAgICAgICBUaGUgYml0cyBhcmUgc2hhcmVkIEdlbmVyYWwgUHVycG9zZSBJbnB1dCBPdXRwdXQgbW9kZSBCaXRzOgoqICAgICAgICBCaXQgNiAtIEdUX0dQSU9fQklUXzY6ICAgIDE6R1BJT1s2XSAgICAwOlNFX1JDTEsxCiogICAgICAgIEJpdCA1IC0gR1RfR1BJT19CSVRfNTogICAgMTpHUElPWzVdICAgIDA6U0VfUkNMSzAKKiAgICAgICAgTm93LCBmb2xsb2luZyBiaXRzIGFyZSByZWFkIG9ubHkuCiogICAgICAgIEJpdCA0IC0gR1RfR1BJT19CSVRfNDogICAgMTpHUElPWzRdICAgIDA6CiogICAgICAgIEJpdCAzIC0gR1RfR1BJT19CSVRfMzogICAgMTpHUElPWzNdICAgIDA6CiogICAgICAgIEJpdCAyIC0gR1RfR1BJT19CSVRfMjogICAgMTpHUElPWzJdICAgIDA6CiogICAgICAgIEJpdCAxIC0gR1RfR1BJT19CSVRfMTogICAgMTpHUElPWzFdICAgIDA6UDZfQ09MCiogICAgICAgIEJpdCAwIC0gR1RfR1BJT19CSVRfMDogICAgMTpHUElPWzBdICAgIDA6UDZfQ1JTCioKKiBJTlBVVFM6CiogICAgICAgIG1vZGUgLSBPUiBbR1RfR1BJT19CSVRfeF0KKgoqIE9VVFBVVFM6CiogICAgICAgIE5vbmUuCioKKiBSRVRVUk5TOgoqICAgICAgICBHVF9PSyAgICAgIC0gb24gc3VjY2VzcwoqICAgICAgICBHVF9GQUlMICAgIC0gb24gZXJyb3IKKiAgICAgICAgR1RfQkFEX1BBUkFNIC0gaWYgaW5wdXQgcGFyYW1ldGVycyBhcmUgYmV5b25kIHJhbmdlLgoqICAgICAgICBHVF9OT1RfU1VQUE9SVEVEIC0gaWYgY3VycmVudCBkZXZpY2UgZG9lcyBub3Qgc3VwcG9ydCB0aGlzIGZlYXR1cmUuCioKKiBDT01NRU5UUzoKKiAgICAgICAgTm9uZQoqCioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCkdUX1NUQVRVUyBnc3lzU2V0R3Bpb0NvbmZpZ01vZAooCiAgICBJTiAgR1RfUURfREVWICAgICAgICAgKmRldiwKICAgIElOICBHVF9VMzIgICAgICAgICAgICBtb2RlCikKewogICAgR1RfU1RBVFVTICAgIHJldFZhbDsgICAgICAgICAvKiBGdW5jdGlvbnMgcmV0dXJuIHZhbHVlLiAgICAgICovCgogICAgREJHX0lORk8oKCJnc3lzU2V0R3Bpb0NvbmZpZ01vZCBDYWxsZWQuXG4iKSk7CgogICAgLyogQ2hlY2sgaWYgU3dpdGNoIHN1cHBvcnRzIHRoaXMgZmVhdHVyZS4gKi8KICAgIGlmICghSVNfSU5fREVWX0dST1VQKGRldixERVZfU0NSQVRDSF9NSVNDX0NUUkwpKQogICAgewogICAgICAgIERCR19JTkZPKCgiR1RfTk9UX1NVUFBPUlRFRFxuIikpOwogICAgICAgIHJldHVybiBHVF9OT1RfU1VQUE9SVEVEOwogICAgfQoKICAgIHJldFZhbCA9IGdzeXNTZXRTY3JhdGNoTWlzY0N0cmwoZGV2LCBHVF9TQ1JBVF9NSVNDX1JFR19HUElPX0NGRywgKEdUX1U4KShtb2RlJjB4N2YpKTsKICAgIGlmKHJldFZhbCAhPSBHVF9PSykKICAgICAgIHsKICAgICAgICAgICBEQkdfSU5GTygoIkZhaWxlZC5cbiIpKTsKICAgICAgICAgICByZXR1cm4gcmV0VmFsOwogICAgfQoKCiAgICByZXR1cm4gR1RfT0s7Cgp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKKiBnc3lzR2V0R3Bpb0NvbmZpZ01vZAoqCiogREVTQ1JJUFRJT046CiogICAgICAgIEdldCBtb2RlIGZyb20gdGhlIFNjcmF0Y2ggYW5kIE1pc2MgQ29udHJvbCByZWdpc3RlciA8R1BJTyBDb25maWd1cmF0aW9uPi4KKiAgICAgICAgVGhlIGJpdHMgYXJlIHNoYXJlZCBHZW5lcmFsIFB1cnBvc2UgSW5wdXQgT3V0cHV0IG1vZGUgQml0czoKKiAgICAgICAgQml0IDYgLSBHVF9HUElPX0JJVF82OiAgICAxOkdQSU9bNl0gICAgMDpTRV9SQ0xLMQoqICAgICAgICBCaXQgNSAtIEdUX0dQSU9fQklUXzU6ICAgIDE6R1BJT1s1XSAgICAwOlNFX1JDTEswCiogICAgICAgIE5vdywgZm9sbG9pbmcgYml0cyBhcmUgcmVhZCBvbmx5LgoqICAgICAgICBCaXQgNCAtIEdUX0dQSU9fQklUXzQ6ICAgIDE6R1BJT1s0XSAgICAwOgoqICAgICAgICBCaXQgMyAtIEdUX0dQSU9fQklUXzM6ICAgIDE6R1BJT1szXSAgICAwOgoqICAgICAgICBCaXQgMiAtIEdUX0dQSU9fQklUXzI6ICAgIDE6R1BJT1syXSAgICAwOgoqICAgICAgICBCaXQgMSAtIEdUX0dQSU9fQklUXzE6ICAgIDE6R1BJT1sxXSAgICAwOlA2X0NPTAoqICAgICAgICBCaXQgMCAtIEdUX0dQSU9fQklUXzA6ICAgIDE6R1BJT1swXSAgICAwOlA2X0NSUwoqCiogSU5QVVRTOgoqICAgICAgICBOb25lLgoqCiogT1VUUFVUUzoKKiAgICAgICAgbW9kZSAtIE9SIFtHVF9HUElPX0JJVF94XQoqCiogUkVUVVJOUzoKKiAgICAgICAgR1RfT0sgICAgICAtIG9uIHN1Y2Nlc3MKKiAgICAgICAgR1RfRkFJTCAgICAtIG9uIGVycm9yCiogICAgICAgIEdUX0JBRF9QQVJBTSAtIGlmIGlucHV0IHBhcmFtZXRlcnMgYXJlIGJleW9uZCByYW5nZS4KKiAgICAgICAgR1RfTk9UX1NVUFBPUlRFRCAtIGlmIGN1cnJlbnQgZGV2aWNlIGRvZXMgbm90IHN1cHBvcnQgdGhpcyBmZWF0dXJlLgoqCiogQ09NTUVOVFM6CiogICAgICAgIE5vbmUKKgoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwpHVF9TVEFUVVMgZ3N5c0dldEdwaW9Db25maWdNb2QKKAogICAgSU4gIEdUX1FEX0RFViAgICAgICAgICpkZXYsCiAgICBJTiAgR1RfVTMyICAgICAgICAgICAgKm1vZGUKKQp7CiAgICBHVF9TVEFUVVMgICAgcmV0VmFsOyAgICAgICAgIC8qIEZ1bmN0aW9ucyByZXR1cm4gdmFsdWUuICAgICAgKi8KICAgIEdUX1U4ICAgICAgICBkYXRhOwoKICAgIERCR19JTkZPKCgiZ3N5c0dldEdwaW9Db25maWdNb2QgQ2FsbGVkLlxuIikpOwoKICAgIC8qIENoZWNrIGlmIFN3aXRjaCBzdXBwb3J0cyB0aGlzIGZlYXR1cmUuICovCiAgICBpZiAoIUlTX0lOX0RFVl9HUk9VUChkZXYsREVWX1NDUkFUQ0hfTUlTQ19DVFJMKSkKICAgIHsKICAgICAgICBEQkdfSU5GTygoIkdUX05PVF9TVVBQT1JURURcbiIpKTsKICAgICAgICByZXR1cm4gR1RfTk9UX1NVUFBPUlRFRDsKICAgIH0KCiAgICByZXRWYWwgPSBnc3lzR2V0U2NyYXRjaE1pc2NDdHJsKGRldiwgR1RfU0NSQVRfTUlTQ19SRUdfR1BJT19DRkcsICZkYXRhKTsKICAgIGlmKHJldFZhbCAhPSBHVF9PSykKICAgICAgIHsKICAgICAgICAgICBEQkdfSU5GTygoIkZhaWxlZC5cbiIpKTsKICAgICAgICAgICByZXR1cm4gcmV0VmFsOwogICAgfQoKICAgICptb2RlID0gMHg3ZiZkYXRhOwoKICAgIHJldHVybiBHVF9PSzsKCn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgoqIGdzeXNTZXRHcGlvRGlyZWN0aW9uCioKKiBERVNDUklQVElPTjoKKiAgICAgICAgU2V0IEdwaW8gZGlyZWN0aW9uIHRvIHRoZSBTY3JhdGNoIGFuZCBNaXNjIENvbnRyb2wgcmVnaXN0ZXIgPEdQSU8gRGlyZWN0aW9uPi4KKiAgICAgICAgVGhlIGJpdHMgYXJlIHVzZWQgdG8gY29udHJvbCB0aGUgZGlyZWN0aW9uIG9mIEdQSU9bNjowXS4KKiAgICAgICAgV2hlbiBhIEdQSU+ScyBiaXQgaXMgc2V0IHRvIGEgb25lIHRoYXQgR1BJTyB3aWxsIGJlY29tZSBhbiBpbnB1dC4gV2hlbiBhCiogICAgICAgIEdQSU+ScyBiaXQgaXMgY2xlYXJlZCB0byBhIHplcm8gdGhhdCBHUElPIHdpbGwgYmVjb21lIGFuIG91dHB1dAoqICAgICAgICBHZW5lcmFsIFB1cnBvc2UgSW5wdXQgT3V0cHV0IGRpcmVjdGlvbiBiaXRzIGFyZToKKiAgICAgICAgQml0IDYgLSBHVF9HUElPX0JJVF82CiogICAgICAgIEJpdCA1IC0gR1RfR1BJT19CSVRfNQoqICAgICAgICBCaXQgNCAtIEdUX0dQSU9fQklUXzQKKiAgICAgICAgQml0IDMgLSBHVF9HUElPX0JJVF8zCiogICAgICAgIEJpdCAyIC0gR1RfR1BJT19CSVRfMgoqICAgICAgICBCaXQgMSAtIEdUX0dQSU9fQklUXzEKKiAgICAgICAgQml0IDAgLSBHVF9HUElPX0JJVF8wCioKKiBJTlBVVFM6CiogICAgICAgIGRpciAtIE9SIFtHVF9HUElPX0JJVF94XQoqCiogT1VUUFVUUzoKKiAgICAgICAgTm9uZS4KKgoqIFJFVFVSTlM6CiogICAgICAgIEdUX09LICAgICAgLSBvbiBzdWNjZXNzCiogICAgICAgIEdUX0ZBSUwgICAgLSBvbiBlcnJvcgoqICAgICAgICBHVF9CQURfUEFSQU0gLSBpZiBpbnB1dCBwYXJhbWV0ZXJzIGFyZSBiZXlvbmQgcmFuZ2UuCiogICAgICAgIEdUX05PVF9TVVBQT1JURUQgLSBpZiBjdXJyZW50IGRldmljZSBkb2VzIG5vdCBzdXBwb3J0IHRoaXMgZmVhdHVyZS4KKgoqIENPTU1FTlRTOgoqICAgICAgICBOb25lCioKKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KR1RfU1RBVFVTIGdzeXNTZXRHcGlvRGlyZWN0aW9uCigKICAgIElOICBHVF9RRF9ERVYgICAgICAgICAqZGV2LAogICAgSU4gIEdUX1UzMiAgICAgICAgICAgIGRpcgopCnsKICAgIEdUX1NUQVRVUyAgICByZXRWYWw7ICAgICAgICAgLyogRnVuY3Rpb25zIHJldHVybiB2YWx1ZS4gICAgICAqLwoKICAgIERCR19JTkZPKCgiZ3N5c1NldEdwaW9EaXJlY3Rpb24gQ2FsbGVkLlxuIikpOwoKICAgIC8qIENoZWNrIGlmIFN3aXRjaCBzdXBwb3J0cyB0aGlzIGZlYXR1cmUuICovCiAgICBpZiAoIUlTX0lOX0RFVl9HUk9VUChkZXYsREVWX1NDUkFUQ0hfTUlTQ19DVFJMKSkKICAgIHsKICAgICAgICBEQkdfSU5GTygoIkdUX05PVF9TVVBQT1JURURcbiIpKTsKICAgICAgICByZXR1cm4gR1RfTk9UX1NVUFBPUlRFRDsKICAgIH0KCiAgICByZXRWYWwgPSBnc3lzU2V0U2NyYXRjaE1pc2NDdHJsKGRldiwgR1RfU0NSQVRfTUlTQ19SRUdfR1BJT19ESVIsIChHVF9VOCkoZGlyJjB4N2YpKTsKICAgIGlmKHJldFZhbCAhPSBHVF9PSykKICAgICAgIHsKICAgICAgICAgICBEQkdfSU5GTygoIkZhaWxlZC5cbiIpKTsKICAgICAgICAgICByZXR1cm4gcmV0VmFsOwogICAgfQoKCiAgICByZXR1cm4gR1RfT0s7Cgp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKKiBnc3lzR2V0R3Bpb0RpcmVjdGlvbgoqCiogREVTQ1JJUFRJT046CiogICAgICAgIGdldCBHcGlvIGRpcmVjdGlvbiBmcm9tIHRoZSBTY3JhdGNoIGFuZCBNaXNjIENvbnRyb2wgcmVnaXN0ZXIgPEdQSU8gRGlyZWN0aW9uPi4KKiAgICAgICAgVGhlIGJpdHMgYXJlIHVzZWQgdG8gY29udHJvbCB0aGUgZGlyZWN0aW9uIG9mIEdQSU9bNjowXS4KKiAgICAgICAgV2hlbiBhIEdQSU+ScyBiaXQgaXMgc2V0IHRvIGEgb25lIHRoYXQgR1BJTyB3aWxsIGJlY29tZSBhbiBpbnB1dC4gV2hlbiBhCiogICAgICAgIEdQSU+ScyBiaXQgaXMgY2xlYXJlZCB0byBhIHplcm8gdGhhdCBHUElPIHdpbGwgYmVjb21lIGFuIG91dHB1dAoqICAgICAgICBHZW5lcmFsIFB1cnBvc2UgSW5wdXQgT3V0cHV0IGRpcmVjdGlvbiBiaXRzIGFyZToKKiAgICAgICAgQml0IDYgLSBHVF9HUElPX0JJVF82CiogICAgICAgIEJpdCA1IC0gR1RfR1BJT19CSVRfNQoqICAgICAgICBCaXQgNCAtIEdUX0dQSU9fQklUXzQKKiAgICAgICAgQml0IDMgLSBHVF9HUElPX0JJVF8zCiogICAgICAgIEJpdCAyIC0gR1RfR1BJT19CSVRfMgoqICAgICAgICBCaXQgMSAtIEdUX0dQSU9fQklUXzEKKiAgICAgICAgQml0IDAgLSBHVF9HUElPX0JJVF8wCioKKiBJTlBVVFM6CiogICAgICAgIE5vbmUuCioKKiBPVVRQVVRTOgoqICAgICAgICBkaXIgLSBPUiBbR1RfR1BJT19CSVRfeF0KKgoqIFJFVFVSTlM6CiogICAgICAgIEdUX09LICAgICAgLSBvbiBzdWNjZXNzCiogICAgICAgIEdUX0ZBSUwgICAgLSBvbiBlcnJvcgoqICAgICAgICBHVF9CQURfUEFSQU0gLSBpZiBpbnB1dCBwYXJhbWV0ZXJzIGFyZSBiZXlvbmQgcmFuZ2UuCiogICAgICAgIEdUX05PVF9TVVBQT1JURUQgLSBpZiBjdXJyZW50IGRldmljZSBkb2VzIG5vdCBzdXBwb3J0IHRoaXMgZmVhdHVyZS4KKgoqIENPTU1FTlRTOgoqICAgICAgICBOb25lCioKKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KR1RfU1RBVFVTIGdzeXNHZXRHcGlvRGlyZWN0aW9uCigKICAgIElOICBHVF9RRF9ERVYgICAgICAgICAqZGV2LAogICAgT1VUICBHVF9VMzIgICAgICAgICAgICAqZGlyCikKewogICAgR1RfU1RBVFVTICAgIHJldFZhbDsgICAgICAgICAvKiBGdW5jdGlvbnMgcmV0dXJuIHZhbHVlLiAgICAgICovCiAgICBHVF9VOCAgICAgICAgZGF0YTsKCiAgICBEQkdfSU5GTygoImdzeXNHZXRHcGlvRGlyZWN0aW9uIENhbGxlZC5cbiIpKTsKCiAgICAvKiBDaGVjayBpZiBTd2l0Y2ggc3VwcG9ydHMgdGhpcyBmZWF0dXJlLiAqLwogICAgaWYgKCFJU19JTl9ERVZfR1JPVVAoZGV2LERFVl9TQ1JBVENIX01JU0NfQ1RSTCkpCiAgICB7CiAgICAgICAgREJHX0lORk8oKCJHVF9OT1RfU1VQUE9SVEVEXG4iKSk7CiAgICAgICAgcmV0dXJuIEdUX05PVF9TVVBQT1JURUQ7CiAgICB9CgogICAgcmV0VmFsID0gZ3N5c0dldFNjcmF0Y2hNaXNjQ3RybChkZXYsIEdUX1NDUkFUX01JU0NfUkVHX0dQSU9fRElSLCAmZGF0YSk7CiAgICBpZihyZXRWYWwgIT0gR1RfT0spCiAgICAgICB7CiAgICAgICAgICAgREJHX0lORk8oKCJGYWlsZWQuXG4iKSk7CiAgICAgICAgICAgcmV0dXJuIHJldFZhbDsKICAgIH0KCiAgICAqZGlyID0gZGF0YTsKCiAgICByZXR1cm4gR1RfT0s7Cgp9CgoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiogZ3N5c1NldEdwaW9EYXRhCioKKiBERVNDUklQVElPTjoKKiAgICAgICAgU2V0IEdwaW8gZGF0YSB0byB0aGUgU2NyYXRjaCBhbmQgTWlzYyBDb250cm9sIHJlZ2lzdGVyIDxHUElPIGRhdGE+LgoqICAgICAgICBXaGVuIGEgR1BJT5JzIGJpdCBpcyBzZXQgdG8gYmUgYW4gaW5wdXQsIGRhdGEgd3JpdHRlbiB0byB0aGlzIGJpdCB3aWxsIGdvCiogICAgICAgIHRvIGEgaG9sZGluZyByZWdpc3RlciBidXQgd2lsbCBub3QgYXBwZWFyIG9uIHRoZSBwaW4gbm9yIGluIHRoaXMgcmVnaXN0ZXIuCiogICAgICAgIFJlYWRzIG9mIHRoaXMgcmVnaXN0ZXIgd2lsbCByZXR1cm4gdGhlIGFjdHVhbCwgcmVhbC10aW1lLCBkYXRhIHRoYXQgaXMKKiAgICAgICAgYXBwZWFyaW5nIG9uIHRoZSBHUElPknMgcGluLgoqICAgICAgICBXaGVuIGEgR1BJT5JzIGJpdCBpcyBzZXQgdG8gYmUgYW4gb3V0cHV0LCBkYXRhIHdyaXR0ZW4gdG8gdGhpcyBiaXQgd2lsbCBnbwoqICAgICAgICB0byBhIGhvbGRpbmcgcmVnaXN0ZXIgYW5kIHdpbGwgYXBwZWFyIG9uIHRoZSBHUElPknMgcGluLiBSZWFkcyBvZiB0aGlzIHJlZ2lzdGVyCiogICAgICAgIHdpbGwgcmV0dXJuIHRoZSBhY3R1YWwsIHJlYWwtdGltZSwgZGF0YSB0aGF0IGlzIGFwcGVhcmluZyBvbiB0aGUgR1BJT5JzIHBpbgoqICAgICAgICAod2hpY2ggaW4gdGhpcyBjYXNlIHNob3VsZCBiZSB0aGUgZGF0YSB3cml0dGVuLCBidXQgaWYgaXRzIGlzbpJ0IHRoYXQgd291bGQKKiAgICAgICAgYmUgYW4gaW5kaWNhdGlvbiBvZiBhIGNvbmZsaWN0KS4KKiAgICAgICAgV2hlbiBhIHBpbpJzIGRpcmVjdGlvbiBjaGFuZ2VzIGZyb20gaW5wdXQgdG8gb3V0cHV0LCB0aGUgZGF0YSBsYXN0IHdyaXR0ZW4KKiAgICAgICAgdG8gdGhlIGhvbGRpbmcgcmVnaXN0ZXIgYXBwZWFycyBvbiB0aGUgR1BJT5JzIHBpbgoqICAgICAgICBHZW5lcmFsIFB1cnBvc2UgSW5wdXQgT3V0cHV0IGRhdGEgYml0cyBhcmU6CiogICAgICAgIEJpdCA2IC0gR1RfR1BJT19CSVRfNgoqICAgICAgICBCaXQgNSAtIEdUX0dQSU9fQklUXzUKKiAgICAgICAgQml0IDQgLSBHVF9HUElPX0JJVF80CiogICAgICAgIEJpdCAzIC0gR1RfR1BJT19CSVRfMwoqICAgICAgICBCaXQgMiAtIEdUX0dQSU9fQklUXzIKKiAgICAgICAgQml0IDEgLSBHVF9HUElPX0JJVF8xCiogICAgICAgIEJpdCAwIC0gR1RfR1BJT19CSVRfMAoqCiogSU5QVVRTOgoqICAgICAgICBkYXRhIC0gT1IgW0dUX0dQSU9fQklUX3hdCioKKiBPVVRQVVRTOgoqICAgICAgICBOb25lLgoqCiogUkVUVVJOUzoKKiAgICAgICAgR1RfT0sgICAgICAtIG9uIHN1Y2Nlc3MKKiAgICAgICAgR1RfRkFJTCAgICAtIG9uIGVycm9yCiogICAgICAgIEdUX0JBRF9QQVJBTSAtIGlmIGlucHV0IHBhcmFtZXRlcnMgYXJlIGJleW9uZCByYW5nZS4KKiAgICAgICAgR1RfTk9UX1NVUFBPUlRFRCAtIGlmIGN1cnJlbnQgZGV2aWNlIGRvZXMgbm90IHN1cHBvcnQgdGhpcyBmZWF0dXJlLgoqCiogQ09NTUVOVFM6CiogICAgICAgIE5vbmUKKgoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwpHVF9TVEFUVVMgZ3N5c1NldEdwaW9EYXRhCigKICAgIElOICBHVF9RRF9ERVYgICAgICAgICAqZGV2LAogICAgSU4gIEdUX1UzMiAgICAgICAgICAgIGRhdGEKKQp7CiAgICBHVF9TVEFUVVMgICAgcmV0VmFsOyAgICAgICAgIC8qIEZ1bmN0aW9ucyByZXR1cm4gdmFsdWUuICAgICAgKi8KCiAgICBEQkdfSU5GTygoImdzeXNTZXRHcGlvRGF0YSBDYWxsZWQuXG4iKSk7CgogICAgLyogQ2hlY2sgaWYgU3dpdGNoIHN1cHBvcnRzIHRoaXMgZmVhdHVyZS4gKi8KICAgIGlmICghSVNfSU5fREVWX0dST1VQKGRldixERVZfU0NSQVRDSF9NSVNDX0NUUkwpKQogICAgewogICAgICAgIERCR19JTkZPKCgiR1RfTk9UX1NVUFBPUlRFRFxuIikpOwogICAgICAgIHJldHVybiBHVF9OT1RfU1VQUE9SVEVEOwogICAgfQoKICAgIHJldFZhbCA9IGdzeXNTZXRTY3JhdGNoTWlzY0N0cmwoZGV2LCBHVF9TQ1JBVF9NSVNDX1JFR19HUElPX0RBVCwgKEdUX1U4KShkYXRhJjB4N2YpKTsKICAgIGlmKHJldFZhbCAhPSBHVF9PSykKICAgICAgIHsKICAgICAgICAgICBEQkdfSU5GTygoIkZhaWxlZC5cbiIpKTsKICAgICAgICAgICByZXR1cm4gcmV0VmFsOwogICAgfQoKCiAgICByZXR1cm4gR1RfT0s7Cgp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgoqIGdzeXNHZXRHcGlvRGF0YQoqCiogREVTQ1JJUFRJT046CiogICAgICAgIGdldCBHcGlvIGRhdGEgdG8gdGhlIFNjcmF0Y2ggYW5kIE1pc2MgQ29udHJvbCByZWdpc3RlciA8R1BJTyBkYXRhPi4KKiAgICAgICAgV2hlbiBhIEdQSU+ScyBiaXQgaXMgc2V0IHRvIGJlIGFuIGlucHV0LCBkYXRhIHdyaXR0ZW4gdG8gdGhpcyBiaXQgd2lsbCBnbwoqICAgICAgICB0byBhIGhvbGRpbmcgcmVnaXN0ZXIgYnV0IHdpbGwgbm90IGFwcGVhciBvbiB0aGUgcGluIG5vciBpbiB0aGlzIHJlZ2lzdGVyLgoqICAgICAgICBSZWFkcyBvZiB0aGlzIHJlZ2lzdGVyIHdpbGwgcmV0dXJuIHRoZSBhY3R1YWwsIHJlYWwtdGltZSwgZGF0YSB0aGF0IGlzCiogICAgICAgIGFwcGVhcmluZyBvbiB0aGUgR1BJT5JzIHBpbi4KKiAgICAgICAgV2hlbiBhIEdQSU+ScyBiaXQgaXMgc2V0IHRvIGJlIGFuIG91dHB1dCwgZGF0YSB3cml0dGVuIHRvIHRoaXMgYml0IHdpbGwgZ28KKiAgICAgICAgdG8gYSBob2xkaW5nIHJlZ2lzdGVyIGFuZCB3aWxsIGFwcGVhciBvbiB0aGUgR1BJT5JzIHBpbi4gUmVhZHMgb2YgdGhpcyByZWdpc3RlcgoqICAgICAgICB3aWxsIHJldHVybiB0aGUgYWN0dWFsLCByZWFsLXRpbWUsIGRhdGEgdGhhdCBpcyBhcHBlYXJpbmcgb24gdGhlIEdQSU+ScyBwaW4KKiAgICAgICAgKHdoaWNoIGluIHRoaXMgY2FzZSBzaG91bGQgYmUgdGhlIGRhdGEgd3JpdHRlbiwgYnV0IGlmIGl0cyBpc26SdCB0aGF0IHdvdWxkCiogICAgICAgIGJlIGFuIGluZGljYXRpb24gb2YgYSBjb25mbGljdCkuCiogICAgICAgIFdoZW4gYSBwaW6ScyBkaXJlY3Rpb24gY2hhbmdlcyBmcm9tIGlucHV0IHRvIG91dHB1dCwgdGhlIGRhdGEgbGFzdCB3cml0dGVuCiogICAgICAgIHRvIHRoZSBob2xkaW5nIHJlZ2lzdGVyIGFwcGVhcnMgb24gdGhlIEdQSU+ScyBwaW4KKiAgICAgICAgR2VuZXJhbCBQdXJwb3NlIElucHV0IE91dHB1dCBkYXRhIGJpdHMgYXJlOgoqICAgICAgICBCaXQgNiAtIEdUX0dQSU9fQklUXzYKKiAgICAgICAgQml0IDUgLSBHVF9HUElPX0JJVF81CiogICAgICAgIEJpdCA0IC0gR1RfR1BJT19CSVRfNAoqICAgICAgICBCaXQgMyAtIEdUX0dQSU9fQklUXzMKKiAgICAgICAgQml0IDIgLSBHVF9HUElPX0JJVF8yCiogICAgICAgIEJpdCAxIC0gR1RfR1BJT19CSVRfMQoqICAgICAgICBCaXQgMCAtIEdUX0dQSU9fQklUXzAKKgoqIElOUFVUUzoKKiAgICAgICAgTm9uZS4KKgoqIE9VVFBVVFM6CiogICAgICAgIGRhdGEgLSBPUiBbR1RfR1BJT19CSVRfeF0KKgoqIFJFVFVSTlM6CiogICAgICAgIEdUX09LICAgICAgLSBvbiBzdWNjZXNzCiogICAgICAgIEdUX0ZBSUwgICAgLSBvbiBlcnJvcgoqICAgICAgICBHVF9CQURfUEFSQU0gLSBpZiBpbnB1dCBwYXJhbWV0ZXJzIGFyZSBiZXlvbmQgcmFuZ2UuCiogICAgICAgIEdUX05PVF9TVVBQT1JURUQgLSBpZiBjdXJyZW50IGRldmljZSBkb2VzIG5vdCBzdXBwb3J0IHRoaXMgZmVhdHVyZS4KKgoqIENPTU1FTlRTOgoqICAgICAgICBOb25lCioKKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KR1RfU1RBVFVTIGdzeXNHZXRHcGlvRGF0YQooCiAgICBJTiAgR1RfUURfREVWICAgICAgICAgKmRldiwKICAgIElOICBHVF9VMzIgICAgICAgICAgICAqZGF0YQopCnsKICAgIEdUX1NUQVRVUyAgICByZXRWYWw7ICAgICAgICAgLyogRnVuY3Rpb25zIHJldHVybiB2YWx1ZS4gICAgICAqLwogICAgR1RfVTggICAgICAgIHRtcERhdGE7CgogICAgREJHX0lORk8oKCJnc3lzR2V0R3Bpb0RhdGEgQ2FsbGVkLlxuIikpOwoKICAgIC8qIENoZWNrIGlmIFN3aXRjaCBzdXBwb3J0cyB0aGlzIGZlYXR1cmUuICovCiAgICBpZiAoIUlTX0lOX0RFVl9HUk9VUChkZXYsREVWX1NDUkFUQ0hfTUlTQ19DVFJMKSkKICAgIHsKICAgICAgICBEQkdfSU5GTygoIkdUX05PVF9TVVBQT1JURURcbiIpKTsKICAgICAgICByZXR1cm4gR1RfTk9UX1NVUFBPUlRFRDsKICAgIH0KCiAgICByZXRWYWwgPSBnc3lzR2V0U2NyYXRjaE1pc2NDdHJsKGRldiwgR1RfU0NSQVRfTUlTQ19SRUdfR1BJT19EQVQsICZ0bXBEYXRhKTsKICAgIGlmKHJldFZhbCAhPSBHVF9PSykKICAgICAgIHsKICAgICAgICAgICBEQkdfSU5GTygoIkZhaWxlZC5cbiIpKTsKICAgICAgICAgICByZXR1cm4gcmV0VmFsOwogICAgfQoKICAgICpkYXRhID0gdG1wRGF0YTsKCiAgICByZXR1cm4gR1RfT0s7Cgp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKKiBnc3lzR2V0Q29uZmlnRGF0YQoqCiogREVTQ1JJUFRJT046CiogICAgICAgIEdldCBSZXNldCBDb25maWd1cmF0aW9uIFBpbiBEYXRhIDAtMy4KKiAgICAgICAgVGhlc2UgcmVnaXN0ZXJzIHJldHVybiB0aGUgdmFsdWVzIG9ic2VydmVkIGFmdGVyIGEgaGFyZHdhcmUgUmVzZXQgb24gdGhlCiogICAgICAgIGxpc3RlZCBDT05GSUcgZGF0YSBsaXN0ZWQgYmVsb3cuCiogICAgICAgICAgICBDb25maWcgZGF0YSAwOgoqICAgICAgICAgICAgICBCaXQgICAgQ29uZmlnICAgIFBpbidzIFByaW1hcnkgTmFtZQoqICAgICAgICAgICAgICAgIDAgICAgVVNFUlswXSAgICAgICAgUDZfT1VURFs1XQoqICAgICAgICAgICAgICAgIDEgICAgVVNFUlsxXSAgICAgICAgUDZfT1VURFs2XQoqICAgICAgICAgICAgICAgIDIgICAgVVNFUlsyXSAgICAgICAgUDZfT1VURFs3XQoqICAgICAgICAgICAgICAgIDMgICAgQUREUlswXSAgICAgICAgUDVfT1VURFswXQoqICAgICAgICAgICAgICAgIDQgICAgQUREUlsxXSAgICAgICAgUDVfT1VURFs1XQoqICAgICAgICAgICAgICAgIDUgICAgQUREUlsyXSAgICAgICAgUDVfT1VURFs2XQoqICAgICAgICAgICAgICAgIDYgICAgQUREUl0zXSAgICAgICAgUDVfT1VURFs3XQoqICAgICAgICAgICAgICAgIDcgICAgQUREUls0XSAgICAgICAgUDVfT1VURFsxXQoqICAgICAgICAgICAgQ29uZmlnIGRhdGEgMToKKiAgICAgICAgICAgICAgICAwICAgIExFRF9TRUxbMF0gICAgUDFfTEVECiogICAgICAgICAgICAgICAgMSAgICBMRURfU0VMWzFdICAgIFAyX0xFRAoqICAgICAgICAgICAgICAgIDIgICAgNENPTCBQM19MRUQKKiAgICAgICAgICAgICAgICAzICAgIE5vcm1DeCAgICAgICAgUDRfTEVECiogICAgICAgICAgICAgICAgNCAgICBKdW1ibyAgICAgICAgUDBfTEVECiogICAgICAgICAgICAgICAgNSAgICBFRV9XRSAgICAgICAgRUVfQ1MvQzJfTEVECiogICAgICAgICAgICAgICAgNiAgICBGRF9GTE9XICAgICAgICBFRV9DTEsvQzFfTEVECiogICAgICAgICAgICAgICAgNyAgICBIRF9GTE9XICAgICAgICBFRV9ESU4vQzBfTEVECiogICAgICAgICAgICBDb25maWcgZGF0YSAyOgoqICAgICAgICAgICAgICAgIDAgICAgUDVfTU9ERVswXSAgICBQNV9PVVREWzJdCiogICAgICAgICAgICAgICAgMSAgICBQNV9NT0RFWzFdICAgIFA1X09VVERbM10KKiAgICAgICAgICAgICAgICAyICAgIFA1X01PREVbMl0gICAgUDVfT1VURFs0XQoqICAgICAgICAgICAgICAgIDMgICAgUmVzZXJ2ZWQgZm9yIGZ1dHVyZSB1c2UKKiAgICAgICAgICAgICAgICA0ICAgIFA2X01PREVbMF0gICAgUDZfT1VURFsyXQoqICAgICAgICAgICAgICAgIDUgICAgUDZfTU9ERVsxXSAgICBQNl9PVVREWzNdCiogICAgICAgICAgICAgICAgNiAgICBQNl9NT0RFWzJdICAgIFA2X09VVERbNF0KKiAgICAgICAgICAgICAgICA3ICAgIFJlc2VydmVkIGZvciBmdXR1cmUgdXNlCiogICAgICAgICAgICBDb25maWcgZGF0YSAzOgoqICAgICAgICAgICAgICAgIDAgICAgUk1VX01PREVbMF0gUDZfT1VURFswXQoqICAgICAgICAgICAgICAgIDEgICAgUk1VX01PREVbMV0gUDZfT1VURFsxXQoqICAgICAgICAgICAgICAgIDIgICAgU19WRERPU1swXSAgICBQVFBfVFJJRwoqICAgICAgICAgICAgICAgIDMgICAgQ0xLMTI1RU4gICAgQ0xLMTI1CiogICAgICAgICAgICAgICAgNCAgICBQNV9WRERPU1swXSBQNV9HVFhDTEsKKiAgICAgICAgICAgICAgICA1ICAgIFA1X1ZERE9TWzFdIFA1X09VVEVOCiogICAgICAgICAgICAgICAgNiAgICBQNl9WRERPU1swXSBQNV9HVFhDTEsKKiAgICAgICAgICAgICAgICA3ICAgIFA2X1ZERE9TWzFdIFA2X09VVEVOCiogSU5QVVRTOgoqICAgICAgICBOb25lLgoqCiogT1VUUFVUUzoKKiAgICAgICBjZmdEYXQgLSBHVF9DT05GSUdfRFRUQQoqCiogUkVUVVJOUzoKKiAgICAgICAgR1RfT0sgICAgICAtIG9uIHN1Y2Nlc3MKKiAgICAgICAgR1RfRkFJTCAgICAtIG9uIGVycm9yCiogICAgICAgIEdUX0JBRF9QQVJBTSAtIGlmIGlucHV0IHBhcmFtZXRlcnMgYXJlIGJleW9uZCByYW5nZS4KKiAgICAgICAgR1RfTk9UX1NVUFBPUlRFRCAtIGlmIGN1cnJlbnQgZGV2aWNlIGRvZXMgbm90IHN1cHBvcnQgdGhpcyBmZWF0dXJlLgoqCiogQ09NTUVOVFM6CiogICAgICAgIE5vbmUKKgoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwpHVF9TVEFUVVMgZ3N5c0dldENvbmZpZ0RhdGEKKAogICAgSU4gIEdUX1FEX0RFViAgICAgICAgICAgICAqZGV2LAogICAgT1VUICBHVF9DT05GSUdfREFUQSAgICAgICAgKmNmZ0RhdGEKKQp7CiAgICBHVF9TVEFUVVMgICAgcmV0VmFsOyAgICAgICAgIC8qIEZ1bmN0aW9ucyByZXR1cm4gdmFsdWUuICAgICAgKi8KICAgIEdUX1U4ICAgICAgICB0bXBEYXRhOwoKICAgIERCR19JTkZPKCgiZ3N5c0dldENvbmZpZ0RhdGEgQ2FsbGVkLlxuIikpOwoKICAgIC8qIENoZWNrIGlmIFN3aXRjaCBzdXBwb3J0cyB0aGlzIGZlYXR1cmUuICovCiAgICBpZiAoIUlTX0lOX0RFVl9HUk9VUChkZXYsREVWX1NDUkFUQ0hfTUlTQ19DVFJMKSkKICAgIHsKICAgICAgICBEQkdfSU5GTygoIkdUX05PVF9TVVBQT1JURURcbiIpKTsKICAgICAgICByZXR1cm4gR1RfTk9UX1NVUFBPUlRFRDsKICAgIH0KCiAgICByZXRWYWwgPSBnc3lzR2V0U2NyYXRjaE1pc2NDdHJsKGRldiwgR1RfU0NSQVRfTUlTQ19SRUdfQ0ZHX0RBVDAsICZ0bXBEYXRhKTsKICAgIGlmKHJldFZhbCAhPSBHVF9PSykKICAgICAgIHsKICAgICAgICAgICBEQkdfSU5GTygoIkZhaWxlZC5cbiIpKTsKICAgICAgICAgICByZXR1cm4gcmV0VmFsOwogICAgfQoKICAgIGNmZ0RhdGEtPmNmZ0RhdGEwLkJ5dGUgPSB0bXBEYXRhOwoKICAgIHJldFZhbCA9IGdzeXNHZXRTY3JhdGNoTWlzY0N0cmwoZGV2LCBHVF9TQ1JBVF9NSVNDX1JFR19DRkdfREFUMSwgJnRtcERhdGEpOwogICAgaWYocmV0VmFsICE9IEdUX09LKQogICAgICAgewogICAgICAgICAgIERCR19JTkZPKCgiRmFpbGVkLlxuIikpOwogICAgICAgICAgIHJldHVybiByZXRWYWw7CiAgICB9CgogICAgY2ZnRGF0YS0+Y2ZnRGF0YTEuQnl0ZSA9IHRtcERhdGE7CgogICAgcmV0VmFsID0gZ3N5c0dldFNjcmF0Y2hNaXNjQ3RybChkZXYsIEdUX1NDUkFUX01JU0NfUkVHX0NGR19EQVQyLCAmdG1wRGF0YSk7CiAgICBpZihyZXRWYWwgIT0gR1RfT0spCiAgICAgICB7CiAgICAgICAgICAgREJHX0lORk8oKCJGYWlsZWQuXG4iKSk7CiAgICAgICAgICAgcmV0dXJuIHJldFZhbDsKICAgIH0KCiAgICBjZmdEYXRhLT5jZmdEYXRhMi5CeXRlID0gdG1wRGF0YTsKCiAgICByZXRWYWwgPSBnc3lzR2V0U2NyYXRjaE1pc2NDdHJsKGRldiwgR1RfU0NSQVRfTUlTQ19SRUdfQ0ZHX0RBVDMsICZ0bXBEYXRhKTsKICAgIGlmKHJldFZhbCAhPSBHVF9PSykKICAgICAgIHsKICAgICAgICAgICBEQkdfSU5GTygoIkZhaWxlZC5cbiIpKTsKICAgICAgICAgICByZXR1cm4gcmV0VmFsOwogICAgfQoKICAgIGNmZ0RhdGEtPmNmZ0RhdGEzLkJ5dGUgPSB0bXBEYXRhOwoKICAgIHJldHVybiBHVF9PSzsKCn0KCgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKKiBnc3lzU2V0U3luY0VUYWkKKgoqIERFU0NSSVBUSU9OOgoqICAgICAgICBTZXQgU3luY0UgYW5kIFRhaSB0byB0aGUgU2NyYXRjaCBhbmQgTWlzYy4gQ29udHJvbCByZWdpc3RlciA8U3luY0UgYW5kIFRBSSBwYWQ+LgoqCiogSU5QVVRTOgoqICAgICAgICB6cHIgLSBaUFIgZm9yIFN5bmNFIGFuZCBUQUkKKiAgICAgICAgem5yIC0gWk5SIGZvciBTeW5jRSBhbmQgVEFJCioKKiBPVVRQVVRTOgoqICAgICAgICBOb25lLgoqCiogUkVUVVJOUzoKKiAgICAgICAgR1RfT0sgICAgICAtIG9uIHN1Y2Nlc3MKKiAgICAgICAgR1RfRkFJTCAgICAtIG9uIGVycm9yCiogICAgICAgIEdUX0JBRF9QQVJBTSAtIGlmIGlucHV0IHBhcmFtZXRlcnMgYXJlIGJleW9uZCByYW5nZS4KKiAgICAgICAgR1RfTk9UX1NVUFBPUlRFRCAtIGlmIGN1cnJlbnQgZGV2aWNlIGRvZXMgbm90IHN1cHBvcnQgdGhpcyBmZWF0dXJlLgoqCiogQ09NTUVOVFM6CiogICAgICAgIE5vbmUKKgoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwpHVF9TVEFUVVMgZ3N5c1NldFN5bmNFVGFpCigKICAgIElOICBHVF9RRF9ERVYgICAgICAgICAqZGV2LAogICAgSU4gIEdUX1U4ICAgICAgICAgICAgenByLAogICAgSU4gIEdUX1U4ICAgICAgICAgICAgem5yCikKewogICAgR1RfU1RBVFVTICAgIHJldFZhbDsgICAgICAgICAvKiBGdW5jdGlvbnMgcmV0dXJuIHZhbHVlLiAgICAgICovCiAgICBHVF9VOCAgICAgICAgZGF0YTsKCiAgICBEQkdfSU5GTygoImdzeXNTZXRTeW5jRVRhaSBDYWxsZWQuXG4iKSk7CgogICAgLyogQ2hlY2sgaWYgU3dpdGNoIHN1cHBvcnRzIHRoaXMgZmVhdHVyZS4gKi8KICAgIGlmICghSVNfSU5fREVWX0dST1VQKGRldixERVZfU0NSQVRDSF9NSVNDX0NUUkwpKQogICAgewogICAgICAgIERCR19JTkZPKCgiR1RfTk9UX1NVUFBPUlRFRFxuIikpOwogICAgICAgIHJldHVybiBHVF9OT1RfU1VQUE9SVEVEOwogICAgfQoKICAgIGlmICgoenByPjB4NykgfHwgKHpucj4weDcpKQogICAgewogICAgICAgIERCR19JTkZPKCgiR1RfQkFEX1BBUkFNXG4iKSk7CiAgICAgICAgcmV0dXJuIEdUX0JBRF9QQVJBTTsKICAgIH0KCiAgICBkYXRhID0gKCh6cHImMHg3KTw8MykgfCAoem5yJjB4Nyk7CgogICAgcmV0VmFsID0gZ3N5c1NldFNjcmF0Y2hNaXNjQ3RybChkZXYsIEdUX1NDUkFUX01JU0NfUkVHX1NZTkNFLCBkYXRhKTsKICAgIGlmKHJldFZhbCAhPSBHVF9PSykKICAgICAgIHsKICAgICAgICAgICBEQkdfSU5GTygoIkZhaWxlZC5cbiIpKTsKICAgICAgICAgICByZXR1cm4gcmV0VmFsOwogICAgfQoKICAgIHJldHVybiBHVF9PSzsKCn0KCgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKKiBnc3lzR2V0U3luY0VUYWkKKgoqIERFU0NSSVBUSU9OOgoqICAgICAgICBHZXQgU3luY0UgYW5kIFRhaSBmcm9tIHRoZSBTY3JhdGNoIGFuZCBNaXNjIENvbnRyb2wgcmVnaXN0ZXIgPFN5bmNFIGFuZCBUQUkgcGFkPi4KKgoqIElOUFVUUzoKKiAgICAgICAgTm9uZS4KKgoqIE9VVFBVVFM6CiogICAgICAgIHpwciAtIFpQUiBmb3IgU3luY0UgYW5kIFRBSQoqICAgICAgICB6bnIgLSBaTlIgZm9yIFN5bmNFIGFuZCBUQUkqCioKKiBSRVRVUk5TOgoqICAgICAgICBHVF9PSyAgICAgIC0gb24gc3VjY2VzcwoqICAgICAgICBHVF9GQUlMICAgIC0gb24gZXJyb3IKKiAgICAgICAgR1RfQkFEX1BBUkFNIC0gaWYgaW5wdXQgcGFyYW1ldGVycyBhcmUgYmV5b25kIHJhbmdlLgoqICAgICAgICBHVF9OT1RfU1VQUE9SVEVEIC0gaWYgY3VycmVudCBkZXZpY2UgZG9lcyBub3Qgc3VwcG9ydCB0aGlzIGZlYXR1cmUuCioKKiBDT01NRU5UUzoKKiAgICAgICAgTm9uZQoqCioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCkdUX1NUQVRVUyBnc3lzR2V0U3luY0VUYWkKKAogICAgSU4gIEdUX1FEX0RFViAgICAgICAgICpkZXYsCiAgICBPVVQgIEdUX1U4ICAgICAgICAgICAgKnpwciwKICAgIE9VVCAgR1RfVTggICAgICAgICAgICAqem5yCikKewogICAgR1RfU1RBVFVTICAgIHJldFZhbDsgICAgICAgICAvKiBGdW5jdGlvbnMgcmV0dXJuIHZhbHVlLiAgICAgICovCiAgICBHVF9VOCAgICAgICAgZGF0YTsKCiAgICBEQkdfSU5GTygoImdzeXNHZXRTeW5jRVRhaSBDYWxsZWQuXG4iKSk7CgogICAgLyogQ2hlY2sgaWYgU3dpdGNoIHN1cHBvcnRzIHRoaXMgZmVhdHVyZS4gKi8KICAgIGlmICghSVNfSU5fREVWX0dST1VQKGRldixERVZfU0NSQVRDSF9NSVNDX0NUUkwpKQogICAgewogICAgICAgIERCR19JTkZPKCgiR1RfTk9UX1NVUFBPUlRFRFxuIikpOwogICAgICAgIHJldHVybiBHVF9OT1RfU1VQUE9SVEVEOwogICAgfQoKICAgIHJldFZhbCA9IGdzeXNHZXRTY3JhdGNoTWlzY0N0cmwoZGV2LCBHVF9TQ1JBVF9NSVNDX1JFR19TWU5DRSwgJmRhdGEpOwogICAgaWYocmV0VmFsICE9IEdUX09LKQogICAgICAgewogICAgICAgICAgIERCR19JTkZPKCgiRmFpbGVkLlxuIikpOwogICAgICAgICAgIHJldHVybiByZXRWYWw7CiAgICB9CgogICAgKnpwciA9IDB4NyAmKGRhdGE+PjMpOwogICAgKnpuciA9IDB4NyAmKGRhdGEpOwoKICAgIHJldHVybiBHVF9PSzsKCn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgoqIGdzeXNTZXRQNl9DbG9jawoqCiogREVTQ1JJUFRJT046CiogICAgICAgIFNldCBQNl9jbG9jayB0byB0aGUgU2NyYXRjaCBhbmQgTWlzYyBDb250cm9sIHJlZ2lzdGVyIDxQNl9DbG9jayBwYWQ+LgoqCiogSU5QVVRTOgoqICAgICAgICB6cHIgLSBaUFIgZm9yIFA2X0Nsb2NrCiogICAgICAgIHpuciAtIFpOUiBmb3IgUDZfQ2xvY2sKKgoqIE9VVFBVVFM6CiogICAgICAgIE5vbmUuCioKKiBSRVRVUk5TOgoqICAgICAgICBHVF9PSyAgICAgIC0gb24gc3VjY2VzcwoqICAgICAgICBHVF9GQUlMICAgIC0gb24gZXJyb3IKKiAgICAgICAgR1RfQkFEX1BBUkFNIC0gaWYgaW5wdXQgcGFyYW1ldGVycyBhcmUgYmV5b25kIHJhbmdlLgoqICAgICAgICBHVF9OT1RfU1VQUE9SVEVEIC0gaWYgY3VycmVudCBkZXZpY2UgZG9lcyBub3Qgc3VwcG9ydCB0aGlzIGZlYXR1cmUuCioKKiBDT01NRU5UUzoKKiAgICAgICAgTm9uZQoqCioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCkdUX1NUQVRVUyBnc3lzU2V0UDZfQ2xvY2sKKAogICAgSU4gIEdUX1FEX0RFViAgICAgICAgICpkZXYsCiAgICBJTiAgR1RfVTggICAgICAgICAgICB6cHIsCiAgICBJTiAgR1RfVTggICAgICAgICAgICB6bnIKKQp7CiAgICBHVF9TVEFUVVMgICAgcmV0VmFsOyAgICAgICAgIC8qIEZ1bmN0aW9ucyByZXR1cm4gdmFsdWUuICAgICAgKi8KICAgIEdUX1U4ICAgICAgICBkYXRhOwoKICAgIERCR19JTkZPKCgiZ3N5c1NldFA2X0Nsb2NrIENhbGxlZC5cbiIpKTsKCiAgICAvKiBDaGVjayBpZiBTd2l0Y2ggc3VwcG9ydHMgdGhpcyBmZWF0dXJlLiAqLwogICAgaWYgKCFJU19JTl9ERVZfR1JPVVAoZGV2LERFVl9TQ1JBVENIX01JU0NfQ1RSTCkpCiAgICB7CiAgICAgICAgREJHX0lORk8oKCJHVF9OT1RfU1VQUE9SVEVEXG4iKSk7CiAgICAgICAgcmV0dXJuIEdUX05PVF9TVVBQT1JURUQ7CiAgICB9CgogICAgaWYgKCh6cHI+MHg3KSB8fCAoem5yPjB4NykpCiAgICB7CiAgICAgICAgREJHX0lORk8oKCJHVF9CQURfUEFSQU1cbiIpKTsKICAgICAgICByZXR1cm4gR1RfQkFEX1BBUkFNOwogICAgfQoKICAgIGRhdGEgPSAoKHpwciYweDcpPDwzKSB8ICh6bnImMHg3KTsKCiAgICByZXRWYWwgPSBnc3lzU2V0U2NyYXRjaE1pc2NDdHJsKGRldiwgR1RfU0NSQVRfTUlTQ19SRUdfUDZfQ0xLLCBkYXRhKTsKICAgIGlmKHJldFZhbCAhPSBHVF9PSykKICAgICAgIHsKICAgICAgICAgICBEQkdfSU5GTygoIkZhaWxlZC5cbiIpKTsKICAgICAgICAgICByZXR1cm4gcmV0VmFsOwogICAgfQoKICAgIHJldHVybiBHVF9PSzsKCn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiogZ3N5c0dldFA2X0Nsb2NrCioKKiBERVNDUklQVElPTjoKKiAgICAgICBHZXQgUDZfY2xvY2sgZnJvbSB0aGUgU2NyYXRjaCBhbmQgTWlzYyBDb250cm9sIHJlZ2lzdGVyIDxQNl9DbG9jayBwYWQ+LgoqCiogSU5QVVRTOgoqICAgICAgICBOb25lLgoqCiogT1VUUFVUUzoKKiAgICAgICAgenByIC0gWlBSIGZvciBQNl9DbG9jawoqICAgICAgICB6bnIgLSBaTlIgZm9yIFA2X0Nsb2NrCioKKiBSRVRVUk5TOgoqICAgICAgICBHVF9PSyAgICAgIC0gb24gc3VjY2VzcwoqICAgICAgICBHVF9GQUlMICAgIC0gb24gZXJyb3IKKiAgICAgICAgR1RfQkFEX1BBUkFNIC0gaWYgaW5wdXQgcGFyYW1ldGVycyBhcmUgYmV5b25kIHJhbmdlLgoqICAgICAgICBHVF9OT1RfU1VQUE9SVEVEIC0gaWYgY3VycmVudCBkZXZpY2UgZG9lcyBub3Qgc3VwcG9ydCB0aGlzIGZlYXR1cmUuCioKKiBDT01NRU5UUzoKKiAgICAgICAgTm9uZQoqCioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCkdUX1NUQVRVUyBnc3lzR2V0UDZfQ2xvY2sKKAogICAgSU4gIEdUX1FEX0RFViAgICAgICAgICpkZXYsCiAgICBPVVQgIEdUX1U4ICAgICAgICAgICAgKnpwciwKICAgIE9VVCAgR1RfVTggICAgICAgICAgICAqem5yCikKewogICAgR1RfU1RBVFVTICAgIHJldFZhbDsgICAgICAgICAvKiBGdW5jdGlvbnMgcmV0dXJuIHZhbHVlLiAgICAgICovCiAgICBHVF9VOCAgICAgICAgZGF0YTsKCiAgICBEQkdfSU5GTygoImdzeXNHZXRQNl9DbG9jayBDYWxsZWQuXG4iKSk7CgogICAgLyogQ2hlY2sgaWYgU3dpdGNoIHN1cHBvcnRzIHRoaXMgZmVhdHVyZS4gKi8KICAgIGlmICghSVNfSU5fREVWX0dST1VQKGRldixERVZfU0NSQVRDSF9NSVNDX0NUUkwpKQogICAgewogICAgICAgIERCR19JTkZPKCgiR1RfTk9UX1NVUFBPUlRFRFxuIikpOwogICAgICAgIHJldHVybiBHVF9OT1RfU1VQUE9SVEVEOwogICAgfQoKICAgIHJldFZhbCA9IGdzeXNHZXRTY3JhdGNoTWlzY0N0cmwoZGV2LCBHVF9TQ1JBVF9NSVNDX1JFR19QNl9DTEssICZkYXRhKTsKICAgIGlmKHJldFZhbCAhPSBHVF9PSykKICAgICAgIHsKICAgICAgICAgICBEQkdfSU5GTygoIkZhaWxlZC5cbiIpKTsKICAgICAgICAgICByZXR1cm4gcmV0VmFsOwogICAgfQoKICAgICp6cHIgPSAweDcgJihkYXRhPj4zKTsKICAgICp6bnIgPSAweDcgJihkYXRhKTsKCiAgICByZXR1cm4gR1RfT0s7Cgp9CgoKCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgoqIGdzeXNTZXRQNV9DbG9jawoqCiogREVTQ1JJUFRJT046CiogICAgICAgU2V0IFA1X2Nsb2NrIHRvIHRoZSBTY3JhdGNoIGFuZCBNaXNjIENvbnRyb2wgcmVnaXN0ZXIgPFA1X0Nsb2NrIHBhZD4uCioKKiBJTlBVVFM6CiogICAgICAgIHpwciAtIFpQUiBmb3IgUDVfQ2xvY2sKKiAgICAgICAgem5yIC0gWk5SIGZvciBQNV9DbG9jawoqCiogT1VUUFVUUzoKKiAgICAgICAgTm9uZS4KKgoqIFJFVFVSTlM6CiogICAgICAgIEdUX09LICAgICAgLSBvbiBzdWNjZXNzCiogICAgICAgIEdUX0ZBSUwgICAgLSBvbiBlcnJvcgoqICAgICAgICBHVF9CQURfUEFSQU0gLSBpZiBpbnB1dCBwYXJhbWV0ZXJzIGFyZSBiZXlvbmQgcmFuZ2UuCiogICAgICAgIEdUX05PVF9TVVBQT1JURUQgLSBpZiBjdXJyZW50IGRldmljZSBkb2VzIG5vdCBzdXBwb3J0IHRoaXMgZmVhdHVyZS4KKgoqIENPTU1FTlRTOgoqICAgICAgICBOb25lCioKKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KR1RfU1RBVFVTIGdzeXNTZXRQNV9DbG9jawooCiAgICBJTiAgR1RfUURfREVWICAgICAgICAgKmRldiwKICAgIElOICBHVF9VOCAgICAgICAgICAgIHpwciwKICAgIElOICBHVF9VOCAgICAgICAgICAgIHpucgopCnsKICAgIEdUX1NUQVRVUyAgICByZXRWYWw7ICAgICAgICAgLyogRnVuY3Rpb25zIHJldHVybiB2YWx1ZS4gICAgICAqLwogICAgR1RfVTggICAgICAgIGRhdGE7CgogICAgREJHX0lORk8oKCJnc3lzU2V0UDVfQ2xvY2sgQ2FsbGVkLlxuIikpOwoKICAgIC8qIENoZWNrIGlmIFN3aXRjaCBzdXBwb3J0cyB0aGlzIGZlYXR1cmUuICovCiAgICBpZiAoIUlTX0lOX0RFVl9HUk9VUChkZXYsREVWX1NDUkFUQ0hfTUlTQ19DVFJMKSkKICAgIHsKICAgICAgICBEQkdfSU5GTygoIkdUX05PVF9TVVBQT1JURURcbiIpKTsKICAgICAgICByZXR1cm4gR1RfTk9UX1NVUFBPUlRFRDsKICAgIH0KCiAgICBpZiAoKHpwcj4weDcpIHx8ICh6bnI+MHg3KSkKICAgIHsKICAgICAgICBEQkdfSU5GTygoIkdUX0JBRF9QQVJBTVxuIikpOwogICAgICAgIHJldHVybiBHVF9CQURfUEFSQU07CiAgICB9CgogICAgZGF0YSA9ICgoenByJjB4Nyk8PDMpIHwgKHpuciYweDcpOwoKICAgIHJldFZhbCA9IGdzeXNTZXRTY3JhdGNoTWlzY0N0cmwoZGV2LCBHVF9TQ1JBVF9NSVNDX1JFR19QNV9DTEssIGRhdGEpOwogICAgaWYocmV0VmFsICE9IEdUX09LKQogICAgICAgewogICAgICAgICAgIERCR19JTkZPKCgiRmFpbGVkLlxuIikpOwogICAgICAgICAgIHJldHVybiByZXRWYWw7CiAgICB9CgogICAgcmV0dXJuIEdUX09LOwoKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKKiBnc3lzR2V0UDVfQ2xvY2sKKgoqIERFU0NSSVBUSU9OOgoqICAgICAgIEdldCBQNV9jbG9jayBmcm9tIHRoZSBTY3JhdGNoIGFuZCBNaXNjIENvbnRyb2wgcmVnaXN0ZXIgPFA1X0Nsb2NrIHBhZD4uCioKKiBJTlBVVFM6CiogICAgICAgIE5vbmUuCioKKiBPVVRQVVRTOgoqICAgICAgICB6cHIgLSBaUFIgZm9yIFA1X0Nsb2NrCiogICAgICAgIHpuciAtIFpOUiBmb3IgUDVfQ2xvY2sKKgoqIFJFVFVSTlM6CiogICAgICAgIEdUX09LICAgICAgLSBvbiBzdWNjZXNzCiogICAgICAgIEdUX0ZBSUwgICAgLSBvbiBlcnJvcgoqICAgICAgICBHVF9CQURfUEFSQU0gLSBpZiBpbnB1dCBwYXJhbWV0ZXJzIGFyZSBiZXlvbmQgcmFuZ2UuCiogICAgICAgIEdUX05PVF9TVVBQT1JURUQgLSBpZiBjdXJyZW50IGRldmljZSBkb2VzIG5vdCBzdXBwb3J0IHRoaXMgZmVhdHVyZS4KKgoqIENPTU1FTlRTOgoqICAgICAgICBOb25lCioKKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KR1RfU1RBVFVTIGdzeXNHZXRQNV9DbG9jawooCiAgICBJTiAgR1RfUURfREVWICAgICAgICAgKmRldiwKICAgIE9VVCAgR1RfVTggICAgICAgICAgICAqenByLAogICAgT1VUICBHVF9VOCAgICAgICAgICAgICp6bnIKKQp7CiAgICBHVF9TVEFUVVMgICAgcmV0VmFsOyAgICAgICAgIC8qIEZ1bmN0aW9ucyByZXR1cm4gdmFsdWUuICAgICAgKi8KICAgIEdUX1U4ICAgICAgICBkYXRhOwoKICAgIERCR19JTkZPKCgiZ3N5c0dldFA2X0Nsb2NrIENhbGxlZC5cbiIpKTsKCiAgICAvKiBDaGVjayBpZiBTd2l0Y2ggc3VwcG9ydHMgdGhpcyBmZWF0dXJlLiAqLwogICAgaWYgKCFJU19JTl9ERVZfR1JPVVAoZGV2LERFVl9TQ1JBVENIX01JU0NfQ1RSTCkpCiAgICB7CiAgICAgICAgREJHX0lORk8oKCJHVF9OT1RfU1VQUE9SVEVEXG4iKSk7CiAgICAgICAgcmV0dXJuIEdUX05PVF9TVVBQT1JURUQ7CiAgICB9CgogICAgcmV0VmFsID0gZ3N5c0dldFNjcmF0Y2hNaXNjQ3RybChkZXYsIEdUX1NDUkFUX01JU0NfUkVHX1A1X0NMSywgJmRhdGEpOwogICAgaWYocmV0VmFsICE9IEdUX09LKQogICAgICAgewogICAgICAgICAgIERCR19JTkZPKCgiRmFpbGVkLlxuIikpOwogICAgICAgICAgIHJldHVybiByZXRWYWw7CiAgICB9CgogICAgKnpwciA9IDB4NyAmKGRhdGE+PjMpOwogICAgKnpuciA9IDB4NyAmKGRhdGEpOwoKICAgIHJldHVybiBHVF9PSzsKCn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgoqIGdzeXNTZXRFRVBST00KKgoqIERFU0NSSVBUSU9OOgoqICAgICAgIFNldCBFRVBST00gY3ljbGUgdG8gdGhlIFNjcmF0Y2ggYW5kIE1pc2MgQ29udHJvbCByZWdpc3RlciA8RUVQUk9NIHBhZD4uCioKKiBJTlBVVFM6CiogICAgICAgIGRzbSAtIERTTSBmb3IgRUVQUk9NIGN5Y2xlCiogICAgICAgIHpwciAtIFpQUiBmb3IgRUVQUk9NIGN5Y2xlCiogICAgICAgIHpuciAtIFpOUiBmb3IgRUVQUk9NIGN5Y2xlCioKKiBPVVRQVVRTOgoqICAgICAgICBOb25lLgoqCiogUkVUVVJOUzoKKiAgICAgICAgR1RfT0sgICAgICAtIG9uIHN1Y2Nlc3MKKiAgICAgICAgR1RfRkFJTCAgICAtIG9uIGVycm9yCiogICAgICAgIEdUX0JBRF9QQVJBTSAtIGlmIGlucHV0IHBhcmFtZXRlcnMgYXJlIGJleW9uZCByYW5nZS4KKiAgICAgICAgR1RfTk9UX1NVUFBPUlRFRCAtIGlmIGN1cnJlbnQgZGV2aWNlIGRvZXMgbm90IHN1cHBvcnQgdGhpcyBmZWF0dXJlLgoqCiogQ09NTUVOVFM6CiogICAgICAgIE5vbmUKKgoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwpHVF9TVEFUVVMgZ3N5c1NldEVFUFJPTQooCiAgICBJTiAgR1RfUURfREVWICAgICAgICAgKmRldiwKICAgIElOICBHVF9VOCAgICAgICAgICAgIGRzbSwKICAgIElOICBHVF9VOCAgICAgICAgICAgIHpwciwKICAgIElOICBHVF9VOCAgICAgICAgICAgIHpucgopCnsKICAgIEdUX1NUQVRVUyAgICByZXRWYWw7ICAgICAgICAgLyogRnVuY3Rpb25zIHJldHVybiB2YWx1ZS4gICAgICAqLwogICAgR1RfVTggICAgICAgIGRhdGE7CgogICAgREJHX0lORk8oKCJnc3lzU2V0RUVQUk9NIENhbGxlZC5cbiIpKTsKCiAgICAvKiBDaGVjayBpZiBTd2l0Y2ggc3VwcG9ydHMgdGhpcyBmZWF0dXJlLiAqLwogICAgaWYgKCFJU19JTl9ERVZfR1JPVVAoZGV2LERFVl9TQ1JBVENIX01JU0NfQ1RSTCkpCiAgICB7CiAgICAgICAgREJHX0lORk8oKCJHVF9OT1RfU1VQUE9SVEVEXG4iKSk7CiAgICAgICAgcmV0dXJuIEdUX05PVF9TVVBQT1JURUQ7CiAgICB9CgogICAgaWYgKCh6cHI+MHg3KSB8fCAoem5yPjB4NykpCiAgICB7CiAgICAgICAgREJHX0lORk8oKCJHVF9CQURfUEFSQU1cbiIpKTsKICAgICAgICByZXR1cm4gR1RfQkFEX1BBUkFNOwogICAgfQoKICAgIGRhdGEgPSAoKGRzbSYweDMpPDw2KSB8ICgoenByJjB4Nyk8PDMpIHwgKHpuciYweDcpOwoKICAgIHJldFZhbCA9IGdzeXNTZXRTY3JhdGNoTWlzY0N0cmwoZGV2LCBHVF9TQ1JBVF9NSVNDX1JFR19FRVBST00sIGRhdGEpOwogICAgaWYocmV0VmFsICE9IEdUX09LKQogICAgICAgewogICAgICAgICAgIERCR19JTkZPKCgiRmFpbGVkLlxuIikpOwogICAgICAgICAgIHJldHVybiByZXRWYWw7CiAgICB9CgogICAgcmV0dXJuIEdUX09LOwoKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKKiBnc3lzR2V0RUVQUk9NCioKKiBERVNDUklQVElPTjoKKiAgICAgICBHZXQgRUVQUk9NIGN5Y2xlIHRvIHRoZSBTY3JhdGNoIGFuZCBNaXNjIENvbnRyb2wgcmVnaXN0ZXIgPEVFUFJPTSBwYWQ+LgoqCiogSU5QVVRTOgoqICAgICAgICBOb25lLgoqCiogT1VUUFVUUzoKKiAgICAgICAgZHNtIC0gRFNNIGZvciBFRVBST00gY3ljbGUKKiAgICAgICAgenByIC0gWlBSIGZvciBFRVBST00gY3ljbGUKKiAgICAgICAgem5yIC0gWk5SIGZvciBFRVBST00gY3ljbGUKKgoqIFJFVFVSTlM6CiogICAgICAgIEdUX09LICAgICAgLSBvbiBzdWNjZXNzCiogICAgICAgIEdUX0ZBSUwgICAgLSBvbiBlcnJvcgoqICAgICAgICBHVF9CQURfUEFSQU0gLSBpZiBpbnB1dCBwYXJhbWV0ZXJzIGFyZSBiZXlvbmQgcmFuZ2UuCiogICAgICAgIEdUX05PVF9TVVBQT1JURUQgLSBpZiBjdXJyZW50IGRldmljZSBkb2VzIG5vdCBzdXBwb3J0IHRoaXMgZmVhdHVyZS4KKgoqIENPTU1FTlRTOgoqICAgICAgICBOb25lCioKKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KR1RfU1RBVFVTIGdzeXNHZXRFRVBST00KKAogICAgSU4gIEdUX1FEX0RFViAgICAgICAgICpkZXYsCiAgICBPVVQgIEdUX1U4ICAgICAgICAgICAgKmRzbSwKICAgIE9VVCAgR1RfVTggICAgICAgICAgICAqenByLAogICAgT1VUICBHVF9VOCAgICAgICAgICAgICp6bnIKKQp7CiAgICBHVF9TVEFUVVMgICAgcmV0VmFsOyAgICAgICAgIC8qIEZ1bmN0aW9ucyByZXR1cm4gdmFsdWUuICAgICAgKi8KICAgIEdUX1U4ICAgICAgICBkYXRhOwoKICAgIERCR19JTkZPKCgiZ3N5c0dldEVFUFJPTSBDYWxsZWQuXG4iKSk7CgogICAgLyogQ2hlY2sgaWYgU3dpdGNoIHN1cHBvcnRzIHRoaXMgZmVhdHVyZS4gKi8KICAgIGlmICghSVNfSU5fREVWX0dST1VQKGRldixERVZfU0NSQVRDSF9NSVNDX0NUUkwpKQogICAgewogICAgICAgIERCR19JTkZPKCgiR1RfTk9UX1NVUFBPUlRFRFxuIikpOwogICAgICAgIHJldHVybiBHVF9OT1RfU1VQUE9SVEVEOwogICAgfQoKICAgIHJldFZhbCA9IGdzeXNHZXRTY3JhdGNoTWlzY0N0cmwoZGV2LCBHVF9TQ1JBVF9NSVNDX1JFR19FRVBST00sICZkYXRhKTsKICAgIGlmKHJldFZhbCAhPSBHVF9PSykKICAgICAgIHsKICAgICAgICAgICBEQkdfSU5GTygoIkZhaWxlZC5cbiIpKTsKICAgICAgICAgICByZXR1cm4gcmV0VmFsOwogICAgfQoKICAgICpkc20gPSAweDMgJihkYXRhPj42KTsKICAgICp6cHIgPSAweDcgJihkYXRhPj4zKTsKICAgICp6bnIgPSAweDcgJihkYXRhKTsKCiAgICByZXR1cm4gR1RfT0s7Cgp9Cg==