LyoKICogKEMpIENvcHlyaWdodCAyMDAyCiAqIERhbmllbCBFbmdzdHL2bSwgT21pY3JvbiBDZXRpIEFCLCBkYW5pZWxAb21pY3Jvbi5zZQogKgogKiAoQykgQ29weXJpZ2h0IDIwMDIKICogU3lzZ28gUmVhbC1UaW1lIFNvbHV0aW9ucywgR21iSCA8d3d3LmVsaW5vcy5jb20+CiAqIEFsZXggWnVlcGtlIDxhenVAc3lzZ28uZGU+CiAqCiAqIFNlZSBmaWxlIENSRURJVFMgZm9yIGxpc3Qgb2YgcGVvcGxlIHdobyBjb250cmlidXRlZCB0byB0aGlzCiAqIHByb2plY3QuCiAqCiAqIFRoaXMgcHJvZ3JhbSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IKICogbW9kaWZ5IGl0IHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgYXMKICogcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb247IGVpdGhlciB2ZXJzaW9uIDIgb2YKICogdGhlIExpY2Vuc2UsIG9yIChhdCB5b3VyIG9wdGlvbikgYW55IGxhdGVyIHZlcnNpb24uCiAqCiAqIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLAogKiBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZgogKiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlCiAqIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGZvciBtb3JlIGRldGFpbHMuCiAqCiAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlCiAqIGFsb25nIHdpdGggdGhpcyBwcm9ncmFtOyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlCiAqIEZvdW5kYXRpb24sIEluYy4sIDU5IFRlbXBsZSBQbGFjZSwgU3VpdGUgMzMwLCBCb3N0b24sCiAqIE1BIDAyMTExLTEzMDcgVVNBCiAqLwoKI2luY2x1ZGUgPGNvbW1vbi5oPgojaW5jbHVkZSA8YXNtL2lvLmg+Cgp1bG9uZyBteWZsdXNoKHZvaWQpOwoKCiNkZWZpbmUgU0M1MjBfTUFYX0ZMQVNIX0JBTktTICAzCiNkZWZpbmUgU0M1MjBfRkxBU0hfQkFOSzBfQkFTRSAweDM4MDAwMDAwICAvKiBCT09UQ1MgKi8KI2RlZmluZSBTQzUyMF9GTEFTSF9CQU5LMV9CQVNFIDB4MzAwMDAwMDAgIC8qIFJPTUNTMCAqLwojZGVmaW5lIFNDNTIwX0ZMQVNIX0JBTksyX0JBU0UgMHgyODAwMDAwMCAgLyogUk9NQ1MxICovCiNkZWZpbmUgU0M1MjBfRkxBU0hfQkFOS1NJWkUgICAweDgwMDAwMDAKCiNkZWZpbmUgQU1EMjlMVjAxNl9TSVpFICAgICAgICAweDIwMDAwMAojZGVmaW5lIEFNRDI5TFYwMTZfU0VDVE9SUyAgICAgMzIKCmZsYXNoX2luZm9fdCAgICBmbGFzaF9pbmZvW1NDNTIwX01BWF9GTEFTSF9CQU5LU107CgojZGVmaW5lIENNRF9SRUFEX0FSUkFZCQkweDAwRjAwMEYwCiNkZWZpbmUgQ01EX1VOTE9DSzEJCTB4MDBBQTAwQUEKI2RlZmluZSBDTURfVU5MT0NLMgkJMHgwMDU1MDA1NQojZGVmaW5lIENNRF9FUkFTRV9TRVRVUAkJMHgwMDgwMDA4MAojZGVmaW5lIENNRF9FUkFTRV9DT05GSVJNCTB4MDAzMDAwMzAKI2RlZmluZSBDTURfUFJPR1JBTQkJMHgwMEEwMDBBMAojZGVmaW5lIENNRF9VTkxPQ0tfQllQQVNTCTB4MDAyMDAwMjAKCgojZGVmaW5lIEJJVF9FUkFTRV9ET05FCQkweDAwODAwMDgwCiNkZWZpbmUgQklUX1JEWV9NQVNLCQkweDAwODAwMDgwCiNkZWZpbmUgQklUX1BST0dSQU1fRVJST1IJMHgwMDIwMDAyMAojZGVmaW5lIEJJVF9USU1FT1VUCQkweDgwMDAwMDAwIC8qIG91ciBmbGFnICovCgojZGVmaW5lIFJFQURZIDEKI2RlZmluZSBFUlIgICAyCiNkZWZpbmUgVE1PICAgNAoKLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQogKi8KCnVsb25nIGZsYXNoX2luaXQodm9pZCkKewoJaW50IGksIGo7Cgl1bG9uZyBzaXplID0gMDsKCglmb3IgKGkgPSAwOyBpIDwgU0M1MjBfTUFYX0ZMQVNIX0JBTktTOyBpKyspIHsKCQl1bG9uZyBmbGFzaGJhc2UgPSAwOwoJCWludCBzZWN0c2l6ZSA9IDA7CgkJaWYgKGk9PTAgfHwgaT09MikgewoJCQkvKiBGaXhNZTogdGhpcyBhc3N1bWVzIHRoYXQgYmFuayAwIGFuZCAyCgkJCSAqIGFyZSBtYXBwZWQgdG8gdGhlIHR3byA4TWIgYmFua3MgKi8KCQkJZmxhc2hfaW5mb1tpXS5mbGFzaF9pZCA9CgkJCQkoQU1EX01BTlVGQUNUICYgRkxBU0hfVkVORE1BU0spIHwKCQkJCShBTURfSURfTFYwMTZCICYgRkxBU0hfVFlQRU1BU0spOwoKCQkJZmxhc2hfaW5mb1tpXS5zaXplID0gQU1EMjlMVjAxNl9TSVpFKjQ7CgkJCWZsYXNoX2luZm9baV0uc2VjdG9yX2NvdW50ID0gQU1EMjlMVjAxNl9TRUNUT1JTOwoJCQlzZWN0c2l6ZSA9IChBTUQyOUxWMDE2X1NJWkUqNCkvQU1EMjlMVjAxNl9TRUNUT1JTOwoJCX0gZWxzZSB7CgkJCS8qIEZpeE1lOiB0aGlzIGFzc3VtZXMgdGhhdCBiYW5rMSBpcyB1bm1hcHBlZAoJCQkgKiAob3IgbWFwcGVkIHRvIHRoZSBzYW1lIGZsYXNoIGJhbmsgYXMgQk9PVENTKSAqLwoJCQlmbGFzaF9pbmZvW2ldLmZsYXNoX2lkID0gMDsKCQkJZmxhc2hfaW5mb1tpXS5zaXplID0gMDsKCQkJZmxhc2hfaW5mb1tpXS5zZWN0b3JfY291bnQgPSAwOwoJCQlzZWN0c2l6ZT0wOwoJCX0KCQltZW1zZXQoZmxhc2hfaW5mb1tpXS5wcm90ZWN0LCAwLCBDRkdfTUFYX0ZMQVNIX1NFQ1QpOwoJCXN3aXRjaCAoaSkgewoJCWNhc2UgMDoKCQkJZmxhc2hiYXNlID0gU0M1MjBfRkxBU0hfQkFOSzBfQkFTRTsKCQkJYnJlYWs7CgkJY2FzZSAxOgoJCQlmbGFzaGJhc2UgPSBTQzUyMF9GTEFTSF9CQU5LMV9CQVNFOwoJCQlicmVhazsKCQljYXNlIDI6CgkJCWZsYXNoYmFzZSA9IFNDNTIwX0ZMQVNIX0JBTkswX0JBU0U7CgkJCWJyZWFrOwoJCWRlZmF1bHQ6CgkJCXBhbmljKCJjb25maWd1cmVkIHRvbyBtYW55IGZsYXNoIGJhbmtzIVxuIik7CgkJfQoKCQlmb3IgKGogPSAwOyBqIDwgZmxhc2hfaW5mb1tpXS5zZWN0b3JfY291bnQ7IGorKykgewoJCQlmbGFzaF9pbmZvW2ldLnN0YXJ0W2pdID0gc2VjdHNpemU7CgkJCWZsYXNoX2luZm9baV0uc3RhcnRbal0gPSBmbGFzaGJhc2UgKyBqICogc2VjdHNpemU7CgkJfQoJCXNpemUgKz0gZmxhc2hfaW5mb1tpXS5zaXplOwoJfQoKCS8qCgkgKiBQcm90ZWN0IG1vbml0b3IgYW5kIGVudmlyb25tZW50IHNlY3RvcnMKCSAqLwoJZmxhc2hfcHJvdGVjdChGTEFHX1BST1RFQ1RfU0VULAoJCSAgICAgIGkzODZib290X3N0YXJ0LVNDNTIwX0ZMQVNIX0JBTkswX0JBU0UsCgkJICAgICAgaTM4NmJvb3RfZW5kLVNDNTIwX0ZMQVNIX0JBTkswX0JBU0UsCgkJICAgICAgJmZsYXNoX2luZm9bMF0pOwoKI2lmZGVmIENGR19FTlZfQUREUgoJZmxhc2hfcHJvdGVjdChGTEFHX1BST1RFQ1RfU0VULAoJCSAgICAgIENGR19FTlZfQUREUiwKCQkgICAgICBDRkdfRU5WX0FERFIgKyBDRkdfRU5WX1NJWkUgLSAxLAoJCSAgICAgICZmbGFzaF9pbmZvWzBdKTsKI2VuZGlmCglyZXR1cm4gc2l6ZTsKfQoKLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQogKi8Kdm9pZCBmbGFzaF9wcmludF9pbmZvKGZsYXNoX2luZm9fdCAqaW5mbykKewoJaW50IGk7CgoJc3dpdGNoIChpbmZvLT5mbGFzaF9pZCAmIEZMQVNIX1ZFTkRNQVNLKSB7CgljYXNlIChBTURfTUFOVUZBQ1QgJiBGTEFTSF9WRU5ETUFTSyk6CgkJcHJpbnRmKCJBTUQ6ICIpOwoJCWJyZWFrOwoJZGVmYXVsdDoKCQlwcmludGYoIlVua25vd24gVmVuZG9yICIpOwoJCWJyZWFrOwoJfQoKCXN3aXRjaCAoaW5mby0+Zmxhc2hfaWQgJiBGTEFTSF9UWVBFTUFTSykgewoJY2FzZSAoQU1EX0lEX0xWMDE2QiAmIEZMQVNIX1RZUEVNQVNLKToKCQlwcmludGYoIjR4IEFtZDI5TFYwMTZCICgxNk1iaXQpXG4iKTsKCQlicmVhazsKCWRlZmF1bHQ6CgkJcHJpbnRmKCJVbmtub3duIENoaXAgVHlwZVxuIik7CgkJZ290byBkb25lOwoJCWJyZWFrOwoJfQoKCXByaW50ZigiICBTaXplOiAlbGQgTUIgaW4gJWQgU2VjdG9yc1xuIiwKCSAgICAgICBpbmZvLT5zaXplID4+IDIwLCBpbmZvLT5zZWN0b3JfY291bnQpOwoKCXByaW50ZigiICBTZWN0b3IgU3RhcnQgQWRkcmVzc2VzOiIpOwoJZm9yIChpID0gMDsgaSA8IGluZm8tPnNlY3Rvcl9jb3VudDsgaSsrKSB7CgkJaWYgKChpICUgNSkgPT0gMCkgewoJCQlwcmludGYgKCJcbiAgICIpOwoJCX0KCQlwcmludGYgKCIgJTA4bFglcyIsIGluZm8tPnN0YXJ0W2ldLAoJCQlpbmZvLT5wcm90ZWN0W2ldID8gIiAoUk8pIiA6ICIgICAgICIpOwoJfQoJcHJpbnRmICgiXG4iKTsKCglkb25lOgp9CgovKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiAqLwoKaW50IGZsYXNoX2VyYXNlKGZsYXNoX2luZm9fdCAqaW5mbywgaW50IHNfZmlyc3QsIGludCBzX2xhc3QpCnsKCXVsb25nIHJlc3VsdDsKCWludCBpZmxhZywgcHJvdCwgc2VjdDsKCWludCByYyA9IEVSUl9PSzsKCWludCBjaGlwMSwgY2hpcDI7CgoJLyogZmlyc3QgbG9vayBmb3IgcHJvdGVjdGlvbiBiaXRzICovCgoJaWYgKGluZm8tPmZsYXNoX2lkID09IEZMQVNIX1VOS05PV04pIHsKCQlyZXR1cm4gRVJSX1VOS05PV05fRkxBU0hfVFlQRTsKCX0KCglpZiAoKHNfZmlyc3QgPCAwKSB8fCAoc19maXJzdCA+IHNfbGFzdCkpIHsKCQlyZXR1cm4gRVJSX0lOVkFMOwoJfQoKCWlmICgoaW5mby0+Zmxhc2hfaWQgJiBGTEFTSF9WRU5ETUFTSykgIT0KCSAgICAoQU1EX01BTlVGQUNUICYgRkxBU0hfVkVORE1BU0spKSB7CgkJcmV0dXJuIEVSUl9VTktOT1dOX0ZMQVNIX1ZFTkRPUjsKCX0KCglwcm90ID0gMDsKCWZvciAoc2VjdD1zX2ZpcnN0OyBzZWN0PD1zX2xhc3Q7ICsrc2VjdCkgewoJCWlmIChpbmZvLT5wcm90ZWN0W3NlY3RdKSB7CgkJCXByb3QrKzsKCQl9Cgl9CglpZiAocHJvdCkgewoJCXJldHVybiBFUlJfUFJPVEVDVEVEOwoJfQoKCS8qCgkgKiBEaXNhYmxlIGludGVycnVwdHMgd2hpY2ggbWlnaHQgY2F1c2UgYSB0aW1lb3V0CgkgKiBoZXJlLiBSZW1lbWJlciB0aGF0IG91ciBleGNlcHRpb24gdmVjdG9ycyBhcmUKCSAqIGF0IGFkZHJlc3MgMCBpbiB0aGUgZmxhc2gsIGFuZCB3ZSBkb24ndCB3YW50IGEKCSAqICh0aWNrZXIpIGV4Y2VwdGlvbiB0byBoYXBwZW4gd2hpbGUgdGhlIGZsYXNoCgkgKiBjaGlwIGlzIGluIHByb2dyYW1taW5nIG1vZGUuCgkgKi8KCWlmbGFnID0gZGlzYWJsZV9pbnRlcnJ1cHRzKCk7CgoJLyogU3RhcnQgZXJhc2Ugb24gdW5wcm90ZWN0ZWQgc2VjdG9ycyAqLwoJZm9yIChzZWN0ID0gc19maXJzdDsgc2VjdDw9c19sYXN0ICYmICFjdHJsYygpOyBzZWN0KyspIHsKCQlwcmludGYoIkVyYXNpbmcgc2VjdG9yICUyZCAuLi4gIiwgc2VjdCk7CgoJCS8qIGFybSBzaW1wbGUsIG5vbiBpbnRlcnJ1cHQgZGVwZW5kZW50IHRpbWVyICovCgkJcmVzZXRfdGltZXIoKTsKCgkJaWYgKGluZm8tPnByb3RlY3Rbc2VjdF0gPT0gMCkgewoJCQkvKiBub3QgcHJvdGVjdGVkICovCgkJCXVsb25nIGFkZHIgPSBpbmZvLT5zdGFydFtzZWN0XTsKCgkJCXdyaXRlbChDTURfVU5MT0NLMSwgYWRkciArIDEpOwoJCQl3cml0ZWwoQ01EX1VOTE9DSzIsIGFkZHIgKyAyKTsKCQkJd3JpdGVsKENNRF9FUkFTRV9TRVRVUCwgYWRkciArIDEpOwoKCQkJd3JpdGVsKENNRF9VTkxPQ0sxLCBhZGRyICsgMSk7CgkJCXdyaXRlbChDTURfVU5MT0NLMiwgYWRkciArIDIpOwoJCQl3cml0ZWwoQ01EX0VSQVNFX0NPTkZJUk0sIGFkZHIpOwoKCgkJCS8qIHdhaXQgdW50aWwgZmxhc2ggaXMgcmVhZHkgKi8KCQkJY2hpcDEgPSBjaGlwMiA9IDA7CgoJCQlkbyB7CgkJCQlyZXN1bHQgPSByZWFkbChhZGRyKTsKCgkJCQkvKiBjaGVjayB0aW1lb3V0ICovCgkJCQlpZiAoZ2V0X3RpbWVyKDApID4gQ0ZHX0ZMQVNIX0VSQVNFX1RPVVQpIHsKCQkJCQl3cml0ZWwoQ01EX1JFQURfQVJSQVksIGFkZHIgKyAxKTsKCQkJCQljaGlwMSA9IFRNTzsKCQkJCQlicmVhazsKCQkJCX0KCgkJCQlpZiAoIWNoaXAxICYmIChyZXN1bHQgJiAweEZGRkYpICYgQklUX0VSQVNFX0RPTkUpIHsKCQkJCQljaGlwMSA9IFJFQURZOwoJCQkJfQoKCQkJCWlmICghY2hpcDEgJiYgKHJlc3VsdCAmIDB4RkZGRikgJiBCSVRfUFJPR1JBTV9FUlJPUikgewoJCQkJCWNoaXAxID0gRVJSOwoJCQkJfQoKCQkJCWlmICghY2hpcDIgJiYgKHJlc3VsdCA+PiAxNikgJiBCSVRfRVJBU0VfRE9ORSkgewoJCQkJCWNoaXAyID0gUkVBRFk7CgkJCQl9CgoJCQkJaWYgKCFjaGlwMiAmJiAocmVzdWx0ID4+IDE2KSAmIEJJVF9QUk9HUkFNX0VSUk9SKSB7CgkJCQkJY2hpcDIgPSBFUlI7CgkJCQl9CgoJCQl9ICB3aGlsZSAoIWNoaXAxIHx8ICFjaGlwMik7CgoJCQl3cml0ZWwoQ01EX1JFQURfQVJSQVksIGFkZHIgKyAxKTsKCgkJCWlmIChjaGlwMSA9PSBFUlIgfHwgY2hpcDIgPT0gRVJSKSB7CgkJCQlyYyA9IEVSUl9QUk9HX0VSUk9SOwoJCQkJZ290byBvdXRhaGVyZTsKCQkJfQoKCQkJaWYgKGNoaXAxID09IFRNTykgewoJCQkJcmMgPSBFUlJfVElNT1VUOwoJCQkJZ290byBvdXRhaGVyZTsKCQkJfQoKCQkJcHJpbnRmKCJvay5cbiIpOwoJCX0gZWxzZSB7IC8qIGl0IHdhcyBwcm90ZWN0ZWQgKi8KCgkJCXByaW50ZigicHJvdGVjdGVkIVxuIik7CgkJfQoJfQoKCWlmIChjdHJsYygpKSB7CgkJcHJpbnRmKCJVc2VyIEludGVycnVwdCFcbiIpOwoJfQoKb3V0YWhlcmU6CgkvKiBhbGxvdyBmbGFzaCB0byBzZXR0bGUgLSB3YWl0IDEwIG1zICovCgl1ZGVsYXkoMTAwMDApOwoKCWlmIChpZmxhZykgewoJCWVuYWJsZV9pbnRlcnJ1cHRzKCk7Cgl9CgoJcmV0dXJuIHJjOwp9CgovKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiAqIENvcHkgbWVtb3J5IHRvIGZsYXNoCiAqLwoKdm9sYXRpbGUgc3RhdGljIGludCB3cml0ZV93b3JkKGZsYXNoX2luZm9fdCAqaW5mbywgdWxvbmcgZGVzdCwgdWxvbmcgZGF0YSkKewoJdWxvbmcgYWRkciA9IGRlc3Q7Cgl1bG9uZyByZXN1bHQ7CglpbnQgcmMgPSBFUlJfT0s7CglpbnQgaWZsYWc7CglpbnQgY2hpcDEsIGNoaXAyOwoKCS8qCgkgKiBDaGVjayBpZiBGbGFzaCBpcyAoc3VmZmljaWVudGx5KSBlcmFzZWQKCSAqLwoJcmVzdWx0ID0gcmVhZGwoYWRkcik7CglpZiAoKHJlc3VsdCAmIGRhdGEpICE9IGRhdGEpIHsKCQlyZXR1cm4gRVJSX05PVF9FUkFTRUQ7Cgl9CgoJLyoKCSAqIERpc2FibGUgaW50ZXJydXB0cyB3aGljaCBtaWdodCBjYXVzZSBhIHRpbWVvdXQKCSAqIGhlcmUuIFJlbWVtYmVyIHRoYXQgb3VyIGV4Y2VwdGlvbiB2ZWN0b3JzIGFyZQoJICogYXQgYWRkcmVzcyAwIGluIHRoZSBmbGFzaCwgYW5kIHdlIGRvbid0IHdhbnQgYQoJICogKHRpY2tlcikgZXhjZXB0aW9uIHRvIGhhcHBlbiB3aGlsZSB0aGUgZmxhc2gKCSAqIGNoaXAgaXMgaW4gcHJvZ3JhbW1pbmcgbW9kZS4KCSAqLwoJaWZsYWcgPSBkaXNhYmxlX2ludGVycnVwdHMoKTsKCgl3cml0ZWwoQ01EX1VOTE9DSzEsIGFkZHIgKyAxKTsKCXdyaXRlbChDTURfVU5MT0NLMiwgYWRkciArIDIpOwoJd3JpdGVsKENNRF9VTkxPQ0tfQllQQVNTLCBhZGRyICsgMSk7Cgl3cml0ZWwoYWRkciwgQ01EX1BST0dSQU0pOwoJd3JpdGVsKGFkZHIsIGRhdGEpOwoKCS8qIGFybSBzaW1wbGUsIG5vbiBpbnRlcnJ1cHQgZGVwZW5kZW50IHRpbWVyICovCglyZXNldF90aW1lcigpOwoKCS8qIHdhaXQgdW50aWwgZmxhc2ggaXMgcmVhZHkgKi8KCWNoaXAxID0gY2hpcDIgPSAwOwoJZG8gewoJCXJlc3VsdCA9IHJlYWRsKGFkZHIpOwoKCQkvKiBjaGVjayB0aW1lb3V0ICovCgkJaWYgKGdldF90aW1lcigwKSA+IENGR19GTEFTSF9FUkFTRV9UT1VUKSB7CgkJCWNoaXAxID0gRVJSIHwgVE1POwoJCQlicmVhazsKCQl9CgoJCWlmICghY2hpcDEgJiYgKChyZXN1bHQgJiAweDgwKSA9PSAoZGF0YSAmIDB4ODApKSkgewoJCQljaGlwMSA9IFJFQURZOwoJCX0KCgkJaWYgKCFjaGlwMSAmJiAoKHJlc3VsdCAmIDB4RkZGRikgJiBCSVRfUFJPR1JBTV9FUlJPUikpIHsKCQkJcmVzdWx0ID0gcmVhZGwoYWRkcik7CgoJCQlpZiAoKHJlc3VsdCAmIDB4ODApID09IChkYXRhICYgMHg4MCkpIHsKCQkJCWNoaXAxID0gUkVBRFk7CgkJCX0gZWxzZSB7CgkJCQljaGlwMSA9IEVSUjsKCQkJfQoJCX0KCgkJaWYgKCFjaGlwMiAmJiAoKHJlc3VsdCAmICgweDgwIDw8IDE2KSkgPT0gKGRhdGEgJiAoMHg4MCA8PCAxNikpKSkgewoJCQljaGlwMiA9IFJFQURZOwoJCX0KCgkJaWYgKCFjaGlwMiAmJiAoKHJlc3VsdCA+PiAxNikgJiBCSVRfUFJPR1JBTV9FUlJPUikpIHsKCQkJcmVzdWx0ID0gcmVhZGwoYWRkcik7CgoJCQlpZiAoKHJlc3VsdCAmICgweDgwIDw8IDE2KSkgPT0gKGRhdGEgJiAoMHg4MCA8PCAxNikpKSB7CgkJCQljaGlwMiA9IFJFQURZOwoJCQl9IGVsc2UgewoJCQkJY2hpcDIgPSBFUlI7CgkJCX0KCQl9CgoJfSAgd2hpbGUgKCFjaGlwMSB8fCAhY2hpcDIpOwoKCXdyaXRlbChDTURfUkVBRF9BUlJBWSwgYWRkcik7CgoJaWYgKGNoaXAxID09IEVSUiB8fCBjaGlwMiA9PSBFUlIgfHwgcmVhZGwoYWRkcikgIT0gZGF0YSkgewoJCXJjID0gRVJSX1BST0dfRVJST1I7Cgl9CgoJaWYgKGlmbGFnKSB7CgkJZW5hYmxlX2ludGVycnVwdHMoKTsKCX0KCglyZXR1cm4gcmM7Cn0KCi8qLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KICogQ29weSBtZW1vcnkgdG8gZmxhc2guCiAqLwoKaW50IHdyaXRlX2J1ZmYoZmxhc2hfaW5mb190ICppbmZvLCB1Y2hhciAqc3JjLCB1bG9uZyBhZGRyLCB1bG9uZyBjbnQpCnsKCXVsb25nIGNwLCB3cCwgZGF0YTsKCWludCBsOwoJaW50IGksIHJjOwoKCXdwID0gKGFkZHIgJiB+Myk7CS8qIGdldCBsb3dlciB3b3JkIGFsaWduZWQgYWRkcmVzcyAqLwoKCS8qCgkgKiBoYW5kbGUgdW5hbGlnbmVkIHN0YXJ0IGJ5dGVzCgkgKi8KCWlmICgobCA9IGFkZHIgLSB3cCkgIT0gMCkgewoJCWRhdGEgPSAwOwoJCWZvciAoaT0wLCBjcD13cDsgaTxsOyArK2ksICsrY3ApIHsKCQkJZGF0YSA9IChkYXRhID4+IDgpIHwgKCoodWNoYXIgKiljcCA8PCAyNCk7CgkJfQoJCWZvciAoOyBpPDQgJiYgY250PjA7ICsraSkgewoJCQlkYXRhID0gKGRhdGEgPj4gOCkgfCAoKnNyYysrIDw8IDI0KTsKCQkJLS1jbnQ7CgkJCSsrY3A7CgkJfQoJCWZvciAoOyBjbnQ9PTAgJiYgaTw0OyArK2ksICsrY3ApIHsKCQkJZGF0YSA9IChkYXRhID4+IDgpIHwgKCoodWNoYXIgKiljcCA8PCAyNCk7CgkJfQoKCQlpZiAoKHJjID0gd3JpdGVfd29yZChpbmZvLCB3cCwgZGF0YSkpICE9IDApIHsKCQkJcmV0dXJuIHJjOwoJCX0KCQl3cCArPSA0OwoJfQoKCS8qCgkgKiBoYW5kbGUgd29yZCBhbGlnbmVkIHBhcnQKCSAqLwoJd2hpbGUgKGNudCA+PSA0KSB7CgkJZGF0YSA9ICooKHZ1X2xvbmcqKXNyYyk7CgkJaWYgKChyYyA9IHdyaXRlX3dvcmQoaW5mbywgd3AsIGRhdGEpKSAhPSAwKSB7CgkJCXJldHVybiByYzsKCQl9CgkJc3JjICs9IDQ7CgkJd3AgICs9IDQ7CgkJY250IC09IDQ7Cgl9CgoJaWYgKGNudCA9PSAwKSB7CgkJcmV0dXJuIEVSUl9PSzsKCX0KCgkvKgoJICogaGFuZGxlIHVuYWxpZ25lZCB0YWlsIGJ5dGVzCgkgKi8KCWRhdGEgPSAwOwoJZm9yIChpPTAsIGNwPXdwOyBpPDQgJiYgY250PjA7ICsraSwgKytjcCkgewoJCWRhdGEgPSAoZGF0YSA+PiA4KSB8ICgqc3JjKysgPDwgMjQpOwoJCS0tY250OwoJfQoJZm9yICg7IGk8NDsgKytpLCArK2NwKSB7CgkJZGF0YSA9IChkYXRhID4+IDgpIHwgKCoodWNoYXIgKiljcCA8PCAyNCk7Cgl9CgoJcmV0dXJuIHdyaXRlX3dvcmQoaW5mbywgd3AsIGRhdGEpOwp9Cg==