LyoKKiBDb3B5cmlnaHQgqSB7MTk5Ny0xOTk5fSwgSW50ZXJuYXRpb25hbCBCdXNpbmVzcyBNYWNoaW5lcyBDb3Jwb3JhdGlvbiBhbmQgb3RoZXJzLiBBbGwgUmlnaHRzIFJlc2VydmVkLgoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCioKKiBGaWxlIFNNUERURk1ULkgKKgoqIE1vZGlmaWNhdGlvbiBIaXN0b3J5OgoqCiogICBEYXRlICAgICAgICBOYW1lICAgICAgICBEZXNjcmlwdGlvbgoqICAgMDIvMTkvOTcgICAgYWxpdSAgICAgICAgQ29udmVydGVkIGZyb20gamF2YS4KKiAgIDA3LzA5Lzk3ICAgIGhlbGVuYSAgICAgIE1ha2UgUGFyc2VQb3NpdGlvbiBpbnRvIGEgY2xhc3MuCiogICAwNy8yMS85OCAgICBzdGVwaGVuICAgICBBZGRlZCBHTVRfUExVUywgR01UX01JTlVTCiogICAgICAgICAgICAgICAgICAgICAgICAgICAgQ2hhbmdlZCBzZXRUd29EaWdpdFN0YXJ0RGF0ZSB0byBzZXQyRGlnaXRZZWFyU3RhcnQKKiAgICAgICAgICAgICAgICAgICAgICAgICAgICBDaGFuZ2VkIGdldFR3b0RpZ2l0U3RhcnREYXRlIHRvIGdldDJEaWdpdFllYXJTdGFydAoqICAgICAgICAgICAgICAgICAgICAgICAgICAgIFJlbW92ZWQgc3ViUGFyc2VMb25nCiogICAgICAgICAgICAgICAgICAgICAgICAgICAgUmVtb3ZlZCBnZXRab25lSW5kZXggKGFkZGVkIGluIERhdGVGb3JtYXRTeW1ib2xzKQoqICAgMDYvMTQvOTkgICAgc3RlcGhlbiAgICAgUmVtb3ZlZCBmZ1RpbWVab25lRGF0YVN1ZmZpeAoqICAgMTAvMTQvOTkgICAgYWxpdSAgICAgICAgVXBkYXRlZCBjbGFzcyBkb2MgdG8gZGVzY3JpYmUgMi1kaWdpdCB5ZWFyIHBhcnNpbmcKKiAgICAgICAgICAgICAgICAgICAgICAgICAgIHtqMjggNDE4MjA2Nn0uCioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKKi8KCiNpZm5kZWYgU01QRFRGTVRfSAojZGVmaW5lIFNNUERURk1UX0gKCiNpbmNsdWRlICJ1bmljb2RlL3V0eXBlcy5oIgojaW5jbHVkZSAidW5pY29kZS9kYXRlZm10LmgiCmNsYXNzIERhdGVGb3JtYXRTeW1ib2xzOwpjbGFzcyBEYXRlRm9ybWF0OwoKLyoqCiAqIFNpbXBsZURhdGVGb3JtYXQgaXMgYSBjb25jcmV0ZSBjbGFzcyBmb3IgZm9ybWF0dGluZyBhbmQgcGFyc2luZyBkYXRlcyBpbiBhCiAqIGxhbmd1YWdlLWluZGVwZW5kZW50IG1hbm5lci4gSXQgYWxsb3dzIGZvciBmb3JtYXR0aW5nIChtaWxsaXMgLT4gdGV4dCksCiAqIHBhcnNpbmcgKHRleHQgLT4gbWlsbGlzKSwgYW5kIG5vcm1hbGl6YXRpb24uIEZvcm1hdHMvUGFyc2VzIGEgZGF0ZSBvciB0aW1lLAogKiB3aGljaCBpcyB0aGUgc3RhbmRhcmQgbWlsbGlzZWNvbmRzIHNpbmNlIDI0OjAwIEdNVCwgSmFuIDEsIDE5NzAuCiAqIDxQPgogKiBDbGllbnRzIGFyZSBlbmNvdXJhZ2VkIHRvIGNyZWF0ZSBhIGRhdGUtdGltZSBmb3JtYXR0ZXIgdXNpbmcgRGF0ZUZvcm1hdDo6Z2V0SW5zdGFuY2UoKSwKICogZ2V0RGF0ZUluc3RhbmNlKCksIGdldERhdGVJbnN0YW5jZSgpLCBvciBnZXREYXRlVGltZUluc3RhbmNlKCkgcmF0aGVyIHRoYW4KICogZXhwbGljaXRseSBjb25zdHJ1Y3RpbmcgYW4gaW5zdGFuY2Ugb2YgU2ltcGxlRGF0ZUZvcm1hdC4gIFRoaXMgd2F5LCB0aGUgY2xpZW50CiAqIGlzIGd1YXJhbnRlZWQgdG8gZ2V0IGFuIGFwcHJvcHJpYXRlIGZvcm1hdHRpbmcgcGF0dGVybiBmb3Igd2hhdGV2ZXIgbG9jYWxlIHRoZQogKiBwcm9ncmFtIGlzIHJ1bm5pbmcgaW4uICBIb3dldmVyLCBpZiB0aGUgY2xpZW50IG5lZWRzIHNvbWV0aGluZyBtb3JlIHVudXN1YWwgdGhhbgogKiB0aGUgZGVmYXVsdCBwYXR0ZXJucyBpbiB0aGUgbG9jYWxlcywgaGUgY2FuIGNvbnN0cnVjdCBhIFNpbXBsZURhdGVGb3JtYXQgZGlyZWN0bHkKICogYW5kIGdpdmUgaXQgYW4gYXBwcm9wcmlhdGUgcGF0dGVybiAob3IgdXNlIG9uZSBvZiB0aGUgZmFjdG9yeSBtZXRob2RzIG9uIERhdGVGb3JtYXQKICogYW5kIG1vZGlmeSB0aGUgcGF0dGVybiBhZnRlciB0aGUgZmFjdCB3aXRoIHRvUGF0dGVybigpIGFuZCBhcHBseVBhdHRlcm4oKS4KICogPFA+CiAqIERhdGUvVGltZSBmb3JtYXQgc3ludGF4OgogKiA8UD4KICogVGhlIGRhdGUvdGltZSBmb3JtYXQgaXMgc3BlY2lmaWVkIGJ5IG1lYW5zIG9mIGEgc3RyaW5nIHRpbWUgcGF0dGVybi4gSW4gdGhpcwogKiBwYXR0ZXJuLCBhbGwgQVNDSUkgbGV0dGVycyBhcmUgcmVzZXJ2ZWQgYXMgcGF0dGVybiBsZXR0ZXJzLCB3aGljaCBhcmUgZGVmaW5lZAogKiBhcyB0aGUgZm9sbG93aW5nOgogKiA8cHJlPgogKiAuICAgU3ltYm9sICAgTWVhbmluZyAgICAgICAgICAgICAgICAgUHJlc2VudGF0aW9uICAgICAgIEV4YW1wbGUKICogLiAgIC0tLS0tLSAgIC0tLS0tLS0gICAgICAgICAgICAgICAgIC0tLS0tLS0tLS0tLSAgICAgICAtLS0tLS0tCiAqIC4gICBHICAgICAgICBlcmEgZGVzaWduYXRvciAgICAgICAgICAoVGV4dCkgICAgICAgICAgICAgQUQKICogLiAgIHkgICAgICAgIHllYXIgICAgICAgICAgICAgICAgICAgIChOdW1iZXIpICAgICAgICAgICAxOTk2CiAqIC4gICBZICAgICAgICB5ZWFyL3dlZWsgb2YgeWVhciAgICAgICAoTnVtYmVyKSAgICAgICAgICAgMTk5NgogKiAuICAgTSAgICAgICAgbW9udGggaW4geWVhciAgICAgICAgICAgKFRleHQgJiBOdW1iZXIpICAgIEp1bHkgJiAwNwogKiAuICAgZCAgICAgICAgZGF5IGluIG1vbnRoICAgICAgICAgICAgKE51bWJlcikgICAgICAgICAgIDEwCiAqIC4gICBoICAgICAgICBob3VyIGluIGFtL3BtICgxfjEyKSAgICAoTnVtYmVyKSAgICAgICAgICAgMTIKICogLiAgIEggICAgICAgIGhvdXIgaW4gZGF5ICgwfjIzKSAgICAgIChOdW1iZXIpICAgICAgICAgICAwCiAqIC4gICBtICAgICAgICBtaW51dGUgaW4gaG91ciAgICAgICAgICAoTnVtYmVyKSAgICAgICAgICAgMzAKICogLiAgIHMgICAgICAgIHNlY29uZCBpbiBtaW51dGUgICAgICAgIChOdW1iZXIpICAgICAgICAgICA1NQogKiAuICAgUyAgICAgICAgbWlsbGlzZWNvbmQgICAgICAgICAgICAgKE51bWJlcikgICAgICAgICAgIDk3OAogKiAuICAgRSAgICAgICAgZGF5IG9mIHdlZWsgICAgICAgICAgICAgKFRleHQpICAgICAgICAgICAgIFR1ZXNkYXkKICogLiAgIGUgICAgICAgIGRheSBvZiB3ZWVrL2xvY2FsICgxfjcpIChOdW1iZXIpICAgICAgICAgICAyCiAqIC4gICBEICAgICAgICBkYXkgb2YgeWVhciAgICAgICAgICAgICAoTnVtYmVyKSAgICAgICAgICAgMTg5CiAqIC4gICBGICAgICAgICBkYXkgb2Ygd2VlayBpbiBtb250aCAgICAoTnVtYmVyKSAgICAgICAgICAgMiAoMm5kIFdlZCBpbiBKdWx5KQogKiAuICAgdyAgICAgICAgd2VlayBpbiB5ZWFyICAgICAgICAgICAgKE51bWJlcikgICAgICAgICAgIDI3CiAqIC4gICBXICAgICAgICB3ZWVrIGluIG1vbnRoICAgICAgICAgICAoTnVtYmVyKSAgICAgICAgICAgMgogKiAuICAgYSAgICAgICAgYW0vcG0gbWFya2VyICAgICAgICAgICAgKFRleHQpICAgICAgICAgICAgIFBNCiAqIC4gICBrICAgICAgICBob3VyIGluIGRheSAoMX4yNCkgICAgICAoTnVtYmVyKSAgICAgICAgICAgMjQKICogLiAgIEsgICAgICAgIGhvdXIgaW4gYW0vcG0gKDB+MTEpICAgIChOdW1iZXIpICAgICAgICAgICAwCiAqIC4gICB6ICAgICAgICB0aW1lIHpvbmUgICAgICAgICAgICAgICAoVGV4dCkgICAgICAgICAgICAgUGFjaWZpYyBTdGFuZGFyZCBUaW1lCiAqIC4gICAnICAgICAgICBlc2NhcGUgZm9yIHRleHQKICogLiAgICcnICAgICAgIHNpbmdsZSBxdW90ZSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnCiAqIDwvcHJlPgogKiBUaGUgY291bnQgb2YgcGF0dGVybiBsZXR0ZXJzIGRldGVybWluZSB0aGUgZm9ybWF0LgogKiA8UD4KICogKFRleHQpOiA0IG9yIG1vcmUsIHVzZSBmdWxsIGZvcm0sICZsdDs0LCB1c2Ugc2hvcnQgb3IgYWJicmV2aWF0ZWQgZm9ybSBpZiBpdAogKiBleGlzdHMuIChlLmcuLCAiRUVFRSIgcHJvZHVjZXMgIk1vbmRheSIsICJFRUUiIHByb2R1Y2VzICJNb24iKQogKiA8UD4KICogKE51bWJlcik6IHRoZSBtaW5pbXVtIG51bWJlciBvZiBkaWdpdHMuIFNob3J0ZXIgbnVtYmVycyBhcmUgemVyby1wYWRkZWQgdG8KICogdGhpcyBhbW91bnQgKGUuZy4gaWYgIm0iIHByb2R1Y2VzICI2IiwgIm1tIiBwcm9kdWNlcyAiMDYiKS4gWWVhciBpcyBoYW5kbGVkCiAqIHNwZWNpYWxseTsgdGhhdCBpcywgaWYgdGhlIGNvdW50IG9mICd5JyBpcyAyLCB0aGUgWWVhciB3aWxsIGJlIHRydW5jYXRlZCB0byAyIGRpZ2l0cy4KICogKGUuZy4sIGlmICJ5eXl5IiBwcm9kdWNlcyAiMTk5NyIsICJ5eSIgcHJvZHVjZXMgIjk3Ii4pCiAqIDxQPgogKiAoVGV4dCAmIE51bWJlcik6IDMgb3Igb3ZlciwgdXNlIHRleHQsIG90aGVyd2lzZSB1c2UgbnVtYmVyLiAgKGUuZy4sICJNIiBwcm9kdWNlcyAiMSIsCiAqICJNTSIgcHJvZHVjZXMgIjAxIiwgIk1NTSIgcHJvZHVjZXMgIkphbiIsIGFuZCAiTU1NTSIgcHJvZHVjZXMgIkphbnVhcnkiLikKICogPFA+CiAqIEFueSBjaGFyYWN0ZXJzIGluIHRoZSBwYXR0ZXJuIHRoYXQgYXJlIG5vdCBpbiB0aGUgcmFuZ2VzIG9mIFsnYScuLid6J10gYW5kCiAqIFsnQScuLidaJ10gd2lsbCBiZSB0cmVhdGVkIGFzIHF1b3RlZCB0ZXh0LiBGb3IgaW5zdGFuY2UsIGNoYXJhY3RlcnMKICogbGlrZSAnOicsICcuJywgJyAnLCAnIycgYW5kICdAJyB3aWxsIGFwcGVhciBpbiB0aGUgcmVzdWx0aW5nIHRpbWUgdGV4dAogKiBldmVuIHRoZXkgYXJlIG5vdCBlbWJyYWNlZCB3aXRoaW4gc2luZ2xlIHF1b3Rlcy4KICogPFA+CiAqIEEgcGF0dGVybiBjb250YWluaW5nIGFueSBpbnZhbGlkIHBhdHRlcm4gbGV0dGVyIHdpbGwgcmVzdWx0IGluIGEgZmFpbGluZwogKiBVRXJyb3JDb2RlIHJlc3VsdCBkdXJpbmcgZm9ybWF0dGluZyBvciBwYXJzaW5nLgogKiA8UD4KICogRXhhbXBsZXMgdXNpbmcgdGhlIFVTIGxvY2FsZToKICogPHByZT4KICogLiAgIEZvcm1hdCBQYXR0ZXJuICAgICAgICAgICAgICAgICAgICAgICAgIFJlc3VsdAogKiAuICAgLS0tLS0tLS0tLS0tLS0gICAgICAgICAgICAgICAgICAgICAgICAgLS0tLS0tLQogKiAuICAgInl5eXkuTU0uZGQgRyAnYXQnIEhIOm1tOnNzIHoiICAgIC0+PiAgMTk5Ni4wNy4xMCBBRCBhdCAxNTowODo1NiBQRFQKICogLiAgICJFRUUsIE1NTSBkLCAnJ3l5IiAgICAgICAgICAgICAgICAtPj4gIFdlZCwgSnVseSAxMCwgJzk2CiAqIC4gICAiaDptbSBhIiAgICAgICAgICAgICAgICAgICAgICAgICAgLT4+ICAxMjowOCBQTQogKiAuICAgImhoICdvJydjbG9jaycgYSwgenp6eiIgICAgICAgICAgIC0+PiAgMTIgbydjbG9jayBQTSwgUGFjaWZpYyBEYXlsaWdodCBUaW1lCiAqIC4gICAiSzptbSBhLCB6IiAgICAgICAgICAgICAgICAgICAgICAgLT4+ICAwOjAwIFBNLCBQU1QKICogLiAgICJ5eXl5eS5NTU1NTS5kZCBHR0cgaGg6bW0gYWFhIiAgICAtPj4gIDE5OTYuSnVseS4xMCBBRCAxMjowOCBQTQogKiA8L3ByZT4KICogQ29kZSBTYW1wbGU6CiAqIDxwcmU+CiAqIC4gICAgVUVycm9yQ29kZSBzdWNjZXNzID0gVV9aRVJPX0VSUk9SOwogKiAuICAgIFNpbXBsZVRpbWVab25lKiBwZHQgPSBuZXcgU2ltcGxlVGltZVpvbmUoLTggKiA2MCAqIDYwICogMTAwMCwgIlBTVCIpOwogKiAuICAgIHBkdC0+c2V0U3RhcnRSdWxlKCBDYWxlbmRhcjo6QVBSSUwsIDEsIENhbGVuZGFyOjpTVU5EQVksIDIqNjAqNjAqMTAwMCk7CiAqIC4gICAgcGR0LT5zZXRFbmRSdWxlKCBDYWxlbmRhcjo6T0NUT0JFUiwgLTEsIENhbGVuZGFyOjpTVU5EQVksIDIqNjAqNjAqMTAwMCk7CiAqIC4gICAgCiAqIC4gICAgLy8gRm9ybWF0IHRoZSBjdXJyZW50IHRpbWUuCiAqIC4gICAgU2ltcGxlRGF0ZUZvcm1hdCogZm9ybWF0dGVyCiAqIC4gICAgICAgID0gbmV3IFNpbXBsZURhdGVGb3JtYXQgKCJ5eXl5Lk1NLmRkIEcgJ2F0JyBoaDptbTpzcyBhIHp6eiIsIHN1Y2Nlc3MgKTsKICogLiAgICBHcmVnb3JpYW5DYWxlbmRhciBjYWwoc3VjY2Vzcyk7CiAqIC4gICAgVURhdGUgY3VycmVudFRpbWVfMSA9IGNhbC5nZXRUaW1lKHN1Y2Nlc3MpOwogKiAuICAgIEZpZWxkUG9zaXRpb24gZnAoMCk7CiAqIC4gICAgVW5pY29kZVN0cmluZyBkYXRlU3RyaW5nOwogKiAuICAgIGZvcm1hdHRlci0+Zm9ybWF0KCBjdXJyZW50VGltZV8xLCBkYXRlU3RyaW5nLCBmcCApOwogKiAuICAgIGNvdXQgJmx0OyZsdDsgInJlc3VsdDogIiAmbHQ7Jmx0OyBkYXRlU3RyaW5nICZsdDsmbHQ7IGVuZGw7CiAqIC4gICAgCiAqIC4gICAgLy8gUGFyc2UgdGhlIHByZXZpb3VzIHN0cmluZyBiYWNrIGludG8gYSBEYXRlLgogKiAuICAgIFBhcnNlUG9zaXRpb24gcHAoMCk7CiAqIC4gICAgVURhdGUgY3VycmVudFRpbWVfMiA9IGZvcm1hdHRlci0+cGFyc2UoZGF0ZVN0cmluZywgcHAgKTsKICogPC9wcmU+CiAqIEluIHRoZSBhYm92ZSBleGFtcGxlLCB0aGUgdGltZSB2YWx1ZSAiY3VycmVudFRpbWVfMiIgb2J0YWluZWQgZnJvbSBwYXJzaW5nCiAqIHdpbGwgYmUgZXF1YWwgdG8gY3VycmVudFRpbWVfMS4gSG93ZXZlciwgdGhleSBtYXkgbm90IGJlIGVxdWFsIGlmIHRoZSBhbS9wbQogKiBtYXJrZXIgJ2EnIGlzIGxlZnQgb3V0IGZyb20gdGhlIGZvcm1hdCBwYXR0ZXJuIHdoaWxlIHRoZSAiaG91ciBpbiBhbS9wbSIKICogcGF0dGVybiBzeW1ib2wgaXMgdXNlZC4gVGhpcyBpbmZvcm1hdGlvbiBsb3NzIGNhbiBoYXBwZW4gd2hlbiBmb3JtYXR0aW5nIHRoZQogKiB0aW1lIGluIFBNLgogKgogKiA8cD4KICogV2hlbiBwYXJzaW5nIGEgZGF0ZSBzdHJpbmcgdXNpbmcgdGhlIGFiYnJldmlhdGVkIHllYXIgcGF0dGVybiAoInkiIG9yICJ5eSIpLAogKiBTaW1wbGVEYXRlRm9ybWF0IG11c3QgaW50ZXJwcmV0IHRoZSBhYmJyZXZpYXRlZCB5ZWFyCiAqIHJlbGF0aXZlIHRvIHNvbWUgY2VudHVyeS4gIEl0IGRvZXMgdGhpcyBieSBhZGp1c3RpbmcgZGF0ZXMgdG8gYmUKICogd2l0aGluIDgwIHllYXJzIGJlZm9yZSBhbmQgMjAgeWVhcnMgYWZ0ZXIgdGhlIHRpbWUgdGhlIFNpbXBsZURhdGVGb3JtYXQKICogaW5zdGFuY2UgaXMgY3JlYXRlZC4gRm9yIGV4YW1wbGUsIHVzaW5nIGEgcGF0dGVybiBvZiAiTU0vZGQveXkiIGFuZCBhCiAqIFNpbXBsZURhdGVGb3JtYXQgaW5zdGFuY2UgY3JlYXRlZCBvbiBKYW4gMSwgMTk5NywgIHRoZSBzdHJpbmcKICogIjAxLzExLzEyIiB3b3VsZCBiZSBpbnRlcnByZXRlZCBhcyBKYW4gMTEsIDIwMTIgd2hpbGUgdGhlIHN0cmluZyAiMDUvMDQvNjQiCiAqIHdvdWxkIGJlIGludGVycHJldGVkIGFzIE1heSA0LCAxOTY0LgogKiBEdXJpbmcgcGFyc2luZywgb25seSBzdHJpbmdzIGNvbnNpc3Rpbmcgb2YgZXhhY3RseSB0d28gZGlnaXRzLCBhcyBkZWZpbmVkIGJ5CiAqIDxjb2RlPlVuaWNvZGU6OmlzRGlnaXQoKTwvY29kZT4sIHdpbGwgYmUgcGFyc2VkIGludG8gdGhlIGRlZmF1bHQgY2VudHVyeS4KICogQW55IG90aGVyIG51bWVyaWMgc3RyaW5nLCBzdWNoIGFzIGEgb25lIGRpZ2l0IHN0cmluZywgYSB0aHJlZSBvciBtb3JlIGRpZ2l0CiAqIHN0cmluZywgb3IgYSB0d28gZGlnaXQgc3RyaW5nIHRoYXQgaXNuJ3QgYWxsIGRpZ2l0cyAoZm9yIGV4YW1wbGUsICItMSIpLCBpcwogKiBpbnRlcnByZXRlZCBsaXRlcmFsbHkuICBTbyAiMDEvMDIvMyIgb3IgIjAxLzAyLzAwMyIgYXJlIHBhcnNlZCwgdXNpbmcgdGhlCiAqIHNhbWUgcGF0dGVybiwgYXMgSmFuIDIsIDMgQUQuICBMaWtld2lzZSwgIjAxLzAyLy0zIiBpcyBwYXJzZWQgYXMgSmFuIDIsIDQgQkMuCiAqCiAqIDxwPgogKiBJZiB0aGUgeWVhciBwYXR0ZXJuIGhhcyBtb3JlIHRoYW4gdHdvICd5JyBjaGFyYWN0ZXJzLCB0aGUgeWVhciBpcwogKiBpbnRlcnByZXRlZCBsaXRlcmFsbHksIHJlZ2FyZGxlc3Mgb2YgdGhlIG51bWJlciBvZiBkaWdpdHMuICBTbyB1c2luZyB0aGUKICogcGF0dGVybiAiTU0vZGQveXl5eSIsICIwMS8xMS8xMiIgcGFyc2VzIHRvIEphbiAxMSwgMTIgQS5ELgogKgogKiA8UD4KICogRm9yIHRpbWUgem9uZXMgdGhhdCBoYXZlIG5vIG5hbWVzLCBTaW1wbGVEYXRlRm9ybWF0IHVzZXMgc3RyaW5ncyBHTVQraG91cnM6bWludXRlcyBvcgogKiBHTVQtaG91cnM6bWludXRlcy4KICogPFA+CiAqIFRoZSBjYWxlbmRhciBkZWZpbmVzIHdoYXQgaXMgdGhlIGZpcnN0IGRheSBvZiB0aGUgd2VlaywgdGhlIGZpcnN0IHdlZWsgb2YgdGhlCiAqIHllYXIsIHdoZXRoZXIgaG91cnMgYXJlIHplcm8gYmFzZWQgb3Igbm90ICgwIHZzIDEyIG9yIDI0KSwgYW5kIHRoZSB0aW1lem9uZS4KICogVGhlcmUgaXMgb25lIGNvbW1vbiBudW1iZXIgZm9ybWF0IHRvIGhhbmRsZSBhbGwgdGhlIG51bWJlcnM7IHRoZSBkaWdpdCBjb3VudAogKiBpcyBoYW5kbGVkIHByb2dyYW1tYXRpY2FsbHkgYWNjb3JkaW5nIHRvIHRoZSBwYXR0ZXJuLgogKi8KY2xhc3MgVV9JMThOX0FQSSBTaW1wbGVEYXRlRm9ybWF0OiBwdWJsaWMgRGF0ZUZvcm1hdCB7CnB1YmxpYzoKICAgIC8qKgogICAgICogQ29uc3RydWN0IGEgU2ltcGxlRGF0ZUZvcm1hdCB1c2luZyB0aGUgZGVmYXVsdCBwYXR0ZXJuIGZvciB0aGUgZGVmYXVsdAogICAgICogbG9jYWxlLgogICAgICogPFA+CiAgICAgKiBbTm90ZTpdIE5vdCBhbGwgbG9jYWxlcyBzdXBwb3J0IFNpbXBsZURhdGVGb3JtYXQ7IGZvciBmdWxsIGdlbmVyYWxpdHksCiAgICAgKiB1c2UgdGhlIGZhY3RvcnkgbWV0aG9kcyBpbiB0aGUgRGF0ZUZvcm1hdCBjbGFzcy4KICAgICAqIEBzdGFibGUKICAgICAqLwogICAgU2ltcGxlRGF0ZUZvcm1hdChVRXJyb3JDb2RlJiBzdGF0dXMpOwoKICAgIC8qKgogICAgICogQ29uc3RydWN0IGEgU2ltcGxlRGF0ZUZvcm1hdCB1c2luZyB0aGUgZ2l2ZW4gcGF0dGVybiBhbmQgdGhlIGRlZmF1bHQgbG9jYWxlLgogICAgICogVGhlIGxvY2FsZSBpcyB1c2VkIHRvIG9idGFpbiB0aGUgc3ltYm9scyB1c2VkIGluIGZvcm1hdHRpbmcgKGUuZy4sIHRoZQogICAgICogbmFtZXMgb2YgdGhlIG1vbnRocyksIGJ1dCBub3QgdG8gcHJvdmlkZSB0aGUgcGF0dGVybi4KICAgICAqIDxQPgogICAgICogW05vdGU6XSBOb3QgYWxsIGxvY2FsZXMgc3VwcG9ydCBTaW1wbGVEYXRlRm9ybWF0OyBmb3IgZnVsbCBnZW5lcmFsaXR5LAogICAgICogdXNlIHRoZSBmYWN0b3J5IG1ldGhvZHMgaW4gdGhlIERhdGVGb3JtYXQgY2xhc3MuCiAgICAgKiBAc3RhYmxlCiAgICAgKi8KICAgIFNpbXBsZURhdGVGb3JtYXQoY29uc3QgVW5pY29kZVN0cmluZyYgcGF0dGVybiwKICAgICAgICAgICAgICAgICAgICAgVUVycm9yQ29kZSYgc3RhdHVzKTsKCiAgICAvKioKICAgICAqIENvbnN0cnVjdCBhIFNpbXBsZURhdGVGb3JtYXQgdXNpbmcgdGhlIGdpdmVuIHBhdHRlcm4gYW5kIGxvY2FsZS4KICAgICAqIFRoZSBsb2NhbGUgaXMgdXNlZCB0byBvYnRhaW4gdGhlIHN5bWJvbHMgdXNlZCBpbiBmb3JtYXR0aW5nIChlLmcuLCB0aGUKICAgICAqIG5hbWVzIG9mIHRoZSBtb250aHMpLCBidXQgbm90IHRvIHByb3ZpZGUgdGhlIHBhdHRlcm4uCiAgICAgKiA8UD4KICAgICAqIFtOb3RlOl0gTm90IGFsbCBsb2NhbGVzIHN1cHBvcnQgU2ltcGxlRGF0ZUZvcm1hdDsgZm9yIGZ1bGwgZ2VuZXJhbGl0eSwKICAgICAqIHVzZSB0aGUgZmFjdG9yeSBtZXRob2RzIGluIHRoZSBEYXRlRm9ybWF0IGNsYXNzLgogICAgICogQHN0YWJsZQogICAgICovCiAgICBTaW1wbGVEYXRlRm9ybWF0KGNvbnN0IFVuaWNvZGVTdHJpbmcmIHBhdHRlcm4sCiAgICAgICAgICAgICAgICAgICAgIGNvbnN0IExvY2FsZSYgbG9jYWxlLAogICAgICAgICAgICAgICAgICAgICBVRXJyb3JDb2RlJiBzdGF0dXMpOwoKICAgIC8qKgogICAgICogQ29uc3RydWN0IGEgU2ltcGxlRGF0ZUZvcm1hdCB1c2luZyB0aGUgZ2l2ZW4gcGF0dGVybiBhbmQgbG9jYWxlLXNwZWNpZmljCiAgICAgKiBzeW1ib2wgZGF0YS4gIFRoZSBmb3JtYXR0ZXIgdGFrZXMgb3duZXJzaGlwIG9mIHRoZSBEYXRlRm9ybWF0U3ltYm9scyBvYmplY3Q7CiAgICAgKiB0aGUgY2FsbGVyIGlzIG5vIGxvbmdlciByZXNwb25zaWJsZSBmb3IgZGVsZXRpbmcgaXQuCiAgICAgKiBAc3RhYmxlCiAgICAgKi8KICAgIFNpbXBsZURhdGVGb3JtYXQoY29uc3QgVW5pY29kZVN0cmluZyYgcGF0dGVybiwKICAgICAgICAgICAgICAgICAgICAgRGF0ZUZvcm1hdFN5bWJvbHMqIGZvcm1hdERhdGFUb0Fkb3B0LAogICAgICAgICAgICAgICAgICAgICBVRXJyb3JDb2RlJiBzdGF0dXMpOwoKICAgIC8qKgogICAgICogQ29uc3RydWN0IGEgU2ltcGxlRGF0ZUZvcm1hdCB1c2luZyB0aGUgZ2l2ZW4gcGF0dGVybiBhbmQgbG9jYWxlLXNwZWNpZmljCiAgICAgKiBzeW1ib2wgZGF0YS4gIFRoZSBEYXRlRm9ybWF0U3ltYm9scyBvYmplY3QgaXMgTk9UIGFkb3B0ZWQ7IHRoZSBjYWxsZXIKICAgICAqIHJlbWFpbnMgcmVzcG9uc2libGUgZm9yIGRlbGV0aW5nIGl0LgogICAgICogQHN0YWJsZQogICAgICovCiAgICBTaW1wbGVEYXRlRm9ybWF0KGNvbnN0IFVuaWNvZGVTdHJpbmcmIHBhdHRlcm4sCiAgICAgICAgICAgICAgICAgICAgIGNvbnN0IERhdGVGb3JtYXRTeW1ib2xzJiBmb3JtYXREYXRhLAogICAgICAgICAgICAgICAgICAgICBVRXJyb3JDb2RlJiBzdGF0dXMpOwoKICAgIC8qKgogICAgICogQ29weSBjb25zdHJ1Y3Rvci4KICAgICAqIEBzdGFibGUKICAgICAqLwogICAgU2ltcGxlRGF0ZUZvcm1hdChjb25zdCBTaW1wbGVEYXRlRm9ybWF0Jik7CgogICAgLyoqCiAgICAgKiBBc3NpZ25tZW50IG9wZXJhdG9yLgogICAgICogQHN0YWJsZQogICAgICovCiAgICBTaW1wbGVEYXRlRm9ybWF0JiBvcGVyYXRvcj0oY29uc3QgU2ltcGxlRGF0ZUZvcm1hdCYpOwoKICAgIC8qKgogICAgICogRGVzdHJ1Y3Rvci4KICAgICAqIEBzdGFibGUKICAgICAqLwogICAgdmlydHVhbCB+U2ltcGxlRGF0ZUZvcm1hdCgpOwoKICAgIC8qKgogICAgICogQ2xvbmUgdGhpcyBGb3JtYXQgb2JqZWN0IHBvbHltb3JwaGljYWxseS4gVGhlIGNhbGxlciBvd25zIHRoZSByZXN1bHQgYW5kCiAgICAgKiBzaG91bGQgZGVsZXRlIGl0IHdoZW4gZG9uZS4KICAgICAqIEBzdGFibGUKICAgICAqLwogICAgdmlydHVhbCBGb3JtYXQqIGNsb25lKHZvaWQpIGNvbnN0OwoKICAgIC8qKgogICAgICogUmV0dXJuIHRydWUgaWYgdGhlIGdpdmVuIEZvcm1hdCBvYmplY3RzIGFyZSBzZW1hbnRpY2FsbHkgZXF1YWwuIE9iamVjdHMKICAgICAqIG9mIGRpZmZlcmVudCBzdWJjbGFzc2VzIGFyZSBjb25zaWRlcmVkIHVuZXF1YWwuCiAgICAgKiBAc3RhYmxlCiAgICAgKi8KICAgIHZpcnR1YWwgVUJvb2wgb3BlcmF0b3I9PShjb25zdCBGb3JtYXQmIG90aGVyKSBjb25zdDsKCiAgICAvKioKICAgICAqIEZvcm1hdCBhIGRhdGUgb3IgdGltZSwgd2hpY2ggaXMgdGhlIHN0YW5kYXJkIG1pbGxpcyBzaW5jZSAyNDowMCBHTVQsIEphbgogICAgICogMSwgMTk3MC4gT3ZlcnJpZGVzIERhdGVGb3JtYXQgcHVyZSB2aXJ0dWFsIG1ldGhvZC4KICAgICAqIDxQPgogICAgICogRXhhbXBsZTogdXNpbmcgdGhlIFVTIGxvY2FsZTogInl5eXkuTU0uZGQgZSAnYXQnIEhIOm1tOnNzIHp6eiIgLT4+CiAgICAgKiAxOTk2LjA3LjEwIEFEIGF0IDE1OjA4OjU2IFBEVAogICAgICoKICAgICAqIEBwYXJhbSBkYXRlICAgICAgICAgIFRoZSBkYXRlLXRpbWUgdmFsdWUgdG8gYmUgZm9ybWF0dGVkIGludG8gYSBkYXRlLXRpbWUgc3RyaW5nLgogICAgICogQHBhcmFtIHRvQXBwZW5kVG8gICAgVGhlIHJlc3VsdCBvZiB0aGUgZm9ybWF0dGluZyBvcGVyYXRpb24gaXMgYXBwZW5kZWQgdG8gdGhpcwogICAgICogICAgICAgICAgICAgICAgICAgICAgc3RyaW5nLgogICAgICogQHBhcmFtIHBvcyAgICAgICAgICAgVGhlIGZvcm1hdHRpbmcgcG9zaXRpb24uIE9uIGlucHV0OiBhbiBhbGlnbm1lbnQgZmllbGQsCiAgICAgKiAgICAgICAgICAgICAgICAgICAgICBpZiBkZXNpcmVkLiBPbiBvdXRwdXQ6IHRoZSBvZmZzZXRzIG9mIHRoZSBhbGlnbm1lbnQgZmllbGQuCiAgICAgKiBAcmV0dXJuICAgICAgICAgICAgICBBIHJlZmVyZW5jZSB0byAndG9BcHBlbmRUbycuCiAgICAgKiBAc3RhYmxlCiAgICAgKi8KICAgIHZpcnR1YWwgVW5pY29kZVN0cmluZyYgZm9ybWF0KCAgVURhdGUgZGF0ZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVW5pY29kZVN0cmluZyYgdG9BcHBlbmRUbywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRmllbGRQb3NpdGlvbiYgcG9zKSBjb25zdDsKCiAgICAvKioKICAgICAqIEZvcm1hdCBhIGRhdGUgb3IgdGltZSwgd2hpY2ggaXMgdGhlIHN0YW5kYXJkIG1pbGxpcyBzaW5jZSAyNDowMCBHTVQsIEphbgogICAgICogMSwgMTk3MC4gT3ZlcnJpZGVzIERhdGVGb3JtYXQgcHVyZSB2aXJ0dWFsIG1ldGhvZC4KICAgICAqIDxQPgogICAgICogRXhhbXBsZTogdXNpbmcgdGhlIFVTIGxvY2FsZTogInl5eXkuTU0uZGQgZSAnYXQnIEhIOm1tOnNzIHp6eiIgLT4+CiAgICAgKiAxOTk2LjA3LjEwIEFEIGF0IDE1OjA4OjU2IFBEVAogICAgICoKICAgICAqIEBwYXJhbSBvYmogICAgICAgICAgIEEgRm9ybWF0dGFibGUgY29udGFpbmluZyB0aGUgZGF0ZS10aW1lIHZhbHVlIHRvIGJlIGZvcm1hdHRlZAogICAgICogICAgICAgICAgICAgICAgICAgICAgaW50byBhIGRhdGUtdGltZSBzdHJpbmcuICBJZiB0aGUgdHlwZSBvZiB0aGUgRm9ybWF0dGFibGUKICAgICAqICAgICAgICAgICAgICAgICAgICAgIGlzIGEgbnVtZXJpYyB0eXBlLCBpdCBpcyB0cmVhdGVkIGFzIGlmIGl0IHdlcmUgYW4KICAgICAqICAgICAgICAgICAgICAgICAgICAgIGluc3RhbmNlIG9mIERhdGUuCiAgICAgKiBAcGFyYW0gdG9BcHBlbmRUbyAgICBUaGUgcmVzdWx0IG9mIHRoZSBmb3JtYXR0aW5nIG9wZXJhdGlvbiBpcyBhcHBlbmRlZCB0byB0aGlzCiAgICAgKiAgICAgICAgICAgICAgICAgICAgICBzdHJpbmcuCiAgICAgKiBAcGFyYW0gcG9zICAgICAgICAgICBUaGUgZm9ybWF0dGluZyBwb3NpdGlvbi4gT24gaW5wdXQ6IGFuIGFsaWdubWVudCBmaWVsZCwKICAgICAqICAgICAgICAgICAgICAgICAgICAgIGlmIGRlc2lyZWQuIE9uIG91dHB1dDogdGhlIG9mZnNldHMgb2YgdGhlIGFsaWdubWVudCBmaWVsZC4KICAgICAqIEByZXR1cm4gICAgICAgICAgICAgIEEgcmVmZXJlbmNlIHRvICd0b0FwcGVuZFRvJy4KICAgICAqIEBzdGFibGUKICAgICAqLwogICAgdmlydHVhbCBVbmljb2RlU3RyaW5nJiBmb3JtYXQoICBjb25zdCBGb3JtYXR0YWJsZSYgb2JqLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBVbmljb2RlU3RyaW5nJiB0b0FwcGVuZFRvLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBGaWVsZFBvc2l0aW9uJiBwb3MsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFVFcnJvckNvZGUmIHN0YXR1cykgY29uc3Q7CgogICAgLyoqCiAgICAgKiBSZWRlY2xhcmVkIERhdGVGb3JtYXQgbWV0aG9kLgogICAgICogQHN0YWJsZQogICAgICovCiAgICBVbmljb2RlU3RyaW5nJiBmb3JtYXQoY29uc3QgRm9ybWF0dGFibGUmIG9iaiwKICAgICAgICAgICAgICAgICAgICAgICAgICBVbmljb2RlU3RyaW5nJiByZXN1bHQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgVUVycm9yQ29kZSYgc3RhdHVzKSBjb25zdDsKCiAgICAvKioKICAgICAqIFJlZGVjbGFyZWQgRGF0ZUZvcm1hdCBtZXRob2QuCiAgICAgKiBAc3RhYmxlCiAgICAgKi8KICAgIFVuaWNvZGVTdHJpbmcmIGZvcm1hdChVRGF0ZSBkYXRlLCBVbmljb2RlU3RyaW5nJiByZXN1bHQpIGNvbnN0OwoKICAgIC8qKgogICAgICogUGFyc2UgYSBkYXRlL3RpbWUgc3RyaW5nIHN0YXJ0aW5nIGF0IHRoZSBnaXZlbiBwYXJzZSBwb3NpdGlvbi4gRm9yCiAgICAgKiBleGFtcGxlLCBhIHRpbWUgdGV4dCAiMDcvMTAvOTYgNDo1IFBNLCBQRFQiIHdpbGwgYmUgcGFyc2VkIGludG8gYSBEYXRlCiAgICAgKiB0aGF0IGlzIGVxdWl2YWxlbnQgdG8gRGF0ZSg4MzcwMzk5MjgwNDYpLgogICAgICogPFA+CiAgICAgKiBCeSBkZWZhdWx0LCBwYXJzaW5nIGlzIGxlbmllbnQ6IElmIHRoZSBpbnB1dCBpcyBub3QgaW4gdGhlIGZvcm0gdXNlZCBieQogICAgICogdGhpcyBvYmplY3QncyBmb3JtYXQgbWV0aG9kIGJ1dCBjYW4gc3RpbGwgYmUgcGFyc2VkIGFzIGEgZGF0ZSwgdGhlbiB0aGUKICAgICAqIHBhcnNlIHN1Y2NlZWRzLiBDbGllbnRzIG1heSBpbnNpc3Qgb24gc3RyaWN0IGFkaGVyZW5jZSB0byB0aGUgZm9ybWF0IGJ5CiAgICAgKiBjYWxsaW5nIHNldExlbmllbnQoZmFsc2UpLgogICAgICoKICAgICAqIEBzZWUgRGF0ZUZvcm1hdDo6c2V0TGVuaWVudChib29sZWFuKQogICAgICoKICAgICAqIEBwYXJhbSB0ZXh0ICBUaGUgZGF0ZS90aW1lIHN0cmluZyB0byBiZSBwYXJzZWQKICAgICAqIEBwYXJhbSBwb3MgICBPbiBpbnB1dCwgdGhlIHBvc2l0aW9uIGF0IHdoaWNoIHRvIHN0YXJ0IHBhcnNpbmc7IG9uCiAgICAgKiAgICAgICAgICAgICAgb3V0cHV0LCB0aGUgcG9zaXRpb24gYXQgd2hpY2ggcGFyc2luZyB0ZXJtaW5hdGVkLCBvciB0aGUKICAgICAqICAgICAgICAgICAgICBzdGFydCBwb3NpdGlvbiBpZiB0aGUgcGFyc2UgZmFpbGVkLgogICAgICogQHJldHVybiAgICAgIEEgdmFsaWQgVURhdGUgaWYgdGhlIGlucHV0IGNvdWxkIGJlIHBhcnNlZC4KICAgICAqIEBzdGFibGUKICAgICAqLwogICAgdmlydHVhbCBVRGF0ZSBwYXJzZSggY29uc3QgVW5pY29kZVN0cmluZyYgdGV4dCwKICAgICAgICAgICAgICAgICAgICAgICAgUGFyc2VQb3NpdGlvbiYgcG9zKSBjb25zdDsKCgogICAgLyoqCiAgICAgKiBQYXJzZSBhIGRhdGUvdGltZSBzdHJpbmcuIEZvciBleGFtcGxlLCBhIHRpbWUgdGV4dCAiMDcvMTAvOTYgNDo1IFBNLCBQRFQiCiAgICAgKiB3aWxsIGJlIHBhcnNlZCBpbnRvIGEgVURhdGUgdGhhdCBpcyBlcXVpdmFsZW50IHRvIERhdGUoODM3MDM5OTI4MDQ2KS4KICAgICAqIFBhcnNpbmcgYmVnaW5zIGF0IHRoZSBiZWdpbm5pbmcgb2YgdGhlIHN0cmluZyBhbmQgcHJvY2VlZHMgYXMgZmFyIGFzCiAgICAgKiBwb3NzaWJsZS4gIEFzc3VtaW5nIG5vIHBhcnNlIGVycm9ycyB3ZXJlIGVuY291bnRlcmVkLCB0aGlzIGZ1bmN0aW9uCiAgICAgKiBkb2Vzbid0IHJldHVybiBhbnkgaW5mb3JtYXRpb24gYWJvdXQgaG93IG11Y2ggb2YgdGhlIHN0cmluZyB3YXMgY29uc3VtZWQKICAgICAqIGJ5IHRoZSBwYXJzaW5nLiAgSWYgeW91IG5lZWQgdGhhdCBpbmZvcm1hdGlvbiwgdXNlIHRoZSB2ZXJzaW9uIG9mCiAgICAgKiBwYXJzZSgpIHRoYXQgdGFrZXMgYSBQYXJzZVBvc2l0aW9uLgogICAgICoKICAgICAqIEBwYXJhbSB0ZXh0ICBUaGUgZGF0ZS90aW1lIHN0cmluZyB0byBiZSBwYXJzZWQKICAgICAqIEBwYXJhbSBzdGF0dXMgRmlsbGVkIGluIHdpdGggVV9aRVJPX0VSUk9SIGlmIHRoZSBwYXJzZSB3YXMgc3VjY2Vzc2Z1bCwgYW5kIHdpdGgKICAgICAqICAgICAgICAgICAgICBhbiBlcnJvciB2YWx1ZSBpZiB0aGVyZSB3YXMgYSBwYXJzZSBlcnJvci4KICAgICAqIEByZXR1cm4gICAgICBBIHZhbGlkIFVEYXRlIGlmIHRoZSBpbnB1dCBjb3VsZCBiZSBwYXJzZWQuCiAgICAgKiBAc3RhYmxlCiAgICAgKi8KICAgIHZpcnR1YWwgVURhdGUgcGFyc2UoIGNvbnN0IFVuaWNvZGVTdHJpbmcmIHRleHQsCiAgICAgICAgICAgICAgICAgICAgICAgIFVFcnJvckNvZGUmIHN0YXR1cykgY29uc3Q7CgogICAgLyoqCiAgICAgKiBTZXQgdGhlIHN0YXJ0IFVEYXRlIHVzZWQgdG8gaW50ZXJwcmV0IHR3by1kaWdpdCB5ZWFyIHN0cmluZ3MuCiAgICAgKiBXaGVuIGRhdGVzIGFyZSBwYXJzZWQgaGF2aW5nIDItZGlnaXQgeWVhciBzdHJpbmdzLCB0aGV5IGFyZSBwbGFjZWQgd2l0aGluCiAgICAgKiBhIGFzc3VtZWQgcmFuZ2Ugb2YgMTAwIHllYXJzIHN0YXJ0aW5nIG9uIHRoZSB0d28gZGlnaXQgc3RhcnQgZGF0ZS4gIEZvcgogICAgICogZXhhbXBsZSwgdGhlIHN0cmluZyAiMjQtSmFuLTE3IiBtYXkgYmUgaW4gdGhlIHllYXIgMTgxNywgMTkxNywgMjAxNywgb3IKICAgICAqIHNvbWUgb3RoZXIgeWVhci4gIFNpbXBsZURhdGVGb3JtYXQgY2hvb3NlcyBhIHllYXIgc28gdGhhdCB0aGUgcmVzdWx0YW50CiAgICAgKiBkYXRlIGlzIG9uIG9yIGFmdGVyIHRoZSB0d28gZGlnaXQgc3RhcnQgZGF0ZSBhbmQgd2l0aGluIDEwMCB5ZWFycyBvZiB0aGUKICAgICAqIHR3byBkaWdpdCBzdGFydCBkYXRlLgogICAgICogPFA+CiAgICAgKiBCeSBkZWZhdWx0LCB0aGUgdHdvIGRpZ2l0IHN0YXJ0IGRhdGUgaXMgc2V0IHRvIDgwIHllYXJzIGJlZm9yZSB0aGUgY3VycmVudAogICAgICogdGltZSBhdCB3aGljaCBhIFNpbXBsZURhdGVGb3JtYXQgb2JqZWN0IGlzIGNyZWF0ZWQuCiAgICAgKiBAc3RhYmxlCiAgICAgKi8KICAgIHZpcnR1YWwgdm9pZCBzZXQyRGlnaXRZZWFyU3RhcnQoVURhdGUgZCwgVUVycm9yQ29kZSYgc3RhdHVzKTsKCiAgICAvKioKICAgICAqIEdldCB0aGUgc3RhcnQgVURhdGUgdXNlZCB0byBpbnRlcnByZXQgdHdvLWRpZ2l0IHllYXIgc3RyaW5ncy4KICAgICAqIFdoZW4gZGF0ZXMgYXJlIHBhcnNlZCBoYXZpbmcgMi1kaWdpdCB5ZWFyIHN0cmluZ3MsIHRoZXkgYXJlIHBsYWNlZCB3aXRoaW4KICAgICAqIGEgYXNzdW1lZCByYW5nZSBvZiAxMDAgeWVhcnMgc3RhcnRpbmcgb24gdGhlIHR3byBkaWdpdCBzdGFydCBkYXRlLiAgRm9yCiAgICAgKiBleGFtcGxlLCB0aGUgc3RyaW5nICIyNC1KYW4tMTciIG1heSBiZSBpbiB0aGUgeWVhciAxODE3LCAxOTE3LCAyMDE3LCBvcgogICAgICogc29tZSBvdGhlciB5ZWFyLiAgU2ltcGxlRGF0ZUZvcm1hdCBjaG9vc2VzIGEgeWVhciBzbyB0aGF0IHRoZSByZXN1bHRhbnQKICAgICAqIGRhdGUgaXMgb24gb3IgYWZ0ZXIgdGhlIHR3byBkaWdpdCBzdGFydCBkYXRlIGFuZCB3aXRoaW4gMTAwIHllYXJzIG9mIHRoZQogICAgICogdHdvIGRpZ2l0IHN0YXJ0IGRhdGUuCiAgICAgKiA8UD4KICAgICAqIEJ5IGRlZmF1bHQsIHRoZSB0d28gZGlnaXQgc3RhcnQgZGF0ZSBpcyBzZXQgdG8gODAgeWVhcnMgYmVmb3JlIHRoZSBjdXJyZW50CiAgICAgKiB0aW1lIGF0IHdoaWNoIGEgU2ltcGxlRGF0ZUZvcm1hdCBvYmplY3QgaXMgY3JlYXRlZC4KICAgICAqIEBzdGFibGUKICAgICAqLwogICAgVURhdGUgZ2V0MkRpZ2l0WWVhclN0YXJ0KFVFcnJvckNvZGUmIHN0YXR1cykgY29uc3Q7CgogICAgLyoqCiAgICAgKiBSZXR1cm4gYSBwYXR0ZXJuIHN0cmluZyBkZXNjcmliaW5nIHRoaXMgZGF0ZSBmb3JtYXQuCiAgICAgKiBAc3RhYmxlCiAgICAgKi8KICAgIHZpcnR1YWwgVW5pY29kZVN0cmluZyYgdG9QYXR0ZXJuKFVuaWNvZGVTdHJpbmcmIHJlc3VsdCkgY29uc3Q7CgogICAgLyoqCiAgICAgKiBSZXR1cm4gYSBsb2NhbGl6ZWQgcGF0dGVybiBzdHJpbmcgZGVzY3JpYmluZyB0aGlzIGRhdGUgZm9ybWF0LgogICAgICogSW4gbW9zdCBjYXNlcywgdGhpcyB3aWxsIHJldHVybiB0aGUgc2FtZSB0aGluZyBhcyB0b1BhdHRlcm4oKSwKICAgICAqIGJ1dCBhIGxvY2FsZSBjYW4gc3BlY2lmeSBjaGFyYWN0ZXJzIHRvIHVzZSBpbiBwYXR0ZXJuIGRlc2NyaXB0aW9ucwogICAgICogaW4gcGxhY2Ugb2YgdGhlIG9uZXMgZGVzY3JpYmVkIGluIHRoaXMgY2xhc3MncyBjbGFzcyBkb2N1bWVudGF0aW9uLgogICAgICogKFByZXN1bWFibHksIGxldHRlcnMgdGhhdCB3b3VsZCBiZSBtb3JlIG1uZW1vbmljIGluIHRoYXQgbG9jYWxlJ3MKICAgICAqIGxhbmd1YWdlLikgIFRoaXMgZnVuY3Rpb24gd291bGQgcHJvZHVjZSBhIHBhdHRlcm4gdXNpbmcgdGhvc2UKICAgICAqIGxldHRlcnMuCiAgICAgKgogICAgICogQHBhcmFtIHJlc3VsdCAgICBSZWNlaXZlcyB0aGUgbG9jYWxpemVkIHBhdHRlcm4uCiAgICAgKiBAcGFyYW0gc3RhdHVzICAgIE91dHB1dCBwYXJhbSBzZXQgdG8gc3VjY2Vzcy9mYWlsdXJlIGNvZGUgb24KICAgICAqICAgICAgICAgICAgICAgICAgZXhpdC4gSWYgdGhlIHBhdHRlcm4gaXMgaW52YWxpZCwgdGhpcyB3aWxsIGJlCiAgICAgKiAgICAgICAgICAgICAgICAgIHNldCB0byBhIGZhaWx1cmUgcmVzdWx0LgogICAgICogQHN0YWJsZQogICAgICovCiAgICB2aXJ0dWFsIFVuaWNvZGVTdHJpbmcmIHRvTG9jYWxpemVkUGF0dGVybihVbmljb2RlU3RyaW5nJiByZXN1bHQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBVRXJyb3JDb2RlJiBzdGF0dXMpIGNvbnN0OwoKICAgIC8qKgogICAgICogQXBwbHkgdGhlIGdpdmVuIHVubG9jYWxpemVkIHBhdHRlcm4gc3RyaW5nIHRvIHRoaXMgZGF0ZSBmb3JtYXQuCiAgICAgKiAoaS5lLiwgYWZ0ZXIgdGhpcyBjYWxsLCB0aGlzIGZvcm1hdHRlciB3aWxsIGZvcm1hdCBkYXRlcyBhY2NvcmRpbmcgdG8KICAgICAqIHRoZSBuZXcgcGF0dGVybikKICAgICAqCiAgICAgKiBAcGFyYW0gcGF0dGVybiAgIFRoZSBwYXR0ZXJuIHRvIGJlIGFwcGxpZWQuCiAgICAgKiBAc3RhYmxlCiAgICAgKi8KICAgIHZpcnR1YWwgdm9pZCBhcHBseVBhdHRlcm4oY29uc3QgVW5pY29kZVN0cmluZyYgcGF0dGVybik7CgogICAgLyoqCiAgICAgKiBBcHBseSB0aGUgZ2l2ZW4gbG9jYWxpemVkIHBhdHRlcm4gc3RyaW5nIHRvIHRoaXMgZGF0ZSBmb3JtYXQuCiAgICAgKiAoc2VlIHRvTG9jYWxpemVkUGF0dGVybigpIGZvciBtb3JlIGluZm9ybWF0aW9uIG9uIGxvY2FsaXplZCBwYXR0ZXJucy4pCiAgICAgKgogICAgICogQHBhcmFtIHBhdHRlcm4gICBUaGUgbG9jYWxpemVkIHBhdHRlcm4gdG8gYmUgYXBwbGllZC4KICAgICAqIEBwYXJhbSBzdGF0dXMgICAgT3V0cHV0IHBhcmFtIHNldCB0byBzdWNjZXNzL2ZhaWx1cmUgY29kZSBvbgogICAgICogICAgICAgICAgICAgICAgICBleGl0LiBJZiB0aGUgcGF0dGVybiBpcyBpbnZhbGlkLCB0aGlzIHdpbGwgYmUKICAgICAqICAgICAgICAgICAgICAgICAgc2V0IHRvIGEgZmFpbHVyZSByZXN1bHQuCiAgICAgKiBAc3RhYmxlCiAgICAgKi8KICAgIHZpcnR1YWwgdm9pZCBhcHBseUxvY2FsaXplZFBhdHRlcm4oY29uc3QgVW5pY29kZVN0cmluZyYgcGF0dGVybiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVUVycm9yQ29kZSYgc3RhdHVzKTsKCiAgICAvKioKICAgICAqIEdldHMgdGhlIGRhdGUvdGltZSBmb3JtYXR0aW5nIHN5bWJvbHMgKHRoaXMgaXMgYW4gb2JqZWN0IGNhcnJ5aW5nCiAgICAgKiB0aGUgdmFyaW91cyBzdHJpbmdzIGFuZCBvdGhlciBzeW1ib2xzIHVzZWQgaW4gZm9ybWF0dGluZzogZS5nLiwgbW9udGgKICAgICAqIG5hbWVzIGFuZCBhYmJyZXZpYXRpb25zLCB0aW1lIHpvbmUgbmFtZXMsIEFNL1BNIHN0cmluZ3MsIGV0Yy4pCiAgICAgKiBAcmV0dXJuIGEgY29weSBvZiB0aGUgZGF0ZS10aW1lIGZvcm1hdHRpbmcgZGF0YSBhc3NvY2lhdGVkCiAgICAgKiB3aXRoIHRoaXMgZGF0ZS10aW1lIGZvcm1hdHRlci4KICAgICAqIEBzdGFibGUKICAgICAqLwogICAgdmlydHVhbCBjb25zdCBEYXRlRm9ybWF0U3ltYm9scyogZ2V0RGF0ZUZvcm1hdFN5bWJvbHModm9pZCkgY29uc3Q7CgogICAgLyoqCiAgICAgKiBTZXQgdGhlIGRhdGUvdGltZSBmb3JtYXR0aW5nIHN5bWJvbHMuICBUaGUgY2FsbGVyIG5vIGxvbmdlciBvd25zIHRoZQogICAgICogRGF0ZUZvcm1hdFN5bWJvbHMgb2JqZWN0IGFuZCBzaG91bGQgbm90IGRlbGV0ZSBpdCBhZnRlciBtYWtpbmcgdGhpcyBjYWxsLgogICAgICogQHBhcmFtIG5ld0Zvcm1hdERhdGEgdGhlIGdpdmVuIGRhdGUtdGltZSBmb3JtYXR0aW5nIGRhdGEuCiAgICAgKiBAc3RhYmxlCiAgICAgKi8KICAgIHZpcnR1YWwgdm9pZCBhZG9wdERhdGVGb3JtYXRTeW1ib2xzKERhdGVGb3JtYXRTeW1ib2xzKiBuZXdGb3JtYXRTeW1ib2xzKTsKCiAgICAvKioKICAgICAqIFNldCB0aGUgZGF0ZS90aW1lIGZvcm1hdHRpbmcgZGF0YS4KICAgICAqIEBwYXJhbSBuZXdGb3JtYXREYXRhIHRoZSBnaXZlbiBkYXRlLXRpbWUgZm9ybWF0dGluZyBkYXRhLgogICAgICogQHN0YWJsZQogICAgICovCiAgICB2aXJ0dWFsIHZvaWQgc2V0RGF0ZUZvcm1hdFN5bWJvbHMoY29uc3QgRGF0ZUZvcm1hdFN5bWJvbHMmIG5ld0Zvcm1hdFN5bWJvbHMpOwoKCnB1YmxpYzoKICAgIC8qKgogICAgICogUmVzb3VyY2UgYnVuZGxlIGZpbGUgc3VmZml4IGFuZCB0YWcgbmFtZXMgdXNlZCBieSB0aGlzIGNsYXNzLgogICAgICovCiAgICBzdGF0aWMgY29uc3QgY2hhciAqZmdFcmFzVGFnOyAgIC8vIHJlc291cmNlIGJ1bmRsZSB0YWcgZm9yIGVyYSBuYW1lcwogICAgc3RhdGljIGNvbnN0IGNoYXIgKmZnTW9udGhOYW1lc1RhZzsgLy8gcmVzb3VyY2UgYnVuZGxlIHRhZyBmb3IgbW9udGggbmFtZXMKICAgIHN0YXRpYyBjb25zdCBjaGFyICpmZ01vbnRoQWJicmV2aWF0aW9uc1RhZzsgLy8gcmVzb3VyY2UgYnVuZGxlIHRhZyBmb3IgbW9udGggYWJicmV2aWF0aW9ucwogICAgc3RhdGljIGNvbnN0IGNoYXIgKmZnRGF5TmFtZXNUYWc7ICAgLy8gcmVzb3VyY2UgYnVuZGxlIHRhZyBmb3IgZGF5IG5hbWVzCiAgICBzdGF0aWMgY29uc3QgY2hhciAqZmdEYXlBYmJyZXZpYXRpb25zVGFnOyAgIC8vIHJlc291cmNlIGJ1bmRsZSB0YWcgZm9yIGRheSBhYmJyZXZpYXRpb25zCiAgICBzdGF0aWMgY29uc3QgY2hhciAqZmdBbVBtTWFya2Vyc1RhZzsgICAgLy8gcmVzb3VyY2UgYnVuZGxlIHRhZyBmb3IgQU0vUE0gc3RyaW5ncwogICAgc3RhdGljIGNvbnN0IGNoYXIgKmZnRGF0ZVRpbWVQYXR0ZXJuc1RhZzsgICAvLyByZXNvdXJjZSBidW5kbGUgdGFnIGZvciBkZWZhdWx0IGRhdGUgYW5kIHRpbWUgcGF0dGVybnMKCiAgICBzdGF0aWMgY29uc3QgY2hhciAqZmdab25lU3RyaW5nc1RhZzsgICAgLy8gcmVzb3VyY2UgYnVuZGxlIHRhZyBmb3IgdGltZSB6b25lIG5hbWVzCiAgICBzdGF0aWMgY29uc3QgY2hhciAqZmdMb2NhbFBhdHRlcm5DaGFyc1RhZzsgIC8vIHJlc291cmNlIGJ1bmRsZSB0YWcgZm9yIGxvY2FsaXplZCBwYXR0ZXJuIGNoYXJhY3RlcnMKCiAgICBzdGF0aWMgY29uc3QgVW5pY29kZVN0cmluZyAgICAgIGZnRGVmYXVsdFBhdHRlcm47ICAgIC8vIGRhdGUvdGltZSBwYXR0ZXJuIG9mIGxhc3QgcmVzb3J0CgpwdWJsaWM6CiAgICAvKioKICAgICAqIFJldHVybiB0aGUgY2xhc3MgSUQgZm9yIHRoaXMgY2xhc3MuIFRoaXMgaXMgdXNlZnVsIG9ubHkgZm9yIGNvbXBhcmluZyB0bwogICAgICogYSByZXR1cm4gdmFsdWUgZnJvbSBnZXREeW5hbWljQ2xhc3NJRCgpLiBGb3IgZXhhbXBsZToKICAgICAqIDxwcmU+CiAgICAgKiAuICAgQmFzZSogcG9seW1vcnBoaWNfcG9pbnRlciA9IGNyZWF0ZVBvbHltb3JwaGljT2JqZWN0KCk7CiAgICAgKiAuICAgaWYgKHBvbHltb3JwaGljX3BvaW50ZXItPmdldER5bmFtaWNDbGFzc0lEKCkgPT0KICAgICAqIC4gICAgICAgZXJpdmVkOjpnZXRTdGF0aWNDbGFzc0lEKCkpIC4uLgogICAgICogPC9wcmU+CiAgICAgKiBAcmV0dXJuICAgICAgICAgIFRoZSBjbGFzcyBJRCBmb3IgYWxsIG9iamVjdHMgb2YgdGhpcyBjbGFzcy4KICAgICAqIEBzdGFibGUKICAgICAqLwogICAgc3RhdGljIFVDbGFzc0lEIGdldFN0YXRpY0NsYXNzSUQodm9pZCkgeyByZXR1cm4gKFVDbGFzc0lEKSZmZ0NsYXNzSUQ7IH0KCiAgICAvKioKICAgICAqIFJldHVybnMgYSB1bmlxdWUgY2xhc3MgSUQgUE9MWU1PUlBISUNBTExZLiBQdXJlIHZpcnR1YWwgb3ZlcnJpZGUuIFRoaXMKICAgICAqIG1ldGhvZCBpcyB0byBpbXBsZW1lbnQgYSBzaW1wbGUgdmVyc2lvbiBvZiBSVFRJLCBzaW5jZSBub3QgYWxsIEMrKwogICAgICogY29tcGlsZXJzIHN1cHBvcnQgZ2VudWluZSBSVFRJLiBQb2x5bW9ycGhpYyBvcGVyYXRvcj09KCkgYW5kIGNsb25lKCkKICAgICAqIG1ldGhvZHMgY2FsbCB0aGlzIG1ldGhvZC4KICAgICAqCiAgICAgKiBAcmV0dXJuICAgICAgICAgIFRoZSBjbGFzcyBJRCBmb3IgdGhpcyBvYmplY3QuIEFsbCBvYmplY3RzIG9mIGEKICAgICAqICAgICAgICAgICAgICAgICAgZ2l2ZW4gY2xhc3MgaGF2ZSB0aGUgc2FtZSBjbGFzcyBJRC4gIE9iamVjdHMgb2YKICAgICAqICAgICAgICAgICAgICAgICAgb3RoZXIgY2xhc3NlcyBoYXZlIGRpZmZlcmVudCBjbGFzcyBJRHMuCiAgICAgKiBAc3RhYmxlCiAgICAgKi8KICAgIHZpcnR1YWwgVUNsYXNzSUQgZ2V0RHluYW1pY0NsYXNzSUQodm9pZCkgY29uc3QgeyByZXR1cm4gZ2V0U3RhdGljQ2xhc3NJRCgpOyB9Cgpwcml2YXRlOgogICAgc3RhdGljIGNoYXIgZmdDbGFzc0lEOwoKICAgIGZyaWVuZCBjbGFzcyBEYXRlRm9ybWF0OwoKICAgIC8qKgogICAgICogR2V0cyB0aGUgaW5kZXggZm9yIHRoZSBnaXZlbiB0aW1lIHpvbmUgSUQgdG8gb2J0YWluIHRoZSB0aW1lem9uZSBzdHJpbmdzCiAgICAgKiBmb3IgZm9ybWF0dGluZy4gVGhlIHRpbWUgem9uZSBJRCBpcyBqdXN0IGZvciBwcm9ncmFtbWF0aWMgbG9va3VwLiBOT1QKICAgICAqIExPQ0FMSVpFRCEhIQogICAgICoKICAgICAqIEBwYXJhbSBEYXRlRm9ybWF0U3ltYm9scyAgICAgYSBEYXRlRm9ybWF0U3ltYm9scyBvYmplY3QgY29udGlhbmluZyB0aGUgdGltZSB6b25lIG5hbWVzCiAgICAgKiBAcGFyYW0gSUQgICAgICAgIHRoZSBnaXZlbiB0aW1lIHpvbmUgSUQuCiAgICAgKiBAcmV0dXJuICAgICAgICAgIHRoZSBpbmRleCBvZiB0aGUgZ2l2ZW4gdGltZSB6b25lIElELiAgUmV0dXJucyAtMSBpZgogICAgICogICAgICAgICAgICAgICAgICB0aGUgZ2l2ZW4gdGltZSB6b25lIElEIGNhbid0IGJlIGxvY2F0ZWQgaW4gdGhlCiAgICAgKiAgICAgICAgICAgICAgICAgIERhdGVGb3JtYXRTeW1ib2xzIG9iamVjdC4KICAgICAqIEBzZWUgU2ltcGxlVGltZVpvbmUKICAgICAqLwogICAgLy9pbnQzMl90IGdldFpvbmVJbmRleChjb25zdCBEYXRlRm9ybWF0U3ltYm9scyYsIGNvbnN0IFVuaWNvZGVTdHJpbmcmIElEKSBjb25zdDsKCiAgICB2b2lkIGluaXRpYWxpemVEZWZhdWx0Q2VudHVyeSh2b2lkKTsKCiAgICAvKioKICAgICAqIFVzZWQgYnkgdGhlIERhdGVGb3JtYXQgZmFjdG9yeSBtZXRob2RzIHRvIGNvbnN0cnVjdCBhIFNpbXBsZURhdGVGb3JtYXQuCiAgICAgKi8KICAgIFNpbXBsZURhdGVGb3JtYXQoRVN0eWxlIHRpbWVTdHlsZSwgRVN0eWxlIGRhdGVTdHlsZSwgY29uc3QgTG9jYWxlJiBsb2NhbGUsIFVFcnJvckNvZGUmIHN0YXR1cyk7CgogICAgLyoqCiAgICAgKiBDb25zdHJ1Y3QgYSBTaW1wbGVEYXRlRm9ybWF0IGZvciB0aGUgZ2l2ZW4gbG9jYWxlLiAgSWYgbm8gcmVzb3VyY2UgZGF0YQogICAgICogaXMgYXZhaWxhYmxlLCBjcmVhdGUgYW4gb2JqZWN0IG9mIGxhc3QgcmVzb3J0LCB1c2luZyBoYXJkLWNvZGVkIHN0cmluZ3MuCiAgICAgKiBUaGlzIGlzIGFuIGludGVybmFsIG1ldGhvZCwgY2FsbGVkIGJ5IERhdGVGb3JtYXQuICBJdCBzaG91bGQgbmV2ZXIgZmFpbC4KICAgICAqLwogICAgU2ltcGxlRGF0ZUZvcm1hdChjb25zdCBMb2NhbGUmIGxvY2FsZSwgVUVycm9yQ29kZSYgc3RhdHVzKTsgLy8gVXNlIGRlZmF1bHQgcGF0dGVybgoKICAgIC8qKgogICAgICogQ2FsbGVkIGJ5IGZvcm1hdCgpIHRvIGZvcm1hdCBhIHNpbmdsZSBmaWVsZC4KICAgICAqCiAgICAgKiBAcGFyYW0gcmVzdWx0ICAgIEZpbGxlZCBpbiB3aXRoIHRoZSByZXN1bHQuCiAgICAgKiBAcGFyYW0gY2ggICAgICAgIFRoZSBmb3JtYXQgY2hhcmFjdGVyIHdlIGVuY291bnRlcmVkIGluIHRoZSBwYXR0ZXJuLgogICAgICogQHBhcmFtIGNvdW50ICAgICBOdW1iZXIgb2YgY2hhcmFjdGVycyBpbiB0aGUgY3VycmVudCBwYXR0ZXJuIHN5bWJvbCAoZS5nLiwKICAgICAqICAgICAgICAgICAgICAgICAgInl5eXkiIGluIHRoZSBwYXR0ZXJuIHdvdWxkIHJlc3VsdCBpbiBhIGNhbGwgdG8gdGhpcyBmdW5jdGlvbgogICAgICogICAgICAgICAgICAgICAgICB3aXRoIGNoIGVxdWFsIHRvICd5JyBhbmQgY291bnQgZXF1YWwgdG8gNCkKICAgICAqIEBwYXJhbSBiZWdpbk9mZnNldCAgIFRlbGxzIHdoZXJlIHRoZSB0ZXh0IHJldHVybmVkIGJ5IHRoaXMgZnVuY3Rpb24gd2lsbCBnbyBpbgogICAgICogICAgICAgICAgICAgICAgICB0aGUgZmluaXNoZWQgc3RyaW5nLiAgVXNlZCB3aGVuIHRoaXMgZnVuY3Rpb24gbmVlZHMgdG8gZmlsbAogICAgICogICAgICAgICAgICAgICAgICBpbiBhIEZpZWxkUG9zaXRpb24KICAgICAqIEBwYXJhbSBwb3MgICAgICAgVGhlIEZpZWxkUG9zaXRpb24gYmVpbmcgZmlsbGVkIGluIGJ5IHRoZSBmb3JtYXQoKSBjYWxsLiAgSWYKICAgICAqICAgICAgICAgICAgICAgICAgdGhpcyBmdW5jdGlvbiBpcyBmb3JtYXR0aW5nIHRoZSBmaWVsZCBzcGVjZmllZCBieSBwb3MsIGl0CiAgICAgKiAgICAgICAgICAgICAgICAgIHdpbGwgZmlsbCBpbiBwb3Mgd2lsbCB0aGUgYmVnaW5uaW5nIGFuZCBlbmRpbmcgb2Zmc2V0cyBvZiB0aGUKICAgICAqICAgICAgICAgICAgICAgICAgZmllbGQuCiAgICAgKiBAcGFyYW0gc3RhdHVzICAgIFJlY2VpdmVzIGEgc3RhdHVzIGNvZGUsIHdoaWNoIHdpbGwgYmUgVV9aRVJPX0VSUk9SIGlmIHRoZSBvcGVyYXRpb24KICAgICAqICAgICAgICAgICAgICAgICAgc3VjY2VlZHMuCiAgICAgKiBAcmV0dXJuIEEgcmVmZXJlbmNlIHRvICJyZXN1bHQiLgogICAgICogQGRyYWZ0CiAgICAgKi8KICAgIFVuaWNvZGVTdHJpbmcmIHN1YkZvcm1hdCggICBVbmljb2RlU3RyaW5nJiByZXN1bHQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVUNoYXIgY2gsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50MzJfdCBjb3VudCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQzMl90IGJlZ2luT2Zmc2V0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEZpZWxkUG9zaXRpb24mIHBvcywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBVRXJyb3JDb2RlJiBzdGF0dXMpIGNvbnN0OyAvLyBpbiBjYXNlIG9mIGlsbGVnYWwgYXJndW1lbnQKCiAgICAvKioKICAgICAqIFVzZWQgYnkgc3ViRm9ybWF0KCkgdG8gZm9ybWF0IGEgbnVtZXJpYyB2YWx1ZS4gIEZpbGxzIGluICJyZXN1bHQiIHdpdGggYSBzdHJpbmcKICAgICAqIHJlcHJlc2VudGF0aW9uIG9mICJ2YWx1ZSIgaGF2aW5nIGEgbnVtYmVyIG9mIGRpZ2l0cyBiZXR3ZWVuICJtaW5EaWdpdHMiIGFuZAogICAgICogIm1heERpZ2l0cyIuICBVc2VzIHRoZSBEYXRlRm9ybWF0J3MgTnVtYmVyRm9ybWF0LgogICAgICogQHBhcmFtIHJlc3VsdCAgICBGaWxsZWQgaW4gd2l0aCB0aGUgZm9ybWF0dGVkIG51bWJlci4KICAgICAqIEBwYXJhbSB2YWx1ZSAgICAgVmFsdWUgdG8gZm9ybWF0LgogICAgICogQHBhcmFtIG1pbkRpZ2l0cyBNaW5pbXVtIG51bWJlciBvZiBkaWdpdHMgdGhlIHJlc3VsdCBzaG91bGQgaGF2ZQogICAgICogQHBhcmFtIG1heERpZ2l0cyBNYXhpbXVtIG51bWJlciBvZiBkaWdpdHMgdGhlIHJlc3VsdCBzaG91bGQgaGF2ZQogICAgICogQHJldHVybiBBIHJlZmVyZW5jZSB0byAicmVzdWx0Ii4KICAgICAqLwogICAgVW5pY29kZVN0cmluZyYgemVyb1BhZGRpbmdOdW1iZXIoVW5pY29kZVN0cmluZyYgcmVzdWx0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50MzJfdCB2YWx1ZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludDMyX3QgbWluRGlnaXRzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50MzJfdCBtYXhEaWdpdHMpIGNvbnN0OwoKICAgIC8qKgogICAgICogQ2FsbGVkIGJ5IHNldmVyYWwgb2YgdGhlIGNvbnN0cnVjdG9ycyB0byBsb2FkIHBhdHRlcm4gZGF0YSBhbmQgZm9ybWF0dGluZyBzeW1ib2xzCiAgICAgKiBvdXQgb2YgYSByZXNvdXJjZSBidW5kbGUgYW5kIGluaXRpYWxpemUgdGhlIGxvY2FsZSBiYXNlZCBvbiBpdC4KICAgICAqIEBwYXJhbSB0aW1lU3R5bGUgICAgIFRoZSB0aW1lIHN0eWxlLCBhcyBwYXNzZWQgdG8gRGF0ZUZvcm1hdDo6Y3JlYXRlRGF0ZUluc3RhbmNlKCkuCiAgICAgKiBAcGFyYW0gZGF0ZVN0eWxlICAgICBUaGUgZGF0ZSBzdHlsZSwgYXMgcGFzc2VkIHRvIERhdGVGb3JtYXQ6OmNyZWF0ZVRpbWVJbnN0YW5jZSgpLgogICAgICogQHBhcmFtIGxvY2FsZSAgICAgICAgVGhlIGxvY2FsZSB0byBsb2FkIHRoZSBwYXR0ZXJucyBmcm9tLgogICAgICogQHBhcmFtIHN0YXR1cyAgICAgICAgRmlsbGVkIGluIHdpdGggYW4gZXJyb3IgY29kZSBpZiBsb2FkaW5nIHRoZSBkYXRhIGZyb20gdGhlCiAgICAgKiAgICAgICAgICAgICAgICAgICAgICByZXNvdXJjZXMgZmFpbHMuCiAgICAgKi8KICAgIHZvaWQgY29uc3RydWN0KEVTdHlsZSB0aW1lU3R5bGUsIEVTdHlsZSBkYXRlU3R5bGUsIGNvbnN0IExvY2FsZSYgbG9jYWxlLCBVRXJyb3JDb2RlJiBzdGF0dXMpOwoKICAgIC8qKgogICAgICogQ2FsbGVkIGJ5IGNvbnN0cnVjdCgpIGFuZCB0aGUgdmFyaW91cyBjb25zdHJ1Y3RvcnMgdG8gc2V0IHVwIHRoZSBTaW1wbGVEYXRlRm9ybWF0J3MKICAgICAqIENhbGVuZGFyIGFuZCBOdW1iZXJGb3JtYXQgb2JqZWN0cy4KICAgICAqIEBwYXJhbSBsb2NhbGUgICAgVGhlIGxvY2FsZSBmb3Igd2hpY2ggd2Ugd2FudCBhIENhbGVuZGFyIGFuZCBhIE51bWJlckZvcm1hdC4KICAgICAqIEBwYXJhbSBzdGF0dWMgICAgRmlsbGVkIGluIHdpdGggYW4gZXJyb3IgY29kZSBpZiBjcmVhdGluZyBlaXRoZXIgc3Vib2JqZWN0IGZhaWxzLgogICAgICovCiAgICB2b2lkIGluaXRpYWxpemUoY29uc3QgTG9jYWxlJiBsb2NhbGUsIFVFcnJvckNvZGUmIHN0YXR1cyk7CgogICAgLyoqCiAgICAgKiBQcml2YXRlIGNvZGUtc2l6ZSByZWR1Y3Rpb24gZnVuY3Rpb24gdXNlZCBieSBzdWJQYXJzZS4KICAgICAqIEBwYXJhbSB0ZXh0IHRoZSB0aW1lIHRleHQgYmVpbmcgcGFyc2VkLgogICAgICogQHBhcmFtIHN0YXJ0IHdoZXJlIHRvIHN0YXJ0IHBhcnNpbmcuCiAgICAgKiBAcGFyYW0gZmllbGQgdGhlIGRhdGUgZmllbGQgYmVpbmcgcGFyc2VkLgogICAgICogQHBhcmFtIGRhdGEgdGhlIHN0cmluZyBhcnJheSB0byBwYXJzZWQuCiAgICAgKiBAcmV0dXJuIHRoZSBuZXcgc3RhcnQgcG9zaXRpb24gaWYgbWF0Y2hpbmcgc3VjY2VlZGVkOyBhIG5lZ2F0aXZlIG51bWJlcgogICAgICogaW5kaWNhdGluZyBtYXRjaGluZyBmYWlsdXJlLCBvdGhlcndpc2UuCiAgICAgKi8KICAgIGludDMyX3QgbWF0Y2hTdHJpbmcoY29uc3QgVW5pY29kZVN0cmluZyYgdGV4dCwgVVRleHRPZmZzZXQgc3RhcnQsIENhbGVuZGFyOjpFRGF0ZUZpZWxkcyBmaWVsZCwKICAgICAgICAgICAgICAgICAgICBjb25zdCBVbmljb2RlU3RyaW5nKiBzdHJpbmdBcnJheSwgaW50MzJfdCBzdHJpbmdBcnJheUNvdW50KSBjb25zdDsKCiAgICAvKioKICAgICAqIFByaXZhdGUgbWVtYmVyIGZ1bmN0aW9uIHRoYXQgY29udmVydHMgdGhlIHBhcnNlZCBkYXRlIHN0cmluZ3MgaW50bwogICAgICogdGltZUZpZWxkcy4gUmV0dXJucyAtc3RhcnQgKGZvciBQYXJzZVBvc2l0aW9uKSBpZiBmYWlsZWQuCiAgICAgKiBAcGFyYW0gdGV4dCB0aGUgdGltZSB0ZXh0IHRvIGJlIHBhcnNlZC4KICAgICAqIEBwYXJhbSBzdGFydCB3aGVyZSB0byBzdGFydCBwYXJzaW5nLgogICAgICogQHBhcmFtIGNoIHRoZSBwYXR0ZXJuIGNoYXJhY3RlciBmb3IgdGhlIGRhdGUgZmllbGQgdGV4dCB0byBiZSBwYXJzZWQuCiAgICAgKiBAcGFyYW0gY291bnQgdGhlIGNvdW50IG9mIGEgcGF0dGVybiBjaGFyYWN0ZXIuCiAgICAgKiBAcGFyYW0gb2JleUNvdW50IGlmIHRydWUgdGhlbiB0aGUgY291bnQgaXMgc3RyaWN0bHkgb2JleWVkLgogICAgICogQHJldHVybiB0aGUgbmV3IHN0YXJ0IHBvc2l0aW9uIGlmIG1hdGNoaW5nIHN1Y2NlZWRlZDsgYSBuZWdhdGl2ZSBudW1iZXIKICAgICAqIGluZGljYXRpbmcgbWF0Y2hpbmcgZmFpbHVyZSwgb3RoZXJ3aXNlLgogICAgICogQGRyYWZ0CiAgICAgKi8KICAgIGludDMyX3Qgc3ViUGFyc2UoY29uc3QgVW5pY29kZVN0cmluZyYgdGV4dCwgaW50MzJfdCYgc3RhcnQsIFVDaGFyIGNoLCBpbnQzMl90IGNvdW50LAogICAgICAgICAgICAgICAgIFVCb29sIG9iZXlDb3VudCwgVUJvb2wgYW1iaWd1b3VzWWVhcltdKSBjb25zdDsKCiAgICAvKioKICAgICAqIFBhcnNlIHRoZSBnaXZlbiB0ZXh0LCBhdCB0aGUgZ2l2ZW4gcG9zaXRpb24sIGFzIGEgbnVtZXJpYyB2YWx1ZSwgdXNpbmcKICAgICAqIHRoaXMgb2JqZWN0J3MgTnVtYmVyRm9ybWF0LiBSZXR1cm4gdGhlIGNvcnJlc3BvbmRpbmcgbG9uZyB2YWx1ZSBpbiB0aGUKICAgICAqIGZpbGwtaW4gcGFyYW1ldGVyICd2YWx1ZScuIElmIHRoZSBwYXJzZSBmYWlscywgdGhpcyBtZXRob2QgbGVhdmVzIHBvcwogICAgICogdW5jaGFuZ2VkIGFuZCByZXR1cm5zIEZBTFNFOyBvdGhlcndpc2UgaXQgYWR2YW5jZXMgcG9zIGFuZAogICAgICogcmV0dXJucyBUUlVFLgogICAgICovCiAgICAvL1VCb29sIHN1YlBhcnNlTG9uZyhjb25zdCBVbmljb2RlU3RyaW5nJiB0ZXh0LCBQYXJzZVBvc2l0aW9uJiBwb3MsIGludDMyX3QmIHZhbHVlKSBjb25zdDsKCiAgICAvKioKICAgICAqIFRyYW5zbGF0ZSBhIHBhdHRlcm4sIG1hcHBpbmcgZWFjaCBjaGFyYWN0ZXIgaW4gdGhlIGZyb20gc3RyaW5nIHRvIHRoZQogICAgICogY29ycmVzcG9uZGluZyBjaGFyYWN0ZXIgaW4gdGhlIHRvIHN0cmluZy4gUmV0dXJuIGFuIGVycm9yIGlmIHRoZSBvcmlnaW5hbAogICAgICogcGF0dGVybiBjb250YWlucyBhbiB1bm1hcHBlZCBjaGFyYWN0ZXIsIG9yIGlmIGEgcXVvdGUgaXMgdW5tYXRjaGVkLgogICAgICogUXVvdGVkIChzaW5nbGUgcXVvdGVzIG9ubHkpIG1hdGVyaWFsIGlzIG5vdCB0cmFuc2xhdGVkLgogICAgICovCiAgICBzdGF0aWMgdm9pZCB0cmFuc2xhdGVQYXR0ZXJuKGNvbnN0IFVuaWNvZGVTdHJpbmcmIG9yaWdpbmFsUGF0dGVybiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBVbmljb2RlU3RyaW5nJiB0cmFuc2xhdGVkUGF0dGVybiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBVbmljb2RlU3RyaW5nJiBmcm9tLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IFVuaWNvZGVTdHJpbmcmIHRvLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFVFcnJvckNvZGUmIHN0YXR1cyk7CiAgICAvKioKICAgICAqIEdpdmVuIGEgem9uZSBJRCwgdHJ5IHRvIGxvY2F0ZSBpdCBpbiBvdXIgdGltZSB6b25lIGFycmF5LiBSZXR1cm4gdGhlCiAgICAgKiBpbmRleCAocm93IGluZGV4KSBvZiB0aGUgZm91bmQgdGltZSB6b25lLCBvciAtMSBpZiB3ZSBjYW4ndCBmaW5kIGl0LgogICAgICovCiAgICAvL2ludDMyX3QgZ2V0Wm9uZUluZGV4KGNvbnN0IFVuaWNvZGVTdHJpbmcmIElEKSBjb25zdDsKCiAgICAvKioKICAgICAqIFNldHMgdGhlIHN0YXJ0aW5nIGRhdGUgb2YgdGhlIDEwMC15ZWFyIHdpbmRvdyB0aGF0IGRhdGVzIHdpdGggMi1kaWdpdCB5ZWFycwogICAgICogYXJlIGNvbnNpZGVyZWQgdG8gZmFsbCB3aXRoaW4uCiAgICAgKi8KICAgIHZvaWQgICAgICAgICBwYXJzZUFtYmlndW91c0RhdGVzQXNBZnRlcihVRGF0ZSBzdGFydERhdGUsIFVFcnJvckNvZGUmIHN0YXR1cyk7CgogICAgLyoqCiAgICAgKiBSZXR1cm5zIHRoZSBiZWdpbm5pbmcgZGF0ZSBvZiB0aGUgMTAwLXllYXIgd2luZG93IHRoYXQgZGF0ZXMgd2l0aCAyLWRpZ2l0IHllYXJzCiAgICAgKiBhcmUgY29uc2lkZXJlZCB0byBmYWxsIHdpdGhpbi4KICAgICAqLwogICAgVURhdGUgICAgICAgICBpbnRlcm5hbEdldERlZmF1bHRDZW50dXJ5U3RhcnQodm9pZCkgY29uc3Q7CgogICAgLyoqCiAgICAgKiBSZXR1cm5zIHRoZSBmaXJzdCB5ZWFyIG9mIHRoZSAxMDAteWVhciB3aW5kb3cgdGhhdCBkYXRlcyB3aXRoIDItZGlnaXQgeWVhcnMKICAgICAqIGFyZSBjb25zaWRlcmVkIHRvIGZhbGwgd2l0aGluLgogICAgICovCiAgICBpbnQzMl90ICAgICAgICAgIGludGVybmFsR2V0RGVmYXVsdENlbnR1cnlTdGFydFllYXIodm9pZCkgY29uc3Q7CgogICAgLyoqCiAgICAgKiBJbml0aWFsaXplcyB0aGUgMTAwLXllYXIgd2luZG93IHRoYXQgZGF0ZXMgd2l0aCAyLWRpZ2l0IHllYXJzIGFyZSBjb25zaWRlcmVkCiAgICAgKiB0byBmYWxsIHdpdGhpbiBzbyB0aGF0IGl0cyBzdGFydCBkYXRlIGlzIDgwIHllYXJzIGJlZm9yZSB0aGUgY3VycmVudCB0aW1lLgogICAgICovCiAgICBzdGF0aWMgdm9pZCAgaW5pdGlhbGl6ZVN5c3RlbURlZmF1bHRDZW50dXJ5KHZvaWQpOwoKICAgIC8qKgogICAgICogTGFzdC1yZXNvcnQgc3RyaW5nIHRvIHVzZSBmb3IgIkdNVCIgd2hlbiBjb25zdHJ1Y3RpbmcgdGltZSB6b25lIHN0cmluZ3MuCiAgICAgKi8KICAgIC8vIEZvciB0aW1lIHpvbmVzIHRoYXQgaGF2ZSBubyBuYW1lcywgdXNlIHN0cmluZ3MgR01UK21pbnV0ZXMgYW5kCiAgICAvLyBHTVQtbWludXRlcy4gRm9yIGluc3RhbmNlLCBpbiBGcmFuY2UgdGhlIHRpbWUgem9uZSBpcyBHTVQrNjAuCiAgICBzdGF0aWMgY29uc3QgVW5pY29kZVN0cmluZyBmZ0dtdFBsdXM7CiAgICBzdGF0aWMgY29uc3QgVW5pY29kZVN0cmluZyBmZ0dtdE1pbnVzOwogICAgc3RhdGljIGNvbnN0IFVuaWNvZGVTdHJpbmcgZmdHbXQ7CgogICAgLyoqCiAgICAgKiBVc2VkIHRvIG1hcCBwYXR0ZXJuIGNoYXJhY3RlcnMgdG8gQ2FsZW5kYXIgZmllbGQgaWRlbnRpZmllcnMuCiAgICAgKi8KICAgIHN0YXRpYyBjb25zdCBDYWxlbmRhcjo6RURhdGVGaWVsZHMgZmdQYXR0ZXJuSW5kZXhUb0NhbGVuZGFyRmllbGRbXTsKCiAgICAvKioKICAgICAqIE1hcCBpbmRleCBpbnRvIHBhdHRlcm4gY2hhcmFjdGVyIHN0cmluZyB0byBEYXRlRm9ybWF0IGZpZWxkIG51bWJlcgogICAgICovCiAgICBzdGF0aWMgY29uc3QgRGF0ZUZvcm1hdDo6RUZpZWxkIGZnUGF0dGVybkluZGV4VG9EYXRlRm9ybWF0RmllbGRbXTsKCiAgICAvKioKICAgICAqIFRoZSBmb3JtYXR0aW5nIHBhdHRlcm4gZm9yIHRoaXMgZm9ybWF0dGVyLgogICAgICovCiAgICBVbmljb2RlU3RyaW5nICAgICAgIGZQYXR0ZXJuOwoKICAgIC8qKgogICAgICogQSBwb2ludGVyIHRvIGFuIG9iamVjdCBjb250YWluaW5nIHRoZSBzdHJpbmdzIHRvIHVzZSBpbiBmb3JtYXR0aW5nIChlLmcuLAogICAgICogbW9udGggYW5kIGRheSBuYW1lcywgQU0gYW5kIFBNIHN0cmluZ3MsIHRpbWUgem9uZSBuYW1lcywgZXRjLikKICAgICAqLwogICAgRGF0ZUZvcm1hdFN5bWJvbHMqICBmU3ltYm9sczsgICAvLyBPd25lZAoKICAgIC8qKgogICAgICogSWYgZGF0ZXMgaGF2ZSBhbWJpZ3VvdXMgeWVhcnMsIHdlIG1hcCB0aGVtIGludG8gdGhlIGNlbnR1cnkgc3RhcnRpbmcKICAgICAqIGF0IGRlZmF1bHRDZW50dXJ5U3RhcnQsIHdoaWNoIG1heSBiZSBhbnkgZGF0ZS4gIElmIGRlZmF1bHRDZW50dXJ5U3RhcnQgaXMKICAgICAqIHNldCB0byBTWVNURU1fREVGQVVMVF9DRU5UVVJZLCB3aGljaCBpdCBpcyBieSBkZWZhdWx0LCB0aGVuIHRoZSBzeXN0ZW0KICAgICAqIHZhbHVlcyBhcmUgdXNlZC4gIFRoZSBpbnN0YW5jZSB2YWx1ZXMgZGVmYXVsdENlbnR1cnlTdGFydCBhbmQKICAgICAqIGRlZmF1bHRDZW50dXJ5U3RhcnRZZWFyIGFyZSBvbmx5IHVzZWQgaWYgZXhwbGljaXRseSBzZXQgYnkgdGhlIHVzZXIKICAgICAqIHRocm91Z2ggdGhlIEFQSSBtZXRob2QgcGFyc2VBbWJpZ3VvdXNEYXRlc0FzQWZ0ZXIoKS4KICAgICAqLwogICAgVURhdGUgICAgICAgICAgICAgICAgZkRlZmF1bHRDZW50dXJ5U3RhcnQ7CgogICAgLyoqCiAgICAgKiBTZWUgZG9jdW1lbnRhdGlvbiBmb3IgZGVmYXVsdENlbnR1cnlTdGFydC4KICAgICAqLwogICAgLyp0cmFuc2llbnQqLyBpbnQzMl90ICAgZkRlZmF1bHRDZW50dXJ5U3RhcnRZZWFyOwoKICAgIC8qKgogICAgICogVGhlIHN5c3RlbSBtYWludGFpbnMgYSBzdGF0aWMgZGVmYXVsdCBjZW50dXJ5IHN0YXJ0IGRhdGUuICBUaGlzIGlzIGluaXRpYWxpemVkCiAgICAgKiB0aGUgZmlyc3QgdGltZSBpdCBpcyB1c2VkLiAgQmVmb3JlIHRoZW4sIGl0IGlzIHNldCB0byBTWVNURU1fREVGQVVMVF9DRU5UVVJZIHRvCiAgICAgKiBpbmRpY2F0ZSBhbiB1bmluaXRpYWxpemVkIHN0YXRlLiAgT25jZSB0aGUgc3lzdGVtIGRlZmF1bHQgY2VudHVyeSBkYXRlIGFuZCB5ZWFyCiAgICAgKiBhcmUgc2V0LCB0aGV5IGRvIG5vdCBjaGFuZ2UuCiAgICAgKi8KICAgIHN0YXRpYyBVRGF0ZSAgICAgICAgIGZnU3lzdGVtRGVmYXVsdENlbnR1cnlTdGFydDsKCiAgICAvKioKICAgICAqIFNlZSBkb2N1bWVudGF0aW9uIGZvciBzeXN0ZW1EZWZhdWx0Q2VudHVyeVN0YXJ0LgogICAgICovCiAgICBzdGF0aWMgaW50MzJfdCAgICAgICAgICBmZ1N5c3RlbURlZmF1bHRDZW50dXJ5U3RhcnRZZWFyOwoKICAgIC8qKgogICAgICogRGVmYXVsdCB2YWx1ZSB0aGF0IGluZGljYXRlcyB0aGUgZGVmYXVsdENlbnR1cnlTdGFydFllYXIgaXMgdW5pdGlhbGl6ZWQKICAgICAqLwogICAgc3RhdGljIGNvbnN0IGludDMyX3QgICAgZmdTeXN0ZW1EZWZhdWx0Q2VudHVyeVllYXI7CgpwdWJsaWM6CiAgICAvKioKICAgICAqIElmIGEgc3RhcnQgZGF0ZSBpcyBzZXQgdG8gdGhpcyB2YWx1ZSwgdGhhdCBpbmRpY2F0ZXMgdGhhdCB0aGUgc3lzdGVtIGRlZmF1bHQKICAgICAqIHN0YXJ0IGlzIGluIGVmZmVjdCBmb3IgdGhpcyBpbnN0YW5jZS4KICAgICAqLwogICAgc3RhdGljIGNvbnN0IFVEYXRlICAgICAgICBmZ1N5c3RlbURlZmF1bHRDZW50dXJ5Owp9OwoKaW5saW5lIFVEYXRlClNpbXBsZURhdGVGb3JtYXQ6OmdldDJEaWdpdFllYXJTdGFydChVRXJyb3JDb2RlJiBzdGF0dXMpIGNvbnN0CnsKICAgIHJldHVybiBmRGVmYXVsdENlbnR1cnlTdGFydDsKfQoKaW5saW5lIFVuaWNvZGVTdHJpbmcmClNpbXBsZURhdGVGb3JtYXQ6OmZvcm1hdChjb25zdCBGb3JtYXR0YWJsZSYgb2JqLAogICAgICAgICAgICAgICAgICAgICAgICAgVW5pY29kZVN0cmluZyYgcmVzdWx0LAogICAgICAgICAgICAgICAgICAgICAgICAgVUVycm9yQ29kZSYgc3RhdHVzKSBjb25zdCB7CiAgICAvLyBEb24ndCB1c2UgRm9ybWF0OjogLSB1c2UgaW1tZWRpYXRlIGJhc2UgY2xhc3Mgb25seSwKICAgIC8vIGluIGNhc2UgaW1tZWRpYXRlIGJhc2UgbW9kaWZpZXMgYmVoYXZpb3IgbGF0ZXIuCiAgICByZXR1cm4gRGF0ZUZvcm1hdDo6Zm9ybWF0KG9iaiwgcmVzdWx0LCBzdGF0dXMpOwp9CgppbmxpbmUgVW5pY29kZVN0cmluZyYKU2ltcGxlRGF0ZUZvcm1hdDo6Zm9ybWF0KFVEYXRlIGRhdGUsIFVuaWNvZGVTdHJpbmcmIHJlc3VsdCkgY29uc3QgewogICAgcmV0dXJuIERhdGVGb3JtYXQ6OmZvcm1hdChkYXRlLCByZXN1bHQpOwp9CgojZW5kaWYgLy8gX1NNUERURk1UCi8vZW9mCg==