LyoKT3BlbiBBc3NldCBJbXBvcnQgTGlicmFyeSAoYXNzaW1wKQotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgpDb3B5cmlnaHQgKGMpIDIwMDYtMjAxNywgYXNzaW1wIHRlYW0KCkFsbCByaWdodHMgcmVzZXJ2ZWQuCgpSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIG9mIHRoaXMgc29mdHdhcmUgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsCndpdGggb3Igd2l0aG91dCBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUKZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlIG1ldDoKCiogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZQogIGNvcHlyaWdodCBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUKICBmb2xsb3dpbmcgZGlzY2xhaW1lci4KCiogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZQogIGNvcHlyaWdodCBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUKICBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIKICBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUgZGlzdHJpYnV0aW9uLgoKKiBOZWl0aGVyIHRoZSBuYW1lIG9mIHRoZSBhc3NpbXAgdGVhbSwgbm9yIHRoZSBuYW1lcyBvZiBpdHMKICBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzCiAgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvcgogIHdyaXR0ZW4gcGVybWlzc2lvbiBvZiB0aGUgYXNzaW1wIHRlYW0uCgpUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTCiJBUyBJUyIgQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UCkxJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUgpBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVApPV05FUiBPUiBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVApMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwKREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZClRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQKKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFCk9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuCgotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiovCgovKiogQGZpbGUgIEZCWE1hdGVyaWFsLmNwcAogKiAgQGJyaWVmIEFzc2ltcDo6RkJYOjpNYXRlcmlhbCBhbmQgQXNzaW1wOjpGQlg6OlRleHR1cmUgaW1wbGVtZW50YXRpb24KICovCgojaWZuZGVmIEFTU0lNUF9CVUlMRF9OT19GQlhfSU1QT1JURVIKCiNpbmNsdWRlICJGQlhQYXJzZXIuaCIKI2luY2x1ZGUgIkZCWERvY3VtZW50LmgiCiNpbmNsdWRlICJGQlhJbXBvcnRlci5oIgojaW5jbHVkZSAiRkJYSW1wb3J0U2V0dGluZ3MuaCIKI2luY2x1ZGUgIkZCWERvY3VtZW50VXRpbC5oIgojaW5jbHVkZSAiRkJYUHJvcGVydGllcy5oIgojaW5jbHVkZSAiQnl0ZVN3YXBwZXIuaCIKCm5hbWVzcGFjZSBBc3NpbXAgewpuYW1lc3BhY2UgRkJYIHsKCiAgICB1c2luZyBuYW1lc3BhY2UgVXRpbDsKCi8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQpNYXRlcmlhbDo6TWF0ZXJpYWwodWludDY0X3QgaWQsIGNvbnN0IEVsZW1lbnQmIGVsZW1lbnQsIGNvbnN0IERvY3VtZW50JiBkb2MsIGNvbnN0IHN0ZDo6c3RyaW5nJiBuYW1lKQo6IE9iamVjdChpZCxlbGVtZW50LG5hbWUpCnsKICAgIGNvbnN0IFNjb3BlJiBzYyA9IEdldFJlcXVpcmVkU2NvcGUoZWxlbWVudCk7CgogICAgY29uc3QgRWxlbWVudCogY29uc3QgU2hhZGluZ01vZGVsID0gc2NbIlNoYWRpbmdNb2RlbCJdOwogICAgY29uc3QgRWxlbWVudCogY29uc3QgTXVsdGlMYXllciA9IHNjWyJNdWx0aUxheWVyIl07CgogICAgaWYoTXVsdGlMYXllcikgewogICAgICAgIG11bHRpbGF5ZXIgPSAhIVBhcnNlVG9rZW5Bc0ludChHZXRSZXF1aXJlZFRva2VuKCpNdWx0aUxheWVyLDApKTsKICAgIH0KCiAgICBpZihTaGFkaW5nTW9kZWwpIHsKICAgICAgICBzaGFkaW5nID0gUGFyc2VUb2tlbkFzU3RyaW5nKEdldFJlcXVpcmVkVG9rZW4oKlNoYWRpbmdNb2RlbCwwKSk7CiAgICB9CiAgICBlbHNlIHsKICAgICAgICBET01XYXJuaW5nKCJzaGFkaW5nIG1vZGUgbm90IHNwZWNpZmllZCwgYXNzdW1pbmcgcGhvbmciLCZlbGVtZW50KTsKICAgICAgICBzaGFkaW5nID0gInBob25nIjsKICAgIH0KCiAgICBzdGQ6OnN0cmluZyB0ZW1wbGF0ZU5hbWU7CgogICAgY29uc3QgY2hhciogY29uc3Qgc2ggPSBzaGFkaW5nLmNfc3RyKCk7CiAgICBpZighc3RyY21wKHNoLCJwaG9uZyIpKSB7CiAgICAgICAgdGVtcGxhdGVOYW1lID0gIk1hdGVyaWFsLkZieFN1cmZhY2VQaG9uZyI7CiAgICB9CiAgICBlbHNlIGlmKCFzdHJjbXAoc2gsImxhbWJlcnQiKSkgewogICAgICAgIHRlbXBsYXRlTmFtZSA9ICJNYXRlcmlhbC5GYnhTdXJmYWNlTGFtYmVydCI7CiAgICB9CiAgICBlbHNlIHsKICAgICAgICBET01XYXJuaW5nKCJzaGFkaW5nIG1vZGUgbm90IHJlY29nbml6ZWQ6ICIgKyBzaGFkaW5nLCZlbGVtZW50KTsKICAgIH0KCiAgICBwcm9wcyA9IEdldFByb3BlcnR5VGFibGUoZG9jLHRlbXBsYXRlTmFtZSxlbGVtZW50LHNjKTsKCiAgICAvLyByZXNvbHZlIHRleHR1cmUgbGlua3MKICAgIGNvbnN0IHN0ZDo6dmVjdG9yPGNvbnN0IENvbm5lY3Rpb24qPiYgY29ubnMgPSBkb2MuR2V0Q29ubmVjdGlvbnNCeURlc3RpbmF0aW9uU2VxdWVuY2VkKElEKCkpOwogICAgZm9yKGNvbnN0IENvbm5lY3Rpb24qIGNvbiA6IGNvbm5zKSB7CgogICAgICAgIC8vIHRleHR1cmUgbGluayB0byBwcm9wZXJ0aWVzLCBub3Qgb2JqZWN0cwogICAgICAgIGlmICghY29uLT5Qcm9wZXJ0eU5hbWUoKS5sZW5ndGgoKSkgewogICAgICAgICAgICBjb250aW51ZTsKICAgICAgICB9CgogICAgICAgIGNvbnN0IE9iamVjdCogY29uc3Qgb2IgPSBjb24tPlNvdXJjZU9iamVjdCgpOwogICAgICAgIGlmKCFvYikgewogICAgICAgICAgICBET01XYXJuaW5nKCJmYWlsZWQgdG8gcmVhZCBzb3VyY2Ugb2JqZWN0IGZvciB0ZXh0dXJlIGxpbmssIGlnbm9yaW5nIiwmZWxlbWVudCk7CiAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgIH0KCiAgICAgICAgY29uc3QgVGV4dHVyZSogY29uc3QgdGV4ID0gZHluYW1pY19jYXN0PGNvbnN0IFRleHR1cmUqPihvYik7CiAgICAgICAgaWYoIXRleCkgewogICAgICAgICAgICBjb25zdCBMYXllcmVkVGV4dHVyZSogY29uc3QgbGF5ZXJlZFRleHR1cmUgPSBkeW5hbWljX2Nhc3Q8Y29uc3QgTGF5ZXJlZFRleHR1cmUqPihvYik7CiAgICAgICAgICAgIGlmKCFsYXllcmVkVGV4dHVyZSkgewogICAgICAgICAgICAgICAgRE9NV2FybmluZygic291cmNlIG9iamVjdCBmb3IgdGV4dHVyZSBsaW5rIGlzIG5vdCBhIHRleHR1cmUgb3IgbGF5ZXJlZCB0ZXh0dXJlLCBpZ25vcmluZyIsJmVsZW1lbnQpOwogICAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgY29uc3Qgc3RkOjpzdHJpbmcmIHByb3AgPSBjb24tPlByb3BlcnR5TmFtZSgpOwogICAgICAgICAgICBpZiAobGF5ZXJlZFRleHR1cmVzLmZpbmQocHJvcCkgIT0gbGF5ZXJlZFRleHR1cmVzLmVuZCgpKSB7CiAgICAgICAgICAgICAgICBET01XYXJuaW5nKCJkdXBsaWNhdGUgbGF5ZXJlZCB0ZXh0dXJlIGxpbms6ICIgKyBwcm9wLCZlbGVtZW50KTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgbGF5ZXJlZFRleHR1cmVzW3Byb3BdID0gbGF5ZXJlZFRleHR1cmU7CiAgICAgICAgICAgICgoTGF5ZXJlZFRleHR1cmUqKWxheWVyZWRUZXh0dXJlKS0+ZmlsbFRleHR1cmUoZG9jKTsKICAgICAgICB9CiAgICAgICAgZWxzZQogICAgICAgIHsKICAgICAgICAgICAgY29uc3Qgc3RkOjpzdHJpbmcmIHByb3AgPSBjb24tPlByb3BlcnR5TmFtZSgpOwogICAgICAgICAgICBpZiAodGV4dHVyZXMuZmluZChwcm9wKSAhPSB0ZXh0dXJlcy5lbmQoKSkgewogICAgICAgICAgICAgICAgRE9NV2FybmluZygiZHVwbGljYXRlIHRleHR1cmUgbGluazogIiArIHByb3AsJmVsZW1lbnQpOwogICAgICAgICAgICB9CgogICAgICAgICAgICB0ZXh0dXJlc1twcm9wXSA9IHRleDsKICAgICAgICB9CgogICAgfQp9CgoKLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCk1hdGVyaWFsOjp+TWF0ZXJpYWwoKQp7Cn0KCgovLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KVGV4dHVyZTo6VGV4dHVyZSh1aW50NjRfdCBpZCwgY29uc3QgRWxlbWVudCYgZWxlbWVudCwgY29uc3QgRG9jdW1lbnQmIGRvYywgY29uc3Qgc3RkOjpzdHJpbmcmIG5hbWUpCjogT2JqZWN0KGlkLGVsZW1lbnQsbmFtZSkKLCB1dlNjYWxpbmcoMS4wZiwxLjBmKQosIG1lZGlhKDApCnsKICAgIGNvbnN0IFNjb3BlJiBzYyA9IEdldFJlcXVpcmVkU2NvcGUoZWxlbWVudCk7CgogICAgY29uc3QgRWxlbWVudCogY29uc3QgVHlwZSA9IHNjWyJUeXBlIl07CiAgICBjb25zdCBFbGVtZW50KiBjb25zdCBGaWxlTmFtZSA9IHNjWyJGaWxlTmFtZSJdOwogICAgY29uc3QgRWxlbWVudCogY29uc3QgUmVsYXRpdmVGaWxlbmFtZSA9IHNjWyJSZWxhdGl2ZUZpbGVuYW1lIl07CiAgICBjb25zdCBFbGVtZW50KiBjb25zdCBNb2RlbFVWVHJhbnNsYXRpb24gPSBzY1siTW9kZWxVVlRyYW5zbGF0aW9uIl07CiAgICBjb25zdCBFbGVtZW50KiBjb25zdCBNb2RlbFVWU2NhbGluZyA9IHNjWyJNb2RlbFVWU2NhbGluZyJdOwogICAgY29uc3QgRWxlbWVudCogY29uc3QgVGV4dHVyZV9BbHBoYV9Tb3VyY2UgPSBzY1siVGV4dHVyZV9BbHBoYV9Tb3VyY2UiXTsKICAgIGNvbnN0IEVsZW1lbnQqIGNvbnN0IENyb3BwaW5nID0gc2NbIkNyb3BwaW5nIl07CgogICAgaWYoVHlwZSkgewogICAgICAgIHR5cGUgPSBQYXJzZVRva2VuQXNTdHJpbmcoR2V0UmVxdWlyZWRUb2tlbigqVHlwZSwwKSk7CiAgICB9CgogICAgaWYoRmlsZU5hbWUpIHsKICAgICAgICBmaWxlTmFtZSA9IFBhcnNlVG9rZW5Bc1N0cmluZyhHZXRSZXF1aXJlZFRva2VuKCpGaWxlTmFtZSwwKSk7CiAgICB9CgogICAgaWYoUmVsYXRpdmVGaWxlbmFtZSkgewogICAgICAgIHJlbGF0aXZlRmlsZU5hbWUgPSBQYXJzZVRva2VuQXNTdHJpbmcoR2V0UmVxdWlyZWRUb2tlbigqUmVsYXRpdmVGaWxlbmFtZSwwKSk7CiAgICB9CgogICAgaWYoTW9kZWxVVlRyYW5zbGF0aW9uKSB7CiAgICAgICAgdXZUcmFucyA9IGFpVmVjdG9yMkQoUGFyc2VUb2tlbkFzRmxvYXQoR2V0UmVxdWlyZWRUb2tlbigqTW9kZWxVVlRyYW5zbGF0aW9uLDApKSwKICAgICAgICAgICAgUGFyc2VUb2tlbkFzRmxvYXQoR2V0UmVxdWlyZWRUb2tlbigqTW9kZWxVVlRyYW5zbGF0aW9uLDEpKQogICAgICAgICk7CiAgICB9CgogICAgaWYoTW9kZWxVVlNjYWxpbmcpIHsKICAgICAgICB1dlNjYWxpbmcgPSBhaVZlY3RvcjJEKFBhcnNlVG9rZW5Bc0Zsb2F0KEdldFJlcXVpcmVkVG9rZW4oKk1vZGVsVVZTY2FsaW5nLDApKSwKICAgICAgICAgICAgUGFyc2VUb2tlbkFzRmxvYXQoR2V0UmVxdWlyZWRUb2tlbigqTW9kZWxVVlNjYWxpbmcsMSkpCiAgICAgICAgKTsKICAgIH0KCiAgICBpZihDcm9wcGluZykgewogICAgICAgIGNyb3BbMF0gPSBQYXJzZVRva2VuQXNJbnQoR2V0UmVxdWlyZWRUb2tlbigqQ3JvcHBpbmcsMCkpOwogICAgICAgIGNyb3BbMV0gPSBQYXJzZVRva2VuQXNJbnQoR2V0UmVxdWlyZWRUb2tlbigqQ3JvcHBpbmcsMSkpOwogICAgICAgIGNyb3BbMl0gPSBQYXJzZVRva2VuQXNJbnQoR2V0UmVxdWlyZWRUb2tlbigqQ3JvcHBpbmcsMikpOwogICAgICAgIGNyb3BbM10gPSBQYXJzZVRva2VuQXNJbnQoR2V0UmVxdWlyZWRUb2tlbigqQ3JvcHBpbmcsMykpOwogICAgfQogICAgZWxzZSB7CiAgICAgICAgLy8gdmM4IGRvZXNuJ3Qgc3VwcG9ydCB0aGUgY3JvcCgpIHN5bnRheCBpbiBpbml0aWFsaXphdGlvbiBsaXN0cwogICAgICAgIC8vIChhbmQgdmM5IFdBUk5TIGFib3V0IHRoZSBuZXcgKGkuZS4gY29tcGxpYW50KSBiZWhhdmlvdXIpLgogICAgICAgIGNyb3BbMF0gPSBjcm9wWzFdID0gY3JvcFsyXSA9IGNyb3BbM10gPSAwOwogICAgfQoKICAgIGlmKFRleHR1cmVfQWxwaGFfU291cmNlKSB7CiAgICAgICAgYWxwaGFTb3VyY2UgPSBQYXJzZVRva2VuQXNTdHJpbmcoR2V0UmVxdWlyZWRUb2tlbigqVGV4dHVyZV9BbHBoYV9Tb3VyY2UsMCkpOwogICAgfQoKICAgIHByb3BzID0gR2V0UHJvcGVydHlUYWJsZShkb2MsIlRleHR1cmUuRmJ4RmlsZVRleHR1cmUiLGVsZW1lbnQsc2MpOwoKICAgIC8vIHJlc29sdmUgdmlkZW8gbGlua3MKICAgIGlmKGRvYy5TZXR0aW5ncygpLnJlYWRUZXh0dXJlcykgewogICAgICAgIGNvbnN0IHN0ZDo6dmVjdG9yPGNvbnN0IENvbm5lY3Rpb24qPiYgY29ubnMgPSBkb2MuR2V0Q29ubmVjdGlvbnNCeURlc3RpbmF0aW9uU2VxdWVuY2VkKElEKCkpOwogICAgICAgIGZvcihjb25zdCBDb25uZWN0aW9uKiBjb24gOiBjb25ucykgewogICAgICAgICAgICBjb25zdCBPYmplY3QqIGNvbnN0IG9iID0gY29uLT5Tb3VyY2VPYmplY3QoKTsKICAgICAgICAgICAgaWYoIW9iKSB7CiAgICAgICAgICAgICAgICBET01XYXJuaW5nKCJmYWlsZWQgdG8gcmVhZCBzb3VyY2Ugb2JqZWN0IGZvciB0ZXh0dXJlIGxpbmssIGlnbm9yaW5nIiwmZWxlbWVudCk7CiAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgY29uc3QgVmlkZW8qIGNvbnN0IHZpZGVvID0gZHluYW1pY19jYXN0PGNvbnN0IFZpZGVvKj4ob2IpOwogICAgICAgICAgICBpZih2aWRlbykgewogICAgICAgICAgICAgICAgbWVkaWEgPSB2aWRlbzsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0KfQoKClRleHR1cmU6On5UZXh0dXJlKCkKewoKfQoKTGF5ZXJlZFRleHR1cmU6OkxheWVyZWRUZXh0dXJlKHVpbnQ2NF90IGlkLCBjb25zdCBFbGVtZW50JiBlbGVtZW50LCBjb25zdCBEb2N1bWVudCYgLypkb2MqLywgY29uc3Qgc3RkOjpzdHJpbmcmIG5hbWUpCjogT2JqZWN0KGlkLGVsZW1lbnQsbmFtZSkKLGJsZW5kTW9kZShCbGVuZE1vZGVfTW9kdWxhdGUpCixhbHBoYSgxKQp7CiAgICBjb25zdCBTY29wZSYgc2MgPSBHZXRSZXF1aXJlZFNjb3BlKGVsZW1lbnQpOwoKICAgIGNvbnN0IEVsZW1lbnQqIGNvbnN0IEJsZW5kTW9kZXMgPSBzY1siQmxlbmRNb2RlcyJdOwogICAgY29uc3QgRWxlbWVudCogY29uc3QgQWxwaGFzID0gc2NbIkFscGhhcyJdOwoKCiAgICBpZihCbGVuZE1vZGVzIT0wKQogICAgewogICAgICAgIGJsZW5kTW9kZSA9IChCbGVuZE1vZGUpUGFyc2VUb2tlbkFzSW50KEdldFJlcXVpcmVkVG9rZW4oKkJsZW5kTW9kZXMsMCkpOwogICAgfQogICAgaWYoQWxwaGFzIT0wKQogICAgewogICAgICAgIGFscGhhID0gUGFyc2VUb2tlbkFzRmxvYXQoR2V0UmVxdWlyZWRUb2tlbigqQWxwaGFzLDApKTsKICAgIH0KfQoKTGF5ZXJlZFRleHR1cmU6On5MYXllcmVkVGV4dHVyZSgpCnsKICAgIAp9Cgp2b2lkIExheWVyZWRUZXh0dXJlOjpmaWxsVGV4dHVyZShjb25zdCBEb2N1bWVudCYgZG9jKQp7CiAgICBjb25zdCBzdGQ6OnZlY3Rvcjxjb25zdCBDb25uZWN0aW9uKj4mIGNvbm5zID0gZG9jLkdldENvbm5lY3Rpb25zQnlEZXN0aW5hdGlvblNlcXVlbmNlZChJRCgpKTsKICAgIGZvcihzaXplX3QgaSA9IDA7IGkgPCBjb25ucy5zaXplKCk7KytpKQogICAgewogICAgICAgIGNvbnN0IENvbm5lY3Rpb24qIGNvbiA9IGNvbm5zLmF0KGkpOwoKICAgICAgICBjb25zdCBPYmplY3QqIGNvbnN0IG9iID0gY29uLT5Tb3VyY2VPYmplY3QoKTsKICAgICAgICBpZighb2IpIHsKICAgICAgICAgICAgRE9NV2FybmluZygiZmFpbGVkIHRvIHJlYWQgc291cmNlIG9iamVjdCBmb3IgdGV4dHVyZSBsaW5rLCBpZ25vcmluZyIsJmVsZW1lbnQpOwogICAgICAgICAgICBjb250aW51ZTsKICAgICAgICB9CgogICAgICAgIGNvbnN0IFRleHR1cmUqIGNvbnN0IHRleCA9IGR5bmFtaWNfY2FzdDxjb25zdCBUZXh0dXJlKj4ob2IpOwoKICAgICAgICB0ZXh0dXJlcy5wdXNoX2JhY2sodGV4KTsKICAgIH0KfQoKCi8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQpWaWRlbzo6VmlkZW8odWludDY0X3QgaWQsIGNvbnN0IEVsZW1lbnQmIGVsZW1lbnQsIGNvbnN0IERvY3VtZW50JiBkb2MsIGNvbnN0IHN0ZDo6c3RyaW5nJiBuYW1lKQo6IE9iamVjdChpZCxlbGVtZW50LG5hbWUpCiwgY29udGVudExlbmd0aCgwKQosIGNvbnRlbnQoMCkKewogICAgY29uc3QgU2NvcGUmIHNjID0gR2V0UmVxdWlyZWRTY29wZShlbGVtZW50KTsKCiAgICBjb25zdCBFbGVtZW50KiBjb25zdCBUeXBlID0gc2NbIlR5cGUiXTsKICAgIGNvbnN0IEVsZW1lbnQqIGNvbnN0IEZpbGVOYW1lID0gc2MuRmluZEVsZW1lbnRDYXNlSW5zZW5zaXRpdmUoIkZpbGVOYW1lIik7ICAvL3NvbWUgZmlsZXMgcmV0YWluIHRoZSBpbmZvcm1hdGlvbiBhcyAiRmlsZW5hbWUiLCBvdGhlcnMgIkZpbGVOYW1lIiwgd2hvIGtub3dzCiAgICBjb25zdCBFbGVtZW50KiBjb25zdCBSZWxhdGl2ZUZpbGVuYW1lID0gc2NbIlJlbGF0aXZlRmlsZW5hbWUiXTsKICAgIGNvbnN0IEVsZW1lbnQqIGNvbnN0IENvbnRlbnQgPSBzY1siQ29udGVudCJdOwoKICAgIGlmKFR5cGUpIHsKICAgICAgICB0eXBlID0gUGFyc2VUb2tlbkFzU3RyaW5nKEdldFJlcXVpcmVkVG9rZW4oKlR5cGUsMCkpOwogICAgfQoKICAgIGlmKEZpbGVOYW1lKSB7CiAgICAgICAgZmlsZU5hbWUgPSBQYXJzZVRva2VuQXNTdHJpbmcoR2V0UmVxdWlyZWRUb2tlbigqRmlsZU5hbWUsMCkpOwoJfQoKICAgIGlmKFJlbGF0aXZlRmlsZW5hbWUpIHsKICAgICAgICByZWxhdGl2ZUZpbGVOYW1lID0gUGFyc2VUb2tlbkFzU3RyaW5nKEdldFJlcXVpcmVkVG9rZW4oKlJlbGF0aXZlRmlsZW5hbWUsMCkpOwogICAgfQoKICAgIGlmKENvbnRlbnQpIHsKCQkvL3RoaXMgZmllbGQgaXMgb21taXRlZCB3aGVuIHRoZSBlbWJlZGRlZCB0ZXh0dXJlIGlzIGFscmVhZHkgbG9hZGVkLCBsZXQncyBpZ25vcmUgaWYgaXS0cyBub3QgZm91bmQKCQl0cnkgewoJCQljb25zdCBUb2tlbiYgdG9rZW4gPSBHZXRSZXF1aXJlZFRva2VuKCpDb250ZW50LCAwKTsKCQkJY29uc3QgY2hhciogZGF0YSA9IHRva2VuLmJlZ2luKCk7CgkJCWlmICghdG9rZW4uSXNCaW5hcnkoKSkgewoJCQkJRE9NV2FybmluZygidmlkZW8gY29udGVudCBpcyBub3QgYmluYXJ5IGRhdGEsIGlnbm9yaW5nIiwgJmVsZW1lbnQpOwoJCQl9CgkJCWVsc2UgaWYgKHN0YXRpY19jYXN0PHNpemVfdD4odG9rZW4uZW5kKCkgLSBkYXRhKSA8IDUpIHsKCQkJCURPTUVycm9yKCJiaW5hcnkgZGF0YSBhcnJheSBpcyB0b28gc2hvcnQsIG5lZWQgZml2ZSAoNSkgYnl0ZXMgZm9yIHR5cGUgc2lnbmF0dXJlIGFuZCBlbGVtZW50IGNvdW50IiwgJmVsZW1lbnQpOwoJCQl9CgkJCWVsc2UgaWYgKCpkYXRhICE9ICdSJykgewoJCQkJRE9NV2FybmluZygidmlkZW8gY29udGVudCBpcyBub3QgcmF3IGJpbmFyeSBkYXRhLCBpZ25vcmluZyIsICZlbGVtZW50KTsKCQkJfQoJCQllbHNlIHsKCQkJCS8vIHJlYWQgbnVtYmVyIG9mIGVsZW1lbnRzCgkJCQl1aW50MzJfdCBsZW4gPSAwOwoJCQkJOjptZW1jcHkoJmxlbiwgZGF0YSArIDEsIHNpemVvZihsZW4pKTsKCQkJCUFJX1NXQVA0KGxlbik7CgoJCQkJY29udGVudExlbmd0aCA9IGxlbjsKCgkJCQljb250ZW50ID0gbmV3IHVpbnQ4X3RbbGVuXTsKCQkJCTo6bWVtY3B5KGNvbnRlbnQsIGRhdGEgKyA1LCBsZW4pOwoJCQl9CgkJfSBjYXRjaCAocnVudGltZV9lcnJvciBydW50aW1lRXJyb3IpIHsKCQkJLy93ZSBkb260dCBuZWVkIHRoZSBjb250ZW50IGRhdGEgZm9yIGNvbnRlbnRzIHRoYXQgaGFzIGFscmVhZHkgYmVlbiBsb2FkZWQKCQl9CiAgICB9CgogICAgcHJvcHMgPSBHZXRQcm9wZXJ0eVRhYmxlKGRvYywiVmlkZW8uRmJ4VmlkZW8iLGVsZW1lbnQsc2MpOwp9CgoKVmlkZW86On5WaWRlbygpCnsKICAgIGlmKGNvbnRlbnQpIHsKICAgICAgICBkZWxldGVbXSBjb250ZW50OwogICAgfQp9Cgp9IC8vIUZCWAp9IC8vIUFzc2ltcAoKI2VuZGlmCg==