0x4774567d…5ac5sent to0x914d7fec…43d7·#25,346,468·view on Etherscan
gICAgICAgICB0aGlzLmxvZygnZGVidWcnLCBgVXBkYXRlZCBwaXhlbGl6YXRpb24gdW5pZm9ybXM6IHJvd3M9JHttYXBwZWRQYXJhbXMucGl4ZWxSb3dzfSwgY29scz0ke3BpeGVsQ29sc30sIGJsZW5kPSR7bWFwcGVkUGFyYW1zLmJsZW5kRmFjdG9yLnRvRml4ZWQoMil9YCk7CgogICAgICAgIH0gY2F0Y2ggKGVycm9yKSB7CiAgICAgICAgICAgIHRoaXMubG9nKCdlcnJvcicsICdGYWlsZWQgdG8gd3JpdGUgcGl4ZWxpemF0aW9uIHVuaWZvcm1zOicsIGVycm9yKTsKICAgICAgICAgICAgdGhyb3cgZXJyb3I7CiAgICAgICAgfQogICAgfQoKICAgIC8qKgogICAgICogVXBkYXRlIGNhbnZhcyBkaW1lbnNpb25zIGZvciBwcm9wZXIgYXNwZWN0IHJhdGlvIGNhbGN1bGF0aW9uCiAgICAgKiBAcGFyYW0ge251bWJlcn0gd2lkdGggLSBDYW52YXMgd2lkdGggaW4gcGl4ZWxzCiAgICAgKiBAcGFyYW0ge251bWJlcn0gaGVpZ2h0IC0gQ2FudmFzIGhlaWdodCBpbiBwaXhlbHMKICAgICAqLwogICAgdXBkYXRlQ2FudmFzRGltZW5zaW9ucyh3aWR0aCwgaGVpZ2h0KSB7CiAgICAgICAgdGhpcy5jYW52YXNXaWR0aCA9IHdpZHRoOwogICAgICAgIHRoaXMuY2FudmFzSGVpZ2h0ID0gaGVpZ2h0OwogICAgICAgIAogICAgICAgIC8vIE1hcmsgdW5pZm9ybXMgYXMgbmVlZGluZyB1cGRhdGUgd2l0aCBuZXcgZGltZW5zaW9ucwogICAgICAgIHRoaXMuc3RhdGUudW5pZm9ybXMubmVlZHNVcGRhdGUgPSB0cnVlOwogICAgICAgIAogICAgICAgIHRoaXMubG9nKCdkZWJ1ZycsIGBDYW52YXMgZGltZW5zaW9ucyB1cGRhdGVkOiAke3dpZHRofXgke2hlaWdodH1gKTsKICAgIH0KCiAgICAvKioKICAgICAqIEdldCBwaXhlbGl6YXRpb24tc3BlY2lmaWMgc3RhdGUgZm9yIGRlYnVnZ2luZwogICAgICogQHJldHVybnMge09iamVjdH0gRXh0ZW5kZWQgc3RhdGUgd2l0aCBwaXhlbGl6YXRpb24gaW5mbwogICAgICovCiAgICBnZXRFZmZlY3RTdGF0ZSgpIHsKICAgICAgICBjb25zdCBiYXNlU3RhdGUgPSBzdXBlci5nZXRFZmZlY3RTdGF0ZSgpOwogICAgICAgIGNvbnN0IG1hcHBlZFBhcmFtcyA9IHRoaXMuc3RhdGUubWV0YWRhdGEuaXNJbml0aWFsaXplZCA/IHRoaXMuZ2V0TWFwcGVkUGFyYW1ldGVycygpIDogbnVsbDsKICAgICAgICAKICAgICAgICByZXR1cm4gewogICAgICAgICAgICAuLi5iYXNlU3RhdGUsCiAgICAgICAgICAgIHBpeGVsaXphdGlvbkNvbmZpZzogdGhpcy5jb25maWcsCiAgICAgICAgICAgIGN1cnJlbnRQaXhlbGl6YXRpb246IG1hcHBlZFBhcmFtcyA/IHsKICAgICAgICAgICAgICAgIHBpeGVsUm93czogbWFwcGVkUGFyYW1zLnBpeGVsUm93cywKICAgICAgICAgICAgICAgIHBpeGVsQ29sczogbWFwcGVkUGFyYW1zLnBpeGVsQ29scywKICAgICAgICAgICAgICAgIGdyYW51bGFyaXR5UGVyY2VudDogTWF0aC5yb3VuZChtYXBwZWRQYXJhbXMuZ3JhbnVsYXJpdHkgKiAxMDApCiAgICAgICAgICAgIH0gOiBudWxsLAogICAgICAgICAgICBjYW52YXNEaW1lbnNpb25zOiB7CiAgICAgICAgICAgICAgICB3aWR0aDogdGhpcy5jYW52YXNXaWR0aCB8fCAndW5rbm93bicsCiAgICAgICAgICAgICAgICBoZWlnaHQ6IHRoaXMuY2FudmFzSGVpZ2h0IHx8ICd1bmtub3duJwogICAgICAgICAgICB9CiAgICAgICAgfTsKICAgIH0KCiAgICAvKioKICAgICAqIEhlbHBlciBtZXRob2QgZm9yIGxvZ2dpbmcKICAgICAqLwogICAgbG9nKGxldmVsLCBtZXNzYWdlLCBkYXRhID0gbnVsbCkgewogICAgICAgIGlmICh0eXBlb2YgTG9nZ2VyICE9PSAndW5kZWZpbmVkJykgewogICAgICAgICAgICBMb2dnZXJbbGV2ZWxdKCdQSVhFTElaQVRJT04nLCBtZXNzYWdlLCBkYXRhKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBjb25zb2xlLmxvZyhgW1BJWEVMSVpBVElPTl0gWyR7bGV2ZWwudG9VcHBlckNhc2UoKX1dICR7bWVzc2FnZX1gLCBkYXRhIHx8ICcnKTsKICAgICAgICB9CiAgICB9Cn0KClBpeGVsaXphdGlvbkVmZmVjdDsKCgovLyBFZmZlY3RNYW5hZ2VyIC0gTWFuYWdlcyBlZmZlY3QgbGlmZWN5Y2xlLCBwaXBlbGluZXMsIGFuZCByZW5kZXJpbmcKLy8gdjI6IFVzZXMgcmVuZGVyZXIgYWJzdHJhY3Rpb24gaW5zdGVhZCBvZiBkaXJlY3QgR1BVIGFjY2VzcwovLyBIYW5kbGVzIGVmZmVjdCByZWdpc3RyYXRpb24sIHBpcGVsaW5lIGNyZWF0aW9uLCBhbmQgcGFyYW1ldGVyIHVwZGF0ZXMKCmNsYXNzIEVmZmVjdE1hbmFnZXIgewogICAgY29uc3RydWN0b3IocmVuZGVyZXIpIHsKICAgICAgICBpZiAoIXJlbmRlcmVyKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcignRWZmZWN0TWFuYWdlciByZXF1aXJlcyBhIHJlbmRlcmVyJyk7CiAgICAgICAgfQogICAgICAgIAogICAgICAgIHRoaXMucmVuZGVyZXIgPSByZW5kZXJlcjsKICAgICAgICAKICAgICAgICAvLyBTdHJ1Y3R1cmVkIHN0YXRlCiAgICAgICAgdGhpcy5zdGF0ZSA9IHsKICAgICAgICAgICAgLy8gUmVnaXN0ZXJlZCBlZmZlY3RzCiAgICAgICAgICAgIGVmZmVjdHM6IHsKICAgICAgICAgICAgICAgIGxpc3Q6IFtdLCAgICAgICAgICAgICAgICAgICAgLy8gQXJyYXkgb2YgRWZmZWN0IGluc3RhbmNlcwogICAgICAgICAgICAgICAgYnlJZDogbmV3IE1hcCgpLCAgICAgICAgICAgICAvLyBNYXAgb2YgaWQgLT4gRWZmZWN0CiAgICAgICAgICAgICAgICBwaXBlbGluZXM6IG5ldyBNYXAoKSwgICAgICAgIC8vIE1hcCBvZiBpZCAtPiBHUFVSZW5kZXJQaXBlbGluZQogICAgICAgICAgICAgICAgY3VycmVudEVmZmVjdElkOiBudWxsICAgICAgICAvLyBDdXJyZW50bHkgYWN0aXZlIGVmZmVjdAogICAgICAgICAgICB9LAogICAgICAgICAgICAKICAgICAgICAgICAgLy8gSW50ZXJhY3Rpb24gc3RhdGUKICAgICAgICAgICAgaW50ZXJhY3Rpb246IHsKICAgICAgICAgICAgICAgIGlzQWN0aXZlOiBmYWxzZSwKICAgICAgICAgICAgICAgIHBvc2l0aW9uOiB7IHg6IDAuNSwgeTogMC41IH0sCiAgICAgICAgICAgICAgICB0aW1lc3RhbXA6IDAKICAgICAgICAgICAgfSwKICAgICAgICAgICAgCiAgICAgICAgICAgIC8vIE1ldGFkYXRhCiAgICAgICAgICAgIG1ldGFkYXRhOiB7CiAgICAgICAgICAgICAgICBpc0luaXRpYWxpemVkOiBmYWxzZSwKICAgICAgICAgICAgICAgIGVmZmVjdHNSZWdpc3RlcmVkOiAwLAogICAgICAgICAgICAgICAgcGlwZWxpbmVzQ3JlYXRlZDogMAogICAgICAgICAgICB9CiAgICAgICAgfTsKICAgICAgICAKICAgICAgICB0aGlzLmxvZygnaW5mbycsICdFZmZlY3RNYW5hZ2VyIGNyZWF0ZWQnKTsKICAgIH0KICAgIAogICAgLyoqCiAgICAgKiBSZWdpc3RlciBhbiBlZmZlY3QgKGRlbGVnYXRlcyB0byByZW5kZXJlcikKICAgICAqIEBwYXJhbSB7RWZmZWN0fSBlZmZlY3QgLSBFZmZlY3QgaW5zdGFuY2UgdG8gcmVnaXN0ZXIKICAgICAqLwogICAgYXN5bmMgcmVnaXN0ZXJFZmZlY3QoZWZmZWN0KSB7CiAgICAgICAgaWYgKCFlZmZlY3QpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdDYW5ub3QgcmVnaXN0ZXIgbnVsbCBlZmZlY3QnKTsKICAgICAgICB9CiAgICAgICAgCiAgICAgICAgLy8gQ2hlY2sgZm9yIGR1cGxpY2F0ZSBJRHMKICAgICAgICBpZiAodGhpcy5zdGF0ZS5lZmZlY3RzLmJ5SWQuaGFzKGVmZmVjdC5pZCkpIHsKICAgICAgICAgICAgdGhpcy5sb2coJ3dhcm4nLCBgRWZmZWN0IElEICR7ZWZmZWN0LmlkfSBhbHJlYWR5IHJlZ2lzdGVyZWQsIHNraXBwaW5nYCk7CiAgICAgICAgICAgIHJldHVybjsKICAgICAgICB9CiAgICAgICAgCiAgICAgICAgdHJ5IHsKICAgICAgICAgICAgLy8gRGVsZWdhdGUgdG8gcmVuZGVyZXIgZm9yIEdQVSByZXNvdXJjZSBjcmVhdGlvbgogICAgICAgICAgICBhd2FpdCB0aGlzLnJlbmRlcmVyLnJlZ2lzdGVyRWZmZWN0KGVmZmVjdCk7CiAgICAgICAgICAgIGVmZmVjdC5zdGF0ZS5tZXRhZGF0YS5pc0luaXRpYWxpemVkID0gdHJ1ZTsKICAgICAgICAgICAgCiAgICAgICAgICAgIC8vIFN0b3JlIGVmZmVjdAogICAgICAgICAgICB0aGlzLnN0YXRlLmVmZmVjdHMubGlzdC5wdXNoKGVmZmVjdCk7CiAgICAgICAgICAgIHRoaXMuc3RhdGUuZWZmZWN0cy5ieUlkLnNldChlZmZlY3QuaWQsIGVmZmVjdCk7CiAgICAgICAgICAgIHRoaXMuc3RhdGUubWV0YWRhdGEuZWZmZWN0c1JlZ2lzdGVyZWQrKzsKICAgICAgICAgICAgCiAgICAgICAgICAgIC8vIFNldCBhcyBjdXJyZW50IGlmIGZpcnN0IGVmZmVjdAogICAgICAgICAgICBpZiAodGhpcy5zdGF0ZS5lZmZlY3RzLmN1cnJlbnRFZmZlY3RJZCA9PT0gbnVsbCkgewogICAgICAgICAgICAgICAgdGhpcy5zdGF0ZS5lZmZlY3RzLmN1cnJlbnRFZmZlY3RJZCA9IGVmZmVjdC5pZDsKICAgICAgICAgICAgfQogICAgICAgICAgICAKICAgICAgICAgICAgdGhpcy5sb2coJ2luZm8nLCBgRWZmZWN0IHJlZ2lzdGVyZWQ6ICR7ZWZmZWN0Lm5hbWV9IChJRDogJHtlZmZlY3QuaWR9KWApOwogICAgICAgICAgICAKICAgICAgICB9IGNhdGNoIChlcnJvcikgewogICAgICAgICAgICB0aGlzLmxvZygnZXJyb3InLCBgRmFpbGVkIHRvIHJlZ2lzdGVyIGVmZmVjdCAke2VmZmVjdC5uYW1lfTpgLCBlcnJvcik7CiAgICAgICAgICAgIHRocm93IGVycm9yOwogICAgICAgIH0KICAgIH0KICAgIAogICAgLyoqCiAgICAgKiBDcmVhdGUgcmVuZGVyIHBpcGVsaW5lIGZvciBhbiBlZmZlY3QgKGRlbGVnYXRlcyB0byByZW5kZXJlcikKICAgICAqIEBwYXJhbSB7RWZmZWN0fSBlZmZlY3QgLSBFZmZlY3QgdG8gY3JlYXRlIHBpcGVsaW5lIGZvcgogICAgICogQHBhcmFtIHtib29sZWFufSBuZWVkc1RleHR1cmVJbnB1dCAtIFdoZXRoZXIgZWZmZWN0IG5lZWRzIHRleHR1cmUgaW5wdXQgKGdyb3VwIDApCiAgICAgKiBAcmV0dXJucyB7UHJvbWlzZTxhbnk+fSBDcmVhdGVkIHBpcGVsaW5lICh0eXBlIGRlcGVuZHMgb24gcmVuZGVyZXIpCiAgICAgKi8KICAgIGFzeW5jIGNyZWF0ZVBpcGVsaW5lKGVmZmVjdCwgbmVlZHNUZXh0dXJlSW5wdXQgPSBmYWxzZSkgewogICAgICAgIHRyeSB7CiAgICAgICAgICAgIHRoaXMubG9nKCdkZWJ1ZycsIGBDcmVhdGluZyBwaXBlbGluZSBmb3IgJHtlZmZlY3QubmFtZX1gKTsKICAgICAgICAgICAgCiAgICAgICAgICAgIC8vIERlbGVnYXRlIHRvIHJlbmRlcmVyIGZvciBwaXBlbGluZSBjcmVhdGlvbgogICAgICAgICAgICBjb25zdCBwaXBlbGluZSA9IGF3YWl0IHRoaXMucmVuZGVyZXIuY3JlYXRlUGlwZWxpbmUoZWZmZWN0LCBuZWVkc1RleHR1cmVJbnB1dCk7CiAgICAgICAgICAgIAogICAgICAgICAgICAvLyBTdG9yZSBwaXBlbGluZSByZWZlcmVuY2UKICAgICAgICAgICAgdGhpcy5zdGF0ZS5lZmZlY3RzLnBpcGVsaW5lcy5zZXQoZWZmZWN0LmlkLCBwaXBlbGluZSk7CiAgICAgICAgICAgIHRoaXMuc3RhdGUubWV0YWRhdGEucGlwZWxpbmVzQ3JlYXRlZCsrOwogICAgICAgICAgICAKICAgICAgICAgICAgdGhpcy5sb2coJ2luZm8nLCBgUGlwZWxpbmUgY3JlYXRlZCBmb3IgJHtlZmZlY3QubmFtZX1gKTsKICAgICAgICAgICAgCiAgICAgICAgICAgIHJldHVybiBwaXBlbGluZTsKICAgICAgICAgICAgCiAgICAgICAgfSBjYXRjaCAoZXJyb3IpIHsKICAgICAgICAgICAgdGhpcy5sb2coJ2Vycm9yJywgYEZhaWxlZCB0byBjcmVhdGUgcGlwZWxpbmUgZm9yICR7ZWZmZWN0Lm5hbWV9OmAsIGVycm9yKTsKICAgICAgICAgICAgdGhyb3cgZXJyb3I7CiAgICAgICAgfQogICAgfQogICAgCiAgICAvKioKICAgICAqIEdldCBjdXJyZW50IGVmZmVjdAogICAgICogQHJldHVybnMge0VmZmVjdHxudWxsfSBDdXJyZW50IGVmZmVjdCBvciBudWxsCiAgICAgKi8KICAgIGdldEN1cnJlbnRFZmZlY3QoKSB7CiAgICAgICAgaWYgKHRoaXMuc3RhdGUuZWZmZWN0cy5jdXJyZW50RWZmZWN0SWQgPT09IG51bGwpIHsKICAgICAgICAgICAgcmV0dXJuIG51bGw7CiAgICAgICAgfQogICAgICAgIHJldHVybiB0aGlzLnN0YXRlLmVmZmVjdHMuYnlJZC5nZXQodGhpcy5zdGF0ZS5lZmZlY3RzLmN1cnJlbnRFZmZlY3RJZCk7CiAgICB9CiAgICAKICAgIC8qKgogICAgICogVXBkYXRlIGludGVyYWN0aW9uIHN0YXRlCiAgICAgKiBAcGFyYW0ge251bWJlcn0geCAtIE5vcm1hbGl6ZWQgWCBwb3NpdGlvbiAoMC0xKQogICAgICogQHBhcmFtIHtudW1iZXJ9IHkgLSBOb3JtYWxpemVkIFkgcG9zaXRpb24gKDAtMSkKICAgICAqIEBwYXJhbSB7Ym9vbGVhbn0gaXNBY3RpdmUgLSBXaGV0aGVyIGludGVyYWN0aW9uIGlzIGFjdGl2ZQogICAgICovCiAgICB1cGRhdGVJbnRlcmFjdGlvbih4LCB5LCBpc0FjdGl2ZSkgewogICAgICAgIHRoaXMuc3RhdGUuaW50ZXJhY3Rpb24gPSB7CiAgICAgICAgICAgIGlzQWN0aXZlLAogICAgICAgICAgICBwb3NpdGlvbjogeyB4LCB5IH0sCiAgICAgICAgICAgIHRpbWVzdGFtcDogcGVyZm9ybWFuY2Uubm93KCkKICAgICAgICB9OwogICAgICAgIAogICAgICAgIGlmIChpc0FjdGl2ZSkgewogICAgICAgICAgICAvLyBVcGRhdGUgcGl4ZWxpemF0aW9uIGVmZmVjdCAoSUQ6IDEpIHdpdGggWSBwYXJhbWV0ZXIKICAgICAgICAgICAgY29uc3QgcGl4ZWxpemF0aW9uRWZmZWN0ID0gdGhpcy5zdGF0ZS5lZmZlY3RzLmJ5SWQuZ2V0KDEpOwogICAgICAgICAgICBpZiAocGl4ZWxpemF0aW9uRWZmZWN0KSB7CiAgICAgICAgICAgICAgICBwaXhlbGl6YXRpb25FZmZlY3QudXBkYXRlUGFyYW1ldGVycyh4LCB5KTsKICAgICAgICAgICAgICAgIC8vIERlYnVnOiBMb2cgdGhlIHVwZGF0ZWQgcGFyYW1ldGVycwogICAgICAgICAgICAgICAgY29uc3QgbWFwcGVkUGFyYW1zID0gcGl4ZWxpemF0aW9uRWZmZWN0LmdldE1hcHBlZFBhcmFtZXRlcnMoKTsKICAgICAgICAgICAgICAgIExvZ2dlci5kZWJ1ZygnRUZGRUNUX01HUicsIGBJbnRlcmFjdGlvbiBZPSR7eS50b0ZpeGVkKDMpfSDihpIgcGl4ZWxSb3dzPSR7bWFwcGVkUGFyYW1zLnBpeGVsUm93c31gKTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0KICAgIAogICAgLyoqCiAgICAgKiBDaGVjayBpZiBjdXJyZW50bHkgaW4gaW50ZXJhY3RpdmUgbW9kZQogICAgICogQHJldHVybnMge2Jvb2xlYW59IFRydWUgaWYgaW50ZXJhY3RpbmcKICAgICAqLwogICAgaXNJbnRlcmFjdGluZygpIHsKICAgICAgICByZXR1cm4gdGhpcy5zdGF0ZS5pbnRlcmFjdGlvbi5pc0FjdGl2ZTsKICAgIH0KICAgIAogICAgLyoqCiAgICAgKiBHZXQgZWZmZWN0IG1hbmFnZXIgc3RhdGUgZm9yIGRlYnVnZ2luZwogICAgICogQHJldHVybnMge09iamVjdH0gQ3VycmVudCBzdGF0ZQogICAgICovCiAgICBnZXRTdGF0ZSgpIHsKICAgICAgICByZXR1cm4gewogICAgICAgICAgICBlZmZlY3RzUmVnaXN0ZXJlZDogdGhpcy5zdGF0ZS5tZXRhZGF0YS5lZmZlY3RzUmVnaXN0ZXJlZCwKICAgICAgICAgICAgcGlwZWxpbmVzQ3JlYXRlZDogdGhpcy5zdGF0ZS5tZXRhZGF0YS5waXBlbGluZXNDcmVhdGVkLAogICAgICAgICAgICBjdXJyZW50RWZmZWN0OiB0aGlzLmdldEN1cnJlbnRFZmZlY3QoKT8ubmFtZSB8fCAnbm9uZScsCiAgICAgICAgICAgIGVmZmVjdHNMaXN0OiB0aGlzLnN0YXRlLmVmZmVjdHMubGlzdC5tYXAoZSA9PiAoewogICAgICAgICAgICAgICAgaWQ6IGUuaWQsCiAgICAgICAgICAgICAgICBuYW1lOiBlLm5hbWUsCiAgICAgICAgICAgICAgICBpc0luaXRpYWxpemVkOiBlLmlzSW5pdGlhbGl6ZWQoKQogICAgICAgICAgICB9KSksCiAgICAgICAgICAgIGlzSW50ZXJhY3Rpbmc6IHRoaXMuc3RhdGUuaW50ZXJhY3Rpb24uaXNBY3RpdmUsCiAgICAgICAgICAgIGludGVyYWN0aW9uUG9zaXRpb246IHsgLi4udGhpcy5zdGF0ZS5pbnRlcmFjdGlvbi5wb3NpdGlvbiB9CiAgICAgICAgfTsKICAgIH0KICAgIAogICAgLyoqCiAgICAgKiBDbGVhbiB1cCBhbGwgcmVzb3VyY2VzCiAgICAgKi8KICAgIGRlc3Ryb3koKSB7CiAgICAgICAgLy8gRGVzdHJveSBhbGwgZWZmZWN0cwogICAgICAgIGZvciAoY29uc3QgZWZmZWN0IG9mIHRoaXMuc3RhdGUuZWZmZWN0cy5saXN0KSB7CiAgICAgICAgICAgIGVmZmVjdC5kZXN0cm95KCk7CiAgICAgICAgfQogICAgICAgIAogICAgICAgIC8vIENsZWFyIHN0YXRlCiAgICAgICAgdGhpcy5zdGF0ZS5lZmZlY3RzLmxpc3QgPSBbXTsKICAgICAgICB0aGlzLnN0YXRlLmVmZmVjdHMuYnlJZC5jbGVhcigpOwogICAgICAgIHRoaXMuc3RhdGUuZWZmZWN0cy5waXBlbGluZXMuY2xlYXIoKTsKICAgICAgICB0aGlzLnN0YXRlLmVmZmVjdHMuY3VycmVudEVmZmVjdElkID0gbnVsbDsKICAgICAgICAKICAgICAgICB0aGlzLmxvZygnaW5mbycsICdFZmZlY3RNYW5hZ2VyIGRlc3Ryb3llZCcpOwogICAgfQogICAgCiAgICAvKioKICAgICAqIEhlbHBlciBtZXRob2QgZm9yIGxvZ2dpbmcKICAgICAqLwogICAgbG9nKGxldmVsLCBtZXNzYWdlLCBkYXRhID0gbnVsbCkgewogICAgICAgIExvZ2dlcltsZXZlbF0oJ0VGRkVDVF9NR1InLCBtZXNzYWdlLCBkYXRhKTsKICAgIH0KfQoKRWZmZWN0TWFuYWdlcjsKCgovKioKICogQXVkaW9Db250cm9sbGVyLmpzCiAqIE1hbmFnZXMgV2ViIEF1ZGlvIEFQSSBmb3IgVFYgc3RhdGljIHdoaXRlIG5vaXNlIGdlbmVyYXRpb24KICogUGhhc2UgRDogQ29udGludW91cyB3aGl0ZSBub2lzZSBwbGF5YmFjawogKiBQaGFzZSBFOiBJbnRlcmFjdGl2ZSBjb250cm9scyAoWS1heGlzOiBsb3ctcGFzcyBmaWx0ZXIsIFgtYXhpczogcmh5dGhtKQogKi8KCmNsYXNzIEF1ZGlvQ29udHJvbGxlciB7CiAgICBjb25zdHJ1Y3RvcigpIHsKICAgICAgICAvLyA9PT09PSBUVU5BQkxFIENPTkZJR1VSQVRJT04gPT09PT0KICAgICAgICAvLyBFYXN5IGFjY2VzcyBmb3IgYWRqdXN0aW5nIGF1ZGlvIHBhcmFtZXRlcnMKICAgICAgICB0aGlzLmNvbmZpZyA9IHsKICAgICAgICAgICAgLy8gTG93LXBhc3MgZmlsdGVyIHNldHRpbmdzIChZLWF4aXMgY29udHJvbCkKICAgICAgICAgICAgZmlsdGVyOiB7CiAgICAgICAgICAgICAgICBtaW5GcmVxdWVuY3k6IDE0NywgICAgIC8vIEJvdHRvbSBvZiBZLWF4aXMgKG1vc3QgbXVmZmxlZCkgLSBIegogICAgICAgICAgICAgICAgbWF4RnJlcXVlbmN5OiA0OTAwLCAgICAvLyBUb3Agb2YgWS1heGlzIChicmlnaHRlc3QpIC0gSHoKICAgICAgICAgICAgICAgIHJlc29uYW5jZTogNi4wICAgICAgICAgLy8gUSBmYWN0b3IgLSBoaWdoZXIgPSBtb3JlIHByb25vdW5jZWQgZmlsdGVyaW5nCiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIAogICAgICAgICAgICAvLyBSaHl0aG0gc2V0dGluZ3MgKFgtYXhpcyBjb250cm9sKQogICAgICAgICAgICByaHl0aG06IHsKICAgICAgICAgICAgICAgIG1pblJhdGU6IDMsICAgICAgICAgICAgLy8gTWluaW11bSBwdWxzZSByYXRlIChsZWZ0IHNpZGUpIC0gSHogKHB1bHNlcyBwZXIgc2Vjb25kKQogICAgICAgICAgICAgICAgbWF4UmF0ZTogMTMsICAgICAgICAgLy8gTWF4aW11bSBwdWxzZSByYXRlIChyaWdodCBzaWRlKSAtIEh6CiAgICAgICAgICAgICAgICAvLyBBRFNSIGVudmVsb3BlIGZvciBlYWNoIHB1bHNlIChpbiBzZWNvbmRzKQogICAgICAgICAgICAgICAgYXR0YWNrOiAwLjAwMDEsICAgICAgICAvLyBBdHRhY2sgdGltZSAtIGhvdyBmYXN0IGl0IGZhZGVzIGluCiAgICAgICAgICAgICAgICBkZWNheTogMC4wNywgICAgICAgICAgIC8vIERlY2F5IHRpbWUgLSBob3cgbG9uZyBpdCB0YWtlcyB0byBkZWNheSBhZnRlciBhdHRhY2sKICAgICAgICAgICAgICAgIHN1c3RhaW46IDAuMDAxLCAgICAgICAgLy8gU3VzdGFpbiBsZXZlbCAoMC0xKSAtIGxldmVsIGR1cmluZyBzdXN0YWluIHBoYXNlCiAgICAgICAgICAgICAgICByZWxlYXNlOiAwLjAyLCAgICAgICAgIC8vIFJlbGVhc2UgdGltZSAtIGhvdyBsb25nIHRvIGZhZGUgb3V0CiAgICAgICAgICAgICAgICBzY2hlZHVsZUFoZWFkOiAwLjIgICAgIC8vIEhvdyBmYXIgYWhlYWQgdG8gc2NoZWR1bGUgcHVsc2VzIChzZWNvbmRzKQogICAgICAgICAgICB9LAogICAgICAgICAgICAKICAgICAgICAgICAgLy8gTWFzdGVyIHZvbHVtZQogICAgICAgICAgICB2b2x1bWU6IDAuMywgICAgICAgICAgICAgICAvLyBWb2x1bWUgbGV2ZWwgKDAtMSkKICAgICAgICAgICAgCiAgICAgICAgICAgIC8vIEF1ZGlvIGVuZ2luZSBzZXR0aW5ncwogICAgICAgICAgICBzYW1wbGVSYXRlOiA0NDEwMCwgICAgICAgICAvLyBBdWRpbyBzYW1wbGUgcmF0ZQogICAgICAgICAgICBidWZmZXJTaXplOiAyLCAgICAgICAgICAgICAvLyBXaGl0ZSBub2lzZSBidWZmZXIgZHVyYXRpb24gaW4gc2Vjb25kcwogICAgICAgICAgICBlbmFibGVMb2dnaW5nOiB0cnVlICAgICAgICAvLyBEZWJ1ZyBsb2dnaW5nCiAgICAgICAgfTsKICAgICAgICAvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogICAgICAgIAogICAgICAgIHRoaXMuc3RhdGUgPSB7CiAgICAgICAgICAgIC8vIEF1ZGlvIGNvbnRleHQgYW5kIG5vZGVzCiAgICAgICAgICAgIGF1ZGlvQ29udGV4dDogbnVsbCwKICAgICAgICAgICAgbm9kZXM6IHsKICAgICAgICAgICAgICAgIHdoaXRlTm9pc2U6IG51bGwsICAgICAgLy8gV2hpdGUgbm9pc2UgYnVmZmVyIHNvdXJjZQogICAgICAgICAgICAgICAgZ2Fpbk5vZGU6IG51bGwsICAgICAgICAvLyBNYXN0ZXIgdm9sdW1lIGNvbnRyb2wKICAgICAgICAgICAgICAgIGZpbHRlck5vZGU6IG51bGwsICAgICAgLy8gTG93LXBhc3MgZmlsdGVyIChQaGFzZSBFIC0gWS1heGlzKQogICAgICAgICAgICAgICAgcmh5dGhtR2FpbjogbnVsbCwgICAgICAvLyBSaHl0aG0gZ2FpbiBmb3IgQURTUiBlbnZlbG9wZSAoUGhhc2UgRSAtIFgtYXhpcykKICAgICAgICAgICAgICAgIGRyb25lR2FpbjogbnVsbCwgICAgICAgLy8gRHJvbmUgZ2FpbiBmb3IgYmFja2dyb3VuZCBkcm9uZSBjb250cm9sIChzcGFjZSBiYXIgdG9nZ2xlKQogICAgICAgICAgICB9LAogICAgICAgICAgICAKICAgICAgICAgICAgLy8gUGxheWJhY2sgc3RhdGUKICAgICAgICAgICAgcGxheWJhY2s6IHsKICAgICAgICAgICAgICAgIGlzUGxheWluZzogZmFsc2UsCiAgICAgICAgICAgICAgICBpc0luaXRpYWxpemVkOiBmYWxzZSwKICAgICAgICAgICAgICAgIHN0YXJ0VGltZTogMAogICAgICAgICAgICB9LAogICAgICAgICAgICAKICAgICAgICAgICAgLy8gUmh5dGhtIGNvbnRyb2wgc3RhdGUKICAgICAgICAgICAgcmh5dGhtOiB7CiAgICAgICAgICAgICAgICBpc0FjdGl2ZTogZmFsc2UsICAgICAgIC8vIFdoZXRoZXIgcmh5dGhtIGlzIGFjdGl2ZSAoWCA+IDApCiAgICAgICAgICAgICAgICBjdXJyZW50UmF0ZTogMCwgICAgICAgIC8vIEN1cnJlbnQgcHVsc2UgcmF0ZSBpbiBIegogICAgICAgICAgICAgICAgbmV4dFB1bHNlVGltZTogMCwgICAgICAvLyBXaGVuIHRoZSBuZXh0IHB1bHNlIHNob3VsZCB0cmlnZ2VyCiAgICAgICAgICAgICAgICBzY2hlZHVsZXJUaW1lcjogbnVsbCAgIC8vIFRpbWVyIGZvciBwdWxzZSBzY2hlZHVsaW5nCiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIAogICAgICAgICAgICAvLyBEcm9uZSBtb2RlIHN0YXRlIChzcGFjZSBiYXIgdG9nZ2xlKQogICAgICAgICAgICBkcm9uZU1vZGU6IHsKICAgICAgICAgICAgICAgIGVuYWJsZWQ6IHRydWUsICAgICAgICAgLy8gU3RhcnQgaW4gZHJvbmUgbW9kZSBPTiAoZGVmYXVsdC9jdXJyZW50IGJlaGF2aW9yKQogICAgICAgICAgICAgICAgaXNJbnRlcmFjdGluZzogZmFsc2UgICAvLyBUcmFjayBpZiBjdXJyZW50bHkgY2xpY2tpbmcvZHJhZ2dpbmcKICAgICAgICAgICAgfSwKICAgICAgICAgICAgCiAgICAgICAgICAgIC8vIEN1cnJlbnQgYXVkaW8gcGFyYW1ldGVycwogICAgICAgICAgICBwYXJhbWV0ZXJzOiB7CiAgICAgICAgICAgICAgICB2b2x1bWU6IDAuMywgICAgICAgICAgIC8vIE1hc3RlciB2b2x1bWUgKDAtMSkKICAgICAgICAgICAgICAgIGZpbHRlckZyZXF1ZW5jeTogNDkwMCwgLy8gTG93LXBhc3MgZmlsdGVyIGN1dG9mZiAtIHN0YXJ0cyBhdCBtYXggKG5vIGZpbHRlcmluZykKICAgICAgICAgICAgICAgIHJoeXRobVJhdGU6IDAgICAgICAgICAgLy8gUmh5dGhtIHJhdGUgaW4gSHogKDAgPSBjb250aW51b3VzL2Ryb25lKQogICAgICAgICAgICB9CiAgICAgICAgfTsKICAgICAgICAKICAgICAgICBMb2dnZXIuaW5mbygnQVVESU8nLCAnQXVkaW9Db250cm9sbGVyIGNyZWF0ZWQnKTsKICAgIH0KICAgIAogICAgLyoqCiAgICAgKiBJbml0aWFsaXplIFdlYiBBdWRpbyBBUEkgKG11c3QgYmUgY2FsbGVkIGFmdGVyIHVzZXIgaW50ZXJhY3Rpb24pCiAgICAgKiBAcmV0dXJucyB7UHJvbWlzZTxib29sZWFuPn0gVHJ1ZSBpZiBpbml0aWFsaXphdGlvbiBzdWNjZXNzZnVsCiAgICAgKi8KICAgIGFzeW5jIGluaXRpYWxpemUoKSB7CiAgICAgICAgdHJ5IHsKICAgICAgICAgICAgaWYgKHRoaXMuc3RhdGUucGxheWJhY2suaXNJbml0aWFsaXplZCkgewogICAgICAgICAgICAgICAgTG9nZ2VyLndhcm4oJ0FVRElPJywgJ0FscmVhZHkgaW5pdGlhbGl6ZWQnKTsKICAgICAgICAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgICAgICB9CiAgICAgICAgICAgIAogICAgICAgICAgICBMb2dnZXIuaW5mbygnQVVESU8nLCAnSW5pdGlhbGl6aW5nIFdlYiBBdWRpbyBBUEkuLi4nKTsKICAgICAgICAgICAgCiAgICAgICAgICAgIC8vIENyZWF0ZSBhdWRpbyBjb250ZXh0CiAgICAgICAgICAgIGNvbnN0IEF1ZGlvQ29udGV4dENsYXNzID0gd2luZG93LkF1ZGlvQ29udGV4dCB8fCB3aW5kb3cud2Via2l0QXVkaW9Db250ZXh0OwogICAgICAgICAgICB0aGlzLnN0YXRlLmF1ZGlvQ29udGV4dCA9IG5ldyBBdWRpb0NvbnRleHRDbGFzcyh7CiAgICAgICAgICAgICAgICBzYW1wbGVSYXRlOiB0aGlzLmNvbmZpZy5zYW1wbGVSYXRlCiAgICAgICAgICAgIH0pOwogICAgICAgICAgICAKICAgICAgICAgICAgLy8gQ3JlYXRlIGF1ZGlvIGdyYXBoCiAgICAgICAgICAgIGF3YWl0IHRoaXMuY3JlYXRlQXVkaW9HcmFwaCgpOwogICAgICAgICAgICAKICAgICAgICAgICAgdGhpcy5zdGF0ZS5wbGF5YmFjay5pc0luaXRpYWxpemVkID0gdHJ1ZTsKICAgICAgICAgICAgTG9nZ2VyLmluZm8oJ0FVRElPJywgYEF1ZGlvIGluaXRpYWxpemVkIChzYW1wbGUgcmF0ZTogJHt0aGlzLnN0YXRlLmF1ZGlvQ29udGV4dC5zYW1wbGVSYXRlfUh6KWApOwogICAgICAgICAgICAKICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgICAgIAogICAgICAgIH0gY2F0Y2ggKGVycm9yKSB7CiAgICAgICAgICAgIExvZ2dlci5lcnJvcignQVVESU8nLCAnRmFpbGVkIHRvIGluaXRpYWxpemUgYXVkaW86JywgZXJyb3IpOwogICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgfQogICAgfQogICAgCiAgICAvKioKICAgICAqIENyZWF0ZSB0aGUgYXVkaW8gcHJvY2Vzc2luZyBncmFwaAogICAgICovCiAgICBhc3luYyBjcmVhdGVBdWRpb0dyYXBoKCkgewogICAgICAgIGNvbnN0IGN0eCA9IHRoaXMuc3RhdGUuYXVkaW9Db250ZXh0OwogICAgICAgIAogICAgICAgIC8vIENyZWF0ZSByaHl0aG0gZ2FpbiBub2RlIGZvciBBRFNSIGVudmVsb3BlIChQaGFzZSBFIC0gWC1heGlzIGNvbnRyb2wpCiAgICAgICAgdGhpcy5zdGF0ZS5ub2Rlcy5yaHl0aG1HYWluID0gY3R4LmNyZWF0ZUdhaW4oKTsKICAgICAgICAvLyBTdGFydCBhdCAxLjAgaWYgZHJvbmUgT04gKGNvbnRpbnVvdXMpLCAwLjAgaWYgZHJvbmUgT0ZGIChyZWFkeSBmb3IgaW5zdGFudCBmaXJzdCBub3RlKQogICAgICAgIHRoaXMuc3RhdGUubm9kZXMucmh5dGhtR2Fpbi5nYWluLnZhbHVlID0gdGhpcy5zdGF0ZS5kcm9uZU1vZGUuZW5hYmxlZCA/IDEuMCA6IDAuMDsKICAgICAgICAKICAgICAgICAvLyBDcmVhdGUgZHJvbmUgZ2FpbiBub2RlIGZvciBiYWNrZ3JvdW5kIGRyb25lIGNvbnRyb2wgKHNwYWNlIGJhciB0b2dnbGUpCiAgICAgICAgdGhpcy5zdGF0ZS5ub2Rlcy5kcm9uZUdhaW4gPSBjdHguY3JlYXRlR2FpbigpOwogICAgICAgIHRoaXMuc3RhdGUubm9kZXMuZHJvbmVHYWluLmdhaW4udmFsdWUgPSAxLjA7IC8vIFN0YXJ0IGF0IGZ1bGwgdm9sdW1lIChkcm9uZSBtb2RlIE9OKQogICAgICAgIAogICAgICAgIC8vIENyZWF0ZSBsb3ctcGFzcyBmaWx0ZXIgKFBoYXNlIEUgLSBZLWF4aXMgY29udHJvbCkKICAgICAgICB0aGlzLnN0YXRlLm5vZGVzLmZpbHRlck5vZGUgPSBjdHguY3JlYXRlQmlxdWFkRmlsdGVyKCk7CiAgICAgICAgdGhpcy5zdGF0ZS5ub2Rlcy5maWx0ZXJOb2RlLnR5cGUgPSAnbG93cGFzcyc7CiAgICAgICAgdGhpcy5zdGF0ZS5ub2Rlcy5maWx0ZXJOb2RlLmZyZXF1ZW5jeS52YWx1ZSA9IHRoaXMuY29uZmlnLmZpbHRlci5tYXhGcmVxdWVuY3k7IC8vIFN0YXJ0IGF0IG1heCAobm8gZmlsdGVyaW5nKQogICAgICAgIHRoaXMuc3RhdGUubm9kZXMuZmlsdGVyTm9kZS5RLnZhbHVlID0gdGhpcy5jb25maWcuZmlsdGVyLnJlc29uYW5jZTsgLy8gUmVzb25hbmNlL2NoYXJhY3RlcgogICAgICAgIAogICAgICAgIC8vIENyZWF0ZSBtYXN0ZXIgZ2FpbiBub2RlIGZvciB2b2x1bWUgY29udHJvbAogICAgICAgIHRoaXMuc3RhdGUubm9kZXMuZ2Fpbk5vZGUgPSBjdHguY3JlYXRlR2FpbigpOwogICAgICAgIHRoaXMuc3RhdGUubm9kZXMuZ2Fpbk5vZGUuZ2Fpbi52YWx1ZSA9IHRoaXMuY29uZmlnLnZvbHVtZTsKICAgICAgICAKICAgICAgICAvLyBDb25uZWN0OiBmaWx0ZXIg4oaSIHJoeXRobSBnYWluIOKGkiBkcm9uZSBnYWluIOKGkiBtYXN0ZXIgZ2FpbiDihpIgZGVzdGluYXRpb24KICAgICAgICB0aGlzLnN0YXRlLm5vZGVzLmZpbHRlck5vZGUuY29ubmVjdCh0aGlzLnN0YXRlLm5vZGVzLnJoeXRobUdhaW4pOwogICAgICAgIHRoaXMuc3RhdGUubm9kZXMucmh5dGhtR2Fpbi5jb25uZWN0KHRoaXMuc3RhdGUubm9kZXMuZHJvbmVHYWluKTsKICAgICAgICB0aGlzLnN0YXRlLm5vZGVzLmRyb25lR2Fpbi5jb25uZWN0KHRoaXMuc3RhdGUubm9kZXMuZ2Fpbk5vZGUpOwogICAgICAgIHRoaXMuc3RhdGUubm9kZXMuZ2Fpbk5vZGUuY29ubmVjdChjdHguZGVzdGluYXRpb24pOwogICAgICAgIAogICAgICAgIExvZ2dlci5pbmZvKCdBVURJTycsIGBBdWRpbyBncmFwaCBjcmVhdGVkIChmaWx0ZXI6ICR7dGhpcy5jb25maWcuZmlsdGVyLm1pbkZyZXF1ZW5jeX0tJHt0aGlzLmNvbmZpZy5maWx0ZXIubWF4RnJlcXVlbmN5fUh6LCBROiAke3RoaXMuY29uZmlnLmZpbHRlci5yZXNvbmFuY2V9LCByaHl0aG06ICR7dGhpcy5jb25maWcucmh5dGhtLm1pblJhdGV9LSR7dGhpcy5jb25maWcucmh5dGhtLm1heFJhdGV9SHosIGRyb25lOiAke3RoaXMuc3RhdGUuZHJvbmVNb2RlLmVuYWJsZWQgPyAnT04nIDogJ09GRid9KWApOwogICAgfQogICAgCiAgICAvKioKICAgICAqIEdlbmVyYXRlIHdoaXRlIG5vaXNlIGJ1ZmZlcgogICAgICogQHJldHVybnMge0F1ZGlvQnVmZmVyfSBCdWZmZXIgY29udGFpbmluZyB3aGl0ZSBub2lzZQogICAgICovCiAgICBnZW5lcmF0ZVdoaXRlTm9pc2VCdWZmZXIoKSB7CiAgICAgICAgY29uc3QgY3R4ID0gdGhpcy5zdGF0ZS5hdWRpb0NvbnRleHQ7CiAgICAgICAgY29uc3QgYnVmZmVyU2l6ZSA9IGN0eC5zYW1wbGVSYXRlICogdGhpcy5jb25maWcuYnVmZmVyU2l6ZTsKICAgICAgICBjb25zdCBidWZmZXIgPSBjdHguY3JlYXRlQnVmZmVyKDEsIGJ1ZmZlclNpemUsIGN0eC5zYW1wbGVSYXRlKTsKICAgICAgICBjb25zdCBvdXRwdXQgPSBidWZmZXIuZ2V0Q2hhbm5lbERhdGEoMCk7CiAgICAgICAgCiAgICAgICAgLy8gRmlsbCBidWZmZXIgd2l0aCByYW5kb20gdmFsdWVzICgtMSB0byAxKSBmb3Igd2hpdGUgbm9pc2UKICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IGJ1ZmZlclNpemU7IGkrKykgewogICAgICAgICAgICBvdXRwdXRbaV0gPSBNYXRoLnJhbmRvbSgpICogMiAtIDE7CiAgICAgICAgfQogICAgICAgIAogICAgICAgIExvZ2dlci5kZWJ1ZygnQVVESU8nLCBgV2hpdGUgbm9pc2UgYnVmZmVyIGdlbmVyYXRlZCAoJHtidWZmZXJTaXplfSBzYW1wbGVzKWApOwogICAgICAgIHJldHVybiBidWZmZXI7CiAgICB9CiAgICAKICAgIC8qKgogICAgICogU3RhcnQgcGxheWluZyB3aGl0ZSBub2lzZSAoY29udGludW91c2x5IGxvb3BpbmcpCiAgICAgKi8KICAgIGFzeW5jIHN0YXJ0V2hpdGVOb2lzZSgpIHsKICAgICAgICBpZiAoIXRoaXMuc3RhdGUucGxheWJhY2suaXNJbml0aWFsaXplZCkgewogICAgICAgICAgICBMb2dnZXIuZXJyb3IoJ0FVRElPJywgJ0Nhbm5vdCBzdGFydCAtIG5vdCBpbml0aWFsaXplZCcpOwogICAgICAgICAgICByZXR1cm47CiAgICAgICAgfQogICAgICAgIAogICAgICAgIGlmICh0aGlzLnN0YXRlLnBsYXliYWNrLmlzUGxheWluZykgewogICAgICAgICAgICBMb2dnZXIud2FybignQVVESU8nLCAnQWxyZWFkeSBwbGF5aW5nJyk7CiAgICAgICAgICAgIHJldHVybjsKICAgICAgICB9CiAgICAgICAgCiAgICAgICAgdHJ5IHsKICAgICAgICAgICAgY29uc3QgY3R4ID0gdGhpcy5zdGF0ZS5hdWRpb0NvbnRleHQ7CiAgICAgICAgICAgIAogICAgICAgICAgICAvLyBSZXN1bWUgYXVkaW8gY29udGV4dCBpZiBzdXNwZW5kZWQgKEFuZHJvaWQvU2FmYXJpIHJlcXVpcmVtZW50KQogICAgICAgICAgICAvLyBBbmRyb2lkIENocm9tZSBpcyBlc3BlY2lhbGx5IHN0cmljdCAtIE1VU1QgYXdhaXQgcmVzdW1lIGJlZm9yZSBzdGFydGluZwogICAgICAgICAgICBpZiAoY3R4LnN0YXRlID09PSAnc3VzcGVuZGVkJykgewogICAgICAgICAgICAgICAgTG9nZ2VyLmluZm8oJ0FVRElPJywgYEF1ZGlvQ29udGV4dCBzdXNwZW5kZWQgKCR7Y3R4LnN0YXRlfSksIHJlc3VtaW5nLi4uYCk7CiAgICAgICAgICAgICAgICBhd2FpdCBjdHgucmVzdW1lKCk7CiAgICAgICAgICAgICAgICBMb2dnZXIuaW5mbygnQVVESU8nLCBgQXVkaW9Db250ZXh0IHJlc3VtZWQsIHN0YXRlOiAke2N0eC5zdGF0ZX1gKTsKICAgICAgICAgICAgfQogICAgICAgICAgICAKICAgICAgICAgICAgLy8gVmVyaWZ5IGNvbnRleHQgaXMgcnVubmluZwogICAgICAgICAgICBpZiAoY3R4LnN0YXRlICE9PSAncnVubmluZycpIHsKICAgICAgICAgICAgICAgIExvZ2dlci5lcnJvcignQVVESU8nLCBgQXVkaW9Db250ZXh0IG5vdCBydW5uaW5nIChzdGF0ZTogJHtjdHguc3RhdGV9KSwgY2Fubm90IHN0YXJ0IGF1ZGlvYCk7CiAgICAgICAgICAgICAgICByZXR1cm47CiAgICAgICAgICAgIH0KICAgICAgICAgICAgCiAgICAgICAgICAgIC8vIENyZWF0ZSBidWZmZXIgc291cmNlCiAgICAgICAgICAgIGNvbnN0IHdoaXRlTm9pc2VCdWZmZXIgPSB0aGlzLmdlbmVyYXRlV2hpdGVOb2lzZUJ1ZmZlcigpOwogICAgICAgICAgICB0aGlzLnN0YXRlLm5vZGVzLndoaXRlTm9pc2UgPSBjdHguY3JlYXRlQnVmZmVyU291cmNlKCk7CiAgICAgICAgICAgIHRoaXMuc3RhdGUubm9kZXMud2hpdGVOb2lzZS5idWZmZXIgPSB3aGl0ZU5vaXNlQnVmZmVyOwogICAgICAgICAgICB0aGlzLnN0YXRlLm5vZGVzLndoaXRlTm9pc2UubG9vcCA9IHRydWU7IC8vIExvb3AgY29udGludW91c2x5CiAgICAgICAgICAgIAogICAgICAgICAgICAvLyBDb25uZWN0IHRvIGF1ZGlvIGdyYXBoCiAgICAgICAgICAgIHRoaXMuc3RhdGUubm9kZXMud2hpdGVOb2lzZS5jb25uZWN0KHRoaXMuc3RhdGUubm9kZXMuZmlsdGVyTm9kZSk7CiAgICAgICAgICAgIAogICAgICAgICAgICAvLyBTdGFydCBwbGF5YmFjawogICAgICAgICAgICB0aGlzLnN0YXRlLm5vZGVzLndoaXRlTm9pc2Uuc3RhcnQoMCk7CiAgICAgICAgICAgIHRoaXMuc3RhdGUucGxheWJhY2suaXNQbGF5aW5nID0gdHJ1ZTsKICAgICAgICAgICAgdGhpcy5zdGF0ZS5wbGF5YmFjay5zdGFydFRpbWUgPSBjdHguY3VycmVudFRpbWU7CiAgICAgICAgICAgIAogICAgICAgICAgICBMb2dnZXIuaW5mbygnQVVESU8nLCAnV2hpdGUgbm9pc2Ugc3RhcnRlZCBzdWNjZXNzZnVsbHknKTsKICAgICAgICAgICAgCiAgICAgICAgfSBjYXRjaCAoZXJyb3IpIHsKICAgICAgICAgICAgTG9nZ2VyLmVycm9yKCdBVURJTycsICdGYWlsZWQgdG8gc3RhcnQgd2hpdGUgbm9pc2U6JywgZXJyb3IpOwogICAgICAgIH0KICAgIH0KICAgIAogICAgLyoqCiAgICAgKiBTdG9wIHdoaXRlIG5vaXNlIHBsYXliYWNrCiAgICAgKi8KICAgIHN0b3BXaGl0ZU5vaXNlKCkgewogICAgICAgIGlmICghdGhpcy5zdGF0ZS5wbGF5YmFjay5pc1BsYXlpbmcpIHsKICAgICAgICAgICAgcmV0dXJuOwogICAgICAgIH0KICAgICAgICAKICAgICAgICB0cnkgewogICAgICAgICAgICBpZiAodGhpcy5zdGF0ZS5ub2Rlcy53aGl0ZU5vaXNlKSB7CiAgICAgICAgICAgICAgICB0aGlzLnN0YXRlLm5vZGVzLndoaXRlTm9pc2Uuc3RvcCgpOwogICAgICAgICAgICAgICAgdGhpcy5zdGF0ZS5ub2Rlcy53aGl0ZU5vaXNlLmRpc2Nvbm5lY3QoKTsKICAgICAgICAgICAgICAgIHRoaXMuc3RhdGUubm9kZXMud2hpdGVOb2lzZSA9IG51bGw7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgCiAgICAgIC