Ly8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KLy8gTmFtZSBkZXMgT2JqZWN0czogICAgU2NobHVlc3NlbGJyZXR0Ci8vIExldHp0ZSBBZW5kZXJ1bmc6ICAgIDAyLjA2LjIwMDEKLy8gT3JpZ2luYWw6ICAgICAgICAgICAgU3dpZnQKLy8gTmV1ZSBWZXJzaW9uOiAgICAgICAgU2VsZXZlbgovLyDcYmVybm9tbWVuOiAgICAgICAgICAyMy4wMS4yMDA2Ci8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCi8qIENoYW5nZWxvZwogICAqIDIxLjA2LjIwMDcsIFplc3N0cmEKICAgICBpbSBpbmhlcml0IGFicy4gUGZhZCBkdXJjaCBMQURFTih4KSBlcnNldHp0LgogICAqIDAxLjA3LjIwMDcsIFplc3N0cmEKICAgICBHZXRPd25lcigpIGRlZmluaWVydC4KICAgKiAxMS4wNS4yMDE1LCBBcmF0aG9ybgogICAgIHdlaXRyYWV1bWlnIHVlYmVyYXJiZWl0ZXQgenVyIEJlaGVidW5nIHZvbiBGZWhsZnVua3Rpb25lbgoqLwojcHJhZ21hIHN0cm9uZ190eXBlcywgcnR0X2NoZWNrcwoKI2luY2x1ZGUgIi9kL3NlaGVyL2hhZXVzZXIvbW9lYmVsL3NjaHJhbmtsYWRlbi5oIgojaW5jbHVkZSA8YW5zaS5oPgppbmhlcml0ICBMQURFTigic3dpZnRfc3RkX2NvbnRhaW5lciIpOwoKI2RlZmluZSBWRVJTSU9OX09CSiAiMyIKLy8gWnVyIEluZGl6aWVydW5nIGRlcyBNYXBwaW5ncyA8aGFrZW4+CiNkZWZpbmUgSE9PS19PQiAgICAwCiNkZWZpbmUgSE9PS19MQUJFTCAxCgpwcml2YXRlIHZhcmFyZ3Mgc3RyaW5nIEtleURlc2NyaXB0aW9uKGludCBrZXludW0pOwpwcml2YXRlIGludCBJc1ZhbGlkS2V5KG9iamVjdCBvYik7CnByaXZhdGUgaW50IEdldE5leHRGcmVlU2xvdCgpOwpwcml2YXRlIG9iamVjdCBHZXRLZXlGb3JMYWJlbChzdHJpbmcgbGFiZWwpOwpwcml2YXRlIGludCBHZXRIb29rTnVtYmVyRm9yS2V5KG9iamVjdCBvYik7CnByaXZhdGUgdm9pZCBDb25zb2xpZGF0ZUludmVudG9yeSgpOwoKLy8gU3RydWt0dXI6IChbIGhha2VuX25yIDogb2JqZWt0OyBiZXNjaHJpZnR1bmcgXSkKcHJpdmF0ZSBtYXBwaW5nIGhha2VuPShbOjJdKTsKcHJpdmF0ZSBpbnQgaG9va2xpc3RfbG9uZyA9IDA7Cgpwcm90ZWN0ZWQgdm9pZCBjcmVhdGUoKSB7CiAgaWYgKCFjbG9uZXAoVE8pKSB7CiAgICBzZXRfbmV4dF9yZXNldCgtMSk7CiAgICByZXR1cm47CiAgfQogIDo6Y3JlYXRlKCk7CiAgCiAgZm9yZWFjaChpbnQgaTogMS4uMTYpIHsKICAgIG1fYWRkKGhha2VuLCBpKTsKICB9CgogIC8vIERFQlVHISBTb25zdCBmdW5rdGlvbmllcnQncyBhdXNzZXJoYWxiIHZvbiBTZWhlcmhhZXVzZXJuIG5pY2h0LgogIFNldFByb3AoInRlc3QiLDEpOwogIFNldFByb3AoUF9TSE9SVCwgIkVpbiBTY2hsdWVzc2VsYnJldHQiKTsKICBTZXQoUF9MT05HLCBmdW5jdGlvbiBzdHJpbmcgKCkgewogICAgc3RyaW5nIHRleHQgPSBCUygKICAgICAgIkVpbiBrbGVpbmVzIEJyZXR0IGF1cyBIb2x6LCBhbiBkZW0gaW4gMiBSZWloZW4gamUgOCBIYWtlbiBiZWZlc3RpZ3QgIgogICAgICAic2luZCwgYW4gZGllIG1hbiBpbnNnZXNhbXQgMTYgU2NobHVlc3NlbCBoYWVuZ2VuIGthbm4uIFVtIGRpZSAiCiAgICAgICJVZWJlcnNpY2h0IG5pY2h0IHp1IHZlcmxpZXJlbiwgYmVmaW5kZXQgc2ljaCB1ZWJlciBqZWRlbSBkZXIgSGFrZW4gIgogICAgICAiZWluIGtsZWluZXMgU2NoaWxkY2hlbiBhdXMgU2NoaWVmZXIsIGRhcyBzaWNoIGJlc2NocmlmdGVuIGxhZXNzdC4gIgogICAgICAiQXVmIGRpZXNlIFdlaXNlIGdlaHQgZGVyIFNpbm4gdW5kIFp3ZWNrIGRlcyBTY2hsdWVzc2VscywgZGVyIGFuICIKICAgICAgImRpZXNlbSBIYWtlbiBydWh0LCBuaWNodCB2ZXJsb3Jlbi4gUHJha3Rpc2NoZXJ3ZWlzZSBoYWVuZ3QgYW4gZWluZXIgIgogICAgICAiU2NobnVyIGVpbiBTdHVlY2sgS3JlaWRlIHZvbiBkZW0gQnJldHQgaGVyYWIsIG1pdCBkZW0gRHUgZGllICIKICAgICAgIlNjaGlsZGNoZW4gYmVzY2hyaWZ0ZW4ga2FubnN0LiIpOwogICAgdGV4dCArPSBLZXlEZXNjcmlwdGlvbigwKTsKICAgIHJldHVybiB0ZXh0OyAKICB9LCBGX1FVRVJZX01FVEhPRCk7CgogIEFkZElkKCh7InNjaGx1ZXNzZWxicmV0dCIsImJyZXR0In0pKTsKICBTZXRQcm9wKCJjbnRfdmVyc2lvbl9vYmoiLCBWRVJTSU9OX09CSik7CiAgU2V0UHJvcChQX0NOVF9TVEFUVVMsIDApOwogIFNldFByb3AoUF9OQU1FLCAiU2NobHVlc3NlbGJyZXR0Iik7CiAgU2V0UHJvcChQX0dFTkRFUiwgTkVVVEVSKTsKICBTZXRQcm9wKFBfV0VJR0hULCAxMDAwKTsgICAgICAgICAvLyBHZXdpY2h0IDEgS2cKICBTZXRQcm9wKFBfTUFYX1dFSUdIVCwgMTAwMDAwMCk7ICAvLyBFcyBwYXNzZW4gZnVlciAxMDAwIGtnIFNhY2hlbiByZWluLgogIFNldFByb3AoUF9XRUlHSFRfUEVSQ0VOVCwgMTAwKTsgIC8vIERhZnVlciBtYWNodCBlciBhdWNoIG5peCBsZWljaHRlciA6KQogIFNldFByb3AoUF9NQVhfT0JKRUNUUywgMTYpOwogIC8vIE1hbiBzb2xsIG5pY2h0cyB1ZWJlciBkZW4gbm9ybWFsZW4gTWVjaGFuaXNtdXMgcmVpbnN0ZWNrZW4gb2RlciAKICAvLyByYXVzbmVobWVuIGtvZW5uZW4uIFdpcmQgdm9uIHB1dF9hbmRfZ2V0LmMgZ2VwcnVlZnQuCiAgU2V0UHJvcChQX0NPTlRBSU5FUiwgMCk7CiAgU2V0UHJvcChQX05PSU5TRVJUX01TRywgQlMoIkFuIGRhcyBTY2hsdWVzc2VsYnJldHQga2FubnN0IER1IG51ciAiCiAgICAiU2NobHVlc3NlbCBoYWVuZ2VuLlxuU3ludGF4OiAnaGFlbmdlIDxzY2hsdWVzc2VsPiBhbiBicmV0dCcuIikpOwogIFNldFByb3AoUF9OT0dFVCwgIkRhcyBnZWh0IG5pY2h0LiAiK05hbWUoV0VSLDEpKwogICAgIiBsYWVzc3Qgc2ljaCBuaWNodCBiZXdlZ2VuLlxuIik7CiAgU2V0UHJvcChQX01BVEVSSUFMLCAoe01BVF9PQUssIE1BVF9NSVNDX01BR0lDfSkgKTsKICBTZXRQcm9wKFBfSU5GTywgIlZlcnN1Y2gncyBtYWwgbWl0OiBcInNrb21tYW5kb3Mgc2NobHVlc3NlbGJyZXR0XCIuXG4iKTsKCiAgQUQoKHsiaG9seiJ9KSwgQlMoIkVjaHRlLCByb2J1c3RlIEVpY2hlLiIpKTsKCiAgUmVtb3ZlQ21kKCh7InNjaGxpZXNzZSIsInNjaGxpZXNzIiwib2VmZm5lIn0pKTsKCiAgQWRkQ21kKCh7InVudCIsICJ1bnRlcnN1Y2hlIiwgImJldHJhY2h0ZSIsICJiZXRyYWNodCIsICJiZXRyIiwKICAgICAgICAgICAic2NoYXVlIiwgInNjaGF1In0pLCAidW50X2hha2VuIik7CiAgQWRkQ21kKCh7ImhhZW5nIiwgImhhZW5nZSJ9KSwgInNjaGx1ZXNzZWxfYW5faGFrZW5faGFlbmdlbiIpOwogIEFkZENtZCgoeyJuaW1tIn0pLCAic2NobHVlc3NlbF92b25faGFrZW5fbmVobWVuIik7CiAgQWRkQ21kKCJzYmVzY2hyaWZ0ZSIsICJjbWRfYmVzY2hyaWZ0ZW4iKTsKICBBZGRDbWQoInNsaXN0ZSIsICJjbWRfc2xpc3RlIik7Cn0KCi8qKioqKiBLT01NQU5ET0ZVTktUSU9ORU4gKioqKiovCgovLyBLb25maWd1cmF0aW9uIGRlciBTY2hsdWVzc2VsbGlzdGUsIGVudHdlZGVyICJhbGxlIiBhbnplaWdlbiBvZGVyIG51ciBkaWUKLy8gYmVsZWd0ZW4gSGFrZW4uCnN0YXRpYyBpbnQgY21kX3NsaXN0ZShzdHJpbmcgc3RyKSB7CiAgbm90aWZ5X2ZhaWwoIlN5bnRheDogJ3NsaXN0ZSBhbGxlfGJlbGVndGUnLlxuIik7CiAgaWYgKCAhc3RyaW5ncChzdHIpIHx8ICFzaXplb2Yoc3RyKSApCiAgICByZXR1cm4gMDsKCiAgaWYgKCBzdHIgPT0gImFsbGUiICkgewogICAgaWYgKCAhaG9va2xpc3RfbG9uZyApIHsKICAgICAgdGVsbF9vYmplY3QoVFAsIEJTKCJPaywgZXMgd2VyZGVuIGpldHp0IGltbWVyIGFsbGUgSGFrZW4gIgogICAgICAgICJhdWZnZWxpc3RldC4iKSk7CiAgICAgIGhvb2tsaXN0X2xvbmcgPSAxOwogICAgfQogICAgZWxzZSAKICAgICAgdGVsbF9vYmplY3QoVFAsIEJTKCJEaWUgRWluc3RlbGx1bmcgd2FyIHNjaG9uICdhbGxlJy4iKSk7CiAgfQogIGVsc2UgaWYgKCBzdHIgPT0gImJlbGVndGUiICkgewogICAgaWYgKCBob29rbGlzdF9sb25nICkgewogICAgICB0ZWxsX29iamVjdChUUCwgQlMoIk9rLCBlcyB3ZXJkZW4gamV0enQgbnVyIGRpZSBiZWxlZ3RlbiBIYWtlbiAiCiAgICAgICAgImF1ZmdlbGlzdGV0LiIpKTsKICAgICAgaG9va2xpc3RfbG9uZyA9MDsKICAgIH0KICAgIGVsc2UgCiAgICAgIHRlbGxfb2JqZWN0KFRQLCBCUygiRGllIEVpbnN0ZWxsdW5nIHdhciBzY2hvbiAnYmVsZWd0ZScuIikpOwogIH0KICBlbHNlIAogICAgcmV0dXJuIDA7CiAgcmV0dXJuIDE7Cn0KCi8vIEhha2VuIHVudGVyc3VjaGVuLiBPaG5lIEFuZ2FiZSBkZXIgTnVtbWVyIHdlcmRlbiBhbGxlIGF1c2dlZ2ViZW4sCi8vIGFuc29uc3RlbiBkZXIgZ2V3dWVuc2NodGUsIHNvZmVybiBlcyBkaWVzZW4gZ2lidC4Kc3RhdGljIGludCB1bnRfaGFrZW4oc3RyaW5nIHN0cikgewogIGlmICggIXN0cmluZ3Aoc3RyKSB8fCAhc2l6ZW9mKHN0cikgfHwgc3Ryc3RyKHN0ciwgImhha2VuIikgPT0gLTEgKQogICAgcmV0dXJuIDA7CiAgCiAgaW50IGhha2VubnI7CiAgaWYgKCBzc2NhbmYoc3RyLCAiaGFrZW4gJWQiLCBoYWtlbm5yKSAhPSAxICkgewogICAgc3RyaW5nIGRldCA9IEtleURlc2NyaXB0aW9uKGhha2VubnIpOwogICAgdGVsbF9vYmplY3QoVFAsIHNpemVvZihkZXQpID8gZGV0IDogIkRpZSBIYWtlbiBzaW5kIGFsbGUgbGVlci5cbiIpOwogICAgcmV0dXJuIDE7CiAgfQoKICBub3RpZnlfZmFpbCgiV2VsY2hlbiBIYWtlbiBtb2VjaHRlc3QgRHUgdW50ZXJzdWNoZW4/IEVzIGdpYnQgbnVyIGRpZSAiCiAgICAiSGFrZW4gMSBiaXMgMTYuXG4iKTsKICBpZiggaGFrZW5ucjwxIHx8IGhha2VubnIgPiAxNiApCiAgICByZXR1cm4gMDsKCi8vICBhdXNnYWJlX2hha2VuKGhha2VubnIpOwogIHRlbGxfb2JqZWN0KFRQLCBLZXlEZXNjcmlwdGlvbihoYWtlbm5yKSk7CiAgcmV0dXJuIDE7Cn0KCi8vIFNjaGx1ZXNzZWwgYXVmaGFlbmdlbi4Kc3RhdGljIGludCBzY2hsdWVzc2VsX2FuX2hha2VuX2hhZW5nZW4oc3RyaW5nIHN0cikgewogIG5vdGlmeV9mYWlsKCJXYXMgd2lsbHN0IER1IHdvcmFuIGhhZW5nZW4/XG4iKTsKICBpZighc3RyaW5ncChzdHIpIHx8ICFzaXplb2Yoc3RyKSkKICAgIHJldHVybiAwOwogIAogIG5vdGlmeV9mYWlsKCJEYXMgZGFyZnN0IER1IG5pY2h0LlxuIik7CiAgaWYoIWVybGF1YnQoKSkKICAgIHJldHVybiAwOwoKICBzdHJpbmcgd2FzLCB3b3JhbjsKICBub3RpZnlfZmFpbCgiRm9sZ2VuZGUgU3ludGF4IHZlcnN0ZWh0IERlaW4gU2NobHVlc3NlbGJyZXR0OlxuIgogICAgIiAgXCJoYWVuZ2UgPHNjaGx1ZXNzZWxuYW1lPiBhbiBoYWtlbiBbbnJdXCIgb2RlclxuIgogICAgIiAgXCJoYWVuZ2UgPHNjaGx1ZXNzZWxuYW1lPiBhbiBbc2NobHVlc3NlbF1icmV0dFwiLlxuIik7CiAgaWYgKCBzc2NhbmYoc3RyLCAiJXMgYW4gJXMiLCB3YXMsIHdvcmFuKSAhPSAyICkKICAgIHJldHVybiAwOwoKICBub3RpZnlfZmFpbCgiV2FzIG1vZWNodGVzdCBEdSBhbiBkYXMgU2NobHVlc3NlbGJyZXR0IGhhZW5nZW4/XG4iKTsKICBpZiAoICFzdHJpbmdwKHdhcykgKSAKICAgIHJldHVybiAwOwoKICBub3RpZnlfZmFpbCgiV29yYW4gd2lsbHN0IER1IGRhcyBkZW5uIGhhZW5nZW4/XG4iKTsKICBpZiAoIHN0cnN0cih3b3JhbiwgImhha2VuIiwgMCk9PS0xICYmICFpZCh3b3JhbikgKQogICAgcmV0dXJuIDA7CgogIC8vIFRlc3QsIG9iIGVzIE9iamVrdGUgZGllc2VzIE5hbWVucyBnaWJ0LgogIG9iamVjdCAqb2JzID0gVFAtPmZpbmRfb2JzKHdhcywgUFVUX0dFVF9OT05FKTsKICAvLyBBdXMgZGVyIExpc3RlIGRlciBnZWZ1bmRlbmVuIE9iamVrdGUgYWxsZSByYXVzZmlsdGVybiwgZGllIGtlaW5lCiAgLy8gU2NobHVlc3NlbCBzaW5kLiBBbHMgU2NobHVlc3NlbCBnZWx0ZW4gaGllciBhbGxlIE9iamVrdGUsIGRpZSBkaWUKICAvLyBJRCAic2NobHVlc3NlbCIgaGFiZW4gb2RlciBkaWUgbWl0dGVscyBRdWVyeURvb3JLZXkoKSBlaW5lciBiZXN0aW1tdGVuCiAgLy8gVHVlciB6dWdlb3JkbmV0IHNpbmQuCiAgb2JzID0gZmlsdGVyKG9icywgIydJc1ZhbGlkS2V5KTsKICBub3RpZnlfZmFpbCgiS2VpbmUobikgU2NobHVlc3NlbCBtaXQgZGVtIE5hbWVuIGdlZnVuZGVuLlxuIik7CiAgaWYgKCAhc2l6ZW9mKG9icykgKQogICAgcmV0dXJuIDA7CgogIGludCBuciA9IEdldE5leHRGcmVlU2xvdCgpOwogIG5vdGlmeV9mYWlsKCJBbSBTY2hsdWVzc2VsYnJldHQgaXN0IGtlaW4gSGFrZW4gbWVociBmcmVpLlxuIik7CiAgaWYgKCAhbnIgKQogICAgcmV0dXJuIDA7CgogIC8vIFdlbm4gbnVyIGVpbiBTY2hsdWVzc2VsIGdlZnVuZGVuIHd1cmRlLCB3aXJkIGdlbmF1ZXIgZ2VzY2hhdXQsIG9iCiAgLy8gZGVyIFNwaWVsZXIgZ2VzYWd0IGhhdCwgd28gZGVyIGhpbnNvbGwuCiAgaWYgKCBzaXplb2Yob2JzKSA9PSAxICkgewogICAgaWYgKCB3b3JhbiAhPSAiaGFrZW4iIHx8ICFpZCh3b3JhbikgKQogICAgICBzc2NhbmYod29yYW4sICJoYWtlbiAlZCIsIG5yKTsKICB9CgogIG5vdGlmeV9mYWlsKCJFcyBnaWJ0IG51ciBkaWUgSGFrZW4gMSBiaXMgMTYuXG4iKTsKICBpZiAoIG5yIDwgMSB8fCBuciA+IDE2ICkKICAgIHJldHVybiAwOwoKICBub3RpZnlfZmFpbCgiRGVyIEhha2VuIGlzdCBuaWNodCBtZWhyIGZyZWkuXG4iKTsKICBpZiAoIG9iamVjdHAoaGFrZW5bbnIsSE9PS19PQl0pICkKICAgIHJldHVybiAwOwoKICAvLyBBbGxlIGdlZnVuZGVuZW4gU2NobHVlc3NlbG9iamVrdGUgYW5zIEJyZXR0IGhhZW5nZW4uCiAgZm9yZWFjaCggb2JqZWN0IGtleSA6IG9icyApIHsKICAgIHN3aXRjaCAoa2V5LT5tb3ZlKE1FLCBNX1BVVCkpIHsKICAgICAgLy8gRGllIEthcGF6aXRhZXQgaXN0IHVlYmVyIFBfTUFYX09CSkVDVFMgYmVncmVuenQuIEFsbGUKICAgICAgLy8gU2NobGVpZmVuZHVyY2hsYWV1ZmUsIGRpZSBkaWUgS2FwYXppdGFldHNncmVuemUgZXJyZWljaGVuLCBsYW5kZW4KICAgICAgLy8gaW4gZGVmYXVsdCB1bmQgYmVlbmRlbiBkYW1pdCBkaWUgU2NobGVpZmUuIERhaGVyIG11ZXNzZW4gc2llIAogICAgICAvLyBuaWNodCBnZXNvbmRlcnQgYmVoYW5kZWx0IHdlcmRlbi4KICAgICAgY2FzZSBNT1ZFX09LIDoKICAgICAgICAvLyBGYWxscyBkYXMgQnJldHQgdm9sbCBzZWluIHNvbGx0ZSwgYWJlciBmYWVsc2NobGljaGVyd2Vpc2UgCiAgICAgICAgLy8gZGVubm9jaCBlaW4gd2VpdGVyZXIgU2NobHVlc3NlbCBoaW5laW5iZXdlZ3Qgd3VyZGUsIGlzdCBucj09MCwKICAgICAgICAvLyB1bmQgZXMgd2lyZCBlaW4gRmVobGVyIGF1c2dlbG9lc3QsIGRhbWl0IG5pY2h0IGhpbnRlcmhlciBlaW4KICAgICAgICAvLyBTY2hsdWVzc2VsIGFuIEhha2VuIDAgaGFlbmd0LgogICAgICAgIGlmICggIW5yICkgewogICAgICAgICAgcmFpc2VfZXJyb3IoIkZlaGxlcjogSGFrZW4gMCBkYXJmIG5pY2h0IGJlbGVndCB3ZXJkZW4uIik7CiAgICAgICAgICBicmVhazsKICAgICAgICB9CiAgICAgICAgdGVsbF9vYmplY3QoVFAsIEJTKCJEdSBoYWVuZ3N0ICIrb2JzWzBdLT5uYW1lKFdFTiwxKSsiIGFuIEhha2VuICIrCiAgICAgICAgICBucisiLiIpKTsKICAgICAgICAvLyBOdXIgd2VubiBlaW4gU2NobHVlc3NlbCBlcmZvbGdyZWljaCBkcmFuZ2VoYWVuZ3Qgd3VyZGUsIHdpcmQgZXIKICAgICAgICAvLyBpbiBkaWUgTGlzdGUgZWluZ2V0cmFnZW4uIEV0d2FpZ2UgQmVzY2hyaWZ0dW5nZW4gYmxlaWJlbiBiZXN0ZWhlbiwKICAgICAgICBoYWtlbltuciwgSE9PS19PQl0gPSBrZXk7CiAgICAgICAgLy8gdW5kIG51ciBkYW5uIHdpcmQgZGVyIG5hZWNoc3RlIFNsb3QgcHJvYmllcnQuIFdlbm4gbnVyIGVpbiAKICAgICAgICAvLyBTY2hsdWVzc2VsIHZlcmFyYmVpdGV0IHdpcmQsIGlzdCBkYXMgaGllciB1bnNjaGFlZGxpY2gsIHdlaWwgZXMgCiAgICAgICAgLy8gbmljaHQgbm9jaG1hbCBhdXNnZXdlcnRldCB3aXJkLgogICAgICAgIG5yID0gR2V0TmV4dEZyZWVTbG90KCk7CiAgICAgICAgLy8gU2NobHVlc3NlbCB3dXJkZSB2ZXJhcmJlaXRldCB1bmQgTWVsZHVuZyBhdXNnZWdlYmVuCiAgICAgICAgb2JzIC09ICh7a2V5fSk7CiAgICAgICAgYnJlYWs7CiAgICAgIGNhc2UgTUVfQ0FOVF9MRUFWRV9FTlYgOgogICAgICBjYXNlIE1FX0NBTlRfQkVfSU5TRVJURUQgOgogICAgICBjYXNlIE1FX0NBTlRfQkVfRFJPUFBFRCA6CiAgICAgICAgLy8gU2NobHVlc3NlbCB3dXJkZSBuaWNodCBlcmZvbGdyZWljaCBkcmFuZ2VoYWVuZ3QuCiAgICAgICAgdGVsbF9vYmplY3QoVFAsIEJTKGtleS0+TmFtZShXRVIsMSkrIiB3ZWlnZXJ0IHNpY2gsIGFucyAiCiAgICAgICAgICAiU2NobHVlc3NlbGJyZXR0IGdlaGFlbmd0IHp1IHdlcmRlbi4iKSk7CiAgICAgICAgLy8gTWVsZHVuZyB3dXJkZSBhdXNnZWdlYmVuLCBuaWNodHMgd2VpdGVyIHp1IHR1bi4KICAgICAgICBvYnMgLT0gKHtrZXl9KTsKICAgICAgICBicmVhazsKICAgICAgLy8gVE9PX01BTllfT0JKRUNUUyB3aXJkIG5pY2h0IGhpZXIgYmVoYW5kZWx0LCBzb25kZXJuIHdlaXRlciB1bnRlbiwKICAgICAgLy8gdW0gZWluZSBBdWZsaXN0dW5nIGRlciBTY2hsdWVzc2VsbmFtZW4gYXVzZ2ViZW4genUga29lbm5lbiwgc3RhdHQKICAgICAgLy8gZWluZSBaZWlsZSBwcm8gU2NobHVlc3NlbC4gRGllIGFuZGVyZW4gUnVlY2tnYWJld2VydGUgdm9uIG1vdmUoKSAKICAgICAgLy8gc2luZCBiZWkgZGllc2VyIEFydCBkZXIgQmV3ZWd1bmcgbmljaHQgenUgZXJ3YXJ0ZW4uCiAgICAgIGRlZmF1bHQ6IGJyZWFrOwogICAgfQogIH0KICAvLyBGdWVyIGFsbGUgdWVicmlnZW4gd2FyIHdvaGwgVE9PX01BTllfT0JKRUNUUyBkZXIgUnVlY2tnYWJld2VydCwgZGVubgogIC8vIGRhcyBTY2hsdWVzc2VsYnJldHQgZXJsYXVidCBudXIgUF9NQVhfT0JKRUNUUyA9IDE2LgogIGlmICggc2l6ZW9mKG9icykgKSB7CiAgICB0ZWxsX29iamVjdChUUCwgQlMoIkZ1ZXIgIitDb3VudFVwKG9icy0+bmFtZShXRU4pKSsiIGlzdCBsZWlkZXIga2VpbiAiCiAgICAgICJIYWtlbiBtZWhyIGFtIFNjaGx1ZXNzZWxicmV0dCBmcmVpLiIpKTsKICB9CiAgcmV0dXJuIDE7Cn0KCi8vIFNjaGx1ZXNzZWwgYWJuZWhtZW4Kc3RhdGljIGludCBzY2hsdWVzc2VsX3Zvbl9oYWtlbl9uZWhtZW4oc3RyaW5nIHN0cikgewogIGlmKCAhc3RyaW5ncChzdHIpIHx8ICFzaXplb2Yoc3RyKSApIAogICAgcmV0dXJuIDA7CgogIHN0cmluZyB3YXMsIHdvcmF1czsKICBpZiAoIHNzY2FuZihzdHIsICIlcyBhdXMgJXMiLCB3YXMsIHdvcmF1cykgIT0gMiAmJiAKICAgICAgIHNzY2FuZihzdHIsICIlcyB2b24gJXMiLCB3YXMsIHdvcmF1cykgIT0gMiApCiAgICByZXR1cm4gMDsKCiAgbm90aWZ5X2ZhaWwoIkRhcyBkYXJmc3QgRHUgbmljaHQhXG4iKTsKICBpZighZXJsYXVidCgpKSAKICAgIHJldHVybiAwOwogCiAgbm90aWZ5X2ZhaWwoIldvcmF1cyB3aWxsc3QgRHUgZGFzIGRlbm4gbmVobWVuP1xuIik7CiAgaWYgKCAhaWQod29yYXVzKSAmJiBzdHJzdHIod29yYXVzLCAiaGFrZW4iLCAwKSA9PSAtMSApIAogICAgcmV0dXJuIDA7CgogIG5vdGlmeV9mYWlsKCJXYXMgd2lsbHN0IER1IGRlbm4gdm9tIFNjaGx1ZXNzZWxicmV0dCBuZWhtZW4/XG4iKTsKICBpZiggIXN0cmluZ3Aod2FzKSApIAogICAgcmV0dXJuIDA7CiAgCiAgbm90aWZ5X2ZhaWwoIkRhcyBTY2hsdWVzc2VsYnJldHQgaXN0IGRvY2ggYWJlciBsZWVyLlxuIik7CiAgaWYgKCAhc2l6ZW9mKGFsbF9pbnZlbnRvcnkoTUUpKSApCiAgICByZXR1cm4gMDsKCiAgaW50IGhha2VubnI7CiAgb2JqZWN0ICprZXlzID0gKHt9KTsKICAvLyBFcyBtdWVzc2VuIGF1Y2ggU2NobHVlc3NlbCB2b24gYmVzdGltbXRlbiBIYWtlbiBhYmdlbm9tbWVuCiAgLy8gd2VyZGVuIGtvZW5uZW4sIG5pY2h0IG51ciBqZXdlaWxzIGRlciBlcnN0ZSBtaXQgZGVyIGFuZ2VnZWJlbmVuIElELgogIC8vIERpZXMgaGF0IGF1Y2ggUHJpbyBnZWdlbnVlYmVyIGRlciBhbGxnZW1laW5lbiBCZWdyaWZmc3N1Y2hlIG1pdAogIC8vIGZpbmRfb2JzKCkuCiAgaWYgKCBzc2NhbmYod29yYXVzLCAiaGFrZW4gJWQiLCBoYWtlbm5yKSA9PSAxICkgewogICAgbm90aWZ5X2ZhaWwoIkVzIGdpYnQgbnVyIGRpZSBIYWtlbiAxIGJpcyAxNi5cbiIpOwogICAgaWYgKCBoYWtlbm5yIDwgMSB8fCBoYWtlbm5yID4gMTYgKSAKICAgICAgcmV0dXJuIDA7CiAgICBub3RpZnlfZmFpbCgiQW4gZGllc2VtIEhha2VuIGhhZW5ndCBhYmVyIGRvY2gga2VpbiBTY2hsdWVzc2VsLlxuIik7CiAgICBpZiAoICFvYmplY3RwKGhha2VuW2hha2VubnIsSE9PS19PQl0pICkKICAgICAgcmV0dXJuIDA7CiAgICAKICAgIGtleXMgKz0gKHsgaGFrZW5baGFrZW5ucixIT09LX09CXSB9KTsKICB9CgogIC8vIEtlaW5lciBnZWZ1bmRlbj8gVmllbGxlaWNodCBpc3QgamEgZWluZXIgbWl0IGVpbmVyIGJlc3RpbW10ZW4gCiAgLy8gQmVzY2hyaWZ0dW5nIGdlbWVpbnQ/CiAgaWYgKCAhc2l6ZW9mKGtleXMpICkgewogICAgLy8gU2NobHVlc3NlbCBtaXQgZGVtIGFuZ2VnZWJlbmVuIE5hbWVuIHN1Y2hlbgogICAga2V5cyA9IFRQLT5maW5kX29icyh3YXMrIiBpbiBicmV0dCBpbiByYXVtIik7CiAgICAvLyBIYWtlbm51bW1lciBlcm1pdHRlbG4sIHdlbm4gZWluZSBCZXNjaHJpZnR1bmcgYW5nZWdlYmVuIHd1cmRlLgogICAgc3RyaW5nIHdhbnRlZF9kZXNjOwogICAgc3NjYW5mKHdhcywgInNjaGx1ZXNzZWwgZnVlciAlcyIsIHdhbnRlZF9kZXNjKTsKICAgIG9iamVjdCB3YW50ZWRfa2V5ID0gR2V0S2V5Rm9yTGFiZWwod2FudGVkX2Rlc2MpOwogICAgaWYgKCBvYmplY3RwKHdhbnRlZF9rZXkpICkKICAgICAga2V5cyArPSAoe3dhbnRlZF9rZXl9KTsKICB9CiAgLy8gSW1tZXIgbm9jaCBuaXggZ2VmdW5kZW4/IERhbm4gbXVzcyBzaWNoIGRlciBTcGllbGVyIHdhcyBhbmRlcmVzIAogIC8vIGVpbmZhbGxlbiBsYXNzZW4uCiAgbm90aWZ5X2ZhaWwoIkFtIFNjaGx1ZXNzZWxicmV0dCBoYWVuZ3Qga2VpbiBzb2xjaGVyIFNjaGx1ZXNzZWwuXG4iKTsKICBpZiAoICFzaXplb2Yoa2V5cykgKQogICAgcmV0dXJuIDA7CgogIC8vIEFsbGUgZ2VmdW5kZW5lbiBTY2hsdWVzc2VsIHZlcmFyYmVpdGVuLiBBbGxlLCBkaWUgbmljaHQgYmV3ZWd0IHdlcmRlbgogIC8vIGtvZW5uZW4sIHZlcmJsZWliZW4gaW4gZGVyIExpc3RlLgogIGZvcmVhY2goIG9iamVjdCBrZXkgOiBrZXlzICkgewogICAgaW50IGN1cnJlbnRfaG9vayA9IEdldEhvb2tOdW1iZXJGb3JLZXkoa2V5KTsKICAgIGlmICgga2V5LT5tb3ZlKFRQLE1fR0VUKSA9PSBNT1ZFX09LICkgewogICAgICBrZXlzIC09ICh7IGtleSB9KTsKICAgICAgdGVsbF9vYmplY3QoVFAsIEJTKCJEdSBuaW1tc3QgIitrZXktPm5hbWUoV0VOLDEpKyIgdm9uIEhha2VuICIrCiAgICAgICAgY3VycmVudF9ob29rKyIgYWIuIikpOwogICAgICAvLyBTY2hsdWVzc2VsIGF1c3RyYWdlbjsgYmVzdGVoZW5kZSBCZXNjaHJpZnR1bmdlbiBibGVpYmVuIGVyaGFsdGVuCiAgICAgIGhha2VuW2N1cnJlbnRfaG9vaywgSE9PS19PQl0gPSAwOwogICAgfQogIH0KICAvLyBWb24gYWxsZW4gbmljaHQgdm9tIEhha2VuIGdlbm9tbWVuZW4gU2NobHVlc3NlbG4gZGllIE5hbWVuIGVybWl0dGVsbgogIC8vIHVuZCBhdWZsaXN0ZW4uCiAgaWYgKCBzaXplb2Yoa2V5cykgKSB7CiAgICB0ZWxsX29iamVjdChUUCwgQlMoY2FwaXRhbGl6ZShDb3VudFVwKGtleXMtPm5hbWUoV0VSLDEpKSkrIiAiKwogICAgICAoc2l6ZW9mKGtleXMpPT0xPyJrb25udGUiOiJrb25udGVuIikrIiBuaWNodCB2b20gU2NobHVlc3NlbGJyZXR0ICIKICAgICAgImFiZ2Vub21tZW4gd2VyZGVuLiIpKTsKICB9CiAgcmV0dXJuIDE7Cn0KCi8vIFZlcmZ1ZWdiYXJlIEtvbW1hbmRvcyBhdWZsaXN0ZW4uCnZhcmFyZ3MgaW50IHNrb21tYW5kb3Moc3RyaW5nIHN0cikgewogIG5vdGlmeV9mYWlsKCAiRmVobGVyOiBEaWVzZXIgQmVmZWhsIGJlbm9ldGlndCBlaW5lIGd1ZWx0aWdlIE9iamVrdC1JZCBhbHMgIgogICAgKyJQYXJhbWV0ZXIuXG5CZWlzcGllbDogc2tvbW1hbmRvcyBbc2NobHVlc3NlbF1icmV0dFxuIik7CiAgCiAgaWYoICFpZChzdHIpICkgcmV0dXJuIDA7CgogIHdyaXRlKAogICAgIj09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0iCiAgICAiPT09PT09PT09PVxuIgogICAgIkFrdHVlbGxlIFZlcnNpb246ICIrUXVlcnlQcm9wKCJjbnRfdmVyc2lvbl9zdGQiKSsKICAgICAgUXVlcnlQcm9wKCJjbnRfdmVyc2lvbl9vYmoiKSsiXG4iKwogICAgQlMoTmFtZShXRVIsMSkrIiBrYW5uIG51ciBpbiBkaWVzZW0gU2VoZXJoYXVzIHZlcndlbmRldCB3ZXJkZW4sICIKICAgICJkYSAiK1F1ZXJ5UHJvbm91bihXRVIpKyIgc3BlemllbGwgZGFmdWVyIGdla2F1ZnQgd3VyZGUuICIrCiAgICBDQVAoUXVlcnlQcm9ub3VuKFdFUikpKyIgdmVyZnVlZ3QgdWViZXIgZm9sZ2VuZGUgS29tbWFuZG9zOiIpKwogICAgIi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0iCiAgICAiLS0tLS0tLVxuIgogICAgInNlcmxhdWJlIFtzY2hsdWVzc2VsXWJyZXR0IFtzcGllbGVybmFtZXxcImhhdXNmcmV1bmRlXCJ8XCJmYW1pbGllXCJdXG4iCiAgICAiICBFcmxhdWJ0IFBlcnNvbmVuLCAiK25hbWUoV0VOLDEpKyIgbWl0enViZW51dHplbi5cbiIKICAgICIgIHNlcmxhdWJlIG9obmUgQW5nYWJlIGVpbmVzIEFyZ3VtZW50cyBsaXN0ZXQgYWxsZSBQZXJzb25lbiBtaXQgWnVncmlmZiAiCiAgICAgICJhdWZcbiAgIituYW1lKFdFTiwxKSsiIGF1Zi5cblxuIgogICAgInZlcnNjaGllYmUgW3NjaGx1ZXNzZWxdYnJldHQgbmFjaCBbYXVzZ2FuZ11cbiIKICAgICIgIERhbWl0IGthbm5zdCBEdSAiK25hbWUoV0VOLDEpKyIgaW5uZXJoYWxiIERlaW5lcyBTZWhlcmhhdXNlcyAiCiAgICAidmVyc2NoaWViZW4uXG5cbiIKICAgICJzdmVyc3RlY2tlIFtzY2hsdWVzc2VsXWJyZXR0XG4iCiAgICAiICBEYW1pdCBtYWNoc3QgRHUgIituYW1lKFdFTiwxKSsiIHVuc2ljaHRiYXIuXG4iCiAgICAic2hvbGUgW3NjaGx1ZXNzZWxdYnJldHQgaGVydm9yXG4iCiAgICAiICBEYW1pdCBtYWNoc3QgRHUgIituYW1lKFdFTiwxKSsiIHdpZWRlciBzaWNodGJhci5cbiIKICAgICJ6ZXJ0cnVlbW1lciBbc2NobHVlc3NlbF1icmV0dFxuIgogICAgIiAgRGFtaXQgemVyc3RvZXJzdCBEdSBkYXMgU2NobHVlc3NlbGJyZXR0LlxuIgogICAgInNiZXNjaHJpZnRlIGhha2VuIDxucj4gbWl0IDx0ZXh0PnxuaWNodHNcbiIKICAgICIgIEVpbmUgQmVzY2hyaWZ0dW5nIGFuIGVpbmVtIEhha2VuIGFuYnJpbmdlbiBvZGVyIGxvZXNjaGVuLlxuIgogICAgInNsaXN0ZSBsYW5nfGt1cnpcbiIKICAgICIgIFNjaGx1ZXNzZWxhbnplaWdlIGtvbmZpZ3VyaWVyZW46IGFsbGUgb2RlciBudXIgYmVsZWd0ZSBhdWZsaXN0ZW4uXG4iCiAgICAiaGFlbmdlIDxzY2hsdWVzc2VsbmFtZT4gYW4gaGFrZW4gW25yXVxuIgogICAgImhhZW5nZSA8c2NobHVlc3NlbG5hbWU+IGFuIFtzY2hsdWVzc2VsXWJyZXR0XG4iCiAgICAiICBEYW1pdCBoYWVuZ3N0IER1IGVpbmVuIFNjaGx1ZXNzZWwgYW4gZGFzIEJyZXR0LlxuIgogICAgIm5pbW0gc2NobHVlc3NlbCB2b24gaGFrZW4gPG5yPlxuIgogICAgIm5pbW0gPHNjaGx1ZXNzZWxuYW1lPiB2b24gW3NjaGx1ZXNzZWxdYnJldHRcbiIKICAgICJuaW1tIHNjaGx1ZXNzZWwgZnVlciA8YmVzY2hyaWZ0dW5nPiB2b24gW3NjaGx1ZXNzZWxdYnJldHQuXG4iCiAgICAiICBEYW1pdCBuaW1tc3QgRHUgZWluZW4gU2NobHVlc3NlbCB2b20gU2NobHVlc3NlbGJyZXR0LlxuIgogICAgIj09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0iCiAgICAiPT09PT09PT09PVxuIik7CiAgcmV0dXJuIDE7Cn0KCnN0YXRpYyBpbnQgZXJsYXVibmlzX2xpc3RlKCkKewogIGlmKCBRdWVyeUhhdXNiZXNpdHplcigpICE9IFF1ZXJ5VFAoKSAmJiAhUXVlcnlQcm9wKCJ0ZXN0IikgKQogIHsKICAgIHRlbGxfb2JqZWN0KFRQLCBCUygiTnVyICIrUXVlcnlIYXVzYmVzaXR6ZXIoKSsiIGRhcmYgQmVyZWNodGlndW5nZW4gIgogICAgICArbmFtZShXRVNTRU4sMSkrIiBhYmZyYWdlbiEiKSk7CiAgICByZXR1cm4gMTsKICB9CiAgCiAgc3RyaW5nICpzdHJzOwogIHN0cmluZyBzdHIgPSAKICAgICI9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09IgogICAgIj09PT09PT09PT1cbiI7CiAgaWYgKCBoYXVzZXJsYXVibmlzICkgewogICAgc3RycyA9IFNIVkVSV0FMVEVSLT5IYXVzUHJvcChMT1dFUihRdWVyeUhhdXNiZXNpdHplcigpKSwgMik7CiAgICBzdHIgKz0gIkZvbGdlbmRlIEZyZXVuZGUgRGVpbmVzIEhhdXNlcyBkdWVyZmVuICIrbmFtZShXRU4sMSkrCiAgICAgICIgbWl0YmVudXR6ZW46XG4iOwogICAgaWYoc2l6ZW9mKHN0cnMpKSB7CiAgICAgIHN0ciArPSBCUyhDb3VudFVwKHN0cnMpKTsKICAgIH0KICAgIGVsc2UgewogICAgICBzdHIgKz0gQlMoIkR1IGhhc3Qga2VpbmVyIFBlcnNvbiBadWdyaWZmIGF1ZiBEZWluIEhhdXMgZ2V3YWVocnQuLi4iKTsKICAgIH0KICB9CiAgZWxzZSB7CiAgICBzdHIrPSBCUygiRGllIEZyZXVuZGUgRGVpbmVzIEhhdXNlcyBkdWVyZmVuICIrbmFtZShXRU4sMSkrCiAgICAgICIgbmljaHQgbWl0YmVudXR6ZW4uIik7CiAgfQoKICBzdHIgKz0gCiAgICAiLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSIKICAgICItLS0tLS0tLS0tXG4iOwoKICBpZihmYW1pbGllKQogIHsKICBpZiggIi9zZWN1cmUvendlaXRpZXMiLT5RdWVyeUZhbWlsaWUoVFApID09IGZhbWlsaWUpCiAgICBzdHIrPUJTKCJBbGxlIERlaW5lIEZhbWlsaWVubWl0Z2xpZWRlciBkdWVyZmVuICIKICAgICAgICAgICAgICtuYW1lKFdFTiwxKSsiIG9lZmZuZW4vc2NobGllc3Nlbi4iKTsKICBlbHNlCiAgICBzdHIrPUJTKCAiQWxsZSBGYW1pbGllbm1pdGdsaWVkZXIgdm9uICIrQ0FQKGV4cGxvZGUoZmFtaWxpZSwiXyIpWzBdKQogICAgICAgICAgICAgKyIgZHVlcmZlbiAiICsgbmFtZShXRU4sMSkgKyAiIG9lZmZuZW4vc2NobGllc3Nlbi4iKTsKICBzdHIrPSItLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tIgogICAgICAgICItLS0tLS0tLS0tXG4iOwogIH0KCiAgc3Rycz1RdWVyeVByb3AoImNudF9lcmxhdWJuaXMiKTsKCiAgaWYoc2l6ZW9mKHN0cnMpKSB7CiAgICBzdHIgKz0gQlMoIkZvbGdlbmRlIHNvbnN0aWdlIFBlcnNvbmVuIGR1ZXJmZW4gIituYW1lKFdFTiwxKSsKICAgICAgIiBtaXRiZW51dHplbjoiKTsKICAgIHN0ciArPSBDb3VudFVwKHN0cnMpOwogIH0KICBlbHNlIHsKICAgIHN0ciArPSBCUygiRXMgZ2lidCBrZWluZSBzb25zdGlnZW4gUGVyc29uZW4sIGRpZSAiK25hbWUoV0VOLDEpKwogICAgICAiIG1pdGJlbnV0emVuIGR1ZXJmZW4uIik7CiAgfQogIHN0ciArPQogICAgIj09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0iCiAgICAiPT09PT09PT09PVxuIjsKCiAgd3JpdGUoc3RyKTsKCiAgcmV0dXJuIDE7Cn0KCi8vIEhha2VuIGJlc2NocmlmdGVuLgpzdGF0aWMgaW50IGNtZF9iZXNjaHJpZnRlbihzdHJpbmcgc3RyKSB7CiAgc3RyaW5nIG5mbSA9ICJTeW50YXg6IHNiZXNjaHJpZnRlIGhha2VuIDxoYWtlbm51bW1lcj4gbWl0ICIKICAgICI8dGV4dD58bmljaHRzXG4iCiAgICAiRnVlciA8dGV4dD4ga2FubnN0IER1IGVpbmVuIGJlbGllYmlnZW4gVGV4dCBtaXQgYmlzIHp1IDMwIFplaWNoZW4gIgogICAgImFuZ2ViZW4sXG4iCiAgICAiJ25pY2h0cycgbG9lc2NodCBkaWUgQmVzY2hyaWZ0dW5nIGVpbmVzIFNjaGlsZGVzLlxuIjsKCiAgbm90aWZ5X2ZhaWwoIkRhcyBkYXJmc3QgRHUgbmljaHQhXG4iKTsKICBpZighZXJsYXVidCgpKSAKICAgIHJldHVybiAwOwogIAogIHN0cmluZyB0ZXh0OwogIGludCBobnI7CiAgc3RyID0gVFAtPl91bnBhcnNlZF9hcmdzKDApOwogIG5vdGlmeV9mYWlsKG5mbSk7CiAgaWYgKCAhc3RyaW5ncChzdHIpIHx8ICFzaXplb2Yoc3RyKSApIAogICAgcmV0dXJuIDA7CiAgaWYgKCBzc2NhbmYoc3RyLCJoYWtlbiAlZCBtaXQgJXMiLCBobnIsIHRleHQpIT0yICkKICAgIHJldHVybiAwOwoKICBub3RpZnlfZmFpbCgiV2VsY2hlbiBIYWtlbiBtb2VjaHRlc3QgRHUgYmVzY2hyaWZ0ZW4/XG4iK25mbSk7CiAgaWYoIWhucikgCiAgICByZXR1cm4gMDsKICAKICBub3RpZnlfZmFpbCgiRXMgZ2lidCBudXIgZGllIEhha2VuIDEgYmlzIDE2LlxuIik7CiAgaWYgKCBobnIgPCAxIHx8IGhuciA+IDE2ICkgCiAgICByZXR1cm4gMDsKCiAgbm90aWZ5X2ZhaWwoIldvbWl0IG1vZWNodGVzdCBEdSBkZW4gSGFrZW4gYmVzY2hyaWZ0ZW4/XG4iK25mbSk7CiAgaWYoICFzdHJpbmdwKHRleHQpIHx8ICFzaXplb2YodGV4dCkgKQogICAgcmV0dXJuIDA7CgogIG5vdGlmeV9mYWlsKCJEZXIgVGV4dCBzb2xsdGUgbmljaHQgbGFlbmdlciBhbHMgMzAgWmVpY2hlbiBzZWluLlxuIik7CiAgaWYoc2l6ZW9mKHRleHQpID4gMzApIAogICAgcmV0dXJuIDA7CgogIGlmICggbG93ZXJfY2FzZSh0ZXh0KSA9PSAibmljaHRzIiApIHsKICAgIGlmICggc3RyaW5ncChoYWtlbltobnIsSE9PS19MQUJFTF0pICkgewogICAgICB0ZWxsX29iamVjdChUUCwgQlMoIlNvcmdmYWVsdGlnIHdpc2Noc3QgRHUgZGllIEJlc2NocmlmdHVuZyBkZXMgIgogICAgICAgICJIYWtlbnMgIitobnIrIiB3ZWcuIikpOwogICAgICBoYWtlbltobnIsSE9PS19MQUJFTF09MDsKICAgIH0KICAgIGVsc2UgewogICAgICB0ZWxsX29iamVjdChUUCwgQlMoIkR1IG11c3N0IERpY2ggZ2VpcnJ0IGhhYmVuLiBIYWtlbiAiK2hucisiIGlzdCAiCiAgICAgICAgImdhciBuaWNodCBiZXNjaHJpZnRldC4iKSk7CiAgICB9CiAgfQogIGVsc2UgaWYgKCBsb3dlcl9jYXNlKHRleHQpID09ICJzY2hsdWVzc2VsIiApIHsKICAgIHRlbGxfb2JqZWN0KFRQLCBCUygKICAgICAgIkR1IHNvbGx0ZXN0IERpciBldHdhcyBBdXNzYWdla3JhZWZ0aWdlcmVzIGVpbmZhbGxlbiBsYXNzZW4uIikpOwogIH0KICBlbHNlIHsKICAgIHRlbGxfb2JqZWN0KFRQLCBCUygiRHUgYmVzY2hyaWZ0ZXN0IGRhcyBTY2hpbGRjaGVuIHVlYmVyIEhha2VuICIraG5yKwogICAgICAiIG1pdCAiK3RleHQrIi4iKSk7CiAgICB0ZWxsX3Jvb20oZW52aXJvbm1lbnQoKSwgQlMoCiAgICAgIFRQLT5OYW1lKFdFUikrIiBzY2hyZWlidCBldHdhcyBhbnMgU2NobHVlc3NlbGJyZXR0LiIpLCAoe1RQfSkpOwogICAgaGFrZW5baG5yLEhPT0tfTEFCRUxdID0gdGV4dDsKICB9CiAgcmV0dXJuIDE7Cn0KCi8qKioqKiBISUxGU0ZVTktUSU9ORU4gKioqKiovCgovLyBCZXNjaHJlaWJ1bmcgZWluZXMgSGFrZW5zIGVyemV1Z2VuLiBXZW5uIDxrZXludW0+IGFuZ2VnZWJlbiB3aXJkLCAKLy8gd2lyZCBudXIgZGVyIGdlc3VjaHRlIEhha2VuIGFuZ2V6ZWlndCwgZWdhbCBvYiBsZWVyIG9kZXIgbmljaHQuIAovLyBBbnNvbnN0ZW4gd2VyZGVuIGRpZSBiZWxlZ3RlbiBIYWtlbiBhbmdlemVpZ3QsIGF1c3NlciB3ZW5uIAovLyA8aG9va2xpc3RfbG9uZz4gZ2VzZXR6dCBpc3QuIERhbm4gd2VyZGVuIGFsbGUgSGFrZW4gYXVmZ2VsaXN0ZXQuCnByaXZhdGUgdmFyYXJncyBzdHJpbmcgS2V5RGVzY3JpcHRpb24oaW50IGtleW51bSkgewogIHN0cmluZyBkZXNjPSIiOwogIG1hcHBpbmcga2V5bGlzdD0oWzoyXSk7CgogIC8vIExpc3RlIGRlckhha2VuIGF1ZiBkZW4vZGllIGdlc3VjaHRlbiBlaW5zY2hyYWVua2VuLgogIC8vIE51ciBlaW4gSGFrZW4gc29sbCBhbmdlc2NoYXV0IHdlcmRlbi4gRGllcyBoYXQgaW1tZXIgUHJpb3JpdGFldCwKICAvLyBkLmguIGF1Y2ggYmVpIDxzbGlzdGUgYWxsZT4gd2lyZCBudXIgZWluIEhha2VuIGdlbGlzdGV0LgogIGlmICgga2V5bnVtICkgewogICAgbV9hZGQoa2V5bGlzdCwga2V5bnVtLCBtX2VudHJ5KGhha2VuLCBrZXludW0pLi4uKTsKICB9CiAgLy8gV2VubiA8c2xpc3RlIGFsbGU+IGdlc2V0enQgaXN0LCBhbGxlIGF1c2dlYmVuLgogIGVsc2UgaWYgKCBob29rbGlzdF9sb25nICkgewogICAga2V5bGlzdCA9IGhha2VuOwogIH0KICAvLyBBbnNvbnN0ZXIgbnVyIGRpZSBiZWxlZ3Rlbi4KICBlbHNlIHsKICAgIGtleWxpc3QgPSBmaWx0ZXIoaGFrZW4sIAogICAgICBmdW5jdGlvbiBpbnQgKGludCBudW0sIDxzdHJpbmd8b2JqZWN0PiogdmFsdWVzKSB7CiAgICAgICAgcmV0dXJuIG9iamVjdHAodmFsdWVzWzBdKTsKICAgICAgfSk7CiAgfQoKICAvLyBVZWJlciBkYXMgTWFwcGluZyBtaXQgZGVuIHNlbGVrdGllcnRlbiBIYWtlbiBsYXVmZW4gdW5kIEF1c2dhYmVuCiAgLy8gZXJ6ZXVnZW4uCiAgZm9yZWFjaChpbnQgbnVtIDogMS4uMTYpIHsKICAgIC8vIEhpZXIgd2lyZCBkZXIgYWt0dWVsbGUgV2VydCB1ZWJlcnNwcnVuZ2VuLCB3ZW5uIGVyIG5pY2h0IGVudGhhbHRlbiAKICAgIC8vIGlzdCwgZGEgZGllIFp1d2Vpc3VuZyBpbiA8a2V5PiB1bmQgPGtleWRlc2M+IGF1Y2ggZGFubiBlaW5lIDAgZXJnZWJlbgogICAgLy8gd3VlcmRlLCB1bmQgc29taXQgS2V5cyBtaXQgbGVlcmVuIFZhbHVlcyBuaWNodCB2b24gbmljaHQgZXhpc3RpZXJlbmRlbgogICAgLy8gS2V5cyB6dSB1bnRlcnNjaGVpZGVuIHdhZXJlbi4KICAgIGlmICggbWVtYmVyKG1faW5kaWNlcyhrZXlsaXN0KSwgbnVtKSA9PSAtMSApCiAgICAgIGNvbnRpbnVlOwogICAgc3RyaW5nIGtleWRlc2MgPSBrZXlsaXN0W251bSwgSE9PS19MQUJFTF07CiAgICBvYmplY3Qga2V5ID0ga2V5bGlzdFtudW0sIEhPT0tfT0JdOwogICAgZGVzYyArPSAiSGFrZW4gIiArIG51bSArIChzdHJpbmdwKGtleWRlc2MpPyIgWyIra2V5ZGVzYysiXTogIiA6ICI6ICIpOwogICAgZGVzYyArPSAob2JqZWN0cChrZXkpID8ga2V5LT5zaG9ydCgpIDogImxlZXJcbiIpOwogIH0KICByZXR1cm4gZGVzYzsKfQoKLy8gUnVlY2tnYWJld2VydDogMSwgd2VubiBlcyBzaWNoIHVtIGVpbiBTY2hsdWVzc2Vsb2JqZWt0IGhhbmRlbHQsIHNvbnN0IDAuCi8vIFNjaGx1ZXNzZWwgd2VyZGVuIGFuaGFuZCBkZXIgSUQgInNjaGx1ZXNzZWwiIGVya2FubnQgb2RlciBkYXJhbiwgZGFzcwovLyBRdWVyeURvb3JLZXkoKSBlaW5lbiBXZXJ0IHp1cnVlY2tnaWJ0LCBkLmguIGRhc3MgZGllc2VzIE9iamVrdCBlaW5lCi8vIFN0YW5kYXJkLURvb3JtYXN0ZXItVHVlciBvZWZmbmV0Lgpwcml2YXRlIGludCBJc1ZhbGlkS2V5KG9iamVjdCBvYikgewogIHJldHVybiAob2JqZWN0cChvYikgJiYgKG9iLT5pZCgic2NobHVlc3NlbCIpIHx8IG9iLT5RdWVyeURvb3JLZXkoKSE9MCkpOwp9CgovLyBHaWJ0IGRpZSBOdW1tZXIgZGVzIG5hZWNoc3RlbiBmcmVpZW4gSGFrZW5zIHp1cnVlY2sgb2RlciAwLCB3ZW5uCi8vIGtlaW5lciBmcmVpIGlzdC4gRGEgTWFwcGluZ3MgbmljaHQgc29ydGllcnQgc2luZCwgbXVzcyB2b24gMS0xNiBudW1lcmlzY2gKLy8gaXRlcmllcnQgd2VyZGVuLCBkYW1pdCBpbW1lciBkZXIgZXJzdGUgZnJlaWUgSGFrZW4gZ2VmdW5kZW4gd2lyZCB1bmQgbmljaHQgCi8vIGlyZ2VuZGVpbmVyLgovLyBSdWVja2dhYmV3ZXJ0OiBIYWtlbm51bW1lciB2b24gMS0xNiBvZGVyIDAsIHdlbm4ga2VpbiBIYWtlbiBmcmVpIGlzdC4KcHJpdmF0ZSBpbnQgR2V0TmV4dEZyZWVTbG90KCkgewogIGludCBzbG90OwogIGZvcmVhY2goaW50IGkgOiAxLi4xNikgewogICAgaWYgKCAhb2JqZWN0cChoYWtlbltpLEhPT0tfT0JdKSApIHsKICAgICAgc2xvdCA9IGk7CiAgICAgIGJyZWFrOwogICAgfQogIH0KICByZXR1cm4gc2xvdDsKfQoKLy8gR2lidCB6dSBlaW5lciBTY2hpbGQtQmVzY2hyaWZ0dW5nIGRpZSB6dWdlaG9lcmlnZSBIYWtlbnBvc2l0aW9uIGF1cy4KLy8gRXMgd2lyZCBkaWUga2xlaW5nZXNjaHJpZWJlbmUgVmFyaWFudGUgZ2VzdWNodCwgc28gZGFzcyBTcGllbGVyIHp3YXIKLy8gR3Jvc3NzY2hyZWlidW5nIGluIGRlbiBCZXNjaHJpZnR1bmdlbiB2ZXJ3ZW5kZW4ga29lbm5lbiwgZGllc2UgYWJlcgovLyBuaWNodCBiZXJ1ZWNrc2ljaHRpZ3Qgd2lyZC4gQW5zb25zdGVuIGtvZW5udGUgZXMgenUgU2Nod2llcmlna2VpdGVuIG1pdAovLyBEb3BwbHVuZ2VuIHdpZSAiVmVzcmF5IiB1bmQgInZlc3JheSIga29tbWVuLgovLyBSdWVja2dhYmV3ZXJ0OiBIYWtlbm51bW1lciB2b24gMS0xNiBvZGVyIDAsIHdlbm4gZGVyIFRleHQgbmljaHQgZ2VmdW5kZW4KLy8gd3VyZGUuCnByaXZhdGUgb2JqZWN0IEdldEtleUZvckxhYmVsKHN0cmluZyBsYWJlbCkgewogIGlmICggbGFiZWwgKSAKICAgIGxhYmVsID0gbG93ZXJfY2FzZShsYWJlbCk7CiAgZm9yZWFjaChpbnQgaTogMS4uMTYpIHsKICAgIGlmICggaGFrZW5baSwgSE9PS19MQUJFTF0gJiYgbGFiZWwgJiYKICAgICAgICAgbG93ZXJfY2FzZShoYWtlbltpLEhPT0tfTEFCRUxdKSA9PSBsYWJlbCApCiAgICAgIHJldHVybiBoYWtlbltpLEhPT0tfT0JdOwogIH0KICByZXR1cm4gMDsKfQoKLy8gR2lidCB6dSBkZW0gdWViZXJnZWJlbmVuIE9iamVrdCBkaWUgTnVtbWVyIGRlcyBIYWtlbnMgenVydWVjaywgYW4gZGVtCi8vIGVzIGhhZW5ndC4KcHJpdmF0ZSBpbnQgR2V0SG9va051bWJlckZvcktleShvYmplY3Qgb2IpIHsKICBmb3JlYWNoKGludCBudW0sIG9iamVjdCBrZXkgOiBoYWtlbikgewogICAgaWYgKCBrZXkgPT0gb2IgKQogICAgICByZXR1cm4gbnVtOwogIH0KICByZXR1cm4gMDsKfQoKLy8gQmVyZWluaWd0IERhdGVuc3RydWt0dXIgaW4gPGhha2VuPiB1bmQgZGFzIEludmVudGFyIGRlcyBCcmV0dGVzLCBpbmRlbQovLyBhKSBnZXBydWVmdCB3aXJkLCBvYiBhbGxlIGluIDxoYWtlbj4gZWluZ2V0cmFnZW5lbiBPYmpla3RlIHNpY2ggYXVjaCBpbSAKLy8gICAgQnJldHQgYmVmaW5kZW4gdW5kCi8vIGIpIGdlcHJ1ZWZ0IHdpcmQsIG9iIGFsbGUgaW0gSW52ZW50YXIgYmVmaW5kbGljaGVuIE9iamVrdGUgYXVjaCBrb3JyZWt0IGluIAovLyAgICA8aGFrZW4+IGVpbmdldHJhZ2VuIHNpbmQuCi8vIFVlYmVyemFlaGxpZ2UgT2JqZWt0ZSB3ZXJkZW4gcmF1c2dld29yZmVuLgpwcml2YXRlIHZvaWQgQ29uc29saWRhdGVJbnZlbnRvcnkoKSB7CiAgZm9yZWFjaChpbnQgaSwgb2JqZWN0IG9iIDogaGFrZW4pIHsKICAgIC8vIE9iamVrdCBleGlzdGllcnQsIGlzdCBhYmVyIG5pY2h0IGltIFNjaGx1ZXNzZWxicmV0dD8gRGFubiBhdXN0cmFnZW4uCiAgICBpZiAob2JqZWN0cChvYikgJiYgZW52aXJvbm1lbnQob2IpICE9IE1FKSB7CiAgICAgIG1fZGVsZXRlKGhha2VuLCBpKTsKICAgICAgLy8gV2lyZCBhdWNoIHZvbSByZXNldCgpIGF1cyBnZXJ1ZmVuLCBkYW5uIGlzdCBUUCA9PSAwLgogICAgICBpZiAoIG9iamVjdHAoVFApICkKICAgICAgICB0ZWxsX29iamVjdChUUCwgQlMoIkhvcHBsYSEgIitvYi0+TmFtZShXRVIsMSkrIiBzY2hlaW50IHZvbSAiCiAgICAgICAgICAiU2NobHVlc3NlbGJyZXR0IHZlcnNjaHd1bmRlbiB6dSBzZWluISIpKTsKICAgIH0KICB9CiAgb2JqZWN0ICpyZXN0ZXJhbXBlID0gYWxsX2ludmVudG9yeShNRSkgLSBtX3ZhbHVlcyhoYWtlbiwgSE9PS19PQik7CiAgaWYgKHNpemVvZihyZXN0ZXJhbXBlKSkgewogICAgcmVzdGVyYW1wZS0+bW92ZShlbnZpcm9ubWVudCgpLE1fUFVUKTsKICAgIHRlbGxfcm9vbShlbnZpcm9ubWVudCgpLCBCUygiUGxvZXR6bGljaCBmYWVsbHQgZXR3YXMgdm9tICIKICAgICAgIlNjaGx1ZXNzZWxicmV0dCB6dSBCb2RlbiwgZGFzIER1IHp1dm9yIGdhciBuaWNodCBnZXNlaGVuIGhhdHRlc3QuIikpOwogIH0KfQoKc3RyaW5nIHNob3J0KCkgewogIHN0cmluZyBzaD1RdWVyeVByb3AoUF9TSE9SVCk7CgogIC8vIFVuc2ljaHRiYXI/IERhbm4gZ2lidHMgbmljaHRzIHp1IHNlaGVuIC4uLgogIGlmICggUXVlcnlQcm9wKFBfSU5WSVMpIHx8ICFzaCApCiAgICByZXR1cm4gMDsKICBpZiAoIFF1ZXJ5UHJvcCgidmVyc3RlY2t0IikgPT0gMSApIAogICAgc2ggPSAiIjsKICBlbHNlIAogICAgc2ggKz0gIi4iOwoKICByZXR1cm4gcHJvY2Vzc19zdHJpbmcoc2gpKyJcbiI7Cn0KCi8vIEltIFJlc2V0IHZvcnNpY2h0c2hhbGJlciBhdWNoIG1hbCBhdWZyYWV1bWVuLgp2b2lkIHJlc2V0KCkgewogIENvbnNvbGlkYXRlSW52ZW50b3J5KCk7CiAgcmV0dXJuIDo6cmVzZXQoKTsKfQoKdmFyYXJncyBpbnQgUHJldmVudEluc2VydChvYmplY3Qgb2IpIHsKICAvLyBLZWluIFNjaGx1ZXNzZWw/IEhhdCBpbiBkaWVzZW0gQ29udGFpbmVyIG5peCB2ZXJsb3JlbiEKICBpZiggIUlzVmFsaWRLZXkob2IgKSkgewogICAgcmV0dXJuIDE7CiAgfQogIENvbnNvbGlkYXRlSW52ZW50b3J5KCk7CiAgcmV0dXJuIDo6UHJldmVudEluc2VydChvYik7Cn0KCi8vIFdlbm4gZWluIFNjaGx1ZXNzZWwgc2ljaCBhdWZsb2VzdCwgbXVzcyBkaWUgTGlzdGUgYWJnZWdsaWNoZW4gd2VyZGVuLgp2b2lkIE5vdGlmeVJlbW92ZShvYmplY3Qgb2IpIHsKICB0ZWxsX3Jvb20oZW52aXJvbm1lbnQoTUUpLCBCUygiSG9wcGxhISAiK29iLT5OYW1lKFdFUiwxKSsiIGhhdCBzaWNoICIKICAgICJnZXJhZGUgaW4gV29obGdlZmFsbGVuIGF1ZmdlbG9lc3QuIikpOwogIC8vIERhcyBPYmpla3QgPG9iPiB6ZXJzdG9lcnQgc2ljaCBlcnN0IG5hY2ggZGVtIEF1ZnJ1ZiBkaWVzZXIgRnVua3Rpb24sCiAgLy8gZGFoZXIgcGVyIGNhbGxfb3V0KCkgYXVmcmFldW1lbi4KICBjYWxsX291dCgjJ0NvbnNvbGlkYXRlSW52ZW50b3J5LCAxKTsKfQoKLy8gWmVzc3RyYSwgMS43LjA3LCBmdWVycyBIb2Vycm9ocgovLyBEYXJmIGljaCBkYSBBcmF0aG9ybiBlaW50cmFnZW4/IDstKQpzdHJpbmcgR2V0T3duZXIoKSB7CiAgcmV0dXJuICJzZWxldmVuIjsKfQoK