IyAtKi0gY29kaW5nOiBpc28tODg1OS0xIC0qLQoiIiIgQSBTQVgyIGRyaXZlciBmb3IgbGlieG1sMiwgb24gdG9wIG9mIGl0J3MgWG1sUmVhZGVyIEFQSQoKVVNBR0UKICAgICMgcHV0IHRoaXMgZmlsZSAoZHJ2X2xpYnhtbDIucHkpIGluIFBZVEhPTlBBVEgKICAgIGltcG9ydCB4bWwuc2F4CiAgICByZWFkZXIgPSB4bWwuc2F4Lm1ha2VfcGFyc2VyKFsiZHJ2X2xpYnhtbDIiXSkKICAgICMgLi4uYW5kIHRoZSByZXN0IGlzIHN0YW5kYXJkIHB5dGhvbiBzYXguCgpDQVZFQVRTCiAgICAtIExleGljYWwgaGFuZGxlcnMgYXJlIHN1cHBvcnRlZCwgZXhjZXB0IGZvciBzdGFydC9lbmRFbnRpdHkKICAgICAgKHdhaXRpbmcgZm9yIFhtbFJlYWRlci5SZXNvbHZlRW50aXR5KSBhbmQgc3RhcnQvZW5kRFRECiAgICAtIEVycm9yIGNhbGxiYWNrcyBhcmUgbm90IGV4YWN0bHkgc3luY2hyb25vdXMsIHRoZXkgdGVuZAogICAgICB0byBiZSBpbnZva2VkIGJlZm9yZSB0aGUgY29ycmVzcG9uZGluZyBjb250ZW50IGNhbGxiYWNrLAogICAgICBiZWNhdXNlIHRoZSB1bmRlcmx5aW5nIHJlYWRlciBpbnRlcmZhY2UgcGFyc2VzCiAgICAgIGRhdGEgYnkgY2h1bmtzIG9mIDUxMiBieXRlcwogICAgClRPRE8KICAgIC0gc2VhcmNoIGZvciBUT0RPCiAgICAtIHNvbWUgRXJyb3JIYW5kbGVyIGV2ZW50cyAod2FybmluZykKICAgIC0gc29tZSBDb250ZW50SGFuZGxlciBldmVudHMgKHNldERvY3VtZW50TG9jYXRvciwgc2tpcHBlZEVudGl0eSkKICAgIC0gRW50aXR5UmVzb2x2ZXIgKHVzaW5nIGxpYnhtbDIuPykKICAgIC0gRFRESGFuZGxlciAoaWYvd2hlbiBsaWJ4bWwyIGV4cG9zZXMgc3VjaCBub2RlIHR5cGVzKQogICAgLSBEZWNsSGFuZGxlciAoaWYvd2hlbiBsaWJ4bWwyIGV4cG9zZXMgc3VjaCBub2RlIHR5cGVzKQogICAgLSBwcm9wZXJ0eV94bWxfc3RyaW5nPwogICAgLSBmZWF0dXJlX3N0cmluZ19pbnRlcm5pbmc/CiAgICAtIEluY3JlbWVudGFsIHBhcnNlcgogICAgLSBhZGRpdGlvbmFsIHBlcmZvcm1hbmNlIHR1bmluZzoKICAgICAgLSBvbmUgbWlnaHQgY2FjaGUgY2FsbGJhY2tzIHRvIGF2b2lkIHNvbWUgbmFtZSBsb29rdXBzCiAgICAgIC0gb25lIG1pZ2h0IGltcGxlbWVudCBhIHNtYXJ0ZXIgd2F5IHRvIHBhc3MgYXR0cmlidXRlcyB0byBzdGFydEVsZW1lbnQKICAgICAgICAoc29tZSBraW5kIG9mIGxhenkgZXZhbHVhdGlvbj8pCiAgICAgIC0gdGhlcmUgbWlnaHQgYmUgcm9vbSBmb3IgaW1wcm92ZW1lbnQgaW4gc3RhcnQvZW5kUHJlZml4TWFwcGluZwogICAgICAtIG90aGVyPwoKIiIiCgpfX2F1dGhvcl9fICA9IHUiU3TpcGhhbmUgQmlkb3VsIDxzYmlAc2t5bmV0LmJlPiIKX192ZXJzaW9uX18gPSAiMC4zIgoKaW1wb3J0IGNvZGVjcwppbXBvcnQgc3lzCmZyb20gdHlwZXMgaW1wb3J0IFN0cmluZ1R5cGUsIFVuaWNvZGVUeXBlClN0cmluZ1R5cGVzID0gKFN0cmluZ1R5cGUsVW5pY29kZVR5cGUpCgpmcm9tIHhtbC5zYXguX2V4Y2VwdGlvbnMgaW1wb3J0ICoKZnJvbSB4bWwuc2F4IGltcG9ydCB4bWxyZWFkZXIsIHNheHV0aWxzCmZyb20geG1sLnNheC5oYW5kbGVyIGltcG9ydCBcCiAgICAgZmVhdHVyZV9uYW1lc3BhY2VzLCBcCiAgICAgZmVhdHVyZV9uYW1lc3BhY2VfcHJlZml4ZXMsIFwKICAgICBmZWF0dXJlX3N0cmluZ19pbnRlcm5pbmcsIFwKICAgICBmZWF0dXJlX3ZhbGlkYXRpb24sIFwKICAgICBmZWF0dXJlX2V4dGVybmFsX2dlcywgXAogICAgIGZlYXR1cmVfZXh0ZXJuYWxfcGVzLCBcCiAgICAgcHJvcGVydHlfbGV4aWNhbF9oYW5kbGVyLCBcCiAgICAgcHJvcGVydHlfZGVjbGFyYXRpb25faGFuZGxlciwgXAogICAgIHByb3BlcnR5X2RvbV9ub2RlLCBcCiAgICAgcHJvcGVydHlfeG1sX3N0cmluZwoKIyBsaWJ4bWwyIHJldHVybnMgc3RyaW5ncyBhcyBVVEY4Cl9kZWNvZGVyID0gY29kZWNzLmxvb2t1cCgidXRmOCIpWzFdCmRlZiBfZChzKToKICAgIGlmIHMgaXMgTm9uZToKICAgICAgICByZXR1cm4gcwogICAgZWxzZToKICAgICAgICByZXR1cm4gX2RlY29kZXIocylbMF0KCnRyeToKICAgIGltcG9ydCBsaWJ4bWwyCmV4Y2VwdCBJbXBvcnRFcnJvciwgZToKICAgIHJhaXNlIFNBWFJlYWRlck5vdEF2YWlsYWJsZSgibGlieG1sMiBub3QgYXZhaWxhYmxlOiAiIFwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiaW1wb3J0IGVycm9yIHdhczogJXMiICUgZSkKCmNsYXNzIExvY2F0b3IoeG1scmVhZGVyLkxvY2F0b3IpOgogICAgIiIiU0FYIExvY2F0b3IgYWRhcHRlciBmb3IgbGlieG1sMi54bWxUZXh0UmVhZGVyTG9jYXRvciIiIgoKICAgIGRlZiBfX2luaXRfXyhzZWxmLGxvY2F0b3IpOgogICAgICAgIHNlbGYuX19sb2NhdG9yID0gbG9jYXRvcgoKICAgIGRlZiBnZXRDb2x1bW5OdW1iZXIoc2VsZik6CiAgICAgICAgIlJldHVybiB0aGUgY29sdW1uIG51bWJlciB3aGVyZSB0aGUgY3VycmVudCBldmVudCBlbmRzLiIKICAgICAgICByZXR1cm4gLTEKCiAgICBkZWYgZ2V0TGluZU51bWJlcihzZWxmKToKICAgICAgICAiUmV0dXJuIHRoZSBsaW5lIG51bWJlciB3aGVyZSB0aGUgY3VycmVudCBldmVudCBlbmRzLiIKICAgICAgICByZXR1cm4gc2VsZi5fX2xvY2F0b3IuTGluZU51bWJlcigpCgogICAgZGVmIGdldFB1YmxpY0lkKHNlbGYpOgogICAgICAgICJSZXR1cm4gdGhlIHB1YmxpYyBpZGVudGlmaWVyIGZvciB0aGUgY3VycmVudCBldmVudC4iCiAgICAgICAgcmV0dXJuIE5vbmUKCiAgICBkZWYgZ2V0U3lzdGVtSWQoc2VsZik6CiAgICAgICAgIlJldHVybiB0aGUgc3lzdGVtIGlkZW50aWZpZXIgZm9yIHRoZSBjdXJyZW50IGV2ZW50LiIKICAgICAgICByZXR1cm4gc2VsZi5fX2xvY2F0b3IuQmFzZVVSSSgpCgpjbGFzcyBMaWJYbWwyUmVhZGVyKHhtbHJlYWRlci5YTUxSZWFkZXIpOgoKICAgIGRlZiBfX2luaXRfXyhzZWxmKToKICAgICAgICB4bWxyZWFkZXIuWE1MUmVhZGVyLl9faW5pdF9fKHNlbGYpCiAgICAgICAgIyBmZWF0dXJlcwogICAgICAgIHNlbGYuX19ucyA9IDAKICAgICAgICBzZWxmLl9fbnNwZnggPSAwCiAgICAgICAgc2VsZi5fX3ZhbGlkYXRlID0gMAogICAgICAgICMgcGFyc2luZyBmbGFnCiAgICAgICAgc2VsZi5fX3BhcnNpbmcgPSAwCiAgICAgICAgIyBhZGRpdGlvbmFsIGhhbmRsZXJzCiAgICAgICAgc2VsZi5fX2xleF9oYW5kbGVyID0gTm9uZQogICAgICAgIHNlbGYuX19kZWNsX2hhbmRsZXIgPSBOb25lCiAgICAgICAgIyBlcnJvciBtZXNzYWdlcyBhY2N1bXVsYXRvcgogICAgICAgIHNlbGYuX19lcnJvcnMgPSBOb25lCgogICAgZGVmIF9lcnJvckhhbmRsZXIoc2VsZixhcmcsbXNnLHNldmVyaXR5LGxvY2F0b3IpOgogICAgICAgIGlmIHNlbGYuX19lcnJvcnMgaXMgTm9uZToKICAgICAgICAgICAgc2VsZi5fX2Vycm9ycyA9IFtdCiAgICAgICAgc2VsZi5fX2Vycm9ycy5hcHBlbmQoKHNldmVyaXR5LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTQVhQYXJzZUV4Y2VwdGlvbihtc2csTm9uZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTG9jYXRvcihsb2NhdG9yKSkpKQoKICAgIGRlZiBfcmVwb3J0RXJyb3JzKHNlbGYsZmF0YWwpOgogICAgICAgIGZvciBzZXZlcml0eSxleGNlcHRpb24gaW4gc2VsZi5fX2Vycm9yczoKICAgICAgICAgICAgaWYgc2V2ZXJpdHkgaW4gKGxpYnhtbDIuUEFSU0VSX1NFVkVSSVRZX1ZBTElESVRZX1dBUk5JTkcsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBsaWJ4bWwyLlBBUlNFUl9TRVZFUklUWV9XQVJOSU5HKToKICAgICAgICAgICAgICAgIHNlbGYuX2Vycl9oYW5kbGVyLndhcm5pbmcoZXhjZXB0aW9uKQogICAgICAgICAgICBlbHNlOgogICAgICAgICAgICAgICAgIyB3aGVuIGZhdGFsIGlzIHNldCwgdGhlIHBhcnNlIHdpbGwgc3RvcDsKICAgICAgICAgICAgICAgICMgd2UgY29uc2lkZXIgdGhhdCB0aGUgbGFzdCBlcnJvciByZXBvcnRlZAogICAgICAgICAgICAgICAgIyBpcyB0aGUgZmF0YWwgb25lLgogICAgICAgICAgICAgICAgaWYgZmF0YWwgYW5kIGV4Y2VwdGlvbiBpcyBzZWxmLl9fZXJyb3JzWy0xXVsxXToKICAgICAgICAgICAgICAgICAgICBzZWxmLl9lcnJfaGFuZGxlci5mYXRhbEVycm9yKGV4Y2VwdGlvbikKICAgICAgICAgICAgICAgIGVsc2U6CiAgICAgICAgICAgICAgICAgICAgc2VsZi5fZXJyX2hhbmRsZXIuZXJyb3IoZXhjZXB0aW9uKQogICAgICAgIHNlbGYuX19lcnJvcnMgPSBOb25lCgogICAgZGVmIHBhcnNlKHNlbGYsIHNvdXJjZSk6CiAgICAgICAgc2VsZi5fX3BhcnNpbmcgPSAxCiAgICAgICAgdHJ5OgogICAgICAgICAgICAjIHByZXBhcmUgc291cmNlIGFuZCBjcmVhdGUgcmVhZGVyCiAgICAgICAgICAgIGlmIHR5cGUoc291cmNlKSBpbiBTdHJpbmdUeXBlczoKICAgICAgICAgICAgICAgIHJlYWRlciA9IGxpYnhtbDIubmV3VGV4dFJlYWRlckZpbGVuYW1lKHNvdXJjZSkKICAgICAgICAgICAgZWxzZToKICAgICAgICAgICAgICAgIHNvdXJjZSA9IHNheHV0aWxzLnByZXBhcmVfaW5wdXRfc291cmNlKHNvdXJjZSkKICAgICAgICAgICAgICAgIGlucHV0ID0gbGlieG1sMi5pbnB1dEJ1ZmZlcihzb3VyY2UuZ2V0Qnl0ZVN0cmVhbSgpKQogICAgICAgICAgICAgICAgcmVhZGVyID0gaW5wdXQubmV3VGV4dFJlYWRlcihzb3VyY2UuZ2V0U3lzdGVtSWQoKSkKICAgICAgICAgICAgcmVhZGVyLlNldEVycm9ySGFuZGxlcihzZWxmLl9lcnJvckhhbmRsZXIsTm9uZSkKICAgICAgICAgICAgIyBjb25maWd1cmUgcmVhZGVyCiAgICAgICAgICAgIHJlYWRlci5TZXRQYXJzZXJQcm9wKGxpYnhtbDIuUEFSU0VSX0xPQUREVEQsMSkKICAgICAgICAgICAgcmVhZGVyLlNldFBhcnNlclByb3AobGlieG1sMi5QQVJTRVJfREVGQVVMVEFUVFJTLDEpCiAgICAgICAgICAgIHJlYWRlci5TZXRQYXJzZXJQcm9wKGxpYnhtbDIuUEFSU0VSX1NVQlNUX0VOVElUSUVTLDEpCiAgICAgICAgICAgIHJlYWRlci5TZXRQYXJzZXJQcm9wKGxpYnhtbDIuUEFSU0VSX1ZBTElEQVRFLHNlbGYuX192YWxpZGF0ZSkKICAgICAgICAgICAgIyB3ZSByZXVzZSBhdHRyaWJ1dGUgbWFwcyAoZm9yIGEgc2xpZ2h0IHBlcmZvcm1hbmNlIGdhaW4pCiAgICAgICAgICAgIGlmIHNlbGYuX19uczoKICAgICAgICAgICAgICAgIGF0dHJpYnV0ZXNOU0ltcGwgPSB4bWxyZWFkZXIuQXR0cmlidXRlc05TSW1wbCh7fSx7fSkKICAgICAgICAgICAgZWxzZToKICAgICAgICAgICAgICAgIGF0dHJpYnV0ZXNJbXBsID0geG1scmVhZGVyLkF0dHJpYnV0ZXNJbXBsKHt9KQogICAgICAgICAgICAjIHByZWZpeGVzIHRvIHBvcCAoZm9yIGVuZFByZWZpeE1hcHBpbmcpCiAgICAgICAgICAgIHByZWZpeGVzID0gW10KICAgICAgICAgICAgIyBzdGFydCBsb29wCiAgICAgICAgICAgIHNlbGYuX2NvbnRfaGFuZGxlci5zdGFydERvY3VtZW50KCkKICAgICAgICAgICAgd2hpbGUgMToKICAgICAgICAgICAgICAgIHIgPSByZWFkZXIuUmVhZCgpCiAgICAgICAgICAgICAgICAjIGNoZWNrIGZvciBlcnJvcnMKICAgICAgICAgICAgICAgIGlmIHIgPT0gMToKICAgICAgICAgICAgICAgICAgICBpZiBub3Qgc2VsZi5fX2Vycm9ycyBpcyBOb25lOgogICAgICAgICAgICAgICAgICAgICAgICBzZWxmLl9yZXBvcnRFcnJvcnMoMCkKICAgICAgICAgICAgICAgIGVsaWYgciA9PSAwOgogICAgICAgICAgICAgICAgICAgIGlmIG5vdCBzZWxmLl9fZXJyb3JzIGlzIE5vbmU6CiAgICAgICAgICAgICAgICAgICAgICAgIHNlbGYuX3JlcG9ydEVycm9ycygwKQogICAgICAgICAgICAgICAgICAgIGJyZWFrICMgZW5kIG9mIHBhcnNlCiAgICAgICAgICAgICAgICBlbHNlOgogICAgICAgICAgICAgICAgICAgIGlmIG5vdCBzZWxmLl9fZXJyb3JzIGlzIE5vbmU6CiAgICAgICAgICAgICAgICAgICAgICAgIHNlbGYuX3JlcG9ydEVycm9ycygxKQogICAgICAgICAgICAgICAgICAgIGVsc2U6CiAgICAgICAgICAgICAgICAgICAgICAgIHNlbGYuX2Vycl9oYW5kbGVyLmZhdGFsRXJyb3IoXAogICAgICAgICAgICAgICAgICAgICAgICAgICAgU0FYRXhjZXB0aW9uKCJSZWFkIGZhaWxlZCAobm8gZGV0YWlscyBhdmFpbGFibGUpIikpCiAgICAgICAgICAgICAgICAgICAgYnJlYWsgIyBmYXRhbCBwYXJzZSBlcnJvcgogICAgICAgICAgICAgICAgIyBnZXQgbm9kZSB0eXBlCiAgICAgICAgICAgICAgICBub2RlVHlwZSA9IHJlYWRlci5Ob2RlVHlwZSgpCiAgICAgICAgICAgICAgICAjIEVsZW1lbnQKICAgICAgICAgICAgICAgIGlmIG5vZGVUeXBlID09IDE6IAogICAgICAgICAgICAgICAgICAgIGlmIHNlbGYuX19uczoKICAgICAgICAgICAgICAgICAgICAgICAgZWx0TmFtZSA9IChfZChyZWFkZXIuTmFtZXNwYWNlVXJpKCkpLFwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBfZChyZWFkZXIuTG9jYWxOYW1lKCkpKQogICAgICAgICAgICAgICAgICAgICAgICBlbHRRTmFtZSA9IF9kKHJlYWRlci5OYW1lKCkpCiAgICAgICAgICAgICAgICAgICAgICAgIGF0dHJpYnV0ZXNOU0ltcGwuX2F0dHJzID0gYXR0cnMgPSB7fQogICAgICAgICAgICAgICAgICAgICAgICBhdHRyaWJ1dGVzTlNJbXBsLl9xbmFtZXMgPSBxbmFtZXMgPSB7fQogICAgICAgICAgICAgICAgICAgICAgICBuZXdQcmVmaXhlcyA9IFtdCiAgICAgICAgICAgICAgICAgICAgICAgIHdoaWxlIHJlYWRlci5Nb3ZlVG9OZXh0QXR0cmlidXRlKCk6CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBxbmFtZSA9IF9kKHJlYWRlci5OYW1lKCkpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YWx1ZSA9IF9kKHJlYWRlci5WYWx1ZSgpKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgcW5hbWUuc3RhcnRzd2l0aCgieG1sbnMiKToKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiBsZW4ocW5hbWUpID4gNToKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV3UHJlZml4ID0gcW5hbWVbNjpdCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZToKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV3UHJlZml4ID0gTm9uZQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ld1ByZWZpeGVzLmFwcGVuZChuZXdQcmVmaXgpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2VsZi5fY29udF9oYW5kbGVyLnN0YXJ0UHJlZml4TWFwcGluZyhcCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ld1ByZWZpeCx2YWx1ZSkKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiBub3Qgc2VsZi5fX25zcGZ4OgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb250aW51ZSAjIGRvbid0IHJlcG9ydCB4bWxucyBhdHRyaWJ1dGUKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGF0dE5hbWUgPSAoX2QocmVhZGVyLk5hbWVzcGFjZVVyaSgpKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgX2QocmVhZGVyLkxvY2FsTmFtZSgpKSkKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHFuYW1lc1thdHROYW1lXSA9IHFuYW1lCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBhdHRyc1thdHROYW1lXSA9IHZhbHVlCiAgICAgICAgICAgICAgICAgICAgICAgIHJlYWRlci5Nb3ZlVG9FbGVtZW50KCkKICAgICAgICAgICAgICAgICAgICAgICAgc2VsZi5fY29udF9oYW5kbGVyLnN0YXJ0RWxlbWVudE5TKCBcCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHROYW1lLGVsdFFOYW1lLGF0dHJpYnV0ZXNOU0ltcGwpIAogICAgICAgICAgICAgICAgICAgICAgICBpZiByZWFkZXIuSXNFbXB0eUVsZW1lbnQoKToKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNlbGYuX2NvbnRfaGFuZGxlci5lbmRFbGVtZW50TlMoZWx0TmFtZSxlbHRRTmFtZSkKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZvciBuZXdQcmVmaXggaW4gbmV3UHJlZml4ZXM6CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2VsZi5fY29udF9oYW5kbGVyLmVuZFByZWZpeE1hcHBpbmcobmV3UHJlZml4KQogICAgICAgICAgICAgICAgICAgICAgICBlbHNlOgogICAgICAgICAgICAgICAgICAgICAgICAgICAgcHJlZml4ZXMuYXBwZW5kKG5ld1ByZWZpeGVzKQogICAgICAgICAgICAgICAgICAgIGVsc2U6CiAgICAgICAgICAgICAgICAgICAgICAgIGVsdE5hbWUgPSBfZChyZWFkZXIuTmFtZSgpKQogICAgICAgICAgICAgICAgICAgICAgICBhdHRyaWJ1dGVzSW1wbC5fYXR0cnMgPSBhdHRycyA9IHt9CiAgICAgICAgICAgICAgICAgICAgICAgIHdoaWxlIHJlYWRlci5Nb3ZlVG9OZXh0QXR0cmlidXRlKCk6CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBhdHROYW1lID0gX2QocmVhZGVyLk5hbWUoKSkKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGF0dHJzW2F0dE5hbWVdID0gX2QocmVhZGVyLlZhbHVlKCkpCiAgICAgICAgICAgICAgICAgICAgICAgIHJlYWRlci5Nb3ZlVG9FbGVtZW50KCkKICAgICAgICAgICAgICAgICAgICAgICAgc2VsZi5fY29udF9oYW5kbGVyLnN0YXJ0RWxlbWVudCggXAogICAgICAgICAgICAgICAgICAgICAgICAgICAgZWx0TmFtZSxhdHRyaWJ1dGVzSW1wbCkKICAgICAgICAgICAgICAgICAgICAgICAgaWYgcmVhZGVyLklzRW1wdHlFbGVtZW50KCk6CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZWxmLl9jb250X2hhbmRsZXIuZW5kRWxlbWVudChlbHROYW1lKQogICAgICAgICAgICAgICAgIyBFbmRFbGVtZW50CiAgICAgICAgICAgICAgICBlbGlmIG5vZGVUeXBlID09IDE1OiAKICAgICAgICAgICAgICAgICAgICBpZiBzZWxmLl9fbnM6CiAgICAgICAgICAgICAgICAgICAgICAgIHNlbGYuX2NvbnRfaGFuZGxlci5lbmRFbGVtZW50TlMoIFwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoX2QocmVhZGVyLk5hbWVzcGFjZVVyaSgpKSxfZChyZWFkZXIuTG9jYWxOYW1lKCkpKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBfZChyZWFkZXIuTmFtZSgpKSkKICAgICAgICAgICAgICAgICAgICAgICAgZm9yIHByZWZpeCBpbiBwcmVmaXhlcy5wb3AoKToKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNlbGYuX2NvbnRfaGFuZGxlci5lbmRQcmVmaXhNYXBwaW5nKHByZWZpeCkKICAgICAgICAgICAgICAgICAgICBlbHNlOgogICAgICAgICAgICAgICAgICAgICAgICBzZWxmLl9jb250X2hhbmRsZXIuZW5kRWxlbWVudChfZChyZWFkZXIuTmFtZSgpKSkKICAgICAgICAgICAgICAgICMgVGV4dAogICAgICAgICAgICAgICAgZWxpZiBub2RlVHlwZSA9PSAzOiAKICAgICAgICAgICAgICAgICAgICBzZWxmLl9jb250X2hhbmRsZXIuY2hhcmFjdGVycyhfZChyZWFkZXIuVmFsdWUoKSkpCiAgICAgICAgICAgICAgICAjIFdoaXRlc3BhY2UKICAgICAgICAgICAgICAgIGVsaWYgbm9kZVR5cGUgPT0gMTM6IAogICAgICAgICAgICAgICAgICAgIHNlbGYuX2NvbnRfaGFuZGxlci5pZ25vcmFibGVXaGl0ZXNwYWNlKF9kKHJlYWRlci5WYWx1ZSgpKSkKICAgICAgICAgICAgICAgICMgU2lnbmlmaWNhbnRXaGl0ZXNwYWNlCiAgICAgICAgICAgICAgICBlbGlmIG5vZGVUeXBlID09IDE0OgogICAgICAgICAgICAgICAgICAgIHNlbGYuX2NvbnRfaGFuZGxlci5jaGFyYWN0ZXJzKF9kKHJlYWRlci5WYWx1ZSgpKSkKICAgICAgICAgICAgICAgICMgQ0RBVEEKICAgICAgICAgICAgICAgIGVsaWYgbm9kZVR5cGUgPT0gNDoKICAgICAgICAgICAgICAgICAgICBpZiBub3Qgc2VsZi5fX2xleF9oYW5kbGVyIGlzIE5vbmU6CiAgICAgICAgICAgICAgICAgICAgICAgIHNlbGYuX19sZXhfaGFuZGxlci5zdGFydENEQVRBKCkKICAgICAgICAgICAgICAgICAgICBzZWxmLl9jb250X2hhbmRsZXIuY2hhcmFjdGVycyhfZChyZWFkZXIuVmFsdWUoKSkpCiAgICAgICAgICAgICAgICAgICAgaWYgbm90IHNlbGYuX19sZXhfaGFuZGxlciBpcyBOb25lOgogICAgICAgICAgICAgICAgICAgICAgICBzZWxmLl9fbGV4X2hhbmRsZXIuZW5kQ0RBVEEoKQogICAgICAgICAgICAgICAgIyBFbnRpdHlSZWZlcmVuY2UKICAgICAgICAgICAgICAgIGVsaWYgbm9kZVR5cGUgPT0gNToKICAgICAgICAgICAgICAgICAgICBpZiBub3Qgc2VsZi5fX2xleF9oYW5kbGVyIGlzIE5vbmU6CiAgICAgICAgICAgICAgICAgICAgICAgIHNlbGYuc3RhcnRFbnRpdHkoX2QocmVhZGVyLk5hbWUoKSkpCiAgICAgICAgICAgICAgICAgICAgcmVhZGVyLlJlc29sdmVFbnRpdHkoKQogICAgICAgICAgICAgICAgIyBFbmRFbnRpdHkKICAgICAgICAgICAgICAgIGVsaWYgbm9kZVR5cGUgPT0gMTY6CiAgICAgICAgICAgICAgICAgICAgaWYgbm90IHNlbGYuX19sZXhfaGFuZGxlciBpcyBOb25lOgogICAgICAgICAgICAgICAgICAgICAgICBzZWxmLmVuZEVudGl0eShfZChyZWFkZXIuTmFtZSgpKSkKICAgICAgICAgICAgICAgICMgUHJvY2Vzc2luZ0luc3RydWN0aW9uCiAgICAgICAgICAgICAgICBlbGlmIG5vZGVUeXBlID09IDc6IAogICAgICAgICAgICAgICAgICAgIHNlbGYuX2NvbnRfaGFuZGxlci5wcm9jZXNzaW5nSW5zdHJ1Y3Rpb24oIFwKICAgICAgICAgICAgICAgICAgICAgICAgX2QocmVhZGVyLk5hbWUoKSksX2QocmVhZGVyLlZhbHVlKCkpKQogICAgICAgICAgICAgICAgIyBDb21tZW50CiAgICAgICAgICAgICAgICBlbGlmIG5vZGVUeXBlID09IDg6CiAgICAgICAgICAgICAgICAgICAgaWYgbm90IHNlbGYuX19sZXhfaGFuZGxlciBpcyBOb25lOgogICAgICAgICAgICAgICAgICAgICAgICBzZWxmLl9fbGV4X2hhbmRsZXIuY29tbWVudChfZChyZWFkZXIuVmFsdWUoKSkpCiAgICAgICAgICAgICAgICAjIERvY3VtZW50VHlwZQogICAgICAgICAgICAgICAgZWxpZiBub2RlVHlwZSA9PSAxMDoKICAgICAgICAgICAgICAgICAgICAjaWYgbm90IHNlbGYuX19sZXhfaGFuZGxlciBpcyBOb25lOgogICAgICAgICAgICAgICAgICAgICMgICAgc2VsZi5fX2xleF9oYW5kbGVyLnN0YXJ0RFREKCkKICAgICAgICAgICAgICAgICAgICBwYXNzICMgVE9ETyAoaG93IHRvIGRldGVjdCBlbmREVEQ/IG9uIGZpcnN0IG5vbi1kdGQgZXZlbnQ/KQogICAgICAgICAgICAgICAgIyBYbWxEZWNsYXJhdGlvbgogICAgICAgICAgICAgICAgZWxpZiBub2RlVHlwZSA9PSAxNzoKICAgICAgICAgICAgICAgICAgICBwYXNzICMgVE9ETwogICAgICAgICAgICAgICAgIyBFbnRpdHkKICAgICAgICAgICAgICAgIGVsaWYgbm9kZVR5cGUgPT0gNjoKICAgICAgICAgICAgICAgICAgICBwYXNzICMgVE9ETyAoZW50aXR5IGRlY2wpCiAgICAgICAgICAgICAgICAjIE5vdGF0aW9uIChkZWNsKQogICAgICAgICAgICAgICAgZWxpZiBub2RlVHlwZSA9PSAxMjoKICAgICAgICAgICAgICAgICAgICBwYXNzICMgVE9ETwogICAgICAgICAgICAgICAgIyBBdHRyaWJ1dGUgKG5ldmVyIGluIHRoaXMgbG9vcCkKICAgICAgICAgICAgICAgICNlbGlmIG5vZGVUeXBlID09IDI6IAogICAgICAgICAgICAgICAgIyAgICBwYXNzCiAgICAgICAgICAgICAgICAjIERvY3VtZW50IChub3QgZXhwb3NlZCkKICAgICAgICAgICAgICAgICNlbGlmIG5vZGVUeXBlID09IDk6IAogICAgICAgICAgICAgICAgIyAgICBwYXNzCiAgICAgICAgICAgICAgICAjIERvY3VtZW50RnJhZ21lbnQgKG5ldmVyIHJldHVybmVkIGJ5IFhtbFJlYWRlcikKICAgICAgICAgICAgICAgICNlbGlmIG5vZGVUeXBlID09IDExOgogICAgICAgICAgICAgICAgIyAgICBwYXNzCiAgICAgICAgICAgICAgICAjIE5vbmUKICAgICAgICAgICAgICAgICNlbGlmIG5vZGVUeXBlID09IDA6CiAgICAgICAgICAgICAgICAjICAgIHBhc3MKICAgICAgICAgICAgICAgICMgLQogICAgICAgICAgICAgICAgZWxzZToKICAgICAgICAgICAgICAgICAgICByYWlzZSBTQVhFeGNlcHRpb24oIlVuZXhwZWN0ZWQgbm9kZSB0eXBlICVkIiAlIG5vZGVUeXBlKQogICAgICAgICAgICBpZiByID09IDA6CiAgICAgICAgICAgICAgICBzZWxmLl9jb250X2hhbmRsZXIuZW5kRG9jdW1lbnQoKQogICAgICAgICAgICByZWFkZXIuQ2xvc2UoKQogICAgICAgIGZpbmFsbHk6CiAgICAgICAgICAgIHNlbGYuX19wYXJzaW5nID0gMAoKICAgIGRlZiBzZXREVERIYW5kbGVyKHNlbGYsIGhhbmRsZXIpOgogICAgICAgICMgVE9ETyAod2hlbiBzdXBwb3J0ZWQsIHRoZSBpbmhlcml0ZWQgbWV0aG9kIHdvcmtzIGp1c3QgZmluZSkKICAgICAgICByYWlzZSBTQVhOb3RTdXBwb3J0ZWRFeGNlcHRpb24oIkRUREhhbmRsZXIgbm90IHN1cHBvcnRlZCIpCgogICAgZGVmIHNldEVudGl0eVJlc29sdmVyKHNlbGYsIHJlc29sdmVyKToKICAgICAgICAjIFRPRE8gKHdoZW4gc3VwcG9ydGVkLCB0aGUgaW5oZXJpdGVkIG1ldGhvZCB3b3JrcyBqdXN0IGZpbmUpCiAgICAgICAgcmFpc2UgU0FYTm90U3VwcG9ydGVkRXhjZXB0aW9uKCJFbnRpdHlSZXNvbHZlciBub3Qgc3VwcG9ydGVkIikKCiAgICBkZWYgZ2V0RmVhdHVyZShzZWxmLCBuYW1lKToKICAgICAgICBpZiBuYW1lID09IGZlYXR1cmVfbmFtZXNwYWNlczoKICAgICAgICAgICAgcmV0dXJuIHNlbGYuX19ucwogICAgICAgIGVsaWYgbmFtZSA9PSBmZWF0dXJlX25hbWVzcGFjZV9wcmVmaXhlczoKICAgICAgICAgICAgcmV0dXJuIHNlbGYuX19uc3BmeAogICAgICAgIGVsaWYgbmFtZSA9PSBmZWF0dXJlX3ZhbGlkYXRpb246CiAgICAgICAgICAgIHJldHVybiBzZWxmLl9fdmFsaWRhdGUKICAgICAgICBlbGlmIG5hbWUgPT0gZmVhdHVyZV9leHRlcm5hbF9nZXM6CiAgICAgICAgICAgIHJldHVybiAxICMgVE9ETyAoZG9lcyB0aGF0IHJlbGF0ZSB0byBQQVJTRVJfTE9BRERURCk/CiAgICAgICAgZWxpZiBuYW1lID09IGZlYXR1cmVfZXh0ZXJuYWxfcGVzOgogICAgICAgICAgICByZXR1cm4gMSAjIFRPRE8gKGRvZXMgdGhhdCByZWxhdGUgdG8gUEFSU0VSX0xPQUREVEQpPwogICAgICAgIGVsc2U6CiAgICAgICAgICAgIHJhaXNlIFNBWE5vdFJlY29nbml6ZWRFeGNlcHRpb24oIkZlYXR1cmUgJyVzJyBub3QgcmVjb2duaXplZCIgJSBcCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmFtZSkKCiAgICBkZWYgc2V0RmVhdHVyZShzZWxmLCBuYW1lLCBzdGF0ZSk6CiAgICAgICAgaWYgc2VsZi5fX3BhcnNpbmc6CiAgICAgICAgICAgIHJhaXNlIFNBWE5vdFN1cHBvcnRlZEV4Y2VwdGlvbigiQ2Fubm90IHNldCBmZWF0dXJlICVzICIgXAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIndoaWxlIHBhcnNpbmciICUgbmFtZSkKICAgICAgICBpZiBuYW1lID09IGZlYXR1cmVfbmFtZXNwYWNlczoKICAgICAgICAgICAgc2VsZi5fX25zID0gc3RhdGUKICAgICAgICBlbGlmIG5hbWUgPT0gZmVhdHVyZV9uYW1lc3BhY2VfcHJlZml4ZXM6CiAgICAgICAgICAgIHNlbGYuX19uc3BmeCA9IHN0YXRlCiAgICAgICAgZWxpZiBuYW1lID09IGZlYXR1cmVfdmFsaWRhdGlvbjoKICAgICAgICAgICAgc2VsZi5fX3ZhbGlkYXRlID0gc3RhdGUKICAgICAgICBlbGlmIG5hbWUgPT0gZmVhdHVyZV9leHRlcm5hbF9nZXM6CiAgICAgICAgICAgIGlmIHN0YXRlID09IDA6CiAgICAgICAgICAgICAgICAjIFRPRE8gKGRvZXMgdGhhdCByZWxhdGUgdG8gUEFSU0VSX0xPQUREVEQpPwogICAgICAgICAgICAgICAgcmFpc2UgU0FYTm90U3VwcG9ydGVkRXhjZXB0aW9uKCJGZWF0dXJlICclcycgbm90IHN1cHBvcnRlZCIgJSBcCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmFtZSkKICAgICAgICBlbGlmIG5hbWUgPT0gZmVhdHVyZV9leHRlcm5hbF9wZXM6CiAgICAgICAgICAgIGlmIHN0YXRlID09IDA6CiAgICAgICAgICAgICAgICAjIFRPRE8gKGRvZXMgdGhhdCByZWxhdGUgdG8gUEFSU0VSX0xPQUREVEQpPwogICAgICAgICAgICAgICAgcmFpc2UgU0FYTm90U3VwcG9ydGVkRXhjZXB0aW9uKCJGZWF0dXJlICclcycgbm90IHN1cHBvcnRlZCIgJSBcCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmFtZSkKICAgICAgICBlbHNlOgogICAgICAgICAgICByYWlzZSBTQVhOb3RSZWNvZ25pemVkRXhjZXB0aW9uKCJGZWF0dXJlICclcycgbm90IHJlY29nbml6ZWQiICUgXAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5hbWUpCgogICAgZGVmIGdldFByb3BlcnR5KHNlbGYsIG5hbWUpOgogICAgICAgIGlmIG5hbWUgPT0gcHJvcGVydHlfbGV4aWNhbF9oYW5kbGVyOgogICAgICAgICAgICByZXR1cm4gc2VsZi5fX2xleF9oYW5kbGVyCiAgICAgICAgZWxpZiBuYW1lID09IHByb3BlcnR5X2RlY2xhcmF0aW9uX2hhbmRsZXI6CiAgICAgICAgICAgIHJldHVybiBzZWxmLl9fZGVjbF9oYW5kbGVyCiAgICAgICAgZWxzZToKICAgICAgICAgICAgcmFpc2UgU0FYTm90UmVjb2duaXplZEV4Y2VwdGlvbigiUHJvcGVydHkgJyVzJyBub3QgcmVjb2duaXplZCIgJSBcCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmFtZSkKCiAgICBkZWYgc2V0UHJvcGVydHkoc2VsZiwgbmFtZSwgdmFsdWUpOiAgICAgCiAgICAgICAgaWYgbmFtZSA9PSBwcm9wZXJ0eV9sZXhpY2FsX2hhbmRsZXI6CiAgICAgICAgICAgIHNlbGYuX19sZXhfaGFuZGxlciA9IHZhbHVlCiAgICAgICAgZWxpZiBuYW1lID09IHByb3BlcnR5X2RlY2xhcmF0aW9uX2hhbmRsZXI6CiAgICAgICAgICAgICMgVE9ETzogcmVtb3ZlIGlmL3doZW4gbGlieG1sMiBzdXBwb3J0cyBkdGQgZXZlbnRzCiAgICAgICAgICAgIHJhaXNlIFNBWE5vdFN1cHBvcnRlZEV4Y2VwdGlvbigiUHJvcGVydHkgJyVzJyBub3Qgc3VwcG9ydGVkIiAlIFwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5hbWUpCiAgICAgICAgICAgIHNlbGYuX19kZWNsX2hhbmRsZXIgPSB2YWx1ZQogICAgICAgIGVsc2U6CiAgICAgICAgICAgIHJhaXNlIFNBWE5vdFJlY29nbml6ZWRFeGNlcHRpb24oIlByb3BlcnR5ICclcycgbm90IHJlY29nbml6ZWQiICUgXAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5hbWUpCgpkZWYgY3JlYXRlX3BhcnNlcigpOgogICAgcmV0dXJuIExpYlhtbDJSZWFkZXIoKQoK