LyoKICogQ29weXJpZ2h0IChjKSAxOTk5IEt1bmdsaWdhIFRla25pc2thIEj2Z3Nrb2xhbgogKiAoUm95YWwgSW5zdGl0dXRlIG9mIFRlY2hub2xvZ3ksIFN0b2NraG9sbSwgU3dlZGVuKS4KICogQWxsIHJpZ2h0cyByZXNlcnZlZC4KICoKICogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0CiAqIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucwogKiBhcmUgbWV0OgogKgogKiAxLiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAogKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCiAqCiAqIDIuIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0CiAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbiB0aGUKICogICAgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlIGRpc3RyaWJ1dGlvbi4KICoKICogMy4gQWxsIGFkdmVydGlzaW5nIG1hdGVyaWFscyBtZW50aW9uaW5nIGZlYXR1cmVzIG9yIHVzZSBvZiB0aGlzIHNvZnR3YXJlCiAqICAgIG11c3QgZGlzcGxheSB0aGUgZm9sbG93aW5nIGFja25vd2xlZGdlbWVudDoKICogICAgICBUaGlzIHByb2R1Y3QgaW5jbHVkZXMgc29mdHdhcmUgZGV2ZWxvcGVkIGJ5IHRoZSBLdW5nbGlnYSBUZWtuaXNrYQogKiAgICAgIEj2Z3Nrb2xhbiBhbmQgaXRzIGNvbnRyaWJ1dG9ycy4KICoKICogNC4gTmVpdGhlciB0aGUgbmFtZSBvZiB0aGUgSW5zdGl0dXRlIG5vciB0aGUgbmFtZXMgb2YgaXRzIGNvbnRyaWJ1dG9ycwogKiAgICBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUKICogICAgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCiAqCiAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIElOU1RJVFVURSBBTkQgQ09OVFJJQlVUT1JTIGBgQVMgSVMnJyBBTkQKICogQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFCiAqIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFCiAqIEFSRSBESVNDTEFJTUVELiAgSU4gTk8gRVZFTlQgU0hBTEwgVEhFIElOU1RJVFVURSBPUiBDT05UUklCVVRPUlMgQkUgTElBQkxFCiAqIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwgU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMCiAqIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTCiAqIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKQogKiBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVAogKiBMSUFCSUxJVFksIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZCiAqIE9VVCBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YKICogU1VDSCBEQU1BR0UuCiAqLwoKLyogJElkOiBpbmV0X250b3AuYyx2IDEuOCAyMDA1LTAyLTA5IDAyOjI1OjQ2IGd1eSBFeHAgJCAqLwoKI2lmbmRlZiBsaW50CnN0YXRpYyBjb25zdCBjaGFyIHJjc2lkW10gX1VfID0KICAgICAiQCgjKSAkSGVhZGVyOiAvdGNwZHVtcC9tYXN0ZXIvdGNwZHVtcC9taXNzaW5nL2luZXRfbnRvcC5jLHYgMS44IDIwMDUtMDItMDkgMDI6MjU6NDYgZ3V5IEV4cCAkIjsKI2VuZGlmCgojaW5jbHVkZSA8dGNwZHVtcC1zdGRpbmMuaD4KCiNpbmNsdWRlIDxzdGRpby5oPgojaW5jbHVkZSA8ZXJybm8uaD4KCi8qCiAqCiAqLwoKI2lmbmRlZiBJTjZBRERSU1oKI2RlZmluZSBJTjZBRERSU1ogICAxNiAgIC8qIElQdjYgVF9BQUFBICovCiNlbmRpZgoKI2lmbmRlZiBJTlQxNlNaCiNkZWZpbmUgSU5UMTZTWiAgICAgMiAgICAvKiB3b3JkIHNpemUgKi8KI2VuZGlmCgpzdGF0aWMgY29uc3QgY2hhciAqCmluZXRfbnRvcF92NCAoY29uc3Qgdm9pZCAqc3JjLCBjaGFyICpkc3QsIHNpemVfdCBzaXplKQp7CiAgICBjb25zdCBjaGFyIGRpZ2l0c1tdID0gIjAxMjM0NTY3ODkiOwogICAgaW50IGk7CiAgICBzdHJ1Y3QgaW5fYWRkciAqYWRkciA9IChzdHJ1Y3QgaW5fYWRkciAqKXNyYzsKICAgIHVfbG9uZyBhID0gbnRvaGwoYWRkci0+c19hZGRyKTsKICAgIGNvbnN0IGNoYXIgKm9yaWdfZHN0ID0gZHN0OwoKICAgIGlmIChzaXplIDwgSU5FVF9BRERSU1RSTEVOKSB7CgllcnJubyA9IEVOT1NQQzsKCXJldHVybiBOVUxMOwogICAgfQogICAgZm9yIChpID0gMDsgaSA8IDQ7ICsraSkgewoJaW50IG4gPSAoYSA+PiAoMjQgLSBpICogOCkpICYgMHhGRjsKCWludCBub25femVyb3AgPSAwOwoKCWlmIChub25femVyb3AgfHwgbiAvIDEwMCA+IDApIHsKCSAgICAqZHN0KysgPSBkaWdpdHNbbiAvIDEwMF07CgkgICAgbiAlPSAxMDA7CgkgICAgbm9uX3plcm9wID0gMTsKCX0KCWlmIChub25femVyb3AgfHwgbiAvIDEwID4gMCkgewoJICAgICpkc3QrKyA9IGRpZ2l0c1tuIC8gMTBdOwoJICAgIG4gJT0gMTA7CgkgICAgbm9uX3plcm9wID0gMTsKCX0KCSpkc3QrKyA9IGRpZ2l0c1tuXTsKCWlmIChpICE9IDMpCgkgICAgKmRzdCsrID0gJy4nOwogICAgfQogICAgKmRzdCsrID0gJ1wwJzsKICAgIHJldHVybiBvcmlnX2RzdDsKfQoKI2lmZGVmIElORVQ2Ci8qCiAqIENvbnZlcnQgSVB2NiBiaW5hcnkgYWRkcmVzcyBpbnRvIHByZXNlbnRhdGlvbiAocHJpbnRhYmxlKSBmb3JtYXQuCiAqLwpzdGF0aWMgY29uc3QgY2hhciAqCmluZXRfbnRvcF92NiAoY29uc3QgdV9jaGFyICpzcmMsIGNoYXIgKmRzdCwgc2l6ZV90IHNpemUpCnsKICAvKgogICAqIE5vdGUgdGhhdCBpbnQzMl90IGFuZCBpbnQxNl90IG5lZWQgb25seSBiZSAiYXQgbGVhc3QiIGxhcmdlIGVub3VnaAogICAqIHRvIGNvbnRhaW4gYSB2YWx1ZSBvZiB0aGUgc3BlY2lmaWVkIHNpemUuICBPbiBzb21lIHN5c3RlbXMsIGxpa2UKICAgKiBDcmF5cywgdGhlcmUgaXMgbm8gc3VjaCB0aGluZyBhcyBhbiBpbnRlZ2VyIHZhcmlhYmxlIHdpdGggMTYgYml0cy4KICAgKiBLZWVwIHRoaXMgaW4gbWluZCBpZiB5b3UgdGhpbmsgdGhpcyBmdW5jdGlvbiBzaG91bGQgaGF2ZSBiZWVuIGNvZGVkCiAgICogdG8gdXNlIHBvaW50ZXIgb3ZlcmxheXMuICBBbGwgdGhlIHdvcmxkJ3Mgbm90IGEgVkFYLgogICAqLwogIGNoYXIgIHRtcCBbSU5FVDZfQUREUlNUUkxFTisxXTsKICBjaGFyICp0cDsKICBzdHJ1Y3QgewogICAgbG9uZyBiYXNlOwogICAgbG9uZyBsZW47CiAgfSBiZXN0LCBjdXI7CiAgdV9sb25nIHdvcmRzIFtJTjZBRERSU1ogLyBJTlQxNlNaXTsKICBpbnQgICAgaTsKCiAgLyogUHJlcHJvY2VzczoKICAgKiAgQ29weSB0aGUgaW5wdXQgKGJ5dGV3aXNlKSBhcnJheSBpbnRvIGEgd29yZHdpc2UgYXJyYXkuCiAgICogIEZpbmQgdGhlIGxvbmdlc3QgcnVuIG9mIDB4MDAncyBpbiBzcmNbXSBmb3IgOjogc2hvcnRoYW5kaW5nLgogICAqLwogIG1lbXNldCAod29yZHMsIDAsIHNpemVvZih3b3JkcykpOwogIGZvciAoaSA9IDA7IGkgPCBJTjZBRERSU1o7IGkrKykKICAgICAgd29yZHNbaS8yXSB8PSAoc3JjW2ldIDw8ICgoMSAtIChpICUgMikpIDw8IDMpKTsKCiAgYmVzdC5iYXNlID0gLTE7CiAgY3VyLmJhc2UgID0gLTE7CiAgZm9yIChpID0gMDsgaSA8IChJTjZBRERSU1ogLyBJTlQxNlNaKTsgaSsrKQogIHsKICAgIGlmICh3b3Jkc1tpXSA9PSAwKQogICAgewogICAgICBpZiAoY3VyLmJhc2UgPT0gLTEpCiAgICAgICAgICAgY3VyLmJhc2UgPSBpLCBjdXIubGVuID0gMTsKICAgICAgZWxzZSBjdXIubGVuKys7CiAgICB9CiAgICBlbHNlIGlmIChjdXIuYmFzZSAhPSAtMSkKICAgIHsKICAgICAgaWYgKGJlc3QuYmFzZSA9PSAtMSB8fCBjdXIubGVuID4gYmVzdC5sZW4pCiAgICAgICAgIGJlc3QgPSBjdXI7CiAgICAgIGN1ci5iYXNlID0gLTE7CiAgICB9CiAgfQogIGlmICgoY3VyLmJhc2UgIT0gLTEpICYmIChiZXN0LmJhc2UgPT0gLTEgfHwgY3VyLmxlbiA+IGJlc3QubGVuKSkKICAgICBiZXN0ID0gY3VyOwogIGlmIChiZXN0LmJhc2UgIT0gLTEgJiYgYmVzdC5sZW4gPCAyKQogICAgIGJlc3QuYmFzZSA9IC0xOwoKICAvKiBGb3JtYXQgdGhlIHJlc3VsdC4KICAgKi8KICB0cCA9IHRtcDsKICBmb3IgKGkgPSAwOyBpIDwgKElONkFERFJTWiAvIElOVDE2U1opOyBpKyspCiAgewogICAgLyogQXJlIHdlIGluc2lkZSB0aGUgYmVzdCBydW4gb2YgMHgwMCdzPwogICAgICovCiAgICBpZiAoYmVzdC5iYXNlICE9IC0xICYmIGkgPj0gYmVzdC5iYXNlICYmIGkgPCAoYmVzdC5iYXNlICsgYmVzdC5sZW4pKQogICAgewogICAgICBpZiAoaSA9PSBiZXN0LmJhc2UpCiAgICAgICAgICp0cCsrID0gJzonOwogICAgICBjb250aW51ZTsKICAgIH0KCiAgICAvKiBBcmUgd2UgZm9sbG93aW5nIGFuIGluaXRpYWwgcnVuIG9mIDB4MDBzIG9yIGFueSByZWFsIGhleD8KICAgICAqLwogICAgaWYgKGkgIT0gMCkKICAgICAgICp0cCsrID0gJzonOwoKICAgIC8qIElzIHRoaXMgYWRkcmVzcyBhbiBlbmNhcHN1bGF0ZWQgSVB2ND8KICAgICAqLwogICAgaWYgKGkgPT0gNiAmJiBiZXN0LmJhc2UgPT0gMCAmJgogICAgICAgIChiZXN0LmxlbiA9PSA2IHx8IChiZXN0LmxlbiA9PSA1ICYmIHdvcmRzWzVdID09IDB4ZmZmZikpKQogICAgewogICAgICBpZiAoIWluZXRfbnRvcF92NChzcmMrMTIsIHRwLCBzaXplb2YodG1wKSAtICh0cCAtIHRtcCkpKQogICAgICB7CiAgICAgICAgZXJybm8gPSBFTk9TUEM7CiAgICAgICAgcmV0dXJuIChOVUxMKTsKICAgICAgfQogICAgICB0cCArPSBzdHJsZW4odHApOwogICAgICBicmVhazsKICAgIH0KICAgIHRwICs9IHNwcmludGYgKHRwLCAiJWxYIiwgd29yZHNbaV0pOwogIH0KCiAgLyogV2FzIGl0IGEgdHJhaWxpbmcgcnVuIG9mIDB4MDAncz8KICAgKi8KICBpZiAoYmVzdC5iYXNlICE9IC0xICYmIChiZXN0LmJhc2UgKyBiZXN0LmxlbikgPT0gKElONkFERFJTWiAvIElOVDE2U1opKQogICAgICp0cCsrID0gJzonOwogICp0cCsrID0gJ1wwJzsKCiAgLyogQ2hlY2sgZm9yIG92ZXJmbG93LCBjb3B5LCBhbmQgd2UncmUgZG9uZS4KICAgKi8KICBpZiAoKHNpemVfdCkodHAgLSB0bXApID4gc2l6ZSkKICB7CiAgICBlcnJubyA9IEVOT1NQQzsKICAgIHJldHVybiAoTlVMTCk7CiAgfQogIHJldHVybiBzdHJjcHkgKGRzdCwgdG1wKTsKICByZXR1cm4gKE5VTEwpOwp9CiNlbmRpZiAgIC8qIElORVQ2ICovCgoKY29uc3QgY2hhciAqCmluZXRfbnRvcChpbnQgYWYsIGNvbnN0IHZvaWQgKnNyYywgY2hhciAqZHN0LCBzaXplX3Qgc2l6ZSkKewogICAgc3dpdGNoIChhZikgewogICAgY2FzZSBBRl9JTkVUIDoKCXJldHVybiBpbmV0X250b3BfdjQgKHNyYywgZHN0LCBzaXplKTsKI2lmZGVmIElORVQ2CiAgICBjYXNlIEFGX0lORVQ2OgogICAgICAgICByZXR1cm4gaW5ldF9udG9wX3Y2ICgoY29uc3QgdV9jaGFyKilzcmMsIGRzdCwgc2l6ZSk7CiNlbmRpZgogICAgZGVmYXVsdCA6CgllcnJubyA9IEVBRk5PU1VQUE9SVDsKCXJldHVybiBOVUxMOwogICAgfQp9Cg==