LyoKICogTW9zdGx5IGRvbmUgYWZ0ZXIgdGhlIFNjaXRlY2ggQmlvcyBlbXVsYXRpb24KICogV3JpdHRlbiBieSBIYW5zLUr2cmcgRnJpZWRlbgogKiBIeXBlcmlvbiBFbnRlcnRhaW5tZW50CiAqLwojaW5jbHVkZSA8Y29tbW9uLmg+CiNpbmNsdWRlICJzY2l0ZWNoL2luY2x1ZGUveDg2ZW11L3g4NmVtdS5oIgojaW5jbHVkZSAiZ2x1ZS5oIgojaW5jbHVkZSAic2NpdGVjaC9pbmNsdWRlL3g4NmVtdS9yZWdzLmgiCiNpbmNsdWRlICJ4ODZpbnRlcmZhY2UuaCIKCiN1bmRlZiBERUJVRwoKI2lmZGVmIERFQlVHCiNkZWZpbmUgUFJJTlRGKGZtdCwgYXJncy4uLikgcHJpbnRmKGZtdCwgIyMgYXJncykKI2Vsc2UKI2RlZmluZSBQUklOVEYoZm10LCBhcmdzLi4uKQojZW5kaWYKCiNkZWZpbmUgQklPU19TRUcgMHhGRkYwCiNkZWZpbmUgUENJQklPU19TVUNDRVNTRlVMIDAKI2RlZmluZSBQQ0lCSU9TX0RFVklDRV9OT1RfRk9VTkQgMHg4NgoKdHlwZWRlZiB1bnNpZ25lZCBjaGFyIFVCWVRFOwp0eXBlZGVmIHVuc2lnbmVkIHNob3J0IFVXT1JEOwp0eXBlZGVmIHVuc2lnbmVkIGxvbmcgVUxPTkc7Cgp0eXBlZGVmIGNoYXIgQllURTsKdHlwZWRlZiBzaG9ydCBXT1JUOwp0eXBlZGVmIGxvbmcgTE9ORzsKCi8vI2RlZmluZSBwb3J0X3RvX21lbShmcm9tKSAoQ0ZHX0lTQV9JT19CQVNFX0FERFJFU1N8KGZyb20pKQovKgojZGVmaW5lIGluX2J5dGUoZnJvbSkgaW44KCAoVUJZVEUgKilwb3J0X3RvX21lbShmcm9tKSkKI2RlZmluZSBpbl93b3JkKGZyb20pIGluMTZyKChVV09SRCAqKXBvcnRfdG9fbWVtKGZyb20pKQojZGVmaW5lIGluX2xvbmcoZnJvbSkgaW4zMnIoVUxPTkcgKilwb3J0X3RvX21lbShmcm9tKSkKI2RlZmluZSBvdXRfYnl0ZSh0bywgdmFsKSBvdXQ4KChVQllURSAqKXBvcnRfdG9fbWVtKHRvKSwgdmFsKQojZGVmaW5lIG91dF93b3JkKHRvLCB2YWwpIG91dDE2cigoVVdPUkQgKilwb3J0X3RvX21lbSh0byksIHZhbCkKI2RlZmluZSBvdXRfbG9uZyh0bywgdmFsKSBvdXQzMnIoKFVMT05HICopcG9ydF90b19tZW0odG8pLCB2YWwpCiovCgojZGVmaW5lIG91dF9ieXRlKHRvLCB2YWwpIG91dDgoKFVCWVRFICopcG9ydF90b19tZW0odG8pLCB2YWwpCgpzdGF0aWMgdm9pZCBYODZBUEkgdW5kZWZpbmVkX2ludHIoaW50IGludG5vKQp7CiAgICBQUklOVEYoIlg4NkFQSSB1bmRlZmluZWRfaW50clxuIik7CiAgICAKICAgIGV4dGVybiB1MTYgQTFfcmR3KHUzMiBhZGRyKTsKICAgIGlmIChBMV9yZHcoaW50bm8gKiA0ICsgMikgPT0gQklPU19TRUcpCiAgICB7CiAgICAJUFJJTlRGKCJVbmRlZmluZWQgaW50ZXJydXB0IDB4JXggY2FsbGVkIEFYID0gMHgleCwgQlggPSAweCV4LCBDWCA9IDB4JXgsIERYID0gMHgleFxuIiwKICAgIAkgICBpbnRubywgTS54ODYuUl9BWCwgTS54ODYuUl9CWCwgTS54ODYuUl9DWCwgTS54ODYuUl9EWCk7CiAgICAJWDg2RU1VX2hhbHRfc3lzKCk7CiAgICB9CiAgICBlbHNlCiAgICB7CiAgICAJUFJJTlRGKCJDYWxsaW5nIGludGVycnVwdCAleGgsIEFMPSV4aCwgQUg9JXhoXG4iLCBpbnRubywgTS54ODYuUl9BTCwgTS54ODYuUl9BSCk7CiAgICAJWDg2RU1VX3ByZXBhcmVGb3JJbnQoaW50bm8pOwogICAgfQp9CgpzdGF0aWMgdm9pZCBYODZBUEkgaW50NDIoaW50IGludG5vKTsKc3RhdGljIHZvaWQgWDg2QVBJIGludDE1KGludCBpbnRubyk7CgpzdGF0aWMgdm9pZCBYODZBUEkgaW50MTAoaW50IGludG5vKQp7CiAgICBQUklOVEYoIlg4NkFQSSBpbnQxMFxuIik7CgogICAgaWYgKEExX3JkdyhpbnRubyo0KzIpID09IEJJT1NfU0VHKQogICAgCWludDQyKGludG5vKTsKICAgIGVsc2UKICAgIHsKICAgIAlQUklOVEYoImludDEwOiBicmFuY2hpbmcgdG8gJTA0WDolMDRYLCBBTD0leGgsIEFIPSV4aFxuIiwgQTFfcmR3KGludG5vKjQrMiksIEExX3JkdyhpbnRubyo0KSwKCSAgICAgICBNLng4Ni5SX0FMLCBNLng4Ni5SX0FIKTsKICAgIAlYODZFTVVfcHJlcGFyZUZvckludChpbnRubyk7CiAgICB9Cn0KCnN0YXRpYyB2b2lkIFg4NkFQSSBpbnQxQShpbnQgaW50bm8pCnsKICAgIFBSSU5URigiWDg2QVBJIGludDFBXG4iKTsKCiAgICBpbnQgZGV2aWNlOwogICAgCiAgICBzd2l0Y2goTS54ODYuUl9BWCkKICAgIHsKICAgIGNhc2UgMHhCMTAxOiAvLyBQQ0kgQmlvcyBQcmVzZW50PwogICAgICAgCU0ueDg2LlJfQUwgID0gMHgwMDsKICAgIAlNLng4Ni5SX0VEWCA9IDB4MjA0OTQzNTA7CiAgICAJTS54ODYuUl9CWCAgPSAweDAyMTA7CiAgICAJTS54ODYuUl9DTCAgPSAzOwogICAgCUNMRUFSX0ZMQUcoRl9DRik7CiAgICAJYnJlYWs7CiAgICBjYXNlIDB4QjEwMjogLy8gRmluZCBkZXZpY2UKICAgIAlkZXZpY2UgPSBteXBjaV9maW5kX2RldmljZShNLng4Ni5SX0RYLCBNLng4Ni5SX0NYLCBNLng4Ni5SX1NJKTsKICAgIAlpZiAoZGV2aWNlICE9IC0xKQogICAgCXsKICAgIAkgICAgTS54ODYuUl9BSCA9IFBDSUJJT1NfU1VDQ0VTU0ZVTDsKICAgIAkgICAgTS54ODYuUl9CSCA9IG15cGNpX2J1cyhkZXZpY2UpOwogICAgCSAgICBNLng4Ni5SX0JMID0gbXlwY2lfZGV2Zm4oZGV2aWNlKTsKICAgIAl9CiAgICAJZWxzZQogICAgCXsKICAgIAkgICAgTS54ODYuUl9BSCA9IFBDSUJJT1NfREVWSUNFX05PVF9GT1VORDsKICAgIAl9CiAgICAJQ09ORElUSU9OQUxfU0VUX0ZMQUcoKE0ueDg2LlJfQUggIT0gUENJQklPU19TVUNDRVNTRlVMKSwgRl9DRik7CiAgICAJYnJlYWs7CiAgICBjYXNlIDB4QjEwMzogLy8gRmluZCBQQ0kgY2xhc3MgY29kZQogICAgCU0ueDg2LlJfQUggPSBQQ0lCSU9TX0RFVklDRV9OT1RfRk9VTkQ7CiAgICAJcHJpbnRmKCJGaW5kIGJ5IGNsYXNzIG5vdCB5ZXQgaW1wbG1lbnRlZCIpOwogICAgCUNPTkRJVElPTkFMX1NFVF9GTEFHKChNLng4Ni5SX0FIICE9IFBDSUJJT1NfU1VDQ0VTU0ZVTCksIEZfQ0YpOwogICAgCWJyZWFrOwogICAgY2FzZSAweEIxMDg6IC8vIHJlYWQgY29uZmlnIGJ5dGUKICAgIAlNLng4Ni5SX0NMID0gbXlwY2lfcmVhZF9jZmdfYnl0ZShNLng4Ni5SX0JILCBNLng4Ni5SX0JMLCBNLng4Ni5SX0RJKTsKICAgIAlNLng4Ni5SX0FIID0gUENJQklPU19TVUNDRVNTRlVMOwogICAgCUNPTkRJVElPTkFMX1NFVF9GTEFHKChNLng4Ni5SX0FIICE9IFBDSUJJT1NfU1VDQ0VTU0ZVTCksIEZfQ0YpOwogICAgCVBSSU5URigicmVhZF9jb25maWdfYnl0ZSAleCwleCwleCAtPiAleFxuIiwgTS54ODYuUl9CSCwgTS54ODYuUl9CTCwgTS54ODYuUl9ESSwgTS54ODYuUl9DTCk7CiAgICAJYnJlYWs7CiAgICBjYXNlIDB4QjEwOTogLy8gcmVhZCBjb25maWcgd29yZAogICAgCU0ueDg2LlJfQ1ggPSBteXBjaV9yZWFkX2NmZ193b3JkKE0ueDg2LlJfQkgsIE0ueDg2LlJfQkwsIE0ueDg2LlJfREkpOwogICAgCU0ueDg2LlJfQUggPSBQQ0lCSU9TX1NVQ0NFU1NGVUw7CiAgICAJQ09ORElUSU9OQUxfU0VUX0ZMQUcoKE0ueDg2LlJfQUggIT0gUENJQklPU19TVUNDRVNTRlVMKSwgRl9DRik7CiAgICAJUFJJTlRGKCJyZWFkX2NvbmZpZ193b3JkICV4LCV4LCV4IC0+ICV4XG4iLCBNLng4Ni5SX0JILCBNLng4Ni5SX0JMLCBNLng4Ni5SX0RJLCBNLng4Ni5SX0NYKTsKICAgIAlicmVhazsKICAgIGNhc2UgMHhCMTBBOiAvLyByZWFkIGNvbmZpZyBkd29yZAogICAgCU0ueDg2LlJfRUNYID0gbXlwY2lfcmVhZF9jZmdfbG9uZyhNLng4Ni5SX0JILCBNLng4Ni5SX0JMLCBNLng4Ni5SX0RJKTsKICAgIAlNLng4Ni5SX0FIID0gUENJQklPU19TVUNDRVNTRlVMOwogICAgCUNPTkRJVElPTkFMX1NFVF9GTEFHKChNLng4Ni5SX0FIICE9IFBDSUJJT1NfU1VDQ0VTU0ZVTCksIEZfQ0YpOwogICAgCVBSSU5URigicmVhZF9jb25maWdfbG9uZyAleCwleCwleCAtPiAleFxuIiwgTS54ODYuUl9CSCwgTS54ODYuUl9CTCwgTS54ODYuUl9ESSwgTS54ODYuUl9FQ1gpOwogICAgCWJyZWFrOwogICAgY2FzZSAweEIxMEI6IC8vIHdyaXRlIGNvbmZpZyBieXRlCiAgICAJbXlwY2lfd3JpdGVfY2ZnX2J5dGUoTS54ODYuUl9CSCwgTS54ODYuUl9CTCwgTS54ODYuUl9ESSwgTS54ODYuUl9DTCk7CiAgICAJTS54ODYuUl9BSCA9IFBDSUJJT1NfU1VDQ0VTU0ZVTDsKICAgIAlDT05ESVRJT05BTF9TRVRfRkxBRygoTS54ODYuUl9BSCAhPSBQQ0lCSU9TX1NVQ0NFU1NGVUwpLCBGX0NGKTsKICAgIAlQUklOVEYoIndyaXRlX2NvbmZpZ19ieXRlICV4LCV4LCV4IDwtICV4XG4iLCBNLng4Ni5SX0JILCBNLng4Ni5SX0JMLCBNLng4Ni5SX0RJLCBNLng4Ni5SX0NMKTsKICAgIAlicmVhazsKICAgIGNhc2UgMHhCMTBDOiAvLyB3cml0ZSBjb25maWcgd29yZAogICAgCW15cGNpX3dyaXRlX2NmZ193b3JkKE0ueDg2LlJfQkgsIE0ueDg2LlJfQkwsIE0ueDg2LlJfREksIE0ueDg2LlJfQ1gpOwogICAgCU0ueDg2LlJfQUggPSBQQ0lCSU9TX1NVQ0NFU1NGVUw7CiAgICAJQ09ORElUSU9OQUxfU0VUX0ZMQUcoKE0ueDg2LlJfQUggIT0gUENJQklPU19TVUNDRVNTRlVMKSwgRl9DRik7CiAgICAJUFJJTlRGKCJ3cml0ZV9jb25maWdfd29yZCAleCwleCwleCA8LSAleFxuIiwgTS54ODYuUl9CSCwgTS54ODYuUl9CTCwgTS54ODYuUl9ESSwgTS54ODYuUl9DWCk7CiAgICAJYnJlYWs7CiAgICBjYXNlIDB4QjEwRDogLy8gd3JpdGUgY29uZmlnIGR3b3JkCiAgICAJbXlwY2lfd3JpdGVfY2ZnX2xvbmcoTS54ODYuUl9CSCwgTS54ODYuUl9CTCwgTS54ODYuUl9ESSwgTS54ODYuUl9FQ1gpOwogICAgCU0ueDg2LlJfQUggPSBQQ0lCSU9TX1NVQ0NFU1NGVUw7CiAgICAJQ09ORElUSU9OQUxfU0VUX0ZMQUcoKE0ueDg2LlJfQUggIT0gUENJQklPU19TVUNDRVNTRlVMKSwgRl9DRik7CiAgICAJUFJJTlRGKCJ3cml0ZV9jb25maWdfbG9uZyAleCwleCwleCA8LSAleFxuIiwgTS54ODYuUl9CSCwgTS54ODYuUl9CTCwgTS54ODYuUl9ESSwgTS54ODYuUl9FQ1gpOwogICAgCWJyZWFrOwogICAgZGVmYXVsdDoKICAgIAlQUklOVEYoIkJJT1MgaW50ICV4aDogVW5rbm93biBmdW5jdGlvbiBBWD0lMDR4aFxuIiwgaW50bm8sIE0ueDg2LlJfQVgpOwogICAgfQp9Cgp2b2lkIGJpb3NfaW5pdCh2b2lkKQp7CiAgICBpbnQgaTsKICAgIFg4NkVNVV9pbnRyRnVuY3MgYmlvc19pbnRyX3RhYlsyNTZdOwoKICAgIFBSSU5URigiSW50ZXJydXB0IHRhYmxlXG4iKTsKICAgIGZvciAoaT0wOyBpPDI1NjsgaSsrKQogICAgewoJICAgIG91dDMycigodm9sYXRpbGUgVUxPTkcgKikoTS5tZW1fYmFzZStpKjQpLCBCSU9TX1NFRzw8MTYpOwoJICAgIGJpb3NfaW50cl90YWJbaV0gPSB1bmRlZmluZWRfaW50cjsKICAgIH0KCiAgICBiaW9zX2ludHJfdGFiWzB4MTBdID0gaW50MTA7CiAgICBiaW9zX2ludHJfdGFiWzB4MUFdID0gaW50MUE7CiAgICBiaW9zX2ludHJfdGFiWzB4NDJdID0gaW50NDI7CiAgICBiaW9zX2ludHJfdGFiWzB4MTVdID0gaW50MTU7CgogICAgYmlvc19pbnRyX3RhYlsweDZEXSA9IGludDQyOwoKICAgIFg4NkVNVV9zZXR1cEludHJGdW5jcyhiaW9zX2ludHJfdGFiKTsKICAgIC8vIHdoeSBoZXJlPyBCZWNhdXNlIGl0IGlzIG5lZWRlZC4KICAgIC8vUFJJTlRGKCJ2aWRlb19pbml0XG4iKTsKICAgIC8vdmlkZW9faW5pdCgpOwp9Cgp1bnNpZ25lZCBjaGFyIHNldHVwXzQweDI1W10gPQp7CiAgICAweDM4LCAweDI4LCAweDJkLCAweDBhLCAweDFmLCA2LCAweDE5LAogICAgMHgxYywgMiwgNywgNiwgNywgMCwgMCwgMCwgMAp9OwoKdW5zaWduZWQgY2hhciBzZXR1cF84MHgyNVtdID0KewogICAgMHg3MSwgMHg1MCwgMHg1YSwgMHgwYSwgMHgxZiwgNiwgMHgxOSwKICAgIDB4MWMsIDIsIDcsIDYsIDcsIDAsIDAsIDAsIDAKfTsKCnVuc2lnbmVkIGNoYXIgc2V0dXBfZ3JhcGhpY3NbXSA9CnsKICAgIDB4MzgsIDB4MjgsIDB4MjAsIDB4MGEsIDB4N2YsIDYsIDB4NjQsCiAgICAweDcwLCAyLCAxLCA2LCA3LCAwLCAwLCAwLCAwCn07Cgp1bnNpZ25lZCBjaGFyIHNldHVwX2J3W10gPQp7CiAgICAweDYxLCAweDUwLCAweDUyLCAweDBmLCAweDE5LCA2LCAweDE5LAogICAgMHgxOSwgMiwgMHgwZCwgMHgwYiwgMHgwYywgMCwgMCwgMCwgMAp9OwoKdW5zaWduZWQgY2hhciAqIHNldHVwX21vZGVzW10gPQp7CiAgICBzZXR1cF80MHgyNSwgICAgIC8vIG1vZGUgMDogNDB4MjUgYncgdGV4dAogICAgc2V0dXBfNDB4MjUsICAgICAvLyBtb2RlIDE6IDQweDI1IGNvbCB0ZXh0CiAgICBzZXR1cF84MHgyNSwgICAgIC8vIG1vZGUgMjogODB4MjUgYncgdGV4dAogICAgc2V0dXBfODB4MjUsICAgICAvLyBtb2RlIDM6IDgweDI1IGNvbCB0ZXh0CiAgICBzZXR1cF9ncmFwaGljcywgIC8vIG1vZGUgNDogMzIweDIwMCBjb2wgZ3JhcGhpY3MKICAgIHNldHVwX2dyYXBoaWNzLCAgLy8gbW9kZSA1OiAzMjB4MjAwIGJ3IGdyYXBoaWNzCiAgICBzZXR1cF9ncmFwaGljcywgIC8vIG1vZGUgNjogNjQweDIwMCBidyBncmFwaGljcwogICAgc2V0dXBfYncgICAgICAgICAvLyBtb2RlIDc6IDgweDI1IG1vbm8gdGV4dAp9OwoKdW5zaWduZWQgaW50IHNldHVwX2NvbHNbXSA9CnsKICAgIDQwLCA0MCwgODAsIDgwLCA0MCwgNDAsIDgwLCA4MAp9OwoKdW5zaWduZWQgY2hhciBzZXR1cF9tb2Rlc2V0c1tdID0KewogICAgIDB4MkMsIDB4MjgsIDB4MkQsIDB4MjksIDB4MkEsIDB4MkUsIDB4MUUsIDB4MjkKfTsKCnVuc2lnbmVkIGludCBzZXR1cF9idWZzaXplW10gPQp7CiAgICAyMDQ4LCAyMDQ4LCA0MDk2LCAyMDk2LCAxNjM4NCwgMTYzODQsIDE2Mzg0LCA0MDk2Cn07CgppbnQgcmVsb2NfbW9kZV9kb25lID0gMDsKCnZvaWQgcmVsb2NfbW9kZV90YWJsZSh2b2lkICpyZWxvY19hZGRyKQp7CiAgICB1bnNpZ25lZCBsb25nIGRlbHRhOwogICAgaW50IGk7CiAgICAKICAgIGlmIChyZWxvY19tb2RlX2RvbmUpIAoJcmV0dXJuOwoKICAgIHJlbG9jX21vZGVfZG9uZSA9IDE7CgogICAgUFJJTlRGKCJyZWxvY19hZGRyID0gJXBcbiIsIHJlbG9jX2FkZHIpOwogICAgZGVsdGEgPSBURVhUX0JBU0UgLSAodW5zaWduZWQgbG9uZylyZWxvY19hZGRyOwogICAgUFJJTlRGKCJkZWx0YSA9ICVwXG4iLCBkZWx0YSk7CgogICAgZm9yIChpID0gMDsgaSA8IHNpemVvZihzZXR1cF9tb2Rlcykvc2l6ZW9mKHVuc2lnbmVkIGNoYXIgKik7IGkrKykKCSAgICBzZXR1cF9tb2Rlc1tpXSA9ICh1bnNpZ25lZCBjaGFyICopICgodW5zaWduZWQgbG9uZylzZXR1cF9tb2Rlc1tpXSAtIGRlbHRhKTsKfQoKdm9pZCBiaW9zX3NldF9tb2RlKGludCBtb2RlKQp7CiAgICBpbnQgaTsKICAgIHVuc2lnbmVkIGNoYXIgbW9kZV9zZXQgPSBzZXR1cF9tb2Rlc2V0c1ttb2RlXTsgLy8gQ29udHJvbCByZWdpc3RlciB2YWx1ZQogICAgdW5zaWduZWQgY2hhciAqc2V0dXBfcmVncyA9IHNldHVwX21vZGVzW21vZGVdOyAvLyBSZWdpc3RlciAzRDQgQXJyYXkKCiAgICBmbHVzaF9jYWNoZSgwLCAzMjc2OCk7CgogICAgUFJJTlRGKCJiaW9zX3NldF9tb2RlOiBtb2RlID0gJWQsIHNldHVwX3JlZ3MgPSAlcFxuIiwgbW9kZSwgc2V0dXBfcmVncyk7CiAgICAKICAgIC8vIFN3aXRjaCB2aWRlbyBvZmYKICAgIG91dF9ieXRlKDB4M0Q4LCBtb2RlX3NldCAmIDB4MzcpOwoKICAgIC8vIFNldCB1cCBwYXJhbWV0ZXJzIGF0IDNENGgKICAgIGZvciAoaT0wOyBpPDE2OyBpKyspCiAgICB7CiAgICAJb3V0X2J5dGUoMHgzRDQsICh1bnNpZ25lZCBjaGFyKWkpOwoJICAgIG91dF9ieXRlKDB4M0Q1LCAgKnNldHVwX3JlZ3MpOwogICAgCXNldHVwX3JlZ3MrKzsKICAgIH0KCiAgICAvLyBFbmFibGUgdmlkZW8KICAgIG91dF9ieXRlKDB4M0Q4LCBtb2RlX3NldCk7CgogICAgLy8gU2V0IG92ZXJzY2FuCiAgICBpZiAobW9kZSA9PSA2KSBvdXRfYnl0ZSgweDNEOSwgMHgzRik7CiAgICBlbHNlICAgICAgICAgICBvdXRfYnl0ZSgweDNEOSwgMHgzMCk7CgogICAgUFJJTlRGKCJiaW9zX3NldF9tb2RlOiBkb25lXG4iKTsKfQovKgpzdGF0aWMgdm9pZCBiaW9zX3ByaW50X3N0cmluZyh2b2lkKQp7CiAgICBleHRlcm4gdm9pZCB2aWRlb19iaW9zX3ByaW50X3N0cmluZyhjaGFyICpzdHJpbmcsIGludCB4LCBpbnQgeSwgaW50IGF0dHIsIGludCBjb3VudCk7CiAgICAvL2NoYXIgKnMgPSAoY2hhciAqKShNLng4Ni5SX0VTPDw0KSArIE0ueDg2LlJfQlA7CiAgICBpbnQgYXR0cjsKICAgIGlmIChNLng4Ni5SX0FMICYgMHgwMikgYXR0ciA9IC0gMTsKICAgIGVsc2UgICAgICAgICAgICAgICAgICAgYXR0ciA9IE0ueDg2LlJfQkw7CiAgICAvL3ZpZGVvX2Jpb3NfcHJpbnRfc3RyaW5nKHMsIE0ueDg2LlJfREgsIE0ueDg2LlJfREwsIGF0dHIsIE0ueDg2LlJfQ1gpOwp9CiovCnN0YXRpYyB2b2lkIFg4NkFQSSBpbnQ0MihpbnQgaW50bm8pCnsKICAgIFBSSU5URigiaW50NDI6IEFIID0gMHgleCwgQUwgPSAweCV4LCBBWCA9IDB4JXgsIEJYID0gMHgleFxuIiwKCQkgICAgTS54ODYuUl9BSCwgTS54ODYuUl9BTCwgTS54ODYuUl9BWCwgTS54ODYuUl9CWCk7CgogICAgc3dpdGNoIChNLng4Ni5SX0FIKQogICAgewogICAgY2FzZSAweDAwOgoJYmlvc19zZXRfbW9kZShNLng4Ni5SX0FMKTsKCWJyZWFrOwogICAgY2FzZSAweDEzOgoJLy9iaW9zX3ByaW50X3N0cmluZygpOwoJYnJlYWs7CiAgICBkZWZhdWx0OgoJUFJJTlRGKCJXYXJuaW5nOiBWSURFTyBCSU9TIGludGVycnVwdCAleGggdW5pbXBsZW1lbnRlZCBmdW5jdGlvbiAleGgsIEFMID0gJXhoXG4iLAoJICAgICAgIGludG5vLCBNLng4Ni5SX0FILCBNLng4Ni5SX0FMKTsKCWJyZWFrOwogICAgfQp9CgpzdGF0aWMgdm9pZCBYODZBUEkgaW50MTUoaW50IGludG5vKQp7CiAgICBQUklOVEYoIkNhbGxlZCBpbnRlcnJ1cHQgMTVoOiBBWCA9ICV4aCwgQlggPSAleGgsIENYID0gJXhoLCBEWCA9ICV4aFxuIiwKCSAgIE0ueDg2LlJfQVgsIE0ueDg2LlJfQlgsIE0ueDg2LlJfQ1gsIE0ueDg2LlJfRFgpOwovLyNpZiAwCiAgICBpZiAoTS54ODYuUl9BWCA9PSAweDA0ZTA4KQogICAgewoJCXN3aXRjaCAoTS54ODYuUl9CTCkKCQl7Ci8qCQoJCSAgICBjYXNlIDB4MDY6CQkJLy8gUG93ZXIgTWFuYWdlbWVudCBNb2RlIHJlcXVlc3QKCQkJTS54ODYuUl9CTCA9IDA7CQkvLyBBc3N1bWUgQVBNCgkJCU0ueDg2LlJfQUwgPSAwOwoJCQlicmVhazsKCQkKCQkgICAgY2FzZSAweDA1OgkJCS8vIEdldCBUViBzdGFuZGFyZAoJCQkJTS54ODYuUl9CWCA9IDB4ZmY7CS8vIFNlbGVjdCBObyBUVgoJCQkJTS54ODYuUl9BTCA9IDA7CgkJCQlicmVhazsKKi8JCQoJCSAgICBjYXNlIDB4MDE6CQkJCQkgLy8gR2V0IFJlcXVlc3QgRGlzcGxheQoJCQkgICAgaWYgKChNLng4Ni5SX0JIICYgMHgwOCkgPT0gMHgwOCkKCQkJICAgIHsJCQkJCQoJCQkJCU0ueDg2LlJfQkwgPSAweDA4OwkvLyBEVkkKCQkJCQlNLng4Ni5SX0JIID0gMDsKCQkJCQlNLng4Ni5SX0FMID0gMDsJCS8vIHN1cHBvcnRlZAoJCQkJCVBSSU5URigiRFZJIE1vbml0b3IgRm91bmRcbiIpOwoJCQkJfQoJCQkKCQkJICAgIGlmICgoKE0ueDg2LlJfQkggJiAweDA4KSA9PSAweDA4KSB8fCAoKE0ueDg2LlJfQkggJiAweDAyKSA9PSAweDAyKSkKCQkJICAgIHsJCQkJCQoJCQkJCU0ueDg2LlJfQkwgPSAweDAyOwkvLyBDUlQKCQkJCQlNLng4Ni5SX0JIID0gMDsKCQkJCQlNLng4Ni5SX0FMID0gMDsJCS8vIHN1cHBvcnRlZAoJCQkJCVBSSU5URigiQ1JUIE1vbml0b3IgRm91bmRcbiIpOwoJCQkJfQoKCQkJICAgIGlmICgoKE0ueDg2LlJfQkggJiAweDA4KSA9PSAweDA4KSB8fCAoKE0ueDg2LlJfQkggJiAweDA0KSA9PSAweDA0KSkKCQkJICAgIHsJCQkJCQoJCQkJCU0ueDg2LlJfQkwgPSAweDA0OwkvLyBDUlQgMgoJCQkJCU0ueDg2LlJfQkggPSAwOwoJCQkJCU0ueDg2LlJfQVggPSAwOwkJLy8gc3VwcG9ydGVkCgkJCQkJUFJJTlRGKCJDUlQyIE1vbml0b3IgRm91bmRcbiIpOwoJCQkJfQoJCQkJCQkJCgkJCQlicmVhazsKCQkJCgkJICAgIGRlZmF1bHQ6CgkJCQlQUklOVEYoIlN1YmZ1bmN0aW9uICVkIG5vdCBpbXBsZW1lbnRlZFxuIiwgTS54ODYuUl9CTCk7CgkJCQlNLng4Ni5SX0FMID0gMjsJCS8vIE5vdCBzdXBwb3J0ZWQKCQkJCWJyZWFrOwoJCX0KCQlQUklOVEYoIlJlc3VsdDogQVggPSAleGgsIEJYID0gJXhoXG4iLCBNLng4Ni5SX0FYLCBNLng4Ni5SX0JYKTsKICAgIH0KLy8jZW5kaWYKLy8gICAgLy8gRm9yIG5vdywganVzdCBkZWNsYXJlIHRoaXMgaW50ZXJydXB0IGFzIG5vdCBpbXBsZW1lbnRlZAovLyAgICBNLng4Ni5SX0FYID0gMjsgICAgCn0K