LyoKICogQ29weXJpZ2h0IChDKSAyMDA1ICBPbGUgQW5kcukgVmFkbGEgUmF2buVzIDxvbGVhdnJAZ21haWwuY29tPgogKiBDb3B5cmlnaHQgKEMpIDIwMDggIFJhbWlybyBQb2xsYSA8cmFtaXJvQGxpc2hhLnVmc2MuYnI+CiAqCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIEZGbXBlZy4KICoKICogRkZtcGVnIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vcgogKiBtb2RpZnkgaXQgdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljCiAqIExpY2Vuc2UgYXMgcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb247IGVpdGhlcgogKiB2ZXJzaW9uIDIuMSBvZiB0aGUgTGljZW5zZSwgb3IgKGF0IHlvdXIgb3B0aW9uKSBhbnkgbGF0ZXIgdmVyc2lvbi4KICoKICogRkZtcGVnIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsCiAqIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mCiAqIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VCiAqIExlc3NlciBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGZvciBtb3JlIGRldGFpbHMuCiAqCiAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWMKICogTGljZW5zZSBhbG9uZyB3aXRoIEZGbXBlZzsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZQogKiBGb3VuZGF0aW9uLCBJbmMuLCA1MSBGcmFua2xpbiBTdHJlZXQsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BIDAyMTEwLTEzMDEgVVNBCiAqLwoKI2luY2x1ZGUgPHN0ZGxpYi5oPgojaW5jbHVkZSA8c3RyaW5nLmg+CiNpbmNsdWRlIDxzdGRpbnQuaD4KCiNpbmNsdWRlICJhdmNvZGVjLmgiCiNpbmNsdWRlICJiaXRzdHJlYW0uaCIKI2luY2x1ZGUgImJ5dGVzdHJlYW0uaCIKI2luY2x1ZGUgImRzcHV0aWwuaCIKCiNkZWZpbmUgTUlNSUNfSEVBREVSX1NJWkUgICAyMAoKdHlwZWRlZiBzdHJ1Y3QgewogICAgQVZDb2RlY0NvbnRleHQgKmF2Y3R4OwoKICAgIGludCAgICAgICAgICAgICBudW1fdmJsb2Nrc1szXTsKICAgIGludCAgICAgICAgICAgICBudW1faGJsb2Nrc1szXTsKCiAgICB1aW50OF90ICAgICAgICAqc3dhcF9idWY7CiAgICBpbnQgICAgICAgICAgICAgc3dhcF9idWZfc2l6ZTsKCiAgICBpbnQgICAgICAgICAgICAgY3VyX2luZGV4OwogICAgaW50ICAgICAgICAgICAgIHByZXZfaW5kZXg7CgogICAgQVZGcmFtZSAgICAgICAgIGJ1Zl9wdHJzICAgIFsxNl07CiAgICBBVlBpY3R1cmUgICAgICAgZmxpcHBlZF9wdHJzWzE2XTsKCiAgICBERUNMQVJFX0FMSUdORURfMTYoRENURUxFTSwgZGN0X2Jsb2NrWzY0XSk7CgogICAgR2V0Qml0Q29udGV4dCAgIGdiOwogICAgU2NhblRhYmxlICAgICAgIHNjYW50YWJsZTsKICAgIERTUENvbnRleHQgICAgICBkc3A7CiAgICBWTEMgICAgICAgICAgICAgdmxjOwp9IE1pbWljQ29udGV4dDsKCnN0YXRpYyBjb25zdCB1aW50MzJfdCBodWZmY29kZXNbXSA9IHsKICAgIDB4MDAwMDAwMGEsIDB4MDAwMDAwMDAsIDB4MDAwMDAwMDAsIDB4MDAwMDAwMDAsIDB4MDAwMDAwMDAsIDB4MDAwMDAwMDAsCiAgICAweDAwMDAwMDAwLCAweDAwMDAwMDAwLCAweDAwMDAwMDAwLCAweDAwMDAwMDAwLCAweDAwMDAwMDAwLCAweDAwMDAwMDAwLAogICAgMHgwMDAwMDAwMCwgMHgwMDAwMDAwMCwgMHgwMDAwMDAwMCwgMHgwMDAwMDAwMCwgMHgwMDAwMDAwMCwgMHgwMDAwMDAwYiwKICAgIDB4MDAwMDAwMWIsIDB4MDAwMDAwMzgsIDB4MDAwMDAwNzgsIDB4MDAwMDAwNzksIDB4MDAwMDAwN2EsIDB4MDAwMDAwZjksCiAgICAweDAwMDAwMGZhLCAweDAwMDAwM2ZiLCAweDAwMDAwN2Y4LCAweDAwMDAwN2Y5LCAweDAwMDAwN2ZhLCAweDAwMDAwN2ZiLAogICAgMHgwMDAwMGZmOCwgMHgwMDAwMGZmOSwgMHgwMDAwMDAwMSwgMHgwMDAwMDAzOSwgMHgwMDAwMDA3YiwgMHgwMDAwMDBmYiwKICAgIDB4MDAwMDAxZjgsIDB4MDAwMDAxZjksIDB4MDAwMDBmZmEsIDB4MDAwMDBmZmIsIDB4MDAwMDFmZjgsIDB4MDAwMDFmZjksCiAgICAweDAwMDAxZmZhLCAweDAwMDAxZmZiLCAweDAwMDAzZmY4LCAweDAwMDAzZmY5LCAweDAwMDAzZmZhLCAweDAwMDAwMDAwLAogICAgMHgwMDAwMDAwNCwgMHgwMDAwMDAzYSwgMHgwMDAwMDFmYSwgMHgwMDAwM2ZmYiwgMHgwMDAwN2ZmOCwgMHgwMDAwN2ZmOSwKICAgIDB4MDAwMDdmZmEsIDB4MDAwMDdmZmIsIDB4MDAwMGZmZjgsIDB4MDAwMGZmZjksIDB4MDAwMGZmZmEsIDB4MDAwMGZmZmIsCiAgICAweDAwMDFmZmY4LCAweDAwMDFmZmY5LCAweDAwMDFmZmZhLCAweDAwMDAwMDAwLCAweDAwMDAwMDBjLCAweDAwMDAwMGY4LAogICAgMHgwMDAwMDFmYiwgMHgwMDAxZmZmYiwgMHgwMDAzZmZmOCwgMHgwMDAzZmZmOSwgMHgwMDAzZmZmYSwgMHgwMDAzZmZmYiwKICAgIDB4MDAwN2ZmZjgsIDB4MDAwN2ZmZjksIDB4MDAwN2ZmZmEsIDB4MDAwN2ZmZmIsIDB4MDAwZmZmZjgsIDB4MDAwZmZmZjksCiAgICAweDAwMGZmZmZhLCAweDAwMDAwMDAwLCAweDAwMDAwMDFhLCAweDAwMDAwM2Y4LCAweDAwMGZmZmZiLCAweDAwMWZmZmY4LAogICAgMHgwMDFmZmZmOSwgMHgwMDFmZmZmYSwgMHgwMDFmZmZmYiwgMHgwMDNmZmZmOCwgMHgwMDNmZmZmOSwgMHgwMDNmZmZmYSwKICAgIDB4MDAzZmZmZmIsIDB4MDA3ZmZmZjgsIDB4MDA3ZmZmZjksIDB4MDA3ZmZmZmEsIDB4MDA3ZmZmZmIsIDB4MDAwMDAwMDAsCiAgICAweDAwMDAwMDNiLCAweDAwMDAwM2Y5LCAweDAwZmZmZmY4LCAweDAwZmZmZmY5LCAweDAwZmZmZmZhLCAweDAwZmZmZmZiLAogICAgMHgwMWZmZmZmOCwgMHgwMWZmZmZmOSwgMHgwMWZmZmZmYSwgMHgwMWZmZmZmYiwgMHgwM2ZmZmZmOCwgMHgwM2ZmZmZmOSwKICAgIDB4MDNmZmZmZmEsIDB4MDNmZmZmZmIsIDB4MDdmZmZmZjgsIDB4MDAwMDAwMDAsIDB4MDAwMDAzZmEsIDB4MDdmZmZmZjksCiAgICAweDA3ZmZmZmZhLCAweDA3ZmZmZmZiLCAweDBmZmZmZmY4LCAweDBmZmZmZmY5LCAweDBmZmZmZmZhLCAweDBmZmZmZmZiLAogICAgMHgxZmZmZmZmOCwgMHgxZmZmZmZmOSwgMHgxZmZmZmZmYSwgMHgxZmZmZmZmYiwgMHgzZmZmZmZmOCwgMHgzZmZmZmZmOSwKICAgIDB4M2ZmZmZmZmEsCn07CgpzdGF0aWMgY29uc3QgdWludDhfdCBodWZmYml0c1tdID0gewogICAgIDQsICAwLCAgMCwgIDAsICAwLCAgMCwgIDAsICAwLCAgMCwgIDAsICAwLCAgMCwKICAgICAwLCAgMCwgIDAsICAwLCAgMiwgIDQsICA1LCAgNiwgIDcsICA3LCAgNywgIDgsCiAgICAgOCwgMTAsIDExLCAxMSwgMTEsIDExLCAxMiwgMTIsICAyLCAgNiwgIDcsICA4LAogICAgIDksICA5LCAxMiwgMTIsIDEzLCAxMywgMTMsIDEzLCAxNCwgMTQsIDE0LCAgMCwKICAgICAzLCAgNiwgIDksIDE0LCAxNSwgMTUsIDE1LCAxNSwgMTYsIDE2LCAxNiwgMTYsCiAgICAxNywgMTcsIDE3LCAgMCwgIDQsICA4LCAgOSwgMTcsIDE4LCAxOCwgMTgsIDE4LAogICAgMTksIDE5LCAxOSwgMTksIDIwLCAyMCwgMjAsICAwLCAgNSwgMTAsIDIwLCAyMSwKICAgIDIxLCAyMSwgMjEsIDIyLCAyMiwgMjIsIDIyLCAyMywgMjMsIDIzLCAyMywgIDAsCiAgICAgNiwgMTAsIDI0LCAyNCwgMjQsIDI0LCAyNSwgMjUsIDI1LCAyNSwgMjYsIDI2LAogICAgMjYsIDI2LCAyNywgIDAsIDEwLCAyNywgMjcsIDI3LCAyOCwgMjgsIDI4LCAyOCwKICAgIDI5LCAyOSwgMjksIDI5LCAzMCwgMzAsIDMwLAp9OwoKc3RhdGljIGNvbnN0IHVpbnQ4X3QgY29sX3phZ1s2NF0gPSB7CiAgICAgMCwgIDgsICAxLCAgMiwgIDksIDE2LCAyNCwgMTcsCiAgICAxMCwgIDMsICA0LCAxMSwgMTgsIDI1LCAzMiwgNDAsCiAgICAzMywgMjYsIDE5LCAxMiwgIDUsICA2LCAxMywgMjAsCiAgICAyNywgMzQsIDQxLCA0OCwgNTYsIDQ5LCA0MiwgMzUsCiAgICAyOCwgMjEsIDE0LCAgNywgMTUsIDIyLCAyOSwgMzYsCiAgICA0MywgNTAsIDU3LCA1OCwgNTEsIDQ0LCAzNywgMzAsCiAgICAyMywgMzEsIDM4LCA0NSwgNTIsIDU5LCAzOSwgNDYsCiAgICA1MywgNjAsIDYxLCA1NCwgNDcsIDU1LCA2MiwgNjMsCn07CgpzdGF0aWMgYXZfY29sZCBpbnQgbWltaWNfZGVjb2RlX2luaXQoQVZDb2RlY0NvbnRleHQgKmF2Y3R4KQp7CiAgICBNaW1pY0NvbnRleHQgKmN0eCA9IGF2Y3R4LT5wcml2X2RhdGE7CgogICAgY3R4LT5wcmV2X2luZGV4ID0gMDsKICAgIGN0eC0+Y3VyX2luZGV4ID0gMTU7CgogICAgaWYoaW5pdF92bGMoJmN0eC0+dmxjLCAxMSwgRkZfQVJSQVlfRUxFTVMoaHVmZmJpdHMpLAogICAgICAgICAgICAgICAgIGh1ZmZiaXRzLCAxLCAxLCBodWZmY29kZXMsIDQsIDQsIDApKSB7CiAgICAgICAgYXZfbG9nKGF2Y3R4LCBBVl9MT0dfRVJST1IsICJlcnJvciBpbml0aWFsaXppbmcgdmxjIHRhYmxlXG4iKTsKICAgICAgICByZXR1cm4gLTE7CiAgICB9CiAgICBkc3B1dGlsX2luaXQoJmN0eC0+ZHNwLCBhdmN0eCk7CiAgICBmZl9pbml0X3NjYW50YWJsZShjdHgtPmRzcC5pZGN0X3Blcm11dGF0aW9uLCAmY3R4LT5zY2FudGFibGUsIGNvbF96YWcpOwoKICAgIHJldHVybiAwOwp9CgpzdGF0aWMgY29uc3QgaW50OF90IHZsY2RlY19sb29rdXBbOV1bNjRdID0gewogICAgeyAgICAwLCB9LAogICAgeyAgIC0xLCAgIDEsIH0sCiAgICB7ICAgLTMsICAgMywgICAtMiwgICAyLCB9LAogICAgeyAgIC03LCAgIDcsICAgLTYsICAgNiwgICAtNSwgICA1LCAgIC00LCAgIDQsIH0sCiAgICB7ICAtMTUsICAxNSwgIC0xNCwgIDE0LCAgLTEzLCAgMTMsICAtMTIsICAxMiwKICAgICAgIC0xMSwgIDExLCAgLTEwLCAgMTAsICAgLTksICAgOSwgICAtOCwgICA4LCB9LAogICAgeyAgLTMxLCAgMzEsICAtMzAsICAzMCwgIC0yOSwgIDI5LCAgLTI4LCAgMjgsCiAgICAgICAtMjcsICAyNywgIC0yNiwgIDI2LCAgLTI1LCAgMjUsICAtMjQsICAyNCwKICAgICAgIC0yMywgIDIzLCAgLTIyLCAgMjIsICAtMjEsICAyMSwgIC0yMCwgIDIwLAogICAgICAgLTE5LCAgMTksICAtMTgsICAxOCwgIC0xNywgIDE3LCAgLTE2LCAgMTYsIH0sCiAgICB7ICAtNjMsICA2MywgIC02MiwgIDYyLCAgLTYxLCAgNjEsICAtNjAsICA2MCwKICAgICAgIC01OSwgIDU5LCAgLTU4LCAgNTgsICAtNTcsICA1NywgIC01NiwgIDU2LAogICAgICAgLTU1LCAgNTUsICAtNTQsICA1NCwgIC01MywgIDUzLCAgLTUyLCAgNTIsCiAgICAgICAtNTEsICA1MSwgIC01MCwgIDUwLCAgLTQ5LCAgNDksICAtNDgsICA0OCwKICAgICAgIC00NywgIDQ3LCAgLTQ2LCAgNDYsICAtNDUsICA0NSwgIC00NCwgIDQ0LAogICAgICAgLTQzLCAgNDMsICAtNDIsICA0MiwgIC00MSwgIDQxLCAgLTQwLCAgNDAsCiAgICAgICAtMzksICAzOSwgIC0zOCwgIDM4LCAgLTM3LCAgMzcsICAtMzYsICAzNiwKICAgICAgIC0zNSwgIDM1LCAgLTM0LCAgMzQsICAtMzMsICAzMywgIC0zMiwgIDMyLCB9LAogICAgeyAtMTI3LCAxMjcsIC0xMjYsIDEyNiwgLTEyNSwgMTI1LCAtMTI0LCAxMjQsCiAgICAgIC0xMjMsIDEyMywgLTEyMiwgMTIyLCAtMTIxLCAxMjEsIC0xMjAsIDEyMCwKICAgICAgLTExOSwgMTE5LCAtMTE4LCAxMTgsIC0xMTcsIDExNywgLTExNiwgMTE2LAogICAgICAtMTE1LCAxMTUsIC0xMTQsIDExNCwgLTExMywgMTEzLCAtMTEyLCAxMTIsCiAgICAgIC0xMTEsIDExMSwgLTExMCwgMTEwLCAtMTA5LCAxMDksIC0xMDgsIDEwOCwKICAgICAgLTEwNywgMTA3LCAtMTA2LCAxMDYsIC0xMDUsIDEwNSwgLTEwNCwgMTA0LAogICAgICAtMTAzLCAxMDMsIC0xMDIsIDEwMiwgLTEwMSwgMTAxLCAtMTAwLCAxMDAsCiAgICAgICAtOTksICA5OSwgIC05OCwgIDk4LCAgLTk3LCAgOTcsICAtOTYsICA5NiwgfSwKICAgIHsgIC05NSwgIDk1LCAgLTk0LCAgOTQsICAtOTMsICA5MywgIC05MiwgIDkyLAogICAgICAgLTkxLCAgOTEsICAtOTAsICA5MCwgIC04OSwgIDg5LCAgLTg4LCAgODgsCiAgICAgICAtODcsICA4NywgIC04NiwgIDg2LCAgLTg1LCAgODUsICAtODQsICA4NCwKICAgICAgIC04MywgIDgzLCAgLTgyLCAgODIsICAtODEsICA4MSwgIC04MCwgIDgwLAogICAgICAgLTc5LCAgNzksICAtNzgsICA3OCwgIC03NywgIDc3LCAgLTc2LCAgNzYsCiAgICAgICAtNzUsICA3NSwgIC03NCwgIDc0LCAgLTczLCAgNzMsICAtNzIsICA3MiwKICAgICAgIC03MSwgIDcxLCAgLTcwLCAgNzAsICAtNjksICA2OSwgIC02OCwgIDY4LAogICAgICAgLTY3LCAgNjcsICAtNjYsICA2NiwgIC02NSwgIDY1LCAgLTY0LCAgNjQsIH0sCn07CgpzdGF0aWMgaW50IHZsY19kZWNvZGVfYmxvY2soTWltaWNDb250ZXh0ICpjdHgsIGludCBudW1fY29lZmZzLCBpbnQgcXNjYWxlKQp7CiAgICBEQ1RFTEVNICpibG9jayA9IGN0eC0+ZGN0X2Jsb2NrOwogICAgdW5zaWduZWQgaW50IHBvczsKCiAgICBjdHgtPmRzcC5jbGVhcl9ibG9jayhibG9jayk7CgogICAgYmxvY2tbMF0gPSBnZXRfYml0cygmY3R4LT5nYiwgOCkgPDwgMzsKCiAgICBmb3IocG9zID0gMTsgcG9zIDwgbnVtX2NvZWZmczsgcG9zKyspIHsKICAgICAgICB1aW50MzJfdCB2bGMsIG51bV9iaXRzOwogICAgICAgIGludCB2YWx1ZTsKICAgICAgICBpbnQgY29lZmY7CgogICAgICAgIHZsYyA9IGdldF92bGMyKCZjdHgtPmdiLCBjdHgtPnZsYy50YWJsZSwgY3R4LT52bGMuYml0cywgMyk7CiAgICAgICAgaWYoIXZsYykgLyogZW5kLW9mLWJsb2NrIGNvZGUgKi8KICAgICAgICAgICAgcmV0dXJuIDE7CiAgICAgICAgaWYodmxjID09IC0xKQogICAgICAgICAgICByZXR1cm4gMDsKCiAgICAgICAgLyogcG9zX2FkZCBhbmQgbnVtX2JpdHMgYXJlIGNvZGVkIGluIHRoZSB2bGMgY29kZSAqLwogICAgICAgIHBvcyArPSAgICAgdmxjJjE1OyAvLyBwb3NfYWRkCiAgICAgICAgbnVtX2JpdHMgPSB2bGM+PjQ7IC8vIG51bV9iaXRzCgogICAgICAgIGlmKHBvcyA+PSA2NCkKICAgICAgICAgICAgcmV0dXJuIDA7CgogICAgICAgIHZhbHVlID0gZ2V0X2JpdHMoJmN0eC0+Z2IsIG51bV9iaXRzKTsKCiAgICAgICAgLyogRkZtcGVnJ3MgSURDVCBiZWhhdmVzIHNvbWV3aGF0IGRpZmZlcmVudCBmcm9tIHRoZSBvcmlnaW5hbCBjb2RlLCBzbwogICAgICAgICAqIGEgZmFjdG9yIG9mIDQgd2FzIGFkZGVkIHRvIHRoZSBpbnB1dCAqLwoKICAgICAgICBjb2VmZiA9IHZsY2RlY19sb29rdXBbbnVtX2JpdHNdW3ZhbHVlXTsKICAgICAgICBpZihwb3M8MykKICAgICAgICAgICAgY29lZmYgPDw9IDQ7CiAgICAgICAgZWxzZSAvKiBUT0RPIFVzZSA+PiAxMCBpbnN0ZWFkIG9mIC8gMTAwMSAqLwogICAgICAgICAgICBjb2VmZiA9IChjb2VmZiAqIHFzY2FsZSkgLyAxMDAxOwoKICAgICAgICBibG9ja1tjdHgtPnNjYW50YWJsZS5wZXJtdXRhdGVkW3Bvc11dID0gY29lZmY7CiAgICB9CgogICAgcmV0dXJuIDE7Cn0KCnN0YXRpYyBpbnQgZGVjb2RlKE1pbWljQ29udGV4dCAqY3R4LCBpbnQgcXVhbGl0eSwgaW50IG51bV9jb2VmZnMsCiAgICAgICAgICAgICAgICAgIGludCBpc19pZnJhbWUpCnsKICAgIGludCB5LCB4LCBwbGFuZTsKCiAgICBmb3IocGxhbmUgPSAwOyBwbGFuZSA8IDM7IHBsYW5lKyspIHsKICAgICAgICBjb25zdCBpbnQgaXNfY2hyb21hID0gISFwbGFuZTsKICAgICAgICBjb25zdCBpbnQgcXNjYWxlID0gYXZfY2xpcCgxMDAwMC1xdWFsaXR5LGlzX2Nocm9tYT8xMDAwOjIwMDAsMTAwMDApPDwyOwogICAgICAgIGNvbnN0IGludCBzdHJpZGUgPSBjdHgtPmZsaXBwZWRfcHRyc1tjdHgtPmN1cl9pbmRleF0ubGluZXNpemVbcGxhbmVdOwogICAgICAgIGNvbnN0IHVpbnQ4X3QgKnNyYyA9IGN0eC0+ZmxpcHBlZF9wdHJzW2N0eC0+cHJldl9pbmRleF0uZGF0YVtwbGFuZV07CiAgICAgICAgdWludDhfdCAgICAgICAqZHN0ID0gY3R4LT5mbGlwcGVkX3B0cnNbY3R4LT5jdXJfaW5kZXggXS5kYXRhW3BsYW5lXTsKCiAgICAgICAgZm9yKHkgPSAwOyB5IDwgY3R4LT5udW1fdmJsb2Nrc1twbGFuZV07IHkrKykgewogICAgICAgICAgICBmb3IoeCA9IDA7IHggPCBjdHgtPm51bV9oYmxvY2tzW3BsYW5lXTsgeCsrKSB7CgogICAgICAgICAgICAgICAgLyogQ2hlY2sgZm9yIGEgY2hhbmdlIGNvbmRpdGlvbiBpbiB0aGUgY3VycmVudCBibG9jay4KICAgICAgICAgICAgICAgICAqIC0gaWZyYW1lcyBhbHdheXMgY2hhbmdlLgogICAgICAgICAgICAgICAgICogLSBMdW1hIHBsYW5lIGNoYW5nZXMgb24gZ2V0X2JpdHMxID09IDAKICAgICAgICAgICAgICAgICAqIC0gQ2hyb21hIHBsYW5lcyBjaGFuZ2Ugb24gZ2V0X2JpdHMxID09IDEgKi8KICAgICAgICAgICAgICAgIGlmKGlzX2lmcmFtZSB8fCBnZXRfYml0czEoJmN0eC0+Z2IpID09IGlzX2Nocm9tYSkgewoKICAgICAgICAgICAgICAgICAgICAvKiBMdW1hIHBsYW5lcyBtYXkgdXNlIGEgYmFja3JlZmVyZW5jZSBmcm9tIHRoZSAxNSBsYXN0CiAgICAgICAgICAgICAgICAgICAgICogZnJhbWVzIHByZWNlZGluZyB0aGUgcHJldmlvdXMuIChnZXRfYml0czEgPT0gMSkKICAgICAgICAgICAgICAgICAgICAgKiBDaHJvbWEgcGxhbmVzIGRvbid0IHVzZSBiYWNrcmVmZXJlbmNlcy4gKi8KICAgICAgICAgICAgICAgICAgICBpZihpc19jaHJvbWEgfHwgaXNfaWZyYW1lIHx8ICFnZXRfYml0czEoJmN0eC0+Z2IpKSB7CgogICAgICAgICAgICAgICAgICAgICAgICBpZighdmxjX2RlY29kZV9ibG9jayhjdHgsIG51bV9jb2VmZnMsIHFzY2FsZSkpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gMDsKICAgICAgICAgICAgICAgICAgICAgICAgY3R4LT5kc3AuaWRjdF9wdXQoZHN0LCBzdHJpZGUsIGN0eC0+ZGN0X2Jsb2NrKTsKICAgICAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgICAgICB1bnNpZ25lZCBpbnQgYmFja3JlZiA9IGdldF9iaXRzKCZjdHgtPmdiLCA0KTsKICAgICAgICAgICAgICAgICAgICAgICAgaW50IGluZGV4ID0gKGN0eC0+Y3VyX2luZGV4K2JhY2tyZWYpJjE1OwogICAgICAgICAgICAgICAgICAgICAgICB1aW50OF90ICpwID0gY3R4LT5mbGlwcGVkX3B0cnNbaW5kZXhdLmRhdGFbMF07CgogICAgICAgICAgICAgICAgICAgICAgICBpZihwKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBwICs9IHNyYyAtCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY3R4LT5mbGlwcGVkX3B0cnNbY3R4LT5wcmV2X2luZGV4XS5kYXRhW3BsYW5lXTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGN0eC0+ZHNwLnB1dF9waXhlbHNfdGFiWzFdWzBdKGRzdCwgcCwgc3RyaWRlLCA4KTsKICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGF2X2xvZyhjdHgtPmF2Y3R4LCBBVl9MT0dfRVJST1IsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiTm8gc3VjaCBiYWNrcmVmZXJlbmNlISBCdWdneSBzYW1wbGUuXG4iKTsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgY3R4LT5kc3AucHV0X3BpeGVsc190YWJbMV1bMF0oZHN0LCBzcmMsIHN0cmlkZSwgOCk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBzcmMgKz0gODsKICAgICAgICAgICAgICAgIGRzdCArPSA4OwogICAgICAgICAgICB9CiAgICAgICAgICAgIHNyYyArPSAoc3RyaWRlIC0gY3R4LT5udW1faGJsb2Nrc1twbGFuZV0pPDwzOwogICAgICAgICAgICBkc3QgKz0gKHN0cmlkZSAtIGN0eC0+bnVtX2hibG9ja3NbcGxhbmVdKTw8MzsKICAgICAgICB9CiAgICB9CgogICAgcmV0dXJuIDE7Cn0KCi8qKgogKiBGbGlwIHRoZSBidWZmZXIgdXBzaWRlLWRvd24gYW5kIHB1dCBpdCBpbiB0aGUgWVZVIG9yZGVyIHRvIG1hdGNoIHRoZQogKiB3YXkgTWltaWMgZW5jb2RlcyBmcmFtZXMuCiAqLwpzdGF0aWMgdm9pZCBwcmVwYXJlX2F2cGljKE1pbWljQ29udGV4dCAqY3R4LCBBVlBpY3R1cmUgKmRzdCwgQVZQaWN0dXJlICpzcmMpCnsKICAgIGludCBpOwogICAgZHN0LT5kYXRhWzBdID0gc3JjLT5kYXRhWzBdKyggY3R4LT5hdmN0eC0+aGVpZ2h0ICAgIC0xKSpzcmMtPmxpbmVzaXplWzBdOwogICAgZHN0LT5kYXRhWzFdID0gc3JjLT5kYXRhWzJdKygoY3R4LT5hdmN0eC0+aGVpZ2h0Pj4xKS0xKSpzcmMtPmxpbmVzaXplWzJdOwogICAgZHN0LT5kYXRhWzJdID0gc3JjLT5kYXRhWzFdKygoY3R4LT5hdmN0eC0+aGVpZ2h0Pj4xKS0xKSpzcmMtPmxpbmVzaXplWzFdOwogICAgZm9yKGkgPSAwOyBpIDwgMzsgaSsrKQogICAgICAgIGRzdC0+bGluZXNpemVbaV0gPSAtc3JjLT5saW5lc2l6ZVtpXTsKfQoKc3RhdGljIGludCBtaW1pY19kZWNvZGVfZnJhbWUoQVZDb2RlY0NvbnRleHQgKmF2Y3R4LCB2b2lkICpkYXRhLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQgKmRhdGFfc2l6ZSwgY29uc3QgdWludDhfdCAqYnVmLCBpbnQgYnVmX3NpemUpCnsKICAgIE1pbWljQ29udGV4dCAqY3R4ID0gYXZjdHgtPnByaXZfZGF0YTsKICAgIGludCBpc19wZnJhbWU7CiAgICBpbnQgd2lkdGgsIGhlaWdodDsKICAgIGludCBxdWFsaXR5LCBudW1fY29lZmZzOwogICAgaW50IHN3YXBfYnVmX3NpemUgPSBidWZfc2l6ZSAtIE1JTUlDX0hFQURFUl9TSVpFOwoKICAgIGlmKGJ1Zl9zaXplIDwgTUlNSUNfSEVBREVSX1NJWkUpIHsKICAgICAgICBhdl9sb2coYXZjdHgsIEFWX0xPR19FUlJPUiwgImluc3VmZmljaWVudCBkYXRhXG4iKTsKICAgICAgICByZXR1cm4gLTE7CiAgICB9CgogICAgYnVmICAgICAgICs9IDI7IC8qIHNvbWUgY29uc3RhbnQgKGFsd2F5cyAyNTYpICovCiAgICBxdWFsaXR5ICAgID0gYnl0ZXN0cmVhbV9nZXRfbGUxNigmYnVmKTsKICAgIHdpZHRoICAgICAgPSBieXRlc3RyZWFtX2dldF9sZTE2KCZidWYpOwogICAgaGVpZ2h0ICAgICA9IGJ5dGVzdHJlYW1fZ2V0X2xlMTYoJmJ1Zik7CiAgICBidWYgICAgICAgKz0gNDsgLyogc29tZSBjb25zdGFudCAqLwogICAgaXNfcGZyYW1lICA9IGJ5dGVzdHJlYW1fZ2V0X2xlMzIoJmJ1Zik7CiAgICBudW1fY29lZmZzID0gYnl0ZXN0cmVhbV9nZXRfYnl0ZSgmYnVmKTsKICAgIGJ1ZiAgICAgICArPSAzOyAvKiBzb21lIGNvbnN0YW50ICovCgogICAgaWYoIWN0eC0+YXZjdHgpIHsKICAgICAgICBpbnQgaTsKCiAgICAgICAgaWYoISh3aWR0aCA9PSAxNjAgJiYgaGVpZ2h0ID09IDEyMCkgJiYKICAgICAgICAgICAhKHdpZHRoID09IDMyMCAmJiBoZWlnaHQgPT0gMjQwKSkgewogICAgICAgICAgICBhdl9sb2coYXZjdHgsIEFWX0xPR19FUlJPUiwgImludmFsaWQgd2lkdGgvaGVpZ2h0IVxuIik7CiAgICAgICAgICAgIHJldHVybiAtMTsKICAgICAgICB9CgogICAgICAgIGN0eC0+YXZjdHggICAgID0gYXZjdHg7CiAgICAgICAgYXZjdHgtPndpZHRoICAgPSB3aWR0aDsKICAgICAgICBhdmN0eC0+aGVpZ2h0ICA9IGhlaWdodDsKICAgICAgICBhdmN0eC0+cGl4X2ZtdCA9IFBJWF9GTVRfWVVWNDIwUDsKICAgICAgICBmb3IoaSA9IDA7IGkgPCAzOyBpKyspIHsKICAgICAgICAgICAgY3R4LT5udW1fdmJsb2Nrc1tpXSA9IC0oKC1oZWlnaHQpID4+ICgzICsgISFpKSk7CiAgICAgICAgICAgIGN0eC0+bnVtX2hibG9ja3NbaV0gPSAgICAgd2lkdGggICA+PiAoMyArICEhaSkgOwogICAgICAgIH0KICAgIH0gZWxzZSBpZih3aWR0aCAhPSBjdHgtPmF2Y3R4LT53aWR0aCB8fCBoZWlnaHQgIT0gY3R4LT5hdmN0eC0+aGVpZ2h0KSB7CiAgICAgICAgYXZfbG9nKGF2Y3R4LCBBVl9MT0dfRVJST1IsICJyZXNvbHV0aW9uIGNoYW5naW5nIGlzIG5vdCBzdXBwb3J0ZWRcbiIpOwogICAgICAgIHJldHVybiAtMTsKICAgIH0KCiAgICBpZihpc19wZnJhbWUgJiYgIWN0eC0+YnVmX3B0cnNbY3R4LT5wcmV2X2luZGV4XS5kYXRhWzBdKSB7CiAgICAgICAgYXZfbG9nKGF2Y3R4LCBBVl9MT0dfRVJST1IsICJkZWNvZGluZyBtdXN0IHN0YXJ0IHdpdGgga2V5ZnJhbWVcbiIpOwogICAgICAgIHJldHVybiAtMTsKICAgIH0KCiAgICBjdHgtPmJ1Zl9wdHJzW2N0eC0+Y3VyX2luZGV4XS5yZWZlcmVuY2UgPSAxOwogICAgaWYoYXZjdHgtPmdldF9idWZmZXIoYXZjdHgsICZjdHgtPmJ1Zl9wdHJzW2N0eC0+Y3VyX2luZGV4XSkpIHsKICAgICAgICBhdl9sb2coYXZjdHgsIEFWX0xPR19FUlJPUiwgImdldF9idWZmZXIoKSBmYWlsZWRcbiIpOwogICAgICAgIHJldHVybiAtMTsKICAgIH0KCiAgICBwcmVwYXJlX2F2cGljKGN0eCwgJmN0eC0+ZmxpcHBlZF9wdHJzW2N0eC0+Y3VyX2luZGV4XSwKICAgICAgICAgICAgICAgICAgKEFWUGljdHVyZSopICZjdHgtPmJ1Zl9wdHJzW2N0eC0+Y3VyX2luZGV4XSk7CgogICAgY3R4LT5zd2FwX2J1ZiA9IGF2X2Zhc3RfcmVhbGxvYyhjdHgtPnN3YXBfYnVmLCAmY3R4LT5zd2FwX2J1Zl9zaXplLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzd2FwX2J1Zl9zaXplICsgRkZfSU5QVVRfQlVGRkVSX1BBRERJTkdfU0laRSk7CiAgICBpZighY3R4LT5zd2FwX2J1ZikKICAgICAgICByZXR1cm4gQVZFUlJPUl9OT01FTTsKCiAgICBjdHgtPmRzcC5ic3dhcF9idWYoKHVpbnQzMl90KiljdHgtPnN3YXBfYnVmLAogICAgICAgICAgICAgICAgICAgICAgICAoY29uc3QgdWludDMyX3QqKSBidWYsCiAgICAgICAgICAgICAgICAgICAgICAgIHN3YXBfYnVmX3NpemU+PjIpOwogICAgaW5pdF9nZXRfYml0cygmY3R4LT5nYiwgY3R4LT5zd2FwX2J1Ziwgc3dhcF9idWZfc2l6ZSA8PCAzKTsKCiAgICBpZighZGVjb2RlKGN0eCwgcXVhbGl0eSwgbnVtX2NvZWZmcywgIWlzX3BmcmFtZSkpIHsKICAgICAgICBhdmN0eC0+cmVsZWFzZV9idWZmZXIoYXZjdHgsICZjdHgtPmJ1Zl9wdHJzW2N0eC0+Y3VyX2luZGV4XSk7CiAgICAgICAgcmV0dXJuIC0xOwogICAgfQoKICAgIGN0eC0+YnVmX3B0cnNbY3R4LT5jdXJfaW5kZXhdLnBpY3RfdHlwZSA9IGlzX3BmcmFtZSA/IEZGX1BfVFlQRTpGRl9JX1RZUEU7CiAgICAqKEFWRnJhbWUqKWRhdGEgPSBjdHgtPmJ1Zl9wdHJzW2N0eC0+Y3VyX2luZGV4XTsKICAgICpkYXRhX3NpemUgPSBzaXplb2YoQVZGcmFtZSk7CgogICAgY3R4LT5wcmV2X2luZGV4ID0gY3R4LT5jdXJfaW5kZXg7CiAgICBjdHgtPmN1cl9pbmRleC0tOwogICAgY3R4LT5jdXJfaW5kZXggJj0gMTU7CgogICAgLyogT25seSByZWxlYXNlIGZyYW1lcyB0aGF0IGFyZW4ndCB1c2VkIGZvciBiYWNrcmVmZXJlbmNlcyBhbnltb3JlICovCiAgICBpZihjdHgtPmJ1Zl9wdHJzW2N0eC0+Y3VyX2luZGV4XS5kYXRhWzBdKQogICAgICAgIGF2Y3R4LT5yZWxlYXNlX2J1ZmZlcihhdmN0eCwgJmN0eC0+YnVmX3B0cnNbY3R4LT5jdXJfaW5kZXhdKTsKCiAgICByZXR1cm4gYnVmX3NpemU7Cn0KCnN0YXRpYyBhdl9jb2xkIGludCBtaW1pY19kZWNvZGVfZW5kKEFWQ29kZWNDb250ZXh0ICphdmN0eCkKewogICAgTWltaWNDb250ZXh0ICpjdHggPSBhdmN0eC0+cHJpdl9kYXRhOwogICAgaW50IGk7CgogICAgYXZfZnJlZShjdHgtPnN3YXBfYnVmKTsKICAgIGZvcihpID0gMDsgaSA8IDE2OyBpKyspCiAgICAgICAgaWYoY3R4LT5idWZfcHRyc1tpXS5kYXRhWzBdKQogICAgICAgICAgICBhdmN0eC0+cmVsZWFzZV9idWZmZXIoYXZjdHgsICZjdHgtPmJ1Zl9wdHJzW2ldKTsKICAgIGZyZWVfdmxjKCZjdHgtPnZsYyk7CgogICAgcmV0dXJuIDA7Cn0KCkFWQ29kZWMgbWltaWNfZGVjb2RlciA9IHsKICAgICJtaW1pYyIsCiAgICBDT0RFQ19UWVBFX1ZJREVPLAogICAgQ09ERUNfSURfTUlNSUMsCiAgICBzaXplb2YoTWltaWNDb250ZXh0KSwKICAgIG1pbWljX2RlY29kZV9pbml0LAogICAgTlVMTCwKICAgIG1pbWljX2RlY29kZV9lbmQsCiAgICBtaW1pY19kZWNvZGVfZnJhbWUsCiAgICBDT0RFQ19DQVBfRFIxLAogICAgLmxvbmdfbmFtZSA9IE5VTExfSUZfQ09ORklHX1NNQUxMKCJNaW1pYyIpLAp9Owo=