LyoKICogQ29weXJpZ2h0IChjKSAxOTk5IEt1bmdsaWdhIFRla25pc2thIEj2Z3Nrb2xhbgogKiAoUm95YWwgSW5zdGl0dXRlIG9mIFRlY2hub2xvZ3ksIFN0b2NraG9sbSwgU3dlZGVuKS4KICogQWxsIHJpZ2h0cyByZXNlcnZlZC4KICoKICogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0CiAqIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucwogKiBhcmUgbWV0OgogKgogKiAxLiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAogKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCiAqCiAqIDIuIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0CiAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbiB0aGUKICogICAgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlIGRpc3RyaWJ1dGlvbi4KICoKICogMy4gQWxsIGFkdmVydGlzaW5nIG1hdGVyaWFscyBtZW50aW9uaW5nIGZlYXR1cmVzIG9yIHVzZSBvZiB0aGlzIHNvZnR3YXJlCiAqICAgIG11c3QgZGlzcGxheSB0aGUgZm9sbG93aW5nIGFja25vd2xlZGdlbWVudDoKICogICAgICBUaGlzIHByb2R1Y3QgaW5jbHVkZXMgc29mdHdhcmUgZGV2ZWxvcGVkIGJ5IHRoZSBLdW5nbGlnYSBUZWtuaXNrYQogKiAgICAgIEj2Z3Nrb2xhbiBhbmQgaXRzIGNvbnRyaWJ1dG9ycy4KICoKICogNC4gTmVpdGhlciB0aGUgbmFtZSBvZiB0aGUgSW5zdGl0dXRlIG5vciB0aGUgbmFtZXMgb2YgaXRzIGNvbnRyaWJ1dG9ycwogKiAgICBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUKICogICAgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCiAqCiAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIElOU1RJVFVURSBBTkQgQ09OVFJJQlVUT1JTIGBgQVMgSVMnJyBBTkQKICogQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFCiAqIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFCiAqIEFSRSBESVNDTEFJTUVELiAgSU4gTk8gRVZFTlQgU0hBTEwgVEhFIElOU1RJVFVURSBPUiBDT05UUklCVVRPUlMgQkUgTElBQkxFCiAqIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwgU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMCiAqIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTCiAqIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKQogKiBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVAogKiBMSUFCSUxJVFksIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZCiAqIE9VVCBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YKICogU1VDSCBEQU1BR0UuCiAqLwoKI2lmZGVmIEhBVkVfQ09ORklHX0gKI2luY2x1ZGUgImNvbmZpZy5oIgojZW5kaWYKCiNpbmNsdWRlIDx0Y3BkdW1wLXN0ZGluYy5oPgoKI2luY2x1ZGUgPHN0ZGlvLmg+CgovKgogKgogKi8KCiNpZm5kZWYgSU42QUREUlNaCiNkZWZpbmUgSU42QUREUlNaICAgMTYgICAvKiBJUHY2IFRfQUFBQSAqLwojZW5kaWYKCiNpZm5kZWYgSU5UMTZTWgojZGVmaW5lIElOVDE2U1ogICAgIDIgICAgLyogd29yZCBzaXplICovCiNlbmRpZgoKc3RhdGljIGNvbnN0IGNoYXIgKgppbmV0X250b3BfdjQgKGNvbnN0IHZvaWQgKnNyYywgY2hhciAqZHN0LCBzaXplX3Qgc2l6ZSkKewogICAgY29uc3QgY2hhciBkaWdpdHNbXSA9ICIwMTIzNDU2Nzg5IjsKICAgIGludCBpOwogICAgc3RydWN0IGluX2FkZHIgKmFkZHIgPSAoc3RydWN0IGluX2FkZHIgKilzcmM7CiAgICB1X2xvbmcgYSA9IG50b2hsKGFkZHItPnNfYWRkcik7CiAgICBjb25zdCBjaGFyICpvcmlnX2RzdCA9IGRzdDsKCiAgICBpZiAoc2l6ZSA8IElORVRfQUREUlNUUkxFTikgewoJZXJybm8gPSBFTk9TUEM7CglyZXR1cm4gTlVMTDsKICAgIH0KICAgIGZvciAoaSA9IDA7IGkgPCA0OyArK2kpIHsKCWludCBuID0gKGEgPj4gKDI0IC0gaSAqIDgpKSAmIDB4RkY7CglpbnQgbm9uX3plcm9wID0gMDsKCglpZiAobm9uX3plcm9wIHx8IG4gLyAxMDAgPiAwKSB7CgkgICAgKmRzdCsrID0gZGlnaXRzW24gLyAxMDBdOwoJICAgIG4gJT0gMTAwOwoJICAgIG5vbl96ZXJvcCA9IDE7Cgl9CglpZiAobm9uX3plcm9wIHx8IG4gLyAxMCA+IDApIHsKCSAgICAqZHN0KysgPSBkaWdpdHNbbiAvIDEwXTsKCSAgICBuICU9IDEwOwoJICAgIG5vbl96ZXJvcCA9IDE7Cgl9CgkqZHN0KysgPSBkaWdpdHNbbl07CglpZiAoaSAhPSAzKQoJICAgICpkc3QrKyA9ICcuJzsKICAgIH0KICAgICpkc3QrKyA9ICdcMCc7CiAgICByZXR1cm4gb3JpZ19kc3Q7Cn0KCiNpZmRlZiBJTkVUNgovKgogKiBDb252ZXJ0IElQdjYgYmluYXJ5IGFkZHJlc3MgaW50byBwcmVzZW50YXRpb24gKHByaW50YWJsZSkgZm9ybWF0LgogKi8Kc3RhdGljIGNvbnN0IGNoYXIgKgppbmV0X250b3BfdjYgKGNvbnN0IHVfY2hhciAqc3JjLCBjaGFyICpkc3QsIHNpemVfdCBzaXplKQp7CiAgLyoKICAgKiBOb3RlIHRoYXQgaW50MzJfdCBhbmQgaW50MTZfdCBuZWVkIG9ubHkgYmUgImF0IGxlYXN0IiBsYXJnZSBlbm91Z2gKICAgKiB0byBjb250YWluIGEgdmFsdWUgb2YgdGhlIHNwZWNpZmllZCBzaXplLiAgT24gc29tZSBzeXN0ZW1zLCBsaWtlCiAgICogQ3JheXMsIHRoZXJlIGlzIG5vIHN1Y2ggdGhpbmcgYXMgYW4gaW50ZWdlciB2YXJpYWJsZSB3aXRoIDE2IGJpdHMuCiAgICogS2VlcCB0aGlzIGluIG1pbmQgaWYgeW91IHRoaW5rIHRoaXMgZnVuY3Rpb24gc2hvdWxkIGhhdmUgYmVlbiBjb2RlZAogICAqIHRvIHVzZSBwb2ludGVyIG92ZXJsYXlzLiAgQWxsIHRoZSB3b3JsZCdzIG5vdCBhIFZBWC4KICAgKi8KICBjaGFyICB0bXAgW0lORVQ2X0FERFJTVFJMRU4rMV07CiAgY2hhciAqdHA7CiAgc3RydWN0IHsKICAgIGxvbmcgYmFzZTsKICAgIGxvbmcgbGVuOwogIH0gYmVzdCwgY3VyOwogIHVfbG9uZyB3b3JkcyBbSU42QUREUlNaIC8gSU5UMTZTWl07CiAgaW50ICAgIGk7CgogIC8qIFByZXByb2Nlc3M6CiAgICogIENvcHkgdGhlIGlucHV0IChieXRld2lzZSkgYXJyYXkgaW50byBhIHdvcmR3aXNlIGFycmF5LgogICAqICBGaW5kIHRoZSBsb25nZXN0IHJ1biBvZiAweDAwJ3MgaW4gc3JjW10gZm9yIDo6IHNob3J0aGFuZGluZy4KICAgKi8KICBtZW1zZXQgKHdvcmRzLCAwLCBzaXplb2Yod29yZHMpKTsKICBmb3IgKGkgPSAwOyBpIDwgSU42QUREUlNaOyBpKyspCiAgICAgIHdvcmRzW2kvMl0gfD0gKHNyY1tpXSA8PCAoKDEgLSAoaSAlIDIpKSA8PCAzKSk7CgogIGJlc3QubGVuID0gMDsKICBiZXN0LmJhc2UgPSAtMTsKICBjdXIubGVuID0gMDsKICBjdXIuYmFzZSAgPSAtMTsKICBmb3IgKGkgPSAwOyBpIDwgKElONkFERFJTWiAvIElOVDE2U1opOyBpKyspCiAgewogICAgaWYgKHdvcmRzW2ldID09IDApCiAgICB7CiAgICAgIGlmIChjdXIuYmFzZSA9PSAtMSkKICAgICAgICAgICBjdXIuYmFzZSA9IGksIGN1ci5sZW4gPSAxOwogICAgICBlbHNlIGN1ci5sZW4rKzsKICAgIH0KICAgIGVsc2UgaWYgKGN1ci5iYXNlICE9IC0xKQogICAgewogICAgICBpZiAoYmVzdC5iYXNlID09IC0xIHx8IGN1ci5sZW4gPiBiZXN0LmxlbikKICAgICAgICAgYmVzdCA9IGN1cjsKICAgICAgY3VyLmJhc2UgPSAtMTsKICAgIH0KICB9CiAgaWYgKChjdXIuYmFzZSAhPSAtMSkgJiYgKGJlc3QuYmFzZSA9PSAtMSB8fCBjdXIubGVuID4gYmVzdC5sZW4pKQogICAgIGJlc3QgPSBjdXI7CiAgaWYgKGJlc3QuYmFzZSAhPSAtMSAmJiBiZXN0LmxlbiA8IDIpCiAgICAgYmVzdC5iYXNlID0gLTE7CgogIC8qIEZvcm1hdCB0aGUgcmVzdWx0LgogICAqLwogIHRwID0gdG1wOwogIGZvciAoaSA9IDA7IGkgPCAoSU42QUREUlNaIC8gSU5UMTZTWik7IGkrKykKICB7CiAgICAvKiBBcmUgd2UgaW5zaWRlIHRoZSBiZXN0IHJ1biBvZiAweDAwJ3M/CiAgICAgKi8KICAgIGlmIChiZXN0LmJhc2UgIT0gLTEgJiYgaSA+PSBiZXN0LmJhc2UgJiYgaSA8IChiZXN0LmJhc2UgKyBiZXN0LmxlbikpCiAgICB7CiAgICAgIGlmIChpID09IGJlc3QuYmFzZSkKICAgICAgICAgKnRwKysgPSAnOic7CiAgICAgIGNvbnRpbnVlOwogICAgfQoKICAgIC8qIEFyZSB3ZSBmb2xsb3dpbmcgYW4gaW5pdGlhbCBydW4gb2YgMHgwMHMgb3IgYW55IHJlYWwgaGV4PwogICAgICovCiAgICBpZiAoaSAhPSAwKQogICAgICAgKnRwKysgPSAnOic7CgogICAgLyogSXMgdGhpcyBhZGRyZXNzIGFuIGVuY2Fwc3VsYXRlZCBJUHY0PwogICAgICovCiAgICBpZiAoaSA9PSA2ICYmIGJlc3QuYmFzZSA9PSAwICYmCiAgICAgICAgKGJlc3QubGVuID09IDYgfHwgKGJlc3QubGVuID09IDUgJiYgd29yZHNbNV0gPT0gMHhmZmZmKSkpCiAgICB7CiAgICAgIGlmICghaW5ldF9udG9wX3Y0KHNyYysxMiwgdHAsIHNpemVvZih0bXApIC0gKHRwIC0gdG1wKSkpCiAgICAgIHsKICAgICAgICBlcnJubyA9IEVOT1NQQzsKICAgICAgICByZXR1cm4gKE5VTEwpOwogICAgICB9CiAgICAgIHRwICs9IHN0cmxlbih0cCk7CiAgICAgIGJyZWFrOwogICAgfQogICAgdHAgKz0gc3ByaW50ZiAodHAsICIlbHgiLCB3b3Jkc1tpXSk7CiAgfQoKICAvKiBXYXMgaXQgYSB0cmFpbGluZyBydW4gb2YgMHgwMCdzPwogICAqLwogIGlmIChiZXN0LmJhc2UgIT0gLTEgJiYgKGJlc3QuYmFzZSArIGJlc3QubGVuKSA9PSAoSU42QUREUlNaIC8gSU5UMTZTWikpCiAgICAgKnRwKysgPSAnOic7CiAgKnRwKysgPSAnXDAnOwoKICAvKiBDaGVjayBmb3Igb3ZlcmZsb3csIGNvcHksIGFuZCB3ZSdyZSBkb25lLgogICAqLwogIGlmICgoc2l6ZV90KSh0cCAtIHRtcCkgPiBzaXplKQogIHsKICAgIGVycm5vID0gRU5PU1BDOwogICAgcmV0dXJuIChOVUxMKTsKICB9CiAgcmV0dXJuIHN0cmNweSAoZHN0LCB0bXApOwp9CiNlbmRpZiAgIC8qIElORVQ2ICovCgoKY29uc3QgY2hhciAqCmluZXRfbnRvcChpbnQgYWYsIGNvbnN0IHZvaWQgKnNyYywgY2hhciAqZHN0LCBzaXplX3Qgc2l6ZSkKewogICAgc3dpdGNoIChhZikgewogICAgY2FzZSBBRl9JTkVUIDoKCXJldHVybiBpbmV0X250b3BfdjQgKHNyYywgZHN0LCBzaXplKTsKI2lmZGVmIElORVQ2CiAgICBjYXNlIEFGX0lORVQ2OgogICAgICAgICByZXR1cm4gaW5ldF9udG9wX3Y2ICgoY29uc3QgdV9jaGFyKilzcmMsIGRzdCwgc2l6ZSk7CiNlbmRpZgogICAgZGVmYXVsdCA6CgllcnJubyA9IEVBRk5PU1VQUE9SVDsKCXJldHVybiBOVUxMOwogICAgfQp9Cg==