IyAtKi0gY29kaW5nOiBpc28tODg1OS0xIC0qLQoiIiIgQSBTQVgyIGRyaXZlciBmb3IgbGlieG1sMiwgb24gdG9wIG9mIGl0J3MgWG1sUmVhZGVyIEFQSQoKVVNBR0UKICAgICMgcHV0IHRoaXMgZmlsZSAoZHJ2X2xpYnhtbDIucHkpIGluIFBZVEhPTlBBVEgKICAgIGltcG9ydCB4bWwuc2F4CiAgICByZWFkZXIgPSB4bWwuc2F4Lm1ha2VfcGFyc2VyKFsiZHJ2X2xpYnhtbDIiXSkKICAgICMgLi4uYW5kIHRoZSByZXN0IGlzIHN0YW5kYXJkIHB5dGhvbiBzYXguCgpDQVZFQVRTCiAgICAtIExleGljYWwgaGFuZGxlcnMgYXJlIHN1cHBvcnRlZCwgZXhjZXB0IGZvciBzdGFydC9lbmRFbnRpdHkKICAgICAgKHdhaXRpbmcgZm9yIFhtbFJlYWRlci5SZXNvbHZlRW50aXR5KSBhbmQgc3RhcnQvZW5kRFRECiAgICAtIEVycm9yIGNhbGxiYWNrcyBhcmUgbm90IGV4YWN0bHkgc3luY2hyb25vdXMsIHRoZXkgdGVuZAogICAgICB0byBiZSBpbnZva2VkIGJlZm9yZSB0aGUgY29ycmVzcG9uZGluZyBjb250ZW50IGNhbGxiYWNrLAogICAgICBiZWNhdXNlIHRoZSB1bmRlcmx5aW5nIHJlYWRlciBpbnRlcmZhY2UgcGFyc2VzCiAgICAgIGRhdGEgYnkgY2h1bmtzIG9mIDUxMiBieXRlcwogICAgClRPRE8KICAgIC0gc2VhcmNoIGZvciBUT0RPCiAgICAtIHNvbWUgRXJyb3JIYW5kbGVyIGV2ZW50cyAod2FybmluZykKICAgIC0gc29tZSBDb250ZW50SGFuZGxlciBldmVudHMgKHNldERvY3VtZW50TG9jYXRvciwgc2tpcHBlZEVudGl0eSkKICAgIC0gRW50aXR5UmVzb2x2ZXIgKHVzaW5nIGxpYnhtbDIuPykKICAgIC0gRFRESGFuZGxlciAoaWYvd2hlbiBsaWJ4bWwyIGV4cG9zZXMgc3VjaCBub2RlIHR5cGVzKQogICAgLSBEZWNsSGFuZGxlciAoaWYvd2hlbiBsaWJ4bWwyIGV4cG9zZXMgc3VjaCBub2RlIHR5cGVzKQogICAgLSBwcm9wZXJ0eV94bWxfc3RyaW5nPwogICAgLSBmZWF0dXJlX3N0cmluZ19pbnRlcm5pbmc/CiAgICAtIEluY3JlbWVudGFsIHBhcnNlcgogICAgLSBhZGRpdGlvbmFsIHBlcmZvcm1hbmNlIHR1bmluZzoKICAgICAgLSBvbmUgbWlnaHQgY2FjaGUgY2FsbGJhY2tzIHRvIGF2b2lkIHNvbWUgbmFtZSBsb29rdXBzCiAgICAgIC0gb25lIG1pZ2h0IGltcGxlbWVudCBhIHNtYXJ0ZXIgd2F5IHRvIHBhc3MgYXR0cmlidXRlcyB0byBzdGFydEVsZW1lbnQKICAgICAgICAoc29tZSBraW5kIG9mIGxhenkgZXZhbHVhdGlvbj8pCiAgICAgIC0gdGhlcmUgbWlnaHQgYmUgcm9vbSBmb3IgaW1wcm92ZW1lbnQgaW4gc3RhcnQvZW5kUHJlZml4TWFwcGluZwogICAgICAtIG90aGVyPwoKIiIiCgpfX2F1dGhvcl9fICA9ICJTdOlwaGFuZSBCaWRvdWwgPHNiaUBza3luZXQuYmU+IgpfX3ZlcnNpb25fXyA9ICIwLjMiCgppbXBvcnQgc3lzCmltcG9ydCBjb2RlY3MKCmlmIHN5cy52ZXJzaW9uX2luZm9bMF0gPCAzOgogICAgX19hdXRob3JfXyAgPSBjb2RlY3MudW5pY29kZV9lc2NhcGVfZGVjb2RlKF9fYXV0aG9yX18pWzBdCgogICAgU3RyaW5nVHlwZXMgPSAoc3RyLCB1bmljb2RlKQogICAgIyBsaWJ4bWwyIHJldHVybnMgc3RyaW5ncyBhcyBVVEY4CiAgICBfZGVjb2RlciA9IGNvZGVjcy5sb29rdXAoInV0ZjgiKVsxXQogICAgZGVmIF9kKHMpOgogICAgICAgIGlmIHMgaXMgTm9uZToKICAgICAgICAgICAgcmV0dXJuIHMKICAgICAgICBlbHNlOgogICAgICAgICAgICByZXR1cm4gX2RlY29kZXIocylbMF0KZWxzZToKICAgIFN0cmluZ1R5cGVzID0gc3RyCiAgICAjIHMgaXMgVW5pY29kZSBgc3RyYCBhbHJlYWR5CiAgICBkZWYgX2Qocyk6CiAgICAgICAgcmV0dXJuIHMKCmZyb20geG1sLnNheC5fZXhjZXB0aW9ucyBpbXBvcnQgKgpmcm9tIHhtbC5zYXggaW1wb3J0IHhtbHJlYWRlciwgc2F4dXRpbHMKZnJvbSB4bWwuc2F4LmhhbmRsZXIgaW1wb3J0IFwKICAgICBmZWF0dXJlX25hbWVzcGFjZXMsIFwKICAgICBmZWF0dXJlX25hbWVzcGFjZV9wcmVmaXhlcywgXAogICAgIGZlYXR1cmVfc3RyaW5nX2ludGVybmluZywgXAogICAgIGZlYXR1cmVfdmFsaWRhdGlvbiwgXAogICAgIGZlYXR1cmVfZXh0ZXJuYWxfZ2VzLCBcCiAgICAgZmVhdHVyZV9leHRlcm5hbF9wZXMsIFwKICAgICBwcm9wZXJ0eV9sZXhpY2FsX2hhbmRsZXIsIFwKICAgICBwcm9wZXJ0eV9kZWNsYXJhdGlvbl9oYW5kbGVyLCBcCiAgICAgcHJvcGVydHlfZG9tX25vZGUsIFwKICAgICBwcm9wZXJ0eV94bWxfc3RyaW5nCgp0cnk6CiAgICBpbXBvcnQgbGlieG1sMgpleGNlcHQgSW1wb3J0RXJyb3I6CiAgICByYWlzZSBTQVhSZWFkZXJOb3RBdmFpbGFibGUoImxpYnhtbDIgbm90IGF2YWlsYWJsZTogIiBcCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgImltcG9ydCBlcnJvciB3YXM6ICVzIiAlIHN5cy5leGNfaW5mbygpWzFdKQoKY2xhc3MgTG9jYXRvcih4bWxyZWFkZXIuTG9jYXRvcik6CiAgICAiIiJTQVggTG9jYXRvciBhZGFwdGVyIGZvciBsaWJ4bWwyLnhtbFRleHRSZWFkZXJMb2NhdG9yIiIiCgogICAgZGVmIF9faW5pdF9fKHNlbGYsbG9jYXRvcik6CiAgICAgICAgc2VsZi5fX2xvY2F0b3IgPSBsb2NhdG9yCgogICAgZGVmIGdldENvbHVtbk51bWJlcihzZWxmKToKICAgICAgICAiUmV0dXJuIHRoZSBjb2x1bW4gbnVtYmVyIHdoZXJlIHRoZSBjdXJyZW50IGV2ZW50IGVuZHMuIgogICAgICAgIHJldHVybiAtMQoKICAgIGRlZiBnZXRMaW5lTnVtYmVyKHNlbGYpOgogICAgICAgICJSZXR1cm4gdGhlIGxpbmUgbnVtYmVyIHdoZXJlIHRoZSBjdXJyZW50IGV2ZW50IGVuZHMuIgogICAgICAgIHJldHVybiBzZWxmLl9fbG9jYXRvci5MaW5lTnVtYmVyKCkKCiAgICBkZWYgZ2V0UHVibGljSWQoc2VsZik6CiAgICAgICAgIlJldHVybiB0aGUgcHVibGljIGlkZW50aWZpZXIgZm9yIHRoZSBjdXJyZW50IGV2ZW50LiIKICAgICAgICByZXR1cm4gTm9uZQoKICAgIGRlZiBnZXRTeXN0ZW1JZChzZWxmKToKICAgICAgICAiUmV0dXJuIHRoZSBzeXN0ZW0gaWRlbnRpZmllciBmb3IgdGhlIGN1cnJlbnQgZXZlbnQuIgogICAgICAgIHJldHVybiBzZWxmLl9fbG9jYXRvci5CYXNlVVJJKCkKCmNsYXNzIExpYlhtbDJSZWFkZXIoeG1scmVhZGVyLlhNTFJlYWRlcik6CgogICAgZGVmIF9faW5pdF9fKHNlbGYpOgogICAgICAgIHhtbHJlYWRlci5YTUxSZWFkZXIuX19pbml0X18oc2VsZikKICAgICAgICAjIGZlYXR1cmVzCiAgICAgICAgc2VsZi5fX25zID0gMAogICAgICAgIHNlbGYuX19uc3BmeCA9IDAKICAgICAgICBzZWxmLl9fdmFsaWRhdGUgPSAwCiAgICAgICAgc2VsZi5fX2V4dHBhcmFtcyA9IDEKICAgICAgICAjIHBhcnNpbmcgZmxhZwogICAgICAgIHNlbGYuX19wYXJzaW5nID0gMAogICAgICAgICMgYWRkaXRpb25hbCBoYW5kbGVycwogICAgICAgIHNlbGYuX19sZXhfaGFuZGxlciA9IE5vbmUKICAgICAgICBzZWxmLl9fZGVjbF9oYW5kbGVyID0gTm9uZQogICAgICAgICMgZXJyb3IgbWVzc2FnZXMgYWNjdW11bGF0b3IKICAgICAgICBzZWxmLl9fZXJyb3JzID0gTm9uZQoKICAgIGRlZiBfZXJyb3JIYW5kbGVyKHNlbGYsYXJnLG1zZyxzZXZlcml0eSxsb2NhdG9yKToKICAgICAgICBpZiBzZWxmLl9fZXJyb3JzIGlzIE5vbmU6CiAgICAgICAgICAgIHNlbGYuX19lcnJvcnMgPSBbXQogICAgICAgIHNlbGYuX19lcnJvcnMuYXBwZW5kKChzZXZlcml0eSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU0FYUGFyc2VFeGNlcHRpb24obXNnLE5vbmUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIExvY2F0b3IobG9jYXRvcikpKSkKCiAgICBkZWYgX3JlcG9ydEVycm9ycyhzZWxmLGZhdGFsKToKICAgICAgICBmb3Igc2V2ZXJpdHksZXhjZXB0aW9uIGluIHNlbGYuX19lcnJvcnM6CiAgICAgICAgICAgIGlmIHNldmVyaXR5IGluIChsaWJ4bWwyLlBBUlNFUl9TRVZFUklUWV9WQUxJRElUWV9XQVJOSU5HLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgbGlieG1sMi5QQVJTRVJfU0VWRVJJVFlfV0FSTklORyk6CiAgICAgICAgICAgICAgICBzZWxmLl9lcnJfaGFuZGxlci53YXJuaW5nKGV4Y2VwdGlvbikKICAgICAgICAgICAgZWxzZToKICAgICAgICAgICAgICAgICMgd2hlbiBmYXRhbCBpcyBzZXQsIHRoZSBwYXJzZSB3aWxsIHN0b3A7CiAgICAgICAgICAgICAgICAjIHdlIGNvbnNpZGVyIHRoYXQgdGhlIGxhc3QgZXJyb3IgcmVwb3J0ZWQKICAgICAgICAgICAgICAgICMgaXMgdGhlIGZhdGFsIG9uZS4KICAgICAgICAgICAgICAgIGlmIGZhdGFsIGFuZCBleGNlcHRpb24gaXMgc2VsZi5fX2Vycm9yc1stMV1bMV06CiAgICAgICAgICAgICAgICAgICAgc2VsZi5fZXJyX2hhbmRsZXIuZmF0YWxFcnJvcihleGNlcHRpb24pCiAgICAgICAgICAgICAgICBlbHNlOgogICAgICAgICAgICAgICAgICAgIHNlbGYuX2Vycl9oYW5kbGVyLmVycm9yKGV4Y2VwdGlvbikKICAgICAgICBzZWxmLl9fZXJyb3JzID0gTm9uZQoKICAgIGRlZiBwYXJzZShzZWxmLCBzb3VyY2UpOgogICAgICAgIHNlbGYuX19wYXJzaW5nID0gMQogICAgICAgIHRyeToKICAgICAgICAgICAgIyBwcmVwYXJlIHNvdXJjZSBhbmQgY3JlYXRlIHJlYWRlcgogICAgICAgICAgICBpZiBpc2luc3RhbmNlKHNvdXJjZSwgU3RyaW5nVHlwZXMpOgogICAgICAgICAgICAgICAgcmVhZGVyID0gbGlieG1sMi5uZXdUZXh0UmVhZGVyRmlsZW5hbWUoc291cmNlKQogICAgICAgICAgICBlbHNlOgogICAgICAgICAgICAgICAgc291cmNlID0gc2F4dXRpbHMucHJlcGFyZV9pbnB1dF9zb3VyY2Uoc291cmNlKQogICAgICAgICAgICAgICAgaW5wdXQgPSBsaWJ4bWwyLmlucHV0QnVmZmVyKHNvdXJjZS5nZXRCeXRlU3RyZWFtKCkpCiAgICAgICAgICAgICAgICByZWFkZXIgPSBpbnB1dC5uZXdUZXh0UmVhZGVyKHNvdXJjZS5nZXRTeXN0ZW1JZCgpKQogICAgICAgICAgICByZWFkZXIuU2V0RXJyb3JIYW5kbGVyKHNlbGYuX2Vycm9ySGFuZGxlcixOb25lKQogICAgICAgICAgICAjIGNvbmZpZ3VyZSByZWFkZXIKICAgICAgICAgICAgaWYgc2VsZi5fX2V4dHBhcmFtczoKICAgICAgICAgICAgICAgIHJlYWRlci5TZXRQYXJzZXJQcm9wKGxpYnhtbDIuUEFSU0VSX0xPQUREVEQsMSkKICAgICAgICAgICAgICAgIHJlYWRlci5TZXRQYXJzZXJQcm9wKGxpYnhtbDIuUEFSU0VSX0RFRkFVTFRBVFRSUywxKQogICAgICAgICAgICAgICAgcmVhZGVyLlNldFBhcnNlclByb3AobGlieG1sMi5QQVJTRVJfU1VCU1RfRU5USVRJRVMsMSkKICAgICAgICAgICAgICAgIHJlYWRlci5TZXRQYXJzZXJQcm9wKGxpYnhtbDIuUEFSU0VSX1ZBTElEQVRFLHNlbGYuX192YWxpZGF0ZSkKICAgICAgICAgICAgZWxzZToKICAgICAgICAgICAgICAgIHJlYWRlci5TZXRQYXJzZXJQcm9wKGxpYnhtbDIuUEFSU0VSX0xPQUREVEQsIDApCiAgICAgICAgICAgICMgd2UgcmV1c2UgYXR0cmlidXRlIG1hcHMgKGZvciBhIHNsaWdodCBwZXJmb3JtYW5jZSBnYWluKQogICAgICAgICAgICBpZiBzZWxmLl9fbnM6CiAgICAgICAgICAgICAgICBhdHRyaWJ1dGVzTlNJbXBsID0geG1scmVhZGVyLkF0dHJpYnV0ZXNOU0ltcGwoe30se30pCiAgICAgICAgICAgIGVsc2U6CiAgICAgICAgICAgICAgICBhdHRyaWJ1dGVzSW1wbCA9IHhtbHJlYWRlci5BdHRyaWJ1dGVzSW1wbCh7fSkKICAgICAgICAgICAgIyBwcmVmaXhlcyB0byBwb3AgKGZvciBlbmRQcmVmaXhNYXBwaW5nKQogICAgICAgICAgICBwcmVmaXhlcyA9IFtdCiAgICAgICAgICAgICMgc3RhcnQgbG9vcAogICAgICAgICAgICBzZWxmLl9jb250X2hhbmRsZXIuc3RhcnREb2N1bWVudCgpCiAgICAgICAgICAgIHdoaWxlIDE6CiAgICAgICAgICAgICAgICByID0gcmVhZGVyLlJlYWQoKQogICAgICAgICAgICAgICAgIyBjaGVjayBmb3IgZXJyb3JzCiAgICAgICAgICAgICAgICBpZiByID09IDE6CiAgICAgICAgICAgICAgICAgICAgaWYgbm90IHNlbGYuX19lcnJvcnMgaXMgTm9uZToKICAgICAgICAgICAgICAgICAgICAgICAgc2VsZi5fcmVwb3J0RXJyb3JzKDApCiAgICAgICAgICAgICAgICBlbGlmIHIgPT0gMDoKICAgICAgICAgICAgICAgICAgICBpZiBub3Qgc2VsZi5fX2Vycm9ycyBpcyBOb25lOgogICAgICAgICAgICAgICAgICAgICAgICBzZWxmLl9yZXBvcnRFcnJvcnMoMCkKICAgICAgICAgICAgICAgICAgICBicmVhayAjIGVuZCBvZiBwYXJzZQogICAgICAgICAgICAgICAgZWxzZToKICAgICAgICAgICAgICAgICAgICBpZiBub3Qgc2VsZi5fX2Vycm9ycyBpcyBOb25lOgogICAgICAgICAgICAgICAgICAgICAgICBzZWxmLl9yZXBvcnRFcnJvcnMoMSkKICAgICAgICAgICAgICAgICAgICBlbHNlOgogICAgICAgICAgICAgICAgICAgICAgICBzZWxmLl9lcnJfaGFuZGxlci5mYXRhbEVycm9yKFwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIFNBWEV4Y2VwdGlvbigiUmVhZCBmYWlsZWQgKG5vIGRldGFpbHMgYXZhaWxhYmxlKSIpKQogICAgICAgICAgICAgICAgICAgIGJyZWFrICMgZmF0YWwgcGFyc2UgZXJyb3IKICAgICAgICAgICAgICAgICMgZ2V0IG5vZGUgdHlwZQogICAgICAgICAgICAgICAgbm9kZVR5cGUgPSByZWFkZXIuTm9kZVR5cGUoKQogICAgICAgICAgICAgICAgIyBFbGVtZW50CiAgICAgICAgICAgICAgICBpZiBub2RlVHlwZSA9PSAxOiAKICAgICAgICAgICAgICAgICAgICBpZiBzZWxmLl9fbnM6CiAgICAgICAgICAgICAgICAgICAgICAgIGVsdE5hbWUgPSAoX2QocmVhZGVyLk5hbWVzcGFjZVVyaSgpKSxcCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgX2QocmVhZGVyLkxvY2FsTmFtZSgpKSkKICAgICAgICAgICAgICAgICAgICAgICAgZWx0UU5hbWUgPSBfZChyZWFkZXIuTmFtZSgpKQogICAgICAgICAgICAgICAgICAgICAgICBhdHRyaWJ1dGVzTlNJbXBsLl9hdHRycyA9IGF0dHJzID0ge30KICAgICAgICAgICAgICAgICAgICAgICAgYXR0cmlidXRlc05TSW1wbC5fcW5hbWVzID0gcW5hbWVzID0ge30KICAgICAgICAgICAgICAgICAgICAgICAgbmV3UHJlZml4ZXMgPSBbXQogICAgICAgICAgICAgICAgICAgICAgICB3aGlsZSByZWFkZXIuTW92ZVRvTmV4dEF0dHJpYnV0ZSgpOgogICAgICAgICAgICAgICAgICAgICAgICAgICAgcW5hbWUgPSBfZChyZWFkZXIuTmFtZSgpKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFsdWUgPSBfZChyZWFkZXIuVmFsdWUoKSkKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIHFuYW1lLnN0YXJ0c3dpdGgoInhtbG5zIik6CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgbGVuKHFuYW1lKSA+IDU6CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ld1ByZWZpeCA9IHFuYW1lWzY6XQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2U6CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ld1ByZWZpeCA9IE5vbmUKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXdQcmVmaXhlcy5hcHBlbmQobmV3UHJlZml4KQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNlbGYuX2NvbnRfaGFuZGxlci5zdGFydFByZWZpeE1hcHBpbmcoXAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXdQcmVmaXgsdmFsdWUpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgbm90IHNlbGYuX19uc3BmeDoKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29udGludWUgIyBkb24ndCByZXBvcnQgeG1sbnMgYXR0cmlidXRlCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBhdHROYW1lID0gKF9kKHJlYWRlci5OYW1lc3BhY2VVcmkoKSksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIF9kKHJlYWRlci5Mb2NhbE5hbWUoKSkpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBxbmFtZXNbYXR0TmFtZV0gPSBxbmFtZQogICAgICAgICAgICAgICAgICAgICAgICAgICAgYXR0cnNbYXR0TmFtZV0gPSB2YWx1ZQogICAgICAgICAgICAgICAgICAgICAgICByZWFkZXIuTW92ZVRvRWxlbWVudCgpCiAgICAgICAgICAgICAgICAgICAgICAgIHNlbGYuX2NvbnRfaGFuZGxlci5zdGFydEVsZW1lbnROUyggXAogICAgICAgICAgICAgICAgICAgICAgICAgICAgZWx0TmFtZSxlbHRRTmFtZSxhdHRyaWJ1dGVzTlNJbXBsKSAKICAgICAgICAgICAgICAgICAgICAgICAgaWYgcmVhZGVyLklzRW1wdHlFbGVtZW50KCk6CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZWxmLl9jb250X2hhbmRsZXIuZW5kRWxlbWVudE5TKGVsdE5hbWUsZWx0UU5hbWUpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBmb3IgbmV3UHJlZml4IGluIG5ld1ByZWZpeGVzOgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNlbGYuX2NvbnRfaGFuZGxlci5lbmRQcmVmaXhNYXBwaW5nKG5ld1ByZWZpeCkKICAgICAgICAgICAgICAgICAgICAgICAgZWxzZToKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHByZWZpeGVzLmFwcGVuZChuZXdQcmVmaXhlcykKICAgICAgICAgICAgICAgICAgICBlbHNlOgogICAgICAgICAgICAgICAgICAgICAgICBlbHROYW1lID0gX2QocmVhZGVyLk5hbWUoKSkKICAgICAgICAgICAgICAgICAgICAgICAgYXR0cmlidXRlc0ltcGwuX2F0dHJzID0gYXR0cnMgPSB7fQogICAgICAgICAgICAgICAgICAgICAgICB3aGlsZSByZWFkZXIuTW92ZVRvTmV4dEF0dHJpYnV0ZSgpOgogICAgICAgICAgICAgICAgICAgICAgICAgICAgYXR0TmFtZSA9IF9kKHJlYWRlci5OYW1lKCkpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBhdHRyc1thdHROYW1lXSA9IF9kKHJlYWRlci5WYWx1ZSgpKQogICAgICAgICAgICAgICAgICAgICAgICByZWFkZXIuTW92ZVRvRWxlbWVudCgpCiAgICAgICAgICAgICAgICAgICAgICAgIHNlbGYuX2NvbnRfaGFuZGxlci5zdGFydEVsZW1lbnQoIFwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsdE5hbWUsYXR0cmlidXRlc0ltcGwpCiAgICAgICAgICAgICAgICAgICAgICAgIGlmIHJlYWRlci5Jc0VtcHR5RWxlbWVudCgpOgogICAgICAgICAgICAgICAgICAgICAgICAgICAgc2VsZi5fY29udF9oYW5kbGVyLmVuZEVsZW1lbnQoZWx0TmFtZSkKICAgICAgICAgICAgICAgICMgRW5kRWxlbWVudAogICAgICAgICAgICAgICAgZWxpZiBub2RlVHlwZSA9PSAxNTogCiAgICAgICAgICAgICAgICAgICAgaWYgc2VsZi5fX25zOgogICAgICAgICAgICAgICAgICAgICAgICBzZWxmLl9jb250X2hhbmRsZXIuZW5kRWxlbWVudE5TKCBcCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKF9kKHJlYWRlci5OYW1lc3BhY2VVcmkoKSksX2QocmVhZGVyLkxvY2FsTmFtZSgpKSksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgX2QocmVhZGVyLk5hbWUoKSkpCiAgICAgICAgICAgICAgICAgICAgICAgIGZvciBwcmVmaXggaW4gcHJlZml4ZXMucG9wKCk6CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZWxmLl9jb250X2hhbmRsZXIuZW5kUHJlZml4TWFwcGluZyhwcmVmaXgpCiAgICAgICAgICAgICAgICAgICAgZWxzZToKICAgICAgICAgICAgICAgICAgICAgICAgc2VsZi5fY29udF9oYW5kbGVyLmVuZEVsZW1lbnQoX2QocmVhZGVyLk5hbWUoKSkpCiAgICAgICAgICAgICAgICAjIFRleHQKICAgICAgICAgICAgICAgIGVsaWYgbm9kZVR5cGUgPT0gMzogCiAgICAgICAgICAgICAgICAgICAgc2VsZi5fY29udF9oYW5kbGVyLmNoYXJhY3RlcnMoX2QocmVhZGVyLlZhbHVlKCkpKQogICAgICAgICAgICAgICAgIyBXaGl0ZXNwYWNlCiAgICAgICAgICAgICAgICBlbGlmIG5vZGVUeXBlID09IDEzOiAKICAgICAgICAgICAgICAgICAgICBzZWxmLl9jb250X2hhbmRsZXIuaWdub3JhYmxlV2hpdGVzcGFjZShfZChyZWFkZXIuVmFsdWUoKSkpCiAgICAgICAgICAgICAgICAjIFNpZ25pZmljYW50V2hpdGVzcGFjZQogICAgICAgICAgICAgICAgZWxpZiBub2RlVHlwZSA9PSAxNDoKICAgICAgICAgICAgICAgICAgICBzZWxmLl9jb250X2hhbmRsZXIuY2hhcmFjdGVycyhfZChyZWFkZXIuVmFsdWUoKSkpCiAgICAgICAgICAgICAgICAjIENEQVRBCiAgICAgICAgICAgICAgICBlbGlmIG5vZGVUeXBlID09IDQ6CiAgICAgICAgICAgICAgICAgICAgaWYgbm90IHNlbGYuX19sZXhfaGFuZGxlciBpcyBOb25lOgogICAgICAgICAgICAgICAgICAgICAgICBzZWxmLl9fbGV4X2hhbmRsZXIuc3RhcnRDREFUQSgpCiAgICAgICAgICAgICAgICAgICAgc2VsZi5fY29udF9oYW5kbGVyLmNoYXJhY3RlcnMoX2QocmVhZGVyLlZhbHVlKCkpKQogICAgICAgICAgICAgICAgICAgIGlmIG5vdCBzZWxmLl9fbGV4X2hhbmRsZXIgaXMgTm9uZToKICAgICAgICAgICAgICAgICAgICAgICAgc2VsZi5fX2xleF9oYW5kbGVyLmVuZENEQVRBKCkKICAgICAgICAgICAgICAgICMgRW50aXR5UmVmZXJlbmNlCiAgICAgICAgICAgICAgICBlbGlmIG5vZGVUeXBlID09IDU6CiAgICAgICAgICAgICAgICAgICAgaWYgbm90IHNlbGYuX19sZXhfaGFuZGxlciBpcyBOb25lOgogICAgICAgICAgICAgICAgICAgICAgICBzZWxmLnN0YXJ0RW50aXR5KF9kKHJlYWRlci5OYW1lKCkpKQogICAgICAgICAgICAgICAgICAgIHJlYWRlci5SZXNvbHZlRW50aXR5KCkKICAgICAgICAgICAgICAgICMgRW5kRW50aXR5CiAgICAgICAgICAgICAgICBlbGlmIG5vZGVUeXBlID09IDE2OgogICAgICAgICAgICAgICAgICAgIGlmIG5vdCBzZWxmLl9fbGV4X2hhbmRsZXIgaXMgTm9uZToKICAgICAgICAgICAgICAgICAgICAgICAgc2VsZi5lbmRFbnRpdHkoX2QocmVhZGVyLk5hbWUoKSkpCiAgICAgICAgICAgICAgICAjIFByb2Nlc3NpbmdJbnN0cnVjdGlvbgogICAgICAgICAgICAgICAgZWxpZiBub2RlVHlwZSA9PSA3OiAKICAgICAgICAgICAgICAgICAgICBzZWxmLl9jb250X2hhbmRsZXIucHJvY2Vzc2luZ0luc3RydWN0aW9uKCBcCiAgICAgICAgICAgICAgICAgICAgICAgIF9kKHJlYWRlci5OYW1lKCkpLF9kKHJlYWRlci5WYWx1ZSgpKSkKICAgICAgICAgICAgICAgICMgQ29tbWVudAogICAgICAgICAgICAgICAgZWxpZiBub2RlVHlwZSA9PSA4OgogICAgICAgICAgICAgICAgICAgIGlmIG5vdCBzZWxmLl9fbGV4X2hhbmRsZXIgaXMgTm9uZToKICAgICAgICAgICAgICAgICAgICAgICAgc2VsZi5fX2xleF9oYW5kbGVyLmNvbW1lbnQoX2QocmVhZGVyLlZhbHVlKCkpKQogICAgICAgICAgICAgICAgIyBEb2N1bWVudFR5cGUKICAgICAgICAgICAgICAgIGVsaWYgbm9kZVR5cGUgPT0gMTA6CiAgICAgICAgICAgICAgICAgICAgI2lmIG5vdCBzZWxmLl9fbGV4X2hhbmRsZXIgaXMgTm9uZToKICAgICAgICAgICAgICAgICAgICAjICAgIHNlbGYuX19sZXhfaGFuZGxlci5zdGFydERURCgpCiAgICAgICAgICAgICAgICAgICAgcGFzcyAjIFRPRE8gKGhvdyB0byBkZXRlY3QgZW5kRFREPyBvbiBmaXJzdCBub24tZHRkIGV2ZW50PykKICAgICAgICAgICAgICAgICMgWG1sRGVjbGFyYXRpb24KICAgICAgICAgICAgICAgIGVsaWYgbm9kZVR5cGUgPT0gMTc6CiAgICAgICAgICAgICAgICAgICAgcGFzcyAjIFRPRE8KICAgICAgICAgICAgICAgICMgRW50aXR5CiAgICAgICAgICAgICAgICBlbGlmIG5vZGVUeXBlID09IDY6CiAgICAgICAgICAgICAgICAgICAgcGFzcyAjIFRPRE8gKGVudGl0eSBkZWNsKQogICAgICAgICAgICAgICAgIyBOb3RhdGlvbiAoZGVjbCkKICAgICAgICAgICAgICAgIGVsaWYgbm9kZVR5cGUgPT0gMTI6CiAgICAgICAgICAgICAgICAgICAgcGFzcyAjIFRPRE8KICAgICAgICAgICAgICAgICMgQXR0cmlidXRlIChuZXZlciBpbiB0aGlzIGxvb3ApCiAgICAgICAgICAgICAgICAjZWxpZiBub2RlVHlwZSA9PSAyOiAKICAgICAgICAgICAgICAgICMgICAgcGFzcwogICAgICAgICAgICAgICAgIyBEb2N1bWVudCAobm90IGV4cG9zZWQpCiAgICAgICAgICAgICAgICAjZWxpZiBub2RlVHlwZSA9PSA5OiAKICAgICAgICAgICAgICAgICMgICAgcGFzcwogICAgICAgICAgICAgICAgIyBEb2N1bWVudEZyYWdtZW50IChuZXZlciByZXR1cm5lZCBieSBYbWxSZWFkZXIpCiAgICAgICAgICAgICAgICAjZWxpZiBub2RlVHlwZSA9PSAxMToKICAgICAgICAgICAgICAgICMgICAgcGFzcwogICAgICAgICAgICAgICAgIyBOb25lCiAgICAgICAgICAgICAgICAjZWxpZiBub2RlVHlwZSA9PSAwOgogICAgICAgICAgICAgICAgIyAgICBwYXNzCiAgICAgICAgICAgICAgICAjIC0KICAgICAgICAgICAgICAgIGVsc2U6CiAgICAgICAgICAgICAgICAgICAgcmFpc2UgU0FYRXhjZXB0aW9uKCJVbmV4cGVjdGVkIG5vZGUgdHlwZSAlZCIgJSBub2RlVHlwZSkKICAgICAgICAgICAgaWYgciA9PSAwOgogICAgICAgICAgICAgICAgc2VsZi5fY29udF9oYW5kbGVyLmVuZERvY3VtZW50KCkKICAgICAgICAgICAgcmVhZGVyLkNsb3NlKCkKICAgICAgICBmaW5hbGx5OgogICAgICAgICAgICBzZWxmLl9fcGFyc2luZyA9IDAKCiAgICBkZWYgc2V0RFRESGFuZGxlcihzZWxmLCBoYW5kbGVyKToKICAgICAgICAjIFRPRE8gKHdoZW4gc3VwcG9ydGVkLCB0aGUgaW5oZXJpdGVkIG1ldGhvZCB3b3JrcyBqdXN0IGZpbmUpCiAgICAgICAgcmFpc2UgU0FYTm90U3VwcG9ydGVkRXhjZXB0aW9uKCJEVERIYW5kbGVyIG5vdCBzdXBwb3J0ZWQiKQoKICAgIGRlZiBzZXRFbnRpdHlSZXNvbHZlcihzZWxmLCByZXNvbHZlcik6CiAgICAgICAgIyBUT0RPICh3aGVuIHN1cHBvcnRlZCwgdGhlIGluaGVyaXRlZCBtZXRob2Qgd29ya3MganVzdCBmaW5lKQogICAgICAgIHJhaXNlIFNBWE5vdFN1cHBvcnRlZEV4Y2VwdGlvbigiRW50aXR5UmVzb2x2ZXIgbm90IHN1cHBvcnRlZCIpCgogICAgZGVmIGdldEZlYXR1cmUoc2VsZiwgbmFtZSk6CiAgICAgICAgaWYgbmFtZSA9PSBmZWF0dXJlX25hbWVzcGFjZXM6CiAgICAgICAgICAgIHJldHVybiBzZWxmLl9fbnMKICAgICAgICBlbGlmIG5hbWUgPT0gZmVhdHVyZV9uYW1lc3BhY2VfcHJlZml4ZXM6CiAgICAgICAgICAgIHJldHVybiBzZWxmLl9fbnNwZngKICAgICAgICBlbGlmIG5hbWUgPT0gZmVhdHVyZV92YWxpZGF0aW9uOgogICAgICAgICAgICByZXR1cm4gc2VsZi5fX3ZhbGlkYXRlCiAgICAgICAgZWxpZiBuYW1lID09IGZlYXR1cmVfZXh0ZXJuYWxfZ2VzOgogICAgICAgICAgICByZXR1cm4gMSAjIFRPRE8gKGRvZXMgdGhhdCByZWxhdGUgdG8gUEFSU0VSX0xPQUREVEQpPwogICAgICAgIGVsaWYgbmFtZSA9PSBmZWF0dXJlX2V4dGVybmFsX3BlczoKICAgICAgICAgICAgcmV0dXJuIHNlbGYuX19leHRwYXJhbXMKICAgICAgICBlbHNlOgogICAgICAgICAgICByYWlzZSBTQVhOb3RSZWNvZ25pemVkRXhjZXB0aW9uKCJGZWF0dXJlICclcycgbm90IHJlY29nbml6ZWQiICUgXAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5hbWUpCgogICAgZGVmIHNldEZlYXR1cmUoc2VsZiwgbmFtZSwgc3RhdGUpOgogICAgICAgIGlmIHNlbGYuX19wYXJzaW5nOgogICAgICAgICAgICByYWlzZSBTQVhOb3RTdXBwb3J0ZWRFeGNlcHRpb24oIkNhbm5vdCBzZXQgZmVhdHVyZSAlcyAiIFwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJ3aGlsZSBwYXJzaW5nIiAlIG5hbWUpCiAgICAgICAgaWYgbmFtZSA9PSBmZWF0dXJlX25hbWVzcGFjZXM6CiAgICAgICAgICAgIHNlbGYuX19ucyA9IHN0YXRlCiAgICAgICAgZWxpZiBuYW1lID09IGZlYXR1cmVfbmFtZXNwYWNlX3ByZWZpeGVzOgogICAgICAgICAgICBzZWxmLl9fbnNwZnggPSBzdGF0ZQogICAgICAgIGVsaWYgbmFtZSA9PSBmZWF0dXJlX3ZhbGlkYXRpb246CiAgICAgICAgICAgIHNlbGYuX192YWxpZGF0ZSA9IHN0YXRlCiAgICAgICAgZWxpZiBuYW1lID09IGZlYXR1cmVfZXh0ZXJuYWxfZ2VzOgogICAgICAgICAgICBpZiBzdGF0ZSA9PSAwOgogICAgICAgICAgICAgICAgIyBUT0RPIChkb2VzIHRoYXQgcmVsYXRlIHRvIFBBUlNFUl9MT0FERFREKT8KICAgICAgICAgICAgICAgIHJhaXNlIFNBWE5vdFN1cHBvcnRlZEV4Y2VwdGlvbigiRmVhdHVyZSAnJXMnIG5vdCBzdXBwb3J0ZWQiICUgXAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5hbWUpCiAgICAgICAgZWxpZiBuYW1lID09IGZlYXR1cmVfZXh0ZXJuYWxfcGVzOgogICAgICAgICAgICBzZWxmLl9fZXh0cGFyYW1zID0gc3RhdGUKICAgICAgICBlbHNlOgogICAgICAgICAgICByYWlzZSBTQVhOb3RSZWNvZ25pemVkRXhjZXB0aW9uKCJGZWF0dXJlICclcycgbm90IHJlY29nbml6ZWQiICUgXAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5hbWUpCgogICAgZGVmIGdldFByb3BlcnR5KHNlbGYsIG5hbWUpOgogICAgICAgIGlmIG5hbWUgPT0gcHJvcGVydHlfbGV4aWNhbF9oYW5kbGVyOgogICAgICAgICAgICByZXR1cm4gc2VsZi5fX2xleF9oYW5kbGVyCiAgICAgICAgZWxpZiBuYW1lID09IHByb3BlcnR5X2RlY2xhcmF0aW9uX2hhbmRsZXI6CiAgICAgICAgICAgIHJldHVybiBzZWxmLl9fZGVjbF9oYW5kbGVyCiAgICAgICAgZWxzZToKICAgICAgICAgICAgcmFpc2UgU0FYTm90UmVjb2duaXplZEV4Y2VwdGlvbigiUHJvcGVydHkgJyVzJyBub3QgcmVjb2duaXplZCIgJSBcCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmFtZSkKCiAgICBkZWYgc2V0UHJvcGVydHkoc2VsZiwgbmFtZSwgdmFsdWUpOiAgICAgCiAgICAgICAgaWYgbmFtZSA9PSBwcm9wZXJ0eV9sZXhpY2FsX2hhbmRsZXI6CiAgICAgICAgICAgIHNlbGYuX19sZXhfaGFuZGxlciA9IHZhbHVlCiAgICAgICAgZWxpZiBuYW1lID09IHByb3BlcnR5X2RlY2xhcmF0aW9uX2hhbmRsZXI6CiAgICAgICAgICAgICMgVE9ETzogcmVtb3ZlIGlmL3doZW4gbGlieG1sMiBzdXBwb3J0cyBkdGQgZXZlbnRzCiAgICAgICAgICAgIHJhaXNlIFNBWE5vdFN1cHBvcnRlZEV4Y2VwdGlvbigiUHJvcGVydHkgJyVzJyBub3Qgc3VwcG9ydGVkIiAlIFwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5hbWUpCiAgICAgICAgICAgIHNlbGYuX19kZWNsX2hhbmRsZXIgPSB2YWx1ZQogICAgICAgIGVsc2U6CiAgICAgICAgICAgIHJhaXNlIFNBWE5vdFJlY29nbml6ZWRFeGNlcHRpb24oIlByb3BlcnR5ICclcycgbm90IHJlY29nbml6ZWQiICUgXAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5hbWUpCgpkZWYgY3JlYXRlX3BhcnNlcigpOgogICAgcmV0dXJuIExpYlhtbDJSZWFkZXIoKQoK