ZGlmZiAtLWdpdCBhL3dwaWxpYmMvQXRoZW5hL3NyYy9BRFhMMzQ1X0kyQy5jcHAgYi93cGlsaWJjL0F0aGVuYS9zcmMvQURYTDM0NV9JMkMuY3BwCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjAwMGQ0YjgKLS0tIC9kZXYvbnVsbAorKysgYi93cGlsaWJjL0F0aGVuYS9zcmMvQURYTDM0NV9JMkMuY3BwCkBAIC0wLDAgKzEsOTQgQEAKKy8qLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovCisvKiBDb3B5cmlnaHQgKGMpIEZJUlNUIDIwMDguIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCisgKi8KKy8qIE9wZW4gU291cmNlIFNvZnR3YXJlIC0gbWF5IGJlIG1vZGlmaWVkIGFuZCBzaGFyZWQgYnkgRlJDIHRlYW1zLiBUaGUgY29kZSAgICovCisvKiBtdXN0IGJlIGFjY29tcGFuaWVkIGJ5IHRoZSBGSVJTVCBCU0QgbGljZW5zZSBmaWxlIGluICQoV0lORF9CQVNFKS9XUElMaWIuICAqLworLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi8KKworI2luY2x1ZGUgIkFEWEwzNDVfSTJDLmgiCisjaW5jbHVkZSAiSTJDLmgiCisjaW5jbHVkZSAiSEFML0hBTC5ocHAiCisjaW5jbHVkZSAiTGl2ZVdpbmRvdy9MaXZlV2luZG93LmgiCisKK2NvbnN0IHVpbnQ4X3QgQURYTDM0NV9JMkM6OmtBZGRyZXNzOworY29uc3QgdWludDhfdCBBRFhMMzQ1X0kyQzo6a1Bvd2VyQ3RsUmVnaXN0ZXI7Citjb25zdCB1aW50OF90IEFEWEwzNDVfSTJDOjprRGF0YUZvcm1hdFJlZ2lzdGVyOworY29uc3QgdWludDhfdCBBRFhMMzQ1X0kyQzo6a0RhdGFSZWdpc3RlcjsKK2NvbnN0ZXhwciBkb3VibGUgQURYTDM0NV9JMkM6OmtHc1BlckxTQjsKKworLyoqCisgKiBDb25zdHJ1Y3Rvci4KKyAqCisgKiBAcGFyYW0gcG9ydCBUaGUgSTJDIHBvcnQgdGhlIGFjY2VsZXJvbWV0ZXIgaXMgYXR0YWNoZWQgdG8KKyAqIEBwYXJhbSByYW5nZSBUaGUgcmFuZ2UgKCsgb3IgLSkgdGhhdCB0aGUgYWNjZWxlcm9tZXRlciB3aWxsIG1lYXN1cmUuCisgKi8KK0FEWEwzNDVfSTJDOjpBRFhMMzQ1X0kyQyhQb3J0IHBvcnQsIFJhbmdlIHJhbmdlKSA6IEkyQyhwb3J0LCBrQWRkcmVzcykgeworICAvLyBUdXJuIG9uIHRoZSBtZWFzdXJlbWVudHMKKyAgV3JpdGUoa1Bvd2VyQ3RsUmVnaXN0ZXIsIGtQb3dlckN0bF9NZWFzdXJlKTsKKyAgLy8gU3BlY2lmeSB0aGUgZGF0YSBmb3JtYXQgdG8gcmVhZAorICBTZXRSYW5nZShyYW5nZSk7CisKKyAgSEFMUmVwb3J0KEhBTFVzYWdlUmVwb3J0aW5nOjprUmVzb3VyY2VUeXBlX0FEWEwzNDUsCisgICAgICAgICAgICBIQUxVc2FnZVJlcG9ydGluZzo6a0FEWEwzNDVfSTJDLCAwKTsKKyAgTGl2ZVdpbmRvdzo6R2V0SW5zdGFuY2UoKS0+QWRkU2Vuc29yKCJBRFhMMzQ1X0kyQyIsIHBvcnQsIHRoaXMpOworfQorCisvKioge0Bpbmhlcml0ZG9jfSAqLwordm9pZCBBRFhMMzQ1X0kyQzo6U2V0UmFuZ2UoUmFuZ2UgcmFuZ2UpIHsKKyAgV3JpdGUoa0RhdGFGb3JtYXRSZWdpc3Rlciwga0RhdGFGb3JtYXRfRnVsbFJlcyB8ICh1aW50OF90KXJhbmdlKTsKK30KKworLyoqIHtAaW5oZXJpdGRvY30gKi8KK2RvdWJsZSBBRFhMMzQ1X0kyQzo6R2V0WCgpIHsgcmV0dXJuIEdldEFjY2VsZXJhdGlvbihrQXhpc19YKTsgfQorCisvKioge0Bpbmhlcml0ZG9jfSAqLworZG91YmxlIEFEWEwzNDVfSTJDOjpHZXRZKCkgeyByZXR1cm4gR2V0QWNjZWxlcmF0aW9uKGtBeGlzX1kpOyB9CisKKy8qKiB7QGluaGVyaXRkb2N9ICovCitkb3VibGUgQURYTDM0NV9JMkM6OkdldFooKSB7IHJldHVybiBHZXRBY2NlbGVyYXRpb24oa0F4aXNfWik7IH0KKworLyoqCisgKiBHZXQgdGhlIGFjY2VsZXJhdGlvbiBvZiBvbmUgYXhpcyBpbiBHcy4KKyAqCisgKiBAcGFyYW0gYXhpcyBUaGUgYXhpcyB0byByZWFkIGZyb20uCisgKiBAcmV0dXJuIEFjY2VsZXJhdGlvbiBvZiB0aGUgQURYTDM0NSBpbiBHcy4KKyAqLworZG91YmxlIEFEWEwzNDVfSTJDOjpHZXRBY2NlbGVyYXRpb24oQURYTDM0NV9JMkM6OkF4ZXMgYXhpcykgeworICBpbnQxNl90IHJhd0FjY2VsID0gMDsKKyAgUmVhZChrRGF0YVJlZ2lzdGVyICsgKHVpbnQ4X3QpYXhpcywgc2l6ZW9mKHJhd0FjY2VsKSwgKHVpbnQ4X3QgKikmcmF3QWNjZWwpOworICByZXR1cm4gcmF3QWNjZWwgKiBrR3NQZXJMU0I7Cit9CisKKy8qKgorICogR2V0IHRoZSBhY2NlbGVyYXRpb24gb2YgYWxsIGF4ZXMgaW4gR3MuCisgKgorICogQHJldHVybiBBbiBvYmplY3QgY29udGFpbmluZyB0aGUgYWNjZWxlcmF0aW9uIG1lYXN1cmVkIG9uIGVhY2ggYXhpcyBvZiB0aGUKKyAqIEFEWEwzNDUgaW4gR3MuCisgKi8KK0FEWEwzNDVfSTJDOjpBbGxBeGVzIEFEWEwzNDVfSTJDOjpHZXRBY2NlbGVyYXRpb25zKCkgeworICBBbGxBeGVzIGRhdGEgPSBBbGxBeGVzKCk7CisgIGludDE2X3QgcmF3RGF0YVszXTsKKyAgUmVhZChrRGF0YVJlZ2lzdGVyLCBzaXplb2YocmF3RGF0YSksICh1aW50OF90ICopcmF3RGF0YSk7CisKKyAgZGF0YS5YQXhpcyA9IHJhd0RhdGFbMF0gKiBrR3NQZXJMU0I7CisgIGRhdGEuWUF4aXMgPSByYXdEYXRhWzFdICoga0dzUGVyTFNCOworICBkYXRhLlpBeGlzID0gcmF3RGF0YVsyXSAqIGtHc1BlckxTQjsKKyAgcmV0dXJuIGRhdGE7Cit9CisKK3N0ZDo6c3RyaW5nIEFEWEwzNDVfSTJDOjpHZXRTbWFydERhc2hib2FyZFR5cGUoKSBjb25zdCB7CisgIHJldHVybiAiM0F4aXNBY2NlbGVyb21ldGVyIjsKK30KKwordm9pZCBBRFhMMzQ1X0kyQzo6SW5pdFRhYmxlKHN0ZDo6c2hhcmVkX3B0cjxJVGFibGU+IHN1YnRhYmxlKSB7CisgIG1fdGFibGUgPSBzdWJ0YWJsZTsKKyAgVXBkYXRlVGFibGUoKTsKK30KKwordm9pZCBBRFhMMzQ1X0kyQzo6VXBkYXRlVGFibGUoKSB7CisgIG1fdGFibGUtPlB1dE51bWJlcigiWCIsIEdldFgoKSk7CisgIG1fdGFibGUtPlB1dE51bWJlcigiWSIsIEdldFkoKSk7CisgIG1fdGFibGUtPlB1dE51bWJlcigiWiIsIEdldFooKSk7Cit9CisKK3N0ZDo6c2hhcmVkX3B0cjxJVGFibGU+IEFEWEwzNDVfSTJDOjpHZXRUYWJsZSgpIGNvbnN0IHsgcmV0dXJuIG1fdGFibGU7IH0KZGlmZiAtLWdpdCBhL3dwaWxpYmMvQXRoZW5hL3NyYy9BRFhMMzQ1X1NQSS5jcHAgYi93cGlsaWJjL0F0aGVuYS9zcmMvQURYTDM0NV9TUEkuY3BwCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjdmYjNiNzEKLS0tIC9kZXYvbnVsbAorKysgYi93cGlsaWJjL0F0aGVuYS9zcmMvQURYTDM0NV9TUEkuY3BwCkBAIC0wLDAgKzEsMTI2IEBACisvKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qLworLyogQ29weXJpZ2h0IChjKSBGSVJTVCAyMDA4LiBBbGwgUmlnaHRzIFJlc2VydmVkLgorICovCisvKiBPcGVuIFNvdXJjZSBTb2Z0d2FyZSAtIG1heSBiZSBtb2RpZmllZCBhbmQgc2hhcmVkIGJ5IEZSQyB0ZWFtcy4gVGhlIGNvZGUgICAqLworLyogbXVzdCBiZSBhY2NvbXBhbmllZCBieSB0aGUgRklSU1QgQlNEIGxpY2Vuc2UgZmlsZSBpbiAkKFdJTkRfQkFTRSkvV1BJTGliLiAgKi8KKy8qLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovCisKKyNpbmNsdWRlICJBRFhMMzQ1X1NQSS5oIgorI2luY2x1ZGUgIkRpZ2l0YWxJbnB1dC5oIgorI2luY2x1ZGUgIkRpZ2l0YWxPdXRwdXQuaCIKKyNpbmNsdWRlICJMaXZlV2luZG93L0xpdmVXaW5kb3cuaCIKKworY29uc3QgdWludDhfdCBBRFhMMzQ1X1NQSTo6a1Bvd2VyQ3RsUmVnaXN0ZXI7Citjb25zdCB1aW50OF90IEFEWEwzNDVfU1BJOjprRGF0YUZvcm1hdFJlZ2lzdGVyOworY29uc3QgdWludDhfdCBBRFhMMzQ1X1NQSTo6a0RhdGFSZWdpc3RlcjsKK2NvbnN0ZXhwciBkb3VibGUgQURYTDM0NV9TUEk6OmtHc1BlckxTQjsKKworLyoqCisgKiBDb25zdHJ1Y3Rvci4KKyAqCisgKiBAcGFyYW0gcG9ydCBUaGUgU1BJIHBvcnQgdGhlIGFjY2VsZXJvbWV0ZXIgaXMgYXR0YWNoZWQgdG8KKyAqIEBwYXJhbSByYW5nZSBUaGUgcmFuZ2UgKCsgb3IgLSkgdGhhdCB0aGUgYWNjZWxlcm9tZXRlciB3aWxsIG1lYXN1cmUuCisgKi8KK0FEWEwzNDVfU1BJOjpBRFhMMzQ1X1NQSShTUEk6OlBvcnQgcG9ydCwgQURYTDM0NV9TUEk6OlJhbmdlIHJhbmdlKSA6IFNQSShwb3J0KSB7CisgIFNldENsb2NrUmF0ZSg1MDAwMDApOworICBTZXRNU0JGaXJzdCgpOworICBTZXRTYW1wbGVEYXRhT25GYWxsaW5nKCk7CisgIFNldENsb2NrQWN0aXZlTG93KCk7CisgIFNldENoaXBTZWxlY3RBY3RpdmVIaWdoKCk7CisKKyAgdWludDhfdCBjb21tYW5kc1syXTsKKyAgLy8gVHVybiBvbiB0aGUgbWVhc3VyZW1lbnRzCisgIGNvbW1hbmRzWzBdID0ga1Bvd2VyQ3RsUmVnaXN0ZXI7CisgIGNvbW1hbmRzWzFdID0ga1Bvd2VyQ3RsX01lYXN1cmU7CisgIFRyYW5zYWN0aW9uKGNvbW1hbmRzLCBjb21tYW5kcywgMik7CisKKyAgU2V0UmFuZ2UocmFuZ2UpOworCisgIEhBTFJlcG9ydChIQUxVc2FnZVJlcG9ydGluZzo6a1Jlc291cmNlVHlwZV9BRFhMMzQ1LAorICAgICAgICAgICAgSEFMVXNhZ2VSZXBvcnRpbmc6OmtBRFhMMzQ1X1NQSSk7CisKKyAgTGl2ZVdpbmRvdzo6R2V0SW5zdGFuY2UoKS0+QWRkU2Vuc29yKCJBRFhMMzQ1X1NQSSIsIHBvcnQsIHRoaXMpOworfQorCisvKioge0Bpbmhlcml0ZG9jfSAqLwordm9pZCBBRFhMMzQ1X1NQSTo6U2V0UmFuZ2UoUmFuZ2UgcmFuZ2UpIHsKKyAgdWludDhfdCBjb21tYW5kc1syXTsKKworICAvLyBTcGVjaWZ5IHRoZSBkYXRhIGZvcm1hdCB0byByZWFkCisgIGNvbW1hbmRzWzBdID0ga0RhdGFGb3JtYXRSZWdpc3RlcjsKKyAgY29tbWFuZHNbMV0gPSBrRGF0YUZvcm1hdF9GdWxsUmVzIHwgKHVpbnQ4X3QpKHJhbmdlICYgMHgwMyk7CisgIFRyYW5zYWN0aW9uKGNvbW1hbmRzLCBjb21tYW5kcywgMik7Cit9CisKKy8qKiB7QGluaGVyaXRkb2N9ICovCitkb3VibGUgQURYTDM0NV9TUEk6OkdldFgoKSB7IHJldHVybiBHZXRBY2NlbGVyYXRpb24oa0F4aXNfWCk7IH0KKworLyoqIHtAaW5oZXJpdGRvY30gKi8KK2RvdWJsZSBBRFhMMzQ1X1NQSTo6R2V0WSgpIHsgcmV0dXJuIEdldEFjY2VsZXJhdGlvbihrQXhpc19ZKTsgfQorCisvKioge0Bpbmhlcml0ZG9jfSAqLworZG91YmxlIEFEWEwzNDVfU1BJOjpHZXRaKCkgeyByZXR1cm4gR2V0QWNjZWxlcmF0aW9uKGtBeGlzX1opOyB9CisKKy8qKgorICogR2V0IHRoZSBhY2NlbGVyYXRpb24gb2Ygb25lIGF4aXMgaW4gR3MuCisgKgorICogQHBhcmFtIGF4aXMgVGhlIGF4aXMgdG8gcmVhZCBmcm9tLgorICogQHJldHVybiBBY2NlbGVyYXRpb24gb2YgdGhlIEFEWEwzNDUgaW4gR3MuCisgKi8KK2RvdWJsZSBBRFhMMzQ1X1NQSTo6R2V0QWNjZWxlcmF0aW9uKEFEWEwzNDVfU1BJOjpBeGVzIGF4aXMpIHsKKyAgdWludDhfdCBidWZmZXJbM107CisgIHVpbnQ4X3QgY29tbWFuZFszXSA9IHswLCAwLCAwfTsKKyAgY29tbWFuZFswXSA9CisgICAgICAoa0FkZHJlc3NfUmVhZCB8IGtBZGRyZXNzX011bHRpQnl0ZSB8IGtEYXRhUmVnaXN0ZXIpICsgKHVpbnQ4X3QpYXhpczsKKyAgVHJhbnNhY3Rpb24oY29tbWFuZCwgYnVmZmVyLCAzKTsKKworICAvLyBTZW5zb3IgaXMgbGl0dGxlIGVuZGlhbi4uLiBzd2FwIGJ5dGVzCisgIGludDE2X3QgcmF3QWNjZWwgPSBidWZmZXJbMl0gPDwgOCB8IGJ1ZmZlclsxXTsKKyAgcmV0dXJuIHJhd0FjY2VsICoga0dzUGVyTFNCOworfQorCisvKioKKyAqIEdldCB0aGUgYWNjZWxlcmF0aW9uIG9mIGFsbCBheGVzIGluIEdzLgorICoKKyAqIEByZXR1cm4gQW4gb2JqZWN0IGNvbnRhaW5pbmcgdGhlIGFjY2VsZXJhdGlvbiBtZWFzdXJlZCBvbiBlYWNoIGF4aXMgb2YgdGhlCisgKiBBRFhMMzQ1IGluIEdzLgorICovCitBRFhMMzQ1X1NQSTo6QWxsQXhlcyBBRFhMMzQ1X1NQSTo6R2V0QWNjZWxlcmF0aW9ucygpIHsKKyAgQWxsQXhlcyBkYXRhID0gQWxsQXhlcygpOworICB1aW50OF90IGRhdGFCdWZmZXJbN10gPSB7MCwgMCwgMCwgMCwgMCwgMCwgMH07CisgIGludDE2X3QgcmF3RGF0YVszXTsKKworICAvLyBTZWxlY3QgdGhlIGRhdGEgYWRkcmVzcy4KKyAgZGF0YUJ1ZmZlclswXSA9IChrQWRkcmVzc19SZWFkIHwga0FkZHJlc3NfTXVsdGlCeXRlIHwga0RhdGFSZWdpc3Rlcik7CisgIFRyYW5zYWN0aW9uKGRhdGFCdWZmZXIsIGRhdGFCdWZmZXIsIDcpOworCisgIGZvciAoaW50MzJfdCBpID0gMDsgaSA8IDM7IGkrKykgeworICAgIC8vIFNlbnNvciBpcyBsaXR0bGUgZW5kaWFuLi4uIHN3YXAgYnl0ZXMKKyAgICByYXdEYXRhW2ldID0gZGF0YUJ1ZmZlcltpICogMiArIDJdIDw8IDggfCBkYXRhQnVmZmVyW2kgKiAyICsgMV07CisgIH0KKworICBkYXRhLlhBeGlzID0gcmF3RGF0YVswXSAqIGtHc1BlckxTQjsKKyAgZGF0YS5ZQXhpcyA9IHJhd0RhdGFbMV0gKiBrR3NQZXJMU0I7CisgIGRhdGEuWkF4aXMgPSByYXdEYXRhWzJdICoga0dzUGVyTFNCOworCisgIHJldHVybiBkYXRhOworfQorCitzdGQ6OnN0cmluZyBBRFhMMzQ1X1NQSTo6R2V0U21hcnREYXNoYm9hcmRUeXBlKCkgY29uc3QgeworICByZXR1cm4gIjNBeGlzQWNjZWxlcm9tZXRlciI7Cit9CisKK3ZvaWQgQURYTDM0NV9TUEk6OkluaXRUYWJsZShzdGQ6OnNoYXJlZF9wdHI8SVRhYmxlPiBzdWJ0YWJsZSkgeworICBtX3RhYmxlID0gc3VidGFibGU7CisgIFVwZGF0ZVRhYmxlKCk7Cit9CisKK3ZvaWQgQURYTDM0NV9TUEk6OlVwZGF0ZVRhYmxlKCkgeworICBpZiAobV90YWJsZSAhPSBudWxscHRyKSB7CisgICAgbV90YWJsZS0+UHV0TnVtYmVyKCJYIiwgR2V0WCgpKTsKKyAgICBtX3RhYmxlLT5QdXROdW1iZXIoIlkiLCBHZXRZKCkpOworICAgIG1fdGFibGUtPlB1dE51bWJlcigiWiIsIEdldFooKSk7CisgIH0KK30KKworc3RkOjpzaGFyZWRfcHRyPElUYWJsZT4gQURYTDM0NV9TUEk6OkdldFRhYmxlKCkgY29uc3QgeyByZXR1cm4gbV90YWJsZTsgfQpkaWZmIC0tZ2l0IGEvd3BpbGliYy9BdGhlbmEvc3JjL0FEWEwzNjIuY3BwIGIvd3BpbGliYy9BdGhlbmEvc3JjL0FEWEwzNjIuY3BwCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjNjNzBiOWIKLS0tIC9kZXYvbnVsbAorKysgYi93cGlsaWJjL0F0aGVuYS9zcmMvQURYTDM2Mi5jcHAKQEAgLTAsMCArMSwxODEgQEAKKy8qLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovCisvKiBDb3B5cmlnaHQgKGMpIEZJUlNUIDIwMDguIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCisgKi8KKy8qIE9wZW4gU291cmNlIFNvZnR3YXJlIC0gbWF5IGJlIG1vZGlmaWVkIGFuZCBzaGFyZWQgYnkgRlJDIHRlYW1zLiBUaGUgY29kZSAgICovCisvKiBtdXN0IGJlIGFjY29tcGFuaWVkIGJ5IHRoZSBGSVJTVCBCU0QgbGljZW5zZSBmaWxlIGluICQoV0lORF9CQVNFKS9XUElMaWIuICAqLworLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi8KKworI2luY2x1ZGUgIkFEWEwzNjIuaCIKKyNpbmNsdWRlICJEaWdpdGFsSW5wdXQuaCIKKyNpbmNsdWRlICJEaWdpdGFsT3V0cHV0LmgiCisjaW5jbHVkZSAiRHJpdmVyU3RhdGlvbi5oIgorI2luY2x1ZGUgIkxpdmVXaW5kb3cvTGl2ZVdpbmRvdy5oIgorCitzdGF0aWMgdWludDhfdCBrUmVnV3JpdGUgPSAweDBBOworc3RhdGljIHVpbnQ4X3Qga1JlZ1JlYWQgPSAweDBCOworCitzdGF0aWMgdWludDhfdCBrUGFydElkUmVnaXN0ZXIgPSAweDAyOworc3RhdGljIHVpbnQ4X3Qga0RhdGFSZWdpc3RlciA9IDB4MEU7CitzdGF0aWMgdWludDhfdCBrRmlsdGVyQ3RsUmVnaXN0ZXIgPSAweDJDOworc3RhdGljIHVpbnQ4X3Qga1Bvd2VyQ3RsUmVnaXN0ZXIgPSAweDJEOworCisvL3N0YXRpYyB1aW50OF90IGtGaWx0ZXJDdGxfUmFuZ2UyRyA9IDB4MDA7CisvL3N0YXRpYyB1aW50OF90IGtGaWx0ZXJDdGxfUmFuZ2U0RyA9IDB4NDA7CisvL3N0YXRpYyB1aW50OF90IGtGaWx0ZXJDdGxfUmFuZ2U4RyA9IDB4ODA7CitzdGF0aWMgdWludDhfdCBrRmlsdGVyQ3RsX09EUl8xMDBIeiA9IDB4MDM7CisKK3N0YXRpYyB1aW50OF90IGtQb3dlckN0bF9VbHRyYUxvd05vaXNlID0gMHgyMDsKKy8vc3RhdGljIHVpbnQ4X3Qga1Bvd2VyQ3RsX0F1dG9TbGVlcCA9IDB4MDQ7CitzdGF0aWMgdWludDhfdCBrUG93ZXJDdGxfTWVhc3VyZSA9IDB4MDI7CisKKy8qKgorICogQ29uc3RydWN0b3IuICBVc2VzIHRoZSBvbmJvYXJkIENTMS4KKyAqCisgKiBAcGFyYW0gcmFuZ2UgVGhlIHJhbmdlICgrIG9yIC0pIHRoYXQgdGhlIGFjY2VsZXJvbWV0ZXIgd2lsbCBtZWFzdXJlLgorICovCitBRFhMMzYyOjpBRFhMMzYyKFJhbmdlIHJhbmdlKSA6IEFEWEwzNjIoU1BJOjpQb3J0OjprT25ib2FyZENTMSwgcmFuZ2UpIHt9CisKKy8qKgorICogQ29uc3RydWN0b3IuCisgKgorICogQHBhcmFtIHBvcnQgVGhlIFNQSSBwb3J0IHRoZSBhY2NlbGVyb21ldGVyIGlzIGF0dGFjaGVkIHRvCisgKiBAcGFyYW0gcmFuZ2UgVGhlIHJhbmdlICgrIG9yIC0pIHRoYXQgdGhlIGFjY2VsZXJvbWV0ZXIgd2lsbCBtZWFzdXJlLgorICovCitBRFhMMzYyOjpBRFhMMzYyKFNQSTo6UG9ydCBwb3J0LCBSYW5nZSByYW5nZSkgOiBtX3NwaShwb3J0KSB7CisgIG1fc3BpLlNldENsb2NrUmF0ZSgzMDAwMDAwKTsKKyAgbV9zcGkuU2V0TVNCRmlyc3QoKTsKKyAgbV9zcGkuU2V0U2FtcGxlRGF0YU9uRmFsbGluZygpOworICBtX3NwaS5TZXRDbG9ja0FjdGl2ZUxvdygpOworICBtX3NwaS5TZXRDaGlwU2VsZWN0QWN0aXZlTG93KCk7CisKKyAgLy8gVmFsaWRhdGUgdGhlIHBhcnQgSUQKKyAgdWludDhfdCBjb21tYW5kc1szXTsKKyAgY29tbWFuZHNbMF0gPSBrUmVnUmVhZDsKKyAgY29tbWFuZHNbMV0gPSBrUGFydElkUmVnaXN0ZXI7CisgIGNvbW1hbmRzWzJdID0gMDsKKyAgbV9zcGkuVHJhbnNhY3Rpb24oY29tbWFuZHMsIGNvbW1hbmRzLCAzKTsKKyAgaWYgKGNvbW1hbmRzWzJdICE9IDB4RjIpIHsKKyAgICBEcml2ZXJTdGF0aW9uOjpSZXBvcnRFcnJvcigiY291bGQgbm90IGZpbmQgQURYTDM2MiIpOworICAgIG1fZ3NQZXJMU0IgPSAwLjA7CisgICAgcmV0dXJuOworICB9CisKKyAgU2V0UmFuZ2UocmFuZ2UpOworCisgIC8vIFR1cm4gb24gdGhlIG1lYXN1cmVtZW50cworICBjb21tYW5kc1swXSA9IGtSZWdXcml0ZTsKKyAgY29tbWFuZHNbMV0gPSBrUG93ZXJDdGxSZWdpc3RlcjsKKyAgY29tbWFuZHNbMl0gPSBrUG93ZXJDdGxfTWVhc3VyZSB8IGtQb3dlckN0bF9VbHRyYUxvd05vaXNlOworICBtX3NwaS5Xcml0ZShjb21tYW5kcywgMyk7CisKKyAgSEFMUmVwb3J0KEhBTFVzYWdlUmVwb3J0aW5nOjprUmVzb3VyY2VUeXBlX0FEWEwzNjIsIHBvcnQpOworCisgIExpdmVXaW5kb3c6OkdldEluc3RhbmNlKCktPkFkZFNlbnNvcigiQURYTDM2MiIsIHBvcnQsIHRoaXMpOworfQorCisvKioge0Bpbmhlcml0ZG9jfSAqLwordm9pZCBBRFhMMzYyOjpTZXRSYW5nZShSYW5nZSByYW5nZSkgeworICBpZiAobV9nc1BlckxTQiA9PSAwLjApIHJldHVybjsKKworICB1aW50OF90IGNvbW1hbmRzWzNdOworCisgIHN3aXRjaCAocmFuZ2UpIHsKKyAgICBjYXNlIGtSYW5nZV8yRzoKKyAgICAgIG1fZ3NQZXJMU0IgPSAwLjAwMTsKKyAgICAgIGJyZWFrOworICAgIGNhc2Uga1JhbmdlXzRHOgorICAgICAgbV9nc1BlckxTQiA9IDAuMDAyOworICAgICAgYnJlYWs7CisgICAgY2FzZSBrUmFuZ2VfOEc6CisgICAgY2FzZSBrUmFuZ2VfMTZHOiAgLy8gMTZHIG5vdCBzdXBwb3J0ZWQ7IHRyZWF0IGFzIDhHCisgICAgICBtX2dzUGVyTFNCID0gMC4wMDQ7CisgICAgICBicmVhazsKKyAgfQorCisgIC8vIFNwZWNpZnkgdGhlIGRhdGEgZm9ybWF0IHRvIHJlYWQKKyAgY29tbWFuZHNbMF0gPSBrUmVnV3JpdGU7CisgIGNvbW1hbmRzWzFdID0ga0ZpbHRlckN0bFJlZ2lzdGVyOworICBjb21tYW5kc1syXSA9IGtGaWx0ZXJDdGxfT0RSXzEwMEh6IHwgKHVpbnQ4X3QpKChyYW5nZSAmIDB4MDMpIDw8IDYpOworICBtX3NwaS5Xcml0ZShjb21tYW5kcywgMyk7Cit9CisKKy8qKiB7QGluaGVyaXRkb2N9ICovCitkb3VibGUgQURYTDM2Mjo6R2V0WCgpIHsgcmV0dXJuIEdldEFjY2VsZXJhdGlvbihrQXhpc19YKTsgfQorCisvKioge0Bpbmhlcml0ZG9jfSAqLworZG91YmxlIEFEWEwzNjI6OkdldFkoKSB7IHJldHVybiBHZXRBY2NlbGVyYXRpb24oa0F4aXNfWSk7IH0KKworLyoqIHtAaW5oZXJpdGRvY30gKi8KK2RvdWJsZSBBRFhMMzYyOjpHZXRaKCkgeyByZXR1cm4gR2V0QWNjZWxlcmF0aW9uKGtBeGlzX1opOyB9CisKKy8qKgorICogR2V0IHRoZSBhY2NlbGVyYXRpb24gb2Ygb25lIGF4aXMgaW4gR3MuCisgKgorICogQHBhcmFtIGF4aXMgVGhlIGF4aXMgdG8gcmVhZCBmcm9tLgorICogQHJldHVybiBBY2NlbGVyYXRpb24gb2YgdGhlIEFEWEwzNjIgaW4gR3MuCisgKi8KK2RvdWJsZSBBRFhMMzYyOjpHZXRBY2NlbGVyYXRpb24oQURYTDM2Mjo6QXhlcyBheGlzKSB7CisgIGlmIChtX2dzUGVyTFNCID09IDAuMCkgcmV0dXJuIDAuMDsKKworICB1aW50OF90IGJ1ZmZlcls0XTsKKyAgdWludDhfdCBjb21tYW5kWzRdID0gezAsIDAsIDAsIDB9OworICBjb21tYW5kWzBdID0ga1JlZ1JlYWQ7CisgIGNvbW1hbmRbMV0gPSBrRGF0YVJlZ2lzdGVyICsgKHVpbnQ4X3QpYXhpczsKKyAgbV9zcGkuVHJhbnNhY3Rpb24oY29tbWFuZCwgYnVmZmVyLCA0KTsKKworICAvLyBTZW5zb3IgaXMgbGl0dGxlIGVuZGlhbi4uLiBzd2FwIGJ5dGVzCisgIGludDE2X3QgcmF3QWNjZWwgPSBidWZmZXJbM10gPDwgOCB8IGJ1ZmZlclsyXTsKKyAgcmV0dXJuIHJhd0FjY2VsICogbV9nc1BlckxTQjsKK30KKworLyoqCisgKiBHZXQgdGhlIGFjY2VsZXJhdGlvbiBvZiBhbGwgYXhlcyBpbiBHcy4KKyAqCisgKiBAcmV0dXJuIEFuIG9iamVjdCBjb250YWluaW5nIHRoZSBhY2NlbGVyYXRpb24gbWVhc3VyZWQgb24gZWFjaCBheGlzIG9mIHRoZQorICogQURYTDM2MiBpbiBHcy4KKyAqLworQURYTDM2Mjo6QWxsQXhlcyBBRFhMMzYyOjpHZXRBY2NlbGVyYXRpb25zKCkgeworICBBbGxBeGVzIGRhdGEgPSBBbGxBeGVzKCk7CisgIGlmIChtX2dzUGVyTFNCID09IDAuMCkgeworICAgIGRhdGEuWEF4aXMgPSBkYXRhLllBeGlzID0gZGF0YS5aQXhpcyA9IDAuMDsKKyAgICByZXR1cm4gZGF0YTsKKyAgfQorCisgIHVpbnQ4X3QgZGF0YUJ1ZmZlcls4XSA9IHswLCAwLCAwLCAwLCAwLCAwLCAwLCAwfTsKKyAgaW50MTZfdCByYXdEYXRhWzNdOworCisgIC8vIFNlbGVjdCB0aGUgZGF0YSBhZGRyZXNzLgorICBkYXRhQnVmZmVyWzBdID0ga1JlZ1JlYWQ7CisgIGRhdGFCdWZmZXJbMV0gPSBrRGF0YVJlZ2lzdGVyOworICBtX3NwaS5UcmFuc2FjdGlvbihkYXRhQnVmZmVyLCBkYXRhQnVmZmVyLCA4KTsKKworICBmb3IgKGludDMyX3QgaSA9IDA7IGkgPCAzOyBpKyspIHsKKyAgICAvLyBTZW5zb3IgaXMgbGl0dGxlIGVuZGlhbi4uLiBzd2FwIGJ5dGVzCisgICAgcmF3RGF0YVtpXSA9IGRhdGFCdWZmZXJbaSAqIDIgKyAzXSA8PCA4IHwgZGF0YUJ1ZmZlcltpICogMiArIDJdOworICB9CisKKyAgZGF0YS5YQXhpcyA9IHJhd0RhdGFbMF0gKiBtX2dzUGVyTFNCOworICBkYXRhLllBeGlzID0gcmF3RGF0YVsxXSAqIG1fZ3NQZXJMU0I7CisgIGRhdGEuWkF4aXMgPSByYXdEYXRhWzJdICogbV9nc1BlckxTQjsKKworICByZXR1cm4gZGF0YTsKK30KKworc3RkOjpzdHJpbmcgQURYTDM2Mjo6R2V0U21hcnREYXNoYm9hcmRUeXBlKCkgY29uc3QgeworICByZXR1cm4gIjNBeGlzQWNjZWxlcm9tZXRlciI7Cit9CisKK3ZvaWQgQURYTDM2Mjo6SW5pdFRhYmxlKHN0ZDo6c2hhcmVkX3B0cjxJVGFibGU+IHN1YnRhYmxlKSB7CisgIG1fdGFibGUgPSBzdWJ0YWJsZTsKKyAgVXBkYXRlVGFibGUoKTsKK30KKwordm9pZCBBRFhMMzYyOjpVcGRhdGVUYWJsZSgpIHsKKyAgaWYgKG1fdGFibGUgIT0gbnVsbHB0cikgeworICAgIG1fdGFibGUtPlB1dE51bWJlcigiWCIsIEdldFgoKSk7CisgICAgbV90YWJsZS0+UHV0TnVtYmVyKCJZIiwgR2V0WSgpKTsKKyAgICBtX3RhYmxlLT5QdXROdW1iZXIoIloiLCBHZXRaKCkpOworICB9Cit9CisKK3N0ZDo6c2hhcmVkX3B0cjxJVGFibGU+IEFEWEwzNjI6OkdldFRhYmxlKCkgY29uc3QgeyByZXR1cm4gbV90YWJsZTsgfQpkaWZmIC0tZ2l0IGEvd3BpbGliYy9BdGhlbmEvc3JjL0FEWFJTNDUwX0d5cm8uY3BwIGIvd3BpbGliYy9BdGhlbmEvc3JjL0FEWFJTNDUwX0d5cm8uY3BwCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjZiMTExY2YKLS0tIC9kZXYvbnVsbAorKysgYi93cGlsaWJjL0F0aGVuYS9zcmMvQURYUlM0NTBfR3lyby5jcHAKQEAgLTAsMCArMSwxNTcgQEAKKy8qLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovCisvKiBDb3B5cmlnaHQgKGMpIEZJUlNUIDIwMTUuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqLworLyogT3BlbiBTb3VyY2UgU29mdHdhcmUgLSBtYXkgYmUgbW9kaWZpZWQgYW5kIHNoYXJlZCBieSBGUkMgdGVhbXMuIFRoZSBjb2RlICAgKi8KKy8qIG11c3QgYmUgYWNjb21wYW5pZWQgYnkgdGhlIEZJUlNUIEJTRCBsaWNlbnNlIGZpbGUgaW4gdGhlIHJvb3QgZGlyZWN0b3J5IG9mICovCisvKiB0aGUgcHJvamVjdC4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqLworLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi8KKworI2luY2x1ZGUgIkFEWFJTNDUwX0d5cm8uaCIKKyNpbmNsdWRlICJEcml2ZXJTdGF0aW9uLmgiCisjaW5jbHVkZSAiTGl2ZVdpbmRvdy9MaXZlV2luZG93LmgiCisjaW5jbHVkZSAiVGltZXIuaCIKKworc3RhdGljIGNvbnN0ZXhwciBkb3VibGUga1NhbXBsZVBlcmlvZCA9IDAuMDAxOworc3RhdGljIGNvbnN0ZXhwciBkb3VibGUga0NhbGlicmF0aW9uU2FtcGxlVGltZSA9IDUuMDsKK3N0YXRpYyBjb25zdGV4cHIgZG91YmxlIGtEZWdyZWVQZXJTZWNvbmRQZXJMU0IgPSAwLjAxMjU7CisKK3N0YXRpYyBjb25zdGV4cHIgdWludDhfdCBrUmF0ZVJlZ2lzdGVyID0gMHgwMDsKK3N0YXRpYyBjb25zdGV4cHIgdWludDhfdCBrVGVtUmVnaXN0ZXIgPSAweDAyOworc3RhdGljIGNvbnN0ZXhwciB1aW50OF90IGtMb0NTVFJlZ2lzdGVyID0gMHgwNDsKK3N0YXRpYyBjb25zdGV4cHIgdWludDhfdCBrSGlDU1RSZWdpc3RlciA9IDB4MDY7CitzdGF0aWMgY29uc3RleHByIHVpbnQ4X3Qga1F1YWRSZWdpc3RlciA9IDB4MDg7CitzdGF0aWMgY29uc3RleHByIHVpbnQ4X3Qga0ZhdWx0UmVnaXN0ZXIgPSAweDBBOworc3RhdGljIGNvbnN0ZXhwciB1aW50OF90IGtQSURSZWdpc3RlciA9IDB4MEM7CitzdGF0aWMgY29uc3RleHByIHVpbnQ4X3Qga1NOSGlnaFJlZ2lzdGVyID0gMHgwRTsKK3N0YXRpYyBjb25zdGV4cHIgdWludDhfdCBrU05Mb3dSZWdpc3RlciA9IDB4MTA7CisKKy8qKgorICogSW5pdGlhbGl6ZSB0aGUgZ3lyby4KKyAqIENhbGlicmF0ZSB0aGUgZ3lybyBieSBydW5uaW5nIGZvciBhIG51bWJlciBvZiBzYW1wbGVzIGFuZCBjb21wdXRpbmcgdGhlCisgKiBjZW50ZXIgdmFsdWUuCisgKiBUaGVuIHVzZSB0aGUgY2VudGVyIHZhbHVlIGFzIHRoZSBBY2N1bXVsYXRvciBjZW50ZXIgdmFsdWUgZm9yIHN1YnNlcXVlbnQKKyAqIG1lYXN1cmVtZW50cy4KKyAqIEl0J3MgaW1wb3J0YW50IHRvIG1ha2Ugc3VyZSB0aGF0IHRoZSByb2JvdCBpcyBub3QgbW92aW5nIHdoaWxlIHRoZSBjZW50ZXJpbmcKKyAqIGNhbGN1bGF0aW9ucyBhcmUgaW4gcHJvZ3Jlc3MsIHRoaXMgaXMgdHlwaWNhbGx5IGRvbmUgd2hlbiB0aGUgcm9ib3QgaXMgZmlyc3QKKyAqIHR1cm5lZCBvbiB3aGlsZSBpdCdzIHNpdHRpbmcgYXQgcmVzdCBiZWZvcmUgdGhlIGNvbXBldGl0aW9uIHN0YXJ0cy4KKyAqLwordm9pZCBBRFhSUzQ1MF9HeXJvOjpDYWxpYnJhdGUoKSB7CisgIFdhaXQoMC4xKTsKKworICBtX3NwaS5TZXRBY2N1bXVsYXRvckNlbnRlcigwKTsKKyAgbV9zcGkuUmVzZXRBY2N1bXVsYXRvcigpOworCisgIFdhaXQoa0NhbGlicmF0aW9uU2FtcGxlVGltZSk7CisKKyAgbV9zcGkuU2V0QWNjdW11bGF0b3JDZW50ZXIoKGludDMyX3QpbV9zcGkuR2V0QWNjdW11bGF0b3JBdmVyYWdlKCkpOworICBtX3NwaS5SZXNldEFjY3VtdWxhdG9yKCk7Cit9CisKKy8qKgorICogR3lybyBjb25zdHJ1Y3RvciBvbiBvbmJvYXJkIENTMC4KKyAqLworQURYUlM0NTBfR3lybzo6QURYUlM0NTBfR3lybygpIDogQURYUlM0NTBfR3lybyhTUEk6OmtPbmJvYXJkQ1MwKSB7fQorCisvKioKKyAqIEd5cm8gY29uc3RydWN0b3Igb24gdGhlIHNwZWNpZmllZCBTUEkgcG9ydC4KKyAqCisgKiBAcGFyYW0gcG9ydCBUaGUgU1BJIHBvcnQgdGhlIGd5cm8gaXMgYXR0YWNoZWQgdG8uCisgKi8KK0FEWFJTNDUwX0d5cm86OkFEWFJTNDUwX0d5cm8oU1BJOjpQb3J0IHBvcnQpIDogbV9zcGkocG9ydCkgeworICBtX3NwaS5TZXRDbG9ja1JhdGUoMzAwMDAwMCk7CisgIG1fc3BpLlNldE1TQkZpcnN0KCk7CisgIG1fc3BpLlNldFNhbXBsZURhdGFPblJpc2luZygpOworICBtX3NwaS5TZXRDbG9ja0FjdGl2ZUhpZ2goKTsKKyAgbV9zcGkuU2V0Q2hpcFNlbGVjdEFjdGl2ZUxvdygpOworCisgIC8vIFZhbGlkYXRlIHRoZSBwYXJ0IElECisgIGlmICgoUmVhZFJlZ2lzdGVyKGtQSURSZWdpc3RlcikgJiAweGZmMDApICE9IDB4NTIwMCkgeworICAgIERyaXZlclN0YXRpb246OlJlcG9ydEVycm9yKCJjb3VsZCBub3QgZmluZCBBRFhSUzQ1MCBneXJvIik7CisgICAgcmV0dXJuOworICB9CisKKyAgbV9zcGkuSW5pdEFjY3VtdWxhdG9yKGtTYW1wbGVQZXJpb2QsIDB4MjAwMDAwMDB1LCA0LCAweDBjMDAwMDAwdSwgMHgwNDAwMDAwMHUsCisgICAgICAgICAgICAgICAgICAgICAgICAxMHUsIDE2dSwgdHJ1ZSwgdHJ1ZSk7CisKKyAgQ2FsaWJyYXRlKCk7CisKKyAgSEFMUmVwb3J0KEhBTFVzYWdlUmVwb3J0aW5nOjprUmVzb3VyY2VUeXBlX0FEWFJTNDUwLCBwb3J0KTsKKyAgTGl2ZVdpbmRvdzo6R2V0SW5zdGFuY2UoKS0+QWRkU2Vuc29yKCJBRFhSUzQ1MF9HeXJvIiwgcG9ydCwgdGhpcyk7Cit9CisKK3N0YXRpYyBib29sIENhbGNQYXJpdHkodWludDMyX3QgdikgeworICBib29sIHBhcml0eSA9IGZhbHNlOworICB3aGlsZSAodiAhPSAwKSB7CisgICAgcGFyaXR5ID0gIXBhcml0eTsKKyAgICB2ID0gdiAmICh2IC0gMSk7CisgIH0KKyAgcmV0dXJuIHBhcml0eTsKK30KKworc3RhdGljIGlubGluZSB1aW50MzJfdCBCeXRlc1RvSW50QkUodWludDhfdCogYnVmKSB7CisgIHVpbnQzMl90IHJlc3VsdCA9ICgodWludDMyX3QpYnVmWzBdKSA8PCAyNDsKKyAgcmVzdWx0IHw9ICgodWludDMyX3QpYnVmWzFdKSA8PCAxNjsKKyAgcmVzdWx0IHw9ICgodWludDMyX3QpYnVmWzJdKSA8PCA4OworICByZXN1bHQgfD0gKHVpbnQzMl90KWJ1ZlszXTsKKyAgcmV0dXJuIHJlc3VsdDsKK30KKwordWludDE2X3QgQURYUlM0NTBfR3lybzo6UmVhZFJlZ2lzdGVyKHVpbnQ4X3QgcmVnKSB7CisgIHVpbnQzMl90IGNtZCA9IDB4ODAwMDAwMDAgfCAoKCh1aW50MzJfdClyZWcpIDw8IDE3KTsKKyAgaWYgKCFDYWxjUGFyaXR5KGNtZCkpIGNtZCB8PSAxdTsKKworICAvLyBiaWcgZW5kaWFuCisgIHVpbnQ4X3QgYnVmWzRdID0geyh1aW50OF90KSgoY21kID4+IDI0KSAmIDB4ZmYpLAorICAgICAgICAgICAgICAgICAgICAodWludDhfdCkoKGNtZCA+PiAxNikgJiAweGZmKSwKKyAgICAgICAgICAgICAgICAgICAgKHVpbnQ4X3QpKChjbWQgPj4gOCkgJiAweGZmKSwKKyAgICAgICAgICAgICAgICAgICAgKHVpbnQ4X3QpKGNtZCAmIDB4ZmYpfTsKKworICBtX3NwaS5Xcml0ZShidWYsIDQpOworICBtX3NwaS5SZWFkKGZhbHNlLCBidWYsIDQpOworICBpZiAoKGJ1ZlswXSAmIDB4ZTApID09IDApIHJldHVybiAwOyAgLy8gZXJyb3IsIHJldHVybiAwCisgIHJldHVybiAodWludDE2X3QpKChCeXRlc1RvSW50QkUoYnVmKSA+PiA1KSAmIDB4ZmZmZik7Cit9CisKKy8qKgorICogUmVzZXQgdGhlIGd5cm8uCisgKiBSZXNldHMgdGhlIGd5cm8gdG8gYSBoZWFkaW5nIG9mIHplcm8uIFRoaXMgY2FuIGJlIHVzZWQgaWYgdGhlcmUgaXMKKyAqIHNpZ25pZmljYW50CisgKiBkcmlmdCBpbiB0aGUgZ3lybyBhbmQgaXQgbmVlZHMgdG8gYmUgcmVjYWxpYnJhdGVkIGFmdGVyIGl0IGhhcyBiZWVuIHJ1bm5pbmcuCisgKi8KK3ZvaWQgQURYUlM0NTBfR3lybzo6UmVzZXQoKSB7CisgIG1fc3BpLlJlc2V0QWNjdW11bGF0b3IoKTsKK30KKworLyoqCisgKiBSZXR1cm4gdGhlIGFjdHVhbCBhbmdsZSBpbiBkZWdyZWVzIHRoYXQgdGhlIHJvYm90IGlzIGN1cnJlbnRseSBmYWNpbmcuCisgKgorICogVGhlIGFuZ2xlIGlzIGJhc2VkIG9uIHRoZSBjdXJyZW50IGFjY3VtdWxhdG9yIHZhbHVlIGNvcnJlY3RlZCBieSB0aGUKKyAqIG92ZXJzYW1wbGluZyByYXRlLCB0aGUKKyAqIGd5cm8gdHlwZSBhbmQgdGhlIEEvRCBjYWxpYnJhdGlvbiB2YWx1ZXMuCisgKiBUaGUgYW5nbGUgaXMgY29udGludW91cywgdGhhdCBpcyBpdCB3aWxsIGNvbnRpbnVlIGZyb20gMzYwLT4zNjEgZGVncmVlcy4gVGhpcworICogYWxsb3dzIGFsZ29yaXRobXMgdGhhdCB3b3VsZG4ndAorICogd2FudCB0byBzZWUgYSBkaXNjb250aW51aXR5IGluIHRoZSBneXJvIG91dHB1dCBhcyBpdCBzd2VlcHMgZnJvbSAzNjAgdG8gMCBvbgorICogdGhlIHNlY29uZCB0aW1lIGFyb3VuZC4KKyAqCisgKiBAcmV0dXJuIHRoZSBjdXJyZW50IGhlYWRpbmcgb2YgdGhlIHJvYm90IGluIGRlZ3JlZXMuIFRoaXMgaGVhZGluZyBpcyBiYXNlZCBvbgorICogaW50ZWdyYXRpb24KKyAqIG9mIHRoZSByZXR1cm5lZCByYXRlIGZyb20gdGhlIGd5cm8uCisgKi8KK2Zsb2F0IEFEWFJTNDUwX0d5cm86OkdldEFuZ2xlKCkgY29uc3QgeworICByZXR1cm4gKGZsb2F0KShtX3NwaS5HZXRBY2N1bXVsYXRvclZhbHVlKCkgKiBrRGVncmVlUGVyU2Vjb25kUGVyTFNCICoKKyAgICAgICAgICAgICAgICAga1NhbXBsZVBlcmlvZCk7Cit9CisKKy8qKgorICogUmV0dXJuIHRoZSByYXRlIG9mIHJvdGF0aW9uIG9mIHRoZSBneXJvCisgKgorICogVGhlIHJhdGUgaXMgYmFzZWQgb24gdGhlIG1vc3QgcmVjZW50IHJlYWRpbmcgb2YgdGhlIGd5cm8gYW5hbG9nIHZhbHVlCisgKgorICogQHJldHVybiB0aGUgY3VycmVudCByYXRlIGluIGRlZ3JlZXMgcGVyIHNlY29uZAorICovCitkb3VibGUgQURYUlM0NTBfR3lybzo6R2V0UmF0ZSgpIGNvbnN0IHsKKyAgcmV0dXJuIChkb3VibGUpbV9zcGkuR2V0QWNjdW11bGF0b3JMYXN0VmFsdWUoKSAqIGtEZWdyZWVQZXJTZWNvbmRQZXJMU0I7Cit9CisKK3N0ZDo6c3RyaW5nIEFEWFJTNDUwX0d5cm86OkdldFNtYXJ0RGFzaGJvYXJkVHlwZSgpIGNvbnN0IHsKKyAgcmV0dXJuICJBRFhSUzQ1MF9HeXJvIjsKK30KZGlmZiAtLWdpdCBhL3dwaWxpYmMvQXRoZW5hL3NyYy9BbmFsb2dBY2NlbGVyb21ldGVyLmNwcCBiL3dwaWxpYmMvQXRoZW5hL3NyYy9BbmFsb2dBY2NlbGVyb21ldGVyLmNwcApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi41Y2Y0MWQ5Ci0tLSAvZGV2L251bGwKKysrIGIvd3BpbGliYy9BdGhlbmEvc3JjL0FuYWxvZ0FjY2VsZXJvbWV0ZXIuY3BwCkBAIC0wLDAgKzEsMTI4IEBACisvKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qLworLyogQ29weXJpZ2h0IChjKSBGSVJTVCAyMDA4LiBBbGwgUmlnaHRzIFJlc2VydmVkLgorICovCisvKiBPcGVuIFNvdXJjZSBTb2Z0d2FyZSAtIG1heSBiZSBtb2RpZmllZCBhbmQgc2hhcmVkIGJ5IEZSQyB0ZWFtcy4gVGhlIGNvZGUgICAqLworLyogbXVzdCBiZSBhY2NvbXBhbmllZCBieSB0aGUgRklSU1QgQlNEIGxpY2Vuc2UgZmlsZSBpbiAkKFdJTkRfQkFTRSkvV1BJTGliLiAgKi8KKy8qLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovCisKKyNpbmNsdWRlICJBbmFsb2dBY2NlbGVyb21ldGVyLmgiCisjaW5jbHVkZSAiV1BJRXJyb3JzLmgiCisjaW5jbHVkZSAiTGl2ZVdpbmRvdy9MaXZlV2luZG93LmgiCisKKy8qKgorICogQ29tbW9uIGZ1bmN0aW9uIGZvciBpbml0aWFsaXppbmcgdGhlIGFjY2VsZXJvbWV0ZXIuCisgKi8KK3ZvaWQgQW5hbG9nQWNjZWxlcm9tZXRlcjo6SW5pdEFjY2VsZXJvbWV0ZXIoKSB7CisgIEhBTFJlcG9ydChIQUxVc2FnZVJlcG9ydGluZzo6a1Jlc291cmNlVHlwZV9BY2NlbGVyb21ldGVyLAorICAgICAgICAgICAgbV9hbmFsb2dJbnB1dC0+R2V0Q2hhbm5lbCgpKTsKKyAgTGl2ZVdpbmRvdzo6R2V0SW5zdGFuY2UoKS0+QWRkU2Vuc29yKCJBY2NlbGVyb21ldGVyIiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1fYW5hbG9nSW5wdXQtPkdldENoYW5uZWwoKSwgdGhpcyk7Cit9CisKKy8qKgorICogQ3JlYXRlIGEgbmV3IGluc3RhbmNlIG9mIGFuIGFjY2VsZXJvbWV0ZXIuCisgKiBUaGUgY29uc3RydWN0b3IgYWxsb2NhdGVzIGRlc2lyZWQgYW5hbG9nIGlucHV0LgorICogQHBhcmFtIGNoYW5uZWwgVGhlIGNoYW5uZWwgbnVtYmVyIGZvciB0aGUgYW5hbG9nIGlucHV0IHRoZSBhY2NlbGVyb21ldGVyIGlzCisgKiBjb25uZWN0ZWQgdG8KKyAqLworQW5hbG9nQWNjZWxlcm9tZXRlcjo6QW5hbG9nQWNjZWxlcm9tZXRlcihpbnQzMl90IGNoYW5uZWwpIHsKKyAgbV9hbmFsb2dJbnB1dCA9IHN0ZDo6bWFrZV9zaGFyZWQ8QW5hbG9nSW5wdXQ+KGNoYW5uZWwpOworICBJbml0QWNjZWxlcm9tZXRlcigpOworfQorCisvKioKKyAqIENyZWF0ZSBhIG5ldyBpbnN0YW5jZSBvZiBBY2NlbGVyb21ldGVyIGZyb20gYW4gZXhpc3RpbmcgQW5hbG9nSW5wdXQuCisgKiBNYWtlIGEgbmV3IGluc3RhbmNlIG9mIGFjY2VsZXJvbWV0ZXIgZ2l2ZW4gYW4gQW5hbG9nSW5wdXQuIFRoaXMgaXMKKyAqIHBhcnRpY3VsYXJseSB1c2VmdWwgaWYgdGhlIHBvcnQgaXMgZ29pbmcgdG8gYmUgcmVhZCBhcyBhbiBhbmFsb2cgY2hhbm5lbCBhcworICogd2VsbCBhcyB0aHJvdWdoIHRoZSBBY2NlbGVyb21ldGVyIGNsYXNzLgorICogQHBhcmFtIGNoYW5uZWwgVGhlIGV4aXN0aW5nIEFuYWxvZ0lucHV0IG9iamVjdCBmb3IgdGhlIGFuYWxvZyBpbnB1dCB0aGUKKyAqIGFjY2VsZXJvbWV0ZXIgaXMgY29ubmVjdGVkIHRvCisgKi8KK0FuYWxvZ0FjY2VsZXJvbWV0ZXI6OkFuYWxvZ0FjY2VsZXJvbWV0ZXIoQW5hbG9nSW5wdXQgKmNoYW5uZWwpCisgICAgOiBtX2FuYWxvZ0lucHV0KGNoYW5uZWwsIE51bGxEZWxldGVyPEFuYWxvZ0lucHV0PigpKSB7CisgIGlmIChjaGFubmVsID09IG51bGxwdHIpIHsKKyAgICB3cGlfc2V0V1BJRXJyb3IoTnVsbFBhcmFtZXRlcik7CisgIH0gZWxzZSB7CisgICAgSW5pdEFjY2VsZXJvbWV0ZXIoKTsKKyAgfQorfQorCisvKioKKyAqIENyZWF0ZSBhIG5ldyBpbnN0YW5jZSBvZiBBY2NlbGVyb21ldGVyIGZyb20gYW4gZXhpc3RpbmcgQW5hbG9nSW5wdXQuCisgKiBNYWtlIGEgbmV3IGluc3RhbmNlIG9mIGFjY2VsZXJvbWV0ZXIgZ2l2ZW4gYW4gQW5hbG9nSW5wdXQuIFRoaXMgaXMKKyAqIHBhcnRpY3VsYXJseSB1c2VmdWwgaWYgdGhlIHBvcnQgaXMgZ29pbmcgdG8gYmUgcmVhZCBhcyBhbiBhbmFsb2cgY2hhbm5lbCBhcworICogd2VsbCBhcyB0aHJvdWdoIHRoZSBBY2NlbGVyb21ldGVyIGNsYXNzLgorICogQHBhcmFtIGNoYW5uZWwgVGhlIGV4aXN0aW5nIEFuYWxvZ0lucHV0IG9iamVjdCBmb3IgdGhlIGFuYWxvZyBpbnB1dCB0aGUKKyAqIGFjY2VsZXJvbWV0ZXIgaXMgY29ubmVjdGVkIHRvCisgKi8KK0FuYWxvZ0FjY2VsZXJvbWV0ZXI6OkFuYWxvZ0FjY2VsZXJvbWV0ZXIoc3RkOjpzaGFyZWRfcHRyPEFuYWxvZ0lucHV0PiBjaGFubmVsKQorICAgIDogbV9hbmFsb2dJbnB1dChjaGFubmVsKSB7CisgIGlmIChjaGFubmVsID09IG51bGxwdHIpIHsKKyAgICB3cGlfc2V0V1BJRXJyb3IoTnVsbFBhcmFtZXRlcik7CisgIH0gZWxzZSB7CisgICAgSW5pdEFjY2VsZXJvbWV0ZXIoKTsKKyAgfQorfQorCisvKioKKyAqIFJldHVybiB0aGUgYWNjZWxlcmF0aW9uIGluIEdzLgorICoKKyAqIFRoZSBhY2NlbGVyYXRpb24gaXMgcmV0dXJuZWQgdW5pdHMgb2YgR3MuCisgKgorICogQHJldHVybiBUaGUgY3VycmVudCBhY2NlbGVyYXRpb24gb2YgdGhlIHNlbnNvciBpbiBHcy4KKyAqLworZmxvYXQgQW5hbG9nQWNjZWxlcm9tZXRlcjo6R2V0QWNjZWxlcmF0aW9uKCkgY29uc3QgeworICByZXR1cm4gKG1fYW5hbG9nSW5wdXQtPkdldEF2ZXJhZ2VWb2x0YWdlKCkgLSBtX3plcm9HVm9sdGFnZSkgLyBtX3ZvbHRzUGVyRzsKK30KKworLyoqCisgKiBTZXQgdGhlIGFjY2VsZXJvbWV0ZXIgc2Vuc2l0aXZpdHkuCisgKgorICogVGhpcyBzZXRzIHRoZSBzZW5zaXRpdml0eSBvZiB0aGUgYWNjZWxlcm9tZXRlciB1c2VkIGZvciBjYWxjdWxhdGluZyB0aGUKKyAqIGFjY2VsZXJhdGlvbi4KKyAqIFRoZSBzZW5zaXRpdml0eSB2YXJpZXMgYnkgYWNjZWxlcm9tZXRlciBtb2RlbC4gVGhlcmUgYXJlIGNvbnN0YW50cyBkZWZpbmVkCisgKiBmb3IgdmFyaW91cyBtb2RlbHMuCisgKgorICogQHBhcmFtIHNlbnNpdGl2aXR5IFRoZSBzZW5zaXRpdml0eSBvZiBhY2NlbGVyb21ldGVyIGluIFZvbHRzIHBlciBHLgorICovCit2b2lkIEFuYWxvZ0FjY2VsZXJvbWV0ZXI6OlNldFNlbnNpdGl2aXR5KGZsb2F0IHNlbnNpdGl2aXR5KSB7CisgIG1fdm9sdHNQZXJHID0gc2Vuc2l0aXZpdHk7Cit9CisKKy8qKgorICogU2V0IHRoZSB2b2x0YWdlIHRoYXQgY29ycmVzcG9uZHMgdG8gMCBHLgorICoKKyAqIFRoZSB6ZXJvIEcgdm9sdGFnZSB2YXJpZXMgYnkgYWNjZWxlcm9tZXRlciBtb2RlbC4gVGhlcmUgYXJlIGNvbnN0YW50cyBkZWZpbmVkCisgKiBmb3IgdmFyaW91cyBtb2RlbHMuCisgKgorICogQHBhcmFtIHplcm8gVGhlIHplcm8gRyB2b2x0YWdlLgorICovCit2b2lkIEFuYWxvZ0FjY2VsZXJvbWV0ZXI6OlNldFplcm8oZmxvYXQgemVybykgeyBtX3plcm9HVm9sdGFnZSA9IHplcm87IH0KKworLyoqCisgKiBHZXQgdGhlIEFjY2VsZXJhdGlvbiBmb3IgdGhlIFBJRCBTb3VyY2UgcGFyZW50LgorICoKKyAqIEByZXR1cm4gVGhlIGN1cnJlbnQgYWNjZWxlcmF0aW9uIGluIEdzLgorICovCitkb3VibGUgQW5hbG9nQWNjZWxlcm9tZXRlcjo6UElER2V0KCkgeyByZXR1cm4gR2V0QWNjZWxlcmF0aW9uKCk7IH0KKwordm9pZCBBbmFsb2dBY2NlbGVyb21ldGVyOjpVcGRhdGVUYWJsZSgpIHsKKyAgaWYgKG1fdGFibGUgIT0gbnVsbHB0cikgeworICAgIG1fdGFibGUtPlB1dE51bWJlcigiVmFsdWUiLCBHZXRBY2NlbGVyYXRpb24oKSk7CisgIH0KK30KKwordm9pZCBBbmFsb2dBY2NlbGVyb21ldGVyOjpTdGFydExpdmVXaW5kb3dNb2RlKCkge30KKwordm9pZCBBbmFsb2dBY2NlbGVyb21ldGVyOjpTdG9wTGl2ZVdpbmRvd01vZGUoKSB7fQorCitzdGQ6OnN0cmluZyBBbmFsb2dBY2NlbGVyb21ldGVyOjpHZXRTbWFydERhc2hib2FyZFR5cGUoKSBjb25zdCB7CisgIHJldHVybiAiQWNjZWxlcm9tZXRlciI7Cit9CisKK3ZvaWQgQW5hbG9nQWNjZWxlcm9tZXRlcjo6SW5pdFRhYmxlKHN0ZDo6c2hhcmVkX3B0cjxJVGFibGU+IHN1YlRhYmxlKSB7CisgIG1fdGFibGUgPSBzdWJUYWJsZTsKKyAgVXBkYXRlVGFibGUoKTsKK30KKworc3RkOjpzaGFyZWRfcHRyPElUYWJsZT4gQW5hbG9nQWNjZWxlcm9tZXRlcjo6R2V0VGFibGUoKSBjb25zdCB7IHJldHVybiBtX3RhYmxlOyB9CmRpZmYgLS1naXQgYS93cGlsaWJjL0F0aGVuYS9zcmMvQW5hbG9nR3lyby5jcHAgYi93cGlsaWJjL0F0aGVuYS9zcmMvQW5hbG9nR3lyby5jcHAKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNTQwOTNlYwotLS0gL2Rldi9udWxsCisrKyBiL3dwaWxpYmMvQXRoZW5hL3NyYy9BbmFsb2dHeXJvLmNwcApAQCAtMCwwICsxLDI1NSBAQAorLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi8KKy8qIENvcHlyaWdodCAoYykgRklSU1QgMjAwOC4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KKyAqLworLyogT3BlbiBTb3VyY2UgU29mdHdhcmUgLSBtYXkgYmUgbW9kaWZpZWQgYW5kIHNoYXJlZCBieSBGUkMgdGVhbXMuIFRoZSBjb2RlICAgKi8KKy8qIG11c3QgYmUgYWNjb21wYW5pZWQgYnkgdGhlIEZJUlNUIEJTRCBsaWNlbnNlIGZpbGUgaW4gJChXSU5EX0JBU0UpL1dQSUxpYi4gICovCisvKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qLworCisjaW5jbHVkZSAiQW5hbG9nR3lyby5oIgorI2luY2x1ZGUgIkFuYWxvZ0lucHV0LmgiCisjaW5jbHVkZSAiVGltZXIuaCIKKyNpbmNsdWRlICJXUElFcnJvcnMuaCIKKyNpbmNsdWRlICJMaXZlV2luZG93L0xpdmVXaW5kb3cuaCIKKyNpbmNsdWRlIDxjbGltaXRzPgorY29uc3QgdWludDMyX3QgQW5hbG9nR3lybzo6a092ZXJzYW1wbGVCaXRzOworY29uc3QgdWludDMyX3QgQW5hbG9nR3lybzo6a0F2ZXJhZ2VCaXRzOworY29uc3RleHByIGZsb2F0IEFuYWxvZ0d5cm86OmtTYW1wbGVzUGVyU2Vjb25kOworY29uc3RleHByIGZsb2F0IEFuYWxvZ0d5cm86OmtDYWxpYnJhdGlvblNhbXBsZVRpbWU7Citjb25zdGV4cHIgZmxvYXQgQW5hbG9nR3lybzo6a0RlZmF1bHRWb2x0c1BlckRlZ3JlZVBlclNlY29uZDsKKworLyoqCisgKiBHeXJvIGNvbnN0cnVjdG9yIHVzaW5nIHRoZSBBbmFsb2cgSW5wdXQgY2hhbm5lbCBudW1iZXIuCisgKgorICogQHBhcmFtIGNoYW5uZWwgVGhlIGFuYWxvZyBjaGFubmVsIHRoZSBneXJvIGlzIGNvbm5lY3RlZCB0by4gR3lyb3MKKyAgICAgICAgICAgICAgICAgICAgICBjYW4gb25seSBiZSB1c2VkIG9uIG9uLWJvYXJkIEFuYWxvZyBJbnB1dHMgMC0xLgorICovCitBbmFsb2dHeXJvOjpBbmFsb2dHeXJvKGludDMyX3QgY2hhbm5lbCkgOgorICAgIEFuYWxvZ0d5cm8oc3RkOjptYWtlX3NoYXJlZDxBbmFsb2dJbnB1dD4oY2hhbm5lbCkpIHt9CisKKy8qKgorICogR3lybyBjb25zdHJ1Y3RvciB3aXRoIGEgcHJlY3JlYXRlZCBBbmFsb2dJbnB1dCBvYmplY3QuCisgKiBVc2UgdGhpcyBjb25zdHJ1Y3RvciB3aGVuIHRoZSBhbmFsb2cgY2hhbm5lbCBuZWVkcyB0byBiZSBzaGFyZWQuCisgKiBUaGlzIG9iamVjdCB3aWxsIG5vdCBjbGVhbiB1cCB0aGUgQW5hbG9nSW5wdXQgb2JqZWN0IHdoZW4gdXNpbmcgdGhpcworICogY29uc3RydWN0b3IuCisgKiBHeXJvcyBjYW4gb25seSBiZSB1c2VkIG9uIG9uLWJvYXJkIGNoYW5uZWxzIDAtMS4KKyAqIEBwYXJhbSBjaGFubmVsIEEgcG9pbnRlciB0byB0aGUgQW5hbG9nSW5wdXQgb2JqZWN0IHRoYXQgdGhlIGd5cm8gaXMgY29ubmVjdGVkCisgKiB0by4KKyAqLworQW5hbG9nR3lybzo6QW5hbG9nR3lybyhBbmFsb2dJbnB1dCAqY2hhbm5lbCkKKyAgICA6IEFuYWxvZ0d5cm8oCisgICAgICAgICAgc3RkOjpzaGFyZWRfcHRyPEFuYWxvZ0lucHV0PihjaGFubmVsLCBOdWxsRGVsZXRlcjxBbmFsb2dJbnB1dD4oKSkpIHt9CisKKy8qKgorICogR3lybyBjb25zdHJ1Y3RvciB3aXRoIGEgcHJlY3JlYXRlZCBBbmFsb2dJbnB1dCBvYmplY3QuCisgKiBVc2UgdGhpcyBjb25zdHJ1Y3RvciB3aGVuIHRoZSBhbmFsb2cgY2hhbm5lbCBuZWVkcyB0byBiZSBzaGFyZWQuCisgKiBUaGlzIG9iamVjdCB3aWxsIG5vdCBjbGVhbiB1cCB0aGUgQW5hbG9nSW5wdXQgb2JqZWN0IHdoZW4gdXNpbmcgdGhpcworICogY29uc3RydWN0b3IKKyAqIEBwYXJhbSBjaGFubmVsIEEgcG9pbnRlciB0byB0aGUgQW5hbG9nSW5wdXQgb2JqZWN0IHRoYXQgdGhlIGd5cm8gaXMKKyAqIGNvbm5lY3RlZCB0by4KKyAqLworQW5hbG9nR3lybzo6QW5hbG9nR3lybyhzdGQ6OnNoYXJlZF9wdHI8QW5hbG9nSW5wdXQ+IGNoYW5uZWwpCisgICAgOiBtX2FuYWxvZyhjaGFubmVsKSB7CisgIGlmIChjaGFubmVsID09IG51bGxwdHIpIHsKKyAgICB3cGlfc2V0V1BJRXJyb3IoTnVsbFBhcmFtZXRlcik7CisgIH0gZWxzZSB7CisgICAgSW5pdEd5cm8oKTsKKyAgICBDYWxpYnJhdGUoKTsKKyAgfQorfQorCisvKioKKyAqIEd5cm8gY29uc3RydWN0b3IgdXNpbmcgdGhlIEFuYWxvZyBJbnB1dCBjaGFubmVsIG51bWJlciB3aXRoIHBhcmFtZXRlcnMgZm9yCisgKiBwcmVzZXR0aW5nIHRoZSBjZW50ZXIgYW5kIG9mZnNldCB2YWx1ZXMuIEJ5cGFzc2VzIGNhbGlicmF0aW9uLgorICoKKyAqIEBwYXJhbSBjaGFubmVsIFRoZSBhbmFsb2cgY2hhbm5lbCB0aGUgZ3lybyBpcyBjb25uZWN0ZWQgdG8uIEd5cm9zCisgKiAgICAgICAgY2FuIG9ubHkgYmUgdXNlZCBvbiBvbi1ib2FyZCBBbmFsb2cgSW5wdXRzIDAtMS4KKyAqIEBwYXJhbSBjZW50ZXIgUHJlc2V0IHVuY2FsaWJyYXRlZCB2YWx1ZSB0byB1c2UgYXMgdGhlIGFjY3VtdWxhdG9yIGNlbnRlciB2YWx1ZS4KKyAqIEBwYXJhbSBvZmZzZXQgUHJlc2V0IHVuY2FsaWJyYXRlZCB2YWx1ZSB0byB1c2UgYXMgdGhlIGd5cm8gb2Zmc2V0LgorICovCitBbmFsb2dHeXJvOjpBbmFsb2dHeXJvKGludDMyX3QgY2hhbm5lbCwgdWludDMyX3QgY2VudGVyLCBmbG9hdCBvZmZzZXQpIHsKKyAgbV9hbmFsb2cgPSBzdGQ6Om1ha2Vfc2hhcmVkPEFuYWxvZ0lucHV0PihjaGFubmVsKTsKKyAgSW5pdEd5cm8oKTsKKyAgbV9jZW50ZXIgPSBjZW50ZXI7CisgIG1fb2Zmc2V0ID0gb2Zmc2V0OworICBtX2FuYWxvZy0+U2V0QWNjdW11bGF0b3JDZW50ZXIobV9jZW50ZXIpOworICBtX2FuYWxvZy0+UmVzZXRBY2N1bXVsYXRvcigpOworfQorCisvKioKKyAqIEd5cm8gY29uc3RydWN0b3Igd2l0aCBhIHByZWNyZWF0ZWQgQW5hbG9nSW5wdXQgb2JqZWN0IGFuZCBjYWxpYnJhdGVkIHBhcmFtZXRlcnMuCisgKiBVc2UgdGhpcyBjb25zdHJ1Y3RvciB3aGVuIHRoZSBhbmFsb2cgY2hhbm5lbCBuZWVkcyB0byBiZSBzaGFyZWQuCisgKiBUaGlzIG9iamVjdCB3aWxsIG5vdCBjbGVhbiB1cCB0aGUgQW5hbG9nSW5wdXQgb2JqZWN0IHdoZW4gdXNpbmcgdGhpcworICogY29uc3RydWN0b3IKKyAqIEBwYXJhbSBjaGFubmVsIEEgcG9pbnRlciB0byB0aGUgQW5hbG9nSW5wdXQgb2JqZWN0IHRoYXQgdGhlIGd5cm8gaXMKKyAqIGNvbm5lY3RlZCB0by4KKyAqLworQW5hbG9nR3lybzo6QW5hbG9nR3lybyhzdGQ6OnNoYXJlZF9wdHI8QW5hbG9nSW5wdXQ+IGNoYW5uZWwsIHVpbnQzMl90IGNlbnRlciwgZmxvYXQgb2Zmc2V0KSA6IG1fYW5hbG9nKGNoYW5uZWwpIHsKKyAgaWYgKGNoYW5uZWwgPT0gbnVsbHB0cikgeworICAgIHdwaV9zZXRXUElFcnJvcihOdWxsUGFyYW1ldGVyKTsKKyAgfSBlbHNlIHsKKyAgICBJbml0R3lybygpOworICAgIG1fY2VudGVyID0gY2VudGVyOworICAgIG1fb2Zmc2V0ID0gb2Zmc2V0OworICAgIG1fYW5hbG9nLT5TZXRBY2N1bXVsYXRvckNlbnRlcihtX2NlbnRlcik7CisgICAgbV9hbmFsb2ctPlJlc2V0QWNjdW11bGF0b3IoKTsKKyAgfQorfQorCisvKioKKyAqIFJlc2V0IHRoZSBneXJvLgorICogUmVzZXRzIHRoZSBneXJvIHRvIGEgaGVhZGluZyBvZiB6ZXJvLiBUaGlzIGNhbiBiZSB1c2VkIGlmIHRoZXJlIGlzCisgKiBzaWduaWZpY2FudAorICogZHJpZnQgaW4gdGhlIGd5cm8gYW5kIGl0IG5lZWRzIHRvIGJlIHJlY2FsaWJyYXRlZCBhZnRlciBpdCBoYXMgYmVlbiBydW5uaW5nLgorICovCit2b2lkIEFuYWxvZ0d5cm86OlJlc2V0KCkgeworICBpZiAoU3RhdHVzSXNGYXRhbCgpKSByZXR1cm47CisgIG1fYW5hbG9nLT5SZXNldEFjY3VtdWxhdG9yKCk7Cit9CisKKy8qKgorICogSW5pdGlhbGl6ZSB0aGUgZ3lyby4gIENhbGlicmF0aW9uIGlzIGhhbmRsZWQgYnkgQ2FsaWJyYXRlKCkuCisgKi8KK3ZvaWQgQW5hbG9nR3lybzo6SW5pdEd5cm8oKSB7CisgIGlmIChTdGF0dXNJc0ZhdGFsKCkpIHJldHVybjsKKworICBpZiAoIW1fYW5hbG9nLT5Jc0FjY3VtdWxhdG9yQ2hhbm5lbCgpKSB7CisgICAgd3BpX3NldFdQSUVycm9yV2l0aENvbnRleHQoUGFyYW1ldGVyT3V0T2ZSYW5nZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiIGNoYW5uZWwgKG11c3QgYmUgYWNjdW11bGF0b3IgY2hhbm5lbCkiKTsKKyAgICBtX2FuYWxvZyA9IG51bGxwdHI7CisgICAgcmV0dXJuOworICB9CisKKyAgbV92b2x0c1BlckRlZ3JlZVBlclNlY29uZCA9IGtEZWZhdWx0Vm9sdHNQZXJEZWdyZWVQZXJTZWNvbmQ7CisgIG1fYW5hbG9nLT5TZXRBdmVyYWdlQml0cyhrQXZlcmFnZUJpdHMpOworICBtX2FuYWxvZy0+U2V0T3ZlcnNhbXBsZUJpdHMoa092ZXJzYW1wbGVCaXRzKTsKKyAgZmxvYXQgc2FtcGxlUmF0ZSA9CisgICAgICBrU2FtcGxlc1BlclNlY29uZCAqICgxIDw8IChrQXZlcmFnZUJpdHMgKyBrT3ZlcnNhbXBsZUJpdHMpKTsKKyAgbV9hbmFsb2ctPlNldFNhbXBsZVJhdGUoc2FtcGxlUmF0ZSk7CisgIFdhaXQoMC4xKTsKKworICBTZXREZWFkYmFuZCgwLjBmKTsKKworICBTZXRQSURTb3VyY2VUeXBlKFBJRFNvdXJjZVR5cGU6OmtEaXNwbGFjZW1lbnQpOworCisgIEhBTFJlcG9ydChIQUxVc2FnZVJlcG9ydGluZzo6a1Jlc291cmNlVHlwZV9HeXJvLCBtX2FuYWxvZy0+R2V0Q2hhbm5lbCgpKTsKKyAgTGl2ZVdpbmRvdzo6R2V0SW5zdGFuY2UoKS0+QWRkU2Vuc29yKCJHeXJvIiwgbV9hbmFsb2ctPkdldENoYW5uZWwoKSwgdGhpcyk7Cit9CisKKy8qKgorICoge0Bpbmhlcml0RG9jfQorICovCit2b2lkIEFuYWxvZ0d5cm86OkNhbGlicmF0ZSgpIHsKKyAgaWYgKFN0YXR1c0lzRmF0YWwoKSkgcmV0dXJuOworCisgIG1fYW5hbG9nLT5Jbml0QWNjdW11bGF0b3IoKTsKKworICBXYWl0KGtDYWxpYnJhdGlvblNhbXBsZVRpbWUpOworCisgIGludDY0X3QgdmFsdWU7CisgIHVpbnQzMl90IGNvdW50OworICBtX2FuYWxvZy0+R2V0QWNjdW11bGF0b3JPdXRwdXQodmFsdWUsIGNvdW50KTsKKworICBtX2NlbnRlciA9ICh1aW50MzJfdCkoKGZsb2F0KXZhbHVlIC8gKGZsb2F0KWNvdW50ICsgLjUpOworCisgIG1fb2Zmc2V0ID0gKChmbG9hdCl2YWx1ZSAvIChmbG9hdCljb3VudCkgLSAoZmxvYXQpbV9jZW50ZXI7CisgIG1fYW5hbG9nLT5TZXRBY2N1bXVsYXRvckNlbnRlcihtX2NlbnRlcik7CisgIG1fYW5hbG9nLT5SZXNldEFjY3VtdWxhdG9yKCk7Cit9CisKKy8qKgorICogUmV0dXJuIHRoZSBhY3R1YWwgYW5nbGUgaW4gZGVncmVlcyB0aGF0IHRoZSByb2JvdCBpcyBjdXJyZW50bHkgZmFjaW5nLgorICoKKyAqIFRoZSBhbmdsZSBpcyBiYXNlZCBvbiB0aGUgY3VycmVudCBhY2N1bXVsYXRvciB2YWx1ZSBjb3JyZWN0ZWQgYnkgdGhlCisgKiBvdmVyc2FtcGxpbmcgcmF0ZSwgdGhlCisgKiBneXJvIHR5cGUgYW5kIHRoZSBBL0QgY2FsaWJyYXRpb24gdmFsdWVzLgorICogVGhlIGFuZ2xlIGlzIGNvbnRpbnVvdXMsIHRoYXQgaXMgaXQgd2lsbCBjb250aW51ZSBmcm9tIDM2MC0+MzYxIGRlZ3JlZXMuIFRoaXMKKyAqIGFsbG93cyBhbGdvcml0aG1zIHRoYXQgd291bGRuJ3QKKyAqIHdhbnQgdG8gc2VlIGEgZGlzY29udGludWl0eSBpbiB0aGUgZ3lybyBvdXRwdXQgYXMgaXQgc3dlZXBzIGZyb20gMzYwIHRvIDAgb24KKyAqIHRoZSBzZWNvbmQgdGltZSBhcm91bmQuCisgKgorICogQHJldHVybiB0aGUgY3VycmVudCBoZWFkaW5nIG9mIHRoZSByb2JvdCBpbiBkZWdyZWVzLiBUaGlzIGhlYWRpbmcgaXMgYmFzZWQgb24KKyAqIGludGVncmF0aW9uCisgKiBvZiB0aGUgcmV0dXJuZWQgcmF0ZSBmcm9tIHRoZSBneXJvLgorICovCitmbG9hdCBBbmFsb2dHeXJvOjpHZXRBbmdsZSgpIGNvbnN0IHsKKyAgaWYgKFN0YXR1c0lzRmF0YWwoKSkgcmV0dXJuIDAuZjsKKworICBpbnQ2NF90IHJhd1ZhbHVlOworICB1aW50MzJfdCBjb3VudDsKKyAgbV9hbmFsb2ctPkdldEFjY3VtdWxhdG9yT3V0cHV0KHJhd1ZhbHVlLCBjb3VudCk7CisKKyAgaW50NjRfdCB2YWx1ZSA9IHJhd1ZhbHVlIC0gKGludDY0X3QpKChmbG9hdCljb3VudCAqIG1fb2Zmc2V0KTsKKworICBkb3VibGUgc2NhbGVkVmFsdWUgPSB2YWx1ZSAqIDFlLTkgKiAoZG91YmxlKW1fYW5hbG9nLT5HZXRMU0JXZWlnaHQoKSAqCisgICAgICAgICAgICAgICAgICAgICAgIChkb3VibGUpKDEgPDwgbV9hbmFsb2ctPkdldEF2ZXJhZ2VCaXRzKCkpIC8KKyAgICAgICAgICAgICAgICAgICAgICAgKG1fYW5hbG9nLT5HZXRTYW1wbGVSYXRlKCkgKiBtX3ZvbHRzUGVyRGVncmVlUGVyU2Vjb25kKTsKKworICByZXR1cm4gKGZsb2F0KXNjYWxlZFZhbHVlOworfQorCisvKioKKyAqIFJldHVybiB0aGUgcmF0ZSBvZiByb3RhdGlvbiBvZiB0aGUgZ3lybworICoKKyAqIFRoZSByYXRlIGlzIGJhc2VkIG9uIHRoZSBtb3N0IHJlY2VudCByZWFkaW5nIG9mIHRoZSBneXJvIGFuYWxvZyB2YWx1ZQorICoKKyAqIEByZXR1cm4gdGhlIGN1cnJlbnQgcmF0ZSBpbiBkZWdyZWVzIHBlciBzZWNvbmQKKyAqLworZG91YmxlIEFuYWxvZ0d5cm86OkdldFJhdGUoKSBjb25zdCB7CisgIGlmIChTdGF0dXNJc0ZhdGFsKCkpIHJldHVybiAwLjA7CisKKyAgcmV0dXJuIChtX2FuYWxvZy0+R2V0QXZlcmFnZVZhbHVlKCkgLSAoKGRvdWJsZSltX2NlbnRlciArIG1fb2Zmc2V0KSkgKiAxZS05ICoKKyAgICAgICAgIG1fYW5hbG9nLT5HZXRMU0JXZWlnaHQoKSAvCisgICAgICAgICAoKDEgPDwgbV9hbmFsb2ctPkdldE92ZXJzYW1wbGVCaXRzKCkpICogbV92b2x0c1BlckRlZ3JlZVBlclNlY29uZCk7Cit9CisKKy8qKgorICogUmV0dXJuIHRoZSBneXJvIG9mZnNldCB2YWx1ZS4gSWYgcnVuIGFmdGVyIGNhbGlicmF0aW9uLAorICogdGhlIG9mZnNldCB2YWx1ZSBjYW4gYmUgdXNlZCBhcyBhIHByZXNldCBsYXRlci4KKyAqCisgKiBAcmV0dXJuIHRoZSBjdXJyZW50IG9mZnNldCB2YWx1ZQorICovCitmbG9hdCBBbmFsb2dHeXJvOjpHZXRPZmZzZXQoKSBjb25zdCB7CisgIHJldHVybiBtX29mZnNldDsKK30KKworLyoqCisgKiBSZXR1cm4gdGhlIGd5cm8gY2VudGVyIHZhbHVlLiBJZiBydW4gYWZ0ZXIgY2FsaWJyYXRpb24sCisgKiB0aGUgY2VudGVyIHZhbHVlIGNhbiBiZSB1c2VkIGFzIGEgcHJlc2V0IGxhdGVyLgorICoKKyAqIEByZXR1cm4gdGhlIGN1cnJlbnQgY2VudGVyIHZhbHVlCisgKi8KK3VpbnQzMl90IEFuYWxvZ0d5cm86OkdldENlbnRlcigpIGNvbnN0IHsKKyAgcmV0dXJuIG1fY2VudGVyOworfQorCisvKioKKyAqIFNldCB0aGUgZ3lybyBzZW5zaXRpdml0eS4KKyAqIFRoaXMgdGFrZXMgdGhlIG51bWJlciBvZiB2b2x0cy9kZWdyZWUvc2Vjb25kIHNlbnNpdGl2aXR5IG9mIHRoZSBneXJvIGFuZCB1c2VzCisgKiBpdCBpbiBzdWJzZXF1ZW50CisgKiBjYWxjdWxhdGlvbnMgdG8gYWxsb3cgdGhlIGNvZGUgdG8gd29yayB3aXRoIG11bHRpcGxlIGd5cm9zLiBUaGlzIHZhbHVlIGlzCisgKiB0eXBpY2FsbHkgZm91bmQgaW4KKyAqIHRoZSBneXJvIGRhdGFzaGVldC4KKyAqCisgKiBAcGFyYW0gdm9sdHNQZXJEZWdyZWVQZXJTZWNvbmQgVGhlIHNlbnNpdGl2aXR5IGluIFZvbHRzL2RlZ3JlZS9zZWNvbmQKKyAqLwordm9pZCBBbmFsb2dHeXJvOjpTZXRTZW5zaXRpdml0eShmbG9hdCB2b2x0c1BlckRlZ3JlZVBlclNlY29uZCkgeworICBtX3ZvbHRzUGVyRGVncmVlUGVyU2Vjb25kID0gdm9sdHNQZXJEZWdyZWVQZXJTZWNvbmQ7Cit9CisKKy8qKgorICogU2V0IHRoZSBzaXplIG9mIHRoZSBuZXV0cmFsIHpvbmUuICBBbnkgdm9sdGFnZSBmcm9tIHRoZSBneXJvIGxlc3MgdGhhbiB0aGlzCisgKiBhbW91bnQgZnJvbSB0aGUgY2VudGVyIGlzIGNvbnNpZGVyZWQgc3RhdGlvbmFyeS4gIFNldHRpbmcgYSBkZWFkYmFuZCB3aWxsCisgKiBkZWNyZWFzZSB0aGUgYW1vdW50IG9mIGRyaWZ0IHdoZW4gdGhlIGd5cm8gaXNuJ3Qgcm90YXRpbmcsIGJ1dCB3aWxsIG1ha2UgaXQKKyAqIGxlc3MgYWNjdXJhdGUuCisgKgorICogQHBhcmFtIHZvbHRzIFRoZSBzaXplIG9mIHRoZSBkZWFkYmFuZCBpbiB2b2x0cworICovCit2b2lkIEFuYWxvZ0d5cm86OlNldERlYWRiYW5kKGZsb2F0IHZvbHRzKSB7CisgIGlmIChTdGF0dXNJc0ZhdGFsKCkpIHJldHVybjsKKworICBpbnQzMl90IGRlYWRiYW5kID0gdm9sdHMgKiAxZTkgLyBtX2FuYWxvZy0+R2V0TFNCV2VpZ2h0KCkgKgorICAgICAgICAgICAgICAgICAgICAgKDEgPDwgbV9hbmFsb2ctPkdldE92ZXJzYW1wbGVCaXRzKCkpOworICBtX2FuYWxvZy0+U2V0QWNjdW11bGF0b3JEZWFkYmFuZChkZWFkYmFuZCk7Cit9CisKK3N0ZDo6c3RyaW5nIEFuYWxvZ0d5cm86OkdldFNtYXJ0RGFzaGJvYXJkVHlwZSgpIGNvbnN0IHsgcmV0dXJuICJBbmFsb2dHeXJvIjsgfQpkaWZmIC0tZ2l0IGEvd3BpbGliYy9BdGhlbmEvc3JjL0FuYWxvZ0lucHV0LmNwcCBiL3dwaWxpYmMvQXRoZW5hL3NyYy9BbmFsb2dJbnB1dC5jcHAKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZGM4ZTg3MgotLS0gL2Rldi9udWxsCisrKyBiL3dwaWxpYmMvQXRoZW5hL3NyYy9BbmFsb2dJbnB1dC5jcHAKQEAgLTAsMCArMSw0MjYgQEAKKy8qLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovCisvKiBDb3B5cmlnaHQgKGMpIEZJUlNUIDIwMDguIEFsbCBSaWdodHMgUmVzZXJ2ZWQuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqLworLyogT3BlbiBTb3VyY2UgU29mdHdhcmUgLSBtYXkgYmUgbW9kaWZpZWQgYW5kIHNoYXJlZCBieSBGUkMgdGVhbXMuIFRoZSBjb2RlICAgKi8KKy8qIG11c3QgYmUgYWNjb21wYW5pZWQgYnkgdGhlIEZJUlNUIEJTRCBsaWNlbnNlIGZpbGUgaW4gJChXSU5EX0JBU0UpL1dQSUxpYi4gICovCisvKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qLworCisjaW5jbHVkZSAiQW5hbG9nSW5wdXQuaCIKKyNpbmNsdWRlICJSZXNvdXJjZS5oIgorI2luY2x1ZGUgIlRpbWVyLmgiCisjaW5jbHVkZSAiV1BJRXJyb3JzLmgiCisjaW5jbHVkZSAiTGl2ZVdpbmRvdy9MaXZlV2luZG93LmgiCisjaW5jbHVkZSAiSEFML1BvcnQuaCIKKworI2luY2x1ZGUgPHNzdHJlYW0+CisKK3N0YXRpYyBzdGQ6OnVuaXF1ZV9wdHI8UmVzb3VyY2U+IGlucHV0czsKKworY29uc3QgdWludDhfdCBBbmFsb2dJbnB1dDo6a0FjY3VtdWxhdG9yTW9kdWxlTnVtYmVyOworY29uc3QgdWludDMyX3QgQW5hbG9nSW5wdXQ6OmtBY2N1bXVsYXRvck51bUNoYW5uZWxzOworY29uc3QgdWludDMyX3QgQW5hbG9nSW5wdXQ6OmtBY2N1bXVsYXRvckNoYW5uZWxzW10gPSB7MCwgMX07CisKKy8qKgorICogQ29uc3RydWN0IGFuIGFuYWxvZyBpbnB1dC4KKyAqCisgKiBAcGFyYW0gY2hhbm5lbCBUaGUgY2hhbm5lbCBudW1iZXIgb24gdGhlIHJvYm9SSU8gdG8gcmVwcmVzZW50LiAwLTMgYXJlCisgKiBvbi1ib2FyZCA0LTcgYXJlIG9uIHRoZSBNWFAgcG9ydC4KKyAqLworQW5hbG9nSW5wdXQ6OkFuYWxvZ0lucHV0KHVpbnQzMl90IGNoYW5uZWwpIHsKKyAgc3RkOjpzdHJpbmdzdHJlYW0gYnVmOworICBidWYgPDwgIkFuYWxvZyBJbnB1dCAiIDw8IGNoYW5uZWw7CisgIFJlc291cmNlOjpDcmVhdGVSZXNvdXJjZU9iamVjdChpbnB1dHMsIGtBbmFsb2dJbnB1dHMpOworCisgIGlmICghY2hlY2tBbmFsb2dJbnB1dENoYW5uZWwoY2hhbm5lbCkpIHsKKyAgICB3cGlfc2V0V1BJRXJyb3JXaXRoQ29udGV4dChDaGFubmVsSW5kZXhPdXRPZlJhbmdlLCBidWYuc3RyKCkpOworICAgIHJldHVybjsKKyAgfQorCisgIGlmIChpbnB1dHMtPkFsbG9jYXRlKGNoYW5uZWwsIGJ1Zi5zdHIoKSkgPT0KKyAgICAgIHN0ZDo6bnVtZXJpY19saW1pdHM8dWludDMyX3Q+OjptYXgoKSkgeworICAgIENsb25lRXJyb3IoKmlucHV0cyk7CisgICAgcmV0dXJuOworICB9CisKKyAgbV9jaGFubmVsID0gY2hhbm5lbDsKKworICB2b2lkKiBwb3J0ID0gZ2V0UG9ydChjaGFubmVsKTsKKyAgaW50MzJfdCBzdGF0dXMgPSAwOworICBtX3BvcnQgPSBpbml0aWFsaXplQW5hbG9nSW5wdXRQb3J0KHBvcnQsICZzdGF0dXMpOworICB3cGlfc2V0RXJyb3JXaXRoQ29udGV4dChzdGF0dXMsIGdldEhBTEVycm9yTWVzc2FnZShzdGF0dXMpKTsKKyAgZnJlZVBvcnQocG9ydCk7CisKKyAgTGl2ZVdpbmRvdzo6R2V0SW5zdGFuY2UoKS0+QWRkU2Vuc29yKCJBbmFsb2dJbnB1dCIsIGNoYW5uZWwsIHRoaXMpOworICBIQUxSZXBvcnQoSEFMVXNhZ2VSZXBvcnRpbmc6OmtSZXNvdXJjZVR5cGVfQW5hbG9nQ2hhbm5lbCwgY2hhbm5lbCk7Cit9CisKKy8qKgorICogQ2hhbm5lbCBkZXN0cnVjdG9yLgorICovCitBbmFsb2dJbnB1dDo6fkFuYWxvZ0lucHV0KCkgeworICBmcmVlQW5hbG9nSW5wdXRQb3J0KG1fcG9ydCk7CisgIGlucHV0cy0+RnJlZShtX2NoYW5uZWwpOworfQorCisvKioKKyAqIEdldCBhIHNhbXBsZSBzdHJhaWdodCBmcm9tIHRoaXMgY2hhbm5lbC4KKyAqIFRoZSBzYW1wbGUgaXMgYSAxMi1iaXQgdmFsdWUgcmVwcmVzZW50aW5nIHRoZSAwViB0byA1ViByYW5nZSBvZiB0aGUgQS9ECisgKiBjb252ZXJ0ZXIgaW4gdGhlIG1vZHVsZS4KKyAqIFRoZSB1bml0cyBhcmUgaW4gQS9EIGNvbnZlcnRlciBjb2Rlcy4gIFVzZSBHZXRWb2x0YWdlKCkgdG8gZ2V0IHRoZSBhbmFsb2cKKyAqIHZhbHVlIGluIGNhbGlicmF0ZWQgdW5pdHMuCisgKiBAcmV0dXJuIEEgc2FtcGxlIHN0cmFpZ2h0IGZyb20gdGhpcyBjaGFubmVsLgorICovCitpbnQxNl90IEFuYWxvZ0lucHV0OjpHZXRWYWx1ZSgpIGNvbnN0IHsKKyAgaWYgKFN0YXR1c0lzRmF0YWwoKSkgcmV0dXJuIDA7CisgIGludDMyX3Qgc3RhdHVzID0gMDsKKyAgaW50MTZfdCB2YWx1ZSA9IGdldEFuYWxvZ1ZhbHVlKG1fcG9ydCwgJnN0YXR1cyk7CisgIHdwaV9zZXRFcnJvcldpdGhDb250ZXh0KHN0YXR1cywgZ2V0SEFMRXJyb3JNZXNzYWdlKHN0YXR1cykpOworICByZXR1cm4gdmFsdWU7Cit9CisKKy8qKgorICogR2V0IGEgc2FtcGxlIGZyb20gdGhlIG91dHB1dCBvZiB0aGUgb3ZlcnNhbXBsZSBhbmQgYXZlcmFnZSBlbmdpbmUgZm9yIHRoaXMKKyAqIGNoYW5uZWwuCisgKiBUaGUgc2FtcGxlIGlzIDEyLWJpdCArIHRoZSBiaXRzIGNvbmZpZ3VyZWQgaW4gU2V0T3ZlcnNhbXBsZUJpdHMoKS4KKyAqIFRoZSB2YWx1ZSBjb25maWd1cmVkIGluIFNldEF2ZXJhZ2VCaXRzKCkgd2lsbCBjYXVzZSB0aGlzIHZhbHVlIHRvIGJlIGF2ZXJhZ2VkCisgKiAyKipiaXRzIG51bWJlciBvZiBzYW1wbGVzLgorICogVGhpcyBpcyBub3QgYSBzbGlkaW5nIHdpbmRvdy4gIFRoZSBzYW1wbGUgd2lsbCBub3QgY2hhbmdlIHVudGlsCisgKiAyKiooT3ZlcnNhbXBsZUJpdHMgKyBBdmVyYWdlQml0cykgc2FtcGxlcworICogaGF2ZSBiZWVuIGFjcXVpcmVkIGZyb20gdGhlIG1vZHVsZSBvbiB0aGlzIGNoYW5uZWwuCisgKiBVc2UgR2V0QXZlcmFnZVZvbHRhZ2UoKSB0byBnZXQgdGhlIGFuYWxvZyB2YWx1ZSBpbiBjYWxpYnJhdGVkIHVuaXRzLgorICogQHJldHVybiBBIHNhbXBsZSBmcm9tIHRoZSBvdmVyc2FtcGxlIGFuZCBhdmVyYWdlIGVuZ2luZSBmb3IgdGhpcyBjaGFubmVsLgorICovCitpbnQzMl90IEFuYWxvZ0lucHV0OjpHZXRBdmVyYWdlVmFsdWUoKSBjb25zdCB7CisgIGlmIChTdGF0dXNJc0ZhdGFsKCkpIHJldHVybiAwOworICBpbnQzMl90IHN0YXR1cyA9IDA7CisgIGludDMyX3QgdmFsdWUgPSBnZXRBbmFsb2dBdmVyYWdlVmFsdWUobV9wb3J0LCAmc3RhdHVzKTsKKyAgd3BpX3NldEVycm9yV2l0aENvbnRleHQoc3RhdHVzLCBnZXRIQUxFcnJvck1lc3NhZ2Uoc3RhdHVzKSk7CisgIHJldHVybiB2YWx1ZTsKK30KKworLyoqCisgKiBHZXQgYSBzY2FsZWQgc2FtcGxlIHN0cmFpZ2h0IGZyb20gdGhpcyBjaGFubmVsLgorICogVGhlIHZhbHVlIGlzIHNjYWxlZCB0byB1bml0cyBvZiBWb2x0cyB1c2luZyB0aGUgY2FsaWJyYXRlZCBzY2FsaW5nIGRhdGEgZnJvbQorICogR2V0TFNCV2VpZ2h0KCkgYW5kIEdldE9mZnNldCgpLgorICogQHJldHVybiBBIHNjYWxlZCBzYW1wbGUgc3RyYWlnaHQgZnJvbSB0aGlzIGNoYW5uZWwuCisgKi8KK2Zsb2F0IEFuYWxvZ0lucHV0OjpHZXRWb2x0YWdlKCkgY29uc3QgeworICBpZiAoU3RhdHVzSXNGYXRhbCgpKSByZXR1cm4gMC4wZjsKKyAgaW50MzJfdCBzdGF0dXMgPSAwOworICBmbG9hdCB2b2x0YWdlID0gZ2V0QW5hbG9nVm9sdGFnZShtX3BvcnQsICZzdGF0dXMpOworICB3cGlfc2V0RXJyb3JXaXRoQ29udGV4dChzdGF0dXMsIGdldEhBTEVycm9yTWVzc2FnZShzdGF0dXMpKTsKKyAgcmV0dXJuIHZvbHRhZ2U7Cit9CisKKy8qKgorICogR2V0IGEgc2NhbGVkIHNhbXBsZSBmcm9tIHRoZSBvdXRwdXQgb2YgdGhlIG92ZXJzYW1wbGUgYW5kIGF2ZXJhZ2UgZW5naW5lIGZvcgorICogdGhpcyBjaGFubmVsLgorICogVGhlIHZhbHVlIGlzIHNjYWxlZCB0byB1bml0cyBvZiBWb2x0cyB1c2luZyB0aGUgY2FsaWJyYXRlZCBzY2FsaW5nIGRhdGEgZnJvbQorICogR2V0TFNCV2VpZ2h0KCkgYW5kIEdldE9mZnNldCgpLgorICogVXNpbmcgb3ZlcnNhbXBsaW5nIHdpbGwgY2F1c2UgdGhpcyB2YWx1ZSB0byBiZSBoaWdoZXIgcmVzb2x1dGlvbiwgYnV0IGl0IHdpbGwKKyAqIHVwZGF0ZSBtb3JlIHNsb3dseS4KKyAqIFVzaW5nIGF2ZXJhZ2luZyB3aWxsIGNhdXNlIHRoaXMgdmFsdWUgdG8gYmUgbW9yZSBzdGFibGUsIGJ1dCBpdCB3aWxsIHVwZGF0ZQorICogbW9yZSBzbG93bHkuCisgKiBAcmV0dXJuIEEgc2NhbGVkIHNhbXBsZSBmcm9tIHRoZSBvdXRwdXQgb2YgdGhlIG92ZXJzYW1wbGUgYW5kIGF2ZXJhZ2UgZW5naW5lCisgKiBmb3IgdGhpcyBjaGFubmVsLgorICovCitmbG9hdCBBbmFsb2dJbnB1dDo6R2V0QXZlcmFnZVZvbHRhZ2UoKSBjb25zdCB7CisgIGlmIChTdGF0dXNJc0ZhdGFsKCkpIHJldHVybiAwLjBmOworICBpbnQzMl90IHN0YXR1cyA9IDA7CisgIGZsb2F0IHZvbHRhZ2UgPSBnZXRBbmFsb2dBdmVyYWdlVm9sdGFnZShtX3BvcnQsICZzdGF0dXMpOworICB3cGlfc2V0RXJyb3JXaXRoQ29udGV4dChzdGF0dXMsIGdldEhBTEVycm9yTWVzc2FnZShzdGF0dXMpKTsKKyAgcmV0dXJuIHZvbHRhZ2U7Cit9CisKKy8qKgorICogR2V0IHRoZSBmYWN0b3J5IHNjYWxpbmcgbGVhc3Qgc2lnbmlmaWNhbnQgYml0IHdlaWdodCBjb25zdGFudC4KKyAqCisgKiBWb2x0cyA9ICgoTFNCX1dlaWdodCAqIDFlLTkpICogcmF3KSAtIChPZmZzZXQgKiAxZS05KQorICoKKyAqIEByZXR1cm4gTGVhc3Qgc2lnbmlmaWNhbnQgYml0IHdlaWdodC4KKyAqLwordWludDMyX3QgQW5hbG9nSW5wdXQ6OkdldExTQldlaWdodCgpIGNvbnN0IHsKKyAgaWYgKFN0YXR1c0lzRmF0YWwoKSkgcmV0dXJuIDA7CisgIGludDMyX3Qgc3RhdHVzID0gMDsKKyAgaW50MzJfdCBsc2JXZWlnaHQgPSBnZXRBbmFsb2dMU0JXZWlnaHQobV9wb3J0LCAmc3RhdHVzKTsKKyAgd3BpX3NldEVycm9yV2l0aENvbnRleHQoc3RhdHVzLCBnZXRIQUxFcnJvck1lc3NhZ2Uoc3RhdHVzKSk7CisgIHJldHVybiBsc2JXZWlnaHQ7Cit9CisKKy8qKgorICogR2V0IHRoZSBmYWN0b3J5IHNjYWxpbmcgb2Zmc2V0IGNvbnN0YW50LgorICoKKyAqIFZvbHRzID0gKChMU0JfV2VpZ2h0ICogMWUtOSkgKiByYXcpIC0gKE9mZnNldCAqIDFlLTkpCisgKgorICogQHJldHVybiBPZmZzZXQgY29uc3RhbnQuCisgKi8KK2ludDMyX3QgQW5hbG9nSW5wdXQ6OkdldE9mZnNldCgpIGNvbnN0IHsKKyAgaWYgKFN0YXR1c0lzRmF0YWwoKSkgcmV0dXJuIDA7CisgIGludDMyX3Qgc3RhdHVzID0gMDsKKyAgaW50MzJfdCBvZmZzZXQgPSBnZXRBbmFsb2dPZmZzZXQobV9wb3J0LCAmc3RhdHVzKTsKKyAgd3BpX3NldEVycm9yV2l0aENvbnRleHQoc3RhdHVzLCBnZXRIQUxFcnJvck1lc3NhZ2Uoc3RhdHVzKSk7CisgIHJldHVybiBvZmZzZXQ7Cit9CisKKy8qKgorICogR2V0IHRoZSBjaGFubmVsIG51bWJlci4KKyAqIEByZXR1cm4gVGhlIGNoYW5uZWwgbnVtYmVyLgorICovCit1aW50MzJfdCBBbmFsb2dJbnB1dDo6R2V0Q2hhbm5lbCgpIGNvbnN0IHsKKyAgaWYgKFN0YXR1c0lzRmF0YWwoKSkgcmV0dXJuIDA7CisgIHJldHVybiBtX2NoYW5uZWw7Cit9CisKKy8qKgorICogU2V0IHRoZSBudW1iZXIgb2YgYXZlcmFnaW5nIGJpdHMuCisgKiBUaGlzIHNldHMgdGhlIG51bWJlciBvZiBhdmVyYWdpbmcgYml0cy4gVGhlIGFjdHVhbCBudW1iZXIgb2YgYXZlcmFnZWQgc2FtcGxlcworICogaXMgMl5iaXRzLgorICogVXNlIGF2ZXJhZ2luZyB0byBpbXByb3ZlIHRoZSBzdGFiaWxpdHkgb2YgeW91ciBtZWFzdXJlbWVudCBhdCB0aGUgZXhwZW5zZSBvZgorICogc2FtcGxpbmcgcmF0ZS4KKyAqIFRoZSBhdmVyYWdpbmcgaXMgZG9uZSBhdXRvbWF0aWNhbGx5IGluIHRoZSBGUEdBLgorICoKKyAqIEBwYXJhbSBiaXRzIE51bWJlciBvZiBiaXRzIG9mIGF2ZXJhZ2luZy4KKyAqLwordm9pZCBBbmFsb2dJbnB1dDo6U2V0QXZlcmFnZUJpdHModWludDMyX3QgYml0cykgeworICBpZiAoU3RhdHVzSXNGYXRhbCgpKSByZXR1cm47CisgIGludDMyX3Qgc3RhdHVzID0gMDsKKyAgc2V0QW5hbG9nQXZlcmFnZUJpdHMobV9wb3J0LCBiaXRzLCAmc3RhdHVzKTsKKyAgd3BpX3NldEVycm9yV2l0aENvbnRleHQoc3RhdHVzLCBnZXRIQUxFcnJvck1lc3NhZ2Uoc3RhdHVzKSk7Cit9CisKKy8qKgorICogR2V0IHRoZSBudW1iZXIgb2YgYXZlcmFnaW5nIGJpdHMgcHJldmlvdXNseSBjb25maWd1cmVkLgorICogVGhpcyBnZXRzIHRoZSBudW1iZXIgb2YgYXZlcmFnaW5nIGJpdHMgZnJvbSB0aGUgRlBHQS4gVGhlIGFjdHVhbCBudW1iZXIgb2YKKyAqIGF2ZXJhZ2VkIHNhbXBsZXMgaXMgMl5iaXRzLgorICogVGhlIGF2ZXJhZ2luZyBpcyBkb25lIGF1dG9tYXRpY2FsbHkgaW4gdGhlIEZQR0EuCisgKgorICogQHJldHVybiBOdW1iZXIgb2YgYml0cyBvZiBhdmVyYWdpbmcgcHJldmlvdXNseSBjb25maWd1cmVkLgorICovCit1aW50MzJfdCBBbmFsb2dJbnB1dDo6R2V0QXZlcmFnZUJpdHMoKSBjb25zdCB7CisgIGludDMyX3Qgc3RhdHVzID0gMDsKKyAgaW50MzJfdCBhdmVyYWdlQml0cyA9IGdldEFuYWxvZ0F2ZXJhZ2VCaXRzKG1fcG9ydCwgJnN0YXR1cyk7CisgIHdwaV9zZXRFcnJvcldpdGhDb250ZXh0KHN0YXR1cywgZ2V0SEFMRXJyb3JNZXNzYWdlKHN0YXR1cykpOworICByZXR1cm4gYXZlcmFnZUJpdHM7Cit9CisKKy8qKgorICogU2V0IHRoZSBudW1iZXIgb2Ygb3ZlcnNhbXBsZSBiaXRzLgorICogVGhpcyBzZXRzIHRoZSBudW1iZXIgb2Ygb3ZlcnNhbXBsZSBiaXRzLiBUaGUgYWN0dWFsIG51bWJlciBvZiBvdmVyc2FtcGxlZAorICogdmFsdWVzIGlzIDJeYml0cy4KKyAqIFVzZSBvdmVyc2FtcGxpbmcgdG8gaW1wcm92ZSB0aGUgcmVzb2x1dGlvbiBvZiB5b3VyIG1lYXN1cmVtZW50cyBhdCB0aGUKKyAqIGV4cGVuc2Ugb2Ygc2FtcGxpbmcgcmF0ZS4KKyAqIFRoZSBvdmVyc2FtcGxpbmcgaXMgZG9uZSBhdXRvbWF0aWNhbGx5IGluIHRoZSBGUEdBLgorICoKKyAqIEBwYXJhbSBiaXRzIE51bWJlciBvZiBiaXRzIG9mIG92ZXJzYW1wbGluZy4KKyAqLwordm9pZCBBbmFsb2dJbnB1dDo6U2V0T3ZlcnNhbXBsZUJpdHModWludDMyX3QgYml0cykgeworICBpZiAoU3RhdHVzSXNGYXRhbCgpKSByZXR1cm47CisgIGludDMyX3Qgc3RhdHVzID0gMDsKKyAgc2V0QW5hbG9nT3ZlcnNhbXBsZUJpdHMobV9wb3J0LCBiaXRzLCAmc3RhdHVzKTsKKyAgd3BpX3NldEVycm9yV2l0aENvbnRleHQoc3RhdHVzLCBnZXRIQUxFcnJvck1lc3NhZ2Uoc3RhdHVzKSk7Cit9CisKKy8qKgorICogR2V0IHRoZSBudW1iZXIgb2Ygb3ZlcnNhbXBsZSBiaXRzIHByZXZpb3VzbHkgY29uZmlndXJlZC4KKyAqIFRoaXMgZ2V0cyB0aGUgbnVtYmVyIG9mIG92ZXJzYW1wbGUgYml0cyBmcm9tIHRoZSBGUEdBLiBUaGUgYWN0dWFsIG51bWJlciBvZgorICogb3ZlcnNhbXBsZWQgdmFsdWVzIGlzCisgKiAyXmJpdHMuIFRoZSBvdmVyc2FtcGxpbmcgaXMgZG9uZSBhdXRvbWF0aWNhbGx5IGluIHRoZSBGUEdBLgorICoKKyAqIEByZXR1cm4gTnVtYmVyIG9mIGJpdHMgb2Ygb3ZlcnNhbXBsaW5nIHByZXZpb3VzbHkgY29uZmlndXJlZC4KKyAqLwordWludDMyX3QgQW5hbG9nSW5wdXQ6OkdldE92ZXJzYW1wbGVCaXRzKCkgY29uc3QgeworICBpZiAoU3RhdHVzSXNGYXRhbCgpKSByZXR1cm4gMDsKKyAgaW50MzJfdCBzdGF0dXMgPSAwOworICBpbnQzMl90IG92ZXJzYW1wbGVCaXRzID0gZ2V0QW5hbG9nT3ZlcnNhbXBsZUJpdHMobV9wb3J0LCAmc3RhdHVzKTsKKyAgd3BpX3NldEVycm9yV2l0aENvbnRleHQoc3RhdHVzLCBnZXRIQUxFcnJvck1lc3NhZ2Uoc3RhdHVzKSk7CisgIHJldHVybiBvdmVyc2FtcGxlQml0czsKK30KKworLyoqCisgKiBJcyB0aGUgY2hhbm5lbCBhdHRhY2hlZCB0byBhbiBhY2N1bXVsYXRvci4KKyAqCisgKiBAcmV0dXJuIFRoZSBhbmFsb2cgaW5wdXQgaXMgYXR0YWNoZWQgdG8gYW4gYWNjdW11bGF0b3IuCisgKi8KK2Jvb2wgQW5hbG9nSW5wdXQ6OklzQWNjdW11bGF0b3JDaGFubmVsKCkgY29uc3QgeworICBpZiAoU3RhdHVzSXNGYXRhbCgpKSByZXR1cm4gZmFsc2U7CisgIGludDMyX3Qgc3RhdHVzID0gMDsKKyAgYm9vbCBpc0FjY3VtID0gaXNBY2N1bXVsYXRvckNoYW5uZWwobV9wb3J0LCAmc3RhdHVzKTsKKyAgd3BpX3NldEVycm9yV2l0aENvbnRleHQoc3RhdHVzLCBnZXRIQUxFcnJvck1lc3NhZ2Uoc3RhdHVzKSk7CisgIHJldHVybiBpc0FjY3VtOworfQorCisvKioKKyAqIEluaXRpYWxpemUgdGhlIGFjY3VtdWxhdG9yLgorICovCit2b2lkIEFuYWxvZ0lucHV0OjpJbml0QWNjdW11bGF0b3IoKSB7CisgIGlmIChTdGF0dXNJc0ZhdGFsKCkpIHJldHVybjsKKyAgbV9hY2N1bXVsYXRvck9mZnNldCA9IDA7CisgIGludDMyX3Qgc3RhdHVzID0gMDsKKyAgaW5pdEFjY3VtdWxhdG9yKG1fcG9ydCwgJnN0YXR1cyk7CisgIHdwaV9zZXRFcnJvcldpdGhDb250ZXh0KHN0YXR1cywgZ2V0SEFMRXJyb3JNZXNzYWdlKHN0YXR1cykpOworfQorCisvKioKKyAqIFNldCBhbiBpbml0aWFsIHZhbHVlIGZvciB0aGUgYWNjdW11bGF0b3IuCisgKgorICogVGhpcyB3aWxsIGJlIGFkZGVkIHRvIGFsbCB2YWx1ZXMgcmV0dXJuZWQgdG8gdGhlIHVzZXIuCisgKiBAcGFyYW0gaW5pdGlhbFZhbHVlIFRoZSB2YWx1ZSB0aGF0IHRoZSBhY2N1bXVsYXRvciBzaG91bGQgc3RhcnQgZnJvbSB3aGVuCisgKiByZXNldC4KKyAqLwordm9pZCBBbmFsb2dJbnB1dDo6U2V0QWNjdW11bGF0b3JJbml0aWFsVmFsdWUoaW50NjRfdCBpbml0aWFsVmFsdWUpIHsKKyAgaWYgKFN0YXR1c0lzRmF0YWwoKSkgcmV0dXJuOworICBtX2FjY3VtdWxhdG9yT2Zmc2V0ID0gaW5pdGlhbFZhbHVlOworfQorCisvKioKKyAqIFJlc2V0cyB0aGUgYWNjdW11bGF0b3IgdG8gdGhlIGluaXRpYWwgdmFsdWUuCisgKi8KK3ZvaWQgQW5hbG9nSW5wdXQ6OlJlc2V0QWNjdW11bGF0b3IoKSB7CisgIGlmIChTdGF0dXNJc0ZhdGFsKCkpIHJldHVybjsKKyAgaW50MzJfdCBzdGF0dXMgPSAwOworICByZXNldEFjY3VtdWxhdG9yKG1fcG9ydCwgJnN0YXR1cyk7CisgIHdwaV9zZXRFcnJvcldpdGhDb250ZXh0KHN0YXR1cywgZ2V0SEFMRXJyb3JNZXNzYWdlKHN0YXR1cykpOworCisgIGlmICghU3RhdHVzSXNGYXRhbCgpKSB7CisgICAgLy8gV2FpdCB1bnRpbCB0aGUgbmV4dCBzYW1wbGUsIHNvIHRoZSBuZXh0IGNhbGwgdG8gR2V0QWNjdW11bGF0b3IqKCkKKyAgICAvLyB3b24ndCBoYXZlIG9sZCB2YWx1ZXMuCisgICAgY29uc3QgZmxvYXQgc2FtcGxlVGltZSA9IDEuMGYgLyBHZXRTYW1wbGVSYXRlKCk7CisgICAgY29uc3QgZmxvYXQgb3ZlclNhbXBsZXMgPSAxIDw8IEdldE92ZXJzYW1wbGVCaXRzKCk7CisgICAgY29uc3QgZmxvYXQgYXZlcmFnZVNhbXBsZXMgPSAxIDw8IEdldEF2ZXJhZ2VCaXRzKCk7CisgICAgV2FpdChzYW1wbGVUaW1lICogb3ZlclNhbXBsZXMgKiBhdmVyYWdlU2FtcGxlcyk7CisgIH0KK30KKworLyoqCisgKiBTZXQgdGhlIGNlbnRlciB2YWx1ZSBvZiB0aGUgYWNjdW11bGF0b3IuCisgKgorICogVGhlIGNlbnRlciB2YWx1ZSBpcyBzdWJ0cmFjdGVkIGZyb20gZWFjaCBBL0QgdmFsdWUgYmVmb3JlIGl0IGlzIGFkZGVkIHRvIHRoZQorICogYWNjdW11bGF0b3IuIFRoaXMKKyAqIGlzIHVzZWQgZm9yIHRoZSBjZW50ZXIgdmFsdWUgb2YgZGV2aWNlcyBsaWtlIGd5cm9zIGFuZCBhY2NlbGVyb21ldGVycyB0bworICogdGFrZSB0aGUgZGV2aWNlIG9mZnNldCBpbnRvIGFjY291bnQgd2hlbiBpbnRlZ3JhdGluZy4KKyAqCisgKiBUaGlzIGNlbnRlciB2YWx1ZSBpcyBiYXNlZCBvbiB0aGUgb3V0cHV0IG9mIHRoZSBvdmVyc2FtcGxlZCBhbmQgYXZlcmFnZWQKKyAqIHNvdXJjZSBmcm9tIHRoZSBhY2N1bXVsYXRvcgorICogY2hhbm5lbC4gQmVjYXVzZSBvZiB0aGlzLCBhbnkgbm9uLXplcm8gb3ZlcnNhbXBsZSBiaXRzIHdpbGwgYWZmZWN0IHRoZSBzaXplCisgKiBvZiB0aGUgdmFsdWUgZm9yIHRoaXMgZmllbGQuCisgKi8KK3ZvaWQgQW5hbG9nSW5wdXQ6OlNldEFjY3VtdWxhdG9yQ2VudGVyKGludDMyX3QgY2VudGVyKSB7CisgIGlmIChTdGF0dXNJc0ZhdGFsKCkpIHJldHVybjsKKyAgaW50MzJfdCBzdGF0dXMgPSAwOworICBzZXRBY2N1bXVsYXRvckNlbnRlcihtX3BvcnQsIGNlbnRlciwgJnN0YXR1cyk7CisgIHdwaV9zZXRFcnJvcldpdGhDb250ZXh0KHN0YXR1cywgZ2V0SEFMRXJyb3JNZXNzYWdlKHN0YXR1cykpOworfQorCisvKioKKyAqIFNldCB0aGUgYWNjdW11bGF0b3IncyBkZWFkYmFuZC4KKyAqIEBwYXJhbQorICovCit2b2lkIEFuYWxvZ0lucHV0OjpTZXRBY2N1bXVsYXRvckRlYWRiYW5kKGludDMyX3QgZGVhZGJhbmQpIHsKKyAgaWYgKFN0YXR1c0lzRmF0YWwoKSkgcmV0dXJuOworICBpbnQzMl90IHN0YXR1cyA9IDA7CisgIHNldEFjY3VtdWxhdG9yRGVhZGJhbmQobV9wb3J0LCBkZWFkYmFuZCwgJnN0YXR1cyk7CisgIHdwaV9zZXRFcnJvcldpdGhDb250ZXh0KHN0YXR1cywgZ2V0SEFMRXJyb3JNZXNzYWdlKHN0YXR1cykpOworfQorCisvKioKKyAqIFJlYWQgdGhlIGFjY3VtdWxhdGVkIHZhbHVlLgorICoKKyAqIFJlYWQgdGhlIHZhbHVlIHRoYXQgaGFzIGJlZW4gYWNjdW11bGF0aW5nLgorICogVGhlIGFjY3VtdWxhdG9yIGlzIGF0dGFjaGVkIGFmdGVyIHRoZSBvdmVyc2FtcGxlIGFuZCBhdmVyYWdlIGVuZ2luZS4KKyAqCisgKiBAcmV0dXJuIFRoZSA2NC1iaXQgdmFsdWUgYWNjdW11bGF0ZWQgc2luY2UgdGhlIGxhc3QgUmVzZXQoKS4KKyAqLworaW50NjRfdCBBbmFsb2dJbnB1dDo6R2V0QWNjdW11bGF0b3JWYWx1ZSgpIGNvbnN0IHsKKyAgaWYgKFN0YXR1c0lzRmF0YWwoKSkgcmV0dXJuIDA7CisgIGludDMyX3Qgc3RhdHVzID0gMDsKKyAgaW50NjRfdCB2YWx1ZSA9IGdldEFjY3VtdWxhdG9yVmFsdWUobV9wb3J0LCAmc3RhdHVzKTsKKyAgd3BpX3NldEVycm9yV2l0aENvbnRleHQoc3RhdHVzLCBnZXRIQUxFcnJvck1lc3NhZ2Uoc3RhdHVzKSk7CisgIHJldHVybiB2YWx1ZSArIG1fYWNjdW11bGF0b3JPZmZzZXQ7Cit9CisKKy8qKgorICogUmVhZCB0aGUgbnVtYmVyIG9mIGFjY3VtdWxhdGVkIHZhbHVlcy4KKyAqCisgKiBSZWFkIHRoZSBjb3VudCBvZiB0aGUgYWNjdW11bGF0ZWQgdmFsdWVzIHNpbmNlIHRoZSBhY2N1bXVsYXRvciB3YXMgbGFzdAorICogUmVzZXQoKS4KKyAqCisgKiBAcmV0dXJuIFRoZSBudW1iZXIgb2YgdGltZXMgc2FtcGxlcyBmcm9tIHRoZSBjaGFubmVsIHdlcmUgYWNjdW11bGF0ZWQuCisgKi8KK3VpbnQzMl90IEFuYWxvZ0lucHV0OjpHZXRBY2N1bXVsYXRvckNvdW50KCkgY29uc3QgeworICBpZiAoU3RhdHVzSXNGYXRhbCgpKSByZXR1cm4gMDsKKyAgaW50MzJfdCBzdGF0dXMgPSAwOworICB1aW50MzJfdCBjb3VudCA9IGdldEFjY3VtdWxhdG9yQ291bnQobV9wb3J0LCAmc3RhdHVzKTsKKyAgd3BpX3NldEVycm9yV2l0aENvbnRleHQoc3RhdHVzLCBnZXRIQUxFcnJvck1lc3NhZ2Uoc3RhdHVzKSk7CisgIHJldHVybiBjb3VudDsKK30KKworLyoqCisgKiBSZWFkIHRoZSBhY2N1bXVsYXRlZCB2YWx1ZSBhbmQgdGhlIG51bWJlciBvZiBhY2N1bXVsYXRlZCB2YWx1ZXMgYXRvbWljYWxseS4KKyAqCisgKiBUaGlzIGZ1bmN0aW9uIHJlYWRzIHRoZSB2YWx1ZSBhbmQgY291bnQgZnJvbSB0aGUgRlBHQSBhdG9taWNhbGx5LgorICogVGhpcyBjYW4gYmUgdXNlZCBmb3IgYXZlcmFnaW5nLgorICoKKyAqIEBwYXJhbSB2YWx1ZSBSZWZlcmVuY2UgdG8gdGhlIDY0LWJpdCBhY2N1bXVsYXRlZCBvdXRwdXQuCisgKiBAcGFyYW0gY291bnQgUmVmZXJlbmNlIHRvIHRoZSBudW1iZXIgb2YgYWNjdW11bGF0aW9uIGN5Y2xlcy4KKyAqLwordm9pZCBBbmFsb2dJbnB1dDo6R2V0QWNjdW11bGF0b3JPdXRwdXQoaW50NjRfdCAmdmFsdWUsIHVpbnQzMl90ICZjb3VudCkgY29uc3QgeworICBpZiAoU3RhdHVzSXNGYXRhbCgpKSByZXR1cm47CisgIGludDMyX3Qgc3RhdHVzID0gMDsKKyAgZ2V0QWNjdW11bGF0b3JPdXRwdXQobV9wb3J0LCAmdmFsdWUsICZjb3VudCwgJnN0YXR1cyk7CisgIHdwaV9zZXRFcnJvcldpdGhDb250ZXh0KHN0YXR1cywgZ2V0SEFMRXJyb3JNZXNzYWdlKHN0YXR1cykpOworICB2YWx1ZSArPSBtX2FjY3VtdWxhdG9yT2Zmc2V0OworfQorCisvKioKKyAqIFNldCB0aGUgc2FtcGxlIHJhdGUgcGVyIGNoYW5uZWwgZm9yIGFsbCBhbmFsb2cgY2hhbm5lbHMuCisgKiBUaGUgbWF4aW11bSByYXRlIGlzIDUwMGtTL3MgZGl2aWRlZCBieSB0aGUgbnVtYmVyIG9mIGNoYW5uZWxzIGluIHVzZS4KKyAqIFRoaXMgaXMgNjI1MDAgc2FtcGxlcy9zIHBlciBjaGFubmVsLgorICogQHBhcmFtIHNhbXBsZXNQZXJTZWNvbmQgVGhlIG51bWJlciBvZiBzYW1wbGVzIHBlciBzZWNvbmQuCisgKi8KK3ZvaWQgQW5hbG9nSW5wdXQ6OlNldFNhbXBsZVJhdGUoZmxvYXQgc2FtcGxlc1BlclNlY29uZCkgeworICBpbnQzMl90IHN0YXR1cyA9IDA7CisgIHNldEFuYWxvZ1NhbXBsZVJhdGUoc2FtcGxlc1BlclNlY29uZCwgJnN0YXR1cyk7CisgIHdwaV9zZXRHbG9iYWxFcnJvcldpdGhDb250ZXh0KHN0YXR1cywgZ2V0SEFMRXJyb3JNZXNzYWdlKHN0YXR1cykpOworfQorCisvKioKKyAqIEdldCB0aGUgY3VycmVudCBzYW1wbGUgcmF0ZSBmb3IgYWxsIGNoYW5uZWxzCisgKgorICogQHJldHVybiBTYW1wbGUgcmF0ZS4KKyAqLworZmxvYXQgQW5hbG9nSW5wdXQ6OkdldFNhbXBsZVJhdGUoKSB7CisgIGludDMyX3Qgc3RhdHVzID0gMDsKKyAgZmxvYXQgc2FtcGxlUmF0ZSA9IGdldEFuYWxvZ1NhbXBsZVJhdGUoJnN0YXR1cyk7CisgIHdwaV9zZXRHbG9iYWxFcnJvcldpdGhDb250ZXh0KHN0YXR1cywgZ2V0SEFMRXJyb3JNZXNzYWdlKHN0YXR1cykpOworICByZXR1cm4gc2FtcGxlUmF0ZTsKK30KKworLyoqCisgKiBHZXQgdGhlIEF2ZXJhZ2UgdmFsdWUgZm9yIHRoZSBQSUQgU291cmNlIGJhc2Ugb2JqZWN0LgorICoKKyAqIEByZXR1cm4gVGhlIGF2ZXJhZ2Ugdm9sdGFnZS4KKyAqLworZG91YmxlIEFuYWxvZ0lucHV0OjpQSURHZXQoKSB7CisgIGlmIChTdGF0dXNJc0ZhdGFsKCkpIHJldHVybiAwLjA7CisgIHJldHVybiBHZXRBdmVyYWdlVm9sdGFnZSgpOworfQorCit2b2lkIEFuYWxvZ0lucHV0OjpVcGRhdGVUYWJsZSgpIHsKKyAgaWYgKG1fdGFibGUgIT0gbnVsbHB0cikgeworICAgIG1fdGFibGUtPlB1dE51bWJlcigiVmFsdWUiLCBHZXRBdmVyYWdlVm9sdGFnZSgpKTsKKyAgfQorfQorCit2b2lkIEFuYWxvZ0lucHV0OjpTdGFydExpdmVXaW5kb3dNb2RlKCkge30KKwordm9pZCBBbmFsb2dJbnB1dDo6U3RvcExpdmVXaW5kb3dNb2RlKCkge30KKworc3RkOjpzdHJpbmcgQW5hbG9nSW5wdXQ6OkdldFNtYXJ0RGFzaGJvYXJkVHlwZSgpIGNvbnN0IHsKKyAgcmV0dXJuICJBbmFsb2cgSW5wdXQiOworfQorCit2b2lkIEFuYWxvZ0lucHV0OjpJbml0VGFibGUoc3RkOjpzaGFyZWRfcHRyPElUYWJsZT4gc3ViVGFibGUpIHsKKyAgbV90YWJsZSA9IHN1YlRhYmxlOworICBVcGRhdGVUYWJsZSgpOworfQorCitzdGQ6OnNoYXJlZF9wdHI8SVRhYmxlPiBBbmFsb2dJbnB1dDo6R2V0VGFibGUoKSBjb25zdCB7IHJldHVybiBtX3RhYmxlOyB9CmRpZmYgLS1naXQgYS93cGlsaWJjL0F0aGVuYS9zcmMvQW5hbG9nT3V0cHV0LmNwcCBiL3dwaWxpYmMvQXRoZW5hL3NyYy9BbmFsb2dPdXRwdXQuY3BwCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjc0YTFmOWMKLS0tIC9kZXYvbnVsbAorKysgYi93cGlsaWJjL0F0aGVuYS9zcmMvQW5hbG9nT3V0cHV0LmNwcApAQCAtMCwwICsxLDExMCBAQAorLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi8KKy8qIENvcHlyaWdodCAoYykgRklSU1QgMjAxNC4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICovCisvKiBPcGVuIFNvdXJjZSBTb2Z0d2FyZSAtIG1heSBiZSBtb2RpZmllZCBhbmQgc2hhcmVkIGJ5IEZSQyB0ZWFtcy4gVGhlIGNvZGUgICAqLworLyogbXVzdCBiZSBhY2NvbXBhbmllZCBieSB0aGUgRklSU1QgQlNEIGxpY2Vuc2UgZmlsZSBpbiB0aGUgcm9vdCBkaXJlY3Rvcnkgb2YgKi8KKy8qIHRoZSBwcm9qZWN0LiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICovCisvKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qLworCisjaW5jbHVkZSAiQW5hbG9nT3V0cHV0LmgiCisjaW5jbHVkZSAiUmVzb3VyY2UuaCIKKyNpbmNsdWRlICJXUElFcnJvcnMuaCIKKyNpbmNsdWRlICJMaXZlV2luZG93L0xpdmVXaW5kb3cuaCIKKyNpbmNsdWRlICJIQUwvUG9ydC5oIgorCisjaW5jbHVkZSA8bGltaXRzPgorI2luY2x1ZGUgPHNzdHJlYW0+CisKK3N0YXRpYyBzdGQ6OnVuaXF1ZV9wdHI8UmVzb3VyY2U+IG91dHB1dHM7CisKKy8qKgorICogQ29uc3RydWN0IGFuIGFuYWxvZyBvdXRwdXQgb24gdGhlIGdpdmVuIGNoYW5uZWwuCisgKiBBbGwgYW5hbG9nIG91dHB1dHMgYXJlIGxvY2F0ZWQgb24gdGhlIE1YUCBwb3J0LgorICogQHBhcmFtIFRoZSBjaGFubmVsIG51bWJlciBvbiB0aGUgcm9ib1JJTyB0byByZXByZXNlbnQuCisgKi8KK0FuYWxvZ091dHB1dDo6QW5hbG9nT3V0cHV0KHVpbnQzMl90IGNoYW5uZWwpIHsKKyAgUmVzb3VyY2U6OkNyZWF0ZVJlc291cmNlT2JqZWN0KG91dHB1dHMsIGtBbmFsb2dPdXRwdXRzKTsKKworICBzdGQ6OnN0cmluZ3N0cmVhbSBidWY7CisgIGJ1ZiA8PCAiYW5hbG9nIGlucHV0ICIgPDwgY2hhbm5lbDsKKworICBpZiAoIWNoZWNrQW5hbG9nT3V0cHV0Q2hhbm5lbChjaGFubmVsKSkgeworICAgIHdwaV9zZXRXUElFcnJvcldpdGhDb250ZXh0KENoYW5uZWxJbmRleE91dE9mUmFuZ2UsIGJ1Zi5zdHIoKSk7CisgICAgbV9jaGFubmVsID0gc3RkOjpudW1lcmljX2xpbWl0czx1aW50MzJfdD46Om1heCgpOworICAgIG1fcG9ydCA9IG51bGxwdHI7CisgICAgcmV0dXJuOworICB9CisKKyAgaWYgKG91dHB1dHMtPkFsbG9jYXRlKGNoYW5uZWwsIGJ1Zi5zdHIoKSkgPT0KKyAgICAgIHN0ZDo6bnVtZXJpY19saW1pdHM8dWludDMyX3Q+OjptYXgoKSkgeworICAgIENsb25lRXJyb3IoKm91dHB1dHMpOworICAgIG1fY2hhbm5lbCA9IHN0ZDo6bnVtZXJpY19saW1pdHM8dWludDMyX3Q+OjptYXgoKTsKKyAgICBtX3BvcnQgPSBudWxscHRyOworICAgIHJldHVybjsKKyAgfQorCisgIG1fY2hhbm5lbCA9IGNoYW5uZWw7CisKKyAgdm9pZCogcG9ydCA9IGdldFBvcnQobV9jaGFubmVsKTsKKyAgaW50MzJfdCBzdGF0dXMgPSAwOworICBtX3BvcnQgPSBpbml0aWFsaXplQW5hbG9nT3V0cHV0UG9ydChwb3J0LCAmc3RhdHVzKTsKKyAgd3BpX3NldEVycm9yV2l0aENvbnRleHQoc3RhdHVzLCBnZXRIQUxFcnJvck1lc3NhZ2Uoc3RhdHVzKSk7CisgIGZyZWVQb3J0KHBvcnQpOworCisgIExpdmVXaW5kb3c6OkdldEluc3RhbmNlKCktPkFkZEFjdHVhdG9yKCJBbmFsb2dPdXRwdXQiLCBtX2NoYW5uZWwsIHRoaXMpOworICBIQUxSZXBvcnQoSEFMVXNhZ2VSZXBvcnRpbmc6OmtSZXNvdXJjZVR5cGVfQW5hbG9nT3V0cHV0LCBtX2NoYW5uZWwpOworfQorCisvKioKKyAqIERlc3RydWN0b3IuIEZyZWVzIGFuYWxvZyBvdXRwdXQgcmVzb3VyY2UKKyAqLworQW5hbG9nT3V0cHV0Ojp+QW5hbG9nT3V0cHV0KCkgeworICBmcmVlQW5hbG9nT3V0cHV0UG9ydChtX3BvcnQpOworICBvdXRwdXRzLT5GcmVlKG1fY2hhbm5lbCk7Cit9CisKKy8qKgorICogU2V0IHRoZSB2YWx1ZSBvZiB0aGUgYW5hbG9nIG91dHB1dAorICoKKyAqIEBwYXJhbSB2b2x0YWdlIFRoZSBvdXRwdXQgdmFsdWUgaW4gVm9sdHMsIGZyb20gMC4wIHRvICs1LjAKKyAqLwordm9pZCBBbmFsb2dPdXRwdXQ6OlNldFZvbHRhZ2UoZmxvYXQgdm9sdGFnZSkgeworICBpbnQzMl90IHN0YXR1cyA9IDA7CisgIHNldEFuYWxvZ091dHB1dChtX3BvcnQsIHZvbHRhZ2UsICZzdGF0dXMpOworCisgIHdwaV9zZXRFcnJvcldpdGhDb250ZXh0KHN0YXR1cywgZ2V0SEFMRXJyb3JNZXNzYWdlKHN0YXR1cykpOworfQorCisvKioKKyAqIEdldCB0aGUgdm9sdGFnZSBvZiB0aGUgYW5hbG9nIG91dHB1dAorICoKKyAqIEByZXR1cm4gVGhlIHZhbHVlIGluIFZvbHRzLCBmcm9tIDAuMCB0byArNS4wCisgKi8KK2Zsb2F0IEFuYWxvZ091dHB1dDo6R2V0Vm9sdGFnZSgpIGNvbnN0IHsKKyAgaW50MzJfdCBzdGF0dXMgPSAwOworICBmbG9hdCB2b2x0YWdlID0gZ2V0QW5hbG9nT3V0cHV0KG1fcG9ydCwgJnN0YXR1cyk7CisKKyAgd3BpX3NldEVycm9yV2l0aENvbnRleHQoc3RhdHVzLCBnZXRIQUxFcnJvck1lc3NhZ2Uoc3RhdHVzKSk7CisKKyAgcmV0dXJuIHZvbHRhZ2U7Cit9CisKK3ZvaWQgQW5hbG9nT3V0cHV0OjpVcGRhdGVUYWJsZSgpIHsKKyAgaWYgKG1fdGFibGUgIT0gbnVsbHB0cikgeworICAgIG1fdGFibGUtPlB1dE51bWJlcigiVmFsdWUiLCBHZXRWb2x0YWdlKCkpOworICB9Cit9CisKK3ZvaWQgQW5hbG9nT3V0cHV0OjpTdGFydExpdmVXaW5kb3dNb2RlKCkge30KKwordm9pZCBBbmFsb2dPdXRwdXQ6OlN0b3BMaXZlV2luZG93TW9kZSgpIHt9CisKK3N0ZDo6c3RyaW5nIEFuYWxvZ091dHB1dDo6R2V0U21hcnREYXNoYm9hcmRUeXBlKCkgY29uc3QgeworICByZXR1cm4gIkFuYWxvZyBPdXRwdXQiOworfQorCit2b2lkIEFuYWxvZ091dHB1dDo6SW5pdFRhYmxlKHN0ZDo6c2hhcmVkX3B0cjxJVGFibGU+IHN1YlRhYmxlKSB7CisgIG1fdGFibGUgPSBzdWJUYWJsZTsKKyAgVXBkYXRlVGFibGUoKTsKK30KKworc3RkOjpzaGFyZWRfcHRyPElUYWJsZT4gQW5hbG9nT3V0cHV0OjpHZXRUYWJsZSgpIGNvbnN0IHsgcmV0dXJuIG1fdGFibGU7IH0KZGlmZiAtLWdpdCBhL3dwaWxpYmMvQXRoZW5hL3NyYy9BbmFsb2dQb3RlbnRpb21ldGVyLmNwcCBiL3dwaWxpYmMvQXRoZW5hL3NyYy9BbmFsb2dQb3RlbnRpb21ldGVyLmNwcApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4xMzcyZDg0Ci0tLSAvZGV2L251bGwKKysrIGIvd3BpbGliYy9BdGhlbmEvc3JjL0FuYWxvZ1BvdGVudGlvbWV0ZXIuY3BwCkBAIC0wLDAgKzEsODcgQEAKKyNpbmNsdWRlICJBbmFsb2dQb3RlbnRpb21ldGVyLmgiCisjaW5jbHVkZSAiQ29udHJvbGxlclBvd2VyLmgiCisKKy8qKgorICogQ29uc3RydWN0IGFuIEFuYWxvZyBQb3RlbnRpb21ldGVyIG9iamVjdCBmcm9tIGEgY2hhbm5lbCBudW1iZXIuCisgKiBAcGFyYW0gY2hhbm5lbCBUaGUgY2hhbm5lbCBudW1iZXIgb24gdGhlIHJvYm9SSU8gdG8gcmVwcmVzZW50LiAwLTMgYXJlCisgKiBvbi1ib2FyZCA0LTcgYXJlIG9uIHRoZSBNWFAgcG9ydC4KKyAqIEBwYXJhbSBmdWxsUmFuZ2UgVGhlIGFuZ3VsYXIgdmFsdWUgKGluIGRlc2lyZWQgdW5pdHMpIHJlcHJlc2VudGluZyB0aGUgZnVsbAorICogMC01ViByYW5nZSBvZiB0aGUgaW5wdXQuCisgKiBAcGFyYW0gb2Zmc2V0IFRoZSBhbmd1bGFyIHZhbHVlIChpbiBkZXNpcmVkIHVuaXRzKSByZXByZXNlbnRpbmcgdGhlIGFuZ3VsYXIKKyAqIG91dHB1dCBhdCAwVi4KKyAqLworQW5hbG9nUG90ZW50aW9tZXRlcjo6QW5hbG9nUG90ZW50aW9tZXRlcihpbnQgY2hhbm5lbCwgZG91YmxlIGZ1bGxSYW5nZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZG91YmxlIG9mZnNldCkKKyAgICA6IG1fYW5hbG9nX2lucHV0KHN0ZDo6bWFrZV91bmlxdWU8QW5hbG9nSW5wdXQ+KGNoYW5uZWwpKSwKKyAgICAgIG1fZnVsbFJhbmdlKGZ1bGxSYW5nZSksCisgICAgICBtX29mZnNldChvZmZzZXQpIHt9CisKKy8qKgorICogQ29uc3RydWN0IGFuIEFuYWxvZyBQb3RlbnRpb21ldGVyIG9iamVjdCBmcm9tIGFuIGV4aXN0aW5nIEFuYWxvZyBJbnB1dAorICogcG9pbnRlci4KKyAqIEBwYXJhbSBjaGFubmVsIFRoZSBleGlzdGluZyBBbmFsb2cgSW5wdXQgcG9pbnRlcgorICogQHBhcmFtIGZ1bGxSYW5nZSBUaGUgYW5ndWxhciB2YWx1ZSAoaW4gZGVzaXJlZCB1bml0cykgcmVwcmVzZW50aW5nIHRoZSBmdWxsCisgKiAwLTVWIHJhbmdlIG9mIHRoZSBpbnB1dC4KKyAqIEBwYXJhbSBvZmZzZXQgVGhlIGFuZ3VsYXIgdmFsdWUgKGluIGRlc2lyZWQgdW5pdHMpIHJlcHJlc2VudGluZyB0aGUgYW5ndWxhcgorICogb3V0cHV0IGF0IDBWLgorICovCitBbmFsb2dQb3RlbnRpb21ldGVyOjpBbmFsb2dQb3RlbnRpb21ldGVyKEFuYWxvZ0lucHV0ICppbnB1dCwgZG91YmxlIGZ1bGxSYW5nZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZG91YmxlIG9mZnNldCkKKyAgICA6IG1fYW5hbG9nX2lucHV0KGlucHV0LCBOdWxsRGVsZXRlcjxBbmFsb2dJbnB1dD4oKSksCisgICAgICBtX2Z1bGxSYW5nZShmdWxsUmFuZ2UpLAorICAgICAgbV9vZmZzZXQob2Zmc2V0KSB7fQorCisvKioKKyAqIENvbnN0cnVjdCBhbiBBbmFsb2cgUG90ZW50aW9tZXRlciBvYmplY3QgZnJvbSBhbiBleGlzdGluZyBBbmFsb2cgSW5wdXQKKyAqIHBvaW50ZXIuCisgKiBAcGFyYW0gY2hhbm5lbCBUaGUgZXhpc3RpbmcgQW5hbG9nIElucHV0IHBvaW50ZXIKKyAqIEBwYXJhbSBmdWxsUmFuZ2UgVGhlIGFuZ3VsYXIgdmFsdWUgKGluIGRlc2lyZWQgdW5pdHMpIHJlcHJlc2VudGluZyB0aGUgZnVsbAorICogMC01ViByYW5nZSBvZiB0aGUgaW5wdXQuCisgKiBAcGFyYW0gb2Zmc2V0IFRoZSBhbmd1bGFyIHZhbHVlIChpbiBkZXNpcmVkIHVuaXRzKSByZXByZXNlbnRpbmcgdGhlIGFuZ3VsYXIKKyAqIG91dHB1dCBhdCAwVi4KKyAqLworQW5hbG9nUG90ZW50aW9tZXRlcjo6QW5hbG9nUG90ZW50aW9tZXRlcihzdGQ6OnNoYXJlZF9wdHI8QW5hbG9nSW5wdXQ+IGlucHV0LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkb3VibGUgZnVsbFJhbmdlLCBkb3VibGUgb2Zmc2V0KQorICAgIDogbV9hbmFsb2dfaW5wdXQoaW5wdXQpLCBtX2Z1bGxSYW5nZShmdWxsUmFuZ2UpLCBtX29mZnNldChvZmZzZXQpIHt9CisKKy8qKgorICogR2V0IHRoZSBjdXJyZW50IHJlYWRpbmcgb2YgdGhlIHBvdGVudGlvbWV0ZXIuCisgKgorICogQHJldHVybiBUaGUgY3VycmVudCBwb3NpdGlvbiBvZiB0aGUgcG90ZW50aW9tZXRlciAoaW4gdGhlIHVuaXRzIHVzZWQgZm9yCisgKiBmdWxsUmFuZWcgYW5kIG9mZnNldCkuCisgKi8KK2RvdWJsZSBBbmFsb2dQb3RlbnRpb21ldGVyOjpHZXQoKSBjb25zdCB7CisgIHJldHVybiAobV9hbmFsb2dfaW5wdXQtPkdldFZvbHRhZ2UoKSAvIENvbnRyb2xsZXJQb3dlcjo6R2V0Vm9sdGFnZTVWKCkpICoKKyAgICAgICAgICAgICBtX2Z1bGxSYW5nZSArCisgICAgICAgICBtX29mZnNldDsKK30KKworLyoqCisgKiBJbXBsZW1lbnQgdGhlIFBJRFNvdXJjZSBpbnRlcmZhY2UuCisgKgorICogQHJldHVybiBUaGUgY3VycmVudCByZWFkaW5nLgorICovCitkb3VibGUgQW5hbG9nUG90ZW50aW9tZXRlcjo6UElER2V0KCkgeyByZXR1cm4gR2V0KCk7IH0KKworLyoqCisgKiBAcmV0dXJuIHRoZSBTbWFydCBEYXNoYm9hcmQgVHlwZQorICovCitzdGQ6OnN0cmluZyBBbmFsb2dQb3RlbnRpb21ldGVyOjpHZXRTbWFydERhc2hib2FyZFR5cGUoKSBjb25zdCB7CisgIHJldHVybiAiQW5hbG9nIElucHV0IjsKK30KKworLyoqCisgKiBMaXZlIFdpbmRvdyBjb2RlLCBvbmx5IGRvZXMgYW55dGhpbmcgaWYgbGl2ZSB3aW5kb3cgaXMgYWN0aXZhdGVkLgorICovCit2b2lkIEFuYWxvZ1BvdGVudGlvbWV0ZXI6OkluaXRUYWJsZShzdGQ6OnNoYXJlZF9wdHI8SVRhYmxlPiBzdWJ0YWJsZSkgeworICBtX3RhYmxlID0gc3VidGFibGU7CisgIFVwZGF0ZVRhYmxlKCk7Cit9CisKK3ZvaWQgQW5hbG9nUG90ZW50aW9tZXRlcjo6VXBkYXRlVGFibGUoKSB7CisgIGlmIChtX3RhYmxlICE9IG51bGxwdHIpIHsKKyAgICBtX3RhYmxlLT5QdXROdW1iZXIoIlZhbHVlIiwgR2V0KCkpOworICB9Cit9CisKK3N0ZDo6c2hhcmVkX3B0cjxJVGFibGU+IEFuYWxvZ1BvdGVudGlvbWV0ZXI6OkdldFRhYmxlKCkgY29uc3QgeyByZXR1cm4gbV90YWJsZTsgfQpkaWZmIC0tZ2l0IGEvd3BpbGliYy9BdGhlbmEvc3JjL0FuYWxvZ1RyaWdnZXIuY3BwIGIvd3BpbGliYy9BdGhlbmEvc3JjL0FuYWxvZ1RyaWdnZXIuY3BwCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmI0OWQ2YTAKLS0tIC9kZXYvbnVsbAorKysgYi93cGlsaWJjL0F0aGVuYS9zcmMvQW5hbG9nVHJpZ2dlci5jcHAKQEAgLTAsMCArMSwxNjEgQEAKKy8qLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovCisvKiBDb3B5cmlnaHQgKGMpIEZJUlNUIDIwMDguIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCisgKi8KKy8qIE9wZW4gU291cmNlIFNvZnR3YXJlIC0gbWF5IGJlIG1vZGlmaWVkIGFuZCBzaGFyZWQgYnkgRlJDIHRlYW1zLiBUaGUgY29kZSAgICovCisvKiBtdXN0IGJlIGFjY29tcGFuaWVkIGJ5IHRoZSBGSVJTVCBCU0QgbGljZW5zZSBmaWxlIGluICQoV0lORF9CQVNFKS9XUElMaWIuICAqLworLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi8KKworI2luY2x1ZGUgIkFuYWxvZ1RyaWdnZXIuaCIKKworI2luY2x1ZGUgIkFuYWxvZ0lucHV0LmgiCisjaW5jbHVkZSAiUmVzb3VyY2UuaCIKKyNpbmNsdWRlICJXUElFcnJvcnMuaCIKKyNpbmNsdWRlICJIQUwvUG9ydC5oIgorCisjaW5jbHVkZSA8bWVtb3J5PgorCisvKioKKyAqIENvbnN0cnVjdG9yIGZvciBhbiBhbmFsb2cgdHJpZ2dlciBnaXZlbiBhIGNoYW5uZWwgbnVtYmVyLgorICoKKyAqIEBwYXJhbSBjaGFubmVsIFRoZSBjaGFubmVsIG51bWJlciBvbiB0aGUgcm9ib1JJTyB0byByZXByZXNlbnQuIDAtMyBhcmUKKyAqIG9uLWJvYXJkIDQtNyBhcmUgb24gdGhlIE1YUCBwb3J0LgorICovCitBbmFsb2dUcmlnZ2VyOjpBbmFsb2dUcmlnZ2VyKGludDMyX3QgY2hhbm5lbCkgeworICB2b2lkKiBwb3J0ID0gZ2V0UG9ydChjaGFubmVsKTsKKyAgaW50MzJfdCBzdGF0dXMgPSAwOworICB1aW50MzJfdCBpbmRleCA9IDA7CisgIG1fdHJpZ2dlciA9IGluaXRpYWxpemVBbmFsb2dUcmlnZ2VyKHBvcnQsICZpbmRleCwgJnN0YXR1cyk7CisgIHdwaV9zZXRFcnJvcldpdGhDb250ZXh0KHN0YXR1cywgZ2V0SEFMRXJyb3JNZXNzYWdlKHN0YXR1cykpOworICBmcmVlUG9ydChwb3J0KTsKKyAgbV9pbmRleCA9IGluZGV4OworCisgIEhBTFJlcG9ydChIQUxVc2FnZVJlcG9ydGluZzo6a1Jlc291cmNlVHlwZV9BbmFsb2dUcmlnZ2VyLCBjaGFubmVsKTsKK30KKworLyoqCisgKiBDb25zdHJ1Y3QgYW4gYW5hbG9nIHRyaWdnZXIgZ2l2ZW4gYW4gYW5hbG9nIGlucHV0LgorICogVGhpcyBzaG91bGQgYmUgdXNlZCBpbiB0aGUgY2FzZSBvZiBzaGFyaW5nIGFuIGFuYWxvZyBjaGFubmVsIGJldHdlZW4gdGhlCisgKiB0cmlnZ2VyIGFuZCBhbiBhbmFsb2cgaW5wdXQgb2JqZWN0LgorICogQHBhcmFtIGNoYW5uZWwgVGhlIHBvaW50ZXIgdG8gdGhlIGV4aXN0aW5nIEFuYWxvZ0lucHV0IG9iamVjdAorICovCitBbmFsb2dUcmlnZ2VyOjpBbmFsb2dUcmlnZ2VyKEFuYWxvZ0lucHV0ICppbnB1dCkgOgorICAgIEFuYWxvZ1RyaWdnZXIoaW5wdXQtPkdldENoYW5uZWwoKSkgeworfQorCitBbmFsb2dUcmlnZ2VyOjp+QW5hbG9nVHJpZ2dlcigpIHsKKyAgaW50MzJfdCBzdGF0dXMgPSAwOworICBjbGVhbkFuYWxvZ1RyaWdnZXIobV90cmlnZ2VyLCAmc3RhdHVzKTsKKyAgd3BpX3NldEVycm9yV2l0aENvbnRleHQoc3RhdHVzLCBnZXRIQUxFcnJvck1lc3NhZ2Uoc3RhdHVzKSk7Cit9CisKKy8qKgorICogU2V0IHRoZSB1cHBlciBhbmQgbG93ZXIgbGltaXRzIG9mIHRoZSBhbmFsb2cgdHJpZ2dlci4KKyAqIFRoZSBsaW1pdHMgYXJlIGdpdmVuIGluIEFEQyBjb2Rlcy4gIElmIG92ZXJzYW1wbGluZyBpcyB1c2VkLCB0aGUgdW5pdHMgbXVzdAorICogYmUgc2NhbGVkCisgKiBhcHByb3ByaWF0ZWx5LgorICogQHBhcmFtIGxvd2VyIFRoZSBsb3dlciBsaW1pdCBvZiB0aGUgdHJpZ2dlciBpbiBBREMgY29kZXMgKDEyLWJpdCB2YWx1ZXMpLgorICogQHBhcmFtIHVwcGVyIFRoZSB1cHBlciBsaW1pdCBvZiB0aGUgdHJpZ2dlciBpbiBBREMgY29kZXMgKDEyLWJpdCB2YWx1ZXMpLgorICovCit2b2lkIEFuYWxvZ1RyaWdnZXI6OlNldExpbWl0c1JhdyhpbnQzMl90IGxvd2VyLCBpbnQzMl90IHVwcGVyKSB7CisgIGlmIChTdGF0dXNJc0ZhdGFsKCkpIHJldHVybjsKKyAgaW50MzJfdCBzdGF0dXMgPSAwOworICBzZXRBbmFsb2dUcmlnZ2VyTGltaXRzUmF3KG1fdHJpZ2dlciwgbG93ZXIsIHVwcGVyLCAmc3RhdHVzKTsKKyAgd3BpX3NldEVycm9yV2l0aENvbnRleHQoc3RhdHVzLCBnZXRIQUxFcnJvck1lc3NhZ2Uoc3RhdHVzKSk7Cit9CisKKy8qKgorICogU2V0IHRoZSB1cHBlciBhbmQgbG93ZXIgbGltaXRzIG9mIHRoZSBhbmFsb2cgdHJpZ2dlci4KKyAqIFRoZSBsaW1pdHMgYXJlIGdpdmVuIGFzIGZsb2F0aW5nIHBvaW50IHZvbHRhZ2UgdmFsdWVzLgorICogQHBhcmFtIGxvd2VyIFRoZSBsb3dlciBsaW1pdCBvZiB0aGUgdHJpZ2dlciBpbiBWb2x0cy4KKyAqIEBwYXJhbSB1cHBlciBUaGUgdXBwZXIgbGltaXQgb2YgdGhlIHRyaWdnZXIgaW4gVm9sdHMuCisgKi8KK3ZvaWQgQW5hbG9nVHJpZ2dlcjo6U2V0TGltaXRzVm9sdGFnZShmbG9hdCBsb3dlciwgZmxvYXQgdXBwZXIpIHsKKyAgaWYgKFN0YXR1c0lzRmF0YWwoKSkgcmV0dXJuOworICBpbnQzMl90IHN0YXR1cyA9IDA7CisgIHNldEFuYWxvZ1RyaWdnZXJMaW1pdHNWb2x0YWdlKG1fdHJpZ2dlciwgbG93ZXIsIHVwcGVyLCAmc3RhdHVzKTsKKyAgd3BpX3NldEVycm9yV2l0aENvbnRleHQoc3RhdHVzLCBnZXRIQUxFcnJvck1lc3NhZ2Uoc3RhdHVzKSk7Cit9CisKKy8qKgorICogQ29uZmlndXJlIHRoZSBhbmFsb2cgdHJpZ2dlciB0byB1c2UgdGhlIGF2ZXJhZ2VkIHZzLiByYXcgdmFsdWVzLgorICogSWYgdGhlIHZhbHVlIGlzIHRydWUsIHRoZW4gdGhlIGF2ZXJhZ2VkIHZhbHVlIGlzIHNlbGVjdGVkIGZvciB0aGUgYW5hbG9nCisgKiB0cmlnZ2VyLCBvdGhlcndpc2UKKyAqIHRoZSBpbW1lZGlhdGUgdmFsdWUgaXMgdXNlZC4KKyAqIEBwYXJhbSB1c2VBdmVyYWdlZFZhbHVlIElmIHRydWUsIHVzZSB0aGUgQXZlcmFnZWQgdmFsdWUsIG90aGVyd2lzZSB1c2UgdGhlCisgKiBpbnN0YW50YW5lb3VzIHJlYWRpbmcKKyAqLwordm9pZCBBbmFsb2dUcmlnZ2VyOjpTZXRBdmVyYWdlZChib29sIHVzZUF2ZXJhZ2VkVmFsdWUpIHsKKyAgaWYgKFN0YXR1c0lzRmF0YWwoKSkgcmV0dXJuOworICBpbnQzMl90IHN0YXR1cyA9IDA7CisgIHNldEFuYWxvZ1RyaWdnZXJBdmVyYWdlZChtX3RyaWdnZXIsIHVzZUF2ZXJhZ2VkVmFsdWUsICZzdGF0dXMpOworICB3cGlfc2V0RXJyb3JXaXRoQ29udGV4dChzdGF0dXMsIGdldEhBTEVycm9yTWVzc2FnZShzdGF0dXMpKTsKK30KKworLyoqCisgKiBDb25maWd1cmUgdGhlIGFuYWxvZyB0cmlnZ2VyIHRvIHVzZSBhIGZpbHRlcmVkIHZhbHVlLgorICogVGhlIGFuYWxvZyB0cmlnZ2VyIHdpbGwgb3BlcmF0ZSB3aXRoIGEgMyBwb2ludCBhdmVyYWdlIHJlamVjdGlvbiBmaWx0ZXIuIFRoaXMKKyAqIGlzIGRlc2lnbmVkIHRvCisgKiBoZWxwIHdpdGggMzYwIGRlZ3JlZSBwb3QgYXBwbGljYXRpb25zIGZvciB0aGUgcGVyaW9kIHdoZXJlIHRoZSBwb3QgY3Jvc3NlcworICogdGhyb3VnaCB6ZXJvLgorICogQHBhcmFtIHVzZUZpbHRlcmVkVmFsdWUgSWYgdHJ1ZSwgdXNlIHRoZSAzIHBvaW50IHJlamVjdGlvbiBmaWx0ZXIsIG90aGVyd2lzZQorICogdXNlIHRoZSB1bmZpbHRlcmVkIHZhbHVlCisgKi8KK3ZvaWQgQW5hbG9nVHJpZ2dlcjo6U2V0RmlsdGVyZWQoYm9vbCB1c2VGaWx0ZXJlZFZhbHVlKSB7CisgIGlmIChTdGF0dXNJc0ZhdGFsKCkpIHJldHVybjsKKyAgaW50MzJfdCBzdGF0dXMgPSAwOworICBzZXRBbmFsb2dUcmlnZ2VyRmlsdGVyZWQobV90cmlnZ2VyLCB1c2VGaWx0ZXJlZFZhbHVlLCAmc3RhdHVzKTsKKyAgd3BpX3NldEVycm9yV2l0aENvbnRleHQoc3RhdHVzLCBnZXRIQUxFcnJvck1lc3NhZ2Uoc3RhdHVzKSk7Cit9CisKKy8qKgorICogUmV0dXJuIHRoZSBpbmRleCBvZiB0aGUgYW5hbG9nIHRyaWdnZXIuCisgKiBUaGlzIGlzIHRoZSBGUEdBIGluZGV4IG9mIHRoaXMgYW5hbG9nIHRyaWdnZXIgaW5zdGFuY2UuCisgKiBAcmV0dXJuIFRoZSBpbmRleCBvZiB0aGUgYW5hbG9nIHRyaWdnZXIuCisgKi8KK3VpbnQzMl90IEFuYWxvZ1RyaWdnZXI6OkdldEluZGV4KCkgY29uc3QgeworICBpZiAoU3RhdHVzSXNGYXRhbCgpKSByZXR1cm4gc3RkOjpudW1lcmljX2xpbWl0czx1aW50MzJfdD46Om1heCgpOworICByZXR1cm4gbV9pbmRleDsKK30KKworLyoqCisgKiBSZXR1cm4gdGhlIEluV2luZG93IG91dHB1dCBvZiB0aGUgYW5hbG9nIHRyaWdnZXIuCisgKiBUcnVlIGlmIHRoZSBhbmFsb2cgaW5wdXQgaXMgYmV0d2VlbiB0aGUgdXBwZXIgYW5kIGxvd2VyIGxpbWl0cy4KKyAqIEByZXR1cm4gVHJ1ZSBpZiB0aGUgYW5hbG9nIGlucHV0IGlzIGJldHdlZW4gdGhlIHVwcGVyIGFuZCBsb3dlciBsaW1pdHMuCisgKi8KK2Jvb2wgQW5hbG9nVHJpZ2dlcjo6R2V0SW5XaW5kb3coKSB7CisgIGlmIChTdGF0dXNJc0ZhdGFsKCkpIHJldHVybiBmYWxzZTsKKyAgaW50MzJfdCBzdGF0dXMgPSAwOworICBib29sIHJlc3VsdCA9IGdldEFuYWxvZ1RyaWdnZXJJbldpbmRvdyhtX3RyaWdnZXIsICZzdGF0dXMpOworICB3cGlfc2V0RXJyb3JXaXRoQ29udGV4dChzdGF0dXMsIGdldEhBTEVycm9yTWVzc2FnZShzdGF0dXMpKTsKKyAgcmV0dXJuIHJlc3VsdDsKK30KKworLyoqCisgKiBSZXR1cm4gdGhlIFRyaWdnZXJTdGF0ZSBvdXRwdXQgb2YgdGhlIGFuYWxvZyB0cmlnZ2VyLgorICogVHJ1ZSBpZiBhYm92ZSB1cHBlciBsaW1pdC4KKyAqIEZhbHNlIGlmIGJlbG93IGxvd2VyIGxpbWl0LgorICogSWYgaW4gSHlzdGVyZXNpcywgbWFpbnRhaW4gcHJldmlvdXMgc3RhdGUuCisgKiBAcmV0dXJuIFRydWUgaWYgYWJvdmUgdXBwZXIgbGltaXQuIEZhbHNlIGlmIGJlbG93IGxvd2VyIGxpbWl0LiBJZiBpbgorICogSHlzdGVyZXNpcywgbWFpbnRhaW4gcHJldmlvdXMgc3RhdGUuCisgKi8KK2Jvb2wgQW5hbG9nVHJpZ2dlcjo6R2V0VHJpZ2dlclN0YXRlKCkgeworICBpZiAoU3RhdHVzSXNGYXRhbCgpKSByZXR1cm4gZmFsc2U7CisgIGludDMyX3Qgc3RhdHVzID0gMDsKKyAgYm9vbCByZXN1bHQgPSBnZXRBbmFsb2dUcmlnZ2VyVHJpZ2dlclN0YXRlKG1fdHJpZ2dlciwgJnN0YXR1cyk7CisgIHdwaV9zZXRFcnJvcldpdGhDb250ZXh0KHN0YXR1cywgZ2V0SEFMRXJyb3JNZXNzYWdlKHN0YXR1cykpOworICByZXR1cm4gcmVzdWx0OworfQorCisvKioKKyAqIENyZWF0ZXMgYW4gQW5hbG9nVHJpZ2dlck91dHB1dCBvYmplY3QuCisgKiBHZXRzIGFuIG91dHB1dCBvYmplY3QgdGhhdCBjYW4gYmUgdXNlZCBmb3Igcm91dGluZy4KKyAqIENhbGxlciBpcyByZXNwb25zaWJsZSBmb3IgZGVsZXRpbmcgdGhlIEFuYWxvZ1RyaWdnZXJPdXRwdXQgb2JqZWN0LgorICogQHBhcmFtIHR5cGUgQW4gZW51bSBvZiB0aGUgdHlwZSBvZiBvdXRwdXQgb2JqZWN0IHRvIGNyZWF0ZS4KKyAqIEByZXR1cm4gQSBwb2ludGVyIHRvIGEgbmV3IEFuYWxvZ1RyaWdnZXJPdXRwdXQgb2JqZWN0LgorICovCitzdGQ6OnNoYXJlZF9wdHI8QW5hbG9nVHJpZ2dlck91dHB1dD4gQW5hbG9nVHJpZ2dlcjo6Q3JlYXRlT3V0cHV0KAorICAgIEFuYWxvZ1RyaWdnZXJUeXBlIHR5cGUpIGNvbnN0IHsKKyAgaWYgKFN0YXR1c0lzRmF0YWwoKSkgcmV0dXJuIG51bGxwdHI7CisgIHJldHVybiBzdGQ6OnNoYXJlZF9wdHI8QW5hbG9nVHJpZ2dlck91dHB1dD4oCisgICAgICBuZXcgQW5hbG9nVHJpZ2dlck91dHB1dCgqdGhpcywgdHlwZSksIE51bGxEZWxldGVyPEFuYWxvZ1RyaWdnZXJPdXRwdXQ+KCkpOworfQpkaWZmIC0tZ2l0IGEvd3BpbGliYy9BdGhlbmEvc3JjL0FuYWxvZ1RyaWdnZXJPdXRwdXQuY3BwIGIvd3BpbGliYy9BdGhlbmEvc3JjL0FuYWxvZ1RyaWdnZXJPdXRwdXQuY3BwCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjgyNTQyNzUKLS0tIC9kZXYvbnVsbAorKysgYi93cGlsaWJjL0F0aGVuYS9zcmMvQW5hbG9nVHJpZ2dlck91dHB1dC5jcHAKQEAgLTAsMCArMSw2OCBAQAorLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi8KKy8qIENvcHlyaWdodCAoYykgRklSU1QgMjAwOC4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KKyAqLworLyogT3BlbiBTb3VyY2UgU29mdHdhcmUgLSBtYXkgYmUgbW9kaWZpZWQgYW5kIHNoYXJlZCBieSBGUkMgdGVhbXMuIFRoZSBjb2RlICAgKi8KKy8qIG11c3QgYmUgYWNjb21wYW5pZWQgYnkgdGhlIEZJUlNUIEJTRCBsaWNlbnNlIGZpbGUgaW4gJChXSU5EX0JBU0UpL1dQSUxpYi4gICovCisvKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qLworCisjaW5jbHVkZSAiQW5hbG9nVHJpZ2dlck91dHB1dC5oIgorI2luY2x1ZGUgIkFuYWxvZ1RyaWdnZXIuaCIKKyNpbmNsdWRlICJXUElFcnJvcnMuaCIKKworLyoqCisgKiBDcmVhdGUgYW4gb2JqZWN0IHRoYXQgcmVwcmVzZW50cyBvbmUgb2YgdGhlIGZvdXIgb3V0cHV0cyBmcm9tIGFuIGFuYWxvZworICogdHJpZ2dlci4KKyAqCisgKiBCZWNhdXNlIHRoaXMgY2xhc3MgZGVyaXZlcyBmcm9tIERpZ2l0YWxTb3VyY2UsIGl0IGNhbiBiZSBwYXNzZWQgaW50byByb3V0aW5nCisgKiBmdW5jdGlvbnMKKyAqIGZvciBDb3VudGVyLCBFbmNvZGVyLCBldGMuCisgKgorICogQHBhcmFtIHRyaWdnZXIgQSBwb2ludGVyIHRvIHRoZSB0cmlnZ2VyIGZvciB3aGljaCB0aGlzIGlzIGFuIG91dHB1dC4KKyAqIEBwYXJhbSBvdXRwdXRUeXBlIEFuIGVudW0gdGhhdCBzcGVjaWZpZXMgdGhlIG91dHB1dCBvbiB0aGUgdHJpZ2dlciB0bworICogcmVwcmVzZW50LgorICovCitBbmFsb2dUcmlnZ2VyT3V0cHV0OjpBbmFsb2dUcmlnZ2VyT3V0cHV0KGNvbnN0IEFuYWxvZ1RyaWdnZXIgJnRyaWdnZXIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEFuYWxvZ1RyaWdnZXJUeXBlIG91dHB1dFR5cGUpCisgICAgOiBtX3RyaWdnZXIodHJpZ2dlciksIG1fb3V0cHV0VHlwZShvdXRwdXRUeXBlKSB7CisgIEhBTFJlcG9ydChIQUxVc2FnZVJlcG9ydGluZzo6a1Jlc291cmNlVHlwZV9BbmFsb2dUcmlnZ2VyT3V0cHV0LAorICAgICAgICAgICAgdHJpZ2dlci5HZXRJbmRleCgpLCBvdXRwdXRUeXBlKTsKK30KKworQW5hbG9nVHJpZ2dlck91dHB1dDo6fkFuYWxvZ1RyaWdnZXJPdXRwdXQoKSB7CisgIGlmIChtX2ludGVycnVwdCAhPSBudWxscHRyKSB7CisgICAgaW50MzJfdCBzdGF0dXMgPSAwOworICAgIGNsZWFuSW50ZXJydXB0cyhtX2ludGVycnVwdCwgJnN0YXR1cyk7CisgICAgd3BpX3NldEVycm9yV2l0aENvbnRleHQoc3RhdHVzLCBnZXRIQUxFcnJvck1lc3NhZ2Uoc3RhdHVzKSk7CisgICAgbV9pbnRlcnJ1cHQgPSBudWxscHRyOworICAgIG1faW50ZXJydXB0cy0+RnJlZShtX2ludGVycnVwdEluZGV4KTsKKyAgfQorfQorCisvKioKKyAqIEdldCB0aGUgc3RhdGUgb2YgdGhlIGFuYWxvZyB0cmlnZ2VyIG91dHB1dC4KKyAqIEByZXR1cm4gVGhlIHN0YXRlIG9mIHRoZSBhbmFsb2cgdHJpZ2dlciBvdXRwdXQuCisgKi8KK2Jvb2wgQW5hbG9nVHJpZ2dlck91dHB1dDo6R2V0KCkgY29uc3QgeworICBpbnQzMl90IHN0YXR1cyA9IDA7CisgIGJvb2wgcmVzdWx0ID0KKyAgICAgIGdldEFuYWxvZ1RyaWdnZXJPdXRwdXQobV90cmlnZ2VyLm1fdHJpZ2dlciwgbV9vdXRwdXRUeXBlLCAmc3RhdHVzKTsKKyAgd3BpX3NldEVycm9yV2l0aENvbnRleHQoc3RhdHVzLCBnZXRIQUxFcnJvck1lc3NhZ2Uoc3RhdHVzKSk7CisgIHJldHVybiByZXN1bHQ7Cit9CisKKy8qKgorICogQHJldHVybiBUaGUgdmFsdWUgdG8gYmUgd3JpdHRlbiB0byB0aGUgY2hhbm5lbCBmaWVsZCBvZiBhIHJvdXRpbmcgbXV4LgorICovCit1aW50MzJfdCBBbmFsb2dUcmlnZ2VyT3V0cHV0OjpHZXRDaGFubmVsRm9yUm91dGluZygpIGNvbnN0IHsKKyAgcmV0dXJuIChtX3RyaWdnZXIubV9pbmRleCA8PCAyKSArIG1fb3V0cHV0VHlwZTsKK30KKworLyoqCisgKiBAcmV0dXJuIFRoZSB2YWx1ZSB0byBiZSB3cml0dGVuIHRvIHRoZSBtb2R1bGUgZmllbGQgb2YgYSByb3V0aW5nIG11eC4KKyAqLwordWludDMyX3QgQW5hbG9nVHJpZ2dlck91dHB1dDo6R2V0TW9kdWxlRm9yUm91dGluZygpIGNvbnN0IHsgcmV0dXJuIDA7IH0KKworLyoqCisgKiBAcmV0dXJuIFRoZSB2YWx1ZSB0byBiZSB3cml0dGVuIHRvIHRoZSBtb2R1bGUgZmllbGQgb2YgYSByb3V0aW5nIG11eC4KKyAqLworYm9vbCBBbmFsb2dUcmlnZ2VyT3V0cHV0OjpHZXRBbmFsb2dUcmlnZ2VyRm9yUm91dGluZygpIGNvbnN0IHsgcmV0dXJuIHRydWU7IH0KZGlmZiAtLWdpdCBhL3dwaWxpYmMvQXRoZW5hL3NyYy9CdWlsdEluQWNjZWxlcm9tZXRlci5jcHAgYi93cGlsaWJjL0F0aGVuYS9zcmMvQnVpbHRJbkFjY2VsZXJvbWV0ZXIuY3BwCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmE1MDQ1MjQKLS0tIC9kZXYvbnVsbAorKysgYi93cGlsaWJjL0F0aGVuYS9zcmMvQnVpbHRJbkFjY2VsZXJvbWV0ZXIuY3BwCkBAIC0wLDAgKzEsNjggQEAKKy8qLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovCisvKiBDb3B5cmlnaHQgKGMpIEZJUlNUIDIwMTQuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqLworLyogT3BlbiBTb3VyY2UgU29mdHdhcmUgLSBtYXkgYmUgbW9kaWZpZWQgYW5kIHNoYXJlZCBieSBGUkMgdGVhbXMuIFRoZSBjb2RlICAgKi8KKy8qIG11c3QgYmUgYWNjb21wYW5pZWQgYnkgdGhlIEZJUlNUIEJTRCBsaWNlbnNlIGZpbGUgaW4gJChXSU5EX0JBU0UpL1dQSUxpYi4gICovCisvKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qLworCisjaW5jbHVkZSAiQnVpbHRJbkFjY2VsZXJvbWV0ZXIuaCIKKyNpbmNsdWRlICJIQUwvSEFMLmhwcCIKKyNpbmNsdWRlICJXUElFcnJvcnMuaCIKKyNpbmNsdWRlICJMaXZlV2luZG93L0xpdmVXaW5kb3cuaCIKKworLyoqCisgKiBDb25zdHJ1Y3Rvci4KKyAqIEBwYXJhbSByYW5nZSBUaGUgcmFuZ2UgdGhlIGFjY2VsZXJvbWV0ZXIgd2lsbCBtZWFzdXJlCisgKi8KK0J1aWx0SW5BY2NlbGVyb21ldGVyOjpCdWlsdEluQWNjZWxlcm9tZXRlcihSYW5nZSByYW5nZSkgeworICBTZXRSYW5nZShyYW5nZSk7CisKKyAgSEFMUmVwb3J0KEhBTFVzYWdlUmVwb3J0aW5nOjprUmVzb3VyY2VUeXBlX0FjY2VsZXJvbWV0ZXIsIDAsIDAsCisgICAgICAgICAgICAiQnVpbHQtaW4gYWNjZWxlcm9tZXRlciIpOworICBMaXZlV2luZG93OjpHZXRJbnN0YW5jZSgpLT5BZGRTZW5zb3IoKHN0ZDo6c3RyaW5nKSAiQnVpbHRJbkFjY2VsIiwgMCwgdGhpcyk7Cit9CisKKy8qKiB7QGluaGVyaXRkb2N9ICovCit2b2lkIEJ1aWx0SW5BY2NlbGVyb21ldGVyOjpTZXRSYW5nZShSYW5nZSByYW5nZSkgeworICBpZiAocmFuZ2UgPT0ga1JhbmdlXzE2RykgeworICAgIHdwaV9zZXRXUElFcnJvcldpdGhDb250ZXh0KAorICAgICAgICBQYXJhbWV0ZXJPdXRPZlJhbmdlLCAiMTZHIHJhbmdlIG5vdCBzdXBwb3J0ZWQgKHVzZSBrMkcsIGs0Rywgb3IgazhHKSIpOworICB9CisKKyAgc2V0QWNjZWxlcm9tZXRlckFjdGl2ZShmYWxzZSk7CisgIHNldEFjY2VsZXJvbWV0ZXJSYW5nZSgoQWNjZWxlcm9tZXRlclJhbmdlKXJhbmdlKTsKKyAgc2V0QWNjZWxlcm9tZXRlckFjdGl2ZSh0cnVlKTsKK30KKworLyoqCisgKiBAcmV0dXJuIFRoZSBhY2NlbGVyYXRpb24gb2YgdGhlIFJvYm9SSU8gYWxvbmcgdGhlIFggYXhpcyBpbiBnLWZvcmNlcworICovCitkb3VibGUgQnVpbHRJbkFjY2VsZXJvbWV0ZXI6OkdldFgoKSB7IHJldHVybiBnZXRBY2NlbGVyb21ldGVyWCgpOyB9CisKKy8qKgorICogQHJldHVybiBUaGUgYWNjZWxlcmF0aW9uIG9mIHRoZSBSb2JvUklPIGFsb25nIHRoZSBZIGF4aXMgaW4gZy1mb3JjZXMKKyAqLworZG91YmxlIEJ1aWx0SW5BY2NlbGVyb21ldGVyOjpHZXRZKCkgeyByZXR1cm4gZ2V0QWNjZWxlcm9tZXRlclkoKTsgfQorCisvKioKKyAqIEByZXR1cm4gVGhlIGFjY2VsZXJhdGlvbiBvZiB0aGUgUm9ib1JJTyBhbG9uZyB0aGUgWiBheGlzIGluIGctZm9yY2VzCisgKi8KK2RvdWJsZSBCdWlsdEluQWNjZWxlcm9tZXRlcjo6R2V0WigpIHsgcmV0dXJuIGdldEFjY2VsZXJvbWV0ZXJaKCk7IH0KKworc3RkOjpzdHJpbmcgQnVpbHRJbkFjY2VsZXJvbWV0ZXI6OkdldFNtYXJ0RGFzaGJvYXJkVHlwZSgpIGNvbnN0IHsKKyAgcmV0dXJuICIzQXhpc0FjY2VsZXJvbWV0ZXIiOworfQorCit2b2lkIEJ1aWx0SW5BY2NlbGVyb21ldGVyOjpJbml0VGFibGUoc3RkOjpzaGFyZWRfcHRyPElUYWJsZT4gc3VidGFibGUpIHsKKyAgbV90YWJsZSA9IHN1YnRhYmxlOworICBVcGRhdGVUYWJsZSgpOworfQorCit2b2lkIEJ1aWx0SW5BY2NlbGVyb21ldGVyOjpVcGRhdGVUYWJsZSgpIHsKKyAgaWYgKG1fdGFibGUgIT0gbnVsbHB0cikgeworICAgIG1fdGFibGUtPlB1dE51bWJlcigiWCIsIEdldFgoKSk7CisgICAgbV90YWJsZS0+UHV0TnVtYmVyKCJZIiwgR2V0WSgpKTsKKyAgICBtX3RhYmxlLT5QdXROdW1iZXIoIloiLCBHZXRaKCkpOworICB9Cit9CisKK3N0ZDo6c2hhcmVkX3B0cjxJVGFibGU+IEJ1aWx0SW5BY2NlbGVyb21ldGVyOjpHZXRUYWJsZSgpIGNvbnN0IHsgcmV0dXJuIG1fdGFibGU7IH0KZGlmZiAtLWdpdCBhL3dwaWxpYmMvQXRoZW5hL3NyYy9DQU5KYWd1YXIuY3BwIGIvd3BpbGliYy9BdGhlbmEvc3JjL0NBTkphZ3Vhci5jcHAKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZmM3MWU4NAotLS0gL2Rldi9udWxsCisrKyBiL3dwaWxpYmMvQXRoZW5hL3NyYy9DQU5KYWd1YXIuY3BwCkBAIC0wLDAgKzEsMjAxMyBAQAorLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi8KKy8qIENvcHlyaWdodCAoYykgRklSU1QgMjAwOS4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICovCisvKiBPcGVuIFNvdXJjZSBTb2Z0d2FyZSAtIG1heSBiZSBtb2RpZmllZCBhbmQgc2hhcmVkIGJ5IEZSQyB0ZWFtcy4gVGhlIGNvZGUgICAqLworLyogbXVzdCBiZSBhY2NvbXBhbmllZCBieSB0aGUgRklSU1QgQlNEIGxpY2Vuc2UgZmlsZSBpbiAkKFdJTkRfQkFTRSkvV1BJTGliLiAgKi8KKy8qLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovCisKKyNpbmNsdWRlICJDQU5KYWd1YXIuaCIKKyNpbmNsdWRlICJUaW1lci5oIgorI2RlZmluZSB0TklSSU9faTMyIGludAorI2luY2x1ZGUgIk5ldHdvcmtDb21tdW5pY2F0aW9uL0NBTlNlc3Npb25NdXguaCIKKyNpbmNsdWRlICJXUElFcnJvcnMuaCIKKyNpbmNsdWRlIDxjc3RkaW8+CisjaW5jbHVkZSA8Y2Fzc2VydD4KKyNpbmNsdWRlICJMaXZlV2luZG93L0xpdmVXaW5kb3cuaCIKKworLyogd2UgYXJlIG9uIEFSTS1MRSBub3csIG5vdCBGcmVlc2NhbGUgc28gbm8gbmVlZCB0byBzd2FwICovCisjZGVmaW5lIHN3YXAxNih4KSAoeCkKKyNkZWZpbmUgc3dhcDMyKHgpICh4KQorCisvKiBDb21wYXJlIGZsb2F0cyBmb3IgZXF1YWxpdHkgYXMgZml4ZWQgcG9pbnQgbnVtYmVycyAqLworI2RlZmluZSBGWFA4X0VRKGEsIGIpICgoaW50MTZfdCkoKGEpKjI1Ni4wKSA9PSAoaW50MTZfdCkoKGIpKjI1Ni4wKSkKKyNkZWZpbmUgRlhQMTZfRVEoYSwgYikgKChpbnQzMl90KSgoYSkqNjU1MzYuMCkgPT0gKGludDMyX3QpKChiKSo2NTUzNi4wKSkKKworY29uc3QgaW50MzJfdCBDQU5KYWd1YXI6OmtDb250cm9sbGVyUmF0ZTsKK2NvbnN0ZXhwciBkb3VibGUgQ0FOSmFndWFyOjprQXBwcm94QnVzVm9sdGFnZTsKKworc3RhdGljIGNvbnN0IGludDMyX3Qga1NlbmRNZXNzYWdlUGVyaW9kID0gMjA7CitzdGF0aWMgY29uc3QgdWludDMyX3Qga0Z1bGxNZXNzYWdlSURNYXNrID0KKyAgICAoQ0FOX01TR0lEX0FQSV9NIHwgQ0FOX01TR0lEX01GUl9NIHwgQ0FOX01TR0lEX0RUWVBFX00pOworCitzdGF0aWMgY29uc3QgaW50MzJfdCBrUmVjZWl2ZVN0YXR1c0F0dGVtcHRzID0gNTA7CisKK3N0YXRpYyBzdGQ6OnVuaXF1ZV9wdHI8UmVzb3VyY2U+IGFsbG9jYXRlZDsKKworc3RhdGljIGludDMyX3Qgc2VuZE1lc3NhZ2VIZWxwZXIodWludDMyX3QgbWVzc2FnZUlELCBjb25zdCB1aW50OF90ICpkYXRhLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdWludDhfdCBkYXRhU2l6ZSwgaW50MzJfdCBwZXJpb2QpIHsKKyAgc3RhdGljIGNvbnN0IHVpbnQzMl90IGtUcnVzdGVkTWVzc2FnZXNbXSA9IHsKKyAgICAgIExNX0FQSV9WT0xUX1RfRU4sICBMTV9BUElfVk9MVF9UX1NFVCwgIExNX0FQSV9TUERfVF9FTiwgTE1fQVBJX1NQRF9UX1NFVCwKKyAgICAgIExNX0FQSV9WQ09NUF9UX0VOLCBMTV9BUElfVkNPTVBfVF9TRVQsIExNX0FQSV9QT1NfVF9FTiwgTE1fQVBJX1BPU19UX1NFVCwKKyAgICAgIExNX0FQSV9JQ1RSTF9UX0VOLCBMTV9BUElfSUNUUkxfVF9TRVR9OworCisgIGludDMyX3Qgc3RhdHVzID0gMDsKKworICBmb3IgKGF1dG8mIGtUcnVzdGVkTWVzc2FnZSA6IGtUcnVzdGVkTWVzc2FnZXMpIHsKKyAgICBpZiAoKGtGdWxsTWVzc2FnZUlETWFzayAmIG1lc3NhZ2VJRCkgPT0ga1RydXN0ZWRNZXNzYWdlKSB7CisgICAgICB1aW50OF90IGRhdGFCdWZmZXJbOF07CisgICAgICBkYXRhQnVmZmVyWzBdID0gMDsKKyAgICAgIGRhdGFCdWZmZXJbMV0gPSAwOworCisgICAgICAvLyBNYWtlIHN1cmUgdGhlIGRhdGEgd2lsbCBzdGlsbCBmaXQgYWZ0ZXIgYWRqdXN0aW5nIGZvciB0aGUgdG9rZW4uCisgICAgICBhc3NlcnQoZGF0YVNpemUgPD0gNik7CisKKyAgICAgIGZvciAodWludDhfdCBqID0gMDsgaiA8IGRhdGFTaXplOyBqKyspIHsKKyAgICAgICAgZGF0YUJ1ZmZlcltqICsgMl0gPSBkYXRhW2pdOworICAgICAgfQorCisgICAgICBGUkNfTmV0d29ya0NvbW11bmljYXRpb25fQ0FOU2Vzc2lvbk11eF9zZW5kTWVzc2FnZSgKKyAgICAgICAgICBtZXNzYWdlSUQsIGRhdGFCdWZmZXIsIGRhdGFTaXplICsgMiwgcGVyaW9kLCAmc3RhdHVzKTsKKworICAgICAgcmV0dXJuIHN0YXR1czsKKyAgICB9CisgIH0KKworICBGUkNfTmV0d29ya0NvbW11bmljYXRpb25fQ0FOU2Vzc2lvbk11eF9zZW5kTWVzc2FnZShtZXNzYWdlSUQsIGRhdGEsIGRhdGFTaXplLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwZXJpb2QsICZzdGF0dXMpOworCisgIHJldHVybiBzdGF0dXM7Cit9CisKKy8qKgorICogQ29tbW9uIGluaXRpYWxpemF0aW9uIGNvZGUgY2FsbGVkIGJ5IGFsbCBjb25zdHJ1Y3RvcnMuCisgKi8KK3ZvaWQgQ0FOSmFndWFyOjpJbml0Q0FOSmFndWFyKCkgeworICBtX3NhZmV0eUhlbHBlciA9IHN0ZDo6bWFrZV91bmlxdWU8TW90b3JTYWZldHlIZWxwZXI+KHRoaXMpOworCisgIGJvb2wgcmVjZWl2ZWRGaXJtd2FyZVZlcnNpb24gPSBmYWxzZTsKKyAgdWludDhfdCBkYXRhQnVmZmVyWzhdOworICB1aW50OF90IGRhdGFTaXplOworCisgIC8vIFJlcXVlc3QgZmlybXdhcmUgYW5kIGhhcmR3YXJlIHZlcnNpb24gb25seSBvbmNlCisgIHJlcXVlc3RNZXNzYWdlKENBTl9JU19GUkFNRV9SRU1PVEUgfCBDQU5fTVNHSURfQVBJX0ZJUk1WRVIpOworICByZXF1ZXN0TWVzc2FnZShMTV9BUElfSFdWRVIpOworCisgIC8vIFdhaXQgdW50aWwgd2UndmUgZ290dGVuIGFsbCBvZiB0aGUgc3RhdHVzIGRhdGEgYXQgbGVhc3Qgb25jZS4KKyAgZm9yIChpbnQgaSA9IDA7IGkgPCBrUmVjZWl2ZVN0YXR1c0F0dGVtcHRzOyBpKyspIHsKKyAgICBXYWl0KDAuMDAxKTsKKworICAgIHNldHVwUGVyaW9kaWNTdGF0dXMoKTsKKyAgICB1cGRhdGVQZXJpb2RpY1N0YXR1cygpOworCisgICAgaWYgKCFyZWNlaXZlZEZpcm13YXJlVmVyc2lvbiAmJgorICAgICAgICBnZXRNZXNzYWdlKENBTl9NU0dJRF9BUElfRklSTVZFUiwgQ0FOX01TR0lEX0ZVTExfTSwgZGF0YUJ1ZmZlciwKKyAgICAgICAgICAgICAgICAgICAmZGF0YVNpemUpKSB7CisgICAgICBtX2Zpcm13YXJlVmVyc2lvbiA9IHVucGFja2ludDMyX3QoZGF0YUJ1ZmZlcik7CisgICAgICByZWNlaXZlZEZpcm13YXJlVmVyc2lvbiA9IHRydWU7CisgICAgfQorCisgICAgaWYgKG1fcmVjZWl2ZWRTdGF0dXNNZXNzYWdlMCAmJiBtX3JlY2VpdmVkU3RhdHVzTWVzc2FnZTEgJiYKKyAgICAgICAgbV9yZWNlaXZlZFN0YXR1c01lc3NhZ2UyICYmIHJlY2VpdmVkRmlybXdhcmVWZXJzaW9uKSB7CisgICAgICBicmVhazsKKyAgICB9CisgIH0KKworICBpZiAoIW1fcmVjZWl2ZWRTdGF0dXNNZXNzYWdlMCB8fCAhbV9yZWNlaXZlZFN0YXR1c01lc3NhZ2UxIHx8CisgICAgICAhbV9yZWNlaXZlZFN0YXR1c01lc3NhZ2UyIHx8ICFyZWNlaXZlZEZpcm13YXJlVmVyc2lvbikgeworICAgIHdwaV9zZXRXUElFcnJvcldpdGhDb250ZXh0KEphZ3Vhck1lc3NhZ2VOb3RGb3VuZCwgIlN0YXR1cyBkYXRhIG5vdCBmb3VuZCIpOworICB9CisKKyAgaWYgKGdldE1lc3NhZ2UoTE1fQVBJX0hXVkVSLCBDQU5fTVNHSURfRlVMTF9NLCBkYXRhQnVmZmVyLCAmZGF0YVNpemUpKQorICAgIG1faGFyZHdhcmVWZXJzaW9uID0gZGF0YUJ1ZmZlclswXTsKKworICBpZiAobV9kZXZpY2VOdW1iZXIgPCAxIHx8IG1fZGV2aWNlTnVtYmVyID4gNjMpIHsKKyAgICBzdGQ6OnN0cmluZ3N0cmVhbSBidWY7CisgICAgYnVmIDw8ICJkZXZpY2UgbnVtYmVyIFwiIiA8PCBtX2RldmljZU51bWJlcgorICAgICAgICA8PCAiXCIgbXVzdCBiZSBiZXR3ZWVuIDEgYW5kIDYzIjsKKyAgICB3cGlfc2V0V1BJRXJyb3JXaXRoQ29udGV4dChQYXJhbWV0ZXJPdXRPZlJhbmdlLCBidWYuc3RyKCkpOworICAgIHJldHVybjsKKyAgfQorCisgIGlmIChTdGF0dXNJc0ZhdGFsKCkpIHJldHVybjsKKworICAvLyAzMzMwIHdhcyB0aGUgZmlyc3Qgc2hpcHBpbmcgUkRLIGZpcm13YXJlIHZlcnNpb24gZm9yIHRoZSBKYWd1YXIKKyAgaWYgKG1fZmlybXdhcmVWZXJzaW9uID49IDMzMzAgfHwgbV9maXJtd2FyZVZlcnNpb24gPCAxMDgpIHsKKyAgICBzdGQ6OnN0cmluZ3N0cmVhbSBidWY7CisgICAgaWYgKG1fZmlybXdhcmVWZXJzaW9uIDwgMzMzMCkgeworICAgICAgYnVmIDw8ICJKYWcgIyIgPDwgbV9kZXZpY2VOdW1iZXIgPDwgIiBmaXJtd2FyZSAoIiA8PCBtX2Zpcm13YXJlVmVyc2lvbgorICAgICAgICAgIDw8ICIpIGlzIHRvbyBvbGQgKG11c3QgYmUgYXQgbGVhc3QgdmVyc2lvbiAxMDggIgorICAgICAgICAgICAgICJvZiB0aGUgRklSU1QgYXBwcm92ZWQgZmlybXdhcmUpIjsKKyAgICB9IGVsc2UgeworICAgICAgYnVmIDw8ICJKYWcgIyIgPDwgbV9kZXZpY2VOdW1iZXIgPDwgIiBmaXJtd2FyZSAoIiA8PCBtX2Zpcm13YXJlVmVyc2lvbgorICAgICAgICAgIDw8ICIpIGlzIG5vdCBGSVJTVCBhcHByb3ZlZCAobXVzdCBiZSBhdCBsZWFzdCAiCisgICAgICAgICAgICAgInZlcnNpb24gMTA4IG9mIHRoZSBGSVJTVCBhcHByb3ZlZCBmaXJtd2FyZSkiOworICAgIH0KKyAgICB3cGlfc2V0V1BJRXJyb3JXaXRoQ29udGV4dChKYWd1YXJWZXJzaW9uRXJyb3IsIGJ1Zi5zdHIoKSk7CisgICAgcmV0dXJuOworICB9CisKKyAgc3dpdGNoIChtX2NvbnRyb2xNb2RlKSB7CisgICAgY2FzZSBrUGVyY2VudFZidXM6CisgICAgY2FzZSBrVm9sdGFnZToKKyAgICAgIC8vIE5vIGFkZGl0aW9uYWwgY29uZmlndXJhdGlvbiByZXF1aXJlZC4uLiBzdGFydCBlbmFibGVkLgorICAgICAgRW5hYmxlQ29udHJvbCgpOworICAgICAgYnJlYWs7CisgICAgZGVmYXVsdDoKKyAgICAgIGJyZWFrOworICB9CisgIEhBTFJlcG9ydChIQUxVc2FnZVJlcG9ydGluZzo6a1Jlc291cmNlVHlwZV9DQU5KYWd1YXIsIG1fZGV2aWNlTnVtYmVyLAorICAgICAgICAgICAgbV9jb250cm9sTW9kZSk7CisgIExpdmVXaW5kb3c6OkdldEluc3RhbmNlKCktPkFkZEFjdHVhdG9yKCJDQU5KYWd1YXIiLCBtX2RldmljZU51bWJlciwgdGhpcyk7Cit9CisKKy8qKgorICogQ29uc3RydWN0b3IgZm9yIHRoZSBDQU5KYWd1YXIgZGV2aWNlLjxicj4KKyAqIEJ5IGRlZmF1bHQgdGhlIGRldmljZSBpcyBjb25maWd1cmVkIGluIFBlcmNlbnQgbW9kZS4KKyAqIFRoZSBjb250cm9sIG1vZGUgY2FuIGJlIGNoYW5nZWQgYnkgY2FsbGluZyBvbmUgb2YgdGhlIGNvbnRyb2wgbW9kZXMgbGlzdGVkCisgKiBiZWxvdy4KKyAqCisgKiBAcGFyYW0gZGV2aWNlTnVtYmVyIFRoZSBhZGRyZXNzIG9mIHRoZSBKYWd1YXIgb24gdGhlIENBTiBidXMuCisgKiBAc2VlIENBTkphZ3VhciNTZXRDdXJyZW50TW9kZShkb3VibGUsIGRvdWJsZSwgZG91YmxlKQorICogQHNlZSBDQU5KYWd1YXIjU2V0Q3VycmVudE1vZGUoUG90ZW50aW9tZXRlclRhZywgZG91YmxlLCBkb3VibGUsIGRvdWJsZSkKKyAqIEBzZWUgQ0FOSmFndWFyI1NldEN1cnJlbnRNb2RlKEVuY29kZXJUYWcsIGludCwgZG91YmxlLCBkb3VibGUsIGRvdWJsZSkKKyAqIEBzZWUgQ0FOSmFndWFyI1NldEN1cnJlbnRNb2RlKFF1YWRFbmNvZGVyVGFnLCBpbnQsIGRvdWJsZSwgZG91YmxlLCBkb3VibGUpCisgKiBAc2VlIENBTkphZ3VhciNTZXRQZXJjZW50TW9kZSgpCisgKiBAc2VlIENBTkphZ3VhciNTZXRQZXJjZW50TW9kZShQb3RlbnRpb21ldGVyVGFnKQorICogQHNlZSBDQU5KYWd1YXIjU2V0UGVyY2VudE1vZGUoRW5jb2RlclRhZywgaW50KQorICogQHNlZSBDQU5KYWd1YXIjU2V0UGVyY2VudE1vZGUoUXVhZEVuY29kZXJUYWcsIGludCkKKyAqIEBzZWUgQ0FOSmFndWFyI1NldFBvc2l0aW9uTW9kZShQb3RlbnRpb21ldGVyVGFnLCBkb3VibGUsIGRvdWJsZSwgZG91YmxlKQorICogQHNlZSBDQU5KYWd1YXIjU2V0UG9zaXRpb25Nb2RlKFF1YWRFbmNvZGVyVGFnLCBpbnQsIGRvdWJsZSwgZG91YmxlLCBkb3VibGUpCisgKiBAc2VlIENBTkphZ3VhciNTZXRTcGVlZE1vZGUoRW5jb2RlclRhZywgaW50LCBkb3VibGUsIGRvdWJsZSwgZG91YmxlKQorICogQHNlZSBDQU5KYWd1YXIjU2V0U3BlZWRNb2RlKFF1YWRFbmNvZGVyVGFnLCBpbnQsIGRvdWJsZSwgZG91YmxlLCBkb3VibGUpCisgKiBAc2VlIENBTkphZ3VhciNTZXRWb2x0YWdlTW9kZSgpCisgKiBAc2VlIENBTkphZ3VhciNTZXRWb2x0YWdlTW9kZShQb3RlbnRpb21ldGVyVGFnKQorICogQHNlZSBDQU5KYWd1YXIjU2V0Vm9sdGFnZU1vZGUoRW5jb2RlclRhZywgaW50KQorICogQHNlZSBDQU5KYWd1YXIjU2V0Vm9sdGFnZU1vZGUoUXVhZEVuY29kZXJUYWcsIGludCkKKyAqLworQ0FOSmFndWFyOjpDQU5KYWd1YXIodWludDhfdCBkZXZpY2VOdW1iZXIpCisgICAgOiBtX2RldmljZU51bWJlcihkZXZpY2VOdW1iZXIpIHsKKyAgc3RkOjpzdHJpbmdzdHJlYW0gYnVmOworICBidWYgPDwgIkNBTkphZ3VhciBkZXZpY2UgbnVtYmVyICIgPDwgbV9kZXZpY2VOdW1iZXI7CisgIFJlc291cmNlOjpDcmVhdGVSZXNvdXJjZU9iamVjdChhbGxvY2F0ZWQsIDYzKTsKKworICBpZiAoYWxsb2NhdGVkLT5BbGxvY2F0ZShtX2RldmljZU51bWJlciAtIDEsIGJ1Zi5zdHIoKSkgPT0KKyAgICAgIHN0ZDo6bnVtZXJpY19saW1pdHM8dWludDMyX3Q+OjptYXgoKSkgeworICAgIENsb25lRXJyb3IoKmFsbG9jYXRlZCk7CisgICAgcmV0dXJuOworICB9CisKKyAgU2V0UGVyY2VudE1vZGUoKTsKKyAgSW5pdENBTkphZ3VhcigpOworICBDb25maWdNYXhPdXRwdXRWb2x0YWdlKGtBcHByb3hCdXNWb2x0YWdlKTsKK30KKworQ0FOSmFndWFyOjp+Q0FOSmFndWFyKCkgeworICBhbGxvY2F0ZWQtPkZyZWUobV9kZXZpY2VOdW1iZXIgLSAxKTsKKworICBpbnQzMl90IHN0YXR1czsKKworICAvLyBEaXNhYmxlIHBlcmlvZGljIHNldHBvaW50cworICBpZiAobV9jb250cm9sTW9kZSA9PSBrUGVyY2VudFZidXMpCisgICAgRlJDX05ldHdvcmtDb21tdW5pY2F0aW9uX0NBTlNlc3Npb25NdXhfc2VuZE1lc3NhZ2UoCisgICAgICAgIG1fZGV2aWNlTnVtYmVyIHwgTE1fQVBJX1ZPTFRfVF9TRVQsIG51bGxwdHIsIDAsCisgICAgICAgIENBTl9TRU5EX1BFUklPRF9TVE9QX1JFUEVBVElORywgJnN0YXR1cyk7CisgIGVsc2UgaWYgKG1fY29udHJvbE1vZGUgPT0ga1NwZWVkKQorICAgIEZSQ19OZXR3b3JrQ29tbXVuaWNhdGlvbl9DQU5TZXNzaW9uTXV4X3NlbmRNZXNzYWdlKAorICAgICAgICBtX2RldmljZU51bWJlciB8IExNX0FQSV9TUERfVF9TRVQsIG51bGxwdHIsIDAsCisgICAgICAgIENBTl9TRU5EX1BFUklPRF9TVE9QX1JFUEVBVElORywgJnN0YXR1cyk7CisgIGVsc2UgaWYgKG1fY29udHJvbE1vZGUgPT0ga1Bvc2l0aW9uKQorICAgIEZSQ19OZXR3b3JrQ29tbXVuaWNhdGlvbl9DQU5TZXNzaW9uTXV4X3NlbmRNZXNzYWdlKAorICAgICAgICBtX2RldmljZU51bWJlciB8IExNX0FQSV9QT1NfVF9TRVQsIG51bGxwdHIsIDAsCisgICAgICAgIENBTl9TRU5EX1BFUklPRF9TVE9QX1JFUEVBVElORywgJnN0YXR1cyk7CisgIGVsc2UgaWYgKG1fY29udHJvbE1vZGUgPT0ga0N1cnJlbnQpCisgICAgRlJDX05ldHdvcmtDb21tdW5pY2F0aW9uX0NBTlNlc3Npb25NdXhfc2VuZE1lc3NhZ2UoCisgICAgICAgIG1fZGV2aWNlTnVtYmVyIHwgTE1fQVBJX0lDVFJMX1RfU0VULCBudWxscHRyLCAwLAorICAgICAgICBDQU5fU0VORF9QRVJJT0RfU1RPUF9SRVBFQVRJTkcsICZzdGF0dXMpOworICBlbHNlIGlmIChtX2NvbnRyb2xNb2RlID09IGtWb2x0YWdlKQorICAgIEZSQ19OZXR3b3JrQ29tbXVuaWNhdGlvbl9DQU5TZXNzaW9uTXV4X3NlbmRNZXNzYWdlKAorICAgICAgICBtX2RldmljZU51bWJlciB8IExNX0FQSV9WQ09NUF9UX1NFVCwgbnVsbHB0ciwgMCwKKyAgICAgICAgQ0FOX1NFTkRfUEVSSU9EX1NUT1BfUkVQRUFUSU5HLCAmc3RhdHVzKTsKKworICBpZiAobV90YWJsZSAhPSBudWxscHRyKSBtX3RhYmxlLT5SZW1vdmVUYWJsZUxpc3RlbmVyKHRoaXMpOworfQorCisvKioKKyAqIEByZXR1cm4gVGhlIENBTiBJRCBwYXNzZWQgaW4gdGhlIGNvbnN0cnVjdG9yCisgKi8KK3VpbnQ4X3QgQ0FOSmFndWFyOjpnZXREZXZpY2VOdW1iZXIoKSBjb25zdCB7IHJldHVybiBtX2RldmljZU51bWJlcjsgfQorCisvKioKKyAqIFNldHMgdGhlIG91dHB1dCBzZXQtcG9pbnQgdmFsdWUuCisgKgorICogVGhlIHNjYWxlIGFuZCB0aGUgdW5pdHMgZGVwZW5kIG9uIHRoZSBtb2RlIHRoZSBKYWd1YXIgaXMgaW4uPGJyPgorICogSW4gcGVyY2VudFZidXMgTW9kZSwgdGhlIG91dHB1dFZhbHVlIGlzIGZyb20gLTEuMCB0byAxLjAgKHNhbWUgYXMgUFdNCisgKiBKYWd1YXIpLjxicj4KKyAqIEluIHZvbHRhZ2UgTW9kZSwgdGhlIG91dHB1dFZhbHVlIGlzIGluIHZvbHRzLiA8YnI+CisgKiBJbiBjdXJyZW50IE1vZGUsIHRoZSBvdXRwdXRWYWx1ZSBpcyBpbiBhbXBzLiA8YnI+CisgKiBJbiBzcGVlZCBNb2RlLCB0aGUgb3V0cHV0VmFsdWUgaXMgaW4gcm90YXRpb25zL21pbnV0ZS48YnI+CisgKiBJbiBwb3NpdGlvbiBNb2RlLCB0aGUgb3V0cHV0VmFsdWUgaXMgaW4gcm90YXRpb25zLgorICoKKyAqIEBwYXJhbSBvdXRwdXRWYWx1ZSBUaGUgc2V0LXBvaW50IHRvIHNlbnQgdG8gdGhlIG1vdG9yIGNvbnRyb2xsZXIuCisgKiBAcGFyYW0gc3luY0dyb3VwIFRoZSB1cGRhdGUgZ3JvdXAgdG8gYWRkIHRoaXMgU2V0KCkgdG8sIHBlbmRpbmcKKyAqIFVwZGF0ZVN5bmNHcm91cCgpLiAgSWYgMCwgdXBkYXRlIGltbWVkaWF0ZWx5LgorICovCit2b2lkIENBTkphZ3Vhcjo6U2V0KGZsb2F0IG91dHB1dFZhbHVlLCB1aW50OF90IHN5bmNHcm91cCkgeworICB1aW50MzJfdCBtZXNzYWdlSUQ7CisgIHVpbnQ4X3QgZGF0YUJ1ZmZlcls4XTsKKyAgdWludDhfdCBkYXRhU2l6ZTsKKworICBpZiAobV9zYWZldHlIZWxwZXIgJiYgIW1fc2FmZXR5SGVscGVyLT5Jc0FsaXZlKCkgJiYgbV9jb250cm9sRW5hYmxlZCkgeworICAgIEVuYWJsZUNvbnRyb2woKTsKKyAgfQorCisgIGlmIChtX2NvbnRyb2xFbmFibGVkKSB7CisgICAgc3dpdGNoIChtX2NvbnRyb2xNb2RlKSB7CisgICAgICBjYXNlIGtQZXJjZW50VmJ1czogeworICAgICAgICBtZXNzYWdlSUQgPSBMTV9BUElfVk9MVF9UX1NFVDsKKyAgICAgICAgaWYgKG91dHB1dFZhbHVlID4gMS4wKSBvdXRwdXRWYWx1ZSA9IDEuMDsKKyAgICAgICAgaWYgKG91dHB1dFZhbHVlIDwgLTEuMCkgb3V0cHV0VmFsdWUgPSAtMS4wOworICAgICAgICBkYXRhU2l6ZSA9IHBhY2tQZXJjZW50YWdlKGRhdGFCdWZmZXIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKG1faXNJbnZlcnRlZCA/IC1vdXRwdXRWYWx1ZSA6IG91dHB1dFZhbHVlKSk7CisgICAgICB9IGJyZWFrOworICAgICAgY2FzZSBrU3BlZWQ6IHsKKyAgICAgICAgbWVzc2FnZUlEID0gTE1fQVBJX1NQRF9UX1NFVDsKKyAgICAgICAgZGF0YVNpemUgPSBwYWNrRlhQMTZfMTYoZGF0YUJ1ZmZlciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKG1faXNJbnZlcnRlZCA/IC1vdXRwdXRWYWx1ZSA6IG91dHB1dFZhbHVlKSk7CisgICAgICB9IGJyZWFrOworICAgICAgY2FzZSBrUG9zaXRpb246IHsKKyAgICAgICAgbWVzc2FnZUlEID0gTE1fQVBJX1BPU19UX1NFVDsKKyAgICAgICAgZGF0YVNpemUgPSBwYWNrRlhQMTZfMTYoZGF0YUJ1ZmZlciwgb3V0cHV0VmFsdWUpOworICAgICAgfSBicmVhazsKKyAgICAgIGNhc2Uga0N1cnJlbnQ6IHsKKyAgICAgICAgbWVzc2FnZUlEID0gTE1fQVBJX0lDVFJMX1RfU0VUOworICAgICAgICBkYXRhU2l6ZSA9IHBhY2tGWFA4XzgoZGF0YUJ1ZmZlciwgb3V0cHV0VmFsdWUpOworICAgICAgfSBicmVhazsKKyAgICAgIGNhc2Uga1ZvbHRhZ2U6IHsKKyAgICAgICAgbWVzc2FnZUlEID0gTE1fQVBJX1ZDT01QX1RfU0VUOworICAgICAgICBkYXRhU2l6ZSA9CisgICAgICAgICAgICBwYWNrRlhQOF84KGRhdGFCdWZmZXIsIChtX2lzSW52ZXJ0ZWQgPyAtb3V0cHV0VmFsdWUgOiBvdXRwdXRWYWx1ZSkpOworICAgICAgfSBicmVhazsKKyAgICAgIGRlZmF1bHQ6CisgICAgICAgIHdwaV9zZXRXUElFcnJvcldpdGhDb250ZXh0KEluY29tcGF0aWJsZU1vZGUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJUaGUgSmFndWFyIG9ubHkgc3VwcG9ydHMgQ3VycmVudCwgVm9sdGFnZSwgIgorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiUG9zaXRpb24sIFNwZWVkLCBhbmQgUGVyY2VudCAoVGhyb3R0bGUpICIKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIm1vZGVzLiIpOworICAgICAgICByZXR1cm47CisgICAgfQorICAgIGlmIChzeW5jR3JvdXAgIT0gMCkgeworICAgICAgZGF0YUJ1ZmZlcltkYXRhU2l6ZV0gPSBzeW5jR3JvdXA7CisgICAgICBkYXRhU2l6ZSsrOworICAgIH0KKworICAgIHNlbmRNZXNzYWdlKG1lc3NhZ2VJRCwgZGF0YUJ1ZmZlciwgZGF0YVNpemUsIGtTZW5kTWVzc2FnZVBlcmlvZCk7CisKKyAgICBpZiAobV9zYWZldHlIZWxwZXIpIG1fc2FmZXR5SGVscGVyLT5GZWVkKCk7CisgIH0KKworICBtX3ZhbHVlID0gb3V0cHV0VmFsdWU7CisKKyAgdmVyaWZ5KCk7Cit9CisKKy8qKgorICogR2V0IHRoZSByZWNlbnRseSBzZXQgb3V0cHV0VmFsdWUgc2V0cG9pbnQuCisgKgorICogVGhlIHNjYWxlIGFuZCB0aGUgdW5pdHMgZGVwZW5kIG9uIHRoZSBtb2RlIHRoZSBKYWd1YXIgaXMgaW4uPGJyPgorICogSW4gcGVyY2VudFZidXMgTW9kZSwgdGhlIG91dHB1dFZhbHVlIGlzIGZyb20gLTEuMCB0byAxLjAgKHNhbWUgYXMgUFdNCisgKiBKYWd1YXIpLjxicj4KKyAqIEluIHZvbHRhZ2UgTW9kZSwgdGhlIG91dHB1dFZhbHVlIGlzIGluIHZvbHRzLjxicj4KKyAqIEluIGN1cnJlbnQgTW9kZSwgdGhlIG91dHB1dFZhbHVlIGlzIGluIGFtcHMuPGJyPgorICogSW4gc3BlZWQgTW9kZSwgdGhlIG91dHB1dFZhbHVlIGlzIGluIHJvdGF0aW9ucy9taW51dGUuPGJyPgorICogSW4gcG9zaXRpb24gTW9kZSwgdGhlIG91dHB1dFZhbHVlIGlzIGluIHJvdGF0aW9ucy48YnI+CisgKgorICogQHJldHVybiBUaGUgbW9zdCByZWNlbnRseSBzZXQgb3V0cHV0VmFsdWUgc2V0cG9pbnQuCisgKi8KK2Zsb2F0IENBTkphZ3Vhcjo6R2V0KCkgY29uc3QgeyByZXR1cm4gbV92YWx1ZTsgfQorCisvKioKKyogQ29tbW9uIGludGVyZmFjZSBmb3IgZGlzYWJsaW5nIGEgbW90b3IuCisqCisqIEBkZXByZWNhdGVkIENhbGwge0BsaW5rICNEaXNhYmxlQ29udHJvbCgpfSBpbnN0ZWFkLgorKi8KK3ZvaWQgQ0FOSmFndWFyOjpEaXNhYmxlKCkgeyBEaXNhYmxlQ29udHJvbCgpOyB9CisKKy8qKgorICogV3JpdGUgb3V0IHRoZSBQSUQgdmFsdWUgYXMgc2VlbiBpbiB0aGUgUElET3V0cHV0IGJhc2Ugb2JqZWN0LgorICoKKyAqIEBkZXByZWNhdGVkIENhbGwgU2V0IGluc3RlYWQuCisgKgorICogQHBhcmFtIG91dHB1dCBXcml0ZSBvdXQgdGhlIFBlcmNlbnRWYnVzIHZhbHVlIGFzIHdhcyBjb21wdXRlZCBieSB0aGUKKyAqIFBJRENvbnRyb2xsZXIKKyAqLwordm9pZCBDQU5KYWd1YXI6OlBJRFdyaXRlKGZsb2F0IG91dHB1dCkgeworICBpZiAobV9jb250cm9sTW9kZSA9PSBrUGVyY2VudFZidXMpIHsKKyAgICBTZXQob3V0cHV0KTsKKyAgfSBlbHNlIHsKKyAgICB3cGlfc2V0V1BJRXJyb3JXaXRoQ29udGV4dChJbmNvbXBhdGlibGVNb2RlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJQSUQgb25seSBzdXBwb3J0ZWQgaW4gUGVyY2VudFZidXMgbW9kZSIpOworICB9Cit9CisKK3VpbnQ4X3QgQ0FOSmFndWFyOjpwYWNrUGVyY2VudGFnZSh1aW50OF90ICpidWZmZXIsIGRvdWJsZSB2YWx1ZSkgeworICBpbnQxNl90IGludFZhbHVlID0gKGludDE2X3QpKHZhbHVlICogMzI3NjcuMCk7CisgICooKGludDE2X3QgKilidWZmZXIpID0gc3dhcDE2KGludFZhbHVlKTsKKyAgcmV0dXJuIHNpemVvZihpbnQxNl90KTsKK30KKwordWludDhfdCBDQU5KYWd1YXI6OnBhY2tGWFA4XzgodWludDhfdCAqYnVmZmVyLCBkb3VibGUgdmFsdWUpIHsKKyAgaW50MTZfdCBpbnRWYWx1ZSA9IChpbnQxNl90KSh2YWx1ZSAqIDI1Ni4wKTsKKyAgKigoaW50MTZfdCAqKWJ1ZmZlcikgPSBzd2FwMTYoaW50VmFsdWUpOworICByZXR1cm4gc2l6ZW9mKGludDE2X3QpOworfQorCit1aW50OF90IENBTkphZ3Vhcjo6cGFja0ZYUDE2XzE2KHVpbnQ4X3QgKmJ1ZmZlciwgZG91YmxlIHZhbHVlKSB7CisgIGludDMyX3QgaW50VmFsdWUgPSAoaW50MzJfdCkodmFsdWUgKiA2NTUzNi4wKTsKKyAgKigoaW50MzJfdCAqKWJ1ZmZlcikgPSBzd2FwMzIoaW50VmFsdWUpOworICByZXR1cm4gc2l6ZW9mKGludDMyX3QpOworfQorCit1aW50OF90IENBTkphZ3Vhcjo6cGFja2ludDE2X3QodWludDhfdCAqYnVmZmVyLCBpbnQxNl90IHZhbHVlKSB7CisgICooKGludDE2X3QgKilidWZmZXIpID0gc3dhcDE2KHZhbHVlKTsKKyAgcmV0dXJuIHNpemVvZihpbnQxNl90KTsKK30KKwordWludDhfdCBDQU5KYWd1YXI6OnBhY2tpbnQzMl90KHVpbnQ4X3QgKmJ1ZmZlciwgaW50MzJfdCB2YWx1ZSkgeworICAqKChpbnQzMl90ICopYnVmZmVyKSA9IHN3YXAzMih2YWx1ZSk7CisgIHJldHVybiBzaXplb2YoaW50MzJfdCk7Cit9CisKK2RvdWJsZSBDQU5KYWd1YXI6OnVucGFja1BlcmNlbnRhZ2UodWludDhfdCAqYnVmZmVyKSBjb25zdCB7CisgIGludDE2X3QgdmFsdWUgPSAqKChpbnQxNl90ICopYnVmZmVyKTsKKyAgdmFsdWUgPSBzd2FwMTYodmFsdWUpOworICByZXR1cm4gdmFsdWUgLyAzMjc2Ny4wOworfQorCitkb3VibGUgQ0FOSmFndWFyOjp1bnBhY2tGWFA4XzgodWludDhfdCAqYnVmZmVyKSBjb25zdCB7CisgIGludDE2X3QgdmFsdWUgPSAqKChpbnQxNl90ICopYnVmZmVyKTsKKyAgdmFsdWUgPSBzd2FwMTYodmFsdWUpOworICByZXR1cm4gdmFsdWUgLyAyNTYuMDsKK30KKworZG91YmxlIENBTkphZ3Vhcjo6dW5wYWNrRlhQMTZfMTYodWludDhfdCAqYnVmZmVyKSBjb25zdCB7CisgIGludDMyX3QgdmFsdWUgPSAqKChpbnQzMl90ICopYnVmZmVyKTsKKyAgdmFsdWUgPSBzd2FwMzIodmFsdWUpOworICByZXR1cm4gdmFsdWUgLyA2NTUzNi4wOworfQorCitpbnQxNl90IENBTkphZ3Vhcjo6dW5wYWNraW50MTZfdCh1aW50OF90ICpidWZmZXIpIGNvbnN0IHsKKyAgaW50MTZfdCB2YWx1ZSA9ICooKGludDE2X3QgKilidWZmZXIpOworICByZXR1cm4gc3dhcDE2KHZhbHVlKTsKK30KKworaW50MzJfdCBDQU5KYWd1YXI6OnVucGFja2ludDMyX3QodWludDhfdCAqYnVmZmVyKSBjb25zdCB7CisgIGludDMyX3QgdmFsdWUgPSAqKChpbnQzMl90ICopYnVmZmVyKTsKKyAgcmV0dXJuIHN3YXAzMih2YWx1ZSk7Cit9CisKKy8qKgorICogU2VuZCBhIG1lc3NhZ2UgdG8gdGhlIEphZ3Vhci4KKyAqCisgKiBAcGFyYW0gbWVzc2FnZUlEIFRoZSBtZXNzYWdlSUQgdG8gYmUgdXNlZCBvbiB0aGUgQ0FOIGJ1cyAoZGV2aWNlIG51bWJlciBpcworICogYWRkZWQgaW50ZXJuYWxseSkKKyAqIEBwYXJhbSBkYXRhIFRoZSB1cCB0byA4IGJ5dGVzIG9mIGRhdGEgdG8gYmUgc2VudCB3aXRoIHRoZSBtZXNzYWdlCisgKiBAcGFyYW0gZGF0YVNpemUgU3BlY2lmeSBob3cgbXVjaCBvZiB0aGUgZGF0YSBpbiAiZGF0YSIgdG8gc2VuZAorICogQHBhcmFtIHBlcmlvZGljIElmIHBvc2l0aXZlLCB0ZWxsIE5ldHdvcmsgQ29tbXVuaWNhdGlvbnMgdG8gc2VuZCB0aGUgbWVzc2FnZQorICogCWV2ZXJ5ICJwZXJpb2QiIG1pbGxpc2Vjb25kcy4KKyAqLwordm9pZCBDQU5KYWd1YXI6OnNlbmRNZXNzYWdlKHVpbnQzMl90IG1lc3NhZ2VJRCwgY29uc3QgdWludDhfdCAqZGF0YSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICB1aW50OF90IGRhdGFTaXplLCBpbnQzMl90IHBlcmlvZCkgeworICBpbnQzMl90IGxvY2FsU3RhdHVzID0KKyAgICAgIHNlbmRNZXNzYWdlSGVscGVyKG1lc3NhZ2VJRCB8IG1fZGV2aWNlTnVtYmVyLCBkYXRhLCBkYXRhU2l6ZSwgcGVyaW9kKTsKKworICBpZiAobG9jYWxTdGF0dXMgPCAwKSB7CisgICAgd3BpX3NldEVycm9yV2l0aENvbnRleHQobG9jYWxTdGF0dXMsICJzZW5kTWVzc2FnZSIpOworICB9Cit9CisKKy8qKgorICogUmVxdWVzdCBhIG1lc3NhZ2UgZnJvbSB0aGUgSmFndWFyLCBidXQgZG9uJ3Qgd2FpdCBmb3IgaXQgdG8gYXJyaXZlLgorICoKKyAqIEBwYXJhbSBtZXNzYWdlSUQgVGhlIG1lc3NhZ2UgdG8gcmVxdWVzdAorICogQHBhcmFtIHBlcmlvZGljIElmIHBvc2l0aXZlLCB0ZWxsIE5ldHdvcmsgQ29tbXVuaWNhdGlvbnMgdG8gc2VuZCB0aGUgbWVzc2FnZQorICogCWV2ZXJ5ICJwZXJpb2QiIG1pbGxpc2Vjb25kcy4KKyAqLwordm9pZCBDQU5KYWd1YXI6OnJlcXVlc3RNZXNzYWdlKHVpbnQzMl90IG1lc3NhZ2VJRCwgaW50MzJfdCBwZXJpb2QpIHsKKyAgc2VuZE1lc3NhZ2VIZWxwZXIobWVzc2FnZUlEIHwgbV9kZXZpY2VOdW1iZXIsIG51bGxwdHIsIDAsIHBlcmlvZCk7Cit9CisKKy8qKgorICogR2V0IGEgcHJldmlvdXNseSByZXF1ZXN0ZWQgbWVzc2FnZS4KKyAqCisgKiBKYWd1YXIgYWx3YXlzIGdlbmVyYXRlcyBhIG1lc3NhZ2Ugd2l0aCB0aGUgc2FtZSBtZXNzYWdlIElEIHdoZW4gcmVwbHlpbmcuCisgKgorICogQHBhcmFtIG1lc3NhZ2VJRCBUaGUgbWVzc2FnZUlEIHRvIHJlYWQgZnJvbSB0aGUgQ0FOIGJ1cyAoZGV2aWNlIG51bWJlciBpcworICogYWRkZWQgaW50ZXJuYWxseSkKKyAqIEBwYXJhbSBkYXRhIFRoZSB1cCB0byA4IGJ5dGVzIG9mIGRhdGEgdGhhdCB3YXMgcmVjZWl2ZWQgd2l0aCB0aGUgbWVzc2FnZQorICogQHBhcmFtIGRhdGFTaXplIEluZGljYXRlcyBob3cgbXVjaCBkYXRhIHdhcyByZWNlaXZlZAorICoKKyAqIEByZXR1cm4gdHJ1ZSBpZiB0aGUgbWVzc2FnZSB3YXMgZm91bmQuICBPdGhlcndpc2UsIG5vIG5ldyBtZXNzYWdlIGlzCisgKiBhdmFpbGFibGUuCisgKi8KK2Jvb2wgQ0FOSmFndWFyOjpnZXRNZXNzYWdlKHVpbnQzMl90IG1lc3NhZ2VJRCwgdWludDMyX3QgbWVzc2FnZU1hc2ssCisgICAgICAgICAgICAgICAgICAgICAgICAgICB1aW50OF90ICpkYXRhLCB1aW50OF90ICpkYXRhU2l6ZSkgY29uc3QgeworICB1aW50MzJfdCB0YXJnZXRlZE1lc3NhZ2VJRCA9IG1lc3NhZ2VJRCB8IG1fZGV2aWNlTnVtYmVyOworICBpbnQzMl90IHN0YXR1cyA9IDA7CisgIHVpbnQzMl90IHRpbWVTdGFtcDsKKworICAvLyBDYWxsZXIgbWF5IGhhdmUgc2V0IGJpdDMxIGZvciByZW1vdGUgZnJhbWUgdHJhbnNtaXNzaW9uIHNvIGNsZWFyIGludmFsaWQKKyAgLy8gYml0c1szMS0yOV0KKyAgdGFyZ2V0ZWRNZXNzYWdlSUQgJj0gQ0FOX01TR0lEX0ZVTExfTTsKKworICAvLyBHZXQgdGhlIGRhdGEuCisgIEZSQ19OZXR3b3JrQ29tbXVuaWNhdGlvbl9DQU5TZXNzaW9uTXV4X3JlY2VpdmVNZXNzYWdlKAorICAgICAgJnRhcmdldGVkTWVzc2FnZUlELCBtZXNzYWdlTWFzaywgZGF0YSwgZGF0YVNpemUsICZ0aW1lU3RhbXAsICZzdGF0dXMpOworCisgIC8vIERvIHdlIGFscmVhZHkgaGF2ZSB0aGUgbW9zdCByZWNlbnQgdmFsdWU/CisgIGlmIChzdGF0dXMgPT0gRVJSX0NBTlNlc3Npb25NdXhfTWVzc2FnZU5vdEZvdW5kKQorICAgIHJldHVybiBmYWxzZTsKKyAgZWxzZQorICAgIHdwaV9zZXRFcnJvcldpdGhDb250ZXh0KHN0YXR1cywgInJlY2VpdmVNZXNzYWdlIik7CisKKyAgcmV0dXJuIHRydWU7Cit9CisKKy8qKgorICogRW5hYmxlcyBwZXJpb2RpYyBzdGF0dXMgdXBkYXRlcyBmcm9tIHRoZSBKYWd1YXIuCisgKi8KK3ZvaWQgQ0FOSmFndWFyOjpzZXR1cFBlcmlvZGljU3RhdHVzKCkgeworICB1aW50OF90IGRhdGFbOF07CisgIHVpbnQ4X3QgZGF0YVNpemU7CisKKyAgLy8gTWVzc2FnZSAwIHJldHVybnMgYnVzIHZvbHRhZ2UsIG91dHB1dCB2b2x0YWdlLCBvdXRwdXQgY3VycmVudCwgYW5kCisgIC8vIHRlbXBlcmF0dXJlLgorICBzdGF0aWMgY29uc3QgdWludDhfdCBrTWVzc2FnZTBEYXRhW10gPSB7CisgICAgICBMTV9QU1RBVF9WT0xUQlVTX0IwLCBMTV9QU1RBVF9WT0xUQlVTX0IxLCBMTV9QU1RBVF9WT0xUT1VUX0IwLAorICAgICAgTE1fUFNUQVRfVk9MVE9VVF9CMSwgTE1fUFNUQVRfQ1VSUkVOVF9CMCwgTE1fUFNUQVRfQ1VSUkVOVF9CMSwKKyAgICAgIExNX1BTVEFUX1RFTVBfQjAsICAgIExNX1BTVEFUX1RFTVBfQjF9OworCisgIC8vIE1lc3NhZ2UgMSByZXR1cm5zIHBvc2l0aW9uIGFuZCBzcGVlZAorICBzdGF0aWMgY29uc3QgdWludDhfdCBrTWVzc2FnZTFEYXRhW10gPSB7CisgICAgICBMTV9QU1RBVF9QT1NfQjAsIExNX1BTVEFUX1BPU19CMSwgTE1fUFNUQVRfUE9TX0IyLCBMTV9QU1RBVF9QT1NfQjMsCisgICAgICBMTV9QU1RBVF9TUERfQjAsIExNX1BTVEFUX1NQRF9CMSwgTE1fUFNUQVRfU1BEX0IyLCBMTV9QU1RBVF9TUERfQjN9OworCisgIC8vIE1lc3NhZ2UgMiByZXR1cm5zIGxpbWl0cyBhbmQgZmF1bHRzCisgIHN0YXRpYyBjb25zdCB1aW50OF90IGtNZXNzYWdlMkRhdGFbXSA9IHtMTV9QU1RBVF9MSU1JVF9DTFIsIExNX1BTVEFUX0ZBVUxULAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTE1fUFNUQVRfRU5EfTsKKworICBkYXRhU2l6ZSA9IHBhY2tpbnQxNl90KGRhdGEsIGtTZW5kTWVzc2FnZVBlcmlvZCk7CisgIHNlbmRNZXNzYWdlKExNX0FQSV9QU1RBVF9QRVJfRU5fUzAsIGRhdGEsIGRhdGFTaXplKTsKKyAgc2VuZE1lc3NhZ2UoTE1fQVBJX1BTVEFUX1BFUl9FTl9TMSwgZGF0YSwgZGF0YVNpemUpOworICBzZW5kTWVzc2FnZShMTV9BUElfUFNUQVRfUEVSX0VOX1MyLCBkYXRhLCBkYXRhU2l6ZSk7CisKKyAgZGF0YVNpemUgPSA4OworICBzZW5kTWVzc2FnZShMTV9BUElfUFNUQVRfQ0ZHX1MwLCBrTWVzc2FnZTBEYXRhLCBkYXRhU2l6ZSk7CisgIHNlbmRNZXNzYWdlKExNX0FQSV9QU1RBVF9DRkdfUzEsIGtNZXNzYWdlMURhdGEsIGRhdGFTaXplKTsKKyAgc2VuZE1lc3NhZ2UoTE1fQVBJX1BTVEFUX0NGR19TMiwga01lc3NhZ2UyRGF0YSwgZGF0YVNpemUpOworfQorCisvKioKKyAqIENoZWNrIGZvciBuZXcgcGVyaW9kaWMgc3RhdHVzIHVwZGF0ZXMgYW5kIHVucGFjayB0aGVtIGludG8gbG9jYWwgdmFyaWFibGVzCisgKi8KK3ZvaWQgQ0FOSmFndWFyOjp1cGRhdGVQZXJpb2RpY1N0YXR1cygpIGNvbnN0IHsKKyAgdWludDhfdCBkYXRhWzhdOworICB1aW50OF90IGRhdGFTaXplOworCisgIC8vIENoZWNrIGlmIGEgbmV3IGJ1cyB2b2x0YWdlL291dHB1dCB2b2x0YWdlL2N1cnJlbnQvdGVtcGVyYXR1cmUgbWVzc2FnZQorICAvLyBoYXMgYXJyaXZlZCBhbmQgdW5wYWNrIHRoZSB2YWx1ZXMgaW50byB0aGUgY2FjaGVkIG1lbWJlciB2YXJpYWJsZXMKKyAgaWYgKGdldE1lc3NhZ2UoTE1fQVBJX1BTVEFUX0RBVEFfUzAsIENBTl9NU0dJRF9GVUxMX00sIGRhdGEsICZkYXRhU2l6ZSkpIHsKKyAgICBtX211dGV4LmxvY2soKTsKKyAgICBtX2J1c1ZvbHRhZ2UgPSB1bnBhY2tGWFA4XzgoZGF0YSk7CisgICAgbV9vdXRwdXRWb2x0YWdlID0gdW5wYWNrUGVyY2VudGFnZShkYXRhICsgMikgKiBtX2J1c1ZvbHRhZ2U7CisgICAgbV9vdXRwdXRDdXJyZW50ID0gdW5wYWNrRlhQOF84KGRhdGEgKyA0KTsKKyAgICBtX3RlbXBlcmF0dXJlID0gdW5wYWNrRlhQOF84KGRhdGEgKyA2KTsKKyAgICBtX211dGV4LnVubG9jaygpOworCisgICAgbV9yZWNlaXZlZFN0YXR1c01lc3NhZ2UwID0gdHJ1ZTsKKyAgfQorCisgIC8vIENoZWNrIGlmIGEgbmV3IHBvc2l0aW9uL3NwZWVkIG1lc3NhZ2UgaGFzIGFycml2ZWQgYW5kIGRvIHRoZSBzYW1lCisgIGlmIChnZXRNZXNzYWdlKExNX0FQSV9QU1RBVF9EQVRBX1MxLCBDQU5fTVNHSURfRlVMTF9NLCBkYXRhLCAmZGF0YVNpemUpKSB7CisgICAgbV9tdXRleC5sb2NrKCk7CisgICAgbV9wb3NpdGlvbiA9IHVucGFja0ZYUDE2XzE2KGRhdGEpOworICAgIG1fc3BlZWQgPSB1bnBhY2tGWFAxNl8xNihkYXRhICsgNCk7CisgICAgbV9tdXRleC51bmxvY2soKTsKKworICAgIG1fcmVjZWl2ZWRTdGF0dXNNZXNzYWdlMSA9IHRydWU7CisgIH0KKworICAvLyBDaGVjayBpZiBhIG5ldyBsaW1pdHMvZmF1bHRzIG1lc3NhZ2UgaGFzIGFycml2ZWQgYW5kIGRvIHRoZSBzYW1lCisgIGlmIChnZXRNZXNzYWdlKExNX0FQSV9QU1RBVF9EQVRBX1MyLCBDQU5fTVNHSURfRlVMTF9NLCBkYXRhLCAmZGF0YVNpemUpKSB7CisgICAgbV9tdXRleC5sb2NrKCk7CisgICAgbV9saW1pdHMgPSBkYXRhWzBdOworICAgIG1fZmF1bHRzID0gZGF0YVsxXTsKKyAgICBtX211dGV4LnVubG9jaygpOworCisgICAgbV9yZWNlaXZlZFN0YXR1c01lc3NhZ2UyID0gdHJ1ZTsKKyAgfQorfQorCisvKioKKyAqIENoZWNrIGFsbCB1bnZlcmlmaWVkIHBhcmFtcyBhbmQgbWFrZSBzdXJlIHRoZXkncmUgZXF1YWwgdG8gdGhlaXIgbG9jYWwKKyAqIGNhY2hlZCB2ZXJzaW9ucy4gSWYgYSB2YWx1ZSBpc24ndCBhdmFpbGFibGUsIGl0IGdldHMgcmVxdWVzdGVkLiAgSWYgYSB2YWx1ZQorICogZG9lc24ndCBtYXRjaCB1cCwgaXQgZ2V0cyBzZXQgYWdhaW4uCisgKi8KK3ZvaWQgQ0FOSmFndWFyOjp2ZXJpZnkoKSB7CisgIHVpbnQ4X3QgZGF0YUJ1ZmZlcls4XTsKKyAgdWludDhfdCBkYXRhU2l6ZTsKKworICAvLyBJZiB0aGUgSmFndWFyIGxvc3QgcG93ZXIsIGV2ZXJ5dGhpbmcgc2hvdWxkIGJlIGNvbnNpZGVyZWQgdW52ZXJpZmllZC4KKyAgaWYgKGdldE1lc3NhZ2UoTE1fQVBJX1NUQVRVU19QT1dFUiwgQ0FOX01TR0lEX0ZVTExfTSwgZGF0YUJ1ZmZlciwKKyAgICAgICAgICAgICAgICAgJmRhdGFTaXplKSkgeworICAgIGJvb2wgcG93ZXJDeWNsZWQgPSAoYm9vbClkYXRhQnVmZmVyWzBdOworCisgICAgaWYgKHBvd2VyQ3ljbGVkKSB7CisgICAgICAvLyBDbGVhciB0aGUgcG93ZXIgY3ljbGVkIGJpdAorICAgICAgZGF0YUJ1ZmZlclswXSA9IDE7CisgICAgICBzZW5kTWVzc2FnZShMTV9BUElfU1RBVFVTX1BPV0VSLCBkYXRhQnVmZmVyLCBzaXplb2YodWludDhfdCkpOworCisgICAgICAvLyBNYXJrIGV2ZXJ5dGhpbmcgYXMgdW52ZXJpZmllZAorICAgICAgbV9jb250cm9sTW9kZVZlcmlmaWVkID0gZmFsc2U7CisgICAgICBtX3NwZWVkUmVmVmVyaWZpZWQgPSBmYWxzZTsKKyAgICAgIG1fcG9zUmVmVmVyaWZpZWQgPSBmYWxzZTsKKyAgICAgIG1fbmV1dHJhbE1vZGVWZXJpZmllZCA9IGZhbHNlOworICAgICAgbV9lbmNvZGVyQ29kZXNQZXJSZXZWZXJpZmllZCA9IGZhbHNlOworICAgICAgbV9wb3RlbnRpb21ldGVyVHVybnNWZXJpZmllZCA9IGZhbHNlOworICAgICAgbV9mb3J3YXJkTGltaXRWZXJpZmllZCA9IGZhbHNlOworICAgICAgbV9yZXZlcnNlTGltaXRWZXJpZmllZCA9IGZhbHNlOworICAgICAgbV9saW1pdE1vZGVWZXJpZmllZCA9IGZhbHNlOworICAgICAgbV9tYXhPdXRwdXRWb2x0YWdlVmVyaWZpZWQgPSBmYWxzZTsKKyAgICAgIG1fZmF1bHRUaW1lVmVyaWZpZWQgPSBmYWxzZTsKKworICAgICAgaWYgKG1fY29udHJvbE1vZGUgPT0ga1BlcmNlbnRWYnVzIHx8IG1fY29udHJvbE1vZGUgPT0ga1ZvbHRhZ2UpIHsKKyAgICAgICAgbV92b2x0YWdlUmFtcFJhdGVWZXJpZmllZCA9IGZhbHNlOworICAgICAgfSBlbHNlIHsKKyAgICAgICAgbV9wVmVyaWZpZWQgPSBmYWxzZTsKKyAgICAgICAgbV9pVmVyaWZpZWQgPSBmYWxzZTsKKyAgICAgICAgbV9kVmVyaWZpZWQgPSBmYWxzZTsKKyAgICAgIH0KKworICAgICAgLy8gVmVyaWZ5IHBlcmlvZGljIHN0YXR1cyBtZXNzYWdlcyBhZ2FpbgorICAgICAgbV9yZWNlaXZlZFN0YXR1c01lc3NhZ2UwID0gZmFsc2U7CisgICAgICBtX3JlY2VpdmVkU3RhdHVzTWVzc2FnZTEgPSBmYWxzZTsKKyAgICAgIG1fcmVjZWl2ZWRTdGF0dXNNZXNzYWdlMiA9IGZhbHNlOworCisgICAgICAvLyBSZW1vdmUgYW55IG9sZCB2YWx1ZXMgZnJvbSBuZXRjb21tcy4gT3RoZXJ3aXNlLCBwYXJhbWV0ZXJzIGFyZQorICAgICAgLy8gaW5jb3JyZWN0bHkgbWFya2VkIGFzIHZlcmlmaWVkIGJhc2VkIG9uIHN0YWxlIG1lc3NhZ2VzLgorICAgICAgZ2V0TWVzc2FnZShMTV9BUElfU1BEX1JFRiwgQ0FOX01TR0lEX0ZVTExfTSwgZGF0YUJ1ZmZlciwgJmRhdGFTaXplKTsKKyAgICAgIGdldE1lc3NhZ2UoTE1fQVBJX1BPU19SRUYsIENBTl9NU0dJRF9GVUxMX00sIGRhdGFCdWZmZXIsICZkYXRhU2l6ZSk7CisgICAgICBnZXRNZXNzYWdlKExNX0FQSV9TUERfUEMsIENBTl9NU0dJRF9GVUxMX00sIGRhdGFCdWZmZXIsICZkYXRhU2l6ZSk7CisgICAgICBnZXRNZXNzYWdlKExNX0FQSV9QT1NfUEMsIENBTl9NU0dJRF9GVUxMX00sIGRhdGFCdWZmZXIsICZkYXRhU2l6ZSk7CisgICAgICBnZXRNZXNzYWdlKExNX0FQSV9JQ1RSTF9QQywgQ0FOX01TR0lEX0ZVTExfTSwgZGF0YUJ1ZmZlciwgJmRhdGFTaXplKTsKKyAgICAgIGdldE1lc3NhZ2UoTE1fQVBJX1NQRF9JQywgQ0FOX01TR0lEX0ZVTExfTSwgZGF0YUJ1ZmZlciwgJmRhdGFTaXplKTsKKyAgICAgIGdldE1lc3NhZ2UoTE1fQVBJX1BPU19JQywgQ0FOX01TR0lEX0ZVTExfTSwgZGF0YUJ1ZmZlciwgJmRhdGFTaXplKTsKKyAgICAgIGdldE1lc3NhZ2UoTE1fQVBJX0lDVFJMX0lDLCBDQU5fTVNHSURfRlVMTF9NLCBkYXRhQnVmZmVyLCAmZGF0YVNpemUpOworICAgICAgZ2V0TWVzc2FnZShMTV9BUElfU1BEX0RDLCBDQU5fTVNHSURfRlVMTF9NLCBkYXRhQnVmZmVyLCAmZGF0YVNpemUpOworICAgICAgZ2V0TWVzc2FnZShMTV9BUElfUE9TX0RDLCBDQU5fTVNHSURfRlVMTF9NLCBkYXRhQnVmZmVyLCAmZGF0YVNpemUpOworICAgICAgZ2V0TWVzc2FnZShMTV9BUElfSUNUUkxfREMsIENBTl9NU0dJRF9GVUxMX00sIGRhdGFCdWZmZXIsICZkYXRhU2l6ZSk7CisgICAgICBnZXRNZXNzYWdlKExNX0FQSV9DRkdfQlJBS0VfQ09BU1QsIENBTl9NU0dJRF9GVUxMX00sIGRhdGFCdWZmZXIsCisgICAgICAgICAgICAgICAgICZkYXRhU2l6ZSk7CisgICAgICBnZXRNZXNzYWdlKExNX0FQSV9DRkdfRU5DX0xJTkVTLCBDQU5fTVNHSURfRlVMTF9NLCBkYXRhQnVmZmVyLCAmZGF0YVNpemUpOworICAgICAgZ2V0TWVzc2FnZShMTV9BUElfQ0ZHX1BPVF9UVVJOUywgQ0FOX01TR0lEX0ZVTExfTSwgZGF0YUJ1ZmZlciwgJmRhdGFTaXplKTsKKyAgICAgIGdldE1lc3NhZ2UoTE1fQVBJX0NGR19MSU1JVF9NT0RFLCBDQU5fTVNHSURfRlVMTF9NLCBkYXRhQnVmZmVyLAorICAgICAgICAgICAgICAgICAmZGF0YVNpemUpOworICAgICAgZ2V0TWVzc2FnZShMTV9BUElfQ0ZHX0xJTUlUX0ZXRCwgQ0FOX01TR0lEX0ZVTExfTSwgZGF0YUJ1ZmZlciwgJmRhdGFTaXplKTsKKyAgICAgIGdldE1lc3NhZ2UoTE1fQVBJX0NGR19MSU1JVF9SRVYsIENBTl9NU0dJRF9GVUxMX00sIGRhdGFCdWZmZXIsICZkYXRhU2l6ZSk7CisgICAgICBnZXRNZXNzYWdlKExNX0FQSV9DRkdfTUFYX1ZPVVQsIENBTl9NU0dJRF9GVUxMX00sIGRhdGFCdWZmZXIsICZkYXRhU2l6ZSk7CisgICAgICBnZXRNZXNzYWdlKExNX0FQSV9WT0xUX1NFVF9SQU1QLCBDQU5fTVNHSURfRlVMTF9NLCBkYXRhQnVmZmVyLCAmZGF0YVNpemUpOworICAgICAgZ2V0TWVzc2FnZShMTV9BUElfVkNPTVBfQ09NUF9SQU1QLCBDQU5fTVNHSURfRlVMTF9NLCBkYXRhQnVmZmVyLAorICAgICAgICAgICAgICAgICAmZGF0YVNpemUpOworICAgICAgZ2V0TWVzc2FnZShMTV9BUElfQ0ZHX0ZBVUxUX1RJTUUsIENBTl9NU0dJRF9GVUxMX00sIGRhdGFCdWZmZXIsCisgICAgICAgICAgICAgICAgICZkYXRhU2l6ZSk7CisgICAgfQorICB9IGVsc2UgeworICAgIHJlcXVlc3RNZXNzYWdlKExNX0FQSV9TVEFUVVNfUE9XRVIpOworICB9CisKKyAgLy8gVmVyaWZ5IHRoYXQgYW55IHJlY2VudGx5IHNldCBwYXJhbWV0ZXJzIGFyZSBjb3JyZWN0CisgIGlmICghbV9jb250cm9sTW9kZVZlcmlmaWVkICYmIG1fY29udHJvbEVuYWJsZWQpIHsKKyAgICBpZiAoZ2V0TWVzc2FnZShMTV9BUElfU1RBVFVTX0NNT0RFLCBDQU5fTVNHSURfRlVMTF9NLCBkYXRhQnVmZmVyLAorICAgICAgICAgICAgICAgICAgICZkYXRhU2l6ZSkpIHsKKyAgICAgIENvbnRyb2xNb2RlIG1vZGUgPSAoQ29udHJvbE1vZGUpZGF0YUJ1ZmZlclswXTsKKworICAgICAgaWYgKG1fY29udHJvbE1vZGUgPT0gbW9kZSkKKyAgICAgICAgbV9jb250cm9sTW9kZVZlcmlmaWVkID0gdHJ1ZTsKKyAgICAgIGVsc2UKKyAgICAgICAgLy8gRW5hYmxlIGNvbnRyb2wgYWdhaW4gdG8gcmVzZW5kIHRoZSBjb250cm9sIG1vZGUKKyAgICAgICAgRW5hYmxlQ29udHJvbCgpOworICAgIH0gZWxzZSB7CisgICAgICAvLyBWZXJpZmljYXRpb24gaXMgbmVlZGVkIGJ1dCBub3QgYXZhaWxhYmxlIC0gcmVxdWVzdCBpdCBhZ2Fpbi4KKyAgICAgIHJlcXVlc3RNZXNzYWdlKExNX0FQSV9TVEFUVVNfQ01PREUpOworICAgIH0KKyAgfQorCisgIGlmICghbV9zcGVlZFJlZlZlcmlmaWVkKSB7CisgICAgaWYgKGdldE1lc3NhZ2UoTE1fQVBJX1NQRF9SRUYsIENBTl9NU0dJRF9GVUxMX00sIGRhdGFCdWZmZXIsICZkYXRhU2l6ZSkpIHsKKyAgICAgIHVpbnQ4X3Qgc3BlZWRSZWYgPSBkYXRhQnVmZmVyWzBdOworCisgICAgICBpZiAobV9zcGVlZFJlZmVyZW5jZSA9PSBzcGVlZFJlZikKKyAgICAgICAgbV9zcGVlZFJlZlZlcmlmaWVkID0gdHJ1ZTsKKyAgICAgIGVsc2UKKyAgICAgICAgLy8gSXQncyB3cm9uZyAtIHNldCBpdCBhZ2FpbgorICAgICAgICBTZXRTcGVlZFJlZmVyZW5jZShtX3NwZWVkUmVmZXJlbmNlKTsKKyAgICB9IGVsc2UgeworICAgICAgLy8gVmVyaWZpY2F0aW9uIGlzIG5lZWRlZCBidXQgbm90IGF2YWlsYWJsZSAtIHJlcXVlc3QgaXQgYWdhaW4uCisgICAgICByZXF1ZXN0TWVzc2FnZShMTV9BUElfU1BEX1JFRik7CisgICAgfQorICB9CisKKyAgaWYgKCFtX3Bvc1JlZlZlcmlmaWVkKSB7CisgICAgaWYgKGdldE1lc3NhZ2UoTE1fQVBJX1BPU19SRUYsIENBTl9NU0dJRF9GVUxMX00sIGRhdGFCdWZmZXIsICZkYXRhU2l6ZSkpIHsKKyAgICAgIHVpbnQ4X3QgcG9zUmVmID0gZGF0YUJ1ZmZlclswXTsKKworICAgICAgaWYgKG1fcG9zaXRpb25SZWZlcmVuY2UgPT0gcG9zUmVmKQorICAgICAgICBtX3Bvc1JlZlZlcmlmaWVkID0gdHJ1ZTsKKyAgICAgIGVsc2UKKyAgICAgICAgLy8gSXQncyB3cm9uZyAtIHNldCBpdCBhZ2FpbgorICAgICAgICBTZXRQb3NpdGlvblJlZmVyZW5jZShtX3Bvc2l0aW9uUmVmZXJlbmNlKTsKKyAgICB9IGVsc2UgeworICAgICAgLy8gVmVyaWZpY2F0aW9uIGlzIG5lZWRlZCBidXQgbm90IGF2YWlsYWJsZSAtIHJlcXVlc3QgaXQgYWdhaW4uCisgICAgICByZXF1ZXN0TWVzc2FnZShMTV9BUElfUE9TX1JFRik7CisgICAgfQorICB9CisKKyAgaWYgKCFtX3BWZXJpZmllZCkgeworICAgIHVpbnQzMl90IG1lc3NhZ2UgPSAwOworCisgICAgaWYgKG1fY29udHJvbE1vZGUgPT0ga1NwZWVkKQorICAgICAgbWVzc2FnZSA9IExNX0FQSV9TUERfUEM7CisgICAgZWxzZSBpZiAobV9jb250cm9sTW9kZSA9PSBrUG9zaXRpb24pCisgICAgICBtZXNzYWdlID0gTE1fQVBJX1BPU19QQzsKKyAgICBlbHNlIGlmIChtX2NvbnRyb2xNb2RlID09IGtDdXJyZW50KQorICAgICAgbWVzc2FnZSA9IExNX0FQSV9JQ1RSTF9QQzsKKyAgICBlbHNlIHsKKyAgICAgIHdwaV9zZXRXUElFcnJvcldpdGhDb250ZXh0KAorICAgICAgICAgIEluY29tcGF0aWJsZU1vZGUsCisgICAgICAgICAgIlBJRCBjb25zdGFudHMgb25seSBhcHBseSBpbiBTcGVlZCwgUG9zaXRpb24sIGFuZCBDdXJyZW50IG1vZGUiKTsKKyAgICAgIHJldHVybjsKKyAgICB9CisKKyAgICBpZiAoZ2V0TWVzc2FnZShtZXNzYWdlLCBDQU5fTVNHSURfRlVMTF9NLCBkYXRhQnVmZmVyLCAmZGF0YVNpemUpKSB7CisgICAgICBkb3VibGUgcCA9IHVucGFja0ZYUDE2XzE2KGRhdGFCdWZmZXIpOworCisgICAgICBpZiAoRlhQMTZfRVEobV9wLCBwKSkKKyAgICAgICAgbV9wVmVyaWZpZWQgPSB0cnVlOworICAgICAgZWxzZQorICAgICAgICAvLyBJdCdzIHdyb25nIC0gc2V0IGl0IGFnYWluCisgICAgICAgIFNldFAobV9wKTsKKyAgICB9IGVsc2UgeworICAgICAgLy8gVmVyaWZpY2F0aW9uIGlzIG5lZWRlZCBidXQgbm90IGF2YWlsYWJsZSAtIHJlcXVlc3QgaXQgYWdhaW4uCisgICAgICByZXF1ZXN0TWVzc2FnZShtZXNzYWdlKTsKKyAgICB9CisgIH0KKworICBpZiAoIW1faVZlcmlmaWVkKSB7CisgICAgdWludDMyX3QgbWVzc2FnZSA9IDA7CisKKyAgICBpZiAobV9jb250cm9sTW9kZSA9PSBrU3BlZWQpCisgICAgICBtZXNzYWdlID0gTE1fQVBJX1NQRF9JQzsKKyAgICBlbHNlIGlmIChtX2NvbnRyb2xNb2RlID09IGtQb3NpdGlvbikKKyAgICAgIG1lc3NhZ2UgPSBMTV9BUElfUE9TX0lDOworICAgIGVsc2UgaWYgKG1fY29udHJvbE1vZGUgPT0ga0N1cnJlbnQpCisgICAgICBtZXNzYWdlID0gTE1fQVBJX0lDVFJMX0lDOworICAgIGVsc2UgeworICAgICAgd3BpX3NldFdQSUVycm9yV2l0aENvbnRleHQoCisgICAgICAgICAgSW5jb21wYXRpYmxlTW9kZSwKKyAgICAgICAgICAiUElEIGNvbnN0YW50cyBvbmx5IGFwcGx5IGluIFNwZWVkLCBQb3NpdGlvbiwgYW5kIEN1cnJlbnQgbW9kZSIpOworICAgICAgcmV0dXJuOworICAgIH0KKworICAgIGlmIChnZXRNZXNzYWdlKG1lc3NhZ2UsIENBTl9NU0dJRF9GVUxMX00sIGRhdGFCdWZmZXIsICZkYXRhU2l6ZSkpIHsKKyAgICAgIGRvdWJsZSBpID0gdW5wYWNrRlhQMTZfMTYoZGF0YUJ1ZmZlcik7CisKKyAgICAgIGlmIChGWFAxNl9FUShtX2ksIGkpKQorICAgICAgICBtX2lWZXJpZmllZCA9IHRydWU7CisgICAgICBlbHNlCisgICAgICAgIC8vIEl0J3Mgd3JvbmcgLSBzZXQgaXQgYWdhaW4KKyAgICAgICAgU2V0SShtX2kpOworICAgIH0gZWxzZSB7CisgICAgICAvLyBWZXJpZmljYXRpb24gaXMgbmVlZGVkIGJ1dCBub3QgYXZhaWxhYmxlIC0gcmVxdWVzdCBpdCBhZ2Fpbi4KKyAgICAgIHJlcXVlc3RNZXNzYWdlKG1lc3NhZ2UpOworICAgIH0KKyAgfQorCisgIGlmICghbV9kVmVyaWZpZWQpIHsKKyAgICB1aW50MzJfdCBtZXNzYWdlID0gMDsKKworICAgIGlmIChtX2NvbnRyb2xNb2RlID09IGtTcGVlZCkKKyAgICAgIG1lc3NhZ2UgPSBMTV9BUElfU1BEX0RDOworICAgIGVsc2UgaWYgKG1fY29udHJvbE1vZGUgPT0ga1Bvc2l0aW9uKQorICAgICAgbWVzc2FnZSA9IExNX0FQSV9QT1NfREM7CisgICAgZWxzZSBpZiAobV9jb250cm9sTW9kZSA9PSBrQ3VycmVudCkKKyAgICAgIG1lc3NhZ2UgPSBMTV9BUElfSUNUUkxfREM7CisgICAgZWxzZSB7CisgICAgICB3cGlfc2V0V1BJRXJyb3JXaXRoQ29udGV4dCgKKyAgICAgICAgICBJbmNvbXBhdGlibGVNb2RlLAorICAgICAgICAgICJQSUQgY29uc3RhbnRzIG9ubHkgYXBwbHkgaW4gU3BlZWQsIFBvc2l0aW9uLCBhbmQgQ3VycmVudCBtb2RlIik7CisgICAgICByZXR1cm47CisgICAgfQorCisgICAgaWYgKGdldE1lc3NhZ2UobWVzc2FnZSwgQ0FOX01TR0lEX0ZVTExfTSwgZGF0YUJ1ZmZlciwgJmRhdGFTaXplKSkgeworICAgICAgZG91YmxlIGQgPSB1bnBhY2tGWFAxNl8xNihkYXRhQnVmZmVyKTsKKworICAgICAgaWYgKEZYUDE2X0VRKG1fZCwgZCkpCisgICAgICAgIG1fZFZlcmlmaWVkID0gdHJ1ZTsKKyAgICAgIGVsc2UKKyAgICAgICAgLy8gSXQncyB3cm9uZyAtIHNldCBpdCBhZ2FpbgorICAgICAgICBTZXREKG1fZCk7CisgICAgfSBlbHNlIHsKKyAgICAgIC8vIFZlcmlmaWNhdGlvbiBpcyBuZWVkZWQgYnV0IG5vdCBhdmFpbGFibGUgLSByZXF1ZXN0IGl0IGFnYWluLgorICAgICAgcmVxdWVzdE1lc3NhZ2UobWVzc2FnZSk7CisgICAgfQorICB9CisKKyAgaWYgKCFtX25ldXRyYWxNb2RlVmVyaWZpZWQpIHsKKyAgICBpZiAoZ2V0TWVzc2FnZShMTV9BUElfQ0ZHX0JSQUtFX0NPQVNULCBDQU5fTVNHSURfRlVMTF9NLCBkYXRhQnVmZmVyLAorICAgICAgICAgICAgICAgICAgICZkYXRhU2l6ZSkpIHsKKyAgICAgIE5ldXRyYWxNb2RlIG1vZGUgPSAoTmV1dHJhbE1vZGUpZGF0YUJ1ZmZlclswXTsKKworICAgICAgaWYgKG1vZGUgPT0gbV9uZXV0cmFsTW9kZSkKKyAgICAgICAgbV9uZXV0cmFsTW9kZVZlcmlmaWVkID0gdHJ1ZTsKKyAgICAgIGVsc2UKKyAgICAgICAgLy8gSXQncyB3cm9uZyAtIHNldCBpdCBhZ2FpbgorICAgICAgICBDb25maWdOZXV0cmFsTW9kZShtX25ldXRyYWxNb2RlKTsKKyAgICB9IGVsc2UgeworICAgICAgLy8gVmVyaWZpY2F0aW9uIGlzIG5lZWRlZCBidXQgbm90IGF2YWlsYWJsZSAtIHJlcXVlc3QgaXQgYWdhaW4uCisgICAgICByZXF1ZXN0TWVzc2FnZShMTV9BUElfQ0ZHX0JSQUtFX0NPQVNUKTsKKyAgICB9CisgIH0KKworICBpZiAoIW1fZW5jb2RlckNvZGVzUGVyUmV2VmVyaWZpZWQpIHsKKyAgICBpZiAoZ2V0TWVzc2FnZShMTV9BUElfQ0ZHX0VOQ19MSU5FUywgQ0FOX01TR0lEX0ZVTExfTSwgZGF0YUJ1ZmZlciwKKyAgICAgICAgICAgICAgICAgICAmZGF0YVNpemUpKSB7CisgICAgICB1aW50MTZfdCBjb2RlcyA9IHVucGFja2ludDE2X3QoZGF0YUJ1ZmZlcik7CisKKyAgICAgIGlmIChjb2RlcyA9PSBtX2VuY29kZXJDb2Rlc1BlclJldikKKyAgICAgICAgbV9lbmNvZGVyQ29kZXNQZXJSZXZWZXJpZmllZCA9IHRydWU7CisgICAgICBlbHNlCisgICAgICAgIC8vIEl0J3Mgd3JvbmcgLSBzZXQgaXQgYWdhaW4KKyAgICAgICAgQ29uZmlnRW5jb2RlckNvZGVzUGVyUmV2KG1fZW5jb2RlckNvZGVzUGVyUmV2KTsKKyAgICB9IGVsc2UgeworICAgICAgLy8gVmVyaWZpY2F0aW9uIGlzIG5lZWRlZCBidXQgbm90IGF2YWlsYWJsZSAtIHJlcXVlc3QgaXQgYWdhaW4uCisgICAgICByZXF1ZXN0TWVzc2FnZShMTV9BUElfQ0ZHX0VOQ19MSU5FUyk7CisgICAgfQorICB9CisKKyAgaWYgKCFtX3BvdGVudGlvbWV0ZXJUdXJuc1ZlcmlmaWVkKSB7CisgICAgaWYgKGdldE1lc3NhZ2UoTE1fQVBJX0NGR19QT1RfVFVSTlMsIENBTl9NU0dJRF9GVUxMX00sIGRhdGFCdWZmZXIsCisgICAgICAgICAgICAgICAgICAgJmRhdGFTaXplKSkgeworICAgICAgdWludDE2X3QgdHVybnMgPSB1bnBhY2tpbnQxNl90KGRhdGFCdWZmZXIpOworCisgICAgICBpZiAodHVybnMgPT0gbV9wb3RlbnRpb21ldGVyVHVybnMpCisgICAgICAgIG1fcG90ZW50aW9tZXRlclR1cm5zVmVyaWZpZWQgPSB0cnVlOworICAgICAgZWxzZQorICAgICAgICAvLyBJdCdzIHdyb25nIC0gc2V0IGl0IGFnYWluCisgICAgICAgIENvbmZpZ1BvdGVudGlvbWV0ZXJUdXJucyhtX3BvdGVudGlvbWV0ZXJUdXJucyk7CisgICAgfSBlbHNlIHsKKyAgICAgIC8vIFZlcmlmaWNhdGlvbiBpcyBuZWVkZWQgYnV0IG5vdCBhdmFpbGFibGUgLSByZXF1ZXN0IGl0IGFnYWluLgorICAgICAgcmVxdWVzdE1lc3NhZ2UoTE1fQVBJX0NGR19QT1RfVFVSTlMpOworICAgIH0KKyAgfQorCisgIGlmICghbV9saW1pdE1vZGVWZXJpZmllZCkgeworICAgIGlmIChnZXRNZXNzYWdlKExNX0FQSV9DRkdfTElNSVRfTU9ERSwgQ0FOX01TR0lEX0ZVTExfTSwgZGF0YUJ1ZmZlciwKKyAgICAgICAgICAgICAgICAgICAmZGF0YVNpemUpKSB7CisgICAgICBMaW1pdE1vZGUgbW9kZSA9IChMaW1pdE1vZGUpZGF0YUJ1ZmZlclswXTsKKworICAgICAgaWYgKG1vZGUgPT0gbV9saW1pdE1vZGUpCisgICAgICAgIG1fbGltaXRNb2RlVmVyaWZpZWQgPSB0cnVlOworICAgICAgZWxzZSB7CisgICAgICAgIC8vIEl0J3Mgd3JvbmcgLSBzZXQgaXQgYWdhaW4KKyAgICAgICAgQ29uZmlnTGltaXRNb2RlKG1fbGltaXRNb2RlKTsKKyAgICAgIH0KKyAgICB9IGVsc2UgeworICAgICAgLy8gVmVyaWZpY2F0aW9uIGlzIG5lZWRlZCBidXQgbm90IGF2YWlsYWJsZSAtIHJlcXVlc3QgaXQgYWdhaW4uCisgICAgICByZXF1ZXN0TWVzc2FnZShMTV9BUElfQ0ZHX0xJTUlUX01PREUpOworICAgIH0KKyAgfQorCisgIGlmICghbV9mb3J3YXJkTGltaXRWZXJpZmllZCkgeworICAgIGlmIChnZXRNZXNzYWdlKExNX0FQSV9DRkdfTElNSVRfRldELCBDQU5fTVNHSURfRlVMTF9NLCBkYXRhQnVmZmVyLAorICAgICAgICAgICAgICAgICAgICZkYXRhU2l6ZSkpIHsKKyAgICAgIGRvdWJsZSBsaW1pdCA9IHVucGFja0ZYUDE2XzE2KGRhdGFCdWZmZXIpOworCisgICAgICBpZiAoRlhQMTZfRVEobGltaXQsIG1fZm9yd2FyZExpbWl0KSkKKyAgICAgICAgbV9mb3J3YXJkTGltaXRWZXJpZmllZCA9IHRydWU7CisgICAgICBlbHNlIHsKKyAgICAgICAgLy8gSXQncyB3cm9uZyAtIHNldCBpdCBhZ2FpbgorICAgICAgICBDb25maWdGb3J3YXJkTGltaXQobV9mb3J3YXJkTGltaXQpOworICAgICAgfQorICAgIH0gZWxzZSB7CisgICAgICAvLyBWZXJpZmljYXRpb24gaXMgbmVlZGVkIGJ1dCBub3QgYXZhaWxhYmxlIC0gcmVxdWVzdCBpdCBhZ2Fpbi4KKyAgICAgIHJlcXVlc3RNZXNzYWdlKExNX0FQSV9DRkdfTElNSVRfRldEKTsKKyAgICB9CisgIH0KKworICBpZiAoIW1fcmV2ZXJzZUxpbWl0VmVyaWZpZWQpIHsKKyAgICBpZiAoZ2V0TWVzc2FnZShMTV9BUElfQ0ZHX0xJTUlUX1JFViwgQ0FOX01TR0lEX0ZVTExfTSwgZGF0YUJ1ZmZlciwKKyAgICAgICAgICAgICAgICAgICAmZGF0YVNpemUpKSB7CisgICAgICBkb3VibGUgbGltaXQgPSB1bnBhY2tGWFAxNl8xNihkYXRhQnVmZmVyKTsKKworICAgICAgaWYgKEZYUDE2X0VRKGxpbWl0LCBtX3JldmVyc2VMaW1pdCkpCisgICAgICAgIG1fcmV2ZXJzZUxpbWl0VmVyaWZpZWQgPSB0cnVlOworICAgICAgZWxzZSB7CisgICAgICAgIC8vIEl0J3Mgd3JvbmcgLSBzZXQgaXQgYWdhaW4KKyAgICAgICAgQ29uZmlnUmV2ZXJzZUxpbWl0KG1fcmV2ZXJzZUxpbWl0KTsKKyAgICAgIH0KKyAgICB9IGVsc2UgeworICAgICAgLy8gVmVyaWZpY2F0aW9uIGlzIG5lZWRlZCBidXQgbm90IGF2YWlsYWJsZSAtIHJlcXVlc3QgaXQgYWdhaW4uCisgICAgICByZXF1ZXN0TWVzc2FnZShMTV9BUElfQ0ZHX0xJTUlUX1JFVik7CisgICAgfQorICB9CisKKyAgaWYgKCFtX21heE91dHB1dFZvbHRhZ2VWZXJpZmllZCkgeworICAgIGlmIChnZXRNZXNzYWdlKExNX0FQSV9DRkdfTUFYX1ZPVVQsIENBTl9NU0dJRF9GVUxMX00sIGRhdGFCdWZmZXIsCisgICAgICAgICAgICAgICAgICAgJmRhdGFTaXplKSkgeworICAgICAgZG91YmxlIHZvbHRhZ2UgPSB1bnBhY2tGWFA4XzgoZGF0YUJ1ZmZlcik7CisKKyAgICAgIC8vIFRoZSByZXR1cm5lZCBtYXggb3V0cHV0IHZvbHRhZ2UgaXMgc29tZXRpbWVzIHNsaWdodGx5IGhpZ2hlciBvcgorICAgICAgLy8gbG93ZXIgdGhhbiB3aGF0IHdhcyBzZW50LiAgVGhpcyBzaG91bGQgbm90IHRyaWdnZXIgcmVzZW5kaW5nCisgICAgICAvLyB0aGUgbWVzc2FnZS4KKyAgICAgIGlmIChzdGQ6OmFicyh2b2x0YWdlIC0gbV9tYXhPdXRwdXRWb2x0YWdlKSA8IDAuMSkKKyAgICAgICAgbV9tYXhPdXRwdXRWb2x0YWdlVmVyaWZpZWQgPSB0cnVlOworICAgICAgZWxzZSB7CisgICAgICAgIC8vIEl0J3Mgd3JvbmcgLSBzZXQgaXQgYWdhaW4KKyAgICAgICAgQ29uZmlnTWF4T3V0cHV0Vm9sdGFnZShtX21heE91dHB1dFZvbHRhZ2UpOworICAgICAgfQorICAgIH0gZWxzZSB7CisgICAgICAvLyBWZXJpZmljYXRpb24gaXMgbmVlZGVkIGJ1dCBub3QgYXZhaWxhYmxlIC0gcmVxdWVzdCBpdCBhZ2Fpbi4KKyAgICAgIHJlcXVlc3RNZXNzYWdlKExNX0FQSV9DRkdfTUFYX1ZPVVQpOworICAgIH0KKyAgfQorCisgIGlmICghbV92b2x0YWdlUmFtcFJhdGVWZXJpZmllZCkgeworICAgIGlmIChtX2NvbnRyb2xNb2RlID09IGtQZXJjZW50VmJ1cykgeworICAgICAgaWYgKGdldE1lc3NhZ2UoTE1fQVBJX1ZPTFRfU0VUX1JBTVAsIENBTl9NU0dJRF9GVUxMX00sIGRhdGFCdWZmZXIsCisgICAgICAgICAgICAgICAgICAgICAmZGF0YVNpemUpKSB7CisgICAgICAgIGRvdWJsZSByYXRlID0gdW5wYWNrUGVyY2VudGFnZShkYXRhQnVmZmVyKTsKKworICAgICAgICBpZiAoRlhQMTZfRVEocmF0ZSwgbV92b2x0YWdlUmFtcFJhdGUpKQorICAgICAgICAgIG1fdm9sdGFnZVJhbXBSYXRlVmVyaWZpZWQgPSB0cnVlOworICAgICAgICBlbHNlIHsKKyAgICAgICAgICAvLyBJdCdzIHdyb25nIC0gc2V0IGl0IGFnYWluCisgICAgICAgICAgU2V0Vm9sdGFnZVJhbXBSYXRlKG1fdm9sdGFnZVJhbXBSYXRlKTsKKyAgICAgICAgfQorICAgICAgfSBlbHNlIHsKKyAgICAgICAgLy8gVmVyaWZpY2F0aW9uIGlzIG5lZWRlZCBidXQgbm90IGF2YWlsYWJsZSAtIHJlcXVlc3QgaXQgYWdhaW4uCisgICAgICAgIHJlcXVlc3RNZXNzYWdlKExNX0FQSV9WT0xUX1NFVF9SQU1QKTsKKyAgICAgIH0KKyAgICB9IGVsc2UgaWYgKG1fY29udHJvbE1vZGUgPT0ga1ZvbHRhZ2UpIHsKKyAgICAgIGlmIChnZXRNZXNzYWdlKExNX0FQSV9WQ09NUF9DT01QX1JBTVAsIENBTl9NU0dJRF9GVUxMX00sIGRhdGFCdWZmZXIsCisgICAgICAgICAgICAgICAgICAgICAmZGF0YVNpemUpKSB7CisgICAgICAgIGRvdWJsZSByYXRlID0gdW5wYWNrRlhQOF84KGRhdGFCdWZmZXIpOworCisgICAgICAgIGlmIChGWFA4X0VRKHJhdGUsIG1fdm9sdGFnZVJhbXBSYXRlKSkKKyAgICAgICAgICBtX3ZvbHRhZ2VSYW1wUmF0ZVZlcmlmaWVkID0gdHJ1ZTsKKyAgICAgICAgZWxzZSB7CisgICAgICAgICAgLy8gSXQncyB3cm9uZyAtIHNldCBpdCBhZ2FpbgorICAgICAgICAgIFNldFZvbHRhZ2VSYW1wUmF0ZShtX3ZvbHRhZ2VSYW1wUmF0ZSk7CisgICAgICAgIH0KKyAgICAgIH0gZWxzZSB7CisgICAgICAgIC8vIFZlcmlmaWNhdGlvbiBpcyBuZWVkZWQgYnV0IG5vdCBhdmFpbGFibGUgLSByZXF1ZXN0IGl0IGFnYWluLgorICAgICAgICByZXF1ZXN0TWVzc2FnZShMTV9BUElfVkNPTVBfQ09NUF9SQU1QKTsKKyAgICAgIH0KKyAgICB9CisgIH0KKworICBpZiAoIW1fZmF1bHRUaW1lVmVyaWZpZWQpIHsKKyAgICBpZiAoZ2V0TWVzc2FnZShMTV9BUElfQ0ZHX0ZBVUxUX1RJTUUsIENBTl9NU0dJRF9GVUxMX00sIGRhdGFCdWZmZXIsCisgICAgICAgICAgICAgICAgICAgJmRhdGFTaXplKSkgeworICAgICAgdWludDE2X3QgZmF1bHRUaW1lID0gdW5wYWNraW50MTZfdChkYXRhQnVmZmVyKTsKKworICAgICAgaWYgKCh1aW50MTZfdCkobV9mYXVsdFRpbWUgKiAxMDAwLjApID09IGZhdWx0VGltZSkKKyAgICAgICAgbV9mYXVsdFRpbWVWZXJpZmllZCA9IHRydWU7CisgICAgICBlbHNlIHsKKyAgICAgICAgLy8gSXQncyB3cm9uZyAtIHNldCBpdCBhZ2FpbgorICAgICAgICBDb25maWdGYXVsdFRpbWUobV9mYXVsdFRpbWUpOworICAgICAgfQorICAgIH0gZWxzZSB7CisgICAgICAvLyBWZXJpZmljYXRpb24gaXMgbmVlZGVkIGJ1dCBub3QgYXZhaWxhYmxlIC0gcmVxdWVzdCBpdCBhZ2Fpbi4KKyAgICAgIHJlcXVlc3RNZXNzYWdlKExNX0FQSV9DRkdfRkFVTFRfVElNRSk7CisgICAgfQorICB9CisKKyAgaWYgKCFtX3JlY2VpdmVkU3RhdHVzTWVzc2FnZTAgfHwgIW1fcmVjZWl2ZWRTdGF0dXNNZXNzYWdlMSB8fAorICAgICAgIW1fcmVjZWl2ZWRTdGF0dXNNZXNzYWdlMikgeworICAgIC8vIElmIHRoZSBwZXJpb2RpYyBzdGF0dXMgbWVzc2FnZXMgaGF2ZW4ndCBiZWVuIHZlcmlmaWVkIGFzIHJlY2VpdmVkLAorICAgIC8vIHJlcXVlc3QgcGVyaW9kaWMgc3RhdHVzIG1lc3NhZ2VzIGFnYWluIGFuZCBhdHRlbXB0IHRvIHVucGFjayBhbnkKKyAgICAvLyBhdmFpbGFibGUgb25lcy4KKyAgICBzZXR1cFBlcmlvZGljU3RhdHVzKCk7CisgICAgR2V0VGVtcGVyYXR1cmUoKTsKKyAgICBHZXRQb3NpdGlvbigpOworICAgIEdldEZhdWx0cygpOworICB9Cit9CisKKy8qKgorICogU2V0IHRoZSByZWZlcmVuY2Ugc291cmNlIGRldmljZSBmb3Igc3BlZWQgY29udHJvbGxlciBtb2RlLgorICoKKyAqIENob29zZSBlbmNvZGVyIGFzIHRoZSBzb3VyY2Ugb2Ygc3BlZWQgZmVlZGJhY2sgd2hlbiBpbiBzcGVlZCBjb250cm9sIG1vZGUuCisgKgorICogQHBhcmFtIHJlZmVyZW5jZSBTcGVjaWZ5IGEgc3BlZWQgcmVmZXJlbmNlLgorICovCit2b2lkIENBTkphZ3Vhcjo6U2V0U3BlZWRSZWZlcmVuY2UodWludDhfdCByZWZlcmVuY2UpIHsKKyAgdWludDhfdCBkYXRhQnVmZmVyWzhdOworCisgIC8vIFNlbmQgdGhlIHNwZWVkIHJlZmVyZW5jZSBwYXJhbWV0ZXIKKyAgZGF0YUJ1ZmZlclswXSA9IHJlZmVyZW5jZTsKKyAgc2VuZE1lc3NhZ2UoTE1fQVBJX1NQRF9SRUYsIGRhdGFCdWZmZXIsIHNpemVvZih1aW50OF90KSk7CisKKyAgbV9zcGVlZFJlZmVyZW5jZSA9IHJlZmVyZW5jZTsKKyAgbV9zcGVlZFJlZlZlcmlmaWVkID0gZmFsc2U7Cit9CisKKy8qKgorICogR2V0IHRoZSByZWZlcmVuY2Ugc291cmNlIGRldmljZSBmb3Igc3BlZWQgY29udHJvbGxlciBtb2RlLgorICoKKyAqIEByZXR1cm4gQSBzcGVlZCByZWZlcmVuY2UgaW5kaWNhdGluZyB0aGUgY3VycmVudGx5IHNlbGVjdGVkIHJlZmVyZW5jZSBkZXZpY2UKKyAqIGZvciBzcGVlZCBjb250cm9sbGVyIG1vZGUuCisgKi8KK3VpbnQ4X3QgQ0FOSmFndWFyOjpHZXRTcGVlZFJlZmVyZW5jZSgpIGNvbnN0IHsgcmV0dXJuIG1fc3BlZWRSZWZlcmVuY2U7IH0KKworLyoqCisgKiBTZXQgdGhlIHJlZmVyZW5jZSBzb3VyY2UgZGV2aWNlIGZvciBwb3NpdGlvbiBjb250cm9sbGVyIG1vZGUuCisgKgorICogQ2hvb3NlIGJldHdlZW4gdXNpbmcgYW5kIGVuY29kZXIgYW5kIHVzaW5nIGEgcG90ZW50aW9tZXRlcgorICogYXMgdGhlIHNvdXJjZSBvZiBwb3NpdGlvbiBmZWVkYmFjayB3aGVuIGluIHBvc2l0aW9uIGNvbnRyb2wgbW9kZS4KKyAqCisgKiBAcGFyYW0gcmVmZXJlbmNlIFNwZWNpZnkgYSBQb3NpdGlvblJlZmVyZW5jZS4KKyAqLwordm9pZCBDQU5KYWd1YXI6OlNldFBvc2l0aW9uUmVmZXJlbmNlKHVpbnQ4X3QgcmVmZXJlbmNlKSB7CisgIHVpbnQ4X3QgZGF0YUJ1ZmZlcls4XTsKKworICAvLyBTZW5kIHRoZSBwb3NpdGlvbiByZWZlcmVuY2UgcGFyYW1ldGVyCisgIGRhdGFCdWZmZXJbMF0gPSByZWZlcmVuY2U7CisgIHNlbmRNZXNzYWdlKExNX0FQSV9QT1NfUkVGLCBkYXRhQnVmZmVyLCBzaXplb2YodWludDhfdCkpOworCisgIG1fcG9zaXRpb25SZWZlcmVuY2UgPSByZWZlcmVuY2U7CisgIG1fcG9zUmVmVmVyaWZpZWQgPSBmYWxzZTsKK30KKworLyoqCisgKiBHZXQgdGhlIHJlZmVyZW5jZSBzb3VyY2UgZGV2aWNlIGZvciBwb3NpdGlvbiBjb250cm9sbGVyIG1vZGUuCisgKgorICogQHJldHVybiBBIFBvc2l0aW9uUmVmZXJlbmNlIGluZGljYXRpbmcgdGhlIGN1cnJlbnRseSBzZWxlY3RlZCByZWZlcmVuY2UKKyAqIGRldmljZSBmb3IgcG9zaXRpb24gY29udHJvbGxlciBtb2RlLgorICovCit1aW50OF90IENBTkphZ3Vhcjo6R2V0UG9zaXRpb25SZWZlcmVuY2UoKSBjb25zdCB7IHJldHVybiBtX3Bvc2l0aW9uUmVmZXJlbmNlOyB9CisKKy8qKgorICogU2V0IHRoZSBQLCBJLCBhbmQgRCBjb25zdGFudHMgZm9yIHRoZSBjbG9zZWQgbG9vcCBtb2Rlcy4KKyAqCisgKiBAcGFyYW0gcCBUaGUgcHJvcG9ydGlvbmFsIGdhaW4gb2YgdGhlIEphZ3VhcidzIFBJRCBjb250cm9sbGVyLgorICogQHBhcmFtIGkgVGhlIGludGVncmFsIGdhaW4gb2YgdGhlIEphZ3VhcidzIFBJRCBjb250cm9sbGVyLgorICogQHBhcmFtIGQgVGhlIGRpZmZlcmVudGlhbCBnYWluIG9mIHRoZSBKYWd1YXIncyBQSUQgY29udHJvbGxlci4KKyAqLwordm9pZCBDQU5KYWd1YXI6OlNldFBJRChkb3VibGUgcCwgZG91YmxlIGksIGRvdWJsZSBkKSB7CisgIFNldFAocCk7CisgIFNldEkoaSk7CisgIFNldEQoZCk7Cit9CisKKy8qKgorICogU2V0IHRoZSBQIGNvbnN0YW50IGZvciB0aGUgY2xvc2VkIGxvb3AgbW9kZXMuCisgKgorICogQHBhcmFtIHAgVGhlIHByb3BvcnRpb25hbCBnYWluIG9mIHRoZSBKYWd1YXIncyBQSUQgY29udHJvbGxlci4KKyAqLwordm9pZCBDQU5KYWd1YXI6OlNldFAoZG91YmxlIHApIHsKKyAgdWludDhfdCBkYXRhQnVmZmVyWzhdOworICB1aW50OF90IGRhdGFTaXplOworCisgIHN3aXRjaCAobV9jb250cm9sTW9kZSkgeworICAgIGNhc2Uga1BlcmNlbnRWYnVzOgorICAgIGNhc2Uga1ZvbHRhZ2U6CisgICAgY2FzZSBrRm9sbG93ZXI6CisgICAgICB3cGlfc2V0V1BJRXJyb3JXaXRoQ29udGV4dCgKKyAgICAgICAgICBJbmNvbXBhdGlibGVNb2RlLAorICAgICAgICAgICJQSUQgY29uc3RhbnRzIG9ubHkgYXBwbHkgaW4gU3BlZWQsIFBvc2l0aW9uLCBhbmQgQ3VycmVudCBtb2RlIik7CisgICAgICBicmVhazsKKyAgICBjYXNlIGtTcGVlZDoKKyAgICAgIGRhdGFTaXplID0gcGFja0ZYUDE2XzE2KGRhdGFCdWZmZXIsIHApOworICAgICAgc2VuZE1lc3NhZ2UoTE1fQVBJX1NQRF9QQywgZGF0YUJ1ZmZlciwgZGF0YVNpemUpOworICAgICAgYnJlYWs7CisgICAgY2FzZSBrUG9zaXRpb246CisgICAgICBkYXRhU2l6ZSA9IHBhY2tGWFAxNl8xNihkYXRhQnVmZmVyLCBwKTsKKyAgICAgIHNlbmRNZXNzYWdlKExNX0FQSV9QT1NfUEMsIGRhdGFCdWZmZXIsIGRhdGFTaXplKTsKKyAgICAgIGJyZWFrOworICAgIGNhc2Uga0N1cnJlbnQ6CisgICAgICBkYXRhU2l6ZSA9IHBhY2tGWFAxNl8xNihkYXRhQnVmZmVyLCBwKTsKKyAgICAgIHNlbmRNZXNzYWdlKExNX0FQSV9JQ1RSTF9QQywgZGF0YUJ1ZmZlciwgZGF0YVNpemUpOworICAgICAgYnJlYWs7CisgIH0KKworICBtX3AgPSBwOworICBtX3BWZXJpZmllZCA9IGZhbHNlOworfQorCisvKioKKyAqIFNldCB0aGUgSSBjb25zdGFudCBmb3IgdGhlIGNsb3NlZCBsb29wIG1vZGVzLgorICoKKyAqIEBwYXJhbSBpIFRoZSBpbnRlZ3JhbCBnYWluIG9mIHRoZSBKYWd1YXIncyBQSUQgY29udHJvbGxlci4KKyAqLwordm9pZCBDQU5KYWd1YXI6OlNldEkoZG91YmxlIGkpIHsKKyAgdWludDhfdCBkYXRhQnVmZmVyWzhdOworICB1aW50OF90IGRhdGFTaXplOworCisgIHN3aXRjaCAobV9jb250cm9sTW9kZSkgeworICAgIGNhc2Uga1BlcmNlbnRWYnVzOgorICAgIGNhc2Uga1ZvbHRhZ2U6CisgICAgY2FzZSBrRm9sbG93ZXI6CisgICAgICB3cGlfc2V0V1BJRXJyb3JXaXRoQ29udGV4dCgKKyAgICAgICAgICBJbmNvbXBhdGlibGVNb2RlLAorICAgICAgICAgICJQSUQgY29uc3RhbnRzIG9ubHkgYXBwbHkgaW4gU3BlZWQsIFBvc2l0aW9uLCBhbmQgQ3VycmVudCBtb2RlIik7CisgICAgICBicmVhazsKKyAgICBjYXNlIGtTcGVlZDoKKyAgICAgIGRhdGFTaXplID0gcGFja0ZYUDE2XzE2KGRhdGFCdWZmZXIsIGkpOworICAgICAgc2VuZE1lc3NhZ2UoTE1fQVBJX1NQRF9JQywgZGF0YUJ1ZmZlciwgZGF0YVNpemUpOworICAgICAgYnJlYWs7CisgICAgY2FzZSBrUG9zaXRpb246CisgICAgICBkYXRhU2l6ZSA9IHBhY2tGWFAxNl8xNihkYXRhQnVmZmVyLCBpKTsKKyAgICAgIHNlbmRNZXNzYWdlKExNX0FQSV9QT1NfSUMsIGRhdGFCdWZmZXIsIGRhdGFTaXplKTsKKyAgICAgIGJyZWFrOworICAgIGNhc2Uga0N1cnJlbnQ6CisgICAgICBkYXRhU2l6ZSA9IHBhY2tGWFAxNl8xNihkYXRhQnVmZmVyLCBpKTsKKyAgICAgIHNlbmRNZXNzYWdlKExNX0FQSV9JQ1RSTF9JQywgZGF0YUJ1ZmZlciwgZGF0YVNpemUpOworICAgICAgYnJlYWs7CisgIH0KKworICBtX2kgPSBpOworICBtX2lWZXJpZmllZCA9IGZhbHNlOworfQorCisvKioKKyAqIFNldCB0aGUgRCBjb25zdGFudCBmb3IgdGhlIGNsb3NlZCBsb29wIG1vZGVzLgorICoKKyAqIEBwYXJhbSBkIFRoZSBkZXJpdmF0aXZlIGdhaW4gb2YgdGhlIEphZ3VhcidzIFBJRCBjb250cm9sbGVyLgorICovCit2b2lkIENBTkphZ3Vhcjo6U2V0RChkb3VibGUgZCkgeworICB1aW50OF90IGRhdGFCdWZmZXJbOF07CisgIHVpbnQ4X3QgZGF0YVNpemU7CisKKyAgc3dpdGNoIChtX2NvbnRyb2xNb2RlKSB7CisgICAgY2FzZSBrUGVyY2VudFZidXM6CisgICAgY2FzZSBrVm9sdGFnZToKKyAgICBjYXNlIGtGb2xsb3dlcjoKKyAgICAgIHdwaV9zZXRXUElFcnJvcldpdGhDb250ZXh0KAorICAgICAgICAgIEluY29tcGF0aWJsZU1vZGUsCisgICAgICAgICAgIlBJRCBjb25zdGFudHMgb25seSBhcHBseSBpbiBTcGVlZCwgUG9zaXRpb24sIGFuZCBDdXJyZW50IG1vZGUiKTsKKyAgICAgIGJyZWFrOworICAgIGNhc2Uga1NwZWVkOgorICAgICAgZGF0YVNpemUgPSBwYWNrRlhQMTZfMTYoZGF0YUJ1ZmZlciwgZCk7CisgICAgICBzZW5kTWVzc2FnZShMTV9BUElfU1BEX0RDLCBkYXRhQnVmZmVyLCBkYXRhU2l6ZSk7CisgICAgICBicmVhazsKKyAgICBjYXNlIGtQb3NpdGlvbjoKKyAgICAgIGRhdGFTaXplID0gcGFja0ZYUDE2XzE2KGRhdGFCdWZmZXIsIGQpOworICAgICAgc2VuZE1lc3NhZ2UoTE1fQVBJX1BPU19EQywgZGF0YUJ1ZmZlciwgZGF0YVNpemUpOworICAgICAgYnJlYWs7CisgICAgY2FzZSBrQ3VycmVudDoKKyAgICAgIGRhdGFTaXplID0gcGFja0ZYUDE2XzE2KGRhdGFCdWZmZXIsIGQpOworICAgICAgc2VuZE1lc3NhZ2UoTE1fQVBJX0lDVFJMX0RDLCBkYXRhQnVmZmVyLCBkYXRhU2l6ZSk7CisgICAgICBicmVhazsKKyAgfQorCisgIG1fZCA9IGQ7CisgIG1fZFZlcmlmaWVkID0gZmFsc2U7Cit9CisKKy8qKgorICogR2V0IHRoZSBQcm9wb3J0aW9uYWwgZ2FpbiBvZiB0aGUgY29udHJvbGxlci4KKyAqCisgKiBAcmV0dXJuIFRoZSBwcm9wb3J0aW9uYWwgZ2Fpbi4KKyAqLworZG91YmxlIENBTkphZ3Vhcjo6R2V0UCgpIGNvbnN0IHsKKyAgaWYgKG1fY29udHJvbE1vZGUgPT0ga1BlcmNlbnRWYnVzIHx8IG1fY29udHJvbE1vZGUgPT0ga1ZvbHRhZ2UpIHsKKyAgICB3cGlfc2V0V1BJRXJyb3JXaXRoQ29udGV4dCgKKyAgICAgICAgSW5jb21wYXRpYmxlTW9kZSwKKyAgICAgICAgIlBJRCBjb25zdGFudHMgb25seSBhcHBseSBpbiBTcGVlZCwgUG9zaXRpb24sIGFuZCBDdXJyZW50IG1vZGUiKTsKKyAgICByZXR1cm4gMC4wOworICB9CisKKyAgcmV0dXJuIG1fcDsKK30KKworLyoqCisgKiBHZXQgdGhlIEludHJlZ3JhbCBnYWluIG9mIHRoZSBjb250cm9sbGVyLgorICoKKyAqIEByZXR1cm4gVGhlIGludGVncmFsIGdhaW4uCisgKi8KK2RvdWJsZSBDQU5KYWd1YXI6OkdldEkoKSBjb25zdCB7CisgIGlmIChtX2NvbnRyb2xNb2RlID09IGtQZXJjZW50VmJ1cyB8fCBtX2NvbnRyb2xNb2RlID09IGtWb2x0YWdlKSB7CisgICAgd3BpX3NldFdQSUVycm9yV2l0aENvbnRleHQoCisgICAgICAgIEluY29tcGF0aWJsZU1vZGUsCisgICAgICAgICJQSUQgY29uc3RhbnRzIG9ubHkgYXBwbHkgaW4gU3BlZWQsIFBvc2l0aW9uLCBhbmQgQ3VycmVudCBtb2RlIik7CisgICAgcmV0dXJuIDAuMDsKKyAgfQorCisgIHJldHVybiBtX2k7Cit9CisKKy8qKgorICogR2V0IHRoZSBEaWZmZXJlbnRpYWwgZ2FpbiBvZiB0aGUgY29udHJvbGxlci4KKyAqCisgKiBAcmV0dXJuIFRoZSBkaWZmZXJlbnRpYWwgZ2Fpbi4KKyAqLworZG91YmxlIENBTkphZ3Vhcjo6R2V0RCgpIGNvbnN0IHsKKyAgaWYgKG1fY29udHJvbE1vZGUgPT0ga1BlcmNlbnRWYnVzIHx8IG1fY29udHJvbE1vZGUgPT0ga1ZvbHRhZ2UpIHsKKyAgICB3cGlfc2V0V1BJRXJyb3JXaXRoQ29udGV4dCgKKyAgICAgICAgSW5jb21wYXRpYmxlTW9kZSwKKyAgICAgICAgIlBJRCBjb25zdGFudHMgb25seSBhcHBseSBpbiBTcGVlZCwgUG9zaXRpb24sIGFuZCBDdXJyZW50IG1vZGUiKTsKKyAgICByZXR1cm4gMC4wOworICB9CisKKyAgcmV0dXJuIG1fZDsKK30KKworLyoqCisgKiBFbmFibGUgdGhlIGNsb3NlZCBsb29wIGNvbnRyb2xsZXIuCisgKgorICogU3RhcnQgYWN0dWFsbHkgY29udHJvbGxpbmcgdGhlIG91dHB1dCBiYXNlZCBvbiB0aGUgZmVlZGJhY2suCisgKiBJZiBzdGFydGluZyBhIHBvc2l0aW9uIGNvbnRyb2xsZXIgd2l0aCBhbiBlbmNvZGVyIHJlZmVyZW5jZSwKKyAqIHVzZSB0aGUgZW5jb2RlckluaXRpYWxQb3NpdGlvbiBwYXJhbWV0ZXIgdG8gaW5pdGlhbGl6ZSB0aGUKKyAqIGVuY29kZXIgc3RhdGUuCisgKgorICogQHBhcmFtIGVuY29kZXJJbml0aWFsUG9zaXRpb24gRW5jb2RlciBwb3NpdGlvbiB0byBzZXQgaWYgcG9zaXRpb24gd2l0aAorICogZW5jb2RlciByZWZlcmVuY2UuICBJZ25vcmVkIG90aGVyd2lzZS4KKyAqLwordm9pZCBDQU5KYWd1YXI6OkVuYWJsZUNvbnRyb2woZG91YmxlIGVuY29kZXJJbml0aWFsUG9zaXRpb24pIHsKKyAgdWludDhfdCBkYXRhQnVmZmVyWzhdOworICB1aW50OF90IGRhdGFTaXplID0gMDsKKworICBzd2l0Y2ggKG1fY29udHJvbE1vZGUpIHsKKyAgICBjYXNlIGtQZXJjZW50VmJ1czoKKyAgICAgIHNlbmRNZXNzYWdlKExNX0FQSV9WT0xUX1RfRU4sIGRhdGFCdWZmZXIsIGRhdGFTaXplKTsKKyAgICAgIGJyZWFrOworICAgIGNhc2Uga1NwZWVkOgorICAgICAgc2VuZE1lc3NhZ2UoTE1fQVBJX1NQRF9UX0VOLCBkYXRhQnVmZmVyLCBkYXRhU2l6ZSk7CisgICAgICBicmVhazsKKyAgICBjYXNlIGtQb3NpdGlvbjoKKyAgICAgIGRhdGFTaXplID0gcGFja0ZYUDE2XzE2KGRhdGFCdWZmZXIsIGVuY29kZXJJbml0aWFsUG9zaXRpb24pOworICAgICAgc2VuZE1lc3NhZ2UoTE1fQVBJX1BPU19UX0VOLCBkYXRhQnVmZmVyLCBkYXRhU2l6ZSk7CisgICAgICBicmVhazsKKyAgICBjYXNlIGtDdXJyZW50OgorICAgICAgc2VuZE1lc3NhZ2UoTE1fQVBJX0lDVFJMX1RfRU4sIGRhdGFCdWZmZXIsIGRhdGFTaXplKTsKKyAgICAgIGJyZWFrOworICAgIGNhc2Uga1ZvbHRhZ2U6CisgICAgICBzZW5kTWVzc2FnZShMTV9BUElfVkNPTVBfVF9FTiwgZGF0YUJ1ZmZlciwgZGF0YVNpemUpOworICAgICAgYnJlYWs7CisgICAgZGVmYXVsdDoKKyAgICAgIHdwaV9zZXRXUElFcnJvcldpdGhDb250ZXh0KEluY29tcGF0aWJsZU1vZGUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiVGhlIEphZ3VhciBvbmx5IHN1cHBvcnRzIEN1cnJlbnQsIFZvbHRhZ2UsICIKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJQb3NpdGlvbiwgU3BlZWQsIGFuZCBQZXJjZW50IChUaHJvdHRsZSkgIgorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIm1vZGVzLiIpOworICAgICAgcmV0dXJuOworICB9CisKKyAgbV9jb250cm9sRW5hYmxlZCA9IHRydWU7CisgIG1fY29udHJvbE1vZGVWZXJpZmllZCA9IGZhbHNlOworfQorCisvKioKKyAqIERpc2FibGUgdGhlIGNsb3NlZCBsb29wIGNvbnRyb2xsZXIuCisgKgorICogU3RvcCBkcml2aW5nIHRoZSBvdXRwdXQgYmFzZWQgb24gdGhlIGZlZWRiYWNrLgorICovCit2b2lkIENBTkphZ3Vhcjo6RGlzYWJsZUNvbnRyb2woKSB7CisgIHVpbnQ4X3QgZGF0YUJ1ZmZlcls4XTsKKyAgdWludDhfdCBkYXRhU2l6ZSA9IDA7CisKKyAgLy8gRGlzYWJsZSBhbGwgY29udHJvbAorICBzZW5kTWVzc2FnZShMTV9BUElfVk9MVF9ESVMsIGRhdGFCdWZmZXIsIGRhdGFTaXplKTsKKyAgc2VuZE1lc3NhZ2UoTE1fQVBJX1NQRF9ESVMsIGRhdGFCdWZmZXIsIGRhdGFTaXplKTsKKyAgc2VuZE1lc3NhZ2UoTE1fQVBJX1BPU19ESVMsIGRhdGFCdWZmZXIsIGRhdGFTaXplKTsKKyAgc2VuZE1lc3NhZ2UoTE1fQVBJX0lDVFJMX0RJUywgZGF0YUJ1ZmZlciwgZGF0YVNpemUpOworICBzZW5kTWVzc2FnZShMTV9BUElfVkNPTVBfRElTLCBkYXRhQnVmZmVyLCBkYXRhU2l6ZSk7CisKKyAgLy8gU3RvcCBhbGwgcGVyaW9kaWMgc2V0cG9pbnRzCisgIHNlbmRNZXNzYWdlKExNX0FQSV9WT0xUX1RfU0VULCBkYXRhQnVmZmVyLCBkYXRhU2l6ZSwKKyAgICAgICAgICAgICAgQ0FOX1NFTkRfUEVSSU9EX1NUT1BfUkVQRUFUSU5HKTsKKyAgc2VuZE1lc3NhZ2UoTE1fQVBJX1NQRF9UX1NFVCwgZGF0YUJ1ZmZlciwgZGF0YVNpemUsCisgICAgICAgICAgICAgIENBTl9TRU5EX1BFUklPRF9TVE9QX1JFUEVBVElORyk7CisgIHNlbmRNZXNzYWdlKExNX0FQSV9QT1NfVF9TRVQsIGRhdGFCdWZmZXIsIGRhdGFTaXplLAorICAgICAgICAgICAgICBDQU5fU0VORF9QRVJJT0RfU1RPUF9SRVBFQVRJTkcpOworICBzZW5kTWVzc2FnZShMTV9BUElfSUNUUkxfVF9TRVQsIGRhdGFCdWZmZXIsIGRhdGFTaXplLAorICAgICAgICAgICAgICBDQU5fU0VORF9QRVJJT0RfU1RPUF9SRVBFQVRJTkcpOworICBzZW5kTWVzc2FnZShMTV9BUElfVkNPTVBfVF9TRVQsIGRhdGFCdWZmZXIsIGRhdGFTaXplLAorICAgICAgICAgICAgICBDQU5fU0VORF9QRVJJT0RfU1RPUF9SRVBFQVRJTkcpOworCisgIG1fY29udHJvbEVuYWJsZWQgPSBmYWxzZTsKK30KKworLyoqCisgKiBFbmFibGUgY29udHJvbGxpbmcgdGhlIG1vdG9yIHZvbHRhZ2UgYXMgYSBwZXJjZW50YWdlIG9mIHRoZSBidXMgdm9sdGFnZQorICogd2l0aG91dCBhbnkgcG9zaXRpb24gb3Igc3BlZWQgZmVlZGJhY2suPGJyPgorICogQWZ0ZXIgY2FsbGluZyB0aGlzIHlvdSBtdXN0IGNhbGwge0BsaW5rIENBTkphZ3VhciNFbmFibGVDb250cm9sKCl9IG9yIHtAbGluaworICogQ0FOSmFndWFyI0VuYWJsZUNvbnRyb2woZG91YmxlKX0gdG8gZW5hYmxlIHRoZSBkZXZpY2UuCisgKi8KK3ZvaWQgQ0FOSmFndWFyOjpTZXRQZXJjZW50TW9kZSgpIHsKKyAgU2V0Q29udHJvbE1vZGUoa1BlcmNlbnRWYnVzKTsKKyAgU2V0UG9zaXRpb25SZWZlcmVuY2UoTE1fUkVGX05PTkUpOworICBTZXRTcGVlZFJlZmVyZW5jZShMTV9SRUZfTk9ORSk7Cit9CisKKy8qKgorICogRW5hYmxlIGNvbnRyb2xsaW5nIHRoZSBtb3RvciB2b2x0YWdlIGFzIGEgcGVyY2VudGFnZSBvZiB0aGUgYnVzIHZvbHRhZ2UsCisgKiBhbmQgZW5hYmxlIHNwZWVkIHNlbnNpbmcgZnJvbSBhIG5vbi1xdWFkcmF0dXJlIGVuY29kZXIuPGJyPgorICogQWZ0ZXIgY2FsbGluZyB0aGlzIHlvdSBtdXN0IGNhbGwge0BsaW5rIENBTkphZ3VhciNFbmFibGVDb250cm9sKCl9IG9yIHtAbGluaworICogQ0FOSmFndWFyI0VuYWJsZUNvbnRyb2woZG91YmxlKX0gdG8gZW5hYmxlIHRoZSBkZXZpY2UuCisgKgorICogQHBhcmFtIHRhZyBUaGUgY29uc3RhbnQgQ0FOSmFndWFyOjpFbmNvZGVyCisgKiBAcGFyYW0gY29kZXNQZXJSZXYgVGhlIGNvdW50cyBwZXIgcmV2b2x1dGlvbiBvbiB0aGUgZW5jb2RlcgorICovCit2b2lkIENBTkphZ3Vhcjo6U2V0UGVyY2VudE1vZGUoQ0FOSmFndWFyOjpFbmNvZGVyU3RydWN0LCB1aW50MTZfdCBjb2Rlc1BlclJldikgeworICBTZXRDb250cm9sTW9kZShrUGVyY2VudFZidXMpOworICBTZXRQb3NpdGlvblJlZmVyZW5jZShMTV9SRUZfTk9ORSk7CisgIFNldFNwZWVkUmVmZXJlbmNlKExNX1JFRl9FTkNPREVSKTsKKyAgQ29uZmlnRW5jb2RlckNvZGVzUGVyUmV2KGNvZGVzUGVyUmV2KTsKK30KKworLyoqCisgKiBFbmFibGUgY29udHJvbGxpbmcgdGhlIG1vdG9yIHZvbHRhZ2UgYXMgYSBwZXJjZW50YWdlIG9mIHRoZSBidXMgdm9sdGFnZSwKKyAqIGFuZCBlbmFibGUgc3BlZWQgc2Vuc2luZyBmcm9tIGEgbm9uLXF1YWRyYXR1cmUgZW5jb2Rlci48YnI+CisgKiBBZnRlciBjYWxsaW5nIHRoaXMgeW91IG11c3QgY2FsbCB7QGxpbmsgQ0FOSmFndWFyI0VuYWJsZUNvbnRyb2woKX0gb3Ige0BsaW5rCisgKiBDQU5KYWd1YXIjRW5hYmxlQ29udHJvbChkb3VibGUpfSB0byBlbmFibGUgdGhlIGRldmljZS4KKyAqCisgKiBAcGFyYW0gdGFnIFRoZSBjb25zdGFudCBDQU5KYWd1YXI6OlF1YWRFbmNvZGVyCisgKiBAcGFyYW0gY29kZXNQZXJSZXYgVGhlIGNvdW50cyBwZXIgcmV2b2x1dGlvbiBvbiB0aGUgZW5jb2RlcgorICovCit2b2lkIENBTkphZ3Vhcjo6U2V0UGVyY2VudE1vZGUoQ0FOSmFndWFyOjpRdWFkRW5jb2RlclN0cnVjdCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB1aW50MTZfdCBjb2Rlc1BlclJldikgeworICBTZXRDb250cm9sTW9kZShrUGVyY2VudFZidXMpOworICBTZXRQb3NpdGlvblJlZmVyZW5jZShMTV9SRUZfRU5DT0RFUik7CisgIFNldFNwZWVkUmVmZXJlbmNlKExNX1JFRl9RVUFEX0VOQ09ERVIpOworICBDb25maWdFbmNvZGVyQ29kZXNQZXJSZXYoY29kZXNQZXJSZXYpOworfQorCisvKioKKyogRW5hYmxlIGNvbnRyb2xsaW5nIHRoZSBtb3RvciB2b2x0YWdlIGFzIGEgcGVyY2VudGFnZSBvZiB0aGUgYnVzIHZvbHRhZ2UsCisqIGFuZCBlbmFibGUgcG9zaXRpb24gc2Vuc2luZyBmcm9tIGEgcG90ZW50aW9tZXRlciBhbmQgbm8gc3BlZWQgZmVlZGJhY2suPGJyPgorKiBBZnRlciBjYWxsaW5nIHRoaXMgeW91IG11c3QgY2FsbCB7QGxpbmsgQ0FOSmFndWFyI0VuYWJsZUNvbnRyb2woKX0gb3Ige0BsaW5rCisqIENBTkphZ3VhciNFbmFibGVDb250cm9sKGRvdWJsZSl9IHRvIGVuYWJsZSB0aGUgZGV2aWNlLgorKgorKiBAcGFyYW0gcG90ZW50aW9tZXRlciBUaGUgY29uc3RhbnQgQ0FOSmFndWFyOjpQb3RlbnRpb21ldGVyCisqLwordm9pZCBDQU5KYWd1YXI6OlNldFBlcmNlbnRNb2RlKENBTkphZ3Vhcjo6UG90ZW50aW9tZXRlclN0cnVjdCkgeworICBTZXRDb250cm9sTW9kZShrUGVyY2VudFZidXMpOworICBTZXRQb3NpdGlvblJlZmVyZW5jZShMTV9SRUZfUE9UKTsKKyAgU2V0U3BlZWRSZWZlcmVuY2UoTE1fUkVGX05PTkUpOworICBDb25maWdQb3RlbnRpb21ldGVyVHVybnMoMSk7Cit9CisKKy8qKgorICogRW5hYmxlIGNvbnRyb2xsaW5nIHRoZSBtb3RvciBjdXJyZW50IHdpdGggYSBQSUQgbG9vcC48YnI+CisgKiBBZnRlciBjYWxsaW5nIHRoaXMgeW91IG11c3QgY2FsbCB7QGxpbmsgQ0FOSmFndWFyI0VuYWJsZUNvbnRyb2woKX0gb3Ige0BsaW5rCisgKiBDQU5KYWd1YXIjRW5hYmxlQ29udHJvbChkb3VibGUpfSB0byBlbmFibGUgdGhlIGRldmljZS4KKyAqCisgKiBAcGFyYW0gcCBUaGUgcHJvcG9ydGlvbmFsIGdhaW4gb2YgdGhlIEphZ3VhcidzIFBJRCBjb250cm9sbGVyLgorICogQHBhcmFtIGkgVGhlIGludGVncmFsIGdhaW4gb2YgdGhlIEphZ3VhcidzIFBJRCBjb250cm9sbGVyLgorICogQHBhcmFtIGQgVGhlIGRpZmZlcmVudGlhbCBnYWluIG9mIHRoZSBKYWd1YXIncyBQSUQgY29udHJvbGxlci4KKyAqLwordm9pZCBDQU5KYWd1YXI6OlNldEN1cnJlbnRNb2RlKGRvdWJsZSBwLCBkb3VibGUgaSwgZG91YmxlIGQpIHsKKyAgU2V0Q29udHJvbE1vZGUoa0N1cnJlbnQpOworICBTZXRQb3NpdGlvblJlZmVyZW5jZShMTV9SRUZfTk9ORSk7CisgIFNldFNwZWVkUmVmZXJlbmNlKExNX1JFRl9OT05FKTsKKyAgU2V0UElEKHAsIGksIGQpOworfQorCisvKioKKyogRW5hYmxlIGNvbnRyb2xsaW5nIHRoZSBtb3RvciBjdXJyZW50IHdpdGggYSBQSUQgbG9vcCwgYW5kIGVuYWJsZSBzcGVlZAorKiBzZW5zaW5nIGZyb20gYSBub24tcXVhZHJhdHVyZSBlbmNvZGVyLjxicj4KKyogQWZ0ZXIgY2FsbGluZyB0aGlzIHlvdSBtdXN0IGNhbGwge0BsaW5rIENBTkphZ3VhciNFbmFibGVDb250cm9sKCl9IG9yIHtAbGluaworKiBDQU5KYWd1YXIjRW5hYmxlQ29udHJvbChkb3VibGUpfSB0byBlbmFibGUgdGhlIGRldmljZS4KKyoKKyogQHBhcmFtIGVuY29kZXIgVGhlIGNvbnN0YW50IENBTkphZ3Vhcjo6RW5jb2RlcgorKiBAcGFyYW0gcCBUaGUgcHJvcG9ydGlvbmFsIGdhaW4gb2YgdGhlIEphZ3VhcidzIFBJRCBjb250cm9sbGVyLgorKiBAcGFyYW0gaSBUaGUgaW50ZWdyYWwgZ2FpbiBvZiB0aGUgSmFndWFyJ3MgUElEIGNvbnRyb2xsZXIuCisqIEBwYXJhbSBkIFRoZSBkaWZmZXJlbnRpYWwgZ2FpbiBvZiB0aGUgSmFndWFyJ3MgUElEIGNvbnRyb2xsZXIuCisqLwordm9pZCBDQU5KYWd1YXI6OlNldEN1cnJlbnRNb2RlKENBTkphZ3Vhcjo6RW5jb2RlclN0cnVjdCwgdWludDE2X3QgY29kZXNQZXJSZXYsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZG91YmxlIHAsIGRvdWJsZSBpLCBkb3VibGUgZCkgeworICBTZXRDb250cm9sTW9kZShrQ3VycmVudCk7CisgIFNldFBvc2l0aW9uUmVmZXJlbmNlKExNX1JFRl9OT05FKTsKKyAgU2V0U3BlZWRSZWZlcmVuY2UoTE1fUkVGX05PTkUpOworICBDb25maWdFbmNvZGVyQ29kZXNQZXJSZXYoY29kZXNQZXJSZXYpOworICBTZXRQSUQocCwgaSwgZCk7Cit9CisKKy8qKgorKiBFbmFibGUgY29udHJvbGxpbmcgdGhlIG1vdG9yIGN1cnJlbnQgd2l0aCBhIFBJRCBsb29wLCBhbmQgZW5hYmxlIHNwZWVkIGFuZAorKiBwb3NpdGlvbiBzZW5zaW5nIGZyb20gYSBxdWFkcmF0dXJlIGVuY29kZXIuPGJyPgorKiBBZnRlciBjYWxsaW5nIHRoaXMgeW91IG11c3QgY2FsbCB7QGxpbmsgQ0FOSmFndWFyI0VuYWJsZUNvbnRyb2woKX0gb3Ige0BsaW5rCisqIENBTkphZ3VhciNFbmFibGVDb250cm9sKGRvdWJsZSl9IHRvIGVuYWJsZSB0aGUgZGV2aWNlLgorKgorKiBAcGFyYW0gZW5kb2VyIFRoZSBjb25zdGFudCBDQU5KYWd1YXI6OlF1YWRFbmNvZGVyCisqIEBwYXJhbSBwIFRoZSBwcm9wb3J0aW9uYWwgZ2FpbiBvZiB0aGUgSmFndWFyJ3MgUElEIGNvbnRyb2xsZXIuCisqIEBwYXJhbSBpIFRoZSBpbnRlZ3JhbCBnYWluIG9mIHRoZSBKYWd1YXIncyBQSUQgY29udHJvbGxlci4KKyogQHBhcmFtIGQgVGhlIGRpZmZlcmVudGlhbCBnYWluIG9mIHRoZSBKYWd1YXIncyBQSUQgY29udHJvbGxlci4KKyovCit2b2lkIENBTkphZ3Vhcjo6U2V0Q3VycmVudE1vZGUoQ0FOSmFndWFyOjpRdWFkRW5jb2RlclN0cnVjdCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB1aW50MTZfdCBjb2Rlc1BlclJldiwgZG91YmxlIHAsIGRvdWJsZSBpLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRvdWJsZSBkKSB7CisgIFNldENvbnRyb2xNb2RlKGtDdXJyZW50KTsKKyAgU2V0UG9zaXRpb25SZWZlcmVuY2UoTE1fUkVGX0VOQ09ERVIpOworICBTZXRTcGVlZFJlZmVyZW5jZShMTV9SRUZfUVVBRF9FTkNPREVSKTsKKyAgQ29uZmlnRW5jb2RlckNvZGVzUGVyUmV2KGNvZGVzUGVyUmV2KTsKKyAgU2V0UElEKHAsIGksIGQpOworfQorCisvKioKKyogRW5hYmxlIGNvbnRyb2xsaW5nIHRoZSBtb3RvciBjdXJyZW50IHdpdGggYSBQSUQgbG9vcCwgYW5kIGVuYWJsZSBwb3NpdGlvbgorKiBzZW5zaW5nIGZyb20gYSBwb3RlbnRpb21ldGVyLjxicj4KKyogQWZ0ZXIgY2FsbGluZyB0aGlzIHlvdSBtdXN0IGNhbGwge0BsaW5rIENBTkphZ3VhciNFbmFibGVDb250cm9sKCl9IG9yIHtAbGluaworKiBDQU5KYWd1YXIjRW5hYmxlQ29udHJvbChkb3VibGUpfSB0byBlbmFibGUgdGhlIGRldmljZS4KKyoKKyogQHBhcmFtIHBvdGVudGlvbWV0ZXIgVGhlIGNvbnN0YW50IENBTkphZ3Vhcjo6UG90ZW50aW9tZXRlcgorKiBAcGFyYW0gcCBUaGUgcHJvcG9ydGlvbmFsIGdhaW4gb2YgdGhlIEphZ3VhcidzIFBJRCBjb250cm9sbGVyLgorKiBAcGFyYW0gaSBUaGUgaW50ZWdyYWwgZ2FpbiBvZiB0aGUgSmFndWFyJ3MgUElEIGNvbnRyb2xsZXIuCisqIEBwYXJhbSBkIFRoZSBkaWZmZXJlbnRpYWwgZ2FpbiBvZiB0aGUgSmFndWFyJ3MgUElEIGNvbnRyb2xsZXIuCisqLwordm9pZCBDQU5KYWd1YXI6OlNldEN1cnJlbnRNb2RlKENBTkphZ3Vhcjo6UG90ZW50aW9tZXRlclN0cnVjdCwgZG91YmxlIHAsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZG91YmxlIGksIGRvdWJsZSBkKSB7CisgIFNldENvbnRyb2xNb2RlKGtDdXJyZW50KTsKKyAgU2V0UG9zaXRpb25SZWZlcmVuY2UoTE1fUkVGX1BPVCk7CisgIFNldFNwZWVkUmVmZXJlbmNlKExNX1JFRl9OT05FKTsKKyAgQ29uZmlnUG90ZW50aW9tZXRlclR1cm5zKDEpOworICBTZXRQSUQocCwgaSwgZCk7Cit9CisKKy8qKgorICogRW5hYmxlIGNvbnRyb2xsaW5nIHRoZSBzcGVlZCB3aXRoIGEgZmVlZGJhY2sgbG9vcCBmcm9tIGEgbm9uLXF1YWRyYXR1cmUKKyAqIGVuY29kZXIuPGJyPgorICogQWZ0ZXIgY2FsbGluZyB0aGlzIHlvdSBtdXN0IGNhbGwge0BsaW5rIENBTkphZ3VhciNFbmFibGVDb250cm9sKCl9IG9yIHtAbGluaworICogQ0FOSmFndWFyI0VuYWJsZUNvbnRyb2woZG91YmxlKX0gdG8gZW5hYmxlIHRoZSBkZXZpY2UuCisgKgorICogQHBhcmFtIGVuY29kZXIgVGhlIGNvbnN0YW50IENBTkphZ3Vhcjo6RW5jb2RlcgorICogQHBhcmFtIGNvZGVzUGVyUmV2IFRoZSBjb3VudHMgcGVyIHJldm9sdXRpb24gb24gdGhlIGVuY29kZXIuCisgKiBAcGFyYW0gcCBUaGUgcHJvcG9ydGlvbmFsIGdhaW4gb2YgdGhlIEphZ3VhcidzIFBJRCBjb250cm9sbGVyLgorICogQHBhcmFtIGkgVGhlIGludGVncmFsIGdhaW4gb2YgdGhlIEphZ3VhcidzIFBJRCBjb250cm9sbGVyLgorICogQHBhcmFtIGQgVGhlIGRpZmZlcmVudGlhbCBnYWluIG9mIHRoZSBKYWd1YXIncyBQSUQgY29udHJvbGxlci4KKyAqLwordm9pZCBDQU5KYWd1YXI6OlNldFNwZWVkTW9kZShDQU5KYWd1YXI6OkVuY29kZXJTdHJ1Y3QsIHVpbnQxNl90IGNvZGVzUGVyUmV2LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkb3VibGUgcCwgZG91YmxlIGksIGRvdWJsZSBkKSB7CisgIFNldENvbnRyb2xNb2RlKGtTcGVlZCk7CisgIFNldFBvc2l0aW9uUmVmZXJlbmNlKExNX1JFRl9OT05FKTsKKyAgU2V0U3BlZWRSZWZlcmVuY2UoTE1fUkVGX0VOQ09ERVIpOworICBDb25maWdFbmNvZGVyQ29kZXNQZXJSZXYoY29kZXNQZXJSZXYpOworICBTZXRQSUQocCwgaSwgZCk7Cit9CisKKy8qKgorKiBFbmFibGUgY29udHJvbGxpbmcgdGhlIHNwZWVkIHdpdGggYSBmZWVkYmFjayBsb29wIGZyb20gYSBxdWFkcmF0dXJlCisqIGVuY29kZXIuPGJyPgorKiBBZnRlciBjYWxsaW5nIHRoaXMgeW91IG11c3QgY2FsbCB7QGxpbmsgQ0FOSmFndWFyI0VuYWJsZUNvbnRyb2woKX0gb3Ige0BsaW5rCisqIENBTkphZ3VhciNFbmFibGVDb250cm9sKGRvdWJsZSl9IHRvIGVuYWJsZSB0aGUgZGV2aWNlLgorKgorKiBAcGFyYW0gZW5jb2RlciBUaGUgY29uc3RhbnQgQ0FOSmFndWFyOjpRdWFkRW5jb2RlcgorKiBAcGFyYW0gY29kZXNQZXJSZXYgVGhlIGNvdW50cyBwZXIgcmV2b2x1dGlvbiBvbiB0aGUgZW5jb2Rlci4KKyogQHBhcmFtIHAgVGhlIHByb3BvcnRpb25hbCBnYWluIG9mIHRoZSBKYWd1YXIncyBQSUQgY29udHJvbGxlci4KKyogQHBhcmFtIGkgVGhlIGludGVncmFsIGdhaW4gb2YgdGhlIEphZ3VhcidzIFBJRCBjb250cm9sbGVyLgorKiBAcGFyYW0gZCBUaGUgZGlmZmVyZW50aWFsIGdhaW4gb2YgdGhlIEphZ3VhcidzIFBJRCBjb250cm9sbGVyLgorKi8KK3ZvaWQgQ0FOSmFndWFyOjpTZXRTcGVlZE1vZGUoQ0FOSmFndWFyOjpRdWFkRW5jb2RlclN0cnVjdCwgdWludDE2X3QgY29kZXNQZXJSZXYsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRvdWJsZSBwLCBkb3VibGUgaSwgZG91YmxlIGQpIHsKKyAgU2V0Q29udHJvbE1vZGUoa1NwZWVkKTsKKyAgU2V0UG9zaXRpb25SZWZlcmVuY2UoTE1fUkVGX0VOQ09ERVIpOworICBTZXRTcGVlZFJlZmVyZW5jZShMTV9SRUZfUVVBRF9FTkNPREVSKTsKKyAgQ29uZmlnRW5jb2RlckNvZGVzUGVyUmV2KGNvZGVzUGVyUmV2KTsKKyAgU2V0UElEKHAsIGksIGQpOworfQorCisvKioKKyAqIEVuYWJsZSBjb250cm9sbGluZyB0aGUgcG9zaXRpb24gd2l0aCBhIGZlZWRiYWNrIGxvb3AgdXNpbmcgYW4gZW5jb2Rlci48YnI+CisgKiBBZnRlciBjYWxsaW5nIHRoaXMgeW91IG11c3QgY2FsbCB7QGxpbmsgQ0FOSmFndWFyI0VuYWJsZUNvbnRyb2woKX0gb3Ige0BsaW5rCisgKiBDQU5KYWd1YXIjRW5hYmxlQ29udHJvbChkb3VibGUpfSB0byBlbmFibGUgdGhlIGRldmljZS4KKyAqCisgKiBAcGFyYW0gZW5jb2RlciBUaGUgY29uc3RhbnQgQ0FOSmFndWFyOjpRdWFkRW5jb2RlcgorICogQHBhcmFtIGNvZGVzUGVyUmV2IFRoZSBjb3VudHMgcGVyIHJldm9sdXRpb24gb24gdGhlIGVuY29kZXIuCisgKiBAcGFyYW0gcCBUaGUgcHJvcG9ydGlvbmFsIGdhaW4gb2YgdGhlIEphZ3VhcidzIFBJRCBjb250cm9sbGVyLgorICogQHBhcmFtIGkgVGhlIGludGVncmFsIGdhaW4gb2YgdGhlIEphZ3VhcidzIFBJRCBjb250cm9sbGVyLgorICogQHBhcmFtIGQgVGhlIGRpZmZlcmVudGlhbCBnYWluIG9mIHRoZSBKYWd1YXIncyBQSUQgY29udHJvbGxlci4KKyAqCisgKi8KK3ZvaWQgQ0FOSmFndWFyOjpTZXRQb3NpdGlvbk1vZGUoQ0FOSmFndWFyOjpRdWFkRW5jb2RlclN0cnVjdCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdWludDE2X3QgY29kZXNQZXJSZXYsIGRvdWJsZSBwLCBkb3VibGUgaSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZG91YmxlIGQpIHsKKyAgU2V0Q29udHJvbE1vZGUoa1Bvc2l0aW9uKTsKKyAgU2V0UG9zaXRpb25SZWZlcmVuY2UoTE1fUkVGX0VOQ09ERVIpOworICBDb25maWdFbmNvZGVyQ29kZXNQZXJSZXYoY29kZXNQZXJSZXYpOworICBTZXRQSUQocCwgaSwgZCk7Cit9CisKKy8qKgorKiBFbmFibGUgY29udHJvbGxpbmcgdGhlIHBvc2l0aW9uIHdpdGggYSBmZWVkYmFjayBsb29wIHVzaW5nIGEKKyogcG90ZW50aW9tZXRlci48YnI+CisqIEFmdGVyIGNhbGxpbmcgdGhpcyB5b3UgbXVzdCBjYWxsIHtAbGluayBDQU5KYWd1YXIjRW5hYmxlQ29udHJvbCgpfSBvciB7QGxpbmsKKyogQ0FOSmFndWFyI0VuYWJsZUNvbnRyb2woZG91YmxlKX0gdG8gZW5hYmxlIHRoZSBkZXZpY2UuCisqIEBwYXJhbSBwIFRoZSBwcm9wb3J0aW9uYWwgZ2FpbiBvZiB0aGUgSmFndWFyJ3MgUElEIGNvbnRyb2xsZXIuCisqIEBwYXJhbSBpIFRoZSBpbnRlZ3JhbCBnYWluIG9mIHRoZSBKYWd1YXIncyBQSUQgY29udHJvbGxlci4KKyogQHBhcmFtIGQgVGhlIGRpZmZlcmVudGlhbCBnYWluIG9mIHRoZSBKYWd1YXIncyBQSUQgY29udHJvbGxlci4KKyovCit2b2lkIENBTkphZ3Vhcjo6U2V0UG9zaXRpb25Nb2RlKENBTkphZ3Vhcjo6UG90ZW50aW9tZXRlclN0cnVjdCwgZG91YmxlIHAsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRvdWJsZSBpLCBkb3VibGUgZCkgeworICBTZXRDb250cm9sTW9kZShrUG9zaXRpb24pOworICBTZXRQb3NpdGlvblJlZmVyZW5jZShMTV9SRUZfUE9UKTsKKyAgQ29uZmlnUG90ZW50aW9tZXRlclR1cm5zKDEpOworICBTZXRQSUQocCwgaSwgZCk7Cit9CisKKy8qKgorKiBFbmFibGUgY29udHJvbGxpbmcgdGhlIG1vdG9yIHZvbHRhZ2Ugd2l0aG91dCBhbnkgcG9zaXRpb24gb3Igc3BlZWQKKyogZmVlZGJhY2suPGJyPgorKiBBZnRlciBjYWxsaW5nIHRoaXMgeW91IG11c3QgY2FsbCB7QGxpbmsgQ0FOSmFndWFyI0VuYWJsZUNvbnRyb2woKX0gb3Ige0BsaW5rCisqIENBTkphZ3VhciNFbmFibGVDb250cm9sKGRvdWJsZSl9IHRvIGVuYWJsZSB0aGUgZGV2aWNlLgorKi8KK3ZvaWQgQ0FOSmFndWFyOjpTZXRWb2x0YWdlTW9kZSgpIHsKKyAgU2V0Q29udHJvbE1vZGUoa1ZvbHRhZ2UpOworICBTZXRQb3NpdGlvblJlZmVyZW5jZShMTV9SRUZfTk9ORSk7CisgIFNldFNwZWVkUmVmZXJlbmNlKExNX1JFRl9OT05FKTsKK30KKworLyoqCisqIEVuYWJsZSBjb250cm9sbGluZyB0aGUgbW90b3Igdm9sdGFnZSB3aXRoIHNwZWVkIGZlZWRiYWNrIGZyb20gYQorKiBub24tcXVhZHJhdHVyZSBlbmNvZGVyIGFuZCBubyBwb3NpdGlvbiBmZWVkYmFjay48YnI+CisqIEFmdGVyIGNhbGxpbmcgdGhpcyB5b3UgbXVzdCBjYWxsIHtAbGluayBDQU5KYWd1YXIjRW5hYmxlQ29udHJvbCgpfSBvciB7QGxpbmsKKyogQ0FOSmFndWFyI0VuYWJsZUNvbnRyb2woZG91YmxlKX0gdG8gZW5hYmxlIHRoZSBkZXZpY2UuCisqCisqIEBwYXJhbSBlbmNvZGVyIFRoZSBjb25zdGFudCBDQU5KYWd1YXI6OkVuY29kZXIKKyogQHBhcmFtIGNvZGVzUGVyUmV2IFRoZSBjb3VudHMgcGVyIHJldm9sdXRpb24gb24gdGhlIGVuY29kZXIKKyovCit2b2lkIENBTkphZ3Vhcjo6U2V0Vm9sdGFnZU1vZGUoQ0FOSmFndWFyOjpFbmNvZGVyU3RydWN0LCB1aW50MTZfdCBjb2Rlc1BlclJldikgeworICBTZXRDb250cm9sTW9kZShrVm9sdGFnZSk7CisgIFNldFBvc2l0aW9uUmVmZXJlbmNlKExNX1JFRl9OT05FKTsKKyAgU2V0U3BlZWRSZWZlcmVuY2UoTE1fUkVGX0VOQ09ERVIpOworICBDb25maWdFbmNvZGVyQ29kZXNQZXJSZXYoY29kZXNQZXJSZXYpOworfQorCisvKioKKyogRW5hYmxlIGNvbnRyb2xsaW5nIHRoZSBtb3RvciB2b2x0YWdlIHdpdGggcG9zaXRpb24gYW5kIHNwZWVkIGZlZWRiYWNrIGZyb20gYQorKiBxdWFkcmF0dXJlIGVuY29kZXIuPGJyPgorKiBBZnRlciBjYWxsaW5nIHRoaXMgeW91IG11c3QgY2FsbCB7QGxpbmsgQ0FOSmFndWFyI0VuYWJsZUNvbnRyb2woKX0gb3Ige0BsaW5rCisqIENBTkphZ3VhciNFbmFibGVDb250cm9sKGRvdWJsZSl9IHRvIGVuYWJsZSB0aGUgZGV2aWNlLgorKgorKiBAcGFyYW0gZW5jb2RlciBUaGUgY29uc3RhbnQgQ0FOSmFndWFyOjpRdWFkRW5jb2RlcgorKiBAcGFyYW0gY29kZXNQZXJSZXYgVGhlIGNvdW50cyBwZXIgcmV2b2x1dGlvbiBvbiB0aGUgZW5jb2RlcgorKi8KK3ZvaWQgQ0FOSmFndWFyOjpTZXRWb2x0YWdlTW9kZShDQU5KYWd1YXI6OlF1YWRFbmNvZGVyU3RydWN0LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVpbnQxNl90IGNvZGVzUGVyUmV2KSB7CisgIFNldENvbnRyb2xNb2RlKGtWb2x0YWdlKTsKKyAgU2V0UG9zaXRpb25SZWZlcmVuY2UoTE1fUkVGX0VOQ09ERVIpOworICBTZXRTcGVlZFJlZmVyZW5jZShMTV9SRUZfUVVBRF9FTkNPREVSKTsKKyAgQ29uZmlnRW5jb2RlckNvZGVzUGVyUmV2KGNvZGVzUGVyUmV2KTsKK30KKworLyoqCisqIEVuYWJsZSBjb250cm9sbGluZyB0aGUgbW90b3Igdm9sdGFnZSB3aXRoIHBvc2l0aW9uIGZlZWRiYWNrIGZyb20gYQorKiBwb3RlbnRpb21ldGVyIGFuZCBubyBzcGVlZCBmZWVkYmFjay48YnI+CisqIEFmdGVyIGNhbGxpbmcgdGhpcyB5b3UgbXVzdCBjYWxsIHtAbGluayBDQU5KYWd1YXIjRW5hYmxlQ29udHJvbCgpfSBvciB7QGxpbmsKKyogQ0FOSmFndWFyI0VuYWJsZUNvbnRyb2woZG91YmxlKX0gdG8gZW5hYmxlIHRoZSBkZXZpY2UuCisqCisqIEBwYXJhbSBwb3RlbnRpb21ldGVyIFRoZSBjb25zdGFudCBDQU5KYWd1YXI6OlBvdGVudGlvbWV0ZXIKKyovCit2b2lkIENBTkphZ3Vhcjo6U2V0Vm9sdGFnZU1vZGUoQ0FOSmFndWFyOjpQb3RlbnRpb21ldGVyU3RydWN0KSB7CisgIFNldENvbnRyb2xNb2RlKGtWb2x0YWdlKTsKKyAgU2V0UG9zaXRpb25SZWZlcmVuY2UoTE1fUkVGX1BPVCk7CisgIFNldFNwZWVkUmVmZXJlbmNlKExNX1JFRl9OT05FKTsKKyAgQ29uZmlnUG90ZW50aW9tZXRlclR1cm5zKDEpOworfQorCisvKioKKyAqIFVzZWQgaW50ZXJuYWxseS4gSW4gb3JkZXIgdG8gc2V0IHRoZSBjb250cm9sIG1vZGUgc2VlIHRoZSBtZXRob2RzIGxpc3RlZAorICogYmVsb3cuCisgKiBDaGFuZ2UgdGhlIGNvbnRyb2wgbW9kZSBvZiB0aGlzIEphZ3VhciBvYmplY3QuCisgKgorICogQWZ0ZXIgY2hhbmdpbmcgbW9kZXMsIGNvbmZpZ3VyZSBhbnkgUElEIGNvbnN0YW50cyBvciBvdGhlciBzZXR0aW5ncyBuZWVkZWQKKyAqIGFuZCB0aGVuIEVuYWJsZUNvbnRyb2woKSB0byBhY3R1YWxseSBjaGFuZ2UgdGhlIG1vZGUgb24gdGhlIEphZ3Vhci4KKyAqCisgKiBAcGFyYW0gY29udHJvbE1vZGUgVGhlIG5ldyBtb2RlLgorICovCit2b2lkIENBTkphZ3Vhcjo6U2V0Q29udHJvbE1vZGUoQ29udHJvbE1vZGUgY29udHJvbE1vZGUpIHsKKyAgLy8gRGlzYWJsZSB0aGUgcHJldmlvdXMgbW9kZQorICBEaXNhYmxlQ29udHJvbCgpOworCisgIGlmIChjb250cm9sTW9kZSA9PSBrRm9sbG93ZXIpCisgICAgd3BpX3NldFdQSUVycm9yV2l0aENvbnRleHQoSW5jb21wYXRpYmxlTW9kZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiVGhlIEphZ3VhciBvbmx5IHN1cHBvcnRzIEN1cnJlbnQsIFZvbHRhZ2UsICIKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiUG9zaXRpb24sIFNwZWVkLCBhbmQgUGVyY2VudCAoVGhyb3R0bGUpICIKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAibW9kZXMuIik7CisKKyAgLy8gVXBkYXRlIHRoZSBsb2NhbCBtb2RlCisgIG1fY29udHJvbE1vZGUgPSBjb250cm9sTW9kZTsKKyAgbV9jb250cm9sTW9kZVZlcmlmaWVkID0gZmFsc2U7CisKKyAgSEFMUmVwb3J0KEhBTFVzYWdlUmVwb3J0aW5nOjprUmVzb3VyY2VUeXBlX0NBTkphZ3VhciwgbV9kZXZpY2VOdW1iZXIsCisgICAgICAgICAgICBtX2NvbnRyb2xNb2RlKTsKK30KKworLyoqCisgKiBHZXQgdGhlIGFjdGl2ZSBjb250cm9sIG1vZGUgZnJvbSB0aGUgSmFndWFyLgorICoKKyAqIEFzayB0aGUgSmFnIHdoYXQgbW9kZSBpdCBpcyBpbi4KKyAqCisgKiBAcmV0dXJuIENvbnRyb2xNb2RlIHRoYXQgdGhlIEphZyBpcyBpbi4KKyAqLworQ0FOSmFndWFyOjpDb250cm9sTW9kZSBDQU5KYWd1YXI6OkdldENvbnRyb2xNb2RlKCkgY29uc3QgeworICByZXR1cm4gbV9jb250cm9sTW9kZTsKK30KKworLyoqCisgKiBHZXQgdGhlIHZvbHRhZ2UgYXQgdGhlIGJhdHRlcnkgaW5wdXQgdGVybWluYWxzIG9mIHRoZSBKYWd1YXIuCisgKgorICogQHJldHVybiBUaGUgYnVzIHZvbHRhZ2UgaW4gdm9sdHMuCisgKi8KK2Zsb2F0IENBTkphZ3Vhcjo6R2V0QnVzVm9sdGFnZSgpIGNvbnN0IHsKKyAgdXBkYXRlUGVyaW9kaWNTdGF0dXMoKTsKKyAgc3RkOjpsb2NrX2d1YXJkPHByaW9yaXR5X3JlY3Vyc2l2ZV9tdXRleD4gbG9jayhtX211dGV4KTsKKworICByZXR1cm4gbV9idXNWb2x0YWdlOworfQorCisvKioKKyAqIEdldCB0aGUgdm9sdGFnZSBiZWluZyBvdXRwdXQgZnJvbSB0aGUgbW90b3IgdGVybWluYWxzIG9mIHRoZSBKYWd1YXIuCisgKgorICogQHJldHVybiBUaGUgb3V0cHV0IHZvbHRhZ2UgaW4gdm9sdHMuCisgKi8KK2Zsb2F0IENBTkphZ3Vhcjo6R2V0T3V0cHV0Vm9sdGFnZSgpIGNvbnN0IHsKKyAgdXBkYXRlUGVyaW9kaWNTdGF0dXMoKTsKKyAgc3RkOjpsb2NrX2d1YXJkPHByaW9yaXR5X3JlY3Vyc2l2ZV9tdXRleD4gbG9jayhtX211dGV4KTsKKworICByZXR1cm4gbV9vdXRwdXRWb2x0YWdlOworfQorCisvKioKKyAqIEdldCB0aGUgY3VycmVudCB0aHJvdWdoIHRoZSBtb3RvciB0ZXJtaW5hbHMgb2YgdGhlIEphZ3Vhci4KKyAqCisgKiBAcmV0dXJuIFRoZSBvdXRwdXQgY3VycmVudCBpbiBhbXBzLgorICovCitmbG9hdCBDQU5KYWd1YXI6OkdldE91dHB1dEN1cnJlbnQoKSBjb25zdCB7CisgIHVwZGF0ZVBlcmlvZGljU3RhdHVzKCk7CisgIHN0ZDo6bG9ja19ndWFyZDxwcmlvcml0eV9yZWN1cnNpdmVfbXV0ZXg+IGxvY2sobV9tdXRleCk7CisKKyAgcmV0dXJuIG1fb3V0cHV0Q3VycmVudDsKK30KKworLyoqCisgKiBHZXQgdGhlIGludGVybmFsIHRlbXBlcmF0dXJlIG9mIHRoZSBKYWd1YXIuCisgKgorICogQHJldHVybiBUaGUgdGVtcGVyYXR1cmUgb2YgdGhlIEphZ3VhciBpbiBkZWdyZWVzIENlbHNpdXMuCisgKi8KK2Zsb2F0IENBTkphZ3Vhcjo6R2V0VGVtcGVyYXR1cmUoKSBjb25zdCB7CisgIHVwZGF0ZVBlcmlvZGljU3RhdHVzKCk7CisgIHN0ZDo6bG9ja19ndWFyZDxwcmlvcml0eV9yZWN1cnNpdmVfbXV0ZXg+IGxvY2sobV9tdXRleCk7CisKKyAgcmV0dXJuIG1fdGVtcGVyYXR1cmU7Cit9CisKKy8qKgorICogR2V0IHRoZSBwb3NpdGlvbiBvZiB0aGUgZW5jb2RlciBvciBwb3RlbnRpb21ldGVyLgorICoKKyAqIEByZXR1cm4gVGhlIHBvc2l0aW9uIG9mIHRoZSBtb3RvciBpbiByb3RhdGlvbnMgYmFzZWQgb24gdGhlIGNvbmZpZ3VyZWQKKyAqIGZlZWRiYWNrLgorICogQHNlZSBDQU5KYWd1YXIjQ29uZmlnUG90ZW50aW9tZXRlclR1cm5zKGludCkKKyAqIEBzZWUgQ0FOSmFndWFyI0NvbmZpZ0VuY29kZXJDb2Rlc1BlclJldihpbnQpCisgKi8KK2RvdWJsZSBDQU5KYWd1YXI6OkdldFBvc2l0aW9uKCkgY29uc3QgeworICB1cGRhdGVQZXJpb2RpY1N0YXR1cygpOworICBzdGQ6OmxvY2tfZ3VhcmQ8cHJpb3JpdHlfcmVjdXJzaXZlX211dGV4PiBsb2NrKG1fbXV0ZXgpOworCisgIHJldHVybiBtX3Bvc2l0aW9uOworfQorCisvKioKKyAqIEdldCB0aGUgc3BlZWQgb2YgdGhlIGVuY29kZXIuCisgKgorICogQHJldHVybiBUaGUgc3BlZWQgb2YgdGhlIG1vdG9yIGluIFJQTSBiYXNlZCBvbiB0aGUgY29uZmlndXJlZCBmZWVkYmFjay4KKyAqLworZG91YmxlIENBTkphZ3Vhcjo6R2V0U3BlZWQoKSBjb25zdCB7CisgIHVwZGF0ZVBlcmlvZGljU3RhdHVzKCk7CisgIHN0ZDo6bG9ja19ndWFyZDxwcmlvcml0eV9yZWN1cnNpdmVfbXV0ZXg+IGxvY2sobV9tdXRleCk7CisKKyAgcmV0dXJuIG1fc3BlZWQ7Cit9CisKKy8qKgorICogR2V0IHRoZSBzdGF0dXMgb2YgdGhlIGZvcndhcmQgbGltaXQgc3dpdGNoLgorICoKKyAqIEByZXR1cm4gVGhlIG1vdG9yIGlzIGFsbG93ZWQgdG8gdHVybiBpbiB0aGUgZm9yd2FyZCBkaXJlY3Rpb24gd2hlbiB0cnVlLgorICovCitib29sIENBTkphZ3Vhcjo6R2V0Rm9yd2FyZExpbWl0T0soKSBjb25zdCB7CisgIHVwZGF0ZVBlcmlvZGljU3RhdHVzKCk7CisgIHN0ZDo6bG9ja19ndWFyZDxwcmlvcml0eV9yZWN1cnNpdmVfbXV0ZXg+IGxvY2sobV9tdXRleCk7CisKKyAgcmV0dXJuIG1fbGltaXRzICYga0ZvcndhcmRMaW1pdDsKK30KKworLyoqCisgKiBHZXQgdGhlIHN0YXR1cyBvZiB0aGUgcmV2ZXJzZSBsaW1pdCBzd2l0Y2guCisgKgorICogQHJldHVybiBUaGUgbW90b3IgaXMgYWxsb3dlZCB0byB0dXJuIGluIHRoZSByZXZlcnNlIGRpcmVjdGlvbiB3aGVuIHRydWUuCisgKi8KK2Jvb2wgQ0FOSmFndWFyOjpHZXRSZXZlcnNlTGltaXRPSygpIGNvbnN0IHsKKyAgdXBkYXRlUGVyaW9kaWNTdGF0dXMoKTsKKyAgc3RkOjpsb2NrX2d1YXJkPHByaW9yaXR5X3JlY3Vyc2l2ZV9tdXRleD4gbG9jayhtX211dGV4KTsKKworICByZXR1cm4gbV9saW1pdHMgJiBrUmV2ZXJzZUxpbWl0OworfQorCisvKioKKyAqIEdldCB0aGUgc3RhdHVzIG9mIGFueSBmYXVsdHMgdGhlIEphZ3VhciBoYXMgZGV0ZWN0ZWQuCisgKgorICogQHJldHVybiBBIGJpdC1tYXNrIG9mIGZhdWx0cyBkZWZpbmVkIGJ5IHRoZSAiRmF1bHRzIiBlbnVtLgorICogQHNlZSAja0N1cnJlbnRGYXVsdAorICogQHNlZSAja0J1c1ZvbHRhZ2VGYXVsdAorICogQHNlZSAja1RlbXBlcmF0dXJlRmF1bHQKKyAqIEBzZWUgI2tHYXRlRHJpdmVyRmF1bHQKKyAqLwordWludDE2X3QgQ0FOSmFndWFyOjpHZXRGYXVsdHMoKSBjb25zdCB7CisgIHVwZGF0ZVBlcmlvZGljU3RhdHVzKCk7CisgIHN0ZDo6bG9ja19ndWFyZDxwcmlvcml0eV9yZWN1cnNpdmVfbXV0ZXg+IGxvY2sobV9tdXRleCk7CisKKyAgcmV0dXJuIG1fZmF1bHRzOworfQorCisvKioKKyAqIFNldCB0aGUgbWF4aW11bSB2b2x0YWdlIGNoYW5nZSByYXRlLgorICoKKyAqIFdoZW4gaW4gUGVyY2VudFZidXMgb3IgVm9sdGFnZSBvdXRwdXQgbW9kZSwgdGhlIHJhdGUgYXQgd2hpY2ggdGhlIHZvbHRhZ2UKKyAqIGNoYW5nZXMgY2FuCisgKiBiZSBsaW1pdGVkIHRvIHJlZHVjZSBjdXJyZW50IHNwaWtlcy4gIFNldCB0aGlzIHRvIDAuMCB0byBkaXNhYmxlIHJhdGUKKyAqIGxpbWl0aW5nLgorICoKKyAqIEBwYXJhbSByYW1wUmF0ZSBUaGUgbWF4aW11bSByYXRlIG9mIHZvbHRhZ2UgY2hhbmdlIGluIFBlcmNlbnQgVm9sdGFnZSBtb2RlIGluCisgKiBWL3MuCisgKi8KK3ZvaWQgQ0FOSmFndWFyOjpTZXRWb2x0YWdlUmFtcFJhdGUoZG91YmxlIHJhbXBSYXRlKSB7CisgIHVpbnQ4X3QgZGF0YUJ1ZmZlcls4XTsKKyAgdWludDhfdCBkYXRhU2l6ZTsKKyAgdWludDMyX3QgbWVzc2FnZTsKKworICBzd2l0Y2ggKG1fY29udHJvbE1vZGUpIHsKKyAgICBjYXNlIGtQZXJjZW50VmJ1czoKKyAgICAgIGRhdGFTaXplID0gcGFja1BlcmNlbnRhZ2UoCisgICAgICAgICAgZGF0YUJ1ZmZlciwgcmFtcFJhdGUgLyAobV9tYXhPdXRwdXRWb2x0YWdlICoga0NvbnRyb2xsZXJSYXRlKSk7CisgICAgICBtZXNzYWdlID0gTE1fQVBJX1ZPTFRfU0VUX1JBTVA7CisgICAgICBicmVhazsKKyAgICBjYXNlIGtWb2x0YWdlOgorICAgICAgZGF0YVNpemUgPSBwYWNrRlhQOF84KGRhdGFCdWZmZXIsIHJhbXBSYXRlIC8ga0NvbnRyb2xsZXJSYXRlKTsKKyAgICAgIG1lc3NhZ2UgPSBMTV9BUElfVkNPTVBfQ09NUF9SQU1QOworICAgICAgYnJlYWs7CisgICAgZGVmYXVsdDoKKyAgICAgIHdwaV9zZXRXUElFcnJvcldpdGhDb250ZXh0KAorICAgICAgICAgIEluY29tcGF0aWJsZU1vZGUsCisgICAgICAgICAgIlNldFZvbHRhZ2VSYW1wUmF0ZSBvbmx5IGFwcGxpZXMgaW4gVm9sdGFnZSBhbmQgUGVyY2VudCBtb2RlIik7CisgICAgICByZXR1cm47CisgIH0KKworICBzZW5kTWVzc2FnZShtZXNzYWdlLCBkYXRhQnVmZmVyLCBkYXRhU2l6ZSk7CisKKyAgbV92b2x0YWdlUmFtcFJhdGUgPSByYW1wUmF0ZTsKKyAgbV92b2x0YWdlUmFtcFJhdGVWZXJpZmllZCA9IGZhbHNlOworfQorCisvKioKKyAqIEdldCB0aGUgdmVyc2lvbiBvZiB0aGUgZmlybXdhcmUgcnVubmluZyBvbiB0aGUgSmFndWFyLgorICoKKyAqIEByZXR1cm4gVGhlIGZpcm13YXJlIHZlcnNpb24uICAwIGlmIHRoZSBkZXZpY2UgZGlkIG5vdCByZXNwb25kLgorICovCit1aW50MzJfdCBDQU5KYWd1YXI6OkdldEZpcm13YXJlVmVyc2lvbigpIGNvbnN0IHsgcmV0dXJuIG1fZmlybXdhcmVWZXJzaW9uOyB9CisKKy8qKgorICogR2V0IHRoZSB2ZXJzaW9uIG9mIHRoZSBKYWd1YXIgaGFyZHdhcmUuCisgKgorICogQHJldHVybiBUaGUgaGFyZHdhcmUgdmVyc2lvbi4gMTogSmFndWFyLCAgMjogQmxhY2sgSmFndWFyCisgKi8KK3VpbnQ4X3QgQ0FOSmFndWFyOjpHZXRIYXJkd2FyZVZlcnNpb24oKSBjb25zdCB7IHJldHVybiBtX2hhcmR3YXJlVmVyc2lvbjsgfQorCisvKioKKyAqIENvbmZpZ3VyZSB3aGF0IHRoZSBjb250cm9sbGVyIGRvZXMgdG8gdGhlIEgtQnJpZGdlIHdoZW4gbmV1dHJhbCAobm90IGRyaXZpbmcKKyAqIHRoZSBvdXRwdXQpLgorICoKKyAqIFRoaXMgYWxsb3dzIHlvdSB0byBvdmVycmlkZSB0aGUganVtcGVyIGNvbmZpZ3VyYXRpb24gZm9yIGJyYWtlIG9yIGNvYXN0LgorICoKKyAqIEBwYXJhbSBtb2RlIFNlbGVjdCB0byB1c2UgdGhlIGp1bXBlciBzZXR0aW5nIG9yIHRvIG92ZXJyaWRlIGl0IHRvIGNvYXN0IG9yCisgKiBicmFrZS4KKyAqLwordm9pZCBDQU5KYWd1YXI6OkNvbmZpZ05ldXRyYWxNb2RlKE5ldXRyYWxNb2RlIG1vZGUpIHsKKyAgdWludDhfdCBkYXRhQnVmZmVyWzhdOworCisgIC8vIFNldCB0aGUgbmV1dHJhbCBtb2RlCisgIHNlbmRNZXNzYWdlKExNX0FQSV9DRkdfQlJBS0VfQ09BU1QsIGRhdGFCdWZmZXIsIHNpemVvZih1aW50OF90KSk7CisKKyAgbV9uZXV0cmFsTW9kZSA9IG1vZGU7CisgIG1fbmV1dHJhbE1vZGVWZXJpZmllZCA9IGZhbHNlOworfQorCisvKioKKyAqIENvbmZpZ3VyZSBob3cgbWFueSBjb2RlcyBwZXIgcmV2b2x1dGlvbiBhcmUgZ2VuZXJhdGVkIGJ5IHlvdXIgZW5jb2Rlci4KKyAqCisgKiBAcGFyYW0gY29kZXNQZXJSZXYgVGhlIG51bWJlciBvZiBjb3VudHMgcGVyIHJldm9sdXRpb24gaW4gMVggbW9kZS4KKyAqLwordm9pZCBDQU5KYWd1YXI6OkNvbmZpZ0VuY29kZXJDb2Rlc1BlclJldih1aW50MTZfdCBjb2Rlc1BlclJldikgeworICB1aW50OF90IGRhdGFCdWZmZXJbOF07CisKKyAgLy8gU2V0IHRoZSBjb2RlcyBwZXIgcmV2b2x1dGlvbiBtb2RlCisgIHBhY2tpbnQxNl90KGRhdGFCdWZmZXIsIGNvZGVzUGVyUmV2KTsKKyAgc2VuZE1lc3NhZ2UoTE1fQVBJX0NGR19FTkNfTElORVMsIGRhdGFCdWZmZXIsIHNpemVvZih1aW50MTZfdCkpOworCisgIG1fZW5jb2RlckNvZGVzUGVyUmV2ID0gY29kZXNQZXJSZXY7CisgIG1fZW5jb2RlckNvZGVzUGVyUmV2VmVyaWZpZWQgPSBmYWxzZTsKK30KKworLyoqCisgKiBDb25maWd1cmUgdGhlIG51bWJlciBvZiB0dXJucyBvbiB0aGUgcG90ZW50aW9tZXRlci4KKyAqCisgKiBUaGVyZSBpcyBubyBzcGVjaWFsIHN1cHBvcnQgZm9yIGNvbnRpbnVvdXMgdHVybiBwb3RlbnRpb21ldGVycy4KKyAqIE9ubHkgaW50ZWdlciBudW1iZXJzIG9mIHR1cm5zIGFyZSBzdXBwb3J0ZWQuCisgKgorICogQHBhcmFtIHR1cm5zIFRoZSBudW1iZXIgb2YgdHVybnMgb2YgdGhlIHBvdGVudGlvbWV0ZXIuCisgKi8KK3ZvaWQgQ0FOSmFndWFyOjpDb25maWdQb3RlbnRpb21ldGVyVHVybnModWludDE2X3QgdHVybnMpIHsKKyAgdWludDhfdCBkYXRhQnVmZmVyWzhdOworICB1aW50OF90IGRhdGFTaXplOworCisgIC8vIFNldCB0aGUgcG90IHR1cm5zCisgIGRhdGFTaXplID0gcGFja2ludDE2X3QoZGF0YUJ1ZmZlciwgdHVybnMpOworICBzZW5kTWVzc2FnZShMTV9BUElfQ0ZHX1BPVF9UVVJOUywgZGF0YUJ1ZmZlciwgZGF0YVNpemUpOworCisgIG1fcG90ZW50aW9tZXRlclR1cm5zID0gdHVybnM7CisgIG1fcG90ZW50aW9tZXRlclR1cm5zVmVyaWZpZWQgPSBmYWxzZTsKK30KKworLyoqCisgKiBDb25maWd1cmUgU29mdCBQb3NpdGlvbiBMaW1pdHMgd2hlbiBpbiBQb3NpdGlvbiBDb250cm9sbGVyIG1vZGUuCisgKgorICogV2hlbiBjb250cm9sbGluZyBwb3NpdGlvbiwgeW91IGNhbiBhZGQgYWRkaXRpb25hbCBsaW1pdHMgb24gdG9wIG9mIHRoZSBsaW1pdAorIHN3aXRjaCBpbnB1dHMKKyAqIHRoYXQgYXJlIGJhc2VkIG9uIHRoZSBwb3NpdGlvbiBmZWVkYmFjay4gIElmIHRoZSBwb3NpdGlvbiBsaW1pdCBpcyByZWFjaGVkIG9yCisgdGhlCisgKiBzd2l0Y2ggaXMgb3BlbmVkLCB0aGF0IGRpcmVjdGlvbiB3aWxsIGJlIGRpc2FibGVkLgorICoKKworICogQHBhcmFtIGZvcndhcmRMaW1pdFBvc2l0aW9uIFRoZSBwb3NpdGlvbiB0aGF0IGlmIGV4Y2VlZGVkIHdpbGwgZGlzYWJsZSB0aGUKKyBmb3J3YXJkIGRpcmVjdGlvbi4KKyAqIEBwYXJhbSByZXZlcnNlTGltaXRQb3NpdGlvbiBUaGUgcG9zaXRpb24gdGhhdCBpZiBleGNlZWRlZCB3aWxsIGRpc2FibGUgdGhlCisgcmV2ZXJzZSBkaXJlY3Rpb24uCisgKi8KK3ZvaWQgQ0FOSmFndWFyOjpDb25maWdTb2Z0UG9zaXRpb25MaW1pdHMoZG91YmxlIGZvcndhcmRMaW1pdFBvc2l0aW9uLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkb3VibGUgcmV2ZXJzZUxpbWl0UG9zaXRpb24pIHsKKyAgQ29uZmlnTGltaXRNb2RlKGtMaW1pdE1vZGVfU29mdFBvc2l0aW9uTGltaXRzKTsKKyAgQ29uZmlnRm9yd2FyZExpbWl0KGZvcndhcmRMaW1pdFBvc2l0aW9uKTsKKyAgQ29uZmlnUmV2ZXJzZUxpbWl0KHJldmVyc2VMaW1pdFBvc2l0aW9uKTsKK30KKworLyoqCisgKiBEaXNhYmxlIFNvZnQgUG9zaXRpb24gTGltaXRzIGlmIHByZXZpb3VzbHkgZW5hYmxlZC4KKyAqCisgKiBTb2Z0IFBvc2l0aW9uIExpbWl0cyBhcmUgZGlzYWJsZWQgYnkgZGVmYXVsdC4KKyAqLwordm9pZCBDQU5KYWd1YXI6OkRpc2FibGVTb2Z0UG9zaXRpb25MaW1pdHMoKSB7CisgIENvbmZpZ0xpbWl0TW9kZShrTGltaXRNb2RlX1N3aXRjaElucHV0c09ubHkpOworfQorCisvKioKKyAqIFNldCB0aGUgbGltaXQgbW9kZSBmb3IgcG9zaXRpb24gY29udHJvbCBtb2RlLgorICoKKyAqIFVzZSBDb25maWdTb2Z0UG9zaXRpb25MaW1pdHMgb3IgRGlzYWJsZVNvZnRQb3NpdGlvbkxpbWl0cyB0byBzZXQgdGhpcworICogYXV0b21hdGljYWxseS4KKyAqLwordm9pZCBDQU5KYWd1YXI6OkNvbmZpZ0xpbWl0TW9kZShMaW1pdE1vZGUgbW9kZSkgeworICB1aW50OF90IGRhdGFCdWZmZXJbOF07CisKKyAgZGF0YUJ1ZmZlclswXSA9IG1vZGU7CisgIHNlbmRNZXNzYWdlKExNX0FQSV9DRkdfTElNSVRfTU9ERSwgZGF0YUJ1ZmZlciwgc2l6ZW9mKHVpbnQ4X3QpKTsKKworICBtX2xpbWl0TW9kZSA9IG1vZGU7CisgIG1fbGltaXRNb2RlVmVyaWZpZWQgPSBmYWxzZTsKK30KKworLyoqCisqIFNldCB0aGUgcG9zaXRpb24gdGhhdCBpZiBleGNlZWRlZCB3aWxsIGRpc2FibGUgdGhlIGZvcndhcmQgZGlyZWN0aW9uLgorKgorKiBVc2UgQ29uZmlnU29mdFBvc2l0aW9uTGltaXRzIHRvIHNldCB0aGlzIGFuZCB0aGUgbGltaXQgbW9kZSBhdXRvbWF0aWNhbGx5LgorKi8KK3ZvaWQgQ0FOSmFndWFyOjpDb25maWdGb3J3YXJkTGltaXQoZG91YmxlIGZvcndhcmRMaW1pdFBvc2l0aW9uKSB7CisgIHVpbnQ4X3QgZGF0YUJ1ZmZlcls4XTsKKyAgdWludDhfdCBkYXRhU2l6ZTsKKworICBkYXRhU2l6ZSA9IHBhY2tGWFAxNl8xNihkYXRhQnVmZmVyLCBmb3J3YXJkTGltaXRQb3NpdGlvbik7CisgIGRhdGFCdWZmZXJbZGF0YVNpemUrK10gPSAxOworICBzZW5kTWVzc2FnZShMTV9BUElfQ0ZHX0xJTUlUX0ZXRCwgZGF0YUJ1ZmZlciwgZGF0YVNpemUpOworCisgIG1fZm9yd2FyZExpbWl0ID0gZm9yd2FyZExpbWl0UG9zaXRpb247CisgIG1fZm9yd2FyZExpbWl0VmVyaWZpZWQgPSBmYWxzZTsKK30KKworLyoqCisqIFNldCB0aGUgcG9zaXRpb24gdGhhdCBpZiBleGNlZWRlZCB3aWxsIGRpc2FibGUgdGhlIHJldmVyc2UgZGlyZWN0aW9uLgorKgorKiBVc2UgQ29uZmlnU29mdFBvc2l0aW9uTGltaXRzIHRvIHNldCB0aGlzIGFuZCB0aGUgbGltaXQgbW9kZSBhdXRvbWF0aWNhbGx5LgorKi8KK3ZvaWQgQ0FOSmFndWFyOjpDb25maWdSZXZlcnNlTGltaXQoZG91YmxlIHJldmVyc2VMaW1pdFBvc2l0aW9uKSB7CisgIHVpbnQ4X3QgZGF0YUJ1ZmZlcls4XTsKKyAgdWludDhfdCBkYXRhU2l6ZTsKKworICBkYXRhU2l6ZSA9IHBhY2tGWFAxNl8xNihkYXRhQnVmZmVyLCByZXZlcnNlTGltaXRQb3NpdGlvbik7CisgIGRhdGFCdWZmZXJbZGF0YVNpemUrK10gPSAwOworICBzZW5kTWVzc2FnZShMTV9BUElfQ0ZHX0xJTUlUX1JFViwgZGF0YUJ1ZmZlciwgZGF0YVNpemUpOworCisgIG1fcmV2ZXJzZUxpbWl0ID0gcmV2ZXJzZUxpbWl0UG9zaXRpb247CisgIG1fcmV2ZXJzZUxpbWl0VmVyaWZpZWQgPSBmYWxzZTsKK30KKworLyoqCisgKiBDb25maWd1cmUgdGhlIG1heGltdW0gdm9sdGFnZSB0aGF0IHRoZSBKYWd1YXIgd2lsbCBldmVyIG91dHB1dC4KKyAqCisgKiBUaGlzIGNhbiBiZSB1c2VkIHRvIGxpbWl0IHRoZSBtYXhpbXVtIG91dHB1dCB2b2x0YWdlIGluIGFsbCBtb2RlcyBzbyB0aGF0CisgKiBtb3RvcnMgd2hpY2ggY2Fubm90IHdpdGhzdGFuZCBmdWxsIGJ1cyB2b2x0YWdlIGNhbiBiZSB1c2VkIHNhZmVseS4KKyAqCisgKiBAcGFyYW0gdm9sdGFnZSBUaGUgbWF4aW11bSB2b2x0YWdlIG91dHB1dCBieSB0aGUgSmFndWFyLgorICovCit2b2lkIENBTkphZ3Vhcjo6Q29uZmlnTWF4T3V0cHV0Vm9sdGFnZShkb3VibGUgdm9sdGFnZSkgeworICB1aW50OF90IGRhdGFCdWZmZXJbOF07CisgIHVpbnQ4X3QgZGF0YVNpemU7CisKKyAgZGF0YVNpemUgPSBwYWNrRlhQOF84KGRhdGFCdWZmZXIsIHZvbHRhZ2UpOworICBzZW5kTWVzc2FnZShMTV9BUElfQ0ZHX01BWF9WT1VULCBkYXRhQnVmZmVyLCBkYXRhU2l6ZSk7CisKKyAgbV9tYXhPdXRwdXRWb2x0YWdlID0gdm9sdGFnZTsKKyAgbV9tYXhPdXRwdXRWb2x0YWdlVmVyaWZpZWQgPSBmYWxzZTsKK30KKworLyoqCisgKiBDb25maWd1cmUgaG93IGxvbmcgdGhlIEphZ3VhciB3YWl0cyBpbiB0aGUgY2FzZSBvZiBhIGZhdWx0IGJlZm9yZSByZXN1bWluZworICogb3BlcmF0aW9uLgorICoKKyAqIEZhdWx0cyBpbmNsdWRlIG92ZXIgdGVtZXJhdHVyZSwgb3ZlciBjdXJyZW50LCBhbmQgYnVzIHVuZGVyIHZvbHRhZ2UuCisgKiBUaGUgZGVmYXVsdCBpcyAzLjAgc2Vjb25kcywgYnV0IGNhbiBiZSByZWR1Y2VkIHRvIGFzIGxvdyBhcyAwLjUgc2Vjb25kcy4KKyAqCisgKiBAcGFyYW0gZmF1bHRUaW1lIFRoZSB0aW1lIHRvIHdhaXQgYmVmb3JlIHJlc3VtaW5nIG9wZXJhdGlvbiwgaW4gc2Vjb25kcy4KKyAqLwordm9pZCBDQU5KYWd1YXI6OkNvbmZpZ0ZhdWx0VGltZShmbG9hdCBmYXVsdFRpbWUpIHsKKyAgdWludDhfdCBkYXRhQnVmZmVyWzhdOworICB1aW50OF90IGRhdGFTaXplOworCisgIGlmIChmYXVsdFRpbWUgPCAwLjUpCisgICAgZmF1bHRUaW1lID0gMC41OworICBlbHNlIGlmIChmYXVsdFRpbWUgPiAzLjApCisgICAgZmF1bHRUaW1lID0gMy4wOworCisgIC8vIE1lc3NhZ2UgdGFrZXMgbXMKKyAgZGF0YVNpemUgPSBwYWNraW50MTZfdChkYXRhQnVmZmVyLCAoaW50MTZfdCkoZmF1bHRUaW1lICogMTAwMC4wKSk7CisgIHNlbmRNZXNzYWdlKExNX0FQSV9DRkdfRkFVTFRfVElNRSwgZGF0YUJ1ZmZlciwgZGF0YVNpemUpOworCisgIG1fZmF1bHRUaW1lID0gZmF1bHRUaW1lOworICBtX2ZhdWx0VGltZVZlcmlmaWVkID0gZmFsc2U7Cit9CisKKy8qKgorICogVXBkYXRlIGFsbCB0aGUgbW90b3JzIHRoYXQgaGF2ZSBwZW5kaW5nIHNldHMgaW4gdGhlIHN5bmNHcm91cC4KKyAqCisgKiBAcGFyYW0gc3luY0dyb3VwIEEgYml0bWFzayBvZiBncm91cHMgdG8gZ2VuZXJhdGUgc3luY2hyb25vdXMgb3V0cHV0LgorICovCit2b2lkIENBTkphZ3Vhcjo6VXBkYXRlU3luY0dyb3VwKHVpbnQ4X3Qgc3luY0dyb3VwKSB7CisgIHNlbmRNZXNzYWdlSGVscGVyKENBTl9NU0dJRF9BUElfU1lOQywgJnN5bmNHcm91cCwgc2l6ZW9mKHN5bmNHcm91cCksCisgICAgICAgICAgICAgICAgICAgIENBTl9TRU5EX1BFUklPRF9OT19SRVBFQVQpOworfQorCit2b2lkIENBTkphZ3Vhcjo6U2V0RXhwaXJhdGlvbihmbG9hdCB0aW1lb3V0KSB7CisgIGlmIChtX3NhZmV0eUhlbHBlcikgbV9zYWZldHlIZWxwZXItPlNldEV4cGlyYXRpb24odGltZW91dCk7Cit9CisKK2Zsb2F0IENBTkphZ3Vhcjo6R2V0RXhwaXJhdGlvbigpIGNvbnN0IHsKKyAgaWYgKCFtX3NhZmV0eUhlbHBlcikgcmV0dXJuIDAuMDsKKyAgcmV0dXJuIG1fc2FmZXR5SGVscGVyLT5HZXRFeHBpcmF0aW9uKCk7Cit9CisKK2Jvb2wgQ0FOSmFndWFyOjpJc0FsaXZlKCkgY29uc3QgeworICBpZiAoIW1fc2FmZXR5SGVscGVyKSByZXR1cm4gZmFsc2U7CisgIHJldHVybiBtX3NhZmV0eUhlbHBlci0+SXNBbGl2ZSgpOworfQorCitib29sIENBTkphZ3Vhcjo6SXNTYWZldHlFbmFibGVkKCkgY29uc3QgeworICBpZiAoIW1fc2FmZXR5SGVscGVyKSByZXR1cm4gZmFsc2U7CisgIHJldHVybiBtX3NhZmV0eUhlbHBlci0+SXNTYWZldHlFbmFibGVkKCk7Cit9CisKK3ZvaWQgQ0FOSmFndWFyOjpTZXRTYWZldHlFbmFibGVkKGJvb2wgZW5hYmxlZCkgeworICBpZiAobV9zYWZldHlIZWxwZXIpIG1fc2FmZXR5SGVscGVyLT5TZXRTYWZldHlFbmFibGVkKGVuYWJsZWQpOworfQorCit2b2lkIENBTkphZ3Vhcjo6R2V0RGVzY3JpcHRpb24oc3RkOjpvc3RyaW5nc3RyZWFtJiBkZXNjKSBjb25zdCB7CisgIGRlc2MgPDwgIkNBTkphZ3VhciBJRCAiIDw8IG1fZGV2aWNlTnVtYmVyOworfQorCit1aW50OF90IENBTkphZ3Vhcjo6R2V0RGV2aWNlSUQoKSBjb25zdCB7IHJldHVybiBtX2RldmljZU51bWJlcjsgfQorCisvKioKKyAqIENvbW1vbiBpbnRlcmZhY2UgZm9yIHN0b3BwaW5nIHRoZSBtb3RvcgorICogUGFydCBvZiB0aGUgTW90b3JTYWZldHkgaW50ZXJmYWNlCisgKgorICogQGRlcHJlY2F0ZWQgQ2FsbCBEaXNhYmxlQ29udHJvbCBpbnN0ZWFkLgorICovCit2b2lkIENBTkphZ3Vhcjo6U3RvcE1vdG9yKCkgeyBEaXNhYmxlQ29udHJvbCgpOyB9CisKKy8qKgorKiBDb21tb24gaW50ZXJmYWNlIGZvciBpbnZlcnRpbmcgZGlyZWN0aW9uIG9mIGEgc3BlZWQgY29udHJvbGxlci4KKyogT25seSB3b3JrcyBpbiBQZXJjZW50VmJ1cywgc3BlZWQsIGFuZCBWb2x0YWdlIG1vZGVzLgorKiBAcGFyYW0gaXNJbnZlcnRlZCBUaGUgc3RhdGUgb2YgaW52ZXJzaW9uLCB0cnVlIGlzIGludmVydGVkCisqLwordm9pZCBDQU5KYWd1YXI6OlNldEludmVydGVkKGJvb2wgaXNJbnZlcnRlZCkgeyBtX2lzSW52ZXJ0ZWQgPSBpc0ludmVydGVkOyB9CisKKy8qKgorICogQ29tbW9uIGludGVyZmFjZSBmb3IgdGhlIGludmVydGluZyBkaXJlY3Rpb24gb2YgYSBzcGVlZCBjb250cm9sbGVyLgorICoKKyAqIEByZXR1cm4gaXNJbnZlcnRlZCBUaGUgc3RhdGUgb2YgaW52ZXJzaW9uLCB0cnVlIGlzIGludmVydGVkLgorICoKKyAqLworYm9vbCBDQU5KYWd1YXI6OkdldEludmVydGVkKCkgY29uc3QgeyByZXR1cm4gbV9pc0ludmVydGVkOyB9CisKK3ZvaWQgQ0FOSmFndWFyOjpWYWx1ZUNoYW5nZWQoSVRhYmxlKiBzb3VyY2UsIGxsdm06OlN0cmluZ1JlZiBrZXksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0ZDo6c2hhcmVkX3B0cjxudDo6VmFsdWU+IHZhbHVlLCBib29sIGlzTmV3KSB7CisgIGlmKGtleSA9PSAiTW9kZSIgJiYgdmFsdWUtPklzRG91YmxlKCkpIFNldENvbnRyb2xNb2RlKHN0YXRpY19jYXN0PENBTlNwZWVkQ29udHJvbGxlcjo6Q29udHJvbE1vZGU+KHZhbHVlLT5HZXREb3VibGUoKSkpOworICBpZihJc01vZGVQSUQobV9jb250cm9sTW9kZSkgJiYgdmFsdWUtPklzRG91YmxlKCkpIHsKKyAgICBpZihrZXkgPT0gInAiKSBTZXRQKHZhbHVlLT5HZXREb3VibGUoKSk7CisgICAgaWYoa2V5ID09ICJpIikgU2V0SSh2YWx1ZS0+R2V0RG91YmxlKCkpOworICAgIGlmKGtleSA9PSAiZCIpIFNldEQodmFsdWUtPkdldERvdWJsZSgpKTsKKyAgfQorICBpZihrZXkgPT0gIkVuYWJsZWQiICYmIHZhbHVlLT5Jc0Jvb2xlYW4oKSkgeworICAgICAgaWYgKHZhbHVlLT5HZXRCb29sZWFuKCkpIHsKKyAgICAgICAgRW5hYmxlQ29udHJvbCgpOworICAgICAgfSBlbHNlIHsKKyAgICAgICAgRGlzYWJsZUNvbnRyb2woKTsKKyAgICAgIH0KKyAgfQorICBpZihrZXkgPT0gIlZhbHVlIiAmJiB2YWx1ZS0+SXNEb3VibGUoKSkgU2V0KHZhbHVlLT5HZXREb3VibGUoKSk7Cit9CisKK2Jvb2wgQ0FOSmFndWFyOjpJc01vZGVQSUQoQ0FOU3BlZWRDb250cm9sbGVyOjpDb250cm9sTW9kZSBtb2RlKSBjb25zdCB7CisgIHJldHVybiBtb2RlID09IGtDdXJyZW50IHx8IG1vZGUgPT0ga1NwZWVkIHx8IG1vZGUgPT0ga1Bvc2l0aW9uOworfQorCit2b2lkIENBTkphZ3Vhcjo6VXBkYXRlVGFibGUoKSB7CisgIGlmIChtX3RhYmxlICE9IG51bGxwdHIpIHsKKyAgICBtX3RhYmxlLT5QdXRTdHJpbmcoIn5UWVBFfiIsICJDQU5TcGVlZENvbnRyb2xsZXIiKTsKKyAgICBtX3RhYmxlLT5QdXRTdHJpbmcoIlR5cGUiLCAiQ0FOSmFndWFyIik7CisgICAgbV90YWJsZS0+UHV0U3RyaW5nKCJNb2RlIiwgR2V0TW9kZU5hbWUobV9jb250cm9sTW9kZSkpOworICAgIGlmIChJc01vZGVQSUQobV9jb250cm9sTW9kZSkpIHsKKyAgICAgICAgbV90YWJsZS0+UHV0TnVtYmVyKCJwIiwgR2V0UCgpKTsKKyAgICAgICAgbV90YWJsZS0+UHV0TnVtYmVyKCJpIiwgR2V0SSgpKTsKKyAgICAgICAgbV90YWJsZS0+UHV0TnVtYmVyKCJkIiwgR2V0RCgpKTsKKyAgICB9CisgICAgbV90YWJsZS0+UHV0Qm9vbGVhbigiRW5hYmxlZCIsIG1fY29udHJvbEVuYWJsZWQpOworICAgIG1fdGFibGUtPlB1dE51bWJlcigiVmFsdWUiLCBHZXQoKSk7CisgIH0KK30KKwordm9pZCBDQU5KYWd1YXI6OlN0YXJ0TGl2ZVdpbmRvd01vZGUoKSB7CisgIGlmIChtX3RhYmxlICE9IG51bGxwdHIpIHsKKyAgICBtX3RhYmxlLT5BZGRUYWJsZUxpc3RlbmVyKHRoaXMsIHRydWUpOworICB9Cit9CisKK3ZvaWQgQ0FOSmFndWFyOjpTdG9wTGl2ZVdpbmRvd01vZGUoKSB7CisgIGlmIChtX3RhYmxlICE9IG51bGxwdHIpIHsKKyAgICBtX3RhYmxlLT5SZW1vdmVUYWJsZUxpc3RlbmVyKHRoaXMpOworICB9Cit9CisKK3N0ZDo6c3RyaW5nIENBTkphZ3Vhcjo6R2V0U21hcnREYXNoYm9hcmRUeXBlKCkgY29uc3QgeworICByZXR1cm4gIkNBTlNwZWVkQ29udHJvbGxlciI7Cit9CisKK3ZvaWQgQ0FOSmFndWFyOjpJbml0VGFibGUoc3RkOjpzaGFyZWRfcHRyPElUYWJsZT4gc3ViVGFibGUpIHsKKyAgbV90YWJsZSA9IHN1YlRhYmxlOworICBVcGRhdGVUYWJsZSgpOworfQorCitzdGQ6OnNoYXJlZF9wdHI8SVRhYmxlPiBDQU5KYWd1YXI6OkdldFRhYmxlKCkgY29uc3QgeyByZXR1cm4gbV90YWJsZTsgfQpkaWZmIC0tZ2l0IGEvd3BpbGliYy9BdGhlbmEvc3JjL0NBTlRhbG9uLmNwcCBiL3dwaWxpYmMvQXRoZW5hL3NyYy9DQU5UYWxvbi5jcHAKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZjkzNzIxMgotLS0gL2Rldi9udWxsCisrKyBiL3dwaWxpYmMvQXRoZW5hL3NyYy9DQU5UYWxvbi5jcHAKQEAgLTAsMCArMSwxNzUwIEBACisvKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qLworLyogQ29weXJpZ2h0IChjKSBGSVJTVCAyMDE0LiBBbGwgUmlnaHRzIFJlc2VydmVkLiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKi8KKy8qIE9wZW4gU291cmNlIFNvZnR3YXJlIC0gbWF5IGJlIG1vZGlmaWVkIGFuZCBzaGFyZWQgYnkgRlJDIHRlYW1zLiBUaGUgY29kZSAgICovCisvKiBtdXN0IGJlIGFjY29tcGFuaWVkIGJ5IHRoZSBGSVJTVCBCU0QgbGljZW5zZSBmaWxlIGluICQoV0lORF9CQVNFKS9XUElMaWIuICAqLworLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi8KKworI2luY2x1ZGUgIkNBTlRhbG9uLmgiCisjaW5jbHVkZSAiV1BJRXJyb3JzLmgiCisjaW5jbHVkZSA8dW5pc3RkLmg+ICAvLyB1c2xlZXAKKyNpbmNsdWRlIDxzc3RyZWFtPgorLyoqCisgKiBOdW1iZXIgb2YgYWRjIGVuZ2luZWVyaW5nIHVuaXRzIHBlciAwIHRvIDMuM1Ygc3dlZXAuCisgKiBUaGlzIGlzIG5lY2Vzc2FyeSBmb3Igc2NhbGluZyBBbmFsb2cgUG9zaXRpb24gaW4gcm90YXRpb25zL1JQTS4KKyAqLworY29uc3QgZG91YmxlIGtOYXRpdmVBZGNVbml0c1BlclJvdGF0aW9uID0gMTAyNC4wOworLyoqCisgKiBOdW1iZXIgb2YgcHVsc2Ugd2lkdGggZW5naW5lZXJpbmcgdW5pdHMgcGVyIGZ1bGwgcm90YXRpb24uCisgKiBUaGlzIGlzIG5lY2Vzc2FyeSBmb3Igc2NhbGluZyBQdWxzZSBXaWR0aCBEZWNvZGVkIFBvc2l0aW9uIGluIHJvdGF0aW9ucy9SUE0uCisgKi8KK2NvbnN0IGRvdWJsZSBrTmF0aXZlUHdkVW5pdHNQZXJSb3RhdGlvbiA9IDQwOTYuMDsKKy8qKgorICogTnVtYmVyIG9mIG1pbnV0ZXMgcGVyIDEwMG1zIHVuaXQuICBVc2VmdWwgZm9yIHNjYWxpbmcgdmVsb2NpdGllcworICogbWVhc3VyZWQgYnkgVGFsb24ncyAxMDBtcyB0aW1lYmFzZSB0byByb3RhdGlvbnMgcGVyIG1pbnV0ZS4KKyAqLworY29uc3QgZG91YmxlIGtNaW51dGVzUGVyMTAwbXNVbml0ID0gMS4wLzYwMC4wOworCisvKioKKyAqIENvbnN0cnVjdG9yIGZvciB0aGUgQ0FOVGFsb24gZGV2aWNlLgorICogQHBhcmFtIGRldmljZU51bWJlciBUaGUgQ0FOIElEIG9mIHRoZSBUYWxvbiBTUlgKKyAqLworQ0FOVGFsb246OkNBTlRhbG9uKGludCBkZXZpY2VOdW1iZXIpCisgICAgOiBtX2RldmljZU51bWJlcihkZXZpY2VOdW1iZXIpLAorICAgICAgbV9pbXBsKG5ldyBDYW5UYWxvblNSWChkZXZpY2VOdW1iZXIpKSwKKyAgICAgIG1fc2FmZXR5SGVscGVyKG5ldyBNb3RvclNhZmV0eUhlbHBlcih0aGlzKSkgeworICBBcHBseUNvbnRyb2xNb2RlKG1fY29udHJvbE1vZGUpOworICBtX2ltcGwtPlNldFByb2ZpbGVTbG90U2VsZWN0KG1fcHJvZmlsZSk7CisgIG1faXNJbnZlcnRlZCA9IGZhbHNlOworfQorLyoqCisgKiBDb25zdHJ1Y3RvciBmb3IgdGhlIENBTlRhbG9uIGRldmljZS4KKyAqIEBwYXJhbSBkZXZpY2VOdW1iZXIgVGhlIENBTiBJRCBvZiB0aGUgVGFsb24gU1JYCisgKiBAcGFyYW0gY29udHJvbFBlcmlvZE1zIFRoZSBwZXJpb2QgaW4gbXMgdG8gc2VuZCB0aGUgQ0FOIGNvbnRyb2wgZnJhbWUuCisgKiAgICAgICAgICAgICAgICAgICAgICAgIFBlcmlvZCBpcyBib3VuZGVkIHRvIFsxbXMsOTVtc10uCisgKi8KK0NBTlRhbG9uOjpDQU5UYWxvbihpbnQgZGV2aWNlTnVtYmVyLCBpbnQgY29udHJvbFBlcmlvZE1zKQorICAgIDogbV9kZXZpY2VOdW1iZXIoZGV2aWNlTnVtYmVyKSwKKyAgICAgIG1faW1wbChuZXcgQ2FuVGFsb25TUlgoZGV2aWNlTnVtYmVyLGNvbnRyb2xQZXJpb2RNcykpLAorICAgICAgbV9zYWZldHlIZWxwZXIobmV3IE1vdG9yU2FmZXR5SGVscGVyKHRoaXMpKSB7CisgIEFwcGx5Q29udHJvbE1vZGUobV9jb250cm9sTW9kZSk7CisgIG1faW1wbC0+U2V0UHJvZmlsZVNsb3RTZWxlY3QobV9wcm9maWxlKTsKK30KKworQ0FOVGFsb246On5DQU5UYWxvbigpIHsKKyAgaWYgKG1fdGFibGUgIT0gbnVsbHB0cikgbV90YWJsZS0+UmVtb3ZlVGFibGVMaXN0ZW5lcih0aGlzKTsKKyAgaWYgKG1faGFzQmVlbk1vdmVkKSByZXR1cm47CisgIERpc2FibGUoKTsKK30KKworLyoqCisqIFdyaXRlIG91dCB0aGUgUElEIHZhbHVlIGFzIHNlZW4gaW4gdGhlIFBJRE91dHB1dCBiYXNlIG9iamVjdC4KKyoKKyogQGRlcHJlY2F0ZWQgQ2FsbCBTZXQgaW5zdGVhZC4KKyoKKyogQHBhcmFtIG91dHB1dCBXcml0ZSBvdXQgdGhlIFBlcmNlbnRWYnVzIHZhbHVlIGFzIHdhcyBjb21wdXRlZCBieSB0aGUKKyogUElEQ29udHJvbGxlcgorKi8KK3ZvaWQgQ0FOVGFsb246OlBJRFdyaXRlKGZsb2F0IG91dHB1dCkgeworICBpZiAoR2V0Q29udHJvbE1vZGUoKSA9PSBrUGVyY2VudFZidXMpIHsKKyAgICBTZXQob3V0cHV0KTsKKyAgfSBlbHNlIHsKKyAgICB3cGlfc2V0V1BJRXJyb3JXaXRoQ29udGV4dChJbmNvbXBhdGlibGVNb2RlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJQSUQgb25seSBzdXBwb3J0ZWQgaW4gUGVyY2VudFZidXMgbW9kZSIpOworICB9Cit9CisKKy8qKgorICogUmV0cmlldmUgdGhlIGN1cnJlbnQgc2Vuc29yIHZhbHVlLiBFcXVpdmFsZW50IHRvIEdldCgpLgorICoKKyAqIEByZXR1cm4gVGhlIGN1cnJlbnQgc2Vuc29yIHZhbHVlIG9mIHRoZSBUYWxvbi4KKyAqLworZG91YmxlIENBTlRhbG9uOjpQSURHZXQoKSB7IHJldHVybiBHZXQoKTsgfQorCisvKioKKyAqIEdldHMgdGhlIGN1cnJlbnQgc3RhdHVzIG9mIHRoZSBUYWxvbiAodXN1YWxseSBhIHNlbnNvciB2YWx1ZSkuCisgKgorICogSW4gQ3VycmVudCBtb2RlOiByZXR1cm5zIG91dHB1dCBjdXJyZW50LgorICogSW4gU3BlZWQgbW9kZTogcmV0dXJucyBjdXJyZW50IHNwZWVkLgorICogSW4gUG9zaXRpb24gbW9kZTogcmV0dXJucyBjdXJyZW50IHNlbnNvciBwb3NpdGlvbi4KKyAqIEluIFBlcmNlbnRWYnVzIGFuZCBGb2xsb3dlciBtb2RlczogcmV0dXJucyBjdXJyZW50IGFwcGxpZWQgdGhyb3R0bGUuCisgKgorICogQHJldHVybiBUaGUgY3VycmVudCBzZW5zb3IgdmFsdWUgb2YgdGhlIFRhbG9uLgorICovCitmbG9hdCBDQU5UYWxvbjo6R2V0KCkgY29uc3QgeworICBpbnQgdmFsdWU7CisgIHN3aXRjaCAobV9jb250cm9sTW9kZSkgeworICAgIGNhc2Uga1ZvbHRhZ2U6CisgICAgICByZXR1cm4gR2V0T3V0cHV0Vm9sdGFnZSgpOworICAgIGNhc2Uga0N1cnJlbnQ6CisgICAgICByZXR1cm4gR2V0T3V0cHV0Q3VycmVudCgpOworICAgIGNhc2Uga1NwZWVkOgorICAgICAgbV9pbXBsLT5HZXRTZW5zb3JWZWxvY2l0eSh2YWx1ZSk7CisgICAgICByZXR1cm4gU2NhbGVOYXRpdmVVbml0c1RvUnBtKG1fZmVlZGJhY2tEZXZpY2UsIHZhbHVlKTsKKyAgICBjYXNlIGtQb3NpdGlvbjoKKyAgICAgIG1faW1wbC0+R2V0U2Vuc29yUG9zaXRpb24odmFsdWUpOworICAgICAgcmV0dXJuIFNjYWxlTmF0aXZlVW5pdHNUb1JvdGF0aW9ucyhtX2ZlZWRiYWNrRGV2aWNlLCB2YWx1ZSk7CisgICAgY2FzZSBrUGVyY2VudFZidXM6CisgICAgY2FzZSBrRm9sbG93ZXI6CisgICAgZGVmYXVsdDoKKyAgICAgIG1faW1wbC0+R2V0QXBwbGllZFRocm90dGxlKHZhbHVlKTsKKyAgICAgIHJldHVybiAoZmxvYXQpdmFsdWUgLyAxMDIzLjA7CisgIH0KK30KKworLyoqCisgKiBTZXRzIHRoZSBhcHByb3ByaWF0ZSBvdXRwdXQgb24gdGhlIHRhbG9uLCBkZXBlbmRpbmcgb24gdGhlIG1vZGUuCisgKgorICogSW4gUGVyY2VudFZidXMsIHRoZSBvdXRwdXQgaXMgYmV0d2VlbiAtMS4wIGFuZCAxLjAsIHdpdGggMC4wIGFzIHN0b3BwZWQuCisgKiBJbiBWb2x0YWdlIG1vZGUsIG91dHB1dCB2YWx1ZSBpcyBpbiB2b2x0cy4KKyAqIEluIEN1cnJlbnQgbW9kZSwgb3V0cHV0IHZhbHVlIGlzIGluIGFtcGVyZXMuCisgKiBJbiBTcGVlZCBtb2RlLCBvdXRwdXQgdmFsdWUgaXMgaW4gcG9zaXRpb24gY2hhbmdlIC8gMTBtcy4KKyAqIEluIFBvc2l0aW9uIG1vZGUsIG91dHB1dCB2YWx1ZSBpcyBpbiBlbmNvZGVyIHRpY2tzIG9yIGFuIGFuYWxvZyB2YWx1ZSwKKyAqICAgZGVwZW5kaW5nIG9uIHRoZSBzZW5zb3IuCisgKiBJbiBGb2xsb3dlciBtb2RlLCB0aGUgb3V0cHV0IHZhbHVlIGlzIHRoZSBpbnRlZ2VyIGRldmljZSBJRCBvZiB0aGUgdGFsb24gdG8KKyAqIGR1cGxpY2F0ZS4KKyAqCisgKiBAcGFyYW0gb3V0cHV0VmFsdWUgVGhlIHNldHBvaW50IHZhbHVlLCBhcyBkZXNjcmliZWQgYWJvdmUuCisgKiBAc2VlIFNlbGVjdFByb2ZpbGVTbG90IHRvIGNob29zZSBiZXR3ZWVuIHRoZSB0d28gc2V0cyBvZiBnYWlucy4KKyAqLwordm9pZCBDQU5UYWxvbjo6U2V0KGZsb2F0IHZhbHVlLCB1aW50OF90IHN5bmNHcm91cCkgeworICAvKiBmZWVkIHNhZmV0eSBoZWxwZXIgc2luY2UgY2FsbGVyIGp1c3QgdXBkYXRlZCBvdXIgb3V0cHV0ICovCisgIG1fc2FmZXR5SGVscGVyLT5GZWVkKCk7CisgIGlmIChtX2NvbnRyb2xFbmFibGVkKSB7CisgICAgbV9zZXRQb2ludCA9IHZhbHVlOyAgLyogY2FjaGUgc2V0IHBvaW50IGZvciBHZXRTZXRwb2ludCgpICovCisgICAgQ1RSX0NvZGUgc3RhdHVzID0gQ1RSX09LQVk7CisgICAgc3dpdGNoIChtX2NvbnRyb2xNb2RlKSB7CisgICAgICBjYXNlIENBTlNwZWVkQ29udHJvbGxlcjo6a1BlcmNlbnRWYnVzOiB7CisgICAgICAgIG1faW1wbC0+U2V0KG1faXNJbnZlcnRlZCA/IC12YWx1ZSA6IHZhbHVlKTsKKyAgICAgICAgc3RhdHVzID0gQ1RSX09LQVk7CisgICAgICB9IGJyZWFrOworICAgICAgY2FzZSBDQU5TcGVlZENvbnRyb2xsZXI6OmtGb2xsb3dlcjogeworICAgICAgICBzdGF0dXMgPSBtX2ltcGwtPlNldERlbWFuZCgoaW50KXZhbHVlKTsKKyAgICAgIH0gYnJlYWs7CisgICAgICBjYXNlIENBTlNwZWVkQ29udHJvbGxlcjo6a1ZvbHRhZ2U6IHsKKyAgICAgICAgLy8gVm9sdGFnZSBpcyBhbiA4LjggZml4ZWQgcG9pbnQgbnVtYmVyLgorICAgICAgICBpbnQgdm9sdHMgPSBpbnQoKG1faXNJbnZlcnRlZCA/IC12YWx1ZSA6IHZhbHVlKSAqIDI1Nik7CisgICAgICAgIHN0YXR1cyA9IG1faW1wbC0+U2V0RGVtYW5kKHZvbHRzKTsKKyAgICAgIH0gYnJlYWs7CisgICAgICBjYXNlIENBTlNwZWVkQ29udHJvbGxlcjo6a1NwZWVkOgorICAgICAgICAvKiBpZiB0aGUgY2FsbGVyIGhhcyBwcm92aWRlZCBzY2FsaW5nIGluZm8sIGFwcGx5IGl0ICovCisgICAgICAgIHN0YXR1cyA9IG1faW1wbC0+U2V0RGVtYW5kKFNjYWxlVmVsb2NpdHlUb05hdGl2ZVVuaXRzKG1fZmVlZGJhY2tEZXZpY2UsIG1faXNJbnZlcnRlZCA/IC12YWx1ZSA6IHZhbHVlKSk7CisgICAgICAgIGJyZWFrOworICAgICAgY2FzZSBDQU5TcGVlZENvbnRyb2xsZXI6OmtQb3NpdGlvbjoKKyAgICAgICAgc3RhdHVzID0gbV9pbXBsLT5TZXREZW1hbmQoU2NhbGVSb3RhdGlvbnNUb05hdGl2ZVVuaXRzKG1fZmVlZGJhY2tEZXZpY2UsIHZhbHVlKSk7CisgICAgICAgIGJyZWFrOworICAgICAgY2FzZSBDQU5TcGVlZENvbnRyb2xsZXI6OmtDdXJyZW50OiB7CisgICAgICAgIGRvdWJsZSBtaWxsaWFtcGVyZXMgPSAobV9pc0ludmVydGVkID8gLXZhbHVlIDogdmFsdWUpICogMTAwMC4wOyAvKiBtQSovCisgICAgICAgIHN0YXR1cyA9IG1faW1wbC0+U2V0RGVtYW5kKG1pbGxpYW1wZXJlcyk7CisgICAgICB9IGJyZWFrOworICAgICAgZGVmYXVsdDoKKyAgICAgICAgd3BpX3NldFdQSUVycm9yV2l0aENvbnRleHQoCisgICAgICAgICAgICBJbmNvbXBhdGlibGVNb2RlLAorICAgICAgICAgICAgIlRoZSBDQU4gVGFsb24gZG9lcyBub3Qgc3VwcG9ydCB0aGlzIGNvbnRyb2wgbW9kZS4iKTsKKyAgICAgICAgYnJlYWs7CisgICAgfQorICAgIGlmIChzdGF0dXMgIT0gQ1RSX09LQVkpIHsKKyAgICAgIHdwaV9zZXRFcnJvcldpdGhDb250ZXh0KHN0YXR1cywgZ2V0SEFMRXJyb3JNZXNzYWdlKHN0YXR1cykpOworICAgIH0KKworICAgIHN0YXR1cyA9IG1faW1wbC0+U2V0TW9kZVNlbGVjdChtX3NlbmRNb2RlKTsKKworICAgIGlmIChzdGF0dXMgIT0gQ1RSX09LQVkpIHsKKyAgICAgIHdwaV9zZXRFcnJvcldpdGhDb250ZXh0KHN0YXR1cywgZ2V0SEFMRXJyb3JNZXNzYWdlKHN0YXR1cykpOworICAgIH0KKyAgfQorfQorCisvKioKKyAqIFNldHMgdGhlIHNldHBvaW50IHRvIHZhbHVlLiBFcXVpdmFsZW50IHRvIFNldCgpLgorICovCit2b2lkIENBTlRhbG9uOjpTZXRTZXRwb2ludChmbG9hdCB2YWx1ZSkgeyBTZXQodmFsdWUpOyB9CisKKy8qKgorICogUmVzZXRzIHRoZSBpbnRlZ3JhbCB0ZXJtIGFuZCBkaXNhYmxlcyB0aGUgY29udHJvbGxlci4KKyAqLwordm9pZCBDQU5UYWxvbjo6UmVzZXQoKSB7CisgIENsZWFySWFjY3VtKCk7CisgIERpc2FibGUoKTsKK30KKworLyoqCisgKiBEaXNhYmxlcyBjb250cm9sIG9mIHRoZSB0YWxvbiwgY2F1c2luZyB0aGUgbW90b3IgdG8gYnJha2Ugb3IgY29hc3QKKyAqIGRlcGVuZGluZyBvbiBpdHMgbW9kZSAoc2VlIHRoZSBUYWxvbiBTUlggU29mdHdhcmUgUmVmZXJlbmNlIG1hbnVhbAorICogZm9yIG1vcmUgaW5mb3JtYXRpb24pLgorICovCit2b2lkIENBTlRhbG9uOjpEaXNhYmxlKCkgeworICBtX2ltcGwtPlNldE1vZGVTZWxlY3QoKGludClDQU5UYWxvbjo6a0Rpc2FibGVkKTsKKyAgbV9jb250cm9sRW5hYmxlZCA9IGZhbHNlOworfQorCisvKioKKyAqIEVuYWJsZXMgY29udHJvbCBvZiB0aGUgVGFsb24sIGFsbG93aW5nIHRoZSBtb3RvciB0byBtb3ZlLgorICovCit2b2lkIENBTlRhbG9uOjpFbmFibGVDb250cm9sKCkgeworICBTZXRDb250cm9sTW9kZShtX2NvbnRyb2xNb2RlKTsKKyAgbV9jb250cm9sRW5hYmxlZCA9IHRydWU7Cit9CisKKy8qKgorICogRW5hYmxlcyBjb250cm9sIG9mIHRoZSBUYWxvbiwgYWxsb3dpbmcgdGhlIG1vdG9yIHRvIG1vdmUuCisgKi8KK3ZvaWQgQ0FOVGFsb246OkVuYWJsZSgpIHsgRW5hYmxlQ29udHJvbCgpOyB9CisKKy8qKgorICogQHJldHVybiBXaGV0aGVyIHRoZSBUYWxvbiBpcyBjdXJyZW50bHkgZW5hYmxlZC4KKyAqLworYm9vbCBDQU5UYWxvbjo6SXNDb250cm9sRW5hYmxlZCgpIGNvbnN0IHsgcmV0dXJuIG1fY29udHJvbEVuYWJsZWQ7IH0KKworLyoqCisgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIFRhbG9uIGlzIGN1cnJlbnRseSBlbmFibGVkLgorICovCitib29sIENBTlRhbG9uOjpJc0VuYWJsZWQoKSBjb25zdCB7IHJldHVybiBJc0NvbnRyb2xFbmFibGVkKCk7IH0KKworLyoqCisgKiBAcGFyYW0gcCBQcm9wb3J0aW9uYWwgY29uc3RhbnQgdG8gdXNlIGluIFBJRCBsb29wLgorICogQHNlZSBTZWxlY3RQcm9maWxlU2xvdCB0byBjaG9vc2UgYmV0d2VlbiB0aGUgdHdvIHNldHMgb2YgZ2FpbnMuCisgKi8KK3ZvaWQgQ0FOVGFsb246OlNldFAoZG91YmxlIHApIHsKKyAgQ1RSX0NvZGUgc3RhdHVzID0gbV9pbXBsLT5TZXRQZ2FpbihtX3Byb2ZpbGUsIHApOworICBpZiAoc3RhdHVzICE9IENUUl9PS0FZKSB7CisgICAgd3BpX3NldEVycm9yV2l0aENvbnRleHQoc3RhdHVzLCBnZXRIQUxFcnJvck1lc3NhZ2Uoc3RhdHVzKSk7CisgIH0KK30KKworLyoqCisgKiBTZXQgdGhlIGludGVncmF0aW9uIGNvbnN0YW50IG9mIHRoZSBjdXJyZW50bHkgc2VsZWN0ZWQgcHJvZmlsZS4KKyAqCisgKiBAcGFyYW0gaSBJbnRlZ3JhdGlvbiBjb25zdGFudCBmb3IgdGhlIGN1cnJlbnRseSBzZWxlY3RlZCBQSUQgcHJvZmlsZS4KKyAqIEBzZWUgU2VsZWN0UHJvZmlsZVNsb3QgdG8gY2hvb3NlIGJldHdlZW4gdGhlIHR3byBzZXRzIG9mIGdhaW5zLgorICovCit2b2lkIENBTlRhbG9uOjpTZXRJKGRvdWJsZSBpKSB7CisgIENUUl9Db2RlIHN0YXR1cyA9IG1faW1wbC0+U2V0SWdhaW4obV9wcm9maWxlLCBpKTsKKyAgaWYgKHN0YXR1cyAhPSBDVFJfT0tBWSkgeworICAgIHdwaV9zZXRFcnJvcldpdGhDb250ZXh0KHN0YXR1cywgZ2V0SEFMRXJyb3JNZXNzYWdlKHN0YXR1cykpOworICB9Cit9CisKKy8qKgorICogU2V0IHRoZSBkZXJpdmF0aXZlIGNvbnN0YW50IG9mIHRoZSBjdXJyZW50bHkgc2VsZWN0ZWQgcHJvZmlsZS4KKyAqCisgKiBAcGFyYW0gZCBEZXJpdmF0aXZlIGNvbnN0YW50IGZvciB0aGUgY3VycmVudGx5IHNlbGVjdGVkIFBJRCBwcm9maWxlLgorICogQHNlZSBTZWxlY3RQcm9maWxlU2xvdCB0byBjaG9vc2UgYmV0d2VlbiB0aGUgdHdvIHNldHMgb2YgZ2FpbnMuCisgKi8KK3ZvaWQgQ0FOVGFsb246OlNldEQoZG91YmxlIGQpIHsKKyAgQ1RSX0NvZGUgc3RhdHVzID0gbV9pbXBsLT5TZXREZ2FpbihtX3Byb2ZpbGUsIGQpOworICBpZiAoc3RhdHVzICE9IENUUl9PS0FZKSB7CisgICAgd3BpX3NldEVycm9yV2l0aENvbnRleHQoc3RhdHVzLCBnZXRIQUxFcnJvck1lc3NhZ2Uoc3RhdHVzKSk7CisgIH0KK30KKy8qKgorICogU2V0IHRoZSBmZWVkZm9yd2FyZCB2YWx1ZSBvZiB0aGUgY3VycmVudGx5IHNlbGVjdGVkIHByb2ZpbGUuCisgKgorICogQHBhcmFtIGYgRmVlZGZvcndhcmQgY29uc3RhbnQgZm9yIHRoZSBjdXJyZW50bHkgc2VsZWN0ZWQgUElEIHByb2ZpbGUuCisgKiBAc2VlIFNlbGVjdFByb2ZpbGVTbG90IHRvIGNob29zZSBiZXR3ZWVuIHRoZSB0d28gc2V0cyBvZiBnYWlucy4KKyAqLwordm9pZCBDQU5UYWxvbjo6U2V0Rihkb3VibGUgZikgeworICBDVFJfQ29kZSBzdGF0dXMgPSBtX2ltcGwtPlNldEZnYWluKG1fcHJvZmlsZSwgZik7CisgIGlmIChzdGF0dXMgIT0gQ1RSX09LQVkpIHsKKyAgICB3cGlfc2V0RXJyb3JXaXRoQ29udGV4dChzdGF0dXMsIGdldEhBTEVycm9yTWVzc2FnZShzdGF0dXMpKTsKKyAgfQorfQorLyoqCisgKiBTZXQgdGhlIEl6b25lIHRvIGEgbm9uemVybyB2YWx1ZSB0byBhdXRvIGNsZWFyIHRoZSBpbnRlZ3JhbCBhY2N1bXVsYXRvcgorICogICAgIHdoZW4gdGhlIGFic29sdXRlIHZhbHVlIG9mIENsb3NlTG9vcEVycm9yIGV4Y2VlZHMgSXpvbmUuCisgKgorICogQHNlZSBTZWxlY3RQcm9maWxlU2xvdCB0byBjaG9vc2UgYmV0d2VlbiB0aGUgdHdvIHNldHMgb2YgZ2FpbnMuCisgKi8KK3ZvaWQgQ0FOVGFsb246OlNldEl6b25lKHVuc2lnbmVkIGl6KSB7CisgIENUUl9Db2RlIHN0YXR1cyA9IG1faW1wbC0+U2V0SXpvbmUobV9wcm9maWxlLCBpeik7CisgIGlmIChzdGF0dXMgIT0gQ1RSX09LQVkpIHsKKyAgICB3cGlfc2V0RXJyb3JXaXRoQ29udGV4dChzdGF0dXMsIGdldEhBTEVycm9yTWVzc2FnZShzdGF0dXMpKTsKKyAgfQorfQorLyoqCisgKiBTUlggaGFzIHR3byBhdmFpbGFibGUgc2xvdHMgZm9yIFBJRC4KKyAqIEBwYXJhbSBzbG90SWR4IG9uZSBvciB6ZXJvIGRlcGVuZGluZyBvbiB3aGljaCBzbG90IGNhbGxlciB3YW50cy4KKyAqLwordm9pZCBDQU5UYWxvbjo6U2VsZWN0UHJvZmlsZVNsb3QoaW50IHNsb3RJZHgpIHsKKyAgbV9wcm9maWxlID0gKHNsb3RJZHggPT0gMCkgPyAwIDogMTsgLyogb25seSBnZXQgdHdvIHNsb3RzIGZvciBub3cgKi8KKyAgQ1RSX0NvZGUgc3RhdHVzID0gbV9pbXBsLT5TZXRQcm9maWxlU2xvdFNlbGVjdChtX3Byb2ZpbGUpOworICBpZiAoc3RhdHVzICE9IENUUl9PS0FZKSB7CisgICAgd3BpX3NldEVycm9yV2l0aENvbnRleHQoc3RhdHVzLCBnZXRIQUxFcnJvck1lc3NhZ2Uoc3RhdHVzKSk7CisgIH0KK30KKy8qKgorICogU2V0cyBjb250cm9sIHZhbHVlcyBmb3IgY2xvc2VkIGxvb3AgY29udHJvbC4KKyAqCisgKiBAcGFyYW0gcCBQcm9wb3J0aW9uYWwgY29uc3RhbnQuCisgKiBAcGFyYW0gaSBJbnRlZ3JhdGlvbiBjb25zdGFudC4KKyAqIEBwYXJhbSBkIERpZmZlcmVudGlhbCBjb25zdGFudC4KKyAqIFRoaXMgZnVuY3Rpb24gZG9lcyBub3QgbW9kaWZ5IEYtZ2Fpbi4gIENvbnNpZGVyYWJsZSBwYXNzaW5nIGEgemVybyBmb3IgZgorICogdXNpbmcKKyAqIHRoZSBmb3VyLXBhcmFtZXRlciBmdW5jdGlvbi4KKyAqLwordm9pZCBDQU5UYWxvbjo6U2V0UElEKGRvdWJsZSBwLCBkb3VibGUgaSwgZG91YmxlIGQpIHsKKyAgU2V0UChwKTsKKyAgU2V0SShpKTsKKyAgU2V0RChkKTsKK30KKy8qKgorICogU2V0cyBjb250cm9sIHZhbHVlcyBmb3IgY2xvc2VkIGxvb3AgY29udHJvbC4KKyAqCisgKiBAcGFyYW0gcCBQcm9wb3J0aW9uYWwgY29uc3RhbnQuCisgKiBAcGFyYW0gaSBJbnRlZ3JhdGlvbiBjb25zdGFudC4KKyAqIEBwYXJhbSBkIERpZmZlcmVudGlhbCBjb25zdGFudC4KKyAqIEBwYXJhbSBmIEZlZWRmb3J3YXJkIGNvbnN0YW50LgorICovCit2b2lkIENBTlRhbG9uOjpTZXRQSUQoZG91YmxlIHAsIGRvdWJsZSBpLCBkb3VibGUgZCwgZG91YmxlIGYpIHsKKyAgU2V0UChwKTsKKyAgU2V0SShpKTsKKyAgU2V0RChkKTsKKyAgU2V0RihmKTsKK30KKy8qKgorICogU2VsZWN0IHRoZSBmZWVkYmFjayBkZXZpY2UgdG8gdXNlIGluIGNsb3NlZC1sb29wCisgKi8KK3ZvaWQgQ0FOVGFsb246OlNldEZlZWRiYWNrRGV2aWNlKEZlZWRiYWNrRGV2aWNlIGZlZWRiYWNrRGV2aWNlKSB7CisgIC8qIHNhdmUgdGhlIHNlbGVjdGlvbiBzbyB0aGF0IGZ1dHVyZSBzZXR0ZXJzL2dldHRlcnMga25vdyB3aGljaCBzY2FsYXJzIHRvIGFwcGx5ICovCisgIG1fZmVlZGJhY2tEZXZpY2UgPSBmZWVkYmFja0RldmljZTsKKyAgLyogcGFzcyBmZWVkYmFjayB0byBhY3R1YWwgQ0FOIGZyYW1lICovCisgIENUUl9Db2RlIHN0YXR1cyA9IG1faW1wbC0+U2V0RmVlZGJhY2tEZXZpY2VTZWxlY3QoKGludClmZWVkYmFja0RldmljZSk7CisgIGlmIChzdGF0dXMgIT0gQ1RSX09LQVkpIHsKKyAgICB3cGlfc2V0RXJyb3JXaXRoQ29udGV4dChzdGF0dXMsIGdldEhBTEVycm9yTWVzc2FnZShzdGF0dXMpKTsKKyAgfQorfQorLyoqCisgKiBTZWxlY3QgdGhlIGZlZWRiYWNrIGRldmljZSB0byB1c2UgaW4gY2xvc2VkLWxvb3AKKyAqLwordm9pZCBDQU5UYWxvbjo6U2V0U3RhdHVzRnJhbWVSYXRlTXMoU3RhdHVzRnJhbWVSYXRlIHN0YXRlRnJhbWUsIGludCBwZXJpb2RNcykgeworICBDVFJfQ29kZSBzdGF0dXMgPSBtX2ltcGwtPlNldFN0YXR1c0ZyYW1lUmF0ZSgoaW50KXN0YXRlRnJhbWUsIHBlcmlvZE1zKTsKKyAgaWYgKHN0YXR1cyAhPSBDVFJfT0tBWSkgeworICAgIHdwaV9zZXRFcnJvcldpdGhDb250ZXh0KHN0YXR1cywgZ2V0SEFMRXJyb3JNZXNzYWdlKHN0YXR1cykpOworICB9Cit9CisKKy8qKgorICogR2V0IHRoZSBjdXJyZW50IHByb3BvcnRpb25hbCBjb25zdGFudC4KKyAqCisgKiBAcmV0dXJuIGRvdWJsZSBwcm9wb3J0aW9uYWwgY29uc3RhbnQgZm9yIGN1cnJlbnQgcHJvZmlsZS4KKyAqIEBzZWUgU2VsZWN0UHJvZmlsZVNsb3QgdG8gY2hvb3NlIGJldHdlZW4gdGhlIHR3byBzZXRzIG9mIGdhaW5zLgorICovCitkb3VibGUgQ0FOVGFsb246OkdldFAoKSBjb25zdCB7CisgIENhblRhbG9uU1JYOjpwYXJhbV90IHBhcmFtID0gbV9wcm9maWxlID8gQ2FuVGFsb25TUlg6OmVQcm9maWxlUGFyYW1TbG90MV9QCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDogQ2FuVGFsb25TUlg6OmVQcm9maWxlUGFyYW1TbG90MF9QOworICAvLyBVcGRhdGUgdGhlIGluZm8gaW4gbV9pbXBsLgorICBDVFJfQ29kZSBzdGF0dXMgPSBtX2ltcGwtPlJlcXVlc3RQYXJhbShwYXJhbSk7CisgIGlmIChzdGF0dXMgIT0gQ1RSX09LQVkpIHsKKyAgICB3cGlfc2V0RXJyb3JXaXRoQ29udGV4dChzdGF0dXMsIGdldEhBTEVycm9yTWVzc2FnZShzdGF0dXMpKTsKKyAgfQorICB1c2xlZXAoa0RlbGF5Rm9yU29saWNpdGVkU2lnbmFsc1VzKTsgLyogc21hbGwgeWllbGQgZm9yIGdldHRpbmcgcmVzcG9uc2UgKi8KKyAgZG91YmxlIHA7CisgIHN0YXR1cyA9IG1faW1wbC0+R2V0UGdhaW4obV9wcm9maWxlLCBwKTsKKyAgaWYgKHN0YXR1cyAhPSBDVFJfT0tBWSkgeworICAgIHdwaV9zZXRFcnJvcldpdGhDb250ZXh0KHN0YXR1cywgZ2V0SEFMRXJyb3JNZXNzYWdlKHN0YXR1cykpOworICB9CisgIHJldHVybiBwOworfQorCisvKioKKyAqIFRPRE8gZG9jdW1lbnRhdGlvbiAoc2VlIENBTkphZ3Vhci5jcHApCisgKiBAc2VlIFNlbGVjdFByb2ZpbGVTbG90IHRvIGNob29zZSBiZXR3ZWVuIHRoZSB0d28gc2V0cyBvZiBnYWlucy4KKyAqLworZG91YmxlIENBTlRhbG9uOjpHZXRJKCkgY29uc3QgeworICBDYW5UYWxvblNSWDo6cGFyYW1fdCBwYXJhbSA9IG1fcHJvZmlsZSA/IENhblRhbG9uU1JYOjplUHJvZmlsZVBhcmFtU2xvdDFfSQorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA6IENhblRhbG9uU1JYOjplUHJvZmlsZVBhcmFtU2xvdDBfSTsKKyAgLy8gVXBkYXRlIHRoZSBpbmZvIGluIG1faW1wbC4KKyAgQ1RSX0NvZGUgc3RhdHVzID0gbV9pbXBsLT5SZXF1ZXN0UGFyYW0ocGFyYW0pOworICBpZiAoc3RhdHVzICE9IENUUl9PS0FZKSB7CisgICAgd3BpX3NldEVycm9yV2l0aENvbnRleHQoc3RhdHVzLCBnZXRIQUxFcnJvck1lc3NhZ2Uoc3RhdHVzKSk7CisgIH0KKyAgdXNsZWVwKGtEZWxheUZvclNvbGljaXRlZFNpZ25hbHNVcyk7IC8qIHNtYWxsIHlpZWxkIGZvciBnZXR0aW5nIHJlc3BvbnNlICovCisKKyAgZG91YmxlIGk7CisgIHN0YXR1cyA9IG1faW1wbC0+R2V0SWdhaW4obV9wcm9maWxlLCBpKTsKKyAgaWYgKHN0YXR1cyAhPSBDVFJfT0tBWSkgeworICAgIHdwaV9zZXRFcnJvcldpdGhDb250ZXh0KHN0YXR1cywgZ2V0SEFMRXJyb3JNZXNzYWdlKHN0YXR1cykpOworICB9CisgIHJldHVybiBpOworfQorCisvKioKKyAqIFRPRE8gZG9jdW1lbnRhdGlvbiAoc2VlIENBTkphZ3Vhci5jcHApCisgKiBAc2VlIFNlbGVjdFByb2ZpbGVTbG90IHRvIGNob29zZSBiZXR3ZWVuIHRoZSB0d28gc2V0cyBvZiBnYWlucy4KKyAqLworZG91YmxlIENBTlRhbG9uOjpHZXREKCkgY29uc3QgeworICBDYW5UYWxvblNSWDo6cGFyYW1fdCBwYXJhbSA9IG1fcHJvZmlsZSA/IENhblRhbG9uU1JYOjplUHJvZmlsZVBhcmFtU2xvdDFfRAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA6IENhblRhbG9uU1JYOjplUHJvZmlsZVBhcmFtU2xvdDBfRDsKKyAgLy8gVXBkYXRlIHRoZSBpbmZvIGluIG1faW1wbC4KKyAgQ1RSX0NvZGUgc3RhdHVzID0gbV9pbXBsLT5SZXF1ZXN0UGFyYW0ocGFyYW0pOworICBpZiAoc3RhdHVzICE9IENUUl9PS0FZKSB7CisgICAgd3BpX3NldEVycm9yV2l0aENvbnRleHQoc3RhdHVzLCBnZXRIQUxFcnJvck1lc3NhZ2Uoc3RhdHVzKSk7CisgIH0KKyAgdXNsZWVwKGtEZWxheUZvclNvbGljaXRlZFNpZ25hbHNVcyk7IC8qIHNtYWxsIHlpZWxkIGZvciBnZXR0aW5nIHJlc3BvbnNlICovCisKKyAgZG91YmxlIGQ7CisgIHN0YXR1cyA9IG1faW1wbC0+R2V0RGdhaW4obV9wcm9maWxlLCBkKTsKKyAgaWYgKHN0YXR1cyAhPSBDVFJfT0tBWSkgeworICAgIHdwaV9zZXRFcnJvcldpdGhDb250ZXh0KHN0YXR1cywgZ2V0SEFMRXJyb3JNZXNzYWdlKHN0YXR1cykpOworICB9CisgIHJldHVybiBkOworfQorLyoqCisgKgorICogQHNlZSBTZWxlY3RQcm9maWxlU2xvdCB0byBjaG9vc2UgYmV0d2VlbiB0aGUgdHdvIHNldHMgb2YgZ2FpbnMuCisgKi8KK2RvdWJsZSBDQU5UYWxvbjo6R2V0RigpIGNvbnN0IHsKKyAgQ2FuVGFsb25TUlg6OnBhcmFtX3QgcGFyYW0gPSBtX3Byb2ZpbGUgPyBDYW5UYWxvblNSWDo6ZVByb2ZpbGVQYXJhbVNsb3QxX0YKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgOiBDYW5UYWxvblNSWDo6ZVByb2ZpbGVQYXJhbVNsb3QwX0Y7CisgIC8vIFVwZGF0ZSB0aGUgaW5mbyBpbiBtX2ltcGwuCisgIENUUl9Db2RlIHN0YXR1cyA9IG1faW1wbC0+UmVxdWVzdFBhcmFtKHBhcmFtKTsKKyAgaWYgKHN0YXR1cyAhPSBDVFJfT0tBWSkgeworICAgIHdwaV9zZXRFcnJvcldpdGhDb250ZXh0KHN0YXR1cywgZ2V0SEFMRXJyb3JNZXNzYWdlKHN0YXR1cykpOworICB9CisKKyAgdXNsZWVwKGtEZWxheUZvclNvbGljaXRlZFNpZ25hbHNVcyk7IC8qIHNtYWxsIHlpZWxkIGZvciBnZXR0aW5nIHJlc3BvbnNlICovCisgIGRvdWJsZSBmOworICBzdGF0dXMgPSBtX2ltcGwtPkdldEZnYWluKG1fcHJvZmlsZSwgZik7CisgIGlmIChzdGF0dXMgIT0gQ1RSX09LQVkpIHsKKyAgICB3cGlfc2V0RXJyb3JXaXRoQ29udGV4dChzdGF0dXMsIGdldEhBTEVycm9yTWVzc2FnZShzdGF0dXMpKTsKKyAgfQorICByZXR1cm4gZjsKK30KKy8qKgorICogQHNlZSBTZWxlY3RQcm9maWxlU2xvdCB0byBjaG9vc2UgYmV0d2VlbiB0aGUgdHdvIHNldHMgb2YgZ2FpbnMuCisgKi8KK2ludCBDQU5UYWxvbjo6R2V0SXpvbmUoKSBjb25zdCB7CisgIENhblRhbG9uU1JYOjpwYXJhbV90IHBhcmFtID0gbV9wcm9maWxlCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgID8gQ2FuVGFsb25TUlg6OmVQcm9maWxlUGFyYW1TbG90MV9JWm9uZQorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA6IENhblRhbG9uU1JYOjplUHJvZmlsZVBhcmFtU2xvdDBfSVpvbmU7CisgIC8vIFVwZGF0ZSB0aGUgaW5mbyBpbiBtX2ltcGwuCisgIENUUl9Db2RlIHN0YXR1cyA9IG1faW1wbC0+UmVxdWVzdFBhcmFtKHBhcmFtKTsKKyAgaWYgKHN0YXR1cyAhPSBDVFJfT0tBWSkgeworICAgIHdwaV9zZXRFcnJvcldpdGhDb250ZXh0KHN0YXR1cywgZ2V0SEFMRXJyb3JNZXNzYWdlKHN0YXR1cykpOworICB9CisgIHVzbGVlcChrRGVsYXlGb3JTb2xpY2l0ZWRTaWduYWxzVXMpOworCisgIGludCBpejsKKyAgc3RhdHVzID0gbV9pbXBsLT5HZXRJem9uZShtX3Byb2ZpbGUsIGl6KTsKKyAgaWYgKHN0YXR1cyAhPSBDVFJfT0tBWSkgeworICAgIHdwaV9zZXRFcnJvcldpdGhDb250ZXh0KHN0YXR1cywgZ2V0SEFMRXJyb3JNZXNzYWdlKHN0YXR1cykpOworICB9CisgIHJldHVybiBpejsKK30KKworLyoqCisgKiBAcmV0dXJuIHRoZSBjdXJyZW50IHNldHBvaW50OyBpZSwgd2hhdGV2ZXIgd2FzIGxhc3QgcGFzc2VkIHRvIFNldCgpLgorICovCitkb3VibGUgQ0FOVGFsb246OkdldFNldHBvaW50KCkgY29uc3QgeyByZXR1cm4gbV9zZXRQb2ludDsgfQorCisvKioKKyAqIFJldHVybnMgdGhlIHZvbHRhZ2UgY29taW5nIGluIGZyb20gdGhlIGJhdHRlcnkuCisgKgorICogQHJldHVybiBUaGUgaW5wdXQgdm9sdGFnZSBpbiB2b2x0cy4KKyAqLworZmxvYXQgQ0FOVGFsb246OkdldEJ1c1ZvbHRhZ2UoKSBjb25zdCB7CisgIGRvdWJsZSB2b2x0YWdlOworICBDVFJfQ29kZSBzdGF0dXMgPSBtX2ltcGwtPkdldEJhdHRlcnlWKHZvbHRhZ2UpOworICBpZiAoc3RhdHVzICE9IENUUl9PS0FZKSB7CisgICAgd3BpX3NldEVycm9yV2l0aENvbnRleHQoc3RhdHVzLCBnZXRIQUxFcnJvck1lc3NhZ2Uoc3RhdHVzKSk7CisgIH0KKyAgcmV0dXJuIHZvbHRhZ2U7Cit9CisKKy8qKgorICogQHJldHVybiBUaGUgdm9sdGFnZSBiZWluZyBvdXRwdXQgYnkgdGhlIFRhbG9uLCBpbiBWb2x0cy4KKyAqLworZmxvYXQgQ0FOVGFsb246OkdldE91dHB1dFZvbHRhZ2UoKSBjb25zdCB7CisgIGludCB0aHJvdHRsZTExOworICBDVFJfQ29kZSBzdGF0dXMgPSBtX2ltcGwtPkdldEFwcGxpZWRUaHJvdHRsZSh0aHJvdHRsZTExKTsKKyAgZmxvYXQgdm9sdGFnZSA9IEdldEJ1c1ZvbHRhZ2UoKSAqIChmbG9hdCh0aHJvdHRsZTExKSAvIDEwMjMuMCk7CisgIGlmIChzdGF0dXMgIT0gQ1RSX09LQVkpIHsKKyAgICB3cGlfc2V0RXJyb3JXaXRoQ29udGV4dChzdGF0dXMsIGdldEhBTEVycm9yTWVzc2FnZShzdGF0dXMpKTsKKyAgfQorICByZXR1cm4gdm9sdGFnZTsKK30KKworLyoqCisgKiAgUmV0dXJucyB0aGUgY3VycmVudCBnb2luZyB0aHJvdWdoIHRoZSBUYWxvbiwgaW4gQW1wZXJlcy4KKyAqLworZmxvYXQgQ0FOVGFsb246OkdldE91dHB1dEN1cnJlbnQoKSBjb25zdCB7CisgIGRvdWJsZSBjdXJyZW50OworCisgIENUUl9Db2RlIHN0YXR1cyA9IG1faW1wbC0+R2V0Q3VycmVudChjdXJyZW50KTsKKyAgaWYgKHN0YXR1cyAhPSBDVFJfT0tBWSkgeworICAgIHdwaV9zZXRFcnJvcldpdGhDb250ZXh0KHN0YXR1cywgZ2V0SEFMRXJyb3JNZXNzYWdlKHN0YXR1cykpOworICB9CisKKyAgcmV0dXJuIGN1cnJlbnQ7Cit9CisKKy8qKgorICogIFJldHVybnMgdGVtcGVyYXR1cmUgb2YgVGFsb24sIGluIGRlZ3JlZXMgQ2Vsc2l1cy4KKyAqLworZmxvYXQgQ0FOVGFsb246OkdldFRlbXBlcmF0dXJlKCkgY29uc3QgeworICBkb3VibGUgdGVtcDsKKworICBDVFJfQ29kZSBzdGF0dXMgPSBtX2ltcGwtPkdldFRlbXAodGVtcCk7CisgIGlmICh0ZW1wICE9IENUUl9PS0FZKSB7CisgICAgd3BpX3NldEVycm9yV2l0aENvbnRleHQoc3RhdHVzLCBnZXRIQUxFcnJvck1lc3NhZ2Uoc3RhdHVzKSk7CisgIH0KKyAgcmV0dXJuIHRlbXA7Cit9CisvKioKKyAqIFNldCB0aGUgcG9zaXRpb24gdmFsdWUgb2YgdGhlIHNlbGVjdGVkIHNlbnNvci4gIFRoaXMgaXMgdXNlZnVsIGZvciB6ZXJvLWluZworICogcXVhZHJhdHVyZSBlbmNvZGVycy4KKyAqIENvbnRpbnVvdXMgc2Vuc29ycyAobGlrZSBhbmFsb2cgZW5jb2RlcmVzKSBjYW4gYWxzbyBwYXJ0aWFsbHkgYmUgc2V0ICh0aGUKKyAqIHBvcnRpb24gb2YgdGhlIHBvc3Rpb24gYmFzZWQgb24gb3ZlcmZsb3dzKS4KKyAqLwordm9pZCBDQU5UYWxvbjo6U2V0UG9zaXRpb24oZG91YmxlIHBvcykgeworICBpbnQzMl90IG5hdGl2ZVBvcyA9IFNjYWxlUm90YXRpb25zVG9OYXRpdmVVbml0cyhtX2ZlZWRiYWNrRGV2aWNlLCBwb3MpOworICBDVFJfQ29kZSBzdGF0dXMgPSBtX2ltcGwtPlNldFNlbnNvclBvc2l0aW9uKG5hdGl2ZVBvcyk7CisgIGlmIChzdGF0dXMgIT0gQ1RSX09LQVkpIHsKKyAgICB3cGlfc2V0RXJyb3JXaXRoQ29udGV4dChzdGF0dXMsIGdldEhBTEVycm9yTWVzc2FnZShzdGF0dXMpKTsKKyAgfQorfQorLyoqCisgKiBUT0RPIGRvY3VtZW50YXRpb24gKHNlZSBDQU5KYWd1YXIuY3BwKQorICoKKyAqIEByZXR1cm4gVGhlIHBvc2l0aW9uIG9mIHRoZSBzZW5zb3IgY3VycmVudGx5IHByb3ZpZGluZyBmZWVkYmFjay4KKyAqICAgICAgIFdoZW4gdXNpbmcgYW5hbG9nIHNlbnNvcnMsIDAgdW5pdHMgY29ycmVzcG9uZHMgdG8gMFYsIDEwMjMKKyAqIHVuaXRzIGNvcnJlc3BvbmRzIHRvIDMuM1YKKyAqICAgICAgIFdoZW4gdXNpbmcgYW4gYW5hbG9nIGVuY29kZXIgKHdyYXBwaW5nIGFyb3VuZCAxMDIzID0+IDAgaXMKKyAqIHBvc3NpYmxlKSB0aGUgdW5pdHMgYXJlIHN0aWxsIDMuM1YgcGVyIDEwMjMgdW5pdHMuCisgKiAgICAgICBXaGVuIHVzaW5nIHF1YWRyYXR1cmUsIGVhY2ggdW5pdCBpcyBhIHF1YWRyYXR1cmUgZWRnZSAoNFgpCisgKiBtb2RlLgorICovCitkb3VibGUgQ0FOVGFsb246OkdldFBvc2l0aW9uKCkgY29uc3QgeworICBpbnQzMl90IHBvc2l0aW9uOworICBDVFJfQ29kZSBzdGF0dXMgPSBtX2ltcGwtPkdldFNlbnNvclBvc2l0aW9uKHBvc2l0aW9uKTsKKyAgaWYgKHN0YXR1cyAhPSBDVFJfT0tBWSkgeworICAgIHdwaV9zZXRFcnJvcldpdGhDb250ZXh0KHN0YXR1cywgZ2V0SEFMRXJyb3JNZXNzYWdlKHN0YXR1cykpOworICB9CisgIHJldHVybiBTY2FsZU5hdGl2ZVVuaXRzVG9Sb3RhdGlvbnMobV9mZWVkYmFja0RldmljZSwgcG9zaXRpb24pOworfQorLyoqCisgKiBJZiBzZW5zb3IgYW5kIG1vdG9yIGFyZSBvdXQgb2YgcGhhc2UsIHNlbnNvciBjYW4gYmUgaW52ZXJ0ZWQKKyAqIChwb3NpdGlvbiBhbmQgdmVsb2NpdHkgbXVsdGlwbGllZCBieSAtMSkuCisgKiBAc2VlIEdldFBvc2l0aW9uIGFuZCBAc2VlIEdldFNwZWVkLgorICovCit2b2lkIENBTlRhbG9uOjpTZXRTZW5zb3JEaXJlY3Rpb24oYm9vbCByZXZlcnNlU2Vuc29yKSB7CisgIENUUl9Db2RlIHN0YXR1cyA9IG1faW1wbC0+U2V0UmV2RmVlZGJhY2tTZW5zb3IocmV2ZXJzZVNlbnNvciA/IDEgOiAwKTsKKyAgaWYgKHN0YXR1cyAhPSBDVFJfT0tBWSkgeworICAgIHdwaV9zZXRFcnJvcldpdGhDb250ZXh0KHN0YXR1cywgZ2V0SEFMRXJyb3JNZXNzYWdlKHN0YXR1cykpOworICB9Cit9CisvKioKKyAqIEZsaXBzIHRoZSBzaWduIChtdWx0aXBsaWVzIGJ5IG5lZ2F0aXZlIG9uZSkgdGhlIHRocm90dGxlIHZhbHVlcyBnb2luZyBpbnRvCisgKiB0aGUgbW90b3Igb24gdGhlIHRhbG9uIGluIGNsb3NlZCBsb29wIG1vZGVzLiAgVHlwaWNhbGx5IHRoZSBhcHBsaWNhdGlvbgorICogc2hvdWxkIHVzZSBTZXRTZW5zb3JEaXJlY3Rpb24gdG8ga2VlcCBzZW5zb3IgYW5kIG1vdG9yIGluIHBoYXNlLgorICogQHNlZSBTZXRTZW5zb3JEaXJlY3Rpb24KKyAqIEhvd2V2ZXIgdGhpcyByb3V0aW5lIGlzIGhlbHBmdWwgZm9yIHJldmVyc2luZyB0aGUgbW90b3IgZGlyZWN0aW9uCisgKiB3aGVuIFRhbG9uIGlzIGluIHNsYXZlIG1vZGUsIG9yIHdoZW4gdXNpbmcgYSBzaW5nbGUtZGlyZWN0aW9uIHBvc2l0aW9uCisgKiBzZW5zb3IgaW4gYSBjbG9zZWQtbG9vcCBtb2RlLgorICoKKyAqIEBwYXJhbSByZXZlcnNlT3V0cHV0IFRydWUgaWYgbW90b3Igb3V0cHV0IHNob3VsZCBiZSBmbGlwcGVkOyBGYWxzZSBpZiBub3QuCisgKi8KK3ZvaWQgQ0FOVGFsb246OlNldENsb3NlZExvb3BPdXRwdXREaXJlY3Rpb24oYm9vbCByZXZlcnNlT3V0cHV0KSB7CisgIENUUl9Db2RlIHN0YXR1cyA9IG1faW1wbC0+U2V0UmV2TW90RHVyaW5nQ2xvc2VMb29wRW4ocmV2ZXJzZU91dHB1dCA/IDEgOiAwKTsKKyAgaWYgKHN0YXR1cyAhPSBDVFJfT0tBWSkgeworICAgIHdwaV9zZXRFcnJvcldpdGhDb250ZXh0KHN0YXR1cywgZ2V0SEFMRXJyb3JNZXNzYWdlKHN0YXR1cykpOworICB9Cit9CisvKioKKyAqIFJldHVybnMgdGhlIGN1cnJlbnQgZXJyb3IgaW4gdGhlIGNvbnRyb2xsZXIuCisgKgorICogQHJldHVybiB0aGUgZGlmZmVyZW5jZSBiZXR3ZWVuIHRoZSBzZXRwb2ludCBhbmQgdGhlIHNlbnNvciB2YWx1ZS4KKyAqLworaW50IENBTlRhbG9uOjpHZXRDbG9zZWRMb29wRXJyb3IoKSBjb25zdCB7CisgIGludCBlcnJvcjsKKyAgLyogcmV0cmlldmUgdGhlIGNsb3NlZCBsb29wIGVycm9yIGluIG5hdGl2ZSB1bml0cyAqLworICBDVFJfQ29kZSBzdGF0dXMgPSBtX2ltcGwtPkdldENsb3NlTG9vcEVycihlcnJvcik7CisgIGlmIChzdGF0dXMgIT0gQ1RSX09LQVkpIHsKKyAgICB3cGlfc2V0RXJyb3JXaXRoQ29udGV4dChzdGF0dXMsIGdldEhBTEVycm9yTWVzc2FnZShzdGF0dXMpKTsKKyAgfQorICByZXR1cm4gZXJyb3I7Cit9CisvKioKKyAqIFNldCB0aGUgYWxsb3dhYmxlIGNsb3NlZCBsb29wIGVycm9yLgorICogQHBhcmFtIGFsbG93YWJsZUNsb3NlTG9vcEVycm9yIGFsbG93YWJsZSBjbG9zZWQgbG9vcCBlcnJvciBmb3Igc2VsZWN0ZWQgcHJvZmlsZS4KKyAqICAgICAgIG1BIGZvciBDdXJlbnQgY2xvc2VkIGxvb3AuCisgKiAgICAgICBUYWxvbiBOYXRpdmUgVW5pdHMgZm9yIHBvc2l0aW9uIGFuZCB2ZWxvY2l0eS4KKyAqLwordm9pZCBDQU5UYWxvbjo6U2V0QWxsb3dhYmxlQ2xvc2VkTG9vcEVycih1aW50MzJfdCBhbGxvd2FibGVDbG9zZUxvb3BFcnJvcikKK3sKKyAgLyogZ3JhYiBwYXJhbSBlbnVtICovCisgIENhblRhbG9uU1JYOjpwYXJhbV90IHBhcmFtOworICBpZiAobV9wcm9maWxlID09IDEpIHsKKyAgICBwYXJhbSA9IENhblRhbG9uU1JYOjplUHJvZmlsZVBhcmFtU2xvdDFfQWxsb3dhYmxlQ2xvc2VkTG9vcEVycjsKKyAgfSBlbHNlIHsKKyAgICBwYXJhbSA9IENhblRhbG9uU1JYOjplUHJvZmlsZVBhcmFtU2xvdDBfQWxsb3dhYmxlQ2xvc2VkTG9vcEVycjsKKyAgfQorICAvKiBzZW5kIGFsbG93YWJsZSBjbG9zZSBsb29wIGVyIGluIG5hdGl2ZSB1bml0cyAqLworICBDb25maWdTZXRQYXJhbWV0ZXIocGFyYW0sIGFsbG93YWJsZUNsb3NlTG9vcEVycm9yKTsKK30KKworLyoqCisgKiBUT0RPIGRvY3VtZW50YXRpb24gKHNlZSBDQU5KYWd1YXIuY3BwKQorICoKKyAqIEByZXR1cm5zIFRoZSBzcGVlZCBvZiB0aGUgc2Vuc29yIGN1cnJlbnRseSBwcm92aWRpbmcgZmVlZGJhY2suCisgKgorICogVGhlIHNwZWVkIHVuaXRzIHdpbGwgYmUgaW4gdGhlIHNlbnNvcidzIG5hdGl2ZSB0aWNrcyBwZXIgMTAwbXMuCisgKgorICogRm9yIGFuYWxvZyBzZW5zb3JzLCAzLjNWIGNvcnJlc3BvbmRzIHRvIDEwMjMgdW5pdHMuCisgKiAgICAgU28gYSBzcGVlZCBvZiAyMDAgZXF1YXRlcyB0byB+MC42NDUgZFYgcGVyIDEwMG1zIG9yIDYuNDUxIGRWIHBlcgorICogc2Vjb25kLgorICogICAgIElmIHRoaXMgaXMgYW4gYW5hbG9nIGVuY29kZXIsIHRoYXQgbGlrZWx5IG1lYW5zIDEuOTU0OCByb3RhdGlvbnMKKyAqIHBlciBzZWMuCisgKiBGb3IgcXVhZHJhdHVyZSBlbmNvZGVycywgZWFjaCB1bml0IGNvcnJlc3BvbmRzIGEgcXVhZHJhdHVyZSBlZGdlICg0WCkuCisgKiAgICAgU28gYSAyNTAgY291bnQgZW5jb2RlciB3aWxsIHByb2R1Y2UgMTAwMCBlZGdlIGV2ZW50cyBwZXIKKyAqIHJvdGF0aW9uLgorICogICAgIEFuIGV4YW1wbGUgc3BlZWQgb2YgMjAwIHdvdWxkIHRoZW4gZXF1YXRlIHRvIDIwJSBvZiBhIHJvdGF0aW9uCisgKiBwZXIgMTAwbXMsCisgKiAgICAgb3IgMTAgcm90YXRpb25zIHBlciBzZWNvbmQuCisgKi8KK2RvdWJsZSBDQU5UYWxvbjo6R2V0U3BlZWQoKSBjb25zdCB7CisgIGludDMyX3Qgc3BlZWQ7CisgIENUUl9Db2RlIHN0YXR1cyA9IG1faW1wbC0+R2V0U2Vuc29yVmVsb2NpdHkoc3BlZWQpOworICBpZiAoc3RhdHVzICE9IENUUl9PS0FZKSB7CisgICAgd3BpX3NldEVycm9yV2l0aENvbnRleHQoc3RhdHVzLCBnZXRIQUxFcnJvck1lc3NhZ2Uoc3RhdHVzKSk7CisgIH0KKyAgcmV0dXJuIFNjYWxlTmF0aXZlVW5pdHNUb1JwbShtX2ZlZWRiYWNrRGV2aWNlLCBzcGVlZCk7Cit9CisKKy8qKgorICogR2V0IHRoZSBwb3NpdGlvbiBvZiB3aGF0ZXZlciBpcyBpbiB0aGUgYW5hbG9nIHBpbiBvZiB0aGUgVGFsb24sIHJlZ2FyZGxlc3Mgb2YKKyAqIHdoZXRoZXIgaXQgaXMgYWN0dWFsbHkgYmVpbmcgdXNlZCBmb3IgZmVlZGJhY2suCisgKgorICogQHJldHVybnMgVGhlIDI0Yml0IGFuYWxvZyB2YWx1ZS4gIFRoZSBib3R0b20gdGVuIGJpdHMgaXMgdGhlIEFEQyAoMCAtIDEwMjMpCisgKiAgICAgICAgICBvbiB0aGUgYW5hbG9nIHBpbiBvZiB0aGUgVGFsb24uCisgKiAgICAgICAgICBUaGUgdXBwZXIgMTQgYml0cyB0cmFja3MgdGhlIG92ZXJmbG93cyBhbmQKKyAqIHVuZGVyZmxvd3MgKGNvbnRpbnVvdXMgc2Vuc29yKS4KKyAqLworaW50IENBTlRhbG9uOjpHZXRBbmFsb2dJbigpIGNvbnN0IHsKKyAgaW50IHBvc2l0aW9uOworICBDVFJfQ29kZSBzdGF0dXMgPSBtX2ltcGwtPkdldEFuYWxvZ0luV2l0aE92KHBvc2l0aW9uKTsKKyAgaWYgKHN0YXR1cyAhPSBDVFJfT0tBWSkgeworICAgIHdwaV9zZXRFcnJvcldpdGhDb250ZXh0KHN0YXR1cywgZ2V0SEFMRXJyb3JNZXNzYWdlKHN0YXR1cykpOworICB9CisgIHJldHVybiBwb3NpdGlvbjsKK30KKwordm9pZCBDQU5UYWxvbjo6U2V0QW5hbG9nUG9zaXRpb24oaW50IG5ld1Bvc2l0aW9uKSB7CisgIENUUl9Db2RlIHN0YXR1cyA9IG1faW1wbC0+U2V0UGFyYW0oQ2FuVGFsb25TUlg6OmVBaW5Qb3NpdGlvbiwgbmV3UG9zaXRpb24pOworICBpZiAoc3RhdHVzICE9IENUUl9PS0FZKSB7CisgICAgd3BpX3NldEVycm9yV2l0aENvbnRleHQoc3RhdHVzLCBnZXRIQUxFcnJvck1lc3NhZ2Uoc3RhdHVzKSk7CisgIH0KK30KKy8qKgorICogR2V0IHRoZSBwb3NpdGlvbiBvZiB3aGF0ZXZlciBpcyBpbiB0aGUgYW5hbG9nIHBpbiBvZiB0aGUgVGFsb24sIHJlZ2FyZGxlc3Mgb2YKKyAqIHdoZXRoZXIgaXQgaXMgYWN0dWFsbHkgYmVpbmcgdXNlZCBmb3IgZmVlZGJhY2suCisgKgorICogQHJldHVybnMgVGhlIEFEQyAoMCAtIDEwMjMpIG9uIGFuYWxvZyBwaW4gb2YgdGhlIFRhbG9uLgorICovCitpbnQgQ0FOVGFsb246OkdldEFuYWxvZ0luUmF3KCkgY29uc3QgeyByZXR1cm4gR2V0QW5hbG9nSW4oKSAmIDB4M0ZGOyB9CisvKioKKyAqIEdldCB0aGUgcG9zaXRpb24gb2Ygd2hhdGV2ZXIgaXMgaW4gdGhlIGFuYWxvZyBwaW4gb2YgdGhlIFRhbG9uLCByZWdhcmRsZXNzIG9mCisgKiB3aGV0aGVyIGl0IGlzIGFjdHVhbGx5IGJlaW5nIHVzZWQgZm9yIGZlZWRiYWNrLgorICoKKyAqIEByZXR1cm5zIFRoZSB2YWx1ZSAoMCAtIDEwMjMpIG9uIHRoZSBhbmFsb2cgcGluIG9mIHRoZSBUYWxvbi4KKyAqLworaW50IENBTlRhbG9uOjpHZXRBbmFsb2dJblZlbCgpIGNvbnN0IHsKKyAgaW50IHZlbDsKKyAgQ1RSX0NvZGUgc3RhdHVzID0gbV9pbXBsLT5HZXRBbmFsb2dJblZlbCh2ZWwpOworICBpZiAoc3RhdHVzICE9IENUUl9PS0FZKSB7CisgICAgd3BpX3NldEVycm9yV2l0aENvbnRleHQoc3RhdHVzLCBnZXRIQUxFcnJvck1lc3NhZ2Uoc3RhdHVzKSk7CisgIH0KKyAgcmV0dXJuIHZlbDsKK30KKworLyoqCisgKiBHZXQgdGhlIHBvc2l0aW9uIG9mIHdoYXRldmVyIGlzIGluIHRoZSBhbmFsb2cgcGluIG9mIHRoZSBUYWxvbiwgcmVnYXJkbGVzcyBvZgorICogd2hldGhlciBpdCBpcyBhY3R1YWxseSBiZWluZyB1c2VkIGZvciBmZWVkYmFjay4KKyAqCisgKiBAcmV0dXJucyBUaGUgdmFsdWUgKDAgLSAxMDIzKSBvbiB0aGUgYW5hbG9nIHBpbiBvZiB0aGUgVGFsb24uCisgKi8KK2ludCBDQU5UYWxvbjo6R2V0RW5jUG9zaXRpb24oKSBjb25zdCB7CisgIGludCBwb3NpdGlvbjsKKyAgQ1RSX0NvZGUgc3RhdHVzID0gbV9pbXBsLT5HZXRFbmNQb3NpdGlvbihwb3NpdGlvbik7CisgIGlmIChzdGF0dXMgIT0gQ1RSX09LQVkpIHsKKyAgICB3cGlfc2V0RXJyb3JXaXRoQ29udGV4dChzdGF0dXMsIGdldEhBTEVycm9yTWVzc2FnZShzdGF0dXMpKTsKKyAgfQorICByZXR1cm4gcG9zaXRpb247Cit9Cit2b2lkIENBTlRhbG9uOjpTZXRFbmNQb3NpdGlvbihpbnQgbmV3UG9zaXRpb24pIHsKKyAgQ1RSX0NvZGUgc3RhdHVzID0gbV9pbXBsLT5TZXRQYXJhbShDYW5UYWxvblNSWDo6ZUVuY1Bvc2l0aW9uLCBuZXdQb3NpdGlvbik7CisgIGlmIChzdGF0dXMgIT0gQ1RSX09LQVkpIHsKKyAgICB3cGlfc2V0RXJyb3JXaXRoQ29udGV4dChzdGF0dXMsIGdldEhBTEVycm9yTWVzc2FnZShzdGF0dXMpKTsKKyAgfQorfQorCisvKioKKyAqIEdldCB0aGUgcG9zaXRpb24gb2Ygd2hhdGV2ZXIgaXMgaW4gdGhlIGFuYWxvZyBwaW4gb2YgdGhlIFRhbG9uLCByZWdhcmRsZXNzIG9mCisgKiB3aGV0aGVyIGl0IGlzIGFjdHVhbGx5IGJlaW5nIHVzZWQgZm9yIGZlZWRiYWNrLgorICoKKyAqIEByZXR1cm5zIFRoZSB2YWx1ZSAoMCAtIDEwMjMpIG9uIHRoZSBhbmFsb2cgcGluIG9mIHRoZSBUYWxvbi4KKyAqLworaW50IENBTlRhbG9uOjpHZXRFbmNWZWwoKSBjb25zdCB7CisgIGludCB2ZWw7CisgIENUUl9Db2RlIHN0YXR1cyA9IG1faW1wbC0+R2V0RW5jVmVsKHZlbCk7CisgIGlmIChzdGF0dXMgIT0gQ1RSX09LQVkpIHsKKyAgICB3cGlfc2V0RXJyb3JXaXRoQ29udGV4dChzdGF0dXMsIGdldEhBTEVycm9yTWVzc2FnZShzdGF0dXMpKTsKKyAgfQorICByZXR1cm4gdmVsOworfQoraW50IENBTlRhbG9uOjpHZXRQdWxzZVdpZHRoUG9zaXRpb24oKSBjb25zdCB7CisgIGludCBwYXJhbTsKKyAgQ1RSX0NvZGUgc3RhdHVzID0gbV9pbXBsLT5HZXRQdWxzZVdpZHRoUG9zaXRpb24ocGFyYW0pOworICBpZiAoc3RhdHVzICE9IENUUl9PS0FZKQorICAgIHdwaV9zZXRFcnJvcldpdGhDb250ZXh0KHN0YXR1cywgZ2V0SEFMRXJyb3JNZXNzYWdlKHN0YXR1cykpOworICByZXR1cm4gcGFyYW07Cit9Cit2b2lkIENBTlRhbG9uOjpTZXRQdWxzZVdpZHRoUG9zaXRpb24oaW50IG5ld1Bvc2l0aW9uKQoreworICBDVFJfQ29kZSBzdGF0dXMgPSBtX2ltcGwtPlNldFBhcmFtKENhblRhbG9uU1JYOjplUHdkUG9zaXRpb24sIG5ld1Bvc2l0aW9uKTsKKyAgaWYgKHN0YXR1cyAhPSBDVFJfT0tBWSkgeworICAgIHdwaV9zZXRFcnJvcldpdGhDb250ZXh0KHN0YXR1cywgZ2V0SEFMRXJyb3JNZXNzYWdlKHN0YXR1cykpOworICB9Cit9CitpbnQgQ0FOVGFsb246OkdldFB1bHNlV2lkdGhWZWxvY2l0eSgpY29uc3QKK3sKKyAgaW50IHBhcmFtOworICBDVFJfQ29kZSBzdGF0dXMgPSBtX2ltcGwtPkdldFB1bHNlV2lkdGhWZWxvY2l0eShwYXJhbSk7CisgIGlmIChzdGF0dXMgIT0gQ1RSX09LQVkpCisgICAgd3BpX3NldEVycm9yV2l0aENvbnRleHQoc3RhdHVzLCBnZXRIQUxFcnJvck1lc3NhZ2Uoc3RhdHVzKSk7CisgIHJldHVybiBwYXJhbTsKK30KK2ludCBDQU5UYWxvbjo6R2V0UHVsc2VXaWR0aFJpc2VUb0ZhbGxVcygpY29uc3QKK3sKKyAgaW50IHBhcmFtOworICBDVFJfQ29kZSBzdGF0dXMgPSBtX2ltcGwtPkdldFB1bHNlV2lkdGhSaXNlVG9GYWxsVXMocGFyYW0pOworICBpZiAoc3RhdHVzICE9IENUUl9PS0FZKQorICAgIHdwaV9zZXRFcnJvcldpdGhDb250ZXh0KHN0YXR1cywgZ2V0SEFMRXJyb3JNZXNzYWdlKHN0YXR1cykpOworICByZXR1cm4gcGFyYW07Cit9CitpbnQgQ0FOVGFsb246OkdldFB1bHNlV2lkdGhSaXNlVG9SaXNlVXMoKWNvbnN0Cit7CisgIGludCBwYXJhbTsKKyAgQ1RSX0NvZGUgc3RhdHVzID0gbV9pbXBsLT5HZXRQdWxzZVdpZHRoUmlzZVRvUmlzZVVzKHBhcmFtKTsKKyAgaWYgKHN0YXR1cyAhPSBDVFJfT0tBWSkKKyAgICB3cGlfc2V0RXJyb3JXaXRoQ29udGV4dChzdGF0dXMsIGdldEhBTEVycm9yTWVzc2FnZShzdGF0dXMpKTsKKyAgcmV0dXJuIHBhcmFtOworfQorLyoqCisgKiBAcGFyYW0gd2hpY2ggZmVlZGJhY2sgc2Vuc29yIHRvIGNoZWNrIGl0IGlmIGlzIGNvbm5lY3RlZC4KKyAqIEByZXR1cm4gc3RhdHVzIG9mIGNhbGxlcidzIHNwZWNpZmllZCBzZW5zb3IgdHlwZS4KKyAqLworQ0FOVGFsb246OkZlZWRiYWNrRGV2aWNlU3RhdHVzIENBTlRhbG9uOjpJc1NlbnNvclByZXNlbnQoRmVlZGJhY2tEZXZpY2UgZmVlZGJhY2tEZXZpY2UpY29uc3QKK3sKKyAgRmVlZGJhY2tEZXZpY2VTdGF0dXMgcmV0dmFsID0gRmVlZGJhY2tTdGF0dXNVbmtub3duOworICBpbnQgcGFyYW07CisgIC8qIGRldGVjdGluZyBzZW5zb3IgaGVhbHRoIGRlcGVuZHMgb24gd2hpY2ggc2Vuc29yIGNhbGxlciBjYXJlcyBhYm91dCAqLworICBzd2l0Y2ggKGZlZWRiYWNrRGV2aWNlKSB7CisgICAgY2FzZSBRdWFkRW5jb2RlcjoKKyAgICBjYXNlIEFuYWxvZ1BvdDoKKyAgICBjYXNlIEFuYWxvZ0VuY29kZXI6CisgICAgY2FzZSBFbmNSaXNpbmc6CisgICAgY2FzZSBFbmNGYWxsaW5nOgorICAgICAgLyogbm8gcmVhbCBnb29kIHdheSB0byB0ZWxsIGlmIHRoZXNlIHNlbnNvcgorICAgICAgICBhcmUgYWN0dWFsbHkgcHJlc2VudCBzbyByZXR1cm4gc3RhdHVzIHVua25vd24uICovCisgICAgICBicmVhazsKKyAgICBjYXNlIFB1bHNlV2lkdGg6CisgICAgY2FzZSBDdHJlTWFnRW5jb2Rlcl9SZWxhdGl2ZToKKyAgICBjYXNlIEN0cmVNYWdFbmNvZGVyX0Fic29sdXRlOgorICAgICAgLyogYWxsIG9mIHRoZXNlIHJlcXVpcmUgcHVsc2Ugd2lkdGggc2lnbmFsIHRvIGJlIHByZXNlbnQuICovCisgICAgICBDVFJfQ29kZSBzdGF0dXMgPSBtX2ltcGwtPklzUHVsc2VXaWR0aFNlbnNvclByZXNlbnQocGFyYW0pOworICAgICAgaWYgKHN0YXR1cyAhPSBDVFJfT0tBWSkgeworICAgICAgICAvKiB3ZSdyZSBub3QgZ2V0dGluZyBzdGF0dXMgaW5mbywgc2lnbmFsIHVua25vd24gc3RhdHVzICovCisgICAgICB9IGVsc2UgeworICAgICAgICAvKiBwYXJhbSBpcyB1cGRhdGVkICovCisgICAgICAgIGlmIChwYXJhbSkgeworICAgICAgICAgIC8qIHB1bHNlIHNpZ25hbCBpcyBwcmVzZW50LCBzZW5zb3IgbXVzdCBiZSB3b3JraW5nIHNpbmNlIGl0IGFsd2F5cworICAgICAgICAgICAgZ2VuZXJhdGVzIGEgcHVsc2Ugd2F2ZWZvcm0uKi8KKyAgICAgICAgICByZXR2YWwgPSBGZWVkYmFja1N0YXR1c1ByZXNlbnQ7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgLyogbm8gcHVsc2UgcHJlc2VudCwgc2Vuc29yIGRpc2Nvbm5lY3RlZCAqLworICAgICAgICAgIHJldHZhbCA9IEZlZWRiYWNrU3RhdHVzTm90UHJlc2VudDsKKyAgICAgICAgfQorICAgICAgfQorICAgICAgYnJlYWs7CisgIH0KKyAgcmV0dXJuIHJldHZhbDsKK30KKy8qKgorICogQHJldHVybiBJTyBsZXZlbCBvZiBRVUFEQSBwaW4uCisgKi8KK2ludCBDQU5UYWxvbjo6R2V0UGluU3RhdGVRdWFkQSgpIGNvbnN0IHsKKyAgaW50IHJldHZhbDsKKyAgQ1RSX0NvZGUgc3RhdHVzID0gbV9pbXBsLT5HZXRRdWFkQXBpbihyZXR2YWwpOworICBpZiAoc3RhdHVzICE9IENUUl9PS0FZKSB7CisgICAgd3BpX3NldEVycm9yV2l0aENvbnRleHQoc3RhdHVzLCBnZXRIQUxFcnJvck1lc3NhZ2Uoc3RhdHVzKSk7CisgIH0KKyAgcmV0dXJuIHJldHZhbDsKK30KKy8qKgorICogQHJldHVybiBJTyBsZXZlbCBvZiBRVUFEQiBwaW4uCisgKi8KK2ludCBDQU5UYWxvbjo6R2V0UGluU3RhdGVRdWFkQigpIGNvbnN0IHsKKyAgaW50IHJldHZhbDsKKyAgQ1RSX0NvZGUgc3RhdHVzID0gbV9pbXBsLT5HZXRRdWFkQnBpbihyZXR2YWwpOworICBpZiAoc3RhdHVzICE9IENUUl9PS0FZKSB7CisgICAgd3BpX3NldEVycm9yV2l0aENvbnRleHQoc3RhdHVzLCBnZXRIQUxFcnJvck1lc3NhZ2Uoc3RhdHVzKSk7CisgIH0KKyAgcmV0dXJuIHJldHZhbDsKK30KKy8qKgorICogQHJldHVybiBJTyBsZXZlbCBvZiBRVUFEIEluZGV4IHBpbi4KKyAqLworaW50IENBTlRhbG9uOjpHZXRQaW5TdGF0ZVF1YWRJZHgoKSBjb25zdCB7CisgIGludCByZXR2YWw7CisgIENUUl9Db2RlIHN0YXR1cyA9IG1faW1wbC0+R2V0UXVhZElkeHBpbihyZXR2YWwpOworICBpZiAoc3RhdHVzICE9IENUUl9PS0FZKSB7CisgICAgd3BpX3NldEVycm9yV2l0aENvbnRleHQoc3RhdHVzLCBnZXRIQUxFcnJvck1lc3NhZ2Uoc3RhdHVzKSk7CisgIH0KKyAgcmV0dXJuIHJldHZhbDsKK30KKy8qKgorICogQHJldHVybiAnMScgaWZmIGZvcndhcmQgbGltaXQgc3dpdGNoIGlzIGNsb3NlZCwgMCBpZmYgc3dpdGNoIGlzIG9wZW4uCisgKiBUaGlzIGZ1bmN0aW9uIHdvcmtzIHJlZ2FyZGxlc3MgaWYgbGltaXQgc3dpdGNoIGZlYXR1cmUgaXMgZW5hYmxlZC4KKyAqLworaW50IENBTlRhbG9uOjpJc0Z3ZExpbWl0U3dpdGNoQ2xvc2VkKCkgY29uc3QgeworICBpbnQgcmV0dmFsOworICBDVFJfQ29kZSBzdGF0dXMgPSBtX2ltcGwtPkdldExpbWl0U3dpdGNoQ2xvc2VkRm9yKAorICAgICAgcmV0dmFsKTsgLyogcmVuYW1lIHRoaXMgZnVuYywgJzEnID0+IG9wZW4sICcwJyA9PiBjbG9zZWQgKi8KKyAgaWYgKHN0YXR1cyAhPSBDVFJfT0tBWSkgeworICAgIHdwaV9zZXRFcnJvcldpdGhDb250ZXh0KHN0YXR1cywgZ2V0SEFMRXJyb3JNZXNzYWdlKHN0YXR1cykpOworICB9CisgIHJldHVybiByZXR2YWwgPyAwIDogMTsKK30KKy8qKgorICogQHJldHVybiAnMScgaWZmIHJldmVyc2UgbGltaXQgc3dpdGNoIGlzIGNsb3NlZCwgMCBpZmYgc3dpdGNoIGlzIG9wZW4uCisgKiBUaGlzIGZ1bmN0aW9uIHdvcmtzIHJlZ2FyZGxlc3MgaWYgbGltaXQgc3dpdGNoIGZlYXR1cmUgaXMgZW5hYmxlZC4KKyAqLworaW50IENBTlRhbG9uOjpJc1JldkxpbWl0U3dpdGNoQ2xvc2VkKCkgY29uc3QgeworICBpbnQgcmV0dmFsOworICBDVFJfQ29kZSBzdGF0dXMgPSBtX2ltcGwtPkdldExpbWl0U3dpdGNoQ2xvc2VkUmV2KAorICAgICAgcmV0dmFsKTsgLyogcmVuYW1lIHRoaXMgZnVuYywgJzEnID0+IG9wZW4sICcwJyA9PiBjbG9zZWQgKi8KKyAgaWYgKHN0YXR1cyAhPSBDVFJfT0tBWSkgeworICAgIHdwaV9zZXRFcnJvcldpdGhDb250ZXh0KHN0YXR1cywgZ2V0SEFMRXJyb3JNZXNzYWdlKHN0YXR1cykpOworICB9CisgIHJldHVybiByZXR2YWwgPyAwIDogMTsKK30KKy8qCisgKiBTaW1wbGUgYWNjZXNzb3IgZm9yIHRyYWNrZWQgcmlzZSBldmVudHNvIGluZGV4IHBpbi4KKyAqIEByZXR1cm4gbnVtYmVyIG9mIHJpc2luZyBlZGdlcyBvbiBpZHggcGluLgorICovCitpbnQgQ0FOVGFsb246OkdldE51bWJlck9mUXVhZElkeFJpc2VzKCkgY29uc3QgeworICBpbnQgcmlzZXM7CisgIENUUl9Db2RlIHN0YXR1cyA9IG1faW1wbC0+R2V0RW5jSW5kZXhSaXNlRXZlbnRzKAorICAgICAgcmlzZXMpOyAvKiByZW5hbWUgdGhpcyBmdW5jLCAnMScgPT4gb3BlbiwgJzAnID0+IGNsb3NlZCAqLworICBpZiAoc3RhdHVzICE9IENUUl9PS0FZKSB7CisgICAgd3BpX3NldEVycm9yV2l0aENvbnRleHQoc3RhdHVzLCBnZXRIQUxFcnJvck1lc3NhZ2Uoc3RhdHVzKSk7CisgIH0KKyAgcmV0dXJuIHJpc2VzOworfQorLyoKKyAqIEBwYXJhbSByaXNlcyBpbnRlZ3JhbCB2YWx1ZSB0byBzZXQgaW50byBpbmRleC1yaXNlcyByZWdpc3Rlci4gIEdyZWF0IHdheSB0bworICogemVybyB0aGUgaW5kZXggY291bnQuCisgKi8KK3ZvaWQgQ0FOVGFsb246OlNldE51bWJlck9mUXVhZElkeFJpc2VzKGludCByaXNlcykgeworICBDVFJfQ29kZSBzdGF0dXMgPSBtX2ltcGwtPlNldFBhcmFtKAorICAgICAgQ2FuVGFsb25TUlg6OmVFbmNJbmRleFJpc2VFdmVudHMsCisgICAgICByaXNlcyk7IC8qIHJlbmFtZSB0aGlzIGZ1bmMsICcxJyA9PiBvcGVuLCAnMCcgPT4gY2xvc2VkICovCisgIGlmIChzdGF0dXMgIT0gQ1RSX09LQVkpIHsKKyAgICB3cGlfc2V0RXJyb3JXaXRoQ29udGV4dChzdGF0dXMsIGdldEhBTEVycm9yTWVzc2FnZShzdGF0dXMpKTsKKyAgfQorfQorLyoqCisgKiBUT0RPIGRvY3VtZW50YXRpb24gKHNlZSBDQU5KYWd1YXIuY3BwKQorICovCitib29sIENBTlRhbG9uOjpHZXRGb3J3YXJkTGltaXRPSygpIGNvbnN0IHsKKyAgaW50IGxpbVN3aXQgPSAwOworICBpbnQgc29mdExpbSA9IDA7CisgIENUUl9Db2RlIHN0YXR1cyA9IENUUl9PS0FZOworICBzdGF0dXMgPSBtX2ltcGwtPkdldEZhdWx0X0ZvclNvZnRMaW0oc29mdExpbSk7CisgIGlmIChzdGF0dXMgIT0gQ1RSX09LQVkpIHsKKyAgICB3cGlfc2V0RXJyb3JXaXRoQ29udGV4dChzdGF0dXMsIGdldEhBTEVycm9yTWVzc2FnZShzdGF0dXMpKTsKKyAgfQorICBzdGF0dXMgPSBtX2ltcGwtPkdldEZhdWx0X0ZvckxpbShsaW1Td2l0KTsKKyAgaWYgKHN0YXR1cyAhPSBDVFJfT0tBWSkgeworICAgIHdwaV9zZXRFcnJvcldpdGhDb250ZXh0KHN0YXR1cywgZ2V0SEFMRXJyb3JNZXNzYWdlKHN0YXR1cykpOworICB9CisgIC8qIElmIGVpdGhlciBmYXVsdCBpcyBhc3NlcnRlZCwgc2lnbmFsIGNhbGxlciB3ZSBhcmUgZGlzYWJsZWQgKHdpdGggZmFsc2U/KSAqLworICByZXR1cm4gKHNvZnRMaW0gfCBsaW1Td2l0KSA/IGZhbHNlIDogdHJ1ZTsKK30KKworLyoqCisgKiBUT0RPIGRvY3VtZW50YXRpb24gKHNlZSBDQU5KYWd1YXIuY3BwKQorICovCitib29sIENBTlRhbG9uOjpHZXRSZXZlcnNlTGltaXRPSygpIGNvbnN0IHsKKyAgaW50IGxpbVN3aXQgPSAwOworICBpbnQgc29mdExpbSA9IDA7CisgIENUUl9Db2RlIHN0YXR1cyA9IENUUl9PS0FZOworICBzdGF0dXMgPSBtX2ltcGwtPkdldEZhdWx0X1JldlNvZnRMaW0oc29mdExpbSk7CisgIGlmIChzdGF0dXMgIT0gQ1RSX09LQVkpIHsKKyAgICB3cGlfc2V0RXJyb3JXaXRoQ29udGV4dChzdGF0dXMsIGdldEhBTEVycm9yTWVzc2FnZShzdGF0dXMpKTsKKyAgfQorICBzdGF0dXMgPSBtX2ltcGwtPkdldEZhdWx0X1JldkxpbShsaW1Td2l0KTsKKyAgaWYgKHN0YXR1cyAhPSBDVFJfT0tBWSkgeworICAgIHdwaV9zZXRFcnJvcldpdGhDb250ZXh0KHN0YXR1cywgZ2V0SEFMRXJyb3JNZXNzYWdlKHN0YXR1cykpOworICB9CisgIC8qIElmIGVpdGhlciBmYXVsdCBpcyBhc3NlcnRlZCwgc2lnbmFsIGNhbGxlciB3ZSBhcmUgZGlzYWJsZWQgKHdpdGggZmFsc2U/KSAqLworICByZXR1cm4gKHNvZnRMaW0gfCBsaW1Td2l0KSA/IGZhbHNlIDogdHJ1ZTsKK30KKworLyoqCisgKiBUT0RPIGRvY3VtZW50YXRpb24gKHNlZSBDQU5KYWd1YXIuY3BwKQorICovCit1aW50MTZfdCBDQU5UYWxvbjo6R2V0RmF1bHRzKCkgY29uc3QgeworICB1aW50MTZfdCByZXR2YWwgPSAwOworICBpbnQgdmFsOworICBDVFJfQ29kZSBzdGF0dXMgPSBDVFJfT0tBWTsKKworICAvKiB0ZW1wZXJhdHVyZSAqLworICB2YWwgPSAwOworICBzdGF0dXMgPSBtX2ltcGwtPkdldEZhdWx0X092ZXJUZW1wKHZhbCk7CisgIGlmIChzdGF0dXMgIT0gQ1RSX09LQVkpCisgICAgd3BpX3NldEVycm9yV2l0aENvbnRleHQoc3RhdHVzLCBnZXRIQUxFcnJvck1lc3NhZ2Uoc3RhdHVzKSk7CisgIHJldHZhbCB8PSAodmFsKSA/IENBTlNwZWVkQ29udHJvbGxlcjo6a1RlbXBlcmF0dXJlRmF1bHQgOiAwOworCisgIC8qIHZvbHRhZ2UgKi8KKyAgdmFsID0gMDsKKyAgc3RhdHVzID0gbV9pbXBsLT5HZXRGYXVsdF9VbmRlclZvbHRhZ2UodmFsKTsKKyAgaWYgKHN0YXR1cyAhPSBDVFJfT0tBWSkKKyAgICB3cGlfc2V0RXJyb3JXaXRoQ29udGV4dChzdGF0dXMsIGdldEhBTEVycm9yTWVzc2FnZShzdGF0dXMpKTsKKyAgcmV0dmFsIHw9ICh2YWwpID8gQ0FOU3BlZWRDb250cm9sbGVyOjprQnVzVm9sdGFnZUZhdWx0IDogMDsKKworICAvKiBmd2QtbGltaXQtc3dpdGNoICovCisgIHZhbCA9IDA7CisgIHN0YXR1cyA9IG1faW1wbC0+R2V0RmF1bHRfRm9yTGltKHZhbCk7CisgIGlmIChzdGF0dXMgIT0gQ1RSX09LQVkpCisgICAgd3BpX3NldEVycm9yV2l0aENvbnRleHQoc3RhdHVzLCBnZXRIQUxFcnJvck1lc3NhZ2Uoc3RhdHVzKSk7CisgIHJldHZhbCB8PSAodmFsKSA/IENBTlNwZWVkQ29udHJvbGxlcjo6a0Z3ZExpbWl0U3dpdGNoIDogMDsKKworICAvKiByZXYtbGltaXQtc3dpdGNoICovCisgIHZhbCA9IDA7CisgIHN0YXR1cyA9IG1faW1wbC0+R2V0RmF1bHRfUmV2TGltKHZhbCk7CisgIGlmIChzdGF0dXMgIT0gQ1RSX09LQVkpCisgICAgd3BpX3NldEVycm9yV2l0aENvbnRleHQoc3RhdHVzLCBnZXRIQUxFcnJvck1lc3NhZ2Uoc3RhdHVzKSk7CisgIHJldHZhbCB8PSAodmFsKSA/IENBTlNwZWVkQ29udHJvbGxlcjo6a1JldkxpbWl0U3dpdGNoIDogMDsKKworICAvKiBmd2Qtc29mdC1saW1pdCAqLworICB2YWwgPSAwOworICBzdGF0dXMgPSBtX2ltcGwtPkdldEZhdWx0X0ZvclNvZnRMaW0odmFsKTsKKyAgaWYgKHN0YXR1cyAhPSBDVFJfT0tBWSkKKyAgICB3cGlfc2V0RXJyb3JXaXRoQ29udGV4dChzdGF0dXMsIGdldEhBTEVycm9yTWVzc2FnZShzdGF0dXMpKTsKKyAgcmV0dmFsIHw9ICh2YWwpID8gQ0FOU3BlZWRDb250cm9sbGVyOjprRndkU29mdExpbWl0IDogMDsKKworICAvKiByZXYtc29mdC1saW1pdCAqLworICB2YWwgPSAwOworICBzdGF0dXMgPSBtX2ltcGwtPkdldEZhdWx0X1JldlNvZnRMaW0odmFsKTsKKyAgaWYgKHN0YXR1cyAhPSBDVFJfT0tBWSkKKyAgICB3cGlfc2V0RXJyb3JXaXRoQ29udGV4dChzdGF0dXMsIGdldEhBTEVycm9yTWVzc2FnZShzdGF0dXMpKTsKKyAgcmV0dmFsIHw9ICh2YWwpID8gQ0FOU3BlZWRDb250cm9sbGVyOjprUmV2U29mdExpbWl0IDogMDsKKworICByZXR1cm4gcmV0dmFsOworfQordWludDE2X3QgQ0FOVGFsb246OkdldFN0aWNreUZhdWx0cygpIGNvbnN0IHsKKyAgdWludDE2X3QgcmV0dmFsID0gMDsKKyAgaW50IHZhbDsKKyAgQ1RSX0NvZGUgc3RhdHVzID0gQ1RSX09LQVk7CisKKyAgLyogdGVtcGVyYXR1cmUgKi8KKyAgdmFsID0gMDsKKyAgc3RhdHVzID0gbV9pbXBsLT5HZXRTdGNreUZhdWx0X092ZXJUZW1wKHZhbCk7CisgIGlmIChzdGF0dXMgIT0gQ1RSX09LQVkpCisgICAgd3BpX3NldEVycm9yV2l0aENvbnRleHQoc3RhdHVzLCBnZXRIQUxFcnJvck1lc3NhZ2Uoc3RhdHVzKSk7CisgIHJldHZhbCB8PSAodmFsKSA/IENBTlNwZWVkQ29udHJvbGxlcjo6a1RlbXBlcmF0dXJlRmF1bHQgOiAwOworCisgIC8qIHZvbHRhZ2UgKi8KKyAgdmFsID0gMDsKKyAgc3RhdHVzID0gbV9pbXBsLT5HZXRTdGNreUZhdWx0X1VuZGVyVm9sdGFnZSh2YWwpOworICBpZiAoc3RhdHVzICE9IENUUl9PS0FZKQorICAgIHdwaV9zZXRFcnJvcldpdGhDb250ZXh0KHN0YXR1cywgZ2V0SEFMRXJyb3JNZXNzYWdlKHN0YXR1cykpOworICByZXR2YWwgfD0gKHZhbCkgPyBDQU5TcGVlZENvbnRyb2xsZXI6OmtCdXNWb2x0YWdlRmF1bHQgOiAwOworCisgIC8qIGZ3ZC1saW1pdC1zd2l0Y2ggKi8KKyAgdmFsID0gMDsKKyAgc3RhdHVzID0gbV9pbXBsLT5HZXRTdGNreUZhdWx0X0ZvckxpbSh2YWwpOworICBpZiAoc3RhdHVzICE9IENUUl9PS0FZKQorICAgIHdwaV9zZXRFcnJvcldpdGhDb250ZXh0KHN0YXR1cywgZ2V0SEFMRXJyb3JNZXNzYWdlKHN0YXR1cykpOworICByZXR2YWwgfD0gKHZhbCkgPyBDQU5TcGVlZENvbnRyb2xsZXI6OmtGd2RMaW1pdFN3aXRjaCA6IDA7CisKKyAgLyogcmV2LWxpbWl0LXN3aXRjaCAqLworICB2YWwgPSAwOworICBzdGF0dXMgPSBtX2ltcGwtPkdldFN0Y2t5RmF1bHRfUmV2TGltKHZhbCk7CisgIGlmIChzdGF0dXMgIT0gQ1RSX09LQVkpCisgICAgd3BpX3NldEVycm9yV2l0aENvbnRleHQoc3RhdHVzLCBnZXRIQUxFcnJvck1lc3NhZ2Uoc3RhdHVzKSk7CisgIHJldHZhbCB8PSAodmFsKSA/IENBTlNwZWVkQ29udHJvbGxlcjo6a1JldkxpbWl0U3dpdGNoIDogMDsKKworICAvKiBmd2Qtc29mdC1saW1pdCAqLworICB2YWwgPSAwOworICBzdGF0dXMgPSBtX2ltcGwtPkdldFN0Y2t5RmF1bHRfRm9yU29mdExpbSh2YWwpOworICBpZiAoc3RhdHVzICE9IENUUl9PS0FZKQorICAgIHdwaV9zZXRFcnJvcldpdGhDb250ZXh0KHN0YXR1cywgZ2V0SEFMRXJyb3JNZXNzYWdlKHN0YXR1cykpOworICByZXR2YWwgfD0gKHZhbCkgPyBDQU5TcGVlZENvbnRyb2xsZXI6OmtGd2RTb2Z0TGltaXQgOiAwOworCisgIC8qIHJldi1zb2Z0LWxpbWl0ICovCisgIHZhbCA9IDA7CisgIHN0YXR1cyA9IG1faW1wbC0+R2V0U3Rja3lGYXVsdF9SZXZTb2Z0TGltKHZhbCk7CisgIGlmIChzdGF0dXMgIT0gQ1RSX09LQVkpCisgICAgd3BpX3NldEVycm9yV2l0aENvbnRleHQoc3RhdHVzLCBnZXRIQUxFcnJvck1lc3NhZ2Uoc3RhdHVzKSk7CisgIHJldHZhbCB8PSAodmFsKSA/IENBTlNwZWVkQ29udHJvbGxlcjo6a1JldlNvZnRMaW1pdCA6IDA7CisKKyAgcmV0dXJuIHJldHZhbDsKK30KK3ZvaWQgQ0FOVGFsb246OkNsZWFyU3RpY2t5RmF1bHRzKCkgeworICBDVFJfQ29kZSBzdGF0dXMgPSBtX2ltcGwtPkNsZWFyU3RpY2t5RmF1bHRzKCk7CisgIHdwaV9zZXRFcnJvcldpdGhDb250ZXh0KHN0YXR1cywgZ2V0SEFMRXJyb3JNZXNzYWdlKHN0YXR1cykpOworfQorCisvKioKKyAqIFNldCB0aGUgbWF4aW11bSB2b2x0YWdlIGNoYW5nZSByYXRlLiAgVGhpcyByYW1wIHJhdGUgaXMgaW4gYWZmZWN0IHJlZ2FyZGxlc3MKKyAqIG9mIHdoaWNoIGNvbnRyb2wgbW9kZQorICogdGhlIFRBTE9OIGlzIGluLgorICoKKyAqIFdoZW4gaW4gUGVyY2VudFZidXMgb3IgVm9sdGFnZSBvdXRwdXQgbW9kZSwgdGhlIHJhdGUgYXQgd2hpY2ggdGhlIHZvbHRhZ2UKKyAqIGNoYW5nZXMgY2FuCisgKiBiZSBsaW1pdGVkIHRvIHJlZHVjZSBjdXJyZW50IHNwaWtlcy4gIFNldCB0aGlzIHRvIDAuMCB0byBkaXNhYmxlIHJhdGUKKyAqIGxpbWl0aW5nLgorICoKKyAqIEBwYXJhbSByYW1wUmF0ZSBUaGUgbWF4aW11bSByYXRlIG9mIHZvbHRhZ2UgY2hhbmdlIGluIFBlcmNlbnQgVm9sdGFnZSBtb2RlIGluCisgKiBWL3MuCisgKi8KK3ZvaWQgQ0FOVGFsb246OlNldFZvbHRhZ2VSYW1wUmF0ZShkb3VibGUgcmFtcFJhdGUpIHsKKyAgLyogQ2FsbGVyIGlzIGV4cHJlc3NpbmcgcmFtcCBhcyBWb2x0YWdlIHBlciBzZWMsIGFzc3VtaW5nIDEyViBpcyBmdWxsLgorICAgICAgICAgIFRhbG9uJ3MgdGhyb3R0bGUgcmFtcCBpcyBpbiBkVGhyb3QvZDEwbXMuICAxMDIzIGlzIGZ1bGwgZndkLCAtMTAyMyBpcworICAgICBmdWxsIHJldi4gKi8KKyAgZG91YmxlIHJhbXBSYXRlZFRocm90UGVyMTBtcyA9IChyYW1wUmF0ZSAqIDEwMjMuMCAvIDEyLjApIC8gMTAwOworICBDVFJfQ29kZSBzdGF0dXMgPSBtX2ltcGwtPlNldFJhbXBUaHJvdHRsZSgoaW50KXJhbXBSYXRlZFRocm90UGVyMTBtcyk7CisgIGlmIChzdGF0dXMgIT0gQ1RSX09LQVkpIHsKKyAgICB3cGlfc2V0RXJyb3JXaXRoQ29udGV4dChzdGF0dXMsIGdldEhBTEVycm9yTWVzc2FnZShzdGF0dXMpKTsKKyAgfQorfQordm9pZCBDQU5UYWxvbjo6U2V0Vm9sdGFnZUNvbXBlbnNhdGlvblJhbXBSYXRlKGRvdWJsZSByYW1wUmF0ZSkgeworICAvKiB3aGVuIGluIHZvbHRhZ2UgY29tcGVuc2F0aW9uIG1vZGUsIHRoZSB2b2x0YWdlIGNvbXBlbnNhdGlvbiByYXRlCisgICAgZGlyZWN0bHkgY2FwcyB0aGUgY2hhbmdlIGluIHRhcmdldCB2b2x0YWdlICovCisgIENUUl9Db2RlIHN0YXR1cyA9IENUUl9PS0FZOworICBzdGF0dXMgPSBtX2ltcGwtPlNldFZvbHRhZ2VDb21wZW5zYXRpb25SYXRlKHJhbXBSYXRlIC8gMTAwMCk7CisgIGlmIChzdGF0dXMgIT0gQ1RSX09LQVkpIHsKKyAgICB3cGlfc2V0RXJyb3JXaXRoQ29udGV4dChzdGF0dXMsIGdldEhBTEVycm9yTWVzc2FnZShzdGF0dXMpKTsKKyAgfQorfQorLyoqCisgKiBTZXRzIGEgdm9sdGFnZSBjaGFuZ2UgcmF0ZSB0aGF0IGFwcGxpZXMgb25seSB3aGVuIGEgY2xvc2UgbG9vcCBjb250b3JsIG1vZGUKKyAqIGlzIGVuYWJsZWQuCisgKiBUaGlzIGFsbG93cyBjbG9zZSBsb29wIHNwZWNpZmljIHJhbXAgYmVoYXZpb3IuCisgKgorICogQHBhcmFtIHJhbXBSYXRlIFRoZSBtYXhpbXVtIHJhdGUgb2Ygdm9sdGFnZSBjaGFuZ2UgaW4gUGVyY2VudCBWb2x0YWdlIG1vZGUgaW4KKyAqIFYvcy4KKyAqLwordm9pZCBDQU5UYWxvbjo6U2V0Q2xvc2VMb29wUmFtcFJhdGUoZG91YmxlIHJhbXBSYXRlKSB7CisgIENUUl9Db2RlIHN0YXR1cyA9IG1faW1wbC0+U2V0Q2xvc2VMb29wUmFtcFJhdGUoCisgICAgICBtX3Byb2ZpbGUsIHJhbXBSYXRlICogMTAyMy4wIC8gMTIuMCAvIDEwMDAuMCk7CisgIGlmIChzdGF0dXMgIT0gQ1RSX09LQVkpIHsKKyAgICB3cGlfc2V0RXJyb3JXaXRoQ29udGV4dChzdGF0dXMsIGdldEhBTEVycm9yTWVzc2FnZShzdGF0dXMpKTsKKyAgfQorfQorCisvKioKKyAqIEByZXR1cm4gVGhlIHZlcnNpb24gb2YgdGhlIGZpcm13YXJlIHJ1bm5pbmcgb24gdGhlIFRhbG9uCisgKi8KK3VpbnQzMl90IENBTlRhbG9uOjpHZXRGaXJtd2FyZVZlcnNpb24oKSBjb25zdCB7CisgIGludCBmaXJtd2FyZVZlcnNpb247CisgIENUUl9Db2RlIHN0YXR1cyA9IG1faW1wbC0+UmVxdWVzdFBhcmFtKENhblRhbG9uU1JYOjplRmlybVZlcnMpOworICBpZiAoc3RhdHVzICE9IENUUl9PS0FZKSB7CisgICAgd3BpX3NldEVycm9yV2l0aENvbnRleHQoc3RhdHVzLCBnZXRIQUxFcnJvck1lc3NhZ2Uoc3RhdHVzKSk7CisgIH0KKyAgdXNsZWVwKGtEZWxheUZvclNvbGljaXRlZFNpZ25hbHNVcyk7CisgIHN0YXR1cyA9CisgICAgICBtX2ltcGwtPkdldFBhcmFtUmVzcG9uc2VJbnQzMihDYW5UYWxvblNSWDo6ZUZpcm1WZXJzLCBmaXJtd2FyZVZlcnNpb24pOworICBpZiAoc3RhdHVzICE9IENUUl9PS0FZKSB7CisgICAgd3BpX3NldEVycm9yV2l0aENvbnRleHQoc3RhdHVzLCBnZXRIQUxFcnJvck1lc3NhZ2Uoc3RhdHVzKSk7CisgIH0KKworICAvKiBvbmx5IHNlbnQgb25jZSBvbiBib290ICovCisgIC8vIENUUl9Db2RlIHN0YXR1cyA9IG1faW1wbC0+R2V0RmlybVZlcnMoZmlybXdhcmVWZXJzaW9uKTsKKyAgLy8gaWYgKHN0YXR1cyAhPSBDVFJfT0tBWSkgeworICAvLyAgd3BpX3NldEVycm9yV2l0aENvbnRleHQoc3RhdHVzLCBnZXRIQUxFcnJvck1lc3NhZ2Uoc3RhdHVzKSk7CisgIC8vfQorCisgIHJldHVybiBmaXJtd2FyZVZlcnNpb247Cit9CisvKioKKyAqIEByZXR1cm4gVGhlIGFjY3VtdWxhdG9yIGZvciBJIGdhaW4uCisgKi8KK2ludCBDQU5UYWxvbjo6R2V0SWFjY3VtKCkgY29uc3QgeworICBDVFJfQ29kZSBzdGF0dXMgPSBtX2ltcGwtPlJlcXVlc3RQYXJhbShDYW5UYWxvblNSWDo6ZVBpZElhY2N1bSk7CisgIGlmIChzdGF0dXMgIT0gQ1RSX09LQVkpIHsKKyAgICB3cGlfc2V0RXJyb3JXaXRoQ29udGV4dChzdGF0dXMsIGdldEhBTEVycm9yTWVzc2FnZShzdGF0dXMpKTsKKyAgfQorICB1c2xlZXAoa0RlbGF5Rm9yU29saWNpdGVkU2lnbmFsc1VzKTsgLyogc21hbGwgeWllbGQgZm9yIGdldHRpbmcgcmVzcG9uc2UgKi8KKyAgaW50IGlhY2N1bTsKKyAgc3RhdHVzID0gbV9pbXBsLT5HZXRQYXJhbVJlc3BvbnNlSW50MzIoQ2FuVGFsb25TUlg6OmVQaWRJYWNjdW0sIGlhY2N1bSk7CisgIGlmIChzdGF0dXMgIT0gQ1RSX09LQVkpIHsKKyAgICB3cGlfc2V0RXJyb3JXaXRoQ29udGV4dChzdGF0dXMsIGdldEhBTEVycm9yTWVzc2FnZShzdGF0dXMpKTsKKyAgfQorICByZXR1cm4gaWFjY3VtOworfQorLyoqCisgKiBDbGVhciB0aGUgYWNjdW11bGF0b3IgZm9yIEkgZ2Fpbi4KKyAqLwordm9pZCBDQU5UYWxvbjo6Q2xlYXJJYWNjdW0oKSB7CisgIENUUl9Db2RlIHN0YXR1cyA9IG1faW1wbC0+U2V0UGFyYW0oQ2FuVGFsb25TUlg6OmVQaWRJYWNjdW0sIDApOworICBpZiAoc3RhdHVzICE9IENUUl9PS0FZKSB7CisgICAgd3BpX3NldEVycm9yV2l0aENvbnRleHQoc3RhdHVzLCBnZXRIQUxFcnJvck1lc3NhZ2Uoc3RhdHVzKSk7CisgIH0KK30KKworLyoqCisgKiBUT0RPIGRvY3VtZW50YXRpb24gKHNlZSBDQU5KYWd1YXIuY3BwKQorICovCit2b2lkIENBTlRhbG9uOjpDb25maWdOZXV0cmFsTW9kZShOZXV0cmFsTW9kZSBtb2RlKSB7CisgIENUUl9Db2RlIHN0YXR1cyA9IENUUl9PS0FZOworICBzd2l0Y2ggKG1vZGUpIHsKKyAgICBkZWZhdWx0OgorICAgIGNhc2Uga05ldXRyYWxNb2RlX0p1bXBlcjogLyogdXNlIGRlZmF1bHQgc2V0dGluZyBpbiBmbGFzaCBiYXNlZCBvbgorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgd2ViZGFzaC9CcmFrZUNhbCBidXR0b24gc2VsZWN0aW9uICovCisgICAgICBzdGF0dXMgPSBtX2ltcGwtPlNldE92ZXJyaWRlQnJha2VUeXBlKAorICAgICAgICAgIENhblRhbG9uU1JYOjprQnJha2VPdmVycmlkZV9Vc2VEZWZhdWx0c0Zyb21GbGFzaCk7CisgICAgICBicmVhazsKKyAgICBjYXNlIGtOZXV0cmFsTW9kZV9CcmFrZToKKyAgICAgIHN0YXR1cyA9IG1faW1wbC0+U2V0T3ZlcnJpZGVCcmFrZVR5cGUoCisgICAgICAgICAgQ2FuVGFsb25TUlg6OmtCcmFrZU92ZXJyaWRlX092ZXJyaWRlQnJha2UpOworICAgICAgYnJlYWs7CisgICAgY2FzZSBrTmV1dHJhbE1vZGVfQ29hc3Q6CisgICAgICBzdGF0dXMgPSBtX2ltcGwtPlNldE92ZXJyaWRlQnJha2VUeXBlKAorICAgICAgICAgIENhblRhbG9uU1JYOjprQnJha2VPdmVycmlkZV9PdmVycmlkZUNvYXN0KTsKKyAgICAgIGJyZWFrOworICB9CisgIGlmIChzdGF0dXMgIT0gQ1RSX09LQVkpIHsKKyAgICB3cGlfc2V0RXJyb3JXaXRoQ29udGV4dChzdGF0dXMsIGdldEhBTEVycm9yTWVzc2FnZShzdGF0dXMpKTsKKyAgfQorfQorLyoqCisgKiBAcmV0dXJuIG5vbnplcm8gaWYgYnJha2UgaXMgZW5hYmxlZCBkdXJpbmcgbmV1dHJhbC4gIFplcm8gaWYgY29hc3QgaXMgZW5hYmxlZAorICogZHVyaW5nIG5ldXRyYWwuCisgKi8KK2ludCBDQU5UYWxvbjo6R2V0QnJha2VFbmFibGVEdXJpbmdOZXV0cmFsKCkgY29uc3QgeworICBpbnQgYnJha2VFbiA9IDA7CisgIENUUl9Db2RlIHN0YXR1cyA9IG1faW1wbC0+R2V0QnJha2VJc0VuYWJsZWQoYnJha2VFbik7CisgIGlmIChzdGF0dXMgIT0gQ1RSX09LQVkpIHsKKyAgICB3cGlfc2V0RXJyb3JXaXRoQ29udGV4dChzdGF0dXMsIGdldEhBTEVycm9yTWVzc2FnZShzdGF0dXMpKTsKKyAgfQorICByZXR1cm4gYnJha2VFbjsKK30KKy8qKgorICogQ29uZmlndXJlIGhvdyBtYW55IGNvZGVzIHBlciByZXZvbHV0aW9uIGFyZSBnZW5lcmF0ZWQgYnkgeW91ciBlbmNvZGVyLgorICoKKyAqIEBwYXJhbSBjb2Rlc1BlclJldiBUaGUgbnVtYmVyIG9mIGNvdW50cyBwZXIgcmV2b2x1dGlvbi4KKyAqLwordm9pZCBDQU5UYWxvbjo6Q29uZmlnRW5jb2RlckNvZGVzUGVyUmV2KHVpbnQxNl90IGNvZGVzUGVyUmV2KSB7CisgIC8qIGZpcnN0IHNhdmUgdGhlIHNjYWxhciBzbyB0aGF0IGFsbCBnZXR0ZXJzL3NldHRlciB3b3JrIGFzIHRoZSB1c2VyIGV4cGVjdHMgKi8KKyAgbV9jb2Rlc1BlclJldiA9IGNvZGVzUGVyUmV2OworICAvKiBuZXh0IHNlbmQgdGhlIHNjYWxhciB0byB0aGUgVGFsb24gb3ZlciBDQU4uICBUaGlzIGlzIHNvIHRoYXQgdGhlIFRhbG9uIGNhbiByZXBvcnQKKyAgICBpdCB0byB3aG9ldmVyIG5lZWRzIGl0LCBsaWtlIHRoZSB3ZWJkYXNoLiAgRG9uJ3QgYm90aGVyIGNoZWNraW5nIHRoZSByZXR1cm4sCisgICAgdGhpcyBpcyBvbmx5IGZvciBpbnN0cnVtZW50YXRpb24gYW5kIGlzIG5vdCBuZWNlc3NhcnkgZm9yIFRhbG9uIGZ1bmN0aW9uYWxpdHkuICovCisgICh2b2lkKW1faW1wbC0+U2V0UGFyYW0oQ2FuVGFsb25TUlg6OmVOdW1iZXJFbmNvZGVyQ1BSLCBtX2NvZGVzUGVyUmV2KTsKK30KKworLyoqCisgKiBDb25maWd1cmUgdGhlIG51bWJlciBvZiB0dXJucyBvbiB0aGUgcG90ZW50aW9tZXRlci4KKyAqCisgKiBAcGFyYW0gdHVybnMgVGhlIG51bWJlciBvZiB0dXJucyBvZiB0aGUgcG90ZW50aW9tZXRlci4KKyAqLwordm9pZCBDQU5UYWxvbjo6Q29uZmlnUG90ZW50aW9tZXRlclR1cm5zKHVpbnQxNl90IHR1cm5zKSB7CisgIC8qIGZpcnN0IHNhdmUgdGhlIHNjYWxhciBzbyB0aGF0IGFsbCBnZXR0ZXJzL3NldHRlciB3b3JrIGFzIHRoZSB1c2VyIGV4cGVjdHMgKi8KKyAgbV9udW1Qb3RUdXJucyA9IHR1cm5zOworICAvKiBuZXh0IHNlbmQgdGhlIHNjYWxhciB0byB0aGUgVGFsb24gb3ZlciBDQU4uICBUaGlzIGlzIHNvIHRoYXQgdGhlIFRhbG9uIGNhbiByZXBvcnQKKyAgICBpdCB0byB3aG9ldmVyIG5lZWRzIGl0LCBsaWtlIHRoZSB3ZWJkYXNoLiAgRG9uJ3QgYm90aGVyIGNoZWNraW5nIHRoZSByZXR1cm4sCisgICAgdGhpcyBpcyBvbmx5IGZvciBpbnN0cnVtZW50YXRpb24gYW5kIGlzIG5vdCBuZWNlc3NhcnkgZm9yIFRhbG9uIGZ1bmN0aW9uYWxpdHkuICovCisgICh2b2lkKW1faW1wbC0+U2V0UGFyYW0oQ2FuVGFsb25TUlg6OmVOdW1iZXJQb3RUdXJucywgbV9udW1Qb3RUdXJucyk7Cit9CisKKy8qKgorICogQGRlcHJlY2F0ZWQgbm90IGltcGxlbWVudGVkCisgKi8KK3ZvaWQgQ0FOVGFsb246OkNvbmZpZ1NvZnRQb3NpdGlvbkxpbWl0cyhkb3VibGUgZm9yd2FyZExpbWl0UG9zaXRpb24sCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZG91YmxlIHJldmVyc2VMaW1pdFBvc2l0aW9uKSB7CisgIENvbmZpZ0xpbWl0TW9kZShrTGltaXRNb2RlX1NvZnRQb3NpdGlvbkxpbWl0cyk7CisgIENvbmZpZ0ZvcndhcmRMaW1pdChmb3J3YXJkTGltaXRQb3NpdGlvbik7CisgIENvbmZpZ1JldmVyc2VMaW1pdChyZXZlcnNlTGltaXRQb3NpdGlvbik7Cit9CisKKy8qKgorICogVE9ETyBkb2N1bWVudGF0aW9uIChzZWUgQ0FOSmFndWFyLmNwcCkKKyAqLwordm9pZCBDQU5UYWxvbjo6RGlzYWJsZVNvZnRQb3NpdGlvbkxpbWl0cygpIHsKKyAgQ29uZmlnTGltaXRNb2RlKGtMaW1pdE1vZGVfU3dpdGNoSW5wdXRzT25seSk7Cit9CisKKy8qKgorICogVE9ETyBkb2N1bWVudGF0aW9uIChzZWUgQ0FOSmFndWFyLmNwcCkKKyAqIENvbmZpZ3VyZXMgdGhlIHNvZnQgbGltaXQgZW5hYmxlICh3ZWFyIGxldmVsZWQgcGVyc2lzdGVudCBtZW1vcnkpLgorICogQWxzbyBzZXRzIHRoZSBsaW1pdCBzd2l0Y2ggb3ZlcnJpZGVzLgorICovCit2b2lkIENBTlRhbG9uOjpDb25maWdMaW1pdE1vZGUoTGltaXRNb2RlIG1vZGUpIHsKKyAgQ1RSX0NvZGUgc3RhdHVzID0gQ1RSX09LQVk7CisgIHN3aXRjaCAobW9kZSkgeworICAgIGNhc2Uga0xpbWl0TW9kZV9Td2l0Y2hJbnB1dHNPbmx5OiAvKiogT25seSB1c2Ugc3dpdGNoZXMgZm9yIGxpbWl0cyAqLworICAgICAgLyogdHVybiBPRkYgYm90aCBsaW1pdHMuIFNSWCBoYXMgaW5kaXZpZHVhbCBlbmFibGVzIGFuZCBwb2xhcml0eSBmb3IgZWFjaAorICAgICAgICogbGltaXQgc3dpdGNoLiovCisgICAgICBzdGF0dXMgPSBtX2ltcGwtPlNldEZvcndhcmRTb2Z0RW5hYmxlKGZhbHNlKTsKKyAgICAgIGlmIChzdGF0dXMgIT0gQ1RSX09LQVkpIHsKKyAgICAgICAgd3BpX3NldEVycm9yV2l0aENvbnRleHQoc3RhdHVzLCBnZXRIQUxFcnJvck1lc3NhZ2Uoc3RhdHVzKSk7CisgICAgICB9CisgICAgICBzdGF0dXMgPSBtX2ltcGwtPlNldFJldmVyc2VTb2Z0RW5hYmxlKGZhbHNlKTsKKyAgICAgIGlmIChzdGF0dXMgIT0gQ1RSX09LQVkpIHsKKyAgICAgICAgd3BpX3NldEVycm9yV2l0aENvbnRleHQoc3RhdHVzLCBnZXRIQUxFcnJvck1lc3NhZ2Uoc3RhdHVzKSk7CisgICAgICB9CisgICAgICAvKiBvdmVycmlkZSBlbmFibGUgdGhlIGxpbWl0IHN3aXRjaGVzLCB0aGlzIGNpcmN1bXZlbnRzIHRoZSB3ZWJkYXNoICovCisgICAgICBzdGF0dXMgPSBtX2ltcGwtPlNldE92ZXJyaWRlTGltaXRTd2l0Y2hFbigKKyAgICAgICAgICBDYW5UYWxvblNSWDo6a0xpbWl0U3dpdGNoT3ZlcnJpZGVfRW5hYmxlRndkX0VuYWJsZVJldik7CisgICAgICBpZiAoc3RhdHVzICE9IENUUl9PS0FZKSB7CisgICAgICAgIHdwaV9zZXRFcnJvcldpdGhDb250ZXh0KHN0YXR1cywgZ2V0SEFMRXJyb3JNZXNzYWdlKHN0YXR1cykpOworICAgICAgfQorICAgICAgYnJlYWs7CisgICAgY2FzZSBrTGltaXRNb2RlX1NvZnRQb3NpdGlvbkxpbWl0czogLyoqIFVzZSBib3RoIHN3aXRjaGVzIGFuZCBzb2Z0IGxpbWl0cyAqLworICAgICAgLyogdHVybiBvbiBib3RoIGxpbWl0cy4gU1JYIGhhcyBpbmRpdmlkdWFsIGVuYWJsZXMgYW5kIHBvbGFyaXR5IGZvciBlYWNoCisgICAgICAgKiBsaW1pdCBzd2l0Y2guKi8KKyAgICAgIHN0YXR1cyA9IG1faW1wbC0+U2V0Rm9yd2FyZFNvZnRFbmFibGUodHJ1ZSk7CisgICAgICBpZiAoc3RhdHVzICE9IENUUl9PS0FZKSB7CisgICAgICAgIHdwaV9zZXRFcnJvcldpdGhDb250ZXh0KHN0YXR1cywgZ2V0SEFMRXJyb3JNZXNzYWdlKHN0YXR1cykpOworICAgICAgfQorICAgICAgc3RhdHVzID0gbV9pbXBsLT5TZXRSZXZlcnNlU29mdEVuYWJsZSh0cnVlKTsKKyAgICAgIGlmIChzdGF0dXMgIT0gQ1RSX09LQVkpIHsKKyAgICAgICAgd3BpX3NldEVycm9yV2l0aENvbnRleHQoc3RhdHVzLCBnZXRIQUxFcnJvck1lc3NhZ2Uoc3RhdHVzKSk7CisgICAgICB9CisgICAgICAvKiBvdmVycmlkZSBlbmFibGUgdGhlIGxpbWl0IHN3aXRjaGVzLCB0aGlzIGNpcmN1bXZlbnRzIHRoZSB3ZWJkYXNoICovCisgICAgICBzdGF0dXMgPSBtX2ltcGwtPlNldE92ZXJyaWRlTGltaXRTd2l0Y2hFbigKKyAgICAgICAgICBDYW5UYWxvblNSWDo6a0xpbWl0U3dpdGNoT3ZlcnJpZGVfRW5hYmxlRndkX0VuYWJsZVJldik7CisgICAgICBpZiAoc3RhdHVzICE9IENUUl9PS0FZKSB7CisgICAgICAgIHdwaV9zZXRFcnJvcldpdGhDb250ZXh0KHN0YXR1cywgZ2V0SEFMRXJyb3JNZXNzYWdlKHN0YXR1cykpOworICAgICAgfQorICAgICAgYnJlYWs7CisKKyAgICBjYXNlIGtMaW1pdE1vZGVfU3J4RGlzYWJsZVN3aXRjaElucHV0czogLyoqIGRpc2FibGUgYm90aCBsaW1pdCBzd2l0Y2hlcyBhbmQKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc29mdCBsaW1pdHMgKi8KKyAgICAgIC8qIHR1cm4gb24gYm90aCBsaW1pdHMuIFNSWCBoYXMgaW5kaXZpZHVhbCBlbmFibGVzIGFuZCBwb2xhcml0eSBmb3IgZWFjaAorICAgICAgICogbGltaXQgc3dpdGNoLiovCisgICAgICBzdGF0dXMgPSBtX2ltcGwtPlNldEZvcndhcmRTb2Z0RW5hYmxlKGZhbHNlKTsKKyAgICAgIGlmIChzdGF0dXMgIT0gQ1RSX09LQVkpIHsKKyAgICAgICAgd3BpX3NldEVycm9yV2l0aENvbnRleHQoc3RhdHVzLCBnZXRIQUxFcnJvck1lc3NhZ2Uoc3RhdHVzKSk7CisgICAgICB9CisgICAgICBzdGF0dXMgPSBtX2ltcGwtPlNldFJldmVyc2VTb2Z0RW5hYmxlKGZhbHNlKTsKKyAgICAgIGlmIChzdGF0dXMgIT0gQ1RSX09LQVkpIHsKKyAgICAgICAgd3BpX3NldEVycm9yV2l0aENvbnRleHQoc3RhdHVzLCBnZXRIQUxFcnJvck1lc3NhZ2Uoc3RhdHVzKSk7CisgICAgICB9CisgICAgICAvKiBvdmVycmlkZSBlbmFibGUgdGhlIGxpbWl0IHN3aXRjaGVzLCB0aGlzIGNpcmN1bXZlbnRzIHRoZSB3ZWJkYXNoICovCisgICAgICBzdGF0dXMgPSBtX2ltcGwtPlNldE92ZXJyaWRlTGltaXRTd2l0Y2hFbigKKyAgICAgICAgICBDYW5UYWxvblNSWDo6a0xpbWl0U3dpdGNoT3ZlcnJpZGVfRGlzYWJsZUZ3ZF9EaXNhYmxlUmV2KTsKKyAgICAgIGlmIChzdGF0dXMgIT0gQ1RSX09LQVkpIHsKKyAgICAgICAgd3BpX3NldEVycm9yV2l0aENvbnRleHQoc3RhdHVzLCBnZXRIQUxFcnJvck1lc3NhZ2Uoc3RhdHVzKSk7CisgICAgICB9CisgICAgICBicmVhazsKKyAgfQorfQorCisvKioKKyAqIFRPRE8gZG9jdW1lbnRhdGlvbiAoc2VlIENBTkphZ3Vhci5jcHApCisgKi8KK3ZvaWQgQ0FOVGFsb246OkNvbmZpZ0ZvcndhcmRMaW1pdChkb3VibGUgZm9yd2FyZExpbWl0UG9zaXRpb24pIHsKKyAgQ1RSX0NvZGUgc3RhdHVzID0gQ1RSX09LQVk7CisgIGludDMyX3QgbmF0aXZlTGltaXRQb3MgPSBTY2FsZVJvdGF0aW9uc1RvTmF0aXZlVW5pdHMobV9mZWVkYmFja0RldmljZSwgZm9yd2FyZExpbWl0UG9zaXRpb24pOworICBzdGF0dXMgPSBtX2ltcGwtPlNldEZvcndhcmRTb2Z0TGltaXQobmF0aXZlTGltaXRQb3MpOworICBpZiAoc3RhdHVzICE9IENUUl9PS0FZKSB7CisgICAgd3BpX3NldEVycm9yV2l0aENvbnRleHQoc3RhdHVzLCBnZXRIQUxFcnJvck1lc3NhZ2Uoc3RhdHVzKSk7CisgIH0KK30KKy8qKgorICogQ2hhbmdlIHRoZSBmd2QgbGltaXQgc3dpdGNoIHNldHRpbmcgdG8gbm9ybWFsbHkgb3BlbiBvciBjbG9zZWQuCisgKiBUYWxvbiB3aWxsIGRpc2FibGUgbW9tZW50YXJpbGx5IGlmIHRoZSBUYWxvbidzIGN1cnJlbnQgc2V0dGluZworICogaXMgZGlzc2ltaWxhciB0byB0aGUgY2FsbGVyJ3MgcmVxdWVzdGVkIHNldHRpbmcuCisgKgorICogU2luY2UgVGFsb24gc2F2ZXMgc2V0dGluZyB0byBmbGFzaCB0aGlzIHNob3VsZCBvbmx5IGFmZmVjdAorICogYSBnaXZlbiBUYWxvbiBpbml0aWFsbHkgZHVyaW5nIHJvYm90IGluc3RhbGwuCisgKgorICogQHBhcmFtIG5vcm1hbGx5T3BlbiB0cnVlIGZvciBub3JtYWxseSBvcGVuLiAgZmFsc2UgZm9yIG5vcm1hbGx5IGNsb3NlZC4KKyAqLwordm9pZCBDQU5UYWxvbjo6Q29uZmlnRndkTGltaXRTd2l0Y2hOb3JtYWxseU9wZW4oYm9vbCBub3JtYWxseU9wZW4pIHsKKyAgQ1RSX0NvZGUgc3RhdHVzID0KKyAgICAgIG1faW1wbC0+U2V0UGFyYW0oQ2FuVGFsb25TUlg6OmVPbkJvb3RfTGltaXRTd2l0Y2hfRm9yd2FyZF9Ob3JtYWxseUNsb3NlZCwKKyAgICAgICAgICAgICAgICAgICAgICAgbm9ybWFsbHlPcGVuID8gMCA6IDEpOworICBpZiAoc3RhdHVzICE9IENUUl9PS0FZKSB7CisgICAgd3BpX3NldEVycm9yV2l0aENvbnRleHQoc3RhdHVzLCBnZXRIQUxFcnJvck1lc3NhZ2Uoc3RhdHVzKSk7CisgIH0KK30KKy8qKgorICogQ2hhbmdlIHRoZSByZXYgbGltaXQgc3dpdGNoIHNldHRpbmcgdG8gbm9ybWFsbHkgb3BlbiBvciBjbG9zZWQuCisgKiBUYWxvbiB3aWxsIGRpc2FibGUgbW9tZW50YXJpbGx5IGlmIHRoZSBUYWxvbidzIGN1cnJlbnQgc2V0dGluZworICogaXMgZGlzc2ltaWxhciB0byB0aGUgY2FsbGVyJ3MgcmVxdWVzdGVkIHNldHRpbmcuCisgKgorICogU2luY2UgVGFsb24gc2F2ZXMgc2V0dGluZyB0byBmbGFzaCB0aGlzIHNob3VsZCBvbmx5IGFmZmVjdAorICogYSBnaXZlbiBUYWxvbiBpbml0aWFsbHkgZHVyaW5nIHJvYm90IGluc3RhbGwuCisgKgorICogQHBhcmFtIG5vcm1hbGx5T3BlbiB0cnVlIGZvciBub3JtYWxseSBvcGVuLiAgZmFsc2UgZm9yIG5vcm1hbGx5IGNsb3NlZC4KKyAqLwordm9pZCBDQU5UYWxvbjo6Q29uZmlnUmV2TGltaXRTd2l0Y2hOb3JtYWxseU9wZW4oYm9vbCBub3JtYWxseU9wZW4pIHsKKyAgQ1RSX0NvZGUgc3RhdHVzID0KKyAgICAgIG1faW1wbC0+U2V0UGFyYW0oQ2FuVGFsb25TUlg6OmVPbkJvb3RfTGltaXRTd2l0Y2hfUmV2ZXJzZV9Ob3JtYWxseUNsb3NlZCwKKyAgICAgICAgICAgICAgICAgICAgICAgbm9ybWFsbHlPcGVuID8gMCA6IDEpOworICBpZiAoc3RhdHVzICE9IENUUl9PS0FZKSB7CisgICAgd3BpX3NldEVycm9yV2l0aENvbnRleHQoc3RhdHVzLCBnZXRIQUxFcnJvck1lc3NhZ2Uoc3RhdHVzKSk7CisgIH0KK30KKy8qKgorICogVE9ETyBkb2N1bWVudGF0aW9uIChzZWUgQ0FOSmFndWFyLmNwcCkKKyAqLwordm9pZCBDQU5UYWxvbjo6Q29uZmlnUmV2ZXJzZUxpbWl0KGRvdWJsZSByZXZlcnNlTGltaXRQb3NpdGlvbikgeworICBDVFJfQ29kZSBzdGF0dXMgPSBDVFJfT0tBWTsKKyAgaW50MzJfdCBuYXRpdmVMaW1pdFBvcyA9IFNjYWxlUm90YXRpb25zVG9OYXRpdmVVbml0cyhtX2ZlZWRiYWNrRGV2aWNlLCByZXZlcnNlTGltaXRQb3NpdGlvbik7CisgIHN0YXR1cyA9IG1faW1wbC0+U2V0UmV2ZXJzZVNvZnRMaW1pdChuYXRpdmVMaW1pdFBvcyk7CisgIGlmIChzdGF0dXMgIT0gQ1RSX09LQVkpIHsKKyAgICB3cGlfc2V0RXJyb3JXaXRoQ29udGV4dChzdGF0dXMsIGdldEhBTEVycm9yTWVzc2FnZShzdGF0dXMpKTsKKyAgfQorfQorLyoqCisgKiBUT0RPIGRvY3VtZW50YXRpb24gKHNlZSBDQU5KYWd1YXIuY3BwKQorICovCit2b2lkIENBTlRhbG9uOjpDb25maWdNYXhPdXRwdXRWb2x0YWdlKGRvdWJsZSB2b2x0YWdlKSB7CisgIC8qIGNvbmZpZyBwZWFrIHRocm90dGxlIHdoZW4gaW4gY2xvc2VkLWxvb3AgbW9kZSBpbiB0aGUgZndkIGFuZCByZXYgZGlyZWN0aW9uLiAqLworICBDb25maWdQZWFrT3V0cHV0Vm9sdGFnZSh2b2x0YWdlLCAtdm9sdGFnZSk7Cit9Cit2b2lkIENBTlRhbG9uOjpDb25maWdQZWFrT3V0cHV0Vm9sdGFnZShkb3VibGUgZm9yd2FyZFZvbHRhZ2UsZG91YmxlIHJldmVyc2VWb2x0YWdlKSB7CisgIC8qIGJvdW5kcyBjaGVja2luZyAqLworICBpZiAoZm9yd2FyZFZvbHRhZ2UgPiAxMikKKyAgICBmb3J3YXJkVm9sdGFnZSA9IDEyOworICBlbHNlIGlmIChmb3J3YXJkVm9sdGFnZSA8IDApCisgICAgZm9yd2FyZFZvbHRhZ2UgPSAwOworICBpZiAocmV2ZXJzZVZvbHRhZ2UgPiAwKQorICAgIHJldmVyc2VWb2x0YWdlID0gMDsKKyAgZWxzZSBpZiAocmV2ZXJzZVZvbHRhZ2UgPCAtMTIpCisgICAgcmV2ZXJzZVZvbHRhZ2UgPSAtMTI7CisgIC8qIGNvbmZpZyBjYWxscyAqLworICBDb25maWdTZXRQYXJhbWV0ZXIoQ2FuVGFsb25TUlg6OmVQZWFrUG9zT3V0cHV0LCAxMDIzICogZm9yd2FyZFZvbHRhZ2UgLyAxMi4wKTsKKyAgQ29uZmlnU2V0UGFyYW1ldGVyKENhblRhbG9uU1JYOjplUGVha05lZ091dHB1dCwgMTAyMyAqIHJldmVyc2VWb2x0YWdlIC8gMTIuMCk7Cit9Cit2b2lkIENBTlRhbG9uOjpDb25maWdOb21pbmFsT3V0cHV0Vm9sdGFnZShkb3VibGUgZm9yd2FyZFZvbHRhZ2UsZG91YmxlIHJldmVyc2VWb2x0YWdlKSB7CisgIC8qIGJvdW5kcyBjaGVja2luZyAqLworICBpZiAoZm9yd2FyZFZvbHRhZ2UgPiAxMikKKyAgICBmb3J3YXJkVm9sdGFnZSA9IDEyOworICBlbHNlIGlmIChmb3J3YXJkVm9sdGFnZSA8IDApCisgICAgZm9yd2FyZFZvbHRhZ2UgPSAwOworICBpZiAocmV2ZXJzZVZvbHRhZ2UgPiAwKQorICAgIHJldmVyc2VWb2x0YWdlID0gMDsKKyAgZWxzZSBpZiAocmV2ZXJzZVZvbHRhZ2UgPCAtMTIpCisgICAgcmV2ZXJzZVZvbHRhZ2UgPSAtMTI7CisgIC8qIGNvbmZpZyBjYWxscyAqLworICBDb25maWdTZXRQYXJhbWV0ZXIoQ2FuVGFsb25TUlg6OmVOb21pbmFsUG9zT3V0cHV0LDEwMjMqZm9yd2FyZFZvbHRhZ2UvMTIuMCk7CisgIENvbmZpZ1NldFBhcmFtZXRlcihDYW5UYWxvblNSWDo6ZU5vbWluYWxOZWdPdXRwdXQsMTAyMypyZXZlcnNlVm9sdGFnZS8xMi4wKTsKK30KKy8qKgorICogR2VuZXJhbCBzZXQgZnJhbWUuICBTaW5jZSB0aGUgcGFyYW1ldGVyIGlzIGEgZ2VuZXJhbCBpbnRlZ3JhbCB0eXBlLCB0aGlzIGNhbgorICogYmUgdXNlZCBmb3IgdGVzdGluZyBmdXR1cmUgZmVhdHVyZXMuCisgKi8KK3ZvaWQgQ0FOVGFsb246OkNvbmZpZ1NldFBhcmFtZXRlcih1aW50MzJfdCBwYXJhbUVudW0sIGRvdWJsZSB2YWx1ZSkgeworICBDVFJfQ29kZSBzdGF0dXM7CisgIC8qIGNvbmZpZyBwZWFrIHRocm90dGxlIHdoZW4gaW4gY2xvc2VkLWxvb3AgbW9kZSBpbiB0aGUgcG9zaXRpdmUgZGlyZWN0aW9uLiAqLworICBzdGF0dXMgPSBtX2ltcGwtPlNldFBhcmFtKChDYW5UYWxvblNSWDo6cGFyYW1fdClwYXJhbUVudW0sdmFsdWUpOworICBpZiAoc3RhdHVzICE9IENUUl9PS0FZKSB7CisgICAgd3BpX3NldEVycm9yV2l0aENvbnRleHQoc3RhdHVzLCBnZXRIQUxFcnJvck1lc3NhZ2Uoc3RhdHVzKSk7CisgIH0KK30KKy8qKgorICogR2VuZXJhbCBnZXQgZnJhbWUuICBTaW5jZSB0aGUgcGFyYW1ldGVyIGlzIGEgZ2VuZXJhbCBpbnRlZ3JhbCB0eXBlLCB0aGlzIGNhbgorICogYmUgdXNlZCBmb3IgdGVzdGluZyBmdXR1cmUgZmVhdHVyZXMuCisgKi8KK2Jvb2wgQ0FOVGFsb246OkdldFBhcmFtZXRlcih1aW50MzJfdCBwYXJhbUVudW0sIGRvdWJsZSAmIGR2YWx1ZSkgY29uc3QgeworICBib29sIHJldHZhbCA9IHRydWU7CisgIC8qIHNlbmQgdGhlIHJlcXVlc3QgZnJhbWUgKi8KKyAgQ1RSX0NvZGUgc3RhdHVzID0gbV9pbXBsLT5SZXF1ZXN0UGFyYW0oKENhblRhbG9uU1JYOjpwYXJhbV90KXBhcmFtRW51bSk7CisgIGlmIChzdGF0dXMgIT0gQ1RSX09LQVkpIHsKKyAgICB3cGlfc2V0RXJyb3JXaXRoQ29udGV4dChzdGF0dXMsIGdldEhBTEVycm9yTWVzc2FnZShzdGF0dXMpKTsKKyAgICByZXR2YWwgPSBmYWxzZTsKKyAgfQorICAvKiBzbWFsbCB5aWVsZCBmb3IgZ2V0dGluZyByZXNwb25zZSAqLworICB1c2xlZXAoa0RlbGF5Rm9yU29saWNpdGVkU2lnbmFsc1VzKTsKKyAgLyogZ2V0IHRoZSBsYXN0IHJlY2VpdmVkIHVwZGF0ZSAqLworICBzdGF0dXMgPSBtX2ltcGwtPkdldFBhcmFtUmVzcG9uc2UoKENhblRhbG9uU1JYOjpwYXJhbV90KXBhcmFtRW51bSwgZHZhbHVlKTsKKyAgaWYgKHN0YXR1cyAhPSBDVFJfT0tBWSkgeworICAgIHdwaV9zZXRFcnJvcldpdGhDb250ZXh0KHN0YXR1cywgZ2V0SEFMRXJyb3JNZXNzYWdlKHN0YXR1cykpOworICAgIHJldHZhbCA9IGZhbHNlOworICB9CisgIHJldHVybiByZXR2YWw7Cit9CisKKy8qKgorICogVE9ETyBkb2N1bWVudGF0aW9uIChzZWUgQ0FOSmFndWFyLmNwcCkKKyAqLwordm9pZCBDQU5UYWxvbjo6Q29uZmlnRmF1bHRUaW1lKGZsb2F0IGZhdWx0VGltZSkgeworICAvKiBTUlggZG9lcyBub3QgaGF2ZSBmYXVsdCB0aW1lLiAgU1JYIG1vdG9yIGRyaXZlIGlzIG9ubHkgZGlzYWJsZWQgZm9yIHNvZnQKKyAgICogbGltaXRzIGFuZCBsaW1pdC1zd2l0Y2ggZmF1bHRzLiAqLworICB3cGlfc2V0V1BJRXJyb3JXaXRoQ29udGV4dChJbmNvbXBhdGlibGVNb2RlLCAiRmF1bHQgVGltZSBub3Qgc3VwcG9ydGVkLiIpOworfQorCisvKioKKyAqIEZpeHVwIHRoZSBzZW5kTW9kZSBzbyBTZXQoKSBzZXJpYWxpemVzIHRoZSBjb3JyZWN0IGRlbWFuZCB2YWx1ZS4KKyAqIEFsc28gZmlsbHMgdGhlIG1vZGVTZWxlY2V0IGluIHRoZSBjb250cm9sIGZyYW1lIHRvIGRpc2FibGVkLgorICogQHBhcmFtIG1vZGUgQ29udHJvbCBtb2RlIHRvIHVsdGltYXRlbHkgZW50ZXIgb25jZSB1c2VyIGNhbGxzIFNldCgpLgorICogQHNlZSBTZXQoKQorICovCit2b2lkIENBTlRhbG9uOjpBcHBseUNvbnRyb2xNb2RlKENBTlNwZWVkQ29udHJvbGxlcjo6Q29udHJvbE1vZGUgbW9kZSkgeworICBtX2NvbnRyb2xNb2RlID0gbW9kZTsKKyAgSEFMUmVwb3J0KEhBTFVzYWdlUmVwb3J0aW5nOjprUmVzb3VyY2VUeXBlX0NBTlRhbG9uU1JYLCBtX2RldmljZU51bWJlciArIDEsCisgICAgICAgICAgICBtb2RlKTsKKyAgc3dpdGNoIChtb2RlKSB7CisgICAgY2FzZSBrUGVyY2VudFZidXM6CisgICAgICBtX3NlbmRNb2RlID0ga1Rocm90dGxlOworICAgICAgYnJlYWs7CisgICAgY2FzZSBrQ3VycmVudDoKKyAgICAgIG1fc2VuZE1vZGUgPSBrQ3VycmVudE1vZGU7CisgICAgICBicmVhazsKKyAgICBjYXNlIGtTcGVlZDoKKyAgICAgIG1fc2VuZE1vZGUgPSBrU3BlZWRNb2RlOworICAgICAgYnJlYWs7CisgICAgY2FzZSBrUG9zaXRpb246CisgICAgICBtX3NlbmRNb2RlID0ga1Bvc2l0aW9uTW9kZTsKKyAgICAgIGJyZWFrOworICAgIGNhc2Uga1ZvbHRhZ2U6CisgICAgICBtX3NlbmRNb2RlID0ga1ZvbHRhZ2VNb2RlOworICAgICAgYnJlYWs7CisgICAgY2FzZSBrRm9sbG93ZXI6CisgICAgICBtX3NlbmRNb2RlID0ga0ZvbGxvd2VyTW9kZTsKKyAgICAgIGJyZWFrOworICB9CisgIC8vIEtlZXAgdGhlIHRhbG9uIGRpc2FibGVkIHVudGlsIFNldCgpIGlzIGNhbGxlZC4KKyAgQ1RSX0NvZGUgc3RhdHVzID0gbV9pbXBsLT5TZXRNb2RlU2VsZWN0KChpbnQpa0Rpc2FibGVkKTsKKyAgaWYgKHN0YXR1cyAhPSBDVFJfT0tBWSkgeworICAgIHdwaV9zZXRFcnJvcldpdGhDb250ZXh0KHN0YXR1cywgZ2V0SEFMRXJyb3JNZXNzYWdlKHN0YXR1cykpOworICB9Cit9CisvKioKKyAqIFRPRE8gZG9jdW1lbnRhdGlvbiAoc2VlIENBTkphZ3Vhci5jcHApCisgKi8KK3ZvaWQgQ0FOVGFsb246OlNldENvbnRyb2xNb2RlKENBTlNwZWVkQ29udHJvbGxlcjo6Q29udHJvbE1vZGUgbW9kZSkgeworICBpZiAobV9jb250cm9sTW9kZSA9PSBtb2RlKSB7CisgICAgLyogd2UgYWxyZWFkeSBhcmUgaW4gdGhpcyBtb2RlLCBkb24ndCBwZXJmb3JtIGRpc2FibGUgd29ya2Fyb3VuZCAqLworICB9IGVsc2UgeworICAgIEFwcGx5Q29udHJvbE1vZGUobW9kZSk7CisgIH0KK30KKworLyoqCisgKiBUT0RPIGRvY3VtZW50YXRpb24gKHNlZSBDQU5KYWd1YXIuY3BwKQorICovCitDQU5TcGVlZENvbnRyb2xsZXI6OkNvbnRyb2xNb2RlIENBTlRhbG9uOjpHZXRDb250cm9sTW9kZSgpIGNvbnN0IHsKKyAgcmV0dXJuIG1fY29udHJvbE1vZGU7Cit9CisKK3ZvaWQgQ0FOVGFsb246OlNldEV4cGlyYXRpb24oZmxvYXQgdGltZW91dCkgeworICBtX3NhZmV0eUhlbHBlci0+U2V0RXhwaXJhdGlvbih0aW1lb3V0KTsKK30KKworZmxvYXQgQ0FOVGFsb246OkdldEV4cGlyYXRpb24oKSBjb25zdCB7CisgIHJldHVybiBtX3NhZmV0eUhlbHBlci0+R2V0RXhwaXJhdGlvbigpOworfQorCitib29sIENBTlRhbG9uOjpJc0FsaXZlKCkgY29uc3QgeyByZXR1cm4gbV9zYWZldHlIZWxwZXItPklzQWxpdmUoKTsgfQorCitib29sIENBTlRhbG9uOjpJc1NhZmV0eUVuYWJsZWQoKSBjb25zdCB7CisgIHJldHVybiBtX3NhZmV0eUhlbHBlci0+SXNTYWZldHlFbmFibGVkKCk7Cit9CisKK3ZvaWQgQ0FOVGFsb246OlNldFNhZmV0eUVuYWJsZWQoYm9vbCBlbmFibGVkKSB7CisgIG1fc2FmZXR5SGVscGVyLT5TZXRTYWZldHlFbmFibGVkKGVuYWJsZWQpOworfQorCit2b2lkIENBTlRhbG9uOjpHZXREZXNjcmlwdGlvbihzdGQ6Om9zdHJpbmdzdHJlYW0mIGRlc2MpIGNvbnN0IHsKKyAgZGVzYyA8PCAiQ0FOVGFsb24gSUQgIiA8PCAgbV9kZXZpY2VOdW1iZXI7Cit9CisvKioKKyAqIEBwYXJhbSBkZXZUb0xvb2t1cCBGZWVkYmFja0RldmljZSB0byBsb29rdXAgdGhlIHNjYWxhciBmb3IuICBCZWNhdXNlIFRhbG9uCisgKiAgICAgICAgICAgIGFsbG93cyBtdWx0aXBsZSBzZW5zb3JzIHRvIGJlIGF0dGFjaGVkIHNpbXVsdGFuZW91c2x5LCBjYWxsZXIgbXVzdAorICogICAgICAgICAgICBzcGVjaWZ5IHdoaWNoIHNlbnNvciB0byBsb29rdXAuCisgKiBAcmV0dXJuICAgIFRoZSBudW1iZXIgb2YgbmF0aXZlIFRhbG9uIHVuaXRzIHBlciByb3RhdGlvbiBvZiB0aGUgc2VsZWN0ZWQgc2Vuc29yLgorICogICAgICAgICAgICBaZXJvIGlmIHRoZSBuZWNlc3Nhcnkgc2Vuc29yIGluZm9ybWF0aW9uIGlzIG5vdCBhdmFpbGFibGUuCisgKiBAc2VlIENvbmZpZ0VuY29kZXJDb2Rlc1BlclJldgorICogQHNlZSBDb25maWdQb3RlbnRpb21ldGVyVHVybnMKKyAqLworZG91YmxlIENBTlRhbG9uOjpHZXROYXRpdmVVbml0c1BlclJvdGF0aW9uU2NhbGFyKEZlZWRiYWNrRGV2aWNlIGRldlRvTG9va3VwKWNvbnN0Cit7CisgIGJvb2wgc2NhbGluZ0F2YWlsID0gZmFsc2U7CisgIENUUl9Db2RlIHN0YXR1cyA9IENUUl9PS0FZOworICBkb3VibGUgcmV0dmFsID0gMDsKKyAgc3dpdGNoIChkZXZUb0xvb2t1cCkgeworICAgIGNhc2UgUXVhZEVuY29kZXI6CisgICAgeyAvKiBXaGVuIGNhbGxlciB3YW50cyB0byBsb29rdXAgUXVhZHJhdHVyZSwgdGhlIFFFSSBtYXkgYmUgaW4gMXggaWYgdGhlIHNlbGVjdGVkIGZlZWRiYWNrIGlzIGVkZ2UgY291bnRlci4KKyAgICAgICAqIEFkZGl0aW9uYWxseSBpZiB0aGUgcXVhZHJhdHVyZSBzb3VyY2UgaXMgdGhlIENUUkUgTWFnIGVuY29kZXIsIHRoZW4gdGhlIENQUiBpcyBrbm93bi4KKyAgICAgICAqIFRoaXMgaXMgbmljZSBpbiB0aGF0IHRoZSBjYWxsaW5nIGFwcCBkb2VzIG5vdCByZXF1aXJlIGtub3dpbmcgdGhlIENQUiBhdCBhbGwuCisgICAgICAgKiBTbyBkbyBib3RoIGNoZWNrcyBoZXJlLgorICAgICAgICovCisgICAgICBpbnQzMl90IHFlaVB1bHNlUGVyQ291bnQgPSA0OyAvKiBkZWZhdWx0IHRvIDR4ICovCisgICAgICBzd2l0Y2ggKG1fZmVlZGJhY2tEZXZpY2UpIHsKKyAgICAgICAgY2FzZSBDdHJlTWFnRW5jb2Rlcl9SZWxhdGl2ZToKKyAgICAgICAgY2FzZSBDdHJlTWFnRW5jb2Rlcl9BYnNvbHV0ZToKKyAgICAgICAgICAvKiB3ZSBhc3N1bWUgdGhlIHF1YWRyYXR1cmUgc2lnbmFsIGNvbWVzIGZyb20gdGhlIE1hZ0VuYywKKyAgICAgICAgICAgIG9mIHdoaWNoIHdlIGtub3cgdGhlIENQUiBhbHJlYWR5ICovCisgICAgICAgICAgcmV0dmFsID0ga05hdGl2ZVB3ZFVuaXRzUGVyUm90YXRpb247CisgICAgICAgICAgc2NhbGluZ0F2YWlsID0gdHJ1ZTsKKyAgICAgICAgICBicmVhazsKKyAgICAgICAgY2FzZSBFbmNSaXNpbmc6IC8qIFRhbG9uJ3MgUUVJIGlzIHNldHVwIGZvciAxeCwgc28gcGVyZm9ybSAxeCBtYXRoICovCisgICAgICAgIGNhc2UgRW5jRmFsbGluZzoKKyAgICAgICAgICBxZWlQdWxzZVBlckNvdW50ID0gMTsKKyAgICAgICAgICBicmVhazsKKyAgICAgICAgY2FzZSBRdWFkRW5jb2RlcjogLyogVGFsb24ncyBRRUkgaXMgNHggKi8KKyAgICAgICAgZGVmYXVsdDogLyogcHVsc2Ugd2lkdGggYW5kIGV2ZXJ5dGhpbmcgZWxzZSwgYXNzdW1lIGl0cyByZWd1bGFyIHF1YWQgdXNlLiAqLworICAgICAgICAgIGJyZWFrOworICAgICAgfQorICAgICAgaWYgKHNjYWxpbmdBdmFpbCkgeworICAgICAgICAvKiBhbHJlYWR5IGRlZHVjZWQgdGhlIHNjYWxhciBhYm92ZSwgd2UncmUgZG9uZS4gKi8KKyAgICAgIH0gZWxzZSB7CisgICAgICAgIC8qIHdlIGNvdWxkbid0IGRlZHVjZSB0aGUgc2NhbGFyIGp1c3QgYmFzZWQgb24gdGhlIHNlbGVjdGlvbiAqLworICAgICAgICBpZiAoMCA9PSBtX2NvZGVzUGVyUmV2KSB7CisgICAgICAgICAgLyogY2FsbGVyIGhhcyBuZXZlciBzZXQgdGhlIENQUi4gIE1vc3QgbGlrZWx5IGNhbGxlcgorICAgICAgICAgICAgaXMganVzdCB1c2luZyBlbmdpbmVlcmluZyB1bml0cyBzbyBmYWxsIHRvIHRoZQorICAgICAgICAgICAgYm90dG9tIG9mIHRoaXMgZnVuYy4qLworICAgICAgICB9IGVsc2UgeworICAgICAgICAgIC8qIFRhbG9uIGV4cGVjdHMgUFBSIHVuaXRzICovCisgICAgICAgICAgcmV0dmFsID0gcWVpUHVsc2VQZXJDb3VudCAqIG1fY29kZXNQZXJSZXY7CisgICAgICAgICAgc2NhbGluZ0F2YWlsID0gdHJ1ZTsKKyAgICAgICAgfQorICAgICAgfQorICAgIH0gIGJyZWFrOworICAgIGNhc2UgRW5jUmlzaW5nOgorICAgIGNhc2UgRW5jRmFsbGluZzoKKyAgICAgIGlmICgwID09IG1fY29kZXNQZXJSZXYpIHsKKyAgICAgICAgLyogY2FsbGVyIGhhcyBuZXZlciBzZXQgdGhlIENQUi4gIE1vc3QgbGlrZWx5IGNhbGxlcgorICAgICAgICAgIGlzIGp1c3QgdXNpbmcgZW5naW5lZXJpbmcgdW5pdHMgc28gZmFsbCB0byB0aGUKKyAgICAgICAgICBib3R0b20gb2YgdGhpcyBmdW5jLiovCisgICAgICB9IGVsc2UgeworICAgICAgICAvKiBUYWxvbiBleHBlY3RzIFBQUiB1bml0cyAqLworICAgICAgICByZXR2YWwgPSAxICogbV9jb2Rlc1BlclJldjsKKyAgICAgICAgc2NhbGluZ0F2YWlsID0gdHJ1ZTsKKyAgICAgIH0KKyAgICAgIGJyZWFrOworICAgIGNhc2UgQW5hbG9nUG90OgorICAgIGNhc2UgQW5hbG9nRW5jb2RlcjoKKyAgICAgIGlmICgwID09IG1fbnVtUG90VHVybnMpIHsKKyAgICAgICAgLyogY2FsbGVyIGhhcyBuZXZlciBzZXQgdGhlIENQUi4gIE1vc3QgbGlrZWx5IGNhbGxlcgorICAgICAgICAgIGlzIGp1c3QgdXNpbmcgZW5naW5lZXJpbmcgdW5pdHMgc28gZmFsbCB0byB0aGUKKyAgICAgICAgICBib3R0b20gb2YgdGhpcyBmdW5jLiovCisgICAgICB9IGVsc2UgeworICAgICAgICByZXR2YWwgPSAoZG91YmxlKWtOYXRpdmVBZGNVbml0c1BlclJvdGF0aW9uIC8gbV9udW1Qb3RUdXJuczsKKyAgICAgICAgc2NhbGluZ0F2YWlsID0gdHJ1ZTsKKyAgICAgIH0KKyAgICAgIGJyZWFrOworICAgIGNhc2UgQ3RyZU1hZ0VuY29kZXJfUmVsYXRpdmU6CisgICAgY2FzZSBDdHJlTWFnRW5jb2Rlcl9BYnNvbHV0ZToKKyAgICBjYXNlIFB1bHNlV2lkdGg6CisgICAgICByZXR2YWwgPSBrTmF0aXZlUHdkVW5pdHNQZXJSb3RhdGlvbjsKKyAgICAgIHNjYWxpbmdBdmFpbCA9IHRydWU7CisgICAgICBicmVhazsKKyAgfQorICAvKiBoYW5kbGUgYW55IGRldGVjdGVkIGVycm9ycyAqLworICBpZiAoc3RhdHVzICE9IENUUl9PS0FZKSB7CisgICAgd3BpX3NldEVycm9yV2l0aENvbnRleHQoc3RhdHVzLCBnZXRIQUxFcnJvck1lc3NhZ2Uoc3RhdHVzKSk7CisgIH0KKyAgLyogaWYgc2NhbGluZyBpbmZvcm1hdGlvbiBpcyBub3QgcG9zc2libGUsIHNpZ25hbCBjYWxsZXIKKyAgICBieSByZXR1cm5pbmcgemVybyAqLworICBpZiAoZmFsc2UgPT0gc2NhbGluZ0F2YWlsKQorICAgIHJldHZhbCA9IDA7CisgIHJldHVybiByZXR2YWw7Cit9CisvKioKKyAqIEBwYXJhbSBmdWxsUm90YXRpb25zICAgZG91YmxlIHByZWNpc2lvbiB2YWx1ZSByZXByZXNlbnRpbmcgbnVtYmVyIG9mIHJvdGF0aW9ucyBvZiBzZWxlY3RlZCBmZWVkYmFjayBzZW5zb3IuCisgKiAgICAgICAgICAgICAgSWYgdXNlciBoYXMgbmV2ZXIgY2FsbGVkIHRoZSBjb25maWcgcm91dGluZSBmb3IgdGhlIHNlbGVjdGVkIHNlbnNvciwgdGhlbiB0aGUgY2FsbGVyCisgKiAgICAgICAgICAgICAgaXMgbGlrZWx5IHBhc3Npbmcgcm90YXRpb25zIGluIGVuZ2luZWVyaW5nIHVuaXRzIGFscmVhZHksIGluIHdoaWNoIGNhc2UgaXQgaXMgcmV0dXJuZWQKKyAqICAgICAgICAgICAgICBhcyBpcy4KKyAqICAgICAgICAgICAgICBAc2VlIENvbmZpZ1BvdGVudGlvbWV0ZXJUdXJucworICogICAgICAgICAgICAgIEBzZWUgQ29uZmlnRW5jb2RlckNvZGVzUGVyUmV2CisgKiBAcmV0dXJuIGZ1bGxSb3RhdGlvbnMgaW4gbmF0aXZlIGVuZ2luZWVyaW5nIHVuaXRzIG9mIHRoZSBUYWxvbiBTUlggZmlybXdhcmUuCisgKi8KK2ludDMyX3QgQ0FOVGFsb246OlNjYWxlUm90YXRpb25zVG9OYXRpdmVVbml0cyhGZWVkYmFja0RldmljZSBkZXZUb0xvb2t1cCxkb3VibGUgZnVsbFJvdGF0aW9ucyljb25zdAoreworICAvKiBmaXJzdCBhc3N1bWUgd2UgZG9uJ3QgaGF2ZSBjb25maWcgaW5mbywgcHJlcCB0aGUgZGVmYXVsdCByZXR1cm4gKi8KKyAgaW50MzJfdCByZXR2YWwgPSAoaW50MzJfdClmdWxsUm90YXRpb25zOworICAvKiByZXRyaWV2ZSBzY2FsaW5nIGluZm8gKi8KKyAgZG91YmxlIHNjYWxhciA9IEdldE5hdGl2ZVVuaXRzUGVyUm90YXRpb25TY2FsYXIoZGV2VG9Mb29rdXApOworICAvKiBhcHBseSBzY2FsYXIgaWYgaXRzIGF2YWlsYWJsZSAqLworICBpZiAoc2NhbGFyID4gMCkKKyAgICByZXR2YWwgPSAoaW50MzJfdCkoZnVsbFJvdGF0aW9ucypzY2FsYXIpOworICByZXR1cm4gcmV0dmFsOworfQorLyoqCisgKiBAcGFyYW0gcnBtICAgZG91YmxlIHByZWNpc2lvbiB2YWx1ZSByZXByZXNlbnRpbmcgbnVtYmVyIG9mIHJvdGF0aW9ucyBwZXIgbWludXRlIG9mIHNlbGVjdGVkIGZlZWRiYWNrIHNlbnNvci4KKyAqICAgICAgICAgICAgICBJZiB1c2VyIGhhcyBuZXZlciBjYWxsZWQgdGhlIGNvbmZpZyByb3V0aW5lIGZvciB0aGUgc2VsZWN0ZWQgc2Vuc29yLCB0aGVuIHRoZSBjYWxsZXIKKyAqICAgICAgICAgICAgICBpcyBsaWtlbHkgcGFzc2luZyByb3RhdGlvbnMgaW4gZW5naW5lZXJpbmcgdW5pdHMgYWxyZWFkeSwgaW4gd2hpY2ggY2FzZSBpdCBpcyByZXR1cm5lZAorICogICAgICAgICAgICAgIGFzIGlzLgorICogICAgICAgICAgICAgIEBzZWUgQ29uZmlnUG90ZW50aW9tZXRlclR1cm5zCisgKiAgICAgICAgICAgICAgQHNlZSBDb25maWdFbmNvZGVyQ29kZXNQZXJSZXYKKyAqIEByZXR1cm4gc2Vuc29yIHZlbG9jaXR5IGluIG5hdGl2ZSBlbmdpbmVlcmluZyB1bml0cyBvZiB0aGUgVGFsb24gU1JYIGZpcm13YXJlLgorICovCitpbnQzMl90IENBTlRhbG9uOjpTY2FsZVZlbG9jaXR5VG9OYXRpdmVVbml0cyhGZWVkYmFja0RldmljZSBkZXZUb0xvb2t1cCxkb3VibGUgcnBtKWNvbnN0Cit7CisgIC8qIGZpcnN0IGFzc3VtZSB3ZSBkb24ndCBoYXZlIGNvbmZpZyBpbmZvLCBwcmVwIHRoZSBkZWZhdWx0IHJldHVybiAqLworICBpbnQzMl90IHJldHZhbCA9IChpbnQzMl90KXJwbTsKKyAgLyogcmV0cmlldmUgc2NhbGluZyBpbmZvICovCisgIGRvdWJsZSBzY2FsYXIgPSBHZXROYXRpdmVVbml0c1BlclJvdGF0aW9uU2NhbGFyKGRldlRvTG9va3VwKTsKKyAgLyogYXBwbHkgc2NhbGFyIGlmIGl0cyBhdmFpbGFibGUgKi8KKyAgaWYgKHNjYWxhciA+IDApCisgICAgcmV0dmFsID0gKGludDMyX3QpKHJwbSAqIGtNaW51dGVzUGVyMTAwbXNVbml0ICogc2NhbGFyKTsKKyAgcmV0dXJuIHJldHZhbDsKK30KKy8qKgorICogQHBhcmFtIG5hdGl2ZVBvcyAgIGludGVncmFsIHBvc2l0aW9uIG9mIHRoZSBmZWVkYmFjayBzZW5zb3IgaW4gbmF0aXZlIFRhbG9uIFNSWCB1bml0cy4KKyAqICAgICAgICAgICAgICBJZiB1c2VyIGhhcyBuZXZlciBjYWxsZWQgdGhlIGNvbmZpZyByb3V0aW5lIGZvciB0aGUgc2VsZWN0ZWQgc2Vuc29yLCB0aGVuIHRoZSByZXR1cm4KKyAqICAgICAgICAgICAgICB3aWxsIGJlIGluIFRBTE9OIFNSWCB1bml0cyBhcyB3ZWxsIHRvIG1hdGNoIHRoZSBiZWhhdmlvciBpbiB0aGUgMjAxNSBzZWFzb24uCisgKiAgICAgICAgICAgICAgQHNlZSBDb25maWdQb3RlbnRpb21ldGVyVHVybnMKKyAqICAgICAgICAgICAgICBAc2VlIENvbmZpZ0VuY29kZXJDb2Rlc1BlclJldgorICogQHJldHVybiBkb3VibGUgcHJlY2lzaW9uIG51bWJlciBvZiByb3RhdGlvbnMsIHVubGVzcyBjb25maWcgd2FzIG5ldmVyIHBlcmZvcm1lZC4KKyAqLworZG91YmxlIENBTlRhbG9uOjpTY2FsZU5hdGl2ZVVuaXRzVG9Sb3RhdGlvbnMoRmVlZGJhY2tEZXZpY2UgZGV2VG9Mb29rdXAsaW50MzJfdCBuYXRpdmVQb3MpY29uc3QKK3sKKyAgLyogZmlyc3QgYXNzdW1lIHdlIGRvbid0IGhhdmUgY29uZmlnIGluZm8sIHByZXAgdGhlIGRlZmF1bHQgcmV0dXJuICovCisgIGRvdWJsZSByZXR2YWwgPSAoZG91YmxlKW5hdGl2ZVBvczsKKyAgLyogcmV0cmlldmUgc2NhbGluZyBpbmZvICovCisgIGRvdWJsZSBzY2FsYXIgPSBHZXROYXRpdmVVbml0c1BlclJvdGF0aW9uU2NhbGFyKGRldlRvTG9va3VwKTsKKyAgLyogYXBwbHkgc2NhbGFyIGlmIGl0cyBhdmFpbGFibGUgKi8KKyAgaWYgKHNjYWxhciA+IDApCisgICAgcmV0dmFsID0gKChkb3VibGUpbmF0aXZlUG9zKSAvIHNjYWxhcjsKKyAgcmV0dXJuIHJldHZhbDsKK30KKy8qKgorICogQHBhcmFtIG5hdGl2ZVZlbCAgIGludGVncmFsIHZlbG9jaXR5IG9mIHRoZSBmZWVkYmFjayBzZW5zb3IgaW4gbmF0aXZlIFRhbG9uIFNSWCB1bml0cy4KKyAqICAgICAgICAgICAgICBJZiB1c2VyIGhhcyBuZXZlciBjYWxsZWQgdGhlIGNvbmZpZyByb3V0aW5lIGZvciB0aGUgc2VsZWN0ZWQgc2Vuc29yLCB0aGVuIHRoZSByZXR1cm4KKyAqICAgICAgICAgICAgICB3aWxsIGJlIGluIFRBTE9OIFNSWCB1bml0cyBhcyB3ZWxsIHRvIG1hdGNoIHRoZSBiZWhhdmlvciBpbiB0aGUgMjAxNSBzZWFzb24uCisgKiAgICAgICAgICAgICAgQHNlZSBDb25maWdQb3RlbnRpb21ldGVyVHVybnMKKyAqICAgICAgICAgICAgICBAc2VlIENvbmZpZ0VuY29kZXJDb2Rlc1BlclJldgorICogQHJldHVybiBkb3VibGUgcHJlY2lzaW9uIG9mIHNlbnNvciB2ZWxvY2l0eSBpbiBSUE0sIHVubGVzcyBjb25maWcgd2FzIG5ldmVyIHBlcmZvcm1lZC4KKyAqLworZG91YmxlIENBTlRhbG9uOjpTY2FsZU5hdGl2ZVVuaXRzVG9ScG0oRmVlZGJhY2tEZXZpY2UgZGV2VG9Mb29rdXAsIGludDMyX3QgbmF0aXZlVmVsKWNvbnN0Cit7CisgIC8qIGZpcnN0IGFzc3VtZSB3ZSBkb24ndCBoYXZlIGNvbmZpZyBpbmZvLCBwcmVwIHRoZSBkZWZhdWx0IHJldHVybiAqLworICBkb3VibGUgcmV0dmFsID0gKGRvdWJsZSluYXRpdmVWZWw7CisgIC8qIHJldHJpZXZlIHNjYWxpbmcgaW5mbyAqLworICBkb3VibGUgc2NhbGFyID0gR2V0TmF0aXZlVW5pdHNQZXJSb3RhdGlvblNjYWxhcihkZXZUb0xvb2t1cCk7CisgIC8qIGFwcGx5IHNjYWxhciBpZiBpdHMgYXZhaWxhYmxlICovCisgIGlmIChzY2FsYXIgPiAwKQorICAgIHJldHZhbCA9IChkb3VibGUpKG5hdGl2ZVZlbCkgLyAoc2NhbGFyKmtNaW51dGVzUGVyMTAwbXNVbml0KTsKKyAgcmV0dXJuIHJldHZhbDsKK30KKworLyoqCisgKiBFbmFibGVzIFRhbG9uIFNSWCB0byBhdXRvbWF0aWNhbGx5IHplcm8gdGhlIFNlbnNvciBQb3NpdGlvbiB3aGVuZXZlciBhbgorICogZWRnZSBpcyBkZXRlY3RlZCBvbiB0aGUgaW5kZXggc2lnbmFsLgorICogQHBhcmFtIGVuYWJsZSAgICAgYm9vbGVhbiBpbnB1dCwgcGFzcyB0cnVlIHRvIGVuYWJsZSBmZWF0dXJlIG9yIGZhbHNlIHRvIGRpc2FibGUuCisgKiBAcGFyYW0gcmlzaW5nRWRnZSAgIGJvb2xlYW4gaW5wdXQsIHBhc3MgdHJ1ZSB0byBjbGVhciB0aGUgcG9zaXRpb24gb24gcmlzaW5nIGVkZ2UsCisgKiAgICAgICAgICBwYXNzIGZhbHNlIHRvIGNsZWFyIHRoZSBwb3NpdGlvbiBvbiBmYWxsaW5nIGVkZ2UuCisgKi8KK3ZvaWQgQ0FOVGFsb246OkVuYWJsZVplcm9TZW5zb3JQb3NpdGlvbk9uSW5kZXgoYm9vbCBlbmFibGUsIGJvb2wgcmlzaW5nRWRnZSkKK3sKKyAgaWYgKGVuYWJsZSkgeworICAgIC8qIGVuYWJsZSB0aGUgZmVhdHVyZSwgdXBkYXRlIHRoZSBlZGdlIHBvbGFyaXR5IGZpcnN0IHRvIGVuc3VyZQorICAgICAgaXQgaXMgY29ycmVjdCBiZWZvcmUgdGhlIGZlYXR1cmUgaXMgZW5hYmxlZC4gKi8KKyAgICBDb25maWdTZXRQYXJhbWV0ZXIoQ2FuVGFsb25TUlg6OmVRdWFkSWR4UG9sYXJpdHkscmlzaW5nRWRnZSAgPyAxIDogMCk7CisgICAgQ29uZmlnU2V0UGFyYW1ldGVyKENhblRhbG9uU1JYOjplQ2xlYXJQb3NpdGlvbk9uSWR4LDEpOworICB9IGVsc2UgeworICAgIC8qIGRpc2FibGUgdGhlIGZlYXR1cmUgZmlyc3QsIHRoZW4gdXBkYXRlIHRoZSBlZGdlIHBvbGFyaXR5LiAqLworICAgIENvbmZpZ1NldFBhcmFtZXRlcihDYW5UYWxvblNSWDo6ZUNsZWFyUG9zaXRpb25PbklkeCwwKTsKKyAgICBDb25maWdTZXRQYXJhbWV0ZXIoQ2FuVGFsb25TUlg6OmVRdWFkSWR4UG9sYXJpdHkscmlzaW5nRWRnZSAgPyAxIDogMCk7CisgIH0KK30KKy8qKgorKiBDb21tb24gaW50ZXJmYWNlIGZvciBpbnZlcnRpbmcgZGlyZWN0aW9uIG9mIGEgc3BlZWQgY29udHJvbGxlci4KKyogT25seSB3b3JrcyBpbiBQZXJjZW50VmJ1cywgc3BlZWQsIGFuZCBWb2x0YWdlIG1vZGVzLgorKiBAcGFyYW0gaXNJbnZlcnRlZCBUaGUgc3RhdGUgb2YgaW52ZXJzaW9uLCB0cnVlIGlzIGludmVydGVkLgorKi8KK3ZvaWQgQ0FOVGFsb246OlNldEludmVydGVkKGJvb2wgaXNJbnZlcnRlZCkgeyBtX2lzSW52ZXJ0ZWQgPSBpc0ludmVydGVkOyB9CisKKy8qKgorICogQ29tbW9uIGludGVyZmFjZSBmb3IgdGhlIGludmVydGluZyBkaXJlY3Rpb24gb2YgYSBzcGVlZCBjb250cm9sbGVyLgorICoKKyAqIEByZXR1cm4gaXNJbnZlcnRlZCBUaGUgc3RhdGUgb2YgaW52ZXJzaW9uLCB0cnVlIGlzIGludmVydGVkLgorICoKKyAqLworYm9vbCBDQU5UYWxvbjo6R2V0SW52ZXJ0ZWQoKSBjb25zdCB7IHJldHVybiBtX2lzSW52ZXJ0ZWQ7IH0KKworLyoqCisgKiBDb21tb24gaW50ZXJmYWNlIGZvciBzdG9wcGluZyB0aGUgbW90b3IKKyAqIFBhcnQgb2YgdGhlIE1vdG9yU2FmZXR5IGludGVyZmFjZQorICoKKyAqIEBkZXByZWNhdGVkIENhbGwgRGlzYWJsZSBpbnN0ZWFkLgorKi8KK3ZvaWQgQ0FOVGFsb246OlN0b3BNb3RvcigpIHsgRGlzYWJsZSgpOyB9CisKK3ZvaWQgQ0FOVGFsb246OlZhbHVlQ2hhbmdlZChJVGFibGUqIHNvdXJjZSwgbGx2bTo6U3RyaW5nUmVmIGtleSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdGQ6OnNoYXJlZF9wdHI8bnQ6OlZhbHVlPiB2YWx1ZSwgYm9vbCBpc05ldykgeworICBpZihrZXkgPT0gIk1vZGUiICYmIHZhbHVlLT5Jc0RvdWJsZSgpKSBTZXRDb250cm9sTW9kZShzdGF0aWNfY2FzdDxDQU5TcGVlZENvbnRyb2xsZXI6OkNvbnRyb2xNb2RlPih2YWx1ZS0+R2V0RG91YmxlKCkpKTsKKyAgaWYoa2V5ID09ICJwIiAmJiB2YWx1ZS0+SXNEb3VibGUoKSkgU2V0UCh2YWx1ZS0+R2V0RG91YmxlKCkpOworICBpZihrZXkgPT0gImkiICYmIHZhbHVlLT5Jc0RvdWJsZSgpKSBTZXRJKHZhbHVlLT5HZXREb3VibGUoKSk7CisgIGlmKGtleSA9PSAiZCIgJiYgdmFsdWUtPklzRG91YmxlKCkpIFNldEQodmFsdWUtPkdldERvdWJsZSgpKTsKKyAgaWYoa2V5ID09ICJmIiAmJiB2YWx1ZS0+SXNEb3VibGUoKSkgU2V0Rih2YWx1ZS0+R2V0RG91YmxlKCkpOworICBpZihrZXkgPT0gIkVuYWJsZWQiICYmIHZhbHVlLT5Jc0Jvb2xlYW4oKSkgeworICAgICAgaWYgKHZhbHVlLT5HZXRCb29sZWFuKCkpIHsKKyAgICAgICAgRW5hYmxlKCk7CisgICAgICB9IGVsc2UgeworICAgICAgICBEaXNhYmxlKCk7CisgICAgICB9CisgIH0KKyAgaWYoa2V5ID09ICJWYWx1ZSIgJiYgdmFsdWUtPklzRG91YmxlKCkpIFNldCh2YWx1ZS0+R2V0RG91YmxlKCkpOworfQorCitib29sIENBTlRhbG9uOjpJc01vZGVQSUQoQ0FOU3BlZWRDb250cm9sbGVyOjpDb250cm9sTW9kZSBtb2RlKSBjb25zdCB7CisgIHJldHVybiBtb2RlID09IGtDdXJyZW50IHx8IG1vZGUgPT0ga1NwZWVkIHx8IG1vZGUgPT0ga1Bvc2l0aW9uOworfQorCit2b2lkIENBTlRhbG9uOjpVcGRhdGVUYWJsZSgpIHsKKyAgaWYgKG1fdGFibGUgIT0gbnVsbHB0cikgeworICAgIG1fdGFibGUtPlB1dFN0cmluZygiflRZUEV+IiwgIkNBTlNwZWVkQ29udHJvbGxlciIpOworICAgIG1fdGFibGUtPlB1dFN0cmluZygiVHlwZSIsICJDQU5UYWxvbiIpOworICAgIG1fdGFibGUtPlB1dFN0cmluZygiTW9kZSIsIEdldE1vZGVOYW1lKG1fY29udHJvbE1vZGUpKTsKKyAgICBtX3RhYmxlLT5QdXROdW1iZXIoInAiLCBHZXRQKCkpOworICAgIG1fdGFibGUtPlB1dE51bWJlcigiaSIsIEdldEkoKSk7CisgICAgbV90YWJsZS0+UHV0TnVtYmVyKCJkIiwgR2V0RCgpKTsKKyAgICBtX3RhYmxlLT5QdXROdW1iZXIoImYiLCBHZXRGKCkpOworICAgIG1fdGFibGUtPlB1dEJvb2xlYW4oIkVuYWJsZWQiLCBJc0NvbnRyb2xFbmFibGVkKCkpOworICAgIG1fdGFibGUtPlB1dE51bWJlcigiVmFsdWUiLCBHZXQoKSk7CisgIH0KK30KKwordm9pZCBDQU5UYWxvbjo6U3RhcnRMaXZlV2luZG93TW9kZSgpIHsKKyAgaWYgKG1fdGFibGUgIT0gbnVsbHB0cikgeworICAgIG1fdGFibGUtPkFkZFRhYmxlTGlzdGVuZXIodGhpcywgdHJ1ZSk7CisgIH0KK30KKwordm9pZCBDQU5UYWxvbjo6U3RvcExpdmVXaW5kb3dNb2RlKCkgeworICBpZiAobV90YWJsZSAhPSBudWxscHRyKSB7CisgICAgbV90YWJsZS0+UmVtb3ZlVGFibGVMaXN0ZW5lcih0aGlzKTsKKyAgfQorfQorCitzdGQ6OnN0cmluZyBDQU5UYWxvbjo6R2V0U21hcnREYXNoYm9hcmRUeXBlKCkgY29uc3QgeworICByZXR1cm4gIkNBTlNwZWVkQ29udHJvbGxlciI7Cit9CisKK3ZvaWQgQ0FOVGFsb246OkluaXRUYWJsZShzdGQ6OnNoYXJlZF9wdHI8SVRhYmxlPiBzdWJUYWJsZSkgeworICBtX3RhYmxlID0gc3ViVGFibGU7CisgIFVwZGF0ZVRhYmxlKCk7Cit9CisKK3N0ZDo6c2hhcmVkX3B0cjxJVGFibGU+IENBTlRhbG9uOjpHZXRUYWJsZSgpIGNvbnN0IHsgcmV0dXJuIG1fdGFibGU7IH0KZGlmZiAtLWdpdCBhL3dwaWxpYmMvQXRoZW5hL3NyYy9DYW1lcmFTZXJ2ZXIuY3BwIGIvd3BpbGliYy9BdGhlbmEvc3JjL0NhbWVyYVNlcnZlci5jcHAKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYWYzMTlhNAotLS0gL2Rldi9udWxsCisrKyBiL3dwaWxpYmMvQXRoZW5hL3NyYy9DYW1lcmFTZXJ2ZXIuY3BwCkBAIC0wLDAgKzEsMjYwIEBACisjaW5jbHVkZSAiQ2FtZXJhU2VydmVyLmgiCisjaW5jbHVkZSAiV1BJRXJyb3JzLmgiCisjaW5jbHVkZSAiVXRpbGl0eS5oIgorCisjaW5jbHVkZSA8aW9zdHJlYW0+CisjaW5jbHVkZSA8Y2hyb25vPgorI2luY2x1ZGUgPGNzdHJpbmc+CisjaW5jbHVkZSA8c3lzL3NvY2tldC5oPgorI2luY2x1ZGUgPHVuaXN0ZC5oPgorI2luY2x1ZGUgPG5ldGRiLmg+CisKK2NvbnN0ZXhwciB1aW50OF90IENhbWVyYVNlcnZlcjo6a01hZ2ljTnVtYmVyW107CisKK0NhbWVyYVNlcnZlciogQ2FtZXJhU2VydmVyOjpHZXRJbnN0YW5jZSgpIHsKKyAgc3RhdGljIENhbWVyYVNlcnZlciBpbnN0YW5jZTsKKyAgcmV0dXJuICZpbnN0YW5jZTsKK30KKworQ2FtZXJhU2VydmVyOjpDYW1lcmFTZXJ2ZXIoKQorICAgIDogbV9jYW1lcmEoKSwKKyAgICAgIG1fc2VydmVyVGhyZWFkKCZDYW1lcmFTZXJ2ZXI6OlNlcnZlLCB0aGlzKSwKKyAgICAgIG1fY2FwdHVyZVRocmVhZCgpLAorICAgICAgbV9pbWFnZU11dGV4KCksCisgICAgICBtX25ld0ltYWdlVmFyaWFibGUoKSwKKyAgICAgIG1fZGF0YVBvb2woMyksCisgICAgICBtX3F1YWxpdHkoNTApLAorICAgICAgbV9hdXRvQ2FwdHVyZVN0YXJ0ZWQoZmFsc2UpLAorICAgICAgbV9od0NsaWVudCh0cnVlKSwKKyAgICAgIG1faW1hZ2VEYXRhKG51bGxwdHIsIDAsIDAsIGZhbHNlKSB7CisgIGZvciAoaW50IGkgPSAwOyBpIDwgMzsgaSsrKSBtX2RhdGFQb29sLnB1c2hfYmFjayhuZXcgdWludDhfdFtrTWF4SW1hZ2VTaXplXSk7Cit9CisKK3ZvaWQgQ2FtZXJhU2VydmVyOjpGcmVlSW1hZ2VEYXRhKAorICAgIHN0ZDo6dHVwbGU8dWludDhfdCosIHVuc2lnbmVkIGludCwgdW5zaWduZWQgaW50LCBib29sPiBpbWFnZURhdGEpIHsKKyAgaWYgKHN0ZDo6Z2V0PDM+KGltYWdlRGF0YSkpCisgICAgaW1hcURpc3Bvc2Uoc3RkOjpnZXQ8MD4oaW1hZ2VEYXRhKSk7CisgIGVsc2UgaWYgKHN0ZDo6Z2V0PDA+KGltYWdlRGF0YSkgIT0gbnVsbHB0cikgeworICAgIHN0ZDo6bG9ja19ndWFyZDxwcmlvcml0eV9yZWN1cnNpdmVfbXV0ZXg+IGxvY2sobV9pbWFnZU11dGV4KTsKKyAgICBtX2RhdGFQb29sLnB1c2hfYmFjayhzdGQ6OmdldDwwPihpbWFnZURhdGEpKTsKKyAgfQorfQorCit2b2lkIENhbWVyYVNlcnZlcjo6U2V0SW1hZ2VEYXRhKHVpbnQ4X3QqIGRhdGEsIHVuc2lnbmVkIGludCBzaXplLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB1bnNpZ25lZCBpbnQgc3RhcnQsIGJvb2wgaW1hcURhdGEpIHsKKyAgc3RkOjpsb2NrX2d1YXJkPHByaW9yaXR5X3JlY3Vyc2l2ZV9tdXRleD4gbG9jayhtX2ltYWdlTXV0ZXgpOworICBGcmVlSW1hZ2VEYXRhKG1faW1hZ2VEYXRhKTsKKyAgbV9pbWFnZURhdGEgPSBzdGQ6Om1ha2VfdHVwbGUoZGF0YSwgc2l6ZSwgc3RhcnQsIGltYXFEYXRhKTsKKyAgbV9uZXdJbWFnZVZhcmlhYmxlLm5vdGlmeV9hbGwoKTsKK30KKwordm9pZCBDYW1lcmFTZXJ2ZXI6OlNldEltYWdlKEltYWdlIGNvbnN0KiBpbWFnZSkgeworICB1bnNpZ25lZCBpbnQgZGF0YVNpemUgPSAwOworICB1aW50OF90KiBkYXRhID0KKyAgICAgICh1aW50OF90KilpbWFxRmxhdHRlbihpbWFnZSwgSU1BUV9GTEFUVEVOX0lNQUdFLCBJTUFRX0NPTVBSRVNTSU9OX0pQRUcsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgMTAgKiBtX3F1YWxpdHksICZkYXRhU2l6ZSk7CisKKyAgLy8gSWYgd2UncmUgdXNpbmcgYSBIVyBjYW1lcmEsIHRoZW4gZmluZCB0aGUgc3RhcnQgb2YgdGhlIGRhdGEKKyAgYm9vbCBod0NsaWVudDsKKyAgeworICAgIC8vIE1ha2UgYSBsb2NhbCBjb3B5IG9mIHRoZSBod0NsaWVudCB2YXJpYWJsZSBzbyB0aGF0IHdlIGNhbiBzYWZlbHkgdXNlIGl0LgorICAgIHN0ZDo6bG9ja19ndWFyZDxwcmlvcml0eV9yZWN1cnNpdmVfbXV0ZXg+IGxvY2sobV9pbWFnZU11dGV4KTsKKyAgICBod0NsaWVudCA9IG1faHdDbGllbnQ7CisgIH0KKyAgdW5zaWduZWQgaW50IHN0YXJ0ID0gMDsKKyAgaWYgKGh3Q2xpZW50KSB7CisgICAgd2hpbGUgKHN0YXJ0IDwgZGF0YVNpemUgLSAxKSB7CisgICAgICBpZiAoZGF0YVtzdGFydF0gPT0gMHhGRiAmJiBkYXRhW3N0YXJ0ICsgMV0gPT0gMHhEOCkKKyAgICAgICAgYnJlYWs7CisgICAgICBlbHNlCisgICAgICAgIHN0YXJ0Kys7CisgICAgfQorICB9CisgIGRhdGFTaXplIC09IHN0YXJ0OworCisgIHdwaV9hc3NlcnQoZGF0YVNpemUgPiAyKTsKKyAgU2V0SW1hZ2VEYXRhKGRhdGEsIGRhdGFTaXplLCBzdGFydCwgdHJ1ZSk7Cit9CisKK3ZvaWQgQ2FtZXJhU2VydmVyOjpBdXRvQ2FwdHVyZSgpIHsKKyAgSW1hZ2UqIGZyYW1lID0gaW1hcUNyZWF0ZUltYWdlKElNQVFfSU1BR0VfUkdCLCAwKTsKKworICB3aGlsZSAodHJ1ZSkgeworICAgIGJvb2wgaHdDbGllbnQ7CisgICAgdWludDhfdCogZGF0YSA9IG51bGxwdHI7CisgICAgeworICAgICAgc3RkOjpsb2NrX2d1YXJkPHByaW9yaXR5X3JlY3Vyc2l2ZV9tdXRleD4gbG9jayhtX2ltYWdlTXV0ZXgpOworICAgICAgaHdDbGllbnQgPSBtX2h3Q2xpZW50OworICAgICAgaWYgKGh3Q2xpZW50KSB7CisgICAgICAgIGRhdGEgPSBtX2RhdGFQb29sLmJhY2soKTsKKyAgICAgICAgbV9kYXRhUG9vbC5wb3BfYmFjaygpOworICAgICAgfQorICAgIH0KKworICAgIGlmIChod0NsaWVudCkgeworICAgICAgdW5zaWduZWQgaW50IHNpemUgPSBtX2NhbWVyYS0+R2V0SW1hZ2VEYXRhKGRhdGEsIGtNYXhJbWFnZVNpemUpOworICAgICAgU2V0SW1hZ2VEYXRhKGRhdGEsIHNpemUpOworICAgIH0gZWxzZSB7CisgICAgICBtX2NhbWVyYS0+R2V0SW1hZ2UoZnJhbWUpOworICAgICAgU2V0SW1hZ2UoZnJhbWUpOworICAgIH0KKyAgfQorfQorCit2b2lkIENhbWVyYVNlcnZlcjo6U3RhcnRBdXRvbWF0aWNDYXB0dXJlKGNoYXIgY29uc3QqIGNhbWVyYU5hbWUpIHsKKyAgc3RkOjpzaGFyZWRfcHRyPFVTQkNhbWVyYT4gY2FtZXJhID0KKyAgICAgIHN0ZDo6bWFrZV9zaGFyZWQ8VVNCQ2FtZXJhPihjYW1lcmFOYW1lLCB0cnVlKTsKKyAgY2FtZXJhLT5PcGVuQ2FtZXJhKCk7CisgIFN0YXJ0QXV0b21hdGljQ2FwdHVyZShjYW1lcmEpOworfQorCit2b2lkIENhbWVyYVNlcnZlcjo6U3RhcnRBdXRvbWF0aWNDYXB0dXJlKHN0ZDo6c2hhcmVkX3B0cjxVU0JDYW1lcmE+IGNhbWVyYSkgeworICBzdGQ6OmxvY2tfZ3VhcmQ8cHJpb3JpdHlfcmVjdXJzaXZlX211dGV4PiBsb2NrKG1faW1hZ2VNdXRleCk7CisgIGlmIChtX2F1dG9DYXB0dXJlU3RhcnRlZCkgcmV0dXJuOworCisgIG1fY2FtZXJhID0gY2FtZXJhOworICBtX2NhbWVyYS0+U3RhcnRDYXB0dXJlKCk7CisKKyAgbV9jYXB0dXJlVGhyZWFkID0gc3RkOjp0aHJlYWQoJkNhbWVyYVNlcnZlcjo6QXV0b0NhcHR1cmUsIHRoaXMpOworICBtX2NhcHR1cmVUaHJlYWQuZGV0YWNoKCk7CisgIG1fYXV0b0NhcHR1cmVTdGFydGVkID0gdHJ1ZTsKK30KKworYm9vbCBDYW1lcmFTZXJ2ZXI6OklzQXV0b0NhcHR1cmVTdGFydGVkKCkgeworICBzdGQ6OmxvY2tfZ3VhcmQ8cHJpb3JpdHlfcmVjdXJzaXZlX211dGV4PiBsb2NrKG1faW1hZ2VNdXRleCk7CisgIHJldHVybiBtX2F1dG9DYXB0dXJlU3RhcnRlZDsKK30KKwordm9pZCBDYW1lcmFTZXJ2ZXI6OlNldFNpemUodW5zaWduZWQgaW50IHNpemUpIHsKKyAgc3RkOjpsb2NrX2d1YXJkPHByaW9yaXR5X3JlY3Vyc2l2ZV9tdXRleD4gbG9jayhtX2ltYWdlTXV0ZXgpOworICBpZiAoIW1fY2FtZXJhKSByZXR1cm47CisgIGlmIChzaXplID09IGtTaXplMTYweDEyMCkKKyAgICBtX2NhbWVyYS0+U2V0U2l6ZSgxNjAsIDEyMCk7CisgIGVsc2UgaWYgKHNpemUgPT0ga1NpemUzMjB4MjQwKQorICAgIG1fY2FtZXJhLT5TZXRTaXplKDMyMCwgMjQwKTsKKyAgZWxzZSBpZiAoc2l6ZSA9PSBrU2l6ZTY0MHg0ODApCisgICAgbV9jYW1lcmEtPlNldFNpemUoNjQwLCA0ODApOworfQorCit2b2lkIENhbWVyYVNlcnZlcjo6U2V0UXVhbGl0eSh1bnNpZ25lZCBpbnQgcXVhbGl0eSkgeworICBzdGQ6OmxvY2tfZ3VhcmQ8cHJpb3JpdHlfcmVjdXJzaXZlX211dGV4PiBsb2NrKG1faW1hZ2VNdXRleCk7CisgIG1fcXVhbGl0eSA9IHF1YWxpdHkgPiAxMDAgPyAxMDAgOiBxdWFsaXR5OworfQorCit1bnNpZ25lZCBpbnQgQ2FtZXJhU2VydmVyOjpHZXRRdWFsaXR5KCkgeworICBzdGQ6OmxvY2tfZ3VhcmQ8cHJpb3JpdHlfcmVjdXJzaXZlX211dGV4PiBsb2NrKG1faW1hZ2VNdXRleCk7CisgIHJldHVybiBtX3F1YWxpdHk7Cit9CisKK3ZvaWQgQ2FtZXJhU2VydmVyOjpTZXJ2ZSgpIHsKKyAgaW50IHNvY2sgPSBzb2NrZXQoQUZfSU5FVCwgU09DS19TVFJFQU0sIDApOworCisgIGlmIChzb2NrID09IC0xKSB7CisgICAgd3BpX3NldEVycm5vRXJyb3IoKTsKKyAgICByZXR1cm47CisgIH0KKworICBpbnQgcmV1c2VBZGRyID0gMTsKKyAgaWYgKHNldHNvY2tvcHQoc29jaywgU09MX1NPQ0tFVCwgU09fUkVVU0VBRERSLCAmcmV1c2VBZGRyLAorICAgICAgICAgICAgICAgICBzaXplb2YocmV1c2VBZGRyKSkgPT0gLTEpCisgICAgd3BpX3NldEVycm5vRXJyb3IoKTsKKworICBzb2NrYWRkcl9pbiBhZGRyZXNzLCBjbGllbnRBZGRyZXNzOworCisgIG1lbXNldCgmYWRkcmVzcywgMCwgc2l6ZW9mKGFkZHJlc3MpKTsKKyAgYWRkcmVzcy5zaW5fZmFtaWx5ID0gQUZfSU5FVDsKKyAgYWRkcmVzcy5zaW5fYWRkci5zX2FkZHIgPSBodG9ubChJTkFERFJfQU5ZKTsKKyAgYWRkcmVzcy5zaW5fcG9ydCA9IGh0b25zKGtQb3J0KTsKKworICBpZiAoYmluZChzb2NrLCAoc3RydWN0IHNvY2thZGRyKikmYWRkcmVzcywgc2l6ZW9mKGFkZHJlc3MpKSA9PSAtMSkKKyAgICB3cGlfc2V0RXJybm9FcnJvcigpOworCisgIGlmIChsaXN0ZW4oc29jaywgMTApID09IC0xKSB3cGlfc2V0RXJybm9FcnJvcigpOworCisgIHdoaWxlICh0cnVlKSB7CisgICAgc29ja2xlbl90IGNsaWVudEFkZHJlc3NMZW4gPSBzaXplb2YoY2xpZW50QWRkcmVzcyk7CisKKyAgICBpbnQgY29ubiA9CisgICAgICAgIGFjY2VwdChzb2NrLCAoc3RydWN0IHNvY2thZGRyKikmY2xpZW50QWRkcmVzcywgJmNsaWVudEFkZHJlc3NMZW4pOworICAgIGlmIChjb25uID09IC0xKSB7CisgICAgICB3cGlfc2V0RXJybm9FcnJvcigpOworICAgICAgY29udGludWU7CisgICAgfQorCisgICAgUmVxdWVzdCByZXE7CisgICAgaWYgKHJlYWQoY29ubiwgJnJlcSwgc2l6ZW9mKHJlcSkpID09IC0xKSB7CisgICAgICB3cGlfc2V0RXJybm9FcnJvcigpOworICAgICAgY2xvc2UoY29ubik7CisgICAgICBjb250aW51ZTsKKyAgICB9IGVsc2UgeworICAgICAgcmVxLmZwcyA9IG50b2hsKHJlcS5mcHMpOworICAgICAgcmVxLmNvbXByZXNzaW9uID0gbnRvaGwocmVxLmNvbXByZXNzaW9uKTsKKyAgICAgIHJlcS5zaXplID0gbnRvaGwocmVxLnNpemUpOworICAgIH0KKworICAgIC8vIFRPRE86IFN1cHBvcnQgdGhlIFNXIENvbXByZXNzaW9uLiBUaGUgcmVzdCBvZiB0aGUgY29kZSBiZWxvdyB3aWxsIHdvcmsgYXMKKyAgICAvLyB0aG91Z2ggdGhpcworICAgIC8vIGNoZWNrIGlzbid0IGhlcmUKKyAgICBpZiAocmVxLmNvbXByZXNzaW9uICE9IGtIYXJkd2FyZUNvbXByZXNzaW9uKSB7CisgICAgICB3cGlfc2V0V1BJRXJyb3JXaXRoQ29udGV4dChJbmNvbXBhdGlibGVTdGF0ZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJDaG9vc2UgXCJVU0IgQ2FtZXJhIEhXXCIgb24gdGhlIGRhc2hib2FyZCIpOworICAgICAgY2xvc2UoY29ubik7CisgICAgICBjb250aW51ZTsKKyAgICB9CisKKyAgICB7CisgICAgICAvLyBXYWl0IGZvciB0aGUgY2FtZXJhIHRvIGJlIHNldHcKKyAgICAgIHN0ZDo6dW5pcXVlX2xvY2s8cHJpb3JpdHlfcmVjdXJzaXZlX211dGV4PiBsb2NrKG1faW1hZ2VNdXRleCk7CisgICAgICBpZiAoIW1fY2FtZXJhKSB7CisgICAgICAgIHN0ZDo6Y291dCA8PCAiQ2FtZXJhIG5vdCB5ZXQgcmVhZHksIGF3YWl0aW5nIGZpcnN0IGltYWdlIiA8PCBzdGQ6OmVuZGw7CisgICAgICAgIG1fbmV3SW1hZ2VWYXJpYWJsZS53YWl0KGxvY2spOworICAgICAgfQorICAgICAgbV9od0NsaWVudCA9IHJlcS5jb21wcmVzc2lvbiA9PSBrSGFyZHdhcmVDb21wcmVzc2lvbjsKKyAgICAgIGlmICghbV9od0NsaWVudCkKKyAgICAgICAgU2V0UXVhbGl0eSgxMDAgLSByZXEuY29tcHJlc3Npb24pOworICAgICAgZWxzZSBpZiAobV9jYW1lcmEpCisgICAgICAgIG1fY2FtZXJhLT5TZXRGUFMocmVxLmZwcyk7CisgICAgICBTZXRTaXplKHJlcS5zaXplKTsKKyAgICB9CisKKyAgICBhdXRvIHBlcmlvZCA9IHN0ZDo6Y2hyb25vOjptaWNyb3NlY29uZHMoMTAwMDAwMCkgLyByZXEuZnBzOworICAgIHdoaWxlICh0cnVlKSB7CisgICAgICBhdXRvIHN0YXJ0VGltZSA9IHN0ZDo6Y2hyb25vOjpzdGVhZHlfY2xvY2s6Om5vdygpOworICAgICAgc3RkOjp0dXBsZTx1aW50OF90KiwgdW5zaWduZWQgaW50LCB1bnNpZ25lZCBpbnQsIGJvb2w+IGltYWdlRGF0YTsKKyAgICAgIHsKKyAgICAgICAgc3RkOjp1bmlxdWVfbG9jazxwcmlvcml0eV9yZWN1cnNpdmVfbXV0ZXg+IGxvY2sobV9pbWFnZU11dGV4KTsKKyAgICAgICAgbV9uZXdJbWFnZVZhcmlhYmxlLndhaXQobG9jayk7CisgICAgICAgIGltYWdlRGF0YSA9IG1faW1hZ2VEYXRhOworICAgICAgICBtX2ltYWdlRGF0YSA9IHN0ZDo6bWFrZV90dXBsZTx1aW50OF90Kj4obnVsbHB0ciwgMCwgMCwgZmFsc2UpOworICAgICAgfQorCisgICAgICB1bnNpZ25lZCBpbnQgc2l6ZSA9IHN0ZDo6Z2V0PDE+KGltYWdlRGF0YSk7CisgICAgICB1bnNpZ25lZCBpbnQgbmV0U2l6ZSA9IGh0b25sKHNpemUpOworICAgICAgdW5zaWduZWQgaW50IHN0YXJ0ID0gc3RkOjpnZXQ8Mj4oaW1hZ2VEYXRhKTsKKyAgICAgIHVpbnQ4X3QqIGRhdGEgPSBzdGQ6OmdldDwwPihpbWFnZURhdGEpOworCisgICAgICBpZiAoZGF0YSA9PSBudWxscHRyKSBjb250aW51ZTsKKworICAgICAgaWYgKHdyaXRlKGNvbm4sIGtNYWdpY051bWJlciwgc2l6ZW9mKGtNYWdpY051bWJlcikpID09IC0xKSB7CisgICAgICAgIHdwaV9zZXRFcnJub0Vycm9yV2l0aENvbnRleHQoCisgICAgICAgICAgICAiW0NhbWVyYVNlcnZlcl0gRXJyb3Igc2VuZGluZyBtYWdpYyBudW1iZXIiKTsKKyAgICAgICAgRnJlZUltYWdlRGF0YShpbWFnZURhdGEpOworICAgICAgICBicmVhazsKKyAgICAgIH0KKyAgICAgIGlmICh3cml0ZShjb25uLCAmbmV0U2l6ZSwgc2l6ZW9mKG5ldFNpemUpKSA9PSAtMSkgeworICAgICAgICB3cGlfc2V0RXJybm9FcnJvcldpdGhDb250ZXh0KCJbQ2FtZXJhU2VydmVyXSBFcnJvciBzZW5kaW5nIGltYWdlIHNpemUiKTsKKyAgICAgICAgRnJlZUltYWdlRGF0YShpbWFnZURhdGEpOworICAgICAgICBicmVhazsKKyAgICAgIH0KKyAgICAgIGlmICh3cml0ZShjb25uLCAmZGF0YVtzdGFydF0sIHNpemVvZih1aW50OF90KSAqIHNpemUpID09IC0xKSB7CisgICAgICAgIHdwaV9zZXRFcnJub0Vycm9yV2l0aENvbnRleHQoIltDYW1lcmFTZXJ2ZXJdIEVycm9yIHNlbmRpbmcgaW1hZ2UgZGF0YSIpOworICAgICAgICBGcmVlSW1hZ2VEYXRhKGltYWdlRGF0YSk7CisgICAgICAgIGJyZWFrOworICAgICAgfQorICAgICAgRnJlZUltYWdlRGF0YShpbWFnZURhdGEpOworICAgICAgc3RkOjp0aGlzX3RocmVhZDo6c2xlZXBfdW50aWwoc3RhcnRUaW1lICsgcGVyaW9kKTsKKyAgICB9CisgICAgY2xvc2UoY29ubik7CisgIH0KKyAgY2xvc2Uoc29jayk7Cit9CmRpZmYgLS1naXQgYS93cGlsaWJjL0F0aGVuYS9zcmMvQ29tcHJlc3Nvci5jcHAgYi93cGlsaWJjL0F0aGVuYS9zcmMvQ29tcHJlc3Nvci5jcHAKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uOWFiODllMAotLS0gL2Rldi9udWxsCisrKyBiL3dwaWxpYmMvQXRoZW5hL3NyYy9Db21wcmVzc29yLmNwcApAQCAtMCwwICsxLDI3NyBAQAorLyoKKyAqIENvbXByZXNzb3IuY3BwCisgKi8KKworI2luY2x1ZGUgIkNvbXByZXNzb3IuaCIKKyNpbmNsdWRlICJXUElFcnJvcnMuaCIKKworLyoqCisgKiBDb25zdHJ1Y3RvcgorICoKKyAqIEBwYXJhbSBtb2R1bGUgVGhlIFBDTSBJRCB0byB1c2UgKDAtNjIpCisgKi8KK0NvbXByZXNzb3I6OkNvbXByZXNzb3IodWludDhfdCBwY21JRCkgeworICBtX3BjbV9wb2ludGVyID0gaW5pdGlhbGl6ZUNvbXByZXNzb3IocGNtSUQpOworICBTZXRDbG9zZWRMb29wQ29udHJvbCh0cnVlKTsKK30KKworLyoqCisgKiAgU3RhcnRzIGNsb3NlZC1sb29wIGNvbnRyb2wuIE5vdGUgdGhhdCBjbG9zZWQgbG9vcCBjb250cm9sIGlzIGVuYWJsZWQgYnkKKyAqIGRlZmF1bHQuCisgKi8KK3ZvaWQgQ29tcHJlc3Nvcjo6U3RhcnQoKSB7IFNldENsb3NlZExvb3BDb250cm9sKHRydWUpOyB9CisKKy8qKgorICogIFN0b3BzIGNsb3NlZC1sb29wIGNvbnRyb2wuIE5vdGUgdGhhdCBjbG9zZWQgbG9vcCBjb250cm9sIGlzIGVuYWJsZWQgYnkKKyAqIGRlZmF1bHQuCisgKi8KK3ZvaWQgQ29tcHJlc3Nvcjo6U3RvcCgpIHsgU2V0Q2xvc2VkTG9vcENvbnRyb2woZmFsc2UpOyB9CisKKy8qKgorICogQ2hlY2sgaWYgY29tcHJlc3NvciBvdXRwdXQgaXMgYWN0aXZlCisgKiBAcmV0dXJuIHRydWUgaWYgdGhlIGNvbXByZXNzb3IgaXMgb24KKyAqLworYm9vbCBDb21wcmVzc29yOjpFbmFibGVkKCkgY29uc3QgeworICBpbnQzMl90IHN0YXR1cyA9IDA7CisgIGJvb2wgdmFsdWU7CisKKyAgdmFsdWUgPSBnZXRDb21wcmVzc29yKG1fcGNtX3BvaW50ZXIsICZzdGF0dXMpOworCisgIGlmIChzdGF0dXMpIHsKKyAgICB3cGlfc2V0V1BJRXJyb3IoVGltZW91dCk7CisgIH0KKworICByZXR1cm4gdmFsdWU7Cit9CisKKy8qKgorICogQ2hlY2sgaWYgdGhlIHByZXNzdXJlIHN3aXRjaCBpcyB0cmlnZ2VyZWQKKyAqIEByZXR1cm4gdHJ1ZSBpZiBwcmVzc3VyZSBpcyBsb3cKKyAqLworYm9vbCBDb21wcmVzc29yOjpHZXRQcmVzc3VyZVN3aXRjaFZhbHVlKCkgY29uc3QgeworICBpbnQzMl90IHN0YXR1cyA9IDA7CisgIGJvb2wgdmFsdWU7CisKKyAgdmFsdWUgPSBnZXRQcmVzc3VyZVN3aXRjaChtX3BjbV9wb2ludGVyLCAmc3RhdHVzKTsKKworICBpZiAoc3RhdHVzKSB7CisgICAgd3BpX3NldFdQSUVycm9yKFRpbWVvdXQpOworICB9CisKKyAgcmV0dXJuIHZhbHVlOworfQorCisvKioKKyAqIFF1ZXJ5IGhvdyBtdWNoIGN1cnJlbnQgdGhlIGNvbXByZXNzb3IgaXMgZHJhd2luZworICogQHJldHVybiBUaGUgY3VycmVudCB0aHJvdWdoIHRoZSBjb21wcmVzc29yLCBpbiBhbXBzCisgKi8KK2Zsb2F0IENvbXByZXNzb3I6OkdldENvbXByZXNzb3JDdXJyZW50KCkgY29uc3QgeworICBpbnQzMl90IHN0YXR1cyA9IDA7CisgIGZsb2F0IHZhbHVlOworCisgIHZhbHVlID0gZ2V0Q29tcHJlc3NvckN1cnJlbnQobV9wY21fcG9pbnRlciwgJnN0YXR1cyk7CisKKyAgaWYgKHN0YXR1cykgeworICAgIHdwaV9zZXRXUElFcnJvcihUaW1lb3V0KTsKKyAgfQorCisgIHJldHVybiB2YWx1ZTsKK30KKworLyoqCisgKiBFbmFibGVzIG9yIGRpc2FibGVzIGF1dG9tYXRpY2FsbHkgdHVybmluZyB0aGUgY29tcHJlc3NvciBvbiB3aGVuIHRoZQorICogcHJlc3N1cmUgaXMgbG93LgorICogQHBhcmFtIG9uIFNldCB0byB0cnVlIHRvIGVuYWJsZSBjbG9zZWQgbG9vcCBjb250cm9sIG9mIHRoZSBjb21wcmVzc29yLiBGYWxzZQorICogdG8gZGlzYWJsZS4KKyAqLwordm9pZCBDb21wcmVzc29yOjpTZXRDbG9zZWRMb29wQ29udHJvbChib29sIG9uKSB7CisgIGludDMyX3Qgc3RhdHVzID0gMDsKKworICBzZXRDbG9zZWRMb29wQ29udHJvbChtX3BjbV9wb2ludGVyLCBvbiwgJnN0YXR1cyk7CisKKyAgaWYgKHN0YXR1cykgeworICAgIHdwaV9zZXRXUElFcnJvcihUaW1lb3V0KTsKKyAgfQorfQorCisvKioKKyAqIFJldHVybnMgdHJ1ZSBpZiB0aGUgY29tcHJlc3NvciB3aWxsIGF1dG9tYXRpY2FsbHkgdHVybiBvbiB3aGVuIHRoZQorICogcHJlc3N1cmUgaXMgbG93LgorICogQHJldHVybiBUcnVlIGlmIGNsb3NlZCBsb29wIGNvbnRyb2wgb2YgdGhlIGNvbXByZXNzb3IgaXMgZW5hYmxlZC4gRmFsc2UgaWYKKyAqIGRpc2FibGVkLgorICovCitib29sIENvbXByZXNzb3I6OkdldENsb3NlZExvb3BDb250cm9sKCkgY29uc3QgeworICBpbnQzMl90IHN0YXR1cyA9IDA7CisgIGJvb2wgdmFsdWU7CisKKyAgdmFsdWUgPSBnZXRDbG9zZWRMb29wQ29udHJvbChtX3BjbV9wb2ludGVyLCAmc3RhdHVzKTsKKworICBpZiAoc3RhdHVzKSB7CisgICAgd3BpX3NldFdQSUVycm9yKFRpbWVvdXQpOworICB9CisKKyAgcmV0dXJuIHZhbHVlOworfQorCisvKioKKyAqIFF1ZXJ5IGlmIHRoZSBjb21wcmVzc29yIG91dHB1dCBoYXMgYmVlbiBkaXNhYmxlZCBkdWUgdG8gaGlnaCBjdXJyZW50IGRyYXcuCisgKiBAcmV0dXJuIHRydWUgaWYgUENNIGlzIGluIGZhdWx0IHN0YXRlIDogQ29tcHJlc3NvciBEcml2ZSBpcworICogCQkJZGlzYWJsZWQgZHVlIHRvIGNvbXByZXNzb3IgY3VycmVudCBiZWluZyB0b28gaGlnaC4KKyAqLworYm9vbCBDb21wcmVzc29yOjpHZXRDb21wcmVzc29yQ3VycmVudFRvb0hpZ2hGYXVsdCgpIGNvbnN0IHsKKyAgaW50MzJfdCBzdGF0dXMgPSAwOworICBib29sIHZhbHVlOworCisgIHZhbHVlID0gZ2V0Q29tcHJlc3NvckN1cnJlbnRUb29IaWdoRmF1bHQobV9wY21fcG9pbnRlciwgJnN0YXR1cyk7CisKKyAgaWYgKHN0YXR1cykgeworICAgIHdwaV9zZXRXUElFcnJvcihUaW1lb3V0KTsKKyAgfQorCisgIHJldHVybiB2YWx1ZTsKK30KKy8qKgorICogUXVlcnkgaWYgdGhlIGNvbXByZXNzb3Igb3V0cHV0IGhhcyBiZWVuIGRpc2FibGVkIGR1ZSB0byBoaWdoIGN1cnJlbnQgZHJhdworICogKHN0aWNreSkuCisgKiBBIHN0aWNreSBmYXVsdCB3aWxsIG5vdCBjbGVhciBvbiBkZXZpY2UgcmVib290LCBpdCBtdXN0IGJlIGNsZWFyZWQgdGhyb3VnaAorICogY29kZSBvciB0aGUgd2ViZGFzaC4KKyAqIEByZXR1cm4gdHJ1ZSBpZiBQQ00gc3RpY2t5IGZhdWx0IGlzIHNldCA6IENvbXByZXNzb3IgRHJpdmUgaXMKKyAqIAkJCWRpc2FibGVkIGR1ZSB0byBjb21wcmVzc29yIGN1cnJlbnQgYmVpbmcgdG9vIGhpZ2guCisgKi8KK2Jvb2wgQ29tcHJlc3Nvcjo6R2V0Q29tcHJlc3NvckN1cnJlbnRUb29IaWdoU3RpY2t5RmF1bHQoKSBjb25zdCB7CisgIGludDMyX3Qgc3RhdHVzID0gMDsKKyAgYm9vbCB2YWx1ZTsKKworICB2YWx1ZSA9IGdldENvbXByZXNzb3JDdXJyZW50VG9vSGlnaFN0aWNreUZhdWx0KG1fcGNtX3BvaW50ZXIsICZzdGF0dXMpOworCisgIGlmIChzdGF0dXMpIHsKKyAgICB3cGlfc2V0V1BJRXJyb3IoVGltZW91dCk7CisgIH0KKworICByZXR1cm4gdmFsdWU7Cit9CisvKioKKyAqIFF1ZXJ5IGlmIHRoZSBjb21wcmVzc29yIG91dHB1dCBoYXMgYmVlbiBkaXNhYmxlZCBkdWUgdG8gYSBzaG9ydCBjaXJjdWl0CisgKiAoc3RpY2t5KS4KKyAqIEEgc3RpY2t5IGZhdWx0IHdpbGwgbm90IGNsZWFyIG9uIGRldmljZSByZWJvb3QsIGl0IG11c3QgYmUgY2xlYXJlZCB0aHJvdWdoCisgKiBjb2RlIG9yIHRoZSB3ZWJkYXNoLgorICogQHJldHVybiB0cnVlIGlmIFBDTSBzdGlja3kgZmF1bHQgaXMgc2V0IDogQ29tcHJlc3NvciBvdXRwdXQKKyAqIAkJCWFwcGVhcnMgdG8gYmUgc2hvcnRlZC4KKyAqLworYm9vbCBDb21wcmVzc29yOjpHZXRDb21wcmVzc29yU2hvcnRlZFN0aWNreUZhdWx0KCkgY29uc3QgeworICBpbnQzMl90IHN0YXR1cyA9IDA7CisgIGJvb2wgdmFsdWU7CisKKyAgdmFsdWUgPSBnZXRDb21wcmVzc29yU2hvcnRlZFN0aWNreUZhdWx0KG1fcGNtX3BvaW50ZXIsICZzdGF0dXMpOworCisgIGlmIChzdGF0dXMpIHsKKyAgICB3cGlfc2V0V1BJRXJyb3IoVGltZW91dCk7CisgIH0KKworICByZXR1cm4gdmFsdWU7Cit9CisvKioKKyAqIFF1ZXJ5IGlmIHRoZSBjb21wcmVzc29yIG91dHB1dCBoYXMgYmVlbiBkaXNhYmxlZCBkdWUgdG8gYSBzaG9ydCBjaXJjdWl0LgorICogQHJldHVybiB0cnVlIGlmIFBDTSBpcyBpbiBmYXVsdCBzdGF0ZSA6IENvbXByZXNzb3Igb3V0cHV0CisgKiAJCQlhcHBlYXJzIHRvIGJlIHNob3J0ZWQuCisgKi8KK2Jvb2wgQ29tcHJlc3Nvcjo6R2V0Q29tcHJlc3NvclNob3J0ZWRGYXVsdCgpIGNvbnN0IHsKKyAgaW50MzJfdCBzdGF0dXMgPSAwOworICBib29sIHZhbHVlOworCisgIHZhbHVlID0gZ2V0Q29tcHJlc3NvclNob3J0ZWRGYXVsdChtX3BjbV9wb2ludGVyLCAmc3RhdHVzKTsKKworICBpZiAoc3RhdHVzKSB7CisgICAgd3BpX3NldFdQSUVycm9yKFRpbWVvdXQpOworICB9CisKKyAgcmV0dXJuIHZhbHVlOworfQorLyoqCisgKiBRdWVyeSBpZiB0aGUgY29tcHJlc3NvciBvdXRwdXQgZG9lcyBub3QgYXBwZWFyIHRvIGJlIHdpcmVkIChzdGlja3kpLgorICogQSBzdGlja3kgZmF1bHQgd2lsbCBub3QgY2xlYXIgb24gZGV2aWNlIHJlYm9vdCwgaXQgbXVzdCBiZSBjbGVhcmVkIHRocm91Z2gKKyAqIGNvZGUgb3IgdGhlIHdlYmRhc2guCisgKiBAcmV0dXJuIHRydWUgaWYgUENNIHN0aWNreSBmYXVsdCBpcyBzZXQgOiBDb21wcmVzc29yIGRvZXMgbm90CisgKiAJCQlhcHBlYXIgdG8gYmUgd2lyZWQsIGkuZS4gY29tcHJlc3NvciBpcworICogCQkJbm90IGRyYXdpbmcgZW5vdWdoIGN1cnJlbnQuCisgKi8KK2Jvb2wgQ29tcHJlc3Nvcjo6R2V0Q29tcHJlc3Nvck5vdENvbm5lY3RlZFN0aWNreUZhdWx0KCkgY29uc3QgeworICBpbnQzMl90IHN0YXR1cyA9IDA7CisgIGJvb2wgdmFsdWU7CisKKyAgdmFsdWUgPSBnZXRDb21wcmVzc29yTm90Q29ubmVjdGVkU3RpY2t5RmF1bHQobV9wY21fcG9pbnRlciwgJnN0YXR1cyk7CisKKyAgaWYgKHN0YXR1cykgeworICAgIHdwaV9zZXRXUElFcnJvcihUaW1lb3V0KTsKKyAgfQorCisgIHJldHVybiB2YWx1ZTsKK30KKy8qKgorICogUXVlcnkgaWYgdGhlIGNvbXByZXNzb3Igb3V0cHV0IGRvZXMgbm90IGFwcGVhciB0byBiZSB3aXJlZC4KKyAqIEByZXR1cm4gdHJ1ZSBpZiBQQ00gaXMgaW4gZmF1bHQgc3RhdGUgOiBDb21wcmVzc29yIGRvZXMgbm90CisgKiAJCQlhcHBlYXIgdG8gYmUgd2lyZWQsIGkuZS4gY29tcHJlc3NvciBpcworICogCQkJbm90IGRyYXdpbmcgZW5vdWdoIGN1cnJlbnQuCisgKi8KK2Jvb2wgQ29tcHJlc3Nvcjo6R2V0Q29tcHJlc3Nvck5vdENvbm5lY3RlZEZhdWx0KCkgY29uc3QgeworICBpbnQzMl90IHN0YXR1cyA9IDA7CisgIGJvb2wgdmFsdWU7CisKKyAgdmFsdWUgPSBnZXRDb21wcmVzc29yTm90Q29ubmVjdGVkRmF1bHQobV9wY21fcG9pbnRlciwgJnN0YXR1cyk7CisKKyAgaWYgKHN0YXR1cykgeworICAgIHdwaV9zZXRXUElFcnJvcihUaW1lb3V0KTsKKyAgfQorCisgIHJldHVybiB2YWx1ZTsKK30KKy8qKgorICogQ2xlYXIgQUxMIHN0aWNreSBmYXVsdHMgaW5zaWRlIFBDTSB0aGF0IENvbXByZXNzb3IgaXMgd2lyZWQgdG8uCisgKgorICogSWYgYSBzdGlja3kgZmF1bHQgaXMgc2V0LCB0aGVuIGl0IHdpbGwgYmUgcGVyc2lzdGVudGx5IGNsZWFyZWQuICBDb21wcmVzc29yCisgKiBkcml2ZQorICogCQltYXliZSBtb21lbnRhcmlseSBkaXNhYmxlIHdoaWxlIGZsYWdzIGFyZSBiZWluZyBjbGVhcmVkLiBDYXJlCisgKiBzaG91bGQgYmUKKyAqIAkJdGFrZW4gdG8gbm90IGNhbGwgdGhpcyB0b28gZnJlcXVlbnRseSwgb3RoZXJ3aXNlIG5vcm1hbAorICogY29tcHJlc3NvcgorICogCQlmdW5jdGlvbmFsaXR5IG1heSBiZSBwcmV2ZW50ZWQuCisgKgorICogSWYgbm8gc3RpY2t5IGZhdWx0cyBhcmUgc2V0IHRoZW4gdGhpcyBjYWxsIHdpbGwgaGF2ZSBubyBlZmZlY3QuCisgKi8KK3ZvaWQgQ29tcHJlc3Nvcjo6Q2xlYXJBbGxQQ01TdGlja3lGYXVsdHMoKSB7CisgIGludDMyX3Qgc3RhdHVzID0gMDsKKworICBjbGVhckFsbFBDTVN0aWNreUZhdWx0cyhtX3BjbV9wb2ludGVyLCAmc3RhdHVzKTsKKworICBpZiAoc3RhdHVzKSB7CisgICAgd3BpX3NldFdQSUVycm9yKFRpbWVvdXQpOworICB9Cit9Cit2b2lkIENvbXByZXNzb3I6OlVwZGF0ZVRhYmxlKCkgeworICBpZiAobV90YWJsZSkgeworICAgIG1fdGFibGUtPlB1dEJvb2xlYW4oIkVuYWJsZWQiLCBFbmFibGVkKCkpOworICAgIG1fdGFibGUtPlB1dEJvb2xlYW4oIlByZXNzdXJlIHN3aXRjaCIsIEdldFByZXNzdXJlU3dpdGNoVmFsdWUoKSk7CisgIH0KK30KKwordm9pZCBDb21wcmVzc29yOjpTdGFydExpdmVXaW5kb3dNb2RlKCkge30KKwordm9pZCBDb21wcmVzc29yOjpTdG9wTGl2ZVdpbmRvd01vZGUoKSB7fQorCitzdGQ6OnN0cmluZyBDb21wcmVzc29yOjpHZXRTbWFydERhc2hib2FyZFR5cGUoKSBjb25zdCB7IHJldHVybiAiQ29tcHJlc3NvciI7IH0KKwordm9pZCBDb21wcmVzc29yOjpJbml0VGFibGUoc3RkOjpzaGFyZWRfcHRyPElUYWJsZT4gc3ViVGFibGUpIHsKKyAgbV90YWJsZSA9IHN1YlRhYmxlOworICBVcGRhdGVUYWJsZSgpOworfQorCitzdGQ6OnNoYXJlZF9wdHI8SVRhYmxlPiBDb21wcmVzc29yOjpHZXRUYWJsZSgpIGNvbnN0IHsgcmV0dXJuIG1fdGFibGU7IH0KKwordm9pZCBDb21wcmVzc29yOjpWYWx1ZUNoYW5nZWQoSVRhYmxlKiBzb3VyY2UsIGxsdm06OlN0cmluZ1JlZiBrZXksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdGQ6OnNoYXJlZF9wdHI8bnQ6OlZhbHVlPiB2YWx1ZSwgYm9vbCBpc05ldykgeworICBpZiAoIXZhbHVlLT5Jc0Jvb2xlYW4oKSkgcmV0dXJuOworICBpZiAodmFsdWUtPkdldEJvb2xlYW4oKSkKKyAgICBTdGFydCgpOworICBlbHNlCisgICAgU3RvcCgpOworfQpkaWZmIC0tZ2l0IGEvd3BpbGliYy9BdGhlbmEvc3JjL0NvbnRyb2xsZXJQb3dlci5jcHAgYi93cGlsaWJjL0F0aGVuYS9zcmMvQ29udHJvbGxlclBvd2VyLmNwcApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5lYTUwOGFmCi0tLSAvZGV2L251bGwKKysrIGIvd3BpbGliYy9BdGhlbmEvc3JjL0NvbnRyb2xsZXJQb3dlci5jcHAKQEAgLTAsMCArMSwxNzYgQEAKKy8qLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovCisvKiBDb3B5cmlnaHQgKGMpIEZJUlNUIDIwMTEuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCisgKi8KKy8qIE9wZW4gU291cmNlIFNvZnR3YXJlIC0gbWF5IGJlIG1vZGlmaWVkIGFuZCBzaGFyZWQgYnkgRlJDIHRlYW1zLiBUaGUgY29kZSAgICovCisvKiBtdXN0IGJlIGFjY29tcGFuaWVkIGJ5IHRoZSBGSVJTVCBCU0QgbGljZW5zZSBmaWxlIGluICQoV0lORF9CQVNFKS9XUElMaWIuICAqLworLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi8KKworI2luY2x1ZGUgIkNvbnRyb2xsZXJQb3dlci5oIgorCisjaW5jbHVkZSA8c3RkaW50Lmg+CisjaW5jbHVkZSA8SEFML1Bvd2VyLmhwcD4KKyNpbmNsdWRlIDxIQUwvSEFMLmhwcD4KKyNpbmNsdWRlICJFcnJvckJhc2UuaCIKKworLyoqCisgKiBHZXQgdGhlIGlucHV0IHZvbHRhZ2UgdG8gdGhlIHJvYm90IGNvbnRyb2xsZXIKKyAqIEByZXR1cm4gVGhlIGNvbnRyb2xsZXIgaW5wdXQgdm9sdGFnZSB2YWx1ZSBpbiBWb2x0cworICovCitkb3VibGUgQ29udHJvbGxlclBvd2VyOjpHZXRJbnB1dFZvbHRhZ2UoKSB7CisgIGludDMyX3Qgc3RhdHVzID0gMDsKKyAgZG91YmxlIHJldFZhbCA9IGdldFZpblZvbHRhZ2UoJnN0YXR1cyk7CisgIHdwaV9zZXRHbG9iYWxFcnJvcldpdGhDb250ZXh0KHN0YXR1cywgZ2V0SEFMRXJyb3JNZXNzYWdlKHN0YXR1cykpOworICByZXR1cm4gcmV0VmFsOworfQorCisvKioKKyAqIEdldCB0aGUgaW5wdXQgY3VycmVudCB0byB0aGUgcm9ib3QgY29udHJvbGxlcgorICogQHJldHVybiBUaGUgY29udHJvbGxlciBpbnB1dCBjdXJyZW50IHZhbHVlIGluIEFtcHMKKyAqLworZG91YmxlIENvbnRyb2xsZXJQb3dlcjo6R2V0SW5wdXRDdXJyZW50KCkgeworICBpbnQzMl90IHN0YXR1cyA9IDA7CisgIGRvdWJsZSByZXRWYWwgPSBnZXRWaW5DdXJyZW50KCZzdGF0dXMpOworICB3cGlfc2V0R2xvYmFsRXJyb3JXaXRoQ29udGV4dChzdGF0dXMsIGdldEhBTEVycm9yTWVzc2FnZShzdGF0dXMpKTsKKyAgcmV0dXJuIHJldFZhbDsKK30KKworLyoqCisgKiBHZXQgdGhlIHZvbHRhZ2Ugb2YgdGhlIDZWIHJhaWwKKyAqIEByZXR1cm4gVGhlIGNvbnRyb2xsZXIgNlYgcmFpbCB2b2x0YWdlIHZhbHVlIGluIFZvbHRzCisgKi8KK2RvdWJsZSBDb250cm9sbGVyUG93ZXI6OkdldFZvbHRhZ2U2VigpIHsKKyAgaW50MzJfdCBzdGF0dXMgPSAwOworICBkb3VibGUgcmV0VmFsID0gZ2V0VXNlclZvbHRhZ2U2Vigmc3RhdHVzKTsKKyAgd3BpX3NldEdsb2JhbEVycm9yV2l0aENvbnRleHQoc3RhdHVzLCBnZXRIQUxFcnJvck1lc3NhZ2Uoc3RhdHVzKSk7CisgIHJldHVybiByZXRWYWw7Cit9CisKKy8qKgorICogR2V0IHRoZSBjdXJyZW50IG91dHB1dCBvZiB0aGUgNlYgcmFpbAorICogQHJldHVybiBUaGUgY29udHJvbGxlciA2ViByYWlsIG91dHB1dCBjdXJyZW50IHZhbHVlIGluIEFtcHMKKyAqLworZG91YmxlIENvbnRyb2xsZXJQb3dlcjo6R2V0Q3VycmVudDZWKCkgeworICBpbnQzMl90IHN0YXR1cyA9IDA7CisgIGRvdWJsZSByZXRWYWwgPSBnZXRVc2VyQ3VycmVudDZWKCZzdGF0dXMpOworICB3cGlfc2V0R2xvYmFsRXJyb3JXaXRoQ29udGV4dChzdGF0dXMsIGdldEhBTEVycm9yTWVzc2FnZShzdGF0dXMpKTsKKyAgcmV0dXJuIHJldFZhbDsKK30KKworLyoqCisgKiBHZXQgdGhlIGVuYWJsZWQgc3RhdGUgb2YgdGhlIDZWIHJhaWwuIFRoZSByYWlsIG1heSBiZSBkaXNhYmxlZCBkdWUgdG8gYQorICogY29udHJvbGxlcgorICogYnJvd25vdXQsIGEgc2hvcnQgY2lyY3VpdCBvbiB0aGUgcmFpbCwgb3IgY29udHJvbGxlciBvdmVyLXZvbHRhZ2UKKyAqIEByZXR1cm4gVGhlIGNvbnRyb2xsZXIgNlYgcmFpbCBlbmFibGVkIHZhbHVlLiBUcnVlIGZvciBlbmFibGVkLgorICovCitib29sIENvbnRyb2xsZXJQb3dlcjo6R2V0RW5hYmxlZDZWKCkgeworICBpbnQzMl90IHN0YXR1cyA9IDA7CisgIGJvb2wgcmV0VmFsID0gZ2V0VXNlckFjdGl2ZTZWKCZzdGF0dXMpOworICB3cGlfc2V0R2xvYmFsRXJyb3JXaXRoQ29udGV4dChzdGF0dXMsIGdldEhBTEVycm9yTWVzc2FnZShzdGF0dXMpKTsKKyAgcmV0dXJuIHJldFZhbDsKK30KKworLyoqCisgKiBHZXQgdGhlIGNvdW50IG9mIHRoZSB0b3RhbCBjdXJyZW50IGZhdWx0cyBvbiB0aGUgNlYgcmFpbCBzaW5jZSB0aGUgY29udHJvbGxlcgorICogaGFzIGJvb3RlZAorICogQHJldHVybiBUaGUgbnVtYmVyIG9mIGZhdWx0cy4KKyAqLworaW50IENvbnRyb2xsZXJQb3dlcjo6R2V0RmF1bHRDb3VudDZWKCkgeworICBpbnQzMl90IHN0YXR1cyA9IDA7CisgIGludCByZXRWYWwgPSBnZXRVc2VyQ3VycmVudEZhdWx0czZWKCZzdGF0dXMpOworICB3cGlfc2V0R2xvYmFsRXJyb3JXaXRoQ29udGV4dChzdGF0dXMsIGdldEhBTEVycm9yTWVzc2FnZShzdGF0dXMpKTsKKyAgcmV0dXJuIHJldFZhbDsKK30KKworLyoqCisgKiBHZXQgdGhlIHZvbHRhZ2Ugb2YgdGhlIDVWIHJhaWwKKyAqIEByZXR1cm4gVGhlIGNvbnRyb2xsZXIgNVYgcmFpbCB2b2x0YWdlIHZhbHVlIGluIFZvbHRzCisgKi8KK2RvdWJsZSBDb250cm9sbGVyUG93ZXI6OkdldFZvbHRhZ2U1VigpIHsKKyAgaW50MzJfdCBzdGF0dXMgPSAwOworICBkb3VibGUgcmV0VmFsID0gZ2V0VXNlclZvbHRhZ2U1Vigmc3RhdHVzKTsKKyAgd3BpX3NldEdsb2JhbEVycm9yV2l0aENvbnRleHQoc3RhdHVzLCBnZXRIQUxFcnJvck1lc3NhZ2Uoc3RhdHVzKSk7CisgIHJldHVybiByZXRWYWw7Cit9CisKKy8qKgorICogR2V0IHRoZSBjdXJyZW50IG91dHB1dCBvZiB0aGUgNVYgcmFpbAorICogQHJldHVybiBUaGUgY29udHJvbGxlciA1ViByYWlsIG91dHB1dCBjdXJyZW50IHZhbHVlIGluIEFtcHMKKyAqLworZG91YmxlIENvbnRyb2xsZXJQb3dlcjo6R2V0Q3VycmVudDVWKCkgeworICBpbnQzMl90IHN0YXR1cyA9IDA7CisgIGRvdWJsZSByZXRWYWwgPSBnZXRVc2VyQ3VycmVudDVWKCZzdGF0dXMpOworICB3cGlfc2V0R2xvYmFsRXJyb3JXaXRoQ29udGV4dChzdGF0dXMsIGdldEhBTEVycm9yTWVzc2FnZShzdGF0dXMpKTsKKyAgcmV0dXJuIHJldFZhbDsKK30KKworLyoqCisgKiBHZXQgdGhlIGVuYWJsZWQgc3RhdGUgb2YgdGhlIDVWIHJhaWwuIFRoZSByYWlsIG1heSBiZSBkaXNhYmxlZCBkdWUgdG8gYQorICogY29udHJvbGxlcgorICogYnJvd25vdXQsIGEgc2hvcnQgY2lyY3VpdCBvbiB0aGUgcmFpbCwgb3IgY29udHJvbGxlciBvdmVyLXZvbHRhZ2UKKyAqIEByZXR1cm4gVGhlIGNvbnRyb2xsZXIgNVYgcmFpbCBlbmFibGVkIHZhbHVlLiBUcnVlIGZvciBlbmFibGVkLgorICovCitib29sIENvbnRyb2xsZXJQb3dlcjo6R2V0RW5hYmxlZDVWKCkgeworICBpbnQzMl90IHN0YXR1cyA9IDA7CisgIGJvb2wgcmV0VmFsID0gZ2V0VXNlckFjdGl2ZTVWKCZzdGF0dXMpOworICB3cGlfc2V0R2xvYmFsRXJyb3JXaXRoQ29udGV4dChzdGF0dXMsIGdldEhBTEVycm9yTWVzc2FnZShzdGF0dXMpKTsKKyAgcmV0dXJuIHJldFZhbDsKK30KKworLyoqCisgKiBHZXQgdGhlIGNvdW50IG9mIHRoZSB0b3RhbCBjdXJyZW50IGZhdWx0cyBvbiB0aGUgNVYgcmFpbCBzaW5jZSB0aGUgY29udHJvbGxlcgorICogaGFzIGJvb3RlZAorICogQHJldHVybiBUaGUgbnVtYmVyIG9mIGZhdWx0cworICovCitpbnQgQ29udHJvbGxlclBvd2VyOjpHZXRGYXVsdENvdW50NVYoKSB7CisgIGludDMyX3Qgc3RhdHVzID0gMDsKKyAgaW50IHJldFZhbCA9IGdldFVzZXJDdXJyZW50RmF1bHRzNVYoJnN0YXR1cyk7CisgIHdwaV9zZXRHbG9iYWxFcnJvcldpdGhDb250ZXh0KHN0YXR1cywgZ2V0SEFMRXJyb3JNZXNzYWdlKHN0YXR1cykpOworICByZXR1cm4gcmV0VmFsOworfQorCisvKioKKyAqIEdldCB0aGUgdm9sdGFnZSBvZiB0aGUgMy4zViByYWlsCisgKiBAcmV0dXJuIFRoZSBjb250cm9sbGVyIDMuM1YgcmFpbCB2b2x0YWdlIHZhbHVlIGluIFZvbHRzCisgKi8KK2RvdWJsZSBDb250cm9sbGVyUG93ZXI6OkdldFZvbHRhZ2UzVjMoKSB7CisgIGludDMyX3Qgc3RhdHVzID0gMDsKKyAgZG91YmxlIHJldFZhbCA9IGdldFVzZXJWb2x0YWdlM1YzKCZzdGF0dXMpOworICB3cGlfc2V0R2xvYmFsRXJyb3JXaXRoQ29udGV4dChzdGF0dXMsIGdldEhBTEVycm9yTWVzc2FnZShzdGF0dXMpKTsKKyAgcmV0dXJuIHJldFZhbDsKK30KKworLyoqCisgKiBHZXQgdGhlIGN1cnJlbnQgb3V0cHV0IG9mIHRoZSAzLjNWIHJhaWwKKyAqIEByZXR1cm4gVGhlIGNvbnRyb2xsZXIgMy4zViByYWlsIG91dHB1dCBjdXJyZW50IHZhbHVlIGluIEFtcHMKKyAqLworZG91YmxlIENvbnRyb2xsZXJQb3dlcjo6R2V0Q3VycmVudDNWMygpIHsKKyAgaW50MzJfdCBzdGF0dXMgPSAwOworICBkb3VibGUgcmV0VmFsID0gZ2V0VXNlckN1cnJlbnQzVjMoJnN0YXR1cyk7CisgIHdwaV9zZXRHbG9iYWxFcnJvcldpdGhDb250ZXh0KHN0YXR1cywgZ2V0SEFMRXJyb3JNZXNzYWdlKHN0YXR1cykpOworICByZXR1cm4gcmV0VmFsOworfQorCisvKioKKyAqIEdldCB0aGUgZW5hYmxlZCBzdGF0ZSBvZiB0aGUgMy4zViByYWlsLiBUaGUgcmFpbCBtYXkgYmUgZGlzYWJsZWQgZHVlIHRvIGEKKyAqIGNvbnRyb2xsZXIKKyAqIGJyb3dub3V0LCBhIHNob3J0IGNpcmN1aXQgb24gdGhlIHJhaWwsIG9yIGNvbnRyb2xsZXIgb3Zlci12b2x0YWdlCisgKiBAcmV0dXJuIFRoZSBjb250cm9sbGVyIDMuM1YgcmFpbCBlbmFibGVkIHZhbHVlLiBUcnVlIGZvciBlbmFibGVkLgorICovCitib29sIENvbnRyb2xsZXJQb3dlcjo6R2V0RW5hYmxlZDNWMygpIHsKKyAgaW50MzJfdCBzdGF0dXMgPSAwOworICBib29sIHJldFZhbCA9IGdldFVzZXJBY3RpdmUzVjMoJnN0YXR1cyk7CisgIHdwaV9zZXRHbG9iYWxFcnJvcldpdGhDb250ZXh0KHN0YXR1cywgZ2V0SEFMRXJyb3JNZXNzYWdlKHN0YXR1cykpOworICByZXR1cm4gcmV0VmFsOworfQorCisvKioKKyAqIEdldCB0aGUgY291bnQgb2YgdGhlIHRvdGFsIGN1cnJlbnQgZmF1bHRzIG9uIHRoZSAzLjNWIHJhaWwgc2luY2UgdGhlCisgKiBjb250cm9sbGVyIGhhcyBib290ZWQKKyAqIEByZXR1cm4gVGhlIG51bWJlciBvZiBmYXVsdHMKKyAqLworaW50IENvbnRyb2xsZXJQb3dlcjo6R2V0RmF1bHRDb3VudDNWMygpIHsKKyAgaW50MzJfdCBzdGF0dXMgPSAwOworICBpbnQgcmV0VmFsID0gZ2V0VXNlckN1cnJlbnRGYXVsdHMzVjMoJnN0YXR1cyk7CisgIHdwaV9zZXRHbG9iYWxFcnJvcldpdGhDb250ZXh0KHN0YXR1cywgZ2V0SEFMRXJyb3JNZXNzYWdlKHN0YXR1cykpOworICByZXR1cm4gcmV0VmFsOworfQpcIE5vIG5ld2xpbmUgYXQgZW5kIG9mIGZpbGUKZGlmZiAtLWdpdCBhL3dwaWxpYmMvQXRoZW5hL3NyYy9Db3VudGVyLmNwcCBiL3dwaWxpYmMvQXRoZW5hL3NyYy9Db3VudGVyLmNwcApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5jZDcwZGU1Ci0tLSAvZGV2L251bGwKKysrIGIvd3BpbGliYy9BdGhlbmEvc3JjL0NvdW50ZXIuY3BwCkBAIC0wLDAgKzEsNTkwIEBACisvKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qLworLyogQ29weXJpZ2h0IChjKSBGSVJTVCAyMDA4LiBBbGwgUmlnaHRzIFJlc2VydmVkLgorICovCisvKiBPcGVuIFNvdXJjZSBTb2Z0d2FyZSAtIG1heSBiZSBtb2RpZmllZCBhbmQgc2hhcmVkIGJ5IEZSQyB0ZWFtcy4gVGhlIGNvZGUgICAqLworLyogbXVzdCBiZSBhY2NvbXBhbmllZCBieSB0aGUgRklSU1QgQlNEIGxpY2Vuc2UgZmlsZSBpbiAkKFdJTkRfQkFTRSkvV1BJTGliLiAgKi8KKy8qLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovCisKKyNpbmNsdWRlICJDb3VudGVyLmgiCisjaW5jbHVkZSAiQW5hbG9nVHJpZ2dlci5oIgorI2luY2x1ZGUgIkRpZ2l0YWxJbnB1dC5oIgorI2luY2x1ZGUgIlJlc291cmNlLmgiCisjaW5jbHVkZSAiV1BJRXJyb3JzLmgiCisKKy8qKgorICogQ3JlYXRlIGFuIGluc3RhbmNlIG9mIGEgY291bnRlciB3aGVyZSBubyBzb3VyY2VzIGFyZSBzZWxlY3RlZC4KKyAqIFRoZXkgYWxsIG11c3QgYmUgc2VsZWN0ZWQgYnkgY2FsbGluZyBmdW5jdGlvbnMgdG8gc3BlY2lmeSB0aGUgdXBzb3VyY2UgYW5kCisgKiB0aGUgZG93bnNvdXJjZQorICogaW5kZXBlbmRlbnRseS4KKyAqCisgKiBUaGlzIGNyZWF0ZXMgYSBDaGlwT2JqZWN0IGNvdW50ZXIgYW5kIGluaXRpYWxpemVzIHN0YXR1cyB2YXJpYWJsZXMKKyAqIGFwcHJvcHJpYXRlbHkuCisgKgorICogVGhlIGNvdW50ZXIgd2lsbCBzdGFydCBjb3VudGluZyBpbW1lZGlhdGVseS4KKyAqIEBwYXJhbSBtb2RlIFRoZSBjb3VudGVyIG1vZGUKKyAqLworQ291bnRlcjo6Q291bnRlcihNb2RlIG1vZGUpIHsKKyAgaW50MzJfdCBzdGF0dXMgPSAwOworICBtX2NvdW50ZXIgPSBpbml0aWFsaXplQ291bnRlcihtb2RlLCAmbV9pbmRleCwgJnN0YXR1cyk7CisgIHdwaV9zZXRFcnJvcldpdGhDb250ZXh0KHN0YXR1cywgZ2V0SEFMRXJyb3JNZXNzYWdlKHN0YXR1cykpOworCisgIFNldE1heFBlcmlvZCguNSk7CisKKyAgSEFMUmVwb3J0KEhBTFVzYWdlUmVwb3J0aW5nOjprUmVzb3VyY2VUeXBlX0NvdW50ZXIsIG1faW5kZXgsIG1vZGUpOworfQorCisvKioKKyAqIENyZWF0ZSBhbiBpbnN0YW5jZSBvZiBhIGNvdW50ZXIgZnJvbSBhIERpZ2l0YWwgU291cmNlIChzdWNoIGFzIGEgRGlnaXRhbAorICogSW5wdXQpLgorICogVGhpcyBpcyB1c2VkIGlmIGFuIGV4aXN0aW5nIGRpZ2l0YWwgaW5wdXQgaXMgdG8gYmUgc2hhcmVkIGJ5IG11bHRpcGxlIG90aGVyCisgKiBvYmplY3RzIHN1Y2gKKyAqIGFzIGVuY29kZXJzIG9yIGlmIHRoZSBEaWdpdGFsIFNvdXJjZSBpcyBub3QgYSBEaWdpdGFsIElucHV0IGNoYW5uZWwgKHN1Y2ggYXMKKyAqIGFuIEFuYWxvZyBUcmlnZ2VyKS4KKyAqCisgKiBUaGUgY291bnRlciB3aWxsIHN0YXJ0IGNvdW50aW5nIGltbWVkaWF0ZWx5LgorICogQHBhcmFtIHNvdXJjZSBBIHBvaW50ZXIgdG8gdGhlIGV4aXN0aW5nIERpZ2l0YWxTb3VyY2Ugb2JqZWN0LiBJdCB3aWxsIGJlIHNldAorICogYXMgdGhlIFVwIFNvdXJjZS4KKyAqLworQ291bnRlcjo6Q291bnRlcihEaWdpdGFsU291cmNlICpzb3VyY2UpIDogQ291bnRlcihrVHdvUHVsc2UpIHsKKyAgU2V0VXBTb3VyY2Uoc291cmNlKTsKKyAgQ2xlYXJEb3duU291cmNlKCk7Cit9CisKKy8qKgorICogQ3JlYXRlIGFuIGluc3RhbmNlIG9mIGEgY291bnRlciBmcm9tIGEgRGlnaXRhbCBTb3VyY2UgKHN1Y2ggYXMgYSBEaWdpdGFsCisgKiBJbnB1dCkuCisgKiBUaGlzIGlzIHVzZWQgaWYgYW4gZXhpc3RpbmcgZGlnaXRhbCBpbnB1dCBpcyB0byBiZSBzaGFyZWQgYnkgbXVsdGlwbGUgb3RoZXIKKyAqIG9iamVjdHMgc3VjaAorICogYXMgZW5jb2RlcnMgb3IgaWYgdGhlIERpZ2l0YWwgU291cmNlIGlzIG5vdCBhIERpZ2l0YWwgSW5wdXQgY2hhbm5lbCAoc3VjaCBhcworICogYW4gQW5hbG9nIFRyaWdnZXIpLgorICoKKyAqIFRoZSBjb3VudGVyIHdpbGwgc3RhcnQgY291bnRpbmcgaW1tZWRpYXRlbHkuCisgKiBAcGFyYW0gc291cmNlIEEgcG9pbnRlciB0byB0aGUgZXhpc3RpbmcgRGlnaXRhbFNvdXJjZSBvYmplY3QuIEl0IHdpbGwgYmUKKyAqIHNldCBhcyB0aGUgVXAgU291cmNlLgorICovCitDb3VudGVyOjpDb3VudGVyKHN0ZDo6c2hhcmVkX3B0cjxEaWdpdGFsU291cmNlPiBzb3VyY2UpIDogQ291bnRlcihrVHdvUHVsc2UpIHsKKyAgU2V0VXBTb3VyY2Uoc291cmNlKTsKKyAgQ2xlYXJEb3duU291cmNlKCk7Cit9CisKKy8qKgorICogQ3JlYXRlIGFuIGluc3RhbmNlIG9mIGEgQ291bnRlciBvYmplY3QuCisgKiBDcmVhdGUgYW4gdXAtQ291bnRlciBpbnN0YW5jZSBnaXZlbiBhIGNoYW5uZWwuCisgKgorICogVGhlIGNvdW50ZXIgd2lsbCBzdGFydCBjb3VudGluZyBpbW1lZGlhdGVseS4KKyAqIEBwYXJhbSBjaGFubmVsIFRoZSBESU8gY2hhbm5lbCB0byB1c2UgYXMgdGhlIHVwIHNvdXJjZS4gMC05IGFyZSBvbi1ib2FyZCwKKyAqIDEwLTI1IGFyZSBvbiB0aGUgTVhQCisgKi8KK0NvdW50ZXI6OkNvdW50ZXIoaW50MzJfdCBjaGFubmVsKSA6IENvdW50ZXIoa1R3b1B1bHNlKSB7CisgIFNldFVwU291cmNlKGNoYW5uZWwpOworICBDbGVhckRvd25Tb3VyY2UoKTsKK30KKworLyoqCisgKiBDcmVhdGUgYW4gaW5zdGFuY2Ugb2YgYSBDb3VudGVyIG9iamVjdC4KKyAqIENyZWF0ZSBhbiBpbnN0YW5jZSBvZiBhIHNpbXBsZSB1cC1Db3VudGVyIGdpdmVuIGFuIGFuYWxvZyB0cmlnZ2VyLgorICogVXNlIHRoZSB0cmlnZ2VyIHN0YXRlIG91dHB1dCBmcm9tIHRoZSBhbmFsb2cgdHJpZ2dlci4KKyAqCisgKiBUaGUgY291bnRlciB3aWxsIHN0YXJ0IGNvdW50aW5nIGltbWVkaWF0ZWx5LgorICogQHBhcmFtIHRyaWdnZXIgVGhlIHBvaW50ZXIgdG8gdGhlIGV4aXN0aW5nIEFuYWxvZ1RyaWdnZXIgb2JqZWN0LgorICovCitERVBSRUNBVEVEKCJVc2UgcGFzcy1ieS1yZWZlcmVuY2UgaW5zdGVhZC4iKQorQ291bnRlcjo6Q291bnRlcihBbmFsb2dUcmlnZ2VyICp0cmlnZ2VyKSA6IENvdW50ZXIoa1R3b1B1bHNlKSB7CisgIFNldFVwU291cmNlKHRyaWdnZXItPkNyZWF0ZU91dHB1dChrU3RhdGUpKTsKKyAgQ2xlYXJEb3duU291cmNlKCk7Cit9CisKKy8qKgorICogQ3JlYXRlIGFuIGluc3RhbmNlIG9mIGEgQ291bnRlciBvYmplY3QuCisgKiBDcmVhdGUgYW4gaW5zdGFuY2Ugb2YgYSBzaW1wbGUgdXAtQ291bnRlciBnaXZlbiBhbiBhbmFsb2cgdHJpZ2dlci4KKyAqIFVzZSB0aGUgdHJpZ2dlciBzdGF0ZSBvdXRwdXQgZnJvbSB0aGUgYW5hbG9nIHRyaWdnZXIuCisgKgorICogVGhlIGNvdW50ZXIgd2lsbCBzdGFydCBjb3VudGluZyBpbW1lZGlhdGVseS4KKyAqIEBwYXJhbSB0cmlnZ2VyIFRoZSByZWZlcmVuY2UgdG8gdGhlIGV4aXN0aW5nIEFuYWxvZ1RyaWdnZXIgb2JqZWN0LgorICovCitDb3VudGVyOjpDb3VudGVyKGNvbnN0IEFuYWxvZ1RyaWdnZXIgJnRyaWdnZXIpIDogQ291bnRlcihrVHdvUHVsc2UpIHsKKyAgU2V0VXBTb3VyY2UodHJpZ2dlci5DcmVhdGVPdXRwdXQoa1N0YXRlKSk7CisgIENsZWFyRG93blNvdXJjZSgpOworfQorCisvKioKKyAqIENyZWF0ZSBhbiBpbnN0YW5jZSBvZiBhIENvdW50ZXIgb2JqZWN0LgorICogQ3JlYXRlcyBhIGZ1bGwgdXAtZG93biBjb3VudGVyIGdpdmVuIHR3byBEaWdpdGFsIFNvdXJjZXMKKyAqIEBwYXJhbSBlbmNvZGluZ1R5cGUgVGhlIHF1YWRyYXR1cmUgZGVjb2RpbmcgbW9kZSAoMXggb3IgMngpCisgKiBAcGFyYW0gdXBTb3VyY2UgVGhlIHBvaW50ZXIgdG8gdGhlIERpZ2l0YWxTb3VyY2UgdG8gc2V0IGFzIHRoZSB1cCBzb3VyY2UKKyAqIEBwYXJhbSBkb3duU291cmNlIFRoZSBwb2ludGVyIHRvIHRoZSBEaWdpdGFsU291cmNlIHRvIHNldCBhcyB0aGUgZG93biBzb3VyY2UKKyAqIEBwYXJhbSBpbnZlcnRlZCBUcnVlIHRvIGludmVydCB0aGUgb3V0cHV0IChyZXZlcnNlIHRoZSBkaXJlY3Rpb24pCisgKi8KK0NvdW50ZXI6OkNvdW50ZXIoRW5jb2RpbmdUeXBlIGVuY29kaW5nVHlwZSwgRGlnaXRhbFNvdXJjZSAqdXBTb3VyY2UsCisgICAgICAgICAgICAgICAgIERpZ2l0YWxTb3VyY2UgKmRvd25Tb3VyY2UsIGJvb2wgaW52ZXJ0ZWQpCisgICAgOiBDb3VudGVyKGVuY29kaW5nVHlwZSwKKyAgICAgICAgICAgICAgc3RkOjpzaGFyZWRfcHRyPERpZ2l0YWxTb3VyY2U+KHVwU291cmNlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBOdWxsRGVsZXRlcjxEaWdpdGFsU291cmNlPigpKSwKKyAgICAgICAgICAgICAgc3RkOjpzaGFyZWRfcHRyPERpZ2l0YWxTb3VyY2U+KGRvd25Tb3VyY2UsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE51bGxEZWxldGVyPERpZ2l0YWxTb3VyY2U+KCkpLAorICAgICAgICAgICAgICBpbnZlcnRlZCkge30KKworLyoqCisgKiBDcmVhdGUgYW4gaW5zdGFuY2Ugb2YgYSBDb3VudGVyIG9iamVjdC4KKyAqIENyZWF0ZXMgYSBmdWxsIHVwLWRvd24gY291bnRlciBnaXZlbiB0d28gRGlnaXRhbCBTb3VyY2VzCisgKiBAcGFyYW0gZW5jb2RpbmdUeXBlIFRoZSBxdWFkcmF0dXJlIGRlY29kaW5nIG1vZGUgKDF4IG9yIDJ4KQorICogQHBhcmFtIHVwU291cmNlIFRoZSBwb2ludGVyIHRvIHRoZSBEaWdpdGFsU291cmNlIHRvIHNldCBhcyB0aGUgdXAgc291cmNlCisgKiBAcGFyYW0gZG93blNvdXJjZSBUaGUgcG9pbnRlciB0byB0aGUgRGlnaXRhbFNvdXJjZSB0byBzZXQgYXMgdGhlIGRvd24gc291cmNlCisgKiBAcGFyYW0gaW52ZXJ0ZWQgVHJ1ZSB0byBpbnZlcnQgdGhlIG91dHB1dCAocmV2ZXJzZSB0aGUgZGlyZWN0aW9uKQorICovCitDb3VudGVyOjpDb3VudGVyKEVuY29kaW5nVHlwZSBlbmNvZGluZ1R5cGUsCisgICAgICAgICAgICAgICAgIHN0ZDo6c2hhcmVkX3B0cjxEaWdpdGFsU291cmNlPiB1cFNvdXJjZSwKKyAgICAgICAgICAgICAgICAgc3RkOjpzaGFyZWRfcHRyPERpZ2l0YWxTb3VyY2U+IGRvd25Tb3VyY2UsIGJvb2wgaW52ZXJ0ZWQpCisgICAgOiBDb3VudGVyKGtFeHRlcm5hbERpcmVjdGlvbikgeworICBpZiAoZW5jb2RpbmdUeXBlICE9IGsxWCAmJiBlbmNvZGluZ1R5cGUgIT0gazJYKSB7CisgICAgd3BpX3NldFdQSUVycm9yV2l0aENvbnRleHQoCisgICAgICAgIFBhcmFtZXRlck91dE9mUmFuZ2UsCisgICAgICAgICJDb3VudGVyIG9ubHkgc3VwcG9ydHMgMVggYW5kIDJYIHF1YWRyYXR1cmUgZGVjb2RpbmcuIik7CisgICAgcmV0dXJuOworICB9CisgIFNldFVwU291cmNlKHVwU291cmNlKTsKKyAgU2V0RG93blNvdXJjZShkb3duU291cmNlKTsKKyAgaW50MzJfdCBzdGF0dXMgPSAwOworCisgIGlmIChlbmNvZGluZ1R5cGUgPT0gazFYKSB7CisgICAgU2V0VXBTb3VyY2VFZGdlKHRydWUsIGZhbHNlKTsKKyAgICBzZXRDb3VudGVyQXZlcmFnZVNpemUobV9jb3VudGVyLCAxLCAmc3RhdHVzKTsKKyAgfSBlbHNlIHsKKyAgICBTZXRVcFNvdXJjZUVkZ2UodHJ1ZSwgdHJ1ZSk7CisgICAgc2V0Q291bnRlckF2ZXJhZ2VTaXplKG1fY291bnRlciwgMiwgJnN0YXR1cyk7CisgIH0KKworICB3cGlfc2V0RXJyb3JXaXRoQ29udGV4dChzdGF0dXMsIGdldEhBTEVycm9yTWVzc2FnZShzdGF0dXMpKTsKKyAgU2V0RG93blNvdXJjZUVkZ2UoaW52ZXJ0ZWQsIHRydWUpOworfQorCisvKioKKyAqIERlbGV0ZSB0aGUgQ291bnRlciBvYmplY3QuCisgKi8KK0NvdW50ZXI6On5Db3VudGVyKCkgeworICBTZXRVcGRhdGVXaGVuRW1wdHkodHJ1ZSk7CisKKyAgaW50MzJfdCBzdGF0dXMgPSAwOworICBmcmVlQ291bnRlcihtX2NvdW50ZXIsICZzdGF0dXMpOworICB3cGlfc2V0RXJyb3JXaXRoQ29udGV4dChzdGF0dXMsIGdldEhBTEVycm9yTWVzc2FnZShzdGF0dXMpKTsKKyAgbV9jb3VudGVyID0gbnVsbHB0cjsKK30KKworLyoqCisgKiBTZXQgdGhlIHVwc291cmNlIGZvciB0aGUgY291bnRlciBhcyBhIGRpZ2l0YWwgaW5wdXQgY2hhbm5lbC4KKyAqIEBwYXJhbSBjaGFubmVsIFRoZSBESU8gY2hhbm5lbCB0byB1c2UgYXMgdGhlIHVwIHNvdXJjZS4gMC05IGFyZSBvbi1ib2FyZCwKKyAqIDEwLTI1IGFyZSBvbiB0aGUgTVhQCisgKi8KK3ZvaWQgQ291bnRlcjo6U2V0VXBTb3VyY2UoaW50MzJfdCBjaGFubmVsKSB7CisgIGlmIChTdGF0dXNJc0ZhdGFsKCkpIHJldHVybjsKKyAgU2V0VXBTb3VyY2Uoc3RkOjptYWtlX3NoYXJlZDxEaWdpdGFsSW5wdXQ+KGNoYW5uZWwpKTsKK30KKworLyoqCisgKiBTZXQgdGhlIHVwIGNvdW50aW5nIHNvdXJjZSB0byBiZSBhbiBhbmFsb2cgdHJpZ2dlci4KKyAqIEBwYXJhbSBhbmFsb2dUcmlnZ2VyIFRoZSBhbmFsb2cgdHJpZ2dlciBvYmplY3QgdGhhdCBpcyB1c2VkIGZvciB0aGUgVXAgU291cmNlCisgKiBAcGFyYW0gdHJpZ2dlclR5cGUgVGhlIGFuYWxvZyB0cmlnZ2VyIG91dHB1dCB0aGF0IHdpbGwgdHJpZ2dlciB0aGUgY291bnRlci4KKyAqLwordm9pZCBDb3VudGVyOjpTZXRVcFNvdXJjZShBbmFsb2dUcmlnZ2VyICphbmFsb2dUcmlnZ2VyLAorICAgICAgICAgICAgICAgICAgICAgICAgICBBbmFsb2dUcmlnZ2VyVHlwZSB0cmlnZ2VyVHlwZSkgeworICBTZXRVcFNvdXJjZShzdGQ6OnNoYXJlZF9wdHI8QW5hbG9nVHJpZ2dlcj4oYW5hbG9nVHJpZ2dlciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTnVsbERlbGV0ZXI8QW5hbG9nVHJpZ2dlcj4oKSksCisgICAgICAgICAgICAgIHRyaWdnZXJUeXBlKTsKK30KKworLyoqCisgKiBTZXQgdGhlIHVwIGNvdW50aW5nIHNvdXJjZSB0byBiZSBhbiBhbmFsb2cgdHJpZ2dlci4KKyAqIEBwYXJhbSBhbmFsb2dUcmlnZ2VyIFRoZSBhbmFsb2cgdHJpZ2dlciBvYmplY3QgdGhhdCBpcyB1c2VkIGZvciB0aGUgVXAgU291cmNlCisgKiBAcGFyYW0gdHJpZ2dlclR5cGUgVGhlIGFuYWxvZyB0cmlnZ2VyIG91dHB1dCB0aGF0IHdpbGwgdHJpZ2dlciB0aGUgY291bnRlci4KKyAqLwordm9pZCBDb3VudGVyOjpTZXRVcFNvdXJjZShzdGQ6OnNoYXJlZF9wdHI8QW5hbG9nVHJpZ2dlcj4gYW5hbG9nVHJpZ2dlciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgQW5hbG9nVHJpZ2dlclR5cGUgdHJpZ2dlclR5cGUpIHsKKyAgaWYgKFN0YXR1c0lzRmF0YWwoKSkgcmV0dXJuOworICBTZXRVcFNvdXJjZShhbmFsb2dUcmlnZ2VyLT5DcmVhdGVPdXRwdXQodHJpZ2dlclR5cGUpKTsKK30KKworLyoqCisgKiBTZXQgdGhlIHNvdXJjZSBvYmplY3QgdGhhdCBjYXVzZXMgdGhlIGNvdW50ZXIgdG8gY291bnQgdXAuCisgKiBTZXQgdGhlIHVwIGNvdW50aW5nIERpZ2l0YWxTb3VyY2UuCisgKiBAcGFyYW0gc291cmNlIFBvaW50ZXIgdG8gdGhlIERpZ2l0YWxTb3VyY2Ugb2JqZWN0IHRvIHNldCBhcyB0aGUgdXAgc291cmNlCisgKi8KK3ZvaWQgQ291bnRlcjo6U2V0VXBTb3VyY2Uoc3RkOjpzaGFyZWRfcHRyPERpZ2l0YWxTb3VyY2U+IHNvdXJjZSkgeworICBpZiAoU3RhdHVzSXNGYXRhbCgpKSByZXR1cm47CisgIG1fdXBTb3VyY2UgPSBzb3VyY2U7CisgIGlmIChtX3VwU291cmNlLT5TdGF0dXNJc0ZhdGFsKCkpIHsKKyAgICBDbG9uZUVycm9yKCptX3VwU291cmNlKTsKKyAgfSBlbHNlIHsKKyAgICBpbnQzMl90IHN0YXR1cyA9IDA7CisgICAgc2V0Q291bnRlclVwU291cmNlKG1fY291bnRlciwgc291cmNlLT5HZXRDaGFubmVsRm9yUm91dGluZygpLAorICAgICAgICAgICAgICAgICAgICAgICBzb3VyY2UtPkdldEFuYWxvZ1RyaWdnZXJGb3JSb3V0aW5nKCksICZzdGF0dXMpOworICAgIHdwaV9zZXRFcnJvcldpdGhDb250ZXh0KHN0YXR1cywgZ2V0SEFMRXJyb3JNZXNzYWdlKHN0YXR1cykpOworICB9Cit9CisKK3ZvaWQgQ291bnRlcjo6U2V0VXBTb3VyY2UoRGlnaXRhbFNvdXJjZSAqc291cmNlKSB7CisgIFNldFVwU291cmNlKAorICAgICAgc3RkOjpzaGFyZWRfcHRyPERpZ2l0YWxTb3VyY2U+KHNvdXJjZSwgTnVsbERlbGV0ZXI8RGlnaXRhbFNvdXJjZT4oKSkpOworfQorCisvKioKKyAqIFNldCB0aGUgc291cmNlIG9iamVjdCB0aGF0IGNhdXNlcyB0aGUgY291bnRlciB0byBjb3VudCB1cC4KKyAqIFNldCB0aGUgdXAgY291bnRpbmcgRGlnaXRhbFNvdXJjZS4KKyAqIEBwYXJhbSBzb3VyY2UgUmVmZXJlbmNlIHRvIHRoZSBEaWdpdGFsU291cmNlIG9iamVjdCB0byBzZXQgYXMgdGhlIHVwIHNvdXJjZQorICovCit2b2lkIENvdW50ZXI6OlNldFVwU291cmNlKERpZ2l0YWxTb3VyY2UgJnNvdXJjZSkgeworICBTZXRVcFNvdXJjZSgKKyAgICAgIHN0ZDo6c2hhcmVkX3B0cjxEaWdpdGFsU291cmNlPigmc291cmNlLCBOdWxsRGVsZXRlcjxEaWdpdGFsU291cmNlPigpKSk7Cit9CisKKy8qKgorICogU2V0IHRoZSBlZGdlIHNlbnNpdGl2aXR5IG9uIGFuIHVwIGNvdW50aW5nIHNvdXJjZS4KKyAqIFNldCB0aGUgdXAgc291cmNlIHRvIGVpdGhlciBkZXRlY3QgcmlzaW5nIGVkZ2VzIG9yIGZhbGxpbmcgZWRnZXMgb3IgYm90aC4KKyAqIEBwYXJhbSByaXNpbmdFZGdlIFRydWUgdG8gdHJpZ2dlciBvbiByaXNpbmcgZWRnZXMKKyAqIEBwYXJhbSBmYWxsaW5nRWRnZSBUcnVlIHRvIHRyaWdnZXIgb24gZmFsbGluZyBlZGdlcworICovCit2b2lkIENvdW50ZXI6OlNldFVwU291cmNlRWRnZShib29sIHJpc2luZ0VkZ2UsIGJvb2wgZmFsbGluZ0VkZ2UpIHsKKyAgaWYgKFN0YXR1c0lzRmF0YWwoKSkgcmV0dXJuOworICBpZiAobV91cFNvdXJjZSA9PSBudWxscHRyKSB7CisgICAgd3BpX3NldFdQSUVycm9yV2l0aENvbnRleHQoCisgICAgICAgIE51bGxQYXJhbWV0ZXIsCisgICAgICAgICJNdXN0IHNldCBub24tbnVsbHB0ciBVcFNvdXJjZSBiZWZvcmUgc2V0dGluZyBVcFNvdXJjZUVkZ2UiKTsKKyAgfQorICBpbnQzMl90IHN0YXR1cyA9IDA7CisgIHNldENvdW50ZXJVcFNvdXJjZUVkZ2UobV9jb3VudGVyLCByaXNpbmdFZGdlLCBmYWxsaW5nRWRnZSwgJnN0YXR1cyk7CisgIHdwaV9zZXRFcnJvcldpdGhDb250ZXh0KHN0YXR1cywgZ2V0SEFMRXJyb3JNZXNzYWdlKHN0YXR1cykpOworfQorCisvKioKKyAqIERpc2FibGUgdGhlIHVwIGNvdW50aW5nIHNvdXJjZSB0byB0aGUgY291bnRlci4KKyAqLwordm9pZCBDb3VudGVyOjpDbGVhclVwU291cmNlKCkgeworICBpZiAoU3RhdHVzSXNGYXRhbCgpKSByZXR1cm47CisgIG1fdXBTb3VyY2UucmVzZXQoKTsKKyAgaW50MzJfdCBzdGF0dXMgPSAwOworICBjbGVhckNvdW50ZXJVcFNvdXJjZShtX2NvdW50ZXIsICZzdGF0dXMpOworICB3cGlfc2V0RXJyb3JXaXRoQ29udGV4dChzdGF0dXMsIGdldEhBTEVycm9yTWVzc2FnZShzdGF0dXMpKTsKK30KKworLyoqCisgKiBTZXQgdGhlIGRvd24gY291bnRpbmcgc291cmNlIHRvIGJlIGEgZGlnaXRhbCBpbnB1dCBjaGFubmVsLgorICogQHBhcmFtIGNoYW5uZWwgVGhlIERJTyBjaGFubmVsIHRvIHVzZSBhcyB0aGUgdXAgc291cmNlLiAwLTkgYXJlIG9uLWJvYXJkLAorICogMTAtMjUgYXJlIG9uIHRoZSBNWFAKKyAqLwordm9pZCBDb3VudGVyOjpTZXREb3duU291cmNlKGludDMyX3QgY2hhbm5lbCkgeworICBpZiAoU3RhdHVzSXNGYXRhbCgpKSByZXR1cm47CisgIFNldERvd25Tb3VyY2Uoc3RkOjptYWtlX3NoYXJlZDxEaWdpdGFsSW5wdXQ+KGNoYW5uZWwpKTsKK30KKworLyoqCisgKiBTZXQgdGhlIGRvd24gY291bnRpbmcgc291cmNlIHRvIGJlIGFuIGFuYWxvZyB0cmlnZ2VyLgorICogQHBhcmFtIGFuYWxvZ1RyaWdnZXIgVGhlIGFuYWxvZyB0cmlnZ2VyIG9iamVjdCB0aGF0IGlzIHVzZWQgZm9yIHRoZSBEb3duCisgKiBTb3VyY2UKKyAqIEBwYXJhbSB0cmlnZ2VyVHlwZSBUaGUgYW5hbG9nIHRyaWdnZXIgb3V0cHV0IHRoYXQgd2lsbCB0cmlnZ2VyIHRoZSBjb3VudGVyLgorICovCit2b2lkIENvdW50ZXI6OlNldERvd25Tb3VyY2UoQW5hbG9nVHJpZ2dlciAqYW5hbG9nVHJpZ2dlciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBBbmFsb2dUcmlnZ2VyVHlwZSB0cmlnZ2VyVHlwZSkgeworICBTZXREb3duU291cmNlKHN0ZDo6c2hhcmVkX3B0cjxBbmFsb2dUcmlnZ2VyPihhbmFsb2dUcmlnZ2VyLCBOdWxsRGVsZXRlcjxBbmFsb2dUcmlnZ2VyPigpKSwgdHJpZ2dlclR5cGUpOworfQorCisvKioKKyAqIFNldCB0aGUgZG93biBjb3VudGluZyBzb3VyY2UgdG8gYmUgYW4gYW5hbG9nIHRyaWdnZXIuCisgKiBAcGFyYW0gYW5hbG9nVHJpZ2dlciBUaGUgYW5hbG9nIHRyaWdnZXIgb2JqZWN0IHRoYXQgaXMgdXNlZCBmb3IgdGhlIERvd24KKyAqIFNvdXJjZQorICogQHBhcmFtIHRyaWdnZXJUeXBlIFRoZSBhbmFsb2cgdHJpZ2dlciBvdXRwdXQgdGhhdCB3aWxsIHRyaWdnZXIgdGhlIGNvdW50ZXIuCisgKi8KK3ZvaWQgQ291bnRlcjo6U2V0RG93blNvdXJjZShzdGQ6OnNoYXJlZF9wdHI8QW5hbG9nVHJpZ2dlcj4gYW5hbG9nVHJpZ2dlciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBBbmFsb2dUcmlnZ2VyVHlwZSB0cmlnZ2VyVHlwZSkgeworICBpZiAoU3RhdHVzSXNGYXRhbCgpKSByZXR1cm47CisgIFNldERvd25Tb3VyY2UoYW5hbG9nVHJpZ2dlci0+Q3JlYXRlT3V0cHV0KHRyaWdnZXJUeXBlKSk7Cit9CisKKy8qKgorICogU2V0IHRoZSBzb3VyY2Ugb2JqZWN0IHRoYXQgY2F1c2VzIHRoZSBjb3VudGVyIHRvIGNvdW50IGRvd24uCisgKiBTZXQgdGhlIGRvd24gY291bnRpbmcgRGlnaXRhbFNvdXJjZS4KKyAqIEBwYXJhbSBzb3VyY2UgUG9pbnRlciB0byB0aGUgRGlnaXRhbFNvdXJjZSBvYmplY3QgdG8gc2V0IGFzIHRoZSBkb3duIHNvdXJjZQorICovCit2b2lkIENvdW50ZXI6OlNldERvd25Tb3VyY2Uoc3RkOjpzaGFyZWRfcHRyPERpZ2l0YWxTb3VyY2U+IHNvdXJjZSkgeworICBpZiAoU3RhdHVzSXNGYXRhbCgpKSByZXR1cm47CisgIG1fZG93blNvdXJjZSA9IHNvdXJjZTsKKyAgaWYgKG1fZG93blNvdXJjZS0+U3RhdHVzSXNGYXRhbCgpKSB7CisgICAgQ2xvbmVFcnJvcigqbV9kb3duU291cmNlKTsKKyAgfSBlbHNlIHsKKyAgICBpbnQzMl90IHN0YXR1cyA9IDA7CisgICAgc2V0Q291bnRlckRvd25Tb3VyY2UobV9jb3VudGVyLCBzb3VyY2UtPkdldENoYW5uZWxGb3JSb3V0aW5nKCksCisgICAgICAgICAgICAgICAgICAgICAgICAgc291cmNlLT5HZXRBbmFsb2dUcmlnZ2VyRm9yUm91dGluZygpLCAmc3RhdHVzKTsKKyAgICB3cGlfc2V0RXJyb3JXaXRoQ29udGV4dChzdGF0dXMsIGdldEhBTEVycm9yTWVzc2FnZShzdGF0dXMpKTsKKyAgfQorfQorCit2b2lkIENvdW50ZXI6OlNldERvd25Tb3VyY2UoRGlnaXRhbFNvdXJjZSAqc291cmNlKSB7CisgIFNldERvd25Tb3VyY2Uoc3RkOjpzaGFyZWRfcHRyPERpZ2l0YWxTb3VyY2U+KHNvdXJjZSwgTnVsbERlbGV0ZXI8RGlnaXRhbFNvdXJjZT4oKSkpOworfQorCisvKioKKyAqIFNldCB0aGUgc291cmNlIG9iamVjdCB0aGF0IGNhdXNlcyB0aGUgY291bnRlciB0byBjb3VudCBkb3duLgorICogU2V0IHRoZSBkb3duIGNvdW50aW5nIERpZ2l0YWxTb3VyY2UuCisgKiBAcGFyYW0gc291cmNlIFJlZmVyZW5jZSB0byB0aGUgRGlnaXRhbFNvdXJjZSBvYmplY3QgdG8gc2V0IGFzIHRoZSBkb3duIHNvdXJjZQorICovCit2b2lkIENvdW50ZXI6OlNldERvd25Tb3VyY2UoRGlnaXRhbFNvdXJjZSAmc291cmNlKSB7CisgIFNldERvd25Tb3VyY2Uoc3RkOjpzaGFyZWRfcHRyPERpZ2l0YWxTb3VyY2U+KCZzb3VyY2UsIE51bGxEZWxldGVyPERpZ2l0YWxTb3VyY2U+KCkpKTsKK30KKworLyoqCisgKiBTZXQgdGhlIGVkZ2Ugc2Vuc2l0aXZpdHkgb24gYSBkb3duIGNvdW50aW5nIHNvdXJjZS4KKyAqIFNldCB0aGUgZG93biBzb3VyY2UgdG8gZWl0aGVyIGRldGVjdCByaXNpbmcgZWRnZXMgb3IgZmFsbGluZyBlZGdlcy4KKyAqIEBwYXJhbSByaXNpbmdFZGdlIFRydWUgdG8gdHJpZ2dlciBvbiByaXNpbmcgZWRnZXMKKyAqIEBwYXJhbSBmYWxsaW5nRWRnZSBUcnVlIHRvIHRyaWdnZXIgb24gZmFsbGluZyBlZGdlcworICovCit2b2lkIENvdW50ZXI6OlNldERvd25Tb3VyY2VFZGdlKGJvb2wgcmlzaW5nRWRnZSwgYm9vbCBmYWxsaW5nRWRnZSkgeworICBpZiAoU3RhdHVzSXNGYXRhbCgpKSByZXR1cm47CisgIGlmIChtX2Rvd25Tb3VyY2UgPT0gbnVsbHB0cikgeworICAgIHdwaV9zZXRXUElFcnJvcldpdGhDb250ZXh0KAorICAgICAgICBOdWxsUGFyYW1ldGVyLAorICAgICAgICAiTXVzdCBzZXQgbm9uLW51bGxwdHIgRG93blNvdXJjZSBiZWZvcmUgc2V0dGluZyBEb3duU291cmNlRWRnZSIpOworICB9CisgIGludDMyX3Qgc3RhdHVzID0gMDsKKyAgc2V0Q291bnRlckRvd25Tb3VyY2VFZGdlKG1fY291bnRlciwgcmlzaW5nRWRnZSwgZmFsbGluZ0VkZ2UsICZzdGF0dXMpOworICB3cGlfc2V0RXJyb3JXaXRoQ29udGV4dChzdGF0dXMsIGdldEhBTEVycm9yTWVzc2FnZShzdGF0dXMpKTsKK30KKworLyoqCisgKiBEaXNhYmxlIHRoZSBkb3duIGNvdW50aW5nIHNvdXJjZSB0byB0aGUgY291bnRlci4KKyAqLwordm9pZCBDb3VudGVyOjpDbGVhckRvd25Tb3VyY2UoKSB7CisgIGlmIChTdGF0dXNJc0ZhdGFsKCkpIHJldHVybjsKKyAgbV9kb3duU291cmNlLnJlc2V0KCk7CisgIGludDMyX3Qgc3RhdHVzID0gMDsKKyAgY2xlYXJDb3VudGVyRG93blNvdXJjZShtX2NvdW50ZXIsICZzdGF0dXMpOworICB3cGlfc2V0RXJyb3JXaXRoQ29udGV4dChzdGF0dXMsIGdldEhBTEVycm9yTWVzc2FnZShzdGF0dXMpKTsKK30KKworLyoqCisgKiBTZXQgc3RhbmRhcmQgdXAgLyBkb3duIGNvdW50aW5nIG1vZGUgb24gdGhpcyBjb3VudGVyLgorICogVXAgYW5kIGRvd24gY291bnRzIGFyZSBzb3VyY2VkIGluZGVwZW5kZW50bHkgZnJvbSB0d28gaW5wdXRzLgorICovCit2b2lkIENvdW50ZXI6OlNldFVwRG93bkNvdW50ZXJNb2RlKCkgeworICBpZiAoU3RhdHVzSXNGYXRhbCgpKSByZXR1cm47CisgIGludDMyX3Qgc3RhdHVzID0gMDsKKyAgc2V0Q291bnRlclVwRG93bk1vZGUobV9jb3VudGVyLCAmc3RhdHVzKTsKKyAgd3BpX3NldEVycm9yV2l0aENvbnRleHQoc3RhdHVzLCBnZXRIQUxFcnJvck1lc3NhZ2Uoc3RhdHVzKSk7Cit9CisKKy8qKgorICogU2V0IGV4dGVybmFsIGRpcmVjdGlvbiBtb2RlIG9uIHRoaXMgY291bnRlci4KKyAqIENvdW50cyBhcmUgc291cmNlZCBvbiB0aGUgVXAgY291bnRlciBpbnB1dC4KKyAqIFRoZSBEb3duIGNvdW50ZXIgaW5wdXQgcmVwcmVzZW50cyB0aGUgZGlyZWN0aW9uIHRvIGNvdW50LgorICovCit2b2lkIENvdW50ZXI6OlNldEV4dGVybmFsRGlyZWN0aW9uTW9kZSgpIHsKKyAgaWYgKFN0YXR1c0lzRmF0YWwoKSkgcmV0dXJuOworICBpbnQzMl90IHN0YXR1cyA9IDA7CisgIHNldENvdW50ZXJFeHRlcm5hbERpcmVjdGlvbk1vZGUobV9jb3VudGVyLCAmc3RhdHVzKTsKKyAgd3BpX3NldEVycm9yV2l0aENvbnRleHQoc3RhdHVzLCBnZXRIQUxFcnJvck1lc3NhZ2Uoc3RhdHVzKSk7Cit9CisKKy8qKgorICogU2V0IFNlbWktcGVyaW9kIG1vZGUgb24gdGhpcyBjb3VudGVyLgorICogQ291bnRzIHVwIG9uIGJvdGggcmlzaW5nIGFuZCBmYWxsaW5nIGVkZ2VzLgorICovCit2b2lkIENvdW50ZXI6OlNldFNlbWlQZXJpb2RNb2RlKGJvb2wgaGlnaFNlbWlQZXJpb2QpIHsKKyAgaWYgKFN0YXR1c0lzRmF0YWwoKSkgcmV0dXJuOworICBpbnQzMl90IHN0YXR1cyA9IDA7CisgIHNldENvdW50ZXJTZW1pUGVyaW9kTW9kZShtX2NvdW50ZXIsIGhpZ2hTZW1pUGVyaW9kLCAmc3RhdHVzKTsKKyAgd3BpX3NldEVycm9yV2l0aENvbnRleHQoc3RhdHVzLCBnZXRIQUxFcnJvck1lc3NhZ2Uoc3RhdHVzKSk7Cit9CisKKy8qKgorICogQ29uZmlndXJlIHRoZSBjb3VudGVyIHRvIGNvdW50IGluIHVwIG9yIGRvd24gYmFzZWQgb24gdGhlIGxlbmd0aCBvZiB0aGUgaW5wdXQKKyAqIHB1bHNlLgorICogVGhpcyBtb2RlIGlzIG1vc3QgdXNlZnVsIGZvciBkaXJlY3Rpb24gc2Vuc2l0aXZlIGdlYXIgdG9vdGggc2Vuc29ycy4KKyAqIEBwYXJhbSB0aHJlc2hvbGQgVGhlIHB1bHNlIGxlbmd0aCBiZXlvbmQgd2hpY2ggdGhlIGNvdW50ZXIgY291bnRzIHRoZQorICogb3Bwb3NpdGUgZGlyZWN0aW9uLiAgVW5pdHMgYXJlIHNlY29uZHMuCisgKi8KK3ZvaWQgQ291bnRlcjo6U2V0UHVsc2VMZW5ndGhNb2RlKGZsb2F0IHRocmVzaG9sZCkgeworICBpZiAoU3RhdHVzSXNGYXRhbCgpKSByZXR1cm47CisgIGludDMyX3Qgc3RhdHVzID0gMDsKKyAgc2V0Q291bnRlclB1bHNlTGVuZ3RoTW9kZShtX2NvdW50ZXIsIHRocmVzaG9sZCwgJnN0YXR1cyk7CisgIHdwaV9zZXRFcnJvcldpdGhDb250ZXh0KHN0YXR1cywgZ2V0SEFMRXJyb3JNZXNzYWdlKHN0YXR1cykpOworfQorCisvKioKKyAqIEdldCB0aGUgU2FtcGxlcyB0byBBdmVyYWdlIHdoaWNoIHNwZWNpZmllcyB0aGUgbnVtYmVyIG9mIHNhbXBsZXMgb2YgdGhlIHRpbWVyCisgKiB0bworICogYXZlcmFnZSB3aGVuIGNhbGN1bGF0aW5nIHRoZSBwZXJpb2QuIFBlcmZvcm0gYXZlcmFnaW5nIHRvIGFjY291bnQgZm9yCisgKiBtZWNoYW5pY2FsIGltcGVyZmVjdGlvbnMgb3IgYXMgb3ZlcnNhbXBsaW5nIHRvIGluY3JlYXNlIHJlc29sdXRpb24uCisgKiBAcmV0dXJuIFNhbXBsZXNUb0F2ZXJhZ2UgVGhlIG51bWJlciBvZiBzYW1wbGVzIGJlaW5nIGF2ZXJhZ2VkIChmcm9tIDEgdG8gMTI3KQorICovCitpbnQgQ291bnRlcjo6R2V0U2FtcGxlc1RvQXZlcmFnZSgpIGNvbnN0IHsKKyAgaW50MzJfdCBzdGF0dXMgPSAwOworICBpbnQzMl90IHNhbXBsZXMgPSBnZXRDb3VudGVyU2FtcGxlc1RvQXZlcmFnZShtX2NvdW50ZXIsICZzdGF0dXMpOworICB3cGlfc2V0RXJyb3JXaXRoQ29udGV4dChzdGF0dXMsIGdldEhBTEVycm9yTWVzc2FnZShzdGF0dXMpKTsKKyAgcmV0dXJuIHNhbXBsZXM7Cit9CisKKy8qKgorICogU2V0IHRoZSBTYW1wbGVzIHRvIEF2ZXJhZ2Ugd2hpY2ggc3BlY2lmaWVzIHRoZSBudW1iZXIgb2Ygc2FtcGxlcyBvZiB0aGUgdGltZXIKKyAqIHRvCisgKiBhdmVyYWdlIHdoZW4gY2FsY3VsYXRpbmcgdGhlIHBlcmlvZC4gUGVyZm9ybSBhdmVyYWdpbmcgdG8gYWNjb3VudCBmb3IKKyAqIG1lY2hhbmljYWwgaW1wZXJmZWN0aW9ucyBvciBhcyBvdmVyc2FtcGxpbmcgdG8gaW5jcmVhc2UgcmVzb2x1dGlvbi4KKyAqIEBwYXJhbSBzYW1wbGVzVG9BdmVyYWdlIFRoZSBudW1iZXIgb2Ygc2FtcGxlcyB0byBhdmVyYWdlIGZyb20gMSB0byAxMjcuCisgKi8KK3ZvaWQgQ291bnRlcjo6U2V0U2FtcGxlc1RvQXZlcmFnZShpbnQgc2FtcGxlc1RvQXZlcmFnZSkgeworICBpZiAoc2FtcGxlc1RvQXZlcmFnZSA8IDEgfHwgc2FtcGxlc1RvQXZlcmFnZSA+IDEyNykgeworICAgIHdwaV9zZXRXUElFcnJvcldpdGhDb250ZXh0KAorICAgICAgICBQYXJhbWV0ZXJPdXRPZlJhbmdlLAorICAgICAgICAiQXZlcmFnZSBjb3VudGVyIHZhbHVlcyBtdXN0IGJlIGJldHdlZW4gMSBhbmQgMTI3Iik7CisgIH0KKyAgaW50MzJfdCBzdGF0dXMgPSAwOworICBzZXRDb3VudGVyU2FtcGxlc1RvQXZlcmFnZShtX2NvdW50ZXIsIHNhbXBsZXNUb0F2ZXJhZ2UsICZzdGF0dXMpOworICB3cGlfc2V0RXJyb3JXaXRoQ29udGV4dChzdGF0dXMsIGdldEhBTEVycm9yTWVzc2FnZShzdGF0dXMpKTsKK30KKworLyoqCisgKiBSZWFkIHRoZSBjdXJyZW50IGNvdW50ZXIgdmFsdWUuCisgKiBSZWFkIHRoZSB2YWx1ZSBhdCB0aGlzIGluc3RhbnQuIEl0IG1heSBzdGlsbCBiZSBydW5uaW5nLCBzbyBpdCByZWZsZWN0cyB0aGUKKyAqIGN1cnJlbnQgdmFsdWUuIE5leHQKKyAqIHRpbWUgaXQgaXMgcmVhZCwgaXQgbWlnaHQgaGF2ZSBhIGRpZmZlcmVudCB2YWx1ZS4KKyAqLworaW50MzJfdCBDb3VudGVyOjpHZXQoKSBjb25zdCB7CisgIGlmIChTdGF0dXNJc0ZhdGFsKCkpIHJldHVybiAwOworICBpbnQzMl90IHN0YXR1cyA9IDA7CisgIGludDMyX3QgdmFsdWUgPSBnZXRDb3VudGVyKG1fY291bnRlciwgJnN0YXR1cyk7CisgIHdwaV9zZXRFcnJvcldpdGhDb250ZXh0KHN0YXR1cywgZ2V0SEFMRXJyb3JNZXNzYWdlKHN0YXR1cykpOworICByZXR1cm4gdmFsdWU7Cit9CisKKy8qKgorICogUmVzZXQgdGhlIENvdW50ZXIgdG8gemVyby4KKyAqIFNldCB0aGUgY291bnRlciB2YWx1ZSB0byB6ZXJvLiBUaGlzIGRvZXNuJ3QgZWZmZWN0IHRoZSBydW5uaW5nIHN0YXRlIG9mIHRoZQorICogY291bnRlciwganVzdCBzZXRzCisgKiB0aGUgY3VycmVudCB2YWx1ZSB0byB6ZXJvLgorICovCit2b2lkIENvdW50ZXI6OlJlc2V0KCkgeworICBpZiAoU3RhdHVzSXNGYXRhbCgpKSByZXR1cm47CisgIGludDMyX3Qgc3RhdHVzID0gMDsKKyAgcmVzZXRDb3VudGVyKG1fY291bnRlciwgJnN0YXR1cyk7CisgIHdwaV9zZXRFcnJvcldpdGhDb250ZXh0KHN0YXR1cywgZ2V0SEFMRXJyb3JNZXNzYWdlKHN0YXR1cykpOworfQorCisvKioKKyAqIEdldCB0aGUgUGVyaW9kIG9mIHRoZSBtb3N0IHJlY2VudCBjb3VudC4KKyAqIFJldHVybnMgdGhlIHRpbWUgaW50ZXJ2YWwgb2YgdGhlIG1vc3QgcmVjZW50IGNvdW50LiBUaGlzIGNhbiBiZSB1c2VkIGZvcgorICogdmVsb2NpdHkgY2FsY3VsYXRpb25zCisgKiB0byBkZXRlcm1pbmUgc2hhZnQgc3BlZWQuCisgKiBAcmV0dXJucyBUaGUgcGVyaW9kIGJldHdlZW4gdGhlIGxhc3QgdHdvIHB1bHNlcyBpbiB1bml0cyBvZiBzZWNvbmRzLgorICovCitkb3VibGUgQ291bnRlcjo6R2V0UGVyaW9kKCkgY29uc3QgeworICBpZiAoU3RhdHVzSXNGYXRhbCgpKSByZXR1cm4gMC4wOworICBpbnQzMl90IHN0YXR1cyA9IDA7CisgIGRvdWJsZSB2YWx1ZSA9IGdldENvdW50ZXJQZXJpb2QobV9jb3VudGVyLCAmc3RhdHVzKTsKKyAgd3BpX3NldEVycm9yV2l0aENvbnRleHQoc3RhdHVzLCBnZXRIQUxFcnJvck1lc3NhZ2Uoc3RhdHVzKSk7CisgIHJldHVybiB2YWx1ZTsKK30KKworLyoqCisgKiBTZXQgdGhlIG1heGltdW0gcGVyaW9kIHdoZXJlIHRoZSBkZXZpY2UgaXMgc3RpbGwgY29uc2lkZXJlZCAibW92aW5nIi4KKyAqIFNldHMgdGhlIG1heGltdW0gcGVyaW9kIHdoZXJlIHRoZSBkZXZpY2UgaXMgY29uc2lkZXJlZCBtb3ZpbmcuIFRoaXMgdmFsdWUgaXMKKyAqIHVzZWQgdG8gZGV0ZXJtaW5lCisgKiB0aGUgInN0b3BwZWQiIHN0YXRlIG9mIHRoZSBjb3VudGVyIHVzaW5nIHRoZSBHZXRTdG9wcGVkIG1ldGhvZC4KKyAqIEBwYXJhbSBtYXhQZXJpb2QgVGhlIG1heGltdW0gcGVyaW9kIHdoZXJlIHRoZSBjb3VudGVkIGRldmljZSBpcyBjb25zaWRlcmVkCisgKiBtb3ZpbmcgaW4KKyAqIHNlY29uZHMuCisgKi8KK3ZvaWQgQ291bnRlcjo6U2V0TWF4UGVyaW9kKGRvdWJsZSBtYXhQZXJpb2QpIHsKKyAgaWYgKFN0YXR1c0lzRmF0YWwoKSkgcmV0dXJuOworICBpbnQzMl90IHN0YXR1cyA9IDA7CisgIHNldENvdW50ZXJNYXhQZXJpb2QobV9jb3VudGVyLCBtYXhQZXJpb2QsICZzdGF0dXMpOworICB3cGlfc2V0RXJyb3JXaXRoQ29udGV4dChzdGF0dXMsIGdldEhBTEVycm9yTWVzc2FnZShzdGF0dXMpKTsKK30KKworLyoqCisgKiBTZWxlY3Qgd2hldGhlciB5b3Ugd2FudCB0byBjb250aW51ZSB1cGRhdGluZyB0aGUgZXZlbnQgdGltZXIgb3V0cHV0IHdoZW4KKyAqIHRoZXJlIGFyZSBubyBzYW1wbGVzIGNhcHR1cmVkLgorICogVGhlIG91dHB1dCBvZiB0aGUgZXZlbnQgdGltZXIgaGFzIGEgYnVmZmVyIG9mIHBlcmlvZHMgdGhhdCBhcmUgYXZlcmFnZWQgYW5kCisgKiBwb3N0ZWQgdG8KKyAqIGEgcmVnaXN0ZXIgb24gdGhlIEZQR0EuICBXaGVuIHRoZSB0aW1lciBkZXRlY3RzIHRoYXQgdGhlIGV2ZW50IHNvdXJjZSBoYXMKKyAqIHN0b3BwZWQKKyAqIChiYXNlZCBvbiB0aGUgTWF4UGVyaW9kKSB0aGUgYnVmZmVyIG9mIHNhbXBsZXMgdG8gYmUgYXZlcmFnZWQgaXMgZW1wdGllZC4gIElmCisgKiB5b3UKKyAqIGVuYWJsZSB0aGUgdXBkYXRlIHdoZW4gZW1wdHksIHlvdSB3aWxsIGJlIG5vdGlmaWVkIG9mIHRoZSBzdG9wcGVkIHNvdXJjZSBhbmQKKyAqIHRoZSBldmVudAorICogdGltZSB3aWxsIHJlcG9ydCAwIHNhbXBsZXMuICBJZiB5b3UgZGlzYWJsZSB1cGRhdGUgd2hlbiBlbXB0eSwgdGhlIG1vc3QKKyAqIHJlY2VudCBhdmVyYWdlCisgKiB3aWxsIHJlbWFpbiBvbiB0aGUgb3V0cHV0IHVudGlsIGEgbmV3IHNhbXBsZSBpcyBhY3F1aXJlZC4gIFlvdSB3aWxsIG5ldmVyIHNlZQorICogMCBzYW1wbGVzCisgKiBvdXRwdXQgKGV4Y2VwdCB3aGVuIHRoZXJlIGhhdmUgYmVlbiBubyBldmVudHMgc2luY2UgYW4gRlBHQSByZXNldCkgYW5kIHlvdQorICogd2lsbCBsaWtlbHkgbm90CisgKiBzZWUgdGhlIHN0b3BwZWQgYml0IGJlY29tZSB0cnVlIChzaW5jZSBpdCBpcyB1cGRhdGVkIGF0IHRoZSBlbmQgb2YgYW4gYXZlcmFnZQorICogYW5kIHRoZXJlIGFyZQorICogbm8gc2FtcGxlcyB0byBhdmVyYWdlKS4KKyAqIEBwYXJhbSBlbmFibGVkIFRydWUgdG8gZW5hYmxlIHVwZGF0ZSB3aGVuIGVtcHR5CisgKi8KK3ZvaWQgQ291bnRlcjo6U2V0VXBkYXRlV2hlbkVtcHR5KGJvb2wgZW5hYmxlZCkgeworICBpZiAoU3RhdHVzSXNGYXRhbCgpKSByZXR1cm47CisgIGludDMyX3Qgc3RhdHVzID0gMDsKKyAgc2V0Q291bnRlclVwZGF0ZVdoZW5FbXB0eShtX2NvdW50ZXIsIGVuYWJsZWQsICZzdGF0dXMpOworICB3cGlfc2V0RXJyb3JXaXRoQ29udGV4dChzdGF0dXMsIGdldEhBTEVycm9yTWVzc2FnZShzdGF0dXMpKTsKK30KKworLyoqCisgKiBEZXRlcm1pbmUgaWYgdGhlIGNsb2NrIGlzIHN0b3BwZWQuCisgKiBEZXRlcm1pbmUgaWYgdGhlIGNsb2NrZWQgaW5wdXQgaXMgc3RvcHBlZCBiYXNlZCBvbiB0aGUgTWF4UGVyaW9kIHZhbHVlIHNldAorICogdXNpbmcgdGhlCisgKiBTZXRNYXhQZXJpb2QgbWV0aG9kLiBJZiB0aGUgY2xvY2sgZXhjZWVkcyB0aGUgTWF4UGVyaW9kLCB0aGVuIHRoZSBkZXZpY2UgKGFuZAorICogY291bnRlcikgYXJlCisgKiBhc3N1bWVkIHRvIGJlIHN0b3BwZWQgYW5kIGl0IHJldHVybnMgdHJ1ZS4KKyAqIEByZXR1cm4gUmV0dXJucyB0cnVlIGlmIHRoZSBtb3N0IHJlY2VudCBjb3VudGVyIHBlcmlvZCBleGNlZWRzIHRoZSBNYXhQZXJpb2QKKyAqIHZhbHVlIHNldCBieQorICogU2V0TWF4UGVyaW9kLgorICovCitib29sIENvdW50ZXI6OkdldFN0b3BwZWQoKSBjb25zdCB7CisgIGlmIChTdGF0dXNJc0ZhdGFsKCkpIHJldHVybiBmYWxzZTsKKyAgaW50MzJfdCBzdGF0dXMgPSAwOworICBib29sIHZhbHVlID0gZ2V0Q291bnRlclN0b3BwZWQobV9jb3VudGVyLCAmc3RhdHVzKTsKKyAgd3BpX3NldEVycm9yV2l0aENvbnRleHQoc3RhdHVzLCBnZXRIQUxFcnJvck1lc3NhZ2Uoc3RhdHVzKSk7CisgIHJldHVybiB2YWx1ZTsKK30KKworLyoqCisgKiBUaGUgbGFzdCBkaXJlY3Rpb24gdGhlIGNvdW50ZXIgdmFsdWUgY2hhbmdlZC4KKyAqIEByZXR1cm4gVGhlIGxhc3QgZGlyZWN0aW9uIHRoZSBjb3VudGVyIHZhbHVlIGNoYW5nZWQuCisgKi8KK2Jvb2wgQ291bnRlcjo6R2V0RGlyZWN0aW9uKCkgY29uc3QgeworICBpZiAoU3RhdHVzSXNGYXRhbCgpKSByZXR1cm4gZmFsc2U7CisgIGludDMyX3Qgc3RhdHVzID0gMDsKKyAgYm9vbCB2YWx1ZSA9IGdldENvdW50ZXJEaXJlY3Rpb24obV9jb3VudGVyLCAmc3RhdHVzKTsKKyAgd3BpX3NldEVycm9yV2l0aENvbnRleHQoc3RhdHVzLCBnZXRIQUxFcnJvck1lc3NhZ2Uoc3RhdHVzKSk7CisgIHJldHVybiB2YWx1ZTsKK30KKworLyoqCisgKiBTZXQgdGhlIENvdW50ZXIgdG8gcmV0dXJuIHJldmVyc2VkIHNlbnNpbmcgb24gdGhlIGRpcmVjdGlvbi4KKyAqIFRoaXMgYWxsb3dzIGNvdW50ZXJzIHRvIGNoYW5nZSB0aGUgZGlyZWN0aW9uIHRoZXkgYXJlIGNvdW50aW5nIGluIHRoZSBjYXNlIG9mCisgKiAxWCBhbmQgMlgKKyAqIHF1YWRyYXR1cmUgZW5jb2Rpbmcgb25seS4gQW55IG90aGVyIGNvdW50ZXIgbW9kZSBpc24ndCBzdXBwb3J0ZWQuCisgKiBAcGFyYW0gcmV2ZXJzZURpcmVjdGlvbiB0cnVlIGlmIHRoZSB2YWx1ZSBjb3VudGVkIHNob3VsZCBiZSBuZWdhdGVkLgorICovCit2b2lkIENvdW50ZXI6OlNldFJldmVyc2VEaXJlY3Rpb24oYm9vbCByZXZlcnNlRGlyZWN0aW9uKSB7CisgIGlmIChTdGF0dXNJc0ZhdGFsKCkpIHJldHVybjsKKyAgaW50MzJfdCBzdGF0dXMgPSAwOworICBzZXRDb3VudGVyUmV2ZXJzZURpcmVjdGlvbihtX2NvdW50ZXIsIHJldmVyc2VEaXJlY3Rpb24sICZzdGF0dXMpOworICB3cGlfc2V0RXJyb3JXaXRoQ29udGV4dChzdGF0dXMsIGdldEhBTEVycm9yTWVzc2FnZShzdGF0dXMpKTsKK30KKwordm9pZCBDb3VudGVyOjpVcGRhdGVUYWJsZSgpIHsKKyAgaWYgKG1fdGFibGUgIT0gbnVsbHB0cikgeworICAgIG1fdGFibGUtPlB1dE51bWJlcigiVmFsdWUiLCBHZXQoKSk7CisgIH0KK30KKwordm9pZCBDb3VudGVyOjpTdGFydExpdmVXaW5kb3dNb2RlKCkge30KKwordm9pZCBDb3VudGVyOjpTdG9wTGl2ZVdpbmRvd01vZGUoKSB7fQorCitzdGQ6OnN0cmluZyBDb3VudGVyOjpHZXRTbWFydERhc2hib2FyZFR5cGUoKSBjb25zdCB7IHJldHVybiAiQ291bnRlciI7IH0KKwordm9pZCBDb3VudGVyOjpJbml0VGFibGUoc3RkOjpzaGFyZWRfcHRyPElUYWJsZT4gc3ViVGFibGUpIHsKKyAgbV90YWJsZSA9IHN1YlRhYmxlOworICBVcGRhdGVUYWJsZSgpOworfQorCitzdGQ6OnNoYXJlZF9wdHI8SVRhYmxlPiBDb3VudGVyOjpHZXRUYWJsZSgpIGNvbnN0IHsgcmV0dXJuIG1fdGFibGU7IH0KZGlmZiAtLWdpdCBhL3dwaWxpYmMvQXRoZW5hL3NyYy9EaWdpdGFsR2xpdGNoRmlsdGVyLmNwcCBiL3dwaWxpYmMvQXRoZW5hL3NyYy9EaWdpdGFsR2xpdGNoRmlsdGVyLmNwcApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi41NjE0N2NiCi0tLSAvZGV2L251bGwKKysrIGIvd3BpbGliYy9BdGhlbmEvc3JjL0RpZ2l0YWxHbGl0Y2hGaWx0ZXIuY3BwCkBAIC0wLDAgKzEsMTkwIEBACisvKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qLworLyogQ29weXJpZ2h0IChjKSBGSVJTVCAyMDE1LiBBbGwgUmlnaHRzIFJlc2VydmVkLiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKi8KKy8qIE9wZW4gU291cmNlIFNvZnR3YXJlIC0gbWF5IGJlIG1vZGlmaWVkIGFuZCBzaGFyZWQgYnkgRlJDIHRlYW1zLiBUaGUgY29kZSAgICovCisvKiBtdXN0IGJlIGFjY29tcGFuaWVkIGJ5IHRoZSBGSVJTVCBCU0QgbGljZW5zZSBmaWxlIGluICQoV0lORF9CQVNFKS9XUElMaWIuICAqLworLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi8KKworI2luY2x1ZGUgPGFsZ29yaXRobT4KKyNpbmNsdWRlIDxhcnJheT4KKworI2luY2x1ZGUgIkRpZ2l0YWxHbGl0Y2hGaWx0ZXIuaCIKKyNpbmNsdWRlICJSZXNvdXJjZS5oIgorI2luY2x1ZGUgIldQSUVycm9ycy5oIgorI2luY2x1ZGUgIkVuY29kZXIuaCIKKyNpbmNsdWRlICJDb3VudGVyLmgiCisjaW5jbHVkZSAiVXRpbGl0eS5oIgorCitzdGQ6OmFycmF5PGJvb2wsIDM+IERpZ2l0YWxHbGl0Y2hGaWx0ZXI6Om1fZmlsdGVyQWxsb2NhdGVkID0ge3tmYWxzZSwgZmFsc2UsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmYWxzZX19OworcHJpb3JpdHlfbXV0ZXggRGlnaXRhbEdsaXRjaEZpbHRlcjo6bV9tdXRleDsKKworRGlnaXRhbEdsaXRjaEZpbHRlcjo6RGlnaXRhbEdsaXRjaEZpbHRlcigpIHsKKyAgc3RkOjpsb2NrX2d1YXJkPHByaW9yaXR5X211dGV4PiBzeW5jKG1fbXV0ZXgpOworICBhdXRvIGluZGV4ID0KKyAgICAgIHN0ZDo6ZmluZChtX2ZpbHRlckFsbG9jYXRlZC5iZWdpbigpLCBtX2ZpbHRlckFsbG9jYXRlZC5lbmQoKSwgZmFsc2UpOworICB3cGlfYXNzZXJ0KGluZGV4ICE9IG1fZmlsdGVyQWxsb2NhdGVkLmVuZCgpKTsKKworICBtX2NoYW5uZWxJbmRleCA9IHN0ZDo6ZGlzdGFuY2UobV9maWx0ZXJBbGxvY2F0ZWQuYmVnaW4oKSwgaW5kZXgpOworICAqaW5kZXggPSB0cnVlOworCisgIEhBTFJlcG9ydChIQUxVc2FnZVJlcG9ydGluZzo6a1Jlc291cmNlVHlwZV9EaWdpdGFsRmlsdGVyLCBtX2NoYW5uZWxJbmRleCk7Cit9CisKK0RpZ2l0YWxHbGl0Y2hGaWx0ZXI6On5EaWdpdGFsR2xpdGNoRmlsdGVyKCkgeworICBpZiAobV9jaGFubmVsSW5kZXggPj0gMCkgeworICAgIHN0ZDo6bG9ja19ndWFyZDxwcmlvcml0eV9tdXRleD4gc3luYyhtX211dGV4KTsKKyAgICBtX2ZpbHRlckFsbG9jYXRlZFttX2NoYW5uZWxJbmRleF0gPSBmYWxzZTsKKyAgfQorfQorCisvKioKKyAqIEFzc2lnbnMgdGhlIERpZ2l0YWxTb3VyY2UgdG8gdGhpcyBnbGl0Y2ggZmlsdGVyLgorICoKKyAqIEBwYXJhbSBpbnB1dCBUaGUgRGlnaXRhbFNvdXJjZSB0byBhZGQuCisgKi8KK3ZvaWQgRGlnaXRhbEdsaXRjaEZpbHRlcjo6QWRkKERpZ2l0YWxTb3VyY2UgKmlucHV0KSB7CisgIERvQWRkKGlucHV0LCBtX2NoYW5uZWxJbmRleCArIDEpOworfQorCit2b2lkIERpZ2l0YWxHbGl0Y2hGaWx0ZXI6OkRvQWRkKERpZ2l0YWxTb3VyY2UgKmlucHV0LCBpbnQgcmVxdWVzdGVkX2luZGV4KSB7CisgIC8vIFNvbWUgc291cmNlcyBmcm9tIENvdW50ZXJzIGFuZCBFbmNvZGVycyBhcmUgbnVsbC4gIEJ5IHB1c2hpbmcgdGhlIGNoZWNrCisgIC8vIGhlcmUsIHdlIGNhdGNoIHRoZSBpc3N1ZSBtb3JlIGdlbmVyYWxseS4KKyAgaWYgKGlucHV0KSB7CisgICAgaW50MzJfdCBzdGF0dXMgPSAwOworICAgIHNldEZpbHRlclNlbGVjdChtX2RpZ2l0YWxfcG9ydHNbaW5wdXQtPkdldENoYW5uZWxGb3JSb3V0aW5nKCldLAorICAgICAgICAgICAgICAgICAgICByZXF1ZXN0ZWRfaW5kZXgsICZzdGF0dXMpOworICAgIHdwaV9zZXRFcnJvcldpdGhDb250ZXh0KHN0YXR1cywgZ2V0SEFMRXJyb3JNZXNzYWdlKHN0YXR1cykpOworCisgICAgLy8gVmFsaWRhdGUgdGhhdCB3ZSBzZXQgaXQgY29ycmVjdGx5LgorICAgIGludCBhY3R1YWxfaW5kZXggPSBnZXRGaWx0ZXJTZWxlY3QoCisgICAgICAgIG1fZGlnaXRhbF9wb3J0c1tpbnB1dC0+R2V0Q2hhbm5lbEZvclJvdXRpbmcoKV0sICZzdGF0dXMpOworICAgIHdwaV9hc3NlcnRFcXVhbChhY3R1YWxfaW5kZXgsIHJlcXVlc3RlZF9pbmRleCk7CisKKyAgICBIQUxSZXBvcnQoSEFMVXNhZ2VSZXBvcnRpbmc6OmtSZXNvdXJjZVR5cGVfRGlnaXRhbElucHV0LAorICAgICAgICAgICAgICBpbnB1dC0+R2V0Q2hhbm5lbEZvclJvdXRpbmcoKSk7CisgIH0KK30KKworLyoqCisgKiBBc3NpZ25zIHRoZSBFbmNvZGVyIHRvIHRoaXMgZ2xpdGNoIGZpbHRlci4KKyAqCisgKiBAcGFyYW0gaW5wdXQgVGhlIEVuY29kZXIgdG8gYWRkLgorICovCit2b2lkIERpZ2l0YWxHbGl0Y2hGaWx0ZXI6OkFkZChFbmNvZGVyICppbnB1dCkgeworICBBZGQoaW5wdXQtPm1fYVNvdXJjZS5nZXQoKSk7CisgIGlmIChTdGF0dXNJc0ZhdGFsKCkpIHsKKyAgICByZXR1cm47CisgIH0KKyAgQWRkKGlucHV0LT5tX2JTb3VyY2UuZ2V0KCkpOworfQorCisvKioKKyAqIEFzc2lnbnMgdGhlIENvdW50ZXIgdG8gdGhpcyBnbGl0Y2ggZmlsdGVyLgorICoKKyAqIEBwYXJhbSBpbnB1dCBUaGUgQ291bnRlciB0byBhZGQuCisgKi8KK3ZvaWQgRGlnaXRhbEdsaXRjaEZpbHRlcjo6QWRkKENvdW50ZXIgKmlucHV0KSB7CisgIEFkZChpbnB1dC0+bV91cFNvdXJjZS5nZXQoKSk7CisgIGlmIChTdGF0dXNJc0ZhdGFsKCkpIHsKKyAgICByZXR1cm47CisgIH0KKyAgQWRkKGlucHV0LT5tX2Rvd25Tb3VyY2UuZ2V0KCkpOworfQorCisvKioKKyAqIFJlbW92ZXMgYSBkaWdpdGFsIGlucHV0IGZyb20gdGhpcyBmaWx0ZXIuCisgKgorICogUmVtb3ZlcyB0aGUgRGlnaXRhbFNvdXJjZSBmcm9tIHRoaXMgZ2xpdGNoIGZpbHRlciBhbmQgcmUtYXNzaWducyBpdCB0bworICogdGhlIGRlZmF1bHQgZmlsdGVyLgorICoKKyAqIEBwYXJhbSBpbnB1dCBUaGUgRGlnaXRhbFNvdXJjZSB0byByZW1vdmUuCisgKi8KK3ZvaWQgRGlnaXRhbEdsaXRjaEZpbHRlcjo6UmVtb3ZlKERpZ2l0YWxTb3VyY2UgKmlucHV0KSB7CisgIERvQWRkKGlucHV0LCAwKTsKK30KKworLyoqCisgKiBSZW1vdmVzIGFuIGVuY29kZXIgZnJvbSB0aGlzIGZpbHRlci4KKyAqCisgKiBSZW1vdmVzIHRoZSBFbmNvZGVyIGZyb20gdGhpcyBnbGl0Y2ggZmlsdGVyIGFuZCByZS1hc3NpZ25zIGl0IHRvCisgKiB0aGUgZGVmYXVsdCBmaWx0ZXIuCisgKgorICogQHBhcmFtIGlucHV0IFRoZSBFbmNvZGVyIHRvIHJlbW92ZS4KKyAqLwordm9pZCBEaWdpdGFsR2xpdGNoRmlsdGVyOjpSZW1vdmUoRW5jb2RlciAqaW5wdXQpIHsKKyAgUmVtb3ZlKGlucHV0LT5tX2FTb3VyY2UuZ2V0KCkpOworICBpZiAoU3RhdHVzSXNGYXRhbCgpKSB7CisgICAgcmV0dXJuOworICB9CisgIFJlbW92ZShpbnB1dC0+bV9iU291cmNlLmdldCgpKTsKK30KKworLyoqCisgKiBSZW1vdmVzIGEgY291bnRlciBmcm9tIHRoaXMgZmlsdGVyLgorICoKKyAqIFJlbW92ZXMgdGhlIENvdW50ZXIgZnJvbSB0aGlzIGdsaXRjaCBmaWx0ZXIgYW5kIHJlLWFzc2lnbnMgaXQgdG8KKyAqIHRoZSBkZWZhdWx0IGZpbHRlci4KKyAqCisgKiBAcGFyYW0gaW5wdXQgVGhlIENvdW50ZXIgdG8gcmVtb3ZlLgorICovCit2b2lkIERpZ2l0YWxHbGl0Y2hGaWx0ZXI6OlJlbW92ZShDb3VudGVyICppbnB1dCkgeworICBSZW1vdmUoaW5wdXQtPm1fdXBTb3VyY2UuZ2V0KCkpOworICBpZiAoU3RhdHVzSXNGYXRhbCgpKSB7CisgICAgcmV0dXJuOworICB9CisgIFJlbW92ZShpbnB1dC0+bV9kb3duU291cmNlLmdldCgpKTsKK30KKworLyoqCisgKiBTZXRzIHRoZSBudW1iZXIgb2YgY3ljbGVzIHRoYXQgdGhlIGlucHV0IG11c3Qgbm90IGNoYW5nZSBzdGF0ZSBmb3IuCisgKgorICogQHBhcmFtIGZwZ2FfY3ljbGVzIFRoZSBudW1iZXIgb2YgRlBHQSBjeWNsZXMuCisgKi8KK3ZvaWQgRGlnaXRhbEdsaXRjaEZpbHRlcjo6U2V0UGVyaW9kQ3ljbGVzKHVpbnQzMl90IGZwZ2FfY3ljbGVzKSB7CisgIGludDMyX3Qgc3RhdHVzID0gMDsKKyAgc2V0RmlsdGVyUGVyaW9kKG1fY2hhbm5lbEluZGV4LCBmcGdhX2N5Y2xlcywgJnN0YXR1cyk7CisgIHdwaV9zZXRFcnJvcldpdGhDb250ZXh0KHN0YXR1cywgZ2V0SEFMRXJyb3JNZXNzYWdlKHN0YXR1cykpOworfQorCisvKioKKyAqIFNldHMgdGhlIG51bWJlciBvZiBuYW5vc2Vjb25kcyB0aGF0IHRoZSBpbnB1dCBtdXN0IG5vdCBjaGFuZ2Ugc3RhdGUgZm9yLgorICoKKyAqIEBwYXJhbSBuYW5vc2Vjb25kcyBUaGUgbnVtYmVyIG9mIG5hbm9zZWNvbmRzLgorICovCit2b2lkIERpZ2l0YWxHbGl0Y2hGaWx0ZXI6OlNldFBlcmlvZE5hbm9TZWNvbmRzKHVpbnQ2NF90IG5hbm9zZWNvbmRzKSB7CisgIGludDMyX3Qgc3RhdHVzID0gMDsKKyAgdWludDMyX3QgZnBnYV9jeWNsZXMgPQorICAgICAgbmFub3NlY29uZHMgKiBrU3lzdGVtQ2xvY2tUaWNrc1Blck1pY3Jvc2Vjb25kIC8gNCAvIDEwMDA7CisgIHNldEZpbHRlclBlcmlvZChtX2NoYW5uZWxJbmRleCwgZnBnYV9jeWNsZXMsICZzdGF0dXMpOworCisgIHdwaV9zZXRFcnJvcldpdGhDb250ZXh0KHN0YXR1cywgZ2V0SEFMRXJyb3JNZXNzYWdlKHN0YXR1cykpOworfQorCisvKioKKyAqIEdldHMgdGhlIG51bWJlciBvZiBjeWNsZXMgdGhhdCB0aGUgaW5wdXQgbXVzdCBub3QgY2hhbmdlIHN0YXRlIGZvci4KKyAqCisgKiBAcmV0dXJuIFRoZSBudW1iZXIgb2YgY3ljbGVzLgorICovCit1aW50MzJfdCBEaWdpdGFsR2xpdGNoRmlsdGVyOjpHZXRQZXJpb2RDeWNsZXMoKSB7CisgIGludDMyX3Qgc3RhdHVzID0gMDsKKyAgdWludDMyX3QgZnBnYV9jeWNsZXMgPSBnZXRGaWx0ZXJQZXJpb2QobV9jaGFubmVsSW5kZXgsICZzdGF0dXMpOworCisgIHdwaV9zZXRFcnJvcldpdGhDb250ZXh0KHN0YXR1cywgZ2V0SEFMRXJyb3JNZXNzYWdlKHN0YXR1cykpOworCisgIHJldHVybiBmcGdhX2N5Y2xlczsKK30KKworLyoqCisgKiBHZXRzIHRoZSBudW1iZXIgb2YgbmFub3NlY29uZHMgdGhhdCB0aGUgaW5wdXQgbXVzdCBub3QgY2hhbmdlIHN0YXRlIGZvci4KKyAqCisgKiBAcmV0dXJuIFRoZSBudW1iZXIgb2YgbmFub3NlY29uZHMuCisgKi8KK3VpbnQ2NF90IERpZ2l0YWxHbGl0Y2hGaWx0ZXI6OkdldFBlcmlvZE5hbm9TZWNvbmRzKCkgeworICBpbnQzMl90IHN0YXR1cyA9IDA7CisgIHVpbnQzMl90IGZwZ2FfY3ljbGVzID0gZ2V0RmlsdGVyUGVyaW9kKG1fY2hhbm5lbEluZGV4LCAmc3RhdHVzKTsKKworICB3cGlfc2V0RXJyb3JXaXRoQ29udGV4dChzdGF0dXMsIGdldEhBTEVycm9yTWVzc2FnZShzdGF0dXMpKTsKKworICByZXR1cm4gc3RhdGljX2Nhc3Q8dWludDY0X3Q+KGZwZ2FfY3ljbGVzKSAqIDEwMDBMIC8KKyAgICAgICAgIHN0YXRpY19jYXN0PHVpbnQ2NF90PihrU3lzdGVtQ2xvY2tUaWNrc1Blck1pY3Jvc2Vjb25kIC8gNCk7Cit9CmRpZmYgLS1naXQgYS93cGlsaWJjL0F0aGVuYS9zcmMvRGlnaXRhbElucHV0LmNwcCBiL3dwaWxpYmMvQXRoZW5hL3NyYy9EaWdpdGFsSW5wdXQuY3BwCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmY2Yjk2ZjUKLS0tIC9kZXYvbnVsbAorKysgYi93cGlsaWJjL0F0aGVuYS9zcmMvRGlnaXRhbElucHV0LmNwcApAQCAtMCwwICsxLDExMCBAQAorLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi8KKy8qIENvcHlyaWdodCAoYykgRklSU1QgMjAwOC4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KKyAqLworLyogT3BlbiBTb3VyY2UgU29mdHdhcmUgLSBtYXkgYmUgbW9kaWZpZWQgYW5kIHNoYXJlZCBieSBGUkMgdGVhbXMuIFRoZSBjb2RlICAgKi8KKy8qIG11c3QgYmUgYWNjb21wYW5pZWQgYnkgdGhlIEZJUlNUIEJTRCBsaWNlbnNlIGZpbGUgaW4gJChXSU5EX0JBU0UpL1dQSUxpYi4gICovCisvKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qLworCisjaW5jbHVkZSAiRGlnaXRhbElucHV0LmgiCisjaW5jbHVkZSAiUmVzb3VyY2UuaCIKKyNpbmNsdWRlICJXUElFcnJvcnMuaCIKKyNpbmNsdWRlICJMaXZlV2luZG93L0xpdmVXaW5kb3cuaCIKKworI2luY2x1ZGUgPGxpbWl0cz4KKyNpbmNsdWRlIDxzc3RyZWFtPgorCisvKioKKyAqIENyZWF0ZSBhbiBpbnN0YW5jZSBvZiBhIERpZ2l0YWwgSW5wdXQgY2xhc3MuCisgKiBDcmVhdGVzIGEgZGlnaXRhbCBpbnB1dCBnaXZlbiBhIGNoYW5uZWwuCisgKgorICogQHBhcmFtIGNoYW5uZWwgVGhlIERJTyBjaGFubmVsIDAtOSBhcmUgb24tYm9hcmQsIDEwLTI1IGFyZSBvbiB0aGUgTVhQIHBvcnQKKyAqLworRGlnaXRhbElucHV0OjpEaWdpdGFsSW5wdXQodWludDMyX3QgY2hhbm5lbCkgeworICBzdGQ6OnN0cmluZ3N0cmVhbSBidWY7CisKKyAgaWYgKCFDaGVja0RpZ2l0YWxDaGFubmVsKGNoYW5uZWwpKSB7CisgICAgYnVmIDw8ICJEaWdpdGFsIENoYW5uZWwgIiA8PCBjaGFubmVsOworICAgIHdwaV9zZXRXUElFcnJvcldpdGhDb250ZXh0KENoYW5uZWxJbmRleE91dE9mUmFuZ2UsIGJ1Zi5zdHIoKSk7CisgICAgbV9jaGFubmVsID0gc3RkOjpudW1lcmljX2xpbWl0czx1aW50MzJfdD46Om1heCgpOworICAgIHJldHVybjsKKyAgfQorICBtX2NoYW5uZWwgPSBjaGFubmVsOworCisgIGludDMyX3Qgc3RhdHVzID0gMDsKKyAgYWxsb2NhdGVESU8obV9kaWdpdGFsX3BvcnRzW2NoYW5uZWxdLCB0cnVlLCAmc3RhdHVzKTsKKyAgd3BpX3NldEVycm9yV2l0aENvbnRleHQoc3RhdHVzLCBnZXRIQUxFcnJvck1lc3NhZ2Uoc3RhdHVzKSk7CisKKyAgTGl2ZVdpbmRvdzo6R2V0SW5zdGFuY2UoKS0+QWRkU2Vuc29yKCJEaWdpdGFsSW5wdXQiLCBjaGFubmVsLCB0aGlzKTsKKyAgSEFMUmVwb3J0KEhBTFVzYWdlUmVwb3J0aW5nOjprUmVzb3VyY2VUeXBlX0RpZ2l0YWxJbnB1dCwgY2hhbm5lbCk7Cit9CisKKy8qKgorICogRnJlZSByZXNvdXJjZXMgYXNzb2NpYXRlZCB3aXRoIHRoZSBEaWdpdGFsIElucHV0IGNsYXNzLgorICovCitEaWdpdGFsSW5wdXQ6On5EaWdpdGFsSW5wdXQoKSB7CisgIGlmIChTdGF0dXNJc0ZhdGFsKCkpIHJldHVybjsKKyAgaWYgKG1faW50ZXJydXB0ICE9IG51bGxwdHIpIHsKKyAgICBpbnQzMl90IHN0YXR1cyA9IDA7CisgICAgY2xlYW5JbnRlcnJ1cHRzKG1faW50ZXJydXB0LCAmc3RhdHVzKTsKKyAgICB3cGlfc2V0RXJyb3JXaXRoQ29udGV4dChzdGF0dXMsIGdldEhBTEVycm9yTWVzc2FnZShzdGF0dXMpKTsKKyAgICBtX2ludGVycnVwdCA9IG51bGxwdHI7CisgICAgbV9pbnRlcnJ1cHRzLT5GcmVlKG1faW50ZXJydXB0SW5kZXgpOworICB9CisKKyAgaW50MzJfdCBzdGF0dXMgPSAwOworICBmcmVlRElPKG1fZGlnaXRhbF9wb3J0c1ttX2NoYW5uZWxdLCAmc3RhdHVzKTsKKyAgd3BpX3NldEVycm9yV2l0aENvbnRleHQoc3RhdHVzLCBnZXRIQUxFcnJvck1lc3NhZ2Uoc3RhdHVzKSk7Cit9CisKKy8qKgorICogR2V0IHRoZSB2YWx1ZSBmcm9tIGEgZGlnaXRhbCBpbnB1dCBjaGFubmVsLgorICogUmV0cmlldmUgdGhlIHZhbHVlIG9mIGEgc2luZ2xlIGRpZ2l0YWwgaW5wdXQgY2hhbm5lbCBmcm9tIHRoZSBGUEdBLgorICovCitib29sIERpZ2l0YWxJbnB1dDo6R2V0KCkgY29uc3QgeworICBpZiAoU3RhdHVzSXNGYXRhbCgpKSByZXR1cm4gZmFsc2U7CisgIGludDMyX3Qgc3RhdHVzID0gMDsKKyAgYm9vbCB2YWx1ZSA9IGdldERJTyhtX2RpZ2l0YWxfcG9ydHNbbV9jaGFubmVsXSwgJnN0YXR1cyk7CisgIHdwaV9zZXRFcnJvcldpdGhDb250ZXh0KHN0YXR1cywgZ2V0SEFMRXJyb3JNZXNzYWdlKHN0YXR1cykpOworICByZXR1cm4gdmFsdWU7Cit9CisKKy8qKgorICogQHJldHVybiBUaGUgR1BJTyBjaGFubmVsIG51bWJlciB0aGF0IHRoaXMgb2JqZWN0IHJlcHJlc2VudHMuCisgKi8KK3VpbnQzMl90IERpZ2l0YWxJbnB1dDo6R2V0Q2hhbm5lbCgpIGNvbnN0IHsgcmV0dXJuIG1fY2hhbm5lbDsgfQorCisvKioKKyAqIEByZXR1cm4gVGhlIHZhbHVlIHRvIGJlIHdyaXR0ZW4gdG8gdGhlIGNoYW5uZWwgZmllbGQgb2YgYSByb3V0aW5nIG11eC4KKyAqLwordWludDMyX3QgRGlnaXRhbElucHV0OjpHZXRDaGFubmVsRm9yUm91dGluZygpIGNvbnN0IHsgcmV0dXJuIEdldENoYW5uZWwoKTsgfQorCisvKioKKyAqIEByZXR1cm4gVGhlIHZhbHVlIHRvIGJlIHdyaXR0ZW4gdG8gdGhlIG1vZHVsZSBmaWVsZCBvZiBhIHJvdXRpbmcgbXV4LgorICovCit1aW50MzJfdCBEaWdpdGFsSW5wdXQ6OkdldE1vZHVsZUZvclJvdXRpbmcoKSBjb25zdCB7IHJldHVybiAwOyB9CisKKy8qKgorICogQHJldHVybiBUaGUgdmFsdWUgdG8gYmUgd3JpdHRlbiB0byB0aGUgYW5hbG9nIHRyaWdnZXIgZmllbGQgb2YgYSByb3V0aW5nIG11eC4KKyAqLworYm9vbCBEaWdpdGFsSW5wdXQ6OkdldEFuYWxvZ1RyaWdnZXJGb3JSb3V0aW5nKCkgY29uc3QgeyByZXR1cm4gZmFsc2U7IH0KKwordm9pZCBEaWdpdGFsSW5wdXQ6OlVwZGF0ZVRhYmxlKCkgeworICBpZiAobV90YWJsZSAhPSBudWxscHRyKSB7CisgICAgbV90YWJsZS0+UHV0Qm9vbGVhbigiVmFsdWUiLCBHZXQoKSk7CisgIH0KK30KKwordm9pZCBEaWdpdGFsSW5wdXQ6OlN0YXJ0TGl2ZVdpbmRvd01vZGUoKSB7fQorCit2b2lkIERpZ2l0YWxJbnB1dDo6U3RvcExpdmVXaW5kb3dNb2RlKCkge30KKworc3RkOjpzdHJpbmcgRGlnaXRhbElucHV0OjpHZXRTbWFydERhc2hib2FyZFR5cGUoKSBjb25zdCB7CisgIHJldHVybiAiRGlnaXRhbElucHV0IjsKK30KKwordm9pZCBEaWdpdGFsSW5wdXQ6OkluaXRUYWJsZShzdGQ6OnNoYXJlZF9wdHI8SVRhYmxlPiBzdWJUYWJsZSkgeworICBtX3RhYmxlID0gc3ViVGFibGU7CisgIFVwZGF0ZVRhYmxlKCk7Cit9CisKK3N0ZDo6c2hhcmVkX3B0cjxJVGFibGU+IERpZ2l0YWxJbnB1dDo6R2V0VGFibGUoKSBjb25zdCB7IHJldHVybiBtX3RhYmxlOyB9CmRpZmYgLS1naXQgYS93cGlsaWJjL0F0aGVuYS9zcmMvRGlnaXRhbE91dHB1dC5jcHAgYi93cGlsaWJjL0F0aGVuYS9zcmMvRGlnaXRhbE91dHB1dC5jcHAKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZDc0ZjkzYgotLS0gL2Rldi9udWxsCisrKyBiL3dwaWxpYmMvQXRoZW5hL3NyYy9EaWdpdGFsT3V0cHV0LmNwcApAQCAtMCwwICsxLDIzMCBAQAorLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi8KKy8qIENvcHlyaWdodCAoYykgRklSU1QgMjAwOC4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICovCisvKiBPcGVuIFNvdXJjZSBTb2Z0d2FyZSAtIG1heSBiZSBtb2RpZmllZCBhbmQgc2hhcmVkIGJ5IEZSQyB0ZWFtcy4gVGhlIGNvZGUgICAqLworLyogbXVzdCBiZSBhY2NvbXBhbmllZCBieSB0aGUgRklSU1QgQlNEIGxpY2Vuc2UgZmlsZSBpbiAkKFdJTkRfQkFTRSkvV1BJTGliLiAgKi8KKy8qLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovCisKKyNpbmNsdWRlICJEaWdpdGFsT3V0cHV0LmgiCisjaW5jbHVkZSAiUmVzb3VyY2UuaCIKKyNpbmNsdWRlICJXUElFcnJvcnMuaCIKKworI2luY2x1ZGUgPGxpbWl0cz4KKyNpbmNsdWRlIDxzc3RyZWFtPgorCisvKioKKyAqIENyZWF0ZSBhbiBpbnN0YW5jZSBvZiBhIGRpZ2l0YWwgb3V0cHV0LgorICogQ3JlYXRlIGEgZGlnaXRhbCBvdXRwdXQgZ2l2ZW4gYSBjaGFubmVsLgorICoKKyAqIEBwYXJhbSBjaGFubmVsIFRoZSBkaWdpdGFsIGNoYW5uZWwgMC05IGFyZSBvbi1ib2FyZCwgMTAtMjUgYXJlIG9uIHRoZSBNWFAKKyAqIHBvcnQKKyAqLworRGlnaXRhbE91dHB1dDo6RGlnaXRhbE91dHB1dCh1aW50MzJfdCBjaGFubmVsKSB7CisgIHN0ZDo6c3RyaW5nc3RyZWFtIGJ1ZjsKKworICBtX3B3bUdlbmVyYXRvciA9ICh2b2lkICopc3RkOjpudW1lcmljX2xpbWl0czx1aW50MzJfdD46Om1heCgpOworICBpZiAoIUNoZWNrRGlnaXRhbENoYW5uZWwoY2hhbm5lbCkpIHsKKyAgICBidWYgPDwgIkRpZ2l0YWwgQ2hhbm5lbCAiIDw8IGNoYW5uZWw7CisgICAgd3BpX3NldFdQSUVycm9yV2l0aENvbnRleHQoQ2hhbm5lbEluZGV4T3V0T2ZSYW5nZSwgYnVmLnN0cigpKTsKKyAgICBtX2NoYW5uZWwgPSBzdGQ6Om51bWVyaWNfbGltaXRzPHVpbnQzMl90Pjo6bWF4KCk7CisgICAgcmV0dXJuOworICB9CisgIG1fY2hhbm5lbCA9IGNoYW5uZWw7CisKKyAgaW50MzJfdCBzdGF0dXMgPSAwOworICBhbGxvY2F0ZURJTyhtX2RpZ2l0YWxfcG9ydHNbY2hhbm5lbF0sIGZhbHNlLCAmc3RhdHVzKTsKKyAgd3BpX3NldEVycm9yV2l0aENvbnRleHQoc3RhdHVzLCBnZXRIQUxFcnJvck1lc3NhZ2Uoc3RhdHVzKSk7CisKKyAgSEFMUmVwb3J0KEhBTFVzYWdlUmVwb3J0aW5nOjprUmVzb3VyY2VUeXBlX0RpZ2l0YWxPdXRwdXQsIGNoYW5uZWwpOworfQorCisvKioKKyAqIEZyZWUgdGhlIHJlc291cmNlcyBhc3NvY2lhdGVkIHdpdGggYSBkaWdpdGFsIG91dHB1dC4KKyAqLworRGlnaXRhbE91dHB1dDo6fkRpZ2l0YWxPdXRwdXQoKSB7CisgIGlmIChtX3RhYmxlICE9IG51bGxwdHIpIG1fdGFibGUtPlJlbW92ZVRhYmxlTGlzdGVuZXIodGhpcyk7CisgIGlmIChTdGF0dXNJc0ZhdGFsKCkpIHJldHVybjsKKyAgLy8gRGlzYWJsZSB0aGUgUFdNIGluIGNhc2UgaXQgd2FzIHJ1bm5pbmcuCisgIERpc2FibGVQV00oKTsKKworICBpbnQzMl90IHN0YXR1cyA9IDA7CisgIGZyZWVESU8obV9kaWdpdGFsX3BvcnRzW21fY2hhbm5lbF0sICZzdGF0dXMpOworICB3cGlfc2V0RXJyb3JXaXRoQ29udGV4dChzdGF0dXMsIGdldEhBTEVycm9yTWVzc2FnZShzdGF0dXMpKTsKK30KKworLyoqCisgKiBTZXQgdGhlIHZhbHVlIG9mIGEgZGlnaXRhbCBvdXRwdXQuCisgKiBTZXQgdGhlIHZhbHVlIG9mIGEgZGlnaXRhbCBvdXRwdXQgdG8gZWl0aGVyIG9uZSAodHJ1ZSkgb3IgemVybyAoZmFsc2UpLgorICogQHBhcmFtIHZhbHVlIDEgKHRydWUpIGZvciBoaWdoLCAwIChmYWxzZSkgZm9yIGRpc2FibGVkCisgKi8KK3ZvaWQgRGlnaXRhbE91dHB1dDo6U2V0KHVpbnQzMl90IHZhbHVlKSB7CisgIGlmIChTdGF0dXNJc0ZhdGFsKCkpIHJldHVybjsKKworICBpbnQzMl90IHN0YXR1cyA9IDA7CisgIHNldERJTyhtX2RpZ2l0YWxfcG9ydHNbbV9jaGFubmVsXSwgdmFsdWUsICZzdGF0dXMpOworICB3cGlfc2V0RXJyb3JXaXRoQ29udGV4dChzdGF0dXMsIGdldEhBTEVycm9yTWVzc2FnZShzdGF0dXMpKTsKK30KKworLyoqCisgKiBAcmV0dXJuIFRoZSBHUElPIGNoYW5uZWwgbnVtYmVyIHRoYXQgdGhpcyBvYmplY3QgcmVwcmVzZW50cy4KKyAqLwordWludDMyX3QgRGlnaXRhbE91dHB1dDo6R2V0Q2hhbm5lbCgpIGNvbnN0IHsgcmV0dXJuIG1fY2hhbm5lbDsgfQorCisvKioKKyAqIE91dHB1dCBhIHNpbmdsZSBwdWxzZSBvbiB0aGUgZGlnaXRhbCBvdXRwdXQgbGluZS4KKyAqIFNlbmQgYSBzaW5nbGUgcHVsc2Ugb24gdGhlIGRpZ2l0YWwgb3V0cHV0IGxpbmUgd2hlcmUgdGhlIHB1bHNlIGR1cmF0aW9uIGlzCisgKiBzcGVjaWZpZWQgaW4gc2Vjb25kcy4KKyAqIE1heGltdW0gcHVsc2UgbGVuZ3RoIGlzIDAuMDAxNiBzZWNvbmRzLgorICogQHBhcmFtIGxlbmd0aCBUaGUgcHVsc2VsZW5ndGggaW4gc2Vjb25kcworICovCit2b2lkIERpZ2l0YWxPdXRwdXQ6OlB1bHNlKGZsb2F0IGxlbmd0aCkgeworICBpZiAoU3RhdHVzSXNGYXRhbCgpKSByZXR1cm47CisKKyAgaW50MzJfdCBzdGF0dXMgPSAwOworICBwdWxzZShtX2RpZ2l0YWxfcG9ydHNbbV9jaGFubmVsXSwgbGVuZ3RoLCAmc3RhdHVzKTsKKyAgd3BpX3NldEVycm9yV2l0aENvbnRleHQoc3RhdHVzLCBnZXRIQUxFcnJvck1lc3NhZ2Uoc3RhdHVzKSk7Cit9CisKKy8qKgorICogRGV0ZXJtaW5lIGlmIHRoZSBwdWxzZSBpcyBzdGlsbCBnb2luZy4KKyAqIERldGVybWluZSBpZiBhIHByZXZpb3VzbHkgc3RhcnRlZCBwdWxzZSBpcyBzdGlsbCBnb2luZy4KKyAqLworYm9vbCBEaWdpdGFsT3V0cHV0OjpJc1B1bHNpbmcoKSBjb25zdCB7CisgIGlmIChTdGF0dXNJc0ZhdGFsKCkpIHJldHVybiBmYWxzZTsKKworICBpbnQzMl90IHN0YXR1cyA9IDA7CisgIGJvb2wgdmFsdWUgPSBpc1B1bHNpbmcobV9kaWdpdGFsX3BvcnRzW21fY2hhbm5lbF0sICZzdGF0dXMpOworICB3cGlfc2V0RXJyb3JXaXRoQ29udGV4dChzdGF0dXMsIGdldEhBTEVycm9yTWVzc2FnZShzdGF0dXMpKTsKKyAgcmV0dXJuIHZhbHVlOworfQorCisvKioKKyAqIENoYW5nZSB0aGUgUFdNIGZyZXF1ZW5jeSBvZiB0aGUgUFdNIG91dHB1dCBvbiBhIERpZ2l0YWwgT3V0cHV0IGxpbmUuCisgKgorICogVGhlIHZhbGlkIHJhbmdlIGlzIGZyb20gMC42IEh6IHRvIDE5IGtIei4gIFRoZSBmcmVxdWVuY3kgcmVzb2x1dGlvbiBpcworICogbG9nYXJpdGhtaWMuCisgKgorICogVGhlcmUgaXMgb25seSBvbmUgUFdNIGZyZXF1ZW5jeSBmb3IgYWxsIGRpZ2l0YWwgY2hhbm5lbHMuCisgKgorICogQHBhcmFtIHJhdGUgVGhlIGZyZXF1ZW5jeSB0byBvdXRwdXQgYWxsIGRpZ2l0YWwgb3V0cHV0IFBXTSBzaWduYWxzLgorICovCit2b2lkIERpZ2l0YWxPdXRwdXQ6OlNldFBXTVJhdGUoZmxvYXQgcmF0ZSkgeworICBpZiAoU3RhdHVzSXNGYXRhbCgpKSByZXR1cm47CisKKyAgaW50MzJfdCBzdGF0dXMgPSAwOworICBzZXRQV01SYXRlKHJhdGUsICZzdGF0dXMpOworICB3cGlfc2V0RXJyb3JXaXRoQ29udGV4dChzdGF0dXMsIGdldEhBTEVycm9yTWVzc2FnZShzdGF0dXMpKTsKK30KKworLyoqCisgKiBFbmFibGUgYSBQV00gT3V0cHV0IG9uIHRoaXMgbGluZS4KKyAqCisgKiBBbGxvY2F0ZSBvbmUgb2YgdGhlIDYgRE8gUFdNIGdlbmVyYXRvciByZXNvdXJjZXMgZnJvbSB0aGlzIG1vZHVsZS4KKyAqCisgKiBTdXBwbHkgdGhlIGluaXRpYWwgZHV0eS1jeWNsZSB0byBvdXRwdXQgc28gYXMgdG8gYXZvaWQgYSBnbGl0Y2ggd2hlbiBmaXJzdAorICogc3RhcnRpbmcuCisgKgorICogVGhlIHJlc29sdXRpb24gb2YgdGhlIGR1dHkgY3ljbGUgaXMgOC1iaXQgZm9yIGxvdyBmcmVxdWVuY2llcyAoMWtIeiBvciBsZXNzKQorICogYnV0IGlzIHJlZHVjZWQgdGhlIGhpZ2hlciB0aGUgZnJlcXVlbmN5IG9mIHRoZSBQV00gc2lnbmFsIGlzLgorICoKKyAqIEBwYXJhbSBpbml0aWFsRHV0eUN5Y2xlIFRoZSBkdXR5LWN5Y2xlIHRvIHN0YXJ0IGdlbmVyYXRpbmcuIFswLi4xXQorICovCit2b2lkIERpZ2l0YWxPdXRwdXQ6OkVuYWJsZVBXTShmbG9hdCBpbml0aWFsRHV0eUN5Y2xlKSB7CisgIGlmIChtX3B3bUdlbmVyYXRvciAhPSAodm9pZCAqKXN0ZDo6bnVtZXJpY19saW1pdHM8dWludDMyX3Q+OjptYXgoKSkgcmV0dXJuOworCisgIGludDMyX3Qgc3RhdHVzID0gMDsKKworICBpZiAoU3RhdHVzSXNGYXRhbCgpKSByZXR1cm47CisgIG1fcHdtR2VuZXJhdG9yID0gYWxsb2NhdGVQV00oJnN0YXR1cyk7CisgIHdwaV9zZXRFcnJvcldpdGhDb250ZXh0KHN0YXR1cywgZ2V0SEFMRXJyb3JNZXNzYWdlKHN0YXR1cykpOworCisgIGlmIChTdGF0dXNJc0ZhdGFsKCkpIHJldHVybjsKKyAgc2V0UFdNRHV0eUN5Y2xlKG1fcHdtR2VuZXJhdG9yLCBpbml0aWFsRHV0eUN5Y2xlLCAmc3RhdHVzKTsKKyAgd3BpX3NldEVycm9yV2l0aENvbnRleHQoc3RhdHVzLCBnZXRIQUxFcnJvck1lc3NhZ2Uoc3RhdHVzKSk7CisKKyAgaWYgKFN0YXR1c0lzRmF0YWwoKSkgcmV0dXJuOworICBzZXRQV01PdXRwdXRDaGFubmVsKG1fcHdtR2VuZXJhdG9yLCBtX2NoYW5uZWwsICZzdGF0dXMpOworICB3cGlfc2V0RXJyb3JXaXRoQ29udGV4dChzdGF0dXMsIGdldEhBTEVycm9yTWVzc2FnZShzdGF0dXMpKTsKK30KKworLyoqCisgKiBDaGFuZ2UgdGhpcyBsaW5lIGZyb20gYSBQV00gb3V0cHV0IGJhY2sgdG8gYSBzdGF0aWMgRGlnaXRhbCBPdXRwdXQgbGluZS4KKyAqCisgKiBGcmVlIHVwIG9uZSBvZiB0aGUgNiBETyBQV00gZ2VuZXJhdG9yIHJlc291cmNlcyB0aGF0IHdlcmUgaW4gdXNlLgorICovCit2b2lkIERpZ2l0YWxPdXRwdXQ6OkRpc2FibGVQV00oKSB7CisgIGlmIChTdGF0dXNJc0ZhdGFsKCkpIHJldHVybjsKKyAgaWYgKG1fcHdtR2VuZXJhdG9yID09ICh2b2lkICopc3RkOjpudW1lcmljX2xpbWl0czx1aW50MzJfdD46Om1heCgpKSByZXR1cm47CisKKyAgaW50MzJfdCBzdGF0dXMgPSAwOworCisgIC8vIERpc2FibGUgdGhlIG91dHB1dCBieSByb3V0aW5nIHRvIGEgZGVhZCBiaXQuCisgIHNldFBXTU91dHB1dENoYW5uZWwobV9wd21HZW5lcmF0b3IsIGtEaWdpdGFsQ2hhbm5lbHMsICZzdGF0dXMpOworICB3cGlfc2V0RXJyb3JXaXRoQ29udGV4dChzdGF0dXMsIGdldEhBTEVycm9yTWVzc2FnZShzdGF0dXMpKTsKKworICBmcmVlUFdNKG1fcHdtR2VuZXJhdG9yLCAmc3RhdHVzKTsKKyAgd3BpX3NldEVycm9yV2l0aENvbnRleHQoc3RhdHVzLCBnZXRIQUxFcnJvck1lc3NhZ2Uoc3RhdHVzKSk7CisKKyAgbV9wd21HZW5lcmF0b3IgPSAodm9pZCAqKXN0ZDo6bnVtZXJpY19saW1pdHM8dWludDMyX3Q+OjptYXgoKTsKK30KKworLyoqCisgKiBDaGFuZ2UgdGhlIGR1dHktY3ljbGUgdGhhdCBpcyBiZWluZyBnZW5lcmF0ZWQgb24gdGhlIGxpbmUuCisgKgorICogVGhlIHJlc29sdXRpb24gb2YgdGhlIGR1dHkgY3ljbGUgaXMgOC1iaXQgZm9yIGxvdyBmcmVxdWVuY2llcyAoMWtIeiBvciBsZXNzKQorICogYnV0IGlzIHJlZHVjZWQgdGhlIGhpZ2hlciB0aGUgZnJlcXVlbmN5IG9mIHRoZSBQV00gc2lnbmFsIGlzLgorICoKKyAqIEBwYXJhbSBkdXR5Q3ljbGUgVGhlIGR1dHktY3ljbGUgdG8gY2hhbmdlIHRvLiBbMC4uMV0KKyAqLwordm9pZCBEaWdpdGFsT3V0cHV0OjpVcGRhdGVEdXR5Q3ljbGUoZmxvYXQgZHV0eUN5Y2xlKSB7CisgIGlmIChTdGF0dXNJc0ZhdGFsKCkpIHJldHVybjsKKworICBpbnQzMl90IHN0YXR1cyA9IDA7CisgIHNldFBXTUR1dHlDeWNsZShtX3B3bUdlbmVyYXRvciwgZHV0eUN5Y2xlLCAmc3RhdHVzKTsKKyAgd3BpX3NldEVycm9yV2l0aENvbnRleHQoc3RhdHVzLCBnZXRIQUxFcnJvck1lc3NhZ2Uoc3RhdHVzKSk7Cit9CisKKy8qKgorICogQHJldHVybiBUaGUgdmFsdWUgdG8gYmUgd3JpdHRlbiB0byB0aGUgY2hhbm5lbCBmaWVsZCBvZiBhIHJvdXRpbmcgbXV4LgorICovCit1aW50MzJfdCBEaWdpdGFsT3V0cHV0OjpHZXRDaGFubmVsRm9yUm91dGluZygpIGNvbnN0IHsgcmV0dXJuIEdldENoYW5uZWwoKTsgfQorCisvKioKKyAqIEByZXR1cm4gVGhlIHZhbHVlIHRvIGJlIHdyaXR0ZW4gdG8gdGhlIG1vZHVsZSBmaWVsZCBvZiBhIHJvdXRpbmcgbXV4LgorICovCit1aW50MzJfdCBEaWdpdGFsT3V0cHV0OjpHZXRNb2R1bGVGb3JSb3V0aW5nKCkgY29uc3QgeyByZXR1cm4gMDsgfQorCisvKioKKyAqIEByZXR1cm4gVGhlIHZhbHVlIHRvIGJlIHdyaXR0ZW4gdG8gdGhlIGFuYWxvZyB0cmlnZ2VyIGZpZWxkIG9mIGEgcm91dGluZyBtdXguCisgKi8KK2Jvb2wgRGlnaXRhbE91dHB1dDo6R2V0QW5hbG9nVHJpZ2dlckZvclJvdXRpbmcoKSBjb25zdCB7IHJldHVybiBmYWxzZTsgfQorCit2b2lkIERpZ2l0YWxPdXRwdXQ6OlZhbHVlQ2hhbmdlZChJVGFibGUqIHNvdXJjZSwgbGx2bTo6U3RyaW5nUmVmIGtleSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0ZDo6c2hhcmVkX3B0cjxudDo6VmFsdWU+IHZhbHVlLCBib29sIGlzTmV3KSB7CisgIGlmICghdmFsdWUtPklzQm9vbGVhbigpKSByZXR1cm47CisgIFNldCh2YWx1ZS0+R2V0Qm9vbGVhbigpKTsKK30KKwordm9pZCBEaWdpdGFsT3V0cHV0OjpVcGRhdGVUYWJsZSgpIHt9CisKK3ZvaWQgRGlnaXRhbE91dHB1dDo6U3RhcnRMaXZlV2luZG93TW9kZSgpIHsKKyAgaWYgKG1fdGFibGUgIT0gbnVsbHB0cikgeworICAgIG1fdGFibGUtPkFkZFRhYmxlTGlzdGVuZXIoIlZhbHVlIiwgdGhpcywgdHJ1ZSk7CisgIH0KK30KKwordm9pZCBEaWdpdGFsT3V0cHV0OjpTdG9wTGl2ZVdpbmRvd01vZGUoKSB7CisgIGlmIChtX3RhYmxlICE9IG51bGxwdHIpIHsKKyAgICBtX3RhYmxlLT5SZW1vdmVUYWJsZUxpc3RlbmVyKHRoaXMpOworICB9Cit9CisKK3N0ZDo6c3RyaW5nIERpZ2l0YWxPdXRwdXQ6OkdldFNtYXJ0RGFzaGJvYXJkVHlwZSgpIGNvbnN0IHsKKyAgcmV0dXJuICJEaWdpdGFsIE91dHB1dCI7Cit9CisKK3ZvaWQgRGlnaXRhbE91dHB1dDo6SW5pdFRhYmxlKHN0ZDo6c2hhcmVkX3B0cjxJVGFibGU+IHN1YlRhYmxlKSB7CisgIG1fdGFibGUgPSBzdWJUYWJsZTsKKyAgVXBkYXRlVGFibGUoKTsKK30KKworc3RkOjpzaGFyZWRfcHRyPElUYWJsZT4gRGlnaXRhbE91dHB1dDo6R2V0VGFibGUoKSBjb25zdCB7IHJldHVybiBtX3RhYmxlOyB9CmRpZmYgLS1naXQgYS93cGlsaWJjL0F0aGVuYS9zcmMvRG91YmxlU29sZW5vaWQuY3BwIGIvd3BpbGliYy9BdGhlbmEvc3JjL0RvdWJsZVNvbGVub2lkLmNwcApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi40ZmIyOTQzCi0tLSAvZGV2L251bGwKKysrIGIvd3BpbGliYy9BdGhlbmEvc3JjL0RvdWJsZVNvbGVub2lkLmNwcApAQCAtMCwwICsxLDE5NyBAQAorLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi8KKy8qIENvcHlyaWdodCAoYykgRklSU1QgMjAwOC4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICovCisvKiBPcGVuIFNvdXJjZSBTb2Z0d2FyZSAtIG1heSBiZSBtb2RpZmllZCBhbmQgc2hhcmVkIGJ5IEZSQyB0ZWFtcy4gVGhlIGNvZGUgICAqLworLyogbXVzdCBiZSBhY2NvbXBhbmllZCBieSB0aGUgRklSU1QgQlNEIGxpY2Vuc2UgZmlsZSBpbiAkKFdJTkRfQkFTRSkvV1BJTGliLiAgKi8KKy8qLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovCisKKyNpbmNsdWRlICJEb3VibGVTb2xlbm9pZC5oIgorI2luY2x1ZGUgIldQSUVycm9ycy5oIgorI2luY2x1ZGUgIkxpdmVXaW5kb3cvTGl2ZVdpbmRvdy5oIgorCisjaW5jbHVkZSA8c3N0cmVhbT4KKworLyoqCisgKiBDb25zdHJ1Y3Rvci4KKyAqIFVzZXMgdGhlIGRlZmF1bHQgUENNIElEIG9mIDAKKyAqIEBwYXJhbSBmb3J3YXJkQ2hhbm5lbCBUaGUgZm9yd2FyZCBjaGFubmVsIG51bWJlciBvbiB0aGUgUENNICgwLi43KS4KKyAqIEBwYXJhbSByZXZlcnNlQ2hhbm5lbCBUaGUgcmV2ZXJzZSBjaGFubmVsIG51bWJlciBvbiB0aGUgUENNICgwLi43KS4KKyAqLworRG91YmxlU29sZW5vaWQ6OkRvdWJsZVNvbGVub2lkKHVpbnQzMl90IGZvcndhcmRDaGFubmVsLCB1aW50MzJfdCByZXZlcnNlQ2hhbm5lbCkKKyAgICA6IERvdWJsZVNvbGVub2lkKEdldERlZmF1bHRTb2xlbm9pZE1vZHVsZSgpLCBmb3J3YXJkQ2hhbm5lbCwgcmV2ZXJzZUNoYW5uZWwpIHt9CisKKy8qKgorICogQ29uc3RydWN0b3IuCisgKgorICogQHBhcmFtIG1vZHVsZU51bWJlciBUaGUgQ0FOIElEIG9mIHRoZSBQQ00uCisgKiBAcGFyYW0gZm9yd2FyZENoYW5uZWwgVGhlIGZvcndhcmQgY2hhbm5lbCBvbiB0aGUgUENNIHRvIGNvbnRyb2wgKDAuLjcpLgorICogQHBhcmFtIHJldmVyc2VDaGFubmVsIFRoZSByZXZlcnNlIGNoYW5uZWwgb24gdGhlIFBDTSB0byBjb250cm9sICgwLi43KS4KKyAqLworRG91YmxlU29sZW5vaWQ6OkRvdWJsZVNvbGVub2lkKHVpbnQ4X3QgbW9kdWxlTnVtYmVyLCB1aW50MzJfdCBmb3J3YXJkQ2hhbm5lbCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB1aW50MzJfdCByZXZlcnNlQ2hhbm5lbCkKKyAgICA6IFNvbGVub2lkQmFzZShtb2R1bGVOdW1iZXIpLAorICAgICAgbV9mb3J3YXJkQ2hhbm5lbChmb3J3YXJkQ2hhbm5lbCksCisgICAgICBtX3JldmVyc2VDaGFubmVsKHJldmVyc2VDaGFubmVsKSB7CisgIHN0ZDo6c3RyaW5nc3RyZWFtIGJ1ZjsKKyAgaWYgKCFDaGVja1NvbGVub2lkTW9kdWxlKG1fbW9kdWxlTnVtYmVyKSkgeworICAgIGJ1ZiA8PCAiU29sZW5vaWQgTW9kdWxlICIgPDwgbV9tb2R1bGVOdW1iZXI7CisgICAgd3BpX3NldFdQSUVycm9yV2l0aENvbnRleHQoTW9kdWxlSW5kZXhPdXRPZlJhbmdlLCBidWYuc3RyKCkpOworICAgIHJldHVybjsKKyAgfQorICBpZiAoIUNoZWNrU29sZW5vaWRDaGFubmVsKG1fZm9yd2FyZENoYW5uZWwpKSB7CisgICAgYnVmIDw8ICJTb2xlbm9pZCBNb2R1bGUgIiA8PCBtX2ZvcndhcmRDaGFubmVsOworICAgIHdwaV9zZXRXUElFcnJvcldpdGhDb250ZXh0KENoYW5uZWxJbmRleE91dE9mUmFuZ2UsIGJ1Zi5zdHIoKSk7CisgICAgcmV0dXJuOworICB9CisgIGlmICghQ2hlY2tTb2xlbm9pZENoYW5uZWwobV9yZXZlcnNlQ2hhbm5lbCkpIHsKKyAgICBidWYgPDwgIlNvbGVub2lkIE1vZHVsZSAiIDw8IG1fcmV2ZXJzZUNoYW5uZWw7CisgICAgd3BpX3NldFdQSUVycm9yV2l0aENvbnRleHQoQ2hhbm5lbEluZGV4T3V0T2ZSYW5nZSwgYnVmLnN0cigpKTsKKyAgICByZXR1cm47CisgIH0KKyAgUmVzb3VyY2U6OkNyZWF0ZVJlc291cmNlT2JqZWN0KAorICAgICAgbV9hbGxvY2F0ZWQsIG1fbWF4TW9kdWxlcyAqIG1fbWF4UG9ydHMpOworCisgIGJ1ZiA8PCAiU29sZW5vaWQgIiA8PCBtX2ZvcndhcmRDaGFubmVsIDw8ICIgKE1vZHVsZTogIiA8PCBtX21vZHVsZU51bWJlcgorICAgICAgPDwgIikiOworICBpZiAobV9hbGxvY2F0ZWQtPkFsbG9jYXRlKAorICAgICAgICAgIG1fbW9kdWxlTnVtYmVyICoga1NvbGVub2lkQ2hhbm5lbHMgKyBtX2ZvcndhcmRDaGFubmVsLCBidWYuc3RyKCkpID09CisgICAgICBzdGQ6Om51bWVyaWNfbGltaXRzPHVpbnQzMl90Pjo6bWF4KCkpIHsKKyAgICBDbG9uZUVycm9yKCptX2FsbG9jYXRlZCk7CisgICAgcmV0dXJuOworICB9CisKKyAgYnVmIDw8ICJTb2xlbm9pZCAiIDw8IG1fcmV2ZXJzZUNoYW5uZWwgPDwgIiAoTW9kdWxlOiAiIDw8IG1fbW9kdWxlTnVtYmVyCisgICAgICA8PCAiKSI7CisgIGlmIChtX2FsbG9jYXRlZC0+QWxsb2NhdGUoCisgICAgICAgICAgbV9tb2R1bGVOdW1iZXIgKiBrU29sZW5vaWRDaGFubmVscyArIG1fcmV2ZXJzZUNoYW5uZWwsIGJ1Zi5zdHIoKSkgPT0KKyAgICAgIHN0ZDo6bnVtZXJpY19saW1pdHM8dWludDMyX3Q+OjptYXgoKSkgeworICAgIENsb25lRXJyb3IoKm1fYWxsb2NhdGVkKTsKKyAgICByZXR1cm47CisgIH0KKworICBtX2ZvcndhcmRNYXNrID0gMSA8PCBtX2ZvcndhcmRDaGFubmVsOworICBtX3JldmVyc2VNYXNrID0gMSA8PCBtX3JldmVyc2VDaGFubmVsOworICBIQUxSZXBvcnQoSEFMVXNhZ2VSZXBvcnRpbmc6OmtSZXNvdXJjZVR5cGVfU29sZW5vaWQsIG1fZm9yd2FyZENoYW5uZWwsCisgICAgICAgICAgICBtX21vZHVsZU51bWJlcik7CisgIEhBTFJlcG9ydChIQUxVc2FnZVJlcG9ydGluZzo6a1Jlc291cmNlVHlwZV9Tb2xlbm9pZCwgbV9yZXZlcnNlQ2hhbm5lbCwKKyAgICAgICAgICAgIG1fbW9kdWxlTnVtYmVyKTsKKyAgTGl2ZVdpbmRvdzo6R2V0SW5zdGFuY2UoKS0+QWRkQWN0dWF0b3IoIkRvdWJsZVNvbGVub2lkIiwgbV9tb2R1bGVOdW1iZXIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1fZm9yd2FyZENoYW5uZWwsIHRoaXMpOworfQorCisvKioKKyAqIERlc3RydWN0b3IuCisgKi8KK0RvdWJsZVNvbGVub2lkOjp+RG91YmxlU29sZW5vaWQoKSB7CisgIGlmIChDaGVja1NvbGVub2lkTW9kdWxlKG1fbW9kdWxlTnVtYmVyKSkgeworICAgIG1fYWxsb2NhdGVkLT5GcmVlKG1fbW9kdWxlTnVtYmVyICoga1NvbGVub2lkQ2hhbm5lbHMgKyBtX2ZvcndhcmRDaGFubmVsKTsKKyAgICBtX2FsbG9jYXRlZC0+RnJlZShtX21vZHVsZU51bWJlciAqIGtTb2xlbm9pZENoYW5uZWxzICsgbV9yZXZlcnNlQ2hhbm5lbCk7CisgIH0KKyAgaWYgKG1fdGFibGUgIT0gbnVsbHB0cikgbV90YWJsZS0+UmVtb3ZlVGFibGVMaXN0ZW5lcih0aGlzKTsKK30KKworLyoqCisgKiBTZXQgdGhlIHZhbHVlIG9mIGEgc29sZW5vaWQuCisgKgorICogQHBhcmFtIHZhbHVlIFRoZSB2YWx1ZSB0byBzZXQgKE9mZiwgRm9yd2FyZCBvciBSZXZlcnNlKQorICovCit2b2lkIERvdWJsZVNvbGVub2lkOjpTZXQoVmFsdWUgdmFsdWUpIHsKKyAgaWYgKFN0YXR1c0lzRmF0YWwoKSkgcmV0dXJuOworICB1aW50OF90IHJhd1ZhbHVlID0gMHgwMDsKKworICBzd2l0Y2ggKHZhbHVlKSB7CisgICAgY2FzZSBrT2ZmOgorICAgICAgcmF3VmFsdWUgPSAweDAwOworICAgICAgYnJlYWs7CisgICAgY2FzZSBrRm9yd2FyZDoKKyAgICAgIHJhd1ZhbHVlID0gbV9mb3J3YXJkTWFzazsKKyAgICAgIGJyZWFrOworICAgIGNhc2Uga1JldmVyc2U6CisgICAgICByYXdWYWx1ZSA9IG1fcmV2ZXJzZU1hc2s7CisgICAgICBicmVhazsKKyAgfQorCisgIFNvbGVub2lkQmFzZTo6U2V0KHJhd1ZhbHVlLCBtX2ZvcndhcmRNYXNrIHwgbV9yZXZlcnNlTWFzaywgbV9tb2R1bGVOdW1iZXIpOworfQorCisvKioKKyAqIFJlYWQgdGhlIGN1cnJlbnQgdmFsdWUgb2YgdGhlIHNvbGVub2lkLgorICoKKyAqIEByZXR1cm4gVGhlIGN1cnJlbnQgdmFsdWUgb2YgdGhlIHNvbGVub2lkLgorICovCitEb3VibGVTb2xlbm9pZDo6VmFsdWUgRG91YmxlU29sZW5vaWQ6OkdldCgpIGNvbnN0IHsKKyAgaWYgKFN0YXR1c0lzRmF0YWwoKSkgcmV0dXJuIGtPZmY7CisgIHVpbnQ4X3QgdmFsdWUgPSBHZXRBbGwobV9tb2R1bGVOdW1iZXIpOworCisgIGlmICh2YWx1ZSAmIG1fZm9yd2FyZE1hc2spIHJldHVybiBrRm9yd2FyZDsKKyAgaWYgKHZhbHVlICYgbV9yZXZlcnNlTWFzaykgcmV0dXJuIGtSZXZlcnNlOworICByZXR1cm4ga09mZjsKK30KKy8qKgorICogQ2hlY2sgaWYgdGhlIGZvcndhcmQgc29sZW5vaWQgaXMgYmxhY2tsaXN0ZWQuCisgKiAJCUlmIGEgc29sZW5vaWQgaXMgc2hvcnRlZCwgaXQgaXMgYWRkZWQgdG8gdGhlIGJsYWNrbGlzdCBhbmQKKyAqIAkJZGlzYWJsZWQgdW50aWwgcG93ZXIgY3ljbGUsIG9yIHVudGlsIGZhdWx0cyBhcmUgY2xlYXJlZC4KKyAqIAkJQHNlZSBDbGVhckFsbFBDTVN0aWNreUZhdWx0cygpCisgKgorICogQHJldHVybiBJZiBzb2xlbm9pZCBpcyBkaXNhYmxlZCBkdWUgdG8gc2hvcnQuCisgKi8KK2Jvb2wgRG91YmxlU29sZW5vaWQ6OklzRndkU29sZW5vaWRCbGFja0xpc3RlZCgpIGNvbnN0IHsKKyAgaW50IGJsYWNrTGlzdCA9IEdldFBDTVNvbGVub2lkQmxhY2tMaXN0KG1fbW9kdWxlTnVtYmVyKTsKKyAgcmV0dXJuIChibGFja0xpc3QgJiBtX2ZvcndhcmRNYXNrKSA/IDEgOiAwOworfQorLyoqCisgKiBDaGVjayBpZiB0aGUgcmV2ZXJzZSBzb2xlbm9pZCBpcyBibGFja2xpc3RlZC4KKyAqIAkJSWYgYSBzb2xlbm9pZCBpcyBzaG9ydGVkLCBpdCBpcyBhZGRlZCB0byB0aGUgYmxhY2tsaXN0IGFuZAorICogCQlkaXNhYmxlZCB1bnRpbCBwb3dlciBjeWNsZSwgb3IgdW50aWwgZmF1bHRzIGFyZSBjbGVhcmVkLgorICogCQlAc2VlIENsZWFyQWxsUENNU3RpY2t5RmF1bHRzKCkKKyAqCisgKiBAcmV0dXJuIElmIHNvbGVub2lkIGlzIGRpc2FibGVkIGR1ZSB0byBzaG9ydC4KKyAqLworYm9vbCBEb3VibGVTb2xlbm9pZDo6SXNSZXZTb2xlbm9pZEJsYWNrTGlzdGVkKCkgY29uc3QgeworICBpbnQgYmxhY2tMaXN0ID0gR2V0UENNU29sZW5vaWRCbGFja0xpc3QobV9tb2R1bGVOdW1iZXIpOworICByZXR1cm4gKGJsYWNrTGlzdCAmIG1fcmV2ZXJzZU1hc2spID8gMSA6IDA7Cit9CisKK3ZvaWQgRG91YmxlU29sZW5vaWQ6OlZhbHVlQ2hhbmdlZChJVGFibGUqIHNvdXJjZSwgbGx2bTo6U3RyaW5nUmVmIGtleSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdGQ6OnNoYXJlZF9wdHI8bnQ6OlZhbHVlPiB2YWx1ZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBib29sIGlzTmV3KSB7CisgIGlmICghdmFsdWUtPklzU3RyaW5nKCkpIHJldHVybjsKKyAgVmFsdWUgbHZhbHVlID0ga09mZjsKKyAgaWYgKHZhbHVlLT5HZXRTdHJpbmcoKSA9PSAiRm9yd2FyZCIpCisgICAgbHZhbHVlID0ga0ZvcndhcmQ7CisgIGVsc2UgaWYgKHZhbHVlLT5HZXRTdHJpbmcoKSA9PSAiUmV2ZXJzZSIpCisgICAgbHZhbHVlID0ga1JldmVyc2U7CisgIFNldChsdmFsdWUpOworfQorCit2b2lkIERvdWJsZVNvbGVub2lkOjpVcGRhdGVUYWJsZSgpIHsKKyAgaWYgKG1fdGFibGUgIT0gbnVsbHB0cikgeworICAgIG1fdGFibGUtPlB1dFN0cmluZygKKyAgICAgICAgIlZhbHVlIiwgKEdldCgpID09IGtGb3J3YXJkID8gIkZvcndhcmQiCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA6IChHZXQoKSA9PSBrUmV2ZXJzZSA/ICJSZXZlcnNlIiA6ICJPZmYiKSkpOworICB9Cit9CisKK3ZvaWQgRG91YmxlU29sZW5vaWQ6OlN0YXJ0TGl2ZVdpbmRvd01vZGUoKSB7CisgIFNldChrT2ZmKTsKKyAgaWYgKG1fdGFibGUgIT0gbnVsbHB0cikgeworICAgIG1fdGFibGUtPkFkZFRhYmxlTGlzdGVuZXIoIlZhbHVlIiwgdGhpcywgdHJ1ZSk7CisgIH0KK30KKwordm9pZCBEb3VibGVTb2xlbm9pZDo6U3RvcExpdmVXaW5kb3dNb2RlKCkgeworICBTZXQoa09mZik7CisgIGlmIChtX3RhYmxlICE9IG51bGxwdHIpIHsKKyAgICBtX3RhYmxlLT5SZW1vdmVUYWJsZUxpc3RlbmVyKHRoaXMpOworICB9Cit9CisKK3N0ZDo6c3RyaW5nIERvdWJsZVNvbGVub2lkOjpHZXRTbWFydERhc2hib2FyZFR5cGUoKSBjb25zdCB7CisgIHJldHVybiAiRG91YmxlIFNvbGVub2lkIjsKK30KKwordm9pZCBEb3VibGVTb2xlbm9pZDo6SW5pdFRhYmxlKHN0ZDo6c2hhcmVkX3B0cjxJVGFibGU+IHN1YlRhYmxlKSB7CisgIG1fdGFibGUgPSBzdWJUYWJsZTsKKyAgVXBkYXRlVGFibGUoKTsKK30KKworc3RkOjpzaGFyZWRfcHRyPElUYWJsZT4gRG91YmxlU29sZW5vaWQ6OkdldFRhYmxlKCkgY29uc3QgeyByZXR1cm4gbV90YWJsZTsgfQpkaWZmIC0tZ2l0IGEvd3BpbGliYy9BdGhlbmEvc3JjL0RyaXZlclN0YXRpb24uY3BwIGIvd3BpbGliYy9BdGhlbmEvc3JjL0RyaXZlclN0YXRpb24uY3BwCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjQ1NWE5ODcKLS0tIC9kZXYvbnVsbAorKysgYi93cGlsaWJjL0F0aGVuYS9zcmMvRHJpdmVyU3RhdGlvbi5jcHAKQEAgLTAsMCArMSw1MzcgQEAKKy8qLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovCisvKiBDb3B5cmlnaHQgKGMpIEZJUlNUIDIwMDguIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCisgKi8KKy8qIE9wZW4gU291cmNlIFNvZnR3YXJlIC0gbWF5IGJlIG1vZGlmaWVkIGFuZCBzaGFyZWQgYnkgRlJDIHRlYW1zLiBUaGUgY29kZSAgICovCisvKiBtdXN0IGJlIGFjY29tcGFuaWVkIGJ5IHRoZSBGSVJTVCBCU0QgbGljZW5zZSBmaWxlIGluICQoV0lORF9CQVNFKS9XUElMaWIuICAqLworLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi8KKworI2luY2x1ZGUgIkRyaXZlclN0YXRpb24uaCIKKyNpbmNsdWRlICJBbmFsb2dJbnB1dC5oIgorI2luY2x1ZGUgIlRpbWVyLmgiCisjaW5jbHVkZSAiTmV0d29ya0NvbW11bmljYXRpb24vRlJDQ29tbS5oIgorI2luY2x1ZGUgIk1vdG9yU2FmZXR5SGVscGVyLmgiCisjaW5jbHVkZSAiVXRpbGl0eS5oIgorI2luY2x1ZGUgIldQSUVycm9ycy5oIgorI2luY2x1ZGUgPHN0cmluZy5oPgorI2luY2x1ZGUgIkxvZy5ocHAiCisKKy8vIHNldCB0aGUgbG9nZ2luZyBsZXZlbAorVExvZ0xldmVsIGRzTG9nTGV2ZWwgPSBsb2dERUJVRzsKK2NvbnN0IGRvdWJsZSBKT1lTVElDS19VTlBMVUdHRURfTUVTU0FHRV9JTlRFUlZBTCA9IDEuMDsKKworI2RlZmluZSBEU19MT0cobGV2ZWwpICAgICBcCisgIGlmIChsZXZlbCA+IGRzTG9nTGV2ZWwpIFwKKyAgICA7ICAgICAgICAgICAgICAgICAgICAgXAorICBlbHNlICAgICAgICAgICAgICAgICAgICBcCisgIExvZygpLkdldChsZXZlbCkKKworY29uc3QgdWludDMyX3QgRHJpdmVyU3RhdGlvbjo6a0pveXN0aWNrUG9ydHM7CisKKy8qKgorICogRHJpdmVyU3RhdGlvbiBjb25zdHJ1Y3Rvci4KKyAqCisgKiBUaGlzIGlzIG9ubHkgY2FsbGVkIG9uY2UgdGhlIGZpcnN0IHRpbWUgR2V0SW5zdGFuY2UoKSBpcyBjYWxsZWQKKyAqLworRHJpdmVyU3RhdGlvbjo6RHJpdmVyU3RhdGlvbigpIHsKKyAgLy8gQWxsIGpveXN0aWNrcyBzaG91bGQgZGVmYXVsdCB0byBoYXZpbmcgemVybyBheGVzLCBwb3ZzIGFuZCBidXR0b25zLCBzbworICAvLyB1bmluaXRpYWxpemVkIG1lbW9yeSBkb2Vzbid0IGdldCBzZW50IHRvIHNwZWVkIGNvbnRyb2xsZXJzLgorICBmb3IgKHVuc2lnbmVkIGludCBpID0gMDsgaSA8IGtKb3lzdGlja1BvcnRzOyBpKyspIHsKKyAgICBtX2pveXN0aWNrQXhlc1tpXS5jb3VudCA9IDA7CisgICAgbV9qb3lzdGlja1BPVnNbaV0uY291bnQgPSAwOworICAgIG1fam95c3RpY2tCdXR0b25zW2ldLmNvdW50ID0gMDsKKyAgICBtX2pveXN0aWNrRGVzY3JpcHRvcltpXS5pc1hib3ggPSAwOworICAgIG1fam95c3RpY2tEZXNjcmlwdG9yW2ldLnR5cGUgPSAtMTsKKyAgICBtX2pveXN0aWNrRGVzY3JpcHRvcltpXS5uYW1lWzBdID0gJ1wwJzsKKyAgfQorICAvLyBSZWdpc3RlciB0aGF0IHNlbWFwaG9yZSB3aXRoIHRoZSBuZXR3b3JrIGNvbW11bmljYXRpb25zIHRhc2suCisgIC8vIEl0IHdpbGwgc2lnbmFsIHdoZW4gbmV3IHBhY2tldCBkYXRhIGlzIGF2YWlsYWJsZS4KKyAgSEFMU2V0TmV3RGF0YVNlbSgmbV9wYWNrZXREYXRhQXZhaWxhYmxlQ29uZCk7CisKKyAgQWRkVG9TaW5nbGV0b25MaXN0KCk7CisKKyAgbV90YXNrID0gVGFzaygiRHJpdmVyU3RhdGlvbiIsICZEcml2ZXJTdGF0aW9uOjpSdW4sIHRoaXMpOworfQorCitEcml2ZXJTdGF0aW9uOjp+RHJpdmVyU3RhdGlvbigpIHsKKyAgbV9pc1J1bm5pbmcgPSBmYWxzZTsKKyAgbV90YXNrLmpvaW4oKTsKKworICAvLyBVbnJlZ2lzdGVyIG91ciBzZW1hcGhvcmUuCisgIEhBTFNldE5ld0RhdGFTZW0obnVsbHB0cik7Cit9CisKK3ZvaWQgRHJpdmVyU3RhdGlvbjo6UnVuKCkgeworICBtX2lzUnVubmluZyA9IHRydWU7CisgIGludCBwZXJpb2QgPSAwOworICB3aGlsZSAobV9pc1J1bm5pbmcpIHsKKyAgICB7CisgICAgICBzdGQ6OnVuaXF1ZV9sb2NrPHByaW9yaXR5X211dGV4PiBsb2NrKG1fcGFja2V0RGF0YUF2YWlsYWJsZU11dGV4KTsKKyAgICAgIG1fcGFja2V0RGF0YUF2YWlsYWJsZUNvbmQud2FpdChsb2NrKTsKKyAgICB9CisgICAgR2V0RGF0YSgpOworICAgIG1fd2FpdEZvckRhdGFDb25kLm5vdGlmeV9hbGwoKTsKKworICAgIGlmICgrK3BlcmlvZCA+PSA0KSB7CisgICAgICBNb3RvclNhZmV0eUhlbHBlcjo6Q2hlY2tNb3RvcnMoKTsKKyAgICAgIHBlcmlvZCA9IDA7CisgICAgfQorICAgIGlmIChtX3VzZXJJbkRpc2FibGVkKSBIQUxOZXR3b3JrQ29tbXVuaWNhdGlvbk9ic2VydmVVc2VyUHJvZ3JhbURpc2FibGVkKCk7CisgICAgaWYgKG1fdXNlckluQXV0b25vbW91cykKKyAgICAgIEhBTE5ldHdvcmtDb21tdW5pY2F0aW9uT2JzZXJ2ZVVzZXJQcm9ncmFtQXV0b25vbW91cygpOworICAgIGlmIChtX3VzZXJJblRlbGVvcCkgSEFMTmV0d29ya0NvbW11bmljYXRpb25PYnNlcnZlVXNlclByb2dyYW1UZWxlb3AoKTsKKyAgICBpZiAobV91c2VySW5UZXN0KSBIQUxOZXR3b3JrQ29tbXVuaWNhdGlvbk9ic2VydmVVc2VyUHJvZ3JhbVRlc3QoKTsKKyAgfQorfQorCisvKioKKyAqIFJldHVybiBhIHBvaW50ZXIgdG8gdGhlIHNpbmdsZXRvbiBEcml2ZXJTdGF0aW9uLgorICogQHJldHVybiBQb2ludGVyIHRvIHRoZSBEUyBpbnN0YW5jZQorICovCitEcml2ZXJTdGF0aW9uICZEcml2ZXJTdGF0aW9uOjpHZXRJbnN0YW5jZSgpIHsKKyAgc3RhdGljIERyaXZlclN0YXRpb24gaW5zdGFuY2U7CisgIHJldHVybiBpbnN0YW5jZTsKK30KKworLyoqCisgKiBDb3B5IGRhdGEgZnJvbSB0aGUgRFMgdGFzayBmb3IgdGhlIHVzZXIuCisgKiBJZiBubyBuZXcgZGF0YSBleGlzdHMsIGl0IHdpbGwganVzdCBiZSByZXR1cm5lZCwgb3RoZXJ3aXNlCisgKiB0aGUgZGF0YSB3aWxsIGJlIGNvcGllZCBmcm9tIHRoZSBEUyBwb2xsaW5nIGxvb3AuCisgKi8KK3ZvaWQgRHJpdmVyU3RhdGlvbjo6R2V0RGF0YSgpIHsKKyAgLy8gR2V0IHRoZSBzdGF0dXMgb2YgYWxsIG9mIHRoZSBqb3lzdGlja3MKKyAgZm9yICh1aW50OF90IHN0aWNrID0gMDsgc3RpY2sgPCBrSm95c3RpY2tQb3J0czsgc3RpY2srKykgeworICAgIEhBTEdldEpveXN0aWNrQXhlcyhzdGljaywgJm1fam95c3RpY2tBeGVzW3N0aWNrXSk7CisgICAgSEFMR2V0Sm95c3RpY2tQT1ZzKHN0aWNrLCAmbV9qb3lzdGlja1BPVnNbc3RpY2tdKTsKKyAgICBIQUxHZXRKb3lzdGlja0J1dHRvbnMoc3RpY2ssICZtX2pveXN0aWNrQnV0dG9uc1tzdGlja10pOworICAgIEhBTEdldEpveXN0aWNrRGVzY3JpcHRvcihzdGljaywgJm1fam95c3RpY2tEZXNjcmlwdG9yW3N0aWNrXSk7CisgIH0KKyAgbV9uZXdDb250cm9sRGF0YS5naXZlKCk7Cit9CisKKy8qKgorICogUmVhZCB0aGUgYmF0dGVyeSB2b2x0YWdlLgorICoKKyAqIEByZXR1cm4gVGhlIGJhdHRlcnkgdm9sdGFnZSBpbiBWb2x0cy4KKyAqLworZmxvYXQgRHJpdmVyU3RhdGlvbjo6R2V0QmF0dGVyeVZvbHRhZ2UoKSBjb25zdCB7CisgIGludDMyX3Qgc3RhdHVzID0gMDsKKyAgZmxvYXQgdm9sdGFnZSA9IGdldFZpblZvbHRhZ2UoJnN0YXR1cyk7CisgIHdwaV9zZXRFcnJvcldpdGhDb250ZXh0KHN0YXR1cywgImdldFZpblZvbHRhZ2UiKTsKKworICByZXR1cm4gdm9sdGFnZTsKK30KKworLyoqCisgKiBSZXBvcnRzIGVycm9ycyByZWxhdGVkIHRvIHVucGx1Z2dlZCBqb3lzdGlja3MKKyAqIFRocm90dGxlcyB0aGUgZXJyb3JzIHNvIHRoYXQgdGhleSBkb24ndCBvdmVyd2hlbG0gdGhlIERTCisgKi8KK3ZvaWQgRHJpdmVyU3RhdGlvbjo6UmVwb3J0Sm95c3RpY2tVbnBsdWdnZWRFcnJvcihzdGQ6OnN0cmluZyBtZXNzYWdlKSB7CisgIGRvdWJsZSBjdXJyZW50VGltZSA9IFRpbWVyOjpHZXRGUEdBVGltZXN0YW1wKCk7CisgIGlmIChjdXJyZW50VGltZSA+IG1fbmV4dE1lc3NhZ2VUaW1lKSB7CisgICAgUmVwb3J0RXJyb3IobWVzc2FnZSk7CisgICAgbV9uZXh0TWVzc2FnZVRpbWUgPSBjdXJyZW50VGltZSArIEpPWVNUSUNLX1VOUExVR0dFRF9NRVNTQUdFX0lOVEVSVkFMOworICB9Cit9CisKKy8qKgorICogUmV0dXJucyB0aGUgbnVtYmVyIG9mIGF4ZXMgb24gYSBnaXZlbiBqb3lzdGljayBwb3J0CisgKgorICogQHBhcmFtIHN0aWNrIFRoZSBqb3lzdGljayBwb3J0IG51bWJlcgorICogQHJldHVybiBUaGUgbnVtYmVyIG9mIGF4ZXMgb24gdGhlIGluZGljYXRlZCBqb3lzdGljaworICovCitpbnQgRHJpdmVyU3RhdGlvbjo6R2V0U3RpY2tBeGlzQ291bnQodWludDMyX3Qgc3RpY2spIGNvbnN0IHsKKyAgaWYgKHN0aWNrID49IGtKb3lzdGlja1BvcnRzKSB7CisgICAgd3BpX3NldFdQSUVycm9yKEJhZEpveXN0aWNrSW5kZXgpOworICAgIHJldHVybiAwOworICB9CisgIEhBTEpveXN0aWNrQXhlcyBqb3lzdGlja0F4ZXM7CisgIEhBTEdldEpveXN0aWNrQXhlcyhzdGljaywgJmpveXN0aWNrQXhlcyk7CisgIHJldHVybiBqb3lzdGlja0F4ZXMuY291bnQ7Cit9CisKKy8qKgorICogUmV0dXJucyB0aGUgbmFtZSBvZiB0aGUgam95c3RpY2sgYXQgdGhlIGdpdmVuIHBvcnQKKyAqCisgKiBAcGFyYW0gc3RpY2sgVGhlIGpveXN0aWNrIHBvcnQgbnVtYmVyCisgKiBAcmV0dXJuIFRoZSBuYW1lIG9mIHRoZSBqb3lzdGljayBhdCB0aGUgZ2l2ZW4gcG9ydAorICovCitzdGQ6OnN0cmluZyBEcml2ZXJTdGF0aW9uOjpHZXRKb3lzdGlja05hbWUodWludDMyX3Qgc3RpY2spIGNvbnN0IHsKKyAgaWYgKHN0aWNrID49IGtKb3lzdGlja1BvcnRzKSB7CisgICAgd3BpX3NldFdQSUVycm9yKEJhZEpveXN0aWNrSW5kZXgpOworICB9CisgIHN0ZDo6c3RyaW5nIHJldFZhbChtX2pveXN0aWNrRGVzY3JpcHRvclswXS5uYW1lKTsKKyAgcmV0dXJuIHJldFZhbDsKK30KKworLyoqCisgKiBSZXR1cm5zIHRoZSB0eXBlIG9mIGpveXN0aWNrIGF0IGEgZ2l2ZW4gcG9ydAorICoKKyAqIEBwYXJhbSBzdGljayBUaGUgam95c3RpY2sgcG9ydCBudW1iZXIKKyAqIEByZXR1cm4gVGhlIEhJRCB0eXBlIG9mIGpveXN0aWNrIGF0IHRoZSBnaXZlbiBwb3J0CisgKi8KK2ludCBEcml2ZXJTdGF0aW9uOjpHZXRKb3lzdGlja1R5cGUodWludDMyX3Qgc3RpY2spIGNvbnN0IHsKKyAgaWYgKHN0aWNrID49IGtKb3lzdGlja1BvcnRzKSB7CisgICAgd3BpX3NldFdQSUVycm9yKEJhZEpveXN0aWNrSW5kZXgpOworICAgIHJldHVybiAtMTsKKyAgfQorICByZXR1cm4gKGludCltX2pveXN0aWNrRGVzY3JpcHRvcltzdGlja10udHlwZTsKK30KKworLyoqCisgKiBSZXR1cm5zIGEgYm9vbGVhbiBpbmRpY2F0aW5nIGlmIHRoZSBjb250cm9sbGVyIGlzIGFuIHhib3ggY29udHJvbGxlci4KKyAqCisgKiBAcGFyYW0gc3RpY2sgVGhlIGpveXN0aWNrIHBvcnQgbnVtYmVyCisgKiBAcmV0dXJuIEEgYm9vbGVhbiB0aGF0IGlzIHRydWUgaWYgdGhlIGNvbnRyb2xsZXIgaXMgYW4geGJveCBjb250cm9sbGVyLgorICovCitib29sIERyaXZlclN0YXRpb246OkdldEpveXN0aWNrSXNYYm94KHVpbnQzMl90IHN0aWNrKSBjb25zdCB7CisgIGlmIChzdGljayA+PSBrSm95c3RpY2tQb3J0cykgeworICAgIHdwaV9zZXRXUElFcnJvcihCYWRKb3lzdGlja0luZGV4KTsKKyAgICByZXR1cm4gZmFsc2U7CisgIH0KKyAgcmV0dXJuIChib29sKW1fam95c3RpY2tEZXNjcmlwdG9yW3N0aWNrXS5pc1hib3g7Cit9CisKKy8qKgorICogUmV0dXJucyB0aGUgdHlwZXMgb2YgQXhlcyBvbiBhIGdpdmVuIGpveXN0aWNrIHBvcnQKKyAqCisgKiBAcGFyYW0gc3RpY2sgVGhlIGpveXN0aWNrIHBvcnQgbnVtYmVyIGFuZCB0aGUgdGFyZ2V0IGF4aXMKKyAqIEByZXR1cm4gV2hhdCB0eXBlIG9mIGF4aXMgdGhlIGF4aXMgaXMgcmVwb3J0aW5nIHRvIGJlCisgKi8KK2ludCBEcml2ZXJTdGF0aW9uOjpHZXRKb3lzdGlja0F4aXNUeXBlKHVpbnQzMl90IHN0aWNrLCB1aW50OF90IGF4aXMpIGNvbnN0IHsKKyAgaWYgKHN0aWNrID49IGtKb3lzdGlja1BvcnRzKSB7CisgICAgd3BpX3NldFdQSUVycm9yKEJhZEpveXN0aWNrSW5kZXgpOworICAgIHJldHVybiAtMTsKKyAgfQorICByZXR1cm4gbV9qb3lzdGlja0Rlc2NyaXB0b3Jbc3RpY2tdLmF4aXNUeXBlc1theGlzXTsKK30KKworLyoqCisgKiBSZXR1cm5zIHRoZSBudW1iZXIgb2YgUE9WcyBvbiBhIGdpdmVuIGpveXN0aWNrIHBvcnQKKyAqCisgKiBAcGFyYW0gc3RpY2sgVGhlIGpveXN0aWNrIHBvcnQgbnVtYmVyCisgKiBAcmV0dXJuIFRoZSBudW1iZXIgb2YgUE9WcyBvbiB0aGUgaW5kaWNhdGVkIGpveXN0aWNrCisgKi8KK2ludCBEcml2ZXJTdGF0aW9uOjpHZXRTdGlja1BPVkNvdW50KHVpbnQzMl90IHN0aWNrKSBjb25zdCB7CisgIGlmIChzdGljayA+PSBrSm95c3RpY2tQb3J0cykgeworICAgIHdwaV9zZXRXUElFcnJvcihCYWRKb3lzdGlja0luZGV4KTsKKyAgICByZXR1cm4gMDsKKyAgfQorICBIQUxKb3lzdGlja1BPVnMgam95c3RpY2tQT1ZzOworICBIQUxHZXRKb3lzdGlja1BPVnMoc3RpY2ssICZqb3lzdGlja1BPVnMpOworICByZXR1cm4gam95c3RpY2tQT1ZzLmNvdW50OworfQorCisvKioKKyAqIFJldHVybnMgdGhlIG51bWJlciBvZiBidXR0b25zIG9uIGEgZ2l2ZW4gam95c3RpY2sgcG9ydAorICoKKyAqIEBwYXJhbSBzdGljayBUaGUgam95c3RpY2sgcG9ydCBudW1iZXIKKyAqIEByZXR1cm4gVGhlIG51bWJlciBvZiBidXR0b25zIG9uIHRoZSBpbmRpY2F0ZWQgam95c3RpY2sKKyAqLworaW50IERyaXZlclN0YXRpb246OkdldFN0aWNrQnV0dG9uQ291bnQodWludDMyX3Qgc3RpY2spIGNvbnN0IHsKKyAgaWYgKHN0aWNrID49IGtKb3lzdGlja1BvcnRzKSB7CisgICAgd3BpX3NldFdQSUVycm9yKEJhZEpveXN0aWNrSW5kZXgpOworICAgIHJldHVybiAwOworICB9CisgIEhBTEpveXN0aWNrQnV0dG9ucyBqb3lzdGlja0J1dHRvbnM7CisgIEhBTEdldEpveXN0aWNrQnV0dG9ucyhzdGljaywgJmpveXN0aWNrQnV0dG9ucyk7CisgIHJldHVybiBqb3lzdGlja0J1dHRvbnMuY291bnQ7Cit9CisKKy8qKgorICogR2V0IHRoZSB2YWx1ZSBvZiB0aGUgYXhpcyBvbiBhIGpveXN0aWNrLgorICogVGhpcyBkZXBlbmRzIG9uIHRoZSBtYXBwaW5nIG9mIHRoZSBqb3lzdGljayBjb25uZWN0ZWQgdG8gdGhlIHNwZWNpZmllZCBwb3J0LgorICoKKyAqIEBwYXJhbSBzdGljayBUaGUgam95c3RpY2sgdG8gcmVhZC4KKyAqIEBwYXJhbSBheGlzIFRoZSBhbmFsb2cgYXhpcyB2YWx1ZSB0byByZWFkIGZyb20gdGhlIGpveXN0aWNrLgorICogQHJldHVybiBUaGUgdmFsdWUgb2YgdGhlIGF4aXMgb24gdGhlIGpveXN0aWNrLgorICovCitmbG9hdCBEcml2ZXJTdGF0aW9uOjpHZXRTdGlja0F4aXModWludDMyX3Qgc3RpY2ssIHVpbnQzMl90IGF4aXMpIHsKKyAgaWYgKHN0aWNrID49IGtKb3lzdGlja1BvcnRzKSB7CisgICAgd3BpX3NldFdQSUVycm9yKEJhZEpveXN0aWNrSW5kZXgpOworICAgIHJldHVybiAwOworICB9CisKKyAgaWYgKGF4aXMgPj0gbV9qb3lzdGlja0F4ZXNbc3RpY2tdLmNvdW50KSB7CisgICAgaWYgKGF4aXMgPj0ga01heEpveXN0aWNrQXhlcykKKyAgICAgIHdwaV9zZXRXUElFcnJvcihCYWRKb3lzdGlja0F4aXMpOworICAgIGVsc2UKKyAgICAgIFJlcG9ydEpveXN0aWNrVW5wbHVnZ2VkRXJyb3IoCisgICAgICAgICAgIldBUk5JTkc6IEpveXN0aWNrIEF4aXMgbWlzc2luZywgY2hlY2sgaWYgYWxsIGNvbnRyb2xsZXJzIGFyZSAiCisgICAgICAgICAgInBsdWdnZWQgaW5cbiIpOworICAgIHJldHVybiAwLjBmOworICB9CisKKyAgaW50OF90IHZhbHVlID0gbV9qb3lzdGlja0F4ZXNbc3RpY2tdLmF4ZXNbYXhpc107CisKKyAgaWYgKHZhbHVlIDwgMCkgeworICAgIHJldHVybiB2YWx1ZSAvIDEyOC4wZjsKKyAgfSBlbHNlIHsKKyAgICByZXR1cm4gdmFsdWUgLyAxMjcuMGY7CisgIH0KK30KKworLyoqCisgKiBHZXQgdGhlIHN0YXRlIG9mIGEgUE9WIG9uIHRoZSBqb3lzdGljay4KKyAqCisgKiBAcmV0dXJuIHRoZSBhbmdsZSBvZiB0aGUgUE9WIGluIGRlZ3JlZXMsIG9yIC0xIGlmIHRoZSBQT1YgaXMgbm90IHByZXNzZWQuCisgKi8KK2ludCBEcml2ZXJTdGF0aW9uOjpHZXRTdGlja1BPVih1aW50MzJfdCBzdGljaywgdWludDMyX3QgcG92KSB7CisgIGlmIChzdGljayA+PSBrSm95c3RpY2tQb3J0cykgeworICAgIHdwaV9zZXRXUElFcnJvcihCYWRKb3lzdGlja0luZGV4KTsKKyAgICByZXR1cm4gLTE7CisgIH0KKworICBpZiAocG92ID49IG1fam95c3RpY2tQT1ZzW3N0aWNrXS5jb3VudCkgeworICAgIGlmIChwb3YgPj0ga01heEpveXN0aWNrUE9WcykKKyAgICAgIHdwaV9zZXRXUElFcnJvcihCYWRKb3lzdGlja0F4aXMpOworICAgIGVsc2UKKyAgICAgIFJlcG9ydEpveXN0aWNrVW5wbHVnZ2VkRXJyb3IoCisgICAgICAgICAgIldBUk5JTkc6IEpveXN0aWNrIFBPViBtaXNzaW5nLCBjaGVjayBpZiBhbGwgY29udHJvbGxlcnMgYXJlIHBsdWdnZWQgIgorICAgICAgICAgICJpblxuIik7CisgICAgcmV0dXJuIC0xOworICB9CisKKyAgcmV0dXJuIG1fam95c3RpY2tQT1ZzW3N0aWNrXS5wb3ZzW3Bvdl07Cit9CisKKy8qKgorICogVGhlIHN0YXRlIG9mIHRoZSBidXR0b25zIG9uIHRoZSBqb3lzdGljay4KKyAqCisgKiBAcGFyYW0gc3RpY2sgVGhlIGpveXN0aWNrIHRvIHJlYWQuCisgKiBAcmV0dXJuIFRoZSBzdGF0ZSBvZiB0aGUgYnV0dG9ucyBvbiB0aGUgam95c3RpY2suCisgKi8KK3VpbnQzMl90IERyaXZlclN0YXRpb246OkdldFN0aWNrQnV0dG9ucyh1aW50MzJfdCBzdGljaykgY29uc3QgeworICBpZiAoc3RpY2sgPj0ga0pveXN0aWNrUG9ydHMpIHsKKyAgICB3cGlfc2V0V1BJRXJyb3IoQmFkSm95c3RpY2tJbmRleCk7CisgICAgcmV0dXJuIDA7CisgIH0KKworICByZXR1cm4gbV9qb3lzdGlja0J1dHRvbnNbc3RpY2tdLmJ1dHRvbnM7Cit9CisKKy8qKgorICogVGhlIHN0YXRlIG9mIG9uZSBqb3lzdGljayBidXR0b24uIEJ1dHRvbiBpbmRleGVzIGJlZ2luIGF0IDEuCisgKgorICogQHBhcmFtIHN0aWNrIFRoZSBqb3lzdGljayB0byByZWFkLgorICogQHBhcmFtIGJ1dHRvbiBUaGUgYnV0dG9uIGluZGV4LCBiZWdpbm5pbmcgYXQgMS4KKyAqIEByZXR1cm4gVGhlIHN0YXRlIG9mIHRoZSBqb3lzdGljayBidXR0b24uCisgKi8KK2Jvb2wgRHJpdmVyU3RhdGlvbjo6R2V0U3RpY2tCdXR0b24odWludDMyX3Qgc3RpY2ssIHVpbnQ4X3QgYnV0dG9uKSB7CisgIGlmIChzdGljayA+PSBrSm95c3RpY2tQb3J0cykgeworICAgIHdwaV9zZXRXUElFcnJvcihCYWRKb3lzdGlja0luZGV4KTsKKyAgICByZXR1cm4gZmFsc2U7CisgIH0KKworICBpZiAoYnV0dG9uID4gbV9qb3lzdGlja0J1dHRvbnNbc3RpY2tdLmNvdW50KSB7CisgICAgUmVwb3J0Sm95c3RpY2tVbnBsdWdnZWRFcnJvcigKKyAgICAgICAgIldBUk5JTkc6IEpveXN0aWNrIEJ1dHRvbiBtaXNzaW5nLCBjaGVjayBpZiBhbGwgY29udHJvbGxlcnMgYXJlICIKKyAgICAgICAgInBsdWdnZWQgaW5cbiIpOworICAgIHJldHVybiBmYWxzZTsKKyAgfQorICBpZiAoYnV0dG9uID09IDApIHsKKyAgICBSZXBvcnRKb3lzdGlja1VucGx1Z2dlZEVycm9yKAorICAgICAgICAiRVJST1I6IEJ1dHRvbiBpbmRleGVzIGJlZ2luIGF0IDEgaW4gV1BJTGliIGZvciBDKysgYW5kIEphdmEiKTsKKyAgICByZXR1cm4gZmFsc2U7CisgIH0KKyAgcmV0dXJuICgoMHgxIDw8IChidXR0b24gLSAxKSkgJiBtX2pveXN0aWNrQnV0dG9uc1tzdGlja10uYnV0dG9ucykgIT0gMDsKK30KKworLyoqCisgKiBDaGVjayBpZiB0aGUgRFMgaGFzIGVuYWJsZWQgdGhlIHJvYm90CisgKiBAcmV0dXJuIFRydWUgaWYgdGhlIHJvYm90IGlzIGVuYWJsZWQgYW5kIHRoZSBEUyBpcyBjb25uZWN0ZWQKKyAqLworYm9vbCBEcml2ZXJTdGF0aW9uOjpJc0VuYWJsZWQoKSBjb25zdCB7CisgIEhBTENvbnRyb2xXb3JkIGNvbnRyb2xXb3JkOworICBtZW1zZXQoJmNvbnRyb2xXb3JkLCAwLCBzaXplb2YoY29udHJvbFdvcmQpKTsKKyAgSEFMR2V0Q29udHJvbFdvcmQoJmNvbnRyb2xXb3JkKTsKKyAgcmV0dXJuIGNvbnRyb2xXb3JkLmVuYWJsZWQgJiYgY29udHJvbFdvcmQuZHNBdHRhY2hlZDsKK30KKworLyoqCisgKiBDaGVjayBpZiB0aGUgcm9ib3QgaXMgZGlzYWJsZWQKKyAqIEByZXR1cm4gVHJ1ZSBpZiB0aGUgcm9ib3QgaXMgZXhwbGljaXRseSBkaXNhYmxlZCBvciB0aGUgRFMgaXMgbm90IGNvbm5lY3RlZAorICovCitib29sIERyaXZlclN0YXRpb246OklzRGlzYWJsZWQoKSBjb25zdCB7CisgIEhBTENvbnRyb2xXb3JkIGNvbnRyb2xXb3JkOworICBtZW1zZXQoJmNvbnRyb2xXb3JkLCAwLCBzaXplb2YoY29udHJvbFdvcmQpKTsKKyAgSEFMR2V0Q29udHJvbFdvcmQoJmNvbnRyb2xXb3JkKTsKKyAgcmV0dXJuICEoY29udHJvbFdvcmQuZW5hYmxlZCAmJiBjb250cm9sV29yZC5kc0F0dGFjaGVkKTsKK30KKworLyoqCisgKiBDaGVjayBpZiB0aGUgRFMgaXMgY29tbWFuZGluZyBhdXRvbm9tb3VzIG1vZGUKKyAqIEByZXR1cm4gVHJ1ZSBpZiB0aGUgcm9ib3QgaXMgYmVpbmcgY29tbWFuZGVkIHRvIGJlIGluIGF1dG9ub21vdXMgbW9kZQorICovCitib29sIERyaXZlclN0YXRpb246OklzQXV0b25vbW91cygpIGNvbnN0IHsKKyAgSEFMQ29udHJvbFdvcmQgY29udHJvbFdvcmQ7CisgIG1lbXNldCgmY29udHJvbFdvcmQsIDAsIHNpemVvZihjb250cm9sV29yZCkpOworICBIQUxHZXRDb250cm9sV29yZCgmY29udHJvbFdvcmQpOworICByZXR1cm4gY29udHJvbFdvcmQuYXV0b25vbW91czsKK30KKworLyoqCisgKiBDaGVjayBpZiB0aGUgRFMgaXMgY29tbWFuZGluZyB0ZWxlb3AgbW9kZQorICogQHJldHVybiBUcnVlIGlmIHRoZSByb2JvdCBpcyBiZWluZyBjb21tYW5kZWQgdG8gYmUgaW4gdGVsZW9wIG1vZGUKKyAqLworYm9vbCBEcml2ZXJTdGF0aW9uOjpJc09wZXJhdG9yQ29udHJvbCgpIGNvbnN0IHsKKyAgSEFMQ29udHJvbFdvcmQgY29udHJvbFdvcmQ7CisgIG1lbXNldCgmY29udHJvbFdvcmQsIDAsIHNpemVvZihjb250cm9sV29yZCkpOworICBIQUxHZXRDb250cm9sV29yZCgmY29udHJvbFdvcmQpOworICByZXR1cm4gIShjb250cm9sV29yZC5hdXRvbm9tb3VzIHx8IGNvbnRyb2xXb3JkLnRlc3QpOworfQorCisvKioKKyAqIENoZWNrIGlmIHRoZSBEUyBpcyBjb21tYW5kaW5nIHRlc3QgbW9kZQorICogQHJldHVybiBUcnVlIGlmIHRoZSByb2JvdCBpcyBiZWluZyBjb21tYW5kZWQgdG8gYmUgaW4gdGVzdCBtb2RlCisgKi8KK2Jvb2wgRHJpdmVyU3RhdGlvbjo6SXNUZXN0KCkgY29uc3QgeworICBIQUxDb250cm9sV29yZCBjb250cm9sV29yZDsKKyAgSEFMR2V0Q29udHJvbFdvcmQoJmNvbnRyb2xXb3JkKTsKKyAgcmV0dXJuIGNvbnRyb2xXb3JkLnRlc3Q7Cit9CisKKy8qKgorICogQ2hlY2sgaWYgdGhlIERTIGlzIGF0dGFjaGVkCisgKiBAcmV0dXJuIFRydWUgaWYgdGhlIERTIGlzIGNvbm5lY3RlZCB0byB0aGUgcm9ib3QKKyAqLworYm9vbCBEcml2ZXJTdGF0aW9uOjpJc0RTQXR0YWNoZWQoKSBjb25zdCB7CisgIEhBTENvbnRyb2xXb3JkIGNvbnRyb2xXb3JkOworICBtZW1zZXQoJmNvbnRyb2xXb3JkLCAwLCBzaXplb2YoY29udHJvbFdvcmQpKTsKKyAgSEFMR2V0Q29udHJvbFdvcmQoJmNvbnRyb2xXb3JkKTsKKyAgcmV0dXJuIGNvbnRyb2xXb3JkLmRzQXR0YWNoZWQ7Cit9CisKKy8qKgorICogQ2hlY2sgaWYgdGhlIEZQR0Egb3V0cHV0cyBhcmUgZW5hYmxlZC4gVGhlIG91dHB1dHMgbWF5IGJlIGRpc2FibGVkIGlmIHRoZQorICogcm9ib3QgaXMgZGlzYWJsZWQKKyAqIG9yIGUtc3RvcHBlZCwgdGhlIHdhdGNoZG9nIGhhcyBleHBpcmVkLCBvciBpZiB0aGUgcm9ib1JJTyBicm93bnMgb3V0LgorICogQHJldHVybiBUcnVlIGlmIHRoZSBGUEdBIG91dHB1dHMgYXJlIGVuYWJsZWQuCisgKi8KK2Jvb2wgRHJpdmVyU3RhdGlvbjo6SXNTeXNBY3RpdmUoKSBjb25zdCB7CisgIGludDMyX3Qgc3RhdHVzID0gMDsKKyAgYm9vbCByZXRWYWwgPSBIQUxHZXRTeXN0ZW1BY3RpdmUoJnN0YXR1cyk7CisgIHdwaV9zZXRFcnJvcldpdGhDb250ZXh0KHN0YXR1cywgZ2V0SEFMRXJyb3JNZXNzYWdlKHN0YXR1cykpOworICByZXR1cm4gcmV0VmFsOworfQorCisvKioKKyAqIENoZWNrIGlmIHRoZSBzeXN0ZW0gaXMgYnJvd25lZCBvdXQuCisgKiBAcmV0dXJuIFRydWUgaWYgdGhlIHN5c3RlbSBpcyBicm93bmVkIG91dAorICovCitib29sIERyaXZlclN0YXRpb246OklzU3lzQnJvd25lZE91dCgpIGNvbnN0IHsKKyAgaW50MzJfdCBzdGF0dXMgPSAwOworICBib29sIHJldFZhbCA9IEhBTEdldEJyb3duZWRPdXQoJnN0YXR1cyk7CisgIHdwaV9zZXRFcnJvcldpdGhDb250ZXh0KHN0YXR1cywgZ2V0SEFMRXJyb3JNZXNzYWdlKHN0YXR1cykpOworICByZXR1cm4gcmV0VmFsOworfQorCisvKioKKyAqIEhhcyBhIG5ldyBjb250cm9sIHBhY2tldCBmcm9tIHRoZSBkcml2ZXIgc3RhdGlvbiBhcnJpdmVkIHNpbmNlIHRoZSBsYXN0IHRpbWUKKyAqIHRoaXMgZnVuY3Rpb24gd2FzIGNhbGxlZD8KKyAqIFdhcm5pbmc6IElmIHlvdSBjYWxsIHRoaXMgZnVuY3Rpb24gZnJvbSBtb3JlIHRoYW4gb25lIHBsYWNlIGF0IHRoZSBzYW1lIHRpbWUsCisgKiB5b3Ugd2lsbCBub3QgZ2V0IHRoZSBnZXQgdGhlIGludGVuZGVkIGJlaGF2aW91ci4KKyAqIEByZXR1cm4gVHJ1ZSBpZiB0aGUgY29udHJvbCBkYXRhIGhhcyBiZWVuIHVwZGF0ZWQgc2luY2UgdGhlIGxhc3QgY2FsbC4KKyAqLworYm9vbCBEcml2ZXJTdGF0aW9uOjpJc05ld0NvbnRyb2xEYXRhKCkgY29uc3QgeworICByZXR1cm4gbV9uZXdDb250cm9sRGF0YS50cnlUYWtlKCkgPT0gZmFsc2U7Cit9CisKKy8qKgorICogSXMgdGhlIGRyaXZlciBzdGF0aW9uIGF0dGFjaGVkIHRvIGEgRmllbGQgTWFuYWdlbWVudCBTeXN0ZW0/CisgKiBAcmV0dXJuIFRydWUgaWYgdGhlIHJvYm90IGlzIGNvbXBldGluZyBvbiBhIGZpZWxkIGJlaW5nIGNvbnRyb2xsZWQgYnkgYSBGaWVsZAorICogTWFuYWdlbWVudCBTeXN0ZW0KKyAqLworYm9vbCBEcml2ZXJTdGF0aW9uOjpJc0ZNU0F0dGFjaGVkKCkgY29uc3QgeworICBIQUxDb250cm9sV29yZCBjb250cm9sV29yZDsKKyAgSEFMR2V0Q29udHJvbFdvcmQoJmNvbnRyb2xXb3JkKTsKKyAgcmV0dXJuIGNvbnRyb2xXb3JkLmZtc0F0dGFjaGVkOworfQorCisvKioKKyAqIFJldHVybiB0aGUgYWxsaWFuY2UgdGhhdCB0aGUgZHJpdmVyIHN0YXRpb24gc2F5cyBpdCBpcyBvbi4KKyAqIFRoaXMgY291bGQgcmV0dXJuIGtSZWQgb3Iga0JsdWUKKyAqIEByZXR1cm4gVGhlIEFsbGlhbmNlIGVudW0gKGtSZWQsIGtCbHVlIG9yIGtJbnZhbGlkKQorICovCitEcml2ZXJTdGF0aW9uOjpBbGxpYW5jZSBEcml2ZXJTdGF0aW9uOjpHZXRBbGxpYW5jZSgpIGNvbnN0IHsKKyAgSEFMQWxsaWFuY2VTdGF0aW9uSUQgYWxsaWFuY2VTdGF0aW9uSUQ7CisgIEhBTEdldEFsbGlhbmNlU3RhdGlvbigmYWxsaWFuY2VTdGF0aW9uSUQpOworICBzd2l0Y2ggKGFsbGlhbmNlU3RhdGlvbklEKSB7CisgICAgY2FzZSBrSEFMQWxsaWFuY2VTdGF0aW9uSURfcmVkMToKKyAgICBjYXNlIGtIQUxBbGxpYW5jZVN0YXRpb25JRF9yZWQyOgorICAgIGNhc2Uga0hBTEFsbGlhbmNlU3RhdGlvbklEX3JlZDM6CisgICAgICByZXR1cm4ga1JlZDsKKyAgICBjYXNlIGtIQUxBbGxpYW5jZVN0YXRpb25JRF9ibHVlMToKKyAgICBjYXNlIGtIQUxBbGxpYW5jZVN0YXRpb25JRF9ibHVlMjoKKyAgICBjYXNlIGtIQUxBbGxpYW5jZVN0YXRpb25JRF9ibHVlMzoKKyAgICAgIHJldHVybiBrQmx1ZTsKKyAgICBkZWZhdWx0OgorICAgICAgcmV0dXJuIGtJbnZhbGlkOworICB9Cit9CisKKy8qKgorICogUmV0dXJuIHRoZSBkcml2ZXIgc3RhdGlvbiBsb2NhdGlvbiBvbiB0aGUgZmllbGQKKyAqIFRoaXMgY291bGQgcmV0dXJuIDEsIDIsIG9yIDMKKyAqIEByZXR1cm4gVGhlIGxvY2F0aW9uIG9mIHRoZSBkcml2ZXIgc3RhdGlvbiAoMS0zLCAwIGZvciBpbnZhbGlkKQorICovCit1aW50MzJfdCBEcml2ZXJTdGF0aW9uOjpHZXRMb2NhdGlvbigpIGNvbnN0IHsKKyAgSEFMQWxsaWFuY2VTdGF0aW9uSUQgYWxsaWFuY2VTdGF0aW9uSUQ7CisgIEhBTEdldEFsbGlhbmNlU3RhdGlvbigmYWxsaWFuY2VTdGF0aW9uSUQpOworICBzd2l0Y2ggKGFsbGlhbmNlU3RhdGlvbklEKSB7CisgICAgY2FzZSBrSEFMQWxsaWFuY2VTdGF0aW9uSURfcmVkMToKKyAgICBjYXNlIGtIQUxBbGxpYW5jZVN0YXRpb25JRF9ibHVlMToKKyAgICAgIHJldHVybiAxOworICAgIGNhc2Uga0hBTEFsbGlhbmNlU3RhdGlvbklEX3JlZDI6CisgICAgY2FzZSBrSEFMQWxsaWFuY2VTdGF0aW9uSURfYmx1ZTI6CisgICAgICByZXR1cm4gMjsKKyAgICBjYXNlIGtIQUxBbGxpYW5jZVN0YXRpb25JRF9yZWQzOgorICAgIGNhc2Uga0hBTEFsbGlhbmNlU3RhdGlvbklEX2JsdWUzOgorICAgICAgcmV0dXJuIDM7CisgICAgZGVmYXVsdDoKKyAgICAgIHJldHVybiAwOworICB9Cit9CisKKy8qKgorICogV2FpdCB1bnRpbCBhIG5ldyBwYWNrZXQgY29tZXMgZnJvbSB0aGUgZHJpdmVyIHN0YXRpb24KKyAqIFRoaXMgYmxvY2tzIG9uIGEgc2VtYXBob3JlLCBzbyB0aGUgd2FpdGluZyBpcyBlZmZpY2llbnQuCisgKiBUaGlzIGlzIGEgZ29vZCB3YXkgdG8gZGVsYXkgcHJvY2Vzc2luZyB1bnRpbCB0aGVyZSBpcyBuZXcgZHJpdmVyIHN0YXRpb24gZGF0YQorICogdG8gYWN0IG9uCisgKi8KK3ZvaWQgRHJpdmVyU3RhdGlvbjo6V2FpdEZvckRhdGEoKSB7CisgIHN0ZDo6dW5pcXVlX2xvY2s8cHJpb3JpdHlfbXV0ZXg+IGxvY2sobV93YWl0Rm9yRGF0YU11dGV4KTsKKyAgbV93YWl0Rm9yRGF0YUNvbmQud2FpdChsb2NrKTsKK30KKworLyoqCisgKiBSZXR1cm4gdGhlIGFwcHJveGltYXRlIG1hdGNoIHRpbWUKKyAqIFRoZSBGTVMgZG9lcyBub3Qgc2VuZCBhbiBvZmZpY2lhbCBtYXRjaCB0aW1lIHRvIHRoZSByb2JvdHMsIGJ1dCBkb2VzIHNlbmQgYW4KKyAqIGFwcHJveGltYXRlIG1hdGNoIHRpbWUuCisgKiBUaGUgdmFsdWUgd2lsbCBjb3VudCBkb3duIHRoZSB0aW1lIHJlbWFpbmluZyBpbiB0aGUgY3VycmVudCBwZXJpb2QgKGF1dG8gb3IKKyAqIHRlbGVvcCkuCisgKiBXYXJuaW5nOiBUaGlzIGlzIG5vdCBhbiBvZmZpY2lhbCB0aW1lIChzbyBpdCBjYW5ub3QgYmUgdXNlZCB0byBkaXNwdXRlIHJlZgorICogY2FsbHMgb3IgZ3VhcmFudGVlIHRoYXQgYSBmdW5jdGlvbgorICogd2lsbCB0cmlnZ2VyIGJlZm9yZSB0aGUgbWF0Y2ggZW5kcykKKyAqIFRoZSBQcmFjdGljZSBNYXRjaCBmdW5jdGlvbiBvZiB0aGUgRFMgYXBwcm94aW1hdGVzIHRoZSBiZWhhdmlvdXIgc2VlbiBvbiB0aGUKKyAqIGZpZWxkLgorICogQHJldHVybiBUaW1lIHJlbWFpbmluZyBpbiBjdXJyZW50IG1hdGNoIHBlcmlvZCAoYXV0byBvciB0ZWxlb3ApCisgKi8KK2RvdWJsZSBEcml2ZXJTdGF0aW9uOjpHZXRNYXRjaFRpbWUoKSBjb25zdCB7CisgIGZsb2F0IG1hdGNoVGltZTsKKyAgSEFMR2V0TWF0Y2hUaW1lKCZtYXRjaFRpbWUpOworICByZXR1cm4gKGRvdWJsZSltYXRjaFRpbWU7Cit9CisKKy8qKgorICogUmVwb3J0IGFuIGVycm9yIHRvIHRoZSBEcml2ZXJTdGF0aW9uIG1lc3NhZ2VzIHdpbmRvdy4KKyAqIFRoZSBlcnJvciBpcyBhbHNvIHByaW50ZWQgdG8gdGhlIHByb2dyYW0gY29uc29sZS4KKyAqLwordm9pZCBEcml2ZXJTdGF0aW9uOjpSZXBvcnRFcnJvcihzdGQ6OnN0cmluZyBlcnJvcikgeworICBzdGQ6OmNvdXQgPDwgZXJyb3IgPDwgc3RkOjplbmRsOworCisgIEhBTENvbnRyb2xXb3JkIGNvbnRyb2xXb3JkOworICBIQUxHZXRDb250cm9sV29yZCgmY29udHJvbFdvcmQpOworICBpZiAoY29udHJvbFdvcmQuZHNBdHRhY2hlZCkgeworICAgIEhBTFNldEVycm9yRGF0YShlcnJvci5jX3N0cigpLCBlcnJvci5zaXplKCksIDApOworICB9Cit9CmRpZmYgLS1naXQgYS93cGlsaWJjL0F0aGVuYS9zcmMvRW5jb2Rlci5jcHAgYi93cGlsaWJjL0F0aGVuYS9zcmMvRW5jb2Rlci5jcHAKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMGZhMTJkZgotLS0gL2Rldi9udWxsCisrKyBiL3dwaWxpYmMvQXRoZW5hL3NyYy9FbmNvZGVyLmNwcApAQCAtMCwwICsxLDU2MSBAQAorLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi8KKy8qIENvcHlyaWdodCAoYykgRklSU1QgMjAwOC4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KKyAqLworLyogT3BlbiBTb3VyY2UgU29mdHdhcmUgLSBtYXkgYmUgbW9kaWZpZWQgYW5kIHNoYXJlZCBieSBGUkMgdGVhbXMuIFRoZSBjb2RlICAgKi8KKy8qIG11c3QgYmUgYWNjb21wYW5pZWQgYnkgdGhlIEZJUlNUIEJTRCBsaWNlbnNlIGZpbGUgaW4gJChXSU5EX0JBU0UpL1dQSUxpYi4gICovCisvKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qLworCisjaW5jbHVkZSAiRW5jb2Rlci5oIgorI2luY2x1ZGUgIkRpZ2l0YWxJbnB1dC5oIgorI2luY2x1ZGUgIlJlc291cmNlLmgiCisjaW5jbHVkZSAiV1BJRXJyb3JzLmgiCisjaW5jbHVkZSAiTGl2ZVdpbmRvdy9MaXZlV2luZG93LmgiCisKKy8qKgorICogQ29tbW9uIGluaXRpYWxpemF0aW9uIGNvZGUgZm9yIEVuY29kZXJzLgorICogVGhpcyBjb2RlIGFsbG9jYXRlcyByZXNvdXJjZXMgZm9yIEVuY29kZXJzIGFuZCBpcyBjb21tb24gdG8gYWxsIGNvbnN0cnVjdG9ycy4KKyAqCisgKiBUaGUgY291bnRlciB3aWxsIHN0YXJ0IGNvdW50aW5nIGltbWVkaWF0ZWx5LgorICoKKyAqIEBwYXJhbSByZXZlcnNlRGlyZWN0aW9uIElmIHRydWUsIGNvdW50cyBkb3duIGluc3RlYWQgb2YgdXAgKHRoaXMgaXMgYWxsCisgKiByZWxhdGl2ZSkKKyAqIEBwYXJhbSBlbmNvZGluZ1R5cGUgZWl0aGVyIGsxWCwgazJYLCBvciBrNFggdG8gaW5kaWNhdGUgMVgsIDJYIG9yIDRYCisgKiBkZWNvZGluZy4gSWYgNFggaXMKKyAqIHNlbGVjdGVkLCB0aGVuIGFuIGVuY29kZXIgRlBHQSBvYmplY3QgaXMgdXNlZCBhbmQgdGhlIHJldHVybmVkIGNvdW50cyB3aWxsIGJlCisgKiA0eCB0aGUgZW5jb2RlcgorICogc3BlYydkIHZhbHVlIHNpbmNlIGFsbCByaXNpbmcgYW5kIGZhbGxpbmcgZWRnZXMgYXJlIGNvdW50ZWQuIElmIDFYIG9yIDJYIGFyZQorICogc2VsZWN0ZWQgdGhlbgorICogYSBjb3VudGVyIG9iamVjdCB3aWxsIGJlIHVzZWQgYW5kIHRoZSByZXR1cm5lZCB2YWx1ZSB3aWxsIGVpdGhlciBleGFjdGx5CisgKiBtYXRjaCB0aGUgc3BlYydkIGNvdW50CisgKiBvciBiZSBkb3VibGUgKDJ4KSB0aGUgc3BlYydkIGNvdW50LgorICovCit2b2lkIEVuY29kZXI6OkluaXRFbmNvZGVyKGJvb2wgcmV2ZXJzZURpcmVjdGlvbiwgRW5jb2RpbmdUeXBlIGVuY29kaW5nVHlwZSkgeworICBtX2VuY29kaW5nVHlwZSA9IGVuY29kaW5nVHlwZTsKKyAgc3dpdGNoIChlbmNvZGluZ1R5cGUpIHsKKyAgICBjYXNlIGs0WDogeworICAgICAgbV9lbmNvZGluZ1NjYWxlID0gNDsKKyAgICAgIGlmIChtX2FTb3VyY2UtPlN0YXR1c0lzRmF0YWwoKSkgeworICAgICAgICBDbG9uZUVycm9yKCptX2FTb3VyY2UpOworICAgICAgICByZXR1cm47CisgICAgICB9CisgICAgICBpZiAobV9iU291cmNlLT5TdGF0dXNJc0ZhdGFsKCkpIHsKKyAgICAgICAgQ2xvbmVFcnJvcigqbV9iU291cmNlKTsKKyAgICAgICAgcmV0dXJuOworICAgICAgfQorICAgICAgaW50MzJfdCBzdGF0dXMgPSAwOworICAgICAgbV9lbmNvZGVyID0gaW5pdGlhbGl6ZUVuY29kZXIoCisgICAgICAgICAgbV9hU291cmNlLT5HZXRNb2R1bGVGb3JSb3V0aW5nKCksIG1fYVNvdXJjZS0+R2V0Q2hhbm5lbEZvclJvdXRpbmcoKSwKKyAgICAgICAgICBtX2FTb3VyY2UtPkdldEFuYWxvZ1RyaWdnZXJGb3JSb3V0aW5nKCksCisgICAgICAgICAgbV9iU291cmNlLT5HZXRNb2R1bGVGb3JSb3V0aW5nKCksIG1fYlNvdXJjZS0+R2V0Q2hhbm5lbEZvclJvdXRpbmcoKSwKKyAgICAgICAgICBtX2JTb3VyY2UtPkdldEFuYWxvZ1RyaWdnZXJGb3JSb3V0aW5nKCksIHJldmVyc2VEaXJlY3Rpb24sICZtX2luZGV4LAorICAgICAgICAgICZzdGF0dXMpOworICAgICAgd3BpX3NldEVycm9yV2l0aENvbnRleHQoc3RhdHVzLCBnZXRIQUxFcnJvck1lc3NhZ2Uoc3RhdHVzKSk7CisgICAgICBtX2NvdW50ZXIgPSBudWxscHRyOworICAgICAgU2V0TWF4UGVyaW9kKC41KTsKKyAgICAgIGJyZWFrOworICAgIH0KKyAgICBjYXNlIGsxWDoKKyAgICBjYXNlIGsyWDogeworICAgICAgbV9lbmNvZGluZ1NjYWxlID0gZW5jb2RpbmdUeXBlID09IGsxWCA/IDEgOiAyOworICAgICAgbV9jb3VudGVyID0gc3RkOjptYWtlX3VuaXF1ZTxDb3VudGVyPihtX2VuY29kaW5nVHlwZSwgbV9hU291cmNlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1fYlNvdXJjZSwgcmV2ZXJzZURpcmVjdGlvbik7CisgICAgICBtX2luZGV4ID0gbV9jb3VudGVyLT5HZXRGUEdBSW5kZXgoKTsKKyAgICAgIGJyZWFrOworICAgIH0KKyAgICBkZWZhdWx0OgorICAgICAgd3BpX3NldEVycm9yV2l0aENvbnRleHQoLTEsICJJbnZhbGlkIGVuY29kaW5nVHlwZSBhcmd1bWVudCIpOworICAgICAgYnJlYWs7CisgIH0KKworICBIQUxSZXBvcnQoSEFMVXNhZ2VSZXBvcnRpbmc6OmtSZXNvdXJjZVR5cGVfRW5jb2RlciwgbV9pbmRleCwgZW5jb2RpbmdUeXBlKTsKKyAgTGl2ZVdpbmRvdzo6R2V0SW5zdGFuY2UoKS0+QWRkU2Vuc29yKCJFbmNvZGVyIiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1fYVNvdXJjZS0+R2V0Q2hhbm5lbEZvclJvdXRpbmcoKSwgdGhpcyk7Cit9CisKKy8qKgorICogRW5jb2RlciBjb25zdHJ1Y3Rvci4KKyAqIENvbnN0cnVjdCBhIEVuY29kZXIgZ2l2ZW4gYSBhbmQgYiBjaGFubmVscy4KKyAqCisgKiBUaGUgY291bnRlciB3aWxsIHN0YXJ0IGNvdW50aW5nIGltbWVkaWF0ZWx5LgorICoKKyAqIEBwYXJhbSBhQ2hhbm5lbCBUaGUgYSBjaGFubmVsIERJTyBjaGFubmVsLiAwLTkgYXJlIG9uLWJvYXJkLCAxMC0yNSBhcmUgb24gdGhlCisgKiBNWFAgcG9ydAorICogQHBhcmFtIGJDaGFubmVsIFRoZSBiIGNoYW5uZWwgRElPIGNoYW5uZWwuIDAtOSBhcmUgb24tYm9hcmQsIDEwLTI1IGFyZSBvbiB0aGUKKyAqIE1YUCBwb3J0CisgKiBAcGFyYW0gcmV2ZXJzZURpcmVjdGlvbiByZXByZXNlbnRzIHRoZSBvcmllbnRhdGlvbiBvZiB0aGUgZW5jb2RlciBhbmQgaW52ZXJ0cworICogdGhlIG91dHB1dCB2YWx1ZXMKKyAqIGlmIG5lY2Vzc2FyeSBzbyBmb3J3YXJkIHJlcHJlc2VudHMgcG9zaXRpdmUgdmFsdWVzLgorICogQHBhcmFtIGVuY29kaW5nVHlwZSBlaXRoZXIgazFYLCBrMlgsIG9yIGs0WCB0byBpbmRpY2F0ZSAxWCwgMlggb3IgNFgKKyAqIGRlY29kaW5nLiBJZiA0WCBpcworICogc2VsZWN0ZWQsIHRoZW4gYW4gZW5jb2RlciBGUEdBIG9iamVjdCBpcyB1c2VkIGFuZCB0aGUgcmV0dXJuZWQgY291bnRzIHdpbGwgYmUKKyAqIDR4IHRoZSBlbmNvZGVyCisgKiBzcGVjJ2QgdmFsdWUgc2luY2UgYWxsIHJpc2luZyBhbmQgZmFsbGluZyBlZGdlcyBhcmUgY291bnRlZC4gSWYgMVggb3IgMlggYXJlCisgKiBzZWxlY3RlZCB0aGVuCisgKiBhIGNvdW50ZXIgb2JqZWN0IHdpbGwgYmUgdXNlZCBhbmQgdGhlIHJldHVybmVkIHZhbHVlIHdpbGwgZWl0aGVyIGV4YWN0bHkKKyAqIG1hdGNoIHRoZSBzcGVjJ2QgY291bnQKKyAqIG9yIGJlIGRvdWJsZSAoMngpIHRoZSBzcGVjJ2QgY291bnQuCisgKi8KK0VuY29kZXI6OkVuY29kZXIodWludDMyX3QgYUNoYW5uZWwsIHVpbnQzMl90IGJDaGFubmVsLCBib29sIHJldmVyc2VEaXJlY3Rpb24sCisgICAgICAgICAgICAgICAgIEVuY29kaW5nVHlwZSBlbmNvZGluZ1R5cGUpIHsKKyAgbV9hU291cmNlID0gc3RkOjptYWtlX3NoYXJlZDxEaWdpdGFsSW5wdXQ+KGFDaGFubmVsKTsKKyAgbV9iU291cmNlID0gc3RkOjptYWtlX3NoYXJlZDxEaWdpdGFsSW5wdXQ+KGJDaGFubmVsKTsKKyAgSW5pdEVuY29kZXIocmV2ZXJzZURpcmVjdGlvbiwgZW5jb2RpbmdUeXBlKTsKK30KKworLyoqCisgKiBFbmNvZGVyIGNvbnN0cnVjdG9yLgorICogQ29uc3RydWN0IGEgRW5jb2RlciBnaXZlbiBhIGFuZCBiIGNoYW5uZWxzIGFzIGRpZ2l0YWwgaW5wdXRzLiBUaGlzIGlzIHVzZWQgaW4KKyAqIHRoZSBjYXNlIHdoZXJlIHRoZSBkaWdpdGFsIGlucHV0cyBhcmUgc2hhcmVkLiBUaGUgRW5jb2RlciBjbGFzcyB3aWxsIG5vdAorICogYWxsb2NhdGUgdGhlIGRpZ2l0YWwgaW5wdXRzIGFuZCBhc3N1bWUgdGhhdCB0aGV5IGFscmVhZHkgYXJlIGNvdW50ZWQuCisgKiBUaGUgY291bnRlciB3aWxsIHN0YXJ0IGNvdW50aW5nIGltbWVkaWF0ZWx5LgorICoKKyAqIEBwYXJhbSBhU291cmNlIFRoZSBzb3VyY2UgdGhhdCBzaG91bGQgYmUgdXNlZCBmb3IgdGhlIGEgY2hhbm5lbC4KKyAqIEBwYXJhbSBiU291cmNlIHRoZSBzb3VyY2UgdGhhdCBzaG91bGQgYmUgdXNlZCBmb3IgdGhlIGIgY2hhbm5lbC4KKyAqIEBwYXJhbSByZXZlcnNlRGlyZWN0aW9uIHJlcHJlc2VudHMgdGhlIG9yaWVudGF0aW9uIG9mIHRoZSBlbmNvZGVyIGFuZCBpbnZlcnRzCisgKiB0aGUgb3V0cHV0IHZhbHVlcworICogaWYgbmVjZXNzYXJ5IHNvIGZvcndhcmQgcmVwcmVzZW50cyBwb3NpdGl2ZSB2YWx1ZXMuCisgKiBAcGFyYW0gZW5jb2RpbmdUeXBlIGVpdGhlciBrMVgsIGsyWCwgb3IgazRYIHRvIGluZGljYXRlIDFYLCAyWCBvciA0WAorICogZGVjb2RpbmcuIElmIDRYIGlzCisgKiBzZWxlY3RlZCwgdGhlbiBhbiBlbmNvZGVyIEZQR0Egb2JqZWN0IGlzIHVzZWQgYW5kIHRoZSByZXR1cm5lZCBjb3VudHMgd2lsbCBiZQorICogNHggdGhlIGVuY29kZXIKKyAqIHNwZWMnZCB2YWx1ZSBzaW5jZSBhbGwgcmlzaW5nIGFuZCBmYWxsaW5nIGVkZ2VzIGFyZSBjb3VudGVkLiBJZiAxWCBvciAyWCBhcmUKKyAqIHNlbGVjdGVkIHRoZW4KKyAqIGEgY291bnRlciBvYmplY3Qgd2lsbCBiZSB1c2VkIGFuZCB0aGUgcmV0dXJuZWQgdmFsdWUgd2lsbCBlaXRoZXIgZXhhY3RseQorICogbWF0Y2ggdGhlIHNwZWMnZCBjb3VudAorICogb3IgYmUgZG91YmxlICgyeCkgdGhlIHNwZWMnZCBjb3VudC4KKyAqLworRW5jb2Rlcjo6RW5jb2RlcihEaWdpdGFsU291cmNlICphU291cmNlLCBEaWdpdGFsU291cmNlICpiU291cmNlLAorICAgICAgICAgICAgICAgICBib29sIHJldmVyc2VEaXJlY3Rpb24sIEVuY29kaW5nVHlwZSBlbmNvZGluZ1R5cGUpCisgICAgOiBtX2FTb3VyY2UoYVNvdXJjZSwgTnVsbERlbGV0ZXI8RGlnaXRhbFNvdXJjZT4oKSksCisgICAgICBtX2JTb3VyY2UoYlNvdXJjZSwgTnVsbERlbGV0ZXI8RGlnaXRhbFNvdXJjZT4oKSkgeworICBpZiAobV9hU291cmNlID09IG51bGxwdHIgfHwgbV9iU291cmNlID09IG51bGxwdHIpCisgICAgd3BpX3NldFdQSUVycm9yKE51bGxQYXJhbWV0ZXIpOworICBlbHNlCisgICAgSW5pdEVuY29kZXIocmV2ZXJzZURpcmVjdGlvbiwgZW5jb2RpbmdUeXBlKTsKK30KKworRW5jb2Rlcjo6RW5jb2RlcihzdGQ6OnNoYXJlZF9wdHI8RGlnaXRhbFNvdXJjZT4gYVNvdXJjZSwKKyAgICAgICAgICAgICAgICAgc3RkOjpzaGFyZWRfcHRyPERpZ2l0YWxTb3VyY2U+IGJTb3VyY2UsCisgICAgICAgICAgICAgICAgIGJvb2wgcmV2ZXJzZURpcmVjdGlvbiwgRW5jb2RpbmdUeXBlIGVuY29kaW5nVHlwZSkKKyAgICA6IG1fYVNvdXJjZShhU291cmNlKSwgbV9iU291cmNlKGJTb3VyY2UpIHsKKyAgaWYgKG1fYVNvdXJjZSA9PSBudWxscHRyIHx8IG1fYlNvdXJjZSA9PSBudWxscHRyKQorICAgIHdwaV9zZXRXUElFcnJvcihOdWxsUGFyYW1ldGVyKTsKKyAgZWxzZQorICAgIEluaXRFbmNvZGVyKHJldmVyc2VEaXJlY3Rpb24sIGVuY29kaW5nVHlwZSk7Cit9CisKKy8qKgorICogRW5jb2RlciBjb25zdHJ1Y3Rvci4KKyAqIENvbnN0cnVjdCBhIEVuY29kZXIgZ2l2ZW4gYSBhbmQgYiBjaGFubmVscyBhcyBkaWdpdGFsIGlucHV0cy4gVGhpcyBpcyB1c2VkIGluCisgKiB0aGUgY2FzZQorICogd2hlcmUgdGhlIGRpZ2l0YWwgaW5wdXRzIGFyZSBzaGFyZWQuIFRoZSBFbmNvZGVyIGNsYXNzIHdpbGwgbm90IGFsbG9jYXRlIHRoZQorICogZGlnaXRhbCBpbnB1dHMKKyAqIGFuZCBhc3N1bWUgdGhhdCB0aGV5IGFscmVhZHkgYXJlIGNvdW50ZWQuCisgKgorICogVGhlIGNvdW50ZXIgd2lsbCBzdGFydCBjb3VudGluZyBpbW1lZGlhdGVseS4KKyAqCisgKiBAcGFyYW0gYVNvdXJjZSBUaGUgc291cmNlIHRoYXQgc2hvdWxkIGJlIHVzZWQgZm9yIHRoZSBhIGNoYW5uZWwuCisgKiBAcGFyYW0gYlNvdXJjZSB0aGUgc291cmNlIHRoYXQgc2hvdWxkIGJlIHVzZWQgZm9yIHRoZSBiIGNoYW5uZWwuCisgKiBAcGFyYW0gcmV2ZXJzZURpcmVjdGlvbiByZXByZXNlbnRzIHRoZSBvcmllbnRhdGlvbiBvZiB0aGUgZW5jb2RlciBhbmQgaW52ZXJ0cworICogdGhlIG91dHB1dCB2YWx1ZXMKKyAqIGlmIG5lY2Vzc2FyeSBzbyBmb3J3YXJkIHJlcHJlc2VudHMgcG9zaXRpdmUgdmFsdWVzLgorICogQHBhcmFtIGVuY29kaW5nVHlwZSBlaXRoZXIgazFYLCBrMlgsIG9yIGs0WCB0byBpbmRpY2F0ZSAxWCwgMlggb3IgNFgKKyAqIGRlY29kaW5nLiBJZiA0WCBpcworICogc2VsZWN0ZWQsIHRoZW4gYW4gZW5jb2RlciBGUEdBIG9iamVjdCBpcyB1c2VkIGFuZCB0aGUgcmV0dXJuZWQgY291bnRzIHdpbGwgYmUKKyAqIDR4IHRoZSBlbmNvZGVyCisgKiBzcGVjJ2QgdmFsdWUgc2luY2UgYWxsIHJpc2luZyBhbmQgZmFsbGluZyBlZGdlcyBhcmUgY291bnRlZC4gSWYgMVggb3IgMlggYXJlCisgKiBzZWxlY3RlZCB0aGVuCisgKiBhIGNvdW50ZXIgb2JqZWN0IHdpbGwgYmUgdXNlZCBhbmQgdGhlIHJldHVybmVkIHZhbHVlIHdpbGwgZWl0aGVyIGV4YWN0bHkKKyAqIG1hdGNoIHRoZSBzcGVjJ2QgY291bnQKKyAqIG9yIGJlIGRvdWJsZSAoMngpIHRoZSBzcGVjJ2QgY291bnQuCisgKi8KK0VuY29kZXI6OkVuY29kZXIoRGlnaXRhbFNvdXJjZSAmYVNvdXJjZSwgRGlnaXRhbFNvdXJjZSAmYlNvdXJjZSwKKyAgICAgICAgICAgICAgICAgYm9vbCByZXZlcnNlRGlyZWN0aW9uLCBFbmNvZGluZ1R5cGUgZW5jb2RpbmdUeXBlKQorICAgIDogbV9hU291cmNlKCZhU291cmNlLCBOdWxsRGVsZXRlcjxEaWdpdGFsU291cmNlPigpKSwKKyAgICAgIG1fYlNvdXJjZSgmYlNvdXJjZSwgTnVsbERlbGV0ZXI8RGlnaXRhbFNvdXJjZT4oKSkKK3sKKyAgSW5pdEVuY29kZXIocmV2ZXJzZURpcmVjdGlvbiwgZW5jb2RpbmdUeXBlKTsKK30KKworLyoqCisgKiBGcmVlIHRoZSByZXNvdXJjZXMgZm9yIGFuIEVuY29kZXIuCisgKiBGcmVlcyB0aGUgRlBHQSByZXNvdXJjZXMgYXNzb2NpYXRlZCB3aXRoIGFuIEVuY29kZXIuCisgKi8KK0VuY29kZXI6On5FbmNvZGVyKCkgeworICBpZiAoIW1fY291bnRlcikgeworICAgIGludDMyX3Qgc3RhdHVzID0gMDsKKyAgICBmcmVlRW5jb2RlcihtX2VuY29kZXIsICZzdGF0dXMpOworICAgIHdwaV9zZXRFcnJvcldpdGhDb250ZXh0KHN0YXR1cywgZ2V0SEFMRXJyb3JNZXNzYWdlKHN0YXR1cykpOworICB9Cit9CisKKy8qKgorICogVGhlIGVuY29kaW5nIHNjYWxlIGZhY3RvciAxeCwgMngsIG9yIDR4LCBwZXIgdGhlIHJlcXVlc3RlZCBlbmNvZGluZ1R5cGUuCisgKiBVc2VkIHRvIGRpdmlkZSByYXcgZWRnZSBjb3VudHMgZG93biB0byBzcGVjJ2QgY291bnRzLgorICovCitpbnQzMl90IEVuY29kZXI6OkdldEVuY29kaW5nU2NhbGUoKSBjb25zdCB7IHJldHVybiBtX2VuY29kaW5nU2NhbGU7IH0KKworLyoqCisgKiBHZXRzIHRoZSByYXcgdmFsdWUgZnJvbSB0aGUgZW5jb2Rlci4KKyAqIFRoZSByYXcgdmFsdWUgaXMgdGhlIGFjdHVhbCBjb3VudCB1bnNjYWxlZCBieSB0aGUgMXgsIDJ4LCBvciA0eCBzY2FsZQorICogZmFjdG9yLgorICogQHJldHVybiBDdXJyZW50IHJhdyBjb3VudCBmcm9tIHRoZSBlbmNvZGVyCisgKi8KK2ludDMyX3QgRW5jb2Rlcjo6R2V0UmF3KCkgY29uc3QgeworICBpZiAoU3RhdHVzSXNGYXRhbCgpKSByZXR1cm4gMDsKKyAgaW50MzJfdCB2YWx1ZTsKKyAgaWYgKG1fY291bnRlcikKKyAgICB2YWx1ZSA9IG1fY291bnRlci0+R2V0KCk7CisgIGVsc2UgeworICAgIGludDMyX3Qgc3RhdHVzID0gMDsKKyAgICB2YWx1ZSA9IGdldEVuY29kZXIobV9lbmNvZGVyLCAmc3RhdHVzKTsKKyAgICB3cGlfc2V0RXJyb3JXaXRoQ29udGV4dChzdGF0dXMsIGdldEhBTEVycm9yTWVzc2FnZShzdGF0dXMpKTsKKyAgfQorICByZXR1cm4gdmFsdWU7Cit9CisKKy8qKgorICogR2V0cyB0aGUgY3VycmVudCBjb3VudC4KKyAqIFJldHVybnMgdGhlIGN1cnJlbnQgY291bnQgb24gdGhlIEVuY29kZXIuCisgKiBUaGlzIG1ldGhvZCBjb21wZW5zYXRlcyBmb3IgdGhlIGRlY29kaW5nIHR5cGUuCisgKgorICogQHJldHVybiBDdXJyZW50IGNvdW50IGZyb20gdGhlIEVuY29kZXIgYWRqdXN0ZWQgZm9yIHRoZSAxeCwgMngsIG9yIDR4IHNjYWxlCisgKiBmYWN0b3IuCisgKi8KK2ludDMyX3QgRW5jb2Rlcjo6R2V0KCkgY29uc3QgeworICBpZiAoU3RhdHVzSXNGYXRhbCgpKSByZXR1cm4gMDsKKyAgcmV0dXJuIChpbnQzMl90KShHZXRSYXcoKSAqIERlY29kaW5nU2NhbGVGYWN0b3IoKSk7Cit9CisKKy8qKgorICogUmVzZXQgdGhlIEVuY29kZXIgZGlzdGFuY2UgdG8gemVyby4KKyAqIFJlc2V0cyB0aGUgY3VycmVudCBjb3VudCB0byB6ZXJvIG9uIHRoZSBlbmNvZGVyLgorICovCit2b2lkIEVuY29kZXI6OlJlc2V0KCkgeworICBpZiAoU3RhdHVzSXNGYXRhbCgpKSByZXR1cm47CisgIGlmIChtX2NvdW50ZXIpCisgICAgbV9jb3VudGVyLT5SZXNldCgpOworICBlbHNlIHsKKyAgICBpbnQzMl90IHN0YXR1cyA9IDA7CisgICAgcmVzZXRFbmNvZGVyKG1fZW5jb2RlciwgJnN0YXR1cyk7CisgICAgd3BpX3NldEVycm9yV2l0aENvbnRleHQoc3RhdHVzLCBnZXRIQUxFcnJvck1lc3NhZ2Uoc3RhdHVzKSk7CisgIH0KK30KKworLyoqCisgKiBSZXR1cm5zIHRoZSBwZXJpb2Qgb2YgdGhlIG1vc3QgcmVjZW50IHB1bHNlLgorICogUmV0dXJucyB0aGUgcGVyaW9kIG9mIHRoZSBtb3N0IHJlY2VudCBFbmNvZGVyIHB1bHNlIGluIHNlY29uZHMuCisgKiBUaGlzIG1ldGhvZCBjb21wZW5zYXRlcyBmb3IgdGhlIGRlY29kaW5nIHR5cGUuCisgKgorICogQGRlcHJlY2F0ZWQgVXNlIEdldFJhdGUoKSBpbiBmYXZvciBvZiB0aGlzIG1ldGhvZC4gIFRoaXMgcmV0dXJucyB1bnNjYWxlZAorICogcGVyaW9kcyBhbmQgR2V0UmF0ZSgpIHNjYWxlcyB1c2luZyB2YWx1ZSBmcm9tIFNldERpc3RhbmNlUGVyUHVsc2UoKS4KKyAqCisgKiBAcmV0dXJuIFBlcmlvZCBpbiBzZWNvbmRzIG9mIHRoZSBtb3N0IHJlY2VudCBwdWxzZS4KKyAqLworZG91YmxlIEVuY29kZXI6OkdldFBlcmlvZCgpIGNvbnN0IHsKKyAgaWYgKFN0YXR1c0lzRmF0YWwoKSkgcmV0dXJuIDAuMDsKKyAgaWYgKG1fY291bnRlcikgeworICAgIHJldHVybiBtX2NvdW50ZXItPkdldFBlcmlvZCgpIC8gRGVjb2RpbmdTY2FsZUZhY3RvcigpOworICB9IGVsc2UgeworICAgIGludDMyX3Qgc3RhdHVzID0gMDsKKyAgICBkb3VibGUgcGVyaW9kID0gZ2V0RW5jb2RlclBlcmlvZChtX2VuY29kZXIsICZzdGF0dXMpOworICAgIHdwaV9zZXRFcnJvcldpdGhDb250ZXh0KHN0YXR1cywgZ2V0SEFMRXJyb3JNZXNzYWdlKHN0YXR1cykpOworICAgIHJldHVybiBwZXJpb2Q7CisgIH0KK30KKworLyoqCisgKiBTZXRzIHRoZSBtYXhpbXVtIHBlcmlvZCBmb3Igc3RvcHBlZCBkZXRlY3Rpb24uCisgKiBTZXRzIHRoZSB2YWx1ZSB0aGF0IHJlcHJlc2VudHMgdGhlIG1heGltdW0gcGVyaW9kIG9mIHRoZSBFbmNvZGVyIGJlZm9yZSBpdAorICogd2lsbCBhc3N1bWUKKyAqIHRoYXQgdGhlIGF0dGFjaGVkIGRldmljZSBpcyBzdG9wcGVkLiBUaGlzIHRpbWVvdXQgYWxsb3dzIHVzZXJzIHRvIGRldGVybWluZQorICogaWYgdGhlIHdoZWVscyBvcgorICogb3RoZXIgc2hhZnQgaGFzIHN0b3BwZWQgcm90YXRpbmcuCisgKiBUaGlzIG1ldGhvZCBjb21wZW5zYXRlcyBmb3IgdGhlIGRlY29kaW5nIHR5cGUuCisgKgorICogQGRlcHJlY2F0ZWQgVXNlIFNldE1pblJhdGUoKSBpbiBmYXZvciBvZiB0aGlzIG1ldGhvZC4gIFRoaXMgdGFrZXMgdW5zY2FsZWQKKyAqIHBlcmlvZHMgYW5kIFNldE1pblJhdGUoKSBzY2FsZXMgdXNpbmcgdmFsdWUgZnJvbSBTZXREaXN0YW5jZVBlclB1bHNlKCkuCisgKgorICogQHBhcmFtIG1heFBlcmlvZCBUaGUgbWF4aW11bSB0aW1lIGJldHdlZW4gcmlzaW5nIGFuZCBmYWxsaW5nIGVkZ2VzIGJlZm9yZSB0aGUKKyAqIEZQR0Egd2lsbAorICogcmVwb3J0IHRoZSBkZXZpY2Ugc3RvcHBlZC4gVGhpcyBpcyBleHByZXNzZWQgaW4gc2Vjb25kcy4KKyAqLwordm9pZCBFbmNvZGVyOjpTZXRNYXhQZXJpb2QoZG91YmxlIG1heFBlcmlvZCkgeworICBpZiAoU3RhdHVzSXNGYXRhbCgpKSByZXR1cm47CisgIGlmIChtX2NvdW50ZXIpIHsKKyAgICBtX2NvdW50ZXItPlNldE1heFBlcmlvZChtYXhQZXJpb2QgKiBEZWNvZGluZ1NjYWxlRmFjdG9yKCkpOworICB9IGVsc2UgeworICAgIGludDMyX3Qgc3RhdHVzID0gMDsKKyAgICBzZXRFbmNvZGVyTWF4UGVyaW9kKG1fZW5jb2RlciwgbWF4UGVyaW9kLCAmc3RhdHVzKTsKKyAgICB3cGlfc2V0RXJyb3JXaXRoQ29udGV4dChzdGF0dXMsIGdldEhBTEVycm9yTWVzc2FnZShzdGF0dXMpKTsKKyAgfQorfQorCisvKioKKyAqIERldGVybWluZSBpZiB0aGUgZW5jb2RlciBpcyBzdG9wcGVkLgorICogVXNpbmcgdGhlIE1heFBlcmlvZCB2YWx1ZSwgYSBib29sZWFuIGlzIHJldHVybmVkIHRoYXQgaXMgdHJ1ZSBpZiB0aGUgZW5jb2RlcgorICogaXMgY29uc2lkZXJlZAorICogc3RvcHBlZCBhbmQgZmFsc2UgaWYgaXQgaXMgc3RpbGwgbW92aW5nLiBBIHN0b3BwZWQgZW5jb2RlciBpcyBvbmUgd2hlcmUgdGhlCisgKiBtb3N0IHJlY2VudCBwdWxzZQorICogd2lkdGggZXhjZWVkcyB0aGUgTWF4UGVyaW9kLgorICogQHJldHVybiBUcnVlIGlmIHRoZSBlbmNvZGVyIGlzIGNvbnNpZGVyZWQgc3RvcHBlZC4KKyAqLworYm9vbCBFbmNvZGVyOjpHZXRTdG9wcGVkKCkgY29uc3QgeworICBpZiAoU3RhdHVzSXNGYXRhbCgpKSByZXR1cm4gdHJ1ZTsKKyAgaWYgKG1fY291bnRlcikgeworICAgIHJldHVybiBtX2NvdW50ZXItPkdldFN0b3BwZWQoKTsKKyAgfSBlbHNlIHsKKyAgICBpbnQzMl90IHN0YXR1cyA9IDA7CisgICAgYm9vbCB2YWx1ZSA9IGdldEVuY29kZXJTdG9wcGVkKG1fZW5jb2RlciwgJnN0YXR1cyk7CisgICAgd3BpX3NldEVycm9yV2l0aENvbnRleHQoc3RhdHVzLCBnZXRIQUxFcnJvck1lc3NhZ2Uoc3RhdHVzKSk7CisgICAgcmV0dXJuIHZhbHVlOworICB9Cit9CisKKy8qKgorICogVGhlIGxhc3QgZGlyZWN0aW9uIHRoZSBlbmNvZGVyIHZhbHVlIGNoYW5nZWQuCisgKiBAcmV0dXJuIFRoZSBsYXN0IGRpcmVjdGlvbiB0aGUgZW5jb2RlciB2YWx1ZSBjaGFuZ2VkLgorICovCitib29sIEVuY29kZXI6OkdldERpcmVjdGlvbigpIGNvbnN0IHsKKyAgaWYgKFN0YXR1c0lzRmF0YWwoKSkgcmV0dXJuIGZhbHNlOworICBpZiAobV9jb3VudGVyKSB7CisgICAgcmV0dXJuIG1fY291bnRlci0+R2V0RGlyZWN0aW9uKCk7CisgIH0gZWxzZSB7CisgICAgaW50MzJfdCBzdGF0dXMgPSAwOworICAgIGJvb2wgdmFsdWUgPSBnZXRFbmNvZGVyRGlyZWN0aW9uKG1fZW5jb2RlciwgJnN0YXR1cyk7CisgICAgd3BpX3NldEVycm9yV2l0aENvbnRleHQoc3RhdHVzLCBnZXRIQUxFcnJvck1lc3NhZ2Uoc3RhdHVzKSk7CisgICAgcmV0dXJuIHZhbHVlOworICB9Cit9CisKKy8qKgorICogVGhlIHNjYWxlIG5lZWRlZCB0byBjb252ZXJ0IGEgcmF3IGNvdW50ZXIgdmFsdWUgaW50byBhIG51bWJlciBvZiBlbmNvZGVyCisgKiBwdWxzZXMuCisgKi8KK2RvdWJsZSBFbmNvZGVyOjpEZWNvZGluZ1NjYWxlRmFjdG9yKCkgY29uc3QgeworICBpZiAoU3RhdHVzSXNGYXRhbCgpKSByZXR1cm4gMC4wOworICBzd2l0Y2ggKG1fZW5jb2RpbmdUeXBlKSB7CisgICAgY2FzZSBrMVg6CisgICAgICByZXR1cm4gMS4wOworICAgIGNhc2UgazJYOgorICAgICAgcmV0dXJuIDAuNTsKKyAgICBjYXNlIGs0WDoKKyAgICAgIHJldHVybiAwLjI1OworICAgIGRlZmF1bHQ6CisgICAgICByZXR1cm4gMC4wOworICB9Cit9CisKKy8qKgorICogR2V0IHRoZSBkaXN0YW5jZSB0aGUgcm9ib3QgaGFzIGRyaXZlbiBzaW5jZSB0aGUgbGFzdCByZXNldC4KKyAqCisgKiBAcmV0dXJuIFRoZSBkaXN0YW5jZSBkcml2ZW4gc2luY2UgdGhlIGxhc3QgcmVzZXQgYXMgc2NhbGVkIGJ5IHRoZSB2YWx1ZSBmcm9tCisgKiBTZXREaXN0YW5jZVBlclB1bHNlKCkuCisgKi8KK2RvdWJsZSBFbmNvZGVyOjpHZXREaXN0YW5jZSgpIGNvbnN0IHsKKyAgaWYgKFN0YXR1c0lzRmF0YWwoKSkgcmV0dXJuIDAuMDsKKyAgcmV0dXJuIEdldFJhdygpICogRGVjb2RpbmdTY2FsZUZhY3RvcigpICogbV9kaXN0YW5jZVBlclB1bHNlOworfQorCisvKioKKyAqIEdldCB0aGUgY3VycmVudCByYXRlIG9mIHRoZSBlbmNvZGVyLgorICogVW5pdHMgYXJlIGRpc3RhbmNlIHBlciBzZWNvbmQgYXMgc2NhbGVkIGJ5IHRoZSB2YWx1ZSBmcm9tCisgKiBTZXREaXN0YW5jZVBlclB1bHNlKCkuCisgKgorICogQHJldHVybiBUaGUgY3VycmVudCByYXRlIG9mIHRoZSBlbmNvZGVyLgorICovCitkb3VibGUgRW5jb2Rlcjo6R2V0UmF0ZSgpIGNvbnN0IHsKKyAgaWYgKFN0YXR1c0lzRmF0YWwoKSkgcmV0dXJuIDAuMDsKKyAgcmV0dXJuIChtX2Rpc3RhbmNlUGVyUHVsc2UgLyBHZXRQZXJpb2QoKSk7Cit9CisKKy8qKgorICogU2V0IHRoZSBtaW5pbXVtIHJhdGUgb2YgdGhlIGRldmljZSBiZWZvcmUgdGhlIGhhcmR3YXJlIHJlcG9ydHMgaXQgc3RvcHBlZC4KKyAqCisgKiBAcGFyYW0gbWluUmF0ZSBUaGUgbWluaW11bSByYXRlLiAgVGhlIHVuaXRzIGFyZSBpbiBkaXN0YW5jZSBwZXIgc2Vjb25kIGFzCisgKiBzY2FsZWQgYnkgdGhlIHZhbHVlIGZyb20gU2V0RGlzdGFuY2VQZXJQdWxzZSgpLgorICovCit2b2lkIEVuY29kZXI6OlNldE1pblJhdGUoZG91YmxlIG1pblJhdGUpIHsKKyAgaWYgKFN0YXR1c0lzRmF0YWwoKSkgcmV0dXJuOworICBTZXRNYXhQZXJpb2QobV9kaXN0YW5jZVBlclB1bHNlIC8gbWluUmF0ZSk7Cit9CisKKy8qKgorICogU2V0IHRoZSBkaXN0YW5jZSBwZXIgcHVsc2UgZm9yIHRoaXMgZW5jb2Rlci4KKyAqIFRoaXMgc2V0cyB0aGUgbXVsdGlwbGllciB1c2VkIHRvIGRldGVybWluZSB0aGUgZGlzdGFuY2UgZHJpdmVuIGJhc2VkIG9uIHRoZQorICogY291bnQgdmFsdWUKKyAqIGZyb20gdGhlIGVuY29kZXIuCisgKiBEbyBub3QgaW5jbHVkZSB0aGUgZGVjb2RpbmcgdHlwZSBpbiB0aGlzIHNjYWxlLiAgVGhlIGxpYnJhcnkgYWxyZWFkeQorICogY29tcGVuc2F0ZXMgZm9yIHRoZSBkZWNvZGluZyB0eXBlLgorICogU2V0IHRoaXMgdmFsdWUgYmFzZWQgb24gdGhlIGVuY29kZXIncyByYXRlZCBQdWxzZXMgcGVyIFJldm9sdXRpb24gYW5kCisgKiBmYWN0b3IgaW4gZ2VhcmluZyByZWR1Y3Rpb25zIGZvbGxvd2luZyB0aGUgZW5jb2RlciBzaGFmdC4KKyAqIFRoaXMgZGlzdGFuY2UgY2FuIGJlIGluIGFueSB1bml0cyB5b3UgbGlrZSwgbGluZWFyIG9yIGFuZ3VsYXIuCisgKgorICogQHBhcmFtIGRpc3RhbmNlUGVyUHVsc2UgVGhlIHNjYWxlIGZhY3RvciB0aGF0IHdpbGwgYmUgdXNlZCB0byBjb252ZXJ0IHB1bHNlcworICogdG8gdXNlZnVsIHVuaXRzLgorICovCit2b2lkIEVuY29kZXI6OlNldERpc3RhbmNlUGVyUHVsc2UoZG91YmxlIGRpc3RhbmNlUGVyUHVsc2UpIHsKKyAgaWYgKFN0YXR1c0lzRmF0YWwoKSkgcmV0dXJuOworICBtX2Rpc3RhbmNlUGVyUHVsc2UgPSBkaXN0YW5jZVBlclB1bHNlOworfQorCisvKioKKyAqIFNldCB0aGUgZGlyZWN0aW9uIHNlbnNpbmcgZm9yIHRoaXMgZW5jb2Rlci4KKyAqIFRoaXMgc2V0cyB0aGUgZGlyZWN0aW9uIHNlbnNpbmcgb24gdGhlIGVuY29kZXIgc28gdGhhdCBpdCBjb3VsZCBjb3VudCBpbiB0aGUKKyAqIGNvcnJlY3QKKyAqIHNvZnR3YXJlIGRpcmVjdGlvbiByZWdhcmRsZXNzIG9mIHRoZSBtb3VudGluZy4KKyAqIEBwYXJhbSByZXZlcnNlRGlyZWN0aW9uIHRydWUgaWYgdGhlIGVuY29kZXIgZGlyZWN0aW9uIHNob3VsZCBiZSByZXZlcnNlZAorICovCit2b2lkIEVuY29kZXI6OlNldFJldmVyc2VEaXJlY3Rpb24oYm9vbCByZXZlcnNlRGlyZWN0aW9uKSB7CisgIGlmIChTdGF0dXNJc0ZhdGFsKCkpIHJldHVybjsKKyAgaWYgKG1fY291bnRlcikgeworICAgIG1fY291bnRlci0+U2V0UmV2ZXJzZURpcmVjdGlvbihyZXZlcnNlRGlyZWN0aW9uKTsKKyAgfSBlbHNlIHsKKyAgICBpbnQzMl90IHN0YXR1cyA9IDA7CisgICAgc2V0RW5jb2RlclJldmVyc2VEaXJlY3Rpb24obV9lbmNvZGVyLCByZXZlcnNlRGlyZWN0aW9uLCAmc3RhdHVzKTsKKyAgICB3cGlfc2V0RXJyb3JXaXRoQ29udGV4dChzdGF0dXMsIGdldEhBTEVycm9yTWVzc2FnZShzdGF0dXMpKTsKKyAgfQorfQorCisvKioKKyAqIFNldCB0aGUgU2FtcGxlcyB0byBBdmVyYWdlIHdoaWNoIHNwZWNpZmllcyB0aGUgbnVtYmVyIG9mIHNhbXBsZXMgb2YgdGhlIHRpbWVyCisgKiB0bworICogYXZlcmFnZSB3aGVuIGNhbGN1bGF0aW5nIHRoZSBwZXJpb2QuIFBlcmZvcm0gYXZlcmFnaW5nIHRvIGFjY291bnQgZm9yCisgKiBtZWNoYW5pY2FsIGltcGVyZmVjdGlvbnMgb3IgYXMgb3ZlcnNhbXBsaW5nIHRvIGluY3JlYXNlIHJlc29sdXRpb24uCisgKiBAcGFyYW0gc2FtcGxlc1RvQXZlcmFnZSBUaGUgbnVtYmVyIG9mIHNhbXBsZXMgdG8gYXZlcmFnZSBmcm9tIDEgdG8gMTI3LgorICovCit2b2lkIEVuY29kZXI6OlNldFNhbXBsZXNUb0F2ZXJhZ2UoaW50IHNhbXBsZXNUb0F2ZXJhZ2UpIHsKKyAgaWYgKHNhbXBsZXNUb0F2ZXJhZ2UgPCAxIHx8IHNhbXBsZXNUb0F2ZXJhZ2UgPiAxMjcpIHsKKyAgICB3cGlfc2V0V1BJRXJyb3JXaXRoQ29udGV4dCgKKyAgICAgICAgUGFyYW1ldGVyT3V0T2ZSYW5nZSwKKyAgICAgICAgIkF2ZXJhZ2UgY291bnRlciB2YWx1ZXMgbXVzdCBiZSBiZXR3ZWVuIDEgYW5kIDEyNyIpOworICB9CisgIGludDMyX3Qgc3RhdHVzID0gMDsKKyAgc3dpdGNoIChtX2VuY29kaW5nVHlwZSkgeworICAgIGNhc2UgazRYOgorICAgICAgc2V0RW5jb2RlclNhbXBsZXNUb0F2ZXJhZ2UobV9lbmNvZGVyLCBzYW1wbGVzVG9BdmVyYWdlLCAmc3RhdHVzKTsKKyAgICAgIHdwaV9zZXRFcnJvcldpdGhDb250ZXh0KHN0YXR1cywgZ2V0SEFMRXJyb3JNZXNzYWdlKHN0YXR1cykpOworICAgICAgYnJlYWs7CisgICAgY2FzZSBrMVg6CisgICAgY2FzZSBrMlg6CisgICAgICBtX2NvdW50ZXItPlNldFNhbXBsZXNUb0F2ZXJhZ2Uoc2FtcGxlc1RvQXZlcmFnZSk7CisgICAgICBicmVhazsKKyAgfQorfQorCisvKioKKyAqIEdldCB0aGUgU2FtcGxlcyB0byBBdmVyYWdlIHdoaWNoIHNwZWNpZmllcyB0aGUgbnVtYmVyIG9mIHNhbXBsZXMgb2YgdGhlIHRpbWVyCisgKiB0bworICogYXZlcmFnZSB3aGVuIGNhbGN1bGF0aW5nIHRoZSBwZXJpb2QuIFBlcmZvcm0gYXZlcmFnaW5nIHRvIGFjY291bnQgZm9yCisgKiBtZWNoYW5pY2FsIGltcGVyZmVjdGlvbnMgb3IgYXMgb3ZlcnNhbXBsaW5nIHRvIGluY3JlYXNlIHJlc29sdXRpb24uCisgKiBAcmV0dXJuIFNhbXBsZXNUb0F2ZXJhZ2UgVGhlIG51bWJlciBvZiBzYW1wbGVzIGJlaW5nIGF2ZXJhZ2VkIChmcm9tIDEgdG8gMTI3KQorICovCitpbnQgRW5jb2Rlcjo6R2V0U2FtcGxlc1RvQXZlcmFnZSgpIGNvbnN0IHsKKyAgaW50IHJlc3VsdCA9IDE7CisgIGludDMyX3Qgc3RhdHVzID0gMDsKKyAgc3dpdGNoIChtX2VuY29kaW5nVHlwZSkgeworICAgIGNhc2UgazRYOgorICAgICAgcmVzdWx0ID0gZ2V0RW5jb2RlclNhbXBsZXNUb0F2ZXJhZ2UobV9lbmNvZGVyLCAmc3RhdHVzKTsKKyAgICAgIHdwaV9zZXRFcnJvcldpdGhDb250ZXh0KHN0YXR1cywgZ2V0SEFMRXJyb3JNZXNzYWdlKHN0YXR1cykpOworICAgICAgYnJlYWs7CisgICAgY2FzZSBrMVg6CisgICAgY2FzZSBrMlg6CisgICAgICByZXN1bHQgPSBtX2NvdW50ZXItPkdldFNhbXBsZXNUb0F2ZXJhZ2UoKTsKKyAgICAgIGJyZWFrOworICB9CisgIHJldHVybiByZXN1bHQ7Cit9CisKKy8qKgorICogSW1wbGVtZW50IHRoZSBQSURTb3VyY2UgaW50ZXJmYWNlLgorICoKKyAqIEByZXR1cm4gVGhlIGN1cnJlbnQgdmFsdWUgb2YgdGhlIHNlbGVjdGVkIHNvdXJjZSBwYXJhbWV0ZXIuCisgKi8KK2RvdWJsZSBFbmNvZGVyOjpQSURHZXQoKSB7CisgIGlmIChTdGF0dXNJc0ZhdGFsKCkpIHJldHVybiAwLjA7CisgIHN3aXRjaCAoR2V0UElEU291cmNlVHlwZSgpKSB7CisgICAgY2FzZSBQSURTb3VyY2VUeXBlOjprRGlzcGxhY2VtZW50OgorICAgICAgcmV0dXJuIEdldERpc3RhbmNlKCk7CisgICAgY2FzZSBQSURTb3VyY2VUeXBlOjprUmF0ZToKKyAgICAgIHJldHVybiBHZXRSYXRlKCk7CisgICAgZGVmYXVsdDoKKyAgICAgIHJldHVybiAwLjA7CisgIH0KK30KKworLyoqCisgKiBTZXQgdGhlIGluZGV4IHNvdXJjZSBmb3IgdGhlIGVuY29kZXIuICBXaGVuIHRoaXMgc291cmNlIGlzIGFjdGl2YXRlZCwgdGhlCisgKiBlbmNvZGVyIGNvdW50IGF1dG9tYXRpY2FsbHkgcmVzZXRzLgorICoKKyAqIEBwYXJhbSBjaGFubmVsIEEgRElPIGNoYW5uZWwgdG8gc2V0IGFzIHRoZSBlbmNvZGVyIGluZGV4CisgKiBAcGFyYW0gdHlwZSBUaGUgc3RhdGUgdGhhdCB3aWxsIGNhdXNlIHRoZSBlbmNvZGVyIHRvIHJlc2V0CisgKi8KK3ZvaWQgRW5jb2Rlcjo6U2V0SW5kZXhTb3VyY2UodWludDMyX3QgY2hhbm5lbCwgRW5jb2Rlcjo6SW5kZXhpbmdUeXBlIHR5cGUpIHsKKyAgaW50MzJfdCBzdGF0dXMgPSAwOworICBib29sIGFjdGl2ZUhpZ2ggPSAodHlwZSA9PSBrUmVzZXRXaGlsZUhpZ2gpIHx8ICh0eXBlID09IGtSZXNldE9uUmlzaW5nRWRnZSk7CisgIGJvb2wgZWRnZVNlbnNpdGl2ZSA9CisgICAgICAodHlwZSA9PSBrUmVzZXRPbkZhbGxpbmdFZGdlKSB8fCAodHlwZSA9PSBrUmVzZXRPblJpc2luZ0VkZ2UpOworCisgIHNldEVuY29kZXJJbmRleFNvdXJjZShtX2VuY29kZXIsIGNoYW5uZWwsIGZhbHNlLCBhY3RpdmVIaWdoLCBlZGdlU2Vuc2l0aXZlLAorICAgICAgICAgICAgICAgICAgICAgICAgJnN0YXR1cyk7CisgIHdwaV9zZXRHbG9iYWxFcnJvcldpdGhDb250ZXh0KHN0YXR1cywgZ2V0SEFMRXJyb3JNZXNzYWdlKHN0YXR1cykpOworfQorCisvKioKKyAqIFNldCB0aGUgaW5kZXggc291cmNlIGZvciB0aGUgZW5jb2Rlci4gIFdoZW4gdGhpcyBzb3VyY2UgaXMgYWN0aXZhdGVkLCB0aGUKKyAqIGVuY29kZXIgY291bnQgYXV0b21hdGljYWxseSByZXNldHMuCisgKgorICogQHBhcmFtIGNoYW5uZWwgQSBkaWdpdGFsIHNvdXJjZSB0byBzZXQgYXMgdGhlIGVuY29kZXIgaW5kZXgKKyAqIEBwYXJhbSB0eXBlIFRoZSBzdGF0ZSB0aGF0IHdpbGwgY2F1c2UgdGhlIGVuY29kZXIgdG8gcmVzZXQKKyAqLworREVQUkVDQVRFRCgiVXNlIHBhc3MtYnktcmVmZXJlbmNlIGluc3RlYWQuIikKK3ZvaWQgRW5jb2Rlcjo6U2V0SW5kZXhTb3VyY2UoRGlnaXRhbFNvdXJjZSAqc291cmNlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICBFbmNvZGVyOjpJbmRleGluZ1R5cGUgdHlwZSkgeworICBTZXRJbmRleFNvdXJjZSgqc291cmNlLCB0eXBlKTsKK30KKworLyoqCisgKiBTZXQgdGhlIGluZGV4IHNvdXJjZSBmb3IgdGhlIGVuY29kZXIuICBXaGVuIHRoaXMgc291cmNlIGlzIGFjdGl2YXRlZCwgdGhlCisgKiBlbmNvZGVyIGNvdW50IGF1dG9tYXRpY2FsbHkgcmVzZXRzLgorICoKKyAqIEBwYXJhbSBjaGFubmVsIEEgZGlnaXRhbCBzb3VyY2UgdG8gc2V0IGFzIHRoZSBlbmNvZGVyIGluZGV4CisgKiBAcGFyYW0gdHlwZSBUaGUgc3RhdGUgdGhhdCB3aWxsIGNhdXNlIHRoZSBlbmNvZGVyIHRvIHJlc2V0CisgKi8KK3ZvaWQgRW5jb2Rlcjo6U2V0SW5kZXhTb3VyY2UoY29uc3QgRGlnaXRhbFNvdXJjZSAmc291cmNlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICBFbmNvZGVyOjpJbmRleGluZ1R5cGUgdHlwZSkgeworICBpbnQzMl90IHN0YXR1cyA9IDA7CisgIGJvb2wgYWN0aXZlSGlnaCA9ICh0eXBlID09IGtSZXNldFdoaWxlSGlnaCkgfHwgKHR5cGUgPT0ga1Jlc2V0T25SaXNpbmdFZGdlKTsKKyAgYm9vbCBlZGdlU2Vuc2l0aXZlID0KKyAgICAgICh0eXBlID09IGtSZXNldE9uRmFsbGluZ0VkZ2UpIHx8ICh0eXBlID09IGtSZXNldE9uUmlzaW5nRWRnZSk7CisKKyAgc2V0RW5jb2RlckluZGV4U291cmNlKG1fZW5jb2Rlciwgc291cmNlLkdldENoYW5uZWxGb3JSb3V0aW5nKCksCisgICAgICAgICAgICAgICAgICAgICAgICBzb3VyY2UuR2V0QW5hbG9nVHJpZ2dlckZvclJvdXRpbmcoKSwgYWN0aXZlSGlnaCwKKyAgICAgICAgICAgICAgICAgICAgICAgIGVkZ2VTZW5zaXRpdmUsICZzdGF0dXMpOworICB3cGlfc2V0R2xvYmFsRXJyb3JXaXRoQ29udGV4dChzdGF0dXMsIGdldEhBTEVycm9yTWVzc2FnZShzdGF0dXMpKTsKK30KKwordm9pZCBFbmNvZGVyOjpVcGRhdGVUYWJsZSgpIHsKKyAgaWYgKG1fdGFibGUgIT0gbnVsbHB0cikgeworICAgIG1fdGFibGUtPlB1dE51bWJlcigiU3BlZWQiLCBHZXRSYXRlKCkpOworICAgIG1fdGFibGUtPlB1dE51bWJlcigiRGlzdGFuY2UiLCBHZXREaXN0YW5jZSgpKTsKKyAgICBtX3RhYmxlLT5QdXROdW1iZXIoIkRpc3RhbmNlIHBlciBUaWNrIiwgbV9kaXN0YW5jZVBlclB1bHNlKTsKKyAgfQorfQorCit2b2lkIEVuY29kZXI6OlN0YXJ0TGl2ZVdpbmRvd01vZGUoKSB7fQorCit2b2lkIEVuY29kZXI6OlN0b3BMaXZlV2luZG93TW9kZSgpIHt9CisKK3N0ZDo6c3RyaW5nIEVuY29kZXI6OkdldFNtYXJ0RGFzaGJvYXJkVHlwZSgpIGNvbnN0IHsKKyAgaWYgKG1fZW5jb2RpbmdUeXBlID09IGs0WCkKKyAgICByZXR1cm4gIlF1YWRyYXR1cmUgRW5jb2RlciI7CisgIGVsc2UKKyAgICByZXR1cm4gIkVuY29kZXIiOworfQorCit2b2lkIEVuY29kZXI6OkluaXRUYWJsZShzdGQ6OnNoYXJlZF9wdHI8SVRhYmxlPiBzdWJUYWJsZSkgeworICBtX3RhYmxlID0gc3ViVGFibGU7CisgIFVwZGF0ZVRhYmxlKCk7Cit9CisKK3N0ZDo6c2hhcmVkX3B0cjxJVGFibGU+IEVuY29kZXI6OkdldFRhYmxlKCkgY29uc3QgeyByZXR1cm4gbV90YWJsZTsgfQpkaWZmIC0tZ2l0IGEvd3BpbGliYy9BdGhlbmEvc3JjL0dlYXJUb290aC5jcHAgYi93cGlsaWJjL0F0aGVuYS9zcmMvR2VhclRvb3RoLmNwcApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5iNjU5MTI1Ci0tLSAvZGV2L251bGwKKysrIGIvd3BpbGliYy9BdGhlbmEvc3JjL0dlYXJUb290aC5jcHAKQEAgLTAsMCArMSw2NCBAQAorLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi8KKy8qIENvcHlyaWdodCAoYykgRklSU1QgMjAwOC4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KKyAqLworLyogT3BlbiBTb3VyY2UgU29mdHdhcmUgLSBtYXkgYmUgbW9kaWZpZWQgYW5kIHNoYXJlZCBieSBGUkMgdGVhbXMuIFRoZSBjb2RlICAgKi8KKy8qIG11c3QgYmUgYWNjb21wYW5pZWQgYnkgdGhlIEZJUlNUIEJTRCBsaWNlbnNlIGZpbGUgaW4gJChXSU5EX0JBU0UpL1dQSUxpYi4gICovCisvKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qLworCisjaW5jbHVkZSAiR2VhclRvb3RoLmgiCisjaW5jbHVkZSAiTGl2ZVdpbmRvdy9MaXZlV2luZG93LmgiCisKK2NvbnN0ZXhwciBkb3VibGUgR2VhclRvb3RoOjprR2VhclRvb3RoVGhyZXNob2xkOworCisvKioKKyAqIENvbW1vbiBjb2RlIGNhbGxlZCBieSB0aGUgY29uc3RydWN0b3JzLgorICovCit2b2lkIEdlYXJUb290aDo6RW5hYmxlRGlyZWN0aW9uU2Vuc2luZyhib29sIGRpcmVjdGlvblNlbnNpdGl2ZSkgeworICBpZiAoZGlyZWN0aW9uU2Vuc2l0aXZlKSB7CisgICAgU2V0UHVsc2VMZW5ndGhNb2RlKGtHZWFyVG9vdGhUaHJlc2hvbGQpOworICB9Cit9CisKKy8qKgorICogQ29uc3RydWN0IGEgR2VhclRvb3RoIHNlbnNvciBnaXZlbiBhIGNoYW5uZWwuCisgKgorICogQHBhcmFtIGNoYW5uZWwgVGhlIERJTyBjaGFubmVsIHRoYXQgdGhlIHNlbnNvciBpcyBjb25uZWN0ZWQgdG8uIDAtOSBhcmUKKyAqIG9uLWJvYXJkLCAxMC0yNSBhcmUgb24gdGhlIE1YUC4KKyAqIEBwYXJhbSBkaXJlY3Rpb25TZW5zaXRpdmUgVHJ1ZSB0byBlbmFibGUgdGhlIHB1bHNlIGxlbmd0aCBkZWNvZGluZyBpbgorICogaGFyZHdhcmUgdG8gc3BlY2lmeSBjb3VudCBkaXJlY3Rpb24uCisgKi8KK0dlYXJUb290aDo6R2VhclRvb3RoKHVpbnQzMl90IGNoYW5uZWwsIGJvb2wgZGlyZWN0aW9uU2Vuc2l0aXZlKQorICAgIDogQ291bnRlcihjaGFubmVsKSB7CisgIEVuYWJsZURpcmVjdGlvblNlbnNpbmcoZGlyZWN0aW9uU2Vuc2l0aXZlKTsKKyAgTGl2ZVdpbmRvdzo6R2V0SW5zdGFuY2UoKS0+QWRkU2Vuc29yKCJHZWFyVG9vdGgiLCBjaGFubmVsLCB0aGlzKTsKK30KKworLyoqCisgKiBDb25zdHJ1Y3QgYSBHZWFyVG9vdGggc2Vuc29yIGdpdmVuIGEgZGlnaXRhbCBpbnB1dC4KKyAqIFRoaXMgc2hvdWxkIGJlIHVzZWQgd2hlbiBzaGFyaW5nIGRpZ2l0YWwgaW5wdXRzLgorICoKKyAqIEBwYXJhbSBzb3VyY2UgQSBwb2ludGVyIHRvIHRoZSBleGlzdGluZyBEaWdpdGFsU291cmNlIG9iamVjdCAoc3VjaCBhcyBhCisgKiBEaWdpdGFsSW5wdXQpCisgKiBAcGFyYW0gZGlyZWN0aW9uU2Vuc2l0aXZlIFRydWUgdG8gZW5hYmxlIHRoZSBwdWxzZSBsZW5ndGggZGVjb2RpbmcgaW4KKyAqIGhhcmR3YXJlIHRvIHNwZWNpZnkgY291bnQgZGlyZWN0aW9uLgorICovCitHZWFyVG9vdGg6OkdlYXJUb290aChEaWdpdGFsU291cmNlICpzb3VyY2UsIGJvb2wgZGlyZWN0aW9uU2Vuc2l0aXZlKQorICAgIDogQ291bnRlcihzb3VyY2UpIHsKKyAgRW5hYmxlRGlyZWN0aW9uU2Vuc2luZyhkaXJlY3Rpb25TZW5zaXRpdmUpOworfQorCisvKioKKyAqIENvbnN0cnVjdCBhIEdlYXJUb290aCBzZW5zb3IgZ2l2ZW4gYSBkaWdpdGFsIGlucHV0LgorICogVGhpcyBzaG91bGQgYmUgdXNlZCB3aGVuIHNoYXJpbmcgZGlnaXRhbCBpbnB1dHMuCisgKgorICogQHBhcmFtIHNvdXJjZSBBIHJlZmVyZW5jZSB0byB0aGUgZXhpc3RpbmcgRGlnaXRhbFNvdXJjZSBvYmplY3QgKHN1Y2ggYXMgYQorICogRGlnaXRhbElucHV0KQorICogQHBhcmFtIGRpcmVjdGlvblNlbnNpdGl2ZSBUcnVlIHRvIGVuYWJsZSB0aGUgcHVsc2UgbGVuZ3RoIGRlY29kaW5nIGluCisgKiBoYXJkd2FyZSB0byBzcGVjaWZ5IGNvdW50IGRpcmVjdGlvbi4KKyAqLworR2VhclRvb3RoOjpHZWFyVG9vdGgoc3RkOjpzaGFyZWRfcHRyPERpZ2l0YWxTb3VyY2U+IHNvdXJjZSwgYm9vbCBkaXJlY3Rpb25TZW5zaXRpdmUpCisgICAgOiBDb3VudGVyKHNvdXJjZSkgeworICBFbmFibGVEaXJlY3Rpb25TZW5zaW5nKGRpcmVjdGlvblNlbnNpdGl2ZSk7Cit9CisKK3N0ZDo6c3RyaW5nIEdlYXJUb290aDo6R2V0U21hcnREYXNoYm9hcmRUeXBlKCkgY29uc3QgeyByZXR1cm4gIkdlYXJUb290aCI7IH0KZGlmZiAtLWdpdCBhL3dwaWxpYmMvQXRoZW5hL3NyYy9HeXJvQmFzZS5jcHAgYi93cGlsaWJjL0F0aGVuYS9zcmMvR3lyb0Jhc2UuY3BwCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjRjYzkwNTYKLS0tIC9kZXYvbnVsbAorKysgYi93cGlsaWJjL0F0aGVuYS9zcmMvR3lyb0Jhc2UuY3BwCkBAIC0wLDAgKzEsNDYgQEAKKy8qLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovCisvKiBDb3B5cmlnaHQgKGMpIEZJUlNUIDIwMDguIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCisgKi8KKy8qIE9wZW4gU291cmNlIFNvZnR3YXJlIC0gbWF5IGJlIG1vZGlmaWVkIGFuZCBzaGFyZWQgYnkgRlJDIHRlYW1zLiBUaGUgY29kZSAgICovCisvKiBtdXN0IGJlIGFjY29tcGFuaWVkIGJ5IHRoZSBGSVJTVCBCU0QgbGljZW5zZSBmaWxlIGluICQoV0lORF9CQVNFKS9XUElMaWIuICAqLworLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi8KKworI2luY2x1ZGUgIkd5cm9CYXNlLmgiCisjaW5jbHVkZSAiV1BJRXJyb3JzLmgiCisjaW5jbHVkZSAiTGl2ZVdpbmRvdy9MaXZlV2luZG93LmgiCisKKy8qKgorICogR2V0IHRoZSBQSURPdXRwdXQgZm9yIHRoZSBQSURTb3VyY2UgYmFzZSBvYmplY3QuIENhbiBiZSBzZXQgdG8gcmV0dXJuCisgKiBhbmdsZSBvciByYXRlIHVzaW5nIFNldFBJRFNvdXJjZVR5cGUoKS4gRGVmYXVsdHMgdG8gYW5nbGUuCisgKgorICogQHJldHVybiBUaGUgUElET3V0cHV0IChhbmdsZSBvciByYXRlLCBkZWZhdWx0cyB0byBhbmdsZSkKKyAqLworZG91YmxlIEd5cm9CYXNlOjpQSURHZXQoKSB7CisgIHN3aXRjaCAoR2V0UElEU291cmNlVHlwZSgpKSB7CisgICAgY2FzZSBQSURTb3VyY2VUeXBlOjprUmF0ZToKKyAgICAgIHJldHVybiBHZXRSYXRlKCk7CisgICAgY2FzZSBQSURTb3VyY2VUeXBlOjprRGlzcGxhY2VtZW50OgorICAgICAgcmV0dXJuIEdldEFuZ2xlKCk7CisgICAgZGVmYXVsdDoKKyAgICAgIHJldHVybiAwOworICB9Cit9CisKK3ZvaWQgR3lyb0Jhc2U6OlVwZGF0ZVRhYmxlKCkgeworICBpZiAobV90YWJsZSAhPSBudWxscHRyKSB7CisgICAgbV90YWJsZS0+UHV0TnVtYmVyKCJWYWx1ZSIsIEdldEFuZ2xlKCkpOworICB9Cit9CisKK3ZvaWQgR3lyb0Jhc2U6OlN0YXJ0TGl2ZVdpbmRvd01vZGUoKSB7fQorCit2b2lkIEd5cm9CYXNlOjpTdG9wTGl2ZVdpbmRvd01vZGUoKSB7fQorCitzdGQ6OnN0cmluZyBHeXJvQmFzZTo6R2V0U21hcnREYXNoYm9hcmRUeXBlKCkgY29uc3QgeyByZXR1cm4gIkd5cm8iOyB9CisKK3ZvaWQgR3lyb0Jhc2U6OkluaXRUYWJsZShzdGQ6OnNoYXJlZF9wdHI8SVRhYmxlPiBzdWJUYWJsZSkgeworICBtX3RhYmxlID0gc3ViVGFibGU7CisgIFVwZGF0ZVRhYmxlKCk7Cit9CisKK3N0ZDo6c2hhcmVkX3B0cjxJVGFibGU+IEd5cm9CYXNlOjpHZXRUYWJsZSgpIGNvbnN0IHsgcmV0dXJuIG1fdGFibGU7IH0KZGlmZiAtLWdpdCBhL3dwaWxpYmMvQXRoZW5hL3NyYy9JMkMuY3BwIGIvd3BpbGliYy9BdGhlbmEvc3JjL0kyQy5jcHAKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNzk3NjdiMwotLS0gL2Rldi9udWxsCisrKyBiL3dwaWxpYmMvQXRoZW5hL3NyYy9JMkMuY3BwCkBAIC0wLDAgKzEsMTk5IEBACisvKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qLworLyogQ29weXJpZ2h0IChjKSBGSVJTVCAyMDA4LiBBbGwgUmlnaHRzIFJlc2VydmVkLgorICovCisvKiBPcGVuIFNvdXJjZSBTb2Z0d2FyZSAtIG1heSBiZSBtb2RpZmllZCBhbmQgc2hhcmVkIGJ5IEZSQyB0ZWFtcy4gVGhlIGNvZGUgICAqLworLyogbXVzdCBiZSBhY2NvbXBhbmllZCBieSB0aGUgRklSU1QgQlNEIGxpY2Vuc2UgZmlsZSBpbiAkKFdJTkRfQkFTRSkvV1BJTGliLiAgKi8KKy8qLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovCisKKyNpbmNsdWRlICJJMkMuaCIKKyNpbmNsdWRlICJIQUwvSEFMLmhwcCIKKyNpbmNsdWRlICJIQUwvRGlnaXRhbC5ocHAiCisjaW5jbHVkZSAiV1BJRXJyb3JzLmgiCisKKy8qKgorICogQ29uc3RydWN0b3IuCisgKgorICogQHBhcmFtIHBvcnQgVGhlIEkyQyBwb3J0IHRvIHdoaWNoIHRoZSBkZXZpY2UgaXMgY29ubmVjdGVkLgorICogQHBhcmFtIGRldmljZUFkZHJlc3MgVGhlIGFkZHJlc3Mgb2YgdGhlIGRldmljZSBvbiB0aGUgSTJDIGJ1cy4KKyAqLworSTJDOjpJMkMoUG9ydCBwb3J0LCB1aW50OF90IGRldmljZUFkZHJlc3MpCisgICAgOiBtX3BvcnQocG9ydCksIG1fZGV2aWNlQWRkcmVzcyhkZXZpY2VBZGRyZXNzKSB7CisgIGludDMyX3Qgc3RhdHVzID0gMDsKKyAgaTJDSW5pdGlhbGl6ZShtX3BvcnQsICZzdGF0dXMpOworICAvLyB3cGlfc2V0RXJyb3JXaXRoQ29udGV4dChzdGF0dXMsIGdldEhBTEVycm9yTWVzc2FnZShzdGF0dXMpKTsKKworICBIQUxSZXBvcnQoSEFMVXNhZ2VSZXBvcnRpbmc6OmtSZXNvdXJjZVR5cGVfSTJDLCBkZXZpY2VBZGRyZXNzKTsKK30KKworLyoqCisgKiBEZXN0cnVjdG9yLgorICovCitJMkM6On5JMkMoKSB7IGkyQ0Nsb3NlKG1fcG9ydCk7IH0KKworLyoqCisgKiBHZW5lcmljIHRyYW5zYWN0aW9uLgorICoKKyAqIFRoaXMgaXMgYSBsb3dlci1sZXZlbCBpbnRlcmZhY2UgdG8gdGhlIEkyQyBoYXJkd2FyZSBnaXZpbmcgeW91IG1vcmUgY29udHJvbAorICogb3ZlciBlYWNoIHRyYW5zYWN0aW9uLgorICoKKyAqIEBwYXJhbSBkYXRhVG9TZW5kIEJ1ZmZlciBvZiBkYXRhIHRvIHNlbmQgYXMgcGFydCBvZiB0aGUgdHJhbnNhY3Rpb24uCisgKiBAcGFyYW0gc2VuZFNpemUgTnVtYmVyIG9mIGJ5dGVzIHRvIHNlbmQgYXMgcGFydCBvZiB0aGUgdHJhbnNhY3Rpb24uCisgKiBAcGFyYW0gZGF0YVJlY2VpdmVkIEJ1ZmZlciB0byByZWFkIGRhdGEgaW50by4KKyAqIEBwYXJhbSByZWNlaXZlU2l6ZSBOdW1iZXIgb2YgYnl0ZXMgdG8gcmVhZCBmcm9tIHRoZSBkZXZpY2UuCisgKiBAcmV0dXJuIFRyYW5zZmVyIEFib3J0ZWQuLi4gZmFsc2UgZm9yIHN1Y2Nlc3MsIHRydWUgZm9yIGFib3J0ZWQuCisgKi8KK2Jvb2wgSTJDOjpUcmFuc2FjdGlvbih1aW50OF90ICpkYXRhVG9TZW5kLCB1aW50OF90IHNlbmRTaXplLAorICAgICAgICAgICAgICAgICAgICAgIHVpbnQ4X3QgKmRhdGFSZWNlaXZlZCwgdWludDhfdCByZWNlaXZlU2l6ZSkgeworICBpbnQzMl90IHN0YXR1cyA9IDA7CisgIHN0YXR1cyA9IGkyQ1RyYW5zYWN0aW9uKG1fcG9ydCwgbV9kZXZpY2VBZGRyZXNzLCBkYXRhVG9TZW5kLCBzZW5kU2l6ZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgZGF0YVJlY2VpdmVkLCByZWNlaXZlU2l6ZSk7CisgIC8vIHdwaV9zZXRFcnJvcldpdGhDb250ZXh0KHN0YXR1cywgZ2V0SEFMRXJyb3JNZXNzYWdlKHN0YXR1cykpOworICByZXR1cm4gc3RhdHVzIDwgMDsKK30KKworLyoqCisgKiBBdHRlbXB0IHRvIGFkZHJlc3MgYSBkZXZpY2Ugb24gdGhlIEkyQyBidXMuCisgKgorICogVGhpcyBhbGxvd3MgeW91IHRvIGZpZ3VyZSBvdXQgaWYgdGhlcmUgaXMgYSBkZXZpY2Ugb24gdGhlIEkyQyBidXMgdGhhdAorICogcmVzcG9uZHMgdG8gdGhlIGFkZHJlc3Mgc3BlY2lmaWVkIGluIHRoZSBjb25zdHJ1Y3Rvci4KKyAqCisgKiBAcmV0dXJuIFRyYW5zZmVyIEFib3J0ZWQuLi4gZmFsc2UgZm9yIHN1Y2Nlc3MsIHRydWUgZm9yIGFib3J0ZWQuCisgKi8KK2Jvb2wgSTJDOjpBZGRyZXNzT25seSgpIHsKKyAgaW50MzJfdCBzdGF0dXMgPSAwOworICBzdGF0dXMgPSBUcmFuc2FjdGlvbihudWxscHRyLCAwLCBudWxscHRyLCAwKTsKKyAgcmV0dXJuIHN0YXR1cyA8IDA7Cit9CisKKy8qKgorICogRXhlY3V0ZSBhIHdyaXRlIHRyYW5zYWN0aW9uIHdpdGggdGhlIGRldmljZS4KKyAqCisgKiBXcml0ZSBhIHNpbmdsZSBieXRlIHRvIGEgcmVnaXN0ZXIgb24gYSBkZXZpY2UgYW5kIHdhaXQgdW50aWwgdGhlCisgKiAgIHRyYW5zYWN0aW9uIGlzIGNvbXBsZXRlLgorICoKKyAqIEBwYXJhbSByZWdpc3RlckFkZHJlc3MgVGhlIGFkZHJlc3Mgb2YgdGhlIHJlZ2lzdGVyIG9uIHRoZSBkZXZpY2UgdG8gYmUKKyAqIHdyaXR0ZW4uCisgKiBAcGFyYW0gZGF0YSBUaGUgYnl0ZSB0byB3cml0ZSB0byB0aGUgcmVnaXN0ZXIgb24gdGhlIGRldmljZS4KKyAqIEByZXR1cm4gVHJhbnNmZXIgQWJvcnRlZC4uLiBmYWxzZSBmb3Igc3VjY2VzcywgdHJ1ZSBmb3IgYWJvcnRlZC4KKyAqLworYm9vbCBJMkM6OldyaXRlKHVpbnQ4X3QgcmVnaXN0ZXJBZGRyZXNzLCB1aW50OF90IGRhdGEpIHsKKyAgdWludDhfdCBidWZmZXJbMl07CisgIGJ1ZmZlclswXSA9IHJlZ2lzdGVyQWRkcmVzczsKKyAgYnVmZmVyWzFdID0gZGF0YTsKKyAgaW50MzJfdCBzdGF0dXMgPSAwOworICBzdGF0dXMgPSBpMkNXcml0ZShtX3BvcnQsIG1fZGV2aWNlQWRkcmVzcywgYnVmZmVyLCBzaXplb2YoYnVmZmVyKSk7CisgIHJldHVybiBzdGF0dXMgPCAwOworfQorCisvKioKKyAqIEV4ZWN1dGUgYSBidWxrIHdyaXRlIHRyYW5zYWN0aW9uIHdpdGggdGhlIGRldmljZS4KKyAqCisgKiBXcml0ZSBtdWx0aXBsZSBieXRlcyB0byBhIGRldmljZSBhbmQgd2FpdCB1bnRpbCB0aGUKKyAqICAgdHJhbnNhY3Rpb24gaXMgY29tcGxldGUuCisgKgorICogQHBhcmFtIGRhdGEgVGhlIGRhdGEgdG8gd3JpdGUgdG8gdGhlIHJlZ2lzdGVyIG9uIHRoZSBkZXZpY2UuCisgKiBAcGFyYW0gY291bnQgVGhlIG51bWJlciBvZiBieXRlcyB0byBiZSB3cml0dGVuLgorICogQHJldHVybiBUcmFuc2ZlciBBYm9ydGVkLi4uIGZhbHNlIGZvciBzdWNjZXNzLCB0cnVlIGZvciBhYm9ydGVkLgorICovCitib29sIEkyQzo6V3JpdGVCdWxrKHVpbnQ4X3QgKmRhdGEsIHVpbnQ4X3QgY291bnQpIHsKKyAgaW50MzJfdCBzdGF0dXMgPSAwOworICBzdGF0dXMgPSBpMkNXcml0ZShtX3BvcnQsIG1fZGV2aWNlQWRkcmVzcywgZGF0YSwgY291bnQpOworICByZXR1cm4gc3RhdHVzIDwgMDsKK30KKworLyoqCisgKiBFeGVjdXRlIGEgcmVhZCB0cmFuc2FjdGlvbiB3aXRoIHRoZSBkZXZpY2UuCisgKgorICogUmVhZCBieXRlcyBmcm9tIGEgZGV2aWNlLgorICogTW9zdCBJMkMgZGV2aWNlcyB3aWxsIGF1dG8taW5jcmVtZW50IHRoZSByZWdpc3RlciBwb2ludGVyIGludGVybmFsbHkgYWxsb3dpbmcKKyAqICAgeW91IHRvIHJlYWQgY29uc2VjdXRpdmUgcmVnaXN0ZXJzIG9uIGEgZGV2aWNlIGluIGEgc2luZ2xlIHRyYW5zYWN0aW9uLgorICoKKyAqIEBwYXJhbSByZWdpc3RlckFkZHJlc3MgVGhlIHJlZ2lzdGVyIHRvIHJlYWQgZmlyc3QgaW4gdGhlIHRyYW5zYWN0aW9uLgorICogQHBhcmFtIGNvdW50IFRoZSBudW1iZXIgb2YgYnl0ZXMgdG8gcmVhZCBpbiB0aGUgdHJhbnNhY3Rpb24uCisgKiBAcGFyYW0gYnVmZmVyIEEgcG9pbnRlciB0byB0aGUgYXJyYXkgb2YgYnl0ZXMgdG8gc3RvcmUgdGhlIGRhdGEgcmVhZCBmcm9tIHRoZQorICogZGV2aWNlLgorICogQHJldHVybiBUcmFuc2ZlciBBYm9ydGVkLi4uIGZhbHNlIGZvciBzdWNjZXNzLCB0cnVlIGZvciBhYm9ydGVkLgorICovCitib29sIEkyQzo6UmVhZCh1aW50OF90IHJlZ2lzdGVyQWRkcmVzcywgdWludDhfdCBjb3VudCwgdWludDhfdCAqYnVmZmVyKSB7CisgIGlmIChjb3VudCA8IDEpIHsKKyAgICB3cGlfc2V0V1BJRXJyb3JXaXRoQ29udGV4dChQYXJhbWV0ZXJPdXRPZlJhbmdlLCAiY291bnQiKTsKKyAgICByZXR1cm4gdHJ1ZTsKKyAgfQorICBpZiAoYnVmZmVyID09IG51bGxwdHIpIHsKKyAgICB3cGlfc2V0V1BJRXJyb3JXaXRoQ29udGV4dChOdWxsUGFyYW1ldGVyLCAiYnVmZmVyIik7CisgICAgcmV0dXJuIHRydWU7CisgIH0KKyAgaW50MzJfdCBzdGF0dXMgPSAwOworICBzdGF0dXMgPQorICAgICAgVHJhbnNhY3Rpb24oJnJlZ2lzdGVyQWRkcmVzcywgc2l6ZW9mKHJlZ2lzdGVyQWRkcmVzcyksIGJ1ZmZlciwgY291bnQpOworICByZXR1cm4gc3RhdHVzIDwgMDsKK30KKworLyoqCisgKiBFeGVjdXRlIGEgcmVhZCBvbmx5IHRyYW5zYWN0aW9uIHdpdGggdGhlIGRldmljZS4KKyAqCisgKiBSZWFkIGJ5dGVzIGZyb20gYSBkZXZpY2UuIFRoaXMgbWV0aG9kIGRvZXMgbm90IHdyaXRlIGFueSBkYXRhIHRvIHByb21wdCB0aGUKKyAqIGRldmljZS4KKyAqCisgKiBAcGFyYW0gYnVmZmVyCisgKiAgICAgICAgICAgIEEgcG9pbnRlciB0byB0aGUgYXJyYXkgb2YgYnl0ZXMgdG8gc3RvcmUgdGhlIGRhdGEgcmVhZCBmcm9tCisgKiAgICAgICAgICAgIHRoZSBkZXZpY2UuCisgKiBAcGFyYW0gY291bnQKKyAgICAgICAgICAgICAgVGhlIG51bWJlciBvZiBieXRlcyB0byByZWFkIGluIHRoZSB0cmFuc2FjdGlvbi4KKyAqIEByZXR1cm4gVHJhbnNmZXIgQWJvcnRlZC4uLiBmYWxzZSBmb3Igc3VjY2VzcywgdHJ1ZSBmb3IgYWJvcnRlZC4KKyAqLworYm9vbCBJMkM6OlJlYWRPbmx5KHVpbnQ4X3QgY291bnQsIHVpbnQ4X3QgKmJ1ZmZlcikgeworICBpZiAoY291bnQgPCAxKSB7CisgICAgd3BpX3NldFdQSUVycm9yV2l0aENvbnRleHQoUGFyYW1ldGVyT3V0T2ZSYW5nZSwgImNvdW50Iik7CisgICAgcmV0dXJuIHRydWU7CisgIH0KKyAgaWYgKGJ1ZmZlciA9PSBudWxscHRyKSB7CisgICAgd3BpX3NldFdQSUVycm9yV2l0aENvbnRleHQoTnVsbFBhcmFtZXRlciwgImJ1ZmZlciIpOworICAgIHJldHVybiB0cnVlOworICB9CisgIGludDMyX3Qgc3RhdHVzID0gMDsKKyAgc3RhdHVzID0gaTJDUmVhZChtX3BvcnQsIG1fZGV2aWNlQWRkcmVzcywgYnVmZmVyLCBjb3VudCk7CisgIHJldHVybiBzdGF0dXMgPCAwOworfQorCisvKioKKyAqIFNlbmQgYSBicm9hZGNhc3Qgd3JpdGUgdG8gYWxsIGRldmljZXMgb24gdGhlIEkyQyBidXMuCisgKgorICogVGhpcyBpcyBub3QgY3VycmVudGx5IGltcGxlbWVudGVkIQorICoKKyAqIEBwYXJhbSByZWdpc3RlckFkZHJlc3MgVGhlIHJlZ2lzdGVyIHRvIHdyaXRlIG9uIGFsbCBkZXZpY2VzIG9uIHRoZSBidXMuCisgKiBAcGFyYW0gZGF0YSBUaGUgdmFsdWUgdG8gd3JpdGUgdG8gdGhlIGRldmljZXMuCisgKi8KK1tbZ251Ojp3YXJuaW5nKCJJMkM6OkJyb2FkY2FzdCgpIGlzIG5vdCBpbXBsZW1lbnRlZC4iKV1dCit2b2lkIEkyQzo6QnJvYWRjYXN0KHVpbnQ4X3QgcmVnaXN0ZXJBZGRyZXNzLCB1aW50OF90IGRhdGEpIHt9CisKKy8qKgorICogVmVyaWZ5IHRoYXQgYSBkZXZpY2UncyByZWdpc3RlcnMgY29udGFpbiBleHBlY3RlZCB2YWx1ZXMuCisgKgorICogTW9zdCBkZXZpY2VzIHdpbGwgaGF2ZSBhIHNldCBvZiByZWdpc3RlcnMgdGhhdCBjb250YWluIGEga25vd24gdmFsdWUgdGhhdAorICogICBjYW4gYmUgdXNlZCB0byBpZGVudGlmeSB0aGVtLiAgVGhpcyBhbGxvd3MgYW4gSTJDIGRldmljZSBkcml2ZXIgdG8gZWFzaWx5CisgKiAgIHZlcmlmeSB0aGF0IHRoZSBkZXZpY2UgY29udGFpbnMgdGhlIGV4cGVjdGVkIHZhbHVlLgorICoKKyAqIEBwcmUgVGhlIGRldmljZSBtdXN0IHN1cHBvcnQgYW5kIGJlIGNvbmZpZ3VyZWQgdG8gdXNlIHJlZ2lzdGVyCisgKiBhdXRvLWluY3JlbWVudC4KKyAqCisgKiBAcGFyYW0gcmVnaXN0ZXJBZGRyZXNzIFRoZSBiYXNlIHJlZ2lzdGVyIHRvIHN0YXJ0IHJlYWRpbmcgZnJvbSB0aGUgZGV2aWNlLgorICogQHBhcmFtIGNvdW50IFRoZSBzaXplIG9mIHRoZSBmaWVsZCB0byBiZSB2ZXJpZmllZC4KKyAqIEBwYXJhbSBleHBlY3RlZCBBIGJ1ZmZlciBjb250YWluaW5nIHRoZSB2YWx1ZXMgZXhwZWN0ZWQgZnJvbSB0aGUgZGV2aWNlLgorICovCitib29sIEkyQzo6VmVyaWZ5U2Vuc29yKHVpbnQ4X3QgcmVnaXN0ZXJBZGRyZXNzLCB1aW50OF90IGNvdW50LAorICAgICAgICAgICAgICAgICAgICAgICBjb25zdCB1aW50OF90ICpleHBlY3RlZCkgeworICAvLyBUT0RPOiBNYWtlIHVzZSBvZiBhbGwgNyByZWFkIGJ5dGVzCisgIHVpbnQ4X3QgZGV2aWNlRGF0YVs0XTsKKyAgZm9yICh1aW50OF90IGkgPSAwLCBjdXJSZWdpc3RlckFkZHJlc3MgPSByZWdpc3RlckFkZHJlc3M7IGkgPCBjb3VudDsKKyAgICAgICBpICs9IDQsIGN1clJlZ2lzdGVyQWRkcmVzcyArPSA0KSB7CisgICAgdWludDhfdCB0b1JlYWQgPSBjb3VudCAtIGkgPCA0ID8gY291bnQgLSBpIDogNDsKKyAgICAvLyBSZWFkIHRoZSBjaHVuayBvZiBkYXRhLiAgUmV0dXJuIGZhbHNlIGlmIHRoZSBzZW5zb3IgZG9lcyBub3QgcmVzcG9uZC4KKyAgICBpZiAoUmVhZChjdXJSZWdpc3RlckFkZHJlc3MsIHRvUmVhZCwgZGV2aWNlRGF0YSkpIHJldHVybiBmYWxzZTsKKworICAgIGZvciAodWludDhfdCBqID0gMDsgaiA8IHRvUmVhZDsgaisrKSB7CisgICAgICBpZiAoZGV2aWNlRGF0YVtqXSAhPSBleHBlY3RlZFtpICsgal0pIHJldHVybiBmYWxzZTsKKyAgICB9CisgIH0KKyAgcmV0dXJuIHRydWU7Cit9CmRpZmYgLS1naXQgYS93cGlsaWJjL0F0aGVuYS9zcmMvSW50ZXJuYWwvSGFyZHdhcmVITFJlcG9ydGluZy5jcHAgYi93cGlsaWJjL0F0aGVuYS9zcmMvSW50ZXJuYWwvSGFyZHdhcmVITFJlcG9ydGluZy5jcHAKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMjE3NmM4MAotLS0gL2Rldi9udWxsCisrKyBiL3dwaWxpYmMvQXRoZW5hL3NyYy9JbnRlcm5hbC9IYXJkd2FyZUhMUmVwb3J0aW5nLmNwcApAQCAtMCwwICsxLDEyIEBACisKKyNpbmNsdWRlICJJbnRlcm5hbC9IYXJkd2FyZUhMUmVwb3J0aW5nLmgiCisjaW5jbHVkZSAiSEFML0hBTC5ocHAiCisKK3ZvaWQgSGFyZHdhcmVITFJlcG9ydGluZzo6UmVwb3J0U2NoZWR1bGVyKCkgeworICBIQUxSZXBvcnQoSEFMVXNhZ2VSZXBvcnRpbmc6OmtSZXNvdXJjZVR5cGVfQ29tbWFuZCwKKyAgICAgICAgICAgIEhBTFVzYWdlUmVwb3J0aW5nOjprQ29tbWFuZF9TY2hlZHVsZXIpOworfQorCit2b2lkIEhhcmR3YXJlSExSZXBvcnRpbmc6OlJlcG9ydFNtYXJ0RGFzaGJvYXJkKCkgeworICBIQUxSZXBvcnQoSEFMVXNhZ2VSZXBvcnRpbmc6OmtSZXNvdXJjZVR5cGVfU21hcnREYXNoYm9hcmQsIDApOworfQpkaWZmIC0tZ2l0IGEvd3BpbGliYy9BdGhlbmEvc3JjL0ludGVycnVwdGFibGVTZW5zb3JCYXNlLmNwcCBiL3dwaWxpYmMvQXRoZW5hL3NyYy9JbnRlcnJ1cHRhYmxlU2Vuc29yQmFzZS5jcHAKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNmU2NmMzNAotLS0gL2Rldi9udWxsCisrKyBiL3dwaWxpYmMvQXRoZW5hL3NyYy9JbnRlcnJ1cHRhYmxlU2Vuc29yQmFzZS5jcHAKQEAgLTAsMCArMSwxOTggQEAKKy8qLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovCisvKiBDb3B5cmlnaHQgKGMpIEZJUlNUIDIwMDguIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCisgKi8KKy8qIE9wZW4gU291cmNlIFNvZnR3YXJlIC0gbWF5IGJlIG1vZGlmaWVkIGFuZCBzaGFyZWQgYnkgRlJDIHRlYW1zLiBUaGUgY29kZSAgICovCisvKiBtdXN0IGJlIGFjY29tcGFuaWVkIGJ5IHRoZSBGSVJTVCBCU0QgbGljZW5zZSBmaWxlIGluICQoV0lORF9CQVNFKS9XUElMaWIuICAqLworLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi8KKworI2luY2x1ZGUgIkludGVycnVwdGFibGVTZW5zb3JCYXNlLmgiCisjaW5jbHVkZSAiVXRpbGl0eS5oIgorI2luY2x1ZGUgIldQSUVycm9ycy5oIgorCitzdGQ6OnVuaXF1ZV9wdHI8UmVzb3VyY2U+IEludGVycnVwdGFibGVTZW5zb3JCYXNlOjptX2ludGVycnVwdHMgPQorICAgIHN0ZDo6bWFrZV91bmlxdWU8UmVzb3VyY2U+KGludGVycnVwdF9rTnVtU3lzdGVtcyk7CisKK0ludGVycnVwdGFibGVTZW5zb3JCYXNlOjpJbnRlcnJ1cHRhYmxlU2Vuc29yQmFzZSgpIHsKK30KKworLyoqCisqIFJlcXVlc3Qgb25lIG9mIHRoZSA4IGludGVycnVwdHMgYXN5bmNocm9ub3VzbHkgb24gdGhpcyBkaWdpdGFsIGlucHV0LgorKiBSZXF1ZXN0IGludGVycnVwdHMgaW4gYXN5bmNocm9ub3VzIG1vZGUgd2hlcmUgdGhlIHVzZXIncyBpbnRlcnJ1cHQgaGFuZGxlcgorKiB3aWxsIGJlCisqIGNhbGxlZCB3aGVuIHRoZSBpbnRlcnJ1cHQgZmlyZXMuIFVzZXJzIHRoYXQgd2FudCBjb250cm9sIG92ZXIgdGhlIHRocmVhZAorKiBwcmlvcml0eQorKiBzaG91bGQgdXNlIHRoZSBzeW5jaHJvbm91cyBtZXRob2Qgd2l0aCB0aGVpciBvd24gc3Bhd25lZCB0aHJlYWQuCisqIFRoZSBkZWZhdWx0IGlzIGludGVycnVwdCBvbiByaXNpbmcgZWRnZXMgb25seS4KKyovCit2b2lkIEludGVycnVwdGFibGVTZW5zb3JCYXNlOjpSZXF1ZXN0SW50ZXJydXB0cygKKyAgICBJbnRlcnJ1cHRIYW5kbGVyRnVuY3Rpb24gaGFuZGxlciwgdm9pZCAqcGFyYW0pIHsKKyAgaWYgKFN0YXR1c0lzRmF0YWwoKSkgcmV0dXJuOworICB1aW50MzJfdCBpbmRleCA9IG1faW50ZXJydXB0cy0+QWxsb2NhdGUoIkFzeW5jIEludGVycnVwdCIpOworICBpZiAoaW5kZXggPT0gc3RkOjpudW1lcmljX2xpbWl0czx1aW50MzJfdD46Om1heCgpKSB7CisgICAgQ2xvbmVFcnJvcigqbV9pbnRlcnJ1cHRzKTsKKyAgICByZXR1cm47CisgIH0KKyAgbV9pbnRlcnJ1cHRJbmRleCA9IGluZGV4OworCisgIC8vIENyZWF0ZXMgYSBtYW5hZ2VyIHRvbworICBBbGxvY2F0ZUludGVycnVwdHMoZmFsc2UpOworCisgIGludDMyX3Qgc3RhdHVzID0gMDsKKyAgcmVxdWVzdEludGVycnVwdHMobV9pbnRlcnJ1cHQsIEdldE1vZHVsZUZvclJvdXRpbmcoKSwgR2V0Q2hhbm5lbEZvclJvdXRpbmcoKSwKKyAgICAgICAgICAgICAgICAgICAgR2V0QW5hbG9nVHJpZ2dlckZvclJvdXRpbmcoKSwgJnN0YXR1cyk7CisgIFNldFVwU291cmNlRWRnZSh0cnVlLCBmYWxzZSk7CisgIGF0dGFjaEludGVycnVwdEhhbmRsZXIobV9pbnRlcnJ1cHQsIGhhbmRsZXIsIHBhcmFtLCAmc3RhdHVzKTsKKyAgd3BpX3NldEVycm9yV2l0aENvbnRleHQoc3RhdHVzLCBnZXRIQUxFcnJvck1lc3NhZ2Uoc3RhdHVzKSk7Cit9CisKKy8qKgorKiBSZXF1ZXN0IG9uZSBvZiB0aGUgOCBpbnRlcnJ1cHRzIHN5bmNocm9ub3VzbHkgb24gdGhpcyBkaWdpdGFsIGlucHV0LgorKiBSZXF1ZXN0IGludGVycnVwdHMgaW4gc3luY2hyb25vdXMgbW9kZSB3aGVyZSB0aGUgdXNlciBwcm9ncmFtIHdpbGwgaGF2ZSB0bworKiBleHBsaWNpdGx5CisqIHdhaXQgZm9yIHRoZSBpbnRlcnJ1cHQgdG8gb2NjdXIgdXNpbmcgV2FpdEZvckludGVycnVwdC4KKyogVGhlIGRlZmF1bHQgaXMgaW50ZXJydXB0IG9uIHJpc2luZyBlZGdlcyBvbmx5LgorKi8KK3ZvaWQgSW50ZXJydXB0YWJsZVNlbnNvckJhc2U6OlJlcXVlc3RJbnRlcnJ1cHRzKCkgeworICBpZiAoU3RhdHVzSXNGYXRhbCgpKSByZXR1cm47CisgIHVpbnQzMl90IGluZGV4ID0gbV9pbnRlcnJ1cHRzLT5BbGxvY2F0ZSgiU3luYyBJbnRlcnJ1cHQiKTsKKyAgaWYgKGluZGV4ID09IHN0ZDo6bnVtZXJpY19saW1pdHM8dWludDMyX3Q+OjptYXgoKSkgeworICAgIENsb25lRXJyb3IoKm1faW50ZXJydXB0cyk7CisgICAgcmV0dXJuOworICB9CisgIG1faW50ZXJydXB0SW5kZXggPSBpbmRleDsKKworICBBbGxvY2F0ZUludGVycnVwdHModHJ1ZSk7CisKKyAgaW50MzJfdCBzdGF0dXMgPSAwOworICByZXF1ZXN0SW50ZXJydXB0cyhtX2ludGVycnVwdCwgR2V0TW9kdWxlRm9yUm91dGluZygpLCBHZXRDaGFubmVsRm9yUm91dGluZygpLAorICAgICAgICAgICAgICAgICAgICBHZXRBbmFsb2dUcmlnZ2VyRm9yUm91dGluZygpLCAmc3RhdHVzKTsKKyAgd3BpX3NldEVycm9yV2l0aENvbnRleHQoc3RhdHVzLCBnZXRIQUxFcnJvck1lc3NhZ2Uoc3RhdHVzKSk7CisgIFNldFVwU291cmNlRWRnZSh0cnVlLCBmYWxzZSk7Cit9CisKK3ZvaWQgSW50ZXJydXB0YWJsZVNlbnNvckJhc2U6OkFsbG9jYXRlSW50ZXJydXB0cyhib29sIHdhdGNoZXIpIHsKKyAgd3BpX2Fzc2VydChtX2ludGVycnVwdCA9PSBudWxscHRyKTsKKyAgLy8gRXhwZWN0cyB0aGUgY2FsbGluZyBsZWFmIGNsYXNzIHRvIGFsbG9jYXRlIGFuIGludGVycnVwdCBpbmRleC4KKyAgaW50MzJfdCBzdGF0dXMgPSAwOworICBtX2ludGVycnVwdCA9IGluaXRpYWxpemVJbnRlcnJ1cHRzKG1faW50ZXJydXB0SW5kZXgsIHdhdGNoZXIsICZzdGF0dXMpOworICB3cGlfc2V0RXJyb3JXaXRoQ29udGV4dChzdGF0dXMsIGdldEhBTEVycm9yTWVzc2FnZShzdGF0dXMpKTsKK30KKworLyoqCisgKiBDYW5jZWwgaW50ZXJydXB0cyBvbiB0aGlzIGRldmljZS4KKyAqIFRoaXMgZGVhbGxvY2F0ZXMgYWxsIHRoZSBjaGlwb2JqZWN0IHN0cnVjdHVyZXMgYW5kIGRpc2FibGVzIGFueSBpbnRlcnJ1cHRzLgorICovCit2b2lkIEludGVycnVwdGFibGVTZW5zb3JCYXNlOjpDYW5jZWxJbnRlcnJ1cHRzKCkgeworICBpZiAoU3RhdHVzSXNGYXRhbCgpKSByZXR1cm47CisgIHdwaV9hc3NlcnQobV9pbnRlcnJ1cHQgIT0gbnVsbHB0cik7CisgIGludDMyX3Qgc3RhdHVzID0gMDsKKyAgY2xlYW5JbnRlcnJ1cHRzKG1faW50ZXJydXB0LCAmc3RhdHVzKTsKKyAgd3BpX3NldEVycm9yV2l0aENvbnRleHQoc3RhdHVzLCBnZXRIQUxFcnJvck1lc3NhZ2Uoc3RhdHVzKSk7CisgIG1faW50ZXJydXB0ID0gbnVsbHB0cjsKKyAgbV9pbnRlcnJ1cHRzLT5GcmVlKG1faW50ZXJydXB0SW5kZXgpOworfQorCisvKioKKyAqIEluIHN5bmNocm9ub3VzIG1vZGUsIHdhaXQgZm9yIHRoZSBkZWZpbmVkIGludGVycnVwdCB0byBvY2N1ci4gWW91IHNob3VsZAorICogPGI+Tk9UPC9iPiBhdHRlbXB0IHRvIHJlYWQgdGhlCisgKiBzZW5zb3IgZnJvbSBhbm90aGVyIHRocmVhZCB3aGlsZSB3YWl0aW5nIGZvciBhbiBpbnRlcnJ1cHQuIFRoaXMgaXMgbm90CisgKiB0aHJlYWRzYWZlLCBhbmQgY2FuIGNhdXNlCisgKiBtZW1vcnkgY29ycnVwdGlvbgorICogQHBhcmFtIHRpbWVvdXQgVGltZW91dCBpbiBzZWNvbmRzCisgKiBAcGFyYW0gaWdub3JlUHJldmlvdXMgSWYgdHJ1ZSwgaWdub3JlIGludGVycnVwdHMgdGhhdCBoYXBwZW5lZCBiZWZvcmUKKyAqIFdhaXRGb3JJbnRlcnJ1cHQgd2FzIGNhbGxlZC4KKyAqIEByZXR1cm4gV2hhdCBpbnRlcnJ1cHRzIGZpcmVkCisgKi8KK0ludGVycnVwdGFibGVTZW5zb3JCYXNlOjpXYWl0UmVzdWx0IEludGVycnVwdGFibGVTZW5zb3JCYXNlOjpXYWl0Rm9ySW50ZXJydXB0KAorICAgIGZsb2F0IHRpbWVvdXQsIGJvb2wgaWdub3JlUHJldmlvdXMpIHsKKyAgaWYgKFN0YXR1c0lzRmF0YWwoKSkgcmV0dXJuIEludGVycnVwdGFibGVTZW5zb3JCYXNlOjprVGltZW91dDsKKyAgd3BpX2Fzc2VydChtX2ludGVycnVwdCAhPSBudWxscHRyKTsKKyAgaW50MzJfdCBzdGF0dXMgPSAwOworICB1aW50MzJfdCByZXN1bHQ7CisKKyAgcmVzdWx0ID0gd2FpdEZvckludGVycnVwdChtX2ludGVycnVwdCwgdGltZW91dCwgaWdub3JlUHJldmlvdXMsICZzdGF0dXMpOworICB3cGlfc2V0RXJyb3JXaXRoQ29udGV4dChzdGF0dXMsIGdldEhBTEVycm9yTWVzc2FnZShzdGF0dXMpKTsKKworICByZXR1cm4gc3RhdGljX2Nhc3Q8V2FpdFJlc3VsdD4ocmVzdWx0KTsKK30KKworLyoqCisgKiBFbmFibGUgaW50ZXJydXB0cyB0byBvY2N1ciBvbiB0aGlzIGlucHV0LgorICogSW50ZXJydXB0cyBhcmUgZGlzYWJsZWQgd2hlbiB0aGUgUmVxdWVzdEludGVycnVwdCBjYWxsIGlzIG1hZGUuIFRoaXMgZ2l2ZXMKKyAqIHRpbWUgdG8gZG8gdGhlCisgKiBzZXR1cCBvZiB0aGUgb3RoZXIgb3B0aW9ucyBiZWZvcmUgc3RhcnRpbmcgdG8gZmllbGQgaW50ZXJydXB0cy4KKyAqLwordm9pZCBJbnRlcnJ1cHRhYmxlU2Vuc29yQmFzZTo6RW5hYmxlSW50ZXJydXB0cygpIHsKKyAgaWYgKFN0YXR1c0lzRmF0YWwoKSkgcmV0dXJuOworICB3cGlfYXNzZXJ0KG1faW50ZXJydXB0ICE9IG51bGxwdHIpOworICBpbnQzMl90IHN0YXR1cyA9IDA7CisgIGVuYWJsZUludGVycnVwdHMobV9pbnRlcnJ1cHQsICZzdGF0dXMpOworICB3cGlfc2V0RXJyb3JXaXRoQ29udGV4dChzdGF0dXMsIGdldEhBTEVycm9yTWVzc2FnZShzdGF0dXMpKTsKK30KKworLyoqCisgKiBEaXNhYmxlIEludGVycnVwdHMgd2l0aG91dCB3aXRob3V0IGRlYWxsb2NhdGluZyBzdHJ1Y3R1cmVzLgorICovCit2b2lkIEludGVycnVwdGFibGVTZW5zb3JCYXNlOjpEaXNhYmxlSW50ZXJydXB0cygpIHsKKyAgaWYgKFN0YXR1c0lzRmF0YWwoKSkgcmV0dXJuOworICB3cGlfYXNzZXJ0KG1faW50ZXJydXB0ICE9IG51bGxwdHIpOworICBpbnQzMl90IHN0YXR1cyA9IDA7CisgIGRpc2FibGVJbnRlcnJ1cHRzKG1faW50ZXJydXB0LCAmc3RhdHVzKTsKKyAgd3BpX3NldEVycm9yV2l0aENvbnRleHQoc3RhdHVzLCBnZXRIQUxFcnJvck1lc3NhZ2Uoc3RhdHVzKSk7Cit9CisKKy8qKgorICogUmV0dXJuIHRoZSB0aW1lc3RhbXAgZm9yIHRoZSByaXNpbmcgaW50ZXJydXB0IHRoYXQgb2NjdXJyZWQgbW9zdCByZWNlbnRseS4KKyAqIFRoaXMgaXMgaW4gdGhlIHNhbWUgdGltZSBkb21haW4gYXMgR2V0Q2xvY2soKS4KKyAqIFRoZSByaXNpbmctZWRnZSBpbnRlcnJ1cHQgc2hvdWxkIGJlIGVuYWJsZWQgd2l0aAorICoge0BsaW5rICNEaWdpdGFsSW5wdXQuU2V0VXBTb3VyY2VFZGdlfQorICogQHJldHVybiBUaW1lc3RhbXAgaW4gc2Vjb25kcyBzaW5jZSBib290LgorICovCitkb3VibGUgSW50ZXJydXB0YWJsZVNlbnNvckJhc2U6OlJlYWRSaXNpbmdUaW1lc3RhbXAoKSB7CisgIGlmIChTdGF0dXNJc0ZhdGFsKCkpIHJldHVybiAwLjA7CisgIHdwaV9hc3NlcnQobV9pbnRlcnJ1cHQgIT0gbnVsbHB0cik7CisgIGludDMyX3Qgc3RhdHVzID0gMDsKKyAgZG91YmxlIHRpbWVzdGFtcCA9IHJlYWRSaXNpbmdUaW1lc3RhbXAobV9pbnRlcnJ1cHQsICZzdGF0dXMpOworICB3cGlfc2V0RXJyb3JXaXRoQ29udGV4dChzdGF0dXMsIGdldEhBTEVycm9yTWVzc2FnZShzdGF0dXMpKTsKKyAgcmV0dXJuIHRpbWVzdGFtcDsKK30KKworLyoqCisgKiBSZXR1cm4gdGhlIHRpbWVzdGFtcCBmb3IgdGhlIGZhbGxpbmcgaW50ZXJydXB0IHRoYXQgb2NjdXJyZWQgbW9zdCByZWNlbnRseS4KKyAqIFRoaXMgaXMgaW4gdGhlIHNhbWUgdGltZSBkb21haW4gYXMgR2V0Q2xvY2soKS4KKyAqIFRoZSBmYWxsaW5nLWVkZ2UgaW50ZXJydXB0IHNob3VsZCBiZSBlbmFibGVkIHdpdGgKKyAqIHtAbGluayAjRGlnaXRhbElucHV0LlNldFVwU291cmNlRWRnZX0KKyAqIEByZXR1cm4gVGltZXN0YW1wIGluIHNlY29uZHMgc2luY2UgYm9vdC4KKyovCitkb3VibGUgSW50ZXJydXB0YWJsZVNlbnNvckJhc2U6OlJlYWRGYWxsaW5nVGltZXN0YW1wKCkgeworICBpZiAoU3RhdHVzSXNGYXRhbCgpKSByZXR1cm4gMC4wOworICB3cGlfYXNzZXJ0KG1faW50ZXJydXB0ICE9IG51bGxwdHIpOworICBpbnQzMl90IHN0YXR1cyA9IDA7CisgIGRvdWJsZSB0aW1lc3RhbXAgPSByZWFkRmFsbGluZ1RpbWVzdGFtcChtX2ludGVycnVwdCwgJnN0YXR1cyk7CisgIHdwaV9zZXRFcnJvcldpdGhDb250ZXh0KHN0YXR1cywgZ2V0SEFMRXJyb3JNZXNzYWdlKHN0YXR1cykpOworICByZXR1cm4gdGltZXN0YW1wOworfQorCisvKioKKyAqIFNldCB3aGljaCBlZGdlIHRvIHRyaWdnZXIgaW50ZXJydXB0cyBvbgorICoKKyAqIEBwYXJhbSByaXNpbmdFZGdlCisgKiAgICAgICAgICAgIHRydWUgdG8gaW50ZXJydXB0IG9uIHJpc2luZyBlZGdlCisgKiBAcGFyYW0gZmFsbGluZ0VkZ2UKKyAqICAgICAgICAgICAgdHJ1ZSB0byBpbnRlcnJ1cHQgb24gZmFsbGluZyBlZGdlCisgKi8KK3ZvaWQgSW50ZXJydXB0YWJsZVNlbnNvckJhc2U6OlNldFVwU291cmNlRWRnZShib29sIHJpc2luZ0VkZ2UsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYm9vbCBmYWxsaW5nRWRnZSkgeworICBpZiAoU3RhdHVzSXNGYXRhbCgpKSByZXR1cm47CisgIGlmIChtX2ludGVycnVwdCA9PSBudWxscHRyKSB7CisgICAgd3BpX3NldFdQSUVycm9yV2l0aENvbnRleHQoCisgICAgICAgIE51bGxQYXJhbWV0ZXIsCisgICAgICAgICJZb3UgbXVzdCBjYWxsIFJlcXVlc3RJbnRlcnJ1cHRzIGJlZm9yZSBTZXRVcFNvdXJjZUVkZ2UiKTsKKyAgICByZXR1cm47CisgIH0KKyAgaWYgKG1faW50ZXJydXB0ICE9IG51bGxwdHIpIHsKKyAgICBpbnQzMl90IHN0YXR1cyA9IDA7CisgICAgc2V0SW50ZXJydXB0VXBTb3VyY2VFZGdlKG1faW50ZXJydXB0LCByaXNpbmdFZGdlLCBmYWxsaW5nRWRnZSwgJnN0YXR1cyk7CisgICAgd3BpX3NldEVycm9yV2l0aENvbnRleHQoc3RhdHVzLCBnZXRIQUxFcnJvck1lc3NhZ2Uoc3RhdHVzKSk7CisgIH0KK30KZGlmZiAtLWdpdCBhL3dwaWxpYmMvQXRoZW5hL3NyYy9JdGVyYXRpdmVSb2JvdC5jcHAgYi93cGlsaWJjL0F0aGVuYS9zcmMvSXRlcmF0aXZlUm9ib3QuY3BwCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmZhMWQyYmEKLS0tIC9kZXYvbnVsbAorKysgYi93cGlsaWJjL0F0aGVuYS9zcmMvSXRlcmF0aXZlUm9ib3QuY3BwCkBAIC0wLDAgKzEsMjI4IEBACisvKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qLworLyogQ29weXJpZ2h0IChjKSBGSVJTVCAyMDA4LiBBbGwgUmlnaHRzIFJlc2VydmVkLgorICovCisvKiBPcGVuIFNvdXJjZSBTb2Z0d2FyZSAtIG1heSBiZSBtb2RpZmllZCBhbmQgc2hhcmVkIGJ5IEZSQyB0ZWFtcy4gVGhlIGNvZGUgICAqLworLyogbXVzdCBiZSBhY2NvbXBhbmllZCBieSB0aGUgRklSU1QgQlNEIGxpY2Vuc2UgZmlsZSBpbiAkKFdJTkRfQkFTRSkvV1BJTGliLiAgKi8KKy8qLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovCisKKyNpbmNsdWRlICJJdGVyYXRpdmVSb2JvdC5oIgorCisjaW5jbHVkZSAiRHJpdmVyU3RhdGlvbi5oIgorI2luY2x1ZGUgIkhBTC9IQUwuaHBwIgorI2luY2x1ZGUgIlNtYXJ0RGFzaGJvYXJkL1NtYXJ0RGFzaGJvYXJkLmgiCisjaW5jbHVkZSAiTGl2ZVdpbmRvdy9MaXZlV2luZG93LmgiCisjaW5jbHVkZSAibmV0d29ya3RhYmxlcy9OZXR3b3JrVGFibGUuaCIKKworY29uc3RleHByIGRvdWJsZSBJdGVyYXRpdmVSb2JvdDo6a0RlZmF1bHRQZXJpb2Q7CisKKy8qKgorICogUHJvdmlkZSBhbiBhbHRlcm5hdGUgIm1haW4gbG9vcCIgdmlhIFN0YXJ0Q29tcGV0aXRpb24oKS4KKyAqCisgKiBUaGlzIHNwZWNpZmljIFN0YXJ0Q29tcGV0aXRpb24oKSBpbXBsZW1lbnRzICJtYWluIGxvb3AiIGJlaGF2aW91ciBzeW5jZWQgd2l0aAorICogdGhlIERTIHBhY2tldHMKKyAqLwordm9pZCBJdGVyYXRpdmVSb2JvdDo6U3RhcnRDb21wZXRpdGlvbigpIHsKKyAgSEFMUmVwb3J0KEhBTFVzYWdlUmVwb3J0aW5nOjprUmVzb3VyY2VUeXBlX0ZyYW1ld29yaywKKyAgICAgICAgICAgIEhBTFVzYWdlUmVwb3J0aW5nOjprRnJhbWV3b3JrX0l0ZXJhdGl2ZSk7CisKKyAgTGl2ZVdpbmRvdyAqbHcgPSBMaXZlV2luZG93OjpHZXRJbnN0YW5jZSgpOworICAvLyBmaXJzdCBhbmQgb25lLXRpbWUgaW5pdGlhbGl6YXRpb24KKyAgU21hcnREYXNoYm9hcmQ6OmluaXQoKTsKKyAgTmV0d29ya1RhYmxlOjpHZXRUYWJsZSgiTGl2ZVdpbmRvdyIpCisgICAgICAtPkdldFN1YlRhYmxlKCJ+U1RBVFVTfiIpCisgICAgICAtPlB1dEJvb2xlYW4oIkxXIEVuYWJsZWQiLCBmYWxzZSk7CisgIFJvYm90SW5pdCgpOworCisgIC8vIFRlbGwgdGhlIERTIHRoYXQgdGhlIHJvYm90IGlzIHJlYWR5IHRvIGJlIGVuYWJsZWQKKyAgSEFMTmV0d29ya0NvbW11bmljYXRpb25PYnNlcnZlVXNlclByb2dyYW1TdGFydGluZygpOworCisgIC8vIGxvb3AgZm9yZXZlciwgY2FsbGluZyB0aGUgYXBwcm9wcmlhdGUgbW9kZS1kZXBlbmRlbnQgZnVuY3Rpb24KKyAgbHctPlNldEVuYWJsZWQoZmFsc2UpOworICB3aGlsZSAodHJ1ZSkgeworICAgIC8vIENhbGwgdGhlIGFwcHJvcHJpYXRlIGZ1bmN0aW9uIGRlcGVuZGluZyB1cG9uIHRoZSBjdXJyZW50IHJvYm90IG1vZGUKKyAgICBpZiAoSXNEaXNhYmxlZCgpKSB7CisgICAgICAvLyBjYWxsIERpc2FibGVkSW5pdCgpIGlmIHdlIGFyZSBub3cganVzdCBlbnRlcmluZyBkaXNhYmxlZCBtb2RlIGZyb20KKyAgICAgIC8vIGVpdGhlciBhIGRpZmZlcmVudCBtb2RlIG9yIGZyb20gcG93ZXItb24KKyAgICAgIGlmICghbV9kaXNhYmxlZEluaXRpYWxpemVkKSB7CisgICAgICAgIGx3LT5TZXRFbmFibGVkKGZhbHNlKTsKKyAgICAgICAgRGlzYWJsZWRJbml0KCk7CisgICAgICAgIG1fZGlzYWJsZWRJbml0aWFsaXplZCA9IHRydWU7CisgICAgICAgIC8vIHJlc2V0IHRoZSBpbml0aWFsaXphdGlvbiBmbGFncyBmb3IgdGhlIG90aGVyIG1vZGVzCisgICAgICAgIG1fYXV0b25vbW91c0luaXRpYWxpemVkID0gZmFsc2U7CisgICAgICAgIG1fdGVsZW9wSW5pdGlhbGl6ZWQgPSBmYWxzZTsKKyAgICAgICAgbV90ZXN0SW5pdGlhbGl6ZWQgPSBmYWxzZTsKKyAgICAgIH0KKyAgICAgIEhBTE5ldHdvcmtDb21tdW5pY2F0aW9uT2JzZXJ2ZVVzZXJQcm9ncmFtRGlzYWJsZWQoKTsKKyAgICAgIERpc2FibGVkUGVyaW9kaWMoKTsKKyAgICB9IGVsc2UgaWYgKElzQXV0b25vbW91cygpKSB7CisgICAgICAvLyBjYWxsIEF1dG9ub21vdXNJbml0KCkgaWYgd2UgYXJlIG5vdyBqdXN0IGVudGVyaW5nIGF1dG9ub21vdXMgbW9kZSBmcm9tCisgICAgICAvLyBlaXRoZXIgYSBkaWZmZXJlbnQgbW9kZSBvciBmcm9tIHBvd2VyLW9uCisgICAgICBpZiAoIW1fYXV0b25vbW91c0luaXRpYWxpemVkKSB7CisgICAgICAgIGx3LT5TZXRFbmFibGVkKGZhbHNlKTsKKyAgICAgICAgQXV0b25vbW91c0luaXQoKTsKKyAgICAgICAgbV9hdXRvbm9tb3VzSW5pdGlhbGl6ZWQgPSB0cnVlOworICAgICAgICAvLyByZXNldCB0aGUgaW5pdGlhbGl6YXRpb24gZmxhZ3MgZm9yIHRoZSBvdGhlciBtb2RlcworICAgICAgICBtX2Rpc2FibGVkSW5pdGlhbGl6ZWQgPSBmYWxzZTsKKyAgICAgICAgbV90ZWxlb3BJbml0aWFsaXplZCA9IGZhbHNlOworICAgICAgICBtX3Rlc3RJbml0aWFsaXplZCA9IGZhbHNlOworICAgICAgfQorICAgICAgSEFMTmV0d29ya0NvbW11bmljYXRpb25PYnNlcnZlVXNlclByb2dyYW1BdXRvbm9tb3VzKCk7CisgICAgICBBdXRvbm9tb3VzUGVyaW9kaWMoKTsKKyAgICB9IGVsc2UgaWYgKElzVGVzdCgpKSB7CisgICAgICAvLyBjYWxsIFRlc3RJbml0KCkgaWYgd2UgYXJlIG5vdyBqdXN0IGVudGVyaW5nIHRlc3QgbW9kZSBmcm9tCisgICAgICAvLyBlaXRoZXIgYSBkaWZmZXJlbnQgbW9kZSBvciBmcm9tIHBvd2VyLW9uCisgICAgICBpZiAoIW1fdGVzdEluaXRpYWxpemVkKSB7CisgICAgICAgIGx3LT5TZXRFbmFibGVkKHRydWUpOworICAgICAgICBUZXN0SW5pdCgpOworICAgICAgICBtX3Rlc3RJbml0aWFsaXplZCA9IHRydWU7CisgICAgICAgIC8vIHJlc2V0IHRoZSBpbml0aWFsaXphdGlvbiBmbGFncyBmb3IgdGhlIG90aGVyIG1vZGVzCisgICAgICAgIG1fZGlzYWJsZWRJbml0aWFsaXplZCA9IGZhbHNlOworICAgICAgICBtX2F1dG9ub21vdXNJbml0aWFsaXplZCA9IGZhbHNlOworICAgICAgICBtX3RlbGVvcEluaXRpYWxpemVkID0gZmFsc2U7CisgICAgICB9CisgICAgICBIQUxOZXR3b3JrQ29tbXVuaWNhdGlvbk9ic2VydmVVc2VyUHJvZ3JhbVRlc3QoKTsKKyAgICAgIFRlc3RQZXJpb2RpYygpOworICAgIH0gZWxzZSB7CisgICAgICAvLyBjYWxsIFRlbGVvcEluaXQoKSBpZiB3ZSBhcmUgbm93IGp1c3QgZW50ZXJpbmcgdGVsZW9wIG1vZGUgZnJvbQorICAgICAgLy8gZWl0aGVyIGEgZGlmZmVyZW50IG1vZGUgb3IgZnJvbSBwb3dlci1vbgorICAgICAgaWYgKCFtX3RlbGVvcEluaXRpYWxpemVkKSB7CisgICAgICAgIGx3LT5TZXRFbmFibGVkKGZhbHNlKTsKKyAgICAgICAgVGVsZW9wSW5pdCgpOworICAgICAgICBtX3RlbGVvcEluaXRpYWxpemVkID0gdHJ1ZTsKKyAgICAgICAgLy8gcmVzZXQgdGhlIGluaXRpYWxpemF0aW9uIGZsYWdzIGZvciB0aGUgb3RoZXIgbW9kZXMKKyAgICAgICAgbV9kaXNhYmxlZEluaXRpYWxpemVkID0gZmFsc2U7CisgICAgICAgIG1fYXV0b25vbW91c0luaXRpYWxpemVkID0gZmFsc2U7CisgICAgICAgIG1fdGVzdEluaXRpYWxpemVkID0gZmFsc2U7CisgICAgICAgIFNjaGVkdWxlcjo6R2V0SW5zdGFuY2UoKS0+U2V0RW5hYmxlZCh0cnVlKTsKKyAgICAgIH0KKyAgICAgIEhBTE5ldHdvcmtDb21tdW5pY2F0aW9uT2JzZXJ2ZVVzZXJQcm9ncmFtVGVsZW9wKCk7CisgICAgICBUZWxlb3BQZXJpb2RpYygpOworICAgIH0KKyAgICAvLyB3YWl0IGZvciBkcml2ZXIgc3RhdGlvbiBkYXRhIHNvIHRoZSBsb29wIGRvZXNuJ3QgaG9nIHRoZSBDUFUKKyAgICBtX2RzLldhaXRGb3JEYXRhKCk7CisgIH0KK30KKworLyoqCisgKiBSb2JvdC13aWRlIGluaXRpYWxpemF0aW9uIGNvZGUgc2hvdWxkIGdvIGhlcmUuCisgKgorICogVXNlcnMgc2hvdWxkIG92ZXJyaWRlIHRoaXMgbWV0aG9kIGZvciBkZWZhdWx0IFJvYm90LXdpZGUgaW5pdGlhbGl6YXRpb24gd2hpY2gKKyAqIHdpbGwgYmUgY2FsbGVkIHdoZW4gdGhlIHJvYm90IGlzIGZpcnN0IHBvd2VyZWQgb24uIEl0IHdpbGwgYmUgY2FsbGVkIGV4YWN0bHkKKyAqIG9uZSB0aW1lLgorICoKKyAqIFdhcm5pbmc6IHRoZSBEcml2ZXIgU3RhdGlvbiAiUm9ib3QgQ29kZSIgbGlnaHQgYW5kIEZNUyAiUm9ib3QgUmVhZHkiCisgKiBpbmRpY2F0b3JzIHdpbGwgYmUgb2ZmIHVudGlsIFJvYm90SW5pdCgpIGV4aXRzLiBDb2RlIGluIFJvYm90SW5pdCgpIHRoYXQKKyAqIHdhaXRzIGZvciBlbmFibGUgd2lsbCBjYXVzZSB0aGUgcm9ib3QgdG8gbmV2ZXIgaW5kaWNhdGUgdGhhdCB0aGUgY29kZSBpcworICogcmVhZHksIGNhdXNpbmcgdGhlIHJvYm90IHRvIGJlIGJ5cGFzc2VkIGluIGEgbWF0Y2guCisgKi8KK3ZvaWQgSXRlcmF0aXZlUm9ib3Q6OlJvYm90SW5pdCgpIHsKKyAgcHJpbnRmKCJEZWZhdWx0ICVzKCkgbWV0aG9kLi4uIE92ZXJsb2FkIG1lIVxuIiwgX19GVU5DVElPTl9fKTsKK30KKworLyoqCisgKiBJbml0aWFsaXphdGlvbiBjb2RlIGZvciBkaXNhYmxlZCBtb2RlIHNob3VsZCBnbyBoZXJlLgorICoKKyAqIFVzZXJzIHNob3VsZCBvdmVycmlkZSB0aGlzIG1ldGhvZCBmb3IgaW5pdGlhbGl6YXRpb24gY29kZSB3aGljaCB3aWxsIGJlCisgKiBjYWxsZWQgZWFjaCB0aW1lCisgKiB0aGUgcm9ib3QgZW50ZXJzIGRpc2FibGVkIG1vZGUuCisgKi8KK3ZvaWQgSXRlcmF0aXZlUm9ib3Q6OkRpc2FibGVkSW5pdCgpIHsKKyAgcHJpbnRmKCJEZWZhdWx0ICVzKCkgbWV0aG9kLi4uIE92ZXJsb2FkIG1lIVxuIiwgX19GVU5DVElPTl9fKTsKK30KKworLyoqCisgKiBJbml0aWFsaXphdGlvbiBjb2RlIGZvciBhdXRvbm9tb3VzIG1vZGUgc2hvdWxkIGdvIGhlcmUuCisgKgorICogVXNlcnMgc2hvdWxkIG92ZXJyaWRlIHRoaXMgbWV0aG9kIGZvciBpbml0aWFsaXphdGlvbiBjb2RlIHdoaWNoIHdpbGwgYmUKKyAqIGNhbGxlZCBlYWNoIHRpbWUKKyAqIHRoZSByb2JvdCBlbnRlcnMgYXV0b25vbW91cyBtb2RlLgorICovCit2b2lkIEl0ZXJhdGl2ZVJvYm90OjpBdXRvbm9tb3VzSW5pdCgpIHsKKyAgcHJpbnRmKCJEZWZhdWx0ICVzKCkgbWV0aG9kLi4uIE92ZXJsb2FkIG1lIVxuIiwgX19GVU5DVElPTl9fKTsKK30KKworLyoqCisgKiBJbml0aWFsaXphdGlvbiBjb2RlIGZvciB0ZWxlb3AgbW9kZSBzaG91bGQgZ28gaGVyZS4KKyAqCisgKiBVc2VycyBzaG91bGQgb3ZlcnJpZGUgdGhpcyBtZXRob2QgZm9yIGluaXRpYWxpemF0aW9uIGNvZGUgd2hpY2ggd2lsbCBiZQorICogY2FsbGVkIGVhY2ggdGltZQorICogdGhlIHJvYm90IGVudGVycyB0ZWxlb3AgbW9kZS4KKyAqLwordm9pZCBJdGVyYXRpdmVSb2JvdDo6VGVsZW9wSW5pdCgpIHsKKyAgcHJpbnRmKCJEZWZhdWx0ICVzKCkgbWV0aG9kLi4uIE92ZXJsb2FkIG1lIVxuIiwgX19GVU5DVElPTl9fKTsKK30KKworLyoqCisgKiBJbml0aWFsaXphdGlvbiBjb2RlIGZvciB0ZXN0IG1vZGUgc2hvdWxkIGdvIGhlcmUuCisgKgorICogVXNlcnMgc2hvdWxkIG92ZXJyaWRlIHRoaXMgbWV0aG9kIGZvciBpbml0aWFsaXphdGlvbiBjb2RlIHdoaWNoIHdpbGwgYmUKKyAqIGNhbGxlZCBlYWNoIHRpbWUKKyAqIHRoZSByb2JvdCBlbnRlcnMgdGVzdCBtb2RlLgorICovCit2b2lkIEl0ZXJhdGl2ZVJvYm90OjpUZXN0SW5pdCgpIHsKKyAgcHJpbnRmKCJEZWZhdWx0ICVzKCkgbWV0aG9kLi4uIE92ZXJsb2FkIG1lIVxuIiwgX19GVU5DVElPTl9fKTsKK30KKworLyoqCisgKiBQZXJpb2RpYyBjb2RlIGZvciBkaXNhYmxlZCBtb2RlIHNob3VsZCBnbyBoZXJlLgorICoKKyAqIFVzZXJzIHNob3VsZCBvdmVycmlkZSB0aGlzIG1ldGhvZCBmb3IgY29kZSB3aGljaCB3aWxsIGJlIGNhbGxlZCBwZXJpb2RpY2FsbHkKKyAqIGF0IGEgcmVndWxhcgorICogcmF0ZSB3aGlsZSB0aGUgcm9ib3QgaXMgaW4gZGlzYWJsZWQgbW9kZS4KKyAqLwordm9pZCBJdGVyYXRpdmVSb2JvdDo6RGlzYWJsZWRQZXJpb2RpYygpIHsKKyAgc3RhdGljIGJvb2wgZmlyc3RSdW4gPSB0cnVlOworICBpZiAoZmlyc3RSdW4pIHsKKyAgICBwcmludGYoIkRlZmF1bHQgJXMoKSBtZXRob2QuLi4gT3ZlcmxvYWQgbWUhXG4iLCBfX0ZVTkNUSU9OX18pOworICAgIGZpcnN0UnVuID0gZmFsc2U7CisgIH0KKyAgZGVsYXlUaWNrcygxKTsKK30KKworLyoqCisgKiBQZXJpb2RpYyBjb2RlIGZvciBhdXRvbm9tb3VzIG1vZGUgc2hvdWxkIGdvIGhlcmUuCisgKgorICogVXNlcnMgc2hvdWxkIG92ZXJyaWRlIHRoaXMgbWV0aG9kIGZvciBjb2RlIHdoaWNoIHdpbGwgYmUgY2FsbGVkIHBlcmlvZGljYWxseQorICogYXQgYSByZWd1bGFyCisgKiByYXRlIHdoaWxlIHRoZSByb2JvdCBpcyBpbiBhdXRvbm9tb3VzIG1vZGUuCisgKi8KK3ZvaWQgSXRlcmF0aXZlUm9ib3Q6OkF1dG9ub21vdXNQZXJpb2RpYygpIHsKKyAgc3RhdGljIGJvb2wgZmlyc3RSdW4gPSB0cnVlOworICBpZiAoZmlyc3RSdW4pIHsKKyAgICBwcmludGYoIkRlZmF1bHQgJXMoKSBtZXRob2QuLi4gT3ZlcmxvYWQgbWUhXG4iLCBfX0ZVTkNUSU9OX18pOworICAgIGZpcnN0UnVuID0gZmFsc2U7CisgIH0KKyAgZGVsYXlUaWNrcygxKTsKK30KKworLyoqCisgKiBQZXJpb2RpYyBjb2RlIGZvciB0ZWxlb3AgbW9kZSBzaG91bGQgZ28gaGVyZS4KKyAqCisgKiBVc2VycyBzaG91bGQgb3ZlcnJpZGUgdGhpcyBtZXRob2QgZm9yIGNvZGUgd2hpY2ggd2lsbCBiZSBjYWxsZWQgcGVyaW9kaWNhbGx5CisgKiBhdCBhIHJlZ3VsYXIKKyAqIHJhdGUgd2hpbGUgdGhlIHJvYm90IGlzIGluIHRlbGVvcCBtb2RlLgorICovCit2b2lkIEl0ZXJhdGl2ZVJvYm90OjpUZWxlb3BQZXJpb2RpYygpIHsKKyAgc3RhdGljIGJvb2wgZmlyc3RSdW4gPSB0cnVlOworICBpZiAoZmlyc3RSdW4pIHsKKyAgICBwcmludGYoIkRlZmF1bHQgJXMoKSBtZXRob2QuLi4gT3ZlcmxvYWQgbWUhXG4iLCBfX0ZVTkNUSU9OX18pOworICAgIGZpcnN0UnVuID0gZmFsc2U7CisgIH0KKyAgZGVsYXlUaWNrcygxKTsKK30KKworLyoqCisgKiBQZXJpb2RpYyBjb2RlIGZvciB0ZXN0IG1vZGUgc2hvdWxkIGdvIGhlcmUuCisgKgorICogVXNlcnMgc2hvdWxkIG92ZXJyaWRlIHRoaXMgbWV0aG9kIGZvciBjb2RlIHdoaWNoIHdpbGwgYmUgY2FsbGVkIHBlcmlvZGljYWxseQorICogYXQgYSByZWd1bGFyCisgKiByYXRlIHdoaWxlIHRoZSByb2JvdCBpcyBpbiB0ZXN0IG1vZGUuCisgKi8KK3ZvaWQgSXRlcmF0aXZlUm9ib3Q6OlRlc3RQZXJpb2RpYygpIHsKKyAgc3RhdGljIGJvb2wgZmlyc3RSdW4gPSB0cnVlOworICBpZiAoZmlyc3RSdW4pIHsKKyAgICBwcmludGYoIkRlZmF1bHQgJXMoKSBtZXRob2QuLi4gT3ZlcmxvYWQgbWUhXG4iLCBfX0ZVTkNUSU9OX18pOworICAgIGZpcnN0UnVuID0gZmFsc2U7CisgIH0KKyAgZGVsYXlUaWNrcygxKTsKK30KZGlmZiAtLWdpdCBhL3dwaWxpYmMvQXRoZW5hL3NyYy9KYWd1YXIuY3BwIGIvd3BpbGliYy9BdGhlbmEvc3JjL0phZ3Vhci5jcHAKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uY2U2MWQzNgotLS0gL2Rldi9udWxsCisrKyBiL3dwaWxpYmMvQXRoZW5hL3NyYy9KYWd1YXIuY3BwCkBAIC0wLDAgKzEsNzkgQEAKKy8qLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovCisvKiBDb3B5cmlnaHQgKGMpIEZJUlNUIDIwMDguIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCisgKi8KKy8qIE9wZW4gU291cmNlIFNvZnR3YXJlIC0gbWF5IGJlIG1vZGlmaWVkIGFuZCBzaGFyZWQgYnkgRlJDIHRlYW1zLiBUaGUgY29kZSAgICovCisvKiBtdXN0IGJlIGFjY29tcGFuaWVkIGJ5IHRoZSBGSVJTVCBCU0QgbGljZW5zZSBmaWxlIGluICQoV0lORF9CQVNFKS9XUElMaWIuICAqLworLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi8KKworI2luY2x1ZGUgIkphZ3Vhci5oIgorI2luY2x1ZGUgIkxpdmVXaW5kb3cvTGl2ZVdpbmRvdy5oIgorCisvKioKKyAqIENvbnN0cnVjdG9yIGZvciBhIEphZ3VhciBjb25uZWN0ZWQgdmlhIFBXTQorICogQHBhcmFtIGNoYW5uZWwgVGhlIFBXTSBjaGFubmVsIHRoYXQgdGhlIEphZ3VhciBpcyBhdHRhY2hlZCB0by4gMC05IGFyZQorICogb24tYm9hcmQsIDEwLTE5IGFyZSBvbiB0aGUgTVhQIHBvcnQKKyAqLworSmFndWFyOjpKYWd1YXIodWludDMyX3QgY2hhbm5lbCkgOiBTYWZlUFdNKGNoYW5uZWwpIHsKKyAgLyoqCisgICAqIElucHV0IHByb2ZpbGUgZGVmaW5lZCBieSBMdW1pbmFyeSBNaWNyby4KKyAgICoKKyAgICogRnVsbCByZXZlcnNlIHJhbmdlcyBmcm9tIDAuNjcxMzI1bXMgdG8gMC42OTcyMjExbXMKKyAgICogUHJvcG9ydGlvbmFsIHJldmVyc2UgcmFuZ2VzIGZyb20gMC42OTcyMjExbXMgdG8gMS40NDgyMDc4bXMKKyAgICogTmV1dHJhbCByYW5nZXMgZnJvbSAxLjQ0ODIwNzhtcyB0byAxLjU1MTc5MjJtcworICAgKiBQcm9wb3J0aW9uYWwgZm9yd2FyZCByYW5nZXMgZnJvbSAxLjU1MTc5MjJtcyB0byAyLjMwMjc3ODltcworICAgKiBGdWxsIGZvcndhcmQgcmFuZ2VzIGZyb20gMi4zMDI3Nzg5bXMgdG8gMi4zMjg2NzVtcworICAgKi8KKyAgU2V0Qm91bmRzKDIuMzEsIDEuNTUsIDEuNTA3LCAxLjQ1NCwgLjY5Nyk7CisgIFNldFBlcmlvZE11bHRpcGxpZXIoa1BlcmlvZE11bHRpcGxpZXJfMVgpOworICBTZXRSYXcobV9jZW50ZXJQd20pOworICBTZXRaZXJvTGF0Y2goKTsKKworICBIQUxSZXBvcnQoSEFMVXNhZ2VSZXBvcnRpbmc6OmtSZXNvdXJjZVR5cGVfSmFndWFyLCBHZXRDaGFubmVsKCkpOworICBMaXZlV2luZG93OjpHZXRJbnN0YW5jZSgpLT5BZGRBY3R1YXRvcigiSmFndWFyIiwgR2V0Q2hhbm5lbCgpLCB0aGlzKTsKK30KKworLyoqCisgKiBTZXQgdGhlIFBXTSB2YWx1ZS4KKyAqCisgKiBUaGUgUFdNIHZhbHVlIGlzIHNldCB1c2luZyBhIHJhbmdlIG9mIC0xLjAgdG8gMS4wLCBhcHByb3ByaWF0ZWx5CisgKiBzY2FsaW5nIHRoZSB2YWx1ZSBmb3IgdGhlIEZQR0EuCisgKgorICogQHBhcmFtIHNwZWVkIFRoZSBzcGVlZCB2YWx1ZSBiZXR3ZWVuIC0xLjAgYW5kIDEuMCB0byBzZXQuCisgKiBAcGFyYW0gc3luY0dyb3VwIFVudXNlZCBpbnRlcmZhY2UuCisgKi8KK3ZvaWQgSmFndWFyOjpTZXQoZmxvYXQgc3BlZWQsIHVpbnQ4X3Qgc3luY0dyb3VwKSB7CisgIFNldFNwZWVkKG1faXNJbnZlcnRlZCA/IC1zcGVlZCA6IHNwZWVkKTsKK30KKworLyoqCisgKiBHZXQgdGhlIHJlY2VudGx5IHNldCB2YWx1ZSBvZiB0aGUgUFdNLgorICoKKyAqIEByZXR1cm4gVGhlIG1vc3QgcmVjZW50bHkgc2V0IHZhbHVlIGZvciB0aGUgUFdNIGJldHdlZW4gLTEuMCBhbmQgMS4wLgorICovCitmbG9hdCBKYWd1YXI6OkdldCgpIGNvbnN0IHsgcmV0dXJuIEdldFNwZWVkKCk7IH0KKworLyoqCisgKiBDb21tb24gaW50ZXJmYWNlIGZvciBkaXNhYmxpbmcgYSBtb3Rvci4KKyAqLwordm9pZCBKYWd1YXI6OkRpc2FibGUoKSB7IFNldFJhdyhrUHdtRGlzYWJsZWQpOyB9CisKKy8qKgorKiBDb21tb24gaW50ZXJmYWNlIGZvciBpbnZlcnRpbmcgZGlyZWN0aW9uIG9mIGEgc3BlZWQgY29udHJvbGxlci4KKyogQHBhcmFtIGlzSW52ZXJ0ZWQgVGhlIHN0YXRlIG9mIGludmVyc2lvbiwgdHJ1ZSBpcyBpbnZlcnRlZC4KKyovCit2b2lkIEphZ3Vhcjo6U2V0SW52ZXJ0ZWQoYm9vbCBpc0ludmVydGVkKSB7IG1faXNJbnZlcnRlZCA9IGlzSW52ZXJ0ZWQ7IH0KKworLyoqCisgKiBDb21tb24gaW50ZXJmYWNlIGZvciB0aGUgaW52ZXJ0aW5nIGRpcmVjdGlvbiBvZiBhIHNwZWVkIGNvbnRyb2xsZXIuCisgKgorICogQHJldHVybiBpc0ludmVydGVkIFRoZSBzdGF0ZSBvZiBpbnZlcnNpb24sIHRydWUgaXMgaW52ZXJ0ZWQuCisgKgorICovCitib29sIEphZ3Vhcjo6R2V0SW52ZXJ0ZWQoKSBjb25zdCB7IHJldHVybiBtX2lzSW52ZXJ0ZWQ7IH0KKworLyoqCisgKiBXcml0ZSBvdXQgdGhlIFBJRCB2YWx1ZSBhcyBzZWVuIGluIHRoZSBQSURPdXRwdXQgYmFzZSBvYmplY3QuCisgKgorICogQHBhcmFtIG91dHB1dCBXcml0ZSBvdXQgdGhlIFBXTSB2YWx1ZSBhcyB3YXMgZm91bmQgaW4gdGhlIFBJRENvbnRyb2xsZXIKKyAqLwordm9pZCBKYWd1YXI6OlBJRFdyaXRlKGZsb2F0IG91dHB1dCkgeyBTZXQob3V0cHV0KTsgfQpkaWZmIC0tZ2l0IGEvd3BpbGliYy9BdGhlbmEvc3JjL0pveXN0aWNrLmNwcCBiL3dwaWxpYmMvQXRoZW5hL3NyYy9Kb3lzdGljay5jcHAKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMzg4ODMyYwotLS0gL2Rldi9udWxsCisrKyBiL3dwaWxpYmMvQXRoZW5hL3NyYy9Kb3lzdGljay5jcHAKQEAgLTAsMCArMSwzNzYgQEAKKy8qLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovCisvKiBDb3B5cmlnaHQgKGMpIEZJUlNUIDIwMDguIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCisgKi8KKy8qIE9wZW4gU291cmNlIFNvZnR3YXJlIC0gbWF5IGJlIG1vZGlmaWVkIGFuZCBzaGFyZWQgYnkgRlJDIHRlYW1zLiBUaGUgY29kZSAgICovCisvKiBtdXN0IGJlIGFjY29tcGFuaWVkIGJ5IHRoZSBGSVJTVCBCU0QgbGljZW5zZSBmaWxlIGluICQoV0lORF9CQVNFKS9XUElMaWIuICAqLworLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi8KKworI2luY2x1ZGUgIkpveXN0aWNrLmgiCisjaW5jbHVkZSAiRHJpdmVyU3RhdGlvbi5oIgorI2luY2x1ZGUgIldQSUVycm9ycy5oIgorI2luY2x1ZGUgPG1hdGguaD4KKyNpbmNsdWRlIDxzdHJpbmcuaD4KKworY29uc3QgdWludDMyX3QgSm95c3RpY2s6OmtEZWZhdWx0WEF4aXM7Citjb25zdCB1aW50MzJfdCBKb3lzdGljazo6a0RlZmF1bHRZQXhpczsKK2NvbnN0IHVpbnQzMl90IEpveXN0aWNrOjprRGVmYXVsdFpBeGlzOworY29uc3QgdWludDMyX3QgSm95c3RpY2s6OmtEZWZhdWx0VHdpc3RBeGlzOworY29uc3QgdWludDMyX3QgSm95c3RpY2s6OmtEZWZhdWx0VGhyb3R0bGVBeGlzOworY29uc3QgdWludDMyX3QgSm95c3RpY2s6OmtEZWZhdWx0VHJpZ2dlckJ1dHRvbjsKK2NvbnN0IHVpbnQzMl90IEpveXN0aWNrOjprRGVmYXVsdFRvcEJ1dHRvbjsKK3N0YXRpYyBKb3lzdGljayAqam95c3RpY2tzW0RyaXZlclN0YXRpb246OmtKb3lzdGlja1BvcnRzXTsKK3N0YXRpYyBib29sIGpveVN0aWNrc0luaXRpYWxpemVkID0gZmFsc2U7CisKKy8qKgorICogQ29uc3RydWN0IGFuIGluc3RhbmNlIG9mIGEgam95c3RpY2suCisgKiBUaGUgam95c3RpY2sgaW5kZXggaXMgdGhlIHVzYiBwb3J0IG9uIHRoZSBkcml2ZXJzIHN0YXRpb24uCisgKgorICogQHBhcmFtIHBvcnQgVGhlIHBvcnQgb24gdGhlIGRyaXZlciBzdGF0aW9uIHRoYXQgdGhlIGpveXN0aWNrIGlzIHBsdWdnZWQgaW50bworICogKDAtNSkuCisgKi8KK0pveXN0aWNrOjpKb3lzdGljayh1aW50MzJfdCBwb3J0KQorICAgIDogSm95c3RpY2socG9ydCwga051bUF4aXNUeXBlcywga051bUJ1dHRvblR5cGVzKSB7CisgIG1fYXhlc1trWEF4aXNdID0ga0RlZmF1bHRYQXhpczsKKyAgbV9heGVzW2tZQXhpc10gPSBrRGVmYXVsdFlBeGlzOworICBtX2F4ZXNba1pBeGlzXSA9IGtEZWZhdWx0WkF4aXM7CisgIG1fYXhlc1trVHdpc3RBeGlzXSA9IGtEZWZhdWx0VHdpc3RBeGlzOworICBtX2F4ZXNba1Rocm90dGxlQXhpc10gPSBrRGVmYXVsdFRocm90dGxlQXhpczsKKworICBtX2J1dHRvbnNba1RyaWdnZXJCdXR0b25dID0ga0RlZmF1bHRUcmlnZ2VyQnV0dG9uOworICBtX2J1dHRvbnNba1RvcEJ1dHRvbl0gPSBrRGVmYXVsdFRvcEJ1dHRvbjsKKworICBIQUxSZXBvcnQoSEFMVXNhZ2VSZXBvcnRpbmc6OmtSZXNvdXJjZVR5cGVfSm95c3RpY2ssIHBvcnQpOworfQorCisvKioKKyAqIFZlcnNpb24gb2YgdGhlIGNvbnN0cnVjdG9yIHRvIGJlIGNhbGxlZCBieSBzdWItY2xhc3Nlcy4KKyAqCisgKiBUaGlzIGNvbnN0cnVjdG9yIGFsbG93cyB0aGUgc3ViY2xhc3MgdG8gY29uZmlndXJlIHRoZSBudW1iZXIgb2YgY29uc3RhbnRzCisgKiBmb3IgYXhlcyBhbmQgYnV0dG9ucy4KKyAqCisgKiBAcGFyYW0gcG9ydCBUaGUgcG9ydCBvbiB0aGUgZHJpdmVyIHN0YXRpb24gdGhhdCB0aGUgam95c3RpY2sgaXMgcGx1Z2dlZCBpbnRvLgorICogQHBhcmFtIG51bUF4aXNUeXBlcyBUaGUgbnVtYmVyIG9mIGF4aXMgdHlwZXMgaW4gdGhlIGVudW0uCisgKiBAcGFyYW0gbnVtQnV0dG9uVHlwZXMgVGhlIG51bWJlciBvZiBidXR0b24gdHlwZXMgaW4gdGhlIGVudW0uCisgKi8KK0pveXN0aWNrOjpKb3lzdGljayh1aW50MzJfdCBwb3J0LCB1aW50MzJfdCBudW1BeGlzVHlwZXMsCisgICAgICAgICAgICAgICAgICAgdWludDMyX3QgbnVtQnV0dG9uVHlwZXMpCisgICAgOiBtX2RzKERyaXZlclN0YXRpb246OkdldEluc3RhbmNlKCkpLAorICAgICAgbV9wb3J0KHBvcnQpLAorICAgICAgbV9heGVzKG51bUF4aXNUeXBlcyksCisgICAgICBtX2J1dHRvbnMobnVtQnV0dG9uVHlwZXMpIHsKKyAgaWYgKCFqb3lTdGlja3NJbml0aWFsaXplZCkgeworICAgIGZvciAoYXV0byYgam95c3RpY2sgOiBqb3lzdGlja3MpIGpveXN0aWNrID0gbnVsbHB0cjsKKyAgICBqb3lTdGlja3NJbml0aWFsaXplZCA9IHRydWU7CisgIH0KKyAgaWYgKG1fcG9ydCA+PSBEcml2ZXJTdGF0aW9uOjprSm95c3RpY2tQb3J0cykgeworICAgIHdwaV9zZXRXUElFcnJvcihCYWRKb3lzdGlja0luZGV4KTsKKyAgfSBlbHNlIHsKKyAgICBqb3lzdGlja3NbbV9wb3J0XSA9IHRoaXM7CisgIH0KK30KKworSm95c3RpY2sgKkpveXN0aWNrOjpHZXRTdGlja0ZvclBvcnQodWludDMyX3QgcG9ydCkgeworICBKb3lzdGljayAqc3RpY2sgPSBqb3lzdGlja3NbcG9ydF07CisgIGlmIChzdGljayA9PSBudWxscHRyKSB7CisgICAgc3RpY2sgPSBuZXcgSm95c3RpY2socG9ydCk7CisgICAgam95c3RpY2tzW3BvcnRdID0gc3RpY2s7CisgIH0KKyAgcmV0dXJuIHN0aWNrOworfQorCisvKioKKyAqIEdldCB0aGUgWCB2YWx1ZSBvZiB0aGUgam95c3RpY2suCisgKiBUaGlzIGRlcGVuZHMgb24gdGhlIG1hcHBpbmcgb2YgdGhlIGpveXN0aWNrIGNvbm5lY3RlZCB0byB0aGUgY3VycmVudCBwb3J0LgorICogQHBhcmFtIGhhbmQgVGhpcyBwYXJhbWV0ZXIgaXMgaWdub3JlZCBmb3IgdGhlIEpveXN0aWNrIGNsYXNzIGFuZCBpcyBvbmx5IGhlcmUKKyAqIHRvIGNvbXBsZXRlIHRoZSBHZW5lcmljSElEIGludGVyZmFjZS4KKyAqLworZmxvYXQgSm95c3RpY2s6OkdldFgoSm95c3RpY2tIYW5kIGhhbmQpIGNvbnN0IHsKKyAgcmV0dXJuIEdldFJhd0F4aXMobV9heGVzW2tYQXhpc10pOworfQorCisvKioKKyAqIEdldCB0aGUgWSB2YWx1ZSBvZiB0aGUgam95c3RpY2suCisgKiBUaGlzIGRlcGVuZHMgb24gdGhlIG1hcHBpbmcgb2YgdGhlIGpveXN0aWNrIGNvbm5lY3RlZCB0byB0aGUgY3VycmVudCBwb3J0LgorICogQHBhcmFtIGhhbmQgVGhpcyBwYXJhbWV0ZXIgaXMgaWdub3JlZCBmb3IgdGhlIEpveXN0aWNrIGNsYXNzIGFuZCBpcyBvbmx5IGhlcmUKKyAqIHRvIGNvbXBsZXRlIHRoZSBHZW5lcmljSElEIGludGVyZmFjZS4KKyAqLworZmxvYXQgSm95c3RpY2s6OkdldFkoSm95c3RpY2tIYW5kIGhhbmQpIGNvbnN0IHsKKyAgcmV0dXJuIEdldFJhd0F4aXMobV9heGVzW2tZQXhpc10pOworfQorCisvKioKKyAqIEdldCB0aGUgWiB2YWx1ZSBvZiB0aGUgY3VycmVudCBqb3lzdGljay4KKyAqIFRoaXMgZGVwZW5kcyBvbiB0aGUgbWFwcGluZyBvZiB0aGUgam95c3RpY2sgY29ubmVjdGVkIHRvIHRoZSBjdXJyZW50IHBvcnQuCisgKi8KK2Zsb2F0IEpveXN0aWNrOjpHZXRaKCkgY29uc3QgeyByZXR1cm4gR2V0UmF3QXhpcyhtX2F4ZXNba1pBeGlzXSk7IH0KKworLyoqCisgKiBHZXQgdGhlIHR3aXN0IHZhbHVlIG9mIHRoZSBjdXJyZW50IGpveXN0aWNrLgorICogVGhpcyBkZXBlbmRzIG9uIHRoZSBtYXBwaW5nIG9mIHRoZSBqb3lzdGljayBjb25uZWN0ZWQgdG8gdGhlIGN1cnJlbnQgcG9ydC4KKyAqLworZmxvYXQgSm95c3RpY2s6OkdldFR3aXN0KCkgY29uc3QgeyByZXR1cm4gR2V0UmF3QXhpcyhtX2F4ZXNba1R3aXN0QXhpc10pOyB9CisKKy8qKgorICogR2V0IHRoZSB0aHJvdHRsZSB2YWx1ZSBvZiB0aGUgY3VycmVudCBqb3lzdGljay4KKyAqIFRoaXMgZGVwZW5kcyBvbiB0aGUgbWFwcGluZyBvZiB0aGUgam95c3RpY2sgY29ubmVjdGVkIHRvIHRoZSBjdXJyZW50IHBvcnQuCisgKi8KK2Zsb2F0IEpveXN0aWNrOjpHZXRUaHJvdHRsZSgpIGNvbnN0IHsKKyAgcmV0dXJuIEdldFJhd0F4aXMobV9heGVzW2tUaHJvdHRsZUF4aXNdKTsKK30KKworLyoqCisgKiBHZXQgdGhlIHZhbHVlIG9mIHRoZSBheGlzLgorICoKKyAqIEBwYXJhbSBheGlzIFRoZSBheGlzIHRvIHJlYWQsIHN0YXJ0aW5nIGF0IDAuCisgKiBAcmV0dXJuIFRoZSB2YWx1ZSBvZiB0aGUgYXhpcy4KKyAqLworZmxvYXQgSm95c3RpY2s6OkdldFJhd0F4aXModWludDMyX3QgYXhpcykgY29uc3QgeworICByZXR1cm4gbV9kcy5HZXRTdGlja0F4aXMobV9wb3J0LCBheGlzKTsKK30KKworLyoqCisgKiBGb3IgdGhlIGN1cnJlbnQgam95c3RpY2ssIHJldHVybiB0aGUgYXhpcyBkZXRlcm1pbmVkIGJ5IHRoZSBhcmd1bWVudC4KKyAqCisgKiBUaGlzIGlzIGZvciBjYXNlcyB3aGVyZSB0aGUgam95c3RpY2sgYXhpcyBpcyByZXR1cm5lZCBwcm9ncmFtYXRpY2FsbHksCisgKiBvdGhlcndpc2Ugb25lIG9mIHRoZQorICogcHJldmlvdXMgZnVuY3Rpb25zIHdvdWxkIGJlIHByZWZlcmFibGUgKGZvciBleGFtcGxlIEdldFgoKSkuCisgKgorICogQHBhcmFtIGF4aXMgVGhlIGF4aXMgdG8gcmVhZC4KKyAqIEByZXR1cm4gVGhlIHZhbHVlIG9mIHRoZSBheGlzLgorICovCitmbG9hdCBKb3lzdGljazo6R2V0QXhpcyhBeGlzVHlwZSBheGlzKSBjb25zdCB7CisgIHN3aXRjaCAoYXhpcykgeworICAgIGNhc2Uga1hBeGlzOgorICAgICAgcmV0dXJuIHRoaXMtPkdldFgoKTsKKyAgICBjYXNlIGtZQXhpczoKKyAgICAgIHJldHVybiB0aGlzLT5HZXRZKCk7CisgICAgY2FzZSBrWkF4aXM6CisgICAgICByZXR1cm4gdGhpcy0+R2V0WigpOworICAgIGNhc2Uga1R3aXN0QXhpczoKKyAgICAgIHJldHVybiB0aGlzLT5HZXRUd2lzdCgpOworICAgIGNhc2Uga1Rocm90dGxlQXhpczoKKyAgICAgIHJldHVybiB0aGlzLT5HZXRUaHJvdHRsZSgpOworICAgIGRlZmF1bHQ6CisgICAgICB3cGlfc2V0V1BJRXJyb3IoQmFkSm95c3RpY2tBeGlzKTsKKyAgICAgIHJldHVybiAwLjA7CisgIH0KK30KKworLyoqCisgKiBSZWFkIHRoZSBzdGF0ZSBvZiB0aGUgdHJpZ2dlciBvbiB0aGUgam95c3RpY2suCisgKgorICogTG9vayB1cCB3aGljaCBidXR0b24gaGFzIGJlZW4gYXNzaWduZWQgdG8gdGhlIHRyaWdnZXIgYW5kIHJlYWQgaXRzIHN0YXRlLgorICoKKyAqIEBwYXJhbSBoYW5kIFRoaXMgcGFyYW1ldGVyIGlzIGlnbm9yZWQgZm9yIHRoZSBKb3lzdGljayBjbGFzcyBhbmQgaXMgb25seSBoZXJlCisgKiB0byBjb21wbGV0ZSB0aGUgR2VuZXJpY0hJRCBpbnRlcmZhY2UuCisgKiBAcmV0dXJuIFRoZSBzdGF0ZSBvZiB0aGUgdHJpZ2dlci4KKyAqLworYm9vbCBKb3lzdGljazo6R2V0VHJpZ2dlcihKb3lzdGlja0hhbmQgaGFuZCkgY29uc3QgeworICByZXR1cm4gR2V0UmF3QnV0dG9uKG1fYnV0dG9uc1trVHJpZ2dlckJ1dHRvbl0pOworfQorCisvKioKKyAqIFJlYWQgdGhlIHN0YXRlIG9mIHRoZSB0b3AgYnV0dG9uIG9uIHRoZSBqb3lzdGljay4KKyAqCisgKiBMb29rIHVwIHdoaWNoIGJ1dHRvbiBoYXMgYmVlbiBhc3NpZ25lZCB0byB0aGUgdG9wIGFuZCByZWFkIGl0cyBzdGF0ZS4KKyAqCisgKiBAcGFyYW0gaGFuZCBUaGlzIHBhcmFtZXRlciBpcyBpZ25vcmVkIGZvciB0aGUgSm95c3RpY2sgY2xhc3MgYW5kIGlzIG9ubHkgaGVyZQorICogdG8gY29tcGxldGUgdGhlIEdlbmVyaWNISUQgaW50ZXJmYWNlLgorICogQHJldHVybiBUaGUgc3RhdGUgb2YgdGhlIHRvcCBidXR0b24uCisgKi8KK2Jvb2wgSm95c3RpY2s6OkdldFRvcChKb3lzdGlja0hhbmQgaGFuZCkgY29uc3QgeworICByZXR1cm4gR2V0UmF3QnV0dG9uKG1fYnV0dG9uc1trVG9wQnV0dG9uXSk7Cit9CisKKy8qKgorICogVGhpcyBpcyBub3Qgc3VwcG9ydGVkIGZvciB0aGUgSm95c3RpY2suCisgKiBUaGlzIG1ldGhvZCBpcyBvbmx5IGhlcmUgdG8gY29tcGxldGUgdGhlIEdlbmVyaWNISUQgaW50ZXJmYWNlLgorICovCitib29sIEpveXN0aWNrOjpHZXRCdW1wZXIoSm95c3RpY2tIYW5kIGhhbmQpIGNvbnN0IHsKKyAgLy8gSm95c3RpY2tzIGRvbid0IGhhdmUgYnVtcGVycy4KKyAgcmV0dXJuIGZhbHNlOworfQorCisvKioKKyAqIEdldCB0aGUgYnV0dG9uIHZhbHVlIChzdGFydGluZyBhdCBidXR0b24gMSkKKyAqCisgKiBUaGUgYnV0dG9ucyBhcmUgcmV0dXJuZWQgaW4gYSBzaW5nbGUgMTYgYml0IHZhbHVlIHdpdGggb25lIGJpdCByZXByZXNlbnRpbmcKKyAqIHRoZSBzdGF0ZQorICogb2YgZWFjaCBidXR0b24uIFRoZSBhcHByb3ByaWF0ZSBidXR0b24gaXMgcmV0dXJuZWQgYXMgYSBib29sZWFuIHZhbHVlLgorICoKKyAqIEBwYXJhbSBidXR0b24gVGhlIGJ1dHRvbiBudW1iZXIgdG8gYmUgcmVhZCAoc3RhcnRpbmcgYXQgMSkKKyAqIEByZXR1cm4gVGhlIHN0YXRlIG9mIHRoZSBidXR0b24uCisgKiovCitib29sIEpveXN0aWNrOjpHZXRSYXdCdXR0b24odWludDMyX3QgYnV0dG9uKSBjb25zdCB7CisgIHJldHVybiBtX2RzLkdldFN0aWNrQnV0dG9uKG1fcG9ydCwgYnV0dG9uKTsKK30KKworLyoqCisgKiBHZXQgdGhlIHN0YXRlIG9mIGEgUE9WIG9uIHRoZSBqb3lzdGljay4KKyAqCisgKiBAcGFyYW0gcG92IFRoZSBpbmRleCBvZiB0aGUgUE9WIHRvIHJlYWQgKHN0YXJ0aW5nIGF0IDApCisgKiBAcmV0dXJuIHRoZSBhbmdsZSBvZiB0aGUgUE9WIGluIGRlZ3JlZXMsIG9yIC0xIGlmIHRoZSBQT1YgaXMgbm90IHByZXNzZWQuCisgKi8KK2ludCBKb3lzdGljazo6R2V0UE9WKHVpbnQzMl90IHBvdikgY29uc3QgeworICByZXR1cm4gbV9kcy5HZXRTdGlja1BPVihtX3BvcnQsIHBvdik7Cit9CisKKy8qKgorICogR2V0IGJ1dHRvbnMgYmFzZWQgb24gYW4gZW51bWVyYXRlZCB0eXBlLgorICoKKyAqIFRoZSBidXR0b24gdHlwZSB3aWxsIGJlIGxvb2tlZCB1cCBpbiB0aGUgbGlzdCBvZiBidXR0b25zIGFuZCB0aGVuIHJlYWQuCisgKgorICogQHBhcmFtIGJ1dHRvbiBUaGUgdHlwZSBvZiBidXR0b24gdG8gcmVhZC4KKyAqIEByZXR1cm4gVGhlIHN0YXRlIG9mIHRoZSBidXR0b24uCisgKi8KK2Jvb2wgSm95c3RpY2s6OkdldEJ1dHRvbihCdXR0b25UeXBlIGJ1dHRvbikgY29uc3QgeworICBzd2l0Y2ggKGJ1dHRvbikgeworICAgIGNhc2Uga1RyaWdnZXJCdXR0b246CisgICAgICByZXR1cm4gR2V0VHJpZ2dlcigpOworICAgIGNhc2Uga1RvcEJ1dHRvbjoKKyAgICAgIHJldHVybiBHZXRUb3AoKTsKKyAgICBkZWZhdWx0OgorICAgICAgcmV0dXJuIGZhbHNlOworICB9Cit9CisKKy8qKgorICogR2V0IHRoZSBudW1iZXIgb2YgYXhpcyBmb3IgYSBqb3lzdGljaworICoKKyAqIEByZXR1cm4gdGhlIG51bWJlciBvZiBheGlzIGZvciB0aGUgY3VycmVudCBqb3lzdGljaworICovCitpbnQgSm95c3RpY2s6OkdldEF4aXNDb3VudCgpIGNvbnN0IHsgcmV0dXJuIG1fZHMuR2V0U3RpY2tBeGlzQ291bnQobV9wb3J0KTsgfQorCisvKioKKyAqIEdldCB0aGUgdmFsdWUgb2YgaXNYYm94IGZvciB0aGUgam95c3RpY2suCisgKgorICogQHJldHVybiBBIGJvb2xlYW4gdGhhdCBpcyB0cnVlIGlmIHRoZSBqb3lzdGljayBpcyBhbiB4Ym94IGNvbnRyb2xsZXIuCisgKi8KK2Jvb2wgSm95c3RpY2s6OkdldElzWGJveCgpIGNvbnN0IHsgcmV0dXJuIG1fZHMuR2V0Sm95c3RpY2tJc1hib3gobV9wb3J0KTsgfQorCisvKioKKyAqIEdldCB0aGUgSElEIHR5cGUgb2YgdGhlIGNvbnRyb2xsZXIuCisgKgorICogQHJldHVybiB0aGUgSElEIHR5cGUgb2YgdGhlIGNvbnRyb2xsZXIuCisgKi8KK0pveXN0aWNrOjpISURUeXBlIEpveXN0aWNrOjpHZXRUeXBlKCkgY29uc3QgeworICByZXR1cm4gc3RhdGljX2Nhc3Q8SElEVHlwZT4obV9kcy5HZXRKb3lzdGlja1R5cGUobV9wb3J0KSk7Cit9CisKKy8qKgorICogR2V0IHRoZSBuYW1lIG9mIHRoZSBqb3lzdGljay4KKyAqCisgKiBAcmV0dXJuIHRoZSBuYW1lIG9mIHRoZSBjb250cm9sbGVyLgorICovCitzdGQ6OnN0cmluZyBKb3lzdGljazo6R2V0TmFtZSgpIGNvbnN0IHsgcmV0dXJuIG1fZHMuR2V0Sm95c3RpY2tOYW1lKG1fcG9ydCk7IH0KKworLy8gaW50IEpveXN0aWNrOjpHZXRBeGlzVHlwZSh1aW50OF90IGF4aXMpIGNvbnN0CisvL3sKKy8vCXJldHVybiBtX2RzLkdldEpveXN0aWNrQXhpc1R5cGUobV9wb3J0LCBheGlzKTsKKy8vfQorCisvKioKKyAgKiBHZXQgdGhlIG51bWJlciBvZiBheGlzIGZvciBhIGpveXN0aWNrCisgICoKKyogQHJldHVybiB0aGUgbnVtYmVyIG9mIGJ1dHRvbnMgb24gdGhlIGN1cnJlbnQgam95c3RpY2sKKyAqLworaW50IEpveXN0aWNrOjpHZXRCdXR0b25Db3VudCgpIGNvbnN0IHsKKyAgcmV0dXJuIG1fZHMuR2V0U3RpY2tCdXR0b25Db3VudChtX3BvcnQpOworfQorCisvKioKKyAqIEdldCB0aGUgbnVtYmVyIG9mIGF4aXMgZm9yIGEgam95c3RpY2sKKyAqCisgKiBAcmV0dXJuIHRoZW4gdW1iZXIgb2YgUE9WcyBmb3IgdGhlIGN1cnJlbnQgam95c3RpY2sKKyAqLworaW50IEpveXN0aWNrOjpHZXRQT1ZDb3VudCgpIGNvbnN0IHsgcmV0dXJuIG1fZHMuR2V0U3RpY2tQT1ZDb3VudChtX3BvcnQpOyB9CisKKy8qKgorICogR2V0IHRoZSBjaGFubmVsIGN1cnJlbnRseSBhc3NvY2lhdGVkIHdpdGggdGhlIHNwZWNpZmllZCBheGlzLgorICoKKyAqIEBwYXJhbSBheGlzIFRoZSBheGlzIHRvIGxvb2sgdXAgdGhlIGNoYW5uZWwgZm9yLgorICogQHJldHVybiBUaGUgY2hhbm5lbCBmciB0aGUgYXhpcy4KKyAqLwordWludDMyX3QgSm95c3RpY2s6OkdldEF4aXNDaGFubmVsKEF4aXNUeXBlIGF4aXMpIGNvbnN0IHsgcmV0dXJuIG1fYXhlc1theGlzXTsgfQorCisvKioKKyAqIFNldCB0aGUgY2hhbm5lbCBhc3NvY2lhdGVkIHdpdGggYSBzcGVjaWZpZWQgYXhpcy4KKyAqCisgKiBAcGFyYW0gYXhpcyBUaGUgYXhpcyB0byBzZXQgdGhlIGNoYW5uZWwgZm9yLgorICogQHBhcmFtIGNoYW5uZWwgVGhlIGNoYW5uZWwgdG8gc2V0IHRoZSBheGlzIHRvLgorICovCit2b2lkIEpveXN0aWNrOjpTZXRBeGlzQ2hhbm5lbChBeGlzVHlwZSBheGlzLCB1aW50MzJfdCBjaGFubmVsKSB7CisgIG1fYXhlc1theGlzXSA9IGNoYW5uZWw7Cit9CisKKy8qKgorICogR2V0IHRoZSBtYWduaXR1ZGUgb2YgdGhlIGRpcmVjdGlvbiB2ZWN0b3IgZm9ybWVkIGJ5IHRoZSBqb3lzdGljaydzCisgKiBjdXJyZW50IHBvc2l0aW9uIHJlbGF0aXZlIHRvIGl0cyBvcmlnaW4KKyAqCisgKiBAcmV0dXJuIFRoZSBtYWduaXR1ZGUgb2YgdGhlIGRpcmVjdGlvbiB2ZWN0b3IKKyAqLworZmxvYXQgSm95c3RpY2s6OkdldE1hZ25pdHVkZSgpIGNvbnN0IHsKKyAgcmV0dXJuIHNxcnQocG93KEdldFgoKSwgMikgKyBwb3coR2V0WSgpLCAyKSk7Cit9CisKKy8qKgorICogR2V0IHRoZSBkaXJlY3Rpb24gb2YgdGhlIHZlY3RvciBmb3JtZWQgYnkgdGhlIGpveXN0aWNrIGFuZCBpdHMgb3JpZ2luCisgKiBpbiByYWRpYW5zCisgKgorICogQHJldHVybiBUaGUgZGlyZWN0aW9uIG9mIHRoZSB2ZWN0b3IgaW4gcmFkaWFucworICovCitmbG9hdCBKb3lzdGljazo6R2V0RGlyZWN0aW9uUmFkaWFucygpIGNvbnN0IHsgcmV0dXJuIGF0YW4yKEdldFgoKSwgLUdldFkoKSk7IH0KKworLyoqCisgKiBHZXQgdGhlIGRpcmVjdGlvbiBvZiB0aGUgdmVjdG9yIGZvcm1lZCBieSB0aGUgam95c3RpY2sgYW5kIGl0cyBvcmlnaW4KKyAqIGluIGRlZ3JlZXMKKyAqCisgKiB1c2VzIGFjb3MoLTEpIHRvIHJlcHJlc2VudCBQaSBkdWUgdG8gYWJzZW5jZSBvZiByZWFkaWx5IGFjY2Vzc2libGUgUGkKKyAqIGNvbnN0YW50IGluIEMrKworICoKKyAqIEByZXR1cm4gVGhlIGRpcmVjdGlvbiBvZiB0aGUgdmVjdG9yIGluIGRlZ3JlZXMKKyAqLworZmxvYXQgSm95c3RpY2s6OkdldERpcmVjdGlvbkRlZ3JlZXMoKSBjb25zdCB7CisgIHJldHVybiAoMTgwIC8gYWNvcygtMSkpICogR2V0RGlyZWN0aW9uUmFkaWFucygpOworfQorCisvKioKKyAqIFNldCB0aGUgcnVtYmxlIG91dHB1dCBmb3IgdGhlIGpveXN0aWNrLiBUaGUgRFMgY3VycmVudGx5IHN1cHBvcnRzIDIgcnVtYmxlCisgKiB2YWx1ZXMsCisgKiBsZWZ0IHJ1bWJsZSBhbmQgcmlnaHQgcnVtYmxlCisgKiBAcGFyYW0gdHlwZSBXaGljaCBydW1ibGUgdmFsdWUgdG8gc2V0CisgKiBAcGFyYW0gdmFsdWUgVGhlIG5vcm1hbGl6ZWQgdmFsdWUgKDAgdG8gMSkgdG8gc2V0IHRoZSBydW1ibGUgdG8KKyAqLwordm9pZCBKb3lzdGljazo6U2V0UnVtYmxlKFJ1bWJsZVR5cGUgdHlwZSwgZmxvYXQgdmFsdWUpIHsKKyAgaWYgKHZhbHVlIDwgMCkKKyAgICB2YWx1ZSA9IDA7CisgIGVsc2UgaWYgKHZhbHVlID4gMSkKKyAgICB2YWx1ZSA9IDE7CisgIGlmICh0eXBlID09IGtMZWZ0UnVtYmxlKQorICAgIG1fbGVmdFJ1bWJsZSA9IHZhbHVlICogNjU1MzU7CisgIGVsc2UKKyAgICBtX3JpZ2h0UnVtYmxlID0gdmFsdWUgKiA2NTUzNTsKKyAgSEFMU2V0Sm95c3RpY2tPdXRwdXRzKG1fcG9ydCwgbV9vdXRwdXRzLCBtX2xlZnRSdW1ibGUsIG1fcmlnaHRSdW1ibGUpOworfQorCisvKioKKyAqIFNldCBhIHNpbmdsZSBISUQgb3V0cHV0IHZhbHVlIGZvciB0aGUgam95c3RpY2suCisgKiBAcGFyYW0gb3V0cHV0TnVtYmVyIFRoZSBpbmRleCBvZiB0aGUgb3V0cHV0IHRvIHNldCAoMS0zMikKKyAqIEBwYXJhbSB2YWx1ZSBUaGUgdmFsdWUgdG8gc2V0IHRoZSBvdXRwdXQgdG8KKyAqLworCit2b2lkIEpveXN0aWNrOjpTZXRPdXRwdXQodWludDhfdCBvdXRwdXROdW1iZXIsIGJvb2wgdmFsdWUpIHsKKyAgbV9vdXRwdXRzID0KKyAgICAgIChtX291dHB1dHMgJiB+KDEgPDwgKG91dHB1dE51bWJlciAtIDEpKSkgfCAodmFsdWUgPDwgKG91dHB1dE51bWJlciAtIDEpKTsKKworICBIQUxTZXRKb3lzdGlja091dHB1dHMobV9wb3J0LCBtX291dHB1dHMsIG1fbGVmdFJ1bWJsZSwgbV9yaWdodFJ1bWJsZSk7Cit9CisKKy8qKgorICogU2V0IGFsbCBISUQgb3V0cHV0IHZhbHVlcyBmb3IgdGhlIGpveXN0aWNrLgorICogQHBhcmFtIHZhbHVlIFRoZSAzMiBiaXQgb3V0cHV0IHZhbHVlICgxIGJpdCBmb3IgZWFjaCBvdXRwdXQpCisgKi8KK3ZvaWQgSm95c3RpY2s6OlNldE91dHB1dHModWludDMyX3QgdmFsdWUpIHsKKyAgbV9vdXRwdXRzID0gdmFsdWU7CisgIEhBTFNldEpveXN0aWNrT3V0cHV0cyhtX3BvcnQsIG1fb3V0cHV0cywgbV9sZWZ0UnVtYmxlLCBtX3JpZ2h0UnVtYmxlKTsKK30KZGlmZiAtLWdpdCBhL3dwaWxpYmMvQXRoZW5hL3NyYy9Nb3RvclNhZmV0eUhlbHBlci5jcHAgYi93cGlsaWJjL0F0aGVuYS9zcmMvTW90b3JTYWZldHlIZWxwZXIuY3BwCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjYwYmJhMzAKLS0tIC9kZXYvbnVsbAorKysgYi93cGlsaWJjL0F0aGVuYS9zcmMvTW90b3JTYWZldHlIZWxwZXIuY3BwCkBAIC0wLDAgKzEsMTM5IEBACisvKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qLworLyogQ29weXJpZ2h0IChjKSBGSVJTVCAyMDA4LiBBbGwgUmlnaHRzIFJlc2VydmVkLgorICovCisvKiBPcGVuIFNvdXJjZSBTb2Z0d2FyZSAtIG1heSBiZSBtb2RpZmllZCBhbmQgc2hhcmVkIGJ5IEZSQyB0ZWFtcy4gVGhlIGNvZGUgICAqLworLyogbXVzdCBiZSBhY2NvbXBhbmllZCBieSB0aGUgRklSU1QgQlNEIGxpY2Vuc2UgZmlsZSBpbiAkKFdJTkRfQkFTRSkvV1BJTGliLiAgKi8KKy8qLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovCisKKyNpbmNsdWRlICJNb3RvclNhZmV0eUhlbHBlci5oIgorCisjaW5jbHVkZSAiRHJpdmVyU3RhdGlvbi5oIgorI2luY2x1ZGUgIk1vdG9yU2FmZXR5LmgiCisjaW5jbHVkZSAiVGltZXIuaCIKKyNpbmNsdWRlICJXUElFcnJvcnMuaCIKKworI2luY2x1ZGUgPHN0ZGlvLmg+CisjaW5jbHVkZSA8c3N0cmVhbT4KKworc3RkOjpzZXQ8TW90b3JTYWZldHlIZWxwZXIqPiBNb3RvclNhZmV0eUhlbHBlcjo6bV9oZWxwZXJMaXN0OworcHJpb3JpdHlfcmVjdXJzaXZlX211dGV4IE1vdG9yU2FmZXR5SGVscGVyOjptX2xpc3RNdXRleDsKKworLyoqCisgKiBUaGUgY29uc3RydWN0b3IgZm9yIGEgTW90b3JTYWZldHlIZWxwZXIgb2JqZWN0LgorICogVGhlIGhlbHBlciBvYmplY3QgaXMgY29uc3RydWN0ZWQgZm9yIGV2ZXJ5IG9iamVjdCB0aGF0IHdhbnRzIHRvIGltcGxlbWVudCB0aGUKKyAqIE1vdG9yCisgKiBTYWZldHkgcHJvdG9jb2wuIFRoZSBoZWxwZXIgb2JqZWN0IGhhcyB0aGUgY29kZSB0byBhY3R1YWxseSBkbyB0aGUgdGltaW5nIGFuZAorICogY2FsbCB0aGUKKyAqIG1vdG9ycyBTdG9wKCkgbWV0aG9kIHdoZW4gdGhlIHRpbWVvdXQgZXhwaXJlcy4gVGhlIG1vdG9yIG9iamVjdCBpcyBleHBlY3RlZAorICogdG8gY2FsbCB0aGUKKyAqIEZlZWQoKSBtZXRob2Qgd2hlbmV2ZXIgdGhlIG1vdG9ycyB2YWx1ZSBpcyB1cGRhdGVkLgorICogQHBhcmFtIHNhZmVPYmplY3QgYSBwb2ludGVyIHRvIHRoZSBtb3RvciBvYmplY3QgaW1wbGVtZW50aW5nIE1vdG9yU2FmZXR5LgorICogVGhpcyBpcyB1c2VkCisgKiB0byBjYWxsIHRoZSBTdG9wKCkgbWV0aG9kIG9uIHRoZSBtb3Rvci4KKyAqLworTW90b3JTYWZldHlIZWxwZXI6Ok1vdG9yU2FmZXR5SGVscGVyKE1vdG9yU2FmZXR5ICpzYWZlT2JqZWN0KQorICAgIDogbV9zYWZlT2JqZWN0KHNhZmVPYmplY3QpIHsKKyAgbV9lbmFibGVkID0gZmFsc2U7CisgIG1fZXhwaXJhdGlvbiA9IERFRkFVTFRfU0FGRVRZX0VYUElSQVRJT047CisgIG1fc3RvcFRpbWUgPSBUaW1lcjo6R2V0RlBHQVRpbWVzdGFtcCgpOworCisgIHN0ZDo6bG9ja19ndWFyZDxwcmlvcml0eV9yZWN1cnNpdmVfbXV0ZXg+IHN5bmMobV9saXN0TXV0ZXgpOworICBtX2hlbHBlckxpc3QuaW5zZXJ0KHRoaXMpOworfQorCitNb3RvclNhZmV0eUhlbHBlcjo6fk1vdG9yU2FmZXR5SGVscGVyKCkgeworICBzdGQ6OmxvY2tfZ3VhcmQ8cHJpb3JpdHlfcmVjdXJzaXZlX211dGV4PiBzeW5jKG1fbGlzdE11dGV4KTsKKyAgbV9oZWxwZXJMaXN0LmVyYXNlKHRoaXMpOworfQorCisvKioKKyAqIEZlZWQgdGhlIG1vdG9yIHNhZmV0eSBvYmplY3QuCisgKiBSZXNldHMgdGhlIHRpbWVyIG9uIHRoaXMgb2JqZWN0IHRoYXQgaXMgdXNlZCB0byBkbyB0aGUgdGltZW91dHMuCisgKi8KK3ZvaWQgTW90b3JTYWZldHlIZWxwZXI6OkZlZWQoKSB7CisgIHN0ZDo6bG9ja19ndWFyZDxwcmlvcml0eV9yZWN1cnNpdmVfbXV0ZXg+IHN5bmMobV9zeW5jTXV0ZXgpOworICBtX3N0b3BUaW1lID0gVGltZXI6OkdldEZQR0FUaW1lc3RhbXAoKSArIG1fZXhwaXJhdGlvbjsKK30KKworLyoqCisgKiBTZXQgdGhlIGV4cGlyYXRpb24gdGltZSBmb3IgdGhlIGNvcnJlc3BvbmRpbmcgbW90b3Igc2FmZXR5IG9iamVjdC4KKyAqIEBwYXJhbSBleHBpcmF0aW9uVGltZSBUaGUgdGltZW91dCB2YWx1ZSBpbiBzZWNvbmRzLgorICovCit2b2lkIE1vdG9yU2FmZXR5SGVscGVyOjpTZXRFeHBpcmF0aW9uKGZsb2F0IGV4cGlyYXRpb25UaW1lKSB7CisgIHN0ZDo6bG9ja19ndWFyZDxwcmlvcml0eV9yZWN1cnNpdmVfbXV0ZXg+IHN5bmMobV9zeW5jTXV0ZXgpOworICBtX2V4cGlyYXRpb24gPSBleHBpcmF0aW9uVGltZTsKK30KKworLyoqCisgKiBSZXRyaWV2ZSB0aGUgdGltZW91dCB2YWx1ZSBmb3IgdGhlIGNvcnJlc3BvbmRpbmcgbW90b3Igc2FmZXR5IG9iamVjdC4KKyAqIEByZXR1cm4gdGhlIHRpbWVvdXQgdmFsdWUgaW4gc2Vjb25kcy4KKyAqLworZmxvYXQgTW90b3JTYWZldHlIZWxwZXI6OkdldEV4cGlyYXRpb24oKSBjb25zdCB7CisgIHN0ZDo6bG9ja19ndWFyZDxwcmlvcml0eV9yZWN1cnNpdmVfbXV0ZXg+IHN5bmMobV9zeW5jTXV0ZXgpOworICByZXR1cm4gbV9leHBpcmF0aW9uOworfQorCisvKioKKyAqIERldGVybWluZSBpZiB0aGUgbW90b3IgaXMgc3RpbGwgb3BlcmF0aW5nIG9yIGhhcyB0aW1lZCBvdXQuCisgKiBAcmV0dXJuIGEgdHJ1ZSB2YWx1ZSBpZiB0aGUgbW90b3IgaXMgc3RpbGwgb3BlcmF0aW5nIG5vcm1hbGx5IGFuZCBoYXNuJ3QKKyAqIHRpbWVkIG91dC4KKyAqLworYm9vbCBNb3RvclNhZmV0eUhlbHBlcjo6SXNBbGl2ZSgpIGNvbnN0IHsKKyAgc3RkOjpsb2NrX2d1YXJkPHByaW9yaXR5X3JlY3Vyc2l2ZV9tdXRleD4gc3luYyhtX3N5bmNNdXRleCk7CisgIHJldHVybiAhbV9lbmFibGVkIHx8IG1fc3RvcFRpbWUgPiBUaW1lcjo6R2V0RlBHQVRpbWVzdGFtcCgpOworfQorCisvKioKKyAqIENoZWNrIGlmIHRoaXMgbW90b3IgaGFzIGV4Y2VlZGVkIGl0cyB0aW1lb3V0LgorICogVGhpcyBtZXRob2QgaXMgY2FsbGVkIHBlcmlvZGljYWxseSB0byBkZXRlcm1pbmUgaWYgdGhpcyBtb3RvciBoYXMgZXhjZWVkZWQKKyAqIGl0cyB0aW1lb3V0CisgKiB2YWx1ZS4gSWYgaXQgaGFzLCB0aGUgc3RvcCBtZXRob2QgaXMgY2FsbGVkLCBhbmQgdGhlIG1vdG9yIGlzIHNodXQgZG93biB1bnRpbAorICogaXRzIHZhbHVlIGlzCisgKiB1cGRhdGVkIGFnYWluLgorICovCit2b2lkIE1vdG9yU2FmZXR5SGVscGVyOjpDaGVjaygpIHsKKyAgRHJpdmVyU3RhdGlvbiAmZHMgPSBEcml2ZXJTdGF0aW9uOjpHZXRJbnN0YW5jZSgpOworICBpZiAoIW1fZW5hYmxlZCB8fCBkcy5Jc0Rpc2FibGVkKCkgfHwgZHMuSXNUZXN0KCkpIHJldHVybjsKKworICBzdGQ6OmxvY2tfZ3VhcmQ8cHJpb3JpdHlfcmVjdXJzaXZlX211dGV4PiBzeW5jKG1fc3luY011dGV4KTsKKyAgaWYgKG1fc3RvcFRpbWUgPCBUaW1lcjo6R2V0RlBHQVRpbWVzdGFtcCgpKSB7CisgICAgc3RkOjpvc3RyaW5nc3RyZWFtIGRlc2M7CisgICAgbV9zYWZlT2JqZWN0LT5HZXREZXNjcmlwdGlvbihkZXNjKTsKKyAgICBkZXNjIDw8ICAiLi4uIE91dHB1dCBub3QgdXBkYXRlZCBvZnRlbiBlbm91Z2guIjsKKyAgICB3cGlfc2V0V1BJRXJyb3JXaXRoQ29udGV4dChUaW1lb3V0LCBkZXNjLnN0cigpLmNfc3RyKCkpOworICAgIG1fc2FmZU9iamVjdC0+U3RvcE1vdG9yKCk7CisgIH0KK30KKworLyoqCisgKiBFbmFibGUvZGlzYWJsZSBtb3RvciBzYWZldHkgZm9yIHRoaXMgZGV2aWNlCisgKiBUdXJuIG9uIGFuZCBvZmYgdGhlIG1vdG9yIHNhZmV0eSBvcHRpb24gZm9yIHRoaXMgUFdNIG9iamVjdC4KKyAqIEBwYXJhbSBlbmFibGVkIFRydWUgaWYgbW90b3Igc2FmZXR5IGlzIGVuZm9yY2VkIGZvciB0aGlzIG9iamVjdAorICovCit2b2lkIE1vdG9yU2FmZXR5SGVscGVyOjpTZXRTYWZldHlFbmFibGVkKGJvb2wgZW5hYmxlZCkgeworICBzdGQ6OmxvY2tfZ3VhcmQ8cHJpb3JpdHlfcmVjdXJzaXZlX211dGV4PiBzeW5jKG1fc3luY011dGV4KTsKKyAgbV9lbmFibGVkID0gZW5hYmxlZDsKK30KKworLyoqCisgKiBSZXR1cm4gdGhlIHN0YXRlIG9mIHRoZSBtb3RvciBzYWZldHkgZW5hYmxlZCBmbGFnCisgKiBSZXR1cm4gaWYgdGhlIG1vdG9yIHNhZmV0eSBpcyBjdXJyZW50bHkgZW5hYmxlZCBmb3IgdGhpcyBkZXZpY2NlLgorICogQHJldHVybiBUcnVlIGlmIG1vdG9yIHNhZmV0eSBpcyBlbmZvcmNlZCBmb3IgdGhpcyBkZXZpY2UKKyAqLworYm9vbCBNb3RvclNhZmV0eUhlbHBlcjo6SXNTYWZldHlFbmFibGVkKCkgY29uc3QgeworICBzdGQ6OmxvY2tfZ3VhcmQ8cHJpb3JpdHlfcmVjdXJzaXZlX211dGV4PiBzeW5jKG1fc3luY011dGV4KTsKKyAgcmV0dXJuIG1fZW5hYmxlZDsKK30KKworLyoqCisgKiBDaGVjayB0aGUgbW90b3JzIHRvIHNlZSBpZiBhbnkgaGF2ZSB0aW1lZCBvdXQuCisgKiBUaGlzIHN0YXRpYyAgbWV0aG9kIGlzIGNhbGxlZCBwZXJpb2RpY2FsbHkgdG8gcG9sbCBhbGwgdGhlIG1vdG9ycyBhbmQgc3RvcAorICogYW55IHRoYXQgaGF2ZQorICogdGltZWQgb3V0LgorICovCit2b2lkIE1vdG9yU2FmZXR5SGVscGVyOjpDaGVja01vdG9ycygpIHsKKyAgc3RkOjpsb2NrX2d1YXJkPHByaW9yaXR5X3JlY3Vyc2l2ZV9tdXRleD4gc3luYyhtX2xpc3RNdXRleCk7CisgIGZvciAoYXV0byBlbGVtIDogbV9oZWxwZXJMaXN0KSB7CisgICAgZWxlbS0+Q2hlY2soKTsKKyAgfQorfQpkaWZmIC0tZ2l0IGEvd3BpbGliYy9BdGhlbmEvc3JjL05vdGlmaWVyLmNwcCBiL3dwaWxpYmMvQXRoZW5hL3NyYy9Ob3RpZmllci5jcHAKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZmMzMDU5YwotLS0gL2Rldi9udWxsCisrKyBiL3dwaWxpYmMvQXRoZW5hL3NyYy9Ob3RpZmllci5jcHAKQEAgLTAsMCArMSwyNjMgQEAKKy8qLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovCisvKiBDb3B5cmlnaHQgKGMpIEZJUlNUIDIwMDguIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCisgKi8KKy8qIE9wZW4gU291cmNlIFNvZnR3YXJlIC0gbWF5IGJlIG1vZGlmaWVkIGFuZCBzaGFyZWQgYnkgRlJDIHRlYW1zLiBUaGUgY29kZSAgICovCisvKiBtdXN0IGJlIGFjY29tcGFuaWVkIGJ5IHRoZSBGSVJTVCBCU0QgbGljZW5zZSBmaWxlIGluICQoV0lORF9CQVNFKS9XUElMaWIuICAqLworLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi8KKworI2luY2x1ZGUgIk5vdGlmaWVyLmgiCisjaW5jbHVkZSAiVGltZXIuaCIKKyNpbmNsdWRlICJVdGlsaXR5LmgiCisjaW5jbHVkZSAiV1BJRXJyb3JzLmgiCisjaW5jbHVkZSAiSEFML0hBTC5ocHAiCisKK05vdGlmaWVyICpOb3RpZmllcjo6dGltZXJRdWV1ZUhlYWQgPSBudWxscHRyOworcHJpb3JpdHlfcmVjdXJzaXZlX211dGV4IE5vdGlmaWVyOjpxdWV1ZU11dGV4OworcHJpb3JpdHlfbXV0ZXggTm90aWZpZXI6OmhhbE11dGV4Owordm9pZCAqTm90aWZpZXI6Om1fbm90aWZpZXIgPSBudWxscHRyOworc3RkOjphdG9taWM8aW50PiBOb3RpZmllcjo6cmVmY291bnR7MH07CisKKy8qKgorICogQ3JlYXRlIGEgTm90aWZpZXIgZm9yIHRpbWVyIGV2ZW50IG5vdGlmaWNhdGlvbi4KKyAqIEBwYXJhbSBoYW5kbGVyIFRoZSBoYW5kbGVyIGlzIGNhbGxlZCBhdCB0aGUgbm90aWZpY2F0aW9uIHRpbWUgd2hpY2ggaXMgc2V0CisgKiB1c2luZyBTdGFydFNpbmdsZSBvciBTdGFydFBlcmlvZGljLgorICovCitOb3RpZmllcjo6Tm90aWZpZXIoVGltZXJFdmVudEhhbmRsZXIgaGFuZGxlciwgdm9pZCAqcGFyYW0pIHsKKyAgaWYgKGhhbmRsZXIgPT0gbnVsbHB0cikKKyAgICB3cGlfc2V0V1BJRXJyb3JXaXRoQ29udGV4dChOdWxsUGFyYW1ldGVyLCAiaGFuZGxlciBtdXN0IG5vdCBiZSBudWxscHRyIik7CisgIG1faGFuZGxlciA9IGhhbmRsZXI7CisgIG1fcGFyYW0gPSBwYXJhbTsKKyAgLy8gZG8gdGhlIGZpcnN0IHRpbWUgaW50aWFsaXphdGlvbiBvZiBzdGF0aWMgdmFyaWFibGVzCisgIGlmIChyZWZjb3VudC5mZXRjaF9hZGQoMSkgPT0gMCkgeworICAgIGludDMyX3Qgc3RhdHVzID0gMDsKKyAgICB7CisgICAgICBzdGQ6OmxvY2tfZ3VhcmQ8cHJpb3JpdHlfbXV0ZXg+IHN5bmMoaGFsTXV0ZXgpOworICAgICAgaWYgKCFtX25vdGlmaWVyKQorICAgICAgICBtX25vdGlmaWVyID0gaW5pdGlhbGl6ZU5vdGlmaWVyKFByb2Nlc3NRdWV1ZSwgbnVsbHB0ciwgJnN0YXR1cyk7CisgICAgfQorICAgIHdwaV9zZXRFcnJvcldpdGhDb250ZXh0KHN0YXR1cywgZ2V0SEFMRXJyb3JNZXNzYWdlKHN0YXR1cykpOworICB9Cit9CisKKy8qKgorICogRnJlZSB0aGUgcmVzb3VyY2VzIGZvciBhIHRpbWVyIGV2ZW50LgorICogQWxsIHJlc291cmNlcyB3aWxsIGJlIGZyZWVkIGFuZCB0aGUgdGltZXIgZXZlbnQgd2lsbCBiZSByZW1vdmVkIGZyb20gdGhlCisgKiBxdWV1ZSBpZiBuZWNlc3NhcnkuCisgKi8KK05vdGlmaWVyOjp+Tm90aWZpZXIoKSB7CisgIHsKKyAgICBzdGQ6OmxvY2tfZ3VhcmQ8cHJpb3JpdHlfcmVjdXJzaXZlX211dGV4PiBzeW5jKHF1ZXVlTXV0ZXgpOworICAgIERlbGV0ZUZyb21RdWV1ZSgpOworICB9CisKKyAgLy8gRGVsZXRlIHRoZSBzdGF0aWMgdmFyaWFibGVzIHdoZW4gdGhlIGxhc3Qgb25lIGlzIGdvaW5nIGF3YXkKKyAgaWYgKHJlZmNvdW50LmZldGNoX3N1YigxKSA9PSAxKSB7CisgICAgaW50MzJfdCBzdGF0dXMgPSAwOworICAgIHsKKyAgICAgIHN0ZDo6bG9ja19ndWFyZDxwcmlvcml0eV9tdXRleD4gc3luYyhoYWxNdXRleCk7CisgICAgICBpZiAobV9ub3RpZmllcikgeworICAgICAgICBjbGVhbk5vdGlmaWVyKG1fbm90aWZpZXIsICZzdGF0dXMpOworICAgICAgICBtX25vdGlmaWVyID0gbnVsbHB0cjsKKyAgICAgIH0KKyAgICB9CisgICAgd3BpX3NldEVycm9yV2l0aENvbnRleHQoc3RhdHVzLCBnZXRIQUxFcnJvck1lc3NhZ2Uoc3RhdHVzKSk7CisgIH0KKworICAvLyBBY3F1aXJlIHRoZSBtdXRleDsgdGhpcyBtYWtlcyBjZXJ0YWluIHRoYXQgdGhlIGhhbmRsZXIgaXMKKyAgLy8gbm90IGJlaW5nIGV4ZWN1dGVkIGJ5IHRoZSBpbnRlcnJ1cHQgbWFuYWdlci4KKyAgc3RkOjpsb2NrX2d1YXJkPHByaW9yaXR5X211dGV4PiBsb2NrKG1faGFuZGxlck11dGV4KTsKK30KKworLyoqCisgKiBVcGRhdGUgdGhlIGFsYXJtIGhhcmR3YXJlIHRvIHJlZmxlY3QgdGhlIGN1cnJlbnQgZmlyc3QgZWxlbWVudCBpbiB0aGUgcXVldWUuCisgKiBDb21wdXRlIHRoZSB0aW1lIHRoZSBuZXh0IGFsYXJtIHNob3VsZCBvY2N1ciBiYXNlZCBvbiB0aGUgY3VycmVudCB0aW1lIGFuZAorICogdGhlCisgKiBwZXJpb2QgZm9yIHRoZSBmaXJzdCBlbGVtZW50IGluIHRoZSB0aW1lciBxdWV1ZS4KKyAqIFdBUk5JTkc6IHRoaXMgbWV0aG9kIGRvZXMgbm90IGRvIHN5bmNocm9uaXphdGlvbiEgSXQgbXVzdCBiZSBjYWxsZWQgZnJvbQorICogc29tZXdoZXJlCisgKiB0aGF0IGlzIHRha2luZyBjYXJlIG9mIHN5bmNocm9uaXppbmcgYWNjZXNzIHRvIHRoZSBxdWV1ZS4KKyAqLwordm9pZCBOb3RpZmllcjo6VXBkYXRlQWxhcm0oKSB7CisgIGlmICh0aW1lclF1ZXVlSGVhZCAhPSBudWxscHRyKSB7CisgICAgaW50MzJfdCBzdGF0dXMgPSAwOworICAgIC8vIFRoaXMgbG9ja2luZyBpcyBuZWNlc3NhcnkgaW4gb3JkZXIgdG8gYXZvaWQgdHdvIHRoaW5nczoKKyAgICAvLyAgMSkgUmFjZSBjb25kaXRpb24gaXNzdWVzIHdpdGggY2FsbGluZyBjbGVhbk5vdGlmZXIoKSBhbmQKKyAgICAvLyAgICAgdXBkYXRlTm90aWZpZXJBbGFybSgpIGF0IHRoZSBzYW1lIHRpbWUuCisgICAgLy8gIDIpIEF2b2lkIGRlYWRsb2NrIGJ5IG1ha2luZyBpdCBzbyB0aGF0IHRoaXMgd29uJ3QgYmxvY2sgd2FpdGluZworICAgIC8vICAgICBmb3IgdGhlIG11dGV4IHRvIHVubG9jay4KKyAgICAvLyBDaGVja2luZyByZWZjb3VudCBhcyB3ZWxsIGlzIHVubmVjZXNzYXJ5LCBidXQgd2lsbCBub3QgaHVydC4KKyAgICBpZiAoaGFsTXV0ZXgudHJ5X2xvY2soKSAmJiByZWZjb3VudCAhPSAwKSB7CisgICAgICBpZiAobV9ub3RpZmllcikKKyAgICAgICAgdXBkYXRlTm90aWZpZXJBbGFybShtX25vdGlmaWVyLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICh1aW50MzJfdCkodGltZXJRdWV1ZUhlYWQtPm1fZXhwaXJhdGlvblRpbWUgKiAxZTYpLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICZzdGF0dXMpOworICAgICAgaGFsTXV0ZXgudW5sb2NrKCk7CisgICAgfQorICAgIHdwaV9zZXRTdGF0aWNFcnJvcldpdGhDb250ZXh0KHRpbWVyUXVldWVIZWFkLCBzdGF0dXMsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZ2V0SEFMRXJyb3JNZXNzYWdlKHN0YXR1cykpOworICB9Cit9CisKKy8qKgorICogUHJvY2Vzc1F1ZXVlIGlzIGNhbGxlZCB3aGVuZXZlciB0aGVyZSBpcyBhIHRpbWVyIGludGVycnVwdC4KKyAqIFdlIG5lZWQgdG8gd2FrZSB1cCBhbmQgcHJvY2VzcyB0aGUgY3VycmVudCB0b3AgaXRlbSBpbiB0aGUgdGltZXIgcXVldWUgYXMKKyAqIGxvbmcKKyAqIGFzIGl0cyBzY2hlZHVsZWQgdGltZSBpcyBhZnRlciB0aGUgY3VycmVudCB0aW1lLiBUaGVuIHRoZSBpdGVtIGlzIHJlbW92ZWQgb3IKKyAqIHJlc2NoZWR1bGVkIChyZXBldGl0aXZlIGV2ZW50cykgaW4gdGhlIHF1ZXVlLgorICovCit2b2lkIE5vdGlmaWVyOjpQcm9jZXNzUXVldWUodWludDMyX3QgY3VycmVudFRpbWVJbnQsIHZvaWQgKnBhcmFtcykgeworICBOb3RpZmllciAqY3VycmVudDsKKyAgd2hpbGUgKHRydWUpICAvLyBrZWVwIHByb2Nlc3NpbmcgcGFzdCBldmVudHMgdW50aWwgbm8gbW9yZQorICB7CisgICAgeworICAgICAgc3RkOjpsb2NrX2d1YXJkPHByaW9yaXR5X3JlY3Vyc2l2ZV9tdXRleD4gc3luYyhxdWV1ZU11dGV4KTsKKyAgICAgIGRvdWJsZSBjdXJyZW50VGltZSA9IGN1cnJlbnRUaW1lSW50ICogMS4wZS02OworICAgICAgY3VycmVudCA9IHRpbWVyUXVldWVIZWFkOworICAgICAgaWYgKGN1cnJlbnQgPT0gbnVsbHB0ciB8fCBjdXJyZW50LT5tX2V4cGlyYXRpb25UaW1lID4gY3VycmVudFRpbWUpIHsKKyAgICAgICAgYnJlYWs7ICAvLyBubyBtb3JlIHRpbWVyIGV2ZW50cyB0byBwcm9jZXNzCisgICAgICB9CisgICAgICAvLyBuZWVkIHRvIHByb2Nlc3MgdGhpcyBlbnRyeQorICAgICAgdGltZXJRdWV1ZUhlYWQgPSBjdXJyZW50LT5tX25leHRFdmVudDsKKyAgICAgIGlmIChjdXJyZW50LT5tX3BlcmlvZGljKSB7CisgICAgICAgIC8vIGlmIHBlcmlvZGljLCByZXF1ZXVlIHRoZSBldmVudAorICAgICAgICAvLyBjb21wdXRlIHdoZW4gdG8gcHV0IGludG8gcXVldWUKKyAgICAgICAgY3VycmVudC0+SW5zZXJ0SW5RdWV1ZSh0cnVlKTsKKyAgICAgIH0gZWxzZSB7CisgICAgICAgIC8vIG5vdCBwZXJpb2RpYzsgcmVtb3ZlZCBmcm9tIHF1ZXVlCisgICAgICAgIGN1cnJlbnQtPm1fcXVldWVkID0gZmFsc2U7CisgICAgICB9CisgICAgICAvLyBUYWtlIGhhbmRsZXIgbXV0ZXggd2hpbGUgaG9sZGluZyBxdWV1ZSBtdXRleCB0byBtYWtlIHN1cmUKKyAgICAgIC8vICB0aGUgaGFuZGxlciB3aWxsIGV4ZWN1dGUgdG8gY29tcGxldGlvbiBpbiBjYXNlIHdlIGFyZSBiZWluZyBkZWxldGVkLgorICAgICAgY3VycmVudC0+bV9oYW5kbGVyTXV0ZXgubG9jaygpOworICAgIH0KKworICAgIGN1cnJlbnQtPm1faGFuZGxlcihjdXJyZW50LT5tX3BhcmFtKTsgIC8vIGNhbGwgdGhlIGV2ZW50IGhhbmRsZXIKKyAgICBjdXJyZW50LT5tX2hhbmRsZXJNdXRleC51bmxvY2soKTsKKyAgfQorICAvLyByZXNjaGVkdWxlIHRoZSBmaXJzdCBpdGVtIGluIHRoZSBxdWV1ZQorICBzdGQ6OmxvY2tfZ3VhcmQ8cHJpb3JpdHlfcmVjdXJzaXZlX211dGV4PiBzeW5jKHF1ZXVlTXV0ZXgpOworICBVcGRhdGVBbGFybSgpOworfQorCisvKioKKyAqIEluc2VydCB0aGlzIE5vdGlmaWVyIGludG8gdGhlIHRpbWVyIHF1ZXVlIGluIHJpZ2h0IHBsYWNlLgorICogV0FSTklORzogdGhpcyBtZXRob2QgZG9lcyBub3QgZG8gc3luY2hyb25pemF0aW9uISBJdCBtdXN0IGJlIGNhbGxlZCBmcm9tCisgKiBzb21ld2hlcmUKKyAqIHRoYXQgaXMgdGFraW5nIGNhcmUgb2Ygc3luY2hyb25pemluZyBhY2Nlc3MgdG8gdGhlIHF1ZXVlLgorICogQHBhcmFtIHJlc2NoZWR1bGUgSWYgZmFsc2UsIHRoZSBzY2hlZHVsZWQgYWxhcm0gaXMgYmFzZWQgb24gdGhlIGN1cnJlbnQgdGltZQorICogYW5kIFVwZGF0ZUFsYXJtCisgKiBtZXRob2QgaXMgY2FsbGVkIHdoaWNoIHdpbGwgZW5hYmxlIHRoZSBhbGFybSBpZiBuZWNlc3NhcnkuCisgKiBJZiB0cnVlLCB1cGRhdGUgdGhlIHRpbWUgYnkgYWRkaW5nIHRoZSBwZXJpb2QgKG5vIGRyaWZ0KSB3aGVuIHJlc2NoZWR1bGVkCisgKiBwZXJpb2RpYyBmcm9tIFByb2Nlc3NRdWV1ZS4KKyAqIFRoaXMgZW5zdXJlcyB0aGF0IHRoZSBwdWJsaWMgbWV0aG9kcyBvbmx5IHVwZGF0ZSB0aGUgcXVldWUgYWZ0ZXIgZmluaXNoaW5nCisgKiBpbnNlcnRpbmcuCisgKi8KK3ZvaWQgTm90aWZpZXI6Okluc2VydEluUXVldWUoYm9vbCByZXNjaGVkdWxlKSB7CisgIGlmIChyZXNjaGVkdWxlKSB7CisgICAgbV9leHBpcmF0aW9uVGltZSArPSBtX3BlcmlvZDsKKyAgfSBlbHNlIHsKKyAgICBtX2V4cGlyYXRpb25UaW1lID0gR2V0Q2xvY2soKSArIG1fcGVyaW9kOworICB9CisgIGlmIChtX2V4cGlyYXRpb25UaW1lID4gVGltZXI6OmtSb2xsb3ZlclRpbWUpIHsKKyAgICBtX2V4cGlyYXRpb25UaW1lIC09IFRpbWVyOjprUm9sbG92ZXJUaW1lOworICB9CisgIGlmICh0aW1lclF1ZXVlSGVhZCA9PSBudWxscHRyIHx8CisgICAgICB0aW1lclF1ZXVlSGVhZC0+bV9leHBpcmF0aW9uVGltZSA+PSB0aGlzLT5tX2V4cGlyYXRpb25UaW1lKSB7CisgICAgLy8gdGhlIHF1ZXVlIGlzIGVtcHR5IG9yIGdyZWF0ZXIgdGhhbiB0aGUgbmV3IGVudHJ5CisgICAgLy8gdGhlIG5ldyBlbnRyeSBiZWNvbWVzIHRoZSBmaXJzdCBlbGVtZW50CisgICAgdGhpcy0+bV9uZXh0RXZlbnQgPSB0aW1lclF1ZXVlSGVhZDsKKyAgICB0aW1lclF1ZXVlSGVhZCA9IHRoaXM7CisgICAgaWYgKCFyZXNjaGVkdWxlKSB7CisgICAgICAvLyBzaW5jZSB0aGUgZmlyc3QgZWxlbWVudCBjaGFuZ2VkLCB1cGRhdGUgYWxhcm0sIHVubGVzcyB3ZSBhbHJlYWR5IHBsYW4KKyAgICAgIC8vIHRvCisgICAgICBVcGRhdGVBbGFybSgpOworICAgIH0KKyAgfSBlbHNlIHsKKyAgICBmb3IgKE5vdGlmaWVyICoqbnBwID0gJih0aW1lclF1ZXVlSGVhZC0+bV9uZXh0RXZlbnQpOzsKKyAgICAgICAgIG5wcCA9ICYoKm5wcCktPm1fbmV4dEV2ZW50KSB7CisgICAgICBOb3RpZmllciAqbiA9ICpucHA7CisgICAgICBpZiAobiA9PSBudWxscHRyIHx8IG4tPm1fZXhwaXJhdGlvblRpbWUgPiB0aGlzLT5tX2V4cGlyYXRpb25UaW1lKSB7CisgICAgICAgICpucHAgPSB0aGlzOworICAgICAgICB0aGlzLT5tX25leHRFdmVudCA9IG47CisgICAgICAgIGJyZWFrOworICAgICAgfQorICAgIH0KKyAgfQorICBtX3F1ZXVlZCA9IHRydWU7Cit9CisKKy8qKgorICogRGVsZXRlIHRoaXMgTm90aWZpZXIgZnJvbSB0aGUgdGltZXIgcXVldWUuCisgKiBXQVJOSU5HOiB0aGlzIG1ldGhvZCBkb2VzIG5vdCBkbyBzeW5jaHJvbml6YXRpb24hIEl0IG11c3QgYmUgY2FsbGVkIGZyb20KKyAqIHNvbWV3aGVyZQorICogdGhhdCBpcyB0YWtpbmcgY2FyZSBvZiBzeW5jaHJvbml6aW5nIGFjY2VzcyB0byB0aGUgcXVldWUuCisgKiBSZW1vdmUgdGhpcyBOb3RpZmllciBmcm9tIHRoZSB0aW1lciBxdWV1ZSBhbmQgYWRqdXN0IHRoZSBuZXh0IGludGVycnVwdCB0aW1lCisgKiB0byByZWZsZWN0CisgKiB0aGUgY3VycmVudCB0b3Agb2YgdGhlIHF1ZXVlLgorICovCit2b2lkIE5vdGlmaWVyOjpEZWxldGVGcm9tUXVldWUoKSB7CisgIGlmIChtX3F1ZXVlZCkgeworICAgIG1fcXVldWVkID0gZmFsc2U7CisgICAgd3BpX2Fzc2VydCh0aW1lclF1ZXVlSGVhZCAhPSBudWxscHRyKTsKKyAgICBpZiAodGltZXJRdWV1ZUhlYWQgPT0gdGhpcykgeworICAgICAgLy8gcmVtb3ZlIHRoZSBmaXJzdCBpdGVtIGluIHRoZSBsaXN0IC0gdXBkYXRlIHRoZSBhbGFybQorICAgICAgdGltZXJRdWV1ZUhlYWQgPSB0aGlzLT5tX25leHRFdmVudDsKKyAgICAgIFVwZGF0ZUFsYXJtKCk7CisgICAgfSBlbHNlIHsKKyAgICAgIGZvciAoTm90aWZpZXIgKm4gPSB0aW1lclF1ZXVlSGVhZDsgbiAhPSBudWxscHRyOyBuID0gbi0+bV9uZXh0RXZlbnQpIHsKKyAgICAgICAgaWYgKG4tPm1fbmV4dEV2ZW50ID09IHRoaXMpIHsKKyAgICAgICAgICAvLyB0aGlzIGVsZW1lbnQgaXMgdGhlIG5leHQgZWxlbWVudCBmcm9tICpuIGZyb20gdGhlIHF1ZXVlCisgICAgICAgICAgbi0+bV9uZXh0RXZlbnQgPSB0aGlzLT5tX25leHRFdmVudDsgIC8vIHBvaW50IGFyb3VuZCB0aGlzIG9uZQorICAgICAgICB9CisgICAgICB9CisgICAgfQorICB9Cit9CisKKy8qKgorICogUmVnaXN0ZXIgZm9yIHNpbmdsZSBldmVudCBub3RpZmljYXRpb24uCisgKiBBIHRpbWVyIGV2ZW50IGlzIHF1ZXVlZCBmb3IgYSBzaW5nbGUgZXZlbnQgYWZ0ZXIgdGhlIHNwZWNpZmllZCBkZWxheS4KKyAqIEBwYXJhbSBkZWxheSBTZWNvbmRzIHRvIHdhaXQgYmVmb3JlIHRoZSBoYW5kbGVyIGlzIGNhbGxlZC4KKyAqLwordm9pZCBOb3RpZmllcjo6U3RhcnRTaW5nbGUoZG91YmxlIGRlbGF5KSB7CisgIHN0ZDo6bG9ja19ndWFyZDxwcmlvcml0eV9yZWN1cnNpdmVfbXV0ZXg+IHN5bmMocXVldWVNdXRleCk7CisgIG1fcGVyaW9kaWMgPSBmYWxzZTsKKyAgbV9wZXJpb2QgPSBkZWxheTsKKyAgRGVsZXRlRnJvbVF1ZXVlKCk7CisgIEluc2VydEluUXVldWUoZmFsc2UpOworfQorCisvKioKKyAqIFJlZ2lzdGVyIGZvciBwZXJpb2RpYyBldmVudCBub3RpZmljYXRpb24uCisgKiBBIHRpbWVyIGV2ZW50IGlzIHF1ZXVlZCBmb3IgcGVyaW9kaWMgZXZlbnQgbm90aWZpY2F0aW9uLiBFYWNoIHRpbWUgdGhlCisgKiBpbnRlcnJ1cHQKKyAqIG9jY3VycywgdGhlIGV2ZW50IHdpbGwgYmUgaW1tZWRpYXRlbHkgcmVxdWV1ZWQgZm9yIHRoZSBzYW1lIHRpbWUgaW50ZXJ2YWwuCisgKiBAcGFyYW0gcGVyaW9kIFBlcmlvZCBpbiBzZWNvbmRzIHRvIGNhbGwgdGhlIGhhbmRsZXIgc3RhcnRpbmcgb25lIHBlcmlvZCBhZnRlcgorICogdGhlIGNhbGwgdG8gdGhpcyBtZXRob2QuCisgKi8KK3ZvaWQgTm90aWZpZXI6OlN0YXJ0UGVyaW9kaWMoZG91YmxlIHBlcmlvZCkgeworICBzdGQ6OmxvY2tfZ3VhcmQ8cHJpb3JpdHlfcmVjdXJzaXZlX211dGV4PiBzeW5jKHF1ZXVlTXV0ZXgpOworICBtX3BlcmlvZGljID0gdHJ1ZTsKKyAgbV9wZXJpb2QgPSBwZXJpb2Q7CisgIERlbGV0ZUZyb21RdWV1ZSgpOworICBJbnNlcnRJblF1ZXVlKGZhbHNlKTsKK30KKworLyoqCisgKiBTdG9wIHRpbWVyIGV2ZW50cyBmcm9tIG9jY3VyaW5nLgorICogU3RvcCBhbnkgcmVwZWF0aW5nIHRpbWVyIGV2ZW50cyBmcm9tIG9jY3VyaW5nLiBUaGlzIHdpbGwgYWxzbyByZW1vdmUgYW55CisgKiBzaW5nbGUKKyAqIG5vdGlmaWNhdGlvbiBldmVudHMgZnJvbSB0aGUgcXVldWUuCisgKiBJZiBhIHRpbWVyLWJhc2VkIGNhbGwgdG8gdGhlIHJlZ2lzdGVyZWQgaGFuZGxlciBpcyBpbiBwcm9ncmVzcywgdGhpcyBmdW5jdGlvbgorICogd2lsbAorICogYmxvY2sgdW50aWwgdGhlIGhhbmRsZXIgY2FsbCBpcyBjb21wbGV0ZS4KKyAqLwordm9pZCBOb3RpZmllcjo6U3RvcCgpIHsKKyAgeworICAgIHN0ZDo6bG9ja19ndWFyZDxwcmlvcml0eV9yZWN1cnNpdmVfbXV0ZXg+IHN5bmMocXVldWVNdXRleCk7CisgICAgRGVsZXRlRnJvbVF1ZXVlKCk7CisgIH0KKyAgLy8gV2FpdCBmb3IgYSBjdXJyZW50bHkgZXhlY3V0aW5nIGhhbmRsZXIgdG8gY29tcGxldGUgYmVmb3JlIHJldHVybmluZyBmcm9tCisgIC8vIFN0b3AoKQorICBzdGQ6OmxvY2tfZ3VhcmQ8cHJpb3JpdHlfbXV0ZXg+IHN5bmMobV9oYW5kbGVyTXV0ZXgpOworfQpkaWZmIC0tZ2l0IGEvd3BpbGliYy9BdGhlbmEvc3JjL1BJRENvbnRyb2xsZXIuY3BwIGIvd3BpbGliYy9BdGhlbmEvc3JjL1BJRENvbnRyb2xsZXIuY3BwCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmZkYmJiNWEKLS0tIC9kZXYvbnVsbAorKysgYi93cGlsaWJjL0F0aGVuYS9zcmMvUElEQ29udHJvbGxlci5jcHAKQEAgLTAsMCArMSw1ODIgQEAKKy8qLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovCisvKiBDb3B5cmlnaHQgKGMpIEZJUlNUIDIwMDguIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCisgKi8KKy8qIE9wZW4gU291cmNlIFNvZnR3YXJlIC0gbWF5IGJlIG1vZGlmaWVkIGFuZCBzaGFyZWQgYnkgRlJDIHRlYW1zLiBUaGUgY29kZSAgICovCisvKiBtdXN0IGJlIGFjY29tcGFuaWVkIGJ5IHRoZSBGSVJTVCBCU0QgbGljZW5zZSBmaWxlIGluICQoV0lORF9CQVNFKS9XUElMaWIuICAqLworLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi8KKworI2luY2x1ZGUgIlBJRENvbnRyb2xsZXIuaCIKKyNpbmNsdWRlICJOb3RpZmllci5oIgorI2luY2x1ZGUgIlBJRFNvdXJjZS5oIgorI2luY2x1ZGUgIlBJRE91dHB1dC5oIgorI2luY2x1ZGUgPG1hdGguaD4KKyNpbmNsdWRlIDx2ZWN0b3I+CisjaW5jbHVkZSAiSEFML0hBTC5ocHAiCisKK3N0YXRpYyBjb25zdCBzdGQ6OnN0cmluZyBrUCA9ICJwIjsKK3N0YXRpYyBjb25zdCBzdGQ6OnN0cmluZyBrSSA9ICJpIjsKK3N0YXRpYyBjb25zdCBzdGQ6OnN0cmluZyBrRCA9ICJkIjsKK3N0YXRpYyBjb25zdCBzdGQ6OnN0cmluZyBrRiA9ICJmIjsKK3N0YXRpYyBjb25zdCBzdGQ6OnN0cmluZyBrU2V0cG9pbnQgPSAic2V0cG9pbnQiOworc3RhdGljIGNvbnN0IHN0ZDo6c3RyaW5nIGtFbmFibGVkID0gImVuYWJsZWQiOworCisvKioKKyAqIEFsbG9jYXRlIGEgUElEIG9iamVjdCB3aXRoIHRoZSBnaXZlbiBjb25zdGFudHMgZm9yIFAsIEksIEQKKyAqIEBwYXJhbSBLcCB0aGUgcHJvcG9ydGlvbmFsIGNvZWZmaWNpZW50CisgKiBAcGFyYW0gS2kgdGhlIGludGVncmFsIGNvZWZmaWNpZW50CisgKiBAcGFyYW0gS2QgdGhlIGRlcml2YXRpdmUgY29lZmZpY2llbnQKKyAqIEBwYXJhbSBzb3VyY2UgVGhlIFBJRFNvdXJjZSBvYmplY3QgdGhhdCBpcyB1c2VkIHRvIGdldCB2YWx1ZXMKKyAqIEBwYXJhbSBvdXRwdXQgVGhlIFBJRE91dHB1dCBvYmplY3QgdGhhdCBpcyBzZXQgdG8gdGhlIG91dHB1dCB2YWx1ZQorICogQHBhcmFtIHBlcmlvZCB0aGUgbG9vcCB0aW1lIGZvciBkb2luZyBjYWxjdWxhdGlvbnMuIFRoaXMgcGFydGljdWxhcmx5IGVmZmVjdHMKKyAqIGNhbGN1bGF0aW9ucyBvZiB0aGUKKyAqIGludGVncmFsIGFuZCBkaWZmZXJlbnRhbCB0ZXJtcy4gVGhlIGRlZmF1bHQgaXMgNTBtcy4KKyAqLworUElEQ29udHJvbGxlcjo6UElEQ29udHJvbGxlcihmbG9hdCBLcCwgZmxvYXQgS2ksIGZsb2F0IEtkLCBQSURTb3VyY2UgKnNvdXJjZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUElET3V0cHV0ICpvdXRwdXQsIGZsb2F0IHBlcmlvZCkgeworICBJbml0aWFsaXplKEtwLCBLaSwgS2QsIDAuMGYsIHNvdXJjZSwgb3V0cHV0LCBwZXJpb2QpOworfQorCisvKioKKyAqIEFsbG9jYXRlIGEgUElEIG9iamVjdCB3aXRoIHRoZSBnaXZlbiBjb25zdGFudHMgZm9yIFAsIEksIEQKKyAqIEBwYXJhbSBLcCB0aGUgcHJvcG9ydGlvbmFsIGNvZWZmaWNpZW50CisgKiBAcGFyYW0gS2kgdGhlIGludGVncmFsIGNvZWZmaWNpZW50CisgKiBAcGFyYW0gS2QgdGhlIGRlcml2YXRpdmUgY29lZmZpY2llbnQKKyAqIEBwYXJhbSBzb3VyY2UgVGhlIFBJRFNvdXJjZSBvYmplY3QgdGhhdCBpcyB1c2VkIHRvIGdldCB2YWx1ZXMKKyAqIEBwYXJhbSBvdXRwdXQgVGhlIFBJRE91dHB1dCBvYmplY3QgdGhhdCBpcyBzZXQgdG8gdGhlIG91dHB1dCB2YWx1ZQorICogQHBhcmFtIHBlcmlvZCB0aGUgbG9vcCB0aW1lIGZvciBkb2luZyBjYWxjdWxhdGlvbnMuIFRoaXMgcGFydGljdWxhcmx5IGVmZmVjdHMKKyAqIGNhbGN1bGF0aW9ucyBvZiB0aGUKKyAqIGludGVncmFsIGFuZCBkaWZmZXJlbnRhbCB0ZXJtcy4gVGhlIGRlZmF1bHQgaXMgNTBtcy4KKyAqLworUElEQ29udHJvbGxlcjo6UElEQ29udHJvbGxlcihmbG9hdCBLcCwgZmxvYXQgS2ksIGZsb2F0IEtkLCBmbG9hdCBLZiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUElEU291cmNlICpzb3VyY2UsIFBJRE91dHB1dCAqb3V0cHV0LCBmbG9hdCBwZXJpb2QpIHsKKyAgSW5pdGlhbGl6ZShLcCwgS2ksIEtkLCBLZiwgc291cmNlLCBvdXRwdXQsIHBlcmlvZCk7Cit9CisKK3ZvaWQgUElEQ29udHJvbGxlcjo6SW5pdGlhbGl6ZShmbG9hdCBLcCwgZmxvYXQgS2ksIGZsb2F0IEtkLCBmbG9hdCBLZiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBQSURTb3VyY2UgKnNvdXJjZSwgUElET3V0cHV0ICpvdXRwdXQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmxvYXQgcGVyaW9kKSB7CisgIG1fY29udHJvbExvb3AgPSBzdGQ6Om1ha2VfdW5pcXVlPE5vdGlmaWVyPihQSURDb250cm9sbGVyOjpDYWxsQ2FsY3VsYXRlLCB0aGlzKTsKKworICBtX1AgPSBLcDsKKyAgbV9JID0gS2k7CisgIG1fRCA9IEtkOworICBtX0YgPSBLZjsKKworICBtX3BpZElucHV0ID0gc291cmNlOworICBtX3BpZE91dHB1dCA9IG91dHB1dDsKKyAgbV9wZXJpb2QgPSBwZXJpb2Q7CisKKyAgbV9jb250cm9sTG9vcC0+U3RhcnRQZXJpb2RpYyhtX3BlcmlvZCk7CisKKyAgc3RhdGljIGludDMyX3QgaW5zdGFuY2VzID0gMDsKKyAgaW5zdGFuY2VzKys7CisgIEhBTFJlcG9ydChIQUxVc2FnZVJlcG9ydGluZzo6a1Jlc291cmNlVHlwZV9QSURDb250cm9sbGVyLCBpbnN0YW5jZXMpOworfQorCitQSURDb250cm9sbGVyOjp+UElEQ29udHJvbGxlcigpIHsKKyAgaWYgKG1fdGFibGUgIT0gbnVsbHB0cikgbV90YWJsZS0+UmVtb3ZlVGFibGVMaXN0ZW5lcih0aGlzKTsKK30KKworLyoqCisgKiBDYWxsIHRoZSBDYWxjdWxhdGUgbWV0aG9kIGFzIGEgbm9uLXN0YXRpYyBtZXRob2QuIFRoaXMgYXZvaWRzIGhhdmluZyB0bworICogcHJlcGVuZAorICogYWxsIGxvY2FsIHZhcmlhYmxlcyBpbiB0aGF0IG1ldGhvZCB3aXRoIHRoZSBjbGFzcyBwb2ludGVyLiBUaGlzIHdheSB0aGUKKyAqICJ0aGlzIgorICogcG9pbnRlciB3aWxsIGJlIHNldCB1cCBhbmQgY2xhc3MgdmFyaWFibGVzIGNhbiBiZSBjYWxsZWQgbW9yZSBlYXNpbHkuCisgKiBUaGlzIG1ldGhvZCBpcyBzdGF0aWMgYW5kIGNhbGxlZCBieSB0aGUgTm90aWZpZXIgY2xhc3MuCisgKiBAcGFyYW0gY29udHJvbGxlciB0aGUgYWRkcmVzcyBvZiB0aGUgUElEIGNvbnRyb2xsZXIgb2JqZWN0IHRvIHVzZSBpbiB0aGUKKyAqIGJhY2tncm91bmQgbG9vcAorICovCit2b2lkIFBJRENvbnRyb2xsZXI6OkNhbGxDYWxjdWxhdGUodm9pZCAqY29udHJvbGxlcikgeworICBQSURDb250cm9sbGVyICpjb250cm9sID0gKFBJRENvbnRyb2xsZXIgKiljb250cm9sbGVyOworICBjb250cm9sLT5DYWxjdWxhdGUoKTsKK30KKworLyoqCisgKiBSZWFkIHRoZSBpbnB1dCwgY2FsY3VsYXRlIHRoZSBvdXRwdXQgYWNjb3JkaW5nbHksIGFuZCB3cml0ZSB0byB0aGUgb3V0cHV0LgorICogVGhpcyBzaG91bGQgb25seSBiZSBjYWxsZWQgYnkgdGhlIE5vdGlmaWVyIGluZGlyZWN0bHkgdGhyb3VnaCBDYWxsQ2FsY3VsYXRlCisgKiBhbmQgaXMgY3JlYXRlZCBkdXJpbmcgaW5pdGlhbGl6YXRpb24uCisgKi8KK3ZvaWQgUElEQ29udHJvbGxlcjo6Q2FsY3VsYXRlKCkgeworICBib29sIGVuYWJsZWQ7CisgIFBJRFNvdXJjZSAqcGlkSW5wdXQ7CisgIFBJRE91dHB1dCAqcGlkT3V0cHV0OworCisgIHsKKyAgICBzdGQ6OmxvY2tfZ3VhcmQ8cHJpb3JpdHlfbXV0ZXg+IHN5bmMobV9tdXRleCk7CisgICAgcGlkSW5wdXQgPSBtX3BpZElucHV0OworICAgIHBpZE91dHB1dCA9IG1fcGlkT3V0cHV0OworICAgIGVuYWJsZWQgPSBtX2VuYWJsZWQ7CisgIH0KKworICBpZiAocGlkSW5wdXQgPT0gbnVsbHB0cikgcmV0dXJuOworICBpZiAocGlkT3V0cHV0ID09IG51bGxwdHIpIHJldHVybjsKKworICBpZiAoZW5hYmxlZCkgeworICAgIHN0ZDo6bG9ja19ndWFyZDxwcmlvcml0eV9tdXRleD4gc3luYyhtX211dGV4KTsKKyAgICBmbG9hdCBpbnB1dCA9IHBpZElucHV0LT5QSURHZXQoKTsKKyAgICBmbG9hdCByZXN1bHQ7CisgICAgUElET3V0cHV0ICpwaWRPdXRwdXQ7CisKKyAgICBtX2Vycm9yID0gbV9zZXRwb2ludCAtIGlucHV0OworICAgIGlmIChtX2NvbnRpbnVvdXMpIHsKKyAgICAgIGlmIChmYWJzKG1fZXJyb3IpID4gKG1fbWF4aW11bUlucHV0IC0gbV9taW5pbXVtSW5wdXQpIC8gMikgeworICAgICAgICBpZiAobV9lcnJvciA+IDApIHsKKyAgICAgICAgICBtX2Vycm9yID0gbV9lcnJvciAtIG1fbWF4aW11bUlucHV0ICsgbV9taW5pbXVtSW5wdXQ7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgbV9lcnJvciA9IG1fZXJyb3IgKyBtX21heGltdW1JbnB1dCAtIG1fbWluaW11bUlucHV0OworICAgICAgICB9CisgICAgICB9CisgICAgfQorCisgICAgaWYgKG1fcGlkSW5wdXQtPkdldFBJRFNvdXJjZVR5cGUoKSA9PSBQSURTb3VyY2VUeXBlOjprUmF0ZSkgeworICAgICAgaWYgKG1fUCAhPSAwKSB7CisgICAgICAgIGRvdWJsZSBwb3RlbnRpYWxQR2FpbiA9IChtX3RvdGFsRXJyb3IgKyBtX2Vycm9yKSAqIG1fUDsKKyAgICAgICAgaWYgKHBvdGVudGlhbFBHYWluIDwgbV9tYXhpbXVtT3V0cHV0KSB7CisgICAgICAgICAgaWYgKHBvdGVudGlhbFBHYWluID4gbV9taW5pbXVtT3V0cHV0KQorICAgICAgICAgICAgbV90b3RhbEVycm9yICs9IG1fZXJyb3I7CisgICAgICAgICAgZWxzZQorICAgICAgICAgICAgbV90b3RhbEVycm9yID0gbV9taW5pbXVtT3V0cHV0IC8gbV9QOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgIG1fdG90YWxFcnJvciA9IG1fbWF4aW11bU91dHB1dCAvIG1fUDsKKyAgICAgICAgfQorICAgICAgfQorCisgICAgICBtX3Jlc3VsdCA9IG1fRCAqIG1fZXJyb3IgKyBtX1AgKiBtX3RvdGFsRXJyb3IgKyBtX3NldHBvaW50ICogbV9GOworICAgIH0KKyAgICBlbHNlIHsKKyAgICAgIGlmIChtX0kgIT0gMCkgeworICAgICAgICBkb3VibGUgcG90ZW50aWFsSUdhaW4gPSAobV90b3RhbEVycm9yICsgbV9lcnJvcikgKiBtX0k7CisgICAgICAgIGlmIChwb3RlbnRpYWxJR2FpbiA8IG1fbWF4aW11bU91dHB1dCkgeworICAgICAgICAgIGlmIChwb3RlbnRpYWxJR2FpbiA+IG1fbWluaW11bU91dHB1dCkKKyAgICAgICAgICAgIG1fdG90YWxFcnJvciArPSBtX2Vycm9yOworICAgICAgICAgIGVsc2UKKyAgICAgICAgICAgIG1fdG90YWxFcnJvciA9IG1fbWluaW11bU91dHB1dCAvIG1fSTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICBtX3RvdGFsRXJyb3IgPSBtX21heGltdW1PdXRwdXQgLyBtX0k7CisgICAgICAgIH0KKyAgICAgIH0KKworICAgICAgbV9yZXN1bHQgPSBtX1AgKiBtX2Vycm9yICsgbV9JICogbV90b3RhbEVycm9yICsKKyAgICAgICAgICAgICAgICAgbV9EICogKG1fcHJldklucHV0IC0gaW5wdXQpICsgbV9zZXRwb2ludCAqIG1fRjsKKyAgICB9CisgICAgbV9wcmV2SW5wdXQgPSBpbnB1dDsKKworICAgIGlmIChtX3Jlc3VsdCA+IG1fbWF4aW11bU91dHB1dCkKKyAgICAgIG1fcmVzdWx0ID0gbV9tYXhpbXVtT3V0cHV0OworICAgIGVsc2UgaWYgKG1fcmVzdWx0IDwgbV9taW5pbXVtT3V0cHV0KQorICAgICAgbV9yZXN1bHQgPSBtX21pbmltdW1PdXRwdXQ7CisKKyAgICBwaWRPdXRwdXQgPSBtX3BpZE91dHB1dDsKKyAgICByZXN1bHQgPSBtX3Jlc3VsdDsKKworICAgIHBpZE91dHB1dC0+UElEV3JpdGUocmVzdWx0KTsKKworICAgIC8vIFVwZGF0ZSB0aGUgYnVmZmVyLgorICAgIG1fYnVmLnB1c2gobV9lcnJvcik7CisgICAgbV9idWZUb3RhbCArPSBtX2Vycm9yOworICAgIC8vIFJlbW92ZSBvbGQgZWxlbWVudHMgd2hlbiBidWZmZXIgaXMgZnVsbC4KKyAgICBpZiAobV9idWYuc2l6ZSgpID4gbV9idWZMZW5ndGgpIHsKKyAgICAgIG1fYnVmVG90YWwgLT0gbV9idWYuZnJvbnQoKTsKKyAgICAgIG1fYnVmLnBvcCgpOworICAgIH0KKyAgfQorfQorCisvKioKKyAqIFNldCB0aGUgUElEIENvbnRyb2xsZXIgZ2FpbiBwYXJhbWV0ZXJzLgorICogU2V0IHRoZSBwcm9wb3J0aW9uYWwsIGludGVncmFsLCBhbmQgZGlmZmVyZW50aWFsIGNvZWZmaWNpZW50cy4KKyAqIEBwYXJhbSBwIFByb3BvcnRpb25hbCBjb2VmZmljaWVudAorICogQHBhcmFtIGkgSW50ZWdyYWwgY29lZmZpY2llbnQKKyAqIEBwYXJhbSBkIERpZmZlcmVudGlhbCBjb2VmZmljaWVudAorICovCit2b2lkIFBJRENvbnRyb2xsZXI6OlNldFBJRChkb3VibGUgcCwgZG91YmxlIGksIGRvdWJsZSBkKSB7CisgIHsKKyAgICBzdGQ6OmxvY2tfZ3VhcmQ8cHJpb3JpdHlfbXV0ZXg+IHN5bmMobV9tdXRleCk7CisgICAgbV9QID0gcDsKKyAgICBtX0kgPSBpOworICAgIG1fRCA9IGQ7CisgIH0KKworICBpZiAobV90YWJsZSAhPSBudWxscHRyKSB7CisgICAgbV90YWJsZS0+UHV0TnVtYmVyKCJwIiwgbV9QKTsKKyAgICBtX3RhYmxlLT5QdXROdW1iZXIoImkiLCBtX0kpOworICAgIG1fdGFibGUtPlB1dE51bWJlcigiZCIsIG1fRCk7CisgIH0KK30KKworLyoqCisgKiBTZXQgdGhlIFBJRCBDb250cm9sbGVyIGdhaW4gcGFyYW1ldGVycy4KKyAqIFNldCB0aGUgcHJvcG9ydGlvbmFsLCBpbnRlZ3JhbCwgYW5kIGRpZmZlcmVudGlhbCBjb2VmZmljaWVudHMuCisgKiBAcGFyYW0gcCBQcm9wb3J0aW9uYWwgY29lZmZpY2llbnQKKyAqIEBwYXJhbSBpIEludGVncmFsIGNvZWZmaWNpZW50CisgKiBAcGFyYW0gZCBEaWZmZXJlbnRpYWwgY29lZmZpY2llbnQKKyAqIEBwYXJhbSBmIEZlZWQgZm9yd2FyZCBjb2VmZmljaWVudAorICovCit2b2lkIFBJRENvbnRyb2xsZXI6OlNldFBJRChkb3VibGUgcCwgZG91YmxlIGksIGRvdWJsZSBkLCBkb3VibGUgZikgeworICB7CisgICAgc3RkOjpsb2NrX2d1YXJkPHByaW9yaXR5X211dGV4PiBzeW5jKG1fbXV0ZXgpOworICAgIG1fUCA9IHA7CisgICAgbV9JID0gaTsKKyAgICBtX0QgPSBkOworICAgIG1fRiA9IGY7CisgIH0KKworICBpZiAobV90YWJsZSAhPSBudWxscHRyKSB7CisgICAgbV90YWJsZS0+UHV0TnVtYmVyKCJwIiwgbV9QKTsKKyAgICBtX3RhYmxlLT5QdXROdW1iZXIoImkiLCBtX0kpOworICAgIG1fdGFibGUtPlB1dE51bWJlcigiZCIsIG1fRCk7CisgICAgbV90YWJsZS0+UHV0TnVtYmVyKCJmIiwgbV9GKTsKKyAgfQorfQorCisvKioKKyAqIEdldCB0aGUgUHJvcG9ydGlvbmFsIGNvZWZmaWNpZW50CisgKiBAcmV0dXJuIHByb3BvcnRpb25hbCBjb2VmZmljaWVudAorICovCitkb3VibGUgUElEQ29udHJvbGxlcjo6R2V0UCgpIGNvbnN0IHsKKyAgc3RkOjpsb2NrX2d1YXJkPHByaW9yaXR5X211dGV4PiBzeW5jKG1fbXV0ZXgpOworICByZXR1cm4gbV9QOworfQorCisvKioKKyAqIEdldCB0aGUgSW50ZWdyYWwgY29lZmZpY2llbnQKKyAqIEByZXR1cm4gaW50ZWdyYWwgY29lZmZpY2llbnQKKyAqLworZG91YmxlIFBJRENvbnRyb2xsZXI6OkdldEkoKSBjb25zdCB7CisgIHN0ZDo6bG9ja19ndWFyZDxwcmlvcml0eV9tdXRleD4gc3luYyhtX211dGV4KTsKKyAgcmV0dXJuIG1fSTsKK30KKworLyoqCisgKiBHZXQgdGhlIERpZmZlcmVudGlhbCBjb2VmZmljaWVudAorICogQHJldHVybiBkaWZmZXJlbnRpYWwgY29lZmZpY2llbnQKKyAqLworZG91YmxlIFBJRENvbnRyb2xsZXI6OkdldEQoKSBjb25zdCB7CisgIHN0ZDo6bG9ja19ndWFyZDxwcmlvcml0eV9tdXRleD4gc3luYyhtX211dGV4KTsKKyAgcmV0dXJuIG1fRDsKK30KKworLyoqCisgKiBHZXQgdGhlIEZlZWQgZm9yd2FyZCBjb2VmZmljaWVudAorICogQHJldHVybiBGZWVkIGZvcndhcmQgY29lZmZpY2llbnQKKyAqLworZG91YmxlIFBJRENvbnRyb2xsZXI6OkdldEYoKSBjb25zdCB7CisgIHN0ZDo6bG9ja19ndWFyZDxwcmlvcml0eV9tdXRleD4gc3luYyhtX211dGV4KTsKKyAgcmV0dXJuIG1fRjsKK30KKworLyoqCisgKiBSZXR1cm4gdGhlIGN1cnJlbnQgUElEIHJlc3VsdAorICogVGhpcyBpcyBhbHdheXMgY2VudGVyZWQgb24gemVybyBhbmQgY29uc3RyYWluZWQgdGhlIHRoZSBtYXggYW5kIG1pbiBvdXRzCisgKiBAcmV0dXJuIHRoZSBsYXRlc3QgY2FsY3VsYXRlZCBvdXRwdXQKKyAqLworZmxvYXQgUElEQ29udHJvbGxlcjo6R2V0KCkgY29uc3QgeworICBzdGQ6OmxvY2tfZ3VhcmQ8cHJpb3JpdHlfbXV0ZXg+IHN5bmMobV9tdXRleCk7CisgIHJldHVybiBtX3Jlc3VsdDsKK30KKworLyoqCisgKiAgU2V0IHRoZSBQSUQgY29udHJvbGxlciB0byBjb25zaWRlciB0aGUgaW5wdXQgdG8gYmUgY29udGludW91cywKKyAqICBSYXRoZXIgdGhlbiB1c2luZyB0aGUgbWF4IGFuZCBtaW4gaW4gYXMgY29uc3RyYWludHMsIGl0IGNvbnNpZGVycyB0aGVtIHRvCisgKiAgYmUgdGhlIHNhbWUgcG9pbnQgYW5kIGF1dG9tYXRpY2FsbHkgY2FsY3VsYXRlcyB0aGUgc2hvcnRlc3Qgcm91dGUgdG8KKyAqICB0aGUgc2V0cG9pbnQuCisgKiBAcGFyYW0gY29udGludW91cyBTZXQgdG8gdHJ1ZSB0dXJucyBvbiBjb250aW51b3VzLCBmYWxzZSB0dXJucyBvZmYgY29udGludW91cworICovCit2b2lkIFBJRENvbnRyb2xsZXI6OlNldENvbnRpbnVvdXMoYm9vbCBjb250aW51b3VzKSB7CisgIHN0ZDo6bG9ja19ndWFyZDxwcmlvcml0eV9tdXRleD4gc3luYyhtX211dGV4KTsKKyAgbV9jb250aW51b3VzID0gY29udGludW91czsKK30KKworLyoqCisgKiBTZXRzIHRoZSBtYXhpbXVtIGFuZCBtaW5pbXVtIHZhbHVlcyBleHBlY3RlZCBmcm9tIHRoZSBpbnB1dC4KKyAqCisgKiBAcGFyYW0gbWluaW11bUlucHV0IHRoZSBtaW5pbXVtIHZhbHVlIGV4cGVjdGVkIGZyb20gdGhlIGlucHV0CisgKiBAcGFyYW0gbWF4aW11bUlucHV0IHRoZSBtYXhpbXVtIHZhbHVlIGV4cGVjdGVkIGZyb20gdGhlIG91dHB1dAorICovCit2b2lkIFBJRENvbnRyb2xsZXI6OlNldElucHV0UmFuZ2UoZmxvYXQgbWluaW11bUlucHV0LCBmbG9hdCBtYXhpbXVtSW5wdXQpIHsKKyAgeworICAgIHN0ZDo6bG9ja19ndWFyZDxwcmlvcml0eV9tdXRleD4gc3luYyhtX211dGV4KTsKKyAgICBtX21pbmltdW1JbnB1dCA9IG1pbmltdW1JbnB1dDsKKyAgICBtX21heGltdW1JbnB1dCA9IG1heGltdW1JbnB1dDsKKyAgfQorCisgIFNldFNldHBvaW50KG1fc2V0cG9pbnQpOworfQorCisvKioKKyAqIFNldHMgdGhlIG1pbmltdW0gYW5kIG1heGltdW0gdmFsdWVzIHRvIHdyaXRlLgorICoKKyAqIEBwYXJhbSBtaW5pbXVtT3V0cHV0IHRoZSBtaW5pbXVtIHZhbHVlIHRvIHdyaXRlIHRvIHRoZSBvdXRwdXQKKyAqIEBwYXJhbSBtYXhpbXVtT3V0cHV0IHRoZSBtYXhpbXVtIHZhbHVlIHRvIHdyaXRlIHRvIHRoZSBvdXRwdXQKKyAqLwordm9pZCBQSURDb250cm9sbGVyOjpTZXRPdXRwdXRSYW5nZShmbG9hdCBtaW5pbXVtT3V0cHV0LCBmbG9hdCBtYXhpbXVtT3V0cHV0KSB7CisgIHsKKyAgICBzdGQ6OmxvY2tfZ3VhcmQ8cHJpb3JpdHlfbXV0ZXg+IHN5bmMobV9tdXRleCk7CisgICAgbV9taW5pbXVtT3V0cHV0ID0gbWluaW11bU91dHB1dDsKKyAgICBtX21heGltdW1PdXRwdXQgPSBtYXhpbXVtT3V0cHV0OworICB9Cit9CisKKy8qKgorICogU2V0IHRoZSBzZXRwb2ludCBmb3IgdGhlIFBJRENvbnRyb2xsZXIKKyAqIENsZWFycyB0aGUgcXVldWUgZm9yIEdldEF2Z0Vycm9yKCkuCisgKiBAcGFyYW0gc2V0cG9pbnQgdGhlIGRlc2lyZWQgc2V0cG9pbnQKKyAqLwordm9pZCBQSURDb250cm9sbGVyOjpTZXRTZXRwb2ludChmbG9hdCBzZXRwb2ludCkgeworICB7CisgICAgc3RkOjpsb2NrX2d1YXJkPHByaW9yaXR5X211dGV4PiBzeW5jKG1fbXV0ZXgpOworICAgIGlmIChtX21heGltdW1JbnB1dCA+IG1fbWluaW11bUlucHV0KSB7CisgICAgICBpZiAoc2V0cG9pbnQgPiBtX21heGltdW1JbnB1dCkKKyAgICAgICAgbV9zZXRwb2ludCA9IG1fbWF4aW11bUlucHV0OworICAgICAgZWxzZSBpZiAoc2V0cG9pbnQgPCBtX21pbmltdW1JbnB1dCkKKyAgICAgICAgbV9zZXRwb2ludCA9IG1fbWluaW11bUlucHV0OworICAgICAgZWxzZQorICAgICAgICBtX3NldHBvaW50ID0gc2V0cG9pbnQ7CisgICAgfSBlbHNlIHsKKyAgICAgIG1fc2V0cG9pbnQgPSBzZXRwb2ludDsKKyAgICB9CisKKyAgICAvLyBDbGVhciBtX2J1Zi4KKyAgICBtX2J1ZiA9IHN0ZDo6cXVldWU8ZG91YmxlPigpOworICB9CisKKyAgaWYgKG1fdGFibGUgIT0gbnVsbHB0cikgeworICAgIG1fdGFibGUtPlB1dE51bWJlcigic2V0cG9pbnQiLCBtX3NldHBvaW50KTsKKyAgfQorfQorCisvKioKKyAqIFJldHVybnMgdGhlIGN1cnJlbnQgc2V0cG9pbnQgb2YgdGhlIFBJRENvbnRyb2xsZXIKKyAqIEByZXR1cm4gdGhlIGN1cnJlbnQgc2V0cG9pbnQKKyAqLworZG91YmxlIFBJRENvbnRyb2xsZXI6OkdldFNldHBvaW50KCkgY29uc3QgeworICBzdGQ6OmxvY2tfZ3VhcmQ8cHJpb3JpdHlfbXV0ZXg+IHN5bmMobV9tdXRleCk7CisgIHJldHVybiBtX3NldHBvaW50OworfQorCisvKioKKyAqIFJldHVybnMgdGhlIGN1cnJlbnQgZGlmZmVyZW5jZSBvZiB0aGUgaW5wdXQgZnJvbSB0aGUgc2V0cG9pbnQKKyAqIEByZXR1cm4gdGhlIGN1cnJlbnQgZXJyb3IKKyAqLworZmxvYXQgUElEQ29udHJvbGxlcjo6R2V0RXJyb3IoKSBjb25zdCB7CisgIGRvdWJsZSBwaWRJbnB1dDsKKyAgeworICAgIHN0ZDo6bG9ja19ndWFyZDxwcmlvcml0eV9tdXRleD4gc3luYyhtX211dGV4KTsKKyAgICBwaWRJbnB1dCA9IG1fcGlkSW5wdXQtPlBJREdldCgpOworICB9CisgIHJldHVybiBHZXRTZXRwb2ludCgpIC0gcGlkSW5wdXQ7Cit9CisKKy8qKgorICogU2V0cyB3aGF0IHR5cGUgb2YgaW5wdXQgdGhlIFBJRCBjb250cm9sbGVyIHdpbGwgdXNlCisgKi8KK3ZvaWQgUElEQ29udHJvbGxlcjo6U2V0UElEU291cmNlVHlwZShQSURTb3VyY2VUeXBlIHBpZFNvdXJjZSkgeworICBtX3BpZElucHV0LT5TZXRQSURTb3VyY2VUeXBlKHBpZFNvdXJjZSk7Cit9CisvKioKKyAqIFJldHVybnMgdGhlIHR5cGUgb2YgaW5wdXQgdGhlIFBJRCBjb250cm9sbGVyIGlzIHVzaW5nCisgKiBAcmV0dXJuIHRoZSBQSUQgY29udHJvbGxlciBpbnB1dCB0eXBlCisgKi8KK1BJRFNvdXJjZVR5cGUgUElEQ29udHJvbGxlcjo6R2V0UElEU291cmNlVHlwZSgpIGNvbnN0IHsKKyAgcmV0dXJuIG1fcGlkSW5wdXQtPkdldFBJRFNvdXJjZVR5cGUoKTsKK30KKworLyoqCisgKiBSZXR1cm5zIHRoZSBjdXJyZW50IGF2ZXJhZ2Ugb2YgdGhlIGVycm9yIG92ZXIgdGhlIHBhc3QgZmV3IGl0ZXJhdGlvbnMuCisgKiBZb3UgY2FuIHNwZWNpZnkgdGhlIG51bWJlciBvZiBpdGVyYXRpb25zIHRvIGF2ZXJhZ2Ugd2l0aCBTZXRUb2xlcmFuY2VCdWZmZXIoKQorICogKGRlZmF1bHRzIHRvIDEpLiBUaGlzIGlzIHRoZSBzYW1lIHZhbHVlIHRoYXQgaXMgdXNlZCBmb3IgT25UYXJnZXQoKS4KKyAqIEByZXR1cm4gdGhlIGF2ZXJhZ2UgZXJyb3IKKyAqLworZmxvYXQgUElEQ29udHJvbGxlcjo6R2V0QXZnRXJyb3IoKSBjb25zdCB7CisgIGZsb2F0IGF2Z0Vycm9yID0gMDsKKyAgeworICAgIHN0ZDo6bG9ja19ndWFyZDxwcmlvcml0eV9tdXRleD4gc3luYyhtX211dGV4KTsKKyAgICAvLyBEb24ndCBkaXZpZGUgYnkgemVyby4KKyAgICBpZiAobV9idWYuc2l6ZSgpKSBhdmdFcnJvciA9IG1fYnVmVG90YWwgLyBtX2J1Zi5zaXplKCk7CisgIH0KKyAgcmV0dXJuIGF2Z0Vycm9yOworfQorCisvKgorICogU2V0IHRoZSBwZXJjZW50YWdlIGVycm9yIHdoaWNoIGlzIGNvbnNpZGVyZWQgdG9sZXJhYmxlIGZvciB1c2Ugd2l0aAorICogT25UYXJnZXQuCisgKiBAcGFyYW0gcGVyY2VudGFnZSBlcnJvciB3aGljaCBpcyB0b2xlcmFibGUKKyAqLwordm9pZCBQSURDb250cm9sbGVyOjpTZXRUb2xlcmFuY2UoZmxvYXQgcGVyY2VudCkgeworICB7CisgICAgc3RkOjpsb2NrX2d1YXJkPHByaW9yaXR5X211dGV4PiBzeW5jKG1fbXV0ZXgpOworICAgIG1fdG9sZXJhbmNlVHlwZSA9IGtQZXJjZW50VG9sZXJhbmNlOworICAgIG1fdG9sZXJhbmNlID0gcGVyY2VudDsKKyAgfQorfQorCisvKgorICogU2V0IHRoZSBwZXJjZW50YWdlIGVycm9yIHdoaWNoIGlzIGNvbnNpZGVyZWQgdG9sZXJhYmxlIGZvciB1c2Ugd2l0aAorICogT25UYXJnZXQuCisgKiBAcGFyYW0gcGVyY2VudGFnZSBlcnJvciB3aGljaCBpcyB0b2xlcmFibGUKKyAqLwordm9pZCBQSURDb250cm9sbGVyOjpTZXRQZXJjZW50VG9sZXJhbmNlKGZsb2F0IHBlcmNlbnQpIHsKKyAgeworICAgIHN0ZDo6bG9ja19ndWFyZDxwcmlvcml0eV9tdXRleD4gc3luYyhtX211dGV4KTsKKyAgICBtX3RvbGVyYW5jZVR5cGUgPSBrUGVyY2VudFRvbGVyYW5jZTsKKyAgICBtX3RvbGVyYW5jZSA9IHBlcmNlbnQ7CisgIH0KK30KKworLyoKKyAqIFNldCB0aGUgYWJzb2x1dGUgZXJyb3Igd2hpY2ggaXMgY29uc2lkZXJlZCB0b2xlcmFibGUgZm9yIHVzZSB3aXRoCisgKiBPblRhcmdldC4KKyAqIEBwYXJhbSBwZXJjZW50YWdlIGVycm9yIHdoaWNoIGlzIHRvbGVyYWJsZQorICovCit2b2lkIFBJRENvbnRyb2xsZXI6OlNldEFic29sdXRlVG9sZXJhbmNlKGZsb2F0IGFic1RvbGVyYW5jZSkgeworICB7CisgICAgc3RkOjpsb2NrX2d1YXJkPHByaW9yaXR5X211dGV4PiBzeW5jKG1fbXV0ZXgpOworICAgIG1fdG9sZXJhbmNlVHlwZSA9IGtBYnNvbHV0ZVRvbGVyYW5jZTsKKyAgICBtX3RvbGVyYW5jZSA9IGFic1RvbGVyYW5jZTsKKyAgfQorfQorCisvKgorICogU2V0IHRoZSBudW1iZXIgb2YgcHJldmlvdXMgZXJyb3Igc2FtcGxlcyB0byBhdmVyYWdlIGZvciB0b2xlcmFuY2luZy4gV2hlbgorICogZGV0ZXJtaW5pbmcgd2hldGhlciBhIG1lY2hhbmlzbSBpcyBvbiB0YXJnZXQsIHRoZSB1c2VyIG1heSB3YW50IHRvIHVzZSBhCisgKiByb2xsaW5nIGF2ZXJhZ2Ugb2YgcHJldmlvdXMgbWVhc3VyZW1lbnRzIGluc3RlYWQgb2YgYSBwcmVjaXNlIHBvc2l0aW9uIG9yCisgKiB2ZWxvY2l0eS4gVGhpcyBpcyB1c2VmdWwgZm9yIG5vaXN5IHNlbnNvcnMgd2hpY2ggcmV0dXJuIGEgZmV3IGVycm9uZW91cworICogbWVhc3VyZW1lbnRzIHdoZW4gdGhlIG1lY2hhbmlzbSBpcyBvbiB0YXJnZXQuIEhvd2V2ZXIsIHRoZSBtZWNoYW5pc20gd2lsbAorICogbm90IHJlZ2lzdGVyIGFzIG9uIHRhcmdldCBmb3IgYXQgbGVhc3QgdGhlIHNwZWNpZmllZCBidWZMZW5ndGggY3ljbGVzLgorICogQHBhcmFtIGJ1Zkxlbmd0aCBOdW1iZXIgb2YgcHJldmlvdXMgY3ljbGVzIHRvIGF2ZXJhZ2UuIERlZmF1bHRzIHRvIDEuCisgKi8KK3ZvaWQgUElEQ29udHJvbGxlcjo6U2V0VG9sZXJhbmNlQnVmZmVyKHVuc2lnbmVkIGJ1Zkxlbmd0aCkgeworICBtX2J1Zkxlbmd0aCA9IGJ1Zkxlbmd0aDsKKworICAvLyBDdXQgdGhlIGJ1ZmZlciBkb3duIHRvIHNpemUgaWYgbmVlZGVkLgorICB3aGlsZSAobV9idWYuc2l6ZSgpID4gYnVmTGVuZ3RoKSB7CisgICAgbV9idWZUb3RhbCAtPSBtX2J1Zi5mcm9udCgpOworICAgIG1fYnVmLnBvcCgpOworICB9Cit9CisKKy8qCisgKiBSZXR1cm4gdHJ1ZSBpZiB0aGUgZXJyb3IgaXMgd2l0aGluIHRoZSBwZXJjZW50YWdlIG9mIHRoZSB0b3RhbCBpbnB1dCByYW5nZSwKKyAqIGRldGVybWluZWQgYnkgU2V0VG9sZXJhbmNlLiBUaGlzIGFzc3N1bWVzIHRoYXQgdGhlIG1heGltdW0gYW5kIG1pbmltdW0gaW5wdXQKKyAqIHdlcmUgc2V0IHVzaW5nIFNldElucHV0LgorICogQ3VycmVudGx5IHRoaXMganVzdCByZXBvcnRzIG9uIHRhcmdldCBhcyB0aGUgYWN0dWFsIHZhbHVlIHBhc3NlcyB0aHJvdWdoIHRoZQorICogc2V0cG9pbnQuCisgKiBJZGVhbGx5IGl0IHNob3VsZCBiZSBiYXNlZCBvbiBiZWluZyB3aXRoaW4gdGhlIHRvbGVyYW5jZSBmb3Igc29tZSBwZXJpb2Qgb2YKKyAqIHRpbWUuCisgKi8KK2Jvb2wgUElEQ29udHJvbGxlcjo6T25UYXJnZXQoKSBjb25zdCB7CisgIGRvdWJsZSBlcnJvciA9IEdldEF2Z0Vycm9yKCk7CisKKyAgc3RkOjpsb2NrX2d1YXJkPHByaW9yaXR5X211dGV4PiBzeW5jKG1fbXV0ZXgpOworICBzd2l0Y2ggKG1fdG9sZXJhbmNlVHlwZSkgeworICAgIGNhc2Uga1BlcmNlbnRUb2xlcmFuY2U6CisgICAgICByZXR1cm4gZmFicyhlcnJvcikgPCBtX3RvbGVyYW5jZSAvIDEwMCAqIChtX21heGltdW1JbnB1dCAtIG1fbWluaW11bUlucHV0KTsKKyAgICAgIGJyZWFrOworICAgIGNhc2Uga0Fic29sdXRlVG9sZXJhbmNlOgorICAgICAgcmV0dXJuIGZhYnMoZXJyb3IpIDwgbV90b2xlcmFuY2U7CisgICAgICBicmVhazsKKyAgICBjYXNlIGtOb1RvbGVyYW5jZToKKyAgICAgIC8vIFRPRE86IHRoaXMgY2FzZSBuZWVkcyBhbiBlcnJvcgorICAgICAgcmV0dXJuIGZhbHNlOworICB9CisgIHJldHVybiBmYWxzZTsKK30KKworLyoqCisgKiBCZWdpbiBydW5uaW5nIHRoZSBQSURDb250cm9sbGVyCisgKi8KK3ZvaWQgUElEQ29udHJvbGxlcjo6RW5hYmxlKCkgeworICB7CisgICAgc3RkOjpsb2NrX2d1YXJkPHByaW9yaXR5X211dGV4PiBzeW5jKG1fbXV0ZXgpOworICAgIG1fZW5hYmxlZCA9IHRydWU7CisgIH0KKworICBpZiAobV90YWJsZSAhPSBudWxscHRyKSB7CisgICAgbV90YWJsZS0+UHV0Qm9vbGVhbigiZW5hYmxlZCIsIHRydWUpOworICB9Cit9CisKKy8qKgorICogU3RvcCBydW5uaW5nIHRoZSBQSURDb250cm9sbGVyLCB0aGlzIHNldHMgdGhlIG91dHB1dCB0byB6ZXJvIGJlZm9yZSBzdG9wcGluZy4KKyAqLwordm9pZCBQSURDb250cm9sbGVyOjpEaXNhYmxlKCkgeworICB7CisgICAgc3RkOjpsb2NrX2d1YXJkPHByaW9yaXR5X211dGV4PiBzeW5jKG1fbXV0ZXgpOworICAgIG1fcGlkT3V0cHV0LT5QSURXcml0ZSgwKTsKKyAgICBtX2VuYWJsZWQgPSBmYWxzZTsKKyAgfQorCisgIGlmIChtX3RhYmxlICE9IG51bGxwdHIpIHsKKyAgICBtX3RhYmxlLT5QdXRCb29sZWFuKCJlbmFibGVkIiwgZmFsc2UpOworICB9Cit9CisKKy8qKgorICogUmV0dXJuIHRydWUgaWYgUElEQ29udHJvbGxlciBpcyBlbmFibGVkLgorICovCitib29sIFBJRENvbnRyb2xsZXI6OklzRW5hYmxlZCgpIGNvbnN0IHsKKyAgc3RkOjpsb2NrX2d1YXJkPHByaW9yaXR5X211dGV4PiBzeW5jKG1fbXV0ZXgpOworICByZXR1cm4gbV9lbmFibGVkOworfQorCisvKioKKyAqIFJlc2V0IHRoZSBwcmV2aW91cyBlcnJvciwsIHRoZSBpbnRlZ3JhbCB0ZXJtLCBhbmQgZGlzYWJsZSB0aGUgY29udHJvbGxlci4KKyAqLwordm9pZCBQSURDb250cm9sbGVyOjpSZXNldCgpIHsKKyAgRGlzYWJsZSgpOworCisgIHN0ZDo6bG9ja19ndWFyZDxwcmlvcml0eV9tdXRleD4gc3luYyhtX211dGV4KTsKKyAgbV9wcmV2SW5wdXQgPSAwOworICBtX3RvdGFsRXJyb3IgPSAwOworICBtX3Jlc3VsdCA9IDA7Cit9CisKK3N0ZDo6c3RyaW5nIFBJRENvbnRyb2xsZXI6OkdldFNtYXJ0RGFzaGJvYXJkVHlwZSgpIGNvbnN0IHsKKyAgcmV0dXJuICJQSURDb250cm9sbGVyIjsKK30KKwordm9pZCBQSURDb250cm9sbGVyOjpJbml0VGFibGUoc3RkOjpzaGFyZWRfcHRyPElUYWJsZT4gdGFibGUpIHsKKyAgaWYgKG1fdGFibGUgIT0gbnVsbHB0cikgbV90YWJsZS0+UmVtb3ZlVGFibGVMaXN0ZW5lcih0aGlzKTsKKyAgbV90YWJsZSA9IHRhYmxlOworICBpZiAobV90YWJsZSAhPSBudWxscHRyKSB7CisgICAgbV90YWJsZS0+UHV0TnVtYmVyKGtQLCBHZXRQKCkpOworICAgIG1fdGFibGUtPlB1dE51bWJlcihrSSwgR2V0SSgpKTsKKyAgICBtX3RhYmxlLT5QdXROdW1iZXIoa0QsIEdldEQoKSk7CisgICAgbV90YWJsZS0+UHV0TnVtYmVyKGtGLCBHZXRGKCkpOworICAgIG1fdGFibGUtPlB1dE51bWJlcihrU2V0cG9pbnQsIEdldFNldHBvaW50KCkpOworICAgIG1fdGFibGUtPlB1dEJvb2xlYW4oa0VuYWJsZWQsIElzRW5hYmxlZCgpKTsKKyAgICBtX3RhYmxlLT5BZGRUYWJsZUxpc3RlbmVyKHRoaXMsIGZhbHNlKTsKKyAgfQorfQorCitzdGQ6OnNoYXJlZF9wdHI8SVRhYmxlPiBQSURDb250cm9sbGVyOjpHZXRUYWJsZSgpIGNvbnN0IHsgcmV0dXJuIG1fdGFibGU7IH0KKwordm9pZCBQSURDb250cm9sbGVyOjpWYWx1ZUNoYW5nZWQoSVRhYmxlKiBzb3VyY2UsIGxsdm06OlN0cmluZ1JlZiBrZXksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdGQ6OnNoYXJlZF9wdHI8bnQ6OlZhbHVlPiB2YWx1ZSwgYm9vbCBpc05ldykgeworICBpZiAoa2V5ID09IGtQIHx8IGtleSA9PSBrSSB8fCBrZXkgPT0ga0QgfHwga2V5ID09IGtGKSB7CisgICAgaWYgKG1fUCAhPSBtX3RhYmxlLT5HZXROdW1iZXIoa1AsIDAuMCkgfHwKKyAgICAgICAgbV9JICE9IG1fdGFibGUtPkdldE51bWJlcihrSSwgMC4wKSB8fAorICAgICAgICBtX0QgIT0gbV90YWJsZS0+R2V0TnVtYmVyKGtELCAwLjApIHx8CisgICAgICAgIG1fRiAhPSBtX3RhYmxlLT5HZXROdW1iZXIoa0YsIDAuMCkpIHsKKyAgICAgIFNldFBJRChtX3RhYmxlLT5HZXROdW1iZXIoa1AsIDAuMCksIG1fdGFibGUtPkdldE51bWJlcihrSSwgMC4wKSwKKyAgICAgICAgICAgICBtX3RhYmxlLT5HZXROdW1iZXIoa0QsIDAuMCksIG1fdGFibGUtPkdldE51bWJlcihrRiwgMC4wKSk7CisgICAgfQorICB9IGVsc2UgaWYgKGtleSA9PSBrU2V0cG9pbnQgJiYgdmFsdWUtPklzRG91YmxlKCkgJiYKKyAgICAgICAgICAgICBtX3NldHBvaW50ICE9IHZhbHVlLT5HZXREb3VibGUoKSkgeworICAgIFNldFNldHBvaW50KHZhbHVlLT5HZXREb3VibGUoKSk7CisgIH0gZWxzZSBpZiAoa2V5ID09IGtFbmFibGVkICYmIHZhbHVlLT5Jc0Jvb2xlYW4oKSAmJgorICAgICAgICAgICAgIG1fZW5hYmxlZCAhPSB2YWx1ZS0+R2V0Qm9vbGVhbigpKSB7CisgICAgaWYgKHZhbHVlLT5HZXRCb29sZWFuKCkpIHsKKyAgICAgIEVuYWJsZSgpOworICAgIH0gZWxzZSB7CisgICAgICBEaXNhYmxlKCk7CisgICAgfQorICB9Cit9CisKK3ZvaWQgUElEQ29udHJvbGxlcjo6VXBkYXRlVGFibGUoKSB7fQorCit2b2lkIFBJRENvbnRyb2xsZXI6OlN0YXJ0TGl2ZVdpbmRvd01vZGUoKSB7IERpc2FibGUoKTsgfQorCit2b2lkIFBJRENvbnRyb2xsZXI6OlN0b3BMaXZlV2luZG93TW9kZSgpIHt9CmRpZmYgLS1naXQgYS93cGlsaWJjL0F0aGVuYS9zcmMvUFdNLmNwcCBiL3dwaWxpYmMvQXRoZW5hL3NyYy9QV00uY3BwCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjZiM2I0YjcKLS0tIC9kZXYvbnVsbAorKysgYi93cGlsaWJjL0F0aGVuYS9zcmMvUFdNLmNwcApAQCAtMCwwICsxLDM3NCBAQAorLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi8KKy8qIENvcHlyaWdodCAoYykgRklSU1QgMjAwOC4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KKyAqLworLyogT3BlbiBTb3VyY2UgU29mdHdhcmUgLSBtYXkgYmUgbW9kaWZpZWQgYW5kIHNoYXJlZCBieSBGUkMgdGVhbXMuIFRoZSBjb2RlICAgKi8KKy8qIG11c3QgYmUgYWNjb21wYW5pZWQgYnkgdGhlIEZJUlNUIEJTRCBsaWNlbnNlIGZpbGUgaW4gJChXSU5EX0JBU0UpL1dQSUxpYi4gICovCisvKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qLworCisjaW5jbHVkZSAiUFdNLmgiCisKKyNpbmNsdWRlICJSZXNvdXJjZS5oIgorI2luY2x1ZGUgIlV0aWxpdHkuaCIKKyNpbmNsdWRlICJXUElFcnJvcnMuaCIKKyNpbmNsdWRlICJIQUwvSEFMLmhwcCIKKworI2luY2x1ZGUgPHNzdHJlYW0+CisKK2NvbnN0ZXhwciBmbG9hdCBQV006OmtEZWZhdWx0UHdtUGVyaW9kOworY29uc3RleHByIGZsb2F0IFBXTTo6a0RlZmF1bHRQd21DZW50ZXI7Citjb25zdCBpbnQzMl90IFBXTTo6a0RlZmF1bHRQd21TdGVwc0Rvd247Citjb25zdCBpbnQzMl90IFBXTTo6a1B3bURpc2FibGVkOworCisvKioKKyAqIEFsbG9jYXRlIGEgUFdNIGdpdmVuIGEgY2hhbm5lbCBudW1iZXIuCisgKgorICogQ2hlY2tzIGNoYW5uZWwgdmFsdWUgcmFuZ2UgYW5kIGFsbG9jYXRlcyB0aGUgYXBwcm9wcmlhdGUgY2hhbm5lbC4KKyAqIFRoZSBhbGxvY2F0aW9uIGlzIG9ubHkgZG9uZSB0byBoZWxwIHVzZXJzIGVuc3VyZSB0aGF0IHRoZXkgZG9uJ3QgZG91YmxlCisgKiBhc3NpZ24gY2hhbm5lbHMuCisgKiBAcGFyYW0gY2hhbm5lbCBUaGUgUFdNIGNoYW5uZWwgbnVtYmVyLiAwLTkgYXJlIG9uLWJvYXJkLCAxMC0xOSBhcmUgb24gdGhlIE1YUAorICogcG9ydAorICovCitQV006OlBXTSh1aW50MzJfdCBjaGFubmVsKSB7CisgIHN0ZDo6c3RyaW5nc3RyZWFtIGJ1ZjsKKworICBpZiAoIUNoZWNrUFdNQ2hhbm5lbChjaGFubmVsKSkgeworICAgIGJ1ZiA8PCAiUFdNIENoYW5uZWwgIiA8PCBjaGFubmVsOworICAgIHdwaV9zZXRXUElFcnJvcldpdGhDb250ZXh0KENoYW5uZWxJbmRleE91dE9mUmFuZ2UsIGJ1Zi5zdHIoKSk7CisgICAgcmV0dXJuOworICB9CisKKyAgaW50MzJfdCBzdGF0dXMgPSAwOworICBhbGxvY2F0ZVBXTUNoYW5uZWwobV9wd21fcG9ydHNbY2hhbm5lbF0sICZzdGF0dXMpOworICB3cGlfc2V0RXJyb3JXaXRoQ29udGV4dChzdGF0dXMsIGdldEhBTEVycm9yTWVzc2FnZShzdGF0dXMpKTsKKworICBtX2NoYW5uZWwgPSBjaGFubmVsOworCisgIHNldFBXTShtX3B3bV9wb3J0c1ttX2NoYW5uZWxdLCBrUHdtRGlzYWJsZWQsICZzdGF0dXMpOworICB3cGlfc2V0RXJyb3JXaXRoQ29udGV4dChzdGF0dXMsIGdldEhBTEVycm9yTWVzc2FnZShzdGF0dXMpKTsKKworICBtX2VsaW1pbmF0ZURlYWRiYW5kID0gZmFsc2U7CisKKyAgSEFMUmVwb3J0KEhBTFVzYWdlUmVwb3J0aW5nOjprUmVzb3VyY2VUeXBlX1BXTSwgY2hhbm5lbCk7Cit9CisKKy8qKgorICogRnJlZSB0aGUgUFdNIGNoYW5uZWwuCisgKgorICogRnJlZSB0aGUgcmVzb3VyY2UgYXNzb2NpYXRlZCB3aXRoIHRoZSBQV00gY2hhbm5lbCBhbmQgc2V0IHRoZSB2YWx1ZSB0byAwLgorICovCitQV006On5QV00oKSB7CisgIGludDMyX3Qgc3RhdHVzID0gMDsKKworICBzZXRQV00obV9wd21fcG9ydHNbbV9jaGFubmVsXSwga1B3bURpc2FibGVkLCAmc3RhdHVzKTsKKyAgd3BpX3NldEVycm9yV2l0aENvbnRleHQoc3RhdHVzLCBnZXRIQUxFcnJvck1lc3NhZ2Uoc3RhdHVzKSk7CisKKyAgZnJlZVBXTUNoYW5uZWwobV9wd21fcG9ydHNbbV9jaGFubmVsXSwgJnN0YXR1cyk7CisgIHdwaV9zZXRFcnJvcldpdGhDb250ZXh0KHN0YXR1cywgZ2V0SEFMRXJyb3JNZXNzYWdlKHN0YXR1cykpOworCisgIGlmIChtX3RhYmxlICE9IG51bGxwdHIpIG1fdGFibGUtPlJlbW92ZVRhYmxlTGlzdGVuZXIodGhpcyk7Cit9CisKKy8qKgorICogT3B0aW9uYWxseSBlbGltaW5hdGUgdGhlIGRlYWRiYW5kIGZyb20gYSBzcGVlZCBjb250cm9sbGVyLgorICogQHBhcmFtIGVsaW1pbmF0ZURlYWRiYW5kIElmIHRydWUsIHNldCB0aGUgbW90b3IgY3VydmUgb24gdGhlIEphZ3VhciB0bworICogZWxpbWluYXRlCisgKiB0aGUgZGVhZGJhbmQgaW4gdGhlIG1pZGRsZSBvZiB0aGUgcmFuZ2UuIE90aGVyd2lzZSwga2VlcCB0aGUgZnVsbCByYW5nZQorICogd2l0aG91dAorICogbW9kaWZ5aW5nIGFueSB2YWx1ZXMuCisgKi8KK3ZvaWQgUFdNOjpFbmFibGVEZWFkYmFuZEVsaW1pbmF0aW9uKGJvb2wgZWxpbWluYXRlRGVhZGJhbmQpIHsKKyAgaWYgKFN0YXR1c0lzRmF0YWwoKSkgcmV0dXJuOworICBtX2VsaW1pbmF0ZURlYWRiYW5kID0gZWxpbWluYXRlRGVhZGJhbmQ7Cit9CisKKy8qKgorICogU2V0IHRoZSBib3VuZHMgb24gdGhlIFBXTSB2YWx1ZXMuCisgKiBUaGlzIHNldHMgdGhlIGJvdW5kcyBvbiB0aGUgUFdNIHZhbHVlcyBmb3IgYSBwYXJ0aWN1bGFyIGVhY2ggdHlwZSBvZgorICogY29udHJvbGxlci4gVGhlIHZhbHVlcworICogZGV0ZXJtaW5lIHRoZSB1cHBlciBhbmQgbG93ZXIgc3BlZWRzIGFzIHdlbGwgYXMgdGhlIGRlYWRiYW5kIGJyYWNrZXQuCisgKiBAcGFyYW0gbWF4IFRoZSBNaW5pbXVtIHB3bSB2YWx1ZQorICogQHBhcmFtIGRlYWRiYW5kTWF4IFRoZSBoaWdoIGVuZCBvZiB0aGUgZGVhZGJhbmQgcmFuZ2UKKyAqIEBwYXJhbSBjZW50ZXIgVGhlIGNlbnRlciBzcGVlZCAob2ZmKQorICogQHBhcmFtIGRlYWRiYW5kTWluIFRoZSBsb3cgZW5kIG9mIHRoZSBkZWFkYmFuZCByYW5nZQorICogQHBhcmFtIG1pbiBUaGUgbWluaW11bSBwd20gdmFsdWUKKyAqLwordm9pZCBQV006OlNldEJvdW5kcyhpbnQzMl90IG1heCwgaW50MzJfdCBkZWFkYmFuZE1heCwgaW50MzJfdCBjZW50ZXIsCisgICAgICAgICAgICAgICAgICAgIGludDMyX3QgZGVhZGJhbmRNaW4sIGludDMyX3QgbWluKSB7CisgIGlmIChTdGF0dXNJc0ZhdGFsKCkpIHJldHVybjsKKyAgbV9tYXhQd20gPSBtYXg7CisgIG1fZGVhZGJhbmRNYXhQd20gPSBkZWFkYmFuZE1heDsKKyAgbV9jZW50ZXJQd20gPSBjZW50ZXI7CisgIG1fZGVhZGJhbmRNaW5Qd20gPSBkZWFkYmFuZE1pbjsKKyAgbV9taW5Qd20gPSBtaW47Cit9CisKKy8qKgorICogU2V0IHRoZSBib3VuZHMgb24gdGhlIFBXTSBwdWxzZSB3aWR0aHMuCisgKiBUaGlzIHNldHMgdGhlIGJvdW5kcyBvbiB0aGUgUFdNIHZhbHVlcyBmb3IgYSBwYXJ0aWN1bGFyIHR5cGUgb2YgY29udHJvbGxlci4KKyAqIFRoZSB2YWx1ZXMKKyAqIGRldGVybWluZSB0aGUgdXBwZXIgYW5kIGxvd2VyIHNwZWVkcyBhcyB3ZWxsIGFzIHRoZSBkZWFkYmFuZCBicmFja2V0LgorICogQHBhcmFtIG1heCBUaGUgbWF4IFBXTSBwdWxzZSB3aWR0aCBpbiBtcworICogQHBhcmFtIGRlYWRiYW5kTWF4IFRoZSBoaWdoIGVuZCBvZiB0aGUgZGVhZGJhbmQgcmFuZ2UgcHVsc2Ugd2lkdGggaW4gbXMKKyAqIEBwYXJhbSBjZW50ZXIgVGhlIGNlbnRlciAob2ZmKSBwdWxzZSB3aWR0aCBpbiBtcworICogQHBhcmFtIGRlYWRiYW5kTWluIFRoZSBsb3cgZW5kIG9mIHRoZSBkZWFkYmFuZCBwdWxzZSB3aWR0aCBpbiBtcworICogQHBhcmFtIG1pbiBUaGUgbWluaW11bSBwdWxzZSB3aWR0aCBpbiBtcworICovCit2b2lkIFBXTTo6U2V0Qm91bmRzKGRvdWJsZSBtYXgsIGRvdWJsZSBkZWFkYmFuZE1heCwgZG91YmxlIGNlbnRlciwKKyAgICAgICAgICAgICAgICAgICAgZG91YmxlIGRlYWRiYW5kTWluLCBkb3VibGUgbWluKSB7CisgIC8vIGNhbGN1bGF0ZSB0aGUgbG9vcCB0aW1lIGluIG1pbGxpc2Vjb25kcworICBpbnQzMl90IHN0YXR1cyA9IDA7CisgIGRvdWJsZSBsb29wVGltZSA9CisgICAgICBnZXRMb29wVGltaW5nKCZzdGF0dXMpIC8gKGtTeXN0ZW1DbG9ja1RpY2tzUGVyTWljcm9zZWNvbmQgKiAxZTMpOworICB3cGlfc2V0RXJyb3JXaXRoQ29udGV4dChzdGF0dXMsIGdldEhBTEVycm9yTWVzc2FnZShzdGF0dXMpKTsKKworICBpZiAoU3RhdHVzSXNGYXRhbCgpKSByZXR1cm47CisKKyAgbV9tYXhQd20gPSAoaW50MzJfdCkoKG1heCAtIGtEZWZhdWx0UHdtQ2VudGVyKSAvIGxvb3BUaW1lICsKKyAgICAgICAgICAgICAgICAgICAgICAga0RlZmF1bHRQd21TdGVwc0Rvd24gLSAxKTsKKyAgbV9kZWFkYmFuZE1heFB3bSA9IChpbnQzMl90KSgoZGVhZGJhbmRNYXggLSBrRGVmYXVsdFB3bUNlbnRlcikgLyBsb29wVGltZSArCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAga0RlZmF1bHRQd21TdGVwc0Rvd24gLSAxKTsKKyAgbV9jZW50ZXJQd20gPSAoaW50MzJfdCkoKGNlbnRlciAtIGtEZWZhdWx0UHdtQ2VudGVyKSAvIGxvb3BUaW1lICsKKyAgICAgICAgICAgICAgICAgICAgICAgICAga0RlZmF1bHRQd21TdGVwc0Rvd24gLSAxKTsKKyAgbV9kZWFkYmFuZE1pblB3bSA9IChpbnQzMl90KSgoZGVhZGJhbmRNaW4gLSBrRGVmYXVsdFB3bUNlbnRlcikgLyBsb29wVGltZSArCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAga0RlZmF1bHRQd21TdGVwc0Rvd24gLSAxKTsKKyAgbV9taW5Qd20gPSAoaW50MzJfdCkoKG1pbiAtIGtEZWZhdWx0UHdtQ2VudGVyKSAvIGxvb3BUaW1lICsKKyAgICAgICAgICAgICAgICAgICAgICAga0RlZmF1bHRQd21TdGVwc0Rvd24gLSAxKTsKK30KKworLyoqCisgKiBTZXQgdGhlIFBXTSB2YWx1ZSBiYXNlZCBvbiBhIHBvc2l0aW9uLgorICoKKyAqIFRoaXMgaXMgaW50ZW5kZWQgdG8gYmUgdXNlZCBieSBzZXJ2b3MuCisgKgorICogQHByZSBTZXRNYXhQb3NpdGl2ZVB3bSgpIGNhbGxlZC4KKyAqIEBwcmUgU2V0TWluTmVnYXRpdmVQd20oKSBjYWxsZWQuCisgKgorICogQHBhcmFtIHBvcyBUaGUgcG9zaXRpb24gdG8gc2V0IHRoZSBzZXJ2byBiZXR3ZWVuIDAuMCBhbmQgMS4wLgorICovCit2b2lkIFBXTTo6U2V0UG9zaXRpb24oZmxvYXQgcG9zKSB7CisgIGlmIChTdGF0dXNJc0ZhdGFsKCkpIHJldHVybjsKKyAgaWYgKHBvcyA8IDAuMCkgeworICAgIHBvcyA9IDAuMDsKKyAgfSBlbHNlIGlmIChwb3MgPiAxLjApIHsKKyAgICBwb3MgPSAxLjA7CisgIH0KKworICAvLyBub3RlLCBuZWVkIHRvIHBlcmZvcm0gdGhlIG11bHRpcGxpY2F0aW9uIGJlbG93IGFzIGZsb2F0aW5nIHBvaW50IGJlZm9yZQorICAvLyBjb252ZXJ0aW5nIHRvIGludAorICB1bnNpZ25lZCBzaG9ydCByYXdWYWx1ZSA9CisgICAgICAoaW50MzJfdCkoKHBvcyAqIChmbG9hdClHZXRGdWxsUmFuZ2VTY2FsZUZhY3RvcigpKSArIEdldE1pbk5lZ2F0aXZlUHdtKCkpOworICAvLwlwcmludGYoIk1pbk5lZ1BXTTogJWQgRnVsbFJhbmdlU2NhbGVGYWN0b3I6ICVkIFJhdyB2YWx1ZTogJTVkICAgSW5wdXQKKyAgLy92YWx1ZTogJTQuNGZcbiIsIEdldE1pbk5lZ2F0aXZlUHdtKCksIEdldEZ1bGxSYW5nZVNjYWxlRmFjdG9yKCksIHJhd1ZhbHVlLAorICAvL3Bvcyk7CisKKyAgLy8Jd3BpX2Fzc2VydCgocmF3VmFsdWUgPj0gR2V0TWluTmVnYXRpdmVQd20oKSkgJiYgKHJhd1ZhbHVlIDw9CisgIC8vR2V0TWF4UG9zaXRpdmVQd20oKSkpOworICB3cGlfYXNzZXJ0KHJhd1ZhbHVlICE9IGtQd21EaXNhYmxlZCk7CisKKyAgLy8gc2VuZCB0aGUgY29tcHV0ZWQgcHdtIHZhbHVlIHRvIHRoZSBGUEdBCisgIFNldFJhdygodW5zaWduZWQgc2hvcnQpcmF3VmFsdWUpOworfQorCisvKioKKyAqIEdldCB0aGUgUFdNIHZhbHVlIGluIHRlcm1zIG9mIGEgcG9zaXRpb24uCisgKgorICogVGhpcyBpcyBpbnRlbmRlZCB0byBiZSB1c2VkIGJ5IHNlcnZvcy4KKyAqCisgKiBAcHJlIFNldE1heFBvc2l0aXZlUHdtKCkgY2FsbGVkLgorICogQHByZSBTZXRNaW5OZWdhdGl2ZVB3bSgpIGNhbGxlZC4KKyAqCisgKiBAcmV0dXJuIFRoZSBwb3NpdGlvbiB0aGUgc2Vydm8gaXMgc2V0IHRvIGJldHdlZW4gMC4wIGFuZCAxLjAuCisgKi8KK2Zsb2F0IFBXTTo6R2V0UG9zaXRpb24oKSBjb25zdCB7CisgIGlmIChTdGF0dXNJc0ZhdGFsKCkpIHJldHVybiAwLjA7CisgIGludDMyX3QgdmFsdWUgPSBHZXRSYXcoKTsKKyAgaWYgKHZhbHVlIDwgR2V0TWluTmVnYXRpdmVQd20oKSkgeworICAgIHJldHVybiAwLjA7CisgIH0gZWxzZSBpZiAodmFsdWUgPiBHZXRNYXhQb3NpdGl2ZVB3bSgpKSB7CisgICAgcmV0dXJuIDEuMDsKKyAgfSBlbHNlIHsKKyAgICByZXR1cm4gKGZsb2F0KSh2YWx1ZSAtIEdldE1pbk5lZ2F0aXZlUHdtKCkpIC8KKyAgICAgICAgICAgKGZsb2F0KUdldEZ1bGxSYW5nZVNjYWxlRmFjdG9yKCk7CisgIH0KK30KKworLyoqCisgKiBTZXQgdGhlIFBXTSB2YWx1ZSBiYXNlZCBvbiBhIHNwZWVkLgorICoKKyAqIFRoaXMgaXMgaW50ZW5kZWQgdG8gYmUgdXNlZCBieSBzcGVlZCBjb250cm9sbGVycy4KKyAqCisgKiBAcHJlIFNldE1heFBvc2l0aXZlUHdtKCkgY2FsbGVkLgorICogQHByZSBTZXRNaW5Qb3NpdGl2ZVB3bSgpIGNhbGxlZC4KKyAqIEBwcmUgU2V0Q2VudGVyUHdtKCkgY2FsbGVkLgorICogQHByZSBTZXRNYXhOZWdhdGl2ZVB3bSgpIGNhbGxlZC4KKyAqIEBwcmUgU2V0TWluTmVnYXRpdmVQd20oKSBjYWxsZWQuCisgKgorICogQHBhcmFtIHNwZWVkIFRoZSBzcGVlZCB0byBzZXQgdGhlIHNwZWVkIGNvbnRyb2xsZXIgYmV0d2VlbiAtMS4wIGFuZCAxLjAuCisgKi8KK3ZvaWQgUFdNOjpTZXRTcGVlZChmbG9hdCBzcGVlZCkgeworICBpZiAoU3RhdHVzSXNGYXRhbCgpKSByZXR1cm47CisgIC8vIGNsYW1wIHNwZWVkIHRvIGJlIGluIHRoZSByYW5nZSAxLjAgPj0gc3BlZWQgPj0gLTEuMAorICBpZiAoc3BlZWQgPCAtMS4wKSB7CisgICAgc3BlZWQgPSAtMS4wOworICB9IGVsc2UgaWYgKHNwZWVkID4gMS4wKSB7CisgICAgc3BlZWQgPSAxLjA7CisgIH0KKworICAvLyBjYWxjdWxhdGUgdGhlIGRlc2lyZWQgb3V0cHV0IHB3bSB2YWx1ZSBieSBzY2FsaW5nIHRoZSBzcGVlZCBhcHByb3ByaWF0ZWx5CisgIGludDMyX3QgcmF3VmFsdWU7CisgIGlmIChzcGVlZCA9PSAwLjApIHsKKyAgICByYXdWYWx1ZSA9IEdldENlbnRlclB3bSgpOworICB9IGVsc2UgaWYgKHNwZWVkID4gMC4wKSB7CisgICAgcmF3VmFsdWUgPSAoaW50MzJfdCkoc3BlZWQgKiAoKGZsb2F0KUdldFBvc2l0aXZlU2NhbGVGYWN0b3IoKSkgKworICAgICAgICAgICAgICAgICAgICAgICAgICgoZmxvYXQpR2V0TWluUG9zaXRpdmVQd20oKSkgKyAwLjUpOworICB9IGVsc2UgeworICAgIHJhd1ZhbHVlID0gKGludDMyX3QpKHNwZWVkICogKChmbG9hdClHZXROZWdhdGl2ZVNjYWxlRmFjdG9yKCkpICsKKyAgICAgICAgICAgICAgICAgICAgICAgICAoKGZsb2F0KUdldE1heE5lZ2F0aXZlUHdtKCkpICsgMC41KTsKKyAgfQorCisgIC8vIHRoZSBhYm92ZSBzaG91bGQgcmVzdWx0IGluIGEgcHdtX3ZhbHVlIGluIHRoZSB2YWxpZCByYW5nZQorICB3cGlfYXNzZXJ0KChyYXdWYWx1ZSA+PSBHZXRNaW5OZWdhdGl2ZVB3bSgpKSAmJgorICAgICAgICAgICAgIChyYXdWYWx1ZSA8PSBHZXRNYXhQb3NpdGl2ZVB3bSgpKSk7CisgIHdwaV9hc3NlcnQocmF3VmFsdWUgIT0ga1B3bURpc2FibGVkKTsKKworICAvLyBzZW5kIHRoZSBjb21wdXRlZCBwd20gdmFsdWUgdG8gdGhlIEZQR0EKKyAgU2V0UmF3KHJhd1ZhbHVlKTsKK30KKworLyoqCisgKiBHZXQgdGhlIFBXTSB2YWx1ZSBpbiB0ZXJtcyBvZiBzcGVlZC4KKyAqCisgKiBUaGlzIGlzIGludGVuZGVkIHRvIGJlIHVzZWQgYnkgc3BlZWQgY29udHJvbGxlcnMuCisgKgorICogQHByZSBTZXRNYXhQb3NpdGl2ZVB3bSgpIGNhbGxlZC4KKyAqIEBwcmUgU2V0TWluUG9zaXRpdmVQd20oKSBjYWxsZWQuCisgKiBAcHJlIFNldE1heE5lZ2F0aXZlUHdtKCkgY2FsbGVkLgorICogQHByZSBTZXRNaW5OZWdhdGl2ZVB3bSgpIGNhbGxlZC4KKyAqCisgKiBAcmV0dXJuIFRoZSBtb3N0IHJlY2VudGx5IHNldCBzcGVlZCBiZXR3ZWVuIC0xLjAgYW5kIDEuMC4KKyAqLworZmxvYXQgUFdNOjpHZXRTcGVlZCgpIGNvbnN0IHsKKyAgaWYgKFN0YXR1c0lzRmF0YWwoKSkgcmV0dXJuIDAuMDsKKyAgaW50MzJfdCB2YWx1ZSA9IEdldFJhdygpOworICBpZiAodmFsdWUgPT0gUFdNOjprUHdtRGlzYWJsZWQpIHsKKyAgICByZXR1cm4gMC4wOworICB9IGVsc2UgaWYgKHZhbHVlID4gR2V0TWF4UG9zaXRpdmVQd20oKSkgeworICAgIHJldHVybiAxLjA7CisgIH0gZWxzZSBpZiAodmFsdWUgPCBHZXRNaW5OZWdhdGl2ZVB3bSgpKSB7CisgICAgcmV0dXJuIC0xLjA7CisgIH0gZWxzZSBpZiAodmFsdWUgPiBHZXRNaW5Qb3NpdGl2ZVB3bSgpKSB7CisgICAgcmV0dXJuIChmbG9hdCkodmFsdWUgLSBHZXRNaW5Qb3NpdGl2ZVB3bSgpKSAvCisgICAgICAgICAgIChmbG9hdClHZXRQb3NpdGl2ZVNjYWxlRmFjdG9yKCk7CisgIH0gZWxzZSBpZiAodmFsdWUgPCBHZXRNYXhOZWdhdGl2ZVB3bSgpKSB7CisgICAgcmV0dXJuIChmbG9hdCkodmFsdWUgLSBHZXRNYXhOZWdhdGl2ZVB3bSgpKSAvCisgICAgICAgICAgIChmbG9hdClHZXROZWdhdGl2ZVNjYWxlRmFjdG9yKCk7CisgIH0gZWxzZSB7CisgICAgcmV0dXJuIDAuMDsKKyAgfQorfQorCisvKioKKyAqIFNldCB0aGUgUFdNIHZhbHVlIGRpcmVjdGx5IHRvIHRoZSBoYXJkd2FyZS4KKyAqCisgKiBXcml0ZSBhIHJhdyB2YWx1ZSB0byBhIFBXTSBjaGFubmVsLgorICoKKyAqIEBwYXJhbSB2YWx1ZSBSYXcgUFdNIHZhbHVlLgorICovCit2b2lkIFBXTTo6U2V0UmF3KHVuc2lnbmVkIHNob3J0IHZhbHVlKSB7CisgIGlmIChTdGF0dXNJc0ZhdGFsKCkpIHJldHVybjsKKworICBpbnQzMl90IHN0YXR1cyA9IDA7CisgIHNldFBXTShtX3B3bV9wb3J0c1ttX2NoYW5uZWxdLCB2YWx1ZSwgJnN0YXR1cyk7CisgIHdwaV9zZXRFcnJvcldpdGhDb250ZXh0KHN0YXR1cywgZ2V0SEFMRXJyb3JNZXNzYWdlKHN0YXR1cykpOworfQorCisvKioKKyAqIEdldCB0aGUgUFdNIHZhbHVlIGRpcmVjdGx5IGZyb20gdGhlIGhhcmR3YXJlLgorICoKKyAqIFJlYWQgYSByYXcgdmFsdWUgZnJvbSBhIFBXTSBjaGFubmVsLgorICoKKyAqIEByZXR1cm4gUmF3IFBXTSBjb250cm9sIHZhbHVlLgorICovCit1bnNpZ25lZCBzaG9ydCBQV006OkdldFJhdygpIGNvbnN0IHsKKyAgaWYgKFN0YXR1c0lzRmF0YWwoKSkgcmV0dXJuIDA7CisKKyAgaW50MzJfdCBzdGF0dXMgPSAwOworICB1bnNpZ25lZCBzaG9ydCB2YWx1ZSA9IGdldFBXTShtX3B3bV9wb3J0c1ttX2NoYW5uZWxdLCAmc3RhdHVzKTsKKyAgd3BpX3NldEVycm9yV2l0aENvbnRleHQoc3RhdHVzLCBnZXRIQUxFcnJvck1lc3NhZ2Uoc3RhdHVzKSk7CisKKyAgcmV0dXJuIHZhbHVlOworfQorCisvKioKKyAqIFNsb3cgZG93biB0aGUgUFdNIHNpZ25hbCBmb3Igb2xkIGRldmljZXMuCisgKgorICogQHBhcmFtIG11bHQgVGhlIHBlcmlvZCBtdWx0aXBsaWVyIHRvIGFwcGx5IHRvIHRoaXMgY2hhbm5lbAorICovCit2b2lkIFBXTTo6U2V0UGVyaW9kTXVsdGlwbGllcihQZXJpb2RNdWx0aXBsaWVyIG11bHQpIHsKKyAgaWYgKFN0YXR1c0lzRmF0YWwoKSkgcmV0dXJuOworCisgIGludDMyX3Qgc3RhdHVzID0gMDsKKworICBzd2l0Y2ggKG11bHQpIHsKKyAgICBjYXNlIGtQZXJpb2RNdWx0aXBsaWVyXzRYOgorICAgICAgc2V0UFdNUGVyaW9kU2NhbGUobV9wd21fcG9ydHNbbV9jaGFubmVsXSwgMywKKyAgICAgICAgICAgICAgICAgICAgICAgICZzdGF0dXMpOyAgLy8gU3F1ZWxjaCAzIG91dCBvZiA0IG91dHB1dHMKKyAgICAgIGJyZWFrOworICAgIGNhc2Uga1BlcmlvZE11bHRpcGxpZXJfMlg6CisgICAgICBzZXRQV01QZXJpb2RTY2FsZShtX3B3bV9wb3J0c1ttX2NoYW5uZWxdLCAxLAorICAgICAgICAgICAgICAgICAgICAgICAgJnN0YXR1cyk7ICAvLyBTcXVlbGNoIDEgb3V0IG9mIDIgb3V0cHV0cworICAgICAgYnJlYWs7CisgICAgY2FzZSBrUGVyaW9kTXVsdGlwbGllcl8xWDoKKyAgICAgIHNldFBXTVBlcmlvZFNjYWxlKG1fcHdtX3BvcnRzW21fY2hhbm5lbF0sIDAsCisgICAgICAgICAgICAgICAgICAgICAgICAmc3RhdHVzKTsgIC8vIERvbid0IHNxdWVsY2ggYW55IG91dHB1dHMKKyAgICAgIGJyZWFrOworICAgIGRlZmF1bHQ6CisgICAgICB3cGlfYXNzZXJ0KGZhbHNlKTsKKyAgfQorCisgIHdwaV9zZXRFcnJvcldpdGhDb250ZXh0KHN0YXR1cywgZ2V0SEFMRXJyb3JNZXNzYWdlKHN0YXR1cykpOworfQorCit2b2lkIFBXTTo6U2V0WmVyb0xhdGNoKCkgeworICBpZiAoU3RhdHVzSXNGYXRhbCgpKSByZXR1cm47CisKKyAgaW50MzJfdCBzdGF0dXMgPSAwOworCisgIGxhdGNoUFdNWmVybyhtX3B3bV9wb3J0c1ttX2NoYW5uZWxdLCAmc3RhdHVzKTsKKyAgd3BpX3NldEVycm9yV2l0aENvbnRleHQoc3RhdHVzLCBnZXRIQUxFcnJvck1lc3NhZ2Uoc3RhdHVzKSk7Cit9CisKK3ZvaWQgUFdNOjpWYWx1ZUNoYW5nZWQoSVRhYmxlKiBzb3VyY2UsIGxsdm06OlN0cmluZ1JlZiBrZXksCisgICAgICAgICAgICAgICAgICAgICAgIHN0ZDo6c2hhcmVkX3B0cjxudDo6VmFsdWU+IHZhbHVlLCBib29sIGlzTmV3KSB7CisgIGlmICghdmFsdWUtPklzRG91YmxlKCkpIHJldHVybjsKKyAgU2V0U3BlZWQodmFsdWUtPkdldERvdWJsZSgpKTsKK30KKwordm9pZCBQV006OlVwZGF0ZVRhYmxlKCkgeworICBpZiAobV90YWJsZSAhPSBudWxscHRyKSB7CisgICAgbV90YWJsZS0+UHV0TnVtYmVyKCJWYWx1ZSIsIEdldFNwZWVkKCkpOworICB9Cit9CisKK3ZvaWQgUFdNOjpTdGFydExpdmVXaW5kb3dNb2RlKCkgeworICBTZXRTcGVlZCgwKTsKKyAgaWYgKG1fdGFibGUgIT0gbnVsbHB0cikgeworICAgIG1fdGFibGUtPkFkZFRhYmxlTGlzdGVuZXIoIlZhbHVlIiwgdGhpcywgdHJ1ZSk7CisgIH0KK30KKwordm9pZCBQV006OlN0b3BMaXZlV2luZG93TW9kZSgpIHsKKyAgU2V0U3BlZWQoMCk7CisgIGlmIChtX3RhYmxlICE9IG51bGxwdHIpIHsKKyAgICBtX3RhYmxlLT5SZW1vdmVUYWJsZUxpc3RlbmVyKHRoaXMpOworICB9Cit9CisKK3N0ZDo6c3RyaW5nIFBXTTo6R2V0U21hcnREYXNoYm9hcmRUeXBlKCkgY29uc3QgeyByZXR1cm4gIlNwZWVkIENvbnRyb2xsZXIiOyB9CisKK3ZvaWQgUFdNOjpJbml0VGFibGUoc3RkOjpzaGFyZWRfcHRyPElUYWJsZT4gc3ViVGFibGUpIHsKKyAgbV90YWJsZSA9IHN1YlRhYmxlOworICBVcGRhdGVUYWJsZSgpOworfQorCitzdGQ6OnNoYXJlZF9wdHI8SVRhYmxlPiBQV006OkdldFRhYmxlKCkgY29uc3QgeyByZXR1cm4gbV90YWJsZTsgfQpkaWZmIC0tZ2l0IGEvd3BpbGliYy9BdGhlbmEvc3JjL1Bvd2VyRGlzdHJpYnV0aW9uUGFuZWwuY3BwIGIvd3BpbGliYy9BdGhlbmEvc3JjL1Bvd2VyRGlzdHJpYnV0aW9uUGFuZWwuY3BwCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmZiNDI4Y2YKLS0tIC9kZXYvbnVsbAorKysgYi93cGlsaWJjL0F0aGVuYS9zcmMvUG93ZXJEaXN0cmlidXRpb25QYW5lbC5jcHAKQEAgLTAsMCArMSwxOTAgQEAKKy8qLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovCisvKiBDb3B5cmlnaHQgKGMpIEZJUlNUIDIwMTQuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCisgKi8KKy8qIE9wZW4gU291cmNlIFNvZnR3YXJlIC0gbWF5IGJlIG1vZGlmaWVkIGFuZCBzaGFyZWQgYnkgRlJDIHRlYW1zLiBUaGUgY29kZSAgICovCisvKiBtdXN0IGJlIGFjY29tcGFuaWVkIGJ5IHRoZSBGSVJTVCBCU0QgbGljZW5zZSBmaWxlIGluICQoV0lORF9CQVNFKS9XUElMaWIuICAqLworLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi8KKworI2luY2x1ZGUgIlBvd2VyRGlzdHJpYnV0aW9uUGFuZWwuaCIKKyNpbmNsdWRlICJXUElFcnJvcnMuaCIKKyNpbmNsdWRlICJIQUwvUERQLmhwcCIKKyNpbmNsdWRlICJMaXZlV2luZG93L0xpdmVXaW5kb3cuaCIKKworI2luY2x1ZGUgPHNzdHJlYW0+CisKK1Bvd2VyRGlzdHJpYnV0aW9uUGFuZWw6OlBvd2VyRGlzdHJpYnV0aW9uUGFuZWwoKSA6IFBvd2VyRGlzdHJpYnV0aW9uUGFuZWwoMCkge30KKworLyoqCisgKiBJbml0aWFsaXplIHRoZSBQRFAuCisgKi8KK1Bvd2VyRGlzdHJpYnV0aW9uUGFuZWw6OlBvd2VyRGlzdHJpYnV0aW9uUGFuZWwodWludDhfdCBtb2R1bGUpCisgICAgOiBtX21vZHVsZShtb2R1bGUpIHsKKyAgaW5pdGlhbGl6ZVBEUChtX21vZHVsZSk7Cit9CisKKy8qKgorICogUXVlcnkgdGhlIGlucHV0IHZvbHRhZ2Ugb2YgdGhlIFBEUAorICogQHJldHVybiBUaGUgdm9sdGFnZSBvZiB0aGUgUERQIGluIHZvbHRzCisgKi8KK2RvdWJsZSBQb3dlckRpc3RyaWJ1dGlvblBhbmVsOjpHZXRWb2x0YWdlKCkgY29uc3QgeworICBpbnQzMl90IHN0YXR1cyA9IDA7CisKKyAgZG91YmxlIHZvbHRhZ2UgPSBnZXRQRFBWb2x0YWdlKG1fbW9kdWxlLCAmc3RhdHVzKTsKKworICBpZiAoc3RhdHVzKSB7CisgICAgd3BpX3NldFdQSUVycm9yV2l0aENvbnRleHQoVGltZW91dCwgIiIpOworICB9CisKKyAgcmV0dXJuIHZvbHRhZ2U7Cit9CisKKy8qKgorICogUXVlcnkgdGhlIHRlbXBlcmF0dXJlIG9mIHRoZSBQRFAKKyAqIEByZXR1cm4gVGhlIHRlbXBlcmF0dXJlIG9mIHRoZSBQRFAgaW4gZGVncmVlcyBDZWxzaXVzCisgKi8KK2RvdWJsZSBQb3dlckRpc3RyaWJ1dGlvblBhbmVsOjpHZXRUZW1wZXJhdHVyZSgpIGNvbnN0IHsKKyAgaW50MzJfdCBzdGF0dXMgPSAwOworCisgIGRvdWJsZSB0ZW1wZXJhdHVyZSA9IGdldFBEUFRlbXBlcmF0dXJlKG1fbW9kdWxlLCAmc3RhdHVzKTsKKworICBpZiAoc3RhdHVzKSB7CisgICAgd3BpX3NldFdQSUVycm9yV2l0aENvbnRleHQoVGltZW91dCwgIiIpOworICB9CisKKyAgcmV0dXJuIHRlbXBlcmF0dXJlOworfQorCisvKioKKyAqIFF1ZXJ5IHRoZSBjdXJyZW50IG9mIGEgc2luZ2xlIGNoYW5uZWwgb2YgdGhlIFBEUAorICogQHJldHVybiBUaGUgY3VycmVudCBvZiBvbmUgb2YgdGhlIFBEUCBjaGFubmVscyAoY2hhbm5lbHMgMC0xNSkgaW4gQW1wZXJlcworICovCitkb3VibGUgUG93ZXJEaXN0cmlidXRpb25QYW5lbDo6R2V0Q3VycmVudCh1aW50OF90IGNoYW5uZWwpIGNvbnN0IHsKKyAgaW50MzJfdCBzdGF0dXMgPSAwOworCisgIGlmICghQ2hlY2tQRFBDaGFubmVsKGNoYW5uZWwpKSB7CisgICAgc3RkOjpzdHJpbmdzdHJlYW0gYnVmOworICAgIGJ1ZiA8PCAiUERQIENoYW5uZWwgIiA8PCBjaGFubmVsOworICAgIHdwaV9zZXRXUElFcnJvcldpdGhDb250ZXh0KENoYW5uZWxJbmRleE91dE9mUmFuZ2UsIGJ1Zi5zdHIoKSk7CisgIH0KKworICBkb3VibGUgY3VycmVudCA9IGdldFBEUENoYW5uZWxDdXJyZW50KG1fbW9kdWxlLCBjaGFubmVsLCAmc3RhdHVzKTsKKworICBpZiAoc3RhdHVzKSB7CisgICAgd3BpX3NldFdQSUVycm9yV2l0aENvbnRleHQoVGltZW91dCwgIiIpOworICB9CisKKyAgcmV0dXJuIGN1cnJlbnQ7Cit9CisKKy8qKgorICogUXVlcnkgdGhlIHRvdGFsIGN1cnJlbnQgb2YgYWxsIG1vbml0b3JlZCBQRFAgY2hhbm5lbHMgKDAtMTUpCisgKiBAcmV0dXJuIFRoZSB0aGUgdG90YWwgY3VycmVudCBkcmF3biBmcm9tIHRoZSBQRFAgY2hhbm5lbHMgaW4gQW1wZXJlcworICovCitkb3VibGUgUG93ZXJEaXN0cmlidXRpb25QYW5lbDo6R2V0VG90YWxDdXJyZW50KCkgY29uc3QgeworICBpbnQzMl90IHN0YXR1cyA9IDA7CisKKyAgZG91YmxlIGN1cnJlbnQgPSBnZXRQRFBUb3RhbEN1cnJlbnQobV9tb2R1bGUsICZzdGF0dXMpOworCisgIGlmIChzdGF0dXMpIHsKKyAgICB3cGlfc2V0V1BJRXJyb3JXaXRoQ29udGV4dChUaW1lb3V0LCAiIik7CisgIH0KKworICByZXR1cm4gY3VycmVudDsKK30KKworLyoqCisgKiBRdWVyeSB0aGUgdG90YWwgcG93ZXIgZHJhd24gZnJvbSB0aGUgbW9uaXRvcmVkIFBEUCBjaGFubmVscworICogQHJldHVybiBUaGUgdGhlIHRvdGFsIHBvd2VyIGRyYXduIGZyb20gdGhlIFBEUCBjaGFubmVscyBpbiBXYXR0cworICovCitkb3VibGUgUG93ZXJEaXN0cmlidXRpb25QYW5lbDo6R2V0VG90YWxQb3dlcigpIGNvbnN0IHsKKyAgaW50MzJfdCBzdGF0dXMgPSAwOworCisgIGRvdWJsZSBwb3dlciA9IGdldFBEUFRvdGFsUG93ZXIobV9tb2R1bGUsICZzdGF0dXMpOworCisgIGlmIChzdGF0dXMpIHsKKyAgICB3cGlfc2V0V1BJRXJyb3JXaXRoQ29udGV4dChUaW1lb3V0LCAiIik7CisgIH0KKworICByZXR1cm4gcG93ZXI7Cit9CisKKy8qKgorICogUXVlcnkgdGhlIHRvdGFsIGVuZXJneSBkcmF3biBmcm9tIHRoZSBtb25pdG9yZWQgUERQIGNoYW5uZWxzCisgKiBAcmV0dXJuIFRoZSB0aGUgdG90YWwgZW5lcmd5IGRyYXduIGZyb20gdGhlIFBEUCBjaGFubmVscyBpbiBKb3VsZXMKKyAqLworZG91YmxlIFBvd2VyRGlzdHJpYnV0aW9uUGFuZWw6OkdldFRvdGFsRW5lcmd5KCkgY29uc3QgeworICBpbnQzMl90IHN0YXR1cyA9IDA7CisKKyAgZG91YmxlIGVuZXJneSA9IGdldFBEUFRvdGFsRW5lcmd5KG1fbW9kdWxlLCAmc3RhdHVzKTsKKworICBpZiAoc3RhdHVzKSB7CisgICAgd3BpX3NldFdQSUVycm9yV2l0aENvbnRleHQoVGltZW91dCwgIiIpOworICB9CisKKyAgcmV0dXJuIGVuZXJneTsKK30KKworLyoqCisgKiBSZXNldCB0aGUgdG90YWwgZW5lcmd5IGRyYXduIGZyb20gdGhlIFBEUAorICogQHNlZSBQb3dlckRpc3RyaWJ1dGlvblBhbmVsI0dldFRvdGFsRW5lcmd5CisgKi8KK3ZvaWQgUG93ZXJEaXN0cmlidXRpb25QYW5lbDo6UmVzZXRUb3RhbEVuZXJneSgpIHsKKyAgaW50MzJfdCBzdGF0dXMgPSAwOworCisgIHJlc2V0UERQVG90YWxFbmVyZ3kobV9tb2R1bGUsICZzdGF0dXMpOworCisgIGlmIChzdGF0dXMpIHsKKyAgICB3cGlfc2V0V1BJRXJyb3JXaXRoQ29udGV4dChUaW1lb3V0LCAiIik7CisgIH0KK30KKworLyoqCisgKiBSZW1vdmUgYWxsIG9mIHRoZSBmYXVsdCBmbGFncyBvbiB0aGUgUERQCisgKi8KK3ZvaWQgUG93ZXJEaXN0cmlidXRpb25QYW5lbDo6Q2xlYXJTdGlja3lGYXVsdHMoKSB7CisgIGludDMyX3Qgc3RhdHVzID0gMDsKKworICBjbGVhclBEUFN0aWNreUZhdWx0cyhtX21vZHVsZSwgJnN0YXR1cyk7CisKKyAgaWYgKHN0YXR1cykgeworICAgIHdwaV9zZXRXUElFcnJvcldpdGhDb250ZXh0KFRpbWVvdXQsICIiKTsKKyAgfQorfQorCit2b2lkIFBvd2VyRGlzdHJpYnV0aW9uUGFuZWw6OlVwZGF0ZVRhYmxlKCkgeworICBpZiAobV90YWJsZSAhPSBudWxscHRyKSB7CisgICAgbV90YWJsZS0+UHV0TnVtYmVyKCJDaGFuMCIsIEdldEN1cnJlbnQoMCkpOworICAgIG1fdGFibGUtPlB1dE51bWJlcigiQ2hhbjEiLCBHZXRDdXJyZW50KDEpKTsKKyAgICBtX3RhYmxlLT5QdXROdW1iZXIoIkNoYW4yIiwgR2V0Q3VycmVudCgyKSk7CisgICAgbV90YWJsZS0+UHV0TnVtYmVyKCJDaGFuMyIsIEdldEN1cnJlbnQoMykpOworICAgIG1fdGFibGUtPlB1dE51bWJlcigiQ2hhbjQiLCBHZXRDdXJyZW50KDQpKTsKKyAgICBtX3RhYmxlLT5QdXROdW1iZXIoIkNoYW41IiwgR2V0Q3VycmVudCg1KSk7CisgICAgbV90YWJsZS0+UHV0TnVtYmVyKCJDaGFuNiIsIEdldEN1cnJlbnQoNikpOworICAgIG1fdGFibGUtPlB1dE51bWJlcigiQ2hhbjciLCBHZXRDdXJyZW50KDcpKTsKKyAgICBtX3RhYmxlLT5QdXROdW1iZXIoIkNoYW44IiwgR2V0Q3VycmVudCg4KSk7CisgICAgbV90YWJsZS0+UHV0TnVtYmVyKCJDaGFuOSIsIEdldEN1cnJlbnQoOSkpOworICAgIG1fdGFibGUtPlB1dE51bWJlcigiQ2hhbjEwIiwgR2V0Q3VycmVudCgxMCkpOworICAgIG1fdGFibGUtPlB1dE51bWJlcigiQ2hhbjExIiwgR2V0Q3VycmVudCgxMSkpOworICAgIG1fdGFibGUtPlB1dE51bWJlcigiQ2hhbjEyIiwgR2V0Q3VycmVudCgxMikpOworICAgIG1fdGFibGUtPlB1dE51bWJlcigiQ2hhbjEzIiwgR2V0Q3VycmVudCgxMykpOworICAgIG1fdGFibGUtPlB1dE51bWJlcigiQ2hhbjE0IiwgR2V0Q3VycmVudCgxNCkpOworICAgIG1fdGFibGUtPlB1dE51bWJlcigiQ2hhbjE1IiwgR2V0Q3VycmVudCgxNSkpOworICAgIG1fdGFibGUtPlB1dE51bWJlcigiVm9sdGFnZSIsIEdldFZvbHRhZ2UoKSk7CisgICAgbV90YWJsZS0+UHV0TnVtYmVyKCJUb3RhbEN1cnJlbnQiLCBHZXRUb3RhbEN1cnJlbnQoKSk7CisgIH0KK30KKwordm9pZCBQb3dlckRpc3RyaWJ1dGlvblBhbmVsOjpTdGFydExpdmVXaW5kb3dNb2RlKCkge30KKwordm9pZCBQb3dlckRpc3RyaWJ1dGlvblBhbmVsOjpTdG9wTGl2ZVdpbmRvd01vZGUoKSB7fQorCitzdGQ6OnN0cmluZyBQb3dlckRpc3RyaWJ1dGlvblBhbmVsOjpHZXRTbWFydERhc2hib2FyZFR5cGUoKSBjb25zdCB7CisgIHJldHVybiAiUG93ZXJEaXN0cmlidXRpb25QYW5lbCI7Cit9CisKK3ZvaWQgUG93ZXJEaXN0cmlidXRpb25QYW5lbDo6SW5pdFRhYmxlKHN0ZDo6c2hhcmVkX3B0cjxJVGFibGU+IHN1YlRhYmxlKSB7CisgIG1fdGFibGUgPSBzdWJUYWJsZTsKKyAgVXBkYXRlVGFibGUoKTsKK30KKworc3RkOjpzaGFyZWRfcHRyPElUYWJsZT4gUG93ZXJEaXN0cmlidXRpb25QYW5lbDo6R2V0VGFibGUoKSBjb25zdCB7IHJldHVybiBtX3RhYmxlOyB9CmRpZmYgLS1naXQgYS93cGlsaWJjL0F0aGVuYS9zcmMvUHJlZmVyZW5jZXMuY3BwIGIvd3BpbGliYy9BdGhlbmEvc3JjL1ByZWZlcmVuY2VzLmNwcApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi45NWY2YTRhCi0tLSAvZGV2L251bGwKKysrIGIvd3BpbGliYy9BdGhlbmEvc3JjL1ByZWZlcmVuY2VzLmNwcApAQCAtMCwwICsxLDIxNyBAQAorLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi8KKy8qIENvcHlyaWdodCAoYykgRklSU1QgMjAxMS4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICovCisvKiBPcGVuIFNvdXJjZSBTb2Z0d2FyZSAtIG1heSBiZSBtb2RpZmllZCBhbmQgc2hhcmVkIGJ5IEZSQyB0ZWFtcy4gVGhlIGNvZGUgICAqLworLyogbXVzdCBiZSBhY2NvbXBhbmllZCBieSB0aGUgRklSU1QgQlNEIGxpY2Vuc2UgZmlsZSBpbiAkKFdJTkRfQkFTRSkvV1BJTGliLiAgKi8KKy8qLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovCisKKyNpbmNsdWRlICJQcmVmZXJlbmNlcy5oIgorCisjaW5jbHVkZSAiV1BJRXJyb3JzLmgiCisjaW5jbHVkZSAiSEFML0hBTC5ocHAiCisKKyNpbmNsdWRlIDxzdGRpby5oPgorI2luY2x1ZGUgPGFsZ29yaXRobT4KKworLyoqIFRoZSBQcmVmZXJlbmNlcyB0YWJsZSBuYW1lICovCitzdGF0aWMgY29uc3QgY2hhciAqa1RhYmxlTmFtZSA9ICJQcmVmZXJlbmNlcyI7CisKK3ZvaWQgUHJlZmVyZW5jZXM6Okxpc3RlbmVyOjpWYWx1ZUNoYW5nZWQoSVRhYmxlKiBzb3VyY2UsIGxsdm06OlN0cmluZ1JlZiBrZXksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0ZDo6c2hhcmVkX3B0cjxudDo6VmFsdWU+IHZhbHVlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBib29sIGlzTmV3KSB7fQordm9pZCBQcmVmZXJlbmNlczo6TGlzdGVuZXI6OlZhbHVlQ2hhbmdlZEV4KElUYWJsZSogc291cmNlLCBsbHZtOjpTdHJpbmdSZWYga2V5LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0ZDo6c2hhcmVkX3B0cjxudDo6VmFsdWU+IHZhbHVlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVuc2lnbmVkIGludCBmbGFncykgeworICBzb3VyY2UtPlNldFBlcnNpc3RlbnQoa2V5KTsKK30KKworUHJlZmVyZW5jZXM6OlByZWZlcmVuY2VzKCkgOiBtX3RhYmxlKE5ldHdvcmtUYWJsZTo6R2V0VGFibGUoa1RhYmxlTmFtZSkpIHsKKyAgbV90YWJsZS0+QWRkVGFibGVMaXN0ZW5lckV4KCZtX2xpc3RlbmVyLCBOVF9OT1RJRllfTkVXIHwgTlRfTk9USUZZX0lNTUVESUFURSk7CisgIEhBTFJlcG9ydChIQUxVc2FnZVJlcG9ydGluZzo6a1Jlc291cmNlVHlwZV9QcmVmZXJlbmNlcywgMCk7Cit9CisKKy8qKgorICogR2V0IHRoZSBvbmUgYW5kIG9ubHkge0BsaW5rIFByZWZlcmVuY2VzfSBvYmplY3QKKyAqIEByZXR1cm4gcG9pbnRlciB0byB0aGUge0BsaW5rIFByZWZlcmVuY2VzfQorICovCitQcmVmZXJlbmNlcyAqUHJlZmVyZW5jZXM6OkdldEluc3RhbmNlKCkgeworICBzdGF0aWMgUHJlZmVyZW5jZXMgaW5zdGFuY2U7CisgIHJldHVybiAmaW5zdGFuY2U7Cit9CisKKy8qKgorICogUmV0dXJucyBhIHZlY3RvciBvZiBhbGwgdGhlIGtleXMKKyAqIEByZXR1cm4gYSB2ZWN0b3Igb2YgdGhlIGtleXMKKyAqLworc3RkOjp2ZWN0b3I8c3RkOjpzdHJpbmc+IFByZWZlcmVuY2VzOjpHZXRLZXlzKCkgeyByZXR1cm4gbV90YWJsZS0+R2V0S2V5cygpOyB9CisKKy8qKgorICogUmV0dXJucyB0aGUgc3RyaW5nIGF0IHRoZSBnaXZlbiBrZXkuICBJZiB0aGlzIHRhYmxlIGRvZXMgbm90IGhhdmUgYSB2YWx1ZQorICogZm9yIHRoYXQgcG9zaXRpb24sIHRoZW4gdGhlIGdpdmVuIGRlZmF1bHRWYWx1ZSB3aWxsIGJlIHJldHVybmVkLgorICogQHBhcmFtIGtleSB0aGUga2V5CisgKiBAcGFyYW0gZGVmYXVsdFZhbHVlIHRoZSB2YWx1ZSB0byByZXR1cm4gaWYgbm9uZSBleGlzdHMgaW4gdGhlIHRhYmxlCisgKiBAcmV0dXJuIGVpdGhlciB0aGUgdmFsdWUgaW4gdGhlIHRhYmxlLCBvciB0aGUgZGVmYXVsdFZhbHVlCisgKi8KK3N0ZDo6c3RyaW5nIFByZWZlcmVuY2VzOjpHZXRTdHJpbmcobGx2bTo6U3RyaW5nUmVmIGtleSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGx2bTo6U3RyaW5nUmVmIGRlZmF1bHRWYWx1ZSkgeworICByZXR1cm4gbV90YWJsZS0+R2V0U3RyaW5nKGtleSwgZGVmYXVsdFZhbHVlKTsKK30KKworLyoqCisgKiBSZXR1cm5zIHRoZSBpbnQgYXQgdGhlIGdpdmVuIGtleS4gIElmIHRoaXMgdGFibGUgZG9lcyBub3QgaGF2ZSBhIHZhbHVlCisgKiBmb3IgdGhhdCBwb3NpdGlvbiwgdGhlbiB0aGUgZ2l2ZW4gZGVmYXVsdFZhbHVlIHZhbHVlIHdpbGwgYmUgcmV0dXJuZWQuCisgKiBAcGFyYW0ga2V5IHRoZSBrZXkKKyAqIEBwYXJhbSBkZWZhdWx0VmFsdWUgdGhlIHZhbHVlIHRvIHJldHVybiBpZiBub25lIGV4aXN0cyBpbiB0aGUgdGFibGUKKyAqIEByZXR1cm4gZWl0aGVyIHRoZSB2YWx1ZSBpbiB0aGUgdGFibGUsIG9yIHRoZSBkZWZhdWx0VmFsdWUKKyAqLworaW50IFByZWZlcmVuY2VzOjpHZXRJbnQobGx2bTo6U3RyaW5nUmVmIGtleSwgaW50IGRlZmF1bHRWYWx1ZSkgeworICByZXR1cm4gc3RhdGljX2Nhc3Q8aW50PihtX3RhYmxlLT5HZXROdW1iZXIoa2V5LCBkZWZhdWx0VmFsdWUpKTsKK30KKworLyoqCisgKiBSZXR1cm5zIHRoZSBkb3VibGUgYXQgdGhlIGdpdmVuIGtleS4gIElmIHRoaXMgdGFibGUgZG9lcyBub3QgaGF2ZSBhIHZhbHVlCisgKiBmb3IgdGhhdCBwb3NpdGlvbiwgdGhlbiB0aGUgZ2l2ZW4gZGVmYXVsdFZhbHVlIHZhbHVlIHdpbGwgYmUgcmV0dXJuZWQuCisgKiBAcGFyYW0ga2V5IHRoZSBrZXkKKyAqIEBwYXJhbSBkZWZhdWx0VmFsdWUgdGhlIHZhbHVlIHRvIHJldHVybiBpZiBub25lIGV4aXN0cyBpbiB0aGUgdGFibGUKKyAqIEByZXR1cm4gZWl0aGVyIHRoZSB2YWx1ZSBpbiB0aGUgdGFibGUsIG9yIHRoZSBkZWZhdWx0VmFsdWUKKyAqLworZG91YmxlIFByZWZlcmVuY2VzOjpHZXREb3VibGUobGx2bTo6U3RyaW5nUmVmIGtleSwgZG91YmxlIGRlZmF1bHRWYWx1ZSkgeworICByZXR1cm4gbV90YWJsZS0+R2V0TnVtYmVyKGtleSwgZGVmYXVsdFZhbHVlKTsKK30KKworLyoqCisgKiBSZXR1cm5zIHRoZSBmbG9hdCBhdCB0aGUgZ2l2ZW4ga2V5LiAgSWYgdGhpcyB0YWJsZSBkb2VzIG5vdCBoYXZlIGEgdmFsdWUKKyAqIGZvciB0aGF0IHBvc2l0aW9uLCB0aGVuIHRoZSBnaXZlbiBkZWZhdWx0VmFsdWUgdmFsdWUgd2lsbCBiZSByZXR1cm5lZC4KKyAqIEBwYXJhbSBrZXkgdGhlIGtleQorICogQHBhcmFtIGRlZmF1bHRWYWx1ZSB0aGUgdmFsdWUgdG8gcmV0dXJuIGlmIG5vbmUgZXhpc3RzIGluIHRoZSB0YWJsZQorICogQHJldHVybiBlaXRoZXIgdGhlIHZhbHVlIGluIHRoZSB0YWJsZSwgb3IgdGhlIGRlZmF1bHRWYWx1ZQorICovCitmbG9hdCBQcmVmZXJlbmNlczo6R2V0RmxvYXQobGx2bTo6U3RyaW5nUmVmIGtleSwgZmxvYXQgZGVmYXVsdFZhbHVlKSB7CisgIHJldHVybiBzdGF0aWNfY2FzdDxmbG9hdD4obV90YWJsZS0+R2V0TnVtYmVyKGtleSwgZGVmYXVsdFZhbHVlKSk7Cit9CisKKy8qKgorICogUmV0dXJucyB0aGUgYm9vbGVhbiBhdCB0aGUgZ2l2ZW4ga2V5LiAgSWYgdGhpcyB0YWJsZSBkb2VzIG5vdCBoYXZlIGEgdmFsdWUKKyAqIGZvciB0aGF0IHBvc2l0aW9uLCB0aGVuIHRoZSBnaXZlbiBkZWZhdWx0VmFsdWUgdmFsdWUgd2lsbCBiZSByZXR1cm5lZC4KKyAqIEBwYXJhbSBrZXkgdGhlIGtleQorICogQHBhcmFtIGRlZmF1bHRWYWx1ZSB0aGUgdmFsdWUgdG8gcmV0dXJuIGlmIG5vbmUgZXhpc3RzIGluIHRoZSB0YWJsZQorICogQHJldHVybiBlaXRoZXIgdGhlIHZhbHVlIGluIHRoZSB0YWJsZSwgb3IgdGhlIGRlZmF1bHRWYWx1ZQorICovCitib29sIFByZWZlcmVuY2VzOjpHZXRCb29sZWFuKGxsdm06OlN0cmluZ1JlZiBrZXksIGJvb2wgZGVmYXVsdFZhbHVlKSB7CisgIHJldHVybiBtX3RhYmxlLT5HZXRCb29sZWFuKGtleSwgZGVmYXVsdFZhbHVlKTsKK30KKworLyoqCisgKiBSZXR1cm5zIHRoZSBsb25nIChpbnQ2NF90KSBhdCB0aGUgZ2l2ZW4ga2V5LiAgSWYgdGhpcyB0YWJsZSBkb2VzIG5vdCBoYXZlIGEKKyAqIHZhbHVlCisgKiBmb3IgdGhhdCBwb3NpdGlvbiwgdGhlbiB0aGUgZ2l2ZW4gZGVmYXVsdFZhbHVlIHZhbHVlIHdpbGwgYmUgcmV0dXJuZWQuCisgKiBAcGFyYW0ga2V5IHRoZSBrZXkKKyAqIEBwYXJhbSBkZWZhdWx0VmFsdWUgdGhlIHZhbHVlIHRvIHJldHVybiBpZiBub25lIGV4aXN0cyBpbiB0aGUgdGFibGUKKyAqIEByZXR1cm4gZWl0aGVyIHRoZSB2YWx1ZSBpbiB0aGUgdGFibGUsIG9yIHRoZSBkZWZhdWx0VmFsdWUKKyAqLworaW50NjRfdCBQcmVmZXJlbmNlczo6R2V0TG9uZyhsbHZtOjpTdHJpbmdSZWYga2V5LCBpbnQ2NF90IGRlZmF1bHRWYWx1ZSkgeworICByZXR1cm4gc3RhdGljX2Nhc3Q8aW50NjRfdD4obV90YWJsZS0+R2V0TnVtYmVyKGtleSwgZGVmYXVsdFZhbHVlKSk7Cit9CisKKy8qKgorICogUHV0cyB0aGUgZ2l2ZW4gc3RyaW5nIGludG8gdGhlIHByZWZlcmVuY2VzIHRhYmxlLgorICoKKyAqIDxwPlRoZSB2YWx1ZSBtYXkgbm90IGhhdmUgcXVvdGF0aW9uIG1hcmtzLCBub3IgbWF5IHRoZSBrZXkKKyAqIGhhdmUgYW55IHdoaXRlc3BhY2Ugbm9yIGFuIGVxdWFscyBzaWduPC9wPgorICoKKyAqIEBwYXJhbSBrZXkgdGhlIGtleQorICogQHBhcmFtIHZhbHVlIHRoZSB2YWx1ZQorICovCit2b2lkIFByZWZlcmVuY2VzOjpQdXRTdHJpbmcobGx2bTo6U3RyaW5nUmVmIGtleSwgbGx2bTo6U3RyaW5nUmVmIHZhbHVlKSB7CisgIG1fdGFibGUtPlB1dFN0cmluZyhrZXksIHZhbHVlKTsKKyAgbV90YWJsZS0+U2V0UGVyc2lzdGVudChrZXkpOworfQorCisvKioKKyAqIFB1dHMgdGhlIGdpdmVuIGludCBpbnRvIHRoZSBwcmVmZXJlbmNlcyB0YWJsZS4KKyAqCisgKiA8cD5UaGUga2V5IG1heSBub3QgaGF2ZSBhbnkgd2hpdGVzcGFjZSBub3IgYW4gZXF1YWxzIHNpZ248L3A+CisgKgorICogQHBhcmFtIGtleSB0aGUga2V5CisgKiBAcGFyYW0gdmFsdWUgdGhlIHZhbHVlCisgKi8KK3ZvaWQgUHJlZmVyZW5jZXM6OlB1dEludChsbHZtOjpTdHJpbmdSZWYga2V5LCBpbnQgdmFsdWUpIHsKKyAgbV90YWJsZS0+UHV0TnVtYmVyKGtleSwgdmFsdWUpOworICBtX3RhYmxlLT5TZXRQZXJzaXN0ZW50KGtleSk7Cit9CisKKy8qKgorICogUHV0cyB0aGUgZ2l2ZW4gZG91YmxlIGludG8gdGhlIHByZWZlcmVuY2VzIHRhYmxlLgorICoKKyAqIDxwPlRoZSBrZXkgbWF5IG5vdCBoYXZlIGFueSB3aGl0ZXNwYWNlIG5vciBhbiBlcXVhbHMgc2lnbjwvcD4KKyAqCisgKiBAcGFyYW0ga2V5IHRoZSBrZXkKKyAqIEBwYXJhbSB2YWx1ZSB0aGUgdmFsdWUKKyAqLwordm9pZCBQcmVmZXJlbmNlczo6UHV0RG91YmxlKGxsdm06OlN0cmluZ1JlZiBrZXksIGRvdWJsZSB2YWx1ZSkgeworICBtX3RhYmxlLT5QdXROdW1iZXIoa2V5LCB2YWx1ZSk7CisgIG1fdGFibGUtPlNldFBlcnNpc3RlbnQoa2V5KTsKK30KKworLyoqCisgKiBQdXRzIHRoZSBnaXZlbiBmbG9hdCBpbnRvIHRoZSBwcmVmZXJlbmNlcyB0YWJsZS4KKyAqCisgKiA8cD5UaGUga2V5IG1heSBub3QgaGF2ZSBhbnkgd2hpdGVzcGFjZSBub3IgYW4gZXF1YWxzIHNpZ248L3A+CisgKgorICogQHBhcmFtIGtleSB0aGUga2V5CisgKiBAcGFyYW0gdmFsdWUgdGhlIHZhbHVlCisgKi8KK3ZvaWQgUHJlZmVyZW5jZXM6OlB1dEZsb2F0KGxsdm06OlN0cmluZ1JlZiBrZXksIGZsb2F0IHZhbHVlKSB7CisgIG1fdGFibGUtPlB1dE51bWJlcihrZXksIHZhbHVlKTsKKyAgbV90YWJsZS0+U2V0UGVyc2lzdGVudChrZXkpOworfQorCisvKioKKyAqIFB1dHMgdGhlIGdpdmVuIGJvb2xlYW4gaW50byB0aGUgcHJlZmVyZW5jZXMgdGFibGUuCisgKgorICogPHA+VGhlIGtleSBtYXkgbm90IGhhdmUgYW55IHdoaXRlc3BhY2Ugbm9yIGFuIGVxdWFscyBzaWduPC9wPgorICoKKyAqIEBwYXJhbSBrZXkgdGhlIGtleQorICogQHBhcmFtIHZhbHVlIHRoZSB2YWx1ZQorICovCit2b2lkIFByZWZlcmVuY2VzOjpQdXRCb29sZWFuKGxsdm06OlN0cmluZ1JlZiBrZXksIGJvb2wgdmFsdWUpIHsKKyAgbV90YWJsZS0+UHV0Qm9vbGVhbihrZXksIHZhbHVlKTsKKyAgbV90YWJsZS0+U2V0UGVyc2lzdGVudChrZXkpOworfQorCisvKioKKyAqIFB1dHMgdGhlIGdpdmVuIGxvbmcgKGludDY0X3QpIGludG8gdGhlIHByZWZlcmVuY2VzIHRhYmxlLgorICoKKyAqIDxwPlRoZSBrZXkgbWF5IG5vdCBoYXZlIGFueSB3aGl0ZXNwYWNlIG5vciBhbiBlcXVhbHMgc2lnbjwvcD4KKyAqCisgKiBAcGFyYW0ga2V5IHRoZSBrZXkKKyAqIEBwYXJhbSB2YWx1ZSB0aGUgdmFsdWUKKyAqLwordm9pZCBQcmVmZXJlbmNlczo6UHV0TG9uZyhsbHZtOjpTdHJpbmdSZWYga2V5LCBpbnQ2NF90IHZhbHVlKSB7CisgIG1fdGFibGUtPlB1dE51bWJlcihrZXksIHZhbHVlKTsKKyAgbV90YWJsZS0+U2V0UGVyc2lzdGVudChrZXkpOworfQorCisvKioKKyAqIFRoaXMgZnVuY3Rpb24gaXMgbm8gbG9uZ2VyIHJlcXVpcmVkLCBhcyBOZXR3b3JrVGFibGVzIGF1dG9tYXRpY2FsbHkKKyAqIHNhdmVzIHBlcnNpc3RlbnQgdmFsdWVzICh3aGljaCBhbGwgUHJlZmVyZW5jZXMgdmFsdWVzIGFyZSkgcGVyaW9kaWNhbGx5CisgKiB3aGVuIHJ1bm5pbmcgYXMgYSBzZXJ2ZXIuCisgKiBAZGVwcmVjYXRlZCBiYWNrd2FyZHMgY29tcGF0aWJpbGl0eSBzaGltCisgKi8KK3ZvaWQgUHJlZmVyZW5jZXM6OlNhdmUoKSB7fQorCisvKioKKyAqIFJldHVybnMgd2hldGhlciBvciBub3QgdGhlcmUgaXMgYSBrZXkgd2l0aCB0aGUgZ2l2ZW4gbmFtZS4KKyAqIEBwYXJhbSBrZXkgdGhlIGtleQorICogQHJldHVybiBpZiB0aGVyZSBpcyBhIHZhbHVlIGF0IHRoZSBnaXZlbiBrZXkKKyAqLworYm9vbCBQcmVmZXJlbmNlczo6Q29udGFpbnNLZXkobGx2bTo6U3RyaW5nUmVmIGtleSkgeworICByZXR1cm4gbV90YWJsZS0+Q29udGFpbnNLZXkoa2V5KTsKK30KKworLyoqCisgKiBSZW1vdmUgYSBwcmVmZXJlbmNlCisgKiBAcGFyYW0ga2V5IHRoZSBrZXkKKyAqLwordm9pZCBQcmVmZXJlbmNlczo6UmVtb3ZlKGxsdm06OlN0cmluZ1JlZiBrZXkpIHsKKyAgbV90YWJsZS0+RGVsZXRlKGtleSk7Cit9CmRpZmYgLS1naXQgYS93cGlsaWJjL0F0aGVuYS9zcmMvUmVsYXkuY3BwIGIvd3BpbGliYy9BdGhlbmEvc3JjL1JlbGF5LmNwcApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4xN2YwZWY4Ci0tLSAvZGV2L251bGwKKysrIGIvd3BpbGliYy9BdGhlbmEvc3JjL1JlbGF5LmNwcApAQCAtMCwwICsxLDI5MyBAQAorLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi8KKy8qIENvcHlyaWdodCAoYykgRklSU1QgMjAwOC4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KKyAqLworLyogT3BlbiBTb3VyY2UgU29mdHdhcmUgLSBtYXkgYmUgbW9kaWZpZWQgYW5kIHNoYXJlZCBieSBGUkMgdGVhbXMuIFRoZSBjb2RlCisgKi8KKy8qIG11c3QgYmUgYWNjb21wYW5pZWQgYnkgdGhlIEZJUlNUIEJTRCBsaWNlbnNlIGZpbGUgaW4gJChXSU5EX0JBU0UpL1dQSUxpYi4gICovCisvKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qLworCisjaW5jbHVkZSAiUmVsYXkuaCIKKworI2luY2x1ZGUgIk1vdG9yU2FmZXR5SGVscGVyLmgiCisjaW5jbHVkZSAiUmVzb3VyY2UuaCIKKyNpbmNsdWRlICJXUElFcnJvcnMuaCIKKyNpbmNsdWRlICJMaXZlV2luZG93L0xpdmVXaW5kb3cuaCIKKyNpbmNsdWRlICJIQUwvSEFMLmhwcCIKKworI2luY2x1ZGUgPHNzdHJlYW0+CisKKy8vIEFsbG9jYXRlIGVhY2ggZGlyZWN0aW9uIHNlcGFyYXRlbHkuCitzdGF0aWMgc3RkOjp1bmlxdWVfcHRyPFJlc291cmNlPiByZWxheUNoYW5uZWxzOworCisvKioKKyAqIFJlbGF5IGNvbnN0cnVjdG9yIGdpdmVuIGEgY2hhbm5lbC4KKyAqCisgKiBUaGlzIGNvZGUgaW5pdGlhbGl6ZXMgdGhlIHJlbGF5IGFuZCByZXNlcnZlcyBhbGwgcmVzb3VyY2VzIHRoYXQgbmVlZCB0byBiZQorICogbG9ja2VkLiBJbml0aWFsbHkgdGhlIHJlbGF5IGlzIHNldCB0byBib3RoIGxpbmVzIGF0IDB2LgorICogQHBhcmFtIGNoYW5uZWwgVGhlIGNoYW5uZWwgbnVtYmVyICgwLTMpLgorICogQHBhcmFtIGRpcmVjdGlvbiBUaGUgZGlyZWN0aW9uIHRoYXQgdGhlIFJlbGF5IG9iamVjdCB3aWxsIGNvbnRyb2wuCisgKi8KK1JlbGF5OjpSZWxheSh1aW50MzJfdCBjaGFubmVsLCBSZWxheTo6RGlyZWN0aW9uIGRpcmVjdGlvbikKKyAgICA6IG1fY2hhbm5lbChjaGFubmVsKSwgbV9kaXJlY3Rpb24oZGlyZWN0aW9uKSB7CisgIHN0ZDo6c3RyaW5nc3RyZWFtIGJ1ZjsKKyAgUmVzb3VyY2U6OkNyZWF0ZVJlc291cmNlT2JqZWN0KHJlbGF5Q2hhbm5lbHMsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkaW9fa051bVN5c3RlbXMgKiBrUmVsYXlDaGFubmVscyAqIDIpOworICBpZiAoIVNlbnNvckJhc2U6OkNoZWNrUmVsYXlDaGFubmVsKG1fY2hhbm5lbCkpIHsKKyAgICBidWYgPDwgIlJlbGF5IENoYW5uZWwgIiA8PCBtX2NoYW5uZWw7CisgICAgd3BpX3NldFdQSUVycm9yV2l0aENvbnRleHQoQ2hhbm5lbEluZGV4T3V0T2ZSYW5nZSwgYnVmLnN0cigpKTsKKyAgICByZXR1cm47CisgIH0KKworICBpZiAobV9kaXJlY3Rpb24gPT0ga0JvdGhEaXJlY3Rpb25zIHx8IG1fZGlyZWN0aW9uID09IGtGb3J3YXJkT25seSkgeworICAgIGJ1ZiA8PCAiRm9yd2FyZCBSZWxheSAiIDw8IG1fY2hhbm5lbDsKKyAgICBpZiAocmVsYXlDaGFubmVscy0+QWxsb2NhdGUobV9jaGFubmVsICogMiwgYnVmLnN0cigpKSA9PQorICAgICAgICBzdGQ6Om51bWVyaWNfbGltaXRzPHVpbnQzMl90Pjo6bWF4KCkpIHsKKyAgICAgIENsb25lRXJyb3IoKnJlbGF5Q2hhbm5lbHMpOworICAgICAgcmV0dXJuOworICAgIH0KKworICAgIEhBTFJlcG9ydChIQUxVc2FnZVJlcG9ydGluZzo6a1Jlc291cmNlVHlwZV9SZWxheSwgbV9jaGFubmVsKTsKKyAgfQorICBpZiAobV9kaXJlY3Rpb24gPT0ga0JvdGhEaXJlY3Rpb25zIHx8IG1fZGlyZWN0aW9uID09IGtSZXZlcnNlT25seSkgeworICAgIGJ1ZiA8PCAiUmV2ZXJzZSBSZWxheSAiIDw8IG1fY2hhbm5lbDsKKyAgICBpZiAocmVsYXlDaGFubmVscy0+QWxsb2NhdGUobV9jaGFubmVsICogMiArIDEsIGJ1Zi5zdHIoKSkgPT0KKyAgICAgICAgc3RkOjpudW1lcmljX2xpbWl0czx1aW50MzJfdD46Om1heCgpKSB7CisgICAgICBDbG9uZUVycm9yKCpyZWxheUNoYW5uZWxzKTsKKyAgICAgIHJldHVybjsKKyAgICB9CisKKyAgICBIQUxSZXBvcnQoSEFMVXNhZ2VSZXBvcnRpbmc6OmtSZXNvdXJjZVR5cGVfUmVsYXksIG1fY2hhbm5lbCArIDEyOCk7CisgIH0KKworICBpbnQzMl90IHN0YXR1cyA9IDA7CisgIHNldFJlbGF5Rm9yd2FyZChtX3JlbGF5X3BvcnRzW21fY2hhbm5lbF0sIGZhbHNlLCAmc3RhdHVzKTsKKyAgc2V0UmVsYXlSZXZlcnNlKG1fcmVsYXlfcG9ydHNbbV9jaGFubmVsXSwgZmFsc2UsICZzdGF0dXMpOworICB3cGlfc2V0RXJyb3JXaXRoQ29udGV4dChzdGF0dXMsIGdldEhBTEVycm9yTWVzc2FnZShzdGF0dXMpKTsKKworICBtX3NhZmV0eUhlbHBlciA9IHN0ZDo6bWFrZV91bmlxdWU8TW90b3JTYWZldHlIZWxwZXI+KHRoaXMpOworICBtX3NhZmV0eUhlbHBlci0+U2V0U2FmZXR5RW5hYmxlZChmYWxzZSk7CisKKyAgTGl2ZVdpbmRvdzo6R2V0SW5zdGFuY2UoKS0+QWRkQWN0dWF0b3IoIlJlbGF5IiwgMSwgbV9jaGFubmVsLCB0aGlzKTsKK30KKworLyoqCisgKiBGcmVlIHRoZSByZXNvdXJjZSBhc3NvY2lhdGVkIHdpdGggYSByZWxheS4KKyAqIFRoZSByZWxheSBjaGFubmVscyBhcmUgc2V0IHRvIGZyZWUgYW5kIHRoZSByZWxheSBvdXRwdXQgaXMgdHVybmVkIG9mZi4KKyAqLworUmVsYXk6On5SZWxheSgpIHsKKyAgaW50MzJfdCBzdGF0dXMgPSAwOworICBzZXRSZWxheUZvcndhcmQobV9yZWxheV9wb3J0c1ttX2NoYW5uZWxdLCBmYWxzZSwgJnN0YXR1cyk7CisgIHNldFJlbGF5UmV2ZXJzZShtX3JlbGF5X3BvcnRzW21fY2hhbm5lbF0sIGZhbHNlLCAmc3RhdHVzKTsKKyAgd3BpX3NldEVycm9yV2l0aENvbnRleHQoc3RhdHVzLCBnZXRIQUxFcnJvck1lc3NhZ2Uoc3RhdHVzKSk7CisKKyAgaWYgKG1fZGlyZWN0aW9uID09IGtCb3RoRGlyZWN0aW9ucyB8fCBtX2RpcmVjdGlvbiA9PSBrRm9yd2FyZE9ubHkpIHsKKyAgICByZWxheUNoYW5uZWxzLT5GcmVlKG1fY2hhbm5lbCAqIDIpOworICB9CisgIGlmIChtX2RpcmVjdGlvbiA9PSBrQm90aERpcmVjdGlvbnMgfHwgbV9kaXJlY3Rpb24gPT0ga1JldmVyc2VPbmx5KSB7CisgICAgcmVsYXlDaGFubmVscy0+RnJlZShtX2NoYW5uZWwgKiAyICsgMSk7CisgIH0KKyAgaWYgKG1fdGFibGUgIT0gbnVsbHB0cikgbV90YWJsZS0+UmVtb3ZlVGFibGVMaXN0ZW5lcih0aGlzKTsKK30KKworLyoqCisgKiBTZXQgdGhlIHJlbGF5IHN0YXRlLgorICoKKyAqIFZhbGlkIHZhbHVlcyBkZXBlbmQgb24gd2hpY2ggZGlyZWN0aW9ucyBvZiB0aGUgcmVsYXkgYXJlIGNvbnRyb2xsZWQgYnkgdGhlCisgKiBvYmplY3QuCisgKgorICogV2hlbiBzZXQgdG8ga0JvdGhEaXJlY3Rpb25zLCB0aGUgcmVsYXkgY2FuIGJlIGFueSBvZiB0aGUgZm91ciBzdGF0ZXM6CisgKiAJIDB2LTB2LCAwdi0xMnYsIDEydi0wdiwgMTJ2LTEydgorICoKKyAqIFdoZW4gc2V0IHRvIGtGb3J3YXJkT25seSBvciBrUmV2ZXJzZU9ubHksIHlvdSBjYW4gc3BlY2lmeSB0aGUgY29uc3RhbnQgZm9yCisgKiB0aGUKKyAqIAkgZGlyZWN0aW9uIG9yIHlvdSBjYW4gc2ltcGx5IHNwZWNpZnkga09mZiBhbmQga09uLiAgVXNpbmcgb25seSBrT2ZmIGFuZAorICoga09uIGlzCisgKiAJIHJlY29tbWVuZGVkLgorICoKKyAqIEBwYXJhbSB2YWx1ZSBUaGUgc3RhdGUgdG8gc2V0IHRoZSByZWxheS4KKyAqLwordm9pZCBSZWxheTo6U2V0KFJlbGF5OjpWYWx1ZSB2YWx1ZSkgeworICBpZiAoU3RhdHVzSXNGYXRhbCgpKSByZXR1cm47CisKKyAgaW50MzJfdCBzdGF0dXMgPSAwOworCisgIHN3aXRjaCAodmFsdWUpIHsKKyAgICBjYXNlIGtPZmY6CisgICAgICBpZiAobV9kaXJlY3Rpb24gPT0ga0JvdGhEaXJlY3Rpb25zIHx8IG1fZGlyZWN0aW9uID09IGtGb3J3YXJkT25seSkgeworICAgICAgICBzZXRSZWxheUZvcndhcmQobV9yZWxheV9wb3J0c1ttX2NoYW5uZWxdLCBmYWxzZSwgJnN0YXR1cyk7CisgICAgICB9CisgICAgICBpZiAobV9kaXJlY3Rpb24gPT0ga0JvdGhEaXJlY3Rpb25zIHx8IG1fZGlyZWN0aW9uID09IGtSZXZlcnNlT25seSkgeworICAgICAgICBzZXRSZWxheVJldmVyc2UobV9yZWxheV9wb3J0c1ttX2NoYW5uZWxdLCBmYWxzZSwgJnN0YXR1cyk7CisgICAgICB9CisgICAgICBicmVhazsKKyAgICBjYXNlIGtPbjoKKyAgICAgIGlmIChtX2RpcmVjdGlvbiA9PSBrQm90aERpcmVjdGlvbnMgfHwgbV9kaXJlY3Rpb24gPT0ga0ZvcndhcmRPbmx5KSB7CisgICAgICAgIHNldFJlbGF5Rm9yd2FyZChtX3JlbGF5X3BvcnRzW21fY2hhbm5lbF0sIHRydWUsICZzdGF0dXMpOworICAgICAgfQorICAgICAgaWYgKG1fZGlyZWN0aW9uID09IGtCb3RoRGlyZWN0aW9ucyB8fCBtX2RpcmVjdGlvbiA9PSBrUmV2ZXJzZU9ubHkpIHsKKyAgICAgICAgc2V0UmVsYXlSZXZlcnNlKG1fcmVsYXlfcG9ydHNbbV9jaGFubmVsXSwgdHJ1ZSwgJnN0YXR1cyk7CisgICAgICB9CisgICAgICBicmVhazsKKyAgICBjYXNlIGtGb3J3YXJkOgorICAgICAgaWYgKG1fZGlyZWN0aW9uID09IGtSZXZlcnNlT25seSkgeworICAgICAgICB3cGlfc2V0V1BJRXJyb3IoSW5jb21wYXRpYmxlTW9kZSk7CisgICAgICAgIGJyZWFrOworICAgICAgfQorICAgICAgaWYgKG1fZGlyZWN0aW9uID09IGtCb3RoRGlyZWN0aW9ucyB8fCBtX2RpcmVjdGlvbiA9PSBrRm9yd2FyZE9ubHkpIHsKKyAgICAgICAgc2V0UmVsYXlGb3J3YXJkKG1fcmVsYXlfcG9ydHNbbV9jaGFubmVsXSwgdHJ1ZSwgJnN0YXR1cyk7CisgICAgICB9CisgICAgICBpZiAobV9kaXJlY3Rpb24gPT0ga0JvdGhEaXJlY3Rpb25zKSB7CisgICAgICAgIHNldFJlbGF5UmV2ZXJzZShtX3JlbGF5X3BvcnRzW21fY2hhbm5lbF0sIGZhbHNlLCAmc3RhdHVzKTsKKyAgICAgIH0KKyAgICAgIGJyZWFrOworICAgIGNhc2Uga1JldmVyc2U6CisgICAgICBpZiAobV9kaXJlY3Rpb24gPT0ga0ZvcndhcmRPbmx5KSB7CisgICAgICAgIHdwaV9zZXRXUElFcnJvcihJbmNvbXBhdGlibGVNb2RlKTsKKyAgICAgICAgYnJlYWs7CisgICAgICB9CisgICAgICBpZiAobV9kaXJlY3Rpb24gPT0ga0JvdGhEaXJlY3Rpb25zKSB7CisgICAgICAgIHNldFJlbGF5Rm9yd2FyZChtX3JlbGF5X3BvcnRzW21fY2hhbm5lbF0sIGZhbHNlLCAmc3RhdHVzKTsKKyAgICAgIH0KKyAgICAgIGlmIChtX2RpcmVjdGlvbiA9PSBrQm90aERpcmVjdGlvbnMgfHwgbV9kaXJlY3Rpb24gPT0ga1JldmVyc2VPbmx5KSB7CisgICAgICAgIHNldFJlbGF5UmV2ZXJzZShtX3JlbGF5X3BvcnRzW21fY2hhbm5lbF0sIHRydWUsICZzdGF0dXMpOworICAgICAgfQorICAgICAgYnJlYWs7CisgIH0KKworICB3cGlfc2V0RXJyb3JXaXRoQ29udGV4dChzdGF0dXMsIGdldEhBTEVycm9yTWVzc2FnZShzdGF0dXMpKTsKK30KKworLyoqCisgKiBHZXQgdGhlIFJlbGF5IFN0YXRlCisgKgorICogR2V0cyB0aGUgY3VycmVudCBzdGF0ZSBvZiB0aGUgcmVsYXkuCisgKgorICogV2hlbiBzZXQgdG8ga0ZvcndhcmRPbmx5IG9yIGtSZXZlcnNlT25seSwgdmFsdWUgaXMgcmV0dXJuZWQgYXMga09uL2tPZmYgbm90CisgKiBrRm9yd2FyZC9rUmV2ZXJzZSAocGVyIHRoZSByZWNvbW1lbmRhdGlvbiBpbiBTZXQpCisgKgorICogQHJldHVybiBUaGUgY3VycmVudCBzdGF0ZSBvZiB0aGUgcmVsYXkgYXMgYSBSZWxheTo6VmFsdWUKKyAqLworUmVsYXk6OlZhbHVlIFJlbGF5OjpHZXQoKSBjb25zdCB7CisgIGludDMyX3Qgc3RhdHVzOworCisgIGlmIChnZXRSZWxheUZvcndhcmQobV9yZWxheV9wb3J0c1ttX2NoYW5uZWxdLCAmc3RhdHVzKSkgeworICAgIGlmIChnZXRSZWxheVJldmVyc2UobV9yZWxheV9wb3J0c1ttX2NoYW5uZWxdLCAmc3RhdHVzKSkgeworICAgICAgcmV0dXJuIGtPbjsKKyAgICB9IGVsc2UgeworICAgICAgaWYgKG1fZGlyZWN0aW9uID09IGtGb3J3YXJkT25seSkgeworICAgICAgICByZXR1cm4ga09uOworICAgICAgfSBlbHNlIHsKKyAgICAgICAgcmV0dXJuIGtGb3J3YXJkOworICAgICAgfQorICAgIH0KKyAgfSBlbHNlIHsKKyAgICBpZiAoZ2V0UmVsYXlSZXZlcnNlKG1fcmVsYXlfcG9ydHNbbV9jaGFubmVsXSwgJnN0YXR1cykpIHsKKyAgICAgIGlmIChtX2RpcmVjdGlvbiA9PSBrUmV2ZXJzZU9ubHkpIHsKKyAgICAgICAgcmV0dXJuIGtPbjsKKyAgICAgIH0gZWxzZSB7CisgICAgICAgIHJldHVybiBrUmV2ZXJzZTsKKyAgICAgIH0KKyAgICB9IGVsc2UgeworICAgICAgcmV0dXJuIGtPZmY7CisgICAgfQorICB9CisKKyAgd3BpX3NldEVycm9yV2l0aENvbnRleHQoc3RhdHVzLCBnZXRIQUxFcnJvck1lc3NhZ2Uoc3RhdHVzKSk7Cit9CisKK3VpbnQzMl90IFJlbGF5OjpHZXRDaGFubmVsKCkgY29uc3QgeworICByZXR1cm4gbV9jaGFubmVsOworfQorCisvKioKKyAqIFNldCB0aGUgZXhwaXJhdGlvbiB0aW1lIGZvciB0aGUgUmVsYXkgb2JqZWN0CisgKiBAcGFyYW0gdGltZW91dCBUaGUgdGltZW91dCAoaW4gc2Vjb25kcykgZm9yIHRoaXMgcmVsYXkgb2JqZWN0CisgKi8KK3ZvaWQgUmVsYXk6OlNldEV4cGlyYXRpb24oZmxvYXQgdGltZW91dCkgeworICBtX3NhZmV0eUhlbHBlci0+U2V0RXhwaXJhdGlvbih0aW1lb3V0KTsKK30KKworLyoqCisgKiBSZXR1cm4gdGhlIGV4cGlyYXRpb24gdGltZSBmb3IgdGhlIHJlbGF5IG9iamVjdC4KKyAqIEByZXR1cm4gVGhlIGV4cGlyYXRpb24gdGltZSB2YWx1ZS4KKyAqLworZmxvYXQgUmVsYXk6OkdldEV4cGlyYXRpb24oKSBjb25zdCB7IHJldHVybiBtX3NhZmV0eUhlbHBlci0+R2V0RXhwaXJhdGlvbigpOyB9CisKKy8qKgorICogQ2hlY2sgaWYgdGhlIHJlbGF5IG9iamVjdCBpcyBjdXJyZW50bHkgYWxpdmUgb3Igc3RvcHBlZCBkdWUgdG8gYSB0aW1lb3V0LgorICogQHJldHVybnMgYSBib29sIHZhbHVlIHRoYXQgaXMgdHJ1ZSBpZiB0aGUgbW90b3IgaGFzIE5PVCB0aW1lZCBvdXQgYW5kIHNob3VsZAorICogc3RpbGwgYmUgcnVubmluZy4KKyAqLworYm9vbCBSZWxheTo6SXNBbGl2ZSgpIGNvbnN0IHsgcmV0dXJuIG1fc2FmZXR5SGVscGVyLT5Jc0FsaXZlKCk7IH0KKworLyoqCisgKiBTdG9wIHRoZSBtb3RvciBhc3NvY2lhdGVkIHdpdGggdGhpcyBQV00gb2JqZWN0LgorICogVGhpcyBpcyBjYWxsZWQgYnkgdGhlIE1vdG9yU2FmZXR5SGVscGVyIG9iamVjdCB3aGVuIGl0IGhhcyBhIHRpbWVvdXQgZm9yIHRoaXMKKyAqIHJlbGF5IGFuZCBuZWVkcyB0byBzdG9wIGl0IGZyb20gcnVubmluZy4KKyAqLwordm9pZCBSZWxheTo6U3RvcE1vdG9yKCkgeyBTZXQoa09mZik7IH0KKworLyoqCisgKiBFbmFibGUvZGlzYWJsZSBtb3RvciBzYWZldHkgZm9yIHRoaXMgZGV2aWNlCisgKiBUdXJuIG9uIGFuZCBvZmYgdGhlIG1vdG9yIHNhZmV0eSBvcHRpb24gZm9yIHRoaXMgcmVsYXkgb2JqZWN0LgorICogQHBhcmFtIGVuYWJsZWQgVHJ1ZSBpZiBtb3RvciBzYWZldHkgaXMgZW5mb3JjZWQgZm9yIHRoaXMgb2JqZWN0CisgKi8KK3ZvaWQgUmVsYXk6OlNldFNhZmV0eUVuYWJsZWQoYm9vbCBlbmFibGVkKSB7CisgIG1fc2FmZXR5SGVscGVyLT5TZXRTYWZldHlFbmFibGVkKGVuYWJsZWQpOworfQorCisvKioKKyAqIENoZWNrIGlmIG1vdG9yIHNhZmV0eSBpcyBlbmFibGVkIGZvciB0aGlzIG9iamVjdAorICogQHJldHVybnMgVHJ1ZSBpZiBtb3RvciBzYWZldHkgaXMgZW5mb3JjZWQgZm9yIHRoaXMgb2JqZWN0CisgKi8KK2Jvb2wgUmVsYXk6OklzU2FmZXR5RW5hYmxlZCgpIGNvbnN0IHsKKyAgcmV0dXJuIG1fc2FmZXR5SGVscGVyLT5Jc1NhZmV0eUVuYWJsZWQoKTsKK30KKwordm9pZCBSZWxheTo6R2V0RGVzY3JpcHRpb24oc3RkOjpvc3RyaW5nc3RyZWFtJiBkZXNjKSBjb25zdCB7CisgIGRlc2MgPDwgIlJlbGF5ICIgPDwgR2V0Q2hhbm5lbCgpOworfQorCit2b2lkIFJlbGF5OjpWYWx1ZUNoYW5nZWQoSVRhYmxlKiBzb3VyY2UsIGxsdm06OlN0cmluZ1JlZiBrZXksCisgICAgICAgICAgICAgICAgICAgICAgICAgc3RkOjpzaGFyZWRfcHRyPG50OjpWYWx1ZT4gdmFsdWUsIGJvb2wgaXNOZXcpIHsKKyAgaWYgKCF2YWx1ZS0+SXNTdHJpbmcoKSkgcmV0dXJuOworICBpZiAodmFsdWUtPkdldFN0cmluZygpID09ICJPZmYiKSBTZXQoa09mZik7CisgIGVsc2UgaWYgKHZhbHVlLT5HZXRTdHJpbmcoKSA9PSAiRm9yd2FyZCIpIFNldChrRm9yd2FyZCk7CisgIGVsc2UgaWYgKHZhbHVlLT5HZXRTdHJpbmcoKSA9PSAiUmV2ZXJzZSIpIFNldChrUmV2ZXJzZSk7CisgIGVsc2UgaWYgKHZhbHVlLT5HZXRTdHJpbmcoKSA9PSAiT24iKSBTZXQoa09uKTsKK30KKwordm9pZCBSZWxheTo6VXBkYXRlVGFibGUoKSB7CisgIGlmIChtX3RhYmxlICE9IG51bGxwdHIpIHsKKyAgICBpZiAoR2V0KCkgPT0ga09uKSB7CisgICAgICBtX3RhYmxlLT5QdXRTdHJpbmcoIlZhbHVlIiwgIk9uIik7CisgICAgfSBlbHNlIGlmIChHZXQoKSA9PSBrRm9yd2FyZCkgeworICAgICAgbV90YWJsZS0+UHV0U3RyaW5nKCJWYWx1ZSIsICJGb3J3YXJkIik7CisgICAgfSBlbHNlIGlmIChHZXQoKSA9PSBrUmV2ZXJzZSkgeworICAgICAgbV90YWJsZS0+UHV0U3RyaW5nKCJWYWx1ZSIsICJSZXZlcnNlIik7CisgICAgfSBlbHNlIHsKKyAgICAgIG1fdGFibGUtPlB1dFN0cmluZygiVmFsdWUiLCAiT2ZmIik7CisgICAgfQorICB9Cit9CisKK3ZvaWQgUmVsYXk6OlN0YXJ0TGl2ZVdpbmRvd01vZGUoKSB7CisgIGlmIChtX3RhYmxlICE9IG51bGxwdHIpIHsKKyAgICBtX3RhYmxlLT5BZGRUYWJsZUxpc3RlbmVyKCJWYWx1ZSIsIHRoaXMsIHRydWUpOworICB9Cit9CisKK3ZvaWQgUmVsYXk6OlN0b3BMaXZlV2luZG93TW9kZSgpIHsKKyAgaWYgKG1fdGFibGUgIT0gbnVsbHB0cikgeworICAgIG1fdGFibGUtPlJlbW92ZVRhYmxlTGlzdGVuZXIodGhpcyk7CisgIH0KK30KKworc3RkOjpzdHJpbmcgUmVsYXk6OkdldFNtYXJ0RGFzaGJvYXJkVHlwZSgpIGNvbnN0IHsgcmV0dXJuICJSZWxheSI7IH0KKwordm9pZCBSZWxheTo6SW5pdFRhYmxlKHN0ZDo6c2hhcmVkX3B0cjxJVGFibGU+IHN1YlRhYmxlKSB7CisgIG1fdGFibGUgPSBzdWJUYWJsZTsKKyAgVXBkYXRlVGFibGUoKTsKK30KKworc3RkOjpzaGFyZWRfcHRyPElUYWJsZT4gUmVsYXk6OkdldFRhYmxlKCkgY29uc3QgeyByZXR1cm4gbV90YWJsZTsgfQpkaWZmIC0tZ2l0IGEvd3BpbGliYy9BdGhlbmEvc3JjL1JvYm90QmFzZS5jcHAgYi93cGlsaWJjL0F0aGVuYS9zcmMvUm9ib3RCYXNlLmNwcApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4yYmQxZDEzCi0tLSAvZGV2L251bGwKKysrIGIvd3BpbGliYy9BdGhlbmEvc3JjL1JvYm90QmFzZS5jcHAKQEAgLTAsMCArMSwxMjkgQEAKKy8qLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovCisvKiBDb3B5cmlnaHQgKGMpIEZJUlNUIDIwMDguIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCisgKi8KKy8qIE9wZW4gU291cmNlIFNvZnR3YXJlIC0gbWF5IGJlIG1vZGlmaWVkIGFuZCBzaGFyZWQgYnkgRlJDIHRlYW1zLiBUaGUgY29kZSAgICovCisvKiBtdXN0IGJlIGFjY29tcGFuaWVkIGJ5IHRoZSBGSVJTVCBCU0QgbGljZW5zZSBmaWxlIGluICQoV0lORF9CQVNFKS9XUElMaWIuICAqLworLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi8KKworI2luY2x1ZGUgIlJvYm90QmFzZS5oIgorCisjaW5jbHVkZSAiRHJpdmVyU3RhdGlvbi5oIgorI2luY2x1ZGUgIlJvYm90U3RhdGUuaCIKKyNpbmNsdWRlICJITFVzYWdlUmVwb3J0aW5nLmgiCisjaW5jbHVkZSAiSW50ZXJuYWwvSGFyZHdhcmVITFJlcG9ydGluZy5oIgorI2luY2x1ZGUgIlV0aWxpdHkuaCIKKyNpbmNsdWRlICJuZXR3b3JrdGFibGVzL05ldHdvcmtUYWJsZS5oIgorI2luY2x1ZGUgPGNzdHJpbmc+CisjaW5jbHVkZSAiSEFML0hBTC5ocHAiCisjaW5jbHVkZSA8Y3N0ZGlvPgorCitSb2JvdEJhc2UgKlJvYm90QmFzZTo6bV9pbnN0YW5jZSA9IG51bGxwdHI7CisKK3ZvaWQgUm9ib3RCYXNlOjpzZXRJbnN0YW5jZShSb2JvdEJhc2UgKnJvYm90KSB7CisgIHdwaV9hc3NlcnQobV9pbnN0YW5jZSA9PSBudWxscHRyKTsKKyAgbV9pbnN0YW5jZSA9IHJvYm90OworfQorCitSb2JvdEJhc2UgJlJvYm90QmFzZTo6Z2V0SW5zdGFuY2UoKSB7IHJldHVybiAqbV9pbnN0YW5jZTsgfQorCit2b2lkIFJvYm90QmFzZTo6cm9ib3RTZXR1cChSb2JvdEJhc2UgKnJvYm90KSB7CisgIHJvYm90LT5TdGFydENvbXBldGl0aW9uKCk7Cit9CisKKy8qKgorICogQ29uc3RydWN0b3IgZm9yIGEgZ2VuZXJpYyByb2JvdCBwcm9ncmFtLgorICogVXNlciBjb2RlIHNob3VsZCBiZSBwbGFjZWQgaW4gdGhlIGNvbnN0cnVjdG9yIHRoYXQgcnVucyBiZWZvcmUgdGhlIEF1dG9ub21vdXMKKyAqIG9yIE9wZXJhdG9yCisgKiBDb250cm9sIHBlcmlvZCBzdGFydHMuIFRoZSBjb25zdHJ1Y3RvciB3aWxsIHJ1biB0byBjb21wbGV0aW9uIGJlZm9yZQorICogQXV0b25vbW91cyBpcyBlbnRlcmVkLgorICoKKyAqIFRoaXMgbXVzdCBiZSB1c2VkIHRvIGVuc3VyZSB0aGF0IHRoZSBjb21tdW5pY2F0aW9ucyBjb2RlIHN0YXJ0cy4gSW4gdGhlCisgKiBmdXR1cmUgaXQgd291bGQgYmUKKyAqIG5pY2UgdG8gcHV0IHRoaXMgY29kZSBpbnRvIGl0J3Mgb3duIHRhc2sgdGhhdCBsb2FkcyBvbiBib290IHNvIGVuc3VyZSB0aGF0IGl0CisgKiBydW5zLgorICovCitSb2JvdEJhc2U6OlJvYm90QmFzZSgpIDogbV9kcyhEcml2ZXJTdGF0aW9uOjpHZXRJbnN0YW5jZSgpKSB7CisgIFJvYm90U3RhdGU6OlNldEltcGxlbWVudGF0aW9uKERyaXZlclN0YXRpb246OkdldEluc3RhbmNlKCkpOworICBITFVzYWdlUmVwb3J0aW5nOjpTZXRJbXBsZW1lbnRhdGlvbihuZXcgSGFyZHdhcmVITFJlcG9ydGluZygpKTsKKworICBSb2JvdEJhc2U6OnNldEluc3RhbmNlKHRoaXMpOworCisgIE5ldHdvcmtUYWJsZTo6U2V0TmV0d29ya0lkZW50aXR5KCJSb2JvdCIpOworCisgIEZJTEUgKmZpbGUgPSBudWxscHRyOworICBmaWxlID0gZm9wZW4oIi90bXAvZnJjX3ZlcnNpb25zL0ZSQ19MaWJfVmVyc2lvbi5pbmkiLCAidyIpOworCisgIGlmIChmaWxlICE9IG51bGxwdHIpIHsKKyAgICBmcHV0cygiMjAxNiBDKysgQmV0YTUuMCIsIGZpbGUpOworICAgIGZjbG9zZShmaWxlKTsKKyAgfQorfQorCisvKioKKyAqIEZyZWUgdGhlIHJlc291cmNlcyBmb3IgYSBSb2JvdEJhc2UgY2xhc3MuCisgKiBUaGlzIGluY2x1ZGVzIGRlbGV0aW5nIGFsbCBjbGFzc2VzIHRoYXQgbWlnaHQgaGF2ZSBiZWVuIGFsbG9jYXRlZCBhcworICogU2luZ2xldG9ucyB0byB0aGV5CisgKiB3b3VsZCBuZXZlciBiZSBkZWxldGVkIGV4Y2VwdCBoZXJlLgorICovCitSb2JvdEJhc2U6On5Sb2JvdEJhc2UoKSB7CisgIFNlbnNvckJhc2U6OkRlbGV0ZVNpbmdsZXRvbnMoKTsKKyAgZGVsZXRlIG1fdGFzazsKKyAgbV90YXNrID0gbnVsbHB0cjsKKyAgbV9pbnN0YW5jZSA9IG51bGxwdHI7Cit9CisKKy8qKgorICogRGV0ZXJtaW5lIGlmIHRoZSBSb2JvdCBpcyBjdXJyZW50bHkgZW5hYmxlZC4KKyAqIEByZXR1cm4gVHJ1ZSBpZiB0aGUgUm9ib3QgaXMgY3VycmVudGx5IGVuYWJsZWQgYnkgdGhlIGZpZWxkIGNvbnRyb2xzLgorICovCitib29sIFJvYm90QmFzZTo6SXNFbmFibGVkKCkgY29uc3QgeyByZXR1cm4gbV9kcy5Jc0VuYWJsZWQoKTsgfQorCisvKioKKyAqIERldGVybWluZSBpZiB0aGUgUm9ib3QgaXMgY3VycmVudGx5IGRpc2FibGVkLgorICogQHJldHVybiBUcnVlIGlmIHRoZSBSb2JvdCBpcyBjdXJyZW50bHkgZGlzYWJsZWQgYnkgdGhlIGZpZWxkIGNvbnRyb2xzLgorICovCitib29sIFJvYm90QmFzZTo6SXNEaXNhYmxlZCgpIGNvbnN0IHsgcmV0dXJuIG1fZHMuSXNEaXNhYmxlZCgpOyB9CisKKy8qKgorICogRGV0ZXJtaW5lIGlmIHRoZSByb2JvdCBpcyBjdXJyZW50bHkgaW4gQXV0b25vbW91cyBtb2RlLgorICogQHJldHVybiBUcnVlIGlmIHRoZSByb2JvdCBpcyBjdXJyZW50bHkgb3BlcmF0aW5nIEF1dG9ub21vdXNseSBhcyBkZXRlcm1pbmVkCisgKiBieSB0aGUgZmllbGQgY29udHJvbHMuCisgKi8KK2Jvb2wgUm9ib3RCYXNlOjpJc0F1dG9ub21vdXMoKSBjb25zdCB7IHJldHVybiBtX2RzLklzQXV0b25vbW91cygpOyB9CisKKy8qKgorICogRGV0ZXJtaW5lIGlmIHRoZSByb2JvdCBpcyBjdXJyZW50bHkgaW4gT3BlcmF0b3IgQ29udHJvbCBtb2RlLgorICogQHJldHVybiBUcnVlIGlmIHRoZSByb2JvdCBpcyBjdXJyZW50bHkgb3BlcmF0aW5nIGluIFRlbGUtT3AgbW9kZSBhcworICogZGV0ZXJtaW5lZCBieSB0aGUgZmllbGQgY29udHJvbHMuCisgKi8KK2Jvb2wgUm9ib3RCYXNlOjpJc09wZXJhdG9yQ29udHJvbCgpIGNvbnN0IHsgcmV0dXJuIG1fZHMuSXNPcGVyYXRvckNvbnRyb2woKTsgfQorCisvKioKKyAqIERldGVybWluZSBpZiB0aGUgcm9ib3QgaXMgY3VycmVudGx5IGluIFRlc3QgbW9kZS4KKyAqIEByZXR1cm4gVHJ1ZSBpZiB0aGUgcm9ib3QgaXMgY3VycmVudGx5IHJ1bm5pbmcgdGVzdHMgYXMgZGV0ZXJtaW5lZCBieSB0aGUKKyAqIGZpZWxkIGNvbnRyb2xzLgorICovCitib29sIFJvYm90QmFzZTo6SXNUZXN0KCkgY29uc3QgeyByZXR1cm4gbV9kcy5Jc1Rlc3QoKTsgfQorCisvKioKKyAqIEluZGljYXRlcyBpZiBuZXcgZGF0YSBpcyBhdmFpbGFibGUgZnJvbSB0aGUgZHJpdmVyIHN0YXRpb24uCisgKiBAcmV0dXJuIEhhcyBuZXcgZGF0YSBhcnJpdmVkIG92ZXIgdGhlIG5ldHdvcmsgc2luY2UgdGhlIGxhc3QgdGltZSB0aGlzCisgKiBmdW5jdGlvbiB3YXMgY2FsbGVkPworICovCitib29sIFJvYm90QmFzZTo6SXNOZXdEYXRhQXZhaWxhYmxlKCkgY29uc3QgeyByZXR1cm4gbV9kcy5Jc05ld0NvbnRyb2xEYXRhKCk7IH0KKworLyoqCisgKiBUaGlzIGNsYXNzIGV4aXN0cyBmb3IgdGhlIHNvbGUgcHVycG9zZSBvZiBnZXR0aW5nIGl0cyBkZXN0cnVjdG9yIGNhbGxlZCB3aGVuCisgKiB0aGUgbW9kdWxlIHVubG9hZHMuCisgKiBCZWZvcmUgdGhlIG1vZHVsZSBpcyBkb25lIHVubG9hZGluZywgd2UgbmVlZCB0byBkZWxldGUgdGhlIFJvYm90QmFzZSBkZXJpdmVkCisgKiBzaW5nbGV0b24uICBUaGlzIHNob3VsZCBkZWxldGUKKyAqIHRoZSBvdGhlciByZW1haW5pbmcgc2luZ2xldG9ucyB0aGF0IHdlcmUgcmVnaXN0ZXJlZC4gIFRoaXMgc2hvdWxkIGFsc28gc3RvcAorICogYWxsIHRhc2tzIHRoYXQgYXJlIHVzaW5nCisgKiB0aGUgVGFzayBjbGFzcy4KKyAqLworY2xhc3MgUm9ib3REZWxldGVyIHsKKyBwdWJsaWM6CisgIFJvYm90RGVsZXRlcigpIHt9CisgIH5Sb2JvdERlbGV0ZXIoKSB7IGRlbGV0ZSAmUm9ib3RCYXNlOjpnZXRJbnN0YW5jZSgpOyB9Cit9Oworc3RhdGljIFJvYm90RGVsZXRlciBnX3JvYm90RGVsZXRlcjsKZGlmZiAtLWdpdCBhL3dwaWxpYmMvQXRoZW5hL3NyYy9Sb2JvdERyaXZlLmNwcCBiL3dwaWxpYmMvQXRoZW5hL3NyYy9Sb2JvdERyaXZlLmNwcApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5jMTM1M2U5Ci0tLSAvZGV2L251bGwKKysrIGIvd3BpbGliYy9BdGhlbmEvc3JjL1JvYm90RHJpdmUuY3BwCkBAIC0wLDAgKzEsNzUzIEBACisvKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qLworLyogQ29weXJpZ2h0IChjKSBGSVJTVCAyMDA4LiBBbGwgUmlnaHRzIFJlc2VydmVkLgorICovCisvKiBPcGVuIFNvdXJjZSBTb2Z0d2FyZSAtIG1heSBiZSBtb2RpZmllZCBhbmQgc2hhcmVkIGJ5IEZSQyB0ZWFtcy4gVGhlIGNvZGUgICAqLworLyogbXVzdCBiZSBhY2NvbXBhbmllZCBieSB0aGUgRklSU1QgQlNEIGxpY2Vuc2UgZmlsZSBpbiAkKFdJTkRfQkFTRSkvV1BJTGliLiAgKi8KKy8qLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovCisKKyNpbmNsdWRlICJSb2JvdERyaXZlLmgiCisKKyNpbmNsdWRlICJDQU5KYWd1YXIuaCIKKyNpbmNsdWRlICJHZW5lcmljSElELmgiCisjaW5jbHVkZSAiSm95c3RpY2suaCIKKyNpbmNsdWRlICJUYWxvbi5oIgorI2luY2x1ZGUgIlV0aWxpdHkuaCIKKyNpbmNsdWRlICJXUElFcnJvcnMuaCIKKyNpbmNsdWRlIDxtYXRoLmg+CisKKyN1bmRlZiBtYXgKKyNpbmNsdWRlIDxhbGdvcml0aG0+CisKK2NvbnN0IGludDMyX3QgUm9ib3REcml2ZTo6a01heE51bWJlck9mTW90b3JzOworCitzdGF0aWMgYXV0byBtYWtlX3NoYXJlZF9ub2RlbGV0ZShTcGVlZENvbnRyb2xsZXIgKnB0cikgeworICByZXR1cm4gc3RkOjpzaGFyZWRfcHRyPFNwZWVkQ29udHJvbGxlcj4ocHRyLCBOdWxsRGVsZXRlcjxTcGVlZENvbnRyb2xsZXI+KCkpOworfQorCisvKgorICogRHJpdmluZyBmdW5jdGlvbnMKKyAqIFRoZXNlIGZ1bmN0aW9ucyBwcm92aWRlIGFuIGludGVyZmFjZSB0byBtdWx0aXBsZSBtb3RvcnMgdGhhdCBpcyB1c2VkIGZvciBDCisgKiBwcm9ncmFtbWluZworICogVGhlIERyaXZlKHNwZWVkLCBkaXJlY3Rpb24pIGZ1bmN0aW9uIGlzIHRoZSBtYWluIHBhcnQgb2YgdGhlIHNldCB0aGF0IG1ha2VzCisgKiBpdCBlYXN5CisgKiB0byBzZXQgc3BlZWRzIGFuZCBkaXJlY3Rpb24gaW5kZXBlbmRlbnRseSBpbiBvbmUgY2FsbC4KKyAqLworCisvKioKKyAqIENvbW1vbiBmdW5jdGlvbiB0byBpbml0aWFsaXplIGFsbCB0aGUgcm9ib3QgZHJpdmUgY29uc3RydWN0b3JzLgorICogQ3JlYXRlIGEgbW90b3Igc2FmZXR5IG9iamVjdCAodGhlIHJlYWwgcmVhc29uIGZvciB0aGUgY29tbW9uIGNvZGUpIGFuZAorICogaW5pdGlhbGl6ZSBhbGwgdGhlIG1vdG9yIGFzc2lnbm1lbnRzLiBUaGUgZGVmYXVsdCB0aW1lb3V0IGlzIHNldCBmb3IgdGhlCisgKiByb2JvdCBkcml2ZS4KKyAqLwordm9pZCBSb2JvdERyaXZlOjpJbml0Um9ib3REcml2ZSgpIHsKKyAgbV9zYWZldHlIZWxwZXIgPSBzdGQ6Om1ha2VfdW5pcXVlPE1vdG9yU2FmZXR5SGVscGVyPih0aGlzKTsKKyAgbV9zYWZldHlIZWxwZXItPlNldFNhZmV0eUVuYWJsZWQodHJ1ZSk7Cit9CisKKy8qKgorICogQ29uc3RydWN0b3IgZm9yIFJvYm90RHJpdmUgd2l0aCAyIG1vdG9ycyBzcGVjaWZpZWQgd2l0aCBjaGFubmVsIG51bWJlcnMuCisgKiBTZXQgdXAgcGFyYW1ldGVycyBmb3IgYSB0d28gd2hlZWwgZHJpdmUgc3lzdGVtIHdoZXJlIHRoZQorICogbGVmdCBhbmQgcmlnaHQgbW90b3IgcHdtIGNoYW5uZWxzIGFyZSBzcGVjaWZpZWQgaW4gdGhlIGNhbGwuCisgKiBUaGlzIGNhbGwgYXNzdW1lcyBUYWxvbnMgZm9yIGNvbnRyb2xsaW5nIHRoZSBtb3RvcnMuCisgKiBAcGFyYW0gbGVmdE1vdG9yQ2hhbm5lbCBUaGUgUFdNIGNoYW5uZWwgbnVtYmVyIHRoYXQgZHJpdmVzIHRoZSBsZWZ0IG1vdG9yLgorICogMC05IGFyZSBvbi1ib2FyZCwgMTAtMTkgYXJlIG9uIHRoZSBNWFAgcG9ydAorICogQHBhcmFtIHJpZ2h0TW90b3JDaGFubmVsIFRoZSBQV00gY2hhbm5lbCBudW1iZXIgdGhhdCBkcml2ZXMgdGhlIHJpZ2h0IG1vdG9yLgorICogMC05IGFyZSBvbi1ib2FyZCwgMTAtMTkgYXJlIG9uIHRoZSBNWFAgcG9ydAorICovCitSb2JvdERyaXZlOjpSb2JvdERyaXZlKHVpbnQzMl90IGxlZnRNb3RvckNoYW5uZWwsIHVpbnQzMl90IHJpZ2h0TW90b3JDaGFubmVsKSB7CisgIEluaXRSb2JvdERyaXZlKCk7CisgIG1fcmVhckxlZnRNb3RvciA9IHN0ZDo6bWFrZV9zaGFyZWQ8VGFsb24+KGxlZnRNb3RvckNoYW5uZWwpOworICBtX3JlYXJSaWdodE1vdG9yID0gc3RkOjptYWtlX3NoYXJlZDxUYWxvbj4ocmlnaHRNb3RvckNoYW5uZWwpOworICBTZXRMZWZ0UmlnaHRNb3Rvck91dHB1dHMoMC4wLCAwLjApOworfQorCisvKioKKyAqIENvbnN0cnVjdG9yIGZvciBSb2JvdERyaXZlIHdpdGggNCBtb3RvcnMgc3BlY2lmaWVkIHdpdGggY2hhbm5lbCBudW1iZXJzLgorICogU2V0IHVwIHBhcmFtZXRlcnMgZm9yIGEgZm91ciB3aGVlbCBkcml2ZSBzeXN0ZW0gd2hlcmUgYWxsIGZvdXIgbW90b3IKKyAqIHB3bSBjaGFubmVscyBhcmUgc3BlY2lmaWVkIGluIHRoZSBjYWxsLgorICogVGhpcyBjYWxsIGFzc3VtZXMgVGFsb25zIGZvciBjb250cm9sbGluZyB0aGUgbW90b3JzLgorICogQHBhcmFtIGZyb250TGVmdE1vdG9yIEZyb250IGxlZnQgbW90b3IgY2hhbm5lbCBudW1iZXIuIDAtOSBhcmUgb24tYm9hcmQsCisgKiAxMC0xOSBhcmUgb24gdGhlIE1YUCBwb3J0CisgKiBAcGFyYW0gcmVhckxlZnRNb3RvciBSZWFyIExlZnQgbW90b3IgY2hhbm5lbCBudW1iZXIuIDAtOSBhcmUgb24tYm9hcmQsIDEwLTE5CisgKiBhcmUgb24gdGhlIE1YUCBwb3J0CisgKiBAcGFyYW0gZnJvbnRSaWdodE1vdG9yIEZyb250IHJpZ2h0IG1vdG9yIGNoYW5uZWwgbnVtYmVyLiAwLTkgYXJlIG9uLWJvYXJkLAorICogMTAtMTkgYXJlIG9uIHRoZSBNWFAgcG9ydAorICogQHBhcmFtIHJlYXJSaWdodE1vdG9yIFJlYXIgUmlnaHQgbW90b3IgY2hhbm5lbCBudW1iZXIuIDAtOSBhcmUgb24tYm9hcmQsCisgKiAxMC0xOSBhcmUgb24gdGhlIE1YUCBwb3J0CisgKi8KK1JvYm90RHJpdmU6OlJvYm90RHJpdmUodWludDMyX3QgZnJvbnRMZWZ0TW90b3IsIHVpbnQzMl90IHJlYXJMZWZ0TW90b3IsCisgICAgICAgICAgICAgICAgICAgICAgIHVpbnQzMl90IGZyb250UmlnaHRNb3RvciwgdWludDMyX3QgcmVhclJpZ2h0TW90b3IpIHsKKyAgSW5pdFJvYm90RHJpdmUoKTsKKyAgbV9yZWFyTGVmdE1vdG9yID0gc3RkOjptYWtlX3NoYXJlZDxUYWxvbj4ocmVhckxlZnRNb3Rvcik7CisgIG1fcmVhclJpZ2h0TW90b3IgPSBzdGQ6Om1ha2Vfc2hhcmVkPFRhbG9uPihyZWFyUmlnaHRNb3Rvcik7CisgIG1fZnJvbnRMZWZ0TW90b3IgPSBzdGQ6Om1ha2Vfc2hhcmVkPFRhbG9uPihmcm9udExlZnRNb3Rvcik7CisgIG1fZnJvbnRSaWdodE1vdG9yID0gc3RkOjptYWtlX3NoYXJlZDxUYWxvbj4oZnJvbnRSaWdodE1vdG9yKTsKKyAgU2V0TGVmdFJpZ2h0TW90b3JPdXRwdXRzKDAuMCwgMC4wKTsKK30KKworLyoqCisgKiBDb25zdHJ1Y3RvciBmb3IgUm9ib3REcml2ZSB3aXRoIDIgbW90b3JzIHNwZWNpZmllZCBhcyBTcGVlZENvbnRyb2xsZXIKKyAqIG9iamVjdHMuCisgKiBUaGUgU3BlZWRDb250cm9sbGVyIHZlcnNpb24gb2YgdGhlIGNvbnN0cnVjdG9yIGVuYWJsZXMgcHJvZ3JhbXMgdG8gdXNlIHRoZQorICogUm9ib3REcml2ZSBjbGFzc2VzIHdpdGgKKyAqIHN1YmNsYXNzZXMgb2YgdGhlIFNwZWVkQ29udHJvbGxlciBvYmplY3RzLCBmb3IgZXhhbXBsZSwgdmVyc2lvbnMgd2l0aCByYW1waW5nCisgKiBvciByZXNoYXBpbmcgb2YKKyAqIHRoZSBjdXJ2ZSB0byBzdWl0IG1vdG9yIGJpYXMgb3IgZGVhZGJhbmQgZWxpbWluYXRpb24uCisgKiBAcGFyYW0gbGVmdE1vdG9yIFRoZSBsZWZ0IFNwZWVkQ29udHJvbGxlciBvYmplY3QgdXNlZCB0byBkcml2ZSB0aGUgcm9ib3QuCisgKiBAcGFyYW0gcmlnaHRNb3RvciB0aGUgcmlnaHQgU3BlZWRDb250cm9sbGVyIG9iamVjdCB1c2VkIHRvIGRyaXZlIHRoZSByb2JvdC4KKyAqLworUm9ib3REcml2ZTo6Um9ib3REcml2ZShTcGVlZENvbnRyb2xsZXIgKmxlZnRNb3RvciwKKyAgICAgICAgICAgICAgICAgICAgICAgU3BlZWRDb250cm9sbGVyICpyaWdodE1vdG9yKSB7CisgIEluaXRSb2JvdERyaXZlKCk7CisgIGlmIChsZWZ0TW90b3IgPT0gbnVsbHB0ciB8fCByaWdodE1vdG9yID09IG51bGxwdHIpIHsKKyAgICB3cGlfc2V0V1BJRXJyb3IoTnVsbFBhcmFtZXRlcik7CisgICAgbV9yZWFyTGVmdE1vdG9yID0gbV9yZWFyUmlnaHRNb3RvciA9IG51bGxwdHI7CisgICAgcmV0dXJuOworICB9CisgIG1fcmVhckxlZnRNb3RvciA9IG1ha2Vfc2hhcmVkX25vZGVsZXRlKGxlZnRNb3Rvcik7CisgIG1fcmVhclJpZ2h0TW90b3IgPSBtYWtlX3NoYXJlZF9ub2RlbGV0ZShyaWdodE1vdG9yKTsKK30KKworLy9UT0RPOiBDaGFuZ2UgdG8gcnZhbHVlIHJlZmVyZW5jZXMgJiBtb3ZlIHN5bnRheC4KK1JvYm90RHJpdmU6OlJvYm90RHJpdmUoU3BlZWRDb250cm9sbGVyICZsZWZ0TW90b3IsCisgICAgICAgICAgICAgICAgICAgICAgIFNwZWVkQ29udHJvbGxlciAmcmlnaHRNb3RvcikgeworICBJbml0Um9ib3REcml2ZSgpOworICBtX3JlYXJMZWZ0TW90b3IgPSBtYWtlX3NoYXJlZF9ub2RlbGV0ZSgmbGVmdE1vdG9yKTsKKyAgbV9yZWFyUmlnaHRNb3RvciA9IG1ha2Vfc2hhcmVkX25vZGVsZXRlKCZyaWdodE1vdG9yKTsKK30KKworUm9ib3REcml2ZTo6Um9ib3REcml2ZShzdGQ6OnNoYXJlZF9wdHI8U3BlZWRDb250cm9sbGVyPiBsZWZ0TW90b3IsCisgICAgICAgICAgICAgICAgICAgICAgIHN0ZDo6c2hhcmVkX3B0cjxTcGVlZENvbnRyb2xsZXI+IHJpZ2h0TW90b3IpIHsKKyAgSW5pdFJvYm90RHJpdmUoKTsKKyAgaWYgKGxlZnRNb3RvciA9PSBudWxscHRyIHx8IHJpZ2h0TW90b3IgPT0gbnVsbHB0cikgeworICAgIHdwaV9zZXRXUElFcnJvcihOdWxsUGFyYW1ldGVyKTsKKyAgICBtX3JlYXJMZWZ0TW90b3IgPSBtX3JlYXJSaWdodE1vdG9yID0gbnVsbHB0cjsKKyAgICByZXR1cm47CisgIH0KKyAgbV9yZWFyTGVmdE1vdG9yID0gbGVmdE1vdG9yOworICBtX3JlYXJSaWdodE1vdG9yID0gcmlnaHRNb3RvcjsKK30KKworLyoqCisgKiBDb25zdHJ1Y3RvciBmb3IgUm9ib3REcml2ZSB3aXRoIDQgbW90b3JzIHNwZWNpZmllZCBhcyBTcGVlZENvbnRyb2xsZXIKKyAqIG9iamVjdHMuCisgKiBTcGVlZCBjb250cm9sbGVyIGlucHV0IHZlcnNpb24gb2YgUm9ib3REcml2ZSAoc2VlIHByZXZpb3VzIGNvbW1lbnRzKS4KKyAqIEBwYXJhbSByZWFyTGVmdE1vdG9yIFRoZSBiYWNrIGxlZnQgU3BlZWRDb250cm9sbGVyIG9iamVjdCB1c2VkIHRvIGRyaXZlIHRoZQorICogcm9ib3QuCisgKiBAcGFyYW0gZnJvbnRMZWZ0TW90b3IgVGhlIGZyb250IGxlZnQgU3BlZWRDb250cm9sbGVyIG9iamVjdCB1c2VkIHRvIGRyaXZlIHRoZQorICogcm9ib3QKKyAqIEBwYXJhbSByZWFyUmlnaHRNb3RvciBUaGUgYmFjayByaWdodCBTcGVlZENvbnRyb2xsZXIgb2JqZWN0IHVzZWQgdG8gZHJpdmUgdGhlCisgKiByb2JvdC4KKyAqIEBwYXJhbSBmcm9udFJpZ2h0TW90b3IgVGhlIGZyb250IHJpZ2h0IFNwZWVkQ29udHJvbGxlciBvYmplY3QgdXNlZCB0byBkcml2ZQorICogdGhlIHJvYm90LgorICovCitSb2JvdERyaXZlOjpSb2JvdERyaXZlKFNwZWVkQ29udHJvbGxlciAqZnJvbnRMZWZ0TW90b3IsCisgICAgICAgICAgICAgICAgICAgICAgIFNwZWVkQ29udHJvbGxlciAqcmVhckxlZnRNb3RvciwKKyAgICAgICAgICAgICAgICAgICAgICAgU3BlZWRDb250cm9sbGVyICpmcm9udFJpZ2h0TW90b3IsCisgICAgICAgICAgICAgICAgICAgICAgIFNwZWVkQ29udHJvbGxlciAqcmVhclJpZ2h0TW90b3IpIHsKKyAgSW5pdFJvYm90RHJpdmUoKTsKKyAgaWYgKGZyb250TGVmdE1vdG9yID09IG51bGxwdHIgfHwgcmVhckxlZnRNb3RvciA9PSBudWxscHRyIHx8CisgICAgICBmcm9udFJpZ2h0TW90b3IgPT0gbnVsbHB0ciB8fCByZWFyUmlnaHRNb3RvciA9PSBudWxscHRyKSB7CisgICAgd3BpX3NldFdQSUVycm9yKE51bGxQYXJhbWV0ZXIpOworICAgIHJldHVybjsKKyAgfQorICBtX2Zyb250TGVmdE1vdG9yID0gbWFrZV9zaGFyZWRfbm9kZWxldGUoZnJvbnRMZWZ0TW90b3IpOworICBtX3JlYXJMZWZ0TW90b3IgPSBtYWtlX3NoYXJlZF9ub2RlbGV0ZShyZWFyTGVmdE1vdG9yKTsKKyAgbV9mcm9udFJpZ2h0TW90b3IgPSBtYWtlX3NoYXJlZF9ub2RlbGV0ZShmcm9udFJpZ2h0TW90b3IpOworICBtX3JlYXJSaWdodE1vdG9yID0gbWFrZV9zaGFyZWRfbm9kZWxldGUocmVhclJpZ2h0TW90b3IpOworfQorCitSb2JvdERyaXZlOjpSb2JvdERyaXZlKFNwZWVkQ29udHJvbGxlciAmZnJvbnRMZWZ0TW90b3IsCisgICAgICAgICAgICAgICAgICAgICAgIFNwZWVkQ29udHJvbGxlciAmcmVhckxlZnRNb3RvciwKKyAgICAgICAgICAgICAgICAgICAgICAgU3BlZWRDb250cm9sbGVyICZmcm9udFJpZ2h0TW90b3IsCisgICAgICAgICAgICAgICAgICAgICAgIFNwZWVkQ29udHJvbGxlciAmcmVhclJpZ2h0TW90b3IpIHsKKyAgSW5pdFJvYm90RHJpdmUoKTsKKyAgbV9mcm9udExlZnRNb3RvciA9IG1ha2Vfc2hhcmVkX25vZGVsZXRlKCZmcm9udExlZnRNb3Rvcik7CisgIG1fcmVhckxlZnRNb3RvciA9IG1ha2Vfc2hhcmVkX25vZGVsZXRlKCZyZWFyTGVmdE1vdG9yKTsKKyAgbV9mcm9udFJpZ2h0TW90b3IgPSBtYWtlX3NoYXJlZF9ub2RlbGV0ZSgmZnJvbnRSaWdodE1vdG9yKTsKKyAgbV9yZWFyUmlnaHRNb3RvciA9IG1ha2Vfc2hhcmVkX25vZGVsZXRlKCZyZWFyUmlnaHRNb3Rvcik7Cit9CisKK1JvYm90RHJpdmU6OlJvYm90RHJpdmUoc3RkOjpzaGFyZWRfcHRyPFNwZWVkQ29udHJvbGxlcj4gZnJvbnRMZWZ0TW90b3IsCisgICAgICAgICAgICAgICAgICAgICAgIHN0ZDo6c2hhcmVkX3B0cjxTcGVlZENvbnRyb2xsZXI+IHJlYXJMZWZ0TW90b3IsCisgICAgICAgICAgICAgICAgICAgICAgIHN0ZDo6c2hhcmVkX3B0cjxTcGVlZENvbnRyb2xsZXI+IGZyb250UmlnaHRNb3RvciwKKyAgICAgICAgICAgICAgICAgICAgICAgc3RkOjpzaGFyZWRfcHRyPFNwZWVkQ29udHJvbGxlcj4gcmVhclJpZ2h0TW90b3IpIHsKKyAgSW5pdFJvYm90RHJpdmUoKTsKKyAgaWYgKGZyb250TGVmdE1vdG9yID09IG51bGxwdHIgfHwgcmVhckxlZnRNb3RvciA9PSBudWxscHRyIHx8CisgICAgICBmcm9udFJpZ2h0TW90b3IgPT0gbnVsbHB0ciB8fCByZWFyUmlnaHRNb3RvciA9PSBudWxscHRyKSB7CisgICAgd3BpX3NldFdQSUVycm9yKE51bGxQYXJhbWV0ZXIpOworICAgIHJldHVybjsKKyAgfQorICBtX2Zyb250TGVmdE1vdG9yID0gZnJvbnRMZWZ0TW90b3I7CisgIG1fcmVhckxlZnRNb3RvciA9IHJlYXJMZWZ0TW90b3I7CisgIG1fZnJvbnRSaWdodE1vdG9yID0gZnJvbnRSaWdodE1vdG9yOworICBtX3JlYXJSaWdodE1vdG9yID0gcmVhclJpZ2h0TW90b3I7Cit9CisKKy8qKgorICogRHJpdmUgdGhlIG1vdG9ycyBhdCAib3V0cHV0TWFnbml0dWRlIiBhbmQgImN1cnZlIi4KKyAqIEJvdGggb3V0cHV0TWFnbml0dWRlIGFuZCBjdXJ2ZSBhcmUgLTEuMCB0byArMS4wIHZhbHVlcywgd2hlcmUgMC4wIHJlcHJlc2VudHMKKyAqIHN0b3BwZWQgYW5kIG5vdCB0dXJuaW5nLiBjdXJ2ZSA8IDAgd2lsbCB0dXJuIGxlZnQgYW5kIGN1cnZlID4gMCB3aWxsIHR1cm4KKyAqIHJpZ2h0LgorICoKKyAqIFRoZSBhbGdvcml0aG0gZm9yIHN0ZWVyaW5nIHByb3ZpZGVzIGEgY29uc3RhbnQgdHVybiByYWRpdXMgZm9yIGFueSBub3JtYWwKKyAqIHNwZWVkIHJhbmdlLCBib3RoIGZvcndhcmQgYW5kIGJhY2t3YXJkLiBJbmNyZWFzaW5nIG1fc2Vuc2l0aXZpdHkgY2F1c2VzCisgKiBzaGFycGVyIHR1cm5zIGZvciBmaXhlZCB2YWx1ZXMgb2YgY3VydmUuCisgKgorICogVGhpcyBmdW5jdGlvbiB3aWxsIG1vc3QgbGlrZWx5IGJlIHVzZWQgaW4gYW4gYXV0b25vbW91cyByb3V0aW5lLgorICoKKyAqIEBwYXJhbSBvdXRwdXRNYWduaXR1ZGUgVGhlIHNwZWVkIHNldHRpbmcgZm9yIHRoZSBvdXRzaWRlIHdoZWVsIGluIGEgdHVybiwKKyAqICAgICAgICBmb3J3YXJkIG9yIGJhY2t3YXJkcywgKzEgdG8gLTEuCisgKiBAcGFyYW0gY3VydmUgVGhlIHJhdGUgb2YgdHVybiwgY29uc3RhbnQgZm9yIGRpZmZlcmVudCBmb3J3YXJkIHNwZWVkcy4gU2V0CisgKiAgICAgICAgY3VydmUgPCAwIGZvciBsZWZ0IHR1cm4gb3IgY3VydmUgPiAwIGZvciByaWdodCB0dXJuLgorICogU2V0IGN1cnZlID0gZV4oLXIvdykgdG8gZ2V0IGEgdHVybiByYWRpdXMgciBmb3Igd2hlZWxiYXNlIHcgb2YgeW91ciByb2JvdC4KKyAqIENvbnZlcnNlbHksIHR1cm4gcmFkaXVzIHIgPSAtbG4oY3VydmUpKncgZm9yIGEgZ2l2ZW4gdmFsdWUgb2YgY3VydmUgYW5kCisgKiB3aGVlbGJhc2Ugdy4KKyAqLwordm9pZCBSb2JvdERyaXZlOjpEcml2ZShmbG9hdCBvdXRwdXRNYWduaXR1ZGUsIGZsb2F0IGN1cnZlKSB7CisgIGZsb2F0IGxlZnRPdXRwdXQsIHJpZ2h0T3V0cHV0OworICBzdGF0aWMgYm9vbCByZXBvcnRlZCA9IGZhbHNlOworICBpZiAoIXJlcG9ydGVkKSB7CisgICAgSEFMUmVwb3J0KEhBTFVzYWdlUmVwb3J0aW5nOjprUmVzb3VyY2VUeXBlX1JvYm90RHJpdmUsIEdldE51bU1vdG9ycygpLAorICAgICAgICAgICAgICBIQUxVc2FnZVJlcG9ydGluZzo6a1JvYm90RHJpdmVfQXJjYWRlUmF0aW9DdXJ2ZSk7CisgICAgcmVwb3J0ZWQgPSB0cnVlOworICB9CisKKyAgaWYgKGN1cnZlIDwgMCkgeworICAgIGZsb2F0IHZhbHVlID0gbG9nKC1jdXJ2ZSk7CisgICAgZmxvYXQgcmF0aW8gPSAodmFsdWUgLSBtX3NlbnNpdGl2aXR5KSAvICh2YWx1ZSArIG1fc2Vuc2l0aXZpdHkpOworICAgIGlmIChyYXRpbyA9PSAwKSByYXRpbyA9IC4wMDAwMDAwMDAxOworICAgIGxlZnRPdXRwdXQgPSBvdXRwdXRNYWduaXR1ZGUgLyByYXRpbzsKKyAgICByaWdodE91dHB1dCA9IG91dHB1dE1hZ25pdHVkZTsKKyAgfSBlbHNlIGlmIChjdXJ2ZSA+IDApIHsKKyAgICBmbG9hdCB2YWx1ZSA9IGxvZyhjdXJ2ZSk7CisgICAgZmxvYXQgcmF0aW8gPSAodmFsdWUgLSBtX3NlbnNpdGl2aXR5KSAvICh2YWx1ZSArIG1fc2Vuc2l0aXZpdHkpOworICAgIGlmIChyYXRpbyA9PSAwKSByYXRpbyA9IC4wMDAwMDAwMDAxOworICAgIGxlZnRPdXRwdXQgPSBvdXRwdXRNYWduaXR1ZGU7CisgICAgcmlnaHRPdXRwdXQgPSBvdXRwdXRNYWduaXR1ZGUgLyByYXRpbzsKKyAgfSBlbHNlIHsKKyAgICBsZWZ0T3V0cHV0ID0gb3V0cHV0TWFnbml0dWRlOworICAgIHJpZ2h0T3V0cHV0ID0gb3V0cHV0TWFnbml0dWRlOworICB9CisgIFNldExlZnRSaWdodE1vdG9yT3V0cHV0cyhsZWZ0T3V0cHV0LCByaWdodE91dHB1dCk7Cit9CisKKy8qKgorICogUHJvdmlkZSB0YW5rIHN0ZWVyaW5nIHVzaW5nIHRoZSBzdG9yZWQgcm9ib3QgY29uZmlndXJhdGlvbi4KKyAqIERyaXZlIHRoZSByb2JvdCB1c2luZyB0d28gam95c3RpY2sgaW5wdXRzLiBUaGUgWS1heGlzIHdpbGwgYmUgc2VsZWN0ZWQgZnJvbQorICogZWFjaCBKb3lzdGljayBvYmplY3QuCisgKiBAcGFyYW0gbGVmdFN0aWNrIFRoZSBqb3lzdGljayB0byBjb250cm9sIHRoZSBsZWZ0IHNpZGUgb2YgdGhlIHJvYm90LgorICogQHBhcmFtIHJpZ2h0U3RpY2sgVGhlIGpveXN0aWNrIHRvIGNvbnRyb2wgdGhlIHJpZ2h0IHNpZGUgb2YgdGhlIHJvYm90LgorICovCit2b2lkIFJvYm90RHJpdmU6OlRhbmtEcml2ZShHZW5lcmljSElEICpsZWZ0U3RpY2ssIEdlbmVyaWNISUQgKnJpZ2h0U3RpY2ssCisgICAgICAgICAgICAgICAgICAgICAgICAgICBib29sIHNxdWFyZWRJbnB1dHMpIHsKKyAgaWYgKGxlZnRTdGljayA9PSBudWxscHRyIHx8IHJpZ2h0U3RpY2sgPT0gbnVsbHB0cikgeworICAgIHdwaV9zZXRXUElFcnJvcihOdWxsUGFyYW1ldGVyKTsKKyAgICByZXR1cm47CisgIH0KKyAgVGFua0RyaXZlKGxlZnRTdGljay0+R2V0WSgpLCByaWdodFN0aWNrLT5HZXRZKCksIHNxdWFyZWRJbnB1dHMpOworfQorCit2b2lkIFJvYm90RHJpdmU6OlRhbmtEcml2ZShHZW5lcmljSElEICZsZWZ0U3RpY2ssIEdlbmVyaWNISUQgJnJpZ2h0U3RpY2ssCisgICAgICAgICAgICAgICAgICAgICAgICAgICBib29sIHNxdWFyZWRJbnB1dHMpIHsKKyAgVGFua0RyaXZlKGxlZnRTdGljay5HZXRZKCksIHJpZ2h0U3RpY2suR2V0WSgpLCBzcXVhcmVkSW5wdXRzKTsKK30KKworLyoqCisgKiBQcm92aWRlIHRhbmsgc3RlZXJpbmcgdXNpbmcgdGhlIHN0b3JlZCByb2JvdCBjb25maWd1cmF0aW9uLgorICogVGhpcyBmdW5jdGlvbiBsZXRzIHlvdSBwaWNrIHRoZSBheGlzIHRvIGJlIHVzZWQgb24gZWFjaCBKb3lzdGljayBvYmplY3QgZm9yCisgKiB0aGUgbGVmdAorICogYW5kIHJpZ2h0IHNpZGVzIG9mIHRoZSByb2JvdC4KKyAqIEBwYXJhbSBsZWZ0U3RpY2sgVGhlIEpveXN0aWNrIG9iamVjdCB0byB1c2UgZm9yIHRoZSBsZWZ0IHNpZGUgb2YgdGhlIHJvYm90LgorICogQHBhcmFtIGxlZnRBeGlzIFRoZSBheGlzIHRvIHNlbGVjdCBvbiB0aGUgbGVmdCBzaWRlIEpveXN0aWNrIG9iamVjdC4KKyAqIEBwYXJhbSByaWdodFN0aWNrIFRoZSBKb3lzdGljayBvYmplY3QgdG8gdXNlIGZvciB0aGUgcmlnaHQgc2lkZSBvZiB0aGUgcm9ib3QuCisgKiBAcGFyYW0gcmlnaHRBeGlzIFRoZSBheGlzIHRvIHNlbGVjdCBvbiB0aGUgcmlnaHQgc2lkZSBKb3lzdGljayBvYmplY3QuCisgKi8KK3ZvaWQgUm9ib3REcml2ZTo6VGFua0RyaXZlKEdlbmVyaWNISUQgKmxlZnRTdGljaywgdWludDMyX3QgbGVmdEF4aXMsCisgICAgICAgICAgICAgICAgICAgICAgICAgICBHZW5lcmljSElEICpyaWdodFN0aWNrLCB1aW50MzJfdCByaWdodEF4aXMsCisgICAgICAgICAgICAgICAgICAgICAgICAgICBib29sIHNxdWFyZWRJbnB1dHMpIHsKKyAgaWYgKGxlZnRTdGljayA9PSBudWxscHRyIHx8IHJpZ2h0U3RpY2sgPT0gbnVsbHB0cikgeworICAgIHdwaV9zZXRXUElFcnJvcihOdWxsUGFyYW1ldGVyKTsKKyAgICByZXR1cm47CisgIH0KKyAgVGFua0RyaXZlKGxlZnRTdGljay0+R2V0UmF3QXhpcyhsZWZ0QXhpcyksIHJpZ2h0U3RpY2stPkdldFJhd0F4aXMocmlnaHRBeGlzKSwKKyAgICAgICAgICAgIHNxdWFyZWRJbnB1dHMpOworfQorCit2b2lkIFJvYm90RHJpdmU6OlRhbmtEcml2ZShHZW5lcmljSElEICZsZWZ0U3RpY2ssIHVpbnQzMl90IGxlZnRBeGlzLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgR2VuZXJpY0hJRCAmcmlnaHRTdGljaywgdWludDMyX3QgcmlnaHRBeGlzLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgYm9vbCBzcXVhcmVkSW5wdXRzKSB7CisgIFRhbmtEcml2ZShsZWZ0U3RpY2suR2V0UmF3QXhpcyhsZWZ0QXhpcyksIHJpZ2h0U3RpY2suR2V0UmF3QXhpcyhyaWdodEF4aXMpLAorICAgICAgICAgICAgc3F1YXJlZElucHV0cyk7Cit9CisKKy8qKgorICogUHJvdmlkZSB0YW5rIHN0ZWVyaW5nIHVzaW5nIHRoZSBzdG9yZWQgcm9ib3QgY29uZmlndXJhdGlvbi4KKyAqIFRoaXMgZnVuY3Rpb24gbGV0cyB5b3UgZGlyZWN0bHkgcHJvdmlkZSBqb3lzdGljayB2YWx1ZXMgZnJvbSBhbnkgc291cmNlLgorICogQHBhcmFtIGxlZnRWYWx1ZSBUaGUgdmFsdWUgb2YgdGhlIGxlZnQgc3RpY2suCisgKiBAcGFyYW0gcmlnaHRWYWx1ZSBUaGUgdmFsdWUgb2YgdGhlIHJpZ2h0IHN0aWNrLgorICovCit2b2lkIFJvYm90RHJpdmU6OlRhbmtEcml2ZShmbG9hdCBsZWZ0VmFsdWUsIGZsb2F0IHJpZ2h0VmFsdWUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICBib29sIHNxdWFyZWRJbnB1dHMpIHsKKyAgc3RhdGljIGJvb2wgcmVwb3J0ZWQgPSBmYWxzZTsKKyAgaWYgKCFyZXBvcnRlZCkgeworICAgIEhBTFJlcG9ydChIQUxVc2FnZVJlcG9ydGluZzo6a1Jlc291cmNlVHlwZV9Sb2JvdERyaXZlLCBHZXROdW1Nb3RvcnMoKSwKKyAgICAgICAgICAgICAgSEFMVXNhZ2VSZXBvcnRpbmc6OmtSb2JvdERyaXZlX1RhbmspOworICAgIHJlcG9ydGVkID0gdHJ1ZTsKKyAgfQorCisgIC8vIHNxdWFyZSB0aGUgaW5wdXRzICh3aGlsZSBwcmVzZXJ2aW5nIHRoZSBzaWduKSB0byBpbmNyZWFzZSBmaW5lIGNvbnRyb2wKKyAgLy8gd2hpbGUgcGVybWl0dGluZyBmdWxsIHBvd2VyCisgIGxlZnRWYWx1ZSA9IExpbWl0KGxlZnRWYWx1ZSk7CisgIHJpZ2h0VmFsdWUgPSBMaW1pdChyaWdodFZhbHVlKTsKKyAgaWYgKHNxdWFyZWRJbnB1dHMpIHsKKyAgICBpZiAobGVmdFZhbHVlID49IDAuMCkgeworICAgICAgbGVmdFZhbHVlID0gKGxlZnRWYWx1ZSAqIGxlZnRWYWx1ZSk7CisgICAgfSBlbHNlIHsKKyAgICAgIGxlZnRWYWx1ZSA9IC0obGVmdFZhbHVlICogbGVmdFZhbHVlKTsKKyAgICB9CisgICAgaWYgKHJpZ2h0VmFsdWUgPj0gMC4wKSB7CisgICAgICByaWdodFZhbHVlID0gKHJpZ2h0VmFsdWUgKiByaWdodFZhbHVlKTsKKyAgICB9IGVsc2UgeworICAgICAgcmlnaHRWYWx1ZSA9IC0ocmlnaHRWYWx1ZSAqIHJpZ2h0VmFsdWUpOworICAgIH0KKyAgfQorCisgIFNldExlZnRSaWdodE1vdG9yT3V0cHV0cyhsZWZ0VmFsdWUsIHJpZ2h0VmFsdWUpOworfQorCisvKioKKyAqIEFyY2FkZSBkcml2ZSBpbXBsZW1lbnRzIHNpbmdsZSBzdGljayBkcml2aW5nLgorICogR2l2ZW4gYSBzaW5nbGUgSm95c3RpY2ssIHRoZSBjbGFzcyBhc3N1bWVzIHRoZSBZIGF4aXMgZm9yIHRoZSBtb3ZlIHZhbHVlIGFuZAorICogdGhlIFggYXhpcworICogZm9yIHRoZSByb3RhdGUgdmFsdWUuCisgKiAoU2hvdWxkIGFkZCBtb3JlIGluZm9ybWF0aW9uIGhlcmUgcmVnYXJkaW5nIHRoZSB3YXkgdGhhdCBhcmNhZGUgZHJpdmUgd29ya3MuKQorICogQHBhcmFtIHN0aWNrIFRoZSBqb3lzdGljayB0byB1c2UgZm9yIEFyY2FkZSBzaW5nbGUtc3RpY2sgZHJpdmluZy4gVGhlIFktYXhpcworICogd2lsbCBiZSBzZWxlY3RlZAorICogZm9yIGZvcndhcmRzL2JhY2t3YXJkcyBhbmQgdGhlIFgtYXhpcyB3aWxsIGJlIHNlbGVjdGVkIGZvciByb3RhdGlvbiByYXRlLgorICogQHBhcmFtIHNxdWFyZWRJbnB1dHMgSWYgdHJ1ZSwgdGhlIHNlbnNpdGl2aXR5IHdpbGwgYmUgaW5jcmVhc2VkIGZvciBzbWFsbAorICogdmFsdWVzCisgKi8KK3ZvaWQgUm9ib3REcml2ZTo6QXJjYWRlRHJpdmUoR2VuZXJpY0hJRCAqc3RpY2ssIGJvb2wgc3F1YXJlZElucHV0cykgeworICAvLyBzaW1wbHkgY2FsbCB0aGUgZnVsbC1mZWF0dXJlZCBBcmNhZGVEcml2ZSB3aXRoIHRoZSBhcHByb3ByaWF0ZSB2YWx1ZXMKKyAgQXJjYWRlRHJpdmUoc3RpY2stPkdldFkoKSwgc3RpY2stPkdldFgoKSwgc3F1YXJlZElucHV0cyk7Cit9CisKKy8qKgorICogQXJjYWRlIGRyaXZlIGltcGxlbWVudHMgc2luZ2xlIHN0aWNrIGRyaXZpbmcuCisgKiBHaXZlbiBhIHNpbmdsZSBKb3lzdGljaywgdGhlIGNsYXNzIGFzc3VtZXMgdGhlIFkgYXhpcyBmb3IgdGhlIG1vdmUgdmFsdWUgYW5kCisgKiB0aGUgWCBheGlzCisgKiBmb3IgdGhlIHJvdGF0ZSB2YWx1ZS4KKyAqIChTaG91bGQgYWRkIG1vcmUgaW5mb3JtYXRpb24gaGVyZSByZWdhcmRpbmcgdGhlIHdheSB0aGF0IGFyY2FkZSBkcml2ZSB3b3Jrcy4pCisgKiBAcGFyYW0gc3RpY2sgVGhlIGpveXN0aWNrIHRvIHVzZSBmb3IgQXJjYWRlIHNpbmdsZS1zdGljayBkcml2aW5nLiBUaGUgWS1heGlzCisgKiB3aWxsIGJlIHNlbGVjdGVkCisgKiBmb3IgZm9yd2FyZHMvYmFja3dhcmRzIGFuZCB0aGUgWC1heGlzIHdpbGwgYmUgc2VsZWN0ZWQgZm9yIHJvdGF0aW9uIHJhdGUuCisgKiBAcGFyYW0gc3F1YXJlZElucHV0cyBJZiB0cnVlLCB0aGUgc2Vuc2l0aXZpdHkgd2lsbCBiZSBpbmNyZWFzZWQgZm9yIHNtYWxsCisgKiB2YWx1ZXMKKyAqLwordm9pZCBSb2JvdERyaXZlOjpBcmNhZGVEcml2ZShHZW5lcmljSElEICZzdGljaywgYm9vbCBzcXVhcmVkSW5wdXRzKSB7CisgIC8vIHNpbXBseSBjYWxsIHRoZSBmdWxsLWZlYXR1cmVkIEFyY2FkZURyaXZlIHdpdGggdGhlIGFwcHJvcHJpYXRlIHZhbHVlcworICBBcmNhZGVEcml2ZShzdGljay5HZXRZKCksIHN0aWNrLkdldFgoKSwgc3F1YXJlZElucHV0cyk7Cit9CisKKy8qKgorICogQXJjYWRlIGRyaXZlIGltcGxlbWVudHMgc2luZ2xlIHN0aWNrIGRyaXZpbmcuCisgKiBHaXZlbiB0d28gam95c3RpY2sgaW5zdGFuY2VzIGFuZCB0d28gYXhpcywgY29tcHV0ZSB0aGUgdmFsdWVzIHRvIHNlbmQgdG8KKyAqIGVpdGhlciB0d28KKyAqIG9yIGZvdXIgbW90b3JzLgorICogQHBhcmFtIG1vdmVTdGljayBUaGUgSm95c3RpY2sgb2JqZWN0IHRoYXQgcmVwcmVzZW50cyB0aGUgZm9yd2FyZC9iYWNrd2FyZAorICogZGlyZWN0aW9uCisgKiBAcGFyYW0gbW92ZUF4aXMgVGhlIGF4aXMgb24gdGhlIG1vdmVTdGljayBvYmplY3QgdG8gdXNlIGZvciBmb3dhcmRzL2JhY2t3YXJkcworICogKHR5cGljYWxseSBZX0FYSVMpCisgKiBAcGFyYW0gcm90YXRlU3RpY2sgVGhlIEpveXN0aWNrIG9iamVjdCB0aGF0IHJlcHJlc2VudHMgdGhlIHJvdGF0aW9uIHZhbHVlCisgKiBAcGFyYW0gcm90YXRlQXhpcyBUaGUgYXhpcyBvbiB0aGUgcm90YXRpb24gb2JqZWN0IHRvIHVzZSBmb3IgdGhlIHJvdGF0ZQorICogcmlnaHQvbGVmdCAodHlwaWNhbGx5IFhfQVhJUykKKyAqIEBwYXJhbSBzcXVhcmVkSW5wdXRzIFNldHRpbmcgdGhpcyBwYXJhbWV0ZXIgdG8gdHJ1ZSBpbmNyZWFzZXMgdGhlIHNlbnNpdGl2aXR5CisgKiBhdCBsb3dlciBzcGVlZHMKKyAqLwordm9pZCBSb2JvdERyaXZlOjpBcmNhZGVEcml2ZShHZW5lcmljSElEICptb3ZlU3RpY2ssIHVpbnQzMl90IG1vdmVBeGlzLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICBHZW5lcmljSElEICpyb3RhdGVTdGljaywgdWludDMyX3Qgcm90YXRlQXhpcywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYm9vbCBzcXVhcmVkSW5wdXRzKSB7CisgIGZsb2F0IG1vdmVWYWx1ZSA9IG1vdmVTdGljay0+R2V0UmF3QXhpcyhtb3ZlQXhpcyk7CisgIGZsb2F0IHJvdGF0ZVZhbHVlID0gcm90YXRlU3RpY2stPkdldFJhd0F4aXMocm90YXRlQXhpcyk7CisKKyAgQXJjYWRlRHJpdmUobW92ZVZhbHVlLCByb3RhdGVWYWx1ZSwgc3F1YXJlZElucHV0cyk7Cit9CisKKy8qKgorICogQXJjYWRlIGRyaXZlIGltcGxlbWVudHMgc2luZ2xlIHN0aWNrIGRyaXZpbmcuCisgKiBHaXZlbiB0d28gam95c3RpY2sgaW5zdGFuY2VzIGFuZCB0d28gYXhpcywgY29tcHV0ZSB0aGUgdmFsdWVzIHRvIHNlbmQgdG8KKyAqIGVpdGhlciB0d28KKyAqIG9yIGZvdXIgbW90b3JzLgorICogQHBhcmFtIG1vdmVTdGljayBUaGUgSm95c3RpY2sgb2JqZWN0IHRoYXQgcmVwcmVzZW50cyB0aGUgZm9yd2FyZC9iYWNrd2FyZAorICogZGlyZWN0aW9uCisgKiBAcGFyYW0gbW92ZUF4aXMgVGhlIGF4aXMgb24gdGhlIG1vdmVTdGljayBvYmplY3QgdG8gdXNlIGZvciBmb3dhcmRzL2JhY2t3YXJkcworICogKHR5cGljYWxseSBZX0FYSVMpCisgKiBAcGFyYW0gcm90YXRlU3RpY2sgVGhlIEpveXN0aWNrIG9iamVjdCB0aGF0IHJlcHJlc2VudHMgdGhlIHJvdGF0aW9uIHZhbHVlCisgKiBAcGFyYW0gcm90YXRlQXhpcyBUaGUgYXhpcyBvbiB0aGUgcm90YXRpb24gb2JqZWN0IHRvIHVzZSBmb3IgdGhlIHJvdGF0ZQorICogcmlnaHQvbGVmdCAodHlwaWNhbGx5IFhfQVhJUykKKyAqIEBwYXJhbSBzcXVhcmVkSW5wdXRzIFNldHRpbmcgdGhpcyBwYXJhbWV0ZXIgdG8gdHJ1ZSBpbmNyZWFzZXMgdGhlIHNlbnNpdGl2aXR5CisgKiBhdCBsb3dlciBzcGVlZHMKKyAqLworCit2b2lkIFJvYm90RHJpdmU6OkFyY2FkZURyaXZlKEdlbmVyaWNISUQgJm1vdmVTdGljaywgdWludDMyX3QgbW92ZUF4aXMsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEdlbmVyaWNISUQgJnJvdGF0ZVN0aWNrLCB1aW50MzJfdCByb3RhdGVBeGlzLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICBib29sIHNxdWFyZWRJbnB1dHMpIHsKKyAgZmxvYXQgbW92ZVZhbHVlID0gbW92ZVN0aWNrLkdldFJhd0F4aXMobW92ZUF4aXMpOworICBmbG9hdCByb3RhdGVWYWx1ZSA9IHJvdGF0ZVN0aWNrLkdldFJhd0F4aXMocm90YXRlQXhpcyk7CisKKyAgQXJjYWRlRHJpdmUobW92ZVZhbHVlLCByb3RhdGVWYWx1ZSwgc3F1YXJlZElucHV0cyk7Cit9CisKKy8qKgorICogQXJjYWRlIGRyaXZlIGltcGxlbWVudHMgc2luZ2xlIHN0aWNrIGRyaXZpbmcuCisgKiBUaGlzIGZ1bmN0aW9uIGxldHMgeW91IGRpcmVjdGx5IHByb3ZpZGUgam95c3RpY2sgdmFsdWVzIGZyb20gYW55IHNvdXJjZS4KKyAqIEBwYXJhbSBtb3ZlVmFsdWUgVGhlIHZhbHVlIHRvIHVzZSBmb3IgZm93YXJkcy9iYWNrd2FyZHMKKyAqIEBwYXJhbSByb3RhdGVWYWx1ZSBUaGUgdmFsdWUgdG8gdXNlIGZvciB0aGUgcm90YXRlIHJpZ2h0L2xlZnQKKyAqIEBwYXJhbSBzcXVhcmVkSW5wdXRzIElmIHNldCwgaW5jcmVhc2VzIHRoZSBzZW5zaXRpdml0eSBhdCBsb3cgc3BlZWRzCisgKi8KK3ZvaWQgUm9ib3REcml2ZTo6QXJjYWRlRHJpdmUoZmxvYXQgbW92ZVZhbHVlLCBmbG9hdCByb3RhdGVWYWx1ZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYm9vbCBzcXVhcmVkSW5wdXRzKSB7CisgIHN0YXRpYyBib29sIHJlcG9ydGVkID0gZmFsc2U7CisgIGlmICghcmVwb3J0ZWQpIHsKKyAgICBIQUxSZXBvcnQoSEFMVXNhZ2VSZXBvcnRpbmc6OmtSZXNvdXJjZVR5cGVfUm9ib3REcml2ZSwgR2V0TnVtTW90b3JzKCksCisgICAgICAgICAgICAgIEhBTFVzYWdlUmVwb3J0aW5nOjprUm9ib3REcml2ZV9BcmNhZGVTdGFuZGFyZCk7CisgICAgcmVwb3J0ZWQgPSB0cnVlOworICB9CisKKyAgLy8gbG9jYWwgdmFyaWFibGVzIHRvIGhvbGQgdGhlIGNvbXB1dGVkIFBXTSB2YWx1ZXMgZm9yIHRoZSBtb3RvcnMKKyAgZmxvYXQgbGVmdE1vdG9yT3V0cHV0OworICBmbG9hdCByaWdodE1vdG9yT3V0cHV0OworCisgIG1vdmVWYWx1ZSA9IExpbWl0KG1vdmVWYWx1ZSk7CisgIHJvdGF0ZVZhbHVlID0gTGltaXQocm90YXRlVmFsdWUpOworCisgIGlmIChzcXVhcmVkSW5wdXRzKSB7CisgICAgLy8gc3F1YXJlIHRoZSBpbnB1dHMgKHdoaWxlIHByZXNlcnZpbmcgdGhlIHNpZ24pIHRvIGluY3JlYXNlIGZpbmUgY29udHJvbAorICAgIC8vIHdoaWxlIHBlcm1pdHRpbmcgZnVsbCBwb3dlcgorICAgIGlmIChtb3ZlVmFsdWUgPj0gMC4wKSB7CisgICAgICBtb3ZlVmFsdWUgPSAobW92ZVZhbHVlICogbW92ZVZhbHVlKTsKKyAgICB9IGVsc2UgeworICAgICAgbW92ZVZhbHVlID0gLShtb3ZlVmFsdWUgKiBtb3ZlVmFsdWUpOworICAgIH0KKyAgICBpZiAocm90YXRlVmFsdWUgPj0gMC4wKSB7CisgICAgICByb3RhdGVWYWx1ZSA9IChyb3RhdGVWYWx1ZSAqIHJvdGF0ZVZhbHVlKTsKKyAgICB9IGVsc2UgeworICAgICAgcm90YXRlVmFsdWUgPSAtKHJvdGF0ZVZhbHVlICogcm90YXRlVmFsdWUpOworICAgIH0KKyAgfQorCisgIGlmIChtb3ZlVmFsdWUgPiAwLjApIHsKKyAgICBpZiAocm90YXRlVmFsdWUgPiAwLjApIHsKKyAgICAgIGxlZnRNb3Rvck91dHB1dCA9IG1vdmVWYWx1ZSAtIHJvdGF0ZVZhbHVlOworICAgICAgcmlnaHRNb3Rvck91dHB1dCA9IHN0ZDo6bWF4KG1vdmVWYWx1ZSwgcm90YXRlVmFsdWUpOworICAgIH0gZWxzZSB7CisgICAgICBsZWZ0TW90b3JPdXRwdXQgPSBzdGQ6Om1heChtb3ZlVmFsdWUsIC1yb3RhdGVWYWx1ZSk7CisgICAgICByaWdodE1vdG9yT3V0cHV0ID0gbW92ZVZhbHVlICsgcm90YXRlVmFsdWU7CisgICAgfQorICB9IGVsc2UgeworICAgIGlmIChyb3RhdGVWYWx1ZSA+IDAuMCkgeworICAgICAgbGVmdE1vdG9yT3V0cHV0ID0gLXN0ZDo6bWF4KC1tb3ZlVmFsdWUsIHJvdGF0ZVZhbHVlKTsKKyAgICAgIHJpZ2h0TW90b3JPdXRwdXQgPSBtb3ZlVmFsdWUgKyByb3RhdGVWYWx1ZTsKKyAgICB9IGVsc2UgeworICAgICAgbGVmdE1vdG9yT3V0cHV0ID0gbW92ZVZhbHVlIC0gcm90YXRlVmFsdWU7CisgICAgICByaWdodE1vdG9yT3V0cHV0ID0gLXN0ZDo6bWF4KC1tb3ZlVmFsdWUsIC1yb3RhdGVWYWx1ZSk7CisgICAgfQorICB9CisgIFNldExlZnRSaWdodE1vdG9yT3V0cHV0cyhsZWZ0TW90b3JPdXRwdXQsIHJpZ2h0TW90b3JPdXRwdXQpOworfQorCisvKioKKyAqIERyaXZlIG1ldGhvZCBmb3IgTWVjYW51bSB3aGVlbGVkIHJvYm90cy4KKyAqCisgKiBBIG1ldGhvZCBmb3IgZHJpdmluZyB3aXRoIE1lY2FudW0gd2hlZWxlZCByb2JvdHMuIFRoZXJlIGFyZSA0IHdoZWVscworICogb24gdGhlIHJvYm90LCBhcnJhbmdlZCBzbyB0aGF0IHRoZSBmcm9udCBhbmQgYmFjayB3aGVlbHMgYXJlIHRvZWQgaW4gNDUKKyAqIGRlZ3JlZXMuCisgKiBXaGVuIGxvb2tpbmcgYXQgdGhlIHdoZWVscyBmcm9tIHRoZSB0b3AsIHRoZSByb2xsZXIgYXhsZXMgc2hvdWxkIGZvcm0gYW4gWAorICogYWNyb3NzIHRoZSByb2JvdC4KKyAqCisgKiBUaGlzIGlzIGRlc2lnbmVkIHRvIGJlIGRpcmVjdGx5IGRyaXZlbiBieSBqb3lzdGljayBheGVzLgorICoKKyAqIEBwYXJhbSB4IFRoZSBzcGVlZCB0aGF0IHRoZSByb2JvdCBzaG91bGQgZHJpdmUgaW4gdGhlIFggZGlyZWN0aW9uLgorICogWy0xLjAuLjEuMF0KKyAqIEBwYXJhbSB5IFRoZSBzcGVlZCB0aGF0IHRoZSByb2JvdCBzaG91bGQgZHJpdmUgaW4gdGhlIFkgZGlyZWN0aW9uLgorICogVGhpcyBpbnB1dCBpcyBpbnZlcnRlZCB0byBtYXRjaCB0aGUgZm9yd2FyZCA9PSAtMS4wIHRoYXQgam95c3RpY2tzIHByb2R1Y2UuCisgKiBbLTEuMC4uMS4wXQorICogQHBhcmFtIHJvdGF0aW9uIFRoZSByYXRlIG9mIHJvdGF0aW9uIGZvciB0aGUgcm9ib3QgdGhhdCBpcyBjb21wbGV0ZWx5CisgKiBpbmRlcGVuZGVudCBvZgorICogdGhlIHRyYW5zbGF0aW9uLiBbLTEuMC4uMS4wXQorICogQHBhcmFtIGd5cm9BbmdsZSBUaGUgY3VycmVudCBhbmdsZSByZWFkaW5nIGZyb20gdGhlIGd5cm8uICBVc2UgdGhpcyB0bworICogaW1wbGVtZW50IGZpZWxkLW9yaWVudGVkIGNvbnRyb2xzLgorICovCit2b2lkIFJvYm90RHJpdmU6Ok1lY2FudW1Ecml2ZV9DYXJ0ZXNpYW4oZmxvYXQgeCwgZmxvYXQgeSwgZmxvYXQgcm90YXRpb24sCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmxvYXQgZ3lyb0FuZ2xlKSB7CisgIHN0YXRpYyBib29sIHJlcG9ydGVkID0gZmFsc2U7CisgIGlmICghcmVwb3J0ZWQpIHsKKyAgICBIQUxSZXBvcnQoSEFMVXNhZ2VSZXBvcnRpbmc6OmtSZXNvdXJjZVR5cGVfUm9ib3REcml2ZSwgR2V0TnVtTW90b3JzKCksCisgICAgICAgICAgICAgIEhBTFVzYWdlUmVwb3J0aW5nOjprUm9ib3REcml2ZV9NZWNhbnVtQ2FydGVzaWFuKTsKKyAgICByZXBvcnRlZCA9IHRydWU7CisgIH0KKworICBkb3VibGUgeEluID0geDsKKyAgZG91YmxlIHlJbiA9IHk7CisgIC8vIE5lZ2F0ZSB5IGZvciB0aGUgam95c3RpY2suCisgIHlJbiA9IC15SW47CisgIC8vIENvbXBlbnN0YXRlIGZvciBneXJvIGFuZ2xlLgorICBSb3RhdGVWZWN0b3IoeEluLCB5SW4sIGd5cm9BbmdsZSk7CisKKyAgZG91YmxlIHdoZWVsU3BlZWRzW2tNYXhOdW1iZXJPZk1vdG9yc107CisgIHdoZWVsU3BlZWRzW2tGcm9udExlZnRNb3Rvcl0gPSB4SW4gKyB5SW4gKyByb3RhdGlvbjsKKyAgd2hlZWxTcGVlZHNba0Zyb250UmlnaHRNb3Rvcl0gPSAteEluICsgeUluIC0gcm90YXRpb247CisgIHdoZWVsU3BlZWRzW2tSZWFyTGVmdE1vdG9yXSA9IC14SW4gKyB5SW4gKyByb3RhdGlvbjsKKyAgd2hlZWxTcGVlZHNba1JlYXJSaWdodE1vdG9yXSA9IHhJbiArIHlJbiAtIHJvdGF0aW9uOworCisgIE5vcm1hbGl6ZSh3aGVlbFNwZWVkcyk7CisKKyAgbV9mcm9udExlZnRNb3Rvci0+U2V0KHdoZWVsU3BlZWRzW2tGcm9udExlZnRNb3Rvcl0gKiBtX21heE91dHB1dCwKKyAgICAgICAgICAgICAgICAgICAgICAgIG1fc3luY0dyb3VwKTsKKyAgbV9mcm9udFJpZ2h0TW90b3ItPlNldCh3aGVlbFNwZWVkc1trRnJvbnRSaWdodE1vdG9yXSAqIG1fbWF4T3V0cHV0LAorICAgICAgICAgICAgICAgICAgICAgICAgIG1fc3luY0dyb3VwKTsKKyAgbV9yZWFyTGVmdE1vdG9yLT5TZXQod2hlZWxTcGVlZHNba1JlYXJMZWZ0TW90b3JdICogbV9tYXhPdXRwdXQsIG1fc3luY0dyb3VwKTsKKyAgbV9yZWFyUmlnaHRNb3Rvci0+U2V0KHdoZWVsU3BlZWRzW2tSZWFyUmlnaHRNb3Rvcl0gKiBtX21heE91dHB1dCwKKyAgICAgICAgICAgICAgICAgICAgICAgIG1fc3luY0dyb3VwKTsKKworICBpZiAobV9zeW5jR3JvdXAgIT0gMCkgeworICAgIENBTkphZ3Vhcjo6VXBkYXRlU3luY0dyb3VwKG1fc3luY0dyb3VwKTsKKyAgfQorCisgIG1fc2FmZXR5SGVscGVyLT5GZWVkKCk7Cit9CisKKy8qKgorICogRHJpdmUgbWV0aG9kIGZvciBNZWNhbnVtIHdoZWVsZWQgcm9ib3RzLgorICoKKyAqIEEgbWV0aG9kIGZvciBkcml2aW5nIHdpdGggTWVjYW51bSB3aGVlbGVkIHJvYm90cy4gVGhlcmUgYXJlIDQgd2hlZWxzCisgKiBvbiB0aGUgcm9ib3QsIGFycmFuZ2VkIHNvIHRoYXQgdGhlIGZyb250IGFuZCBiYWNrIHdoZWVscyBhcmUgdG9lZCBpbiA0NQorICogZGVncmVlcy4KKyAqIFdoZW4gbG9va2luZyBhdCB0aGUgd2hlZWxzIGZyb20gdGhlIHRvcCwgdGhlIHJvbGxlciBheGxlcyBzaG91bGQgZm9ybSBhbiBYCisgKiBhY3Jvc3MgdGhlIHJvYm90LgorICoKKyAqIEBwYXJhbSBtYWduaXR1ZGUgVGhlIHNwZWVkIHRoYXQgdGhlIHJvYm90IHNob3VsZCBkcml2ZSBpbiBhIGdpdmVuIGRpcmVjdGlvbi4KKyAqIFstMS4wLi4xLjBdCisgKiBAcGFyYW0gZGlyZWN0aW9uIFRoZSBkaXJlY3Rpb24gdGhlIHJvYm90IHNob3VsZCBkcml2ZSBpbiBkZWdyZWVzLiBUaGUKKyAqIGRpcmVjdGlvbiBhbmQgbWFnaW5pdHV0ZSBhcmUKKyAqIGluZGVwZW5kZW50IG9mIHRoZSByb3RhdGlvbiByYXRlLgorICogQHBhcmFtIHJvdGF0aW9uIFRoZSByYXRlIG9mIHJvdGF0aW9uIGZvciB0aGUgcm9ib3QgdGhhdCBpcyBjb21wbGV0ZWx5CisgKiBpbmRlcGVuZGVudCBvZgorICogdGhlIG1hZ25pdHV0ZSBvciBkaXJlY3Rpb24uIFstMS4wLi4xLjBdCisgKi8KK3ZvaWQgUm9ib3REcml2ZTo6TWVjYW51bURyaXZlX1BvbGFyKGZsb2F0IG1hZ25pdHVkZSwgZmxvYXQgZGlyZWN0aW9uLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmxvYXQgcm90YXRpb24pIHsKKyAgc3RhdGljIGJvb2wgcmVwb3J0ZWQgPSBmYWxzZTsKKyAgaWYgKCFyZXBvcnRlZCkgeworICAgIEhBTFJlcG9ydChIQUxVc2FnZVJlcG9ydGluZzo6a1Jlc291cmNlVHlwZV9Sb2JvdERyaXZlLCBHZXROdW1Nb3RvcnMoKSwKKyAgICAgICAgICAgICAgSEFMVXNhZ2VSZXBvcnRpbmc6OmtSb2JvdERyaXZlX01lY2FudW1Qb2xhcik7CisgICAgcmVwb3J0ZWQgPSB0cnVlOworICB9CisKKyAgLy8gTm9ybWFsaXplZCBmb3IgZnVsbCBwb3dlciBhbG9uZyB0aGUgQ2FydGVzaWFuIGF4ZXMuCisgIG1hZ25pdHVkZSA9IExpbWl0KG1hZ25pdHVkZSkgKiBzcXJ0KDIuMCk7CisgIC8vIFRoZSByb2xsZXJzIGFyZSBhdCA0NSBkZWdyZWUgYW5nbGVzLgorICBkb3VibGUgZGlySW5SYWQgPSAoZGlyZWN0aW9uICsgNDUuMCkgKiAzLjE0MTU5IC8gMTgwLjA7CisgIGRvdWJsZSBjb3NEID0gY29zKGRpckluUmFkKTsKKyAgZG91YmxlIHNpbkQgPSBzaW4oZGlySW5SYWQpOworCisgIGRvdWJsZSB3aGVlbFNwZWVkc1trTWF4TnVtYmVyT2ZNb3RvcnNdOworICB3aGVlbFNwZWVkc1trRnJvbnRMZWZ0TW90b3JdID0gc2luRCAqIG1hZ25pdHVkZSArIHJvdGF0aW9uOworICB3aGVlbFNwZWVkc1trRnJvbnRSaWdodE1vdG9yXSA9IGNvc0QgKiBtYWduaXR1ZGUgLSByb3RhdGlvbjsKKyAgd2hlZWxTcGVlZHNba1JlYXJMZWZ0TW90b3JdID0gY29zRCAqIG1hZ25pdHVkZSArIHJvdGF0aW9uOworICB3aGVlbFNwZWVkc1trUmVhclJpZ2h0TW90b3JdID0gc2luRCAqIG1hZ25pdHVkZSAtIHJvdGF0aW9uOworCisgIE5vcm1hbGl6ZSh3aGVlbFNwZWVkcyk7CisKKyAgbV9mcm9udExlZnRNb3Rvci0+U2V0KHdoZWVsU3BlZWRzW2tGcm9udExlZnRNb3Rvcl0gKiBtX21heE91dHB1dCwKKyAgICAgICAgICAgICAgICAgICAgICAgIG1fc3luY0dyb3VwKTsKKyAgbV9mcm9udFJpZ2h0TW90b3ItPlNldCh3aGVlbFNwZWVkc1trRnJvbnRSaWdodE1vdG9yXSAqIG1fbWF4T3V0cHV0LAorICAgICAgICAgICAgICAgICAgICAgICAgIG1fc3luY0dyb3VwKTsKKyAgbV9yZWFyTGVmdE1vdG9yLT5TZXQod2hlZWxTcGVlZHNba1JlYXJMZWZ0TW90b3JdICogbV9tYXhPdXRwdXQsIG1fc3luY0dyb3VwKTsKKyAgbV9yZWFyUmlnaHRNb3Rvci0+U2V0KHdoZWVsU3BlZWRzW2tSZWFyUmlnaHRNb3Rvcl0gKiBtX21heE91dHB1dCwKKyAgICAgICAgICAgICAgICAgICAgICAgIG1fc3luY0dyb3VwKTsKKworICBpZiAobV9zeW5jR3JvdXAgIT0gMCkgeworICAgIENBTkphZ3Vhcjo6VXBkYXRlU3luY0dyb3VwKG1fc3luY0dyb3VwKTsKKyAgfQorCisgIG1fc2FmZXR5SGVscGVyLT5GZWVkKCk7Cit9CisKKy8qKgorICogSG9sb25vbWljIERyaXZlIG1ldGhvZCBmb3IgTWVjYW51bSB3aGVlbGVkIHJvYm90cy4KKyAqCisgKiBUaGlzIGlzIGFuIGFsaWFzIHRvIE1lY2FudW1Ecml2ZV9Qb2xhcigpIGZvciBiYWNrd2FyZCBjb21wYXRhYmlsaXR5CisgKgorICogQHBhcmFtIG1hZ25pdHVkZSBUaGUgc3BlZWQgdGhhdCB0aGUgcm9ib3Qgc2hvdWxkIGRyaXZlIGluIGEgZ2l2ZW4gZGlyZWN0aW9uLgorICogWy0xLjAuLjEuMF0KKyAqIEBwYXJhbSBkaXJlY3Rpb24gVGhlIGRpcmVjdGlvbiB0aGUgcm9ib3Qgc2hvdWxkIGRyaXZlLiBUaGUgZGlyZWN0aW9uIGFuZAorICogbWFnaW5pdHV0ZSBhcmUKKyAqIGluZGVwZW5kZW50IG9mIHRoZSByb3RhdGlvbiByYXRlLgorICogQHBhcmFtIHJvdGF0aW9uIFRoZSByYXRlIG9mIHJvdGF0aW9uIGZvciB0aGUgcm9ib3QgdGhhdCBpcyBjb21wbGV0ZWx5CisgKiBpbmRlcGVuZGVudCBvZgorICogdGhlIG1hZ25pdHV0ZSBvciBkaXJlY3Rpb24uICBbLTEuMC4uMS4wXQorICovCit2b2lkIFJvYm90RHJpdmU6OkhvbG9ub21pY0RyaXZlKGZsb2F0IG1hZ25pdHVkZSwgZmxvYXQgZGlyZWN0aW9uLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmbG9hdCByb3RhdGlvbikgeworICBNZWNhbnVtRHJpdmVfUG9sYXIobWFnbml0dWRlLCBkaXJlY3Rpb24sIHJvdGF0aW9uKTsKK30KKworLyoqIFNldCB0aGUgc3BlZWQgb2YgdGhlIHJpZ2h0IGFuZCBsZWZ0IG1vdG9ycy4KKyAqIFRoaXMgaXMgdXNlZCBvbmNlIGFuIGFwcHJvcHJpYXRlIGRyaXZlIHNldHVwIGZ1bmN0aW9uIGlzIGNhbGxlZCBzdWNoIGFzCisgKiBUd29XaGVlbERyaXZlKCkuIFRoZSBtb3RvcnMgYXJlIHNldCB0byAibGVmdE91dHB1dCIgYW5kICJyaWdodE91dHB1dCIKKyAqIGFuZCBpbmNsdWRlcyBmbGlwcGluZyB0aGUgZGlyZWN0aW9uIG9mIG9uZSBzaWRlIGZvciBvcHBvc2luZyBtb3RvcnMuCisgKiBAcGFyYW0gbGVmdE91dHB1dCBUaGUgc3BlZWQgdG8gc2VuZCB0byB0aGUgbGVmdCBzaWRlIG9mIHRoZSByb2JvdC4KKyAqIEBwYXJhbSByaWdodE91dHB1dCBUaGUgc3BlZWQgdG8gc2VuZCB0byB0aGUgcmlnaHQgc2lkZSBvZiB0aGUgcm9ib3QuCisgKi8KK3ZvaWQgUm9ib3REcml2ZTo6U2V0TGVmdFJpZ2h0TW90b3JPdXRwdXRzKGZsb2F0IGxlZnRPdXRwdXQsIGZsb2F0IHJpZ2h0T3V0cHV0KSB7CisgIHdwaV9hc3NlcnQobV9yZWFyTGVmdE1vdG9yICE9IG51bGxwdHIgJiYgbV9yZWFyUmlnaHRNb3RvciAhPSBudWxscHRyKTsKKworICBpZiAobV9mcm9udExlZnRNb3RvciAhPSBudWxscHRyKQorICAgIG1fZnJvbnRMZWZ0TW90b3ItPlNldChMaW1pdChsZWZ0T3V0cHV0KSAqIG1fbWF4T3V0cHV0LCBtX3N5bmNHcm91cCk7CisgIG1fcmVhckxlZnRNb3Rvci0+U2V0KExpbWl0KGxlZnRPdXRwdXQpICogbV9tYXhPdXRwdXQsIG1fc3luY0dyb3VwKTsKKworICBpZiAobV9mcm9udFJpZ2h0TW90b3IgIT0gbnVsbHB0cikKKyAgICBtX2Zyb250UmlnaHRNb3Rvci0+U2V0KC1MaW1pdChyaWdodE91dHB1dCkgKiBtX21heE91dHB1dCwgbV9zeW5jR3JvdXApOworICBtX3JlYXJSaWdodE1vdG9yLT5TZXQoLUxpbWl0KHJpZ2h0T3V0cHV0KSAqIG1fbWF4T3V0cHV0LCBtX3N5bmNHcm91cCk7CisKKyAgaWYgKG1fc3luY0dyb3VwICE9IDApIHsKKyAgICBDQU5KYWd1YXI6OlVwZGF0ZVN5bmNHcm91cChtX3N5bmNHcm91cCk7CisgIH0KKworICBtX3NhZmV0eUhlbHBlci0+RmVlZCgpOworfQorCisvKioKKyAqIExpbWl0IG1vdG9yIHZhbHVlcyB0byB0aGUgLTEuMCB0byArMS4wIHJhbmdlLgorICovCitmbG9hdCBSb2JvdERyaXZlOjpMaW1pdChmbG9hdCBudW0pIHsKKyAgaWYgKG51bSA+IDEuMCkgeworICAgIHJldHVybiAxLjA7CisgIH0KKyAgaWYgKG51bSA8IC0xLjApIHsKKyAgICByZXR1cm4gLTEuMDsKKyAgfQorICByZXR1cm4gbnVtOworfQorCisvKioKKyAqIE5vcm1hbGl6ZSBhbGwgd2hlZWwgc3BlZWRzIGlmIHRoZSBtYWduaXR1ZGUgb2YgYW55IHdoZWVsIGlzIGdyZWF0ZXIgdGhhbiAxLjAuCisgKi8KK3ZvaWQgUm9ib3REcml2ZTo6Tm9ybWFsaXplKGRvdWJsZSAqd2hlZWxTcGVlZHMpIHsKKyAgZG91YmxlIG1heE1hZ25pdHVkZSA9IGZhYnMod2hlZWxTcGVlZHNbMF0pOworICBpbnQzMl90IGk7CisgIGZvciAoaSA9IDE7IGkgPCBrTWF4TnVtYmVyT2ZNb3RvcnM7IGkrKykgeworICAgIGRvdWJsZSB0ZW1wID0gZmFicyh3aGVlbFNwZWVkc1tpXSk7CisgICAgaWYgKG1heE1hZ25pdHVkZSA8IHRlbXApIG1heE1hZ25pdHVkZSA9IHRlbXA7CisgIH0KKyAgaWYgKG1heE1hZ25pdHVkZSA+IDEuMCkgeworICAgIGZvciAoaSA9IDA7IGkgPCBrTWF4TnVtYmVyT2ZNb3RvcnM7IGkrKykgeworICAgICAgd2hlZWxTcGVlZHNbaV0gPSB3aGVlbFNwZWVkc1tpXSAvIG1heE1hZ25pdHVkZTsKKyAgICB9CisgIH0KK30KKworLyoqCisgKiBSb3RhdGUgYSB2ZWN0b3IgaW4gQ2FydGVzaWFuIHNwYWNlLgorICovCit2b2lkIFJvYm90RHJpdmU6OlJvdGF0ZVZlY3Rvcihkb3VibGUgJngsIGRvdWJsZSAmeSwgZG91YmxlIGFuZ2xlKSB7CisgIGRvdWJsZSBjb3NBID0gY29zKGFuZ2xlICogKDMuMTQxNTkgLyAxODAuMCkpOworICBkb3VibGUgc2luQSA9IHNpbihhbmdsZSAqICgzLjE0MTU5IC8gMTgwLjApKTsKKyAgZG91YmxlIHhPdXQgPSB4ICogY29zQSAtIHkgKiBzaW5BOworICBkb3VibGUgeU91dCA9IHggKiBzaW5BICsgeSAqIGNvc0E7CisgIHggPSB4T3V0OworICB5ID0geU91dDsKK30KKworLyoKKyAqIEludmVydCBhIG1vdG9yIGRpcmVjdGlvbi4KKyAqIFRoaXMgaXMgdXNlZCB3aGVuIGEgbW90b3Igc2hvdWxkIHJ1biBpbiB0aGUgb3Bwb3NpdGUgZGlyZWN0aW9uIGFzIHRoZSBkcml2ZQorICogY29kZSB3b3VsZCBub3JtYWxseSBydW4gaXQuIE1vdG9ycyB0aGF0IGFyZSBkaXJlY3QgZHJpdmUgd291bGQgYmUgaW52ZXJ0ZWQsCisgKiB0aGUKKyAqIERyaXZlIGNvZGUgYXNzdW1lcyB0aGF0IHRoZSBtb3RvcnMgYXJlIGdlYXJlZCB3aXRoIG9uZSByZXZlcnNhbC4KKyAqIEBwYXJhbSBtb3RvciBUaGUgbW90b3IgaW5kZXggdG8gaW52ZXJ0LgorICogQHBhcmFtIGlzSW52ZXJ0ZWQgVHJ1ZSBpZiB0aGUgbW90b3Igc2hvdWxkIGJlIGludmVydGVkIHdoZW4gb3BlcmF0ZWQuCisgKi8KK3ZvaWQgUm9ib3REcml2ZTo6U2V0SW52ZXJ0ZWRNb3RvcihNb3RvclR5cGUgbW90b3IsIGJvb2wgaXNJbnZlcnRlZCkgeworICBpZiAobW90b3IgPCAwIHx8IG1vdG9yID4gMykgeworICAgIHdwaV9zZXRXUElFcnJvcihJbnZhbGlkTW90b3JJbmRleCk7CisgICAgcmV0dXJuOworICB9CisgIHN3aXRjaCAobW90b3IpIHsKKyAgICBjYXNlIGtGcm9udExlZnRNb3RvcjoKKyAgICAgIG1fZnJvbnRMZWZ0TW90b3ItPlNldEludmVydGVkKGlzSW52ZXJ0ZWQpOworICAgICAgYnJlYWs7CisgICAgY2FzZSBrRnJvbnRSaWdodE1vdG9yOgorICAgICAgbV9mcm9udFJpZ2h0TW90b3ItPlNldEludmVydGVkKGlzSW52ZXJ0ZWQpOworICAgICAgYnJlYWs7CisgICAgY2FzZSBrUmVhckxlZnRNb3RvcjoKKyAgICAgIG1fcmVhckxlZnRNb3Rvci0+U2V0SW52ZXJ0ZWQoaXNJbnZlcnRlZCk7CisgICAgICBicmVhazsKKyAgICBjYXNlIGtSZWFyUmlnaHRNb3RvcjoKKyAgICAgIG1fcmVhclJpZ2h0TW90b3ItPlNldEludmVydGVkKGlzSW52ZXJ0ZWQpOworICAgICAgYnJlYWs7CisgIH0KK30KKworLyoqCisgKiBTZXQgdGhlIHR1cm5pbmcgc2Vuc2l0aXZpdHkuCisgKgorICogVGhpcyBvbmx5IGltcGFjdHMgdGhlIERyaXZlKCkgZW50cnktcG9pbnQuCisgKiBAcGFyYW0gc2Vuc2l0aXZpdHkgRWZmZWN0aXZlbHkgc2V0cyB0aGUgdHVybmluZyBzZW5zaXRpdml0eSAob3IgdHVybiByYWRpdXMKKyAqIGZvciBhIGdpdmVuIHZhbHVlKQorICovCit2b2lkIFJvYm90RHJpdmU6OlNldFNlbnNpdGl2aXR5KGZsb2F0IHNlbnNpdGl2aXR5KSB7CisgIG1fc2Vuc2l0aXZpdHkgPSBzZW5zaXRpdml0eTsKK30KKworLyoqCisgKiBDb25maWd1cmUgdGhlIHNjYWxpbmcgZmFjdG9yIGZvciB1c2luZyBSb2JvdERyaXZlIHdpdGggbW90b3IgY29udHJvbGxlcnMgaW4gYQorICogbW9kZSBvdGhlciB0aGFuIFBlcmNlbnRWYnVzLgorICogQHBhcmFtIG1heE91dHB1dCBNdWx0aXBsaWVkIHdpdGggdGhlIG91dHB1dCBwZXJjZW50YWdlIGNvbXB1dGVkIGJ5IHRoZSBkcml2ZQorICogZnVuY3Rpb25zLgorICovCit2b2lkIFJvYm90RHJpdmU6OlNldE1heE91dHB1dChkb3VibGUgbWF4T3V0cHV0KSB7IG1fbWF4T3V0cHV0ID0gbWF4T3V0cHV0OyB9CisKKy8qKgorICogU2V0IHRoZSBudW1iZXIgb2YgdGhlIHN5bmMgZ3JvdXAgZm9yIHRoZSBtb3RvciBjb250cm9sbGVycy4gIElmIHRoZSBtb3RvcgorICogY29udHJvbGxlcnMgYXJlIHtAbGluayBDQU5KYWd1YXJ9cywKKyAqIHRoZW4gdGhleSB3aWxsIGFsbCBiZSBhZGRlZCB0byB0aGlzIHN5bmMgZ3JvdXAsIGNhdXNpbmcgdGhlbSB0byB1cGRhdGUgdGhlaXIKKyAqIHZhbHVlcyBhdCB0aGUgc2FtZSB0aW1lLgorICoKKyAqIEBwYXJhbSBzeW5jR3JvdXAgdGhlIHVwZGF0ZSBncm91cCB0byBhZGQgdGhlIG1vdG9yIGNvbnRyb2xsZXJzIHRvCisgKi8KK3ZvaWQgUm9ib3REcml2ZTo6U2V0Q0FOSmFndWFyU3luY0dyb3VwKHVpbnQ4X3Qgc3luY0dyb3VwKSB7CisgIG1fc3luY0dyb3VwID0gc3luY0dyb3VwOworfQorCit2b2lkIFJvYm90RHJpdmU6OlNldEV4cGlyYXRpb24oZmxvYXQgdGltZW91dCkgeworICBtX3NhZmV0eUhlbHBlci0+U2V0RXhwaXJhdGlvbih0aW1lb3V0KTsKK30KKworZmxvYXQgUm9ib3REcml2ZTo6R2V0RXhwaXJhdGlvbigpIGNvbnN0IHsKKyAgcmV0dXJuIG1fc2FmZXR5SGVscGVyLT5HZXRFeHBpcmF0aW9uKCk7Cit9CisKK2Jvb2wgUm9ib3REcml2ZTo6SXNBbGl2ZSgpIGNvbnN0IHsgcmV0dXJuIG1fc2FmZXR5SGVscGVyLT5Jc0FsaXZlKCk7IH0KKworYm9vbCBSb2JvdERyaXZlOjpJc1NhZmV0eUVuYWJsZWQoKSBjb25zdCB7CisgIHJldHVybiBtX3NhZmV0eUhlbHBlci0+SXNTYWZldHlFbmFibGVkKCk7Cit9CisKK3ZvaWQgUm9ib3REcml2ZTo6U2V0U2FmZXR5RW5hYmxlZChib29sIGVuYWJsZWQpIHsKKyAgbV9zYWZldHlIZWxwZXItPlNldFNhZmV0eUVuYWJsZWQoZW5hYmxlZCk7Cit9CisKK3ZvaWQgUm9ib3REcml2ZTo6R2V0RGVzY3JpcHRpb24oc3RkOjpvc3RyaW5nc3RyZWFtJiBkZXNjKSBjb25zdCB7CisgIGRlc2MgPDwgIlJvYm90RHJpdmUiOworfQorCit2b2lkIFJvYm90RHJpdmU6OlN0b3BNb3RvcigpIHsKKyAgaWYgKG1fZnJvbnRMZWZ0TW90b3IgIT0gbnVsbHB0cikgbV9mcm9udExlZnRNb3Rvci0+RGlzYWJsZSgpOworICBpZiAobV9mcm9udFJpZ2h0TW90b3IgIT0gbnVsbHB0cikgbV9mcm9udFJpZ2h0TW90b3ItPkRpc2FibGUoKTsKKyAgaWYgKG1fcmVhckxlZnRNb3RvciAhPSBudWxscHRyKSBtX3JlYXJMZWZ0TW90b3ItPkRpc2FibGUoKTsKKyAgaWYgKG1fcmVhclJpZ2h0TW90b3IgIT0gbnVsbHB0cikgbV9yZWFyUmlnaHRNb3Rvci0+RGlzYWJsZSgpOworICBtX3NhZmV0eUhlbHBlci0+RmVlZCgpOworfQpkaWZmIC0tZ2l0IGEvd3BpbGliYy9BdGhlbmEvc3JjL1NQSS5jcHAgYi93cGlsaWJjL0F0aGVuYS9zcmMvU1BJLmNwcApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5hNDcwNTk3Ci0tLSAvZGV2L251bGwKKysrIGIvd3BpbGliYy9BdGhlbmEvc3JjL1NQSS5jcHAKQEAgLTAsMCArMSwzMDMgQEAKKy8qLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovCisvKiBDb3B5cmlnaHQgKGMpIEZJUlNUIDIwMDguIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCisgKi8KKy8qIE9wZW4gU291cmNlIFNvZnR3YXJlIC0gbWF5IGJlIG1vZGlmaWVkIGFuZCBzaGFyZWQgYnkgRlJDIHRlYW1zLiBUaGUgY29kZSAgICovCisvKiBtdXN0IGJlIGFjY29tcGFuaWVkIGJ5IHRoZSBGSVJTVCBCU0QgbGljZW5zZSBmaWxlIGluICQoV0lORF9CQVNFKS9XUElMaWIuICAqLworLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi8KKworI2luY2x1ZGUgIlNQSS5oIgorCisjaW5jbHVkZSAiV1BJRXJyb3JzLmgiCisjaW5jbHVkZSAiSEFML0RpZ2l0YWwuaHBwIgorCisjaW5jbHVkZSA8c3RyaW5nLmg+CisKKy8qKgorICogQ29uc3RydWN0b3IKKyAqCisgKiBAcGFyYW0gU1BJcG9ydCB0aGUgcGh5c2ljYWwgU1BJIHBvcnQKKyAqLworU1BJOjpTUEkoUG9ydCBTUElwb3J0KSB7CisgIG1fcG9ydCA9IFNQSXBvcnQ7CisgIGludDMyX3Qgc3RhdHVzID0gMDsKKyAgc3BpSW5pdGlhbGl6ZShtX3BvcnQsICZzdGF0dXMpOworICB3cGlfc2V0RXJyb3JXaXRoQ29udGV4dChzdGF0dXMsIGdldEhBTEVycm9yTWVzc2FnZShzdGF0dXMpKTsKKworICBzdGF0aWMgaW50MzJfdCBpbnN0YW5jZXMgPSAwOworICBpbnN0YW5jZXMrKzsKKyAgSEFMUmVwb3J0KEhBTFVzYWdlUmVwb3J0aW5nOjprUmVzb3VyY2VUeXBlX1NQSSwgaW5zdGFuY2VzKTsKK30KKworLyoqCisgKiBEZXN0cnVjdG9yLgorICovCitTUEk6On5TUEkoKSB7IHNwaUNsb3NlKG1fcG9ydCk7IH0KKworLyoqCisgKiBDb25maWd1cmUgdGhlIHJhdGUgb2YgdGhlIGdlbmVyYXRlZCBjbG9jayBzaWduYWwuCisgKgorICogVGhlIGRlZmF1bHQgdmFsdWUgaXMgNTAwLDAwMEh6LgorICogVGhlIG1heGltdW0gdmFsdWUgaXMgNCwwMDAsMDAwSHouCisgKgorICogQHBhcmFtIGh6CVRoZSBjbG9jayByYXRlIGluIEhlcnR6LgorICovCit2b2lkIFNQSTo6U2V0Q2xvY2tSYXRlKGRvdWJsZSBoeikgeyBzcGlTZXRTcGVlZChtX3BvcnQsIGh6KTsgfQorCisvKioKKyAqIENvbmZpZ3VyZSB0aGUgb3JkZXIgdGhhdCBiaXRzIGFyZSBzZW50IGFuZCByZWNlaXZlZCBvbiB0aGUgd2lyZQorICogdG8gYmUgbW9zdCBzaWduaWZpY2FudCBiaXQgZmlyc3QuCisgKi8KK3ZvaWQgU1BJOjpTZXRNU0JGaXJzdCgpIHsKKyAgbV9tc2JGaXJzdCA9IHRydWU7CisgIHNwaVNldE9wdHMobV9wb3J0LCAoaW50KW1fbXNiRmlyc3QsIChpbnQpbV9zYW1wbGVPblRyYWlsaW5nLAorICAgICAgICAgICAgIChpbnQpbV9jbGtfaWRsZV9oaWdoKTsKK30KKworLyoqCisgKiBDb25maWd1cmUgdGhlIG9yZGVyIHRoYXQgYml0cyBhcmUgc2VudCBhbmQgcmVjZWl2ZWQgb24gdGhlIHdpcmUKKyAqIHRvIGJlIGxlYXN0IHNpZ25pZmljYW50IGJpdCBmaXJzdC4KKyAqLwordm9pZCBTUEk6OlNldExTQkZpcnN0KCkgeworICBtX21zYkZpcnN0ID0gZmFsc2U7CisgIHNwaVNldE9wdHMobV9wb3J0LCAoaW50KW1fbXNiRmlyc3QsIChpbnQpbV9zYW1wbGVPblRyYWlsaW5nLAorICAgICAgICAgICAgIChpbnQpbV9jbGtfaWRsZV9oaWdoKTsKK30KKworLyoqCisgKiBDb25maWd1cmUgdGhhdCB0aGUgZGF0YSBpcyBzdGFibGUgb24gdGhlIGZhbGxpbmcgZWRnZSBhbmQgdGhlIGRhdGEKKyAqIGNoYW5nZXMgb24gdGhlIHJpc2luZyBlZGdlLgorICovCit2b2lkIFNQSTo6U2V0U2FtcGxlRGF0YU9uRmFsbGluZygpIHsKKyAgbV9zYW1wbGVPblRyYWlsaW5nID0gdHJ1ZTsKKyAgc3BpU2V0T3B0cyhtX3BvcnQsIChpbnQpbV9tc2JGaXJzdCwgKGludCltX3NhbXBsZU9uVHJhaWxpbmcsCisgICAgICAgICAgICAgKGludCltX2Nsa19pZGxlX2hpZ2gpOworfQorCisvKioKKyAqIENvbmZpZ3VyZSB0aGF0IHRoZSBkYXRhIGlzIHN0YWJsZSBvbiB0aGUgcmlzaW5nIGVkZ2UgYW5kIHRoZSBkYXRhCisgKiBjaGFuZ2VzIG9uIHRoZSBmYWxsaW5nIGVkZ2UuCisgKi8KK3ZvaWQgU1BJOjpTZXRTYW1wbGVEYXRhT25SaXNpbmcoKSB7CisgIG1fc2FtcGxlT25UcmFpbGluZyA9IGZhbHNlOworICBzcGlTZXRPcHRzKG1fcG9ydCwgKGludCltX21zYkZpcnN0LCAoaW50KW1fc2FtcGxlT25UcmFpbGluZywKKyAgICAgICAgICAgICAoaW50KW1fY2xrX2lkbGVfaGlnaCk7Cit9CisKKy8qKgorICogQ29uZmlndXJlIHRoZSBjbG9jayBvdXRwdXQgbGluZSB0byBiZSBhY3RpdmUgbG93LgorICogVGhpcyBpcyBzb21ldGltZXMgY2FsbGVkIGNsb2NrIHBvbGFyaXR5IGhpZ2ggb3IgY2xvY2sgaWRsZSBoaWdoLgorICovCit2b2lkIFNQSTo6U2V0Q2xvY2tBY3RpdmVMb3coKSB7CisgIG1fY2xrX2lkbGVfaGlnaCA9IHRydWU7CisgIHNwaVNldE9wdHMobV9wb3J0LCAoaW50KW1fbXNiRmlyc3QsIChpbnQpbV9zYW1wbGVPblRyYWlsaW5nLAorICAgICAgICAgICAgIChpbnQpbV9jbGtfaWRsZV9oaWdoKTsKK30KKworLyoqCisgKiBDb25maWd1cmUgdGhlIGNsb2NrIG91dHB1dCBsaW5lIHRvIGJlIGFjdGl2ZSBoaWdoLgorICogVGhpcyBpcyBzb21ldGltZXMgY2FsbGVkIGNsb2NrIHBvbGFyaXR5IGxvdyBvciBjbG9jayBpZGxlIGxvdy4KKyAqLwordm9pZCBTUEk6OlNldENsb2NrQWN0aXZlSGlnaCgpIHsKKyAgbV9jbGtfaWRsZV9oaWdoID0gZmFsc2U7CisgIHNwaVNldE9wdHMobV9wb3J0LCAoaW50KW1fbXNiRmlyc3QsIChpbnQpbV9zYW1wbGVPblRyYWlsaW5nLAorICAgICAgICAgICAgIChpbnQpbV9jbGtfaWRsZV9oaWdoKTsKK30KKworLyoqCisgKiBDb25maWd1cmUgdGhlIGNoaXAgc2VsZWN0IGxpbmUgdG8gYmUgYWN0aXZlIGhpZ2guCisgKi8KK3ZvaWQgU1BJOjpTZXRDaGlwU2VsZWN0QWN0aXZlSGlnaCgpIHsKKyAgaW50MzJfdCBzdGF0dXMgPSAwOworICBzcGlTZXRDaGlwU2VsZWN0QWN0aXZlSGlnaChtX3BvcnQsICZzdGF0dXMpOworICB3cGlfc2V0RXJyb3JXaXRoQ29udGV4dChzdGF0dXMsIGdldEhBTEVycm9yTWVzc2FnZShzdGF0dXMpKTsKK30KKworLyoqCisgKiBDb25maWd1cmUgdGhlIGNoaXAgc2VsZWN0IGxpbmUgdG8gYmUgYWN0aXZlIGxvdy4KKyAqLwordm9pZCBTUEk6OlNldENoaXBTZWxlY3RBY3RpdmVMb3coKSB7CisgIGludDMyX3Qgc3RhdHVzID0gMDsKKyAgc3BpU2V0Q2hpcFNlbGVjdEFjdGl2ZUxvdyhtX3BvcnQsICZzdGF0dXMpOworICB3cGlfc2V0RXJyb3JXaXRoQ29udGV4dChzdGF0dXMsIGdldEhBTEVycm9yTWVzc2FnZShzdGF0dXMpKTsKK30KKworLyoqCisgKiBXcml0ZSBkYXRhIHRvIHRoZSBzbGF2ZSBkZXZpY2UuICBCbG9ja3MgdW50aWwgdGhlcmUgaXMgc3BhY2UgaW4gdGhlCisgKiBvdXRwdXQgRklGTy4KKyAqCisgKiBJZiBub3QgcnVubmluZyBpbiBvdXRwdXQgb25seSBtb2RlLCBhbHNvIHNhdmVzIHRoZSBkYXRhIHJlY2VpdmVkCisgKiBvbiB0aGUgTUlTTyBpbnB1dCBkdXJpbmcgdGhlIHRyYW5zZmVyIGludG8gdGhlIHJlY2VpdmUgRklGTy4KKyAqLworaW50MzJfdCBTUEk6OldyaXRlKHVpbnQ4X3QqIGRhdGEsIHVpbnQ4X3Qgc2l6ZSkgeworICBpbnQzMl90IHJldFZhbCA9IDA7CisgIHJldFZhbCA9IHNwaVdyaXRlKG1fcG9ydCwgZGF0YSwgc2l6ZSk7CisgIHJldHVybiByZXRWYWw7Cit9CisKKy8qKgorICogUmVhZCBhIHdvcmQgZnJvbSB0aGUgcmVjZWl2ZSBGSUZPLgorICoKKyAqIFdhaXRzIGZvciB0aGUgY3VycmVudCB0cmFuc2ZlciB0byBjb21wbGV0ZSBpZiB0aGUgcmVjZWl2ZSBGSUZPIGlzIGVtcHR5LgorICoKKyAqIElmIHRoZSByZWNlaXZlIEZJRk8gaXMgZW1wdHksIHRoZXJlIGlzIG5vIGFjdGl2ZSB0cmFuc2ZlciwgYW5kIGluaXRpYXRlCisgKiBpcyBmYWxzZSwgZXJyb3JzLgorICoKKyAqIEBwYXJhbSBpbml0aWF0ZQlJZiB0cnVlLCB0aGlzIGZ1bmN0aW9uIHB1c2hlcyAiMCIgaW50byB0aGUKKyAqIAkJCQkgICAgdHJhbnNtaXQgYnVmZmVyIGFuZCBpbml0aWF0ZXMgYSB0cmFuc2Zlci4KKyAqIAkJCQkgICAgSWYgZmFsc2UsIHRoaXMgZnVuY3Rpb24gYXNzdW1lcyB0aGF0IGRhdGEgaXMKKyAqIAkJCQkgICAgYWxyZWFkeSBpbiB0aGUgcmVjZWl2ZSBGSUZPIGZyb20gYSBwcmV2aW91cworICogd3JpdGUuCisgKi8KK2ludDMyX3QgU1BJOjpSZWFkKGJvb2wgaW5pdGlhdGUsIHVpbnQ4X3QqIGRhdGFSZWNlaXZlZCwgdWludDhfdCBzaXplKSB7CisgIGludDMyX3QgcmV0VmFsID0gMDsKKyAgaWYgKGluaXRpYXRlKSB7CisgICAgYXV0byBkYXRhVG9TZW5kID0gbmV3IHVpbnQ4X3Rbc2l6ZV07CisgICAgbWVtc2V0KGRhdGFUb1NlbmQsIDAsIHNpemUpOworICAgIHJldFZhbCA9IHNwaVRyYW5zYWN0aW9uKG1fcG9ydCwgZGF0YVRvU2VuZCwgZGF0YVJlY2VpdmVkLCBzaXplKTsKKyAgfSBlbHNlCisgICAgcmV0VmFsID0gc3BpUmVhZChtX3BvcnQsIGRhdGFSZWNlaXZlZCwgc2l6ZSk7CisgIHJldHVybiByZXRWYWw7Cit9CisKKy8qKgorICogUGVyZm9ybSBhIHNpbXVsdGFuZW91cyByZWFkL3dyaXRlIHRyYW5zYWN0aW9uIHdpdGggdGhlIGRldmljZQorICoKKyAqIEBwYXJhbSBkYXRhVG9TZW5kIFRoZSBkYXRhIHRvIGJlIHdyaXR0ZW4gb3V0IHRvIHRoZSBkZXZpY2UKKyAqIEBwYXJhbSBkYXRhUmVjZWl2ZWQgQnVmZmVyIHRvIHJlY2VpdmUgZGF0YSBmcm9tIHRoZSBkZXZpY2UKKyAqIEBwYXJhbSBzaXplIFRoZSBsZW5ndGggb2YgdGhlIHRyYW5zYWN0aW9uLCBpbiBieXRlcworICovCitpbnQzMl90IFNQSTo6VHJhbnNhY3Rpb24odWludDhfdCogZGF0YVRvU2VuZCwgdWludDhfdCogZGF0YVJlY2VpdmVkLAorICAgICAgICAgICAgICAgICAgICAgICAgIHVpbnQ4X3Qgc2l6ZSkgeworICBpbnQzMl90IHJldFZhbCA9IDA7CisgIHJldFZhbCA9IHNwaVRyYW5zYWN0aW9uKG1fcG9ydCwgZGF0YVRvU2VuZCwgZGF0YVJlY2VpdmVkLCBzaXplKTsKKyAgcmV0dXJuIHJldFZhbDsKK30KKworLyoqCisgKiBJbml0aWFsaXplIHRoZSBhY2N1bXVsYXRvci4KKyAqCisgKiBAcGFyYW0gcGVyaW9kIFRpbWUgYmV0d2VlbiByZWFkcworICogQHBhcmFtIGNtZCBTUEkgY29tbWFuZCB0byBzZW5kIHRvIHJlcXVlc3QgZGF0YQorICogQHBhcmFtIHhmZXJfc2l6ZSBTUEkgdHJhbnNmZXIgc2l6ZSwgaW4gYnl0ZXMKKyAqIEBwYXJhbSB2YWxpZF9tYXNrIE1hc2sgdG8gYXBwbHkgdG8gcmVjZWl2ZWQgZGF0YSBmb3IgdmFsaWRpdHkgY2hlY2tpbmcKKyAqIEBwYXJhbSB2YWxpZF9kYXRhIEFmdGVyIHZhbGlkX21hc2sgaXMgYXBwbGllZCwgcmVxdWlyZWQgbWF0Y2hpbmcgdmFsdWUgZm9yCisgKiAgICAgICAgICAgICAgICAgICB2YWxpZGl0eSBjaGVja2luZworICogQHBhcmFtIGRhdGFfc2hpZnQgQml0IHNoaWZ0IHRvIGFwcGx5IHRvIHJlY2VpdmVkIGRhdGEgdG8gZ2V0IGFjdHVhbCBkYXRhCisgKiAgICAgICAgICAgICAgICAgICB2YWx1ZQorICogQHBhcmFtIGRhdGFfc2l6ZSBTaXplIChpbiBiaXRzKSBvZiBkYXRhIGZpZWxkCisgKiBAcGFyYW0gaXNfc2lnbmVkIElzIGRhdGEgZmllbGQgc2lnbmVkPworICogQHBhcmFtIGJpZ19lbmRpYW4gSXMgZGV2aWNlIGJpZyBlbmRpYW4/CisgKi8KK3ZvaWQgU1BJOjpJbml0QWNjdW11bGF0b3IoZG91YmxlIHBlcmlvZCwgdWludDMyX3QgY21kLCB1aW50OF90IHhmZXJfc2l6ZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgdWludDMyX3QgdmFsaWRfbWFzaywgdWludDMyX3QgdmFsaWRfdmFsdWUsCisgICAgICAgICAgICAgICAgICAgICAgICAgIHVpbnQ4X3QgZGF0YV9zaGlmdCwgdWludDhfdCBkYXRhX3NpemUsIGJvb2wgaXNfc2lnbmVkLAorICAgICAgICAgICAgICAgICAgICAgICAgICBib29sIGJpZ19lbmRpYW4pIHsKKyAgaW50MzJfdCBzdGF0dXMgPSAwOworICBzcGlJbml0QWNjdW11bGF0b3IobV9wb3J0LCAodWludDMyX3QpKHBlcmlvZCAqIDFlNiksIGNtZCwgeGZlcl9zaXplLAorICAgICAgICAgICAgICAgICAgICAgdmFsaWRfbWFzaywgdmFsaWRfdmFsdWUsIGRhdGFfc2hpZnQsIGRhdGFfc2l6ZSwgaXNfc2lnbmVkLAorICAgICAgICAgICAgICAgICAgICAgYmlnX2VuZGlhbiwgJnN0YXR1cyk7CisgIHdwaV9zZXRFcnJvcldpdGhDb250ZXh0KHN0YXR1cywgZ2V0SEFMRXJyb3JNZXNzYWdlKHN0YXR1cykpOworfQorCisvKioKKyAqIEZyZWVzIHRoZSBhY2N1bXVsYXRvci4KKyAqLwordm9pZCBTUEk6OkZyZWVBY2N1bXVsYXRvcigpIHsKKyAgaW50MzJfdCBzdGF0dXMgPSAwOworICBzcGlGcmVlQWNjdW11bGF0b3IobV9wb3J0LCAmc3RhdHVzKTsKKyAgd3BpX3NldEVycm9yV2l0aENvbnRleHQoc3RhdHVzLCBnZXRIQUxFcnJvck1lc3NhZ2Uoc3RhdHVzKSk7Cit9CisKKy8qKgorICogUmVzZXRzIHRoZSBhY2N1bXVsYXRvciB0byB6ZXJvLgorICovCit2b2lkIFNQSTo6UmVzZXRBY2N1bXVsYXRvcigpIHsKKyAgaW50MzJfdCBzdGF0dXMgPSAwOworICBzcGlSZXNldEFjY3VtdWxhdG9yKG1fcG9ydCwgJnN0YXR1cyk7CisgIHdwaV9zZXRFcnJvcldpdGhDb250ZXh0KHN0YXR1cywgZ2V0SEFMRXJyb3JNZXNzYWdlKHN0YXR1cykpOworfQorCisvKioKKyAqIFNldCB0aGUgY2VudGVyIHZhbHVlIG9mIHRoZSBhY2N1bXVsYXRvci4KKyAqCisgKiBUaGUgY2VudGVyIHZhbHVlIGlzIHN1YnRyYWN0ZWQgZnJvbSBlYWNoIHZhbHVlIGJlZm9yZSBpdCBpcyBhZGRlZCB0byB0aGUgYWNjdW11bGF0b3IuIFRoaXMKKyAqIGlzIHVzZWQgZm9yIHRoZSBjZW50ZXIgdmFsdWUgb2YgZGV2aWNlcyBsaWtlIGd5cm9zIGFuZCBhY2NlbGVyb21ldGVycyB0byBtYWtlIGludGVncmF0aW9uIHdvcmsKKyAqIGFuZCB0byB0YWtlIHRoZSBkZXZpY2Ugb2Zmc2V0IGludG8gYWNjb3VudCB3aGVuIGludGVncmF0aW5nLgorICovCit2b2lkIFNQSTo6U2V0QWNjdW11bGF0b3JDZW50ZXIoaW50MzJfdCBjZW50ZXIpIHsKKyAgaW50MzJfdCBzdGF0dXMgPSAwOworICBzcGlTZXRBY2N1bXVsYXRvckNlbnRlcihtX3BvcnQsIGNlbnRlciwgJnN0YXR1cyk7CisgIHdwaV9zZXRFcnJvcldpdGhDb250ZXh0KHN0YXR1cywgZ2V0SEFMRXJyb3JNZXNzYWdlKHN0YXR1cykpOworfQorCisvKioKKyAqIFNldCB0aGUgYWNjdW11bGF0b3IncyBkZWFkYmFuZC4KKyAqLwordm9pZCBTUEk6OlNldEFjY3VtdWxhdG9yRGVhZGJhbmQoaW50MzJfdCBkZWFkYmFuZCkgeworICBpbnQzMl90IHN0YXR1cyA9IDA7CisgIHNwaVNldEFjY3VtdWxhdG9yRGVhZGJhbmQobV9wb3J0LCBkZWFkYmFuZCwgJnN0YXR1cyk7CisgIHdwaV9zZXRFcnJvcldpdGhDb250ZXh0KHN0YXR1cywgZ2V0SEFMRXJyb3JNZXNzYWdlKHN0YXR1cykpOworfQorCisvKioKKyAqIFJlYWQgdGhlIGxhc3QgdmFsdWUgcmVhZCBieSB0aGUgYWNjdW11bGF0b3IgZW5naW5lLgorICovCitpbnQzMl90IFNQSTo6R2V0QWNjdW11bGF0b3JMYXN0VmFsdWUoKSBjb25zdCB7CisgIGludDMyX3Qgc3RhdHVzID0gMDsKKyAgaW50MzJfdCByZXRWYWwgPSBzcGlHZXRBY2N1bXVsYXRvckxhc3RWYWx1ZShtX3BvcnQsICZzdGF0dXMpOworICB3cGlfc2V0RXJyb3JXaXRoQ29udGV4dChzdGF0dXMsIGdldEhBTEVycm9yTWVzc2FnZShzdGF0dXMpKTsKKyAgcmV0dXJuIHJldFZhbDsKK30KKworLyoqCisgKiBSZWFkIHRoZSBhY2N1bXVsYXRlZCB2YWx1ZS4KKyAqCisgKiBAcmV0dXJuIFRoZSA2NC1iaXQgdmFsdWUgYWNjdW11bGF0ZWQgc2luY2UgdGhlIGxhc3QgUmVzZXQoKS4KKyAqLworaW50NjRfdCBTUEk6OkdldEFjY3VtdWxhdG9yVmFsdWUoKSBjb25zdCB7CisgIGludDMyX3Qgc3RhdHVzID0gMDsKKyAgaW50NjRfdCByZXRWYWwgPSBzcGlHZXRBY2N1bXVsYXRvclZhbHVlKG1fcG9ydCwgJnN0YXR1cyk7CisgIHdwaV9zZXRFcnJvcldpdGhDb250ZXh0KHN0YXR1cywgZ2V0SEFMRXJyb3JNZXNzYWdlKHN0YXR1cykpOworICByZXR1cm4gcmV0VmFsOworfQorCisvKioKKyAqIFJlYWQgdGhlIG51bWJlciBvZiBhY2N1bXVsYXRlZCB2YWx1ZXMuCisgKgorICogUmVhZCB0aGUgY291bnQgb2YgdGhlIGFjY3VtdWxhdGVkIHZhbHVlcyBzaW5jZSB0aGUgYWNjdW11bGF0b3Igd2FzIGxhc3QgUmVzZXQoKS4KKyAqCisgKiBAcmV0dXJuIFRoZSBudW1iZXIgb2YgdGltZXMgc2FtcGxlcyBmcm9tIHRoZSBjaGFubmVsIHdlcmUgYWNjdW11bGF0ZWQuCisgKi8KK3VpbnQzMl90IFNQSTo6R2V0QWNjdW11bGF0b3JDb3VudCgpIGNvbnN0IHsKKyAgaW50MzJfdCBzdGF0dXMgPSAwOworICB1aW50MzJfdCByZXRWYWwgPSBzcGlHZXRBY2N1bXVsYXRvckNvdW50KG1fcG9ydCwgJnN0YXR1cyk7CisgIHdwaV9zZXRFcnJvcldpdGhDb250ZXh0KHN0YXR1cywgZ2V0SEFMRXJyb3JNZXNzYWdlKHN0YXR1cykpOworICByZXR1cm4gcmV0VmFsOworfQorCisvKioKKyAqIFJlYWQgdGhlIGF2ZXJhZ2Ugb2YgdGhlIGFjY3VtdWxhdGVkIHZhbHVlLgorICoKKyAqIEByZXR1cm4gVGhlIGFjY3VtdWxhdGVkIGF2ZXJhZ2UgdmFsdWUgKHZhbHVlIC8gY291bnQpLgorICovCitkb3VibGUgU1BJOjpHZXRBY2N1bXVsYXRvckF2ZXJhZ2UoKSBjb25zdCB7CisgIGludDMyX3Qgc3RhdHVzID0gMDsKKyAgZG91YmxlIHJldFZhbCA9IHNwaUdldEFjY3VtdWxhdG9yQXZlcmFnZShtX3BvcnQsICZzdGF0dXMpOworICB3cGlfc2V0RXJyb3JXaXRoQ29udGV4dChzdGF0dXMsIGdldEhBTEVycm9yTWVzc2FnZShzdGF0dXMpKTsKKyAgcmV0dXJuIHJldFZhbDsKK30KKworLyoqCisgKiBSZWFkIHRoZSBhY2N1bXVsYXRlZCB2YWx1ZSBhbmQgdGhlIG51bWJlciBvZiBhY2N1bXVsYXRlZCB2YWx1ZXMgYXRvbWljYWxseS4KKyAqCisgKiBUaGlzIGZ1bmN0aW9uIHJlYWRzIHRoZSB2YWx1ZSBhbmQgY291bnQgYXRvbWljYWxseS4KKyAqIFRoaXMgY2FuIGJlIHVzZWQgZm9yIGF2ZXJhZ2luZy4KKyAqCisgKiBAcGFyYW0gdmFsdWUgUG9pbnRlciB0byB0aGUgNjQtYml0IGFjY3VtdWxhdGVkIG91dHB1dC4KKyAqIEBwYXJhbSBjb3VudCBQb2ludGVyIHRvIHRoZSBudW1iZXIgb2YgYWNjdW11bGF0aW9uIGN5Y2xlcy4KKyAqLwordm9pZCBTUEk6OkdldEFjY3VtdWxhdG9yT3V0cHV0KGludDY0X3QgJnZhbHVlLCB1aW50MzJfdCAmY291bnQpIGNvbnN0IHsKKyAgaW50MzJfdCBzdGF0dXMgPSAwOworICBzcGlHZXRBY2N1bXVsYXRvck91dHB1dChtX3BvcnQsICZ2YWx1ZSwgJmNvdW50LCAmc3RhdHVzKTsKKyAgd3BpX3NldEVycm9yV2l0aENvbnRleHQoc3RhdHVzLCBnZXRIQUxFcnJvck1lc3NhZ2Uoc3RhdHVzKSk7Cit9CmRpZmYgLS1naXQgYS93cGlsaWJjL0F0aGVuYS9zcmMvU2FmZVBXTS5jcHAgYi93cGlsaWJjL0F0aGVuYS9zcmMvU2FmZVBXTS5jcHAKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uODAxZTNlZQotLS0gL2Rldi9udWxsCisrKyBiL3dwaWxpYmMvQXRoZW5hL3NyYy9TYWZlUFdNLmNwcApAQCAtMCwwICsxLDgxIEBACisvKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qLworLyogQ29weXJpZ2h0IChjKSBGSVJTVCAyMDA4LiBBbGwgUmlnaHRzIFJlc2VydmVkLgorICovCisvKiBPcGVuIFNvdXJjZSBTb2Z0d2FyZSAtIG1heSBiZSBtb2RpZmllZCBhbmQgc2hhcmVkIGJ5IEZSQyB0ZWFtcy4gVGhlIGNvZGUgICAqLworLyogbXVzdCBiZSBhY2NvbXBhbmllZCBieSB0aGUgRklSU1QgQlNEIGxpY2Vuc2UgZmlsZSBpbiAkKFdJTkRfQkFTRSkvV1BJTGliLiAgKi8KKy8qLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovCisKKyNpbmNsdWRlICJTYWZlUFdNLmgiCisKKy8qKgorICogQ29uc3RydWN0b3IgZm9yIGEgU2FmZVBXTSBvYmplY3QgdGFraW5nIGEgY2hhbm5lbCBudW1iZXIuCisgKiBAcGFyYW0gY2hhbm5lbCBUaGUgUFdNIGNoYW5uZWwgbnVtYmVyIDAtOSBhcmUgb24tYm9hcmQsIDEwLTE5IGFyZSBvbiB0aGUgTVhQCisgKiBwb3J0CisgKi8KK1NhZmVQV006OlNhZmVQV00odWludDMyX3QgY2hhbm5lbCkgOiBQV00oY2hhbm5lbCkgeworICBtX3NhZmV0eUhlbHBlciA9IHN0ZDo6bWFrZV91bmlxdWU8TW90b3JTYWZldHlIZWxwZXI+KHRoaXMpOworICBtX3NhZmV0eUhlbHBlci0+U2V0U2FmZXR5RW5hYmxlZChmYWxzZSk7Cit9CisKKy8qKgorICogU2V0IHRoZSBleHBpcmF0aW9uIHRpbWUgZm9yIHRoZSBQV00gb2JqZWN0CisgKiBAcGFyYW0gdGltZW91dCBUaGUgdGltZW91dCAoaW4gc2Vjb25kcykgZm9yIHRoaXMgbW90b3Igb2JqZWN0CisgKi8KK3ZvaWQgU2FmZVBXTTo6U2V0RXhwaXJhdGlvbihmbG9hdCB0aW1lb3V0KSB7CisgIG1fc2FmZXR5SGVscGVyLT5TZXRFeHBpcmF0aW9uKHRpbWVvdXQpOworfQorCisvKioKKyAqIFJldHVybiB0aGUgZXhwaXJhdGlvbiB0aW1lIGZvciB0aGUgUFdNIG9iamVjdC4KKyAqIEByZXR1cm5zIFRoZSBleHBpcmF0aW9uIHRpbWUgdmFsdWUuCisgKi8KK2Zsb2F0IFNhZmVQV006OkdldEV4cGlyYXRpb24oKSBjb25zdCB7IHJldHVybiBtX3NhZmV0eUhlbHBlci0+R2V0RXhwaXJhdGlvbigpOyB9CisKKy8qKgorICogQ2hlY2sgaWYgdGhlIFBXTSBvYmplY3QgaXMgY3VycmVudGx5IGFsaXZlIG9yIHN0b3BwZWQgZHVlIHRvIGEgdGltZW91dC4KKyAqIEByZXR1cm5zIGEgYm9vbCB2YWx1ZSB0aGF0IGlzIHRydWUgaWYgdGhlIG1vdG9yIGhhcyBOT1QgdGltZWQgb3V0IGFuZCBzaG91bGQKKyAqIHN0aWxsCisgKiBiZSBydW5uaW5nLgorICovCitib29sIFNhZmVQV006OklzQWxpdmUoKSBjb25zdCB7IHJldHVybiBtX3NhZmV0eUhlbHBlci0+SXNBbGl2ZSgpOyB9CisKKy8qKgorICogU3RvcCB0aGUgbW90b3IgYXNzb2NpYXRlZCB3aXRoIHRoaXMgUFdNIG9iamVjdC4KKyAqIFRoaXMgaXMgY2FsbGVkIGJ5IHRoZSBNb3RvclNhZmV0eUhlbHBlciBvYmplY3Qgd2hlbiBpdCBoYXMgYSB0aW1lb3V0IGZvciB0aGlzCisgKiBQV00gYW5kIG5lZWRzIHRvCisgKiBzdG9wIGl0IGZyb20gcnVubmluZy4KKyAqLwordm9pZCBTYWZlUFdNOjpTdG9wTW90b3IoKSB7IFNldFJhdyhrUHdtRGlzYWJsZWQpOyB9CisKKy8qKgorICogRW5hYmxlL2Rpc2FibGUgbW90b3Igc2FmZXR5IGZvciB0aGlzIGRldmljZQorICogVHVybiBvbiBhbmQgb2ZmIHRoZSBtb3RvciBzYWZldHkgb3B0aW9uIGZvciB0aGlzIFBXTSBvYmplY3QuCisgKiBAcGFyYW0gZW5hYmxlZCBUcnVlIGlmIG1vdG9yIHNhZmV0eSBpcyBlbmZvcmNlZCBmb3IgdGhpcyBvYmplY3QKKyAqLwordm9pZCBTYWZlUFdNOjpTZXRTYWZldHlFbmFibGVkKGJvb2wgZW5hYmxlZCkgeworICBtX3NhZmV0eUhlbHBlci0+U2V0U2FmZXR5RW5hYmxlZChlbmFibGVkKTsKK30KKworLyoqCisgKiBDaGVjayBpZiBtb3RvciBzYWZldHkgaXMgZW5hYmxlZCBmb3IgdGhpcyBvYmplY3QKKyAqIEByZXR1cm5zIFRydWUgaWYgbW90b3Igc2FmZXR5IGlzIGVuZm9yY2VkIGZvciB0aGlzIG9iamVjdAorICovCitib29sIFNhZmVQV006OklzU2FmZXR5RW5hYmxlZCgpIGNvbnN0IHsKKyAgcmV0dXJuIG1fc2FmZXR5SGVscGVyLT5Jc1NhZmV0eUVuYWJsZWQoKTsKK30KKwordm9pZCBTYWZlUFdNOjpHZXREZXNjcmlwdGlvbihzdGQ6Om9zdHJpbmdzdHJlYW0mIGRlc2MpIGNvbnN0IHsKKyAgZGVzYyA8PCAiUFdNICIgPDwgR2V0Q2hhbm5lbCgpOworfQorCisvKioKKyAqIEZlZWQgdGhlIE1vdG9yU2FmZXR5IHRpbWVyIHdoZW4gc2V0dGluZyB0aGUgc3BlZWQuCisgKiBUaGlzIG1ldGhvZCBpcyBjYWxsZWQgYnkgdGhlIHN1YmNsYXNzIG1vdG9yIHdoZW5ldmVyIGl0IHVwZGF0ZXMgaXRzIHNwZWVkLAorICogdGhlcmVieSByZXNldGluZworICogdGhlIHRpbWVvdXQgdmFsdWUuCisgKiBAcGFyYW0gc3BlZWQgVmFsdWUgdG8gcGFzcyB0byB0aGUgUFdNIGNsYXNzCisgKi8KK3ZvaWQgU2FmZVBXTTo6U2V0U3BlZWQoZmxvYXQgc3BlZWQpIHsKKyAgUFdNOjpTZXRTcGVlZChzcGVlZCk7CisgIG1fc2FmZXR5SGVscGVyLT5GZWVkKCk7Cit9CmRpZmYgLS1naXQgYS93cGlsaWJjL0F0aGVuYS9zcmMvU2FtcGxlUm9ib3QuY3BwIGIvd3BpbGliYy9BdGhlbmEvc3JjL1NhbXBsZVJvYm90LmNwcApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4zN2IxMzRmCi0tLSAvZGV2L251bGwKKysrIGIvd3BpbGliYy9BdGhlbmEvc3JjL1NhbXBsZVJvYm90LmNwcApAQCAtMCwwICsxLDE1NSBAQAorLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi8KKy8qIENvcHlyaWdodCAoYykgRklSU1QgMjAwOC4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KKyAqLworLyogT3BlbiBTb3VyY2UgU29mdHdhcmUgLSBtYXkgYmUgbW9kaWZpZWQgYW5kIHNoYXJlZCBieSBGUkMgdGVhbXMuIFRoZSBjb2RlICAgKi8KKy8qIG11c3QgYmUgYWNjb21wYW5pZWQgYnkgdGhlIEZJUlNUIEJTRCBsaWNlbnNlIGZpbGUgaW4gJChXSU5EX0JBU0UpL1dQSUxpYi4gICovCisvKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qLworCisjaW5jbHVkZSAiU2FtcGxlUm9ib3QuaCIKKworI2luY2x1ZGUgIkRyaXZlclN0YXRpb24uaCIKKyNpbmNsdWRlICJUaW1lci5oIgorI2luY2x1ZGUgIlNtYXJ0RGFzaGJvYXJkL1NtYXJ0RGFzaGJvYXJkLmgiCisjaW5jbHVkZSAiTGl2ZVdpbmRvdy9MaXZlV2luZG93LmgiCisjaW5jbHVkZSAibmV0d29ya3RhYmxlcy9OZXR3b3JrVGFibGUuaCIKKworU2FtcGxlUm9ib3Q6OlNhbXBsZVJvYm90KCkgOiBtX3JvYm90TWFpbk92ZXJyaWRkZW4odHJ1ZSkge30KKworLyoqCisgKiBSb2JvdC13aWRlIGluaXRpYWxpemF0aW9uIGNvZGUgc2hvdWxkIGdvIGhlcmUuCisgKgorICogVXNlcnMgc2hvdWxkIG92ZXJyaWRlIHRoaXMgbWV0aG9kIGZvciBkZWZhdWx0IFJvYm90LXdpZGUgaW5pdGlhbGl6YXRpb24gd2hpY2gKKyAqIHdpbGwgYmUgY2FsbGVkIHdoZW4gdGhlIHJvYm90IGlzIGZpcnN0IHBvd2VyZWQgb24uIEl0IHdpbGwgYmUgY2FsbGVkIGV4YWN0bHkKKyAqIG9uZSB0aW1lLgorICoKKyAqIFdhcm5pbmc6IHRoZSBEcml2ZXIgU3RhdGlvbiAiUm9ib3QgQ29kZSIgbGlnaHQgYW5kIEZNUyAiUm9ib3QgUmVhZHkiCisgKiBpbmRpY2F0b3JzIHdpbGwgYmUgb2ZmIHVudGlsIFJvYm90SW5pdCgpIGV4aXRzLiBDb2RlIGluIFJvYm90SW5pdCgpIHRoYXQKKyAqIHdhaXRzIGZvciBlbmFibGUgd2lsbCBjYXVzZSB0aGUgcm9ib3QgdG8gbmV2ZXIgaW5kaWNhdGUgdGhhdCB0aGUgY29kZSBpcworICogcmVhZHksIGNhdXNpbmcgdGhlIHJvYm90IHRvIGJlIGJ5cGFzc2VkIGluIGEgbWF0Y2guCisgKi8KK3ZvaWQgU2FtcGxlUm9ib3Q6OlJvYm90SW5pdCgpIHsKKyAgcHJpbnRmKCJEZWZhdWx0ICVzKCkgbWV0aG9kLi4uIE92ZXJyaWRlIG1lIVxuIiwgX19GVU5DVElPTl9fKTsKK30KKworLyoqCisgKiBEaXNhYmxlZCBzaG91bGQgZ28gaGVyZS4KKyAqIFByb2dyYW1tZXJzIHNob3VsZCBvdmVycmlkZSB0aGlzIG1ldGhvZCB0byBydW4gY29kZSB0aGF0IHNob3VsZCBydW4gd2hpbGUgdGhlCisgKiBmaWVsZCBpcworICogZGlzYWJsZWQuCisgKi8KK3ZvaWQgU2FtcGxlUm9ib3Q6OkRpc2FibGVkKCkgeworICBwcmludGYoIkRlZmF1bHQgJXMoKSBtZXRob2QuLi4gT3ZlcnJpZGUgbWUhXG4iLCBfX0ZVTkNUSU9OX18pOworfQorCisvKioKKyAqIEF1dG9ub21vdXMgc2hvdWxkIGdvIGhlcmUuCisgKiBQcm9ncmFtbWVycyBzaG91bGQgb3ZlcnJpZGUgdGhpcyBtZXRob2QgdG8gcnVuIGNvZGUgdGhhdCBzaG91bGQgcnVuIHdoaWxlIHRoZQorICogZmllbGQgaXMKKyAqIGluIHRoZSBhdXRvbm9tb3VzIHBlcmlvZC4gVGhpcyB3aWxsIGJlIGNhbGxlZCBvbmNlIGVhY2ggdGltZSB0aGUgcm9ib3QgZW50ZXJzCisgKiB0aGUKKyAqIGF1dG9ub21vdXMgc3RhdGUuCisgKi8KK3ZvaWQgU2FtcGxlUm9ib3Q6OkF1dG9ub21vdXMoKSB7CisgIHByaW50ZigiRGVmYXVsdCAlcygpIG1ldGhvZC4uLiBPdmVycmlkZSBtZSFcbiIsIF9fRlVOQ1RJT05fXyk7Cit9CisKKy8qKgorICogT3BlcmF0b3IgY29udHJvbCAodGVsZS1vcGVyYXRlZCkgY29kZSBzaG91bGQgZ28gaGVyZS4KKyAqIFByb2dyYW1tZXJzIHNob3VsZCBvdmVycmlkZSB0aGlzIG1ldGhvZCB0byBydW4gY29kZSB0aGF0IHNob3VsZCBydW4gd2hpbGUgdGhlCisgKiBmaWVsZCBpcworICogaW4gdGhlIE9wZXJhdG9yIENvbnRyb2wgKHRlbGUtb3BlcmF0ZWQpIHBlcmlvZC4gVGhpcyBpcyBjYWxsZWQgb25jZSBlYWNoIHRpbWUKKyAqIHRoZSByb2JvdAorICogZW50ZXJzIHRoZSB0ZWxlb3Agc3RhdGUuCisgKi8KK3ZvaWQgU2FtcGxlUm9ib3Q6Ok9wZXJhdG9yQ29udHJvbCgpIHsKKyAgcHJpbnRmKCJEZWZhdWx0ICVzKCkgbWV0aG9kLi4uIE92ZXJyaWRlIG1lIVxuIiwgX19GVU5DVElPTl9fKTsKK30KKworLyoqCisgKiBUZXN0IHByb2dyYW0gc2hvdWxkIGdvIGhlcmUuCisgKiBQcm9ncmFtbWVycyBzaG91bGQgb3ZlcnJpZGUgdGhpcyBtZXRob2QgdG8gcnVuIGNvZGUgdGhhdCBleGVjdXRlcyB3aGlsZSB0aGUKKyAqIHJvYm90IGlzCisgKiBpbiB0ZXN0IG1vZGUuIFRoaXMgd2lsbCBiZSBjYWxsZWQgb25jZSB3aGVuZXZlciB0aGUgcm9ib3QgZW50ZXJzIHRlc3QgbW9kZQorICovCit2b2lkIFNhbXBsZVJvYm90OjpUZXN0KCkgeworICBwcmludGYoIkRlZmF1bHQgJXMoKSBtZXRob2QuLi4gT3ZlcnJpZGUgbWUhXG4iLCBfX0ZVTkNUSU9OX18pOworfQorCisvKioKKyAqIFJvYm90IG1haW4gcHJvZ3JhbSBmb3IgZnJlZS1mb3JtIHByb2dyYW1zLgorICoKKyAqIFRoaXMgc2hvdWxkIGJlIG92ZXJyaWRkZW4gYnkgdXNlciBzdWJjbGFzc2VzIGlmIHRoZSBpbnRlbnQgaXMgdG8gbm90IHVzZSB0aGUKKyAqIEF1dG9ub21vdXMoKSBhbmQKKyAqIE9wZXJhdG9yQ29udHJvbCgpIG1ldGhvZHMuIEluIHRoYXQgY2FzZSwgdGhlIHByb2dyYW0gaXMgcmVzcG9uc2libGUgZm9yCisgKiBzZW5zaW5nIHdoZW4gdG8gcnVuCisgKiB0aGUgYXV0b25vbW91cyBhbmQgb3BlcmF0b3IgY29udHJvbCBmdW5jdGlvbnMgaW4gdGhlaXIgcHJvZ3JhbS4KKyAqCisgKiBUaGlzIG1ldGhvZCB3aWxsIGJlIGNhbGxlZCBpbW1lZGlhdGVseSBhZnRlciB0aGUgY29uc3RydWN0b3IgaXMgY2FsbGVkLiBJZiBpdAorICogaGFzIG5vdCBiZWVuCisgKiBvdmVycmlkZGVuIGJ5IGEgdXNlciBzdWJjbGFzcyAoaS5lLiB0aGUgZGVmYXVsdCB2ZXJzaW9uIHJ1bnMpLCB0aGVuIHRoZQorICogQXV0b25vbW91cygpIGFuZAorICogT3BlcmF0b3JDb250cm9sKCkgbWV0aG9kcyB3aWxsIGJlIGNhbGxlZC4KKyAqLwordm9pZCBTYW1wbGVSb2JvdDo6Um9ib3RNYWluKCkgeyBtX3JvYm90TWFpbk92ZXJyaWRkZW4gPSBmYWxzZTsgfQorCisvKioKKyAqIFN0YXJ0IGEgY29tcGV0aXRpb24uCisgKiBUaGlzIGNvZGUgbmVlZHMgdG8gdHJhY2sgdGhlIG9yZGVyIG9mIHRoZSBmaWVsZCBzdGFydGluZyB0byBlbnN1cmUgdGhhdAorICogZXZlcnl0aGluZyBoYXBwZW5zCisgKiBpbiB0aGUgcmlnaHQgb3JkZXIuIFJlcGVhdGVkbHkgcnVuIHRoZSBjb3JyZWN0IG1ldGhvZCwgZWl0aGVyIEF1dG9ub21vdXMgb3IKKyAqIE9wZXJhdG9yQ29udHJvbAorICogb3IgVGVzdCB3aGVuIHRoZSByb2JvdCBpcyBlbmFibGVkLiBBZnRlciBydW5uaW5nIHRoZSBjb3JyZWN0IG1ldGhvZCwgd2FpdCBmb3IKKyAqIHNvbWUgc3RhdGUgdG8KKyAqIGNoYW5nZSwgZWl0aGVyIHRoZSBvdGhlciBtb2RlIHN0YXJ0cyBvciB0aGUgcm9ib3QgaXMgZGlzYWJsZWQuIFRoZW4gZ28gYmFjaworICogYW5kIHdhaXQgZm9yIHRoZQorICogcm9ib3QgdG8gYmUgZW5hYmxlZCBhZ2Fpbi4KKyAqLwordm9pZCBTYW1wbGVSb2JvdDo6U3RhcnRDb21wZXRpdGlvbigpIHsKKyAgTGl2ZVdpbmRvdyAqbHcgPSBMaXZlV2luZG93OjpHZXRJbnN0YW5jZSgpOworCisgIEhBTFJlcG9ydChIQUxVc2FnZVJlcG9ydGluZzo6a1Jlc291cmNlVHlwZV9GcmFtZXdvcmssCisgICAgICAgICAgICBIQUxVc2FnZVJlcG9ydGluZzo6a0ZyYW1ld29ya19TYW1wbGUpOworCisgIFNtYXJ0RGFzaGJvYXJkOjppbml0KCk7CisgIE5ldHdvcmtUYWJsZTo6R2V0VGFibGUoIkxpdmVXaW5kb3ciKQorICAgICAgLT5HZXRTdWJUYWJsZSgiflNUQVRVU34iKQorICAgICAgLT5QdXRCb29sZWFuKCJMVyBFbmFibGVkIiwgZmFsc2UpOworCisgIFJvYm90SW5pdCgpOworCisgIC8vIFRlbGwgdGhlIERTIHRoYXQgdGhlIHJvYm90IGlzIHJlYWR5IHRvIGJlIGVuYWJsZWQKKyAgSEFMTmV0d29ya0NvbW11bmljYXRpb25PYnNlcnZlVXNlclByb2dyYW1TdGFydGluZygpOworCisgIFJvYm90TWFpbigpOworCisgIGlmICghbV9yb2JvdE1haW5PdmVycmlkZGVuKSB7CisgICAgLy8gZmlyc3QgYW5kIG9uZS10aW1lIGluaXRpYWxpemF0aW9uCisgICAgbHctPlNldEVuYWJsZWQoZmFsc2UpOworCisgICAgd2hpbGUgKHRydWUpIHsKKyAgICAgIGlmIChJc0Rpc2FibGVkKCkpIHsKKyAgICAgICAgbV9kcy5JbkRpc2FibGVkKHRydWUpOworICAgICAgICBEaXNhYmxlZCgpOworICAgICAgICBtX2RzLkluRGlzYWJsZWQoZmFsc2UpOworICAgICAgICB3aGlsZSAoSXNEaXNhYmxlZCgpKSBtX2RzLldhaXRGb3JEYXRhKCk7CisgICAgICB9IGVsc2UgaWYgKElzQXV0b25vbW91cygpKSB7CisgICAgICAgIG1fZHMuSW5BdXRvbm9tb3VzKHRydWUpOworICAgICAgICBBdXRvbm9tb3VzKCk7CisgICAgICAgIG1fZHMuSW5BdXRvbm9tb3VzKGZhbHNlKTsKKyAgICAgICAgd2hpbGUgKElzQXV0b25vbW91cygpICYmIElzRW5hYmxlZCgpKSBtX2RzLldhaXRGb3JEYXRhKCk7CisgICAgICB9IGVsc2UgaWYgKElzVGVzdCgpKSB7CisgICAgICAgIGx3LT5TZXRFbmFibGVkKHRydWUpOworICAgICAgICBtX2RzLkluVGVzdCh0cnVlKTsKKyAgICAgICAgVGVzdCgpOworICAgICAgICBtX2RzLkluVGVzdChmYWxzZSk7CisgICAgICAgIHdoaWxlIChJc1Rlc3QoKSAmJiBJc0VuYWJsZWQoKSkgbV9kcy5XYWl0Rm9yRGF0YSgpOworICAgICAgICBsdy0+U2V0RW5hYmxlZChmYWxzZSk7CisgICAgICB9IGVsc2UgeworICAgICAgICBtX2RzLkluT3BlcmF0b3JDb250cm9sKHRydWUpOworICAgICAgICBPcGVyYXRvckNvbnRyb2woKTsKKyAgICAgICAgbV9kcy5Jbk9wZXJhdG9yQ29udHJvbChmYWxzZSk7CisgICAgICAgIHdoaWxlIChJc09wZXJhdG9yQ29udHJvbCgpICYmIElzRW5hYmxlZCgpKSBtX2RzLldhaXRGb3JEYXRhKCk7CisgICAgICB9CisgICAgfQorICB9Cit9CmRpZmYgLS1naXQgYS93cGlsaWJjL0F0aGVuYS9zcmMvU2Vuc29yQmFzZS5jcHAgYi93cGlsaWJjL0F0aGVuYS9zcmMvU2Vuc29yQmFzZS5jcHAKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMDVmOWY0ZgotLS0gL2Rldi9udWxsCisrKyBiL3dwaWxpYmMvQXRoZW5hL3NyYy9TZW5zb3JCYXNlLmNwcApAQCAtMCwwICsxLDE4MyBAQAorLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi8KKy8qIENvcHlyaWdodCAoYykgRklSU1QgMjAwOC4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KKyAqLworLyogT3BlbiBTb3VyY2UgU29mdHdhcmUgLSBtYXkgYmUgbW9kaWZpZWQgYW5kIHNoYXJlZCBieSBGUkMgdGVhbXMuIFRoZSBjb2RlICAgKi8KKy8qIG11c3QgYmUgYWNjb21wYW5pZWQgYnkgdGhlIEZJUlNUIEJTRCBsaWNlbnNlIGZpbGUgaW4gJChXSU5EX0JBU0UpL1dQSUxpYi4gICovCisvKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qLworCisjaW5jbHVkZSAiU2Vuc29yQmFzZS5oIgorCisjaW5jbHVkZSAiTmV0d29ya0NvbW11bmljYXRpb24vTG9hZE91dC5oIgorI2luY2x1ZGUgIldQSUVycm9ycy5oIgorI2luY2x1ZGUgIkhBTC9IQUwuaHBwIgorI2luY2x1ZGUgIkhBTC9Qb3J0LmgiCisKK2NvbnN0IHVpbnQzMl90IFNlbnNvckJhc2U6OmtEaWdpdGFsQ2hhbm5lbHM7Citjb25zdCB1aW50MzJfdCBTZW5zb3JCYXNlOjprQW5hbG9nSW5wdXRzOworY29uc3QgdWludDMyX3QgU2Vuc29yQmFzZTo6a1NvbGVub2lkQ2hhbm5lbHM7Citjb25zdCB1aW50MzJfdCBTZW5zb3JCYXNlOjprU29sZW5vaWRNb2R1bGVzOworY29uc3QgdWludDMyX3QgU2Vuc29yQmFzZTo6a1B3bUNoYW5uZWxzOworY29uc3QgdWludDMyX3QgU2Vuc29yQmFzZTo6a1JlbGF5Q2hhbm5lbHM7Citjb25zdCB1aW50MzJfdCBTZW5zb3JCYXNlOjprUERQQ2hhbm5lbHM7Citjb25zdCB1aW50MzJfdCBTZW5zb3JCYXNlOjprQ2hhc3Npc1Nsb3RzOworU2Vuc29yQmFzZSogU2Vuc29yQmFzZTo6bV9zaW5nbGV0b25MaXN0ID0gbnVsbHB0cjsKKworc3RhdGljIGJvb2wgcG9ydHNJbml0aWFsaXplZCA9IGZhbHNlOwordm9pZCogU2Vuc29yQmFzZTo6bV9kaWdpdGFsX3BvcnRzW2tEaWdpdGFsQ2hhbm5lbHNdOwordm9pZCogU2Vuc29yQmFzZTo6bV9yZWxheV9wb3J0c1trUmVsYXlDaGFubmVsc107Cit2b2lkKiBTZW5zb3JCYXNlOjptX3B3bV9wb3J0c1trUHdtQ2hhbm5lbHNdOworCisvKioKKyAqIENyZWF0ZXMgYW4gaW5zdGFuY2Ugb2YgdGhlIHNlbnNvciBiYXNlIGFuZCBnZXRzIGFuIEZQR0EgaGFuZGxlCisgKi8KK1NlbnNvckJhc2U6OlNlbnNvckJhc2UoKSB7CisgIGlmICghcG9ydHNJbml0aWFsaXplZCkgeworICAgIGZvciAodWludDMyX3QgaSA9IDA7IGkgPCBrRGlnaXRhbENoYW5uZWxzOyBpKyspIHsKKyAgICAgIHZvaWQqIHBvcnQgPSBnZXRQb3J0KGkpOworICAgICAgaW50MzJfdCBzdGF0dXMgPSAwOworICAgICAgbV9kaWdpdGFsX3BvcnRzW2ldID0gaW5pdGlhbGl6ZURpZ2l0YWxQb3J0KHBvcnQsICZzdGF0dXMpOworICAgICAgd3BpX3NldEVycm9yV2l0aENvbnRleHQoc3RhdHVzLCBnZXRIQUxFcnJvck1lc3NhZ2Uoc3RhdHVzKSk7CisgICAgICBmcmVlUG9ydChwb3J0KTsKKyAgICB9CisKKyAgICBmb3IgKHVpbnQzMl90IGkgPSAwOyBpIDwga1JlbGF5Q2hhbm5lbHM7IGkrKykgeworICAgICAgdm9pZCogcG9ydCA9IGdldFBvcnQoaSk7CisgICAgICBpbnQzMl90IHN0YXR1cyA9IDA7CisgICAgICBtX3JlbGF5X3BvcnRzW2ldID0gaW5pdGlhbGl6ZURpZ2l0YWxQb3J0KHBvcnQsICZzdGF0dXMpOworICAgICAgd3BpX3NldEVycm9yV2l0aENvbnRleHQoc3RhdHVzLCBnZXRIQUxFcnJvck1lc3NhZ2Uoc3RhdHVzKSk7CisgICAgICBmcmVlUG9ydChwb3J0KTsKKyAgICB9CisKKyAgICBmb3IgKHVpbnQzMl90IGkgPSAwOyBpIDwga1B3bUNoYW5uZWxzOyBpKyspIHsKKyAgICAgIHZvaWQqIHBvcnQgPSBnZXRQb3J0KGkpOworICAgICAgaW50MzJfdCBzdGF0dXMgPSAwOworICAgICAgbV9wd21fcG9ydHNbaV0gPSBpbml0aWFsaXplRGlnaXRhbFBvcnQocG9ydCwgJnN0YXR1cyk7CisgICAgICB3cGlfc2V0RXJyb3JXaXRoQ29udGV4dChzdGF0dXMsIGdldEhBTEVycm9yTWVzc2FnZShzdGF0dXMpKTsKKyAgICAgIGZyZWVQb3J0KHBvcnQpOworICAgIH0KKyAgfQorfQorCisvKioKKyAqIEFkZCBzZW5zb3IgdG8gdGhlIHNpbmdsZXRvbiBsaXN0LgorICogQWRkIHRoaXMgc2Vuc29yIHRvIHRoZSBsaXN0IG9mIHNpbmdsZXRvbnMgdGhhdCBuZWVkIHRvIGJlIGRlbGV0ZWQgd2hlbgorICogdGhlIHJvYm90IHByb2dyYW0gZXhpdHMuIEVhY2ggb2YgdGhlIHNlbnNvcnMgb24gdGhpcyBsaXN0IGFyZSBzaW5nbGV0b25zLAorICogdGhhdCBpcyB0aGV5IGFyZW4ndCBhbGxvY2F0ZWQgZGlyZWN0bHkgd2l0aCBuZXcsIGJ1dCBpbnN0ZWFkIGFyZSBhbGxvY2F0ZWQKKyAqIGJ5IHRoZSBzdGF0aWMgR2V0SW5zdGFuY2UgbWV0aG9kLiBBcyBhIHJlc3VsdCwgdGhleSBhcmUgbmV2ZXIgZGVsZXRlZCB3aGVuCisgKiB0aGUgcHJvZ3JhbSBleGl0cy4gQ29uc2VxdWVudGx5IHRoZXNlIHNlbnNvcnMgbWF5IHN0aWxsIGJlIGhvbGRpbmcgb250bworICogcmVzb3VyY2VzIGFuZCBuZWVkIHRvIGhhdmUgdGhlaXIgZGVzdHJ1Y3RvcnMgY2FsbGVkIGF0IHRoZSBlbmQgb2YgdGhlCisgKiBwcm9ncmFtLgorICovCit2b2lkIFNlbnNvckJhc2U6OkFkZFRvU2luZ2xldG9uTGlzdCgpIHsKKyAgbV9uZXh0U2luZ2xldG9uID0gbV9zaW5nbGV0b25MaXN0OworICBtX3NpbmdsZXRvbkxpc3QgPSB0aGlzOworfQorCisvKioKKyAqIERlbGV0ZSBhbGwgdGhlIHNpbmdsZXRvbiBjbGFzc2VzIG9uIHRoZSBsaXN0LgorICogQWxsIHRoZSBjbGFzc2VzIHRoYXQgd2VyZSBhbGxvY2F0ZWQgYXMgc2luZ2xldG9ucyBuZWVkIHRvIGJlIGRlbGV0ZWQgc28KKyAqIHRoZWlyIHJlc291cmNlcyBjYW4gYmUgZnJlZWQuCisgKi8KK3ZvaWQgU2Vuc29yQmFzZTo6RGVsZXRlU2luZ2xldG9ucygpIHsKKyAgZm9yIChTZW5zb3JCYXNlKiBuZXh0ID0gbV9zaW5nbGV0b25MaXN0OyBuZXh0ICE9IG51bGxwdHI7KSB7CisgICAgU2Vuc29yQmFzZSogdG1wID0gbmV4dDsKKyAgICBuZXh0ID0gbmV4dC0+bV9uZXh0U2luZ2xldG9uOworICAgIGRlbGV0ZSB0bXA7CisgIH0KKyAgbV9zaW5nbGV0b25MaXN0ID0gbnVsbHB0cjsKK30KKworLyoqCisgKiBDaGVjayB0aGF0IHRoZSBzb2xlbm9pZCBtb2R1bGUgbnVtYmVyIGlzIHZhbGlkLgorICoKKyAqIEByZXR1cm4gU29sZW5vaWQgbW9kdWxlIGlzIHZhbGlkIGFuZCBwcmVzZW50CisgKi8KK2Jvb2wgU2Vuc29yQmFzZTo6Q2hlY2tTb2xlbm9pZE1vZHVsZSh1aW50OF90IG1vZHVsZU51bWJlcikgeworICBpZiAobW9kdWxlTnVtYmVyIDwgNjQpIHJldHVybiB0cnVlOworICByZXR1cm4gZmFsc2U7Cit9CisKKy8qKgorICogQ2hlY2sgdGhhdCB0aGUgZGlnaXRhbCBjaGFubmVsIG51bWJlciBpcyB2YWxpZC4KKyAqIFZlcmlmeSB0aGF0IHRoZSBjaGFubmVsIG51bWJlciBpcyBvbmUgb2YgdGhlIGxlZ2FsIGNoYW5uZWwgbnVtYmVycy4gQ2hhbm5lbAorICogbnVtYmVycyBhcmUKKyAqIDEtYmFzZWQuCisgKgorICogQHJldHVybiBEaWdpdGFsIGNoYW5uZWwgaXMgdmFsaWQKKyAqLworYm9vbCBTZW5zb3JCYXNlOjpDaGVja0RpZ2l0YWxDaGFubmVsKHVpbnQzMl90IGNoYW5uZWwpIHsKKyAgaWYgKGNoYW5uZWwgPCBrRGlnaXRhbENoYW5uZWxzKSByZXR1cm4gdHJ1ZTsKKyAgcmV0dXJuIGZhbHNlOworfQorCisvKioKKyAqIENoZWNrIHRoYXQgdGhlIGRpZ2l0YWwgY2hhbm5lbCBudW1iZXIgaXMgdmFsaWQuCisgKiBWZXJpZnkgdGhhdCB0aGUgY2hhbm5lbCBudW1iZXIgaXMgb25lIG9mIHRoZSBsZWdhbCBjaGFubmVsIG51bWJlcnMuIENoYW5uZWwKKyAqIG51bWJlcnMgYXJlCisgKiAxLWJhc2VkLgorICoKKyAqIEByZXR1cm4gUmVsYXkgY2hhbm5lbCBpcyB2YWxpZAorICovCitib29sIFNlbnNvckJhc2U6OkNoZWNrUmVsYXlDaGFubmVsKHVpbnQzMl90IGNoYW5uZWwpIHsKKyAgaWYgKGNoYW5uZWwgPCBrUmVsYXlDaGFubmVscykgcmV0dXJuIHRydWU7CisgIHJldHVybiBmYWxzZTsKK30KKworLyoqCisgKiBDaGVjayB0aGF0IHRoZSBkaWdpdGFsIGNoYW5uZWwgbnVtYmVyIGlzIHZhbGlkLgorICogVmVyaWZ5IHRoYXQgdGhlIGNoYW5uZWwgbnVtYmVyIGlzIG9uZSBvZiB0aGUgbGVnYWwgY2hhbm5lbCBudW1iZXJzLiBDaGFubmVsCisgKiBudW1iZXJzIGFyZQorICogMS1iYXNlZC4KKyAqCisgKiBAcmV0dXJuIFBXTSBjaGFubmVsIGlzIHZhbGlkCisgKi8KK2Jvb2wgU2Vuc29yQmFzZTo6Q2hlY2tQV01DaGFubmVsKHVpbnQzMl90IGNoYW5uZWwpIHsKKyAgaWYgKGNoYW5uZWwgPCBrUHdtQ2hhbm5lbHMpIHJldHVybiB0cnVlOworICByZXR1cm4gZmFsc2U7Cit9CisKKy8qKgorICogQ2hlY2sgdGhhdCB0aGUgYW5hbG9nIGlucHV0IG51bWJlciBpcyB2YWx1ZS4KKyAqIFZlcmlmeSB0aGF0IHRoZSBhbmFsb2cgaW5wdXQgbnVtYmVyIGlzIG9uZSBvZiB0aGUgbGVnYWwgY2hhbm5lbCBudW1iZXJzLgorICogQ2hhbm5lbCBudW1iZXJzCisgKiBhcmUgMC1iYXNlZC4KKyAqCisgKiBAcmV0dXJuIEFuYWxvZyBjaGFubmVsIGlzIHZhbGlkCisgKi8KK2Jvb2wgU2Vuc29yQmFzZTo6Q2hlY2tBbmFsb2dJbnB1dCh1aW50MzJfdCBjaGFubmVsKSB7CisgIGlmIChjaGFubmVsIDwga0FuYWxvZ0lucHV0cykgcmV0dXJuIHRydWU7CisgIHJldHVybiBmYWxzZTsKK30KKworLyoqCisgKiBDaGVjayB0aGF0IHRoZSBhbmFsb2cgb3V0cHV0IG51bWJlciBpcyB2YWxpZC4KKyAqIFZlcmlmeSB0aGF0IHRoZSBhbmFsb2cgb3V0cHV0IG51bWJlciBpcyBvbmUgb2YgdGhlIGxlZ2FsIGNoYW5uZWwgbnVtYmVycy4KKyAqIENoYW5uZWwgbnVtYmVycworICogYXJlIDAtYmFzZWQuCisgKgorICogQHJldHVybiBBbmFsb2cgY2hhbm5lbCBpcyB2YWxpZAorICovCitib29sIFNlbnNvckJhc2U6OkNoZWNrQW5hbG9nT3V0cHV0KHVpbnQzMl90IGNoYW5uZWwpIHsKKyAgaWYgKGNoYW5uZWwgPCBrQW5hbG9nT3V0cHV0cykgcmV0dXJuIHRydWU7CisgIHJldHVybiBmYWxzZTsKK30KKworLyoqCisgKiBWZXJpZnkgdGhhdCB0aGUgc29sZW5vaWQgY2hhbm5lbCBudW1iZXIgaXMgd2l0aGluIGxpbWl0cy4KKyAqCisgKiBAcmV0dXJuIFNvbGVub2lkIGNoYW5uZWwgaXMgdmFsaWQKKyAqLworYm9vbCBTZW5zb3JCYXNlOjpDaGVja1NvbGVub2lkQ2hhbm5lbCh1aW50MzJfdCBjaGFubmVsKSB7CisgIGlmIChjaGFubmVsIDwga1NvbGVub2lkQ2hhbm5lbHMpIHJldHVybiB0cnVlOworICByZXR1cm4gZmFsc2U7Cit9CisKKy8qKgorICogVmVyaWZ5IHRoYXQgdGhlIHBvd2VyIGRpc3RyaWJ1dGlvbiBjaGFubmVsIG51bWJlciBpcyB3aXRoaW4gbGltaXRzLgorICoKKyAqIEByZXR1cm4gUERQIGNoYW5uZWwgaXMgdmFsaWQKKyAqLworYm9vbCBTZW5zb3JCYXNlOjpDaGVja1BEUENoYW5uZWwodWludDMyX3QgY2hhbm5lbCkgeworICBpZiAoY2hhbm5lbCA8IGtQRFBDaGFubmVscykgcmV0dXJuIHRydWU7CisgIHJldHVybiBmYWxzZTsKK30KZGlmZiAtLWdpdCBhL3dwaWxpYmMvQXRoZW5hL3NyYy9TZXJpYWxQb3J0LmNwcCBiL3dwaWxpYmMvQXRoZW5hL3NyYy9TZXJpYWxQb3J0LmNwcApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5jNGUyNTlhCi0tLSAvZGV2L251bGwKKysrIGIvd3BpbGliYy9BdGhlbmEvc3JjL1NlcmlhbFBvcnQuY3BwCkBAIC0wLDAgKzEsMjI4IEBACisvKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qLworLyogQ29weXJpZ2h0IChjKSBGSVJTVCAyMDA4LiBBbGwgUmlnaHRzIFJlc2VydmVkLgorICovCisvKiBPcGVuIFNvdXJjZSBTb2Z0d2FyZSAtIG1heSBiZSBtb2RpZmllZCBhbmQgc2hhcmVkIGJ5IEZSQyB0ZWFtcy4gVGhlIGNvZGUgICAqLworLyogbXVzdCBiZSBhY2NvbXBhbmllZCBieSB0aGUgRklSU1QgQlNEIGxpY2Vuc2UgZmlsZSBpbiAkKFdJTkRfQkFTRSkvV1BJTGliLiAgKi8KKy8qLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovCisKKyNpbmNsdWRlICJTZXJpYWxQb3J0LmgiCisKKyNpbmNsdWRlICJIQUwvSEFMLmhwcCIKKyNpbmNsdWRlIDxzdGRhcmcuaD4KKworLy8gc3RhdGljIFZpU3RhdHVzIF9WSV9GVU5DSCBpb0NvbXBsZXRlSGFuZGxlciAoVmlTZXNzaW9uIHZpLCBWaUV2ZW50VHlwZQorLy8gZXZlbnRUeXBlLCBWaUV2ZW50IGV2ZW50LCBWaUFkZHIgdXNlckhhbmRsZSk7CisKKy8qKgorICogQ3JlYXRlIGFuIGluc3RhbmNlIG9mIGEgU2VyaWFsIFBvcnQgY2xhc3MuCisgKgorICogQHBhcmFtIGJhdWRSYXRlIFRoZSBiYXVkIHJhdGUgdG8gY29uZmlndXJlIHRoZSBzZXJpYWwgcG9ydC4KKyAqIEBwYXJhbSBwb3J0IFRoZSBwaHlzaWNhbCBwb3J0IHRvIHVzZQorICogQHBhcmFtIGRhdGFCaXRzIFRoZSBudW1iZXIgb2YgZGF0YSBiaXRzIHBlciB0cmFuc2Zlci4gIFZhbGlkIHZhbHVlcyBhcmUKKyAqIGJldHdlZW4gNSBhbmQgOCBiaXRzLgorICogQHBhcmFtIHBhcml0eSBTZWxlY3QgdGhlIHR5cGUgb2YgcGFyaXR5IGNoZWNraW5nIHRvIHVzZS4KKyAqIEBwYXJhbSBzdG9wQml0cyBUaGUgbnVtYmVyIG9mIHN0b3AgYml0cyB0byB1c2UgYXMgZGVmaW5lZCBieSB0aGUgZW51bQorICogU3RvcEJpdHMuCisgKi8KK1NlcmlhbFBvcnQ6OlNlcmlhbFBvcnQodWludDMyX3QgYmF1ZFJhdGUsIFBvcnQgcG9ydCwgdWludDhfdCBkYXRhQml0cywKKyAgICAgICAgICAgICAgICAgICAgICAgU2VyaWFsUG9ydDo6UGFyaXR5IHBhcml0eSwgU2VyaWFsUG9ydDo6U3RvcEJpdHMgc3RvcEJpdHMpCit7CisgIGludDMyX3Qgc3RhdHVzID0gMDsKKworICBtX3BvcnQgPSBwb3J0OworCisgIHNlcmlhbEluaXRpYWxpemVQb3J0KHBvcnQsICZzdGF0dXMpOworICB3cGlfc2V0RXJyb3JXaXRoQ29udGV4dChzdGF0dXMsIGdldEhBTEVycm9yTWVzc2FnZShzdGF0dXMpKTsKKyAgc2VyaWFsU2V0QmF1ZFJhdGUocG9ydCwgYmF1ZFJhdGUsICZzdGF0dXMpOworICB3cGlfc2V0RXJyb3JXaXRoQ29udGV4dChzdGF0dXMsIGdldEhBTEVycm9yTWVzc2FnZShzdGF0dXMpKTsKKyAgc2VyaWFsU2V0RGF0YUJpdHMocG9ydCwgZGF0YUJpdHMsICZzdGF0dXMpOworICB3cGlfc2V0RXJyb3JXaXRoQ29udGV4dChzdGF0dXMsIGdldEhBTEVycm9yTWVzc2FnZShzdGF0dXMpKTsKKyAgc2VyaWFsU2V0UGFyaXR5KHBvcnQsIHBhcml0eSwgJnN0YXR1cyk7CisgIHdwaV9zZXRFcnJvcldpdGhDb250ZXh0KHN0YXR1cywgZ2V0SEFMRXJyb3JNZXNzYWdlKHN0YXR1cykpOworICBzZXJpYWxTZXRTdG9wQml0cyhwb3J0LCBzdG9wQml0cywgJnN0YXR1cyk7CisgIHdwaV9zZXRFcnJvcldpdGhDb250ZXh0KHN0YXR1cywgZ2V0SEFMRXJyb3JNZXNzYWdlKHN0YXR1cykpOworCisgIC8vIFNldCB0aGUgZGVmYXVsdCB0aW1lb3V0IHRvIDUgc2Vjb25kcy4KKyAgU2V0VGltZW91dCg1LjBmKTsKKworICAvLyBEb24ndCB3YWl0IHVudGlsIHRoZSBidWZmZXIgaXMgZnVsbCB0byB0cmFuc21pdC4KKyAgU2V0V3JpdGVCdWZmZXJNb2RlKGtGbHVzaE9uQWNjZXNzKTsKKworICBFbmFibGVUZXJtaW5hdGlvbigpOworCisgIC8vIHZpSW5zdGFsbEhhbmRsZXIobV9wb3J0SGFuZGxlLCBWSV9FVkVOVF9JT19DT01QTEVUSU9OLCBpb0NvbXBsZXRlSGFuZGxlciwKKyAgLy8gdGhpcyk7CisgIC8vIHZpRW5hYmxlRXZlbnQobV9wb3J0SGFuZGxlLCBWSV9FVkVOVF9JT19DT01QTEVUSU9OLCBWSV9ITkRMUiwgVklfbnVsbHB0cik7CisKKyAgSEFMUmVwb3J0KEhBTFVzYWdlUmVwb3J0aW5nOjprUmVzb3VyY2VUeXBlX1NlcmlhbFBvcnQsIDApOworfQorCisvKioKKyAqIERlc3RydWN0b3IuCisgKi8KK1NlcmlhbFBvcnQ6On5TZXJpYWxQb3J0KCkgeworICBpbnQzMl90IHN0YXR1cyA9IDA7CisgIHNlcmlhbENsb3NlKG1fcG9ydCwgJnN0YXR1cyk7CisgIHdwaV9zZXRFcnJvcldpdGhDb250ZXh0KHN0YXR1cywgZ2V0SEFMRXJyb3JNZXNzYWdlKHN0YXR1cykpOworfQorCisvKioKKyAqIFNldCB0aGUgdHlwZSBvZiBmbG93IGNvbnRyb2wgdG8gZW5hYmxlIG9uIHRoaXMgcG9ydC4KKyAqCisgKiBCeSBkZWZhdWx0LCBmbG93IGNvbnRyb2wgaXMgZGlzYWJsZWQuCisgKi8KK3ZvaWQgU2VyaWFsUG9ydDo6U2V0Rmxvd0NvbnRyb2woU2VyaWFsUG9ydDo6Rmxvd0NvbnRyb2wgZmxvd0NvbnRyb2wpIHsKKyAgaW50MzJfdCBzdGF0dXMgPSAwOworICBzZXJpYWxTZXRGbG93Q29udHJvbChtX3BvcnQsIGZsb3dDb250cm9sLCAmc3RhdHVzKTsKKyAgd3BpX3NldEVycm9yV2l0aENvbnRleHQoc3RhdHVzLCBnZXRIQUxFcnJvck1lc3NhZ2Uoc3RhdHVzKSk7Cit9CisKKy8qKgorICogRW5hYmxlIHRlcm1pbmF0aW9uIGFuZCBzcGVjaWZ5IHRoZSB0ZXJtaW5hdGlvbiBjaGFyYWN0ZXIuCisgKgorICogVGVybWluYXRpb24gaXMgY3VycmVudGx5IG9ubHkgaW1wbGVtZW50ZWQgZm9yIHJlY2VpdmUuCisgKiBXaGVuIHRoZSB0aGUgdGVybWluYXRvciBpcyByZWNpZXZlZCwgdGhlIFJlYWQoKSBvciBTY2FuZigpIHdpbGwgcmV0dXJuCisgKiAgIGZld2VyIGJ5dGVzIHRoYW4gcmVxdWVzdGVkLCBzdG9wcGluZyBhZnRlciB0aGUgdGVybWluYXRvci4KKyAqCisgKiBAcGFyYW0gdGVybWluYXRvciBUaGUgY2hhcmFjdGVyIHRvIHVzZSBmb3IgdGVybWluYXRpb24uCisgKi8KK3ZvaWQgU2VyaWFsUG9ydDo6RW5hYmxlVGVybWluYXRpb24oY2hhciB0ZXJtaW5hdG9yKSB7CisgIGludDMyX3Qgc3RhdHVzID0gMDsKKyAgc2VyaWFsRW5hYmxlVGVybWluYXRpb24obV9wb3J0LCB0ZXJtaW5hdG9yLCAmc3RhdHVzKTsKKyAgd3BpX3NldEVycm9yV2l0aENvbnRleHQoc3RhdHVzLCBnZXRIQUxFcnJvck1lc3NhZ2Uoc3RhdHVzKSk7Cit9CisKKy8qKgorICogRGlzYWJsZSB0ZXJtaW5hdGlvbiBiZWhhdmlvci4KKyAqLwordm9pZCBTZXJpYWxQb3J0OjpEaXNhYmxlVGVybWluYXRpb24oKSB7CisgIGludDMyX3Qgc3RhdHVzID0gMDsKKyAgc2VyaWFsRGlzYWJsZVRlcm1pbmF0aW9uKG1fcG9ydCwgJnN0YXR1cyk7CisgIHdwaV9zZXRFcnJvcldpdGhDb250ZXh0KHN0YXR1cywgZ2V0SEFMRXJyb3JNZXNzYWdlKHN0YXR1cykpOworfQorCisvKioKKyAqIEdldCB0aGUgbnVtYmVyIG9mIGJ5dGVzIGN1cnJlbnRseSBhdmFpbGFibGUgdG8gcmVhZCBmcm9tIHRoZSBzZXJpYWwgcG9ydC4KKyAqCisgKiBAcmV0dXJuIFRoZSBudW1iZXIgb2YgYnl0ZXMgYXZhaWxhYmxlIHRvIHJlYWQKKyAqLworaW50MzJfdCBTZXJpYWxQb3J0OjpHZXRCeXRlc1JlY2VpdmVkKCkgeworICBpbnQzMl90IHN0YXR1cyA9IDA7CisgIGludDMyX3QgcmV0VmFsID0gc2VyaWFsR2V0Qnl0ZXNSZWNlaXZlZChtX3BvcnQsICZzdGF0dXMpOworICB3cGlfc2V0RXJyb3JXaXRoQ29udGV4dChzdGF0dXMsIGdldEhBTEVycm9yTWVzc2FnZShzdGF0dXMpKTsKKyAgcmV0dXJuIHJldFZhbDsKK30KKworLyoqCisgKiBSZWFkIHJhdyBieXRlcyBvdXQgb2YgdGhlIGJ1ZmZlci4KKyAqCisgKiBAcGFyYW0gYnVmZmVyIFBvaW50ZXIgdG8gdGhlIGJ1ZmZlciB0byBzdG9yZSB0aGUgYnl0ZXMgaW4uCisgKiBAcGFyYW0gY291bnQgVGhlIG1heGltdW0gbnVtYmVyIG9mIGJ5dGVzIHRvIHJlYWQuCisgKiBAcmV0dXJuIFRoZSBudW1iZXIgb2YgYnl0ZXMgYWN0dWFsbHkgcmVhZCBpbnRvIHRoZSBidWZmZXIuCisgKi8KK3VpbnQzMl90IFNlcmlhbFBvcnQ6OlJlYWQoY2hhciAqYnVmZmVyLCBpbnQzMl90IGNvdW50KSB7CisgIGludDMyX3Qgc3RhdHVzID0gMDsKKyAgaW50MzJfdCByZXRWYWwgPSBzZXJpYWxSZWFkKG1fcG9ydCwgYnVmZmVyLCBjb3VudCwgJnN0YXR1cyk7CisgIHdwaV9zZXRFcnJvcldpdGhDb250ZXh0KHN0YXR1cywgZ2V0SEFMRXJyb3JNZXNzYWdlKHN0YXR1cykpOworICByZXR1cm4gcmV0VmFsOworfQorCisvKioKKyAqIFdyaXRlIHJhdyBieXRlcyB0byB0aGUgYnVmZmVyLgorICoKKyAqIEBwYXJhbSBidWZmZXIgUG9pbnRlciB0byB0aGUgYnVmZmVyIHRvIHJlYWQgdGhlIGJ5dGVzIGZyb20uCisgKiBAcGFyYW0gY291bnQgVGhlIG1heGltdW0gbnVtYmVyIG9mIGJ5dGVzIHRvIHdyaXRlLgorICogQHJldHVybiBUaGUgbnVtYmVyIG9mIGJ5dGVzIGFjdHVhbGx5IHdyaXR0ZW4gaW50byB0aGUgcG9ydC4KKyAqLwordWludDMyX3QgU2VyaWFsUG9ydDo6V3JpdGUoY29uc3Qgc3RkOjpzdHJpbmcgJmJ1ZmZlciwgaW50MzJfdCBjb3VudCkgeworICBpbnQzMl90IHN0YXR1cyA9IDA7CisgIGludDMyX3QgcmV0VmFsID0gc2VyaWFsV3JpdGUobV9wb3J0LCBidWZmZXIuY19zdHIoKSwgY291bnQsICZzdGF0dXMpOworICB3cGlfc2V0RXJyb3JXaXRoQ29udGV4dChzdGF0dXMsIGdldEhBTEVycm9yTWVzc2FnZShzdGF0dXMpKTsKKyAgcmV0dXJuIHJldFZhbDsKK30KKworLyoqCisgKiBDb25maWd1cmUgdGhlIHRpbWVvdXQgb2YgdGhlIHNlcmlhbCBwb3J0LgorICoKKyAqIFRoaXMgZGVmaW5lcyB0aGUgdGltZW91dCBmb3IgdHJhbnNhY3Rpb25zIHdpdGggdGhlIGhhcmR3YXJlLgorICogSXQgd2lsbCBhZmZlY3QgcmVhZHMgYW5kIHZlcnkgbGFyZ2Ugd3JpdGVzLgorICoKKyAqIEBwYXJhbSB0aW1lb3V0IFRoZSBudW1iZXIgb2Ygc2Vjb25kcyB0byB0byB3YWl0IGZvciBJL08uCisgKi8KK3ZvaWQgU2VyaWFsUG9ydDo6U2V0VGltZW91dChmbG9hdCB0aW1lb3V0KSB7CisgIGludDMyX3Qgc3RhdHVzID0gMDsKKyAgc2VyaWFsU2V0VGltZW91dChtX3BvcnQsIHRpbWVvdXQsICZzdGF0dXMpOworICB3cGlfc2V0RXJyb3JXaXRoQ29udGV4dChzdGF0dXMsIGdldEhBTEVycm9yTWVzc2FnZShzdGF0dXMpKTsKK30KKworLyoqCisgKiBTcGVjaWZ5IHRoZSBzaXplIG9mIHRoZSBpbnB1dCBidWZmZXIuCisgKgorICogU3BlY2lmeSB0aGUgYW1vdW50IG9mIGRhdGEgdGhhdCBjYW4gYmUgc3RvcmVkIGJlZm9yZSBkYXRhCisgKiBmcm9tIHRoZSBkZXZpY2UgaXMgcmV0dXJuZWQgdG8gUmVhZCBvciBTY2FuZi4gIElmIHlvdSB3YW50CisgKiBkYXRhIHRoYXQgaXMgcmVjaWV2ZWQgdG8gYmUgcmV0dXJuZWQgaW1tZWRpYXRlbHksIHNldCB0aGlzIHRvIDEuCisgKgorICogSXQgdGhlIGJ1ZmZlciBpcyBub3QgZmlsbGVkIGJlZm9yZSB0aGUgcmVhZCB0aW1lb3V0IGV4cGlyZXMsIGFsbAorICogZGF0YSB0aGF0IGhhcyBiZWVuIHJlY2VpdmVkIHNvIGZhciB3aWxsIGJlIHJldHVybmVkLgorICoKKyAqIEBwYXJhbSBzaXplIFRoZSByZWFkIGJ1ZmZlciBzaXplLgorICovCit2b2lkIFNlcmlhbFBvcnQ6OlNldFJlYWRCdWZmZXJTaXplKHVpbnQzMl90IHNpemUpIHsKKyAgaW50MzJfdCBzdGF0dXMgPSAwOworICBzZXJpYWxTZXRSZWFkQnVmZmVyU2l6ZShtX3BvcnQsIHNpemUsICZzdGF0dXMpOworICB3cGlfc2V0RXJyb3JXaXRoQ29udGV4dChzdGF0dXMsIGdldEhBTEVycm9yTWVzc2FnZShzdGF0dXMpKTsKK30KKworLyoqCisgKiBTcGVjaWZ5IHRoZSBzaXplIG9mIHRoZSBvdXRwdXQgYnVmZmVyLgorICoKKyAqIFNwZWNpZnkgdGhlIGFtb3VudCBvZiBkYXRhIHRoYXQgY2FuIGJlIHN0b3JlZCBiZWZvcmUgYmVpbmcKKyAqIHRyYW5zbWl0dGVkIHRvIHRoZSBkZXZpY2UuCisgKgorICogQHBhcmFtIHNpemUgVGhlIHdyaXRlIGJ1ZmZlciBzaXplLgorICovCit2b2lkIFNlcmlhbFBvcnQ6OlNldFdyaXRlQnVmZmVyU2l6ZSh1aW50MzJfdCBzaXplKSB7CisgIGludDMyX3Qgc3RhdHVzID0gMDsKKyAgc2VyaWFsU2V0V3JpdGVCdWZmZXJTaXplKG1fcG9ydCwgc2l6ZSwgJnN0YXR1cyk7CisgIHdwaV9zZXRFcnJvcldpdGhDb250ZXh0KHN0YXR1cywgZ2V0SEFMRXJyb3JNZXNzYWdlKHN0YXR1cykpOworfQorCisvKioKKyAqIFNwZWNpZnkgdGhlIGZsdXNoaW5nIGJlaGF2aW9yIG9mIHRoZSBvdXRwdXQgYnVmZmVyLgorICoKKyAqIFdoZW4gc2V0IHRvIGtGbHVzaE9uQWNjZXNzLCBkYXRhIGlzIHN5bmNocm9ub3VzbHkgd3JpdHRlbiB0byB0aGUgc2VyaWFsIHBvcnQKKyAqICAgYWZ0ZXIgZWFjaCBjYWxsIHRvIGVpdGhlciBQcmludGYoKSBvciBXcml0ZSgpLgorICoKKyAqIFdoZW4gc2V0IHRvIGtGbHVzaFdoZW5GdWxsLCBkYXRhIHdpbGwgb25seSBiZSB3cml0dGVuIHRvIHRoZSBzZXJpYWwgcG9ydCB3aGVuCisgKiAgIHRoZSBidWZmZXIgaXMgZnVsbCBvciB3aGVuIEZsdXNoKCkgaXMgY2FsbGVkLgorICoKKyAqIEBwYXJhbSBtb2RlIFRoZSB3cml0ZSBidWZmZXIgbW9kZS4KKyAqLwordm9pZCBTZXJpYWxQb3J0OjpTZXRXcml0ZUJ1ZmZlck1vZGUoU2VyaWFsUG9ydDo6V3JpdGVCdWZmZXJNb2RlIG1vZGUpIHsKKyAgaW50MzJfdCBzdGF0dXMgPSAwOworICBzZXJpYWxTZXRXcml0ZU1vZGUobV9wb3J0LCBtb2RlLCAmc3RhdHVzKTsKKyAgd3BpX3NldEVycm9yV2l0aENvbnRleHQoc3RhdHVzLCBnZXRIQUxFcnJvck1lc3NhZ2Uoc3RhdHVzKSk7Cit9CisKKy8qKgorICogRm9yY2UgdGhlIG91dHB1dCBidWZmZXIgdG8gYmUgd3JpdHRlbiB0byB0aGUgcG9ydC4KKyAqCisgKiBUaGlzIGlzIHVzZWQgd2hlbiBTZXRXcml0ZUJ1ZmZlck1vZGUoKSBpcyBzZXQgdG8ga0ZsdXNoV2hlbkZ1bGwgdG8gZm9yY2UgYQorICogZmx1c2ggYmVmb3JlIHRoZSBidWZmZXIgaXMgZnVsbC4KKyAqLwordm9pZCBTZXJpYWxQb3J0OjpGbHVzaCgpIHsKKyAgaW50MzJfdCBzdGF0dXMgPSAwOworICBzZXJpYWxGbHVzaChtX3BvcnQsICZzdGF0dXMpOworICB3cGlfc2V0RXJyb3JXaXRoQ29udGV4dChzdGF0dXMsIGdldEhBTEVycm9yTWVzc2FnZShzdGF0dXMpKTsKK30KKworLyoqCisgKiBSZXNldCB0aGUgc2VyaWFsIHBvcnQgZHJpdmVyIHRvIGEga25vd24gc3RhdGUuCisgKgorICogRW1wdHkgdGhlIHRyYW5zbWl0IGFuZCByZWNlaXZlIGJ1ZmZlcnMgaW4gdGhlIGRldmljZSBhbmQgZm9ybWF0dGVkIEkvTy4KKyAqLwordm9pZCBTZXJpYWxQb3J0OjpSZXNldCgpIHsKKyAgaW50MzJfdCBzdGF0dXMgPSAwOworICBzZXJpYWxDbGVhcihtX3BvcnQsICZzdGF0dXMpOworICB3cGlfc2V0RXJyb3JXaXRoQ29udGV4dChzdGF0dXMsIGdldEhBTEVycm9yTWVzc2FnZShzdGF0dXMpKTsKK30KZGlmZiAtLWdpdCBhL3dwaWxpYmMvQXRoZW5hL3NyYy9TZXJ2by5jcHAgYi93cGlsaWJjL0F0aGVuYS9zcmMvU2Vydm8uY3BwCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjQzMDBjYzQKLS0tIC9kZXYvbnVsbAorKysgYi93cGlsaWJjL0F0aGVuYS9zcmMvU2Vydm8uY3BwCkBAIC0wLDAgKzEsMTMyIEBACisvKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qLworLyogQ29weXJpZ2h0IChjKSBGSVJTVCAyMDA4LiBBbGwgUmlnaHRzIFJlc2VydmVkLgorICovCisvKiBPcGVuIFNvdXJjZSBTb2Z0d2FyZSAtIG1heSBiZSBtb2RpZmllZCBhbmQgc2hhcmVkIGJ5IEZSQyB0ZWFtcy4gVGhlIGNvZGUgICAqLworLyogbXVzdCBiZSBhY2NvbXBhbmllZCBieSB0aGUgRklSU1QgQlNEIGxpY2Vuc2UgZmlsZSBpbiAkKFdJTkRfQkFTRSkvV1BJTGliLiAgKi8KKy8qLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovCisKKyNpbmNsdWRlICJTZXJ2by5oIgorCisjaW5jbHVkZSAiTGl2ZVdpbmRvdy9MaXZlV2luZG93LmgiCisKK2NvbnN0ZXhwciBmbG9hdCBTZXJ2bzo6a01heFNlcnZvQW5nbGU7Citjb25zdGV4cHIgZmxvYXQgU2Vydm86OmtNaW5TZXJ2b0FuZ2xlOworCitjb25zdGV4cHIgZmxvYXQgU2Vydm86OmtEZWZhdWx0TWF4U2Vydm9QV007Citjb25zdGV4cHIgZmxvYXQgU2Vydm86OmtEZWZhdWx0TWluU2Vydm9QV007CisKKy8qKgorICogQHBhcmFtIGNoYW5uZWwgVGhlIFBXTSBjaGFubmVsIHRvIHdoaWNoIHRoZSBzZXJ2byBpcyBhdHRhY2hlZC4gMC05IGFyZQorICogb24tYm9hcmQsIDEwLTE5IGFyZSBvbiB0aGUgTVhQIHBvcnQKKyAqLworU2Vydm86OlNlcnZvKHVpbnQzMl90IGNoYW5uZWwpIDogU2FmZVBXTShjaGFubmVsKSB7CisgIC8vIFNldCBtaW5pbXVtIGFuZCBtYXhpbXVtIFBXTSB2YWx1ZXMgc3VwcG9ydGVkIGJ5IHRoZSBzZXJ2bworICBTZXRCb3VuZHMoa0RlZmF1bHRNYXhTZXJ2b1BXTSwgMC4wLCAwLjAsIDAuMCwga0RlZmF1bHRNaW5TZXJ2b1BXTSk7CisKKyAgLy8gQXNzaWduIGRlZmF1bHRzIGZvciBwZXJpb2QgbXVsdGlwbGllciBmb3IgdGhlIHNlcnZvIFBXTSBjb250cm9sIHNpZ25hbAorICBTZXRQZXJpb2RNdWx0aXBsaWVyKGtQZXJpb2RNdWx0aXBsaWVyXzRYKTsKKworICAvLwlwcmludGYoIkRvbmUgaW5pdGlhbGl6aW5nIHNlcnZvICVkXG4iLCBjaGFubmVsKTsKK30KKworU2Vydm86On5TZXJ2bygpIHsKKyAgaWYgKG1fdGFibGUgIT0gbnVsbHB0cikgeworICAgIG1fdGFibGUtPlJlbW92ZVRhYmxlTGlzdGVuZXIodGhpcyk7CisgIH0KK30KKworLyoqCisgKiBTZXQgdGhlIHNlcnZvIHBvc2l0aW9uLgorICoKKyAqIFNlcnZvIHZhbHVlcyByYW5nZSBmcm9tIDAuMCB0byAxLjAgY29ycmVzcG9uZGluZyB0byB0aGUgcmFuZ2Ugb2YgZnVsbCBsZWZ0IHRvCisgKiBmdWxsIHJpZ2h0LgorICoKKyAqIEBwYXJhbSB2YWx1ZSBQb3NpdGlvbiBmcm9tIDAuMCB0byAxLjAuCisgKi8KK3ZvaWQgU2Vydm86OlNldChmbG9hdCB2YWx1ZSkgeyBTZXRQb3NpdGlvbih2YWx1ZSk7IH0KKworLyoqCisgKiBTZXQgdGhlIHNlcnZvIHRvIG9mZmxpbmUuCisgKgorICogU2V0IHRoZSBzZXJ2byByYXcgdmFsdWUgdG8gMCAodW5kcml2ZW4pCisgKi8KK3ZvaWQgU2Vydm86OlNldE9mZmxpbmUoKSB7IFNldFJhdygwKTsgfQorCisvKioKKyAqIEdldCB0aGUgc2Vydm8gcG9zaXRpb24uCisgKgorICogU2Vydm8gdmFsdWVzIHJhbmdlIGZyb20gMC4wIHRvIDEuMCBjb3JyZXNwb25kaW5nIHRvIHRoZSByYW5nZSBvZiBmdWxsIGxlZnQgdG8KKyAqIGZ1bGwgcmlnaHQuCisgKgorICogQHJldHVybiBQb3NpdGlvbiBmcm9tIDAuMCB0byAxLjAuCisgKi8KK2Zsb2F0IFNlcnZvOjpHZXQoKSBjb25zdCB7IHJldHVybiBHZXRQb3NpdGlvbigpOyB9CisKKy8qKgorICogU2V0IHRoZSBzZXJ2byBhbmdsZS4KKyAqCisgKiBBc3N1bWUgdGhhdCB0aGUgc2Vydm8gYW5nbGUgaXMgbGluZWFyIHdpdGggcmVzcGVjdCB0byB0aGUgUFdNIHZhbHVlIChiaWcKKyAqIGFzc3VtcHRpb24sIG5lZWQgdG8gdGVzdCkuCisgKgorICogU2Vydm8gYW5nbGVzIHRoYXQgYXJlIG91dCBvZiB0aGUgc3VwcG9ydGVkIHJhbmdlIG9mIHRoZSBzZXJ2byBzaW1wbHkKKyAqICJzYXR1cmF0ZSIgaW4gdGhhdCBkaXJlY3Rpb24KKyAqIEluIG90aGVyIHdvcmRzLCBpZiB0aGUgc2Vydm8gaGFzIGEgcmFuZ2Ugb2YgKFggZGVncmVlcyB0byBZIGRlZ3JlZXMpIHRoYW4KKyAqIGFuZ2xlcyBvZiBsZXNzIHRoYW4gWAorICogcmVzdWx0IGluIGFuIGFuZ2xlIG9mIFggYmVpbmcgc2V0IGFuZCBhbmdsZXMgb2YgbW9yZSB0aGFuIFkgZGVncmVlcyByZXN1bHQgaW4KKyAqIGFuIGFuZ2xlIG9mIFkgYmVpbmcgc2V0LgorICoKKyAqIEBwYXJhbSBkZWdyZWVzIFRoZSBhbmdsZSBpbiBkZWdyZWVzIHRvIHNldCB0aGUgc2Vydm8uCisgKi8KK3ZvaWQgU2Vydm86OlNldEFuZ2xlKGZsb2F0IGRlZ3JlZXMpIHsKKyAgaWYgKGRlZ3JlZXMgPCBrTWluU2Vydm9BbmdsZSkgeworICAgIGRlZ3JlZXMgPSBrTWluU2Vydm9BbmdsZTsKKyAgfSBlbHNlIGlmIChkZWdyZWVzID4ga01heFNlcnZvQW5nbGUpIHsKKyAgICBkZWdyZWVzID0ga01heFNlcnZvQW5nbGU7CisgIH0KKworICBTZXRQb3NpdGlvbigoKGZsb2F0KShkZWdyZWVzIC0ga01pblNlcnZvQW5nbGUpKSAvIEdldFNlcnZvQW5nbGVSYW5nZSgpKTsKK30KKworLyoqCisgKiBHZXQgdGhlIHNlcnZvIGFuZ2xlLgorICoKKyAqIEFzc3VtZSB0aGF0IHRoZSBzZXJ2byBhbmdsZSBpcyBsaW5lYXIgd2l0aCByZXNwZWN0IHRvIHRoZSBQV00gdmFsdWUgKGJpZworICogYXNzdW1wdGlvbiwgbmVlZCB0byB0ZXN0KS4KKyAqIEByZXR1cm4gVGhlIGFuZ2xlIGluIGRlZ3JlZXMgdG8gd2hpY2ggdGhlIHNlcnZvIGlzIHNldC4KKyAqLworZmxvYXQgU2Vydm86OkdldEFuZ2xlKCkgY29uc3QgeworICByZXR1cm4gKGZsb2F0KUdldFBvc2l0aW9uKCkgKiBHZXRTZXJ2b0FuZ2xlUmFuZ2UoKSArIGtNaW5TZXJ2b0FuZ2xlOworfQorCit2b2lkIFNlcnZvOjpWYWx1ZUNoYW5nZWQoSVRhYmxlKiBzb3VyY2UsIGxsdm06OlN0cmluZ1JlZiBrZXksCisgICAgICAgICAgICAgICAgICAgICAgICAgc3RkOjpzaGFyZWRfcHRyPG50OjpWYWx1ZT4gdmFsdWUsIGJvb2wgaXNOZXcpIHsKKyAgaWYgKCF2YWx1ZS0+SXNEb3VibGUoKSkgcmV0dXJuOworICBTZXQodmFsdWUtPkdldERvdWJsZSgpKTsKK30KKwordm9pZCBTZXJ2bzo6VXBkYXRlVGFibGUoKSB7CisgIGlmIChtX3RhYmxlICE9IG51bGxwdHIpIHsKKyAgICBtX3RhYmxlLT5QdXROdW1iZXIoIlZhbHVlIiwgR2V0KCkpOworICB9Cit9CisKK3ZvaWQgU2Vydm86OlN0YXJ0TGl2ZVdpbmRvd01vZGUoKSB7CisgIGlmIChtX3RhYmxlICE9IG51bGxwdHIpIHsKKyAgICBtX3RhYmxlLT5BZGRUYWJsZUxpc3RlbmVyKCJWYWx1ZSIsIHRoaXMsIHRydWUpOworICB9Cit9CisKK3ZvaWQgU2Vydm86OlN0b3BMaXZlV2luZG93TW9kZSgpIHsKKyAgaWYgKG1fdGFibGUgIT0gbnVsbHB0cikgeworICAgIG1fdGFibGUtPlJlbW92ZVRhYmxlTGlzdGVuZXIodGhpcyk7CisgIH0KK30KKworc3RkOjpzdHJpbmcgU2Vydm86OkdldFNtYXJ0RGFzaGJvYXJkVHlwZSgpIGNvbnN0IHsgcmV0dXJuICJTZXJ2byI7IH0KKwordm9pZCBTZXJ2bzo6SW5pdFRhYmxlKHN0ZDo6c2hhcmVkX3B0cjxJVGFibGU+IHN1YlRhYmxlKSB7CisgIG1fdGFibGUgPSBzdWJUYWJsZTsKKyAgVXBkYXRlVGFibGUoKTsKK30KKworc3RkOjpzaGFyZWRfcHRyPElUYWJsZT4gU2Vydm86OkdldFRhYmxlKCkgY29uc3QgeyByZXR1cm4gbV90YWJsZTsgfQpkaWZmIC0tZ2l0IGEvd3BpbGliYy9BdGhlbmEvc3JjL1NvbGVub2lkLmNwcCBiL3dwaWxpYmMvQXRoZW5hL3NyYy9Tb2xlbm9pZC5jcHAKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNTE3NGY5OAotLS0gL2Rldi9udWxsCisrKyBiL3dwaWxpYmMvQXRoZW5hL3NyYy9Tb2xlbm9pZC5jcHAKQEAgLTAsMCArMSwxMzUgQEAKKy8qLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovCisvKiBDb3B5cmlnaHQgKGMpIEZJUlNUIDIwMDguIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCisgKi8KKy8qIE9wZW4gU291cmNlIFNvZnR3YXJlIC0gbWF5IGJlIG1vZGlmaWVkIGFuZCBzaGFyZWQgYnkgRlJDIHRlYW1zLiBUaGUgY29kZSAgICovCisvKiBtdXN0IGJlIGFjY29tcGFuaWVkIGJ5IHRoZSBGSVJTVCBCU0QgbGljZW5zZSBmaWxlIGluICQoV0lORF9CQVNFKS9XUElMaWIuICAqLworLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi8KKworI2luY2x1ZGUgIlNvbGVub2lkLmgiCisjaW5jbHVkZSAiV1BJRXJyb3JzLmgiCisjaW5jbHVkZSAiTGl2ZVdpbmRvdy9MaXZlV2luZG93LmgiCisKKyNpbmNsdWRlIDxzc3RyZWFtPgorCisvKioKKyAqIENvbnN0cnVjdG9yIHVzaW5nIHRoZSBkZWZhdWx0IFBDTSBJRCAoMCkuCisgKgorICogQHBhcmFtIGNoYW5uZWwgVGhlIGNoYW5uZWwgb24gdGhlIFBDTSB0byBjb250cm9sICgwLi43KS4KKyAqLworU29sZW5vaWQ6OlNvbGVub2lkKHVpbnQzMl90IGNoYW5uZWwpCisgICAgOiBTb2xlbm9pZChHZXREZWZhdWx0U29sZW5vaWRNb2R1bGUoKSwgY2hhbm5lbCkge30KKworLyoqCisgKiBDb25zdHJ1Y3Rvci4KKyAqCisgKiBAcGFyYW0gbW9kdWxlTnVtYmVyIFRoZSBDQU4gSUQgb2YgdGhlIFBDTSB0aGUgc29sZW5vaWQgaXMgYXR0YWNoZWQgdG8KKyAqIEBwYXJhbSBjaGFubmVsIFRoZSBjaGFubmVsIG9uIHRoZSBQQ00gdG8gY29udHJvbCAoMC4uNykuCisgKi8KK1NvbGVub2lkOjpTb2xlbm9pZCh1aW50OF90IG1vZHVsZU51bWJlciwgdWludDMyX3QgY2hhbm5lbCkKKyAgICA6IFNvbGVub2lkQmFzZShtb2R1bGVOdW1iZXIpLCBtX2NoYW5uZWwoY2hhbm5lbCkgeworICBzdGQ6OnN0cmluZ3N0cmVhbSBidWY7CisgIGlmICghQ2hlY2tTb2xlbm9pZE1vZHVsZShtX21vZHVsZU51bWJlcikpIHsKKyAgICBidWYgPDwgIlNvbGVub2lkIE1vZHVsZSAiIDw8IG1fbW9kdWxlTnVtYmVyOworICAgIHdwaV9zZXRXUElFcnJvcldpdGhDb250ZXh0KE1vZHVsZUluZGV4T3V0T2ZSYW5nZSwgYnVmLnN0cigpKTsKKyAgICByZXR1cm47CisgIH0KKyAgaWYgKCFDaGVja1NvbGVub2lkQ2hhbm5lbChtX2NoYW5uZWwpKSB7CisgICAgYnVmIDw8ICJTb2xlbm9pZCBNb2R1bGUgIiA8PCBtX2NoYW5uZWw7CisgICAgd3BpX3NldFdQSUVycm9yV2l0aENvbnRleHQoQ2hhbm5lbEluZGV4T3V0T2ZSYW5nZSwgYnVmLnN0cigpKTsKKyAgICByZXR1cm47CisgIH0KKyAgUmVzb3VyY2U6OkNyZWF0ZVJlc291cmNlT2JqZWN0KG1fYWxsb2NhdGVkLCBtX21heE1vZHVsZXMgKiBtX21heFBvcnRzKTsKKyAgYnVmIDw8ICJTb2xlbm9pZCAiIDw8IG1fY2hhbm5lbCA8PCAiIChNb2R1bGU6ICIgPDwgbV9tb2R1bGVOdW1iZXIgPDwgIikiOworICBpZiAobV9hbGxvY2F0ZWQtPkFsbG9jYXRlKG1fbW9kdWxlTnVtYmVyICoga1NvbGVub2lkQ2hhbm5lbHMgKyBtX2NoYW5uZWwsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnVmLnN0cigpKSA9PQorICAgICAgc3RkOjpudW1lcmljX2xpbWl0czx1aW50MzJfdD46Om1heCgpKSB7CisgICAgQ2xvbmVFcnJvcigqbV9hbGxvY2F0ZWQpOworICAgIHJldHVybjsKKyAgfQorCisgIExpdmVXaW5kb3c6OkdldEluc3RhbmNlKCktPkFkZEFjdHVhdG9yKCJTb2xlbm9pZCIsIG1fbW9kdWxlTnVtYmVyLCBtX2NoYW5uZWwsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMpOworICBIQUxSZXBvcnQoSEFMVXNhZ2VSZXBvcnRpbmc6OmtSZXNvdXJjZVR5cGVfU29sZW5vaWQsIG1fY2hhbm5lbCwKKyAgICAgICAgICAgIG1fbW9kdWxlTnVtYmVyKTsKK30KKworLyoqCisgKiBEZXN0cnVjdG9yLgorICovCitTb2xlbm9pZDo6flNvbGVub2lkKCkgeworICBpZiAoQ2hlY2tTb2xlbm9pZE1vZHVsZShtX21vZHVsZU51bWJlcikpIHsKKyAgICBtX2FsbG9jYXRlZC0+RnJlZShtX21vZHVsZU51bWJlciAqIGtTb2xlbm9pZENoYW5uZWxzICsgbV9jaGFubmVsKTsKKyAgfQorICBpZiAobV90YWJsZSAhPSBudWxscHRyKSBtX3RhYmxlLT5SZW1vdmVUYWJsZUxpc3RlbmVyKHRoaXMpOworfQorCisvKioKKyAqIFNldCB0aGUgdmFsdWUgb2YgYSBzb2xlbm9pZC4KKyAqCisgKiBAcGFyYW0gb24gVHVybiB0aGUgc29sZW5vaWQgb3V0cHV0IG9mZiBvciBvbi4KKyAqLwordm9pZCBTb2xlbm9pZDo6U2V0KGJvb2wgb24pIHsKKyAgaWYgKFN0YXR1c0lzRmF0YWwoKSkgcmV0dXJuOworICB1aW50OF90IHZhbHVlID0gb24gPyAweEZGIDogMHgwMDsKKyAgdWludDhfdCBtYXNrID0gMSA8PCBtX2NoYW5uZWw7CisKKyAgU29sZW5vaWRCYXNlOjpTZXQodmFsdWUsIG1hc2ssIG1fbW9kdWxlTnVtYmVyKTsKK30KKworLyoqCisgKiBSZWFkIHRoZSBjdXJyZW50IHZhbHVlIG9mIHRoZSBzb2xlbm9pZC4KKyAqCisgKiBAcmV0dXJuIFRoZSBjdXJyZW50IHZhbHVlIG9mIHRoZSBzb2xlbm9pZC4KKyAqLworYm9vbCBTb2xlbm9pZDo6R2V0KCkgY29uc3QgeworICBpZiAoU3RhdHVzSXNGYXRhbCgpKSByZXR1cm4gZmFsc2U7CisgIHVpbnQ4X3QgdmFsdWUgPSBHZXRBbGwobV9tb2R1bGVOdW1iZXIpICYgKDEgPDwgbV9jaGFubmVsKTsKKyAgcmV0dXJuICh2YWx1ZSAhPSAwKTsKK30KKy8qKgorICogQ2hlY2sgaWYgc29sZW5vaWQgaXMgYmxhY2tsaXN0ZWQuCisgKiAJCUlmIGEgc29sZW5vaWQgaXMgc2hvcnRlZCwgaXQgaXMgYWRkZWQgdG8gdGhlIGJsYWNrbGlzdCBhbmQKKyAqIAkJZGlzYWJsZWQgdW50aWwgcG93ZXIgY3ljbGUsIG9yIHVudGlsIGZhdWx0cyBhcmUgY2xlYXJlZC4KKyAqIAkJQHNlZSBDbGVhckFsbFBDTVN0aWNreUZhdWx0cygpCisgKgorICogQHJldHVybiBJZiBzb2xlbm9pZCBpcyBkaXNhYmxlZCBkdWUgdG8gc2hvcnQuCisgKi8KK2Jvb2wgU29sZW5vaWQ6OklzQmxhY2tMaXN0ZWQoKSBjb25zdCB7CisgIGludCB2YWx1ZSA9IEdldFBDTVNvbGVub2lkQmxhY2tMaXN0KG1fbW9kdWxlTnVtYmVyKSAmICgxIDw8IG1fY2hhbm5lbCk7CisgIHJldHVybiAodmFsdWUgIT0gMCk7Cit9CisKK3ZvaWQgU29sZW5vaWQ6OlZhbHVlQ2hhbmdlZChJVGFibGUqIHNvdXJjZSwgbGx2bTo6U3RyaW5nUmVmIGtleSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdGQ6OnNoYXJlZF9wdHI8bnQ6OlZhbHVlPiB2YWx1ZSwgYm9vbCBpc05ldykgeworICBpZiAoIXZhbHVlLT5Jc0Jvb2xlYW4oKSkgcmV0dXJuOworICBTZXQodmFsdWUtPkdldEJvb2xlYW4oKSk7Cit9CisKK3ZvaWQgU29sZW5vaWQ6OlVwZGF0ZVRhYmxlKCkgeworICBpZiAobV90YWJsZSAhPSBudWxscHRyKSB7CisgICAgbV90YWJsZS0+UHV0Qm9vbGVhbigiVmFsdWUiLCBHZXQoKSk7CisgIH0KK30KKwordm9pZCBTb2xlbm9pZDo6U3RhcnRMaXZlV2luZG93TW9kZSgpIHsKKyAgU2V0KGZhbHNlKTsKKyAgaWYgKG1fdGFibGUgIT0gbnVsbHB0cikgeworICAgIG1fdGFibGUtPkFkZFRhYmxlTGlzdGVuZXIoIlZhbHVlIiwgdGhpcywgdHJ1ZSk7CisgIH0KK30KKwordm9pZCBTb2xlbm9pZDo6U3RvcExpdmVXaW5kb3dNb2RlKCkgeworICBTZXQoZmFsc2UpOworICBpZiAobV90YWJsZSAhPSBudWxscHRyKSB7CisgICAgbV90YWJsZS0+UmVtb3ZlVGFibGVMaXN0ZW5lcih0aGlzKTsKKyAgfQorfQorCitzdGQ6OnN0cmluZyBTb2xlbm9pZDo6R2V0U21hcnREYXNoYm9hcmRUeXBlKCkgY29uc3QgeyByZXR1cm4gIlNvbGVub2lkIjsgfQorCit2b2lkIFNvbGVub2lkOjpJbml0VGFibGUoc3RkOjpzaGFyZWRfcHRyPElUYWJsZT4gc3ViVGFibGUpIHsKKyAgbV90YWJsZSA9IHN1YlRhYmxlOworICBVcGRhdGVUYWJsZSgpOworfQorCitzdGQ6OnNoYXJlZF9wdHI8SVRhYmxlPiBTb2xlbm9pZDo6R2V0VGFibGUoKSBjb25zdCB7IHJldHVybiBtX3RhYmxlOyB9CmRpZmYgLS1naXQgYS93cGlsaWJjL0F0aGVuYS9zcmMvU29sZW5vaWRCYXNlLmNwcCBiL3dwaWxpYmMvQXRoZW5hL3NyYy9Tb2xlbm9pZEJhc2UuY3BwCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmRmZGYxZWIKLS0tIC9kZXYvbnVsbAorKysgYi93cGlsaWJjL0F0aGVuYS9zcmMvU29sZW5vaWRCYXNlLmNwcApAQCAtMCwwICsxLDEwNSBAQAorLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi8KKy8qIENvcHlyaWdodCAoYykgRklSU1QgMjAwOC4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KKyAqLworLyogT3BlbiBTb3VyY2UgU29mdHdhcmUgLSBtYXkgYmUgbW9kaWZpZWQgYW5kIHNoYXJlZCBieSBGUkMgdGVhbXMuIFRoZSBjb2RlICAgKi8KKy8qIG11c3QgYmUgYWNjb21wYW5pZWQgYnkgdGhlIEZJUlNUIEJTRCBsaWNlbnNlIGZpbGUgaW4gJChXSU5EX0JBU0UpL1dQSUxpYi4gICovCisvKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qLworCisjaW5jbHVkZSAiU29sZW5vaWRCYXNlLmgiCisKK3ZvaWQqIFNvbGVub2lkQmFzZTo6bV9wb3J0c1ttX21heE1vZHVsZXNdW21fbWF4UG9ydHNdOworc3RkOjp1bmlxdWVfcHRyPFJlc291cmNlPiBTb2xlbm9pZEJhc2U6Om1fYWxsb2NhdGVkOworCisvKioKKyAqIENvbnN0cnVjdG9yCisgKgorICogQHBhcmFtIG1vZHVsZU51bWJlciBUaGUgQ0FOIFBDTSBJRC4KKyAqLworU29sZW5vaWRCYXNlOjpTb2xlbm9pZEJhc2UodWludDhfdCBtb2R1bGVOdW1iZXIpCisgICAgOiBtX21vZHVsZU51bWJlcihtb2R1bGVOdW1iZXIpIHsKKyAgZm9yICh1aW50MzJfdCBpID0gMDsgaSA8IGtTb2xlbm9pZENoYW5uZWxzOyBpKyspIHsKKyAgICB2b2lkKiBwb3J0ID0gZ2V0UG9ydFdpdGhNb2R1bGUobW9kdWxlTnVtYmVyLCBpKTsKKyAgICBpbnQzMl90IHN0YXR1cyA9IDA7CisgICAgU29sZW5vaWRCYXNlOjptX3BvcnRzW21vZHVsZU51bWJlcl1baV0gPQorICAgICAgICBpbml0aWFsaXplU29sZW5vaWRQb3J0KHBvcnQsICZzdGF0dXMpOworICAgIHdwaV9zZXRFcnJvcldpdGhDb250ZXh0KHN0YXR1cywgZ2V0SEFMRXJyb3JNZXNzYWdlKHN0YXR1cykpOworICAgIGZyZWVQb3J0KHBvcnQpOworICB9Cit9CisKKy8qKgorICogU2V0IHRoZSB2YWx1ZSBvZiBhIHNvbGVub2lkLgorICoKKyAqIEBwYXJhbSB2YWx1ZSBUaGUgdmFsdWUgeW91IHdhbnQgdG8gc2V0IG9uIHRoZSBtb2R1bGUuCisgKiBAcGFyYW0gbWFzayBUaGUgY2hhbm5lbHMgeW91IHdhbnQgdG8gYmUgYWZmZWN0ZWQuCisgKi8KK3ZvaWQgU29sZW5vaWRCYXNlOjpTZXQodWludDhfdCB2YWx1ZSwgdWludDhfdCBtYXNrLCBpbnQgbW9kdWxlKSB7CisgIGludDMyX3Qgc3RhdHVzID0gMDsKKyAgZm9yIChpbnQgaSA9IDA7IGkgPCBtX21heFBvcnRzOyBpKyspIHsKKyAgICB1aW50OF90IGxvY2FsX21hc2sgPSAxIDw8IGk7CisgICAgaWYgKG1hc2sgJiBsb2NhbF9tYXNrKQorICAgICAgc2V0U29sZW5vaWQobV9wb3J0c1ttb2R1bGVdW2ldLCB2YWx1ZSAmIGxvY2FsX21hc2ssICZzdGF0dXMpOworICB9CisgIHdwaV9zZXRFcnJvcldpdGhDb250ZXh0KHN0YXR1cywgZ2V0SEFMRXJyb3JNZXNzYWdlKHN0YXR1cykpOworfQorCisvKioKKyAqIFJlYWQgYWxsIDggc29sZW5vaWRzIGFzIGEgc2luZ2xlIGJ5dGUKKyAqCisgKiBAcmV0dXJuIFRoZSBjdXJyZW50IHZhbHVlIG9mIGFsbCA4IHNvbGVub2lkcyBvbiB0aGUgbW9kdWxlLgorICovCit1aW50OF90IFNvbGVub2lkQmFzZTo6R2V0QWxsKGludCBtb2R1bGUpIGNvbnN0IHsKKyAgdWludDhfdCB2YWx1ZSA9IDA7CisgIGludDMyX3Qgc3RhdHVzID0gMDsKKyAgdmFsdWUgPSBnZXRBbGxTb2xlbm9pZHMobV9wb3J0c1ttb2R1bGVdWzBdLCAmc3RhdHVzKTsKKyAgd3BpX3NldEVycm9yV2l0aENvbnRleHQoc3RhdHVzLCBnZXRIQUxFcnJvck1lc3NhZ2Uoc3RhdHVzKSk7CisgIHJldHVybiB2YWx1ZTsKK30KKy8qKgorICogUmVhZHMgY29tcGxldGUgc29sZW5vaWQgYmxhY2tsaXN0IGZvciBhbGwgOCBzb2xlbm9pZHMgYXMgYSBzaW5nbGUgYnl0ZS4KKyAqCisgKiAJCUlmIGEgc29sZW5vaWQgaXMgc2hvcnRlZCwgaXQgaXMgYWRkZWQgdG8gdGhlIGJsYWNrbGlzdCBhbmQKKyAqIAkJZGlzYWJsZWQgdW50aWwgcG93ZXIgY3ljbGUsIG9yIHVudGlsIGZhdWx0cyBhcmUgY2xlYXJlZC4KKyAqIAkJQHNlZSBDbGVhckFsbFBDTVN0aWNreUZhdWx0cygpCisgKgorICogQHJldHVybiBUaGUgc29sZW5vaWQgYmxhY2tsaXN0IG9mIGFsbCA4IHNvbGVub2lkcyBvbiB0aGUgbW9kdWxlLgorICovCit1aW50OF90IFNvbGVub2lkQmFzZTo6R2V0UENNU29sZW5vaWRCbGFja0xpc3QoaW50IG1vZHVsZSkgY29uc3QgeworICBpbnQzMl90IHN0YXR1cyA9IDA7CisgIHJldHVybiBnZXRQQ01Tb2xlbm9pZEJsYWNrTGlzdChtX3BvcnRzW21vZHVsZV1bMF0sICZzdGF0dXMpOworfQorLyoqCisgKiBAcmV0dXJuIHRydWUgaWYgUENNIHN0aWNreSBmYXVsdCBpcyBzZXQgOiBUaGUgY29tbW9uCisgKiAJCQloaWdoc2lkZSBzb2xlbm9pZCB2b2x0YWdlIHJhaWwgaXMgdG9vIGxvdywKKyAqIAkgCQltb3N0IGxpa2VseSBhIHNvbGVub2lkIGNoYW5uZWwgaXMgc2hvcnRlZC4KKyAqLworYm9vbCBTb2xlbm9pZEJhc2U6OkdldFBDTVNvbGVub2lkVm9sdGFnZVN0aWNreUZhdWx0KGludCBtb2R1bGUpIGNvbnN0IHsKKyAgaW50MzJfdCBzdGF0dXMgPSAwOworICByZXR1cm4gZ2V0UENNU29sZW5vaWRWb2x0YWdlU3RpY2t5RmF1bHQobV9wb3J0c1ttb2R1bGVdWzBdLCAmc3RhdHVzKTsKK30KKy8qKgorICogQHJldHVybiB0cnVlIGlmIFBDTSBpcyBpbiBmYXVsdCBzdGF0ZSA6IFRoZSBjb21tb24KKyAqIAkJCWhpZ2hzaWRlIHNvbGVub2lkIHZvbHRhZ2UgcmFpbCBpcyB0b28gbG93LAorICogCSAJCW1vc3QgbGlrZWx5IGEgc29sZW5vaWQgY2hhbm5lbCBpcyBzaG9ydGVkLgorICovCitib29sIFNvbGVub2lkQmFzZTo6R2V0UENNU29sZW5vaWRWb2x0YWdlRmF1bHQoaW50IG1vZHVsZSkgY29uc3QgeworICBpbnQzMl90IHN0YXR1cyA9IDA7CisgIHJldHVybiBnZXRQQ01Tb2xlbm9pZFZvbHRhZ2VGYXVsdChtX3BvcnRzW21vZHVsZV1bMF0sICZzdGF0dXMpOworfQorLyoqCisgKiBDbGVhciBBTEwgc3RpY2t5IGZhdWx0cyBpbnNpZGUgUENNIHRoYXQgQ29tcHJlc3NvciBpcyB3aXJlZCB0by4KKyAqCisgKiBJZiBhIHN0aWNreSBmYXVsdCBpcyBzZXQsIHRoZW4gaXQgd2lsbCBiZSBwZXJzaXN0ZW50bHkgY2xlYXJlZC4gIENvbXByZXNzb3IKKyAqIGRyaXZlCisgKiAJCW1heWJlIG1vbWVudGFyaWx5IGRpc2FibGUgd2hpbGUgZmxhZ3MgYXJlIGJlaW5nIGNsZWFyZWQuIENhcmUKKyAqIHNob3VsZCBiZQorICogCQl0YWtlbiB0byBub3QgY2FsbCB0aGlzIHRvbyBmcmVxdWVudGx5LCBvdGhlcndpc2Ugbm9ybWFsCisgKiBjb21wcmVzc29yCisgKiAJCWZ1bmN0aW9uYWxpdHkgbWF5IGJlIHByZXZlbnRlZC4KKyAqCisgKiBJZiBubyBzdGlja3kgZmF1bHRzIGFyZSBzZXQgdGhlbiB0aGlzIGNhbGwgd2lsbCBoYXZlIG5vIGVmZmVjdC4KKyAqLwordm9pZCBTb2xlbm9pZEJhc2U6OkNsZWFyQWxsUENNU3RpY2t5RmF1bHRzKGludCBtb2R1bGUpIHsKKyAgaW50MzJfdCBzdGF0dXMgPSAwOworICByZXR1cm4gY2xlYXJBbGxQQ01TdGlja3lGYXVsdHNfc29sKG1fcG9ydHNbbW9kdWxlXVswXSwgJnN0YXR1cyk7Cit9CmRpZmYgLS1naXQgYS93cGlsaWJjL0F0aGVuYS9zcmMvVGFsb24uY3BwIGIvd3BpbGliYy9BdGhlbmEvc3JjL1RhbG9uLmNwcApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5kYzFjZjNiCi0tLSAvZGV2L251bGwKKysrIGIvd3BpbGliYy9BdGhlbmEvc3JjL1RhbG9uLmNwcApAQCAtMCwwICsxLDg0IEBACisvKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qLworLyogQ29weXJpZ2h0IChjKSBGSVJTVCAyMDA4LiBBbGwgUmlnaHRzIFJlc2VydmVkLgorICovCisvKiBPcGVuIFNvdXJjZSBTb2Z0d2FyZSAtIG1heSBiZSBtb2RpZmllZCBhbmQgc2hhcmVkIGJ5IEZSQyB0ZWFtcy4gVGhlIGNvZGUgICAqLworLyogbXVzdCBiZSBhY2NvbXBhbmllZCBieSB0aGUgRklSU1QgQlNEIGxpY2Vuc2UgZmlsZSBpbiAkKFdJTkRfQkFTRSkvV1BJTGliLiAgKi8KKy8qLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovCisKKyNpbmNsdWRlICJUYWxvbi5oIgorCisjaW5jbHVkZSAiTGl2ZVdpbmRvdy9MaXZlV2luZG93LmgiCisKKy8qKgorICogQ29uc3RydWN0b3IgZm9yIGEgVGFsb24gKG9yaWdpbmFsIG9yIFRhbG9uIFNSKQorICogQHBhcmFtIGNoYW5uZWwgVGhlIFBXTSBjaGFubmVsIG51bWJlciB0aGF0IHRoZSBUYWxvbiBpcyBhdHRhY2hlZCB0by4gMC05IGFyZQorICogb24tYm9hcmQsIDEwLTE5IGFyZSBvbiB0aGUgTVhQIHBvcnQKKyAqLworVGFsb246OlRhbG9uKHVpbnQzMl90IGNoYW5uZWwpIDogU2FmZVBXTShjaGFubmVsKSB7CisgIC8qIE5vdGUgdGhhdCB0aGUgVGFsb24gdXNlcyB0aGUgZm9sbG93aW5nIGJvdW5kcyBmb3IgUFdNIHZhbHVlcy4gVGhlc2UgdmFsdWVzCisgICAqIHNob3VsZCB3b3JrIHJlYXNvbmFibHkgd2VsbCBmb3IgbW9zdCBjb250cm9sbGVycywgYnV0IGlmIHVzZXJzIGV4cGVyaWVuY2UKKyAgICogaXNzdWVzIHN1Y2ggYXMgYXN5bW1ldHJpYyBiZWhhdmlvciBhcm91bmQgdGhlIGRlYWRiYW5kIG9yIGluYWJpbGl0eSB0bworICAgKiBzYXR1cmF0ZSB0aGUgY29udHJvbGxlciBpbiBlaXRoZXIgZGlyZWN0aW9uLCBjYWxpYnJhdGlvbiBpcyByZWNvbW1lbmRlZC4KKyAgICogVGhlIGNhbGlicmF0aW9uIHByb2NlZHVyZSBjYW4gYmUgZm91bmQgaW4gdGhlIFRhbG9uIFVzZXIgTWFudWFsIGF2YWlsYWJsZQorICAgKiBmcm9tIENUUkUuCisgICAqCisgICAqICAgMi4wMzdtcyA9IGZ1bGwgImZvcndhcmQiCisgICAqICAgMS41MzltcyA9IHRoZSAiaGlnaCBlbmQiIG9mIHRoZSBkZWFkYmFuZCByYW5nZQorICAgKiAgIDEuNTEzbXMgPSBjZW50ZXIgb2YgdGhlIGRlYWRiYW5kIHJhbmdlIChvZmYpCisgICAqICAgMS40ODdtcyA9IHRoZSAibG93IGVuZCIgb2YgdGhlIGRlYWRiYW5kIHJhbmdlCisgICAqICAgMC45ODltcyA9IGZ1bGwgInJldmVyc2UiCisgICAqLworICBTZXRCb3VuZHMoMi4wMzcsIDEuNTM5LCAxLjUxMywgMS40ODcsIC45ODkpOworICBTZXRQZXJpb2RNdWx0aXBsaWVyKGtQZXJpb2RNdWx0aXBsaWVyXzFYKTsKKyAgU2V0UmF3KG1fY2VudGVyUHdtKTsKKyAgU2V0WmVyb0xhdGNoKCk7CisKKyAgSEFMUmVwb3J0KEhBTFVzYWdlUmVwb3J0aW5nOjprUmVzb3VyY2VUeXBlX1RhbG9uLCBHZXRDaGFubmVsKCkpOworICBMaXZlV2luZG93OjpHZXRJbnN0YW5jZSgpLT5BZGRBY3R1YXRvcigiVGFsb24iLCBHZXRDaGFubmVsKCksIHRoaXMpOworfQorCisvKioKKyAqIFNldCB0aGUgUFdNIHZhbHVlLgorICoKKyAqIFRoZSBQV00gdmFsdWUgaXMgc2V0IHVzaW5nIGEgcmFuZ2Ugb2YgLTEuMCB0byAxLjAsIGFwcHJvcHJpYXRlbHkKKyAqIHNjYWxpbmcgdGhlIHZhbHVlIGZvciB0aGUgRlBHQS4KKyAqCisgKiBAcGFyYW0gc3BlZWQgVGhlIHNwZWVkIHZhbHVlIGJldHdlZW4gLTEuMCBhbmQgMS4wIHRvIHNldC4KKyAqIEBwYXJhbSBzeW5jR3JvdXAgVW51c2VkIGludGVyZmFjZS4KKyAqLwordm9pZCBUYWxvbjo6U2V0KGZsb2F0IHNwZWVkLCB1aW50OF90IHN5bmNHcm91cCkgeworICBTZXRTcGVlZChtX2lzSW52ZXJ0ZWQgPyAtc3BlZWQgOiBzcGVlZCk7Cit9CisKKy8qKgorICogR2V0IHRoZSByZWNlbnRseSBzZXQgdmFsdWUgb2YgdGhlIFBXTS4KKyAqCisgKiBAcmV0dXJuIFRoZSBtb3N0IHJlY2VudGx5IHNldCB2YWx1ZSBmb3IgdGhlIFBXTSBiZXR3ZWVuIC0xLjAgYW5kIDEuMC4KKyAqLworZmxvYXQgVGFsb246OkdldCgpIGNvbnN0IHsgcmV0dXJuIEdldFNwZWVkKCk7IH0KKworLyoqCisgKiBDb21tb24gaW50ZXJmYWNlIGZvciBkaXNhYmxpbmcgYSBtb3Rvci4KKyAqLwordm9pZCBUYWxvbjo6RGlzYWJsZSgpIHsgU2V0UmF3KGtQd21EaXNhYmxlZCk7IH0KKworLyoqCisqIGNvbW1vbiBpbnRlcmZhY2UgZm9yIGludmVydGluZyBkaXJlY3Rpb24gb2YgYSBzcGVlZCBjb250cm9sbGVyCisqIEBwYXJhbSBpc0ludmVydGVkIFRoZSBzdGF0ZSBvZiBpbnZlcnNpb24gdHJ1ZSBpcyBpbnZlcnRlZAorKi8KK3ZvaWQgVGFsb246OlNldEludmVydGVkKGJvb2wgaXNJbnZlcnRlZCkgeyBtX2lzSW52ZXJ0ZWQgPSBpc0ludmVydGVkOyB9CisKKy8qKgorICogQ29tbW9uIGludGVyZmFjZSBmb3IgdGhlIGludmVydGluZyBkaXJlY3Rpb24gb2YgYSBzcGVlZCBjb250cm9sbGVyLgorICoKKyAqIEByZXR1cm4gaXNJbnZlcnRlZCBUaGUgc3RhdGUgb2YgaW52ZXJzaW9uLCB0cnVlIGlzIGludmVydGVkLgorICoKKyAqLworYm9vbCBUYWxvbjo6R2V0SW52ZXJ0ZWQoKSBjb25zdCB7IHJldHVybiBtX2lzSW52ZXJ0ZWQ7IH0KKworLyoqCisgKiBXcml0ZSBvdXQgdGhlIFBJRCB2YWx1ZSBhcyBzZWVuIGluIHRoZSBQSURPdXRwdXQgYmFzZSBvYmplY3QuCisgKgorICogQHBhcmFtIG91dHB1dCBXcml0ZSBvdXQgdGhlIFBXTSB2YWx1ZSBhcyB3YXMgZm91bmQgaW4gdGhlIFBJRENvbnRyb2xsZXIKKyAqLwordm9pZCBUYWxvbjo6UElEV3JpdGUoZmxvYXQgb3V0cHV0KSB7IFNldChvdXRwdXQpOyB9CmRpZmYgLS1naXQgYS93cGlsaWJjL0F0aGVuYS9zcmMvVGFsb25TUlguY3BwIGIvd3BpbGliYy9BdGhlbmEvc3JjL1RhbG9uU1JYLmNwcApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4wNzQzOGM0Ci0tLSAvZGV2L251bGwKKysrIGIvd3BpbGliYy9BdGhlbmEvc3JjL1RhbG9uU1JYLmNwcApAQCAtMCwwICsxLDgxIEBACisvKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qLworLyogQ29weXJpZ2h0IChjKSBGSVJTVCAyMDA4LiBBbGwgUmlnaHRzIFJlc2VydmVkLgorICovCisvKiBPcGVuIFNvdXJjZSBTb2Z0d2FyZSAtIG1heSBiZSBtb2RpZmllZCBhbmQgc2hhcmVkIGJ5IEZSQyB0ZWFtcy4gVGhlIGNvZGUgICAqLworLyogbXVzdCBiZSBhY2NvbXBhbmllZCBieSB0aGUgRklSU1QgQlNEIGxpY2Vuc2UgZmlsZSBpbiAkKFdJTkRfQkFTRSkvV1BJTGliLiAgKi8KKy8qLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovCisKKyNpbmNsdWRlICJUYWxvblNSWC5oIgorCisjaW5jbHVkZSAiTGl2ZVdpbmRvdy9MaXZlV2luZG93LmgiCisKKy8qKgorICogQ29uc3RydWN0IGEgVGFsb25TUlggY29ubmVjdGVkIHZpYSBQV00KKyAqIEBwYXJhbSBjaGFubmVsIFRoZSBQV00gY2hhbm5lbCB0aGF0IHRoZSBUYWxvblNSWCBpcyBhdHRhY2hlZCB0by4gMC05IGFyZQorICogb24tYm9hcmQsIDEwLTE5IGFyZSBvbiB0aGUgTVhQIHBvcnQKKyAqLworVGFsb25TUlg6OlRhbG9uU1JYKHVpbnQzMl90IGNoYW5uZWwpIDogU2FmZVBXTShjaGFubmVsKSB7CisgIC8qIE5vdGUgdGhhdCB0aGUgVGFsb25TUlggdXNlcyB0aGUgZm9sbG93aW5nIGJvdW5kcyBmb3IgUFdNIHZhbHVlcy4gVGhlc2UKKyAgICogdmFsdWVzIHNob3VsZCB3b3JrIHJlYXNvbmFibHkgd2VsbCBmb3IgbW9zdCBjb250cm9sbGVycywgYnV0IGlmIHVzZXJzCisgICAqIGV4cGVyaWVuY2UgaXNzdWVzIHN1Y2ggYXMgYXN5bW1ldHJpYyBiZWhhdmlvciBhcm91bmQgdGhlIGRlYWRiYW5kIG9yCisgICAqIGluYWJpbGl0eSB0byBzYXR1cmF0ZSB0aGUgY29udHJvbGxlciBpbiBlaXRoZXIgZGlyZWN0aW9uLCBjYWxpYnJhdGlvbiBpcworICAgKiByZWNvbW1lbmRlZC4gVGhlIGNhbGlicmF0aW9uIHByb2NlZHVyZSBjYW4gYmUgZm91bmQgaW4gdGhlIFRhbG9uU1JYIFVzZXIKKyAgICogTWFudWFsIGF2YWlsYWJsZSBmcm9tIENyb3NzIFRoZSBSb2FkIEVsZWN0cm9uaWNzLgorICAgKiAgIDIuMDA0bXMgPSBmdWxsICJmb3J3YXJkIgorICAgKiAgIDEuNTJtcyA9IHRoZSAiaGlnaCBlbmQiIG9mIHRoZSBkZWFkYmFuZCByYW5nZQorICAgKiAgIDEuNTBtcyA9IGNlbnRlciBvZiB0aGUgZGVhZGJhbmQgcmFuZ2UgKG9mZikKKyAgICogICAxLjQ4bXMgPSB0aGUgImxvdyBlbmQiIG9mIHRoZSBkZWFkYmFuZCByYW5nZQorICAgKiAgIDAuOTk3bXMgPSBmdWxsICJyZXZlcnNlIgorICAgKi8KKyAgU2V0Qm91bmRzKDIuMDA0LCAxLjUyLCAxLjUwLCAxLjQ4LCAuOTk3KTsKKyAgU2V0UGVyaW9kTXVsdGlwbGllcihrUGVyaW9kTXVsdGlwbGllcl8xWCk7CisgIFNldFJhdyhtX2NlbnRlclB3bSk7CisgIFNldFplcm9MYXRjaCgpOworCisgIEhBTFJlcG9ydChIQUxVc2FnZVJlcG9ydGluZzo6a1Jlc291cmNlVHlwZV9UYWxvblNSWCwgR2V0Q2hhbm5lbCgpKTsKKyAgTGl2ZVdpbmRvdzo6R2V0SW5zdGFuY2UoKS0+QWRkQWN0dWF0b3IoIlRhbG9uU1JYIiwgR2V0Q2hhbm5lbCgpLCB0aGlzKTsKK30KKworLyoqCisgKiBTZXQgdGhlIFBXTSB2YWx1ZS4KKyAqCisgKiBUaGUgUFdNIHZhbHVlIGlzIHNldCB1c2luZyBhIHJhbmdlIG9mIC0xLjAgdG8gMS4wLCBhcHByb3ByaWF0ZWx5CisgKiBzY2FsaW5nIHRoZSB2YWx1ZSBmb3IgdGhlIEZQR0EuCisgKgorICogQHBhcmFtIHNwZWVkIFRoZSBzcGVlZCB2YWx1ZSBiZXR3ZWVuIC0xLjAgYW5kIDEuMCB0byBzZXQuCisgKiBAcGFyYW0gc3luY0dyb3VwIFVudXNlZCBpbnRlcmZhY2UuCisgKi8KK3ZvaWQgVGFsb25TUlg6OlNldChmbG9hdCBzcGVlZCwgdWludDhfdCBzeW5jR3JvdXApIHsgU2V0U3BlZWQoc3BlZWQpOyB9CisKKy8qKgorICogR2V0IHRoZSByZWNlbnRseSBzZXQgdmFsdWUgb2YgdGhlIFBXTS4KKyAqCisgKiBAcmV0dXJuIFRoZSBtb3N0IHJlY2VudGx5IHNldCB2YWx1ZSBmb3IgdGhlIFBXTSBiZXR3ZWVuIC0xLjAgYW5kIDEuMC4KKyAqLworZmxvYXQgVGFsb25TUlg6OkdldCgpIGNvbnN0IHsgcmV0dXJuIEdldFNwZWVkKCk7IH0KKworLyoqCisgKiBDb21tb24gaW50ZXJmYWNlIGZvciBkaXNhYmxpbmcgYSBtb3Rvci4KKyAqLwordm9pZCBUYWxvblNSWDo6RGlzYWJsZSgpIHsgU2V0UmF3KGtQd21EaXNhYmxlZCk7IH0KKworLyoqCisqIENvbW1vbiBpbnRlcmZhY2UgZm9yIGludmVydGluZyBkaXJlY3Rpb24gb2YgYSBzcGVlZCBjb250cm9sbGVyLgorKiBAcGFyYW0gaXNJbnZlcnRlZCBUaGUgc3RhdGUgb2YgaW52ZXJzaW9uLCB0cnVlIGlzIGludmVydGVkLgorKi8KK3ZvaWQgVGFsb25TUlg6OlNldEludmVydGVkKGJvb2wgaXNJbnZlcnRlZCkgeyBtX2lzSW52ZXJ0ZWQgPSBpc0ludmVydGVkOyB9CisKKy8qKgorICogQ29tbW9uIGludGVyZmFjZSBmb3IgdGhlIGludmVydGluZyBkaXJlY3Rpb24gb2YgYSBzcGVlZCBjb250cm9sbGVyLgorICoKKyAqIEByZXR1cm4gaXNJbnZlcnRlZCBUaGUgc3RhdGUgb2YgaW52ZXJzaW9uLCB0cnVlIGlzIGludmVydGVkLgorICoKKyAqLworYm9vbCBUYWxvblNSWDo6R2V0SW52ZXJ0ZWQoKSBjb25zdCB7IHJldHVybiBtX2lzSW52ZXJ0ZWQ7IH0KKworLyoqCisgKiBXcml0ZSBvdXQgdGhlIFBJRCB2YWx1ZSBhcyBzZWVuIGluIHRoZSBQSURPdXRwdXQgYmFzZSBvYmplY3QuCisgKgorICogQHBhcmFtIG91dHB1dCBXcml0ZSBvdXQgdGhlIFBXTSB2YWx1ZSBhcyB3YXMgZm91bmQgaW4gdGhlIFBJRENvbnRyb2xsZXIKKyAqLwordm9pZCBUYWxvblNSWDo6UElEV3JpdGUoZmxvYXQgb3V0cHV0KSB7IFNldChvdXRwdXQpOyB9CmRpZmYgLS1naXQgYS93cGlsaWJjL0F0aGVuYS9zcmMvVGFzay5jcHAgYi93cGlsaWJjL0F0aGVuYS9zcmMvVGFzay5jcHAKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uOTE1N2RjYQotLS0gL2Rldi9udWxsCisrKyBiL3dwaWxpYmMvQXRoZW5hL3NyYy9UYXNrLmNwcApAQCAtMCwwICsxLDExNCBAQAorLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi8KKy8qIENvcHlyaWdodCAoYykgRklSU1QgMjAwOC4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KKyAqLworLyogT3BlbiBTb3VyY2UgU29mdHdhcmUgLSBtYXkgYmUgbW9kaWZpZWQgYW5kIHNoYXJlZCBieSBGUkMgdGVhbXMuIFRoZSBjb2RlICAgKi8KKy8qIG11c3QgYmUgYWNjb21wYW5pZWQgYnkgdGhlIEZJUlNUIEJTRCBsaWNlbnNlIGZpbGUgaW4gJChXSU5EX0JBU0UpL1dQSUxpYi4gICovCisvKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qLworCisjaW5jbHVkZSAiVGFzay5oIgorCisjaW5jbHVkZSAiV1BJRXJyb3JzLmgiCisjaW5jbHVkZSA8ZXJybm8uaD4KKyNpbmNsdWRlIDxzdHJpbmcuaD4KKyNpbmNsdWRlIDxzdGRpby5oPgorCisjaWZuZGVmIE9LCisjZGVmaW5lIE9LIDAKKyNlbmRpZiAvKiBPSyAqLworI2lmbmRlZiBFUlJPUgorI2RlZmluZSBFUlJPUiAoLTEpCisjZW5kaWYgLyogRVJST1IgKi8KKworY29uc3QgdWludDMyX3QgVGFzazo6a0RlZmF1bHRQcmlvcml0eTsKKworVGFzayYgVGFzazo6b3BlcmF0b3I9KFRhc2smJiB0YXNrKSB7CisgIG1fdGhyZWFkLnN3YXAodGFzay5tX3RocmVhZCk7CisgIG1fdGFza05hbWUgPSBzdGQ6Om1vdmUodGFzay5tX3Rhc2tOYW1lKTsKKworICByZXR1cm4gKnRoaXM7Cit9CisKK1Rhc2s6On5UYXNrKCkgeworICBpZiAobV90aHJlYWQuam9pbmFibGUoKSkgeworICAgIHN0ZDo6Y291dCA8PCAiW0hBTF0gRXhpdGVkIHRhc2sgIiA8PCBtX3Rhc2tOYW1lIDw8IHN0ZDo6ZW5kbDsKKyAgfQorfQorCitib29sIFRhc2s6OmpvaW5hYmxlKCkgY29uc3Qgbm9leGNlcHQgeworICByZXR1cm4gbV90aHJlYWQuam9pbmFibGUoKTsKK30KKwordm9pZCBUYXNrOjpqb2luKCkgeworICBtX3RocmVhZC5qb2luKCk7Cit9CisKK3ZvaWQgVGFzazo6ZGV0YWNoKCkgeworICBtX3RocmVhZC5kZXRhY2goKTsKK30KKworc3RkOjp0aHJlYWQ6OmlkIFRhc2s6OmdldF9pZCgpIGNvbnN0IG5vZXhjZXB0IHsKKyAgcmV0dXJuIG1fdGhyZWFkLmdldF9pZCgpOworfQorCitzdGQ6OnRocmVhZDo6bmF0aXZlX2hhbmRsZV90eXBlIFRhc2s6Om5hdGl2ZV9oYW5kbGUoKSB7CisgIHJldHVybiBtX3RocmVhZC5uYXRpdmVfaGFuZGxlKCk7Cit9CisKKy8qKgorICogVmVyaWZpZXMgYSB0YXNrIHN0aWxsIGV4aXN0cy4KKyAqCisgKiBAcmV0dXJuIHRydWUgb24gc3VjY2Vzcy4KKyAqLworYm9vbCBUYXNrOjpWZXJpZnkoKSB7CisgIFRBU0sgaWQgPSAoVEFTSyltX3RocmVhZC5uYXRpdmVfaGFuZGxlKCk7CisgIHJldHVybiB2ZXJpZnlUYXNrSUQoaWQpID09IE9LOworfQorCisvKioKKyAqIEdldHMgdGhlIHByaW9yaXR5IG9mIGEgdGFzay4KKyAqCisgKiBAcmV0dXJuIHRhc2sgcHJpb3JpdHkgb3IgMCBpZiBhbiBlcnJvciBvY2N1cmVkCisgKi8KK2ludDMyX3QgVGFzazo6R2V0UHJpb3JpdHkoKSB7CisgIGludCBwcmlvcml0eTsKKyAgYXV0byBpZCA9IG1fdGhyZWFkLm5hdGl2ZV9oYW5kbGUoKTsKKyAgaWYgKEhhbmRsZUVycm9yKGdldFRhc2tQcmlvcml0eSgmaWQsICZwcmlvcml0eSkpKQorICAgIHJldHVybiBwcmlvcml0eTsKKyAgZWxzZQorICAgIHJldHVybiAwOworfQorCisvKioKKyAqIFRoaXMgcm91dGluZSBjaGFuZ2VzIGEgdGFzaydzIHByaW9yaXR5IHRvIGEgc3BlY2lmaWVkIHByaW9yaXR5LgorICogUHJpb3JpdGllcyByYW5nZSBmcm9tIDEsIHRoZSBsb3dlc3QgcHJpb3JpdHksIHRvIDk5LCB0aGUgaGlnaGVzdCBwcmlvcml0eS4KKyAqIERlZmF1bHQgdGFzayBwcmlvcml0eSBpcyA2MC4KKyAqCisgKiBAcGFyYW0gcHJpb3JpdHkgVGhlIHByaW9yaXR5IGF0IHdoaWNoIHRoZSBpbnRlcm5hbCB0aHJlYWQgc2hvdWxkIHJ1bi4KKyAqIEByZXR1cm4gdHJ1ZSBvbiBzdWNjZXNzLgorICovCitib29sIFRhc2s6OlNldFByaW9yaXR5KGludDMyX3QgcHJpb3JpdHkpIHsKKyAgYXV0byBpZCA9IG1fdGhyZWFkLm5hdGl2ZV9oYW5kbGUoKTsKKyAgcmV0dXJuIEhhbmRsZUVycm9yKHNldFRhc2tQcmlvcml0eSgmaWQsIHByaW9yaXR5KSk7Cit9CisKKy8qKgorICogUmV0dXJucyB0aGUgbmFtZSBvZiB0aGUgdGFzay4KKyAqCisgKiBAcmV0dXJuIFRoZSBuYW1lIG9mIHRoZSB0YXNrLgorICovCitzdGQ6OnN0cmluZyBUYXNrOjpHZXROYW1lKCkgY29uc3QgeyByZXR1cm4gbV90YXNrTmFtZTsgfQorCisvKioKKyAqIEhhbmRsZXMgZXJyb3JzIGdlbmVyYXRlZCBieSB0YXNrIHJlbGF0ZWQgY29kZS4KKyAqLworYm9vbCBUYXNrOjpIYW5kbGVFcnJvcihTVEFUVVMgcmVzdWx0cykgeworICBpZiAocmVzdWx0cyAhPSBFUlJPUikgcmV0dXJuIHRydWU7CisgIGludCBlcnJzdiA9IGVycm5vOworICBpZiAoZXJyc3YgPT0gSEFMX3Rhc2tMaWJfSUxMRUdBTF9QUklPUklUWSkgeworICAgIHdwaV9zZXRXUElFcnJvcldpdGhDb250ZXh0KFRhc2tQcmlvcml0eUVycm9yLCBtX3Rhc2tOYW1lLmNfc3RyKCkpOworICB9IGVsc2UgeworICAgIHByaW50ZigiRVJST1I6IGVycm5vPSVpIiwgZXJyc3YpOworICAgIHdwaV9zZXRXUElFcnJvcldpdGhDb250ZXh0KFRhc2tFcnJvciwgbV90YXNrTmFtZS5jX3N0cigpKTsKKyAgfQorICByZXR1cm4gZmFsc2U7Cit9CmRpZmYgLS1naXQgYS93cGlsaWJjL0F0aGVuYS9zcmMvVGltZXIuY3BwIGIvd3BpbGliYy9BdGhlbmEvc3JjL1RpbWVyLmNwcApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi41MzYzMWU3Ci0tLSAvZGV2L251bGwKKysrIGIvd3BpbGliYy9BdGhlbmEvc3JjL1RpbWVyLmNwcApAQCAtMCwwICsxLDE3NyBAQAorLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi8KKy8qIENvcHlyaWdodCAoYykgRklSU1QgMjAwOC4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KKyAqLworLyogT3BlbiBTb3VyY2UgU29mdHdhcmUgLSBtYXkgYmUgbW9kaWZpZWQgYW5kIHNoYXJlZCBieSBGUkMgdGVhbXMuIFRoZSBjb2RlICAgKi8KKy8qIG11c3QgYmUgYWNjb21wYW5pZWQgYnkgdGhlIEZJUlNUIEJTRCBsaWNlbnNlIGZpbGUgaW4gJChXSU5EX0JBU0UpL1dQSUxpYi4gICovCisvKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qLworCisjaW5jbHVkZSAiVGltZXIuaCIKKworI2luY2x1ZGUgPHRpbWUuaD4KKworI2luY2x1ZGUgIkhBTC9IQUwuaHBwIgorI2luY2x1ZGUgIlV0aWxpdHkuaCIKKyNpbmNsdWRlIDxpb3N0cmVhbT4KKworLyoqCisgKiBQYXVzZSB0aGUgdGFzayBmb3IgYSBzcGVjaWZpZWQgdGltZS4KKyAqCisgKiBQYXVzZSB0aGUgZXhlY3V0aW9uIG9mIHRoZSBwcm9ncmFtIGZvciBhIHNwZWNpZmllZCBwZXJpb2Qgb2YgdGltZSBnaXZlbiBpbgorICogc2Vjb25kcy4KKyAqIE1vdG9ycyB3aWxsIGNvbnRpbnVlIHRvIHJ1biBhdCB0aGVpciBsYXN0IGFzc2lnbmVkIHZhbHVlcywgYW5kIHNlbnNvcnMgd2lsbAorICogY29udGludWUgdG8KKyAqIHVwZGF0ZS4gT25seSB0aGUgdGFzayBjb250YWluaW5nIHRoZSB3YWl0IHdpbGwgcGF1c2UgdW50aWwgdGhlIHdhaXQgdGltZSBpcworICogZXhwaXJlZC4KKyAqCisgKiBAcGFyYW0gc2Vjb25kcyBMZW5ndGggb2YgdGltZSB0byBwYXVzZSwgaW4gc2Vjb25kcy4KKyAqLwordm9pZCBXYWl0KGRvdWJsZSBzZWNvbmRzKSB7CisgIGlmIChzZWNvbmRzIDwgMC4wKSByZXR1cm47CisgIGRlbGF5U2Vjb25kcyhzZWNvbmRzKTsKK30KKworLyoqCisgKiBSZXR1cm4gdGhlIEZQR0Egc3lzdGVtIGNsb2NrIHRpbWUgaW4gc2Vjb25kcy4KKyAqIFRoaXMgaXMgZGVwcmVjYXRlZCBhbmQganVzdCBmb3J3YXJkcyB0byBUaW1lcjo6R2V0RlBHQVRpbWVzdGFtcCgpLgorICogQHJldHVybiBSb2JvdCBydW5uaW5nIHRpbWUgaW4gc2Vjb25kcy4KKyAqLworZG91YmxlIEdldENsb2NrKCkgeyByZXR1cm4gVGltZXI6OkdldEZQR0FUaW1lc3RhbXAoKTsgfQorCisvKioKKyAqIEBicmllZiBHaXZlcyByZWFsLXRpbWUgY2xvY2sgc3lzdGVtIHRpbWUgd2l0aCBuYW5vc2Vjb25kIHJlc29sdXRpb24KKyAqIEByZXR1cm4gVGhlIHRpbWUsIGp1c3QgaW4gY2FzZSB5b3Ugd2FudCB0aGUgcm9ib3QgdG8gc3RhcnQgYXV0b25vbW91cyBhdCA4cG0KKyAqIG9uIFNhdHVyZGF5LgorKi8KK2RvdWJsZSBHZXRUaW1lKCkgeworICBzdHJ1Y3QgdGltZXNwZWMgdHA7CisKKyAgY2xvY2tfZ2V0dGltZShDTE9DS19SRUFMVElNRSwgJnRwKTsKKyAgZG91YmxlIHJlYWxUaW1lID0gKGRvdWJsZSl0cC50dl9zZWMgKyAoZG91YmxlKSgoZG91YmxlKXRwLnR2X25zZWMgKiAxZS05KTsKKworICByZXR1cm4gKHJlYWxUaW1lKTsKK30KKworLy9mb3IgY29tcGF0aWJpbGl0eSB3aXRoIG1zdmMxMi0tc2VlIEMyODY0Citjb25zdCBkb3VibGUgVGltZXI6OmtSb2xsb3ZlclRpbWUgPSAoMWxsIDw8IDMyKSAvIDFlNjsKKy8qKgorICogQ3JlYXRlIGEgbmV3IHRpbWVyIG9iamVjdC4KKyAqCisgKiBDcmVhdGUgYSBuZXcgdGltZXIgb2JqZWN0IGFuZCByZXNldCB0aGUgdGltZSB0byB6ZXJvLiBUaGUgdGltZXIgaXMgaW5pdGlhbGx5CisgKiBub3QgcnVubmluZyBhbmQKKyAqIG11c3QgYmUgc3RhcnRlZC4KKyAqLworVGltZXI6OlRpbWVyKCkgeworICAvLyBDcmVhdGVzIGEgc2VtYXBob3JlIHRvIGNvbnRyb2wgYWNjZXNzIHRvIGNyaXRpY2FsIHJlZ2lvbnMuCisgIC8vIEluaXRpYWxseSAnb3BlbicKKyAgUmVzZXQoKTsKK30KKworLyoqCisgKiBHZXQgdGhlIGN1cnJlbnQgdGltZSBmcm9tIHRoZSB0aW1lci4gSWYgdGhlIGNsb2NrIGlzIHJ1bm5pbmcgaXQgaXMgZGVyaXZlZAorICogZnJvbQorICogdGhlIGN1cnJlbnQgc3lzdGVtIGNsb2NrIHRoZSBzdGFydCB0aW1lIHN0b3JlZCBpbiB0aGUgdGltZXIgY2xhc3MuIElmIHRoZQorICogY2xvY2sKKyAqIGlzIG5vdCBydW5uaW5nLCB0aGVuIHJldHVybiB0aGUgdGltZSB3aGVuIGl0IHdhcyBsYXN0IHN0b3BwZWQuCisgKgorICogQHJldHVybiBDdXJyZW50IHRpbWUgdmFsdWUgZm9yIHRoaXMgdGltZXIgaW4gc2Vjb25kcworICovCitkb3VibGUgVGltZXI6OkdldCgpIGNvbnN0IHsKKyAgZG91YmxlIHJlc3VsdDsKKyAgZG91YmxlIGN1cnJlbnRUaW1lID0gR2V0RlBHQVRpbWVzdGFtcCgpOworCisgIHN0ZDo6bG9ja19ndWFyZDxwcmlvcml0eV9tdXRleD4gc3luYyhtX211dGV4KTsKKyAgaWYgKG1fcnVubmluZykgeworICAgIC8vIElmIHRoZSBjdXJyZW50IHRpbWUgaXMgYmVmb3JlIHRoZSBzdGFydCB0aW1lLCB0aGVuIHRoZSBGUEdBIGNsb2NrCisgICAgLy8gcm9sbGVkIG92ZXIuICBDb21wZW5zYXRlIGJ5IGFkZGluZyB0aGUgfjcxIG1pbnV0ZXMgdGhhdCBpdCB0YWtlcworICAgIC8vIHRvIHJvbGwgb3ZlciB0byB0aGUgY3VycmVudCB0aW1lLgorICAgIGlmIChjdXJyZW50VGltZSA8IG1fc3RhcnRUaW1lKSB7CisgICAgICBjdXJyZW50VGltZSArPSBrUm9sbG92ZXJUaW1lOworICAgIH0KKworICAgIHJlc3VsdCA9IChjdXJyZW50VGltZSAtIG1fc3RhcnRUaW1lKSArIG1fYWNjdW11bGF0ZWRUaW1lOworICB9IGVsc2UgeworICAgIHJlc3VsdCA9IG1fYWNjdW11bGF0ZWRUaW1lOworICB9CisKKyAgcmV0dXJuIHJlc3VsdDsKK30KKworLyoqCisgKiBSZXNldCB0aGUgdGltZXIgYnkgc2V0dGluZyB0aGUgdGltZSB0byAwLgorICoKKyAqIE1ha2UgdGhlIHRpbWVyIHN0YXJ0VGltZSB0aGUgY3VycmVudCB0aW1lIHNvIG5ldyByZXF1ZXN0cyB3aWxsIGJlIHJlbGF0aXZlIHRvCisgKiBub3cKKyAqLwordm9pZCBUaW1lcjo6UmVzZXQoKSB7CisgIHN0ZDo6bG9ja19ndWFyZDxwcmlvcml0eV9tdXRleD4gc3luYyhtX211dGV4KTsKKyAgbV9hY2N1bXVsYXRlZFRpbWUgPSAwOworICBtX3N0YXJ0VGltZSA9IEdldEZQR0FUaW1lc3RhbXAoKTsKK30KKworLyoqCisgKiBTdGFydCB0aGUgdGltZXIgcnVubmluZy4KKyAqIEp1c3Qgc2V0IHRoZSBydW5uaW5nIGZsYWcgdG8gdHJ1ZSBpbmRpY2F0aW5nIHRoYXQgYWxsIHRpbWUgcmVxdWVzdHMgc2hvdWxkIGJlCisgKiByZWxhdGl2ZSB0byB0aGUgc3lzdGVtIGNsb2NrLgorICovCit2b2lkIFRpbWVyOjpTdGFydCgpIHsKKyAgc3RkOjpsb2NrX2d1YXJkPHByaW9yaXR5X211dGV4PiBzeW5jKG1fbXV0ZXgpOworICBpZiAoIW1fcnVubmluZykgeworICAgIG1fc3RhcnRUaW1lID0gR2V0RlBHQVRpbWVzdGFtcCgpOworICAgIG1fcnVubmluZyA9IHRydWU7CisgIH0KK30KKworLyoqCisgKiBTdG9wIHRoZSB0aW1lci4KKyAqIFRoaXMgY29tcHV0ZXMgdGhlIHRpbWUgYXMgb2Ygbm93IGFuZCBjbGVhcnMgdGhlIHJ1bm5pbmcgZmxhZywgY2F1c2luZyBhbGwKKyAqIHN1YnNlcXVlbnQgdGltZSByZXF1ZXN0cyB0byBiZSByZWFkIGZyb20gdGhlIGFjY3VtdWxhdGVkIHRpbWUgcmF0aGVyIHRoYW4KKyAqIGxvb2tpbmcgYXQgdGhlIHN5c3RlbSBjbG9jay4KKyAqLwordm9pZCBUaW1lcjo6U3RvcCgpIHsKKyAgZG91YmxlIHRlbXAgPSBHZXQoKTsKKworICBzdGQ6OmxvY2tfZ3VhcmQ8cHJpb3JpdHlfbXV0ZXg+IHN5bmMobV9tdXRleCk7CisgIGlmIChtX3J1bm5pbmcpIHsKKyAgICBtX2FjY3VtdWxhdGVkVGltZSA9IHRlbXA7CisgICAgbV9ydW5uaW5nID0gZmFsc2U7CisgIH0KK30KKworLyoqCisgKiBDaGVjayBpZiB0aGUgcGVyaW9kIHNwZWNpZmllZCBoYXMgcGFzc2VkIGFuZCBpZiBpdCBoYXMsIGFkdmFuY2UgdGhlIHN0YXJ0CisgKiB0aW1lIGJ5IHRoYXQgcGVyaW9kLiBUaGlzIGlzIHVzZWZ1bCB0byBkZWNpZGUgaWYgaXQncyB0aW1lIHRvIGRvIHBlcmlvZGljCisgKiB3b3JrIHdpdGhvdXQgZHJpZnRpbmcgbGF0ZXIgYnkgdGhlIHRpbWUgaXQgdG9vayB0byBnZXQgYXJvdW5kIHRvIGNoZWNraW5nLgorICoKKyAqIEBwYXJhbSBwZXJpb2QgVGhlIHBlcmlvZCB0byBjaGVjayBmb3IgKGluIHNlY29uZHMpLgorICogQHJldHVybiBUcnVlIGlmIHRoZSBwZXJpb2QgaGFzIHBhc3NlZC4KKyAqLworYm9vbCBUaW1lcjo6SGFzUGVyaW9kUGFzc2VkKGRvdWJsZSBwZXJpb2QpIHsKKyAgaWYgKEdldCgpID4gcGVyaW9kKSB7CisgICAgc3RkOjpsb2NrX2d1YXJkPHByaW9yaXR5X211dGV4PiBzeW5jKG1fbXV0ZXgpOworICAgIC8vIEFkdmFuY2UgdGhlIHN0YXJ0IHRpbWUgYnkgdGhlIHBlcmlvZC4KKyAgICBtX3N0YXJ0VGltZSArPSBwZXJpb2Q7CisgICAgLy8gRG9uJ3Qgc2V0IGl0IHRvIHRoZSBjdXJyZW50IHRpbWUuLi4gd2Ugd2FudCB0byBhdm9pZCBkcmlmdC4KKyAgICByZXR1cm4gdHJ1ZTsKKyAgfQorICByZXR1cm4gZmFsc2U7Cit9CisKKy8qKgorICogUmV0dXJuIHRoZSBGUEdBIHN5c3RlbSBjbG9jayB0aW1lIGluIHNlY29uZHMuCisgKgorICogUmV0dXJuIHRoZSB0aW1lIGZyb20gdGhlIEZQR0EgaGFyZHdhcmUgY2xvY2sgaW4gc2Vjb25kcyBzaW5jZSB0aGUgRlBHQQorICogc3RhcnRlZC4KKyAqIFJvbGxzIG92ZXIgYWZ0ZXIgNzEgbWludXRlcy4KKyAqIEByZXR1cm5zIFJvYm90IHJ1bm5pbmcgdGltZSBpbiBzZWNvbmRzLgorICovCitkb3VibGUgVGltZXI6OkdldEZQR0FUaW1lc3RhbXAoKSB7CisgIC8vIEZQR0EgcmV0dXJucyB0aGUgdGltZXN0YW1wIGluIG1pY3Jvc2Vjb25kcworICAvLyBDYWxsIHRoZSBoZWxwZXIgR2V0RlBHQVRpbWUoKSBpbiBVdGlsaXR5LmNwcAorICByZXR1cm4gR2V0RlBHQVRpbWUoKSAqIDEuMGUtNjsKK30KKworLy8gSW50ZXJuYWwgZnVuY3Rpb24gdGhhdCByZWFkcyB0aGUgUFBDIHRpbWVzdGFtcCBjb3VudGVyLgorZXh0ZXJuICJDIiB7Cit1aW50MzJfdCBuaVRpbWVzdGFtcDMyKHZvaWQpOwordWludDY0X3QgbmlUaW1lc3RhbXA2NCh2b2lkKTsKK30KZGlmZiAtLWdpdCBhL3dwaWxpYmMvQXRoZW5hL3NyYy9VU0JDYW1lcmEuY3BwIGIvd3BpbGliYy9BdGhlbmEvc3JjL1VTQkNhbWVyYS5jcHAKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMGM1N2Q4NQotLS0gL2Rldi9udWxsCisrKyBiL3dwaWxpYmMvQXRoZW5hL3NyYy9VU0JDYW1lcmEuY3BwCkBAIC0wLDAgKzEsMzIzIEBACisjaW5jbHVkZSAiVVNCQ2FtZXJhLmgiCisKKyNpbmNsdWRlICJVdGlsaXR5LmgiCisKKyNpbmNsdWRlIDxyZWdleD4KKyNpbmNsdWRlIDxjaHJvbm8+CisjaW5jbHVkZSA8dGhyZWFkPgorI2luY2x1ZGUgPG1lbW9yeT4KKyNpbmNsdWRlIDxpb3N0cmVhbT4KKyNpbmNsdWRlIDxpb21hbmlwPgorCisvLyBUaGlzIG1hY3JvIGV4cGFuZHMgdGhlIGdpdmVuIGltYXEgZnVuY3Rpb24gdG8gZW5zdXJlIHRoYXQgaXQgaXMgY2FsbGVkIGFuZAorLy8gcHJvcGVybHkgY2hlY2tlZCBmb3IgYW4gZXJyb3IsIGNhbGxpbmcgdGhlIHdwaV9zZXRJbWFxRXJyb3JXaXRoQ29udGV4dAorLy8gbWFjcm8KKy8vIFRvIGNhbGwgaXQsIGp1c3QgZ2l2ZSB0aGUgbmFtZSBvZiB0aGUgZnVuY3Rpb24gYW5kIHRoZSBhcmd1bWVudHMKKyNkZWZpbmUgU0FGRV9JTUFRX0NBTEwoZnVuTmFtZSwgLi4uKSAgICAgICAgICAgICAgICBcCisgIHsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgIHVuc2lnbmVkIGludCBlcnJvciA9IGZ1bk5hbWUoX19WQV9BUkdTX18pOyAgICAgIFwKKyAgICBpZiAoZXJyb3IgIT0gSU1BUWR4RXJyb3JTdWNjZXNzKSAgICAgICAgICAgICAgICBcCisgICAgICB3cGlfc2V0SW1hcUVycm9yV2l0aENvbnRleHQoZXJyb3IsICNmdW5OYW1lKTsgXAorICB9CisKKy8qKgorICogSGVscGVyIGZ1bmN0aW9uIHRvIGRldGVybWluZSB0aGUgc2l6ZSBvZiBhIGpwZWcuIFRoZSBnZW5lcmFsIHN0cnVjdHVyZSBvZgorICogaG93IHRvIHBhcnNlIGEganBlZyBmb3IgbGVuZ3RoIGNhbiBiZSBmb3VuZCBpbiB0aGlzIHN0YWNrb3ZlcmZsb3cgYXJ0aWNsZToKKyAqIGh0dHA6Ly9zdGFja292ZXJmbG93LmNvbS9hLzE2MDI0MjguIEJlIHN1cmUgdG8gYWxzbyByZWFkIHRoZSBjb21tZW50cyBmb3IKKyAqIHRoZSBTT1MgZmxhZyBleHBsYW5hdGlvbi4KKyAqLwordW5zaWduZWQgaW50IFVTQkNhbWVyYTo6R2V0SnBlZ1NpemUodm9pZCogYnVmZmVyLCB1bnNpZ25lZCBpbnQgYnVmZlNpemUpIHsKKyAgdWludDhfdCogZGF0YSA9ICh1aW50OF90KilidWZmZXI7CisgIGlmICghd3BpX2Fzc2VydChkYXRhWzBdID09IDB4ZmYgJiYgZGF0YVsxXSA9PSAweGQ4KSkgcmV0dXJuIDA7CisgIHVuc2lnbmVkIGludCBwb3MgPSAyOworICB3aGlsZSAocG9zIDwgYnVmZlNpemUpIHsKKyAgICAvLyBBbGwgY29udHJvbCBtYXJrZXJzIHN0YXJ0IHdpdGggMHhmZiwgc28gaWYgdGhpcyBpc24ndCBwcmVzZW50LAorICAgIC8vIHRoZSBKUEVHIGlzIG5vdCB2YWxpZAorICAgIGlmICghd3BpX2Fzc2VydChkYXRhW3Bvc10gPT0gMHhmZikpIHJldHVybiAwOworICAgIHVuc2lnbmVkIGNoYXIgdCA9IGRhdGFbcG9zICsgMV07CisgICAgLy8gVGhlc2UgYXJlIFJTVCBtYXJrZXJzLiBXZSBqdXN0IHNraXAgdGhlbSBhbmQgbW92ZSBvbnRvIHRoZSBuZXh0IG1hcmtlcgorICAgIGlmICh0ID09IDB4MDEgfHwgKHQgPj0gMHhkMCAmJiB0IDw9IDB4ZDcpKSB7CisgICAgICBwb3MgKz0gMjsKKyAgICB9IGVsc2UgaWYgKHQgPT0gMHhkOSkgeworICAgICAgLy8gRW5kIG9mIEltYWdlLCBhZGQgMiBmb3IgdGhpcyBhbmQgMC1pbmRleGVkCisgICAgICByZXR1cm4gcG9zICsgMjsKKyAgICB9IGVsc2UgaWYgKCF3cGlfYXNzZXJ0KHQgIT0gMHhkOCkpIHsKKyAgICAgIC8vIEFub3RoZXIgc3RhcnQgb2YgaW1hZ2UsIGludmFsaWQgaW1hZ2UKKyAgICAgIHJldHVybiAwOworICAgIH0gZWxzZSBpZiAodCA9PSAweGRhKSB7CisgICAgICAvLyBTT1MgbWFya2VyLiBUaGUgbmV4dCB0d28gYnl0ZXMgYXJlIGEgMTYtYml0IGJpZy1lbmRpYW4gaW50IHRoYXQgaXMKKyAgICAgIC8vIHRoZSBsZW5ndGggb2YgdGhlIFNPUyBoZWFkZXIsIHNraXAgdGhhdAorICAgICAgdW5zaWduZWQgaW50IGxlbiA9ICgoKHVuc2lnbmVkIGludCkoZGF0YVtwb3MgKyAyXSAmIDB4ZmYpKSA8PCA4IHwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgKCh1bnNpZ25lZCBpbnQpZGF0YVtwb3MgKyAzXSAmIDB4ZmYpKTsKKyAgICAgIHBvcyArPSBsZW4gKyAyOworICAgICAgLy8gVGhlIG5leHQgbWFya2VyIGlzIHRoZSBmaXJzdCBtYXJrZXIgdGhhdCBpcyAweGZmIGZvbGxvd2VkIGJ5IGEgbm9uLVJTVAorICAgICAgLy8gZWxlbWVudC4gMHhmZiBmb2xsb3dlZCBieSAweDAwIGlzIGFuIGVzY2FwZWQgMHhmZi4gMHhkMC0weGQ3IGFyZSBSU1QKKyAgICAgIC8vIG1hcmtlcnMKKyAgICAgIHdoaWxlIChkYXRhW3Bvc10gIT0gMHhmZiB8fCBkYXRhW3BvcyArIDFdID09IDB4MDAgfHwKKyAgICAgICAgICAgICAoZGF0YVtwb3MgKyAxXSA+PSAweGQwICYmIGRhdGFbcG9zICsgMV0gPD0gMHhkNykpIHsKKyAgICAgICAgcG9zICs9IDE7CisgICAgICAgIGlmIChwb3MgPj0gYnVmZlNpemUpIHJldHVybiAwOworICAgICAgfQorICAgIH0gZWxzZSB7CisgICAgICAvLyBUaGlzIGlzIG9uZSBvZiBzZXZlcmFsIHBvc3NpYmxlIG1hcmtlcnMuIFRoZSBuZXh0IHR3byBieXRlcyBhcmUgYQorICAgICAgLy8gMTYtYml0CisgICAgICAvLyBiaWctZW5kaWFuIGludCB3aXRoIHRoZSBsZW5ndGggb2YgdGhlIG1hcmtlciBoZWFkZXIsIHNraXAgdGhhdCB0aGVuCisgICAgICAvLyBjb250aW51ZSBzZWFyY2hpbmcKKyAgICAgIHVuc2lnbmVkIGludCBsZW4gPSAoKCh1bnNpZ25lZCBpbnQpKGRhdGFbcG9zICsgMl0gJiAweGZmKSkgPDwgOCB8CisgICAgICAgICAgICAgICAgICAgICAgICAgICgodW5zaWduZWQgaW50KWRhdGFbcG9zICsgM10gJiAweGZmKSk7CisgICAgICBwb3MgKz0gbGVuICsgMjsKKyAgICB9CisgIH0KKworICByZXR1cm4gMDsKK30KKworVVNCQ2FtZXJhOjpVU0JDYW1lcmEoc3RkOjpzdHJpbmcgbmFtZSwgYm9vbCB1c2VKcGVnKQorICAgIDogbV9uYW1lKG5hbWUpLAorICAgICAgbV91c2VKcGVnKHVzZUpwZWcpIHt9CisKK3ZvaWQgVVNCQ2FtZXJhOjpPcGVuQ2FtZXJhKCkgeworICBzdGQ6OmxvY2tfZ3VhcmQ8cHJpb3JpdHlfcmVjdXJzaXZlX211dGV4PiBsb2NrKG1fbXV0ZXgpOworICBmb3IgKHVuc2lnbmVkIGludCBpID0gMDsgaSA8IDM7IGkrKykgeworICAgIHVJbnQzMiBpZCA9IDA7CisgICAgLy8gQ2FuJ3QgdXNlIFNBRkVfSU1BUV9DQUxMIGhlcmUgYmVjYXVzZSB3ZSBvbmx5IGVycm9yIG9uIHRoZSB0aGlyZCB0aW1lCisgICAgSU1BUWR4RXJyb3IgZXJyb3IgPSBJTUFRZHhPcGVuQ2FtZXJhKAorICAgICAgICBtX25hbWUuY19zdHIoKSwgSU1BUWR4Q2FtZXJhQ29udHJvbE1vZGVDb250cm9sbGVyLCAmaWQpOworICAgIGlmIChlcnJvciAhPSBJTUFRZHhFcnJvclN1Y2Nlc3MpIHsKKyAgICAgIC8vIE9ubHkgZXJyb3Igb24gdGhlIDNyZCB0cnkKKyAgICAgIGlmIChpID49IDIpIHdwaV9zZXRJbWFxRXJyb3JXaXRoQ29udGV4dChlcnJvciwgIklNQVFkeE9wZW5DYW1lcmEiKTsKKyAgICAgIC8vIFNsZWVwIGZvciBhIGZldyBzZWNvbmRzIHRvIGVuc3VyZSB0aGUgZXJyb3IgaGFzIGJlZW4gZGVhbHQgd2l0aAorICAgICAgc3RkOjp0aGlzX3RocmVhZDo6c2xlZXBfZm9yKHN0ZDo6Y2hyb25vOjptaWxsaXNlY29uZHMoMjAwMCkpOworICAgIH0gZWxzZSB7CisgICAgICBtX2lkID0gaWQ7CisgICAgICBtX29wZW4gPSB0cnVlOworICAgICAgcmV0dXJuOworICAgIH0KKyAgfQorfQorCit2b2lkIFVTQkNhbWVyYTo6Q2xvc2VDYW1lcmEoKSB7CisgIHN0ZDo6bG9ja19ndWFyZDxwcmlvcml0eV9yZWN1cnNpdmVfbXV0ZXg+IGxvY2sobV9tdXRleCk7CisgIGlmICghbV9vcGVuKSByZXR1cm47CisgIFNBRkVfSU1BUV9DQUxMKElNQVFkeENsb3NlQ2FtZXJhLCBtX2lkKTsKKyAgbV9pZCA9IDA7CisgIG1fb3BlbiA9IGZhbHNlOworfQorCit2b2lkIFVTQkNhbWVyYTo6U3RhcnRDYXB0dXJlKCkgeworICBzdGQ6OmxvY2tfZ3VhcmQ8cHJpb3JpdHlfcmVjdXJzaXZlX211dGV4PiBsb2NrKG1fbXV0ZXgpOworICBpZiAoIW1fb3BlbiB8fCBtX2FjdGl2ZSkgcmV0dXJuOworICBTQUZFX0lNQVFfQ0FMTChJTUFRZHhDb25maWd1cmVHcmFiLCBtX2lkKTsKKyAgU0FGRV9JTUFRX0NBTEwoSU1BUWR4U3RhcnRBY3F1aXNpdGlvbiwgbV9pZCk7CisgIG1fYWN0aXZlID0gdHJ1ZTsKK30KKwordm9pZCBVU0JDYW1lcmE6OlN0b3BDYXB0dXJlKCkgeworICBzdGQ6OmxvY2tfZ3VhcmQ8cHJpb3JpdHlfcmVjdXJzaXZlX211dGV4PiBsb2NrKG1fbXV0ZXgpOworICBpZiAoIW1fb3BlbiB8fCAhbV9hY3RpdmUpIHJldHVybjsKKyAgU0FGRV9JTUFRX0NBTEwoSU1BUWR4U3RvcEFjcXVpc2l0aW9uLCBtX2lkKTsKKyAgU0FGRV9JTUFRX0NBTEwoSU1BUWR4VW5jb25maWd1cmVBY3F1aXNpdGlvbiwgbV9pZCk7CisgIG1fYWN0aXZlID0gZmFsc2U7Cit9CisKK3ZvaWQgVVNCQ2FtZXJhOjpVcGRhdGVTZXR0aW5ncygpIHsKKyAgc3RkOjpsb2NrX2d1YXJkPHByaW9yaXR5X3JlY3Vyc2l2ZV9tdXRleD4gbG9jayhtX211dGV4KTsKKyAgYm9vbCB3YXNBY3RpdmUgPSBtX2FjdGl2ZTsKKworICBpZiAod2FzQWN0aXZlKSBTdG9wQ2FwdHVyZSgpOworICBpZiAobV9vcGVuKSBDbG9zZUNhbWVyYSgpOworICBPcGVuQ2FtZXJhKCk7CisKKyAgdUludDMyIGNvdW50ID0gMDsKKyAgdUludDMyIGN1cnJlbnRNb2RlID0gMDsKKyAgU0FGRV9JTUFRX0NBTEwoSU1BUWR4RW51bWVyYXRlVmlkZW9Nb2RlcywgbV9pZCwgbnVsbHB0ciwgJmNvdW50LCAmY3VycmVudE1vZGUpOworICBhdXRvIG1vZGVzID0gc3RkOjptYWtlX3VuaXF1ZTxJTUFRZHhWaWRlb01vZGVbXT4oY291bnQpOworICBTQUZFX0lNQVFfQ0FMTChJTUFRZHhFbnVtZXJhdGVWaWRlb01vZGVzLCBtX2lkLCBtb2Rlcy5nZXQoKSwgJmNvdW50LCAmY3VycmVudE1vZGUpOworCisgIC8vIEdyb3VwcyBhcmU6CisgIC8vICAgMCAtIHdpZHRoCisgIC8vICAgMSAtIGhlaWdodAorICAvLyAgIDIgLSBmb3JtYXQKKyAgLy8gICAzIC0gZnBzCisgIHN0ZDo6cmVnZXggcmVNb2RlKCIoWzAtOV0rKVxccyp4XFxzKihbMC05XSspXFxzKyguKj8pXFxzKyhbMC05Ll0rKVxccypmcHMiKTsKKyAgSU1BUWR4VmlkZW9Nb2RlKiBmb3VuZE1vZGUgPSBudWxscHRyOworICBJTUFRZHhWaWRlb01vZGUqIGN1cnJlbnRNb2RlUHRyID0gJm1vZGVzW2N1cnJlbnRNb2RlXTsKKyAgZG91YmxlIGZvdW5kRnBzID0gMTAwMC4wOworCisgIC8vIExvb3AgdGhyb3VnaCB0aGUgbW9kZXMsIGFuZCBmaW5kIHRoZSBtYXRjaCB3aXRoIHRoZSBsb3dlc3QgZnBzCisgIGZvciAodW5zaWduZWQgaW50IGkgPSAwOyBpIDwgY291bnQ7IGkrKykgeworICAgIHN0ZDo6Y21hdGNoIG07CisgICAgaWYgKCFzdGQ6OnJlZ2V4X21hdGNoKG1vZGVzW2ldLk5hbWUsIG0sIHJlTW9kZSkpIGNvbnRpbnVlOworICAgIHVuc2lnbmVkIGludCB3aWR0aCA9ICh1bnNpZ25lZCBpbnQpc3RkOjpzdG91bChtWzFdLnN0cigpKTsKKyAgICB1bnNpZ25lZCBpbnQgaGVpZ2h0ID0gKHVuc2lnbmVkIGludClzdGQ6OnN0b3VsKG1bMl0uc3RyKCkpOworICAgIGlmICh3aWR0aCAhPSBtX3dpZHRoKSBjb250aW51ZTsKKyAgICBpZiAoaGVpZ2h0ICE9IG1faGVpZ2h0KSBjb250aW51ZTsKKyAgICBkb3VibGUgZnBzID0gYXRvZihtWzRdLnN0cigpLmNfc3RyKCkpOworICAgIGlmIChmcHMgPCBtX2ZwcykgY29udGludWU7CisgICAgaWYgKGZwcyA+IGZvdW5kRnBzKSBjb250aW51ZTsKKyAgICBib29sIGlzSnBlZyA9CisgICAgICAgIG1bM10uc3RyKCkuY29tcGFyZSgianBlZyIpID09IDAgfHwgbVszXS5zdHIoKS5jb21wYXJlKCJKUEVHIikgPT0gMDsKKyAgICBpZiAoKG1fdXNlSnBlZyAmJiAhaXNKcGVnKSB8fCAoIW1fdXNlSnBlZyAmJiBpc0pwZWcpKSBjb250aW51ZTsKKyAgICBmb3VuZE1vZGUgPSAmbW9kZXNbaV07CisgICAgZm91bmRGcHMgPSBmcHM7CisgIH0KKyAgaWYgKGZvdW5kTW9kZSAhPSBudWxscHRyKSB7CisgICAgaWYgKGZvdW5kTW9kZS0+VmFsdWUgIT0gY3VycmVudE1vZGVQdHItPlZhbHVlKSB7CisgICAgICBTQUZFX0lNQVFfQ0FMTChJTUFRZHhTZXRBdHRyaWJ1dGUsIG1faWQsIElNQVFkeEF0dHJpYnV0ZVZpZGVvTW9kZSwKKyAgICAgICAgICAgICAgICAgICAgIElNQVFkeFZhbHVlVHlwZVUzMiwgZm91bmRNb2RlLT5WYWx1ZSk7CisgICAgfQorICB9CisKKyAgaWYgKG1fd2hpdGVCYWxhbmNlLmNvbXBhcmUoQVVUTykgPT0gMCkgeworICAgIFNBRkVfSU1BUV9DQUxMKElNQVFkeFNldEF0dHJpYnV0ZSwgbV9pZCwgQVRUUl9XQl9NT0RFLAorICAgICAgICAgICAgICAgICAgIElNQVFkeFZhbHVlVHlwZVN0cmluZywgQVVUTyk7CisgIH0gZWxzZSB7CisgICAgU0FGRV9JTUFRX0NBTEwoSU1BUWR4U2V0QXR0cmlidXRlLCBtX2lkLCBBVFRSX1dCX01PREUsCisgICAgICAgICAgICAgICAgICAgSU1BUWR4VmFsdWVUeXBlU3RyaW5nLCBNQU5VQUwpOworICAgIGlmIChtX3doaXRlQmFsYW5jZVZhbHVlUHJlc2VudCkKKyAgICAgIFNBRkVfSU1BUV9DQUxMKElNQVFkeFNldEF0dHJpYnV0ZSwgbV9pZCwgQVRUUl9XQl9WQUxVRSwKKyAgICAgICAgICAgICAgICAgICAgIElNQVFkeFZhbHVlVHlwZVUzMiwgbV93aGl0ZUJhbGFuY2VWYWx1ZSk7CisgIH0KKworICBpZiAobV9leHBvc3VyZS5jb21wYXJlKEFVVE8pID09IDApIHsKKyAgICBTQUZFX0lNQVFfQ0FMTChJTUFRZHhTZXRBdHRyaWJ1dGUsIG1faWQsIEFUVFJfRVhfTU9ERSwKKyAgICAgICAgICAgICAgICAgICBJTUFRZHhWYWx1ZVR5cGVTdHJpbmcsCisgICAgICAgICAgICAgICAgICAgc3RkOjpzdHJpbmcoIkF1dG9BcGVyYXR1cmVQcmlvcml0eSIpLmNfc3RyKCkpOworICB9IGVsc2UgeworICAgIFNBRkVfSU1BUV9DQUxMKElNQVFkeFNldEF0dHJpYnV0ZSwgbV9pZCwgQVRUUl9FWF9NT0RFLAorICAgICAgICAgICAgICAgICAgIElNQVFkeFZhbHVlVHlwZVN0cmluZywgTUFOVUFMKTsKKyAgICBpZiAobV9leHBvc3VyZVZhbHVlUHJlc2VudCkgeworICAgICAgZG91YmxlIG1pbnYgPSAwLjA7CisgICAgICBkb3VibGUgbWF4diA9IDAuMDsKKyAgICAgIFNBRkVfSU1BUV9DQUxMKElNQVFkeEdldEF0dHJpYnV0ZU1pbmltdW0sIG1faWQsIEFUVFJfRVhfVkFMVUUsCisgICAgICAgICAgICAgICAgICAgICBJTUFRZHhWYWx1ZVR5cGVGNjQsICZtaW52KTsKKyAgICAgIFNBRkVfSU1BUV9DQUxMKElNQVFkeEdldEF0dHJpYnV0ZU1heGltdW0sIG1faWQsIEFUVFJfRVhfVkFMVUUsCisgICAgICAgICAgICAgICAgICAgICBJTUFRZHhWYWx1ZVR5cGVGNjQsICZtYXh2KTsKKyAgICAgIGRvdWJsZSB2YWwgPSBtaW52ICsgKChtYXh2IC0gbWludikgKiAoKGRvdWJsZSltX2V4cG9zdXJlVmFsdWUgLyAxMDAuMCkpOworICAgICAgU0FGRV9JTUFRX0NBTEwoSU1BUWR4U2V0QXR0cmlidXRlLCBtX2lkLCBBVFRSX0VYX1ZBTFVFLAorICAgICAgICAgICAgICAgICAgICAgSU1BUWR4VmFsdWVUeXBlRjY0LCB2YWwpOworICAgIH0KKyAgfQorCisgIFNBRkVfSU1BUV9DQUxMKElNQVFkeFNldEF0dHJpYnV0ZSwgbV9pZCwgQVRUUl9CUl9NT0RFLCBJTUFRZHhWYWx1ZVR5cGVTdHJpbmcsCisgICAgICAgICAgICAgICAgIE1BTlVBTCk7CisgIGRvdWJsZSBtaW52ID0gMC4wOworICBkb3VibGUgbWF4diA9IDAuMDsKKyAgU0FGRV9JTUFRX0NBTEwoSU1BUWR4R2V0QXR0cmlidXRlTWluaW11bSwgbV9pZCwgQVRUUl9CUl9WQUxVRSwKKyAgICAgICAgICAgICAgICAgSU1BUWR4VmFsdWVUeXBlRjY0LCAmbWludik7CisgIFNBRkVfSU1BUV9DQUxMKElNQVFkeEdldEF0dHJpYnV0ZU1heGltdW0sIG1faWQsIEFUVFJfQlJfVkFMVUUsCisgICAgICAgICAgICAgICAgIElNQVFkeFZhbHVlVHlwZUY2NCwgJm1heHYpOworICBkb3VibGUgdmFsID0gbWludiArICgobWF4diAtIG1pbnYpICogKChkb3VibGUpbV9icmlnaHRuZXNzIC8gMTAwLjApKTsKKyAgU0FGRV9JTUFRX0NBTEwoSU1BUWR4U2V0QXR0cmlidXRlLCBtX2lkLCBBVFRSX0JSX1ZBTFVFLCBJTUFRZHhWYWx1ZVR5cGVGNjQsCisgICAgICAgICAgICAgICAgIHZhbCk7CisKKyAgaWYgKHdhc0FjdGl2ZSkgU3RhcnRDYXB0dXJlKCk7Cit9CisKK3ZvaWQgVVNCQ2FtZXJhOjpTZXRGUFMoZG91YmxlIGZwcykgeworICBzdGQ6OmxvY2tfZ3VhcmQ8cHJpb3JpdHlfcmVjdXJzaXZlX211dGV4PiBsb2NrKG1fbXV0ZXgpOworICBpZiAobV9mcHMgIT0gZnBzKSB7CisgICAgbV9uZWVkU2V0dGluZ3NVcGRhdGUgPSB0cnVlOworICAgIG1fZnBzID0gZnBzOworICB9Cit9CisKK3ZvaWQgVVNCQ2FtZXJhOjpTZXRTaXplKHVuc2lnbmVkIGludCB3aWR0aCwgdW5zaWduZWQgaW50IGhlaWdodCkgeworICBzdGQ6OmxvY2tfZ3VhcmQ8cHJpb3JpdHlfcmVjdXJzaXZlX211dGV4PiBsb2NrKG1fbXV0ZXgpOworICBpZiAobV93aWR0aCAhPSB3aWR0aCB8fCBtX2hlaWdodCAhPSBoZWlnaHQpIHsKKyAgICBtX25lZWRTZXR0aW5nc1VwZGF0ZSA9IHRydWU7CisgICAgbV93aWR0aCA9IHdpZHRoOworICAgIG1faGVpZ2h0ID0gaGVpZ2h0OworICB9Cit9CisKK3ZvaWQgVVNCQ2FtZXJhOjpTZXRCcmlnaHRuZXNzKHVuc2lnbmVkIGludCBicmlnaHRuZXNzKSB7CisgIHN0ZDo6bG9ja19ndWFyZDxwcmlvcml0eV9yZWN1cnNpdmVfbXV0ZXg+IGxvY2sobV9tdXRleCk7CisgIGlmIChtX2JyaWdodG5lc3MgIT0gYnJpZ2h0bmVzcykgeworICAgIG1fbmVlZFNldHRpbmdzVXBkYXRlID0gdHJ1ZTsKKyAgICBtX2JyaWdodG5lc3MgPSBicmlnaHRuZXNzOworICB9Cit9CisKK3Vuc2lnbmVkIGludCBVU0JDYW1lcmE6OkdldEJyaWdodG5lc3MoKSB7CisgIHN0ZDo6bG9ja19ndWFyZDxwcmlvcml0eV9yZWN1cnNpdmVfbXV0ZXg+IGxvY2sobV9tdXRleCk7CisgIHJldHVybiBtX2JyaWdodG5lc3M7Cit9CisKK3ZvaWQgVVNCQ2FtZXJhOjpTZXRXaGl0ZUJhbGFuY2VBdXRvKCkgeworICBzdGQ6OmxvY2tfZ3VhcmQ8cHJpb3JpdHlfcmVjdXJzaXZlX211dGV4PiBsb2NrKG1fbXV0ZXgpOworICBtX3doaXRlQmFsYW5jZSA9IEFVVE87CisgIG1fd2hpdGVCYWxhbmNlVmFsdWUgPSAwOworICBtX3doaXRlQmFsYW5jZVZhbHVlUHJlc2VudCA9IGZhbHNlOworICBtX25lZWRTZXR0aW5nc1VwZGF0ZSA9IHRydWU7Cit9CisKK3ZvaWQgVVNCQ2FtZXJhOjpTZXRXaGl0ZUJhbGFuY2VIb2xkQ3VycmVudCgpIHsKKyAgc3RkOjpsb2NrX2d1YXJkPHByaW9yaXR5X3JlY3Vyc2l2ZV9tdXRleD4gbG9jayhtX211dGV4KTsKKyAgbV93aGl0ZUJhbGFuY2UgPSBNQU5VQUw7CisgIG1fd2hpdGVCYWxhbmNlVmFsdWUgPSAwOworICBtX3doaXRlQmFsYW5jZVZhbHVlUHJlc2VudCA9IGZhbHNlOworICBtX25lZWRTZXR0aW5nc1VwZGF0ZSA9IHRydWU7Cit9CisKK3ZvaWQgVVNCQ2FtZXJhOjpTZXRXaGl0ZUJhbGFuY2VNYW51YWwodW5zaWduZWQgaW50IHdoaXRlQmFsYW5jZSkgeworICBzdGQ6OmxvY2tfZ3VhcmQ8cHJpb3JpdHlfcmVjdXJzaXZlX211dGV4PiBsb2NrKG1fbXV0ZXgpOworICBtX3doaXRlQmFsYW5jZSA9IE1BTlVBTDsKKyAgbV93aGl0ZUJhbGFuY2VWYWx1ZSA9IHdoaXRlQmFsYW5jZTsKKyAgbV93aGl0ZUJhbGFuY2VWYWx1ZVByZXNlbnQgPSB0cnVlOworICBtX25lZWRTZXR0aW5nc1VwZGF0ZSA9IHRydWU7Cit9CisKK3ZvaWQgVVNCQ2FtZXJhOjpTZXRFeHBvc3VyZUF1dG8oKSB7CisgIHN0ZDo6bG9ja19ndWFyZDxwcmlvcml0eV9yZWN1cnNpdmVfbXV0ZXg+IGxvY2sobV9tdXRleCk7CisgIG1fZXhwb3N1cmUgPSBBVVRPOworICBtX2V4cG9zdXJlVmFsdWUgPSAwOworICBtX2V4cG9zdXJlVmFsdWVQcmVzZW50ID0gZmFsc2U7CisgIG1fbmVlZFNldHRpbmdzVXBkYXRlID0gdHJ1ZTsKK30KKwordm9pZCBVU0JDYW1lcmE6OlNldEV4cG9zdXJlSG9sZEN1cnJlbnQoKSB7CisgIHN0ZDo6bG9ja19ndWFyZDxwcmlvcml0eV9yZWN1cnNpdmVfbXV0ZXg+IGxvY2sobV9tdXRleCk7CisgIG1fZXhwb3N1cmUgPSBNQU5VQUw7CisgIG1fZXhwb3N1cmVWYWx1ZSA9IDA7CisgIG1fZXhwb3N1cmVWYWx1ZVByZXNlbnQgPSBmYWxzZTsKKyAgbV9uZWVkU2V0dGluZ3NVcGRhdGUgPSB0cnVlOworfQorCit2b2lkIFVTQkNhbWVyYTo6U2V0RXhwb3N1cmVNYW51YWwodW5zaWduZWQgaW50IGxldmVsKSB7CisgIHN0ZDo6bG9ja19ndWFyZDxwcmlvcml0eV9yZWN1cnNpdmVfbXV0ZXg+IGxvY2sobV9tdXRleCk7CisgIG1fZXhwb3N1cmUgPSBNQU5VQUw7CisgIGlmIChsZXZlbCA+IDEwMCkKKyAgICBtX2V4cG9zdXJlVmFsdWUgPSAxMDA7CisgIGVsc2UKKyAgICBtX2V4cG9zdXJlVmFsdWUgPSBsZXZlbDsKKyAgbV9leHBvc3VyZVZhbHVlUHJlc2VudCA9IHRydWU7CisgIG1fbmVlZFNldHRpbmdzVXBkYXRlID0gdHJ1ZTsKK30KKwordm9pZCBVU0JDYW1lcmE6OkdldEltYWdlKEltYWdlKiBpbWFnZSkgeworICBzdGQ6OmxvY2tfZ3VhcmQ8cHJpb3JpdHlfcmVjdXJzaXZlX211dGV4PiBsb2NrKG1fbXV0ZXgpOworICBpZiAobV9uZWVkU2V0dGluZ3NVcGRhdGUgfHwgbV91c2VKcGVnKSB7CisgICAgbV9uZWVkU2V0dGluZ3NVcGRhdGUgPSBmYWxzZTsKKyAgICBtX3VzZUpwZWcgPSBmYWxzZTsKKyAgICBVcGRhdGVTZXR0aW5ncygpOworICB9CisgIC8vIEJ1Zk51bSBpcyBub3QgYWN0dWFsbHkgdXNlZCBmb3IgYW55dGhpbmcgYXQgb3VyIGxldmVsLCBzaW5jZSB3ZSBhcmUKKyAgLy8gd2FpdGluZyB1bnRpbCB0aGUgbmV4dCBpbWFnZSBpcyByZWFkeSBhbnl3YXkKKyAgdUludDMyIGJ1Zk51bTsKKyAgU0FGRV9JTUFRX0NBTEwoSU1BUWR4R3JhYiwgbV9pZCwgaW1hZ2UsIDEsICZidWZOdW0pOworfQorCit1bnNpZ25lZCBpbnQgVVNCQ2FtZXJhOjpHZXRJbWFnZURhdGEodm9pZCogYnVmZmVyLCB1bnNpZ25lZCBpbnQgYnVmZmVyU2l6ZSkgeworICBzdGQ6OmxvY2tfZ3VhcmQ8cHJpb3JpdHlfcmVjdXJzaXZlX211dGV4PiBsb2NrKG1fbXV0ZXgpOworICBpZiAobV9uZWVkU2V0dGluZ3NVcGRhdGUgfHwgIW1fdXNlSnBlZykgeworICAgIG1fbmVlZFNldHRpbmdzVXBkYXRlID0gZmFsc2U7CisgICAgbV91c2VKcGVnID0gdHJ1ZTsKKyAgICBVcGRhdGVTZXR0aW5ncygpOworICB9CisgIC8vIEJ1Zk51bSBpcyBub3QgYWN0dWFsbHkgdXNlZCBmb3IgYW55dGhpbmcgYXQgb3VyIGxldmVsCisgIHVJbnQzMiBidWZOdW07CisgIFNBRkVfSU1BUV9DQUxMKElNQVFkeEdldEltYWdlRGF0YSwgbV9pZCwgYnVmZmVyLCBidWZmZXJTaXplLAorICAgICAgICAgICAgICAgICBJTUFRZHhCdWZmZXJOdW1iZXJNb2RlTGFzdCwgMCwgJmJ1Zk51bSk7CisgIHJldHVybiBHZXRKcGVnU2l6ZShidWZmZXIsIGJ1ZmZlclNpemUpOworfQpkaWZmIC0tZ2l0IGEvd3BpbGliYy9BdGhlbmEvc3JjL1VsdHJhc29uaWMuY3BwIGIvd3BpbGliYy9BdGhlbmEvc3JjL1VsdHJhc29uaWMuY3BwCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmJhMjVhMDQKLS0tIC9kZXYvbnVsbAorKysgYi93cGlsaWJjL0F0aGVuYS9zcmMvVWx0cmFzb25pYy5jcHAKQEAgLTAsMCArMSwzNTQgQEAKKy8qLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovCisvKiBDb3B5cmlnaHQgKGMpIEZJUlNUIDIwMDguIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCisgKi8KKy8qIE9wZW4gU291cmNlIFNvZnR3YXJlIC0gbWF5IGJlIG1vZGlmaWVkIGFuZCBzaGFyZWQgYnkgRlJDIHRlYW1zLiBUaGUgY29kZSAgICovCisvKiBtdXN0IGJlIGFjY29tcGFuaWVkIGJ5IHRoZSBGSVJTVCBCU0QgbGljZW5zZSBmaWxlIGluICQoV0lORF9CQVNFKS9XUElMaWIuICAqLworLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi8KKworI2luY2x1ZGUgIlVsdHJhc29uaWMuaCIKKworI2luY2x1ZGUgIkNvdW50ZXIuaCIKKyNpbmNsdWRlICJEaWdpdGFsSW5wdXQuaCIKKyNpbmNsdWRlICJEaWdpdGFsT3V0cHV0LmgiCisjaW5jbHVkZSAiVGltZXIuaCIKKyNpbmNsdWRlICJVdGlsaXR5LmgiCisjaW5jbHVkZSAiV1BJRXJyb3JzLmgiCisjaW5jbHVkZSAiTGl2ZVdpbmRvdy9MaXZlV2luZG93LmgiCisKK2NvbnN0ZXhwciBkb3VibGUKKyAgICBVbHRyYXNvbmljOjprUGluZ1RpbWU7ICAvLy88IFRpbWUgKHNlYykgZm9yIHRoZSBwaW5nIHRyaWdnZXIgcHVsc2UuCitjb25zdCB1aW50MzJfdCBVbHRyYXNvbmljOjprUHJpb3JpdHk7ICAvLy88IFByaW9yaXR5IHRoYXQgdGhlIHVsdHJhc29uaWMgcm91bmQKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vL3JvYmluIHRhc2sgcnVucy4KK2NvbnN0ZXhwciBkb3VibGUKKyAgICBVbHRyYXNvbmljOjprTWF4VWx0cmFzb25pY1RpbWU7ICAvLy88IE1heCB0aW1lIChtcykgYmV0d2VlbiByZWFkaW5ncy4KK2NvbnN0ZXhwciBkb3VibGUgVWx0cmFzb25pYzo6a1NwZWVkT2ZTb3VuZEluY2hlc1BlclNlYzsKK1VsdHJhc29uaWMgKlVsdHJhc29uaWM6Om1fZmlyc3RTZW5zb3IgPQorICAgIG51bGxwdHI7ICAvLyBoZWFkIG9mIHRoZSB1bHRyYXNvbmljIHNlbnNvciBsaXN0CitUYXNrIFVsdHJhc29uaWM6Om1fdGFzazsKK3N0ZDo6YXRvbWljPGJvb2w+IFVsdHJhc29uaWM6Om1fYXV0b21hdGljRW5hYmxlZHtmYWxzZX07IC8vIGF1dG9tYXRpYyByb3VuZCByb2JpbiBtb2RlCitwcmlvcml0eV9tdXRleCBVbHRyYXNvbmljOjptX211dGV4OworCisvKioKKyAqIEJhY2tncm91bmQgdGFzayB0aGF0IGdvZXMgdGhyb3VnaCB0aGUgbGlzdCBvZiB1bHRyYXNvbmljIHNlbnNvcnMgYW5kIHBpbmdzCisgKiBlYWNoIG9uZSBpbiB0dXJuLiBUaGUgY291bnRlcgorICogaXMgY29uZmlndXJlZCB0byByZWFkIHRoZSB0aW1pbmcgb2YgdGhlIHJldHVybmVkIGVjaG8gcHVsc2UuCisgKgorICogREFOR0VSIFdJTEwgUk9CSU5TT04sIERBTkdFUiBXSUxMIFJPQklOU09OOgorICogVGhpcyBjb2RlIHJ1bnMgYXMgYSB0YXNrIGFuZCBhc3N1bWVzIHRoYXQgbm9uZSBvZiB0aGUgdWx0cmFzb25pYyBzZW5zb3JzIHdpbGwKKyAqIGNoYW5nZSB3aGlsZSBpdCdzCisgKiBydW5uaW5nLiBJZiBvbmUgZG9lcywgdGhlbiB0aGlzIHdpbGwgY2VydGFpbmx5IGJyZWFrLiBNYWtlIHN1cmUgdG8gZGlzYWJsZQorICogYXV0b21hdGljIG1vZGUgYmVmb3JlIGNoYW5naW5nCisgKiBhbnl0aGluZyB3aXRoIHRoZSBzZW5zb3JzISEKKyAqLwordm9pZCBVbHRyYXNvbmljOjpVbHRyYXNvbmljQ2hlY2tlcigpIHsKKyAgVWx0cmFzb25pYyAqdSA9IG51bGxwdHI7CisgIHdoaWxlIChtX2F1dG9tYXRpY0VuYWJsZWQpIHsKKyAgICBpZiAodSA9PSBudWxscHRyKSB1ID0gbV9maXJzdFNlbnNvcjsKKyAgICBpZiAodSA9PSBudWxscHRyKSByZXR1cm47CisgICAgaWYgKHUtPklzRW5hYmxlZCgpKSB1LT5tX3BpbmdDaGFubmVsLT5QdWxzZShrUGluZ1RpbWUpOyAgLy8gZG8gdGhlIHBpbmcKKyAgICB1ID0gdS0+bV9uZXh0U2Vuc29yOworICAgIFdhaXQoMC4xKTsgIC8vIHdhaXQgZm9yIHBpbmcgdG8gcmV0dXJuCisgIH0KK30KKworLyoqCisgKiBJbml0aWFsaXplIHRoZSBVbHRyYXNvbmljIFNlbnNvci4KKyAqIFRoaXMgaXMgdGhlIGNvbW1vbiBjb2RlIHRoYXQgaW5pdGlhbGl6ZXMgdGhlIHVsdHJhc29uaWMgc2Vuc29yIGdpdmVuIHRoYXQKKyAqIHRoZXJlCisgKiBhcmUgdHdvIGRpZ2l0YWwgSS9PIGNoYW5uZWxzIGFsbG9jYXRlZC4gSWYgdGhlIHN5c3RlbSB3YXMgcnVubmluZyBpbgorICogYXV0b21hdGljIG1vZGUgKHJvdW5kIHJvYmluKQorICogd2hlbiB0aGUgbmV3IHNlbnNvciBpcyBhZGRlZCwgaXQgaXMgc3RvcHBlZCwgdGhlIHNlbnNvciBpcyBhZGRlZCwgdGhlbgorICogYXV0b21hdGljIG1vZGUgaXMKKyAqIHJlc3RvcmVkLgorICovCit2b2lkIFVsdHJhc29uaWM6OkluaXRpYWxpemUoKSB7CisgIGJvb2wgb3JpZ2luYWxNb2RlID0gbV9hdXRvbWF0aWNFbmFibGVkOworICBTZXRBdXRvbWF0aWNNb2RlKGZhbHNlKTsgICAgIC8vIGtpbGwgdGFzayB3aGVuIGFkZGluZyBhIG5ldyBzZW5zb3IKKyAgLy8gbGluayB0aGlzIGluc3RhbmNlIG9uIHRoZSBsaXN0CisgIHsKKyAgICBzdGQ6OmxvY2tfZ3VhcmQ8cHJpb3JpdHlfbXV0ZXg+IGxvY2sobV9tdXRleCk7CisgICAgbV9uZXh0U2Vuc29yID0gbV9maXJzdFNlbnNvcjsKKyAgICBtX2ZpcnN0U2Vuc29yID0gdGhpczsKKyAgfQorCisgIG1fY291bnRlci5TZXRNYXhQZXJpb2QoMS4wKTsKKyAgbV9jb3VudGVyLlNldFNlbWlQZXJpb2RNb2RlKHRydWUpOworICBtX2NvdW50ZXIuUmVzZXQoKTsKKyAgbV9lbmFibGVkID0gdHJ1ZTsgIC8vIG1ha2UgaXQgYXZhaWxhYmxlIGZvciByb3VuZCByb2JpbiBzY2hlZHVsaW5nCisgIFNldEF1dG9tYXRpY01vZGUob3JpZ2luYWxNb2RlKTsKKworICBzdGF0aWMgaW50IGluc3RhbmNlcyA9IDA7CisgIGluc3RhbmNlcysrOworICBIQUxSZXBvcnQoSEFMVXNhZ2VSZXBvcnRpbmc6OmtSZXNvdXJjZVR5cGVfVWx0cmFzb25pYywgaW5zdGFuY2VzKTsKKyAgTGl2ZVdpbmRvdzo6R2V0SW5zdGFuY2UoKS0+QWRkU2Vuc29yKCJVbHRyYXNvbmljIiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1fZWNob0NoYW5uZWwtPkdldENoYW5uZWwoKSwgdGhpcyk7Cit9CisKKy8qKgorICogQ3JlYXRlIGFuIGluc3RhbmNlIG9mIHRoZSBVbHRyYXNvbmljIFNlbnNvcgorICogVGhpcyBpcyBkZXNpZ25lZCB0byBzdXBjaGFubmVsIHRoZSBEYXZlbnRlY2ggU1JGMDQgYW5kIFZleCB1bHRyYXNvbmljCisgKiBzZW5zb3JzLgorICogQHBhcmFtIHBpbmdDaGFubmVsIFRoZSBkaWdpdGFsIG91dHB1dCBjaGFubmVsIHRoYXQgc2VuZHMgdGhlIHB1bHNlIHRvCisgKiBpbml0aWF0ZSB0aGUgc2Vuc29yIHNlbmRpbmcKKyAqIHRoZSBwaW5nLgorICogQHBhcmFtIGVjaG9DaGFubmVsIFRoZSBkaWdpdGFsIGlucHV0IGNoYW5uZWwgdGhhdCByZWNlaXZlcyB0aGUgZWNoby4gVGhlCisgKiBsZW5ndGggb2YgdGltZSB0aGF0IHRoZQorICogZWNobyBpcyBoaWdoIHJlcHJlc2VudHMgdGhlIHJvdW5kIHRyaXAgdGltZSBvZiB0aGUgcGluZywgYW5kIHRoZSBkaXN0YW5jZS4KKyAqIEBwYXJhbSB1bml0cyBUaGUgdW5pdHMgcmV0dXJuZWQgaW4gZWl0aGVyIGtJbmNoZXMgb3Iga01pbGxpTWV0ZXJzCisgKi8KK1VsdHJhc29uaWM6OlVsdHJhc29uaWModWludDMyX3QgcGluZ0NoYW5uZWwsIHVpbnQzMl90IGVjaG9DaGFubmVsLAorICAgICAgICAgICAgICAgICAgICAgICBEaXN0YW5jZVVuaXQgdW5pdHMpCisgICAgOiBtX3BpbmdDaGFubmVsKHN0ZDo6bWFrZV9zaGFyZWQ8RGlnaXRhbE91dHB1dD4ocGluZ0NoYW5uZWwpKSwKKyAgICAgIG1fZWNob0NoYW5uZWwoc3RkOjptYWtlX3NoYXJlZDxEaWdpdGFsSW5wdXQ+KGVjaG9DaGFubmVsKSksCisgICAgICBtX2NvdW50ZXIobV9lY2hvQ2hhbm5lbCkgeworICBtX3VuaXRzID0gdW5pdHM7CisgIEluaXRpYWxpemUoKTsKK30KKworLyoqCisgKiBDcmVhdGUgYW4gaW5zdGFuY2Ugb2YgYW4gVWx0cmFzb25pYyBTZW5zb3IgZnJvbSBhIERpZ2l0YWxJbnB1dCBmb3IgdGhlIGVjaG8KKyAqIGNoYW5uZWwgYW5kIGEgRGlnaXRhbE91dHB1dAorICogZm9yIHRoZSBwaW5nIGNoYW5uZWwuCisgKiBAcGFyYW0gcGluZ0NoYW5uZWwgVGhlIGRpZ2l0YWwgb3V0cHV0IG9iamVjdCB0aGF0IHN0YXJ0cyB0aGUgc2Vuc29yIGRvaW5nIGEKKyAqIHBpbmcuIFJlcXVpcmVzIGEgMTB1UyBwdWxzZSB0byBzdGFydC4KKyAqIEBwYXJhbSBlY2hvQ2hhbm5lbCBUaGUgZGlnaXRhbCBpbnB1dCBvYmplY3QgdGhhdCB0aW1lcyB0aGUgcmV0dXJuIHB1bHNlIHRvCisgKiBkZXRlcm1pbmUgdGhlIHJhbmdlLgorICogQHBhcmFtIHVuaXRzIFRoZSB1bml0cyByZXR1cm5lZCBpbiBlaXRoZXIga0luY2hlcyBvciBrTWlsbGlNZXRlcnMKKyAqLworVWx0cmFzb25pYzo6VWx0cmFzb25pYyhEaWdpdGFsT3V0cHV0ICpwaW5nQ2hhbm5lbCwgRGlnaXRhbElucHV0ICplY2hvQ2hhbm5lbCwKKyAgICAgICAgICAgICAgICAgICAgICAgRGlzdGFuY2VVbml0IHVuaXRzKQorICAgIDogbV9waW5nQ2hhbm5lbChwaW5nQ2hhbm5lbCwgTnVsbERlbGV0ZXI8RGlnaXRhbE91dHB1dD4oKSksCisgICAgICBtX2VjaG9DaGFubmVsKGVjaG9DaGFubmVsLCBOdWxsRGVsZXRlcjxEaWdpdGFsSW5wdXQ+KCkpLAorICAgICAgbV9jb3VudGVyKG1fZWNob0NoYW5uZWwpIHsKKyAgaWYgKHBpbmdDaGFubmVsID09IG51bGxwdHIgfHwgZWNob0NoYW5uZWwgPT0gbnVsbHB0cikgeworICAgIHdwaV9zZXRXUElFcnJvcihOdWxsUGFyYW1ldGVyKTsKKyAgICBtX25leHRTZW5zb3IgPSBudWxscHRyOworICAgIG1fdW5pdHMgPSB1bml0czsKKyAgICByZXR1cm47CisgIH0KKyAgbV91bml0cyA9IHVuaXRzOworICBJbml0aWFsaXplKCk7Cit9CisKKy8qKgorICogQ3JlYXRlIGFuIGluc3RhbmNlIG9mIGFuIFVsdHJhc29uaWMgU2Vuc29yIGZyb20gYSBEaWdpdGFsSW5wdXQgZm9yIHRoZSBlY2hvCisgKiBjaGFubmVsIGFuZCBhIERpZ2l0YWxPdXRwdXQKKyAqIGZvciB0aGUgcGluZyBjaGFubmVsLgorICogQHBhcmFtIHBpbmdDaGFubmVsIFRoZSBkaWdpdGFsIG91dHB1dCBvYmplY3QgdGhhdCBzdGFydHMgdGhlIHNlbnNvciBkb2luZyBhCisgKiBwaW5nLiBSZXF1aXJlcyBhIDEwdVMgcHVsc2UgdG8gc3RhcnQuCisgKiBAcGFyYW0gZWNob0NoYW5uZWwgVGhlIGRpZ2l0YWwgaW5wdXQgb2JqZWN0IHRoYXQgdGltZXMgdGhlIHJldHVybiBwdWxzZSB0bworICogZGV0ZXJtaW5lIHRoZSByYW5nZS4KKyAqIEBwYXJhbSB1bml0cyBUaGUgdW5pdHMgcmV0dXJuZWQgaW4gZWl0aGVyIGtJbmNoZXMgb3Iga01pbGxpTWV0ZXJzCisgKi8KK1VsdHJhc29uaWM6OlVsdHJhc29uaWMoRGlnaXRhbE91dHB1dCAmcGluZ0NoYW5uZWwsIERpZ2l0YWxJbnB1dCAmZWNob0NoYW5uZWwsCisgICAgICAgICAgICAgICAgICAgICAgIERpc3RhbmNlVW5pdCB1bml0cykKKyAgICA6IG1fcGluZ0NoYW5uZWwoJnBpbmdDaGFubmVsLCBOdWxsRGVsZXRlcjxEaWdpdGFsT3V0cHV0PigpKSwKKyAgICAgIG1fZWNob0NoYW5uZWwoJmVjaG9DaGFubmVsLCBOdWxsRGVsZXRlcjxEaWdpdGFsSW5wdXQ+KCkpLAorICAgICAgbV9jb3VudGVyKG1fZWNob0NoYW5uZWwpIHsKKyAgbV91bml0cyA9IHVuaXRzOworICBJbml0aWFsaXplKCk7Cit9CisKKy8qKgorICogQ3JlYXRlIGFuIGluc3RhbmNlIG9mIGFuIFVsdHJhc29uaWMgU2Vuc29yIGZyb20gYSBEaWdpdGFsSW5wdXQgZm9yIHRoZSBlY2hvCisgKiBjaGFubmVsIGFuZCBhIERpZ2l0YWxPdXRwdXQKKyAqIGZvciB0aGUgcGluZyBjaGFubmVsLgorICogQHBhcmFtIHBpbmdDaGFubmVsIFRoZSBkaWdpdGFsIG91dHB1dCBvYmplY3QgdGhhdCBzdGFydHMgdGhlIHNlbnNvciBkb2luZyBhCisgKiBwaW5nLiBSZXF1aXJlcyBhIDEwdVMgcHVsc2UgdG8gc3RhcnQuCisgKiBAcGFyYW0gZWNob0NoYW5uZWwgVGhlIGRpZ2l0YWwgaW5wdXQgb2JqZWN0IHRoYXQgdGltZXMgdGhlIHJldHVybiBwdWxzZSB0bworICogZGV0ZXJtaW5lIHRoZSByYW5nZS4KKyAqIEBwYXJhbSB1bml0cyBUaGUgdW5pdHMgcmV0dXJuZWQgaW4gZWl0aGVyIGtJbmNoZXMgb3Iga01pbGxpTWV0ZXJzCisgKi8KK1VsdHJhc29uaWM6OlVsdHJhc29uaWMoc3RkOjpzaGFyZWRfcHRyPERpZ2l0YWxPdXRwdXQ+IHBpbmdDaGFubmVsLAorICAgICAgICAgICAgICAgICAgICAgICBzdGQ6OnNoYXJlZF9wdHI8RGlnaXRhbElucHV0PiBlY2hvQ2hhbm5lbCwKKyAgICAgICAgICAgICAgICAgICAgICAgRGlzdGFuY2VVbml0IHVuaXRzKQorICAgIDogbV9waW5nQ2hhbm5lbChwaW5nQ2hhbm5lbCksCisgICAgICBtX2VjaG9DaGFubmVsKGVjaG9DaGFubmVsKSwKKyAgICAgIG1fY291bnRlcihtX2VjaG9DaGFubmVsKSB7CisgIG1fdW5pdHMgPSB1bml0czsKKyAgSW5pdGlhbGl6ZSgpOworfQorCisvKioKKyAqIERlc3RydWN0b3IgZm9yIHRoZSB1bHRyYXNvbmljIHNlbnNvci4KKyAqIERlbGV0ZSB0aGUgaW5zdGFuY2Ugb2YgdGhlIHVsdHJhc29uaWMgc2Vuc29yIGJ5IGZyZWVpbmcgdGhlIGFsbG9jYXRlZCBkaWdpdGFsCisgKiBjaGFubmVscy4KKyAqIElmIHRoZSBzeXN0ZW0gd2FzIGluIGF1dG9tYXRpYyBtb2RlIChyb3VuZCByb2JpbiksIHRoZW4gaXQgaXMgc3RvcHBlZCwgdGhlbgorICogc3RhcnRlZCBhZ2FpbgorICogYWZ0ZXIgdGhpcyBzZW5zb3IgaXMgcmVtb3ZlZCAocHJvdmlkZWQgdGhpcyB3YXNuJ3QgdGhlIGxhc3Qgc2Vuc29yKS4KKyAqLworVWx0cmFzb25pYzo6flVsdHJhc29uaWMoKSB7CisgIGJvb2wgd2FzQXV0b21hdGljTW9kZSA9IG1fYXV0b21hdGljRW5hYmxlZDsKKyAgU2V0QXV0b21hdGljTW9kZShmYWxzZSk7CisgIHdwaV9hc3NlcnQobV9maXJzdFNlbnNvciAhPSBudWxscHRyKTsKKworICB7CisgICAgc3RkOjpsb2NrX2d1YXJkPHByaW9yaXR5X211dGV4PiBsb2NrKG1fbXV0ZXgpOworICAgIGlmICh0aGlzID09IG1fZmlyc3RTZW5zb3IpIHsKKyAgICAgIG1fZmlyc3RTZW5zb3IgPSBtX25leHRTZW5zb3I7CisgICAgICBpZiAobV9maXJzdFNlbnNvciA9PSBudWxscHRyKSB7CisgICAgICAgIFNldEF1dG9tYXRpY01vZGUoZmFsc2UpOworICAgICAgfQorICAgIH0gZWxzZSB7CisgICAgICB3cGlfYXNzZXJ0KG1fZmlyc3RTZW5zb3ItPm1fbmV4dFNlbnNvciAhPSBudWxscHRyKTsKKyAgICAgIGZvciAoVWx0cmFzb25pYyAqcyA9IG1fZmlyc3RTZW5zb3I7IHMgIT0gbnVsbHB0cjsgcyA9IHMtPm1fbmV4dFNlbnNvcikgeworICAgICAgICBpZiAodGhpcyA9PSBzLT5tX25leHRTZW5zb3IpIHsKKyAgICAgICAgICBzLT5tX25leHRTZW5zb3IgPSBzLT5tX25leHRTZW5zb3ItPm1fbmV4dFNlbnNvcjsKKyAgICAgICAgICBicmVhazsKKyAgICAgICAgfQorICAgICAgfQorICAgIH0KKyAgfQorICBpZiAobV9maXJzdFNlbnNvciAhPSBudWxscHRyICYmIHdhc0F1dG9tYXRpY01vZGUpIFNldEF1dG9tYXRpY01vZGUodHJ1ZSk7Cit9CisKKy8qKgorICogVHVybiBBdXRvbWF0aWMgbW9kZSBvbi9vZmYuCisgKiBXaGVuIGluIEF1dG9tYXRpYyBtb2RlLCBhbGwgc2Vuc29ycyB3aWxsIGZpcmUgaW4gcm91bmQgcm9iaW4sIHdhaXRpbmcgYSBzZXQKKyAqIHRpbWUgYmV0d2VlbiBlYWNoIHNlbnNvci4KKyAqIEBwYXJhbSBlbmFibGluZyBTZXQgdG8gdHJ1ZSBpZiByb3VuZCByb2JpbiBzY2hlZHVsaW5nIHNob3VsZCBzdGFydCBmb3IgYWxsCisgKiB0aGUgdWx0cmFzb25pYyBzZW5zb3JzLiBUaGlzCisgKiBzY2hlZHVsaW5nIG1ldGhvZCBhc3N1cmVzIHRoYXQgdGhlIHNlbnNvcnMgYXJlIG5vbi1pbnRlcmZlcmluZyBiZWNhdXNlIG5vIHR3bworICogc2Vuc29ycyBmaXJlIGF0IHRoZSBzYW1lIHRpbWUuCisgKiBJZiBhbm90aGVyIHNjaGVkdWxpbmcgYWxnb3JpdGhtIGlzIHByZWZlcmVkLCBpdCBjYW4gYmUgaW1wbGVtZW50ZWQgYnkKKyAqIHBpbmdpbmcgdGhlIHNlbnNvcnMgbWFudWFsbHkgYW5kIHdhaXRpbmcKKyAqIGZvciB0aGUgcmVzdWx0cyB0byBjb21lIGJhY2suCisgKi8KK3ZvaWQgVWx0cmFzb25pYzo6U2V0QXV0b21hdGljTW9kZShib29sIGVuYWJsaW5nKSB7CisgIGlmIChlbmFibGluZyA9PSBtX2F1dG9tYXRpY0VuYWJsZWQpIHJldHVybjsgIC8vIGlnbm9yZSB0aGUgY2FzZSBvZiBubyBjaGFuZ2UKKworICBtX2F1dG9tYXRpY0VuYWJsZWQgPSBlbmFibGluZzsKKyAgaWYgKGVuYWJsaW5nKSB7CisgICAgLy8gZW5hYmxpbmcgYXV0b21hdGljIG1vZGUuCisgICAgLy8gQ2xlYXIgYWxsIHRoZSBjb3VudGVycyBzbyBubyBkYXRhIGlzIHZhbGlkCisgICAgZm9yIChVbHRyYXNvbmljICp1ID0gbV9maXJzdFNlbnNvcjsgdSAhPSBudWxscHRyOyB1ID0gdS0+bV9uZXh0U2Vuc29yKSB7CisgICAgICB1LT5tX2NvdW50ZXIuUmVzZXQoKTsKKyAgICB9CisgICAgLy8gU3RhcnQgcm91bmQgcm9iaW4gdGFzaworICAgIHdwaV9hc3NlcnQobV90YXNrLlZlcmlmeSgpID09CisgICAgICAgICAgICAgICBmYWxzZSk7ICAvLyBzaG91bGQgYmUgZmFsc2Ugc2luY2Ugd2FzIHByZXZpb3VzbHkgZGlzYWJsZWQKKyAgICBtX3Rhc2sgPSBUYXNrKCJVbHRyYXNvbmljQ2hlY2tlciIsICZVbHRyYXNvbmljOjpVbHRyYXNvbmljQ2hlY2tlcik7CisKKyAgICAvLyBUT0RPOiBDdXJyZW50bHksIGx2dXNlciBkb2VzIG5vdCBoYXZlIHBlcm1pc3Npb25zIHRvIHNldCB0YXNrIHByaW9yaXRpZXMuCisgICAgLy8gVW50aWwgdGhhdCBpcyB0aGUgY2FzZSwgdW5jb21tZW50aW5nIHRoaXMgd2lsbCBicmVhayB1c2VyIGNvZGUgdGhhdCBjYWxscworICAgIC8vIFVsdHJhc29uaWM6OlNldEF1dG9taWNNb2RlKCkuCisgICAgLy9tX3Rhc2suU2V0UHJpb3JpdHkoa1ByaW9yaXR5KTsKKyAgfSBlbHNlIHsKKyAgICAvLyBkaXNhYmxpbmcgYXV0b21hdGljIG1vZGUuIFdhaXQgZm9yIGJhY2tncm91bmQgdGFzayB0byBzdG9wIHJ1bm5pbmcuCisgICAgd2hpbGUgKG1fdGFzay5WZXJpZnkoKSkKKyAgICAgIFdhaXQoMC4xNSk7ICAvLyBqdXN0IGEgbGl0dGxlIGxvbmdlciB0aGFuIHRoZSBwaW5nIHRpbWUgZm9yIHJvdW5kLXJvYmluIHRvCisgICAgICAgICAgICAgICAgICAgLy8gc3RvcAorCisgICAgLy8gY2xlYXIgYWxsIHRoZSBjb3VudGVycyAoZGF0YSBub3cgaW52YWxpZCkgc2luY2UgYXV0b21hdGljIG1vZGUgaXMgc3RvcHBlZAorICAgIGZvciAoVWx0cmFzb25pYyAqdSA9IG1fZmlyc3RTZW5zb3I7IHUgIT0gbnVsbHB0cjsgdSA9IHUtPm1fbmV4dFNlbnNvcikgeworICAgICAgdS0+bV9jb3VudGVyLlJlc2V0KCk7CisgICAgfQorICAgIG1fYXV0b21hdGljRW5hYmxlZCA9IGZhbHNlOworICAgIG1fdGFzay5qb2luKCk7CisgIH0KK30KKworLyoqCisgKiBTaW5nbGUgcGluZyB0byB1bHRyYXNvbmljIHNlbnNvci4KKyAqIFNlbmQgb3V0IGEgc2luZ2xlIHBpbmcgdG8gdGhlIHVsdHJhc29uaWMgc2Vuc29yLiBUaGlzIG9ubHkgd29ya3MgaWYgYXV0b21hdGljCisgKiAocm91bmQgcm9iaW4pCisgKiBtb2RlIGlzIGRpc2FibGVkLiBBIHNpbmdsZSBwaW5nIGlzIHNlbnQgb3V0LCBhbmQgdGhlIGNvdW50ZXIgc2hvdWxkIGNvdW50IHRoZQorICogc2VtaS1wZXJpb2QKKyAqIHdoZW4gaXQgY29tZXMgaW4uIFRoZSBjb3VudGVyIGlzIHJlc2V0IHRvIG1ha2UgdGhlIGN1cnJlbnQgdmFsdWUgaW52YWxpZC4KKyAqLwordm9pZCBVbHRyYXNvbmljOjpQaW5nKCkgeworICB3cGlfYXNzZXJ0KCFtX2F1dG9tYXRpY0VuYWJsZWQpOworICBtX2NvdW50ZXIuUmVzZXQoKTsgIC8vIHJlc2V0IHRoZSBjb3VudGVyIHRvIHplcm8gKGludmFsaWQgZGF0YSBub3cpCisgIG1fcGluZ0NoYW5uZWwtPlB1bHNlKAorICAgICAga1BpbmdUaW1lKTsgIC8vIGRvIHRoZSBwaW5nIHRvIHN0YXJ0IGdldHRpbmcgYSBzaW5nbGUgcmFuZ2UKK30KKworLyoqCisgKiBDaGVjayBpZiB0aGVyZSBpcyBhIHZhbGlkIHJhbmdlIG1lYXN1cmVtZW50LgorICogVGhlIHJhbmdlcyBhcmUgYWNjdW11bGF0ZWQgaW4gYSBjb3VudGVyIHRoYXQgd2lsbCBpbmNyZW1lbnQgb24gZWFjaCBlZGdlIG9mCisgKiB0aGUgZWNobyAocmV0dXJuKQorICogc2lnbmFsLiBJZiB0aGUgY291bnQgaXMgbm90IGF0IGxlYXN0IDIsIHRoZW4gdGhlIHJhbmdlIGhhcyBub3QgeWV0IGJlZW4KKyAqIG1lYXN1cmVkLCBhbmQgaXMgaW52YWxpZC4KKyAqLworYm9vbCBVbHRyYXNvbmljOjpJc1JhbmdlVmFsaWQoKSBjb25zdCB7IHJldHVybiBtX2NvdW50ZXIuR2V0KCkgPiAxOyB9CisKKy8qKgorICogR2V0IHRoZSByYW5nZSBpbiBpbmNoZXMgZnJvbSB0aGUgdWx0cmFzb25pYyBzZW5zb3IuCisgKiBAcmV0dXJuIGRvdWJsZSBSYW5nZSBpbiBpbmNoZXMgb2YgdGhlIHRhcmdldCByZXR1cm5lZCBmcm9tIHRoZSB1bHRyYXNvbmljCisgKiBzZW5zb3IuIElmIHRoZXJlIGlzCisgKiBubyB2YWxpZCB2YWx1ZSB5ZXQsIGkuZS4gYXQgbGVhc3Qgb25lIG1lYXN1cmVtZW50IGhhc24ndCBjb21wbGV0ZWQsIHRoZW4KKyAqIHJldHVybiAwLgorICovCitkb3VibGUgVWx0cmFzb25pYzo6R2V0UmFuZ2VJbmNoZXMoKSBjb25zdCB7CisgIGlmIChJc1JhbmdlVmFsaWQoKSkKKyAgICByZXR1cm4gbV9jb3VudGVyLkdldFBlcmlvZCgpICoga1NwZWVkT2ZTb3VuZEluY2hlc1BlclNlYyAvIDIuMDsKKyAgZWxzZQorICAgIHJldHVybiAwOworfQorCisvKioKKyAqIEdldCB0aGUgcmFuZ2UgaW4gbWlsbGltZXRlcnMgZnJvbSB0aGUgdWx0cmFzb25pYyBzZW5zb3IuCisgKiBAcmV0dXJuIGRvdWJsZSBSYW5nZSBpbiBtaWxsaW1ldGVycyBvZiB0aGUgdGFyZ2V0IHJldHVybmVkIGJ5IHRoZSB1bHRyYXNvbmljCisgKiBzZW5zb3IuCisgKiBJZiB0aGVyZSBpcyBubyB2YWxpZCB2YWx1ZSB5ZXQsIGkuZS4gYXQgbGVhc3Qgb25lIG1lYXN1cmVtZW50IGhhc24ndAorICogY29tcGx0ZWQsIHRoZW4gcmV0dXJuIDAuCisgKi8KK2RvdWJsZSBVbHRyYXNvbmljOjpHZXRSYW5nZU1NKCkgY29uc3QgeyByZXR1cm4gR2V0UmFuZ2VJbmNoZXMoKSAqIDI1LjQ7IH0KKworLyoqCisgKiBHZXQgdGhlIHJhbmdlIGluIHRoZSBjdXJyZW50IERpc3RhbmNlVW5pdCBmb3IgdGhlIFBJRFNvdXJjZSBiYXNlIG9iamVjdC4KKyAqCisgKiBAcmV0dXJuIFRoZSByYW5nZSBpbiBEaXN0YW5jZVVuaXQKKyAqLworZG91YmxlIFVsdHJhc29uaWM6OlBJREdldCgpIHsKKyAgc3dpdGNoIChtX3VuaXRzKSB7CisgICAgY2FzZSBVbHRyYXNvbmljOjprSW5jaGVzOgorICAgICAgcmV0dXJuIEdldFJhbmdlSW5jaGVzKCk7CisgICAgY2FzZSBVbHRyYXNvbmljOjprTWlsbGlNZXRlcnM6CisgICAgICByZXR1cm4gR2V0UmFuZ2VNTSgpOworICAgIGRlZmF1bHQ6CisgICAgICByZXR1cm4gMC4wOworICB9Cit9CisKK3ZvaWQgVWx0cmFzb25pYzo6U2V0UElEU291cmNlVHlwZShQSURTb3VyY2VUeXBlIHBpZFNvdXJjZSkgeworICBpZiAod3BpX2Fzc2VydChwaWRTb3VyY2UgPT0gUElEU291cmNlVHlwZTo6a0Rpc3BsYWNlbWVudCkpIHsKKyAgICBtX3BpZFNvdXJjZSA9IHBpZFNvdXJjZTsKKyAgfQorfQorCisvKioKKyAqIFNldCB0aGUgY3VycmVudCBEaXN0YW5jZVVuaXQgdGhhdCBzaG91bGQgYmUgdXNlZCBmb3IgdGhlIFBJRFNvdXJjZSBiYXNlCisgKiBvYmplY3QuCisgKgorICogQHBhcmFtIHVuaXRzIFRoZSBEaXN0YW5jZVVuaXQgdGhhdCBzaG91bGQgYmUgdXNlZC4KKyAqLwordm9pZCBVbHRyYXNvbmljOjpTZXREaXN0YW5jZVVuaXRzKERpc3RhbmNlVW5pdCB1bml0cykgeyBtX3VuaXRzID0gdW5pdHM7IH0KKworLyoqCisgKiBHZXQgdGhlIGN1cnJlbnQgRGlzdGFuY2VVbml0IHRoYXQgaXMgdXNlZCBmb3IgdGhlIFBJRFNvdXJjZSBiYXNlIG9iamVjdC4KKyAqCisgKiBAcmV0dXJuIFRoZSB0eXBlIG9mIERpc3RhbmNlVW5pdCB0aGF0IGlzIGJlaW5nIHVzZWQuCisgKi8KK1VsdHJhc29uaWM6OkRpc3RhbmNlVW5pdCBVbHRyYXNvbmljOjpHZXREaXN0YW5jZVVuaXRzKCkgY29uc3QgeworICByZXR1cm4gbV91bml0czsKK30KKwordm9pZCBVbHRyYXNvbmljOjpVcGRhdGVUYWJsZSgpIHsKKyAgaWYgKG1fdGFibGUgIT0gbnVsbHB0cikgeworICAgIG1fdGFibGUtPlB1dE51bWJlcigiVmFsdWUiLCBHZXRSYW5nZUluY2hlcygpKTsKKyAgfQorfQorCit2b2lkIFVsdHJhc29uaWM6OlN0YXJ0TGl2ZVdpbmRvd01vZGUoKSB7fQorCit2b2lkIFVsdHJhc29uaWM6OlN0b3BMaXZlV2luZG93TW9kZSgpIHt9CisKK3N0ZDo6c3RyaW5nIFVsdHJhc29uaWM6OkdldFNtYXJ0RGFzaGJvYXJkVHlwZSgpIGNvbnN0IHsgcmV0dXJuICJVbHRyYXNvbmljIjsgfQorCit2b2lkIFVsdHJhc29uaWM6OkluaXRUYWJsZShzdGQ6OnNoYXJlZF9wdHI8SVRhYmxlPiBzdWJUYWJsZSkgeworICBtX3RhYmxlID0gc3ViVGFibGU7CisgIFVwZGF0ZVRhYmxlKCk7Cit9CisKK3N0ZDo6c2hhcmVkX3B0cjxJVGFibGU+IFVsdHJhc29uaWM6OkdldFRhYmxlKCkgY29uc3QgeyByZXR1cm4gbV90YWJsZTsgfQpkaWZmIC0tZ2l0IGEvd3BpbGliYy9BdGhlbmEvc3JjL1V0aWxpdHkuY3BwIGIvd3BpbGliYy9BdGhlbmEvc3JjL1V0aWxpdHkuY3BwCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjU5OThmMGYKLS0tIC9kZXYvbnVsbAorKysgYi93cGlsaWJjL0F0aGVuYS9zcmMvVXRpbGl0eS5jcHAKQEAgLTAsMCArMSwyMjIgQEAKKy8qLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovCisvKiBDb3B5cmlnaHQgKGMpIEZJUlNUIDIwMDguIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCisgKi8KKy8qIE9wZW4gU291cmNlIFNvZnR3YXJlIC0gbWF5IGJlIG1vZGlmaWVkIGFuZCBzaGFyZWQgYnkgRlJDIHRlYW1zLiBUaGUgY29kZSAgICovCisvKiBtdXN0IGJlIGFjY29tcGFuaWVkIGJ5IHRoZSBGSVJTVCBCU0QgbGljZW5zZSBmaWxlIGluICQoV0lORF9CQVNFKS9XUElMaWIuICAqLworLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi8KKworI2luY2x1ZGUgIlV0aWxpdHkuaCIKKworLy8jaW5jbHVkZSAiTmV0d29ya0NvbW11bmljYXRpb24vRlJDQ29tbS5oIgorI2luY2x1ZGUgIkhBTC9IQUwuaHBwIgorI2luY2x1ZGUgIlRhc2suaCIKKyNpbmNsdWRlIDxpb3N0cmVhbT4KKyNpbmNsdWRlIDxzc3RyZWFtPgorI2luY2x1ZGUgPGNzdGRpbz4KKyNpbmNsdWRlIDxjc3RkbGliPgorI2luY2x1ZGUgPGNzdHJpbmc+CisjaW5jbHVkZSA8ZXhlY2luZm8uaD4KKyNpbmNsdWRlIDxjeHhhYmkuaD4KKyNpbmNsdWRlICJuaXZpc2lvbi5oIgorCisvKioKKyAqIEFzc2VydCBpbXBsZW1lbnRhdGlvbi4KKyAqIFRoaXMgYWxsb3dzIGJyZWFrcG9pbnRzIHRvIGJlIHNldCBvbiBhbiBhc3NlcnQuCisgKiBUaGUgdXNlcnMgZG9uJ3QgY2FsbCB0aGlzLCBidXQgaW5zdGVhZCB1c2UgdGhlIHdwaV9hc3NlcnQgbWFjcm9zIGluCisgKiBVdGlsaXR5LmguCisgKi8KK2Jvb2wgd3BpX2Fzc2VydF9pbXBsKGJvb2wgY29uZGl0aW9uVmFsdWUsIGNvbnN0IGNoYXIgKmNvbmRpdGlvblRleHQsCisgICAgICAgICAgICAgICAgICAgICBjb25zdCBjaGFyICptZXNzYWdlLCBjb25zdCBjaGFyICpmaWxlTmFtZSwKKyAgICAgICAgICAgICAgICAgICAgIHVpbnQzMl90IGxpbmVOdW1iZXIsIGNvbnN0IGNoYXIgKmZ1bmNOYW1lKSB7CisgIGlmICghY29uZGl0aW9uVmFsdWUpIHsKKyAgICBzdGQ6OnN0cmluZ3N0cmVhbSBlcnJvclN0cmVhbTsKKworICAgIGVycm9yU3RyZWFtIDw8ICJBc3NlcnRpb24gXCIiIDw8IGNvbmRpdGlvblRleHQgPDwgIlwiICI7CisgICAgZXJyb3JTdHJlYW0gPDwgIm9uIGxpbmUgIiA8PCBsaW5lTnVtYmVyIDw8ICIgIjsKKyAgICBlcnJvclN0cmVhbSA8PCAib2YgIiA8PCBiYXNlbmFtZShmaWxlTmFtZSkgPDwgIiAiOworCisgICAgaWYgKG1lc3NhZ2VbMF0gIT0gJ1wwJykgeworICAgICAgZXJyb3JTdHJlYW0gPDwgImZhaWxlZDogIiA8PCBtZXNzYWdlIDw8IHN0ZDo6ZW5kbDsKKyAgICB9IGVsc2UgeworICAgICAgZXJyb3JTdHJlYW0gPDwgImZhaWxlZC4iIDw8IHN0ZDo6ZW5kbDsKKyAgICB9CisKKyAgICBlcnJvclN0cmVhbSA8PCBHZXRTdGFja1RyYWNlKDIpOworCisgICAgc3RkOjpzdHJpbmcgZXJyb3IgPSBlcnJvclN0cmVhbS5zdHIoKTsKKworICAgIC8vIFByaW50IHRoZSBlcnJvciBhbmQgc2VuZCBpdCB0byB0aGUgRHJpdmVyU3RhdGlvbgorICAgIHN0ZDo6Y291dCA8PCBlcnJvciA8PCBzdGQ6OmVuZGw7CisgICAgSEFMU2V0RXJyb3JEYXRhKGVycm9yLmNfc3RyKCksIGVycm9yLnNpemUoKSwgMTAwKTsKKyAgfQorCisgIHJldHVybiBjb25kaXRpb25WYWx1ZTsKK30KKworLyoqCisgKiBDb21tb24gZXJyb3Igcm91dGluZXMgZm9yIHdwaV9hc3NlcnRFcXVhbF9pbXBsIGFuZCB3cGlfYXNzZXJ0Tm90RXF1YWxfaW1wbAorICogVGhpcyBzaG91bGQgbm90IGJlIGNhbGxlZCBkaXJlY3RseTsgaXQgc2hvdWxkIG9ubHkgYmUgdXNlZCBieQorICogd3BpX2Fzc2VydEVxdWFsX2ltcGwKKyAqIGFuZCB3cGlfYXNzZXJ0Tm90RXF1YWxfaW1wbC4KKyAqLwordm9pZCB3cGlfYXNzZXJ0RXF1YWxfY29tbW9uX2ltcGwoY29uc3QgY2hhciAqdmFsdWVBLCBjb25zdCBjaGFyICp2YWx1ZUIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBjaGFyICplcXVhbGl0eVR5cGUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBjaGFyICptZXNzYWdlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgY2hhciAqZmlsZU5hbWUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB1aW50MzJfdCBsaW5lTnVtYmVyLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgY2hhciAqZnVuY05hbWUpIHsKKyAgc3RkOjpzdHJpbmdzdHJlYW0gZXJyb3JTdHJlYW07CisKKyAgZXJyb3JTdHJlYW0gPDwgIkFzc2VydGlvbiBcIiIgPDwgdmFsdWVBIDw8ICIgIiA8PCBlcXVhbGl0eVR5cGUgPDwgIiAiCisgICAgICAgICAgICAgIDw8IHZhbHVlQiA8PCAiXCIgIjsKKyAgZXJyb3JTdHJlYW0gPDwgIm9uIGxpbmUgIiA8PCBsaW5lTnVtYmVyIDw8ICIgIjsKKyAgZXJyb3JTdHJlYW0gPDwgIm9mICIgPDwgYmFzZW5hbWUoZmlsZU5hbWUpIDw8ICIgIjsKKworICBpZiAobWVzc2FnZVswXSAhPSAnXDAnKSB7CisgICAgZXJyb3JTdHJlYW0gPDwgImZhaWxlZDogIiA8PCBtZXNzYWdlIDw8IHN0ZDo6ZW5kbDsKKyAgfSBlbHNlIHsKKyAgICBlcnJvclN0cmVhbSA8PCAiZmFpbGVkLiIgPDwgc3RkOjplbmRsOworICB9CisKKyAgZXJyb3JTdHJlYW0gPDwgR2V0U3RhY2tUcmFjZSgzKTsKKworICBzdGQ6OnN0cmluZyBlcnJvciA9IGVycm9yU3RyZWFtLnN0cigpOworCisgIC8vIFByaW50IHRoZSBlcnJvciBhbmQgc2VuZCBpdCB0byB0aGUgRHJpdmVyU3RhdGlvbgorICBzdGQ6OmNvdXQgPDwgZXJyb3IgPDwgc3RkOjplbmRsOworICBIQUxTZXRFcnJvckRhdGEoZXJyb3IuY19zdHIoKSwgZXJyb3Iuc2l6ZSgpLCAxMDApOworfQorCisvKioKKyAqIEFzc2VydCBlcXVhbCBpbXBsZW1lbnRhdGlvbi4KKyAqIFRoaXMgZGV0ZXJtaW5lcyB3aGV0aGVyIHRoZSB0d28gZ2l2ZW4gaW50ZWdlcnMgYXJlIGVxdWFsLiBJZiBub3QsCisgKiB0aGUgdmFsdWUgb2YgZWFjaCBpcyBwcmludGVkIGFsb25nIHdpdGggYW4gb3B0aW9uYWwgbWVzc2FnZSBzdHJpbmcuCisgKiBUaGUgdXNlcnMgZG9uJ3QgY2FsbCB0aGlzLCBidXQgaW5zdGVhZCB1c2UgdGhlIHdwaV9hc3NlcnRFcXVhbCBtYWNyb3MgaW4KKyAqIFV0aWxpdHkuaC4KKyAqLworYm9vbCB3cGlfYXNzZXJ0RXF1YWxfaW1wbChpbnQgdmFsdWVBLCBpbnQgdmFsdWVCLCBjb25zdCBjaGFyICp2YWx1ZUFTdHJpbmcsCisgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGNoYXIgKnZhbHVlQlN0cmluZywgY29uc3QgY2hhciAqbWVzc2FnZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgY2hhciAqZmlsZU5hbWUsIHVpbnQzMl90IGxpbmVOdW1iZXIsCisgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGNoYXIgKmZ1bmNOYW1lKSB7CisgIGlmICghKHZhbHVlQSA9PSB2YWx1ZUIpKSB7CisgICAgd3BpX2Fzc2VydEVxdWFsX2NvbW1vbl9pbXBsKHZhbHVlQVN0cmluZywgdmFsdWVCU3RyaW5nLCAiPT0iLCBtZXNzYWdlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaWxlTmFtZSwgbGluZU51bWJlciwgZnVuY05hbWUpOworICB9CisgIHJldHVybiB2YWx1ZUEgPT0gdmFsdWVCOworfQorCisvKioKKyAqIEFzc2VydCBub3QgZXF1YWwgaW1wbGVtZW50YXRpb24uCisgKiBUaGlzIGRldGVybWluZXMgd2hldGhlciB0aGUgdHdvIGdpdmVuIGludGVnZXJzIGFyZSBlcXVhbC4gSWYgc28sCisgKiB0aGUgdmFsdWUgb2YgZWFjaCBpcyBwcmludGVkIGFsb25nIHdpdGggYW4gb3B0aW9uYWwgbWVzc2FnZSBzdHJpbmcuCisgKiBUaGUgdXNlcnMgZG9uJ3QgY2FsbCB0aGlzLCBidXQgaW5zdGVhZCB1c2UgdGhlIHdwaV9hc3NlcnROb3RFcXVhbCBtYWNyb3MgaW4KKyAqIFV0aWxpdHkuaC4KKyAqLworYm9vbCB3cGlfYXNzZXJ0Tm90RXF1YWxfaW1wbChpbnQgdmFsdWVBLCBpbnQgdmFsdWVCLCBjb25zdCBjaGFyICp2YWx1ZUFTdHJpbmcsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGNoYXIgKnZhbHVlQlN0cmluZywgY29uc3QgY2hhciAqbWVzc2FnZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgY2hhciAqZmlsZU5hbWUsIHVpbnQzMl90IGxpbmVOdW1iZXIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGNoYXIgKmZ1bmNOYW1lKSB7CisgIGlmICghKHZhbHVlQSAhPSB2YWx1ZUIpKSB7CisgICAgd3BpX2Fzc2VydEVxdWFsX2NvbW1vbl9pbXBsKHZhbHVlQVN0cmluZywgdmFsdWVCU3RyaW5nLCAiIT0iLCBtZXNzYWdlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaWxlTmFtZSwgbGluZU51bWJlciwgZnVuY05hbWUpOworICB9CisgIHJldHVybiB2YWx1ZUEgIT0gdmFsdWVCOworfQorCisvKioKKyAqIFJldHVybiB0aGUgRlBHQSBWZXJzaW9uIG51bWJlci4KKyAqIEZvciBub3csIGV4cGVjdCB0aGlzIHRvIGJlIGNvbXBldGl0aW9uIHllYXIuCisgKiBAcmV0dXJuIEZQR0EgVmVyc2lvbiBudW1iZXIuCisgKi8KK3VpbnQxNl90IEdldEZQR0FWZXJzaW9uKCkgeworICBpbnQzMl90IHN0YXR1cyA9IDA7CisgIHVpbnQxNl90IHZlcnNpb24gPSBnZXRGUEdBVmVyc2lvbigmc3RhdHVzKTsKKyAgd3BpX3NldEdsb2JhbEVycm9yV2l0aENvbnRleHQoc3RhdHVzLCBnZXRIQUxFcnJvck1lc3NhZ2Uoc3RhdHVzKSk7CisgIHJldHVybiB2ZXJzaW9uOworfQorCisvKioKKyAqIFJldHVybiB0aGUgRlBHQSBSZXZpc2lvbiBudW1iZXIuCisgKiBUaGUgZm9ybWF0IG9mIHRoZSByZXZpc2lvbiBpcyAzIG51bWJlcnMuCisgKiBUaGUgMTIgbW9zdCBzaWduaWZpY2FudCBiaXRzIGFyZSB0aGUgTWFqb3IgUmV2aXNpb24uCisgKiB0aGUgbmV4dCA4IGJpdHMgYXJlIHRoZSBNaW5vciBSZXZpc2lvbi4KKyAqIFRoZSAxMiBsZWFzdCBzaWduaWZpY2FudCBiaXRzIGFyZSB0aGUgQnVpbGQgTnVtYmVyLgorICogQHJldHVybiBGUEdBIFJldmlzaW9uIG51bWJlci4KKyAqLwordWludDMyX3QgR2V0RlBHQVJldmlzaW9uKCkgeworICBpbnQzMl90IHN0YXR1cyA9IDA7CisgIHVpbnQzMl90IHJldmlzaW9uID0gZ2V0RlBHQVJldmlzaW9uKCZzdGF0dXMpOworICB3cGlfc2V0R2xvYmFsRXJyb3JXaXRoQ29udGV4dChzdGF0dXMsIGdldEhBTEVycm9yTWVzc2FnZShzdGF0dXMpKTsKKyAgcmV0dXJuIHJldmlzaW9uOworfQorCisvKioKKyAqIFJlYWQgdGhlIG1pY3Jvc2Vjb25kLXJlc29sdXRpb24gdGltZXIgb24gdGhlIEZQR0EuCisgKgorICogQHJldHVybiBUaGUgY3VycmVudCB0aW1lIGluIG1pY3Jvc2Vjb25kcyBhY2NvcmRpbmcgdG8gdGhlIEZQR0EgKHNpbmNlIEZQR0EKKyAqIHJlc2V0KS4KKyAqLwordWludDMyX3QgR2V0RlBHQVRpbWUoKSB7CisgIGludDMyX3Qgc3RhdHVzID0gMDsKKyAgdWludDMyX3QgdGltZSA9IGdldEZQR0FUaW1lKCZzdGF0dXMpOworICB3cGlfc2V0R2xvYmFsRXJyb3JXaXRoQ29udGV4dChzdGF0dXMsIGdldEhBTEVycm9yTWVzc2FnZShzdGF0dXMpKTsKKyAgcmV0dXJuIHRpbWU7Cit9CisKKy8qKgorICogR2V0IHRoZSBzdGF0ZSBvZiB0aGUgIlVTRVIiIGJ1dHRvbiBvbiB0aGUgUm9ib1JJTworICogQHJldHVybiBUcnVlIGlmIHRoZSBidXR0b24gaXMgY3VycmVudGx5IHByZXNzZWQgZG93bgorICovCitib29sIEdldFVzZXJCdXR0b24oKSB7CisgIGludDMyX3Qgc3RhdHVzID0gMDsKKworICBib29sIHZhbHVlID0gZ2V0RlBHQUJ1dHRvbigmc3RhdHVzKTsKKyAgd3BpX3NldEdsb2JhbEVycm9yKHN0YXR1cyk7CisKKyAgcmV0dXJuIHZhbHVlOworfQorCisvKioKKyAqIERlbWFuZ2xlIGEgQysrIHN5bWJvbCwgdXNlZCBmb3IgcHJpbnRpbmcgc3RhY2sgdHJhY2VzLgorICovCitzdGF0aWMgc3RkOjpzdHJpbmcgZGVtYW5nbGUoY2hhciBjb25zdCAqbWFuZ2xlZFN5bWJvbCkgeworICBjaGFyIGJ1ZmZlclsyNTZdOworICBzaXplX3QgbGVuZ3RoOworICBpbnQgc3RhdHVzOworCisgIGlmIChzc2NhbmYobWFuZ2xlZFN5bWJvbCwgIiUqW14oXSUqWyhdJTI1NVteKStdIiwgYnVmZmVyKSkgeworICAgIGNoYXIgKnN5bWJvbCA9IGFiaTo6X19jeGFfZGVtYW5nbGUoYnVmZmVyLCBudWxscHRyLCAmbGVuZ3RoLCAmc3RhdHVzKTsKKyAgICBpZiAoc3RhdHVzID09IDApIHsKKyAgICAgIHJldHVybiBzeW1ib2w7CisgICAgfSBlbHNlIHsKKyAgICAgIC8vIElmIHRoZSBzeW1ib2wgY291bGRuJ3QgYmUgZGVtYW5nbGVkLCBpdCdzIHByb2JhYmx5IGEgQyBmdW5jdGlvbiwKKyAgICAgIC8vIHNvIGp1c3QgcmV0dXJuIGl0IGFzLWlzLgorICAgICAgcmV0dXJuIGJ1ZmZlcjsKKyAgICB9CisgIH0KKworICAvLyBJZiBldmVyeXRoaW5nIGVsc2UgZmFpbGVkLCBqdXN0IHJldHVybiB0aGUgbWFuZ2xlZCBzeW1ib2wKKyAgcmV0dXJuIG1hbmdsZWRTeW1ib2w7Cit9CisKKy8qKgorICogR2V0IGEgc3RhY2sgdHJhY2UsIGlnbm9yaW5nIHRoZSBmaXJzdCAib2Zmc2V0IiBzeW1ib2xzLgorICogQHBhcmFtIG9mZnNldCBUaGUgbnVtYmVyIG9mIHN5bWJvbHMgYXQgdGhlIHRvcCBvZiB0aGUgc3RhY2sgdG8gaWdub3JlCisgKi8KK3N0ZDo6c3RyaW5nIEdldFN0YWNrVHJhY2UodWludDMyX3Qgb2Zmc2V0KSB7CisgIHZvaWQgKnN0YWNrVHJhY2VbMTI4XTsKKyAgaW50IHN0YWNrU2l6ZSA9IGJhY2t0cmFjZShzdGFja1RyYWNlLCAxMjgpOworICBjaGFyICoqbWFuZ2xlZFN5bWJvbHMgPSBiYWNrdHJhY2Vfc3ltYm9scyhzdGFja1RyYWNlLCBzdGFja1NpemUpOworICBzdGQ6OnN0cmluZ3N0cmVhbSB0cmFjZTsKKworICBmb3IgKGludCBpID0gb2Zmc2V0OyBpIDwgc3RhY2tTaXplOyBpKyspIHsKKyAgICAvLyBPbmx5IHByaW50IHJlY3Vyc2l2ZSBmdW5jdGlvbnMgb25jZSBpbiBhIHJvdy4KKyAgICBpZiAoaSA9PSAwIHx8IHN0YWNrVHJhY2VbaV0gIT0gc3RhY2tUcmFjZVtpIC0gMV0pIHsKKyAgICAgIHRyYWNlIDw8ICJcdGF0ICIgPDwgZGVtYW5nbGUobWFuZ2xlZFN5bWJvbHNbaV0pIDw8IHN0ZDo6ZW5kbDsKKyAgICB9CisgIH0KKworICBmcmVlKG1hbmdsZWRTeW1ib2xzKTsKKworICByZXR1cm4gdHJhY2Uuc3RyKCk7Cit9CmRpZmYgLS1naXQgYS93cGlsaWJjL0F0aGVuYS9zcmMvVmljdG9yLmNwcCBiL3dwaWxpYmMvQXRoZW5hL3NyYy9WaWN0b3IuY3BwCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmY4YTQ5NzAKLS0tIC9kZXYvbnVsbAorKysgYi93cGlsaWJjL0F0aGVuYS9zcmMvVmljdG9yLmNwcApAQCAtMCwwICsxLDg0IEBACisvKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qLworLyogQ29weXJpZ2h0IChjKSBGSVJTVCAyMDA4LiBBbGwgUmlnaHRzIFJlc2VydmVkLgorICovCisvKiBPcGVuIFNvdXJjZSBTb2Z0d2FyZSAtIG1heSBiZSBtb2RpZmllZCBhbmQgc2hhcmVkIGJ5IEZSQyB0ZWFtcy4gVGhlIGNvZGUgICAqLworLyogbXVzdCBiZSBhY2NvbXBhbmllZCBieSB0aGUgRklSU1QgQlNEIGxpY2Vuc2UgZmlsZSBpbiAkKFdJTkRfQkFTRSkvV1BJTGliLiAgKi8KKy8qLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovCisKKyNpbmNsdWRlICJWaWN0b3IuaCIKKworI2luY2x1ZGUgIkxpdmVXaW5kb3cvTGl2ZVdpbmRvdy5oIgorCisvKioKKyAqIENvbnN0cnVjdG9yIGZvciBhIFZpY3RvcgorICogQHBhcmFtIGNoYW5uZWwgVGhlIFBXTSBjaGFubmVsIG51bWJlciB0aGF0IHRoZSBWaWN0b3IgaXMgYXR0YWNoZWQgdG8uIDAtOSBhcmUKKyAqIG9uLWJvYXJkLCAxMC0xOSBhcmUgb24gdGhlIE1YUCBwb3J0CisgKi8KK1ZpY3Rvcjo6VmljdG9yKHVpbnQzMl90IGNoYW5uZWwpIDogU2FmZVBXTShjaGFubmVsKSB7CisgIC8qIE5vdGUgdGhhdCB0aGUgVmljdG9yIHVzZXMgdGhlIGZvbGxvd2luZyBib3VuZHMgZm9yIFBXTSB2YWx1ZXMuICBUaGVzZQorICAgKiB2YWx1ZXMgd2VyZSBkZXRlcm1pbmVkIGVtcGlyaWNhbGx5IGFuZCBvcHRpbWl6ZWQgZm9yIHRoZSBWaWN0b3IgODg4LiBUaGVzZQorICAgKiB2YWx1ZXMgc2hvdWxkIHdvcmsgcmVhc29uYWJseSB3ZWxsIGZvciBWaWN0b3IgODg0IGNvbnRyb2xsZXJzIGFzIHdlbGwgYnV0CisgICAqIGlmIHVzZXJzIGV4cGVyaWVuY2UgaXNzdWVzIHN1Y2ggYXMgYXN5bW1ldHJpYyBiZWhhdmlvdXIgYXJvdW5kIHRoZSBkZWFkYmFuZAorICAgKiBvciBpbmFiaWxpdHkgdG8gc2F0dXJhdGUgdGhlIGNvbnRyb2xsZXIgaW4gZWl0aGVyIGRpcmVjdGlvbiwgY2FsaWJyYXRpb24gaXMKKyAgICogcmVjb21tZW5kZWQuIFRoZSBjYWxpYnJhdGlvbiBwcm9jZWR1cmUgY2FuIGJlIGZvdW5kIGluIHRoZSBWaWN0b3IgODg0IFVzZXIKKyAgICogTWFudWFsIGF2YWlsYWJsZSBmcm9tIElGSS4KKyAgICoKKyAgICogICAyLjAyN21zID0gZnVsbCAiZm9yd2FyZCIKKyAgICogICAxLjUyNW1zID0gdGhlICJoaWdoIGVuZCIgb2YgdGhlIGRlYWRiYW5kIHJhbmdlCisgICAqICAgMS41MDdtcyA9IGNlbnRlciBvZiB0aGUgZGVhZGJhbmQgcmFuZ2UgKG9mZikKKyAgICogICAxLjQ5bXMgPSB0aGUgImxvdyBlbmQiIG9mIHRoZSBkZWFkYmFuZCByYW5nZQorICAgKiAgIDEuMDI2bXMgPSBmdWxsICJyZXZlcnNlIgorICAgKi8KKyAgU2V0Qm91bmRzKDIuMDI3LCAxLjUyNSwgMS41MDcsIDEuNDksIDEuMDI2KTsKKyAgU2V0UGVyaW9kTXVsdGlwbGllcihrUGVyaW9kTXVsdGlwbGllcl8yWCk7CisgIFNldFJhdyhtX2NlbnRlclB3bSk7CisgIFNldFplcm9MYXRjaCgpOworCisgIExpdmVXaW5kb3c6OkdldEluc3RhbmNlKCktPkFkZEFjdHVhdG9yKCJWaWN0b3IiLCBHZXRDaGFubmVsKCksIHRoaXMpOworICBIQUxSZXBvcnQoSEFMVXNhZ2VSZXBvcnRpbmc6OmtSZXNvdXJjZVR5cGVfVmljdG9yLCBHZXRDaGFubmVsKCkpOworfQorCisvKioKKyAqIFNldCB0aGUgUFdNIHZhbHVlLgorICoKKyAqIFRoZSBQV00gdmFsdWUgaXMgc2V0IHVzaW5nIGEgcmFuZ2Ugb2YgLTEuMCB0byAxLjAsIGFwcHJvcHJpYXRlbHkKKyAqIHNjYWxpbmcgdGhlIHZhbHVlIGZvciB0aGUgRlBHQS4KKyAqCisgKiBAcGFyYW0gc3BlZWQgVGhlIHNwZWVkIHZhbHVlIGJldHdlZW4gLTEuMCBhbmQgMS4wIHRvIHNldC4KKyAqIEBwYXJhbSBzeW5jR3JvdXAgVW51c2VkIGludGVyZmFjZS4KKyAqLwordm9pZCBWaWN0b3I6OlNldChmbG9hdCBzcGVlZCwgdWludDhfdCBzeW5jR3JvdXApIHsKKyAgU2V0U3BlZWQobV9pc0ludmVydGVkID8gLXNwZWVkIDogc3BlZWQpOworfQorCisvKioKKyAqIEdldCB0aGUgcmVjZW50bHkgc2V0IHZhbHVlIG9mIHRoZSBQV00uCisgKgorICogQHJldHVybiBUaGUgbW9zdCByZWNlbnRseSBzZXQgdmFsdWUgZm9yIHRoZSBQV00gYmV0d2VlbiAtMS4wIGFuZCAxLjAuCisgKi8KK2Zsb2F0IFZpY3Rvcjo6R2V0KCkgY29uc3QgeyByZXR1cm4gR2V0U3BlZWQoKTsgfQorCisvKioKKyAqIENvbW1vbiBpbnRlcmZhY2UgZm9yIGRpc2FibGluZyBhIG1vdG9yLgorICovCit2b2lkIFZpY3Rvcjo6RGlzYWJsZSgpIHsgU2V0UmF3KGtQd21EaXNhYmxlZCk7IH0KKy8qKgorKiBDb21tb24gaW50ZXJmYWNlIGZvciBpbnZlcnRpbmcgZGlyZWN0aW9uIG9mIGEgc3BlZWQgY29udHJvbGxlci4KKyogQHBhcmFtIGlzSW52ZXJ0ZWQgVGhlIHN0YXRlIG9mIGludmVyc2lvbiwgdHJ1ZSBpcyBpbnZlcnRlZC4KKyovCit2b2lkIFZpY3Rvcjo6U2V0SW52ZXJ0ZWQoYm9vbCBpc0ludmVydGVkKSB7IG1faXNJbnZlcnRlZCA9IGlzSW52ZXJ0ZWQ7IH0KKworLyoqCisgKiBDb21tb24gaW50ZXJmYWNlIGZvciB0aGUgaW52ZXJ0aW5nIGRpcmVjdGlvbiBvZiBhIHNwZWVkIGNvbnRyb2xsZXIuCisgKgorICogQHJldHVybiBpc0ludmVydGVkIFRoZSBzdGF0ZSBvZiBpbnZlcnNpb24sIHRydWUgaXMgaW52ZXJ0ZWQuCisgKgorICovCitib29sIFZpY3Rvcjo6R2V0SW52ZXJ0ZWQoKSBjb25zdCB7IHJldHVybiBtX2lzSW52ZXJ0ZWQ7IH0KKworLyoqCisgKiBXcml0ZSBvdXQgdGhlIFBJRCB2YWx1ZSBhcyBzZWVuIGluIHRoZSBQSURPdXRwdXQgYmFzZSBvYmplY3QuCisgKgorICogQHBhcmFtIG91dHB1dCBXcml0ZSBvdXQgdGhlIFBXTSB2YWx1ZSBhcyB3YXMgZm91bmQgaW4gdGhlIFBJRENvbnRyb2xsZXIKKyAqLwordm9pZCBWaWN0b3I6OlBJRFdyaXRlKGZsb2F0IG91dHB1dCkgeyBTZXQob3V0cHV0KTsgfQpkaWZmIC0tZ2l0IGEvd3BpbGliYy9BdGhlbmEvc3JjL1ZpY3RvclNQLmNwcCBiL3dwaWxpYmMvQXRoZW5hL3NyYy9WaWN0b3JTUC5jcHAKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uY2NiYzE2MwotLS0gL2Rldi9udWxsCisrKyBiL3dwaWxpYmMvQXRoZW5hL3NyYy9WaWN0b3JTUC5jcHAKQEAgLTAsMCArMSw4OCBAQAorLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi8KKy8qIENvcHlyaWdodCAoYykgRklSU1QgMjAwOC4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KKyAqLworLyogT3BlbiBTb3VyY2UgU29mdHdhcmUgLSBtYXkgYmUgbW9kaWZpZWQgYW5kIHNoYXJlZCBieSBGUkMgdGVhbXMuIFRoZSBjb2RlICAgKi8KKy8qIG11c3QgYmUgYWNjb21wYW5pZWQgYnkgdGhlIEZJUlNUIEJTRCBsaWNlbnNlIGZpbGUgaW4gJChXSU5EX0JBU0UpL1dQSUxpYi4gICovCisvKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qLworCisjaW5jbHVkZSAiVmljdG9yU1AuaCIKKworI2luY2x1ZGUgIkxpdmVXaW5kb3cvTGl2ZVdpbmRvdy5oIgorCisvKioKKyAqIE5vdGUgdGhhdCB0aGUgVmljdG9yU1AgdXNlcyB0aGUgZm9sbG93aW5nIGJvdW5kcyBmb3IgUFdNIHZhbHVlcy4gVGhlc2UgdmFsdWVzCisgKiBzaG91bGQgd29yayByZWFzb25hYmx5IHdlbGwgZm9yCisgKiBtb3N0IGNvbnRyb2xsZXJzLCBidXQgaWYgdXNlcnMgZXhwZXJpZW5jZSBpc3N1ZXMgc3VjaCBhcyBhc3ltbWV0cmljIGJlaGF2aW9yCisgKiBhcm91bmQKKyAqIHRoZSBkZWFkYmFuZCBvciBpbmFiaWxpdHkgdG8gc2F0dXJhdGUgdGhlIGNvbnRyb2xsZXIgaW4gZWl0aGVyIGRpcmVjdGlvbiwKKyAqIGNhbGlicmF0aW9uIGlzIHJlY29tbWVuZGVkLgorICogVGhlIGNhbGlicmF0aW9uIHByb2NlZHVyZSBjYW4gYmUgZm91bmQgaW4gdGhlIFZpY3RvclNQIFVzZXIgTWFudWFsIGF2YWlsYWJsZQorICogZnJvbSBWZXguCisgKgorICogICAyLjAwNG1zID0gZnVsbCAiZm9yd2FyZCIKKyAqICAgMS41Mm1zID0gdGhlICJoaWdoIGVuZCIgb2YgdGhlIGRlYWRiYW5kIHJhbmdlCisgKiAgIDEuNTBtcyA9IGNlbnRlciBvZiB0aGUgZGVhZGJhbmQgcmFuZ2UgKG9mZikKKyAqICAgMS40OG1zID0gdGhlICJsb3cgZW5kIiBvZiB0aGUgZGVhZGJhbmQgcmFuZ2UKKyAqICAgMC45OTdtcyA9IGZ1bGwgInJldmVyc2UiCisgKi8KKworLyoqCisgKiBDb25zdHJ1Y3RvciBmb3IgYSBWaWN0b3JTUAorICogQHBhcmFtIGNoYW5uZWwgVGhlIFBXTSBjaGFubmVsIHRoYXQgdGhlIFZpY3RvclNQIGlzIGF0dGFjaGVkIHRvLiAwLTkgYXJlCisgKiBvbi1ib2FyZCwgMTAtMTkgYXJlIG9uIHRoZSBNWFAgcG9ydAorICovCitWaWN0b3JTUDo6VmljdG9yU1AodWludDMyX3QgY2hhbm5lbCkgOiBTYWZlUFdNKGNoYW5uZWwpIHsKKyAgU2V0Qm91bmRzKDIuMDA0LCAxLjUyLCAxLjUwLCAxLjQ4LCAuOTk3KTsKKyAgU2V0UGVyaW9kTXVsdGlwbGllcihrUGVyaW9kTXVsdGlwbGllcl8xWCk7CisgIFNldFJhdyhtX2NlbnRlclB3bSk7CisgIFNldFplcm9MYXRjaCgpOworCisgIEhBTFJlcG9ydChIQUxVc2FnZVJlcG9ydGluZzo6a1Jlc291cmNlVHlwZV9WaWN0b3JTUCwgR2V0Q2hhbm5lbCgpKTsKKyAgTGl2ZVdpbmRvdzo6R2V0SW5zdGFuY2UoKS0+QWRkQWN0dWF0b3IoIlZpY3RvclNQIiwgR2V0Q2hhbm5lbCgpLCB0aGlzKTsKK30KKworLyoqCisgKiBTZXQgdGhlIFBXTSB2YWx1ZS4KKyAqCisgKiBUaGUgUFdNIHZhbHVlIGlzIHNldCB1c2luZyBhIHJhbmdlIG9mIC0xLjAgdG8gMS4wLCBhcHByb3ByaWF0ZWx5CisgKiBzY2FsaW5nIHRoZSB2YWx1ZSBmb3IgdGhlIEZQR0EuCisgKgorICogQHBhcmFtIHNwZWVkIFRoZSBzcGVlZCB2YWx1ZSBiZXR3ZWVuIC0xLjAgYW5kIDEuMCB0byBzZXQuCisgKiBAcGFyYW0gc3luY0dyb3VwIFVudXNlZCBpbnRlcmZhY2UuCisgKi8KK3ZvaWQgVmljdG9yU1A6OlNldChmbG9hdCBzcGVlZCwgdWludDhfdCBzeW5jR3JvdXApIHsKKyAgU2V0U3BlZWQobV9pc0ludmVydGVkID8gLXNwZWVkIDogc3BlZWQpOworfQorCisvKioKKyAqIEdldCB0aGUgcmVjZW50bHkgc2V0IHZhbHVlIG9mIHRoZSBQV00uCisgKgorICogQHJldHVybiBUaGUgbW9zdCByZWNlbnRseSBzZXQgdmFsdWUgZm9yIHRoZSBQV00gYmV0d2VlbiAtMS4wIGFuZCAxLjAuCisgKi8KK2Zsb2F0IFZpY3RvclNQOjpHZXQoKSBjb25zdCB7IHJldHVybiBHZXRTcGVlZCgpOyB9CisKKy8qKgorICogQ29tbW9uIGludGVyZmFjZSBmb3IgaW52ZXJ0aW5nIGRpcmVjdGlvbiBvZiBhIHNwZWVkIGNvbnRyb2xsZXIuCisgKiBAcGFyYW0gaXNJbnZlcnRlZCBUaGUgc3RhdGUgb2YgaW52ZXJzaW9uLCB0cnVlIGlzIGludmVydGVkLgorICovCit2b2lkIFZpY3RvclNQOjpTZXRJbnZlcnRlZChib29sIGlzSW52ZXJ0ZWQpIHsgbV9pc0ludmVydGVkID0gaXNJbnZlcnRlZDsgfQorCisvKioKKyAqIENvbW1vbiBpbnRlcmZhY2UgZm9yIHRoZSBpbnZlcnRpbmcgZGlyZWN0aW9uIG9mIGEgc3BlZWQgY29udHJvbGxlci4KKyAqCisgKiBAcmV0dXJuIGlzSW52ZXJ0ZWQgVGhlIHN0YXRlIG9mIGludmVyc2lvbiwgdHJ1ZSBpcyBpbnZlcnRlZC4KKyAqCisgKi8KK2Jvb2wgVmljdG9yU1A6OkdldEludmVydGVkKCkgY29uc3QgeyByZXR1cm4gbV9pc0ludmVydGVkOyB9CisKKy8qKgorICogQ29tbW9uIGludGVyZmFjZSBmb3IgZGlzYWJsaW5nIGEgbW90b3IuCisgKi8KK3ZvaWQgVmljdG9yU1A6OkRpc2FibGUoKSB7IFNldFJhdyhrUHdtRGlzYWJsZWQpOyB9CisKKy8qKgorICogV3JpdGUgb3V0IHRoZSBQSUQgdmFsdWUgYXMgc2VlbiBpbiB0aGUgUElET3V0cHV0IGJhc2Ugb2JqZWN0LgorICoKKyAqIEBwYXJhbSBvdXRwdXQgV3JpdGUgb3V0IHRoZSBQV00gdmFsdWUgYXMgd2FzIGZvdW5kIGluIHRoZSBQSURDb250cm9sbGVyCisgKi8KK3ZvaWQgVmljdG9yU1A6OlBJRFdyaXRlKGZsb2F0IG91dHB1dCkgeyBTZXQob3V0cHV0KTsgfQpkaWZmIC0tZ2l0IGEvd3BpbGliYy9BdGhlbmEvc3JjL1Zpc2lvbi9BeGlzQ2FtZXJhLmNwcCBiL3dwaWxpYmMvQXRoZW5hL3NyYy9WaXNpb24vQXhpc0NhbWVyYS5jcHAKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uOTkwYzY4YQotLS0gL2Rldi9udWxsCisrKyBiL3dwaWxpYmMvQXRoZW5hL3NyYy9WaXNpb24vQXhpc0NhbWVyYS5jcHAKQEAgLTAsMCArMSw1OTcgQEAKKy8qLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovCisvKiBDb3B5cmlnaHQgKGMpIEZJUlNUIDIwMTQuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqLworLyogT3BlbiBTb3VyY2UgU29mdHdhcmUgLSBtYXkgYmUgbW9kaWZpZWQgYW5kIHNoYXJlZCBieSBGUkMgdGVhbXMuIFRoZSBjb2RlICAgKi8KKy8qIG11c3QgYmUgYWNjb21wYW5pZWQgYnkgdGhlIEZJUlNUIEJTRCBsaWNlbnNlIGZpbGUgaW4gJChXSU5EX0JBU0UpL1dQSUxpYi4gICovCisvKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qLworCisjaW5jbHVkZSAiVmlzaW9uL0F4aXNDYW1lcmEuaCIKKworI2luY2x1ZGUgIldQSUVycm9ycy5oIgorCisjaW5jbHVkZSA8Y3N0cmluZz4KKyNpbmNsdWRlIDxzeXMvdHlwZXMuaD4KKyNpbmNsdWRlIDxzeXMvc29ja2V0Lmg+CisjaW5jbHVkZSA8bmV0aW5ldC9pbi5oPgorI2luY2x1ZGUgPHVuaXN0ZC5oPgorI2luY2x1ZGUgPG5ldGRiLmg+CisjaW5jbHVkZSA8VGltZXIuaD4KKyNpbmNsdWRlIDxpb3N0cmVhbT4KKyNpbmNsdWRlIDxzc3RyZWFtPgorCitzdGF0aWMgY29uc3QgdW5zaWduZWQgaW50IGtNYXhQYWNrZXRTaXplID0gMTUzNjsKK3N0YXRpYyBjb25zdCB1bnNpZ25lZCBpbnQga0ltYWdlQnVmZmVyQWxsb2NhdGlvbkluY3JlbWVudCA9IDEwMDA7CisKK3N0YXRpYyBjb25zdCBzdGQ6OnN0cmluZyBrV2hpdGVCYWxhbmNlU3RyaW5nc1tdID0geworICAgICJhdXRvIiwgICAgICAgICAiaG9sZCIsICAgICAgICAgImZpeGVkX291dGRvb3IxIiwgImZpeGVkX291dGRvb3IyIiwKKyAgICAiZml4ZWRfaW5kb29yIiwgImZpeGVkX2ZsdW9yMSIsICJmaXhlZF9mbHVvcjIiLAorfTsKKworc3RhdGljIGNvbnN0IHN0ZDo6c3RyaW5nIGtFeHBvc3VyZUNvbnRyb2xTdHJpbmdzW10gPSB7CisgICAgImF1dG8iLCAiaG9sZCIsICJmbGlja2VyZnJlZTUwIiwgImZsaWNrZXJmcmVlNjAiLAorfTsKKworc3RhdGljIGNvbnN0IHN0ZDo6c3RyaW5nIGtSZXNvbHV0aW9uU3RyaW5nc1tdID0geworICAgICI2NDB4NDgwIiwgIjQ4MHgzNjAiLCAiMzIweDI0MCIsICIyNDB4MTgwIiwgIjE3NngxNDQiLCAiMTYweDEyMCIsCit9OworCitzdGF0aWMgY29uc3Qgc3RkOjpzdHJpbmcga1JvdGF0aW9uU3RyaW5nc1tdID0geworICAgICIwIiwgIjE4MCIsCit9OworCisvKioKKyAqIEF4aXNDYW1lcmEgY29uc3RydWN0b3IKKyAqIEBwYXJhbSBjYW1lcmFIb3N0IFRoZSBob3N0IHRvIGZpbmQgdGhlIGNhbWVyYSBhdCwgdHlwaWNhbGx5IGFuIElQIGFkZHJlc3MKKyAqLworQXhpc0NhbWVyYTo6QXhpc0NhbWVyYShzdGQ6OnN0cmluZyBjb25zdCAmY2FtZXJhSG9zdCkKKyAgICA6IG1fY2FtZXJhSG9zdChjYW1lcmFIb3N0KSB7CisgIG1fY2FwdHVyZVRocmVhZCA9IHN0ZDo6dGhyZWFkKCZBeGlzQ2FtZXJhOjpDYXB0dXJlLCB0aGlzKTsKK30KKworQXhpc0NhbWVyYTo6fkF4aXNDYW1lcmEoKSB7CisgIG1fZG9uZSA9IHRydWU7CisgIG1fY2FwdHVyZVRocmVhZC5qb2luKCk7Cit9CisKKy8qCisgKiBSZXR1cm4gdHJ1ZSBpZiB0aGUgbGF0ZXN0IGltYWdlIGZyb20gdGhlIGNhbWVyYSBoYXMgbm90IGJlZW4gcmV0cmlldmVkIGJ5CisgKiBjYWxsaW5nIEdldEltYWdlKCkgeWV0LgorICogQHJldHVybiB0cnVlIGlmIHRoZSBpbWFnZSBoYXMgbm90IGJlZW4gcmV0cmlldmVkIHlldC4KKyAqLworYm9vbCBBeGlzQ2FtZXJhOjpJc0ZyZXNoSW1hZ2UoKSBjb25zdCB7IHJldHVybiBtX2ZyZXNoSW1hZ2U7IH0KKworLyoqCisgKiBHZXQgYW4gaW1hZ2UgZnJvbSB0aGUgY2FtZXJhIGFuZCBzdG9yZSBpdCBpbiB0aGUgcHJvdmlkZWQgaW1hZ2UuCisgKiBAcGFyYW0gaW1hZ2UgVGhlIGltYXEgaW1hZ2UgdG8gc3RvcmUgdGhlIHJlc3VsdCBpbi4gVGhpcyBtdXN0IGJlIGFuIEhTTCBvcgorICogUkdCIGltYWdlLgorICogQHJldHVybiAxIHVwb24gc3VjY2VzcywgemVybyBvbiBhIGZhaWx1cmUKKyAqLworaW50IEF4aXNDYW1lcmE6OkdldEltYWdlKEltYWdlICppbWFnZSkgeworICBpZiAobV9pbWFnZURhdGEuc2l6ZSgpID09IDApIHsKKyAgICByZXR1cm4gMDsKKyAgfQorCisgIHN0ZDo6bG9ja19ndWFyZDxwcmlvcml0eV9tdXRleD4gbG9jayhtX2ltYWdlRGF0YU11dGV4KTsKKworICBQcml2X1JlYWRKUEVHU3RyaW5nX0MoaW1hZ2UsIG1faW1hZ2VEYXRhLmRhdGEoKSwgbV9pbWFnZURhdGEuc2l6ZSgpKTsKKworICBtX2ZyZXNoSW1hZ2UgPSBmYWxzZTsKKworICByZXR1cm4gMTsKK30KKworLyoqCisgKiBHZXQgYW4gaW1hZ2UgZnJvbSB0aGUgY2FtZXJhIGFuZCBzdG9yZSBpdCBpbiB0aGUgcHJvdmlkZWQgaW1hZ2UuCisgKiBAcGFyYW0gaW1hZ2UgVGhlIGltYWdlIHRvIHN0b3JlIHRoZSByZXN1bHQgaW4uIFRoaXMgbXVzdCBiZSBhbiBIU0wgb3IgUkdCCisgKiBpbWFnZQorICogQHJldHVybiAxIHVwb24gc3VjY2VzcywgemVybyBvbiBhIGZhaWx1cmUKKyAqLworaW50IEF4aXNDYW1lcmE6OkdldEltYWdlKENvbG9ySW1hZ2UgKmltYWdlKSB7CisgIHJldHVybiBHZXRJbWFnZShpbWFnZS0+R2V0SW1hcUltYWdlKCkpOworfQorCisvKioKKyAqIEluc3RhbnRpYXRlIGEgbmV3IGltYWdlIG9iamVjdCBhbmQgZmlsbCBpdCB3aXRoIHRoZSBsYXRlc3QgaW1hZ2UgZnJvbSB0aGUKKyAqIGNhbWVyYS4KKyAqCisgKiBUaGUgcmV0dXJuZWQgcG9pbnRlciBpcyBvd25lZCBieSB0aGUgY2FsbGVyIGFuZCBpcyB0aGVpciByZXNwb25zaWJpbGl0eSB0bworICogZGVsZXRlLgorICogQHJldHVybiBhIHBvaW50ZXIgdG8gYW4gSFNMSW1hZ2Ugb2JqZWN0CisgKi8KK0hTTEltYWdlICpBeGlzQ2FtZXJhOjpHZXRJbWFnZSgpIHsKKyAgYXV0byBpbWFnZSA9IG5ldyBIU0xJbWFnZSgpOworICBHZXRJbWFnZShpbWFnZSk7CisgIHJldHVybiBpbWFnZTsKK30KKworLyoqCisgKiBDb3B5IGFuIGltYWdlIGludG8gYW4gZXhpc3RpbmcgYnVmZmVyLgorICogVGhpcyBjb3BpZXMgYW4gaW1hZ2UgaW50byBhbiBleGlzdGluZyBidWZmZXIgcmF0aGVyIHRoYW4gY3JlYXRpbmcgYSBuZXcgaW1hZ2UKKyAqIGluIG1lbW9yeS4gVGhhdCB3YXkgYSBuZXcgaW1hZ2UgaXMgb25seSBhbGxvY2F0ZWQgd2hlbiB0aGUgaW1hZ2UgYmVpbmcgY29waWVkCisgKiBpcworICogbGFyZ2VyIHRoYW4gdGhlIGRlc3RpbmF0aW9uLgorICogVGhpcyBtZXRob2QgaXMgY2FsbGVkIGJ5IHRoZSBQQ1ZpZGVvU2VydmVyIGNsYXNzLgorICogQHBhcmFtIGltYWdlRGF0YSBUaGUgZGVzdGluYXRpb24gaW1hZ2UuCisgKiBAcGFyYW0gbnVtQnl0ZXMgVGhlIHNpemUgb2YgdGhlIGRlc3RpbmF0aW9uIGltYWdlLgorICogQHJldHVybiAwIGlmIGZhaWxlZCAobm8gc291cmNlIGltYWdlIG9yIG5vIG1lbW9yeSksIDEgaWYgc3VjY2Vzcy4KKyAqLworaW50IEF4aXNDYW1lcmE6OkNvcHlKUEVHKGNoYXIgKipkZXN0SW1hZ2UsIHVuc2lnbmVkIGludCAmZGVzdEltYWdlU2l6ZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICB1bnNpZ25lZCBpbnQgJmRlc3RJbWFnZUJ1ZmZlclNpemUpIHsKKyAgc3RkOjpsb2NrX2d1YXJkPHByaW9yaXR5X211dGV4PiBsb2NrKG1faW1hZ2VEYXRhTXV0ZXgpOworICBpZiAoZGVzdEltYWdlID09IG51bGxwdHIpIHsKKyAgICB3cGlfc2V0V1BJRXJyb3JXaXRoQ29udGV4dChOdWxsUGFyYW1ldGVyLCAiZGVzdEltYWdlIG11c3Qgbm90IGJlIG51bGxwdHIiKTsKKyAgICByZXR1cm4gMDsKKyAgfQorCisgIGlmIChtX2ltYWdlRGF0YS5zaXplKCkgPT0gMCkgcmV0dXJuIDA7ICAvLyBpZiBubyBzb3VyY2UgaW1hZ2UKKworICBpZiAoZGVzdEltYWdlQnVmZmVyU2l6ZSA8CisgICAgICBtX2ltYWdlRGF0YS5zaXplKCkpICAvLyBpZiBjdXJyZW50IGRlc3RpbmF0aW9uIGJ1ZmZlciB0b28gc21hbGwKKyAgeworICAgIGlmICgqZGVzdEltYWdlICE9IG51bGxwdHIpIGRlbGV0ZVtdICogZGVzdEltYWdlOworICAgIGRlc3RJbWFnZUJ1ZmZlclNpemUgPSBtX2ltYWdlRGF0YS5zaXplKCkgKyBrSW1hZ2VCdWZmZXJBbGxvY2F0aW9uSW5jcmVtZW50OworICAgICpkZXN0SW1hZ2UgPSBuZXcgY2hhcltkZXN0SW1hZ2VCdWZmZXJTaXplXTsKKyAgICBpZiAoKmRlc3RJbWFnZSA9PSBudWxscHRyKSByZXR1cm4gMDsKKyAgfQorICAvLyBjb3B5IHRoaXMgaW1hZ2UgaW50byBkZXN0aW5hdGlvbiBidWZmZXIKKyAgaWYgKCpkZXN0SW1hZ2UgPT0gbnVsbHB0cikgeworICAgIHdwaV9zZXRXUElFcnJvcldpdGhDb250ZXh0KE51bGxQYXJhbWV0ZXIsICIqZGVzdEltYWdlIG11c3Qgbm90IGJlIG51bGxwdHIiKTsKKyAgfQorCisgIHN0ZDo6Y29weShtX2ltYWdlRGF0YS5iZWdpbigpLCBtX2ltYWdlRGF0YS5lbmQoKSwgKmRlc3RJbWFnZSk7CisgIGRlc3RJbWFnZVNpemUgPSBtX2ltYWdlRGF0YS5zaXplKCk7CisgIDsKKyAgcmV0dXJuIDE7Cit9CisKKy8qKgorICogUmVxdWVzdCBhIGNoYW5nZSBpbiB0aGUgYnJpZ2h0bmVzcyBvZiB0aGUgY2FtZXJhIGltYWdlcy4KKyAqIEBwYXJhbSBicmlnaHRuZXNzIHZhbGlkIHZhbHVlcyAwIC4uIDEwMAorICovCit2b2lkIEF4aXNDYW1lcmE6OldyaXRlQnJpZ2h0bmVzcyhpbnQgYnJpZ2h0bmVzcykgeworICBpZiAoYnJpZ2h0bmVzcyA8IDAgfHwgYnJpZ2h0bmVzcyA+IDEwMCkgeworICAgIHdwaV9zZXRXUElFcnJvcldpdGhDb250ZXh0KFBhcmFtZXRlck91dE9mUmFuZ2UsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIkJyaWdodG5lc3MgbXVzdCBiZSBmcm9tIDAgdG8gMTAwIik7CisgICAgcmV0dXJuOworICB9CisKKyAgc3RkOjpsb2NrX2d1YXJkPHByaW9yaXR5X211dGV4PiBsb2NrKG1fcGFyYW1ldGVyc011dGV4KTsKKworICBpZiAobV9icmlnaHRuZXNzICE9IGJyaWdodG5lc3MpIHsKKyAgICBtX2JyaWdodG5lc3MgPSBicmlnaHRuZXNzOworICAgIG1fcGFyYW1ldGVyc0RpcnR5ID0gdHJ1ZTsKKyAgfQorfQorCisvKioKKyAqIEByZXR1cm4gVGhlIGNvbmZpZ3VyZWQgYnJpZ2h0bmVzcyBvZiB0aGUgY2FtZXJhIGltYWdlcworICovCitpbnQgQXhpc0NhbWVyYTo6R2V0QnJpZ2h0bmVzcygpIHsKKyAgc3RkOjpsb2NrX2d1YXJkPHByaW9yaXR5X211dGV4PiBsb2NrKG1fcGFyYW1ldGVyc011dGV4KTsKKyAgcmV0dXJuIG1fYnJpZ2h0bmVzczsKK30KKworLyoqCisgKiBSZXF1ZXN0IGEgY2hhbmdlIGluIHRoZSB3aGl0ZSBiYWxhbmNlIG9uIHRoZSBjYW1lcmEuCisgKiBAcGFyYW0gd2hpdGVCYWxhbmNlIFZhbGlkIHZhbHVlcyBmcm9tIHRoZSA8Y29kZT5XaGl0ZUJhbGFuY2U8L2NvZGU+IGVudW0uCisgKi8KK3ZvaWQgQXhpc0NhbWVyYTo6V3JpdGVXaGl0ZUJhbGFuY2UoQXhpc0NhbWVyYTo6V2hpdGVCYWxhbmNlIHdoaXRlQmFsYW5jZSkgeworICBzdGQ6OmxvY2tfZ3VhcmQ8cHJpb3JpdHlfbXV0ZXg+IGxvY2sobV9wYXJhbWV0ZXJzTXV0ZXgpOworCisgIGlmIChtX3doaXRlQmFsYW5jZSAhPSB3aGl0ZUJhbGFuY2UpIHsKKyAgICBtX3doaXRlQmFsYW5jZSA9IHdoaXRlQmFsYW5jZTsKKyAgICBtX3BhcmFtZXRlcnNEaXJ0eSA9IHRydWU7CisgIH0KK30KKworLyoqCisgKiBAcmV0dXJuIFRoZSBjb25maWd1cmVkIHdoaXRlIGJhbGFuY2VzIG9mIHRoZSBjYW1lcmEgaW1hZ2VzCisgKi8KK0F4aXNDYW1lcmE6OldoaXRlQmFsYW5jZSBBeGlzQ2FtZXJhOjpHZXRXaGl0ZUJhbGFuY2UoKSB7CisgIHN0ZDo6bG9ja19ndWFyZDxwcmlvcml0eV9tdXRleD4gbG9jayhtX3BhcmFtZXRlcnNNdXRleCk7CisgIHJldHVybiBtX3doaXRlQmFsYW5jZTsKK30KKworLyoqCisgKiBSZXF1ZXN0IGEgY2hhbmdlIGluIHRoZSBjb2xvciBsZXZlbCBvZiB0aGUgY2FtZXJhIGltYWdlcy4KKyAqIEBwYXJhbSBjb2xvckxldmVsIHZhbGlkIHZhbHVlcyBhcmUgMCAuLiAxMDAKKyAqLwordm9pZCBBeGlzQ2FtZXJhOjpXcml0ZUNvbG9yTGV2ZWwoaW50IGNvbG9yTGV2ZWwpIHsKKyAgaWYgKGNvbG9yTGV2ZWwgPCAwIHx8IGNvbG9yTGV2ZWwgPiAxMDApIHsKKyAgICB3cGlfc2V0V1BJRXJyb3JXaXRoQ29udGV4dChQYXJhbWV0ZXJPdXRPZlJhbmdlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJDb2xvciBsZXZlbCBtdXN0IGJlIGZyb20gMCB0byAxMDAiKTsKKyAgICByZXR1cm47CisgIH0KKworICBzdGQ6OmxvY2tfZ3VhcmQ8cHJpb3JpdHlfbXV0ZXg+IGxvY2sobV9wYXJhbWV0ZXJzTXV0ZXgpOworCisgIGlmIChtX2NvbG9yTGV2ZWwgIT0gY29sb3JMZXZlbCkgeworICAgIG1fY29sb3JMZXZlbCA9IGNvbG9yTGV2ZWw7CisgICAgbV9wYXJhbWV0ZXJzRGlydHkgPSB0cnVlOworICB9Cit9CisKKy8qKgorICogQHJldHVybiBUaGUgY29uZmlndXJlZCBjb2xvciBsZXZlbCBvZiB0aGUgY2FtZXJhIGltYWdlcworICovCitpbnQgQXhpc0NhbWVyYTo6R2V0Q29sb3JMZXZlbCgpIHsKKyAgc3RkOjpsb2NrX2d1YXJkPHByaW9yaXR5X211dGV4PiBsb2NrKG1fcGFyYW1ldGVyc011dGV4KTsKKyAgcmV0dXJuIG1fY29sb3JMZXZlbDsKK30KKworLyoqCisgKiBSZXF1ZXN0IGEgY2hhbmdlIGluIHRoZSBjYW1lcmEncyBleHBvc3VyZSBtb2RlLgorICogQHBhcmFtIGV4cG9zdXJlQ29udHJvbCBBIG1vZGUgdG8gd3JpdGUgaW4gdGhlIDxjb2RlPkV4cG9zdXJlPC9jb2RlPiBlbnVtLgorICovCit2b2lkIEF4aXNDYW1lcmE6OldyaXRlRXhwb3N1cmVDb250cm9sKAorICAgIEF4aXNDYW1lcmE6OkV4cG9zdXJlQ29udHJvbCBleHBvc3VyZUNvbnRyb2wpIHsKKyAgc3RkOjpsb2NrX2d1YXJkPHByaW9yaXR5X211dGV4PiBsb2NrKG1fcGFyYW1ldGVyc011dGV4KTsKKworICBpZiAobV9leHBvc3VyZUNvbnRyb2wgIT0gZXhwb3N1cmVDb250cm9sKSB7CisgICAgbV9leHBvc3VyZUNvbnRyb2wgPSBleHBvc3VyZUNvbnRyb2w7CisgICAgbV9wYXJhbWV0ZXJzRGlydHkgPSB0cnVlOworICB9Cit9CisKKy8qKgorICogQHJldHVybiBUaGUgY29uZmlndXJlZCBleHBvc3VyZSBjb250cm9sIG1vZGUgb2YgdGhlIGNhbWVyYQorICovCitBeGlzQ2FtZXJhOjpFeHBvc3VyZUNvbnRyb2wgQXhpc0NhbWVyYTo6R2V0RXhwb3N1cmVDb250cm9sKCkgeworICBzdGQ6OmxvY2tfZ3VhcmQ8cHJpb3JpdHlfbXV0ZXg+IGxvY2sobV9wYXJhbWV0ZXJzTXV0ZXgpOworICByZXR1cm4gbV9leHBvc3VyZUNvbnRyb2w7Cit9CisKKy8qKgorICogUmVxdWVzdCBhIGNoYW5nZSBpbiB0aGUgZXhwb3N1cmUgcHJpb3JpdHkgb2YgdGhlIGNhbWVyYS4KKyAqIEBwYXJhbSBleHBvc3VyZVByaW9yaXR5IFZhbGlkIHZhbHVlcyBhcmUgMCwgNTAsIDEwMC4KKyAqIDAgPSBQcmlvcml0aXplIGltYWdlIHF1YWxpdHkKKyAqIDUwID0gTm9uZQorICogMTAwID0gUHJpb3JpdGl6ZSBmcmFtZSByYXRlCisgKi8KK3ZvaWQgQXhpc0NhbWVyYTo6V3JpdGVFeHBvc3VyZVByaW9yaXR5KGludCBleHBvc3VyZVByaW9yaXR5KSB7CisgIGlmIChleHBvc3VyZVByaW9yaXR5ICE9IDAgJiYgZXhwb3N1cmVQcmlvcml0eSAhPSA1MCAmJgorICAgICAgZXhwb3N1cmVQcmlvcml0eSAhPSAxMDApIHsKKyAgICB3cGlfc2V0V1BJRXJyb3JXaXRoQ29udGV4dChQYXJhbWV0ZXJPdXRPZlJhbmdlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJFeHBvc3VyZSBwcmlvcml0eSBtdXN0IGJlIGZyb20gMCwgNTAsIG9yIDEwMCIpOworICAgIHJldHVybjsKKyAgfQorCisgIHN0ZDo6bG9ja19ndWFyZDxwcmlvcml0eV9tdXRleD4gbG9jayhtX3BhcmFtZXRlcnNNdXRleCk7CisKKyAgaWYgKG1fZXhwb3N1cmVQcmlvcml0eSAhPSBleHBvc3VyZVByaW9yaXR5KSB7CisgICAgbV9leHBvc3VyZVByaW9yaXR5ID0gZXhwb3N1cmVQcmlvcml0eTsKKyAgICBtX3BhcmFtZXRlcnNEaXJ0eSA9IHRydWU7CisgIH0KK30KKworLyoqCisgKiBAcmV0dXJuIFRoZSBjb25maWd1cmVkIGV4cG9zdXJlIHByaW9yaXR5IG9mIHRoZSBjYW1lcmEKKyAqLworaW50IEF4aXNDYW1lcmE6OkdldEV4cG9zdXJlUHJpb3JpdHkoKSB7CisgIHN0ZDo6bG9ja19ndWFyZDxwcmlvcml0eV9tdXRleD4gbG9jayhtX3BhcmFtZXRlcnNNdXRleCk7CisgIHJldHVybiBtX2V4cG9zdXJlUHJpb3JpdHk7Cit9CisKKy8qKgorICogV3JpdGUgdGhlIG1heGltdW0gZnJhbWVzIHBlciBzZWNvbmQgdGhhdCB0aGUgY2FtZXJhIHNob3VsZCBzZW5kCisgKiBXcml0ZSAwIHRvIHNlbmQgYXMgbWFueSBhcyBwb3NzaWJsZS4KKyAqIEBwYXJhbSBtYXhGUFMgVGhlIG51bWJlciBvZiBmcmFtZXMgdGhlIGNhbWVyYSBzaG91bGQgc2VuZCBpbiBhIHNlY29uZCwKKyAqIGV4cG9zdXJlIHBlcm1pdHRpbmcuCisgKi8KK3ZvaWQgQXhpc0NhbWVyYTo6V3JpdGVNYXhGUFMoaW50IG1heEZQUykgeworICBzdGQ6OmxvY2tfZ3VhcmQ8cHJpb3JpdHlfbXV0ZXg+IGxvY2sobV9wYXJhbWV0ZXJzTXV0ZXgpOworCisgIGlmIChtX21heEZQUyAhPSBtYXhGUFMpIHsKKyAgICBtX21heEZQUyA9IG1heEZQUzsKKyAgICBtX3BhcmFtZXRlcnNEaXJ0eSA9IHRydWU7CisgICAgbV9zdHJlYW1EaXJ0eSA9IHRydWU7CisgIH0KK30KKworLyoqCisgKiBAcmV0dXJuIFRoZSBjb25maWd1cmVkIG1heGltdW0gRlBTIG9mIHRoZSBjYW1lcmEKKyAqLworaW50IEF4aXNDYW1lcmE6OkdldE1heEZQUygpIHsKKyAgc3RkOjpsb2NrX2d1YXJkPHByaW9yaXR5X211dGV4PiBsb2NrKG1fcGFyYW1ldGVyc011dGV4KTsKKyAgcmV0dXJuIG1fbWF4RlBTOworfQorCisvKioKKyAqIFdyaXRlIHJlc29sdXRpb24gdmFsdWUgdG8gY2FtZXJhLgorICogQHBhcmFtIHJlc29sdXRpb24gVGhlIGNhbWVyYSByZXNvbHV0aW9uIHZhbHVlIHRvIHdyaXRlIHRvIHRoZSBjYW1lcmEuCisgKi8KK3ZvaWQgQXhpc0NhbWVyYTo6V3JpdGVSZXNvbHV0aW9uKEF4aXNDYW1lcmE6OlJlc29sdXRpb24gcmVzb2x1dGlvbikgeworICBzdGQ6OmxvY2tfZ3VhcmQ8cHJpb3JpdHlfbXV0ZXg+IGxvY2sobV9wYXJhbWV0ZXJzTXV0ZXgpOworCisgIGlmIChtX3Jlc29sdXRpb24gIT0gcmVzb2x1dGlvbikgeworICAgIG1fcmVzb2x1dGlvbiA9IHJlc29sdXRpb247CisgICAgbV9wYXJhbWV0ZXJzRGlydHkgPSB0cnVlOworICAgIG1fc3RyZWFtRGlydHkgPSB0cnVlOworICB9Cit9CisKKy8qKgorICogQHJldHVybiBUaGUgY29uZmlndXJlZCByZXNvbHV0aW9uIG9mIHRoZSBjYW1lcmEgKG5vdCBuZWNlc3NhcmlseSB0aGUgc2FtZQorICogcmVzb2x1dGlvbiBhcyB0aGUgbW9zdCByZWNlbnQgaW1hZ2UsIGlmIGl0IHdhcyBjaGFuZ2VkIHJlY2VudGx5LikKKyAqLworQXhpc0NhbWVyYTo6UmVzb2x1dGlvbiBBeGlzQ2FtZXJhOjpHZXRSZXNvbHV0aW9uKCkgeworICBzdGQ6OmxvY2tfZ3VhcmQ8cHJpb3JpdHlfbXV0ZXg+IGxvY2sobV9wYXJhbWV0ZXJzTXV0ZXgpOworICByZXR1cm4gbV9yZXNvbHV0aW9uOworfQorCisvKioKKyAqIFdyaXRlIHRoZSByb3RhdGlvbiB2YWx1ZSB0byB0aGUgY2FtZXJhLgorICogSWYgeW91IG1vdW50IHlvdXIgY2FtZXJhIHVwc2lkZSBkb3duLCB1c2UgdGhpcyB0byBhZGp1c3QgdGhlIGltYWdlIGZvciB5b3UuCisgKiBAcGFyYW0gcm90YXRpb24gVGhlIGFuZ2xlIHRvIHJvdGF0ZSB0aGUgY2FtZXJhCisgKiAoPGNvZGU+QXhpc0NhbWVyYTo6Um90YXRpb246OmswPC9jb2RlPgorICogb3IgPGNvZGU+QXhpc0NhbWVyYTo6Um90YXRpb246OmsxODA8L2NvZGU+KQorICovCit2b2lkIEF4aXNDYW1lcmE6OldyaXRlUm90YXRpb24oQXhpc0NhbWVyYTo6Um90YXRpb24gcm90YXRpb24pIHsKKyAgc3RkOjpsb2NrX2d1YXJkPHByaW9yaXR5X211dGV4PiBsb2NrKG1fcGFyYW1ldGVyc011dGV4KTsKKworICBpZiAobV9yb3RhdGlvbiAhPSByb3RhdGlvbikgeworICAgIG1fcm90YXRpb24gPSByb3RhdGlvbjsKKyAgICBtX3BhcmFtZXRlcnNEaXJ0eSA9IHRydWU7CisgICAgbV9zdHJlYW1EaXJ0eSA9IHRydWU7CisgIH0KK30KKworLyoqCisgKiBAcmV0dXJuIFRoZSBjb25maWd1cmVkIHJvdGF0aW9uIG1vZGUgb2YgdGhlIGNhbWVyYQorICovCitBeGlzQ2FtZXJhOjpSb3RhdGlvbiBBeGlzQ2FtZXJhOjpHZXRSb3RhdGlvbigpIHsKKyAgc3RkOjpsb2NrX2d1YXJkPHByaW9yaXR5X211dGV4PiBsb2NrKG1fcGFyYW1ldGVyc011dGV4KTsKKyAgcmV0dXJuIG1fcm90YXRpb247Cit9CisKKy8qKgorICogV3JpdGUgdGhlIGNvbXByZXNzaW9uIHZhbHVlIHRvIHRoZSBjYW1lcmEuCisgKiBAcGFyYW0gY29tcHJlc3Npb24gVmFsdWVzIGJldHdlZW4gMCBhbmQgMTAwLgorICovCit2b2lkIEF4aXNDYW1lcmE6OldyaXRlQ29tcHJlc3Npb24oaW50IGNvbXByZXNzaW9uKSB7CisgIGlmIChjb21wcmVzc2lvbiA8IDAgfHwgY29tcHJlc3Npb24gPiAxMDApIHsKKyAgICB3cGlfc2V0V1BJRXJyb3JXaXRoQ29udGV4dChQYXJhbWV0ZXJPdXRPZlJhbmdlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJDb21wcmVzc2lvbiBtdXN0IGJlIGZyb20gMCB0byAxMDAiKTsKKyAgICByZXR1cm47CisgIH0KKworICBzdGQ6OmxvY2tfZ3VhcmQ8cHJpb3JpdHlfbXV0ZXg+IGxvY2sobV9wYXJhbWV0ZXJzTXV0ZXgpOworCisgIGlmIChtX2NvbXByZXNzaW9uICE9IGNvbXByZXNzaW9uKSB7CisgICAgbV9jb21wcmVzc2lvbiA9IGNvbXByZXNzaW9uOworICAgIG1fcGFyYW1ldGVyc0RpcnR5ID0gdHJ1ZTsKKyAgICBtX3N0cmVhbURpcnR5ID0gdHJ1ZTsKKyAgfQorfQorCisvKioKKyAqIEByZXR1cm4gVGhlIGNvbmZpZ3VyZWQgY29tcHJlc3Npb24gbGV2ZWwgb2YgdGhlIGNhbWVyYQorICovCitpbnQgQXhpc0NhbWVyYTo6R2V0Q29tcHJlc3Npb24oKSB7CisgIHN0ZDo6bG9ja19ndWFyZDxwcmlvcml0eV9tdXRleD4gbG9jayhtX3BhcmFtZXRlcnNNdXRleCk7CisgIHJldHVybiBtX2NvbXByZXNzaW9uOworfQorCisvKioKKyAqIE1ldGhvZCBjYWxsZWQgaW4gdGhlIGNhcHR1cmUgdGhyZWFkIHRvIHJlY2VpdmUgaW1hZ2VzIGZyb20gdGhlIGNhbWVyYQorICovCit2b2lkIEF4aXNDYW1lcmE6OkNhcHR1cmUoKSB7CisgIGludCBjb25zZWN1dGl2ZUVycm9ycyA9IDA7CisKKyAgLy8gTG9vcCBvbiB0cnlpbmcgdG8gc2V0dXAgdGhlIGNhbWVyYSBjb25uZWN0aW9uLiBUaGlzIGhhcHBlbnMgaW4gYSBiYWNrZ3JvdW5kCisgIC8vIHRocmVhZCBzbyBpdCBzaG91bGRuJ3QgZWZmZWN0IHRoZSBvcGVyYXRpb24gb2YgdXNlciBwcm9ncmFtcy4KKyAgd2hpbGUgKCFtX2RvbmUpIHsKKyAgICBzdGQ6OnN0cmluZyByZXF1ZXN0U3RyaW5nID0KKyAgICAgICAgIkdFVCAvbWpwZy92aWRlby5tanBnIEhUVFAvMS4xXG4iCisgICAgICAgICJVc2VyLUFnZW50OiBIVFRQU3RyZWFtQ2xpZW50XG4iCisgICAgICAgICJDb25uZWN0aW9uOiBLZWVwLUFsaXZlXG4iCisgICAgICAgICJDYWNoZS1Db250cm9sOiBuby1jYWNoZVxuIgorICAgICAgICAiQXV0aG9yaXphdGlvbjogQmFzaWMgUmxKRE9rWlNRdz09XG5cbiI7CisgICAgbV9jYXB0dXJlTXV0ZXgubG9jaygpOworICAgIG1fY2FtZXJhU29ja2V0ID0gQ3JlYXRlQ2FtZXJhU29ja2V0KHJlcXVlc3RTdHJpbmcsIGNvbnNlY3V0aXZlRXJyb3JzID4gNSk7CisgICAgaWYgKG1fY2FtZXJhU29ja2V0ICE9IC0xKSB7CisgICAgICBSZWFkSW1hZ2VzRnJvbUNhbWVyYSgpOworICAgICAgY29uc2VjdXRpdmVFcnJvcnMgPSAwOworICAgIH0gZWxzZSB7CisgICAgICBjb25zZWN1dGl2ZUVycm9ycysrOworICAgIH0KKyAgICBtX2NhcHR1cmVNdXRleC51bmxvY2soKTsKKyAgICBXYWl0KDAuNSk7CisgIH0KK30KKworLyoqCisgKiBUaGlzIGZ1bmN0aW9uIGFjdHVhbGx5IHJlYWRzIHRoZSBpbWFnZXMgZnJvbSB0aGUgY2FtZXJhLgorICovCit2b2lkIEF4aXNDYW1lcmE6OlJlYWRJbWFnZXNGcm9tQ2FtZXJhKCkgeworICBjaGFyICppbWdCdWZmZXIgPSBudWxscHRyOworICBpbnQgaW1nQnVmZmVyTGVuZ3RoID0gMDsKKworICAvLyBUT0RPOiB0aGVzZSByZWN2IGNhbGxzIG11c3QgYmUgbm9uLWJsb2NraW5nLiBPdGhlcndpc2UgaWYgdGhlIGNhbWVyYQorICAvLyBmYWlscyBkdXJpbmcgYSByZWFkLCB0aGUgY29kZSBoYW5ncyBhbmQgbmV2ZXIgcmV0cmllcyB3aGVuIHRoZSBjYW1lcmEgY29tZXMKKyAgLy8gYmFjayB1cC4KKworICBpbnQgY291bnRlciA9IDI7CisgIHdoaWxlICghbV9kb25lKSB7CisgICAgY2hhciBpbml0aWFsUmVhZEJ1ZmZlcltrTWF4UGFja2V0U2l6ZV0gPSAiIjsKKyAgICBjaGFyIGludGVybWVkaWF0ZUJ1ZmZlclsxXTsKKyAgICBjaGFyICp0cmFpbGluZ1B0ciA9IGluaXRpYWxSZWFkQnVmZmVyOworICAgIGludCB0cmFpbGluZ0NvdW50ZXIgPSAwOworICAgIHdoaWxlIChjb3VudGVyKSB7CisgICAgICAvLyBUT0RPOiBmaXggbWUuLi4gdGhpcyBjYW5ub3QgYmUgdGhlIG1vc3QgZWZmaWNpZW50IHdheSB0byBhcHByb2FjaCB0aGlzLAorICAgICAgLy8gcmVhZGluZyBvbmUgYnl0ZSBhdCBhIHRpbWUuCisgICAgICBpZiAocmVjdihtX2NhbWVyYVNvY2tldCwgaW50ZXJtZWRpYXRlQnVmZmVyLCAxLCAwKSA9PSAtMSkgeworICAgICAgICB3cGlfc2V0RXJybm9FcnJvcldpdGhDb250ZXh0KCJGYWlsZWQgdG8gcmVhZCBpbWFnZSBoZWFkZXIiKTsKKyAgICAgICAgY2xvc2UobV9jYW1lcmFTb2NrZXQpOworICAgICAgICByZXR1cm47CisgICAgICB9CisgICAgICBzdHJuY2F0KGluaXRpYWxSZWFkQnVmZmVyLCBpbnRlcm1lZGlhdGVCdWZmZXIsIDEpOworICAgICAgLy8gdHJhaWxpbmdDb3VudGVyIGVuc3VyZXMgdGhhdCB3ZSBzdGFydCBsb29raW5nIGZvciB0aGUgNCBieXRlIHN0cmluZworICAgICAgLy8gYWZ0ZXIKKyAgICAgIC8vIHRoZXJlIGlzIGF0IGxlYXN0IDQgYnl0ZXMgdG90YWwuIEtpbmQgb2Ygb2JzY3VyZS4KKyAgICAgIC8vIGxvb2sgZm9yIDIgYmxhbmsgbGluZXMgKFxyXG4pCisgICAgICBpZiAobnVsbHB0ciAhPSBzdHJzdHIodHJhaWxpbmdQdHIsICJcclxuXHJcbiIpKSB7CisgICAgICAgIC0tY291bnRlcjsKKyAgICAgIH0KKyAgICAgIGlmICgrK3RyYWlsaW5nQ291bnRlciA+PSA0KSB7CisgICAgICAgIHRyYWlsaW5nUHRyKys7CisgICAgICB9CisgICAgfQorICAgIGNvdW50ZXIgPSAxOworICAgIGNoYXIgKmNvbnRlbnRMZW5ndGggPSBzdHJzdHIoaW5pdGlhbFJlYWRCdWZmZXIsICJDb250ZW50LUxlbmd0aDogIik7CisgICAgaWYgKGNvbnRlbnRMZW5ndGggPT0gbnVsbHB0cikgeworICAgICAgd3BpX3NldFdQSUVycm9yV2l0aENvbnRleHQoSW5jb21wYXRpYmxlTW9kZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJObyBjb250ZW50LWxlbmd0aCB0b2tlbiBmb3VuZCBpbiBwYWNrZXQiKTsKKyAgICAgIGNsb3NlKG1fY2FtZXJhU29ja2V0KTsKKyAgICAgIGlmIChpbWdCdWZmZXIpIGRlbGV0ZVtdIGltZ0J1ZmZlcjsKKyAgICAgIHJldHVybjsKKyAgICB9CisgICAgY29udGVudExlbmd0aCA9IGNvbnRlbnRMZW5ndGggKyAxNjsgICAgLy8gc2tpcCBwYXN0ICJjb250ZW50IGxlbmd0aCIKKyAgICBpbnQgcmVhZExlbmd0aCA9IGF0b2woY29udGVudExlbmd0aCk7ICAvLyBnZXQgdGhlIGltYWdlIGJ5dGUgY291bnQKKworICAgIC8vIE1ha2Ugc3VyZSBidWZmZXIgaXMgbGFyZ2UgZW5vdWdoCisgICAgaWYgKGltZ0J1ZmZlckxlbmd0aCA8IHJlYWRMZW5ndGgpIHsKKyAgICAgIGlmIChpbWdCdWZmZXIpIGRlbGV0ZVtdIGltZ0J1ZmZlcjsKKyAgICAgIGltZ0J1ZmZlckxlbmd0aCA9IHJlYWRMZW5ndGggKyBrSW1hZ2VCdWZmZXJBbGxvY2F0aW9uSW5jcmVtZW50OworICAgICAgaW1nQnVmZmVyID0gbmV3IGNoYXJbaW1nQnVmZmVyTGVuZ3RoXTsKKyAgICAgIGlmIChpbWdCdWZmZXIgPT0gbnVsbHB0cikgeworICAgICAgICBpbWdCdWZmZXJMZW5ndGggPSAwOworICAgICAgICBjb250aW51ZTsKKyAgICAgIH0KKyAgICB9CisKKyAgICAvLyBSZWFkIHRoZSBpbWFnZSBkYXRhIGZvciAiQ29udGVudC1MZW5ndGgiIGJ5dGVzCisgICAgaW50IGJ5dGVzUmVhZCA9IDA7CisgICAgaW50IHJlbWFpbmluZyA9IHJlYWRMZW5ndGg7CisgICAgd2hpbGUgKGJ5dGVzUmVhZCA8IHJlYWRMZW5ndGgpIHsKKyAgICAgIGludCBieXRlc1RoaXNSZWN2ID0KKyAgICAgICAgICByZWN2KG1fY2FtZXJhU29ja2V0LCAmaW1nQnVmZmVyW2J5dGVzUmVhZF0sIHJlbWFpbmluZywgMCk7CisgICAgICBieXRlc1JlYWQgKz0gYnl0ZXNUaGlzUmVjdjsKKyAgICAgIHJlbWFpbmluZyAtPSBieXRlc1RoaXNSZWN2OworICAgIH0KKworICAgIC8vIFVwZGF0ZSBpbWFnZQorICAgIHsKKyAgICAgIHN0ZDo6bG9ja19ndWFyZDxwcmlvcml0eV9tdXRleD4gbG9jayhtX2ltYWdlRGF0YU11dGV4KTsKKworICAgICAgbV9pbWFnZURhdGEuYXNzaWduKGltZ0J1ZmZlciwgaW1nQnVmZmVyICsgaW1nQnVmZmVyTGVuZ3RoKTsKKyAgICAgIG1fZnJlc2hJbWFnZSA9IHRydWU7CisgICAgfQorCisgICAgaWYgKFdyaXRlUGFyYW1ldGVycygpKSB7CisgICAgICBicmVhazsKKyAgICB9CisgIH0KKworICBjbG9zZShtX2NhbWVyYVNvY2tldCk7Cit9CisKKy8qKgorICogU2VuZCBhIHJlcXVlc3QgdG8gdGhlIGNhbWVyYSB0byBzZXQgYWxsIG9mIHRoZSBwYXJhbWV0ZXJzLiAgVGhpcyBpcyBjYWxsZWQKKyAqIGluIHRoZSBjYXB0dXJlIHRocmVhZCBiZXR3ZWVuIGVhY2ggZnJhbWUuIFRoaXMgc3RyYXRlZ3kgYXZvaWRzIG1ha2luZyBsb3RzCisgKiBvZiByZWR1bmRhbnQgSFRUUCByZXF1ZXN0cywgYWNjb3VudHMgZm9yIGZhaWxlZCBpbml0aWFsIHJlcXVlc3RzLCBhbmQKKyAqIGF2b2lkcyBibG9ja2luZyBjYWxscyBpbiB0aGUgbWFpbiB0aHJlYWQgdW5sZXNzIG5lY2Vzc2FyeS4KKyAqCisgKiBUaGlzIG1ldGhvZCBkb2VzIG5vdGhpbmcgaWYgbm8gcGFyYW1ldGVycyBoYXZlIGJlZW4gbW9kaWZpZWQgc2luY2UgaXQgbGFzdAorICogY29tcGxldGVseSBzdWNjZXNzZnVsbHkuCisgKgorICogQHJldHVybiA8Y29kZT50cnVlPC9jb2RlPiBpZiB0aGUgc3RyZWFtIHNob3VsZCBiZSByZXN0YXJ0ZWQgZHVlIHRvIGEKKyAqIHBhcmFtZXRlciBjaGFuZ2luZy4KKyAqLworYm9vbCBBeGlzQ2FtZXJhOjpXcml0ZVBhcmFtZXRlcnMoKSB7CisgIGlmIChtX3BhcmFtZXRlcnNEaXJ0eSkgeworICAgIHN0ZDo6c3RyaW5nc3RyZWFtIHJlcXVlc3Q7CisgICAgcmVxdWVzdCA8PCAiR0VUIC9heGlzLWNnaS9hZG1pbi9wYXJhbS5jZ2k/YWN0aW9uPXVwZGF0ZSI7CisKKyAgICBtX3BhcmFtZXRlcnNNdXRleC5sb2NrKCk7CisgICAgcmVxdWVzdCA8PCAiJkltYWdlU291cmNlLkkwLlNlbnNvci5CcmlnaHRuZXNzPSIgPDwgbV9icmlnaHRuZXNzOworICAgIHJlcXVlc3QgPDwgIiZJbWFnZVNvdXJjZS5JMC5TZW5zb3IuV2hpdGVCYWxhbmNlPSIKKyAgICAgICAgICAgIDw8IGtXaGl0ZUJhbGFuY2VTdHJpbmdzW21fd2hpdGVCYWxhbmNlXTsKKyAgICByZXF1ZXN0IDw8ICImSW1hZ2VTb3VyY2UuSTAuU2Vuc29yLkNvbG9yTGV2ZWw9IiA8PCBtX2NvbG9yTGV2ZWw7CisgICAgcmVxdWVzdCA8PCAiJkltYWdlU291cmNlLkkwLlNlbnNvci5FeHBvc3VyZT0iCisgICAgICAgICAgICA8PCBrRXhwb3N1cmVDb250cm9sU3RyaW5nc1ttX2V4cG9zdXJlQ29udHJvbF07CisgICAgcmVxdWVzdCA8PCAiJkltYWdlU291cmNlLkkwLlNlbnNvci5FeHBvc3VyZVByaW9yaXR5PSIgPDwgbV9leHBvc3VyZVByaW9yaXR5OworICAgIHJlcXVlc3QgPDwgIiZJbWFnZS5JMC5TdHJlYW0uRlBTPSIgPDwgbV9tYXhGUFM7CisgICAgcmVxdWVzdCA8PCAiJkltYWdlLkkwLkFwcGVhcmFuY2UuUmVzb2x1dGlvbj0iCisgICAgICAgICAgICA8PCBrUmVzb2x1dGlvblN0cmluZ3NbbV9yZXNvbHV0aW9uXTsKKyAgICByZXF1ZXN0IDw8ICImSW1hZ2UuSTAuQXBwZWFyYW5jZS5Db21wcmVzc2lvbj0iIDw8IG1fY29tcHJlc3Npb247CisgICAgcmVxdWVzdCA8PCAiJkltYWdlLkkwLkFwcGVhcmFuY2UuUm90YXRpb249IiA8PCBrUm90YXRpb25TdHJpbmdzW21fcm90YXRpb25dOworICAgIG1fcGFyYW1ldGVyc011dGV4LnVubG9jaygpOworCisgICAgcmVxdWVzdCA8PCAiIEhUVFAvMS4xIiA8PCBzdGQ6OmVuZGw7CisgICAgcmVxdWVzdCA8PCAiVXNlci1BZ2VudDogSFRUUFN0cmVhbUNsaWVudCIgPDwgc3RkOjplbmRsOworICAgIHJlcXVlc3QgPDwgIkNvbm5lY3Rpb246IEtlZXAtQWxpdmUiIDw8IHN0ZDo6ZW5kbDsKKyAgICByZXF1ZXN0IDw8ICJDYWNoZS1Db250cm9sOiBuby1jYWNoZSIgPDwgc3RkOjplbmRsOworICAgIHJlcXVlc3QgPDwgIkF1dGhvcml6YXRpb246IEJhc2ljIFJsSkRPa1pTUXc9PSIgPDwgc3RkOjplbmRsOworICAgIHJlcXVlc3QgPDwgc3RkOjplbmRsOworCisgICAgaW50IHNvY2tldCA9IENyZWF0ZUNhbWVyYVNvY2tldChyZXF1ZXN0LnN0cigpLCBmYWxzZSk7CisgICAgaWYgKHNvY2tldCA9PSAtMSkgeworICAgICAgd3BpX3NldEVycm5vRXJyb3JXaXRoQ29udGV4dCgiRXJyb3Igc2V0dGluZyBjYW1lcmEgcGFyYW1ldGVycyIpOworICAgIH0gZWxzZSB7CisgICAgICBjbG9zZShzb2NrZXQpOworICAgICAgbV9wYXJhbWV0ZXJzRGlydHkgPSBmYWxzZTsKKworICAgICAgaWYgKG1fc3RyZWFtRGlydHkpIHsKKyAgICAgICAgbV9zdHJlYW1EaXJ0eSA9IGZhbHNlOworICAgICAgICByZXR1cm4gdHJ1ZTsKKyAgICAgIH0KKyAgICB9CisgIH0KKworICByZXR1cm4gZmFsc2U7Cit9CisKKy8qKgorICogQ3JlYXRlIGEgc29ja2V0IGNvbm5lY3RlZCB0byBjYW1lcmEKKyAqIFVzZWQgdG8gY3JlYXRlIGEgY29ubmVjdGlvbiB0byB0aGUgY2FtZXJhIGZvciBib3RoIGNhcHR1cmluZyBpbWFnZXMgYW5kCisgKiBzZXR0aW5nIHBhcmFtZXRlcnMuCisgKiBAcGFyYW0gcmVxdWVzdFN0cmluZyBUaGUgaW5pdGlhbCByZXF1ZXN0IHN0cmluZyB0byBzZW5kIHVwb24gc3VjY2Vzc2Z1bAorICogY29ubmVjdGlvbi4KKyAqIEBwYXJhbSBzZXRFcnJvciBJZiB0cnVlLCByYWlzIGFuIGVycm9yIGlmIHRoZXJlJ3MgYSBwcm9ibGVtIGNyZWF0aW5nIHRoZQorICogY29ubmVjdGlvbi4KKyAqIFRoaXMgaXMgb25seSBlbmFibGVkIGFmdGVyIHNldmVyYWwgdW5zdWNlc3NmdWwgY29ubmVjdGlvbnMsIHNvIGEgc2luZ2xlIG9uZQorICogZG9lc24ndAorICogY2F1c2UgYW4gZXJyb3IgbWVzc2FnZSB0byBiZSBwcmludGVkIGlmIGl0IGltbWVkaWF0ZWx5IHJlY292ZXJzLgorICogQHJldHVybiAtMSBpZiBmYWlsZWQsIHNvY2tldCBoYW5kbGUgaWYgc3VjY2Vzc2Z1bC4KKyAqLworaW50IEF4aXNDYW1lcmE6OkNyZWF0ZUNhbWVyYVNvY2tldChzdGQ6OnN0cmluZyBjb25zdCAmcmVxdWVzdFN0cmluZywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYm9vbCBzZXRFcnJvcikgeworICBzdHJ1Y3QgYWRkcmluZm8gKmFkZHJlc3MgPSBudWxscHRyOworICBpbnQgY2FtU29ja2V0OworCisgIC8qIGNyZWF0ZSBzb2NrZXQgKi8KKyAgaWYgKChjYW1Tb2NrZXQgPSBzb2NrZXQoQUZfSU5FVCwgU09DS19TVFJFQU0sIDApKSA9PSAtMSkgeworICAgIGlmIChzZXRFcnJvcikKKyAgICAgIHdwaV9zZXRFcnJub0Vycm9yV2l0aENvbnRleHQoIkZhaWxlZCB0byBjcmVhdGUgdGhlIGNhbWVyYSBzb2NrZXQiKTsKKyAgICByZXR1cm4gLTE7CisgIH0KKworICBpZiAoZ2V0YWRkcmluZm8obV9jYW1lcmFIb3N0LmNfc3RyKCksICI4MCIsIG51bGxwdHIsICZhZGRyZXNzKSA9PSAtMSkgeworICAgIGlmIChzZXRFcnJvcikgeworICAgICAgd3BpX3NldEVycm5vRXJyb3JXaXRoQ29udGV4dCgiRmFpbGVkIHRvIGNyZWF0ZSB0aGUgY2FtZXJhIHNvY2tldCIpOworICAgICAgY2xvc2UoY2FtU29ja2V0KTsKKyAgICB9CisgICAgcmV0dXJuIC0xOworICB9CisKKyAgLyogY29ubmVjdCB0byBzZXJ2ZXIgKi8KKyAgaWYgKGNvbm5lY3QoY2FtU29ja2V0LCBhZGRyZXNzLT5haV9hZGRyLCBhZGRyZXNzLT5haV9hZGRybGVuKSA9PSAtMSkgeworICAgIGlmIChzZXRFcnJvcikKKyAgICAgIHdwaV9zZXRFcnJub0Vycm9yV2l0aENvbnRleHQoIkZhaWxlZCB0byBjb25uZWN0IHRvIHRoZSBjYW1lcmEiKTsKKyAgICBmcmVlYWRkcmluZm8oYWRkcmVzcyk7CisgICAgY2xvc2UoY2FtU29ja2V0KTsKKyAgICByZXR1cm4gLTE7CisgIH0KKworICBmcmVlYWRkcmluZm8oYWRkcmVzcyk7CisKKyAgaW50IHNlbnQgPSBzZW5kKGNhbVNvY2tldCwgcmVxdWVzdFN0cmluZy5jX3N0cigpLCByZXF1ZXN0U3RyaW5nLnNpemUoKSwgMCk7CisgIGlmIChzZW50ID09IC0xKSB7CisgICAgaWYgKHNldEVycm9yKQorICAgICAgd3BpX3NldEVycm5vRXJyb3JXaXRoQ29udGV4dCgiRmFpbGVkIHRvIHNlbmQgYSByZXF1ZXN0IHRvIHRoZSBjYW1lcmEiKTsKKyAgICBjbG9zZShjYW1Tb2NrZXQpOworICAgIHJldHVybiAtMTsKKyAgfQorCisgIHJldHVybiBjYW1Tb2NrZXQ7Cit9CmRpZmYgLS1naXQgYS93cGlsaWJjL0F0aGVuYS9zcmMvVmlzaW9uL0JhZVV0aWxpdGllcy5jcHAgYi93cGlsaWJjL0F0aGVuYS9zcmMvVmlzaW9uL0JhZVV0aWxpdGllcy5jcHAKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZjA5ZWM2NAotLS0gL2Rldi9udWxsCisrKyBiL3dwaWxpYmMvQXRoZW5hL3NyYy9WaXNpb24vQmFlVXRpbGl0aWVzLmNwcApAQCAtMCwwICsxLDM2OSBAQAorLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi8KKy8qIENvcHlyaWdodCAoYykgRklSU1QgMjAxNC4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KKyAqLworLyogT3BlbiBTb3VyY2UgU29mdHdhcmUgLSBtYXkgYmUgbW9kaWZpZWQgYW5kIHNoYXJlZCBieSBGUkMgdGVhbXMuIFRoZSBjb2RlICAgKi8KKy8qIG11c3QgYmUgYWNjb21wYW5pZWQgYnkgdGhlIEZJUlNUIEJTRCBsaWNlbnNlIGZpbGUgaW4gJChXSU5EX0JBU0UpL1dQSUxpYi4gICovCisvKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qLworI2luY2x1ZGUgPHN0ZGlvLmg+CisjaW5jbHVkZSA8c3lzL3R5cGVzLmg+CisjaW5jbHVkZSA8c3lzL3N0YXQuaD4KKyNpbmNsdWRlIDx1bmlzdGQuaD4KKyNpbmNsdWRlIDxzdHJpbmcuaD4KKyNpbmNsdWRlIDxtYXRoLmg+CisjaW5jbHVkZSA8c3RkbGliLmg+CisjaW5jbHVkZSA8c3RkYXJnLmg+CisKKyNpbmNsdWRlICJWaXNpb24vQmFlVXRpbGl0aWVzLmgiCisjaW5jbHVkZSAiU2Vydm8uaCIKKyNpbmNsdWRlICJUaW1lci5oIgorCisvKiogQGZpbGUKKyAqICAgVXRpbGl0eSBmdW5jdGlvbnMKKyAqLworCisvKioKKyAqIGRlYnVnIG91dHB1dCBmbGFnIG9wdGlvbnM6CisgKiBERUJVR19PRkYsIERFQlVHX01PU1RMWV9PRkYsIERFQlVHX1NDUkVFTl9PTkxZLCBERUJVR19GSUxFX09OTFksCisgKiBERUJVR19TQ1JFRU5fQU5EX0ZJTEUKKyAqLworc3RhdGljIERlYnVnT3V0cHV0VHlwZSBkcHJpbnRmRmxhZyA9IERFQlVHX09GRjsKKworLyoqCisgKiBTZXQgdGhlIGRlYnVnIGZsYWcgdG8gcHJpbnQgdG8gc2NyZWVuLCBmaWxlIG9uIGNSSU8sIGJvdGggb3IgbmVpdGhlcgorICogQHBhcmFtIHRlbXBTdHJpbmcgVGhlIGZvcm1hdCBzdHJpbmcuCisgKi8KK3ZvaWQgU2V0RGVidWdGbGFnKERlYnVnT3V0cHV0VHlwZSBmbGFnKSB7IGRwcmludGZGbGFnID0gZmxhZzsgfQorCisvKioKKyAqIERlYnVnIHByaW50IHRvIGEgZmlsZSBhbmQvb3IgYSB0ZXJtaW5hbCB3aW5kb3cuCisgKiBDYWxsIGxpa2UgeW91IHdvdWxkIGNhbGwgcHJpbnRmLgorICogU2V0IGZ1bmN0aW9uTmFtZSBpbiB0aGUgZnVuY3Rpb24gaWYgeW91IHdhbnQgdGhlIGNvcnJlY3QgZnVuY3Rpb24gbmFtZSB0bworICogcHJpbnQgb3V0LgorICogVGhlIGZpbGUgbGluZSBudW1iZXIgd2lsbCBhbHNvIGJlIHByaW50ZWQuCisgKiBAcGFyYW0gdGVtcFN0cmluZyBUaGUgZm9ybWF0IHN0cmluZy4KKyAqLwordm9pZCBkcHJpbnRmKGNvbnN0IGNoYXIgKnRlbXBTdHJpbmcsIC4uLikgLyogVmFyaWFibGUgYXJndW1lbnQgbGlzdCAqLworeworICB2YV9saXN0IGFyZ3M7ICAgIC8qIElucHV0IGFyZ3VtZW50IGxpc3QgKi8KKyAgaW50IGxpbmVfbnVtYmVyOyAvKiBMaW5lIG51bWJlciBwYXNzZWQgaW4gYXJndW1lbnQgKi8KKyAgaW50IHR5cGU7CisgIGNvbnN0IGNoYXIgKmZ1bmN0aW9uTmFtZTsgLyogRm9ybWF0IHBhc3NlZCBpbiBhcmd1bWVudCAqLworICBjb25zdCBjaGFyICpmbXQ7ICAgICAgICAgIC8qIEZvcm1hdCBwYXNzZWQgaW4gYXJndW1lbnQgKi8KKyAgY2hhciB0ZXh0WzUxMl07ICAgICAgICAgICAvKiBUZXh0IHN0cmluZyAqLworICBjaGFyIG91dHRleHRbNTEyXTsgICAgICAgIC8qIFRleHQgc3RyaW5nICovCisgIEZJTEUgKm91dGZpbGVfZmQ7ICAgICAgICAgLyogT3V0cHV0IGZpbGUgcG9pbnRlciAqLworICBjaGFyIGZpbGVwYXRoWzEyOF07ICAgICAgIC8qIFRleHQgc3RyaW5nICovCisgIGludCBmYXRhbEZsYWcgPSAwOworICBjb25zdCBjaGFyICpmaWxlbmFtZTsKKyAgaW50IGluZGV4OworICBpbnQgdGVtcFN0cmluZ0xlbjsKKworICBpZiAoZHByaW50ZkZsYWcgPT0gREVCVUdfT0ZGKSB7CisgICAgcmV0dXJuOworICB9CisKKyAgdmFfc3RhcnQoYXJncywgdGVtcFN0cmluZyk7CisKKyAgdGVtcFN0cmluZ0xlbiA9IHN0cmxlbih0ZW1wU3RyaW5nKTsKKyAgZmlsZW5hbWUgPSB0ZW1wU3RyaW5nOworICBmb3IgKGluZGV4ID0gMDsgaW5kZXggPCB0ZW1wU3RyaW5nTGVuOyBpbmRleCsrKSB7CisgICAgaWYgKHRlbXBTdHJpbmdbaW5kZXhdID09ICcgJykgeworICAgICAgcHJpbnRmKCJFUlJPUiBpbiBkcHJpbnRmOiBtYWxmb3JtZWQgY2FsbGluZyBzZXF1ZW5jZSAoJXMpXG4iLCB0ZW1wU3RyaW5nKTsKKyAgICAgIHZhX2VuZChhcmdzKTsKKyAgICAgIHJldHVybjsKKyAgICB9CisgICAgaWYgKHRlbXBTdHJpbmdbaW5kZXhdID09ICdcXCcgfHwgdGVtcFN0cmluZ1tpbmRleF0gPT0gJy8nKQorICAgICAgZmlsZW5hbWUgPSB0ZW1wU3RyaW5nICsgaW5kZXggKyAxOworICB9CisKKyAgLyogRXh0cmFjdCBmdW5jdGlvbiBuYW1lICovCisgIGZ1bmN0aW9uTmFtZSA9IHZhX2FyZyhhcmdzLCBjb25zdCBjaGFyICopOworCisgIC8qIEV4dHJhY3QgbGluZSBudW1iZXIgZnJvbSBhcmd1bWVudCBsaXN0ICovCisgIGxpbmVfbnVtYmVyID0gdmFfYXJnKGFyZ3MsIGludCk7CisKKyAgLyogRXh0cmFjdCBpbmZvcm1hdGlvbiB0eXBlIGZyb20gYXJndW1lbnQgbGlzdCAqLworICB0eXBlID0gdmFfYXJnKGFyZ3MsIGludCk7CisKKyAgLyogRXh0cmFjdCBmb3JtYXQgZnJvbSBhcmd1bWVudCBsaXN0ICovCisgIGZtdCA9IHZhX2FyZyhhcmdzLCBjb25zdCBjaGFyICopOworCisgIHZzcHJpbnRmKHRleHQsIGZtdCwgYXJncyk7CisKKyAgdmFfZW5kKGFyZ3MpOworCisgIC8qIEZvcm1hdCBvdXRwdXQgc3RhdGVtZW50ICovCisgIHN3aXRjaCAodHlwZSkgeworICAgIGNhc2UgREVCVUdfVFlQRToKKyAgICAgIHNwcmludGYob3V0dGV4dCwgIlslczolc0AlMDRkXSBERUJVRyAlc1xuIiwgZmlsZW5hbWUsIGZ1bmN0aW9uTmFtZSwKKyAgICAgICAgICAgICAgbGluZV9udW1iZXIsIHRleHQpOworICAgICAgYnJlYWs7CisgICAgY2FzZSBJTkZPX1RZUEU6CisgICAgICBzcHJpbnRmKG91dHRleHQsICJbJXM6JXNAJTA0ZF0gSU5GTyAlc1xuIiwgZmlsZW5hbWUsIGZ1bmN0aW9uTmFtZSwKKyAgICAgICAgICAgICAgbGluZV9udW1iZXIsIHRleHQpOworICAgICAgYnJlYWs7CisgICAgY2FzZSBFUlJPUl9UWVBFOgorICAgICAgc3ByaW50ZihvdXR0ZXh0LCAiWyVzOiVzQCUwNGRdIEVSUk9SICVzXG4iLCBmaWxlbmFtZSwgZnVuY3Rpb25OYW1lLAorICAgICAgICAgICAgICBsaW5lX251bWJlciwgdGV4dCk7CisgICAgICBicmVhazsKKyAgICBjYXNlIENSSVRJQ0FMX1RZUEU6CisgICAgICBzcHJpbnRmKG91dHRleHQsICJbJXM6JXNAJTA0ZF0gQ1JJVElDQUwgJXNcbiIsIGZpbGVuYW1lLCBmdW5jdGlvbk5hbWUsCisgICAgICAgICAgICAgIGxpbmVfbnVtYmVyLCB0ZXh0KTsKKyAgICAgIGJyZWFrOworICAgIGNhc2UgRkFUQUxfVFlQRToKKyAgICAgIGZhdGFsRmxhZyA9IDE7CisgICAgICBzcHJpbnRmKG91dHRleHQsICJbJXM6JXNAJTA0ZF0gRkFUQUwgJXNcbiIsIGZpbGVuYW1lLCBmdW5jdGlvbk5hbWUsCisgICAgICAgICAgICAgIGxpbmVfbnVtYmVyLCB0ZXh0KTsKKyAgICAgIGJyZWFrOworICAgIGRlZmF1bHQ6CisgICAgICBwcmludGYoIkVSUk9SIGluIGRwcmludGY6IG1hbGZvcm1lZCBjYWxsaW5nIHNlcXVlbmNlXG4iKTsKKyAgICAgIHJldHVybjsKKyAgICAgIGJyZWFrOworICB9CisKKyAgc3ByaW50ZihmaWxlcGF0aCwgIiVzLmRlYnVnIiwgZmlsZW5hbWUpOworCisgIC8qIFdyaXRlIG91dHB1dCBzdGF0ZW1lbnQgKi8KKyAgc3dpdGNoIChkcHJpbnRmRmxhZykgeworICAgIGRlZmF1bHQ6CisgICAgY2FzZSBERUJVR19PRkY6CisgICAgICBicmVhazsKKyAgICBjYXNlIERFQlVHX01PU1RMWV9PRkY6CisgICAgICBpZiAoZmF0YWxGbGFnKSB7CisgICAgICAgIGlmICgob3V0ZmlsZV9mZCA9IGZvcGVuKGZpbGVwYXRoLCAiYSsiKSkgIT0gbnVsbHB0cikgeworICAgICAgICAgIGZ3cml0ZShvdXR0ZXh0LCBzaXplb2YoY2hhciksIHN0cmxlbihvdXR0ZXh0KSwgb3V0ZmlsZV9mZCk7CisgICAgICAgICAgZmNsb3NlKG91dGZpbGVfZmQpOworICAgICAgICB9CisgICAgICB9CisgICAgICBicmVhazsKKyAgICBjYXNlIERFQlVHX1NDUkVFTl9PTkxZOgorICAgICAgcHJpbnRmKCIlcyIsIG91dHRleHQpOworICAgICAgYnJlYWs7CisgICAgY2FzZSBERUJVR19GSUxFX09OTFk6CisgICAgICBpZiAoKG91dGZpbGVfZmQgPSBmb3BlbihmaWxlcGF0aCwgImErIikpICE9IG51bGxwdHIpIHsKKyAgICAgICAgZndyaXRlKG91dHRleHQsIHNpemVvZihjaGFyKSwgc3RybGVuKG91dHRleHQpLCBvdXRmaWxlX2ZkKTsKKyAgICAgICAgZmNsb3NlKG91dGZpbGVfZmQpOworICAgICAgfQorICAgICAgYnJlYWs7CisgICAgY2FzZSBERUJVR19TQ1JFRU5fQU5EX0ZJTEU6ICAvLyBCT1RICisgICAgICBwcmludGYoIiVzIiwgb3V0dGV4dCk7CisgICAgICBpZiAoKG91dGZpbGVfZmQgPSBmb3BlbihmaWxlcGF0aCwgImErIikpICE9IG51bGxwdHIpIHsKKyAgICAgICAgZndyaXRlKG91dHRleHQsIHNpemVvZihjaGFyKSwgc3RybGVuKG91dHRleHQpLCBvdXRmaWxlX2ZkKTsKKyAgICAgICAgZmNsb3NlKG91dGZpbGVfZmQpOworICAgICAgfQorICAgICAgYnJlYWs7CisgIH0KK30KKworLyoqCisgKiBAYnJpZWYgTm9ybWFsaXplcyBhIHZhbHVlIGluIGEgcmFuZ2UsIHVzZWQgZm9yIGRyaXZlIGlucHV0CisgKiBAcGFyYW0gcG9zaXRpb24gVGhlIHBvc2l0aW9uIGluIHRoZSByYW5nZSwgc3RhcnRpbmcgYXQgMAorICogQHBhcmFtIHJhbmdlIFRoZSBzaXplIG9mIHRoZSByYW5nZSB0aGF0IHBvc2l0aW9uIGlzIGluCisgKiBAcmV0dXJuIFRoZSBub3JtYWxpemVkIHBvc2l0aW9uIGZyb20gLTEgdG8gKzEKKyAqLworZG91YmxlIFJhbmdlVG9Ob3JtYWxpemVkKGRvdWJsZSBwb3NpdGlvbiwgaW50IHJhbmdlKSB7CisgIHJldHVybiAoKChwb3NpdGlvbiAqIDIuMCkgLyAoZG91YmxlKXJhbmdlKSAtIDEuMCk7Cit9CisKKy8qKgorICogQGJyaWVmIENvbnZlcnQgYSBub3JtYWxpemVkIHZhbHVlIHRvIHRoZSBjb3JyZXNwb25kaW5nIHZhbHVlIGluIGEgcmFuZ2UuCisgKiBUaGlzIGlzIHVzZWQgdG8gY29udmVydCBub3JtYWxpemVkIHZhbHVlcyB0byB0aGUgc2Vydm8gY29tbWFuZCByYW5nZS4KKyAqIEBwYXJhbSBub3JtYWxpemVkVmFsdWUgVGhlIG5vcm1hbGl6ZWQgdmFsdWUgKGluIHRoZSAtMSB0byArMSByYW5nZSkKKyAqIEBwYXJhbSBtaW5SYW5nZSBUaGUgbWluaW11bSBvZiB0aGUgcmFuZ2UgKDAgaXMgZGVmYXVsdCkKKyAqIEBwYXJhbSBtYXhSYW5nZSBUaGUgbWF4aW11bSBvZiB0aGUgcmFuZ2UgKDEgaXMgZGVmYXVsdCkKKyAqIEByZXR1cm4gVGhlIHZhbHVlIGluIHRoZSByYW5nZSBjb3JyZXNwb25kaW5nIHRvIHRoZSBpbnB1dCBub3JtYWxpemVkIHZhbHVlCisgKi8KK2Zsb2F0IE5vcm1hbGl6ZVRvUmFuZ2UoZmxvYXQgbm9ybWFsaXplZFZhbHVlLCBmbG9hdCBtaW5SYW5nZSwgZmxvYXQgbWF4UmFuZ2UpIHsKKyAgZmxvYXQgcmFuZ2UgPSBtYXhSYW5nZSAtIG1pblJhbmdlOworICBmbG9hdCB0ZW1wID0gKGZsb2F0KSgobm9ybWFsaXplZFZhbHVlIC8gMi4wKSArIDAuNSkgKiByYW5nZTsKKyAgcmV0dXJuICh0ZW1wICsgbWluUmFuZ2UpOworfQorZmxvYXQgTm9ybWFsaXplVG9SYW5nZShmbG9hdCBub3JtYWxpemVkVmFsdWUpIHsKKyAgcmV0dXJuIChmbG9hdCkoKG5vcm1hbGl6ZWRWYWx1ZSAvIDIuMCkgKyAwLjUpOworfQorCisvKioKKyAqIEBicmllZiBEaXNwbGF5cyBhbiBhY3Rpdml0eSBpbmRpY2F0b3IgdG8gY29uc29sZS4KKyAqIENhbGwgdGhpcyBmdW5jdGlvbiBsaWtlIHlvdSB3b3VsZCBjYWxsIHByaW50Zi4KKyAqIEBwYXJhbSBmbXQgVGhlIGZvcm1hdCBzdHJpbmcKKyovCit2b2lkIFNob3dBY3Rpdml0eShjaGFyICpmbXQsIC4uLikgeworICBzdGF0aWMgY2hhciBhY3Rpdml0eV9pbmRpY2F0aW9uX3N0cmluZ1tdID0gInwvLVxcIjsKKyAgc3RhdGljIGludCBhaSA9IDM7CisgIHZhX2xpc3QgYXJnczsKKyAgY2hhciB0ZXh0WzEwMjRdOworCisgIHZhX3N0YXJ0KGFyZ3MsIGZtdCk7CisKKyAgdnNwcmludGYodGV4dCwgZm10LCBhcmdzKTsKKworICBhaSA9IGFpID09IDMgPyAwIDogYWkgKyAxOworCisgIHByaW50ZigiJWMgJXMgXHIiLCBhY3Rpdml0eV9pbmRpY2F0aW9uX3N0cmluZ1thaV0sIHRleHQpOworICBmZmx1c2goc3Rkb3V0KTsKKworICB2YV9lbmQoYXJncyk7Cit9CisKKyNkZWZpbmUgUEkgMy4xNDE1OTI2NTM1ODk3OQorLyoqCisgKiBAYnJpZWYgQ2FsY3VsYXRlIHNpbmUgd2F2ZSBpbmNyZW1lbnRzICgtMS4wIHRvIDEuMCkuCisgKiBUaGUgZmlyc3QgdGltZSB0aGlzIGlzIGNhbGxlZCwgaXQgc2V0cyB1cCB0aGUgdGltZSBpbmNyZW1lbnQuIFN1YnNlcXVlbnQKKyAqIGNhbGxzCisgKiB3aWxsIGdpdmUgdmFsdWVzIGFsb25nIHRoZSBzaW5lIHdhdmUgZGVwZW5kaW5nIG9uIGN1cnJlbnQgdGltZS4gSWYgdGhlIHdhdmUKKyAqIGlzCisgKiBzdG9wcGVkIGFuZCByZXN0YXJ0ZWQsIGl0IG11c3QgYmUgcmVpbml0aWFsaXplZCB3aXRoIGEgbmV3ICJmaXJzdCBjYWxsIi4KKyAqCisgKiBAcGFyYW0gcGVyaW9kIGxlbmd0aCBvZiB0aW1lIHRvIGNvbXBsZXRlIGEgY29tcGxldGUgd2F2ZQorICogQHBhcmFtIHNpblN0YXJ0IFdoZXJlIHRvIHN0YXJ0IHRoZSBzaW5lIHdhdmUgKDAuMCA9IDIgcGksIHBpLzIgPSAxLjAsIGV0Yy4pCisgKi8KK2RvdWJsZSBTaW5Qb3NpdGlvbihkb3VibGUgKnBlcmlvZCwgZG91YmxlIHNpblN0YXJ0KSB7CisgIGRvdWJsZSBydG5WYWw7CisgIHN0YXRpYyBkb3VibGUgc2luZVBlcmlvZCA9IDAuMDsKKyAgc3RhdGljIGRvdWJsZSB0aW1lc3RhbXA7CisgIGRvdWJsZSBzaW5Bcmc7CisKKyAgLy8gMXN0IGNhbGwKKyAgaWYgKHBlcmlvZCAhPSBudWxscHRyKSB7CisgICAgc2luZVBlcmlvZCA9ICpwZXJpb2Q7CisgICAgdGltZXN0YW1wID0gR2V0VGltZSgpOworICAgIHJldHVybiAwLjA7CisgIH0KKworICAvLyBNdWx0aXBseWluZyBieSAyKnBpIHRvIHRoZSB0aW1lIGRpZmZlcmVuY2UgbWFrZXMgc2luZVBlcmlvZCB3b3JrIGlmIGl0J3MKKyAgLy8gbWVhc3VyZWQgaW4gc2Vjb25kcy4KKyAgLy8gQWRkaW5nIHNpblN0YXJ0IHRvIHRoZSBwYXJ0IG11bHRpcGxpZWQgYnkgUEksIGJ1dCBub3QgYnkgMiwgYWxsb3dzIGl0IHRvCisgIC8vIHdvcmsgYXMgZGVzY3JpYmVkIGluIHRoZSBjb21tZW50cy4KKyAgc2luQXJnID0gUEkgKiAoKDIuMCAqIChHZXRUaW1lKCkgLSB0aW1lc3RhbXApKSArIHNpblN0YXJ0KSAvIHNpbmVQZXJpb2Q7CisgIHJ0blZhbCA9IHNpbihzaW5BcmcpOworICByZXR1cm4gKHJ0blZhbCk7Cit9CisKKy8qKgorICogQGJyaWVmIEZpbmQgdGhlIGVsYXBzZWQgdGltZSBzaW5jZSBhIHNwZWNpZmllZCB0aW1lLgorICogQHBhcmFtIHN0YXJ0VGltZSBUaGUgc3RhcnRpbmcgdGltZQorICogQHJldHVybiBIb3cgbG9uZyBpdCBoYXMgYmVlbiBzaW5jZSB0aGUgc3RhcnRpbmcgdGltZQorICovCitkb3VibGUgRWxhcHNlZFRpbWUoZG91YmxlIHN0YXJ0VGltZSkgeworICBkb3VibGUgcmVhbFRpbWUgPSBHZXRUaW1lKCk7CisgIHJldHVybiAocmVhbFRpbWUgLSBzdGFydFRpbWUpOworfQorCisvKioKKyAqIEBicmllZiBJbml0aWFsaXplIHBhbiBwYXJhbWV0ZXJzCisgKiBAcGFyYW0gcGVyaW9kIFRoZSBudW1iZXIgb2Ygc2Vjb25kcyB0byBjb21wbGV0ZSBvbmUgcGFuCisgKi8KK3ZvaWQgcGFuSW5pdCgpIHsKKyAgZG91YmxlIHBlcmlvZCA9IDMuMDsgICAgICAgIC8vIG51bWJlciBvZiBzZWNvbmRzIGZvciBvbmUgY29tcGxldGUgcGFuCisgIFNpblBvc2l0aW9uKCZwZXJpb2QsIDAuMCk7ICAvLyBpbml0aWFsIGNhbGwgdG8gc2V0IHVwIHRpbWUKK30KKwordm9pZCBwYW5Jbml0KGRvdWJsZSBwZXJpb2QpIHsKKyAgaWYgKHBlcmlvZCA8IDAuMCkgcGVyaW9kID0gMy4wOworICBTaW5Qb3NpdGlvbigmcGVyaW9kLCAwLjApOyAgLy8gaW5pdGlhbCBjYWxsIHRvIHNldCB1cCB0aW1lCit9CisKKy8qKgorICogQGJyaWVmIE1vdmUgdGhlIGhvcml6b250YWwgc2Vydm8gYmFjayBhbmQgZm9ydGguCisgKiBAcGFyYW0gcGFuU2Vydm8gVGhlIHNlcnZvIG9iamVjdCB0byBtb3ZlCisgKiBAcGFyYW0gc2luU3RhcnQgVGhlIHBvc2l0aW9uIG9uIHRoZSBzaW5lIHdhdmUgdG8gYmVnaW4gdGhlIHBhbgorICovCit2b2lkIHBhbkZvclRhcmdldChTZXJ2byAqcGFuU2Vydm8pIHsgcGFuRm9yVGFyZ2V0KHBhblNlcnZvLCAwLjApOyB9CisKK3ZvaWQgcGFuRm9yVGFyZ2V0KFNlcnZvICpwYW5TZXJ2bywgZG91YmxlIHNpblN0YXJ0KSB7CisgIGZsb2F0IG5vcm1hbGl6ZWRTaW5Qb3NpdGlvbiA9IChmbG9hdClTaW5Qb3NpdGlvbihudWxscHRyLCBzaW5TdGFydCk7CisgIGZsb2F0IG5ld1NlcnZvUG9zaXRpb24gPSBOb3JtYWxpemVUb1JhbmdlKG5vcm1hbGl6ZWRTaW5Qb3NpdGlvbik7CisgIHBhblNlcnZvLT5TZXQobmV3U2Vydm9Qb3NpdGlvbik7CisgIC8vIFNob3dBY3Rpdml0eSAoInBhbiB4OiBub3JtYWxpemVkICVmIG5ld1NlcnZvUG9zaXRpb24gPSAlZiIgLAorICAvLwkJbm9ybWFsaXplZFNpblBvc2l0aW9uLCBuZXdTZXJ2b1Bvc2l0aW9uICk7Cit9CisKKy8qKiBAYnJpZWYgUmVhZCBhIGZpbGUgYW5kIHJldHVybiBub24tY29tbWVudCBvdXRwdXQgc3RyaW5nCisKK0NhbGwgdGhlIGZpcnN0IHRpbWUgd2l0aCAwIGxpbmVOdW1iZXIgdG8gZ2V0IHRoZSBudW1iZXIgb2YgbGluZXMgdG8gcmVhZAorVGhlbiBjYWxsIHdpdGggZWFjaCBsaW5lTnVtYmVyIHRvIGdldCBvbmUgY2FtZXJhIHBhcmFtZXRlci4gVGhlcmUgc2hvdWxkCitiZSBvbmUgcHJvcGVydHk9dmFsdWUgZW50cnkgb24gZWFjaCBsaW5lLCBpLmUuICJleHBvc3VyZT1hdXRvIgorCisgKiBAcGFyYW0gaW5wdXRGaWxlIGZpbGVuYW1lIHRvIHJlYWQKKyAqIEBwYXJhbSBvdXRwdXRTdHJpbmcgb25lIHN0cmluZworICogQHBhcmFtIGxpbmVOdW1iZXIgaWYgMCwgcmV0dXJuIG51bWJlciBvZiBsaW5lczsgZWxzZSByZXR1cm4gdGhhdCBsaW5lIG51bWJlcgorICogQHJldHVybiBpbnQgbnVtYmVyIG9mIGxpbmVzIG9yIC0xIGlmIGVycm9yCisgKiovCitpbnQgcHJvY2Vzc0ZpbGUoY2hhciAqaW5wdXRGaWxlLCBjaGFyICpvdXRwdXRTdHJpbmcsIGludCBsaW5lTnVtYmVyKSB7CisgIEZJTEUgKmluZmlsZTsKKyAgY29uc3QgaW50IHN0cmluZ1NpemUgPSA4MDsgIC8vIG1heCBzaXplIG9mIG9uZSBsaW5lIGluIGZpbGUKKyAgY2hhciBpbnB1dFN0cltzdHJpbmdTaXplXTsKKyAgaW5wdXRTdHJbMF0gPSAnXDAnOworICBpbnQgbGluZUNvdW50ID0gMDsKKworICBpZiAobGluZU51bWJlciA8IDApIHJldHVybiAoLTEpOworCisgIGlmICgoaW5maWxlID0gZm9wZW4oaW5wdXRGaWxlLCAiciIpKSA9PSBudWxscHRyKSB7CisgICAgcHJpbnRmKCJGYXRhbCBlcnJvciBvcGVuaW5nIGZpbGUgJXNcbiIsIGlucHV0RmlsZSk7CisgICAgcmV0dXJuICgwKTsKKyAgfQorCisgIHdoaWxlICghZmVvZihpbmZpbGUpKSB7CisgICAgaWYgKGZnZXRzKGlucHV0U3RyLCBzdHJpbmdTaXplLCBpbmZpbGUpICE9IG51bGxwdHIpIHsKKyAgICAgIC8vIFNraXAgZW1wdHkgbGluZXMKKyAgICAgIGlmIChlbXB0eVN0cmluZyhpbnB1dFN0cikpIGNvbnRpbnVlOworICAgICAgLy8gU2tpcCBjb21tZW50IGxpbmVzCisgICAgICBpZiAoaW5wdXRTdHJbMF0gPT0gJyMnIHx8IGlucHV0U3RyWzBdID09ICchJykgY29udGludWU7CisKKyAgICAgIGxpbmVDb3VudCsrOworICAgICAgaWYgKGxpbmVOdW1iZXIgPT0gMCkKKyAgICAgICAgY29udGludWU7CisgICAgICBlbHNlIHsKKyAgICAgICAgaWYgKGxpbmVDb3VudCA9PSBsaW5lTnVtYmVyKSBicmVhazsKKyAgICAgIH0KKyAgICB9CisgIH0KKworICAvLyBjbG9zZSBmaWxlCisgIGZjbG9zZShpbmZpbGUpOworICAvLyBpZiBudW1iZXIgbGluZXMgcmVxdWVzdGVkIHJldHVybiB0aGUgY291bnQKKyAgaWYgKGxpbmVOdW1iZXIgPT0gMCkgcmV0dXJuIChsaW5lQ291bnQpOworICAvLyBjaGVjayBmb3IgaW5wdXQgb3V0IG9mIHJhbmdlCisgIGlmIChsaW5lTnVtYmVyID4gbGluZUNvdW50KSByZXR1cm4gKC0xKTsKKyAgLy8gcmV0dXJuIHRoZSBsaW5lIHNlbGVjdGVkOyBsaW5lQ291bnQgZ3VhcmFudGVlZCB0byBiZSBncmVhdGVyIHRoYW4gemVybworICBzdHJpcFN0cmluZyhpbnB1dFN0cik7CisgIHN0cmNweShvdXRwdXRTdHJpbmcsIGlucHV0U3RyKTsKKyAgcmV0dXJuIChsaW5lQ291bnQpOworfQorCisvKiogSWdub3JlIGVtcHR5IHN0cmluZworICogQHBhcmFtIHN0cmluZyB0byBjaGVjayBpZiBlbXB0eQorICoqLworaW50IGVtcHR5U3RyaW5nKGNoYXIgKnN0cmluZykgeworICBpbnQgaSwgbGVuOworCisgIGlmIChzdHJpbmcgPT0gbnVsbHB0cikgcmV0dXJuICgxKTsKKworICBsZW4gPSBzdHJsZW4oc3RyaW5nKTsKKyAgZm9yIChpID0gMDsgaSA8IGxlbjsgaSsrKSB7CisgICAgLy8gSWdub3JlIHRoZSBmb2xsb3dpbmcgY2hhcmFjdGVycworICAgIGlmIChzdHJpbmdbaV0gPT0gJ1xuJyB8fCBzdHJpbmdbaV0gPT0gJ1xyJyB8fCBzdHJpbmdbaV0gPT0gJ1x0JyB8fAorICAgICAgICBzdHJpbmdbaV0gPT0gJyAnKQorICAgICAgY29udGludWU7CisgICAgcmV0dXJuICgwKTsKKyAgfQorICByZXR1cm4gKDEpOworfQorCisvKiogUmVtb3ZlIHNwZWNpYWwgY2hhcmFjdGVycyBmcm9tIHN0cmluZworICogQHBhcmFtIHN0cmluZyB0byBwcm9jZXNzCisgKiovCit2b2lkIHN0cmlwU3RyaW5nKGNoYXIgKnN0cmluZykgeworICBpbnQgaSwgaiwgbGVuOworCisgIGlmIChzdHJpbmcgPT0gbnVsbHB0cikgcmV0dXJuOworCisgIGxlbiA9IHN0cmxlbihzdHJpbmcpOworICBmb3IgKGkgPSAwLCBqID0gMDsgaSA8IGxlbjsgaSsrKSB7CisgICAgLy8gUmVtb3ZlIHRoZSBmb2xsb3dpbmcgY2hhcmFjdGVycyBmcm9tIHRoZSBzdHJpbmcKKyAgICBpZiAoc3RyaW5nW2ldID09ICdcbicgfHwgc3RyaW5nW2ldID09ICdccicgfHwgc3RyaW5nW2ldID09ICdcIicpIGNvbnRpbnVlOworICAgIC8vIENvcHkgYW55dGhpbmcgZWxzZQorICAgIHN0cmluZ1tqKytdID0gc3RyaW5nW2ldOworICB9CisgIHN0cmluZ1tqXSA9ICdcMCc7Cit9CmRpZmYgLS1naXQgYS93cGlsaWJjL0F0aGVuYS9zcmMvVmlzaW9uL0JpbmFyeUltYWdlLmNwcCBiL3dwaWxpYmMvQXRoZW5hL3NyYy9WaXNpb24vQmluYXJ5SW1hZ2UuY3BwCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmVhMTRjYmMKLS0tIC9kZXYvbnVsbAorKysgYi93cGlsaWJjL0F0aGVuYS9zcmMvVmlzaW9uL0JpbmFyeUltYWdlLmNwcApAQCAtMCwwICsxLDIyOCBAQAorLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi8KKy8qIENvcHlyaWdodCAoYykgRklSU1QgMjAxNC4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KKyAqLworLyogT3BlbiBTb3VyY2UgU29mdHdhcmUgLSBtYXkgYmUgbW9kaWZpZWQgYW5kIHNoYXJlZCBieSBGUkMgdGVhbXMuIFRoZSBjb2RlICAgKi8KKy8qIG11c3QgYmUgYWNjb21wYW5pZWQgYnkgdGhlIEZJUlNUIEJTRCBsaWNlbnNlIGZpbGUgaW4gJChXSU5EX0JBU0UpL1dQSUxpYi4gICovCisvKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qLworCisjaW5jbHVkZSAiVmlzaW9uL0JpbmFyeUltYWdlLmgiCisjaW5jbHVkZSAiV1BJRXJyb3JzLmgiCisjaW5jbHVkZSA8Y3N0cmluZz4KKwordXNpbmcgbmFtZXNwYWNlIHN0ZDsKKworLyoqCisgKiBHZXQgdGhlbiBudW1iZXIgb2YgcGFydGljbGVzIGZvciB0aGUgaW1hZ2UuCisgKiBAcmV0dXJucyB0aGUgbnVtYmVyIG9mIHBhcnRpY2xlcyBmb3VuZCBmb3IgdGhlIGltYWdlLgorICovCitpbnQgQmluYXJ5SW1hZ2U6OkdldE51bWJlclBhcnRpY2xlcygpIHsKKyAgaW50IG51bVBhcnRpY2xlcyA9IDA7CisgIGludCBzdWNjZXNzID0gaW1hcUNvdW50UGFydGljbGVzKG1faW1hcUltYWdlLCAxLCAmbnVtUGFydGljbGVzKTsKKyAgd3BpX3NldEltYXFFcnJvcldpdGhDb250ZXh0KHN1Y2Nlc3MsICJFcnJvciBjb3VudGluZyBwYXJ0aWNsZXMiKTsKKyAgcmV0dXJuIG51bVBhcnRpY2xlczsKK30KKworLyoqCisgKiBHZXQgYSBzaW5nbGUgcGFydGljbGUgYW5hbHlzaXMgcmVwb3J0LgorICogR2V0IG9uZSAob2YgcG9zc2libHkgbWFueSkgcGFydGljbGUgYW5hbHlzaXMgcmVwb3J0cyBmb3IgYW4gaW1hZ2UuCisgKiBAcGFyYW0gcGFydGljbGVOdW1iZXIgV2hpY2ggcGFydGljbGUgYW5hbHlzaXMgcmVwb3J0IHRvIHJldHVybi4KKyAqIEByZXR1cm5zIHRoZSBzZWxlY3RlZCBwYXJ0aWNsZSBhbmFseXNpcyByZXBvcnQKKyAqLworUGFydGljbGVBbmFseXNpc1JlcG9ydCBCaW5hcnlJbWFnZTo6R2V0UGFydGljbGVBbmFseXNpc1JlcG9ydCgKKyAgICBpbnQgcGFydGljbGVOdW1iZXIpIHsKKyAgUGFydGljbGVBbmFseXNpc1JlcG9ydCBwYXI7CisgIEdldFBhcnRpY2xlQW5hbHlzaXNSZXBvcnQocGFydGljbGVOdW1iZXIsICZwYXIpOworICByZXR1cm4gcGFyOworfQorCisvKioKKyAqIEdldCBhIHNpbmdsZSBwYXJ0aWNsZSBhbmFseXNpcyByZXBvcnQuCisgKiBHZXQgb25lIChvZiBwb3NzaWJseSBtYW55KSBwYXJ0aWNsZSBhbmFseXNpcyByZXBvcnRzIGZvciBhbiBpbWFnZS4KKyAqIFRoaXMgdmVyc2lvbiBjb3VsZCBiZSBtb3JlIGVmZmljaWVudCB3aGVuIGNvcHlpbmcgbWFueSByZXBvcnRzLgorICogQHBhcmFtIHBhcnRpY2xlTnVtYmVyIFdoaWNoIHBhcnRpY2xlIGFuYWx5c2lzIHJlcG9ydCB0byByZXR1cm4uCisgKiBAcGFyYW0gcGFyIHRoZSBzZWxlY3RlZCBwYXJ0aWNsZSBhbmFseXNpcyByZXBvcnQKKyAqLwordm9pZCBCaW5hcnlJbWFnZTo6R2V0UGFydGljbGVBbmFseXNpc1JlcG9ydChpbnQgcGFydGljbGVOdW1iZXIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFBhcnRpY2xlQW5hbHlzaXNSZXBvcnQgKnBhcikgeworICBpbnQgc3VjY2VzczsKKyAgaW50IG51bVBhcnRpY2xlcyA9IDA7CisKKyAgc3VjY2VzcyA9IGltYXFHZXRJbWFnZVNpemUobV9pbWFxSW1hZ2UsICZwYXItPmltYWdlV2lkdGgsICZwYXItPmltYWdlSGVpZ2h0KTsKKyAgd3BpX3NldEltYXFFcnJvcldpdGhDb250ZXh0KHN1Y2Nlc3MsICJFcnJvciBnZXR0aW5nIGltYWdlIHNpemUiKTsKKyAgaWYgKFN0YXR1c0lzRmF0YWwoKSkgcmV0dXJuOworCisgIHN1Y2Nlc3MgPSBpbWFxQ291bnRQYXJ0aWNsZXMobV9pbWFxSW1hZ2UsIDEsICZudW1QYXJ0aWNsZXMpOworICB3cGlfc2V0SW1hcUVycm9yV2l0aENvbnRleHQoc3VjY2VzcywgIkVycm9yIGNvdW50aW5nIHBhcnRpY2xlcyIpOworICBpZiAoU3RhdHVzSXNGYXRhbCgpKSByZXR1cm47CisKKyAgaWYgKHBhcnRpY2xlTnVtYmVyID49IG51bVBhcnRpY2xlcykgeworICAgIHdwaV9zZXRXUElFcnJvcldpdGhDb250ZXh0KFBhcmFtZXRlck91dE9mUmFuZ2UsICJwYXJ0aWNsZU51bWJlciIpOworICAgIHJldHVybjsKKyAgfQorCisgIHBhci0+cGFydGljbGVJbmRleCA9IHBhcnRpY2xlTnVtYmVyOworICAvLyBEb24ndCBib3RoZXIgbWVhc3VyaW5nIHRoZSByZXN0IG9mIHRoZSBwYXJ0aWNsZSBpZiBvbmUgZmFpbHMKKyAgYm9vbCBnb29kID0gUGFydGljbGVNZWFzdXJlbWVudChwYXJ0aWNsZU51bWJlciwgSU1BUV9NVF9DRU5URVJfT0ZfTUFTU19YLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICZwYXItPmNlbnRlcl9tYXNzX3gpOworICBnb29kID0gZ29vZCAmJiBQYXJ0aWNsZU1lYXN1cmVtZW50KHBhcnRpY2xlTnVtYmVyLCBJTUFRX01UX0NFTlRFUl9PRl9NQVNTX1ksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJnBhci0+Y2VudGVyX21hc3NfeSk7CisgIGdvb2QgPSBnb29kICYmCisgICAgICAgICBQYXJ0aWNsZU1lYXN1cmVtZW50KHBhcnRpY2xlTnVtYmVyLCBJTUFRX01UX0FSRUEsICZwYXItPnBhcnRpY2xlQXJlYSk7CisgIGdvb2QgPSBnb29kICYmIFBhcnRpY2xlTWVhc3VyZW1lbnQocGFydGljbGVOdW1iZXIsIElNQVFfTVRfQk9VTkRJTkdfUkVDVF9UT1AsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJnBhci0+Ym91bmRpbmdSZWN0LnRvcCk7CisgIGdvb2QgPSBnb29kICYmIFBhcnRpY2xlTWVhc3VyZW1lbnQocGFydGljbGVOdW1iZXIsIElNQVFfTVRfQk9VTkRJTkdfUkVDVF9MRUZULAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICZwYXItPmJvdW5kaW5nUmVjdC5sZWZ0KTsKKyAgZ29vZCA9CisgICAgICBnb29kICYmIFBhcnRpY2xlTWVhc3VyZW1lbnQocGFydGljbGVOdW1iZXIsIElNQVFfTVRfQk9VTkRJTkdfUkVDVF9IRUlHSFQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJnBhci0+Ym91bmRpbmdSZWN0LmhlaWdodCk7CisgIGdvb2QgPQorICAgICAgZ29vZCAmJiBQYXJ0aWNsZU1lYXN1cmVtZW50KHBhcnRpY2xlTnVtYmVyLCBJTUFRX01UX0JPVU5ESU5HX1JFQ1RfV0lEVEgsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJnBhci0+Ym91bmRpbmdSZWN0LndpZHRoKTsKKyAgZ29vZCA9IGdvb2QgJiYgUGFydGljbGVNZWFzdXJlbWVudChwYXJ0aWNsZU51bWJlciwgSU1BUV9NVF9BUkVBX0JZX0lNQUdFX0FSRUEsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJnBhci0+cGFydGljbGVUb0ltYWdlUGVyY2VudCk7CisgIGdvb2QgPSBnb29kICYmIFBhcnRpY2xlTWVhc3VyZW1lbnQocGFydGljbGVOdW1iZXIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSU1BUV9NVF9BUkVBX0JZX1BBUlRJQ0xFX0FORF9IT0xFU19BUkVBLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICZwYXItPnBhcnRpY2xlUXVhbGl0eSk7CisKKyAgaWYgKGdvb2QpIHsKKyAgICAvKiBub3JtYWxpemVkIHBvc2l0aW9uICgtMSB0byAxKSAqLworICAgIHBhci0+Y2VudGVyX21hc3NfeF9ub3JtYWxpemVkID0KKyAgICAgICAgTm9ybWFsaXplRnJvbVJhbmdlKHBhci0+Y2VudGVyX21hc3NfeCwgcGFyLT5pbWFnZVdpZHRoKTsKKyAgICBwYXItPmNlbnRlcl9tYXNzX3lfbm9ybWFsaXplZCA9CisgICAgICAgIE5vcm1hbGl6ZUZyb21SYW5nZShwYXItPmNlbnRlcl9tYXNzX3ksIHBhci0+aW1hZ2VIZWlnaHQpOworICB9Cit9CisKKy8qKgorICogR2V0IGFuIG9yZGVyZWQgdmVjdG9yIG9mIHBhcnRpY2xlcyBmb3IgdGhlIGltYWdlLgorICogQ3JlYXRlIGEgdmVjdG9yIG9mIHBhcnRpY2xlIGFuYWx5c2lzIHJlcG9ydHMgc29ydGVkIGJ5IHNpemUgZm9yIGFuIGltYWdlLgorICogVGhlIHZlY3RvciBjb250YWlucyB0aGUgYWN0dWFsIHJlcG9ydCBzdHJ1Y3R1cmVzLgorICogQHJldHVybnMgYSBwb2ludGVyIHRvIHRoZSB2ZWN0b3Igb2YgcGFydGljbGUgYW5hbHlzaXMgcmVwb3J0cy4gVGhlIGNhbGxlcgorICogbXVzdCBkZWxldGUgdGhlCisgKiB2ZWN0b3Igd2hlbiBmaW5pc2hlZCB1c2luZyBpdC4KKyAqLwordmVjdG9yPFBhcnRpY2xlQW5hbHlzaXNSZXBvcnQ+ICoKK0JpbmFyeUltYWdlOjpHZXRPcmRlcmVkUGFydGljbGVBbmFseXNpc1JlcG9ydHMoKSB7CisgIGF1dG8gcGFydGljbGVzID0gbmV3IHZlY3RvcjxQYXJ0aWNsZUFuYWx5c2lzUmVwb3J0PjsKKyAgaW50IHBhcnRpY2xlQ291bnQgPSBHZXROdW1iZXJQYXJ0aWNsZXMoKTsKKyAgZm9yIChpbnQgcGFydGljbGVJbmRleCA9IDA7IHBhcnRpY2xlSW5kZXggPCBwYXJ0aWNsZUNvdW50OyBwYXJ0aWNsZUluZGV4KyspIHsKKyAgICBwYXJ0aWNsZXMtPnB1c2hfYmFjayhHZXRQYXJ0aWNsZUFuYWx5c2lzUmVwb3J0KHBhcnRpY2xlSW5kZXgpKTsKKyAgfQorICAvLyBUT0RPOiBUaGlzIGlzIHByZXR0eSBpbmVmZmljaWVudCBzaW5jZSBlYWNoIGNvbXBhcmUgaW4gdGhlIHNvcnQgY29waWVzCisgIC8vICAgYm90aCByZXBvcnRzIGJlaW5nIGNvbXBhcmVkLi4uIGRvIGl0IG1hbnVhbGx5IGluc3RlYWQuLi4gd2hpbGUgd2UncmUKKyAgLy8gICBhdCBpdCwgd2Ugc2hvdWxkIHByb3ZpZGUgYSB2ZXJzaW9uIHRoYXQgYWxsb3dzIGEgcHJlYWxsb2NhdGVkIGJ1ZmZlciBvZgorICAvLyAgIFBhcnRpY2xlQW5hbHlzaXNSZXBvcnQgc3RydWN0dXJlcworICBzb3J0KHBhcnRpY2xlcy0+YmVnaW4oKSwgcGFydGljbGVzLT5lbmQoKSwgQ29tcGFyZVBhcnRpY2xlU2l6ZXMpOworICByZXR1cm4gcGFydGljbGVzOworfQorCisvKioKKyAqIFdyaXRlIGEgYmluYXJ5IGltYWdlIHRvIGZsYXNoLgorICogV3JpdGVzIHRoZSBiaW5hcnkgaW1hZ2UgdG8gZmxhc2ggb24gdGhlIGNSSU8gZm9yIGxhdGVyIGluc3BlY3Rpb24uCisgKiBAcGFyYW0gZmlsZU5hbWUgdGhlIG5hbWUgb2YgdGhlIGltYWdlIGZpbGUgd3JpdHRlbiB0byB0aGUgZmxhc2guCisgKi8KK3ZvaWQgQmluYXJ5SW1hZ2U6OldyaXRlKGNvbnN0IGNoYXIgKmZpbGVOYW1lKSB7CisgIFJHQlZhbHVlIGNvbG9yVGFibGVbMjU2XTsKKyAgbWVtc2V0KGNvbG9yVGFibGUsIDAsIHNpemVvZihjb2xvclRhYmxlKSk7CisgIGNvbG9yVGFibGVbMF0uUiA9IDA7CisgIGNvbG9yVGFibGVbMV0uUiA9IDI1NTsKKyAgY29sb3JUYWJsZVswXS5HID0gY29sb3JUYWJsZVsxXS5HID0gMDsKKyAgY29sb3JUYWJsZVswXS5CID0gY29sb3JUYWJsZVsxXS5CID0gMDsKKyAgY29sb3JUYWJsZVswXS5hbHBoYSA9IGNvbG9yVGFibGVbMV0uYWxwaGEgPSAwOworICBpbWFxV3JpdGVGaWxlKG1faW1hcUltYWdlLCBmaWxlTmFtZSwgY29sb3JUYWJsZSk7Cit9CisKKy8qKgorICogTWVhc3VyZSBhIHNpbmdsZSBwYXJhbWV0ZXIgZm9yIGFuIGltYWdlLgorICogR2V0IHRoZSBtZWFzdXJlbWVudCBmb3IgYSBzaW5nbGUgcGFyYW1ldGVyIGFib3V0IGFuIGltYWdlIGJ5IGNhbGxpbmcgdGhlCisgKiBpbWFxTWVhc3VyZVBhcnRpY2xlCisgKiBmdW5jdGlvbiBmb3IgdGhlIHNlbGVjdGVkIHBhcmFtZXRlci4KKyAqIEBwYXJhbSBwYXJ0aWNsZU51bWJlciB3aGljaCBwYXJ0aWNsZSBpbiB0aGUgc2V0IG9mIHBhcnRpY2xlcworICogQHBhcmFtIHdoYXRUb01lYXN1cmUgdGhlIGltYXEgTWVhc3VyZW1lbnRUeXBlICh3aGF0IHRvIG1lYXN1cmUpCisgKiBAcGFyYW0gcmVzdWx0IHRoZSB2YWx1ZSBvZiB0aGUgbWVhc3VyZW1lbnQKKyAqIEByZXR1cm5zIGZhbHNlIG9uIGZhaWx1cmUsIHRydWUgb24gc3VjY2VzcworICovCitib29sIEJpbmFyeUltYWdlOjpQYXJ0aWNsZU1lYXN1cmVtZW50KGludCBwYXJ0aWNsZU51bWJlciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTWVhc3VyZW1lbnRUeXBlIHdoYXRUb01lYXN1cmUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludCAqcmVzdWx0KSB7CisgIGRvdWJsZSByZXN1bHREb3VibGU7CisgIGJvb2wgc3VjY2VzcyA9CisgICAgICBQYXJ0aWNsZU1lYXN1cmVtZW50KHBhcnRpY2xlTnVtYmVyLCB3aGF0VG9NZWFzdXJlLCAmcmVzdWx0RG91YmxlKTsKKyAgKnJlc3VsdCA9IChpbnQpcmVzdWx0RG91YmxlOworICByZXR1cm4gc3VjY2VzczsKK30KKworLyoqCisgKiBNZWFzdXJlIGEgc2luZ2xlIHBhcmFtZXRlciBmb3IgYW4gaW1hZ2UuCisgKiBHZXQgdGhlIG1lYXN1cmVtZW50IGZvciBhIHNpbmdsZSBwYXJhbWV0ZXIgYWJvdXQgYW4gaW1hZ2UgYnkgY2FsbGluZyB0aGUKKyAqIGltYXFNZWFzdXJlUGFydGljbGUKKyAqIGZ1bmN0aW9uIGZvciB0aGUgc2VsZWN0ZWQgcGFyYW1ldGVyLgorICogQHBhcmFtIHBhcnRpY2xlTnVtYmVyIHdoaWNoIHBhcnRpY2xlIGluIHRoZSBzZXQgb2YgcGFydGljbGVzCisgKiBAcGFyYW0gd2hhdFRvTWVhc3VyZSB0aGUgaW1hcSBNZWFzdXJlbWVudFR5cGUgKHdoYXQgdG8gbWVhc3VyZSkKKyAqIEBwYXJhbSByZXN1bHQgdGhlIHZhbHVlIG9mIHRoZSBtZWFzdXJlbWVudAorICogQHJldHVybnMgdHJ1ZSBvbiBmYWlsdXJlLCBmYWxzZSBvbiBzdWNjZXNzCisgKi8KK2Jvb2wgQmluYXJ5SW1hZ2U6OlBhcnRpY2xlTWVhc3VyZW1lbnQoaW50IHBhcnRpY2xlTnVtYmVyLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBNZWFzdXJlbWVudFR5cGUgd2hhdFRvTWVhc3VyZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZG91YmxlICpyZXN1bHQpIHsKKyAgaW50IHN1Y2Nlc3M7CisgIHN1Y2Nlc3MgPSBpbWFxTWVhc3VyZVBhcnRpY2xlKG1faW1hcUltYWdlLCBwYXJ0aWNsZU51bWJlciwgMCwgd2hhdFRvTWVhc3VyZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVzdWx0KTsKKyAgd3BpX3NldEltYXFFcnJvcldpdGhDb250ZXh0KHN1Y2Nlc3MsICJFcnJvciBtZWFzdXJpbmcgcGFydGljbGUiKTsKKyAgcmV0dXJuICFTdGF0dXNJc0ZhdGFsKCk7Cit9CisKKy8vIE5vcm1hbGl6ZXMgdG8gWy0xLDFdCitkb3VibGUgQmluYXJ5SW1hZ2U6Ok5vcm1hbGl6ZUZyb21SYW5nZShkb3VibGUgcG9zaXRpb24sIGludCByYW5nZSkgeworICByZXR1cm4gKHBvc2l0aW9uICogMi4wIC8gKGRvdWJsZSlyYW5nZSkgLSAxLjA7Cit9CisKKy8qKgorICogVGhlIGNvbXBhcmUgaGVscGVyIGZ1bmN0aW9uIGZvciBzb3J0LgorICogVGhpcyBmdW5jdGlvbiBjb21wYXJlcyB0d28gcGFydGljbGUgYW5hbHlzaXMgcmVwb3J0cyBhcyBhIGhlbHBlciBmb3IgdGhlIHNvcnQKKyAqIGZ1bmN0aW9uLgorICogQHBhcmFtIHBhcnRpY2xlMSBUaGUgZmlyc3QgcGFydGljbGUgdG8gY29tcGFyZQorICogQHBhcmFtIHBhcnRpY2xlMiB0aGUgc2Vjb25kIHBhcnRpY2xlIHRvIGNvbXBhcmUKKyAqIEByZXR1cm5zIHRydWUgaWYgcGFydGljbGUxIGlzIGdyZWF0ZXIgdGhhbiBwYXJ0aWNsZTIKKyAqLworYm9vbCBCaW5hcnlJbWFnZTo6Q29tcGFyZVBhcnRpY2xlU2l6ZXMoUGFydGljbGVBbmFseXNpc1JlcG9ydCBwYXJ0aWNsZTEsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBQYXJ0aWNsZUFuYWx5c2lzUmVwb3J0IHBhcnRpY2xlMikgeworICAvLyB3ZSB3YW50IGRlc2NlbmRpbmcgc29ydCBvcmRlcgorICByZXR1cm4gcGFydGljbGUxLnBhcnRpY2xlVG9JbWFnZVBlcmNlbnQgPiBwYXJ0aWNsZTIucGFydGljbGVUb0ltYWdlUGVyY2VudDsKK30KKworQmluYXJ5SW1hZ2UgKkJpbmFyeUltYWdlOjpSZW1vdmVTbWFsbE9iamVjdHMoYm9vbCBjb25uZWN0aXZpdHk4LCBpbnQgZXJvc2lvbnMpIHsKKyAgYXV0byByZXN1bHQgPSBuZXcgQmluYXJ5SW1hZ2UoKTsKKyAgaW50IHN1Y2Nlc3MgPSBpbWFxU2l6ZUZpbHRlcihyZXN1bHQtPkdldEltYXFJbWFnZSgpLCBtX2ltYXFJbWFnZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25uZWN0aXZpdHk4LCBlcm9zaW9ucywgSU1BUV9LRUVQX0xBUkdFLCBudWxscHRyKTsKKyAgd3BpX3NldEltYXFFcnJvcldpdGhDb250ZXh0KHN1Y2Nlc3MsICJFcnJvciBpbiBSZW1vdmVTbWFsbE9iamVjdHMiKTsKKyAgcmV0dXJuIHJlc3VsdDsKK30KKworQmluYXJ5SW1hZ2UgKkJpbmFyeUltYWdlOjpSZW1vdmVMYXJnZU9iamVjdHMoYm9vbCBjb25uZWN0aXZpdHk4LCBpbnQgZXJvc2lvbnMpIHsKKyAgYXV0byByZXN1bHQgPSBuZXcgQmluYXJ5SW1hZ2UoKTsKKyAgaW50IHN1Y2Nlc3MgPSBpbWFxU2l6ZUZpbHRlcihyZXN1bHQtPkdldEltYXFJbWFnZSgpLCBtX2ltYXFJbWFnZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25uZWN0aXZpdHk4LCBlcm9zaW9ucywgSU1BUV9LRUVQX1NNQUxMLCBudWxscHRyKTsKKyAgd3BpX3NldEltYXFFcnJvcldpdGhDb250ZXh0KHN1Y2Nlc3MsICJFcnJvciBpbiBSZW1vdmVMYXJnZU9iamVjdHMiKTsKKyAgcmV0dXJuIHJlc3VsdDsKK30KKworQmluYXJ5SW1hZ2UgKkJpbmFyeUltYWdlOjpDb252ZXhIdWxsKGJvb2wgY29ubmVjdGl2aXR5OCkgeworICBhdXRvIHJlc3VsdCA9IG5ldyBCaW5hcnlJbWFnZSgpOworICBpbnQgc3VjY2VzcyA9CisgICAgICBpbWFxQ29udmV4SHVsbChyZXN1bHQtPkdldEltYXFJbWFnZSgpLCBtX2ltYXFJbWFnZSwgY29ubmVjdGl2aXR5OCk7CisgIHdwaV9zZXRJbWFxRXJyb3JXaXRoQ29udGV4dChzdWNjZXNzLCAiRXJyb3IgaW4gY29udmV4IGh1bGwgb3BlcmF0aW9uIik7CisgIHJldHVybiByZXN1bHQ7Cit9CisKK0JpbmFyeUltYWdlICpCaW5hcnlJbWFnZTo6UGFydGljbGVGaWx0ZXIoUGFydGljbGVGaWx0ZXJDcml0ZXJpYTIgKmNyaXRlcmlhLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQgY3JpdGVyaWFDb3VudCkgeworICBhdXRvIHJlc3VsdCA9IG5ldyBCaW5hcnlJbWFnZSgpOworICBpbnQgbnVtUGFydGljbGVzOworICBQYXJ0aWNsZUZpbHRlck9wdGlvbnMyIGZpbHRlck9wdGlvbnMgPSB7MCwgMCwgMCwgMX07CisgIGludCBzdWNjZXNzID0KKyAgICAgIGltYXFQYXJ0aWNsZUZpbHRlcjQocmVzdWx0LT5HZXRJbWFxSW1hZ2UoKSwgbV9pbWFxSW1hZ2UsIGNyaXRlcmlhLAorICAgICAgICAgICAgICAgICAgICAgICAgICBjcml0ZXJpYUNvdW50LCAmZmlsdGVyT3B0aW9ucywgbnVsbHB0ciwgJm51bVBhcnRpY2xlcyk7CisgIHdwaV9zZXRJbWFxRXJyb3JXaXRoQ29udGV4dChzdWNjZXNzLCAiRXJyb3IgaW4gcGFydGljbGUgZmlsdGVyIG9wZXJhdGlvbiIpOworICByZXR1cm4gcmVzdWx0OworfQpkaWZmIC0tZ2l0IGEvd3BpbGliYy9BdGhlbmEvc3JjL1Zpc2lvbi9Db2xvckltYWdlLmNwcCBiL3dwaWxpYmMvQXRoZW5hL3NyYy9WaXNpb24vQ29sb3JJbWFnZS5jcHAKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYmJiYzI0MgotLS0gL2Rldi9udWxsCisrKyBiL3dwaWxpYmMvQXRoZW5hL3NyYy9WaXNpb24vQ29sb3JJbWFnZS5jcHAKQEAgLTAsMCArMSw0NDQgQEAKKy8qLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovCisvKiBDb3B5cmlnaHQgKGMpIEZJUlNUIDIwMTQuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqLworLyogT3BlbiBTb3VyY2UgU29mdHdhcmUgLSBtYXkgYmUgbW9kaWZpZWQgYW5kIHNoYXJlZCBieSBGUkMgdGVhbXMuIFRoZSBjb2RlICAgKi8KKy8qIG11c3QgYmUgYWNjb21wYW5pZWQgYnkgdGhlIEZJUlNUIEJTRCBsaWNlbnNlIGZpbGUgaW4gJChXSU5EX0JBU0UpL1dQSUxpYi4gICovCisvKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qLworCisjaW5jbHVkZSAiVmlzaW9uL0NvbG9ySW1hZ2UuaCIKKworI2luY2x1ZGUgIldQSUVycm9ycy5oIgorCitDb2xvckltYWdlOjpDb2xvckltYWdlKEltYWdlVHlwZSB0eXBlKSA6IEltYWdlQmFzZSh0eXBlKSB7fQorCisvKioKKyAqIFBlcmZvcm0gYSB0aHJlc2hvbGQgb3BlcmF0aW9uIG9uIGEgQ29sb3JJbWFnZS4KKyAqIFBlcmZvcm0gYSB0aHJlc2hvbGQgb3BlcmF0aW9uIG9uIGEgQ29sb3JJbWFnZSB1c2luZyB0aGUgQ29sb3JNb2RlIHN1cHBsaWVkCisgKiBhcyBhIHBhcmFtZXRlci4KKyAqIEBwYXJhbSBjb2xvck1vZGUgVGhlIHR5cGUgb2YgY29sb3JzcGFjZSB0aGlzIG9wZXJhdGlvbiBzaG91bGQgYmUgcGVyZm9ybWVkIGluCisgKiBAcmV0dXJucyBhIHBvaW50ZXIgdG8gYSBiaW5hcnkgaW1hZ2UKKyAqLworQmluYXJ5SW1hZ2UgKkNvbG9ySW1hZ2U6OkNvbXB1dGVUaHJlc2hvbGQoQ29sb3JNb2RlIGNvbG9yTW9kZSwgaW50IGxvdzEsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQgaGlnaDEsIGludCBsb3cyLCBpbnQgaGlnaDIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQgbG93MywgaW50IGhpZ2gzKSB7CisgIGF1dG8gcmVzdWx0ID0gbmV3IEJpbmFyeUltYWdlKCk7CisgIFJhbmdlIHJhbmdlMSA9IHtsb3cxLCBoaWdoMX0sIHJhbmdlMiA9IHtsb3cyLCBoaWdoMn0sIHJhbmdlMyA9IHtsb3czLCBoaWdoM307CisKKyAgaW50IHN1Y2Nlc3MgPSBpbWFxQ29sb3JUaHJlc2hvbGQocmVzdWx0LT5HZXRJbWFxSW1hZ2UoKSwgbV9pbWFxSW1hZ2UsIDEsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbG9yTW9kZSwgJnJhbmdlMSwgJnJhbmdlMiwgJnJhbmdlMyk7CisgIHdwaV9zZXRJbWFxRXJyb3JXaXRoQ29udGV4dChzdWNjZXNzLCAiSW1hcVRocmVzaG9sZCBlcnJvciIpOworICByZXR1cm4gcmVzdWx0OworfQorCisvKioKKyAqIFBlcmZvcm0gYSB0aHJlc2hvbGQgaW4gUkdCIHNwYWNlLgorICogQHBhcmFtIHJlZExvdyBSZWQgbG93IHZhbHVlCisgKiBAcGFyYW0gcmVkSGlnaCBSZWQgaGlnaCB2YWx1ZQorICogQHBhcmFtIGdyZWVuTG93IEdyZWVuIGxvdyB2YWx1ZQorICogQHBhcmFtIGdyZWVuSGlnaCBHcmVlbiBoaWdoIHZhbHVlCisgKiBAcGFyYW0gYmx1ZUxvdyBCbHVlIGxvdyB2YWx1ZQorICogQHBhcmFtIGJsdWVIaWdoIEJsdWUgaGlnaCB2YWx1ZQorICogQHJldHVybnMgQSBwb2ludGVyIHRvIGEgQmluYXJ5SW1hZ2UgdGhhdCByZXByZXNlbnRzIHRoZSByZXN1bHQgb2YgdGhlCisgKiB0aHJlc2hvbGQgb3BlcmF0aW9uLgorICovCitCaW5hcnlJbWFnZSAqQ29sb3JJbWFnZTo6VGhyZXNob2xkUkdCKGludCByZWRMb3csIGludCByZWRIaWdoLCBpbnQgZ3JlZW5Mb3csCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludCBncmVlbkhpZ2gsIGludCBibHVlTG93LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQgYmx1ZUhpZ2gpIHsKKyAgcmV0dXJuIENvbXB1dGVUaHJlc2hvbGQoSU1BUV9SR0IsIHJlZExvdywgcmVkSGlnaCwgZ3JlZW5Mb3csIGdyZWVuSGlnaCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgYmx1ZUxvdywgYmx1ZUhpZ2gpOworfQorCisvKioKKyAqIFBlcmZvcm0gYSB0aHJlc2hvbGQgaW4gUkdCIHNwYWNlLgorICogQHBhcmFtIHRocmVzaG9sZCBhIHJlZmVyZW5jZSB0byB0aGUgVGhyZXNob2xkIG9iamVjdCB0byB1c2UuCisgKiBAcmV0dXJucyBBIHBvaW50ZXIgdG8gYSBCaW5hcnlJbWFnZSB0aGF0IHJlcHJlc2VudHMgdGhlIHJlc3VsdCBvZiB0aGUKKyAqIHRocmVzaG9sZCBvcGVyYXRpb24uCisgKi8KK0JpbmFyeUltYWdlICpDb2xvckltYWdlOjpUaHJlc2hvbGRSR0IoVGhyZXNob2xkICZ0KSB7CisgIHJldHVybiBDb21wdXRlVGhyZXNob2xkKElNQVFfUkdCLCB0LnBsYW5lMUxvdywgdC5wbGFuZTFIaWdoLCB0LnBsYW5lMkxvdywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgdC5wbGFuZTJIaWdoLCB0LnBsYW5lM0xvdywgdC5wbGFuZTNIaWdoKTsKK30KKworLyoqCisgKiBQZXJmb3JtIGEgdGhyZXNob2xkIGluIEhTTCBzcGFjZS4KKyAqIEBwYXJhbSBodWVMb3cgTG93IHZhbHVlIGZvciBodWUKKyAqIEBwYXJhbSBodWVIaWdoIEhpZ2ggdmFsdWUgZm9yIGh1ZQorICogQHBhcmFtIHNhdHVyYXRpb25Mb3cgTG93IHZhbHVlIGZvciBzYXR1cmF0aW9uCisgKiBAcGFyYW0gc2F0dXJhdGlvbkhpZ2ggSGlnaCB2YWx1ZSBmb3Igc2F0dXJhdGlvbgorICogQHBhcmFtIGx1bWluZW5jZUxvdyBMb3cgdmFsdWUgZm9yIGx1bWluZW5jZQorICogQHBhcmFtIGx1bWluZW5jZUhpZ2ggSGlnaCB2YWx1ZSBmb3IgbHVtaW5lbmNlCisgKiBAcmV0dXJucyBhIHBvaW50ZXIgdG8gYSBCaW5hcnlJbWFnZSB0aGF0IHJlcHJlc2VudHMgdGhlIHJlc3VsdCBvZiB0aGUKKyAqIHRocmVzaG9sZCBvcGVyYXRpb24uCisgKi8KK0JpbmFyeUltYWdlICpDb2xvckltYWdlOjpUaHJlc2hvbGRIU0woaW50IGh1ZUxvdywgaW50IGh1ZUhpZ2gsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludCBzYXR1cmF0aW9uTG93LCBpbnQgc2F0dXJhdGlvbkhpZ2gsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludCBsdW1pbmVuY2VMb3csIGludCBsdW1pbmVuY2VIaWdoKSB7CisgIHJldHVybiBDb21wdXRlVGhyZXNob2xkKElNQVFfSFNMLCBodWVMb3csIGh1ZUhpZ2gsIHNhdHVyYXRpb25Mb3csCisgICAgICAgICAgICAgICAgICAgICAgICAgIHNhdHVyYXRpb25IaWdoLCBsdW1pbmVuY2VMb3csIGx1bWluZW5jZUhpZ2gpOworfQorCisvKioKKyAqIFBlcmZvcm0gYSB0aHJlc2hvbGQgaW4gSFNMIHNwYWNlLgorICogQHBhcmFtIHRocmVzaG9sZCBhIHJlZmVyZW5jZSB0byB0aGUgVGhyZXNob2xkIG9iamVjdCB0byB1c2UuCisgKiBAcmV0dXJucyBBIHBvaW50ZXIgdG8gYSBCaW5hcnlJbWFnZSB0aGF0IHJlcHJlc2VudHMgdGhlIHJlc3VsdCBvZiB0aGUKKyAqIHRocmVzaG9sZCBvcGVyYXRpb24uCisgKi8KK0JpbmFyeUltYWdlICpDb2xvckltYWdlOjpUaHJlc2hvbGRIU0woVGhyZXNob2xkICZ0KSB7CisgIHJldHVybiBDb21wdXRlVGhyZXNob2xkKElNQVFfSFNMLCB0LnBsYW5lMUxvdywgdC5wbGFuZTFIaWdoLCB0LnBsYW5lMkxvdywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgdC5wbGFuZTJIaWdoLCB0LnBsYW5lM0xvdywgdC5wbGFuZTNIaWdoKTsKK30KKworLyoqCisgKiBQZXJmb3JtIGEgdGhyZXNob2xkIGluIEhTViBzcGFjZS4KKyAqIEBwYXJhbSBodWVMb3cgTG93IHZhbHVlIGZvciBodWUKKyAqIEBwYXJhbSBodWVIaWdoIEhpZ2ggdmFsdWUgZm9yIGh1ZQorICogQHBhcmFtIHNhdHVyYXRpb25Mb3cgTG93IHZhbHVlIGZvciBzYXR1cmF0aW9uCisgKiBAcGFyYW0gc2F0dXJhdGlvbkhpZ2ggSGlnaCB2YWx1ZSBmb3Igc2F0dXJhdGlvbgorICogQHBhcmFtIHZhbHVlTG93IExvdyB2YWx1ZQorICogQHBhcmFtIHZhbHVlSGlnaCBIaWdoIHZhbHVlCisgKiBAcmV0dXJucyBhIHBvaW50ZXIgdG8gYSBCaW5hcnlJbWFnZSB0aGF0IHJlcHJlc2VudHMgdGhlIHJlc3VsdCBvZiB0aGUKKyAqIHRocmVzaG9sZCBvcGVyYXRpb24uCisgKi8KK0JpbmFyeUltYWdlICpDb2xvckltYWdlOjpUaHJlc2hvbGRIU1YoaW50IGh1ZUxvdywgaW50IGh1ZUhpZ2gsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludCBzYXR1cmF0aW9uTG93LCBpbnQgc2F0dXJhdGlvbkhpZ2gsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludCB2YWx1ZUxvdywgaW50IHZhbHVlSGlnaCkgeworICByZXR1cm4gQ29tcHV0ZVRocmVzaG9sZChJTUFRX0hTViwgaHVlTG93LCBodWVIaWdoLCBzYXR1cmF0aW9uTG93LAorICAgICAgICAgICAgICAgICAgICAgICAgICBzYXR1cmF0aW9uSGlnaCwgdmFsdWVMb3csIHZhbHVlSGlnaCk7Cit9CisKKy8qKgorICogUGVyZm9ybSBhIHRocmVzaG9sZCBpbiBIU1Ygc3BhY2UuCisgKiBAcGFyYW0gdGhyZXNob2xkIGEgcmVmZXJlbmNlIHRvIHRoZSBUaHJlc2hvbGQgb2JqZWN0IHRvIHVzZS4KKyAqIEByZXR1cm5zIEEgcG9pbnRlciB0byBhIEJpbmFyeUltYWdlIHRoYXQgcmVwcmVzZW50cyB0aGUgcmVzdWx0IG9mIHRoZQorICogdGhyZXNob2xkIG9wZXJhdGlvbi4KKyAqLworQmluYXJ5SW1hZ2UgKkNvbG9ySW1hZ2U6OlRocmVzaG9sZEhTVihUaHJlc2hvbGQgJnQpIHsKKyAgcmV0dXJuIENvbXB1dGVUaHJlc2hvbGQoSU1BUV9IU1YsIHQucGxhbmUxTG93LCB0LnBsYW5lMUhpZ2gsIHQucGxhbmUyTG93LAorICAgICAgICAgICAgICAgICAgICAgICAgICB0LnBsYW5lMkhpZ2gsIHQucGxhbmUzTG93LCB0LnBsYW5lM0hpZ2gpOworfQorCisvKioKKyAqIFBlcmZvcm0gYSB0aHJlc2hvbGQgaW4gSFNJIHNwYWNlLgorICogQHBhcmFtIGh1ZUxvdyBMb3cgdmFsdWUgZm9yIGh1ZQorICogQHBhcmFtIGh1ZUhpZ2ggSGlnaCB2YWx1ZSBmb3IgaHVlCisgKiBAcGFyYW0gc2F0dXJhdGlvbkxvdyBMb3cgdmFsdWUgZm9yIHNhdHVyYXRpb24KKyAqIEBwYXJhbSBzYXR1cmF0aW9uSGlnaCBIaWdoIHZhbHVlIGZvciBzYXR1cmF0aW9uCisgKiBAcGFyYW0gdmFsdWVMb3cgTG93IGludGVuc2l0eQorICogQHBhcmFtIHZhbHVlSGlnaCBIaWdoIGludGVuc2l0eQorICogQHJldHVybnMgYSBwb2ludGVyIHRvIGEgQmluYXJ5SW1hZ2UgdGhhdCByZXByZXNlbnRzIHRoZSByZXN1bHQgb2YgdGhlCisgKiB0aHJlc2hvbGQgb3BlcmF0aW9uLgorICovCitCaW5hcnlJbWFnZSAqQ29sb3JJbWFnZTo6VGhyZXNob2xkSFNJKGludCBodWVMb3csIGludCBodWVIaWdoLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQgc2F0dXJhdGlvbkxvdywgaW50IHNhdHVyYXRpb25IaWdoLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQgaW50ZW5zaXR5TG93LCBpbnQgaW50ZW5zaXR5SGlnaCkgeworICByZXR1cm4gQ29tcHV0ZVRocmVzaG9sZChJTUFRX0hTSSwgaHVlTG93LCBodWVIaWdoLCBzYXR1cmF0aW9uTG93LAorICAgICAgICAgICAgICAgICAgICAgICAgICBzYXR1cmF0aW9uSGlnaCwgaW50ZW5zaXR5TG93LCBpbnRlbnNpdHlIaWdoKTsKK30KKworLyoqCisgKiBQZXJmb3JtIGEgdGhyZXNob2xkIGluIEhTSSBzcGFjZS4KKyAqIEBwYXJhbSB0aHJlc2hvbGQgYSByZWZlcmVuY2UgdG8gdGhlIFRocmVzaG9sZCBvYmplY3QgdG8gdXNlLgorICogQHJldHVybnMgQSBwb2ludGVyIHRvIGEgQmluYXJ5SW1hZ2UgdGhhdCByZXByZXNlbnRzIHRoZSByZXN1bHQgb2YgdGhlCisgKiB0aHJlc2hvbGQgb3BlcmF0aW9uLgorICovCitCaW5hcnlJbWFnZSAqQ29sb3JJbWFnZTo6VGhyZXNob2xkSFNJKFRocmVzaG9sZCAmdCkgeworICByZXR1cm4gQ29tcHV0ZVRocmVzaG9sZChJTUFRX0hTSSwgdC5wbGFuZTFMb3csIHQucGxhbmUxSGlnaCwgdC5wbGFuZTJMb3csCisgICAgICAgICAgICAgICAgICAgICAgICAgIHQucGxhbmUySGlnaCwgdC5wbGFuZTNMb3csIHQucGxhbmUzSGlnaCk7Cit9CisKKy8qKgorICogRXh0cmFjdCBhIGNvbG9yIHBsYW5lIGZyb20gdGhlIGltYWdlCisgKiBAcGFyYW0gbW9kZSBUaGUgQ29sb3JNb2RlIHRvIHVzZSBmb3IgdGhlIHBsYW5lIGV4dHJhY3Rpb24KKyAqIEBwYXJhbSBwbGFuZU51bWJlciBXaGljaCBwbGFuZSBpcyB0byBiZSBleHRyYWN0ZWQKKyAqIEByZXR1cm5zIEEgcG9pbnRlciB0byBhIE1vbm9JbWFnZSB0aGF0IHJlcHJlc2VudHMgdGhlIGV4dHJhY3RlZCBwbGFuZS4KKyAqLworTW9ub0ltYWdlICpDb2xvckltYWdlOjpFeHRyYWN0Q29sb3JQbGFuZShDb2xvck1vZGUgbW9kZSwgaW50IHBsYW5lTnVtYmVyKSB7CisgIGF1dG8gcmVzdWx0ID0gbmV3IE1vbm9JbWFnZSgpOworICBpZiAobV9pbWFxSW1hZ2UgPT0gbnVsbHB0cikgd3BpX3NldFdQSUVycm9yKE51bGxQYXJhbWV0ZXIpOworICBpbnQgc3VjY2VzcyA9IGltYXFFeHRyYWN0Q29sb3JQbGFuZXMoCisgICAgICBtX2ltYXFJbWFnZSwgbW9kZSwgKHBsYW5lTnVtYmVyID09IDEpID8gcmVzdWx0LT5HZXRJbWFxSW1hZ2UoKSA6IG51bGxwdHIsCisgICAgICAocGxhbmVOdW1iZXIgPT0gMikgPyByZXN1bHQtPkdldEltYXFJbWFnZSgpIDogbnVsbHB0ciwKKyAgICAgIChwbGFuZU51bWJlciA9PSAzKSA/IHJlc3VsdC0+R2V0SW1hcUltYWdlKCkgOiBudWxscHRyKTsKKyAgd3BpX3NldEltYXFFcnJvcldpdGhDb250ZXh0KHN1Y2Nlc3MsICJJbWFxIEV4dHJhY3RDb2xvclBsYW5lcyBmYWlsZWQiKTsKKyAgcmV0dXJuIHJlc3VsdDsKK30KKworLyoKKyAqIEV4dHJhY3QgdGhlIGZpcnN0IGNvbG9yIHBsYW5lIGZvciBhbiBpbWFnZS4KKyAqIEBwYXJhbSBtb2RlIFRoZSBjb2xvciBtb2RlIGluIHdoaWNoIHRvIG9wZXJhdGUKKyAqIEByZXR1cm5zIGEgcG9pbnRlciB0byBhIE1vbm9JbWFnZSB0aGF0IGlzIHRoZSBleHRyYWN0ZWQgcGxhbmUuCisgKi8KK01vbm9JbWFnZSAqQ29sb3JJbWFnZTo6RXh0cmFjdEZpcnN0Q29sb3JQbGFuZShDb2xvck1vZGUgbW9kZSkgeworICByZXR1cm4gRXh0cmFjdENvbG9yUGxhbmUobW9kZSwgMSk7Cit9CisKKy8qCisgKiBFeHRyYWN0IHRoZSBzZWNvbmQgY29sb3IgcGxhbmUgZm9yIGFuIGltYWdlLgorICogQHBhcmFtIG1vZGUgVGhlIGNvbG9yIG1vZGUgaW4gd2hpY2ggdG8gb3BlcmF0ZQorICogQHJldHVybnMgYSBwb2ludGVyIHRvIGEgTW9ub0ltYWdlIHRoYXQgaXMgdGhlIGV4dHJhY3RlZCBwbGFuZS4KKyAqLworTW9ub0ltYWdlICpDb2xvckltYWdlOjpFeHRyYWN0U2Vjb25kQ29sb3JQbGFuZShDb2xvck1vZGUgbW9kZSkgeworICByZXR1cm4gRXh0cmFjdENvbG9yUGxhbmUobW9kZSwgMik7Cit9CisKKy8qCisgKiBFeHRyYWN0IHRoZSB0aGlyZCBjb2xvciBwbGFuZSBmb3IgYW4gaW1hZ2UuCisgKiBAcGFyYW0gbW9kZSBUaGUgY29sb3IgbW9kZSBpbiB3aGljaCB0byBvcGVyYXRlCisgKiBAcmV0dXJucyBhIHBvaW50ZXIgdG8gYSBNb25vSW1hZ2UgdGhhdCBpcyB0aGUgZXh0cmFjdGVkIHBsYW5lLgorICovCitNb25vSW1hZ2UgKkNvbG9ySW1hZ2U6OkV4dHJhY3RUaGlyZENvbG9yUGxhbmUoQ29sb3JNb2RlIG1vZGUpIHsKKyAgcmV0dXJuIEV4dHJhY3RDb2xvclBsYW5lKG1vZGUsIDMpOworfQorCisvKgorICogRXh0cmFjdCB0aGUgcmVkIHBsYW5lIGZyb20gYW4gUkdCIGltYWdlLgorICogQHJldHVybnMgYSBwb2ludGVyIHRvIGEgTW9ub0ltYWdlIHRoYXQgaXMgdGhlIGV4dHJhY2VkIHBsYW5lLgorICovCitNb25vSW1hZ2UgKkNvbG9ySW1hZ2U6OkdldFJlZFBsYW5lKCkgeworICByZXR1cm4gRXh0cmFjdEZpcnN0Q29sb3JQbGFuZShJTUFRX1JHQik7Cit9CisKKy8qCisgKiBFeHRyYWN0IHRoZSBncmVlbiBwbGFuZSBmcm9tIGFuIFJHQiBpbWFnZS4KKyAqIEByZXR1cm5zIGEgcG9pbnRlciB0byBhIE1vbm9JbWFnZSB0aGF0IGlzIHRoZSBleHRyYWNlZCBwbGFuZS4KKyAqLworTW9ub0ltYWdlICpDb2xvckltYWdlOjpHZXRHcmVlblBsYW5lKCkgeworICByZXR1cm4gRXh0cmFjdFNlY29uZENvbG9yUGxhbmUoSU1BUV9SR0IpOworfQorCisvKgorICogRXh0cmFjdCB0aGUgYmx1ZSBwbGFuZSBmcm9tIGFuIFJHQiBpbWFnZS4KKyAqIEByZXR1cm5zIGEgcG9pbnRlciB0byBhIE1vbm9JbWFnZSB0aGF0IGlzIHRoZSBleHRyYWNlZCBwbGFuZS4KKyAqLworTW9ub0ltYWdlICpDb2xvckltYWdlOjpHZXRCbHVlUGxhbmUoKSB7CisgIHJldHVybiBFeHRyYWN0VGhpcmRDb2xvclBsYW5lKElNQVFfUkdCKTsKK30KKworLyoKKyAqIEV4dHJhY3QgdGhlIEh1ZSBwbGFuZSBmcm9tIGFuIEhTTCBpbWFnZS4KKyAqIEByZXR1cm5zIGEgcG9pbnRlciB0byBhIE1vbm9JbWFnZSB0aGF0IGlzIHRoZSBleHRyYWNlZCBwbGFuZS4KKyAqLworTW9ub0ltYWdlICpDb2xvckltYWdlOjpHZXRIU0xIdWVQbGFuZSgpIHsKKyAgcmV0dXJuIEV4dHJhY3RGaXJzdENvbG9yUGxhbmUoSU1BUV9IU0wpOworfQorCisvKgorICogRXh0cmFjdCB0aGUgSHVlIHBsYW5lIGZyb20gYW4gSFNWIGltYWdlLgorICogQHJldHVybnMgYSBwb2ludGVyIHRvIGEgTW9ub0ltYWdlIHRoYXQgaXMgdGhlIGV4dHJhY2VkIHBsYW5lLgorICovCitNb25vSW1hZ2UgKkNvbG9ySW1hZ2U6OkdldEhTVkh1ZVBsYW5lKCkgeworICByZXR1cm4gRXh0cmFjdEZpcnN0Q29sb3JQbGFuZShJTUFRX0hTVik7Cit9CisKKy8qCisgKiBFeHRyYWN0IHRoZSBIdWUgcGxhbmUgZnJvbSBhbiBIU0kgaW1hZ2UuCisgKiBAcmV0dXJucyBhIHBvaW50ZXIgdG8gYSBNb25vSW1hZ2UgdGhhdCBpcyB0aGUgZXh0cmFjZWQgcGxhbmUuCisgKi8KK01vbm9JbWFnZSAqQ29sb3JJbWFnZTo6R2V0SFNJSHVlUGxhbmUoKSB7CisgIHJldHVybiBFeHRyYWN0Rmlyc3RDb2xvclBsYW5lKElNQVFfSFNJKTsKK30KKworLyoKKyAqIEV4dHJhY3QgdGhlIEx1bWluYW5jZSBwbGFuZSBmcm9tIGFuIEhTTCBpbWFnZS4KKyAqIEByZXR1cm5zIGEgcG9pbnRlciB0byBhIE1vbm9JbWFnZSB0aGF0IGlzIHRoZSBleHRyYWNlZCBwbGFuZS4KKyAqLworTW9ub0ltYWdlICpDb2xvckltYWdlOjpHZXRMdW1pbmFuY2VQbGFuZSgpIHsKKyAgcmV0dXJuIEV4dHJhY3RUaGlyZENvbG9yUGxhbmUoSU1BUV9IU0wpOworfQorCisvKgorICogRXh0cmFjdCB0aGUgVmFsdWUgcGxhbmUgZnJvbSBhbiBIU1YgaW1hZ2UuCisgKiBAcmV0dXJucyBhIHBvaW50ZXIgdG8gYSBNb25vSW1hZ2UgdGhhdCBpcyB0aGUgZXh0cmFjZWQgcGxhbmUuCisgKi8KK01vbm9JbWFnZSAqQ29sb3JJbWFnZTo6R2V0VmFsdWVQbGFuZSgpIHsKKyAgcmV0dXJuIEV4dHJhY3RUaGlyZENvbG9yUGxhbmUoSU1BUV9IU1YpOworfQorCisvKgorICogRXh0cmFjdCB0aGUgSW50ZW5zaXR5IHBsYW5lIGZyb20gYW4gSFNJIGltYWdlLgorICogQHJldHVybnMgYSBwb2ludGVyIHRvIGEgTW9ub0ltYWdlIHRoYXQgaXMgdGhlIGV4dHJhY2VkIHBsYW5lLgorICovCitNb25vSW1hZ2UgKkNvbG9ySW1hZ2U6OkdldEludGVuc2l0eVBsYW5lKCkgeworICByZXR1cm4gRXh0cmFjdFRoaXJkQ29sb3JQbGFuZShJTUFRX0hTSSk7Cit9CisKKy8qKgorICogUmVwbGFjZSBhIHBsYW5lIGluIHRoZSBDb2xvckltYWdlIHdpdGggYSBNb25vSW1hZ2UKKyAqIFJlcGxhY2VzIGEgc2luZ2xlIHBsYW5lIGluIHRoZSBpbWFnZSB3aXRoIGEgTW9ub0ltYWdlCisgKiBAcGFyYW0gbW9kZSBUaGUgQ29sb3JNb2RlIGluIHdoaWNoIHRvIG9wZXJhdGUKKyAqIEBwYXJhbSBwbGFuZSBUaGUgcG9pbnRlciB0byB0aGUgcmVwbGFjZW1lbnQgcGxhbmUgYXMgYSBNb25vSW1hZ2UKKyAqIEBwYXJhbSBwbGFuZU51bWJlciBUaGUgcGxhbmUgbnVtYmVyICgxLCAyLCAzKSB0byByZXBsYWNlCisgKi8KK3ZvaWQgQ29sb3JJbWFnZTo6UmVwbGFjZVBsYW5lKENvbG9yTW9kZSBtb2RlLCBNb25vSW1hZ2UgKnBsYW5lLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50IHBsYW5lTnVtYmVyKSB7CisgIGludCBzdWNjZXNzID0KKyAgICAgIGltYXFSZXBsYWNlQ29sb3JQbGFuZXMobV9pbWFxSW1hZ2UsIChjb25zdCBJbWFnZSAqKW1faW1hcUltYWdlLCBtb2RlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAocGxhbmVOdW1iZXIgPT0gMSkgPyBwbGFuZS0+R2V0SW1hcUltYWdlKCkgOiBudWxscHRyLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAocGxhbmVOdW1iZXIgPT0gMikgPyBwbGFuZS0+R2V0SW1hcUltYWdlKCkgOiBudWxscHRyLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAocGxhbmVOdW1iZXIgPT0gMykgPyBwbGFuZS0+R2V0SW1hcUltYWdlKCkgOiBudWxscHRyKTsKKyAgd3BpX3NldEltYXFFcnJvcldpdGhDb250ZXh0KHN1Y2Nlc3MsICJJbWFxIFJlcGxhY2VDb2xvclBsYW5lcyBmYWlsZWQiKTsKK30KKworLyoqCisgKiBSZXBsYWNlIHRoZSBmaXJzdCBjb2xvciBwbGFuZSB3aXRoIGEgTW9ub0ltYWdlLgorICogQHBhcmFtIG1vZGUgVGhlIGNvbG9yIG1vZGUgaW4gd2hpY2ggdG8gb3BlcmF0ZS4KKyAqIEBwYXJhbSBwbGFuZSBBIHBvaW50ZXIgdG8gYSBNb25vSW1hZ2UgdGhhdCB3aWxsIHJlcGxhY2UgdGhlIHNwZWNpZmllZCBjb2xvcgorICogcGxhbmUuCisgKi8KK3ZvaWQgQ29sb3JJbWFnZTo6UmVwbGFjZUZpcnN0Q29sb3JQbGFuZShDb2xvck1vZGUgbW9kZSwgTW9ub0ltYWdlICpwbGFuZSkgeworICBSZXBsYWNlUGxhbmUobW9kZSwgcGxhbmUsIDEpOworfQorCisvKioKKyAqIFJlcGxhY2UgdGhlIHNlY29uZCBjb2xvciBwbGFuZSB3aXRoIGEgTW9ub0ltYWdlLgorICogQHBhcmFtIG1vZGUgVGhlIGNvbG9yIG1vZGUgaW4gd2hpY2ggdG8gb3BlcmF0ZS4KKyAqIEBwYXJhbSBwbGFuZSBBIHBvaW50ZXIgdG8gYSBNb25vSW1hZ2UgdGhhdCB3aWxsIHJlcGxhY2UgdGhlIHNwZWNpZmllZCBjb2xvcgorICogcGxhbmUuCisgKi8KK3ZvaWQgQ29sb3JJbWFnZTo6UmVwbGFjZVNlY29uZENvbG9yUGxhbmUoQ29sb3JNb2RlIG1vZGUsIE1vbm9JbWFnZSAqcGxhbmUpIHsKKyAgUmVwbGFjZVBsYW5lKG1vZGUsIHBsYW5lLCAyKTsKK30KKworLyoqCisgKiBSZXBsYWNlIHRoZSB0aGlyZCBjb2xvciBwbGFuZSB3aXRoIGEgTW9ub0ltYWdlLgorICogQHBhcmFtIG1vZGUgVGhlIGNvbG9yIG1vZGUgaW4gd2hpY2ggdG8gb3BlcmF0ZS4KKyAqIEBwYXJhbSBwbGFuZSBBIHBvaW50ZXIgdG8gYSBNb25vSW1hZ2UgdGhhdCB3aWxsIHJlcGxhY2UgdGhlIHNwZWNpZmllZCBjb2xvcgorICogcGxhbmUuCisgKi8KK3ZvaWQgQ29sb3JJbWFnZTo6UmVwbGFjZVRoaXJkQ29sb3JQbGFuZShDb2xvck1vZGUgbW9kZSwgTW9ub0ltYWdlICpwbGFuZSkgeworICBSZXBsYWNlUGxhbmUobW9kZSwgcGxhbmUsIDMpOworfQorCisvKioKKyAqIFJlcGxhY2UgdGhlIHJlZCBjb2xvciBwbGFuZSB3aXRoIGEgTW9ub0ltYWdlLgorICogQHBhcmFtIG1vZGUgVGhlIGNvbG9yIG1vZGUgaW4gd2hpY2ggdG8gb3BlcmF0ZS4KKyAqIEBwYXJhbSBwbGFuZSBBIHBvaW50ZXIgdG8gYSBNb25vSW1hZ2UgdGhhdCB3aWxsIHJlcGxhY2UgdGhlIHNwZWNpZmllZCBjb2xvcgorICogcGxhbmUuCisgKi8KK3ZvaWQgQ29sb3JJbWFnZTo6UmVwbGFjZVJlZFBsYW5lKE1vbm9JbWFnZSAqcGxhbmUpIHsKKyAgUmVwbGFjZUZpcnN0Q29sb3JQbGFuZShJTUFRX1JHQiwgcGxhbmUpOworfQorCisvKioKKyAqIFJlcGxhY2UgdGhlIGdyZWVuIGNvbG9yIHBsYW5lIHdpdGggYSBNb25vSW1hZ2UuCisgKiBAcGFyYW0gbW9kZSBUaGUgY29sb3IgbW9kZSBpbiB3aGljaCB0byBvcGVyYXRlLgorICogQHBhcmFtIHBsYW5lIEEgcG9pbnRlciB0byBhIE1vbm9JbWFnZSB0aGF0IHdpbGwgcmVwbGFjZSB0aGUgc3BlY2lmaWVkIGNvbG9yCisgKiBwbGFuZS4KKyAqLwordm9pZCBDb2xvckltYWdlOjpSZXBsYWNlR3JlZW5QbGFuZShNb25vSW1hZ2UgKnBsYW5lKSB7CisgIFJlcGxhY2VTZWNvbmRDb2xvclBsYW5lKElNQVFfUkdCLCBwbGFuZSk7Cit9CisKKy8qKgorICogUmVwbGFjZSB0aGUgYmx1ZSBjb2xvciBwbGFuZSB3aXRoIGEgTW9ub0ltYWdlLgorICogQHBhcmFtIG1vZGUgVGhlIGNvbG9yIG1vZGUgaW4gd2hpY2ggdG8gb3BlcmF0ZS4KKyAqIEBwYXJhbSBwbGFuZSBBIHBvaW50ZXIgdG8gYSBNb25vSW1hZ2UgdGhhdCB3aWxsIHJlcGxhY2UgdGhlIHNwZWNpZmllZCBjb2xvcgorICogcGxhbmUuCisgKi8KK3ZvaWQgQ29sb3JJbWFnZTo6UmVwbGFjZUJsdWVQbGFuZShNb25vSW1hZ2UgKnBsYW5lKSB7CisgIFJlcGxhY2VUaGlyZENvbG9yUGxhbmUoSU1BUV9SR0IsIHBsYW5lKTsKK30KKworLyoqCisgKiBSZXBsYWNlIHRoZSBIdWUgY29sb3IgcGxhbmUgaW4gYSBIU0wgaW1hZ2Ugd2l0aCBhIE1vbm9JbWFnZS4KKyAqIEBwYXJhbSBtb2RlIFRoZSBjb2xvciBtb2RlIGluIHdoaWNoIHRvIG9wZXJhdGUuCisgKiBAcGFyYW0gcGxhbmUgQSBwb2ludGVyIHRvIGEgTW9ub0ltYWdlIHRoYXQgd2lsbCByZXBsYWNlIHRoZSBzcGVjaWZpZWQgY29sb3IKKyAqIHBsYW5lLgorICovCit2b2lkIENvbG9ySW1hZ2U6OlJlcGxhY2VIU0xIdWVQbGFuZShNb25vSW1hZ2UgKnBsYW5lKSB7CisgIHJldHVybiBSZXBsYWNlRmlyc3RDb2xvclBsYW5lKElNQVFfSFNMLCBwbGFuZSk7Cit9CisKKy8qKgorICogUmVwbGFjZSB0aGUgSHVlIGNvbG9yIHBsYW5lIGluIGEgSFNWIGltYWdlIHdpdGggYSBNb25vSW1hZ2UuCisgKiBAcGFyYW0gbW9kZSBUaGUgY29sb3IgbW9kZSBpbiB3aGljaCB0byBvcGVyYXRlLgorICogQHBhcmFtIHBsYW5lIEEgcG9pbnRlciB0byBhIE1vbm9JbWFnZSB0aGF0IHdpbGwgcmVwbGFjZSB0aGUgc3BlY2lmaWVkIGNvbG9yCisgKiBwbGFuZS4KKyAqLwordm9pZCBDb2xvckltYWdlOjpSZXBsYWNlSFNWSHVlUGxhbmUoTW9ub0ltYWdlICpwbGFuZSkgeworICByZXR1cm4gUmVwbGFjZUZpcnN0Q29sb3JQbGFuZShJTUFRX0hTViwgcGxhbmUpOworfQorCisvKioKKyAqIFJlcGxhY2UgdGhlIGZpcnN0IEh1ZSBwbGFuZSBpbiBhIEhTSSBpbWFnZSB3aXRoIGEgTW9ub0ltYWdlLgorICogQHBhcmFtIG1vZGUgVGhlIGNvbG9yIG1vZGUgaW4gd2hpY2ggdG8gb3BlcmF0ZS4KKyAqIEBwYXJhbSBwbGFuZSBBIHBvaW50ZXIgdG8gYSBNb25vSW1hZ2UgdGhhdCB3aWxsIHJlcGxhY2UgdGhlIHNwZWNpZmllZCBjb2xvcgorICogcGxhbmUuCisgKi8KK3ZvaWQgQ29sb3JJbWFnZTo6UmVwbGFjZUhTSUh1ZVBsYW5lKE1vbm9JbWFnZSAqcGxhbmUpIHsKKyAgcmV0dXJuIFJlcGxhY2VGaXJzdENvbG9yUGxhbmUoSU1BUV9IU0ksIHBsYW5lKTsKK30KKworLyoqCisgKiBSZXBsYWNlIHRoZSBTYXR1cmF0aW9uIGNvbG9yIHBsYW5lIGluIGFuIEhTTCBpbWFnZSB3aXRoIGEgTW9ub0ltYWdlLgorICogQHBhcmFtIG1vZGUgVGhlIGNvbG9yIG1vZGUgaW4gd2hpY2ggdG8gb3BlcmF0ZS4KKyAqIEBwYXJhbSBwbGFuZSBBIHBvaW50ZXIgdG8gYSBNb25vSW1hZ2UgdGhhdCB3aWxsIHJlcGxhY2UgdGhlIHNwZWNpZmllZCBjb2xvcgorICogcGxhbmUuCisgKi8KK3ZvaWQgQ29sb3JJbWFnZTo6UmVwbGFjZUhTTFNhdHVyYXRpb25QbGFuZShNb25vSW1hZ2UgKnBsYW5lKSB7CisgIHJldHVybiBSZXBsYWNlU2Vjb25kQ29sb3JQbGFuZShJTUFRX0hTTCwgcGxhbmUpOworfQorCisvKioKKyAqIFJlcGxhY2UgdGhlIFNhdHVyYXRpb24gY29sb3IgcGxhbmUgaW4gYSBIU1YgaW1hZ2Ugd2l0aCBhIE1vbm9JbWFnZS4KKyAqIEBwYXJhbSBtb2RlIFRoZSBjb2xvciBtb2RlIGluIHdoaWNoIHRvIG9wZXJhdGUuCisgKiBAcGFyYW0gcGxhbmUgQSBwb2ludGVyIHRvIGEgTW9ub0ltYWdlIHRoYXQgd2lsbCByZXBsYWNlIHRoZSBzcGVjaWZpZWQgY29sb3IKKyAqIHBsYW5lLgorICovCit2b2lkIENvbG9ySW1hZ2U6OlJlcGxhY2VIU1ZTYXR1cmF0aW9uUGxhbmUoTW9ub0ltYWdlICpwbGFuZSkgeworICByZXR1cm4gUmVwbGFjZVNlY29uZENvbG9yUGxhbmUoSU1BUV9IU1YsIHBsYW5lKTsKK30KKworLyoqCisgKiBSZXBsYWNlIHRoZSBTYXR1cmF0aW9uIGNvbG9yIHBsYW5lIGluIGEgSFNJIGltYWdlIHdpdGggYSBNb25vSW1hZ2UuCisgKiBAcGFyYW0gbW9kZSBUaGUgY29sb3IgbW9kZSBpbiB3aGljaCB0byBvcGVyYXRlLgorICogQHBhcmFtIHBsYW5lIEEgcG9pbnRlciB0byBhIE1vbm9JbWFnZSB0aGF0IHdpbGwgcmVwbGFjZSB0aGUgc3BlY2lmaWVkIGNvbG9yCisgKiBwbGFuZS4KKyAqLwordm9pZCBDb2xvckltYWdlOjpSZXBsYWNlSFNJU2F0dXJhdGlvblBsYW5lKE1vbm9JbWFnZSAqcGxhbmUpIHsKKyAgcmV0dXJuIFJlcGxhY2VTZWNvbmRDb2xvclBsYW5lKElNQVFfSFNJLCBwbGFuZSk7Cit9CisKKy8qKgorICogUmVwbGFjZSB0aGUgTHVtaW5hbmNlIGNvbG9yIHBsYW5lIGluIGFuIEhTTCBpbWFnZSB3aXRoIGEgTW9ub0ltYWdlLgorICogQHBhcmFtIG1vZGUgVGhlIGNvbG9yIG1vZGUgaW4gd2hpY2ggdG8gb3BlcmF0ZS4KKyAqIEBwYXJhbSBwbGFuZSBBIHBvaW50ZXIgdG8gYSBNb25vSW1hZ2UgdGhhdCB3aWxsIHJlcGxhY2UgdGhlIHNwZWNpZmllZCBjb2xvcgorICogcGxhbmUuCisgKi8KK3ZvaWQgQ29sb3JJbWFnZTo6UmVwbGFjZUx1bWluYW5jZVBsYW5lKE1vbm9JbWFnZSAqcGxhbmUpIHsKKyAgcmV0dXJuIFJlcGxhY2VUaGlyZENvbG9yUGxhbmUoSU1BUV9IU0wsIHBsYW5lKTsKK30KKworLyoqCisgKiBSZXBsYWNlIHRoZSBWYWx1ZSBjb2xvciBwbGFuZSBpbiBhbiBIU1Ygd2l0aCBhIE1vbm9JbWFnZS4KKyAqIEBwYXJhbSBtb2RlIFRoZSBjb2xvciBtb2RlIGluIHdoaWNoIHRvIG9wZXJhdGUuCisgKiBAcGFyYW0gcGxhbmUgQSBwb2ludGVyIHRvIGEgTW9ub0ltYWdlIHRoYXQgd2lsbCByZXBsYWNlIHRoZSBzcGVjaWZpZWQgY29sb3IKKyAqIHBsYW5lLgorICovCit2b2lkIENvbG9ySW1hZ2U6OlJlcGxhY2VWYWx1ZVBsYW5lKE1vbm9JbWFnZSAqcGxhbmUpIHsKKyAgcmV0dXJuIFJlcGxhY2VUaGlyZENvbG9yUGxhbmUoSU1BUV9IU1YsIHBsYW5lKTsKK30KKworLyoqCisgKiBSZXBsYWNlIHRoZSBJbnRlbnNpdHkgY29sb3IgcGxhbmUgaW4gYSBIU0kgaW1hZ2Ugd2l0aCBhIE1vbm9JbWFnZS4KKyAqIEBwYXJhbSBtb2RlIFRoZSBjb2xvciBtb2RlIGluIHdoaWNoIHRvIG9wZXJhdGUuCisgKiBAcGFyYW0gcGxhbmUgQSBwb2ludGVyIHRvIGEgTW9ub0ltYWdlIHRoYXQgd2lsbCByZXBsYWNlIHRoZSBzcGVjaWZpZWQgY29sb3IKKyAqIHBsYW5lLgorICovCit2b2lkIENvbG9ySW1hZ2U6OlJlcGxhY2VJbnRlbnNpdHlQbGFuZShNb25vSW1hZ2UgKnBsYW5lKSB7CisgIHJldHVybiBSZXBsYWNlVGhpcmRDb2xvclBsYW5lKElNQVFfSFNJLCBwbGFuZSk7Cit9CisKKy8vIFRPRE86IGZyY0NvbG9yRXF1YWxpemUoSW1hZ2UqIGRlc3QsIGNvbnN0IEltYWdlKiBzb3VyY2UsIGludAorLy8gY29sb3JFcXVhbGl6YXRpb24pIG5lZWRzIHRvIGJlIG1vZGlmaWVkCisvLyBUaGUgY29sb3JFcXVhbGl6YXRpb24gcGFyYW1ldGVyIGlzIGRpc2NhcmRlZCBhbmQgaXMgc2V0IHRvIFRSVUUgaW4gdGhlIGNhbGwKKy8vIHRvIGltYXFDb2xvckVxdWFsaXplLgordm9pZCBDb2xvckltYWdlOjpFcXVhbGl6ZShib29sIGFsbFBsYW5lcykgeworICAvLyBOb3RlIHRoYXQgdGhpcyBjYWxsIHVzZXMgTkktZGVmaW5lZCBUUlVFIGFuZCBGQUxTRQorICBpbnQgc3VjY2VzcyA9IGltYXFDb2xvckVxdWFsaXplKG1faW1hcUltYWdlLCAoY29uc3QgSW1hZ2UgKiltX2ltYXFJbWFnZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoYWxsUGxhbmVzKSA/IFRSVUUgOiBGQUxTRSk7CisgIHdwaV9zZXRJbWFxRXJyb3JXaXRoQ29udGV4dChzdWNjZXNzLCAiSW1hcSBDb2xvckVxdWFsaXplIGVycm9yIik7Cit9CisKK3ZvaWQgQ29sb3JJbWFnZTo6Q29sb3JFcXVhbGl6ZSgpIHsgRXF1YWxpemUodHJ1ZSk7IH0KKwordm9pZCBDb2xvckltYWdlOjpMdW1pbmFuY2VFcXVhbGl6ZSgpIHsgRXF1YWxpemUoZmFsc2UpOyB9CmRpZmYgLS1naXQgYS93cGlsaWJjL0F0aGVuYS9zcmMvVmlzaW9uL0ZyY0Vycm9yLmNwcCBiL3dwaWxpYmMvQXRoZW5hL3NyYy9WaXNpb24vRnJjRXJyb3IuY3BwCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmYwYjQ3MjUKLS0tIC9kZXYvbnVsbAorKysgYi93cGlsaWJjL0F0aGVuYS9zcmMvVmlzaW9uL0ZyY0Vycm9yLmNwcApAQCAtMCwwICsxLDI0MDMgQEAKKy8qLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovCisvKiBDb3B5cmlnaHQgKGMpIEZJUlNUIDIwMTQuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqLworLyogT3BlbiBTb3VyY2UgU29mdHdhcmUgLSBtYXkgYmUgbW9kaWZpZWQgYW5kIHNoYXJlZCBieSBGUkMgdGVhbXMuIFRoZSBjb2RlICAgKi8KKy8qIG11c3QgYmUgYWNjb21wYW5pZWQgYnkgdGhlIEZJUlNUIEJTRCBsaWNlbnNlIGZpbGUgaW4gJChXSU5EX0JBU0UpL1dQSUxpYi4gICovCisvKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qLworCisjaW5jbHVkZSAibml2aXNpb24uaCIKKyNpbmNsdWRlICJWaXNpb24vRnJjRXJyb3IuaCIKKworLyoqCisgKiBHZXQgdGhlIGVycm9yIGNvZGUgcmV0dXJuZWQgZnJvbSB0aGUgTkkgVmlzaW9uIGxpYnJhcnkKKyAqIEByZXR1cm4gVGhlIGxhc3QgZXJyb3IgY29kZS4KKyAqLworaW50IEdldExhc3RWaXNpb25FcnJvcigpIHsKKyAgLy8gaW50IGVycm9yQ29kZSA9IGltYXFHZXRMYXN0VmlzaW9uRXJyb3IoKTsgICAgIC8vIGVycm9yIGNvZGU6IDAgPSBubyBlcnJvcgorICAvLyBjaGFyKiBlcnJvclRleHQgPSBHZXRWaXNpb25FcnJvclRleHQoZXJyb3JDb2RlKTsKKyAgLy8gZHByaW50ZiAoTE9HX0RFQlVHLCAiRXJyb3IgPSAlaSAgJXMgIiwgZXJyb3JDb2RlLCBlcnJvclRleHQpOworICByZXR1cm4gaW1hcUdldExhc3RFcnJvcigpOworfQorCisvKioKKyogR2V0IHRoZSBlcnJvciB0ZXh0IGZvciBhbiBOSSBWaXNpb24gZXJyb3IgY29kZS4KKyogTm90ZTogaW1hcUdldEVycm9yVGV4dCgpIGlzIG5vdCBzdXBwb3J0ZWQgb24gcmVhbCB0aW1lIHN5c3RlbSwgc28KKyogc28gcmVsZXZhbnQgc3RyaW5ncyBhcmUgaGFyZGNvZGVkIGhlcmUgLSB0aGUgbWFpbnRhaW5lZCB2ZXJzaW9uIGlzCisqIGluIHRoZSBMYWJXaW5kb3dzL0NWSSBoZWxwIGZpbGUuCisqIEBwYXJhbSBlcnJvckNvZGUgVGhlIGVycm9yIGNvZGUgdG8gZmluZCB0aGUgdGV4dCBmb3IuCisqIEByZXR1cm4gVGhlIGVycm9yIHRleHQKKyovCitjb25zdCBjaGFyKiBHZXRWaXNpb25FcnJvclRleHQoaW50IGVycm9yQ29kZSkgeworICBjb25zdCBjaGFyKiBlcnJvclRleHQ7CisKKyAgc3dpdGNoIChlcnJvckNvZGUpIHsKKyAgICBkZWZhdWx0OiB7CisgICAgICBlcnJvclRleHQgPSAiVU5LTk9XTl9FUlJPUiI7CisgICAgICBicmVhazsKKyAgICB9CisgICAgY2FzZSAtMTA3NDM5NTEzODogeworICAgICAgZXJyb3JUZXh0ID0gIkVSUl9PQ1JfUkVHSU9OX1RPT19TTUFMTCI7CisgICAgICBicmVhazsKKyAgICB9CisgICAgY2FzZSAtMTA3NDM5NTEzOTogeworICAgICAgZXJyb3JUZXh0ID0gIkVSUl9JTUFRX1FSX0RJTUVOU0lPTl9JTlZBTElEIjsKKyAgICAgIGJyZWFrOworICAgIH0KKyAgICBjYXNlIC0xMDc0Mzk1MTQwOiB7CisgICAgICBlcnJvclRleHQgPSAiRVJSX09DUl9DSEFSX1JFUE9SVF9DT1JSVVBURUQiOworICAgICAgYnJlYWs7CisgICAgfQorICAgIGNhc2UgLTEwNzQzOTUxNDE6IHsKKyAgICAgIGVycm9yVGV4dCA9ICJFUlJfT0NSX05PX1RFWFRfRk9VTkQiOworICAgICAgYnJlYWs7CisgICAgfQorICAgIGNhc2UgLTEwNzQzOTUxNDI6IHsKKyAgICAgIGVycm9yVGV4dCA9ICJFUlJfUVJfREVURUNUSU9OX01PREVMVFlQRSI7CisgICAgICBicmVhazsKKyAgICB9CisgICAgY2FzZSAtMTA3NDM5NTE0MzogeworICAgICAgZXJyb3JUZXh0ID0gIkVSUl9RUl9ERVRFQ1RJT05fTU9ERSI7CisgICAgICBicmVhazsKKyAgICB9CisgICAgY2FzZSAtMTA3NDM5NTE0NDogeworICAgICAgZXJyb3JUZXh0ID0gIkVSUl9RUl9JTlZBTElEX0JBUkNPREUiOworICAgICAgYnJlYWs7CisgICAgfQorICAgIGNhc2UgLTEwNzQzOTUxNDU6IHsKKyAgICAgIGVycm9yVGV4dCA9ICJFUlJfUVJfSU5WQUxJRF9SRUFEIjsKKyAgICAgIGJyZWFrOworICAgIH0KKyAgICBjYXNlIC0xMDc0Mzk1MTQ2OiB7CisgICAgICBlcnJvclRleHQgPSAiRVJSX1FSX0RFVEVDVElPTl9WRVJTSU9OIjsKKyAgICAgIGJyZWFrOworICAgIH0KKyAgICBjYXNlIC0xMDc0Mzk1MTQ3OiB7CisgICAgICBlcnJvclRleHQgPSAiRVJSX0JBUkNPREVfUlNTTElNSVRFRCI7CisgICAgICBicmVhazsKKyAgICB9CisgICAgY2FzZSAtMTA3NDM5NTE0ODogeworICAgICAgZXJyb3JUZXh0ID0gIkVSUl9PVkVSTEFZX0dST1VQX05PVF9GT1VORCI7CisgICAgICBicmVhazsKKyAgICB9CisgICAgY2FzZSAtMTA3NDM5NTE0OTogeworICAgICAgZXJyb3JUZXh0ID0gIkVSUl9EVVBMSUNBVEVfVFJBTlNGT1JNX1RZUEUiOworICAgICAgYnJlYWs7CisgICAgfQorICAgIGNhc2UgLTEwNzQzOTUxNTE6IHsKKyAgICAgIGVycm9yVGV4dCA9ICJFUlJfT0NSX0NPUlJFQ1RJT05fRkFJTEVEIjsKKyAgICAgIGJyZWFrOworICAgIH0KKyAgICBjYXNlIC0xMDc0Mzk1MTU1OiB7CisgICAgICBlcnJvclRleHQgPSAiRVJSX09DUl9PUklFTlRfREVURUNUX0ZBSUxFRCI7CisgICAgICBicmVhazsKKyAgICB9CisgICAgY2FzZSAtMTA3NDM5NTE1NjogeworICAgICAgZXJyb3JUZXh0ID0gIkVSUl9PQ1JfU0tFV19ERVRFQ1RfRkFJTEVEIjsKKyAgICAgIGJyZWFrOworICAgIH0KKyAgICBjYXNlIC0xMDc0Mzk1MTU4OiB7CisgICAgICBlcnJvclRleHQgPSAiRVJSX09DUl9JTlZBTElEX0NPTlRSQVNUTU9ERSI7CisgICAgICBicmVhazsKKyAgICB9CisgICAgY2FzZSAtMTA3NDM5NTE1OTogeworICAgICAgZXJyb3JUZXh0ID0gIkVSUl9PQ1JfSU5WQUxJRF9UT0xFUkFOQ0UiOworICAgICAgYnJlYWs7CisgICAgfQorICAgIGNhc2UgLTEwNzQzOTUxNjA6IHsKKyAgICAgIGVycm9yVGV4dCA9ICJFUlJfT0NSX0lOVkFMSURfTUFYUE9JTlRTSVpFIjsKKyAgICAgIGJyZWFrOworICAgIH0KKyAgICBjYXNlIC0xMDc0Mzk1MTYxOiB7CisgICAgICBlcnJvclRleHQgPSAiRVJSX09DUl9JTlZBTElEX0NPUlJFQ1RJT05MRVZFTCI7CisgICAgICBicmVhazsKKyAgICB9CisgICAgY2FzZSAtMTA3NDM5NTE2MjogeworICAgICAgZXJyb3JUZXh0ID0gIkVSUl9PQ1JfSU5WQUxJRF9DT1JSRUNUSU9OTU9ERSI7CisgICAgICBicmVhazsKKyAgICB9CisgICAgY2FzZSAtMTA3NDM5NTE2MzogeworICAgICAgZXJyb3JUZXh0ID0gIkVSUl9PQ1JfSU5WQUxJRF9DSEFSQUNURVJQUkVGRVJFTkNFIjsKKyAgICAgIGJyZWFrOworICAgIH0KKyAgICBjYXNlIC0xMDc0Mzk1MTY0OiB7CisgICAgICBlcnJvclRleHQgPSAiRVJSX09DUl9BRERfV09SRF9GQUlMRUQiOworICAgICAgYnJlYWs7CisgICAgfQorICAgIGNhc2UgLTEwNzQzOTUxNjU6IHsKKyAgICAgIGVycm9yVGV4dCA9ICJFUlJfT0NSX1dUU19ESVJfTk9UX0ZPVU5EIjsKKyAgICAgIGJyZWFrOworICAgIH0KKyAgICBjYXNlIC0xMDc0Mzk1MTY2OiB7CisgICAgICBlcnJvclRleHQgPSAiRVJSX09DUl9CSU5fRElSX05PVF9GT1VORCI7CisgICAgICBicmVhazsKKyAgICB9CisgICAgY2FzZSAtMTA3NDM5NTE2NzogeworICAgICAgZXJyb3JUZXh0ID0gIkVSUl9PQ1JfSU5WQUxJRF9PVVRQVVRERUxJTUlURVIiOworICAgICAgYnJlYWs7CisgICAgfQorICAgIGNhc2UgLTEwNzQzOTUxNjg6IHsKKyAgICAgIGVycm9yVGV4dCA9ICJFUlJfT0NSX0lOVkFMSURfQVVUT0NPUlJFQ1RJT05NT0RFIjsKKyAgICAgIGJyZWFrOworICAgIH0KKyAgICBjYXNlIC0xMDc0Mzk1MTY5OiB7CisgICAgICBlcnJvclRleHQgPSAiRVJSX09DUl9JTlZBTElEX1JFQ09HTklUSU9OTU9ERSI7CisgICAgICBicmVhazsKKyAgICB9CisgICAgY2FzZSAtMTA3NDM5NTE3MDogeworICAgICAgZXJyb3JUZXh0ID0gIkVSUl9PQ1JfSU5WQUxJRF9DSEFSQUNURVJUWVBFIjsKKyAgICAgIGJyZWFrOworICAgIH0KKyAgICBjYXNlIC0xMDc0Mzk1MTcxOiB7CisgICAgICBlcnJvclRleHQgPSAiRVJSX09DUl9JTklfRklMRV9OT1RfRk9VTkQiOworICAgICAgYnJlYWs7CisgICAgfQorICAgIGNhc2UgLTEwNzQzOTUxNzI6IHsKKyAgICAgIGVycm9yVGV4dCA9ICJFUlJfT0NSX0lOVkFMSURfQ0hBUkFDVEVSU0VUIjsKKyAgICAgIGJyZWFrOworICAgIH0KKyAgICBjYXNlIC0xMDc0Mzk1MTczOiB7CisgICAgICBlcnJvclRleHQgPSAiRVJSX09DUl9JTlZBTElEX0xBTkdVQUdFIjsKKyAgICAgIGJyZWFrOworICAgIH0KKyAgICBjYXNlIC0xMDc0Mzk1MTc0OiB7CisgICAgICBlcnJvclRleHQgPSAiRVJSX09DUl9JTlZBTElEX0FVVE9PUklFTlRNT0RFIjsKKyAgICAgIGJyZWFrOworICAgIH0KKyAgICBjYXNlIC0xMDc0Mzk1MTc1OiB7CisgICAgICBlcnJvclRleHQgPSAiRVJSX09DUl9CQURfVVNFUl9ESUNUSU9OQVJZIjsKKyAgICAgIGJyZWFrOworICAgIH0KKyAgICBjYXNlIC0xMDc0Mzk1MTc4OiB7CisgICAgICBlcnJvclRleHQgPSAiRVJSX09DUl9SRUNPR05JVElPTl9GQUlMRUQiOworICAgICAgYnJlYWs7CisgICAgfQorICAgIGNhc2UgLTEwNzQzOTUxNzk6IHsKKyAgICAgIGVycm9yVGV4dCA9ICJFUlJfT0NSX1BSRVBST0NFU1NJTkdfRkFJTEVEIjsKKyAgICAgIGJyZWFrOworICAgIH0KKyAgICBjYXNlIC0xMDc0Mzk1MjAwOiB7CisgICAgICBlcnJvclRleHQgPSAiRVJSX09DUl9JTlZBTElEX1BBUkFNRVRFUiI7CisgICAgICBicmVhazsKKyAgICB9CisgICAgY2FzZSAtMTA3NDM5NTIwMTogeworICAgICAgZXJyb3JUZXh0ID0gIkVSUl9PQ1JfTE9BRF9MSUJSQVJZIjsKKyAgICAgIGJyZWFrOworICAgIH0KKyAgICBjYXNlIC0xMDc0Mzk1MjAzOiB7CisgICAgICBlcnJvclRleHQgPSAiRVJSX09DUl9MSUJfSU5JVCI7CisgICAgICBicmVhazsKKyAgICB9CisgICAgY2FzZSAtMTA3NDM5NTIxMDogeworICAgICAgZXJyb3JUZXh0ID0gIkVSUl9PQ1JfQ0FOTk9UX01BVENIX1RFWFRfVEVNUExBVEUiOworICAgICAgYnJlYWs7CisgICAgfQorICAgIGNhc2UgLTEwNzQzOTUyMTE6IHsKKyAgICAgIGVycm9yVGV4dCA9ICJFUlJfT0NSX0JBRF9URVhUX1RFTVBMQVRFIjsKKyAgICAgIGJyZWFrOworICAgIH0KKyAgICBjYXNlIC0xMDc0Mzk1MjEyOiB7CisgICAgICBlcnJvclRleHQgPSAiRVJSX09DUl9URU1QTEFURV9XUk9OR19TSVpFIjsKKyAgICAgIGJyZWFrOworICAgIH0KKyAgICBjYXNlIC0xMDc0Mzk1MjMzOiB7CisgICAgICBlcnJvclRleHQgPSAiRVJSX1RFTVBMQVRFX0lNQUdFX1RPT19MQVJHRSI7CisgICAgICBicmVhazsKKyAgICB9CisgICAgY2FzZSAtMTA3NDM5NTIzNDogeworICAgICAgZXJyb3JUZXh0ID0gIkVSUl9URU1QTEFURV9JTUFHRV9UT09fU01BTEwiOworICAgICAgYnJlYWs7CisgICAgfQorICAgIGNhc2UgLTEwNzQzOTUyMzU6IHsKKyAgICAgIGVycm9yVGV4dCA9ICJFUlJfVEVNUExBVEVfSU1BR0VfQ09OVFJBU1RfVE9PX0xPVyI7CisgICAgICBicmVhazsKKyAgICB9CisgICAgY2FzZSAtMTA3NDM5NTIzNzogeworICAgICAgZXJyb3JUZXh0ID0gIkVSUl9URU1QTEFURV9ERVNDUklQVE9SX1NISUZUXzEiOworICAgICAgYnJlYWs7CisgICAgfQorICAgIGNhc2UgLTEwNzQzOTUyMzg6IHsKKyAgICAgIGVycm9yVGV4dCA9ICJFUlJfVEVNUExBVEVfREVTQ1JJUFRPUl9OT1NISUZUIjsKKyAgICAgIGJyZWFrOworICAgIH0KKyAgICBjYXNlIC0xMDc0Mzk1MjM5OiB7CisgICAgICBlcnJvclRleHQgPSAiRVJSX1RFTVBMQVRFX0RFU0NSSVBUT1JfU0hJRlQiOworICAgICAgYnJlYWs7CisgICAgfQorICAgIGNhc2UgLTEwNzQzOTUyNDA6IHsKKyAgICAgIGVycm9yVGV4dCA9ICJFUlJfVEVNUExBVEVfREVTQ1JJUFRPUl9ST1RBVElPTl8xIjsKKyAgICAgIGJyZWFrOworICAgIH0KKyAgICBjYXNlIC0xMDc0Mzk1MjQxOiB7CisgICAgICBlcnJvclRleHQgPSAiRVJSX1RFTVBMQVRFX0RFU0NSSVBUT1JfTk9ST1RBVElPTiI7CisgICAgICBicmVhazsKKyAgICB9CisgICAgY2FzZSAtMTA3NDM5NTI0MjogeworICAgICAgZXJyb3JUZXh0ID0gIkVSUl9URU1QTEFURV9ERVNDUklQVE9SX1JPVEFUSU9OIjsKKyAgICAgIGJyZWFrOworICAgIH0KKyAgICBjYXNlIC0xMDc0Mzk1MjQzOiB7CisgICAgICBlcnJvclRleHQgPSAiRVJSX1RFTVBMQVRFX0RFU0NSSVBUT1JfNCI7CisgICAgICBicmVhazsKKyAgICB9CisgICAgY2FzZSAtMTA3NDM5NTI0NDogeworICAgICAgZXJyb3JUZXh0ID0gIkVSUl9URU1QTEFURV9ERVNDUklQVE9SXzMiOworICAgICAgYnJlYWs7CisgICAgfQorICAgIGNhc2UgLTEwNzQzOTUyNDU6IHsKKyAgICAgIGVycm9yVGV4dCA9ICJFUlJfVEVNUExBVEVfREVTQ1JJUFRPUl8yIjsKKyAgICAgIGJyZWFrOworICAgIH0KKyAgICBjYXNlIC0xMDc0Mzk1MjQ2OiB7CisgICAgICBlcnJvclRleHQgPSAiRVJSX1RFTVBMQVRFX0RFU0NSSVBUT1JfMSI7CisgICAgICBicmVhazsKKyAgICB9CisgICAgY2FzZSAtMTA3NDM5NTI0NzogeworICAgICAgZXJyb3JUZXh0ID0gIkVSUl9URU1QTEFURV9ERVNDUklQVE9SIjsKKyAgICAgIGJyZWFrOworICAgIH0KKyAgICBjYXNlIC0xMDc0Mzk1MjQ4OiB7CisgICAgICBlcnJvclRleHQgPSAiRVJSX1RPT19NQU5ZX1JPVEFUSU9OX0FOR0xFX1JBTkdFUyI7CisgICAgICBicmVhazsKKyAgICB9CisgICAgY2FzZSAtMTA3NDM5NTI0OTogeworICAgICAgZXJyb3JUZXh0ID0gIkVSUl9ST1RBVElPTl9BTkdMRV9SQU5HRV9UT09fTEFSR0UiOworICAgICAgYnJlYWs7CisgICAgfQorICAgIGNhc2UgLTEwNzQzOTUyNTA6IHsKKyAgICAgIGVycm9yVGV4dCA9ICJFUlJfTUFUQ0hfU0VUVVBfREFUQSI7CisgICAgICBicmVhazsKKyAgICB9CisgICAgY2FzZSAtMTA3NDM5NTI1MTogeworICAgICAgZXJyb3JUZXh0ID0gIkVSUl9JTlZBTElEX01BVENIX01PREUiOworICAgICAgYnJlYWs7CisgICAgfQorICAgIGNhc2UgLTEwNzQzOTUyNTI6IHsKKyAgICAgIGVycm9yVGV4dCA9ICJFUlJfTEVBUk5fU0VUVVBfREFUQSI7CisgICAgICBicmVhazsKKyAgICB9CisgICAgY2FzZSAtMTA3NDM5NTI1MzogeworICAgICAgZXJyb3JUZXh0ID0gIkVSUl9JTlZBTElEX0xFQVJOX01PREUiOworICAgICAgYnJlYWs7CisgICAgfQorICAgIGNhc2UgLTEwNzQzOTUyNTY6IHsKKyAgICAgIGVycm9yVGV4dCA9ICJFUlJfRVZFTl9XSU5ET1dfU0laRSI7CisgICAgICBicmVhazsKKyAgICB9CisgICAgY2FzZSAtMTA3NDM5NTI1NzogeworICAgICAgZXJyb3JUZXh0ID0gIkVSUl9JTlZBTElEX0VER0VfRElSIjsKKyAgICAgIGJyZWFrOworICAgIH0KKyAgICBjYXNlIC0xMDc0Mzk1MjU4OiB7CisgICAgICBlcnJvclRleHQgPSAiRVJSX0JBRF9GSUxURVJfV0lEVEgiOworICAgICAgYnJlYWs7CisgICAgfQorICAgIGNhc2UgLTEwNzQzOTUyNjA6IHsKKyAgICAgIGVycm9yVGV4dCA9ICJFUlJfSEVBUF9UUkFTSEVEIjsKKyAgICAgIGJyZWFrOworICAgIH0KKyAgICBjYXNlIC0xMDc0Mzk1MjYxOiB7CisgICAgICBlcnJvclRleHQgPSAiRVJSX0dJUF9SQU5HRSI7CisgICAgICBicmVhazsKKyAgICB9CisgICAgY2FzZSAtMTA3NDM5NTI2MjogeworICAgICAgZXJyb3JUZXh0ID0gIkVSUl9MQ0RfQkFEX01BVENIIjsKKyAgICAgIGJyZWFrOworICAgIH0KKyAgICBjYXNlIC0xMDc0Mzk1MjYzOiB7CisgICAgICBlcnJvclRleHQgPSAiRVJSX0xDRF9OT19TRUdNRU5UUyI7CisgICAgICBicmVhazsKKyAgICB9CisgICAgY2FzZSAtMTA3NDM5NTI2NTogeworICAgICAgZXJyb3JUZXh0ID0gIkVSUl9CQVJDT0RFIjsKKyAgICAgIGJyZWFrOworICAgIH0KKyAgICBjYXNlIC0xMDc0Mzk1MjY3OiB7CisgICAgICBlcnJvclRleHQgPSAiRVJSX0NPTVBMRVhfUk9PVCI7CisgICAgICBicmVhazsKKyAgICB9CisgICAgY2FzZSAtMTA3NDM5NTI2ODogeworICAgICAgZXJyb3JUZXh0ID0gIkVSUl9MSU5FQVJfQ09FRkYiOworICAgICAgYnJlYWs7CisgICAgfQorICAgIGNhc2UgLTEwNzQzOTUyNjk6IHsKKyAgICAgIGVycm9yVGV4dCA9ICJFUlJfbnVsbHB0cl9QT0lOVEVSIjsKKyAgICAgIGJyZWFrOworICAgIH0KKyAgICBjYXNlIC0xMDc0Mzk1MjcwOiB7CisgICAgICBlcnJvclRleHQgPSAiRVJSX0RJVl9CWV9aRVJPIjsKKyAgICAgIGJyZWFrOworICAgIH0KKyAgICBjYXNlIC0xMDc0Mzk1Mjc1OiB7CisgICAgICBlcnJvclRleHQgPSAiRVJSX0lOVkFMSURfQlJPV1NFUl9JTUFHRSI7CisgICAgICBicmVhazsKKyAgICB9CisgICAgY2FzZSAtMTA3NDM5NTI3NjogeworICAgICAgZXJyb3JUZXh0ID0gIkVSUl9MSU5FU19QQVJBTExFTCI7CisgICAgICBicmVhazsKKyAgICB9CisgICAgY2FzZSAtMTA3NDM5NTI3NzogeworICAgICAgZXJyb3JUZXh0ID0gIkVSUl9CQVJDT0RFX0NIRUNLU1VNIjsKKyAgICAgIGJyZWFrOworICAgIH0KKyAgICBjYXNlIC0xMDc0Mzk1Mjc4OiB7CisgICAgICBlcnJvclRleHQgPSAiRVJSX0xDRF9OT1RfTlVNRVJJQyI7CisgICAgICBicmVhazsKKyAgICB9CisgICAgY2FzZSAtMTA3NDM5NTI3OTogeworICAgICAgZXJyb3JUZXh0ID0gIkVSUl9ST0lfTk9UX1BPTFlHT04iOworICAgICAgYnJlYWs7CisgICAgfQorICAgIGNhc2UgLTEwNzQzOTUyODA6IHsKKyAgICAgIGVycm9yVGV4dCA9ICJFUlJfUk9JX05PVF9SRUNUIjsKKyAgICAgIGJyZWFrOworICAgIH0KKyAgICBjYXNlIC0xMDc0Mzk1MjgxOiB7CisgICAgICBlcnJvclRleHQgPSAiRVJSX0lNQUdFX1NNQUxMRVJfVEhBTl9CT1JERVIiOworICAgICAgYnJlYWs7CisgICAgfQorICAgIGNhc2UgLTEwNzQzOTUyODI6IHsKKyAgICAgIGVycm9yVGV4dCA9ICJFUlJfQ0FOVF9EUkFXX0lOVE9fVklFV0VSIjsKKyAgICAgIGJyZWFrOworICAgIH0KKyAgICBjYXNlIC0xMDc0Mzk1MjgzOiB7CisgICAgICBlcnJvclRleHQgPSAiRVJSX0lOVkFMSURfUkFLRV9ESVJFQ1RJT04iOworICAgICAgYnJlYWs7CisgICAgfQorICAgIGNhc2UgLTEwNzQzOTUyODQ6IHsKKyAgICAgIGVycm9yVGV4dCA9ICJFUlJfSU5WQUxJRF9FREdFX1BST0NFU1MiOworICAgICAgYnJlYWs7CisgICAgfQorICAgIGNhc2UgLTEwNzQzOTUyODU6IHsKKyAgICAgIGVycm9yVGV4dCA9ICJFUlJfSU5WQUxJRF9TUE9LRV9ESVJFQ1RJT04iOworICAgICAgYnJlYWs7CisgICAgfQorICAgIGNhc2UgLTEwNzQzOTUyODY6IHsKKyAgICAgIGVycm9yVGV4dCA9ICJFUlJfSU5WQUxJRF9DT05DRU5UUklDX1JBS0VfRElSRUNUSU9OIjsKKyAgICAgIGJyZWFrOworICAgIH0KKyAgICBjYXNlIC0xMDc0Mzk1Mjg3OiB7CisgICAgICBlcnJvclRleHQgPSAiRVJSX0lOVkFMSURfTElORSI7CisgICAgICBicmVhazsKKyAgICB9CisgICAgY2FzZSAtMTA3NDM5NTI5MDogeworICAgICAgZXJyb3JUZXh0ID0gIkVSUl9TSEFQRU1BVENIX0JBRFRFTVBMQVRFIjsKKyAgICAgIGJyZWFrOworICAgIH0KKyAgICBjYXNlIC0xMDc0Mzk1MjkxOiB7CisgICAgICBlcnJvclRleHQgPSAiRVJSX1NIQVBFTUFUQ0hfQkFESU1BR0VEQVRBIjsKKyAgICAgIGJyZWFrOworICAgIH0KKyAgICBjYXNlIC0xMDc0Mzk1MjkyOiB7CisgICAgICBlcnJvclRleHQgPSAiRVJSX1BPSU5UU19BUkVfQ09MTElORUFSIjsKKyAgICAgIGJyZWFrOworICAgIH0KKyAgICBjYXNlIC0xMDc0Mzk1MjkzOiB7CisgICAgICBlcnJvclRleHQgPSAiRVJSX0NPTlRPVVJJRF9OT1RfRk9VTkQiOworICAgICAgYnJlYWs7CisgICAgfQorICAgIGNhc2UgLTEwNzQzOTUyOTQ6IHsKKyAgICAgIGVycm9yVGV4dCA9ICJFUlJfQ09OVE9VUl9JTkRFWF9PVVRfT0ZfUkFOR0UiOworICAgICAgYnJlYWs7CisgICAgfQorICAgIGNhc2UgLTEwNzQzOTUyOTU6IHsKKyAgICAgIGVycm9yVGV4dCA9ICJFUlJfSU5WQUxJRF9JTlRFUlBPTEFUSU9OTUVUSE9EX0lOVEVSUE9MQVRFUE9JTlRTIjsKKyAgICAgIGJyZWFrOworICAgIH0KKyAgICBjYXNlIC0xMDc0Mzk1Mjk2OiB7CisgICAgICBlcnJvclRleHQgPSAiRVJSX0lOVkFMSURfQkFSQ09ERVRZUEUiOworICAgICAgYnJlYWs7CisgICAgfQorICAgIGNhc2UgLTEwNzQzOTUyOTc6IHsKKyAgICAgIGVycm9yVGV4dCA9ICJFUlJfSU5WQUxJRF9QQVJUSUNMRUlORk9NT0RFIjsKKyAgICAgIGJyZWFrOworICAgIH0KKyAgICBjYXNlIC0xMDc0Mzk1Mjk4OiB7CisgICAgICBlcnJvclRleHQgPSAiRVJSX0NPTVBMRVhQTEFORV9OT1RfUkVBTF9PUl9JTUFHSU5BUlkiOworICAgICAgYnJlYWs7CisgICAgfQorICAgIGNhc2UgLTEwNzQzOTUyOTk6IHsKKyAgICAgIGVycm9yVGV4dCA9ICJFUlJfSU5WQUxJRF9DT01QTEVYUExBTkUiOworICAgICAgYnJlYWs7CisgICAgfQorICAgIGNhc2UgLTEwNzQzOTUzMDA6IHsKKyAgICAgIGVycm9yVGV4dCA9ICJFUlJfSU5WQUxJRF9NRVRFUkFSQ01PREUiOworICAgICAgYnJlYWs7CisgICAgfQorICAgIGNhc2UgLTEwNzQzOTUzMDE6IHsKKyAgICAgIGVycm9yVGV4dCA9ICJFUlJfUk9JX05PVF8yX0xJTkVTIjsKKyAgICAgIGJyZWFrOworICAgIH0KKyAgICBjYXNlIC0xMDc0Mzk1MzAyOiB7CisgICAgICBlcnJvclRleHQgPSAiRVJSX0lOVkFMSURfVEhSRVNIT0xETUVUSE9EIjsKKyAgICAgIGJyZWFrOworICAgIH0KKyAgICBjYXNlIC0xMDc0Mzk1MzAzOiB7CisgICAgICBlcnJvclRleHQgPSAiRVJSX0lOVkFMSURfTlVNX09GX0NMQVNTRVMiOworICAgICAgYnJlYWs7CisgICAgfQorICAgIGNhc2UgLTEwNzQzOTUzMDQ6IHsKKyAgICAgIGVycm9yVGV4dCA9ICJFUlJfSU5WQUxJRF9NQVRIVFJBTlNGT1JNTUVUSE9EIjsKKyAgICAgIGJyZWFrOworICAgIH0KKyAgICBjYXNlIC0xMDc0Mzk1MzA1OiB7CisgICAgICBlcnJvclRleHQgPSAiRVJSX0lOVkFMSURfUkVGRVJFTkNFTU9ERSI7CisgICAgICBicmVhazsKKyAgICB9CisgICAgY2FzZSAtMTA3NDM5NTMwNjogeworICAgICAgZXJyb3JUZXh0ID0gIkVSUl9JTlZBTElEX1RPT0wiOworICAgICAgYnJlYWs7CisgICAgfQorICAgIGNhc2UgLTEwNzQzOTUzMDc6IHsKKyAgICAgIGVycm9yVGV4dCA9ICJFUlJfUFJFQ0lTSU9OX05PVF9HVFJfVEhBTl8wIjsKKyAgICAgIGJyZWFrOworICAgIH0KKyAgICBjYXNlIC0xMDc0Mzk1MzA4OiB7CisgICAgICBlcnJvclRleHQgPSAiRVJSX0lOVkFMSURfQ09MT1JTRU5TSVRJVklUWSI7CisgICAgICBicmVhazsKKyAgICB9CisgICAgY2FzZSAtMTA3NDM5NTMwOTogeworICAgICAgZXJyb3JUZXh0ID0gIkVSUl9JTlZBTElEX1dJTkRPV19USFJFQURfUE9MSUNZIjsKKyAgICAgIGJyZWFrOworICAgIH0KKyAgICBjYXNlIC0xMDc0Mzk1MzEwOiB7CisgICAgICBlcnJvclRleHQgPSAiRVJSX0lOVkFMSURfUEFMRVRURV9UWVBFIjsKKyAgICAgIGJyZWFrOworICAgIH0KKyAgICBjYXNlIC0xMDc0Mzk1MzExOiB7CisgICAgICBlcnJvclRleHQgPSAiRVJSX0lOVkFMSURfQ09MT1JfU1BFQ1RSVU0iOworICAgICAgYnJlYWs7CisgICAgfQorICAgIGNhc2UgLTEwNzQzOTUzMTI6IHsKKyAgICAgIGVycm9yVGV4dCA9ICJFUlJfTENEX0NBTElCUkFURSI7CisgICAgICBicmVhazsKKyAgICB9CisgICAgY2FzZSAtMTA3NDM5NTMxMzogeworICAgICAgZXJyb3JUZXh0ID0gIkVSUl9XUklURV9GSUxFX05PVF9TVVBQT1JURUQiOworICAgICAgYnJlYWs7CisgICAgfQorICAgIGNhc2UgLTEwNzQzOTUzMTY6IHsKKyAgICAgIGVycm9yVGV4dCA9ICJFUlJfSU5WQUxJRF9LRVJORUxfQ09ERSI7CisgICAgICBicmVhazsKKyAgICB9CisgICAgY2FzZSAtMTA3NDM5NTMxNzogeworICAgICAgZXJyb3JUZXh0ID0gIkVSUl9VTkRFRl9QT0lOVCI7CisgICAgICBicmVhazsKKyAgICB9CisgICAgY2FzZSAtMTA3NDM5NTMxODogeworICAgICAgZXJyb3JUZXh0ID0gIkVSUl9JTlNGX1BPSU5UUyI7CisgICAgICBicmVhazsKKyAgICB9CisgICAgY2FzZSAtMTA3NDM5NTMxOTogeworICAgICAgZXJyb3JUZXh0ID0gIkVSUl9JTlZBTElEX1NVQlBJWF9UWVBFIjsKKyAgICAgIGJyZWFrOworICAgIH0KKyAgICBjYXNlIC0xMDc0Mzk1MzIwOiB7CisgICAgICBlcnJvclRleHQgPSAiRVJSX1RFTVBMQVRFX0VNUFRZIjsKKyAgICAgIGJyZWFrOworICAgIH0KKyAgICBjYXNlIC0xMDc0Mzk1MzIxOiB7CisgICAgICBlcnJvclRleHQgPSAiRVJSX0lOVkFMSURfTU9SUEhPTE9HWU1FVEhPRCI7CisgICAgICBicmVhazsKKyAgICB9CisgICAgY2FzZSAtMTA3NDM5NTMyMjogeworICAgICAgZXJyb3JUZXh0ID0gIkVSUl9JTlZBTElEX1RFWFRBTElHTk1FTlQiOworICAgICAgYnJlYWs7CisgICAgfQorICAgIGNhc2UgLTEwNzQzOTUzMjM6IHsKKyAgICAgIGVycm9yVGV4dCA9ICJFUlJfSU5WQUxJRF9GT05UQ09MT1IiOworICAgICAgYnJlYWs7CisgICAgfQorICAgIGNhc2UgLTEwNzQzOTUzMjQ6IHsKKyAgICAgIGVycm9yVGV4dCA9ICJFUlJfSU5WQUxJRF9TSEFQRU1PREUiOworICAgICAgYnJlYWs7CisgICAgfQorICAgIGNhc2UgLTEwNzQzOTUzMjU6IHsKKyAgICAgIGVycm9yVGV4dCA9ICJFUlJfSU5WQUxJRF9EUkFXTU9ERSI7CisgICAgICBicmVhazsKKyAgICB9CisgICAgY2FzZSAtMTA3NDM5NTMyNjogeworICAgICAgZXJyb3JUZXh0ID0gIkVSUl9JTlZBTElEX0RSQVdNT0RFX0ZPUl9MSU5FIjsKKyAgICAgIGJyZWFrOworICAgIH0KKyAgICBjYXNlIC0xMDc0Mzk1MzI3OiB7CisgICAgICBlcnJvclRleHQgPSAiRVJSX0lOVkFMSURfU0NBTElOR01PREUiOworICAgICAgYnJlYWs7CisgICAgfQorICAgIGNhc2UgLTEwNzQzOTUzMjg6IHsKKyAgICAgIGVycm9yVGV4dCA9ICJFUlJfSU5WQUxJRF9JTlRFUlBPTEFUSU9OTUVUSE9EIjsKKyAgICAgIGJyZWFrOworICAgIH0KKyAgICBjYXNlIC0xMDc0Mzk1MzI5OiB7CisgICAgICBlcnJvclRleHQgPSAiRVJSX0lOVkFMSURfT1VUTElORU1FVEhPRCI7CisgICAgICBicmVhazsKKyAgICB9CisgICAgY2FzZSAtMTA3NDM5NTMzMDogeworICAgICAgZXJyb3JUZXh0ID0gIkVSUl9JTlZBTElEX0JPUkRFUl9TSVpFIjsKKyAgICAgIGJyZWFrOworICAgIH0KKyAgICBjYXNlIC0xMDc0Mzk1MzMxOiB7CisgICAgICBlcnJvclRleHQgPSAiRVJSX0lOVkFMSURfQk9SREVSTUVUSE9EIjsKKyAgICAgIGJyZWFrOworICAgIH0KKyAgICBjYXNlIC0xMDc0Mzk1MzMyOiB7CisgICAgICBlcnJvclRleHQgPSAiRVJSX0lOVkFMSURfQ09NUEFSRUZVTkNUSU9OIjsKKyAgICAgIGJyZWFrOworICAgIH0KKyAgICBjYXNlIC0xMDc0Mzk1MzMzOiB7CisgICAgICBlcnJvclRleHQgPSAiRVJSX0lOVkFMSURfVkVSVElDQUxfVEVYVF9BTElHTk1FTlQiOworICAgICAgYnJlYWs7CisgICAgfQorICAgIGNhc2UgLTEwNzQzOTUzMzQ6IHsKKyAgICAgIGVycm9yVGV4dCA9ICJFUlJfSU5WQUxJRF9DT05WRVJTSU9OU1RZTEUiOworICAgICAgYnJlYWs7CisgICAgfQorICAgIGNhc2UgLTEwNzQzOTUzMzU6IHsKKyAgICAgIGVycm9yVGV4dCA9ICJFUlJfRElTUEFUQ0hfU1RBVFVTX0NPTkZMSUNUIjsKKyAgICAgIGJyZWFrOworICAgIH0KKyAgICBjYXNlIC0xMDc0Mzk1MzM2OiB7CisgICAgICBlcnJvclRleHQgPSAiRVJSX1VOS05PV05fQUxHT1JJVEhNIjsKKyAgICAgIGJyZWFrOworICAgIH0KKyAgICBjYXNlIC0xMDc0Mzk1MzQwOiB7CisgICAgICBlcnJvclRleHQgPSAiRVJSX0lOVkFMSURfU0laRVRZUEUiOworICAgICAgYnJlYWs7CisgICAgfQorICAgIGNhc2UgLTEwNzQzOTUzNDM6IHsKKyAgICAgIGVycm9yVGV4dCA9ICJFUlJfRklMRV9GSUxFTkFNRV9udWxscHRyIjsKKyAgICAgIGJyZWFrOworICAgIH0KKyAgICBjYXNlIC0xMDc0Mzk1MzQ1OiB7CisgICAgICBlcnJvclRleHQgPSAiRVJSX0lOVkFMSURfRkxJUEFYSVMiOworICAgICAgYnJlYWs7CisgICAgfQorICAgIGNhc2UgLTEwNzQzOTUzNDY6IHsKKyAgICAgIGVycm9yVGV4dCA9ICJFUlJfSU5WQUxJRF9JTlRFUlBPTEFUSU9OTUVUSE9EX0ZPUl9ST1RBVEUiOworICAgICAgYnJlYWs7CisgICAgfQorICAgIGNhc2UgLTEwNzQzOTUzNDc6IHsKKyAgICAgIGVycm9yVGV4dCA9ICJFUlJfSU5WQUxJRF8zRERJUkVDVElPTiI7CisgICAgICBicmVhazsKKyAgICB9CisgICAgY2FzZSAtMTA3NDM5NTM0ODogeworICAgICAgZXJyb3JUZXh0ID0gIkVSUl9JTlZBTElEXzNEUExBTkUiOworICAgICAgYnJlYWs7CisgICAgfQorICAgIGNhc2UgLTEwNzQzOTUzNDk6IHsKKyAgICAgIGVycm9yVGV4dCA9ICJFUlJfSU5WQUxJRF9TS0VMRVRPTk1FVEhPRCI7CisgICAgICBicmVhazsKKyAgICB9CisgICAgY2FzZSAtMTA3NDM5NTM1MDogeworICAgICAgZXJyb3JUZXh0ID0gIkVSUl9JTlZBTElEX1ZJU0lPTl9JTkZPIjsKKyAgICAgIGJyZWFrOworICAgIH0KKyAgICBjYXNlIC0xMDc0Mzk1MzUxOiB7CisgICAgICBlcnJvclRleHQgPSAiRVJSX0lOVkFMSURfUkVDVCI7CisgICAgICBicmVhazsKKyAgICB9CisgICAgY2FzZSAtMTA3NDM5NTM1MjogeworICAgICAgZXJyb3JUZXh0ID0gIkVSUl9JTlZBTElEX0ZFQVRVUkVfTU9ERSI7CisgICAgICBicmVhazsKKyAgICB9CisgICAgY2FzZSAtMTA3NDM5NTM1MzogeworICAgICAgZXJyb3JUZXh0ID0gIkVSUl9JTlZBTElEX1NFQVJDSF9TVFJBVEVHWSI7CisgICAgICBicmVhazsKKyAgICB9CisgICAgY2FzZSAtMTA3NDM5NTM1NDogeworICAgICAgZXJyb3JUZXh0ID0gIkVSUl9JTlZBTElEX0NPTE9SX1dFSUdIVCI7CisgICAgICBicmVhazsKKyAgICB9CisgICAgY2FzZSAtMTA3NDM5NTM1NTogeworICAgICAgZXJyb3JUZXh0ID0gIkVSUl9JTlZBTElEX05VTV9NQVRDSEVTX1JFUVVFU1RFRCI7CisgICAgICBicmVhazsKKyAgICB9CisgICAgY2FzZSAtMTA3NDM5NTM1NjogeworICAgICAgZXJyb3JUZXh0ID0gIkVSUl9JTlZBTElEX01JTl9NQVRDSF9TQ09SRSI7CisgICAgICBicmVhazsKKyAgICB9CisgICAgY2FzZSAtMTA3NDM5NTM1NzogeworICAgICAgZXJyb3JUZXh0ID0gIkVSUl9JTlZBTElEX0NPTE9SX0lHTk9SRV9NT0RFIjsKKyAgICAgIGJyZWFrOworICAgIH0KKyAgICBjYXNlIC0xMDc0Mzk1MzYwOiB7CisgICAgICBlcnJvclRleHQgPSAiRVJSX0NPTVBMRVhfUExBTkUiOworICAgICAgYnJlYWs7CisgICAgfQorICAgIGNhc2UgLTEwNzQzOTUzNjE6IHsKKyAgICAgIGVycm9yVGV4dCA9ICJFUlJfSU5WQUxJRF9TVEVFUE5FU1MiOworICAgICAgYnJlYWs7CisgICAgfQorICAgIGNhc2UgLTEwNzQzOTUzNjI6IHsKKyAgICAgIGVycm9yVGV4dCA9ICJFUlJfSU5WQUxJRF9XSURUSCI7CisgICAgICBicmVhazsKKyAgICB9CisgICAgY2FzZSAtMTA3NDM5NTM2MzogeworICAgICAgZXJyb3JUZXh0ID0gIkVSUl9JTlZBTElEX1NVQlNBTVBMSU5HX1JBVElPIjsKKyAgICAgIGJyZWFrOworICAgIH0KKyAgICBjYXNlIC0xMDc0Mzk1MzY0OiB7CisgICAgICBlcnJvclRleHQgPSAiRVJSX0lHTk9SRV9DT0xPUl9TUEVDVFJVTV9TRVQiOworICAgICAgYnJlYWs7CisgICAgfQorICAgIGNhc2UgLTEwNzQzOTUzNjU6IHsKKyAgICAgIGVycm9yVGV4dCA9ICJFUlJfQ09MT1JfVEVNUExBVEVfREVTQ1JJUFRPUl9OT1NQRUNUUlVNIjsKKyAgICAgIGJyZWFrOworICAgIH0KKyAgICBjYXNlIC0xMDc0Mzk1MzY2OiB7CisgICAgICBlcnJvclRleHQgPSAiRVJSX0NPTE9SX1RFTVBMQVRFX0RFU0NSSVBUT1JfTk9TSEFQRSI7CisgICAgICBicmVhazsKKyAgICB9CisgICAgY2FzZSAtMTA3NDM5NTM2NzogeworICAgICAgZXJyb3JUZXh0ID0gIkVSUl9DT0xPUl9URU1QTEFURV9ERVNDUklQVE9SX1JPVEFUSU9OXzUiOworICAgICAgYnJlYWs7CisgICAgfQorICAgIGNhc2UgLTEwNzQzOTUzNjg6IHsKKyAgICAgIGVycm9yVGV4dCA9ICJFUlJfQ09MT1JfVEVNUExBVEVfREVTQ1JJUFRPUl9ST1RBVElPTl80IjsKKyAgICAgIGJyZWFrOworICAgIH0KKyAgICBjYXNlIC0xMDc0Mzk1MzY5OiB7CisgICAgICBlcnJvclRleHQgPSAiRVJSX0NPTE9SX1RFTVBMQVRFX0RFU0NSSVBUT1JfUk9UQVRJT05fMyI7CisgICAgICBicmVhazsKKyAgICB9CisgICAgY2FzZSAtMTA3NDM5NTM3MDogeworICAgICAgZXJyb3JUZXh0ID0gIkVSUl9DT0xPUl9URU1QTEFURV9ERVNDUklQVE9SX1JPVEFUSU9OXzIiOworICAgICAgYnJlYWs7CisgICAgfQorICAgIGNhc2UgLTEwNzQzOTUzNzE6IHsKKyAgICAgIGVycm9yVGV4dCA9ICJFUlJfQ09MT1JfVEVNUExBVEVfREVTQ1JJUFRPUl9ST1RBVElPTl8xIjsKKyAgICAgIGJyZWFrOworICAgIH0KKyAgICBjYXNlIC0xMDc0Mzk1MzcyOiB7CisgICAgICBlcnJvclRleHQgPSAiRVJSX0NPTE9SX1RFTVBMQVRFX0RFU0NSSVBUT1JfTk9ST1RBVElPTiI7CisgICAgICBicmVhazsKKyAgICB9CisgICAgY2FzZSAtMTA3NDM5NTM3MzogeworICAgICAgZXJyb3JUZXh0ID0gIkVSUl9DT0xPUl9URU1QTEFURV9ERVNDUklQVE9SX1JPVEFUSU9OIjsKKyAgICAgIGJyZWFrOworICAgIH0KKyAgICBjYXNlIC0xMDc0Mzk1Mzc0OiB7CisgICAgICBlcnJvclRleHQgPSAiRVJSX0NPTE9SX1RFTVBMQVRFX0RFU0NSSVBUT1JfU0hJRlRfMiI7CisgICAgICBicmVhazsKKyAgICB9CisgICAgY2FzZSAtMTA3NDM5NTM3NTogeworICAgICAgZXJyb3JUZXh0ID0gIkVSUl9DT0xPUl9URU1QTEFURV9ERVNDUklQVE9SX1NISUZUXzEiOworICAgICAgYnJlYWs7CisgICAgfQorICAgIGNhc2UgLTEwNzQzOTUzNzY6IHsKKyAgICAgIGVycm9yVGV4dCA9ICJFUlJfQ09MT1JfVEVNUExBVEVfREVTQ1JJUFRPUl9OT1NISUZUIjsKKyAgICAgIGJyZWFrOworICAgIH0KKyAgICBjYXNlIC0xMDc0Mzk1Mzc3OiB7CisgICAgICBlcnJvclRleHQgPSAiRVJSX0NPTE9SX1RFTVBMQVRFX0RFU0NSSVBUT1JfU0hJRlQiOworICAgICAgYnJlYWs7CisgICAgfQorICAgIGNhc2UgLTEwNzQzOTUzNzg6IHsKKyAgICAgIGVycm9yVGV4dCA9ICJFUlJfQ09MT1JfVEVNUExBVEVfREVTQ1JJUFRPUl82IjsKKyAgICAgIGJyZWFrOworICAgIH0KKyAgICBjYXNlIC0xMDc0Mzk1Mzc5OiB7CisgICAgICBlcnJvclRleHQgPSAiRVJSX0NPTE9SX1RFTVBMQVRFX0RFU0NSSVBUT1JfNSI7CisgICAgICBicmVhazsKKyAgICB9CisgICAgY2FzZSAtMTA3NDM5NTM4MDogeworICAgICAgZXJyb3JUZXh0ID0gIkVSUl9DT0xPUl9URU1QTEFURV9ERVNDUklQVE9SXzQiOworICAgICAgYnJlYWs7CisgICAgfQorICAgIGNhc2UgLTEwNzQzOTUzODE6IHsKKyAgICAgIGVycm9yVGV4dCA9ICJFUlJfQ09MT1JfVEVNUExBVEVfREVTQ1JJUFRPUl8zIjsKKyAgICAgIGJyZWFrOworICAgIH0KKyAgICBjYXNlIC0xMDc0Mzk1MzgyOiB7CisgICAgICBlcnJvclRleHQgPSAiRVJSX0NPTE9SX1RFTVBMQVRFX0RFU0NSSVBUT1JfMiI7CisgICAgICBicmVhazsKKyAgICB9CisgICAgY2FzZSAtMTA3NDM5NTM4MzogeworICAgICAgZXJyb3JUZXh0ID0gIkVSUl9DT0xPUl9URU1QTEFURV9ERVNDUklQVE9SXzEiOworICAgICAgYnJlYWs7CisgICAgfQorICAgIGNhc2UgLTEwNzQzOTUzODQ6IHsKKyAgICAgIGVycm9yVGV4dCA9ICJFUlJfQ09MT1JfVEVNUExBVEVfREVTQ1JJUFRPUiI7CisgICAgICBicmVhazsKKyAgICB9CisgICAgY2FzZSAtMTA3NDM5NTM4NTogeworICAgICAgZXJyb3JUZXh0ID0gIkVSUl9DT0xPUl9ST1RBVElPTl9SRVFVSVJFU19TSEFQRV9GRUFUVVJFIjsKKyAgICAgIGJyZWFrOworICAgIH0KKyAgICBjYXNlIC0xMDc0Mzk1Mzg2OiB7CisgICAgICBlcnJvclRleHQgPSAiRVJSX0NPTE9SX01BVENIX1NFVFVQX0RBVEFfU0hBUEUiOworICAgICAgYnJlYWs7CisgICAgfQorICAgIGNhc2UgLTEwNzQzOTUzODc6IHsKKyAgICAgIGVycm9yVGV4dCA9ICJFUlJfQ09MT1JfTUFUQ0hfU0VUVVBfREFUQSI7CisgICAgICBicmVhazsKKyAgICB9CisgICAgY2FzZSAtMTA3NDM5NTM4ODogeworICAgICAgZXJyb3JUZXh0ID0gIkVSUl9DT0xPUl9MRUFSTl9TRVRVUF9EQVRBX1NIQVBFIjsKKyAgICAgIGJyZWFrOworICAgIH0KKyAgICBjYXNlIC0xMDc0Mzk1Mzg5OiB7CisgICAgICBlcnJvclRleHQgPSAiRVJSX0NPTE9SX0xFQVJOX1NFVFVQX0RBVEEiOworICAgICAgYnJlYWs7CisgICAgfQorICAgIGNhc2UgLTEwNzQzOTUzOTA6IHsKKyAgICAgIGVycm9yVGV4dCA9ICJFUlJfQ09MT1JfVEVNUExBVEVfSU1BR0VfTFVNSU5BTkNFX0NPTlRSQVNUX1RPT19MT1ciOworICAgICAgYnJlYWs7CisgICAgfQorICAgIGNhc2UgLTEwNzQzOTUzOTE6IHsKKyAgICAgIGVycm9yVGV4dCA9ICJFUlJfQ09MT1JfVEVNUExBVEVfSU1BR0VfSFVFX0NPTlRSQVNUX1RPT19MT1ciOworICAgICAgYnJlYWs7CisgICAgfQorICAgIGNhc2UgLTEwNzQzOTUzOTI6IHsKKyAgICAgIGVycm9yVGV4dCA9ICJFUlJfQ09MT1JfVEVNUExBVEVfSU1BR0VfVE9PX0xBUkdFIjsKKyAgICAgIGJyZWFrOworICAgIH0KKyAgICBjYXNlIC0xMDc0Mzk1MzkzOiB7CisgICAgICBlcnJvclRleHQgPSAiRVJSX0NPTE9SX1RFTVBMQVRFX0lNQUdFX1RPT19TTUFMTCI7CisgICAgICBicmVhazsKKyAgICB9CisgICAgY2FzZSAtMTA3NDM5NTM5NDogeworICAgICAgZXJyb3JUZXh0ID0gIkVSUl9DT0xPUl9TUEVDVFJVTV9NQVNLIjsKKyAgICAgIGJyZWFrOworICAgIH0KKyAgICBjYXNlIC0xMDc0Mzk1Mzk1OiB7CisgICAgICBlcnJvclRleHQgPSAiRVJSX0NPTE9SX0lNQUdFX1JFUVVJUkVEIjsKKyAgICAgIGJyZWFrOworICAgIH0KKyAgICBjYXNlIC0xMDc0Mzk1Mzk3OiB7CisgICAgICBlcnJvclRleHQgPSAiRVJSX0NPTVBMRVhfSU1BR0VfUkVRVUlSRUQiOworICAgICAgYnJlYWs7CisgICAgfQorICAgIGNhc2UgLTEwNzQzOTUzOTk6IHsKKyAgICAgIGVycm9yVGV4dCA9ICJFUlJfTVVMVElDT1JFX0lOVkFMSURfQVJHVU1FTlQiOworICAgICAgYnJlYWs7CisgICAgfQorICAgIGNhc2UgLTEwNzQzOTU0MDA6IHsKKyAgICAgIGVycm9yVGV4dCA9ICJFUlJfTVVMVElDT1JFX09QRVJBVElPTiI7CisgICAgICBicmVhazsKKyAgICB9CisgICAgY2FzZSAtMTA3NDM5NTQwMTogeworICAgICAgZXJyb3JUZXh0ID0gIkVSUl9JTlZBTElEX01BVENIRkFDVE9SIjsKKyAgICAgIGJyZWFrOworICAgIH0KKyAgICBjYXNlIC0xMDc0Mzk1NDAyOiB7CisgICAgICBlcnJvclRleHQgPSAiRVJSX0lOVkFMSURfTUFYUE9JTlRTIjsKKyAgICAgIGJyZWFrOworICAgIH0KKyAgICBjYXNlIC0xMDc0Mzk1NDAzOiB7CisgICAgICBlcnJvclRleHQgPSAiRVJSX0VYVFJBSU5GT19WRVJTSU9OIjsKKyAgICAgIGJyZWFrOworICAgIH0KKyAgICBjYXNlIC0xMDc0Mzk1NDA0OiB7CisgICAgICBlcnJvclRleHQgPSAiRVJSX0lOVkFMSURfSU5URVJQT0xBVElPTk1FVEhPRF9GT1JfVU5XUkFQIjsKKyAgICAgIGJyZWFrOworICAgIH0KKyAgICBjYXNlIC0xMDc0Mzk1NDA1OiB7CisgICAgICBlcnJvclRleHQgPSAiRVJSX0lOVkFMSURfVEVYVE9SSUVOVEFUSU9OIjsKKyAgICAgIGJyZWFrOworICAgIH0KKyAgICBjYXNlIC0xMDc0Mzk1NDA2OiB7CisgICAgICBlcnJvclRleHQgPSAiRVJSX0NPT1JEU1lTX05PVF9GT1VORCI7CisgICAgICBicmVhazsKKyAgICB9CisgICAgY2FzZSAtMTA3NDM5NTQwNzogeworICAgICAgZXJyb3JUZXh0ID0gIkVSUl9JTlZBTElEX0NPTlRSQVNUIjsKKyAgICAgIGJyZWFrOworICAgIH0KKyAgICBjYXNlIC0xMDc0Mzk1NDA4OiB7CisgICAgICBlcnJvclRleHQgPSAiRVJSX0lOVkFMSURfREVURUNUSU9OX01PREUiOworICAgICAgYnJlYWs7CisgICAgfQorICAgIGNhc2UgLTEwNzQzOTU0MDk6IHsKKyAgICAgIGVycm9yVGV4dCA9ICJFUlJfSU5WQUxJRF9TVUJQSVhFTF9ESVZJU0lPTlMiOworICAgICAgYnJlYWs7CisgICAgfQorICAgIGNhc2UgLTEwNzQzOTU0MTA6IHsKKyAgICAgIGVycm9yVGV4dCA9ICJFUlJfSU5WQUxJRF9JQ09OU19QRVJfTElORSI7CisgICAgICBicmVhazsKKyAgICB9CisgICAgY2FzZSAtMTA3NDM5NTU0OTogeworICAgICAgZXJyb3JUZXh0ID0gIkVSUl9OSU9DUl9JTlZBTElEX05VTUJFUl9PRl9PQkpFQ1RTX1RPX1ZFUklGWSI7CisgICAgICBicmVhazsKKyAgICB9CisgICAgY2FzZSAtMTA3NDM5NTU1MDogeworICAgICAgZXJyb3JUZXh0ID0gIkVSUl9OSU9DUl9JTlZBTElEX0NIQVJBQ1RFUl9WQUxVRSI7CisgICAgICBicmVhazsKKyAgICB9CisgICAgY2FzZSAtMTA3NDM5NTU1MTogeworICAgICAgZXJyb3JUZXh0ID0gIkVSUl9OSU9DUl9SRU5BTUVfUkVGQ0hBUiI7CisgICAgICBicmVhazsKKyAgICB9CisgICAgY2FzZSAtMTA3NDM5NTU1MjogeworICAgICAgZXJyb3JUZXh0ID0gIkVSUl9OSU9DUl9OT1RfQV9WQUxJRF9DSEFSQUNURVJfU0VUIjsKKyAgICAgIGJyZWFrOworICAgIH0KKyAgICBjYXNlIC0xMDc0Mzk1NTUzOiB7CisgICAgICBlcnJvclRleHQgPSAiRVJSX05JT0NSX0lOVkFMSURfTUlOX0JPVU5ESU5HX1JFQ1RfSEVJR0hUIjsKKyAgICAgIGJyZWFrOworICAgIH0KKyAgICBjYXNlIC0xMDc0Mzk1NTU0OiB7CisgICAgICBlcnJvclRleHQgPSAiRVJSX05JT0NSX0lOVkFMSURfUkVBRF9SRVNPTFVUSU9OIjsKKyAgICAgIGJyZWFrOworICAgIH0KKyAgICBjYXNlIC0xMDc0Mzk1NTU1OiB7CisgICAgICBlcnJvclRleHQgPSAiRVJSX05JT0NSX0lOVkFMSURfU1BBQ0lOR19SQU5HRSI7CisgICAgICBicmVhazsKKyAgICB9CisgICAgY2FzZSAtMTA3NDM5NTU1NjogeworICAgICAgZXJyb3JUZXh0ID0gIkVSUl9OSU9DUl9JTlZBTElEX0JPVU5ESU5HX1JFQ1RfSEVJR0hUX1JBTkdFIjsKKyAgICAgIGJyZWFrOworICAgIH0KKyAgICBjYXNlIC0xMDc0Mzk1NTU3OiB7CisgICAgICBlcnJvclRleHQgPSAiRVJSX05JT0NSX0lOVkFMSURfQk9VTkRJTkdfUkVDVF9XSURUSF9SQU5HRSI7CisgICAgICBicmVhazsKKyAgICB9CisgICAgY2FzZSAtMTA3NDM5NTU1ODogeworICAgICAgZXJyb3JUZXh0ID0gIkVSUl9OSU9DUl9JTlZBTElEX0NIQVJBQ1RFUl9TSVpFX1JBTkdFIjsKKyAgICAgIGJyZWFrOworICAgIH0KKyAgICBjYXNlIC0xMDc0Mzk1NTU5OiB7CisgICAgICBlcnJvclRleHQgPSAiRVJSX05JT0NSX0lOVkFMSURfUkVBRF9PUFRJT04iOworICAgICAgYnJlYWs7CisgICAgfQorICAgIGNhc2UgLTEwNzQzOTU1NjA6IHsKKyAgICAgIGVycm9yVGV4dCA9ICJFUlJfTklPQ1JfSU5WQUxJRF9PQkpFQ1RfSU5ERVgiOworICAgICAgYnJlYWs7CisgICAgfQorICAgIGNhc2UgLTEwNzQzOTU1NjE6IHsKKyAgICAgIGVycm9yVGV4dCA9ICJFUlJfTklPQ1JfSU5WQUxJRF9OVU1CRVJfT0ZfQ0hBUkFDVEVSUyI7CisgICAgICBicmVhazsKKyAgICB9CisgICAgY2FzZSAtMTA3NDM5NTU2MjogeworICAgICAgZXJyb3JUZXh0ID0gIkVSUl9OSU9DUl9CT09MRUFOX1ZBTFVFX0ZPUl9TVFJJTkdfQVRUUklCVVRFIjsKKyAgICAgIGJyZWFrOworICAgIH0KKyAgICBjYXNlIC0xMDc0Mzk1NTYzOiB7CisgICAgICBlcnJvclRleHQgPSAiRVJSX05JT0NSX1VOTElDRU5TRUQiOworICAgICAgYnJlYWs7CisgICAgfQorICAgIGNhc2UgLTEwNzQzOTU1NjQ6IHsKKyAgICAgIGVycm9yVGV4dCA9ICJFUlJfTklPQ1JfSU5WQUxJRF9QUkVERUZJTkVEX0NIQVJBQ1RFUiI7CisgICAgICBicmVhazsKKyAgICB9CisgICAgY2FzZSAtMTA3NDM5NTU2NTogeworICAgICAgZXJyb3JUZXh0ID0gIkVSUl9OSU9DUl9NVVNUX0JFX1NJTkdMRV9DSEFSQUNURVIiOworICAgICAgYnJlYWs7CisgICAgfQorICAgIGNhc2UgLTEwNzQzOTU1NjY6IHsKKyAgICAgIGVycm9yVGV4dCA9ICJFUlJfTklPQ1JfQk9PTEVBTl9WQUxVRV9GT1JfSU5URUdFUl9BVFRSSUJVVEUiOworICAgICAgYnJlYWs7CisgICAgfQorICAgIGNhc2UgLTEwNzQzOTU1Njc6IHsKKyAgICAgIGVycm9yVGV4dCA9ICJFUlJfTklPQ1JfU1RSSU5HX1ZBTFVFX0ZPUl9CT09MRUFOX0FUVFJJQlVURSI7CisgICAgICBicmVhazsKKyAgICB9CisgICAgY2FzZSAtMTA3NDM5NTU2ODogeworICAgICAgZXJyb3JUZXh0ID0gIkVSUl9OSU9DUl9TVFJJTkdfVkFMVUVfRk9SX0lOVEVHRVJfQVRUUklCVVRFIjsKKyAgICAgIGJyZWFrOworICAgIH0KKyAgICBjYXNlIC0xMDc0Mzk1NTY5OiB7CisgICAgICBlcnJvclRleHQgPSAiRVJSX05JT0NSX0lOVkFMSURfQVRUUklCVVRFIjsKKyAgICAgIGJyZWFrOworICAgIH0KKyAgICBjYXNlIC0xMDc0Mzk1NTcwOiB7CisgICAgICBlcnJvclRleHQgPSAiRVJSX05JT0NSX0lOVEVHRVJfVkFMVUVfRk9SX0JPT0xFQU5fQVRUUklCVVRFIjsKKyAgICAgIGJyZWFrOworICAgIH0KKyAgICBjYXNlIC0xMDc0Mzk1NTcxOiB7CisgICAgICBlcnJvclRleHQgPSAiRVJSX05JT0NSX0dFVF9PTkxZX0FUVFJJQlVURSI7CisgICAgICBicmVhazsKKyAgICB9CisgICAgY2FzZSAtMTA3NDM5NTU3MjogeworICAgICAgZXJyb3JUZXh0ID0gIkVSUl9OSU9DUl9JTlRFR0VSX1ZBTFVFX0ZPUl9TVFJJTkdfQVRUUklCVVRFIjsKKyAgICAgIGJyZWFrOworICAgIH0KKyAgICBjYXNlIC0xMDc0Mzk1NTczOiB7CisgICAgICBlcnJvclRleHQgPSAiRVJSX05JT0NSX0lOVkFMSURfQ0hBUkFDVEVSX1NFVF9GSUxFX1ZFUlNJT04iOworICAgICAgYnJlYWs7CisgICAgfQorICAgIGNhc2UgLTEwNzQzOTU1NzQ6IHsKKyAgICAgIGVycm9yVGV4dCA9ICJFUlJfTklPQ1JfQ0hBUkFDVEVSX1NFVF9ERVNDUklQVElPTl9UT09fTE9ORyI7CisgICAgICBicmVhazsKKyAgICB9CisgICAgY2FzZSAtMTA3NDM5NTU3NTogeworICAgICAgZXJyb3JUZXh0ID0gIkVSUl9OSU9DUl9JTlZBTElEX05VTUJFUl9PRl9FUk9TSU9OUyI7CisgICAgICBicmVhazsKKyAgICB9CisgICAgY2FzZSAtMTA3NDM5NTU3NjogeworICAgICAgZXJyb3JUZXh0ID0gIkVSUl9OSU9DUl9DSEFSQUNURVJfVkFMVUVfVE9PX0xPTkciOworICAgICAgYnJlYWs7CisgICAgfQorICAgIGNhc2UgLTEwNzQzOTU1Nzc6IHsKKyAgICAgIGVycm9yVGV4dCA9ICJFUlJfTklPQ1JfQ0hBUkFDVEVSX1ZBTFVFX0NBTk5PVF9CRV9FTVBUWVNUUklORyI7CisgICAgICBicmVhazsKKyAgICB9CisgICAgY2FzZSAtMTA3NDM5NTU3ODogeworICAgICAgZXJyb3JUZXh0ID0gIkVSUl9OSU9DUl9JTlZBTElEX0NIQVJBQ1RFUl9TRVRfRklMRSI7CisgICAgICBicmVhazsKKyAgICB9CisgICAgY2FzZSAtMTA3NDM5NTU3OTogeworICAgICAgZXJyb3JUZXh0ID0gIkVSUl9OSU9DUl9JTlZBTElEX0FTUEVDVF9SQVRJTyI7CisgICAgICBicmVhazsKKyAgICB9CisgICAgY2FzZSAtMTA3NDM5NTU4MDogeworICAgICAgZXJyb3JUZXh0ID0gIkVSUl9OSU9DUl9JTlZBTElEX01JTl9CT1VORElOR19SRUNUX1dJRFRIIjsKKyAgICAgIGJyZWFrOworICAgIH0KKyAgICBjYXNlIC0xMDc0Mzk1NTgxOiB7CisgICAgICBlcnJvclRleHQgPSAiRVJSX05JT0NSX0lOVkFMSURfTUFYX1ZFUlRfRUxFTUVOVF9TUEFDSU5HIjsKKyAgICAgIGJyZWFrOworICAgIH0KKyAgICBjYXNlIC0xMDc0Mzk1NTgyOiB7CisgICAgICBlcnJvclRleHQgPSAiRVJSX05JT0NSX0lOVkFMSURfTUFYX0hPUklaX0VMRU1FTlRfU1BBQ0lORyI7CisgICAgICBicmVhazsKKyAgICB9CisgICAgY2FzZSAtMTA3NDM5NTU4MzogeworICAgICAgZXJyb3JUZXh0ID0gIkVSUl9OSU9DUl9JTlZBTElEX01JTl9DSEFSX1NQQUNJTkciOworICAgICAgYnJlYWs7CisgICAgfQorICAgIGNhc2UgLTEwNzQzOTU1ODQ6IHsKKyAgICAgIGVycm9yVGV4dCA9ICJFUlJfTklPQ1JfSU5WQUxJRF9USFJFU0hPTERfTElNSVRTIjsKKyAgICAgIGJyZWFrOworICAgIH0KKyAgICBjYXNlIC0xMDc0Mzk1NTg1OiB7CisgICAgICBlcnJvclRleHQgPSAiRVJSX05JT0NSX0lOVkFMSURfVVBQRVJfVEhSRVNIT0xEX0xJTUlUIjsKKyAgICAgIGJyZWFrOworICAgIH0KKyAgICBjYXNlIC0xMDc0Mzk1NTg2OiB7CisgICAgICBlcnJvclRleHQgPSAiRVJSX05JT0NSX0lOVkFMSURfTE9XRVJfVEhSRVNIT0xEX0xJTUlUIjsKKyAgICAgIGJyZWFrOworICAgIH0KKyAgICBjYXNlIC0xMDc0Mzk1NTg3OiB7CisgICAgICBlcnJvclRleHQgPSAiRVJSX05JT0NSX0lOVkFMSURfVEhSRVNIT0xEX1JBTkdFIjsKKyAgICAgIGJyZWFrOworICAgIH0KKyAgICBjYXNlIC0xMDc0Mzk1NTg4OiB7CisgICAgICBlcnJvclRleHQgPSAiRVJSX05JT0NSX0lOVkFMSURfSElHSF9USFJFU0hPTERfVkFMVUUiOworICAgICAgYnJlYWs7CisgICAgfQorICAgIGNhc2UgLTEwNzQzOTU1ODk6IHsKKyAgICAgIGVycm9yVGV4dCA9ICJFUlJfTklPQ1JfSU5WQUxJRF9MT1dfVEhSRVNIT0xEX1ZBTFVFIjsKKyAgICAgIGJyZWFrOworICAgIH0KKyAgICBjYXNlIC0xMDc0Mzk1NTkwOiB7CisgICAgICBlcnJvclRleHQgPSAiRVJSX05JT0NSX0lOVkFMSURfTlVNQkVSX09GX1ZBTElEX0NIQVJBQ1RFUl9QT1NJVElPTlMiOworICAgICAgYnJlYWs7CisgICAgfQorICAgIGNhc2UgLTEwNzQzOTU1OTE6IHsKKyAgICAgIGVycm9yVGV4dCA9ICJFUlJfTklPQ1JfSU5WQUxJRF9DSEFSQUNURVJfSU5ERVgiOworICAgICAgYnJlYWs7CisgICAgfQorICAgIGNhc2UgLTEwNzQzOTU1OTI6IHsKKyAgICAgIGVycm9yVGV4dCA9ICJFUlJfTklPQ1JfSU5WQUxJRF9SRUFEX1NUUkFURUdZIjsKKyAgICAgIGJyZWFrOworICAgIH0KKyAgICBjYXNlIC0xMDc0Mzk1NTkzOiB7CisgICAgICBlcnJvclRleHQgPSAiRVJSX05JT0NSX0lOVkFMSURfTlVNQkVSX09GX0JMT0NLUyI7CisgICAgICBicmVhazsKKyAgICB9CisgICAgY2FzZSAtMTA3NDM5NTU5NDogeworICAgICAgZXJyb3JUZXh0ID0gIkVSUl9OSU9DUl9JTlZBTElEX1NVQlNUSVRVVElPTl9DSEFSQUNURVIiOworICAgICAgYnJlYWs7CisgICAgfQorICAgIGNhc2UgLTEwNzQzOTU1OTU6IHsKKyAgICAgIGVycm9yVGV4dCA9ICJFUlJfTklPQ1JfSU5WQUxJRF9USFJFU0hPTERfTU9ERSI7CisgICAgICBicmVhazsKKyAgICB9CisgICAgY2FzZSAtMTA3NDM5NTU5NjogeworICAgICAgZXJyb3JUZXh0ID0gIkVSUl9OSU9DUl9JTlZBTElEX0NIQVJBQ1RFUl9TSVpFIjsKKyAgICAgIGJyZWFrOworICAgIH0KKyAgICBjYXNlIC0xMDc0Mzk1NTk3OiB7CisgICAgICBlcnJvclRleHQgPSAiRVJSX05JT0NSX05PVF9BX1ZBTElEX1NFU1NJT04iOworICAgICAgYnJlYWs7CisgICAgfQorICAgIGNhc2UgLTEwNzQzOTU1OTg6IHsKKyAgICAgIGVycm9yVGV4dCA9ICJFUlJfTklPQ1JfSU5WQUxJRF9BQ0NFUFRBTkNFX0xFVkVMIjsKKyAgICAgIGJyZWFrOworICAgIH0KKyAgICBjYXNlIC0xMDc0Mzk1NjAwOiB7CisgICAgICBlcnJvclRleHQgPSAiRVJSX0lORk9fTk9UX0ZPVU5EIjsKKyAgICAgIGJyZWFrOworICAgIH0KKyAgICBjYXNlIC0xMDc0Mzk1NjAxOiB7CisgICAgICBlcnJvclRleHQgPSAiRVJSX0lOVkFMSURfRURHRV9USFJFU0hPTEQiOworICAgICAgYnJlYWs7CisgICAgfQorICAgIGNhc2UgLTEwNzQzOTU2MDI6IHsKKyAgICAgIGVycm9yVGV4dCA9ICJFUlJfSU5WQUxJRF9NSU5JTVVNX0NVUlZFX0xFTkdUSCI7CisgICAgICBicmVhazsKKyAgICB9CisgICAgY2FzZSAtMTA3NDM5NTYwMzogeworICAgICAgZXJyb3JUZXh0ID0gIkVSUl9JTlZBTElEX1JPV19TVEVQIjsKKyAgICAgIGJyZWFrOworICAgIH0KKyAgICBjYXNlIC0xMDc0Mzk1NjA0OiB7CisgICAgICBlcnJvclRleHQgPSAiRVJSX0lOVkFMSURfQ09MVU1OX1NURVAiOworICAgICAgYnJlYWs7CisgICAgfQorICAgIGNhc2UgLTEwNzQzOTU2MDU6IHsKKyAgICAgIGVycm9yVGV4dCA9ICJFUlJfSU5WQUxJRF9NQVhJTVVNX0VORF9QT0lOVF9HQVAiOworICAgICAgYnJlYWs7CisgICAgfQorICAgIGNhc2UgLTEwNzQzOTU2MDY6IHsKKyAgICAgIGVycm9yVGV4dCA9ICJFUlJfSU5WQUxJRF9NSU5JTVVNX0ZFQVRVUkVTX1RPX01BVENIIjsKKyAgICAgIGJyZWFrOworICAgIH0KKyAgICBjYXNlIC0xMDc0Mzk1NjA3OiB7CisgICAgICBlcnJvclRleHQgPSAiRVJSX0lOVkFMSURfTUFYSU1VTV9GRUFUVVJFU19QRVJfTUFUQ0giOworICAgICAgYnJlYWs7CisgICAgfQorICAgIGNhc2UgLTEwNzQzOTU2MDg6IHsKKyAgICAgIGVycm9yVGV4dCA9ICJFUlJfSU5WQUxJRF9TVUJQSVhFTF9JVEVSQVRJT05TIjsKKyAgICAgIGJyZWFrOworICAgIH0KKyAgICBjYXNlIC0xMDc0Mzk1NjA5OiB7CisgICAgICBlcnJvclRleHQgPSAiRVJSX0lOVkFMSURfU1VCUElYRUxfVE9MRVJBTkNFIjsKKyAgICAgIGJyZWFrOworICAgIH0KKyAgICBjYXNlIC0xMDc0Mzk1NjEwOiB7CisgICAgICBlcnJvclRleHQgPSAiRVJSX0lOVkFMSURfSU5JVElBTF9NQVRDSF9MSVNUX0xFTkdUSCI7CisgICAgICBicmVhazsKKyAgICB9CisgICAgY2FzZSAtMTA3NDM5NTYxMTogeworICAgICAgZXJyb3JUZXh0ID0gIkVSUl9JTlZBTElEX01JTklNVU1fUkVDVEFOR0xFX0RJTUVOU0lPTiI7CisgICAgICBicmVhazsKKyAgICB9CisgICAgY2FzZSAtMTA3NDM5NTYxMjogeworICAgICAgZXJyb3JUZXh0ID0gIkVSUl9JTlZBTElEX01JTklNVU1fRkVBVFVSRV9SQURJVVMiOworICAgICAgYnJlYWs7CisgICAgfQorICAgIGNhc2UgLTEwNzQzOTU2MTM6IHsKKyAgICAgIGVycm9yVGV4dCA9ICJFUlJfSU5WQUxJRF9NSU5JTVVNX0ZFQVRVUkVfTEVOR1RIIjsKKyAgICAgIGJyZWFrOworICAgIH0KKyAgICBjYXNlIC0xMDc0Mzk1NjE0OiB7CisgICAgICBlcnJvclRleHQgPSAiRVJSX0lOVkFMSURfTUlOSU1VTV9GRUFUVVJFX0FTUEVDVF9SQVRJTyI7CisgICAgICBicmVhazsKKyAgICB9CisgICAgY2FzZSAtMTA3NDM5NTYxNTogeworICAgICAgZXJyb3JUZXh0ID0gIkVSUl9JTlZBTElEX01JTklNVU1fRkVBVFVSRV9TVFJFTkdUSCI7CisgICAgICBicmVhazsKKyAgICB9CisgICAgY2FzZSAtMTA3NDM5NTYxNjogeworICAgICAgZXJyb3JUZXh0ID0gIkVSUl9JTlZBTElEX0VER0VfRklMVEVSX1NJWkUiOworICAgICAgYnJlYWs7CisgICAgfQorICAgIGNhc2UgLTEwNzQzOTU2MTc6IHsKKyAgICAgIGVycm9yVGV4dCA9ICJFUlJfSU5WQUxJRF9OVU1CRVJfT0ZfRkVBVFVSRVNfUkFOR0UiOworICAgICAgYnJlYWs7CisgICAgfQorICAgIGNhc2UgLTEwNzQzOTU2MTg6IHsKKyAgICAgIGVycm9yVGV4dCA9ICJFUlJfVE9PX01BTllfU0NBTEVfUkFOR0VTIjsKKyAgICAgIGJyZWFrOworICAgIH0KKyAgICBjYXNlIC0xMDc0Mzk1NjE5OiB7CisgICAgICBlcnJvclRleHQgPSAiRVJSX1RPT19NQU5ZX09DQ0xVU0lPTl9SQU5HRVMiOworICAgICAgYnJlYWs7CisgICAgfQorICAgIGNhc2UgLTEwNzQzOTU2MjA6IHsKKyAgICAgIGVycm9yVGV4dCA9ICJFUlJfSU5WQUxJRF9DVVJWRV9FWFRSQUNUSU9OX01PREUiOworICAgICAgYnJlYWs7CisgICAgfQorICAgIGNhc2UgLTEwNzQzOTU2MjE6IHsKKyAgICAgIGVycm9yVGV4dCA9ICJFUlJfSU5WQUxJRF9MRUFSTl9HRU9NRVRSSUNfUEFUVEVSTl9TRVRVUF9EQVRBIjsKKyAgICAgIGJyZWFrOworICAgIH0KKyAgICBjYXNlIC0xMDc0Mzk1NjIyOiB7CisgICAgICBlcnJvclRleHQgPSAiRVJSX0lOVkFMSURfTUFUQ0hfR0VPTUVUUklDX1BBVFRFUk5fU0VUVVBfREFUQSI7CisgICAgICBicmVhazsKKyAgICB9CisgICAgY2FzZSAtMTA3NDM5NTYyMzogeworICAgICAgZXJyb3JUZXh0ID0gIkVSUl9JTlZBTElEX1NDQUxFX1JBTkdFIjsKKyAgICAgIGJyZWFrOworICAgIH0KKyAgICBjYXNlIC0xMDc0Mzk1NjI0OiB7CisgICAgICBlcnJvclRleHQgPSAiRVJSX0lOVkFMSURfT0NDTFVTSU9OX1JBTkdFIjsKKyAgICAgIGJyZWFrOworICAgIH0KKyAgICBjYXNlIC0xMDc0Mzk1NjI1OiB7CisgICAgICBlcnJvclRleHQgPSAiRVJSX0lOVkFMSURfTUFUQ0hfQ09OU1RSQUlOVF9UWVBFIjsKKyAgICAgIGJyZWFrOworICAgIH0KKyAgICBjYXNlIC0xMDc0Mzk1NjI2OiB7CisgICAgICBlcnJvclRleHQgPSAiRVJSX05PVF9FTk9VR0hfVEVNUExBVEVfRkVBVFVSRVMiOworICAgICAgYnJlYWs7CisgICAgfQorICAgIGNhc2UgLTEwNzQzOTU2Mjc6IHsKKyAgICAgIGVycm9yVGV4dCA9ICJFUlJfTk9UX0VOT1VHSF9URU1QTEFURV9GRUFUVVJFU18xIjsKKyAgICAgIGJyZWFrOworICAgIH0KKyAgICBjYXNlIC0xMDc0Mzk1NjI4OiB7CisgICAgICBlcnJvclRleHQgPSAiRVJSX0lOVkFMSURfR0VPTUVUUklDX01BVENISU5HX1RFTVBMQVRFIjsKKyAgICAgIGJyZWFrOworICAgIH0KKyAgICBjYXNlIC0xMDc0Mzk1NjI5OiB7CisgICAgICBlcnJvclRleHQgPSAiRVJSX0lOVkFMSURfTUFYSU1VTV9QSVhFTF9ESVNUQU5DRV9GUk9NX0xJTkUiOworICAgICAgYnJlYWs7CisgICAgfQorICAgIGNhc2UgLTEwNzQzOTU2MzA6IHsKKyAgICAgIGVycm9yVGV4dCA9ICJFUlJfSU5WQUxJRF9NQVhJTVVNX0ZFQVRVUkVTX0xFQVJORUQiOworICAgICAgYnJlYWs7CisgICAgfQorICAgIGNhc2UgLTEwNzQzOTU2MzE6IHsKKyAgICAgIGVycm9yVGV4dCA9ICJFUlJfSU5WQUxJRF9NSU5fTUFUQ0hfU0VQQVJBVElPTl9ESVNUQU5DRSI7CisgICAgICBicmVhazsKKyAgICB9CisgICAgY2FzZSAtMTA3NDM5NTYzMjogeworICAgICAgZXJyb3JUZXh0ID0gIkVSUl9JTlZBTElEX01JTl9NQVRDSF9TRVBBUkFUSU9OX0FOR0xFIjsKKyAgICAgIGJyZWFrOworICAgIH0KKyAgICBjYXNlIC0xMDc0Mzk1NjMzOiB7CisgICAgICBlcnJvclRleHQgPSAiRVJSX0lOVkFMSURfTUlOX01BVENIX1NFUEFSQVRJT05fU0NBTEUiOworICAgICAgYnJlYWs7CisgICAgfQorICAgIGNhc2UgLTEwNzQzOTU2MzQ6IHsKKyAgICAgIGVycm9yVGV4dCA9ICJFUlJfSU5WQUxJRF9NQVhfTUFUQ0hfT1ZFUkxBUCI7CisgICAgICBicmVhazsKKyAgICB9CisgICAgY2FzZSAtMTA3NDM5NTYzNTogeworICAgICAgZXJyb3JUZXh0ID0gIkVSUl9JTlZBTElEX1NIQVBFX0RFU0NSSVBUT1IiOworICAgICAgYnJlYWs7CisgICAgfQorICAgIGNhc2UgLTEwNzQzOTU2MzY6IHsKKyAgICAgIGVycm9yVGV4dCA9ICJFUlJfRElSRUNUWF9OT1RfRk9VTkQiOworICAgICAgYnJlYWs7CisgICAgfQorICAgIGNhc2UgLTEwNzQzOTU2Mzc6IHsKKyAgICAgIGVycm9yVGV4dCA9ICJFUlJfSEFSRFdBUkVfRE9FU05UX1NVUFBPUlRfTk9OVEVBUklORyI7CisgICAgICBicmVhazsKKyAgICB9CisgICAgY2FzZSAtMTA3NDM5NTYzODogeworICAgICAgZXJyb3JUZXh0ID0gIkVSUl9JTlZBTElEX0ZJTExfU1RZTEUiOworICAgICAgYnJlYWs7CisgICAgfQorICAgIGNhc2UgLTEwNzQzOTU2Mzk6IHsKKyAgICAgIGVycm9yVGV4dCA9ICJFUlJfSU5WQUxJRF9IQVRDSF9TVFlMRSI7CisgICAgICBicmVhazsKKyAgICB9CisgICAgY2FzZSAtMTA3NDM5NTY0MDogeworICAgICAgZXJyb3JUZXh0ID0gIkVSUl9UT09fTUFOWV9aT05FUyI7CisgICAgICBicmVhazsKKyAgICB9CisgICAgY2FzZSAtMTA3NDM5NTY0MTogeworICAgICAgZXJyb3JUZXh0ID0gIkVSUl9EVVBMSUNBVEVfTEFCRUwiOworICAgICAgYnJlYWs7CisgICAgfQorICAgIGNhc2UgLTEwNzQzOTU2NDI6IHsKKyAgICAgIGVycm9yVGV4dCA9ICJFUlJfTEFCRUxfTk9UX0ZPVU5EIjsKKyAgICAgIGJyZWFrOworICAgIH0KKyAgICBjYXNlIC0xMDc0Mzk1NjQzOiB7CisgICAgICBlcnJvclRleHQgPSAiRVJSX0lOVkFMSURfTlVNQkVSX09GX01BVENIX09QVElPTlMiOworICAgICAgYnJlYWs7CisgICAgfQorICAgIGNhc2UgLTEwNzQzOTU2NDQ6IHsKKyAgICAgIGVycm9yVGV4dCA9ICJFUlJfTEFCRUxfVE9PX0xPTkciOworICAgICAgYnJlYWs7CisgICAgfQorICAgIGNhc2UgLTEwNzQzOTU2NDU6IHsKKyAgICAgIGVycm9yVGV4dCA9ICJFUlJfSU5WQUxJRF9OVU1CRVJfT0ZfTEFCRUxTIjsKKyAgICAgIGJyZWFrOworICAgIH0KKyAgICBjYXNlIC0xMDc0Mzk1NjQ2OiB7CisgICAgICBlcnJvclRleHQgPSAiRVJSX05PX1RFTVBMQVRFX1RPX0xFQVJOIjsKKyAgICAgIGJyZWFrOworICAgIH0KKyAgICBjYXNlIC0xMDc0Mzk1NjQ3OiB7CisgICAgICBlcnJvclRleHQgPSAiRVJSX0lOVkFMSURfTVVMVElQTEVfR0VPTUVUUklDX1RFTVBMQVRFIjsKKyAgICAgIGJyZWFrOworICAgIH0KKyAgICBjYXNlIC0xMDc0Mzk1NjQ4OiB7CisgICAgICBlcnJvclRleHQgPSAiRVJSX1RFTVBMQVRFX05PVF9MRUFSTkVEIjsKKyAgICAgIGJyZWFrOworICAgIH0KKyAgICBjYXNlIC0xMDc0Mzk1NjQ5OiB7CisgICAgICBlcnJvclRleHQgPSAiRVJSX0lOVkFMSURfR0VPTUVUUklDX0ZFQVRVUkVfVFlQRSI7CisgICAgICBicmVhazsKKyAgICB9CisgICAgY2FzZSAtMTA3NDM5NTY1MDogeworICAgICAgZXJyb3JUZXh0ID0gIkVSUl9DVVJWRV9FWFRSQUNUSU9OX01PREVfTVVTVF9CRV9TQU1FIjsKKyAgICAgIGJyZWFrOworICAgIH0KKyAgICBjYXNlIC0xMDc0Mzk1NjUxOiB7CisgICAgICBlcnJvclRleHQgPSAiRVJSX0VER0VfRklMVEVSX1NJWkVfTVVTVF9CRV9TQU1FIjsKKyAgICAgIGJyZWFrOworICAgIH0KKyAgICBjYXNlIC0xMDc0Mzk1NjUyOiB7CisgICAgICBlcnJvclRleHQgPSAiRVJSX09QRU5JTkdfTkVXRVJfR0VPTUVUUklDX01BVENISU5HX1RFTVBMQVRFIjsKKyAgICAgIGJyZWFrOworICAgIH0KKyAgICBjYXNlIC0xMDc0Mzk1NjUzOiB7CisgICAgICBlcnJvclRleHQgPSAiRVJSX09QRU5JTkdfTkVXRVJfTVVMVElQTEVfR0VPTUVUUklDX1RFTVBMQVRFIjsKKyAgICAgIGJyZWFrOworICAgIH0KKyAgICBjYXNlIC0xMDc0Mzk1NjU0OiB7CisgICAgICBlcnJvclRleHQgPSAiRVJSX0dSQURJTkdfSU5GT1JNQVRJT05fTk9UX0ZPVU5EIjsKKyAgICAgIGJyZWFrOworICAgIH0KKyAgICBjYXNlIC0xMDc0Mzk1NjU1OiB7CisgICAgICBlcnJvclRleHQgPSAiRVJSX0VOQUJMRV9DQUxJQlJBVElPTl9TVVBQT1JUX01VU1RfQkVfU0FNRSI7CisgICAgICBicmVhazsKKyAgICB9CisgICAgY2FzZSAtMTA3NDM5NTY1NjogeworICAgICAgZXJyb3JUZXh0ID0gIkVSUl9TTU9PVEhfQ09OVE9VUlNfTVVTVF9CRV9TQU1FIjsKKyAgICAgIGJyZWFrOworICAgIH0KKyAgICBjYXNlIC0xMDc0Mzk1NzAwOiB7CisgICAgICBlcnJvclRleHQgPSAiRVJSX1JFUVVJUkVTX1dJTjIwMDBfT1JfTkVXRVIiOworICAgICAgYnJlYWs7CisgICAgfQorICAgIGNhc2UgLTEwNzQzOTU3MDE6IHsKKyAgICAgIGVycm9yVGV4dCA9ICJFUlJfSU5WQUxJRF9NQVRSSVhfU0laRV9SQU5HRSI7CisgICAgICBicmVhazsKKyAgICB9CisgICAgY2FzZSAtMTA3NDM5NTcwMjogeworICAgICAgZXJyb3JUZXh0ID0gIkVSUl9JTlZBTElEX0xFTkdUSCI7CisgICAgICBicmVhazsKKyAgICB9CisgICAgY2FzZSAtMTA3NDM5NTcwMzogeworICAgICAgZXJyb3JUZXh0ID0gIkVSUl9JTlZBTElEX1RZUEVfT0ZfRkxBVFRFTiI7CisgICAgICBicmVhazsKKyAgICB9CisgICAgY2FzZSAtMTA3NDM5NTcwNDogeworICAgICAgZXJyb3JUZXh0ID0gIkVSUl9JTlZBTElEX0NPTVBSRVNTSU9OX1RZUEUiOworICAgICAgYnJlYWs7CisgICAgfQorICAgIGNhc2UgLTEwNzQzOTU3MDU6IHsKKyAgICAgIGVycm9yVGV4dCA9ICJFUlJfREFUQV9DT1JSVVBURUQiOworICAgICAgYnJlYWs7CisgICAgfQorICAgIGNhc2UgLTEwNzQzOTU3MDY6IHsKKyAgICAgIGVycm9yVGV4dCA9ICJFUlJfQVZJX1NFU1NJT05fQUxSRUFEWV9PUEVOIjsKKyAgICAgIGJyZWFrOworICAgIH0KKyAgICBjYXNlIC0xMDc0Mzk1NzA3OiB7CisgICAgICBlcnJvclRleHQgPSAiRVJSX0FWSV9XUklURV9TRVNTSU9OX1JFUVVJUkVEIjsKKyAgICAgIGJyZWFrOworICAgIH0KKyAgICBjYXNlIC0xMDc0Mzk1NzA4OiB7CisgICAgICBlcnJvclRleHQgPSAiRVJSX0FWSV9SRUFEX1NFU1NJT05fUkVRVUlSRUQiOworICAgICAgYnJlYWs7CisgICAgfQorICAgIGNhc2UgLTEwNzQzOTU3MDk6IHsKKyAgICAgIGVycm9yVGV4dCA9ICJFUlJfQVZJX1VOT1BFTkVEX1NFU1NJT04iOworICAgICAgYnJlYWs7CisgICAgfQorICAgIGNhc2UgLTEwNzQzOTU3MTA6IHsKKyAgICAgIGVycm9yVGV4dCA9ICJFUlJfVE9PX01BTllfUEFSVElDTEVTIjsKKyAgICAgIGJyZWFrOworICAgIH0KKyAgICBjYXNlIC0xMDc0Mzk1NzExOiB7CisgICAgICBlcnJvclRleHQgPSAiRVJSX05PVF9FTk9VR0hfUkVHSU9OUyI7CisgICAgICBicmVhazsKKyAgICB9CisgICAgY2FzZSAtMTA3NDM5NTcxMjogeworICAgICAgZXJyb3JUZXh0ID0gIkVSUl9XUk9OR19SRUdJT05fVFlQRSI7CisgICAgICBicmVhazsKKyAgICB9CisgICAgY2FzZSAtMTA3NDM5NTcxMzogeworICAgICAgZXJyb3JUZXh0ID0gIkVSUl9WQUxVRV9OT1RfSU5fRU5VTSI7CisgICAgICBicmVhazsKKyAgICB9CisgICAgY2FzZSAtMTA3NDM5NTcxNDogeworICAgICAgZXJyb3JUZXh0ID0gIkVSUl9JTlZBTElEX0FYSVNfT1JJRU5UQVRJT04iOworICAgICAgYnJlYWs7CisgICAgfQorICAgIGNhc2UgLTEwNzQzOTU3MTU6IHsKKyAgICAgIGVycm9yVGV4dCA9ICJFUlJfSU5WQUxJRF9DQUxJQlJBVElPTl9VTklUIjsKKyAgICAgIGJyZWFrOworICAgIH0KKyAgICBjYXNlIC0xMDc0Mzk1NzE2OiB7CisgICAgICBlcnJvclRleHQgPSAiRVJSX0lOVkFMSURfU0NBTElOR19NRVRIT0QiOworICAgICAgYnJlYWs7CisgICAgfQorICAgIGNhc2UgLTEwNzQzOTU3MTc6IHsKKyAgICAgIGVycm9yVGV4dCA9ICJFUlJfSU5WQUxJRF9SQU5HRSI7CisgICAgICBicmVhazsKKyAgICB9CisgICAgY2FzZSAtMTA3NDM5NTcxODogeworICAgICAgZXJyb3JUZXh0ID0gIkVSUl9MQUJfVkVSU0lPTiI7CisgICAgICBicmVhazsKKyAgICB9CisgICAgY2FzZSAtMTA3NDM5NTcxOTogeworICAgICAgZXJyb3JUZXh0ID0gIkVSUl9CQURfUk9JX0JPWCI7CisgICAgICBicmVhazsKKyAgICB9CisgICAgY2FzZSAtMTA3NDM5NTcyMDogeworICAgICAgZXJyb3JUZXh0ID0gIkVSUl9CQURfUk9JIjsKKyAgICAgIGJyZWFrOworICAgIH0KKyAgICBjYXNlIC0xMDc0Mzk1NzIxOiB7CisgICAgICBlcnJvclRleHQgPSAiRVJSX0lOVkFMSURfQklUX0RFUFRIIjsKKyAgICAgIGJyZWFrOworICAgIH0KKyAgICBjYXNlIC0xMDc0Mzk1NzIyOiB7CisgICAgICBlcnJvclRleHQgPSAiRVJSX0NMQVNTSUZJRVJfQ0xBU1NJRllfSU1BR0VfV0lUSF9DVVNUT01fU0VTU0lPTiI7CisgICAgICBicmVhazsKKyAgICB9CisgICAgY2FzZSAtMTA3NDM5NTcyMzogeworICAgICAgZXJyb3JUZXh0ID0gIkVSUl9DVVNUT01EQVRBX0tFWV9OT1RfRk9VTkQiOworICAgICAgYnJlYWs7CisgICAgfQorICAgIGNhc2UgLTEwNzQzOTU3MjQ6IHsKKyAgICAgIGVycm9yVGV4dCA9ICJFUlJfQ1VTVE9NREFUQV9JTlZBTElEX1NJWkUiOworICAgICAgYnJlYWs7CisgICAgfQorICAgIGNhc2UgLTEwNzQzOTU3MjU6IHsKKyAgICAgIGVycm9yVGV4dCA9ICJFUlJfREFUQV9WRVJTSU9OIjsKKyAgICAgIGJyZWFrOworICAgIH0KKyAgICBjYXNlIC0xMDc0Mzk1NzI2OiB7CisgICAgICBlcnJvclRleHQgPSAiRVJSX01BVENIRkFDVE9SX09CU09MRVRFIjsKKyAgICAgIGJyZWFrOworICAgIH0KKyAgICBjYXNlIC0xMDc0Mzk1NzI3OiB7CisgICAgICBlcnJvclRleHQgPSAiRVJSX1VOU1VQUE9SVEVEXzJEX0JBUkNPREVfU0VBUkNIX01PREUiOworICAgICAgYnJlYWs7CisgICAgfQorICAgIGNhc2UgLTEwNzQzOTU3Mjg6IHsKKyAgICAgIGVycm9yVGV4dCA9ICJFUlJfSU5WQUxJRF8yRF9CQVJDT0RFX1NFQVJDSF9NT0RFIjsKKyAgICAgIGJyZWFrOworICAgIH0KKyAgICBjYXNlIC0xMDc0Mzk1NzU0OiB7CisgICAgICBlcnJvclRleHQgPSAiRVJSX1RSSUdfVElNRU9VVCI7CisgICAgICBicmVhazsKKyAgICB9CisgICAgY2FzZSAtMTA3NDM5NTc1NjogeworICAgICAgZXJyb3JUZXh0ID0gIkVSUl9ETExfRlVOQ1RJT05fTk9UX0ZPVU5EIjsKKyAgICAgIGJyZWFrOworICAgIH0KKyAgICBjYXNlIC0xMDc0Mzk1NzU3OiB7CisgICAgICBlcnJvclRleHQgPSAiRVJSX0RMTF9OT1RfRk9VTkQiOworICAgICAgYnJlYWs7CisgICAgfQorICAgIGNhc2UgLTEwNzQzOTU3NTg6IHsKKyAgICAgIGVycm9yVGV4dCA9ICJFUlJfQk9BUkRfTk9UX09QRU4iOworICAgICAgYnJlYWs7CisgICAgfQorICAgIGNhc2UgLTEwNzQzOTU3NjA6IHsKKyAgICAgIGVycm9yVGV4dCA9ICJFUlJfQk9BUkRfTk9UX0ZPVU5EIjsKKyAgICAgIGJyZWFrOworICAgIH0KKyAgICBjYXNlIC0xMDc0Mzk1NzYyOiB7CisgICAgICBlcnJvclRleHQgPSAiRVJSX0lOVkFMSURfTklCTEFDS19ERVZJQVRJT05fRkFDVE9SIjsKKyAgICAgIGJyZWFrOworICAgIH0KKyAgICBjYXNlIC0xMDc0Mzk1NzYzOiB7CisgICAgICBlcnJvclRleHQgPSAiRVJSX0lOVkFMSURfTk9STUFMSVpBVElPTl9NRVRIT0QiOworICAgICAgYnJlYWs7CisgICAgfQorICAgIGNhc2UgLTEwNzQzOTU3NjY6IHsKKyAgICAgIGVycm9yVGV4dCA9ICJFUlJfREVQUkVDQVRFRF9GVU5DVElPTiI7CisgICAgICBicmVhazsKKyAgICB9CisgICAgY2FzZSAtMTA3NDM5NTc2NzogeworICAgICAgZXJyb3JUZXh0ID0gIkVSUl9JTlZBTElEX0FMSUdOTUVOVCI7CisgICAgICBicmVhazsKKyAgICB9CisgICAgY2FzZSAtMTA3NDM5NTc2ODogeworICAgICAgZXJyb3JUZXh0ID0gIkVSUl9JTlZBTElEX1NDQUxFIjsKKyAgICAgIGJyZWFrOworICAgIH0KKyAgICBjYXNlIC0xMDc0Mzk1NzY5OiB7CisgICAgICBlcnJvclRleHQgPSAiRVJSX0lOVkFMSURfRURHRV9USElDS05FU1MiOworICAgICAgYnJlYWs7CisgICAgfQorICAgIGNhc2UgLTEwNzQzOTU3NzA6IHsKKyAgICAgIGVycm9yVGV4dCA9ICJFUlJfSU5WQUxJRF9JTlNQRUNUSU9OX1RFTVBMQVRFIjsKKyAgICAgIGJyZWFrOworICAgIH0KKyAgICBjYXNlIC0xMDc0Mzk1NzcxOiB7CisgICAgICBlcnJvclRleHQgPSAiRVJSX09QRU5JTkdfTkVXRVJfSU5TUEVDVElPTl9URU1QTEFURSI7CisgICAgICBicmVhazsKKyAgICB9CisgICAgY2FzZSAtMTA3NDM5NTc3MjogeworICAgICAgZXJyb3JUZXh0ID0gIkVSUl9JTlZBTElEX1JFR0lTVFJBVElPTl9NRVRIT0QiOworICAgICAgYnJlYWs7CisgICAgfQorICAgIGNhc2UgLTEwNzQzOTU3NzM6IHsKKyAgICAgIGVycm9yVGV4dCA9ICJFUlJfTk9fREVTVF9JTUFHRSI7CisgICAgICBicmVhazsKKyAgICB9CisgICAgY2FzZSAtMTA3NDM5NTc3NDogeworICAgICAgZXJyb3JUZXh0ID0gIkVSUl9OT19MQUJFTCI7CisgICAgICBicmVhazsKKyAgICB9CisgICAgY2FzZSAtMTA3NDM5NTc3NTogeworICAgICAgZXJyb3JUZXh0ID0gIkVSUl9ST0lfSEFTX09QRU5fQ09OVE9VUlMiOworICAgICAgYnJlYWs7CisgICAgfQorICAgIGNhc2UgLTEwNzQzOTU3NzY6IHsKKyAgICAgIGVycm9yVGV4dCA9ICJFUlJfSU5WQUxJRF9VU0VfT0ZfQ09NUEFDVF9TRVNTSU9OX0ZJTEUiOworICAgICAgYnJlYWs7CisgICAgfQorICAgIGNhc2UgLTEwNzQzOTU3Nzc6IHsKKyAgICAgIGVycm9yVGV4dCA9ICJFUlJfSU5DT01QQVRJQkxFX0NMQVNTSUZJRVJfVFlQRVMiOworICAgICAgYnJlYWs7CisgICAgfQorICAgIGNhc2UgLTEwNzQzOTU3Nzg6IHsKKyAgICAgIGVycm9yVGV4dCA9ICJFUlJfSU5WQUxJRF9LRVJORUxfU0laRSI7CisgICAgICBicmVhazsKKyAgICB9CisgICAgY2FzZSAtMTA3NDM5NTc3OTogeworICAgICAgZXJyb3JUZXh0ID0gIkVSUl9DQU5OT1RfQ09NUEFDVF9VTlRSQUlORUQiOworICAgICAgYnJlYWs7CisgICAgfQorICAgIGNhc2UgLTEwNzQzOTU3ODA6IHsKKyAgICAgIGVycm9yVGV4dCA9ICJFUlJfSU5WQUxJRF9QQVJUSUNMRV9UWVBFIjsKKyAgICAgIGJyZWFrOworICAgIH0KKyAgICBjYXNlIC0xMDc0Mzk1NzgxOiB7CisgICAgICBlcnJvclRleHQgPSAiRVJSX0NMQVNTSUZJRVJfSU5WQUxJRF9FTkdJTkVfVFlQRSI7CisgICAgICBicmVhazsKKyAgICB9CisgICAgY2FzZSAtMTA3NDM5NTc4MjogeworICAgICAgZXJyb3JUZXh0ID0gIkVSUl9ERVNDUklQVElPTl9UT09fTE9ORyI7CisgICAgICBicmVhazsKKyAgICB9CisgICAgY2FzZSAtMTA3NDM5NTc4MzogeworICAgICAgZXJyb3JUZXh0ID0gIkVSUl9CQURfU0FNUExFX0lOREVYIjsKKyAgICAgIGJyZWFrOworICAgIH0KKyAgICBjYXNlIC0xMDc0Mzk1Nzg0OiB7CisgICAgICBlcnJvclRleHQgPSAiRVJSX0lOVkFMSURfTElNSVRTIjsKKyAgICAgIGJyZWFrOworICAgIH0KKyAgICBjYXNlIC0xMDc0Mzk1Nzg1OiB7CisgICAgICBlcnJvclRleHQgPSAiRVJSX05PX1BBUlRJQ0xFIjsKKyAgICAgIGJyZWFrOworICAgIH0KKyAgICBjYXNlIC0xMDc0Mzk1Nzg2OiB7CisgICAgICBlcnJvclRleHQgPSAiRVJSX0lOVkFMSURfUEFSVElDTEVfT1BUSU9OUyI7CisgICAgICBicmVhazsKKyAgICB9CisgICAgY2FzZSAtMTA3NDM5NTc4NzogeworICAgICAgZXJyb3JUZXh0ID0gIkVSUl9JTlZBTElEX0NMQVNTSUZJRVJfVFlQRSI7CisgICAgICBicmVhazsKKyAgICB9CisgICAgY2FzZSAtMTA3NDM5NTc4ODogeworICAgICAgZXJyb3JUZXh0ID0gIkVSUl9OT19TQU1QTEVTIjsKKyAgICAgIGJyZWFrOworICAgIH0KKyAgICBjYXNlIC0xMDc0Mzk1Nzg5OiB7CisgICAgICBlcnJvclRleHQgPSAiRVJSX09QRU5JTkdfTkVXRVJfQ0xBU1NJRklFUl9TRVNTSU9OIjsKKyAgICAgIGJyZWFrOworICAgIH0KKyAgICBjYXNlIC0xMDc0Mzk1NzkwOiB7CisgICAgICBlcnJvclRleHQgPSAiRVJSX0lOVkFMSURfRElTVEFOQ0VfTUVUUklDIjsKKyAgICAgIGJyZWFrOworICAgIH0KKyAgICBjYXNlIC0xMDc0Mzk1NzkxOiB7CisgICAgICBlcnJvclRleHQgPSAiRVJSX0NMQVNTSUZJRVJfSU5WQUxJRF9TRVNTSU9OX1RZUEUiOworICAgICAgYnJlYWs7CisgICAgfQorICAgIGNhc2UgLTEwNzQzOTU3OTI6IHsKKyAgICAgIGVycm9yVGV4dCA9ICJFUlJfQ0xBU1NJRklFUl9TRVNTSU9OX05PVF9UUkFJTkVEIjsKKyAgICAgIGJyZWFrOworICAgIH0KKyAgICBjYXNlIC0xMDc0Mzk1NzkzOiB7CisgICAgICBlcnJvclRleHQgPSAiRVJSX0lOVkFMSURfT1BFUkFUSU9OX09OX0NPTVBBQ1RfU0VTU0lPTl9BVFRFTVBURUQiOworICAgICAgYnJlYWs7CisgICAgfQorICAgIGNhc2UgLTEwNzQzOTU3OTQ6IHsKKyAgICAgIGVycm9yVGV4dCA9ICJFUlJfS19UT09fSElHSCI7CisgICAgICBicmVhazsKKyAgICB9CisgICAgY2FzZSAtMTA3NDM5NTc5NTogeworICAgICAgZXJyb3JUZXh0ID0gIkVSUl9LX1RPT19MT1ciOworICAgICAgYnJlYWs7CisgICAgfQorICAgIGNhc2UgLTEwNzQzOTU3OTY6IHsKKyAgICAgIGVycm9yVGV4dCA9ICJFUlJfSU5WQUxJRF9LTk5fTUVUSE9EIjsKKyAgICAgIGJyZWFrOworICAgIH0KKyAgICBjYXNlIC0xMDc0Mzk1Nzk3OiB7CisgICAgICBlcnJvclRleHQgPSAiRVJSX0lOVkFMSURfQ0xBU1NJRklFUl9TRVNTSU9OIjsKKyAgICAgIGJyZWFrOworICAgIH0KKyAgICBjYXNlIC0xMDc0Mzk1Nzk4OiB7CisgICAgICBlcnJvclRleHQgPSAiRVJSX0lOVkFMSURfQ1VTVE9NX1NBTVBMRSI7CisgICAgICBicmVhazsKKyAgICB9CisgICAgY2FzZSAtMTA3NDM5NTc5OTogeworICAgICAgZXJyb3JUZXh0ID0gIkVSUl9JTlRFUk5BTCI7CisgICAgICBicmVhazsKKyAgICB9CisgICAgY2FzZSAtMTA3NDM5NTgwMDogeworICAgICAgZXJyb3JUZXh0ID0gIkVSUl9QUk9URUNUSU9OIjsKKyAgICAgIGJyZWFrOworICAgIH0KKyAgICBjYXNlIC0xMDc0Mzk1ODAxOiB7CisgICAgICBlcnJvclRleHQgPSAiRVJSX1RPT19NQU5ZX0NPTlRPVVJTIjsKKyAgICAgIGJyZWFrOworICAgIH0KKyAgICBjYXNlIC0xMDc0Mzk1ODM3OiB7CisgICAgICBlcnJvclRleHQgPSAiRVJSX0lOVkFMSURfQ09NUFJFU1NJT05fUkFUSU8iOworICAgICAgYnJlYWs7CisgICAgfQorICAgIGNhc2UgLTEwNzQzOTU4NDA6IHsKKyAgICAgIGVycm9yVGV4dCA9ICJFUlJfQkFEX0lOREVYIjsKKyAgICAgIGJyZWFrOworICAgIH0KKyAgICBjYXNlIC0xMDc0Mzk1ODc1OiB7CisgICAgICBlcnJvclRleHQgPSAiRVJSX0JBUkNPREVfUEhBUk1BQ09ERSI7CisgICAgICBicmVhazsKKyAgICB9CisgICAgY2FzZSAtMTA3NDM5NTg3NjogeworICAgICAgZXJyb3JUZXh0ID0gIkVSUl9VTlNVUFBPUlRFRF9DT0xPUl9NT0RFIjsKKyAgICAgIGJyZWFrOworICAgIH0KKyAgICBjYXNlIC0xMDc0Mzk1ODc3OiB7CisgICAgICBlcnJvclRleHQgPSAiRVJSX0NPTE9STU9ERV9SRVFVSVJFU19DSEFOR0VDT0xPUlNQQUNFMiI7CisgICAgICBicmVhazsKKyAgICB9CisgICAgY2FzZSAtMTA3NDM5NTg3ODogeworICAgICAgZXJyb3JUZXh0ID0gIkVSUl9QUk9QX05PREVfV1JJVEVfTk9UX1NVUFBPUlRFRCI7CisgICAgICBicmVhazsKKyAgICB9CisgICAgY2FzZSAtMTA3NDM5NTg3OTogeworICAgICAgZXJyb3JUZXh0ID0gIkVSUl9CQURfTUVBU1VSRSI7CisgICAgICBicmVhazsKKyAgICB9CisgICAgY2FzZSAtMTA3NDM5NTg4MDogeworICAgICAgZXJyb3JUZXh0ID0gIkVSUl9QQVJUSUNMRSI7CisgICAgICBicmVhazsKKyAgICB9CisgICAgY2FzZSAtMTA3NDM5NTkyMDogeworICAgICAgZXJyb3JUZXh0ID0gIkVSUl9OVU1CRVJfQ0xBU1MiOworICAgICAgYnJlYWs7CisgICAgfQorICAgIGNhc2UgLTEwNzQzOTU5NTM6IHsKKyAgICAgIGVycm9yVGV4dCA9ICJFUlJfSU5WQUxJRF9XQVZFTEVUX1RSQU5TRk9STV9NT0RFIjsKKyAgICAgIGJyZWFrOworICAgIH0KKyAgICBjYXNlIC0xMDc0Mzk1OTU0OiB7CisgICAgICBlcnJvclRleHQgPSAiRVJSX0lOVkFMSURfUVVBTlRJWkFUSU9OX1NURVBfU0laRSI7CisgICAgICBicmVhazsKKyAgICB9CisgICAgY2FzZSAtMTA3NDM5NTk1NTogeworICAgICAgZXJyb3JUZXh0ID0gIkVSUl9JTlZBTElEX01BWF9XQVZFTEVUX1RSQU5TRk9STV9MRVZFTCI7CisgICAgICBicmVhazsKKyAgICB9CisgICAgY2FzZSAtMTA3NDM5NTk1NjogeworICAgICAgZXJyb3JUZXh0ID0gIkVSUl9JTlZBTElEX1FVQUxJVFkiOworICAgICAgYnJlYWs7CisgICAgfQorICAgIGNhc2UgLTEwNzQzOTU5NTc6IHsKKyAgICAgIGVycm9yVGV4dCA9ICJFUlJfQVJSQVlfU0laRV9NSVNNQVRDSCI7CisgICAgICBicmVhazsKKyAgICB9CisgICAgY2FzZSAtMTA3NDM5NTk1ODogeworICAgICAgZXJyb3JUZXh0ID0gIkVSUl9XSU5ET1dfSUQiOworICAgICAgYnJlYWs7CisgICAgfQorICAgIGNhc2UgLTEwNzQzOTU5NTk6IHsKKyAgICAgIGVycm9yVGV4dCA9ICJFUlJfQ1JFQVRFX1dJTkRPVyI7CisgICAgICBicmVhazsKKyAgICB9CisgICAgY2FzZSAtMTA3NDM5NTk2MDogeworICAgICAgZXJyb3JUZXh0ID0gIkVSUl9JTklUIjsKKyAgICAgIGJyZWFrOworICAgIH0KKyAgICBjYXNlIC0xMDc0Mzk1OTcxOiB7CisgICAgICBlcnJvclRleHQgPSAiRVJSX0lOVkFMSURfT0ZGU0VUIjsKKyAgICAgIGJyZWFrOworICAgIH0KKyAgICBjYXNlIC0xMDc0Mzk1OTcyOiB7CisgICAgICBlcnJvclRleHQgPSAiRVJSX0RJUkVDVFhfRU5VTUVSQVRFX0ZJTFRFUlMiOworICAgICAgYnJlYWs7CisgICAgfQorICAgIGNhc2UgLTEwNzQzOTU5NzM6IHsKKyAgICAgIGVycm9yVGV4dCA9ICJFUlJfSlBFRzIwMDBfVU5TVVBQT1JURURfTVVMVElQTEVfTEFZRVJTIjsKKyAgICAgIGJyZWFrOworICAgIH0KKyAgICBjYXNlIC0xMDc0Mzk1OTc0OiB7CisgICAgICBlcnJvclRleHQgPSAiRVJSX1VOU1VQUE9SVEVEX0pQRUcyMDAwX0NPTE9SU1BBQ0VfTUVUSE9EIjsKKyAgICAgIGJyZWFrOworICAgIH0KKyAgICBjYXNlIC0xMDc0Mzk1OTc1OiB7CisgICAgICBlcnJvclRleHQgPSAiRVJSX0FWSV9USU1FT1VUIjsKKyAgICAgIGJyZWFrOworICAgIH0KKyAgICBjYXNlIC0xMDc0Mzk1OTc2OiB7CisgICAgICBlcnJvclRleHQgPSAiRVJSX05VTUJFUl9PRl9QQUxFVFRFX0NPTE9SUyI7CisgICAgICBicmVhazsKKyAgICB9CisgICAgY2FzZSAtMTA3NDM5NTk3NzogeworICAgICAgZXJyb3JUZXh0ID0gIkVSUl9BVklfVkVSU0lPTiI7CisgICAgICBicmVhazsKKyAgICB9CisgICAgY2FzZSAtMTA3NDM5NTk3ODogeworICAgICAgZXJyb3JUZXh0ID0gIkVSUl9JTlZBTElEX1BBUlRJQ0xFX05VTUJFUiI7CisgICAgICBicmVhazsKKyAgICB9CisgICAgY2FzZSAtMTA3NDM5NTk3OTogeworICAgICAgZXJyb3JUZXh0ID0gIkVSUl9JTlZBTElEX1BBUlRJQ0xFX0lORk8iOworICAgICAgYnJlYWs7CisgICAgfQorICAgIGNhc2UgLTEwNzQzOTU5ODA6IHsKKyAgICAgIGVycm9yVGV4dCA9ICJFUlJfQ09NX0lOSVRJQUxJWkUiOworICAgICAgYnJlYWs7CisgICAgfQorICAgIGNhc2UgLTEwNzQzOTU5ODE6IHsKKyAgICAgIGVycm9yVGV4dCA9ICJFUlJfSU5TVUZGSUNJRU5UX0JVRkZFUl9TSVpFIjsKKyAgICAgIGJyZWFrOworICAgIH0KKyAgICBjYXNlIC0xMDc0Mzk1OTgyOiB7CisgICAgICBlcnJvclRleHQgPSAiRVJSX0lOVkFMSURfRlJBTUVTX1BFUl9TRUNPTkQiOworICAgICAgYnJlYWs7CisgICAgfQorICAgIGNhc2UgLTEwNzQzOTU5ODM6IHsKKyAgICAgIGVycm9yVGV4dCA9ICJFUlJfRklMRV9OT19TUEFDRSI7CisgICAgICBicmVhazsKKyAgICB9CisgICAgY2FzZSAtMTA3NDM5NTk4NDogeworICAgICAgZXJyb3JUZXh0ID0gIkVSUl9GSUxFX0lOVkFMSURfREFUQV9UWVBFIjsKKyAgICAgIGJyZWFrOworICAgIH0KKyAgICBjYXNlIC0xMDc0Mzk1OTg1OiB7CisgICAgICBlcnJvclRleHQgPSAiRVJSX0ZJTEVfT1BFUkFUSU9OIjsKKyAgICAgIGJyZWFrOworICAgIH0KKyAgICBjYXNlIC0xMDc0Mzk1OTg2OiB7CisgICAgICBlcnJvclRleHQgPSAiRVJSX0ZJTEVfRk9STUFUIjsKKyAgICAgIGJyZWFrOworICAgIH0KKyAgICBjYXNlIC0xMDc0Mzk1OTg3OiB7CisgICAgICBlcnJvclRleHQgPSAiRVJSX0ZJTEVfRU9GIjsKKyAgICAgIGJyZWFrOworICAgIH0KKyAgICBjYXNlIC0xMDc0Mzk1OTg4OiB7CisgICAgICBlcnJvclRleHQgPSAiRVJSX0ZJTEVfV1JJVEUiOworICAgICAgYnJlYWs7CisgICAgfQorICAgIGNhc2UgLTEwNzQzOTU5ODk6IHsKKyAgICAgIGVycm9yVGV4dCA9ICJFUlJfRklMRV9SRUFEIjsKKyAgICAgIGJyZWFrOworICAgIH0KKyAgICBjYXNlIC0xMDc0Mzk1OTkwOiB7CisgICAgICBlcnJvclRleHQgPSAiRVJSX0ZJTEVfR0VUX0lORk8iOworICAgICAgYnJlYWs7CisgICAgfQorICAgIGNhc2UgLTEwNzQzOTU5OTE6IHsKKyAgICAgIGVycm9yVGV4dCA9ICJFUlJfRklMRV9JTlZBTElEX1RZUEUiOworICAgICAgYnJlYWs7CisgICAgfQorICAgIGNhc2UgLTEwNzQzOTU5OTI6IHsKKyAgICAgIGVycm9yVGV4dCA9ICJFUlJfRklMRV9QRVJNSVNTSU9OIjsKKyAgICAgIGJyZWFrOworICAgIH0KKyAgICBjYXNlIC0xMDc0Mzk1OTkzOiB7CisgICAgICBlcnJvclRleHQgPSAiRVJSX0ZJTEVfSU9fRVJSIjsKKyAgICAgIGJyZWFrOworICAgIH0KKyAgICBjYXNlIC0xMDc0Mzk1OTk0OiB7CisgICAgICBlcnJvclRleHQgPSAiRVJSX0ZJTEVfVE9PX01BTllfT1BFTiI7CisgICAgICBicmVhazsKKyAgICB9CisgICAgY2FzZSAtMTA3NDM5NTk5NTogeworICAgICAgZXJyb3JUZXh0ID0gIkVSUl9GSUxFX05PVF9GT1VORCI7CisgICAgICBicmVhazsKKyAgICB9CisgICAgY2FzZSAtMTA3NDM5NTk5NjogeworICAgICAgZXJyb3JUZXh0ID0gIkVSUl9GSUxFX09QRU4iOworICAgICAgYnJlYWs7CisgICAgfQorICAgIGNhc2UgLTEwNzQzOTU5OTc6IHsKKyAgICAgIGVycm9yVGV4dCA9ICJFUlJfRklMRV9BUkdFUlIiOworICAgICAgYnJlYWs7CisgICAgfQorICAgIGNhc2UgLTEwNzQzOTU5OTg6IHsKKyAgICAgIGVycm9yVGV4dCA9ICJFUlJfRklMRV9DT0xPUl9UQUJMRSI7CisgICAgICBicmVhazsKKyAgICB9CisgICAgY2FzZSAtMTA3NDM5NTk5OTogeworICAgICAgZXJyb3JUZXh0ID0gIkVSUl9GSUxFX0ZJTEVfVFlQRSI7CisgICAgICBicmVhazsKKyAgICB9CisgICAgY2FzZSAtMTA3NDM5NjAwMDogeworICAgICAgZXJyb3JUZXh0ID0gIkVSUl9GSUxFX0ZJTEVfSEVBREVSIjsKKyAgICAgIGJyZWFrOworICAgIH0KKyAgICBjYXNlIC0xMDc0Mzk2MDAxOiB7CisgICAgICBlcnJvclRleHQgPSAiRVJSX1RPT19NQU5ZX0FWSV9TRVNTSU9OUyI7CisgICAgICBicmVhazsKKyAgICB9CisgICAgY2FzZSAtMTA3NDM5NjAwMjogeworICAgICAgZXJyb3JUZXh0ID0gIkVSUl9JTlZBTElEX0xJTkVHQVVHRU1FVEhPRCI7CisgICAgICBicmVhazsKKyAgICB9CisgICAgY2FzZSAtMTA3NDM5NjAwMzogeworICAgICAgZXJyb3JUZXh0ID0gIkVSUl9BVklfREFUQV9FWENFRURTX0JVRkZFUl9TSVpFIjsKKyAgICAgIGJyZWFrOworICAgIH0KKyAgICBjYXNlIC0xMDc0Mzk2MDA0OiB7CisgICAgICBlcnJvclRleHQgPSAiRVJSX0RJUkVDVFhfQ0VSVElGSUNBVElPTl9GQUlMVVJFIjsKKyAgICAgIGJyZWFrOworICAgIH0KKyAgICBjYXNlIC0xMDc0Mzk2MDA1OiB7CisgICAgICBlcnJvclRleHQgPSAiRVJSX0lOVkFMSURfQVZJX1NFU1NJT04iOworICAgICAgYnJlYWs7CisgICAgfQorICAgIGNhc2UgLTEwNzQzOTYwMDY6IHsKKyAgICAgIGVycm9yVGV4dCA9ICJFUlJfRElSRUNUWF9VTktOT1dOX0NPTVBSRVNTSU9OX0ZJTFRFUiI7CisgICAgICBicmVhazsKKyAgICB9CisgICAgY2FzZSAtMTA3NDM5NjAwNzogeworICAgICAgZXJyb3JUZXh0ID0gIkVSUl9ESVJFQ1RYX0lOQ09NUEFUSUJMRV9DT01QUkVTU0lPTl9GSUxURVIiOworICAgICAgYnJlYWs7CisgICAgfQorICAgIGNhc2UgLTEwNzQzOTYwMDg6IHsKKyAgICAgIGVycm9yVGV4dCA9ICJFUlJfRElSRUNUWF9OT19GSUxURVIiOworICAgICAgYnJlYWs7CisgICAgfQorICAgIGNhc2UgLTEwNzQzOTYwMDk6IHsKKyAgICAgIGVycm9yVGV4dCA9ICJFUlJfRElSRUNUWCI7CisgICAgICBicmVhazsKKyAgICB9CisgICAgY2FzZSAtMTA3NDM5NjAxMDogeworICAgICAgZXJyb3JUZXh0ID0gIkVSUl9JTlZBTElEX0ZSQU1FX05VTUJFUiI7CisgICAgICBicmVhazsKKyAgICB9CisgICAgY2FzZSAtMTA3NDM5NjAxMTogeworICAgICAgZXJyb3JUZXh0ID0gIkVSUl9SUENfQklORCI7CisgICAgICBicmVhazsKKyAgICB9CisgICAgY2FzZSAtMTA3NDM5NjAxMjogeworICAgICAgZXJyb3JUZXh0ID0gIkVSUl9SUENfRVhFQ1VURSI7CisgICAgICBicmVhazsKKyAgICB9CisgICAgY2FzZSAtMTA3NDM5NjAxMzogeworICAgICAgZXJyb3JUZXh0ID0gIkVSUl9JTlZBTElEX1ZJREVPX01PREUiOworICAgICAgYnJlYWs7CisgICAgfQorICAgIGNhc2UgLTEwNzQzOTYwMTQ6IHsKKyAgICAgIGVycm9yVGV4dCA9ICJFUlJfSU5WQUxJRF9WSURFT19CTElUIjsKKyAgICAgIGJyZWFrOworICAgIH0KKyAgICBjYXNlIC0xMDc0Mzk2MDE1OiB7CisgICAgICBlcnJvclRleHQgPSAiRVJSX1JQQ19FWEVDVVRFX0lWQiI7CisgICAgICBicmVhazsKKyAgICB9CisgICAgY2FzZSAtMTA3NDM5NjAxNjogeworICAgICAgZXJyb3JUZXh0ID0gIkVSUl9OT19WSURFT19EUklWRVIiOworICAgICAgYnJlYWs7CisgICAgfQorICAgIGNhc2UgLTEwNzQzOTYwMTc6IHsKKyAgICAgIGVycm9yVGV4dCA9ICJFUlJfT1BFTklOR19ORVdFUl9BSU1fR1JBRElOR19EQVRBIjsKKyAgICAgIGJyZWFrOworICAgIH0KKyAgICBjYXNlIC0xMDc0Mzk2MDE4OiB7CisgICAgICBlcnJvclRleHQgPSAiRVJSX0lOVkFMSURfRURHRV9QT0xBUklUWV9TRUFSQ0hfTU9ERSI7CisgICAgICBicmVhazsKKyAgICB9CisgICAgY2FzZSAtMTA3NDM5NjAxOTogeworICAgICAgZXJyb3JUZXh0ID0gIkVSUl9JTlZBTElEX1RIUkVTSE9MRF9QRVJDRU5UQUdFIjsKKyAgICAgIGJyZWFrOworICAgIH0KKyAgICBjYXNlIC0xMDc0Mzk2MDIwOiB7CisgICAgICBlcnJvclRleHQgPSAiRVJSX0lOVkFMSURfR1JBRElOR19NT0RFIjsKKyAgICAgIGJyZWFrOworICAgIH0KKyAgICBjYXNlIC0xMDc0Mzk2MDIxOiB7CisgICAgICBlcnJvclRleHQgPSAiRVJSX0lOVkFMSURfS0VSTkVMX1NJWkVfRk9SX0VER0VfREVURUNUSU9OIjsKKyAgICAgIGJyZWFrOworICAgIH0KKyAgICBjYXNlIC0xMDc0Mzk2MDIyOiB7CisgICAgICBlcnJvclRleHQgPSAiRVJSX0lOVkFMSURfU0VBUkNIX01PREVfRk9SX1NUUkFJR0hUX0VER0UiOworICAgICAgYnJlYWs7CisgICAgfQorICAgIGNhc2UgLTEwNzQzOTYwMjM6IHsKKyAgICAgIGVycm9yVGV4dCA9ICJFUlJfSU5WQUxJRF9BTkdMRV9UT0xfRk9SX1NUUkFJR0hUX0VER0UiOworICAgICAgYnJlYWs7CisgICAgfQorICAgIGNhc2UgLTEwNzQzOTYwMjQ6IHsKKyAgICAgIGVycm9yVGV4dCA9ICJFUlJfSU5WQUxJRF9NSU5fQ09WRVJBR0VfRk9SX1NUUkFJR0hUX0VER0UiOworICAgICAgYnJlYWs7CisgICAgfQorICAgIGNhc2UgLTEwNzQzOTYwMjU6IHsKKyAgICAgIGVycm9yVGV4dCA9ICJFUlJfSU5WQUxJRF9BTkdMRV9SQU5HRV9GT1JfU1RSQUlHSFRfRURHRSI7CisgICAgICBicmVhazsKKyAgICB9CisgICAgY2FzZSAtMTA3NDM5NjAyNjogeworICAgICAgZXJyb3JUZXh0ID0gIkVSUl9JTlZBTElEX1BST0NFU1NfVFlQRV9GT1JfRURHRV9ERVRFQ1RJT04iOworICAgICAgYnJlYWs7CisgICAgfQorICAgIGNhc2UgLTEwNzQzOTYwMzI6IHsKKyAgICAgIGVycm9yVGV4dCA9ICJFUlJfVEVNUExBVEVERVNDUklQVE9SX1JPVEFUSU9OX1NFQVJDSFNUUkFURUdZIjsKKyAgICAgIGJyZWFrOworICAgIH0KKyAgICBjYXNlIC0xMDc0Mzk2MDMzOiB7CisgICAgICBlcnJvclRleHQgPSAiRVJSX1RFTVBMQVRFREVTQ1JJUFRPUl9MRUFSTlNFVFVQREFUQSI7CisgICAgICBicmVhazsKKyAgICB9CisgICAgY2FzZSAtMTA3NDM5NjAzNDogeworICAgICAgZXJyb3JUZXh0ID0gIkVSUl9URU1QTEFURUlNQUdFX0VER0VJTkZPIjsKKyAgICAgIGJyZWFrOworICAgIH0KKyAgICBjYXNlIC0xMDc0Mzk2MDM1OiB7CisgICAgICBlcnJvclRleHQgPSAiRVJSX1RFTVBMQVRFSU1BR0VfTk9DSVJDTEUiOworICAgICAgYnJlYWs7CisgICAgfQorICAgIGNhc2UgLTEwNzQzOTYwMzY6IHsKKyAgICAgIGVycm9yVGV4dCA9ICJFUlJfSU5WQUxJRF9TS0VMRVRPTk1PREUiOworICAgICAgYnJlYWs7CisgICAgfQorICAgIGNhc2UgLTEwNzQzOTYwMzc6IHsKKyAgICAgIGVycm9yVGV4dCA9ICJFUlJfVElNRU9VVCI7CisgICAgICBicmVhazsKKyAgICB9CisgICAgY2FzZSAtMTA3NDM5NjAzODogeworICAgICAgZXJyb3JUZXh0ID0gIkVSUl9GSU5EX0NPT1JEU1lTX01PUkVfVEhBTl9PTkVfRURHRSI7CisgICAgICBicmVhazsKKyAgICB9CisgICAgY2FzZSAtMTA3NDM5NjAzOTogeworICAgICAgZXJyb3JUZXh0ID0gIkVSUl9JT19FUlJPUiI7CisgICAgICBicmVhazsKKyAgICB9CisgICAgY2FzZSAtMTA3NDM5NjA0MDogeworICAgICAgZXJyb3JUZXh0ID0gIkVSUl9EUklWRVIiOworICAgICAgYnJlYWs7CisgICAgfQorICAgIGNhc2UgLTEwNzQzOTYwNDE6IHsKKyAgICAgIGVycm9yVGV4dCA9ICJFUlJfSU5WQUxJRF8yRF9CQVJDT0RFX1RZUEUiOworICAgICAgYnJlYWs7CisgICAgfQorICAgIGNhc2UgLTEwNzQzOTYwNDI6IHsKKyAgICAgIGVycm9yVGV4dCA9ICJFUlJfSU5WQUxJRF8yRF9CQVJDT0RFX0NPTlRSQVNUIjsKKyAgICAgIGJyZWFrOworICAgIH0KKyAgICBjYXNlIC0xMDc0Mzk2MDQzOiB7CisgICAgICBlcnJvclRleHQgPSAiRVJSX0lOVkFMSURfMkRfQkFSQ09ERV9DRUxMX1NIQVBFIjsKKyAgICAgIGJyZWFrOworICAgIH0KKyAgICBjYXNlIC0xMDc0Mzk2MDQ0OiB7CisgICAgICBlcnJvclRleHQgPSAiRVJSX0lOVkFMSURfMkRfQkFSQ09ERV9TSEFQRSI7CisgICAgICBicmVhazsKKyAgICB9CisgICAgY2FzZSAtMTA3NDM5NjA0NTogeworICAgICAgZXJyb3JUZXh0ID0gIkVSUl9JTlZBTElEXzJEX0JBUkNPREVfU1VCVFlQRSI7CisgICAgICBicmVhazsKKyAgICB9CisgICAgY2FzZSAtMTA3NDM5NjA0NjogeworICAgICAgZXJyb3JUZXh0ID0gIkVSUl9JTlZBTElEXzJEX0JBUkNPREVfQ09OVFJBU1RfRk9SX1JPSSI7CisgICAgICBicmVhazsKKyAgICB9CisgICAgY2FzZSAtMTA3NDM5NjA0NzogeworICAgICAgZXJyb3JUZXh0ID0gIkVSUl9JTlZBTElEX0xJTkVBUl9BVkVSQUdFX01PREUiOworICAgICAgYnJlYWs7CisgICAgfQorICAgIGNhc2UgLTEwNzQzOTYwNDg6IHsKKyAgICAgIGVycm9yVGV4dCA9ICJFUlJfSU5WQUxJRF9DRUxMX1NBTVBMRV9TSVpFIjsKKyAgICAgIGJyZWFrOworICAgIH0KKyAgICBjYXNlIC0xMDc0Mzk2MDQ5OiB7CisgICAgICBlcnJvclRleHQgPSAiRVJSX0lOVkFMSURfTUFUUklYX1BPTEFSSVRZIjsKKyAgICAgIGJyZWFrOworICAgIH0KKyAgICBjYXNlIC0xMDc0Mzk2MDUwOiB7CisgICAgICBlcnJvclRleHQgPSAiRVJSX0lOVkFMSURfRUNDX1RZUEUiOworICAgICAgYnJlYWs7CisgICAgfQorICAgIGNhc2UgLTEwNzQzOTYwNTE6IHsKKyAgICAgIGVycm9yVGV4dCA9ICJFUlJfSU5WQUxJRF9DRUxMX0ZJTFRFUl9NT0RFIjsKKyAgICAgIGJyZWFrOworICAgIH0KKyAgICBjYXNlIC0xMDc0Mzk2MDUyOiB7CisgICAgICBlcnJvclRleHQgPSAiRVJSX0lOVkFMSURfREVNT0RVTEFUSU9OX01PREUiOworICAgICAgYnJlYWs7CisgICAgfQorICAgIGNhc2UgLTEwNzQzOTYwNTM6IHsKKyAgICAgIGVycm9yVGV4dCA9ICJFUlJfSU5WQUxJRF9CT1JERVJfSU5URUdSSVRZIjsKKyAgICAgIGJyZWFrOworICAgIH0KKyAgICBjYXNlIC0xMDc0Mzk2MDU0OiB7CisgICAgICBlcnJvclRleHQgPSAiRVJSX0lOVkFMSURfQ0VMTF9GSUxMX1RZUEUiOworICAgICAgYnJlYWs7CisgICAgfQorICAgIGNhc2UgLTEwNzQzOTYwNTU6IHsKKyAgICAgIGVycm9yVGV4dCA9ICJFUlJfSU5WQUxJRF9BU1BFQ1RfUkFUSU8iOworICAgICAgYnJlYWs7CisgICAgfQorICAgIGNhc2UgLTEwNzQzOTYwNTY6IHsKKyAgICAgIGVycm9yVGV4dCA9ICJFUlJfSU5WQUxJRF9NQVRSSVhfTUlSUk9SX01PREUiOworICAgICAgYnJlYWs7CisgICAgfQorICAgIGNhc2UgLTEwNzQzOTYwNTc6IHsKKyAgICAgIGVycm9yVGV4dCA9ICJFUlJfSU5WQUxJRF9TRUFSQ0hfVkVDVE9SX1dJRFRIIjsKKyAgICAgIGJyZWFrOworICAgIH0KKyAgICBjYXNlIC0xMDc0Mzk2MDU4OiB7CisgICAgICBlcnJvclRleHQgPSAiRVJSX0lOVkFMSURfUk9UQVRJT05fTU9ERSI7CisgICAgICBicmVhazsKKyAgICB9CisgICAgY2FzZSAtMTA3NDM5NjA1OTogeworICAgICAgZXJyb3JUZXh0ID0gIkVSUl9JTlZBTElEX01BWF9JVEVSQVRJT05TIjsKKyAgICAgIGJyZWFrOworICAgIH0KKyAgICBjYXNlIC0xMDc0Mzk2MDYwOiB7CisgICAgICBlcnJvclRleHQgPSAiRVJSX0pQRUcyMDAwX0xPU1NMRVNTX1dJVEhfRkxPQVRJTkdfUE9JTlQiOworICAgICAgYnJlYWs7CisgICAgfQorICAgIGNhc2UgLTEwNzQzOTYwNjE6IHsKKyAgICAgIGVycm9yVGV4dCA9ICJFUlJfSU5WQUxJRF9XSU5ET1dfU0laRSI7CisgICAgICBicmVhazsKKyAgICB9CisgICAgY2FzZSAtMTA3NDM5NjA2MjogeworICAgICAgZXJyb3JUZXh0ID0gIkVSUl9JTlZBTElEX1RPTEVSQU5DRSI7CisgICAgICBicmVhazsKKyAgICB9CisgICAgY2FzZSAtMTA3NDM5NjA2MzogeworICAgICAgZXJyb3JUZXh0ID0gIkVSUl9FWFRFUk5BTF9BTElHTk1FTlQiOworICAgICAgYnJlYWs7CisgICAgfQorICAgIGNhc2UgLTEwNzQzOTYwNjQ6IHsKKyAgICAgIGVycm9yVGV4dCA9ICJFUlJfRVhURVJOQUxfTk9UX1NVUFBPUlRFRCI7CisgICAgICBicmVhazsKKyAgICB9CisgICAgY2FzZSAtMTA3NDM5NjA2NTogeworICAgICAgZXJyb3JUZXh0ID0gIkVSUl9DQU5UX1JFU0laRV9FWFRFUk5BTCI7CisgICAgICBicmVhazsKKyAgICB9CisgICAgY2FzZSAtMTA3NDM5NjA2NjogeworICAgICAgZXJyb3JUZXh0ID0gIkVSUl9JTlZBTElEX1BPSU5UU1lNQk9MIjsKKyAgICAgIGJyZWFrOworICAgIH0KKyAgICBjYXNlIC0xMDc0Mzk2MDY3OiB7CisgICAgICBlcnJvclRleHQgPSAiRVJSX0lNQUdFU19OT1RfRElGRiI7CisgICAgICBicmVhazsKKyAgICB9CisgICAgY2FzZSAtMTA3NDM5NjA2ODogeworICAgICAgZXJyb3JUZXh0ID0gIkVSUl9JTlZBTElEX0FDVElPTiI7CisgICAgICBicmVhazsKKyAgICB9CisgICAgY2FzZSAtMTA3NDM5NjA2OTogeworICAgICAgZXJyb3JUZXh0ID0gIkVSUl9JTlZBTElEX0NPTE9SX01PREUiOworICAgICAgYnJlYWs7CisgICAgfQorICAgIGNhc2UgLTEwNzQzOTYwNzA6IHsKKyAgICAgIGVycm9yVGV4dCA9ICJFUlJfSU5WQUxJRF9GVU5DVElPTiI7CisgICAgICBicmVhazsKKyAgICB9CisgICAgY2FzZSAtMTA3NDM5NjA3MTogeworICAgICAgZXJyb3JUZXh0ID0gIkVSUl9JTlZBTElEX1NDQU5fRElSRUNUSU9OIjsKKyAgICAgIGJyZWFrOworICAgIH0KKyAgICBjYXNlIC0xMDc0Mzk2MDcyOiB7CisgICAgICBlcnJvclRleHQgPSAiRVJSX0lOVkFMSURfQk9SREVSIjsKKyAgICAgIGJyZWFrOworICAgIH0KKyAgICBjYXNlIC0xMDc0Mzk2MDczOiB7CisgICAgICBlcnJvclRleHQgPSAiRVJSX01BU0tfT1VUU0lERV9JTUFHRSI7CisgICAgICBicmVhazsKKyAgICB9CisgICAgY2FzZSAtMTA3NDM5NjA3NDogeworICAgICAgZXJyb3JUZXh0ID0gIkVSUl9JTkNPTVBfU0laRSI7CisgICAgICBicmVhazsKKyAgICB9CisgICAgY2FzZSAtMTA3NDM5NjA3NTogeworICAgICAgZXJyb3JUZXh0ID0gIkVSUl9DT09SRF9TWVNfU0VDT05EX0FYSVMiOworICAgICAgYnJlYWs7CisgICAgfQorICAgIGNhc2UgLTEwNzQzOTYwNzY6IHsKKyAgICAgIGVycm9yVGV4dCA9ICJFUlJfQ09PUkRfU1lTX0ZJUlNUX0FYSVMiOworICAgICAgYnJlYWs7CisgICAgfQorICAgIGNhc2UgLTEwNzQzOTYwNzc6IHsKKyAgICAgIGVycm9yVGV4dCA9ICJFUlJfSU5DT01QX1RZUEUiOworICAgICAgYnJlYWs7CisgICAgfQorICAgIGNhc2UgLTEwNzQzOTYwNzk6IHsKKyAgICAgIGVycm9yVGV4dCA9ICJFUlJfSU5WQUxJRF9NRVRBRklMRV9IQU5ETEUiOworICAgICAgYnJlYWs7CisgICAgfQorICAgIGNhc2UgLTEwNzQzOTYwODA6IHsKKyAgICAgIGVycm9yVGV4dCA9ICJFUlJfSU5WQUxJRF9JTUFHRV9UWVBFIjsKKyAgICAgIGJyZWFrOworICAgIH0KKyAgICBjYXNlIC0xMDc0Mzk2MDgxOiB7CisgICAgICBlcnJvclRleHQgPSAiRVJSX0JBRF9QQVNTV09SRCI7CisgICAgICBicmVhazsKKyAgICB9CisgICAgY2FzZSAtMTA3NDM5NjA4MjogeworICAgICAgZXJyb3JUZXh0ID0gIkVSUl9QQUxFVFRFX05PVF9TVVBQT1JURUQiOworICAgICAgYnJlYWs7CisgICAgfQorICAgIGNhc2UgLTEwNzQzOTYwODM6IHsKKyAgICAgIGVycm9yVGV4dCA9ICJFUlJfUk9MTEJBQ0tfVElNRU9VVCI7CisgICAgICBicmVhazsKKyAgICB9CisgICAgY2FzZSAtMTA3NDM5NjA4NDogeworICAgICAgZXJyb3JUZXh0ID0gIkVSUl9ST0xMQkFDS19ERUxFVEVfVElNRVIiOworICAgICAgYnJlYWs7CisgICAgfQorICAgIGNhc2UgLTEwNzQzOTYwODU6IHsKKyAgICAgIGVycm9yVGV4dCA9ICJFUlJfUk9MTEJBQ0tfSU5JVF9USU1FUiI7CisgICAgICBicmVhazsKKyAgICB9CisgICAgY2FzZSAtMTA3NDM5NjA4NjogeworICAgICAgZXJyb3JUZXh0ID0gIkVSUl9ST0xMQkFDS19TVEFSVF9USU1FUiI7CisgICAgICBicmVhazsKKyAgICB9CisgICAgY2FzZSAtMTA3NDM5NjA4NzogeworICAgICAgZXJyb3JUZXh0ID0gIkVSUl9ST0xMQkFDS19TVE9QX1RJTUVSIjsKKyAgICAgIGJyZWFrOworICAgIH0KKyAgICBjYXNlIC0xMDc0Mzk2MDg4OiB7CisgICAgICBlcnJvclRleHQgPSAiRVJSX1JPTExCQUNLX1JFU0laRSI7CisgICAgICBicmVhazsKKyAgICB9CisgICAgY2FzZSAtMTA3NDM5NjA4OTogeworICAgICAgZXJyb3JUZXh0ID0gIkVSUl9ST0xMQkFDS19SRVNPVVJDRV9SRUlOSVRJQUxJWkUiOworICAgICAgYnJlYWs7CisgICAgfQorICAgIGNhc2UgLTEwNzQzOTYwOTA6IHsKKyAgICAgIGVycm9yVGV4dCA9ICJFUlJfUk9MTEJBQ0tfUkVTT1VSQ0VfRU5BQkxFRCI7CisgICAgICBicmVhazsKKyAgICB9CisgICAgY2FzZSAtMTA3NDM5NjA5MTogeworICAgICAgZXJyb3JUZXh0ID0gIkVSUl9ST0xMQkFDS19SRVNPVVJDRV9VTklOSVRJQUxJWkVEX0VOQUJMRSI7CisgICAgICBicmVhazsKKyAgICB9CisgICAgY2FzZSAtMTA3NDM5NjA5MjogeworICAgICAgZXJyb3JUZXh0ID0gIkVSUl9ST0xMQkFDS19SRVNPVVJDRV9OT05fRU1QVFlfSU5JVElBTElaRSI7CisgICAgICBicmVhazsKKyAgICB9CisgICAgY2FzZSAtMTA3NDM5NjA5MzogeworICAgICAgZXJyb3JUZXh0ID0gIkVSUl9ST0xMQkFDS19SRVNPVVJDRV9MT0NLRUQiOworICAgICAgYnJlYWs7CisgICAgfQorICAgIGNhc2UgLTEwNzQzOTYwOTQ6IHsKKyAgICAgIGVycm9yVGV4dCA9ICJFUlJfUk9MTEJBQ0tfUkVTT1VSQ0VfQ0FOTk9UX1VOTE9DSyI7CisgICAgICBicmVhazsKKyAgICB9CisgICAgY2FzZSAtMTA3NDM5NjA5NTogeworICAgICAgZXJyb3JUZXh0ID0gIkVSUl9DQUxJQlJBVElPTl9EVVBMSUNBVEVfUkVGRVJFTkNFX1BPSU5UIjsKKyAgICAgIGJyZWFrOworICAgIH0KKyAgICBjYXNlIC0xMDc0Mzk2MDk2OiB7CisgICAgICBlcnJvclRleHQgPSAiRVJSX05PVF9BTl9PQkpFQ1QiOworICAgICAgYnJlYWs7CisgICAgfQorICAgIGNhc2UgLTEwNzQzOTYwOTc6IHsKKyAgICAgIGVycm9yVGV4dCA9ICJFUlJfSU5WQUxJRF9QQVJUSUNMRV9QQVJBTUVURVJfVkFMVUUiOworICAgICAgYnJlYWs7CisgICAgfQorICAgIGNhc2UgLTEwNzQzOTYwOTg6IHsKKyAgICAgIGVycm9yVGV4dCA9ICJFUlJfUkVTRVJWRURfTVVTVF9CRV9udWxscHRyIjsKKyAgICAgIGJyZWFrOworICAgIH0KKyAgICBjYXNlIC0xMDc0Mzk2MDk5OiB7CisgICAgICBlcnJvclRleHQgPSAiRVJSX0NBTElCUkFUSU9OX0lORk9fU0lNUExFX1RSQU5TRk9STSI7CisgICAgICBicmVhazsKKyAgICB9CisgICAgY2FzZSAtMTA3NDM5NjEwMDogeworICAgICAgZXJyb3JUZXh0ID0gIkVSUl9DQUxJQlJBVElPTl9JTkZPX1BFUlNQRUNUSVZFX1BST0pFQ1RJT04iOworICAgICAgYnJlYWs7CisgICAgfQorICAgIGNhc2UgLTEwNzQzOTYxMDE6IHsKKyAgICAgIGVycm9yVGV4dCA9ICJFUlJfQ0FMSUJSQVRJT05fSU5GT19NSUNST19QTEFORSI7CisgICAgICBicmVhazsKKyAgICB9CisgICAgY2FzZSAtMTA3NDM5NjEwMjogeworICAgICAgZXJyb3JUZXh0ID0gIkVSUl9DQUxJQlJBVElPTl9JTkZPXzYiOworICAgICAgYnJlYWs7CisgICAgfQorICAgIGNhc2UgLTEwNzQzOTYxMDM6IHsKKyAgICAgIGVycm9yVGV4dCA9ICJFUlJfQ0FMSUJSQVRJT05fSU5GT181IjsKKyAgICAgIGJyZWFrOworICAgIH0KKyAgICBjYXNlIC0xMDc0Mzk2MTA0OiB7CisgICAgICBlcnJvclRleHQgPSAiRVJSX0NBTElCUkFUSU9OX0lORk9fNCI7CisgICAgICBicmVhazsKKyAgICB9CisgICAgY2FzZSAtMTA3NDM5NjEwNTogeworICAgICAgZXJyb3JUZXh0ID0gIkVSUl9DQUxJQlJBVElPTl9JTkZPXzMiOworICAgICAgYnJlYWs7CisgICAgfQorICAgIGNhc2UgLTEwNzQzOTYxMDY6IHsKKyAgICAgIGVycm9yVGV4dCA9ICJFUlJfQ0FMSUJSQVRJT05fSU5GT18yIjsKKyAgICAgIGJyZWFrOworICAgIH0KKyAgICBjYXNlIC0xMDc0Mzk2MTA3OiB7CisgICAgICBlcnJvclRleHQgPSAiRVJSX0NBTElCUkFUSU9OX0lORk9fMSI7CisgICAgICBicmVhazsKKyAgICB9CisgICAgY2FzZSAtMTA3NDM5NjEwODogeworICAgICAgZXJyb3JUZXh0ID0gIkVSUl9DQUxJQlJBVElPTl9FUlJPUk1BUCI7CisgICAgICBicmVhazsKKyAgICB9CisgICAgY2FzZSAtMTA3NDM5NjEwOTogeworICAgICAgZXJyb3JUZXh0ID0gIkVSUl9DQUxJQlJBVElPTl9JTlZBTElEX1NDQUxJTkdfRkFDVE9SIjsKKyAgICAgIGJyZWFrOworICAgIH0KKyAgICBjYXNlIC0xMDc0Mzk2MTEwOiB7CisgICAgICBlcnJvclRleHQgPSAiRVJSX0NBTElCUkFUSU9OX0lORk9fVkVSU0lPTiI7CisgICAgICBicmVhazsKKyAgICB9CisgICAgY2FzZSAtMTA3NDM5NjExMTogeworICAgICAgZXJyb3JUZXh0ID0gIkVSUl9DQUxJQlJBVElPTl9GQUlMRURfVE9fRklORF9HUklEIjsKKyAgICAgIGJyZWFrOworICAgIH0KKyAgICBjYXNlIC0xMDc0Mzk2MTEyOiB7CisgICAgICBlcnJvclRleHQgPSAiRVJSX0lOQ09NUF9NQVRSSVhfU0laRSI7CisgICAgICBicmVhazsKKyAgICB9CisgICAgY2FzZSAtMTA3NDM5NjExMzogeworICAgICAgZXJyb3JUZXh0ID0gIkVSUl9DQUxJQlJBVElPTl9JTUFHRV9VTkNBTElCUkFURUQiOworICAgICAgYnJlYWs7CisgICAgfQorICAgIGNhc2UgLTEwNzQzOTYxMTQ6IHsKKyAgICAgIGVycm9yVGV4dCA9ICJFUlJfQ0FMSUJSQVRJT05fSU5WQUxJRF9ST0kiOworICAgICAgYnJlYWs7CisgICAgfQorICAgIGNhc2UgLTEwNzQzOTYxMTU6IHsKKyAgICAgIGVycm9yVGV4dCA9ICJFUlJfQ0FMSUJSQVRJT05fSU1BR0VfQ09SUkVDVEVEIjsKKyAgICAgIGJyZWFrOworICAgIH0KKyAgICBjYXNlIC0xMDc0Mzk2MTE2OiB7CisgICAgICBlcnJvclRleHQgPSAiRVJSX0NBTElCUkFUSU9OX0lOU0ZfUE9JTlRTIjsKKyAgICAgIGJyZWFrOworICAgIH0KKyAgICBjYXNlIC0xMDc0Mzk2MTE3OiB7CisgICAgICBlcnJvclRleHQgPSAiRVJSX01BVFJJWF9TSVpFIjsKKyAgICAgIGJyZWFrOworICAgIH0KKyAgICBjYXNlIC0xMDc0Mzk2MTE4OiB7CisgICAgICBlcnJvclRleHQgPSAiRVJSX0lOVkFMSURfU1RFUF9TSVpFIjsKKyAgICAgIGJyZWFrOworICAgIH0KKyAgICBjYXNlIC0xMDc0Mzk2MTE5OiB7CisgICAgICBlcnJvclRleHQgPSAiRVJSX0NVU1RPTURBVEFfSU5WQUxJRF9LRVkiOworICAgICAgYnJlYWs7CisgICAgfQorICAgIGNhc2UgLTEwNzQzOTYxMjA6IHsKKyAgICAgIGVycm9yVGV4dCA9ICJFUlJfTk9UX0lNQUdFIjsKKyAgICAgIGJyZWFrOworICAgIH0KKyAgICBjYXNlIC0xMDc0Mzk2MTIxOiB7CisgICAgICBlcnJvclRleHQgPSAiRVJSX1NBVFVSQVRJT05fVEhSRVNIT0xEX09VVF9PRl9SQU5HRSI7CisgICAgICBicmVhazsKKyAgICB9CisgICAgY2FzZSAtMTA3NDM5NjEyMjogeworICAgICAgZXJyb3JUZXh0ID0gIkVSUl9EUkFXVEVYVF9DT0xPUl9NVVNUX0JFX0dSQVlTQ0FMRSI7CisgICAgICBicmVhazsKKyAgICB9CisgICAgY2FzZSAtMTA3NDM5NjEyMzogeworICAgICAgZXJyb3JUZXh0ID0gIkVSUl9JTlZBTElEX0NBTElCUkFUSU9OX01PREUiOworICAgICAgYnJlYWs7CisgICAgfQorICAgIGNhc2UgLTEwNzQzOTYxMjQ6IHsKKyAgICAgIGVycm9yVGV4dCA9ICJFUlJfSU5WQUxJRF9DQUxJQlJBVElPTl9ST0lfTU9ERSI7CisgICAgICBicmVhazsKKyAgICB9CisgICAgY2FzZSAtMTA3NDM5NjEyNTogeworICAgICAgZXJyb3JUZXh0ID0gIkVSUl9JTlZBTElEX0NPTlRSQVNUX1RIUkVTSE9MRCI7CisgICAgICBicmVhazsKKyAgICB9CisgICAgY2FzZSAtMTA3NDM5NjEyNjogeworICAgICAgZXJyb3JUZXh0ID0gIkVSUl9ST0xMQkFDS19SRVNPVVJDRV9DT05GTElDVF8xIjsKKyAgICAgIGJyZWFrOworICAgIH0KKyAgICBjYXNlIC0xMDc0Mzk2MTI3OiB7CisgICAgICBlcnJvclRleHQgPSAiRVJSX1JPTExCQUNLX1JFU09VUkNFX0NPTkZMSUNUXzIiOworICAgICAgYnJlYWs7CisgICAgfQorICAgIGNhc2UgLTEwNzQzOTYxMjg6IHsKKyAgICAgIGVycm9yVGV4dCA9ICJFUlJfUk9MTEJBQ0tfUkVTT1VSQ0VfQ09ORkxJQ1RfMyI7CisgICAgICBicmVhazsKKyAgICB9CisgICAgY2FzZSAtMTA3NDM5NjEyOTogeworICAgICAgZXJyb3JUZXh0ID0gIkVSUl9ST0xMQkFDS19VTkJPVU5ERURfSU5URVJGQUNFIjsKKyAgICAgIGJyZWFrOworICAgIH0KKyAgICBjYXNlIC0xMDc0Mzk2MTMwOiB7CisgICAgICBlcnJvclRleHQgPSAiRVJSX05PVF9SRUNUX09SX1JPVEFURURfUkVDVCI7CisgICAgICBicmVhazsKKyAgICB9CisgICAgY2FzZSAtMTA3NDM5NjEzMjogeworICAgICAgZXJyb3JUZXh0ID0gIkVSUl9NQVNLX05PVF9URU1QTEFURV9TSVpFIjsKKyAgICAgIGJyZWFrOworICAgIH0KKyAgICBjYXNlIC0xMDc0Mzk2MTMzOiB7CisgICAgICBlcnJvclRleHQgPSAiRVJSX1RIUkVBRF9DT1VMRF9OT1RfSU5JVElBTElaRSI7CisgICAgICBicmVhazsKKyAgICB9CisgICAgY2FzZSAtMTA3NDM5NjEzNDogeworICAgICAgZXJyb3JUZXh0ID0gIkVSUl9USFJFQURfSU5JVElBTElaSU5HIjsKKyAgICAgIGJyZWFrOworICAgIH0KKyAgICBjYXNlIC0xMDc0Mzk2MTM1OiB7CisgICAgICBlcnJvclRleHQgPSAiRVJSX0lOVkFMSURfQlVUVE9OX0xBQkVMIjsKKyAgICAgIGJyZWFrOworICAgIH0KKyAgICBjYXNlIC0xMDc0Mzk2MTM2OiB7CisgICAgICBlcnJvclRleHQgPSAiRVJSX0RJUkVDVFhfSU5WQUxJRF9GSUxURVJfUVVBTElUWSI7CisgICAgICBicmVhazsKKyAgICB9CisgICAgY2FzZSAtMTA3NDM5NjEzNzogeworICAgICAgZXJyb3JUZXh0ID0gIkVSUl9ESVJFQ1RYX0RMTF9OT1RfRk9VTkQiOworICAgICAgYnJlYWs7CisgICAgfQorICAgIGNhc2UgLTEwNzQzOTYxMzg6IHsKKyAgICAgIGVycm9yVGV4dCA9ICJFUlJfUk9MTEJBQ0tfTk9UX1NVUFBPUlRFRCI7CisgICAgICBicmVhazsKKyAgICB9CisgICAgY2FzZSAtMTA3NDM5NjEzOTogeworICAgICAgZXJyb3JUZXh0ID0gIkVSUl9ST0xMQkFDS19SRVNPVVJDRV9PVVRfT0ZfTUVNT1JZIjsKKyAgICAgIGJyZWFrOworICAgIH0KKyAgICBjYXNlIC0xMDc0Mzk2MTQwOiB7CisgICAgICBlcnJvclRleHQgPSAiRVJSX0JBUkNPREVfQ09ERTEyOF9TRVQiOworICAgICAgYnJlYWs7CisgICAgfQorICAgIGNhc2UgLTEwNzQzOTYxNDE6IHsKKyAgICAgIGVycm9yVGV4dCA9ICJFUlJfQkFSQ09ERV9DT0RFMTI4X0ZOQyI7CisgICAgICBicmVhazsKKyAgICB9CisgICAgY2FzZSAtMTA3NDM5NjE0MjogeworICAgICAgZXJyb3JUZXh0ID0gIkVSUl9CQVJDT0RFX0lOVkFMSUQiOworICAgICAgYnJlYWs7CisgICAgfQorICAgIGNhc2UgLTEwNzQzOTYxNDM6IHsKKyAgICAgIGVycm9yVGV4dCA9ICJFUlJfQkFSQ09ERV9UWVBFIjsKKyAgICAgIGJyZWFrOworICAgIH0KKyAgICBjYXNlIC0xMDc0Mzk2MTQ0OiB7CisgICAgICBlcnJvclRleHQgPSAiRVJSX0JBUkNPREVfQ09ERTkzX1NISUZUIjsKKyAgICAgIGJyZWFrOworICAgIH0KKyAgICBjYXNlIC0xMDc0Mzk2MTQ1OiB7CisgICAgICBlcnJvclRleHQgPSAiRVJSX0JBUkNPREVfVVBDQSI7CisgICAgICBicmVhazsKKyAgICB9CisgICAgY2FzZSAtMTA3NDM5NjE0NjogeworICAgICAgZXJyb3JUZXh0ID0gIkVSUl9CQVJDT0RFX01TSSI7CisgICAgICBicmVhazsKKyAgICB9CisgICAgY2FzZSAtMTA3NDM5NjE0NzogeworICAgICAgZXJyb3JUZXh0ID0gIkVSUl9CQVJDT0RFX0kyNSI7CisgICAgICBicmVhazsKKyAgICB9CisgICAgY2FzZSAtMTA3NDM5NjE0ODogeworICAgICAgZXJyb3JUZXh0ID0gIkVSUl9CQVJDT0RFX0VBTjEzIjsKKyAgICAgIGJyZWFrOworICAgIH0KKyAgICBjYXNlIC0xMDc0Mzk2MTQ5OiB7CisgICAgICBlcnJvclRleHQgPSAiRVJSX0JBUkNPREVfRUFOOCI7CisgICAgICBicmVhazsKKyAgICB9CisgICAgY2FzZSAtMTA3NDM5NjE1MDogeworICAgICAgZXJyb3JUZXh0ID0gIkVSUl9CQVJDT0RFX0NPREUxMjgiOworICAgICAgYnJlYWs7CisgICAgfQorICAgIGNhc2UgLTEwNzQzOTYxNTE6IHsKKyAgICAgIGVycm9yVGV4dCA9ICJFUlJfQkFSQ09ERV9DT0RFOTMiOworICAgICAgYnJlYWs7CisgICAgfQorICAgIGNhc2UgLTEwNzQzOTYxNTI6IHsKKyAgICAgIGVycm9yVGV4dCA9ICJFUlJfQkFSQ09ERV9DT0RFMzkiOworICAgICAgYnJlYWs7CisgICAgfQorICAgIGNhc2UgLTEwNzQzOTYxNTM6IHsKKyAgICAgIGVycm9yVGV4dCA9ICJFUlJfQkFSQ09ERV9DT0RBQkFSIjsKKyAgICAgIGJyZWFrOworICAgIH0KKyAgICBjYXNlIC0xMDc0Mzk2MTU0OiB7CisgICAgICBlcnJvclRleHQgPSAiRVJSX0lNQUdFX1RPT19TTUFMTCI7CisgICAgICBicmVhazsKKyAgICB9CisgICAgY2FzZSAtMTA3NDM5NjE1NTogeworICAgICAgZXJyb3JUZXh0ID0gIkVSUl9VTklOSVQiOworICAgICAgYnJlYWs7CisgICAgfQorICAgIGNhc2UgLTEwNzQzOTYxNTY6IHsKKyAgICAgIGVycm9yVGV4dCA9ICJFUlJfTkVFRF9GVUxMX1ZFUlNJT04iOworICAgICAgYnJlYWs7CisgICAgfQorICAgIGNhc2UgLTEwNzQzOTYxNTc6IHsKKyAgICAgIGVycm9yVGV4dCA9ICJFUlJfVU5SRUdJU1RFUkVEIjsKKyAgICAgIGJyZWFrOworICAgIH0KKyAgICBjYXNlIC0xMDc0Mzk2MTU4OiB7CisgICAgICBlcnJvclRleHQgPSAiRVJSX01FTU9SWV9FUlJPUiI7CisgICAgICBicmVhazsKKyAgICB9CisgICAgY2FzZSAtMTA3NDM5NjE1OTogeworICAgICAgZXJyb3JUZXh0ID0gIkVSUl9PVVRfT0ZfTUVNT1JZIjsKKyAgICAgIGJyZWFrOworICAgIH0KKyAgICBjYXNlIC0xMDc0Mzk2MTYwOiB7CisgICAgICBlcnJvclRleHQgPSAiRVJSX1NZU1RFTV9FUlJPUiI7CisgICAgICBicmVhazsKKyAgICB9CisgICAgY2FzZSAwOiB7CisgICAgICBlcnJvclRleHQgPSAiRVJSX1NVQ0NFU1MiOworICAgICAgYnJlYWs7CisgICAgfQorICAgIC8vIGVuZCBOYXRpb25hbCBJbnN0cnVtZW50cyBkZWZpbmVkIGVycm9ycworCisgICAgLy8gYmVnaW4gQkFFIGRlZmluZWQgZXJyb3JzCisgICAgY2FzZSBFUlJfVklTSU9OX0dFTkVSQUxfRVJST1I6IHsKKyAgICAgIGVycm9yVGV4dCA9ICJFUlJfVklTSU9OX0dFTkVSQUxfRVJST1IiOworICAgICAgYnJlYWs7CisgICAgfQorICAgIGNhc2UgRVJSX0NPTE9SX05PVF9GT1VORDogeworICAgICAgZXJyb3JUZXh0ID0gIkVSUl9DT0xPUl9OT1RfRk9VTkQiOworICAgICAgYnJlYWs7CisgICAgfQorICAgIGNhc2UgRVJSX1BBUlRJQ0xFX1RPT19TTUFMTDogeworICAgICAgZXJyb3JUZXh0ID0gIkVSUl9QQVJUSUNMRV9UT09fU01BTEwiOworICAgICAgYnJlYWs7CisgICAgfQorICAgIGNhc2UgRVJSX0NBTUVSQV9GQUlMVVJFOiB7CisgICAgICBlcnJvclRleHQgPSAiRVJSX0NBTUVSQV9GQUlMVVJFIjsKKyAgICAgIGJyZWFrOworICAgIH0KKyAgICBjYXNlIEVSUl9DQU1FUkFfU09DS0VUX0NSRUFURV9GQUlMRUQ6IHsKKyAgICAgIGVycm9yVGV4dCA9ICJFUlJfQ0FNRVJBX1NPQ0tFVF9DUkVBVEVfRkFJTEVEIjsKKyAgICAgIGJyZWFrOworICAgIH0KKyAgICBjYXNlIEVSUl9DQU1FUkFfQ09OTkVDVF9GQUlMRUQ6IHsKKyAgICAgIGVycm9yVGV4dCA9ICJFUlJfQ0FNRVJBX0NPTk5FQ1RfRkFJTEVEIjsKKyAgICAgIGJyZWFrOworICAgIH0KKyAgICBjYXNlIEVSUl9DQU1FUkFfU1RBTEVfSU1BR0U6IHsKKyAgICAgIGVycm9yVGV4dCA9ICJFUlJfQ0FNRVJBX1NUQUxFX0lNQUdFIjsKKyAgICAgIGJyZWFrOworICAgIH0KKyAgICBjYXNlIEVSUl9DQU1FUkFfTk9UX0lOSVRJQUxJWkVEOiB7CisgICAgICBlcnJvclRleHQgPSAiRVJSX0NBTUVSQV9OT1RfSU5JVElBTElaRUQiOworICAgICAgYnJlYWs7CisgICAgfQorICAgIGNhc2UgRVJSX0NBTUVSQV9OT19CVUZGRVJfQVZBSUxBQkxFOiB7CisgICAgICBlcnJvclRleHQgPSAiRVJSX0NBTUVSQV9OT19CVUZGRVJfQVZBSUxBQkxFIjsKKyAgICAgIGJyZWFrOworICAgIH0KKyAgICBjYXNlIEVSUl9DQU1FUkFfSEVBREVSX0VSUk9SOiB7CisgICAgICBlcnJvclRleHQgPSAiRVJSX0NBTUVSQV9IRUFERVJfRVJST1IiOworICAgICAgYnJlYWs7CisgICAgfQorICAgIGNhc2UgRVJSX0NBTUVSQV9CTE9DS0lOR19USU1FT1VUOiB7CisgICAgICBlcnJvclRleHQgPSAiRVJSX0NBTUVSQV9CTE9DS0lOR19USU1FT1VUIjsKKyAgICAgIGJyZWFrOworICAgIH0KKyAgICBjYXNlIEVSUl9DQU1FUkFfQVVUSE9SSVpBVElPTl9GQUlMRUQ6IHsKKyAgICAgIGVycm9yVGV4dCA9ICJFUlJfQ0FNRVJBX0FVVEhPUklaQVRJT05fRkFJTEVEIjsKKyAgICAgIGJyZWFrOworICAgIH0KKyAgICBjYXNlIEVSUl9DQU1FUkFfVEFTS19TUEFXTl9GQUlMRUQ6IHsKKyAgICAgIGVycm9yVGV4dCA9ICJFUlJfQ0FNRVJBX1RBU0tfU1BBV05fRkFJTEVEIjsKKyAgICAgIGJyZWFrOworICAgIH0KKyAgICBjYXNlIEVSUl9DQU1FUkFfVEFTS19JTlBVVF9PVVRfT0ZfUkFOR0U6IHsKKyAgICAgIGVycm9yVGV4dCA9ICJFUlJfQ0FNRVJBX1RBU0tfSU5QVVRfT1VUX09GX1JBTkdFIjsKKyAgICAgIGJyZWFrOworICAgIH0KKyAgICBjYXNlIEVSUl9DQU1FUkFfQ09NTUFORF9GQUlMVVJFOiB7CisgICAgICBlcnJvclRleHQgPSAiRVJSX0NBTUVSQV9DT01NQU5EX0ZBSUxVUkUiOworICAgICAgYnJlYWs7CisgICAgfQorICB9CisKKyAgcmV0dXJuIGVycm9yVGV4dDsKK30KZGlmZiAtLWdpdCBhL3dwaWxpYmMvQXRoZW5hL3NyYy9WaXNpb24vSFNMSW1hZ2UuY3BwIGIvd3BpbGliYy9BdGhlbmEvc3JjL1Zpc2lvbi9IU0xJbWFnZS5jcHAKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNWIxMTRjNAotLS0gL2Rldi9udWxsCisrKyBiL3dwaWxpYmMvQXRoZW5hL3NyYy9WaXNpb24vSFNMSW1hZ2UuY3BwCkBAIC0wLDAgKzEsMjEgQEAKKy8qLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovCisvKiBDb3B5cmlnaHQgKGMpIEZJUlNUIDIwMTQuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqLworLyogT3BlbiBTb3VyY2UgU29mdHdhcmUgLSBtYXkgYmUgbW9kaWZpZWQgYW5kIHNoYXJlZCBieSBGUkMgdGVhbXMuIFRoZSBjb2RlICAgKi8KKy8qIG11c3QgYmUgYWNjb21wYW5pZWQgYnkgdGhlIEZJUlNUIEJTRCBsaWNlbnNlIGZpbGUgaW4gJChXSU5EX0JBU0UpL1dQSUxpYi4gICovCisvKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qLworCisjaW5jbHVkZSAiVmlzaW9uL0hTTEltYWdlLmgiCisKKy8qKgorICogQ3JlYXRlIGEgbmV3IGltYWdlIHRoYXQgdXNlcyB0aGUgSHVlLCBTYXR1cmF0aW9uLCBhbmQgTHVtaW5hbmNlIHBsYW5lcy4KKyAqLworSFNMSW1hZ2U6OkhTTEltYWdlKCkgOiBDb2xvckltYWdlKElNQVFfSU1BR0VfSFNMKSB7fQorCisvKioKKyAqIENyZWF0ZSBhIG5ldyBpbWFnZSBieSBsb2FkaW5nIGEgZmlsZS4KKyAqIEBwYXJhbSBmaWxlTmFtZSBUaGUgcGF0aCBvZiB0aGUgZmlsZSB0byBsb2FkLgorICovCitIU0xJbWFnZTo6SFNMSW1hZ2UoY29uc3QgY2hhciAqZmlsZU5hbWUpIDogQ29sb3JJbWFnZShJTUFRX0lNQUdFX0hTTCkgeworICBpbnQgc3VjY2VzcyA9IGltYXFSZWFkRmlsZShtX2ltYXFJbWFnZSwgZmlsZU5hbWUsIG51bGxwdHIsIG51bGxwdHIpOworICB3cGlfc2V0SW1hcUVycm9yV2l0aENvbnRleHQoc3VjY2VzcywgIkltYXEgUmVhZEZpbGUgZXJyb3IiKTsKK30KZGlmZiAtLWdpdCBhL3dwaWxpYmMvQXRoZW5hL3NyYy9WaXNpb24vSW1hZ2VCYXNlLmNwcCBiL3dwaWxpYmMvQXRoZW5hL3NyYy9WaXNpb24vSW1hZ2VCYXNlLmNwcApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5mMzUyMzRhCi0tLSAvZGV2L251bGwKKysrIGIvd3BpbGliYy9BdGhlbmEvc3JjL1Zpc2lvbi9JbWFnZUJhc2UuY3BwCkBAIC0wLDAgKzEsNjMgQEAKKy8qLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovCisvKiBDb3B5cmlnaHQgKGMpIEZJUlNUIDIwMTQuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqLworLyogT3BlbiBTb3VyY2UgU29mdHdhcmUgLSBtYXkgYmUgbW9kaWZpZWQgYW5kIHNoYXJlZCBieSBGUkMgdGVhbXMuIFRoZSBjb2RlICAgKi8KKy8qIG11c3QgYmUgYWNjb21wYW5pZWQgYnkgdGhlIEZJUlNUIEJTRCBsaWNlbnNlIGZpbGUgaW4gJChXSU5EX0JBU0UpL1dQSUxpYi4gICovCisvKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qLworCisjaW5jbHVkZSAiVmlzaW9uL0ltYWdlQmFzZS5oIgorI2luY2x1ZGUgIm5pdmlzaW9uLmgiCisKKy8qKgorICogQ3JlYXRlIGEgbmV3IGluc3RhbmNlIG9mIGFuIEltYWdlQmFzZS4KKyAqIEltYWdlYmFzZSBpcyB0aGUgYmFzZSBvZiBhbGwgdGhlIG90aGVyIGltYWdlIGNsYXNzZXMuIFRoZSBjb25zdHJ1Y3RvcgorICogY3JlYXRlcyBhbnkgdHlwZSBvZiBpbWFnZSBhbmQgc3RvcmVzIHRoZSBwb2ludGVyIHRvIGl0IGluIHRoZSBjbGFzcy4KKyAqIEBwYXJhbSB0eXBlIFRoZSB0eXBlIG9mIGltYWdlIHRvIGNyZWF0ZQorICovCitJbWFnZUJhc2U6OkltYWdlQmFzZShJbWFnZVR5cGUgdHlwZSkgeworICBtX2ltYXFJbWFnZSA9IGltYXFDcmVhdGVJbWFnZSh0eXBlLCBERUZBVUxUX0JPUkRFUl9TSVpFKTsKK30KKworLyoqCisgKiBGcmVlcyBtZW1vcnkgYXNzb2NpYXRlZCB3aXRoIGFuIEltYWdlQmFzZS4KKyAqIERlc3RydWN0b3IgZnJlZXMgdGhlIGltYXEgaW1hZ2UgYWxsb2NhdGVkIHdpdGggdGhlIGNsYXNzLgorICovCitJbWFnZUJhc2U6On5JbWFnZUJhc2UoKSB7CisgIGlmIChtX2ltYXFJbWFnZSkgaW1hcURpc3Bvc2UobV9pbWFxSW1hZ2UpOworfQorCisvKioKKyAqIFdyaXRlcyBhbiBpbWFnZSB0byBhIGZpbGUgd2l0aCB0aGUgZ2l2ZW4gZmlsZW5hbWUuCisgKiBXcml0ZSB0aGUgaW1hZ2UgdG8gYSBmaWxlIGluIHRoZSBmbGFzaCBvbiB0aGUgY1JJTy4KKyAqIEBwYXJhbSBmaWxlTmFtZSBUaGUgbmFtZSBvZiB0aGUgZmlsZSB0byB3cml0ZQorICovCit2b2lkIEltYWdlQmFzZTo6V3JpdGUoY29uc3QgY2hhciAqZmlsZU5hbWUpIHsKKyAgaW50IHN1Y2Nlc3MgPSBpbWFxV3JpdGVGaWxlKG1faW1hcUltYWdlLCBmaWxlTmFtZSwgbnVsbHB0cik7CisgIHdwaV9zZXRJbWFxRXJyb3JXaXRoQ29udGV4dChzdWNjZXNzLCAiSW1hcSBJbWFnZSB3cml0ZUZpbGUgZXJyb3IiKTsKK30KKworLyoqCisgKiBHZXRzIHRoZSBoZWlnaHQgb2YgYW4gaW1hZ2UuCisgKiBAcmV0dXJuIFRoZSBoZWlnaHQgb2YgdGhlIGltYWdlIGluIHBpeGVscy4KKyAqLworaW50IEltYWdlQmFzZTo6R2V0SGVpZ2h0KCkgeworICBpbnQgaGVpZ2h0OworICBpbWFxR2V0SW1hZ2VTaXplKG1faW1hcUltYWdlLCBudWxscHRyLCAmaGVpZ2h0KTsKKyAgcmV0dXJuIGhlaWdodDsKK30KKworLyoqCisgKiBHZXRzIHRoZSB3aWR0aCBvZiBhbiBpbWFnZS4KKyAqIEByZXR1cm4gVGhlIHdpZHRoIG9mIHRoZSBpbWFnZSBpbiBwaXhlbHMuCisgKi8KK2ludCBJbWFnZUJhc2U6OkdldFdpZHRoKCkgeworICBpbnQgd2lkdGg7CisgIGltYXFHZXRJbWFnZVNpemUobV9pbWFxSW1hZ2UsICZ3aWR0aCwgbnVsbHB0cik7CisgIHJldHVybiB3aWR0aDsKK30KKworLyoqCisgKiBBY2Nlc3MgdGhlIGludGVybmFsIElNQVEgSW1hZ2UgZGF0YSBzdHJ1Y3R1cmUuCisgKgorICogQHJldHVybiBBIHBvaW50ZXIgdG8gdGhlIGludGVybmFsIElNQVEgSW1hZ2UgZGF0YSBzdHJ1Y3R1cmUuCisgKi8KK0ltYWdlICpJbWFnZUJhc2U6OkdldEltYXFJbWFnZSgpIHsgcmV0dXJuIG1faW1hcUltYWdlOyB9CmRpZmYgLS1naXQgYS93cGlsaWJjL0F0aGVuYS9zcmMvVmlzaW9uL01vbm9JbWFnZS5jcHAgYi93cGlsaWJjL0F0aGVuYS9zcmMvVmlzaW9uL01vbm9JbWFnZS5jcHAKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uOTA3MDNjMAotLS0gL2Rldi9udWxsCisrKyBiL3dwaWxpYmMvQXRoZW5hL3NyYy9WaXNpb24vTW9ub0ltYWdlLmNwcApAQCAtMCwwICsxLDQ2IEBACisvKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qLworLyogQ29weXJpZ2h0IChjKSBGSVJTVCAyMDE0LiBBbGwgUmlnaHRzIFJlc2VydmVkLiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKi8KKy8qIE9wZW4gU291cmNlIFNvZnR3YXJlIC0gbWF5IGJlIG1vZGlmaWVkIGFuZCBzaGFyZWQgYnkgRlJDIHRlYW1zLiBUaGUgY29kZSAgICovCisvKiBtdXN0IGJlIGFjY29tcGFuaWVkIGJ5IHRoZSBGSVJTVCBCU0QgbGljZW5zZSBmaWxlIGluICQoV0lORF9CQVNFKS9XUElMaWIuICAqLworLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi8KKworI2luY2x1ZGUgIlZpc2lvbi9Nb25vSW1hZ2UuaCIKKyNpbmNsdWRlICJuaXZpc2lvbi5oIgorCit1c2luZyBuYW1lc3BhY2Ugc3RkOworCitNb25vSW1hZ2U6Ok1vbm9JbWFnZSgpIDogSW1hZ2VCYXNlKElNQVFfSU1BR0VfVTgpIHt9CisKKy8qKgorICogTG9vayBmb3IgZWxsaXBzZXMgaW4gYW4gaW1hZ2UuCisgKiBHaXZlbiBzb21lIGlucHV0IHBhcmFtZXRlcnMsIGxvb2sgZm9yIGFueSBudW1iZXIgb2YgZWxsaXBzZXMgaW4gYW4gaW1hZ2UuCisgKiBAcGFyYW0gZWxsaXBzZURlc2NyaXB0b3IgRWxsaXBzZSBkZXNjcmlwdG9yCisgKiBAcGFyYW0gY3VydmVPcHRpb25zIEN1cnZlIG9wdGlvbnMKKyAqIEBwYXJhbSBzaGFwZURldGVjdGlvbk9wdGlvbnMgU2hhcGUgZGV0ZWN0aW9uIG9wdGlvbnMKKyAqIEBwYXJhbSByb2kgUmVnaW9uIG9mIEludGVyZXN0CisgKiBAcmV0dXJucyBhIHZlY3RvciBvZiBFbGxpcHNlTWF0Y2ggc3RydWN0dXJlcyAoMCBsZW5ndGggdmVjdG9yIG9uIG5vIG1hdGNoKQorICovCit2ZWN0b3I8RWxsaXBzZU1hdGNoPiAqTW9ub0ltYWdlOjpEZXRlY3RFbGxpcHNlcygKKyAgICBFbGxpcHNlRGVzY3JpcHRvciAqZWxsaXBzZURlc2NyaXB0b3IsIEN1cnZlT3B0aW9ucyAqY3VydmVPcHRpb25zLAorICAgIFNoYXBlRGV0ZWN0aW9uT3B0aW9ucyAqc2hhcGVEZXRlY3Rpb25PcHRpb25zLCBST0kgKnJvaSkgeworICBpbnQgbnVtYmVyT2ZNYXRjaGVzOworICBFbGxpcHNlTWF0Y2ggKmUgPQorICAgICAgaW1hcURldGVjdEVsbGlwc2VzKG1faW1hcUltYWdlLCBlbGxpcHNlRGVzY3JpcHRvciwgY3VydmVPcHRpb25zLAorICAgICAgICAgICAgICAgICAgICAgICAgIHNoYXBlRGV0ZWN0aW9uT3B0aW9ucywgcm9pLCAmbnVtYmVyT2ZNYXRjaGVzKTsKKyAgYXV0byBlbGxpcHNlcyA9IG5ldyB2ZWN0b3I8RWxsaXBzZU1hdGNoPjsKKyAgaWYgKGUgPT0gbnVsbHB0cikgeworICAgIHJldHVybiBlbGxpcHNlczsKKyAgfQorICBmb3IgKGludCBpID0gMDsgaSA8IG51bWJlck9mTWF0Y2hlczsgaSsrKSB7CisgICAgZWxsaXBzZXMtPnB1c2hfYmFjayhlW2ldKTsKKyAgfQorICBpbWFxRGlzcG9zZShlKTsKKyAgcmV0dXJuIGVsbGlwc2VzOworfQorCit2ZWN0b3I8RWxsaXBzZU1hdGNoPiAqTW9ub0ltYWdlOjpEZXRlY3RFbGxpcHNlcygKKyAgICBFbGxpcHNlRGVzY3JpcHRvciAqZWxsaXBzZURlc2NyaXB0b3IpIHsKKyAgdmVjdG9yPEVsbGlwc2VNYXRjaD4gKmVsbGlwc2VzID0KKyAgICAgIERldGVjdEVsbGlwc2VzKGVsbGlwc2VEZXNjcmlwdG9yLCBudWxscHRyLCBudWxscHRyLCBudWxscHRyKTsKKyAgcmV0dXJuIGVsbGlwc2VzOworfQpkaWZmIC0tZ2l0IGEvd3BpbGliYy9BdGhlbmEvc3JjL1Zpc2lvbi9SR0JJbWFnZS5jcHAgYi93cGlsaWJjL0F0aGVuYS9zcmMvVmlzaW9uL1JHQkltYWdlLmNwcApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi41NDY5MTIyCi0tLSAvZGV2L251bGwKKysrIGIvd3BpbGliYy9BdGhlbmEvc3JjL1Zpc2lvbi9SR0JJbWFnZS5jcHAKQEAgLTAsMCArMSwyMSBAQAorLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi8KKy8qIENvcHlyaWdodCAoYykgRklSU1QgMjAxNC4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICovCisvKiBPcGVuIFNvdXJjZSBTb2Z0d2FyZSAtIG1heSBiZSBtb2RpZmllZCBhbmQgc2hhcmVkIGJ5IEZSQyB0ZWFtcy4gVGhlIGNvZGUgICAqLworLyogbXVzdCBiZSBhY2NvbXBhbmllZCBieSB0aGUgRklSU1QgQlNEIGxpY2Vuc2UgZmlsZSBpbiAkKFdJTkRfQkFTRSkvV1BJTGliLiAgKi8KKy8qLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovCisKKyNpbmNsdWRlICJWaXNpb24vUkdCSW1hZ2UuaCIKKworLyoqCisgKiBDcmVhdGUgYSBuZXcgaW1hZ2UgdGhhdCB1c2VzIFJlZCwgR3JlZW4sIGFuZCBCbHVlIHBsYW5lcy4KKyAqLworUkdCSW1hZ2U6OlJHQkltYWdlKCkgOiBDb2xvckltYWdlKElNQVFfSU1BR0VfUkdCKSB7fQorCisvKioKKyAqIENyZWF0ZSBhIG5ldyBpbWFnZSBieSBsb2FkaW5nIGEgZmlsZS4KKyAqIEBwYXJhbSBmaWxlTmFtZSBUaGUgcGF0aCBvZiB0aGUgZmlsZSB0byBsb2FkLgorICovCitSR0JJbWFnZTo6UkdCSW1hZ2UoY29uc3QgY2hhciAqZmlsZU5hbWUpIDogQ29sb3JJbWFnZShJTUFRX0lNQUdFX1JHQikgeworICBpbnQgc3VjY2VzcyA9IGltYXFSZWFkRmlsZShtX2ltYXFJbWFnZSwgZmlsZU5hbWUsIG51bGxwdHIsIG51bGxwdHIpOworICB3cGlfc2V0SW1hcUVycm9yV2l0aENvbnRleHQoc3VjY2VzcywgIkltYXEgUmVhZEZpbGUgZXJyb3IiKTsKK30KZGlmZiAtLWdpdCBhL3dwaWxpYmMvQXRoZW5hL3NyYy9WaXNpb24vVGhyZXNob2xkLmNwcCBiL3dwaWxpYmMvQXRoZW5hL3NyYy9WaXNpb24vVGhyZXNob2xkLmNwcApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4yZTE3MjQzCi0tLSAvZGV2L251bGwKKysrIGIvd3BpbGliYy9BdGhlbmEvc3JjL1Zpc2lvbi9UaHJlc2hvbGQuY3BwCkBAIC0wLDAgKzEsMTggQEAKKy8qLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovCisvKiBDb3B5cmlnaHQgKGMpIEZJUlNUIDIwMTQuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqLworLyogT3BlbiBTb3VyY2UgU29mdHdhcmUgLSBtYXkgYmUgbW9kaWZpZWQgYW5kIHNoYXJlZCBieSBGUkMgdGVhbXMuIFRoZSBjb2RlICAgKi8KKy8qIG11c3QgYmUgYWNjb21wYW5pZWQgYnkgdGhlIEZJUlNUIEJTRCBsaWNlbnNlIGZpbGUgaW4gJChXSU5EX0JBU0UpL1dQSUxpYi4gICovCisvKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qLworCisjaW5jbHVkZSAiVmlzaW9uL1RocmVzaG9sZC5oIgorCitUaHJlc2hvbGQ6OlRocmVzaG9sZChpbnQgbmV3X3BsYW5lMUxvdywgaW50IG5ld19wbGFuZTFIaWdoLCBpbnQgbmV3X3BsYW5lMkxvdywKKyAgICAgICAgICAgICAgICAgICAgIGludCBuZXdfcGxhbmUySGlnaCwgaW50IG5ld19wbGFuZTNMb3csCisgICAgICAgICAgICAgICAgICAgICBpbnQgbmV3X3BsYW5lM0hpZ2gpIHsKKyAgcGxhbmUxTG93ID0gbmV3X3BsYW5lMUxvdzsKKyAgcGxhbmUxSGlnaCA9IG5ld19wbGFuZTFIaWdoOworICBwbGFuZTJMb3cgPSBuZXdfcGxhbmUyTG93OworICBwbGFuZTJIaWdoID0gbmV3X3BsYW5lMkhpZ2g7CisgIHBsYW5lM0xvdyA9IG5ld19wbGFuZTNMb3c7CisgIHBsYW5lM0hpZ2ggPSBuZXdfcGxhbmUzSGlnaDsKK30KZGlmZiAtLWdpdCBhL3dwaWxpYmMvQXRoZW5hL3NyYy9WaXNpb24vVmlzaW9uQVBJLmNwcCBiL3dwaWxpYmMvQXRoZW5hL3NyYy9WaXNpb24vVmlzaW9uQVBJLmNwcApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4xNjM3MjFkCi0tLSAvZGV2L251bGwKKysrIGIvd3BpbGliYy9BdGhlbmEvc3JjL1Zpc2lvbi9WaXNpb25BUEkuY3BwCkBAIC0wLDAgKzEsODIxIEBACisvKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qLworLyogQ29weXJpZ2h0IChjKSBGSVJTVCAyMDE0LiBBbGwgUmlnaHRzIFJlc2VydmVkLiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKi8KKy8qIE9wZW4gU291cmNlIFNvZnR3YXJlIC0gbWF5IGJlIG1vZGlmaWVkIGFuZCBzaGFyZWQgYnkgRlJDIHRlYW1zLiBUaGUgY29kZSAgICovCisvKiBtdXN0IGJlIGFjY29tcGFuaWVkIGJ5IHRoZSBGSVJTVCBCU0QgbGljZW5zZSBmaWxlIGluICQoV0lORF9CQVNFKS9XUElMaWIuICAqLworLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi8KKworI2luY2x1ZGUgPHN0ZGxpYi5oPgorI2luY2x1ZGUgPHN0ZGFyZy5oPgorCisjaW5jbHVkZSAiVmlzaW9uL0JhZVV0aWxpdGllcy5oIgorI2luY2x1ZGUgIlZpc2lvbi9GcmNFcnJvci5oIgorI2luY2x1ZGUgIlZpc2lvbi9WaXNpb25BUEkuaCIKKworaW50IFZpc2lvbkFQSV9kZWJ1Z0ZsYWcgPSAxOworI2RlZmluZSBEUFJJTlRGIFwKKyAgaWYgKFZpc2lvbkFQSV9kZWJ1Z0ZsYWcpIGRwcmludGYKKworLyoqIEBmaWxlCisgKiAgICBJbWFnZSBNYW5hZ2VtZW50IGZ1bmN0aW9ucworICovCisKKy8qKgorKiBAYnJpZWYgQ3JlYXRlIGFuIGltYWdlIG9iamVjdAorKiBTdXBwb3J0cyBJTUFRX0lNQUdFX1U4LCBJTUFRX0lNQUdFX0kxNiwgSU1BUV9JTUFHRV9TR0wsIElNQVFfSU1BR0VfQ09NUExFWCwKKyogSU1BUV9JTUFHRV9SR0IsIElNQVFfSU1BR0VfSFNMLCBJTUFRX0lNQUdFX1JHQl9VNjQKKyogVGhlIGJvcmRlciBzaXplIGlzIGRlZmF1bHRlZCB0byAzIHNvIHRoYXQgY29udm9sdXRpb25hbCBhbGdvcml0aG1zIHdvcmsgYXQgdGhlCisqIGVkZ2VzLgorKiBXaGVuIHlvdSBhcmUgZmluaXNoZWQgd2l0aCB0aGUgY3JlYXRlZCBpbWFnZSwgZGlzcG9zZSBvZiBpdCBieSBjYWxsaW5nCisqIGZyY0Rpc3Bvc2UoKS4KKyogVG8gZ2V0IGV4dGVuZGVkIGVycm9yIGluZm9ybWF0aW9uLCBjYWxsIEdldExhc3RFcnJvcigpLgorKgorKiBAcGFyYW0gdHlwZSBUeXBlIG9mIGltYWdlIHRvIGNyZWF0ZQorKiBAcmV0dXJuIEltYWdlKiBPbiBzdWNjZXNzLCB0aGlzIGZ1bmN0aW9uIHJldHVybnMgdGhlIGNyZWF0ZWQgaW1hZ2UuIE9uCisqIGZhaWx1cmUsIGl0IHJldHVybnMgbnVsbHB0ci4KKyovCitJbWFnZSogZnJjQ3JlYXRlSW1hZ2UoSW1hZ2VUeXBlIHR5cGUpIHsKKyAgcmV0dXJuIGltYXFDcmVhdGVJbWFnZSh0eXBlLCBERUZBVUxUX0JPUkRFUl9TSVpFKTsKK30KKworLyoqCisqIEBicmllZiBEaXNwb3NlIG9mIG9uZSBvYmplY3QuIFN1cHBvcnRzIGFueSBvYmplY3QgY3JlYXRlZCBvbiB0aGUgaGVhcC4KKyoKKyogQHBhcmFtIG9iamVjdCBvYmplY3QgdG8gZGlzcG9zZSBvZgorKiBAcmV0dXJuIE9uIHN1Y2Nlc3M6IDEuIE9uIGZhaWx1cmU6IDAuIFRvIGdldCBleHRlbmRlZCBlcnJvciBpbmZvcm1hdGlvbiwgY2FsbAorKiBHZXRMYXN0RXJyb3IoKS4KKyovCitpbnQgZnJjRGlzcG9zZSh2b2lkKiBvYmplY3QpIHsgcmV0dXJuIGltYXFEaXNwb3NlKG9iamVjdCk7IH0KKy8qKgorKiBAYnJpZWYgRGlzcG9zZSBvZiBhIGxpc3Qgb2Ygb2JqZWN0cy4gU3VwcG9ydHMgYW55IG9iamVjdCBjcmVhdGVkIG9uIHRoZSBoZWFwLgorKgorKiBAcGFyYW0gZnVuY3Rpb25OYW1lIFRoZSBuYW1lIG9mIHRoZSBmdW5jdGlvbgorKiBAcGFyYW0gLi4uIEEgbGlzdCBvZiBwb2ludGVycyB0byBzdHJ1Y3R1cmVzIHRoYXQgbmVlZCB0byBiZSBkaXNwb3NlZCBvZi4KKyogVGhlIGxhc3QgcG9pbnRlciBpbiB0aGUgbGlzdCBzaG91bGQgYWx3YXlzIGJlIHNldCB0byBudWxscHRyLgorKgorKiBAcmV0dXJuIE9uIHN1Y2Nlc3M6IDEuIE9uIGZhaWx1cmU6IDAuIFRvIGdldCBleHRlbmRlZCBlcnJvciBpbmZvcm1hdGlvbiwgY2FsbAorKiBHZXRMYXN0RXJyb3IoKS4KKyovCitpbnQgZnJjRGlzcG9zZShjb25zdCBjaGFyKiBmdW5jdGlvbk5hbWUsIC4uLikgLyogVmFyaWFibGUgYXJndW1lbnQgbGlzdCAqLworeworICB2YV9saXN0IGRpc3Bvc2FsUHRyTGlzdDsgLyogSW5wdXQgYXJndW1lbnQgbGlzdCAqLworICB2b2lkKiBkaXNwb3NhbFB0cjsgICAgICAgLyogRm9yIGl0ZXJhdGlvbiAqLworICBpbnQgc3VjY2VzcywgcmV0dXJuVmFsdWUgPSAxOworCisgIHZhX3N0YXJ0KGRpc3Bvc2FsUHRyTGlzdCwgZnVuY3Rpb25OYW1lKTsgLyogc3RhcnQgb2YgdmFyaWFibGUgbGlzdCAqLworICBkaXNwb3NhbFB0ciA9IHZhX2FyZyhkaXNwb3NhbFB0ckxpc3QsIHZvaWQqKTsKKyAgd2hpbGUgKGRpc3Bvc2FsUHRyICE9IG51bGxwdHIpIHsKKyAgICBzdWNjZXNzID0gaW1hcURpc3Bvc2UoZGlzcG9zYWxQdHIpOworICAgIGlmICghc3VjY2VzcykgeworICAgICAgcmV0dXJuVmFsdWUgPSAwOworICAgIH0KKyAgICBkaXNwb3NhbFB0ciA9IHZhX2FyZyhkaXNwb3NhbFB0ckxpc3QsIHZvaWQqKTsKKyAgfQorICB2YV9lbmQoZGlzcG9zYWxQdHJMaXN0KTsKKyAgcmV0dXJuIHJldHVyblZhbHVlOworfQorCisvKioKKyogQGJyaWVmIENvcHkgYW4gaW1hZ2Ugb2JqZWN0LgorKiBTdXBwb3J0cyBJTUFRX0lNQUdFX1U4LCBJTUFRX0lNQUdFX0kxNiwgSU1BUV9JTUFHRV9TR0wsIElNQVFfSU1BR0VfUkdCLAorKiBJTUFRX0lNQUdFX0hTTC4KKyoKKyogQHBhcmFtIGRlc3QgQ29weSBvZiBpbWFnZS4gT24gZmFpbHVyZSwgZGVzdCBpcyBudWxscHRyLiBNdXN0IGhhdmUgYWxyZWFkeSBiZWVuCisqIGNyZWF0ZWQgdXNpbmcgZnJjQ3JlYXRlSW1hZ2UoKS4KKyogV2hlbiB5b3UgYXJlIGZpbmlzaGVkIHdpdGggdGhlIGNyZWF0ZWQgaW1hZ2UsIGRpc3Bvc2Ugb2YgaXQgYnkgY2FsbGluZworKiBmcmNEaXNwb3NlKCkuCisqIEBwYXJhbSBzb3VyY2UgSW1hZ2UgdG8gY29weQorKgorKiBAcmV0dXJuIE9uIHN1Y2Nlc3M6IDEuIE9uIGZhaWx1cmU6IDAuIFRvIGdldCBleHRlbmRlZCBlcnJvciBpbmZvcm1hdGlvbiwgY2FsbAorKiBHZXRMYXN0RXJyb3IoKS4KKyovCitpbnQgZnJjQ29weUltYWdlKEltYWdlKiBkZXN0LCBjb25zdCBJbWFnZSogc291cmNlKSB7CisgIHJldHVybiBpbWFxRHVwbGljYXRlKGRlc3QsIHNvdXJjZSk7Cit9CisKKy8qKgorKiBAYnJpZWYgQ3JvcCBpbWFnZSB3aXRob3V0IGNoYW5naW5nIHRoZSBzY2FsZS4KKyogU3VwcG9ydHMgSU1BUV9JTUFHRV9VOCwgSU1BUV9JTUFHRV9JMTYsIElNQVFfSU1BR0VfU0dMLCBJTUFRX0lNQUdFX1JHQiwKKyogSU1BUV9JTUFHRV9IU0wuCisqCisqIEBwYXJhbSBkZXN0IE1vZGlmaWVkIGltYWdlCisqIEBwYXJhbSBzb3VyY2UgSW1hZ2UgdG8gY3JvcAorKiBAcGFyYW0gcmVjdCByZWdpb24gdG8gcHJvY2Vzcywgb3IgSU1BUV9OT19SRUNUCisqCisqIEByZXR1cm4gT24gc3VjY2VzczogMS4gT24gZmFpbHVyZTogMC4gVG8gZ2V0IGV4dGVuZGVkIGVycm9yIGluZm9ybWF0aW9uLCBjYWxsCisqIEdldExhc3RFcnJvcigpLgorKi8KK2ludCBmcmNDcm9wKEltYWdlKiBkZXN0LCBjb25zdCBJbWFnZSogc291cmNlLCBSZWN0IHJlY3QpIHsKKyAgcmV0dXJuIGltYXFTY2FsZShkZXN0LCBzb3VyY2UsIDEsIDEsIElNQVFfU0NBTEVfTEFSR0VSLCByZWN0KTsKK30KKworLyoqCisqIEBicmllZiBTY2FsZXMgdGhlIGVudGlyZSBpbWFnZSBsYXJnZXIgb3Igc21hbGxlci4KKyogU3VwcG9ydHMgSU1BUV9JTUFHRV9VOCwgSU1BUV9JTUFHRV9JMTYsIElNQVFfSU1BR0VfU0dMLCBJTUFRX0lNQUdFX1JHQiwKKyogSU1BUV9JTUFHRV9IU0wuCisqCisqIEBwYXJhbSBkZXN0IE1vZGlmaWVkIGltYWdlCisqIEBwYXJhbSBzb3VyY2UgSW1hZ2UgdG8gc2NhbGUKKyogQHBhcmFtIHhTY2FsZSB0aGUgaG9yaXpvbnRhbCByZWR1Y3Rpb24gcmF0aW8KKyogQHBhcmFtIHlTY2FsZSB0aGUgdmVydGljYWwgcmVkdWN0aW9uIHJhdGlvCisqIEBwYXJhbSBzY2FsZU1vZGUgSU1BUV9TQ0FMRV9MQVJHRVIgb3IgSU1BUV9TQ0FMRV9TTUFMTEVSCisqCisqIEByZXR1cm4gT24gc3VjY2VzczogMS4gT24gZmFpbHVyZTogMC4gVG8gZ2V0IGV4dGVuZGVkIGVycm9yIGluZm9ybWF0aW9uLCBjYWxsCisqIEdldExhc3RFcnJvcigpLgorKi8KK2ludCBmcmNTY2FsZShJbWFnZSogZGVzdCwgY29uc3QgSW1hZ2UqIHNvdXJjZSwgaW50IHhTY2FsZSwgaW50IHlTY2FsZSwKKyAgICAgICAgICAgICBTY2FsaW5nTW9kZSBzY2FsZU1vZGUpIHsKKyAgUmVjdCByZWN0ID0gSU1BUV9OT19SRUNUOworICByZXR1cm4gaW1hcVNjYWxlKGRlc3QsIHNvdXJjZSwgeFNjYWxlLCB5U2NhbGUsIHNjYWxlTW9kZSwgcmVjdCk7Cit9CisKKy8qKgorICogQGJyaWVmIENyZWF0ZXMgaW1hZ2Ugb2JqZWN0IGZyb20gdGhlIGluZm9ybWF0aW9uIGluIGEgZmlsZS4gVGhlIGZpbGUgY2FuIGJlCisgKiBpbiBvbmUgb2YgdGhlIGZvbGxvd2luZyBmb3JtYXRzOgorICogUE5HLCBKUEVHLCBKUEVHMjAwMCwgVElGRiwgQUlQRCwgb3IgQk1QLgorICogU3VwcG9ydHMgSU1BUV9JTUFHRV9VOCwgSU1BUV9JTUFHRV9JMTYsIElNQVFfSU1BR0VfU0dMLCBJTUFRX0lNQUdFX0NPTVBMRVgsCisgKiBJTUFRX0lNQUdFX1JHQiwgSU1BUV9JTUFHRV9IU0wsIElNQVFfSU1BR0VfUkdCX1U2NC4KKyAqCisgKiBAcGFyYW0gaW1hZ2UgSW1hZ2UgcmVhZCBpbgorICogQHBhcmFtIGZpbGVOYW1lIEZpbGUgdG8gcmVhZC4gQ2Fubm90IGJlIG51bGxwdHIKKyAqCisgKiBAcmV0dXJuIE9uIHN1Y2Nlc3M6IDEuIE9uIGZhaWx1cmU6IDAuIFRvIGdldCBleHRlbmRlZCBlcnJvciBpbmZvcm1hdGlvbiwgY2FsbAorICogR2V0TGFzdEVycm9yKCkuCisgKi8KK2ludCBmcmNSZWFkSW1hZ2UoSW1hZ2UqIGltYWdlLCBjb25zdCBjaGFyKiBmaWxlTmFtZSkgeworICByZXR1cm4gaW1hcVJlYWRGaWxlKGltYWdlLCBmaWxlTmFtZSwgbnVsbHB0ciwgbnVsbHB0cik7Cit9CisKKy8qKgorKiBAYnJpZWYgV3JpdGUgaW1hZ2UgdG8gYSBmaWxlLgorKiBTdXBwb3J0cyBJTUFRX0lNQUdFX1U4LCBJTUFRX0lNQUdFX0kxNiwgSU1BUV9JTUFHRV9TR0wsIElNQVFfSU1BR0VfQ09NUExFWCwKKyogSU1BUV9JTUFHRV9SR0IsIElNQVFfSU1BR0VfSFNMLCBJTUFRX0lNQUdFX1JHQl9VNjQuCisqCisqIFRoZSBmaWxlIHR5cGUgaXMgZGV0ZXJtaW5lZCBieSB0aGUgZXh0ZW5zaW9uLCBhcyBmb2xsb3dzOgorKgorKiAJCUV4dGVuc2lvbiAJCQkJCUZpbGUgVHlwZQorKiAJCWFpcGQgb3IgLmFwZCAJCQkJQUlQRAorKiAJCS5ibXAgCQkJCQkJQk1QCisqIAkJLmpwZyBvciAuanBlZyAJCQkJSlBFRworKiAJCS5qcDIgCQkJCQkJSlBFRzIwMDAKKyogCQkucG5nIAkJCQkJCVBORworKiAJCS50aWYgb3IgLnRpZmYgCQkJCVRJRkYKKyoKKyoKKyogVGhlIGZvbGxvd2luZyBhcmUgdGhlIHN1cHBvcnRlZCBpbWFnZSB0eXBlcyBmb3IgZWFjaCBmaWxlIHR5cGU6CisqCisqIAkJRmlsZSBUeXBlcyAJCQkJCUltYWdlIFR5cGVzCisqIAkJQUlQRCAJCQkJCQlhbGwgaW1hZ2UgdHlwZXMKKyogCQlCTVAsIEpQRUcgCQkJCQk4LWJpdCwgUkdCCisqIAkJUE5HLCBUSUZGLCBKUEVHMjAwMCAJCTgtYml0LCAxNi1iaXQsIFJHQiwgUkdCVTY0CisqCisqIEBwYXJhbSBpbWFnZSBJbWFnZSB0byB3cml0ZQorKiBAcGFyYW0gZmlsZU5hbWUgRmlsZSB0byByZWFkLiBDYW5ub3QgYmUgbnVsbHB0ci4gVGhlIGV4dGVuc2lvbiBkZXRlcm1pbmVzIHRoZQorKiBmaWxlIGZvcm1hdCB0aGF0IGlzIHdyaXR0ZW4uCisqCisqIEByZXR1cm4gT24gc3VjY2VzczogMS4gT24gZmFpbHVyZTogMC4gVG8gZ2V0IGV4dGVuZGVkIGVycm9yIGluZm9ybWF0aW9uLCBjYWxsCisqIEdldExhc3RFcnJvcigpLgorKi8KK2ludCBmcmNXcml0ZUltYWdlKGNvbnN0IEltYWdlKiBpbWFnZSwgY29uc3QgY2hhciogZmlsZU5hbWUpIHsKKyAgUkdCVmFsdWUqIGNvbG9yVGFibGUgPSBudWxscHRyOworICByZXR1cm4gaW1hcVdyaXRlRmlsZShpbWFnZSwgZmlsZU5hbWUsIGNvbG9yVGFibGUpOworfQorCisvKiAgTWVhc3VyZSBJbnRlbnNpdHkgZnVuY3Rpb25zICovCisKKy8qKgorKiBAYnJpZWYgTWVhc3VyZXMgdGhlIHBpeGVsIGludGVuc2l0aWVzIGluIGEgcmVjdGFuZ2xlIG9mIGFuIGltYWdlLgorKiBPdXRwdXRzIGludGVuc2l0eSBiYXNlZCBzdGF0aXN0aWNzIGFib3V0IGFuIGltYWdlIHN1Y2ggYXMgTWF4LCBNaW4sIE1lYW4gYW5kCisqIFN0ZCBEZXYgb2YgcGl4ZWwgdmFsdWUuCisqIFN1cHBvcnRzIElNQVFfSU1BR0VfVTgsIElNQVFfSU1BR0VfSTE2LCBJTUFRX0lNQUdFX1NHTC4KKyoKKyogIFBhcmFtZXRlciBEaXNjdXNzaW9uCToKKyogCQlSZWxldmFudCBwYXJhbWV0ZXJzIG9mIHRoZSBIaXN0b2dyYW1SZXBvcnQgaW5jbHVkZToKKyogCQkJbWluLCBtYXgsIG1lYW4gYW5kIHN0ZERldgorKgkJbWluL21heCCXU2V0dGluZyBib3RoIG1pbiBhbmQgbWF4IHRvIDAgY2F1c2VzIHRoZSBmdW5jdGlvbiB0byBzZXQKKyogbWluIHRvIDAKKyogCQkJYW5kIHRoZSBtYXggdG8gMjU1IGZvciA4LWJpdCBpbWFnZXMgYW5kIHRvIHRoZSBhY3R1YWwKKyogbWluaW11bSB2YWx1ZSBhbmQKKyogCQkJbWF4aW11bSB2YWx1ZSBvZiB0aGUgaW1hZ2UgZm9yIGFsbCBvdGhlciBpbWFnZSB0eXBlcy4KKyoJCW1heJdTZXR0aW5nIGJvdGggbWluIGFuZCBtYXggdG8gMCBjYXVzZXMgdGhlIGZ1bmN0aW9uIHRvIHNldCBtYXgKKyogdG8gMjU1CisqIAkJCWZvciA4LWJpdCBpbWFnZXMgYW5kIHRvIHRoZSBhY3R1YWwgbWF4aW11bSB2YWx1ZSBvZiB0aGUKKyogaW1hZ2UgZm9yCisqIAkJCWFsbCBvdGhlciBpbWFnZSB0eXBlcy4KKyoKKyogQHBhcmFtIGltYWdlIEltYWdlIHdob3NlIGhpc3RvZ3JhbSB0aGUgZnVuY3Rpb24gY2FsY3VsYXRlcy4KKyogQHBhcmFtIG51bUNsYXNzZXMgVGhlIG51bWJlciBvZiBjbGFzc2VzIGludG8gd2hpY2ggdGhlIGZ1bmN0aW9uIHNlcGFyYXRlcyB0aGUKKyogcGl4ZWxzLgorKiBEZXRlcm1pbmVzIHRoZSBudW1iZXIgb2YgZWxlbWVudHMgaW4gdGhlIGhpc3RvZ3JhbSBhcnJheSByZXR1cm5lZAorKiBAcGFyYW0gbWluIFRoZSBtaW5pbXVtIHBpeGVsIHZhbHVlIHRvIGNvbnNpZGVyIGZvciB0aGUgaGlzdG9ncmFtLgorKiBUaGUgZnVuY3Rpb24gZG9lcyBub3QgY291bnQgcGl4ZWxzIHdpdGggdmFsdWVzIGxlc3MgdGhhbiBtaW4uCisqIEBwYXJhbSBtYXggVGhlIG1heGltdW0gcGl4ZWwgdmFsdWUgdG8gY29uc2lkZXIgZm9yIHRoZSBoaXN0b2dyYW0uCisqIFRoZSBmdW5jdGlvbiBkb2VzIG5vdCBjb3VudCBwaXhlbHMgd2l0aCB2YWx1ZXMgZ3JlYXRlciB0aGFuIG1heC4KKyogQHBhcmFtIHJlY3QgUmVnaW9uIG9mIGludGVyZXN0IGluIHRoZSBpbWFnZS4gSWYgbm90IGluY2x1ZGVkLCB0aGUgZW50aXJlIGltYWdlCisqIGlzIHVzZWQuCisqIEByZXR1cm4gT24gc3VjY2VzcywgdGhpcyBmdW5jdGlvbiByZXR1cm5zIGEgcmVwb3J0IGRlc2NyaWJpbmcgdGhlIHBpeGVsIHZhbHVlCisqIGNsYXNzaWZpY2F0aW9uLgorKiBXaGVuIHlvdSBhcmUgZmluaXNoZWQgd2l0aCB0aGUgcmVwb3J0LCBkaXNwb3NlIG9mIGl0IGJ5IGNhbGxpbmcgZnJjRGlzcG9zZSgpLgorKiBPbiBmYWlsdXJlLCB0aGlzIGZ1bmN0aW9uIHJldHVybnMgbnVsbHB0ci4gVG8gZ2V0IGV4dGVuZGVkIGVycm9yIGluZm9ybWF0aW9uLAorKiBjYWxsIEdldExhc3RFcnJvcigpLgorKgorKi8KK0hpc3RvZ3JhbVJlcG9ydCogZnJjSGlzdG9ncmFtKGNvbnN0IEltYWdlKiBpbWFnZSwgaW50IG51bUNsYXNzZXMsIGZsb2F0IG1pbiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZsb2F0IG1heCkgeworICBSZWN0IHJlY3QgPSBJTUFRX05PX1JFQ1Q7CisgIHJldHVybiBmcmNIaXN0b2dyYW0oaW1hZ2UsIG51bUNsYXNzZXMsIG1pbiwgbWF4LCByZWN0KTsKK30KK0hpc3RvZ3JhbVJlcG9ydCogZnJjSGlzdG9ncmFtKGNvbnN0IEltYWdlKiBpbWFnZSwgaW50IG51bUNsYXNzZXMsIGZsb2F0IG1pbiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZsb2F0IG1heCwgUmVjdCByZWN0KSB7CisgIGludCBzdWNjZXNzOworICBpbnQgZmlsbFZhbHVlID0gMTsKKworICAvKiBjcmVhdGUgdGhlIHJlZ2lvbiBvZiBpbnRlcmVzdCAqLworICBST0kqIHBSb2kgPSBpbWFxQ3JlYXRlUk9JKCk7CisgIHN1Y2Nlc3MgPSBpbWFxQWRkUmVjdENvbnRvdXIocFJvaSwgcmVjdCk7CisgIGlmICghc3VjY2VzcykgeworICAgIEdldExhc3RWaXNpb25FcnJvcigpOworICAgIHJldHVybiBudWxscHRyOworICB9CisKKyAgLyogbWFrZSBhIG1hc2sgZnJvbSB0aGUgUk9JICovCisgIEltYWdlKiBwTWFzayA9IGZyY0NyZWF0ZUltYWdlKElNQVFfSU1BR0VfVTgpOworICBzdWNjZXNzID0gaW1hcVJPSVRvTWFzayhwTWFzaywgcFJvaSwgZmlsbFZhbHVlLCBudWxscHRyLCBudWxscHRyKTsKKyAgaWYgKCFzdWNjZXNzKSB7CisgICAgR2V0TGFzdFZpc2lvbkVycm9yKCk7CisgICAgZnJjRGlzcG9zZShfX0ZVTkNUSU9OX18sIHBSb2ksIG51bGxwdHIpOworICAgIHJldHVybiBudWxscHRyOworICB9CisKKyAgLyogZ2V0IGEgaGlzdG9ncmFtIHJlcG9ydCAqLworICBIaXN0b2dyYW1SZXBvcnQqIHBIciA9IG51bGxwdHI7CisgIHBIciA9IGltYXFIaXN0b2dyYW0oaW1hZ2UsIG51bUNsYXNzZXMsIG1pbiwgbWF4LCBwTWFzayk7CisKKyAgLyogY2xlYW4gdXAgKi8KKyAgZnJjRGlzcG9zZShfX0ZVTkNUSU9OX18sIHBSb2ksIHBNYXNrLCBudWxscHRyKTsKKworICByZXR1cm4gcEhyOworfQorCisvKioKKyogQGJyaWVmIENhbGN1bGF0ZXMgdGhlIGhpc3RvZ3JhbSwgb3IgcGl4ZWwgZGlzdHJpYnV0aW9uLCBvZiBhIGNvbG9yIGltYWdlLgorKiBTdXBwb3J0cyBJTUFRX0lNQUdFX1JHQiwgSU1BUV9JTUFHRV9IU0wuCisqCisqIEBwYXJhbSBpbWFnZSBJbWFnZSB3aG9zZSBoaXN0b2dyYW0gdGhlIGZ1bmN0aW9uIGNhbGN1bGF0ZXMuCisqIEBwYXJhbSBudW1DbGFzc2VzIFRoZSBudW1iZXIgb2YgY2xhc3NlcyBpbnRvIHdoaWNoIHRoZSBmdW5jdGlvbiBzZXBhcmF0ZXMgdGhlCisqIHBpeGVscy4KKyogRGV0ZXJtaW5lcyB0aGUgbnVtYmVyIG9mIGVsZW1lbnRzIGluIHRoZSBoaXN0b2dyYW0gYXJyYXkgcmV0dXJuZWQKKyogQHBhcmFtIG1vZGUgVGhlIGNvbG9yIHNwYWNlIGluIHdoaWNoIHRvIHBlcmZvcm0gdGhlIGhpc3RvZ3JhbS4gUG9zc2libGUgdmFsdWVzCisqIGluY2x1ZGUgSU1BUV9SR0IgYW5kIElNQVFfSFNMLgorKiBAcGFyYW0gbWFzayBBbiBvcHRpb25hbCBtYXNrIGltYWdlLiBUaGlzIGltYWdlIG11c3QgYmUgYW4gSU1BUV9JTUFHRV9VOCBpbWFnZS4KKyogVGhlIGZ1bmN0aW9uIGNhbGN1bGF0ZXMgdGhlIGhpc3RvZ3JhbSB1c2luZyBvbmx5IHRob3NlIHBpeGVscyBpbiB0aGUgaW1hZ2UKKyogd2hvc2UKKyogY29ycmVzcG9uZGluZyBwaXhlbHMgaW4gdGhlIG1hc2sgYXJlIG5vbi16ZXJvLiBTZXQgdGhpcyBwYXJhbWV0ZXIgdG8gbnVsbHB0ciB0bworKiBjYWxjdWxhdGUKKyogdGhlIGhpc3RvZ3JhbSBvZiB0aGUgZW50aXJlIGltYWdlLCBvciB1c2UgdGhlIHNpbXBsaWZpZWQgY2FsbC4KKyoKKyogQHJldHVybiBPbiBzdWNjZXNzLCB0aGlzIGZ1bmN0aW9uIHJldHVybnMgYSByZXBvcnQgZGVzY3JpYmluZyB0aGUKKyogY2xhc3NpZmljYXRpb24KKyogb2YgZWFjaCBwbGFuZSBpbiBhIEhpc3RvZ3JhbVJlcG9ydC4KKyogV2hlbiB5b3UgYXJlIGZpbmlzaGVkIHdpdGggdGhlIHJlcG9ydCwgZGlzcG9zZSBvZiBpdCBieSBjYWxsaW5nIGZyY0Rpc3Bvc2UoKS4KKyogT24gZmFpbHVyZSwgdGhpcyBmdW5jdGlvbiByZXR1cm5zIG51bGxwdHIuCisqIFRvIGdldCBleHRlbmRlZCBlcnJvciBpbmZvcm1hdGlvbiwgY2FsbCBpbWFxR2V0TGFzdEVycm9yKCkuCisqLworQ29sb3JIaXN0b2dyYW1SZXBvcnQqIGZyY0NvbG9ySGlzdG9ncmFtKGNvbnN0IEltYWdlKiBpbWFnZSwgaW50IG51bUNsYXNzZXMsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQ29sb3JNb2RlIG1vZGUpIHsKKyAgcmV0dXJuIGZyY0NvbG9ySGlzdG9ncmFtKGltYWdlLCBudW1DbGFzc2VzLCBtb2RlLCBudWxscHRyKTsKK30KKworQ29sb3JIaXN0b2dyYW1SZXBvcnQqIGZyY0NvbG9ySGlzdG9ncmFtKGNvbnN0IEltYWdlKiBpbWFnZSwgaW50IG51bUNsYXNzZXMsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQ29sb3JNb2RlIG1vZGUsIEltYWdlKiBtYXNrKSB7CisgIHJldHVybiBpbWFxQ29sb3JIaXN0b2dyYW0yKChJbWFnZSopaW1hZ2UsIG51bUNsYXNzZXMsIG1vZGUsIG51bGxwdHIsIG1hc2spOworfQorCisvKioKKyogQGJyaWVmIE1lYXN1cmVzIHRoZSBwaXhlbCBpbnRlbnNpdGllcyBpbiBhIHJlY3RhbmdsZSBvZiBhbiBpbWFnZS4KKyogT3V0cHV0cyBpbnRlbnNpdHkgYmFzZWQgc3RhdGlzdGljcyBhYm91dCBhbiBpbWFnZSBzdWNoIGFzIE1heCwgTWluLCBNZWFuIGFuZAorKiBTdGQgRGV2IG9mIHBpeGVsIHZhbHVlLgorKiBTdXBwb3J0cyBJTUFRX0lNQUdFX1U4IChncmF5c2NhbGUpIElNQVFfSU1BR0VfUkdCIChjb2xvcikgSU1BUV9JTUFHRV9IU0wKKyogKGNvbG9yLUhTTCkuCisqCisqIEBwYXJhbSBpbWFnZSBUaGUgaW1hZ2Ugd2hvc2UgcGl4ZWwgdmFsdWUgdGhlIGZ1bmN0aW9uIHF1ZXJpZXMKKyogQHBhcmFtIHBpeGVsIFRoZSBjb29yZGluYXRlcyBvZiB0aGUgcGl4ZWwgdGhhdCB0aGUgZnVuY3Rpb24gcXVlcmllcworKiBAcGFyYW0gdmFsdWUgT24gcmV0dXJuLCB0aGUgdmFsdWUgb2YgdGhlIHNwZWNpZmllZCBpbWFnZSBwaXhlbC4gVGhpcyBwYXJhbWV0ZXIKKyogY2Fubm90IGJlIG51bGxwdHIuCisqIFRoaXMgZGF0YSBzdHJ1Y3R1cmUgY29udGFpbnMgZWl0aGVyIGdyYXlzY2FsZSwgUkdCLCBIU0wsIENvbXBsZXggb3IKKyogUkdCVTY0VmFsdWUgZGVwZW5kaW5nIG9uIHRoZSB0eXBlIG9mIGltYWdlLgorKiBAcmV0dXJuIE9uIHN1Y2Nlc3M6IDEuIE9uIGZhaWx1cmU6IDAuIFRvIGdldCBleHRlbmRlZCBlcnJvciBpbmZvcm1hdGlvbiwgY2FsbAorKiBHZXRMYXN0RXJyb3IoKS4KKyovCitpbnQgZnJjR2V0UGl4ZWxWYWx1ZShjb25zdCBJbWFnZSogaW1hZ2UsIFBvaW50IHBpeGVsLCBQaXhlbFZhbHVlKiB2YWx1ZSkgeworICByZXR1cm4gaW1hcUdldFBpeGVsKGltYWdlLCBwaXhlbCwgdmFsdWUpOworfQorCisvKiAgIFBhcnRpY2xlIEFuYWx5c2lzIGZ1bmN0aW9ucyAqLworCisvKioKKyogQGJyaWVmIEZpbHRlcnMgcGFydGljbGVzIG91dCBvZiBhbiBpbWFnZSBiYXNlZCBvbiB0aGVpciBtZWFzdXJlbWVudHMuCisqIFN1cHBvcnRzIElNQVFfSU1BR0VfVTgsIElNQVFfSU1BR0VfSTE2LCBJTUFRX0lNQUdFX1NHTC4KKyoKKyogQHBhcmFtIGRlc3QgVGhlIGRlc3RpbmF0aW9uIGltYWdlLiBJZiBkZXN0IGlzIHVzZWQsIGl0IG11c3QgYmUgdGhlIHNhbWUgc2l6ZQorKiBhcyB0aGUgU291cmNlIGltYWdlLiBJdCB3aWxsIGNvbnRhaW4gb25seSB0aGUgZmlsdGVyZWQgcGFydGljbGVzLgorKiBAcGFyYW0gc291cmNlIFRoZSBpbWFnZSBjb250YWluaW5nIHRoZSBwYXJ0aWNsZXMgdG8gZmlsdGVyLgorKiBAcGFyYW0gY3JpdGVyaWEgQW4gYXJyYXkgb2YgY3JpdGVyaWEgdG8gYXBwbHkgdG8gdGhlIHBhcnRpY2xlcyBpbiB0aGUgc291cmNlCisqIGltYWdlLiBUaGlzIGFycmF5IGNhbm5vdCBiZSBudWxscHRyLgorKiBTZWUgdGhlIE5JVmlzaW9uQ1ZJLmNobSBoZWxwIGZpbGUgZm9yIGRlZmluaXRpb25zIG9mIGNyaXRlcmlhLgorKiBAcGFyYW0gY3JpdGVyaWFDb3VudCBUaGUgbnVtYmVyIG9mIGVsZW1lbnRzIGluIHRoZSBjcml0ZXJpYSBhcnJheS4KKyogQHBhcmFtIG9wdGlvbnMgQmluYXJ5IGZpbHRlciBvcHRpb25zLCBpbmNsdWRpbmcgcmVqZWN0TWF0Y2hlcywgcmVqZWN0Qm9yZGVyLAorKiBhbmQgY29ubmVjdGl2aXR5OC4KKyogQHBhcmFtIHJlY3QgQXJlYSBvZiBpbWFnZSB0byBmaWx0ZXIuIElmIG9taXR0ZWQsIHRoZSBkZWZhdWx0IGlzIGVudGlyZSBpbWFnZS4KKyogQHBhcmFtIG51bVBhcnRpY2xlcyBPbiByZXR1cm4sIHRoZSBudW1iZXIgb2YgcGFydGljbGVzIGxlZnQgaW4gdGhlIGltYWdlCisqIEByZXR1cm4gT24gc3VjY2VzczogMS4gT24gZmFpbHVyZTogMC4gVG8gZ2V0IGV4dGVuZGVkIGVycm9yIGluZm9ybWF0aW9uLCBjYWxsCisqIEdldExhc3RFcnJvcigpLgorKi8KK2ludCBmcmNQYXJ0aWNsZUZpbHRlcihJbWFnZSogZGVzdCwgSW1hZ2UqIHNvdXJjZSwKKyAgICAgICAgICAgICAgICAgICAgICBjb25zdCBQYXJ0aWNsZUZpbHRlckNyaXRlcmlhMiogY3JpdGVyaWEsCisgICAgICAgICAgICAgICAgICAgICAgaW50IGNyaXRlcmlhQ291bnQsIGNvbnN0IFBhcnRpY2xlRmlsdGVyT3B0aW9ucyogb3B0aW9ucywKKyAgICAgICAgICAgICAgICAgICAgICBpbnQqIG51bVBhcnRpY2xlcykgeworICBSZWN0IHJlY3QgPSBJTUFRX05PX1JFQ1Q7CisgIHJldHVybiBmcmNQYXJ0aWNsZUZpbHRlcihkZXN0LCBzb3VyY2UsIGNyaXRlcmlhLCBjcml0ZXJpYUNvdW50LCBvcHRpb25zLCByZWN0LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgbnVtUGFydGljbGVzKTsKK30KKworaW50IGZyY1BhcnRpY2xlRmlsdGVyKEltYWdlKiBkZXN0LCBJbWFnZSogc291cmNlLAorICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IFBhcnRpY2xlRmlsdGVyQ3JpdGVyaWEyKiBjcml0ZXJpYSwKKyAgICAgICAgICAgICAgICAgICAgICBpbnQgY3JpdGVyaWFDb3VudCwgY29uc3QgUGFydGljbGVGaWx0ZXJPcHRpb25zKiBvcHRpb25zLAorICAgICAgICAgICAgICAgICAgICAgIFJlY3QgcmVjdCwgaW50KiBudW1QYXJ0aWNsZXMpIHsKKyAgUk9JKiByb2kgPSBpbWFxQ3JlYXRlUk9JKCk7CisgIGltYXFBZGRSZWN0Q29udG91cihyb2ksIHJlY3QpOworICByZXR1cm4gaW1hcVBhcnRpY2xlRmlsdGVyMyhkZXN0LCBzb3VyY2UsIGNyaXRlcmlhLCBjcml0ZXJpYUNvdW50LCBvcHRpb25zLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICByb2ksIG51bVBhcnRpY2xlcyk7Cit9CisKKy8qKgorKiBAYnJpZWYgUGVyZm9ybXMgbW9ycGhvbG9naWNhbCB0cmFuc2Zvcm1hdGlvbnMgb24gYmluYXJ5IGltYWdlcy4KKyogU3VwcG9ydHMgSU1BUV9JTUFHRV9VOC4KKyoKKyogQHBhcmFtIGRlc3QgVGhlIGRlc3RpbmF0aW9uIGltYWdlLiBUaGUgYm9yZGVyIHNpemUgb2YgdGhlIGRlc3RpbmF0aW9uIGltYWdlIGlzCisqIG5vdCBpbXBvcnRhbnQuCisqIEBwYXJhbSBzb3VyY2UgVGhlIGltYWdlIG9uIHdoaWNoIHRoZSBmdW5jdGlvbiBwZXJmb3JtcyB0aGUgbW9ycGhvbG9naWNhbAorKiBvcGVyYXRpb25zLiBUaGUgY2FsY3VsYXRpb24KKyogbW9kaWZpZXMgdGhlIGJvcmRlciBvZiB0aGUgc291cmNlIGltYWdlLiBUaGUgYm9yZGVyIG11c3QgYmUgYXQgbGVhc3QgaGFsZiBhcworKiBsYXJnZSBhcyB0aGUgbGFyZ2VyCisqIGRpbWVuc2lvbiAgb2YgdGhlIHN0cnVjdHVyaW5nIGVsZW1lbnQuICBUaGUgY29ubmVjdGVkIHNvdXJjZSBpbWFnZSBmb3IgYQorKiBtb3JwaG9sb2dpY2FsIHRyYW5zZm9ybWF0aW9uCisqIG11c3QgaGF2ZSBiZWVuIGNyZWF0ZWQgd2l0aCBhIGJvcmRlciBjYXBhYmxlIG9mIHN1cHBvcnRpbmcgdGhlIHNpemUgb2YgdGhlCisqIHN0cnVjdHVyaW5nIGVsZW1lbnQuCisqIEEgMyBieSAzIHN0cnVjdHVyaW5nIGVsZW1lbnQgcmVxdWlyZXMgYSBtaW5pbWFsIGJvcmRlciBvZiAxLCBhIDUgYnkgNQorKiBzdHJ1Y3R1cmluZyBlbGVtZW50IHJlcXVpcmVzIGEgbWluaW1hbCBib3JkZXIgb2YgMiwgYW5kIHNvIG9uLgorKiBAcGFyYW0gbWV0aG9kIFRoZSBtb3JwaG9sb2dpY2FsIHRyYW5zZm9ybSB0byBhcHBseS4KKyogQHBhcmFtIHN0cnVjdHVyaW5nRWxlbWVudCBUaGUgc3RydWN0dXJpbmcgZWxlbWVudCB1c2VkIGluIHRoZSBvcGVyYXRpb24uIE9taXQKKyogdGhpcyBwYXJhbWV0ZXIgaWYgeW91IGRvIG5vdCB3YW50IGEgY3VzdG9tIHN0cnVjdHVyaW5nIGVsZW1lbnQuCisqIEByZXR1cm4gT24gc3VjY2VzczogMS4gT24gZmFpbHVyZTogMC4gVG8gZ2V0IGV4dGVuZGVkIGVycm9yIGluZm9ybWF0aW9uLCBjYWxsCisqIEdldExhc3RFcnJvcigpLgorKi8KK2ludCBmcmNNb3JwaG9sb2d5KEltYWdlKiBkZXN0LCBJbWFnZSogc291cmNlLCBNb3JwaG9sb2d5TWV0aG9kIG1ldGhvZCkgeworICByZXR1cm4gaW1hcU1vcnBob2xvZ3koZGVzdCwgc291cmNlLCBtZXRob2QsIG51bGxwdHIpOworfQorCitpbnQgZnJjTW9ycGhvbG9neShJbWFnZSogZGVzdCwgSW1hZ2UqIHNvdXJjZSwgTW9ycGhvbG9neU1ldGhvZCBtZXRob2QsCisgICAgICAgICAgICAgICAgICBjb25zdCBTdHJ1Y3R1cmluZ0VsZW1lbnQqIHN0cnVjdHVyaW5nRWxlbWVudCkgeworICByZXR1cm4gaW1hcU1vcnBob2xvZ3koZGVzdCwgc291cmNlLCBtZXRob2QsIHN0cnVjdHVyaW5nRWxlbWVudCk7Cit9CisKKy8qKgorKiBAYnJpZWYgRWxpbWluYXRlcyBwYXJ0aWNsZXMgdGhhdCB0b3VjaCB0aGUgYm9yZGVyIG9mIHRoZSBpbWFnZS4KKyogU3VwcG9ydHMgSU1BUV9JTUFHRV9VOC4KKyoKKyogQHBhcmFtIGRlc3QgVGhlIGRlc3RpbmF0aW9uIGltYWdlLgorKiBAcGFyYW0gc291cmNlIFRoZSBzb3VyY2UgaW1hZ2UuIElmIHRoZSBpbWFnZSBoYXMgYSBib3JkZXIsIHRoZSBmdW5jdGlvbiBzZXRzCisqIGFsbCBib3JkZXIgcGl4ZWwgdmFsdWVzIHRvIDAuCisqIEBwYXJhbSBjb25uZWN0aXZpdHk4IHNwZWNpZmllcyB0aGUgdHlwZSBvZiBjb25uZWN0aXZpdHkgdXNlZCBieSB0aGUgYWxnb3JpdGhtCisqIGZvciBwYXJ0aWNsZSBkZXRlY3Rpb24uCisqIFRoZSBjb25uZWN0aXZpdHkgbW9kZSBkaXJlY3RseSBkZXRlcm1pbmVzIHdoZXRoZXIgYW4gYWRqYWNlbnQgcGl4ZWwgYmVsb25ncyB0bworKiB0aGUgc2FtZSBwYXJ0aWNsZSBvciBhCisqIGRpZmZlcmVudCBwYXJ0aWNsZS4gU2V0IHRvIFRSVUUgdG8gdXNlIGNvbm5lY3Rpdml0eS04IHRvIGRldGVybWluZSB3aGV0aGVyCisqIHBhcnRpY2xlcyBhcmUgdG91Y2hpbmcKKyogU2V0IHRvIEZBTFNFIHRvIHVzZSBjb25uZWN0aXZpdHktNCB0byBkZXRlcm1pbmUgd2hldGhlciBwYXJ0aWNsZXMgYXJlCisqIHRvdWNoaW5nLgorKiBUaGUgZGVmYXVsdCBzZXR0aW5nIGZvciB0aGUgc2ltcGxpZmllZCBjYWxsIGlzIFRSVUUKKyogQHJldHVybiBPbiBzdWNjZXNzOiAxLiBPbiBmYWlsdXJlOiAwLiBUbyBnZXQgZXh0ZW5kZWQgZXJyb3IgaW5mb3JtYXRpb24sIGNhbGwKKyogR2V0TGFzdEVycm9yKCkuCisqLworaW50IGZyY1JlamVjdEJvcmRlcihJbWFnZSogZGVzdCwgSW1hZ2UqIHNvdXJjZSkgeworICByZXR1cm4gaW1hcVJlamVjdEJvcmRlcihkZXN0LCBzb3VyY2UsIFRSVUUpOworfQorCitpbnQgZnJjUmVqZWN0Qm9yZGVyKEltYWdlKiBkZXN0LCBJbWFnZSogc291cmNlLCBpbnQgY29ubmVjdGl2aXR5OCkgeworICByZXR1cm4gaW1hcVJlamVjdEJvcmRlcihkZXN0LCBzb3VyY2UsIGNvbm5lY3Rpdml0eTgpOworfQorCisvKioKKyogQGJyaWVmIENvdW50cyB0aGUgbnVtYmVyIG9mIHBhcnRpY2xlcyBpbiBhIGJpbmFyeSBpbWFnZS4KKyogU3VwcG9ydHMgSU1BUV9JTUFHRV9VOCwgSU1BUV9JTUFHRV9JMTYsIElNQVFfSU1BR0VfU0dMLgorKiBAcGFyYW0gaW1hZ2UgYmluYXJ5ICh0aHJlc2hvbGRlZCkgaW1hZ2UKKyogQHBhcmFtIG51bVBhcnRpY2xlcyBPbiByZXR1cm4sIHRoZSBudW1iZXIgb2YgcGFydGljbGVzLgorKiBAcmV0dXJuIE9uIHN1Y2Nlc3M6IDEuIE9uIGZhaWx1cmU6IDAuIFRvIGdldCBleHRlbmRlZCBlcnJvciBpbmZvcm1hdGlvbiwgY2FsbAorKiBHZXRMYXN0RXJyb3IoKS4KKyovCitpbnQgZnJjQ291bnRQYXJ0aWNsZXMoSW1hZ2UqIGltYWdlLCBpbnQqIG51bVBhcnRpY2xlcykgeworICByZXR1cm4gaW1hcUNvdW50UGFydGljbGVzKGltYWdlLCAxLCBudW1QYXJ0aWNsZXMpOworfQorCisvKioKKyogQGJyaWVmIENvbmR1Y3QgbWVhc3VyZW1lbnRzIGZvciBhIHNpbmdsZSBwYXJ0aWNsZSBpbiBhbiBpbWFnZXMuCisqIFN1cHBvcnRzIElNQVFfSU1BR0VfVTgsIElNQVFfSU1BR0VfSTE2LCBJTUFRX0lNQUdFX1NHTC4KKyoKKyogQHBhcmFtIGltYWdlIGltYWdlIHdpdGggdGhlIHBhcnRpY2xlIHRvIGFuYWx5emUuIFRoaXMgZnVuY3Rpb24gbW9kaWZpZXMgdGhlCisqIHNvdXJjZSBpbWFnZS4KKyogSWYgeW91IG5lZWQgdGhlIG9yaWdpbmFsIGltYWdlLCBjcmVhdGUgYSBjb3B5IG9mIHRoZSBpbWFnZSB1c2luZyBmcmNDb3B5KCkKKyogYmVmb3JlIHVzaW5nIHRoaXMgZnVuY3Rpb24uCisqIEBwYXJhbSBwYXJ0aWNsZU51bWJlciBUaGUgbnVtYmVyIG9mIHRoZSBwYXJ0aWNsZSB0byBnZXQgaW5mb3JtYXRpb24gb24KKyogQHBhcmFtIHBhciBvbiByZXR1cm4sIGEgcGFydGljbGUgYW5hbHlzaXMgcmVwb3J0IGNvbnRhaW5pbmcgaW5mb3JtYXRpb24gYWJvdXQKKyogdGhlIHBhcnRpY2xlLiBUaGlzIHN0cnVjdHVyZSBtdXN0IGJlIGNyZWF0ZWQgYnkgdGhlIGNhbGxlci4KKyogQHJldHVybiBPbiBzdWNjZXNzOiAxLiBPbiBmYWlsdXJlOiAwLiBUbyBnZXQgZXh0ZW5kZWQgZXJyb3IgaW5mb3JtYXRpb24sIGNhbGwKKyogR2V0TGFzdEVycm9yKCkuCisqLworaW50IGZyY1BhcnRpY2xlQW5hbHlzaXMoSW1hZ2UqIGltYWdlLCBpbnQgcGFydGljbGVOdW1iZXIsCisgICAgICAgICAgICAgICAgICAgICAgICBQYXJ0aWNsZUFuYWx5c2lzUmVwb3J0KiBwYXIpIHsKKyAgaW50IHN1Y2Nlc3MgPSAwOworCisgIC8qIGltYWdlIGluZm9ybWF0aW9uICovCisgIGludCBoZWlnaHQsIHdpZHRoOworICBpZiAoIWltYXFHZXRJbWFnZVNpemUoaW1hZ2UsICZ3aWR0aCwgJmhlaWdodCkpIHsKKyAgICByZXR1cm4gc3VjY2VzczsKKyAgfQorICBwYXItPmltYWdlV2lkdGggPSB3aWR0aDsKKyAgcGFyLT5pbWFnZUhlaWdodCA9IGhlaWdodDsKKyAgcGFyLT5wYXJ0aWNsZUluZGV4ID0gcGFydGljbGVOdW1iZXI7CisKKyAgLyogY2VudGVyIG9mIG1hc3MgcG9pbnQgb2YgdGhlIGxhcmdlc3QgcGFydGljbGUJKi8KKyAgZG91YmxlIHJldHVybkRvdWJsZTsKKyAgc3VjY2VzcyA9IGltYXFNZWFzdXJlUGFydGljbGUoaW1hZ2UsIHBhcnRpY2xlTnVtYmVyLCAwLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJTUFRX01UX0NFTlRFUl9PRl9NQVNTX1gsICZyZXR1cm5Eb3VibGUpOworICBpZiAoIXN1Y2Nlc3MpIHsKKyAgICByZXR1cm4gc3VjY2VzczsKKyAgfQorICBwYXItPmNlbnRlcl9tYXNzX3ggPSAoaW50KXJldHVybkRvdWJsZTsgIC8vIHBpeGVsCisKKyAgc3VjY2VzcyA9IGltYXFNZWFzdXJlUGFydGljbGUoaW1hZ2UsIHBhcnRpY2xlTnVtYmVyLCAwLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJTUFRX01UX0NFTlRFUl9PRl9NQVNTX1ksICZyZXR1cm5Eb3VibGUpOworICBpZiAoIXN1Y2Nlc3MpIHsKKyAgICByZXR1cm4gc3VjY2VzczsKKyAgfQorICBwYXItPmNlbnRlcl9tYXNzX3kgPSAoaW50KXJldHVybkRvdWJsZTsgIC8vIHBpeGVsCisKKyAgLyogcGFydGljbGUgc2l6ZSBzdGF0aXN0aWNzICovCisgIHN1Y2Nlc3MgPSBpbWFxTWVhc3VyZVBhcnRpY2xlKGltYWdlLCBwYXJ0aWNsZU51bWJlciwgMCwgSU1BUV9NVF9BUkVBLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmcmV0dXJuRG91YmxlKTsKKyAgaWYgKCFzdWNjZXNzKSB7CisgICAgcmV0dXJuIHN1Y2Nlc3M7CisgIH0KKyAgcGFyLT5wYXJ0aWNsZUFyZWEgPSByZXR1cm5Eb3VibGU7CisKKyAgc3VjY2VzcyA9IGltYXFNZWFzdXJlUGFydGljbGUoaW1hZ2UsIHBhcnRpY2xlTnVtYmVyLCAwLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJTUFRX01UX0JPVU5ESU5HX1JFQ1RfVE9QLCAmcmV0dXJuRG91YmxlKTsKKyAgaWYgKCFzdWNjZXNzKSB7CisgICAgcmV0dXJuIHN1Y2Nlc3M7CisgIH0KKyAgcGFyLT5ib3VuZGluZ1JlY3QudG9wID0gKGludClyZXR1cm5Eb3VibGU7CisKKyAgc3VjY2VzcyA9IGltYXFNZWFzdXJlUGFydGljbGUoaW1hZ2UsIHBhcnRpY2xlTnVtYmVyLCAwLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJTUFRX01UX0JPVU5ESU5HX1JFQ1RfTEVGVCwgJnJldHVybkRvdWJsZSk7CisgIGlmICghc3VjY2VzcykgeworICAgIHJldHVybiBzdWNjZXNzOworICB9CisgIHBhci0+Ym91bmRpbmdSZWN0LmxlZnQgPSAoaW50KXJldHVybkRvdWJsZTsKKworICBzdWNjZXNzID0gaW1hcU1lYXN1cmVQYXJ0aWNsZShpbWFnZSwgcGFydGljbGVOdW1iZXIsIDAsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIElNQVFfTVRfQk9VTkRJTkdfUkVDVF9IRUlHSFQsICZyZXR1cm5Eb3VibGUpOworICBpZiAoIXN1Y2Nlc3MpIHsKKyAgICByZXR1cm4gc3VjY2VzczsKKyAgfQorICBwYXItPmJvdW5kaW5nUmVjdC5oZWlnaHQgPSAoaW50KXJldHVybkRvdWJsZTsKKworICBzdWNjZXNzID0gaW1hcU1lYXN1cmVQYXJ0aWNsZShpbWFnZSwgcGFydGljbGVOdW1iZXIsIDAsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIElNQVFfTVRfQk9VTkRJTkdfUkVDVF9XSURUSCwgJnJldHVybkRvdWJsZSk7CisgIGlmICghc3VjY2VzcykgeworICAgIHJldHVybiBzdWNjZXNzOworICB9CisgIHBhci0+Ym91bmRpbmdSZWN0LndpZHRoID0gKGludClyZXR1cm5Eb3VibGU7CisKKyAgLyogcGFydGljbGUgcXVhbGl0eSBzdGF0aXN0aWNzICovCisgIHN1Y2Nlc3MgPSBpbWFxTWVhc3VyZVBhcnRpY2xlKGltYWdlLCBwYXJ0aWNsZU51bWJlciwgMCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSU1BUV9NVF9BUkVBX0JZX0lNQUdFX0FSRUEsICZyZXR1cm5Eb3VibGUpOworICBpZiAoIXN1Y2Nlc3MpIHsKKyAgICByZXR1cm4gc3VjY2VzczsKKyAgfQorICBwYXItPnBhcnRpY2xlVG9JbWFnZVBlcmNlbnQgPSByZXR1cm5Eb3VibGU7CisKKyAgc3VjY2VzcyA9IGltYXFNZWFzdXJlUGFydGljbGUoaW1hZ2UsIHBhcnRpY2xlTnVtYmVyLCAwLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJTUFRX01UX0FSRUFfQllfUEFSVElDTEVfQU5EX0hPTEVTX0FSRUEsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICZyZXR1cm5Eb3VibGUpOworICBpZiAoIXN1Y2Nlc3MpIHsKKyAgICByZXR1cm4gc3VjY2VzczsKKyAgfQorICBwYXItPnBhcnRpY2xlUXVhbGl0eSA9IHJldHVybkRvdWJsZTsKKworICAvKiBub3JtYWxpemVkIHBvc2l0aW9uICgtMSB0byAxKSAqLworICBwYXItPmNlbnRlcl9tYXNzX3hfbm9ybWFsaXplZCA9IFJhbmdlVG9Ob3JtYWxpemVkKHBhci0+Y2VudGVyX21hc3NfeCwgd2lkdGgpOworICBwYXItPmNlbnRlcl9tYXNzX3lfbm9ybWFsaXplZCA9IFJhbmdlVG9Ob3JtYWxpemVkKHBhci0+Y2VudGVyX21hc3NfeSwgaGVpZ2h0KTsKKworICByZXR1cm4gc3VjY2VzczsKK30KKworLyogICBJbWFnZSBFbmhhbmNlbWVudCBmdW5jdGlvbnMgKi8KKworLyoqCisqIEBicmllZiBJbXByb3ZlcyBjb250cmFzdCBvbiBhIGdyYXlzY2FsZSBpbWFnZS4KKyogU3VwcG9ydHMgSU1BUV9JTUFHRV9VOCwgSU1BUV9JTUFHRV9JMTYuCisqIEBwYXJhbSBkZXN0IFRoZSBkZXN0aW5hdGlvbiBpbWFnZS4KKyogQHBhcmFtIHNvdXJjZSBUaGUgaW1hZ2UgdG8gZXF1YWxpemUKKyogQHBhcmFtIG1pbiB0aGUgc21hbGxlc3QgdmFsdWUgdXNlZCBmb3IgcHJvY2Vzc2luZy4gQWZ0ZXIgcHJvY2Vzc2luZywgYWxsIHBpeGVsCisqIHZhbHVlcyB0aGF0IGFyZSBsZXNzIHRoYW4gb3IgZXF1YWwgdG8gdGhlIE1pbmltdW0gaW4gdGhlIG9yaWdpbmFsIGltYWdlIGFyZSBzZXQKKyogdG8gMCBmb3IgYW4gOC1iaXQgaW1hZ2UuIEluIDE2LWJpdCBhbmQgZmxvYXRpbmctcG9pbnQgaW1hZ2VzLCB0aGVzZSBwaXhlbAorKiB2YWx1ZXMgYXJlIHNldCB0byB0aGUgc21hbGxlc3QgcGl4ZWwgdmFsdWUgZm91bmQgaW4gdGhlIG9yaWdpbmFsIGltYWdlLgorKiBAcGFyYW0gbWF4IHRoZSBsYXJnZXN0IHZhbHVlIHVzZWQgZm9yIHByb2Nlc3NpbmcuIEFmdGVyIHByb2Nlc3NpbmcsIGFsbCBwaXhlbAorKiB2YWx1ZXMgdGhhdCBhcmUgZ3JlYXRlciB0aGFuIG9yIGVxdWFsIHRvIHRoZSBNYXhpbXVtIGluIHRoZSBvcmlnaW5hbCBpbWFnZSBhcmUKKyogc2V0IHRvIDI1NSBmb3IgYW4gOC1iaXQgaW1hZ2UuIEluIDE2LWJpdCBhbmQgZmxvYXRpbmctcG9pbnQgaW1hZ2VzLCB0aGVzZSBwaXhlbAorKiB2YWx1ZXMgYXJlIHNldCB0byB0aGUgbGFyZ2VzdCBwaXhlbCB2YWx1ZSBmb3VuZCBpbiB0aGUgb3JpZ2luYWwgaW1hZ2UuCisqIEBwYXJhbSBtYXNrIGFuIDgtYml0IGltYWdlIHRoYXQgc3BlY2lmaWVzIHRoZSByZWdpb24gb2YgdGhlIHNtYWxsIGltYWdlIHRoYXQKKyogd2lsbCBiZSBjb3BpZWQuIE9ubHkgdGhvc2UgcGl4ZWxzIGluIHRoZSBJbWFnZSBTcmMgKFNtYWxsKSBpbWFnZSB0aGF0CisqIGNvcnJlc3BvbmQgdG8gYW4gZXF1aXZhbGVudCBub24temVybyBwaXhlbCBpbiB0aGUgbWFzayBpbWFnZSBhcmUgY29waWVkLiBBbGwKKyogb3RoZXIgcGl4ZWxzIGtlZXAgdGhlaXIgb3JpZ2luYWwgdmFsdWVzLiBUaGUgZW50aXJlIGltYWdlIGlzIHByb2Nlc3NlZCBpZiBJbWFnZQorKiBNYXNrIGlzIG51bGxwdHIgb3IgdGhpcyBwYXJhbWV0ZXIgaXMgb21pdHRlZC4KKyogQHJldHVybiBPbiBzdWNjZXNzOiAxLiBPbiBmYWlsdXJlOiAwLiBUbyBnZXQgZXh0ZW5kZWQgZXJyb3IgaW5mb3JtYXRpb24sIGNhbGwKKyogR2V0TGFzdEVycm9yKCkuCisqCisqICBvcHRpb24gZGVmYXVsdHM6CisqICAgICAgIHNlYXJjaFJlY3QgPSBJTUFRX05PX1JFQ1QKKyogCQltaW5NYXRjaFNjb3JlID0gREVGQVVMVF9NSU5NQVhfU0NPUkUgKDgwMCkKKyovCitpbnQgZnJjRXF1YWxpemUoSW1hZ2UqIGRlc3QsIGNvbnN0IEltYWdlKiBzb3VyY2UsIGZsb2F0IG1pbiwgZmxvYXQgbWF4KSB7CisgIHJldHVybiBmcmNFcXVhbGl6ZShkZXN0LCBzb3VyY2UsIG1pbiwgbWF4LCBudWxscHRyKTsKK30KKworaW50IGZyY0VxdWFsaXplKEltYWdlKiBkZXN0LCBjb25zdCBJbWFnZSogc291cmNlLCBmbG9hdCBtaW4sIGZsb2F0IG1heCwKKyAgICAgICAgICAgICAgICBjb25zdCBJbWFnZSogbWFzaykgeworICByZXR1cm4gaW1hcUVxdWFsaXplKGRlc3QsIHNvdXJjZSwgbWluLCBtYXgsIG1hc2spOworfQorCisvKioKKyogQGJyaWVmIEltcHJvdmVzIGNvbnRyYXN0IG9uIGEgY29sb3IgaW1hZ2UuCisqIFN1cHBvcnRzIElNQVFfSU1BR0VfUkdCLCBJTUFRX0lNQUdFX0hTTAorKgorKiBvcHRpb24gZGVmYXVsdHM6IGNvbG9yRXF1YWxpemF0aW9uID0gVFJVRSB0byBlcXVhbGl6ZSBhbGwgdGhyZWUgcGxhbmVzIG9mIHRoZQorKiBpbWFnZQorKiBAcmV0dXJuIE9uIHN1Y2Nlc3M6IDEuIE9uIGZhaWx1cmU6IDAuIFRvIGdldCBleHRlbmRlZCBlcnJvciBpbmZvcm1hdGlvbiwgY2FsbAorKiBHZXRMYXN0RXJyb3IoKS4KKyogQHBhcmFtIGRlc3QgVGhlIGRlc3RpbmF0aW9uIGltYWdlLgorKiBAcGFyYW0gc291cmNlIFRoZSBpbWFnZSB0byBlcXVhbGl6ZQorKiBAcGFyYW0gY29sb3JFcXVhbGl6YXRpb24gU2V0IHRoaXMgcGFyYW1ldGVyIHRvIFRSVUUgdG8gZXF1YWxpemUgYWxsIHRocmVlCisqIHBsYW5lcyBvZiB0aGUgaW1hZ2UgKHRoZSBkZWZhdWx0KS4gU2V0IHRoaXMgcGFyYW1ldGVyIHRvIEZBTFNFIHRvIGVxdWFsaXplIG9ubHkKKyogdGhlIGx1bWluYW5jZSBwbGFuZS4KKyovCitpbnQgZnJjQ29sb3JFcXVhbGl6ZShJbWFnZSogZGVzdCwgY29uc3QgSW1hZ2UqIHNvdXJjZSkgeworICByZXR1cm4gaW1hcUNvbG9yRXF1YWxpemUoZGVzdCwgc291cmNlLCBUUlVFKTsKK30KKworaW50IGZyY0NvbG9yRXF1YWxpemUoSW1hZ2UqIGRlc3QsIGNvbnN0IEltYWdlKiBzb3VyY2UsIGludCBjb2xvckVxdWFsaXphdGlvbikgeworICByZXR1cm4gaW1hcUNvbG9yRXF1YWxpemUoZGVzdCwgc291cmNlLCBUUlVFKTsKK30KKworLyogICBJbWFnZSBDb252ZXJzaW9uIGZ1bmN0aW9ucyAqLworCisvKioKKyogQGJyaWVmIEF1dG9tYXRpY2FsbHkgdGhyZXNob2xkcyBhIGdyYXlzY2FsZSBpbWFnZSBpbnRvIGEgYmluYXJ5IGltYWdlIGZvcgorKiBQYXJ0aWNsZSBBbmFseXNpcyBiYXNlZCBvbiBhIHNtYXJ0IHRocmVzaG9sZC4KKyogU3VwcG9ydHMgSU1BUV9JTUFHRV9SR0IsIElNQVFfSU1BR0VfSTE2CisqIEBwYXJhbSBkZXN0IFRoZSBkZXN0aW5hdGlvbiBpbWFnZS4KKyogQHBhcmFtIHNvdXJjZSBUaGUgaW1hZ2UgdG8gdGhyZXNob2xkCisqIEBwYXJhbSB3aW5kb3dXaWR0aCBUaGUgd2lkdGggb2YgdGhlIHJlY3Rhbmd1bGFyIHdpbmRvdyBhcm91bmQgdGhlIHBpeGVsIG9uCisqIHdoaWNoIHRoZSBmdW5jdGlvbgorKiAgcGVyZm9ybXMgdGhlIGxvY2FsIHRocmVzaG9sZC4gVGhpcyBudW1iZXIgbXVzdCBiZSBhdCBsZWFzdCAzIGFuZCBjYW5ub3QgYmUKKyogbGFyZ2VyIHRoYW4gdGhlIHdpZHRoIG9mIHNvdXJjZQorKiBAcGFyYW0gd2luZG93SGVpZ2h0IFRoZSBoZWlnaHQgb2YgdGhlIHJlY3Rhbmd1bGFyIHdpbmRvdyBhcm91bmQgdGhlIHBpeGVsIG9uCisqIHdoaWNoIHRoZSBmdW5jdGlvbgorKiBwZXJmb3JtcyB0aGUgbG9jYWwgdGhyZXNob2xkLiBUaGlzIG51bWJlciBtdXN0IGJlIGF0IGxlYXN0IDMgYW5kIGNhbm5vdCBiZQorKiBsYXJnZXIgdGhhbiB0aGUgaGVpZ2h0IG9mIHNvdXJjZQorKiBAcGFyYW0gbWV0aG9kIFNwZWNpZmllcyB0aGUgbG9jYWwgdGhyZXNob2xkaW5nIG1ldGhvZCB0aGUgZnVuY3Rpb24gdXNlcy4gVmFsdWUKKyogY2FuIGJlIElNQVFfTklCTEFDSworKiAod2hpY2ggY29tcHV0ZXMgdGhyZXNob2xkcyBmb3IgZWFjaCBwaXhlbCBiYXNlZCBvbiBpdHMgbG9jYWwgc3RhdGlzdGljcyB1c2luZworKiB0aGUgTmlibGFjayBsb2NhbCB0aHJlc2hvbGRpbmcKKyogYWxnb3JpdGhtLiksIG9yIElNQVFfQkFDS0dST1VORF9DT1JSRUNUSU9OICh3aGljaCBkb2VzIGJhY2tncm91bmQgY29ycmVjdGlvbgorKiBmaXJzdCB0byBlbGltaW5hdGUgbm9uLXVuaWZvcm0KKyogbGlnaHRpbmcgZWZmZWN0cywgdGhlbiBwZXJmb3JtcyB0aHJlc2hvbGRpbmcgdXNpbmcgdGhlIE90c3UgdGhyZXNob2xkaW5nCisqIGFsZ29yaXRobSkKKyogQHBhcmFtIGRldmlhdGlvbldlaWdodCBTcGVjaWZpZXMgdGhlIGsgY29uc3RhbnQgdXNlZCBpbiB0aGUgTmlibGFjayBsb2NhbAorKiB0aHJlc2hvbGRpbmcgYWxnb3JpdGhtLCB3aGljaAorKiBkZXRlcm1pbmVzIHRoZSB3ZWlnaHQgYXBwbGllZCB0byB0aGUgdmFyaWFuY2UgY2FsY3VsYXRpb24uIFZhbGlkIGsgY29uc3RhbnRzCisqIHJhbmdlIGZyb20gMCB0byAxLiBTZXR0aW5nCisqIHRoaXMgdmFsdWUgdG8gMCB3aWxsIGluY3JlYXNlIHRoZSBwZXJmb3JtYW5jZSBvZiB0aGUgZnVuY3Rpb24gYmVjYXVzZSB0aGUKKyogZnVuY3Rpb24gd2lsbCBub3QgY2FsY3VsYXRlIHRoZQorKiB2YXJpYW5jZSBmb3IgYW55IG9mIHRoZSBwaXhlbHMuIFRoZSBmdW5jdGlvbiBpZ25vcmVzIHRoaXMgdmFsdWUgaWYgbWV0aG9kIGlzCisqIG5vdCBzZXQgdG8gSU1BUV9OSUJMQUNLCisqIEBwYXJhbSB0eXBlIFNwZWNpZmllcyB0aGUgdHlwZSBvZiBvYmplY3RzIGZvciB3aGljaCB5b3Ugd2FudCB0byBsb29rLiBWYWx1ZXMKKyogY2FuIGJlIElNQVFfQlJJR0hUX09CSkVDVFMKKyogb3IgSU1BUV9EQVJLX09CSkVDVFMuCisqIEBwYXJhbSByZXBsYWNlVmFsdWUgU3BlY2lmaWVzIHRoZSByZXBsYWNlbWVudCB2YWx1ZSB0aGUgZnVuY3Rpb24gdXNlcyBmb3IgdGhlCisqIHBpeGVscyBvZiB0aGUga2VwdCBvYmplY3RzCisqIGluIHRoZSBkZXN0aW5hdGlvbiBpbWFnZS4KKyogQHJldHVybiBPbiBzdWNjZXNzOiAxLiBPbiBmYWlsdXJlOiAwLiBUbyBnZXQgZXh0ZW5kZWQgZXJyb3IgaW5mb3JtYXRpb24sIGNhbGwKKyogR2V0TGFzdEVycm9yKCkuCisqLworaW50IGZyY1NtYXJ0VGhyZXNob2xkKEltYWdlKiBkZXN0LCBjb25zdCBJbWFnZSogc291cmNlLAorICAgICAgICAgICAgICAgICAgICAgIHVuc2lnbmVkIGludCB3aW5kb3dXaWR0aCwgdW5zaWduZWQgaW50IHdpbmRvd0hlaWdodCwKKyAgICAgICAgICAgICAgICAgICAgICBMb2NhbFRocmVzaG9sZE1ldGhvZCBtZXRob2QsIGRvdWJsZSBkZXZpYXRpb25XZWlnaHQsCisgICAgICAgICAgICAgICAgICAgICAgT2JqZWN0VHlwZSB0eXBlKSB7CisgIGZsb2F0IHJlcGxhY2VWYWx1ZSA9IDEuMDsKKyAgcmV0dXJuIGltYXFMb2NhbFRocmVzaG9sZChkZXN0LCBzb3VyY2UsIHdpbmRvd1dpZHRoLCB3aW5kb3dIZWlnaHQsIG1ldGhvZCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBkZXZpYXRpb25XZWlnaHQsIHR5cGUsIHJlcGxhY2VWYWx1ZSk7Cit9CisKK2ludCBmcmNTbWFydFRocmVzaG9sZChJbWFnZSogZGVzdCwgY29uc3QgSW1hZ2UqIHNvdXJjZSwKKyAgICAgICAgICAgICAgICAgICAgICB1bnNpZ25lZCBpbnQgd2luZG93V2lkdGgsIHVuc2lnbmVkIGludCB3aW5kb3dIZWlnaHQsCisgICAgICAgICAgICAgICAgICAgICAgTG9jYWxUaHJlc2hvbGRNZXRob2QgbWV0aG9kLCBkb3VibGUgZGV2aWF0aW9uV2VpZ2h0LAorICAgICAgICAgICAgICAgICAgICAgIE9iamVjdFR5cGUgdHlwZSwgZmxvYXQgcmVwbGFjZVZhbHVlKSB7CisgIHJldHVybiBpbWFxTG9jYWxUaHJlc2hvbGQoZGVzdCwgc291cmNlLCB3aW5kb3dXaWR0aCwgd2luZG93SGVpZ2h0LCBtZXRob2QsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGV2aWF0aW9uV2VpZ2h0LCB0eXBlLCByZXBsYWNlVmFsdWUpOworfQorCisvKioKKyogQGJyaWVmIENvbnZlcnRzIGEgZ3JheXNjYWxlIGltYWdlIHRvIGEgYmluYXJ5IGltYWdlIGZvciBQYXJ0aWNsZSBBbmFseXNpcworKiBiYXNlZCBvbiBhIGZpeGVkIHRocmVzaG9sZC4KKyogVGhlIGZ1bmN0aW9uIHNldHMgcGl4ZWxzIHZhbHVlcyBvdXRzaWRlIG9mIHRoZSBnaXZlbiByYW5nZSB0byAwLiBUaGUgZnVuY3Rpb24KKyogc2V0cyBwaXhlbCB2YWx1ZXMKKyogd2l0aGluIHRoZSByYW5nZSB0byBhIGdpdmVuIHZhbHVlIG9yIGxlYXZlcyB0aGUgdmFsdWVzIHVuY2hhbmdlZC4KKyogVXNlIHRoZSBzaW1wbGlmaWVkIGNhbGwgdG8gbGVhdmUgcGl4ZWwgdmFsdWVzIHVuY2hhbmdlZC4KKyogU3VwcG9ydHMgSU1BUV9JTUFHRV9SR0IsIElNQVFfSU1BR0VfSTE2LgorKgorKiBAcGFyYW0gZGVzdCBUaGUgZGVzdGluYXRpb24gaW1hZ2UuCisqIEBwYXJhbSBzb3VyY2UgVGhlIGltYWdlIHRvIHRocmVzaG9sZAorKiBAcGFyYW0gcmFuZ2VNaW4gVGhlIGxvd2VyIGJvdW5kYXJ5IG9mIHRoZSByYW5nZSBvZiBwaXhlbCB2YWx1ZXMgdG8ga2VlcAorKiBAcGFyYW0gcmFuZ2VNYXggVGhlIHVwcGVyIGJvdW5kYXJ5IG9mIHRoZSByYW5nZSBvZiBwaXhlbCB2YWx1ZXMgdG8ga2VlcC4KKyoKKyogQHJldHVybiBpbnQgLSBlcnJvciBjb2RlOiAwID0gZXJyb3IuIFRvIGdldCBleHRlbmRlZCBlcnJvciBpbmZvcm1hdGlvbiwgY2FsbAorKiBHZXRMYXN0RXJyb3IoKS4KKyovCitpbnQgZnJjU2ltcGxlVGhyZXNob2xkKEltYWdlKiBkZXN0LCBjb25zdCBJbWFnZSogc291cmNlLCBmbG9hdCByYW5nZU1pbiwKKyAgICAgICAgICAgICAgICAgICAgICAgZmxvYXQgcmFuZ2VNYXgpIHsKKyAgaW50IG5ld1ZhbHVlID0gMjU1OworICByZXR1cm4gZnJjU2ltcGxlVGhyZXNob2xkKGRlc3QsIHNvdXJjZSwgcmFuZ2VNaW4sIHJhbmdlTWF4LCBuZXdWYWx1ZSk7Cit9CisKKy8qKgorKiBAYnJpZWYgQ29udmVydHMgYSBncmF5c2NhbGUgaW1hZ2UgdG8gYSBiaW5hcnkgaW1hZ2UgZm9yIFBhcnRpY2xlIEFuYWx5c2lzCisqIGJhc2VkIG9uIGEgZml4ZWQgdGhyZXNob2xkLgorKiBUaGUgZnVuY3Rpb24gc2V0cyBwaXhlbHMgdmFsdWVzIG91dHNpZGUgb2YgdGhlIGdpdmVuIHJhbmdlIHRvIDAuIFRoZSBmdW5jdGlvbgorKiBzZXRzCisqIHBpeGVsIHZhbHVlcyB3aXRoaW4gdGhlIHJhbmdlIHRvIHRoZSBnaXZlbiB2YWx1ZS4KKyogU3VwcG9ydHMgSU1BUV9JTUFHRV9SR0IsIElNQVFfSU1BR0VfSTE2LgorKgorKiBAcGFyYW0gZGVzdCBUaGUgZGVzdGluYXRpb24gaW1hZ2UuCisqIEBwYXJhbSBzb3VyY2UgVGhlIGltYWdlIHRvIHRocmVzaG9sZAorKiBAcGFyYW0gcmFuZ2VNaW4gVGhlIGxvd2VyIGJvdW5kYXJ5IG9mIHRoZSByYW5nZSBvZiBwaXhlbCB2YWx1ZXMgdG8ga2VlcAorKiBAcGFyYW0gcmFuZ2VNYXggVGhlIHVwcGVyIGJvdW5kYXJ5IG9mIHRoZSByYW5nZSBvZiBwaXhlbCB2YWx1ZXMgdG8ga2VlcC4KKyogQHBhcmFtIG5ld1ZhbHVlIFRoZSByZXBsYWNlbWVudCB2YWx1ZSBmb3IgcGl4ZWxzIHdpdGhpbiB0aGUgcmFuZ2UuIFVzZSB0aGUKKyogc2ltcGxpZmllZCBjYWxsIHRvIGxlYXZlIHRoZSBwaXhlbCB2YWx1ZXMgdW5jaGFuZ2VkCisqCisqIEByZXR1cm4gaW50IC0gZXJyb3IgY29kZTogMCA9IGVycm9yLiBUbyBnZXQgZXh0ZW5kZWQgZXJyb3IgaW5mb3JtYXRpb24sIGNhbGwKKyogR2V0TGFzdEVycm9yKCkuCisqLworaW50IGZyY1NpbXBsZVRocmVzaG9sZChJbWFnZSogZGVzdCwgY29uc3QgSW1hZ2UqIHNvdXJjZSwgZmxvYXQgcmFuZ2VNaW4sCisgICAgICAgICAgICAgICAgICAgICAgIGZsb2F0IHJhbmdlTWF4LCBmbG9hdCBuZXdWYWx1ZSkgeworICBpbnQgdXNlTmV3VmFsdWUgPSBUUlVFOworICByZXR1cm4gaW1hcVRocmVzaG9sZChkZXN0LCBzb3VyY2UsIHJhbmdlTWluLCByYW5nZU1heCwgdXNlTmV3VmFsdWUsIG5ld1ZhbHVlKTsKK30KKworLyoqCisqIEBicmllZiBBcHBsaWVzIGEgdGhyZXNob2xkIHRvIHRoZSBSZWQsIEdyZWVuLCBhbmQgQmx1ZSB2YWx1ZXMgb2YgYSBSR0IgaW1hZ2UKKyogb3IgdGhlIEh1ZSwKKyogU2F0dXJhdGlvbiwgTHVtaW5hbmNlIHZhbHVlcyBmb3IgYSBIU0wgaW1hZ2UuCisqIFN1cHBvcnRzIElNQVFfSU1BR0VfUkdCLCBJTUFRX0lNQUdFX0hTTC4KKyogVGhpcyBzaW1wbGVyIHZlcnNpb24gZmlsdGVycyBiYXNlZCBvbiBhIGh1ZSByYW5nZSBpbiB0aGUgSFNMIG1vZGUuCisqCisqIEBwYXJhbSBkZXN0IFRoZSBkZXN0aW5hdGlvbiBpbWFnZS4gVGhpcyBtdXN0IGJlIGEgSU1BUV9JTUFHRV9VOCBpbWFnZS4KKyogQHBhcmFtIHNvdXJjZSBUaGUgaW1hZ2UgdG8gdGhyZXNob2xkCisqIEBwYXJhbSBtb2RlIFRoZSBjb2xvciBzcGFjZSB0byBwZXJmb3JtIHRoZSB0aHJlc2hvbGQgaW4uIHZhbGlkIHZhbHVlcyBhcmU6CisqIElNQVFfUkdCLCBJTUFRX0hTTC4KKyogQHBhcmFtIHBsYW5lMVJhbmdlIFRoZSBzZWxlY3Rpb24gcmFuZ2UgZm9yIHRoZSBmaXJzdCBwbGFuZSBvZiB0aGUgaW1hZ2UuIFNldAorKiB0aGlzIHBhcmFtZXRlciB0byBudWxscHRyIHRvIHVzZSBhIHNlbGVjdGlvbiByYW5nZSBmcm9tIDAgdG8gMjU1LgorKiBAcGFyYW0gcGxhbmUyUmFuZ2UgVGhlIHNlbGVjdGlvbiByYW5nZSBmb3IgdGhlIHNlY29uZCBwbGFuZSBvZiB0aGUgaW1hZ2UuIFNldAorKiB0aGlzIHBhcmFtZXRlciB0byBudWxscHRyIHRvIHVzZSBhIHNlbGVjdGlvbiByYW5nZSBmcm9tIDAgdG8gMjU1LgorKiBAcGFyYW0gcGxhbmUzUmFuZ2UgVGhlIHNlbGVjdGlvbiByYW5nZSBmb3IgdGhlIHRoaXJkIHBsYW5lIG9mIHRoZSBpbWFnZS4gU2V0CisqIHRoaXMgcGFyYW1ldGVyIHRvIG51bGxwdHIgdG8gdXNlIGEgc2VsZWN0aW9uIHJhbmdlIGZyb20gMCB0byAyNTUuCisqCisqIEByZXR1cm4gT24gc3VjY2VzczogMS4gT24gZmFpbHVyZTogMC4gVG8gZ2V0IGV4dGVuZGVkIGVycm9yIGluZm9ybWF0aW9uLCBjYWxsCisqIEdldExhc3RFcnJvcigpLgorKiAqLworaW50IGZyY0NvbG9yVGhyZXNob2xkKEltYWdlKiBkZXN0LCBjb25zdCBJbWFnZSogc291cmNlLCBDb2xvck1vZGUgbW9kZSwKKyAgICAgICAgICAgICAgICAgICAgICBjb25zdCBSYW5nZSogcGxhbmUxUmFuZ2UsIGNvbnN0IFJhbmdlKiBwbGFuZTJSYW5nZSwKKyAgICAgICAgICAgICAgICAgICAgICBjb25zdCBSYW5nZSogcGxhbmUzUmFuZ2UpIHsKKyAgaW50IHJlcGxhY2VWYWx1ZSA9IDE7CisgIHJldHVybiBpbWFxQ29sb3JUaHJlc2hvbGQoZGVzdCwgc291cmNlLCByZXBsYWNlVmFsdWUsIG1vZGUsIHBsYW5lMVJhbmdlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBsYW5lMlJhbmdlLCBwbGFuZTNSYW5nZSk7Cit9CisKKy8qKgorKiBAYnJpZWYgQXBwbGllcyBhIHRocmVzaG9sZCB0byB0aGUgUmVkLCBHcmVlbiwgYW5kIEJsdWUgdmFsdWVzIG9mIGEgUkdCIGltYWdlCisqIG9yIHRoZSBIdWUsCisqIFNhdHVyYXRpb24sIEx1bWluYW5jZSB2YWx1ZXMgZm9yIGEgSFNMIGltYWdlLgorKiBTdXBwb3J0cyBJTUFRX0lNQUdFX1JHQiwgSU1BUV9JTUFHRV9IU0wuCisqIFRoZSBzaW1wbGVyIHZlcnNpb24gZmlsdGVycyBiYXNlZCBvbiBhIGh1ZSByYW5nZSBpbiB0aGUgSFNMIG1vZGUuCisqCisqIEBwYXJhbSBkZXN0IFRoZSBkZXN0aW5hdGlvbiBpbWFnZS4gVGhpcyBtdXN0IGJlIGEgSU1BUV9JTUFHRV9VOCBpbWFnZS4KKyogQHBhcmFtIHNvdXJjZSBUaGUgaW1hZ2UgdG8gdGhyZXNob2xkCisqIEBwYXJhbSByZXBsYWNlVmFsdWUgVmFsdWUgdG8gYXNzaWduIHRvIHNlbGVjdGVkIHBpeGVscy4gRGVmYXVsdHMgdG8gMSBpZgorKiBzaW1wbGlmaWVkIGNhbGwgaXMgdXNlZC4KKyogQHBhcmFtIG1vZGUgVGhlIGNvbG9yIHNwYWNlIHRvIHBlcmZvcm0gdGhlIHRocmVzaG9sZCBpbi4gdmFsaWQgdmFsdWVzIGFyZToKKyogSU1BUV9SR0IsIElNQVFfSFNMLgorKiBAcGFyYW0gcGxhbmUxUmFuZ2UgVGhlIHNlbGVjdGlvbiByYW5nZSBmb3IgdGhlIGZpcnN0IHBsYW5lIG9mIHRoZSBpbWFnZS4gU2V0CisqIHRoaXMgcGFyYW1ldGVyIHRvIG51bGxwdHIgdG8gdXNlIGEgc2VsZWN0aW9uIHJhbmdlIGZyb20gMCB0byAyNTUuCisqIEBwYXJhbSBwbGFuZTJSYW5nZSBUaGUgc2VsZWN0aW9uIHJhbmdlIGZvciB0aGUgc2Vjb25kIHBsYW5lIG9mIHRoZSBpbWFnZS4gU2V0CisqIHRoaXMgcGFyYW1ldGVyIHRvIG51bGxwdHIgdG8gdXNlIGEgc2VsZWN0aW9uIHJhbmdlIGZyb20gMCB0byAyNTUuCisqIEBwYXJhbSBwbGFuZTNSYW5nZSBUaGUgc2VsZWN0aW9uIHJhbmdlIGZvciB0aGUgdGhpcmQgcGxhbmUgb2YgdGhlIGltYWdlLiBTZXQKKyogdGhpcyBwYXJhbWV0ZXIgdG8gbnVsbHB0ciB0byB1c2UgYSBzZWxlY3Rpb24gcmFuZ2UgZnJvbSAwIHRvIDI1NS4KKyoKKyogQHJldHVybiBPbiBzdWNjZXNzOiAxLiBPbiBmYWlsdXJlOiAwLiBUbyBnZXQgZXh0ZW5kZWQgZXJyb3IgaW5mb3JtYXRpb24sIGNhbGwKKyogR2V0TGFzdEVycm9yKCkuCisqLworaW50IGZyY0NvbG9yVGhyZXNob2xkKEltYWdlKiBkZXN0LCBjb25zdCBJbWFnZSogc291cmNlLCBpbnQgcmVwbGFjZVZhbHVlLAorICAgICAgICAgICAgICAgICAgICAgIENvbG9yTW9kZSBtb2RlLCBjb25zdCBSYW5nZSogcGxhbmUxUmFuZ2UsCisgICAgICAgICAgICAgICAgICAgICAgY29uc3QgUmFuZ2UqIHBsYW5lMlJhbmdlLCBjb25zdCBSYW5nZSogcGxhbmUzUmFuZ2UpIHsKKyAgcmV0dXJuIGltYXFDb2xvclRocmVzaG9sZChkZXN0LCBzb3VyY2UsIHJlcGxhY2VWYWx1ZSwgbW9kZSwgcGxhbmUxUmFuZ2UsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgcGxhbmUyUmFuZ2UsIHBsYW5lM1JhbmdlKTsKK30KKworLyoqCisqIEBicmllZiBBIHNpbXBsZXIgdmVyc2lvbiBvZiBDb2xvclRocmVzaG9sZCB0aGF0IHRocmVzaG9sZHMgaHVlIHJhbmdlIGluIHRoZQorKiBIU0wgbW9kZS4gU3VwcG9ydHMgSU1BUV9JTUFHRV9SR0IsIElNQVFfSU1BR0VfSFNMLgorKiBAcGFyYW0gZGVzdCBUaGUgZGVzdGluYXRpb24gaW1hZ2UuCisqIEBwYXJhbSBzb3VyY2UgVGhlIGltYWdlIHRvIHRocmVzaG9sZAorKiBAcGFyYW0gaHVlUmFuZ2UgVGhlIHNlbGVjdGlvbiByYW5nZSBmb3IgdGhlIGh1ZSAoY29sb3IpLgorKiBAcGFyYW0gbWluU2F0dXJhdGlvbiBUaGUgbWluaW11bSBzYXR1cmF0aW9uIHZhbHVlICgxLTI1NSkuICBJZiBub3QgdXNlZCwKKyogREVGQVVMVF9TQVRVUkFUSU9OX1RIUkVTSE9MRCBpcyB0aGUgZGVmYXVsdC4KKyoKKyogQHJldHVybiBPbiBzdWNjZXNzOiAxLiBPbiBmYWlsdXJlOiAwLiBUbyBnZXQgZXh0ZW5kZWQgZXJyb3IgaW5mb3JtYXRpb24sIGNhbGwKKyogR2V0TGFzdEVycm9yKCkuCisqLworaW50IGZyY0h1ZVRocmVzaG9sZChJbWFnZSogZGVzdCwgY29uc3QgSW1hZ2UqIHNvdXJjZSwgY29uc3QgUmFuZ2UqIGh1ZVJhbmdlKSB7CisgIHJldHVybiBmcmNIdWVUaHJlc2hvbGQoZGVzdCwgc291cmNlLCBodWVSYW5nZSwgREVGQVVMVF9TQVRVUkFUSU9OX1RIUkVTSE9MRCk7Cit9CisKK2ludCBmcmNIdWVUaHJlc2hvbGQoSW1hZ2UqIGRlc3QsIGNvbnN0IEltYWdlKiBzb3VyY2UsIGNvbnN0IFJhbmdlKiBodWVSYW5nZSwKKyAgICAgICAgICAgICAgICAgICAgaW50IG1pblNhdHVyYXRpb24pIHsKKyAgLy8gYXNzdW1lIEhTTCBtb2RlCisgIENvbG9yTW9kZSBtb2RlID0gSU1BUV9IU0w7CisgIC8vIFNldCBzYXR1cmF0aW9uIDEwMCAtIDI1NQorICBSYW5nZSBzYXRSYW5nZTsKKyAgc2F0UmFuZ2UubWluVmFsdWUgPSBtaW5TYXR1cmF0aW9uOworICBzYXRSYW5nZS5tYXhWYWx1ZSA9IDI1NTsKKyAgLy8gU2V0IGx1bWluYW5jZSAxMDAgLSAyNTUKKyAgUmFuZ2UgbHVtUmFuZ2U7CisgIGx1bVJhbmdlLm1pblZhbHVlID0gMTAwOworICBsdW1SYW5nZS5tYXhWYWx1ZSA9IDI1NTsKKyAgLy8gUmVwbGFjZSBwaXhlbHMgd2l0aCAxIGlmIHBhc3MgdGhyZXNob2xkIGZpbHRlcgorICBpbnQgcmVwbGFjZVZhbHVlID0gMTsKKyAgcmV0dXJuIGltYXFDb2xvclRocmVzaG9sZChkZXN0LCBzb3VyY2UsIHJlcGxhY2VWYWx1ZSwgbW9kZSwgaHVlUmFuZ2UsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgJnNhdFJhbmdlLCAmbHVtUmFuZ2UpOworfQorCisvKioKKyogQGJyaWVmIEV4dHJhY3RzIHRoZSBSZWQsIEdyZWVuLCBCbHVlLCBvciBIdWUsIFNhdHVyYXRpb24gb3IgTHVtaW5hbmNlCisqIGluZm9ybWF0aW9uIGZyb20gYSBjb2xvciBpbWFnZS4KKyogU3VwcG9ydHMgSU1BUV9JTUFHRV9SR0IsIElNQVFfSU1BR0VfSFNMLCBJTUFRX0lNQUdFX1JHQl9VNjQuCisqCisqIEBwYXJhbSBpbWFnZSBUaGUgc291cmNlIGltYWdlIHRoYXQgdGhlIGZ1bmN0aW9uIGV4dHJhY3RzIHRoZSBwbGFuZXMgZnJvbS4KKyogQHBhcmFtIG1vZGUgVGhlIGNvbG9yIHNwYWNlIHRoYXQgdGhlIGZ1bmN0aW9uIGV4dHJhY3RzIHRoZSBwbGFuZXMgZnJvbS4gVmFsaWQKKyogdmFsdWVzIGFyZSBJTUFRX1JHQiwgSU1BUV9IU0wsIElNQVFfSFNWLCBJTUFRX0hTSS4KKyogQHBhcmFtIHBsYW5lMSBPbiByZXR1cm4sIHRoZSBmaXJzdCBleHRyYWN0ZWQgcGxhbmUuIFNldCB0aGlzIHBhcmFtZXRlciB0byBudWxscHRyCisqIGlmIHlvdSBkbyBub3QgbmVlZCB0aGlzIGluZm9ybWF0aW9uLiBSR0ItUmVkLCBIU0wvSFNWL0hTSS1IdWUuCisqIEBwYXJhbSBwbGFuZTIgT24gcmV0dXJuLCB0aGUgc2Vjb25kIGV4dHJhY3RlZCBwbGFuZS4gU2V0IHRoaXMgcGFyYW1ldGVyIHRvCisqIG51bGxwdHIgaWYgeW91IGRvIG5vdCBuZWVkIHRoaXMgaW5mb3JtYXRpb24uIFJHQi1HcmVlbiwgSFNML0hTVi9IU0ktU2F0dXJhdGlvbi4KKyogQHBhcmFtIHBsYW5lMyBPbiByZXR1cm4sIHRoZSB0aGlyZCBleHRyYWN0ZWQgcGxhbmUuIFNldCB0aGlzIHBhcmFtZXRlciB0byBudWxscHRyCisqIGlmIHlvdSBkbyBub3QgbmVlZCB0aGlzIGluZm9ybWF0aW9uLiBSR0ItQmx1ZSwgSFNMLUx1bWluYW5jZSwgSFNWLVZhbHVlLAorKiBIU0ktSW50ZW5zaXR5LgorKgorKiBAcmV0dXJuIGVycm9yIGNvZGU6IDAgPSBlcnJvci4gVG8gZ2V0IGV4dGVuZGVkIGVycm9yIGluZm9ybWF0aW9uLCBjYWxsCisqIEdldExhc3RFcnJvcigpLgorKi8KK2ludCBmcmNFeHRyYWN0Q29sb3JQbGFuZXMoY29uc3QgSW1hZ2UqIGltYWdlLCBDb2xvck1vZGUgbW9kZSwgSW1hZ2UqIHBsYW5lMSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgSW1hZ2UqIHBsYW5lMiwgSW1hZ2UqIHBsYW5lMykgeworICByZXR1cm4gaW1hcUV4dHJhY3RDb2xvclBsYW5lcyhpbWFnZSwgbW9kZSwgcGxhbmUxLCBwbGFuZTIsIHBsYW5lMyk7Cit9CisKKy8qKgorKiBAYnJpZWYgRXh0cmFjdHMgdGhlIEh1ZSBpbmZvcm1hdGlvbiBmcm9tIGEgY29sb3IgaW1hZ2UuIFN1cHBvcnRzCisqIElNQVFfSU1BR0VfUkdCLCBJTUFRX0lNQUdFX0hTTCwgSU1BUV9JTUFHRV9SR0JfVTY0CisqCisqIEBwYXJhbSBpbWFnZSBUaGUgc291cmNlIGltYWdlIHRoYXQgdGhlIGZ1bmN0aW9uIGV4dHJhY3RzIHRoZSBwbGFuZSBmcm9tLgorKiBAcGFyYW0gaHVlUGxhbmUgT24gcmV0dXJuLCB0aGUgZXh0cmFjdGVkIGh1ZSBwbGFuZS4KKyogQHBhcmFtIG1pblNhdHVyYXRpb24gdGhlIG1pbmltdW0gc2F0dXJhdGlvbiBsZXZlbCByZXF1aXJlZCAwLTI1NSAodHJ5IDUwKQorKgorKiBAcmV0dXJuIE9uIHN1Y2Nlc3M6IDEuIE9uIGZhaWx1cmU6IDAuIFRvIGdldCBleHRlbmRlZCBlcnJvciBpbmZvcm1hdGlvbiwgY2FsbAorKiBHZXRMYXN0RXJyb3IoKS4KKyovCitpbnQgZnJjRXh0cmFjdEh1ZVBsYW5lKGNvbnN0IEltYWdlKiBpbWFnZSwgSW1hZ2UqIGh1ZVBsYW5lKSB7CisgIHJldHVybiBmcmNFeHRyYWN0SHVlUGxhbmUoaW1hZ2UsIGh1ZVBsYW5lLCBERUZBVUxUX1NBVFVSQVRJT05fVEhSRVNIT0xEKTsKK30KKworaW50IGZyY0V4dHJhY3RIdWVQbGFuZShjb25zdCBJbWFnZSogaW1hZ2UsIEltYWdlKiBodWVQbGFuZSwgaW50IG1pblNhdHVyYXRpb24pIHsKKyAgcmV0dXJuIGZyY0V4dHJhY3RDb2xvclBsYW5lcyhpbWFnZSwgSU1BUV9IU0wsIGh1ZVBsYW5lLCBudWxscHRyLCBudWxscHRyKTsKK30K