Ly8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQovLyBVcHNhbXBsaW5nIC8gZG93bnNhbXBsaW5nIGNsYXNzZXMKLy8KLy8gRGVzaWduIGFuZCBpbXBsZW1lbnRhdGlvbiBieQovLyAtIEhlcnbpIERyb2xvbiAoZHJvbG9uQGluZm9uaWUuZnIpCi8vIC0gRGV0bGV2IFZlbmR0IChkZXRsZXYudmVuZHRAYnJpbGxpdC5kZSkKLy8gLSBDYXJzdGVuIEtsZWluIChja2xlaW4wNUB1c2Vycy5zb3VyY2Vmb3JnZS5uZXQpCi8vCi8vIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIEZyZWVJbWFnZSAzCi8vCi8vIENPVkVSRUQgQ09ERSBJUyBQUk9WSURFRCBVTkRFUiBUSElTIExJQ0VOU0UgT04gQU4gIkFTIElTIiBCQVNJUywgV0lUSE9VVCBXQVJSQU5UWQovLyBPRiBBTlkgS0lORCwgRUlUSEVSIEVYUFJFU1NFRCBPUiBJTVBMSUVELCBJTkNMVURJTkcsIFdJVEhPVVQgTElNSVRBVElPTiwgV0FSUkFOVElFUwovLyBUSEFUIFRIRSBDT1ZFUkVEIENPREUgSVMgRlJFRSBPRiBERUZFQ1RTLCBNRVJDSEFOVEFCTEUsIEZJVCBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UKLy8gT1IgTk9OLUlORlJJTkdJTkcuIFRIRSBFTlRJUkUgUklTSyBBUyBUTyBUSEUgUVVBTElUWSBBTkQgUEVSRk9STUFOQ0UgT0YgVEhFIENPVkVSRUQKLy8gQ09ERSBJUyBXSVRIIFlPVS4gU0hPVUxEIEFOWSBDT1ZFUkVEIENPREUgUFJPVkUgREVGRUNUSVZFIElOIEFOWSBSRVNQRUNULCBZT1UgKE5PVAovLyBUSEUgSU5JVElBTCBERVZFTE9QRVIgT1IgQU5ZIE9USEVSIENPTlRSSUJVVE9SKSBBU1NVTUUgVEhFIENPU1QgT0YgQU5ZIE5FQ0VTU0FSWQovLyBTRVJWSUNJTkcsIFJFUEFJUiBPUiBDT1JSRUNUSU9OLiBUSElTIERJU0NMQUlNRVIgT0YgV0FSUkFOVFkgQ09OU1RJVFVURVMgQU4gRVNTRU5USUFMCi8vIFBBUlQgT0YgVEhJUyBMSUNFTlNFLiBOTyBVU0UgT0YgQU5ZIENPVkVSRUQgQ09ERSBJUyBBVVRIT1JJWkVEIEhFUkVVTkRFUiBFWENFUFQgVU5ERVIKLy8gVEhJUyBESVNDTEFJTUVSLgovLwovLyBVc2UgYXQgeW91ciBvd24gcmlzayEKLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQoKI2lmbmRlZiBfUkVTSVpFX0hfCiNkZWZpbmUgX1JFU0laRV9IXwoKI2luY2x1ZGUgIkZyZWVJbWFnZS5oIgojaW5jbHVkZSAiVXRpbGl0aWVzLmgiCiNpbmNsdWRlICJGaWx0ZXJzLmgiIAoKLyoqCiAgRmlsdGVyIHdlaWdodHMgdGFibGUuPGJyPgogIFRoaXMgY2xhc3Mgc3RvcmVzIGNvbnRyaWJ1dGlvbiBpbmZvcm1hdGlvbiBmb3IgYW4gZW50aXJlIGxpbmUgKHJvdyBvciBjb2x1bW4pLgoqLwpjbGFzcyBDV2VpZ2h0c1RhYmxlCnsKLyoqCiAgU2FtcGxlZCBmaWx0ZXIgd2VpZ2h0IHRhYmxlLjxicj4KICBDb250cmlidXRpb24gaW5mb3JtYXRpb24gZm9yIGEgc2luZ2xlIHBpeGVsCiovCnR5cGVkZWYgc3RydWN0IHsKCS8vLyBOb3JtYWxpemVkIHdlaWdodHMgb2YgbmVpZ2hib3JpbmcgcGl4ZWxzCglkb3VibGUgKldlaWdodHM7CgkvLy8gQm91bmRzIG9mIHNvdXJjZSBwaXhlbHMgd2luZG93Cgl1bnNpZ25lZCBMZWZ0LCBSaWdodDsKfSBDb250cmlidXRpb247Cgpwcml2YXRlOgoJLy8vIFJvdyAob3IgY29sdW1uKSBvZiBjb250cmlidXRpb24gd2VpZ2h0cyAKCUNvbnRyaWJ1dGlvbiAqbV9XZWlnaHRUYWJsZTsKCS8vLyBGaWx0ZXIgd2luZG93IHNpemUgKG9mIGFmZmVjdGluZyBzb3VyY2UgcGl4ZWxzKSAKCXVuc2lnbmVkIG1fV2luZG93U2l6ZTsKCS8vLyBMZW5ndGggb2YgbGluZSAobm8uIG9mIHJvd3MgLyBjb2xzKSAKCXVuc2lnbmVkIG1fTGluZUxlbmd0aDsKCnB1YmxpYzoKCS8qKiAKCUNvbnN0cnVjdG9yPGJyPgoJQWxsb2NhdGUgYW5kIGNvbXB1dGUgdGhlIHdlaWdodHMgdGFibGUKCUBwYXJhbSBwRmlsdGVyIEZpbHRlciB1c2VkIGZvciB1cHNhbXBsaW5nIG9yIGRvd25zYW1wbGluZwoJQHBhcmFtIHVEc3RTaXplIExlbmd0aCAoaW4gcGl4ZWxzKSBvZiB0aGUgZGVzdGluYXRpb24gbGluZSBidWZmZXIKCUBwYXJhbSB1U3JjU2l6ZSBMZW5ndGggKGluIHBpeGVscykgb2YgdGhlIHNvdXJjZSBsaW5lIGJ1ZmZlcgoJKi8KCUNXZWlnaHRzVGFibGUoQ0dlbmVyaWNGaWx0ZXIgKnBGaWx0ZXIsIHVuc2lnbmVkIHVEc3RTaXplLCB1bnNpZ25lZCB1U3JjU2l6ZSk7CgoJLyoqCglEZXN0cnVjdG9yPGJyPgoJRGVzdHJveSB0aGUgd2VpZ2h0cyB0YWJsZQoJKi8KCX5DV2VpZ2h0c1RhYmxlKCk7CgoJLyoqIFJldHJpZXZlIGEgZmlsdGVyIHdlaWdodCwgZ2l2ZW4gc291cmNlIGFuZCBkZXN0aW5hdGlvbiBwb3NpdGlvbnMKCUBwYXJhbSBkc3RfcG9zIFBpeGVsIHBvc2l0aW9uIGluIGRlc3RpbmF0aW9uIGxpbmUgYnVmZmVyCglAcGFyYW0gc3JjX3BvcyBQaXhlbCBwb3NpdGlvbiBpbiBzb3VyY2UgbGluZSBidWZmZXIKCUByZXR1cm4gUmV0dXJucyB0aGUgZmlsdGVyIHdlaWdodAoJKi8KCWRvdWJsZSBnZXRXZWlnaHQodW5zaWduZWQgZHN0X3BvcywgdW5zaWduZWQgc3JjX3BvcykgewoJCXJldHVybiBtX1dlaWdodFRhYmxlW2RzdF9wb3NdLldlaWdodHNbc3JjX3Bvc107Cgl9CgoJLyoqIFJldHJpZXZlIGxlZnQgYm91bmRhcnkgb2Ygc291cmNlIGxpbmUgYnVmZmVyCglAcGFyYW0gZHN0X3BvcyBQaXhlbCBwb3NpdGlvbiBpbiBkZXN0aW5hdGlvbiBsaW5lIGJ1ZmZlcgoJQHJldHVybiBSZXR1cm5zIHRoZSBsZWZ0IGJvdW5kYXJ5IG9mIHNvdXJjZSBsaW5lIGJ1ZmZlcgoJKi8KCXVuc2lnbmVkIGdldExlZnRCb3VuZGFyeSh1bnNpZ25lZCBkc3RfcG9zKSB7CgkJcmV0dXJuIG1fV2VpZ2h0VGFibGVbZHN0X3Bvc10uTGVmdDsKCX0KCgkvKiogUmV0cmlldmUgcmlnaHQgYm91bmRhcnkgb2Ygc291cmNlIGxpbmUgYnVmZmVyCglAcGFyYW0gZHN0X3BvcyBQaXhlbCBwb3NpdGlvbiBpbiBkZXN0aW5hdGlvbiBsaW5lIGJ1ZmZlcgoJQHJldHVybiBSZXR1cm5zIHRoZSByaWdodCBib3VuZGFyeSBvZiBzb3VyY2UgbGluZSBidWZmZXIKCSovCgl1bnNpZ25lZCBnZXRSaWdodEJvdW5kYXJ5KHVuc2lnbmVkIGRzdF9wb3MpIHsKCQlyZXR1cm4gbV9XZWlnaHRUYWJsZVtkc3RfcG9zXS5SaWdodDsKCX0KfTsKCi8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKLyoqCiBDUmVzaXplRW5naW5lPGJyPgogVGhpcyBjbGFzcyBwZXJmb3JtcyBmaWx0ZXJlZCB6b29tLiBJdCBzY2FsZXMgYW4gaW1hZ2UgdG8gdGhlIGRlc2lyZWQgZGltZW5zaW9ucyB3aXRoIAogYW55IG9mIHRoZSBDR2VuZXJpY0ZpbHRlciBkZXJpdmVkIGZpbHRlciBjbGFzcy48YnI+CiBJdCB3b3JrcyB3aXRoIEZJVF9CSVRNQVAgYnVmZmVycywgV09SRCBidWZmZXJzIChGSVRfVUlOVDE2LCBGSVRfUkdCMTYsIEZJVF9SR0JBMTYpIAogYW5kIGZsb2F0IGJ1ZmZlcnMgKEZJVF9GTE9BVCwgRklUX1JHQkYsIEZJVF9SR0JBRikuPGJyPjxicj4KCiA8Yj5SZWZlcmVuY2VzPC9iPiA6IDxicj4KIFsxXSBQYXVsIEhlY2tiZXJ0LCBDIGNvZGUgdG8gem9vbSByYXN0ZXIgaW1hZ2VzIHVwIG9yIGRvd24sIHdpdGggbmljZSBmaWx0ZXJpbmcuIAogVUMgQmVya2VsZXksIEF1Z3VzdCAxOTg5LiBbb25saW5lXSBodHRwOi8vd3d3LTIuY3MuY211LmVkdS9hZnMvY3MuY211LmVkdS9XZWIvUGVvcGxlL3BoL2hlY2tiZXJ0Lmh0bWwKIFsyXSBFcmFuIFlhcml2LCBUd28gUGFzcyBTY2FsaW5nIHVzaW5nIEZpbHRlcnMuIFRoZSBDb2RlIFByb2plY3QsIERlY2VtYmVyIDE5OTkuIAogW29ubGluZV0gaHR0cDovL3d3dy5jb2RlcHJvamVjdC5jb20vYml0bWFwLzJfcGFzc19zY2FsaW5nLmFzcAoKKi8KY2xhc3MgQ1Jlc2l6ZUVuZ2luZQp7CnByaXZhdGU6CgkvLy8gUG9pbnRlciB0byB0aGUgRklSIC8gSUlSIGZpbHRlcgoJQ0dlbmVyaWNGaWx0ZXIqIG1fcEZpbHRlcjsKCnB1YmxpYzoKCgkvKioKCUNvbnN0cnVjdG9yCglAcGFyYW0gZmlsdGVyIEZJUiAvSUlSIGZpbHRlciB0byBiZSB1c2VkCgkqLwoJQ1Jlc2l6ZUVuZ2luZShDR2VuZXJpY0ZpbHRlciogZmlsdGVyKTptX3BGaWx0ZXIoZmlsdGVyKSB7fQoKCS8vLyBEZXN0cnVjdG9yCgl2aXJ0dWFsIH5DUmVzaXplRW5naW5lKCkge30KCgkvKiogU2NhbGUgYW4gaW1hZ2UgdG8gdGhlIGRlc2lyZWQgZGltZW5zaW9ucy4KCglNZXRob2QgQ1Jlc2l6ZUVuZ2luZTo6c2NhbGUsIGFzIHdlbGwgYXMgdGhlIHR3byBmaWx0ZXJpbmcgbWV0aG9kcwoJQ1Jlc2l6ZUVuZ2luZTo6aG9yaXpvbnRhbEZpbHRlciBhbmQgQ1Jlc2l6ZUVuZ2luZTo6dmVydGljYWxGaWx0ZXIgdGFrZQoJZm91ciBhZGRpdGlvbmFsIHBhcmFtZXRlcnMsIHRoYXQgZGVmaW5lIGEgcmVjdGFuZ2xlIGluIHRoZSBzb3VyY2UKCWltYWdlIHRvIGJlIHJlc2NhbGVkLgoKCVRoZXNlIGFyZSBzcmNfbGVmdCwgc3JjX3RvcCwgc3JjX3dpZHRoIGFuZCBzcmNfaGVpZ2h0IGFuZCBzaG91bGQgd29yawoJbGlrZSB0aGVzZSBvZiBmdW5jdGlvbiBGcmVlSW1hZ2VfQ29weS4gSG93ZXZlciwgc3JjX2xlZnQgYW5kIHNyY190b3AgYXJlCglhY3R1YWxseSBuYW1lZCBzcmNfb2Zmc2V0X3ggYW5kIHNyY19vZmZzZXRfeSBpbiB0aGUgZmlsdGVyaW5nIG1ldGhvZHMuCgoJQWRkaXRpb25hbGx5LCBzaW5jZSBzcmNfaGVpZ2h0IGFuZCBkc3RfaGVpZ2h0IGFyZSBhbHdheXMgdGhlIHNhbWUgZm9yCgltZXRob2QgaG9yaXpvbnRhbEZpbHRlciBhcyBzcmNfd2lkdGggYW5kIGRzdF93aWR0aCBhcmUgYWx3YXlzIHRoZSBzYW1lCglmb3IgdmVydGljYWxGaWx0ZXIsIHRoZXNlIGhhdmUgYmVlbiBzdHJpcHBlZCBkb3duIHRvIGEgc2luZ2xlIHBhcmFtZXRlcgoJaGVpZ2h0IGFuZCB3aWR0aCBmb3IgaG9yaXpvbnRhbEZpbHRlciBhbmQgdmVydGljYWxGaWx0ZXIgcmVzcGVjdGl2ZWx5LgoKCUN1cnJlbnRseSwgbWV0aG9kIHNjYWxlIGlzIGNhbGxlZCB3aXRoIHRoZSBhY3R1YWwgc2l6ZSBvZiB0aGUgc291cmNlCglpbWFnZS4gSG93ZXZlciwgaW4gYSBmdXR1cmUgdmVyc2lvbiwgd2UgY291bGQgcHJvdmlkZSBhIG5ldyBmdW5jdGlvbgoJY2FsbGVkIEZyZWVJbWFnZV9SZXNjYWxlUmVjdCB0aGF0IHJlc2NhbGVzIG9ubHkgcGFydCBvZiBhbiBpbWFnZS4gCgoJQHBhcmFtIHNyYyBQb2ludGVyIHRvIHRoZSBzb3VyY2UgaW1hZ2UKCUBwYXJhbSBkc3Rfd2lkdGggRGVzdGluYXRpb24gaW1hZ2Ugd2lkdGgKCUBwYXJhbSBkc3RfaGVpZ2h0IERlc3RpbmF0aW9uIGltYWdlIGhlaWdodAoJQHBhcmFtIHNyY19sZWZ0IExlZnQgYm91bmRhcnkgb2YgdGhlIHNvdXJjZSByZWN0YW5nbGUgdG8gYmUgc2NhbGVkCglAcGFyYW0gc3JjX3RvcCBUb3AgYm91bmRhcnkgb2YgdGhlIHNvdXJjZSByZWN0YW5nbGUgdG8gYmUgc2NhbGVkCglAcGFyYW0gc3JjX3dpZHRoIFdpZHRoIG9mIHRoZSBzb3VyY2UgcmVjdGFuZ2xlIHRvIGJlIHNjYWxlZAoJQHBhcmFtIHNyY19oZWlnaHQgSGVpZ2h0IG9mIHRoZSBzb3VyY2UgcmVjdGFuZ2xlIHRvIGJlIHNjYWxlZAoJQHJldHVybiBSZXR1cm5zIHRoZSBzY2FsZWQgaW1hZ2UgaWYgc3VjY2Vzc2Z1bCwgcmV0dXJucyBOVUxMIG90aGVyd2lzZQoJKi8KCUZJQklUTUFQKiBzY2FsZShGSUJJVE1BUCAqc3JjLCB1bnNpZ25lZCBkc3Rfd2lkdGgsIHVuc2lnbmVkIGRzdF9oZWlnaHQsIHVuc2lnbmVkIHNyY19sZWZ0LCB1bnNpZ25lZCBzcmNfdG9wLCB1bnNpZ25lZCBzcmNfd2lkdGgsIHVuc2lnbmVkIHNyY19oZWlnaHQsIHVuc2lnbmVkIGZsYWdzKTsKCnByaXZhdGU6CgoJLyoqCglQZXJmb3JtcyBob3Jpem9udGFsIGltYWdlIGZpbHRlcmluZwoKCUBwYXJhbSBzcmMgU291cmNlIGltYWdlCglAcGFyYW0gaGVpZ2h0IFNvdXJjZSAvIERlc3RpbmF0aW9uIGltYWdlIGhlaWdodAoJQHBhcmFtIHNyY193aWR0aCBTb3VyY2UgaW1hZ2Ugd2lkdGgKCUBwYXJhbSBzcmNfb2Zmc2V0X3gKCUBwYXJhbSBzcmNfb2Zmc2V0X3kKCUBwYXJhbSBzcmNfcGFsCglAcGFyYW0gZHN0IERlc3RpbmF0aW9uIGltYWdlCglAcGFyYW0gZHN0X3dpZHRoIERlc3RpbmF0aW9uIGltYWdlIHdpZHRoCgkqLwoJdm9pZCBob3Jpem9udGFsRmlsdGVyKEZJQklUTUFQICogY29uc3Qgc3JjLCBjb25zdCB1bnNpZ25lZCBoZWlnaHQsIGNvbnN0IHVuc2lnbmVkIHNyY193aWR0aCwKCQkJY29uc3QgdW5zaWduZWQgc3JjX29mZnNldF94LCBjb25zdCB1bnNpZ25lZCBzcmNfb2Zmc2V0X3ksIGNvbnN0IFJHQlFVQUQgKiBjb25zdCBzcmNfcGFsLAoJCQlGSUJJVE1BUCAqIGNvbnN0IGRzdCwgY29uc3QgdW5zaWduZWQgZHN0X3dpZHRoKTsKCgkvKioKCVBlcmZvcm1zIHZlcnRpY2FsIGltYWdlIGZpbHRlcmluZwoJQHBhcmFtIHNyYyBTb3VyY2UgaW1hZ2UKCUBwYXJhbSB3aWR0aCBTb3VyY2UgLyBEZXN0aW5hdGlvbiBpbWFnZSB3aWR0aAoJQHBhcmFtIHNyY19oZWlnaHQgU291cmNlIGltYWdlIGhlaWdodAoJQHBhcmFtIHNyY19vZmZzZXRfeAoJQHBhcmFtIHNyY19vZmZzZXRfeQoJQHBhcmFtIHNyY19wYWwKCUBwYXJhbSBkc3QgRGVzdGluYXRpb24gaW1hZ2UKCUBwYXJhbSBkc3RfaGVpZ2h0IERlc3RpbmF0aW9uIGltYWdlIGhlaWdodAoJKi8KCXZvaWQgdmVydGljYWxGaWx0ZXIoRklCSVRNQVAgKiBjb25zdCBzcmMsIGNvbnN0IHVuc2lnbmVkIHdpZHRoLCBjb25zdCB1bnNpZ25lZCBzcmNfaGVpZ2h0LAoJCQljb25zdCB1bnNpZ25lZCBzcmNfb2Zmc2V0X3gsIGNvbnN0IHVuc2lnbmVkIHNyY19vZmZzZXRfeSwgY29uc3QgUkdCUVVBRCAqIGNvbnN0IHNyY19wYWwsCgkJCUZJQklUTUFQICogY29uc3QgZHN0LCBjb25zdCB1bnNpZ25lZCBkc3RfaGVpZ2h0KTsKfTsKCiNlbmRpZiAvLyAgIF9SRVNJWkVfSF8K