LyogbWVtLmMgLS0tIG1lbW9yeSBmb3IgTTMyQyBzaW11bGF0b3IuCgpDb3B5cmlnaHQgKEMpIDIwMDUsIDIwMDcsIDIwMDgsIDIwMDkgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCBJbmMuCkNvbnRyaWJ1dGVkIGJ5IFJlZCBIYXQsIEluYy4KClRoaXMgZmlsZSBpcyBwYXJ0IG9mIHRoZSBHTlUgc2ltdWxhdG9ycy4KClRoaXMgcHJvZ3JhbSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5Cml0IHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgYXMgcHVibGlzaGVkIGJ5CnRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb247IGVpdGhlciB2ZXJzaW9uIDMgb2YgdGhlIExpY2Vuc2UsIG9yCihhdCB5b3VyIG9wdGlvbikgYW55IGxhdGVyIHZlcnNpb24uCgpUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwKYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YKTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZQpHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBmb3IgbW9yZSBkZXRhaWxzLgoKWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UKYWxvbmcgd2l0aCB0aGlzIHByb2dyYW0uICBJZiBub3QsIHNlZSA8aHR0cDovL3d3dy5nbnUub3JnL2xpY2Vuc2VzLz4uICAqLwoKCiNpbmNsdWRlICJjb25maWcuaCIKI2luY2x1ZGUgPHN0ZGlvLmg+CiNpbmNsdWRlIDxzdGRsaWIuaD4KI2luY2x1ZGUgPHN0cmluZy5oPgojaW5jbHVkZSA8Y3R5cGUuaD4KI2luY2x1ZGUgPHN5cy90aW1lLmg+CiNpbmNsdWRlIDxzeXMvdHlwZXMuaD4KI2luY2x1ZGUgPHVuaXN0ZC5oPgojaWZkZWYgSEFWRV9TWVNfU0VMRUNUX0gKI2luY2x1ZGUgPHN5cy9zZWxlY3QuaD4KI2VuZGlmCiNpZmRlZiBIQVZFX1RFUk1JT1NfSAojaW5jbHVkZSA8dGVybWlvcy5oPgojZW5kaWYKCiNpbmNsdWRlICJtZW0uaCIKI2luY2x1ZGUgImNwdS5oIgojaW5jbHVkZSAic3lzY2FsbHMuaCIKI2luY2x1ZGUgIm1pc2MuaCIKI2lmZGVmIFRJTUVSX0EKI2luY2x1ZGUgImludC5oIgojaW5jbHVkZSAidGltZXJfYS5oIgojZW5kaWYKCiNkZWZpbmUgTDFfQklUUyAgKDEwKQojZGVmaW5lIEwyX0JJVFMgICgxMCkKI2RlZmluZSBPRkZfQklUUyAoMTIpCgojZGVmaW5lIEwxX0xFTiAgKDEgPDwgTDFfQklUUykKI2RlZmluZSBMMl9MRU4gICgxIDw8IEwyX0JJVFMpCiNkZWZpbmUgT0ZGX0xFTiAoMSA8PCBPRkZfQklUUykKCnN0YXRpYyB1bnNpZ25lZCBjaGFyICoqcHRbTDFfTEVOXTsKCiNpZmRlZiBIQVZFX1RFUk1JT1NfSAppbnQgbTMyY19jb25zb2xlX2lmZCA9IDA7CiNlbmRpZgppbnQgbTMyY19jb25zb2xlX29mZCA9IDE7CiNpZmRlZiBIQVZFX1RFUk1JT1NfSAppbnQgbTMyY191c2VfcmF3X2NvbnNvbGUgPSAwOwojZW5kaWYKCiNpZmRlZiBUSU1FUl9BClRpbWVyX0EgdGltZXJfYTsKI2VuZGlmCgovKiBbIGdldD0wL3B1dD0xIF1bIGJ5dGUgc2l6ZSBdICovCnN0YXRpYyB1bnNpZ25lZCBpbnQgbWVtX2NvdW50ZXJzWzJdWzVdOwoKI2RlZmluZSBDT1VOVChpc3B1dCxieXRlcykgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKICBpZiAodmVyYm9zZSAmJiBlbmFibGVfY291bnRpbmcpIG1lbV9jb3VudGVyc1tpc3B1dF1bYnl0ZXNdKysKCnZvaWQKaW5pdF9tZW0gKHZvaWQpCnsKICBpbnQgaSwgajsKCiAgZm9yIChpID0gMDsgaSA8IEwxX0xFTjsgaSsrKQogICAgaWYgKHB0W2ldKQogICAgICB7Cglmb3IgKGogPSAwOyBqIDwgTDJfTEVOOyBqKyspCgkgIGlmIChwdFtpXVtqXSkKCSAgICBmcmVlIChwdFtpXVtqXSk7CglmcmVlIChwdFtpXSk7CiAgICAgIH0KICBtZW1zZXQgKHB0LCAwLCBzaXplb2YgKHB0KSk7CiAgbWVtc2V0IChtZW1fY291bnRlcnMsIDAsIHNpemVvZiAobWVtX2NvdW50ZXJzKSk7Cn0KCnN0YXRpYyB1bnNpZ25lZCBjaGFyICoKbWVtX3B0ciAoYWRkcmVzcykKewogIHN0YXRpYyBpbnQgcmVjdXJzaW5nID0gMDsKICBpbnQgcHQxID0gKGFkZHJlc3MgPj4gKEwyX0JJVFMgKyBPRkZfQklUUykpICYgKCgxIDw8IEwxX0JJVFMpIC0gMSk7CiAgaW50IHB0MiA9IChhZGRyZXNzID4+IE9GRl9CSVRTKSAmICgoMSA8PCBMMl9CSVRTKSAtIDEpOwogIGludCBwdG8gPSBhZGRyZXNzICYgKCgxIDw8IE9GRl9CSVRTKSAtIDEpOwoKICBpZiAoYWRkcmVzcyA9PSAwICYmICFyZWN1cnNpbmcpCiAgICB7CiAgICAgIHJlY3Vyc2luZyA9IDE7CiAgICAgIHB1dF9yZWcgKHBjLCBtMzJjX29wY29kZV9wYyk7CiAgICAgIHByaW50ZiAoIk5VTEwgcG9pbnRlciBkZXJlZmVyZW5jZSBhdCBwYz0weCV4XG4iLCBnZXRfcmVnIChwYykpOwogICAgICBzdGVwX3Jlc3VsdCA9IE0zMkNfTUFLRV9ISVRfQlJFQUsgKCk7CiNpZiAwCiAgICAgIC8qIFRoaXMgY29kZSBjYW4gYmUgcmUtZW5hYmxlZCB0byBoZWxwIGRpYWdub3NlIE5VTEwgcG9pbnRlcgogICAgICAgICBidWdzIHRoYXQgYXJlbid0IGRlYnVnZ2FibGUgaW4gR0RCLiAgKi8KICAgICAgbTMyY19kdW1wX2FsbF9yZWdpc3RlcnMgKCk7CiAgICAgIGV4aXQgKDEpOwojZW5kaWYKICAgIH0KCiAgaWYgKHB0W3B0MV0gPT0gMCkKICAgIHB0W3B0MV0gPSAodW5zaWduZWQgY2hhciAqKikgY2FsbG9jIChMMl9MRU4sIHNpemVvZiAoY2hhciAqKikpOwogIGlmIChwdFtwdDFdW3B0Ml0gPT0gMCkKICAgIHsKICAgICAgcHRbcHQxXVtwdDJdID0gKHVuc2lnbmVkIGNoYXIgKikgbWFsbG9jIChPRkZfTEVOKTsKICAgICAgbWVtc2V0IChwdFtwdDFdW3B0Ml0sIDAsIE9GRl9MRU4pOwogICAgfQoKICByZXR1cm4gcHRbcHQxXVtwdDJdICsgcHRvOwp9CgpzdGF0aWMgdm9pZAp1c2VkIChpbnQgcnN0YXJ0LCBpbnQgaSwgaW50IGopCnsKICBpbnQgcmVuZCA9IGkgPDwgKEwyX0JJVFMgKyBPRkZfQklUUyk7CiAgcmVuZCArPSBqIDw8IE9GRl9CSVRTOwogIGlmIChyc3RhcnQgPT0gMHhlMDAwMCAmJiByZW5kID09IDB4ZTEwMDApCiAgICByZXR1cm47CiAgcHJpbnRmICgibWVtOiAgICUwOHggLSAlMDh4ICglZGsgYnl0ZXMpXG4iLCByc3RhcnQsIHJlbmQgLSAxLAoJICAocmVuZCAtIHJzdGFydCkgLyAxMDI0KTsKfQoKc3RhdGljIGNoYXIgKgptY3MgKGludCBpc3B1dCwgaW50IGJ5dGVzKQp7CiAgcmV0dXJuIGNvbW1hIChtZW1fY291bnRlcnNbaXNwdXRdW2J5dGVzXSk7Cn0KCnZvaWQKbWVtX3VzYWdlX3N0YXRzICgpCnsKICBpbnQgaSwgajsKICBpbnQgcnN0YXJ0ID0gMDsKICBpbnQgcGVuZGluZyA9IDA7CgogIGZvciAoaSA9IDA7IGkgPCBMMV9MRU47IGkrKykKICAgIGlmIChwdFtpXSkKICAgICAgewoJZm9yIChqID0gMDsgaiA8IEwyX0xFTjsgaisrKQoJICBpZiAocHRbaV1bal0pCgkgICAgewoJICAgICAgaWYgKCFwZW5kaW5nKQoJCXsKCQkgIHBlbmRpbmcgPSAxOwoJCSAgcnN0YXJ0ID0gKGkgPDwgKEwyX0JJVFMgKyBPRkZfQklUUykpICsgKGogPDwgT0ZGX0JJVFMpOwoJCX0KCSAgICB9CgkgIGVsc2UgaWYgKHBlbmRpbmcpCgkgICAgewoJICAgICAgcGVuZGluZyA9IDA7CgkgICAgICB1c2VkIChyc3RhcnQsIGksIGopOwoJICAgIH0KICAgICAgfQogICAgZWxzZQogICAgICB7CglpZiAocGVuZGluZykKCSAgewoJICAgIHBlbmRpbmcgPSAwOwoJICAgIHVzZWQgKHJzdGFydCwgaSwgMCk7CgkgIH0KICAgICAgfQogIC8qICAgICAgIG1lbSBmb286IDEyMzQ1Njc4OTAxMiAxMjM0NTY3ODkwMTIgMTIzNDU2Nzg5MDEyIDEyMzQ1Njc4OTAxMgogICAgICAgICAgICAxMjM0NTY3ODkwMTIgKi8KICBwcmludGYgKCIgICAgICAgICAgICAgICAgIGJ5dGUgICAgICAgIHNob3J0ICAgICAgcG9pbnRlciAgICAgICAgIGxvbmciCgkgICIgICAgICAgIGZldGNoXG4iKTsKICBwcmludGYgKCJtZW0gZ2V0OiAlMTJzICUxMnMgJTEycyAlMTJzICUxMnNcbiIsIG1jcyAoMCwgMSksIG1jcyAoMCwgMiksCgkgIG1jcyAoMCwgMyksIG1jcyAoMCwgNCksIG1jcyAoMCwgMCkpOwogIHByaW50ZiAoIm1lbSBwdXQ6ICUxMnMgJTEycyAlMTJzICUxMnNcbiIsIG1jcyAoMSwgMSksIG1jcyAoMSwgMiksCgkgIG1jcyAoMSwgMyksIG1jcyAoMSwgNCkpOwp9CgpzdGF0aWMgaW50IHRwciA9IDA7CnN0YXRpYyB2b2lkCnMgKGludCBhZGRyZXNzLCBjaGFyICpkaXIpCnsKICBpZiAodHByID09IDApCiAgICBwcmludGYgKCJNRU1bJTAqeF0gJXMiLCBtZW1idXNfbWFzayA9PSAweGZmZmZmID8gNSA6IDYsIGFkZHJlc3MsIGRpcik7CiAgdHByKys7Cn0KCiNkZWZpbmUgUyhkKSBpZiAodHJhY2UpIHMoYWRkcmVzcywgZCkKc3RhdGljIHZvaWQKZSAoKQp7CiAgaWYgKCF0cmFjZSkKICAgIHJldHVybjsKICB0cHItLTsKICBpZiAodHByID09IDApCiAgICBwcmludGYgKCJcbiIpOwp9CgojZGVmaW5lIEUoKSBpZiAodHJhY2UpIGUoKQoKZXh0ZXJuIGludCBtMzJjX2Rpc2Fzc2VtYmxlOwoKdm9pZAptZW1fcHV0X2J5dGUgKGludCBhZGRyZXNzLCB1bnNpZ25lZCBjaGFyIHZhbHVlKQp7CiAgdW5zaWduZWQgY2hhciAqbTsKICBhZGRyZXNzICY9IG1lbWJ1c19tYXNrOwogIG0gPSBtZW1fcHRyIChhZGRyZXNzKTsKICBpZiAodHJhY2UpCiAgICBwcmludGYgKCIgJTAyeCIsIHZhbHVlKTsKICAqbSA9IHZhbHVlOwogIHN3aXRjaCAoYWRkcmVzcykKICAgIHsKICAgIGNhc2UgMHgwMGUxOgogICAgICB7CglzdGF0aWMgaW50IG9sZF9sZWQgPSAtMTsKCXN0YXRpYyBjaGFyICpsZWRfb25bXSA9CgkgIHsgIlwwMzNbMzFtIE8gIiwgIlwwMzNbMzJtIE8gIiwgIlwwMzNbMzRtIE8gIiB9OwoJc3RhdGljIGNoYXIgKmxlZF9vZmZbXSA9IHsgIlwwMzNbMG0gtyAiLCAiXDAzM1swbSC3ICIsICJcMDMzWzBtILcgIiB9OwoJaW50IGk7CglpZiAob2xkX2xlZCAhPSB2YWx1ZSkKCSAgewoJICAgIGZwdXRzICgiICAiLCBzdGRvdXQpOwoJICAgIGZvciAoaSA9IDA7IGkgPCAzOyBpKyspCgkgICAgICBpZiAodmFsdWUgJiAoMSA8PCBpKSkKCQlmcHV0cyAobGVkX29mZltpXSwgc3Rkb3V0KTsKCSAgICAgIGVsc2UKCQlmcHV0cyAobGVkX29uW2ldLCBzdGRvdXQpOwoJICAgIGZwdXRzICgiXDAzM1swbVxyIiwgc3Rkb3V0KTsKCSAgICBmZmx1c2ggKHN0ZG91dCk7CgkgICAgb2xkX2xlZCA9IHZhbHVlOwoJICB9CiAgICAgIH0KICAgICAgYnJlYWs7CiNpZmRlZiBUSU1FUl9BCiAgICAgIC8qIE0zMkMgVGltZXIgQSAqLwogICAgY2FzZSAweDM0NjoJCS8qIFRBMGxvdyAqLwogICAgICB0aW1lcl9hLmNvdW50ID0gKHRpbWVyX2EuY291bnQgJiAweGZmMDApIHwgdmFsdWU7CiAgICAgIHRpbWVyX2EucmVsb2FkID0gdGltZXJfYS5jb3VudDsKICAgICAgYnJlYWs7CiAgICBjYXNlIDB4MzQ3OgkJLyogVEEwaGlnaCAqLwogICAgICB0aW1lcl9hLmNvdW50ID0gKHRpbWVyX2EuY291bnQgJiAweDAwZmYpIHwgKHZhbHVlIDw8IDgpOwogICAgICB0aW1lcl9hLnJlbG9hZCA9IHRpbWVyX2EuY291bnQ7CiAgICAgIGJyZWFrOwogICAgY2FzZSAweDM0MDoJCS8qIFRBQlNSICovCiAgICAgIHRpbWVyX2EuYnNyID0gdmFsdWU7CiAgICAgIGJyZWFrOwogICAgY2FzZSAweDM1NjoJCS8qIFRBME1SICovCiAgICAgIHRpbWVyX2EubW9kZSA9IHZhbHVlOwogICAgICBicmVhazsKICAgIGNhc2UgMHgzNWY6CQkvKiBUQ1NQUiAqLwogICAgICB0aW1lcl9hLnRjc3ByID0gdmFsdWU7CiAgICAgIGJyZWFrOwogICAgY2FzZSAweDAwNmM6CQkvKiBUQTBJQyAqLwogICAgICB0aW1lcl9hLmljID0gdmFsdWU7CiAgICAgIGJyZWFrOwoKICAgICAgLyogUjhDIFRpbWVyIFJBICovCiAgICBjYXNlIDB4MTAwOgkJLyogVFJBQ1IgKi8KICAgICAgdGltZXJfYS5ic3IgPSB2YWx1ZTsKICAgICAgYnJlYWs7CiAgICBjYXNlIDB4MTAyOgkJLyogVFJBTVIgKi8KICAgICAgdGltZXJfYS5tb2RlID0gdmFsdWU7CiAgICAgIGJyZWFrOwogICAgY2FzZSAweDEwNDoJCS8qIFRSQSAqLwogICAgICB0aW1lcl9hLmNvdW50ID0gdmFsdWU7CiAgICAgIHRpbWVyX2EucmVsb2FkID0gdmFsdWU7CiAgICAgIGJyZWFrOwogICAgY2FzZSAweDEwMzoJCS8qIFRSQVBSRSAqLwogICAgICB0aW1lcl9hLnRjc3ByID0gdmFsdWU7CiAgICAgIGJyZWFrOwogICAgY2FzZSAweDAwNTY6CQkvKiBUQTBJQyAqLwogICAgICB0aW1lcl9hLmljID0gdmFsdWU7CiAgICAgIGJyZWFrOwojZW5kaWYKCiAgICBjYXNlIDB4MmVhOgkJLyogbTMyYyB1YXJ0MXR4ICovCiAgICBjYXNlIDB4M2FhOgkJLyogbTE2YyB1YXJ0MXR4ICovCiAgICAgIHsKCXN0YXRpYyBpbnQgcGVuZGluZ19leGl0ID0gMDsKCWlmICh2YWx1ZSA9PSAwKQoJICB7CgkgICAgaWYgKHBlbmRpbmdfZXhpdCkKCSAgICAgIHsKCQlzdGVwX3Jlc3VsdCA9IE0zMkNfTUFLRV9FWElURUQgKHZhbHVlKTsKCQlyZXR1cm47CgkgICAgICB9CgkgICAgcGVuZGluZ19leGl0ID0gMTsKCSAgfQoJZWxzZQoJICB7CgkgICAgd3JpdGUgKG0zMmNfY29uc29sZV9vZmQsICZ2YWx1ZSwgMSk7CgkgIH0KICAgICAgfQogICAgICBicmVhazsKCiAgICBjYXNlIDB4NDAwOgogICAgICBtMzJjX3N5c2NhbGwgKHZhbHVlKTsKICAgICAgYnJlYWs7CgogICAgY2FzZSAweDQwMToKICAgICAgcHV0Y2hhciAodmFsdWUpOwogICAgICBicmVhazsKCiAgICBjYXNlIDB4NDAyOgogICAgICBwcmludGYgKCJTaW1UcmFjZTogJTA2bHggJTAyeFxuIiwgcmVncy5yX3BjLCB2YWx1ZSk7CiAgICAgIGJyZWFrOwoKICAgIGNhc2UgMHg0MDM6CiAgICAgIHByaW50ZiAoIlNpbVRyYXA6ICUwNmx4ICUwMnhcbiIsIHJlZ3Mucl9wYywgdmFsdWUpOwogICAgICBhYm9ydCAoKTsKICAgIH0KfQoKdm9pZAptZW1fcHV0X3FpIChpbnQgYWRkcmVzcywgdW5zaWduZWQgY2hhciB2YWx1ZSkKewogIFMgKCI8PSIpOwogIG1lbV9wdXRfYnl0ZSAoYWRkcmVzcywgdmFsdWUgJiAweGZmKTsKICBFICgpOwogIENPVU5UICgxLCAxKTsKfQoKdm9pZAptZW1fcHV0X2hpIChpbnQgYWRkcmVzcywgdW5zaWduZWQgc2hvcnQgdmFsdWUpCnsKICBpZiAoYWRkcmVzcyA9PSAweDQwMikKICAgIHsKICAgICAgcHJpbnRmICgiU2ltVHJhY2U6ICUwNmx4ICUwNHhcbiIsIHJlZ3Mucl9wYywgdmFsdWUpOwogICAgICByZXR1cm47CiAgICB9CiAgUyAoIjw9Iik7CiAgbWVtX3B1dF9ieXRlIChhZGRyZXNzLCB2YWx1ZSAmIDB4ZmYpOwogIG1lbV9wdXRfYnl0ZSAoYWRkcmVzcyArIDEsIHZhbHVlID4+IDgpOwogIEUgKCk7CiAgQ09VTlQgKDEsIDIpOwp9Cgp2b2lkCm1lbV9wdXRfcHNpIChpbnQgYWRkcmVzcywgdW5zaWduZWQgbG9uZyB2YWx1ZSkKewogIFMgKCI8PSIpOwogIG1lbV9wdXRfYnl0ZSAoYWRkcmVzcywgdmFsdWUgJiAweGZmKTsKICBtZW1fcHV0X2J5dGUgKGFkZHJlc3MgKyAxLCAodmFsdWUgPj4gOCkgJiAweGZmKTsKICBtZW1fcHV0X2J5dGUgKGFkZHJlc3MgKyAyLCB2YWx1ZSA+PiAxNik7CiAgRSAoKTsKICBDT1VOVCAoMSwgMyk7Cn0KCnZvaWQKbWVtX3B1dF9zaSAoaW50IGFkZHJlc3MsIHVuc2lnbmVkIGxvbmcgdmFsdWUpCnsKICBTICgiPD0iKTsKICBtZW1fcHV0X2J5dGUgKGFkZHJlc3MsIHZhbHVlICYgMHhmZik7CiAgbWVtX3B1dF9ieXRlIChhZGRyZXNzICsgMSwgKHZhbHVlID4+IDgpICYgMHhmZik7CiAgbWVtX3B1dF9ieXRlIChhZGRyZXNzICsgMiwgKHZhbHVlID4+IDE2KSAmIDB4ZmYpOwogIG1lbV9wdXRfYnl0ZSAoYWRkcmVzcyArIDMsICh2YWx1ZSA+PiAyNCkgJiAweGZmKTsKICBFICgpOwogIENPVU5UICgxLCA0KTsKfQoKdm9pZAptZW1fcHV0X2JsayAoaW50IGFkZHJlc3MsIHZvaWQgKmJ1ZnB0ciwgaW50IG5ieXRlcykKewogIFMgKCI8PSIpOwogIGlmIChlbmFibGVfY291bnRpbmcpCiAgICBtZW1fY291bnRlcnNbMV1bMV0gKz0gbmJ5dGVzOwogIHdoaWxlIChuYnl0ZXMtLSkKICAgIG1lbV9wdXRfYnl0ZSAoYWRkcmVzcysrLCAqKHVuc2lnbmVkIGNoYXIgKikgYnVmcHRyKyspOwogIEUgKCk7Cn0KCnVuc2lnbmVkIGNoYXIKbWVtX2dldF9wYyAoKQp7CiAgdW5zaWduZWQgY2hhciAqbSA9IG1lbV9wdHIgKHJlZ3Mucl9wYyAmIG1lbWJ1c19tYXNrKTsKICBDT1VOVCAoMCwgMCk7CiAgcmV0dXJuICptOwp9CgojaWZkZWYgSEFWRV9URVJNSU9TX0gKc3RhdGljIGludCBjb25zb2xlX3JhdyA9IDA7CnN0YXRpYyBzdHJ1Y3QgdGVybWlvcyBvYXR0cjsKCnN0YXRpYyBpbnQKc3RkaW5fcmVhZHkgKCkKewogIGZkX3NldCBpZmQ7CiAgaW50IG47CiAgc3RydWN0IHRpbWV2YWwgdDsKCiAgdC50dl9zZWMgPSAwOwogIHQudHZfdXNlYyA9IDA7CiAgRkRfWkVSTyAoJmlmZCk7CiAgRkRfU0VUIChtMzJjX2NvbnNvbGVfaWZkLCAmaWZkKTsKICBuID0gc2VsZWN0ICgxLCAmaWZkLCAwLCAwLCAmdCk7CiAgcmV0dXJuIG4gPiAwOwp9Cgp2b2lkCm0zMmNfc2ltX3Jlc3RvcmVfY29uc29sZSAoKQp7CiAgaWYgKGNvbnNvbGVfcmF3KQogICAgdGNzZXRhdHRyIChtMzJjX2NvbnNvbGVfaWZkLCBUQ1NBTk9XLCAmb2F0dHIpOwogIGNvbnNvbGVfcmF3ID0gMDsKfQojZW5kaWYKCnN0YXRpYyB1bnNpZ25lZCBjaGFyCm1lbV9nZXRfYnl0ZSAoaW50IGFkZHJlc3MpCnsKICB1bnNpZ25lZCBjaGFyICptOwogIGFkZHJlc3MgJj0gbWVtYnVzX21hc2s7CiAgbSA9IG1lbV9wdHIgKGFkZHJlc3MpOwogIHN3aXRjaCAoYWRkcmVzcykKICAgIHsKI2lmZGVmIEhBVkVfVEVSTUlPU19ICiAgICBjYXNlIDB4MmVkOgkJLyogbTMyYyB1YXJ0MWMxICovCiAgICBjYXNlIDB4M2FkOgkJLyogbTE2YyB1YXJ0MWMxICovCgogICAgICBpZiAoIWNvbnNvbGVfcmF3ICYmIG0zMmNfdXNlX3Jhd19jb25zb2xlKQoJewoJICBzdHJ1Y3QgdGVybWlvcyBhdHRyOwoJICB0Y2dldGF0dHIgKG0zMmNfY29uc29sZV9pZmQsICZhdHRyKTsKCSAgdGNnZXRhdHRyIChtMzJjX2NvbnNvbGVfaWZkLCAmb2F0dHIpOwoJICAvKiBXZSB3YW50IGVhY2gga2V5IHRvIGJlIHNlbnQgYXMgdGhlIHVzZXIgcHJlc3NlcyB0aGVtLiAgKi8KCSAgYXR0ci5jX2xmbGFnICY9IH4oSUNBTk9OIHwgRUNITyB8IEVDSE9FKTsKCSAgdGNzZXRhdHRyIChtMzJjX2NvbnNvbGVfaWZkLCBUQ1NBTk9XLCAmYXR0cik7CgkgIGNvbnNvbGVfcmF3ID0gMTsKCSAgYXRleGl0IChtMzJjX3NpbV9yZXN0b3JlX2NvbnNvbGUpOwoJfQoKICAgICAgaWYgKHN0ZGluX3JlYWR5ICgpKQoJcmV0dXJuIDB4MDI7CQkvKiB0eCBlbXB0eSBhbmQgcnggZnVsbCAqLwogICAgICBlbHNlCglyZXR1cm4gMHgwYTsJCS8qIHRyYW5zbWl0dGVyIGVtcHR5ICovCgogICAgY2FzZSAweDJlZToJCS8qIG0zMmMgdWFydDEgcnggKi8KICAgICAgewoJY2hhciBjOwoJcmVhZCAobTMyY19jb25zb2xlX2lmZCwgJmMsIDEpOwoJaWYgKG0zMmNfY29uc29sZV9pZmQgPT0gMCAmJiBjID09IDMpCS8qIEN0cmwtQyAqLwoJICB7CgkgICAgcHJpbnRmICgiQ3RybC1DIVxuIik7CgkgICAgZXhpdCAoMCk7CgkgIH0KCglpZiAobTMyY19jb25zb2xlX2lmZCAhPSAxKQoJICB7CgkgICAgaWYgKGlzZ3JhcGggKGMpKQoJICAgICAgcHJpbnRmICgiXDAzM1szMW0lY1wwMzNbMG0iLCBjKTsKCSAgICBlbHNlCgkgICAgICBwcmludGYgKCJcMDMzWzMxbSUwMnhcMDMzWzBtIiwgYyk7CgkgIH0KCXJldHVybiBjOwogICAgICB9CiNlbmRpZgoKI2lmZGVmIFRJTUVSX0EKICAgIGNhc2UgMHgzNDY6CQkvKiBUQTBsb3cgKi8KICAgICAgcmV0dXJuIHRpbWVyX2EuY291bnQgJiAweGZmOwogICAgY2FzZSAweDM0NzoJCS8qIFRBMGhpZ2ggKi8KICAgICAgcmV0dXJuICh0aW1lcl9hLmNvdW50ID4+IDgpICYgMHhmZjsKICAgIGNhc2UgMHgxMDQ6CQkvKiBUUkEgKi8KICAgICAgcmV0dXJuIHRpbWVyX2EuY291bnQ7CiNlbmRpZgoKICAgIGRlZmF1bHQ6CiAgICAgIC8qIEluIGNhc2UgYm90aCBjYXNlcyBhYm92ZSBhcmUgbm90IGluY2x1ZGVkLiAgKi8KICAgICAgOwogICAgfQoKICBTICgiPT4iKTsKICBpZiAodHJhY2UpCiAgICBwcmludGYgKCIgJTAyeCIsICptKTsKICBFICgpOwogIHJldHVybiAqbTsKfQoKdW5zaWduZWQgY2hhcgptZW1fZ2V0X3FpIChpbnQgYWRkcmVzcykKewogIHVuc2lnbmVkIGNoYXIgcnY7CiAgUyAoIj0+Iik7CiAgcnYgPSBtZW1fZ2V0X2J5dGUgKGFkZHJlc3MpOwogIENPVU5UICgwLCAxKTsKICBFICgpOwogIHJldHVybiBydjsKfQoKdW5zaWduZWQgc2hvcnQKbWVtX2dldF9oaSAoaW50IGFkZHJlc3MpCnsKICB1bnNpZ25lZCBzaG9ydCBydjsKICBTICgiPT4iKTsKICBydiA9IG1lbV9nZXRfYnl0ZSAoYWRkcmVzcyk7CiAgcnYgfD0gbWVtX2dldF9ieXRlIChhZGRyZXNzICsgMSkgKiAyNTY7CiAgQ09VTlQgKDAsIDIpOwogIEUgKCk7CiAgcmV0dXJuIHJ2Owp9Cgp1bnNpZ25lZCBsb25nCm1lbV9nZXRfcHNpIChpbnQgYWRkcmVzcykKewogIHVuc2lnbmVkIGxvbmcgcnY7CiAgUyAoIj0+Iik7CiAgcnYgPSBtZW1fZ2V0X2J5dGUgKGFkZHJlc3MpOwogIHJ2IHw9IG1lbV9nZXRfYnl0ZSAoYWRkcmVzcyArIDEpICogMjU2OwogIHJ2IHw9IG1lbV9nZXRfYnl0ZSAoYWRkcmVzcyArIDIpICogNjU1MzY7CiAgQ09VTlQgKDAsIDMpOwogIEUgKCk7CiAgcmV0dXJuIHJ2Owp9Cgp1bnNpZ25lZCBsb25nCm1lbV9nZXRfc2kgKGludCBhZGRyZXNzKQp7CiAgdW5zaWduZWQgbG9uZyBydjsKICBTICgiPT4iKTsKICBydiA9IG1lbV9nZXRfYnl0ZSAoYWRkcmVzcyk7CiAgcnYgfD0gbWVtX2dldF9ieXRlIChhZGRyZXNzICsgMSkgPDwgODsKICBydiB8PSBtZW1fZ2V0X2J5dGUgKGFkZHJlc3MgKyAyKSA8PCAxNjsKICBydiB8PSBtZW1fZ2V0X2J5dGUgKGFkZHJlc3MgKyAzKSA8PCAyNDsKICBDT1VOVCAoMCwgNCk7CiAgRSAoKTsKICByZXR1cm4gcnY7Cn0KCnZvaWQKbWVtX2dldF9ibGsgKGludCBhZGRyZXNzLCB2b2lkICpidWZwdHIsIGludCBuYnl0ZXMpCnsKICBTICgiPT4iKTsKICBpZiAoZW5hYmxlX2NvdW50aW5nKQogICAgbWVtX2NvdW50ZXJzWzBdWzFdICs9IG5ieXRlczsKICB3aGlsZSAobmJ5dGVzLS0pCiAgICAqKGNoYXIgKikgYnVmcHRyKysgPSBtZW1fZ2V0X2J5dGUgKGFkZHJlc3MrKyk7CiAgRSAoKTsKfQoKaW50CnNpZ25fZXh0IChpbnQgdiwgaW50IGJpdHMpCnsKICBpZiAoYml0cyA8IDMyKQogICAgewogICAgICB2ICY9ICgxIDw8IGJpdHMpIC0gMTsKICAgICAgaWYgKHYgJiAoMSA8PCAoYml0cyAtIDEpKSkKCXYgLT0gKDEgPDwgYml0cyk7CiAgICB9CiAgcmV0dXJuIHY7Cn0KCiNpZiBUSU1FUl9BCnZvaWQKdXBkYXRlX3RpbWVyX2EgKCkKewogIGlmICh0aW1lcl9hLmJzciAmIDEpCiAgICB7CiAgICAgIHRpbWVyX2EucHJlc2NhbGUtLTsKICAgICAgaWYgKHRpbWVyX2EucHJlc2NhbGUgPCAwKQoJewoJICBpZiAoQTI0KQoJICAgIHsKCSAgICAgIHN3aXRjaCAodGltZXJfYS5tb2RlICYgMHhjMCkKCQl7CgkJY2FzZSAweDAwOgoJCSAgdGltZXJfYS5wcmVzY2FsZSA9IDA7CgkJICBicmVhazsKCQljYXNlIDB4NDA6CgkJICB0aW1lcl9hLnByZXNjYWxlID0gODsKCQkgIGJyZWFrOwoJCWNhc2UgMHg4MDoKCQkgIHRpbWVyX2EucHJlc2NhbGUgPSB0aW1lcl9hLnRjc3ByICYgMHgwZjsKCQkgIGJyZWFrOwoJCWNhc2UgMHhjMDoKCQkgIHRpbWVyX2EucHJlc2NhbGUgPSAzMjsKCQkgIGJyZWFrOwoJCX0KCSAgICB9CgkgIGVsc2UKCSAgICB7CgkgICAgICB0aW1lcl9hLnByZXNjYWxlID0gdGltZXJfYS50Y3NwcjsKCSAgICB9CgkgIHRpbWVyX2EuY291bnQtLTsKCSAgaWYgKHRpbWVyX2EuY291bnQgPCAwKQoJICAgIHsKCSAgICAgIHRpbWVyX2EuY291bnQgPSB0aW1lcl9hLnJlbG9hZDsKCSAgICAgIGlmICh0aW1lcl9hLmljICYgNykKCQl7CgkJICBpZiAoQTI0KQoJCSAgICBtZW1fcHV0X3FpICgweDZjLCB0aW1lcl9hLmljIHwgMHgwOCk7CgkJICBlbHNlCgkJICAgIG1lbV9wdXRfcWkgKDB4NTYsIHRpbWVyX2EuaWMgfCAweDA4KTsKCQl9CgkgICAgfQoJfQogICAgfQoKICBpZiAocmVncy5yX2ZsYWdzICYgRkxBR0JJVF9JCS8qIGludGVycnVwdHMgZW5hYmxlZCAqLwogICAgICAmJiB0aW1lcl9hLmljICYgMHgwOAkvKiB0aW1lciBBIGludGVycnVwdCB0cmlnZ2VyZWQgKi8KICAgICAgJiYgKHRpbWVyX2EuaWMgJiAweDA3KSA+ICgocmVncy5yX2ZsYWdzID4+IDEyKSAmIDB4MDcpKQogICAgewogICAgICBpZiAoQTI0KQoJdHJpZ2dlcl9wZXJpcGhlcmFsX2ludGVycnVwdCAoMTIsIDB4MDZjKTsKICAgICAgZWxzZQoJdHJpZ2dlcl9wZXJpcGhlcmFsX2ludGVycnVwdCAoMjIsIDB4MDU2KTsKICAgIH0KfQojZW5kaWYK