LyogbWVtLmMgLS0tIG1lbW9yeSBmb3IgTTMyQyBzaW11bGF0b3IuCgpDb3B5cmlnaHQgKEMpIDIwMDUtMjAyMSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24sIEluYy4KQ29udHJpYnV0ZWQgYnkgUmVkIEhhdCwgSW5jLgoKVGhpcyBmaWxlIGlzIHBhcnQgb2YgdGhlIEdOVSBzaW11bGF0b3JzLgoKVGhpcyBwcm9ncmFtIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnkKaXQgdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBhcyBwdWJsaXNoZWQgYnkKdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbjsgZWl0aGVyIHZlcnNpb24gMyBvZiB0aGUgTGljZW5zZSwgb3IKKGF0IHlvdXIgb3B0aW9uKSBhbnkgbGF0ZXIgdmVyc2lvbi4KClRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLApidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZgpNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlCkdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGZvciBtb3JlIGRldGFpbHMuCgpZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZQphbG9uZyB3aXRoIHRoaXMgcHJvZ3JhbS4gIElmIG5vdCwgc2VlIDxodHRwOi8vd3d3LmdudS5vcmcvbGljZW5zZXMvPi4gICovCgovKiBUaGlzIG11c3QgY29tZSBiZWZvcmUgYW55IG90aGVyIGluY2x1ZGVzLiAgKi8KI2luY2x1ZGUgImRlZnMuaCIKCiNpbmNsdWRlIDxlcnJuby5oPgojaW5jbHVkZSA8c3RkaW8uaD4KI2luY2x1ZGUgPHN0ZGxpYi5oPgojaW5jbHVkZSA8c3RyaW5nLmg+CiNpbmNsdWRlIDxjdHlwZS5oPgojaW5jbHVkZSA8c3lzL3RpbWUuaD4KI2luY2x1ZGUgPHN5cy90eXBlcy5oPgojaW5jbHVkZSA8dW5pc3RkLmg+CiNpbmNsdWRlIDxzeXMvc2VsZWN0Lmg+CiNpZmRlZiBIQVZFX1RFUk1JT1NfSAojaW5jbHVkZSA8dGVybWlvcy5oPgojZW5kaWYKCiNpbmNsdWRlICJtZW0uaCIKI2luY2x1ZGUgImNwdS5oIgojaW5jbHVkZSAic3lzY2FsbHMuaCIKI2luY2x1ZGUgIm1pc2MuaCIKI2lmZGVmIFRJTUVSX0EKI2luY2x1ZGUgImludC5oIgojaW5jbHVkZSAidGltZXJfYS5oIgojZW5kaWYKCiNkZWZpbmUgTDFfQklUUyAgKDEwKQojZGVmaW5lIEwyX0JJVFMgICgxMCkKI2RlZmluZSBPRkZfQklUUyAoMTIpCgojZGVmaW5lIEwxX0xFTiAgKDEgPDwgTDFfQklUUykKI2RlZmluZSBMMl9MRU4gICgxIDw8IEwyX0JJVFMpCiNkZWZpbmUgT0ZGX0xFTiAoMSA8PCBPRkZfQklUUykKCnN0YXRpYyB1bnNpZ25lZCBjaGFyICoqcHRbTDFfTEVOXTsKCiNpZmRlZiBIQVZFX1RFUk1JT1NfSAppbnQgbTMyY19jb25zb2xlX2lmZCA9IDA7CiNlbmRpZgppbnQgbTMyY19jb25zb2xlX29mZCA9IDE7CiNpZmRlZiBIQVZFX1RFUk1JT1NfSAppbnQgbTMyY191c2VfcmF3X2NvbnNvbGUgPSAwOwojZW5kaWYKCiNpZmRlZiBUSU1FUl9BClRpbWVyX0EgdGltZXJfYTsKI2VuZGlmCgovKiBbIGdldD0wL3B1dD0xIF1bIGJ5dGUgc2l6ZSBdICovCnN0YXRpYyB1bnNpZ25lZCBpbnQgbWVtX2NvdW50ZXJzWzJdWzVdOwoKI2RlZmluZSBDT1VOVChpc3B1dCxieXRlcykgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKICBpZiAodmVyYm9zZSAmJiBlbmFibGVfY291bnRpbmcpIG1lbV9jb3VudGVyc1tpc3B1dF1bYnl0ZXNdKysKCnZvaWQKaW5pdF9tZW0gKHZvaWQpCnsKICBpbnQgaSwgajsKCiAgZm9yIChpID0gMDsgaSA8IEwxX0xFTjsgaSsrKQogICAgaWYgKHB0W2ldKQogICAgICB7Cglmb3IgKGogPSAwOyBqIDwgTDJfTEVOOyBqKyspCgkgIGlmIChwdFtpXVtqXSkKCSAgICBmcmVlIChwdFtpXVtqXSk7CglmcmVlIChwdFtpXSk7CiAgICAgIH0KICBtZW1zZXQgKHB0LCAwLCBzaXplb2YgKHB0KSk7CiAgbWVtc2V0IChtZW1fY291bnRlcnMsIDAsIHNpemVvZiAobWVtX2NvdW50ZXJzKSk7Cn0KCnN0YXRpYyB1bnNpZ25lZCBjaGFyICoKbWVtX3B0ciAoaW50IGFkZHJlc3MpCnsKICBzdGF0aWMgaW50IHJlY3Vyc2luZyA9IDA7CiAgaW50IHB0MSA9IChhZGRyZXNzID4+IChMMl9CSVRTICsgT0ZGX0JJVFMpKSAmICgoMSA8PCBMMV9CSVRTKSAtIDEpOwogIGludCBwdDIgPSAoYWRkcmVzcyA+PiBPRkZfQklUUykgJiAoKDEgPDwgTDJfQklUUykgLSAxKTsKICBpbnQgcHRvID0gYWRkcmVzcyAmICgoMSA8PCBPRkZfQklUUykgLSAxKTsKCiAgaWYgKGFkZHJlc3MgPT0gMCAmJiAhcmVjdXJzaW5nKQogICAgewogICAgICByZWN1cnNpbmcgPSAxOwogICAgICBwdXRfcmVnIChwYywgbTMyY19vcGNvZGVfcGMpOwogICAgICBwcmludGYgKCJOVUxMIHBvaW50ZXIgZGVyZWZlcmVuY2UgYXQgcGM9MHgleFxuIiwgZ2V0X3JlZyAocGMpKTsKICAgICAgc3RlcF9yZXN1bHQgPSBNMzJDX01BS0VfSElUX0JSRUFLICgpOwojaWYgMAogICAgICAvKiBUaGlzIGNvZGUgY2FuIGJlIHJlLWVuYWJsZWQgdG8gaGVscCBkaWFnbm9zZSBOVUxMIHBvaW50ZXIKICAgICAgICAgYnVncyB0aGF0IGFyZW4ndCBkZWJ1Z2dhYmxlIGluIEdEQi4gICovCiAgICAgIG0zMmNfZHVtcF9hbGxfcmVnaXN0ZXJzICgpOwogICAgICBleGl0ICgxKTsKI2VuZGlmCiAgICB9CgogIGlmIChwdFtwdDFdID09IDApCiAgICBwdFtwdDFdID0gKHVuc2lnbmVkIGNoYXIgKiopIGNhbGxvYyAoTDJfTEVOLCBzaXplb2YgKGNoYXIgKiopKTsKICBpZiAocHRbcHQxXVtwdDJdID09IDApCiAgICB7CiAgICAgIHB0W3B0MV1bcHQyXSA9ICh1bnNpZ25lZCBjaGFyICopIG1hbGxvYyAoT0ZGX0xFTik7CiAgICAgIG1lbXNldCAocHRbcHQxXVtwdDJdLCAwLCBPRkZfTEVOKTsKICAgIH0KCiAgcmV0dXJuIHB0W3B0MV1bcHQyXSArIHB0bzsKfQoKc3RhdGljIHZvaWQKdXNlZCAoaW50IHJzdGFydCwgaW50IGksIGludCBqKQp7CiAgaW50IHJlbmQgPSBpIDw8IChMMl9CSVRTICsgT0ZGX0JJVFMpOwogIHJlbmQgKz0gaiA8PCBPRkZfQklUUzsKICBpZiAocnN0YXJ0ID09IDB4ZTAwMDAgJiYgcmVuZCA9PSAweGUxMDAwKQogICAgcmV0dXJuOwogIHByaW50ZiAoIm1lbTogICAlMDh4IC0gJTA4eCAoJWRrIGJ5dGVzKVxuIiwgcnN0YXJ0LCByZW5kIC0gMSwKCSAgKHJlbmQgLSByc3RhcnQpIC8gMTAyNCk7Cn0KCnN0YXRpYyBjaGFyICoKbWNzIChpbnQgaXNwdXQsIGludCBieXRlcykKewogIHJldHVybiBjb21tYSAobWVtX2NvdW50ZXJzW2lzcHV0XVtieXRlc10pOwp9Cgp2b2lkCm1lbV91c2FnZV9zdGF0cyAodm9pZCkKewogIGludCBpLCBqOwogIGludCByc3RhcnQgPSAwOwogIGludCBwZW5kaW5nID0gMDsKCiAgZm9yIChpID0gMDsgaSA8IEwxX0xFTjsgaSsrKQogICAgaWYgKHB0W2ldKQogICAgICB7Cglmb3IgKGogPSAwOyBqIDwgTDJfTEVOOyBqKyspCgkgIGlmIChwdFtpXVtqXSkKCSAgICB7CgkgICAgICBpZiAoIXBlbmRpbmcpCgkJewoJCSAgcGVuZGluZyA9IDE7CgkJICByc3RhcnQgPSAoaSA8PCAoTDJfQklUUyArIE9GRl9CSVRTKSkgKyAoaiA8PCBPRkZfQklUUyk7CgkJfQoJICAgIH0KCSAgZWxzZSBpZiAocGVuZGluZykKCSAgICB7CgkgICAgICBwZW5kaW5nID0gMDsKCSAgICAgIHVzZWQgKHJzdGFydCwgaSwgaik7CgkgICAgfQogICAgICB9CiAgICBlbHNlCiAgICAgIHsKCWlmIChwZW5kaW5nKQoJICB7CgkgICAgcGVuZGluZyA9IDA7CgkgICAgdXNlZCAocnN0YXJ0LCBpLCAwKTsKCSAgfQogICAgICB9CiAgLyogICAgICAgbWVtIGZvbzogMTIzNDU2Nzg5MDEyIDEyMzQ1Njc4OTAxMiAxMjM0NTY3ODkwMTIgMTIzNDU2Nzg5MDEyCiAgICAgICAgICAgIDEyMzQ1Njc4OTAxMiAqLwogIHByaW50ZiAoIiAgICAgICAgICAgICAgICAgYnl0ZSAgICAgICAgc2hvcnQgICAgICBwb2ludGVyICAgICAgICAgbG9uZyIKCSAgIiAgICAgICAgZmV0Y2hcbiIpOwogIHByaW50ZiAoIm1lbSBnZXQ6ICUxMnMgJTEycyAlMTJzICUxMnMgJTEyc1xuIiwgbWNzICgwLCAxKSwgbWNzICgwLCAyKSwKCSAgbWNzICgwLCAzKSwgbWNzICgwLCA0KSwgbWNzICgwLCAwKSk7CiAgcHJpbnRmICgibWVtIHB1dDogJTEycyAlMTJzICUxMnMgJTEyc1xuIiwgbWNzICgxLCAxKSwgbWNzICgxLCAyKSwKCSAgbWNzICgxLCAzKSwgbWNzICgxLCA0KSk7Cn0KCnN0YXRpYyBpbnQgdHByID0gMDsKc3RhdGljIHZvaWQKcyAoaW50IGFkZHJlc3MsIGNoYXIgKmRpcikKewogIGlmICh0cHIgPT0gMCkKICAgIHByaW50ZiAoIk1FTVslMCp4XSAlcyIsIG1lbWJ1c19tYXNrID09IDB4ZmZmZmYgPyA1IDogNiwgYWRkcmVzcywgZGlyKTsKICB0cHIrKzsKfQoKI2RlZmluZSBTKGQpIGlmICh0cmFjZSkgcyhhZGRyZXNzLCBkKQpzdGF0aWMgdm9pZAplICh2b2lkKQp7CiAgaWYgKCF0cmFjZSkKICAgIHJldHVybjsKICB0cHItLTsKICBpZiAodHByID09IDApCiAgICBwcmludGYgKCJcbiIpOwp9CgojZGVmaW5lIEUoKSBpZiAodHJhY2UpIGUoKQoKZXh0ZXJuIGludCBtMzJjX2Rpc2Fzc2VtYmxlOwoKc3RhdGljIHZvaWQKbWVtX3B1dF9ieXRlIChpbnQgYWRkcmVzcywgdW5zaWduZWQgY2hhciB2YWx1ZSkKewogIHVuc2lnbmVkIGNoYXIgKm07CiAgYWRkcmVzcyAmPSBtZW1idXNfbWFzazsKICBtID0gbWVtX3B0ciAoYWRkcmVzcyk7CiAgaWYgKHRyYWNlKQogICAgcHJpbnRmICgiICUwMngiLCB2YWx1ZSk7CiAgKm0gPSB2YWx1ZTsKICBzd2l0Y2ggKGFkZHJlc3MpCiAgICB7CiAgICBjYXNlIDB4MDBlMToKICAgICAgewoJc3RhdGljIGludCBvbGRfbGVkID0gLTE7CglzdGF0aWMgY2hhciAqbGVkX29uW10gPQoJICB7ICJcMDMzWzMxbSBPICIsICJcMDMzWzMybSBPICIsICJcMDMzWzM0bSBPICIgfTsKCXN0YXRpYyBjaGFyICpsZWRfb2ZmW10gPSB7ICJcMDMzWzBtILcgIiwgIlwwMzNbMG0gtyAiLCAiXDAzM1swbSC3ICIgfTsKCWludCBpOwoJaWYgKG9sZF9sZWQgIT0gdmFsdWUpCgkgIHsKCSAgICBmcHV0cyAoIiAgIiwgc3Rkb3V0KTsKCSAgICBmb3IgKGkgPSAwOyBpIDwgMzsgaSsrKQoJICAgICAgaWYgKHZhbHVlICYgKDEgPDwgaSkpCgkJZnB1dHMgKGxlZF9vZmZbaV0sIHN0ZG91dCk7CgkgICAgICBlbHNlCgkJZnB1dHMgKGxlZF9vbltpXSwgc3Rkb3V0KTsKCSAgICBmcHV0cyAoIlwwMzNbMG1cciIsIHN0ZG91dCk7CgkgICAgZmZsdXNoIChzdGRvdXQpOwoJICAgIG9sZF9sZWQgPSB2YWx1ZTsKCSAgfQogICAgICB9CiAgICAgIGJyZWFrOwojaWZkZWYgVElNRVJfQQogICAgICAvKiBNMzJDIFRpbWVyIEEgKi8KICAgIGNhc2UgMHgzNDY6CQkvKiBUQTBsb3cgKi8KICAgICAgdGltZXJfYS5jb3VudCA9ICh0aW1lcl9hLmNvdW50ICYgMHhmZjAwKSB8IHZhbHVlOwogICAgICB0aW1lcl9hLnJlbG9hZCA9IHRpbWVyX2EuY291bnQ7CiAgICAgIGJyZWFrOwogICAgY2FzZSAweDM0NzoJCS8qIFRBMGhpZ2ggKi8KICAgICAgdGltZXJfYS5jb3VudCA9ICh0aW1lcl9hLmNvdW50ICYgMHgwMGZmKSB8ICh2YWx1ZSA8PCA4KTsKICAgICAgdGltZXJfYS5yZWxvYWQgPSB0aW1lcl9hLmNvdW50OwogICAgICBicmVhazsKICAgIGNhc2UgMHgzNDA6CQkvKiBUQUJTUiAqLwogICAgICB0aW1lcl9hLmJzciA9IHZhbHVlOwogICAgICBicmVhazsKICAgIGNhc2UgMHgzNTY6CQkvKiBUQTBNUiAqLwogICAgICB0aW1lcl9hLm1vZGUgPSB2YWx1ZTsKICAgICAgYnJlYWs7CiAgICBjYXNlIDB4MzVmOgkJLyogVENTUFIgKi8KICAgICAgdGltZXJfYS50Y3NwciA9IHZhbHVlOwogICAgICBicmVhazsKICAgIGNhc2UgMHgwMDZjOgkJLyogVEEwSUMgKi8KICAgICAgdGltZXJfYS5pYyA9IHZhbHVlOwogICAgICBicmVhazsKCiAgICAgIC8qIFI4QyBUaW1lciBSQSAqLwogICAgY2FzZSAweDEwMDoJCS8qIFRSQUNSICovCiAgICAgIHRpbWVyX2EuYnNyID0gdmFsdWU7CiAgICAgIGJyZWFrOwogICAgY2FzZSAweDEwMjoJCS8qIFRSQU1SICovCiAgICAgIHRpbWVyX2EubW9kZSA9IHZhbHVlOwogICAgICBicmVhazsKICAgIGNhc2UgMHgxMDQ6CQkvKiBUUkEgKi8KICAgICAgdGltZXJfYS5jb3VudCA9IHZhbHVlOwogICAgICB0aW1lcl9hLnJlbG9hZCA9IHZhbHVlOwogICAgICBicmVhazsKICAgIGNhc2UgMHgxMDM6CQkvKiBUUkFQUkUgKi8KICAgICAgdGltZXJfYS50Y3NwciA9IHZhbHVlOwogICAgICBicmVhazsKICAgIGNhc2UgMHgwMDU2OgkJLyogVEEwSUMgKi8KICAgICAgdGltZXJfYS5pYyA9IHZhbHVlOwogICAgICBicmVhazsKI2VuZGlmCgogICAgY2FzZSAweDJlYToJCS8qIG0zMmMgdWFydDF0eCAqLwogICAgY2FzZSAweDNhYToJCS8qIG0xNmMgdWFydDF0eCAqLwogICAgICB7CglzdGF0aWMgaW50IHBlbmRpbmdfZXhpdCA9IDA7CglpZiAodmFsdWUgPT0gMCkKCSAgewoJICAgIGlmIChwZW5kaW5nX2V4aXQpCgkgICAgICB7CgkJc3RlcF9yZXN1bHQgPSBNMzJDX01BS0VfRVhJVEVEICh2YWx1ZSk7CgkJcmV0dXJuOwoJICAgICAgfQoJICAgIHBlbmRpbmdfZXhpdCA9IDE7CgkgIH0KCWVsc2UKCSAgewoJICAgIGlmICh3cml0ZSAobTMyY19jb25zb2xlX29mZCwgJnZhbHVlLCAxKSAhPSAxKQoJICAgICAgcHJpbnRmICgid3JpdGUgY29uc29sZSBmYWlsZWQ6ICVzXG4iLCBzdHJlcnJvciAoZXJybm8pKTsKCSAgfQogICAgICB9CiAgICAgIGJyZWFrOwoKICAgIGNhc2UgMHg0MDA6CiAgICAgIG0zMmNfc3lzY2FsbCAodmFsdWUpOwogICAgICBicmVhazsKCiAgICBjYXNlIDB4NDAxOgogICAgICBwdXRjaGFyICh2YWx1ZSk7CiAgICAgIGJyZWFrOwoKICAgIGNhc2UgMHg0MDI6CiAgICAgIHByaW50ZiAoIlNpbVRyYWNlOiAlMDZseCAlMDJ4XG4iLCByZWdzLnJfcGMsIHZhbHVlKTsKICAgICAgYnJlYWs7CgogICAgY2FzZSAweDQwMzoKICAgICAgcHJpbnRmICgiU2ltVHJhcDogJTA2bHggJTAyeFxuIiwgcmVncy5yX3BjLCB2YWx1ZSk7CiAgICAgIGFib3J0ICgpOwogICAgfQp9Cgp2b2lkCm1lbV9wdXRfcWkgKGludCBhZGRyZXNzLCB1bnNpZ25lZCBjaGFyIHZhbHVlKQp7CiAgUyAoIjw9Iik7CiAgbWVtX3B1dF9ieXRlIChhZGRyZXNzLCB2YWx1ZSAmIDB4ZmYpOwogIEUgKCk7CiAgQ09VTlQgKDEsIDEpOwp9Cgp2b2lkCm1lbV9wdXRfaGkgKGludCBhZGRyZXNzLCB1bnNpZ25lZCBzaG9ydCB2YWx1ZSkKewogIGlmIChhZGRyZXNzID09IDB4NDAyKQogICAgewogICAgICBwcmludGYgKCJTaW1UcmFjZTogJTA2bHggJTA0eFxuIiwgcmVncy5yX3BjLCB2YWx1ZSk7CiAgICAgIHJldHVybjsKICAgIH0KICBTICgiPD0iKTsKICBtZW1fcHV0X2J5dGUgKGFkZHJlc3MsIHZhbHVlICYgMHhmZik7CiAgbWVtX3B1dF9ieXRlIChhZGRyZXNzICsgMSwgdmFsdWUgPj4gOCk7CiAgRSAoKTsKICBDT1VOVCAoMSwgMik7Cn0KCnZvaWQKbWVtX3B1dF9wc2kgKGludCBhZGRyZXNzLCB1bnNpZ25lZCBsb25nIHZhbHVlKQp7CiAgUyAoIjw9Iik7CiAgbWVtX3B1dF9ieXRlIChhZGRyZXNzLCB2YWx1ZSAmIDB4ZmYpOwogIG1lbV9wdXRfYnl0ZSAoYWRkcmVzcyArIDEsICh2YWx1ZSA+PiA4KSAmIDB4ZmYpOwogIG1lbV9wdXRfYnl0ZSAoYWRkcmVzcyArIDIsIHZhbHVlID4+IDE2KTsKICBFICgpOwogIENPVU5UICgxLCAzKTsKfQoKdm9pZAptZW1fcHV0X3NpIChpbnQgYWRkcmVzcywgdW5zaWduZWQgbG9uZyB2YWx1ZSkKewogIFMgKCI8PSIpOwogIG1lbV9wdXRfYnl0ZSAoYWRkcmVzcywgdmFsdWUgJiAweGZmKTsKICBtZW1fcHV0X2J5dGUgKGFkZHJlc3MgKyAxLCAodmFsdWUgPj4gOCkgJiAweGZmKTsKICBtZW1fcHV0X2J5dGUgKGFkZHJlc3MgKyAyLCAodmFsdWUgPj4gMTYpICYgMHhmZik7CiAgbWVtX3B1dF9ieXRlIChhZGRyZXNzICsgMywgKHZhbHVlID4+IDI0KSAmIDB4ZmYpOwogIEUgKCk7CiAgQ09VTlQgKDEsIDQpOwp9Cgp2b2lkCm1lbV9wdXRfYmxrIChpbnQgYWRkcmVzcywgY29uc3Qgdm9pZCAqYnVmcHRyLCBpbnQgbmJ5dGVzKQp7CiAgY29uc3QgdW5zaWduZWQgY2hhciAqYnVmID0gYnVmcHRyOwoKICBTICgiPD0iKTsKICBpZiAoZW5hYmxlX2NvdW50aW5nKQogICAgbWVtX2NvdW50ZXJzWzFdWzFdICs9IG5ieXRlczsKICB3aGlsZSAobmJ5dGVzLS0pCiAgICBtZW1fcHV0X2J5dGUgKGFkZHJlc3MrKywgKmJ1ZisrKTsKICBFICgpOwp9Cgp1bnNpZ25lZCBjaGFyCm1lbV9nZXRfcGMgKHZvaWQpCnsKICB1bnNpZ25lZCBjaGFyICptID0gbWVtX3B0ciAocmVncy5yX3BjICYgbWVtYnVzX21hc2spOwogIENPVU5UICgwLCAwKTsKICByZXR1cm4gKm07Cn0KCiNpZmRlZiBIQVZFX1RFUk1JT1NfSApzdGF0aWMgaW50IGNvbnNvbGVfcmF3ID0gMDsKc3RhdGljIHN0cnVjdCB0ZXJtaW9zIG9hdHRyOwoKc3RhdGljIGludApzdGRpbl9yZWFkeSAodm9pZCkKewogIGZkX3NldCBpZmQ7CiAgaW50IG47CiAgc3RydWN0IHRpbWV2YWwgdDsKCiAgdC50dl9zZWMgPSAwOwogIHQudHZfdXNlYyA9IDA7CiAgRkRfWkVSTyAoJmlmZCk7CiAgRkRfU0VUIChtMzJjX2NvbnNvbGVfaWZkLCAmaWZkKTsKICBuID0gc2VsZWN0ICgxLCAmaWZkLCAwLCAwLCAmdCk7CiAgcmV0dXJuIG4gPiAwOwp9Cgp2b2lkCm0zMmNfc2ltX3Jlc3RvcmVfY29uc29sZSAodm9pZCkKewogIGlmIChjb25zb2xlX3JhdykKICAgIHRjc2V0YXR0ciAobTMyY19jb25zb2xlX2lmZCwgVENTQU5PVywgJm9hdHRyKTsKICBjb25zb2xlX3JhdyA9IDA7Cn0KI2VuZGlmCgpzdGF0aWMgdW5zaWduZWQgY2hhcgptZW1fZ2V0X2J5dGUgKGludCBhZGRyZXNzKQp7CiAgdW5zaWduZWQgY2hhciAqbTsKICBhZGRyZXNzICY9IG1lbWJ1c19tYXNrOwogIG0gPSBtZW1fcHRyIChhZGRyZXNzKTsKICBzd2l0Y2ggKGFkZHJlc3MpCiAgICB7CiNpZmRlZiBIQVZFX1RFUk1JT1NfSAogICAgY2FzZSAweDJlZDoJCS8qIG0zMmMgdWFydDFjMSAqLwogICAgY2FzZSAweDNhZDoJCS8qIG0xNmMgdWFydDFjMSAqLwoKICAgICAgaWYgKCFjb25zb2xlX3JhdyAmJiBtMzJjX3VzZV9yYXdfY29uc29sZSkKCXsKCSAgc3RydWN0IHRlcm1pb3MgYXR0cjsKCSAgdGNnZXRhdHRyIChtMzJjX2NvbnNvbGVfaWZkLCAmYXR0cik7CgkgIHRjZ2V0YXR0ciAobTMyY19jb25zb2xlX2lmZCwgJm9hdHRyKTsKCSAgLyogV2Ugd2FudCBlYWNoIGtleSB0byBiZSBzZW50IGFzIHRoZSB1c2VyIHByZXNzZXMgdGhlbS4gICovCgkgIGF0dHIuY19sZmxhZyAmPSB+KElDQU5PTiB8IEVDSE8gfCBFQ0hPRSk7CgkgIHRjc2V0YXR0ciAobTMyY19jb25zb2xlX2lmZCwgVENTQU5PVywgJmF0dHIpOwoJICBjb25zb2xlX3JhdyA9IDE7CgkgIGF0ZXhpdCAobTMyY19zaW1fcmVzdG9yZV9jb25zb2xlKTsKCX0KCiAgICAgIGlmIChzdGRpbl9yZWFkeSAoKSkKCXJldHVybiAweDAyOwkJLyogdHggZW1wdHkgYW5kIHJ4IGZ1bGwgKi8KICAgICAgZWxzZQoJcmV0dXJuIDB4MGE7CQkvKiB0cmFuc21pdHRlciBlbXB0eSAqLwoKICAgIGNhc2UgMHgyZWU6CQkvKiBtMzJjIHVhcnQxIHJ4ICovCiAgICAgIHsKCWNoYXIgYzsKCWlmIChyZWFkIChtMzJjX2NvbnNvbGVfaWZkLCAmYywgMSkgIT0gMSkKCSAgcmV0dXJuIDA7CglpZiAobTMyY19jb25zb2xlX2lmZCA9PSAwICYmIGMgPT0gMykJLyogQ3RybC1DICovCgkgIHsKCSAgICBwcmludGYgKCJDdHJsLUMhXG4iKTsKCSAgICBleGl0ICgwKTsKCSAgfQoKCWlmIChtMzJjX2NvbnNvbGVfaWZkICE9IDEpCgkgIHsKCSAgICBpZiAoaXNncmFwaCAoYykpCgkgICAgICBwcmludGYgKCJcMDMzWzMxbSVjXDAzM1swbSIsIGMpOwoJICAgIGVsc2UKCSAgICAgIHByaW50ZiAoIlwwMzNbMzFtJTAyeFwwMzNbMG0iLCBjKTsKCSAgfQoJcmV0dXJuIGM7CiAgICAgIH0KI2VuZGlmCgojaWZkZWYgVElNRVJfQQogICAgY2FzZSAweDM0NjoJCS8qIFRBMGxvdyAqLwogICAgICByZXR1cm4gdGltZXJfYS5jb3VudCAmIDB4ZmY7CiAgICBjYXNlIDB4MzQ3OgkJLyogVEEwaGlnaCAqLwogICAgICByZXR1cm4gKHRpbWVyX2EuY291bnQgPj4gOCkgJiAweGZmOwogICAgY2FzZSAweDEwNDoJCS8qIFRSQSAqLwogICAgICByZXR1cm4gdGltZXJfYS5jb3VudDsKI2VuZGlmCgogICAgZGVmYXVsdDoKICAgICAgLyogSW4gY2FzZSBib3RoIGNhc2VzIGFib3ZlIGFyZSBub3QgaW5jbHVkZWQuICAqLwogICAgICA7CiAgICB9CgogIFMgKCI9PiIpOwogIGlmICh0cmFjZSkKICAgIHByaW50ZiAoIiAlMDJ4IiwgKm0pOwogIEUgKCk7CiAgcmV0dXJuICptOwp9Cgp1bnNpZ25lZCBjaGFyCm1lbV9nZXRfcWkgKGludCBhZGRyZXNzKQp7CiAgdW5zaWduZWQgY2hhciBydjsKICBTICgiPT4iKTsKICBydiA9IG1lbV9nZXRfYnl0ZSAoYWRkcmVzcyk7CiAgQ09VTlQgKDAsIDEpOwogIEUgKCk7CiAgcmV0dXJuIHJ2Owp9Cgp1bnNpZ25lZCBzaG9ydAptZW1fZ2V0X2hpIChpbnQgYWRkcmVzcykKewogIHVuc2lnbmVkIHNob3J0IHJ2OwogIFMgKCI9PiIpOwogIHJ2ID0gbWVtX2dldF9ieXRlIChhZGRyZXNzKTsKICBydiB8PSBtZW1fZ2V0X2J5dGUgKGFkZHJlc3MgKyAxKSAqIDI1NjsKICBDT1VOVCAoMCwgMik7CiAgRSAoKTsKICByZXR1cm4gcnY7Cn0KCnVuc2lnbmVkIGxvbmcKbWVtX2dldF9wc2kgKGludCBhZGRyZXNzKQp7CiAgdW5zaWduZWQgbG9uZyBydjsKICBTICgiPT4iKTsKICBydiA9IG1lbV9nZXRfYnl0ZSAoYWRkcmVzcyk7CiAgcnYgfD0gbWVtX2dldF9ieXRlIChhZGRyZXNzICsgMSkgKiAyNTY7CiAgcnYgfD0gbWVtX2dldF9ieXRlIChhZGRyZXNzICsgMikgKiA2NTUzNjsKICBDT1VOVCAoMCwgMyk7CiAgRSAoKTsKICByZXR1cm4gcnY7Cn0KCnVuc2lnbmVkIGxvbmcKbWVtX2dldF9zaSAoaW50IGFkZHJlc3MpCnsKICB1bnNpZ25lZCBsb25nIHJ2OwogIFMgKCI9PiIpOwogIHJ2ID0gbWVtX2dldF9ieXRlIChhZGRyZXNzKTsKICBydiB8PSBtZW1fZ2V0X2J5dGUgKGFkZHJlc3MgKyAxKSA8PCA4OwogIHJ2IHw9IG1lbV9nZXRfYnl0ZSAoYWRkcmVzcyArIDIpIDw8IDE2OwogIHJ2IHw9IG1lbV9nZXRfYnl0ZSAoYWRkcmVzcyArIDMpIDw8IDI0OwogIENPVU5UICgwLCA0KTsKICBFICgpOwogIHJldHVybiBydjsKfQoKdm9pZAptZW1fZ2V0X2JsayAoaW50IGFkZHJlc3MsIHZvaWQgKmJ1ZnB0ciwgaW50IG5ieXRlcykKewogIGNoYXIgKmJ1ZiA9IGJ1ZnB0cjsKCiAgUyAoIj0+Iik7CiAgaWYgKGVuYWJsZV9jb3VudGluZykKICAgIG1lbV9jb3VudGVyc1swXVsxXSArPSBuYnl0ZXM7CiAgd2hpbGUgKG5ieXRlcy0tKQogICAgKmJ1ZisrID0gbWVtX2dldF9ieXRlIChhZGRyZXNzKyspOwogIEUgKCk7Cn0KCmludApzaWduX2V4dCAoaW50IHYsIGludCBiaXRzKQp7CiAgaWYgKGJpdHMgPCAzMikKICAgIHsKICAgICAgdiAmPSAoMSA8PCBiaXRzKSAtIDE7CiAgICAgIGlmICh2ICYgKDEgPDwgKGJpdHMgLSAxKSkpCgl2IC09ICgxIDw8IGJpdHMpOwogICAgfQogIHJldHVybiB2Owp9CgojaWYgVElNRVJfQQp2b2lkCnVwZGF0ZV90aW1lcl9hICh2b2lkKQp7CiAgaWYgKHRpbWVyX2EuYnNyICYgMSkKICAgIHsKICAgICAgdGltZXJfYS5wcmVzY2FsZS0tOwogICAgICBpZiAodGltZXJfYS5wcmVzY2FsZSA8IDApCgl7CgkgIGlmIChBMjQpCgkgICAgewoJICAgICAgc3dpdGNoICh0aW1lcl9hLm1vZGUgJiAweGMwKQoJCXsKCQljYXNlIDB4MDA6CgkJICB0aW1lcl9hLnByZXNjYWxlID0gMDsKCQkgIGJyZWFrOwoJCWNhc2UgMHg0MDoKCQkgIHRpbWVyX2EucHJlc2NhbGUgPSA4OwoJCSAgYnJlYWs7CgkJY2FzZSAweDgwOgoJCSAgdGltZXJfYS5wcmVzY2FsZSA9IHRpbWVyX2EudGNzcHIgJiAweDBmOwoJCSAgYnJlYWs7CgkJY2FzZSAweGMwOgoJCSAgdGltZXJfYS5wcmVzY2FsZSA9IDMyOwoJCSAgYnJlYWs7CgkJfQoJICAgIH0KCSAgZWxzZQoJICAgIHsKCSAgICAgIHRpbWVyX2EucHJlc2NhbGUgPSB0aW1lcl9hLnRjc3ByOwoJICAgIH0KCSAgdGltZXJfYS5jb3VudC0tOwoJICBpZiAodGltZXJfYS5jb3VudCA8IDApCgkgICAgewoJICAgICAgdGltZXJfYS5jb3VudCA9IHRpbWVyX2EucmVsb2FkOwoJICAgICAgaWYgKHRpbWVyX2EuaWMgJiA3KQoJCXsKCQkgIGlmIChBMjQpCgkJICAgIG1lbV9wdXRfcWkgKDB4NmMsIHRpbWVyX2EuaWMgfCAweDA4KTsKCQkgIGVsc2UKCQkgICAgbWVtX3B1dF9xaSAoMHg1NiwgdGltZXJfYS5pYyB8IDB4MDgpOwoJCX0KCSAgICB9Cgl9CiAgICB9CgogIGlmIChyZWdzLnJfZmxhZ3MgJiBGTEFHQklUX0kJLyogaW50ZXJydXB0cyBlbmFibGVkICovCiAgICAgICYmIHRpbWVyX2EuaWMgJiAweDA4CS8qIHRpbWVyIEEgaW50ZXJydXB0IHRyaWdnZXJlZCAqLwogICAgICAmJiAodGltZXJfYS5pYyAmIDB4MDcpID4gKChyZWdzLnJfZmxhZ3MgPj4gMTIpICYgMHgwNykpCiAgICB7CiAgICAgIGlmIChBMjQpCgl0cmlnZ2VyX3BlcmlwaGVyYWxfaW50ZXJydXB0ICgxMiwgMHgwNmMpOwogICAgICBlbHNlCgl0cmlnZ2VyX3BlcmlwaGVyYWxfaW50ZXJydXB0ICgyMiwgMHgwNTYpOwogICAgfQp9CiNlbmRpZgo=