LyoKICogKEMpIENvcHlyaWdodCAyMDAyLCAyMDAzCiAqIERhbmllbCBFbmdzdHL2bSwgT21pY3JvbiBDZXRpIEFCLCBkYW5pZWxAb21pY3Jvbi5zZQogKgogKiAoQykgQ29weXJpZ2h0IDIwMDIKICogU3lzZ28gUmVhbC1UaW1lIFNvbHV0aW9ucywgR21iSCA8d3d3LmVsaW5vcy5jb20+CiAqIEFsZXggWnVlcGtlIDxhenVAc3lzZ28uZGU+CiAqCiAqIFNlZSBmaWxlIENSRURJVFMgZm9yIGxpc3Qgb2YgcGVvcGxlIHdobyBjb250cmlidXRlZCB0byB0aGlzCiAqIHByb2plY3QuCiAqCiAqIFRoaXMgcHJvZ3JhbSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IKICogbW9kaWZ5IGl0IHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgYXMKICogcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb247IGVpdGhlciB2ZXJzaW9uIDIgb2YKICogdGhlIExpY2Vuc2UsIG9yIChhdCB5b3VyIG9wdGlvbikgYW55IGxhdGVyIHZlcnNpb24uCiAqCiAqIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLAogKiBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZgogKiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlCiAqIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGZvciBtb3JlIGRldGFpbHMuCiAqCiAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlCiAqIGFsb25nIHdpdGggdGhpcyBwcm9ncmFtOyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlCiAqIEZvdW5kYXRpb24sIEluYy4sIDU5IFRlbXBsZSBQbGFjZSwgU3VpdGUgMzMwLCBCb3N0b24sCiAqIE1BIDAyMTExLTEzMDcgVVNBCiAqLwoKI2luY2x1ZGUgPGNvbW1vbi5oPgojaW5jbHVkZSA8YXNtL2lvLmg+CiNpbmNsdWRlIDxwY2kuaD4KI2luY2x1ZGUgPGFzbS9pYy9zYzUyMC5oPgoKI2RlZmluZSBQUk9CRV9CVUZGRVJfU0laRSAxMDI0CnN0YXRpYyB1bnNpZ25lZCBjaGFyIGJ1ZmZlcltQUk9CRV9CVUZGRVJfU0laRV07CgojZGVmaW5lIFNDNTIwX01BWF9GTEFTSF9CQU5LUyAgMwojZGVmaW5lIFNDNTIwX0ZMQVNIX0JBTkswX0JBU0UgMHgzODAwMDAwMCAgLyogQk9PVENTICovCiNkZWZpbmUgU0M1MjBfRkxBU0hfQkFOSzFfQkFTRSAweDMwMDAwMDAwICAvKiBST01DUzAgKi8KI2RlZmluZSBTQzUyMF9GTEFTSF9CQU5LMl9CQVNFIDB4MjgwMDAwMDAgIC8qIFJPTUNTMSAqLwojZGVmaW5lIFNDNTIwX0ZMQVNIX0JBTktTSVpFICAgMHg4MDAwMDAwCgojZGVmaW5lIEFNRDI5TFYwMTZCX1NJWkUgICAgICAgIDB4MjAwMDAwCiNkZWZpbmUgQU1EMjlMVjAxNkJfU0VDVE9SUyAgICAgMzIKCmZsYXNoX2luZm9fdCAgICBmbGFzaF9pbmZvW1NDNTIwX01BWF9GTEFTSF9CQU5LU107CgojZGVmaW5lIFJFQURZIDEKI2RlZmluZSBFUlIgICAyCiNkZWZpbmUgVE1PICAgNAoKLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQogKi8KCgpzdGF0aWMgdTMyIF9wcm9iZV9mbGFzaCh1MzIgYWRkciwgdTMyIGJ3LCBpbnQgaWwpCnsKCXUzMiByZXN1bHQ9MDsKCgkvKiBGaXJzdCBkbyBhbiB1bmxvY2sgY3ljbGUgZm9yIHRoZSBiZW5lZml0IG9mCgkgKiBkZXZpY2VzIHRoYXQgbmVlZCBpdCAqLwoKCXN3aXRjaCAoYncpIHsKCgljYXNlIDE6CgkJKih2b2xhdGlsZSB1OCopKGFkZHIrMHg1NTU1KSA9IDB4YWE7CgkJKih2b2xhdGlsZSB1OCopKGFkZHIrMHgyYWFhKSA9IDB4NTU7CgkJKih2b2xhdGlsZSB1OCopKGFkZHIrMHg1NTU1KSA9IDB4OTA7CgoJCS8qIFJlYWQgdmVuZG9yICovCgkJcmVzdWx0ID0gKih2b2xhdGlsZSB1OCopYWRkcjsKCQlyZXN1bHQgPDw9IDE2OwoKCQkvKiBSZWFkIGRldmljZSAqLwoJCXJlc3VsdCB8PSAqKHZvbGF0aWxlIHU4KikoYWRkcisyKTsKCgkJLyogUmV0dXJuIGRldmljZSB0byBkYXRhIG1vZGUgKi8KCQkqKHZvbGF0aWxlIHU4KilhZGRyID0gMHhmZjsKCQkqKHZvbGF0aWxlIHU4KikoYWRkcisweDU1NTUpLCAweGYwOwoJCWJyZWFrOwoKCWNhc2UgMjoKCQkqKHZvbGF0aWxlIHUxNiopKGFkZHIrMHhhYWFhKSA9IDB4YWFhYTsKCQkqKHZvbGF0aWxlIHUxNiopKGFkZHIrMHg1NTU0KSA9IDB4NTU1NTsKCgkJLyogSXNzdWUgaWRlbnRpZmljYXRpb24gY29tbWFuZCAqLwoJCWlmIChpbCA9PSAyKSB7CgkJCSoodm9sYXRpbGUgdTE2KikoYWRkcisweGFhYWEpID0gMHg5MDkwOwoKCQkJLyogUmVhZCB2ZW5kb3IgKi8KCQkJcmVzdWx0ID0gKih2b2xhdGlsZSB1OCopYWRkcjsKCQkJcmVzdWx0IDw8PSAxNjsKCgkJCS8qIFJlYWQgZGV2aWNlICovCgkJCXJlc3VsdCB8PSAqKHZvbGF0aWxlIHU4KikoYWRkcisyKTsKCgkJCS8qIFJldHVybiBkZXZpY2UgdG8gZGF0YSBtb2RlICovCgkJCSoodm9sYXRpbGUgdTE2KilhZGRyID0gIDB4ZmZmZjsKCQkJKih2b2xhdGlsZSB1MTYqKShhZGRyKzB4YWFhYSksIDB4ZjBmMDsKCgkJfSBlbHNlIHsKCQkJKih2b2xhdGlsZSB1OCopKGFkZHIrMHhhYWFhKSA9IDB4OTA7CgkJCS8qIFJlYWQgdmVuZG9yICovCgkJCXJlc3VsdCA9ICoodm9sYXRpbGUgdTE2KilhZGRyOwoJCQlyZXN1bHQgPDw9IDE2OwoKCQkJLyogUmVhZCBkZXZpY2UgKi8KCQkJcmVzdWx0IHw9ICoodm9sYXRpbGUgdTE2KikoYWRkcisyKTsKCgkJCS8qIFJldHVybiBkZXZpY2UgdG8gZGF0YSBtb2RlICovCgkJCSoodm9sYXRpbGUgdTgqKWFkZHIgPSAweGZmOwoJCQkqKHZvbGF0aWxlIHU4KikoYWRkcisweGFhYWEpLCAweGYwOwoJCX0KCgkJYnJlYWs7CgoJIGNhc2UgNDoKCQkqKHZvbGF0aWxlIHUzMiopKGFkZHIrMHg1NTU0KSA9IDB4YWFhYWFhYWE7CgkJKih2b2xhdGlsZSB1MzIqKShhZGRyKzB4YWFhOCkgPSAweDU1NTU1NTU1OwoKCQlzd2l0Y2ggKGlsKSB7CgkJY2FzZSAxOgoJCQkvKiBJc3N1ZSBpZGVudGlmaWNhdGlvbiBjb21tYW5kICovCgkJCSoodm9sYXRpbGUgdTgqKShhZGRyKzB4NTU1NCkgPSAweDkwOwoKCQkJLyogUmVhZCB2ZW5kb3IgKi8KCQkJcmVzdWx0ID0gKih2b2xhdGlsZSB1MTYqKWFkZHI7CgkJCXJlc3VsdCA8PD0gMTY7CgoJCQkvKiBSZWFkIGRldmljZSAqLwoJCQlyZXN1bHQgfD0gKih2b2xhdGlsZSB1MTYqKShhZGRyKzQpOwoKCQkJLyogUmV0dXJuIGRldmljZSB0byBkYXRhIG1vZGUgKi8KCQkJKih2b2xhdGlsZSB1OCopYWRkciA9ICAweGZmOwoJCQkqKHZvbGF0aWxlIHU4KikoYWRkcisweDU1NTQpLCAweGYwOwoJCQlicmVhazsKCgkJY2FzZSAyOgoJCQkvKiBJc3N1ZSBpZGVudGlmaWNhdGlvbiBjb21tYW5kICovCgkJCSoodm9sYXRpbGUgdTMyKikoYWRkciArIDB4NTU1NCkgPSAweDAwOTAwMDkwOwoKCQkJLyogUmVhZCB2ZW5kb3IgKi8KCQkJcmVzdWx0ID0gKih2b2xhdGlsZSB1MTYqKWFkZHI7CgkJCXJlc3VsdCA8PD0gMTY7CgoJCQkvKiBSZWFkIGRldmljZSAqLwoJCQlyZXN1bHQgfD0gKih2b2xhdGlsZSB1MTYqKShhZGRyKzQpOwoKCQkJLyogUmV0dXJuIGRldmljZSB0byBkYXRhIG1vZGUgKi8KCQkJKih2b2xhdGlsZSB1MzIqKWFkZHIgPSAgMHgwMGZmMDBmZjsKCQkJKih2b2xhdGlsZSB1MzIqKShhZGRyKzB4NTU1NCksIDB4MDBmMDAwZjA7CgkJCWJyZWFrOwoKCQljYXNlIDQ6CgkJCS8qIElzc3VlIGlkZW50aWZpY2F0aW9uIGNvbW1hbmQgKi8KCQkJKih2b2xhdGlsZSB1MzIqKShhZGRyKzB4NTU1NCkgPSAweDkwOTA5MDkwOwoKCQkJLyogUmVhZCB2ZW5kb3IgKi8KCQkJcmVzdWx0ID0gKih2b2xhdGlsZSB1OCopYWRkcjsKCQkJcmVzdWx0IDw8PSAxNjsKCgkJCS8qIFJlYWQgZGV2aWNlICovCgkJCXJlc3VsdCB8PSAqKHZvbGF0aWxlIHU4KikoYWRkcis0KTsKCgkJCS8qIFJldHVybiBkZXZpY2UgdG8gZGF0YSBtb2RlICovCgkJCSoodm9sYXRpbGUgdTMyKilhZGRyID0gIDB4ZmZmZmZmZmY7CgkJCSoodm9sYXRpbGUgdTMyKikoYWRkcisweDU1NTQpLCAweGYwZjBmMGYwOwoJCQlicmVhazsKCQl9CgkJYnJlYWs7Cgl9CgoKCXJldHVybiByZXN1bHQ7Cn0KCmV4dGVybiBpbnQgX3Byb2JlX2ZsYXNoX2VuZDsKYXNtICgiX3Byb2JlX2ZsYXNoX2VuZDpcbiIKICAgICAiLmxvbmcgMFxuIik7CgpzdGF0aWMgaW50IGlkZW50aWZ5X2ZsYXNoKHVuc2lnbmVkIGFkZHJlc3MsIGludCB3aWR0aCkKewoJaW50IGlzOwoJaW50IGRldmljZTsKCWludCB2ZW5kb3I7CglpbnQgc2l6ZTsKCXVuc2lnbmVkIHJlczsKCgl1MzIgKCpfcHJvYmVfZmxhc2hfcHRyKSh1MzIgYSwgdTMyIGJ3LCBpbnQgaWwpOwoKCXNpemUgPSAodW5zaWduZWQpJl9wcm9iZV9mbGFzaF9lbmQgLSAodW5zaWduZWQpX3Byb2JlX2ZsYXNoOwoKCWlmIChzaXplID4gUFJPQkVfQlVGRkVSX1NJWkUpIHsKCQlwcmludGYoIl9wcm9iZV9mbGFzaCgpIHJvdXRpbmUgdG9vIGxhcmdlICglZCkgJXAgLSAlcFxuIiwKCQkgICAgICAgc2l6ZSwgJl9wcm9iZV9mbGFzaF9lbmQsIF9wcm9iZV9mbGFzaCk7CgkJcmV0dXJuIDA7Cgl9CgoJbWVtY3B5KGJ1ZmZlciwgX3Byb2JlX2ZsYXNoLCBzaXplKTsKCV9wcm9iZV9mbGFzaF9wdHIgPSAodm9pZCopYnVmZmVyOwoKCWlzID0gZGlzYWJsZV9pbnRlcnJ1cHRzKCk7CglyZXMgPSBfcHJvYmVfZmxhc2hfcHRyKGFkZHJlc3MsIHdpZHRoLCAxKTsKCWlmIChpcykgewoJCWVuYWJsZV9pbnRlcnJ1cHRzKCk7Cgl9CgoKCXZlbmRvciA9IHJlcyA+PiAxNjsKCWRldmljZSA9IHJlcyAmIDB4ZmZmZjsKCgoJcmV0dXJuIHJlczsKfQoKdWxvbmcgZmxhc2hfaW5pdCh2b2lkKQp7CglpbnQgaSwgajsKCXVsb25nIHNpemUgPSAwOwoKCWZvciAoaSA9IDA7IGkgPCBTQzUyMF9NQVhfRkxBU0hfQkFOS1M7IGkrKykgewoJCXVuc2lnbmVkIGlkOwoJCXVsb25nIGZsYXNoYmFzZSA9IDA7CgkJaW50IHNlY3RzaXplID0gMDsKCgkJbWVtc2V0KGZsYXNoX2luZm9baV0ucHJvdGVjdCwgMCwgQ09ORklHX1NZU19NQVhfRkxBU0hfU0VDVCk7CgkJc3dpdGNoIChpKSB7CgkJY2FzZSAwOgoJCQlmbGFzaGJhc2UgPSBTQzUyMF9GTEFTSF9CQU5LMF9CQVNFOwoJCQlicmVhazsKCQljYXNlIDE6CgkJCWZsYXNoYmFzZSA9IFNDNTIwX0ZMQVNIX0JBTksxX0JBU0U7CgkJCWJyZWFrOwoJCWNhc2UgMjoKCQkJZmxhc2hiYXNlID0gU0M1MjBfRkxBU0hfQkFOSzJfQkFTRTsKCQkJYnJlYWs7CgkJZGVmYXVsdDoKCQkJcGFuaWMoImNvbmZpZ3VyZWQgdG9vIG1hbnkgZmxhc2ggYmFua3MhXG4iKTsKCQl9CgoJCWlkID0gaWRlbnRpZnlfZmxhc2goZmxhc2hiYXNlLCA0KTsKCQlzd2l0Y2ggKGlkICYgMHgwMGZmMDBmZikgewoJCWNhc2UgMHgwMDAxMDBjODoKCQkJLyogMjlMVjAxNkIvMjlMVjAxN0IgKi8KCQkJZmxhc2hfaW5mb1tpXS5mbGFzaF9pZCA9CgkJCQkoQU1EX01BTlVGQUNUICYgRkxBU0hfVkVORE1BU0spIHwKCQkJCShBTURfSURfTFYwMTZCICYgRkxBU0hfVFlQRU1BU0spOwoKCQkJZmxhc2hfaW5mb1tpXS5zaXplID0gQU1EMjlMVjAxNkJfU0laRSo0OwoJCQlmbGFzaF9pbmZvW2ldLnNlY3Rvcl9jb3VudCA9IEFNRDI5TFYwMTZCX1NFQ1RPUlM7CgkJCXNlY3RzaXplID0gKEFNRDI5TFYwMTZCX1NJWkUqNCkvQU1EMjlMVjAxNkJfU0VDVE9SUzsKCQkJcHJpbnRmKCJCYW5rICVkOiA0IHggQU1EIDI5TFYwMTdCXG4iLCBpKTsKCQkJYnJlYWs7CgoKCQlkZWZhdWx0OgoJCQlwcmludGYoIkJhbmsgJWQgaGF2ZSB1bmtub3duIGZsYXNoICUwOHhcbiIsIGksIGlkKTsKCQkJZmxhc2hfaW5mb1tpXS5mbGFzaF9pZCA9IEZMQVNIX1VOS05PV047CgkJCWNvbnRpbnVlOwoJCX0KCgkJZm9yIChqID0gMDsgaiA8IGZsYXNoX2luZm9baV0uc2VjdG9yX2NvdW50OyBqKyspIHsKCQkJZmxhc2hfaW5mb1tpXS5zdGFydFtqXSA9IGZsYXNoYmFzZSArIGogKiBzZWN0c2l6ZTsKCQl9CgkJc2l6ZSArPSBmbGFzaF9pbmZvW2ldLnNpemU7CgoJCWZsYXNoX3Byb3RlY3QoRkxBR19QUk9URUNUX0NMRUFSLAoJCQkgICAgICBmbGFzaF9pbmZvW2ldLnN0YXJ0WzBdLAoJCQkgICAgICAgZmxhc2hfaW5mb1tpXS5zdGFydFswXSArIGZsYXNoX2luZm9baV0uc2l6ZSAtIDEsCgkJCSAgICAgICZmbGFzaF9pbmZvW2ldKTsKCX0KCgkvKgoJICogUHJvdGVjdCBtb25pdG9yIGFuZCBlbnZpcm9ubWVudCBzZWN0b3JzCgkgKi8KCWZsYXNoX3Byb3RlY3QoRkxBR19QUk9URUNUX1NFVCwKCQkgICAgICBpMzg2Ym9vdF9zdGFydCwKCQkgICAgICBpMzg2Ym9vdF9lbmQsCgkJICAgICAgJmZsYXNoX2luZm9bMF0pOwojaWZkZWYgQ09ORklHX0VOVl9BRERSCglmbGFzaF9wcm90ZWN0KEZMQUdfUFJPVEVDVF9TRVQsCgkJICAgICAgQ09ORklHX0VOVl9BRERSLAoJCSAgICAgIENPTkZJR19FTlZfQUREUiArIENPTkZJR19FTlZfU0laRSAtIDEsCgkJICAgICAgJmZsYXNoX2luZm9bMF0pOwojZW5kaWYKCXJldHVybiBzaXplOwp9CgovKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiAqLwp2b2lkIGZsYXNoX3ByaW50X2luZm8oZmxhc2hfaW5mb190ICppbmZvKQp7CglpbnQgaTsKCglzd2l0Y2ggKGluZm8tPmZsYXNoX2lkICYgRkxBU0hfVkVORE1BU0spIHsKCgljYXNlIChBTURfTUFOVUZBQ1QgJiBGTEFTSF9WRU5ETUFTSyk6CgkJcHJpbnRmKCJBTUQ6ICAgIik7CgkJc3dpdGNoIChpbmZvLT5mbGFzaF9pZCAmIEZMQVNIX1RZUEVNQVNLKSB7CgkJY2FzZSAoQU1EX0lEX0xWMDE2QiAmIEZMQVNIX1RZUEVNQVNLKToKCQkJcHJpbnRmKCI0eCBBTUQyOUxWMDE3QiAoNHgxNk1iaXQpXG4iKTsKCQkJYnJlYWs7CgkJZGVmYXVsdDoKCQkJcHJpbnRmKCJVbmtub3duIENoaXAgVHlwZVxuIik7CgkJCWdvdG8gZG9uZTsKCQkJYnJlYWs7CgkJfQoKCQlicmVhazsKCWRlZmF1bHQ6CgkJcHJpbnRmKCJVbmtub3duIFZlbmRvciAiKTsKCQlicmVhazsKCX0KCgoJcHJpbnRmKCIgIFNpemU6ICVsZCBNQiBpbiAlZCBTZWN0b3JzXG4iLAoJICAgICAgIGluZm8tPnNpemUgPj4gMjAsIGluZm8tPnNlY3Rvcl9jb3VudCk7CgoJcHJpbnRmKCIgIFNlY3RvciBTdGFydCBBZGRyZXNzZXM6Iik7Cglmb3IgKGkgPSAwOyBpIDwgaW5mby0+c2VjdG9yX2NvdW50OyBpKyspIHsKCQlpZiAoKGkgJSA1KSA9PSAwKSB7CgkJCXByaW50ZiAoIlxuICAgIik7CgkJfQoJCXByaW50ZiAoIiAlMDhsWCVzIiwgaW5mby0+c3RhcnRbaV0sCgkJCWluZm8tPnByb3RlY3RbaV0gPyAiIChSTykiIDogIiAgICAgIik7Cgl9CglwcmludGYgKCJcbiIpOwoKZG9uZToJOwp9CgovKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiAqLwoKLyogdGhpcyBuZWVkcyB0byBiZSBpbmxpbmVkLCB0aGUgU1dUTVJNTUlMTEkgcmVnaXN0ZXIgaXMgcmVzZXQgYnkgZWFjaCByZWFkICovCiNkZWZpbmUgX191ZGVsYXkoZGVsYXkpIFwKewlcCgl1bnNpZ25lZCBtaWNybzsgXAoJdW5zaWduZWQgbWlsbGk9MDsgXAoJXAoJbWljcm8gPSBzYzUyMF9tbWNyLT5zd3Rtcm1pbGxpOyBcCgkgXAoJZm9yICg7OykgeyBcCgkJXAoJCW1pbGxpICs9IHNjNTIwX21tY3ItPnN3dG1ybWlsbGk7IFwKCQltaWNybyA9IHNjNTIwX21tY3ItPnN3dG1ybWljcm87IFwKCQlcCgkJaWYgKChkZWxheSkgPD0gKG1pY3JvICsgKG1pbGxpICogMTAwMCkpKSB7IFwKCQkJYnJlYWs7IFwKCQl9IFwKCX0gXAp9IHdoaWxlICgwKQoKc3RhdGljIHUzMiBfYW1kX2VyYXNlX2ZsYXNoKHUzMiBhZGRyLCB1MzIgc2VjdG9yKQp7Cgl1bnNpZ25lZCBlbGFwc2VkOwoKCS8qIElzc3VlIGVyYXNlICovCgkqKHZvbGF0aWxlIHUzMiopKGFkZHIgKyAweDU1NTQpID0gMHhBQUFBQUFBQTsKCSoodm9sYXRpbGUgdTMyKikoYWRkciArIDB4YWFhOCkgPSAweDU1NTU1NTU1OwoJKih2b2xhdGlsZSB1MzIqKShhZGRyICsgMHg1NTU0KSA9IDB4ODA4MDgwODA7CgkvKiBBbmQgb25lIHVubG9jayAqLwoJKih2b2xhdGlsZSB1MzIqKShhZGRyICsgMHg1NTU0KSA9IDB4QUFBQUFBQUE7CgkqKHZvbGF0aWxlIHUzMiopKGFkZHIgKyAweGFhYTgpID0gMHg1NTU1NTU1NTsKCS8qIFNlY3RvciBlcmFzZSBjb21tYW5kIGNvbWVzIGxhc3QgKi8KCSoodm9sYXRpbGUgdTMyKikoYWRkciArIHNlY3RvcikgPSAweDMwMzAzMDMwOwoKCWVsYXBzZWQgPSBzYzUyMF9tbWNyLT5zd3Rtcm1pbGxpOyAvKiBkdW1teSByZWFkICovCgllbGFwc2VkID0gMDsKCV9fdWRlbGF5KDUwKTsKCXdoaWxlICgoKCoodm9sYXRpbGUgdTMyKikoYWRkciArIHNlY3RvcikpICYgMHg4MDgwODA4MCkgIT0gMHg4MDgwODA4MCkgewoKCQllbGFwc2VkICs9IHNjNTIwX21tY3ItPnN3dG1ybWlsbGk7CgkJaWYgKGVsYXBzZWQgPiAoKENPTkZJR19TWVNfRkxBU0hfRVJBU0VfVE9VVC9DT05GSUdfU1lTX0haKSAqIDEwMDApKSB7CgkJCSoodm9sYXRpbGUgdTMyKikoYWRkcikgPSAweGYwZjBmMGYwOwoJCQlyZXR1cm4gMTsKCQl9Cgl9CgoJKih2b2xhdGlsZSB1MzIqKShhZGRyKSA9IDB4ZjBmMGYwZjA7CgoJcmV0dXJuIDA7Cn0KCmV4dGVybiBpbnQgX2FtZF9lcmFzZV9mbGFzaF9lbmQ7CmFzbSAoIl9hbWRfZXJhc2VfZmxhc2hfZW5kOlxuIgogICAgICIubG9uZyAwXG4iKTsKCmludCBmbGFzaF9lcmFzZShmbGFzaF9pbmZvX3QgKmluZm8sIGludCBzX2ZpcnN0LCBpbnQgc19sYXN0KQp7Cgl1MzIgKCpfZXJhc2VfZmxhc2hfcHRyKSh1MzIgYSwgdTMyIHNvKTsKCWludCBwcm90OwoJaW50IHNlY3Q7Cgl1bnNpZ25lZCBzaXplOwoKCWlmICgoc19maXJzdCA8IDApIHx8IChzX2ZpcnN0ID4gc19sYXN0KSkgewoJCWlmIChpbmZvLT5mbGFzaF9pZCA9PSBGTEFTSF9VTktOT1dOKSB7CgkJCXByaW50ZigiLSBtaXNzaW5nXG4iKTsKCQl9IGVsc2UgewoJCQlwcmludGYoIi0gbm8gc2VjdG9ycyB0byBlcmFzZVxuIik7CgkJfQoJCXJldHVybiAxOwoJfQoKCWlmICgoaW5mby0+Zmxhc2hfaWQgJiBGTEFTSF9WRU5ETUFTSykgPT0gKEFNRF9NQU5VRkFDVCAmIEZMQVNIX1ZFTkRNQVNLKSkgewoJCXNpemUgPSAodW5zaWduZWQpJl9hbWRfZXJhc2VfZmxhc2hfZW5kIC0gKHVuc2lnbmVkKV9hbWRfZXJhc2VfZmxhc2g7CgoJCWlmIChzaXplID4gUFJPQkVfQlVGRkVSX1NJWkUpIHsKCQkJcHJpbnRmKCJfYW1kX2VyYXNlX2ZsYXNoKCkgcm91dGluZSB0b28gbGFyZ2UgKCVkKSAlcCAtICVwXG4iLAoJCQkgICAgICAgc2l6ZSwgJl9hbWRfZXJhc2VfZmxhc2hfZW5kLCBfYW1kX2VyYXNlX2ZsYXNoKTsKCQkJcmV0dXJuIDA7CgkJfQoKCQltZW1jcHkoYnVmZmVyLCBfYW1kX2VyYXNlX2ZsYXNoLCBzaXplKTsKCQlfZXJhc2VfZmxhc2hfcHRyID0gKHZvaWQqKWJ1ZmZlcjsKCgl9ICBlbHNlIHsKCQlwcmludGYgKCJDYW4ndCBlcmFzZSB1bmtub3duIGZsYXNoIHR5cGUgLSBhYm9ydGVkXG4iKTsKCQlyZXR1cm4gMTsKCX0KCglwcm90ID0gMDsKCWZvciAoc2VjdD1zX2ZpcnN0OyBzZWN0PD1zX2xhc3Q7ICsrc2VjdCkgewoJCWlmIChpbmZvLT5wcm90ZWN0W3NlY3RdKSB7CgkJCXByb3QrKzsKCQl9Cgl9CgoJaWYgKHByb3QpIHsKCQlwcmludGYgKCItIFdhcm5pbmc6ICVkIHByb3RlY3RlZCBzZWN0b3JzIHdpbGwgbm90IGJlIGVyYXNlZCFcbiIsIHByb3QpOwoJfSBlbHNlIHsKCQlwcmludGYgKCJcbiIpOwoJfQoKCgkvKiBTdGFydCBlcmFzZSBvbiB1bnByb3RlY3RlZCBzZWN0b3JzICovCglmb3IgKHNlY3QgPSBzX2ZpcnN0OyBzZWN0PD1zX2xhc3Q7IHNlY3QrKykgewoKCQlpZiAoaW5mby0+cHJvdGVjdFtzZWN0XSA9PSAwKSB7IC8qIG5vdCBwcm90ZWN0ZWQgKi8KCQkJaW50IHJlczsKCQkJaW50IGZsYWc7CgoJCQkvKiBEaXNhYmxlIGludGVycnVwdHMgd2hpY2ggbWlnaHQgY2F1c2UgYSB0aW1lb3V0IGhlcmUgKi8KCQkJZmxhZyA9IGRpc2FibGVfaW50ZXJydXB0cygpOwoKCQkJcmVzID0gX2VyYXNlX2ZsYXNoX3B0cihpbmZvLT5zdGFydFswXSwgaW5mby0+c3RhcnRbc2VjdF0taW5mby0+c3RhcnRbMF0pOwoKCQkJLyogcmUtZW5hYmxlIGludGVycnVwdHMgaWYgbmVjZXNzYXJ5ICovCgkJCWlmIChmbGFnKSB7CgkJCQllbmFibGVfaW50ZXJydXB0cygpOwoJCQl9CgoKCQkJaWYgKHJlcykgewoJCQkJcHJpbnRmKCJFcmFzZSB0aW1lZCBvdXQsIHNlY3RvciAlZFxuIiwgc2VjdCk7CgkJCQlyZXR1cm4gcmVzOwoJCQl9CgoJCQlwdXRjKCcuJyk7CgkJfQoJfQoKCglyZXR1cm4gMDsKfQoKLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQogKiBXcml0ZSBhIHdvcmQgdG8gRmxhc2gsIHJldHVybnM6CiAqIDAgLSBPSwogKiAxIC0gd3JpdGUgdGltZW91dAogKiAyIC0gRmxhc2ggbm90IGVyYXNlZAogKi8Kc3RhdGljIGludCBfYW1kX3dyaXRlX3dvcmQodW5zaWduZWQgc3RhcnQsIHVuc2lnbmVkIGRlc3QsIHVuc2lnbmVkIGRhdGEpCnsKCXZvbGF0aWxlIHUzMiAqYWRkcjIgPSAodTMyKilzdGFydDsKCXZvbGF0aWxlIHUzMiAqZGVzdDIgPSAodTMyKilkZXN0OwoJdm9sYXRpbGUgdTMyICpkYXRhMiA9ICh1MzIqKSZkYXRhOwoJdW5zaWduZWQgZWxhcHNlZDsKCgkvKiBDaGVjayBpZiBGbGFzaCBpcyAoc3VmZmljaWVudGx5KSBlcmFzZWQgKi8KCWlmICgoKigodm9sYXRpbGUgdTMyKilkZXN0KSAmICh1MzIpZGF0YSkgIT0gKHUzMilkYXRhKSB7CgkJcmV0dXJuIDI7Cgl9CgoJYWRkcjJbMHg1NTU0XSA9IDB4QUFBQUFBQUE7CglhZGRyMlsweGFhYThdID0gMHg1NTU1NTU1NTsKCWFkZHIyWzB4NTU1NF0gPSAweEEwQTBBMEEwOwoKCWRlc3QyWzBdID0gZGF0YTsKCgllbGFwc2VkID0gc2M1MjBfbW1jci0+c3d0bXJtaWxsaTsgLyogZHVtbXkgcmVhZCAqLwoJZWxhcHNlZCA9IDA7CgoJLyogZGF0YSBwb2xsaW5nIGZvciBENyAqLwoJd2hpbGUgKChkZXN0MlswXSAmIDB4ODA4MDgwODApICE9IChkYXRhMlswXSAmIDB4ODA4MDgwODApKSB7CgkJZWxhcHNlZCArPSBzYzUyMF9tbWNyLT5zd3Rtcm1pbGxpOwoJCWlmIChlbGFwc2VkID4gKChDT05GSUdfU1lTX0ZMQVNIX1dSSVRFX1RPVVQvQ09ORklHX1NZU19IWikgKiAxMDAwKSkgewoJCQlhZGRyMlswXSA9IDB4ZjBmMGYwZjA7CgkJCXJldHVybiAxOwoJCX0KCX0KCgoJYWRkcjJbMF0gPSAweGYwZjBmMGYwOwoKCXJldHVybiAwOwp9CgpleHRlcm4gaW50IF9hbWRfd3JpdGVfd29yZF9lbmQ7CmFzbSAoIl9hbWRfd3JpdGVfd29yZF9lbmQ6XG4iCiAgICAgIi5sb25nIDBcbiIpOwoKCi8qLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KICogQ29weSBtZW1vcnkgdG8gZmxhc2gsIHJldHVybnM6CiAqIDAgLSBPSwogKiAxIC0gd3JpdGUgdGltZW91dAogKiAyIC0gRmxhc2ggbm90IGVyYXNlZAogKiAzIC0gVW5zdXBwb3J0ZWQgZmxhc2ggdHlwZQogKi8KCmludCB3cml0ZV9idWZmKGZsYXNoX2luZm9fdCAqaW5mbywgdWNoYXIgKnNyYywgdWxvbmcgYWRkciwgdWxvbmcgY250KQp7Cgl1bG9uZyBjcCwgd3AsIGRhdGE7CglpbnQgaSwgbCwgcmM7CglpbnQgZmxhZzsKCXUzMiAoKl93cml0ZV93b3JkX3B0cikodW5zaWduZWQgc3RhcnQsIHVuc2lnbmVkIGRlc3QsIHVuc2lnbmVkIGRhdGEpOwoJdW5zaWduZWQgc2l6ZTsKCglpZiAoKGluZm8tPmZsYXNoX2lkICYgRkxBU0hfVkVORE1BU0spID09IChBTURfTUFOVUZBQ1QgJiBGTEFTSF9WRU5ETUFTSykpIHsKCQlzaXplID0gKHVuc2lnbmVkKSZfYW1kX3dyaXRlX3dvcmRfZW5kIC0gKHVuc2lnbmVkKV9hbWRfd3JpdGVfd29yZDsKCgkJaWYgKHNpemUgPiBQUk9CRV9CVUZGRVJfU0laRSkgewoJCQlwcmludGYoIl9hbWRfd3JpdGVfd29yZCgpIHJvdXRpbmUgdG9vIGxhcmdlICglZCkgJXAgLSAlcFxuIiwKCQkJICAgICAgIHNpemUsICZfYW1kX3dyaXRlX3dvcmRfZW5kLCBfYW1kX3dyaXRlX3dvcmQpOwoJCQlyZXR1cm4gMDsKCQl9CgoJCW1lbWNweShidWZmZXIsIF9hbWRfd3JpdGVfd29yZCwgc2l6ZSk7CgkJX3dyaXRlX3dvcmRfcHRyID0gKHZvaWQqKWJ1ZmZlcjsKCgl9IGVsc2UgewoJCXByaW50ZiAoIkNhbid0IHByb2dyYW0gdW5rbm93biBmbGFzaCB0eXBlIC0gYWJvcnRlZFxuIik7CgkJcmV0dXJuIDM7Cgl9CgoKCXdwID0gKGFkZHIgJiB+Myk7CS8qIGdldCBsb3dlciB3b3JkIGFsaWduZWQgYWRkcmVzcyAqLwoKCgkvKgoJICogaGFuZGxlIHVuYWxpZ25lZCBzdGFydCBieXRlcwoJICovCglpZiAoKGwgPSBhZGRyIC0gd3ApICE9IDApIHsKCQlkYXRhID0gMDsKCQlmb3IgKGk9MCwgY3A9d3A7IGk8bDsgKytpLCArK2NwKSB7CgkJCWRhdGEgfD0gKCoodWNoYXIgKiljcCkgPDwgKDgqaSk7CgkJfQoJCWZvciAoOyBpPDQgJiYgY250PjA7ICsraSkgewoJCQlkYXRhIHw9ICpzcmMrKyA8PCAoOCppKTsKCQkJLS1jbnQ7CgkJCSsrY3A7CgkJfQoJCWZvciAoOyBjbnQ9PTAgJiYgaTw0OyArK2ksICsrY3ApIHsKCQkJZGF0YSB8PSAoKih1Y2hhciAqKWNwKSAgPDwgKDgqaSk7CgkJfQoKCQkvKiBEaXNhYmxlIGludGVycnVwdHMgd2hpY2ggbWlnaHQgY2F1c2UgYSB0aW1lb3V0IGhlcmUgKi8KCQlmbGFnID0gZGlzYWJsZV9pbnRlcnJ1cHRzKCk7CgoJCXJjID0gX3dyaXRlX3dvcmRfcHRyKGluZm8tPnN0YXJ0WzBdLCB3cCwgZGF0YSk7CgoJCS8qIHJlLWVuYWJsZSBpbnRlcnJ1cHRzIGlmIG5lY2Vzc2FyeSAqLwoJCWlmIChmbGFnKSB7CgkJCWVuYWJsZV9pbnRlcnJ1cHRzKCk7CgkJfQoJCWlmIChyYyAhPSAwKSB7CgkJCXJldHVybiByYzsKCQl9CgkJd3AgKz0gNDsKCX0KCgkvKgoJICogaGFuZGxlIHdvcmQgYWxpZ25lZCBwYXJ0CgkgKi8KCXdoaWxlIChjbnQgPj0gNCkgewoJCWRhdGEgPSAwOwoKCQlmb3IgKGk9MDsgaTw0OyArK2kpIHsKCQkJZGF0YSB8PSAqc3JjKysgPDwgKDgqaSk7CgkJfQoKCQkvKiBEaXNhYmxlIGludGVycnVwdHMgd2hpY2ggbWlnaHQgY2F1c2UgYSB0aW1lb3V0IGhlcmUgKi8KCQlmbGFnID0gZGlzYWJsZV9pbnRlcnJ1cHRzKCk7CgoJCXJjID0gX3dyaXRlX3dvcmRfcHRyKGluZm8tPnN0YXJ0WzBdLCB3cCwgZGF0YSk7CgoJCS8qIHJlLWVuYWJsZSBpbnRlcnJ1cHRzIGlmIG5lY2Vzc2FyeSAqLwoJCWlmIChmbGFnKSB7CgkJCWVuYWJsZV9pbnRlcnJ1cHRzKCk7CgkJfQoJCWlmIChyYyAhPSAwKSB7CgkJCXJldHVybiByYzsKCQl9CgkJd3AgICs9IDQ7CgkJY250IC09IDQ7Cgl9CgoJaWYgKGNudCA9PSAwKSB7CgkJcmV0dXJuIDA7Cgl9CgoJLyoKCSAqIGhhbmRsZSB1bmFsaWduZWQgdGFpbCBieXRlcwoJICovCglkYXRhID0gMDsKCWZvciAoaT0wLCBjcD13cDsgaTw0ICYmIGNudD4wOyArK2ksICsrY3ApIHsKCQlkYXRhIHw9ICpzcmMrKyA8PCAoOCppKTsKCQktLWNudDsKCX0KCglmb3IgKDsgaTw0OyArK2ksICsrY3ApIHsKCQlkYXRhIHw9ICgqKHVjaGFyICopY3ApIDw8ICg4KmkpOwoJfQoKCS8qIERpc2FibGUgaW50ZXJydXB0cyB3aGljaCBtaWdodCBjYXVzZSBhIHRpbWVvdXQgaGVyZSAqLwoJZmxhZyA9IGRpc2FibGVfaW50ZXJydXB0cygpOwoKCXJjID0gX3dyaXRlX3dvcmRfcHRyKGluZm8tPnN0YXJ0WzBdLCB3cCwgZGF0YSk7CgoJLyogcmUtZW5hYmxlIGludGVycnVwdHMgaWYgbmVjZXNzYXJ5ICovCglpZiAoZmxhZykgewoJCWVuYWJsZV9pbnRlcnJ1cHRzKCk7Cgl9CgoJcmV0dXJuIHJjOwoKfQo=