0x4774567d…5ac5sent to0x914d7fec…43d7·#25,346,471·view on Etherscan
XJzIHNldCB1cCcpOwogICAgfQoKICAgIC8qKgogICAgICogSGFuZGxlIG1vdXNlIGRvd24gZXZlbnRzCiAgICAgKi8KICAgIGhhbmRsZU1vdXNlRG93bihldmVudCkgewogICAgICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7IC8vIFByZXZlbnQgc2Nyb2xsaW5nCiAgICAgICAgCiAgICAgICAgY29uc3QgcG9zaXRpb24gPSB0aGlzLmdldE1vdXNlUG9zaXRpb24oZXZlbnQpOwogICAgICAgIAogICAgICAgIHRoaXMuc3RhdGUuaW50ZXJhY3Rpb24uaXNBY3RpdmUgPSB0cnVlOwogICAgICAgIHRoaXMuc3RhdGUuaW50ZXJhY3Rpb24udHlwZSA9ICdtb3VzZSc7CiAgICAgICAgdGhpcy5zdGF0ZS5pbnRlcmFjdGlvbi5wb3NpdGlvbiA9IHBvc2l0aW9uOwogICAgICAgIAogICAgICAgIC8vIFN0YXJ0IGF1ZGlvIG9uIGZpcnN0IGludGVyYWN0aW9uIChQaGFzZSBEKQogICAgICAgIGlmICh0aGlzLmF1ZGlvQ29udHJvbGxlcikgewogICAgICAgICAgICB0aGlzLmF1ZGlvQ29udHJvbGxlci5oYW5kbGVGaXJzdEludGVyYWN0aW9uKCk7CiAgICAgICAgfQogICAgICAgIAogICAgICAgIC8vIExvY2sgc2NyZWVuIG9yaWVudGF0aW9uIG9uIGZpcnN0IGludGVyYWN0aW9uIChQaGFzZSBGIC0gTW9iaWxlKQogICAgICAgIGlmICh0aGlzLmFwcCAmJiB0aGlzLmFwcC5sb2NrT3JpZW50YXRpb24pIHsKICAgICAgICAgICAgdGhpcy5hcHAubG9ja09yaWVudGF0aW9uKCk7CiAgICAgICAgfQogICAgICAgIAogICAgICAgIC8vIFVwZGF0ZSBlZmZlY3QgbWFuYWdlciAodmlzdWFsIGVmZmVjdHMpCiAgICAgICAgdGhpcy5lZmZlY3RNYW5hZ2VyLnVwZGF0ZUludGVyYWN0aW9uKHBvc2l0aW9uLngsIHBvc2l0aW9uLnksIHRydWUpOwogICAgICAgIAogICAgICAgIC8vIFVwZGF0ZSBhdWRpbyBjb250cm9sbGVyIChmaWx0ZXIgY29udHJvbCAtIFBoYXNlIEUpCiAgICAgICAgaWYgKHRoaXMuYXVkaW9Db250cm9sbGVyKSB7CiAgICAgICAgICAgIHRoaXMuYXVkaW9Db250cm9sbGVyLnVwZGF0ZUZpbHRlckZyb21JbnRlcmFjdGlvbihwb3NpdGlvbi55LCB0cnVlKTsKICAgICAgICAgICAgdGhpcy5hdWRpb0NvbnRyb2xsZXIudXBkYXRlUmh5dGhtRnJvbUludGVyYWN0aW9uKHBvc2l0aW9uLngsIHRydWUpOwogICAgICAgIH0KICAgICAgICAKICAgICAgICBpZiAodGhpcy5zdGF0ZS5jb25maWcuZW5hYmxlTG9nZ2luZykgewogICAgICAgICAgICBMb2dnZXIuZGVidWcoJ0lOUFVUJywgYE1vdXNlIGRvd24gYXQgKCR7cG9zaXRpb24ueC50b0ZpeGVkKDMpfSwgJHtwb3NpdGlvbi55LnRvRml4ZWQoMyl9KWApOwogICAgICAgIH0KICAgIH0KCiAgICAvKioKICAgICAqIEhhbmRsZSBtb3VzZSBtb3ZlIGV2ZW50cwogICAgICovCiAgICBoYW5kbGVNb3VzZU1vdmUoZXZlbnQpIHsKICAgICAgICBpZiAoIXRoaXMuc3RhdGUuaW50ZXJhY3Rpb24uaXNBY3RpdmUgfHwgdGhpcy5zdGF0ZS5pbnRlcmFjdGlvbi50eXBlICE9PSAnbW91c2UnKSB7CiAgICAgICAgICAgIHJldHVybjsKICAgICAgICB9CiAgICAgICAgCiAgICAgICAgZXZlbnQucHJldmVudERlZmF1bHQoKTsKICAgICAgICAKICAgICAgICBjb25zdCBwb3NpdGlvbiA9IHRoaXMuZ2V0TW91c2VQb3NpdGlvbihldmVudCk7CiAgICAgICAgdGhpcy5zdGF0ZS5pbnRlcmFjdGlvbi5wb3NpdGlvbiA9IHBvc2l0aW9uOwogICAgICAgIAogICAgICAgIC8vIFVwZGF0ZSBlZmZlY3QgbWFuYWdlciAodmlzdWFsIGVmZmVjdHMpCiAgICAgICAgdGhpcy5lZmZlY3RNYW5hZ2VyLnVwZGF0ZUludGVyYWN0aW9uKHBvc2l0aW9uLngsIHBvc2l0aW9uLnksIHRydWUpOwogICAgICAgIAogICAgICAgIC8vIFVwZGF0ZSBhdWRpbyBjb250cm9sbGVyIChmaWx0ZXIgY29udHJvbCAtIFBoYXNlIEUpCiAgICAgICAgaWYgKHRoaXMuYXVkaW9Db250cm9sbGVyKSB7CiAgICAgICAgICAgIHRoaXMuYXVkaW9Db250cm9sbGVyLnVwZGF0ZUZpbHRlckZyb21JbnRlcmFjdGlvbihwb3NpdGlvbi55LCB0cnVlKTsKICAgICAgICAgICAgdGhpcy5hdWRpb0NvbnRyb2xsZXIudXBkYXRlUmh5dGhtRnJvbUludGVyYWN0aW9uKHBvc2l0aW9uLngsIHRydWUpOwogICAgICAgIH0KICAgIH0KCiAgICAvKioKICAgICAqIEhhbmRsZSBtb3VzZSB1cCBldmVudHMKICAgICAqLwogICAgaGFuZGxlTW91c2VVcChldmVudCkgewogICAgICAgIGlmICghdGhpcy5zdGF0ZS5pbnRlcmFjdGlvbi5pc0FjdGl2ZSkgcmV0dXJuOwogICAgICAgIAogICAgICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7CiAgICAgICAgCiAgICAgICAgdGhpcy5lbmRJbnRlcmFjdGlvbigpOwogICAgfQoKCiAgICAvKioKICAgICAqIEhhbmRsZSB0b3VjaCBzdGFydCBldmVudHMKICAgICAqLwogICAgaGFuZGxlVG91Y2hTdGFydChldmVudCkgewogICAgICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7IC8vIFByZXZlbnQgc2Nyb2xsaW5nIQogICAgICAgIAogICAgICAgIC8vIENoZWNrIGZvciAzLWZpbmdlciB0b3VjaCBnZXN0dXJlIChkcm9uZSBtb2RlIHRvZ2dsZSkKICAgICAgICAvLyBPbmx5IHRvZ2dsZSBvbmNlIHdoZW4gdHJhbnNpdGlvbmluZyB0byAzIGZpbmdlcnMKICAgICAgICBpZiAoZXZlbnQudG91Y2hlcy5sZW5ndGggPT09IDMgJiYgIXRoaXMuc3RhdGUuZHJvbmVUb2dnbGUudGhyZWVGaW5nZXJBY3RpdmUpIHsKICAgICAgICAgICAgdGhpcy5zdGF0ZS5kcm9uZVRvZ2dsZS50aHJlZUZpbmdlckFjdGl2ZSA9IHRydWU7CiAgICAgICAgICAgIHRoaXMudG9nZ2xlRHJvbmVNb2RlKCk7CiAgICAgICAgICAgIExvZ2dlci5kZWJ1ZygnSU5QVVQnLCAnMy1maW5nZXIgdG91Y2ggZGV0ZWN0ZWQgLSB0b2dnbGluZyBkcm9uZSBtb2RlJyk7CiAgICAgICAgICAgIHJldHVybjsgLy8gRG9uJ3QgcHJvY2VzcyBhcyBub3JtYWwgaW50ZXJhY3Rpb24KICAgICAgICB9CiAgICAgICAgCiAgICAgICAgLy8gSWYgd2UgYWxyZWFkeSBoYXZlIHRoZSAzLWZpbmdlciBnZXN0dXJlIGFjdGl2ZSwgaWdub3JlIG90aGVyIHRvdWNoZXMKICAgICAgICBpZiAodGhpcy5zdGF0ZS5kcm9uZVRvZ2dsZS50aHJlZUZpbmdlckFjdGl2ZSkgewogICAgICAgICAgICByZXR1cm47CiAgICAgICAgfQogICAgICAgIAogICAgICAgIGlmICh0aGlzLnN0YXRlLmludGVyYWN0aW9uLmlzQWN0aXZlKSByZXR1cm47IC8vIEFscmVhZHkgdHJhY2tpbmcgYSB0b3VjaAogICAgICAgIAogICAgICAgIGNvbnN0IHRvdWNoID0gZXZlbnQuY2hhbmdlZFRvdWNoZXNbMF07CiAgICAgICAgdGhpcy5zdGF0ZS5pbnRlcmFjdGlvbi5pc0FjdGl2ZSA9IHRydWU7CiAgICAgICAgdGhpcy5zdGF0ZS5pbnRlcmFjdGlvbi50eXBlID0gJ3RvdWNoJzsKICAgICAgICB0aGlzLnN0YXRlLmludGVyYWN0aW9uLnRvdWNoSWQgPSB0b3VjaC5pZGVudGlmaWVyOwogICAgICAgIAogICAgICAgIGNvbnN0IHBvc2l0aW9uID0gdGhpcy5nZXRUb3VjaFBvc2l0aW9uKHRvdWNoKTsKICAgICAgICB0aGlzLnN0YXRlLmludGVyYWN0aW9uLnBvc2l0aW9uID0gcG9zaXRpb247CiAgICAgICAgCiAgICAgICAgLy8gU3RhcnQgYXVkaW8gb24gZmlyc3QgaW50ZXJhY3Rpb24gKFBoYXNlIEQpCiAgICAgICAgaWYgKHRoaXMuYXVkaW9Db250cm9sbGVyKSB7CiAgICAgICAgICAgIHRoaXMuYXVkaW9Db250cm9sbGVyLmhhbmRsZUZpcnN0SW50ZXJhY3Rpb24oKTsKICAgICAgICB9CiAgICAgICAgCiAgICAgICAgLy8gTG9jayBzY3JlZW4gb3JpZW50YXRpb24gb24gZmlyc3QgaW50ZXJhY3Rpb24gKFBoYXNlIEYgLSBNb2JpbGUpCiAgICAgICAgaWYgKHRoaXMuYXBwICYmIHRoaXMuYXBwLmxvY2tPcmllbnRhdGlvbikgewogICAgICAgICAgICB0aGlzLmFwcC5sb2NrT3JpZW50YXRpb24oKTsKICAgICAgICB9CiAgICAgICAgCiAgICAgICAgLy8gVXBkYXRlIGVmZmVjdCBtYW5hZ2VyICh2aXN1YWwgZWZmZWN0cykKICAgICAgICB0aGlzLmVmZmVjdE1hbmFnZXIudXBkYXRlSW50ZXJhY3Rpb24ocG9zaXRpb24ueCwgcG9zaXRpb24ueSwgdHJ1ZSk7CiAgICAgICAgCiAgICAgICAgLy8gVXBkYXRlIGF1ZGlvIGNvbnRyb2xsZXIgKGZpbHRlciBjb250cm9sIC0gUGhhc2UgRSkKICAgICAgICBpZiAodGhpcy5hdWRpb0NvbnRyb2xsZXIpIHsKICAgICAgICAgICAgdGhpcy5hdWRpb0NvbnRyb2xsZXIudXBkYXRlRmlsdGVyRnJvbUludGVyYWN0aW9uKHBvc2l0aW9uLnksIHRydWUpOwogICAgICAgICAgICB0aGlzLmF1ZGlvQ29udHJvbGxlci51cGRhdGVSaHl0aG1Gcm9tSW50ZXJhY3Rpb24ocG9zaXRpb24ueCwgdHJ1ZSk7CiAgICAgICAgfQogICAgICAgIAogICAgICAgIGlmICh0aGlzLnN0YXRlLmNvbmZpZy5lbmFibGVMb2dnaW5nKSB7CiAgICAgICAgICAgIExvZ2dlci5kZWJ1ZygnSU5QVVQnLCBgVG91Y2ggc3RhcnQgYXQgKCR7cG9zaXRpb24ueC50b0ZpeGVkKDMpfSwgJHtwb3NpdGlvbi55LnRvRml4ZWQoMyl9KWApOwogICAgICAgIH0KICAgIH0KCiAgICAvKioKICAgICAqIEhhbmRsZSB0b3VjaCBtb3ZlIGV2ZW50cwogICAgICovCiAgICBoYW5kbGVUb3VjaE1vdmUoZXZlbnQpIHsKICAgICAgICAvLyBDaGVjayBmb3IgMy1maW5nZXIgdG91Y2ggZ2VzdHVyZSAoZHJvbmUgbW9kZSB0b2dnbGUpCiAgICAgICAgLy8gT25seSB0b2dnbGUgb25jZSB3aGVuIHRyYW5zaXRpb25pbmcgdG8gMyBmaW5nZXJzCiAgICAgICAgaWYgKGV2ZW50LnRvdWNoZXMubGVuZ3RoID09PSAzICYmICF0aGlzLnN0YXRlLmRyb25lVG9nZ2xlLnRocmVlRmluZ2VyQWN0aXZlKSB7CiAgICAgICAgICAgIHRoaXMuc3RhdGUuZHJvbmVUb2dnbGUudGhyZWVGaW5nZXJBY3RpdmUgPSB0cnVlOwogICAgICAgICAgICBpZiAodGhpcy5zdGF0ZS5pbnRlcmFjdGlvbi5pc0FjdGl2ZSkgewogICAgICAgICAgICAgICAgdGhpcy5lbmRJbnRlcmFjdGlvbigpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHRoaXMudG9nZ2xlRHJvbmVNb2RlKCk7CiAgICAgICAgICAgIExvZ2dlci5kZWJ1ZygnSU5QVVQnLCAnMy1maW5nZXIgdG91Y2ggZGV0ZWN0ZWQgZHVyaW5nIG1vdmUgLSB0b2dnbGluZyBkcm9uZSBtb2RlJyk7CiAgICAgICAgICAgIHJldHVybjsKICAgICAgICB9CiAgICAgICAgCiAgICAgICAgLy8gSWYgd2UgYWxyZWFkeSBoYXZlIHRoZSAzLWZpbmdlciBnZXN0dXJlIGFjdGl2ZSwgaWdub3JlIG90aGVyIHRvdWNoZXMKICAgICAgICBpZiAodGhpcy5zdGF0ZS5kcm9uZVRvZ2dsZS50aHJlZUZpbmdlckFjdGl2ZSkgewogICAgICAgICAgICByZXR1cm47CiAgICAgICAgfQogICAgICAgIAogICAgICAgIGlmICghdGhpcy5zdGF0ZS5pbnRlcmFjdGlvbi5pc0FjdGl2ZSB8fCB0aGlzLnN0YXRlLmludGVyYWN0aW9uLnR5cGUgIT09ICd0b3VjaCcpIHsKICAgICAgICAgICAgcmV0dXJuOwogICAgICAgIH0KICAgICAgICAKICAgICAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpOwogICAgICAgIAogICAgICAgIC8vIEZpbmQgdGhlIHRvdWNoIHdlJ3JlIHRyYWNraW5nCiAgICAgICAgY29uc3QgdG91Y2ggPSBBcnJheS5mcm9tKGV2ZW50LmNoYW5nZWRUb3VjaGVzKS5maW5kKAogICAgICAgICAgICB0ID0+IHQuaWRlbnRpZmllciA9PT0gdGhpcy5zdGF0ZS5pbnRlcmFjdGlvbi50b3VjaElkCiAgICAgICAgKTsKICAgICAgICAKICAgICAgICBpZiAoIXRvdWNoKSByZXR1cm47CiAgICAgICAgCiAgICAgICAgY29uc3QgcG9zaXRpb24gPSB0aGlzLmdldFRvdWNoUG9zaXRpb24odG91Y2gpOwogICAgICAgIHRoaXMuc3RhdGUuaW50ZXJhY3Rpb24ucG9zaXRpb24gPSBwb3NpdGlvbjsKICAgICAgICAKICAgICAgICAvLyBVcGRhdGUgZWZmZWN0IG1hbmFnZXIgKHZpc3VhbCBlZmZlY3RzKQogICAgICAgIHRoaXMuZWZmZWN0TWFuYWdlci51cGRhdGVJbnRlcmFjdGlvbihwb3NpdGlvbi54LCBwb3NpdGlvbi55LCB0cnVlKTsKICAgICAgICAKICAgICAgICAvLyBVcGRhdGUgYXVkaW8gY29udHJvbGxlciAoZmlsdGVyIGNvbnRyb2wgLSBQaGFzZSBFKQogICAgICAgIGlmICh0aGlzLmF1ZGlvQ29udHJvbGxlcikgewogICAgICAgICAgICB0aGlzLmF1ZGlvQ29udHJvbGxlci51cGRhdGVGaWx0ZXJGcm9tSW50ZXJhY3Rpb24ocG9zaXRpb24ueSwgdHJ1ZSk7CiAgICAgICAgICAgIHRoaXMuYXVkaW9Db250cm9sbGVyLnVwZGF0ZVJoeXRobUZyb21JbnRlcmFjdGlvbihwb3NpdGlvbi54LCB0cnVlKTsKICAgICAgICB9CiAgICB9CgogICAgLyoqCiAgICAgKiBIYW5kbGUgdG91Y2ggZW5kIGV2ZW50cwogICAgICovCiAgICBoYW5kbGVUb3VjaEVuZChldmVudCkgewogICAgICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7CiAgICAgICAgCiAgICAgICAgLy8gUmVzZXQgMy1maW5nZXIgZ2VzdHVyZSBmbGFnIHdoZW4gZmluZ2VycyBnbyBiZWxvdyAzCiAgICAgICAgaWYgKGV2ZW50LnRvdWNoZXMubGVuZ3RoIDwgMykgewogICAgICAgICAgICB0aGlzLnN0YXRlLmRyb25lVG9nZ2xlLnRocmVlRmluZ2VyQWN0aXZlID0gZmFsc2U7CiAgICAgICAgICAgIExvZ2dlci5kZWJ1ZygnSU5QVVQnLCAnMy1maW5nZXIgZ2VzdHVyZSByZXNldCAoZmluZ2VycyBsaWZ0ZWQpJyk7CiAgICAgICAgfQogICAgICAgIAogICAgICAgIGlmICghdGhpcy5zdGF0ZS5pbnRlcmFjdGlvbi5pc0FjdGl2ZSkgcmV0dXJuOwogICAgICAgIAogICAgICAgIC8vIENoZWNrIGlmIG91ciB0cmFja2VkIHRvdWNoIGVuZGVkCiAgICAgICAgY29uc3QgdG91Y2ggPSBBcnJheS5mcm9tKGV2ZW50LmNoYW5nZWRUb3VjaGVzKS5maW5kKAogICAgICAgICAgICB0ID0+IHQuaWRlbnRpZmllciA9PT0gdGhpcy5zdGF0ZS5pbnRlcmFjdGlvbi50b3VjaElkCiAgICAgICAgKTsKICAgICAgICAKICAgICAgICBpZiAodG91Y2gpIHsKICAgICAgICAgICAgdGhpcy5lbmRJbnRlcmFjdGlvbigpOwogICAgICAgIH0KICAgIH0KCiAgICAvKioKICAgICAqIEhhbmRsZSB0b3VjaCBjYW5jZWwgZXZlbnRzCiAgICAgKi8KICAgIGhhbmRsZVRvdWNoQ2FuY2VsKGV2ZW50KSB7CiAgICAgICAgLy8gUmVzZXQgMy1maW5nZXIgZ2VzdHVyZSBmbGFnCiAgICAgICAgdGhpcy5zdGF0ZS5kcm9uZVRvZ2dsZS50aHJlZUZpbmdlckFjdGl2ZSA9IGZhbHNlOwogICAgICAgIAogICAgICAgIGlmICh0aGlzLnN0YXRlLmludGVyYWN0aW9uLmlzQWN0aXZlICYmIHRoaXMuc3RhdGUuaW50ZXJhY3Rpb24udHlwZSA9PT0gJ3RvdWNoJykgewogICAgICAgICAgICB0aGlzLmVuZEludGVyYWN0aW9uKCk7CiAgICAgICAgfQogICAgfQoKICAgIC8qKgogICAgICogSGFuZGxlIGtleWJvYXJkIGV2ZW50cyAoc3BhY2UgYmFyIGZvciBkcm9uZSB0b2dnbGUpCiAgICAgKi8KICAgIGhhbmRsZUtleURvd24oZXZlbnQpIHsKICAgICAgICAvLyBTcGFjZSBiYXIgdG9nZ2xlcyBkcm9uZSBtb2RlCiAgICAgICAgaWYgKGV2ZW50LmNvZGUgPT09ICdTcGFjZScgfHwgZXZlbnQua2V5ID09PSAnICcpIHsKICAgICAgICAgICAgZXZlbnQucHJldmVudERlZmF1bHQoKTsgLy8gUHJldmVudCBwYWdlIHNjcm9sbAogICAgICAgICAgICAKICAgICAgICAgICAgaWYgKHRoaXMuc3RhdGUuaW50ZXJhY3Rpb24uaXNBY3RpdmUpIHsKICAgICAgICAgICAgICAgIC8vIEN1cnJlbnRseSBpbnRlcmFjdGluZyAtIHF1ZXVlIHRoZSB0b2dnbGUgZm9yIHdoZW4gaW50ZXJhY3Rpb24gZW5kcwogICAgICAgICAgICAgICAgdGhpcy5zdGF0ZS5kcm9uZVRvZ2dsZS5wZW5kaW5nVG9nZ2xlID0gdHJ1ZTsKICAgICAgICAgICAgICAgIExvZ2dlci5kZWJ1ZygnSU5QVVQnLCAnRHJvbmUgdG9nZ2xlIHF1ZXVlZCAoaW50ZXJhY3Rpb24gYWN0aXZlKScpOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgLy8gTm90IGludGVyYWN0aW5nIC0gdG9nZ2xlIGltbWVkaWF0ZWx5CiAgICAgICAgICAgICAgICB0aGlzLnRvZ2dsZURyb25lTW9kZSgpOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfQoKICAgIC8qKgogICAgICogVG9nZ2xlIGRyb25lIG1vZGUgKGJhY2tncm91bmQgbm9pc2Ugd2hlbiBub3QgY2xpY2tpbmcpCiAgICAgKi8KICAgIHRvZ2dsZURyb25lTW9kZSgpIHsKICAgICAgICBpZiAodGhpcy5hdWRpb0NvbnRyb2xsZXIpIHsKICAgICAgICAgICAgdGhpcy5hdWRpb0NvbnRyb2xsZXIudG9nZ2xlRHJvbmVNb2RlKCk7CiAgICAgICAgICAgIExvZ2dlci5pbmZvKCdJTlBVVCcsICdEcm9uZSBtb2RlIHRvZ2dsZWQnKTsKICAgICAgICB9CiAgICB9CgogICAgLyoqCiAgICAgKiBFbmQgaW50ZXJhY3Rpb24gKHJldHVybiB0byByYXcgc3RhdGljKQogICAgICovCiAgICBlbmRJbnRlcmFjdGlvbigpIHsKICAgICAgICB0aGlzLnN0YXRlLmludGVyYWN0aW9uLmlzQWN0aXZlID0gZmFsc2U7CiAgICAgICAgdGhpcy5zdGF0ZS5pbnRlcmFjdGlvbi50b3VjaElkID0gbnVsbDsKICAgICAgICAKICAgICAgICAvLyBOb3RpZnkgZWZmZWN0IG1hbmFnZXIgKGluc3RhbnQgcmV0dXJuIHRvIHJhdyBzdGF0aWMpCiAgICAgICAgdGhpcy5lZmZlY3RNYW5hZ2VyLnVwZGF0ZUludGVyYWN0aW9uKDAsIDAsIGZhbHNlKTsKICAgICAgICAKICAgICAgICAvLyBSZXNldCBhdWRpbyBmaWx0ZXIgYW5kIHJoeXRobSAoYnlwYXNzIGZpbHRlciwgc3RvcCByaHl0aG0gLSBQaGFzZSBFKQogICAgICAgIGlmICh0aGlzLmF1ZGlvQ29udHJvbGxlcikgewogICAgICAgICAgICB0aGlzLmF1ZGlvQ29udHJvbGxlci51cGRhdGVGaWx0ZXJGcm9tSW50ZXJhY3Rpb24oMCwgZmFsc2UpOwogICAgICAgICAgICB0aGlzLmF1ZGlvQ29udHJvbGxlci51cGRhdGVSaHl0aG1Gcm9tSW50ZXJhY3Rpb24oMCwgZmFsc2UpOwogICAgICAgIH0KICAgICAgICAKICAgICAgICAvLyBFeGVjdXRlIHBlbmRpbmcgZHJvbmUgdG9nZ2xlIGlmIHF1ZXVlZAogICAgICAgIGlmICh0aGlzLnN0YXRlLmRyb25lVG9nZ2xlLnBlbmRpbmdUb2dnbGUpIHsKICAgICAgICAgICAgdGhpcy5zdGF0ZS5kcm9uZVRvZ2dsZS5wZW5kaW5nVG9nZ2xlID0gZmFsc2U7CiAgICAgICAgICAgIHRoaXMudG9nZ2xlRHJvbmVNb2RlKCk7CiAgICAgICAgfQogICAgICAgIAogICAgICAgIGlmICh0aGlzLnN0YXRlLmNvbmZpZy5lbmFibGVMb2dnaW5nKSB7CiAgICAgICAgICAgIExvZ2dlci5kZWJ1ZygnSU5QVVQnLCAnSW50ZXJhY3Rpb24gZW5kZWQnKTsKICAgICAgICB9CiAgICB9CgogICAgLyoqCiAgICAgKiBHZXQgbm9ybWFsaXplZCBtb3VzZSBwb3NpdGlvbiAoMC0xKQogICAgICovCiAgICBnZXRNb3VzZVBvc2l0aW9uKGV2ZW50KSB7CiAgICAgICAgY29uc3QgcmVjdCA9IHRoaXMuY2FudmFzLmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpOwogICAgICAgIAogICAgICAgIGxldCB4ID0gKGV2ZW50LmNsaWVudFggLSByZWN0LmxlZnQpIC8gcmVjdC53aWR0aDsKICAgICAgICBsZXQgeSA9IChldmVudC5jbGllbnRZIC0gcmVjdC50b3ApIC8gcmVjdC5oZWlnaHQ7CiAgICAgICAgCiAgICAgICAgLy8gQXBwbHkgWSBpbnZlcnNpb24gaWYgZW5hYmxlZAogICAgICAgIGlmICh0aGlzLnN0YXRlLmNvbmZpZy5pbnZlcnRZKSB7CiAgICAgICAgICAgIHkgPSAxLjAgLSB5OwogICAgICAgIH0KICAgICAgICAKICAgICAgICAvLyBDbGFtcCB0byAwLTEgcmFuZ2UKICAgICAgICB4ID0gTWF0aC5tYXgoMCwgTWF0aC5taW4oMSwgeCkpOwogICAgICAgIHkgPSBNYXRoLm1heCgwLCBNYXRoLm1pbigxLCB5KSk7CiAgICAgICAgCiAgICAgICAgcmV0dXJuIHsgeCwgeSB9OwogICAgfQoKICAgIC8qKgogICAgICogR2V0IG5vcm1hbGl6ZWQgdG91Y2ggcG9zaXRpb24gKDAtMSkKICAgICAqLwogICAgZ2V0VG91Y2hQb3NpdGlvbih0b3VjaCkgewogICAgICAgIGNvbnN0IHJlY3QgPSB0aGlzLmNhbnZhcy5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKTsKICAgICAgICAKICAgICAgICBsZXQgeCA9ICh0b3VjaC5jbGllbnRYIC0gcmVjdC5sZWZ0KSAvIHJlY3Qud2lkdGg7CiAgICAgICAgbGV0IHkgPSAodG91Y2guY2xpZW50WSAtIHJlY3QudG9wKSAvIHJlY3QuaGVpZ2h0OwogICAgICAgIAogICAgICAgIC8vIEFwcGx5IFkgaW52ZXJzaW9uIGlmIGVuYWJsZWQKICAgICAgICBpZiAodGhpcy5zdGF0ZS5jb25maWcuaW52ZXJ0WSkgewogICAgICAgICAgICB5ID0gMS4wIC0geTsKICAgICAgICB9CiAgICAgICAgCiAgICAgICAgLy8gQ2xhbXAgdG8gMC0xIHJhbmdlCiAgICAgICAgeCA9IE1hdGgubWF4KDAsIE1hdGgubWluKDEsIHgpKTsKICAgICAgICB5ID0gTWF0aC5tYXgoMCwgTWF0aC5taW4oMSwgeSkpOwogICAgICAgIAogICAgICAgIHJldHVybiB7IHgsIHkgfTsKICAgIH0KCiAgICAvKioKICAgICAqIENvbmZpZ3VyZSBpbnB1dCBjb250cm9sbGVyCiAgICAgKi8KICAgIGNvbmZpZ3VyZShjb25maWcpIHsKICAgICAgICBpZiAoY29uZmlnLmludmVydFkgIT09IHVuZGVmaW5lZCkgewogICAgICAgICAgICB0aGlzLnN0YXRlLmNvbmZpZy5pbnZlcnRZID0gQm9vbGVhbihjb25maWcuaW52ZXJ0WSk7CiAgICAgICAgfQogICAgICAgIAogICAgICAgIGlmIChjb25maWcuZW5hYmxlTG9nZ2luZyAhPT0gdW5kZWZpbmVkKSB7CiAgICAgICAgICAgIHRoaXMuc3RhdGUuY29uZmlnLmVuYWJsZUxvZ2dpbmcgPSBCb29sZWFuKGNvbmZpZy5lbmFibGVMb2dnaW5nKTsKICAgICAgICB9CiAgICAgICAgCiAgICAgICAgTG9nZ2VyLmluZm8oJ0lOUFVUJywgJ0NvbmZpZ3VyYXRpb24gdXBkYXRlZDonLCB0aGlzLnN0YXRlLmNvbmZpZyk7CiAgICB9CgogICAgLyoqCiAgICAgKiBHZXQgaW5wdXQgY29udHJvbGxlciBzdGF0ZSBmb3IgZGVidWdnaW5nCiAgICAgKi8KICAgIGdldFN0YXRlKCkgewogICAgICAgIHJldHVybiB7CiAgICAgICAgICAgIGlzQWN0aXZlOiB0aGlzLnN0YXRlLmludGVyYWN0aW9uLmlzQWN0aXZlLAogICAgICAgICAgICB0eXBlOiB0aGlzLnN0YXRlLmludGVyYWN0aW9uLnR5cGUsCiAgICAgICAgICAgIHBvc2l0aW9uOiB7IC4uLnRoaXMuc3RhdGUuaW50ZXJhY3Rpb24ucG9zaXRpb24gfSwKICAgICAgICAgICAgY29uZmlnOiB7IC4uLnRoaXMuc3RhdGUuY29uZmlnIH0KICAgICAgICB9OwogICAgfQoKICAgIC8qKgogICAgICogQ2xlYW4gdXAgZXZlbnQgbGlzdGVuZXJzIGFuZCByZXNvdXJjZXMKICAgICAqLwogICAgZGVzdHJveSgpIHsKICAgICAgICAvLyBSZW1vdmUgZXZlbnQgbGlzdGVuZXJzCiAgICAgICAgdGhpcy5jYW52YXMucmVtb3ZlRXZlbnRMaXN0ZW5lcignbW91c2Vkb3duJywgdGhpcy5oYW5kbGVNb3VzZURvd24pOwogICAgICAgIHdpbmRvdy5yZW1vdmVFdmVudExpc3RlbmVyKCdtb3VzZW1vdmUnLCB0aGlzLmhhbmRsZU1vdXNlTW92ZSk7CiAgICAgICAgd2luZG93LnJlbW92ZUV2ZW50TGlzdGVuZXIoJ21vdXNldXAnLCB0aGlzLmhhbmRsZU1vdXNlVXApOwogICAgICAgIAogICAgICAgIHRoaXMuY2FudmFzLnJlbW92ZUV2ZW50TGlzdGVuZXIoJ3RvdWNoc3RhcnQnLCB0aGlzLmhhbmRsZVRvdWNoU3RhcnQpOwogICAgICAgIHRoaXMuY2FudmFzLnJlbW92ZUV2ZW50TGlzdGVuZXIoJ3RvdWNobW92ZScsIHRoaXMuaGFuZGxlVG91Y2hNb3ZlKTsKICAgICAgICB0aGlzLmNhbnZhcy5yZW1vdmVFdmVudExpc3RlbmVyKCd0b3VjaGVuZCcsIHRoaXMuaGFuZGxlVG91Y2hFbmQpOwogICAgICAgIHRoaXMuY2FudmFzLnJlbW92ZUV2ZW50TGlzdGVuZXIoJ3RvdWNoY2FuY2VsJywgdGhpcy5oYW5kbGVUb3VjaENhbmNlbCk7CiAgICAgICAgCiAgICAgICAgd2luZG93LnJlbW92ZUV2ZW50TGlzdGVuZXIoJ2tleWRvd24nLCB0aGlzLmhhbmRsZUtleURvd24pOwogICAgICAgIAogICAgICAgIExvZ2dlci5pbmZvKCdJTlBVVCcsICdJbnB1dENvbnRyb2xsZXIgZGVzdHJveWVkJyk7CiAgICB9Cn0KCklucHV0Q29udHJvbGxlcjsKCgovLyBtYWluLmpzIC0gVFYgU3RhdGljIEFwcGxpY2F0aW9uIENvcmUKLy8gdjI6IER1YWwgcmVuZGVyZXIgc3VwcG9ydCAoV2ViR1BVICsgV2ViR0wgZmFsbGJhY2spCi8vIEhhbmRsZXMgcmVuZGVyZXIgaW5pdGlhbGl6YXRpb24sIGVmZmVjdCBtYW5hZ2VtZW50LCBhbmQgcmVuZGVyIGxvb3AKCmNsYXNzIFRWU3RhdGljQXBwIHsKICAgIGNvbnN0cnVjdG9yKCkgewogICAgICAgIC8vIFN0cnVjdHVyZWQgc3RhdGUKICAgICAgICB0aGlzLnN0YXRlID0gewogICAgICAgICAgICAvLyBDYW52YXMKICAgICAgICAgICAgY2FudmFzOiBudWxsLAogICAgICAgICAgICAKICAgICAgICAgICAgLy8gUmVuZGVyZXIgKFdlYkdQVSBvciBXZWJHTCAtIGF1dG8tc2VsZWN0ZWQpCiAgICAgICAgICAgIHJlbmRlcmVyOiBudWxsLAogICAgICAgICAgICAKICAgICAgICAgICAgLy8gUmVuZGVyaW5nIHN0YXRlCiAgICAgICAgICAgIHJlbmRlcmluZzogewogICAgICAgICAgICAgICAgYW5pbWF0aW9uRnJhbWVJZDogbnVsbCwKICAgICAgICAgICAgICAgIGlzUnVubmluZzogZmFsc2UsCiAgICAgICAgICAgICAgICBsYXN0RnJhbWVUaW1lOiAwLAogICAgICAgICAgICAgICAgZnJhbWVDb3VudDogMCwKICAgICAgICAgICAgICAgIGZwczogMCwKICAgICAgICAgICAgICAgIGZwc1VwZGF0ZVRpbWU6IDAKICAgICAgICAgICAgfSwKICAgICAgICAgICAgCiAgICAgICAgICAgIC8vIE1hbmFnZXJzCiAgICAgICAgICAgIGVmZmVjdE1hbmFnZXI6IG51bGwsCiAgICAgICAgICAgIGlucHV0Q29udHJvbGxlcjogbnVsbCwKICAgICAgICAgICAgYXVkaW9Db250cm9sbGVyOiBudWxsLAogICAgICAgICAgICAKICAgICAgICAgICAgLy8gRWZmZWN0cyAoc3RvcmVkIGZvciBlYXN5IGFjY2VzcykKICAgICAgICAgICAgZWZmZWN0czogewogICAgICAgICAgICAgICAgc3RhdGljRWZmZWN0OiBudWxsLAogICAgICAgICAgICAgICAgcGl4ZWxpemF0aW9uRWZmZWN0OiBudWxsCiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIAogICAgICAgICAgICAvLyBBcHAgc3RhdGUKICAgICAgICAgICAgYXBwOiB7CiAgICAgICAgICAgICAgICBpc0luaXRpYWxpemVkOiBmYWxzZSwKICAgICAgICAgICAgICAgIHN0YXJ0VGltZTogMCwKICAgICAgICAgICAgICAgIG9yaWVudGF0aW9uTG9ja2VkOiBmYWxzZQogICAgICAgICAgICB9CiAgICAgICAgfTsKICAgICAgICAKICAgICAgICBMb2dnZXIuaW5mbygnQVBQJywgJ1RWIFN0YXRpYyBBcHBsaWNhdGlvbiBjcmVhdGVkICh2MiAtIGR1YWwgcmVuZGVyZXIpJyk7CiAgICB9CiAgICAKICAgIC8qKgogICAgICogSW5pdGlhbGl6ZSB0aGUgYXBwbGljYXRpb24KICAgICAqLwogICAgYXN5bmMgaW5pdGlhbGl6ZSgpIHsKICAgICAgICB0cnkgewogICAgICAgICAgICBMb2dnZXIuaW5mbygnQVBQJywgJ1N0YXJ0aW5nIGluaXRpYWxpemF0aW9uLi4uJyk7CiAgICAgICAgICAgIAogICAgICAgICAgICAvLyAxLiBTZXR1cCBjYW52YXMKICAgICAgICAgICAgdGhpcy5zZXR1cENhbnZhcygpOwogICAgICAgICAgICAKICAgICAgICAgICAgLy8gMi4gSW5pdGlhbGl6ZSByZW5kZXJlciAoV2ViR1BVIG9yIFdlYkdMIC0gYXV0by1zZWxlY3RlZCkKICAgICAgICAgICAgYXdhaXQgdGhpcy5pbml0aWFsaXplUmVuZGVyZXIoKTsKICAgICAgICAgICAgCiAgICAgICAgICAgIC8vIDMuIENyZWF0ZSBlZmZlY3QgbWFuYWdlcgogICAgICAgICAgICB0aGlzLnN0YXRlLmVmZmVjdE1hbmFnZXIgPSBuZXcgRWZmZWN0TWFuYWdlcih0aGlzLnN0YXRlLnJlbmRlcmVyKTsKICAgICAgICAgICAgCiAgICAgICAgICAgIC8vIDQuIENyZWF0ZSBhbmQgcmVnaXN0ZXIgVFYgU3RhdGljIGVmZmVjdCAoSUQ6IDApCiAgICAgICAgICAgIGNvbnN0IHR2U3RhdGljRWZmZWN0ID0gbmV3IFRWU3RhdGljRWZmZWN0KCk7CiAgICAgICAgICAgIHRoaXMuc3RhdGUuZWZmZWN0cy5zdGF0aWNFZmZlY3QgPSB0dlN0YXRpY0VmZmVjdDsKICAgICAgICAgICAgYXdhaXQgdGhpcy5zdGF0ZS5lZmZlY3RNYW5hZ2VyLnJlZ2lzdGVyRWZmZWN0KHR2U3RhdGljRWZmZWN0KTsKICAgICAgICAgICAgYXdhaXQgdGhpcy5zdGF0ZS5lZmZlY3RNYW5hZ2VyLmNyZWF0ZVBpcGVsaW5lKAogICAgICAgICAgICAgICAgdHZTdGF0aWNFZmZlY3QsCiAgICAgICAgICAgICAgICBmYWxzZSAgLy8gbmVlZHNUZXh0dXJlSW5wdXQgPSBmYWxzZSAoZ2VuZXJhdGVzIGNvbnRlbnQpCiAgICAgICAgICAgICk7CiAgICAgICAgICAgIAogICAgICAgICAgICAvLyA1LiBDcmVhdGUgYW5kIHJlZ2lzdGVyIFBpeGVsaXphdGlvbiBlZmZlY3QgKElEOiAxKQogICAgICAgICAgICBjb25zdCBwaXhlbGl6YXRpb25FZmZlY3QgPSBuZXcgUGl4ZWxpemF0aW9uRWZmZWN0KCk7CiAgICAgICAgICAgIHRoaXMuc3RhdGUuZWZmZWN0cy5waXhlbGl6YXRpb25FZmZlY3QgPSBwaXhlbGl6YXRpb25FZmZlY3Q7CiAgICAgICAgICAgIGF3YWl0IHRoaXMuc3RhdGUuZWZmZWN0TWFuYWdlci5yZWdpc3RlckVmZmVjdChwaXhlbGl6YXRpb25FZmZlY3QpOwogICAgICAgICAgICBhd2FpdCB0aGlzLnN0YXRlLmVmZmVjdE1hbmFnZXIuY3JlYXRlUGlwZWxpbmUoCiAgICAgICAgICAgICAgICBwaXhlbGl6YXRpb25FZmZlY3QsCiAgICAgICAgICAgICAgICB0cnVlICAvLyBuZWVkc1RleHR1cmVJbnB1dCA9IHRydWUgKHBvc3QtcHJvY2Vzc2luZyBlZmZlY3QpCiAgICAgICAgICAgICk7CiAgICAgICAgICAgIAogICAgICAgICAgICAvLyA2LiBDcmVhdGUgaW50ZXJtZWRpYXRlIHRleHR1cmUgZm9yIG11bHRpLXBhc3MgcmVuZGVyaW5nCiAgICAgICAgICAgIHRoaXMuc3RhdGUucmVuZGVyZXIuY3JlYXRlSW50ZXJtZWRpYXRlVGV4dHVyZSgKICAgICAgICAgICAgICAgIHRoaXMuc3RhdGUuY2FudmFzLndpZHRoLAogICAgICAgICAgICAgICAgdGhpcy5zdGF0ZS5jYW52YXMuaGVpZ2h0CiAgICAgICAgICAgICk7CiAgICAgICAgICAgIAogICAgICAgICAgICAvLyA3LiBDcmVhdGUgYXVkaW8gY29udHJvbGxlcgogICAgICAgICAgICB0aGlzLnN0YXRlLmF1ZGlvQ29udHJvbGxlciA9IG5ldyBBdWRpb0NvbnRyb2xsZXIoKTsKICAgICAgICAgICAgCiAgICAgICAgICAgIC8vIDguIENyZWF0ZSBpbnB1dCBjb250cm9sbGVyIGZvciBtb3VzZS90b3VjaCBpbnRlcmFjdGlvbgogICAgICAgICAgICB0aGlzLnN0YXRlLmlucHV0Q29udHJvbGxlciA9IG5ldyBJbnB1dENvbnRyb2xsZXIoCiAgICAgICAgICAgICAgICB0aGlzLnN0YXRlLmNhbnZhcywKICAgICAgICAgICAgICAgIHRoaXMuc3RhdGUuZWZmZWN0TWFuYWdlciwKICAgICAgICAgICAgICAgIHRoaXMuc3RhdGUuYXVkaW9Db250cm9sbGVyLAogICAgICAgICAgICAgICAgdGhpcyAgLy8gUGFzcyBhcHAgcmVmZXJlbmNlIGZvciBvcmllbnRhdGlvbiBsb2NrCiAgICAgICAgICAgICk7CiAgICAgICAgICAgIAogICAgICAgICAgICAvLyA5LiBTZXR1cCB3aW5kb3cgcmVzaXplIGhhbmRsZXIKICAgICAgICAgICAgdGhpcy5zZXR1cFJlc2l6ZUhhbmRsZXIoKTsKICAgICAgICAgICAgCiAgICAgICAgICAgIC8vIDEwLiBTdGFydCByZW5kZXIgbG9vcAogICAgICAgICAgICB0aGlzLnN0YXRlLmFwcC5pc0luaXRpYWxpemVkID0gdHJ1ZTsKICAgICAgICAgICAgdGhpcy5zdGF0ZS5hcHAuc3RhcnRUaW1lID0gcGVyZm9ybWFuY2Uubm93KCk7CiAgICAgICAgICAgIHRoaXMuc3RhcnRSZW5kZXJMb29wKCk7CiAgICAgICAgICAgIAogICAgICAgICAgICBMb2dnZXIuaW5mbygnQVBQJywgYEluaXRpYWxpemF0aW9uIGNvbXBsZXRlISBSZW5kZXJlcjogJHt0aGlzLnN0YXRlLnJlbmRlcmVyLmdldFR5cGUoKX1gKTsKICAgICAgICAgICAgCiAgICAgICAgICAgIC8vIGlPUyBTYWZhcmkgV2ViR1BVIGZpeDogRm9yY2UgY2FudmFzIHJlcGFpbnQKICAgICAgICAgICAgaWYgKHRoaXMuc3RhdGUucmVuZGVyZXIuZ2V0VHlwZSgpID09PSAnd2ViZ3B1JykgewogICAgICAgICAgICAgICAgdGhpcy5mb3JjZUNhbnZhc1JlcGFpbnQoKTsKICAgICAgICAgICAgfQogICAgICAgICAgICAKICAgICAgICB9IGNhdGNoIChlcnJvcikgewogICAgICAgICAgICBMb2dnZXIuZXJyb3IoJ0FQUCcsICdJbml0aWFsaXphdGlvbiBmYWlsZWQ6JywgZXJyb3IpOwogICAgICAgICAgICB0aGlzLnNob3dFcnJvcignRmFpbGVkIHRvIGluaXRpYWxpemUgYXBwbGljYXRpb24uIENoZWNrIGNvbnNvbGUgZm9yIGRldGFpbHMuJyk7CiAgICAgICAgICAgIHRocm93IGVycm9yOwogICAgICAgIH0KICAgIH0KICAgIAogICAgLyoqCiAgICAgKiBGb3JjZSBjYW52YXMgcmVwYWludCAoaU9TIFNhZmFyaSBXZWJHUFUgZml4KQogICAgICovCiAgICBmb3JjZUNhbnZhc1JlcGFpbnQoKSB7CiAgICAgICAgY29uc3QgY2FudmFzID0gdGhpcy5zdGF0ZS5jYW52YXM7CiAgICAgICAgCiAgICAgICAgLy8gVHJpZ2dlciBpT1MgY29tcG9zaXRvciBieSB0ZW1wb3JhcmlseSBtb2RpZnlpbmcgY2FudmFzCiAgICAgICAgY29uc3Qgb3JpZ2luYWxEaXNwbGF5ID0gY2FudmFzLnN0eWxlLmRpc3BsYXk7CiAgICAgICAgY2FudmFzLnN0eWxlLmRpc3BsYXkgPSAnbm9uZSc7CiAgICAgICAgCiAgICAgICAgLy8gRm9yY2UgcmVmbG93CiAgICAgICAgdm9pZCBjYW52YXMub2Zmc2V0SGVpZ2h0OwogICAgICAgIAogICAgICAgIGNhbnZhcy5zdHlsZS5kaXNwbGF5ID0gb3JpZ2luYWxEaXNwbGF5OwogICAgICAgIAogICAgICAgIExvZ2dlci5kZWJ1ZygnQVBQJywgJ0ZvcmNlZCBjYW52YXMgcmVwYWludCBmb3IgaU9TIFdlYkdQVSBjb21wYXRpYmlsaXR5Jyk7CiAgICB9CiAgICAKICAgIC8qKgogICAgICogU2V0dXAgY2FudmFzIGVsZW1lbnQKICAgICAqLwogICAgc2V0dXBDYW52YXMoKSB7CiAgICAgICAgdGhpcy5zdGF0ZS5jYW52YXMgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnc3RhdGljQ2FudmFzJyk7CiAgICAgICAgCiAgICAgICAgaWYgKCF0aGlzLnN0YXRlLmNhbnZhcykgewogICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ0NhbnZhcyBlbGVtZW50IG5vdCBmb3VuZCcpOwogICAgICAgIH0KICAgICAgICAKICAgICAgICBpZiAoISh0aGlzLnN0YXRlLmNhbnZhcyBpbnN0YW5jZW9mIEhUTUxDYW52YXNFbGVtZW50KSkgewogICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ3N0YXRpY0NhbnZhcyBpcyBub3QgYSBjYW52YXMgZWxlbWVudCcpOwogICAgICAgIH0KICAgICAgICAKICAgICAgICAvLyBpT1MgZGVidWdnaW5nCiAgICAgICAgY29uc3QgaXNJT1MgPSAvaVBhZHxpUGhvbmV8aVBvZC8udGVzdChuYXZpZ2F0b3IudXNlckFnZW50KTsKICAgICAgICBMb2dnZXIuaW5mbygnQVBQJywgYFBsYXRmb3JtOiAke2lzSU9TID8gJ2lPUycgOiAnT3RoZXInfSwgVXNlciBBZ2VudDogJHtuYXZpZ2F0b3IudXNlckFnZW50LnN1YnN0cmluZygwLCA1MCl9Li4uYCk7CiAgICAgICAgCiAgICAgICAgLy8gU2V0IGNhbnZhcyBzaXplIHRvIHdpbmRvdyBzaXplCiAgICAgICAgdGhpcy5yZXNpemVDYW52YXMoKTsKICAgICAgICAKICAgICAgICAvLyBpT1MgV2ViR1BVIGNhbnZhcyB2aXNpYmlsaXR5IGNoZWNrCiAgICAgICAgY29uc3QgY29tcHV0ZWRTdHlsZSA9IHdpbmRvdy5nZXRDb21wdXRlZFN0eWxlKHRoaXMuc3RhdGUuY2FudmFzKTsKICAgICAgICBMb2dnZXIuaW5mbygnQVBQJywgYENhbnZhcyBzZXR1cCAtIERpbWVuc2lvbnM6ICR7dGhpcy5zdGF0ZS5jYW52YXMud2lkdGh9eCR7dGhpcy5zdGF0ZS5jYW52YXMuaGVpZ2h0fWApOwogICAgICAgIExvZ2dlci5pbmZvKCdBUFAnLCBgQ2FudmFzIGRpc3BsYXk6ICR7Y29tcHV0ZWRTdHlsZS5kaXNwbGF5fSwgdmlzaWJpbGl0eTogJHtjb21wdXRlZFN0eWxlLnZpc2liaWxpdHl9LCBvcGFjaXR5OiAke2NvbXB1dGVkU3R5bGUub3BhY2l0eX0sIHpJbmRleDogJHtjb21wdXRlZFN0eWxlLnpJbmRleH1gKTsKICAgIH0KICAgIAogICAgLyoqCiAgICAgKiBJbml0aWFsaXplIHJlbmRlcmVyIHVzaW5nIGZhY3RvcnkgKGF1dG8tZGV0ZWN0cyBXZWJHUFUvV2ViR0wpCiAgICAgKi8KICAgIGFzeW5jIGluaXRpYWxpemVSZW5kZXJlcigpIHsKICAgICAgICB0cnkgewogICAgICAgICAgICBMb2dnZXIuaW5mbygnQVBQJywgJ0luaXRpYWxpemluZyByZW5kZXJlci4uLicpOwogICAgICAgICAgICAKICAgICAgICAgICAgLy8gVXNlIGZhY3RvcnkgdG8gYXV0by1kZXRlY3QgYW5kIGNyZWF0ZSBiZXN0IGF2YWlsYWJsZSByZW5kZXJlcgogICAgICAgICAgICB0aGlzLnN0YXRlLnJlbmRlcmVyID0gYXdhaXQgUmVuZGVyZXJGYWN0b3J5LmNyZWF0ZVJlbmRlcmVyKHRoaXMuc3RhdGUuY2FudmFzKTsKICAgICAgICAgICAgCiAgICAgICAgICAgIExvZ2dlci5pbmZvKCdBUFAnLCBgUmVuZGVyZXIgaW5pdGlhbGl6ZWQ6ICR7dGhpcy5zdGF0ZS5yZW5kZXJlci5nZXRUeXBlKCl9YCk7CiAgICAgICAgICAgIAogICAgICAgIH0gY2F0Y2ggKGVycm9yKSB7CiAgICAgICAgICAgIExvZ2dlci5lcnJvcignQVBQJywgJ1JlbmRlcmVyIGluaXRpYWxpemF0aW9uIGZhaWxlZDonLCBlcnJvcik7CiAgICAgICAgICAgIHRocm93IGVycm9yOwogICAgICAgIH0KICAgIH0KICAgIAogICAgLyoqCiAgICAgKiBSZXNpemUgY2FudmFzIHRvIG1hdGNoIHdpbmRvdyBzaXplCiAgICAgKi8KICAgIHJlc2l6ZUNhbnZhcygpIHsKICAgICAg