IyAtKi0gY29kaW5nOiBpc28tODg1OS0xIC0qLQoiIiIgQSBTQVgyIGRyaXZlciBmb3IgbGlieG1sMiwgb24gdG9wIG9mIGl0J3MgWG1sUmVhZGVyIEFQSQoKVVNBR0UKICAgICMgcHV0IHRoaXMgZmlsZSAoZHJ2X2xpYnhtbDIucHkpIGluIFBZVEhPTlBBVEgKICAgIGltcG9ydCB4bWwuc2F4CiAgICByZWFkZXIgPSB4bWwuc2F4Lm1ha2VfcGFyc2VyKFsiZHJ2X2xpYnhtbDIiXSkKICAgICMgLi4uYW5kIHRoZSByZXN0IGlzIHN0YW5kYXJkIHB5dGhvbiBzYXguCgpDQVZFQVRTCiAgICAtIExleGljYWwgaGFuZGxlcnMgYXJlIHN1cHBvcnRlZCwgZXhjZXB0IGZvciBzdGFydC9lbmRFbnRpdHkKICAgICAgKHdhaXRpbmcgZm9yIFhtbFJlYWRlci5SZXNvbHZlRW50aXR5KSBhbmQgc3RhcnQvZW5kRFRECiAgICAtIEVycm9yIGNhbGxiYWNrcyBhcmUgbm90IGV4YWN0bHkgc3luY2hyb25vdXMsIHRoZXkgdGVuZAogICAgICB0byBiZSBpbnZva2VkIGJlZm9yZSB0aGUgY29ycmVzcG9uZGluZyBjb250ZW50IGNhbGxiYWNrLAogICAgICBiZWNhdXNlIHRoZSB1bmRlcmx5aW5nIHJlYWRlciBpbnRlcmZhY2UgcGFyc2VzCiAgICAgIGRhdGEgYnkgY2h1bmtzIG9mIDUxMiBieXRlcwogICAgClRPRE8KICAgIC0gc2VhcmNoIGZvciBUT0RPCiAgICAtIHNvbWUgRXJyb3JIYW5kbGVyIGV2ZW50cyAod2FybmluZykKICAgIC0gc29tZSBDb250ZW50SGFuZGxlciBldmVudHMgKHNldERvY3VtZW50TG9jYXRvciwgc2tpcHBlZEVudGl0eSkKICAgIC0gRW50aXR5UmVzb2x2ZXIgKHVzaW5nIGxpYnhtbDIuPykKICAgIC0gRFRESGFuZGxlciAoaWYvd2hlbiBsaWJ4bWwyIGV4cG9zZXMgc3VjaCBub2RlIHR5cGVzKQogICAgLSBEZWNsSGFuZGxlciAoaWYvd2hlbiBsaWJ4bWwyIGV4cG9zZXMgc3VjaCBub2RlIHR5cGVzKQogICAgLSBwcm9wZXJ0eV94bWxfc3RyaW5nPwogICAgLSBmZWF0dXJlX3N0cmluZ19pbnRlcm5pbmc/CiAgICAtIEluY3JlbWVudGFsIHBhcnNlcgogICAgLSBhZGRpdGlvbmFsIHBlcmZvcm1hbmNlIHR1bmluZzoKICAgICAgLSBvbmUgbWlnaHQgY2FjaGUgY2FsbGJhY2tzIHRvIGF2b2lkIHNvbWUgbmFtZSBsb29rdXBzCiAgICAgIC0gb25lIG1pZ2h0IGltcGxlbWVudCBhIHNtYXJ0ZXIgd2F5IHRvIHBhc3MgYXR0cmlidXRlcyB0byBzdGFydEVsZW1lbnQKICAgICAgICAoc29tZSBraW5kIG9mIGxhenkgZXZhbHVhdGlvbj8pCiAgICAgIC0gdGhlcmUgbWlnaHQgYmUgcm9vbSBmb3IgaW1wcm92ZW1lbnQgaW4gc3RhcnQvZW5kUHJlZml4TWFwcGluZwogICAgICAtIG90aGVyPwoKIiIiCgpfX2F1dGhvcl9fICA9ICJTdOlwaGFuZSBCaWRvdWwgPHNiaUBza3luZXQuYmU+IgpfX3ZlcnNpb25fXyA9ICIwLjMiCgppbXBvcnQgc3lzCmltcG9ydCBjb2RlY3MKCmlmIHN5cy52ZXJzaW9uX2luZm9bMF0gPCAzOgogICAgX19hdXRob3JfXyAgPSBjb2RlY3MudW5pY29kZV9lc2NhcGVfZGVjb2RlKF9fYXV0aG9yX18pWzBdCgogICAgU3RyaW5nVHlwZXMgPSAoc3RyLCB1bmljb2RlKQplbHNlOgogICAgU3RyaW5nVHlwZXMgPSBzdHIKCmZyb20geG1sLnNheC5fZXhjZXB0aW9ucyBpbXBvcnQgKgpmcm9tIHhtbC5zYXggaW1wb3J0IHhtbHJlYWRlciwgc2F4dXRpbHMKZnJvbSB4bWwuc2F4LmhhbmRsZXIgaW1wb3J0IFwKICAgICBmZWF0dXJlX25hbWVzcGFjZXMsIFwKICAgICBmZWF0dXJlX25hbWVzcGFjZV9wcmVmaXhlcywgXAogICAgIGZlYXR1cmVfc3RyaW5nX2ludGVybmluZywgXAogICAgIGZlYXR1cmVfdmFsaWRhdGlvbiwgXAogICAgIGZlYXR1cmVfZXh0ZXJuYWxfZ2VzLCBcCiAgICAgZmVhdHVyZV9leHRlcm5hbF9wZXMsIFwKICAgICBwcm9wZXJ0eV9sZXhpY2FsX2hhbmRsZXIsIFwKICAgICBwcm9wZXJ0eV9kZWNsYXJhdGlvbl9oYW5kbGVyLCBcCiAgICAgcHJvcGVydHlfZG9tX25vZGUsIFwKICAgICBwcm9wZXJ0eV94bWxfc3RyaW5nCgojIGxpYnhtbDIgcmV0dXJucyBzdHJpbmdzIGFzIFVURjgKX2RlY29kZXIgPSBjb2RlY3MubG9va3VwKCJ1dGY4IilbMV0KZGVmIF9kKHMpOgogICAgaWYgcyBpcyBOb25lOgogICAgICAgIHJldHVybiBzCiAgICBlbHNlOgogICAgICAgIHJldHVybiBfZGVjb2RlcihzKVswXQoKdHJ5OgogICAgaW1wb3J0IGxpYnhtbDIKZXhjZXB0IEltcG9ydEVycm9yOgogICAgcmFpc2UgU0FYUmVhZGVyTm90QXZhaWxhYmxlKCJsaWJ4bWwyIG5vdCBhdmFpbGFibGU6ICIgXAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJpbXBvcnQgZXJyb3Igd2FzOiAlcyIgJSBzeXMuZXhjX2luZm8oKVsxXSkKCmNsYXNzIExvY2F0b3IoeG1scmVhZGVyLkxvY2F0b3IpOgogICAgIiIiU0FYIExvY2F0b3IgYWRhcHRlciBmb3IgbGlieG1sMi54bWxUZXh0UmVhZGVyTG9jYXRvciIiIgoKICAgIGRlZiBfX2luaXRfXyhzZWxmLGxvY2F0b3IpOgogICAgICAgIHNlbGYuX19sb2NhdG9yID0gbG9jYXRvcgoKICAgIGRlZiBnZXRDb2x1bW5OdW1iZXIoc2VsZik6CiAgICAgICAgIlJldHVybiB0aGUgY29sdW1uIG51bWJlciB3aGVyZSB0aGUgY3VycmVudCBldmVudCBlbmRzLiIKICAgICAgICByZXR1cm4gLTEKCiAgICBkZWYgZ2V0TGluZU51bWJlcihzZWxmKToKICAgICAgICAiUmV0dXJuIHRoZSBsaW5lIG51bWJlciB3aGVyZSB0aGUgY3VycmVudCBldmVudCBlbmRzLiIKICAgICAgICByZXR1cm4gc2VsZi5fX2xvY2F0b3IuTGluZU51bWJlcigpCgogICAgZGVmIGdldFB1YmxpY0lkKHNlbGYpOgogICAgICAgICJSZXR1cm4gdGhlIHB1YmxpYyBpZGVudGlmaWVyIGZvciB0aGUgY3VycmVudCBldmVudC4iCiAgICAgICAgcmV0dXJuIE5vbmUKCiAgICBkZWYgZ2V0U3lzdGVtSWQoc2VsZik6CiAgICAgICAgIlJldHVybiB0aGUgc3lzdGVtIGlkZW50aWZpZXIgZm9yIHRoZSBjdXJyZW50IGV2ZW50LiIKICAgICAgICByZXR1cm4gc2VsZi5fX2xvY2F0b3IuQmFzZVVSSSgpCgpjbGFzcyBMaWJYbWwyUmVhZGVyKHhtbHJlYWRlci5YTUxSZWFkZXIpOgoKICAgIGRlZiBfX2luaXRfXyhzZWxmKToKICAgICAgICB4bWxyZWFkZXIuWE1MUmVhZGVyLl9faW5pdF9fKHNlbGYpCiAgICAgICAgIyBmZWF0dXJlcwogICAgICAgIHNlbGYuX19ucyA9IDAKICAgICAgICBzZWxmLl9fbnNwZnggPSAwCiAgICAgICAgc2VsZi5fX3ZhbGlkYXRlID0gMAogICAgICAgIHNlbGYuX19leHRwYXJhbXMgPSAxCiAgICAgICAgIyBwYXJzaW5nIGZsYWcKICAgICAgICBzZWxmLl9fcGFyc2luZyA9IDAKICAgICAgICAjIGFkZGl0aW9uYWwgaGFuZGxlcnMKICAgICAgICBzZWxmLl9fbGV4X2hhbmRsZXIgPSBOb25lCiAgICAgICAgc2VsZi5fX2RlY2xfaGFuZGxlciA9IE5vbmUKICAgICAgICAjIGVycm9yIG1lc3NhZ2VzIGFjY3VtdWxhdG9yCiAgICAgICAgc2VsZi5fX2Vycm9ycyA9IE5vbmUKCiAgICBkZWYgX2Vycm9ySGFuZGxlcihzZWxmLGFyZyxtc2csc2V2ZXJpdHksbG9jYXRvcik6CiAgICAgICAgaWYgc2VsZi5fX2Vycm9ycyBpcyBOb25lOgogICAgICAgICAgICBzZWxmLl9fZXJyb3JzID0gW10KICAgICAgICBzZWxmLl9fZXJyb3JzLmFwcGVuZCgoc2V2ZXJpdHksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFNBWFBhcnNlRXhjZXB0aW9uKG1zZyxOb25lLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMb2NhdG9yKGxvY2F0b3IpKSkpCgogICAgZGVmIF9yZXBvcnRFcnJvcnMoc2VsZixmYXRhbCk6CiAgICAgICAgZm9yIHNldmVyaXR5LGV4Y2VwdGlvbiBpbiBzZWxmLl9fZXJyb3JzOgogICAgICAgICAgICBpZiBzZXZlcml0eSBpbiAobGlieG1sMi5QQVJTRVJfU0VWRVJJVFlfVkFMSURJVFlfV0FSTklORywKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxpYnhtbDIuUEFSU0VSX1NFVkVSSVRZX1dBUk5JTkcpOgogICAgICAgICAgICAgICAgc2VsZi5fZXJyX2hhbmRsZXIud2FybmluZyhleGNlcHRpb24pCiAgICAgICAgICAgIGVsc2U6CiAgICAgICAgICAgICAgICAjIHdoZW4gZmF0YWwgaXMgc2V0LCB0aGUgcGFyc2Ugd2lsbCBzdG9wOwogICAgICAgICAgICAgICAgIyB3ZSBjb25zaWRlciB0aGF0IHRoZSBsYXN0IGVycm9yIHJlcG9ydGVkCiAgICAgICAgICAgICAgICAjIGlzIHRoZSBmYXRhbCBvbmUuCiAgICAgICAgICAgICAgICBpZiBmYXRhbCBhbmQgZXhjZXB0aW9uIGlzIHNlbGYuX19lcnJvcnNbLTFdWzFdOgogICAgICAgICAgICAgICAgICAgIHNlbGYuX2Vycl9oYW5kbGVyLmZhdGFsRXJyb3IoZXhjZXB0aW9uKQogICAgICAgICAgICAgICAgZWxzZToKICAgICAgICAgICAgICAgICAgICBzZWxmLl9lcnJfaGFuZGxlci5lcnJvcihleGNlcHRpb24pCiAgICAgICAgc2VsZi5fX2Vycm9ycyA9IE5vbmUKCiAgICBkZWYgcGFyc2Uoc2VsZiwgc291cmNlKToKICAgICAgICBzZWxmLl9fcGFyc2luZyA9IDEKICAgICAgICB0cnk6CiAgICAgICAgICAgICMgcHJlcGFyZSBzb3VyY2UgYW5kIGNyZWF0ZSByZWFkZXIKICAgICAgICAgICAgaWYgaXNpbnN0YW5jZShzb3VyY2UsIFN0cmluZ1R5cGVzKToKICAgICAgICAgICAgICAgIHJlYWRlciA9IGxpYnhtbDIubmV3VGV4dFJlYWRlckZpbGVuYW1lKHNvdXJjZSkKICAgICAgICAgICAgZWxzZToKICAgICAgICAgICAgICAgIHNvdXJjZSA9IHNheHV0aWxzLnByZXBhcmVfaW5wdXRfc291cmNlKHNvdXJjZSkKICAgICAgICAgICAgICAgIGlucHV0ID0gbGlieG1sMi5pbnB1dEJ1ZmZlcihzb3VyY2UuZ2V0Qnl0ZVN0cmVhbSgpKQogICAgICAgICAgICAgICAgcmVhZGVyID0gaW5wdXQubmV3VGV4dFJlYWRlcihzb3VyY2UuZ2V0U3lzdGVtSWQoKSkKICAgICAgICAgICAgcmVhZGVyLlNldEVycm9ySGFuZGxlcihzZWxmLl9lcnJvckhhbmRsZXIsTm9uZSkKICAgICAgICAgICAgIyBjb25maWd1cmUgcmVhZGVyCiAgICAgICAgICAgIGlmIHNlbGYuX19leHRwYXJhbXM6CiAgICAgICAgICAgICAgICByZWFkZXIuU2V0UGFyc2VyUHJvcChsaWJ4bWwyLlBBUlNFUl9MT0FERFRELDEpCiAgICAgICAgICAgICAgICByZWFkZXIuU2V0UGFyc2VyUHJvcChsaWJ4bWwyLlBBUlNFUl9ERUZBVUxUQVRUUlMsMSkKICAgICAgICAgICAgICAgIHJlYWRlci5TZXRQYXJzZXJQcm9wKGxpYnhtbDIuUEFSU0VSX1NVQlNUX0VOVElUSUVTLDEpCiAgICAgICAgICAgICAgICByZWFkZXIuU2V0UGFyc2VyUHJvcChsaWJ4bWwyLlBBUlNFUl9WQUxJREFURSxzZWxmLl9fdmFsaWRhdGUpCiAgICAgICAgICAgIGVsc2U6CiAgICAgICAgICAgICAgICByZWFkZXIuU2V0UGFyc2VyUHJvcChsaWJ4bWwyLlBBUlNFUl9MT0FERFRELCAwKQogICAgICAgICAgICAjIHdlIHJldXNlIGF0dHJpYnV0ZSBtYXBzIChmb3IgYSBzbGlnaHQgcGVyZm9ybWFuY2UgZ2FpbikKICAgICAgICAgICAgaWYgc2VsZi5fX25zOgogICAgICAgICAgICAgICAgYXR0cmlidXRlc05TSW1wbCA9IHhtbHJlYWRlci5BdHRyaWJ1dGVzTlNJbXBsKHt9LHt9KQogICAgICAgICAgICBlbHNlOgogICAgICAgICAgICAgICAgYXR0cmlidXRlc0ltcGwgPSB4bWxyZWFkZXIuQXR0cmlidXRlc0ltcGwoe30pCiAgICAgICAgICAgICMgcHJlZml4ZXMgdG8gcG9wIChmb3IgZW5kUHJlZml4TWFwcGluZykKICAgICAgICAgICAgcHJlZml4ZXMgPSBbXQogICAgICAgICAgICAjIHN0YXJ0IGxvb3AKICAgICAgICAgICAgc2VsZi5fY29udF9oYW5kbGVyLnN0YXJ0RG9jdW1lbnQoKQogICAgICAgICAgICB3aGlsZSAxOgogICAgICAgICAgICAgICAgciA9IHJlYWRlci5SZWFkKCkKICAgICAgICAgICAgICAgICMgY2hlY2sgZm9yIGVycm9ycwogICAgICAgICAgICAgICAgaWYgciA9PSAxOgogICAgICAgICAgICAgICAgICAgIGlmIG5vdCBzZWxmLl9fZXJyb3JzIGlzIE5vbmU6CiAgICAgICAgICAgICAgICAgICAgICAgIHNlbGYuX3JlcG9ydEVycm9ycygwKQogICAgICAgICAgICAgICAgZWxpZiByID09IDA6CiAgICAgICAgICAgICAgICAgICAgaWYgbm90IHNlbGYuX19lcnJvcnMgaXMgTm9uZToKICAgICAgICAgICAgICAgICAgICAgICAgc2VsZi5fcmVwb3J0RXJyb3JzKDApCiAgICAgICAgICAgICAgICAgICAgYnJlYWsgIyBlbmQgb2YgcGFyc2UKICAgICAgICAgICAgICAgIGVsc2U6CiAgICAgICAgICAgICAgICAgICAgaWYgbm90IHNlbGYuX19lcnJvcnMgaXMgTm9uZToKICAgICAgICAgICAgICAgICAgICAgICAgc2VsZi5fcmVwb3J0RXJyb3JzKDEpCiAgICAgICAgICAgICAgICAgICAgZWxzZToKICAgICAgICAgICAgICAgICAgICAgICAgc2VsZi5fZXJyX2hhbmRsZXIuZmF0YWxFcnJvcihcCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBTQVhFeGNlcHRpb24oIlJlYWQgZmFpbGVkIChubyBkZXRhaWxzIGF2YWlsYWJsZSkiKSkKICAgICAgICAgICAgICAgICAgICBicmVhayAjIGZhdGFsIHBhcnNlIGVycm9yCiAgICAgICAgICAgICAgICAjIGdldCBub2RlIHR5cGUKICAgICAgICAgICAgICAgIG5vZGVUeXBlID0gcmVhZGVyLk5vZGVUeXBlKCkKICAgICAgICAgICAgICAgICMgRWxlbWVudAogICAgICAgICAgICAgICAgaWYgbm9kZVR5cGUgPT0gMTogCiAgICAgICAgICAgICAgICAgICAgaWYgc2VsZi5fX25zOgogICAgICAgICAgICAgICAgICAgICAgICBlbHROYW1lID0gKF9kKHJlYWRlci5OYW1lc3BhY2VVcmkoKSksXAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIF9kKHJlYWRlci5Mb2NhbE5hbWUoKSkpCiAgICAgICAgICAgICAgICAgICAgICAgIGVsdFFOYW1lID0gX2QocmVhZGVyLk5hbWUoKSkKICAgICAgICAgICAgICAgICAgICAgICAgYXR0cmlidXRlc05TSW1wbC5fYXR0cnMgPSBhdHRycyA9IHt9CiAgICAgICAgICAgICAgICAgICAgICAgIGF0dHJpYnV0ZXNOU0ltcGwuX3FuYW1lcyA9IHFuYW1lcyA9IHt9CiAgICAgICAgICAgICAgICAgICAgICAgIG5ld1ByZWZpeGVzID0gW10KICAgICAgICAgICAgICAgICAgICAgICAgd2hpbGUgcmVhZGVyLk1vdmVUb05leHRBdHRyaWJ1dGUoKToKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHFuYW1lID0gX2QocmVhZGVyLk5hbWUoKSkKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhbHVlID0gX2QocmVhZGVyLlZhbHVlKCkpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiBxbmFtZS5zdGFydHN3aXRoKCJ4bWxucyIpOgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIGxlbihxbmFtZSkgPiA1OgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXdQcmVmaXggPSBxbmFtZVs2Ol0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlOgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXdQcmVmaXggPSBOb25lCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV3UHJlZml4ZXMuYXBwZW5kKG5ld1ByZWZpeCkKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZWxmLl9jb250X2hhbmRsZXIuc3RhcnRQcmVmaXhNYXBwaW5nKFwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV3UHJlZml4LHZhbHVlKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIG5vdCBzZWxmLl9fbnNwZng6CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlICMgZG9uJ3QgcmVwb3J0IHhtbG5zIGF0dHJpYnV0ZQogICAgICAgICAgICAgICAgICAgICAgICAgICAgYXR0TmFtZSA9IChfZChyZWFkZXIuTmFtZXNwYWNlVXJpKCkpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBfZChyZWFkZXIuTG9jYWxOYW1lKCkpKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgcW5hbWVzW2F0dE5hbWVdID0gcW5hbWUKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGF0dHJzW2F0dE5hbWVdID0gdmFsdWUKICAgICAgICAgICAgICAgICAgICAgICAgcmVhZGVyLk1vdmVUb0VsZW1lbnQoKQogICAgICAgICAgICAgICAgICAgICAgICBzZWxmLl9jb250X2hhbmRsZXIuc3RhcnRFbGVtZW50TlMoIFwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsdE5hbWUsZWx0UU5hbWUsYXR0cmlidXRlc05TSW1wbCkgCiAgICAgICAgICAgICAgICAgICAgICAgIGlmIHJlYWRlci5Jc0VtcHR5RWxlbWVudCgpOgogICAgICAgICAgICAgICAgICAgICAgICAgICAgc2VsZi5fY29udF9oYW5kbGVyLmVuZEVsZW1lbnROUyhlbHROYW1lLGVsdFFOYW1lKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgZm9yIG5ld1ByZWZpeCBpbiBuZXdQcmVmaXhlczoKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZWxmLl9jb250X2hhbmRsZXIuZW5kUHJlZml4TWFwcGluZyhuZXdQcmVmaXgpCiAgICAgICAgICAgICAgICAgICAgICAgIGVsc2U6CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBwcmVmaXhlcy5hcHBlbmQobmV3UHJlZml4ZXMpCiAgICAgICAgICAgICAgICAgICAgZWxzZToKICAgICAgICAgICAgICAgICAgICAgICAgZWx0TmFtZSA9IF9kKHJlYWRlci5OYW1lKCkpCiAgICAgICAgICAgICAgICAgICAgICAgIGF0dHJpYnV0ZXNJbXBsLl9hdHRycyA9IGF0dHJzID0ge30KICAgICAgICAgICAgICAgICAgICAgICAgd2hpbGUgcmVhZGVyLk1vdmVUb05leHRBdHRyaWJ1dGUoKToKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGF0dE5hbWUgPSBfZChyZWFkZXIuTmFtZSgpKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgYXR0cnNbYXR0TmFtZV0gPSBfZChyZWFkZXIuVmFsdWUoKSkKICAgICAgICAgICAgICAgICAgICAgICAgcmVhZGVyLk1vdmVUb0VsZW1lbnQoKQogICAgICAgICAgICAgICAgICAgICAgICBzZWxmLl9jb250X2hhbmRsZXIuc3RhcnRFbGVtZW50KCBcCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHROYW1lLGF0dHJpYnV0ZXNJbXBsKQogICAgICAgICAgICAgICAgICAgICAgICBpZiByZWFkZXIuSXNFbXB0eUVsZW1lbnQoKToKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNlbGYuX2NvbnRfaGFuZGxlci5lbmRFbGVtZW50KGVsdE5hbWUpCiAgICAgICAgICAgICAgICAjIEVuZEVsZW1lbnQKICAgICAgICAgICAgICAgIGVsaWYgbm9kZVR5cGUgPT0gMTU6IAogICAgICAgICAgICAgICAgICAgIGlmIHNlbGYuX19uczoKICAgICAgICAgICAgICAgICAgICAgICAgc2VsZi5fY29udF9oYW5kbGVyLmVuZEVsZW1lbnROUyggXAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIChfZChyZWFkZXIuTmFtZXNwYWNlVXJpKCkpLF9kKHJlYWRlci5Mb2NhbE5hbWUoKSkpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIF9kKHJlYWRlci5OYW1lKCkpKQogICAgICAgICAgICAgICAgICAgICAgICBmb3IgcHJlZml4IGluIHByZWZpeGVzLnBvcCgpOgogICAgICAgICAgICAgICAgICAgICAgICAgICAgc2VsZi5fY29udF9oYW5kbGVyLmVuZFByZWZpeE1hcHBpbmcocHJlZml4KQogICAgICAgICAgICAgICAgICAgIGVsc2U6CiAgICAgICAgICAgICAgICAgICAgICAgIHNlbGYuX2NvbnRfaGFuZGxlci5lbmRFbGVtZW50KF9kKHJlYWRlci5OYW1lKCkpKQogICAgICAgICAgICAgICAgIyBUZXh0CiAgICAgICAgICAgICAgICBlbGlmIG5vZGVUeXBlID09IDM6IAogICAgICAgICAgICAgICAgICAgIHNlbGYuX2NvbnRfaGFuZGxlci5jaGFyYWN0ZXJzKF9kKHJlYWRlci5WYWx1ZSgpKSkKICAgICAgICAgICAgICAgICMgV2hpdGVzcGFjZQogICAgICAgICAgICAgICAgZWxpZiBub2RlVHlwZSA9PSAxMzogCiAgICAgICAgICAgICAgICAgICAgc2VsZi5fY29udF9oYW5kbGVyLmlnbm9yYWJsZVdoaXRlc3BhY2UoX2QocmVhZGVyLlZhbHVlKCkpKQogICAgICAgICAgICAgICAgIyBTaWduaWZpY2FudFdoaXRlc3BhY2UKICAgICAgICAgICAgICAgIGVsaWYgbm9kZVR5cGUgPT0gMTQ6CiAgICAgICAgICAgICAgICAgICAgc2VsZi5fY29udF9oYW5kbGVyLmNoYXJhY3RlcnMoX2QocmVhZGVyLlZhbHVlKCkpKQogICAgICAgICAgICAgICAgIyBDREFUQQogICAgICAgICAgICAgICAgZWxpZiBub2RlVHlwZSA9PSA0OgogICAgICAgICAgICAgICAgICAgIGlmIG5vdCBzZWxmLl9fbGV4X2hhbmRsZXIgaXMgTm9uZToKICAgICAgICAgICAgICAgICAgICAgICAgc2VsZi5fX2xleF9oYW5kbGVyLnN0YXJ0Q0RBVEEoKQogICAgICAgICAgICAgICAgICAgIHNlbGYuX2NvbnRfaGFuZGxlci5jaGFyYWN0ZXJzKF9kKHJlYWRlci5WYWx1ZSgpKSkKICAgICAgICAgICAgICAgICAgICBpZiBub3Qgc2VsZi5fX2xleF9oYW5kbGVyIGlzIE5vbmU6CiAgICAgICAgICAgICAgICAgICAgICAgIHNlbGYuX19sZXhfaGFuZGxlci5lbmRDREFUQSgpCiAgICAgICAgICAgICAgICAjIEVudGl0eVJlZmVyZW5jZQogICAgICAgICAgICAgICAgZWxpZiBub2RlVHlwZSA9PSA1OgogICAgICAgICAgICAgICAgICAgIGlmIG5vdCBzZWxmLl9fbGV4X2hhbmRsZXIgaXMgTm9uZToKICAgICAgICAgICAgICAgICAgICAgICAgc2VsZi5zdGFydEVudGl0eShfZChyZWFkZXIuTmFtZSgpKSkKICAgICAgICAgICAgICAgICAgICByZWFkZXIuUmVzb2x2ZUVudGl0eSgpCiAgICAgICAgICAgICAgICAjIEVuZEVudGl0eQogICAgICAgICAgICAgICAgZWxpZiBub2RlVHlwZSA9PSAxNjoKICAgICAgICAgICAgICAgICAgICBpZiBub3Qgc2VsZi5fX2xleF9oYW5kbGVyIGlzIE5vbmU6CiAgICAgICAgICAgICAgICAgICAgICAgIHNlbGYuZW5kRW50aXR5KF9kKHJlYWRlci5OYW1lKCkpKQogICAgICAgICAgICAgICAgIyBQcm9jZXNzaW5nSW5zdHJ1Y3Rpb24KICAgICAgICAgICAgICAgIGVsaWYgbm9kZVR5cGUgPT0gNzogCiAgICAgICAgICAgICAgICAgICAgc2VsZi5fY29udF9oYW5kbGVyLnByb2Nlc3NpbmdJbnN0cnVjdGlvbiggXAogICAgICAgICAgICAgICAgICAgICAgICBfZChyZWFkZXIuTmFtZSgpKSxfZChyZWFkZXIuVmFsdWUoKSkpCiAgICAgICAgICAgICAgICAjIENvbW1lbnQKICAgICAgICAgICAgICAgIGVsaWYgbm9kZVR5cGUgPT0gODoKICAgICAgICAgICAgICAgICAgICBpZiBub3Qgc2VsZi5fX2xleF9oYW5kbGVyIGlzIE5vbmU6CiAgICAgICAgICAgICAgICAgICAgICAgIHNlbGYuX19sZXhfaGFuZGxlci5jb21tZW50KF9kKHJlYWRlci5WYWx1ZSgpKSkKICAgICAgICAgICAgICAgICMgRG9jdW1lbnRUeXBlCiAgICAgICAgICAgICAgICBlbGlmIG5vZGVUeXBlID09IDEwOgogICAgICAgICAgICAgICAgICAgICNpZiBub3Qgc2VsZi5fX2xleF9oYW5kbGVyIGlzIE5vbmU6CiAgICAgICAgICAgICAgICAgICAgIyAgICBzZWxmLl9fbGV4X2hhbmRsZXIuc3RhcnREVEQoKQogICAgICAgICAgICAgICAgICAgIHBhc3MgIyBUT0RPIChob3cgdG8gZGV0ZWN0IGVuZERURD8gb24gZmlyc3Qgbm9uLWR0ZCBldmVudD8pCiAgICAgICAgICAgICAgICAjIFhtbERlY2xhcmF0aW9uCiAgICAgICAgICAgICAgICBlbGlmIG5vZGVUeXBlID09IDE3OgogICAgICAgICAgICAgICAgICAgIHBhc3MgIyBUT0RPCiAgICAgICAgICAgICAgICAjIEVudGl0eQogICAgICAgICAgICAgICAgZWxpZiBub2RlVHlwZSA9PSA2OgogICAgICAgICAgICAgICAgICAgIHBhc3MgIyBUT0RPIChlbnRpdHkgZGVjbCkKICAgICAgICAgICAgICAgICMgTm90YXRpb24gKGRlY2wpCiAgICAgICAgICAgICAgICBlbGlmIG5vZGVUeXBlID09IDEyOgogICAgICAgICAgICAgICAgICAgIHBhc3MgIyBUT0RPCiAgICAgICAgICAgICAgICAjIEF0dHJpYnV0ZSAobmV2ZXIgaW4gdGhpcyBsb29wKQogICAgICAgICAgICAgICAgI2VsaWYgbm9kZVR5cGUgPT0gMjogCiAgICAgICAgICAgICAgICAjICAgIHBhc3MKICAgICAgICAgICAgICAgICMgRG9jdW1lbnQgKG5vdCBleHBvc2VkKQogICAgICAgICAgICAgICAgI2VsaWYgbm9kZVR5cGUgPT0gOTogCiAgICAgICAgICAgICAgICAjICAgIHBhc3MKICAgICAgICAgICAgICAgICMgRG9jdW1lbnRGcmFnbWVudCAobmV2ZXIgcmV0dXJuZWQgYnkgWG1sUmVhZGVyKQogICAgICAgICAgICAgICAgI2VsaWYgbm9kZVR5cGUgPT0gMTE6CiAgICAgICAgICAgICAgICAjICAgIHBhc3MKICAgICAgICAgICAgICAgICMgTm9uZQogICAgICAgICAgICAgICAgI2VsaWYgbm9kZVR5cGUgPT0gMDoKICAgICAgICAgICAgICAgICMgICAgcGFzcwogICAgICAgICAgICAgICAgIyAtCiAgICAgICAgICAgICAgICBlbHNlOgogICAgICAgICAgICAgICAgICAgIHJhaXNlIFNBWEV4Y2VwdGlvbigiVW5leHBlY3RlZCBub2RlIHR5cGUgJWQiICUgbm9kZVR5cGUpCiAgICAgICAgICAgIGlmIHIgPT0gMDoKICAgICAgICAgICAgICAgIHNlbGYuX2NvbnRfaGFuZGxlci5lbmREb2N1bWVudCgpCiAgICAgICAgICAgIHJlYWRlci5DbG9zZSgpCiAgICAgICAgZmluYWxseToKICAgICAgICAgICAgc2VsZi5fX3BhcnNpbmcgPSAwCgogICAgZGVmIHNldERUREhhbmRsZXIoc2VsZiwgaGFuZGxlcik6CiAgICAgICAgIyBUT0RPICh3aGVuIHN1cHBvcnRlZCwgdGhlIGluaGVyaXRlZCBtZXRob2Qgd29ya3MganVzdCBmaW5lKQogICAgICAgIHJhaXNlIFNBWE5vdFN1cHBvcnRlZEV4Y2VwdGlvbigiRFRESGFuZGxlciBub3Qgc3VwcG9ydGVkIikKCiAgICBkZWYgc2V0RW50aXR5UmVzb2x2ZXIoc2VsZiwgcmVzb2x2ZXIpOgogICAgICAgICMgVE9ETyAod2hlbiBzdXBwb3J0ZWQsIHRoZSBpbmhlcml0ZWQgbWV0aG9kIHdvcmtzIGp1c3QgZmluZSkKICAgICAgICByYWlzZSBTQVhOb3RTdXBwb3J0ZWRFeGNlcHRpb24oIkVudGl0eVJlc29sdmVyIG5vdCBzdXBwb3J0ZWQiKQoKICAgIGRlZiBnZXRGZWF0dXJlKHNlbGYsIG5hbWUpOgogICAgICAgIGlmIG5hbWUgPT0gZmVhdHVyZV9uYW1lc3BhY2VzOgogICAgICAgICAgICByZXR1cm4gc2VsZi5fX25zCiAgICAgICAgZWxpZiBuYW1lID09IGZlYXR1cmVfbmFtZXNwYWNlX3ByZWZpeGVzOgogICAgICAgICAgICByZXR1cm4gc2VsZi5fX25zcGZ4CiAgICAgICAgZWxpZiBuYW1lID09IGZlYXR1cmVfdmFsaWRhdGlvbjoKICAgICAgICAgICAgcmV0dXJuIHNlbGYuX192YWxpZGF0ZQogICAgICAgIGVsaWYgbmFtZSA9PSBmZWF0dXJlX2V4dGVybmFsX2dlczoKICAgICAgICAgICAgcmV0dXJuIDEgIyBUT0RPIChkb2VzIHRoYXQgcmVsYXRlIHRvIFBBUlNFUl9MT0FERFREKT8KICAgICAgICBlbGlmIG5hbWUgPT0gZmVhdHVyZV9leHRlcm5hbF9wZXM6CiAgICAgICAgICAgIHJldHVybiBzZWxmLl9fZXh0cGFyYW1zCiAgICAgICAgZWxzZToKICAgICAgICAgICAgcmFpc2UgU0FYTm90UmVjb2duaXplZEV4Y2VwdGlvbigiRmVhdHVyZSAnJXMnIG5vdCByZWNvZ25pemVkIiAlIFwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuYW1lKQoKICAgIGRlZiBzZXRGZWF0dXJlKHNlbGYsIG5hbWUsIHN0YXRlKToKICAgICAgICBpZiBzZWxmLl9fcGFyc2luZzoKICAgICAgICAgICAgcmFpc2UgU0FYTm90U3VwcG9ydGVkRXhjZXB0aW9uKCJDYW5ub3Qgc2V0IGZlYXR1cmUgJXMgIiBcCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAid2hpbGUgcGFyc2luZyIgJSBuYW1lKQogICAgICAgIGlmIG5hbWUgPT0gZmVhdHVyZV9uYW1lc3BhY2VzOgogICAgICAgICAgICBzZWxmLl9fbnMgPSBzdGF0ZQogICAgICAgIGVsaWYgbmFtZSA9PSBmZWF0dXJlX25hbWVzcGFjZV9wcmVmaXhlczoKICAgICAgICAgICAgc2VsZi5fX25zcGZ4ID0gc3RhdGUKICAgICAgICBlbGlmIG5hbWUgPT0gZmVhdHVyZV92YWxpZGF0aW9uOgogICAgICAgICAgICBzZWxmLl9fdmFsaWRhdGUgPSBzdGF0ZQogICAgICAgIGVsaWYgbmFtZSA9PSBmZWF0dXJlX2V4dGVybmFsX2dlczoKICAgICAgICAgICAgaWYgc3RhdGUgPT0gMDoKICAgICAgICAgICAgICAgICMgVE9ETyAoZG9lcyB0aGF0IHJlbGF0ZSB0byBQQVJTRVJfTE9BRERURCk/CiAgICAgICAgICAgICAgICByYWlzZSBTQVhOb3RTdXBwb3J0ZWRFeGNlcHRpb24oIkZlYXR1cmUgJyVzJyBub3Qgc3VwcG9ydGVkIiAlIFwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuYW1lKQogICAgICAgIGVsaWYgbmFtZSA9PSBmZWF0dXJlX2V4dGVybmFsX3BlczoKICAgICAgICAgICAgc2VsZi5fX2V4dHBhcmFtcyA9IHN0YXRlCiAgICAgICAgZWxzZToKICAgICAgICAgICAgcmFpc2UgU0FYTm90UmVjb2duaXplZEV4Y2VwdGlvbigiRmVhdHVyZSAnJXMnIG5vdCByZWNvZ25pemVkIiAlIFwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuYW1lKQoKICAgIGRlZiBnZXRQcm9wZXJ0eShzZWxmLCBuYW1lKToKICAgICAgICBpZiBuYW1lID09IHByb3BlcnR5X2xleGljYWxfaGFuZGxlcjoKICAgICAgICAgICAgcmV0dXJuIHNlbGYuX19sZXhfaGFuZGxlcgogICAgICAgIGVsaWYgbmFtZSA9PSBwcm9wZXJ0eV9kZWNsYXJhdGlvbl9oYW5kbGVyOgogICAgICAgICAgICByZXR1cm4gc2VsZi5fX2RlY2xfaGFuZGxlcgogICAgICAgIGVsc2U6CiAgICAgICAgICAgIHJhaXNlIFNBWE5vdFJlY29nbml6ZWRFeGNlcHRpb24oIlByb3BlcnR5ICclcycgbm90IHJlY29nbml6ZWQiICUgXAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5hbWUpCgogICAgZGVmIHNldFByb3BlcnR5KHNlbGYsIG5hbWUsIHZhbHVlKTogICAgIAogICAgICAgIGlmIG5hbWUgPT0gcHJvcGVydHlfbGV4aWNhbF9oYW5kbGVyOgogICAgICAgICAgICBzZWxmLl9fbGV4X2hhbmRsZXIgPSB2YWx1ZQogICAgICAgIGVsaWYgbmFtZSA9PSBwcm9wZXJ0eV9kZWNsYXJhdGlvbl9oYW5kbGVyOgogICAgICAgICAgICAjIFRPRE86IHJlbW92ZSBpZi93aGVuIGxpYnhtbDIgc3VwcG9ydHMgZHRkIGV2ZW50cwogICAgICAgICAgICByYWlzZSBTQVhOb3RTdXBwb3J0ZWRFeGNlcHRpb24oIlByb3BlcnR5ICclcycgbm90IHN1cHBvcnRlZCIgJSBcCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuYW1lKQogICAgICAgICAgICBzZWxmLl9fZGVjbF9oYW5kbGVyID0gdmFsdWUKICAgICAgICBlbHNlOgogICAgICAgICAgICByYWlzZSBTQVhOb3RSZWNvZ25pemVkRXhjZXB0aW9uKCJQcm9wZXJ0eSAnJXMnIG5vdCByZWNvZ25pemVkIiAlIFwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuYW1lKQoKZGVmIGNyZWF0ZV9wYXJzZXIoKToKICAgIHJldHVybiBMaWJYbWwyUmVhZGVyKCkKCg==