LyoKKiBDb3B5cmlnaHQgqSB7MTk5Ny0xOTk5fSwgSW50ZXJuYXRpb25hbCBCdXNpbmVzcyBNYWNoaW5lcyBDb3Jwb3JhdGlvbiBhbmQgb3RoZXJzLiBBbGwgUmlnaHRzIFJlc2VydmVkLgoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCioKKiBGaWxlIFNNUERURk1ULkgKKgoqIE1vZGlmaWNhdGlvbiBIaXN0b3J5OgoqCiogICBEYXRlICAgICAgICBOYW1lICAgICAgICBEZXNjcmlwdGlvbgoqICAgMDIvMTkvOTcgICAgYWxpdSAgICAgICAgQ29udmVydGVkIGZyb20gamF2YS4KKiAgIDA3LzA5Lzk3ICAgIGhlbGVuYSAgICAgIE1ha2UgUGFyc2VQb3NpdGlvbiBpbnRvIGEgY2xhc3MuCiogICAwNy8yMS85OCAgICBzdGVwaGVuICAgICBBZGRlZCBHTVRfUExVUywgR01UX01JTlVTCiogICAgICAgICAgICAgICAgICAgICAgICAgICAgQ2hhbmdlZCBzZXRUd29EaWdpdFN0YXJ0RGF0ZSB0byBzZXQyRGlnaXRZZWFyU3RhcnQKKiAgICAgICAgICAgICAgICAgICAgICAgICAgICBDaGFuZ2VkIGdldFR3b0RpZ2l0U3RhcnREYXRlIHRvIGdldDJEaWdpdFllYXJTdGFydAoqICAgICAgICAgICAgICAgICAgICAgICAgICAgIFJlbW92ZWQgc3ViUGFyc2VMb25nCiogICAgICAgICAgICAgICAgICAgICAgICAgICAgUmVtb3ZlZCBnZXRab25lSW5kZXggKGFkZGVkIGluIERhdGVGb3JtYXRTeW1ib2xzKQoqICAgMDYvMTQvOTkgICAgc3RlcGhlbiAgICAgUmVtb3ZlZCBmZ1RpbWVab25lRGF0YVN1ZmZpeAoqICAgMTAvMTQvOTkgICAgYWxpdSAgICAgICAgVXBkYXRlZCBjbGFzcyBkb2MgdG8gZGVzY3JpYmUgMi1kaWdpdCB5ZWFyIHBhcnNpbmcKKiAgICAgICAgICAgICAgICAgICAgICAgICAgIHtqMjggNDE4MjA2Nn0uCioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKKi8KCiNpZm5kZWYgU01QRFRGTVRfSAojZGVmaW5lIFNNUERURk1UX0gKCiNpbmNsdWRlICJ1bmljb2RlL3V0eXBlcy5oIgojaW5jbHVkZSAidW5pY29kZS9kYXRlZm10LmgiCmNsYXNzIERhdGVGb3JtYXRTeW1ib2xzOwpjbGFzcyBEYXRlRm9ybWF0OwoKLyoqCiAqIFNpbXBsZURhdGVGb3JtYXQgaXMgYSBjb25jcmV0ZSBjbGFzcyBmb3IgZm9ybWF0dGluZyBhbmQgcGFyc2luZyBkYXRlcyBpbiBhCiAqIGxhbmd1YWdlLWluZGVwZW5kZW50IG1hbm5lci4gSXQgYWxsb3dzIGZvciBmb3JtYXR0aW5nIChtaWxsaXMgLT4gdGV4dCksCiAqIHBhcnNpbmcgKHRleHQgLT4gbWlsbGlzKSwgYW5kIG5vcm1hbGl6YXRpb24uIEZvcm1hdHMvUGFyc2VzIGEgZGF0ZSBvciB0aW1lLAogKiB3aGljaCBpcyB0aGUgc3RhbmRhcmQgbWlsbGlzZWNvbmRzIHNpbmNlIDI0OjAwIEdNVCwgSmFuIDEsIDE5NzAuCiAqIDxQPgogKiBDbGllbnRzIGFyZSBlbmNvdXJhZ2VkIHRvIGNyZWF0ZSBhIGRhdGUtdGltZSBmb3JtYXR0ZXIgdXNpbmcgRGF0ZUZvcm1hdDo6Z2V0SW5zdGFuY2UoKSwKICogZ2V0RGF0ZUluc3RhbmNlKCksIGdldERhdGVJbnN0YW5jZSgpLCBvciBnZXREYXRlVGltZUluc3RhbmNlKCkgcmF0aGVyIHRoYW4KICogZXhwbGljaXRseSBjb25zdHJ1Y3RpbmcgYW4gaW5zdGFuY2Ugb2YgU2ltcGxlRGF0ZUZvcm1hdC4gIFRoaXMgd2F5LCB0aGUgY2xpZW50CiAqIGlzIGd1YXJhbnRlZWQgdG8gZ2V0IGFuIGFwcHJvcHJpYXRlIGZvcm1hdHRpbmcgcGF0dGVybiBmb3Igd2hhdGV2ZXIgbG9jYWxlIHRoZQogKiBwcm9ncmFtIGlzIHJ1bm5pbmcgaW4uICBIb3dldmVyLCBpZiB0aGUgY2xpZW50IG5lZWRzIHNvbWV0aGluZyBtb3JlIHVudXN1YWwgdGhhbgogKiB0aGUgZGVmYXVsdCBwYXR0ZXJucyBpbiB0aGUgbG9jYWxlcywgaGUgY2FuIGNvbnN0cnVjdCBhIFNpbXBsZURhdGVGb3JtYXQgZGlyZWN0bHkKICogYW5kIGdpdmUgaXQgYW4gYXBwcm9wcmlhdGUgcGF0dGVybiAob3IgdXNlIG9uZSBvZiB0aGUgZmFjdG9yeSBtZXRob2RzIG9uIERhdGVGb3JtYXQKICogYW5kIG1vZGlmeSB0aGUgcGF0dGVybiBhZnRlciB0aGUgZmFjdCB3aXRoIHRvUGF0dGVybigpIGFuZCBhcHBseVBhdHRlcm4oKS4KICogPFA+CiAqIERhdGUvVGltZSBmb3JtYXQgc3ludGF4OgogKiA8UD4KICogVGhlIGRhdGUvdGltZSBmb3JtYXQgaXMgc3BlY2lmaWVkIGJ5IG1lYW5zIG9mIGEgc3RyaW5nIHRpbWUgcGF0dGVybi4gSW4gdGhpcwogKiBwYXR0ZXJuLCBhbGwgQVNDSUkgbGV0dGVycyBhcmUgcmVzZXJ2ZWQgYXMgcGF0dGVybiBsZXR0ZXJzLCB3aGljaCBhcmUgZGVmaW5lZAogKiBhcyB0aGUgZm9sbG93aW5nOgogKiA8cHJlPgogKiAuICAgU3ltYm9sICAgTWVhbmluZyAgICAgICAgICAgICAgICAgUHJlc2VudGF0aW9uICAgICAgIEV4YW1wbGUKICogLiAgIC0tLS0tLSAgIC0tLS0tLS0gICAgICAgICAgICAgICAgIC0tLS0tLS0tLS0tLSAgICAgICAtLS0tLS0tCiAqIC4gICBHICAgICAgICBlcmEgZGVzaWduYXRvciAgICAgICAgICAoVGV4dCkgICAgICAgICAgICAgQUQKICogLiAgIHkgICAgICAgIHllYXIgICAgICAgICAgICAgICAgICAgIChOdW1iZXIpICAgICAgICAgICAxOTk2CiAqIC4gICBZICAgICAgICB5ZWFyL3dlZWsgb2YgeWVhciAgICAgICAoTnVtYmVyKSAgICAgICAgICAgMTk5NgogKiAuICAgTSAgICAgICAgbW9udGggaW4geWVhciAgICAgICAgICAgKFRleHQgJiBOdW1iZXIpICAgIEp1bHkgJiAwNwogKiAuICAgZCAgICAgICAgZGF5IGluIG1vbnRoICAgICAgICAgICAgKE51bWJlcikgICAgICAgICAgIDEwCiAqIC4gICBoICAgICAgICBob3VyIGluIGFtL3BtICgxfjEyKSAgICAoTnVtYmVyKSAgICAgICAgICAgMTIKICogLiAgIEggICAgICAgIGhvdXIgaW4gZGF5ICgwfjIzKSAgICAgIChOdW1iZXIpICAgICAgICAgICAwCiAqIC4gICBtICAgICAgICBtaW51dGUgaW4gaG91ciAgICAgICAgICAoTnVtYmVyKSAgICAgICAgICAgMzAKICogLiAgIHMgICAgICAgIHNlY29uZCBpbiBtaW51dGUgICAgICAgIChOdW1iZXIpICAgICAgICAgICA1NQogKiAuICAgUyAgICAgICAgbWlsbGlzZWNvbmQgICAgICAgICAgICAgKE51bWJlcikgICAgICAgICAgIDk3OAogKiAuICAgRSAgICAgICAgZGF5IG9mIHdlZWsgICAgICAgICAgICAgKFRleHQpICAgICAgICAgICAgIFR1ZXNkYXkKICogLiAgIGUgICAgICAgIGRheSBvZiB3ZWVrL2xvY2FsICgxfjcpIChOdW1iZXIpICAgICAgICAgICAyCiAqIC4gICBEICAgICAgICBkYXkgb2YgeWVhciAgICAgICAgICAgICAoTnVtYmVyKSAgICAgICAgICAgMTg5CiAqIC4gICBGICAgICAgICBkYXkgb2Ygd2VlayBpbiBtb250aCAgICAoTnVtYmVyKSAgICAgICAgICAgMiAoMm5kIFdlZCBpbiBKdWx5KQogKiAuICAgdyAgICAgICAgd2VlayBpbiB5ZWFyICAgICAgICAgICAgKE51bWJlcikgICAgICAgICAgIDI3CiAqIC4gICBXICAgICAgICB3ZWVrIGluIG1vbnRoICAgICAgICAgICAoTnVtYmVyKSAgICAgICAgICAgMgogKiAuICAgYSAgICAgICAgYW0vcG0gbWFya2VyICAgICAgICAgICAgKFRleHQpICAgICAgICAgICAgIFBNCiAqIC4gICBrICAgICAgICBob3VyIGluIGRheSAoMX4yNCkgICAgICAoTnVtYmVyKSAgICAgICAgICAgMjQKICogLiAgIEsgICAgICAgIGhvdXIgaW4gYW0vcG0gKDB+MTEpICAgIChOdW1iZXIpICAgICAgICAgICAwCiAqIC4gICB6ICAgICAgICB0aW1lIHpvbmUgICAgICAgICAgICAgICAoVGV4dCkgICAgICAgICAgICAgUGFjaWZpYyBTdGFuZGFyZCBUaW1lCiAqIC4gICAnICAgICAgICBlc2NhcGUgZm9yIHRleHQKICogLiAgICcnICAgICAgIHNpbmdsZSBxdW90ZSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnCiAqIDwvcHJlPgogKiBUaGUgY291bnQgb2YgcGF0dGVybiBsZXR0ZXJzIGRldGVybWluZSB0aGUgZm9ybWF0LgogKiA8UD4KICogKFRleHQpOiA0IG9yIG1vcmUsIHVzZSBmdWxsIGZvcm0sICZsdDs0LCB1c2Ugc2hvcnQgb3IgYWJicmV2aWF0ZWQgZm9ybSBpZiBpdAogKiBleGlzdHMuIChlLmcuLCAiRUVFRSIgcHJvZHVjZXMgIk1vbmRheSIsICJFRUUiIHByb2R1Y2VzICJNb24iKQogKiA8UD4KICogKE51bWJlcik6IHRoZSBtaW5pbXVtIG51bWJlciBvZiBkaWdpdHMuIFNob3J0ZXIgbnVtYmVycyBhcmUgemVyby1wYWRkZWQgdG8KICogdGhpcyBhbW91bnQgKGUuZy4gaWYgIm0iIHByb2R1Y2VzICI2IiwgIm1tIiBwcm9kdWNlcyAiMDYiKS4gWWVhciBpcyBoYW5kbGVkCiAqIHNwZWNpYWxseTsgdGhhdCBpcywgaWYgdGhlIGNvdW50IG9mICd5JyBpcyAyLCB0aGUgWWVhciB3aWxsIGJlIHRydW5jYXRlZCB0byAyIGRpZ2l0cy4KICogKGUuZy4sIGlmICJ5eXl5IiBwcm9kdWNlcyAiMTk5NyIsICJ5eSIgcHJvZHVjZXMgIjk3Ii4pCiAqIDxQPgogKiAoVGV4dCAmIE51bWJlcik6IDMgb3Igb3ZlciwgdXNlIHRleHQsIG90aGVyd2lzZSB1c2UgbnVtYmVyLiAgKGUuZy4sICJNIiBwcm9kdWNlcyAiMSIsCiAqICJNTSIgcHJvZHVjZXMgIjAxIiwgIk1NTSIgcHJvZHVjZXMgIkphbiIsIGFuZCAiTU1NTSIgcHJvZHVjZXMgIkphbnVhcnkiLikKICogPFA+CiAqIEFueSBjaGFyYWN0ZXJzIGluIHRoZSBwYXR0ZXJuIHRoYXQgYXJlIG5vdCBpbiB0aGUgcmFuZ2VzIG9mIFsnYScuLid6J10gYW5kCiAqIFsnQScuLidaJ10gd2lsbCBiZSB0cmVhdGVkIGFzIHF1b3RlZCB0ZXh0LiBGb3IgaW5zdGFuY2UsIGNoYXJhY3RlcnMKICogbGlrZSAnOicsICcuJywgJyAnLCAnIycgYW5kICdAJyB3aWxsIGFwcGVhciBpbiB0aGUgcmVzdWx0aW5nIHRpbWUgdGV4dAogKiBldmVuIHRoZXkgYXJlIG5vdCBlbWJyYWNlZCB3aXRoaW4gc2luZ2xlIHF1b3Rlcy4KICogPFA+CiAqIEEgcGF0dGVybiBjb250YWluaW5nIGFueSBpbnZhbGlkIHBhdHRlcm4gbGV0dGVyIHdpbGwgcmVzdWx0IGluIGEgZmFpbGluZwogKiBVRXJyb3JDb2RlIHJlc3VsdCBkdXJpbmcgZm9ybWF0dGluZyBvciBwYXJzaW5nLgogKiA8UD4KICogRXhhbXBsZXMgdXNpbmcgdGhlIFVTIGxvY2FsZToKICogPHByZT4KICogLiAgIEZvcm1hdCBQYXR0ZXJuICAgICAgICAgICAgICAgICAgICAgICAgIFJlc3VsdAogKiAuICAgLS0tLS0tLS0tLS0tLS0gICAgICAgICAgICAgICAgICAgICAgICAgLS0tLS0tLQogKiAuICAgInl5eXkuTU0uZGQgRyAnYXQnIEhIOm1tOnNzIHoiICAgIC0+PiAgMTk5Ni4wNy4xMCBBRCBhdCAxNTowODo1NiBQRFQKICogLiAgICJFRUUsIE1NTSBkLCAnJ3l5IiAgICAgICAgICAgICAgICAtPj4gIFdlZCwgSnVseSAxMCwgJzk2CiAqIC4gICAiaDptbSBhIiAgICAgICAgICAgICAgICAgICAgICAgICAgLT4+ICAxMjowOCBQTQogKiAuICAgImhoICdvJydjbG9jaycgYSwgenp6eiIgICAgICAgICAgIC0+PiAgMTIgbydjbG9jayBQTSwgUGFjaWZpYyBEYXlsaWdodCBUaW1lCiAqIC4gICAiSzptbSBhLCB6IiAgICAgICAgICAgICAgICAgICAgICAgLT4+ICAwOjAwIFBNLCBQU1QKICogLiAgICJ5eXl5eS5NTU1NTS5kZCBHR0cgaGg6bW0gYWFhIiAgICAtPj4gIDE5OTYuSnVseS4xMCBBRCAxMjowOCBQTQogKiA8L3ByZT4KICogQ29kZSBTYW1wbGU6CiAqIDxwcmU+CiAqIC4gICAgVUVycm9yQ29kZSBzdWNjZXNzID0gVV9aRVJPX0VSUk9SOwogKiAuICAgIFNpbXBsZVRpbWVab25lKiBwZHQgPSBuZXcgU2ltcGxlVGltZVpvbmUoLTggKiA2MCAqIDYwICogMTAwMCwgIlBTVCIpOwogKiAuICAgIHBkdC0+c2V0U3RhcnRSdWxlKCBDYWxlbmRhcjo6QVBSSUwsIDEsIENhbGVuZGFyOjpTVU5EQVksIDIqNjAqNjAqMTAwMCk7CiAqIC4gICAgcGR0LT5zZXRFbmRSdWxlKCBDYWxlbmRhcjo6T0NUT0JFUiwgLTEsIENhbGVuZGFyOjpTVU5EQVksIDIqNjAqNjAqMTAwMCk7CiAqIC4gICAgCiAqIC4gICAgLy8gRm9ybWF0IHRoZSBjdXJyZW50IHRpbWUuCiAqIC4gICAgU2ltcGxlRGF0ZUZvcm1hdCogZm9ybWF0dGVyCiAqIC4gICAgICAgID0gbmV3IFNpbXBsZURhdGVGb3JtYXQgKCJ5eXl5Lk1NLmRkIEcgJ2F0JyBoaDptbTpzcyBhIHp6eiIsIHN1Y2Nlc3MgKTsKICogLiAgICBHcmVnb3JpYW5DYWxlbmRhciBjYWwoc3VjY2Vzcyk7CiAqIC4gICAgVURhdGUgY3VycmVudFRpbWVfMSA9IGNhbC5nZXRUaW1lKHN1Y2Nlc3MpOwogKiAuICAgIEZpZWxkUG9zaXRpb24gZnAoMCk7CiAqIC4gICAgVW5pY29kZVN0cmluZyBkYXRlU3RyaW5nOwogKiAuICAgIGZvcm1hdHRlci0+Zm9ybWF0KCBjdXJyZW50VGltZV8xLCBkYXRlU3RyaW5nLCBmcCApOwogKiAuICAgIGNvdXQgJmx0OyZsdDsgInJlc3VsdDogIiAmbHQ7Jmx0OyBkYXRlU3RyaW5nICZsdDsmbHQ7IGVuZGw7CiAqIC4gICAgCiAqIC4gICAgLy8gUGFyc2UgdGhlIHByZXZpb3VzIHN0cmluZyBiYWNrIGludG8gYSBEYXRlLgogKiAuICAgIFBhcnNlUG9zaXRpb24gcHAoMCk7CiAqIC4gICAgVURhdGUgY3VycmVudFRpbWVfMiA9IGZvcm1hdHRlci0+cGFyc2UoZGF0ZVN0cmluZywgcHAgKTsKICogPC9wcmU+CiAqIEluIHRoZSBhYm92ZSBleGFtcGxlLCB0aGUgdGltZSB2YWx1ZSAiY3VycmVudFRpbWVfMiIgb2J0YWluZWQgZnJvbSBwYXJzaW5nCiAqIHdpbGwgYmUgZXF1YWwgdG8gY3VycmVudFRpbWVfMS4gSG93ZXZlciwgdGhleSBtYXkgbm90IGJlIGVxdWFsIGlmIHRoZSBhbS9wbQogKiBtYXJrZXIgJ2EnIGlzIGxlZnQgb3V0IGZyb20gdGhlIGZvcm1hdCBwYXR0ZXJuIHdoaWxlIHRoZSAiaG91ciBpbiBhbS9wbSIKICogcGF0dGVybiBzeW1ib2wgaXMgdXNlZC4gVGhpcyBpbmZvcm1hdGlvbiBsb3NzIGNhbiBoYXBwZW4gd2hlbiBmb3JtYXR0aW5nIHRoZQogKiB0aW1lIGluIFBNLgogKgogKiA8cD4KICogV2hlbiBwYXJzaW5nIGEgZGF0ZSBzdHJpbmcgdXNpbmcgdGhlIGFiYnJldmlhdGVkIHllYXIgcGF0dGVybiAoInkiIG9yICJ5eSIpLAogKiBTaW1wbGVEYXRlRm9ybWF0IG11c3QgaW50ZXJwcmV0IHRoZSBhYmJyZXZpYXRlZCB5ZWFyCiAqIHJlbGF0aXZlIHRvIHNvbWUgY2VudHVyeS4gIEl0IGRvZXMgdGhpcyBieSBhZGp1c3RpbmcgZGF0ZXMgdG8gYmUKICogd2l0aGluIDgwIHllYXJzIGJlZm9yZSBhbmQgMjAgeWVhcnMgYWZ0ZXIgdGhlIHRpbWUgdGhlIFNpbXBsZURhdGVGb3JtYXQKICogaW5zdGFuY2UgaXMgY3JlYXRlZC4gRm9yIGV4YW1wbGUsIHVzaW5nIGEgcGF0dGVybiBvZiAiTU0vZGQveXkiIGFuZCBhCiAqIFNpbXBsZURhdGVGb3JtYXQgaW5zdGFuY2UgY3JlYXRlZCBvbiBKYW4gMSwgMTk5NywgIHRoZSBzdHJpbmcKICogIjAxLzExLzEyIiB3b3VsZCBiZSBpbnRlcnByZXRlZCBhcyBKYW4gMTEsIDIwMTIgd2hpbGUgdGhlIHN0cmluZyAiMDUvMDQvNjQiCiAqIHdvdWxkIGJlIGludGVycHJldGVkIGFzIE1heSA0LCAxOTY0LgogKiBEdXJpbmcgcGFyc2luZywgb25seSBzdHJpbmdzIGNvbnNpc3Rpbmcgb2YgZXhhY3RseSB0d28gZGlnaXRzLCBhcyBkZWZpbmVkIGJ5CiAqIDxjb2RlPlVuaWNvZGU6OmlzRGlnaXQoKTwvY29kZT4sIHdpbGwgYmUgcGFyc2VkIGludG8gdGhlIGRlZmF1bHQgY2VudHVyeS4KICogQW55IG90aGVyIG51bWVyaWMgc3RyaW5nLCBzdWNoIGFzIGEgb25lIGRpZ2l0IHN0cmluZywgYSB0aHJlZSBvciBtb3JlIGRpZ2l0CiAqIHN0cmluZywgb3IgYSB0d28gZGlnaXQgc3RyaW5nIHRoYXQgaXNuJ3QgYWxsIGRpZ2l0cyAoZm9yIGV4YW1wbGUsICItMSIpLCBpcwogKiBpbnRlcnByZXRlZCBsaXRlcmFsbHkuICBTbyAiMDEvMDIvMyIgb3IgIjAxLzAyLzAwMyIgYXJlIHBhcnNlZCwgdXNpbmcgdGhlCiAqIHNhbWUgcGF0dGVybiwgYXMgSmFuIDIsIDMgQUQuICBMaWtld2lzZSwgIjAxLzAyLy0zIiBpcyBwYXJzZWQgYXMgSmFuIDIsIDQgQkMuCiAqCiAqIDxwPgogKiBJZiB0aGUgeWVhciBwYXR0ZXJuIGhhcyBtb3JlIHRoYW4gdHdvICd5JyBjaGFyYWN0ZXJzLCB0aGUgeWVhciBpcwogKiBpbnRlcnByZXRlZCBsaXRlcmFsbHksIHJlZ2FyZGxlc3Mgb2YgdGhlIG51bWJlciBvZiBkaWdpdHMuICBTbyB1c2luZyB0aGUKICogcGF0dGVybiAiTU0vZGQveXl5eSIsICIwMS8xMS8xMiIgcGFyc2VzIHRvIEphbiAxMSwgMTIgQS5ELgogKgogKiA8UD4KICogRm9yIHRpbWUgem9uZXMgdGhhdCBoYXZlIG5vIG5hbWVzLCBTaW1wbGVEYXRlRm9ybWF0IHVzZXMgc3RyaW5ncyBHTVQraG91cnM6bWludXRlcyBvcgogKiBHTVQtaG91cnM6bWludXRlcy4KICogPFA+CiAqIFRoZSBjYWxlbmRhciBkZWZpbmVzIHdoYXQgaXMgdGhlIGZpcnN0IGRheSBvZiB0aGUgd2VlaywgdGhlIGZpcnN0IHdlZWsgb2YgdGhlCiAqIHllYXIsIHdoZXRoZXIgaG91cnMgYXJlIHplcm8gYmFzZWQgb3Igbm90ICgwIHZzIDEyIG9yIDI0KSwgYW5kIHRoZSB0aW1lem9uZS4KICogVGhlcmUgaXMgb25lIGNvbW1vbiBudW1iZXIgZm9ybWF0IHRvIGhhbmRsZSBhbGwgdGhlIG51bWJlcnM7IHRoZSBkaWdpdCBjb3VudAogKiBpcyBoYW5kbGVkIHByb2dyYW1tYXRpY2FsbHkgYWNjb3JkaW5nIHRvIHRoZSBwYXR0ZXJuLgogKi8KY2xhc3MgVV9JMThOX0FQSSBTaW1wbGVEYXRlRm9ybWF0OiBwdWJsaWMgRGF0ZUZvcm1hdCB7CnB1YmxpYzoKICAgIC8qKgogICAgICogQ29uc3RydWN0IGEgU2ltcGxlRGF0ZUZvcm1hdCB1c2luZyB0aGUgZGVmYXVsdCBwYXR0ZXJuIGZvciB0aGUgZGVmYXVsdAogICAgICogbG9jYWxlLgogICAgICogPFA+CiAgICAgKiBbTm90ZTpdIE5vdCBhbGwgbG9jYWxlcyBzdXBwb3J0IFNpbXBsZURhdGVGb3JtYXQ7IGZvciBmdWxsIGdlbmVyYWxpdHksCiAgICAgKiB1c2UgdGhlIGZhY3RvcnkgbWV0aG9kcyBpbiB0aGUgRGF0ZUZvcm1hdCBjbGFzcy4KICAgICAqIEBzdGFibGUKICAgICAqLwogICAgU2ltcGxlRGF0ZUZvcm1hdChVRXJyb3JDb2RlJiBzdGF0dXMpOwoKICAgIC8qKgogICAgICogQ29uc3RydWN0IGEgU2ltcGxlRGF0ZUZvcm1hdCB1c2luZyB0aGUgZ2l2ZW4gcGF0dGVybiBhbmQgdGhlIGRlZmF1bHQgbG9jYWxlLgogICAgICogVGhlIGxvY2FsZSBpcyB1c2VkIHRvIG9idGFpbiB0aGUgc3ltYm9scyB1c2VkIGluIGZvcm1hdHRpbmcgKGUuZy4sIHRoZQogICAgICogbmFtZXMgb2YgdGhlIG1vbnRocyksIGJ1dCBub3QgdG8gcHJvdmlkZSB0aGUgcGF0dGVybi4KICAgICAqIDxQPgogICAgICogW05vdGU6XSBOb3QgYWxsIGxvY2FsZXMgc3VwcG9ydCBTaW1wbGVEYXRlRm9ybWF0OyBmb3IgZnVsbCBnZW5lcmFsaXR5LAogICAgICogdXNlIHRoZSBmYWN0b3J5IG1ldGhvZHMgaW4gdGhlIERhdGVGb3JtYXQgY2xhc3MuCiAgICAgKiBAc3RhYmxlCiAgICAgKi8KICAgIFNpbXBsZURhdGVGb3JtYXQoY29uc3QgVW5pY29kZVN0cmluZyYgcGF0dGVybiwKICAgICAgICAgICAgICAgICAgICAgVUVycm9yQ29kZSYgc3RhdHVzKTsKCiAgICAvKioKICAgICAqIENvbnN0cnVjdCBhIFNpbXBsZURhdGVGb3JtYXQgdXNpbmcgdGhlIGdpdmVuIHBhdHRlcm4gYW5kIGxvY2FsZS4KICAgICAqIFRoZSBsb2NhbGUgaXMgdXNlZCB0byBvYnRhaW4gdGhlIHN5bWJvbHMgdXNlZCBpbiBmb3JtYXR0aW5nIChlLmcuLCB0aGUKICAgICAqIG5hbWVzIG9mIHRoZSBtb250aHMpLCBidXQgbm90IHRvIHByb3ZpZGUgdGhlIHBhdHRlcm4uCiAgICAgKiA8UD4KICAgICAqIFtOb3RlOl0gTm90IGFsbCBsb2NhbGVzIHN1cHBvcnQgU2ltcGxlRGF0ZUZvcm1hdDsgZm9yIGZ1bGwgZ2VuZXJhbGl0eSwKICAgICAqIHVzZSB0aGUgZmFjdG9yeSBtZXRob2RzIGluIHRoZSBEYXRlRm9ybWF0IGNsYXNzLgogICAgICogQHN0YWJsZQogICAgICovCiAgICBTaW1wbGVEYXRlRm9ybWF0KGNvbnN0IFVuaWNvZGVTdHJpbmcmIHBhdHRlcm4sCiAgICAgICAgICAgICAgICAgICAgIGNvbnN0IExvY2FsZSYgbG9jYWxlLAogICAgICAgICAgICAgICAgICAgICBVRXJyb3JDb2RlJiBzdGF0dXMpOwoKICAgIC8qKgogICAgICogQ29uc3RydWN0IGEgU2ltcGxlRGF0ZUZvcm1hdCB1c2luZyB0aGUgZ2l2ZW4gcGF0dGVybiBhbmQgbG9jYWxlLXNwZWNpZmljCiAgICAgKiBzeW1ib2wgZGF0YS4gIFRoZSBmb3JtYXR0ZXIgdGFrZXMgb3duZXJzaGlwIG9mIHRoZSBEYXRlRm9ybWF0U3ltYm9scyBvYmplY3Q7CiAgICAgKiB0aGUgY2FsbGVyIGlzIG5vIGxvbmdlciByZXNwb25zaWJsZSBmb3IgZGVsZXRpbmcgaXQuCiAgICAgKiBAc3RhYmxlCiAgICAgKi8KICAgIFNpbXBsZURhdGVGb3JtYXQoY29uc3QgVW5pY29kZVN0cmluZyYgcGF0dGVybiwKICAgICAgICAgICAgICAgICAgICAgRGF0ZUZvcm1hdFN5bWJvbHMqIGZvcm1hdERhdGFUb0Fkb3B0LAogICAgICAgICAgICAgICAgICAgICBVRXJyb3JDb2RlJiBzdGF0dXMpOwoKICAgIC8qKgogICAgICogQ29uc3RydWN0IGEgU2ltcGxlRGF0ZUZvcm1hdCB1c2luZyB0aGUgZ2l2ZW4gcGF0dGVybiBhbmQgbG9jYWxlLXNwZWNpZmljCiAgICAgKiBzeW1ib2wgZGF0YS4gIFRoZSBEYXRlRm9ybWF0U3ltYm9scyBvYmplY3QgaXMgTk9UIGFkb3B0ZWQ7IHRoZSBjYWxsZXIKICAgICAqIHJlbWFpbnMgcmVzcG9uc2libGUgZm9yIGRlbGV0aW5nIGl0LgogICAgICogQHN0YWJsZQogICAgICovCiAgICBTaW1wbGVEYXRlRm9ybWF0KGNvbnN0IFVuaWNvZGVTdHJpbmcmIHBhdHRlcm4sCiAgICAgICAgICAgICAgICAgICAgIGNvbnN0IERhdGVGb3JtYXRTeW1ib2xzJiBmb3JtYXREYXRhLAogICAgICAgICAgICAgICAgICAgICBVRXJyb3JDb2RlJiBzdGF0dXMpOwoKICAgIC8qKgogICAgICogQ29weSBjb25zdHJ1Y3Rvci4KICAgICAqIEBzdGFibGUKICAgICAqLwogICAgU2ltcGxlRGF0ZUZvcm1hdChjb25zdCBTaW1wbGVEYXRlRm9ybWF0Jik7CgogICAgLyoqCiAgICAgKiBBc3NpZ25tZW50IG9wZXJhdG9yLgogICAgICogQHN0YWJsZQogICAgICovCiAgICBTaW1wbGVEYXRlRm9ybWF0JiBvcGVyYXRvcj0oY29uc3QgU2ltcGxlRGF0ZUZvcm1hdCYpOwoKICAgIC8qKgogICAgICogRGVzdHJ1Y3Rvci4KICAgICAqIEBzdGFibGUKICAgICAqLwogICAgdmlydHVhbCB+U2ltcGxlRGF0ZUZvcm1hdCgpOwoKICAgIC8qKgogICAgICogQ2xvbmUgdGhpcyBGb3JtYXQgb2JqZWN0IHBvbHltb3JwaGljYWxseS4gVGhlIGNhbGxlciBvd25zIHRoZSByZXN1bHQgYW5kCiAgICAgKiBzaG91bGQgZGVsZXRlIGl0IHdoZW4gZG9uZS4KICAgICAqIEBzdGFibGUKICAgICAqLwogICAgdmlydHVhbCBGb3JtYXQqIGNsb25lKHZvaWQpIGNvbnN0OwoKICAgIC8qKgogICAgICogUmV0dXJuIHRydWUgaWYgdGhlIGdpdmVuIEZvcm1hdCBvYmplY3RzIGFyZSBzZW1hbnRpY2FsbHkgZXF1YWwuIE9iamVjdHMKICAgICAqIG9mIGRpZmZlcmVudCBzdWJjbGFzc2VzIGFyZSBjb25zaWRlcmVkIHVuZXF1YWwuCiAgICAgKiBAc3RhYmxlCiAgICAgKi8KICAgIHZpcnR1YWwgYm9vbF90IG9wZXJhdG9yPT0oY29uc3QgRm9ybWF0JiBvdGhlcikgY29uc3Q7CgogICAgLyoqCiAgICAgKiBGb3JtYXQgYSBkYXRlIG9yIHRpbWUsIHdoaWNoIGlzIHRoZSBzdGFuZGFyZCBtaWxsaXMgc2luY2UgMjQ6MDAgR01ULCBKYW4KICAgICAqIDEsIDE5NzAuIE92ZXJyaWRlcyBEYXRlRm9ybWF0IHB1cmUgdmlydHVhbCBtZXRob2QuCiAgICAgKiA8UD4KICAgICAqIEV4YW1wbGU6IHVzaW5nIHRoZSBVUyBsb2NhbGU6ICJ5eXl5Lk1NLmRkIGUgJ2F0JyBISDptbTpzcyB6enoiIC0+PgogICAgICogMTk5Ni4wNy4xMCBBRCBhdCAxNTowODo1NiBQRFQKICAgICAqCiAgICAgKiBAcGFyYW0gZGF0ZSAgICAgICAgICBUaGUgZGF0ZS10aW1lIHZhbHVlIHRvIGJlIGZvcm1hdHRlZCBpbnRvIGEgZGF0ZS10aW1lIHN0cmluZy4KICAgICAqIEBwYXJhbSB0b0FwcGVuZFRvICAgIFRoZSByZXN1bHQgb2YgdGhlIGZvcm1hdHRpbmcgb3BlcmF0aW9uIGlzIGFwcGVuZGVkIHRvIHRoaXMKICAgICAqICAgICAgICAgICAgICAgICAgICAgIHN0cmluZy4KICAgICAqIEBwYXJhbSBwb3MgICAgICAgICAgIFRoZSBmb3JtYXR0aW5nIHBvc2l0aW9uLiBPbiBpbnB1dDogYW4gYWxpZ25tZW50IGZpZWxkLAogICAgICogICAgICAgICAgICAgICAgICAgICAgaWYgZGVzaXJlZC4gT24gb3V0cHV0OiB0aGUgb2Zmc2V0cyBvZiB0aGUgYWxpZ25tZW50IGZpZWxkLgogICAgICogQHJldHVybiAgICAgICAgICAgICAgQSByZWZlcmVuY2UgdG8gJ3RvQXBwZW5kVG8nLgogICAgICogQHN0YWJsZQogICAgICovCiAgICB2aXJ0dWFsIFVuaWNvZGVTdHJpbmcmIGZvcm1hdCggIFVEYXRlIGRhdGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFVuaWNvZGVTdHJpbmcmIHRvQXBwZW5kVG8sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEZpZWxkUG9zaXRpb24mIHBvcykgY29uc3Q7CgogICAgLyoqCiAgICAgKiBGb3JtYXQgYSBkYXRlIG9yIHRpbWUsIHdoaWNoIGlzIHRoZSBzdGFuZGFyZCBtaWxsaXMgc2luY2UgMjQ6MDAgR01ULCBKYW4KICAgICAqIDEsIDE5NzAuIE92ZXJyaWRlcyBEYXRlRm9ybWF0IHB1cmUgdmlydHVhbCBtZXRob2QuCiAgICAgKiA8UD4KICAgICAqIEV4YW1wbGU6IHVzaW5nIHRoZSBVUyBsb2NhbGU6ICJ5eXl5Lk1NLmRkIGUgJ2F0JyBISDptbTpzcyB6enoiIC0+PgogICAgICogMTk5Ni4wNy4xMCBBRCBhdCAxNTowODo1NiBQRFQKICAgICAqCiAgICAgKiBAcGFyYW0gb2JqICAgICAgICAgICBBIEZvcm1hdHRhYmxlIGNvbnRhaW5pbmcgdGhlIGRhdGUtdGltZSB2YWx1ZSB0byBiZSBmb3JtYXR0ZWQKICAgICAqICAgICAgICAgICAgICAgICAgICAgIGludG8gYSBkYXRlLXRpbWUgc3RyaW5nLiAgSWYgdGhlIHR5cGUgb2YgdGhlIEZvcm1hdHRhYmxlCiAgICAgKiAgICAgICAgICAgICAgICAgICAgICBpcyBhIG51bWVyaWMgdHlwZSwgaXQgaXMgdHJlYXRlZCBhcyBpZiBpdCB3ZXJlIGFuCiAgICAgKiAgICAgICAgICAgICAgICAgICAgICBpbnN0YW5jZSBvZiBEYXRlLgogICAgICogQHBhcmFtIHRvQXBwZW5kVG8gICAgVGhlIHJlc3VsdCBvZiB0aGUgZm9ybWF0dGluZyBvcGVyYXRpb24gaXMgYXBwZW5kZWQgdG8gdGhpcwogICAgICogICAgICAgICAgICAgICAgICAgICAgc3RyaW5nLgogICAgICogQHBhcmFtIHBvcyAgICAgICAgICAgVGhlIGZvcm1hdHRpbmcgcG9zaXRpb24uIE9uIGlucHV0OiBhbiBhbGlnbm1lbnQgZmllbGQsCiAgICAgKiAgICAgICAgICAgICAgICAgICAgICBpZiBkZXNpcmVkLiBPbiBvdXRwdXQ6IHRoZSBvZmZzZXRzIG9mIHRoZSBhbGlnbm1lbnQgZmllbGQuCiAgICAgKiBAcmV0dXJuICAgICAgICAgICAgICBBIHJlZmVyZW5jZSB0byAndG9BcHBlbmRUbycuCiAgICAgKiBAc3RhYmxlCiAgICAgKi8KICAgIHZpcnR1YWwgVW5pY29kZVN0cmluZyYgZm9ybWF0KCAgY29uc3QgRm9ybWF0dGFibGUmIG9iaiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVW5pY29kZVN0cmluZyYgdG9BcHBlbmRUbywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRmllbGRQb3NpdGlvbiYgcG9zLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBVRXJyb3JDb2RlJiBzdGF0dXMpIGNvbnN0OwoKICAgIC8qKgogICAgICogUmVkZWNsYXJlZCBEYXRlRm9ybWF0IG1ldGhvZC4KICAgICAqIEBzdGFibGUKICAgICAqLwogICAgVW5pY29kZVN0cmluZyYgZm9ybWF0KGNvbnN0IEZvcm1hdHRhYmxlJiBvYmosCiAgICAgICAgICAgICAgICAgICAgICAgICAgVW5pY29kZVN0cmluZyYgcmVzdWx0LAogICAgICAgICAgICAgICAgICAgICAgICAgIFVFcnJvckNvZGUmIHN0YXR1cykgY29uc3Q7CgogICAgLyoqCiAgICAgKiBSZWRlY2xhcmVkIERhdGVGb3JtYXQgbWV0aG9kLgogICAgICogQHN0YWJsZQogICAgICovCiAgICBVbmljb2RlU3RyaW5nJiBmb3JtYXQoVURhdGUgZGF0ZSwgVW5pY29kZVN0cmluZyYgcmVzdWx0KSBjb25zdDsKCiAgICAvKioKICAgICAqIFBhcnNlIGEgZGF0ZS90aW1lIHN0cmluZyBzdGFydGluZyBhdCB0aGUgZ2l2ZW4gcGFyc2UgcG9zaXRpb24uIEZvcgogICAgICogZXhhbXBsZSwgYSB0aW1lIHRleHQgIjA3LzEwLzk2IDQ6NSBQTSwgUERUIiB3aWxsIGJlIHBhcnNlZCBpbnRvIGEgRGF0ZQogICAgICogdGhhdCBpcyBlcXVpdmFsZW50IHRvIERhdGUoODM3MDM5OTI4MDQ2KS4KICAgICAqIDxQPgogICAgICogQnkgZGVmYXVsdCwgcGFyc2luZyBpcyBsZW5pZW50OiBJZiB0aGUgaW5wdXQgaXMgbm90IGluIHRoZSBmb3JtIHVzZWQgYnkKICAgICAqIHRoaXMgb2JqZWN0J3MgZm9ybWF0IG1ldGhvZCBidXQgY2FuIHN0aWxsIGJlIHBhcnNlZCBhcyBhIGRhdGUsIHRoZW4gdGhlCiAgICAgKiBwYXJzZSBzdWNjZWVkcy4gQ2xpZW50cyBtYXkgaW5zaXN0IG9uIHN0cmljdCBhZGhlcmVuY2UgdG8gdGhlIGZvcm1hdCBieQogICAgICogY2FsbGluZyBzZXRMZW5pZW50KGZhbHNlKS4KICAgICAqCiAgICAgKiBAc2VlIERhdGVGb3JtYXQ6OnNldExlbmllbnQoYm9vbGVhbikKICAgICAqCiAgICAgKiBAcGFyYW0gdGV4dCAgVGhlIGRhdGUvdGltZSBzdHJpbmcgdG8gYmUgcGFyc2VkCiAgICAgKiBAcGFyYW0gcG9zICAgT24gaW5wdXQsIHRoZSBwb3NpdGlvbiBhdCB3aGljaCB0byBzdGFydCBwYXJzaW5nOyBvbgogICAgICogICAgICAgICAgICAgIG91dHB1dCwgdGhlIHBvc2l0aW9uIGF0IHdoaWNoIHBhcnNpbmcgdGVybWluYXRlZCwgb3IgdGhlCiAgICAgKiAgICAgICAgICAgICAgc3RhcnQgcG9zaXRpb24gaWYgdGhlIHBhcnNlIGZhaWxlZC4KICAgICAqIEByZXR1cm4gICAgICBBIHZhbGlkIFVEYXRlIGlmIHRoZSBpbnB1dCBjb3VsZCBiZSBwYXJzZWQuCiAgICAgKiBAc3RhYmxlCiAgICAgKi8KICAgIHZpcnR1YWwgVURhdGUgcGFyc2UoIGNvbnN0IFVuaWNvZGVTdHJpbmcmIHRleHQsCiAgICAgICAgICAgICAgICAgICAgICAgIFBhcnNlUG9zaXRpb24mIHBvcykgY29uc3Q7CgoKICAgIC8qKgogICAgICogUGFyc2UgYSBkYXRlL3RpbWUgc3RyaW5nLiBGb3IgZXhhbXBsZSwgYSB0aW1lIHRleHQgIjA3LzEwLzk2IDQ6NSBQTSwgUERUIgogICAgICogd2lsbCBiZSBwYXJzZWQgaW50byBhIFVEYXRlIHRoYXQgaXMgZXF1aXZhbGVudCB0byBEYXRlKDgzNzAzOTkyODA0NikuCiAgICAgKiBQYXJzaW5nIGJlZ2lucyBhdCB0aGUgYmVnaW5uaW5nIG9mIHRoZSBzdHJpbmcgYW5kIHByb2NlZWRzIGFzIGZhciBhcwogICAgICogcG9zc2libGUuICBBc3N1bWluZyBubyBwYXJzZSBlcnJvcnMgd2VyZSBlbmNvdW50ZXJlZCwgdGhpcyBmdW5jdGlvbgogICAgICogZG9lc24ndCByZXR1cm4gYW55IGluZm9ybWF0aW9uIGFib3V0IGhvdyBtdWNoIG9mIHRoZSBzdHJpbmcgd2FzIGNvbnN1bWVkCiAgICAgKiBieSB0aGUgcGFyc2luZy4gIElmIHlvdSBuZWVkIHRoYXQgaW5mb3JtYXRpb24sIHVzZSB0aGUgdmVyc2lvbiBvZgogICAgICogcGFyc2UoKSB0aGF0IHRha2VzIGEgUGFyc2VQb3NpdGlvbi4KICAgICAqCiAgICAgKiBAcGFyYW0gdGV4dCAgVGhlIGRhdGUvdGltZSBzdHJpbmcgdG8gYmUgcGFyc2VkCiAgICAgKiBAcGFyYW0gc3RhdHVzIEZpbGxlZCBpbiB3aXRoIFVfWkVST19FUlJPUiBpZiB0aGUgcGFyc2Ugd2FzIHN1Y2Nlc3NmdWwsIGFuZCB3aXRoCiAgICAgKiAgICAgICAgICAgICAgYW4gZXJyb3IgdmFsdWUgaWYgdGhlcmUgd2FzIGEgcGFyc2UgZXJyb3IuCiAgICAgKiBAcmV0dXJuICAgICAgQSB2YWxpZCBVRGF0ZSBpZiB0aGUgaW5wdXQgY291bGQgYmUgcGFyc2VkLgogICAgICogQHN0YWJsZQogICAgICovCiAgICB2aXJ0dWFsIFVEYXRlIHBhcnNlKCBjb25zdCBVbmljb2RlU3RyaW5nJiB0ZXh0LAogICAgICAgICAgICAgICAgICAgICAgICBVRXJyb3JDb2RlJiBzdGF0dXMpIGNvbnN0OwoKICAgIC8qKgogICAgICogU2V0IHRoZSBzdGFydCBVRGF0ZSB1c2VkIHRvIGludGVycHJldCB0d28tZGlnaXQgeWVhciBzdHJpbmdzLgogICAgICogV2hlbiBkYXRlcyBhcmUgcGFyc2VkIGhhdmluZyAyLWRpZ2l0IHllYXIgc3RyaW5ncywgdGhleSBhcmUgcGxhY2VkIHdpdGhpbgogICAgICogYSBhc3N1bWVkIHJhbmdlIG9mIDEwMCB5ZWFycyBzdGFydGluZyBvbiB0aGUgdHdvIGRpZ2l0IHN0YXJ0IGRhdGUuICBGb3IKICAgICAqIGV4YW1wbGUsIHRoZSBzdHJpbmcgIjI0LUphbi0xNyIgbWF5IGJlIGluIHRoZSB5ZWFyIDE4MTcsIDE5MTcsIDIwMTcsIG9yCiAgICAgKiBzb21lIG90aGVyIHllYXIuICBTaW1wbGVEYXRlRm9ybWF0IGNob29zZXMgYSB5ZWFyIHNvIHRoYXQgdGhlIHJlc3VsdGFudAogICAgICogZGF0ZSBpcyBvbiBvciBhZnRlciB0aGUgdHdvIGRpZ2l0IHN0YXJ0IGRhdGUgYW5kIHdpdGhpbiAxMDAgeWVhcnMgb2YgdGhlCiAgICAgKiB0d28gZGlnaXQgc3RhcnQgZGF0ZS4KICAgICAqIDxQPgogICAgICogQnkgZGVmYXVsdCwgdGhlIHR3byBkaWdpdCBzdGFydCBkYXRlIGlzIHNldCB0byA4MCB5ZWFycyBiZWZvcmUgdGhlIGN1cnJlbnQKICAgICAqIHRpbWUgYXQgd2hpY2ggYSBTaW1wbGVEYXRlRm9ybWF0IG9iamVjdCBpcyBjcmVhdGVkLgogICAgICogQHN0YWJsZQogICAgICovCiAgICB2aXJ0dWFsIHZvaWQgc2V0MkRpZ2l0WWVhclN0YXJ0KFVEYXRlIGQsIFVFcnJvckNvZGUmIHN0YXR1cyk7CgogICAgLyoqCiAgICAgKiBHZXQgdGhlIHN0YXJ0IFVEYXRlIHVzZWQgdG8gaW50ZXJwcmV0IHR3by1kaWdpdCB5ZWFyIHN0cmluZ3MuCiAgICAgKiBXaGVuIGRhdGVzIGFyZSBwYXJzZWQgaGF2aW5nIDItZGlnaXQgeWVhciBzdHJpbmdzLCB0aGV5IGFyZSBwbGFjZWQgd2l0aGluCiAgICAgKiBhIGFzc3VtZWQgcmFuZ2Ugb2YgMTAwIHllYXJzIHN0YXJ0aW5nIG9uIHRoZSB0d28gZGlnaXQgc3RhcnQgZGF0ZS4gIEZvcgogICAgICogZXhhbXBsZSwgdGhlIHN0cmluZyAiMjQtSmFuLTE3IiBtYXkgYmUgaW4gdGhlIHllYXIgMTgxNywgMTkxNywgMjAxNywgb3IKICAgICAqIHNvbWUgb3RoZXIgeWVhci4gIFNpbXBsZURhdGVGb3JtYXQgY2hvb3NlcyBhIHllYXIgc28gdGhhdCB0aGUgcmVzdWx0YW50CiAgICAgKiBkYXRlIGlzIG9uIG9yIGFmdGVyIHRoZSB0d28gZGlnaXQgc3RhcnQgZGF0ZSBhbmQgd2l0aGluIDEwMCB5ZWFycyBvZiB0aGUKICAgICAqIHR3byBkaWdpdCBzdGFydCBkYXRlLgogICAgICogPFA+CiAgICAgKiBCeSBkZWZhdWx0LCB0aGUgdHdvIGRpZ2l0IHN0YXJ0IGRhdGUgaXMgc2V0IHRvIDgwIHllYXJzIGJlZm9yZSB0aGUgY3VycmVudAogICAgICogdGltZSBhdCB3aGljaCBhIFNpbXBsZURhdGVGb3JtYXQgb2JqZWN0IGlzIGNyZWF0ZWQuCiAgICAgKiBAc3RhYmxlCiAgICAgKi8KICAgIFVEYXRlIGdldDJEaWdpdFllYXJTdGFydChVRXJyb3JDb2RlJiBzdGF0dXMpIGNvbnN0OwoKICAgIC8qKgogICAgICogUmV0dXJuIGEgcGF0dGVybiBzdHJpbmcgZGVzY3JpYmluZyB0aGlzIGRhdGUgZm9ybWF0LgogICAgICogQHN0YWJsZQogICAgICovCiAgICB2aXJ0dWFsIFVuaWNvZGVTdHJpbmcmIHRvUGF0dGVybihVbmljb2RlU3RyaW5nJiByZXN1bHQpIGNvbnN0OwoKICAgIC8qKgogICAgICogUmV0dXJuIGEgbG9jYWxpemVkIHBhdHRlcm4gc3RyaW5nIGRlc2NyaWJpbmcgdGhpcyBkYXRlIGZvcm1hdC4KICAgICAqIEluIG1vc3QgY2FzZXMsIHRoaXMgd2lsbCByZXR1cm4gdGhlIHNhbWUgdGhpbmcgYXMgdG9QYXR0ZXJuKCksCiAgICAgKiBidXQgYSBsb2NhbGUgY2FuIHNwZWNpZnkgY2hhcmFjdGVycyB0byB1c2UgaW4gcGF0dGVybiBkZXNjcmlwdGlvbnMKICAgICAqIGluIHBsYWNlIG9mIHRoZSBvbmVzIGRlc2NyaWJlZCBpbiB0aGlzIGNsYXNzJ3MgY2xhc3MgZG9jdW1lbnRhdGlvbi4KICAgICAqIChQcmVzdW1hYmx5LCBsZXR0ZXJzIHRoYXQgd291bGQgYmUgbW9yZSBtbmVtb25pYyBpbiB0aGF0IGxvY2FsZSdzCiAgICAgKiBsYW5ndWFnZS4pICBUaGlzIGZ1bmN0aW9uIHdvdWxkIHByb2R1Y2UgYSBwYXR0ZXJuIHVzaW5nIHRob3NlCiAgICAgKiBsZXR0ZXJzLgogICAgICoKICAgICAqIEBwYXJhbSByZXN1bHQgICAgUmVjZWl2ZXMgdGhlIGxvY2FsaXplZCBwYXR0ZXJuLgogICAgICogQHBhcmFtIHN0YXR1cyAgICBPdXRwdXQgcGFyYW0gc2V0IHRvIHN1Y2Nlc3MvZmFpbHVyZSBjb2RlIG9uCiAgICAgKiAgICAgICAgICAgICAgICAgIGV4aXQuIElmIHRoZSBwYXR0ZXJuIGlzIGludmFsaWQsIHRoaXMgd2lsbCBiZQogICAgICogICAgICAgICAgICAgICAgICBzZXQgdG8gYSBmYWlsdXJlIHJlc3VsdC4KICAgICAqIEBzdGFibGUKICAgICAqLwogICAgdmlydHVhbCBVbmljb2RlU3RyaW5nJiB0b0xvY2FsaXplZFBhdHRlcm4oVW5pY29kZVN0cmluZyYgcmVzdWx0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVUVycm9yQ29kZSYgc3RhdHVzKSBjb25zdDsKCiAgICAvKioKICAgICAqIEFwcGx5IHRoZSBnaXZlbiB1bmxvY2FsaXplZCBwYXR0ZXJuIHN0cmluZyB0byB0aGlzIGRhdGUgZm9ybWF0LgogICAgICogKGkuZS4sIGFmdGVyIHRoaXMgY2FsbCwgdGhpcyBmb3JtYXR0ZXIgd2lsbCBmb3JtYXQgZGF0ZXMgYWNjb3JkaW5nIHRvCiAgICAgKiB0aGUgbmV3IHBhdHRlcm4pCiAgICAgKgogICAgICogQHBhcmFtIHBhdHRlcm4gICBUaGUgcGF0dGVybiB0byBiZSBhcHBsaWVkLgogICAgICogQHN0YWJsZQogICAgICovCiAgICB2aXJ0dWFsIHZvaWQgYXBwbHlQYXR0ZXJuKGNvbnN0IFVuaWNvZGVTdHJpbmcmIHBhdHRlcm4pOwoKICAgIC8qKgogICAgICogQXBwbHkgdGhlIGdpdmVuIGxvY2FsaXplZCBwYXR0ZXJuIHN0cmluZyB0byB0aGlzIGRhdGUgZm9ybWF0LgogICAgICogKHNlZSB0b0xvY2FsaXplZFBhdHRlcm4oKSBmb3IgbW9yZSBpbmZvcm1hdGlvbiBvbiBsb2NhbGl6ZWQgcGF0dGVybnMuKQogICAgICoKICAgICAqIEBwYXJhbSBwYXR0ZXJuICAgVGhlIGxvY2FsaXplZCBwYXR0ZXJuIHRvIGJlIGFwcGxpZWQuCiAgICAgKiBAcGFyYW0gc3RhdHVzICAgIE91dHB1dCBwYXJhbSBzZXQgdG8gc3VjY2Vzcy9mYWlsdXJlIGNvZGUgb24KICAgICAqICAgICAgICAgICAgICAgICAgZXhpdC4gSWYgdGhlIHBhdHRlcm4gaXMgaW52YWxpZCwgdGhpcyB3aWxsIGJlCiAgICAgKiAgICAgICAgICAgICAgICAgIHNldCB0byBhIGZhaWx1cmUgcmVzdWx0LgogICAgICogQHN0YWJsZQogICAgICovCiAgICB2aXJ0dWFsIHZvaWQgYXBwbHlMb2NhbGl6ZWRQYXR0ZXJuKGNvbnN0IFVuaWNvZGVTdHJpbmcmIHBhdHRlcm4sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFVFcnJvckNvZGUmIHN0YXR1cyk7CgogICAgLyoqCiAgICAgKiBHZXRzIHRoZSBkYXRlL3RpbWUgZm9ybWF0dGluZyBzeW1ib2xzICh0aGlzIGlzIGFuIG9iamVjdCBjYXJyeWluZwogICAgICogdGhlIHZhcmlvdXMgc3RyaW5ncyBhbmQgb3RoZXIgc3ltYm9scyB1c2VkIGluIGZvcm1hdHRpbmc6IGUuZy4sIG1vbnRoCiAgICAgKiBuYW1lcyBhbmQgYWJicmV2aWF0aW9ucywgdGltZSB6b25lIG5hbWVzLCBBTS9QTSBzdHJpbmdzLCBldGMuKQogICAgICogQHJldHVybiBhIGNvcHkgb2YgdGhlIGRhdGUtdGltZSBmb3JtYXR0aW5nIGRhdGEgYXNzb2NpYXRlZAogICAgICogd2l0aCB0aGlzIGRhdGUtdGltZSBmb3JtYXR0ZXIuCiAgICAgKiBAc3RhYmxlCiAgICAgKi8KICAgIHZpcnR1YWwgY29uc3QgRGF0ZUZvcm1hdFN5bWJvbHMqIGdldERhdGVGb3JtYXRTeW1ib2xzKHZvaWQpIGNvbnN0OwoKICAgIC8qKgogICAgICogU2V0IHRoZSBkYXRlL3RpbWUgZm9ybWF0dGluZyBzeW1ib2xzLiAgVGhlIGNhbGxlciBubyBsb25nZXIgb3ducyB0aGUKICAgICAqIERhdGVGb3JtYXRTeW1ib2xzIG9iamVjdCBhbmQgc2hvdWxkIG5vdCBkZWxldGUgaXQgYWZ0ZXIgbWFraW5nIHRoaXMgY2FsbC4KICAgICAqIEBwYXJhbSBuZXdGb3JtYXREYXRhIHRoZSBnaXZlbiBkYXRlLXRpbWUgZm9ybWF0dGluZyBkYXRhLgogICAgICogQHN0YWJsZQogICAgICovCiAgICB2aXJ0dWFsIHZvaWQgYWRvcHREYXRlRm9ybWF0U3ltYm9scyhEYXRlRm9ybWF0U3ltYm9scyogbmV3Rm9ybWF0U3ltYm9scyk7CgogICAgLyoqCiAgICAgKiBTZXQgdGhlIGRhdGUvdGltZSBmb3JtYXR0aW5nIGRhdGEuCiAgICAgKiBAcGFyYW0gbmV3Rm9ybWF0RGF0YSB0aGUgZ2l2ZW4gZGF0ZS10aW1lIGZvcm1hdHRpbmcgZGF0YS4KICAgICAqIEBzdGFibGUKICAgICAqLwogICAgdmlydHVhbCB2b2lkIHNldERhdGVGb3JtYXRTeW1ib2xzKGNvbnN0IERhdGVGb3JtYXRTeW1ib2xzJiBuZXdGb3JtYXRTeW1ib2xzKTsKCgpwdWJsaWM6CiAgICAvKioKICAgICAqIFJlc291cmNlIGJ1bmRsZSBmaWxlIHN1ZmZpeCBhbmQgdGFnIG5hbWVzIHVzZWQgYnkgdGhpcyBjbGFzcy4KICAgICAqLwogICAgc3RhdGljIGNvbnN0IGNoYXIgKmZnRXJhc1RhZzsgICAvLyByZXNvdXJjZSBidW5kbGUgdGFnIGZvciBlcmEgbmFtZXMKICAgIHN0YXRpYyBjb25zdCBjaGFyICpmZ01vbnRoTmFtZXNUYWc7IC8vIHJlc291cmNlIGJ1bmRsZSB0YWcgZm9yIG1vbnRoIG5hbWVzCiAgICBzdGF0aWMgY29uc3QgY2hhciAqZmdNb250aEFiYnJldmlhdGlvbnNUYWc7IC8vIHJlc291cmNlIGJ1bmRsZSB0YWcgZm9yIG1vbnRoIGFiYnJldmlhdGlvbnMKICAgIHN0YXRpYyBjb25zdCBjaGFyICpmZ0RheU5hbWVzVGFnOyAgIC8vIHJlc291cmNlIGJ1bmRsZSB0YWcgZm9yIGRheSBuYW1lcwogICAgc3RhdGljIGNvbnN0IGNoYXIgKmZnRGF5QWJicmV2aWF0aW9uc1RhZzsgICAvLyByZXNvdXJjZSBidW5kbGUgdGFnIGZvciBkYXkgYWJicmV2aWF0aW9ucwogICAgc3RhdGljIGNvbnN0IGNoYXIgKmZnQW1QbU1hcmtlcnNUYWc7ICAgIC8vIHJlc291cmNlIGJ1bmRsZSB0YWcgZm9yIEFNL1BNIHN0cmluZ3MKICAgIHN0YXRpYyBjb25zdCBjaGFyICpmZ0RhdGVUaW1lUGF0dGVybnNUYWc7ICAgLy8gcmVzb3VyY2UgYnVuZGxlIHRhZyBmb3IgZGVmYXVsdCBkYXRlIGFuZCB0aW1lIHBhdHRlcm5zCgogICAgc3RhdGljIGNvbnN0IGNoYXIgKmZnWm9uZVN0cmluZ3NUYWc7ICAgIC8vIHJlc291cmNlIGJ1bmRsZSB0YWcgZm9yIHRpbWUgem9uZSBuYW1lcwogICAgc3RhdGljIGNvbnN0IGNoYXIgKmZnTG9jYWxQYXR0ZXJuQ2hhcnNUYWc7ICAvLyByZXNvdXJjZSBidW5kbGUgdGFnIGZvciBsb2NhbGl6ZWQgcGF0dGVybiBjaGFyYWN0ZXJzCgogICAgc3RhdGljIGNvbnN0IFVuaWNvZGVTdHJpbmcgICAgICBmZ0RlZmF1bHRQYXR0ZXJuOyAgICAvLyBkYXRlL3RpbWUgcGF0dGVybiBvZiBsYXN0IHJlc29ydAoKcHVibGljOgogICAgLyoqCiAgICAgKiBSZXR1cm4gdGhlIGNsYXNzIElEIGZvciB0aGlzIGNsYXNzLiBUaGlzIGlzIHVzZWZ1bCBvbmx5IGZvciBjb21wYXJpbmcgdG8KICAgICAqIGEgcmV0dXJuIHZhbHVlIGZyb20gZ2V0RHluYW1pY0NsYXNzSUQoKS4gRm9yIGV4YW1wbGU6CiAgICAgKiA8cHJlPgogICAgICogLiAgIEJhc2UqIHBvbHltb3JwaGljX3BvaW50ZXIgPSBjcmVhdGVQb2x5bW9ycGhpY09iamVjdCgpOwogICAgICogLiAgIGlmIChwb2x5bW9ycGhpY19wb2ludGVyLT5nZXREeW5hbWljQ2xhc3NJRCgpID09CiAgICAgKiAuICAgICAgIGVyaXZlZDo6Z2V0U3RhdGljQ2xhc3NJRCgpKSAuLi4KICAgICAqIDwvcHJlPgogICAgICogQHJldHVybiAgICAgICAgICBUaGUgY2xhc3MgSUQgZm9yIGFsbCBvYmplY3RzIG9mIHRoaXMgY2xhc3MuCiAgICAgKiBAc3RhYmxlCiAgICAgKi8KICAgIHN0YXRpYyBVQ2xhc3NJRCBnZXRTdGF0aWNDbGFzc0lEKHZvaWQpIHsgcmV0dXJuIChVQ2xhc3NJRCkmZmdDbGFzc0lEOyB9CgogICAgLyoqCiAgICAgKiBSZXR1cm5zIGEgdW5pcXVlIGNsYXNzIElEIFBPTFlNT1JQSElDQUxMWS4gUHVyZSB2aXJ0dWFsIG92ZXJyaWRlLiBUaGlzCiAgICAgKiBtZXRob2QgaXMgdG8gaW1wbGVtZW50IGEgc2ltcGxlIHZlcnNpb24gb2YgUlRUSSwgc2luY2Ugbm90IGFsbCBDKysKICAgICAqIGNvbXBpbGVycyBzdXBwb3J0IGdlbnVpbmUgUlRUSS4gUG9seW1vcnBoaWMgb3BlcmF0b3I9PSgpIGFuZCBjbG9uZSgpCiAgICAgKiBtZXRob2RzIGNhbGwgdGhpcyBtZXRob2QuCiAgICAgKgogICAgICogQHJldHVybiAgICAgICAgICBUaGUgY2xhc3MgSUQgZm9yIHRoaXMgb2JqZWN0LiBBbGwgb2JqZWN0cyBvZiBhCiAgICAgKiAgICAgICAgICAgICAgICAgIGdpdmVuIGNsYXNzIGhhdmUgdGhlIHNhbWUgY2xhc3MgSUQuICBPYmplY3RzIG9mCiAgICAgKiAgICAgICAgICAgICAgICAgIG90aGVyIGNsYXNzZXMgaGF2ZSBkaWZmZXJlbnQgY2xhc3MgSURzLgogICAgICogQHN0YWJsZQogICAgICovCiAgICB2aXJ0dWFsIFVDbGFzc0lEIGdldER5bmFtaWNDbGFzc0lEKHZvaWQpIGNvbnN0IHsgcmV0dXJuIGdldFN0YXRpY0NsYXNzSUQoKTsgfQoKcHJpdmF0ZToKICAgIHN0YXRpYyBjaGFyIGZnQ2xhc3NJRDsKCiAgICBmcmllbmQgY2xhc3MgRGF0ZUZvcm1hdDsKCiAgICAvKioKICAgICAqIEdldHMgdGhlIGluZGV4IGZvciB0aGUgZ2l2ZW4gdGltZSB6b25lIElEIHRvIG9idGFpbiB0aGUgdGltZXpvbmUgc3RyaW5ncwogICAgICogZm9yIGZvcm1hdHRpbmcuIFRoZSB0aW1lIHpvbmUgSUQgaXMganVzdCBmb3IgcHJvZ3JhbW1hdGljIGxvb2t1cC4gTk9UCiAgICAgKiBMT0NBTElaRUQhISEKICAgICAqCiAgICAgKiBAcGFyYW0gRGF0ZUZvcm1hdFN5bWJvbHMgICAgIGEgRGF0ZUZvcm1hdFN5bWJvbHMgb2JqZWN0IGNvbnRpYW5pbmcgdGhlIHRpbWUgem9uZSBuYW1lcwogICAgICogQHBhcmFtIElEICAgICAgICB0aGUgZ2l2ZW4gdGltZSB6b25lIElELgogICAgICogQHJldHVybiAgICAgICAgICB0aGUgaW5kZXggb2YgdGhlIGdpdmVuIHRpbWUgem9uZSBJRC4gIFJldHVybnMgLTEgaWYKICAgICAqICAgICAgICAgICAgICAgICAgdGhlIGdpdmVuIHRpbWUgem9uZSBJRCBjYW4ndCBiZSBsb2NhdGVkIGluIHRoZQogICAgICogICAgICAgICAgICAgICAgICBEYXRlRm9ybWF0U3ltYm9scyBvYmplY3QuCiAgICAgKiBAc2VlIFNpbXBsZVRpbWVab25lCiAgICAgKi8KICAgIC8vaW50MzJfdCBnZXRab25lSW5kZXgoY29uc3QgRGF0ZUZvcm1hdFN5bWJvbHMmLCBjb25zdCBVbmljb2RlU3RyaW5nJiBJRCkgY29uc3Q7CgogICAgdm9pZCBpbml0aWFsaXplRGVmYXVsdENlbnR1cnkodm9pZCk7CgogICAgLyoqCiAgICAgKiBVc2VkIGJ5IHRoZSBEYXRlRm9ybWF0IGZhY3RvcnkgbWV0aG9kcyB0byBjb25zdHJ1Y3QgYSBTaW1wbGVEYXRlRm9ybWF0LgogICAgICovCiAgICBTaW1wbGVEYXRlRm9ybWF0KEVTdHlsZSB0aW1lU3R5bGUsIEVTdHlsZSBkYXRlU3R5bGUsIGNvbnN0IExvY2FsZSYgbG9jYWxlLCBVRXJyb3JDb2RlJiBzdGF0dXMpOwoKICAgIC8qKgogICAgICogQ29uc3RydWN0IGEgU2ltcGxlRGF0ZUZvcm1hdCBmb3IgdGhlIGdpdmVuIGxvY2FsZS4gIElmIG5vIHJlc291cmNlIGRhdGEKICAgICAqIGlzIGF2YWlsYWJsZSwgY3JlYXRlIGFuIG9iamVjdCBvZiBsYXN0IHJlc29ydCwgdXNpbmcgaGFyZC1jb2RlZCBzdHJpbmdzLgogICAgICogVGhpcyBpcyBhbiBpbnRlcm5hbCBtZXRob2QsIGNhbGxlZCBieSBEYXRlRm9ybWF0LiAgSXQgc2hvdWxkIG5ldmVyIGZhaWwuCiAgICAgKi8KICAgIFNpbXBsZURhdGVGb3JtYXQoY29uc3QgTG9jYWxlJiBsb2NhbGUsIFVFcnJvckNvZGUmIHN0YXR1cyk7IC8vIFVzZSBkZWZhdWx0IHBhdHRlcm4KCiAgICAvKioKICAgICAqIENhbGxlZCBieSBmb3JtYXQoKSB0byBmb3JtYXQgYSBzaW5nbGUgZmllbGQuCiAgICAgKgogICAgICogQHBhcmFtIHJlc3VsdCAgICBGaWxsZWQgaW4gd2l0aCB0aGUgcmVzdWx0LgogICAgICogQHBhcmFtIGNoICAgICAgICBUaGUgZm9ybWF0IGNoYXJhY3RlciB3ZSBlbmNvdW50ZXJlZCBpbiB0aGUgcGF0dGVybi4KICAgICAqIEBwYXJhbSBjb3VudCAgICAgTnVtYmVyIG9mIGNoYXJhY3RlcnMgaW4gdGhlIGN1cnJlbnQgcGF0dGVybiBzeW1ib2wgKGUuZy4sCiAgICAgKiAgICAgICAgICAgICAgICAgICJ5eXl5IiBpbiB0aGUgcGF0dGVybiB3b3VsZCByZXN1bHQgaW4gYSBjYWxsIHRvIHRoaXMgZnVuY3Rpb24KICAgICAqICAgICAgICAgICAgICAgICAgd2l0aCBjaCBlcXVhbCB0byAneScgYW5kIGNvdW50IGVxdWFsIHRvIDQpCiAgICAgKiBAcGFyYW0gYmVnaW5PZmZzZXQgICBUZWxscyB3aGVyZSB0aGUgdGV4dCByZXR1cm5lZCBieSB0aGlzIGZ1bmN0aW9uIHdpbGwgZ28gaW4KICAgICAqICAgICAgICAgICAgICAgICAgdGhlIGZpbmlzaGVkIHN0cmluZy4gIFVzZWQgd2hlbiB0aGlzIGZ1bmN0aW9uIG5lZWRzIHRvIGZpbGwKICAgICAqICAgICAgICAgICAgICAgICAgaW4gYSBGaWVsZFBvc2l0aW9uCiAgICAgKiBAcGFyYW0gcG9zICAgICAgIFRoZSBGaWVsZFBvc2l0aW9uIGJlaW5nIGZpbGxlZCBpbiBieSB0aGUgZm9ybWF0KCkgY2FsbC4gIElmCiAgICAgKiAgICAgICAgICAgICAgICAgIHRoaXMgZnVuY3Rpb24gaXMgZm9ybWF0dGluZyB0aGUgZmllbGQgc3BlY2ZpZWQgYnkgcG9zLCBpdAogICAgICogICAgICAgICAgICAgICAgICB3aWxsIGZpbGwgaW4gcG9zIHdpbGwgdGhlIGJlZ2lubmluZyBhbmQgZW5kaW5nIG9mZnNldHMgb2YgdGhlCiAgICAgKiAgICAgICAgICAgICAgICAgIGZpZWxkLgogICAgICogQHBhcmFtIHN0YXR1cyAgICBSZWNlaXZlcyBhIHN0YXR1cyBjb2RlLCB3aGljaCB3aWxsIGJlIFVfWkVST19FUlJPUiBpZiB0aGUgb3BlcmF0aW9uCiAgICAgKiAgICAgICAgICAgICAgICAgIHN1Y2NlZWRzLgogICAgICogQHJldHVybiBBIHJlZmVyZW5jZSB0byAicmVzdWx0Ii4KICAgICAqIEBkcmFmdAogICAgICovCiAgICBVbmljb2RlU3RyaW5nJiBzdWJGb3JtYXQoICAgVW5pY29kZVN0cmluZyYgcmVzdWx0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFVDaGFyIGNoLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludDMyX3QgY291bnQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50MzJfdCBiZWdpbk9mZnNldCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBGaWVsZFBvc2l0aW9uJiBwb3MsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVUVycm9yQ29kZSYgc3RhdHVzKSBjb25zdDsgLy8gaW4gY2FzZSBvZiBpbGxlZ2FsIGFyZ3VtZW50CgogICAgLyoqCiAgICAgKiBVc2VkIGJ5IHN1YkZvcm1hdCgpIHRvIGZvcm1hdCBhIG51bWVyaWMgdmFsdWUuICBGaWxscyBpbiAicmVzdWx0IiB3aXRoIGEgc3RyaW5nCiAgICAgKiByZXByZXNlbnRhdGlvbiBvZiAidmFsdWUiIGhhdmluZyBhIG51bWJlciBvZiBkaWdpdHMgYmV0d2VlbiAibWluRGlnaXRzIiBhbmQKICAgICAqICJtYXhEaWdpdHMiLiAgVXNlcyB0aGUgRGF0ZUZvcm1hdCdzIE51bWJlckZvcm1hdC4KICAgICAqIEBwYXJhbSByZXN1bHQgICAgRmlsbGVkIGluIHdpdGggdGhlIGZvcm1hdHRlZCBudW1iZXIuCiAgICAgKiBAcGFyYW0gdmFsdWUgICAgIFZhbHVlIHRvIGZvcm1hdC4KICAgICAqIEBwYXJhbSBtaW5EaWdpdHMgTWluaW11bSBudW1iZXIgb2YgZGlnaXRzIHRoZSByZXN1bHQgc2hvdWxkIGhhdmUKICAgICAqIEBwYXJhbSBtYXhEaWdpdHMgTWF4aW11bSBudW1iZXIgb2YgZGlnaXRzIHRoZSByZXN1bHQgc2hvdWxkIGhhdmUKICAgICAqIEByZXR1cm4gQSByZWZlcmVuY2UgdG8gInJlc3VsdCIuCiAgICAgKi8KICAgIFVuaWNvZGVTdHJpbmcmIHplcm9QYWRkaW5nTnVtYmVyKFVuaWNvZGVTdHJpbmcmIHJlc3VsdCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludDMyX3QgdmFsdWUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQzMl90IG1pbkRpZ2l0cywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludDMyX3QgbWF4RGlnaXRzKSBjb25zdDsKCiAgICAvKioKICAgICAqIENhbGxlZCBieSBzZXZlcmFsIG9mIHRoZSBjb25zdHJ1Y3RvcnMgdG8gbG9hZCBwYXR0ZXJuIGRhdGEgYW5kIGZvcm1hdHRpbmcgc3ltYm9scwogICAgICogb3V0IG9mIGEgcmVzb3VyY2UgYnVuZGxlIGFuZCBpbml0aWFsaXplIHRoZSBsb2NhbGUgYmFzZWQgb24gaXQuCiAgICAgKiBAcGFyYW0gdGltZVN0eWxlICAgICBUaGUgdGltZSBzdHlsZSwgYXMgcGFzc2VkIHRvIERhdGVGb3JtYXQ6OmNyZWF0ZURhdGVJbnN0YW5jZSgpLgogICAgICogQHBhcmFtIGRhdGVTdHlsZSAgICAgVGhlIGRhdGUgc3R5bGUsIGFzIHBhc3NlZCB0byBEYXRlRm9ybWF0OjpjcmVhdGVUaW1lSW5zdGFuY2UoKS4KICAgICAqIEBwYXJhbSBsb2NhbGUgICAgICAgIFRoZSBsb2NhbGUgdG8gbG9hZCB0aGUgcGF0dGVybnMgZnJvbS4KICAgICAqIEBwYXJhbSBzdGF0dXMgICAgICAgIEZpbGxlZCBpbiB3aXRoIGFuIGVycm9yIGNvZGUgaWYgbG9hZGluZyB0aGUgZGF0YSBmcm9tIHRoZQogICAgICogICAgICAgICAgICAgICAgICAgICAgcmVzb3VyY2VzIGZhaWxzLgogICAgICovCiAgICB2b2lkIGNvbnN0cnVjdChFU3R5bGUgdGltZVN0eWxlLCBFU3R5bGUgZGF0ZVN0eWxlLCBjb25zdCBMb2NhbGUmIGxvY2FsZSwgVUVycm9yQ29kZSYgc3RhdHVzKTsKCiAgICAvKioKICAgICAqIENhbGxlZCBieSBjb25zdHJ1Y3QoKSBhbmQgdGhlIHZhcmlvdXMgY29uc3RydWN0b3JzIHRvIHNldCB1cCB0aGUgU2ltcGxlRGF0ZUZvcm1hdCdzCiAgICAgKiBDYWxlbmRhciBhbmQgTnVtYmVyRm9ybWF0IG9iamVjdHMuCiAgICAgKiBAcGFyYW0gbG9jYWxlICAgIFRoZSBsb2NhbGUgZm9yIHdoaWNoIHdlIHdhbnQgYSBDYWxlbmRhciBhbmQgYSBOdW1iZXJGb3JtYXQuCiAgICAgKiBAcGFyYW0gc3RhdHVjICAgIEZpbGxlZCBpbiB3aXRoIGFuIGVycm9yIGNvZGUgaWYgY3JlYXRpbmcgZWl0aGVyIHN1Ym9iamVjdCBmYWlscy4KICAgICAqLwogICAgdm9pZCBpbml0aWFsaXplKGNvbnN0IExvY2FsZSYgbG9jYWxlLCBVRXJyb3JDb2RlJiBzdGF0dXMpOwoKICAgIC8qKgogICAgICogUHJpdmF0ZSBjb2RlLXNpemUgcmVkdWN0aW9uIGZ1bmN0aW9uIHVzZWQgYnkgc3ViUGFyc2UuCiAgICAgKiBAcGFyYW0gdGV4dCB0aGUgdGltZSB0ZXh0IGJlaW5nIHBhcnNlZC4KICAgICAqIEBwYXJhbSBzdGFydCB3aGVyZSB0byBzdGFydCBwYXJzaW5nLgogICAgICogQHBhcmFtIGZpZWxkIHRoZSBkYXRlIGZpZWxkIGJlaW5nIHBhcnNlZC4KICAgICAqIEBwYXJhbSBkYXRhIHRoZSBzdHJpbmcgYXJyYXkgdG8gcGFyc2VkLgogICAgICogQHJldHVybiB0aGUgbmV3IHN0YXJ0IHBvc2l0aW9uIGlmIG1hdGNoaW5nIHN1Y2NlZWRlZDsgYSBuZWdhdGl2ZSBudW1iZXIKICAgICAqIGluZGljYXRpbmcgbWF0Y2hpbmcgZmFpbHVyZSwgb3RoZXJ3aXNlLgogICAgICovCiAgICBpbnQzMl90IG1hdGNoU3RyaW5nKGNvbnN0IFVuaWNvZGVTdHJpbmcmIHRleHQsIFVUZXh0T2Zmc2V0IHN0YXJ0LCBDYWxlbmRhcjo6RURhdGVGaWVsZHMgZmllbGQsCiAgICAgICAgICAgICAgICAgICAgY29uc3QgVW5pY29kZVN0cmluZyogc3RyaW5nQXJyYXksIGludDMyX3Qgc3RyaW5nQXJyYXlDb3VudCkgY29uc3Q7CgogICAgLyoqCiAgICAgKiBQcml2YXRlIG1lbWJlciBmdW5jdGlvbiB0aGF0IGNvbnZlcnRzIHRoZSBwYXJzZWQgZGF0ZSBzdHJpbmdzIGludG8KICAgICAqIHRpbWVGaWVsZHMuIFJldHVybnMgLXN0YXJ0IChmb3IgUGFyc2VQb3NpdGlvbikgaWYgZmFpbGVkLgogICAgICogQHBhcmFtIHRleHQgdGhlIHRpbWUgdGV4dCB0byBiZSBwYXJzZWQuCiAgICAgKiBAcGFyYW0gc3RhcnQgd2hlcmUgdG8gc3RhcnQgcGFyc2luZy4KICAgICAqIEBwYXJhbSBjaCB0aGUgcGF0dGVybiBjaGFyYWN0ZXIgZm9yIHRoZSBkYXRlIGZpZWxkIHRleHQgdG8gYmUgcGFyc2VkLgogICAgICogQHBhcmFtIGNvdW50IHRoZSBjb3VudCBvZiBhIHBhdHRlcm4gY2hhcmFjdGVyLgogICAgICogQHBhcmFtIG9iZXlDb3VudCBpZiB0cnVlIHRoZW4gdGhlIGNvdW50IGlzIHN0cmljdGx5IG9iZXllZC4KICAgICAqIEByZXR1cm4gdGhlIG5ldyBzdGFydCBwb3NpdGlvbiBpZiBtYXRjaGluZyBzdWNjZWVkZWQ7IGEgbmVnYXRpdmUgbnVtYmVyCiAgICAgKiBpbmRpY2F0aW5nIG1hdGNoaW5nIGZhaWx1cmUsIG90aGVyd2lzZS4KICAgICAqIEBkcmFmdAogICAgICovCiAgICBpbnQzMl90IHN1YlBhcnNlKGNvbnN0IFVuaWNvZGVTdHJpbmcmIHRleHQsIGludDMyX3QmIHN0YXJ0LCBVQ2hhciBjaCwgaW50MzJfdCBjb3VudCwKICAgICAgICAgICAgICAgICBib29sX3Qgb2JleUNvdW50LCBib29sX3QgYW1iaWd1b3VzWWVhcltdKSBjb25zdDsKCiAgICAvKioKICAgICAqIFBhcnNlIHRoZSBnaXZlbiB0ZXh0LCBhdCB0aGUgZ2l2ZW4gcG9zaXRpb24sIGFzIGEgbnVtZXJpYyB2YWx1ZSwgdXNpbmcKICAgICAqIHRoaXMgb2JqZWN0J3MgTnVtYmVyRm9ybWF0LiBSZXR1cm4gdGhlIGNvcnJlc3BvbmRpbmcgbG9uZyB2YWx1ZSBpbiB0aGUKICAgICAqIGZpbGwtaW4gcGFyYW1ldGVyICd2YWx1ZScuIElmIHRoZSBwYXJzZSBmYWlscywgdGhpcyBtZXRob2QgbGVhdmVzIHBvcwogICAgICogdW5jaGFuZ2VkIGFuZCByZXR1cm5zIEZBTFNFOyBvdGhlcndpc2UgaXQgYWR2YW5jZXMgcG9zIGFuZAogICAgICogcmV0dXJucyBUUlVFLgogICAgICovCiAgICAvL2Jvb2xfdCBzdWJQYXJzZUxvbmcoY29uc3QgVW5pY29kZVN0cmluZyYgdGV4dCwgUGFyc2VQb3NpdGlvbiYgcG9zLCBpbnQzMl90JiB2YWx1ZSkgY29uc3Q7CgogICAgLyoqCiAgICAgKiBUcmFuc2xhdGUgYSBwYXR0ZXJuLCBtYXBwaW5nIGVhY2ggY2hhcmFjdGVyIGluIHRoZSBmcm9tIHN0cmluZyB0byB0aGUKICAgICAqIGNvcnJlc3BvbmRpbmcgY2hhcmFjdGVyIGluIHRoZSB0byBzdHJpbmcuIFJldHVybiBhbiBlcnJvciBpZiB0aGUgb3JpZ2luYWwKICAgICAqIHBhdHRlcm4gY29udGFpbnMgYW4gdW5tYXBwZWQgY2hhcmFjdGVyLCBvciBpZiBhIHF1b3RlIGlzIHVubWF0Y2hlZC4KICAgICAqIFF1b3RlZCAoc2luZ2xlIHF1b3RlcyBvbmx5KSBtYXRlcmlhbCBpcyBub3QgdHJhbnNsYXRlZC4KICAgICAqLwogICAgc3RhdGljIHZvaWQgdHJhbnNsYXRlUGF0dGVybihjb25zdCBVbmljb2RlU3RyaW5nJiBvcmlnaW5hbFBhdHRlcm4sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVW5pY29kZVN0cmluZyYgdHJhbnNsYXRlZFBhdHRlcm4sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgVW5pY29kZVN0cmluZyYgZnJvbSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBVbmljb2RlU3RyaW5nJiB0bywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBVRXJyb3JDb2RlJiBzdGF0dXMpOwogICAgLyoqCiAgICAgKiBHaXZlbiBhIHpvbmUgSUQsIHRyeSB0byBsb2NhdGUgaXQgaW4gb3VyIHRpbWUgem9uZSBhcnJheS4gUmV0dXJuIHRoZQogICAgICogaW5kZXggKHJvdyBpbmRleCkgb2YgdGhlIGZvdW5kIHRpbWUgem9uZSwgb3IgLTEgaWYgd2UgY2FuJ3QgZmluZCBpdC4KICAgICAqLwogICAgLy9pbnQzMl90IGdldFpvbmVJbmRleChjb25zdCBVbmljb2RlU3RyaW5nJiBJRCkgY29uc3Q7CgogICAgLyoqCiAgICAgKiBTZXRzIHRoZSBzdGFydGluZyBkYXRlIG9mIHRoZSAxMDAteWVhciB3aW5kb3cgdGhhdCBkYXRlcyB3aXRoIDItZGlnaXQgeWVhcnMKICAgICAqIGFyZSBjb25zaWRlcmVkIHRvIGZhbGwgd2l0aGluLgogICAgICovCiAgICB2b2lkICAgICAgICAgcGFyc2VBbWJpZ3VvdXNEYXRlc0FzQWZ0ZXIoVURhdGUgc3RhcnREYXRlLCBVRXJyb3JDb2RlJiBzdGF0dXMpOwoKICAgIC8qKgogICAgICogUmV0dXJucyB0aGUgYmVnaW5uaW5nIGRhdGUgb2YgdGhlIDEwMC15ZWFyIHdpbmRvdyB0aGF0IGRhdGVzIHdpdGggMi1kaWdpdCB5ZWFycwogICAgICogYXJlIGNvbnNpZGVyZWQgdG8gZmFsbCB3aXRoaW4uCiAgICAgKi8KICAgIFVEYXRlICAgICAgICAgaW50ZXJuYWxHZXREZWZhdWx0Q2VudHVyeVN0YXJ0KHZvaWQpIGNvbnN0OwoKICAgIC8qKgogICAgICogUmV0dXJucyB0aGUgZmlyc3QgeWVhciBvZiB0aGUgMTAwLXllYXIgd2luZG93IHRoYXQgZGF0ZXMgd2l0aCAyLWRpZ2l0IHllYXJzCiAgICAgKiBhcmUgY29uc2lkZXJlZCB0byBmYWxsIHdpdGhpbi4KICAgICAqLwogICAgaW50MzJfdCAgICAgICAgICBpbnRlcm5hbEdldERlZmF1bHRDZW50dXJ5U3RhcnRZZWFyKHZvaWQpIGNvbnN0OwoKICAgIC8qKgogICAgICogSW5pdGlhbGl6ZXMgdGhlIDEwMC15ZWFyIHdpbmRvdyB0aGF0IGRhdGVzIHdpdGggMi1kaWdpdCB5ZWFycyBhcmUgY29uc2lkZXJlZAogICAgICogdG8gZmFsbCB3aXRoaW4gc28gdGhhdCBpdHMgc3RhcnQgZGF0ZSBpcyA4MCB5ZWFycyBiZWZvcmUgdGhlIGN1cnJlbnQgdGltZS4KICAgICAqLwogICAgc3RhdGljIHZvaWQgIGluaXRpYWxpemVTeXN0ZW1EZWZhdWx0Q2VudHVyeSh2b2lkKTsKCiAgICAvKioKICAgICAqIExhc3QtcmVzb3J0IHN0cmluZyB0byB1c2UgZm9yICJHTVQiIHdoZW4gY29uc3RydWN0aW5nIHRpbWUgem9uZSBzdHJpbmdzLgogICAgICovCiAgICAvLyBGb3IgdGltZSB6b25lcyB0aGF0IGhhdmUgbm8gbmFtZXMsIHVzZSBzdHJpbmdzIEdNVCttaW51dGVzIGFuZAogICAgLy8gR01ULW1pbnV0ZXMuIEZvciBpbnN0YW5jZSwgaW4gRnJhbmNlIHRoZSB0aW1lIHpvbmUgaXMgR01UKzYwLgogICAgc3RhdGljIGNvbnN0IFVuaWNvZGVTdHJpbmcgZmdHbXRQbHVzOwogICAgc3RhdGljIGNvbnN0IFVuaWNvZGVTdHJpbmcgZmdHbXRNaW51czsKICAgIHN0YXRpYyBjb25zdCBVbmljb2RlU3RyaW5nIGZnR210OwoKICAgIC8qKgogICAgICogVXNlZCB0byBtYXAgcGF0dGVybiBjaGFyYWN0ZXJzIHRvIENhbGVuZGFyIGZpZWxkIGlkZW50aWZpZXJzLgogICAgICovCiAgICBzdGF0aWMgY29uc3QgQ2FsZW5kYXI6OkVEYXRlRmllbGRzIGZnUGF0dGVybkluZGV4VG9DYWxlbmRhckZpZWxkW107CgogICAgLyoqCiAgICAgKiBNYXAgaW5kZXggaW50byBwYXR0ZXJuIGNoYXJhY3RlciBzdHJpbmcgdG8gRGF0ZUZvcm1hdCBmaWVsZCBudW1iZXIKICAgICAqLwogICAgc3RhdGljIGNvbnN0IERhdGVGb3JtYXQ6OkVGaWVsZCBmZ1BhdHRlcm5JbmRleFRvRGF0ZUZvcm1hdEZpZWxkW107CgogICAgLyoqCiAgICAgKiBUaGUgZm9ybWF0dGluZyBwYXR0ZXJuIGZvciB0aGlzIGZvcm1hdHRlci4KICAgICAqLwogICAgVW5pY29kZVN0cmluZyAgICAgICBmUGF0dGVybjsKCiAgICAvKioKICAgICAqIEEgcG9pbnRlciB0byBhbiBvYmplY3QgY29udGFpbmluZyB0aGUgc3RyaW5ncyB0byB1c2UgaW4gZm9ybWF0dGluZyAoZS5nLiwKICAgICAqIG1vbnRoIGFuZCBkYXkgbmFtZXMsIEFNIGFuZCBQTSBzdHJpbmdzLCB0aW1lIHpvbmUgbmFtZXMsIGV0Yy4pCiAgICAgKi8KICAgIERhdGVGb3JtYXRTeW1ib2xzKiAgZlN5bWJvbHM7ICAgLy8gT3duZWQKCiAgICAvKioKICAgICAqIElmIGRhdGVzIGhhdmUgYW1iaWd1b3VzIHllYXJzLCB3ZSBtYXAgdGhlbSBpbnRvIHRoZSBjZW50dXJ5IHN0YXJ0aW5nCiAgICAgKiBhdCBkZWZhdWx0Q2VudHVyeVN0YXJ0LCB3aGljaCBtYXkgYmUgYW55IGRhdGUuICBJZiBkZWZhdWx0Q2VudHVyeVN0YXJ0IGlzCiAgICAgKiBzZXQgdG8gU1lTVEVNX0RFRkFVTFRfQ0VOVFVSWSwgd2hpY2ggaXQgaXMgYnkgZGVmYXVsdCwgdGhlbiB0aGUgc3lzdGVtCiAgICAgKiB2YWx1ZXMgYXJlIHVzZWQuICBUaGUgaW5zdGFuY2UgdmFsdWVzIGRlZmF1bHRDZW50dXJ5U3RhcnQgYW5kCiAgICAgKiBkZWZhdWx0Q2VudHVyeVN0YXJ0WWVhciBhcmUgb25seSB1c2VkIGlmIGV4cGxpY2l0bHkgc2V0IGJ5IHRoZSB1c2VyCiAgICAgKiB0aHJvdWdoIHRoZSBBUEkgbWV0aG9kIHBhcnNlQW1iaWd1b3VzRGF0ZXNBc0FmdGVyKCkuCiAgICAgKi8KICAgIFVEYXRlICAgICAgICAgICAgICAgIGZEZWZhdWx0Q2VudHVyeVN0YXJ0OwoKICAgIC8qKgogICAgICogU2VlIGRvY3VtZW50YXRpb24gZm9yIGRlZmF1bHRDZW50dXJ5U3RhcnQuCiAgICAgKi8KICAgIC8qdHJhbnNpZW50Ki8gaW50MzJfdCAgIGZEZWZhdWx0Q2VudHVyeVN0YXJ0WWVhcjsKCiAgICAvKioKICAgICAqIFRoZSBzeXN0ZW0gbWFpbnRhaW5zIGEgc3RhdGljIGRlZmF1bHQgY2VudHVyeSBzdGFydCBkYXRlLiAgVGhpcyBpcyBpbml0aWFsaXplZAogICAgICogdGhlIGZpcnN0IHRpbWUgaXQgaXMgdXNlZC4gIEJlZm9yZSB0aGVuLCBpdCBpcyBzZXQgdG8gU1lTVEVNX0RFRkFVTFRfQ0VOVFVSWSB0bwogICAgICogaW5kaWNhdGUgYW4gdW5pbml0aWFsaXplZCBzdGF0ZS4gIE9uY2UgdGhlIHN5c3RlbSBkZWZhdWx0IGNlbnR1cnkgZGF0ZSBhbmQgeWVhcgogICAgICogYXJlIHNldCwgdGhleSBkbyBub3QgY2hhbmdlLgogICAgICovCiAgICBzdGF0aWMgVURhdGUgICAgICAgICBmZ1N5c3RlbURlZmF1bHRDZW50dXJ5U3RhcnQ7CgogICAgLyoqCiAgICAgKiBTZWUgZG9jdW1lbnRhdGlvbiBmb3Igc3lzdGVtRGVmYXVsdENlbnR1cnlTdGFydC4KICAgICAqLwogICAgc3RhdGljIGludDMyX3QgICAgICAgICAgZmdTeXN0ZW1EZWZhdWx0Q2VudHVyeVN0YXJ0WWVhcjsKCiAgICAvKioKICAgICAqIERlZmF1bHQgdmFsdWUgdGhhdCBpbmRpY2F0ZXMgdGhlIGRlZmF1bHRDZW50dXJ5U3RhcnRZZWFyIGlzIHVuaXRpYWxpemVkCiAgICAgKi8KICAgIHN0YXRpYyBjb25zdCBpbnQzMl90ICAgIGZnU3lzdGVtRGVmYXVsdENlbnR1cnlZZWFyOwoKcHVibGljOgogICAgLyoqCiAgICAgKiBJZiBhIHN0YXJ0IGRhdGUgaXMgc2V0IHRvIHRoaXMgdmFsdWUsIHRoYXQgaW5kaWNhdGVzIHRoYXQgdGhlIHN5c3RlbSBkZWZhdWx0CiAgICAgKiBzdGFydCBpcyBpbiBlZmZlY3QgZm9yIHRoaXMgaW5zdGFuY2UuCiAgICAgKi8KICAgIHN0YXRpYyBjb25zdCBVRGF0ZSAgICAgICAgZmdTeXN0ZW1EZWZhdWx0Q2VudHVyeTsKfTsKCmlubGluZSBVRGF0ZQpTaW1wbGVEYXRlRm9ybWF0OjpnZXQyRGlnaXRZZWFyU3RhcnQoVUVycm9yQ29kZSYgc3RhdHVzKSBjb25zdAp7CiAgICByZXR1cm4gZkRlZmF1bHRDZW50dXJ5U3RhcnQ7Cn0KCmlubGluZSBVbmljb2RlU3RyaW5nJgpTaW1wbGVEYXRlRm9ybWF0Ojpmb3JtYXQoY29uc3QgRm9ybWF0dGFibGUmIG9iaiwKICAgICAgICAgICAgICAgICAgICAgICAgIFVuaWNvZGVTdHJpbmcmIHJlc3VsdCwKICAgICAgICAgICAgICAgICAgICAgICAgIFVFcnJvckNvZGUmIHN0YXR1cykgY29uc3QgewogICAgLy8gRG9uJ3QgdXNlIEZvcm1hdDo6IC0gdXNlIGltbWVkaWF0ZSBiYXNlIGNsYXNzIG9ubHksCiAgICAvLyBpbiBjYXNlIGltbWVkaWF0ZSBiYXNlIG1vZGlmaWVzIGJlaGF2aW9yIGxhdGVyLgogICAgcmV0dXJuIERhdGVGb3JtYXQ6OmZvcm1hdChvYmosIHJlc3VsdCwgc3RhdHVzKTsKfQoKaW5saW5lIFVuaWNvZGVTdHJpbmcmClNpbXBsZURhdGVGb3JtYXQ6OmZvcm1hdChVRGF0ZSBkYXRlLCBVbmljb2RlU3RyaW5nJiByZXN1bHQpIGNvbnN0IHsKICAgIHJldHVybiBEYXRlRm9ybWF0Ojpmb3JtYXQoZGF0ZSwgcmVzdWx0KTsKfQoKI2VuZGlmIC8vIF9TTVBEVEZNVAovL2VvZgo=