LyoKICogJFJDU0lkOiB4Yy9saWIvZm9udGNvbmZpZy9zcmMvZmNjYWNoZS5jLHYgMS4xMiAyMDAyLzA4LzIyIDA3OjM2OjQ0IGtlaXRocCBFeHAgJAogKgogKiBDb3B5cmlnaHQgqSAyMDAwIEtlaXRoIFBhY2thcmQKICoKICogUGVybWlzc2lvbiB0byB1c2UsIGNvcHksIG1vZGlmeSwgZGlzdHJpYnV0ZSwgYW5kIHNlbGwgdGhpcyBzb2Z0d2FyZSBhbmQgaXRzCiAqIGRvY3VtZW50YXRpb24gZm9yIGFueSBwdXJwb3NlIGlzIGhlcmVieSBncmFudGVkIHdpdGhvdXQgZmVlLCBwcm92aWRlZCB0aGF0CiAqIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlIGFwcGVhciBpbiBhbGwgY29waWVzIGFuZCB0aGF0IGJvdGggdGhhdAogKiBjb3B5cmlnaHQgbm90aWNlIGFuZCB0aGlzIHBlcm1pc3Npb24gbm90aWNlIGFwcGVhciBpbiBzdXBwb3J0aW5nCiAqIGRvY3VtZW50YXRpb24sIGFuZCB0aGF0IHRoZSBuYW1lIG9mIEtlaXRoIFBhY2thcmQgbm90IGJlIHVzZWQgaW4KICogYWR2ZXJ0aXNpbmcgb3IgcHVibGljaXR5IHBlcnRhaW5pbmcgdG8gZGlzdHJpYnV0aW9uIG9mIHRoZSBzb2Z0d2FyZSB3aXRob3V0CiAqIHNwZWNpZmljLCB3cml0dGVuIHByaW9yIHBlcm1pc3Npb24uICBLZWl0aCBQYWNrYXJkIG1ha2VzIG5vCiAqIHJlcHJlc2VudGF0aW9ucyBhYm91dCB0aGUgc3VpdGFiaWxpdHkgb2YgdGhpcyBzb2Z0d2FyZSBmb3IgYW55IHB1cnBvc2UuICBJdAogKiBpcyBwcm92aWRlZCAiYXMgaXMiIHdpdGhvdXQgZXhwcmVzcyBvciBpbXBsaWVkIHdhcnJhbnR5LgogKgogKiBLRUlUSCBQQUNLQVJEIERJU0NMQUlNUyBBTEwgV0FSUkFOVElFUyBXSVRIIFJFR0FSRCBUTyBUSElTIFNPRlRXQVJFLAogKiBJTkNMVURJTkcgQUxMIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MsIElOIE5PCiAqIEVWRU5UIFNIQUxMIEtFSVRIIFBBQ0tBUkQgQkUgTElBQkxFIEZPUiBBTlkgU1BFQ0lBTCwgSU5ESVJFQ1QgT1IKICogQ09OU0VRVUVOVElBTCBEQU1BR0VTIE9SIEFOWSBEQU1BR0VTIFdIQVRTT0VWRVIgUkVTVUxUSU5HIEZST00gTE9TUyBPRiBVU0UsCiAqIERBVEEgT1IgUFJPRklUUywgV0hFVEhFUiBJTiBBTiBBQ1RJT04gT0YgQ09OVFJBQ1QsIE5FR0xJR0VOQ0UgT1IgT1RIRVIKICogVE9SVElPVVMgQUNUSU9OLCBBUklTSU5HIE9VVCBPRiBPUiBJTiBDT05ORUNUSU9OIFdJVEggVEhFIFVTRSBPUgogKiBQRVJGT1JNQU5DRSBPRiBUSElTIFNPRlRXQVJFLgogKi8KCiNpbmNsdWRlICJmY2ludC5oIgoKLyoKICogUE9TSVggaGFzIGJyb2tlbiBzdGRpbyBzbyB0aGF0IGdldGMgbXVzdCBkbyB0aHJlYWQtc2FmZSBsb2NraW5nLAogKiB0aGlzIGlzIGEgc2VyaW91cyBwZXJmb3JtYW5jZSBwcm9ibGVtIGZvciBhcHBsaWNhdGlvbnMgZG9pbmcgbGFyZ2UKICogYW1vdW50cyBvZiBJTyB3aXRoIGdldGMgKGFzIGlzIGRvbmUgaGVyZSkuICBJZiBhdmFpbGFibGUsIHVzZQogKiB0aGUgZ2V0Y191bmxvY2tlZCB2YXJpZW50IGluc3RlYWQuCiAqLwogCiNpZiBkZWZpbmVkKGdldGNfdW5sb2NrZWQpIHx8IGRlZmluZWQoX0lPX2dldGNfdW5sb2NrZWQpCiNkZWZpbmUgR0VUQyhmKSBnZXRjX3VubG9ja2VkKGYpCiNkZWZpbmUgUFVUQyhjLGYpIHB1dGNfdW5sb2NrZWQoYyxmKQojZWxzZQojZGVmaW5lIEdFVEMoZikgZ2V0YyhmKQojZGVmaW5lIFBVVEMoYyxmKSBwdXRjKGMsZikKI2VuZGlmCgojZGVmaW5lIEZDX0RCR19DQUNIRV9SRUYgICAgMTAyNAoKc3RhdGljIEZjQ2hhcjggKgpGY0NhY2hlUmVhZFN0cmluZyAoRklMRSAqZiwgRmNDaGFyOCAqZGVzdCwgaW50IGxlbikKewogICAgaW50CQljOwogICAgRmNCb29sCWVzY2FwZTsKICAgIEZjQ2hhcjgJKmQ7CiAgICBpbnQJCXNpemU7CiAgICBpbnQJCWk7CgogICAgd2hpbGUgKChjID0gR0VUQyAoZikpICE9IEVPRikKCWlmIChjID09ICciJykKCSAgICBicmVhazsKICAgIGlmIChjID09IEVPRikKCXJldHVybiBGY0ZhbHNlOwogICAgaWYgKGxlbiA9PSAwKQoJcmV0dXJuIEZjRmFsc2U7CiAgICAKICAgIHNpemUgPSBsZW47CiAgICBpID0gMDsKICAgIGQgPSBkZXN0OwogICAgZXNjYXBlID0gRmNGYWxzZTsKICAgIHdoaWxlICgoYyA9IEdFVEMgKGYpKSAhPSBFT0YpCiAgICB7CglpZiAoIWVzY2FwZSkKCXsKCSAgICBzd2l0Y2ggKGMpIHsKCSAgICBjYXNlICciJzoKCQljID0gJ1wwJzsKCQlicmVhazsKCSAgICBjYXNlICdcXCc6CgkJZXNjYXBlID0gRmNUcnVlOwoJCWNvbnRpbnVlOwoJICAgIH0KCX0KCWlmIChpID09IHNpemUpCgl7CgkgICAgRmNDaGFyOCAqbmV3ID0gbWFsbG9jIChzaXplICogMik7CS8qIGZyZWVkIGluIGNhbGxlciAqLwoJICAgIGlmICghbmV3KQoJCWJyZWFrOwoJICAgIG1lbWNweSAobmV3LCBkLCBzaXplKTsKCSAgICBzaXplICo9IDI7CgkgICAgaWYgKGQgIT0gZGVzdCkKCQlmcmVlIChkKTsKCSAgICBkID0gbmV3OwoJfQoJZFtpKytdID0gYzsKCWlmIChjID09ICdcMCcpCgkgICAgcmV0dXJuIGQ7Cgllc2NhcGUgPSBGY0ZhbHNlOwogICAgfQogICAgaWYgKGQgIT0gZGVzdCkKCWZyZWUgKGQpOwogICAgcmV0dXJuIDA7Cn0KCnN0YXRpYyBGY0Jvb2wKRmNDYWNoZVJlYWRVbG9uZyAoRklMRSAqZiwgdW5zaWduZWQgbG9uZyAqZGVzdCkKewogICAgdW5zaWduZWQgbG9uZyAgIHQ7CiAgICBpbnQJCSAgICBjOwoKICAgIHdoaWxlICgoYyA9IEdFVEMgKGYpKSAhPSBFT0YpCiAgICB7CglpZiAoIWlzc3BhY2UgKGMpKQoJICAgIGJyZWFrOwogICAgfQogICAgaWYgKGMgPT0gRU9GKQoJcmV0dXJuIEZjRmFsc2U7CiAgICB0ID0gMDsKICAgIGZvciAoOzspCiAgICB7CglpZiAoYyA9PSBFT0YgfHwgaXNzcGFjZSAoYykpCgkgICAgYnJlYWs7CglpZiAoIWlzZGlnaXQgKGMpKQoJICAgIHJldHVybiBGY0ZhbHNlOwoJdCA9IHQgKiAxMCArIChjIC0gJzAnKTsKCWMgPSBHRVRDIChmKTsKICAgIH0KICAgICpkZXN0ID0gdDsKICAgIHJldHVybiBGY1RydWU7Cn0KCnN0YXRpYyBGY0Jvb2wKRmNDYWNoZVJlYWRJbnQgKEZJTEUgKmYsIGludCAqZGVzdCkKewogICAgdW5zaWduZWQgbG9uZyAgIHQ7CiAgICBGY0Jvb2wJICAgIHJldDsKCiAgICByZXQgPSBGY0NhY2hlUmVhZFVsb25nIChmLCAmdCk7CiAgICBpZiAocmV0KQoJKmRlc3QgPSAoaW50KSB0OwogICAgcmV0dXJuIHJldDsKfQoKc3RhdGljIEZjQm9vbApGY0NhY2hlUmVhZFRpbWUgKEZJTEUgKmYsIHRpbWVfdCAqZGVzdCkKewogICAgdW5zaWduZWQgbG9uZyAgIHQ7CiAgICBGY0Jvb2wJICAgIHJldDsKCiAgICByZXQgPSBGY0NhY2hlUmVhZFVsb25nIChmLCAmdCk7CiAgICBpZiAocmV0KQoJKmRlc3QgPSAodGltZV90KSB0OwogICAgcmV0dXJuIHJldDsKfQoKc3RhdGljIEZjQm9vbApGY0NhY2hlV3JpdGVDaGFycyAoRklMRSAqZiwgY29uc3QgRmNDaGFyOCAqY2hhcnMpCnsKICAgIEZjQ2hhcjggICAgYzsKICAgIHdoaWxlICgoYyA9ICpjaGFycysrKSkKICAgIHsKCXN3aXRjaCAoYykgewoJY2FzZSAnIic6CgljYXNlICdcXCc6CgkgICAgaWYgKFBVVEMgKCdcXCcsIGYpID09IEVPRikKCQlyZXR1cm4gRmNGYWxzZTsKCSAgICAvKiBmYWxsIHRocm91Z2ggKi8KCWRlZmF1bHQ6CgkgICAgaWYgKFBVVEMgKGMsIGYpID09IEVPRikKCQlyZXR1cm4gRmNGYWxzZTsKCX0KICAgIH0KICAgIHJldHVybiBGY1RydWU7Cn0KCnN0YXRpYyBGY0Jvb2wKRmNDYWNoZVdyaXRlU3RyaW5nIChGSUxFICpmLCBjb25zdCBGY0NoYXI4ICpzdHJpbmcpCnsKCiAgICBpZiAoUFVUQyAoJyInLCBmKSA9PSBFT0YpCglyZXR1cm4gRmNGYWxzZTsKICAgIGlmICghRmNDYWNoZVdyaXRlQ2hhcnMgKGYsIHN0cmluZykpCglyZXR1cm4gRmNGYWxzZTsKICAgIGlmIChQVVRDICgnIicsIGYpID09IEVPRikKCXJldHVybiBGY0ZhbHNlOwogICAgcmV0dXJuIEZjVHJ1ZTsKfQoKc3RhdGljIEZjQm9vbApGY0NhY2hlV3JpdGVQYXRoIChGSUxFICpmLCBjb25zdCBGY0NoYXI4ICpkaXIsIGNvbnN0IEZjQ2hhcjggKmZpbGUpCnsKICAgIGlmIChQVVRDICgnIicsIGYpID09IEVPRikKCXJldHVybiBGY0ZhbHNlOwogICAgaWYgKGRpcikKCWlmICghRmNDYWNoZVdyaXRlQ2hhcnMgKGYsIGRpcikpCgkgICAgcmV0dXJuIEZjRmFsc2U7CiNpZmRlZiBfV0lOMzIKICAgIGlmIChkaXIgJiYKCWRpcltzdHJsZW4oKGNvbnN0IGNoYXIgKikgZGlyKSAtIDFdICE9ICcvJyAmJgoJZGlyW3N0cmxlbigoY29uc3QgY2hhciAqKSBkaXIpIC0gMV0gIT0gJ1xcJykKICAgIHsKCWlmICghRmNDYWNoZVdyaXRlQ2hhcnMgKGYsICJcXCIpKQoJICAgIHJldHVybiBGY0ZhbHNlOwogICAgfQojZWxzZQogICAgaWYgKGRpciAmJiBkaXJbc3RybGVuKChjb25zdCBjaGFyICopIGRpcikgLSAxXSAhPSAnLycpCglpZiAoUFVUQyAoJy8nLCBmKSA9PSBFT0YpCgkgICAgcmV0dXJuIEZjRmFsc2U7CiNlbmRpZgogICAgaWYgKCFGY0NhY2hlV3JpdGVDaGFycyAoZiwgZmlsZSkpCglyZXR1cm4gRmNGYWxzZTsKICAgIGlmIChQVVRDICgnIicsIGYpID09IEVPRikKCXJldHVybiBGY0ZhbHNlOwogICAgcmV0dXJuIEZjVHJ1ZTsKfQoKc3RhdGljIEZjQm9vbApGY0NhY2hlV3JpdGVVbG9uZyAoRklMRSAqZiwgdW5zaWduZWQgbG9uZyB0KQp7CiAgICBpbnQJICAgIHBvdzsKICAgIHVuc2lnbmVkIGxvbmcgICB0ZW1wLCBkaWdpdDsKCiAgICB0ZW1wID0gdDsKICAgIHBvdyA9IDE7CiAgICB3aGlsZSAodGVtcCA+PSAxMCkKICAgIHsKCXRlbXAgLz0gMTA7Cglwb3cgKj0gMTA7CiAgICB9CiAgICB0ZW1wID0gdDsKICAgIHdoaWxlIChwb3cpCiAgICB7CglkaWdpdCA9IHRlbXAgLyBwb3c7CglpZiAoUFVUQyAoKGNoYXIpIGRpZ2l0ICsgJzAnLCBmKSA9PSBFT0YpCgkgICAgcmV0dXJuIEZjRmFsc2U7Cgl0ZW1wID0gdGVtcCAtIHBvdyAqIGRpZ2l0OwoJcG93ID0gcG93IC8gMTA7CiAgICB9CiAgICByZXR1cm4gRmNUcnVlOwp9CgpzdGF0aWMgRmNCb29sCkZjQ2FjaGVXcml0ZUludCAoRklMRSAqZiwgaW50IGkpCnsKICAgIHJldHVybiBGY0NhY2hlV3JpdGVVbG9uZyAoZiwgKHVuc2lnbmVkIGxvbmcpIGkpOwp9CgpzdGF0aWMgRmNCb29sCkZjQ2FjaGVXcml0ZVRpbWUgKEZJTEUgKmYsIHRpbWVfdCB0KQp7CiAgICByZXR1cm4gRmNDYWNoZVdyaXRlVWxvbmcgKGYsICh1bnNpZ25lZCBsb25nKSB0KTsKfQoKc3RhdGljIEZjQm9vbApGY0NhY2hlRm9udFNldEFkZCAoRmNGb250U2V0CSAgICAqc2V0LAoJCSAgIEZjU3RyU2V0CSAgICAqZGlycywKCQkgICBjb25zdCBGY0NoYXI4ICAgICpkaXIsCgkJICAgaW50CQkgICAgZGlyX2xlbiwKCQkgICBjb25zdCBGY0NoYXI4ICAgICpmaWxlLAoJCSAgIGNvbnN0IEZjQ2hhcjggICAgKm5hbWUpCnsKICAgIEZjQ2hhcjgJcGF0aF9idWZbODE5Ml0sICpwYXRoOwogICAgaW50CQlsZW47CiAgICBGY0Jvb2wJcmV0ID0gRmNGYWxzZTsKICAgIEZjUGF0dGVybgkqZm9udDsKICAgIEZjUGF0dGVybgkqZnJvemVuOwoKICAgIHBhdGggPSBwYXRoX2J1ZjsKICAgIGxlbiA9IChkaXJfbGVuICsgMSArIHN0cmxlbiAoKGNvbnN0IGNoYXIgKikgZmlsZSkgKyAxKTsKICAgIGlmIChsZW4gPiBzaXplb2YgKHBhdGhfYnVmKSkKICAgIHsKCXBhdGggPSBtYWxsb2MgKGxlbik7CS8qIGZyZWVkIGRvd24gYmVsb3cgKi8KCWlmICghcGF0aCkKCSAgICByZXR1cm4gRmNGYWxzZTsKICAgIH0KICAgIHN0cm5jcHkgKChjaGFyICopIHBhdGgsIChjb25zdCBjaGFyICopIGRpciwgZGlyX2xlbik7CiNpZmRlZiBfV0lOMzIKICAgIGlmIChkaXJbZGlyX2xlbiAtIDFdICE9ICcvJyAmJiBkaXJbZGlyX2xlbiAtIDFdICE9ICdcXCcgKQoJcGF0aFtkaXJfbGVuKytdID0gJ1xcJzsKI2Vsc2UKICAgIGlmIChkaXJbZGlyX2xlbiAtIDFdICE9ICcvJykKCXBhdGhbZGlyX2xlbisrXSA9ICcvJzsKI2VuZGlmCiAgICBzdHJjcHkgKChjaGFyICopIHBhdGggKyBkaXJfbGVuLCAoY29uc3QgY2hhciAqKSBmaWxlKTsKICAgIGlmICghRmNTdHJDbXAgKG5hbWUsIEZDX0ZPTlRfRklMRV9ESVIpKQogICAgewoJaWYgKEZjRGVidWcgKCkgJiBGQ19EQkdfQ0FDSEVWKQoJICAgIHByaW50ZiAoIiBkaXIgY2FjaGUgZGlyIFwiJXNcIlxuIiwgcGF0aCk7CglyZXQgPSBGY1N0clNldEFkZCAoZGlycywgcGF0aCk7CiAgICB9CiAgICBlbHNlIGlmICghRmNTdHJDbXAgKG5hbWUsIEZDX0ZPTlRfRklMRV9JTlZBTElEKSkKICAgIHsKCXJldCA9IEZjVHJ1ZTsKICAgIH0KICAgIGVsc2UKICAgIHsKCWZvbnQgPSBGY05hbWVQYXJzZSAobmFtZSk7CglpZiAoZm9udCkKCXsKCSAgICBpZiAoRmNEZWJ1ZyAoKSAmIEZDX0RCR19DQUNIRVYpCgkJcHJpbnRmICgiIGRpciBjYWNoZSBmaWxlIFwiJXNcIlxuIiwgZmlsZSk7CgkgICAgcmV0ID0gRmNQYXR0ZXJuQWRkU3RyaW5nIChmb250LCBGQ19GSUxFLCBwYXRoKTsKCSAgICBpZiAocmV0KQoJICAgIHsKCQlmcm96ZW4gPSBGY1BhdHRlcm5GcmVlemUgKGZvbnQpOwoJCXJldCA9IChmcm96ZW4gIT0gMCk7CgkJaWYgKHJldCkKCQkgICByZXQgPSBGY0ZvbnRTZXRBZGQgKHNldCwgZnJvemVuKTsKCSAgICB9CgkgICAgRmNQYXR0ZXJuRGVzdHJveSAoZm9udCk7Cgl9CiAgICB9CiAgICBpZiAocGF0aCAhPSBwYXRoX2J1ZikgZnJlZSAocGF0aCk7CiAgICByZXR1cm4gcmV0OwogICAgCn0KCnN0YXRpYyB1bnNpZ25lZCBpbnQKRmNDYWNoZUhhc2ggKGNvbnN0IEZjQ2hhcjggKnN0cmluZywgaW50IGxlbikKewogICAgdW5zaWduZWQgaW50ICAgIGggPSAwOwogICAgRmNDaGFyOAkgICAgYzsKCiAgICB3aGlsZSAobGVuLS0gJiYgKGMgPSAqc3RyaW5nKyspKQoJaCA9IChoIDw8IDEpIF4gYzsKICAgIHJldHVybiBoOwp9CgovKgogKiBWZXJpZnkgdGhlIHNhdmVkIHRpbWVzdGFtcCBmb3IgYSBmaWxlCiAqLwpGY0Jvb2wKRmNHbG9iYWxDYWNoZUNoZWNrVGltZSAoY29uc3QgRmNDaGFyOCAqZmlsZSwgRmNHbG9iYWxDYWNoZUluZm8gKmluZm8pCnsKICAgIHN0cnVjdCBzdGF0CSAgICBzdGF0YjsKCiAgICBpZiAoc3RhdCAoKGNoYXIgKikgZmlsZSwgJnN0YXRiKSA8IDApCiAgICB7CglpZiAoRmNEZWJ1ZyAoKSAmIEZDX0RCR19DQUNIRSkKCSAgICBwcmludGYgKCIgZmlsZSAlcyBtaXNzaW5nXG4iLCBmaWxlKTsKCXJldHVybiBGY0ZhbHNlOwogICAgfQogICAgaWYgKHN0YXRiLnN0X210aW1lICE9IGluZm8tPnRpbWUpCiAgICB7CglpZiAoRmNEZWJ1ZyAoKSAmIEZDX0RCR19DQUNIRSkKCSAgICBwcmludGYgKCIgdGltZXN0YW1wIG1pc21hdGNoICh3YXMgJWQgaXMgJWQpXG4iLAoJCSAgICAoaW50KSBpbmZvLT50aW1lLCAoaW50KSBzdGF0Yi5zdF9tdGltZSk7CglyZXR1cm4gRmNGYWxzZTsKICAgIH0KICAgIHJldHVybiBGY1RydWU7Cn0KCnZvaWQKRmNHbG9iYWxDYWNoZVJlZmVyZW5jZWQgKEZjR2xvYmFsQ2FjaGUJICAgICpjYWNoZSwKCQkJIEZjR2xvYmFsQ2FjaGVJbmZvICAqaW5mbykKewogICAgaWYgKCFpbmZvLT5yZWZlcmVuY2VkKQogICAgewoJaW5mby0+cmVmZXJlbmNlZCA9IEZjVHJ1ZTsKCWNhY2hlLT5yZWZlcmVuY2VkKys7CglpZiAoRmNEZWJ1ZyAoKSAmIEZDX0RCR19DQUNIRV9SRUYpCgkgICAgcHJpbnRmICgiUmVmZXJlbmNlICVkICVzXG4iLCBjYWNoZS0+cmVmZXJlbmNlZCwgaW5mby0+ZmlsZSk7CiAgICB9Cn0KCi8qCiAqIEJyZWFrIGEgcGF0aCBpbnRvIGRpci9iYXNlIGVsZW1lbnRzIGFuZCBjb21wdXRlIHRoZSBiYXNlIGhhc2gKICogYW5kIHRoZSBkaXIgbGVuZ3RoLiAgVGhpcyBpcyBzaGFyZWQgYmV0d2VlbiB0aGUgZnVuY3Rpb25zCiAqIHdoaWNoIHdhbGsgdGhlIGZpbGUgY2FjaGVzCiAqLwoKdHlwZWRlZiBzdHJ1Y3QgX0ZjRmlsZVBhdGhJbmZvIHsKICAgIGNvbnN0IEZjQ2hhcjggICAqZGlyOwogICAgaW50CQkgICAgZGlyX2xlbjsKICAgIGNvbnN0IEZjQ2hhcjggICAqYmFzZTsKICAgIHVuc2lnbmVkIGludCAgICBiYXNlX2hhc2g7Cn0gRmNGaWxlUGF0aEluZm87CgpzdGF0aWMgRmNGaWxlUGF0aEluZm8KRmNGaWxlUGF0aEluZm9HZXQgKGNvbnN0IEZjQ2hhcjggICAgKnBhdGgpCnsKICAgIEZjRmlsZVBhdGhJbmZvICBpOwogICAgRmNDaGFyOAkgICAgKnNsYXNoOwoKICAgIHNsYXNoID0gRmNTdHJMYXN0U2xhc2ggKHBhdGgpOwogICAgaWYgKHNsYXNoKQogICAgewogICAgICAgIGkuZGlyID0gcGF0aDsKICAgICAgICBpLmRpcl9sZW4gPSBzbGFzaCAtIHBhdGg7CglpZiAoIWkuZGlyX2xlbikKCSAgICBpLmRpcl9sZW4gPSAxOwoJaS5iYXNlID0gc2xhc2ggKyAxOwogICAgfQogICAgZWxzZQogICAgewoJaS5kaXIgPSAoY29uc3QgRmNDaGFyOCAqKSAiLiI7CglpLmRpcl9sZW4gPSAxOwoJaS5iYXNlID0gcGF0aDsKICAgIH0KICAgIGkuYmFzZV9oYXNoID0gRmNDYWNoZUhhc2ggKGkuYmFzZSwgLTEpOwogICAgcmV0dXJuIGk7Cn0KCkZjR2xvYmFsQ2FjaGVEaXIgKgpGY0dsb2JhbENhY2hlRGlyR2V0IChGY0dsb2JhbENhY2hlICAqY2FjaGUsCgkJICAgICBjb25zdCBGY0NoYXI4ICAqZGlyLAoJCSAgICAgaW50CSAgICBsZW4sCgkJICAgICBGY0Jvb2wJICAgIGNyZWF0ZV9taXNzaW5nKQp7CiAgICB1bnNpZ25lZCBpbnQJaGFzaCA9IEZjQ2FjaGVIYXNoIChkaXIsIGxlbik7CiAgICBGY0dsb2JhbENhY2hlRGlyCSpkLCAqKnByZXY7CgogICAgZm9yIChwcmV2ID0gJmNhY2hlLT5lbnRzW2hhc2ggJSBGQ19HTE9CQUxfQ0FDSEVfRElSX0hBU0hfU0laRV07CgkgKGQgPSAqcHJldik7CgkgcHJldiA9ICYoKnByZXYpLT5uZXh0KQogICAgewoJaWYgKGQtPmluZm8uaGFzaCA9PSBoYXNoICYmIGQtPmxlbiA9PSBsZW4gJiYKCSAgICAhc3RybmNtcCAoKGNvbnN0IGNoYXIgKikgZC0+aW5mby5maWxlLAoJCSAgICAgIChjb25zdCBjaGFyICopIGRpciwgbGVuKSkKCSAgICBicmVhazsKICAgIH0KICAgIGlmICghKGQgPSAqcHJldikpCiAgICB7CglpbnQJaTsKCWlmICghY3JlYXRlX21pc3NpbmcpCgkgICAgcmV0dXJuIDA7CglkID0gbWFsbG9jIChzaXplb2YgKEZjR2xvYmFsQ2FjaGVEaXIpICsgbGVuICsgMSk7CglpZiAoIWQpCgkgICAgcmV0dXJuIDA7CglGY01lbUFsbG9jIChGQ19NRU1fQ0FDSEUsIHNpemVvZiAoRmNHbG9iYWxDYWNoZURpcikgKyBsZW4gKyAxKTsKCWQtPm5leHQgPSAqcHJldjsKCSpwcmV2ID0gZDsKCWQtPmluZm8uaGFzaCA9IGhhc2g7CglkLT5pbmZvLmZpbGUgPSAoRmNDaGFyOCAqKSAoZCArIDEpOwoJc3RybmNweSAoKGNoYXIgKikgZC0+aW5mby5maWxlLCAoY29uc3QgY2hhciAqKSBkaXIsIGxlbik7CglkLT5pbmZvLmZpbGVbbGVuXSA9ICdcMCc7CglkLT5pbmZvLnRpbWUgPSAwOwoJZC0+aW5mby5yZWZlcmVuY2VkID0gRmNGYWxzZTsKCWQtPmxlbiA9IGxlbjsKCWZvciAoaSA9IDA7IGkgPCBGQ19HTE9CQUxfQ0FDSEVfRklMRV9IQVNIX1NJWkU7IGkrKykKCSAgICBkLT5lbnRzW2ldID0gMDsKCWQtPnN1YmRpcnMgPSAwOwogICAgfQogICAgcmV0dXJuIGQ7Cn0KCnN0YXRpYyBGY0dsb2JhbENhY2hlSW5mbyAqCkZjR2xvYmFsQ2FjaGVEaXJBZGQgKEZjR2xvYmFsQ2FjaGUgICpjYWNoZSwKCQkgICAgIGNvbnN0IEZjQ2hhcjggICpkaXIsCgkJICAgICB0aW1lX3QJICAgIHRpbWUsCgkJICAgICBGY0Jvb2wJICAgIHJlcGxhY2UsCgkJICAgICBGY0Jvb2wJICAgIGNyZWF0ZV9taXNzaW5nKQp7CiAgICBGY0dsb2JhbENhY2hlRGlyCSpkOwogICAgRmNGaWxlUGF0aEluZm8JaTsKICAgIEZjR2xvYmFsQ2FjaGVTdWJkaXIJKnN1YmRpcjsKICAgIEZjR2xvYmFsQ2FjaGVEaXIJKnBhcmVudDsKCiAgICBpID0gRmNGaWxlUGF0aEluZm9HZXQgKGRpcik7CiAgICBwYXJlbnQgPSBGY0dsb2JhbENhY2hlRGlyR2V0IChjYWNoZSwgaS5kaXIsIGkuZGlyX2xlbiwgY3JlYXRlX21pc3NpbmcpOwogICAgLyoKICAgICAqIFRyaWNreSBoZXJlIC0tIGRpcmVjdG9yaWVzIGNvbnRhaW5pbmcgZm9udHMuY2FjaGUtMSBmaWxlcwogICAgICogbmVlZCBlbnRyaWVzIG9ubHkgd2hlbiB0aGUgcGFyZW50IGRvZXNuJ3QgaGF2ZSBhIGNhY2hlIGZpbGUuCiAgICAgKiBUaGF0IGlzLCB3aGVuIHRoZSBwYXJlbnQgYWxyZWFkeSBleGlzdHMgaW4gdGhlIGNhY2hlLCBpcwogICAgICogcmVmZXJlbmNlZCBhbmQgaGFzIGEgInJlYWwiIHRpbWVzdGFtcC4gIFRoZSB0aW1lIG9mIDAgaXMKICAgICAqIHNwZWNpYWwgYW5kIG1hcmtzIGRpcmVjdG9yaWVzIHdoaWNoIGdvdCBzdHVjayBpbiB0aGUKICAgICAqIGdsb2JhbCBjYWNoZSBmb3IgdGhpcyB2ZXJ5IHJlYXNvbi4gIFllcywgaXQgY291bGQKICAgICAqIHVzZSBhIHNlcGFyYXRlIGJvb2xlYW4gZmllbGQsIGFuZCBwcm9iYWJseSBzaG91bGQuCiAgICAgKi8KICAgIGlmICghcGFyZW50IHx8ICghY3JlYXRlX21pc3NpbmcgJiYgCgkJICAgICghcGFyZW50LT5pbmZvLnJlZmVyZW5jZWQgfHwKCQkgICAgKHBhcmVudC0+aW5mby50aW1lID09IDApKSkpCglyZXR1cm4gMDsKICAgIC8qCiAgICAgKiBBZGQgdGhpcyBkaXJlY3RvcnkgdG8gdGhlIGNhY2hlCiAgICAgKi8KICAgIGQgPSBGY0dsb2JhbENhY2hlRGlyR2V0IChjYWNoZSwgZGlyLCBzdHJsZW4gKChjb25zdCBjaGFyICopIGRpciksIEZjVHJ1ZSk7CiAgICBpZiAoIWQpCglyZXR1cm4gMDsKICAgIGQtPmluZm8udGltZSA9IHRpbWU7CiAgICAvKgogICAgICogQWRkIHRoaXMgZGlyZWN0b3J5IHRvIHRoZSBzdWJkaXJlY3RvcnkgbGlzdCBvZiB0aGUgcGFyZW50CiAgICAgKi8KICAgIHN1YmRpciA9IG1hbGxvYyAoc2l6ZW9mIChGY0dsb2JhbENhY2hlU3ViZGlyKSk7CiAgICBpZiAoIXN1YmRpcikKCXJldHVybiAwOwogICAgRmNNZW1BbGxvYyAoRkNfTUVNX0NBQ0hFLCBzaXplb2YgKEZjR2xvYmFsQ2FjaGVTdWJkaXIpKTsKICAgIHN1YmRpci0+ZW50ID0gZDsKICAgIHN1YmRpci0+bmV4dCA9IHBhcmVudC0+c3ViZGlyczsKICAgIHBhcmVudC0+c3ViZGlycyA9IHN1YmRpcjsKICAgIHJldHVybiAmZC0+aW5mbzsKfQoKc3RhdGljIHZvaWQKRmNHbG9iYWxDYWNoZURpckRlc3Ryb3kgKEZjR2xvYmFsQ2FjaGVEaXIgKmQpCnsKICAgIEZjR2xvYmFsQ2FjaGVGaWxlCSpmLCAqbmV4dDsKICAgIGludAkJCWg7CiAgICBGY0dsb2JhbENhY2hlU3ViZGlyCSpzLCAqbmV4dHM7CgogICAgZm9yIChoID0gMDsgaCA8IEZDX0dMT0JBTF9DQUNIRV9GSUxFX0hBU0hfU0laRTsgaCsrKQoJZm9yIChmID0gZC0+ZW50c1toXTsgZjsgZiA9IG5leHQpCgl7CgkgICAgbmV4dCA9IGYtPm5leHQ7CgkgICAgRmNNZW1GcmVlIChGQ19NRU1fQ0FDSEUsIHNpemVvZiAoRmNHbG9iYWxDYWNoZUZpbGUpICsKCQkgICAgICAgc3RybGVuICgoY2hhciAqKSBmLT5pbmZvLmZpbGUpICsgMSArCgkJICAgICAgIHN0cmxlbiAoKGNoYXIgKikgZi0+bmFtZSkgKyAxKTsKCSAgICBmcmVlIChmKTsKCX0KICAgIGZvciAocyA9IGQtPnN1YmRpcnM7IHM7IHMgPSBuZXh0cykKICAgIHsKCW5leHRzID0gcy0+bmV4dDsKCUZjTWVtRnJlZSAoRkNfTUVNX0NBQ0hFLCBzaXplb2YgKEZjR2xvYmFsQ2FjaGVTdWJkaXIpKTsKCWZyZWUgKHMpOwogICAgfQogICAgRmNNZW1GcmVlIChGQ19NRU1fQ0FDSEUsIHNpemVvZiAoRmNHbG9iYWxDYWNoZURpcikgKyBkLT5sZW4gKyAxKTsKICAgIGZyZWUgKGQpOwp9CgovKgogKiBJZiB0aGUgcGFyZW50IGlzIGluIHRoZSBnbG9iYWwgY2FjaGUgYW5kIHJlZmVyZW5jZWQsIGFkZAogKiBhbiBlbnRyeSBmb3IgJ2RpcicgdG8gdGhlIGdsb2JhbCBjYWNoZS4gIFRoaXMgaXMgdXNlZAogKiBmb3IgZGlyZWN0b3JpZXMgd2l0aCBmb250cy5jYWNoZSBmaWxlcwogKi8KCnZvaWQKRmNHbG9iYWxDYWNoZVJlZmVyZW5jZVN1YmRpciAoRmNHbG9iYWxDYWNoZSAqY2FjaGUsCgkJCSAgICAgIGNvbnN0IEZjQ2hhcjggKmRpcikKewogICAgRmNHbG9iYWxDYWNoZUluZm8JKmluZm87CiAgICBpbmZvID0gRmNHbG9iYWxDYWNoZURpckFkZCAoY2FjaGUsIGRpciwgMCwgRmNGYWxzZSwgRmNGYWxzZSk7CiAgICBpZiAoaW5mbyAmJiAhaW5mby0+cmVmZXJlbmNlZCkKICAgIHsKCWluZm8tPnJlZmVyZW5jZWQgPSBGY1RydWU7CgljYWNoZS0+cmVmZXJlbmNlZCsrOwogICAgfQp9CgovKgogKiBDaGVjayB0byBzZWUgaWYgdGhlIGdsb2JhbCBjYWNoZSBjb250YWlucyB2YWxpZCBkYXRhIGZvciAnZGlyJy4KICogSWYgc28sIHNjYW4gdGhlIGdsb2JhbCBjYWNoZSBmb3IgZmlsZXMgYW5kIGRpcmVjdG9yaWVzIGluICdkaXInLgogKiBlbHNlLCByZXR1cm4gRmFsc2UuCiAqLwpGY0Jvb2wKRmNHbG9iYWxDYWNoZVNjYW5EaXIgKEZjRm9udFNldAkJKnNldCwKCQkgICAgICBGY1N0clNldAkJKmRpcnMsCgkJICAgICAgRmNHbG9iYWxDYWNoZQkqY2FjaGUsCgkJICAgICAgY29uc3QgRmNDaGFyOAkqZGlyKQp7CiAgICBGY0dsb2JhbENhY2hlRGlyCSpkID0gRmNHbG9iYWxDYWNoZURpckdldCAoY2FjaGUsIGRpciwKCQkJCQkJICBzdHJsZW4gKChjb25zdCBjaGFyICopIGRpciksCgkJCQkJCSAgRmNGYWxzZSk7CiAgICBGY0dsb2JhbENhY2hlRmlsZQkqZjsKICAgIGludAkJCWg7CiAgICBpbnQJCQlkaXJfbGVuOwogICAgRmNHbG9iYWxDYWNoZVN1YmRpcgkqc3ViZGlyOwogICAgRmNCb29sCQlhbnlfaW5fY2FjaGUgPSBGY0ZhbHNlOwoKICAgIGlmIChGY0RlYnVnKCkgJiBGQ19EQkdfQ0FDSEUpCglwcmludGYgKCJGY0dsb2JhbENhY2hlU2NhbkRpciAlc1xuIiwgZGlyKTsKICAgIAogICAgaWYgKCFkKQogICAgewoJaWYgKEZjRGVidWcgKCkgJiBGQ19EQkdfQ0FDSEUpCgkgICAgcHJpbnRmICgiXHRObyBkaXIgY2FjaGUgZW50cnlcbiIpOwoJcmV0dXJuIEZjRmFsc2U7CiAgICB9CgogICAgLyoKICAgICAqIFNlZSBpZiB0aGUgdGltZXN0YW1wIHJlY29yZGVkIGluIHRoZSBnbG9iYWwgY2FjaGUKICAgICAqIG1hdGNoZXMgdGhlIGRpcmVjdG9yeSB0aW1lLCBpZiBub3QsIHJldHVybiBGYWxzZQogICAgICovCiAgICBpZiAoIUZjR2xvYmFsQ2FjaGVDaGVja1RpbWUgKGQtPmluZm8uZmlsZSwgJmQtPmluZm8pKQogICAgewoJaWYgKEZjRGVidWcgKCkgJiBGQ19EQkdfQ0FDSEUpCgkgICAgcHJpbnRmICgiXHRkaXIgY2FjaGUgZW50cnkgdGltZSBtaXNtYXRjaFxuIik7CglyZXR1cm4gRmNGYWxzZTsKICAgIH0KCiAgICAvKgogICAgICogQWRkIGZpbGVzIGZyb20gJ2RpcicgdG8gdGhlIGZvbnRzZXQKICAgICAqLwogICAgZGlyX2xlbiA9IHN0cmxlbiAoKGNvbnN0IGNoYXIgKikgZGlyKTsKICAgIGZvciAoaCA9IDA7IGggPCBGQ19HTE9CQUxfQ0FDSEVfRklMRV9IQVNIX1NJWkU7IGgrKykKCWZvciAoZiA9IGQtPmVudHNbaF07IGY7IGYgPSBmLT5uZXh0KQoJewoJICAgIGlmIChGY0RlYnVnKCkgJiBGQ19EQkdfQ0FDSEVWKQoJCXByaW50ZiAoIkZjR2xvYmFsQ2FjaGVTY2FuRGlyIGFkZCBmaWxlICVzXG4iLCBmLT5pbmZvLmZpbGUpOwoJICAgIGFueV9pbl9jYWNoZSA9IEZjVHJ1ZTsKCSAgICBpZiAoIUZjQ2FjaGVGb250U2V0QWRkIChzZXQsIGRpcnMsIGRpciwgZGlyX2xlbiwKCQkJCSAgICBmLT5pbmZvLmZpbGUsIGYtPm5hbWUpKQoJICAgIHsKCQljYWNoZS0+YnJva2VuID0gRmNUcnVlOwoJCXJldHVybiBGY0ZhbHNlOwoJICAgIH0KCSAgICBGY0dsb2JhbENhY2hlUmVmZXJlbmNlZCAoY2FjaGUsICZmLT5pbmZvKTsKCX0KICAgIC8qCiAgICAgKiBBZGQgZGlyZWN0b3JpZXMgaW4gJ2RpcicgdG8gJ2RpcnMnCiAgICAgKi8KICAgIGZvciAoc3ViZGlyID0gZC0+c3ViZGlyczsgc3ViZGlyOyBzdWJkaXIgPSBzdWJkaXItPm5leHQpCiAgICB7CglGY0ZpbGVQYXRoSW5mbwlpbmZvID0gRmNGaWxlUGF0aEluZm9HZXQgKHN1YmRpci0+ZW50LT5pbmZvLmZpbGUpOwoJCiAgICAgICAgYW55X2luX2NhY2hlID0gRmNUcnVlOwoJaWYgKCFGY0NhY2hlRm9udFNldEFkZCAoc2V0LCBkaXJzLCBkaXIsIGRpcl9sZW4sCgkJCQlpbmZvLmJhc2UsIEZDX0ZPTlRfRklMRV9ESVIpKQoJewoJICAgIGNhY2hlLT5icm9rZW4gPSBGY1RydWU7CgkgICAgcmV0dXJuIEZjRmFsc2U7Cgl9CglGY0dsb2JhbENhY2hlUmVmZXJlbmNlZCAoY2FjaGUsICZzdWJkaXItPmVudC0+aW5mbyk7CiAgICB9CiAgICAKICAgIEZjR2xvYmFsQ2FjaGVSZWZlcmVuY2VkIChjYWNoZSwgJmQtPmluZm8pOwoKICAgIC8qCiAgICAgKiBUbyByZWNvdmVyIGZyb20gYSBidWcgaW4gcHJldmlvdXMgdmVyc2lvbnMgb2YgZm9udGNvbmZpZywKICAgICAqIHJldHVybiBGY0ZhbHNlIGlmIG5vIGVudHJpZXMgaW4gdGhlIGNhY2hlIHdlcmUgZm91bmQKICAgICAqIGZvciB0aGlzIGRpcmVjdG9yeS4gIFRoaXMgd2lsbCBjYXVzZSBhbnkgZW1wdHkgZGlyZWN0b3JpZXMKICAgICAqIHRvIGdldCByZXNjYW5uZWQgZXZlcnkgdGltZSBmb250Y29uZmlnIGlzIGluaXRpYWxpemVkLiAgVGhpcwogICAgICogbWlnaHQgZ2V0IHJlbW92ZWQgYXQgc29tZSBwb2ludCB3aGVuIHRoZSBvbGRlciBjYWNoZSBmaWxlcyBhcmUKICAgICAqIHByZXN1bWFibHkgZml4ZWQuCiAgICAgKi8KICAgIHJldHVybiBhbnlfaW5fY2FjaGU7Cn0KCi8qCiAqIExvY2F0ZSB0aGUgY2FjaGUgZW50cnkgZm9yIGEgcGFydGljdWxhciBmaWxlCiAqLwpGY0dsb2JhbENhY2hlRmlsZSAqCkZjR2xvYmFsQ2FjaGVGaWxlR2V0IChGY0dsb2JhbENhY2hlICpjYWNoZSwKCQkgICAgICBjb25zdCBGY0NoYXI4ICpmaWxlLAoJCSAgICAgIGludAkgICAgaWQsCgkJICAgICAgaW50CSAgICAqY291bnQpCnsKICAgIEZjRmlsZVBhdGhJbmZvCWkgPSBGY0ZpbGVQYXRoSW5mb0dldCAoZmlsZSk7CiAgICBGY0dsb2JhbENhY2hlRGlyCSpkID0gRmNHbG9iYWxDYWNoZURpckdldCAoY2FjaGUsIGkuZGlyLCAKCQkJCQkJICBpLmRpcl9sZW4sIEZjRmFsc2UpOwogICAgRmNHbG9iYWxDYWNoZUZpbGUJKmYsICptYXRjaCA9IDA7CiAgICBpbnQJCQltYXggPSAtMTsKCiAgICBpZiAoIWQpCglyZXR1cm4gMDsKICAgIGZvciAoZiA9IGQtPmVudHNbaS5iYXNlX2hhc2ggJSBGQ19HTE9CQUxfQ0FDSEVfRklMRV9IQVNIX1NJWkVdOyBmOyBmID0gZi0+bmV4dCkKICAgIHsKCWlmIChmLT5pbmZvLmhhc2ggPT0gaS5iYXNlX2hhc2ggJiYKCSAgICAhc3RyY21wICgoY29uc3QgY2hhciAqKSBmLT5pbmZvLmZpbGUsIChjb25zdCBjaGFyICopIGkuYmFzZSkpCgl7CgkgICAgaWYgKGYtPmlkID09IGlkKQoJCW1hdGNoID0gZjsKCSAgICBpZiAoZi0+aWQgPiBtYXgpCgkJbWF4ID0gZi0+aWQ7Cgl9CiAgICB9CiAgICBpZiAoY291bnQpCgkqY291bnQgPSBtYXggKyAxOwogICAgcmV0dXJuIG1hdGNoOwp9CiAgICAKLyoKICogQWRkIGEgZmlsZSBlbnRyeSB0byB0aGUgY2FjaGUKICovCnN0YXRpYyBGY0dsb2JhbENhY2hlSW5mbyAqCkZjR2xvYmFsQ2FjaGVGaWxlQWRkIChGY0dsb2JhbENhY2hlICpjYWNoZSwKCQkgICAgICBjb25zdCBGY0NoYXI4ICpwYXRoLAoJCSAgICAgIGludAkgICAgaWQsCgkJICAgICAgdGltZV90CSAgICB0aW1lLAoJCSAgICAgIGNvbnN0IEZjQ2hhcjggKm5hbWUsCgkJICAgICAgRmNCb29sCSAgICByZXBsYWNlKQp7CiAgICBGY0ZpbGVQYXRoSW5mbwlpID0gRmNGaWxlUGF0aEluZm9HZXQgKHBhdGgpOwogICAgRmNHbG9iYWxDYWNoZURpcgkqZCA9IEZjR2xvYmFsQ2FjaGVEaXJHZXQgKGNhY2hlLCBpLmRpciwgCgkJCQkJCSAgaS5kaXJfbGVuLCBGY1RydWUpOwogICAgRmNHbG9iYWxDYWNoZUZpbGUJKmYsICoqcHJldjsKICAgIGludAkJCXNpemU7CgogICAgaWYgKCFkKQoJcmV0dXJuIDA7CiAgICBmb3IgKHByZXYgPSAmZC0+ZW50c1tpLmJhc2VfaGFzaCAlIEZDX0dMT0JBTF9DQUNIRV9GSUxFX0hBU0hfU0laRV07CgkgKGYgPSAqcHJldik7CgkgcHJldiA9ICYoKnByZXYpLT5uZXh0KQogICAgewoJaWYgKGYtPmluZm8uaGFzaCA9PSBpLmJhc2VfaGFzaCAmJiAKCSAgICBmLT5pZCA9PSBpZCAmJgoJICAgICFzdHJjbXAgKChjb25zdCBjaGFyICopIGYtPmluZm8uZmlsZSwgKGNvbnN0IGNoYXIgKikgaS5iYXNlKSkKCXsKCSAgICBicmVhazsKCX0KICAgIH0KICAgIGlmICgqcHJldikKICAgIHsKCWlmICghcmVwbGFjZSkKCSAgICByZXR1cm4gMDsKCglmID0gKnByZXY7CglpZiAoZi0+aW5mby5yZWZlcmVuY2VkKQoJICAgIGNhY2hlLT5yZWZlcmVuY2VkLS07CgkqcHJldiA9IGYtPm5leHQ7CglGY01lbUZyZWUgKEZDX01FTV9DQUNIRSwgc2l6ZW9mIChGY0dsb2JhbENhY2hlRmlsZSkgKwoJCSAgIHN0cmxlbiAoKGNoYXIgKikgZi0+aW5mby5maWxlKSArIDEgKwoJCSAgIHN0cmxlbiAoKGNoYXIgKikgZi0+bmFtZSkgKyAxKTsKCWZyZWUgKGYpOwogICAgfQogICAgc2l6ZSA9IChzaXplb2YgKEZjR2xvYmFsQ2FjaGVGaWxlKSArCgkgICAgc3RybGVuICgoY2hhciAqKSBpLmJhc2UpICsgMSArCgkgICAgc3RybGVuICgoY2hhciAqKSBuYW1lKSArIDEpOwogICAgZiA9IG1hbGxvYyAoc2l6ZSk7CiAgICBpZiAoIWYpCglyZXR1cm4gMDsKICAgIEZjTWVtQWxsb2MgKEZDX01FTV9DQUNIRSwgc2l6ZSk7CiAgICBmLT5uZXh0ID0gKnByZXY7CiAgICAqcHJldiA9IGY7CiAgICBmLT5pbmZvLmhhc2ggPSBpLmJhc2VfaGFzaDsKICAgIGYtPmluZm8uZmlsZSA9IChGY0NoYXI4ICopIChmICsgMSk7CiAgICBmLT5pbmZvLnRpbWUgPSB0aW1lOwogICAgZi0+aW5mby5yZWZlcmVuY2VkID0gRmNGYWxzZTsKICAgIGYtPmlkID0gaWQ7CiAgICBmLT5uYW1lID0gZi0+aW5mby5maWxlICsgc3RybGVuICgoY2hhciAqKSBpLmJhc2UpICsgMTsKICAgIHN0cmNweSAoKGNoYXIgKikgZi0+aW5mby5maWxlLCAoY29uc3QgY2hhciAqKSBpLmJhc2UpOwogICAgc3RyY3B5ICgoY2hhciAqKSBmLT5uYW1lLCAoY29uc3QgY2hhciAqKSBuYW1lKTsKICAgIHJldHVybiAmZi0+aW5mbzsKfQoKRmNHbG9iYWxDYWNoZSAqCkZjR2xvYmFsQ2FjaGVDcmVhdGUgKHZvaWQpCnsKICAgIEZjR2xvYmFsQ2FjaGUgICAqY2FjaGU7CiAgICBpbnQJCSAgICBoOwoKICAgIGNhY2hlID0gbWFsbG9jIChzaXplb2YgKEZjR2xvYmFsQ2FjaGUpKTsKICAgIGlmICghY2FjaGUpCglyZXR1cm4gMDsKICAgIEZjTWVtQWxsb2MgKEZDX01FTV9DQUNIRSwgc2l6ZW9mIChGY0dsb2JhbENhY2hlKSk7CiAgICBmb3IgKGggPSAwOyBoIDwgRkNfR0xPQkFMX0NBQ0hFX0RJUl9IQVNIX1NJWkU7IGgrKykKCWNhY2hlLT5lbnRzW2hdID0gMDsKICAgIGNhY2hlLT5lbnRyaWVzID0gMDsKICAgIGNhY2hlLT5yZWZlcmVuY2VkID0gMDsKICAgIGNhY2hlLT51cGRhdGVkID0gRmNGYWxzZTsKICAgIGNhY2hlLT5icm9rZW4gPSBGY0ZhbHNlOwogICAgcmV0dXJuIGNhY2hlOwp9Cgp2b2lkCkZjR2xvYmFsQ2FjaGVEZXN0cm95IChGY0dsb2JhbENhY2hlICpjYWNoZSkKewogICAgRmNHbG9iYWxDYWNoZURpcgkqZCwgKm5leHQ7CiAgICBpbnQJCQloOwoKICAgIGZvciAoaCA9IDA7IGggPCBGQ19HTE9CQUxfQ0FDSEVfRElSX0hBU0hfU0laRTsgaCsrKQogICAgewoJZm9yIChkID0gY2FjaGUtPmVudHNbaF07IGQ7IGQgPSBuZXh0KQoJewoJICAgIG5leHQgPSBkLT5uZXh0OwoJICAgIEZjR2xvYmFsQ2FjaGVEaXJEZXN0cm95IChkKTsKCX0KICAgIH0KICAgIEZjTWVtRnJlZSAoRkNfTUVNX0NBQ0hFLCBzaXplb2YgKEZjR2xvYmFsQ2FjaGUpKTsKICAgIGZyZWUgKGNhY2hlKTsKfQoKLyoKICogQ2FjaGUgZmlsZSBzeW50YXggaXMgcXVpdGUgc2ltcGxlOgogKgogKiAiZmlsZV9uYW1lIiBpZCB0aW1lICJmb250X25hbWUiIFxuCiAqLwogCnZvaWQKRmNHbG9iYWxDYWNoZUxvYWQgKEZjR2xvYmFsQ2FjaGUgICAgKmNhY2hlLAoJCSAgIGNvbnN0IEZjQ2hhcjggICAgKmNhY2hlX2ZpbGUpCnsKICAgIEZJTEUJCSpmOwogICAgRmNDaGFyOAkJZmlsZV9idWZbODE5Ml0sICpmaWxlOwogICAgaW50CQkJaWQ7CiAgICB0aW1lX3QJCXRpbWU7CiAgICBGY0NoYXI4CQluYW1lX2J1Zls4MTkyXSwgKm5hbWU7CiAgICBGY0dsb2JhbENhY2hlSW5mbwkqaW5mbzsKCiAgICBmID0gZm9wZW4gKChjaGFyICopIGNhY2hlX2ZpbGUsICJyIik7CiAgICBpZiAoIWYpCglyZXR1cm47CgogICAgY2FjaGUtPnVwZGF0ZWQgPSBGY0ZhbHNlOwogICAgZmlsZSA9IDA7CiAgICBuYW1lID0gMDsKICAgIHdoaWxlICgoZmlsZSA9IEZjQ2FjaGVSZWFkU3RyaW5nIChmLCBmaWxlX2J1Ziwgc2l6ZW9mIChmaWxlX2J1ZikpKSAmJgoJICAgRmNDYWNoZVJlYWRJbnQgKGYsICZpZCkgJiYKCSAgIEZjQ2FjaGVSZWFkVGltZSAoZiwgJnRpbWUpICYmCgkgICAobmFtZSA9IEZjQ2FjaGVSZWFkU3RyaW5nIChmLCBuYW1lX2J1Ziwgc2l6ZW9mIChuYW1lX2J1ZikpKSkKICAgIHsKCWlmIChGY0RlYnVnICgpICYgRkNfREJHX0NBQ0hFVikKCSAgICBwcmludGYgKCJGY0dsb2JhbENhY2hlTG9hZCBcIiVzXCIgXCIlMjAuMjBzXCJcbiIsIGZpbGUsIG5hbWUpOwoJaWYgKCFGY1N0ckNtcCAobmFtZSwgRkNfRk9OVF9GSUxFX0RJUikpCgkgICAgaW5mbyA9IEZjR2xvYmFsQ2FjaGVEaXJBZGQgKGNhY2hlLCBmaWxlLCB0aW1lLCBGY0ZhbHNlLCBGY1RydWUpOwoJZWxzZQoJICAgIGluZm8gPSBGY0dsb2JhbENhY2hlRmlsZUFkZCAoY2FjaGUsIGZpbGUsIGlkLCB0aW1lLCBuYW1lLCBGY0ZhbHNlKTsKCWlmICghaW5mbykKCSAgICBjYWNoZS0+YnJva2VuID0gRmNUcnVlOwoJZWxzZQoJICAgIGNhY2hlLT5lbnRyaWVzKys7CglpZiAoRmNEZWJ1ZyAoKSAmIEZDX0RCR19DQUNIRV9SRUYpCgkgICAgcHJpbnRmICgiRmNHbG9iYWxDYWNoZUxvYWQgZW50cnkgJWQgJXNcbiIsCgkJICAgIGNhY2hlLT5lbnRyaWVzLCBmaWxlKTsKCWlmIChmaWxlICE9IGZpbGVfYnVmKQoJICAgIGZyZWUgKGZpbGUpOwoJaWYgKG5hbWUgIT0gbmFtZV9idWYpCgkgICAgZnJlZSAobmFtZSk7CglmaWxlID0gMDsKCW5hbWUgPSAwOwogICAgfQogICAgaWYgKGZpbGUgJiYgZmlsZSAhPSBmaWxlX2J1ZikKCWZyZWUgKGZpbGUpOwogICAgaWYgKG5hbWUgJiYgbmFtZSAhPSBuYW1lX2J1ZikKCWZyZWUgKG5hbWUpOwogICAgZmNsb3NlIChmKTsKfQoKRmNCb29sCkZjR2xvYmFsQ2FjaGVVcGRhdGUgKEZjR2xvYmFsQ2FjaGUgICpjYWNoZSwKCQkgICAgIGNvbnN0IEZjQ2hhcjggICpmaWxlLAoJCSAgICAgaW50CSAgICBpZCwKCQkgICAgIGNvbnN0IEZjQ2hhcjggICpuYW1lKQp7CiAgICBjb25zdCBGY0NoYXI4CSptYXRjaDsKICAgIHN0cnVjdCBzdGF0CQlzdGF0YjsKICAgIEZjR2xvYmFsQ2FjaGVJbmZvCSppbmZvOwoKICAgIG1hdGNoID0gZmlsZTsKCiAgICBpZiAoc3RhdCAoKGNoYXIgKikgZmlsZSwgJnN0YXRiKSA8IDApCglyZXR1cm4gRmNGYWxzZTsKICAgIGlmIChTX0lTRElSIChzdGF0Yi5zdF9tb2RlKSkKCWluZm8gPSBGY0dsb2JhbENhY2hlRGlyQWRkIChjYWNoZSwgZmlsZSwgc3RhdGIuc3RfbXRpbWUsIAoJCQkJICAgIEZjVHJ1ZSwgRmNUcnVlKTsKICAgIGVsc2UKCWluZm8gPSBGY0dsb2JhbENhY2hlRmlsZUFkZCAoY2FjaGUsIGZpbGUsIGlkLCBzdGF0Yi5zdF9tdGltZSwgCgkJCQkgICAgbmFtZSwgRmNUcnVlKTsKICAgIGlmIChpbmZvKQogICAgewoJRmNHbG9iYWxDYWNoZVJlZmVyZW5jZWQgKGNhY2hlLCBpbmZvKTsKCWNhY2hlLT51cGRhdGVkID0gRmNUcnVlOwogICAgfQogICAgZWxzZQoJY2FjaGUtPmJyb2tlbiA9IEZjVHJ1ZTsKICAgIHJldHVybiBpbmZvICE9IDA7Cn0KCkZjQm9vbApGY0dsb2JhbENhY2hlU2F2ZSAoRmNHbG9iYWxDYWNoZSAgICAqY2FjaGUsCgkJICAgY29uc3QgRmNDaGFyOCAgICAqY2FjaGVfZmlsZSkKewogICAgRklMRQkJKmY7CiAgICBpbnQJCQlkaXJfaGFzaCwgZmlsZV9oYXNoOwogICAgRmNHbG9iYWxDYWNoZURpcgkqZGlyOwogICAgRmNHbG9iYWxDYWNoZUZpbGUJKmZpbGU7CiAgICBGY0F0b21pYwkJKmF0b21pYzsKCiAgICBpZiAoIWNhY2hlLT51cGRhdGVkICYmIGNhY2hlLT5yZWZlcmVuY2VkID09IGNhY2hlLT5lbnRyaWVzKQoJcmV0dXJuIEZjVHJ1ZTsKICAgIAogICAgaWYgKGNhY2hlLT5icm9rZW4pCglyZXR1cm4gRmNGYWxzZTsKCiNpZiBkZWZpbmVkIChIQVZFX0dFVFVJRCkgJiYgZGVmaW5lZCAoSEFWRV9HRVRFVUlEKQogICAgLyogU2V0LVVJRCBwcm9ncmFtcyBjYW4ndCBzYWZlbHkgdXBkYXRlIHRoZSBjYWNoZSAqLwogICAgaWYgKGdldHVpZCAoKSAhPSBnZXRldWlkICgpKQoJcmV0dXJuIEZjRmFsc2U7CiNlbmRpZgogICAgCiAgICBhdG9taWMgPSBGY0F0b21pY0NyZWF0ZSAoY2FjaGVfZmlsZSk7CiAgICBpZiAoIWF0b21pYykKCWdvdG8gYmFpbDA7CiAgICBpZiAoIUZjQXRvbWljTG9jayAoYXRvbWljKSkKCWdvdG8gYmFpbDE7CiAgICBmID0gZm9wZW4gKChjaGFyICopIEZjQXRvbWljTmV3RmlsZShhdG9taWMpLCAidyIpOwogICAgaWYgKCFmKQoJZ290byBiYWlsMjsKCiAgICBmb3IgKGRpcl9oYXNoID0gMDsgZGlyX2hhc2ggPCBGQ19HTE9CQUxfQ0FDSEVfRElSX0hBU0hfU0laRTsgZGlyX2hhc2grKykKICAgIHsKCWZvciAoZGlyID0gY2FjaGUtPmVudHNbZGlyX2hhc2hdOyBkaXI7IGRpciA9IGRpci0+bmV4dCkKCXsKCSAgICBpZiAoIWRpci0+aW5mby5yZWZlcmVuY2VkKQoJCWNvbnRpbnVlOwoJICAgIGlmICghRmNDYWNoZVdyaXRlU3RyaW5nIChmLCBkaXItPmluZm8uZmlsZSkpCgkJZ290byBiYWlsNDsKCSAgICBpZiAoUFVUQyAoJyAnLCBmKSA9PSBFT0YpCgkJZ290byBiYWlsNDsKCSAgICBpZiAoIUZjQ2FjaGVXcml0ZUludCAoZiwgMCkpCgkJZ290byBiYWlsNDsKCSAgICBpZiAoUFVUQyAoJyAnLCBmKSA9PSBFT0YpCgkJZ290byBiYWlsNDsKCSAgICBpZiAoIUZjQ2FjaGVXcml0ZVRpbWUgKGYsIGRpci0+aW5mby50aW1lKSkKCQlnb3RvIGJhaWw0OwoJICAgIGlmIChQVVRDICgnICcsIGYpID09IEVPRikKCQlnb3RvIGJhaWw0OwoJICAgIGlmICghRmNDYWNoZVdyaXRlU3RyaW5nIChmLCAoRmNDaGFyOCAqKSBGQ19GT05UX0ZJTEVfRElSKSkKCQlnb3RvIGJhaWw0OwoJICAgIGlmIChQVVRDICgnXG4nLCBmKSA9PSBFT0YpCgkJZ290byBiYWlsNDsKCSAgICAKCSAgICBmb3IgKGZpbGVfaGFzaCA9IDA7IGZpbGVfaGFzaCA8IEZDX0dMT0JBTF9DQUNIRV9GSUxFX0hBU0hfU0laRTsgZmlsZV9oYXNoKyspCgkgICAgewoJCWZvciAoZmlsZSA9IGRpci0+ZW50c1tmaWxlX2hhc2hdOyBmaWxlOyBmaWxlID0gZmlsZS0+bmV4dCkKCQl7CgkJICAgIGlmICghZmlsZS0+aW5mby5yZWZlcmVuY2VkKQoJCQljb250aW51ZTsKCQkgICAgaWYgKCFGY0NhY2hlV3JpdGVQYXRoIChmLCBkaXItPmluZm8uZmlsZSwgZmlsZS0+aW5mby5maWxlKSkKCQkJZ290byBiYWlsNDsKCQkgICAgaWYgKFBVVEMgKCcgJywgZikgPT0gRU9GKQoJCQlnb3RvIGJhaWw0OwoJCSAgICBpZiAoIUZjQ2FjaGVXcml0ZUludCAoZiwgZmlsZS0+aWQgPCAwID8gMCA6IGZpbGUtPmlkKSkKCQkJZ290byBiYWlsNDsKCQkgICAgaWYgKFBVVEMgKCcgJywgZikgPT0gRU9GKQoJCQlnb3RvIGJhaWw0OwoJCSAgICBpZiAoIUZjQ2FjaGVXcml0ZVRpbWUgKGYsIGZpbGUtPmluZm8udGltZSkpCgkJCWdvdG8gYmFpbDQ7CgkJICAgIGlmIChQVVRDICgnICcsIGYpID09IEVPRikKCQkJZ290byBiYWlsNDsKCQkgICAgaWYgKCFGY0NhY2hlV3JpdGVTdHJpbmcgKGYsIGZpbGUtPm5hbWUpKQoJCQlnb3RvIGJhaWw0OwoJCSAgICBpZiAoUFVUQyAoJ1xuJywgZikgPT0gRU9GKQoJCQlnb3RvIGJhaWw0OwoJCX0KCSAgICB9Cgl9CiAgICB9CgogICAgaWYgKGZjbG9zZSAoZikgPT0gRU9GKQoJZ290byBiYWlsMzsKICAgIAogICAgaWYgKCFGY0F0b21pY1JlcGxhY2VPcmlnIChhdG9taWMpKQoJZ290byBiYWlsMzsKICAgIAogICAgRmNBdG9taWNVbmxvY2sgKGF0b21pYyk7CiAgICBGY0F0b21pY0Rlc3Ryb3kgKGF0b21pYyk7CgogICAgY2FjaGUtPnVwZGF0ZWQgPSBGY0ZhbHNlOwogICAgcmV0dXJuIEZjVHJ1ZTsKCmJhaWw0OgogICAgZmNsb3NlIChmKTsKYmFpbDM6CiAgICBGY0F0b21pY0RlbGV0ZU5ldyAoYXRvbWljKTsKYmFpbDI6CiAgICBGY0F0b21pY1VubG9jayAoYXRvbWljKTsKYmFpbDE6CiAgICBGY0F0b21pY0Rlc3Ryb3kgKGF0b21pYyk7CmJhaWwwOgogICAgcmV0dXJuIEZjRmFsc2U7Cn0KCkZjQm9vbApGY0RpckNhY2hlVmFsaWQgKGNvbnN0IEZjQ2hhcjggKmRpcikKewogICAgRmNDaGFyOAkqY2FjaGVfZmlsZSA9IEZjU3RyUGx1cyAoZGlyLCAoRmNDaGFyOCAqKSAiLyIgRkNfRElSX0NBQ0hFX0ZJTEUpOwogICAgc3RydWN0IHN0YXQJZmlsZV9zdGF0LCBkaXJfc3RhdDsKCiAgICBpZiAoc3RhdCAoKGNoYXIgKikgZGlyLCAmZGlyX3N0YXQpIDwgMCkKICAgIHsKCUZjU3RyRnJlZSAoY2FjaGVfZmlsZSk7CglyZXR1cm4gRmNGYWxzZTsKICAgIH0KICAgIGlmIChzdGF0ICgoY2hhciAqKSBjYWNoZV9maWxlLCAmZmlsZV9zdGF0KSA8IDApCiAgICB7CglGY1N0ckZyZWUgKGNhY2hlX2ZpbGUpOwoJcmV0dXJuIEZjRmFsc2U7CiAgICB9CiAgICBGY1N0ckZyZWUgKGNhY2hlX2ZpbGUpOwogICAgLyoKICAgICAqIElmIHRoZSBkaXJlY3RvcnkgaGFzIGJlZW4gbW9kaWZpZWQgbW9yZSByZWNlbnRseSB0aGFuCiAgICAgKiB0aGUgY2FjaGUgZmlsZSwgdGhlIGNhY2hlIGlzIG5vdCB2YWxpZAogICAgICovCiAgICBpZiAoZGlyX3N0YXQuc3RfbXRpbWUgLSBmaWxlX3N0YXQuc3RfbXRpbWUgPiAwKQoJcmV0dXJuIEZjRmFsc2U7CiAgICByZXR1cm4gRmNUcnVlOwp9CgpGY0Jvb2wKRmNEaXJDYWNoZVJlYWREaXIgKEZjRm9udFNldCAqc2V0LCBGY1N0clNldCAqZGlycywgY29uc3QgRmNDaGFyOCAqZGlyKQp7CiAgICBGY0NoYXI4CSAgICAqY2FjaGVfZmlsZSA9IEZjU3RyUGx1cyAoZGlyLCAoRmNDaGFyOCAqKSAiLyIgRkNfRElSX0NBQ0hFX0ZJTEUpOwogICAgRklMRQkgICAgKmY7CiAgICBGY0NoYXI4CSAgICAqYmFzZTsKICAgIGludAkJICAgIGlkOwogICAgaW50CQkgICAgZGlyX2xlbjsKICAgIEZjQ2hhcjgJICAgIGZpbGVfYnVmWzgxOTJdLCAqZmlsZTsKICAgIEZjQ2hhcjgJICAgIG5hbWVfYnVmWzgxOTJdLCAqbmFtZTsKICAgIEZjQm9vbAkgICAgcmV0ID0gRmNGYWxzZTsKCiAgICBpZiAoIWNhY2hlX2ZpbGUpCglnb3RvIGJhaWwwOwogICAgCiAgICBpZiAoRmNEZWJ1ZyAoKSAmIEZDX0RCR19DQUNIRSkKCXByaW50ZiAoIkZjRGlyQ2FjaGVSZWFkRGlyIGNhY2hlX2ZpbGUgXCIlc1wiXG4iLCBjYWNoZV9maWxlKTsKICAgIAogICAgZiA9IGZvcGVuICgoY2hhciAqKSBjYWNoZV9maWxlLCAiciIpOwogICAgaWYgKCFmKQogICAgewoJaWYgKEZjRGVidWcgKCkgJiBGQ19EQkdfQ0FDSEUpCgkgICAgcHJpbnRmICgiIG5vIGNhY2hlIGZpbGVcbiIpOwoJZ290byBiYWlsMTsKICAgIH0KCiAgICBpZiAoIUZjRGlyQ2FjaGVWYWxpZCAoZGlyKSkKICAgIHsKCWlmIChGY0RlYnVnICgpICYgRkNfREJHX0NBQ0hFKQoJICAgIHByaW50ZiAoIiBjYWNoZSBmaWxlIG9sZGVyIHRoYW4gZGlyZWN0b3J5XG4iKTsKCWdvdG8gYmFpbDI7CiAgICB9CiAgICAKICAgIGJhc2UgPSAoRmNDaGFyOCAqKSBzdHJyY2hyICgoY2hhciAqKSBjYWNoZV9maWxlLCAnLycpOwogICAgaWYgKCFiYXNlKQoJZ290byBiYWlsMjsKICAgIGJhc2UrKzsKICAgIGRpcl9sZW4gPSBiYXNlIC0gY2FjaGVfZmlsZTsKICAgIAogICAgZmlsZSA9IDA7CiAgICBuYW1lID0gMDsKICAgIHdoaWxlICgoZmlsZSA9IEZjQ2FjaGVSZWFkU3RyaW5nIChmLCBmaWxlX2J1Ziwgc2l6ZW9mIChmaWxlX2J1ZikpKSAmJgoJICAgRmNDYWNoZVJlYWRJbnQgKGYsICZpZCkgJiYKCSAgIChuYW1lID0gRmNDYWNoZVJlYWRTdHJpbmcgKGYsIG5hbWVfYnVmLCBzaXplb2YgKG5hbWVfYnVmKSkpKQogICAgewoJaWYgKCFGY0NhY2hlRm9udFNldEFkZCAoc2V0LCBkaXJzLCBjYWNoZV9maWxlLCBkaXJfbGVuLAoJCQkJZmlsZSwgbmFtZSkpCgkgICAgZ290byBiYWlsMzsKCWlmIChmaWxlICE9IGZpbGVfYnVmKQoJICAgIGZyZWUgKGZpbGUpOwoJaWYgKG5hbWUgIT0gbmFtZV9idWYpCgkgICAgZnJlZSAobmFtZSk7CglmaWxlID0gbmFtZSA9IDA7CiAgICB9CiAgICBpZiAoRmNEZWJ1ZyAoKSAmIEZDX0RCR19DQUNIRSkKCXByaW50ZiAoIiBjYWNoZSBsb2FkZWRcbiIpOwogICAgCiAgICByZXQgPSBGY1RydWU7CmJhaWwzOgogICAgaWYgKGZpbGUgJiYgZmlsZSAhPSBmaWxlX2J1ZikKCWZyZWUgKGZpbGUpOwogICAgaWYgKG5hbWUgJiYgbmFtZSAhPSBuYW1lX2J1ZikKCWZyZWUgKG5hbWUpOwpiYWlsMjoKICAgIGZjbG9zZSAoZik7CmJhaWwxOgogICAgRmNTdHJGcmVlIChjYWNoZV9maWxlKTsKYmFpbDA6CiAgICByZXR1cm4gcmV0Owp9CgovKgogKiByZXR1cm4gdGhlIHBhdGggZnJvbSB0aGUgZGlyZWN0b3J5IGNvbnRhaW5pbmcgJ2NhY2hlJyB0byAnZmlsZScKICovCgpzdGF0aWMgY29uc3QgRmNDaGFyOCAqCkZjRmlsZUJhc2VOYW1lIChjb25zdCBGY0NoYXI4ICpjYWNoZSwgY29uc3QgRmNDaGFyOCAqZmlsZSkKewogICAgY29uc3QgRmNDaGFyOCAgICpjYWNoZV9zbGFzaDsKCiAgICBjYWNoZV9zbGFzaCA9IEZjU3RyTGFzdFNsYXNoIChjYWNoZSk7CiAgICBpZiAoY2FjaGVfc2xhc2ggJiYgIXN0cm5jbXAgKChjb25zdCBjaGFyICopIGNhY2hlLCAoY29uc3QgY2hhciAqKSBmaWxlLAoJCQkJIChjYWNoZV9zbGFzaCArIDEpIC0gY2FjaGUpKQoJcmV0dXJuIGZpbGUgKyAoKGNhY2hlX3NsYXNoICsgMSkgLSBjYWNoZSk7CiAgICByZXR1cm4gZmlsZTsKfQoKRmNCb29sCkZjRGlyQ2FjaGVXcml0ZURpciAoRmNGb250U2V0ICpzZXQsIEZjU3RyU2V0ICpkaXJzLCBjb25zdCBGY0NoYXI4ICpkaXIpCnsKICAgIEZjQ2hhcjgJICAgICpjYWNoZV9maWxlID0gRmNTdHJQbHVzIChkaXIsIChGY0NoYXI4ICopICIvIiBGQ19ESVJfQ0FDSEVfRklMRSk7CiAgICBGY1BhdHRlcm4JICAgICpmb250OwogICAgRklMRQkgICAgKmY7CiAgICBGY0NoYXI4CSAgICAqbmFtZTsKICAgIGNvbnN0IEZjQ2hhcjggICAqZmlsZSwgKmJhc2U7CiAgICBpbnQJCSAgICBuOwogICAgaW50CQkgICAgaWQ7CiAgICBGY0Jvb2wJICAgIHJldDsKICAgIEZjU3RyTGlzdAkgICAgKmxpc3Q7CgogICAgaWYgKCFjYWNoZV9maWxlKQoJZ290byBiYWlsMDsKICAgIGlmIChGY0RlYnVnICgpICYgRkNfREJHX0NBQ0hFKQoJcHJpbnRmICgiRmNEaXJDYWNoZVdyaXRlRGlyIGNhY2hlX2ZpbGUgXCIlc1wiXG4iLCBjYWNoZV9maWxlKTsKICAgIAogICAgZiA9IGZvcGVuICgoY2hhciAqKSBjYWNoZV9maWxlLCAidyIpOwogICAgaWYgKCFmKQogICAgewoJaWYgKEZjRGVidWcgKCkgJiBGQ19EQkdfQ0FDSEUpCgkgICAgcHJpbnRmICgiIGNhbid0IGNyZWF0ZSBcIiVzXCJcbiIsIGNhY2hlX2ZpbGUpOwoJZ290byBiYWlsMTsKICAgIH0KICAgIAogICAgbGlzdCA9IEZjU3RyTGlzdENyZWF0ZSAoZGlycyk7CiAgICBpZiAoIWxpc3QpCglnb3RvIGJhaWwyOwogICAgCiAgICB3aGlsZSAoKGRpciA9IEZjU3RyTGlzdE5leHQgKGxpc3QpKSkKICAgIHsKCWJhc2UgPSBGY0ZpbGVCYXNlTmFtZSAoY2FjaGVfZmlsZSwgZGlyKTsKCWlmICghRmNDYWNoZVdyaXRlU3RyaW5nIChmLCBiYXNlKSkKCSAgICBnb3RvIGJhaWwzOwoJaWYgKFBVVEMgKCcgJywgZikgPT0gRU9GKQoJICAgIGdvdG8gYmFpbDM7CglpZiAoIUZjQ2FjaGVXcml0ZUludCAoZiwgMCkpCgkgICAgZ290byBiYWlsMzsKICAgICAgICBpZiAoUFVUQyAoJyAnLCBmKSA9PSBFT0YpCgkgICAgZ290byBiYWlsMzsKCWlmICghRmNDYWNoZVdyaXRlU3RyaW5nIChmLCBGQ19GT05UX0ZJTEVfRElSKSkKCSAgICBnb3RvIGJhaWwzOwoJaWYgKFBVVEMgKCdcbicsIGYpID09IEVPRikKCSAgICBnb3RvIGJhaWwzOwogICAgfQogICAgCiAgICBmb3IgKG4gPSAwOyBuIDwgc2V0LT5uZm9udDsgbisrKQogICAgewoJZm9udCA9IHNldC0+Zm9udHNbbl07CglpZiAoRmNQYXR0ZXJuR2V0U3RyaW5nIChmb250LCBGQ19GSUxFLCAwLCAoRmNDaGFyOCAqKikgJmZpbGUpICE9IEZjUmVzdWx0TWF0Y2gpCgkgICAgZ290byBiYWlsMzsKCWJhc2UgPSBGY0ZpbGVCYXNlTmFtZSAoY2FjaGVfZmlsZSwgZmlsZSk7CglpZiAoRmNQYXR0ZXJuR2V0SW50ZWdlciAoZm9udCwgRkNfSU5ERVgsIDAsICZpZCkgIT0gRmNSZXN1bHRNYXRjaCkKCSAgICBnb3RvIGJhaWwzOwoJaWYgKEZjRGVidWcgKCkgJiBGQ19EQkdfQ0FDSEVWKQoJICAgIHByaW50ZiAoIiB3cml0ZSBmaWxlIFwiJXNcIlxuIiwgYmFzZSk7CglpZiAoIUZjQ2FjaGVXcml0ZVN0cmluZyAoZiwgYmFzZSkpCgkgICAgZ290byBiYWlsMzsKCWlmIChQVVRDICgnICcsIGYpID09IEVPRikKCSAgICBnb3RvIGJhaWwzOwoJaWYgKCFGY0NhY2hlV3JpdGVJbnQgKGYsIGlkKSkKCSAgICBnb3RvIGJhaWwzOwogICAgICAgIGlmIChQVVRDICgnICcsIGYpID09IEVPRikKCSAgICBnb3RvIGJhaWwzOwoJbmFtZSA9IEZjTmFtZVVucGFyc2UgKGZvbnQpOwoJaWYgKCFuYW1lKQoJICAgIGdvdG8gYmFpbDM7CglyZXQgPSBGY0NhY2hlV3JpdGVTdHJpbmcgKGYsIG5hbWUpOwoJRmNTdHJGcmVlIChuYW1lKTsKCWlmICghcmV0KQoJICAgIGdvdG8gYmFpbDM7CglpZiAoUFVUQyAoJ1xuJywgZikgPT0gRU9GKQoJICAgIGdvdG8gYmFpbDM7CiAgICB9CiAgICAKICAgIEZjU3RyTGlzdERvbmUgKGxpc3QpOwoKICAgIGlmIChmY2xvc2UgKGYpID09IEVPRikKCWdvdG8gYmFpbDE7CiAgICAKICAgIEZjU3RyRnJlZSAoY2FjaGVfZmlsZSk7CgogICAgaWYgKEZjRGVidWcgKCkgJiBGQ19EQkdfQ0FDSEUpCglwcmludGYgKCIgY2FjaGUgd3JpdHRlblxuIik7CiAgICByZXR1cm4gRmNUcnVlOwogICAgCmJhaWwzOgogICAgRmNTdHJMaXN0RG9uZSAobGlzdCk7CmJhaWwyOgogICAgZmNsb3NlIChmKTsKYmFpbDE6CiAgICB1bmxpbmsgKChjaGFyICopIGNhY2hlX2ZpbGUpOwogICAgRmNTdHJGcmVlIChjYWNoZV9maWxlKTsKYmFpbDA6CiAgICByZXR1cm4gRmNGYWxzZTsKfQo=