LyoKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgdGhlIGNvcmVib290IHByb2plY3QuCiAqCiAqIENvcHlyaWdodCAoQykgMjAwMCBEZW5pcyBEb3dsaW5nIDxkcGRAYWxwaGFsaW5rLmNvbS5hdT4KICogQ29weXJpZ2h0IChDKSAyMDEwIEtlaXRoIEh1aSA8YnV1cmluQGdtYWlsLmNvbT4KICoKICogVGhpcyBwcm9ncmFtIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnkKICogaXQgdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBhcyBwdWJsaXNoZWQgYnkKICogdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbjsgZWl0aGVyIHZlcnNpb24gMiBvZiB0aGUgTGljZW5zZSwgb3IKICogKGF0IHlvdXIgb3B0aW9uKSBhbnkgbGF0ZXIgdmVyc2lvbi4KICoKICogVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsCiAqIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mCiAqIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUKICogR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgZm9yIG1vcmUgZGV0YWlscy4KICoKICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UKICogYWxvbmcgd2l0aCB0aGlzIHByb2dyYW07IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUKICogRm91bmRhdGlvbiwgSW5jLiwgNTEgRnJhbmtsaW4gU3QsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BIDAyMTEwLTEzMDEgVVNBCiAqLwoKLyoKICogSW50ZWwgUGVudGl1bSBMMiBDYWNoZSBpbml0aWFsaXphdGlvbi4KICogVGhpcyBjb2RlIHdhcyBkZXZlbG9wZWQgYnkgcmV2ZXJzZSBlbmdpbmVlcmluZwogKiB0aGUgQklPUy4gV2hlcmUgdGhlIGNvZGUgYWNjZXNzZXMgZG9jdW1lbnRlZAogKiByZWdpc3RlcnMgSSBoYXZlIGFkZGVkIGNvbW1lbnRzIGFzIGJlc3QgSSBjYW4uCiAqIFNvbWUgdW5kb2N1bWVudGVkIHJlZ2lzdGVycyBvbiB0aGUgUGVudGl1bSBJSSBhcmUKICogdXNlZCBzbyBzb21lIG9mIHRoZSBkb2N1bWVudGF0aW9uIGlzIGluY29tcGxldGUuCiAqCiAqIFJlZmVyZW5jZXM6CiAqIEludGVsIEFyY2hpdGVjdHVyZSBTb2Z0d2FyZSBEZXZlbG9wZXIncyBNYW51YWwKICogVm9sdW1lIDNCOiBTeXN0ZW0gUHJvZ3JhbW1pbmcgR3VpZGUsIFBhcnQgMiAoIzI1MzY2OSkKICogQXBwZW5kaXggQi45CiAqLwoKLyogVGhpcyBjb2RlIGlzIHBvcnRlZCBmcm9tIGNvcmVib290IHYxLgogKiBUaGUgTDIgY2FjaGUgaW5pdGFsaXphdGlvbiBzZXF1ZW5jZSBoZXJlIG9ubHkgYXBwbHkgdG8gU0VDQy9TRUNDMiBQNiBmYW1pbHkKICogQ1BVcyB3aXRoIEtsYW1hdGggKDYzeCksIERlc2NodXRlcyAoNjV4KSBhbmQgS2F0bWFpICg2N3gpIGNvcmVzLgogKiBJdCBpcyBub3QgcmVxdWlyZWQgZm9yIENvcHBlcm1pbmUgKDY4eCkgYW5kIFR1YWxhdGluICg2YngpIGNvcmVzLgogKiBJdCBpcyBjdXJyZW50bHkgbm90IGtub3duIGlmIENlbGVyb25zIHdpdGggTWVuZG9jaW5vICg2NngpIGNvcmUgcmVxdWlyZSB0aGUKICogc3BlY2lhbCBpbml0aWFsaXphdGlvbi4KICogQ292aW5ndG9uLWNvcmUgQ2VsZXJvbnMgZG8gbm90IGhhdmUgTDIgY2FjaGUuCiAqLwoKI2luY2x1ZGUgPHN0ZGludC5oPgojaW5jbHVkZSA8Y29uc29sZS9jb25zb2xlLmg+CiNpbmNsdWRlIDxzdHJpbmcuaD4KI2luY2x1ZGUgPGNwdS9jcHUuaD4KI2luY2x1ZGUgPGNwdS94ODYvbXRyci5oPgojaW5jbHVkZSA8Y3B1L2ludGVsL2wyX2NhY2hlLmg+CiNpbmNsdWRlIDxjcHUveDg2L2NhY2hlLmg+CiNpbmNsdWRlIDxjcHUveDg2L21zci5oPgoKLyogTGF0ZW5jeSBUYWJsZXMgKi8Kc3RydWN0IGxhdGVuY3lfZW50cnkgewoJdTgga2V5OwoJdTggdmFsdWU7Cn07Ci8qCkxhdGVuY3kgbWFwcyBmb3IgRGVzY2h1dGVzIGFuZCBLYXRtYWkuCk5vIHN1Y2ggbWFwcGluZyBpcyBhdmFpbGFibGUgZm9yIEtsYW1hdGguCgpDYWNoZSBsYXRlbmN5IHRvCmJlIHdyaXR0ZW4gdG8gTDIgLS0tLS0rKysrCmNvbnRyb2wgcmVnaXN0ZXIgICAgICB8fHx8CjAwMDAgeHggMDAgLS0tLS0+IDAwMCBjY2NjIDAKfHx8fCAgICAwMCA2Nk1Iegp8fHx8ICAgIDEwIDEwME1Iegp8fHx8ICAgIDAxIDEzM01IeiAoS2F0bWFpICJCIiBvbmx5KQorKysrLS0tLS0tIENQVSBmcmVxdWVuY3kgbXVsdGlwbGllcgoKMDAwMCAyeAowMDAxIDN4CjAwMTAgNHgKMDAxMSA1eAowMTAwIDIuNXgKMDEwMSAzLjV4CjAxMTAgNC41eAowMTExIDUuNXgKMTAwMCA2eAoxMDAxIDd4CjEwMTAgOHgKMTAxMSBSZXNlcnZlZAoxMTAwIDYuNXgKMTEwMSA3LjV4CjExMTAgMS41eAoxMTExIDJ4CgoqLwpzdGF0aWMgY29uc3Qgc3RydWN0IGxhdGVuY3lfZW50cnkgbGF0ZW5jeV82NTBfdDBbXSA9IHsKCXsweDEwLCAweDAyfSwgezB4NTAsIDB4MDJ9LCB7MHgyMCwgMHgwNH0sIHsweDYwLCAweDA2fSwKCXsweDAwLCAweDA4fSwgezB4NDAsIDB4MEN9LCB7MHgxMiwgMHgwNn0sIHsweDUyLCAweDBBfSwKCXsweDIyLCAweDBFfSwgezB4NjIsIDB4MTB9LCB7MHgwMiwgMHgxMH0sIHsweEZGLCAweDAwfQp9OwoKc3RhdGljIGNvbnN0IHN0cnVjdCBsYXRlbmN5X2VudHJ5IGxhdGVuY3lfNjUwX3QxW10gPSB7Cgl7MHgxMiwgMHgxNH0sIHsweDUyLCAweDE2fSwgezB4MjIsIDB4MTZ9LCB7MHg2MiwgMHgxNn0sCgl7MHhGRiwgMHgwMH0KfTsKCnN0YXRpYyBjb25zdCBzdHJ1Y3QgbGF0ZW5jeV9lbnRyeSBsYXRlbmN5XzY3MF90MFtdID0gewoJezB4NjAsIDB4MDZ9LCB7MHgwMCwgMHgwOH0sIHsweDEyLCAweDA2fSwgezB4NTIsIDB4MEF9LAoJezB4MjIsIDB4MEV9LCB7MHg2MiwgMHgxMH0sIHsweDAyLCAweDEwfSwgezB4NDIsIDB4MDJ9LAoJezB4MTEsIDB4MEV9LCB7MHg1MSwgMHgwQ30sIHsweDIxLCAweDAyfSwgezB4NjEsIDB4MTB9LAoJezB4MDEsIDB4MTB9LCB7MHg0MSwgMHgwMn0sIHsweEZGLCAweDAwfQp9OwoKc3RhdGljIGNvbnN0IHN0cnVjdCBsYXRlbmN5X2VudHJ5IGxhdGVuY3lfNjcwX3QxW10gPSB7Cgl7MHgyMiwgMHgxOH0sIHsweDYyLCAweDE4fSwgezB4MDIsIDB4MUF9LCB7MHgxMSwgMHgxOH0sCgl7MHhGRiwgMHgwMH0KfTsKCnN0YXRpYyBjb25zdCBzdHJ1Y3QgbGF0ZW5jeV9lbnRyeSBsYXRlbmN5XzY3MF90MltdID0gewoJezB4MjIsIDB4MTJ9LCB7MHg2MiwgMHgxNH0sIHsweDAyLCAweDE2fSwgezB4NDIsIDB4MUV9LAoJezB4MTEsIDB4MTJ9LCB7MHg1MSwgMHgxNn0sIHsweDIxLCAweDFFfSwgezB4NjEsIDB4MTR9LAoJezB4MDEsIDB4MTZ9LCB7MHg0MSwgMHgxRX0sIHsweEZGLCAweDAwfQp9OwoKLyogTGF0ZW5jeSB0YWJsZXMgZm9yIDY1MCBtb2RlbC90eXBlICovCnN0YXRpYyBjb25zdCBzdHJ1Y3QgbGF0ZW5jeV9lbnRyeSAqbGF0ZW5jeV82NTBbXSA9IHsKCWxhdGVuY3lfNjUwX3QwLCBsYXRlbmN5XzY1MF90MSwgbGF0ZW5jeV82NTBfdDEKfTsKCi8qIExhdGVuY3kgdGFibGVzIGZvciA2NzAgbW9kZWwvdHlwZSAqLwpzdGF0aWMgY29uc3Qgc3RydWN0IGxhdGVuY3lfZW50cnkgKmxhdGVuY3lfNjcwW10gPSB7CglsYXRlbmN5XzY3MF90MCwgbGF0ZW5jeV82NzBfdDEsIGxhdGVuY3lfNjcwX3QyCn07CgppbnQgY2FsY3VsYXRlX2wyX2xhdGVuY3kodm9pZCkKewoJdTMyIGVheCwgbCwgc2lnbmF0dXJlOwoJY29uc3Qgc3RydWN0IGxhdGVuY3lfZW50cnkgKmxhdGVuY3lfdGFibGUsICpsZTsKCW1zcl90IG1zcjsKCgkvKiBGaXJzdCwgYXR0ZW1wdCB0byBnZXQgY2FjaGUgbGF0ZW5jeSB2YWx1ZSBmcm9tCgkgICBJQTMyX1BMQVRGT1JNX0lEWzU2OjUzXS4gKEwyIENhY2hlIExhdGVuY3kgUmVhZCkKCSAqLwoJbXNyID0gcmRtc3IoSUEzMl9QTEFURk9STV9JRCk7CgoJcHJpbnRrKEJJT1NfREVCVUcsInJkbXNyKElBMzJfUExBVEZPUk1fSUQpID0gJXg6JXhcbiIsIG1zci5oaSwgbXNyLmxvKTsKCglsID0gKG1zci5oaSA+PiAyMCkgJiAweDFlOwoKCWlmIChsID09IDApIHsKCQkvKiBJZiBsYXRlbmN5IHZhbHVlIGlzbid0IGF2YWlsYWJsZSBmcm9tCgkJICAgSUEzMl9QTEFURk9STV9JRFs1Njo1M10sIHJlYWQgaXQgZnJvbQoJCSAgIEwyIGNvbnRyb2wgcmVnaXN0ZXIgMCBmb3IgbG9va3VwIGZyb20KCQkgICB0YWJsZXMuICovCgkJaW50IHQsIGE7CgoJCS8qIFRoZSByYXcgY29kZSBpcyByZWFkIGZyb20gTDIgcmVnaXN0ZXIgMCwgYml0cyBbNzo0XS4gKi8KCQlhID0gcmVhZF9sMigwKTsKCQlpZiAoYSA8IDApCgkJCXJldHVybiAtMTsKCgkJYSAmPSAweGYwOwoKCQlpZiAoKGEgJiAweDIwKSA9PSAwKQoJCQl0ID0gMDsKCQllbHNlIGlmIChhID09IDB4MjApCgkJCXQgPSAxOwoJCWVsc2UgaWYgKGEgPT0gMHgzMCkKCQkJdCA9IDI7CgkJZWxzZQoJCQlyZXR1cm4gLTE7CgoJCXByaW50ayhCSU9TX0RFQlVHLCJMMiBsYXRlbmN5IHR5cGUgPSAleFxuIiwgdCk7CgoJCS8qIEdldCBDUFVJRCBmYW1pbHkvbW9kZWwgKi8KCQlzaWduYXR1cmUgPSBjcHVpZF9lYXgoMSkgJiAweGZmZjA7CgoJCS8qIFJlYWQgRUJMX0NSX1BPV0VST04gKi8KCQltc3IgPSByZG1zcihFQkxfQ1JfUE9XRVJPTik7CgkJLyogR2V0IGNsb2NrIG11bHRpcGxpZXIgYW5kIEZTQiBmcmVxdWVuY3kuCgkJICogTXVsdGlwbGllciBpcyBpbiBbMjU6MjJdLgoJCSAqIEZTQiBpcyBpbiBbMTk6MThdIGluIEthdG1haSwgWzE5XSBpbiBEZXNjaHV0ZXMgKFsxOF0gaXMgemVybyBmb3IgdGhlbSkuCgkJICovCgkJZWF4ID0gbXNyLmxvID4+IDE4OwoJCWlmIChzaWduYXR1cmUgPT0gMHg2NTApIHsKCQkJZWF4ICY9IH4weGYyOwoJCQlsYXRlbmN5X3RhYmxlID0gbGF0ZW5jeV82NTBbdF07CgkJfSBlbHNlIGlmIChzaWduYXR1cmUgPT0gMHg2NzApIHsKCQkJZWF4ICY9IH4weGYzOwoJCQlsYXRlbmN5X3RhYmxlID0gbGF0ZW5jeV82NzBbdF07CgkJfSBlbHNlCgkJCXJldHVybiAtMTsKCgkJLyogU2VhcmNoIHRhYmxlIGZvciBtYXRjaGluZyBlbnRyeSAqLwoJCWZvciAobGUgPSBsYXRlbmN5X3RhYmxlOyBsZS0+a2V5ICE9IGVheDsgbGUrKykgewoJCQkvKiBGYWlsIGlmIHdlIGdldCB0byB0aGUgZW5kIG9mIHRoZSB0YWJsZSAqLwoJCQlpZiAobGUtPmtleSA9PSAweGZmKSB7CgkJCQlwcmludGsoQklPU19ERUJVRywgIkNvdWxkIG5vdCBmaW5kIGtleSAlMDJ4IGluIGxhdGVuY3kgdGFibGVcbiIsIGVheCk7CgkJCQlyZXR1cm4gLTE7CgkJCX0KCQl9CgoJCWwgPSBsZS0+dmFsdWU7Cgl9CgoJcHJpbnRrKEJJT1NfREVCVUcsIkwyIENhY2hlIGxhdGVuY3kgaXMgJWRcbiIsIGwgLyAyKTsKCgkvKiBXcml0ZXMgdGhlIGNhbGN1bGF0ZWQgbGF0ZW5jeSBpbiBCQkxfQ1JfQ1RMM1s0OjFdLiAqLwoJbXNyID0gcmRtc3IoQkJMX0NSX0NUTDMpOwoJbXNyLmxvICY9IDB4ZmZmZmZmZTE7Cgltc3IubG8gfD0gbDsKCXdybXNyKEJCTF9DUl9DVEwzLCBtc3IpOwoKCXJldHVybiAwOwp9CgoKLyogU2V0dXAgYWRkcmVzcywgZGF0YV9oaWdoOmRhdGFfbG93IGludG8gdGhlIEwyCiAqIGNvbnRyb2wgcmVnaXN0ZXJzIGFuZCB0aGVuIGlzc3VlIGNvbW1hbmQgd2l0aCBjb3JyZWN0IGNhY2hlIHdheQogKi8KaW50IHNpZ25hbF9sMih1MzIgYWRkcmVzcywgdTMyIGRhdGFfaGlnaCwgdTMyIGRhdGFfbG93LCBpbnQgd2F5LCB1OCBjb21tYW5kKQp7CglpbnQgaTsKCW1zcl90IG1zcjsKCgkvKiBXcml0ZSBMMiBBZGRyZXNzIHRvIEJCTF9DUl9BRERSICovCgltc3IubG8gPSBhZGRyZXNzOwoJbXNyLmhpID0gMDsKCXdybXNyKEJCTF9DUl9BRERSLCBtc3IpOwoKCS8qIFdyaXRlIGRhdGEgdG8gQkJMX0NSX0R7MC4uM30gKi8KCW1zci5sbyA9IGRhdGFfbG93OwoJbXNyLmhpID0gZGF0YV9oaWdoOwoJZm9yIChpID0gQkJMX0NSX0QwOyBpIDw9IEJCTF9DUl9EMzsgaSsrKSB7CgkJd3Jtc3IoaSwgbXNyKTsKCX0KCgkvKiBQdXQgdGhlIGNvbW1hbmQgYW5kIHdheSBpbnRvIEJCTF9DUl9DVEwgKi8KCW1zciA9IHJkbXNyKEJCTF9DUl9DVEwpOwoJbXNyLmxvID0gKG1zci5sbyAmIDB4ZmZmZmZjZTApIHwgY29tbWFuZCB8ICh3YXkgPDwgOCk7Cgl3cm1zcihCQkxfQ1JfQ1RMLCBtc3IpOwoKCS8qIFRyaWdnZXIgTDIgY29udHJvbGxlciAqLwoJbXNyLmxvID0gMDsKCW1zci5oaSA9IDA7Cgl3cm1zcihCQkxfQ1JfVFJJRywgbXNyKTsKCgkvKiBQb2xsIHRoZSBjb250cm9sbGVyIHRvIHNlZSB3aGVuIGRvbmUgKi8KCWZvciAoaSA9IDA7IGkgPCAweDEwMDsgaSsrKSB7CgkJLyogUmVhZCBCQkxfQ1JfQlVTWSAqLwoJCW1zciA9IHJkbXNyKEJCTF9DUl9CVVNZKTsKCQkvKiBJZiBub3QgYnVzeSB0aGVuIHJldHVybiAqLwoJCWlmICgobXNyLmxvICYgMSkgPT0gMCkKCQkJcmV0dXJuIDA7Cgl9CgoJLyogUmV0dXJuIHRpbWVvdXQgY29kZSAqLwoJcmV0dXJuIC0xOwp9CgovKiBSZWFkIHRoZSBMMiBDYWNoZSBjb250cm9sbGVyIHJlZ2lzdGVyIGF0IGdpdmVuIGFkZHJlc3MgKi8KaW50IHJlYWRfbDIodTMyIGFkZHJlc3MpCnsKCW1zcl90IG1zcjsKCgkvKiBTZW5kIGEgTDIgQ29udHJvbCBSZWdpc3RlciBSZWFkIHRvIEwyIGNvbnRyb2xsZXIgKi8KCWlmIChzaWduYWxfbDIoYWRkcmVzcyA8PCA1LCAwLCAwLCAwLCBMMkNNRF9DUikgIT0gMCkKCQlyZXR1cm4gLTE7CgoJLyogSWYgT0sgdGhlbiBnZXQgdGhlIHJlc3VsdCBmcm9tIEJCTF9DUl9BRERSICovCgltc3IgPSByZG1zcihCQkxfQ1JfQUREUik7CglyZXR1cm4gKG1zci5sbyA+PiAweDE1KTsKCn0KCi8qIFdyaXRlIGRhdGEgaW50byB0aGUgTDIgY29udHJvbGxlciByZWdpc3RlciBhdCBhZGRyZXNzICovCmludCB3cml0ZV9sMih1MzIgYWRkcmVzcywgdTMyIGRhdGEpCnsKCWludCB2MSwgdjIsIGk7CgoJdjEgPSByZWFkX2wyKDApOwoJaWYgKHYxIDwgMCkKCQlyZXR1cm4gLTE7CgoJdjIgPSByZWFkX2wyKDIpOwoJaWYgKHYyIDwgMCkKCQlyZXR1cm4gLTE7CgoJaWYgKCh2MSAmIDB4MjApID09IDApIHsKCQl2MiAmPSAweDM7CgkJdjIrKzsKCX0gZWxzZQoJCXYyICY9IDB4NzsKCgkvKiBUaGlzIHdyaXRlIGhhcyB0byBiZSByZXBsaWNhdGVkIHRvIGEgbnVtYmVyIG9mIHBsYWNlcy4gTm90IHN1cmUgd2hhdC4gKi8KCglmb3IgKGkgPSAwOyBpIDwgdjI7IGkrKykgewoKCQl1MzIgZGF0YTEsIGRhdGEyOwoJCS8vIEJpdHMgbGVnZW5kCgkJLy8gZGF0YTEgICA9IGZmZmZmZmZmCgkJLy8gZGF0YTIgICA9IDAwMDAwMGRjCgkJLy8gYWRkcmVzcyA9IDAwYWFhYWFhCgkJLy8gRmluYWwgYWRkcmVzcyBzaWduYWxsZWQ6CgkJLy8gMDAwZmZmZmYgZmZmMDAwYzAgMDAwZGNhYWEgYWFhMDAwMDAKCQlkYXRhMSA9IGRhdGEgJiAweGZmOwoJCWRhdGExID0gZGF0YTEgPDwgMjE7CgkJZGF0YTIgPSAoaSA8PCAxMSkgJiAweDE4MDA7CgkJZGF0YTEgfD0gZGF0YTI7CgkJZGF0YTIgPDw9IDY7CgkJZGF0YTIgJj0gMHgyMDAwMDsKCQlkYXRhMSB8PSBkYXRhMjsKCgkJLyogU2lnbmFsIEwyIGNvbnRyb2xsZXIgKi8KCQlpZiAoc2lnbmFsX2wyKChhZGRyZXNzIDw8IDUpIHwgZGF0YTEsIDAsIDAsIDAsIDMpKQoJCQlyZXR1cm4gLTE7Cgl9CglyZXR1cm4gMDsKfQoKLyogV3JpdGUgZGF0YV9oaWdoOmRhdGFfbG93IGludG8gdGhlIGNhY2hlIGF0IGFkZHJlc3MxLiBUZXN0IGFkZHJlc3MyCiAqIHRvIHNlZSBpZiB0aGUgc2FtZSBkYXRhIGlzIHJldHVybmVkLiBSZXR1cm4gMCBpZiB0aGUgZGF0YSBtYXRjaGVzLgogKiByZXR1cm4gbG93ZXIgMTYgYml0cyBpZiBtaXNtYXRjaGVkIGRhdGEgaWYgbWlzbWF0Y2guIFJldHVybiAtMQogKiBvbiBlcnJvcgogKi8KaW50IHRlc3RfbDJfYWRkcmVzc19hbGlhcyh1MzIgYWRkcmVzczEsIHUzMiBhZGRyZXNzMiwKCQkJCSB1MzIgZGF0YV9oaWdoLCB1MzIgZGF0YV9sb3cpCnsKCWludCBkOwoJbXNyX3QgbXNyOwoKCS8qIFRhZyBXcml0ZSB3aXRoIERhdGEgV3JpdGUgZm9yIEwyICovCglpZiAoc2lnbmFsX2wyKGFkZHJlc3MxLCBkYXRhX2hpZ2gsIGRhdGFfbG93LCAwLCBMMkNNRF9UV1cpKQoJCXJldHVybiAtMTsKCgkvKiBUYWcgUmVhZCB3aXRoIERhdGEgUmVhZCBmb3IgTDIgKi8KCWlmIChzaWduYWxfbDIoYWRkcmVzczIsIDAsIDAsIDAsIEwyQ01EX1RSUikpCgkJcmV0dXJuIC0xOwoKCS8qIFJlYWQgZGF0YSBmcm9tIEJCTF9DUl9EWzAtM10gKi8KCWZvciAoZCA9IEJCTF9DUl9EMDsgZCA8PSBCQkxfQ1JfRDM7IGQrKykgewoJCW1zciA9IHJkbXNyKGQpOwoJCWlmIChtc3IubG8gIT0gZGF0YV9sb3cgfHwgbXNyLmhpICE9IGRhdGFfaGlnaCkKCQkJcmV0dXJuIChtc3IubG8gJiAweGZmZmYpOwoJfQoKCXJldHVybiAwOwp9CgovKiBDYWxjdWxhdGVzIHRoZSBMMiBjYWNoZSBzaXplLgogKgogKiBSZWZlcmVuY2U6IEludGVsKFIpIDY0IGFuZCBJQS0zMiBBcmNoaXRlY3R1cmVzIFNvZnR3YXJlIERldmVsb3BlcpJzIE1hbnVhbAogKiAgICAgICAgICAgIFZvbHVtZSAzQjogU3lzdGVtIFByb2dyYW1taW5nIEd1aWRlLCBQYXJ0IDIsIEludGVsIHB1Yi4gMjUzNjY5LCBwZy4gQi0xNzIuCiAqCiAqLwppbnQgY2FsY3VsYXRlX2wyX2NhY2hlX3NpemUodm9pZCkKewoJaW50IHY7Cgltc3JfdCBtc3I7Cgl1MzIgY2FjaGVfc2V0dGluZzsKCXUzMiBhZGRyZXNzLCBzaXplLCBlYXgsIGJibGNyMzsKCgl2ID0gcmVhZF9sMigwKTsKCWlmICh2IDwgMCkKCQlyZXR1cm4gLTE7CglpZiAoKHYgJiAweDIwKSA9PSAwKSB7CgkJbXNyID0gcmRtc3IoQkJMX0NSX0NUTDMpOwoJCWJibGNyMyA9IG1zci5sbyAmIH5CQkxDUjNfTDJfU0laRTsKCQkvKgoJCSAqIFN1Y2Nlc3NpdmVseSB3cml0ZSBpbiBhbGwgdGhlIHBvc3NpYmxlIGNhY2hlIHNpemUgcGVyIGJhbmsKCQkgKiBpbnRvIEJCTF9DUl9DVEwzWzE3OjEzXSwgc3RhcnRpbmcgZnJvbSAyNTZLQiAoMDAwMDEpIHRvIDRNQiAoMTAwMDApLAoJCSAqIGFuZCByZWFkIHRoZSBsYXN0IHZhbHVlIHdyaXR0ZW4gYW5kIGFjY2VwdGVkIGJ5IHRoZSBjYWNoZS4KCQkgKgoJCSAqIE5vIGlkZWEgd2h5IHRoZXNlIGJpdHMgYXJlIHdyaXRhYmxlIGF0IGFsbC4KCQkgKi8KCQlmb3IgKGNhY2hlX3NldHRpbmcgPSBCQkxDUjNfTDJfU0laRV8yNTZLOwoJCSAgICAgY2FjaGVfc2V0dGluZyA8PSBCQkxDUjNfTDJfU0laRV80TTsgY2FjaGVfc2V0dGluZyA8PD0gMSkgewoKCQkJZWF4ID0gYmJsY3IzIHwgY2FjaGVfc2V0dGluZzsKCQkJbXNyLmxvID0gZWF4OwoJCQl3cm1zcihCQkxfQ1JfQ1RMMywgbXNyKTsKCQkJbXNyID0gcmRtc3IoQkJMX0NSX0NUTDMpOwoKCQkJLyogVmFsdWUgbm90IGFjY2VwdGVkICovCgkJCWlmIChtc3IubG8gIT0gZWF4KQoJCQkJYnJlYWs7CgkJfQoKCQkvKiBCYWNrdHJhY2sgdG8gdGhlIGxhc3QgdmFsdWUgdGhhdCB3b3JrZWQuLi4gKi8KCQljYWNoZV9zZXR0aW5nID4+PSAxOwoKCQkvKiBhbmQgd3JpdGUgaXQgaW50byBCQkxfQ1JfQ1RMMyAqLwoJCW1zci5sbyAmPSB+QkJMQ1IzX0wyX1NJWkU7CgkJbXNyLmxvIHw9IChjYWNoZV9zZXR0aW5nICYgQkJMQ1IzX0wyX1NJWkUpOwoKCQl3cm1zcihCQkxfQ1JfQ1RMMywgbXNyKTsKCgkJcHJpbnRrKEJJT1NfREVCVUcsIk1heGltdW0gY2FjaGUgbWFzayBpcyAleFxuIiwgY2FjaGVfc2V0dGluZyk7CgoJCS8qIEZvciBub3csIEJCTF9DUl9DVEwzIGhhcyB0aGUgaGlnaGVzdCBjYWNoZSAic2l6ZSIgdGhhdCByZWdpc3RlcgoJCSAqIHdpbGwgYWNjZXB0LiBOb3cgd2UnbGwgcGluZyB0aGUgY2FjaGUgYW5kIHNlZSB3aGVyZSBpdCB3cmFwcy4KCQkgKi8KCgkJLyogV3JpdGUgYWFhYWFhYWE6YWFhYWFhYWEgdG8gYWRkcmVzcyAwIGluIHRoZSBsMiBjYWNoZS4KCQkgKiBJZiB0aGlzICJhbGlhcyB0ZXN0IiByZXR1cm5zIGFuICJhZGRyZXNzIiwgaXQgbWVhbnMgdGhlCgkJICogY2FjaGUgY2Fubm90IGJlIHdyaXR0ZW4gdG8gcHJvcGVybHksIGFuZCB3ZSBoYXZlIGEgcHJvYmxlbS4KCQkgKi8KCQl2ID0gdGVzdF9sMl9hZGRyZXNzX2FsaWFzKDAsIDAsIDB4YWFhYWFhYWEsIDB4YWFhYWFhYWEpOwoJCWlmICh2ICE9IDApCgkJCXJldHVybiAtMTsKCgkJLyogU3RhcnQgd2l0aCAzMksgd3JhcCBwb2ludCAoMjU2S0IgYWN0dWFsbHkpICovCgkJc2l6ZSA9IDE7CgkJYWRkcmVzcyA9IDB4ODAwMDsKCgkJd2hpbGUgKDEpIHsKCQkJdiA9IHRlc3RfbDJfYWRkcmVzc19hbGlhcyhhZGRyZXNzLCAwLCAweDU1NTU1NTU1LAoJCQkJCQkgIDB4NTU1NTU1NTUpOwoJCQkvLyBXcml0ZSBmYWlsZWQuCgkJCWlmICh2IDwgMCkKCQkJCXJldHVybiAtMTsKCQkJLy8gSXQgd3JhcHMgaGVyZS4KCQkJZWxzZSBpZiAodiA9PSAwKQoJCQkJYnJlYWs7CgoJCQlzaXplIDw8PSAxOwoJCQlhZGRyZXNzIDw8PSAxOwoKCQkJaWYgKGFkZHJlc3MgPiAweDIwMDAwMCkKCQkJCXJldHVybiAtMTsKCQl9CgoJCS8qIE1hc2sgc2l6ZSAqLwoJCXNpemUgJj0gMHgzZTsKCgkJLyogU2hpZnQgdG8gWzE3OjEzXSAqLwoJCXNpemUgPDw9IDEyOwoKCQkvKiBTZXQgdGhpcyBpbnRvIEJCTF9DUl9DVEwzICovCgkJbXNyID0gcmRtc3IoQkJMX0NSX0NUTDMpOwoJCW1zci5sbyAmPSB+QkJMQ1IzX0wyX1NJWkU7CgkJbXNyLmxvIHw9IHNpemU7CgkJd3Jtc3IoQkJMX0NSX0NUTDMsIG1zcik7CgoJCXByaW50ayhCSU9TX0RFQlVHLCJMMiBDYWNoZSBNYXNrIGlzICV4XG4iLCBzaXplKTsKCgkJLyogU2hpZnQgdG8gWzY6Ml0gKi8KCQlzaXplID4+PSAxMTsKCgkJdiA9IHJlYWRfbDIoMik7CgoJCWlmICh2IDwgMCkKCQkJcmV0dXJuIC0xOwoKCQlwcmludGsoQklPU19ERUJVRywiTDIoMik6ICV4ICIsIHYpOwoKCQl2ICY9IDB4MzsKCgkJLyogU2hpZnQgc2l6ZSByaWdodCBieSB2ICovCgkJc2l6ZSA+Pj0gdjsKCgkJLyogT3IgaW4gdGhpcyBzaXplICovCgkJdiB8PSBzaXplOwoKCQlwcmludGsoQklPU19ERUJVRywiLT4gJXhcbiIsIHYpOwoKCQlpZiAod3JpdGVfbDIoMiwgdikgIT0gMCkKCQkJcmV0dXJuIC0xOwoJfSBlbHNlIHsKCQkvLyBTb21lIGNhY2hlIHNpemUgaW5mb3JtYXRpb24gaXMgYXZhaWxhYmxlIGZyb20gTDIgcmVnaXN0ZXJzLgoJCS8vIFdvcmsgZnJvbSB0aGVyZS4KCQlpbnQgYiwgYzsKCgkJdiA9IHJlYWRfbDIoMik7CgoJCXByaW50ayhCSU9TX0RFQlVHLCJMMigyKSA9ICV4XG4iLCB2KTsKCgkJaWYgKHYgPCAwKQoJCQlyZXR1cm4gLTE7CgoJCS8vIEwyIHJlZ2lzdGVyIDIgYml0bWFwOiBjYy0tLWJiYgoJCWIgPSB2ICYgMHg3OwoJCWMgPSB2ID4+IDY7CgoJCXYgPSAxIDw8IGMgKiBiOwoKCQl2ICY9IDB4ZjsKCgkJcHJpbnRrKEJJT1NfREVCVUcsIkNhbGN1bGF0ZWQgYSA9ICV4XG4iLCB2KTsKCgkJaWYgKHYgPT0gMCkKCQkJcmV0dXJuIC0xOwoKCQkvKiBTaGlmdCB0byAxNzoxNCAqLwoJCXYgPDw9IDE0OwoKCQkvKiBXcml0ZSB0aGlzIHNpemUgaW50byBCQkxfQ1JfQ1RMMyAqLwoJCW1zciA9IHJkbXNyKEJCTF9DUl9DVEwzKTsKCQltc3IubG8gJj0gfkJCTENSM19MMl9TSVpFOwoJCW1zci5sbyB8PSB2OwoJCXdybXNyKEJCTF9DUl9DVEwzLCBtc3IpOwoJfQoKCXJldHVybiAwOwp9CgovLyBMMiBwaHlzaWNhbCBhZGRyZXNzIHJhbmdlIGNhbiBiZSBmb3VuZCBmcm9tIEwyIGNvbnRyb2wgcmVnaXN0ZXIgMywgYml0cyBbMjowXS4KaW50IGNhbGN1bGF0ZV9sMl9waHlzaWNhbF9hZGRyZXNzX3JhbmdlKHZvaWQpCnsKCWludCByMCwgcjM7Cgltc3JfdCBtc3I7CgoJcjMgPSByZWFkX2wyKDMpOwoJaWYgKHIzIDwgMCkKCQlyZXR1cm4gLTE7CgoJcjAgPSByZWFkX2wyKDApOwoJaWYgKHIwIDwgMCkKCQlyZXR1cm4gLTE7CgoJaWYgKHIwICYgMHgyMCkKCQlyMyA9IDB4NzsKCWVsc2UKCQlyMyAmPSAweDc7CgoJcHJpbnRrKEJJT1NfREVCVUcsIkwyIFBoeXNpY2FsIEFkZHJlc3MgUmFuZ2UgaXMgJWRNXG4iLCAoMSA8PCByMykgKiA1MTIpOwoKCS8qIFNoaWZ0IGludG8gWzIyOjIwXSB0byBiZSBzYXZlZCBpbnRvIEJCTF9DUl9DVEwzLiAqLwoJcjMgPSByMyA8PCAyMDsKCgltc3IgPSByZG1zcihCQkxfQ1JfQ1RMMyk7Cgltc3IubG8gJj0gfkJCTENSM19MMl9QSFlTSUNBTF9SQU5HRTsKCW1zci5sbyB8PSByMzsKCXdybXNyKEJCTF9DUl9DVEwzLCBtc3IpOwoKCXJldHVybiAwOwp9CgppbnQgc2V0X2wyX2VjYyh2b2lkKQp7Cgl1MzIgZWF4OwoJY29uc3QgdTMyIGRhdGExID0gMHhhYTU1YWE1NTsKCWNvbnN0IHUzMiBkYXRhMiA9IDB4YWFhYWFhYWE7Cgltc3JfdCBtc3I7CgoJLyogU2V0IFVzZXIgU3VwcGxpZWQgRUNDIGluIEJCTF9DUl9DVEwgKi8KCW1zciA9IHJkbXNyKEJCTF9DUl9DVEwpOwoJbXNyLmxvIHw9IEJCTENSM19MMl9TVVBQTElFRF9FQ0M7Cgl3cm1zcihCQkxfQ1JfQ1RMLCBtc3IpOwoKCS8qIFdyaXRlIGEgdmFsdWUgaW50byB0aGUgTDIgRGF0YSBFQ0MgcmVnaXN0ZXIgQkJMX0NSX0RFQ0MgKi8KCW1zci5sbyA9IGRhdGExOwoJbXNyLmhpID0gMDsKCXdybXNyKEJCTF9DUl9ERUNDLCBtc3IpOwoKCWlmICh0ZXN0X2wyX2FkZHJlc3NfYWxpYXMoMCwgMCwgZGF0YTIsIGRhdGEyKSA8IDApCgkJcmV0dXJuIC0xOwoKCS8qIFJlYWQgYmFjayBFQ0MgZnJvbSBCQkxfQ1JfREVDQyAqLwoJbXNyID0gcmRtc3IoQkJMX0NSX0RFQ0MpOwoJZWF4ID0gbXNyLmxvOwoKCWlmIChlYXggPT0gZGF0YTEpIHsKCQlwcmludGsoQklPU19ERUJVRywiTDIgRUNDIENoZWNraW5nIGlzIGVuYWJsZWRcbiIpOwoKCQkvKiBTZXQgRUNDIENoZWNrIEVuYWJsZSBpbiBCQkxfQ1JfQ1RMMyAqLwoJCW1zciA9IHJkbXNyKEJCTF9DUl9DVEwzKTsKCQltc3IubG8gfD0gQkJMQ1IzX0wyX0VDQ19DSEVDS19FTkFCTEU7CgkJd3Jtc3IoQkJMX0NSX0NUTDMsIG1zcik7Cgl9CgoJLyogQ2xlYXIgVXNlciBTdXBwbGllZCBFQ0MgaW4gQkJMX0NSX0NUTCAqLwoJbXNyID0gcmRtc3IoQkJMX0NSX0NUTCk7Cgltc3IubG8gJj0gfkJCTENSM19MMl9TVVBQTElFRF9FQ0M7Cgl3cm1zcihCQkxfQ1JfQ1RMLCBtc3IpOwoKCXJldHVybiAwOwp9CgovKgogKiBUaGlzIGlzIHRoZSBmdW5jdGlvbiBjYWxsZWQgZnJvbSBDUFUgaW5pdGlhbGl6YXRpb24KICogZHJpdmVyIHRvIHNldCB1cCBQNiBmYW1pbHkgTDIgY2FjaGUuCiAqLwoKaW50IHA2X2NvbmZpZ3VyZV9sMl9jYWNoZSh2b2lkKQp7Cgltc3JfdCBtc3IsIGJibGN0bDM7Cgl1bnNpZ25lZCBpbnQgZWF4OwoJdTE2IHNpZ25hdHVyZTsKCWludCBjYWNoZV9zaXplLCBiYW5rOwoJaW50IHJlc3VsdCwgY2FsY19lYXg7CglpbnQgdiwgYTsKCglpbnQgYmFkY2xrMSwgYmFkY2xrMiwgY2xrcmF0aW87CglpbnQgY3JjdGwzX29yOwoKCXByaW50ayhCSU9TX0lORk8sICJDb25maWd1cmluZyBMMiBjYWNoZS4uLiAiKTsKCgkvKiBSZWFkIEJCTF9DUl9DVEwzICovCgliYmxjdGwzID0gcmRtc3IoQkJMX0NSX0NUTDMpOwoJLyogSWYgYml0IDIzIChMMiBIYXJkd2FyZSBkaXNhYmxlKSBpcyBzZXQgdGhlbiBkb25lICovCgkvKiBUaGVzZSB3b3VsZCBiZSBDb3Zpbmd0b24gY29yZSBDZWxlcm9ucyB3aXRoIG5vIEwyIGNhY2hlICovCglpZiAoYmJsY3RsMy5sbyAmIEJCTENSM19MMl9OT1RfUFJFU0VOVCkgewoJCXByaW50ayhCSU9TX0lORk8sImhhcmR3YXJlIGRpc2FibGVkXG4iKTsKCQlyZXR1cm4gMDsKCX0KCglzaWduYXR1cmUgPSBjcHVpZF9lYXgoMSkgJiAweGZmZjA7CgoJLyogS2xhbWF0aC1zcGVjaWZpYyBiaXQgc2V0dGluZ3MgZm9yIGNlcnRhaW4KCSAgIHByZWxpbWluYXJ5IGNoZWNrcy4KCSAqLwoJaWYgKHNpZ25hdHVyZSA9PSAweDYzMCkgewoJCWNsa3JhdGlvID0gMHgxYzAwMDAwOwoJCWJhZGNsazIgPSAweDEwMDAwMDA7CgkJY3JjdGwzX29yID0gMHg0NDAwMDsKCX0gZWxzZSB7CgkJY2xrcmF0aW8gPSAweDNjMDAwMDA7CgkJYmFkY2xrMiA9IDB4MzAwMDAwMDsKCQljcmN0bDNfb3IgPSAweDQwMDAwOwoJfQoJYmFkY2xrMSA9IDB4YzAwMDAwOwoKCS8qIFJlYWQgRUJMX0NSX1BPV0VST04gKi8KCW1zciA9IHJkbXNyKEVCTF9DUl9QT1dFUk9OKTsKCWVheCA9IG1zci5sbzsKCS8qIE1hc2sgb3V0IFsyMi0yNV0gQ2xvY2sgZnJlcXVlbmN5IHJhdGlvICovCgllYXggJj0gY2xrcmF0aW87CglpZiAoZWF4ID09IGJhZGNsazEgfHwgZWF4ID09IGJhZGNsazIpIHsKCQlwcmludGsoQklPU19FUlIsICJJbmNvcnJlY3QgY2xvY2sgZnJlcXVlbmN5IHJhdGlvICV4XG4iLCBlYXgpOwoJCXJldHVybiAtMTsKCX0KCglkaXNhYmxlX2NhY2hlKCk7CgoJLyogTWFzayBvdXQgZnJvbSBCQkxfQ1JfQ1RMMzoKCSAqIFswXSBMMiBDb25maWd1cmVkCgkgKiBbNV0gRUNDIENoZWNrIEVuYWJsZQoJICogWzZdIEFkZHJlc3MgUGFyaXR5IENoZWNrIEVuYWJsZQoJICogWzddIENSVE4gUGFyaXR5IENoZWNrIEVuYWJsZQoJICogWzhdIEwyIEVuYWJsZWQKCSAqIFsxMjoxMV0gTnVtYmVyIG9mIEwyIGJhbmtzCgkgKiBbMTc6MTNdIENhY2hlIHNpemUgcGVyIGJhbmsKCSAqIFsxOF0gKFNldCBiZWxvdykKCSAqIFsyMjoyMF0gTDIgUGh5c2ljYWwgQWRkcmVzcyBSYW5nZSBTdXBwb3J0CgkgKi8KCWJibGN0bDMubG8gJj0gMHhmZjg4MDYxZTsKCS8qIFNldDoKCSAqIFsxNzoxM10gPSAwMDAxMCA9IDUxMktieXRlIENhY2hlIHNpemUgcGVyIGJhbmsgKDYzeCkKCSAqIFsxNzoxM10gPSAwMDAwMCA9IDEyOEtieXRlIENhY2hlIHNpemUgcGVyIGJhbmsgKGFsbCBvdGhlcnMpCgkgKiBbMThdIENhY2hlIHN0YXRlIGVycm9yIGNoZWNraW5nIGVuYWJsZQoJICovCgliYmxjdGwzLmxvIHw9IGNyY3RsM19vcjsKCgkvKiBXcml0ZSBCQkxfQ1JfQ1RMMyAqLwoJd3Jtc3IoQkJMX0NSX0NUTDMsIGJibGN0bDMpOwoKCWlmIChzaWduYXR1cmUgIT0gMHg2MzApIHsKCQllYXggPSBiYmxjdGwzLmxvOwoKCQkvKiBTZXQgdGhlIGwyIGxhdGVuY3kgaW4gQkJMX0NSX0NUTDMgKi8KCQlpZiAoY2FsY3VsYXRlX2wyX2xhdGVuY3koKSAhPSAwKQoJCQlnb3RvIGJhZDsKCgkJLyogUmVhZCB0aGUgbmV3IGxhdGVuY3kgdmFsdWVzIGJhY2sgKi8KCQliYmxjdGwzID0gcmRtc3IoQkJMX0NSX0NUTDMpOwoJCWNhbGNfZWF4ID0gYmJsY3RsMy5sbzsKCgkJLyogV3JpdGUgYmFjayB0aGUgb3JpZ2luYWwgZGVmYXVsdCB2YWx1ZSAqLwoJCWJibGN0bDMubG8gPSBlYXg7CgkJd3Jtc3IoQkJMX0NSX0NUTDMsIGJibGN0bDMpOwoKCQkvKiBXcml0ZSBCQkxfQ1JfQ1RMM1syNzoyNl0gKHJlc2VydmVkPz8pIHRvIGJpdHMgWzE6MF0gb2YgTDIgcmVnaXN0ZXIgNC4KCQkgKiBBcHBhcmVudGx5IGFsbCBvdGhlciBiaXRzIG11c3QgYmUgcHJlc2VydmVkLCBoZW5jZSB0aGVzZSBjb2RlLgoJCSAqLwoKCQl2ID0gKGNhbGNfZWF4ID4+IDI2KSAmIDB4MzsKCgkJcHJpbnRrKEJJT1NfREVCVUcsIndyaXRlX2wyKDQsICV4KVxuIiwgdik7CgoJCWEgPSByZWFkX2wyKDQpOwoJCWlmIChhID49IDApCgkJewoJCQlhICY9IDB4ZmZmYzsKCQkJYSB8PSB2OwoJCQlhID0gd3JpdGVfbDIoNCwgYSk7CgkJCS8qIGEgbm93IGNvbnRhaW5zIHJlc3VsdCBjb2RlIGZyb20gd3JpdGVfbDIoKSAqLwoJCX0KCQlpZiAoYSAhPSAwKQoJCQlnb3RvIGJhZDsKCgkJLyogUmVzdG9yZSB0aGUgY29ycmVjdCBsYXRlbmN5IHZhbHVlIGludG8gQkJMX0NSX0NUTDMgKi8KCQliYmxjdGwzLmxvID0gY2FsY19lYXg7CgkJd3Jtc3IoQkJMX0NSX0NUTDMsIGJibGN0bDMpOwoJfSAvKiAhIDYzeCBDUFUgKi8KCgkvKiBSZWFkIEwyIHJlZ2lzdGVyIDAgKi8KCXYgPSByZWFkX2wyKDApOwoKCS8qIElmIEwyKDApWzVdIHNldCAoYW5kIGNhbiBiZSByZWFkIHByb3Blcmx5KSwgZW5hYmxlIENSVE4gYW5kIGFkZHJlc3MgcGFyaXR5CgkgKi8KCWlmICh2ID49IDAgJiYgKHYgJiAweDIwKSkgewoJCWJibGN0bDMgPSByZG1zcihCQkxfQ1JfQ1RMMyk7CgkJYmJsY3RsMy5sbyB8PSAoQkJMQ1IzX0wyX0FERFJfUEFSSVRZX0VOQUJMRSB8CgkJICAgICAgICAgICAgICAgQkJMQ1IzX0wyX0NSVE5fUEFSSVRZX0VOQUJMRSk7CgkJd3Jtc3IoQkJMX0NSX0NUTDMsIGJibGN0bDMpOwoJfQoKCS8qIElmIHNvbWV0aGluZyBnb2VzIHdyb25nIGF0IEwyIEVDQyBzZXR1cCwgY2FjaGUgRUNDCgkgKiB3aWxsIGp1c3QgcmVtYWluIGRpc2FibGVkLgoJICovCglzZXRfbDJfZWNjKCk7CgoJaWYgKGNhbGN1bGF0ZV9sMl9waHlzaWNhbF9hZGRyZXNzX3JhbmdlKCkgIT0gMCkgewoJCXByaW50ayhCSU9TX0VSUiwgIkZhaWxlZCB0byBjYWxjdWxhdGUgTDIgcGh5c2ljYWwgYWRkcmVzcyByYW5nZSIpOwoJCWdvdG8gYmFkOwoJfQoKCWlmIChjYWxjdWxhdGVfbDJfY2FjaGVfc2l6ZSgpICE9IDApIHsKCQlwcmludGsoQklPU19FUlIsICJGYWlsZWQgdG8gY2FsY3VsYXRlIEwyIGNhY2hlIHNpemUiKTsKCQlnb3RvIGJhZDsKCX0KCgkvKiBUdXJuIG9uIGNhY2hlLiBPbmx5IEwxIGlzIGFjdGl2ZSBhdCB0aGlzIHRpbWUuICovCgllbmFibGVfY2FjaGUoKTsKCgkvKiBHZXQgdGhlIGNhbGN1bGF0ZWQgY2FjaGUgc2l6ZSBmcm9tIEJCTF9DUl9DVEwzWzE3OjEzXSAqLwoJYmJsY3RsMyA9IHJkbXNyKEJCTF9DUl9DVEwzKTsKCWNhY2hlX3NpemUgPSAoYmJsY3RsMy5sbyAmIEJCTENSM19MMl9TSVpFKTsKCWlmIChjYWNoZV9zaXplID09IDApCgkJY2FjaGVfc2l6ZSA9IDB4MTAwMDsKCWNhY2hlX3NpemUgPSBjYWNoZV9zaXplIDw8IDM7CgoJLyogVE9ETzogQ2FjaGUgc2l6ZSBhYm92ZSBpcyBwZXIgYmFuay4gV2UncmUgc3VwcG9zZWQgdG8gZ2V0CgkgKiB0aGUgbnVtYmVyIG9mIGJhbmtzIGZyb20gQkJMX0NSX0NUTDNbMTI6MTFdLgoJICogQ29uZmlybSB0aGF0IHRoaXMgc3RpbGwgcHJvdmlkZXMgdGhlIGNvcnJlY3QgYW5zd2VyLgoJICovCgliYW5rID0gKGJibGN0bDMubG8gPj4gMTEpICYgMHgzOwoJaWYgKGJhbmsgPT0gMCkKCQliYW5rID0gMTsKCglwcmludGsoQklPU19JTkZPLCAic2l6ZSAlZEsuLi4gIiwgY2FjaGVfc2l6ZSAqIGJhbmsgKiA0IC8gMTAyNCk7CgoJLyogV3JpdGUgdG8gYWxsIGNhY2hlIGxpbmVzIHRvIGluaXRpYWxpemUgKi8KCgl3aGlsZSAoY2FjaGVfc2l6ZSA+IDApIHsKCgkJLyogRWFjaCBjYWNoZSBsaW5lIGlzIDMyIGJ5dGVzLiAqLwoJCWNhY2hlX3NpemUgLT0gMzI7CgoJCS8qIFVwZGF0ZSBlYWNoIHdheSAqLwoKCQkvKiBXZSdyZSBzdXBwb3NlZCB0byBnZXQgTDIgYXNzb2NpYXRpdml0eSBmcm9tIEJCTF9DUl9DVEwzWzEwOjldLgoJCSAqIEJ1dCB0aGlzIGNvZGUgb25seSBhcHBsaWVzIHRvIGNlcnRhaW4gbWVtYmVycyBvZiB0aGUgUDYgcHJvY2Vzc29yIGZhbWlseQoJCSAqIGFuZCBzaW5jZSBhbGwgUDYgcHJvY2Vzc29ycyBoYXZlIDQtd2F5IEwyIGNhY2hlLCB3ZSBjYW4gc2FmZWx5IGFzc3VtZQoJCSAqIDQgd2F5IGZvciBhbGwgY2FjaGUgb3BlcmF0aW9ucy4KCQkgKi8KCgkJZm9yICh2ID0gMDsgdiA8IDQ7IHYrKykgewoJCQkvKiBTZW5kIFRhZyBXcml0ZSB3L0RhdGEgV3JpdGUgKFRXVykgdG8gTDIgY29udHJvbGxlcgoJCQkgKiBNRVNJID0gSW52YWxpZAoJCQkgKi8KCQkJaWYgKHNpZ25hbF9sMihjYWNoZV9zaXplLCAwLCAwLCB2LCBMMkNNRF9UV1cgfCBMMkNNRF9NRVNJX0kpICE9IDApIHsKCQkJCXByaW50ayhCSU9TX0VSUiwgIkZhaWxlZCBvbiBzaWduYWxfbDIoJXgsICV4KVxuIiwKCQkJCSAgICAgICBjYWNoZV9zaXplLCB2KTsKCQkJCWdvdG8gYmFkOwoJCQl9CgkJfQoJfQoJcHJpbnRrKEJJT1NfREVCVUcsICJMMiBDYWNoZSBsaW5lcyBpbml0aWFsaXplZFxuIik7CgoJLyogRGlzYWJsZSBjYWNoZSAqLwoJZGlzYWJsZV9jYWNoZSgpOwoKCS8qIFNldCBMMiBjYWNoZSBjb25maWd1cmVkIGluIEJCTF9DUl9DVEwzICovCgliYmxjdGwzID0gcmRtc3IoQkJMX0NSX0NUTDMpOwoJYmJsY3RsMy5sbyB8PSBCQkxDUjNfTDJfQ09ORklHVVJFRDsKCXdybXNyKEJCTF9DUl9DVEwzLCBiYmxjdGwzKTsKCgkvKiBJbnZhbGlkYXRlIGNhY2hlIGFuZCBkaXNjYXJkIHVuc2F2ZWQgd3JpdGVzICovCglhc20gdm9sYXRpbGUgKCJpbnZkIik7CgoJLyogV3JpdGUgMCB0byBMMiBjb250cm9sIHJlZ2lzdGVyIDUgKi8KCWlmICh3cml0ZV9sMig1LCAwKSAhPSAwKSB7CgkJcHJpbnRrKEJJT1NfRVJSLCJ3cml0ZV9sMig1LCAwKSBmYWlsZWRcbiIpOwoJCWdvdG8gZG9uZTsKCX0KCgliYmxjdGwzID0gcmRtc3IoQkJMX0NSX0NUTDMpOwoJaWYgKHNpZ25hdHVyZSA9PSAweDY1MCkgewoJCS8qIENoYW5nZSB0aGUgTDIgbGF0ZW5jeSB0byAwMTAxIHRoZW4gYmFjayB0bwoJCSAqIG9yaWdpbmFsIHZhbHVlLiBJIGRvbid0IGtub3cgd2h5IHRoaXMgaXMgbmVlZGVkIC0gZHBkCgkJICovCgkJZWF4ID0gYmJsY3RsMy5sbzsKCQliYmxjdGwzLmxvICY9IH5CQkxDUjNfTDJfTEFURU5DWTsKCQliYmxjdGwzLmxvIHw9IDB4MGE7CgkJd3Jtc3IoQkJMX0NSX0NUTDMsIGJibGN0bDMpOwoJCWJibGN0bDMubG8gPSBlYXg7CgkJd3Jtc3IoQkJMX0NSX0NUTDMsIGJibGN0bDMpOwoJfQoKCS8qIEVuYWJsZSBMMiBpbiBCQkxfQ1JfQ1RMMyAqLwoJYmJsY3RsMy5sbyB8PSBCQkxDUjNfTDJfRU5BQkxFRDsKCXdybXNyKEJCTF9DUl9DVEwzLCBiYmxjdGwzKTsKCgkvKiBUdXJuIG9uIGNhY2hlLiBCb3RoIEwxIGFuZCBMMiBhcmUgbm93IGFjdGl2ZS4gV2Fob28hICovCmRvbmU6CglyZXN1bHQgPSAwOwoJZ290byBvdXQ7CmJhZDoKCXJlc3VsdCA9IC0xOwpvdXQ6CglwcmludGsoQklPU19JTkZPLCAiZG9uZS5cbiIpOwoJcmV0dXJuIHJlc3VsdDsKfQoK