LyoKICogQ29weXJpZ2h0IChDKSAyMDA1ICBPbGUgQW5kcukgVmFkbGEgUmF2buVzIDxvbGVhdnJAZ21haWwuY29tPgogKiBDb3B5cmlnaHQgKEMpIDIwMDggIFJhbWlybyBQb2xsYQogKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiBGRm1wZWcuCiAqCiAqIEZGbXBlZyBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IKICogbW9kaWZ5IGl0IHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpYwogKiBMaWNlbnNlIGFzIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uOyBlaXRoZXIKICogdmVyc2lvbiAyLjEgb2YgdGhlIExpY2Vuc2UsIG9yIChhdCB5b3VyIG9wdGlvbikgYW55IGxhdGVyIHZlcnNpb24uCiAqCiAqIEZGbXBlZyBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLAogKiBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZgogKiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVQogKiBMZXNzZXIgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBmb3IgbW9yZSBkZXRhaWxzLgogKgogKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljCiAqIExpY2Vuc2UgYWxvbmcgd2l0aCBGRm1wZWc7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUKICogRm91bmRhdGlvbiwgSW5jLiwgNTEgRnJhbmtsaW4gU3RyZWV0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAwMjExMC0xMzAxIFVTQQogKi8KCiNpbmNsdWRlIDxzdGRsaWIuaD4KI2luY2x1ZGUgPHN0cmluZy5oPgojaW5jbHVkZSA8c3RkaW50Lmg+CgojaW5jbHVkZSAiYXZjb2RlYy5oIgojaW5jbHVkZSAiZ2V0X2JpdHMuaCIKI2luY2x1ZGUgImJ5dGVzdHJlYW0uaCIKI2luY2x1ZGUgImRzcHV0aWwuaCIKI2luY2x1ZGUgInRocmVhZC5oIgoKI2RlZmluZSBNSU1JQ19IRUFERVJfU0laRSAgIDIwCgp0eXBlZGVmIHN0cnVjdCB7CiAgICBBVkNvZGVjQ29udGV4dCAqYXZjdHg7CgogICAgaW50ICAgICAgICAgICAgIG51bV92YmxvY2tzWzNdOwogICAgaW50ICAgICAgICAgICAgIG51bV9oYmxvY2tzWzNdOwoKICAgIHZvaWQgICAgICAgICAgICpzd2FwX2J1ZjsKICAgIGludCAgICAgICAgICAgICBzd2FwX2J1Zl9zaXplOwoKICAgIGludCAgICAgICAgICAgICBjdXJfaW5kZXg7CiAgICBpbnQgICAgICAgICAgICAgcHJldl9pbmRleDsKCiAgICBBVkZyYW1lICAgICAgICAgYnVmX3B0cnMgICAgWzE2XTsKICAgIEFWUGljdHVyZSAgICAgICBmbGlwcGVkX3B0cnNbMTZdOwoKICAgIERFQ0xBUkVfQUxJR05FRCgxNiwgRENURUxFTSwgZGN0X2Jsb2NrKVs2NF07CgogICAgR2V0Qml0Q29udGV4dCAgIGdiOwogICAgU2NhblRhYmxlICAgICAgIHNjYW50YWJsZTsKICAgIERTUENvbnRleHQgICAgICBkc3A7CiAgICBWTEMgICAgICAgICAgICAgdmxjOwoKICAgIC8qIEtlcHQgaW4gdGhlIGNvbnRleHQgc28gbXVsdGl0aHJlYWRpbmcgY2FuIGhhdmUgYSBjb25zdGFudCB0byByZWFkIGZyb20gKi8KICAgIGludCAgICAgICAgICAgICBuZXh0X2N1cl9pbmRleDsKICAgIGludCAgICAgICAgICAgICBuZXh0X3ByZXZfaW5kZXg7Cn0gTWltaWNDb250ZXh0OwoKc3RhdGljIGNvbnN0IHVpbnQzMl90IGh1ZmZjb2Rlc1tdID0gewogICAgMHgwMDAwMDAwYSwgMHgwMDAwMDAwMCwgMHgwMDAwMDAwMCwgMHgwMDAwMDAwMCwgMHgwMDAwMDAwMCwgMHgwMDAwMDAwMCwKICAgIDB4MDAwMDAwMDAsIDB4MDAwMDAwMDAsIDB4MDAwMDAwMDAsIDB4MDAwMDAwMDAsIDB4MDAwMDAwMDAsIDB4MDAwMDAwMDAsCiAgICAweDAwMDAwMDAwLCAweDAwMDAwMDAwLCAweDAwMDAwMDAwLCAweDAwMDAwMDAwLCAweDAwMDAwMDAwLCAweDAwMDAwMDBiLAogICAgMHgwMDAwMDAxYiwgMHgwMDAwMDAzOCwgMHgwMDAwMDA3OCwgMHgwMDAwMDA3OSwgMHgwMDAwMDA3YSwgMHgwMDAwMDBmOSwKICAgIDB4MDAwMDAwZmEsIDB4MDAwMDAzZmIsIDB4MDAwMDA3ZjgsIDB4MDAwMDA3ZjksIDB4MDAwMDA3ZmEsIDB4MDAwMDA3ZmIsCiAgICAweDAwMDAwZmY4LCAweDAwMDAwZmY5LCAweDAwMDAwMDAxLCAweDAwMDAwMDM5LCAweDAwMDAwMDdiLCAweDAwMDAwMGZiLAogICAgMHgwMDAwMDFmOCwgMHgwMDAwMDFmOSwgMHgwMDAwMGZmYSwgMHgwMDAwMGZmYiwgMHgwMDAwMWZmOCwgMHgwMDAwMWZmOSwKICAgIDB4MDAwMDFmZmEsIDB4MDAwMDFmZmIsIDB4MDAwMDNmZjgsIDB4MDAwMDNmZjksIDB4MDAwMDNmZmEsIDB4MDAwMDAwMDAsCiAgICAweDAwMDAwMDA0LCAweDAwMDAwMDNhLCAweDAwMDAwMWZhLCAweDAwMDAzZmZiLCAweDAwMDA3ZmY4LCAweDAwMDA3ZmY5LAogICAgMHgwMDAwN2ZmYSwgMHgwMDAwN2ZmYiwgMHgwMDAwZmZmOCwgMHgwMDAwZmZmOSwgMHgwMDAwZmZmYSwgMHgwMDAwZmZmYiwKICAgIDB4MDAwMWZmZjgsIDB4MDAwMWZmZjksIDB4MDAwMWZmZmEsIDB4MDAwMDAwMDAsIDB4MDAwMDAwMGMsIDB4MDAwMDAwZjgsCiAgICAweDAwMDAwMWZiLCAweDAwMDFmZmZiLCAweDAwMDNmZmY4LCAweDAwMDNmZmY5LCAweDAwMDNmZmZhLCAweDAwMDNmZmZiLAogICAgMHgwMDA3ZmZmOCwgMHgwMDA3ZmZmOSwgMHgwMDA3ZmZmYSwgMHgwMDA3ZmZmYiwgMHgwMDBmZmZmOCwgMHgwMDBmZmZmOSwKICAgIDB4MDAwZmZmZmEsIDB4MDAwMDAwMDAsIDB4MDAwMDAwMWEsIDB4MDAwMDAzZjgsIDB4MDAwZmZmZmIsIDB4MDAxZmZmZjgsCiAgICAweDAwMWZmZmY5LCAweDAwMWZmZmZhLCAweDAwMWZmZmZiLCAweDAwM2ZmZmY4LCAweDAwM2ZmZmY5LCAweDAwM2ZmZmZhLAogICAgMHgwMDNmZmZmYiwgMHgwMDdmZmZmOCwgMHgwMDdmZmZmOSwgMHgwMDdmZmZmYSwgMHgwMDdmZmZmYiwgMHgwMDAwMDAwMCwKICAgIDB4MDAwMDAwM2IsIDB4MDAwMDAzZjksIDB4MDBmZmZmZjgsIDB4MDBmZmZmZjksIDB4MDBmZmZmZmEsIDB4MDBmZmZmZmIsCiAgICAweDAxZmZmZmY4LCAweDAxZmZmZmY5LCAweDAxZmZmZmZhLCAweDAxZmZmZmZiLCAweDAzZmZmZmY4LCAweDAzZmZmZmY5LAogICAgMHgwM2ZmZmZmYSwgMHgwM2ZmZmZmYiwgMHgwN2ZmZmZmOCwgMHgwMDAwMDAwMCwgMHgwMDAwMDNmYSwgMHgwN2ZmZmZmOSwKICAgIDB4MDdmZmZmZmEsIDB4MDdmZmZmZmIsIDB4MGZmZmZmZjgsIDB4MGZmZmZmZjksIDB4MGZmZmZmZmEsIDB4MGZmZmZmZmIsCiAgICAweDFmZmZmZmY4LCAweDFmZmZmZmY5LCAweDFmZmZmZmZhLCAweDFmZmZmZmZiLCAweDNmZmZmZmY4LCAweDNmZmZmZmY5LAogICAgMHgzZmZmZmZmYSwKfTsKCnN0YXRpYyBjb25zdCB1aW50OF90IGh1ZmZiaXRzW10gPSB7CiAgICAgNCwgIDAsICAwLCAgMCwgIDAsICAwLCAgMCwgIDAsICAwLCAgMCwgIDAsICAwLAogICAgIDAsICAwLCAgMCwgIDAsICAyLCAgNCwgIDUsICA2LCAgNywgIDcsICA3LCAgOCwKICAgICA4LCAxMCwgMTEsIDExLCAxMSwgMTEsIDEyLCAxMiwgIDIsICA2LCAgNywgIDgsCiAgICAgOSwgIDksIDEyLCAxMiwgMTMsIDEzLCAxMywgMTMsIDE0LCAxNCwgMTQsICAwLAogICAgIDMsICA2LCAgOSwgMTQsIDE1LCAxNSwgMTUsIDE1LCAxNiwgMTYsIDE2LCAxNiwKICAgIDE3LCAxNywgMTcsICAwLCAgNCwgIDgsICA5LCAxNywgMTgsIDE4LCAxOCwgMTgsCiAgICAxOSwgMTksIDE5LCAxOSwgMjAsIDIwLCAyMCwgIDAsICA1LCAxMCwgMjAsIDIxLAogICAgMjEsIDIxLCAyMSwgMjIsIDIyLCAyMiwgMjIsIDIzLCAyMywgMjMsIDIzLCAgMCwKICAgICA2LCAxMCwgMjQsIDI0LCAyNCwgMjQsIDI1LCAyNSwgMjUsIDI1LCAyNiwgMjYsCiAgICAyNiwgMjYsIDI3LCAgMCwgMTAsIDI3LCAyNywgMjcsIDI4LCAyOCwgMjgsIDI4LAogICAgMjksIDI5LCAyOSwgMjksIDMwLCAzMCwgMzAsCn07CgpzdGF0aWMgY29uc3QgdWludDhfdCBjb2xfemFnWzY0XSA9IHsKICAgICAwLCAgOCwgIDEsICAyLCAgOSwgMTYsIDI0LCAxNywKICAgIDEwLCAgMywgIDQsIDExLCAxOCwgMjUsIDMyLCA0MCwKICAgIDMzLCAyNiwgMTksIDEyLCAgNSwgIDYsIDEzLCAyMCwKICAgIDI3LCAzNCwgNDEsIDQ4LCA1NiwgNDksIDQyLCAzNSwKICAgIDI4LCAyMSwgMTQsICA3LCAxNSwgMjIsIDI5LCAzNiwKICAgIDQzLCA1MCwgNTcsIDU4LCA1MSwgNDQsIDM3LCAzMCwKICAgIDIzLCAzMSwgMzgsIDQ1LCA1MiwgNTksIDM5LCA0NiwKICAgIDUzLCA2MCwgNjEsIDU0LCA0NywgNTUsIDYyLCA2MywKfTsKCnN0YXRpYyBhdl9jb2xkIGludCBtaW1pY19kZWNvZGVfaW5pdChBVkNvZGVjQ29udGV4dCAqYXZjdHgpCnsKICAgIE1pbWljQ29udGV4dCAqY3R4ID0gYXZjdHgtPnByaXZfZGF0YTsKCiAgICBjdHgtPnByZXZfaW5kZXggPSAwOwogICAgY3R4LT5jdXJfaW5kZXggPSAxNTsKCiAgICBpZihpbml0X3ZsYygmY3R4LT52bGMsIDExLCBGRl9BUlJBWV9FTEVNUyhodWZmYml0cyksCiAgICAgICAgICAgICAgICAgaHVmZmJpdHMsIDEsIDEsIGh1ZmZjb2RlcywgNCwgNCwgMCkpIHsKICAgICAgICBhdl9sb2coYXZjdHgsIEFWX0xPR19FUlJPUiwgImVycm9yIGluaXRpYWxpemluZyB2bGMgdGFibGVcbiIpOwogICAgICAgIHJldHVybiAtMTsKICAgIH0KICAgIGRzcHV0aWxfaW5pdCgmY3R4LT5kc3AsIGF2Y3R4KTsKICAgIGZmX2luaXRfc2NhbnRhYmxlKGN0eC0+ZHNwLmlkY3RfcGVybXV0YXRpb24sICZjdHgtPnNjYW50YWJsZSwgY29sX3phZyk7CgogICAgcmV0dXJuIDA7Cn0KCnN0YXRpYyBpbnQgbWltaWNfZGVjb2RlX3VwZGF0ZV90aHJlYWRfY29udGV4dChBVkNvZGVjQ29udGV4dCAqYXZjdHgsIGNvbnN0IEFWQ29kZWNDb250ZXh0ICphdmN0eF9mcm9tKQp7CiAgICBNaW1pY0NvbnRleHQgKmRzdCA9IGF2Y3R4LT5wcml2X2RhdGEsICpzcmMgPSBhdmN0eF9mcm9tLT5wcml2X2RhdGE7CgogICAgaWYgKGF2Y3R4ID09IGF2Y3R4X2Zyb20pIHJldHVybiAwOwoKICAgIGRzdC0+Y3VyX2luZGV4ICA9IHNyYy0+bmV4dF9jdXJfaW5kZXg7CiAgICBkc3QtPnByZXZfaW5kZXggPSBzcmMtPm5leHRfcHJldl9pbmRleDsKCiAgICBtZW1jcHkoZHN0LT5idWZfcHRycywgc3JjLT5idWZfcHRycywgc2l6ZW9mKHNyYy0+YnVmX3B0cnMpKTsKICAgIG1lbWNweShkc3QtPmZsaXBwZWRfcHRycywgc3JjLT5mbGlwcGVkX3B0cnMsIHNpemVvZihzcmMtPmZsaXBwZWRfcHRycykpOwoKICAgIG1lbXNldCgmZHN0LT5idWZfcHRyc1tkc3QtPmN1cl9pbmRleF0sIDAsIHNpemVvZihBVkZyYW1lKSk7CgogICAgcmV0dXJuIDA7Cn0KCnN0YXRpYyBjb25zdCBpbnQ4X3QgdmxjZGVjX2xvb2t1cFs5XVs2NF0gPSB7CiAgICB7ICAgIDAsIH0sCiAgICB7ICAgLTEsICAgMSwgfSwKICAgIHsgICAtMywgICAzLCAgIC0yLCAgIDIsIH0sCiAgICB7ICAgLTcsICAgNywgICAtNiwgICA2LCAgIC01LCAgIDUsICAgLTQsICAgNCwgfSwKICAgIHsgIC0xNSwgIDE1LCAgLTE0LCAgMTQsICAtMTMsICAxMywgIC0xMiwgIDEyLAogICAgICAgLTExLCAgMTEsICAtMTAsICAxMCwgICAtOSwgICA5LCAgIC04LCAgIDgsIH0sCiAgICB7ICAtMzEsICAzMSwgIC0zMCwgIDMwLCAgLTI5LCAgMjksICAtMjgsICAyOCwKICAgICAgIC0yNywgIDI3LCAgLTI2LCAgMjYsICAtMjUsICAyNSwgIC0yNCwgIDI0LAogICAgICAgLTIzLCAgMjMsICAtMjIsICAyMiwgIC0yMSwgIDIxLCAgLTIwLCAgMjAsCiAgICAgICAtMTksICAxOSwgIC0xOCwgIDE4LCAgLTE3LCAgMTcsICAtMTYsICAxNiwgfSwKICAgIHsgIC02MywgIDYzLCAgLTYyLCAgNjIsICAtNjEsICA2MSwgIC02MCwgIDYwLAogICAgICAgLTU5LCAgNTksICAtNTgsICA1OCwgIC01NywgIDU3LCAgLTU2LCAgNTYsCiAgICAgICAtNTUsICA1NSwgIC01NCwgIDU0LCAgLTUzLCAgNTMsICAtNTIsICA1MiwKICAgICAgIC01MSwgIDUxLCAgLTUwLCAgNTAsICAtNDksICA0OSwgIC00OCwgIDQ4LAogICAgICAgLTQ3LCAgNDcsICAtNDYsICA0NiwgIC00NSwgIDQ1LCAgLTQ0LCAgNDQsCiAgICAgICAtNDMsICA0MywgIC00MiwgIDQyLCAgLTQxLCAgNDEsICAtNDAsICA0MCwKICAgICAgIC0zOSwgIDM5LCAgLTM4LCAgMzgsICAtMzcsICAzNywgIC0zNiwgIDM2LAogICAgICAgLTM1LCAgMzUsICAtMzQsICAzNCwgIC0zMywgIDMzLCAgLTMyLCAgMzIsIH0sCiAgICB7IC0xMjcsIDEyNywgLTEyNiwgMTI2LCAtMTI1LCAxMjUsIC0xMjQsIDEyNCwKICAgICAgLTEyMywgMTIzLCAtMTIyLCAxMjIsIC0xMjEsIDEyMSwgLTEyMCwgMTIwLAogICAgICAtMTE5LCAxMTksIC0xMTgsIDExOCwgLTExNywgMTE3LCAtMTE2LCAxMTYsCiAgICAgIC0xMTUsIDExNSwgLTExNCwgMTE0LCAtMTEzLCAxMTMsIC0xMTIsIDExMiwKICAgICAgLTExMSwgMTExLCAtMTEwLCAxMTAsIC0xMDksIDEwOSwgLTEwOCwgMTA4LAogICAgICAtMTA3LCAxMDcsIC0xMDYsIDEwNiwgLTEwNSwgMTA1LCAtMTA0LCAxMDQsCiAgICAgIC0xMDMsIDEwMywgLTEwMiwgMTAyLCAtMTAxLCAxMDEsIC0xMDAsIDEwMCwKICAgICAgIC05OSwgIDk5LCAgLTk4LCAgOTgsICAtOTcsICA5NywgIC05NiwgIDk2LCB9LAogICAgeyAgLTk1LCAgOTUsICAtOTQsICA5NCwgIC05MywgIDkzLCAgLTkyLCAgOTIsCiAgICAgICAtOTEsICA5MSwgIC05MCwgIDkwLCAgLTg5LCAgODksICAtODgsICA4OCwKICAgICAgIC04NywgIDg3LCAgLTg2LCAgODYsICAtODUsICA4NSwgIC04NCwgIDg0LAogICAgICAgLTgzLCAgODMsICAtODIsICA4MiwgIC04MSwgIDgxLCAgLTgwLCAgODAsCiAgICAgICAtNzksICA3OSwgIC03OCwgIDc4LCAgLTc3LCAgNzcsICAtNzYsICA3NiwKICAgICAgIC03NSwgIDc1LCAgLTc0LCAgNzQsICAtNzMsICA3MywgIC03MiwgIDcyLAogICAgICAgLTcxLCAgNzEsICAtNzAsICA3MCwgIC02OSwgIDY5LCAgLTY4LCAgNjgsCiAgICAgICAtNjcsICA2NywgIC02NiwgIDY2LCAgLTY1LCAgNjUsICAtNjQsICA2NCwgfSwKfTsKCnN0YXRpYyBpbnQgdmxjX2RlY29kZV9ibG9jayhNaW1pY0NvbnRleHQgKmN0eCwgaW50IG51bV9jb2VmZnMsIGludCBxc2NhbGUpCnsKICAgIERDVEVMRU0gKmJsb2NrID0gY3R4LT5kY3RfYmxvY2s7CiAgICB1bnNpZ25lZCBpbnQgcG9zOwoKICAgIGN0eC0+ZHNwLmNsZWFyX2Jsb2NrKGJsb2NrKTsKCiAgICBibG9ja1swXSA9IGdldF9iaXRzKCZjdHgtPmdiLCA4KSA8PCAzOwoKICAgIGZvcihwb3MgPSAxOyBwb3MgPCBudW1fY29lZmZzOyBwb3MrKykgewogICAgICAgIHVpbnQzMl90IHZsYywgbnVtX2JpdHM7CiAgICAgICAgaW50IHZhbHVlOwogICAgICAgIGludCBjb2VmZjsKCiAgICAgICAgdmxjID0gZ2V0X3ZsYzIoJmN0eC0+Z2IsIGN0eC0+dmxjLnRhYmxlLCBjdHgtPnZsYy5iaXRzLCAzKTsKICAgICAgICBpZighdmxjKSAvKiBlbmQtb2YtYmxvY2sgY29kZSAqLwogICAgICAgICAgICByZXR1cm4gMTsKICAgICAgICBpZih2bGMgPT0gLTEpCiAgICAgICAgICAgIHJldHVybiAwOwoKICAgICAgICAvKiBwb3NfYWRkIGFuZCBudW1fYml0cyBhcmUgY29kZWQgaW4gdGhlIHZsYyBjb2RlICovCiAgICAgICAgcG9zICs9ICAgICB2bGMmMTU7IC8vIHBvc19hZGQKICAgICAgICBudW1fYml0cyA9IHZsYz4+NDsgLy8gbnVtX2JpdHMKCiAgICAgICAgaWYocG9zID49IDY0KQogICAgICAgICAgICByZXR1cm4gMDsKCiAgICAgICAgdmFsdWUgPSBnZXRfYml0cygmY3R4LT5nYiwgbnVtX2JpdHMpOwoKICAgICAgICAvKiBGRm1wZWcncyBJRENUIGJlaGF2ZXMgc29tZXdoYXQgZGlmZmVyZW50IGZyb20gdGhlIG9yaWdpbmFsIGNvZGUsIHNvCiAgICAgICAgICogYSBmYWN0b3Igb2YgNCB3YXMgYWRkZWQgdG8gdGhlIGlucHV0ICovCgogICAgICAgIGNvZWZmID0gdmxjZGVjX2xvb2t1cFtudW1fYml0c11bdmFsdWVdOwogICAgICAgIGlmKHBvczwzKQogICAgICAgICAgICBjb2VmZiA8PD0gNDsKICAgICAgICBlbHNlIC8qIFRPRE8gVXNlID4+IDEwIGluc3RlYWQgb2YgLyAxMDAxICovCiAgICAgICAgICAgIGNvZWZmID0gKGNvZWZmICogcXNjYWxlKSAvIDEwMDE7CgogICAgICAgIGJsb2NrW2N0eC0+c2NhbnRhYmxlLnBlcm11dGF0ZWRbcG9zXV0gPSBjb2VmZjsKICAgIH0KCiAgICByZXR1cm4gMTsKfQoKc3RhdGljIGludCBkZWNvZGUoTWltaWNDb250ZXh0ICpjdHgsIGludCBxdWFsaXR5LCBpbnQgbnVtX2NvZWZmcywKICAgICAgICAgICAgICAgICAgaW50IGlzX2lmcmFtZSkKewogICAgaW50IHksIHgsIHBsYW5lLCBjdXJfcm93ID0gMDsKCiAgICBmb3IocGxhbmUgPSAwOyBwbGFuZSA8IDM7IHBsYW5lKyspIHsKICAgICAgICBjb25zdCBpbnQgaXNfY2hyb21hID0gISFwbGFuZTsKICAgICAgICBjb25zdCBpbnQgcXNjYWxlID0gYXZfY2xpcCgxMDAwMC1xdWFsaXR5LGlzX2Nocm9tYT8xMDAwOjIwMDAsMTAwMDApPDwyOwogICAgICAgIGNvbnN0IGludCBzdHJpZGUgPSBjdHgtPmZsaXBwZWRfcHRyc1tjdHgtPmN1cl9pbmRleF0ubGluZXNpemVbcGxhbmVdOwogICAgICAgIGNvbnN0IHVpbnQ4X3QgKnNyYyA9IGN0eC0+ZmxpcHBlZF9wdHJzW2N0eC0+cHJldl9pbmRleF0uZGF0YVtwbGFuZV07CiAgICAgICAgdWludDhfdCAgICAgICAqZHN0ID0gY3R4LT5mbGlwcGVkX3B0cnNbY3R4LT5jdXJfaW5kZXggXS5kYXRhW3BsYW5lXTsKCiAgICAgICAgZm9yKHkgPSAwOyB5IDwgY3R4LT5udW1fdmJsb2Nrc1twbGFuZV07IHkrKykgewogICAgICAgICAgICBmb3IoeCA9IDA7IHggPCBjdHgtPm51bV9oYmxvY2tzW3BsYW5lXTsgeCsrKSB7CgogICAgICAgICAgICAgICAgLyogQ2hlY2sgZm9yIGEgY2hhbmdlIGNvbmRpdGlvbiBpbiB0aGUgY3VycmVudCBibG9jay4KICAgICAgICAgICAgICAgICAqIC0gaWZyYW1lcyBhbHdheXMgY2hhbmdlLgogICAgICAgICAgICAgICAgICogLSBMdW1hIHBsYW5lIGNoYW5nZXMgb24gZ2V0X2JpdHMxID09IDAKICAgICAgICAgICAgICAgICAqIC0gQ2hyb21hIHBsYW5lcyBjaGFuZ2Ugb24gZ2V0X2JpdHMxID09IDEgKi8KICAgICAgICAgICAgICAgIGlmKGlzX2lmcmFtZSB8fCBnZXRfYml0czEoJmN0eC0+Z2IpID09IGlzX2Nocm9tYSkgewoKICAgICAgICAgICAgICAgICAgICAvKiBMdW1hIHBsYW5lcyBtYXkgdXNlIGEgYmFja3JlZmVyZW5jZSBmcm9tIHRoZSAxNSBsYXN0CiAgICAgICAgICAgICAgICAgICAgICogZnJhbWVzIHByZWNlZGluZyB0aGUgcHJldmlvdXMuIChnZXRfYml0czEgPT0gMSkKICAgICAgICAgICAgICAgICAgICAgKiBDaHJvbWEgcGxhbmVzIGRvbid0IHVzZSBiYWNrcmVmZXJlbmNlcy4gKi8KICAgICAgICAgICAgICAgICAgICBpZihpc19jaHJvbWEgfHwgaXNfaWZyYW1lIHx8ICFnZXRfYml0czEoJmN0eC0+Z2IpKSB7CgogICAgICAgICAgICAgICAgICAgICAgICBpZighdmxjX2RlY29kZV9ibG9jayhjdHgsIG51bV9jb2VmZnMsIHFzY2FsZSkpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gMDsKICAgICAgICAgICAgICAgICAgICAgICAgY3R4LT5kc3AuaWRjdF9wdXQoZHN0LCBzdHJpZGUsIGN0eC0+ZGN0X2Jsb2NrKTsKICAgICAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgICAgICB1bnNpZ25lZCBpbnQgYmFja3JlZiA9IGdldF9iaXRzKCZjdHgtPmdiLCA0KTsKICAgICAgICAgICAgICAgICAgICAgICAgaW50IGluZGV4ID0gKGN0eC0+Y3VyX2luZGV4K2JhY2tyZWYpJjE1OwogICAgICAgICAgICAgICAgICAgICAgICB1aW50OF90ICpwID0gY3R4LT5mbGlwcGVkX3B0cnNbaW5kZXhdLmRhdGFbMF07CgogICAgICAgICAgICAgICAgICAgICAgICBmZl90aHJlYWRfYXdhaXRfcHJvZ3Jlc3MoJmN0eC0+YnVmX3B0cnNbaW5kZXhdLCBjdXJfcm93LCAwKTsKICAgICAgICAgICAgICAgICAgICAgICAgaWYocCkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgcCArPSBzcmMgLQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGN0eC0+ZmxpcHBlZF9wdHJzW2N0eC0+cHJldl9pbmRleF0uZGF0YVtwbGFuZV07CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjdHgtPmRzcC5wdXRfcGl4ZWxzX3RhYlsxXVswXShkc3QsIHAsIHN0cmlkZSwgOCk7CiAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBhdl9sb2coY3R4LT5hdmN0eCwgQVZfTE9HX0VSUk9SLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIk5vIHN1Y2ggYmFja3JlZmVyZW5jZSEgQnVnZ3kgc2FtcGxlLlxuIik7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgIGZmX3RocmVhZF9hd2FpdF9wcm9ncmVzcygmY3R4LT5idWZfcHRyc1tjdHgtPnByZXZfaW5kZXhdLCBjdXJfcm93LCAwKTsKICAgICAgICAgICAgICAgICAgICBjdHgtPmRzcC5wdXRfcGl4ZWxzX3RhYlsxXVswXShkc3QsIHNyYywgc3RyaWRlLCA4KTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIHNyYyArPSA4OwogICAgICAgICAgICAgICAgZHN0ICs9IDg7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgc3JjICs9IChzdHJpZGUgLSBjdHgtPm51bV9oYmxvY2tzW3BsYW5lXSk8PDM7CiAgICAgICAgICAgIGRzdCArPSAoc3RyaWRlIC0gY3R4LT5udW1faGJsb2Nrc1twbGFuZV0pPDwzOwoKICAgICAgICAgICAgZmZfdGhyZWFkX3JlcG9ydF9wcm9ncmVzcygmY3R4LT5idWZfcHRyc1tjdHgtPmN1cl9pbmRleF0sIGN1cl9yb3crKywgMCk7CiAgICAgICAgfQogICAgfQoKICAgIHJldHVybiAxOwp9CgovKioKICogRmxpcCB0aGUgYnVmZmVyIHVwc2lkZS1kb3duIGFuZCBwdXQgaXQgaW4gdGhlIFlWVSBvcmRlciB0byBtYXRjaCB0aGUKICogd2F5IE1pbWljIGVuY29kZXMgZnJhbWVzLgogKi8Kc3RhdGljIHZvaWQgcHJlcGFyZV9hdnBpYyhNaW1pY0NvbnRleHQgKmN0eCwgQVZQaWN0dXJlICpkc3QsIEFWUGljdHVyZSAqc3JjKQp7CiAgICBpbnQgaTsKICAgIGRzdC0+ZGF0YVswXSA9IHNyYy0+ZGF0YVswXSsoIGN0eC0+YXZjdHgtPmhlaWdodCAgICAtMSkqc3JjLT5saW5lc2l6ZVswXTsKICAgIGRzdC0+ZGF0YVsxXSA9IHNyYy0+ZGF0YVsyXSsoKGN0eC0+YXZjdHgtPmhlaWdodD4+MSktMSkqc3JjLT5saW5lc2l6ZVsyXTsKICAgIGRzdC0+ZGF0YVsyXSA9IHNyYy0+ZGF0YVsxXSsoKGN0eC0+YXZjdHgtPmhlaWdodD4+MSktMSkqc3JjLT5saW5lc2l6ZVsxXTsKICAgIGZvcihpID0gMDsgaSA8IDM7IGkrKykKICAgICAgICBkc3QtPmxpbmVzaXplW2ldID0gLXNyYy0+bGluZXNpemVbaV07Cn0KCnN0YXRpYyBpbnQgbWltaWNfZGVjb2RlX2ZyYW1lKEFWQ29kZWNDb250ZXh0ICphdmN0eCwgdm9pZCAqZGF0YSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50ICpkYXRhX3NpemUsIEFWUGFja2V0ICphdnBrdCkKewogICAgY29uc3QgdWludDhfdCAqYnVmID0gYXZwa3QtPmRhdGE7CiAgICBpbnQgYnVmX3NpemUgPSBhdnBrdC0+c2l6ZTsKICAgIE1pbWljQ29udGV4dCAqY3R4ID0gYXZjdHgtPnByaXZfZGF0YTsKICAgIGludCBpc19wZnJhbWU7CiAgICBpbnQgd2lkdGgsIGhlaWdodDsKICAgIGludCBxdWFsaXR5LCBudW1fY29lZmZzOwogICAgaW50IHN3YXBfYnVmX3NpemUgPSBidWZfc2l6ZSAtIE1JTUlDX0hFQURFUl9TSVpFOwoKICAgIGlmKGJ1Zl9zaXplIDwgTUlNSUNfSEVBREVSX1NJWkUpIHsKICAgICAgICBhdl9sb2coYXZjdHgsIEFWX0xPR19FUlJPUiwgImluc3VmZmljaWVudCBkYXRhXG4iKTsKICAgICAgICByZXR1cm4gLTE7CiAgICB9CgogICAgYnVmICAgICAgICs9IDI7IC8qIHNvbWUgY29uc3RhbnQgKGFsd2F5cyAyNTYpICovCiAgICBxdWFsaXR5ICAgID0gYnl0ZXN0cmVhbV9nZXRfbGUxNigmYnVmKTsKICAgIHdpZHRoICAgICAgPSBieXRlc3RyZWFtX2dldF9sZTE2KCZidWYpOwogICAgaGVpZ2h0ICAgICA9IGJ5dGVzdHJlYW1fZ2V0X2xlMTYoJmJ1Zik7CiAgICBidWYgICAgICAgKz0gNDsgLyogc29tZSBjb25zdGFudCAqLwogICAgaXNfcGZyYW1lICA9IGJ5dGVzdHJlYW1fZ2V0X2xlMzIoJmJ1Zik7CiAgICBudW1fY29lZmZzID0gYnl0ZXN0cmVhbV9nZXRfYnl0ZSgmYnVmKTsKICAgIGJ1ZiAgICAgICArPSAzOyAvKiBzb21lIGNvbnN0YW50ICovCgogICAgaWYoIWN0eC0+YXZjdHgpIHsKICAgICAgICBpbnQgaTsKCiAgICAgICAgaWYoISh3aWR0aCA9PSAxNjAgJiYgaGVpZ2h0ID09IDEyMCkgJiYKICAgICAgICAgICAhKHdpZHRoID09IDMyMCAmJiBoZWlnaHQgPT0gMjQwKSkgewogICAgICAgICAgICBhdl9sb2coYXZjdHgsIEFWX0xPR19FUlJPUiwgImludmFsaWQgd2lkdGgvaGVpZ2h0IVxuIik7CiAgICAgICAgICAgIHJldHVybiAtMTsKICAgICAgICB9CgogICAgICAgIGN0eC0+YXZjdHggICAgID0gYXZjdHg7CiAgICAgICAgYXZjdHgtPndpZHRoICAgPSB3aWR0aDsKICAgICAgICBhdmN0eC0+aGVpZ2h0ICA9IGhlaWdodDsKICAgICAgICBhdmN0eC0+cGl4X2ZtdCA9IFBJWF9GTVRfWVVWNDIwUDsKICAgICAgICBmb3IoaSA9IDA7IGkgPCAzOyBpKyspIHsKICAgICAgICAgICAgY3R4LT5udW1fdmJsb2Nrc1tpXSA9IC0oKC1oZWlnaHQpID4+ICgzICsgISFpKSk7CiAgICAgICAgICAgIGN0eC0+bnVtX2hibG9ja3NbaV0gPSAgICAgd2lkdGggICA+PiAoMyArICEhaSkgOwogICAgICAgIH0KICAgIH0gZWxzZSBpZih3aWR0aCAhPSBjdHgtPmF2Y3R4LT53aWR0aCB8fCBoZWlnaHQgIT0gY3R4LT5hdmN0eC0+aGVpZ2h0KSB7CiAgICAgICAgYXZfbG9nKGF2Y3R4LCBBVl9MT0dfRVJST1IsICJyZXNvbHV0aW9uIGNoYW5naW5nIGlzIG5vdCBzdXBwb3J0ZWRcbiIpOwogICAgICAgIHJldHVybiAtMTsKICAgIH0KCiAgICBpZihpc19wZnJhbWUgJiYgIWN0eC0+YnVmX3B0cnNbY3R4LT5wcmV2X2luZGV4XS5kYXRhWzBdKSB7CiAgICAgICAgYXZfbG9nKGF2Y3R4LCBBVl9MT0dfRVJST1IsICJkZWNvZGluZyBtdXN0IHN0YXJ0IHdpdGgga2V5ZnJhbWVcbiIpOwogICAgICAgIHJldHVybiAtMTsKICAgIH0KCiAgICBjdHgtPmJ1Zl9wdHJzW2N0eC0+Y3VyX2luZGV4XS5yZWZlcmVuY2UgPSAxOwogICAgY3R4LT5idWZfcHRyc1tjdHgtPmN1cl9pbmRleF0ucGljdF90eXBlID0gaXNfcGZyYW1lID8gQVZfUElDVFVSRV9UWVBFX1A6QVZfUElDVFVSRV9UWVBFX0k7CiAgICBpZihmZl90aHJlYWRfZ2V0X2J1ZmZlcihhdmN0eCwgJmN0eC0+YnVmX3B0cnNbY3R4LT5jdXJfaW5kZXhdKSkgewogICAgICAgIGF2X2xvZyhhdmN0eCwgQVZfTE9HX0VSUk9SLCAiZ2V0X2J1ZmZlcigpIGZhaWxlZFxuIik7CiAgICAgICAgcmV0dXJuIC0xOwogICAgfQoKICAgIGN0eC0+bmV4dF9wcmV2X2luZGV4ID0gY3R4LT5jdXJfaW5kZXg7CiAgICBjdHgtPm5leHRfY3VyX2luZGV4ICA9IChjdHgtPmN1cl9pbmRleCAtIDEpICYgMTU7CgogICAgcHJlcGFyZV9hdnBpYyhjdHgsICZjdHgtPmZsaXBwZWRfcHRyc1tjdHgtPmN1cl9pbmRleF0sCiAgICAgICAgICAgICAgICAgIChBVlBpY3R1cmUqKSAmY3R4LT5idWZfcHRyc1tjdHgtPmN1cl9pbmRleF0pOwoKICAgIGZmX3RocmVhZF9maW5pc2hfc2V0dXAoYXZjdHgpOwoKICAgIGF2X2Zhc3RfbWFsbG9jKCZjdHgtPnN3YXBfYnVmLCAmY3R4LT5zd2FwX2J1Zl9zaXplLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzd2FwX2J1Zl9zaXplICsgRkZfSU5QVVRfQlVGRkVSX1BBRERJTkdfU0laRSk7CiAgICBpZighY3R4LT5zd2FwX2J1ZikKICAgICAgICByZXR1cm4gQVZFUlJPUihFTk9NRU0pOwoKICAgIGN0eC0+ZHNwLmJzd2FwX2J1ZihjdHgtPnN3YXBfYnVmLAogICAgICAgICAgICAgICAgICAgICAgICAoY29uc3QgdWludDMyX3QqKSBidWYsCiAgICAgICAgICAgICAgICAgICAgICAgIHN3YXBfYnVmX3NpemU+PjIpOwogICAgaW5pdF9nZXRfYml0cygmY3R4LT5nYiwgY3R4LT5zd2FwX2J1Ziwgc3dhcF9idWZfc2l6ZSA8PCAzKTsKCiAgICBpZighZGVjb2RlKGN0eCwgcXVhbGl0eSwgbnVtX2NvZWZmcywgIWlzX3BmcmFtZSkpIHsKICAgICAgICBpZiAoYXZjdHgtPmFjdGl2ZV90aHJlYWRfdHlwZSZGRl9USFJFQURfRlJBTUUpCiAgICAgICAgICAgIGZmX3RocmVhZF9yZXBvcnRfcHJvZ3Jlc3MoJmN0eC0+YnVmX3B0cnNbY3R4LT5jdXJfaW5kZXhdLCBJTlRfTUFYLCAwKTsKICAgICAgICBlbHNlIHsKICAgICAgICAgICAgZmZfdGhyZWFkX3JlbGVhc2VfYnVmZmVyKGF2Y3R4LCAmY3R4LT5idWZfcHRyc1tjdHgtPmN1cl9pbmRleF0pOwogICAgICAgICAgICByZXR1cm4gLTE7CiAgICAgICAgfQogICAgfQoKICAgICooQVZGcmFtZSopZGF0YSA9IGN0eC0+YnVmX3B0cnNbY3R4LT5jdXJfaW5kZXhdOwogICAgKmRhdGFfc2l6ZSA9IHNpemVvZihBVkZyYW1lKTsKCiAgICBjdHgtPnByZXZfaW5kZXggPSBjdHgtPm5leHRfcHJldl9pbmRleDsKICAgIGN0eC0+Y3VyX2luZGV4ICA9IGN0eC0+bmV4dF9jdXJfaW5kZXg7CgogICAgLyogT25seSByZWxlYXNlIGZyYW1lcyB0aGF0IGFyZW4ndCB1c2VkIGZvciBiYWNrcmVmZXJlbmNlcyBhbnltb3JlICovCiAgICBpZihjdHgtPmJ1Zl9wdHJzW2N0eC0+Y3VyX2luZGV4XS5kYXRhWzBdKQogICAgICAgIGZmX3RocmVhZF9yZWxlYXNlX2J1ZmZlcihhdmN0eCwgJmN0eC0+YnVmX3B0cnNbY3R4LT5jdXJfaW5kZXhdKTsKCiAgICByZXR1cm4gYnVmX3NpemU7Cn0KCnN0YXRpYyBhdl9jb2xkIGludCBtaW1pY19kZWNvZGVfZW5kKEFWQ29kZWNDb250ZXh0ICphdmN0eCkKewogICAgTWltaWNDb250ZXh0ICpjdHggPSBhdmN0eC0+cHJpdl9kYXRhOwogICAgaW50IGk7CgogICAgYXZfZnJlZShjdHgtPnN3YXBfYnVmKTsKCiAgICBpZihhdmN0eC0+aXNfY29weSkgcmV0dXJuIDA7CgogICAgZm9yKGkgPSAwOyBpIDwgMTY7IGkrKykKICAgICAgICBpZihjdHgtPmJ1Zl9wdHJzW2ldLmRhdGFbMF0pCiAgICAgICAgICAgIGZmX3RocmVhZF9yZWxlYXNlX2J1ZmZlcihhdmN0eCwgJmN0eC0+YnVmX3B0cnNbaV0pOwogICAgZnJlZV92bGMoJmN0eC0+dmxjKTsKCiAgICByZXR1cm4gMDsKfQoKQVZDb2RlYyBmZl9taW1pY19kZWNvZGVyID0gewogICAgIm1pbWljIiwKICAgIEFWTUVESUFfVFlQRV9WSURFTywKICAgIENPREVDX0lEX01JTUlDLAogICAgc2l6ZW9mKE1pbWljQ29udGV4dCksCiAgICBtaW1pY19kZWNvZGVfaW5pdCwKICAgIE5VTEwsCiAgICBtaW1pY19kZWNvZGVfZW5kLAogICAgbWltaWNfZGVjb2RlX2ZyYW1lLAogICAgQ09ERUNfQ0FQX0RSMSB8IENPREVDX0NBUF9GUkFNRV9USFJFQURTLAogICAgLmxvbmdfbmFtZSA9IE5VTExfSUZfQ09ORklHX1NNQUxMKCJNaW1pYyIpLAogICAgLnVwZGF0ZV90aHJlYWRfY29udGV4dCA9IE9OTFlfSUZfVEhSRUFEU19FTkFCTEVEKG1pbWljX2RlY29kZV91cGRhdGVfdGhyZWFkX2NvbnRleHQpCn07Cg==