LyoKICogKEMpIENvcHlyaWdodCAyMDAyLCAyMDAzCiAqIERhbmllbCBFbmdzdHL2bSwgT21pY3JvbiBDZXRpIEFCLCBkYW5pZWxAb21pY3Jvbi5zZQogKiAKICogKEMpIENvcHlyaWdodCAyMDAyCiAqIFN5c2dvIFJlYWwtVGltZSBTb2x1dGlvbnMsIEdtYkggPHd3dy5lbGlub3MuY29tPgogKiBBbGV4IFp1ZXBrZSA8YXp1QHN5c2dvLmRlPgogKgogKiBTZWUgZmlsZSBDUkVESVRTIGZvciBsaXN0IG9mIHBlb3BsZSB3aG8gY29udHJpYnV0ZWQgdG8gdGhpcwogKiBwcm9qZWN0LgogKgogKiBUaGlzIHByb2dyYW0gaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yCiAqIG1vZGlmeSBpdCB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGFzCiAqIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uOyBlaXRoZXIgdmVyc2lvbiAyIG9mCiAqIHRoZSBMaWNlbnNlLCBvciAoYXQgeW91ciBvcHRpb24pIGFueSBsYXRlciB2ZXJzaW9uLgogKgogKiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwKICogYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YKICogTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZQogKiBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBmb3IgbW9yZSBkZXRhaWxzLgogKgogKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZQogKiBhbG9uZyB3aXRoIHRoaXMgcHJvZ3JhbTsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZQogKiBGb3VuZGF0aW9uLCBJbmMuLCA1OSBUZW1wbGUgUGxhY2UsIFN1aXRlIDMzMCwgQm9zdG9uLAogKiBNQSAwMjExMS0xMzA3IFVTQQogKi8KCiNpbmNsdWRlIDxjb21tb24uaD4KI2luY2x1ZGUgPGFzbS9pby5oPgojaW5jbHVkZSA8cGNpLmg+CiNpbmNsdWRlIDxhc20vaWMvc2M1MjAuaD4KCiNkZWZpbmUgUFJPQkVfQlVGRkVSX1NJWkUgMTAyNApzdGF0aWMgdW5zaWduZWQgY2hhciBidWZmZXJbUFJPQkVfQlVGRkVSX1NJWkVdOwoKCiNkZWZpbmUgU0M1MjBfTUFYX0ZMQVNIX0JBTktTICAxCiNkZWZpbmUgU0M1MjBfRkxBU0hfQkFOSzBfQkFTRSAweDM4MDAwMDAwICAvKiBCT09UQ1MgKi8KI2RlZmluZSBTQzUyMF9GTEFTSF9CQU5LU0laRSAgIDB4ODAwMDAwMAoKI2RlZmluZSBBMjlMVjY0MURIX1NJWkUgICAgICAgIDB4ODAwMDAwCiNkZWZpbmUgQTI5TFY2NDFESF9TRUNUT1JTICAgICAxMjgKCiNkZWZpbmUgQTI5TFY2NDFNSF9TSVpFICAgICAgICAweDgwMDAwMAojZGVmaW5lIEEyOUxWNjQxTUhfU0VDVE9SUyAgICAgMTI4CgojZGVmaW5lIEkyOEYzMjBKM0FfU0laRSAgICAgICAgMHg0MDAwMDAKI2RlZmluZSBJMjhGMzIwSjNBX1NFQ1RPUlMgICAgIDMyCgojZGVmaW5lIEkyOEY2NDBKM0FfU0laRSAgICAgICAgMHg4MDAwMDAKI2RlZmluZSBJMjhGNjQwSjNBX1NFQ1RPUlMgICAgIDY0CgojZGVmaW5lIEkyOEYxMjhKM0FfU0laRSAgICAgICAgMHgxMDAwMDAwCiNkZWZpbmUgSTI4RjEyOEozQV9TRUNUT1JTICAgICAxMjgKCmZsYXNoX2luZm9fdCAgICBmbGFzaF9pbmZvW1NDNTIwX01BWF9GTEFTSF9CQU5LU107CgojZGVmaW5lIFJFQURZIDEKI2RlZmluZSBFUlIgICAyCiNkZWZpbmUgVE1PICAgNAoKLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQogKi8KCgpzdGF0aWMgdTMyIF9wcm9iZV9mbGFzaCh1MzIgYWRkciwgdTMyIGJ3LCBpbnQgaWwpCnsKCXUzMiByZXN1bHQ9MDsKCQoJLyogRmlyc3QgZG8gYW4gdW5sb2NrIGN5Y2xlIGZvciB0aGUgYmVuZWZpdCBvZgoJICogZGV2aWNlcyB0aGF0IG5lZWQgaXQgKi8KCQoJc3dpdGNoIChidykgewoJCQoJY2FzZSAxOgoJCSoodm9sYXRpbGUgdTgqKShhZGRyKzB4NTU1NSkgPSAweGFhOwoJCSoodm9sYXRpbGUgdTgqKShhZGRyKzB4MmFhYSkgPSAweDU1OwoJCSoodm9sYXRpbGUgdTgqKShhZGRyKzB4NTU1NSkgPSAweDkwOwoJCQoJCS8qIFJlYWQgdmVuZG9yICovCgkJcmVzdWx0ID0gKih2b2xhdGlsZSB1OCopYWRkcjsKCQlyZXN1bHQgPDw9IDE2OwoJCQoJCS8qIFJlYWQgZGV2aWNlICovCgkJcmVzdWx0IHw9ICoodm9sYXRpbGUgdTgqKShhZGRyKzIpOwoJCQoJCS8qIFJldHVybiBkZXZpY2UgdG8gZGF0YSBtb2RlICovCgkJKih2b2xhdGlsZSB1OCopYWRkciA9IDB4ZmY7CgkJKih2b2xhdGlsZSB1OCopKGFkZHIrMHg1NTU1KSwgMHhmMDsgIAoJCWJyZWFrOwoJCQoJY2FzZSAyOgoJCSoodm9sYXRpbGUgdTE2KikoYWRkcisweGFhYWEpID0gMHhhYWFhOwoJCSoodm9sYXRpbGUgdTE2KikoYWRkcisweDU1NTQpID0gMHg1NTU1OwoJCQoJCS8qIElzc3VlIGlkZW50aWZpY2F0aW9uIGNvbW1hbmQgKi8KCQlpZiAoaWwgPT0gMikgewoJCQkqKHZvbGF0aWxlIHUxNiopKGFkZHIrMHhhYWFhKSA9IDB4OTA5MDsKCQkJCgkJCS8qIFJlYWQgdmVuZG9yICovCgkJCXJlc3VsdCA9ICoodm9sYXRpbGUgdTgqKWFkZHI7CgkJCXJlc3VsdCA8PD0gMTY7CgkJCQoJCQkvKiBSZWFkIGRldmljZSAqLwoJCQlyZXN1bHQgfD0gKih2b2xhdGlsZSB1OCopKGFkZHIrMik7CgkJCQoJCQkvKiBSZXR1cm4gZGV2aWNlIHRvIGRhdGEgbW9kZSAqLwoJCQkqKHZvbGF0aWxlIHUxNiopYWRkciA9ICAweGZmZmY7CgkJCSoodm9sYXRpbGUgdTE2KikoYWRkcisweGFhYWEpLCAweGYwZjA7ICAKCQkJCgkJfSBlbHNlIHsKCQkJKih2b2xhdGlsZSB1OCopKGFkZHIrMHhhYWFhKSA9IDB4OTA7CgkJCS8qIFJlYWQgdmVuZG9yICovCgkJCXJlc3VsdCA9ICoodm9sYXRpbGUgdTE2KilhZGRyOwoJCQlyZXN1bHQgPDw9IDE2OwoJCQkKCQkJLyogUmVhZCBkZXZpY2UgKi8KCQkJcmVzdWx0IHw9ICoodm9sYXRpbGUgdTE2KikoYWRkcisyKTsKCQkJCgkJCS8qIFJldHVybiBkZXZpY2UgdG8gZGF0YSBtb2RlICovCgkJCSoodm9sYXRpbGUgdTgqKWFkZHIgPSAweGZmOwoJCQkqKHZvbGF0aWxlIHU4KikoYWRkcisweGFhYWEpLCAweGYwOyAgCQkJCgkJfQoJCQoJCWJyZWFrOwoJCQoJIGNhc2UgNDoKCQkqKHZvbGF0aWxlIHUzMiopKGFkZHIrMHg1NTU0KSA9IDB4YWFhYWFhYWE7CgkJKih2b2xhdGlsZSB1MzIqKShhZGRyKzB4YWFhOCkgPSAweDU1NTU1NTU1OwoJCQoJCXN3aXRjaCAoaWwpIHsKCQljYXNlIDE6CgkJCS8qIElzc3VlIGlkZW50aWZpY2F0aW9uIGNvbW1hbmQgKi8KCQkJKih2b2xhdGlsZSB1OCopKGFkZHIrMHg1NTU0KSA9IDB4OTA7CgkJCQoJCQkvKiBSZWFkIHZlbmRvciAqLwoJCQlyZXN1bHQgPSAqKHZvbGF0aWxlIHUxNiopYWRkcjsKCQkJcmVzdWx0IDw8PSAxNjsKCQkKCQkJLyogUmVhZCBkZXZpY2UgKi8KCQkJcmVzdWx0IHw9ICoodm9sYXRpbGUgdTE2KikoYWRkcis0KTsKCQkJCgkJCS8qIFJldHVybiBkZXZpY2UgdG8gZGF0YSBtb2RlICovCgkJCSoodm9sYXRpbGUgdTgqKWFkZHIgPSAgMHhmZjsKCQkJKih2b2xhdGlsZSB1OCopKGFkZHIrMHg1NTU0KSwgMHhmMDsgIAoJCQlicmVhazsKCQkJCgkJY2FzZSAyOgoJCQkvKiBJc3N1ZSBpZGVudGlmaWNhdGlvbiBjb21tYW5kICovCgkJCSoodm9sYXRpbGUgdTMyKikoYWRkciArIDB4NTU1NCkgPSAweDAwOTAwMDkwOwoJCQkKCQkJLyogUmVhZCB2ZW5kb3IgKi8KCQkJcmVzdWx0ID0gKih2b2xhdGlsZSB1MTYqKWFkZHI7CgkJCXJlc3VsdCA8PD0gMTY7CgkJCQoJCQkvKiBSZWFkIGRldmljZSAqLwoJCQlyZXN1bHQgfD0gKih2b2xhdGlsZSB1MTYqKShhZGRyKzQpOwoJCQkKCQkJLyogUmV0dXJuIGRldmljZSB0byBkYXRhIG1vZGUgKi8KCQkJKih2b2xhdGlsZSB1MzIqKWFkZHIgPSAgMHgwMGZmMDBmZjsKCQkJKih2b2xhdGlsZSB1MzIqKShhZGRyKzB4NTU1NCksIDB4MDBmMDAwZjA7ICAKCQkJYnJlYWs7CgkJCQoJCWNhc2UgNDoKCQkJLyogSXNzdWUgaWRlbnRpZmljYXRpb24gY29tbWFuZCAqLwoJCQkqKHZvbGF0aWxlIHUzMiopKGFkZHIrMHg1NTU0KSA9IDB4OTA5MDkwOTA7CgkJCQoJCQkvKiBSZWFkIHZlbmRvciAqLwoJCQlyZXN1bHQgPSAqKHZvbGF0aWxlIHU4KilhZGRyOwoJCQlyZXN1bHQgPDw9IDE2OwoJCQkKCQkJLyogUmVhZCBkZXZpY2UgKi8KCQkJcmVzdWx0IHw9ICoodm9sYXRpbGUgdTgqKShhZGRyKzQpOwoJCQkKCQkJLyogUmV0dXJuIGRldmljZSB0byBkYXRhIG1vZGUgKi8KCQkJKih2b2xhdGlsZSB1MzIqKWFkZHIgPSAgMHhmZmZmZmZmZjsKCQkJKih2b2xhdGlsZSB1MzIqKShhZGRyKzB4NTU1NCksIDB4ZjBmMGYwZjA7IAoJCQlicmVhazsKCQl9CgkJYnJlYWs7Cgl9CgkKCQoJCglyZXR1cm4gcmVzdWx0Owp9CgpleHRlcm4gaW50IF9wcm9iZV9mbGFzaF9lbmQ7CmFzbSAoIl9wcm9iZV9mbGFzaF9lbmQ6XG4iCiAgICAgIi5sb25nIDBcbiIpOwoKc3RhdGljIGludCBpZGVudGlmeV9mbGFzaCh1bnNpZ25lZCBhZGRyZXNzLCBpbnQgd2lkdGgpCnsKCWludCBpczsJCglpbnQgZGV2aWNlOwoJaW50IHZlbmRvcjsJCglpbnQgc2l6ZTsKCXVuc2lnbmVkIHJlczsKCQoJdTMyICgqX3Byb2JlX2ZsYXNoX3B0cikodTMyIGEsIHUzMiBidywgaW50IGlsKTsKCQoJc2l6ZSA9ICh1bnNpZ25lZCkmX3Byb2JlX2ZsYXNoX2VuZCAtICh1bnNpZ25lZClfcHJvYmVfZmxhc2g7IAoJCglpZiAoc2l6ZSA+IFBST0JFX0JVRkZFUl9TSVpFKSB7CgkJcHJpbnRmKCJfcHJvYmVfZmxhc2goKSByb3V0aW5lIHRvbyBsYXJnZSAoJWQpICVwIC0gJXBcbiIsCgkJICAgICAgIHNpemUsICZfcHJvYmVfZmxhc2hfZW5kLCBfcHJvYmVfZmxhc2gpOwoJCXJldHVybiAwOwoJfQoJCgltZW1jcHkoYnVmZmVyLCBfcHJvYmVfZmxhc2gsIHNpemUpOwoJX3Byb2JlX2ZsYXNoX3B0ciA9ICh2b2lkKilidWZmZXI7CgkKCWlzID0gZGlzYWJsZV9pbnRlcnJ1cHRzKCk7CglyZXMgPSBfcHJvYmVfZmxhc2hfcHRyKGFkZHJlc3MsIHdpZHRoLCAxKTsKCWlmIChpcykgewoJCWVuYWJsZV9pbnRlcnJ1cHRzKCk7Cgl9CgkKCQogICAgICAgIHZlbmRvciA9IHJlcyA+PiAxNjsKCWRldmljZSA9IHJlcyAmIDB4ZmZmZjsKCQoJCQoJcmV0dXJuIHJlczsKfQoKdWxvbmcgZmxhc2hfaW5pdCh2b2lkKQp7CglpbnQgaSwgajsKCXVsb25nIHNpemUgPSAwOwoJCglmb3IgKGkgPSAwOyBpIDwgU0M1MjBfTUFYX0ZMQVNIX0JBTktTOyBpKyspIHsKCQl1bnNpZ25lZCBpZDsKCQl1bG9uZyBmbGFzaGJhc2UgPSAwOwoJCWludCBzZWN0c2l6ZSA9IDA7IAoJCQoJCW1lbXNldChmbGFzaF9pbmZvW2ldLnByb3RlY3QsIDAsIENGR19NQVhfRkxBU0hfU0VDVCk7CgkJc3dpdGNoIChpKSB7CgkJY2FzZSAwOgoJCQlmbGFzaGJhc2UgPSBTQzUyMF9GTEFTSF9CQU5LMF9CQVNFOwoJCQlicmVhazsKCQlkZWZhdWx0OgoJCQlwYW5pYygiY29uZmlndXJlZCB0byBtYW55IGZsYXNoIGJhbmtzIVxuIik7CgkJfQoJCQoJCWlkID0gaWRlbnRpZnlfZmxhc2goZmxhc2hiYXNlLCAyKTsKCQlzd2l0Y2ggKGlkKSB7CgkJY2FzZSAweDAwMDEyMmQ3OgoJCQkvKiAyOUxWNjQxREggKi8KCQkJZmxhc2hfaW5mb1tpXS5mbGFzaF9pZCA9CgkJCQkoQU1EX01BTlVGQUNUICYgRkxBU0hfVkVORE1BU0spIHwKCQkJCShBTURfSURfTFY2NDBVICYgRkxBU0hfVFlQRU1BU0spOwoJCQkKCQkJZmxhc2hfaW5mb1tpXS5zaXplID0gQTI5TFY2NDFESF9TSVpFOwoJCQlmbGFzaF9pbmZvW2ldLnNlY3Rvcl9jb3VudCA9IEEyOUxWNjQxREhfU0VDVE9SUzsKCQkJc2VjdHNpemUgPSBBMjlMVjY0MURIX1NJWkUvQTI5TFY2NDFESF9TRUNUT1JTOwoJCQlwcmludGYoIkJhbmsgJWQ6IEFNRCAyOUxWNjQxREhcbiIsIGkpOwoJCQlicmVhazsKCQkJCgkJY2FzZSAweDAwMDEyMjdFOgoJCQkvKiAyOUxWNjQxTUggKi8KCQkJZmxhc2hfaW5mb1tpXS5mbGFzaF9pZCA9CgkJCQkoQU1EX01BTlVGQUNUICYgRkxBU0hfVkVORE1BU0spIHwKCQkJCShBTURfSURfREw2NDAgJiBGTEFTSF9UWVBFTUFTSyk7CgkJCQoJCQlmbGFzaF9pbmZvW2ldLnNpemUgPSBBMjlMVjY0MU1IX1NJWkU7CgkJCWZsYXNoX2luZm9baV0uc2VjdG9yX2NvdW50ID0gQTI5TFY2NDFNSF9TRUNUT1JTOwoJCQlzZWN0c2l6ZSA9IEEyOUxWNjQxTUhfU0laRS9BMjlMVjY0MU1IX1NFQ1RPUlM7CgkJCXByaW50ZigiQmFuayAlZDogQU1EIDI5TFY2NDFNSFxuIiwgaSk7CgkJCWJyZWFrOwoJCQkKCQljYXNlIDB4MDA4OTAwMTY6CgkJCS8qIDI4RjMyMEozQSAqLwoJCQlmbGFzaF9pbmZvW2ldLmZsYXNoX2lkID0KCQkJCShJTlRFTF9NQU5VRkFDVCAmIEZMQVNIX1ZFTkRNQVNLKSB8CgkJCQkoSU5URUxfSURfMjhGMzIwSjNBICYgRkxBU0hfVFlQRU1BU0spOwoJCQkKCQkJZmxhc2hfaW5mb1tpXS5zaXplID0gSTI4RjMyMEozQV9TSVpFOwoJCQlmbGFzaF9pbmZvW2ldLnNlY3Rvcl9jb3VudCA9IEkyOEYzMjBKM0FfU0VDVE9SUzsKCQkJc2VjdHNpemUgPSBJMjhGMzIwSjNBX1NJWkUvSTI4RjMyMEozQV9TRUNUT1JTOwoJCQlwcmludGYoIkJhbmsgJWQ6IEludGVsIDI4RjMyMEozQVxuIiwgaSk7CgkJCWJyZWFrOwoJCQkKCQljYXNlIDB4MDA4OTAwMTc6CgkJCS8qIDI4RjY0MEozQSAqLwoJCQlmbGFzaF9pbmZvW2ldLmZsYXNoX2lkID0KCQkJCShJTlRFTF9NQU5VRkFDVCAmIEZMQVNIX1ZFTkRNQVNLKSB8CgkJCQkoSU5URUxfSURfMjhGNjQwSjNBICYgRkxBU0hfVFlQRU1BU0spOwoJCQkKCQkJZmxhc2hfaW5mb1tpXS5zaXplID0gSTI4RjY0MEozQV9TSVpFOwoJCQlmbGFzaF9pbmZvW2ldLnNlY3Rvcl9jb3VudCA9IEkyOEY2NDBKM0FfU0VDVE9SUzsKCQkJc2VjdHNpemUgPSBJMjhGNjQwSjNBX1NJWkUvSTI4RjY0MEozQV9TRUNUT1JTOwoJCQlwcmludGYoIkJhbmsgJWQ6IEludGVsIDI4RjY0MEozQVxuIiwgaSk7CgkJCWJyZWFrOwoJCQkKCQljYXNlIDB4MDA4OTAwMTg6CgkJCS8qIDI4RjEyOEozQSAqLwoJCQlmbGFzaF9pbmZvW2ldLmZsYXNoX2lkID0KCQkJCShJTlRFTF9NQU5VRkFDVCAmIEZMQVNIX1ZFTkRNQVNLKSB8CgkJCQkoSU5URUxfSURfMjhGMTI4SjNBICYgRkxBU0hfVFlQRU1BU0spOwoJCQkKCQkJZmxhc2hfaW5mb1tpXS5zaXplID0gSTI4RjEyOEozQV9TSVpFOwoJCQlmbGFzaF9pbmZvW2ldLnNlY3Rvcl9jb3VudCA9IEkyOEYxMjhKM0FfU0VDVE9SUzsKCQkJc2VjdHNpemUgPSBJMjhGMTI4SjNBX1NJWkUvSTI4RjEyOEozQV9TRUNUT1JTOwoJCQlwcmludGYoIkJhbmsgJWQ6IEludGVsIDI4RjEyOEozQVxuIiwgaSk7CgkJCWJyZWFrOwoJCQkKCQlkZWZhdWx0OgoJCQlwcmludGYoIkJhbmsgJWQgaGF2ZSB1bmtub3duIGZsYXNoICUwOHhcbiIsIGksIGlkKTsKCQkJZmxhc2hfaW5mb1tpXS5mbGFzaF9pZCA9IEZMQVNIX1VOS05PV047CgkJCWNvbnRpbnVlOwoJCX0KCQkKCQlmb3IgKGogPSAwOyBqIDwgZmxhc2hfaW5mb1tpXS5zZWN0b3JfY291bnQ7IGorKykgewoJCQlmbGFzaF9pbmZvW2ldLnN0YXJ0W2pdID0gZmxhc2hiYXNlICsgaiAqIHNlY3RzaXplOwoJCX0KCQlzaXplICs9IGZsYXNoX2luZm9baV0uc2l6ZTsKCQkKCQlmbGFzaF9wcm90ZWN0KEZMQUdfUFJPVEVDVF9DTEVBUiwKCQkJICAgICAgZmxhc2hfaW5mb1tpXS5zdGFydFswXSwKCQkJICAgICAgIGZsYXNoX2luZm9baV0uc3RhcnRbMF0gKyBmbGFzaF9pbmZvW2ldLnNpemUgLSAxLAoJCQkgICAgICAmZmxhc2hfaW5mb1tpXSk7Cgl9CgkKCS8qCgkgKiBQcm90ZWN0IG1vbml0b3IgYW5kIGVudmlyb25tZW50IHNlY3RvcnMKCSAqLwoJZmxhc2hfcHJvdGVjdChGTEFHX1BST1RFQ1RfU0VULAoJCSAgICAgIGkzODZib290X3N0YXJ0LAoJCSAgICAgIGkzODZib290X2VuZCwKCQkgICAgICAmZmxhc2hfaW5mb1swXSk7CiNpZmRlZiBDRkdfRU5WX0FERFIKCWZsYXNoX3Byb3RlY3QoRkxBR19QUk9URUNUX1NFVCwKCQkgICAgICBDRkdfRU5WX0FERFIsCgkJICAgICAgQ0ZHX0VOVl9BRERSICsgQ0ZHX0VOVl9TSVpFIC0gMSwKCQkgICAgICAmZmxhc2hfaW5mb1swXSk7CiNlbmRpZgkKCXJldHVybiBzaXplOwp9CgovKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiAqLwp2b2lkIGZsYXNoX3ByaW50X2luZm8oZmxhc2hfaW5mb190ICppbmZvKQp7CglpbnQgaTsKCQoJc3dpdGNoIChpbmZvLT5mbGFzaF9pZCAmIEZMQVNIX1ZFTkRNQVNLKSB7CgljYXNlIChJTlRFTF9NQU5VRkFDVCAmIEZMQVNIX1ZFTkRNQVNLKToKCQlwcmludGYoIklOVEVMOiAiKTsKCQlzd2l0Y2ggKGluZm8tPmZsYXNoX2lkICYgRkxBU0hfVFlQRU1BU0spIHsKCQljYXNlIChJTlRFTF9JRF8yOEYzMjBKM0EgJiBGTEFTSF9UWVBFTUFTSyk6CgkJCXByaW50ZigiMXggSTI4RjMyMEozQSAoMzJNYml0KVxuIik7CgkJCWJyZWFrOwoJCWNhc2UgKElOVEVMX0lEXzI4RjY0MEozQSAmIEZMQVNIX1RZUEVNQVNLKToKCQkJcHJpbnRmKCIxeCBJMjhGNjQwSjNBICg2NE1iaXQpXG4iKTsKCQkJYnJlYWs7CgkJY2FzZSAoSU5URUxfSURfMjhGMTI4SjNBICYgRkxBU0hfVFlQRU1BU0spOgoJCQlwcmludGYoIjF4IEkyOEYxMjhKM0EgKDEyOE1iaXQpXG4iKTsKCQkJYnJlYWs7CgkJZGVmYXVsdDoKCQkJcHJpbnRmKCJVbmtub3duIENoaXAgVHlwZVxuIik7CgkJCWdvdG8gZG9uZTsKCQkJYnJlYWs7CgkJfQoJCQoJCWJyZWFrOwoJCQoJY2FzZSAoQU1EX01BTlVGQUNUICYgRkxBU0hfVkVORE1BU0spOgoJCXByaW50ZigiQU1EOiAgICIpOwoJCXN3aXRjaCAoaW5mby0+Zmxhc2hfaWQgJiBGTEFTSF9UWVBFTUFTSykgewoJCWNhc2UgKEFNRF9JRF9MVjY0MFUgJiBGTEFTSF9UWVBFTUFTSyk6CgkJCXByaW50ZigiMXggQU1EMjlMVjY0MURIICg2NE1iaXQpXG4iKTsKCQkJYnJlYWs7CgkJY2FzZSAoQU1EX0lEX0RMNjQwICYgRkxBU0hfVFlQRU1BU0spOgoJCQlwcmludGYoIjF4IEFNRDI5TFY2NDFNSCAoNjRNYml0KVxuIik7CgkJCWJyZWFrOwoJCWRlZmF1bHQ6CgkJCXByaW50ZigiVW5rbm93biBDaGlwIFR5cGVcbiIpOwoJCQlnb3RvIGRvbmU7CgkJCWJyZWFrOwoJCX0KCQkKCQlicmVhazsKCWRlZmF1bHQ6CgkJcHJpbnRmKCJVbmtub3duIFZlbmRvciAiKTsKCQlicmVhazsKCX0KCQoJCglwcmludGYoIiAgU2l6ZTogJWxkIE1CIGluICVkIFNlY3RvcnNcbiIsCgkgICAgICAgaW5mby0+c2l6ZSA+PiAyMCwgaW5mby0+c2VjdG9yX2NvdW50KTsKCQoJcHJpbnRmKCIgIFNlY3RvciBTdGFydCBBZGRyZXNzZXM6Iik7Cglmb3IgKGkgPSAwOyBpIDwgaW5mby0+c2VjdG9yX2NvdW50OyBpKyspIHsKCQlpZiAoKGkgJSA1KSA9PSAwKSB7CgkJCXByaW50ZiAoIlxuICAgIik7CgkJfQoJCXByaW50ZiAoIiAlMDhsWCVzIiwgaW5mby0+c3RhcnRbaV0sCgkJCWluZm8tPnByb3RlY3RbaV0gPyAiIChSTykiIDogIiAgICAgIik7Cgl9CglwcmludGYgKCJcbiIpOwoJCglkb25lOgp9CgovKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiAqLwoKCnN0YXRpYyB1MzIgX2FtZF9lcmFzZV9mbGFzaCh1MzIgYWRkciwgdTMyIHNlY3RvcikKewoJdW5zaWduZWQgZWxhcHNlZDsKCQoJLyogSXNzdWUgZXJhc2UgKi8KCSoodm9sYXRpbGUgdTE2KikoYWRkciArIDB4YWFhYSkgPSAweDAwQUE7CgkqKHZvbGF0aWxlIHUxNiopKGFkZHIgKyAweDU1NTQpID0gMHgwMDU1OwoJKih2b2xhdGlsZSB1MTYqKShhZGRyICsgMHhhYWFhKSA9IDB4MDA4MDsKCS8qIEFuZCBvbmUgdW5sb2NrICovCgkqKHZvbGF0aWxlIHUxNiopKGFkZHIgKyAweGFhYWEpID0gMHgwMEFBOwoJKih2b2xhdGlsZSB1MTYqKShhZGRyICsgMHg1NTU0KSA9IDB4MDA1NTsKCS8qIFNlY3RvciBlcmFzZSBjb21tYW5kIGNvbWVzIGxhc3QgKi8KCSoodm9sYXRpbGUgdTE2KikoYWRkciArIHNlY3RvcikgPSAweDAwMzA7CgkKCWVsYXBzZWQgPSAqKHZvbGF0aWxlIHUxNiopKDB4ZmZmZWYwMDArU0M1MjBfU1dUTVJNSUxMSSk7IC8qIGR1bW15IHJlYWQgKi8KCWVsYXBzZWQgPSAwOwoJd2hpbGUgKCgoKih2b2xhdGlsZSB1MTYqKShhZGRyICsgc2VjdG9yKSkgJiAweDAwODApICE9IDB4MDA4MCkgewoJCQoJCWVsYXBzZWQgKz0gKih2b2xhdGlsZSB1MTYqKSgweGZmZmVmMDAwK1NDNTIwX1NXVE1STUlMTEkpOwoJCWlmIChlbGFwc2VkID4gKChDRkdfRkxBU0hfRVJBU0VfVE9VVC9DRkdfSFopICogMTAwMCkpIHsKCQkJKih2b2xhdGlsZSB1MTYqKShhZGRyKSA9IDB4MDBmMDsKCQkJcmV0dXJuIDE7CQkJCgkJfQoJfQoJCgkqKHZvbGF0aWxlIHUxNiopKGFkZHIpID0gMHgwMGYwOwoJCglyZXR1cm4gMDsKfQoKZXh0ZXJuIGludCBfYW1kX2VyYXNlX2ZsYXNoX2VuZDsKYXNtICgiX2FtZF9lcmFzZV9mbGFzaF9lbmQ6XG4iCiAgICAgIi5sb25nIDBcbiIpOwoKLyogdGhpcyBuZWVkcyB0byBiZSBpbmxpbmVkLCB0aGUgU1dUTVJNTUlMTEkgcmVnaXN0ZXIgaXMgcmVzZXQgYnkgZWFjaCByZWFkICovCiNkZWZpbmUgX191ZGVsYXkoZGVsYXkpIFwKewlcCgl1bnNpZ25lZCBtaWNybzsgXAoJdW5zaWduZWQgbWlsbGk9MDsgXAoJXAoJbWljcm8gPSAqKHZvbGF0aWxlIHUxNiopKDB4ZmZmZWYwMDArU0M1MjBfU1dUTVJNSUxMSSk7IFwKICAgICAgICAgXAoJZm9yICg7OykgeyBcCgkJXAoJCW1pbGxpICs9ICoodm9sYXRpbGUgdTE2KikoMHhmZmZlZjAwMCtTQzUyMF9TV1RNUk1JTExJKTsgXAoJCW1pY3JvID0gKih2b2xhdGlsZSB1MTYqKSgweGZmZmVmMDAwK1NDNTIwX1NXVE1STUlDUk8pOyBcCgkJXAoJCWlmICgoZGVsYXkpIDw9IChtaWNybyArIChtaWxsaSAqIDEwMDApKSkgeyBcCgkJCWJyZWFrOyBcCgkJfSBcCgl9IFwKfSB3aGlsZSAoMCkgCgpzdGF0aWMgdTMyIF9pbnRlbF9lcmFzZV9mbGFzaCh1MzIgYWRkciwgdTMyIHNlY3RvcikKewkKCXVuc2lnbmVkIGVsYXBzZWQ7CgkKCSoodm9sYXRpbGUgdTE2KikoYWRkciArIHNlY3RvcikgPSAweDAwNTA7ICAgLyogY2xlYXIgc3RhdHVzIHJlZ2lzdGVyICovCgkqKHZvbGF0aWxlIHUxNiopKGFkZHIgKyBzZWN0b3IpID0gMHgwMDIwOyAgIC8qIGVyYXNlIHNldHVwICovCgkqKHZvbGF0aWxlIHUxNiopKGFkZHIgKyBzZWN0b3IpID0gMHgwMEQwOyAgIC8qIGVyYXNlIGNvbmZpcm0gKi8KCgkKCS8qIFdhaXQgYXQgbGVhc3QgODB1cyAtIGxldCdzIHdhaXQgMSBtcyAqLwoJX191ZGVsYXkoMTAwMCk7CgkKCWVsYXBzZWQgPSAwOwoJd2hpbGUgKCgoKih2b2xhdGlsZSB1MTYqKShhZGRyICsgc2VjdG9yKSkgJiAweDAwODApICE9IDB4MDA4MCkgewoJCWVsYXBzZWQgKz0gKih2b2xhdGlsZSB1MTYqKSgweGZmZmVmMDAwK1NDNTIwX1NXVE1STUlMTEkpOwoJCWlmIChlbGFwc2VkID4gKChDRkdfRkxBU0hfRVJBU0VfVE9VVC9DRkdfSFopICogMTAwMCkpIHsKCQkJKih2b2xhdGlsZSB1MTYqKShhZGRyICsgc2VjdG9yKSA9IDB4MDBCMDsgIC8qIHN1c3BlbmQgZXJhc2UgICAgICAqLwoJCQkqKHZvbGF0aWxlIHUxNiopKGFkZHIgKyBzZWN0b3IpID0gMHgwMEZGOyAgLyogcmVzZXQgdG8gcmVhZCBtb2RlICovCgkJCXJldHVybiAxOwkJCQoJCX0KCX0KCQoJKih2b2xhdGlsZSB1MTYqKShhZGRyICsgc2VjdG9yKSA9IDB4MDBGRjsgIC8qIHJlc2V0IHRvIHJlYWQgbW9kZSAqLwoJCglyZXR1cm4gMDsKfQoKCmV4dGVybiBpbnQgX2ludGVsX2VyYXNlX2ZsYXNoX2VuZDsKYXNtICgiX2ludGVsX2VyYXNlX2ZsYXNoX2VuZDpcbiIKICAgICAiLmxvbmcgMFxuIik7CgppbnQgZmxhc2hfZXJhc2UoZmxhc2hfaW5mb190ICppbmZvLCBpbnQgc19maXJzdCwgaW50IHNfbGFzdCkKewoJdTMyICgqX2VyYXNlX2ZsYXNoX3B0cikodTMyIGEsIHUzMiBzbyk7CglpbnQgcHJvdDsKCWludCBzZWN0OwoJdW5zaWduZWQgc2l6ZTsKCQoJaWYgKChzX2ZpcnN0IDwgMCkgfHwgKHNfZmlyc3QgPiBzX2xhc3QpKSB7CgkJaWYgKGluZm8tPmZsYXNoX2lkID09IEZMQVNIX1VOS05PV04pIHsKCQkJcHJpbnRmKCItIG1pc3NpbmdcbiIpOwoJCX0gZWxzZSB7CgkJCXByaW50ZigiLSBubyBzZWN0b3JzIHRvIGVyYXNlXG4iKTsKCQl9CgkJcmV0dXJuIDE7Cgl9CgkKCWlmICgoaW5mby0+Zmxhc2hfaWQgJiBGTEFTSF9WRU5ETUFTSykgPT0gKEFNRF9NQU5VRkFDVCAmIEZMQVNIX1ZFTkRNQVNLKSkgewoJCXNpemUgPSAodW5zaWduZWQpJl9hbWRfZXJhc2VfZmxhc2hfZW5kIC0gKHVuc2lnbmVkKV9hbWRfZXJhc2VfZmxhc2g7IAoJCQoJCWlmIChzaXplID4gUFJPQkVfQlVGRkVSX1NJWkUpIHsKCQkJcHJpbnRmKCJfYW1kX2VyYXNlX2ZsYXNoKCkgcm91dGluZSB0b28gbGFyZ2UgKCVkKSAlcCAtICVwXG4iLAoJCQkgICAgICAgc2l6ZSwgJl9hbWRfZXJhc2VfZmxhc2hfZW5kLCBfYW1kX2VyYXNlX2ZsYXNoKTsKCQkJcmV0dXJuIDA7CgkJfQoJCQoJCW1lbWNweShidWZmZXIsIF9hbWRfZXJhc2VfZmxhc2gsIHNpemUpOwoJCV9lcmFzZV9mbGFzaF9wdHIgPSAodm9pZCopYnVmZmVyOwoJCgl9IGVsc2UgaWYgKChpbmZvLT5mbGFzaF9pZCAmIEZMQVNIX1ZFTkRNQVNLKSA9PSAoSU5URUxfTUFOVUZBQ1QgJiBGTEFTSF9WRU5ETUFTSykpIHsKCQlzaXplID0gKHVuc2lnbmVkKSZfaW50ZWxfZXJhc2VfZmxhc2hfZW5kIC0gKHVuc2lnbmVkKV9pbnRlbF9lcmFzZV9mbGFzaDsgCgkJCgkJaWYgKHNpemUgPiBQUk9CRV9CVUZGRVJfU0laRSkgewoJCQlwcmludGYoIl9pbnRlbF9lcmFzZV9mbGFzaCgpIHJvdXRpbmUgdG9vIGxhcmdlICglZCkgJXAgLSAlcFxuIiwKCQkJICAgICAgIHNpemUsICZfaW50ZWxfZXJhc2VfZmxhc2hfZW5kLCBfaW50ZWxfZXJhc2VfZmxhc2gpOwoJCQlyZXR1cm4gMDsKCQl9CgkJCgkJbWVtY3B5KGJ1ZmZlciwgX2ludGVsX2VyYXNlX2ZsYXNoLCBzaXplKTsKCQlfZXJhc2VfZmxhc2hfcHRyID0gKHZvaWQqKWJ1ZmZlcjsKCX0gZWxzZSB7CgkJcHJpbnRmICgiQ2FuJ3QgZXJhc2UgdW5rbm93biBmbGFzaCB0eXBlIC0gYWJvcnRlZFxuIik7CgkJcmV0dXJuIDE7Cgl9CgkKCXByb3QgPSAwOwoJZm9yIChzZWN0PXNfZmlyc3Q7IHNlY3Q8PXNfbGFzdDsgKytzZWN0KSB7CgkJaWYgKGluZm8tPnByb3RlY3Rbc2VjdF0pIHsKCQkJcHJvdCsrOwoJCX0KCX0KCQoJaWYgKHByb3QpIHsKCQlwcmludGYgKCItIFdhcm5pbmc6ICVkIHByb3RlY3RlZCBzZWN0b3JzIHdpbGwgbm90IGJlIGVyYXNlZCFcbiIsIHByb3QpOwoJfSBlbHNlIHsKCQlwcmludGYgKCJcbiIpOwoJfQoJCQoJCgkvKiBTdGFydCBlcmFzZSBvbiB1bnByb3RlY3RlZCBzZWN0b3JzICovCglmb3IgKHNlY3QgPSBzX2ZpcnN0OyBzZWN0PD1zX2xhc3Q7IHNlY3QrKykgewoJCQoJCWlmIChpbmZvLT5wcm90ZWN0W3NlY3RdID09IDApIHsgLyogbm90IHByb3RlY3RlZCAqLwoJCQlpbnQgcmVzOwoJCQlpbnQgZmxhZzsKCQkJCgkJCS8qIERpc2FibGUgaW50ZXJydXB0cyB3aGljaCBtaWdodCBjYXVzZSBhIHRpbWVvdXQgaGVyZSAqLwoJCQlmbGFnID0gZGlzYWJsZV9pbnRlcnJ1cHRzKCk7CgkJCQoJCQlyZXMgPSBfZXJhc2VfZmxhc2hfcHRyKGluZm8tPnN0YXJ0WzBdLCBpbmZvLT5zdGFydFtzZWN0XS1pbmZvLT5zdGFydFswXSk7CgkJCQoJCQkvKiByZS1lbmFibGUgaW50ZXJydXB0cyBpZiBuZWNlc3NhcnkgKi8KCQkJaWYgKGZsYWcpIHsKCQkJCWVuYWJsZV9pbnRlcnJ1cHRzKCk7CgkJCX0KCQkJCgkJCQoJCQlpZiAocmVzKSB7CgkJCQlwcmludGYoIkVyYXNlIHRpbWVkIG91dCwgc2VjdG9yICVkXG4iLCBzZWN0KTsKCQkJCXJldHVybiByZXM7CgkJCX0KCQkJCgkJCXB1dGMoJy4nKTsJCQkKCQl9CQkKCX0KCgkKCXJldHVybiAwOwp9CgovKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiAqIFdyaXRlIGEgd29yZCB0byBGbGFzaCwgcmV0dXJuczoKICogMCAtIE9LCiAqIDEgLSB3cml0ZSB0aW1lb3V0CiAqIDIgLSBGbGFzaCBub3QgZXJhc2VkCiAqLwpzdGF0aWMgaW50IF9hbWRfd3JpdGVfd29yZCh1bnNpZ25lZCBzdGFydCwgdW5zaWduZWQgZGVzdCwgdW5zaWduZWQgZGF0YSkKewoJdm9sYXRpbGUgdTE2ICphZGRyMiA9ICh1MTYqKXN0YXJ0OwoJdm9sYXRpbGUgdTE2ICpkZXN0MiA9ICh1MTYqKWRlc3Q7Cgl2b2xhdGlsZSB1MTYgKmRhdGEyID0gKHUxNiopJmRhdGE7CglpbnQgaTsKCXVuc2lnbmVkIGVsYXBzZWQ7CgkKCS8qIENoZWNrIGlmIEZsYXNoIGlzIChzdWZmaWNpZW50bHkpIGVyYXNlZCAqLwoJaWYgKCgqKCh2b2xhdGlsZSB1MTYqKWRlc3QpICYgKHUxNilkYXRhKSAhPSAodTE2KWRhdGEpIHsKCQlyZXR1cm4gMjsKCX0KCQoJZm9yIChpID0gMDsgaSA8IDI7IGkrKykgewoJCQoJCQoJCWFkZHIyWzB4NTU1NV0gPSAweDAwQUE7CgkJYWRkcjJbMHgyYWFhXSA9IDB4MDA1NTsKCQlhZGRyMlsweDU1NTVdID0gMHgwMEEwOwoJCQoJCWRlc3QyW2ldID0gKGRhdGEgPj4gKGkqMTYpKSAmIDB4ZmZmZjsKCQkKCQllbGFwc2VkID0gKih2b2xhdGlsZSB1MTYqKSgweGZmZmVmMDAwK1NDNTIwX1NXVE1STUlMTEkpOyAvKiBkdW1teSByZWFkICovCgkJZWxhcHNlZCA9IDA7CgkJCgkJLyogZGF0YSBwb2xsaW5nIGZvciBENyAqLwoJCXdoaWxlICgoZGVzdDJbaV0gJiAweDAwODApICE9IChkYXRhMltpXSAmIDB4MDA4MCkpIHsKCQkJZWxhcHNlZCArPSAqKHZvbGF0aWxlIHUxNiopKDB4ZmZmZWYwMDArU0M1MjBfU1dUTVJNSUxMSSk7CgkJCWlmIChlbGFwc2VkID4gKChDRkdfRkxBU0hfV1JJVEVfVE9VVC9DRkdfSFopICogMTAwMCkpIHsKCQkJCWFkZHIyW2ldID0gMHgwMGYwOwoJCQkJcmV0dXJuIDE7CQkJCgkJCX0KCQl9Cgl9CgkKCWFkZHIyW2ldID0gMHgwMGYwOwoJCglyZXR1cm4gMDsKfQoKZXh0ZXJuIGludCBfYW1kX3dyaXRlX3dvcmRfZW5kOwphc20gKCJfYW1kX3dyaXRlX3dvcmRfZW5kOlxuIgogICAgICIubG9uZyAwXG4iKTsKCgoKc3RhdGljIGludCBfaW50ZWxfd3JpdGVfd29yZCh1bnNpZ25lZCBzdGFydCwgdW5zaWduZWQgZGVzdCwgdW5zaWduZWQgZGF0YSkKewoJaW50IGk7Cgl1bnNpZ25lZCBlbGFwc2VkOwoJCgkvKiBDaGVjayBpZiBGbGFzaCBpcyAoc3VmZmljaWVudGx5KSBlcmFzZWQgKi8KCWlmICgoKigodm9sYXRpbGUgdTE2KilkZXN0KSAmICh1MTYpZGF0YSkgIT0gKHUxNilkYXRhKSB7CgkJcmV0dXJuIDI7Cgl9CgkKCWZvciAoaSA9IDA7IGkgPCAyOyBpKyspIHsKCQkKCQkqKHZvbGF0aWxlIHUxNiopKGRlc3QrMippKSA9IDB4MDA0MDsgLyogd3JpdGUgc2V0dXAgKi8JCQoJCSoodm9sYXRpbGUgdTE2KikoZGVzdCsyKmkpID0gKGRhdGEgPj4gKGkqMTYpKSAmIDB4ZmZmZjsKCQkKCQllbGFwc2VkID0gKih2b2xhdGlsZSB1MTYqKSgweGZmZmVmMDAwK1NDNTIwX1NXVE1STUlMTEkpOyAvKiBkdW1teSByZWFkICovCgkJZWxhcHNlZCA9IDA7CgkJCgkJLyogZGF0YSBwb2xsaW5nIGZvciBENyAqLwoJCXdoaWxlICgoKih2b2xhdGlsZSB1MTYqKWRlc3QgJiAweDAwODApICE9IDB4MDA4MCkgewoJCQllbGFwc2VkICs9ICoodm9sYXRpbGUgdTE2KikoMHhmZmZlZjAwMCtTQzUyMF9TV1RNUk1JTExJKTsKCQkJaWYgKGVsYXBzZWQgPiAoKENGR19GTEFTSF9XUklURV9UT1VUL0NGR19IWikgKiAxMDAwKSkgewoJCQkJKih2b2xhdGlsZSB1MTYqKWRlc3QgPSAweDAwZmY7CgkJCQlyZXR1cm4gMTsJCQkKCQkJfQoJCX0KCX0KCQoJKih2b2xhdGlsZSB1MTYqKWRlc3QgPSAweDAwZmY7CgkKCQoJcmV0dXJuIDA7Cgp9CgpleHRlcm4gaW50IF9pbnRlbF93cml0ZV93b3JkX2VuZDsKYXNtICgiX2ludGVsX3dyaXRlX3dvcmRfZW5kOlxuIgogICAgICIubG9uZyAwXG4iKTsKCgovKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiAqIENvcHkgbWVtb3J5IHRvIGZsYXNoLCByZXR1cm5zOgogKiAwIC0gT0sKICogMSAtIHdyaXRlIHRpbWVvdXQKICogMiAtIEZsYXNoIG5vdCBlcmFzZWQKICogMyAtIFVuc3VwcG9ydGVkIGZsYXNoIHR5cGUKICovCgppbnQgd3JpdGVfYnVmZihmbGFzaF9pbmZvX3QgKmluZm8sIHVjaGFyICpzcmMsIHVsb25nIGFkZHIsIHVsb25nIGNudCkKewoJdWxvbmcgY3AsIHdwLCBkYXRhOwoJaW50IGksIGwsIHJjOwoJaW50IGZsYWc7Cgl1MzIgKCpfd3JpdGVfd29yZF9wdHIpKHVuc2lnbmVkIHN0YXJ0LCB1bnNpZ25lZCBkZXN0LCB1bnNpZ25lZCBkYXRhKTsKCXVuc2lnbmVkIHNpemU7CgkKCWlmICgoaW5mby0+Zmxhc2hfaWQgJiBGTEFTSF9WRU5ETUFTSykgPT0gKEFNRF9NQU5VRkFDVCAmIEZMQVNIX1ZFTkRNQVNLKSkgewoJCXNpemUgPSAodW5zaWduZWQpJl9hbWRfd3JpdGVfd29yZF9lbmQgLSAodW5zaWduZWQpX2FtZF93cml0ZV93b3JkOyAKCQkKCQlpZiAoc2l6ZSA+IFBST0JFX0JVRkZFUl9TSVpFKSB7CgkJCXByaW50ZigiX2FtZF93cml0ZV93b3JkKCkgcm91dGluZSB0b28gbGFyZ2UgKCVkKSAlcCAtICVwXG4iLAoJCQkgICAgICAgc2l6ZSwgJl9hbWRfd3JpdGVfd29yZF9lbmQsIF9hbWRfd3JpdGVfd29yZCk7CgkJCXJldHVybiAwOwoJCX0KCQkKCQltZW1jcHkoYnVmZmVyLCBfYW1kX3dyaXRlX3dvcmQsIHNpemUpOwoJCV93cml0ZV93b3JkX3B0ciA9ICh2b2lkKilidWZmZXI7CgkKCX0gZWxzZSBpZiAoKGluZm8tPmZsYXNoX2lkICYgRkxBU0hfVkVORE1BU0spID09IChJTlRFTF9NQU5VRkFDVCAmIEZMQVNIX1ZFTkRNQVNLKSkgewoJCXNpemUgPSAodW5zaWduZWQpJl9pbnRlbF93cml0ZV93b3JkX2VuZCAtICh1bnNpZ25lZClfaW50ZWxfd3JpdGVfd29yZDsgCgkJCgkJaWYgKHNpemUgPiBQUk9CRV9CVUZGRVJfU0laRSkgewoJCQlwcmludGYoIl9pbnRlbF93cml0ZV93b3JkKCkgcm91dGluZSB0b28gbGFyZ2UgKCVkKSAlcCAtICVwXG4iLAoJCQkgICAgICAgc2l6ZSwgJl9pbnRlbF93cml0ZV93b3JkX2VuZCwgX2ludGVsX3dyaXRlX3dvcmQpOwoJCQlyZXR1cm4gMDsKCQl9CgkJCgkJbWVtY3B5KGJ1ZmZlciwgX2ludGVsX3dyaXRlX3dvcmQsIHNpemUpOwoJCV93cml0ZV93b3JkX3B0ciA9ICh2b2lkKilidWZmZXI7Cgl9IGVsc2UgewoJCXByaW50ZiAoIkNhbid0IHByb2dyYW0gdW5rbm93biBmbGFzaCB0eXBlIC0gYWJvcnRlZFxuIik7CgkJcmV0dXJuIDM7Cgl9CgoKCXdwID0gKGFkZHIgJiB+Myk7CS8qIGdldCBsb3dlciB3b3JkIGFsaWduZWQgYWRkcmVzcyAqLwoJCgoJLyoKCSAqIGhhbmRsZSB1bmFsaWduZWQgc3RhcnQgYnl0ZXMKCSAqLwoJaWYgKChsID0gYWRkciAtIHdwKSAhPSAwKSB7CgkJZGF0YSA9IDA7CgkJZm9yIChpPTAsIGNwPXdwOyBpPGw7ICsraSwgKytjcCkgewoJCQlkYXRhIHw9ICgqKHVjaGFyICopY3ApIDw8ICg4KmkpOwoJCX0KCQlmb3IgKDsgaTw0ICYmIGNudD4wOyArK2kpIHsKCQkJZGF0YSB8PSAqc3JjKysgPDwgKDgqaSk7CgkJCS0tY250OwoJCQkrK2NwOwoJCX0KCQlmb3IgKDsgY250PT0wICYmIGk8NDsgKytpLCArK2NwKSB7CgkJCWRhdGEgfD0gKCoodWNoYXIgKiljcCkgIDw8ICg4KmkpOwoJCX0KCQkKCQkvKiBEaXNhYmxlIGludGVycnVwdHMgd2hpY2ggbWlnaHQgY2F1c2UgYSB0aW1lb3V0IGhlcmUgKi8KCQlmbGFnID0gZGlzYWJsZV9pbnRlcnJ1cHRzKCk7CgkJCgkJcmMgPSBfd3JpdGVfd29yZF9wdHIoaW5mby0+c3RhcnRbMF0sIHdwLCBkYXRhKTsKCQkKCQkvKiByZS1lbmFibGUgaW50ZXJydXB0cyBpZiBuZWNlc3NhcnkgKi8KCQlpZiAoZmxhZykgewoJCQllbmFibGVfaW50ZXJydXB0cygpOwoJCX0KCQlpZiAocmMgIT0gMCkgewoJCQlyZXR1cm4gcmM7CgkJfQoJCXdwICs9IDQ7Cgl9CgkKCS8qCgkgKiBoYW5kbGUgd29yZCBhbGlnbmVkIHBhcnQKCSAqLwoJd2hpbGUgKGNudCA+PSA0KSB7CgkJZGF0YSA9IDA7CgkJCSAgICAgICAKCQlmb3IgKGk9MDsgaTw0OyArK2kpIHsKCQkJZGF0YSB8PSAqc3JjKysgPDwgKDgqaSk7CgkJfQoJCQoJCS8qIERpc2FibGUgaW50ZXJydXB0cyB3aGljaCBtaWdodCBjYXVzZSBhIHRpbWVvdXQgaGVyZSAqLwoJCWZsYWcgPSBkaXNhYmxlX2ludGVycnVwdHMoKTsKCgkJcmMgPSBfd3JpdGVfd29yZF9wdHIoaW5mby0+c3RhcnRbMF0sIHdwLCBkYXRhKTsKCQkKCQkvKiByZS1lbmFibGUgaW50ZXJydXB0cyBpZiBuZWNlc3NhcnkgKi8KCQlpZiAoZmxhZykgewoJCQllbmFibGVfaW50ZXJydXB0cygpOwoJCX0KCQlpZiAocmMgIT0gMCkgewoJCQlyZXR1cm4gcmM7CgkJfQoJCXdwICArPSA0OwoJCWNudCAtPSA0OwoJfQoJCglpZiAoY250ID09IDApIHsKCQlyZXR1cm4gMDsKCX0KCQoJLyoKCSAqIGhhbmRsZSB1bmFsaWduZWQgdGFpbCBieXRlcwoJICovCglkYXRhID0gMDsKCWZvciAoaT0wLCBjcD13cDsgaTw0ICYmIGNudD4wOyArK2ksICsrY3ApIHsKCQlkYXRhIHw9ICpzcmMrKyA8PCAoOCppKTsKCQktLWNudDsKCX0KCQoJZm9yICg7IGk8NDsgKytpLCArK2NwKSB7CgkJZGF0YSB8PSAoKih1Y2hhciAqKWNwKSA8PCAoOCppKTsKCX0KCgkvKiBEaXNhYmxlIGludGVycnVwdHMgd2hpY2ggbWlnaHQgY2F1c2UgYSB0aW1lb3V0IGhlcmUgKi8KCWZsYWcgPSBkaXNhYmxlX2ludGVycnVwdHMoKTsKCglyYyA9IF93cml0ZV93b3JkX3B0cihpbmZvLT5zdGFydFswXSwgd3AsIGRhdGEpOwoJCgkvKiByZS1lbmFibGUgaW50ZXJydXB0cyBpZiBuZWNlc3NhcnkgKi8KCWlmIChmbGFnKSB7CgkJZW5hYmxlX2ludGVycnVwdHMoKTsKCX0KCQoJcmV0dXJuIHJjOwoJCn0KCgo=