ZGlmZiAtLWdpdCBhL3NyYy9CYXNlNjQuY3BwIGIvc3JjL0Jhc2U2NC5jcHAKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMTdhYTEyNQotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9CYXNlNjQuY3BwCkBAIC0wLDAgKzEsMTUyIEBACisvKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qLworLyogQ29weXJpZ2h0IChjKSBGSVJTVCAyMDE1LiBBbGwgUmlnaHRzIFJlc2VydmVkLiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKi8KKy8qIE9wZW4gU291cmNlIFNvZnR3YXJlIC0gbWF5IGJlIG1vZGlmaWVkIGFuZCBzaGFyZWQgYnkgRlJDIHRlYW1zLiBUaGUgY29kZSAgICovCisvKiBtdXN0IGJlIGFjY29tcGFuaWVkIGJ5IHRoZSBGSVJTVCBCU0QgbGljZW5zZSBmaWxlIGluIHRoZSByb290IGRpcmVjdG9yeSBvZiAqLworLyogdGhlIHByb2plY3QuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKi8KKy8qLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovCisKKy8qID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CisgKiBDb3B5cmlnaHQgKGMpIDE5OTUtMTk5OSBUaGUgQXBhY2hlIEdyb3VwLiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KKyAqCisgKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKKyAqIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucworICogYXJlIG1ldDoKKyAqCisgKiAxLiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAorICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgorICoKKyAqIDIuIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0CisgKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4KKyAqICAgIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKKyAqICAgIGRpc3RyaWJ1dGlvbi4KKyAqCisgKiAzLiBBbGwgYWR2ZXJ0aXNpbmcgbWF0ZXJpYWxzIG1lbnRpb25pbmcgZmVhdHVyZXMgb3IgdXNlIG9mIHRoaXMKKyAqICAgIHNvZnR3YXJlIG11c3QgZGlzcGxheSB0aGUgZm9sbG93aW5nIGFja25vd2xlZGdtZW50OgorICogICAgIlRoaXMgcHJvZHVjdCBpbmNsdWRlcyBzb2Z0d2FyZSBkZXZlbG9wZWQgYnkgdGhlIEFwYWNoZSBHcm91cAorICogICAgZm9yIHVzZSBpbiB0aGUgQXBhY2hlIEhUVFAgc2VydmVyIHByb2plY3QgKGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8pLiIKKyAqCisgKiA0LiBUaGUgbmFtZXMgIkFwYWNoZSBTZXJ2ZXIiIGFuZCAiQXBhY2hlIEdyb3VwIiBtdXN0IG5vdCBiZSB1c2VkIHRvCisgKiAgICBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgd2l0aG91dAorICogICAgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLiBGb3Igd3JpdHRlbiBwZXJtaXNzaW9uLCBwbGVhc2UgY29udGFjdAorICogICAgYXBhY2hlQGFwYWNoZS5vcmcuCisgKgorICogNS4gUHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgbWF5IG5vdCBiZSBjYWxsZWQgIkFwYWNoZSIKKyAqICAgIG5vciBtYXkgIkFwYWNoZSIgYXBwZWFyIGluIHRoZWlyIG5hbWVzIHdpdGhvdXQgcHJpb3Igd3JpdHRlbgorICogICAgcGVybWlzc2lvbiBvZiB0aGUgQXBhY2hlIEdyb3VwLgorICoKKyAqIDYuIFJlZGlzdHJpYnV0aW9ucyBvZiBhbnkgZm9ybSB3aGF0c29ldmVyIG11c3QgcmV0YWluIHRoZSBmb2xsb3dpbmcKKyAqICAgIGFja25vd2xlZGdtZW50OgorICogICAgIlRoaXMgcHJvZHVjdCBpbmNsdWRlcyBzb2Z0d2FyZSBkZXZlbG9wZWQgYnkgdGhlIEFwYWNoZSBHcm91cAorICogICAgZm9yIHVzZSBpbiB0aGUgQXBhY2hlIEhUVFAgc2VydmVyIHByb2plY3QgKGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8pLiIKKyAqCisgKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBBUEFDSEUgR1JPVVAgYGBBUyBJUycnIEFORCBBTlkKKyAqIEVYUFJFU1NFRCBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUKKyAqIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUgorICogUFVSUE9TRSBBUkUgRElTQ0xBSU1FRC4gIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBBUEFDSEUgR1JPVVAgT1IKKyAqIElUUyBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKKyAqIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVAorICogTk9UIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7CisgKiBMT1NTIE9GIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKQorICogSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULAorICogU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKQorICogQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRAorICogT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLgorICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KKyAqCisgKiBUaGlzIHNvZnR3YXJlIGNvbnNpc3RzIG9mIHZvbHVudGFyeSBjb250cmlidXRpb25zIG1hZGUgYnkgbWFueQorICogaW5kaXZpZHVhbHMgb24gYmVoYWxmIG9mIHRoZSBBcGFjaGUgR3JvdXAgYW5kIHdhcyBvcmlnaW5hbGx5IGJhc2VkCisgKiBvbiBwdWJsaWMgZG9tYWluIHNvZnR3YXJlIHdyaXR0ZW4gYXQgdGhlIE5hdGlvbmFsIENlbnRlciBmb3IKKyAqIFN1cGVyY29tcHV0aW5nIEFwcGxpY2F0aW9ucywgVW5pdmVyc2l0eSBvZiBJbGxpbm9pcywgVXJiYW5hLUNoYW1wYWlnbi4KKyAqIEZvciBtb3JlIGluZm9ybWF0aW9uIG9uIHRoZSBBcGFjaGUgR3JvdXAgYW5kIHRoZSBBcGFjaGUgSFRUUCBzZXJ2ZXIKKyAqIHByb2plY3QsIHBsZWFzZSBzZWUgPGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8+LgorICoKKyAqLworCisjaW5jbHVkZSAiQmFzZTY0LmgiCisKK25hbWVzcGFjZSBudCB7CisKKy8vIGFhYWFjayBidXQgaXQncyBmYXN0IGFuZCBjb25zdCBzaG91bGQgbWFrZSBpdCBzaGFyZWQgdGV4dCBwYWdlLgorc3RhdGljIGNvbnN0IHVuc2lnbmVkIGNoYXIgcHIyc2l4WzI1Nl0gPQoreworICAgIC8vIEFTQ0lJIHRhYmxlCisgICAgNjQsIDY0LCA2NCwgNjQsIDY0LCA2NCwgNjQsIDY0LCA2NCwgNjQsIDY0LCA2NCwgNjQsIDY0LCA2NCwgNjQsCisgICAgNjQsIDY0LCA2NCwgNjQsIDY0LCA2NCwgNjQsIDY0LCA2NCwgNjQsIDY0LCA2NCwgNjQsIDY0LCA2NCwgNjQsCisgICAgNjQsIDY0LCA2NCwgNjQsIDY0LCA2NCwgNjQsIDY0LCA2NCwgNjQsIDY0LCA2MiwgNjQsIDY0LCA2NCwgNjMsCisgICAgNTIsIDUzLCA1NCwgNTUsIDU2LCA1NywgNTgsIDU5LCA2MCwgNjEsIDY0LCA2NCwgNjQsIDY0LCA2NCwgNjQsCisgICAgNjQsICAwLCAgMSwgIDIsICAzLCAgNCwgIDUsICA2LCAgNywgIDgsICA5LCAxMCwgMTEsIDEyLCAxMywgMTQsCisgICAgMTUsIDE2LCAxNywgMTgsIDE5LCAyMCwgMjEsIDIyLCAyMywgMjQsIDI1LCA2NCwgNjQsIDY0LCA2NCwgNjQsCisgICAgNjQsIDI2LCAyNywgMjgsIDI5LCAzMCwgMzEsIDMyLCAzMywgMzQsIDM1LCAzNiwgMzcsIDM4LCAzOSwgNDAsCisgICAgNDEsIDQyLCA0MywgNDQsIDQ1LCA0NiwgNDcsIDQ4LCA0OSwgNTAsIDUxLCA2NCwgNjQsIDY0LCA2NCwgNjQsCisgICAgNjQsIDY0LCA2NCwgNjQsIDY0LCA2NCwgNjQsIDY0LCA2NCwgNjQsIDY0LCA2NCwgNjQsIDY0LCA2NCwgNjQsCisgICAgNjQsIDY0LCA2NCwgNjQsIDY0LCA2NCwgNjQsIDY0LCA2NCwgNjQsIDY0LCA2NCwgNjQsIDY0LCA2NCwgNjQsCisgICAgNjQsIDY0LCA2NCwgNjQsIDY0LCA2NCwgNjQsIDY0LCA2NCwgNjQsIDY0LCA2NCwgNjQsIDY0LCA2NCwgNjQsCisgICAgNjQsIDY0LCA2NCwgNjQsIDY0LCA2NCwgNjQsIDY0LCA2NCwgNjQsIDY0LCA2NCwgNjQsIDY0LCA2NCwgNjQsCisgICAgNjQsIDY0LCA2NCwgNjQsIDY0LCA2NCwgNjQsIDY0LCA2NCwgNjQsIDY0LCA2NCwgNjQsIDY0LCA2NCwgNjQsCisgICAgNjQsIDY0LCA2NCwgNjQsIDY0LCA2NCwgNjQsIDY0LCA2NCwgNjQsIDY0LCA2NCwgNjQsIDY0LCA2NCwgNjQsCisgICAgNjQsIDY0LCA2NCwgNjQsIDY0LCA2NCwgNjQsIDY0LCA2NCwgNjQsIDY0LCA2NCwgNjQsIDY0LCA2NCwgNjQsCisgICAgNjQsIDY0LCA2NCwgNjQsIDY0LCA2NCwgNjQsIDY0LCA2NCwgNjQsIDY0LCA2NCwgNjQsIDY0LCA2NCwgNjQKK307CisKK3N0ZDo6c2l6ZV90IEJhc2U2NERlY29kZShsbHZtOjpTdHJpbmdSZWYgZW5jb2RlZCwgc3RkOjpzdHJpbmcqIHBsYWluKSB7CisgIGNvbnN0IHVuc2lnbmVkIGNoYXIgKmVuZCA9IGVuY29kZWQuYnl0ZXNfYmVnaW4oKTsKKyAgd2hpbGUgKHByMnNpeFsqZW5kXSA8PSA2MyAmJiBlbmQgIT0gZW5jb2RlZC5ieXRlc19lbmQoKSkgKytlbmQ7CisgIHN0ZDo6c2l6ZV90IG5wcmJ5dGVzID0gZW5kIC0gZW5jb2RlZC5ieXRlc19iZWdpbigpOworCisgIHBsYWluLT5jbGVhcigpOworICBpZiAobnByYnl0ZXMgPT0gMCkKKyAgICByZXR1cm4gMDsKKyAgcGxhaW4tPnJlc2VydmUoKChucHJieXRlcyArIDMpIC8gNCkgKiAzKTsKKworICBjb25zdCB1bnNpZ25lZCBjaGFyICpjdXIgPSBlbmNvZGVkLmJ5dGVzX2JlZ2luKCk7CisKKyAgd2hpbGUgKG5wcmJ5dGVzID4gNCkgeworICAgICgqcGxhaW4pICs9IChwcjJzaXhbY3VyWzBdXSA8PCAyIHwgcHIyc2l4W2N1clsxXV0gPj4gNCk7CisgICAgKCpwbGFpbikgKz0gKHByMnNpeFtjdXJbMV1dIDw8IDQgfCBwcjJzaXhbY3VyWzJdXSA+PiAyKTsKKyAgICAoKnBsYWluKSArPSAocHIyc2l4W2N1clsyXV0gPDwgNiB8IHByMnNpeFtjdXJbM11dKTsKKyAgICBjdXIgKz0gNDsKKyAgICBucHJieXRlcyAtPSA0OworICB9CisKKyAgLy8gTm90ZTogKG5wcmJ5dGVzID09IDEpIHdvdWxkIGJlIGFuIGVycm9yLCBzbyBqdXN0IGlnbm9yZSB0aGF0IGNhc2UKKyAgaWYgKG5wcmJ5dGVzID4gMSkgKCpwbGFpbikgKz0gKHByMnNpeFtjdXJbMF1dIDw8IDIgfCBwcjJzaXhbY3VyWzFdXSA+PiA0KTsKKyAgaWYgKG5wcmJ5dGVzID4gMikgKCpwbGFpbikgKz0gKHByMnNpeFtjdXJbMV1dIDw8IDQgfCBwcjJzaXhbY3VyWzJdXSA+PiAyKTsKKyAgaWYgKG5wcmJ5dGVzID4gMykgKCpwbGFpbikgKz0gKHByMnNpeFtjdXJbMl1dIDw8IDYgfCBwcjJzaXhbY3VyWzNdXSk7CisKKyAgcmV0dXJuIChlbmQgLSBlbmNvZGVkLmJ5dGVzX2JlZ2luKCkpICsgKCg0IC0gbnByYnl0ZXMpICYgMyk7Cit9CisKK3N0YXRpYyBjb25zdCBjaGFyIGJhc2lzXzY0W10gPQorICAgICJBQkNERUZHSElKS0xNTk9QUVJTVFVWV1hZWmFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6MDEyMzQ1Njc4OSsvIjsKKwordm9pZCBCYXNlNjRFbmNvZGUobGx2bTo6U3RyaW5nUmVmIHBsYWluLCBzdGQ6OnN0cmluZyogZW5jb2RlZCkgeworICBlbmNvZGVkLT5jbGVhcigpOworICBpZiAocGxhaW4uZW1wdHkoKSkKKyAgICByZXR1cm47CisgIHN0ZDo6c2l6ZV90IGxlbiA9IHBsYWluLnNpemUoKTsKKyAgZW5jb2RlZC0+cmVzZXJ2ZSgoKGxlbiArIDIpIC8gMyAqIDQpICsgMSk7CisKKyAgc3RkOjpzaXplX3QgaTsKKyAgZm9yIChpID0gMDsgKGkgKyAyKSA8IGxlbjsgaSArPSAzKSB7CisgICAgKCplbmNvZGVkKSArPSBiYXNpc182NFsocGxhaW5baV0gPj4gMikgJiAweDNGXTsKKyAgICAoKmVuY29kZWQpICs9CisgICAgICAgIGJhc2lzXzY0WygocGxhaW5baV0gJiAweDMpIDw8IDQpIHwgKChpbnQpKHBsYWluW2kgKyAxXSAmIDB4RjApID4+IDQpXTsKKyAgICAoKmVuY29kZWQpICs9IGJhc2lzXzY0WygocGxhaW5baSArIDFdICYgMHhGKSA8PCAyKSB8CisgICAgICAgICAgICAgICAgICAgICAgICAgICAoKGludCkocGxhaW5baSArIDJdICYgMHhDMCkgPj4gNildOworICAgICgqZW5jb2RlZCkgKz0gYmFzaXNfNjRbcGxhaW5baSArIDJdICYgMHgzRl07CisgIH0KKyAgaWYgKGkgPCBsZW4pIHsKKyAgICAoKmVuY29kZWQpICs9IGJhc2lzXzY0WyhwbGFpbltpXSA+PiAyKSAmIDB4M0ZdOworICAgIGlmIChpID09IChsZW4gLSAxKSkgeworICAgICAgKCplbmNvZGVkKSArPSBiYXNpc182NFsoKHBsYWluW2ldICYgMHgzKSA8PCA0KV07CisgICAgICAoKmVuY29kZWQpICs9ICc9JzsKKyAgICB9IGVsc2UgeworICAgICAgKCplbmNvZGVkKSArPQorICAgICAgICAgIGJhc2lzXzY0WygocGxhaW5baV0gJiAweDMpIDw8IDQpIHwgKChpbnQpKHBsYWluW2kgKyAxXSAmIDB4RjApID4+IDQpXTsKKyAgICAgICgqZW5jb2RlZCkgKz0gYmFzaXNfNjRbKChwbGFpbltpICsgMV0gJiAweEYpIDw8IDIpXTsKKyAgICB9CisgICAgKCplbmNvZGVkKSArPSAnPSc7CisgIH0KK30KKworfSAgLy8gbmFtZXNwYWNlIG50CmRpZmYgLS1naXQgYS9zcmMvQmFzZTY0LmggYi9zcmMvQmFzZTY0LmgKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYTg2ZTY5OQotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9CYXNlNjQuaApAQCAtMCwwICsxLDIzIEBACisvKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qLworLyogQ29weXJpZ2h0IChjKSBGSVJTVCAyMDE1LiBBbGwgUmlnaHRzIFJlc2VydmVkLiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKi8KKy8qIE9wZW4gU291cmNlIFNvZnR3YXJlIC0gbWF5IGJlIG1vZGlmaWVkIGFuZCBzaGFyZWQgYnkgRlJDIHRlYW1zLiBUaGUgY29kZSAgICovCisvKiBtdXN0IGJlIGFjY29tcGFuaWVkIGJ5IHRoZSBGSVJTVCBCU0QgbGljZW5zZSBmaWxlIGluIHRoZSByb290IGRpcmVjdG9yeSBvZiAqLworLyogdGhlIHByb2plY3QuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKi8KKy8qLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovCisKKyNpZm5kZWYgTlRfQkFTRTY0X0hfCisjZGVmaW5lIE5UX0JBU0U2NF9IXworCisjaW5jbHVkZSA8Y3N0ZGRlZj4KKyNpbmNsdWRlIDxzdHJpbmc+CisKKyNpbmNsdWRlICJsbHZtL1N0cmluZ1JlZi5oIgorCituYW1lc3BhY2UgbnQgeworCitzdGQ6OnNpemVfdCBCYXNlNjREZWNvZGUobGx2bTo6U3RyaW5nUmVmIGVuY29kZWQsIHN0ZDo6c3RyaW5nKiBwbGFpbik7Cit2b2lkIEJhc2U2NEVuY29kZShsbHZtOjpTdHJpbmdSZWYgcGxhaW4sIHN0ZDo6c3RyaW5nKiBlbmNvZGVkKTsKKworfSAgLy8gbmFtZXNwYWNlIG50CisKKyNlbmRpZiAgLy8gTlRfQkFTRTY0X0hfCmRpZmYgLS1naXQgYS9zcmMvRGlzcGF0Y2hlci5jcHAgYi9zcmMvRGlzcGF0Y2hlci5jcHAKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMmI4ZmNiMgotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9EaXNwYXRjaGVyLmNwcApAQCAtMCwwICsxLDQ4NyBAQAorLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi8KKy8qIENvcHlyaWdodCAoYykgRklSU1QgMjAxNS4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICovCisvKiBPcGVuIFNvdXJjZSBTb2Z0d2FyZSAtIG1heSBiZSBtb2RpZmllZCBhbmQgc2hhcmVkIGJ5IEZSQyB0ZWFtcy4gVGhlIGNvZGUgICAqLworLyogbXVzdCBiZSBhY2NvbXBhbmllZCBieSB0aGUgRklSU1QgQlNEIGxpY2Vuc2UgZmlsZSBpbiB0aGUgcm9vdCBkaXJlY3Rvcnkgb2YgKi8KKy8qIHRoZSBwcm9qZWN0LiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICovCisvKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qLworCisjaW5jbHVkZSAiRGlzcGF0Y2hlci5oIgorCisjaW5jbHVkZSA8YWxnb3JpdGhtPgorI2luY2x1ZGUgPGl0ZXJhdG9yPgorCisjaW5jbHVkZSAidGNwc29ja2V0cy9UQ1BBY2NlcHRvci5oIgorI2luY2x1ZGUgInRjcHNvY2tldHMvVENQQ29ubmVjdG9yLmgiCisjaW5jbHVkZSAiTG9nLmgiCisKK3VzaW5nIG5hbWVzcGFjZSBudDsKKworQVRPTUlDX1NUQVRJQ19JTklUKERpc3BhdGNoZXIpCisKK3ZvaWQgRGlzcGF0Y2hlcjo6U3RhcnRTZXJ2ZXIoU3RyaW5nUmVmIHBlcnNpc3RfZmlsZW5hbWUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGNoYXIqIGxpc3Rlbl9hZGRyZXNzLCB1bnNpZ25lZCBpbnQgcG9ydCkgeworICBEaXNwYXRjaGVyQmFzZTo6U3RhcnRTZXJ2ZXIocGVyc2lzdF9maWxlbmFtZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0ZDo6dW5pcXVlX3B0cjxOZXR3b3JrQWNjZXB0b3I+KG5ldyBUQ1BBY2NlcHRvcigKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdGF0aWNfY2FzdDxpbnQ+KHBvcnQpLCBsaXN0ZW5fYWRkcmVzcykpKTsKK30KKwordm9pZCBEaXNwYXRjaGVyOjpTdGFydENsaWVudChjb25zdCBjaGFyKiBzZXJ2ZXJfbmFtZSwgdW5zaWduZWQgaW50IHBvcnQpIHsKKyAgc3RkOjpzdHJpbmcgc2VydmVyX25hbWVfY29weShzZXJ2ZXJfbmFtZSk7CisgIERpc3BhdGNoZXJCYXNlOjpTdGFydENsaWVudChbPV0oKSAtPiBzdGQ6OnVuaXF1ZV9wdHI8TmV0d29ya1N0cmVhbT4geworICAgIHJldHVybiBUQ1BDb25uZWN0b3I6OmNvbm5lY3Qoc2VydmVyX25hbWVfY29weS5jX3N0cigpLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RhdGljX2Nhc3Q8aW50Pihwb3J0KSwgMSk7CisgIH0pOworfQorCitEaXNwYXRjaGVyOjpEaXNwYXRjaGVyKCkKKyAgICA6IERpc3BhdGNoZXIoU3RvcmFnZTo6R2V0SW5zdGFuY2UoKSwgTm90aWZpZXI6OkdldEluc3RhbmNlKCkpIHt9CisKK0Rpc3BhdGNoZXJCYXNlOjpEaXNwYXRjaGVyQmFzZShTdG9yYWdlJiBzdG9yYWdlLCBOb3RpZmllciYgbm90aWZpZXIpCisgICAgOiBtX3N0b3JhZ2Uoc3RvcmFnZSksIG1fbm90aWZpZXIobm90aWZpZXIpIHsKKyAgbV9hY3RpdmUgPSBmYWxzZTsKKyAgbV91cGRhdGVfcmF0ZSA9IDEwMDsKK30KKworRGlzcGF0Y2hlckJhc2U6On5EaXNwYXRjaGVyQmFzZSgpIHsKKyAgTG9nZ2VyOjpHZXRJbnN0YW5jZSgpLlNldExvZ2dlcihudWxscHRyKTsKKyAgU3RvcCgpOworfQorCit2b2lkIERpc3BhdGNoZXJCYXNlOjpTdGFydFNlcnZlcihTdHJpbmdSZWYgcGVyc2lzdF9maWxlbmFtZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0ZDo6dW5pcXVlX3B0cjxOZXR3b3JrQWNjZXB0b3I+IGFjY2VwdG9yKSB7CisgIHsKKyAgICBzdGQ6OmxvY2tfZ3VhcmQ8c3RkOjptdXRleD4gbG9jayhtX3VzZXJfbXV0ZXgpOworICAgIGlmIChtX2FjdGl2ZSkgcmV0dXJuOworICAgIG1fYWN0aXZlID0gdHJ1ZTsKKyAgfQorICBtX3NlcnZlciA9IHRydWU7CisgIG1fcGVyc2lzdF9maWxlbmFtZSA9IHBlcnNpc3RfZmlsZW5hbWU7CisgIG1fc2VydmVyX2FjY2VwdG9yID0gc3RkOjptb3ZlKGFjY2VwdG9yKTsKKworICAvLyBMb2FkIHBlcnNpc3RlbnQgZmlsZS4gIElnbm9yZSBlcnJvcnMsIGJ1dCBwYXNzIGFsb25nIHdhcm5pbmdzLgorICBpZiAoIXBlcnNpc3RfZmlsZW5hbWUuZW1wdHkoKSkgeworICAgIGJvb2wgZmlyc3QgPSB0cnVlOworICAgIG1fc3RvcmFnZS5Mb2FkUGVyc2lzdGVudCgKKyAgICAgICAgcGVyc2lzdF9maWxlbmFtZSwgWyZdKHN0ZDo6c2l6ZV90IGxpbmUsIGNvbnN0IGNoYXIqIG1zZykgeworICAgICAgICAgIGlmIChmaXJzdCkgeworICAgICAgICAgICAgZmlyc3QgPSBmYWxzZTsKKyAgICAgICAgICAgIFdBUk5JTkcoIldoZW4gcmVhZGluZyBpbml0aWFsIHBlcnNpc3RlbnQgdmFsdWVzIGZyb20gJyIKKyAgICAgICAgICAgICAgICAgICAgPDwgcGVyc2lzdF9maWxlbmFtZSA8PCAiJzoiKTsKKyAgICAgICAgICB9CisgICAgICAgICAgV0FSTklORyhwZXJzaXN0X2ZpbGVuYW1lIDw8ICI6IiA8PCBsaW5lIDw8ICI6ICIgPDwgbXNnKTsKKyAgICAgICAgfSk7CisgIH0KKworICB1c2luZyBuYW1lc3BhY2Ugc3RkOjpwbGFjZWhvbGRlcnM7CisgIG1fc3RvcmFnZS5TZXRPdXRnb2luZyhzdGQ6OmJpbmQoJkRpc3BhdGNoZXI6OlF1ZXVlT3V0Z29pbmcsIHRoaXMsIF8xLCBfMiwgXzMpLAorICAgICAgICAgICAgICAgICAgICAgICAgbV9zZXJ2ZXIpOworCisgIG1fZGlzcGF0Y2hfdGhyZWFkID0gc3RkOjp0aHJlYWQoJkRpc3BhdGNoZXI6OkRpc3BhdGNoVGhyZWFkTWFpbiwgdGhpcyk7CisgIG1fY2xpZW50c2VydmVyX3RocmVhZCA9IHN0ZDo6dGhyZWFkKCZEaXNwYXRjaGVyOjpTZXJ2ZXJUaHJlYWRNYWluLCB0aGlzKTsKK30KKwordm9pZCBEaXNwYXRjaGVyQmFzZTo6U3RhcnRDbGllbnQoCisgICAgc3RkOjpmdW5jdGlvbjxzdGQ6OnVuaXF1ZV9wdHI8TmV0d29ya1N0cmVhbT4oKT4gY29ubmVjdCkgeworICB7CisgICAgc3RkOjpsb2NrX2d1YXJkPHN0ZDo6bXV0ZXg+IGxvY2sobV91c2VyX211dGV4KTsKKyAgICBpZiAobV9hY3RpdmUpIHJldHVybjsKKyAgICBtX2FjdGl2ZSA9IHRydWU7CisgIH0KKyAgbV9zZXJ2ZXIgPSBmYWxzZTsKKworICB1c2luZyBuYW1lc3BhY2Ugc3RkOjpwbGFjZWhvbGRlcnM7CisgIG1fc3RvcmFnZS5TZXRPdXRnb2luZyhzdGQ6OmJpbmQoJkRpc3BhdGNoZXI6OlF1ZXVlT3V0Z29pbmcsIHRoaXMsIF8xLCBfMiwgXzMpLAorICAgICAgICAgICAgICAgICAgICAgICAgbV9zZXJ2ZXIpOworCisgIG1fZGlzcGF0Y2hfdGhyZWFkID0gc3RkOjp0aHJlYWQoJkRpc3BhdGNoZXI6OkRpc3BhdGNoVGhyZWFkTWFpbiwgdGhpcyk7CisgIG1fY2xpZW50c2VydmVyX3RocmVhZCA9CisgICAgICBzdGQ6OnRocmVhZCgmRGlzcGF0Y2hlcjo6Q2xpZW50VGhyZWFkTWFpbiwgdGhpcywgY29ubmVjdCk7Cit9CisKK3ZvaWQgRGlzcGF0Y2hlckJhc2U6OlN0b3AoKSB7CisgIG1fYWN0aXZlID0gZmFsc2U7CisKKyAgLy8gd2FrZSB1cCBkaXNwYXRjaCB0aHJlYWQgd2l0aCBhIGZsdXNoCisgIG1fZmx1c2hfY3Yubm90aWZ5X29uZSgpOworCisgIC8vIHdha2UgdXAgY2xpZW50IHRocmVhZCB3aXRoIGEgcmVjb25uZWN0CisgIENsaWVudFJlY29ubmVjdCgpOworCisgIC8vIHdha2UgdXAgc2VydmVyIHRocmVhZCBieSBzaHV0dGluZyBkb3duIHRoZSBzb2NrZXQKKyAgaWYgKG1fc2VydmVyX2FjY2VwdG9yKSBtX3NlcnZlcl9hY2NlcHRvci0+c2h1dGRvd24oKTsKKworICAvLyBqb2luIHRocmVhZHMsIHdpdGggdGltZW91dAorICBpZiAobV9kaXNwYXRjaF90aHJlYWQuam9pbmFibGUoKSkgbV9kaXNwYXRjaF90aHJlYWQuam9pbigpOworICBpZiAobV9jbGllbnRzZXJ2ZXJfdGhyZWFkLmpvaW5hYmxlKCkpIG1fY2xpZW50c2VydmVyX3RocmVhZC5qb2luKCk7CisKKyAgc3RkOjp2ZWN0b3I8c3RkOjpzaGFyZWRfcHRyPE5ldHdvcmtDb25uZWN0aW9uPj4gY29ubnM7CisgIHsKKyAgICBzdGQ6OmxvY2tfZ3VhcmQ8c3RkOjptdXRleD4gbG9jayhtX3VzZXJfbXV0ZXgpOworICAgIGNvbm5zLnN3YXAobV9jb25uZWN0aW9ucyk7CisgIH0KKworICAvLyBjbG9zZSBhbGwgY29ubmVjdGlvbnMKKyAgY29ubnMucmVzaXplKDApOworfQorCit2b2lkIERpc3BhdGNoZXJCYXNlOjpTZXRVcGRhdGVSYXRlKGRvdWJsZSBpbnRlcnZhbCkgeworICAvLyBkb24ndCBhbGxvdyB1cGRhdGUgcmF0ZXMgZmFzdGVyIHRoYW4gMTAwIG1zIG9yIHNsb3dlciB0aGFuIDEgc2Vjb25kCisgIGlmIChpbnRlcnZhbCA8IDAuMSkKKyAgICBpbnRlcnZhbCA9IDAuMTsKKyAgZWxzZSBpZiAoaW50ZXJ2YWwgPiAxLjApCisgICAgaW50ZXJ2YWwgPSAxLjA7CisgIG1fdXBkYXRlX3JhdGUgPSBzdGF0aWNfY2FzdDx1bnNpZ25lZCBpbnQ+KGludGVydmFsICogMTAwMCk7Cit9CisKK3ZvaWQgRGlzcGF0Y2hlckJhc2U6OlNldElkZW50aXR5KGxsdm06OlN0cmluZ1JlZiBuYW1lKSB7CisgIHN0ZDo6bG9ja19ndWFyZDxzdGQ6Om11dGV4PiBsb2NrKG1fdXNlcl9tdXRleCk7CisgIG1faWRlbnRpdHkgPSBuYW1lOworfQorCit2b2lkIERpc3BhdGNoZXJCYXNlOjpGbHVzaCgpIHsKKyAgYXV0byBub3cgPSBzdGQ6OmNocm9ubzo6c3RlYWR5X2Nsb2NrOjpub3coKTsKKyAgeworICAgIHN0ZDo6bG9ja19ndWFyZDxzdGQ6Om11dGV4PiBsb2NrKG1fZmx1c2hfbXV0ZXgpOworICAgIC8vIGRvbid0IGFsbG93IGZsdXNoZXMgbW9yZSBvZnRlbiB0aGFuIGV2ZXJ5IDEwMCBtcworICAgIGlmICgobm93IC0gbV9sYXN0X2ZsdXNoKSA8IHN0ZDo6Y2hyb25vOjptaWxsaXNlY29uZHMoMTAwKSkKKyAgICAgIHJldHVybjsKKyAgICBtX2xhc3RfZmx1c2ggPSBub3c7CisgICAgbV9kb19mbHVzaCA9IHRydWU7CisgIH0KKyAgbV9mbHVzaF9jdi5ub3RpZnlfb25lKCk7Cit9CisKK3N0ZDo6dmVjdG9yPENvbm5lY3Rpb25JbmZvPiBEaXNwYXRjaGVyQmFzZTo6R2V0Q29ubmVjdGlvbnMoKSBjb25zdCB7CisgIHN0ZDo6dmVjdG9yPENvbm5lY3Rpb25JbmZvPiBjb25uczsKKyAgaWYgKCFtX2FjdGl2ZSkgcmV0dXJuIGNvbm5zOworCisgIHN0ZDo6bG9ja19ndWFyZDxzdGQ6Om11dGV4PiBsb2NrKG1fdXNlcl9tdXRleCk7CisgIGZvciAoYXV0byYgY29ubiA6IG1fY29ubmVjdGlvbnMpIHsKKyAgICBpZiAoY29ubi0+c3RhdGUoKSAhPSBOZXR3b3JrQ29ubmVjdGlvbjo6a0FjdGl2ZSkgY29udGludWU7CisgICAgY29ubnMuZW1wbGFjZV9iYWNrKGNvbm4tPmluZm8oKSk7CisgIH0KKworICByZXR1cm4gY29ubnM7Cit9CisKK3ZvaWQgRGlzcGF0Y2hlckJhc2U6Ok5vdGlmeUNvbm5lY3Rpb25zKAorICAgIENvbm5lY3Rpb25MaXN0ZW5lckNhbGxiYWNrIGNhbGxiYWNrKSBjb25zdCB7CisgIHN0ZDo6bG9ja19ndWFyZDxzdGQ6Om11dGV4PiBsb2NrKG1fdXNlcl9tdXRleCk7CisgIGZvciAoYXV0byYgY29ubiA6IG1fY29ubmVjdGlvbnMpIHsKKyAgICBpZiAoY29ubi0+c3RhdGUoKSAhPSBOZXR3b3JrQ29ubmVjdGlvbjo6a0FjdGl2ZSkgY29udGludWU7CisgICAgbV9ub3RpZmllci5Ob3RpZnlDb25uZWN0aW9uKHRydWUsIGNvbm4tPmluZm8oKSwgY2FsbGJhY2spOworICB9Cit9CisKK3ZvaWQgRGlzcGF0Y2hlckJhc2U6OkRpc3BhdGNoVGhyZWFkTWFpbigpIHsKKyAgYXV0byB0aW1lb3V0X3RpbWUgPSBzdGQ6OmNocm9ubzo6c3RlYWR5X2Nsb2NrOjpub3coKTsKKworICBzdGF0aWMgY29uc3QgYXV0byBzYXZlX2RlbHRhX3RpbWUgPSBzdGQ6OmNocm9ubzo6c2Vjb25kcygxKTsKKyAgYXV0byBuZXh0X3NhdmVfdGltZSA9IHRpbWVvdXRfdGltZSArIHNhdmVfZGVsdGFfdGltZTsKKworICBpbnQgY291bnQgPSAwOworCisgIHN0ZDo6dW5pcXVlX2xvY2s8c3RkOjptdXRleD4gZmx1c2hfbG9jayhtX2ZsdXNoX211dGV4KTsKKyAgd2hpbGUgKG1fYWN0aXZlKSB7CisgICAgLy8gaGFuZGxlIGxvb3AgdGFraW5nIHRvbyBsb25nCisgICAgYXV0byBzdGFydCA9IHN0ZDo6Y2hyb25vOjpzdGVhZHlfY2xvY2s6Om5vdygpOworICAgIGlmIChzdGFydCA+IHRpbWVvdXRfdGltZSkKKyAgICAgIHRpbWVvdXRfdGltZSA9IHN0YXJ0OworCisgICAgLy8gd2FpdCBmb3IgcGVyaW9kaWMgb3Igd2hlbiBmbHVzaGVkCisgICAgdGltZW91dF90aW1lICs9IHN0ZDo6Y2hyb25vOjptaWxsaXNlY29uZHMobV91cGRhdGVfcmF0ZSk7CisgICAgbV9mbHVzaF9jdi53YWl0X3VudGlsKGZsdXNoX2xvY2ssIHRpbWVvdXRfdGltZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgWyZdIHsgcmV0dXJuICFtX2FjdGl2ZSB8fCBtX2RvX2ZsdXNoOyB9KTsKKyAgICBtX2RvX2ZsdXNoID0gZmFsc2U7CisgICAgaWYgKCFtX2FjdGl2ZSkgYnJlYWs7ICAvLyBpbiBjYXNlIHdlIHdlcmUgd29rZW4gdXAgdG8gdGVybWluYXRlCisKKyAgICAvLyBwZXJmb3JtIHBlcmlvZGljIHBlcnNpc3RlbnQgc2F2ZQorICAgIGlmIChtX3NlcnZlciAmJiAhbV9wZXJzaXN0X2ZpbGVuYW1lLmVtcHR5KCkgJiYgc3RhcnQgPiBuZXh0X3NhdmVfdGltZSkgeworICAgICAgbmV4dF9zYXZlX3RpbWUgKz0gc2F2ZV9kZWx0YV90aW1lOworICAgICAgLy8gaGFuZGxlIGxvb3AgdGFraW5nIHRvbyBsb25nCisgICAgICBpZiAoc3RhcnQgPiBuZXh0X3NhdmVfdGltZSkgbmV4dF9zYXZlX3RpbWUgPSBzdGFydCArIHNhdmVfZGVsdGFfdGltZTsKKyAgICAgIGNvbnN0IGNoYXIqIGVyciA9IG1fc3RvcmFnZS5TYXZlUGVyc2lzdGVudChtX3BlcnNpc3RfZmlsZW5hbWUsIHRydWUpOworICAgICAgaWYgKGVycikgV0FSTklORygicGVyaW9kaWMgcGVyc2lzdGVudCBzYXZlOiAiIDw8IGVycik7CisgICAgfQorCisgICAgeworICAgICAgc3RkOjpsb2NrX2d1YXJkPHN0ZDo6bXV0ZXg+IHVzZXJfbG9jayhtX3VzZXJfbXV0ZXgpOworICAgICAgYm9vbCByZWNvbm5lY3QgPSBmYWxzZTsKKworICAgICAgaWYgKCsrY291bnQgPiAxMCkgeworICAgICAgICBERUJVRygiZGlzcGF0Y2ggcnVubmluZyAiIDw8IG1fY29ubmVjdGlvbnMuc2l6ZSgpIDw8ICIgY29ubmVjdGlvbnMiKTsKKyAgICAgICAgY291bnQgPSAwOworICAgICAgfQorCisgICAgICBmb3IgKGF1dG8mIGNvbm4gOiBtX2Nvbm5lY3Rpb25zKSB7CisgICAgICAgIC8vIHBvc3Qgb3V0Z29pbmcgbWVzc2FnZXMgaWYgY29ubmVjdGlvbiBpcyBhY3RpdmUKKyAgICAgICAgLy8gb25seSBzZW5kIGtlZXAtYWxpdmVzIG9uIGNsaWVudAorICAgICAgICBpZiAoY29ubi0+c3RhdGUoKSA9PSBOZXR3b3JrQ29ubmVjdGlvbjo6a0FjdGl2ZSkKKyAgICAgICAgICBjb25uLT5Qb3N0T3V0Z29pbmcoIW1fc2VydmVyKTsKKworICAgICAgICAvLyBpZiBjbGllbnQsIHJlY29ubmVjdCBpZiBjb25uZWN0aW9uIGRpZWQKKyAgICAgICAgaWYgKCFtX3NlcnZlciAmJiBjb25uLT5zdGF0ZSgpID09IE5ldHdvcmtDb25uZWN0aW9uOjprRGVhZCkKKyAgICAgICAgICByZWNvbm5lY3QgPSB0cnVlOworICAgICAgfQorICAgICAgLy8gcmVjb25uZWN0IGlmIHdlIGRpc2Nvbm5lY3RlZCAoYW5kIGEgcmVjb25uZWN0IGlzIG5vdCBpbiBwcm9ncmVzcykKKyAgICAgIGlmIChyZWNvbm5lY3QgJiYgIW1fZG9fcmVjb25uZWN0KSB7CisgICAgICAgIG1fZG9fcmVjb25uZWN0ID0gdHJ1ZTsKKyAgICAgICAgbV9yZWNvbm5lY3RfY3Yubm90aWZ5X29uZSgpOworICAgICAgfQorICAgIH0KKyAgfQorfQorCit2b2lkIERpc3BhdGNoZXJCYXNlOjpRdWV1ZU91dGdvaW5nKHN0ZDo6c2hhcmVkX3B0cjxNZXNzYWdlPiBtc2csCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE5ldHdvcmtDb25uZWN0aW9uKiBvbmx5LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBOZXR3b3JrQ29ubmVjdGlvbiogZXhjZXB0KSB7CisgIHN0ZDo6bG9ja19ndWFyZDxzdGQ6Om11dGV4PiB1c2VyX2xvY2sobV91c2VyX211dGV4KTsKKyAgZm9yIChhdXRvJiBjb25uIDogbV9jb25uZWN0aW9ucykgeworICAgIGlmIChjb25uLmdldCgpID09IGV4Y2VwdCkgY29udGludWU7CisgICAgaWYgKG9ubHkgJiYgY29ubi5nZXQoKSAhPSBvbmx5KSBjb250aW51ZTsKKyAgICBhdXRvIHN0YXRlID0gY29ubi0+c3RhdGUoKTsKKyAgICBpZiAoc3RhdGUgIT0gTmV0d29ya0Nvbm5lY3Rpb246OmtTeW5jaHJvbml6ZWQgJiYKKyAgICAgICAgc3RhdGUgIT0gTmV0d29ya0Nvbm5lY3Rpb246OmtBY3RpdmUpIGNvbnRpbnVlOworICAgIGNvbm4tPlF1ZXVlT3V0Z29pbmcobXNnKTsKKyAgfQorfQorCit2b2lkIERpc3BhdGNoZXJCYXNlOjpTZXJ2ZXJUaHJlYWRNYWluKCkgeworICBpZiAobV9zZXJ2ZXJfYWNjZXB0b3ItPnN0YXJ0KCkgIT0gMCkgeworICAgIG1fYWN0aXZlID0gZmFsc2U7CisgICAgcmV0dXJuOworICB9CisgIHdoaWxlIChtX2FjdGl2ZSkgeworICAgIGF1dG8gc3RyZWFtID0gbV9zZXJ2ZXJfYWNjZXB0b3ItPmFjY2VwdCgpOworICAgIGlmICghc3RyZWFtKSB7CisgICAgICBtX2FjdGl2ZSA9IGZhbHNlOworICAgICAgcmV0dXJuOworICAgIH0KKyAgICBpZiAoIW1fYWN0aXZlKSByZXR1cm47CisgICAgREVCVUcoInNlcnZlcjogY2xpZW50IGNvbm5lY3Rpb24gZnJvbSAiIDw8IHN0cmVhbS0+Z2V0UGVlcklQKCkgPDwgIiBwb3J0ICIKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPDwgc3RyZWFtLT5nZXRQZWVyUG9ydCgpKTsKKworICAgIC8vIGFkZCB0byBjb25uZWN0aW9ucyBsaXN0CisgICAgdXNpbmcgbmFtZXNwYWNlIHN0ZDo6cGxhY2Vob2xkZXJzOworICAgIGF1dG8gY29ubiA9IHN0ZDo6bWFrZV9zaGFyZWQ8TmV0d29ya0Nvbm5lY3Rpb24+KAorICAgICAgICBzdGQ6Om1vdmUoc3RyZWFtKSwgbV9ub3RpZmllciwKKyAgICAgICAgc3RkOjpiaW5kKCZEaXNwYXRjaGVyOjpTZXJ2ZXJIYW5kc2hha2UsIHRoaXMsIF8xLCBfMiwgXzMpLAorICAgICAgICBzdGQ6OmJpbmQoJlN0b3JhZ2U6OkdldEVudHJ5VHlwZSwgJm1fc3RvcmFnZSwgXzEpKTsKKyAgICBjb25uLT5zZXRfcHJvY2Vzc19pbmNvbWluZygKKyAgICAgICAgc3RkOjpiaW5kKCZTdG9yYWdlOjpQcm9jZXNzSW5jb21pbmcsICZtX3N0b3JhZ2UsIF8xLCBfMiwKKyAgICAgICAgICAgICAgICAgIHN0ZDo6d2Vha19wdHI8TmV0d29ya0Nvbm5lY3Rpb24+KGNvbm4pKSk7CisgICAgeworICAgICAgc3RkOjpsb2NrX2d1YXJkPHN0ZDo6bXV0ZXg+IGxvY2sobV91c2VyX211dGV4KTsKKyAgICAgIC8vIHJldXNlIGRlYWQgY29ubmVjdGlvbiBzbG90cworICAgICAgYm9vbCBwbGFjZWQgPSBmYWxzZTsKKyAgICAgIGZvciAoYXV0byYgYyA6IG1fY29ubmVjdGlvbnMpIHsKKyAgICAgICAgaWYgKGMtPnN0YXRlKCkgPT0gTmV0d29ya0Nvbm5lY3Rpb246OmtEZWFkKSB7CisgICAgICAgICAgYyA9IGNvbm47CisgICAgICAgICAgcGxhY2VkID0gdHJ1ZTsKKyAgICAgICAgICBicmVhazsKKyAgICAgICAgfQorICAgICAgfQorICAgICAgaWYgKCFwbGFjZWQpIG1fY29ubmVjdGlvbnMuZW1wbGFjZV9iYWNrKGNvbm4pOworICAgICAgY29ubi0+U3RhcnQoKTsKKyAgICB9CisgIH0KK30KKwordm9pZCBEaXNwYXRjaGVyQmFzZTo6Q2xpZW50VGhyZWFkTWFpbigKKyAgICBzdGQ6OmZ1bmN0aW9uPHN0ZDo6dW5pcXVlX3B0cjxOZXR3b3JrU3RyZWFtPigpPiBjb25uZWN0KSB7CisgIHdoaWxlIChtX2FjdGl2ZSkgeworICAgIC8vIHNsZWVwIGJldHdlZW4gcmV0cmllcworICAgIHN0ZDo6dGhpc190aHJlYWQ6OnNsZWVwX2ZvcihzdGQ6OmNocm9ubzo6bWlsbGlzZWNvbmRzKDUwMCkpOworCisgICAgLy8gdHJ5IHRvIGNvbm5lY3QgKHdpdGggdGltZW91dCkKKyAgICBERUJVRygiY2xpZW50IHRyeWluZyB0byBjb25uZWN0Iik7CisgICAgYXV0byBzdHJlYW0gPSBjb25uZWN0KCk7CisgICAgaWYgKCFzdHJlYW0pIGNvbnRpbnVlOyAgLy8ga2VlcCByZXRyeWluZworICAgIERFQlVHKCJjbGllbnQgY29ubmVjdGVkIik7CisKKyAgICBzdGQ6OnVuaXF1ZV9sb2NrPHN0ZDo6bXV0ZXg+IGxvY2sobV91c2VyX211dGV4KTsKKyAgICB1c2luZyBuYW1lc3BhY2Ugc3RkOjpwbGFjZWhvbGRlcnM7CisgICAgYXV0byBjb25uID0gc3RkOjptYWtlX3NoYXJlZDxOZXR3b3JrQ29ubmVjdGlvbj4oCisgICAgICAgIHN0ZDo6bW92ZShzdHJlYW0pLCBtX25vdGlmaWVyLAorICAgICAgICBzdGQ6OmJpbmQoJkRpc3BhdGNoZXI6OkNsaWVudEhhbmRzaGFrZSwgdGhpcywgXzEsIF8yLCBfMyksCisgICAgICAgIHN0ZDo6YmluZCgmU3RvcmFnZTo6R2V0RW50cnlUeXBlLCAmbV9zdG9yYWdlLCBfMSkpOworICAgIGNvbm4tPnNldF9wcm9jZXNzX2luY29taW5nKAorICAgICAgICBzdGQ6OmJpbmQoJlN0b3JhZ2U6OlByb2Nlc3NJbmNvbWluZywgJm1fc3RvcmFnZSwgXzEsIF8yLAorICAgICAgICAgICAgICAgICAgc3RkOjp3ZWFrX3B0cjxOZXR3b3JrQ29ubmVjdGlvbj4oY29ubikpKTsKKyAgICBtX2Nvbm5lY3Rpb25zLnJlc2l6ZSgwKTsgIC8vIGRpc2Nvbm5lY3QgYW55IGN1cnJlbnQKKyAgICBtX2Nvbm5lY3Rpb25zLmVtcGxhY2VfYmFjayhjb25uKTsKKyAgICBjb25uLT5zZXRfcHJvdG9fcmV2KG1fcmVjb25uZWN0X3Byb3RvX3Jldik7CisgICAgY29ubi0+U3RhcnQoKTsKKworICAgIC8vIGJsb2NrIHVudGlsIHRvbGQgdG8gcmVjb25uZWN0CisgICAgbV9kb19yZWNvbm5lY3QgPSBmYWxzZTsKKyAgICBtX3JlY29ubmVjdF9jdi53YWl0KGxvY2ssIFsmXSB7IHJldHVybiAhbV9hY3RpdmUgfHwgbV9kb19yZWNvbm5lY3Q7IH0pOworICB9Cit9CisKK2Jvb2wgRGlzcGF0Y2hlckJhc2U6OkNsaWVudEhhbmRzaGFrZSgKKyAgICBOZXR3b3JrQ29ubmVjdGlvbiYgY29ubiwKKyAgICBzdGQ6OmZ1bmN0aW9uPHN0ZDo6c2hhcmVkX3B0cjxNZXNzYWdlPigpPiBnZXRfbXNnLAorICAgIHN0ZDo6ZnVuY3Rpb248dm9pZChsbHZtOjpBcnJheVJlZjxzdGQ6OnNoYXJlZF9wdHI8TWVzc2FnZT4+KT4gc2VuZF9tc2dzKSB7CisgIC8vIGdldCBpZGVudGl0eQorICBzdGQ6OnN0cmluZyBzZWxmX2lkOworICB7CisgICAgc3RkOjpsb2NrX2d1YXJkPHN0ZDo6bXV0ZXg+IGxvY2sobV91c2VyX211dGV4KTsKKyAgICBzZWxmX2lkID0gbV9pZGVudGl0eTsKKyAgfQorCisgIC8vIHNlbmQgY2xpZW50IGhlbGxvCisgIERFQlVHKCJjbGllbnQ6IHNlbmRpbmcgaGVsbG8iKTsKKyAgc2VuZF9tc2dzKE1lc3NhZ2U6OkNsaWVudEhlbGxvKHNlbGZfaWQpKTsKKworICAvLyB3YWl0IGZvciByZXNwb25zZQorICBhdXRvIG1zZyA9IGdldF9tc2coKTsKKyAgaWYgKCFtc2cpIHsKKyAgICAvLyBkaXNjb25uZWN0ZWQsIHJldHJ5CisgICAgREVCVUcoImNsaWVudDogc2VydmVyIGRpc2Nvbm5lY3RlZCBiZWZvcmUgZmlyc3QgcmVzcG9uc2UiKTsKKyAgICByZXR1cm4gZmFsc2U7CisgIH0KKworICBpZiAobXNnLT5JcyhNZXNzYWdlOjprUHJvdG9VbnN1cCkpIHsKKyAgICBpZiAobXNnLT5pZCgpID09IDB4MDIwMCkgQ2xpZW50UmVjb25uZWN0KDB4MDIwMCk7CisgICAgcmV0dXJuIGZhbHNlOworICB9CisKKyAgYm9vbCBuZXdfc2VydmVyID0gdHJ1ZTsKKyAgaWYgKGNvbm4ucHJvdG9fcmV2KCkgPj0gMHgwMzAwKSB7CisgICAgLy8gc2hvdWxkIGJlIHNlcnZlciBoZWxsbzsgaWYgbm90LCBkaXNjb25uZWN0LgorICAgIGlmICghbXNnLT5JcyhNZXNzYWdlOjprU2VydmVySGVsbG8pKSByZXR1cm4gZmFsc2U7CisgICAgY29ubi5zZXRfcmVtb3RlX2lkKG1zZy0+c3RyKCkpOworICAgIGlmICgobXNnLT5mbGFncygpICYgMSkgIT0gMCkgbmV3X3NlcnZlciA9IGZhbHNlOworICAgIC8vIGdldCB0aGUgbmV4dCBtZXNzYWdlCisgICAgbXNnID0gZ2V0X21zZygpOworICB9CisKKyAgLy8gcmVjZWl2ZSBpbml0aWFsIGFzc2lnbm1lbnRzCisgIHN0ZDo6dmVjdG9yPHN0ZDo6c2hhcmVkX3B0cjxNZXNzYWdlPj4gaW5jb21pbmc7CisgIGZvciAoOzspIHsKKyAgICBpZiAoIW1zZykgeworICAgICAgLy8gZGlzY29ubmVjdGVkLCByZXRyeQorICAgICAgREVCVUcoImNsaWVudDogc2VydmVyIGRpc2Nvbm5lY3RlZCBkdXJpbmcgaW5pdGlhbCBlbnRyaWVzIik7CisgICAgICByZXR1cm4gZmFsc2U7CisgICAgfQorICAgIERFQlVHNCgicmVjZWl2ZWQgaW5pdCBzdHI9IiA8PCBtc2ctPnN0cigpIDw8ICIgaWQ9IiA8PCBtc2ctPmlkKCkKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPDwgIiBzZXFfbnVtPSIgPDwgbXNnLT5zZXFfbnVtX3VpZCgpKTsKKyAgICBpZiAobXNnLT5JcyhNZXNzYWdlOjprU2VydmVySGVsbG9Eb25lKSkgYnJlYWs7CisgICAgaWYgKCFtc2ctPklzKE1lc3NhZ2U6OmtFbnRyeUFzc2lnbikpIHsKKyAgICAgIC8vIHVuZXhwZWN0ZWQgbWVzc2FnZQorICAgICAgREVCVUcoImNsaWVudDogcmVjZWl2ZWQgbWVzc2FnZSAoIiA8PCBtc2ctPnR5cGUoKSA8PCAiKSBvdGhlciB0aGFuIGVudHJ5IGFzc2lnbm1lbnQgZHVyaW5nIGluaXRpYWwgaGFuZHNoYWtlIik7CisgICAgICByZXR1cm4gZmFsc2U7CisgICAgfQorICAgIGluY29taW5nLmVtcGxhY2VfYmFjayhzdGQ6Om1vdmUobXNnKSk7CisgICAgLy8gZ2V0IHRoZSBuZXh0IG1lc3NhZ2UKKyAgICBtc2cgPSBnZXRfbXNnKCk7CisgIH0KKworICAvLyBnZW5lcmF0ZSBvdXRnb2luZyBhc3NpZ25tZW50cworICBOZXR3b3JrQ29ubmVjdGlvbjo6T3V0Z29pbmcgb3V0Z29pbmc7CisKKyAgbV9zdG9yYWdlLkFwcGx5SW5pdGlhbEFzc2lnbm1lbnRzKGNvbm4sIGluY29taW5nLCBuZXdfc2VydmVyLCAmb3V0Z29pbmcpOworCisgIGlmIChjb25uLnByb3RvX3JldigpID49IDB4MDMwMCkKKyAgICBvdXRnb2luZy5lbXBsYWNlX2JhY2soTWVzc2FnZTo6Q2xpZW50SGVsbG9Eb25lKCkpOworCisgIGlmICghb3V0Z29pbmcuZW1wdHkoKSkgc2VuZF9tc2dzKG91dGdvaW5nKTsKKworICBJTkZPKCJjbGllbnQ6IENPTk5FQ1RFRCB0byBzZXJ2ZXIgIiA8PCBjb25uLnN0cmVhbSgpLmdldFBlZXJJUCgpIDw8ICIgcG9ydCAiCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDw8IGNvbm4uc3RyZWFtKCkuZ2V0UGVlclBvcnQoKSk7CisgIHJldHVybiB0cnVlOworfQorCitib29sIERpc3BhdGNoZXJCYXNlOjpTZXJ2ZXJIYW5kc2hha2UoCisgICAgTmV0d29ya0Nvbm5lY3Rpb24mIGNvbm4sCisgICAgc3RkOjpmdW5jdGlvbjxzdGQ6OnNoYXJlZF9wdHI8TWVzc2FnZT4oKT4gZ2V0X21zZywKKyAgICBzdGQ6OmZ1bmN0aW9uPHZvaWQobGx2bTo6QXJyYXlSZWY8c3RkOjpzaGFyZWRfcHRyPE1lc3NhZ2U+Pik+IHNlbmRfbXNncykgeworICAvLyBXYWl0IGZvciB0aGUgY2xpZW50IHRvIHNlbmQgdXMgYSBoZWxsby4KKyAgYXV0byBtc2cgPSBnZXRfbXNnKCk7CisgIGlmICghbXNnKSB7CisgICAgREVCVUcoInNlcnZlcjogY2xpZW50IGRpc2Nvbm5lY3RlZCBiZWZvcmUgc2VuZGluZyBoZWxsbyIpOworICAgIHJldHVybiBmYWxzZTsKKyAgfQorICBpZiAoIW1zZy0+SXMoTWVzc2FnZTo6a0NsaWVudEhlbGxvKSkgeworICAgIERFQlVHKCJzZXJ2ZXI6IGNsaWVudCBpbml0aWFsIG1lc3NhZ2Ugd2FzIG5vdCBjbGllbnQgaGVsbG8iKTsKKyAgICByZXR1cm4gZmFsc2U7CisgIH0KKworICAvLyBDaGVjayB0aGF0IHRoZSBjbGllbnQgcmVxdWVzdGVkIHZlcnNpb24gaXMgbm90IHRvbyBoaWdoLgorICB1bnNpZ25lZCBpbnQgcHJvdG9fcmV2ID0gbXNnLT5pZCgpOworICBpZiAocHJvdG9fcmV2ID4gMHgwMzAwKSB7CisgICAgREVCVUcoInNlcnZlcjogY2xpZW50IHJlcXVlc3RlZCBwcm90byA+IDB4MDMwMCIpOworICAgIHNlbmRfbXNncyhNZXNzYWdlOjpQcm90b1Vuc3VwKCkpOworICAgIHJldHVybiBmYWxzZTsKKyAgfQorCisgIGlmIChwcm90b19yZXYgPj0gMHgwMzAwKSBjb25uLnNldF9yZW1vdGVfaWQobXNnLT5zdHIoKSk7CisKKyAgLy8gU2V0IHRoZSBwcm90byB2ZXJzaW9uIHRvIHRoZSBjbGllbnQgcmVxdWVzdGVkIHZlcnNpb24KKyAgREVCVUcoInNlcnZlcjogY2xpZW50IHByb3RvY29sICIgPDwgcHJvdG9fcmV2KTsKKyAgY29ubi5zZXRfcHJvdG9fcmV2KHByb3RvX3Jldik7CisKKyAgLy8gU2VuZCBpbml0aWFsIHNldCBvZiBhc3NpZ25tZW50cworICBOZXR3b3JrQ29ubmVjdGlvbjo6T3V0Z29pbmcgb3V0Z29pbmc7CisKKyAgLy8gU3RhcnQgd2l0aCBzZXJ2ZXIgaGVsbG8uICBUT0RPOiBpbml0aWFsIGNvbm5lY3Rpb24gZmxhZworICBpZiAocHJvdG9fcmV2ID49IDB4MDMwMCkgeworICAgIHN0ZDo6bG9ja19ndWFyZDxzdGQ6Om11dGV4PiBsb2NrKG1fdXNlcl9tdXRleCk7CisgICAgb3V0Z29pbmcuZW1wbGFjZV9iYWNrKE1lc3NhZ2U6OlNlcnZlckhlbGxvKDB1LCBtX2lkZW50aXR5KSk7CisgIH0KKworICAvLyBHZXQgc25hcHNob3Qgb2YgaW5pdGlhbCBhc3NpZ25tZW50cworICBtX3N0b3JhZ2UuR2V0SW5pdGlhbEFzc2lnbm1lbnRzKGNvbm4sICZvdXRnb2luZyk7CisKKyAgLy8gRmluaXNoIHdpdGggc2VydmVyIGhlbGxvIGRvbmUKKyAgb3V0Z29pbmcuZW1wbGFjZV9iYWNrKE1lc3NhZ2U6OlNlcnZlckhlbGxvRG9uZSgpKTsKKworICAvLyBCYXRjaCB0cmFuc21pdAorICBERUJVRygic2VydmVyOiBzZW5kaW5nIGluaXRpYWwgYXNzaWdubWVudHMiKTsKKyAgc2VuZF9tc2dzKG91dGdvaW5nKTsKKworICAvLyBJbiBwcm90byByZXYgMy4wIGFuZCBsYXRlciwgdGhlIGhhbmRzaGFrZSBjb25jbHVkZXMgd2l0aCBhIGNsaWVudCBoZWxsbworICAvLyBkb25lIG1lc3NhZ2UsIHNvIHdlIGNhbiBiYXRjaCB0aGUgYXNzaWducyBiZWZvcmUgbWFya2luZyB0aGUgY29ubmVjdGlvbgorICAvLyBhY3RpdmUuICBJbiBwcmUtMy4wLCB3ZSBuZWVkIHRvIGp1c3QgaW1tZWRpYXRlbHkgbWFyayBpdCBhY3RpdmUgYW5kIGhhbmQKKyAgLy8gb2ZmIGNvbnRyb2wgdG8gdGhlIGRpc3BhdGNoZXIgdG8gYXNzaWduIHRoZW0gYXMgdGhleSBhcnJpdmUuCisgIGlmIChwcm90b19yZXYgPj0gMHgwMzAwKSB7CisgICAgLy8gcmVjZWl2ZSBjbGllbnQgaW5pdGlhbCBhc3NpZ25tZW50cworICAgIHN0ZDo6dmVjdG9yPHN0ZDo6c2hhcmVkX3B0cjxNZXNzYWdlPj4gaW5jb21pbmc7CisgICAgbXNnID0gZ2V0X21zZygpOworICAgIGZvciAoOzspIHsKKyAgICAgIGlmICghbXNnKSB7CisgICAgICAgIC8vIGRpc2Nvbm5lY3RlZCwgcmV0cnkKKyAgICAgICAgREVCVUcoInNlcnZlcjogZGlzY29ubmVjdGVkIHdhaXRpbmcgZm9yIGluaXRpYWwgZW50cmllcyIpOworICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICB9CisgICAgICBpZiAobXNnLT5JcyhNZXNzYWdlOjprQ2xpZW50SGVsbG9Eb25lKSkgYnJlYWs7CisgICAgICBpZiAoIW1zZy0+SXMoTWVzc2FnZTo6a0VudHJ5QXNzaWduKSkgeworICAgICAgICAvLyB1bmV4cGVjdGVkIG1lc3NhZ2UKKyAgICAgICAgREVCVUcoInNlcnZlcjogcmVjZWl2ZWQgbWVzc2FnZSAoIgorICAgICAgICAgICAgICA8PCBtc2ctPnR5cGUoKQorICAgICAgICAgICAgICA8PCAiKSBvdGhlciB0aGFuIGVudHJ5IGFzc2lnbm1lbnQgZHVyaW5nIGluaXRpYWwgaGFuZHNoYWtlIik7CisgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgIH0KKyAgICAgIGluY29taW5nLnB1c2hfYmFjayhtc2cpOworICAgICAgLy8gZ2V0IHRoZSBuZXh0IG1lc3NhZ2UgKGJsb2NrcykKKyAgICAgIG1zZyA9IGdldF9tc2coKTsKKyAgICB9CisgICAgZm9yIChhdXRvJiBtc2cgOiBpbmNvbWluZykKKyAgICAgIG1fc3RvcmFnZS5Qcm9jZXNzSW5jb21pbmcobXNnLCAmY29ubiwgc3RkOjp3ZWFrX3B0cjxOZXR3b3JrQ29ubmVjdGlvbj4oKSk7CisgIH0KKworICBJTkZPKCJzZXJ2ZXI6IGNsaWVudCBDT05ORUNURUQ6ICIgPDwgY29ubi5zdHJlYW0oKS5nZXRQZWVySVAoKSA8PCAiIHBvcnQgIgorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPDwgY29ubi5zdHJlYW0oKS5nZXRQZWVyUG9ydCgpKTsKKyAgcmV0dXJuIHRydWU7Cit9CisKK3ZvaWQgRGlzcGF0Y2hlckJhc2U6OkNsaWVudFJlY29ubmVjdCh1bnNpZ25lZCBpbnQgcHJvdG9fcmV2KSB7CisgIGlmIChtX3NlcnZlcikgcmV0dXJuOworICB7CisgICAgc3RkOjpsb2NrX2d1YXJkPHN0ZDo6bXV0ZXg+IGxvY2sobV91c2VyX211dGV4KTsKKyAgICBtX3JlY29ubmVjdF9wcm90b19yZXYgPSBwcm90b19yZXY7CisgICAgbV9kb19yZWNvbm5lY3QgPSB0cnVlOworICB9CisgIG1fcmVjb25uZWN0X2N2Lm5vdGlmeV9vbmUoKTsKK30KZGlmZiAtLWdpdCBhL3NyYy9EaXNwYXRjaGVyLmggYi9zcmMvRGlzcGF0Y2hlci5oCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjI2ZjVlNzYKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvRGlzcGF0Y2hlci5oCkBAIC0wLDAgKzEsMTI3IEBACisvKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qLworLyogQ29weXJpZ2h0IChjKSBGSVJTVCAyMDE1LiBBbGwgUmlnaHRzIFJlc2VydmVkLiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKi8KKy8qIE9wZW4gU291cmNlIFNvZnR3YXJlIC0gbWF5IGJlIG1vZGlmaWVkIGFuZCBzaGFyZWQgYnkgRlJDIHRlYW1zLiBUaGUgY29kZSAgICovCisvKiBtdXN0IGJlIGFjY29tcGFuaWVkIGJ5IHRoZSBGSVJTVCBCU0QgbGljZW5zZSBmaWxlIGluIHRoZSByb290IGRpcmVjdG9yeSBvZiAqLworLyogdGhlIHByb2plY3QuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKi8KKy8qLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovCisKKyNpZm5kZWYgTlRfRElTUEFUQ0hFUl9IXworI2RlZmluZSBOVF9ESVNQQVRDSEVSX0hfCisKKyNpbmNsdWRlIDxhdG9taWM+CisjaW5jbHVkZSA8Y2hyb25vPgorI2luY2x1ZGUgPGNvbmRpdGlvbl92YXJpYWJsZT4KKyNpbmNsdWRlIDxmdW5jdGlvbmFsPgorI2luY2x1ZGUgPG1lbW9yeT4KKyNpbmNsdWRlIDxtdXRleD4KKyNpbmNsdWRlIDxzdHJpbmc+CisjaW5jbHVkZSA8dmVjdG9yPgorCisjaW5jbHVkZSAibGx2bS9TdHJpbmdSZWYuaCIKKworI2luY2x1ZGUgImF0b21pY19zdGF0aWMuaCIKKyNpbmNsdWRlICJOZXR3b3JrQ29ubmVjdGlvbi5oIgorI2luY2x1ZGUgIk5vdGlmaWVyLmgiCisjaW5jbHVkZSAiU3RvcmFnZS5oIgorCitjbGFzcyBOZXR3b3JrQWNjZXB0b3I7CitjbGFzcyBOZXR3b3JrU3RyZWFtOworCituYW1lc3BhY2UgbnQgeworCitjbGFzcyBEaXNwYXRjaGVyQmFzZSB7CisgIGZyaWVuZCBjbGFzcyBEaXNwYXRjaGVyVGVzdDsKKyBwdWJsaWM6CisgIHZpcnR1YWwgfkRpc3BhdGNoZXJCYXNlKCk7CisKKyAgdm9pZCBTdGFydFNlcnZlcihTdHJpbmdSZWYgcGVyc2lzdF9maWxlbmFtZSwKKyAgICAgICAgICAgICAgICAgICBzdGQ6OnVuaXF1ZV9wdHI8TmV0d29ya0FjY2VwdG9yPiBhY2NlcHRvcik7CisgIHZvaWQgU3RhcnRDbGllbnQoc3RkOjpmdW5jdGlvbjxzdGQ6OnVuaXF1ZV9wdHI8TmV0d29ya1N0cmVhbT4oKT4gY29ubmVjdCk7CisgIHZvaWQgU3RvcCgpOworICB2b2lkIFNldFVwZGF0ZVJhdGUoZG91YmxlIGludGVydmFsKTsKKyAgdm9pZCBTZXRJZGVudGl0eShsbHZtOjpTdHJpbmdSZWYgbmFtZSk7CisgIHZvaWQgRmx1c2goKTsKKyAgc3RkOjp2ZWN0b3I8Q29ubmVjdGlvbkluZm8+IEdldENvbm5lY3Rpb25zKCkgY29uc3Q7CisgIHZvaWQgTm90aWZ5Q29ubmVjdGlvbnMoQ29ubmVjdGlvbkxpc3RlbmVyQ2FsbGJhY2sgY2FsbGJhY2spIGNvbnN0OworCisgIGJvb2wgYWN0aXZlKCkgY29uc3QgeyByZXR1cm4gbV9hY3RpdmU7IH0KKworICBEaXNwYXRjaGVyQmFzZShjb25zdCBEaXNwYXRjaGVyQmFzZSYpID0gZGVsZXRlOworICBEaXNwYXRjaGVyQmFzZSYgb3BlcmF0b3I9KGNvbnN0IERpc3BhdGNoZXJCYXNlJikgPSBkZWxldGU7CisKKyBwcm90ZWN0ZWQ6CisgIERpc3BhdGNoZXJCYXNlKFN0b3JhZ2UmIHN0b3JhZ2UsIE5vdGlmaWVyJiBub3RpZmllcik7CisKKyBwcml2YXRlOgorICB2b2lkIERpc3BhdGNoVGhyZWFkTWFpbigpOworICB2b2lkIFNlcnZlclRocmVhZE1haW4oKTsKKyAgdm9pZCBDbGllbnRUaHJlYWRNYWluKAorICAgICAgc3RkOjpmdW5jdGlvbjxzdGQ6OnVuaXF1ZV9wdHI8TmV0d29ya1N0cmVhbT4oKT4gY29ubmVjdCk7CisKKyAgYm9vbCBDbGllbnRIYW5kc2hha2UoCisgICAgICBOZXR3b3JrQ29ubmVjdGlvbiYgY29ubiwKKyAgICAgIHN0ZDo6ZnVuY3Rpb248c3RkOjpzaGFyZWRfcHRyPE1lc3NhZ2U+KCk+IGdldF9tc2csCisgICAgICBzdGQ6OmZ1bmN0aW9uPHZvaWQobGx2bTo6QXJyYXlSZWY8c3RkOjpzaGFyZWRfcHRyPE1lc3NhZ2U+Pik+IHNlbmRfbXNncyk7CisgIGJvb2wgU2VydmVySGFuZHNoYWtlKAorICAgICAgTmV0d29ya0Nvbm5lY3Rpb24mIGNvbm4sCisgICAgICBzdGQ6OmZ1bmN0aW9uPHN0ZDo6c2hhcmVkX3B0cjxNZXNzYWdlPigpPiBnZXRfbXNnLAorICAgICAgc3RkOjpmdW5jdGlvbjx2b2lkKGxsdm06OkFycmF5UmVmPHN0ZDo6c2hhcmVkX3B0cjxNZXNzYWdlPj4pPiBzZW5kX21zZ3MpOworCisgIHZvaWQgQ2xpZW50UmVjb25uZWN0KHVuc2lnbmVkIGludCBwcm90b19yZXYgPSAweDAzMDApOworCisgIHZvaWQgUXVldWVPdXRnb2luZyhzdGQ6OnNoYXJlZF9wdHI8TWVzc2FnZT4gbXNnLCBOZXR3b3JrQ29ubmVjdGlvbiogb25seSwKKyAgICAgICAgICAgICAgICAgICAgIE5ldHdvcmtDb25uZWN0aW9uKiBleGNlcHQpOworCisgIFN0b3JhZ2UmIG1fc3RvcmFnZTsKKyAgTm90aWZpZXImIG1fbm90aWZpZXI7CisgIGJvb2wgbV9zZXJ2ZXIgPSBmYWxzZTsKKyAgc3RkOjpzdHJpbmcgbV9wZXJzaXN0X2ZpbGVuYW1lOworICBzdGQ6OnRocmVhZCBtX2Rpc3BhdGNoX3RocmVhZDsKKyAgc3RkOjp0aHJlYWQgbV9jbGllbnRzZXJ2ZXJfdGhyZWFkOworCisgIHN0ZDo6dW5pcXVlX3B0cjxOZXR3b3JrQWNjZXB0b3I+IG1fc2VydmVyX2FjY2VwdG9yOworCisgIC8vIE11dGV4IGZvciB1c2VyLWFjY2Vzc2libGUgaXRlbXMKKyAgbXV0YWJsZSBzdGQ6Om11dGV4IG1fdXNlcl9tdXRleDsKKyAgc3RkOjp2ZWN0b3I8c3RkOjpzaGFyZWRfcHRyPE5ldHdvcmtDb25uZWN0aW9uPj4gbV9jb25uZWN0aW9uczsKKyAgc3RkOjpzdHJpbmcgbV9pZGVudGl0eTsKKworICBzdGQ6OmF0b21pY19ib29sIG1fYWN0aXZlOyAgLy8gc2V0IHRvIGZhbHNlIHRvIHRlcm1pbmF0ZSB0aHJlYWRzCisgIHN0ZDo6YXRvbWljX3VpbnQgbV91cGRhdGVfcmF0ZTsgIC8vIHBlcmlvZGljIGRpc3BhdGNoIHVwZGF0ZSByYXRlLCBpbiBtcworCisgIC8vIENvbmRpdGlvbiB2YXJpYWJsZSBmb3IgZm9yY2VkIGRpc3BhdGNoIHdha2V1cCAoZmx1c2gpCisgIHN0ZDo6bXV0ZXggbV9mbHVzaF9tdXRleDsKKyAgc3RkOjpjb25kaXRpb25fdmFyaWFibGUgbV9mbHVzaF9jdjsKKyAgc3RkOjpjaHJvbm86OnN0ZWFkeV9jbG9jazo6dGltZV9wb2ludCBtX2xhc3RfZmx1c2g7CisgIGJvb2wgbV9kb19mbHVzaCA9IGZhbHNlOworCisgIC8vIENvbmRpdGlvbiB2YXJpYWJsZSBmb3IgY2xpZW50IHJlY29ubmVjdCAodXNlcyB1c2VyIG11dGV4KQorICBzdGQ6OmNvbmRpdGlvbl92YXJpYWJsZSBtX3JlY29ubmVjdF9jdjsKKyAgdW5zaWduZWQgaW50IG1fcmVjb25uZWN0X3Byb3RvX3JldiA9IDB4MDMwMDsKKyAgYm9vbCBtX2RvX3JlY29ubmVjdCA9IHRydWU7Cit9OworCitjbGFzcyBEaXNwYXRjaGVyIDogcHVibGljIERpc3BhdGNoZXJCYXNlIHsKKyAgZnJpZW5kIGNsYXNzIERpc3BhdGNoZXJUZXN0OworIHB1YmxpYzoKKyAgc3RhdGljIERpc3BhdGNoZXImIEdldEluc3RhbmNlKCkgeworICAgIEFUT01JQ19TVEFUSUMoRGlzcGF0Y2hlciwgaW5zdGFuY2UpOworICAgIHJldHVybiBpbnN0YW5jZTsKKyAgfQorCisgIHZvaWQgU3RhcnRTZXJ2ZXIoU3RyaW5nUmVmIHBlcnNpc3RfZmlsZW5hbWUsIGNvbnN0IGNoYXIqIGxpc3Rlbl9hZGRyZXNzLAorICAgICAgICAgICAgICAgICAgIHVuc2lnbmVkIGludCBwb3J0KTsKKyAgdm9pZCBTdGFydENsaWVudChjb25zdCBjaGFyKiBzZXJ2ZXJfbmFtZSwgdW5zaWduZWQgaW50IHBvcnQpOworCisgcHJpdmF0ZToKKyAgRGlzcGF0Y2hlcigpOworICBEaXNwYXRjaGVyKFN0b3JhZ2UmIHN0b3JhZ2UsIE5vdGlmaWVyJiBub3RpZmllcikKKyAgICAgIDogRGlzcGF0Y2hlckJhc2Uoc3RvcmFnZSwgbm90aWZpZXIpIHt9CisKKyAgQVRPTUlDX1NUQVRJQ19ERUNMKERpc3BhdGNoZXIpCit9OworCisKK30gIC8vIG5hbWVzcGFjZSBudAorCisjZW5kaWYgIC8vIE5UX0RJU1BBVENIRVJfSF8KZGlmZiAtLWdpdCBhL3NyYy9Mb2cuY3BwIGIvc3JjL0xvZy5jcHAKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uOWI1YTE4ZAotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9Mb2cuY3BwCkBAIC0wLDAgKzEsNjIgQEAKKy8qLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovCisvKiBDb3B5cmlnaHQgKGMpIEZJUlNUIDIwMTUuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqLworLyogT3BlbiBTb3VyY2UgU29mdHdhcmUgLSBtYXkgYmUgbW9kaWZpZWQgYW5kIHNoYXJlZCBieSBGUkMgdGVhbXMuIFRoZSBjb2RlICAgKi8KKy8qIG11c3QgYmUgYWNjb21wYW5pZWQgYnkgdGhlIEZJUlNUIEJTRCBsaWNlbnNlIGZpbGUgaW4gdGhlIHJvb3QgZGlyZWN0b3J5IG9mICovCisvKiB0aGUgcHJvamVjdC4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqLworLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi8KKworI2luY2x1ZGUgIkxvZy5oIgorCisjaW5jbHVkZSA8Y3N0ZGlvPgorI2lmZGVmIF9XSU4zMgorICNpbmNsdWRlIDxjc3RkbGliPgorI2Vsc2UKKyAjaW5jbHVkZSA8Y3N0cmluZz4KKyNlbmRpZgorCisjaWZkZWYgX19BUFBMRV9fCisgI2luY2x1ZGUgPGxpYmdlbi5oPgorI2VuZGlmCisKK3VzaW5nIG5hbWVzcGFjZSBudDsKKworQVRPTUlDX1NUQVRJQ19JTklUKExvZ2dlcikKKworc3RhdGljIHZvaWQgZGVmX2xvZ19mdW5jKHVuc2lnbmVkIGludCBsZXZlbCwgY29uc3QgY2hhciogZmlsZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICB1bnNpZ25lZCBpbnQgbGluZSwgY29uc3QgY2hhciogbXNnKSB7CisgIGlmIChsZXZlbCA9PSAyMCkgeworICAgIHN0ZDo6ZnByaW50ZihzdGRlcnIsICJOVDogJXNcbiIsIG1zZyk7CisgICAgcmV0dXJuOworICB9CisKKyAgY29uc3QgY2hhciogbGV2ZWxtc2c7CisgIGlmIChsZXZlbCA+PSA1MCkKKyAgICBsZXZlbG1zZyA9ICJDUklUSUNBTCI7CisgIGVsc2UgaWYgKGxldmVsID49IDQwKQorICAgIGxldmVsbXNnID0gIkVSUk9SIjsKKyAgZWxzZSBpZiAobGV2ZWwgPj0gMzApCisgICAgbGV2ZWxtc2cgPSAiV0FSTklORyI7CisgIGVsc2UKKyAgICByZXR1cm47CisjaWZkZWYgX1dJTjMyCisgIGNoYXIgZm5hbWVbNjBdOworICBjaGFyIGV4dFsxMF07CisgIF9zcGxpdHBhdGhfcyhmaWxlLCBudWxscHRyLCAwLCBudWxscHRyLCAwLCBmbmFtZSwgNjAsIGV4dCwgMTApOworICBzdGQ6OmZwcmludGYoc3RkZXJyLCAiTlQ6ICVzOiAlcyAoJXMlczolZClcbiIsIGxldmVsbXNnLCBtc2csIGZuYW1lLCBleHQsCisgICAgICAgICAgICAgICBsaW5lKTsKKyNlbGlmIF9fQVBQTEVfXworICBpbnQgbGVuID0gc3RybGVuKG1zZykgKyAxOworICBjaGFyKiBiYXNlc3RyID0gbmV3IGNoYXJbbGVuICsgMV07CisgIHN0cm5jcHkoYmFzZXN0ciwgZmlsZSwgbGVuKTsKKyAgc3RkOjpmcHJpbnRmKHN0ZGVyciwgIk5UOiAlczogJXMgKCVzOiVkKVxuIiwgbGV2ZWxtc2csIG1zZywgYmFzZW5hbWUoYmFzZXN0ciksCisgICAgICAgICAgICAgICBsaW5lKTsKKyAgZGVsZXRlW10gYmFzZXN0cjsKKyNlbHNlCisgIHN0ZDo6ZnByaW50ZihzdGRlcnIsICJOVDogJXM6ICVzICglczolZClcbiIsIGxldmVsbXNnLCBtc2csIGJhc2VuYW1lKGZpbGUpLAorICAgICAgICAgICAgICAgbGluZSk7CisjZW5kaWYKK30KKworTG9nZ2VyOjpMb2dnZXIoKSA6IG1fZnVuYyhkZWZfbG9nX2Z1bmMpIHt9CisKK0xvZ2dlcjo6fkxvZ2dlcigpIHt9CmRpZmYgLS1naXQgYS9zcmMvTG9nLmggYi9zcmMvTG9nLmgKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZGQ5ZTEyNQotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9Mb2cuaApAQCAtMCwwICsxLDg0IEBACisvKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qLworLyogQ29weXJpZ2h0IChjKSBGSVJTVCAyMDE1LiBBbGwgUmlnaHRzIFJlc2VydmVkLiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKi8KKy8qIE9wZW4gU291cmNlIFNvZnR3YXJlIC0gbWF5IGJlIG1vZGlmaWVkIGFuZCBzaGFyZWQgYnkgRlJDIHRlYW1zLiBUaGUgY29kZSAgICovCisvKiBtdXN0IGJlIGFjY29tcGFuaWVkIGJ5IHRoZSBGSVJTVCBCU0QgbGljZW5zZSBmaWxlIGluIHRoZSByb290IGRpcmVjdG9yeSBvZiAqLworLyogdGhlIHByb2plY3QuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKi8KKy8qLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovCisKKyNpZm5kZWYgTlRfTE9HX0hfCisjZGVmaW5lIE5UX0xPR19IXworCisjaW5jbHVkZSA8ZnVuY3Rpb25hbD4KKyNpbmNsdWRlIDxzc3RyZWFtPgorI2luY2x1ZGUgPHN0cmluZz4KKworI2luY2x1ZGUgImF0b21pY19zdGF0aWMuaCIKKyNpbmNsdWRlICJudGNvcmVfYy5oIgorCituYW1lc3BhY2UgbnQgeworCitjbGFzcyBMb2dnZXIgeworIHB1YmxpYzoKKyAgc3RhdGljIExvZ2dlciYgR2V0SW5zdGFuY2UoKSB7CisgICAgQVRPTUlDX1NUQVRJQyhMb2dnZXIsIGluc3RhbmNlKTsKKyAgICByZXR1cm4gaW5zdGFuY2U7CisgIH0KKyAgfkxvZ2dlcigpOworCisgIHR5cGVkZWYgc3RkOjpmdW5jdGlvbjx2b2lkKHVuc2lnbmVkIGludCBsZXZlbCwgY29uc3QgY2hhciogZmlsZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdW5zaWduZWQgaW50IGxpbmUsIGNvbnN0IGNoYXIqIG1zZyk+IExvZ0Z1bmM7CisKKyAgdm9pZCBTZXRMb2dnZXIoTG9nRnVuYyBmdW5jKSB7IG1fZnVuYyA9IGZ1bmM7IH0KKworICB2b2lkIHNldF9taW5fbGV2ZWwodW5zaWduZWQgaW50IGxldmVsKSB7IG1fbWluX2xldmVsID0gbGV2ZWw7IH0KKyAgdW5zaWduZWQgaW50IG1pbl9sZXZlbCgpIGNvbnN0IHsgcmV0dXJuIG1fbWluX2xldmVsOyB9CisKKyAgdm9pZCBMb2codW5zaWduZWQgaW50IGxldmVsLCBjb25zdCBjaGFyKiBmaWxlLCB1bnNpZ25lZCBpbnQgbGluZSwKKyAgICAgICAgICAgY29uc3QgY2hhciogbXNnKSB7CisgICAgaWYgKCFtX2Z1bmMgfHwgbGV2ZWwgPCBtX21pbl9sZXZlbCkgcmV0dXJuOworICAgIG1fZnVuYyhsZXZlbCwgZmlsZSwgbGluZSwgbXNnKTsKKyAgfQorCisgIGJvb2wgSGFzTG9nZ2VyKCkgY29uc3QgeyByZXR1cm4gbV9mdW5jICE9IG51bGxwdHI7IH0KKworIHByaXZhdGU6CisgIExvZ2dlcigpOworCisgIExvZ0Z1bmMgbV9mdW5jOworICB1bnNpZ25lZCBpbnQgbV9taW5fbGV2ZWwgPSAyMDsKKworICBBVE9NSUNfU1RBVElDX0RFQ0woTG9nZ2VyKQorfTsKKworI2RlZmluZSBMT0cobGV2ZWwsIHgpICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgZG8geyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgICAgbnQ6OkxvZ2dlciYgbG9nZ2VyID0gbnQ6OkxvZ2dlcjo6R2V0SW5zdGFuY2UoKTsgICAgICAgICAgICAgXAorICAgIGlmIChsb2dnZXIubWluX2xldmVsKCkgPD0gbGV2ZWwgJiYgbG9nZ2VyLkhhc0xvZ2dlcigpKSB7ICAgIFwKKyAgICAgIHN0ZDo6b3N0cmluZ3N0cmVhbSBvc3M7ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgICAgICBvc3MgPDwgeDsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgICAgbG9nZ2VyLkxvZyhsZXZlbCwgX19GSUxFX18sIF9fTElORV9fLCBvc3Muc3RyKCkuY19zdHIoKSk7IFwKKyAgICB9ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgIH0gd2hpbGUgKDApCisKKyN1bmRlZiBFUlJPUgorI2RlZmluZSBFUlJPUih4KSBMT0coTlRfTE9HX0VSUk9SLCB4KQorI2RlZmluZSBXQVJOSU5HKHgpIExPRyhOVF9MT0dfV0FSTklORywgeCkKKyNkZWZpbmUgSU5GTyh4KSBMT0coTlRfTE9HX0lORk8sIHgpCisKKyNpZmRlZiBOREVCVUcKKyNkZWZpbmUgREVCVUcoeCkgZG8ge30gd2hpbGUgKDApCisjZGVmaW5lIERFQlVHMSh4KSBkbyB7fSB3aGlsZSAoMCkKKyNkZWZpbmUgREVCVUcyKHgpIGRvIHt9IHdoaWxlICgwKQorI2RlZmluZSBERUJVRzMoeCkgZG8ge30gd2hpbGUgKDApCisjZGVmaW5lIERFQlVHNCh4KSBkbyB7fSB3aGlsZSAoMCkKKyNlbHNlCisjZGVmaW5lIERFQlVHKHgpIExPRyhOVF9MT0dfREVCVUcsIHgpCisjZGVmaW5lIERFQlVHMSh4KSBMT0coTlRfTE9HX0RFQlVHMSwgeCkKKyNkZWZpbmUgREVCVUcyKHgpIExPRyhOVF9MT0dfREVCVUcyLCB4KQorI2RlZmluZSBERUJVRzMoeCkgTE9HKE5UX0xPR19ERUJVRzMsIHgpCisjZGVmaW5lIERFQlVHNCh4KSBMT0coTlRfTE9HX0RFQlVHNCwgeCkKKyNlbmRpZgorCit9IC8vIG5hbWVzcGFjZSBudAorCisjZW5kaWYgIC8vIE5UX0xPR19IXwpkaWZmIC0tZ2l0IGEvc3JjL01lc3NhZ2UuY3BwIGIvc3JjL01lc3NhZ2UuY3BwCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjE2MWQzMDMKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvTWVzc2FnZS5jcHAKQEAgLTAsMCArMSwzMDMgQEAKKy8qLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovCisvKiBDb3B5cmlnaHQgKGMpIEZJUlNUIDIwMTUuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqLworLyogT3BlbiBTb3VyY2UgU29mdHdhcmUgLSBtYXkgYmUgbW9kaWZpZWQgYW5kIHNoYXJlZCBieSBGUkMgdGVhbXMuIFRoZSBjb2RlICAgKi8KKy8qIG11c3QgYmUgYWNjb21wYW5pZWQgYnkgdGhlIEZJUlNUIEJTRCBsaWNlbnNlIGZpbGUgaW4gdGhlIHJvb3QgZGlyZWN0b3J5IG9mICovCisvKiB0aGUgcHJvamVjdC4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqLworLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi8KKworI2luY2x1ZGUgIk1lc3NhZ2UuaCIKKworI2luY2x1ZGUgIkxvZy5oIgorI2luY2x1ZGUgIldpcmVEZWNvZGVyLmgiCisjaW5jbHVkZSAiV2lyZUVuY29kZXIuaCIKKworI2RlZmluZSBrQ2xlYXJBbGxNYWdpYyAweEQwNkNCMjdBdWwKKwordXNpbmcgbmFtZXNwYWNlIG50OworCitzdGQ6OnNoYXJlZF9wdHI8TWVzc2FnZT4gTWVzc2FnZTo6UmVhZChXaXJlRGVjb2RlciYgZGVjb2RlciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEdldEVudHJ5VHlwZUZ1bmMgZ2V0X2VudHJ5X3R5cGUpIHsKKyAgdW5zaWduZWQgaW50IG1zZ190eXBlOworICBpZiAoIWRlY29kZXIuUmVhZDgoJm1zZ190eXBlKSkgcmV0dXJuIG51bGxwdHI7CisgIGF1dG8gbXNnID0KKyAgICAgIHN0ZDo6bWFrZV9zaGFyZWQ8TWVzc2FnZT4oc3RhdGljX2Nhc3Q8TXNnVHlwZT4obXNnX3R5cGUpLCBwcml2YXRlX2luaXQoKSk7CisgIHN3aXRjaCAobXNnX3R5cGUpIHsKKyAgICBjYXNlIGtLZWVwQWxpdmU6CisgICAgICBicmVhazsKKyAgICBjYXNlIGtDbGllbnRIZWxsbzogeworICAgICAgdW5zaWduZWQgaW50IHByb3RvX3JldjsKKyAgICAgIGlmICghZGVjb2Rlci5SZWFkMTYoJnByb3RvX3JldikpIHJldHVybiBudWxscHRyOworICAgICAgbXNnLT5tX2lkID0gcHJvdG9fcmV2OworICAgICAgLy8gVGhpcyBpbnRlbnRpb25hbGx5IHVzZXMgdGhlIHByb3ZpZGVkIHByb3RvX3JldiBpbnN0ZWFkIG9mCisgICAgICAvLyBkZWNvZGVyLnByb3RvX3JldigpLgorICAgICAgaWYgKHByb3RvX3JldiA+PSAweDAzMDB1KSB7CisgICAgICAgIGlmICghZGVjb2Rlci5SZWFkU3RyaW5nKCZtc2ctPm1fc3RyKSkgcmV0dXJuIG51bGxwdHI7CisgICAgICB9CisgICAgICBicmVhazsKKyAgICB9CisgICAgY2FzZSBrUHJvdG9VbnN1cDogeworICAgICAgaWYgKCFkZWNvZGVyLlJlYWQxNigmbXNnLT5tX2lkKSkgcmV0dXJuIG51bGxwdHI7ICAvLyBwcm90byByZXYKKyAgICAgIGJyZWFrOworICAgIH0KKyAgICBjYXNlIGtTZXJ2ZXJIZWxsb0RvbmU6CisgICAgICBpZiAoZGVjb2Rlci5wcm90b19yZXYoKSA8IDB4MDMwMHUpIHsKKyAgICAgICAgZGVjb2Rlci5zZXRfZXJyb3IoInJlY2VpdmVkIFNFUlZFUl9IRUxMT19ET05FIGluIHByb3RvY29sIDwgMy4wIik7CisgICAgICAgIHJldHVybiBudWxscHRyOworICAgICAgfQorICAgICAgYnJlYWs7CisgICAgY2FzZSBrU2VydmVySGVsbG86CisgICAgICBpZiAoZGVjb2Rlci5wcm90b19yZXYoKSA8IDB4MDMwMHUpIHsKKyAgICAgICAgZGVjb2Rlci5zZXRfZXJyb3IoInJlY2VpdmVkIFNFUlZFUl9IRUxMT19ET05FIGluIHByb3RvY29sIDwgMy4wIik7CisgICAgICAgIHJldHVybiBudWxscHRyOworICAgICAgfQorICAgICAgaWYgKCFkZWNvZGVyLlJlYWQ4KCZtc2ctPm1fZmxhZ3MpKSByZXR1cm4gbnVsbHB0cjsKKyAgICAgIGlmICghZGVjb2Rlci5SZWFkU3RyaW5nKCZtc2ctPm1fc3RyKSkgcmV0dXJuIG51bGxwdHI7CisgICAgICBicmVhazsKKyAgICBjYXNlIGtDbGllbnRIZWxsb0RvbmU6CisgICAgICBpZiAoZGVjb2Rlci5wcm90b19yZXYoKSA8IDB4MDMwMHUpIHsKKyAgICAgICAgZGVjb2Rlci5zZXRfZXJyb3IoInJlY2VpdmVkIENMSUVOVF9IRUxMT19ET05FIGluIHByb3RvY29sIDwgMy4wIik7CisgICAgICAgIHJldHVybiBudWxscHRyOworICAgICAgfQorICAgICAgYnJlYWs7CisgICAgY2FzZSBrRW50cnlBc3NpZ246IHsKKyAgICAgIGlmICghZGVjb2Rlci5SZWFkU3RyaW5nKCZtc2ctPm1fc3RyKSkgcmV0dXJuIG51bGxwdHI7CisgICAgICBOVF9UeXBlIHR5cGU7CisgICAgICBpZiAoIWRlY29kZXIuUmVhZFR5cGUoJnR5cGUpKSByZXR1cm4gbnVsbHB0cjsgIC8vIG5hbWUKKyAgICAgIGlmICghZGVjb2Rlci5SZWFkMTYoJm1zZy0+bV9pZCkpIHJldHVybiBudWxscHRyOyAgLy8gaWQKKyAgICAgIGlmICghZGVjb2Rlci5SZWFkMTYoJm1zZy0+bV9zZXFfbnVtX3VpZCkpIHJldHVybiBudWxscHRyOyAgLy8gc2VxIG51bQorICAgICAgaWYgKGRlY29kZXIucHJvdG9fcmV2KCkgPj0gMHgwMzAwdSkgeworICAgICAgICBpZiAoIWRlY29kZXIuUmVhZDgoJm1zZy0+bV9mbGFncykpIHJldHVybiBudWxscHRyOyAgLy8gZmxhZ3MKKyAgICAgIH0KKyAgICAgIG1zZy0+bV92YWx1ZSA9IGRlY29kZXIuUmVhZFZhbHVlKHR5cGUpOworICAgICAgaWYgKCFtc2ctPm1fdmFsdWUpIHJldHVybiBudWxscHRyOworICAgICAgYnJlYWs7CisgICAgfQorICAgIGNhc2Uga0VudHJ5VXBkYXRlOiB7CisgICAgICBpZiAoIWRlY29kZXIuUmVhZDE2KCZtc2ctPm1faWQpKSByZXR1cm4gbnVsbHB0cjsgIC8vIGlkCisgICAgICBpZiAoIWRlY29kZXIuUmVhZDE2KCZtc2ctPm1fc2VxX251bV91aWQpKSByZXR1cm4gbnVsbHB0cjsgIC8vIHNlcSBudW0KKyAgICAgIE5UX1R5cGUgdHlwZTsKKyAgICAgIGlmIChkZWNvZGVyLnByb3RvX3JldigpID49IDB4MDMwMHUpIHsKKyAgICAgICAgaWYgKCFkZWNvZGVyLlJlYWRUeXBlKCZ0eXBlKSkgcmV0dXJuIG51bGxwdHI7CisgICAgICB9IGVsc2UgeworICAgICAgICB0eXBlID0gZ2V0X2VudHJ5X3R5cGUobXNnLT5tX2lkKTsKKyAgICAgIH0KKyAgICAgIERFQlVHNCgidXBkYXRlIG1lc3NhZ2UgZGF0YSB0eXBlOiAiIDw8IHR5cGUpOworICAgICAgbXNnLT5tX3ZhbHVlID0gZGVjb2Rlci5SZWFkVmFsdWUodHlwZSk7CisgICAgICBpZiAoIW1zZy0+bV92YWx1ZSkgcmV0dXJuIG51bGxwdHI7CisgICAgICBicmVhazsKKyAgICB9CisgICAgY2FzZSBrRmxhZ3NVcGRhdGU6IHsKKyAgICAgIGlmIChkZWNvZGVyLnByb3RvX3JldigpIDwgMHgwMzAwdSkgeworICAgICAgICBkZWNvZGVyLnNldF9lcnJvcigicmVjZWl2ZWQgRkxBR1NfVVBEQVRFIGluIHByb3RvY29sIDwgMy4wIik7CisgICAgICAgIHJldHVybiBudWxscHRyOworICAgICAgfQorICAgICAgaWYgKCFkZWNvZGVyLlJlYWQxNigmbXNnLT5tX2lkKSkgcmV0dXJuIG51bGxwdHI7CisgICAgICBpZiAoIWRlY29kZXIuUmVhZDgoJm1zZy0+bV9mbGFncykpIHJldHVybiBudWxscHRyOworICAgICAgYnJlYWs7CisgICAgfQorICAgIGNhc2Uga0VudHJ5RGVsZXRlOiB7CisgICAgICBpZiAoZGVjb2Rlci5wcm90b19yZXYoKSA8IDB4MDMwMHUpIHsKKyAgICAgICAgZGVjb2Rlci5zZXRfZXJyb3IoInJlY2VpdmVkIEVOVFJZX0RFTEVURSBpbiBwcm90b2NvbCA8IDMuMCIpOworICAgICAgICByZXR1cm4gbnVsbHB0cjsKKyAgICAgIH0KKyAgICAgIGlmICghZGVjb2Rlci5SZWFkMTYoJm1zZy0+bV9pZCkpIHJldHVybiBudWxscHRyOworICAgICAgYnJlYWs7CisgICAgfQorICAgIGNhc2Uga0NsZWFyRW50cmllczogeworICAgICAgaWYgKGRlY29kZXIucHJvdG9fcmV2KCkgPCAweDAzMDB1KSB7CisgICAgICAgIGRlY29kZXIuc2V0X2Vycm9yKCJyZWNlaXZlZCBDTEVBUl9FTlRSSUVTIGluIHByb3RvY29sIDwgMy4wIik7CisgICAgICAgIHJldHVybiBudWxscHRyOworICAgICAgfQorICAgICAgdW5zaWduZWQgbG9uZyBtYWdpYzsKKyAgICAgIGlmICghZGVjb2Rlci5SZWFkMzIoJm1hZ2ljKSkgcmV0dXJuIG51bGxwdHI7CisgICAgICBpZiAobWFnaWMgIT0ga0NsZWFyQWxsTWFnaWMpIHsKKyAgICAgICAgZGVjb2Rlci5zZXRfZXJyb3IoCisgICAgICAgICAgICAicmVjZWl2ZWQgaW5jb3JyZWN0IENMRUFSX0VOVFJJRVMgbWFnaWMgdmFsdWUsIGlnbm9yaW5nIik7CisgICAgICAgIHJldHVybiBudWxscHRyOworICAgICAgfQorICAgICAgYnJlYWs7CisgICAgfQorICAgIGNhc2Uga0V4ZWN1dGVScGM6IHsKKyAgICAgIGlmIChkZWNvZGVyLnByb3RvX3JldigpIDwgMHgwMzAwdSkgeworICAgICAgICBkZWNvZGVyLnNldF9lcnJvcigicmVjZWl2ZWQgRVhFQ1VURV9SUEMgaW4gcHJvdG9jb2wgPCAzLjAiKTsKKyAgICAgICAgcmV0dXJuIG51bGxwdHI7CisgICAgICB9CisgICAgICBpZiAoIWRlY29kZXIuUmVhZDE2KCZtc2ctPm1faWQpKSByZXR1cm4gbnVsbHB0cjsKKyAgICAgIGlmICghZGVjb2Rlci5SZWFkMTYoJm1zZy0+bV9zZXFfbnVtX3VpZCkpIHJldHVybiBudWxscHRyOyAgLy8gdWlkCisgICAgICB1bnNpZ25lZCBsb25nIHNpemU7CisgICAgICBpZiAoIWRlY29kZXIuUmVhZFVsZWIxMjgoJnNpemUpKSByZXR1cm4gbnVsbHB0cjsKKyAgICAgIGNvbnN0IGNoYXIqIHBhcmFtczsKKyAgICAgIGlmICghZGVjb2Rlci5SZWFkKCZwYXJhbXMsIHNpemUpKSByZXR1cm4gbnVsbHB0cjsKKyAgICAgIG1zZy0+bV9zdHIgPSBsbHZtOjpTdHJpbmdSZWYocGFyYW1zLCBzaXplKTsKKyAgICAgIGJyZWFrOworICAgIH0KKyAgICBjYXNlIGtScGNSZXNwb25zZTogeworICAgICAgaWYgKGRlY29kZXIucHJvdG9fcmV2KCkgPCAweDAzMDB1KSB7CisgICAgICAgIGRlY29kZXIuc2V0X2Vycm9yKCJyZWNlaXZlZCBSUENfUkVTUE9OU0UgaW4gcHJvdG9jb2wgPCAzLjAiKTsKKyAgICAgICAgcmV0dXJuIG51bGxwdHI7CisgICAgICB9CisgICAgICBpZiAoIWRlY29kZXIuUmVhZDE2KCZtc2ctPm1faWQpKSByZXR1cm4gbnVsbHB0cjsKKyAgICAgIGlmICghZGVjb2Rlci5SZWFkMTYoJm1zZy0+bV9zZXFfbnVtX3VpZCkpIHJldHVybiBudWxscHRyOyAgLy8gdWlkCisgICAgICB1bnNpZ25lZCBsb25nIHNpemU7CisgICAgICBpZiAoIWRlY29kZXIuUmVhZFVsZWIxMjgoJnNpemUpKSByZXR1cm4gbnVsbHB0cjsKKyAgICAgIGNvbnN0IGNoYXIqIHJlc3VsdHM7CisgICAgICBpZiAoIWRlY29kZXIuUmVhZCgmcmVzdWx0cywgc2l6ZSkpIHJldHVybiBudWxscHRyOworICAgICAgbXNnLT5tX3N0ciA9IGxsdm06OlN0cmluZ1JlZihyZXN1bHRzLCBzaXplKTsKKyAgICAgIGJyZWFrOworICAgIH0KKyAgICBkZWZhdWx0OgorICAgICAgZGVjb2Rlci5zZXRfZXJyb3IoInVucmVjb2duaXplZCBtZXNzYWdlIHR5cGUiKTsKKyAgICAgIElORk8oInVucmVjb2duaXplZCBtZXNzYWdlIHR5cGU6ICIgPDwgbXNnX3R5cGUpOworICAgICAgcmV0dXJuIG51bGxwdHI7CisgIH0KKyAgcmV0dXJuIG1zZzsKK30KKworc3RkOjpzaGFyZWRfcHRyPE1lc3NhZ2U+IE1lc3NhZ2U6OkNsaWVudEhlbGxvKGxsdm06OlN0cmluZ1JlZiBzZWxmX2lkKSB7CisgIGF1dG8gbXNnID0gc3RkOjptYWtlX3NoYXJlZDxNZXNzYWdlPihrQ2xpZW50SGVsbG8sIHByaXZhdGVfaW5pdCgpKTsKKyAgbXNnLT5tX3N0ciA9IHNlbGZfaWQ7CisgIHJldHVybiBtc2c7Cit9CisKK3N0ZDo6c2hhcmVkX3B0cjxNZXNzYWdlPiBNZXNzYWdlOjpTZXJ2ZXJIZWxsbyh1bnNpZ25lZCBpbnQgZmxhZ3MsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGx2bTo6U3RyaW5nUmVmIHNlbGZfaWQpIHsKKyAgYXV0byBtc2cgPSBzdGQ6Om1ha2Vfc2hhcmVkPE1lc3NhZ2U+KGtTZXJ2ZXJIZWxsbywgcHJpdmF0ZV9pbml0KCkpOworICBtc2ctPm1fc3RyID0gc2VsZl9pZDsKKyAgbXNnLT5tX2ZsYWdzID0gZmxhZ3M7CisgIHJldHVybiBtc2c7Cit9CisKK3N0ZDo6c2hhcmVkX3B0cjxNZXNzYWdlPiBNZXNzYWdlOjpFbnRyeUFzc2lnbihsbHZtOjpTdHJpbmdSZWYgbmFtZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB1bnNpZ25lZCBpbnQgaWQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdW5zaWduZWQgaW50IHNlcV9udW0sCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RkOjpzaGFyZWRfcHRyPFZhbHVlPiB2YWx1ZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB1bnNpZ25lZCBpbnQgZmxhZ3MpIHsKKyAgYXV0byBtc2cgPSBzdGQ6Om1ha2Vfc2hhcmVkPE1lc3NhZ2U+KGtFbnRyeUFzc2lnbiwgcHJpdmF0ZV9pbml0KCkpOworICBtc2ctPm1fc3RyID0gbmFtZTsKKyAgbXNnLT5tX3ZhbHVlID0gdmFsdWU7CisgIG1zZy0+bV9pZCA9IGlkOworICBtc2ctPm1fZmxhZ3MgPSBmbGFnczsKKyAgbXNnLT5tX3NlcV9udW1fdWlkID0gc2VxX251bTsKKyAgcmV0dXJuIG1zZzsKK30KKworc3RkOjpzaGFyZWRfcHRyPE1lc3NhZ2U+IE1lc3NhZ2U6OkVudHJ5VXBkYXRlKHVuc2lnbmVkIGludCBpZCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB1bnNpZ25lZCBpbnQgc2VxX251bSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdGQ6OnNoYXJlZF9wdHI8VmFsdWU+IHZhbHVlKSB7CisgIGF1dG8gbXNnID0gc3RkOjptYWtlX3NoYXJlZDxNZXNzYWdlPihrRW50cnlVcGRhdGUsIHByaXZhdGVfaW5pdCgpKTsKKyAgbXNnLT5tX3ZhbHVlID0gdmFsdWU7CisgIG1zZy0+bV9pZCA9IGlkOworICBtc2ctPm1fc2VxX251bV91aWQgPSBzZXFfbnVtOworICByZXR1cm4gbXNnOworfQorCitzdGQ6OnNoYXJlZF9wdHI8TWVzc2FnZT4gTWVzc2FnZTo6RmxhZ3NVcGRhdGUodW5zaWduZWQgaW50IGlkLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVuc2lnbmVkIGludCBmbGFncykgeworICBhdXRvIG1zZyA9IHN0ZDo6bWFrZV9zaGFyZWQ8TWVzc2FnZT4oa0ZsYWdzVXBkYXRlLCBwcml2YXRlX2luaXQoKSk7CisgIG1zZy0+bV9pZCA9IGlkOworICBtc2ctPm1fZmxhZ3MgPSBmbGFnczsKKyAgcmV0dXJuIG1zZzsKK30KKworc3RkOjpzaGFyZWRfcHRyPE1lc3NhZ2U+IE1lc3NhZ2U6OkVudHJ5RGVsZXRlKHVuc2lnbmVkIGludCBpZCkgeworICBhdXRvIG1zZyA9IHN0ZDo6bWFrZV9zaGFyZWQ8TWVzc2FnZT4oa0VudHJ5RGVsZXRlLCBwcml2YXRlX2luaXQoKSk7CisgIG1zZy0+bV9pZCA9IGlkOworICByZXR1cm4gbXNnOworfQorCitzdGQ6OnNoYXJlZF9wdHI8TWVzc2FnZT4gTWVzc2FnZTo6RXhlY3V0ZVJwYyh1bnNpZ25lZCBpbnQgaWQsIHVuc2lnbmVkIGludCB1aWQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsbHZtOjpTdHJpbmdSZWYgcGFyYW1zKSB7CisgIGF1dG8gbXNnID0gc3RkOjptYWtlX3NoYXJlZDxNZXNzYWdlPihrRXhlY3V0ZVJwYywgcHJpdmF0ZV9pbml0KCkpOworICBtc2ctPm1fc3RyID0gcGFyYW1zOworICBtc2ctPm1faWQgPSBpZDsKKyAgbXNnLT5tX3NlcV9udW1fdWlkID0gdWlkOworICByZXR1cm4gbXNnOworfQorCitzdGQ6OnNoYXJlZF9wdHI8TWVzc2FnZT4gTWVzc2FnZTo6UnBjUmVzcG9uc2UodW5zaWduZWQgaW50IGlkLCB1bnNpZ25lZCBpbnQgdWlkLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxsdm06OlN0cmluZ1JlZiByZXN1bHRzKSB7CisgIGF1dG8gbXNnID0gc3RkOjptYWtlX3NoYXJlZDxNZXNzYWdlPihrUnBjUmVzcG9uc2UsIHByaXZhdGVfaW5pdCgpKTsKKyAgbXNnLT5tX3N0ciA9IHJlc3VsdHM7CisgIG1zZy0+bV9pZCA9IGlkOworICBtc2ctPm1fc2VxX251bV91aWQgPSB1aWQ7CisgIHJldHVybiBtc2c7Cit9CisKK3ZvaWQgTWVzc2FnZTo6V3JpdGUoV2lyZUVuY29kZXImIGVuY29kZXIpIGNvbnN0IHsKKyAgc3dpdGNoIChtX3R5cGUpIHsKKyAgICBjYXNlIGtLZWVwQWxpdmU6CisgICAgICBlbmNvZGVyLldyaXRlOChrS2VlcEFsaXZlKTsKKyAgICAgIGJyZWFrOworICAgIGNhc2Uga0NsaWVudEhlbGxvOgorICAgICAgZW5jb2Rlci5Xcml0ZTgoa0NsaWVudEhlbGxvKTsKKyAgICAgIGVuY29kZXIuV3JpdGUxNihlbmNvZGVyLnByb3RvX3JldigpKTsKKyAgICAgIGlmIChlbmNvZGVyLnByb3RvX3JldigpIDwgMHgwMzAwdSkgcmV0dXJuOworICAgICAgZW5jb2Rlci5Xcml0ZVN0cmluZyhtX3N0cik7CisgICAgICBicmVhazsKKyAgICBjYXNlIGtQcm90b1Vuc3VwOgorICAgICAgZW5jb2Rlci5Xcml0ZTgoa1Byb3RvVW5zdXApOworICAgICAgZW5jb2Rlci5Xcml0ZTE2KGVuY29kZXIucHJvdG9fcmV2KCkpOworICAgICAgYnJlYWs7CisgICAgY2FzZSBrU2VydmVySGVsbG9Eb25lOgorICAgICAgZW5jb2Rlci5Xcml0ZTgoa1NlcnZlckhlbGxvRG9uZSk7CisgICAgICBicmVhazsKKyAgICBjYXNlIGtTZXJ2ZXJIZWxsbzoKKyAgICAgIGlmIChlbmNvZGVyLnByb3RvX3JldigpIDwgMHgwMzAwdSkgcmV0dXJuOyAgLy8gbmV3IG1lc3NhZ2UgaW4gdmVyc2lvbiAzLjAKKyAgICAgIGVuY29kZXIuV3JpdGU4KGtTZXJ2ZXJIZWxsbyk7CisgICAgICBlbmNvZGVyLldyaXRlOChtX2ZsYWdzKTsKKyAgICAgIGVuY29kZXIuV3JpdGVTdHJpbmcobV9zdHIpOworICAgICAgYnJlYWs7CisgICAgY2FzZSBrQ2xpZW50SGVsbG9Eb25lOgorICAgICAgaWYgKGVuY29kZXIucHJvdG9fcmV2KCkgPCAweDAzMDB1KSByZXR1cm47ICAvLyBuZXcgbWVzc2FnZSBpbiB2ZXJzaW9uIDMuMAorICAgICAgZW5jb2Rlci5Xcml0ZTgoa0NsaWVudEhlbGxvRG9uZSk7CisgICAgICBicmVhazsKKyAgICBjYXNlIGtFbnRyeUFzc2lnbjoKKyAgICAgIGVuY29kZXIuV3JpdGU4KGtFbnRyeUFzc2lnbik7CisgICAgICBlbmNvZGVyLldyaXRlU3RyaW5nKG1fc3RyKTsKKyAgICAgIGVuY29kZXIuV3JpdGVUeXBlKG1fdmFsdWUtPnR5cGUoKSk7CisgICAgICBlbmNvZGVyLldyaXRlMTYobV9pZCk7CisgICAgICBlbmNvZGVyLldyaXRlMTYobV9zZXFfbnVtX3VpZCk7CisgICAgICBpZiAoZW5jb2Rlci5wcm90b19yZXYoKSA+PSAweDAzMDB1KSBlbmNvZGVyLldyaXRlOChtX2ZsYWdzKTsKKyAgICAgIGVuY29kZXIuV3JpdGVWYWx1ZSgqbV92YWx1ZSk7CisgICAgICBicmVhazsKKyAgICBjYXNlIGtFbnRyeVVwZGF0ZToKKyAgICAgIGVuY29kZXIuV3JpdGU4KGtFbnRyeVVwZGF0ZSk7CisgICAgICBlbmNvZGVyLldyaXRlMTYobV9pZCk7CisgICAgICBlbmNvZGVyLldyaXRlMTYobV9zZXFfbnVtX3VpZCk7CisgICAgICBpZiAoZW5jb2Rlci5wcm90b19yZXYoKSA+PSAweDAzMDB1KSBlbmNvZGVyLldyaXRlVHlwZShtX3ZhbHVlLT50eXBlKCkpOworICAgICAgZW5jb2Rlci5Xcml0ZVZhbHVlKCptX3ZhbHVlKTsKKyAgICAgIGJyZWFrOworICAgIGNhc2Uga0ZsYWdzVXBkYXRlOgorICAgICAgaWYgKGVuY29kZXIucHJvdG9fcmV2KCkgPCAweDAzMDB1KSByZXR1cm47ICAvLyBuZXcgbWVzc2FnZSBpbiB2ZXJzaW9uIDMuMAorICAgICAgZW5jb2Rlci5Xcml0ZTgoa0ZsYWdzVXBkYXRlKTsKKyAgICAgIGVuY29kZXIuV3JpdGUxNihtX2lkKTsKKyAgICAgIGVuY29kZXIuV3JpdGU4KG1fZmxhZ3MpOworICAgICAgYnJlYWs7CisgICAgY2FzZSBrRW50cnlEZWxldGU6CisgICAgICBpZiAoZW5jb2Rlci5wcm90b19yZXYoKSA8IDB4MDMwMHUpIHJldHVybjsgIC8vIG5ldyBtZXNzYWdlIGluIHZlcnNpb24gMy4wCisgICAgICBlbmNvZGVyLldyaXRlOChrRW50cnlEZWxldGUpOworICAgICAgZW5jb2Rlci5Xcml0ZTE2KG1faWQpOworICAgICAgYnJlYWs7CisgICAgY2FzZSBrQ2xlYXJFbnRyaWVzOgorICAgICAgaWYgKGVuY29kZXIucHJvdG9fcmV2KCkgPCAweDAzMDB1KSByZXR1cm47ICAvLyBuZXcgbWVzc2FnZSBpbiB2ZXJzaW9uIDMuMAorICAgICAgZW5jb2Rlci5Xcml0ZTgoa0NsZWFyRW50cmllcyk7CisgICAgICBlbmNvZGVyLldyaXRlMzIoa0NsZWFyQWxsTWFnaWMpOworICAgICAgYnJlYWs7CisgICAgY2FzZSBrRXhlY3V0ZVJwYzoKKyAgICAgIGlmIChlbmNvZGVyLnByb3RvX3JldigpIDwgMHgwMzAwdSkgcmV0dXJuOyAgLy8gbmV3IG1lc3NhZ2UgaW4gdmVyc2lvbiAzLjAKKyAgICAgIGVuY29kZXIuV3JpdGU4KGtFeGVjdXRlUnBjKTsKKyAgICAgIGVuY29kZXIuV3JpdGUxNihtX2lkKTsKKyAgICAgIGVuY29kZXIuV3JpdGUxNihtX3NlcV9udW1fdWlkKTsKKyAgICAgIGVuY29kZXIuV3JpdGVTdHJpbmcobV9zdHIpOworICAgICAgYnJlYWs7CisgICAgY2FzZSBrUnBjUmVzcG9uc2U6CisgICAgICBpZiAoZW5jb2Rlci5wcm90b19yZXYoKSA8IDB4MDMwMHUpIHJldHVybjsgIC8vIG5ldyBtZXNzYWdlIGluIHZlcnNpb24gMy4wCisgICAgICBlbmNvZGVyLldyaXRlOChrUnBjUmVzcG9uc2UpOworICAgICAgZW5jb2Rlci5Xcml0ZTE2KG1faWQpOworICAgICAgZW5jb2Rlci5Xcml0ZTE2KG1fc2VxX251bV91aWQpOworICAgICAgZW5jb2Rlci5Xcml0ZVN0cmluZyhtX3N0cik7CisgICAgICBicmVhazsKKyAgICBkZWZhdWx0OgorICAgICAgYnJlYWs7CisgIH0KK30KZGlmZiAtLWdpdCBhL3NyYy9NZXNzYWdlLmggYi9zcmMvTWVzc2FnZS5oCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjMwNDc4MzQKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvTWVzc2FnZS5oCkBAIC0wLDAgKzEsMTE3IEBACisvKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qLworLyogQ29weXJpZ2h0IChjKSBGSVJTVCAyMDE1LiBBbGwgUmlnaHRzIFJlc2VydmVkLiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKi8KKy8qIE9wZW4gU291cmNlIFNvZnR3YXJlIC0gbWF5IGJlIG1vZGlmaWVkIGFuZCBzaGFyZWQgYnkgRlJDIHRlYW1zLiBUaGUgY29kZSAgICovCisvKiBtdXN0IGJlIGFjY29tcGFuaWVkIGJ5IHRoZSBGSVJTVCBCU0QgbGljZW5zZSBmaWxlIGluIHRoZSByb290IGRpcmVjdG9yeSBvZiAqLworLyogdGhlIHByb2plY3QuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKi8KKy8qLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovCisKKyNpZm5kZWYgTlRfTUVTU0FHRV9IXworI2RlZmluZSBOVF9NRVNTQUdFX0hfCisKKyNpbmNsdWRlIDxmdW5jdGlvbmFsPgorI2luY2x1ZGUgPG1lbW9yeT4KKyNpbmNsdWRlIDxzdHJpbmc+CisKKyNpbmNsdWRlICJudF9WYWx1ZS5oIgorCituYW1lc3BhY2UgbnQgeworCitjbGFzcyBXaXJlRGVjb2RlcjsKK2NsYXNzIFdpcmVFbmNvZGVyOworCitjbGFzcyBNZXNzYWdlIHsKKyAgc3RydWN0IHByaXZhdGVfaW5pdCB7fTsKKworIHB1YmxpYzoKKyAgZW51bSBNc2dUeXBlIHsKKyAgICBrVW5rbm93biA9IC0xLAorICAgIGtLZWVwQWxpdmUgPSAweDAwLAorICAgIGtDbGllbnRIZWxsbyA9IDB4MDEsCisgICAga1Byb3RvVW5zdXAgPSAweDAyLAorICAgIGtTZXJ2ZXJIZWxsb0RvbmUgPSAweDAzLAorICAgIGtTZXJ2ZXJIZWxsbyA9IDB4MDQsCisgICAga0NsaWVudEhlbGxvRG9uZSA9IDB4MDUsCisgICAga0VudHJ5QXNzaWduID0gMHgxMCwKKyAgICBrRW50cnlVcGRhdGUgPSAweDExLAorICAgIGtGbGFnc1VwZGF0ZSA9IDB4MTIsCisgICAga0VudHJ5RGVsZXRlID0gMHgxMywKKyAgICBrQ2xlYXJFbnRyaWVzID0gMHgxNCwKKyAgICBrRXhlY3V0ZVJwYyA9IDB4MjAsCisgICAga1JwY1Jlc3BvbnNlID0gMHgyMQorICB9OworICB0eXBlZGVmIHN0ZDo6ZnVuY3Rpb248TlRfVHlwZSh1bnNpZ25lZCBpbnQgaWQpPiBHZXRFbnRyeVR5cGVGdW5jOworCisgIE1lc3NhZ2UoKSA6IG1fdHlwZShrVW5rbm93biksIG1faWQoMCksIG1fZmxhZ3MoMCksIG1fc2VxX251bV91aWQoMCkge30KKyAgTWVzc2FnZShNc2dUeXBlIHR5cGUsIGNvbnN0IHByaXZhdGVfaW5pdCYpCisgICAgICA6IG1fdHlwZSh0eXBlKSwgbV9pZCgwKSwgbV9mbGFncygwKSwgbV9zZXFfbnVtX3VpZCgwKSB7fQorCisgIE1zZ1R5cGUgdHlwZSgpIGNvbnN0IHsgcmV0dXJuIG1fdHlwZTsgfQorICBib29sIElzKE1zZ1R5cGUgdHlwZSkgY29uc3QgeyByZXR1cm4gdHlwZSA9PSBtX3R5cGU7IH0KKworICAvLyBNZXNzYWdlIGRhdGEgYWNjZXNzb3JzLiAgQ2FsbGVycyBhcmUgcmVzcG9uc2libGUgZm9yIGtub3dpbmcgd2hhdCBkYXRhIGlzCisgIC8vIGFjdHVhbGx5IHByb3ZpZGVkIGZvciBhIHBhcnRpY3VsYXIgbWVzc2FnZS4KKyAgbGx2bTo6U3RyaW5nUmVmIHN0cigpIGNvbnN0IHsgcmV0dXJuIG1fc3RyOyB9CisgIHN0ZDo6c2hhcmVkX3B0cjxWYWx1ZT4gdmFsdWUoKSBjb25zdCB7IHJldHVybiBtX3ZhbHVlOyB9CisgIHVuc2lnbmVkIGludCBpZCgpIGNvbnN0IHsgcmV0dXJuIG1faWQ7IH0KKyAgdW5zaWduZWQgaW50IGZsYWdzKCkgY29uc3QgeyByZXR1cm4gbV9mbGFnczsgfQorICB1bnNpZ25lZCBpbnQgc2VxX251bV91aWQoKSBjb25zdCB7IHJldHVybiBtX3NlcV9udW1fdWlkOyB9CisKKyAgLy8gUmVhZCBhbmQgd3JpdGUgZnJvbSB3aXJlIHJlcHJlc2VudGF0aW9uCisgIHZvaWQgV3JpdGUoV2lyZUVuY29kZXImIGVuY29kZXIpIGNvbnN0OworICBzdGF0aWMgc3RkOjpzaGFyZWRfcHRyPE1lc3NhZ2U+IFJlYWQoV2lyZURlY29kZXImIGRlY29kZXIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBHZXRFbnRyeVR5cGVGdW5jIGdldF9lbnRyeV90eXBlKTsKKworICAvLyBDcmVhdGUgbWVzc2FnZXMgd2l0aG91dCBkYXRhCisgIHN0YXRpYyBzdGQ6OnNoYXJlZF9wdHI8TWVzc2FnZT4gS2VlcEFsaXZlKCkgeworICAgIHJldHVybiBzdGQ6Om1ha2Vfc2hhcmVkPE1lc3NhZ2U+KGtLZWVwQWxpdmUsIHByaXZhdGVfaW5pdCgpKTsKKyAgfQorICBzdGF0aWMgc3RkOjpzaGFyZWRfcHRyPE1lc3NhZ2U+IFByb3RvVW5zdXAoKSB7CisgICAgcmV0dXJuIHN0ZDo6bWFrZV9zaGFyZWQ8TWVzc2FnZT4oa1Byb3RvVW5zdXAsIHByaXZhdGVfaW5pdCgpKTsKKyAgfQorICBzdGF0aWMgc3RkOjpzaGFyZWRfcHRyPE1lc3NhZ2U+IFNlcnZlckhlbGxvRG9uZSgpIHsKKyAgICByZXR1cm4gc3RkOjptYWtlX3NoYXJlZDxNZXNzYWdlPihrU2VydmVySGVsbG9Eb25lLCBwcml2YXRlX2luaXQoKSk7CisgIH0KKyAgc3RhdGljIHN0ZDo6c2hhcmVkX3B0cjxNZXNzYWdlPiBDbGllbnRIZWxsb0RvbmUoKSB7CisgICAgcmV0dXJuIHN0ZDo6bWFrZV9zaGFyZWQ8TWVzc2FnZT4oa0NsaWVudEhlbGxvRG9uZSwgcHJpdmF0ZV9pbml0KCkpOworICB9CisgIHN0YXRpYyBzdGQ6OnNoYXJlZF9wdHI8TWVzc2FnZT4gQ2xlYXJFbnRyaWVzKCkgeworICAgIHJldHVybiBzdGQ6Om1ha2Vfc2hhcmVkPE1lc3NhZ2U+KGtDbGVhckVudHJpZXMsIHByaXZhdGVfaW5pdCgpKTsKKyAgfQorCisgIC8vIENyZWF0ZSBtZXNzYWdlcyB3aXRoIGRhdGEKKyAgc3RhdGljIHN0ZDo6c2hhcmVkX3B0cjxNZXNzYWdlPiBDbGllbnRIZWxsbyhsbHZtOjpTdHJpbmdSZWYgc2VsZl9pZCk7CisgIHN0YXRpYyBzdGQ6OnNoYXJlZF9wdHI8TWVzc2FnZT4gU2VydmVySGVsbG8odW5zaWduZWQgaW50IGZsYWdzLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxsdm06OlN0cmluZ1JlZiBzZWxmX2lkKTsKKyAgc3RhdGljIHN0ZDo6c2hhcmVkX3B0cjxNZXNzYWdlPiBFbnRyeUFzc2lnbihsbHZtOjpTdHJpbmdSZWYgbmFtZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB1bnNpZ25lZCBpbnQgaWQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdW5zaWduZWQgaW50IHNlcV9udW0sCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RkOjpzaGFyZWRfcHRyPFZhbHVlPiB2YWx1ZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB1bnNpZ25lZCBpbnQgZmxhZ3MpOworICBzdGF0aWMgc3RkOjpzaGFyZWRfcHRyPE1lc3NhZ2U+IEVudHJ5VXBkYXRlKHVuc2lnbmVkIGludCBpZCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB1bnNpZ25lZCBpbnQgc2VxX251bSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdGQ6OnNoYXJlZF9wdHI8VmFsdWU+IHZhbHVlKTsKKyAgc3RhdGljIHN0ZDo6c2hhcmVkX3B0cjxNZXNzYWdlPiBGbGFnc1VwZGF0ZSh1bnNpZ25lZCBpbnQgaWQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdW5zaWduZWQgaW50IGZsYWdzKTsKKyAgc3RhdGljIHN0ZDo6c2hhcmVkX3B0cjxNZXNzYWdlPiBFbnRyeURlbGV0ZSh1bnNpZ25lZCBpbnQgaWQpOworICBzdGF0aWMgc3RkOjpzaGFyZWRfcHRyPE1lc3NhZ2U+IEV4ZWN1dGVScGModW5zaWduZWQgaW50IGlkLCB1bnNpZ25lZCBpbnQgdWlkLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGx2bTo6U3RyaW5nUmVmIHBhcmFtcyk7CisgIHN0YXRpYyBzdGQ6OnNoYXJlZF9wdHI8TWVzc2FnZT4gUnBjUmVzcG9uc2UodW5zaWduZWQgaW50IGlkLCB1bnNpZ25lZCBpbnQgdWlkLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxsdm06OlN0cmluZ1JlZiByZXN1bHRzKTsKKworICBNZXNzYWdlKGNvbnN0IE1lc3NhZ2UmKSA9IGRlbGV0ZTsKKyAgTWVzc2FnZSYgb3BlcmF0b3I9KGNvbnN0IE1lc3NhZ2UmKSA9IGRlbGV0ZTsKKworIHByaXZhdGU6CisgIE1zZ1R5cGUgbV90eXBlOworCisgIC8vIE1lc3NhZ2UgZGF0YS4gIFVzZSB2YXJpZXMgYnkgbWVzc2FnZSB0eXBlLgorICBzdGQ6OnN0cmluZyBtX3N0cjsKKyAgc3RkOjpzaGFyZWRfcHRyPFZhbHVlPiBtX3ZhbHVlOworICB1bnNpZ25lZCBpbnQgbV9pZDsgIC8vIGFsc28gdXNlZCBmb3IgcHJvdG9fcmV2CisgIHVuc2lnbmVkIGludCBtX2ZsYWdzOworICB1bnNpZ25lZCBpbnQgbV9zZXFfbnVtX3VpZDsKK307CisKK30gIC8vIG5hbWVzcGFjZSBudAorCisjZW5kaWYgIC8vIE5UX01FU1NBR0VfSF8KZGlmZiAtLWdpdCBhL3NyYy9OZXR3b3JrQ29ubmVjdGlvbi5jcHAgYi9zcmMvTmV0d29ya0Nvbm5lY3Rpb24uY3BwCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmIyYjc0MWUKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvTmV0d29ya0Nvbm5lY3Rpb24uY3BwCkBAIC0wLDAgKzEsMzExIEBACisvKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qLworLyogQ29weXJpZ2h0IChjKSBGSVJTVCAyMDE1LiBBbGwgUmlnaHRzIFJlc2VydmVkLiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKi8KKy8qIE9wZW4gU291cmNlIFNvZnR3YXJlIC0gbWF5IGJlIG1vZGlmaWVkIGFuZCBzaGFyZWQgYnkgRlJDIHRlYW1zLiBUaGUgY29kZSAgICovCisvKiBtdXN0IGJlIGFjY29tcGFuaWVkIGJ5IHRoZSBGSVJTVCBCU0QgbGljZW5zZSBmaWxlIGluIHRoZSByb290IGRpcmVjdG9yeSBvZiAqLworLyogdGhlIHByb2plY3QuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKi8KKy8qLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovCisKKyNpbmNsdWRlICJOZXR3b3JrQ29ubmVjdGlvbi5oIgorCisjaW5jbHVkZSAic3VwcG9ydC90aW1lc3RhbXAuaCIKKyNpbmNsdWRlICJ0Y3Bzb2NrZXRzL05ldHdvcmtTdHJlYW0uaCIKKyNpbmNsdWRlICJMb2cuaCIKKyNpbmNsdWRlICJOb3RpZmllci5oIgorI2luY2x1ZGUgInJhd19zb2NrZXRfaXN0cmVhbS5oIgorI2luY2x1ZGUgIldpcmVEZWNvZGVyLmgiCisjaW5jbHVkZSAiV2lyZUVuY29kZXIuaCIKKwordXNpbmcgbmFtZXNwYWNlIG50OworCitzdGQ6OmF0b21pY191aW50IE5ldHdvcmtDb25uZWN0aW9uOjpzX3VpZDsKKworTmV0d29ya0Nvbm5lY3Rpb246Ok5ldHdvcmtDb25uZWN0aW9uKHN0ZDo6dW5pcXVlX3B0cjxOZXR3b3JrU3RyZWFtPiBzdHJlYW0sCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTm90aWZpZXImIG5vdGlmaWVyLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEhhbmRzaGFrZUZ1bmMgaGFuZHNoYWtlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE1lc3NhZ2U6OkdldEVudHJ5VHlwZUZ1bmMgZ2V0X2VudHJ5X3R5cGUpCisgICAgOiBtX3VpZChzX3VpZC5mZXRjaF9hZGQoMSkpLAorICAgICAgbV9zdHJlYW0oc3RkOjptb3ZlKHN0cmVhbSkpLAorICAgICAgbV9ub3RpZmllcihub3RpZmllciksCisgICAgICBtX2hhbmRzaGFrZShoYW5kc2hha2UpLAorICAgICAgbV9nZXRfZW50cnlfdHlwZShnZXRfZW50cnlfdHlwZSkgeworICBtX2FjdGl2ZSA9IGZhbHNlOworICBtX3Byb3RvX3JldiA9IDB4MDMwMDsKKyAgbV9zdGF0ZSA9IHN0YXRpY19jYXN0PGludD4oa0NyZWF0ZWQpOworICBtX2xhc3RfdXBkYXRlID0gMDsKKworICAvLyB0dXJuIG9mZiBOYWdsZSBhbGdvcml0aG07IHdlIGJ1bmRsZSBwYWNrZXRzIGZvciB0cmFuc21pc3Npb24KKyAgbV9zdHJlYW0tPnNldE5vRGVsYXkoKTsKK30KKworTmV0d29ya0Nvbm5lY3Rpb246On5OZXR3b3JrQ29ubmVjdGlvbigpIHsgU3RvcCgpOyB9CisKK3ZvaWQgTmV0d29ya0Nvbm5lY3Rpb246OlN0YXJ0KCkgeworICBpZiAobV9hY3RpdmUpIHJldHVybjsKKyAgbV9hY3RpdmUgPSB0cnVlOworICBtX3N0YXRlID0gc3RhdGljX2Nhc3Q8aW50PihrSW5pdCk7CisgIC8vIGNsZWFyIHF1ZXVlCisgIHdoaWxlICghbV9vdXRnb2luZy5lbXB0eSgpKSBtX291dGdvaW5nLnBvcCgpOworICAvLyByZXNldCBzaHV0ZG93biBmbGFncworICB7CisgICAgc3RkOjpsb2NrX2d1YXJkPHN0ZDo6bXV0ZXg+IGxvY2sobV9zaHV0ZG93bl9tdXRleCk7CisgICAgbV9yZWFkX3NodXRkb3duID0gZmFsc2U7CisgICAgbV93cml0ZV9zaHV0ZG93biA9IGZhbHNlOworICB9CisgIC8vIHN0YXJ0IHRocmVhZHMKKyAgbV93cml0ZV90aHJlYWQgPSBzdGQ6OnRocmVhZCgmTmV0d29ya0Nvbm5lY3Rpb246OldyaXRlVGhyZWFkTWFpbiwgdGhpcyk7CisgIG1fcmVhZF90aHJlYWQgPSBzdGQ6OnRocmVhZCgmTmV0d29ya0Nvbm5lY3Rpb246OlJlYWRUaHJlYWRNYWluLCB0aGlzKTsKK30KKwordm9pZCBOZXR3b3JrQ29ubmVjdGlvbjo6U3RvcCgpIHsKKyAgREVCVUcyKCJOZXR3b3JrQ29ubmVjdGlvbiBzdG9wcGluZyAoIiA8PCB0aGlzIDw8ICIpIik7CisgIG1fc3RhdGUgPSBzdGF0aWNfY2FzdDxpbnQ+KGtEZWFkKTsKKyAgbV9hY3RpdmUgPSBmYWxzZTsKKyAgLy8gY2xvc2luZyB0aGUgc3RyZWFtIHNvIHRoZSByZWFkIHRocmVhZCB0ZXJtaW5hdGVzCisgIGlmIChtX3N0cmVhbSkgbV9zdHJlYW0tPmNsb3NlKCk7CisgIC8vIHNlbmQgYW4gZW1wdHkgb3V0Z29pbmcgbWVzc2FnZSBzZXQgc28gdGhlIHdyaXRlIHRocmVhZCB0ZXJtaW5hdGVzCisgIG1fb3V0Z29pbmcucHVzaChPdXRnb2luZygpKTsKKyAgLy8gd2FpdCBmb3IgdGhyZWFkcyB0byB0ZXJtaW5hdGUsIHdpdGggdGltZW91dAorICBpZiAobV93cml0ZV90aHJlYWQuam9pbmFibGUoKSkgeworICAgIHN0ZDo6dW5pcXVlX2xvY2s8c3RkOjptdXRleD4gbG9jayhtX3NodXRkb3duX211dGV4KTsKKyAgICBhdXRvIHRpbWVvdXRfdGltZSA9CisgICAgICAgIHN0ZDo6Y2hyb25vOjpzdGVhZHlfY2xvY2s6Om5vdygpICsgc3RkOjpjaHJvbm86Om1pbGxpc2Vjb25kcygyMDApOworICAgIGlmIChtX3dyaXRlX3NodXRkb3duX2N2LndhaXRfdW50aWwobG9jaywgdGltZW91dF90aW1lLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgWyZdIHsgcmV0dXJuIG1fd3JpdGVfc2h1dGRvd247IH0pKQorICAgICAgbV93cml0ZV90aHJlYWQuam9pbigpOworICAgIGVsc2UKKyAgICAgIG1fd3JpdGVfdGhyZWFkLmRldGFjaCgpOyAgLy8gdGltZWQgb3V0LCBkZXRhY2ggaXQKKyAgfQorICBpZiAobV9yZWFkX3RocmVhZC5qb2luYWJsZSgpKSB7CisgICAgc3RkOjp1bmlxdWVfbG9jazxzdGQ6Om11dGV4PiBsb2NrKG1fc2h1dGRvd25fbXV0ZXgpOworICAgIGF1dG8gdGltZW91dF90aW1lID0KKyAgICAgICAgc3RkOjpjaHJvbm86OnN0ZWFkeV9jbG9jazo6bm93KCkgKyBzdGQ6OmNocm9ubzo6bWlsbGlzZWNvbmRzKDIwMCk7CisgICAgaWYgKG1fcmVhZF9zaHV0ZG93bl9jdi53YWl0X3VudGlsKGxvY2ssIHRpbWVvdXRfdGltZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgWyZdIHsgcmV0dXJuIG1fcmVhZF9zaHV0ZG93bjsgfSkpCisgICAgICBtX3JlYWRfdGhyZWFkLmpvaW4oKTsKKyAgICBlbHNlCisgICAgICBtX3JlYWRfdGhyZWFkLmRldGFjaCgpOyAgLy8gdGltZWQgb3V0LCBkZXRhY2ggaXQKKyAgfQorICAvLyBjbGVhciBxdWV1ZQorICB3aGlsZSAoIW1fb3V0Z29pbmcuZW1wdHkoKSkgbV9vdXRnb2luZy5wb3AoKTsKK30KKworQ29ubmVjdGlvbkluZm8gTmV0d29ya0Nvbm5lY3Rpb246OmluZm8oKSBjb25zdCB7CisgIHJldHVybiBDb25uZWN0aW9uSW5mb3tyZW1vdGVfaWQoKSwgbV9zdHJlYW0tPmdldFBlZXJJUCgpLAorICAgICAgICAgICAgICAgICAgICAgICAgc3RhdGljX2Nhc3Q8dW5zaWduZWQgaW50PihtX3N0cmVhbS0+Z2V0UGVlclBvcnQoKSksCisgICAgICAgICAgICAgICAgICAgICAgICBtX2xhc3RfdXBkYXRlLCBtX3Byb3RvX3Jldn07Cit9CisKK3N0ZDo6c3RyaW5nIE5ldHdvcmtDb25uZWN0aW9uOjpyZW1vdGVfaWQoKSBjb25zdCB7CisgIHN0ZDo6bG9ja19ndWFyZDxzdGQ6Om11dGV4PiBsb2NrKG1fcmVtb3RlX2lkX211dGV4KTsKKyAgcmV0dXJuIG1fcmVtb3RlX2lkOworfQorCit2b2lkIE5ldHdvcmtDb25uZWN0aW9uOjpzZXRfcmVtb3RlX2lkKFN0cmluZ1JlZiByZW1vdGVfaWQpIHsKKyAgc3RkOjpsb2NrX2d1YXJkPHN0ZDo6bXV0ZXg+IGxvY2sobV9yZW1vdGVfaWRfbXV0ZXgpOworICBtX3JlbW90ZV9pZCA9IHJlbW90ZV9pZDsKK30KKwordm9pZCBOZXR3b3JrQ29ubmVjdGlvbjo6UmVhZFRocmVhZE1haW4oKSB7CisgIHJhd19zb2NrZXRfaXN0cmVhbSBpcygqbV9zdHJlYW0pOworICBXaXJlRGVjb2RlciBkZWNvZGVyKGlzLCBtX3Byb3RvX3Jldik7CisKKyAgbV9zdGF0ZSA9IHN0YXRpY19jYXN0PGludD4oa0hhbmRzaGFrZSk7CisgIGlmICghbV9oYW5kc2hha2UoKnRoaXMsCisgICAgICAgICAgICAgICAgICAgWyZdIHsKKyAgICAgICAgICAgICAgICAgICAgIGRlY29kZXIuc2V0X3Byb3RvX3JldihtX3Byb3RvX3Jldik7CisgICAgICAgICAgICAgICAgICAgICBhdXRvIG1zZyA9IE1lc3NhZ2U6OlJlYWQoZGVjb2RlciwgbV9nZXRfZW50cnlfdHlwZSk7CisgICAgICAgICAgICAgICAgICAgICBpZiAoIW1zZyAmJiBkZWNvZGVyLmVycm9yKCkpCisgICAgICAgICAgICAgICAgICAgICAgIERFQlVHKCJlcnJvciByZWFkaW5nIGluIGhhbmRzaGFrZTogIiA8PCBkZWNvZGVyLmVycm9yKCkpOworICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG1zZzsKKyAgICAgICAgICAgICAgICAgICB9LAorICAgICAgICAgICAgICAgICAgIFsmXShsbHZtOjpBcnJheVJlZjxzdGQ6OnNoYXJlZF9wdHI8TWVzc2FnZT4+IG1zZ3MpIHsKKyAgICAgICAgICAgICAgICAgICAgIG1fb3V0Z29pbmcuZW1wbGFjZShtc2dzKTsKKyAgICAgICAgICAgICAgICAgICB9KSkgeworICAgIG1fc3RhdGUgPSBzdGF0aWNfY2FzdDxpbnQ+KGtEZWFkKTsKKyAgICBtX2FjdGl2ZSA9IGZhbHNlOworICAgIGdvdG8gZG9uZTsKKyAgfQorCisgIG1fc3RhdGUgPSBzdGF0aWNfY2FzdDxpbnQ+KGtBY3RpdmUpOworICBtX25vdGlmaWVyLk5vdGlmeUNvbm5lY3Rpb24odHJ1ZSwgaW5mbygpKTsKKyAgd2hpbGUgKG1fYWN0aXZlKSB7CisgICAgaWYgKCFtX3N0cmVhbSkKKyAgICAgIGJyZWFrOworICAgIGRlY29kZXIuc2V0X3Byb3RvX3JldihtX3Byb3RvX3Jldik7CisgICAgZGVjb2Rlci5SZXNldCgpOworICAgIGF1dG8gbXNnID0gTWVzc2FnZTo6UmVhZChkZWNvZGVyLCBtX2dldF9lbnRyeV90eXBlKTsKKyAgICBpZiAoIW1zZykgeworICAgICAgaWYgKGRlY29kZXIuZXJyb3IoKSkgSU5GTygicmVhZCBlcnJvcjogIiA8PCBkZWNvZGVyLmVycm9yKCkpOworICAgICAgLy8gdGVybWluYXRlIGNvbm5lY3Rpb24gb24gYmFkIG1lc3NhZ2UKKyAgICAgIGlmIChtX3N0cmVhbSkgbV9zdHJlYW0tPmNsb3NlKCk7CisgICAgICBicmVhazsKKyAgICB9CisgICAgREVCVUczKCJyZWNlaXZlZCB0eXBlPSIgPDwgbXNnLT50eXBlKCkgPDwgIiB3aXRoIHN0cj0iIDw8IG1zZy0+c3RyKCkKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICA8PCAiIGlkPSIgPDwgbXNnLT5pZCgpCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgPDwgIiBzZXFfbnVtPSIgPDwgbXNnLT5zZXFfbnVtX3VpZCgpKTsKKyAgICBtX2xhc3RfdXBkYXRlID0gTm93KCk7CisgICAgbV9wcm9jZXNzX2luY29taW5nKHN0ZDo6bW92ZShtc2cpLCB0aGlzKTsKKyAgfQorICBERUJVRzIoInJlYWQgdGhyZWFkIGRpZWQgKCIgPDwgdGhpcyA8PCAiKSIpOworICBpZiAobV9zdGF0ZSAhPSBrRGVhZCkgbV9ub3RpZmllci5Ob3RpZnlDb25uZWN0aW9uKGZhbHNlLCBpbmZvKCkpOworICBtX3N0YXRlID0gc3RhdGljX2Nhc3Q8aW50PihrRGVhZCk7CisgIG1fYWN0aXZlID0gZmFsc2U7CisgIG1fb3V0Z29pbmcucHVzaChPdXRnb2luZygpKTsgIC8vIGFsc28ga2lsbCB3cml0ZSB0aHJlYWQKKworZG9uZToKKyAgLy8gdXNlIGNvbmRpdGlvbiB2YXJpYWJsZSB0byBzaWduYWwgdGhyZWFkIHNodXRkb3duCisgIHsKKyAgICBzdGQ6OmxvY2tfZ3VhcmQ8c3RkOjptdXRleD4gbG9jayhtX3NodXRkb3duX211dGV4KTsKKyAgICBtX3JlYWRfc2h1dGRvd24gPSB0cnVlOworICAgIG1fcmVhZF9zaHV0ZG93bl9jdi5ub3RpZnlfb25lKCk7CisgIH0KK30KKwordm9pZCBOZXR3b3JrQ29ubmVjdGlvbjo6V3JpdGVUaHJlYWRNYWluKCkgeworICBXaXJlRW5jb2RlciBlbmNvZGVyKG1fcHJvdG9fcmV2KTsKKworICB3aGlsZSAobV9hY3RpdmUpIHsKKyAgICBhdXRvIG1zZ3MgPSBtX291dGdvaW5nLnBvcCgpOworICAgIERFQlVHNCgid3JpdGUgdGhyZWFkIHdva2UgdXAiKTsKKyAgICBpZiAobXNncy5lbXB0eSgpKSBjb250aW51ZTsKKyAgICBlbmNvZGVyLnNldF9wcm90b19yZXYobV9wcm90b19yZXYpOworICAgIGVuY29kZXIuUmVzZXQoKTsKKyAgICBERUJVRzMoInNlbmRpbmcgIiA8PCBtc2dzLnNpemUoKSA8PCAiIG1lc3NhZ2VzIik7CisgICAgZm9yIChhdXRvJiBtc2cgOiBtc2dzKSB7CisgICAgICBpZiAobXNnKSB7CisgICAgICAgIERFQlVHMygic2VuZGluZyB0eXBlPSIgPDwgbXNnLT50eXBlKCkgPDwgIiB3aXRoIHN0cj0iIDw8IG1zZy0+c3RyKCkKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8PCAiIGlkPSIgPDwgbXNnLT5pZCgpCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPDwgIiBzZXFfbnVtPSIgPDwgbXNnLT5zZXFfbnVtX3VpZCgpKTsKKyAgICAgICAgbXNnLT5Xcml0ZShlbmNvZGVyKTsKKyAgICAgIH0KKyAgICB9CisgICAgTmV0d29ya1N0cmVhbTo6RXJyb3IgZXJyOworICAgIGlmICghbV9zdHJlYW0pIGJyZWFrOworICAgIGlmIChlbmNvZGVyLnNpemUoKSA9PSAwKSBjb250aW51ZTsKKyAgICBpZiAobV9zdHJlYW0tPnNlbmQoZW5jb2Rlci5kYXRhKCksIGVuY29kZXIuc2l6ZSgpLCAmZXJyKSA9PSAwKSBicmVhazsKKyAgICBERUJVRzQoInNlbnQgIiA8PCBlbmNvZGVyLnNpemUoKSA8PCAiIGJ5dGVzIik7CisgIH0KKyAgREVCVUcyKCJ3cml0ZSB0aHJlYWQgZGllZCAoIiA8PCB0aGlzIDw8ICIpIik7CisgIGlmIChtX3N0YXRlICE9IGtEZWFkKSBtX25vdGlmaWVyLk5vdGlmeUNvbm5lY3Rpb24oZmFsc2UsIGluZm8oKSk7CisgIG1fc3RhdGUgPSBzdGF0aWNfY2FzdDxpbnQ+KGtEZWFkKTsKKyAgbV9hY3RpdmUgPSBmYWxzZTsKKyAgaWYgKG1fc3RyZWFtKSBtX3N0cmVhbS0+Y2xvc2UoKTsgIC8vIGFsc28ga2lsbCByZWFkIHRocmVhZAorCisgIC8vIHVzZSBjb25kaXRpb24gdmFyaWFibGUgdG8gc2lnbmFsIHRocmVhZCBzaHV0ZG93bgorICB7CisgICAgc3RkOjpsb2NrX2d1YXJkPHN0ZDo6bXV0ZXg+IGxvY2sobV9zaHV0ZG93bl9tdXRleCk7CisgICAgbV93cml0ZV9zaHV0ZG93biA9IHRydWU7CisgICAgbV93cml0ZV9zaHV0ZG93bl9jdi5ub3RpZnlfb25lKCk7CisgIH0KK30KKwordm9pZCBOZXR3b3JrQ29ubmVjdGlvbjo6UXVldWVPdXRnb2luZyhzdGQ6OnNoYXJlZF9wdHI8TWVzc2FnZT4gbXNnKSB7CisgIHN0ZDo6bG9ja19ndWFyZDxzdGQ6Om11dGV4PiBsb2NrKG1fcGVuZGluZ19tdXRleCk7CisKKyAgLy8gTWVyZ2Ugd2l0aCBwcmV2aW91cy4gIE9uZSBjYXNlIHdlIGRvbid0IGNvbWJpbmU6IGRlbGV0ZS9hc3NpZ24gbG9vcC4KKyAgc3dpdGNoIChtc2ctPnR5cGUoKSkgeworICAgIGNhc2UgTWVzc2FnZTo6a0VudHJ5QXNzaWduOgorICAgIGNhc2UgTWVzc2FnZTo6a0VudHJ5VXBkYXRlOiB7CisgICAgICAvLyBkb24ndCBkbyB0aGlzIGZvciB1bmFzc2lnbmVkIGlkJ3MKKyAgICAgIHVuc2lnbmVkIGludCBpZCA9IG1zZy0+aWQoKTsKKyAgICAgIGlmIChpZCA9PSAweGZmZmYpIHsKKyAgICAgICAgbV9wZW5kaW5nX291dGdvaW5nLnB1c2hfYmFjayhtc2cpOworICAgICAgICBicmVhazsKKyAgICAgIH0KKyAgICAgIGlmIChpZCA8IG1fcGVuZGluZ191cGRhdGUuc2l6ZSgpICYmIG1fcGVuZGluZ191cGRhdGVbaWRdLmZpcnN0ICE9IDApIHsKKyAgICAgICAgLy8gb3ZlcndyaXRlIHRoZSBwcmV2aW91cyBvbmUgZm9yIHRoaXMgaWQKKyAgICAgICAgYXV0byYgb2xkbXNnID0gbV9wZW5kaW5nX291dGdvaW5nW21fcGVuZGluZ191cGRhdGVbaWRdLmZpcnN0IC0gMV07CisgICAgICAgIGlmIChvbGRtc2cgJiYgb2xkbXNnLT5JcyhNZXNzYWdlOjprRW50cnlBc3NpZ24pICYmCisgICAgICAgICAgICBtc2ctPklzKE1lc3NhZ2U6OmtFbnRyeVVwZGF0ZSkpIHsKKyAgICAgICAgICAvLyBuZWVkIHRvIHVwZGF0ZSBhc3NpZ25tZW50IHdpdGggbmV3IHNlcV9udW0gYW5kIHZhbHVlCisgICAgICAgICAgb2xkbXNnID0gTWVzc2FnZTo6RW50cnlBc3NpZ24ob2xkbXNnLT5zdHIoKSwgaWQsIG1zZy0+c2VxX251bV91aWQoKSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtc2ctPnZhbHVlKCksIG9sZG1zZy0+ZmxhZ3MoKSk7CisgICAgICAgIH0gZWxzZQorICAgICAgICAgIG9sZG1zZyA9IG1zZzsgIC8vIGVhc3kgdXBkYXRlCisgICAgICB9IGVsc2UgeworICAgICAgICAvLyBuZXcsIGJ1dCByZW1lbWJlciBpdAorICAgICAgICBzdGQ6OnNpemVfdCBwb3MgPSBtX3BlbmRpbmdfb3V0Z29pbmcuc2l6ZSgpOworICAgICAgICBtX3BlbmRpbmdfb3V0Z29pbmcucHVzaF9iYWNrKG1zZyk7CisgICAgICAgIGlmIChpZCA+PSBtX3BlbmRpbmdfdXBkYXRlLnNpemUoKSkgbV9wZW5kaW5nX3VwZGF0ZS5yZXNpemUoaWQgKyAxKTsKKyAgICAgICAgbV9wZW5kaW5nX3VwZGF0ZVtpZF0uZmlyc3QgPSBwb3MgKyAxOworICAgICAgfQorICAgICAgYnJlYWs7CisgICAgfQorICAgIGNhc2UgTWVzc2FnZTo6a0VudHJ5RGVsZXRlOiB7CisgICAgICAvLyBkb24ndCBkbyB0aGlzIGZvciB1bmFzc2lnbmVkIGlkJ3MKKyAgICAgIHVuc2lnbmVkIGludCBpZCA9IG1zZy0+aWQoKTsKKyAgICAgIGlmIChpZCA9PSAweGZmZmYpIHsKKyAgICAgICAgbV9wZW5kaW5nX291dGdvaW5nLnB1c2hfYmFjayhtc2cpOworICAgICAgICBicmVhazsKKyAgICAgIH0KKworICAgICAgLy8gY2xlYXIgcHJldmlvdXMgdXBkYXRlcworICAgICAgaWYgKGlkIDwgbV9wZW5kaW5nX3VwZGF0ZS5zaXplKCkpIHsKKyAgICAgICAgaWYgKG1fcGVuZGluZ191cGRhdGVbaWRdLmZpcnN0ICE9IDApIHsKKyAgICAgICAgICBtX3BlbmRpbmdfb3V0Z29pbmdbbV9wZW5kaW5nX3VwZGF0ZVtpZF0uZmlyc3QgLSAxXS5yZXNldCgpOworICAgICAgICAgIG1fcGVuZGluZ191cGRhdGVbaWRdLmZpcnN0ID0gMDsKKyAgICAgICAgfQorICAgICAgICBpZiAobV9wZW5kaW5nX3VwZGF0ZVtpZF0uc2Vjb25kICE9IDApIHsKKyAgICAgICAgICBtX3BlbmRpbmdfb3V0Z29pbmdbbV9wZW5kaW5nX3VwZGF0ZVtpZF0uc2Vjb25kIC0gMV0ucmVzZXQoKTsKKyAgICAgICAgICBtX3BlbmRpbmdfdXBkYXRlW2lkXS5zZWNvbmQgPSAwOworICAgICAgICB9CisgICAgICB9CisKKyAgICAgIC8vIGFkZCBkZWxldGlvbgorICAgICAgbV9wZW5kaW5nX291dGdvaW5nLnB1c2hfYmFjayhtc2cpOworICAgICAgYnJlYWs7CisgICAgfQorICAgIGNhc2UgTWVzc2FnZTo6a0ZsYWdzVXBkYXRlOiB7CisgICAgICAvLyBkb24ndCBkbyB0aGlzIGZvciB1bmFzc2lnbmVkIGlkJ3MKKyAgICAgIHVuc2lnbmVkIGludCBpZCA9IG1zZy0+aWQoKTsKKyAgICAgIGlmIChpZCA9PSAweGZmZmYpIHsKKyAgICAgICAgbV9wZW5kaW5nX291dGdvaW5nLnB1c2hfYmFjayhtc2cpOworICAgICAgICBicmVhazsKKyAgICAgIH0KKyAgICAgIGlmIChpZCA8IG1fcGVuZGluZ191cGRhdGUuc2l6ZSgpICYmIG1fcGVuZGluZ191cGRhdGVbaWRdLnNlY29uZCAhPSAwKSB7CisgICAgICAgIC8vIG92ZXJ3cml0ZSB0aGUgcHJldmlvdXMgb25lIGZvciB0aGlzIGlkCisgICAgICAgIG1fcGVuZGluZ19vdXRnb2luZ1ttX3BlbmRpbmdfdXBkYXRlW2lkXS5zZWNvbmQgLSAxXSA9IG1zZzsKKyAgICAgIH0gZWxzZSB7CisgICAgICAgIC8vIG5ldywgYnV0IHJlbWVtYmVyIGl0CisgICAgICAgIHN0ZDo6c2l6ZV90IHBvcyA9IG1fcGVuZGluZ19vdXRnb2luZy5zaXplKCk7CisgICAgICAgIG1fcGVuZGluZ19vdXRnb2luZy5wdXNoX2JhY2sobXNnKTsKKyAgICAgICAgaWYgKGlkID49IG1fcGVuZGluZ191cGRhdGUuc2l6ZSgpKSBtX3BlbmRpbmdfdXBkYXRlLnJlc2l6ZShpZCArIDEpOworICAgICAgICBtX3BlbmRpbmdfdXBkYXRlW2lkXS5zZWNvbmQgPSBwb3MgKyAxOworICAgICAgfQorICAgICAgYnJlYWs7CisgICAgfQorICAgIGNhc2UgTWVzc2FnZTo6a0NsZWFyRW50cmllczogeworICAgICAgLy8ga25vY2sgb3V0IGFsbCBwcmV2aW91cyBhc3NpZ25zL3VwZGF0ZXMhCisgICAgICBmb3IgKGF1dG8mIGkgOiBtX3BlbmRpbmdfb3V0Z29pbmcpIHsKKyAgICAgICAgaWYgKCFpKSBjb250aW51ZTsKKyAgICAgICAgYXV0byB0ID0gaS0+dHlwZSgpOworICAgICAgICBpZiAodCA9PSBNZXNzYWdlOjprRW50cnlBc3NpZ24gfHwgdCA9PSBNZXNzYWdlOjprRW50cnlVcGRhdGUgfHwKKyAgICAgICAgICAgIHQgPT0gTWVzc2FnZTo6a0ZsYWdzVXBkYXRlIHx8IHQgPT0gTWVzc2FnZTo6a0VudHJ5RGVsZXRlIHx8CisgICAgICAgICAgICB0ID09IE1lc3NhZ2U6OmtDbGVhckVudHJpZXMpCisgICAgICAgICAgaS5yZXNldCgpOworICAgICAgfQorICAgICAgbV9wZW5kaW5nX3VwZGF0ZS5yZXNpemUoMCk7CisgICAgICBtX3BlbmRpbmdfb3V0Z29pbmcucHVzaF9iYWNrKG1zZyk7CisgICAgICBicmVhazsKKyAgICB9CisgICAgZGVmYXVsdDoKKyAgICAgIG1fcGVuZGluZ19vdXRnb2luZy5wdXNoX2JhY2sobXNnKTsKKyAgICAgIGJyZWFrOworICB9Cit9CisKK3ZvaWQgTmV0d29ya0Nvbm5lY3Rpb246OlBvc3RPdXRnb2luZyhib29sIGtlZXBfYWxpdmUpIHsKKyAgc3RkOjpsb2NrX2d1YXJkPHN0ZDo6bXV0ZXg+IGxvY2sobV9wZW5kaW5nX211dGV4KTsKKyAgYXV0byBub3cgPSBzdGQ6OmNocm9ubzo6c3RlYWR5X2Nsb2NrOjpub3coKTsKKyAgaWYgKG1fcGVuZGluZ19vdXRnb2luZy5lbXB0eSgpKSB7CisgICAgaWYgKCFrZWVwX2FsaXZlKSByZXR1cm47CisgICAgLy8gc2VuZCBrZWVwLWFsaXZlcyBvbmNlIGEgc2Vjb25kIChpZiBubyBvdGhlciBtZXNzYWdlcyBoYXZlIGJlZW4gc2VudCkKKyAgICBpZiAoKG5vdyAtIG1fbGFzdF9wb3N0KSA8IHN0ZDo6Y2hyb25vOjpzZWNvbmRzKDEpKSByZXR1cm47CisgICAgbV9vdXRnb2luZy5lbXBsYWNlKE91dGdvaW5ne01lc3NhZ2U6OktlZXBBbGl2ZSgpfSk7CisgIH0gZWxzZSB7CisgICAgbV9vdXRnb2luZy5lbXBsYWNlKHN0ZDo6bW92ZShtX3BlbmRpbmdfb3V0Z29pbmcpKTsKKyAgICBtX3BlbmRpbmdfb3V0Z29pbmcucmVzaXplKDApOworICAgIG1fcGVuZGluZ191cGRhdGUucmVzaXplKDApOworICB9CisgIG1fbGFzdF9wb3N0ID0gbm93OworfQpkaWZmIC0tZ2l0IGEvc3JjL05ldHdvcmtDb25uZWN0aW9uLmggYi9zcmMvTmV0d29ya0Nvbm5lY3Rpb24uaApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4yZjEwNzNjCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL05ldHdvcmtDb25uZWN0aW9uLmgKQEAgLTAsMCArMSwxMTUgQEAKKy8qLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovCisvKiBDb3B5cmlnaHQgKGMpIEZJUlNUIDIwMTUuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqLworLyogT3BlbiBTb3VyY2UgU29mdHdhcmUgLSBtYXkgYmUgbW9kaWZpZWQgYW5kIHNoYXJlZCBieSBGUkMgdGVhbXMuIFRoZSBjb2RlICAgKi8KKy8qIG11c3QgYmUgYWNjb21wYW5pZWQgYnkgdGhlIEZJUlNUIEJTRCBsaWNlbnNlIGZpbGUgaW4gdGhlIHJvb3QgZGlyZWN0b3J5IG9mICovCisvKiB0aGUgcHJvamVjdC4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqLworLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi8KKworI2lmbmRlZiBOVF9ORVRXT1JLQ09OTkVDVElPTl9IXworI2RlZmluZSBOVF9ORVRXT1JLQ09OTkVDVElPTl9IXworCisjaW5jbHVkZSA8YXRvbWljPgorI2luY2x1ZGUgPGNocm9ubz4KKyNpbmNsdWRlIDxtZW1vcnk+CisjaW5jbHVkZSA8dGhyZWFkPgorCisjaW5jbHVkZSAic3VwcG9ydC9Db25jdXJyZW50UXVldWUuaCIKKyNpbmNsdWRlICJNZXNzYWdlLmgiCisjaW5jbHVkZSAibnRjb3JlX2NwcC5oIgorCitjbGFzcyBOZXR3b3JrU3RyZWFtOworCituYW1lc3BhY2UgbnQgeworCitjbGFzcyBOb3RpZmllcjsKKworY2xhc3MgTmV0d29ya0Nvbm5lY3Rpb24geworIHB1YmxpYzoKKyAgZW51bSBTdGF0ZSB7IGtDcmVhdGVkLCBrSW5pdCwga0hhbmRzaGFrZSwga1N5bmNocm9uaXplZCwga0FjdGl2ZSwga0RlYWQgfTsKKworICB0eXBlZGVmIHN0ZDo6ZnVuY3Rpb248Ym9vbCgKKyAgICAgIE5ldHdvcmtDb25uZWN0aW9uJiBjb25uLAorICAgICAgc3RkOjpmdW5jdGlvbjxzdGQ6OnNoYXJlZF9wdHI8TWVzc2FnZT4oKT4gZ2V0X21zZywKKyAgICAgIHN0ZDo6ZnVuY3Rpb248dm9pZChsbHZtOjpBcnJheVJlZjxzdGQ6OnNoYXJlZF9wdHI8TWVzc2FnZT4+KT4gc2VuZF9tc2dzKT4KKyAgICAgIEhhbmRzaGFrZUZ1bmM7CisgIHR5cGVkZWYgc3RkOjpmdW5jdGlvbjx2b2lkKHN0ZDo6c2hhcmVkX3B0cjxNZXNzYWdlPiBtc2csCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE5ldHdvcmtDb25uZWN0aW9uKiBjb25uKT4gUHJvY2Vzc0luY29taW5nRnVuYzsKKyAgdHlwZWRlZiBzdGQ6OnZlY3RvcjxzdGQ6OnNoYXJlZF9wdHI8TWVzc2FnZT4+IE91dGdvaW5nOworICB0eXBlZGVmIENvbmN1cnJlbnRRdWV1ZTxPdXRnb2luZz4gT3V0Z29pbmdRdWV1ZTsKKworICBOZXR3b3JrQ29ubmVjdGlvbihzdGQ6OnVuaXF1ZV9wdHI8TmV0d29ya1N0cmVhbT4gc3RyZWFtLAorICAgICAgICAgICAgICAgICAgICBOb3RpZmllciYgbm90aWZpZXIsCisgICAgICAgICAgICAgICAgICAgIEhhbmRzaGFrZUZ1bmMgaGFuZHNoYWtlLAorICAgICAgICAgICAgICAgICAgICBNZXNzYWdlOjpHZXRFbnRyeVR5cGVGdW5jIGdldF9lbnRyeV90eXBlKTsKKyAgfk5ldHdvcmtDb25uZWN0aW9uKCk7CisKKyAgLy8gU2V0IHRoZSBpbnB1dCBwcm9jZXNzb3IgZnVuY3Rpb24uICBUaGlzIG11c3QgYmUgY2FsbGVkIGJlZm9yZSBTdGFydCgpLgorICB2b2lkIHNldF9wcm9jZXNzX2luY29taW5nKFByb2Nlc3NJbmNvbWluZ0Z1bmMgZnVuYykgeworICAgIG1fcHJvY2Vzc19pbmNvbWluZyA9IGZ1bmM7CisgIH0KKworICB2b2lkIFN0YXJ0KCk7CisgIHZvaWQgU3RvcCgpOworCisgIENvbm5lY3Rpb25JbmZvIGluZm8oKSBjb25zdDsKKworICBib29sIGFjdGl2ZSgpIGNvbnN0IHsgcmV0dXJuIG1fYWN0aXZlOyB9CisgIE5ldHdvcmtTdHJlYW0mIHN0cmVhbSgpIHsgcmV0dXJuICptX3N0cmVhbTsgfQorCisgIHZvaWQgUXVldWVPdXRnb2luZyhzdGQ6OnNoYXJlZF9wdHI8TWVzc2FnZT4gbXNnKTsKKyAgdm9pZCBQb3N0T3V0Z29pbmcoYm9vbCBrZWVwX2FsaXZlKTsKKworICB1bnNpZ25lZCBpbnQgdWlkKCkgY29uc3QgeyByZXR1cm4gbV91aWQ7IH0KKworICB1bnNpZ25lZCBpbnQgcHJvdG9fcmV2KCkgY29uc3QgeyByZXR1cm4gbV9wcm90b19yZXY7IH0KKyAgdm9pZCBzZXRfcHJvdG9fcmV2KHVuc2lnbmVkIGludCBwcm90b19yZXYpIHsgbV9wcm90b19yZXYgPSBwcm90b19yZXY7IH0KKworICBTdGF0ZSBzdGF0ZSgpIGNvbnN0IHsgcmV0dXJuIHN0YXRpY19jYXN0PFN0YXRlPihtX3N0YXRlLmxvYWQoKSk7IH0KKyAgdm9pZCBzZXRfc3RhdGUoU3RhdGUgc3RhdGUpIHsgbV9zdGF0ZSA9IHN0YXRpY19jYXN0PGludD4oc3RhdGUpOyB9CisKKyAgc3RkOjpzdHJpbmcgcmVtb3RlX2lkKCkgY29uc3Q7CisgIHZvaWQgc2V0X3JlbW90ZV9pZChTdHJpbmdSZWYgcmVtb3RlX2lkKTsKKworICB1bnNpZ25lZCBsb25nIGxvbmcgbGFzdF91cGRhdGUoKSBjb25zdCB7IHJldHVybiBtX2xhc3RfdXBkYXRlOyB9CisKKyAgTmV0d29ya0Nvbm5lY3Rpb24oY29uc3QgTmV0d29ya0Nvbm5lY3Rpb24mKSA9IGRlbGV0ZTsKKyAgTmV0d29ya0Nvbm5lY3Rpb24mIG9wZXJhdG9yPShjb25zdCBOZXR3b3JrQ29ubmVjdGlvbiYpID0gZGVsZXRlOworCisgcHJpdmF0ZToKKyAgdm9pZCBSZWFkVGhyZWFkTWFpbigpOworICB2b2lkIFdyaXRlVGhyZWFkTWFpbigpOworCisgIHN0YXRpYyBzdGQ6OmF0b21pY191aW50IHNfdWlkOworCisgIHVuc2lnbmVkIGludCBtX3VpZDsKKyAgc3RkOjp1bmlxdWVfcHRyPE5ldHdvcmtTdHJlYW0+IG1fc3RyZWFtOworICBOb3RpZmllciYgbV9ub3RpZmllcjsKKyAgT3V0Z29pbmdRdWV1ZSBtX291dGdvaW5nOworICBIYW5kc2hha2VGdW5jIG1faGFuZHNoYWtlOworICBNZXNzYWdlOjpHZXRFbnRyeVR5cGVGdW5jIG1fZ2V0X2VudHJ5X3R5cGU7CisgIFByb2Nlc3NJbmNvbWluZ0Z1bmMgbV9wcm9jZXNzX2luY29taW5nOworICBzdGQ6OnRocmVhZCBtX3JlYWRfdGhyZWFkOworICBzdGQ6OnRocmVhZCBtX3dyaXRlX3RocmVhZDsKKyAgc3RkOjphdG9taWNfYm9vbCBtX2FjdGl2ZTsKKyAgc3RkOjphdG9taWNfdWludCBtX3Byb3RvX3JldjsKKyAgc3RkOjphdG9taWNfaW50IG1fc3RhdGU7CisgIG11dGFibGUgc3RkOjptdXRleCBtX3JlbW90ZV9pZF9tdXRleDsKKyAgc3RkOjpzdHJpbmcgbV9yZW1vdGVfaWQ7CisgIHN0ZDo6YXRvbWljX3VsbG9uZyBtX2xhc3RfdXBkYXRlOworICBzdGQ6OmNocm9ubzo6c3RlYWR5X2Nsb2NrOjp0aW1lX3BvaW50IG1fbGFzdF9wb3N0OworCisgIHN0ZDo6bXV0ZXggbV9wZW5kaW5nX211dGV4OworICBPdXRnb2luZyBtX3BlbmRpbmdfb3V0Z29pbmc7CisgIHN0ZDo6dmVjdG9yPHN0ZDo6cGFpcjxzdGQ6OnNpemVfdCwgc3RkOjpzaXplX3Q+PiBtX3BlbmRpbmdfdXBkYXRlOworCisgIC8vIENvbmRpdGlvbiB2YXJpYWJsZXMgZm9yIHNodXRkb3duCisgIHN0ZDo6bXV0ZXggbV9zaHV0ZG93bl9tdXRleDsKKyAgc3RkOjpjb25kaXRpb25fdmFyaWFibGUgbV9yZWFkX3NodXRkb3duX2N2OworICBzdGQ6OmNvbmRpdGlvbl92YXJpYWJsZSBtX3dyaXRlX3NodXRkb3duX2N2OworICBib29sIG1fcmVhZF9zaHV0ZG93biA9IGZhbHNlOworICBib29sIG1fd3JpdGVfc2h1dGRvd24gPSBmYWxzZTsKK307CisKK30gIC8vIG5hbWVzcGFjZSBudAorCisjZW5kaWYgIC8vIE5UX05FVFdPUktDT05ORUNUSU9OX0hfCmRpZmYgLS1naXQgYS9zcmMvTm90aWZpZXIuY3BwIGIvc3JjL05vdGlmaWVyLmNwcApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5mYjJlOGRjCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL05vdGlmaWVyLmNwcApAQCAtMCwwICsxLDIwMiBAQAorLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi8KKy8qIENvcHlyaWdodCAoYykgRklSU1QgMjAxNS4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICovCisvKiBPcGVuIFNvdXJjZSBTb2Z0d2FyZSAtIG1heSBiZSBtb2RpZmllZCBhbmQgc2hhcmVkIGJ5IEZSQyB0ZWFtcy4gVGhlIGNvZGUgICAqLworLyogbXVzdCBiZSBhY2NvbXBhbmllZCBieSB0aGUgRklSU1QgQlNEIGxpY2Vuc2UgZmlsZSBpbiB0aGUgcm9vdCBkaXJlY3Rvcnkgb2YgKi8KKy8qIHRoZSBwcm9qZWN0LiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICovCisvKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qLworCisjaW5jbHVkZSAiTm90aWZpZXIuaCIKKwordXNpbmcgbmFtZXNwYWNlIG50OworCitBVE9NSUNfU1RBVElDX0lOSVQoTm90aWZpZXIpCitib29sIE5vdGlmaWVyOjpzX2Rlc3Ryb3llZCA9IGZhbHNlOworCitOb3RpZmllcjo6Tm90aWZpZXIoKSB7CisgIG1fYWN0aXZlID0gZmFsc2U7CisgIG1fbG9jYWxfbm90aWZpZXJzID0gZmFsc2U7CisgIHNfZGVzdHJveWVkID0gZmFsc2U7Cit9CisKK05vdGlmaWVyOjp+Tm90aWZpZXIoKSB7CisgIHNfZGVzdHJveWVkID0gdHJ1ZTsKKyAgU3RvcCgpOworfQorCit2b2lkIE5vdGlmaWVyOjpTdGFydCgpIHsKKyAgeworICAgIHN0ZDo6bG9ja19ndWFyZDxzdGQ6Om11dGV4PiBsb2NrKG1fbXV0ZXgpOworICAgIGlmIChtX2FjdGl2ZSkgcmV0dXJuOworICAgIG1fYWN0aXZlID0gdHJ1ZTsKKyAgfQorICB7CisgICAgc3RkOjpsb2NrX2d1YXJkPHN0ZDo6bXV0ZXg+IGxvY2sobV9zaHV0ZG93bl9tdXRleCk7CisgICAgbV9zaHV0ZG93biA9IGZhbHNlOworICB9CisgIG1fdGhyZWFkID0gc3RkOjp0aHJlYWQoJk5vdGlmaWVyOjpUaHJlYWRNYWluLCB0aGlzKTsKK30KKwordm9pZCBOb3RpZmllcjo6U3RvcCgpIHsKKyAgbV9hY3RpdmUgPSBmYWxzZTsKKyAgLy8gc2VuZCBub3RpZmljYXRpb24gc28gdGhlIHRocmVhZCB0ZXJtaW5hdGVzCisgIG1fY29uZC5ub3RpZnlfb25lKCk7CisgIGlmIChtX3RocmVhZC5qb2luYWJsZSgpKSB7CisgICAgLy8gam9pbiB3aXRoIHRpbWVvdXQKKyAgICBzdGQ6OnVuaXF1ZV9sb2NrPHN0ZDo6bXV0ZXg+IGxvY2sobV9zaHV0ZG93bl9tdXRleCk7CisgICAgYXV0byB0aW1lb3V0X3RpbWUgPQorICAgICAgICBzdGQ6OmNocm9ubzo6c3RlYWR5X2Nsb2NrOjpub3coKSArIHN0ZDo6Y2hyb25vOjpzZWNvbmRzKDEpOworICAgIGlmIChtX3NodXRkb3duX2N2LndhaXRfdW50aWwobG9jaywgdGltZW91dF90aW1lLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgWyZdIHsgcmV0dXJuIG1fc2h1dGRvd247IH0pKQorICAgICAgbV90aHJlYWQuam9pbigpOworICAgIGVsc2UKKyAgICAgIG1fdGhyZWFkLmRldGFjaCgpOyAgLy8gdGltZWQgb3V0LCBkZXRhY2ggaXQKKyAgfQorfQorCit2b2lkIE5vdGlmaWVyOjpUaHJlYWRNYWluKCkgeworICBpZiAobV9vbl9zdGFydCkgbV9vbl9zdGFydCgpOworCisgIHN0ZDo6dW5pcXVlX2xvY2s8c3RkOjptdXRleD4gbG9jayhtX211dGV4KTsKKyAgd2hpbGUgKG1fYWN0aXZlKSB7CisgICAgd2hpbGUgKG1fZW50cnlfbm90aWZpY2F0aW9ucy5lbXB0eSgpICYmIG1fY29ubl9ub3RpZmljYXRpb25zLmVtcHR5KCkpIHsKKyAgICAgIG1fY29uZC53YWl0KGxvY2spOworICAgICAgaWYgKCFtX2FjdGl2ZSkgZ290byBkb25lOworICAgIH0KKworICAgIC8vIEVudHJ5IG5vdGlmaWNhdGlvbnMKKyAgICB3aGlsZSAoIW1fZW50cnlfbm90aWZpY2F0aW9ucy5lbXB0eSgpKSB7CisgICAgICBpZiAoIW1fYWN0aXZlKSBnb3RvIGRvbmU7CisgICAgICBhdXRvIGl0ZW0gPSBzdGQ6Om1vdmUobV9lbnRyeV9ub3RpZmljYXRpb25zLmZyb250KCkpOworICAgICAgbV9lbnRyeV9ub3RpZmljYXRpb25zLnBvcCgpOworCisgICAgICBpZiAoIWl0ZW0udmFsdWUpIGNvbnRpbnVlOworICAgICAgU3RyaW5nUmVmIG5hbWUoaXRlbS5uYW1lKTsKKworICAgICAgaWYgKGl0ZW0ub25seSkgeworICAgICAgICAvLyBEb24ndCBob2xkIG11dGV4IGR1cmluZyBjYWxsYmFjayBleGVjdXRpb24hCisgICAgICAgIGxvY2sudW5sb2NrKCk7CisgICAgICAgIGl0ZW0ub25seSgwLCBuYW1lLCBpdGVtLnZhbHVlLCBpdGVtLmZsYWdzKTsKKyAgICAgICAgbG9jay5sb2NrKCk7CisgICAgICAgIGNvbnRpbnVlOworICAgICAgfQorCisgICAgICAvLyBVc2UgaW5kZXggYmVjYXVzZSBpdGVyYXRvciBtaWdodCBnZXQgaW52YWxpZGF0ZWQuCisgICAgICBmb3IgKHN0ZDo6c2l6ZV90IGk9MDsgaTxtX2VudHJ5X2xpc3RlbmVycy5zaXplKCk7ICsraSkgeworICAgICAgICBpZiAoIW1fZW50cnlfbGlzdGVuZXJzW2ldLmNhbGxiYWNrKSBjb250aW51ZTsgIC8vIHJlbW92ZWQKKworICAgICAgICAvLyBGbGFncyBtdXN0IGJlIHdpdGhpbiByZXF1ZXN0ZWQgZmxhZyBzZXQgZm9yIHRoaXMgbGlzdGVuZXIuCisgICAgICAgIC8vIEJlY2F1c2UgYXNzaWduIG1lc3NhZ2VzIGNhbiByZXN1bHQgaW4gYm90aCBhIHZhbHVlIGFuZCBmbGFncyB1cGRhdGUsCisgICAgICAgIC8vIHdlIGhhbmRsZSB0aGF0IGNhc2Ugc3BlY2lhbGx5LgorICAgICAgICB1bnNpZ25lZCBpbnQgbGlzdGVuX2ZsYWdzID0gbV9lbnRyeV9saXN0ZW5lcnNbaV0uZmxhZ3M7CisgICAgICAgIHVuc2lnbmVkIGludCBmbGFncyA9IGl0ZW0uZmxhZ3M7CisgICAgICAgIHVuc2lnbmVkIGludCBhc3NpZ25fYm90aCA9IE5UX05PVElGWV9VUERBVEUgfCBOVF9OT1RJRllfRkxBR1M7CisgICAgICAgIGlmICgoZmxhZ3MgJiBhc3NpZ25fYm90aCkgPT0gYXNzaWduX2JvdGgpIHsKKyAgICAgICAgICBpZiAoKGxpc3Rlbl9mbGFncyAmIGFzc2lnbl9ib3RoKSA9PSAwKSBjb250aW51ZTsKKyAgICAgICAgICBsaXN0ZW5fZmxhZ3MgJj0gfmFzc2lnbl9ib3RoOworICAgICAgICAgIGZsYWdzICY9IH5hc3NpZ25fYm90aDsKKyAgICAgICAgfQorICAgICAgICBpZiAoKGZsYWdzICYgfmxpc3Rlbl9mbGFncykgIT0gMCkgY29udGludWU7CisKKyAgICAgICAgLy8gbXVzdCBtYXRjaCBwcmVmaXgKKyAgICAgICAgaWYgKCFuYW1lLnN0YXJ0c3dpdGgobV9lbnRyeV9saXN0ZW5lcnNbaV0ucHJlZml4KSkgY29udGludWU7CisKKyAgICAgICAgLy8gbWFrZSBhIGNvcHkgb2YgdGhlIGNhbGxiYWNrIHNvIHdlIGNhbiBzYWZlbHkgcmVsZWFzZSB0aGUgbXV0ZXgKKyAgICAgICAgYXV0byBjYWxsYmFjayA9IG1fZW50cnlfbGlzdGVuZXJzW2ldLmNhbGxiYWNrOworCisgICAgICAgIC8vIERvbid0IGhvbGQgbXV0ZXggZHVyaW5nIGNhbGxiYWNrIGV4ZWN1dGlvbiEKKyAgICAgICAgbG9jay51bmxvY2soKTsKKyAgICAgICAgY2FsbGJhY2soaSsxLCBuYW1lLCBpdGVtLnZhbHVlLCBpdGVtLmZsYWdzKTsKKyAgICAgICAgbG9jay5sb2NrKCk7CisgICAgICB9CisgICAgfQorCisgICAgLy8gQ29ubmVjdGlvbiBub3RpZmljYXRpb25zCisgICAgd2hpbGUgKCFtX2Nvbm5fbm90aWZpY2F0aW9ucy5lbXB0eSgpKSB7CisgICAgICBpZiAoIW1fYWN0aXZlKSBnb3RvIGRvbmU7CisgICAgICBhdXRvIGl0ZW0gPSBzdGQ6Om1vdmUobV9jb25uX25vdGlmaWNhdGlvbnMuZnJvbnQoKSk7CisgICAgICBtX2Nvbm5fbm90aWZpY2F0aW9ucy5wb3AoKTsKKworICAgICAgaWYgKGl0ZW0ub25seSkgeworICAgICAgICAvLyBEb24ndCBob2xkIG11dGV4IGR1cmluZyBjYWxsYmFjayBleGVjdXRpb24hCisgICAgICAgIGxvY2sudW5sb2NrKCk7CisgICAgICAgIGl0ZW0ub25seSgwLCBpdGVtLmNvbm5lY3RlZCwgaXRlbS5jb25uX2luZm8pOworICAgICAgICBsb2NrLmxvY2soKTsKKyAgICAgICAgY29udGludWU7CisgICAgICB9CisKKyAgICAgIC8vIFVzZSBpbmRleCBiZWNhdXNlIGl0ZXJhdG9yIG1pZ2h0IGdldCBpbnZhbGlkYXRlZC4KKyAgICAgIGZvciAoc3RkOjpzaXplX3QgaT0wOyBpPG1fY29ubl9saXN0ZW5lcnMuc2l6ZSgpOyArK2kpIHsKKyAgICAgICAgaWYgKCFtX2Nvbm5fbGlzdGVuZXJzW2ldKSBjb250aW51ZTsgIC8vIHJlbW92ZWQKKyAgICAgICAgYXV0byBjYWxsYmFjayA9IG1fY29ubl9saXN0ZW5lcnNbaV07CisgICAgICAgIC8vIERvbid0IGhvbGQgbXV0ZXggZHVyaW5nIGNhbGxiYWNrIGV4ZWN1dGlvbiEKKyAgICAgICAgbG9jay51bmxvY2soKTsKKyAgICAgICAgY2FsbGJhY2soaSsxLCBpdGVtLmNvbm5lY3RlZCwgaXRlbS5jb25uX2luZm8pOworICAgICAgICBsb2NrLmxvY2soKTsKKyAgICAgIH0KKyAgICB9CisgIH0KKworZG9uZToKKyAgaWYgKG1fb25fZXhpdCkgbV9vbl9leGl0KCk7CisKKyAgLy8gdXNlIGNvbmRpdGlvbiB2YXJpYWJsZSB0byBzaWduYWwgdGhyZWFkIHNodXRkb3duCisgIHsKKyAgICBzdGQ6OmxvY2tfZ3VhcmQ8c3RkOjptdXRleD4gbG9jayhtX3NodXRkb3duX211dGV4KTsKKyAgICBtX3NodXRkb3duID0gdHJ1ZTsKKyAgICBtX3NodXRkb3duX2N2Lm5vdGlmeV9vbmUoKTsKKyAgfQorfQorCit1bnNpZ25lZCBpbnQgTm90aWZpZXI6OkFkZEVudHJ5TGlzdGVuZXIoU3RyaW5nUmVmIHByZWZpeCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBFbnRyeUxpc3RlbmVyQ2FsbGJhY2sgY2FsbGJhY2ssCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdW5zaWduZWQgaW50IGZsYWdzKSB7CisgIHN0ZDo6bG9ja19ndWFyZDxzdGQ6Om11dGV4PiBsb2NrKG1fbXV0ZXgpOworICB1bnNpZ25lZCBpbnQgdWlkID0gbV9lbnRyeV9saXN0ZW5lcnMuc2l6ZSgpOworICBtX2VudHJ5X2xpc3RlbmVycy5lbXBsYWNlX2JhY2socHJlZml4LCBjYWxsYmFjaywgZmxhZ3MpOworICBpZiAoKGZsYWdzICYgTlRfTk9USUZZX0xPQ0FMKSAhPSAwKSBtX2xvY2FsX25vdGlmaWVycyA9IHRydWU7CisgIHJldHVybiB1aWQgKyAxOworfQorCit2b2lkIE5vdGlmaWVyOjpSZW1vdmVFbnRyeUxpc3RlbmVyKHVuc2lnbmVkIGludCBlbnRyeV9saXN0ZW5lcl91aWQpIHsKKyAgLS1lbnRyeV9saXN0ZW5lcl91aWQ7CisgIHN0ZDo6bG9ja19ndWFyZDxzdGQ6Om11dGV4PiBsb2NrKG1fbXV0ZXgpOworICBpZiAoZW50cnlfbGlzdGVuZXJfdWlkIDwgbV9lbnRyeV9saXN0ZW5lcnMuc2l6ZSgpKQorICAgIG1fZW50cnlfbGlzdGVuZXJzW2VudHJ5X2xpc3RlbmVyX3VpZF0uY2FsbGJhY2sgPSBudWxscHRyOworfQorCit2b2lkIE5vdGlmaWVyOjpOb3RpZnlFbnRyeShTdHJpbmdSZWYgbmFtZSwgc3RkOjpzaGFyZWRfcHRyPFZhbHVlPiB2YWx1ZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgIHVuc2lnbmVkIGludCBmbGFncywgRW50cnlMaXN0ZW5lckNhbGxiYWNrIG9ubHkpIHsKKyAgaWYgKCFtX2FjdGl2ZSkgcmV0dXJuOworICAvLyBvcHRpbWl6YXRpb246IGRvbid0IGdlbmVyYXRlIG5lZWRsZXNzIGxvY2FsIHF1ZXVlIGVudHJpZXMgaWYgd2UgaGF2ZQorICAvLyBubyBsb2NhbCBsaXN0ZW5lcnMgKGFzIHRoaXMgaXMgYSBjb21tb24gY2FzZSBvbiB0aGUgc2VydmVyIHNpZGUpCisgIGlmICgoZmxhZ3MgJiBOVF9OT1RJRllfTE9DQUwpICE9IDAgJiYgIW1fbG9jYWxfbm90aWZpZXJzKSByZXR1cm47CisgIHN0ZDo6dW5pcXVlX2xvY2s8c3RkOjptdXRleD4gbG9jayhtX211dGV4KTsKKyAgbV9lbnRyeV9ub3RpZmljYXRpb25zLmVtcGxhY2UobmFtZSwgdmFsdWUsIGZsYWdzLCBvbmx5KTsKKyAgbG9jay51bmxvY2soKTsKKyAgbV9jb25kLm5vdGlmeV9vbmUoKTsKK30KKwordW5zaWduZWQgaW50IE5vdGlmaWVyOjpBZGRDb25uZWN0aW9uTGlzdGVuZXIoCisgICAgQ29ubmVjdGlvbkxpc3RlbmVyQ2FsbGJhY2sgY2FsbGJhY2spIHsKKyAgc3RkOjpsb2NrX2d1YXJkPHN0ZDo6bXV0ZXg+IGxvY2sobV9tdXRleCk7CisgIHVuc2lnbmVkIGludCB1aWQgPSBtX2VudHJ5X2xpc3RlbmVycy5zaXplKCk7CisgIG1fY29ubl9saXN0ZW5lcnMuZW1wbGFjZV9iYWNrKGNhbGxiYWNrKTsKKyAgcmV0dXJuIHVpZCArIDE7Cit9CisKK3ZvaWQgTm90aWZpZXI6OlJlbW92ZUNvbm5lY3Rpb25MaXN0ZW5lcih1bnNpZ25lZCBpbnQgY29ubl9saXN0ZW5lcl91aWQpIHsKKyAgLS1jb25uX2xpc3RlbmVyX3VpZDsKKyAgc3RkOjpsb2NrX2d1YXJkPHN0ZDo6bXV0ZXg+IGxvY2sobV9tdXRleCk7CisgIGlmIChjb25uX2xpc3RlbmVyX3VpZCA8IG1fY29ubl9saXN0ZW5lcnMuc2l6ZSgpKQorICAgIG1fY29ubl9saXN0ZW5lcnNbY29ubl9saXN0ZW5lcl91aWRdID0gbnVsbHB0cjsKK30KKwordm9pZCBOb3RpZmllcjo6Tm90aWZ5Q29ubmVjdGlvbihib29sIGNvbm5lY3RlZCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgQ29ubmVjdGlvbkluZm8mIGNvbm5faW5mbywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQ29ubmVjdGlvbkxpc3RlbmVyQ2FsbGJhY2sgb25seSkgeworICBpZiAoIW1fYWN0aXZlKSByZXR1cm47CisgIHN0ZDo6dW5pcXVlX2xvY2s8c3RkOjptdXRleD4gbG9jayhtX211dGV4KTsKKyAgbV9jb25uX25vdGlmaWNhdGlvbnMuZW1wbGFjZShjb25uZWN0ZWQsIGNvbm5faW5mbywgb25seSk7CisgIGxvY2sudW5sb2NrKCk7CisgIG1fY29uZC5ub3RpZnlfb25lKCk7Cit9CmRpZmYgLS1naXQgYS9zcmMvTm90aWZpZXIuaCBiL3NyYy9Ob3RpZmllci5oCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmQxMDA1NGMKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvTm90aWZpZXIuaApAQCAtMCwwICsxLDEyMCBAQAorLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi8KKy8qIENvcHlyaWdodCAoYykgRklSU1QgMjAxNS4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICovCisvKiBPcGVuIFNvdXJjZSBTb2Z0d2FyZSAtIG1heSBiZSBtb2RpZmllZCBhbmQgc2hhcmVkIGJ5IEZSQyB0ZWFtcy4gVGhlIGNvZGUgICAqLworLyogbXVzdCBiZSBhY2NvbXBhbmllZCBieSB0aGUgRklSU1QgQlNEIGxpY2Vuc2UgZmlsZSBpbiB0aGUgcm9vdCBkaXJlY3Rvcnkgb2YgKi8KKy8qIHRoZSBwcm9qZWN0LiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICovCisvKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qLworCisjaWZuZGVmIE5UX05PVElGSUVSX0hfCisjZGVmaW5lIE5UX05PVElGSUVSX0hfCisKKyNpbmNsdWRlIDxhdG9taWM+CisjaW5jbHVkZSA8Y29uZGl0aW9uX3ZhcmlhYmxlPgorI2luY2x1ZGUgPG11dGV4PgorI2luY2x1ZGUgPHF1ZXVlPgorI2luY2x1ZGUgPHRocmVhZD4KKyNpbmNsdWRlIDx1dGlsaXR5PgorI2luY2x1ZGUgPHZlY3Rvcj4KKworI2luY2x1ZGUgImF0b21pY19zdGF0aWMuaCIKKyNpbmNsdWRlICJudGNvcmVfY3BwLmgiCisKK25hbWVzcGFjZSBudCB7CisKK2NsYXNzIE5vdGlmaWVyIHsKKyAgZnJpZW5kIGNsYXNzIE5vdGlmaWVyVGVzdDsKKyBwdWJsaWM6CisgIHN0YXRpYyBOb3RpZmllciYgR2V0SW5zdGFuY2UoKSB7CisgICAgQVRPTUlDX1NUQVRJQyhOb3RpZmllciwgaW5zdGFuY2UpOworICAgIHJldHVybiBpbnN0YW5jZTsKKyAgfQorICB+Tm90aWZpZXIoKTsKKworICB2b2lkIFN0YXJ0KCk7CisgIHZvaWQgU3RvcCgpOworCisgIGJvb2wgYWN0aXZlKCkgY29uc3QgeyByZXR1cm4gbV9hY3RpdmU7IH0KKyAgYm9vbCBsb2NhbF9ub3RpZmllcnMoKSBjb25zdCB7IHJldHVybiBtX2xvY2FsX25vdGlmaWVyczsgfQorICBzdGF0aWMgYm9vbCBkZXN0cm95ZWQoKSB7IHJldHVybiBzX2Rlc3Ryb3llZDsgfQorCisgIHZvaWQgU2V0T25TdGFydChzdGQ6OmZ1bmN0aW9uPHZvaWQoKT4gb25fc3RhcnQpIHsgbV9vbl9zdGFydCA9IG9uX3N0YXJ0OyB9CisgIHZvaWQgU2V0T25FeGl0KHN0ZDo6ZnVuY3Rpb248dm9pZCgpPiBvbl9leGl0KSB7IG1fb25fZXhpdCA9IG9uX2V4aXQ7IH0KKworICB1bnNpZ25lZCBpbnQgQWRkRW50cnlMaXN0ZW5lcihTdHJpbmdSZWYgcHJlZml4LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBFbnRyeUxpc3RlbmVyQ2FsbGJhY2sgY2FsbGJhY2ssCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVuc2lnbmVkIGludCBmbGFncyk7CisgIHZvaWQgUmVtb3ZlRW50cnlMaXN0ZW5lcih1bnNpZ25lZCBpbnQgZW50cnlfbGlzdGVuZXJfdWlkKTsKKworICB2b2lkIE5vdGlmeUVudHJ5KFN0cmluZ1JlZiBuYW1lLCBzdGQ6OnNoYXJlZF9wdHI8VmFsdWU+IHZhbHVlLAorICAgICAgICAgICAgICAgICAgIHVuc2lnbmVkIGludCBmbGFncywgRW50cnlMaXN0ZW5lckNhbGxiYWNrIG9ubHkgPSBudWxscHRyKTsKKworICB1bnNpZ25lZCBpbnQgQWRkQ29ubmVjdGlvbkxpc3RlbmVyKENvbm5lY3Rpb25MaXN0ZW5lckNhbGxiYWNrIGNhbGxiYWNrKTsKKyAgdm9pZCBSZW1vdmVDb25uZWN0aW9uTGlzdGVuZXIodW5zaWduZWQgaW50IGNvbm5fbGlzdGVuZXJfdWlkKTsKKworICB2b2lkIE5vdGlmeUNvbm5lY3Rpb24oYm9vbCBjb25uZWN0ZWQsIGNvbnN0IENvbm5lY3Rpb25JbmZvJiBjb25uX2luZm8sCisgICAgICAgICAgICAgICAgICAgICAgICBDb25uZWN0aW9uTGlzdGVuZXJDYWxsYmFjayBvbmx5ID0gbnVsbHB0cik7CisKKyBwcml2YXRlOgorICBOb3RpZmllcigpOworCisgIHZvaWQgVGhyZWFkTWFpbigpOworCisgIHN0ZDo6YXRvbWljX2Jvb2wgbV9hY3RpdmU7CisgIHN0ZDo6YXRvbWljX2Jvb2wgbV9sb2NhbF9ub3RpZmllcnM7CisKKyAgc3RkOjptdXRleCBtX211dGV4OworICBzdGQ6OmNvbmRpdGlvbl92YXJpYWJsZSBtX2NvbmQ7CisKKyAgc3RydWN0IEVudHJ5TGlzdGVuZXIgeworICAgIEVudHJ5TGlzdGVuZXIoU3RyaW5nUmVmIHByZWZpeF8sIEVudHJ5TGlzdGVuZXJDYWxsYmFjayBjYWxsYmFja18sCisgICAgICAgICAgICAgICAgICB1bnNpZ25lZCBpbnQgZmxhZ3NfKQorICAgICAgICA6IHByZWZpeChwcmVmaXhfKSwgY2FsbGJhY2soY2FsbGJhY2tfKSwgZmxhZ3MoZmxhZ3NfKSB7fQorCisgICAgc3RkOjpzdHJpbmcgcHJlZml4OworICAgIEVudHJ5TGlzdGVuZXJDYWxsYmFjayBjYWxsYmFjazsKKyAgICB1bnNpZ25lZCBpbnQgZmxhZ3M7CisgIH07CisgIHN0ZDo6dmVjdG9yPEVudHJ5TGlzdGVuZXI+IG1fZW50cnlfbGlzdGVuZXJzOworICBzdGQ6OnZlY3RvcjxDb25uZWN0aW9uTGlzdGVuZXJDYWxsYmFjaz4gbV9jb25uX2xpc3RlbmVyczsKKworICBzdHJ1Y3QgRW50cnlOb3RpZmljYXRpb24geworICAgIEVudHJ5Tm90aWZpY2F0aW9uKFN0cmluZ1JlZiBuYW1lXywgc3RkOjpzaGFyZWRfcHRyPFZhbHVlPiB2YWx1ZV8sCisgICAgICAgICAgICAgICAgICAgICAgdW5zaWduZWQgaW50IGZsYWdzXywgRW50cnlMaXN0ZW5lckNhbGxiYWNrIG9ubHlfKQorICAgICAgICA6IG5hbWUobmFtZV8pLAorICAgICAgICAgIHZhbHVlKHZhbHVlXyksCisgICAgICAgICAgZmxhZ3MoZmxhZ3NfKSwKKyAgICAgICAgICBvbmx5KG9ubHlfKSB7fQorCisgICAgc3RkOjpzdHJpbmcgbmFtZTsKKyAgICBzdGQ6OnNoYXJlZF9wdHI8VmFsdWU+IHZhbHVlOworICAgIHVuc2lnbmVkIGludCBmbGFnczsKKyAgICBFbnRyeUxpc3RlbmVyQ2FsbGJhY2sgb25seTsKKyAgfTsKKyAgc3RkOjpxdWV1ZTxFbnRyeU5vdGlmaWNhdGlvbj4gbV9lbnRyeV9ub3RpZmljYXRpb25zOworCisgIHN0cnVjdCBDb25uZWN0aW9uTm90aWZpY2F0aW9uIHsKKyAgICBDb25uZWN0aW9uTm90aWZpY2F0aW9uKGJvb2wgY29ubmVjdGVkXywgY29uc3QgQ29ubmVjdGlvbkluZm8mIGNvbm5faW5mb18sCisgICAgICAgICAgICAgICAgICAgICAgICAgICBDb25uZWN0aW9uTGlzdGVuZXJDYWxsYmFjayBvbmx5XykKKyAgICAgICAgOiBjb25uZWN0ZWQoY29ubmVjdGVkXyksIGNvbm5faW5mbyhjb25uX2luZm9fKSwgb25seShvbmx5Xykge30KKworICAgIGJvb2wgY29ubmVjdGVkOworICAgIENvbm5lY3Rpb25JbmZvIGNvbm5faW5mbzsKKyAgICBDb25uZWN0aW9uTGlzdGVuZXJDYWxsYmFjayBvbmx5OworICB9OworICBzdGQ6OnF1ZXVlPENvbm5lY3Rpb25Ob3RpZmljYXRpb24+IG1fY29ubl9ub3RpZmljYXRpb25zOworCisgIHN0ZDo6dGhyZWFkIG1fdGhyZWFkOworICBzdGQ6Om11dGV4IG1fc2h1dGRvd25fbXV0ZXg7CisgIHN0ZDo6Y29uZGl0aW9uX3ZhcmlhYmxlIG1fc2h1dGRvd25fY3Y7CisgIGJvb2wgbV9zaHV0ZG93biA9IGZhbHNlOworCisgIHN0ZDo6ZnVuY3Rpb248dm9pZCgpPiBtX29uX3N0YXJ0OworICBzdGQ6OmZ1bmN0aW9uPHZvaWQoKT4gbV9vbl9leGl0OworCisgIEFUT01JQ19TVEFUSUNfREVDTChOb3RpZmllcikKKyAgc3RhdGljIGJvb2wgc19kZXN0cm95ZWQ7Cit9OworCit9ICAvLyBuYW1lc3BhY2UgbnQKKworI2VuZGlmICAvLyBOVF9OT1RJRklFUl9IXwpkaWZmIC0tZ2l0IGEvc3JjL1JwY1NlcnZlci5jcHAgYi9zcmMvUnBjU2VydmVyLmNwcApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi40M2QzN2RlCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL1JwY1NlcnZlci5jcHAKQEAgLTAsMCArMSwxNDEgQEAKKy8qLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovCisvKiBDb3B5cmlnaHQgKGMpIEZJUlNUIDIwMTUuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqLworLyogT3BlbiBTb3VyY2UgU29mdHdhcmUgLSBtYXkgYmUgbW9kaWZpZWQgYW5kIHNoYXJlZCBieSBGUkMgdGVhbXMuIFRoZSBjb2RlICAgKi8KKy8qIG11c3QgYmUgYWNjb21wYW5pZWQgYnkgdGhlIEZJUlNUIEJTRCBsaWNlbnNlIGZpbGUgaW4gdGhlIHJvb3QgZGlyZWN0b3J5IG9mICovCisvKiB0aGUgcHJvamVjdC4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqLworLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi8KKworI2luY2x1ZGUgIlJwY1NlcnZlci5oIgorCisjaW5jbHVkZSAiTG9nLmgiCisKK3VzaW5nIG5hbWVzcGFjZSBudDsKKworQVRPTUlDX1NUQVRJQ19JTklUKFJwY1NlcnZlcikKKworUnBjU2VydmVyOjpScGNTZXJ2ZXIoKSB7CisgIG1fYWN0aXZlID0gZmFsc2U7CisgIG1fdGVybWluYXRpbmcgPSBmYWxzZTsKK30KKworUnBjU2VydmVyOjp+UnBjU2VydmVyKCkgeworICBMb2dnZXI6OkdldEluc3RhbmNlKCkuU2V0TG9nZ2VyKG51bGxwdHIpOworICBTdG9wKCk7CisgIG1fdGVybWluYXRpbmcgPSB0cnVlOworICBtX3BvbGxfY29uZC5ub3RpZnlfYWxsKCk7Cit9CisKK3ZvaWQgUnBjU2VydmVyOjpTdGFydCgpIHsKKyAgeworICAgIHN0ZDo6bG9ja19ndWFyZDxzdGQ6Om11dGV4PiBsb2NrKG1fbXV0ZXgpOworICAgIGlmIChtX2FjdGl2ZSkgcmV0dXJuOworICAgIG1fYWN0aXZlID0gdHJ1ZTsKKyAgfQorICB7CisgICAgc3RkOjpsb2NrX2d1YXJkPHN0ZDo6bXV0ZXg+IGxvY2sobV9zaHV0ZG93bl9tdXRleCk7CisgICAgbV9zaHV0ZG93biA9IGZhbHNlOworICB9CisgIG1fdGhyZWFkID0gc3RkOjp0aHJlYWQoJlJwY1NlcnZlcjo6VGhyZWFkTWFpbiwgdGhpcyk7Cit9CisKK3ZvaWQgUnBjU2VydmVyOjpTdG9wKCkgeworICBtX2FjdGl2ZSA9IGZhbHNlOworICBpZiAobV90aHJlYWQuam9pbmFibGUoKSkgeworICAgIC8vIHNlbmQgbm90aWZpY2F0aW9uIHNvIHRoZSB0aHJlYWQgdGVybWluYXRlcworICAgIG1fY2FsbF9jb25kLm5vdGlmeV9vbmUoKTsKKyAgICAvLyBqb2luIHdpdGggdGltZW91dAorICAgIHN0ZDo6dW5pcXVlX2xvY2s8c3RkOjptdXRleD4gbG9jayhtX3NodXRkb3duX211dGV4KTsKKyAgICBhdXRvIHRpbWVvdXRfdGltZSA9CisgICAgICAgIHN0ZDo6Y2hyb25vOjpzdGVhZHlfY2xvY2s6Om5vdygpICsgc3RkOjpjaHJvbm86OnNlY29uZHMoMSk7CisgICAgaWYgKG1fc2h1dGRvd25fY3Yud2FpdF91bnRpbChsb2NrLCB0aW1lb3V0X3RpbWUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbJl0geyByZXR1cm4gbV9zaHV0ZG93bjsgfSkpCisgICAgICBtX3RocmVhZC5qb2luKCk7CisgICAgZWxzZQorICAgICAgbV90aHJlYWQuZGV0YWNoKCk7ICAvLyB0aW1lZCBvdXQsIGRldGFjaCBpdAorICB9Cit9CisKK3ZvaWQgUnBjU2VydmVyOjpQcm9jZXNzUnBjKFN0cmluZ1JlZiBuYW1lLCBzdGQ6OnNoYXJlZF9wdHI8TWVzc2FnZT4gbXNnLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgUnBjQ2FsbGJhY2sgZnVuYywgdW5zaWduZWQgaW50IGNvbm5faWQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICBTZW5kTXNnRnVuYyBzZW5kX3Jlc3BvbnNlKSB7CisgIHN0ZDo6dW5pcXVlX2xvY2s8c3RkOjptdXRleD4gbG9jayhtX211dGV4KTsKKworICBpZiAoZnVuYykKKyAgICBtX2NhbGxfcXVldWUuZW1wbGFjZShuYW1lLCBtc2csIGZ1bmMsIGNvbm5faWQsIHNlbmRfcmVzcG9uc2UpOworICBlbHNlCisgICAgbV9wb2xsX3F1ZXVlLmVtcGxhY2UobmFtZSwgbXNnLCBmdW5jLCBjb25uX2lkLCBzZW5kX3Jlc3BvbnNlKTsKKworICBsb2NrLnVubG9jaygpOworCisgIGlmIChmdW5jKQorICAgIG1fY2FsbF9jb25kLm5vdGlmeV9vbmUoKTsKKyAgZWxzZQorICAgIG1fcG9sbF9jb25kLm5vdGlmeV9vbmUoKTsKK30KKworYm9vbCBScGNTZXJ2ZXI6OlBvbGxScGMoYm9vbCBibG9ja2luZywgUnBjQ2FsbEluZm8qIGNhbGxfaW5mbykgeworICBzdGQ6OnVuaXF1ZV9sb2NrPHN0ZDo6bXV0ZXg+IGxvY2sobV9tdXRleCk7CisgIHdoaWxlIChtX3BvbGxfcXVldWUuZW1wdHkoKSkgeworICAgIGlmICghYmxvY2tpbmcgfHwgbV90ZXJtaW5hdGluZykgcmV0dXJuIGZhbHNlOworICAgIG1fcG9sbF9jb25kLndhaXQobG9jayk7CisgIH0KKworICBhdXRvJiBpdGVtID0gbV9wb2xsX3F1ZXVlLmZyb250KCk7CisgIHVuc2lnbmVkIGludCBjYWxsX3VpZCA9IChpdGVtLmNvbm5faWQgPDwgMTYpIHwgaXRlbS5tc2ctPnNlcV9udW1fdWlkKCk7CisgIGNhbGxfaW5mby0+cnBjX2lkID0gaXRlbS5tc2ctPmlkKCk7CisgIGNhbGxfaW5mby0+Y2FsbF91aWQgPSBjYWxsX3VpZDsKKyAgY2FsbF9pbmZvLT5uYW1lID0gc3RkOjptb3ZlKGl0ZW0ubmFtZSk7CisgIGNhbGxfaW5mby0+cGFyYW1zID0gaXRlbS5tc2ctPnN0cigpOworICBtX3Jlc3BvbnNlX21hcC5pbnNlcnQoc3RkOjptYWtlX3BhaXIoc3RkOjptYWtlX3BhaXIoaXRlbS5tc2ctPmlkKCksIGNhbGxfdWlkKSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGl0ZW0uc2VuZF9yZXNwb25zZSkpOworICBtX3BvbGxfcXVldWUucG9wKCk7CisgIHJldHVybiB0cnVlOworfQorCit2b2lkIFJwY1NlcnZlcjo6UG9zdFJwY1Jlc3BvbnNlKHVuc2lnbmVkIGludCBycGNfaWQsIHVuc2lnbmVkIGludCBjYWxsX3VpZCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGx2bTo6U3RyaW5nUmVmIHJlc3VsdCkgeworICBhdXRvIGkgPSBtX3Jlc3BvbnNlX21hcC5maW5kKHN0ZDo6bWFrZV9wYWlyKHJwY19pZCwgY2FsbF91aWQpKTsKKyAgaWYgKGkgPT0gbV9yZXNwb25zZV9tYXAuZW5kKCkpIHsKKyAgICBXQVJOSU5HKCJwb3N0aW5nIFJQQyByZXNwb25zZSB0byBub25leGlzdGVudCBjYWxsIChvciBkdXBsaWNhdGUgcmVzcG9uc2UpIik7CisgICAgcmV0dXJuOworICB9CisgIChpLT5nZXRTZWNvbmQoKSkoTWVzc2FnZTo6UnBjUmVzcG9uc2UocnBjX2lkLCBjYWxsX3VpZCwgcmVzdWx0KSk7CisgIG1fcmVzcG9uc2VfbWFwLmVyYXNlKGkpOworfQorCit2b2lkIFJwY1NlcnZlcjo6VGhyZWFkTWFpbigpIHsKKyAgc3RkOjp1bmlxdWVfbG9jazxzdGQ6Om11dGV4PiBsb2NrKG1fbXV0ZXgpOworICBzdGQ6OnN0cmluZyB0bXA7CisgIHdoaWxlIChtX2FjdGl2ZSkgeworICAgIHdoaWxlIChtX2NhbGxfcXVldWUuZW1wdHkoKSkgeworICAgICAgbV9jYWxsX2NvbmQud2FpdChsb2NrKTsKKyAgICAgIGlmICghbV9hY3RpdmUpIGdvdG8gZG9uZTsKKyAgICB9CisKKyAgICB3aGlsZSAoIW1fY2FsbF9xdWV1ZS5lbXB0eSgpKSB7CisgICAgICBpZiAoIW1fYWN0aXZlKSBnb3RvIGRvbmU7CisgICAgICBhdXRvIGl0ZW0gPSBzdGQ6Om1vdmUobV9jYWxsX3F1ZXVlLmZyb250KCkpOworICAgICAgbV9jYWxsX3F1ZXVlLnBvcCgpOworCisgICAgICBERUJVRzQoInJwYyBjYWxsaW5nICIgPDwgaXRlbS5uYW1lKTsKKworICAgICAgaWYgKGl0ZW0ubmFtZS5lbXB0eSgpIHx8ICFpdGVtLm1zZyB8fCAhaXRlbS5mdW5jIHx8ICFpdGVtLnNlbmRfcmVzcG9uc2UpCisgICAgICAgIGNvbnRpbnVlOworCisgICAgICAvLyBEb24ndCBob2xkIG11dGV4IGR1cmluZyBjYWxsYmFjayBleGVjdXRpb24hCisgICAgICBsb2NrLnVubG9jaygpOworICAgICAgYXV0byByZXN1bHQgPSBpdGVtLmZ1bmMoaXRlbS5uYW1lLCBpdGVtLm1zZy0+c3RyKCkpOworICAgICAgaXRlbS5zZW5kX3Jlc3BvbnNlKE1lc3NhZ2U6OlJwY1Jlc3BvbnNlKGl0ZW0ubXNnLT5pZCgpLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGl0ZW0ubXNnLT5zZXFfbnVtX3VpZCgpLCByZXN1bHQpKTsKKyAgICAgIGxvY2subG9jaygpOworICAgIH0KKyAgfQorCitkb25lOgorICAvLyB1c2UgY29uZGl0aW9uIHZhcmlhYmxlIHRvIHNpZ25hbCB0aHJlYWQgc2h1dGRvd24KKyAgeworICAgIHN0ZDo6bG9ja19ndWFyZDxzdGQ6Om11dGV4PiBsb2NrKG1fc2h1dGRvd25fbXV0ZXgpOworICAgIG1fc2h1dGRvd24gPSB0cnVlOworICAgIG1fc2h1dGRvd25fY3Yubm90aWZ5X29uZSgpOworICB9Cit9CmRpZmYgLS1naXQgYS9zcmMvUnBjU2VydmVyLmggYi9zcmMvUnBjU2VydmVyLmgKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNzI2MDM0ZAotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9ScGNTZXJ2ZXIuaApAQCAtMCwwICsxLDkxIEBACisvKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qLworLyogQ29weXJpZ2h0IChjKSBGSVJTVCAyMDE1LiBBbGwgUmlnaHRzIFJlc2VydmVkLiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKi8KKy8qIE9wZW4gU291cmNlIFNvZnR3YXJlIC0gbWF5IGJlIG1vZGlmaWVkIGFuZCBzaGFyZWQgYnkgRlJDIHRlYW1zLiBUaGUgY29kZSAgICovCisvKiBtdXN0IGJlIGFjY29tcGFuaWVkIGJ5IHRoZSBGSVJTVCBCU0QgbGljZW5zZSBmaWxlIGluIHRoZSByb290IGRpcmVjdG9yeSBvZiAqLworLyogdGhlIHByb2plY3QuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKi8KKy8qLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovCisKKyNpZm5kZWYgTlRfUlBDU0VSVkVSX0hfCisjZGVmaW5lIE5UX1JQQ1NFUlZFUl9IXworCisjaW5jbHVkZSA8YXRvbWljPgorI2luY2x1ZGUgPGNvbmRpdGlvbl92YXJpYWJsZT4KKyNpbmNsdWRlIDxtdXRleD4KKyNpbmNsdWRlIDxxdWV1ZT4KKyNpbmNsdWRlIDx0aHJlYWQ+CisjaW5jbHVkZSA8dXRpbGl0eT4KKyNpbmNsdWRlIDx2ZWN0b3I+CisKKyNpbmNsdWRlICJsbHZtL0RlbnNlTWFwLmgiCisjaW5jbHVkZSAiYXRvbWljX3N0YXRpYy5oIgorI2luY2x1ZGUgIk1lc3NhZ2UuaCIKKyNpbmNsdWRlICJudGNvcmVfY3BwLmgiCisKK25hbWVzcGFjZSBudCB7CisKK2NsYXNzIFJwY1NlcnZlciB7CisgIGZyaWVuZCBjbGFzcyBScGNTZXJ2ZXJUZXN0OworIHB1YmxpYzoKKyAgc3RhdGljIFJwY1NlcnZlciYgR2V0SW5zdGFuY2UoKSB7CisgICAgQVRPTUlDX1NUQVRJQyhScGNTZXJ2ZXIsIGluc3RhbmNlKTsKKyAgICByZXR1cm4gaW5zdGFuY2U7CisgIH0KKyAgflJwY1NlcnZlcigpOworCisgIHR5cGVkZWYgc3RkOjpmdW5jdGlvbjx2b2lkKHN0ZDo6c2hhcmVkX3B0cjxNZXNzYWdlPik+IFNlbmRNc2dGdW5jOworCisgIHZvaWQgU3RhcnQoKTsKKyAgdm9pZCBTdG9wKCk7CisKKyAgYm9vbCBhY3RpdmUoKSBjb25zdCB7IHJldHVybiBtX2FjdGl2ZTsgfQorCisgIHZvaWQgUHJvY2Vzc1JwYyhTdHJpbmdSZWYgbmFtZSwgc3RkOjpzaGFyZWRfcHRyPE1lc3NhZ2U+IG1zZywKKyAgICAgICAgICAgICAgICAgIFJwY0NhbGxiYWNrIGZ1bmMsIHVuc2lnbmVkIGludCBjb25uX2lkLAorICAgICAgICAgICAgICAgICAgU2VuZE1zZ0Z1bmMgc2VuZF9yZXNwb25zZSk7CisKKyAgYm9vbCBQb2xsUnBjKGJvb2wgYmxvY2tpbmcsIFJwY0NhbGxJbmZvKiBjYWxsX2luZm8pOworICB2b2lkIFBvc3RScGNSZXNwb25zZSh1bnNpZ25lZCBpbnQgcnBjX2lkLCB1bnNpZ25lZCBpbnQgY2FsbF91aWQsCisgICAgICAgICAgICAgICAgICAgICAgIGxsdm06OlN0cmluZ1JlZiByZXN1bHQpOworCisgcHJpdmF0ZToKKyAgUnBjU2VydmVyKCk7CisKKyAgdm9pZCBUaHJlYWRNYWluKCk7CisKKyAgc3RkOjphdG9taWNfYm9vbCBtX2FjdGl2ZTsKKyAgc3RkOjphdG9taWNfYm9vbCBtX3Rlcm1pbmF0aW5nOworCisgIHN0ZDo6bXV0ZXggbV9tdXRleDsKKyAgc3RkOjpjb25kaXRpb25fdmFyaWFibGUgbV9jYWxsX2NvbmQsIG1fcG9sbF9jb25kOworCisgIHN0cnVjdCBScGNDYWxsIHsKKyAgICBScGNDYWxsKFN0cmluZ1JlZiBuYW1lXywgc3RkOjpzaGFyZWRfcHRyPE1lc3NhZ2U+IG1zZ18sIFJwY0NhbGxiYWNrIGZ1bmNfLAorICAgICAgICAgICAgdW5zaWduZWQgaW50IGNvbm5faWRfLCBTZW5kTXNnRnVuYyBzZW5kX3Jlc3BvbnNlXykKKyAgICAgICAgOiBuYW1lKG5hbWVfKSwKKyAgICAgICAgICBtc2cobXNnXyksCisgICAgICAgICAgZnVuYyhmdW5jXyksCisgICAgICAgICAgY29ubl9pZChjb25uX2lkXyksCisgICAgICAgICAgc2VuZF9yZXNwb25zZShzZW5kX3Jlc3BvbnNlXykge30KKworICAgIHN0ZDo6c3RyaW5nIG5hbWU7CisgICAgc3RkOjpzaGFyZWRfcHRyPE1lc3NhZ2U+IG1zZzsKKyAgICBScGNDYWxsYmFjayBmdW5jOworICAgIHVuc2lnbmVkIGludCBjb25uX2lkOworICAgIFNlbmRNc2dGdW5jIHNlbmRfcmVzcG9uc2U7CisgIH07CisgIHN0ZDo6cXVldWU8UnBjQ2FsbD4gbV9jYWxsX3F1ZXVlLCBtX3BvbGxfcXVldWU7CisKKyAgbGx2bTo6RGVuc2VNYXA8c3RkOjpwYWlyPHVuc2lnbmVkIGludCwgdW5zaWduZWQgaW50PiwgU2VuZE1zZ0Z1bmM+CisgICAgICBtX3Jlc3BvbnNlX21hcDsKKworICBzdGQ6OnRocmVhZCBtX3RocmVhZDsKKyAgc3RkOjptdXRleCBtX3NodXRkb3duX211dGV4OworICBzdGQ6OmNvbmRpdGlvbl92YXJpYWJsZSBtX3NodXRkb3duX2N2OworICBib29sIG1fc2h1dGRvd24gPSBmYWxzZTsKKworICBBVE9NSUNfU1RBVElDX0RFQ0woUnBjU2VydmVyKQorfTsKKworfSAgLy8gbmFtZXNwYWNlIG50CisKKyNlbmRpZiAgLy8gTlRfUlBDU0VSVkVSX0hfCmRpZmYgLS1naXQgYS9zcmMvU2VxdWVuY2VOdW1iZXIuY3BwIGIvc3JjL1NlcXVlbmNlTnVtYmVyLmNwcApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5iMjJiZmVjCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL1NlcXVlbmNlTnVtYmVyLmNwcApAQCAtMCwwICsxLDMwIEBACisvKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qLworLyogQ29weXJpZ2h0IChjKSBGSVJTVCAyMDE1LiBBbGwgUmlnaHRzIFJlc2VydmVkLiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKi8KKy8qIE9wZW4gU291cmNlIFNvZnR3YXJlIC0gbWF5IGJlIG1vZGlmaWVkIGFuZCBzaGFyZWQgYnkgRlJDIHRlYW1zLiBUaGUgY29kZSAgICovCisvKiBtdXN0IGJlIGFjY29tcGFuaWVkIGJ5IHRoZSBGSVJTVCBCU0QgbGljZW5zZSBmaWxlIGluIHRoZSByb290IGRpcmVjdG9yeSBvZiAqLworLyogdGhlIHByb2plY3QuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKi8KKy8qLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovCisKKyNpbmNsdWRlICJTZXF1ZW5jZU51bWJlci5oIgorCituYW1lc3BhY2UgbnQgeworCitib29sIG9wZXJhdG9yPChjb25zdCBTZXF1ZW5jZU51bWJlciYgbGhzLCBjb25zdCBTZXF1ZW5jZU51bWJlciYgcmhzKSB7CisgIGlmIChsaHMubV92YWx1ZSA8IHJocy5tX3ZhbHVlKQorICAgIHJldHVybiAocmhzLm1fdmFsdWUgLSBsaHMubV92YWx1ZSkgPCAoMXUgPDwgMTUpOworICBlbHNlIGlmIChsaHMubV92YWx1ZSA+IHJocy5tX3ZhbHVlKQorICAgIHJldHVybiAobGhzLm1fdmFsdWUgLSByaHMubV92YWx1ZSkgPiAoMXUgPDwgMTUpOworICBlbHNlCisgICAgcmV0dXJuIGZhbHNlOworfQorCitib29sIG9wZXJhdG9yPihjb25zdCBTZXF1ZW5jZU51bWJlciYgbGhzLCBjb25zdCBTZXF1ZW5jZU51bWJlciYgcmhzKSB7CisgIGlmIChsaHMubV92YWx1ZSA8IHJocy5tX3ZhbHVlKQorICAgIHJldHVybiAocmhzLm1fdmFsdWUgLSBsaHMubV92YWx1ZSkgPiAoMXUgPDwgMTUpOworICBlbHNlIGlmIChsaHMubV92YWx1ZSA+IHJocy5tX3ZhbHVlKQorICAgIHJldHVybiAobGhzLm1fdmFsdWUgLSByaHMubV92YWx1ZSkgPCAoMXUgPDwgMTUpOworICBlbHNlCisgICAgcmV0dXJuIGZhbHNlOworfQorCit9ICAvLyBuYW1lc3BhY2UgbnQKZGlmZiAtLWdpdCBhL3NyYy9TZXF1ZW5jZU51bWJlci5oIGIvc3JjL1NlcXVlbmNlTnVtYmVyLmgKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYThmODVhNAotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9TZXF1ZW5jZU51bWJlci5oCkBAIC0wLDAgKzEsNjMgQEAKKy8qLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovCisvKiBDb3B5cmlnaHQgKGMpIEZJUlNUIDIwMTUuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqLworLyogT3BlbiBTb3VyY2UgU29mdHdhcmUgLSBtYXkgYmUgbW9kaWZpZWQgYW5kIHNoYXJlZCBieSBGUkMgdGVhbXMuIFRoZSBjb2RlICAgKi8KKy8qIG11c3QgYmUgYWNjb21wYW5pZWQgYnkgdGhlIEZJUlNUIEJTRCBsaWNlbnNlIGZpbGUgaW4gdGhlIHJvb3QgZGlyZWN0b3J5IG9mICovCisvKiB0aGUgcHJvamVjdC4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqLworLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi8KKworI2lmbmRlZiBOVF9TRVFOVU1fSF8KKyNkZWZpbmUgTlRfU0VRTlVNX0hfCisKK25hbWVzcGFjZSBudCB7CisKKy8qIEEgc2VxdWVuY2UgbnVtYmVyIHBlciBSRkMgMTk4MiAqLworY2xhc3MgU2VxdWVuY2VOdW1iZXIgeworIHB1YmxpYzoKKyAgU2VxdWVuY2VOdW1iZXIoKSA6IG1fdmFsdWUoMCkge30KKyAgZXhwbGljaXQgU2VxdWVuY2VOdW1iZXIodW5zaWduZWQgaW50IHZhbHVlKSA6IG1fdmFsdWUodmFsdWUpIHt9CisgIHVuc2lnbmVkIGludCB2YWx1ZSgpIGNvbnN0IHsgcmV0dXJuIG1fdmFsdWU7IH0KKworICBTZXF1ZW5jZU51bWJlciYgb3BlcmF0b3IrKygpIHsKKyAgICArK21fdmFsdWU7CisgICAgaWYgKG1fdmFsdWUgPiAweGZmZmYpIG1fdmFsdWUgPSAwOworICAgIHJldHVybiAqdGhpczsKKyAgfQorICBTZXF1ZW5jZU51bWJlciBvcGVyYXRvcisrKGludCkgeworICAgIFNlcXVlbmNlTnVtYmVyIHRtcCgqdGhpcyk7CisgICAgb3BlcmF0b3IrKygpOworICAgIHJldHVybiB0bXA7CisgIH0KKworICBmcmllbmQgYm9vbCBvcGVyYXRvcjwoY29uc3QgU2VxdWVuY2VOdW1iZXImIGxocywgY29uc3QgU2VxdWVuY2VOdW1iZXImIHJocyk7CisgIGZyaWVuZCBib29sIG9wZXJhdG9yPihjb25zdCBTZXF1ZW5jZU51bWJlciYgbGhzLCBjb25zdCBTZXF1ZW5jZU51bWJlciYgcmhzKTsKKyAgZnJpZW5kIGJvb2wgb3BlcmF0b3I8PShjb25zdCBTZXF1ZW5jZU51bWJlciYgbGhzLCBjb25zdCBTZXF1ZW5jZU51bWJlciYgcmhzKTsKKyAgZnJpZW5kIGJvb2wgb3BlcmF0b3I+PShjb25zdCBTZXF1ZW5jZU51bWJlciYgbGhzLCBjb25zdCBTZXF1ZW5jZU51bWJlciYgcmhzKTsKKyAgZnJpZW5kIGJvb2wgb3BlcmF0b3I9PShjb25zdCBTZXF1ZW5jZU51bWJlciYgbGhzLCBjb25zdCBTZXF1ZW5jZU51bWJlciYgcmhzKTsKKyAgZnJpZW5kIGJvb2wgb3BlcmF0b3IhPShjb25zdCBTZXF1ZW5jZU51bWJlciYgbGhzLCBjb25zdCBTZXF1ZW5jZU51bWJlciYgcmhzKTsKKworIHByaXZhdGU6CisgIHVuc2lnbmVkIGludCBtX3ZhbHVlOworfTsKKworYm9vbCBvcGVyYXRvcjwoY29uc3QgU2VxdWVuY2VOdW1iZXImIGxocywgY29uc3QgU2VxdWVuY2VOdW1iZXImIHJocyk7Citib29sIG9wZXJhdG9yPihjb25zdCBTZXF1ZW5jZU51bWJlciYgbGhzLCBjb25zdCBTZXF1ZW5jZU51bWJlciYgcmhzKTsKKworaW5saW5lIGJvb2wgb3BlcmF0b3I8PShjb25zdCBTZXF1ZW5jZU51bWJlciYgbGhzLCBjb25zdCBTZXF1ZW5jZU51bWJlciYgcmhzKSB7CisgIHJldHVybiBsaHMgPT0gcmhzIHx8IGxocyA8IHJoczsKK30KKworaW5saW5lIGJvb2wgb3BlcmF0b3I+PShjb25zdCBTZXF1ZW5jZU51bWJlciYgbGhzLCBjb25zdCBTZXF1ZW5jZU51bWJlciYgcmhzKSB7CisgIHJldHVybiBsaHMgPT0gcmhzIHx8IGxocyA+IHJoczsKK30KKworaW5saW5lIGJvb2wgb3BlcmF0b3I9PShjb25zdCBTZXF1ZW5jZU51bWJlciYgbGhzLCBjb25zdCBTZXF1ZW5jZU51bWJlciYgcmhzKSB7CisgIHJldHVybiBsaHMubV92YWx1ZSA9PSByaHMubV92YWx1ZTsKK30KKworaW5saW5lIGJvb2wgb3BlcmF0b3IhPShjb25zdCBTZXF1ZW5jZU51bWJlciYgbGhzLCBjb25zdCBTZXF1ZW5jZU51bWJlciYgcmhzKSB7CisgIHJldHVybiBsaHMubV92YWx1ZSAhPSByaHMubV92YWx1ZTsKK30KKworfSAgLy8gbmFtZXNwYWNlIG50CisKKyNlbmRpZiAgLy8gTlRfU0VRTlVNX0hfCmRpZmYgLS1naXQgYS9zcmMvU3RvcmFnZS5jcHAgYi9zcmMvU3RvcmFnZS5jcHAKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZTI5MDNlMAotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9TdG9yYWdlLmNwcApAQCAtMCwwICsxLDEzODEgQEAKKy8qLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovCisvKiBDb3B5cmlnaHQgKGMpIEZJUlNUIDIwMTUuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqLworLyogT3BlbiBTb3VyY2UgU29mdHdhcmUgLSBtYXkgYmUgbW9kaWZpZWQgYW5kIHNoYXJlZCBieSBGUkMgdGVhbXMuIFRoZSBjb2RlICAgKi8KKy8qIG11c3QgYmUgYWNjb21wYW5pZWQgYnkgdGhlIEZJUlNUIEJTRCBsaWNlbnNlIGZpbGUgaW4gdGhlIHJvb3QgZGlyZWN0b3J5IG9mICovCisvKiB0aGUgcHJvamVjdC4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqLworLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi8KKworI2luY2x1ZGUgIlN0b3JhZ2UuaCIKKworI2luY2x1ZGUgPGNjdHlwZT4KKyNpbmNsdWRlIDxzdHJpbmc+CisjaW5jbHVkZSA8dHVwbGU+CisKKyNpbmNsdWRlICJsbHZtL1N0cmluZ0V4dHJhcy5oIgorI2luY2x1ZGUgIkJhc2U2NC5oIgorI2luY2x1ZGUgIkxvZy5oIgorI2luY2x1ZGUgIk5ldHdvcmtDb25uZWN0aW9uLmgiCisKK3VzaW5nIG5hbWVzcGFjZSBudDsKKworQVRPTUlDX1NUQVRJQ19JTklUKFN0b3JhZ2UpCisKK1N0b3JhZ2U6OlN0b3JhZ2UoKQorICAgIDogU3RvcmFnZShOb3RpZmllcjo6R2V0SW5zdGFuY2UoKSwgUnBjU2VydmVyOjpHZXRJbnN0YW5jZSgpKSB7fQorCitTdG9yYWdlOjpTdG9yYWdlKE5vdGlmaWVyJiBub3RpZmllciwgUnBjU2VydmVyJiBycGNfc2VydmVyKQorICAgIDogbV9ub3RpZmllcihub3RpZmllciksIG1fcnBjX3NlcnZlcihycGNfc2VydmVyKSB7CisgIG1fdGVybWluYXRpbmcgPSBmYWxzZTsKK30KKworU3RvcmFnZTo6flN0b3JhZ2UoKSB7CisgIExvZ2dlcjo6R2V0SW5zdGFuY2UoKS5TZXRMb2dnZXIobnVsbHB0cik7CisgIG1fdGVybWluYXRpbmcgPSB0cnVlOworICBtX3JwY19yZXN1bHRzX2NvbmQubm90aWZ5X2FsbCgpOworfQorCit2b2lkIFN0b3JhZ2U6OlNldE91dGdvaW5nKFF1ZXVlT3V0Z29pbmdGdW5jIHF1ZXVlX291dGdvaW5nLCBib29sIHNlcnZlcikgeworICBzdGQ6OmxvY2tfZ3VhcmQ8c3RkOjptdXRleD4gbG9jayhtX211dGV4KTsKKyAgbV9xdWV1ZV9vdXRnb2luZyA9IHF1ZXVlX291dGdvaW5nOworICBtX3NlcnZlciA9IHNlcnZlcjsKK30KKwordm9pZCBTdG9yYWdlOjpDbGVhck91dGdvaW5nKCkgeworICBtX3F1ZXVlX291dGdvaW5nID0gbnVsbHB0cjsKK30KKworTlRfVHlwZSBTdG9yYWdlOjpHZXRFbnRyeVR5cGUodW5zaWduZWQgaW50IGlkKSBjb25zdCB7CisgIHN0ZDo6bG9ja19ndWFyZDxzdGQ6Om11dGV4PiBsb2NrKG1fbXV0ZXgpOworICBpZiAoaWQgPj0gbV9pZG1hcC5zaXplKCkpIHJldHVybiBOVF9VTkFTU0lHTkVEOworICBFbnRyeSogZW50cnkgPSBtX2lkbWFwW2lkXTsKKyAgaWYgKCFlbnRyeSB8fCAhZW50cnktPnZhbHVlKSByZXR1cm4gTlRfVU5BU1NJR05FRDsKKyAgcmV0dXJuIGVudHJ5LT52YWx1ZS0+dHlwZSgpOworfQorCit2b2lkIFN0b3JhZ2U6OlByb2Nlc3NJbmNvbWluZyhzdGQ6OnNoYXJlZF9wdHI8TWVzc2FnZT4gbXNnLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTmV0d29ya0Nvbm5lY3Rpb24qIGNvbm4sCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdGQ6OndlYWtfcHRyPE5ldHdvcmtDb25uZWN0aW9uPiBjb25uX3dlYWspIHsKKyAgc3RkOjp1bmlxdWVfbG9jazxzdGQ6Om11dGV4PiBsb2NrKG1fbXV0ZXgpOworICBzd2l0Y2ggKG1zZy0+dHlwZSgpKSB7CisgICAgY2FzZSBNZXNzYWdlOjprS2VlcEFsaXZlOgorICAgICAgYnJlYWs7ICAvLyBpZ25vcmUKKyAgICBjYXNlIE1lc3NhZ2U6OmtDbGllbnRIZWxsbzoKKyAgICBjYXNlIE1lc3NhZ2U6OmtQcm90b1Vuc3VwOgorICAgIGNhc2UgTWVzc2FnZTo6a1NlcnZlckhlbGxvRG9uZToKKyAgICBjYXNlIE1lc3NhZ2U6OmtTZXJ2ZXJIZWxsbzoKKyAgICBjYXNlIE1lc3NhZ2U6OmtDbGllbnRIZWxsb0RvbmU6CisgICAgICAvLyBzaG91bGRuJ3QgZ2V0IHRoZXNlLCBidXQgaWdub3JlIGlmIHdlIGRvCisgICAgICBicmVhazsKKyAgICBjYXNlIE1lc3NhZ2U6OmtFbnRyeUFzc2lnbjogeworICAgICAgdW5zaWduZWQgaW50IGlkID0gbXNnLT5pZCgpOworICAgICAgU3RyaW5nUmVmIG5hbWUgPSBtc2ctPnN0cigpOworICAgICAgRW50cnkqIGVudHJ5OworICAgICAgYm9vbCBtYXlfbmVlZF91cGRhdGUgPSBmYWxzZTsKKyAgICAgIGlmIChtX3NlcnZlcikgeworICAgICAgICAvLyBpZiB3ZSdyZSBhIHNlcnZlciwgaWQ9MHhmZmZmIHJlcXVlc3RzIGFyZSByZXF1ZXN0cyBmb3IgYW4gaWQKKyAgICAgICAgLy8gdG8gYmUgYXNzaWduZWQsIGFuZCB3ZSBuZWVkIHRvIHNlbmQgdGhlIG5ldyBhc3NpZ25tZW50IGJhY2sgdG8KKyAgICAgICAgLy8gdGhlIHNlbmRlciBhcyB3ZWxsIGFzIGFsbCBvdGhlciBjb25uZWN0aW9ucy4KKyAgICAgICAgaWYgKGlkID09IDB4ZmZmZikgeworICAgICAgICAgIC8vIHNlZSBpZiBpdCB3YXMgYWxyZWFkeSBhc3NpZ25lZDsgaWdub3JlIGlmIHNvLgorICAgICAgICAgIGlmIChtX2VudHJpZXMuY291bnQobmFtZSkgIT0gMCkgcmV0dXJuOworCisgICAgICAgICAgLy8gY3JlYXRlIGl0IGxvY2FsbHkKKyAgICAgICAgICBpZCA9IG1faWRtYXAuc2l6ZSgpOworICAgICAgICAgIGF1dG8mIG5ld19lbnRyeSA9IG1fZW50cmllc1tuYW1lXTsKKyAgICAgICAgICBpZiAoIW5ld19lbnRyeSkgbmV3X2VudHJ5LnJlc2V0KG5ldyBFbnRyeShuYW1lKSk7CisgICAgICAgICAgZW50cnkgPSBuZXdfZW50cnkuZ2V0KCk7CisgICAgICAgICAgZW50cnktPnZhbHVlID0gbXNnLT52YWx1ZSgpOworICAgICAgICAgIGVudHJ5LT5mbGFncyA9IG1zZy0+ZmxhZ3MoKTsKKyAgICAgICAgICBlbnRyeS0+aWQgPSBpZDsKKyAgICAgICAgICBtX2lkbWFwLnB1c2hfYmFjayhlbnRyeSk7CisKKyAgICAgICAgICAvLyB1cGRhdGUgcGVyc2lzdGVudCBkaXJ0eSBmbGFnIGlmIGl0J3MgcGVyc2lzdGVudAorICAgICAgICAgIGlmIChlbnRyeS0+SXNQZXJzaXN0ZW50KCkpIG1fcGVyc2lzdGVudF9kaXJ0eSA9IHRydWU7CisKKyAgICAgICAgICAvLyBub3RpZnkKKyAgICAgICAgICBtX25vdGlmaWVyLk5vdGlmeUVudHJ5KG5hbWUsIGVudHJ5LT52YWx1ZSwgTlRfTk9USUZZX05FVyk7CisKKyAgICAgICAgICAvLyBzZW5kIHRoZSBhc3NpZ25tZW50IHRvIGV2ZXJ5b25lIChpbmNsdWRpbmcgdGhlIG9yaWdpbmF0b3IpCisgICAgICAgICAgaWYgKG1fcXVldWVfb3V0Z29pbmcpIHsKKyAgICAgICAgICAgIGF1dG8gcXVldWVfb3V0Z29pbmcgPSBtX3F1ZXVlX291dGdvaW5nOworICAgICAgICAgICAgYXV0byBvdXRtc2cgPSBNZXNzYWdlOjpFbnRyeUFzc2lnbigKKyAgICAgICAgICAgICAgICBuYW1lLCBpZCwgZW50cnktPnNlcV9udW0udmFsdWUoKSwgbXNnLT52YWx1ZSgpLCBtc2ctPmZsYWdzKCkpOworICAgICAgICAgICAgbG9jay51bmxvY2soKTsKKyAgICAgICAgICAgIHF1ZXVlX291dGdvaW5nKG91dG1zZywgbnVsbHB0ciwgbnVsbHB0cik7CisgICAgICAgICAgfQorICAgICAgICAgIHJldHVybjsKKyAgICAgICAgfQorICAgICAgICBpZiAoaWQgPj0gbV9pZG1hcC5zaXplKCkgfHwgIW1faWRtYXBbaWRdKSB7CisgICAgICAgICAgLy8gaWdub3JlIGFyYml0cmFyeSBlbnRyeSBhc3NpZ25tZW50cworICAgICAgICAgIC8vIHRoaXMgY2FuIGhhcHBlbiBkdWUgdG8gZS5nLiBhc3NpZ25tZW50IHRvIGRlbGV0ZWQgZW50cnkKKyAgICAgICAgICBsb2NrLnVubG9jaygpOworICAgICAgICAgIERFQlVHKCJzZXJ2ZXI6IHJlY2VpdmVkIGFzc2lnbm1lbnQgdG8gdW5rbm93biBlbnRyeSIpOworICAgICAgICAgIHJldHVybjsKKyAgICAgICAgfQorICAgICAgICBlbnRyeSA9IG1faWRtYXBbaWRdOworICAgICAgfSBlbHNlIHsKKyAgICAgICAgLy8gY2xpZW50cyBzaW1wbHkgYWNjZXB0IG5ldyBhc3NpZ25tZW50cworICAgICAgICBpZiAoaWQgPT0gMHhmZmZmKSB7CisgICAgICAgICAgbG9jay51bmxvY2soKTsKKyAgICAgICAgICBERUJVRygiY2xpZW50OiByZWNlaXZlZCBlbnRyeSBhc3NpZ25tZW50IHJlcXVlc3Q/Iik7CisgICAgICAgICAgcmV0dXJuOworICAgICAgICB9CisgICAgICAgIGlmIChpZCA+PSBtX2lkbWFwLnNpemUoKSkgbV9pZG1hcC5yZXNpemUoaWQrMSk7CisgICAgICAgIGVudHJ5ID0gbV9pZG1hcFtpZF07CisgICAgICAgIGlmICghZW50cnkpIHsKKyAgICAgICAgICAvLyBjcmVhdGUgbG9jYWwKKyAgICAgICAgICBhdXRvJiBuZXdfZW50cnkgPSBtX2VudHJpZXNbbmFtZV07CisgICAgICAgICAgaWYgKCFuZXdfZW50cnkpIHsKKyAgICAgICAgICAgIC8vIGRpZG4ndCBleGlzdCBhdCBhbGwgKHJhdGhlciB0aGFuIGp1c3QgYmVpbmcgYSByZXNwb25zZSB0byBhCisgICAgICAgICAgICAvLyBpZCBhc3NpZ25tZW50IHJlcXVlc3QpCisgICAgICAgICAgICBuZXdfZW50cnkucmVzZXQobmV3IEVudHJ5KG5hbWUpKTsKKyAgICAgICAgICAgIG5ld19lbnRyeS0+dmFsdWUgPSBtc2ctPnZhbHVlKCk7CisgICAgICAgICAgICBuZXdfZW50cnktPmZsYWdzID0gbXNnLT5mbGFncygpOworICAgICAgICAgICAgbmV3X2VudHJ5LT5pZCA9IGlkOworICAgICAgICAgICAgbV9pZG1hcFtpZF0gPSBuZXdfZW50cnkuZ2V0KCk7CisKKyAgICAgICAgICAgIC8vIG5vdGlmeQorICAgICAgICAgICAgbV9ub3RpZmllci5Ob3RpZnlFbnRyeShuYW1lLCBuZXdfZW50cnktPnZhbHVlLCBOVF9OT1RJRllfTkVXKTsKKyAgICAgICAgICAgIHJldHVybjsKKyAgICAgICAgICB9CisgICAgICAgICAgbWF5X25lZWRfdXBkYXRlID0gdHJ1ZTsgIC8vIHdlIG1heSBuZWVkIHRvIHNlbmQgYW4gdXBkYXRlIG1lc3NhZ2UKKyAgICAgICAgICBlbnRyeSA9IG5ld19lbnRyeS5nZXQoKTsKKyAgICAgICAgICBlbnRyeS0+aWQgPSBpZDsKKyAgICAgICAgICBtX2lkbWFwW2lkXSA9IGVudHJ5OworCisgICAgICAgICAgLy8gaWYgdGhlIHJlY2VpdmVkIGZsYWdzIGRvbid0IG1hdGNoIHdoYXQgd2Ugc2VudCwgd2UgbW9zdCBsaWtlbHkKKyAgICAgICAgICAvLyB1cGRhdGVkIGZsYWdzIGxvY2FsbHkgaW4gdGhlIGludGVyaW07IHNlbmQgZmxhZ3MgdXBkYXRlIG1lc3NhZ2UuCisgICAgICAgICAgaWYgKG1zZy0+ZmxhZ3MoKSAhPSBlbnRyeS0+ZmxhZ3MpIHsKKyAgICAgICAgICAgIGF1dG8gcXVldWVfb3V0Z29pbmcgPSBtX3F1ZXVlX291dGdvaW5nOworICAgICAgICAgICAgYXV0byBvdXRtc2cgPSBNZXNzYWdlOjpGbGFnc1VwZGF0ZShpZCwgZW50cnktPmZsYWdzKTsKKyAgICAgICAgICAgIGxvY2sudW5sb2NrKCk7CisgICAgICAgICAgICBxdWV1ZV9vdXRnb2luZyhvdXRtc2csIG51bGxwdHIsIG51bGxwdHIpOworICAgICAgICAgICAgbG9jay5sb2NrKCk7CisgICAgICAgICAgfQorICAgICAgICB9CisgICAgICB9CisKKyAgICAgIC8vIGNvbW1vbiBjbGllbnQgYW5kIHNlcnZlciBoYW5kbGluZworCisgICAgICAvLyBhbHJlYWR5IGV4aXN0czsgaWdub3JlIGlmIHNlcXVlbmNlIG51bWJlciBub3QgaGlnaGVyIHRoYW4gbG9jYWwKKyAgICAgIFNlcXVlbmNlTnVtYmVyIHNlcV9udW0obXNnLT5zZXFfbnVtX3VpZCgpKTsKKyAgICAgIGlmIChzZXFfbnVtIDwgZW50cnktPnNlcV9udW0pIHsKKyAgICAgICAgaWYgKG1heV9uZWVkX3VwZGF0ZSkgeworICAgICAgICAgIGF1dG8gcXVldWVfb3V0Z29pbmcgPSBtX3F1ZXVlX291dGdvaW5nOworICAgICAgICAgIGF1dG8gb3V0bXNnID0gTWVzc2FnZTo6RW50cnlVcGRhdGUoZW50cnktPmlkLCBlbnRyeS0+c2VxX251bS52YWx1ZSgpLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZW50cnktPnZhbHVlKTsKKyAgICAgICAgICBsb2NrLnVubG9jaygpOworICAgICAgICAgIHF1ZXVlX291dGdvaW5nKG91dG1zZywgbnVsbHB0ciwgbnVsbHB0cik7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuOworICAgICAgfQorCisgICAgICAvLyBzYW5pdHkgY2hlY2s6IG5hbWUgc2hvdWxkIG1hdGNoIGlkCisgICAgICBpZiAobXNnLT5zdHIoKSAhPSBlbnRyeS0+bmFtZSkgeworICAgICAgICBsb2NrLnVubG9jaygpOworICAgICAgICBERUJVRygiZW50cnkgYXNzaWdubWVudCBmb3Igc2FtZSBpZCB3aXRoIGRpZmZlcmVudCBuYW1lPyIpOworICAgICAgICByZXR1cm47CisgICAgICB9CisKKyAgICAgIHVuc2lnbmVkIGludCBub3RpZnlfZmxhZ3MgPSBOVF9OT1RJRllfVVBEQVRFOworCisgICAgICAvLyBkb24ndCB1cGRhdGUgZmxhZ3MgZnJvbSBhIDwzLjAgcmVtb3RlIChub3QgcGFydCBvZiBtZXNzYWdlKQorICAgICAgLy8gZG9uJ3QgdXBkYXRlIGZsYWdzIGlmIHRoaXMgaXMgYSBzZXJ2ZXIgcmVzcG9uc2UgdG8gYSBjbGllbnQgaWQgcmVxdWVzdAorICAgICAgaWYgKCFtYXlfbmVlZF91cGRhdGUgJiYgY29ubi0+cHJvdG9fcmV2KCkgPj0gMHgwMzAwKSB7CisgICAgICAgIC8vIHVwZGF0ZSBwZXJzaXN0ZW50IGRpcnR5IGZsYWcgaWYgcGVyc2lzdGVudCBmbGFnIGNoYW5nZWQKKyAgICAgICAgaWYgKChlbnRyeS0+ZmxhZ3MgJiBOVF9QRVJTSVNURU5UKSAhPSAobXNnLT5mbGFncygpICYgTlRfUEVSU0lTVEVOVCkpCisgICAgICAgICAgbV9wZXJzaXN0ZW50X2RpcnR5ID0gdHJ1ZTsKKyAgICAgICAgaWYgKGVudHJ5LT5mbGFncyAhPSBtc2ctPmZsYWdzKCkpCisgICAgICAgICAgbm90aWZ5X2ZsYWdzIHw9IE5UX05PVElGWV9GTEFHUzsKKyAgICAgICAgZW50cnktPmZsYWdzID0gbXNnLT5mbGFncygpOworICAgICAgfQorCisgICAgICAvLyB1cGRhdGUgcGVyc2lzdGVudCBkaXJ0eSBmbGFnIGlmIHRoZSB2YWx1ZSBjaGFuZ2VkIGFuZCBpdCdzIHBlcnNpc3RlbnQKKyAgICAgIGlmIChlbnRyeS0+SXNQZXJzaXN0ZW50KCkgJiYgKmVudHJ5LT52YWx1ZSAhPSAqbXNnLT52YWx1ZSgpKQorICAgICAgICBtX3BlcnNpc3RlbnRfZGlydHkgPSB0cnVlOworCisgICAgICAvLyB1cGRhdGUgbG9jYWwKKyAgICAgIGVudHJ5LT52YWx1ZSA9IG1zZy0+dmFsdWUoKTsKKyAgICAgIGVudHJ5LT5zZXFfbnVtID0gc2VxX251bTsKKworICAgICAgLy8gbm90aWZ5CisgICAgICBtX25vdGlmaWVyLk5vdGlmeUVudHJ5KG5hbWUsIGVudHJ5LT52YWx1ZSwgbm90aWZ5X2ZsYWdzKTsKKworICAgICAgLy8gYnJvYWRjYXN0IHRvIGFsbCBvdGhlciBjb25uZWN0aW9ucyAobm90ZSBmb3IgY2xpZW50IHRoZXJlIHdvbid0CisgICAgICAvLyBiZSBhbnkgb3RoZXIgY29ubmVjdGlvbnMsIHNvIGRvbid0IGJvdGhlcikKKyAgICAgIGlmIChtX3NlcnZlciAmJiBtX3F1ZXVlX291dGdvaW5nKSB7CisgICAgICAgIGF1dG8gcXVldWVfb3V0Z29pbmcgPSBtX3F1ZXVlX291dGdvaW5nOworICAgICAgICBhdXRvIG91dG1zZyA9CisgICAgICAgICAgICBNZXNzYWdlOjpFbnRyeUFzc2lnbihlbnRyeS0+bmFtZSwgaWQsIG1zZy0+c2VxX251bV91aWQoKSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1zZy0+dmFsdWUoKSwgZW50cnktPmZsYWdzKTsKKyAgICAgICAgbG9jay51bmxvY2soKTsKKyAgICAgICAgcXVldWVfb3V0Z29pbmcob3V0bXNnLCBudWxscHRyLCBjb25uKTsKKyAgICAgIH0KKyAgICAgIGJyZWFrOworICAgIH0KKyAgICBjYXNlIE1lc3NhZ2U6OmtFbnRyeVVwZGF0ZTogeworICAgICAgdW5zaWduZWQgaW50IGlkID0gbXNnLT5pZCgpOworICAgICAgaWYgKGlkID49IG1faWRtYXAuc2l6ZSgpIHx8ICFtX2lkbWFwW2lkXSkgeworICAgICAgICAvLyBpZ25vcmUgYXJiaXRyYXJ5IGVudHJ5IHVwZGF0ZXM7CisgICAgICAgIC8vIHRoaXMgY2FuIGhhcHBlbiBkdWUgdG8gZGVsZXRlZCBlbnRyaWVzCisgICAgICAgIGxvY2sudW5sb2NrKCk7CisgICAgICAgIERFQlVHKCJyZWNlaXZlZCB1cGRhdGUgdG8gdW5rbm93biBlbnRyeSIpOworICAgICAgICByZXR1cm47CisgICAgICB9CisgICAgICBFbnRyeSogZW50cnkgPSBtX2lkbWFwW2lkXTsKKworICAgICAgLy8gaWdub3JlIGlmIHNlcXVlbmNlIG51bWJlciBub3QgaGlnaGVyIHRoYW4gbG9jYWwKKyAgICAgIFNlcXVlbmNlTnVtYmVyIHNlcV9udW0obXNnLT5zZXFfbnVtX3VpZCgpKTsKKyAgICAgIGlmIChzZXFfbnVtIDw9IGVudHJ5LT5zZXFfbnVtKSByZXR1cm47CisKKyAgICAgIC8vIHVwZGF0ZSBsb2NhbAorICAgICAgZW50cnktPnZhbHVlID0gbXNnLT52YWx1ZSgpOworICAgICAgZW50cnktPnNlcV9udW0gPSBzZXFfbnVtOworCisgICAgICAvLyB1cGRhdGUgcGVyc2lzdGVudCBkaXJ0eSBmbGFnIGlmIGl0J3MgYSBwZXJzaXN0ZW50IHZhbHVlCisgICAgICBpZiAoZW50cnktPklzUGVyc2lzdGVudCgpKSBtX3BlcnNpc3RlbnRfZGlydHkgPSB0cnVlOworCisgICAgICAvLyBub3RpZnkKKyAgICAgIG1fbm90aWZpZXIuTm90aWZ5RW50cnkoZW50cnktPm5hbWUsIGVudHJ5LT52YWx1ZSwgTlRfTk9USUZZX1VQREFURSk7CisKKyAgICAgIC8vIGJyb2FkY2FzdCB0byBhbGwgb3RoZXIgY29ubmVjdGlvbnMgKG5vdGUgZm9yIGNsaWVudCB0aGVyZSB3b24ndAorICAgICAgLy8gYmUgYW55IG90aGVyIGNvbm5lY3Rpb25zLCBzbyBkb24ndCBib3RoZXIpCisgICAgICBpZiAobV9zZXJ2ZXIgJiYgbV9xdWV1ZV9vdXRnb2luZykgeworICAgICAgICBhdXRvIHF1ZXVlX291dGdvaW5nID0gbV9xdWV1ZV9vdXRnb2luZzsKKyAgICAgICAgbG9jay51bmxvY2soKTsKKyAgICAgICAgcXVldWVfb3V0Z29pbmcobXNnLCBudWxscHRyLCBjb25uKTsKKyAgICAgIH0KKyAgICAgIGJyZWFrOworICAgIH0KKyAgICBjYXNlIE1lc3NhZ2U6OmtGbGFnc1VwZGF0ZTogeworICAgICAgdW5zaWduZWQgaW50IGlkID0gbXNnLT5pZCgpOworICAgICAgaWYgKGlkID49IG1faWRtYXAuc2l6ZSgpIHx8ICFtX2lkbWFwW2lkXSkgeworICAgICAgICAvLyBpZ25vcmUgYXJiaXRyYXJ5IGVudHJ5IHVwZGF0ZXM7CisgICAgICAgIC8vIHRoaXMgY2FuIGhhcHBlbiBkdWUgdG8gZGVsZXRlZCBlbnRyaWVzCisgICAgICAgIGxvY2sudW5sb2NrKCk7CisgICAgICAgIERFQlVHKCJyZWNlaXZlZCBmbGFncyB1cGRhdGUgdG8gdW5rbm93biBlbnRyeSIpOworICAgICAgICByZXR1cm47CisgICAgICB9CisgICAgICBFbnRyeSogZW50cnkgPSBtX2lkbWFwW2lkXTsKKworICAgICAgLy8gaWdub3JlIGlmIGZsYWdzIGRpZG4ndCBhY3R1YWxseSBjaGFuZ2UKKyAgICAgIGlmIChlbnRyeS0+ZmxhZ3MgPT0gbXNnLT5mbGFncygpKSByZXR1cm47CisKKyAgICAgIC8vIHVwZGF0ZSBwZXJzaXN0ZW50IGRpcnR5IGZsYWcgaWYgcGVyc2lzdGVudCBmbGFnIGNoYW5nZWQKKyAgICAgIGlmICgoZW50cnktPmZsYWdzICYgTlRfUEVSU0lTVEVOVCkgIT0gKG1zZy0+ZmxhZ3MoKSAmIE5UX1BFUlNJU1RFTlQpKQorICAgICAgICBtX3BlcnNpc3RlbnRfZGlydHkgPSB0cnVlOworCisgICAgICAvLyB1cGRhdGUgbG9jYWwKKyAgICAgIGVudHJ5LT5mbGFncyA9IG1zZy0+ZmxhZ3MoKTsKKworICAgICAgLy8gbm90aWZ5CisgICAgICBtX25vdGlmaWVyLk5vdGlmeUVudHJ5KGVudHJ5LT5uYW1lLCBlbnRyeS0+dmFsdWUsIE5UX05PVElGWV9GTEFHUyk7CisKKyAgICAgIC8vIGJyb2FkY2FzdCB0byBhbGwgb3RoZXIgY29ubmVjdGlvbnMgKG5vdGUgZm9yIGNsaWVudCB0aGVyZSB3b24ndAorICAgICAgLy8gYmUgYW55IG90aGVyIGNvbm5lY3Rpb25zLCBzbyBkb24ndCBib3RoZXIpCisgICAgICBpZiAobV9zZXJ2ZXIgJiYgbV9xdWV1ZV9vdXRnb2luZykgeworICAgICAgICBhdXRvIHF1ZXVlX291dGdvaW5nID0gbV9xdWV1ZV9vdXRnb2luZzsKKyAgICAgICAgbG9jay51bmxvY2soKTsKKyAgICAgICAgcXVldWVfb3V0Z29pbmcobXNnLCBudWxscHRyLCBjb25uKTsKKyAgICAgIH0KKyAgICAgIGJyZWFrOworICAgIH0KKyAgICBjYXNlIE1lc3NhZ2U6OmtFbnRyeURlbGV0ZTogeworICAgICAgdW5zaWduZWQgaW50IGlkID0gbXNnLT5pZCgpOworICAgICAgaWYgKGlkID49IG1faWRtYXAuc2l6ZSgpIHx8ICFtX2lkbWFwW2lkXSkgeworICAgICAgICAvLyBpZ25vcmUgYXJiaXRyYXJ5IGVudHJ5IHVwZGF0ZXM7CisgICAgICAgIC8vIHRoaXMgY2FuIGhhcHBlbiBkdWUgdG8gZGVsZXRlZCBlbnRyaWVzCisgICAgICAgIGxvY2sudW5sb2NrKCk7CisgICAgICAgIERFQlVHKCJyZWNlaXZlZCBkZWxldGUgdG8gdW5rbm93biBlbnRyeSIpOworICAgICAgICByZXR1cm47CisgICAgICB9CisgICAgICBFbnRyeSogZW50cnkgPSBtX2lkbWFwW2lkXTsKKworICAgICAgLy8gdXBkYXRlIHBlcnNpc3RlbnQgZGlydHkgZmxhZyBpZiBpdCdzIGEgcGVyc2lzdGVudCB2YWx1ZQorICAgICAgaWYgKGVudHJ5LT5Jc1BlcnNpc3RlbnQoKSkgbV9wZXJzaXN0ZW50X2RpcnR5ID0gdHJ1ZTsKKworICAgICAgLy8gZGVsZXRlIGl0IGZyb20gaWRtYXAKKyAgICAgIG1faWRtYXBbaWRdID0gbnVsbHB0cjsKKworICAgICAgLy8gZ2V0IGVudHJ5IChhcyB3ZSdsbCBuZWVkIGl0IGZvciBub3RpZnkpIGFuZCBlcmFzZSBpdCBmcm9tIHRoZSBtYXAKKyAgICAgIC8vIGl0IHNob3VsZCBhbHdheXMgYmUgaW4gdGhlIG1hcCwgYnV0IHNhbml0eSBjaGVjayBqdXN0IGluIGNhc2UKKyAgICAgIGF1dG8gaSA9IG1fZW50cmllcy5maW5kKGVudHJ5LT5uYW1lKTsKKyAgICAgIGlmIChpICE9IG1fZW50cmllcy5lbmQoKSkgeworICAgICAgICBhdXRvIGVudHJ5MiA9IHN0ZDo6bW92ZShpLT5nZXRWYWx1ZSgpKTsgIC8vIG1vdmUgdGhlIHZhbHVlIG91dAorICAgICAgICBtX2VudHJpZXMuZXJhc2UoaSk7CisKKyAgICAgICAgLy8gbm90aWZ5CisgICAgICAgIG1fbm90aWZpZXIuTm90aWZ5RW50cnkoZW50cnkyLT5uYW1lLCBlbnRyeTItPnZhbHVlLCBOVF9OT1RJRllfREVMRVRFKTsKKyAgICAgIH0KKworICAgICAgLy8gYnJvYWRjYXN0IHRvIGFsbCBvdGhlciBjb25uZWN0aW9ucyAobm90ZSBmb3IgY2xpZW50IHRoZXJlIHdvbid0CisgICAgICAvLyBiZSBhbnkgb3RoZXIgY29ubmVjdGlvbnMsIHNvIGRvbid0IGJvdGhlcikKKyAgICAgIGlmIChtX3NlcnZlciAmJiBtX3F1ZXVlX291dGdvaW5nKSB7CisgICAgICAgIGF1dG8gcXVldWVfb3V0Z29pbmcgPSBtX3F1ZXVlX291dGdvaW5nOworICAgICAgICBsb2NrLnVubG9jaygpOworICAgICAgICBxdWV1ZV9vdXRnb2luZyhtc2csIG51bGxwdHIsIGNvbm4pOworICAgICAgfQorICAgICAgYnJlYWs7CisgICAgfQorICAgIGNhc2UgTWVzc2FnZTo6a0NsZWFyRW50cmllczogeworICAgICAgLy8gdXBkYXRlIGxvY2FsCisgICAgICBFbnRyaWVzTWFwIG1hcDsKKyAgICAgIG1fZW50cmllcy5zd2FwKG1hcCk7CisgICAgICBtX2lkbWFwLnJlc2l6ZSgwKTsKKworICAgICAgLy8gc2V0IHBlcnNpc3RlbnQgZGlydHkgZmxhZworICAgICAgbV9wZXJzaXN0ZW50X2RpcnR5ID0gdHJ1ZTsKKworICAgICAgLy8gbm90aWZ5CisgICAgICBmb3IgKGF1dG8mIGVudHJ5IDogbWFwKQorICAgICAgICBtX25vdGlmaWVyLk5vdGlmeUVudHJ5KGVudHJ5LmdldEtleSgpLCBlbnRyeS5nZXRWYWx1ZSgpLT52YWx1ZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBOVF9OT1RJRllfREVMRVRFKTsKKworICAgICAgLy8gYnJvYWRjYXN0IHRvIGFsbCBvdGhlciBjb25uZWN0aW9ucyAobm90ZSBmb3IgY2xpZW50IHRoZXJlIHdvbid0CisgICAgICAvLyBiZSBhbnkgb3RoZXIgY29ubmVjdGlvbnMsIHNvIGRvbid0IGJvdGhlcikKKyAgICAgIGlmIChtX3NlcnZlciAmJiBtX3F1ZXVlX291dGdvaW5nKSB7CisgICAgICAgIGF1dG8gcXVldWVfb3V0Z29pbmcgPSBtX3F1ZXVlX291dGdvaW5nOworICAgICAgICBsb2NrLnVubG9jaygpOworICAgICAgICBxdWV1ZV9vdXRnb2luZyhtc2csIG51bGxwdHIsIGNvbm4pOworICAgICAgfQorICAgICAgYnJlYWs7CisgICAgfQorICAgIGNhc2UgTWVzc2FnZTo6a0V4ZWN1dGVScGM6IHsKKyAgICAgIGlmICghbV9zZXJ2ZXIpIHJldHVybjsgIC8vIG9ubHkgcHJvY2VzcyBvbiBzZXJ2ZXIKKyAgICAgIHVuc2lnbmVkIGludCBpZCA9IG1zZy0+aWQoKTsKKyAgICAgIGlmIChpZCA+PSBtX2lkbWFwLnNpemUoKSB8fCAhbV9pZG1hcFtpZF0pIHsKKyAgICAgICAgLy8gaWdub3JlIGNhbGwgdG8gbm9uLWV4aXN0ZW50IFJQQworICAgICAgICAvLyB0aGlzIGNhbiBoYXBwZW4gZHVlIHRvIGRlbGV0ZWQgZW50cmllcworICAgICAgICBsb2NrLnVubG9jaygpOworICAgICAgICBERUJVRygicmVjZWl2ZWQgUlBDIGNhbGwgdG8gdW5rbm93biBlbnRyeSIpOworICAgICAgICByZXR1cm47CisgICAgICB9CisgICAgICBFbnRyeSogZW50cnkgPSBtX2lkbWFwW2lkXTsKKyAgICAgIGlmICghZW50cnktPnZhbHVlLT5Jc1JwYygpKSB7CisgICAgICAgIGxvY2sudW5sb2NrKCk7CisgICAgICAgIERFQlVHKCJyZWNlaXZlZCBSUEMgY2FsbCB0byBub24tUlBDIGVudHJ5Iik7CisgICAgICAgIHJldHVybjsKKyAgICAgIH0KKyAgICAgIG1fcnBjX3NlcnZlci5Qcm9jZXNzUnBjKGVudHJ5LT5uYW1lLCBtc2csIGVudHJ5LT5ycGNfY2FsbGJhY2ssCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25uLT51aWQoKSwgWz1dKHN0ZDo6c2hhcmVkX3B0cjxNZXNzYWdlPiBtc2cpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYXV0byBjID0gY29ubl93ZWFrLmxvY2soKTsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGMpIGMtPlF1ZXVlT3V0Z29pbmcobXNnKTsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0pOworICAgICAgYnJlYWs7CisgICAgfQorICAgIGNhc2UgTWVzc2FnZTo6a1JwY1Jlc3BvbnNlOiB7CisgICAgICBpZiAobV9zZXJ2ZXIpIHJldHVybjsgIC8vIG9ubHkgcHJvY2VzcyBvbiBjbGllbnQKKyAgICAgIG1fcnBjX3Jlc3VsdHMuaW5zZXJ0KHN0ZDo6bWFrZV9wYWlyKAorICAgICAgICAgIHN0ZDo6bWFrZV9wYWlyKG1zZy0+aWQoKSwgbXNnLT5zZXFfbnVtX3VpZCgpKSwgbXNnLT5zdHIoKSkpOworICAgICAgbV9ycGNfcmVzdWx0c19jb25kLm5vdGlmeV9hbGwoKTsKKyAgICAgIGJyZWFrOworICAgIH0KKyAgICBkZWZhdWx0OgorICAgICAgYnJlYWs7CisgIH0KK30KKwordm9pZCBTdG9yYWdlOjpHZXRJbml0aWFsQXNzaWdubWVudHMoCisgICAgTmV0d29ya0Nvbm5lY3Rpb24mIGNvbm4sIHN0ZDo6dmVjdG9yPHN0ZDo6c2hhcmVkX3B0cjxNZXNzYWdlPj4qIG1zZ3MpIHsKKyAgc3RkOjpsb2NrX2d1YXJkPHN0ZDo6bXV0ZXg+IGxvY2sobV9tdXRleCk7CisgIGNvbm4uc2V0X3N0YXRlKE5ldHdvcmtDb25uZWN0aW9uOjprU3luY2hyb25pemVkKTsKKyAgZm9yIChhdXRvJiBpIDogbV9lbnRyaWVzKSB7CisgICAgRW50cnkqIGVudHJ5ID0gaS5nZXRWYWx1ZSgpLmdldCgpOworICAgIG1zZ3MtPmVtcGxhY2VfYmFjayhNZXNzYWdlOjpFbnRyeUFzc2lnbihpLmdldEtleSgpLCBlbnRyeS0+aWQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVudHJ5LT5zZXFfbnVtLnZhbHVlKCksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVudHJ5LT52YWx1ZSwgZW50cnktPmZsYWdzKSk7CisgIH0KK30KKwordm9pZCBTdG9yYWdlOjpBcHBseUluaXRpYWxBc3NpZ25tZW50cygKKyAgICBOZXR3b3JrQ29ubmVjdGlvbiYgY29ubiwgbGx2bTo6QXJyYXlSZWY8c3RkOjpzaGFyZWRfcHRyPE1lc3NhZ2U+PiBtc2dzLAorICAgIGJvb2wgbmV3X3NlcnZlciwgc3RkOjp2ZWN0b3I8c3RkOjpzaGFyZWRfcHRyPE1lc3NhZ2U+Piogb3V0X21zZ3MpIHsKKyAgc3RkOjp1bmlxdWVfbG9jazxzdGQ6Om11dGV4PiBsb2NrKG1fbXV0ZXgpOworICBpZiAobV9zZXJ2ZXIpIHJldHVybjsgIC8vIHNob3VsZCBub3QgZG8gdGhpcyBvbiBzZXJ2ZXIKKworICBjb25uLnNldF9zdGF0ZShOZXR3b3JrQ29ubmVjdGlvbjo6a1N5bmNocm9uaXplZCk7CisKKyAgc3RkOjp2ZWN0b3I8c3RkOjpzaGFyZWRfcHRyPE1lc3NhZ2U+PiB1cGRhdGVfbXNnczsKKworICAvLyBjbGVhciBleGlzdGluZyBpZCdzCisgIGZvciAoYXV0byYgaSA6IG1fZW50cmllcykgaS5nZXRWYWx1ZSgpLT5pZCA9IDB4ZmZmZjsKKworICAvLyBjbGVhciBleGlzdGluZyBpZG1hcAorICBtX2lkbWFwLnJlc2l6ZSgwKTsKKworICAvLyBhcHBseSBhc3NpZ25tZW50cworICBmb3IgKGF1dG8mIG1zZyA6IG1zZ3MpIHsKKyAgICBpZiAoIW1zZy0+SXMoTWVzc2FnZTo6a0VudHJ5QXNzaWduKSkgeworICAgICAgREVCVUcoImNsaWVudDogcmVjZWl2ZWQgbm9uLWVudHJ5IGFzc2lnbm1lbnQgcmVxdWVzdD8iKTsKKyAgICAgIGNvbnRpbnVlOworICAgIH0KKworICAgIHVuc2lnbmVkIGludCBpZCA9IG1zZy0+aWQoKTsKKyAgICBpZiAoaWQgPT0gMHhmZmZmKSB7CisgICAgICBERUJVRygiY2xpZW50OiByZWNlaXZlZCBlbnRyeSBhc3NpZ25tZW50IHJlcXVlc3Q/Iik7CisgICAgICBjb250aW51ZTsKKyAgICB9CisKKyAgICBTZXF1ZW5jZU51bWJlciBzZXFfbnVtKG1zZy0+c2VxX251bV91aWQoKSk7CisgICAgU3RyaW5nUmVmIG5hbWUgPSBtc2ctPnN0cigpOworCisgICAgYXV0byYgZW50cnkgPSBtX2VudHJpZXNbbmFtZV07CisgICAgaWYgKCFlbnRyeSkgeworICAgICAgLy8gZG9lc24ndCBjdXJyZW50bHkgZXhpc3QKKyAgICAgIGVudHJ5LnJlc2V0KG5ldyBFbnRyeShuYW1lKSk7CisgICAgICBlbnRyeS0+dmFsdWUgPSBtc2ctPnZhbHVlKCk7CisgICAgICBlbnRyeS0+ZmxhZ3MgPSBtc2ctPmZsYWdzKCk7CisgICAgICBlbnRyeS0+c2VxX251bSA9IHNlcV9udW07CisgICAgICAvLyBub3RpZnkKKyAgICAgIG1fbm90aWZpZXIuTm90aWZ5RW50cnkobmFtZSwgZW50cnktPnZhbHVlLCBOVF9OT1RJRllfTkVXKTsKKyAgICB9IGVsc2UgeworICAgICAgLy8gaWYgcmVjb25uZWN0IGFuZCBzZXF1ZW5jZSBudW1iZXIgbm90IGhpZ2hlciB0aGFuIGxvY2FsLCB0aGVuIHdlCisgICAgICAvLyBkb24ndCB1cGRhdGUgdGhlIGxvY2FsIHZhbHVlIGFuZCBpbnN0ZWFkIHNlbmQgaXQgYmFjayB0byB0aGUgc2VydmVyCisgICAgICAvLyBhcyBhbiB1cGRhdGUgbWVzc2FnZQorICAgICAgaWYgKCFuZXdfc2VydmVyICYmIHNlcV9udW0gPD0gZW50cnktPnNlcV9udW0pIHsKKyAgICAgICAgdXBkYXRlX21zZ3MuZW1wbGFjZV9iYWNrKE1lc3NhZ2U6OkVudHJ5VXBkYXRlKAorICAgICAgICAgICAgZW50cnktPmlkLCBlbnRyeS0+c2VxX251bS52YWx1ZSgpLCBlbnRyeS0+dmFsdWUpKTsKKyAgICAgIH0gZWxzZSB7CisgICAgICAgIGVudHJ5LT52YWx1ZSA9IG1zZy0+dmFsdWUoKTsKKyAgICAgICAgZW50cnktPnNlcV9udW0gPSBzZXFfbnVtOworICAgICAgICB1bnNpZ25lZCBpbnQgbm90aWZ5X2ZsYWdzID0gTlRfTk9USUZZX1VQREFURTsKKyAgICAgICAgLy8gZG9uJ3QgdXBkYXRlIGZsYWdzIGZyb20gYSA8My4wIHJlbW90ZSAobm90IHBhcnQgb2YgbWVzc2FnZSkKKyAgICAgICAgaWYgKGNvbm4ucHJvdG9fcmV2KCkgPj0gMHgwMzAwKSB7CisgICAgICAgICAgaWYgKGVudHJ5LT5mbGFncyAhPSBtc2ctPmZsYWdzKCkpIG5vdGlmeV9mbGFncyB8PSBOVF9OT1RJRllfRkxBR1M7CisgICAgICAgICAgZW50cnktPmZsYWdzID0gbXNnLT5mbGFncygpOworICAgICAgICB9CisgICAgICAgIC8vIG5vdGlmeQorICAgICAgICBtX25vdGlmaWVyLk5vdGlmeUVudHJ5KG5hbWUsIGVudHJ5LT52YWx1ZSwgbm90aWZ5X2ZsYWdzKTsKKyAgICAgIH0KKyAgICB9CisKKyAgICAvLyBzZXQgaWQgYW5kIHNhdmUgdG8gaWRtYXAKKyAgICBlbnRyeS0+aWQgPSBpZDsKKyAgICBpZiAoaWQgPj0gbV9pZG1hcC5zaXplKCkpIG1faWRtYXAucmVzaXplKGlkKzEpOworICAgIG1faWRtYXBbaWRdID0gZW50cnkuZ2V0KCk7CisgIH0KKworICAvLyBnZW5lcmF0ZSBhc3NpZ24gbWVzc2FnZXMgZm9yIHVuYXNzaWduZWQgbG9jYWwgZW50cmllcworICBmb3IgKGF1dG8mIGkgOiBtX2VudHJpZXMpIHsKKyAgICBFbnRyeSogZW50cnkgPSBpLmdldFZhbHVlKCkuZ2V0KCk7CisgICAgaWYgKGVudHJ5LT5pZCAhPSAweGZmZmYpIGNvbnRpbnVlOworICAgIG91dF9tc2dzLT5lbXBsYWNlX2JhY2soTWVzc2FnZTo6RW50cnlBc3NpZ24oZW50cnktPm5hbWUsIGVudHJ5LT5pZCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVudHJ5LT5zZXFfbnVtLnZhbHVlKCksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbnRyeS0+dmFsdWUsIGVudHJ5LT5mbGFncykpOworICB9CisgIGF1dG8gcXVldWVfb3V0Z29pbmcgPSBtX3F1ZXVlX291dGdvaW5nOworICBsb2NrLnVubG9jaygpOworICBmb3IgKGF1dG8mIG1zZyA6IHVwZGF0ZV9tc2dzKSBxdWV1ZV9vdXRnb2luZyhtc2csIG51bGxwdHIsIG51bGxwdHIpOworfQorCitzdGQ6OnNoYXJlZF9wdHI8VmFsdWU+IFN0b3JhZ2U6OkdldEVudHJ5VmFsdWUoU3RyaW5nUmVmIG5hbWUpIGNvbnN0IHsKKyAgc3RkOjpsb2NrX2d1YXJkPHN0ZDo6bXV0ZXg+IGxvY2sobV9tdXRleCk7CisgIGF1dG8gaSA9IG1fZW50cmllcy5maW5kKG5hbWUpOworICByZXR1cm4gaSA9PSBtX2VudHJpZXMuZW5kKCkgPyBudWxscHRyIDogaS0+Z2V0VmFsdWUoKS0+dmFsdWU7Cit9CisKK2Jvb2wgU3RvcmFnZTo6U2V0RW50cnlWYWx1ZShTdHJpbmdSZWYgbmFtZSwgc3RkOjpzaGFyZWRfcHRyPFZhbHVlPiB2YWx1ZSkgeworICBpZiAobmFtZS5lbXB0eSgpKSByZXR1cm4gdHJ1ZTsKKyAgaWYgKCF2YWx1ZSkgcmV0dXJuIHRydWU7CisgIHN0ZDo6dW5pcXVlX2xvY2s8c3RkOjptdXRleD4gbG9jayhtX211dGV4KTsKKyAgYXV0byYgbmV3X2VudHJ5ID0gbV9lbnRyaWVzW25hbWVdOworICBpZiAoIW5ld19lbnRyeSkgbmV3X2VudHJ5LnJlc2V0KG5ldyBFbnRyeShuYW1lKSk7CisgIEVudHJ5KiBlbnRyeSA9IG5ld19lbnRyeS5nZXQoKTsKKyAgYXV0byBvbGRfdmFsdWUgPSBlbnRyeS0+dmFsdWU7CisgIGlmIChvbGRfdmFsdWUgJiYgb2xkX3ZhbHVlLT50eXBlKCkgIT0gdmFsdWUtPnR5cGUoKSkKKyAgICByZXR1cm4gZmFsc2U7ICAvLyBlcnJvciBvbiB0eXBlIG1pc21hdGNoCisgIGVudHJ5LT52YWx1ZSA9IHZhbHVlOworCisgIC8vIGlmIHdlJ3JlIHRoZSBzZXJ2ZXIsIGFzc2lnbiBhbiBpZCBpZiBpdCBkb2Vzbid0IGhhdmUgb25lCisgIGlmIChtX3NlcnZlciAmJiBlbnRyeS0+aWQgPT0gMHhmZmZmKSB7CisgICAgdW5zaWduZWQgaW50IGlkID0gbV9pZG1hcC5zaXplKCk7CisgICAgZW50cnktPmlkID0gaWQ7CisgICAgbV9pZG1hcC5wdXNoX2JhY2soZW50cnkpOworICB9CisKKyAgLy8gdXBkYXRlIHBlcnNpc3RlbnQgZGlydHkgZmxhZyBpZiB2YWx1ZSBjaGFuZ2VkIGFuZCBpdCdzIHBlcnNpc3RlbnQKKyAgaWYgKGVudHJ5LT5Jc1BlcnNpc3RlbnQoKSAmJiAqb2xkX3ZhbHVlICE9ICp2YWx1ZSkgbV9wZXJzaXN0ZW50X2RpcnR5ID0gdHJ1ZTsKKworICAvLyBub3RpZnkgKGZvciBsb2NhbCBsaXN0ZW5lcnMpCisgIGlmIChtX25vdGlmaWVyLmxvY2FsX25vdGlmaWVycygpKSB7CisgICAgaWYgKCFvbGRfdmFsdWUpCisgICAgICBtX25vdGlmaWVyLk5vdGlmeUVudHJ5KG5hbWUsIHZhbHVlLCBOVF9OT1RJRllfTkVXIHwgTlRfTk9USUZZX0xPQ0FMKTsKKyAgICBlbHNlIGlmICgqb2xkX3ZhbHVlICE9ICp2YWx1ZSkKKyAgICAgIG1fbm90aWZpZXIuTm90aWZ5RW50cnkobmFtZSwgdmFsdWUsIE5UX05PVElGWV9VUERBVEUgfCBOVF9OT1RJRllfTE9DQUwpOworICB9CisKKyAgLy8gZ2VuZXJhdGUgbWVzc2FnZQorICBpZiAoIW1fcXVldWVfb3V0Z29pbmcpIHJldHVybiB0cnVlOworICBhdXRvIHF1ZXVlX291dGdvaW5nID0gbV9xdWV1ZV9vdXRnb2luZzsKKyAgaWYgKCFvbGRfdmFsdWUpIHsKKyAgICBhdXRvIG1zZyA9IE1lc3NhZ2U6OkVudHJ5QXNzaWduKG5hbWUsIGVudHJ5LT5pZCwgZW50cnktPnNlcV9udW0udmFsdWUoKSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhbHVlLCBlbnRyeS0+ZmxhZ3MpOworICAgIGxvY2sudW5sb2NrKCk7CisgICAgcXVldWVfb3V0Z29pbmcobXNnLCBudWxscHRyLCBudWxscHRyKTsKKyAgfSBlbHNlIGlmICgqb2xkX3ZhbHVlICE9ICp2YWx1ZSkgeworICAgICsrZW50cnktPnNlcV9udW07CisgICAgLy8gZG9uJ3Qgc2VuZCBhbiB1cGRhdGUgaWYgd2UgZG9uJ3QgaGF2ZSBhbiBhc3NpZ25lZCBpZCB5ZXQKKyAgICBpZiAoZW50cnktPmlkICE9IDB4ZmZmZikgeworICAgICAgYXV0byBtc2cgPQorICAgICAgICAgIE1lc3NhZ2U6OkVudHJ5VXBkYXRlKGVudHJ5LT5pZCwgZW50cnktPnNlcV9udW0udmFsdWUoKSwgdmFsdWUpOworICAgICAgbG9jay51bmxvY2soKTsKKyAgICAgIHF1ZXVlX291dGdvaW5nKG1zZywgbnVsbHB0ciwgbnVsbHB0cik7CisgICAgfQorICB9CisgIHJldHVybiB0cnVlOworfQorCit2b2lkIFN0b3JhZ2U6OlNldEVudHJ5VHlwZVZhbHVlKFN0cmluZ1JlZiBuYW1lLCBzdGQ6OnNoYXJlZF9wdHI8VmFsdWU+IHZhbHVlKSB7CisgIGlmIChuYW1lLmVtcHR5KCkpIHJldHVybjsKKyAgaWYgKCF2YWx1ZSkgcmV0dXJuOworICBzdGQ6OnVuaXF1ZV9sb2NrPHN0ZDo6bXV0ZXg+IGxvY2sobV9tdXRleCk7CisgIGF1dG8mIG5ld19lbnRyeSA9IG1fZW50cmllc1tuYW1lXTsKKyAgaWYgKCFuZXdfZW50cnkpIG5ld19lbnRyeS5yZXNldChuZXcgRW50cnkobmFtZSkpOworICBFbnRyeSogZW50cnkgPSBuZXdfZW50cnkuZ2V0KCk7CisgIGF1dG8gb2xkX3ZhbHVlID0gZW50cnktPnZhbHVlOworICBlbnRyeS0+dmFsdWUgPSB2YWx1ZTsKKyAgaWYgKG9sZF92YWx1ZSAmJiAqb2xkX3ZhbHVlID09ICp2YWx1ZSkgcmV0dXJuOworCisgIC8vIGlmIHdlJ3JlIHRoZSBzZXJ2ZXIsIGFzc2lnbiBhbiBpZCBpZiBpdCBkb2Vzbid0IGhhdmUgb25lCisgIGlmIChtX3NlcnZlciAmJiBlbnRyeS0+aWQgPT0gMHhmZmZmKSB7CisgICAgdW5zaWduZWQgaW50IGlkID0gbV9pZG1hcC5zaXplKCk7CisgICAgZW50cnktPmlkID0gaWQ7CisgICAgbV9pZG1hcC5wdXNoX2JhY2soZW50cnkpOworICB9CisKKyAgLy8gdXBkYXRlIHBlcnNpc3RlbnQgZGlydHkgZmxhZyBpZiBpdCdzIGEgcGVyc2lzdGVudCB2YWx1ZQorICBpZiAoZW50cnktPklzUGVyc2lzdGVudCgpKSBtX3BlcnNpc3RlbnRfZGlydHkgPSB0cnVlOworCisgIC8vIG5vdGlmeSAoZm9yIGxvY2FsIGxpc3RlbmVycykKKyAgaWYgKG1fbm90aWZpZXIubG9jYWxfbm90aWZpZXJzKCkpIHsKKyAgICBpZiAoIW9sZF92YWx1ZSkKKyAgICAgIG1fbm90aWZpZXIuTm90aWZ5RW50cnkobmFtZSwgdmFsdWUsIE5UX05PVElGWV9ORVcgfCBOVF9OT1RJRllfTE9DQUwpOworICAgIGVsc2UKKyAgICAgIG1fbm90aWZpZXIuTm90aWZ5RW50cnkobmFtZSwgdmFsdWUsIE5UX05PVElGWV9VUERBVEUgfCBOVF9OT1RJRllfTE9DQUwpOworICB9CisKKyAgLy8gZ2VuZXJhdGUgbWVzc2FnZQorICBpZiAoIW1fcXVldWVfb3V0Z29pbmcpIHJldHVybjsKKyAgYXV0byBxdWV1ZV9vdXRnb2luZyA9IG1fcXVldWVfb3V0Z29pbmc7CisgIGlmICghb2xkX3ZhbHVlIHx8IG9sZF92YWx1ZS0+dHlwZSgpICE9IHZhbHVlLT50eXBlKCkpIHsKKyAgICArK2VudHJ5LT5zZXFfbnVtOworICAgIGF1dG8gbXNnID0gTWVzc2FnZTo6RW50cnlBc3NpZ24obmFtZSwgZW50cnktPmlkLCBlbnRyeS0+c2VxX251bS52YWx1ZSgpLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFsdWUsIGVudHJ5LT5mbGFncyk7CisgICAgbG9jay51bmxvY2soKTsKKyAgICBxdWV1ZV9vdXRnb2luZyhtc2csIG51bGxwdHIsIG51bGxwdHIpOworICB9IGVsc2UgeworICAgICsrZW50cnktPnNlcV9udW07CisgICAgLy8gZG9uJ3Qgc2VuZCBhbiB1cGRhdGUgaWYgd2UgZG9uJ3QgaGF2ZSBhbiBhc3NpZ25lZCBpZCB5ZXQKKyAgICBpZiAoZW50cnktPmlkICE9IDB4ZmZmZikgeworICAgICAgYXV0byBtc2cgPQorICAgICAgICAgIE1lc3NhZ2U6OkVudHJ5VXBkYXRlKGVudHJ5LT5pZCwgZW50cnktPnNlcV9udW0udmFsdWUoKSwgdmFsdWUpOworICAgICAgbG9jay51bmxvY2soKTsKKyAgICAgIHF1ZXVlX291dGdvaW5nKG1zZywgbnVsbHB0ciwgbnVsbHB0cik7CisgICAgfQorICB9Cit9CisKK3ZvaWQgU3RvcmFnZTo6U2V0RW50cnlGbGFncyhTdHJpbmdSZWYgbmFtZSwgdW5zaWduZWQgaW50IGZsYWdzKSB7CisgIGlmIChuYW1lLmVtcHR5KCkpIHJldHVybjsKKyAgc3RkOjp1bmlxdWVfbG9jazxzdGQ6Om11dGV4PiBsb2NrKG1fbXV0ZXgpOworICBhdXRvIGkgPSBtX2VudHJpZXMuZmluZChuYW1lKTsKKyAgaWYgKGkgPT0gbV9lbnRyaWVzLmVuZCgpKSByZXR1cm47CisgIEVudHJ5KiBlbnRyeSA9IGktPmdldFZhbHVlKCkuZ2V0KCk7CisgIGlmIChlbnRyeS0+ZmxhZ3MgPT0gZmxhZ3MpIHJldHVybjsKKworICAvLyB1cGRhdGUgcGVyc2lzdGVudCBkaXJ0eSBmbGFnIGlmIHBlcnNpc3RlbnQgZmxhZyBjaGFuZ2VkCisgIGlmICgoZW50cnktPmZsYWdzICYgTlRfUEVSU0lTVEVOVCkgIT0gKGZsYWdzICYgTlRfUEVSU0lTVEVOVCkpCisgICAgbV9wZXJzaXN0ZW50X2RpcnR5ID0gdHJ1ZTsKKworICBlbnRyeS0+ZmxhZ3MgPSBmbGFnczsKKworICAvLyBub3RpZnkKKyAgbV9ub3RpZmllci5Ob3RpZnlFbnRyeShuYW1lLCBlbnRyeS0+dmFsdWUsIE5UX05PVElGWV9GTEFHUyB8IE5UX05PVElGWV9MT0NBTCk7CisKKyAgLy8gZ2VuZXJhdGUgbWVzc2FnZQorICBpZiAoIW1fcXVldWVfb3V0Z29pbmcpIHJldHVybjsKKyAgYXV0byBxdWV1ZV9vdXRnb2luZyA9IG1fcXVldWVfb3V0Z29pbmc7CisgIHVuc2lnbmVkIGludCBpZCA9IGVudHJ5LT5pZDsKKyAgLy8gZG9uJ3Qgc2VuZCBhbiB1cGRhdGUgaWYgd2UgZG9uJ3QgaGF2ZSBhbiBhc3NpZ25lZCBpZCB5ZXQKKyAgaWYgKGlkICE9IDB4ZmZmZikgeworICAgIGxvY2sudW5sb2NrKCk7CisgICAgcXVldWVfb3V0Z29pbmcoTWVzc2FnZTo6RmxhZ3NVcGRhdGUoaWQsIGZsYWdzKSwgbnVsbHB0ciwgbnVsbHB0cik7CisgIH0KK30KKwordW5zaWduZWQgaW50IFN0b3JhZ2U6OkdldEVudHJ5RmxhZ3MoU3RyaW5nUmVmIG5hbWUpIGNvbnN0IHsKKyAgc3RkOjpsb2NrX2d1YXJkPHN0ZDo6bXV0ZXg+IGxvY2sobV9tdXRleCk7CisgIGF1dG8gaSA9IG1fZW50cmllcy5maW5kKG5hbWUpOworICByZXR1cm4gaSA9PSBtX2VudHJpZXMuZW5kKCkgPyAwIDogaS0+Z2V0VmFsdWUoKS0+ZmxhZ3M7Cit9CisKK3ZvaWQgU3RvcmFnZTo6RGVsZXRlRW50cnkoU3RyaW5nUmVmIG5hbWUpIHsKKyAgc3RkOjp1bmlxdWVfbG9jazxzdGQ6Om11dGV4PiBsb2NrKG1fbXV0ZXgpOworICBhdXRvIGkgPSBtX2VudHJpZXMuZmluZChuYW1lKTsKKyAgaWYgKGkgPT0gbV9lbnRyaWVzLmVuZCgpKSByZXR1cm47CisgIGF1dG8gZW50cnkgPSBzdGQ6Om1vdmUoaS0+Z2V0VmFsdWUoKSk7CisgIHVuc2lnbmVkIGludCBpZCA9IGVudHJ5LT5pZDsKKworICAvLyB1cGRhdGUgcGVyc2lzdGVudCBkaXJ0eSBmbGFnIGlmIGl0J3MgYSBwZXJzaXN0ZW50IHZhbHVlCisgIGlmIChlbnRyeS0+SXNQZXJzaXN0ZW50KCkpIG1fcGVyc2lzdGVudF9kaXJ0eSA9IHRydWU7CisKKyAgbV9lbnRyaWVzLmVyYXNlKGkpOyAgLy8gZXJhc2UgZnJvbSBtYXAKKyAgaWYgKGlkIDwgbV9pZG1hcC5zaXplKCkpIG1faWRtYXBbaWRdID0gbnVsbHB0cjsgCisKKyAgaWYgKCFlbnRyeS0+dmFsdWUpIHJldHVybjsKKworICAvLyBub3RpZnkKKyAgbV9ub3RpZmllci5Ob3RpZnlFbnRyeShuYW1lLCBlbnRyeS0+dmFsdWUsCisgICAgICAgICAgICAgICAgICAgICAgICAgTlRfTk9USUZZX0RFTEVURSB8IE5UX05PVElGWV9MT0NBTCk7CisKKyAgLy8gaWYgaXQgaGFkIGEgdmFsdWUsIGdlbmVyYXRlIG1lc3NhZ2UKKyAgLy8gZG9uJ3Qgc2VuZCBhbiB1cGRhdGUgaWYgd2UgZG9uJ3QgaGF2ZSBhbiBhc3NpZ25lZCBpZCB5ZXQKKyAgaWYgKGlkICE9IDB4ZmZmZikgeworICAgIGlmICghbV9xdWV1ZV9vdXRnb2luZykgcmV0dXJuOworICAgIGF1dG8gcXVldWVfb3V0Z29pbmcgPSBtX3F1ZXVlX291dGdvaW5nOworICAgIGxvY2sudW5sb2NrKCk7CisgICAgcXVldWVfb3V0Z29pbmcoTWVzc2FnZTo6RW50cnlEZWxldGUoaWQpLCBudWxscHRyLCBudWxscHRyKTsKKyAgfQorfQorCit2b2lkIFN0b3JhZ2U6OkRlbGV0ZUFsbEVudHJpZXMoKSB7CisgIHN0ZDo6dW5pcXVlX2xvY2s8c3RkOjptdXRleD4gbG9jayhtX211dGV4KTsKKyAgaWYgKG1fZW50cmllcy5lbXB0eSgpKSByZXR1cm47CisgIEVudHJpZXNNYXAgbWFwOworICBtX2VudHJpZXMuc3dhcChtYXApOworICBtX2lkbWFwLnJlc2l6ZSgwKTsKKworICAvLyBzZXQgcGVyc2lzdGVudCBkaXJ0eSBmbGFnCisgIG1fcGVyc2lzdGVudF9kaXJ0eSA9IHRydWU7CisKKyAgLy8gbm90aWZ5CisgIGlmIChtX25vdGlmaWVyLmxvY2FsX25vdGlmaWVycygpKSB7CisgICAgZm9yIChhdXRvJiBlbnRyeSA6IG1hcCkKKyAgICAgIG1fbm90aWZpZXIuTm90aWZ5RW50cnkoZW50cnkuZ2V0S2V5KCksIGVudHJ5LmdldFZhbHVlKCktPnZhbHVlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICBOVF9OT1RJRllfREVMRVRFIHwgTlRfTk9USUZZX0xPQ0FMKTsKKyAgfQorCisgIC8vIGdlbmVyYXRlIG1lc3NhZ2UKKyAgaWYgKCFtX3F1ZXVlX291dGdvaW5nKSByZXR1cm47CisgIGF1dG8gcXVldWVfb3V0Z29pbmcgPSBtX3F1ZXVlX291dGdvaW5nOworICBsb2NrLnVubG9jaygpOworICBxdWV1ZV9vdXRnb2luZyhNZXNzYWdlOjpDbGVhckVudHJpZXMoKSwgbnVsbHB0ciwgbnVsbHB0cik7Cit9CisKK3N0ZDo6dmVjdG9yPEVudHJ5SW5mbz4gU3RvcmFnZTo6R2V0RW50cnlJbmZvKFN0cmluZ1JlZiBwcmVmaXgsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB1bnNpZ25lZCBpbnQgdHlwZXMpIHsKKyAgc3RkOjpsb2NrX2d1YXJkPHN0ZDo6bXV0ZXg+IGxvY2sobV9tdXRleCk7CisgIHN0ZDo6dmVjdG9yPEVudHJ5SW5mbz4gaW5mb3M7CisgIGZvciAoYXV0byYgaSA6IG1fZW50cmllcykgeworICAgIGlmICghaS5nZXRLZXkoKS5zdGFydHN3aXRoKHByZWZpeCkpIGNvbnRpbnVlOworICAgIEVudHJ5KiBlbnRyeSA9IGkuZ2V0VmFsdWUoKS5nZXQoKTsKKyAgICBhdXRvIHZhbHVlID0gZW50cnktPnZhbHVlOworICAgIGlmICghdmFsdWUpIGNvbnRpbnVlOworICAgIGlmICh0eXBlcyAhPSAwICYmICh0eXBlcyAmIHZhbHVlLT50eXBlKCkpID09IDApIGNvbnRpbnVlOworICAgIEVudHJ5SW5mbyBpbmZvOworICAgIGluZm8ubmFtZSA9IGkuZ2V0S2V5KCk7CisgICAgaW5mby50eXBlID0gdmFsdWUtPnR5cGUoKTsKKyAgICBpbmZvLmZsYWdzID0gZW50cnktPmZsYWdzOworICAgIGluZm8ubGFzdF9jaGFuZ2UgPSB2YWx1ZS0+bGFzdF9jaGFuZ2UoKTsKKyAgICBpbmZvcy5wdXNoX2JhY2soc3RkOjptb3ZlKGluZm8pKTsKKyAgfQorICByZXR1cm4gaW5mb3M7Cit9CisKK3ZvaWQgU3RvcmFnZTo6Tm90aWZ5RW50cmllcyhTdHJpbmdSZWYgcHJlZml4LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIEVudHJ5TGlzdGVuZXJDYWxsYmFjayBvbmx5KSBjb25zdCB7CisgIHN0ZDo6bG9ja19ndWFyZDxzdGQ6Om11dGV4PiBsb2NrKG1fbXV0ZXgpOworICBmb3IgKGF1dG8mIGkgOiBtX2VudHJpZXMpIHsKKyAgICBpZiAoIWkuZ2V0S2V5KCkuc3RhcnRzd2l0aChwcmVmaXgpKSBjb250aW51ZTsKKyAgICBtX25vdGlmaWVyLk5vdGlmeUVudHJ5KGkuZ2V0S2V5KCksIGkuZ2V0VmFsdWUoKS0+dmFsdWUsIE5UX05PVElGWV9JTU1FRElBVEUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICBvbmx5KTsKKyAgfQorfQorCisvKiBFc2NhcGVzIGFuZCB3cml0ZXMgYSBzdHJpbmcsIGluY2x1ZGluZyBzdGFydCBhbmQgZW5kIGRvdWJsZSBxdW90ZXMgKi8KK3N0YXRpYyB2b2lkIFdyaXRlU3RyaW5nKHN0ZDo6b3N0cmVhbSYgb3MsIGxsdm06OlN0cmluZ1JlZiBzdHIpIHsKKyAgb3MgPDwgJyInOworICBmb3IgKGF1dG8gYyA6IHN0cikgeworICAgIHN3aXRjaCAoYykgeworICAgICAgY2FzZSAnXFwnOgorICAgICAgICBvcyA8PCAiXFxcXCI7CisgICAgICAgIGJyZWFrOworICAgICAgY2FzZSAnXHQnOgorICAgICAgICBvcyA8PCAiXFx0IjsKKyAgICAgICAgYnJlYWs7CisgICAgICBjYXNlICdcbic6CisgICAgICAgIG9zIDw8ICJcXG4iOworICAgICAgICBicmVhazsKKyAgICAgIGNhc2UgJyInOgorICAgICAgICBvcyA8PCAiXFxcIiI7CisgICAgICAgIGJyZWFrOworICAgICAgZGVmYXVsdDoKKyAgICAgICAgaWYgKHN0ZDo6aXNwcmludChjKSkgeworICAgICAgICAgIG9zIDw8IGM7CisgICAgICAgICAgYnJlYWs7CisgICAgICAgIH0KKworICAgICAgICAvLyBXcml0ZSBvdXQgdGhlIGVzY2FwZWQgcmVwcmVzZW50YXRpb24uCisgICAgICAgIG9zIDw8ICJcXHgiOworICAgICAgICBvcyA8PCBsbHZtOjpoZXhkaWdpdCgoYyA+PiA0KSAmIDB4Rik7CisgICAgICAgIG9zIDw8IGxsdm06OmhleGRpZ2l0KChjID4+IDApICYgMHhGKTsKKyAgICB9CisgIH0KKyAgb3MgPDwgJyInOworfQorCitib29sIFN0b3JhZ2U6OkdldFBlcnNpc3RlbnRFbnRyaWVzKAorICAgIGJvb2wgcGVyaW9kaWMsCisgICAgc3RkOjp2ZWN0b3I8c3RkOjpwYWlyPHN0ZDo6c3RyaW5nLCBzdGQ6OnNoYXJlZF9wdHI8VmFsdWU+Pj4qIGVudHJpZXMpCisgICAgY29uc3QgeworICAvLyBjb3B5IHZhbHVlcyBvdXQgb2Ygc3RvcmFnZSBhcyBxdWlja2x5IGFzIHBvc3NpYmxlIHNvIGxvY2sgaXNuJ3QgaGVsZAorICB7CisgICAgc3RkOjpsb2NrX2d1YXJkPHN0ZDo6bXV0ZXg+IGxvY2sobV9tdXRleCk7CisgICAgLy8gZm9yIHBlcmlvZGljLCBkb24ndCByZS1zYXZlIHVubGVzcyBzb21ldGhpbmcgaGFzIGNoYW5nZWQKKyAgICBpZiAocGVyaW9kaWMgJiYgIW1fcGVyc2lzdGVudF9kaXJ0eSkgcmV0dXJuIGZhbHNlOworICAgIG1fcGVyc2lzdGVudF9kaXJ0eSA9IGZhbHNlOworICAgIGVudHJpZXMtPnJlc2VydmUobV9lbnRyaWVzLnNpemUoKSk7CisgICAgZm9yIChhdXRvJiBpIDogbV9lbnRyaWVzKSB7CisgICAgICBFbnRyeSogZW50cnkgPSBpLmdldFZhbHVlKCkuZ2V0KCk7CisgICAgICAvLyBvbmx5IHdyaXRlIHBlcnNpc3RlbnQtZmxhZ2dlZCB2YWx1ZXMKKyAgICAgIGlmICghZW50cnktPklzUGVyc2lzdGVudCgpKSBjb250aW51ZTsKKyAgICAgIGVudHJpZXMtPmVtcGxhY2VfYmFjayhpLmdldEtleSgpLCBlbnRyeS0+dmFsdWUpOworICAgIH0KKyAgfQorCisgIC8vIHNvcnQgaW4gbmFtZSBvcmRlcgorICBzdGQ6OnNvcnQoZW50cmllcy0+YmVnaW4oKSwgZW50cmllcy0+ZW5kKCksCisgICAgICAgICAgICBbXShjb25zdCBzdGQ6OnBhaXI8c3RkOjpzdHJpbmcsIHN0ZDo6c2hhcmVkX3B0cjxWYWx1ZT4+JiBhLAorICAgICAgICAgICAgICAgY29uc3Qgc3RkOjpwYWlyPHN0ZDo6c3RyaW5nLCBzdGQ6OnNoYXJlZF9wdHI8VmFsdWU+PiYgYikgeworICAgICAgICAgICAgICByZXR1cm4gYS5maXJzdCA8IGIuZmlyc3Q7CisgICAgICAgICAgICB9KTsKKyAgcmV0dXJuIHRydWU7Cit9CisKK3N0YXRpYyB2b2lkIFNhdmVQZXJzaXN0ZW50SW1wbCgKKyAgICBzdGQ6Om9zdHJlYW0mIG9zLAorICAgIGxsdm06OkFycmF5UmVmPHN0ZDo6cGFpcjxzdGQ6OnN0cmluZywgc3RkOjpzaGFyZWRfcHRyPFZhbHVlPj4+IGVudHJpZXMpIHsKKyAgc3RkOjpzdHJpbmcgYmFzZTY0X2VuY29kZWQ7CisKKyAgLy8gaGVhZGVyCisgIG9zIDw8ICJbTmV0d29ya1RhYmxlcyBTdG9yYWdlIDMuMF1cbiI7CisKKyAgZm9yIChhdXRvJiBpIDogZW50cmllcykgeworICAgIC8vIHR5cGUKKyAgICBhdXRvIHYgPSBpLnNlY29uZDsKKyAgICBpZiAoIXYpIGNvbnRpbnVlOworICAgIHN3aXRjaCAodi0+dHlwZSgpKSB7CisgICAgICBjYXNlIE5UX0JPT0xFQU46CisgICAgICAgIG9zIDw8ICJib29sZWFuICI7CisgICAgICAgIGJyZWFrOworICAgICAgY2FzZSBOVF9ET1VCTEU6CisgICAgICAgIG9zIDw8ICJkb3VibGUgIjsKKyAgICAgICAgYnJlYWs7CisgICAgICBjYXNlIE5UX1NUUklORzoKKyAgICAgICAgb3MgPDwgInN0cmluZyAiOworICAgICAgICBicmVhazsKKyAgICAgIGNhc2UgTlRfUkFXOgorICAgICAgICBvcyA8PCAicmF3ICI7CisgICAgICAgIGJyZWFrOworICAgICAgY2FzZSBOVF9CT09MRUFOX0FSUkFZOgorICAgICAgICBvcyA8PCAiYXJyYXkgYm9vbGVhbiAiOworICAgICAgICBicmVhazsKKyAgICAgIGNhc2UgTlRfRE9VQkxFX0FSUkFZOgorICAgICAgICBvcyA8PCAiYXJyYXkgZG91YmxlICI7CisgICAgICAgIGJyZWFrOworICAgICAgY2FzZSBOVF9TVFJJTkdfQVJSQVk6CisgICAgICAgIG9zIDw8ICJhcnJheSBzdHJpbmcgIjsKKyAgICAgICAgYnJlYWs7CisgICAgICBkZWZhdWx0OgorICAgICAgICBjb250aW51ZTsKKyAgICB9CisKKyAgICAvLyBuYW1lCisgICAgV3JpdGVTdHJpbmcob3MsIGkuZmlyc3QpOworCisgICAgLy8gPQorICAgIG9zIDw8ICc9JzsKKworICAgIC8vIHZhbHVlCisgICAgc3dpdGNoICh2LT50eXBlKCkpIHsKKyAgICAgIGNhc2UgTlRfQk9PTEVBTjoKKyAgICAgICAgb3MgPDwgKHYtPkdldEJvb2xlYW4oKSA/ICJ0cnVlIiA6ICJmYWxzZSIpOworICAgICAgICBicmVhazsKKyAgICAgIGNhc2UgTlRfRE9VQkxFOgorICAgICAgICBvcyA8PCB2LT5HZXREb3VibGUoKTsKKyAgICAgICAgYnJlYWs7CisgICAgICBjYXNlIE5UX1NUUklORzoKKyAgICAgICAgV3JpdGVTdHJpbmcob3MsIHYtPkdldFN0cmluZygpKTsKKyAgICAgICAgYnJlYWs7CisgICAgICBjYXNlIE5UX1JBVzoKKyAgICAgICAgQmFzZTY0RW5jb2RlKHYtPkdldFJhdygpLCAmYmFzZTY0X2VuY29kZWQpOworICAgICAgICBvcyA8PCBiYXNlNjRfZW5jb2RlZDsKKyAgICAgICAgYnJlYWs7CisgICAgICBjYXNlIE5UX0JPT0xFQU5fQVJSQVk6IHsKKyAgICAgICAgYm9vbCBmaXJzdCA9IHRydWU7CisgICAgICAgIGZvciAoYXV0byBlbGVtIDogdi0+R2V0Qm9vbGVhbkFycmF5KCkpIHsKKyAgICAgICAgICBpZiAoIWZpcnN0KSBvcyA8PCAnLCc7CisgICAgICAgICAgZmlyc3QgPSBmYWxzZTsKKyAgICAgICAgICBvcyA8PCAoZWxlbSA/ICJ0cnVlIiA6ICJmYWxzZSIpOworICAgICAgICB9CisgICAgICAgIGJyZWFrOworICAgICAgfQorICAgICAgY2FzZSBOVF9ET1VCTEVfQVJSQVk6IHsKKyAgICAgICAgYm9vbCBmaXJzdCA9IHRydWU7CisgICAgICAgIGZvciAoYXV0byBlbGVtIDogdi0+R2V0RG91YmxlQXJyYXkoKSkgeworICAgICAgICAgIGlmICghZmlyc3QpIG9zIDw8ICcsJzsKKyAgICAgICAgICBmaXJzdCA9IGZhbHNlOworICAgICAgICAgIG9zIDw8IGVsZW07CisgICAgICAgIH0KKyAgICAgICAgYnJlYWs7CisgICAgICB9CisgICAgICBjYXNlIE5UX1NUUklOR19BUlJBWTogeworICAgICAgICBib29sIGZpcnN0ID0gdHJ1ZTsKKyAgICAgICAgZm9yIChhdXRvJiBlbGVtIDogdi0+R2V0U3RyaW5nQXJyYXkoKSkgeworICAgICAgICAgIGlmICghZmlyc3QpIG9zIDw8ICcsJzsKKyAgICAgICAgICBmaXJzdCA9IGZhbHNlOworICAgICAgICAgIFdyaXRlU3RyaW5nKG9zLCBlbGVtKTsKKyAgICAgICAgfQorICAgICAgICBicmVhazsKKyAgICAgIH0KKyAgICAgIGRlZmF1bHQ6CisgICAgICAgIGJyZWFrOworICAgIH0KKworICAgIC8vIGVvbAorICAgIG9zIDw8ICdcbic7CisgIH0KK30KKwordm9pZCBTdG9yYWdlOjpTYXZlUGVyc2lzdGVudChzdGQ6Om9zdHJlYW0mIG9zLCBib29sIHBlcmlvZGljKSBjb25zdCB7CisgIHN0ZDo6dmVjdG9yPHN0ZDo6cGFpcjxzdGQ6OnN0cmluZywgc3RkOjpzaGFyZWRfcHRyPFZhbHVlPj4+IGVudHJpZXM7CisgIGlmICghR2V0UGVyc2lzdGVudEVudHJpZXMocGVyaW9kaWMsICZlbnRyaWVzKSkgcmV0dXJuOworICBTYXZlUGVyc2lzdGVudEltcGwob3MsIGVudHJpZXMpOworfQorCitjb25zdCBjaGFyKiBTdG9yYWdlOjpTYXZlUGVyc2lzdGVudChTdHJpbmdSZWYgZmlsZW5hbWUsIGJvb2wgcGVyaW9kaWMpIGNvbnN0IHsKKyAgc3RkOjpzdHJpbmcgZm4gPSBmaWxlbmFtZTsKKyAgc3RkOjpzdHJpbmcgdG1wID0gZmlsZW5hbWU7CisgIHRtcCArPSAiLnRtcCI7CisgIHN0ZDo6c3RyaW5nIGJhayA9IGZpbGVuYW1lOworICBiYWsgKz0gIi5iYWsiOworCisgIC8vIEdldCBlbnRyaWVzIGJlZm9yZSBjcmVhdGluZyBmaWxlCisgIHN0ZDo6dmVjdG9yPHN0ZDo6cGFpcjxzdGQ6OnN0cmluZywgc3RkOjpzaGFyZWRfcHRyPFZhbHVlPj4+IGVudHJpZXM7CisgIGlmICghR2V0UGVyc2lzdGVudEVudHJpZXMocGVyaW9kaWMsICZlbnRyaWVzKSkgcmV0dXJuIG51bGxwdHI7CisKKyAgY29uc3QgY2hhciogZXJyID0gbnVsbHB0cjsKKworICAvLyBzdGFydCBieSB3cml0aW5nIHRvIHRlbXBvcmFyeSBmaWxlCisgIHN0ZDo6b2ZzdHJlYW0gb3ModG1wKTsKKyAgaWYgKCFvcykgeworICAgIGVyciA9ICJjb3VsZCBub3Qgb3BlbiBmaWxlIjsKKyAgICBnb3RvIGRvbmU7CisgIH0KKyAgREVCVUcoInNhdmluZyBwZXJzaXN0ZW50IGZpbGUgJyIgPDwgZmlsZW5hbWUgPDwgIiciKTsKKyAgU2F2ZVBlcnNpc3RlbnRJbXBsKG9zLCBlbnRyaWVzKTsKKyAgb3MuZmx1c2goKTsKKyAgaWYgKCFvcykgeworICAgIG9zLmNsb3NlKCk7CisgICAgc3RkOjpyZW1vdmUodG1wLmNfc3RyKCkpOworICAgIGVyciA9ICJlcnJvciBzYXZpbmcgZmlsZSI7CisgICAgZ290byBkb25lOworICB9CisgIG9zLmNsb3NlKCk7CisKKyAgLy8gU2FmZWx5IG1vdmUgdG8gcmVhbCBmaWxlLiAgV2UgaWdub3JlIGFueSBmYWlsdXJlcyByZWxhdGVkIHRvIHRoZSBiYWNrdXAuCisgIHN0ZDo6cmVtb3ZlKGJhay5jX3N0cigpKTsKKyAgc3RkOjpyZW5hbWUoZm4uY19zdHIoKSwgYmFrLmNfc3RyKCkpOworICBpZiAoc3RkOjpyZW5hbWUodG1wLmNfc3RyKCksIGZuLmNfc3RyKCkpICE9IDApIHsKKyAgICBzdGQ6OnJlbmFtZShiYWsuY19zdHIoKSwgZm4uY19zdHIoKSk7ICAvLyBhdHRlbXB0IHRvIHJlc3RvcmUgYmFja3VwCisgICAgZXJyID0gImNvdWxkIG5vdCByZW5hbWUgdGVtcCBmaWxlIHRvIHJlYWwgZmlsZSI7CisgICAgZ290byBkb25lOworICB9CisKK2RvbmU6CisgIC8vIHRyeSBhZ2FpbiBpZiB0aGVyZSB3YXMgYW4gZXJyb3IKKyAgaWYgKGVyciAmJiBwZXJpb2RpYykgbV9wZXJzaXN0ZW50X2RpcnR5ID0gdHJ1ZTsKKyAgcmV0dXJuIGVycjsKK30KKworLyogRXh0cmFjdHMgYW4gZXNjYXBlZCBzdHJpbmcgdG9rZW4uICBEb2VzIG5vdCB1bmVzY2FwZSB0aGUgc3RyaW5nLgorICogSWYgYSBzdHJpbmcgY2Fubm90IGJlIG1hdGNoZWQsIGFuIGVtcHR5IHN0cmluZyBpcyByZXR1cm5lZC4KKyAqIElmIHRoZSBzdHJpbmcgaXMgdW50ZXJtaW5hdGVkLCBhbiBlbXB0eSB0YWlsIHN0cmluZyBpcyByZXR1cm5lZC4KKyAqIFRoZSByZXR1cm5lZCB0b2tlbiBpbmNsdWRlcyB0aGUgc3RhcnRpbmcgYW5kIHRyYWlsaW5nIHF1b3RlcyAodW5sZXNzIHRoZQorICogc3RyaW5nIGlzIHVudGVybWluYXRlZCkuCisgKiBSZXR1cm5zIGEgcGFpciBjb250YWluaW5nIHRoZSBleHRyYWN0ZWQgdG9rZW4gKGlmIGFueSkgYW5kIHRoZSByZW1haW5pbmcKKyAqIHRhaWwgc3RyaW5nLgorICovCitzdGF0aWMgc3RkOjpwYWlyPGxsdm06OlN0cmluZ1JlZiwgbGx2bTo6U3RyaW5nUmVmPiBSZWFkU3RyaW5nVG9rZW4oCisgICAgbGx2bTo6U3RyaW5nUmVmIHNvdXJjZSkgeworICAvLyBNYXRjaCBvcGVuaW5nIHF1b3RlCisgIGlmIChzb3VyY2UuZW1wdHkoKSB8fCBzb3VyY2UuZnJvbnQoKSAhPSAnIicpCisgICAgcmV0dXJuIHN0ZDo6bWFrZV9wYWlyKGxsdm06OlN0cmluZ1JlZigpLCBzb3VyY2UpOworCisgIC8vIFNjYW4gZm9yIGVuZGluZyBkb3VibGUgcXVvdGUsIGNoZWNraW5nIGZvciBlc2NhcGVkIGFzIHdlIGdvLgorICBzdGQ6OnNpemVfdCBzaXplID0gc291cmNlLnNpemUoKTsKKyAgc3RkOjpzaXplX3QgcG9zOworICBmb3IgKHBvcyA9IDE7IHBvcyA8IHNpemU7ICsrcG9zKSB7CisgICAgaWYgKHNvdXJjZVtwb3NdID09ICciJyAmJiBzb3VyY2VbcG9zIC0gMV0gIT0gJ1xcJykgeworICAgICAgKytwb3M7ICAvLyB3ZSB3YW50IHRvIGluY2x1ZGUgdGhlIHRyYWlsaW5nIHF1b3RlIGluIHRoZSByZXN1bHQKKyAgICAgIGJyZWFrOworICAgIH0KKyAgfQorICByZXR1cm4gc3RkOjptYWtlX3BhaXIoc291cmNlLnNsaWNlKDAsIHBvcyksIHNvdXJjZS5zdWJzdHIocG9zKSk7Cit9CisKK3N0YXRpYyBpbnQgZnJvbXhkaWdpdChjaGFyIGNoKSB7CisgIGlmIChjaCA+PSAnYScgJiYgY2ggPD0gJ2YnKQorICAgIHJldHVybiAoY2ggLSAnYScgKyAxMCk7CisgIGVsc2UgaWYgKGNoID49ICdBJyAmJiBjaCA8PSAnRicpCisgICAgcmV0dXJuIChjaCAtICdBJyArIDEwKTsKKyAgZWxzZQorICAgIHJldHVybiBjaCAtICcwJzsKK30KKworc3RhdGljIHZvaWQgVW5lc2NhcGVTdHJpbmcobGx2bTo6U3RyaW5nUmVmIHNvdXJjZSwgc3RkOjpzdHJpbmcqIGRlc3QpIHsKKyAgYXNzZXJ0KHNvdXJjZS5zaXplKCkgPj0gMiAmJiBzb3VyY2UuZnJvbnQoKSA9PSAnIicgJiYgc291cmNlLmJhY2soKSA9PSAnIicpOworICBkZXN0LT5jbGVhcigpOworICBkZXN0LT5yZXNlcnZlKHNvdXJjZS5zaXplKCkgLSAyKTsKKyAgZm9yIChhdXRvIHMgPSBzb3VyY2UuYmVnaW4oKSArIDEsIGVuZCA9IHNvdXJjZS5lbmQoKSAtIDE7IHMgIT0gZW5kOyArK3MpIHsKKyAgICBpZiAoKnMgIT0gJ1xcJykgeworICAgICAgZGVzdC0+cHVzaF9iYWNrKCpzKTsKKyAgICAgIGNvbnRpbnVlOworICAgIH0KKyAgICBzd2l0Y2ggKCorK3MpIHsKKyAgICAgIGNhc2UgJ1xcJzoKKyAgICAgIGNhc2UgJyInOgorICAgICAgICBkZXN0LT5wdXNoX2JhY2soc1stMV0pOworICAgICAgICBicmVhazsKKyAgICAgIGNhc2UgJ3QnOgorICAgICAgICBkZXN0LT5wdXNoX2JhY2soJ1x0Jyk7CisgICAgICAgIGJyZWFrOworICAgICAgY2FzZSAnbic6CisgICAgICAgIGRlc3QtPnB1c2hfYmFjaygnXG4nKTsKKyAgICAgICAgYnJlYWs7CisgICAgICBjYXNlICd4JzogeworICAgICAgICBpZiAoIWlzeGRpZ2l0KCoocysxKSkpIHsKKyAgICAgICAgICBkZXN0LT5wdXNoX2JhY2soJ3gnKTsgIC8vIHRyZWF0IGl0IGxpa2UgYSB1bmtub3duIGVzY2FwZQorICAgICAgICAgIGJyZWFrOworICAgICAgICB9CisgICAgICAgIGludCBjaCA9IGZyb214ZGlnaXQoKisrcyk7CisgICAgICAgIGlmIChpc3hkaWdpdCgqKHMrMSkpKSB7CisgICAgICAgICAgY2ggPDw9IDQ7CisgICAgICAgICAgY2ggfD0gZnJvbXhkaWdpdCgqKytzKTsKKyAgICAgICAgfQorICAgICAgICBkZXN0LT5wdXNoX2JhY2soc3RhdGljX2Nhc3Q8Y2hhcj4oY2gpKTsKKyAgICAgICAgYnJlYWs7CisgICAgICB9CisgICAgICBkZWZhdWx0OgorICAgICAgICBkZXN0LT5wdXNoX2JhY2soc1stMV0pOworICAgICAgICBicmVhazsKKyAgICB9CisgIH0KK30KKworYm9vbCBTdG9yYWdlOjpMb2FkUGVyc2lzdGVudCgKKyAgICBzdGQ6OmlzdHJlYW0mIGlzLAorICAgIHN0ZDo6ZnVuY3Rpb248dm9pZChzdGQ6OnNpemVfdCBsaW5lLCBjb25zdCBjaGFyKiBtc2cpPiB3YXJuKSB7CisgIHN0ZDo6c3RyaW5nIGxpbmVfc3RyOworICBzdGQ6OnNpemVfdCBsaW5lX251bSA9IDE7CisKKyAgLy8gZW50cmllcyB0byBhZGQKKyAgc3RkOjp2ZWN0b3I8c3RkOjpwYWlyPHN0ZDo6c3RyaW5nLCBzdGQ6OnNoYXJlZF9wdHI8VmFsdWU+Pj4gZW50cmllczsKKworICAvLyBkZWNsYXJlIHRoZXNlIG91dHNpZGUgdGhlIGxvb3AgdG8gcmVkdWNlIHJlYWxsb2NzCisgIHN0ZDo6c3RyaW5nIG5hbWUsIHN0cjsKKyAgc3RkOjp2ZWN0b3I8aW50PiBib29sZWFuX2FycmF5OworICBzdGQ6OnZlY3Rvcjxkb3VibGU+IGRvdWJsZV9hcnJheTsKKyAgc3RkOjp2ZWN0b3I8c3RkOjpzdHJpbmc+IHN0cmluZ19hcnJheTsKKworICAvLyBpZ25vcmUgYmxhbmsgbGluZXMgYW5kIGxpbmVzIHRoYXQgc3RhcnQgd2l0aCA7IG9yICMgKGNvbW1lbnRzKQorICB3aGlsZSAoc3RkOjpnZXRsaW5lKGlzLCBsaW5lX3N0cikpIHsKKyAgICBsbHZtOjpTdHJpbmdSZWYgbGluZSA9IGxsdm06OlN0cmluZ1JlZihsaW5lX3N0cikudHJpbSgpOworICAgIGlmICghbGluZS5lbXB0eSgpICYmIGxpbmUuZnJvbnQoKSAhPSAnOycgJiYgbGluZS5mcm9udCgpICE9ICcjJykKKyAgICAgIGJyZWFrOworICB9CisKKyAgLy8gaGVhZGVyCisgIGlmIChsaW5lX3N0ciAhPSAiW05ldHdvcmtUYWJsZXMgU3RvcmFnZSAzLjBdIikgeworICAgIGlmICh3YXJuKSB3YXJuKGxpbmVfbnVtLCAiaGVhZGVyIGxpbmUgbWlzbWF0Y2gsIGlnbm9yaW5nIHJlc3Qgb2YgZmlsZSIpOworICAgIHJldHVybiBmYWxzZTsKKyAgfQorCisgIHdoaWxlIChzdGQ6OmdldGxpbmUoaXMsIGxpbmVfc3RyKSkgeworICAgIGxsdm06OlN0cmluZ1JlZiBsaW5lID0gbGx2bTo6U3RyaW5nUmVmKGxpbmVfc3RyKS50cmltKCk7CisgICAgKytsaW5lX251bTsKKworICAgIC8vIGlnbm9yZSBibGFuayBsaW5lcyBhbmQgbGluZXMgdGhhdCBzdGFydCB3aXRoIDsgb3IgIyAoY29tbWVudHMpCisgICAgaWYgKGxpbmUuZW1wdHkoKSB8fCBsaW5lLmZyb250KCkgPT0gJzsnIHx8IGxpbmUuZnJvbnQoKSA9PSAnIycpCisgICAgICBjb250aW51ZTsKKworICAgIC8vIHR5cGUKKyAgICBsbHZtOjpTdHJpbmdSZWYgdHlwZV90b2s7CisgICAgc3RkOjp0aWUodHlwZV90b2ssIGxpbmUpID0gbGluZS5zcGxpdCgnICcpOworICAgIE5UX1R5cGUgdHlwZSA9IE5UX1VOQVNTSUdORUQ7CisgICAgaWYgKHR5cGVfdG9rID09ICJib29sZWFuIikgdHlwZSA9IE5UX0JPT0xFQU47CisgICAgZWxzZSBpZiAodHlwZV90b2sgPT0gImRvdWJsZSIpIHR5cGUgPSBOVF9ET1VCTEU7CisgICAgZWxzZSBpZiAodHlwZV90b2sgPT0gInN0cmluZyIpIHR5cGUgPSBOVF9TVFJJTkc7CisgICAgZWxzZSBpZiAodHlwZV90b2sgPT0gInJhdyIpIHR5cGUgPSBOVF9SQVc7CisgICAgZWxzZSBpZiAodHlwZV90b2sgPT0gImFycmF5IikgeworICAgICAgbGx2bTo6U3RyaW5nUmVmIGFycmF5X3RvazsKKyAgICAgIHN0ZDo6dGllKGFycmF5X3RvaywgbGluZSkgPSBsaW5lLnNwbGl0KCcgJyk7CisgICAgICBpZiAoYXJyYXlfdG9rID09ICJib29sZWFuIikgdHlwZSA9IE5UX0JPT0xFQU5fQVJSQVk7CisgICAgICBlbHNlIGlmIChhcnJheV90b2sgPT0gImRvdWJsZSIpIHR5cGUgPSBOVF9ET1VCTEVfQVJSQVk7CisgICAgICBlbHNlIGlmIChhcnJheV90b2sgPT0gInN0cmluZyIpIHR5cGUgPSBOVF9TVFJJTkdfQVJSQVk7CisgICAgfQorICAgIGlmICh0eXBlID09IE5UX1VOQVNTSUdORUQpIHsKKyAgICAgIGlmICh3YXJuKSB3YXJuKGxpbmVfbnVtLCAidW5yZWNvZ25pemVkIHR5cGUiKTsKKyAgICAgIGNvbnRpbnVlOworICAgIH0KKworICAgIC8vIG5hbWUKKyAgICBsbHZtOjpTdHJpbmdSZWYgbmFtZV90b2s7CisgICAgc3RkOjp0aWUobmFtZV90b2ssIGxpbmUpID0gUmVhZFN0cmluZ1Rva2VuKGxpbmUpOworICAgIGlmIChuYW1lX3Rvay5lbXB0eSgpKSB7CisgICAgICBpZiAod2Fybikgd2FybihsaW5lX251bSwgIm1pc3NpbmcgbmFtZSIpOworICAgICAgY29udGludWU7CisgICAgfQorICAgIGlmIChuYW1lX3Rvay5iYWNrKCkgIT0gJyInKSB7CisgICAgICBpZiAod2Fybikgd2FybihsaW5lX251bSwgInVudGVybWluYXRlZCBuYW1lIHN0cmluZyIpOworICAgICAgY29udGludWU7CisgICAgfQorICAgIFVuZXNjYXBlU3RyaW5nKG5hbWVfdG9rLCAmbmFtZSk7CisKKyAgICAvLyA9CisgICAgbGluZSA9IGxpbmUubHRyaW0oIiBcdCIpOworICAgIGlmIChsaW5lLmVtcHR5KCkgfHwgbGluZS5mcm9udCgpICE9ICc9JykgeworICAgICAgaWYgKHdhcm4pIHdhcm4obGluZV9udW0sICJleHBlY3RlZCA9IGFmdGVyIG5hbWUiKTsKKyAgICAgIGNvbnRpbnVlOworICAgIH0KKyAgICBsaW5lID0gbGluZS5kcm9wX2Zyb250KCkubHRyaW0oIiBcdCIpOworCisgICAgLy8gdmFsdWUKKyAgICBzdGQ6OnNoYXJlZF9wdHI8VmFsdWU+IHZhbHVlOworICAgIHN3aXRjaCAodHlwZSkgeworICAgICAgY2FzZSBOVF9CT09MRUFOOgorICAgICAgICAvLyBvbmx5IHRydWUgb3IgZmFsc2UgaXMgYWNjZXB0ZWQKKyAgICAgICAgaWYgKGxpbmUgPT0gInRydWUiKQorICAgICAgICAgIHZhbHVlID0gVmFsdWU6Ok1ha2VCb29sZWFuKHRydWUpOworICAgICAgICBlbHNlIGlmIChsaW5lID09ICJmYWxzZSIpCisgICAgICAgICAgdmFsdWUgPSBWYWx1ZTo6TWFrZUJvb2xlYW4oZmFsc2UpOworICAgICAgICBlbHNlIHsKKyAgICAgICAgICBpZiAod2FybikKKyAgICAgICAgICAgIHdhcm4obGluZV9udW0sICJ1bnJlY29nbml6ZWQgYm9vbGVhbiB2YWx1ZSwgbm90ICd0cnVlJyBvciAnZmFsc2UnIik7CisgICAgICAgICAgZ290byBuZXh0X2xpbmU7CisgICAgICAgIH0KKyAgICAgICAgYnJlYWs7CisgICAgICBjYXNlIE5UX0RPVUJMRTogeworICAgICAgICAvLyBuZWVkIHRvIGNvbnZlcnQgdG8gbnVsbC10ZXJtaW5hdGVkIHN0cmluZyBmb3Igc3RydG9kKCkKKyAgICAgICAgc3RyLmNsZWFyKCk7CisgICAgICAgIHN0ciArPSBsaW5lOworICAgICAgICBjaGFyKiBlbmQ7CisgICAgICAgIGRvdWJsZSB2ID0gc3RkOjpzdHJ0b2Qoc3RyLmNfc3RyKCksICZlbmQpOworICAgICAgICBpZiAoKmVuZCAhPSAnXDAnKSB7CisgICAgICAgICAgaWYgKHdhcm4pIHdhcm4obGluZV9udW0sICJpbnZhbGlkIGRvdWJsZSB2YWx1ZSIpOworICAgICAgICAgIGdvdG8gbmV4dF9saW5lOworICAgICAgICB9CisgICAgICAgIHZhbHVlID0gVmFsdWU6Ok1ha2VEb3VibGUodik7CisgICAgICAgIGJyZWFrOworICAgICAgfQorICAgICAgY2FzZSBOVF9TVFJJTkc6IHsKKyAgICAgICAgbGx2bTo6U3RyaW5nUmVmIHN0cl90b2s7CisgICAgICAgIHN0ZDo6dGllKHN0cl90b2ssIGxpbmUpID0gUmVhZFN0cmluZ1Rva2VuKGxpbmUpOworICAgICAgICBpZiAoc3RyX3Rvay5lbXB0eSgpKSB7CisgICAgICAgICAgaWYgKHdhcm4pIHdhcm4obGluZV9udW0sICJtaXNzaW5nIHN0cmluZyB2YWx1ZSIpOworICAgICAgICAgIGdvdG8gbmV4dF9saW5lOworICAgICAgICB9CisgICAgICAgIGlmIChzdHJfdG9rLmJhY2soKSAhPSAnIicpIHsKKyAgICAgICAgICBpZiAod2Fybikgd2FybihsaW5lX251bSwgInVudGVybWluYXRlZCBzdHJpbmcgdmFsdWUiKTsKKyAgICAgICAgICBnb3RvIG5leHRfbGluZTsKKyAgICAgICAgfQorICAgICAgICBVbmVzY2FwZVN0cmluZyhzdHJfdG9rLCAmc3RyKTsKKyAgICAgICAgdmFsdWUgPSBWYWx1ZTo6TWFrZVN0cmluZyhzdGQ6Om1vdmUoc3RyKSk7CisgICAgICAgIGJyZWFrOworICAgICAgfQorICAgICAgY2FzZSBOVF9SQVc6CisgICAgICAgIEJhc2U2NERlY29kZShsaW5lLCAmc3RyKTsKKyAgICAgICAgdmFsdWUgPSBWYWx1ZTo6TWFrZVJhdyhzdGQ6Om1vdmUoc3RyKSk7CisgICAgICAgIGJyZWFrOworICAgICAgY2FzZSBOVF9CT09MRUFOX0FSUkFZOiB7CisgICAgICAgIGxsdm06OlN0cmluZ1JlZiBlbGVtX3RvazsKKyAgICAgICAgYm9vbGVhbl9hcnJheS5jbGVhcigpOworICAgICAgICB3aGlsZSAoIWxpbmUuZW1wdHkoKSkgeworICAgICAgICAgIHN0ZDo6dGllKGVsZW1fdG9rLCBsaW5lKSA9IGxpbmUuc3BsaXQoJywnKTsKKyAgICAgICAgICBlbGVtX3RvayA9IGVsZW1fdG9rLnRyaW0oIiBcdCIpOworICAgICAgICAgIGlmIChlbGVtX3RvayA9PSAidHJ1ZSIpCisgICAgICAgICAgICBib29sZWFuX2FycmF5LnB1c2hfYmFjaygxKTsKKyAgICAgICAgICBlbHNlIGlmIChlbGVtX3RvayA9PSAiZmFsc2UiKQorICAgICAgICAgICAgYm9vbGVhbl9hcnJheS5wdXNoX2JhY2soMCk7CisgICAgICAgICAgZWxzZSB7CisgICAgICAgICAgICBpZiAod2FybikKKyAgICAgICAgICAgICAgd2FybihsaW5lX251bSwKKyAgICAgICAgICAgICAgICAgICAidW5yZWNvZ25pemVkIGJvb2xlYW4gdmFsdWUsIG5vdCAndHJ1ZScgb3IgJ2ZhbHNlJyIpOworICAgICAgICAgICAgZ290byBuZXh0X2xpbmU7CisgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgdmFsdWUgPSBWYWx1ZTo6TWFrZUJvb2xlYW5BcnJheShzdGQ6Om1vdmUoYm9vbGVhbl9hcnJheSkpOworICAgICAgICBicmVhazsKKyAgICAgIH0KKyAgICAgIGNhc2UgTlRfRE9VQkxFX0FSUkFZOiB7CisgICAgICAgIGxsdm06OlN0cmluZ1JlZiBlbGVtX3RvazsKKyAgICAgICAgZG91YmxlX2FycmF5LmNsZWFyKCk7CisgICAgICAgIHdoaWxlICghbGluZS5lbXB0eSgpKSB7CisgICAgICAgICAgc3RkOjp0aWUoZWxlbV90b2ssIGxpbmUpID0gbGluZS5zcGxpdCgnLCcpOworICAgICAgICAgIGVsZW1fdG9rID0gZWxlbV90b2sudHJpbSgiIFx0Iik7CisgICAgICAgICAgLy8gbmVlZCB0byBjb252ZXJ0IHRvIG51bGwtdGVybWluYXRlZCBzdHJpbmcgZm9yIHN0cnRvZCgpCisgICAgICAgICAgc3RyLmNsZWFyKCk7CisgICAgICAgICAgc3RyICs9IGVsZW1fdG9rOworICAgICAgICAgIGNoYXIqIGVuZDsKKyAgICAgICAgICBkb3VibGUgdiA9IHN0ZDo6c3RydG9kKHN0ci5jX3N0cigpLCAmZW5kKTsKKyAgICAgICAgICBpZiAoKmVuZCAhPSAnXDAnKSB7CisgICAgICAgICAgICBpZiAod2Fybikgd2FybihsaW5lX251bSwgImludmFsaWQgZG91YmxlIHZhbHVlIik7CisgICAgICAgICAgICBnb3RvIG5leHRfbGluZTsKKyAgICAgICAgICB9CisgICAgICAgICAgZG91YmxlX2FycmF5LnB1c2hfYmFjayh2KTsKKyAgICAgICAgfQorCisgICAgICAgIHZhbHVlID0gVmFsdWU6Ok1ha2VEb3VibGVBcnJheShzdGQ6Om1vdmUoZG91YmxlX2FycmF5KSk7CisgICAgICAgIGJyZWFrOworICAgICAgfQorICAgICAgY2FzZSBOVF9TVFJJTkdfQVJSQVk6IHsKKyAgICAgICAgbGx2bTo6U3RyaW5nUmVmIGVsZW1fdG9rOworICAgICAgICBzdHJpbmdfYXJyYXkuY2xlYXIoKTsKKyAgICAgICAgd2hpbGUgKCFsaW5lLmVtcHR5KCkpIHsKKyAgICAgICAgICBzdGQ6OnRpZShlbGVtX3RvaywgbGluZSkgPSBSZWFkU3RyaW5nVG9rZW4obGluZSk7CisgICAgICAgICAgaWYgKGVsZW1fdG9rLmVtcHR5KCkpIHsKKyAgICAgICAgICAgIGlmICh3YXJuKSB3YXJuKGxpbmVfbnVtLCAibWlzc2luZyBzdHJpbmcgdmFsdWUiKTsKKyAgICAgICAgICAgIGdvdG8gbmV4dF9saW5lOworICAgICAgICAgIH0KKyAgICAgICAgICBpZiAoZWxlbV90b2suYmFjaygpICE9ICciJykgeworICAgICAgICAgICAgaWYgKHdhcm4pIHdhcm4obGluZV9udW0sICJ1bnRlcm1pbmF0ZWQgc3RyaW5nIHZhbHVlIik7CisgICAgICAgICAgICBnb3RvIG5leHRfbGluZTsKKyAgICAgICAgICB9CisKKyAgICAgICAgICBVbmVzY2FwZVN0cmluZyhlbGVtX3RvaywgJnN0cik7CisgICAgICAgICAgc3RyaW5nX2FycmF5LnB1c2hfYmFjayhzdGQ6Om1vdmUoc3RyKSk7CisKKyAgICAgICAgICBsaW5lID0gbGluZS5sdHJpbSgiIFx0Iik7CisgICAgICAgICAgaWYgKGxpbmUuZW1wdHkoKSkgYnJlYWs7CisgICAgICAgICAgaWYgKGxpbmUuZnJvbnQoKSAhPSAnLCcpIHsKKyAgICAgICAgICAgIGlmICh3YXJuKSB3YXJuKGxpbmVfbnVtLCAiZXhwZWN0ZWQgY29tbWEgYmV0d2VlbiBzdHJpbmdzIik7CisgICAgICAgICAgICBnb3RvIG5leHRfbGluZTsKKyAgICAgICAgICB9CisgICAgICAgICAgbGluZSA9IGxpbmUuZHJvcF9mcm9udCgpLmx0cmltKCIgXHQiKTsKKyAgICAgICAgfQorCisgICAgICAgIHZhbHVlID0gVmFsdWU6Ok1ha2VTdHJpbmdBcnJheShzdGQ6Om1vdmUoc3RyaW5nX2FycmF5KSk7CisgICAgICAgIGJyZWFrOworICAgICAgfQorICAgICAgZGVmYXVsdDoKKyAgICAgICAgYnJlYWs7CisgICAgfQorICAgIGlmICghbmFtZS5lbXB0eSgpICYmIHZhbHVlKQorICAgICAgZW50cmllcy5wdXNoX2JhY2soc3RkOjptYWtlX3BhaXIoc3RkOjptb3ZlKG5hbWUpLCBzdGQ6Om1vdmUodmFsdWUpKSk7CituZXh0X2xpbmU6CisgICAgOworICB9CisKKyAgLy8gY29weSB2YWx1ZXMgaW50byBzdG9yYWdlIGFzIHF1aWNrbHkgYXMgcG9zc2libGUgc28gbG9jayBpc24ndCBoZWxkCisgIHsKKyAgICBzdGQ6OnZlY3RvcjxzdGQ6OnNoYXJlZF9wdHI8TWVzc2FnZT4+IG1zZ3M7CisgICAgc3RkOjp1bmlxdWVfbG9jazxzdGQ6Om11dGV4PiBsb2NrKG1fbXV0ZXgpOworICAgIGZvciAoYXV0byYgaSA6IGVudHJpZXMpIHsKKyAgICAgIGF1dG8mIG5ld19lbnRyeSA9IG1fZW50cmllc1tpLmZpcnN0XTsKKyAgICAgIGlmICghbmV3X2VudHJ5KSBuZXdfZW50cnkucmVzZXQobmV3IEVudHJ5KGkuZmlyc3QpKTsKKyAgICAgIEVudHJ5KiBlbnRyeSA9IG5ld19lbnRyeS5nZXQoKTsKKyAgICAgIGF1dG8gb2xkX3ZhbHVlID0gZW50cnktPnZhbHVlOworICAgICAgZW50cnktPnZhbHVlID0gaS5zZWNvbmQ7CisgICAgICBib29sIHdhc19wZXJzaXN0ID0gZW50cnktPklzUGVyc2lzdGVudCgpOworICAgICAgaWYgKCF3YXNfcGVyc2lzdCkgZW50cnktPmZsYWdzIHw9IE5UX1BFUlNJU1RFTlQ7CisKKyAgICAgIC8vIGlmIHdlJ3JlIHRoZSBzZXJ2ZXIsIGFzc2lnbiBhbiBpZCBpZiBpdCBkb2Vzbid0IGhhdmUgb25lCisgICAgICBpZiAobV9zZXJ2ZXIgJiYgZW50cnktPmlkID09IDB4ZmZmZikgeworICAgICAgICB1bnNpZ25lZCBpbnQgaWQgPSBtX2lkbWFwLnNpemUoKTsKKyAgICAgICAgZW50cnktPmlkID0gaWQ7CisgICAgICAgIG1faWRtYXAucHVzaF9iYWNrKGVudHJ5KTsKKyAgICAgIH0KKworICAgICAgLy8gbm90aWZ5IChmb3IgbG9jYWwgbGlzdGVuZXJzKQorICAgICAgaWYgKG1fbm90aWZpZXIubG9jYWxfbm90aWZpZXJzKCkpIHsKKyAgICAgICAgaWYgKCFvbGRfdmFsdWUpCisgICAgICAgICAgbV9ub3RpZmllci5Ob3RpZnlFbnRyeShpLmZpcnN0LCBpLnNlY29uZCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE5UX05PVElGWV9ORVcgfCBOVF9OT1RJRllfTE9DQUwpOworICAgICAgICBlbHNlIGlmICgqb2xkX3ZhbHVlICE9ICppLnNlY29uZCkgeworICAgICAgICAgIHVuc2lnbmVkIGludCBub3RpZnlfZmxhZ3MgPSBOVF9OT1RJRllfVVBEQVRFIHwgTlRfTk9USUZZX0xPQ0FMOworICAgICAgICAgIGlmICghd2FzX3BlcnNpc3QpIG5vdGlmeV9mbGFncyB8PSBOVF9OT1RJRllfRkxBR1M7CisgICAgICAgICAgbV9ub3RpZmllci5Ob3RpZnlFbnRyeShpLmZpcnN0LCBpLnNlY29uZCwgbm90aWZ5X2ZsYWdzKTsKKyAgICAgICAgfQorICAgICAgfQorCisgICAgICBpZiAoIW1fcXVldWVfb3V0Z29pbmcpIGNvbnRpbnVlOyAgLy8gc2hvcnRjdXQKKyAgICAgICsrZW50cnktPnNlcV9udW07CisKKyAgICAgIC8vIHB1dCBvbiB1cGRhdGUgcXVldWUKKyAgICAgIGlmICghb2xkX3ZhbHVlIHx8IG9sZF92YWx1ZS0+dHlwZSgpICE9IGkuc2Vjb25kLT50eXBlKCkpCisgICAgICAgIG1zZ3MuZW1wbGFjZV9iYWNrKE1lc3NhZ2U6OkVudHJ5QXNzaWduKGkuZmlyc3QsIGVudHJ5LT5pZCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZW50cnktPnNlcV9udW0udmFsdWUoKSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaS5zZWNvbmQsIGVudHJ5LT5mbGFncykpOworICAgICAgZWxzZSBpZiAoZW50cnktPmlkICE9IDB4ZmZmZikgeworICAgICAgICAvLyBkb24ndCBzZW5kIGFuIHVwZGF0ZSBpZiB3ZSBkb24ndCBoYXZlIGFuIGFzc2lnbmVkIGlkIHlldAorICAgICAgICBpZiAoKm9sZF92YWx1ZSAhPSAqaS5zZWNvbmQpCisgICAgICAgICAgbXNncy5lbXBsYWNlX2JhY2soTWVzc2FnZTo6RW50cnlVcGRhdGUoCisgICAgICAgICAgICAgIGVudHJ5LT5pZCwgZW50cnktPnNlcV9udW0udmFsdWUoKSwgaS5zZWNvbmQpKTsKKyAgICAgICAgaWYgKCF3YXNfcGVyc2lzdCkKKyAgICAgICAgICBtc2dzLmVtcGxhY2VfYmFjayhNZXNzYWdlOjpGbGFnc1VwZGF0ZShlbnRyeS0+aWQsIGVudHJ5LT5mbGFncykpOworICAgICAgfQorICAgIH0KKworICAgIGlmIChtX3F1ZXVlX291dGdvaW5nKSB7CisgICAgICBhdXRvIHF1ZXVlX291dGdvaW5nID0gbV9xdWV1ZV9vdXRnb2luZzsKKyAgICAgIGxvY2sudW5sb2NrKCk7CisgICAgICBmb3IgKGF1dG8mIG1zZyA6IG1zZ3MpIHF1ZXVlX291dGdvaW5nKHN0ZDo6bW92ZShtc2cpLCBudWxscHRyLCBudWxscHRyKTsKKyAgICB9CisgIH0KKworICByZXR1cm4gdHJ1ZTsKK30KKworY29uc3QgY2hhciogU3RvcmFnZTo6TG9hZFBlcnNpc3RlbnQoCisgICAgU3RyaW5nUmVmIGZpbGVuYW1lLAorICAgIHN0ZDo6ZnVuY3Rpb248dm9pZChzdGQ6OnNpemVfdCBsaW5lLCBjb25zdCBjaGFyKiBtc2cpPiB3YXJuKSB7CisgIHN0ZDo6aWZzdHJlYW0gaXMoZmlsZW5hbWUpOworICBpZiAoIWlzKSByZXR1cm4gImNvdWxkIG5vdCBvcGVuIGZpbGUiOworICBpZiAoIUxvYWRQZXJzaXN0ZW50KGlzLCB3YXJuKSkgcmV0dXJuICJlcnJvciByZWFkaW5nIGZpbGUiOworICByZXR1cm4gbnVsbHB0cjsKK30KKwordm9pZCBTdG9yYWdlOjpDcmVhdGVScGMoU3RyaW5nUmVmIG5hbWUsIFN0cmluZ1JlZiBkZWYsIFJwY0NhbGxiYWNrIGNhbGxiYWNrKSB7CisgIGlmIChuYW1lLmVtcHR5KCkgfHwgZGVmLmVtcHR5KCkgfHwgIWNhbGxiYWNrKSByZXR1cm47CisgIHN0ZDo6dW5pcXVlX2xvY2s8c3RkOjptdXRleD4gbG9jayhtX211dGV4KTsKKyAgaWYgKCFtX3NlcnZlcikgcmV0dXJuOyAvLyBvbmx5IHNlcnZlciBjYW4gY3JlYXRlIFJQQ3MKKworICBhdXRvJiBuZXdfZW50cnkgPSBtX2VudHJpZXNbbmFtZV07CisgIGlmICghbmV3X2VudHJ5KSBuZXdfZW50cnkucmVzZXQobmV3IEVudHJ5KG5hbWUpKTsKKyAgRW50cnkqIGVudHJ5ID0gbmV3X2VudHJ5LmdldCgpOworICBhdXRvIG9sZF92YWx1ZSA9IGVudHJ5LT52YWx1ZTsKKyAgYXV0byB2YWx1ZSA9IFZhbHVlOjpNYWtlUnBjKGRlZik7CisgIGVudHJ5LT52YWx1ZSA9IHZhbHVlOworCisgIC8vIHNldCB1cCB0aGUgbmV3IGNhbGxiYWNrCisgIGVudHJ5LT5ycGNfY2FsbGJhY2sgPSBjYWxsYmFjazsKKworICAvLyBzdGFydCB0aGUgUlBDIHNlcnZlcgorICBpZiAoIW1fcnBjX3NlcnZlci5hY3RpdmUoKSkgbV9ycGNfc2VydmVyLlN0YXJ0KCk7CisKKyAgaWYgKG9sZF92YWx1ZSAmJiAqb2xkX3ZhbHVlID09ICp2YWx1ZSkgcmV0dXJuOworCisgIC8vIGFzc2lnbiBhbiBpZCBpZiBpdCBkb2Vzbid0IGhhdmUgb25lCisgIGlmIChlbnRyeS0+aWQgPT0gMHhmZmZmKSB7CisgICAgdW5zaWduZWQgaW50IGlkID0gbV9pZG1hcC5zaXplKCk7CisgICAgZW50cnktPmlkID0gaWQ7CisgICAgbV9pZG1hcC5wdXNoX2JhY2soZW50cnkpOworICB9CisKKyAgLy8gZ2VuZXJhdGUgbWVzc2FnZQorICBpZiAoIW1fcXVldWVfb3V0Z29pbmcpIHJldHVybjsKKyAgYXV0byBxdWV1ZV9vdXRnb2luZyA9IG1fcXVldWVfb3V0Z29pbmc7CisgIGlmICghb2xkX3ZhbHVlIHx8IG9sZF92YWx1ZS0+dHlwZSgpICE9IHZhbHVlLT50eXBlKCkpIHsKKyAgICArK2VudHJ5LT5zZXFfbnVtOworICAgIGF1dG8gbXNnID0gTWVzc2FnZTo6RW50cnlBc3NpZ24obmFtZSwgZW50cnktPmlkLCBlbnRyeS0+c2VxX251bS52YWx1ZSgpLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFsdWUsIGVudHJ5LT5mbGFncyk7CisgICAgbG9jay51bmxvY2soKTsKKyAgICBxdWV1ZV9vdXRnb2luZyhtc2csIG51bGxwdHIsIG51bGxwdHIpOworICB9IGVsc2UgeworICAgICsrZW50cnktPnNlcV9udW07CisgICAgYXV0byBtc2cgPSBNZXNzYWdlOjpFbnRyeVVwZGF0ZShlbnRyeS0+aWQsIGVudHJ5LT5zZXFfbnVtLnZhbHVlKCksIHZhbHVlKTsKKyAgICBsb2NrLnVubG9jaygpOworICAgIHF1ZXVlX291dGdvaW5nKG1zZywgbnVsbHB0ciwgbnVsbHB0cik7CisgIH0KK30KKwordm9pZCBTdG9yYWdlOjpDcmVhdGVQb2xsZWRScGMoU3RyaW5nUmVmIG5hbWUsIFN0cmluZ1JlZiBkZWYpIHsKKyAgaWYgKG5hbWUuZW1wdHkoKSB8fCBkZWYuZW1wdHkoKSkgcmV0dXJuOworICBzdGQ6OnVuaXF1ZV9sb2NrPHN0ZDo6bXV0ZXg+IGxvY2sobV9tdXRleCk7CisgIGlmICghbV9zZXJ2ZXIpIHJldHVybjsgLy8gb25seSBzZXJ2ZXIgY2FuIGNyZWF0ZSBSUENzCisKKyAgYXV0byYgbmV3X2VudHJ5ID0gbV9lbnRyaWVzW25hbWVdOworICBpZiAoIW5ld19lbnRyeSkgbmV3X2VudHJ5LnJlc2V0KG5ldyBFbnRyeShuYW1lKSk7CisgIEVudHJ5KiBlbnRyeSA9IG5ld19lbnRyeS5nZXQoKTsKKyAgYXV0byBvbGRfdmFsdWUgPSBlbnRyeS0+dmFsdWU7CisgIGF1dG8gdmFsdWUgPSBWYWx1ZTo6TWFrZVJwYyhkZWYpOworICBlbnRyeS0+dmFsdWUgPSB2YWx1ZTsKKworICAvLyBhIG51bGxwdHIgY2FsbGJhY2sgaW5kaWNhdGVzIGEgcG9sbGVkIFJQQworICBlbnRyeS0+cnBjX2NhbGxiYWNrID0gbnVsbHB0cjsKKworICBpZiAob2xkX3ZhbHVlICYmICpvbGRfdmFsdWUgPT0gKnZhbHVlKSByZXR1cm47CisKKyAgLy8gYXNzaWduIGFuIGlkIGlmIGl0IGRvZXNuJ3QgaGF2ZSBvbmUKKyAgaWYgKGVudHJ5LT5pZCA9PSAweGZmZmYpIHsKKyAgICB1bnNpZ25lZCBpbnQgaWQgPSBtX2lkbWFwLnNpemUoKTsKKyAgICBlbnRyeS0+aWQgPSBpZDsKKyAgICBtX2lkbWFwLnB1c2hfYmFjayhlbnRyeSk7CisgIH0KKworICAvLyBnZW5lcmF0ZSBtZXNzYWdlCisgIGlmICghbV9xdWV1ZV9vdXRnb2luZykgcmV0dXJuOworICBhdXRvIHF1ZXVlX291dGdvaW5nID0gbV9xdWV1ZV9vdXRnb2luZzsKKyAgaWYgKCFvbGRfdmFsdWUgfHwgb2xkX3ZhbHVlLT50eXBlKCkgIT0gdmFsdWUtPnR5cGUoKSkgeworICAgICsrZW50cnktPnNlcV9udW07CisgICAgYXV0byBtc2cgPSBNZXNzYWdlOjpFbnRyeUFzc2lnbihuYW1lLCBlbnRyeS0+aWQsIGVudHJ5LT5zZXFfbnVtLnZhbHVlKCksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YWx1ZSwgZW50cnktPmZsYWdzKTsKKyAgICBsb2NrLnVubG9jaygpOworICAgIHF1ZXVlX291dGdvaW5nKG1zZywgbnVsbHB0ciwgbnVsbHB0cik7CisgIH0gZWxzZSB7CisgICAgKytlbnRyeS0+c2VxX251bTsKKyAgICBhdXRvIG1zZyA9IE1lc3NhZ2U6OkVudHJ5VXBkYXRlKGVudHJ5LT5pZCwgZW50cnktPnNlcV9udW0udmFsdWUoKSwgdmFsdWUpOworICAgIGxvY2sudW5sb2NrKCk7CisgICAgcXVldWVfb3V0Z29pbmcobXNnLCBudWxscHRyLCBudWxscHRyKTsKKyAgfQorfQorCit1bnNpZ25lZCBpbnQgU3RvcmFnZTo6Q2FsbFJwYyhTdHJpbmdSZWYgbmFtZSwgU3RyaW5nUmVmIHBhcmFtcykgeworICBzdGQ6OnVuaXF1ZV9sb2NrPHN0ZDo6bXV0ZXg+IGxvY2sobV9tdXRleCk7CisgIGF1dG8gaSA9IG1fZW50cmllcy5maW5kKG5hbWUpOworICBpZiAoaSA9PSBtX2VudHJpZXMuZW5kKCkpIHJldHVybiAwOworICBhdXRvJiBlbnRyeSA9IGktPmdldFZhbHVlKCk7CisgIGlmICghZW50cnktPnZhbHVlLT5Jc1JwYygpKSByZXR1cm4gMDsKKworICArK2VudHJ5LT5ycGNfY2FsbF91aWQ7CisgIGlmIChlbnRyeS0+cnBjX2NhbGxfdWlkID4gMHhmZmZmKSBlbnRyeS0+cnBjX2NhbGxfdWlkID0gMDsKKyAgdW5zaWduZWQgaW50IGNvbWJpbmVkX3VpZCA9IChlbnRyeS0+aWQgPDwgMTYpIHwgZW50cnktPnJwY19jYWxsX3VpZDsKKyAgYXV0byBtc2cgPSBNZXNzYWdlOjpFeGVjdXRlUnBjKGVudHJ5LT5pZCwgZW50cnktPnJwY19jYWxsX3VpZCwgcGFyYW1zKTsKKyAgaWYgKG1fc2VydmVyKSB7CisgICAgLy8gUlBDcyBhcmUgdW5saWtlbHkgdG8gYmUgdXNlZCBsb2NhbGx5IG9uIHRoZSBzZXJ2ZXIsIGJ1dCBoYW5kbGUgaXQKKyAgICAvLyBncmFjZWZ1bGx5IGFueXdheS4KKyAgICBhdXRvIHJwY19jYWxsYmFjayA9IGVudHJ5LT5ycGNfY2FsbGJhY2s7CisgICAgbG9jay51bmxvY2soKTsKKyAgICBtX3JwY19zZXJ2ZXIuUHJvY2Vzc1JwYygKKyAgICAgICAgbmFtZSwgbXNnLCBycGNfY2FsbGJhY2ssIDB4ZmZmZlUsIFt0aGlzXShzdGQ6OnNoYXJlZF9wdHI8TWVzc2FnZT4gbXNnKSB7CisgICAgICAgICAgc3RkOjpsb2NrX2d1YXJkPHN0ZDo6bXV0ZXg+IGxvY2sobV9tdXRleCk7CisgICAgICAgICAgbV9ycGNfcmVzdWx0cy5pbnNlcnQoc3RkOjptYWtlX3BhaXIoCisgICAgICAgICAgICAgIHN0ZDo6bWFrZV9wYWlyKG1zZy0+aWQoKSwgbXNnLT5zZXFfbnVtX3VpZCgpKSwgbXNnLT5zdHIoKSkpOworICAgICAgICAgIG1fcnBjX3Jlc3VsdHNfY29uZC5ub3RpZnlfYWxsKCk7CisgICAgICAgIH0pOworICB9IGVsc2UgeworICAgIGF1dG8gcXVldWVfb3V0Z29pbmcgPSBtX3F1ZXVlX291dGdvaW5nOworICAgIGxvY2sudW5sb2NrKCk7CisgICAgcXVldWVfb3V0Z29pbmcobXNnLCBudWxscHRyLCBudWxscHRyKTsKKyAgfQorICByZXR1cm4gY29tYmluZWRfdWlkOworfQorCitib29sIFN0b3JhZ2U6OkdldFJwY1Jlc3VsdChib29sIGJsb2NraW5nLCB1bnNpZ25lZCBpbnQgY2FsbF91aWQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICBzdGQ6OnN0cmluZyogcmVzdWx0KSB7CisgIHN0ZDo6dW5pcXVlX2xvY2s8c3RkOjptdXRleD4gbG9jayhtX211dGV4KTsKKyAgZm9yICg7OykgeworICAgIGF1dG8gaSA9CisgICAgICAgIG1fcnBjX3Jlc3VsdHMuZmluZChzdGQ6Om1ha2VfcGFpcihjYWxsX3VpZCA+PiAxNiwgY2FsbF91aWQgJiAweGZmZmYpKTsKKyAgICBpZiAoaSA9PSBtX3JwY19yZXN1bHRzLmVuZCgpKSB7CisgICAgICBpZiAoIWJsb2NraW5nIHx8IG1fdGVybWluYXRpbmcpIHJldHVybiBmYWxzZTsKKyAgICAgIG1fcnBjX3Jlc3VsdHNfY29uZC53YWl0KGxvY2spOworICAgICAgaWYgKG1fdGVybWluYXRpbmcpIHJldHVybiBmYWxzZTsKKyAgICAgIGNvbnRpbnVlOworICAgIH0KKyAgICByZXN1bHQtPnN3YXAoaS0+Z2V0U2Vjb25kKCkpOworICAgIG1fcnBjX3Jlc3VsdHMuZXJhc2UoaSk7CisgICAgcmV0dXJuIHRydWU7CisgIH0KK30KZGlmZiAtLWdpdCBhL3NyYy9TdG9yYWdlLmggYi9zcmMvU3RvcmFnZS5oCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmM4N2EzN2IKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvU3RvcmFnZS5oCkBAIC0wLDAgKzEsMTczIEBACisvKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qLworLyogQ29weXJpZ2h0IChjKSBGSVJTVCAyMDE1LiBBbGwgUmlnaHRzIFJlc2VydmVkLiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKi8KKy8qIE9wZW4gU291cmNlIFNvZnR3YXJlIC0gbWF5IGJlIG1vZGlmaWVkIGFuZCBzaGFyZWQgYnkgRlJDIHRlYW1zLiBUaGUgY29kZSAgICovCisvKiBtdXN0IGJlIGFjY29tcGFuaWVkIGJ5IHRoZSBGSVJTVCBCU0QgbGljZW5zZSBmaWxlIGluIHRoZSByb290IGRpcmVjdG9yeSBvZiAqLworLyogdGhlIHByb2plY3QuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKi8KKy8qLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovCisKKyNpZm5kZWYgTlRfU1RPUkFHRV9IXworI2RlZmluZSBOVF9TVE9SQUdFX0hfCisKKyNpbmNsdWRlIDxhdG9taWM+CisjaW5jbHVkZSA8Y3N0ZGRlZj4KKyNpbmNsdWRlIDxmc3RyZWFtPgorI2luY2x1ZGUgPGZ1bmN0aW9uYWw+CisjaW5jbHVkZSA8aW9zZndkPgorI2luY2x1ZGUgPG1lbW9yeT4KKyNpbmNsdWRlIDxtdXRleD4KKyNpbmNsdWRlIDx2ZWN0b3I+CisKKyNpbmNsdWRlICJsbHZtL0RlbnNlTWFwLmgiCisjaW5jbHVkZSAibGx2bS9TdHJpbmdNYXAuaCIKKyNpbmNsdWRlICJhdG9taWNfc3RhdGljLmgiCisjaW5jbHVkZSAiTWVzc2FnZS5oIgorI2luY2x1ZGUgIk5vdGlmaWVyLmgiCisjaW5jbHVkZSAibnRjb3JlX2NwcC5oIgorI2luY2x1ZGUgIlJwY1NlcnZlci5oIgorI2luY2x1ZGUgIlNlcXVlbmNlTnVtYmVyLmgiCisKK25hbWVzcGFjZSBudCB7CisKK2NsYXNzIE5ldHdvcmtDb25uZWN0aW9uOworY2xhc3MgU3RvcmFnZVRlc3Q7CisKK2NsYXNzIFN0b3JhZ2UgeworICBmcmllbmQgY2xhc3MgU3RvcmFnZVRlc3Q7CisgcHVibGljOgorICBzdGF0aWMgU3RvcmFnZSYgR2V0SW5zdGFuY2UoKSB7CisgICAgQVRPTUlDX1NUQVRJQyhTdG9yYWdlLCBpbnN0YW5jZSk7CisgICAgcmV0dXJuIGluc3RhbmNlOworICB9CisgIH5TdG9yYWdlKCk7CisKKyAgLy8gQWNjZXNzb3JzIHJlcXVpcmVkIGJ5IERpc3BhdGNoZXIuICBBIGZ1bmN0aW9uIHBvaW50ZXIgaXMgdXNlZCBmb3IKKyAgLy8gZ2VuZXJhdGlvbiBvZiBvdXRnb2luZyBtZXNzYWdlcyB0byBicmVhayBhIGRlcGVuZGVuY3kgbG9vcCBiZXR3ZWVuCisgIC8vIFN0b3JhZ2UgYW5kIERpc3BhdGNoZXI7IGluIG9wZXJhdGlvbiB0aGlzIGlzIGFsd2F5cyBzZXQgdG8KKyAgLy8gRGlzcGF0Y2hlcjo6UXVldWVPdXRnb2luZy4KKyAgdHlwZWRlZiBzdGQ6OmZ1bmN0aW9uPHZvaWQoc3RkOjpzaGFyZWRfcHRyPE1lc3NhZ2U+IG1zZywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTmV0d29ya0Nvbm5lY3Rpb24qIG9ubHksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE5ldHdvcmtDb25uZWN0aW9uKiBleGNlcHQpPiBRdWV1ZU91dGdvaW5nRnVuYzsKKyAgdm9pZCBTZXRPdXRnb2luZyhRdWV1ZU91dGdvaW5nRnVuYyBxdWV1ZV9vdXRnb2luZywgYm9vbCBzZXJ2ZXIpOworICB2b2lkIENsZWFyT3V0Z29pbmcoKTsKKworICAvLyBSZXF1aXJlZCBmb3Igd2lyZSBwcm90b2NvbCAyLjAgdG8gZ2V0IHRoZSBlbnRyeSB0eXBlIG9mIGFuIGVudHJ5IHdoZW4KKyAgLy8gcmVjZWl2aW5nIGVudHJ5IHVwZGF0ZXMgKGJlY2F1c2UgdGhlIGxlbmd0aC90eXBlIGlzIG5vdCBwcm92aWRlZCBpbiB0aGUKKyAgLy8gbWVzc2FnZSBpdHNlbGYpLiAgTm90IHVzZWQgaW4gd2lyZSBwcm90b2NvbCAzLjAuCisgIE5UX1R5cGUgR2V0RW50cnlUeXBlKHVuc2lnbmVkIGludCBpZCkgY29uc3Q7CisKKyAgdm9pZCBQcm9jZXNzSW5jb21pbmcoc3RkOjpzaGFyZWRfcHRyPE1lc3NhZ2U+IG1zZywgTmV0d29ya0Nvbm5lY3Rpb24qIGNvbm4sCisgICAgICAgICAgICAgICAgICAgICAgIHN0ZDo6d2Vha19wdHI8TmV0d29ya0Nvbm5lY3Rpb24+IGNvbm5fd2Vhayk7CisgIHZvaWQgR2V0SW5pdGlhbEFzc2lnbm1lbnRzKE5ldHdvcmtDb25uZWN0aW9uJiBjb25uLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdGQ6OnZlY3RvcjxzdGQ6OnNoYXJlZF9wdHI8TWVzc2FnZT4+KiBtc2dzKTsKKyAgdm9pZCBBcHBseUluaXRpYWxBc3NpZ25tZW50cyhOZXR3b3JrQ29ubmVjdGlvbiYgY29ubiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsbHZtOjpBcnJheVJlZjxzdGQ6OnNoYXJlZF9wdHI8TWVzc2FnZT4+IG1zZ3MsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYm9vbCBuZXdfc2VydmVyLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0ZDo6dmVjdG9yPHN0ZDo6c2hhcmVkX3B0cjxNZXNzYWdlPj4qIG91dF9tc2dzKTsKKworICAvLyBVc2VyIGZ1bmN0aW9ucy4gIFRoZXNlIGFyZSB0aGUgYWN0dWFsIGltcGxlbWVudGF0aW9ucyBvZiB0aGUgY29ycmVzcG9uZGluZworICAvLyB1c2VyIEFQSSBmdW5jdGlvbnMgaW4gbnRjb3JlX2NwcC4KKyAgc3RkOjpzaGFyZWRfcHRyPFZhbHVlPiBHZXRFbnRyeVZhbHVlKFN0cmluZ1JlZiBuYW1lKSBjb25zdDsKKyAgYm9vbCBTZXRFbnRyeVZhbHVlKFN0cmluZ1JlZiBuYW1lLCBzdGQ6OnNoYXJlZF9wdHI8VmFsdWU+IHZhbHVlKTsKKyAgdm9pZCBTZXRFbnRyeVR5cGVWYWx1ZShTdHJpbmdSZWYgbmFtZSwgc3RkOjpzaGFyZWRfcHRyPFZhbHVlPiB2YWx1ZSk7CisgIHZvaWQgU2V0RW50cnlGbGFncyhTdHJpbmdSZWYgbmFtZSwgdW5zaWduZWQgaW50IGZsYWdzKTsKKyAgdW5zaWduZWQgaW50IEdldEVudHJ5RmxhZ3MoU3RyaW5nUmVmIG5hbWUpIGNvbnN0OworICB2b2lkIERlbGV0ZUVudHJ5KFN0cmluZ1JlZiBuYW1lKTsKKyAgdm9pZCBEZWxldGVBbGxFbnRyaWVzKCk7CisgIHN0ZDo6dmVjdG9yPEVudHJ5SW5mbz4gR2V0RW50cnlJbmZvKFN0cmluZ1JlZiBwcmVmaXgsIHVuc2lnbmVkIGludCB0eXBlcyk7CisgIHZvaWQgTm90aWZ5RW50cmllcyhTdHJpbmdSZWYgcHJlZml4LAorICAgICAgICAgICAgICAgICAgICAgRW50cnlMaXN0ZW5lckNhbGxiYWNrIG9ubHkgPSBudWxscHRyKSBjb25zdDsKKworICAvLyBGaWxlbmFtZS1iYXNlZCBzYXZlL2xvYWQgZnVuY3Rpb25zLiAgVXNlZCBib3RoIGJ5IHBlcmlvZGljIHNhdmVzIGFuZAorICAvLyBhY2Nlc3NpYmxlIGRpcmVjdGx5IHZpYSB0aGUgdXNlciBBUEkuCisgIGNvbnN0IGNoYXIqIFNhdmVQZXJzaXN0ZW50KFN0cmluZ1JlZiBmaWxlbmFtZSwgYm9vbCBwZXJpb2RpYykgY29uc3Q7CisgIGNvbnN0IGNoYXIqIExvYWRQZXJzaXN0ZW50KAorICAgICAgU3RyaW5nUmVmIGZpbGVuYW1lLAorICAgICAgc3RkOjpmdW5jdGlvbjx2b2lkKHN0ZDo6c2l6ZV90IGxpbmUsIGNvbnN0IGNoYXIqIG1zZyk+IHdhcm4pOworCisgIC8vIFN0cmVhbS1iYXNlZCBzYXZlL2xvYWQgZnVuY3Rpb25zIChleHBvc2VkIGZvciB0ZXN0aW5nIHB1cnBvc2VzKS4gIFRoZXNlCisgIC8vIGltcGxlbWVudCB0aGUgZ3V0cyBvZiB0aGUgZmlsZW5hbWUtYmFzZWQgZnVuY3Rpb25zLgorICB2b2lkIFNhdmVQZXJzaXN0ZW50KHN0ZDo6b3N0cmVhbSYgb3MsIGJvb2wgcGVyaW9kaWMpIGNvbnN0OworICBib29sIExvYWRQZXJzaXN0ZW50KAorICAgICAgc3RkOjppc3RyZWFtJiBpcywKKyAgICAgIHN0ZDo6ZnVuY3Rpb248dm9pZChzdGQ6OnNpemVfdCBsaW5lLCBjb25zdCBjaGFyKiBtc2cpPiB3YXJuKTsKKworICAvLyBSUEMgY29uZmlndXJhdGlvbiBuZWVkcyB0byBjb21lIHRocm91Z2ggaGVyZSBhcyBSUEMgZGVmaW5pdGlvbnMgYXJlCisgIC8vIGFjdHVhbGx5IHNwZWNpYWwgU3RvcmFnZSB2YWx1ZSB0eXBlcy4KKyAgdm9pZCBDcmVhdGVScGMoU3RyaW5nUmVmIG5hbWUsIFN0cmluZ1JlZiBkZWYsIFJwY0NhbGxiYWNrIGNhbGxiYWNrKTsKKyAgdm9pZCBDcmVhdGVQb2xsZWRScGMoU3RyaW5nUmVmIG5hbWUsIFN0cmluZ1JlZiBkZWYpOworCisgIHVuc2lnbmVkIGludCBDYWxsUnBjKFN0cmluZ1JlZiBuYW1lLCBTdHJpbmdSZWYgcGFyYW1zKTsKKyAgYm9vbCBHZXRScGNSZXN1bHQoYm9vbCBibG9ja2luZywgdW5zaWduZWQgaW50IGNhbGxfdWlkLCBzdGQ6OnN0cmluZyogcmVzdWx0KTsKKworIHByaXZhdGU6CisgIFN0b3JhZ2UoKTsKKyAgU3RvcmFnZShOb3RpZmllciYgbm90aWZpZXIsIFJwY1NlcnZlciYgcnBjc2VydmVyKTsKKyAgU3RvcmFnZShjb25zdCBTdG9yYWdlJikgPSBkZWxldGU7CisgIFN0b3JhZ2UmIG9wZXJhdG9yPShjb25zdCBTdG9yYWdlJikgPSBkZWxldGU7CisKKyAgLy8gRGF0YSBmb3IgZWFjaCB0YWJsZSBlbnRyeS4KKyAgc3RydWN0IEVudHJ5IHsKKyAgICBFbnRyeShsbHZtOjpTdHJpbmdSZWYgbmFtZV8pCisgICAgICAgIDogbmFtZShuYW1lXyksIGZsYWdzKDApLCBpZCgweGZmZmYpLCBycGNfY2FsbF91aWQoMCkge30KKyAgICBib29sIElzUGVyc2lzdGVudCgpIGNvbnN0IHsgcmV0dXJuIChmbGFncyAmIE5UX1BFUlNJU1RFTlQpICE9IDA7IH0KKworICAgIC8vIFdlIHJlZHVuZGFudGx5IHN0b3JlIHRoZSBuYW1lIHNvIHRoYXQgaXQncyBhdmFpbGFibGUgd2hlbiBhY2Nlc3NpbmcgdGhlCisgICAgLy8gcmF3IEVudHJ5KiB2aWEgdGhlIElEIG1hcC4KKyAgICBzdGQ6OnN0cmluZyBuYW1lOworCisgICAgLy8gVGhlIGN1cnJlbnQgdmFsdWUgYW5kIGZsYWdzLgorICAgIHN0ZDo6c2hhcmVkX3B0cjxWYWx1ZT4gdmFsdWU7CisgICAgdW5zaWduZWQgaW50IGZsYWdzOworCisgICAgLy8gVW5pcXVlIElEIGZvciB0aGlzIGVudHJ5IGFzIHVzZWQgaW4gbmV0d29yayBtZXNzYWdlcy4gIFRoZSB2YWx1ZSBpcworICAgIC8vIGFzc2lnbmVkIGJ5IHRoZSBzZXJ2ZXIsIHNvIG9uIHRoZSBjbGllbnQgdGhpcyBpcyAweGZmZmYgdW50aWwgYW4KKyAgICAvLyBlbnRyeSBhc3NpZ25tZW50IGlzIHJlY2VpdmVkIGJhY2sgZnJvbSB0aGUgc2VydmVyLgorICAgIHVuc2lnbmVkIGludCBpZDsKKworICAgIC8vIFNlcXVlbmNlIG51bWJlciBmb3IgdXBkYXRlIHJlc29sdXRpb24uCisgICAgU2VxdWVuY2VOdW1iZXIgc2VxX251bTsKKworICAgIC8vIFJQQyBjYWxsYmFjayBmdW5jdGlvbi4gIE51bGwgaWYgZWl0aGVyIG5vdCBhbiBSUEMgb3IgaWYgdGhlIFJQQyBpcworICAgIC8vIHBvbGxlZC4KKyAgICBScGNDYWxsYmFjayBycGNfY2FsbGJhY2s7CisKKyAgICAvLyBMYXN0IFVJRCB1c2VkIHdoZW4gY2FsbGluZyB0aGlzIFJQQyAocHJpbWFyaWx5IGZvciBjbGllbnQgdXNlKS4gIFRoaXMKKyAgICAvLyBpcyBpbmNyZW1lbnRlZCBmb3IgZWFjaCBjYWxsLgorICAgIHVuc2lnbmVkIGludCBycGNfY2FsbF91aWQ7CisgIH07CisKKyAgdHlwZWRlZiBsbHZtOjpTdHJpbmdNYXA8c3RkOjp1bmlxdWVfcHRyPEVudHJ5Pj4gRW50cmllc01hcDsKKyAgdHlwZWRlZiBzdGQ6OnZlY3RvcjxFbnRyeSo+IElkTWFwOworICB0eXBlZGVmIGxsdm06OkRlbnNlTWFwPHN0ZDo6cGFpcjx1bnNpZ25lZCBpbnQsIHVuc2lnbmVkIGludD4sIHN0ZDo6c3RyaW5nPgorICAgICAgUnBjUmVzdWx0TWFwOworCisgIG11dGFibGUgc3RkOjptdXRleCBtX211dGV4OworICBFbnRyaWVzTWFwIG1fZW50cmllczsKKyAgSWRNYXAgbV9pZG1hcDsKKyAgUnBjUmVzdWx0TWFwIG1fcnBjX3Jlc3VsdHM7CisgIC8vIElmIGFueSBwZXJzaXN0ZW50IHZhbHVlcyBoYXZlIGNoYW5nZWQKKyAgbXV0YWJsZSBib29sIG1fcGVyc2lzdGVudF9kaXJ0eSA9IGZhbHNlOworCisgIC8vIGNvbmRpdGlvbiB2YXJpYWJsZSBhbmQgdGVybWluYXRpb24gZmxhZyBmb3IgYmxvY2tpbmcgb24gYSBSUEMgcmVzdWx0CisgIHN0ZDo6YXRvbWljX2Jvb2wgbV90ZXJtaW5hdGluZzsKKyAgc3RkOjpjb25kaXRpb25fdmFyaWFibGUgbV9ycGNfcmVzdWx0c19jb25kOworCisgIC8vIGNvbmZpZ3VyZWQgYnkgZGlzcGF0Y2hlciBhdCBzdGFydHVwCisgIFF1ZXVlT3V0Z29pbmdGdW5jIG1fcXVldWVfb3V0Z29pbmc7CisgIGJvb2wgbV9zZXJ2ZXIgPSB0cnVlOworCisgIC8vIHJlZmVyZW5jZXMgdG8gc2luZ2xldG9ucyAod2UgZG9uJ3QgZ3JhYiB0aGVtIGRpcmVjdGx5IGZvciB0ZXN0aW5nIHB1cnBvc2VzKQorICBOb3RpZmllciYgbV9ub3RpZmllcjsKKyAgUnBjU2VydmVyJiBtX3JwY19zZXJ2ZXI7CisKKyAgYm9vbCBHZXRQZXJzaXN0ZW50RW50cmllcygKKyAgICAgIGJvb2wgcGVyaW9kaWMsCisgICAgICBzdGQ6OnZlY3RvcjxzdGQ6OnBhaXI8c3RkOjpzdHJpbmcsIHN0ZDo6c2hhcmVkX3B0cjxWYWx1ZT4+PiogZW50cmllcykKKyAgICAgIGNvbnN0OworCisgIEFUT01JQ19TVEFUSUNfREVDTChTdG9yYWdlKQorfTsKKworfSAgLy8gbmFtZXNwYWNlIG50CisKKyNlbmRpZiAgLy8gTlRfU1RPUkFHRV9IXwpkaWZmIC0tZ2l0IGEvc3JjL1ZhbHVlLmNwcCBiL3NyYy9WYWx1ZS5jcHAKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uODA5NWZhOQotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9WYWx1ZS5jcHAKQEAgLTAsMCArMSwyMTAgQEAKKy8qLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovCisvKiBDb3B5cmlnaHQgKGMpIEZJUlNUIDIwMTUuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqLworLyogT3BlbiBTb3VyY2UgU29mdHdhcmUgLSBtYXkgYmUgbW9kaWZpZWQgYW5kIHNoYXJlZCBieSBGUkMgdGVhbXMuIFRoZSBjb2RlICAgKi8KKy8qIG11c3QgYmUgYWNjb21wYW5pZWQgYnkgdGhlIEZJUlNUIEJTRCBsaWNlbnNlIGZpbGUgaW4gdGhlIHJvb3QgZGlyZWN0b3J5IG9mICovCisvKiB0aGUgcHJvamVjdC4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqLworLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi8KKworI2luY2x1ZGUgIm50X1ZhbHVlLmgiCisjaW5jbHVkZSAiVmFsdWVfaW50ZXJuYWwuaCIKKyNpbmNsdWRlICJzdXBwb3J0L3RpbWVzdGFtcC5oIgorCit1c2luZyBuYW1lc3BhY2UgbnQ7CisKK1ZhbHVlOjpWYWx1ZSgpIHsKKyAgbV92YWwudHlwZSA9IE5UX1VOQVNTSUdORUQ7CisgIG1fdmFsLmxhc3RfY2hhbmdlID0gTm93KCk7Cit9CisKK1ZhbHVlOjpWYWx1ZShOVF9UeXBlIHR5cGUsIGNvbnN0IHByaXZhdGVfaW5pdCYpIHsKKyAgbV92YWwudHlwZSA9IHR5cGU7CisgIG1fdmFsLmxhc3RfY2hhbmdlID0gTm93KCk7CisgIGlmIChtX3ZhbC50eXBlID09IE5UX0JPT0xFQU5fQVJSQVkpCisgICAgbV92YWwuZGF0YS5hcnJfYm9vbGVhbi5hcnIgPSBudWxscHRyOworICBlbHNlIGlmIChtX3ZhbC50eXBlID09IE5UX0RPVUJMRV9BUlJBWSkKKyAgICBtX3ZhbC5kYXRhLmFycl9kb3VibGUuYXJyID0gbnVsbHB0cjsKKyAgZWxzZSBpZiAobV92YWwudHlwZSA9PSBOVF9TVFJJTkdfQVJSQVkpCisgICAgbV92YWwuZGF0YS5hcnJfc3RyaW5nLmFyciA9IG51bGxwdHI7Cit9CisKK1ZhbHVlOjp+VmFsdWUoKSB7CisgIGlmIChtX3ZhbC50eXBlID09IE5UX0JPT0xFQU5fQVJSQVkpCisgICAgZGVsZXRlW10gbV92YWwuZGF0YS5hcnJfYm9vbGVhbi5hcnI7CisgIGVsc2UgaWYgKG1fdmFsLnR5cGUgPT0gTlRfRE9VQkxFX0FSUkFZKQorICAgIGRlbGV0ZVtdIG1fdmFsLmRhdGEuYXJyX2RvdWJsZS5hcnI7CisgIGVsc2UgaWYgKG1fdmFsLnR5cGUgPT0gTlRfU1RSSU5HX0FSUkFZKQorICAgIGRlbGV0ZVtdIG1fdmFsLmRhdGEuYXJyX3N0cmluZy5hcnI7Cit9CisKK3N0ZDo6c2hhcmVkX3B0cjxWYWx1ZT4gVmFsdWU6Ok1ha2VCb29sZWFuQXJyYXkobGx2bTo6QXJyYXlSZWY8aW50PiB2YWx1ZSkgeworICBhdXRvIHZhbCA9IHN0ZDo6bWFrZV9zaGFyZWQ8VmFsdWU+KE5UX0JPT0xFQU5fQVJSQVksIHByaXZhdGVfaW5pdCgpKTsKKyAgdmFsLT5tX3ZhbC5kYXRhLmFycl9ib29sZWFuLmFyciA9IG5ldyBpbnRbdmFsdWUuc2l6ZSgpXTsKKyAgdmFsLT5tX3ZhbC5kYXRhLmFycl9ib29sZWFuLnNpemUgPSB2YWx1ZS5zaXplKCk7CisgIHN0ZDo6Y29weSh2YWx1ZS5iZWdpbigpLCB2YWx1ZS5lbmQoKSwgdmFsLT5tX3ZhbC5kYXRhLmFycl9ib29sZWFuLmFycik7CisgIHJldHVybiB2YWw7Cit9CisKK3N0ZDo6c2hhcmVkX3B0cjxWYWx1ZT4gVmFsdWU6Ok1ha2VEb3VibGVBcnJheShsbHZtOjpBcnJheVJlZjxkb3VibGU+IHZhbHVlKSB7CisgIGF1dG8gdmFsID0gc3RkOjptYWtlX3NoYXJlZDxWYWx1ZT4oTlRfRE9VQkxFX0FSUkFZLCBwcml2YXRlX2luaXQoKSk7CisgIHZhbC0+bV92YWwuZGF0YS5hcnJfZG91YmxlLmFyciA9IG5ldyBkb3VibGVbdmFsdWUuc2l6ZSgpXTsKKyAgdmFsLT5tX3ZhbC5kYXRhLmFycl9kb3VibGUuc2l6ZSA9IHZhbHVlLnNpemUoKTsKKyAgc3RkOjpjb3B5KHZhbHVlLmJlZ2luKCksIHZhbHVlLmVuZCgpLCB2YWwtPm1fdmFsLmRhdGEuYXJyX2RvdWJsZS5hcnIpOworICByZXR1cm4gdmFsOworfQorCitzdGQ6OnNoYXJlZF9wdHI8VmFsdWU+IFZhbHVlOjpNYWtlU3RyaW5nQXJyYXkoCisgICAgbGx2bTo6QXJyYXlSZWY8c3RkOjpzdHJpbmc+IHZhbHVlKSB7CisgIGF1dG8gdmFsID0gc3RkOjptYWtlX3NoYXJlZDxWYWx1ZT4oTlRfU1RSSU5HX0FSUkFZLCBwcml2YXRlX2luaXQoKSk7CisgIHZhbC0+bV9zdHJpbmdfYXJyYXkgPSB2YWx1ZTsKKyAgLy8gcG9pbnQgTlRfVmFsdWUgdG8gdGhlIGNvbnRlbnRzIGluIHRoZSB2ZWN0b3IuCisgIHZhbC0+bV92YWwuZGF0YS5hcnJfc3RyaW5nLmFyciA9IG5ldyBOVF9TdHJpbmdbdmFsdWUuc2l6ZSgpXTsKKyAgdmFsLT5tX3ZhbC5kYXRhLmFycl9zdHJpbmcuc2l6ZSA9IHZhbC0+bV9zdHJpbmdfYXJyYXkuc2l6ZSgpOworICBmb3IgKHN0ZDo6c2l6ZV90IGk9MDsgaTx2YWx1ZS5zaXplKCk7ICsraSkgeworICAgIHZhbC0+bV92YWwuZGF0YS5hcnJfc3RyaW5nLmFycltpXS5zdHIgPSBjb25zdF9jYXN0PGNoYXIqPih2YWx1ZVtpXS5jX3N0cigpKTsKKyAgICB2YWwtPm1fdmFsLmRhdGEuYXJyX3N0cmluZy5hcnJbaV0ubGVuID0gdmFsdWVbaV0uc2l6ZSgpOworICB9CisgIHJldHVybiB2YWw7Cit9CisKK3N0ZDo6c2hhcmVkX3B0cjxWYWx1ZT4gVmFsdWU6Ok1ha2VTdHJpbmdBcnJheSgKKyAgICBzdGQ6OnZlY3RvcjxzdGQ6OnN0cmluZz4mJiB2YWx1ZSkgeworICBhdXRvIHZhbCA9IHN0ZDo6bWFrZV9zaGFyZWQ8VmFsdWU+KE5UX1NUUklOR19BUlJBWSwgcHJpdmF0ZV9pbml0KCkpOworICB2YWwtPm1fc3RyaW5nX2FycmF5ID0gc3RkOjptb3ZlKHZhbHVlKTsKKyAgdmFsdWUuY2xlYXIoKTsKKyAgLy8gcG9pbnQgTlRfVmFsdWUgdG8gdGhlIGNvbnRlbnRzIGluIHRoZSB2ZWN0b3IuCisgIHZhbC0+bV92YWwuZGF0YS5hcnJfc3RyaW5nLmFyciA9IG5ldyBOVF9TdHJpbmdbdmFsLT5tX3N0cmluZ19hcnJheS5zaXplKCldOworICB2YWwtPm1fdmFsLmRhdGEuYXJyX3N0cmluZy5zaXplID0gdmFsLT5tX3N0cmluZ19hcnJheS5zaXplKCk7CisgIGZvciAoc3RkOjpzaXplX3QgaT0wOyBpPHZhbC0+bV9zdHJpbmdfYXJyYXkuc2l6ZSgpOyArK2kpIHsKKyAgICB2YWwtPm1fdmFsLmRhdGEuYXJyX3N0cmluZy5hcnJbaV0uc3RyID0KKyAgICAgICAgY29uc3RfY2FzdDxjaGFyKj4odmFsLT5tX3N0cmluZ19hcnJheVtpXS5jX3N0cigpKTsKKyAgICB2YWwtPm1fdmFsLmRhdGEuYXJyX3N0cmluZy5hcnJbaV0ubGVuID0gdmFsLT5tX3N0cmluZ19hcnJheVtpXS5zaXplKCk7CisgIH0KKyAgcmV0dXJuIHZhbDsKK30KKwordm9pZCBudDo6Q29udmVydFRvQyhjb25zdCBWYWx1ZSYgaW4sIE5UX1ZhbHVlKiBvdXQpIHsKKyAgb3V0LT50eXBlID0gTlRfVU5BU1NJR05FRDsKKyAgc3dpdGNoIChpbi50eXBlKCkpIHsKKyAgICBjYXNlIE5UX1VOQVNTSUdORUQ6CisgICAgICByZXR1cm47CisgICAgY2FzZSBOVF9CT09MRUFOOgorICAgICAgb3V0LT5kYXRhLnZfYm9vbGVhbiA9IGluLkdldEJvb2xlYW4oKSA/IDEgOiAwOworICAgICAgYnJlYWs7CisgICAgY2FzZSBOVF9ET1VCTEU6CisgICAgICBvdXQtPmRhdGEudl9kb3VibGUgPSBpbi5HZXREb3VibGUoKTsKKyAgICAgIGJyZWFrOworICAgIGNhc2UgTlRfU1RSSU5HOgorICAgICAgQ29udmVydFRvQyhpbi5HZXRTdHJpbmcoKSwgJm91dC0+ZGF0YS52X3N0cmluZyk7CisgICAgICBicmVhazsKKyAgICBjYXNlIE5UX1JBVzoKKyAgICAgIENvbnZlcnRUb0MoaW4uR2V0UmF3KCksICZvdXQtPmRhdGEudl9yYXcpOworICAgICAgYnJlYWs7CisgICAgY2FzZSBOVF9SUEM6CisgICAgICBDb252ZXJ0VG9DKGluLkdldFJwYygpLCAmb3V0LT5kYXRhLnZfcmF3KTsKKyAgICAgIGJyZWFrOworICAgIGNhc2UgTlRfQk9PTEVBTl9BUlJBWTogeworICAgICAgYXV0byB2ID0gaW4uR2V0Qm9vbGVhbkFycmF5KCk7CisgICAgICBvdXQtPmRhdGEuYXJyX2Jvb2xlYW4uYXJyID0KKyAgICAgICAgICBzdGF0aWNfY2FzdDxpbnQqPihzdGQ6Om1hbGxvYyh2LnNpemUoKSAqIHNpemVvZihpbnQpKSk7CisgICAgICBvdXQtPmRhdGEuYXJyX2Jvb2xlYW4uc2l6ZSA9IHYuc2l6ZSgpOworICAgICAgc3RkOjpjb3B5KHYuYmVnaW4oKSwgdi5lbmQoKSwgb3V0LT5kYXRhLmFycl9ib29sZWFuLmFycik7CisgICAgICBicmVhazsKKyAgICB9CisgICAgY2FzZSBOVF9ET1VCTEVfQVJSQVk6IHsKKyAgICAgIGF1dG8gdiA9IGluLkdldERvdWJsZUFycmF5KCk7CisgICAgICBvdXQtPmRhdGEuYXJyX2RvdWJsZS5hcnIgPQorICAgICAgICAgIHN0YXRpY19jYXN0PGRvdWJsZSo+KHN0ZDo6bWFsbG9jKHYuc2l6ZSgpICogc2l6ZW9mKGRvdWJsZSkpKTsKKyAgICAgIG91dC0+ZGF0YS5hcnJfZG91YmxlLnNpemUgPSB2LnNpemUoKTsKKyAgICAgIHN0ZDo6Y29weSh2LmJlZ2luKCksIHYuZW5kKCksIG91dC0+ZGF0YS5hcnJfZG91YmxlLmFycik7CisgICAgICBicmVhazsKKyAgICB9CisgICAgY2FzZSBOVF9TVFJJTkdfQVJSQVk6IHsKKyAgICAgIGF1dG8gdiA9IGluLkdldFN0cmluZ0FycmF5KCk7CisgICAgICBvdXQtPmRhdGEuYXJyX3N0cmluZy5hcnIgPQorICAgICAgICAgIHN0YXRpY19jYXN0PE5UX1N0cmluZyo+KHN0ZDo6bWFsbG9jKHYuc2l6ZSgpKnNpemVvZihOVF9TdHJpbmcpKSk7CisgICAgICBmb3IgKHNpemVfdCBpID0gMDsgaSA8IHYuc2l6ZSgpOyArK2kpCisgICAgICAgIENvbnZlcnRUb0ModltpXSwgJm91dC0+ZGF0YS5hcnJfc3RyaW5nLmFycltpXSk7CisgICAgICBvdXQtPmRhdGEuYXJyX3N0cmluZy5zaXplID0gdi5zaXplKCk7CisgICAgICBicmVhazsKKyAgICB9CisgICAgZGVmYXVsdDoKKyAgICAgIC8vIGFzc2VydChmYWxzZSAmJiAidW5rbm93biB2YWx1ZSB0eXBlIik7CisgICAgICByZXR1cm47CisgIH0KKyAgb3V0LT50eXBlID0gaW4udHlwZSgpOworfQorCit2b2lkIG50OjpDb252ZXJ0VG9DKGxsdm06OlN0cmluZ1JlZiBpbiwgTlRfU3RyaW5nKiBvdXQpIHsKKyAgb3V0LT5sZW4gPSBpbi5zaXplKCk7CisgIG91dC0+c3RyID0gc3RhdGljX2Nhc3Q8Y2hhcio+KHN0ZDo6bWFsbG9jKGluLnNpemUoKSsxKSk7CisgIHN0ZDo6bWVtY3B5KG91dC0+c3RyLCBpbi5kYXRhKCksIGluLnNpemUoKSk7CisgIG91dC0+c3RyW2luLnNpemUoKV0gPSAnXDAnOworfQorCitzdGQ6OnNoYXJlZF9wdHI8VmFsdWU+IG50OjpDb252ZXJ0RnJvbUMoY29uc3QgTlRfVmFsdWUmIHZhbHVlKSB7CisgIHN3aXRjaCAodmFsdWUudHlwZSkgeworICAgIGNhc2UgTlRfVU5BU1NJR05FRDoKKyAgICAgIHJldHVybiBudWxscHRyOworICAgIGNhc2UgTlRfQk9PTEVBTjoKKyAgICAgIHJldHVybiBWYWx1ZTo6TWFrZUJvb2xlYW4odmFsdWUuZGF0YS52X2Jvb2xlYW4gIT0gMCk7CisgICAgY2FzZSBOVF9ET1VCTEU6CisgICAgICByZXR1cm4gVmFsdWU6Ok1ha2VEb3VibGUodmFsdWUuZGF0YS52X2RvdWJsZSk7CisgICAgY2FzZSBOVF9TVFJJTkc6CisgICAgICByZXR1cm4gVmFsdWU6Ok1ha2VTdHJpbmcoQ29udmVydEZyb21DKHZhbHVlLmRhdGEudl9zdHJpbmcpKTsKKyAgICBjYXNlIE5UX1JBVzoKKyAgICAgIHJldHVybiBWYWx1ZTo6TWFrZVJhdyhDb252ZXJ0RnJvbUModmFsdWUuZGF0YS52X3JhdykpOworICAgIGNhc2UgTlRfUlBDOgorICAgICAgcmV0dXJuIFZhbHVlOjpNYWtlUnBjKENvbnZlcnRGcm9tQyh2YWx1ZS5kYXRhLnZfcmF3KSk7CisgICAgY2FzZSBOVF9CT09MRUFOX0FSUkFZOgorICAgICAgcmV0dXJuIFZhbHVlOjpNYWtlQm9vbGVhbkFycmF5KGxsdm06OkFycmF5UmVmPGludD4oCisgICAgICAgICAgdmFsdWUuZGF0YS5hcnJfYm9vbGVhbi5hcnIsIHZhbHVlLmRhdGEuYXJyX2Jvb2xlYW4uc2l6ZSkpOworICAgIGNhc2UgTlRfRE9VQkxFX0FSUkFZOgorICAgICAgcmV0dXJuIFZhbHVlOjpNYWtlRG91YmxlQXJyYXkobGx2bTo6QXJyYXlSZWY8ZG91YmxlPigKKyAgICAgICAgICB2YWx1ZS5kYXRhLmFycl9kb3VibGUuYXJyLCB2YWx1ZS5kYXRhLmFycl9kb3VibGUuc2l6ZSkpOworICAgIGNhc2UgTlRfU1RSSU5HX0FSUkFZOiB7CisgICAgICBzdGQ6OnZlY3RvcjxzdGQ6OnN0cmluZz4gdjsKKyAgICAgIHYucmVzZXJ2ZSh2YWx1ZS5kYXRhLmFycl9zdHJpbmcuc2l6ZSk7CisgICAgICBmb3IgKHNpemVfdCBpPTA7IGk8dmFsdWUuZGF0YS5hcnJfc3RyaW5nLnNpemU7ICsraSkKKyAgICAgICAgdi5wdXNoX2JhY2soQ29udmVydEZyb21DKHZhbHVlLmRhdGEuYXJyX3N0cmluZy5hcnJbaV0pKTsKKyAgICAgIHJldHVybiBWYWx1ZTo6TWFrZVN0cmluZ0FycmF5KHN0ZDo6bW92ZSh2KSk7CisgICAgfQorICAgIGRlZmF1bHQ6CisgICAgICAvLyBhc3NlcnQoZmFsc2UgJiYgInVua25vd24gdmFsdWUgdHlwZSIpOworICAgICAgcmV0dXJuIG51bGxwdHI7CisgIH0KK30KKworYm9vbCBudDo6b3BlcmF0b3I9PShjb25zdCBWYWx1ZSYgbGhzLCBjb25zdCBWYWx1ZSYgcmhzKSB7CisgIGlmIChsaHMudHlwZSgpICE9IHJocy50eXBlKCkpIHJldHVybiBmYWxzZTsKKyAgc3dpdGNoIChsaHMudHlwZSgpKSB7CisgICAgY2FzZSBOVF9VTkFTU0lHTkVEOgorICAgICAgcmV0dXJuIHRydWU7ICAvLyBYWFg6IGlzIHRoaXMgYmV0dGVyIGJlaW5nIGZhbHNlIGluc3RlYWQ/CisgICAgY2FzZSBOVF9CT09MRUFOOgorICAgICAgcmV0dXJuIGxocy5tX3ZhbC5kYXRhLnZfYm9vbGVhbiA9PSByaHMubV92YWwuZGF0YS52X2Jvb2xlYW47CisgICAgY2FzZSBOVF9ET1VCTEU6CisgICAgICByZXR1cm4gbGhzLm1fdmFsLmRhdGEudl9kb3VibGUgPT0gcmhzLm1fdmFsLmRhdGEudl9kb3VibGU7CisgICAgY2FzZSBOVF9TVFJJTkc6CisgICAgY2FzZSBOVF9SQVc6CisgICAgY2FzZSBOVF9SUEM6CisgICAgICByZXR1cm4gbGhzLm1fc3RyaW5nID09IHJocy5tX3N0cmluZzsKKyAgICBjYXNlIE5UX0JPT0xFQU5fQVJSQVk6CisgICAgICBpZiAobGhzLm1fdmFsLmRhdGEuYXJyX2Jvb2xlYW4uc2l6ZSAhPSByaHMubV92YWwuZGF0YS5hcnJfYm9vbGVhbi5zaXplKQorICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICByZXR1cm4gc3RkOjptZW1jbXAobGhzLm1fdmFsLmRhdGEuYXJyX2Jvb2xlYW4uYXJyLAorICAgICAgICAgICAgICAgICAgICAgICAgIHJocy5tX3ZhbC5kYXRhLmFycl9ib29sZWFuLmFyciwKKyAgICAgICAgICAgICAgICAgICAgICAgICBsaHMubV92YWwuZGF0YS5hcnJfYm9vbGVhbi5zaXplICoKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2l6ZW9mKGxocy5tX3ZhbC5kYXRhLmFycl9ib29sZWFuLmFyclswXSkpID09IDA7CisgICAgY2FzZSBOVF9ET1VCTEVfQVJSQVk6CisgICAgICBpZiAobGhzLm1fdmFsLmRhdGEuYXJyX2RvdWJsZS5zaXplICE9IHJocy5tX3ZhbC5kYXRhLmFycl9kb3VibGUuc2l6ZSkKKyAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgcmV0dXJuIHN0ZDo6bWVtY21wKGxocy5tX3ZhbC5kYXRhLmFycl9kb3VibGUuYXJyLAorICAgICAgICAgICAgICAgICAgICAgICAgIHJocy5tX3ZhbC5kYXRhLmFycl9kb3VibGUuYXJyLAorICAgICAgICAgICAgICAgICAgICAgICAgIGxocy5tX3ZhbC5kYXRhLmFycl9kb3VibGUuc2l6ZSAqCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNpemVvZihsaHMubV92YWwuZGF0YS5hcnJfZG91YmxlLmFyclswXSkpID09IDA7CisgICAgY2FzZSBOVF9TVFJJTkdfQVJSQVk6CisgICAgICByZXR1cm4gbGhzLm1fc3RyaW5nX2FycmF5ID09IHJocy5tX3N0cmluZ19hcnJheTsKKyAgICBkZWZhdWx0OgorICAgICAgLy8gYXNzZXJ0KGZhbHNlICYmICJ1bmtub3duIHZhbHVlIHR5cGUiKTsKKyAgICAgIHJldHVybiBmYWxzZTsKKyAgfQorfQpkaWZmIC0tZ2l0IGEvc3JjL1ZhbHVlX2ludGVybmFsLmggYi9zcmMvVmFsdWVfaW50ZXJuYWwuaApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5mMDk3NDhjCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL1ZhbHVlX2ludGVybmFsLmgKQEAgLTAsMCArMSwzMCBAQAorLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi8KKy8qIENvcHlyaWdodCAoYykgRklSU1QgMjAxNS4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICovCisvKiBPcGVuIFNvdXJjZSBTb2Z0d2FyZSAtIG1heSBiZSBtb2RpZmllZCBhbmQgc2hhcmVkIGJ5IEZSQyB0ZWFtcy4gVGhlIGNvZGUgICAqLworLyogbXVzdCBiZSBhY2NvbXBhbmllZCBieSB0aGUgRklSU1QgQlNEIGxpY2Vuc2UgZmlsZSBpbiB0aGUgcm9vdCBkaXJlY3Rvcnkgb2YgKi8KKy8qIHRoZSBwcm9qZWN0LiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICovCisvKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qLworCisjaWZuZGVmIE5UX1ZBTFVFX0lOVEVSTkFMX0hfCisjZGVmaW5lIE5UX1ZBTFVFX0lOVEVSTkFMX0hfCisKKyNpbmNsdWRlIDxtZW1vcnk+CisjaW5jbHVkZSA8c3RyaW5nPgorCisjaW5jbHVkZSAibGx2bS9TdHJpbmdSZWYuaCIKKyNpbmNsdWRlICJudGNvcmVfYy5oIgorCituYW1lc3BhY2UgbnQgeworCitjbGFzcyBWYWx1ZTsKKwordm9pZCBDb252ZXJ0VG9DKGNvbnN0IFZhbHVlJiBpbiwgTlRfVmFsdWUqIG91dCk7CitzdGQ6OnNoYXJlZF9wdHI8VmFsdWU+IENvbnZlcnRGcm9tQyhjb25zdCBOVF9WYWx1ZSYgdmFsdWUpOwordm9pZCBDb252ZXJ0VG9DKGxsdm06OlN0cmluZ1JlZiBpbiwgTlRfU3RyaW5nKiBvdXQpOworaW5saW5lIGxsdm06OlN0cmluZ1JlZiBDb252ZXJ0RnJvbUMoY29uc3QgTlRfU3RyaW5nJiBzdHIpIHsKKyAgcmV0dXJuIGxsdm06OlN0cmluZ1JlZihzdHIuc3RyLCBzdHIubGVuKTsKK30KKworfSAgLy8gbmFtZXNwYWNlIG50CisKKyNlbmRpZiAgLy8gTlRfVkFMVUVfSU5URVJOQUxfSF8KZGlmZiAtLWdpdCBhL3NyYy9XaXJlRGVjb2Rlci5jcHAgYi9zcmMvV2lyZURlY29kZXIuY3BwCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjEzODIyNWUKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvV2lyZURlY29kZXIuY3BwCkBAIC0wLDAgKzEsMjA2IEBACisvKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qLworLyogQ29weXJpZ2h0IChjKSBGSVJTVCAyMDE1LiBBbGwgUmlnaHRzIFJlc2VydmVkLiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKi8KKy8qIE9wZW4gU291cmNlIFNvZnR3YXJlIC0gbWF5IGJlIG1vZGlmaWVkIGFuZCBzaGFyZWQgYnkgRlJDIHRlYW1zLiBUaGUgY29kZSAgICovCisvKiBtdXN0IGJlIGFjY29tcGFuaWVkIGJ5IHRoZSBGSVJTVCBCU0QgbGljZW5zZSBmaWxlIGluIHRoZSByb290IGRpcmVjdG9yeSBvZiAqLworLyogdGhlIHByb2plY3QuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKi8KKy8qLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovCisKKyNpbmNsdWRlICJXaXJlRGVjb2Rlci5oIgorCisjaW5jbHVkZSA8Y2Fzc2VydD4KKyNpbmNsdWRlIDxjc3RkaW50PgorI2luY2x1ZGUgPGNzdGRsaWI+CisjaW5jbHVkZSA8Y3N0cmluZz4KKworI2luY2x1ZGUgImxsdm0vTWF0aEV4dHJhcy5oIgorI2luY2x1ZGUgImxlYjEyOC5oIgorCit1c2luZyBuYW1lc3BhY2UgbnQ7CisKK3N0YXRpYyBkb3VibGUgUmVhZERvdWJsZShjb25zdCBjaGFyKiYgYnVmKSB7CisgIC8vIEZhc3QgYnV0IG5vbi1wb3J0YWJsZSEKKyAgc3RkOjp1aW50NjRfdCB2YWwgPSAoKnJlaW50ZXJwcmV0X2Nhc3Q8Y29uc3QgdW5zaWduZWQgY2hhcio+KGJ1ZikpICYgMHhmZjsKKyAgKytidWY7CisgIHZhbCA8PD0gODsKKyAgdmFsIHw9ICgqcmVpbnRlcnByZXRfY2FzdDxjb25zdCB1bnNpZ25lZCBjaGFyKj4oYnVmKSkgJiAweGZmOworICArK2J1ZjsKKyAgdmFsIDw8PSA4OworICB2YWwgfD0gKCpyZWludGVycHJldF9jYXN0PGNvbnN0IHVuc2lnbmVkIGNoYXIqPihidWYpKSAmIDB4ZmY7CisgICsrYnVmOworICB2YWwgPDw9IDg7CisgIHZhbCB8PSAoKnJlaW50ZXJwcmV0X2Nhc3Q8Y29uc3QgdW5zaWduZWQgY2hhcio+KGJ1ZikpICYgMHhmZjsKKyAgKytidWY7CisgIHZhbCA8PD0gODsKKyAgdmFsIHw9ICgqcmVpbnRlcnByZXRfY2FzdDxjb25zdCB1bnNpZ25lZCBjaGFyKj4oYnVmKSkgJiAweGZmOworICArK2J1ZjsKKyAgdmFsIDw8PSA4OworICB2YWwgfD0gKCpyZWludGVycHJldF9jYXN0PGNvbnN0IHVuc2lnbmVkIGNoYXIqPihidWYpKSAmIDB4ZmY7CisgICsrYnVmOworICB2YWwgPDw9IDg7CisgIHZhbCB8PSAoKnJlaW50ZXJwcmV0X2Nhc3Q8Y29uc3QgdW5zaWduZWQgY2hhcio+KGJ1ZikpICYgMHhmZjsKKyAgKytidWY7CisgIHZhbCA8PD0gODsKKyAgdmFsIHw9ICgqcmVpbnRlcnByZXRfY2FzdDxjb25zdCB1bnNpZ25lZCBjaGFyKj4oYnVmKSkgJiAweGZmOworICArK2J1ZjsKKyAgcmV0dXJuIGxsdm06OkJpdHNUb0RvdWJsZSh2YWwpOworfQorCitXaXJlRGVjb2Rlcjo6V2lyZURlY29kZXIocmF3X2lzdHJlYW0mIGlzLCB1bnNpZ25lZCBpbnQgcHJvdG9fcmV2KSA6IG1faXMoaXMpIHsKKyAgLy8gU3RhcnQgd2l0aCBhIDFLIHRlbXBvcmFyeSBidWZmZXIuICBVc2UgbWFsbG9jIGluc3RlYWQgb2YgbmV3IHNvIHdlIGNhbgorICAvLyByZWFsbG9jLgorICBtX2FsbG9jYXRlZCA9IDEwMjQ7CisgIG1fYnVmID0gc3RhdGljX2Nhc3Q8Y2hhcio+KHN0ZDo6bWFsbG9jKG1fYWxsb2NhdGVkKSk7CisgIG1fcHJvdG9fcmV2ID0gcHJvdG9fcmV2OworICBtX2Vycm9yID0gbnVsbHB0cjsKK30KKworV2lyZURlY29kZXI6On5XaXJlRGVjb2RlcigpIHsgc3RkOjpmcmVlKG1fYnVmKTsgfQorCitib29sIFdpcmVEZWNvZGVyOjpSZWFkRG91YmxlKGRvdWJsZSogdmFsKSB7CisgIGNvbnN0IGNoYXIqIGJ1ZjsKKyAgaWYgKCFSZWFkKCZidWYsIDgpKSByZXR1cm4gZmFsc2U7CisgICp2YWwgPSA6OlJlYWREb3VibGUoYnVmKTsKKyAgcmV0dXJuIHRydWU7Cit9CisKK3ZvaWQgV2lyZURlY29kZXI6OlJlYWxsb2Moc3RkOjpzaXplX3QgbGVuKSB7CisgIC8vIERvdWJsZSBjdXJyZW50IGJ1ZmZlciBzaXplIHVudGlsIHdlIGhhdmUgZW5vdWdoIHNwYWNlLgorICBpZiAobV9hbGxvY2F0ZWQgPj0gbGVuKSByZXR1cm47CisgIHN0ZDo6c2l6ZV90IG5ld2xlbiA9IG1fYWxsb2NhdGVkICogMjsKKyAgd2hpbGUgKG5ld2xlbiA8IGxlbikgbmV3bGVuICo9IDI7CisgIG1fYnVmID0gc3RhdGljX2Nhc3Q8Y2hhcio+KHN0ZDo6cmVhbGxvYyhtX2J1ZiwgbmV3bGVuKSk7CisgIG1fYWxsb2NhdGVkID0gbmV3bGVuOworfQorCitib29sIFdpcmVEZWNvZGVyOjpSZWFkVHlwZShOVF9UeXBlKiB0eXBlKSB7CisgIHVuc2lnbmVkIGludCBpdHlwZTsKKyAgaWYgKCFSZWFkOCgmaXR5cGUpKSByZXR1cm4gZmFsc2U7CisgIC8vIENvbnZlcnQgZnJvbSBieXRlIHZhbHVlIHRvIGVudW0KKyAgc3dpdGNoIChpdHlwZSkgeworICAgIGNhc2UgMHgwMDoKKyAgICAgICp0eXBlID0gTlRfQk9PTEVBTjsKKyAgICAgIGJyZWFrOworICAgIGNhc2UgMHgwMToKKyAgICAgICp0eXBlID0gTlRfRE9VQkxFOworICAgICAgYnJlYWs7CisgICAgY2FzZSAweDAyOgorICAgICAgKnR5cGUgPSBOVF9TVFJJTkc7CisgICAgICBicmVhazsKKyAgICBjYXNlIDB4MDM6CisgICAgICAqdHlwZSA9IE5UX1JBVzsKKyAgICAgIGJyZWFrOworICAgIGNhc2UgMHgxMDoKKyAgICAgICp0eXBlID0gTlRfQk9PTEVBTl9BUlJBWTsKKyAgICAgIGJyZWFrOworICAgIGNhc2UgMHgxMToKKyAgICAgICp0eXBlID0gTlRfRE9VQkxFX0FSUkFZOworICAgICAgYnJlYWs7CisgICAgY2FzZSAweDEyOgorICAgICAgKnR5cGUgPSBOVF9TVFJJTkdfQVJSQVk7CisgICAgICBicmVhazsKKyAgICBjYXNlIDB4MjA6CisgICAgICAqdHlwZSA9IE5UX1JQQzsKKyAgICAgIGJyZWFrOworICAgIGRlZmF1bHQ6CisgICAgICAqdHlwZSA9IE5UX1VOQVNTSUdORUQ7CisgICAgICBtX2Vycm9yID0gInVucmVjb2duaXplZCB2YWx1ZSB0eXBlIjsKKyAgICAgIHJldHVybiBmYWxzZTsKKyAgfQorICByZXR1cm4gdHJ1ZTsKK30KKworc3RkOjpzaGFyZWRfcHRyPFZhbHVlPiBXaXJlRGVjb2Rlcjo6UmVhZFZhbHVlKE5UX1R5cGUgdHlwZSkgeworICBzd2l0Y2ggKHR5cGUpIHsKKyAgICBjYXNlIE5UX0JPT0xFQU46IHsKKyAgICAgIHVuc2lnbmVkIGludCB2OworICAgICAgaWYgKCFSZWFkOCgmdikpIHJldHVybiBudWxscHRyOworICAgICAgcmV0dXJuIFZhbHVlOjpNYWtlQm9vbGVhbih2ICE9IDApOworICAgIH0KKyAgICBjYXNlIE5UX0RPVUJMRTogeworICAgICAgZG91YmxlIHY7CisgICAgICBpZiAoIVJlYWREb3VibGUoJnYpKSByZXR1cm4gbnVsbHB0cjsKKyAgICAgIHJldHVybiBWYWx1ZTo6TWFrZURvdWJsZSh2KTsKKyAgICB9CisgICAgY2FzZSBOVF9TVFJJTkc6IHsKKyAgICAgIHN0ZDo6c3RyaW5nIHY7CisgICAgICBpZiAoIVJlYWRTdHJpbmcoJnYpKSByZXR1cm4gbnVsbHB0cjsKKyAgICAgIHJldHVybiBWYWx1ZTo6TWFrZVN0cmluZyhzdGQ6Om1vdmUodikpOworICAgIH0KKyAgICBjYXNlIE5UX1JBVzogeworICAgICAgaWYgKG1fcHJvdG9fcmV2IDwgMHgwMzAwdSkgeworICAgICAgICBtX2Vycm9yID0gInJlY2VpdmVkIHJhdyB2YWx1ZSBpbiBwcm90b2NvbCA8IDMuMCI7CisgICAgICAgIHJldHVybiBudWxscHRyOworICAgICAgfQorICAgICAgc3RkOjpzdHJpbmcgdjsKKyAgICAgIGlmICghUmVhZFN0cmluZygmdikpIHJldHVybiBudWxscHRyOworICAgICAgcmV0dXJuIFZhbHVlOjpNYWtlUmF3KHN0ZDo6bW92ZSh2KSk7CisgICAgfQorICAgIGNhc2UgTlRfUlBDOiB7CisgICAgICBpZiAobV9wcm90b19yZXYgPCAweDAzMDB1KSB7CisgICAgICAgIG1fZXJyb3IgPSAicmVjZWl2ZWQgUlBDIHZhbHVlIGluIHByb3RvY29sIDwgMy4wIjsKKyAgICAgICAgcmV0dXJuIG51bGxwdHI7CisgICAgICB9CisgICAgICBzdGQ6OnN0cmluZyB2OworICAgICAgaWYgKCFSZWFkU3RyaW5nKCZ2KSkgcmV0dXJuIG51bGxwdHI7CisgICAgICByZXR1cm4gVmFsdWU6Ok1ha2VScGMoc3RkOjptb3ZlKHYpKTsKKyAgICB9CisgICAgY2FzZSBOVF9CT09MRUFOX0FSUkFZOiB7CisgICAgICAvLyBzaXplCisgICAgICB1bnNpZ25lZCBpbnQgc2l6ZTsKKyAgICAgIGlmICghUmVhZDgoJnNpemUpKSByZXR1cm4gbnVsbHB0cjsKKworICAgICAgLy8gYXJyYXkgdmFsdWVzCisgICAgICBjb25zdCBjaGFyKiBidWY7CisgICAgICBpZiAoIVJlYWQoJmJ1Ziwgc2l6ZSkpIHJldHVybiBudWxscHRyOworICAgICAgc3RkOjp2ZWN0b3I8aW50PiB2KHNpemUpOworICAgICAgZm9yICh1bnNpZ25lZCBpbnQgaSA9IDA7IGkgPCBzaXplOyArK2kpCisgICAgICAgIHZbaV0gPSBidWZbaV0gPyAxIDogMDsKKyAgICAgIHJldHVybiBWYWx1ZTo6TWFrZUJvb2xlYW5BcnJheShzdGQ6Om1vdmUodikpOworICAgIH0KKyAgICBjYXNlIE5UX0RPVUJMRV9BUlJBWTogeworICAgICAgLy8gc2l6ZQorICAgICAgdW5zaWduZWQgaW50IHNpemU7CisgICAgICBpZiAoIVJlYWQ4KCZzaXplKSkgcmV0dXJuIG51bGxwdHI7CisKKyAgICAgIC8vIGFycmF5IHZhbHVlcworICAgICAgY29uc3QgY2hhciogYnVmOworICAgICAgaWYgKCFSZWFkKCZidWYsIHNpemUgKiA4KSkgcmV0dXJuIG51bGxwdHI7CisgICAgICBzdGQ6OnZlY3Rvcjxkb3VibGU+IHYoc2l6ZSk7CisgICAgICBmb3IgKHVuc2lnbmVkIGludCBpID0gMDsgaSA8IHNpemU7ICsraSkKKyAgICAgICAgdltpXSA9IDo6UmVhZERvdWJsZShidWYpOworICAgICAgcmV0dXJuIFZhbHVlOjpNYWtlRG91YmxlQXJyYXkoc3RkOjptb3ZlKHYpKTsKKyAgICB9CisgICAgY2FzZSBOVF9TVFJJTkdfQVJSQVk6IHsKKyAgICAgIC8vIHNpemUKKyAgICAgIHVuc2lnbmVkIGludCBzaXplOworICAgICAgaWYgKCFSZWFkOCgmc2l6ZSkpIHJldHVybiBudWxscHRyOworCisgICAgICAvLyBhcnJheSB2YWx1ZXMKKyAgICAgIHN0ZDo6dmVjdG9yPHN0ZDo6c3RyaW5nPiB2KHNpemUpOworICAgICAgZm9yICh1bnNpZ25lZCBpbnQgaSA9IDA7IGkgPCBzaXplOyArK2kpIHsKKyAgICAgICAgaWYgKCFSZWFkU3RyaW5nKCZ2W2ldKSkgcmV0dXJuIG51bGxwdHI7CisgICAgICB9CisgICAgICByZXR1cm4gVmFsdWU6Ok1ha2VTdHJpbmdBcnJheShzdGQ6Om1vdmUodikpOworICAgIH0KKyAgICBkZWZhdWx0OgorICAgICAgbV9lcnJvciA9ICJpbnZhbGlkIHR5cGUgd2hlbiB0cnlpbmcgdG8gcmVhZCB2YWx1ZSI7CisgICAgICByZXR1cm4gbnVsbHB0cjsKKyAgfQorfQorCitib29sIFdpcmVEZWNvZGVyOjpSZWFkU3RyaW5nKHN0ZDo6c3RyaW5nKiBzdHIpIHsKKyAgc2l6ZV90IGxlbjsKKyAgaWYgKG1fcHJvdG9fcmV2IDwgMHgwMzAwdSkgeworICAgIHVuc2lnbmVkIGludCB2OworICAgIGlmICghUmVhZDE2KCZ2KSkgcmV0dXJuIGZhbHNlOworICAgIGxlbiA9IHY7CisgIH0gZWxzZSB7CisgICAgdW5zaWduZWQgbG9uZyB2OworICAgIGlmICghUmVhZFVsZWIxMjgoJnYpKSByZXR1cm4gZmFsc2U7CisgICAgbGVuID0gdjsKKyAgfQorICBjb25zdCBjaGFyKiBidWY7CisgIGlmICghUmVhZCgmYnVmLCBsZW4pKSByZXR1cm4gZmFsc2U7CisgICpzdHIgPSBsbHZtOjpTdHJpbmdSZWYoYnVmLCBsZW4pOworICByZXR1cm4gdHJ1ZTsKK30KZGlmZiAtLWdpdCBhL3NyYy9XaXJlRGVjb2Rlci5oIGIvc3JjL1dpcmVEZWNvZGVyLmgKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYzUyMGJlNwotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9XaXJlRGVjb2Rlci5oCkBAIC0wLDAgKzEsMTQ5IEBACisvKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qLworLyogQ29weXJpZ2h0IChjKSBGSVJTVCAyMDE1LiBBbGwgUmlnaHRzIFJlc2VydmVkLiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKi8KKy8qIE9wZW4gU291cmNlIFNvZnR3YXJlIC0gbWF5IGJlIG1vZGlmaWVkIGFuZCBzaGFyZWQgYnkgRlJDIHRlYW1zLiBUaGUgY29kZSAgICovCisvKiBtdXN0IGJlIGFjY29tcGFuaWVkIGJ5IHRoZSBGSVJTVCBCU0QgbGljZW5zZSBmaWxlIGluIHRoZSByb290IGRpcmVjdG9yeSBvZiAqLworLyogdGhlIHByb2plY3QuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKi8KKy8qLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovCisKKyNpZm5kZWYgTlRfV0lSRURFQ09ERVJfSF8KKyNkZWZpbmUgTlRfV0lSRURFQ09ERVJfSF8KKworI2luY2x1ZGUgPGNzdGRkZWY+CisKKyNpbmNsdWRlICJudF9WYWx1ZS5oIgorI2luY2x1ZGUgImxlYjEyOC5oIgorLy8jaW5jbHVkZSAiTG9nLmgiCisjaW5jbHVkZSAicmF3X2lzdHJlYW0uaCIKKworbmFtZXNwYWNlIG50IHsKKworLyogRGVjb2RlcyBuZXR3b3JrIGRhdGEgaW50byBuYXRpdmUgcmVwcmVzZW50YXRpb24uCisgKiBUaGlzIGNsYXNzIGlzIGRlc2lnbmVkIHRvIHJlYWQgZnJvbSBhIHJhd19pc3RyZWFtLCB3aGljaCBwcm92aWRlcyBhIGJsb2NraW5nCisgKiByZWFkIGludGVyZmFjZS4gIFRoZXJlIGFyZSBubyBwcm92aXNpb25zIGluIHRoaXMgY2xhc3MgZm9yIHJlc3VtaW5nIGEgcmVhZAorICogdGhhdCB3YXMgaW50ZXJydXB0ZWQgcGFydHdheS4gIFJlYWQgZnVuY3Rpb25zIHJldHVybiBmYWxzZSBpZgorICogcmF3X2lzdHJlYW0ucmVhZCgpIHJldHVybmVkIGZhbHNlIChpbmRpY2F0aW5nIHRoZSBlbmQgb2YgdGhlIGlucHV0IGRhdGEKKyAqIHN0cmVhbSkuCisgKi8KK2NsYXNzIFdpcmVEZWNvZGVyIHsKKyBwdWJsaWM6CisgIGV4cGxpY2l0IFdpcmVEZWNvZGVyKHJhd19pc3RyZWFtJiBpcywgdW5zaWduZWQgaW50IHByb3RvX3Jldik7CisgIH5XaXJlRGVjb2RlcigpOworCisgIHZvaWQgc2V0X3Byb3RvX3Jldih1bnNpZ25lZCBpbnQgcHJvdG9fcmV2KSB7IG1fcHJvdG9fcmV2ID0gcHJvdG9fcmV2OyB9CisKKyAgLyogR2V0IHRoZSBhY3RpdmUgcHJvdG9jb2wgcmV2aXNpb24uICovCisgIHVuc2lnbmVkIGludCBwcm90b19yZXYoKSBjb25zdCB7IHJldHVybiBtX3Byb3RvX3JldjsgfQorCisgIC8qIENsZWFycyBlcnJvciBpbmRpY2F0b3IuICovCisgIHZvaWQgUmVzZXQoKSB7IG1fZXJyb3IgPSBudWxscHRyOyB9CisKKyAgLyogUmV0dXJucyBlcnJvciBpbmRpY2F0b3IgKGEgc3RyaW5nIGRlc2NyaWJpbmcgdGhlIGVycm9yKS4gIFJldHVybnMgbnVsbHB0cgorICAgKiBpZiBubyBlcnJvciBoYXMgb2NjdXJyZWQuCisgICAqLworICBjb25zdCBjaGFyKiBlcnJvcigpIGNvbnN0IHsgcmV0dXJuIG1fZXJyb3I7IH0KKworICB2b2lkIHNldF9lcnJvcihjb25zdCBjaGFyKiBlcnJvcikgeyBtX2Vycm9yID0gZXJyb3I7IH0KKworICAvKiBSZWFkcyB0aGUgc3BlY2lmaWVkIG51bWJlciBvZiBieXRlcy4KKyAgICogQHBhcmFtIGJ1ZiBwb2ludGVyIHRvIHJlYWQgZGF0YSAob3V0cHV0IHBhcmFtZXRlcikKKyAgICogQHBhcmFtIGxlbiBudW1iZXIgb2YgYnl0ZXMgdG8gcmVhZAorICAgKiBDYXV0aW9uOiB0aGUgYnVmZmVyIGlzIG9ubHkgdGVtcG9yYXJpbHkgdmFsaWQuCisgICAqLworICBib29sIFJlYWQoY29uc3QgY2hhcioqIGJ1Ziwgc3RkOjpzaXplX3QgbGVuKSB7CisgICAgaWYgKGxlbiA+IG1fYWxsb2NhdGVkKSBSZWFsbG9jKGxlbik7CisgICAgKmJ1ZiA9IG1fYnVmOworICAgIGJvb2wgcnYgPSBtX2lzLnJlYWQobV9idWYsIGxlbik7CisjaWYgMAorICAgIG50OjpMb2dnZXImIGxvZ2dlciA9IG50OjpMb2dnZXI6OkdldEluc3RhbmNlKCk7CisgICAgaWYgKGxvZ2dlci5taW5fbGV2ZWwoKSA8PSBOVF9MT0dfREVCVUc0ICYmIGxvZ2dlci5IYXNMb2dnZXIoKSkgeworICAgICAgc3RkOjpvc3RyaW5nc3RyZWFtIG9zczsKKyAgICAgIG9zcyA8PCAicmVhZCAiIDw8IGxlbiA8PCAiIGJ5dGVzOiIgPDwgc3RkOjpoZXg7CisgICAgICBpZiAoIXJ2KQorICAgICAgICBvc3MgPDwgImVycm9yIjsKKyAgICAgIGVsc2UgeworICAgICAgICBmb3IgKHN0ZDo6c2l6ZV90IGk9MDsgaSA8IGxlbjsgKytpKQorICAgICAgICAgIG9zcyA8PCAnICcgPDwgKHVuc2lnbmVkIGludCkoKCpidWYpW2ldKTsKKyAgICAgIH0KKyAgICAgIGxvZ2dlci5Mb2coTlRfTE9HX0RFQlVHNCwgX19GSUxFX18sIF9fTElORV9fLCBvc3Muc3RyKCkuY19zdHIoKSk7CisgICAgfQorI2VuZGlmCisgICAgcmV0dXJuIHJ2OworICB9CisKKyAgLyogUmVhZHMgYSBzaW5nbGUgYnl0ZS4gKi8KKyAgYm9vbCBSZWFkOCh1bnNpZ25lZCBpbnQqIHZhbCkgeworICAgIGNvbnN0IGNoYXIqIGJ1ZjsKKyAgICBpZiAoIVJlYWQoJmJ1ZiwgMSkpIHJldHVybiBmYWxzZTsKKyAgICAqdmFsID0gKCpyZWludGVycHJldF9jYXN0PGNvbnN0IHVuc2lnbmVkIGNoYXIqPihidWYpKSAmIDB4ZmY7CisgICAgcmV0dXJuIHRydWU7CisgIH0KKworICAvKiBSZWFkcyBhIDE2LWJpdCB3b3JkLiAqLworICBib29sIFJlYWQxNih1bnNpZ25lZCBpbnQqIHZhbCkgeworICAgIGNvbnN0IGNoYXIqIGJ1ZjsKKyAgICBpZiAoIVJlYWQoJmJ1ZiwgMikpIHJldHVybiBmYWxzZTsKKyAgICB1bnNpZ25lZCBpbnQgdiA9ICgqcmVpbnRlcnByZXRfY2FzdDxjb25zdCB1bnNpZ25lZCBjaGFyKj4oYnVmKSkgJiAweGZmOworICAgICsrYnVmOworICAgIHYgPDw9IDg7CisgICAgdiB8PSAoKnJlaW50ZXJwcmV0X2Nhc3Q8Y29uc3QgdW5zaWduZWQgY2hhcio+KGJ1ZikpICYgMHhmZjsKKyAgICAqdmFsID0gdjsKKyAgICByZXR1cm4gdHJ1ZTsKKyAgfQorCisgIC8qIFJlYWRzIGEgMzItYml0IHdvcmQuICovCisgIGJvb2wgUmVhZDMyKHVuc2lnbmVkIGxvbmcqIHZhbCkgeworICAgIGNvbnN0IGNoYXIqIGJ1ZjsKKyAgICBpZiAoIVJlYWQoJmJ1ZiwgNCkpIHJldHVybiBmYWxzZTsKKyAgICB1bnNpZ25lZCBpbnQgdiA9ICgqcmVpbnRlcnByZXRfY2FzdDxjb25zdCB1bnNpZ25lZCBjaGFyKj4oYnVmKSkgJiAweGZmOworICAgICsrYnVmOworICAgIHYgPDw9IDg7CisgICAgdiB8PSAoKnJlaW50ZXJwcmV0X2Nhc3Q8Y29uc3QgdW5zaWduZWQgY2hhcio+KGJ1ZikpICYgMHhmZjsKKyAgICArK2J1ZjsKKyAgICB2IDw8PSA4OworICAgIHYgfD0gKCpyZWludGVycHJldF9jYXN0PGNvbnN0IHVuc2lnbmVkIGNoYXIqPihidWYpKSAmIDB4ZmY7CisgICAgKytidWY7CisgICAgdiA8PD0gODsKKyAgICB2IHw9ICgqcmVpbnRlcnByZXRfY2FzdDxjb25zdCB1bnNpZ25lZCBjaGFyKj4oYnVmKSkgJiAweGZmOworICAgICp2YWwgPSB2OworICAgIHJldHVybiB0cnVlOworICB9CisKKyAgLyogUmVhZHMgYSBkb3VibGUuICovCisgIGJvb2wgUmVhZERvdWJsZShkb3VibGUqIHZhbCk7CisKKyAgLyogUmVhZHMgYW4gVUxFQjEyOC1lbmNvZGVkIHVuc2lnbmVkIGludGVnZXIuICovCisgIGJvb2wgUmVhZFVsZWIxMjgodW5zaWduZWQgbG9uZyogdmFsKSB7CisgICAgcmV0dXJuIG50OjpSZWFkVWxlYjEyOChtX2lzLCB2YWwpOworICB9CisKKyAgYm9vbCBSZWFkVHlwZShOVF9UeXBlKiB0eXBlKTsKKyAgYm9vbCBSZWFkU3RyaW5nKHN0ZDo6c3RyaW5nKiBzdHIpOworICBzdGQ6OnNoYXJlZF9wdHI8VmFsdWU+IFJlYWRWYWx1ZShOVF9UeXBlIHR5cGUpOworCisgIFdpcmVEZWNvZGVyKGNvbnN0IFdpcmVEZWNvZGVyJikgPSBkZWxldGU7CisgIFdpcmVEZWNvZGVyJiBvcGVyYXRvcj0oY29uc3QgV2lyZURlY29kZXImKSA9IGRlbGV0ZTsKKworIHByb3RlY3RlZDoKKyAgLyogVGhlIHByb3RvY29sIHJldmlzaW9uLiAgRS5nLiAweDAyMDAgZm9yIHZlcnNpb24gMi4wLiAqLworICB1bnNpZ25lZCBpbnQgbV9wcm90b19yZXY7CisKKyAgLyogRXJyb3IgaW5kaWNhdG9yLiAqLworICBjb25zdCBjaGFyKiBtX2Vycm9yOworCisgcHJpdmF0ZToKKyAgLyogUmVhbGxvY2F0ZSB0ZW1wb3JhcnkgYnVmZmVyIHRvIHNwZWNpZmllZCBsZW5ndGguICovCisgIHZvaWQgUmVhbGxvYyhzdGQ6OnNpemVfdCBsZW4pOworCisgIC8qIGlucHV0IHN0cmVhbSAqLworICByYXdfaXN0cmVhbSYgbV9pczsKKworICAvKiB0ZW1wb3JhcnkgYnVmZmVyICovCisgIGNoYXIqIG1fYnVmOworCisgIC8qIGFsbG9jYXRlZCBzaXplIG9mIHRlbXBvcmFyeSBidWZmZXIgKi8KKyAgc3RkOjpzaXplX3QgbV9hbGxvY2F0ZWQ7Cit9OworCit9ICAvLyBuYW1lc3BhY2UgbnQKKworI2VuZGlmICAvLyBOVF9XSVJFREVDT0RFUl9IXwpkaWZmIC0tZ2l0IGEvc3JjL1dpcmVFbmNvZGVyLmNwcCBiL3NyYy9XaXJlRW5jb2Rlci5jcHAKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNjEwYTUzZgotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9XaXJlRW5jb2Rlci5jcHAKQEAgLTAsMCArMSwyMDggQEAKKy8qLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovCisvKiBDb3B5cmlnaHQgKGMpIEZJUlNUIDIwMTUuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqLworLyogT3BlbiBTb3VyY2UgU29mdHdhcmUgLSBtYXkgYmUgbW9kaWZpZWQgYW5kIHNoYXJlZCBieSBGUkMgdGVhbXMuIFRoZSBjb2RlICAgKi8KKy8qIG11c3QgYmUgYWNjb21wYW5pZWQgYnkgdGhlIEZJUlNUIEJTRCBsaWNlbnNlIGZpbGUgaW4gdGhlIHJvb3QgZGlyZWN0b3J5IG9mICovCisvKiB0aGUgcHJvamVjdC4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqLworLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi8KKworI2luY2x1ZGUgIldpcmVFbmNvZGVyLmgiCisKKyNpbmNsdWRlIDxjYXNzZXJ0PgorI2luY2x1ZGUgPGNzdGRpbnQ+CisjaW5jbHVkZSA8Y3N0ZGxpYj4KKyNpbmNsdWRlIDxjc3RyaW5nPgorCisjaW5jbHVkZSAibGx2bS9NYXRoRXh0cmFzLmgiCisjaW5jbHVkZSAibGViMTI4LmgiCisKK3VzaW5nIG5hbWVzcGFjZSBudDsKKworV2lyZUVuY29kZXI6OldpcmVFbmNvZGVyKHVuc2lnbmVkIGludCBwcm90b19yZXYpIHsKKyAgbV9wcm90b19yZXYgPSBwcm90b19yZXY7CisgIG1fZXJyb3IgPSBudWxscHRyOworfQorCit2b2lkIFdpcmVFbmNvZGVyOjpXcml0ZURvdWJsZShkb3VibGUgdmFsKSB7CisgIC8vIFRoZSBoaWdoZXN0IHBlcmZvcm1hbmNlIHdheSB0byBkbyB0aGlzLCBhbGJlaXQgbm9uLXBvcnRhYmxlLgorICBzdGQ6OnVpbnQ2NF90IHYgPSBsbHZtOjpEb3VibGVUb0JpdHModmFsKTsKKyAgbV9kYXRhLmFwcGVuZCh7CisgICAgKGNoYXIpKCh2ID4+IDU2KSAmIDB4ZmYpLAorICAgIChjaGFyKSgodiA+PiA0OCkgJiAweGZmKSwKKyAgICAoY2hhcikoKHYgPj4gNDApICYgMHhmZiksCisgICAgKGNoYXIpKCh2ID4+IDMyKSAmIDB4ZmYpLAorICAgIChjaGFyKSgodiA+PiAyNCkgJiAweGZmKSwKKyAgICAoY2hhcikoKHYgPj4gMTYpICYgMHhmZiksCisgICAgKGNoYXIpKCh2ID4+IDgpICYgMHhmZiksCisgICAgKGNoYXIpKHYgJiAweGZmKQorICB9KTsKK30KKwordm9pZCBXaXJlRW5jb2Rlcjo6V3JpdGVVbGViMTI4KHVuc2lnbmVkIGxvbmcgdmFsKSB7CisgIG50OjpXcml0ZVVsZWIxMjgobV9kYXRhLCB2YWwpOworfQorCit2b2lkIFdpcmVFbmNvZGVyOjpXcml0ZVR5cGUoTlRfVHlwZSB0eXBlKSB7CisgIGNoYXIgY2g7CisgIC8vIENvbnZlcnQgZnJvbSBlbnVtIHRvIGFjdHVhbCBieXRlIHZhbHVlLgorICBzd2l0Y2ggKHR5cGUpIHsKKyAgICBjYXNlIE5UX0JPT0xFQU46CisgICAgICBjaCA9IDB4MDA7CisgICAgICBicmVhazsKKyAgICBjYXNlIE5UX0RPVUJMRToKKyAgICAgIGNoID0gMHgwMTsKKyAgICAgIGJyZWFrOworICAgIGNhc2UgTlRfU1RSSU5HOgorICAgICAgY2ggPSAweDAyOworICAgICAgYnJlYWs7CisgICAgY2FzZSBOVF9SQVc6CisgICAgICBpZiAobV9wcm90b19yZXYgPCAweDAzMDB1KSB7CisgICAgICAgIG1fZXJyb3IgPSAicmF3IHR5cGUgbm90IHN1cHBvcnRlZCBpbiBwcm90b2NvbCA8IDMuMCI7CisgICAgICAgIHJldHVybjsKKyAgICAgIH0KKyAgICAgIGNoID0gMHgwMzsKKyAgICAgIGJyZWFrOworICAgIGNhc2UgTlRfQk9PTEVBTl9BUlJBWToKKyAgICAgIGNoID0gMHgxMDsKKyAgICAgIGJyZWFrOworICAgIGNhc2UgTlRfRE9VQkxFX0FSUkFZOgorICAgICAgY2ggPSAweDExOworICAgICAgYnJlYWs7CisgICAgY2FzZSBOVF9TVFJJTkdfQVJSQVk6CisgICAgICBjaCA9IDB4MTI7CisgICAgICBicmVhazsKKyAgICBjYXNlIE5UX1JQQzoKKyAgICAgIGlmIChtX3Byb3RvX3JldiA8IDB4MDMwMHUpIHsKKyAgICAgICAgbV9lcnJvciA9ICJSUEMgdHlwZSBub3Qgc3VwcG9ydGVkIGluIHByb3RvY29sIDwgMy4wIjsKKyAgICAgICAgcmV0dXJuOworICAgICAgfQorICAgICAgY2ggPSAweDIwOworICAgICAgYnJlYWs7CisgICAgZGVmYXVsdDoKKyAgICAgIG1fZXJyb3IgPSAidW5yZWNvZ25pemVkIHR5cGUiOworICAgICAgcmV0dXJuOworICB9CisgIG1fZGF0YS5wdXNoX2JhY2soY2gpOworfQorCitzdGQ6OnNpemVfdCBXaXJlRW5jb2Rlcjo6R2V0VmFsdWVTaXplKGNvbnN0IFZhbHVlJiB2YWx1ZSkgY29uc3QgeworICBzd2l0Y2ggKHZhbHVlLnR5cGUoKSkgeworICAgIGNhc2UgTlRfQk9PTEVBTjoKKyAgICAgIHJldHVybiAxOworICAgIGNhc2UgTlRfRE9VQkxFOgorICAgICAgcmV0dXJuIDg7CisgICAgY2FzZSBOVF9TVFJJTkc6CisgICAgICByZXR1cm4gR2V0U3RyaW5nU2l6ZSh2YWx1ZS5HZXRTdHJpbmcoKSk7CisgICAgY2FzZSBOVF9SQVc6CisgICAgICBpZiAobV9wcm90b19yZXYgPCAweDAzMDB1KSByZXR1cm4gMDsKKyAgICAgIHJldHVybiBHZXRTdHJpbmdTaXplKHZhbHVlLkdldFJhdygpKTsKKyAgICBjYXNlIE5UX1JQQzoKKyAgICAgIGlmIChtX3Byb3RvX3JldiA8IDB4MDMwMHUpIHJldHVybiAwOworICAgICAgcmV0dXJuIEdldFN0cmluZ1NpemUodmFsdWUuR2V0UnBjKCkpOworICAgIGNhc2UgTlRfQk9PTEVBTl9BUlJBWTogeworICAgICAgLy8gMS1ieXRlIHNpemUsIDEgYnl0ZSBwZXIgZWxlbWVudAorICAgICAgc3RkOjpzaXplX3Qgc2l6ZSA9IHZhbHVlLkdldEJvb2xlYW5BcnJheSgpLnNpemUoKTsKKyAgICAgIGlmIChzaXplID4gMHhmZikgc2l6ZSA9IDB4ZmY7IC8vIHNpemUgaXMgb25seSAxIGJ5dGUsIHRydW5jYXRlCisgICAgICByZXR1cm4gMSArIHNpemU7CisgICAgfQorICAgIGNhc2UgTlRfRE9VQkxFX0FSUkFZOiB7CisgICAgICAvLyAxLWJ5dGUgc2l6ZSwgOCBieXRlcyBwZXIgZWxlbWVudAorICAgICAgc3RkOjpzaXplX3Qgc2l6ZSA9IHZhbHVlLkdldERvdWJsZUFycmF5KCkuc2l6ZSgpOworICAgICAgaWYgKHNpemUgPiAweGZmKSBzaXplID0gMHhmZjsgLy8gc2l6ZSBpcyBvbmx5IDEgYnl0ZSwgdHJ1bmNhdGUKKyAgICAgIHJldHVybiAxICsgc2l6ZSAqIDg7CisgICAgfQorICAgIGNhc2UgTlRfU1RSSU5HX0FSUkFZOiB7CisgICAgICBhdXRvIHYgPSB2YWx1ZS5HZXRTdHJpbmdBcnJheSgpOworICAgICAgc3RkOjpzaXplX3Qgc2l6ZSA9IHYuc2l6ZSgpOworICAgICAgaWYgKHNpemUgPiAweGZmKSBzaXplID0gMHhmZjsgLy8gc2l6ZSBpcyBvbmx5IDEgYnl0ZSwgdHJ1bmNhdGUKKyAgICAgIHN0ZDo6c2l6ZV90IGxlbiA9IDE7IC8vIDEtYnl0ZSBzaXplCisgICAgICBmb3IgKHN0ZDo6c2l6ZV90IGkgPSAwOyBpIDwgc2l6ZTsgKytpKQorICAgICAgICBsZW4gKz0gR2V0U3RyaW5nU2l6ZSh2W2ldKTsKKyAgICAgIHJldHVybiBsZW47CisgICAgfQorICAgIGRlZmF1bHQ6CisgICAgICByZXR1cm4gMDsKKyAgfQorfQorCit2b2lkIFdpcmVFbmNvZGVyOjpXcml0ZVZhbHVlKGNvbnN0IFZhbHVlJiB2YWx1ZSkgeworICBzd2l0Y2ggKHZhbHVlLnR5cGUoKSkgeworICAgIGNhc2UgTlRfQk9PTEVBTjoKKyAgICAgIFdyaXRlOCh2YWx1ZS5HZXRCb29sZWFuKCkgPyAxIDogMCk7CisgICAgICBicmVhazsKKyAgICBjYXNlIE5UX0RPVUJMRToKKyAgICAgIFdyaXRlRG91YmxlKHZhbHVlLkdldERvdWJsZSgpKTsKKyAgICAgIGJyZWFrOworICAgIGNhc2UgTlRfU1RSSU5HOgorICAgICAgV3JpdGVTdHJpbmcodmFsdWUuR2V0U3RyaW5nKCkpOworICAgICAgYnJlYWs7CisgICAgY2FzZSBOVF9SQVc6CisgICAgICBpZiAobV9wcm90b19yZXYgPCAweDAzMDB1KSB7CisgICAgICAgIG1fZXJyb3IgPSAicmF3IHZhbHVlcyBub3Qgc3VwcG9ydGVkIGluIHByb3RvY29sIDwgMy4wIjsKKyAgICAgICAgcmV0dXJuOworICAgICAgfQorICAgICAgV3JpdGVTdHJpbmcodmFsdWUuR2V0UmF3KCkpOworICAgICAgYnJlYWs7CisgICAgY2FzZSBOVF9SUEM6CisgICAgICBpZiAobV9wcm90b19yZXYgPCAweDAzMDB1KSB7CisgICAgICAgIG1fZXJyb3IgPSAiUlBDIHZhbHVlcyBub3Qgc3VwcG9ydGVkIGluIHByb3RvY29sIDwgMy4wIjsKKyAgICAgICAgcmV0dXJuOworICAgICAgfQorICAgICAgV3JpdGVTdHJpbmcodmFsdWUuR2V0UnBjKCkpOworICAgICAgYnJlYWs7CisgICAgY2FzZSBOVF9CT09MRUFOX0FSUkFZOiB7CisgICAgICBhdXRvIHYgPSB2YWx1ZS5HZXRCb29sZWFuQXJyYXkoKTsKKyAgICAgIHN0ZDo6c2l6ZV90IHNpemUgPSB2LnNpemUoKTsKKyAgICAgIGlmIChzaXplID4gMHhmZikgc2l6ZSA9IDB4ZmY7IC8vIHNpemUgaXMgb25seSAxIGJ5dGUsIHRydW5jYXRlCisgICAgICBXcml0ZTgoc2l6ZSk7CisKKyAgICAgIGZvciAoc3RkOjpzaXplX3QgaSA9IDA7IGkgPCBzaXplOyArK2kpCisgICAgICAgIFdyaXRlOCh2W2ldID8gMSA6IDApOworICAgICAgYnJlYWs7CisgICAgfQorICAgIGNhc2UgTlRfRE9VQkxFX0FSUkFZOiB7CisgICAgICBhdXRvIHYgPSB2YWx1ZS5HZXREb3VibGVBcnJheSgpOworICAgICAgc3RkOjpzaXplX3Qgc2l6ZSA9IHYuc2l6ZSgpOworICAgICAgaWYgKHNpemUgPiAweGZmKSBzaXplID0gMHhmZjsgLy8gc2l6ZSBpcyBvbmx5IDEgYnl0ZSwgdHJ1bmNhdGUKKyAgICAgIFdyaXRlOChzaXplKTsKKworICAgICAgZm9yIChzdGQ6OnNpemVfdCBpID0gMDsgaSA8IHNpemU7ICsraSkKKyAgICAgICAgV3JpdGVEb3VibGUodltpXSk7CisgICAgICBicmVhazsKKyAgICB9CisgICAgY2FzZSBOVF9TVFJJTkdfQVJSQVk6IHsKKyAgICAgIGF1dG8gdiA9IHZhbHVlLkdldFN0cmluZ0FycmF5KCk7CisgICAgICBzdGQ6OnNpemVfdCBzaXplID0gdi5zaXplKCk7CisgICAgICBpZiAoc2l6ZSA+IDB4ZmYpIHNpemUgPSAweGZmOyAvLyBzaXplIGlzIG9ubHkgMSBieXRlLCB0cnVuY2F0ZQorICAgICAgV3JpdGU4KHNpemUpOworCisgICAgICBmb3IgKHN0ZDo6c2l6ZV90IGkgPSAwOyBpIDwgc2l6ZTsgKytpKQorICAgICAgICBXcml0ZVN0cmluZyh2W2ldKTsKKyAgICAgIGJyZWFrOworICAgIH0KKyAgICBkZWZhdWx0OgorICAgICAgbV9lcnJvciA9ICJ1bnJlY29nbml6ZWQgdHlwZSB3aGVuIHdyaXRpbmcgdmFsdWUiOworICAgICAgcmV0dXJuOworICB9Cit9CisKK3N0ZDo6c2l6ZV90IFdpcmVFbmNvZGVyOjpHZXRTdHJpbmdTaXplKGxsdm06OlN0cmluZ1JlZiBzdHIpIGNvbnN0IHsKKyAgaWYgKG1fcHJvdG9fcmV2IDwgMHgwMzAwdSkgeworICAgIHN0ZDo6c2l6ZV90IGxlbiA9IHN0ci5zaXplKCk7CisgICAgaWYgKGxlbiA+IDB4ZmZmZikgbGVuID0gMHhmZmZmOyAvLyBMaW1pdGVkIHRvIDY0SyBsZW5ndGg7IHRydW5jYXRlCisgICAgcmV0dXJuIDIgKyBsZW47CisgIH0KKyAgcmV0dXJuIFNpemVVbGViMTI4KHN0ci5zaXplKCkpICsgc3RyLnNpemUoKTsKK30KKwordm9pZCBXaXJlRW5jb2Rlcjo6V3JpdGVTdHJpbmcobGx2bTo6U3RyaW5nUmVmIHN0cikgeworICAvLyBsZW5ndGgKKyAgc3RkOjpzaXplX3QgbGVuID0gc3RyLnNpemUoKTsKKyAgaWYgKG1fcHJvdG9fcmV2IDwgMHgwMzAwdSkgeworICAgIGlmIChsZW4gPiAweGZmZmYpIGxlbiA9IDB4ZmZmZjsgLy8gTGltaXRlZCB0byA2NEsgbGVuZ3RoOyB0cnVuY2F0ZQorICAgIFdyaXRlMTYobGVuKTsKKyAgfSBlbHNlCisgICAgV3JpdGVVbGViMTI4KGxlbik7CisKKyAgLy8gY29udGVudHMKKyAgbV9kYXRhLmFwcGVuZChzdHIuZGF0YSgpLCBzdHIuZGF0YSgpICsgbGVuKTsKK30KZGlmZiAtLWdpdCBhL3NyYy9XaXJlRW5jb2Rlci5oIGIvc3JjL1dpcmVFbmNvZGVyLmgKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNDBhNGNhMAotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9XaXJlRW5jb2Rlci5oCkBAIC0wLDAgKzEsMTA1IEBACisvKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qLworLyogQ29weXJpZ2h0IChjKSBGSVJTVCAyMDE1LiBBbGwgUmlnaHRzIFJlc2VydmVkLiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKi8KKy8qIE9wZW4gU291cmNlIFNvZnR3YXJlIC0gbWF5IGJlIG1vZGlmaWVkIGFuZCBzaGFyZWQgYnkgRlJDIHRlYW1zLiBUaGUgY29kZSAgICovCisvKiBtdXN0IGJlIGFjY29tcGFuaWVkIGJ5IHRoZSBGSVJTVCBCU0QgbGljZW5zZSBmaWxlIGluIHRoZSByb290IGRpcmVjdG9yeSBvZiAqLworLyogdGhlIHByb2plY3QuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKi8KKy8qLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovCisKKyNpZm5kZWYgTlRfV0lSRUVOQ09ERVJfSF8KKyNkZWZpbmUgTlRfV0lSRUVOQ09ERVJfSF8KKworI2luY2x1ZGUgPGNhc3NlcnQ+CisjaW5jbHVkZSA8Y3N0ZGRlZj4KKworI2luY2x1ZGUgImxsdm0vU21hbGxWZWN0b3IuaCIKKyNpbmNsdWRlICJsbHZtL1N0cmluZ1JlZi5oIgorI2luY2x1ZGUgIm50X1ZhbHVlLmgiCisKK25hbWVzcGFjZSBudCB7CisKKy8qIEVuY29kZXMgbmF0aXZlIGRhdGEgZm9yIG5ldHdvcmsgdHJhbnNtaXNzaW9uLgorICogVGhpcyBjbGFzcyBtYWludGFpbnMgYW4gaW50ZXJuYWwgbWVtb3J5IGJ1ZmZlciBmb3Igd3JpdHRlbiBkYXRhIHNvIHRoYXQKKyAqIGl0IGNhbiBiZSBlZmZpY2llbnRseSBidXJzdGVkIHRvIHRoZSBuZXR3b3JrIGFmdGVyIGEgbnVtYmVyIG9mIHdyaXRlcworICogaGF2ZSBiZWVuIHBlcmZvcm1lZC4gIEZvciB0aGlzIHJlYXNvbiwgYWxsIG9wZXJhdGlvbnMgYXJlIG5vbi1ibG9ja2luZy4KKyAqLworY2xhc3MgV2lyZUVuY29kZXIgeworIHB1YmxpYzoKKyAgZXhwbGljaXQgV2lyZUVuY29kZXIodW5zaWduZWQgaW50IHByb3RvX3Jldik7CisKKyAgLyogQ2hhbmdlIHRoZSBwcm90b2NvbCByZXZpc2lvbiAobW9zdGx5IGFmZmVjdHMgdmFsdWUgZW5jb2RpbmcpLiAqLworICB2b2lkIHNldF9wcm90b19yZXYodW5zaWduZWQgaW50IHByb3RvX3JldikgeyBtX3Byb3RvX3JldiA9IHByb3RvX3JldjsgfQorCisgIC8qIEdldCB0aGUgYWN0aXZlIHByb3RvY29sIHJldmlzaW9uLiAqLworICB1bnNpZ25lZCBpbnQgcHJvdG9fcmV2KCkgY29uc3QgeyByZXR1cm4gbV9wcm90b19yZXY7IH0KKworICAvKiBDbGVhcnMgYnVmZmVyIGFuZCBlcnJvciBpbmRpY2F0b3IuICovCisgIHZvaWQgUmVzZXQoKSB7CisgICAgbV9kYXRhLmNsZWFyKCk7CisgICAgbV9lcnJvciA9IG51bGxwdHI7CisgIH0KKworICAvKiBSZXR1cm5zIGVycm9yIGluZGljYXRvciAoYSBzdHJpbmcgZGVzY3JpYmluZyB0aGUgZXJyb3IpLiAgUmV0dXJucyBudWxscHRyCisgICAqIGlmIG5vIGVycm9yIGhhcyBvY2N1cnJlZC4KKyAgICovCisgIGNvbnN0IGNoYXIqIGVycm9yKCkgY29uc3QgeyByZXR1cm4gbV9lcnJvcjsgfQorCisgIC8qIFJldHVybnMgcG9pbnRlciB0byBzdGFydCBvZiBtZW1vcnkgYnVmZmVyIHdpdGggd3JpdHRlbiBkYXRhLiAqLworICBjb25zdCBjaGFyKiBkYXRhKCkgY29uc3QgeyByZXR1cm4gbV9kYXRhLmRhdGEoKTsgfQorCisgIC8qIFJldHVybnMgbnVtYmVyIG9mIGJ5dGVzIHdyaXR0ZW4gdG8gbWVtb3J5IGJ1ZmZlci4gKi8KKyAgc3RkOjpzaXplX3Qgc2l6ZSgpIGNvbnN0IHsgcmV0dXJuIG1fZGF0YS5zaXplKCk7IH0KKworICBsbHZtOjpTdHJpbmdSZWYgVG9TdHJpbmdSZWYoKSBjb25zdCB7CisgICAgcmV0dXJuIGxsdm06OlN0cmluZ1JlZihtX2RhdGEuZGF0YSgpLCBtX2RhdGEuc2l6ZSgpKTsKKyAgfQorCisgIC8qIFdyaXRlcyBhIHNpbmdsZSBieXRlLiAqLworICB2b2lkIFdyaXRlOCh1bnNpZ25lZCBpbnQgdmFsKSB7IG1fZGF0YS5wdXNoX2JhY2soKGNoYXIpKHZhbCAmIDB4ZmYpKTsgfQorCisgIC8qIFdyaXRlcyBhIDE2LWJpdCB3b3JkLiAqLworICB2b2lkIFdyaXRlMTYodW5zaWduZWQgaW50IHZhbCkgeworICAgIG1fZGF0YS5hcHBlbmQoeyhjaGFyKSgodmFsID4+IDgpICYgMHhmZiksIChjaGFyKSh2YWwgJiAweGZmKX0pOworICB9CisKKyAgLyogV3JpdGVzIGEgMzItYml0IHdvcmQuICovCisgIHZvaWQgV3JpdGUzMih1bnNpZ25lZCBsb25nIHZhbCkgeworICAgIG1fZGF0YS5hcHBlbmQoeyhjaGFyKSgodmFsID4+IDI0KSAmIDB4ZmYpLAorICAgICAgICAgICAgICAgICAgIChjaGFyKSgodmFsID4+IDE2KSAmIDB4ZmYpLAorICAgICAgICAgICAgICAgICAgIChjaGFyKSgodmFsID4+IDgpICYgMHhmZiksCisgICAgICAgICAgICAgICAgICAgKGNoYXIpKHZhbCAmIDB4ZmYpfSk7CisgIH0KKworICAvKiBXcml0ZXMgYSBkb3VibGUuICovCisgIHZvaWQgV3JpdGVEb3VibGUoZG91YmxlIHZhbCk7CisKKyAgLyogV3JpdGVzIGFuIFVMRUIxMjgtZW5jb2RlZCB1bnNpZ25lZCBpbnRlZ2VyLiAqLworICB2b2lkIFdyaXRlVWxlYjEyOCh1bnNpZ25lZCBsb25nIHZhbCk7CisKKyAgdm9pZCBXcml0ZVR5cGUoTlRfVHlwZSB0eXBlKTsKKyAgdm9pZCBXcml0ZVZhbHVlKGNvbnN0IFZhbHVlJiB2YWx1ZSk7CisgIHZvaWQgV3JpdGVTdHJpbmcobGx2bTo6U3RyaW5nUmVmIHN0cik7CisKKyAgLyogVXRpbGl0eSBmdW5jdGlvbiB0byBnZXQgdGhlIHdyaXR0ZW4gc2l6ZSBvZiBhIHZhbHVlICh3aXRob3V0IGFjdHVhbGx5CisgICAqIHdyaXRpbmcgaXQpLgorICAgKi8KKyAgc3RkOjpzaXplX3QgR2V0VmFsdWVTaXplKGNvbnN0IFZhbHVlJiB2YWx1ZSkgY29uc3Q7CisKKyAgLyogVXRpbGl0eSBmdW5jdGlvbiB0byBnZXQgdGhlIHdyaXR0ZW4gc2l6ZSBvZiBhIHN0cmluZyAod2l0aG91dCBhY3R1YWxseQorICAgKiB3cml0aW5nIGl0KS4KKyAgICovCisgIHN0ZDo6c2l6ZV90IEdldFN0cmluZ1NpemUobGx2bTo6U3RyaW5nUmVmIHN0cikgY29uc3Q7CisKKyBwcm90ZWN0ZWQ6CisgIC8qIFRoZSBwcm90b2NvbCByZXZpc2lvbi4gIEUuZy4gMHgwMjAwIGZvciB2ZXJzaW9uIDIuMC4gKi8KKyAgdW5zaWduZWQgaW50IG1fcHJvdG9fcmV2OworCisgIC8qIEVycm9yIGluZGljYXRvci4gKi8KKyAgY29uc3QgY2hhciogbV9lcnJvcjsKKworIHByaXZhdGU6CisgIGxsdm06OlNtYWxsVmVjdG9yPGNoYXIsIDI1Nj4gbV9kYXRhOworfTsKKworfSAgLy8gbmFtZXNwYWNlIG50CisKKyNlbmRpZiAgLy8gTlRfV0lSRUVOQ09ERVJfSF8KZGlmZiAtLWdpdCBhL3NyYy9hdG9taWNfc3RhdGljLmggYi9zcmMvYXRvbWljX3N0YXRpYy5oCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmIwMGNjZGEKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvYXRvbWljX3N0YXRpYy5oCkBAIC0wLDAgKzEsNDkgQEAKKy8qLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovCisvKiBDb3B5cmlnaHQgKGMpIEZJUlNUIDIwMTUuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqLworLyogT3BlbiBTb3VyY2UgU29mdHdhcmUgLSBtYXkgYmUgbW9kaWZpZWQgYW5kIHNoYXJlZCBieSBGUkMgdGVhbXMuIFRoZSBjb2RlICAgKi8KKy8qIG11c3QgYmUgYWNjb21wYW5pZWQgYnkgdGhlIEZJUlNUIEJTRCBsaWNlbnNlIGZpbGUgaW4gdGhlIHJvb3QgZGlyZWN0b3J5IG9mICovCisvKiB0aGUgcHJvamVjdC4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqLworLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi8KKworI2lmbmRlZiBOVF9BVE9NSUNfU1RBVElDX0hfCisjZGVmaW5lIE5UX0FUT01JQ19TVEFUSUNfSF8KKworI2lmICFkZWZpbmVkKF9NU0NfVkVSKSB8fCAoX01TQ19WRVIgPj0gMTkwMCkKKworLy8gSnVzdCB1c2UgYSBsb2NhbCBzdGF0aWMuICBUaGlzIGlzIHRocmVhZC1zYWZlIHBlcgorLy8gaHR0cDovL3ByZXNoaW5nLmNvbS8yMDEzMDkzMC9kb3VibGUtY2hlY2tlZC1sb2NraW5nLWlzLWZpeGVkLWluLWNwcDExLworCisvLyBQZXIgaHR0cHM6Ly9tc2RuLm1pY3Jvc29mdC5jb20vZW4tdXMvbGlicmFyeS9IaDU2NzM2OC5hc3B4ICJNYWdpYyBTdGF0aWNzIgorLy8gYXJlIHN1cHBvcnRlZCBpbiBWaXN1YWwgU3R1ZGlvIDIwMTUgYnV0IG5vdCBpbiBlYXJsaWVyIHZlcnNpb25zLgorI2RlZmluZSBBVE9NSUNfU1RBVElDKGNscywgaW5zdCkgc3RhdGljIGNscyBpbnN0CisjZGVmaW5lIEFUT01JQ19TVEFUSUNfREVDTChjbHMpCisjZGVmaW5lIEFUT01JQ19TVEFUSUNfSU5JVChjbHMpCisKKyNlbHNlCisvLyBGcm9tIGh0dHA6Ly9wcmVzaGluZy5jb20vMjAxMzA5MzAvZG91YmxlLWNoZWNrZWQtbG9ja2luZy1pcy1maXhlZC1pbi1jcHAxMS8KKyNpbmNsdWRlIDxhdG9taWM+CisjaW5jbHVkZSA8bXV0ZXg+CisKKyNkZWZpbmUgQVRPTUlDX1NUQVRJQyhjbHMsIGluc3QpIFwKKyAgICBjbHMqIGluc3QjI3RtcCA9IG1faW5zdGFuY2UubG9hZChzdGQ6Om1lbW9yeV9vcmRlcl9hY3F1aXJlKTsgXAorICAgIGlmIChpbnN0IyN0bXAgPT0gbnVsbHB0cikgeyBcCisgICAgICBzdGQ6OmxvY2tfZ3VhcmQ8c3RkOjptdXRleD4gbG9jayhtX2luc3RhbmNlX211dGV4KTsgXAorICAgICAgaW5zdCMjdG1wID0gbV9pbnN0YW5jZS5sb2FkKHN0ZDo6bWVtb3J5X29yZGVyX3JlbGF4ZWQpOyBcCisgICAgICBpZiAoaW5zdCMjdG1wID09IG51bGxwdHIpIHsgXAorICAgICAgICBpbnN0IyN0bXAgPSBuZXcgY2xzOyBcCisgICAgICAgIG1faW5zdGFuY2Uuc3RvcmUoaW5zdCMjdG1wLCBzdGQ6Om1lbW9yeV9vcmRlcl9yZWxlYXNlKTsgXAorICAgICAgfSBcCisgICAgfSBcCisgICAgY2xzJiBpbnN0ID0gKmluc3QjI3RtcAorCisjZGVmaW5lIEFUT01JQ19TVEFUSUNfREVDTChjbHMpIFwKKyAgICBzdGF0aWMgc3RkOjphdG9taWM8Y2xzKj4gbV9pbnN0YW5jZTsgXAorICAgIHN0YXRpYyBzdGQ6Om11dGV4IG1faW5zdGFuY2VfbXV0ZXg7CisKKyNkZWZpbmUgQVRPTUlDX1NUQVRJQ19JTklUKGNscykgXAorICAgIHN0ZDo6YXRvbWljPGNscyo+IGNsczo6bV9pbnN0YW5jZTsgXAorICAgIHN0ZDo6bXV0ZXggY2xzOjptX2luc3RhbmNlX211dGV4OworCisjZW5kaWYKKworI2VuZGlmICAvLyBOVF9BVE9NSUNfU1RBVElDX0hfCmRpZmYgLS1naXQgYS9zcmMvbGViMTI4LmNwcCBiL3NyYy9sZWIxMjguY3BwCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjNlOTk4NDIKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvbGViMTI4LmNwcApAQCAtMCwwICsxLDExOSBAQAorLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi8KKy8qIENvcHlyaWdodCAoYykgRklSU1QgMjAxNS4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICovCisvKiBPcGVuIFNvdXJjZSBTb2Z0d2FyZSAtIG1heSBiZSBtb2RpZmllZCBhbmQgc2hhcmVkIGJ5IEZSQyB0ZWFtcy4gVGhlIGNvZGUgICAqLworLyogbXVzdCBiZSBhY2NvbXBhbmllZCBieSB0aGUgRklSU1QgQlNEIGxpY2Vuc2UgZmlsZSBpbiB0aGUgcm9vdCBkaXJlY3Rvcnkgb2YgKi8KKy8qIHRoZSBwcm9qZWN0LiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICovCisvKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qLworCisjaW5jbHVkZSAibGViMTI4LmgiCisKKyNpbmNsdWRlICJyYXdfaXN0cmVhbS5oIgorCituYW1lc3BhY2UgbnQgeworCisvKioKKyAqIEdldCBzaXplIG9mIHVuc2lnbmVkIExFQjEyOCBkYXRhCisgKiBAdmFsOiB2YWx1ZQorICoKKyAqIERldGVybWluZSB0aGUgbnVtYmVyIG9mIGJ5dGVzIHJlcXVpcmVkIHRvIGVuY29kZSBhbiB1bnNpZ25lZCBMRUIxMjggZGF0dW0uCisgKiBUaGUgYWxnb3JpdGhtIGlzIHRha2VuIGZyb20gQXBwZW5kaXggQyBvZiB0aGUgRFdBUkYgMyBzcGVjLiBGb3IgaW5mb3JtYXRpb24KKyAqIG9uIHRoZSBlbmNvZGluZ3MgcmVmZXIgdG8gc2VjdGlvbiAiNy42IC0gVmFyaWFibGUgTGVuZ3RoIERhdGEiLiBSZXR1cm4KKyAqIHRoZSBudW1iZXIgb2YgYnl0ZXMgcmVxdWlyZWQuCisgKi8KK3N0ZDo6c2l6ZV90IFNpemVVbGViMTI4KHVuc2lnbmVkIGxvbmcgdmFsKSB7CisgIHN0ZDo6c2l6ZV90IGNvdW50ID0gMDsKKyAgZG8geworICAgIHZhbCA+Pj0gNzsKKyAgICArK2NvdW50OworICB9IHdoaWxlICh2YWwgIT0gMCk7CisgIHJldHVybiBjb3VudDsKK30KKworLyoqCisgKiBXcml0ZSB1bnNpZ25lZCBMRUIxMjggZGF0YQorICogQGFkZHI6IHRoZSBhZGRyZXNzIHdoZXJlIHRoZSBVTEVCMTI4IGRhdGEgaXMgdG8gYmUgc3RvcmVkCisgKiBAdmFsOiB2YWx1ZSB0byBiZSBzdG9yZWQKKyAqCisgKiBFbmNvZGUgYW4gdW5zaWduZWQgTEVCMTI4IGVuY29kZWQgZGF0dW0uIFRoZSBhbGdvcml0aG0gaXMgdGFrZW4KKyAqIGZyb20gQXBwZW5kaXggQyBvZiB0aGUgRFdBUkYgMyBzcGVjLiBGb3IgaW5mb3JtYXRpb24gb24gdGhlCisgKiBlbmNvZGluZ3MgcmVmZXIgdG8gc2VjdGlvbiAiNy42IC0gVmFyaWFibGUgTGVuZ3RoIERhdGEiLiBSZXR1cm4KKyAqIHRoZSBudW1iZXIgb2YgYnl0ZXMgd3JpdHRlbi4KKyAqLworc3RkOjpzaXplX3QgV3JpdGVVbGViMTI4KGxsdm06OlNtYWxsVmVjdG9ySW1wbDxjaGFyPiYgZGVzdCwgdW5zaWduZWQgbG9uZyB2YWwpIHsKKyAgc3RkOjpzaXplX3QgY291bnQgPSAwOworCisgIGRvIHsKKyAgICB1bnNpZ25lZCBjaGFyIGJ5dGUgPSB2YWwgJiAweDdmOworICAgIHZhbCA+Pj0gNzsKKworICAgIGlmICh2YWwgIT0gMCkKKyAgICAgIGJ5dGUgfD0gMHg4MDsgIC8vIG1hcmsgdGhpcyBieXRlIHRvIHNob3cgdGhhdCBtb3JlIGJ5dGVzIHdpbGwgZm9sbG93CisKKyAgICBkZXN0LnB1c2hfYmFjayhieXRlKTsKKyAgICBjb3VudCsrOworICB9IHdoaWxlICh2YWwgIT0gMCk7CisKKyAgcmV0dXJuIGNvdW50OworfQorCisvKioKKyAqIFJlYWQgdW5zaWduZWQgTEVCMTI4IGRhdGEKKyAqIEBhZGRyOiB0aGUgYWRkcmVzcyB3aGVyZSB0aGUgVUxFQjEyOCBkYXRhIGlzIHN0b3JlZAorICogQHJldDogYWRkcmVzcyB0byBzdG9yZSB0aGUgcmVzdWx0CisgKgorICogRGVjb2RlIGFuIHVuc2lnbmVkIExFQjEyOCBlbmNvZGVkIGRhdHVtLiBUaGUgYWxnb3JpdGhtIGlzIHRha2VuCisgKiBmcm9tIEFwcGVuZGl4IEMgb2YgdGhlIERXQVJGIDMgc3BlYy4gRm9yIGluZm9ybWF0aW9uIG9uIHRoZQorICogZW5jb2RpbmdzIHJlZmVyIHRvIHNlY3Rpb24gIjcuNiAtIFZhcmlhYmxlIExlbmd0aCBEYXRhIi4gUmV0dXJuCisgKiB0aGUgbnVtYmVyIG9mIGJ5dGVzIHJlYWQuCisgKi8KK3N0ZDo6c2l6ZV90IFJlYWRVbGViMTI4KGNvbnN0IGNoYXIqIGFkZHIsIHVuc2lnbmVkIGxvbmcqIHJldCkgeworICB1bnNpZ25lZCBsb25nIHJlc3VsdCA9IDA7CisgIGludCBzaGlmdCA9IDA7CisgIHN0ZDo6c2l6ZV90IGNvdW50ID0gMDsKKworICB3aGlsZSAoMSkgeworICAgIHVuc2lnbmVkIGNoYXIgYnl0ZSA9ICpyZWludGVycHJldF9jYXN0PGNvbnN0IHVuc2lnbmVkIGNoYXIqPihhZGRyKTsKKyAgICBhZGRyKys7CisgICAgY291bnQrKzsKKworICAgIHJlc3VsdCB8PSAoYnl0ZSAmIDB4N2YpIDw8IHNoaWZ0OworICAgIHNoaWZ0ICs9IDc7CisKKyAgICBpZiAoIShieXRlICYgMHg4MCkpIGJyZWFrOworICB9CisKKyAgKnJldCA9IHJlc3VsdDsKKworICByZXR1cm4gY291bnQ7Cit9CisKKy8qKgorICogUmVhZCB1bnNpZ25lZCBMRUIxMjggZGF0YSBmcm9tIGEgc3RyZWFtCisgKiBAaXM6IHRoZSBpbnB1dCBzdHJlYW0gd2hlcmUgdGhlIFVMRUIxMjggZGF0YSBpcyB0byBiZSByZWFkIGZyb20KKyAqIEByZXQ6IGFkZHJlc3MgdG8gc3RvcmUgdGhlIHJlc3VsdAorICoKKyAqIERlY29kZSBhbiB1bnNpZ25lZCBMRUIxMjggZW5jb2RlZCBkYXR1bS4gVGhlIGFsZ29yaXRobSBpcyB0YWtlbgorICogZnJvbSBBcHBlbmRpeCBDIG9mIHRoZSBEV0FSRiAzIHNwZWMuIEZvciBpbmZvcm1hdGlvbiBvbiB0aGUKKyAqIGVuY29kaW5ncyByZWZlciB0byBzZWN0aW9uICI3LjYgLSBWYXJpYWJsZSBMZW5ndGggRGF0YSIuIFJldHVybgorICogZmFsc2Ugb24gc3RyZWFtIGVycm9yLCB0cnVlIG9uIHN1Y2Nlc3MuCisgKi8KK2Jvb2wgUmVhZFVsZWIxMjgocmF3X2lzdHJlYW0mIGlzLCB1bnNpZ25lZCBsb25nKiByZXQpIHsKKyAgdW5zaWduZWQgbG9uZyByZXN1bHQgPSAwOworICBpbnQgc2hpZnQgPSAwOworCisgIHdoaWxlICgxKSB7CisgICAgdW5zaWduZWQgY2hhciBieXRlOworICAgIGlmICghaXMucmVhZCgoY2hhciopJmJ5dGUsIDEpKSByZXR1cm4gZmFsc2U7CisKKyAgICByZXN1bHQgfD0gKGJ5dGUgJiAweDdmKSA8PCBzaGlmdDsKKyAgICBzaGlmdCArPSA3OworCisgICAgaWYgKCEoYnl0ZSAmIDB4ODApKSBicmVhazsKKyAgfQorCisgICpyZXQgPSByZXN1bHQ7CisKKyAgcmV0dXJuIHRydWU7Cit9CisKK30gIC8vIG5hbWVzcGFjZSBudApkaWZmIC0tZ2l0IGEvc3JjL2xlYjEyOC5oIGIvc3JjL2xlYjEyOC5oCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjczY2EyNDUKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvbGViMTI4LmgKQEAgLTAsMCArMSwyNiBAQAorLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi8KKy8qIENvcHlyaWdodCAoYykgRklSU1QgMjAxNS4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICovCisvKiBPcGVuIFNvdXJjZSBTb2Z0d2FyZSAtIG1heSBiZSBtb2RpZmllZCBhbmQgc2hhcmVkIGJ5IEZSQyB0ZWFtcy4gVGhlIGNvZGUgICAqLworLyogbXVzdCBiZSBhY2NvbXBhbmllZCBieSB0aGUgRklSU1QgQlNEIGxpY2Vuc2UgZmlsZSBpbiB0aGUgcm9vdCBkaXJlY3Rvcnkgb2YgKi8KKy8qIHRoZSBwcm9qZWN0LiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICovCisvKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qLworCisjaWZuZGVmIE5UX0xFQjEyOF9IXworI2RlZmluZSBOVF9MRUIxMjhfSF8KKworI2luY2x1ZGUgPGNzdGRkZWY+CisKKyNpbmNsdWRlICJsbHZtL1NtYWxsVmVjdG9yLmgiCisKK25hbWVzcGFjZSBudCB7CisKK2NsYXNzIHJhd19pc3RyZWFtOworCitzdGQ6OnNpemVfdCBTaXplVWxlYjEyOCh1bnNpZ25lZCBsb25nIHZhbCk7CitzdGQ6OnNpemVfdCBXcml0ZVVsZWIxMjgobGx2bTo6U21hbGxWZWN0b3JJbXBsPGNoYXI+JiBkZXN0LCB1bnNpZ25lZCBsb25nIHZhbCk7CitzdGQ6OnNpemVfdCBSZWFkVWxlYjEyOChjb25zdCBjaGFyKiBhZGRyLCB1bnNpZ25lZCBsb25nKiByZXQpOworYm9vbCBSZWFkVWxlYjEyOChyYXdfaXN0cmVhbSYgaXMsIHVuc2lnbmVkIGxvbmcqIHJldCk7CisKK30gIC8vIG5hbWVzcGFjZSBudAorCisjZW5kaWYgIC8vIE5UX0xFQjEyOF9IXwpkaWZmIC0tZ2l0IGEvc3JjL2xsdm0vU21hbGxQdHJTZXQuY3BwIGIvc3JjL2xsdm0vU21hbGxQdHJTZXQuY3BwCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmQyMzU5OWEKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvbGx2bS9TbWFsbFB0clNldC5jcHAKQEAgLTAsMCArMSwzMzggQEAKKy8vPT09LSBsbHZtL0FEVC9TbWFsbFB0clNldC5jcHAgLSAnTm9ybWFsbHkgc21hbGwnIHBvaW50ZXIgc2V0IC0tLS0tLS0tLS0tLT09PS8vCisvLworLy8gICAgICAgICAgICAgICAgICAgICBUaGUgTExWTSBDb21waWxlciBJbmZyYXN0cnVjdHVyZQorLy8KKy8vIFRoaXMgZmlsZSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVW5pdmVyc2l0eSBvZiBJbGxpbm9pcyBPcGVuIFNvdXJjZQorLy8gTGljZW5zZS4gU2VlIExJQ0VOU0UuVFhUIGZvciBkZXRhaWxzLgorLy8KKy8vPT09LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLT09PS8vCisvLworLy8gVGhpcyBmaWxlIGltcGxlbWVudHMgdGhlIFNtYWxsUHRyU2V0IGNsYXNzLiAgU2VlIFNtYWxsUHRyU2V0LmggZm9yIGFuCisvLyBvdmVydmlldyBvZiB0aGUgYWxnb3JpdGhtLgorLy8KKy8vPT09LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLT09PS8vCisKKyNpbmNsdWRlICJsbHZtL1NtYWxsUHRyU2V0LmgiCisjaW5jbHVkZSAibGx2bS9EZW5zZU1hcEluZm8uaCIKKyNpbmNsdWRlICJsbHZtL01hdGhFeHRyYXMuaCIKKyNpbmNsdWRlIDxhbGdvcml0aG0+CisjaW5jbHVkZSA8Y3N0ZGxpYj4KKwordXNpbmcgbmFtZXNwYWNlIGxsdm07CisKK3ZvaWQgU21hbGxQdHJTZXRJbXBsQmFzZTo6c2hyaW5rX2FuZF9jbGVhcigpIHsKKyAgYXNzZXJ0KCFpc1NtYWxsKCkgJiYgIkNhbid0IHNocmluayBhIHNtYWxsIHNldCEiKTsKKyAgZnJlZShDdXJBcnJheSk7CisKKyAgLy8gUmVkdWNlIHRoZSBudW1iZXIgb2YgYnVja2V0cy4KKyAgQ3VyQXJyYXlTaXplID0gTnVtRWxlbWVudHMgPiAxNiA/IDEgPDwgKExvZzJfMzJfQ2VpbChOdW1FbGVtZW50cykgKyAxKSA6IDMyOworICBOdW1FbGVtZW50cyA9IE51bVRvbWJzdG9uZXMgPSAwOworCisgIC8vIEluc3RhbGwgdGhlIG5ldyBhcnJheS4gIENsZWFyIGFsbCB0aGUgYnVja2V0cyB0byBlbXB0eS4KKyAgQ3VyQXJyYXkgPSAoY29uc3Qgdm9pZCoqKW1hbGxvYyhzaXplb2Yodm9pZCopICogQ3VyQXJyYXlTaXplKTsKKyAgYXNzZXJ0KEN1ckFycmF5ICYmICJGYWlsZWQgdG8gYWxsb2NhdGUgbWVtb3J5PyIpOworICBtZW1zZXQoQ3VyQXJyYXksIC0xLCBDdXJBcnJheVNpemUqc2l6ZW9mKHZvaWQqKSk7Cit9CisKK3N0ZDo6cGFpcjxjb25zdCB2b2lkICpjb25zdCAqLCBib29sPgorU21hbGxQdHJTZXRJbXBsQmFzZTo6aW5zZXJ0X2ltcChjb25zdCB2b2lkICpQdHIpIHsKKyAgaWYgKGlzU21hbGwoKSkgeworICAgIC8vIENoZWNrIHRvIHNlZSBpZiBpdCBpcyBhbHJlYWR5IGluIHRoZSBzZXQuCisgICAgZm9yIChjb25zdCB2b2lkICoqQVB0ciA9IFNtYWxsQXJyYXksICoqRSA9IFNtYWxsQXJyYXkrTnVtRWxlbWVudHM7CisgICAgICAgICBBUHRyICE9IEU7ICsrQVB0cikKKyAgICAgIGlmICgqQVB0ciA9PSBQdHIpCisgICAgICAgIHJldHVybiBzdGQ6Om1ha2VfcGFpcihBUHRyLCBmYWxzZSk7CisKKyAgICAvLyBOb3BlLCB0aGVyZSBpc24ndC4gIElmIHdlIHN0YXkgc21hbGwsIGp1c3QgJ3B1c2hiYWNrJyBub3cuCisgICAgaWYgKE51bUVsZW1lbnRzIDwgQ3VyQXJyYXlTaXplKSB7CisgICAgICBTbWFsbEFycmF5W051bUVsZW1lbnRzKytdID0gUHRyOworICAgICAgcmV0dXJuIHN0ZDo6bWFrZV9wYWlyKFNtYWxsQXJyYXkgKyAoTnVtRWxlbWVudHMgLSAxKSwgdHJ1ZSk7CisgICAgfQorICAgIC8vIE90aGVyd2lzZSwgaGl0IHRoZSBiaWcgc2V0IGNhc2UsIHdoaWNoIHdpbGwgY2FsbCBncm93LgorICB9CisKKyAgaWYgKExMVk1fVU5MSUtFTFkoTnVtRWxlbWVudHMgKiA0ID49IEN1ckFycmF5U2l6ZSAqIDMpKSB7CisgICAgLy8gSWYgbW9yZSB0aGFuIDMvNCBvZiB0aGUgYXJyYXkgaXMgZnVsbCwgZ3Jvdy4KKyAgICBHcm93KEN1ckFycmF5U2l6ZSA8IDY0ID8gMTI4IDogQ3VyQXJyYXlTaXplKjIpOworICB9IGVsc2UgaWYgKExMVk1fVU5MSUtFTFkoQ3VyQXJyYXlTaXplIC0gKE51bUVsZW1lbnRzICsgTnVtVG9tYnN0b25lcykgPAorICAgICAgICAgICAgICAgICAgICAgICAgICAgQ3VyQXJyYXlTaXplIC8gOCkpIHsKKyAgICAvLyBJZiBmZXdlciBvZiAxLzggb2YgdGhlIGFycmF5IGlzIGVtcHR5IChtZWFuaW5nIHRoYXQgbWFueSBhcmUgZmlsbGVkIHdpdGgKKyAgICAvLyB0b21ic3RvbmVzKSwgcmVoYXNoLgorICAgIEdyb3coQ3VyQXJyYXlTaXplKTsKKyAgfQorICAKKyAgLy8gT2theSwgd2Uga25vdyB3ZSBoYXZlIHNwYWNlLiAgRmluZCBhIGhhc2ggYnVja2V0LgorICBjb25zdCB2b2lkICoqQnVja2V0ID0gY29uc3RfY2FzdDxjb25zdCB2b2lkKio+KEZpbmRCdWNrZXRGb3IoUHRyKSk7CisgIGlmICgqQnVja2V0ID09IFB0cikKKyAgICByZXR1cm4gc3RkOjptYWtlX3BhaXIoQnVja2V0LCBmYWxzZSk7IC8vIEFscmVhZHkgaW5zZXJ0ZWQsIGdvb2QuCisKKyAgLy8gT3RoZXJ3aXNlLCBpbnNlcnQgaXQhCisgIGlmICgqQnVja2V0ID09IGdldFRvbWJzdG9uZU1hcmtlcigpKQorICAgIC0tTnVtVG9tYnN0b25lczsKKyAgKkJ1Y2tldCA9IFB0cjsKKyAgKytOdW1FbGVtZW50czsgIC8vIFRyYWNrIGRlbnNpdHkuCisgIHJldHVybiBzdGQ6Om1ha2VfcGFpcihCdWNrZXQsIHRydWUpOworfQorCitib29sIFNtYWxsUHRyU2V0SW1wbEJhc2U6OmVyYXNlX2ltcChjb25zdCB2b2lkICogUHRyKSB7CisgIGlmIChpc1NtYWxsKCkpIHsKKyAgICAvLyBDaGVjayB0byBzZWUgaWYgaXQgaXMgaW4gdGhlIHNldC4KKyAgICBmb3IgKGNvbnN0IHZvaWQgKipBUHRyID0gU21hbGxBcnJheSwgKipFID0gU21hbGxBcnJheStOdW1FbGVtZW50czsKKyAgICAgICAgIEFQdHIgIT0gRTsgKytBUHRyKQorICAgICAgaWYgKCpBUHRyID09IFB0cikgeworICAgICAgICAvLyBJZiBpdCBpcyBpbiB0aGUgc2V0LCByZXBsYWNlIHRoaXMgZWxlbWVudC4KKyAgICAgICAgKkFQdHIgPSBFWy0xXTsKKyAgICAgICAgRVstMV0gPSBnZXRFbXB0eU1hcmtlcigpOworICAgICAgICAtLU51bUVsZW1lbnRzOworICAgICAgICByZXR1cm4gdHJ1ZTsKKyAgICAgIH0KKyAgICAKKyAgICByZXR1cm4gZmFsc2U7CisgIH0KKyAgCisgIC8vIE9rYXksIHdlIGtub3cgd2UgaGF2ZSBzcGFjZS4gIEZpbmQgYSBoYXNoIGJ1Y2tldC4KKyAgdm9pZCAqKkJ1Y2tldCA9IGNvbnN0X2Nhc3Q8dm9pZCoqPihGaW5kQnVja2V0Rm9yKFB0cikpOworICBpZiAoKkJ1Y2tldCAhPSBQdHIpIHJldHVybiBmYWxzZTsgIC8vIE5vdCBpbiB0aGUgc2V0PworCisgIC8vIFNldCB0aGlzIGFzIGEgdG9tYnN0b25lLgorICAqQnVja2V0ID0gZ2V0VG9tYnN0b25lTWFya2VyKCk7CisgIC0tTnVtRWxlbWVudHM7CisgICsrTnVtVG9tYnN0b25lczsKKyAgcmV0dXJuIHRydWU7Cit9CisKK2NvbnN0IHZvaWQgKiBjb25zdCAqU21hbGxQdHJTZXRJbXBsQmFzZTo6RmluZEJ1Y2tldEZvcihjb25zdCB2b2lkICpQdHIpIGNvbnN0IHsKKyAgdW5zaWduZWQgQnVja2V0ID0gRGVuc2VNYXBJbmZvPHZvaWQgKj46OmdldEhhc2hWYWx1ZShQdHIpICYgKEN1ckFycmF5U2l6ZS0xKTsKKyAgdW5zaWduZWQgQXJyYXlTaXplID0gQ3VyQXJyYXlTaXplOworICB1bnNpZ25lZCBQcm9iZUFtdCA9IDE7CisgIGNvbnN0IHZvaWQgKmNvbnN0ICpBcnJheSA9IEN1ckFycmF5OworICBjb25zdCB2b2lkICpjb25zdCAqVG9tYnN0b25lID0gbnVsbHB0cjsKKyAgd2hpbGUgKDEpIHsKKyAgICAvLyBJZiB3ZSBmb3VuZCBhbiBlbXB0eSBidWNrZXQsIHRoZSBwb2ludGVyIGRvZXNuJ3QgZXhpc3QgaW4gdGhlIHNldC4KKyAgICAvLyBSZXR1cm4gYSB0b21ic3RvbmUgaWYgd2UndmUgc2VlbiBvbmUgc28gZmFyLCBvciB0aGUgZW1wdHkgYnVja2V0IGlmCisgICAgLy8gbm90LgorICAgIGlmIChMTFZNX0xJS0VMWShBcnJheVtCdWNrZXRdID09IGdldEVtcHR5TWFya2VyKCkpKQorICAgICAgcmV0dXJuIFRvbWJzdG9uZSA/IFRvbWJzdG9uZSA6IEFycmF5K0J1Y2tldDsKKworICAgIC8vIEZvdW5kIFB0cidzIGJ1Y2tldD8KKyAgICBpZiAoTExWTV9MSUtFTFkoQXJyYXlbQnVja2V0XSA9PSBQdHIpKQorICAgICAgcmV0dXJuIEFycmF5K0J1Y2tldDsKKworICAgIC8vIElmIHRoaXMgaXMgYSB0b21ic3RvbmUsIHJlbWVtYmVyIGl0LiAgSWYgUHRyIGVuZHMgdXAgbm90IGluIHRoZSBzZXQsIHdlCisgICAgLy8gcHJlZmVyIHRvIHJldHVybiBpdCB0aGFuIHNvbWV0aGluZyB0aGF0IHdvdWxkIHJlcXVpcmUgbW9yZSBwcm9iaW5nLgorICAgIGlmIChBcnJheVtCdWNrZXRdID09IGdldFRvbWJzdG9uZU1hcmtlcigpICYmICFUb21ic3RvbmUpCisgICAgICBUb21ic3RvbmUgPSBBcnJheStCdWNrZXQ7ICAvLyBSZW1lbWJlciB0aGUgZmlyc3QgdG9tYnN0b25lIGZvdW5kLgorICAgIAorICAgIC8vIEl0J3MgYSBoYXNoIGNvbGxpc2lvbiBvciBhIHRvbWJzdG9uZS4gUmVwcm9iZS4KKyAgICBCdWNrZXQgPSAoQnVja2V0ICsgUHJvYmVBbXQrKykgJiAoQXJyYXlTaXplLTEpOworICB9Cit9CisKKy8vLyBHcm93IC0gQWxsb2NhdGUgYSBsYXJnZXIgYmFja2luZyBzdG9yZSBmb3IgdGhlIGJ1Y2tldHMgYW5kIG1vdmUgaXQgb3Zlci4KKy8vLwordm9pZCBTbWFsbFB0clNldEltcGxCYXNlOjpHcm93KHVuc2lnbmVkIE5ld1NpemUpIHsKKyAgLy8gQWxsb2NhdGUgYXQgdHdpY2UgYXMgbWFueSBidWNrZXRzLCBidXQgYXQgbGVhc3QgMTI4LgorICB1bnNpZ25lZCBPbGRTaXplID0gQ3VyQXJyYXlTaXplOworICAKKyAgY29uc3Qgdm9pZCAqKk9sZEJ1Y2tldHMgPSBDdXJBcnJheTsKKyAgYm9vbCBXYXNTbWFsbCA9IGlzU21hbGwoKTsKKyAgCisgIC8vIEluc3RhbGwgdGhlIG5ldyBhcnJheS4gIENsZWFyIGFsbCB0aGUgYnVja2V0cyB0byBlbXB0eS4KKyAgQ3VyQXJyYXkgPSAoY29uc3Qgdm9pZCoqKW1hbGxvYyhzaXplb2Yodm9pZCopICogTmV3U2l6ZSk7CisgIGFzc2VydChDdXJBcnJheSAmJiAiRmFpbGVkIHRvIGFsbG9jYXRlIG1lbW9yeT8iKTsKKyAgQ3VyQXJyYXlTaXplID0gTmV3U2l6ZTsKKyAgbWVtc2V0KEN1ckFycmF5LCAtMSwgTmV3U2l6ZSpzaXplb2Yodm9pZCopKTsKKyAgCisgIC8vIENvcHkgb3ZlciBhbGwgdGhlIGVsZW1lbnRzLgorICBpZiAoV2FzU21hbGwpIHsKKyAgICAvLyBTbWFsbCBzZXRzIHN0b3JlIHRoZWlyIGVsZW1lbnRzIGluIG9yZGVyLgorICAgIGZvciAoY29uc3Qgdm9pZCAqKkJ1Y2tldFB0ciA9IE9sZEJ1Y2tldHMsICoqRSA9IE9sZEJ1Y2tldHMrTnVtRWxlbWVudHM7CisgICAgICAgICBCdWNrZXRQdHIgIT0gRTsgKytCdWNrZXRQdHIpIHsKKyAgICAgIGNvbnN0IHZvaWQgKkVsdCA9ICpCdWNrZXRQdHI7CisgICAgICAqY29uc3RfY2FzdDx2b2lkKio+KEZpbmRCdWNrZXRGb3IoRWx0KSkgPSBjb25zdF9jYXN0PHZvaWQqPihFbHQpOworICAgIH0KKyAgfSBlbHNlIHsKKyAgICAvLyBDb3B5IG92ZXIgYWxsIHZhbGlkIGVudHJpZXMuCisgICAgZm9yIChjb25zdCB2b2lkICoqQnVja2V0UHRyID0gT2xkQnVja2V0cywgKipFID0gT2xkQnVja2V0cytPbGRTaXplOworICAgICAgICAgQnVja2V0UHRyICE9IEU7ICsrQnVja2V0UHRyKSB7CisgICAgICAvLyBDb3B5IG92ZXIgdGhlIGVsZW1lbnQgaWYgaXQgaXMgdmFsaWQuCisgICAgICBjb25zdCB2b2lkICpFbHQgPSAqQnVja2V0UHRyOworICAgICAgaWYgKEVsdCAhPSBnZXRUb21ic3RvbmVNYXJrZXIoKSAmJiBFbHQgIT0gZ2V0RW1wdHlNYXJrZXIoKSkKKyAgICAgICAgKmNvbnN0X2Nhc3Q8dm9pZCoqPihGaW5kQnVja2V0Rm9yKEVsdCkpID0gY29uc3RfY2FzdDx2b2lkKj4oRWx0KTsKKyAgICB9CisgICAgCisgICAgZnJlZShPbGRCdWNrZXRzKTsKKyAgICBOdW1Ub21ic3RvbmVzID0gMDsKKyAgfQorfQorCitTbWFsbFB0clNldEltcGxCYXNlOjpTbWFsbFB0clNldEltcGxCYXNlKGNvbnN0IHZvaWQgKipTbWFsbFN0b3JhZ2UsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBTbWFsbFB0clNldEltcGxCYXNlJiB0aGF0KSB7CisgIFNtYWxsQXJyYXkgPSBTbWFsbFN0b3JhZ2U7CisKKyAgLy8gSWYgd2UncmUgYmVjb21pbmcgc21hbGwsIHByZXBhcmUgdG8gaW5zZXJ0IGludG8gb3VyIHN0YWNrIHNwYWNlCisgIGlmICh0aGF0LmlzU21hbGwoKSkgeworICAgIEN1ckFycmF5ID0gU21hbGxBcnJheTsKKyAgLy8gT3RoZXJ3aXNlLCBhbGxvY2F0ZSBuZXcgaGVhcCBzcGFjZSAodW5sZXNzIHdlIHdlcmUgdGhlIHNhbWUgc2l6ZSkKKyAgfSBlbHNlIHsKKyAgICBDdXJBcnJheSA9IChjb25zdCB2b2lkKiopbWFsbG9jKHNpemVvZih2b2lkKikgKiB0aGF0LkN1ckFycmF5U2l6ZSk7CisgICAgYXNzZXJ0KEN1ckFycmF5ICYmICJGYWlsZWQgdG8gYWxsb2NhdGUgbWVtb3J5PyIpOworICB9CisgIAorICAvLyBDb3B5IG92ZXIgdGhlIG5ldyBhcnJheSBzaXplCisgIEN1ckFycmF5U2l6ZSA9IHRoYXQuQ3VyQXJyYXlTaXplOworCisgIC8vIENvcHkgb3ZlciB0aGUgY29udGVudHMgZnJvbSB0aGUgb3RoZXIgc2V0CisgIG1lbWNweShDdXJBcnJheSwgdGhhdC5DdXJBcnJheSwgc2l6ZW9mKHZvaWQqKSpDdXJBcnJheVNpemUpOworICAKKyAgTnVtRWxlbWVudHMgPSB0aGF0Lk51bUVsZW1lbnRzOworICBOdW1Ub21ic3RvbmVzID0gdGhhdC5OdW1Ub21ic3RvbmVzOworfQorCitTbWFsbFB0clNldEltcGxCYXNlOjpTbWFsbFB0clNldEltcGxCYXNlKGNvbnN0IHZvaWQgKipTbWFsbFN0b3JhZ2UsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVuc2lnbmVkIFNtYWxsU2l6ZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU21hbGxQdHJTZXRJbXBsQmFzZSAmJnRoYXQpIHsKKyAgU21hbGxBcnJheSA9IFNtYWxsU3RvcmFnZTsKKworICAvLyBDb3B5IG92ZXIgdGhlIGJhc2ljIG1lbWJlcnMuCisgIEN1ckFycmF5U2l6ZSA9IHRoYXQuQ3VyQXJyYXlTaXplOworICBOdW1FbGVtZW50cyA9IHRoYXQuTnVtRWxlbWVudHM7CisgIE51bVRvbWJzdG9uZXMgPSB0aGF0Lk51bVRvbWJzdG9uZXM7CisKKyAgLy8gV2hlbiBzbWFsbCwganVzdCBjb3B5IGludG8gb3VyIHNtYWxsIGJ1ZmZlci4KKyAgaWYgKHRoYXQuaXNTbWFsbCgpKSB7CisgICAgQ3VyQXJyYXkgPSBTbWFsbEFycmF5OworICAgIG1lbWNweShDdXJBcnJheSwgdGhhdC5DdXJBcnJheSwgc2l6ZW9mKHZvaWQgKikgKiBDdXJBcnJheVNpemUpOworICB9IGVsc2UgeworICAgIC8vIE90aGVyd2lzZSwgd2Ugc3RlYWwgdGhlIGxhcmdlIG1lbW9yeSBhbGxvY2F0aW9uIGFuZCBubyBjb3B5IGlzIG5lZWRlZC4KKyAgICBDdXJBcnJheSA9IHRoYXQuQ3VyQXJyYXk7CisgICAgdGhhdC5DdXJBcnJheSA9IHRoYXQuU21hbGxBcnJheTsKKyAgfQorCisgIC8vIE1ha2UgdGhlICJ0aGF0IiBvYmplY3Qgc21hbGwgYW5kIGVtcHR5LgorICB0aGF0LkN1ckFycmF5U2l6ZSA9IFNtYWxsU2l6ZTsKKyAgYXNzZXJ0KHRoYXQuQ3VyQXJyYXkgPT0gdGhhdC5TbWFsbEFycmF5KTsKKyAgdGhhdC5OdW1FbGVtZW50cyA9IDA7CisgIHRoYXQuTnVtVG9tYnN0b25lcyA9IDA7Cit9CisKKy8vLyBDb3B5RnJvbSAtIGltcGxlbWVudCBvcGVyYXRvcj0gZnJvbSBhIHNtYWxscHRyc2V0IHRoYXQgaGFzIHRoZSBzYW1lIHBvaW50ZXIKKy8vLyB0eXBlLCBidXQgbWF5IGhhdmUgYSBkaWZmZXJlbnQgc21hbGwgc2l6ZS4KK3ZvaWQgU21hbGxQdHJTZXRJbXBsQmFzZTo6Q29weUZyb20oY29uc3QgU21hbGxQdHJTZXRJbXBsQmFzZSAmUkhTKSB7CisgIGFzc2VydCgmUkhTICE9IHRoaXMgJiYgIlNlbGYtY29weSBzaG91bGQgYmUgaGFuZGxlZCBieSB0aGUgY2FsbGVyLiIpOworCisgIGlmIChpc1NtYWxsKCkgJiYgUkhTLmlzU21hbGwoKSkKKyAgICBhc3NlcnQoQ3VyQXJyYXlTaXplID09IFJIUy5DdXJBcnJheVNpemUgJiYKKyAgICAgICAgICAgIkNhbm5vdCBhc3NpZ24gc2V0cyB3aXRoIGRpZmZlcmVudCBzbWFsbCBzaXplcyIpOworCisgIC8vIElmIHdlJ3JlIGJlY29taW5nIHNtYWxsLCBwcmVwYXJlIHRvIGluc2VydCBpbnRvIG91ciBzdGFjayBzcGFjZQorICBpZiAoUkhTLmlzU21hbGwoKSkgeworICAgIGlmICghaXNTbWFsbCgpKQorICAgICAgZnJlZShDdXJBcnJheSk7CisgICAgQ3VyQXJyYXkgPSBTbWFsbEFycmF5OworICAvLyBPdGhlcndpc2UsIGFsbG9jYXRlIG5ldyBoZWFwIHNwYWNlICh1bmxlc3Mgd2Ugd2VyZSB0aGUgc2FtZSBzaXplKQorICB9IGVsc2UgaWYgKEN1ckFycmF5U2l6ZSAhPSBSSFMuQ3VyQXJyYXlTaXplKSB7CisgICAgaWYgKGlzU21hbGwoKSkKKyAgICAgIEN1ckFycmF5ID0gKGNvbnN0IHZvaWQqKiltYWxsb2Moc2l6ZW9mKHZvaWQqKSAqIFJIUy5DdXJBcnJheVNpemUpOworICAgIGVsc2UgeworICAgICAgY29uc3Qgdm9pZCAqKlQgPSAoY29uc3Qgdm9pZCoqKXJlYWxsb2MoQ3VyQXJyYXksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzaXplb2Yodm9pZCopICogUkhTLkN1ckFycmF5U2l6ZSk7CisgICAgICBpZiAoIVQpCisgICAgICAgIGZyZWUoQ3VyQXJyYXkpOworICAgICAgQ3VyQXJyYXkgPSBUOworICAgIH0KKyAgICBhc3NlcnQoQ3VyQXJyYXkgJiYgIkZhaWxlZCB0byBhbGxvY2F0ZSBtZW1vcnk/Iik7CisgIH0KKyAgCisgIC8vIENvcHkgb3ZlciB0aGUgbmV3IGFycmF5IHNpemUKKyAgQ3VyQXJyYXlTaXplID0gUkhTLkN1ckFycmF5U2l6ZTsKKworICAvLyBDb3B5IG92ZXIgdGhlIGNvbnRlbnRzIGZyb20gdGhlIG90aGVyIHNldAorICBtZW1jcHkoQ3VyQXJyYXksIFJIUy5DdXJBcnJheSwgc2l6ZW9mKHZvaWQqKSpDdXJBcnJheVNpemUpOworICAKKyAgTnVtRWxlbWVudHMgPSBSSFMuTnVtRWxlbWVudHM7CisgIE51bVRvbWJzdG9uZXMgPSBSSFMuTnVtVG9tYnN0b25lczsKK30KKwordm9pZCBTbWFsbFB0clNldEltcGxCYXNlOjpNb3ZlRnJvbSh1bnNpZ25lZCBTbWFsbFNpemUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFNtYWxsUHRyU2V0SW1wbEJhc2UgJiZSSFMpIHsKKyAgYXNzZXJ0KCZSSFMgIT0gdGhpcyAmJiAiU2VsZi1tb3ZlIHNob3VsZCBiZSBoYW5kbGVkIGJ5IHRoZSBjYWxsZXIuIik7CisKKyAgaWYgKCFpc1NtYWxsKCkpCisgICAgZnJlZShDdXJBcnJheSk7CisKKyAgaWYgKFJIUy5pc1NtYWxsKCkpIHsKKyAgICAvLyBDb3B5IGEgc21hbGwgUkhTIHJhdGhlciB0aGFuIG1vdmluZy4KKyAgICBDdXJBcnJheSA9IFNtYWxsQXJyYXk7CisgICAgbWVtY3B5KEN1ckFycmF5LCBSSFMuQ3VyQXJyYXksIHNpemVvZih2b2lkKikqUkhTLkN1ckFycmF5U2l6ZSk7CisgIH0gZWxzZSB7CisgICAgQ3VyQXJyYXkgPSBSSFMuQ3VyQXJyYXk7CisgICAgUkhTLkN1ckFycmF5ID0gUkhTLlNtYWxsQXJyYXk7CisgIH0KKworICAvLyBDb3B5IHRoZSByZXN0IG9mIHRoZSB0cml2aWFsIG1lbWJlcnMuCisgIEN1ckFycmF5U2l6ZSA9IFJIUy5DdXJBcnJheVNpemU7CisgIE51bUVsZW1lbnRzID0gUkhTLk51bUVsZW1lbnRzOworICBOdW1Ub21ic3RvbmVzID0gUkhTLk51bVRvbWJzdG9uZXM7CisKKyAgLy8gTWFrZSB0aGUgUkhTIHNtYWxsIGFuZCBlbXB0eS4KKyAgUkhTLkN1ckFycmF5U2l6ZSA9IFNtYWxsU2l6ZTsKKyAgYXNzZXJ0KFJIUy5DdXJBcnJheSA9PSBSSFMuU21hbGxBcnJheSk7CisgIFJIUy5OdW1FbGVtZW50cyA9IDA7CisgIFJIUy5OdW1Ub21ic3RvbmVzID0gMDsKK30KKwordm9pZCBTbWFsbFB0clNldEltcGxCYXNlOjpzd2FwKFNtYWxsUHRyU2V0SW1wbEJhc2UgJlJIUykgeworICBpZiAodGhpcyA9PSAmUkhTKSByZXR1cm47CisKKyAgLy8gV2UgY2FuIG9ubHkgYXZvaWQgY29weWluZyBlbGVtZW50cyBpZiBuZWl0aGVyIHNldCBpcyBzbWFsbC4KKyAgaWYgKCF0aGlzLT5pc1NtYWxsKCkgJiYgIVJIUy5pc1NtYWxsKCkpIHsKKyAgICBzdGQ6OnN3YXAodGhpcy0+Q3VyQXJyYXksIFJIUy5DdXJBcnJheSk7CisgICAgc3RkOjpzd2FwKHRoaXMtPkN1ckFycmF5U2l6ZSwgUkhTLkN1ckFycmF5U2l6ZSk7CisgICAgc3RkOjpzd2FwKHRoaXMtPk51bUVsZW1lbnRzLCBSSFMuTnVtRWxlbWVudHMpOworICAgIHN0ZDo6c3dhcCh0aGlzLT5OdW1Ub21ic3RvbmVzLCBSSFMuTnVtVG9tYnN0b25lcyk7CisgICAgcmV0dXJuOworICB9CisKKyAgLy8gRklYTUU6IEZyb20gaGVyZSBvbiB3ZSBhc3N1bWUgdGhhdCBib3RoIHNldHMgaGF2ZSB0aGUgc2FtZSBzbWFsbCBzaXplLgorCisgIC8vIElmIG9ubHkgUkhTIGlzIHNtYWxsLCBjb3B5IHRoZSBzbWFsbCBlbGVtZW50cyBpbnRvIExIUyBhbmQgbW92ZSB0aGUgcG9pbnRlcgorICAvLyBmcm9tIExIUyB0byBSSFMuCisgIGlmICghdGhpcy0+aXNTbWFsbCgpICYmIFJIUy5pc1NtYWxsKCkpIHsKKyAgICBzdGQ6OmNvcHkoUkhTLlNtYWxsQXJyYXksIFJIUy5TbWFsbEFycmF5K1JIUy5DdXJBcnJheVNpemUsCisgICAgICAgICAgICAgIHRoaXMtPlNtYWxsQXJyYXkpOworICAgIHN0ZDo6c3dhcCh0aGlzLT5OdW1FbGVtZW50cywgUkhTLk51bUVsZW1lbnRzKTsKKyAgICBzdGQ6OnN3YXAodGhpcy0+Q3VyQXJyYXlTaXplLCBSSFMuQ3VyQXJyYXlTaXplKTsKKyAgICBSSFMuQ3VyQXJyYXkgPSB0aGlzLT5DdXJBcnJheTsKKyAgICBSSFMuTnVtVG9tYnN0b25lcyA9IHRoaXMtPk51bVRvbWJzdG9uZXM7CisgICAgdGhpcy0+Q3VyQXJyYXkgPSB0aGlzLT5TbWFsbEFycmF5OworICAgIHRoaXMtPk51bVRvbWJzdG9uZXMgPSAwOworICAgIHJldHVybjsKKyAgfQorCisgIC8vIElmIG9ubHkgTEhTIGlzIHNtYWxsLCBjb3B5IHRoZSBzbWFsbCBlbGVtZW50cyBpbnRvIFJIUyBhbmQgbW92ZSB0aGUgcG9pbnRlcgorICAvLyBmcm9tIFJIUyB0byBMSFMuCisgIGlmICh0aGlzLT5pc1NtYWxsKCkgJiYgIVJIUy5pc1NtYWxsKCkpIHsKKyAgICBzdGQ6OmNvcHkodGhpcy0+U21hbGxBcnJheSwgdGhpcy0+U21hbGxBcnJheSt0aGlzLT5DdXJBcnJheVNpemUsCisgICAgICAgICAgICAgIFJIUy5TbWFsbEFycmF5KTsKKyAgICBzdGQ6OnN3YXAoUkhTLk51bUVsZW1lbnRzLCB0aGlzLT5OdW1FbGVtZW50cyk7CisgICAgc3RkOjpzd2FwKFJIUy5DdXJBcnJheVNpemUsIHRoaXMtPkN1ckFycmF5U2l6ZSk7CisgICAgdGhpcy0+Q3VyQXJyYXkgPSBSSFMuQ3VyQXJyYXk7CisgICAgdGhpcy0+TnVtVG9tYnN0b25lcyA9IFJIUy5OdW1Ub21ic3RvbmVzOworICAgIFJIUy5DdXJBcnJheSA9IFJIUy5TbWFsbEFycmF5OworICAgIFJIUy5OdW1Ub21ic3RvbmVzID0gMDsKKyAgICByZXR1cm47CisgIH0KKworICAvLyBCb3RoIGEgc21hbGwsIGp1c3Qgc3dhcCB0aGUgc21hbGwgZWxlbWVudHMuCisgIGFzc2VydCh0aGlzLT5pc1NtYWxsKCkgJiYgUkhTLmlzU21hbGwoKSk7CisgIGFzc2VydCh0aGlzLT5DdXJBcnJheVNpemUgPT0gUkhTLkN1ckFycmF5U2l6ZSk7CisgIHN0ZDo6c3dhcF9yYW5nZXModGhpcy0+U21hbGxBcnJheSwgdGhpcy0+U21hbGxBcnJheSt0aGlzLT5DdXJBcnJheVNpemUsCisgICAgICAgICAgICAgICAgICAgUkhTLlNtYWxsQXJyYXkpOworICBzdGQ6OnN3YXAodGhpcy0+TnVtRWxlbWVudHMsIFJIUy5OdW1FbGVtZW50cyk7Cit9CisKK1NtYWxsUHRyU2V0SW1wbEJhc2U6On5TbWFsbFB0clNldEltcGxCYXNlKCkgeworICBpZiAoIWlzU21hbGwoKSkKKyAgICBmcmVlKEN1ckFycmF5KTsKK30KZGlmZiAtLWdpdCBhL3NyYy9sbHZtL1NtYWxsVmVjdG9yLmNwcCBiL3NyYy9sbHZtL1NtYWxsVmVjdG9yLmNwcApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi42YWE3MDllCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL2xsdm0vU21hbGxWZWN0b3IuY3BwCkBAIC0wLDAgKzEsNDEgQEAKKy8vPT09LSBsbHZtL0FEVC9TbWFsbFZlY3Rvci5jcHAgLSAnTm9ybWFsbHkgc21hbGwnIHZlY3RvcnMgLS0tLS0tLS0tLS0tLS0tLT09PS8vCisvLworLy8gICAgICAgICAgICAgICAgICAgICBUaGUgTExWTSBDb21waWxlciBJbmZyYXN0cnVjdHVyZQorLy8KKy8vIFRoaXMgZmlsZSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVW5pdmVyc2l0eSBvZiBJbGxpbm9pcyBPcGVuIFNvdXJjZQorLy8gTGljZW5zZS4gU2VlIExJQ0VOU0UuVFhUIGZvciBkZXRhaWxzLgorLy8KKy8vPT09LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLT09PS8vCisvLworLy8gVGhpcyBmaWxlIGltcGxlbWVudHMgdGhlIFNtYWxsVmVjdG9yIGNsYXNzLgorLy8KKy8vPT09LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLT09PS8vCisKKyNpbmNsdWRlICJsbHZtL1NtYWxsVmVjdG9yLmgiCit1c2luZyBuYW1lc3BhY2UgbGx2bTsKKworLy8vIGdyb3dfcG9kIC0gVGhpcyBpcyBhbiBpbXBsZW1lbnRhdGlvbiBvZiB0aGUgZ3JvdygpIG1ldGhvZCB3aGljaCBvbmx5IHdvcmtzCisvLy8gb24gUE9ELWxpa2UgZGF0YXR5cGVzIGFuZCBpcyBvdXQgb2YgbGluZSB0byByZWR1Y2UgY29kZSBkdXBsaWNhdGlvbi4KK3ZvaWQgU21hbGxWZWN0b3JCYXNlOjpncm93X3BvZCh2b2lkICpGaXJzdEVsLCBzaXplX3QgTWluU2l6ZUluQnl0ZXMsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2l6ZV90IFRTaXplKSB7CisgIHNpemVfdCBDdXJTaXplQnl0ZXMgPSBzaXplX2luX2J5dGVzKCk7CisgIHNpemVfdCBOZXdDYXBhY2l0eUluQnl0ZXMgPSAyICogY2FwYWNpdHlfaW5fYnl0ZXMoKSArIFRTaXplOyAvLyBBbHdheXMgZ3Jvdy4KKyAgaWYgKE5ld0NhcGFjaXR5SW5CeXRlcyA8IE1pblNpemVJbkJ5dGVzKQorICAgIE5ld0NhcGFjaXR5SW5CeXRlcyA9IE1pblNpemVJbkJ5dGVzOworCisgIHZvaWQgKk5ld0VsdHM7CisgIGlmIChCZWdpblggPT0gRmlyc3RFbCkgeworICAgIE5ld0VsdHMgPSBtYWxsb2MoTmV3Q2FwYWNpdHlJbkJ5dGVzKTsKKworICAgIC8vIENvcHkgdGhlIGVsZW1lbnRzIG92ZXIuICBObyBuZWVkIHRvIHJ1biBkdG9ycyBvbiBQT0RzLgorICAgIG1lbWNweShOZXdFbHRzLCB0aGlzLT5CZWdpblgsIEN1clNpemVCeXRlcyk7CisgIH0gZWxzZSB7CisgICAgLy8gSWYgdGhpcyB3YXNuJ3QgZ3Jvd24gZnJvbSB0aGUgaW5saW5lIGNvcHksIGdyb3cgdGhlIGFsbG9jYXRlZCBzcGFjZS4KKyAgICBOZXdFbHRzID0gcmVhbGxvYyh0aGlzLT5CZWdpblgsIE5ld0NhcGFjaXR5SW5CeXRlcyk7CisgIH0KKyAgYXNzZXJ0KE5ld0VsdHMgJiYgIk91dCBvZiBtZW1vcnkiKTsKKworICB0aGlzLT5FbmRYID0gKGNoYXIqKU5ld0VsdHMrQ3VyU2l6ZUJ5dGVzOworICB0aGlzLT5CZWdpblggPSBOZXdFbHRzOworICB0aGlzLT5DYXBhY2l0eVggPSAoY2hhciopdGhpcy0+QmVnaW5YICsgTmV3Q2FwYWNpdHlJbkJ5dGVzOworfQpkaWZmIC0tZ2l0IGEvc3JjL2xsdm0vU3RyaW5nRXh0cmFzLmNwcCBiL3NyYy9sbHZtL1N0cmluZ0V4dHJhcy5jcHAKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNzRiNDdhNQotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9sbHZtL1N0cmluZ0V4dHJhcy5jcHAKQEAgLTAsMCArMSw1OCBAQAorLy89PT0tLSBTdHJpbmdFeHRyYXMuY3BwIC0gSW1wbGVtZW50IHRoZSBTdHJpbmdFeHRyYXMgaGVhZGVyIC0tLS0tLS0tLS0tLS0tPT09Ly8KKy8vCisvLyAgICAgICAgICAgICAgICAgICAgIFRoZSBMTFZNIENvbXBpbGVyIEluZnJhc3RydWN0dXJlCisvLworLy8gVGhpcyBmaWxlIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBVbml2ZXJzaXR5IG9mIElsbGlub2lzIE9wZW4gU291cmNlCisvLyBMaWNlbnNlLiBTZWUgTElDRU5TRS5UWFQgZm9yIGRldGFpbHMuCisvLworLy89PT0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tPT09Ly8KKy8vCisvLyBUaGlzIGZpbGUgaW1wbGVtZW50cyB0aGUgU3RyaW5nRXh0cmFzLmggaGVhZGVyCisvLworLy89PT0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tPT09Ly8KKworI2luY2x1ZGUgImxsdm0vU3RyaW5nRXh0cmFzLmgiCisjaW5jbHVkZSAibGx2bS9TbWFsbFZlY3Rvci5oIgordXNpbmcgbmFtZXNwYWNlIGxsdm07CisKKy8vLyBTdHJJblN0ck5vQ2FzZSAtIFBvcnRhYmxlIHZlcnNpb24gb2Ygc3RyY2FzZXN0ci4gIExvY2F0ZXMgdGhlIGZpcnN0CisvLy8gb2NjdXJyZW5jZSBvZiBzdHJpbmcgJ3MxJyBpbiBzdHJpbmcgJ3MyJywgaWdub3JpbmcgY2FzZS4gIFJldHVybnMKKy8vLyB0aGUgb2Zmc2V0IG9mIHMyIGluIHMxIG9yIG5wb3MgaWYgczIgY2Fubm90IGJlIGZvdW5kLgorU3RyaW5nUmVmOjpzaXplX3R5cGUgbGx2bTo6U3RySW5TdHJOb0Nhc2UoU3RyaW5nUmVmIHMxLCBTdHJpbmdSZWYgczIpIHsKKyAgc2l6ZV90IE4gPSBzMi5zaXplKCksIE0gPSBzMS5zaXplKCk7CisgIGlmIChOID4gTSkKKyAgICByZXR1cm4gU3RyaW5nUmVmOjpucG9zOworICBmb3IgKHNpemVfdCBpID0gMCwgZSA9IE0gLSBOICsgMTsgaSAhPSBlOyArK2kpCisgICAgaWYgKHMxLnN1YnN0cihpLCBOKS5lcXVhbHNfbG93ZXIoczIpKQorICAgICAgcmV0dXJuIGk7CisgIHJldHVybiBTdHJpbmdSZWY6Om5wb3M7Cit9CisKKy8vLyBnZXRUb2tlbiAtIFRoaXMgZnVuY3Rpb24gZXh0cmFjdHMgb25lIHRva2VuIGZyb20gc291cmNlLCBpZ25vcmluZyBhbnkKKy8vLyBsZWFkaW5nIGNoYXJhY3RlcnMgdGhhdCBhcHBlYXIgaW4gdGhlIERlbGltaXRlcnMgc3RyaW5nLCBhbmQgZW5kaW5nIHRoZQorLy8vIHRva2VuIGF0IGFueSBvZiB0aGUgY2hhcmFjdGVycyB0aGF0IGFwcGVhciBpbiB0aGUgRGVsaW1pdGVycyBzdHJpbmcuICBJZgorLy8vIHRoZXJlIGFyZSBubyB0b2tlbnMgaW4gdGhlIHNvdXJjZSBzdHJpbmcsIGFuIGVtcHR5IHN0cmluZyBpcyByZXR1cm5lZC4KKy8vLyBUaGUgZnVuY3Rpb24gcmV0dXJucyBhIHBhaXIgY29udGFpbmluZyB0aGUgZXh0cmFjdGVkIHRva2VuIGFuZCB0aGUKKy8vLyByZW1haW5pbmcgdGFpbCBzdHJpbmcuCitzdGQ6OnBhaXI8U3RyaW5nUmVmLCBTdHJpbmdSZWY+IGxsdm06OmdldFRva2VuKFN0cmluZ1JlZiBTb3VyY2UsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFN0cmluZ1JlZiBEZWxpbWl0ZXJzKSB7CisgIC8vIEZpZ3VyZSBvdXQgd2hlcmUgdGhlIHRva2VuIHN0YXJ0cy4KKyAgU3RyaW5nUmVmOjpzaXplX3R5cGUgU3RhcnQgPSBTb3VyY2UuZmluZF9maXJzdF9ub3Rfb2YoRGVsaW1pdGVycyk7CisKKyAgLy8gRmluZCB0aGUgbmV4dCBvY2N1cnJlbmNlIG9mIHRoZSBkZWxpbWl0ZXIuCisgIFN0cmluZ1JlZjo6c2l6ZV90eXBlIEVuZCA9IFNvdXJjZS5maW5kX2ZpcnN0X29mKERlbGltaXRlcnMsIFN0YXJ0KTsKKworICByZXR1cm4gc3RkOjptYWtlX3BhaXIoU291cmNlLnNsaWNlKFN0YXJ0LCBFbmQpLCBTb3VyY2Uuc3Vic3RyKEVuZCkpOworfQorCisvLy8gU3BsaXRTdHJpbmcgLSBTcGxpdCB1cCB0aGUgc3BlY2lmaWVkIHN0cmluZyBhY2NvcmRpbmcgdG8gdGhlIHNwZWNpZmllZAorLy8vIGRlbGltaXRlcnMsIGFwcGVuZGluZyB0aGUgcmVzdWx0IGZyYWdtZW50cyB0byB0aGUgb3V0cHV0IGxpc3QuCit2b2lkIGxsdm06OlNwbGl0U3RyaW5nKFN0cmluZ1JlZiBTb3VyY2UsCisgICAgICAgICAgICAgICAgICAgICAgIFNtYWxsVmVjdG9ySW1wbDxTdHJpbmdSZWY+ICZPdXRGcmFnbWVudHMsCisgICAgICAgICAgICAgICAgICAgICAgIFN0cmluZ1JlZiBEZWxpbWl0ZXJzKSB7CisgIHN0ZDo6cGFpcjxTdHJpbmdSZWYsIFN0cmluZ1JlZj4gUyA9IGdldFRva2VuKFNvdXJjZSwgRGVsaW1pdGVycyk7CisgIHdoaWxlICghUy5maXJzdC5lbXB0eSgpKSB7CisgICAgT3V0RnJhZ21lbnRzLnB1c2hfYmFjayhTLmZpcnN0KTsKKyAgICBTID0gZ2V0VG9rZW4oUy5zZWNvbmQsIERlbGltaXRlcnMpOworICB9Cit9CmRpZmYgLS1naXQgYS9zcmMvbGx2bS9TdHJpbmdNYXAuY3BwIGIvc3JjL2xsdm0vU3RyaW5nTWFwLmNwcApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi41NjQ5ODM0Ci0tLSAvZGV2L251bGwKKysrIGIvc3JjL2xsdm0vU3RyaW5nTWFwLmNwcApAQCAtMCwwICsxLDI0NCBAQAorLy89PT0tLS0gU3RyaW5nTWFwLmNwcCAtIFN0cmluZyBIYXNoIHRhYmxlIG1hcCBpbXBsZW1lbnRhdGlvbiAtLS0tLS0tLS0tLS0tPT09Ly8KKy8vCisvLyAgICAgICAgICAgICAgICAgICAgIFRoZSBMTFZNIENvbXBpbGVyIEluZnJhc3RydWN0dXJlCisvLworLy8gVGhpcyBmaWxlIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBVbml2ZXJzaXR5IG9mIElsbGlub2lzIE9wZW4gU291cmNlCisvLyBMaWNlbnNlLiBTZWUgTElDRU5TRS5UWFQgZm9yIGRldGFpbHMuCisvLworLy89PT0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tPT09Ly8KKy8vCisvLyBUaGlzIGZpbGUgaW1wbGVtZW50cyB0aGUgU3RyaW5nTWFwIGNsYXNzLgorLy8KKy8vPT09LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLT09PS8vCisKKyNpbmNsdWRlICJsbHZtL1N0cmluZ01hcC5oIgorI2luY2x1ZGUgImxsdm0vU3RyaW5nRXh0cmFzLmgiCisvLyNpbmNsdWRlICJsbHZtL1N1cHBvcnQvQ29tcGlsZXIuaCIKKyNpbmNsdWRlIDxjYXNzZXJ0PgordXNpbmcgbmFtZXNwYWNlIGxsdm07CisKK1N0cmluZ01hcEltcGw6OlN0cmluZ01hcEltcGwodW5zaWduZWQgSW5pdFNpemUsIHVuc2lnbmVkIGl0ZW1TaXplKSB7CisgIEl0ZW1TaXplID0gaXRlbVNpemU7CisKKyAgLy8gSWYgYSBzaXplIGlzIHNwZWNpZmllZCwgaW5pdGlhbGl6ZSB0aGUgdGFibGUgd2l0aCB0aGF0IG1hbnkgYnVja2V0cy4KKyAgaWYgKEluaXRTaXplKSB7CisgICAgaW5pdChJbml0U2l6ZSk7CisgICAgcmV0dXJuOworICB9CisKKyAgLy8gT3RoZXJ3aXNlLCBpbml0aWFsaXplIGl0IHdpdGggemVybyBidWNrZXRzIHRvIGF2b2lkIHRoZSBhbGxvY2F0aW9uLgorICBUaGVUYWJsZSA9IG51bGxwdHI7CisgIE51bUJ1Y2tldHMgPSAwOworICBOdW1JdGVtcyA9IDA7CisgIE51bVRvbWJzdG9uZXMgPSAwOworfQorCit2b2lkIFN0cmluZ01hcEltcGw6OmluaXQodW5zaWduZWQgSW5pdFNpemUpIHsKKyAgYXNzZXJ0KChJbml0U2l6ZSAmIChJbml0U2l6ZS0xKSkgPT0gMCAmJgorICAgICAgICAgIkluaXQgU2l6ZSBtdXN0IGJlIGEgcG93ZXIgb2YgMiBvciB6ZXJvISIpOworICBOdW1CdWNrZXRzID0gSW5pdFNpemUgPyBJbml0U2l6ZSA6IDE2OworICBOdW1JdGVtcyA9IDA7CisgIE51bVRvbWJzdG9uZXMgPSAwOworCisgIFRoZVRhYmxlID0gKFN0cmluZ01hcEVudHJ5QmFzZSAqKiljYWxsb2MoTnVtQnVja2V0cysxLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNpemVvZihTdHJpbmdNYXBFbnRyeUJhc2UgKiopICsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzaXplb2YodW5zaWduZWQpKTsKKworICAvLyBBbGxvY2F0ZSBvbmUgZXh0cmEgYnVja2V0LCBzZXQgaXQgdG8gbG9vayBmaWxsZWQgc28gdGhlIGl0ZXJhdG9ycyBzdG9wIGF0CisgIC8vIGVuZC4KKyAgVGhlVGFibGVbTnVtQnVja2V0c10gPSAoU3RyaW5nTWFwRW50cnlCYXNlKikyOworfQorCisKKy8vLyBMb29rdXBCdWNrZXRGb3IgLSBMb29rIHVwIHRoZSBidWNrZXQgdGhhdCB0aGUgc3BlY2lmaWVkIHN0cmluZyBzaG91bGQgZW5kCisvLy8gdXAgaW4uICBJZiBpdCBhbHJlYWR5IGV4aXN0cyBhcyBhIGtleSBpbiB0aGUgbWFwLCB0aGUgSXRlbSBwb2ludGVyIGZvciB0aGUKKy8vLyBzcGVjaWZpZWQgYnVja2V0IHdpbGwgYmUgbm9uLW51bGwuICBPdGhlcndpc2UsIGl0IHdpbGwgYmUgbnVsbC4gIEluIGVpdGhlcgorLy8vIGNhc2UsIHRoZSBGdWxsSGFzaFZhbHVlIGZpZWxkIG9mIHRoZSBidWNrZXQgd2lsbCBiZSBzZXQgdG8gdGhlIGhhc2ggdmFsdWUKKy8vLyBvZiB0aGUgc3RyaW5nLgordW5zaWduZWQgU3RyaW5nTWFwSW1wbDo6TG9va3VwQnVja2V0Rm9yKFN0cmluZ1JlZiBOYW1lKSB7CisgIHVuc2lnbmVkIEhUU2l6ZSA9IE51bUJ1Y2tldHM7CisgIGlmIChIVFNpemUgPT0gMCkgeyAgLy8gSGFzaCB0YWJsZSB1bmFsbG9jYXRlZCBzbyBmYXI/CisgICAgaW5pdCgxNik7CisgICAgSFRTaXplID0gTnVtQnVja2V0czsKKyAgfQorICB1bnNpZ25lZCBGdWxsSGFzaFZhbHVlID0gSGFzaFN0cmluZyhOYW1lKTsKKyAgdW5zaWduZWQgQnVja2V0Tm8gPSBGdWxsSGFzaFZhbHVlICYgKEhUU2l6ZS0xKTsKKyAgdW5zaWduZWQgKkhhc2hUYWJsZSA9ICh1bnNpZ25lZCAqKShUaGVUYWJsZSArIE51bUJ1Y2tldHMgKyAxKTsKKworICB1bnNpZ25lZCBQcm9iZUFtdCA9IDE7CisgIGludCBGaXJzdFRvbWJzdG9uZSA9IC0xOworICB3aGlsZSAoMSkgeworICAgIFN0cmluZ01hcEVudHJ5QmFzZSAqQnVja2V0SXRlbSA9IFRoZVRhYmxlW0J1Y2tldE5vXTsKKyAgICAvLyBJZiB3ZSBmb3VuZCBhbiBlbXB0eSBidWNrZXQsIHRoaXMga2V5IGlzbid0IGluIHRoZSB0YWJsZSB5ZXQsIHJldHVybiBpdC4KKyAgICBpZiAoIUJ1Y2tldEl0ZW0pIHsKKyAgICAgIC8vIElmIHdlIGZvdW5kIGEgdG9tYnN0b25lLCB3ZSB3YW50IHRvIHJldXNlIHRoZSB0b21ic3RvbmUgaW5zdGVhZCBvZiBhbgorICAgICAgLy8gZW1wdHkgYnVja2V0LiAgVGhpcyByZWR1Y2VzIHByb2JpbmcuCisgICAgICBpZiAoRmlyc3RUb21ic3RvbmUgIT0gLTEpIHsKKyAgICAgICAgSGFzaFRhYmxlW0ZpcnN0VG9tYnN0b25lXSA9IEZ1bGxIYXNoVmFsdWU7CisgICAgICAgIHJldHVybiBGaXJzdFRvbWJzdG9uZTsKKyAgICAgIH0KKworICAgICAgSGFzaFRhYmxlW0J1Y2tldE5vXSA9IEZ1bGxIYXNoVmFsdWU7CisgICAgICByZXR1cm4gQnVja2V0Tm87CisgICAgfQorCisgICAgaWYgKEJ1Y2tldEl0ZW0gPT0gZ2V0VG9tYnN0b25lVmFsKCkpIHsKKyAgICAgIC8vIFNraXAgb3ZlciB0b21ic3RvbmVzLiAgSG93ZXZlciwgcmVtZW1iZXIgdGhlIGZpcnN0IG9uZSB3ZSBzZWUuCisgICAgICBpZiAoRmlyc3RUb21ic3RvbmUgPT0gLTEpIEZpcnN0VG9tYnN0b25lID0gQnVja2V0Tm87CisgICAgfSBlbHNlIGlmIChIYXNoVGFibGVbQnVja2V0Tm9dID09IEZ1bGxIYXNoVmFsdWUpIHsKKyAgICAgIC8vIElmIHRoZSBmdWxsIGhhc2ggdmFsdWUgbWF0Y2hlcywgY2hlY2sgZGVlcGx5IGZvciBhIG1hdGNoLiAgVGhlIGNvbW1vbgorICAgICAgLy8gY2FzZSBoZXJlIGlzIHRoYXQgd2UgYXJlIG9ubHkgbG9va2luZyBhdCB0aGUgYnVja2V0cyAoZm9yIGl0ZW0gaW5mbworICAgICAgLy8gYmVpbmcgbm9uLW51bGwgYW5kIGZvciB0aGUgZnVsbCBoYXNoIHZhbHVlKSBub3QgYXQgdGhlIGl0ZW1zLiAgVGhpcworICAgICAgLy8gaXMgaW1wb3J0YW50IGZvciBjYWNoZSBsb2NhbGl0eS4KKworICAgICAgLy8gRG8gdGhlIGNvbXBhcmlzb24gbGlrZSB0aGlzIGJlY2F1c2UgTmFtZSBpc24ndCBuZWNlc3NhcmlseQorICAgICAgLy8gbnVsbC10ZXJtaW5hdGVkIQorICAgICAgY2hhciAqSXRlbVN0ciA9IChjaGFyKilCdWNrZXRJdGVtK0l0ZW1TaXplOworICAgICAgaWYgKE5hbWUgPT0gU3RyaW5nUmVmKEl0ZW1TdHIsIEJ1Y2tldEl0ZW0tPmdldEtleUxlbmd0aCgpKSkgeworICAgICAgICAvLyBXZSBmb3VuZCBhIG1hdGNoIQorICAgICAgICByZXR1cm4gQnVja2V0Tm87CisgICAgICB9CisgICAgfQorCisgICAgLy8gT2theSwgd2UgZGlkbid0IGZpbmQgdGhlIGl0ZW0uICBQcm9iZSB0byB0aGUgbmV4dCBidWNrZXQuCisgICAgQnVja2V0Tm8gPSAoQnVja2V0Tm8rUHJvYmVBbXQpICYgKEhUU2l6ZS0xKTsKKworICAgIC8vIFVzZSBxdWFkcmF0aWMgcHJvYmluZywgaXQgaGFzIGZld2VyIGNsdW1waW5nIGFydGlmYWN0cyB0aGFuIGxpbmVhcgorICAgIC8vIHByb2JpbmcgYW5kIGhhcyBnb29kIGNhY2hlIGJlaGF2aW9yIGluIHRoZSBjb21tb24gY2FzZS4KKyAgICArK1Byb2JlQW10OworICB9Cit9CisKKworLy8vIEZpbmRLZXkgLSBMb29rIHVwIHRoZSBidWNrZXQgdGhhdCBjb250YWlucyB0aGUgc3BlY2lmaWVkIGtleS4gSWYgaXQgZXhpc3RzCisvLy8gaW4gdGhlIG1hcCwgcmV0dXJuIHRoZSBidWNrZXQgbnVtYmVyIG9mIHRoZSBrZXkuICBPdGhlcndpc2UgcmV0dXJuIC0xLgorLy8vIFRoaXMgZG9lcyBub3QgbW9kaWZ5IHRoZSBtYXAuCitpbnQgU3RyaW5nTWFwSW1wbDo6RmluZEtleShTdHJpbmdSZWYgS2V5KSBjb25zdCB7CisgIHVuc2lnbmVkIEhUU2l6ZSA9IE51bUJ1Y2tldHM7CisgIGlmIChIVFNpemUgPT0gMCkgcmV0dXJuIC0xOyAgLy8gUmVhbGx5IGVtcHR5IHRhYmxlPworICB1bnNpZ25lZCBGdWxsSGFzaFZhbHVlID0gSGFzaFN0cmluZyhLZXkpOworICB1bnNpZ25lZCBCdWNrZXRObyA9IEZ1bGxIYXNoVmFsdWUgJiAoSFRTaXplLTEpOworICB1bnNpZ25lZCAqSGFzaFRhYmxlID0gKHVuc2lnbmVkICopKFRoZVRhYmxlICsgTnVtQnVja2V0cyArIDEpOworCisgIHVuc2lnbmVkIFByb2JlQW10ID0gMTsKKyAgd2hpbGUgKDEpIHsKKyAgICBTdHJpbmdNYXBFbnRyeUJhc2UgKkJ1Y2tldEl0ZW0gPSBUaGVUYWJsZVtCdWNrZXROb107CisgICAgLy8gSWYgd2UgZm91bmQgYW4gZW1wdHkgYnVja2V0LCB0aGlzIGtleSBpc24ndCBpbiB0aGUgdGFibGUgeWV0LCByZXR1cm4uCisgICAgaWYgKCFCdWNrZXRJdGVtKQorICAgICAgcmV0dXJuIC0xOworCisgICAgaWYgKEJ1Y2tldEl0ZW0gPT0gZ2V0VG9tYnN0b25lVmFsKCkpIHsKKyAgICAgIC8vIElnbm9yZSB0b21ic3RvbmVzLgorICAgIH0gZWxzZSBpZiAoSGFzaFRhYmxlW0J1Y2tldE5vXSA9PSBGdWxsSGFzaFZhbHVlKSB7CisgICAgICAvLyBJZiB0aGUgZnVsbCBoYXNoIHZhbHVlIG1hdGNoZXMsIGNoZWNrIGRlZXBseSBmb3IgYSBtYXRjaC4gIFRoZSBjb21tb24KKyAgICAgIC8vIGNhc2UgaGVyZSBpcyB0aGF0IHdlIGFyZSBvbmx5IGxvb2tpbmcgYXQgdGhlIGJ1Y2tldHMgKGZvciBpdGVtIGluZm8KKyAgICAgIC8vIGJlaW5nIG5vbi1udWxsIGFuZCBmb3IgdGhlIGZ1bGwgaGFzaCB2YWx1ZSkgbm90IGF0IHRoZSBpdGVtcy4gIFRoaXMKKyAgICAgIC8vIGlzIGltcG9ydGFudCBmb3IgY2FjaGUgbG9jYWxpdHkuCisKKyAgICAgIC8vIERvIHRoZSBjb21wYXJpc29uIGxpa2UgdGhpcyBiZWNhdXNlIE5hbWVTdGFydCBpc24ndCBuZWNlc3NhcmlseQorICAgICAgLy8gbnVsbC10ZXJtaW5hdGVkIQorICAgICAgY2hhciAqSXRlbVN0ciA9IChjaGFyKilCdWNrZXRJdGVtK0l0ZW1TaXplOworICAgICAgaWYgKEtleSA9PSBTdHJpbmdSZWYoSXRlbVN0ciwgQnVja2V0SXRlbS0+Z2V0S2V5TGVuZ3RoKCkpKSB7CisgICAgICAgIC8vIFdlIGZvdW5kIGEgbWF0Y2ghCisgICAgICAgIHJldHVybiBCdWNrZXRObzsKKyAgICAgIH0KKyAgICB9CisKKyAgICAvLyBPa2F5LCB3ZSBkaWRuJ3QgZmluZCB0aGUgaXRlbS4gIFByb2JlIHRvIHRoZSBuZXh0IGJ1Y2tldC4KKyAgICBCdWNrZXRObyA9IChCdWNrZXRObytQcm9iZUFtdCkgJiAoSFRTaXplLTEpOworCisgICAgLy8gVXNlIHF1YWRyYXRpYyBwcm9iaW5nLCBpdCBoYXMgZmV3ZXIgY2x1bXBpbmcgYXJ0aWZhY3RzIHRoYW4gbGluZWFyCisgICAgLy8gcHJvYmluZyBhbmQgaGFzIGdvb2QgY2FjaGUgYmVoYXZpb3IgaW4gdGhlIGNvbW1vbiBjYXNlLgorICAgICsrUHJvYmVBbXQ7CisgIH0KK30KKworLy8vIFJlbW92ZUtleSAtIFJlbW92ZSB0aGUgc3BlY2lmaWVkIFN0cmluZ01hcEVudHJ5IGZyb20gdGhlIHRhYmxlLCBidXQgZG8gbm90CisvLy8gZGVsZXRlIGl0LiAgVGhpcyBhYm9ydHMgaWYgdGhlIHZhbHVlIGlzbid0IGluIHRoZSB0YWJsZS4KK3ZvaWQgU3RyaW5nTWFwSW1wbDo6UmVtb3ZlS2V5KFN0cmluZ01hcEVudHJ5QmFzZSAqVikgeworICBjb25zdCBjaGFyICpWU3RyID0gKGNoYXIqKVYgKyBJdGVtU2l6ZTsKKyAgU3RyaW5nTWFwRW50cnlCYXNlICpWMiA9IFJlbW92ZUtleShTdHJpbmdSZWYoVlN0ciwgVi0+Z2V0S2V5TGVuZ3RoKCkpKTsKKyAgKHZvaWQpVjI7CisgIGFzc2VydChWID09IFYyICYmICJEaWRuJ3QgZmluZCBrZXk/Iik7Cit9CisKKy8vLyBSZW1vdmVLZXkgLSBSZW1vdmUgdGhlIFN0cmluZ01hcEVudHJ5IGZvciB0aGUgc3BlY2lmaWVkIGtleSBmcm9tIHRoZQorLy8vIHRhYmxlLCByZXR1cm5pbmcgaXQuICBJZiB0aGUga2V5IGlzIG5vdCBpbiB0aGUgdGFibGUsIHRoaXMgcmV0dXJucyBudWxsLgorU3RyaW5nTWFwRW50cnlCYXNlICpTdHJpbmdNYXBJbXBsOjpSZW1vdmVLZXkoU3RyaW5nUmVmIEtleSkgeworICBpbnQgQnVja2V0ID0gRmluZEtleShLZXkpOworICBpZiAoQnVja2V0ID09IC0xKSByZXR1cm4gbnVsbHB0cjsKKworICBTdHJpbmdNYXBFbnRyeUJhc2UgKlJlc3VsdCA9IFRoZVRhYmxlW0J1Y2tldF07CisgIFRoZVRhYmxlW0J1Y2tldF0gPSBnZXRUb21ic3RvbmVWYWwoKTsKKyAgLS1OdW1JdGVtczsKKyAgKytOdW1Ub21ic3RvbmVzOworICBhc3NlcnQoTnVtSXRlbXMgKyBOdW1Ub21ic3RvbmVzIDw9IE51bUJ1Y2tldHMpOworCisgIHJldHVybiBSZXN1bHQ7Cit9CisKKworCisvLy8gUmVoYXNoVGFibGUgLSBHcm93IHRoZSB0YWJsZSwgcmVkaXN0cmlidXRpbmcgdmFsdWVzIGludG8gdGhlIGJ1Y2tldHMgd2l0aAorLy8vIHRoZSBhcHByb3ByaWF0ZSBtb2Qtb2YtaGFzaHRhYmxlLXNpemUuCit1bnNpZ25lZCBTdHJpbmdNYXBJbXBsOjpSZWhhc2hUYWJsZSh1bnNpZ25lZCBCdWNrZXRObykgeworICB1bnNpZ25lZCBOZXdTaXplOworICB1bnNpZ25lZCAqSGFzaFRhYmxlID0gKHVuc2lnbmVkICopKFRoZVRhYmxlICsgTnVtQnVja2V0cyArIDEpOworCisgIC8vIElmIHRoZSBoYXNoIHRhYmxlIGlzIG5vdyBtb3JlIHRoYW4gMy80IGZ1bGwsIG9yIGlmIGZld2VyIHRoYW4gMS84IG9mCisgIC8vIHRoZSBidWNrZXRzIGFyZSBlbXB0eSAobWVhbmluZyB0aGF0IG1hbnkgYXJlIGZpbGxlZCB3aXRoIHRvbWJzdG9uZXMpLAorICAvLyBncm93L3JlaGFzaCB0aGUgdGFibGUuCisgIGlmIChOdW1JdGVtcyAqIDQgPiBOdW1CdWNrZXRzICogMykgeworICAgIE5ld1NpemUgPSBOdW1CdWNrZXRzKjI7CisgIH0gZWxzZSBpZiAoTnVtQnVja2V0cyAtIChOdW1JdGVtcyArIE51bVRvbWJzdG9uZXMpIDw9IE51bUJ1Y2tldHMgLyA4KSB7CisgICAgTmV3U2l6ZSA9IE51bUJ1Y2tldHM7CisgIH0gZWxzZSB7CisgICAgcmV0dXJuIEJ1Y2tldE5vOworICB9CisKKyAgdW5zaWduZWQgTmV3QnVja2V0Tm8gPSBCdWNrZXRObzsKKyAgLy8gQWxsb2NhdGUgb25lIGV4dHJhIGJ1Y2tldCB3aGljaCB3aWxsIGFsd2F5cyBiZSBub24tZW1wdHkuICBUaGlzIGFsbG93cyB0aGUKKyAgLy8gaXRlcmF0b3JzIHRvIHN0b3AgYXQgZW5kLgorICBTdHJpbmdNYXBFbnRyeUJhc2UgKipOZXdUYWJsZUFycmF5ID0KKyAgICAoU3RyaW5nTWFwRW50cnlCYXNlICoqKWNhbGxvYyhOZXdTaXplKzEsIHNpemVvZihTdHJpbmdNYXBFbnRyeUJhc2UgKikgKworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2l6ZW9mKHVuc2lnbmVkKSk7CisgIHVuc2lnbmVkICpOZXdIYXNoQXJyYXkgPSAodW5zaWduZWQgKikoTmV3VGFibGVBcnJheSArIE5ld1NpemUgKyAxKTsKKyAgTmV3VGFibGVBcnJheVtOZXdTaXplXSA9IChTdHJpbmdNYXBFbnRyeUJhc2UqKTI7CisKKyAgLy8gUmVoYXNoIGFsbCB0aGUgaXRlbXMgaW50byB0aGVpciBuZXcgYnVja2V0cy4gIEx1Y2tpbHkgOikgd2UgYWxyZWFkeSBoYXZlCisgIC8vIHRoZSBoYXNoIHZhbHVlcyBhdmFpbGFibGUsIHNvIHdlIGRvbid0IGhhdmUgdG8gcmVoYXNoIGFueSBzdHJpbmdzLgorICBmb3IgKHVuc2lnbmVkIEkgPSAwLCBFID0gTnVtQnVja2V0czsgSSAhPSBFOyArK0kpIHsKKyAgICBTdHJpbmdNYXBFbnRyeUJhc2UgKkJ1Y2tldCA9IFRoZVRhYmxlW0ldOworICAgIGlmIChCdWNrZXQgJiYgQnVja2V0ICE9IGdldFRvbWJzdG9uZVZhbCgpKSB7CisgICAgICAvLyBGYXN0IGNhc2UsIGJ1Y2tldCBhdmFpbGFibGUuCisgICAgICB1bnNpZ25lZCBGdWxsSGFzaCA9IEhhc2hUYWJsZVtJXTsKKyAgICAgIHVuc2lnbmVkIE5ld0J1Y2tldCA9IEZ1bGxIYXNoICYgKE5ld1NpemUtMSk7CisgICAgICBpZiAoIU5ld1RhYmxlQXJyYXlbTmV3QnVja2V0XSkgeworICAgICAgICBOZXdUYWJsZUFycmF5W0Z1bGxIYXNoICYgKE5ld1NpemUtMSldID0gQnVja2V0OworICAgICAgICBOZXdIYXNoQXJyYXlbRnVsbEhhc2ggJiAoTmV3U2l6ZS0xKV0gPSBGdWxsSGFzaDsKKyAgICAgICAgaWYgKEkgPT0gQnVja2V0Tm8pCisgICAgICAgICAgTmV3QnVja2V0Tm8gPSBOZXdCdWNrZXQ7CisgICAgICAgIGNvbnRpbnVlOworICAgICAgfQorCisgICAgICAvLyBPdGhlcndpc2UgcHJvYmUgZm9yIGEgc3BvdC4KKyAgICAgIHVuc2lnbmVkIFByb2JlU2l6ZSA9IDE7CisgICAgICBkbyB7CisgICAgICAgIE5ld0J1Y2tldCA9IChOZXdCdWNrZXQgKyBQcm9iZVNpemUrKykgJiAoTmV3U2l6ZS0xKTsKKyAgICAgIH0gd2hpbGUgKE5ld1RhYmxlQXJyYXlbTmV3QnVja2V0XSk7CisKKyAgICAgIC8vIEZpbmFsbHkgZm91bmQgYSBzbG90LiAgRmlsbCBpdCBpbi4KKyAgICAgIE5ld1RhYmxlQXJyYXlbTmV3QnVja2V0XSA9IEJ1Y2tldDsKKyAgICAgIE5ld0hhc2hBcnJheVtOZXdCdWNrZXRdID0gRnVsbEhhc2g7CisgICAgICBpZiAoSSA9PSBCdWNrZXRObykKKyAgICAgICAgTmV3QnVja2V0Tm8gPSBOZXdCdWNrZXQ7CisgICAgfQorICB9CisKKyAgZnJlZShUaGVUYWJsZSk7CisKKyAgVGhlVGFibGUgPSBOZXdUYWJsZUFycmF5OworICBOdW1CdWNrZXRzID0gTmV3U2l6ZTsKKyAgTnVtVG9tYnN0b25lcyA9IDA7CisgIHJldHVybiBOZXdCdWNrZXRObzsKK30KZGlmZiAtLWdpdCBhL3NyYy9sbHZtL1N0cmluZ1JlZi5jcHAgYi9zcmMvbGx2bS9TdHJpbmdSZWYuY3BwCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmYxMjMxOGMKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvbGx2bS9TdHJpbmdSZWYuY3BwCkBAIC0wLDAgKzEsMzkzIEBACisvLz09PS0tIFN0cmluZ1JlZi5jcHAgLSBMaWdodHdlaWdodCBTdHJpbmcgUmVmZXJlbmNlcyAtLS0tLS0tLS0tLS0tLS0tLS0tLS09PT0vLworLy8KKy8vICAgICAgICAgICAgICAgICAgICAgVGhlIExMVk0gQ29tcGlsZXIgSW5mcmFzdHJ1Y3R1cmUKKy8vCisvLyBUaGlzIGZpbGUgaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFVuaXZlcnNpdHkgb2YgSWxsaW5vaXMgT3BlbiBTb3VyY2UKKy8vIExpY2Vuc2UuIFNlZSBMSUNFTlNFLlRYVCBmb3IgZGV0YWlscy4KKy8vCisvLz09PS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS09PT0vLworCisjaW5jbHVkZSAibGx2bS9TdHJpbmdSZWYuaCIKKyNpbmNsdWRlICJsbHZtL1NtYWxsVmVjdG9yLmgiCisjaW5jbHVkZSA8Yml0c2V0PgorI2luY2x1ZGUgPGNsaW1pdHM+CisKK3VzaW5nIG5hbWVzcGFjZSBsbHZtOworCisvLyBNU1ZDIGVtaXRzIHJlZmVyZW5jZXMgdG8gdGhpcyBpbnRvIHRoZSB0cmFuc2xhdGlvbiB1bml0cyB3aGljaCByZWZlcmVuY2UgaXQuCisjaWZuZGVmIF9NU0NfVkVSCitjb25zdCBzaXplX3QgU3RyaW5nUmVmOjpucG9zOworI2VuZGlmCisKK3N0YXRpYyBjaGFyIGFzY2lpX3RvbG93ZXIoY2hhciB4KSB7CisgIGlmICh4ID49ICdBJyAmJiB4IDw9ICdaJykKKyAgICByZXR1cm4geCAtICdBJyArICdhJzsKKyAgcmV0dXJuIHg7Cit9CisKK3N0YXRpYyBjaGFyIGFzY2lpX3RvdXBwZXIoY2hhciB4KSB7CisgIGlmICh4ID49ICdhJyAmJiB4IDw9ICd6JykKKyAgICByZXR1cm4geCAtICdhJyArICdBJzsKKyAgcmV0dXJuIHg7Cit9CisKK3N0YXRpYyBib29sIGFzY2lpX2lzZGlnaXQoY2hhciB4KSB7CisgIHJldHVybiB4ID49ICcwJyAmJiB4IDw9ICc5JzsKK30KKworLy8gc3RybmNhc2VjbXAoKSBpcyBub3QgYXZhaWxhYmxlIG9uIG5vbi1QT1NJWCBzeXN0ZW1zLCBzbyBkZWZpbmUgYW4KKy8vIGFsdGVybmF0aXZlIGZ1bmN0aW9uIGhlcmUuCitzdGF0aWMgaW50IGFzY2lpX3N0cm5jYXNlY21wKGNvbnN0IGNoYXIgKkxIUywgY29uc3QgY2hhciAqUkhTLCBzaXplX3QgTGVuZ3RoKSB7CisgIGZvciAoc2l6ZV90IEkgPSAwOyBJIDwgTGVuZ3RoOyArK0kpIHsKKyAgICB1bnNpZ25lZCBjaGFyIExIQyA9IGFzY2lpX3RvbG93ZXIoTEhTW0ldKTsKKyAgICB1bnNpZ25lZCBjaGFyIFJIQyA9IGFzY2lpX3RvbG93ZXIoUkhTW0ldKTsKKyAgICBpZiAoTEhDICE9IFJIQykKKyAgICAgIHJldHVybiBMSEMgPCBSSEMgPyAtMSA6IDE7CisgIH0KKyAgcmV0dXJuIDA7Cit9CisKKy8vLyBjb21wYXJlX2xvd2VyIC0gQ29tcGFyZSBzdHJpbmdzLCBpZ25vcmluZyBjYXNlLgoraW50IFN0cmluZ1JlZjo6Y29tcGFyZV9sb3dlcihTdHJpbmdSZWYgUkhTKSBjb25zdCB7CisgIGlmIChpbnQgUmVzID0gYXNjaWlfc3RybmNhc2VjbXAoRGF0YSwgUkhTLkRhdGEsIHN0ZDo6bWluKExlbmd0aCwgUkhTLkxlbmd0aCkpKQorICAgIHJldHVybiBSZXM7CisgIGlmIChMZW5ndGggPT0gUkhTLkxlbmd0aCkKKyAgICByZXR1cm4gMDsKKyAgcmV0dXJuIExlbmd0aCA8IFJIUy5MZW5ndGggPyAtMSA6IDE7Cit9CisKKy8vLyBDaGVjayBpZiB0aGlzIHN0cmluZyBzdGFydHMgd2l0aCB0aGUgZ2l2ZW4gXHAgUHJlZml4LCBpZ25vcmluZyBjYXNlLgorYm9vbCBTdHJpbmdSZWY6OnN0YXJ0c3dpdGhfbG93ZXIoU3RyaW5nUmVmIFByZWZpeCkgY29uc3QgeworICByZXR1cm4gTGVuZ3RoID49IFByZWZpeC5MZW5ndGggJiYKKyAgICAgIGFzY2lpX3N0cm5jYXNlY21wKERhdGEsIFByZWZpeC5EYXRhLCBQcmVmaXguTGVuZ3RoKSA9PSAwOworfQorCisvLy8gQ2hlY2sgaWYgdGhpcyBzdHJpbmcgZW5kcyB3aXRoIHRoZSBnaXZlbiBccCBTdWZmaXgsIGlnbm9yaW5nIGNhc2UuCitib29sIFN0cmluZ1JlZjo6ZW5kc3dpdGhfbG93ZXIoU3RyaW5nUmVmIFN1ZmZpeCkgY29uc3QgeworICByZXR1cm4gTGVuZ3RoID49IFN1ZmZpeC5MZW5ndGggJiYKKyAgICAgIGFzY2lpX3N0cm5jYXNlY21wKGVuZCgpIC0gU3VmZml4Lkxlbmd0aCwgU3VmZml4LkRhdGEsIFN1ZmZpeC5MZW5ndGgpID09IDA7Cit9CisKKy8vLyBjb21wYXJlX251bWVyaWMgLSBDb21wYXJlIHN0cmluZ3MsIGhhbmRsZSBlbWJlZGRlZCBudW1iZXJzLgoraW50IFN0cmluZ1JlZjo6Y29tcGFyZV9udW1lcmljKFN0cmluZ1JlZiBSSFMpIGNvbnN0IHsKKyAgZm9yIChzaXplX3QgSSA9IDAsIEUgPSBzdGQ6Om1pbihMZW5ndGgsIFJIUy5MZW5ndGgpOyBJICE9IEU7ICsrSSkgeworICAgIC8vIENoZWNrIGZvciBzZXF1ZW5jZXMgb2YgZGlnaXRzLgorICAgIGlmIChhc2NpaV9pc2RpZ2l0KERhdGFbSV0pICYmIGFzY2lpX2lzZGlnaXQoUkhTLkRhdGFbSV0pKSB7CisgICAgICAvLyBUaGUgbG9uZ2VyIHNlcXVlbmNlIG9mIG51bWJlcnMgaXMgY29uc2lkZXJlZCBsYXJnZXIuCisgICAgICAvLyBUaGlzIGRvZXNuJ3QgcmVhbGx5IGhhbmRsZSBwcmVmaXhlZCB6ZXJvcyB3ZWxsLgorICAgICAgc2l6ZV90IEo7CisgICAgICBmb3IgKEogPSBJICsgMTsgSiAhPSBFICsgMTsgKytKKSB7CisgICAgICAgIGJvb2wgbGQgPSBKIDwgTGVuZ3RoICYmIGFzY2lpX2lzZGlnaXQoRGF0YVtKXSk7CisgICAgICAgIGJvb2wgcmQgPSBKIDwgUkhTLkxlbmd0aCAmJiBhc2NpaV9pc2RpZ2l0KFJIUy5EYXRhW0pdKTsKKyAgICAgICAgaWYgKGxkICE9IHJkKQorICAgICAgICAgIHJldHVybiByZCA/IC0xIDogMTsKKyAgICAgICAgaWYgKCFyZCkKKyAgICAgICAgICBicmVhazsKKyAgICAgIH0KKyAgICAgIC8vIFRoZSB0d28gbnVtYmVyIHNlcXVlbmNlcyBoYXZlIHRoZSBzYW1lIGxlbmd0aCAoSi1JKSwganVzdCBtZW1jbXAgdGhlbS4KKyAgICAgIGlmIChpbnQgUmVzID0gY29tcGFyZU1lbW9yeShEYXRhICsgSSwgUkhTLkRhdGEgKyBJLCBKIC0gSSkpCisgICAgICAgIHJldHVybiBSZXMgPCAwID8gLTEgOiAxOworICAgICAgLy8gSWRlbnRpY2FsIG51bWJlciBzZXF1ZW5jZXMsIGNvbnRpbnVlIHNlYXJjaCBhZnRlciB0aGUgbnVtYmVycy4KKyAgICAgIEkgPSBKIC0gMTsKKyAgICAgIGNvbnRpbnVlOworICAgIH0KKyAgICBpZiAoRGF0YVtJXSAhPSBSSFMuRGF0YVtJXSkKKyAgICAgIHJldHVybiAodW5zaWduZWQgY2hhcilEYXRhW0ldIDwgKHVuc2lnbmVkIGNoYXIpUkhTLkRhdGFbSV0gPyAtMSA6IDE7CisgIH0KKyAgaWYgKExlbmd0aCA9PSBSSFMuTGVuZ3RoKQorICAgIHJldHVybiAwOworICByZXR1cm4gTGVuZ3RoIDwgUkhTLkxlbmd0aCA/IC0xIDogMTsKK30KKworLy89PT0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tPT09Ly8KKy8vIFN0cmluZyBPcGVyYXRpb25zCisvLz09PS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS09PT0vLworCitzdGQ6OnN0cmluZyBTdHJpbmdSZWY6Omxvd2VyKCkgY29uc3QgeworICBzdGQ6OnN0cmluZyBSZXN1bHQoc2l6ZSgpLCBjaGFyKCkpOworICBmb3IgKHNpemVfdHlwZSBpID0gMCwgZSA9IHNpemUoKTsgaSAhPSBlOyArK2kpIHsKKyAgICBSZXN1bHRbaV0gPSBhc2NpaV90b2xvd2VyKERhdGFbaV0pOworICB9CisgIHJldHVybiBSZXN1bHQ7Cit9CisKK3N0ZDo6c3RyaW5nIFN0cmluZ1JlZjo6dXBwZXIoKSBjb25zdCB7CisgIHN0ZDo6c3RyaW5nIFJlc3VsdChzaXplKCksIGNoYXIoKSk7CisgIGZvciAoc2l6ZV90eXBlIGkgPSAwLCBlID0gc2l6ZSgpOyBpICE9IGU7ICsraSkgeworICAgIFJlc3VsdFtpXSA9IGFzY2lpX3RvdXBwZXIoRGF0YVtpXSk7CisgIH0KKyAgcmV0dXJuIFJlc3VsdDsKK30KKworLy89PT0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tPT09Ly8KKy8vIFN0cmluZyBTZWFyY2hpbmcKKy8vPT09LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLT09PS8vCisKKworLy8vIGZpbmQgLSBTZWFyY2ggZm9yIHRoZSBmaXJzdCBzdHJpbmcgXGFyZyBTdHIgaW4gdGhlIHN0cmluZy4KKy8vLworLy8vIFxyZXR1cm4gLSBUaGUgaW5kZXggb2YgdGhlIGZpcnN0IG9jY3VycmVuY2Ugb2YgXGFyZyBTdHIsIG9yIG5wb3MgaWYgbm90CisvLy8gZm91bmQuCitzaXplX3QgU3RyaW5nUmVmOjpmaW5kKFN0cmluZ1JlZiBTdHIsIHNpemVfdCBGcm9tKSBjb25zdCB7CisgIHNpemVfdCBOID0gU3RyLnNpemUoKTsKKyAgaWYgKE4gPiBMZW5ndGgpCisgICAgcmV0dXJuIG5wb3M7CisKKyAgLy8gRm9yIHNob3J0IGhheXN0YWNrcyBvciB1bnN1cHBvcnRlZCBuZWVkbGVzIGZhbGwgYmFjayB0byB0aGUgbmFpdmUgYWxnb3JpdGhtCisgIGlmIChMZW5ndGggPCAxNiB8fCBOID4gMjU1IHx8IE4gPT0gMCkgeworICAgIGZvciAoc2l6ZV90IGUgPSBMZW5ndGggLSBOICsgMSwgaSA9IHN0ZDo6bWluKEZyb20sIGUpOyBpICE9IGU7ICsraSkKKyAgICAgIGlmIChzdWJzdHIoaSwgTikuZXF1YWxzKFN0cikpCisgICAgICAgIHJldHVybiBpOworICAgIHJldHVybiBucG9zOworICB9CisKKyAgaWYgKEZyb20gPj0gTGVuZ3RoKQorICAgIHJldHVybiBucG9zOworCisgIC8vIEJ1aWxkIHRoZSBiYWQgY2hhciBoZXVyaXN0aWMgdGFibGUsIHdpdGggdWludDhfdCB0byByZWR1Y2UgY2FjaGUgdGhyYXNoaW5nLgorICB1aW50OF90IEJhZENoYXJTa2lwWzI1Nl07CisgIHN0ZDo6bWVtc2V0KEJhZENoYXJTa2lwLCBOLCAyNTYpOworICBmb3IgKHVuc2lnbmVkIGkgPSAwOyBpICE9IE4tMTsgKytpKQorICAgIEJhZENoYXJTa2lwWyh1aW50OF90KVN0cltpXV0gPSBOLTEtaTsKKworICB1bnNpZ25lZCBMZW4gPSBMZW5ndGgtRnJvbSwgUG9zID0gRnJvbTsKKyAgd2hpbGUgKExlbiA+PSBOKSB7CisgICAgaWYgKHN1YnN0cihQb3MsIE4pLmVxdWFscyhTdHIpKSAvLyBTZWUgaWYgdGhpcyBpcyB0aGUgY29ycmVjdCBzdWJzdHJpbmcuCisgICAgICByZXR1cm4gUG9zOworCisgICAgLy8gT3RoZXJ3aXNlIHNraXAgdGhlIGFwcHJvcHJpYXRlIG51bWJlciBvZiBieXRlcy4KKyAgICB1aW50OF90IFNraXAgPSBCYWRDaGFyU2tpcFsodWludDhfdCkoKnRoaXMpW1BvcytOLTFdXTsKKyAgICBMZW4gLT0gU2tpcDsKKyAgICBQb3MgKz0gU2tpcDsKKyAgfQorCisgIHJldHVybiBucG9zOworfQorCisvLy8gcmZpbmQgLSBTZWFyY2ggZm9yIHRoZSBsYXN0IHN0cmluZyBcYXJnIFN0ciBpbiB0aGUgc3RyaW5nLgorLy8vCisvLy8gXHJldHVybiAtIFRoZSBpbmRleCBvZiB0aGUgbGFzdCBvY2N1cnJlbmNlIG9mIFxhcmcgU3RyLCBvciBucG9zIGlmIG5vdAorLy8vIGZvdW5kLgorc2l6ZV90IFN0cmluZ1JlZjo6cmZpbmQoU3RyaW5nUmVmIFN0cikgY29uc3QgeworICBzaXplX3QgTiA9IFN0ci5zaXplKCk7CisgIGlmIChOID4gTGVuZ3RoKQorICAgIHJldHVybiBucG9zOworICBmb3IgKHNpemVfdCBpID0gTGVuZ3RoIC0gTiArIDEsIGUgPSAwOyBpICE9IGU7KSB7CisgICAgLS1pOworICAgIGlmIChzdWJzdHIoaSwgTikuZXF1YWxzKFN0cikpCisgICAgICByZXR1cm4gaTsKKyAgfQorICByZXR1cm4gbnBvczsKK30KKworLy8vIGZpbmRfZmlyc3Rfb2YgLSBGaW5kIHRoZSBmaXJzdCBjaGFyYWN0ZXIgaW4gdGhlIHN0cmluZyB0aGF0IGlzIGluIFxhcmcKKy8vLyBDaGFycywgb3IgbnBvcyBpZiBub3QgZm91bmQuCisvLy8KKy8vLyBOb3RlOiBPKHNpemUoKSArIENoYXJzLnNpemUoKSkKK1N0cmluZ1JlZjo6c2l6ZV90eXBlIFN0cmluZ1JlZjo6ZmluZF9maXJzdF9vZihTdHJpbmdSZWYgQ2hhcnMsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2l6ZV90IEZyb20pIGNvbnN0IHsKKyAgc3RkOjpiaXRzZXQ8MSA8PCBDSEFSX0JJVD4gQ2hhckJpdHM7CisgIGZvciAoc2l6ZV90eXBlIGkgPSAwOyBpICE9IENoYXJzLnNpemUoKTsgKytpKQorICAgIENoYXJCaXRzLnNldCgodW5zaWduZWQgY2hhcilDaGFyc1tpXSk7CisKKyAgZm9yIChzaXplX3R5cGUgaSA9IHN0ZDo6bWluKEZyb20sIExlbmd0aCksIGUgPSBMZW5ndGg7IGkgIT0gZTsgKytpKQorICAgIGlmIChDaGFyQml0cy50ZXN0KCh1bnNpZ25lZCBjaGFyKURhdGFbaV0pKQorICAgICAgcmV0dXJuIGk7CisgIHJldHVybiBucG9zOworfQorCisvLy8gZmluZF9maXJzdF9ub3Rfb2YgLSBGaW5kIHRoZSBmaXJzdCBjaGFyYWN0ZXIgaW4gdGhlIHN0cmluZyB0aGF0IGlzIG5vdAorLy8vIFxhcmcgQyBvciBucG9zIGlmIG5vdCBmb3VuZC4KK1N0cmluZ1JlZjo6c2l6ZV90eXBlIFN0cmluZ1JlZjo6ZmluZF9maXJzdF9ub3Rfb2YoY2hhciBDLCBzaXplX3QgRnJvbSkgY29uc3QgeworICBmb3IgKHNpemVfdHlwZSBpID0gc3RkOjptaW4oRnJvbSwgTGVuZ3RoKSwgZSA9IExlbmd0aDsgaSAhPSBlOyArK2kpCisgICAgaWYgKERhdGFbaV0gIT0gQykKKyAgICAgIHJldHVybiBpOworICByZXR1cm4gbnBvczsKK30KKworLy8vIGZpbmRfZmlyc3Rfbm90X29mIC0gRmluZCB0aGUgZmlyc3QgY2hhcmFjdGVyIGluIHRoZSBzdHJpbmcgdGhhdCBpcyBub3QKKy8vLyBpbiB0aGUgc3RyaW5nIFxhcmcgQ2hhcnMsIG9yIG5wb3MgaWYgbm90IGZvdW5kLgorLy8vCisvLy8gTm90ZTogTyhzaXplKCkgKyBDaGFycy5zaXplKCkpCitTdHJpbmdSZWY6OnNpemVfdHlwZSBTdHJpbmdSZWY6OmZpbmRfZmlyc3Rfbm90X29mKFN0cmluZ1JlZiBDaGFycywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2l6ZV90IEZyb20pIGNvbnN0IHsKKyAgc3RkOjpiaXRzZXQ8MSA8PCBDSEFSX0JJVD4gQ2hhckJpdHM7CisgIGZvciAoc2l6ZV90eXBlIGkgPSAwOyBpICE9IENoYXJzLnNpemUoKTsgKytpKQorICAgIENoYXJCaXRzLnNldCgodW5zaWduZWQgY2hhcilDaGFyc1tpXSk7CisKKyAgZm9yIChzaXplX3R5cGUgaSA9IHN0ZDo6bWluKEZyb20sIExlbmd0aCksIGUgPSBMZW5ndGg7IGkgIT0gZTsgKytpKQorICAgIGlmICghQ2hhckJpdHMudGVzdCgodW5zaWduZWQgY2hhcilEYXRhW2ldKSkKKyAgICAgIHJldHVybiBpOworICByZXR1cm4gbnBvczsKK30KKworLy8vIGZpbmRfbGFzdF9vZiAtIEZpbmQgdGhlIGxhc3QgY2hhcmFjdGVyIGluIHRoZSBzdHJpbmcgdGhhdCBpcyBpbiBcYXJnIEMsCisvLy8gb3IgbnBvcyBpZiBub3QgZm91bmQuCisvLy8KKy8vLyBOb3RlOiBPKHNpemUoKSArIENoYXJzLnNpemUoKSkKK1N0cmluZ1JlZjo6c2l6ZV90eXBlIFN0cmluZ1JlZjo6ZmluZF9sYXN0X29mKFN0cmluZ1JlZiBDaGFycywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNpemVfdCBGcm9tKSBjb25zdCB7CisgIHN0ZDo6Yml0c2V0PDEgPDwgQ0hBUl9CSVQ+IENoYXJCaXRzOworICBmb3IgKHNpemVfdHlwZSBpID0gMDsgaSAhPSBDaGFycy5zaXplKCk7ICsraSkKKyAgICBDaGFyQml0cy5zZXQoKHVuc2lnbmVkIGNoYXIpQ2hhcnNbaV0pOworCisgIGZvciAoc2l6ZV90eXBlIGkgPSBzdGQ6Om1pbihGcm9tLCBMZW5ndGgpIC0gMSwgZSA9IC0xOyBpICE9IGU7IC0taSkKKyAgICBpZiAoQ2hhckJpdHMudGVzdCgodW5zaWduZWQgY2hhcilEYXRhW2ldKSkKKyAgICAgIHJldHVybiBpOworICByZXR1cm4gbnBvczsKK30KKworLy8vIGZpbmRfbGFzdF9ub3Rfb2YgLSBGaW5kIHRoZSBsYXN0IGNoYXJhY3RlciBpbiB0aGUgc3RyaW5nIHRoYXQgaXMgbm90CisvLy8gXGFyZyBDLCBvciBucG9zIGlmIG5vdCBmb3VuZC4KK1N0cmluZ1JlZjo6c2l6ZV90eXBlIFN0cmluZ1JlZjo6ZmluZF9sYXN0X25vdF9vZihjaGFyIEMsIHNpemVfdCBGcm9tKSBjb25zdCB7CisgIGZvciAoc2l6ZV90eXBlIGkgPSBzdGQ6Om1pbihGcm9tLCBMZW5ndGgpIC0gMSwgZSA9IC0xOyBpICE9IGU7IC0taSkKKyAgICBpZiAoRGF0YVtpXSAhPSBDKQorICAgICAgcmV0dXJuIGk7CisgIHJldHVybiBucG9zOworfQorCisvLy8gZmluZF9sYXN0X25vdF9vZiAtIEZpbmQgdGhlIGxhc3QgY2hhcmFjdGVyIGluIHRoZSBzdHJpbmcgdGhhdCBpcyBub3QgaW4KKy8vLyBcYXJnIENoYXJzLCBvciBucG9zIGlmIG5vdCBmb3VuZC4KKy8vLworLy8vIE5vdGU6IE8oc2l6ZSgpICsgQ2hhcnMuc2l6ZSgpKQorU3RyaW5nUmVmOjpzaXplX3R5cGUgU3RyaW5nUmVmOjpmaW5kX2xhc3Rfbm90X29mKFN0cmluZ1JlZiBDaGFycywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzaXplX3QgRnJvbSkgY29uc3QgeworICBzdGQ6OmJpdHNldDwxIDw8IENIQVJfQklUPiBDaGFyQml0czsKKyAgZm9yIChzaXplX3R5cGUgaSA9IDAsIGUgPSBDaGFycy5zaXplKCk7IGkgIT0gZTsgKytpKQorICAgIENoYXJCaXRzLnNldCgodW5zaWduZWQgY2hhcilDaGFyc1tpXSk7CisKKyAgZm9yIChzaXplX3R5cGUgaSA9IHN0ZDo6bWluKEZyb20sIExlbmd0aCkgLSAxLCBlID0gLTE7IGkgIT0gZTsgLS1pKQorICAgIGlmICghQ2hhckJpdHMudGVzdCgodW5zaWduZWQgY2hhcilEYXRhW2ldKSkKKyAgICAgIHJldHVybiBpOworICByZXR1cm4gbnBvczsKK30KKwordm9pZCBTdHJpbmdSZWY6OnNwbGl0KFNtYWxsVmVjdG9ySW1wbDxTdHJpbmdSZWY+ICZBLAorICAgICAgICAgICAgICAgICAgICAgIFN0cmluZ1JlZiBTZXBhcmF0b3JzLCBpbnQgTWF4U3BsaXQsCisgICAgICAgICAgICAgICAgICAgICAgYm9vbCBLZWVwRW1wdHkpIGNvbnN0IHsKKyAgU3RyaW5nUmVmIHJlc3QgPSAqdGhpczsKKworICAvLyByZXN0LmRhdGEoKSBpcyB1c2VkIHRvIGRpc3Rpbmd1aXNoIGNhc2VzIGxpa2UgImEsIiB0aGF0IHNwbGl0cyBpbnRvCisgIC8vICJhIiArICIiIGFuZCAiYSIgdGhhdCBzcGxpdHMgaW50byAiYSIgKyAwLgorICBmb3IgKGludCBzcGxpdHMgPSAwOworICAgICAgIHJlc3QuZGF0YSgpICE9IG51bGxwdHIgJiYgKE1heFNwbGl0IDwgMCB8fCBzcGxpdHMgPCBNYXhTcGxpdCk7CisgICAgICAgKytzcGxpdHMpIHsKKyAgICBzdGQ6OnBhaXI8U3RyaW5nUmVmLCBTdHJpbmdSZWY+IHAgPSByZXN0LnNwbGl0KFNlcGFyYXRvcnMpOworCisgICAgaWYgKEtlZXBFbXB0eSB8fCBwLmZpcnN0LnNpemUoKSAhPSAwKQorICAgICAgQS5wdXNoX2JhY2socC5maXJzdCk7CisgICAgcmVzdCA9IHAuc2Vjb25kOworICB9CisgIC8vIElmIHdlIGhhdmUgYSB0YWlsIGxlZnQsIGFkZCBpdC4KKyAgaWYgKHJlc3QuZGF0YSgpICE9IG51bGxwdHIgJiYgKHJlc3Quc2l6ZSgpICE9IDAgfHwgS2VlcEVtcHR5KSkKKyAgICBBLnB1c2hfYmFjayhyZXN0KTsKK30KKworLy89PT0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tPT09Ly8KKy8vIEhlbHBmdWwgQWxnb3JpdGhtcworLy89PT0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tPT09Ly8KKworLy8vIGNvdW50IC0gUmV0dXJuIHRoZSBudW1iZXIgb2Ygbm9uLW92ZXJsYXBwZWQgb2NjdXJyZW5jZXMgb2YgXGFyZyBTdHIgaW4KKy8vLyB0aGUgc3RyaW5nLgorc2l6ZV90IFN0cmluZ1JlZjo6Y291bnQoU3RyaW5nUmVmIFN0cikgY29uc3QgeworICBzaXplX3QgQ291bnQgPSAwOworICBzaXplX3QgTiA9IFN0ci5zaXplKCk7CisgIGlmIChOID4gTGVuZ3RoKQorICAgIHJldHVybiAwOworICBmb3IgKHNpemVfdCBpID0gMCwgZSA9IExlbmd0aCAtIE4gKyAxOyBpICE9IGU7ICsraSkKKyAgICBpZiAoc3Vic3RyKGksIE4pLmVxdWFscyhTdHIpKQorICAgICAgKytDb3VudDsKKyAgcmV0dXJuIENvdW50OworfQorCitzdGF0aWMgdW5zaWduZWQgR2V0QXV0b1NlbnNlUmFkaXgoU3RyaW5nUmVmICZTdHIpIHsKKyAgaWYgKFN0ci5zdGFydHN3aXRoKCIweCIpKSB7CisgICAgU3RyID0gU3RyLnN1YnN0cigyKTsKKyAgICByZXR1cm4gMTY7CisgIH0KKworICBpZiAoU3RyLnN0YXJ0c3dpdGgoIjBiIikpIHsKKyAgICBTdHIgPSBTdHIuc3Vic3RyKDIpOworICAgIHJldHVybiAyOworICB9CisKKyAgaWYgKFN0ci5zdGFydHN3aXRoKCIwbyIpKSB7CisgICAgU3RyID0gU3RyLnN1YnN0cigyKTsKKyAgICByZXR1cm4gODsKKyAgfQorCisgIGlmIChTdHIuc3RhcnRzd2l0aCgiMCIpKQorICAgIHJldHVybiA4OworCisgIHJldHVybiAxMDsKK30KKworCisvLy8gR2V0QXNVbnNpZ25lZEludGVnZXIgLSBXb3JraG9yc2UgbWV0aG9kIHRoYXQgY29udmVydHMgYSBpbnRlZ2VyIGNoYXJhY3RlcgorLy8vIHNlcXVlbmNlIG9mIHJhZGl4IHVwIHRvIDM2IHRvIGFuIHVuc2lnbmVkIGxvbmcgbG9uZyB2YWx1ZS4KK2Jvb2wgbGx2bTo6Z2V0QXNVbnNpZ25lZEludGVnZXIoU3RyaW5nUmVmIFN0ciwgdW5zaWduZWQgUmFkaXgsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVuc2lnbmVkIGxvbmcgbG9uZyAmUmVzdWx0KSB7CisgIC8vIEF1dG9zZW5zZSByYWRpeCBpZiBub3Qgc3BlY2lmaWVkLgorICBpZiAoUmFkaXggPT0gMCkKKyAgICBSYWRpeCA9IEdldEF1dG9TZW5zZVJhZGl4KFN0cik7CisKKyAgLy8gRW1wdHkgc3RyaW5ncyAoYWZ0ZXIgdGhlIHJhZGl4IGF1dG9zZW5zZSkgYXJlIGludmFsaWQuCisgIGlmIChTdHIuZW1wdHkoKSkgcmV0dXJuIHRydWU7CisKKyAgLy8gUGFyc2UgYWxsIHRoZSBieXRlcyBvZiB0aGUgc3RyaW5nIGdpdmVuIHRoaXMgcmFkaXguICBXYXRjaCBmb3Igb3ZlcmZsb3cuCisgIFJlc3VsdCA9IDA7CisgIHdoaWxlICghU3RyLmVtcHR5KCkpIHsKKyAgICB1bnNpZ25lZCBDaGFyVmFsOworICAgIGlmIChTdHJbMF0gPj0gJzAnICYmIFN0clswXSA8PSAnOScpCisgICAgICBDaGFyVmFsID0gU3RyWzBdLScwJzsKKyAgICBlbHNlIGlmIChTdHJbMF0gPj0gJ2EnICYmIFN0clswXSA8PSAneicpCisgICAgICBDaGFyVmFsID0gU3RyWzBdLSdhJysxMDsKKyAgICBlbHNlIGlmIChTdHJbMF0gPj0gJ0EnICYmIFN0clswXSA8PSAnWicpCisgICAgICBDaGFyVmFsID0gU3RyWzBdLSdBJysxMDsKKyAgICBlbHNlCisgICAgICByZXR1cm4gdHJ1ZTsKKworICAgIC8vIElmIHRoZSBwYXJzZWQgdmFsdWUgaXMgbGFyZ2VyIHRoYW4gdGhlIGludGVnZXIgcmFkaXgsIHRoZSBzdHJpbmcgaXMKKyAgICAvLyBpbnZhbGlkLgorICAgIGlmIChDaGFyVmFsID49IFJhZGl4KQorICAgICAgcmV0dXJuIHRydWU7CisKKyAgICAvLyBBZGQgaW4gdGhpcyBjaGFyYWN0ZXIuCisgICAgdW5zaWduZWQgbG9uZyBsb25nIFByZXZSZXN1bHQgPSBSZXN1bHQ7CisgICAgUmVzdWx0ID0gUmVzdWx0KlJhZGl4K0NoYXJWYWw7CisKKyAgICAvLyBDaGVjayBmb3Igb3ZlcmZsb3cgYnkgc2hpZnRpbmcgYmFjayBhbmQgc2VlaW5nIGlmIGJpdHMgd2VyZSBsb3N0LgorICAgIGlmIChSZXN1bHQvUmFkaXggPCBQcmV2UmVzdWx0KQorICAgICAgcmV0dXJuIHRydWU7CisKKyAgICBTdHIgPSBTdHIuc3Vic3RyKDEpOworICB9CisKKyAgcmV0dXJuIGZhbHNlOworfQorCitib29sIGxsdm06OmdldEFzU2lnbmVkSW50ZWdlcihTdHJpbmdSZWYgU3RyLCB1bnNpZ25lZCBSYWRpeCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxvbmcgbG9uZyAmUmVzdWx0KSB7CisgIHVuc2lnbmVkIGxvbmcgbG9uZyBVTExWYWw7CisKKyAgLy8gSGFuZGxlIHBvc2l0aXZlIHN0cmluZ3MgZmlyc3QuCisgIGlmIChTdHIuZW1wdHkoKSB8fCBTdHIuZnJvbnQoKSAhPSAnLScpIHsKKyAgICBpZiAoZ2V0QXNVbnNpZ25lZEludGVnZXIoU3RyLCBSYWRpeCwgVUxMVmFsKSB8fAorICAgICAgICAvLyBDaGVjayBmb3IgdmFsdWUgc28gbGFyZ2UgaXQgb3ZlcmZsb3dzIGEgc2lnbmVkIHZhbHVlLgorICAgICAgICAobG9uZyBsb25nKVVMTFZhbCA8IDApCisgICAgICByZXR1cm4gdHJ1ZTsKKyAgICBSZXN1bHQgPSBVTExWYWw7CisgICAgcmV0dXJuIGZhbHNlOworICB9CisKKyAgLy8gR2V0IHRoZSBwb3NpdGl2ZSBwYXJ0IG9mIHRoZSB2YWx1ZS4KKyAgaWYgKGdldEFzVW5zaWduZWRJbnRlZ2VyKFN0ci5zdWJzdHIoMSksIFJhZGl4LCBVTExWYWwpIHx8CisgICAgICAvLyBSZWplY3QgdmFsdWVzIHNvIGxhcmdlIHRoZXknZCBvdmVyZmxvdyBhcyBuZWdhdGl2ZSBzaWduZWQsIGJ1dCBhbGxvdworICAgICAgLy8gIi0wIi4gIFRoaXMgbmVnYXRlcyB0aGUgdW5zaWduZWQgc28gdGhhdCB0aGUgbmVnYXRpdmUgaXNuJ3QgdW5kZWZpbmVkCisgICAgICAvLyBvbiBzaWduZWQgb3ZlcmZsb3cuCisgICAgICAobG9uZyBsb25nKS1VTExWYWwgPiAwKQorICAgIHJldHVybiB0cnVlOworCisgIFJlc3VsdCA9IC1VTExWYWw7CisgIHJldHVybiBmYWxzZTsKK30KZGlmZiAtLWdpdCBhL3NyYy9uZXR3b3JrdGFibGVzL05ldHdvcmtUYWJsZS5jcHAgYi9zcmMvbmV0d29ya3RhYmxlcy9OZXR3b3JrVGFibGUuY3BwCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjdlYjM3NzIKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvbmV0d29ya3RhYmxlcy9OZXR3b3JrVGFibGUuY3BwCkBAIC0wLDAgKzEsMzgxIEBACisjaW5jbHVkZSAibmV0d29ya3RhYmxlcy9OZXR3b3JrVGFibGUuaCIKKworI2luY2x1ZGUgPGFsZ29yaXRobT4KKworI2luY2x1ZGUgImxsdm0vU21hbGxTdHJpbmcuaCIKKyNpbmNsdWRlICJsbHZtL1N0cmluZ01hcC5oIgorI2luY2x1ZGUgInRhYmxlcy9JVGFibGVMaXN0ZW5lci5oIgorI2luY2x1ZGUgInRhYmxlcy9UYWJsZUtleU5vdERlZmluZWRFeGNlcHRpb24uaCIKKyNpbmNsdWRlICJudGNvcmUuaCIKKwordXNpbmcgbGx2bTo6U3RyaW5nUmVmOworCitjb25zdCBjaGFyIE5ldHdvcmtUYWJsZTo6UEFUSF9TRVBBUkFUT1JfQ0hBUiA9ICcvJzsKK3N0ZDo6c3RyaW5nIE5ldHdvcmtUYWJsZTo6c19pcF9hZGRyZXNzOworc3RkOjpzdHJpbmcgTmV0d29ya1RhYmxlOjpzX3BlcnNpc3RlbnRfZmlsZW5hbWUgPSAibmV0d29ya3RhYmxlcy5pbmkiOworYm9vbCBOZXR3b3JrVGFibGU6OnNfY2xpZW50ID0gZmFsc2U7Citib29sIE5ldHdvcmtUYWJsZTo6c19ydW5uaW5nID0gZmFsc2U7Cit1bnNpZ25lZCBpbnQgTmV0d29ya1RhYmxlOjpzX3BvcnQgPSBOVF9ERUZBVUxUX1BPUlQ7CisKK3ZvaWQgTmV0d29ya1RhYmxlOjpJbml0aWFsaXplKCkgeworICBpZiAoc19ydW5uaW5nKSBTaHV0ZG93bigpOworICBpZiAoc19jbGllbnQpCisgICAgbnQ6OlN0YXJ0Q2xpZW50KHNfaXBfYWRkcmVzcy5jX3N0cigpLCBzX3BvcnQpOworICBlbHNlCisgICAgbnQ6OlN0YXJ0U2VydmVyKHNfcGVyc2lzdGVudF9maWxlbmFtZSwgIiIsIHNfcG9ydCk7CisgIHNfcnVubmluZyA9IHRydWU7Cit9CisKK3ZvaWQgTmV0d29ya1RhYmxlOjpTaHV0ZG93bigpIHsKKyAgaWYgKCFzX3J1bm5pbmcpIHJldHVybjsKKyAgaWYgKHNfY2xpZW50KQorICAgIG50OjpTdG9wQ2xpZW50KCk7CisgIGVsc2UKKyAgICBudDo6U3RvcFNlcnZlcigpOworICBzX3J1bm5pbmcgPSBmYWxzZTsKK30KKwordm9pZCBOZXR3b3JrVGFibGU6OlNldENsaWVudE1vZGUoKSB7IHNfY2xpZW50ID0gdHJ1ZTsgfQorCit2b2lkIE5ldHdvcmtUYWJsZTo6U2V0U2VydmVyTW9kZSgpIHsgc19jbGllbnQgPSBmYWxzZTsgfQorCit2b2lkIE5ldHdvcmtUYWJsZTo6U2V0VGVhbShpbnQgdGVhbSkgeworICBjaGFyIHRtcFszMF07CisjaWZkZWYgX01TQ19WRVIKKyAgc3ByaW50Zl9zKHRtcCwgInJvYm9SSU8tJWQtRlJDLmxvY2FsXG4iLCB0ZWFtKTsKKyNlbHNlCisgIHN0ZDo6c25wcmludGYodG1wLCAzMCwgInJvYm9SSU8tJWQtRlJDLmxvY2FsXG4iLHRlYW0pOworI2VuZGlmCisgIFNldElQQWRkcmVzcyh0bXApOworfQorCit2b2lkIE5ldHdvcmtUYWJsZTo6U2V0SVBBZGRyZXNzKFN0cmluZ1JlZiBhZGRyZXNzKSB7IHNfaXBfYWRkcmVzcyA9IGFkZHJlc3M7IH0KKwordm9pZCBOZXR3b3JrVGFibGU6OlNldFBvcnQodW5zaWduZWQgaW50IHBvcnQpIHsgc19wb3J0ID0gcG9ydDsgfQorCit2b2lkIE5ldHdvcmtUYWJsZTo6U2V0UGVyc2lzdGVudEZpbGVuYW1lKFN0cmluZ1JlZiBmaWxlbmFtZSkgeworICBzX3BlcnNpc3RlbnRfZmlsZW5hbWUgPSBmaWxlbmFtZTsKK30KKwordm9pZCBOZXR3b3JrVGFibGU6OlNldE5ldHdvcmtJZGVudGl0eShTdHJpbmdSZWYgbmFtZSkgeworICBudDo6U2V0TmV0d29ya0lkZW50aXR5KG5hbWUpOworfQorCit2b2lkIE5ldHdvcmtUYWJsZTo6R2xvYmFsRGVsZXRlQWxsKCkgeyBudDo6RGVsZXRlQWxsRW50cmllcygpOyB9CisKK3ZvaWQgTmV0d29ya1RhYmxlOjpGbHVzaCgpIHsgbnQ6OkZsdXNoKCk7IH0KKwordm9pZCBOZXR3b3JrVGFibGU6OlNldFVwZGF0ZVJhdGUoZG91YmxlIGludGVydmFsKSB7CisgIG50OjpTZXRVcGRhdGVSYXRlKGludGVydmFsKTsKK30KKworY29uc3QgY2hhciogTmV0d29ya1RhYmxlOjpTYXZlUGVyc2lzdGVudChsbHZtOjpTdHJpbmdSZWYgZmlsZW5hbWUpIHsKKyAgcmV0dXJuIG50OjpTYXZlUGVyc2lzdGVudChmaWxlbmFtZSk7Cit9CisKK2NvbnN0IGNoYXIqIE5ldHdvcmtUYWJsZTo6TG9hZFBlcnNpc3RlbnQoCisgICAgbGx2bTo6U3RyaW5nUmVmIGZpbGVuYW1lLAorICAgIHN0ZDo6ZnVuY3Rpb248dm9pZChzaXplX3QgbGluZSwgY29uc3QgY2hhciogbXNnKT4gd2FybikgeworICByZXR1cm4gbnQ6OkxvYWRQZXJzaXN0ZW50KGZpbGVuYW1lLCB3YXJuKTsKK30KKworc3RkOjpzaGFyZWRfcHRyPE5ldHdvcmtUYWJsZT4gTmV0d29ya1RhYmxlOjpHZXRUYWJsZShTdHJpbmdSZWYga2V5KSB7CisgIGlmICghc19ydW5uaW5nKSBJbml0aWFsaXplKCk7CisgIGxsdm06OlNtYWxsU3RyaW5nPDEyOD4gcGF0aDsKKyAgaWYgKCFrZXkuZW1wdHkoKSkgeworICAgIHBhdGggKz0gUEFUSF9TRVBBUkFUT1JfQ0hBUjsKKyAgICBwYXRoICs9IGtleTsKKyAgfQorICByZXR1cm4gc3RkOjptYWtlX3NoYXJlZDxOZXR3b3JrVGFibGU+KHBhdGgsIHByaXZhdGVfaW5pdCgpKTsKK30KKworTmV0d29ya1RhYmxlOjpOZXR3b3JrVGFibGUoU3RyaW5nUmVmIHBhdGgsIGNvbnN0IHByaXZhdGVfaW5pdCYpCisgICAgOiBtX3BhdGgocGF0aCkge30KKworTmV0d29ya1RhYmxlOjp+TmV0d29ya1RhYmxlKCkgeworICBmb3IgKGF1dG8mIGkgOiBtX2xpc3RlbmVycykKKyAgICBudDo6UmVtb3ZlRW50cnlMaXN0ZW5lcihpLnNlY29uZCk7Cit9CisKK3ZvaWQgTmV0d29ya1RhYmxlOjpBZGRUYWJsZUxpc3RlbmVyKElUYWJsZUxpc3RlbmVyKiBsaXN0ZW5lcikgeworICBBZGRUYWJsZUxpc3RlbmVyRXgobGlzdGVuZXIsIE5UX05PVElGWV9ORVcgfCBOVF9OT1RJRllfVVBEQVRFKTsKK30KKwordm9pZCBOZXR3b3JrVGFibGU6OkFkZFRhYmxlTGlzdGVuZXIoSVRhYmxlTGlzdGVuZXIqIGxpc3RlbmVyLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYm9vbCBpbW1lZGlhdGVOb3RpZnkpIHsKKyAgdW5zaWduZWQgaW50IGZsYWdzID0gTlRfTk9USUZZX05FVyB8IE5UX05PVElGWV9VUERBVEU7CisgIGlmIChpbW1lZGlhdGVOb3RpZnkpIGZsYWdzIHw9IE5UX05PVElGWV9JTU1FRElBVEU7CisgIEFkZFRhYmxlTGlzdGVuZXJFeChsaXN0ZW5lciwgZmxhZ3MpOworfQorCit2b2lkIE5ldHdvcmtUYWJsZTo6QWRkVGFibGVMaXN0ZW5lckV4KElUYWJsZUxpc3RlbmVyKiBsaXN0ZW5lciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdW5zaWduZWQgaW50IGZsYWdzKSB7CisgIHN0ZDo6bG9ja19ndWFyZDxzdGQ6Om11dGV4PiBsb2NrKG1fbXV0ZXgpOworICBsbHZtOjpTbWFsbFN0cmluZzwxMjg+IHBhdGgobV9wYXRoKTsKKyAgcGF0aCArPSBQQVRIX1NFUEFSQVRPUl9DSEFSOworICBzdGQ6OnNpemVfdCBwcmVmaXhfbGVuID0gcGF0aC5zaXplKCk7CisgIHVuc2lnbmVkIGludCBpZCA9IG50OjpBZGRFbnRyeUxpc3RlbmVyKAorICAgICAgcGF0aCwKKyAgICAgIFs9XSh1bnNpZ25lZCBpbnQgLyp1aWQqLywgU3RyaW5nUmVmIG5hbWUsCisgICAgICAgICAgc3RkOjpzaGFyZWRfcHRyPG50OjpWYWx1ZT4gdmFsdWUsIHVuc2lnbmVkIGludCBmbGFnc18pIHsKKyAgICAgICAgU3RyaW5nUmVmIHJlbGF0aXZlX2tleSA9IG5hbWUuc3Vic3RyKHByZWZpeF9sZW4pOworICAgICAgICBpZiAocmVsYXRpdmVfa2V5LmZpbmQoUEFUSF9TRVBBUkFUT1JfQ0hBUikgIT0gU3RyaW5nUmVmOjpucG9zKSByZXR1cm47CisgICAgICAgIGxpc3RlbmVyLT5WYWx1ZUNoYW5nZWRFeCh0aGlzLCByZWxhdGl2ZV9rZXksIHZhbHVlLCBmbGFnc18pOworICAgICAgfSwKKyAgICAgIGZsYWdzKTsKKyAgbV9saXN0ZW5lcnMuZW1wbGFjZV9iYWNrKGxpc3RlbmVyLCBpZCk7Cit9CisKK3ZvaWQgTmV0d29ya1RhYmxlOjpBZGRUYWJsZUxpc3RlbmVyKFN0cmluZ1JlZiBrZXksIElUYWJsZUxpc3RlbmVyKiBsaXN0ZW5lciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJvb2wgaW1tZWRpYXRlTm90aWZ5KSB7CisgIHVuc2lnbmVkIGludCBmbGFncyA9IE5UX05PVElGWV9ORVcgfCBOVF9OT1RJRllfVVBEQVRFOworICBpZiAoaW1tZWRpYXRlTm90aWZ5KSBmbGFncyB8PSBOVF9OT1RJRllfSU1NRURJQVRFOworICBBZGRUYWJsZUxpc3RlbmVyRXgoa2V5LCBsaXN0ZW5lciwgZmxhZ3MpOworfQorCit2b2lkIE5ldHdvcmtUYWJsZTo6QWRkVGFibGVMaXN0ZW5lckV4KFN0cmluZ1JlZiBrZXksIElUYWJsZUxpc3RlbmVyKiBsaXN0ZW5lciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdW5zaWduZWQgaW50IGZsYWdzKSB7CisgIHN0ZDo6bG9ja19ndWFyZDxzdGQ6Om11dGV4PiBsb2NrKG1fbXV0ZXgpOworICBsbHZtOjpTbWFsbFN0cmluZzwxMjg+IHBhdGgobV9wYXRoKTsKKyAgcGF0aCArPSBQQVRIX1NFUEFSQVRPUl9DSEFSOworICBzdGQ6OnNpemVfdCBwcmVmaXhfbGVuID0gcGF0aC5zaXplKCk7CisgIHBhdGggKz0ga2V5OworICB1bnNpZ25lZCBpbnQgaWQgPSBudDo6QWRkRW50cnlMaXN0ZW5lcigKKyAgICAgIHBhdGgsCisgICAgICBbPV0odW5zaWduZWQgaW50IC8qdWlkKi8sIFN0cmluZ1JlZiBuYW1lLCBzdGQ6OnNoYXJlZF9wdHI8bnQ6OlZhbHVlPiB2YWx1ZSwKKyAgICAgICAgICB1bnNpZ25lZCBpbnQgZmxhZ3NfKSB7CisgICAgICAgIGlmIChuYW1lICE9IHBhdGgpIHJldHVybjsKKyAgICAgICAgbGlzdGVuZXItPlZhbHVlQ2hhbmdlZEV4KHRoaXMsIG5hbWUuc3Vic3RyKHByZWZpeF9sZW4pLCB2YWx1ZSwgZmxhZ3NfKTsKKyAgICAgIH0sCisgICAgICBmbGFncyk7CisgIG1fbGlzdGVuZXJzLmVtcGxhY2VfYmFjayhsaXN0ZW5lciwgaWQpOworfQorCit2b2lkIE5ldHdvcmtUYWJsZTo6QWRkU3ViVGFibGVMaXN0ZW5lcihJVGFibGVMaXN0ZW5lciogbGlzdGVuZXIpIHsKKyAgQWRkU3ViVGFibGVMaXN0ZW5lcihsaXN0ZW5lciwgZmFsc2UpOworfQorCit2b2lkIE5ldHdvcmtUYWJsZTo6QWRkU3ViVGFibGVMaXN0ZW5lcihJVGFibGVMaXN0ZW5lciogbGlzdGVuZXIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBib29sIGxvY2FsTm90aWZ5KSB7CisgIHN0ZDo6bG9ja19ndWFyZDxzdGQ6Om11dGV4PiBsb2NrKG1fbXV0ZXgpOworICBsbHZtOjpTbWFsbFN0cmluZzwxMjg+IHBhdGgobV9wYXRoKTsKKyAgcGF0aCArPSBQQVRIX1NFUEFSQVRPUl9DSEFSOworICBzdGQ6OnNpemVfdCBwcmVmaXhfbGVuID0gcGF0aC5zaXplKCk7CisKKyAgLy8gVGhlIGxhbWJkYSBuZWVkcyB0byBiZSBjb3B5YWJsZSwgYnV0IFN0cmluZ01hcCBpcyBub3QsIHNvIHVzZQorICAvLyBhIHNoYXJlZF9wdHIgdG8gaXQuCisgIGF1dG8gbm90aWZpZWRfdGFibGVzID0gc3RkOjptYWtlX3NoYXJlZDxsbHZtOjpTdHJpbmdNYXA8Y2hhcj4+KCk7CisKKyAgdW5zaWduZWQgaW50IGZsYWdzID0gTlRfTk9USUZZX05FVyB8IE5UX05PVElGWV9JTU1FRElBVEU7CisgIGlmIChsb2NhbE5vdGlmeSkgZmxhZ3MgfD0gTlRfTk9USUZZX0xPQ0FMOworICB1bnNpZ25lZCBpbnQgaWQgPSBudDo6QWRkRW50cnlMaXN0ZW5lcigKKyAgICAgIHBhdGgsCisgICAgICBbPV0odW5zaWduZWQgaW50IC8qdWlkKi8sIFN0cmluZ1JlZiBuYW1lLAorICAgICAgICAgIHN0ZDo6c2hhcmVkX3B0cjxudDo6VmFsdWU+IC8qdmFsdWUqLywgdW5zaWduZWQgaW50IGZsYWdzXykgbXV0YWJsZSB7CisgICAgICAgIFN0cmluZ1JlZiByZWxhdGl2ZV9rZXkgPSBuYW1lLnN1YnN0cihwcmVmaXhfbGVuKTsKKyAgICAgICAgYXV0byBlbmRfc3ViX3RhYmxlID0gcmVsYXRpdmVfa2V5LmZpbmQoUEFUSF9TRVBBUkFUT1JfQ0hBUik7CisgICAgICAgIGlmIChlbmRfc3ViX3RhYmxlID09IFN0cmluZ1JlZjo6bnBvcykgcmV0dXJuOworICAgICAgICBTdHJpbmdSZWYgc3ViX3RhYmxlX2tleSA9IHJlbGF0aXZlX2tleS5zdWJzdHIoMCwgZW5kX3N1Yl90YWJsZSk7CisgICAgICAgIGlmIChub3RpZmllZF90YWJsZXMtPmZpbmQoc3ViX3RhYmxlX2tleSkgPT0gbm90aWZpZWRfdGFibGVzLT5lbmQoKSkKKyAgICAgICAgICByZXR1cm47CisgICAgICAgIG5vdGlmaWVkX3RhYmxlcy0+aW5zZXJ0KHN0ZDo6bWFrZV9wYWlyKHN1Yl90YWJsZV9rZXksICdcMCcpKTsKKyAgICAgICAgbGlzdGVuZXItPlZhbHVlQ2hhbmdlZEV4KHRoaXMsIHN1Yl90YWJsZV9rZXksIG51bGxwdHIsIGZsYWdzXyk7CisgICAgICB9LAorICAgICAgZmxhZ3MpOworICBtX2xpc3RlbmVycy5lbXBsYWNlX2JhY2sobGlzdGVuZXIsIGlkKTsKK30KKwordm9pZCBOZXR3b3JrVGFibGU6OlJlbW92ZVRhYmxlTGlzdGVuZXIoSVRhYmxlTGlzdGVuZXIqIGxpc3RlbmVyKSB7CisgIHN0ZDo6bG9ja19ndWFyZDxzdGQ6Om11dGV4PiBsb2NrKG1fbXV0ZXgpOworICBhdXRvIG1hdGNoZXNfYmVnaW4gPQorICAgICAgc3RkOjpyZW1vdmVfaWYobV9saXN0ZW5lcnMuYmVnaW4oKSwgbV9saXN0ZW5lcnMuZW5kKCksCisgICAgICAgICAgICAgICAgICAgICBbPV0oY29uc3QgTGlzdGVuZXImIHgpIHsgcmV0dXJuIHguZmlyc3QgPT0gbGlzdGVuZXI7IH0pOworCisgIGZvciAoYXV0byBpID0gbWF0Y2hlc19iZWdpbjsgaSAhPSBtX2xpc3RlbmVycy5lbmQoKTsgKytpKQorICAgIG50OjpSZW1vdmVFbnRyeUxpc3RlbmVyKGktPnNlY29uZCk7CisgIG1fbGlzdGVuZXJzLmVyYXNlKG1hdGNoZXNfYmVnaW4sIG1fbGlzdGVuZXJzLmVuZCgpKTsKK30KKworc3RkOjpzaGFyZWRfcHRyPElUYWJsZT4gTmV0d29ya1RhYmxlOjpHZXRTdWJUYWJsZShTdHJpbmdSZWYga2V5KSBjb25zdCB7CisgIGxsdm06OlNtYWxsU3RyaW5nPDEyOD4gcGF0aChtX3BhdGgpOworICBwYXRoICs9IFBBVEhfU0VQQVJBVE9SX0NIQVI7CisgIHBhdGggKz0ga2V5OworICByZXR1cm4gc3RkOjptYWtlX3NoYXJlZDxOZXR3b3JrVGFibGU+KHBhdGgsIHByaXZhdGVfaW5pdCgpKTsKK30KKworYm9vbCBOZXR3b3JrVGFibGU6OkNvbnRhaW5zS2V5KFN0cmluZ1JlZiBrZXkpIGNvbnN0IHsKKyAgbGx2bTo6U21hbGxTdHJpbmc8MTI4PiBwYXRoKG1fcGF0aCk7CisgIHBhdGggKz0gUEFUSF9TRVBBUkFUT1JfQ0hBUjsKKyAgcGF0aCArPSBrZXk7CisgIHJldHVybiBudDo6R2V0RW50cnlWYWx1ZShwYXRoKSAhPSBudWxscHRyOworfQorCitib29sIE5ldHdvcmtUYWJsZTo6Q29udGFpbnNTdWJUYWJsZShTdHJpbmdSZWYga2V5KSBjb25zdCB7CisgIGxsdm06OlNtYWxsU3RyaW5nPDEyOD4gcGF0aChtX3BhdGgpOworICBwYXRoICs9IFBBVEhfU0VQQVJBVE9SX0NIQVI7CisgIHBhdGggKz0ga2V5OworICBwYXRoICs9IFBBVEhfU0VQQVJBVE9SX0NIQVI7CisgIHJldHVybiAhbnQ6OkdldEVudHJ5SW5mbyhwYXRoLCAwKS5lbXB0eSgpOworfQorCitzdGQ6OnZlY3RvcjxzdGQ6OnN0cmluZz4gTmV0d29ya1RhYmxlOjpHZXRLZXlzKGludCB0eXBlcykgY29uc3QgeworICBzdGQ6OnZlY3RvcjxzdGQ6OnN0cmluZz4ga2V5czsKKyAgbGx2bTo6U21hbGxTdHJpbmc8MTI4PiBwYXRoKG1fcGF0aCk7CisgIHBhdGggKz0gUEFUSF9TRVBBUkFUT1JfQ0hBUjsKKyAgZm9yIChhdXRvJiBlbnRyeSA6IG50OjpHZXRFbnRyeUluZm8ocGF0aCwgdHlwZXMpKSB7CisgICAgYXV0byByZWxhdGl2ZV9rZXkgPSBTdHJpbmdSZWYoZW50cnkubmFtZSkuc3Vic3RyKHBhdGguc2l6ZSgpKTsKKyAgICBpZiAocmVsYXRpdmVfa2V5LmZpbmQoUEFUSF9TRVBBUkFUT1JfQ0hBUikgIT0gU3RyaW5nUmVmOjpucG9zKQorICAgICAgY29udGludWU7CisgICAga2V5cy5wdXNoX2JhY2socmVsYXRpdmVfa2V5KTsKKyAgfQorICByZXR1cm4ga2V5czsKK30KKworc3RkOjp2ZWN0b3I8c3RkOjpzdHJpbmc+IE5ldHdvcmtUYWJsZTo6R2V0U3ViVGFibGVzKCkgY29uc3QgeworICBzdGQ6OnZlY3RvcjxzdGQ6OnN0cmluZz4ga2V5czsKKyAgbGx2bTo6U21hbGxTdHJpbmc8MTI4PiBwYXRoKG1fcGF0aCk7CisgIHBhdGggKz0gUEFUSF9TRVBBUkFUT1JfQ0hBUjsKKyAgZm9yIChhdXRvJiBlbnRyeSA6IG50OjpHZXRFbnRyeUluZm8ocGF0aCwgMCkpIHsKKyAgICBhdXRvIHJlbGF0aXZlX2tleSA9IFN0cmluZ1JlZihlbnRyeS5uYW1lKS5zdWJzdHIocGF0aC5zaXplKCkpOworICAgIHN0ZDo6c2l6ZV90IGVuZF9zdWJ0YWJsZSA9IHJlbGF0aXZlX2tleS5maW5kKFBBVEhfU0VQQVJBVE9SX0NIQVIpOworICAgIGlmIChlbmRfc3VidGFibGUgPT0gU3RyaW5nUmVmOjpucG9zKSBjb250aW51ZTsKKyAgICBrZXlzLnB1c2hfYmFjayhyZWxhdGl2ZV9rZXkuc3Vic3RyKDAsIGVuZF9zdWJ0YWJsZSkpOworICB9CisgIHJldHVybiBrZXlzOworfQorCit2b2lkIE5ldHdvcmtUYWJsZTo6U2V0UGVyc2lzdGVudChTdHJpbmdSZWYga2V5KSB7CisgIFNldEZsYWdzKGtleSwgTlRfUEVSU0lTVEVOVCk7Cit9CisKK3ZvaWQgTmV0d29ya1RhYmxlOjpDbGVhclBlcnNpc3RlbnQoU3RyaW5nUmVmIGtleSkgeworICBDbGVhckZsYWdzKGtleSwgTlRfUEVSU0lTVEVOVCk7Cit9CisKK2Jvb2wgTmV0d29ya1RhYmxlOjpJc1BlcnNpc3RlbnQoU3RyaW5nUmVmIGtleSkgY29uc3QgeworICByZXR1cm4gKEdldEZsYWdzKGtleSkgJiBOVF9QRVJTSVNURU5UKSAhPSAwOworfQorCit2b2lkIE5ldHdvcmtUYWJsZTo6U2V0RmxhZ3MoU3RyaW5nUmVmIGtleSwgdW5zaWduZWQgaW50IGZsYWdzKSB7CisgIGxsdm06OlNtYWxsU3RyaW5nPDEyOD4gcGF0aChtX3BhdGgpOworICBwYXRoICs9IFBBVEhfU0VQQVJBVE9SX0NIQVI7CisgIHBhdGggKz0ga2V5OworICBudDo6U2V0RW50cnlGbGFncyhwYXRoLCBudDo6R2V0RW50cnlGbGFncyhrZXkpIHwgZmxhZ3MpOworfQorCit2b2lkIE5ldHdvcmtUYWJsZTo6Q2xlYXJGbGFncyhTdHJpbmdSZWYga2V5LCB1bnNpZ25lZCBpbnQgZmxhZ3MpIHsKKyAgbGx2bTo6U21hbGxTdHJpbmc8MTI4PiBwYXRoKG1fcGF0aCk7CisgIHBhdGggKz0gUEFUSF9TRVBBUkFUT1JfQ0hBUjsKKyAgcGF0aCArPSBrZXk7CisgIG50OjpTZXRFbnRyeUZsYWdzKHBhdGgsIG50OjpHZXRFbnRyeUZsYWdzKHBhdGgpICYgfmZsYWdzKTsKK30KKwordW5zaWduZWQgaW50IE5ldHdvcmtUYWJsZTo6R2V0RmxhZ3MoU3RyaW5nUmVmIGtleSkgY29uc3QgeworICBsbHZtOjpTbWFsbFN0cmluZzwxMjg+IHBhdGgobV9wYXRoKTsKKyAgcGF0aCArPSBQQVRIX1NFUEFSQVRPUl9DSEFSOworICBwYXRoICs9IGtleTsKKyAgcmV0dXJuIG50OjpHZXRFbnRyeUZsYWdzKHBhdGgpOworfQorCit2b2lkIE5ldHdvcmtUYWJsZTo6RGVsZXRlKFN0cmluZ1JlZiBrZXkpIHsKKyAgbGx2bTo6U21hbGxTdHJpbmc8MTI4PiBwYXRoKG1fcGF0aCk7CisgIHBhdGggKz0gUEFUSF9TRVBBUkFUT1JfQ0hBUjsKKyAgcGF0aCArPSBrZXk7CisgIG50OjpEZWxldGVFbnRyeShwYXRoKTsKK30KKworYm9vbCBOZXR3b3JrVGFibGU6OlB1dE51bWJlcihTdHJpbmdSZWYga2V5LCBkb3VibGUgdmFsdWUpIHsKKyAgbGx2bTo6U21hbGxTdHJpbmc8MTI4PiBwYXRoKG1fcGF0aCk7CisgIHBhdGggKz0gUEFUSF9TRVBBUkFUT1JfQ0hBUjsKKyAgcGF0aCArPSBrZXk7CisgIHJldHVybiBudDo6U2V0RW50cnlWYWx1ZShwYXRoLCBudDo6VmFsdWU6Ok1ha2VEb3VibGUodmFsdWUpKTsKK30KKworZG91YmxlIE5ldHdvcmtUYWJsZTo6R2V0TnVtYmVyKFN0cmluZ1JlZiBrZXkpIGNvbnN0IHsKKyAgbGx2bTo6U21hbGxTdHJpbmc8MTI4PiBwYXRoKG1fcGF0aCk7CisgIHBhdGggKz0gUEFUSF9TRVBBUkFUT1JfQ0hBUjsKKyAgcGF0aCArPSBrZXk7CisgIGF1dG8gdmFsdWUgPSBudDo6R2V0RW50cnlWYWx1ZShwYXRoKTsKKyAgaWYgKCF2YWx1ZSB8fCB2YWx1ZS0+dHlwZSgpICE9IE5UX0RPVUJMRSkKKyAgICB0aHJvdyBUYWJsZUtleU5vdERlZmluZWRFeGNlcHRpb24ocGF0aCk7CisgIHJldHVybiB2YWx1ZS0+R2V0RG91YmxlKCk7Cit9CisKK2RvdWJsZSBOZXR3b3JrVGFibGU6OkdldE51bWJlcihTdHJpbmdSZWYga2V5LCBkb3VibGUgZGVmYXVsdFZhbHVlKSBjb25zdCB7CisgIGxsdm06OlNtYWxsU3RyaW5nPDEyOD4gcGF0aChtX3BhdGgpOworICBwYXRoICs9IFBBVEhfU0VQQVJBVE9SX0NIQVI7CisgIHBhdGggKz0ga2V5OworICBhdXRvIHZhbHVlID0gbnQ6OkdldEVudHJ5VmFsdWUocGF0aCk7CisgIGlmICghdmFsdWUgfHwgdmFsdWUtPnR5cGUoKSAhPSBOVF9ET1VCTEUpCisgICAgcmV0dXJuIGRlZmF1bHRWYWx1ZTsKKyAgcmV0dXJuIHZhbHVlLT5HZXREb3VibGUoKTsKK30KKworYm9vbCBOZXR3b3JrVGFibGU6OlB1dFN0cmluZyhTdHJpbmdSZWYga2V5LCBTdHJpbmdSZWYgdmFsdWUpIHsKKyAgbGx2bTo6U21hbGxTdHJpbmc8MTI4PiBwYXRoKG1fcGF0aCk7CisgIHBhdGggKz0gUEFUSF9TRVBBUkFUT1JfQ0hBUjsKKyAgcGF0aCArPSBrZXk7CisgIHJldHVybiBudDo6U2V0RW50cnlWYWx1ZShwYXRoLCBudDo6VmFsdWU6Ok1ha2VTdHJpbmcodmFsdWUpKTsKK30KKworc3RkOjpzdHJpbmcgTmV0d29ya1RhYmxlOjpHZXRTdHJpbmcoU3RyaW5nUmVmIGtleSkgY29uc3QgeworICBsbHZtOjpTbWFsbFN0cmluZzwxMjg+IHBhdGgobV9wYXRoKTsKKyAgcGF0aCArPSBQQVRIX1NFUEFSQVRPUl9DSEFSOworICBwYXRoICs9IGtleTsKKyAgYXV0byB2YWx1ZSA9IG50OjpHZXRFbnRyeVZhbHVlKHBhdGgpOworICBpZiAoIXZhbHVlIHx8IHZhbHVlLT50eXBlKCkgIT0gTlRfU1RSSU5HKQorICAgIHRocm93IFRhYmxlS2V5Tm90RGVmaW5lZEV4Y2VwdGlvbihwYXRoKTsKKyAgcmV0dXJuIHZhbHVlLT5HZXRTdHJpbmcoKTsKK30KKworc3RkOjpzdHJpbmcgTmV0d29ya1RhYmxlOjpHZXRTdHJpbmcoU3RyaW5nUmVmIGtleSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFN0cmluZ1JlZiBkZWZhdWx0VmFsdWUpIGNvbnN0IHsKKyAgbGx2bTo6U21hbGxTdHJpbmc8MTI4PiBwYXRoKG1fcGF0aCk7CisgIHBhdGggKz0gUEFUSF9TRVBBUkFUT1JfQ0hBUjsKKyAgcGF0aCArPSBrZXk7CisgIGF1dG8gdmFsdWUgPSBudDo6R2V0RW50cnlWYWx1ZShwYXRoKTsKKyAgaWYgKCF2YWx1ZSB8fCB2YWx1ZS0+dHlwZSgpICE9IE5UX1NUUklORykKKyAgICByZXR1cm4gZGVmYXVsdFZhbHVlOworICByZXR1cm4gdmFsdWUtPkdldFN0cmluZygpOworfQorCitib29sIE5ldHdvcmtUYWJsZTo6UHV0Qm9vbGVhbihTdHJpbmdSZWYga2V5LCBib29sIHZhbHVlKSB7CisgIGxsdm06OlNtYWxsU3RyaW5nPDEyOD4gcGF0aChtX3BhdGgpOworICBwYXRoICs9IFBBVEhfU0VQQVJBVE9SX0NIQVI7CisgIHBhdGggKz0ga2V5OworICByZXR1cm4gbnQ6OlNldEVudHJ5VmFsdWUocGF0aCwgbnQ6OlZhbHVlOjpNYWtlQm9vbGVhbih2YWx1ZSkpOworfQorCitib29sIE5ldHdvcmtUYWJsZTo6R2V0Qm9vbGVhbihTdHJpbmdSZWYga2V5KSBjb25zdCB7CisgIGxsdm06OlNtYWxsU3RyaW5nPDEyOD4gcGF0aChtX3BhdGgpOworICBwYXRoICs9IFBBVEhfU0VQQVJBVE9SX0NIQVI7CisgIHBhdGggKz0ga2V5OworICBhdXRvIHZhbHVlID0gbnQ6OkdldEVudHJ5VmFsdWUocGF0aCk7CisgIGlmICghdmFsdWUgfHwgdmFsdWUtPnR5cGUoKSAhPSBOVF9CT09MRUFOKQorICAgIHRocm93IFRhYmxlS2V5Tm90RGVmaW5lZEV4Y2VwdGlvbihwYXRoKTsKKyAgcmV0dXJuIHZhbHVlLT5HZXRCb29sZWFuKCk7Cit9CisKK2Jvb2wgTmV0d29ya1RhYmxlOjpHZXRCb29sZWFuKFN0cmluZ1JlZiBrZXksIGJvb2wgZGVmYXVsdFZhbHVlKSBjb25zdCB7CisgIGxsdm06OlNtYWxsU3RyaW5nPDEyOD4gcGF0aChtX3BhdGgpOworICBwYXRoICs9IFBBVEhfU0VQQVJBVE9SX0NIQVI7CisgIHBhdGggKz0ga2V5OworICBhdXRvIHZhbHVlID0gbnQ6OkdldEVudHJ5VmFsdWUocGF0aCk7CisgIGlmICghdmFsdWUgfHwgdmFsdWUtPnR5cGUoKSAhPSBOVF9CT09MRUFOKQorICAgIHJldHVybiBkZWZhdWx0VmFsdWU7CisgIHJldHVybiB2YWx1ZS0+R2V0Qm9vbGVhbigpOworfQorCitib29sIE5ldHdvcmtUYWJsZTo6UHV0VmFsdWUoU3RyaW5nUmVmIGtleSwgc3RkOjpzaGFyZWRfcHRyPG50OjpWYWx1ZT4gdmFsdWUpIHsKKyAgbGx2bTo6U21hbGxTdHJpbmc8MTI4PiBwYXRoKG1fcGF0aCk7CisgIHBhdGggKz0gUEFUSF9TRVBBUkFUT1JfQ0hBUjsKKyAgcGF0aCArPSBrZXk7CisgIHJldHVybiBudDo6U2V0RW50cnlWYWx1ZShwYXRoLCB2YWx1ZSk7Cit9CisKK3N0ZDo6c2hhcmVkX3B0cjxudDo6VmFsdWU+IE5ldHdvcmtUYWJsZTo6R2V0VmFsdWUoU3RyaW5nUmVmIGtleSkgY29uc3QgeworICBsbHZtOjpTbWFsbFN0cmluZzwxMjg+IHBhdGgobV9wYXRoKTsKKyAgcGF0aCArPSBQQVRIX1NFUEFSQVRPUl9DSEFSOworICBwYXRoICs9IGtleTsKKyAgcmV0dXJuIG50OjpHZXRFbnRyeVZhbHVlKHBhdGgpOworfQpkaWZmIC0tZ2l0IGEvc3JjL250Y29yZV9jLmNwcCBiL3NyYy9udGNvcmVfYy5jcHAKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZDdmNTQ1NgotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9udGNvcmVfYy5jcHAKQEAgLTAsMCArMSw3NzAgQEAKKy8qLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovCisvKiBDb3B5cmlnaHQgKGMpIEZJUlNUIDIwMTUuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqLworLyogT3BlbiBTb3VyY2UgU29mdHdhcmUgLSBtYXkgYmUgbW9kaWZpZWQgYW5kIHNoYXJlZCBieSBGUkMgdGVhbXMuIFRoZSBjb2RlICAgKi8KKy8qIG11c3QgYmUgYWNjb21wYW5pZWQgYnkgdGhlIEZJUlNUIEJTRCBsaWNlbnNlIGZpbGUgaW4gdGhlIHJvb3QgZGlyZWN0b3J5IG9mICovCisvKiB0aGUgcHJvamVjdC4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqLworLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi8KKworI2luY2x1ZGUgIm50Y29yZS5oIgorCisjaW5jbHVkZSA8Y2Fzc2VydD4KKyNpbmNsdWRlIDxjc3RkbGliPgorCisjaW5jbHVkZSAiVmFsdWVfaW50ZXJuYWwuaCIKKwordXNpbmcgbmFtZXNwYWNlIG50OworCisvLyBDb252ZXJzaW9uIGhlbHBlcnMKKworc3RhdGljIHZvaWQgQ29udmVydFRvQyhsbHZtOjpTdHJpbmdSZWYgaW4sIGNoYXIqKiBvdXQpIHsKKyAgKm91dCA9IHN0YXRpY19jYXN0PGNoYXIqPihzdGQ6Om1hbGxvYyhpbi5zaXplKCkgKyAxKSk7CisgIHN0ZDo6bWVtbW92ZSgqb3V0LCBpbi5kYXRhKCksIGluLnNpemUoKSk7CisgICgqb3V0KVtpbi5zaXplKCldID0gJ1wwJzsKK30KKworc3RhdGljIHZvaWQgQ29udmVydFRvQyhjb25zdCBFbnRyeUluZm8mIGluLCBOVF9FbnRyeUluZm8qIG91dCkgeworICBDb252ZXJ0VG9DKGluLm5hbWUsICZvdXQtPm5hbWUpOworICBvdXQtPnR5cGUgPSBpbi50eXBlOworICBvdXQtPmZsYWdzID0gaW4uZmxhZ3M7CisgIG91dC0+bGFzdF9jaGFuZ2UgPSBpbi5sYXN0X2NoYW5nZTsKK30KKworc3RhdGljIHZvaWQgQ29udmVydFRvQyhjb25zdCBDb25uZWN0aW9uSW5mbyYgaW4sIE5UX0Nvbm5lY3Rpb25JbmZvKiBvdXQpIHsKKyAgQ29udmVydFRvQyhpbi5yZW1vdGVfaWQsICZvdXQtPnJlbW90ZV9pZCk7CisgIENvbnZlcnRUb0MoaW4ucmVtb3RlX25hbWUsICZvdXQtPnJlbW90ZV9uYW1lKTsKKyAgb3V0LT5yZW1vdGVfcG9ydCA9IGluLnJlbW90ZV9wb3J0OworICBvdXQtPmxhc3RfdXBkYXRlID0gaW4ubGFzdF91cGRhdGU7CisgIG91dC0+cHJvdG9jb2xfdmVyc2lvbiA9IGluLnByb3RvY29sX3ZlcnNpb247Cit9CisKK3N0YXRpYyB2b2lkIENvbnZlcnRUb0MoY29uc3QgUnBjUGFyYW1EZWYmIGluLCBOVF9ScGNQYXJhbURlZiogb3V0KSB7CisgIENvbnZlcnRUb0MoaW4ubmFtZSwgJm91dC0+bmFtZSk7CisgIENvbnZlcnRUb0MoKmluLmRlZl92YWx1ZSwgJm91dC0+ZGVmX3ZhbHVlKTsKK30KKworc3RhdGljIHZvaWQgQ29udmVydFRvQyhjb25zdCBScGNSZXN1bHREZWYmIGluLCBOVF9ScGNSZXN1bHREZWYqIG91dCkgeworICBDb252ZXJ0VG9DKGluLm5hbWUsICZvdXQtPm5hbWUpOworICBvdXQtPnR5cGUgPSBpbi50eXBlOworfQorCitzdGF0aWMgdm9pZCBDb252ZXJ0VG9DKGNvbnN0IFJwY0RlZmluaXRpb24mIGluLCBOVF9ScGNEZWZpbml0aW9uKiBvdXQpIHsKKyAgb3V0LT52ZXJzaW9uID0gaW4udmVyc2lvbjsKKyAgQ29udmVydFRvQyhpbi5uYW1lLCAmb3V0LT5uYW1lKTsKKworICBvdXQtPm51bV9wYXJhbXMgPSBpbi5wYXJhbXMuc2l6ZSgpOworICBvdXQtPnBhcmFtcyA9IHN0YXRpY19jYXN0PE5UX1JwY1BhcmFtRGVmKj4oCisgICAgICBzdGQ6Om1hbGxvYyhpbi5wYXJhbXMuc2l6ZSgpICogc2l6ZW9mKE5UX1JwY1BhcmFtRGVmKSkpOworICBmb3IgKHNpemVfdCBpID0gMDsgaSA8IGluLnBhcmFtcy5zaXplKCk7ICsraSkKKyAgICBDb252ZXJ0VG9DKGluLnBhcmFtc1tpXSwgJm91dC0+cGFyYW1zW2ldKTsKKworICBvdXQtPm51bV9yZXN1bHRzID0gaW4ucmVzdWx0cy5zaXplKCk7CisgIG91dC0+cmVzdWx0cyA9IHN0YXRpY19jYXN0PE5UX1JwY1Jlc3VsdERlZio+KAorICAgICAgc3RkOjptYWxsb2MoaW4ucmVzdWx0cy5zaXplKCkgKiBzaXplb2YoTlRfUnBjUmVzdWx0RGVmKSkpOworICBmb3IgKHNpemVfdCBpID0gMDsgaSA8IGluLnJlc3VsdHMuc2l6ZSgpOyArK2kpCisgICAgQ29udmVydFRvQyhpbi5yZXN1bHRzW2ldLCAmb3V0LT5yZXN1bHRzW2ldKTsKK30KKworc3RhdGljIHZvaWQgQ29udmVydFRvQyhjb25zdCBScGNDYWxsSW5mbyYgaW4sIE5UX1JwY0NhbGxJbmZvKiBvdXQpIHsKKyAgb3V0LT5ycGNfaWQgPSBpbi5ycGNfaWQ7CisgIG91dC0+Y2FsbF91aWQgPSBpbi5jYWxsX3VpZDsKKyAgQ29udmVydFRvQyhpbi5uYW1lLCAmb3V0LT5uYW1lKTsKKyAgQ29udmVydFRvQyhpbi5wYXJhbXMsICZvdXQtPnBhcmFtcyk7Cit9CisKK3N0YXRpYyB2b2lkIERpc3Bvc2VDb25uZWN0aW9uSW5mbyhOVF9Db25uZWN0aW9uSW5mbyAqaW5mbykgeworICBzdGQ6OmZyZWUoaW5mby0+cmVtb3RlX2lkLnN0cik7CisgIHN0ZDo6ZnJlZShpbmZvLT5yZW1vdGVfbmFtZSk7Cit9CisKK3N0YXRpYyB2b2lkIERpc3Bvc2VFbnRyeUluZm8oTlRfRW50cnlJbmZvICppbmZvKSB7CisgIHN0ZDo6ZnJlZShpbmZvLT5uYW1lLnN0cik7Cit9CisKK3N0YXRpYyBScGNQYXJhbURlZiBDb252ZXJ0RnJvbUMoY29uc3QgTlRfUnBjUGFyYW1EZWYmIGluKSB7CisgIFJwY1BhcmFtRGVmIG91dDsKKyAgb3V0Lm5hbWUgPSBDb252ZXJ0RnJvbUMoaW4ubmFtZSk7CisgIG91dC5kZWZfdmFsdWUgPSBDb252ZXJ0RnJvbUMoaW4uZGVmX3ZhbHVlKTsKKyAgcmV0dXJuIG91dDsKK30KKworc3RhdGljIFJwY1Jlc3VsdERlZiBDb252ZXJ0RnJvbUMoY29uc3QgTlRfUnBjUmVzdWx0RGVmJiBpbikgeworICBScGNSZXN1bHREZWYgb3V0OworICBvdXQubmFtZSA9IENvbnZlcnRGcm9tQyhpbi5uYW1lKTsKKyAgb3V0LnR5cGUgPSBpbi50eXBlOworICByZXR1cm4gb3V0OworfQorCitzdGF0aWMgUnBjRGVmaW5pdGlvbiBDb252ZXJ0RnJvbUMoY29uc3QgTlRfUnBjRGVmaW5pdGlvbiYgaW4pIHsKKyAgUnBjRGVmaW5pdGlvbiBvdXQ7CisgIG91dC52ZXJzaW9uID0gaW4udmVyc2lvbjsKKyAgb3V0Lm5hbWUgPSBDb252ZXJ0RnJvbUMoaW4ubmFtZSk7CisKKyAgb3V0LnBhcmFtcy5yZXNlcnZlKGluLm51bV9wYXJhbXMpOworICBmb3IgKHNpemVfdCBpID0gMDsgaSA8IGluLm51bV9wYXJhbXM7ICsraSkKKyAgICBvdXQucGFyYW1zLnB1c2hfYmFjayhDb252ZXJ0RnJvbUMoaW4ucGFyYW1zW2ldKSk7CisKKyAgb3V0LnJlc3VsdHMucmVzZXJ2ZShpbi5udW1fcmVzdWx0cyk7CisgIGZvciAoc2l6ZV90IGkgPSAwOyBpIDwgaW4ubnVtX3Jlc3VsdHM7ICsraSkKKyAgICBvdXQucmVzdWx0cy5wdXNoX2JhY2soQ29udmVydEZyb21DKGluLnJlc3VsdHNbaV0pKTsKKworICByZXR1cm4gb3V0OworfQorCitleHRlcm4gIkMiIHsKKworLyoKKyAqIFRhYmxlIEZ1bmN0aW9ucworICovCisKK3ZvaWQgTlRfR2V0RW50cnlWYWx1ZShjb25zdCBjaGFyICpuYW1lLCBzaXplX3QgbmFtZV9sZW4sCisgICAgICAgICAgICAgICAgICAgICAgc3RydWN0IE5UX1ZhbHVlICp2YWx1ZSkgeworICBOVF9Jbml0VmFsdWUodmFsdWUpOworICBhdXRvIHYgPSBudDo6R2V0RW50cnlWYWx1ZShTdHJpbmdSZWYobmFtZSwgbmFtZV9sZW4pKTsKKyAgaWYgKCF2KSByZXR1cm47CisgIENvbnZlcnRUb0MoKnYsIHZhbHVlKTsKK30KKworaW50IE5UX1NldEVudHJ5VmFsdWUoY29uc3QgY2hhciAqbmFtZSwgc2l6ZV90IG5hbWVfbGVuLAorICAgICAgICAgICAgICAgICAgICAgY29uc3Qgc3RydWN0IE5UX1ZhbHVlICp2YWx1ZSkgeworICByZXR1cm4gbnQ6OlNldEVudHJ5VmFsdWUoU3RyaW5nUmVmKG5hbWUsIG5hbWVfbGVuKSwgQ29udmVydEZyb21DKCp2YWx1ZSkpOworfQorCit2b2lkIE5UX1NldEVudHJ5VHlwZVZhbHVlKGNvbnN0IGNoYXIgKm5hbWUsIHNpemVfdCBuYW1lX2xlbiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3Qgc3RydWN0IE5UX1ZhbHVlICp2YWx1ZSkgeworICBudDo6U2V0RW50cnlUeXBlVmFsdWUoU3RyaW5nUmVmKG5hbWUsIG5hbWVfbGVuKSwgQ29udmVydEZyb21DKCp2YWx1ZSkpOworfQorCit2b2lkIE5UX1NldEVudHJ5RmxhZ3MoY29uc3QgY2hhciAqbmFtZSwgc2l6ZV90IG5hbWVfbGVuLCB1bnNpZ25lZCBpbnQgZmxhZ3MpIHsKKyAgbnQ6OlNldEVudHJ5RmxhZ3MoU3RyaW5nUmVmKG5hbWUsIG5hbWVfbGVuKSwgZmxhZ3MpOworfQorCit1bnNpZ25lZCBpbnQgTlRfR2V0RW50cnlGbGFncyhjb25zdCBjaGFyICpuYW1lLCBzaXplX3QgbmFtZV9sZW4pIHsKKyAgcmV0dXJuIG50OjpHZXRFbnRyeUZsYWdzKFN0cmluZ1JlZihuYW1lLCBuYW1lX2xlbikpOworfQorCit2b2lkIE5UX0RlbGV0ZUVudHJ5KGNvbnN0IGNoYXIgKm5hbWUsIHNpemVfdCBuYW1lX2xlbikgeworICBudDo6RGVsZXRlRW50cnkoU3RyaW5nUmVmKG5hbWUsIG5hbWVfbGVuKSk7Cit9CisKK3ZvaWQgTlRfRGVsZXRlQWxsRW50cmllcyh2b2lkKSB7IG50OjpEZWxldGVBbGxFbnRyaWVzKCk7IH0KKworc3RydWN0IE5UX0VudHJ5SW5mbyAqTlRfR2V0RW50cnlJbmZvKGNvbnN0IGNoYXIgKnByZWZpeCwgc2l6ZV90IHByZWZpeF9sZW4sCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdW5zaWduZWQgaW50IHR5cGVzLCBzaXplX3QgKmNvdW50KSB7CisgIGF1dG8gaW5mb192ID0gbnQ6OkdldEVudHJ5SW5mbyhTdHJpbmdSZWYocHJlZml4LCBwcmVmaXhfbGVuKSwgdHlwZXMpOworICAqY291bnQgPSBpbmZvX3Yuc2l6ZSgpOworICBpZiAoaW5mb192LnNpemUoKSA9PSAwKSByZXR1cm4gbnVsbHB0cjsKKworICAvLyBjcmVhdGUgYXJyYXkgYW5kIGNvcHkgaW50byBpdAorICBOVF9FbnRyeUluZm8qIGluZm8gPSBzdGF0aWNfY2FzdDxOVF9FbnRyeUluZm8qPigKKyAgICAgIHN0ZDo6bWFsbG9jKGluZm9fdi5zaXplKCkgKiBzaXplb2YoTlRfRW50cnlJbmZvKSkpOworICBmb3IgKHNpemVfdCBpID0gMDsgaSA8IGluZm9fdi5zaXplKCk7ICsraSkgQ29udmVydFRvQyhpbmZvX3ZbaV0sICZpbmZvW2ldKTsKKyAgcmV0dXJuIGluZm87Cit9CisKK3ZvaWQgTlRfRmx1c2godm9pZCkgeyBudDo6Rmx1c2goKTsgfQorCisvKgorICogQ2FsbGJhY2sgQ3JlYXRpb24gRnVuY3Rpb25zCisgKi8KKwordm9pZCBOVF9TZXRMaXN0ZW5lck9uU3RhcnQodm9pZCAoKm9uX3N0YXJ0KSh2b2lkICpkYXRhKSwgdm9pZCAqZGF0YSkgeworICBudDo6U2V0TGlzdGVuZXJPblN0YXJ0KFs9XSgpIHsgb25fc3RhcnQoZGF0YSk7IH0pOworfQorCit2b2lkIE5UX1NldExpc3RlbmVyT25FeGl0KHZvaWQgKCpvbl9leGl0KSh2b2lkICpkYXRhKSwgdm9pZCAqZGF0YSkgeworICBudDo6U2V0TGlzdGVuZXJPbkV4aXQoWz1dKCkgeyBvbl9leGl0KGRhdGEpOyB9KTsKK30KKwordW5zaWduZWQgaW50IE5UX0FkZEVudHJ5TGlzdGVuZXIoY29uc3QgY2hhciAqcHJlZml4LCBzaXplX3QgcHJlZml4X2xlbiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZvaWQgKmRhdGEsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBOVF9FbnRyeUxpc3RlbmVyQ2FsbGJhY2sgY2FsbGJhY2ssCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB1bnNpZ25lZCBpbnQgZmxhZ3MpIHsKKyAgcmV0dXJuIG50OjpBZGRFbnRyeUxpc3RlbmVyKAorICAgICAgU3RyaW5nUmVmKHByZWZpeCwgcHJlZml4X2xlbiksCisgICAgICBbPV0odW5zaWduZWQgaW50IHVpZCwgU3RyaW5nUmVmIG5hbWUsIHN0ZDo6c2hhcmVkX3B0cjxWYWx1ZT4gdmFsdWUsCisgICAgICAgICAgdW5zaWduZWQgaW50IGZsYWdzXykgeworICAgICAgICBjYWxsYmFjayh1aWQsIGRhdGEsIG5hbWUuZGF0YSgpLCBuYW1lLnNpemUoKSwgJnZhbHVlLT52YWx1ZSgpLCBmbGFnc18pOworICAgICAgfSwKKyAgICAgIGZsYWdzKTsKK30KKwordm9pZCBOVF9SZW1vdmVFbnRyeUxpc3RlbmVyKHVuc2lnbmVkIGludCBlbnRyeV9saXN0ZW5lcl91aWQpIHsKKyAgbnQ6OlJlbW92ZUVudHJ5TGlzdGVuZXIoZW50cnlfbGlzdGVuZXJfdWlkKTsKK30KKwordW5zaWduZWQgaW50IE5UX0FkZENvbm5lY3Rpb25MaXN0ZW5lcih2b2lkICpkYXRhLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBOVF9Db25uZWN0aW9uTGlzdGVuZXJDYWxsYmFjayBjYWxsYmFjaywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50IGltbWVkaWF0ZV9ub3RpZnkpIHsKKyAgcmV0dXJuIG50OjpBZGRDb25uZWN0aW9uTGlzdGVuZXIoCisgICAgICBbPV0odW5zaWduZWQgaW50IHVpZCwgYm9vbCBjb25uZWN0ZWQsIGNvbnN0IENvbm5lY3Rpb25JbmZvICZjb25uKSB7CisgICAgICAgIE5UX0Nvbm5lY3Rpb25JbmZvIGNvbm5fYzsKKyAgICAgICAgQ29udmVydFRvQyhjb25uLCAmY29ubl9jKTsKKyAgICAgICAgY2FsbGJhY2sodWlkLCBkYXRhLCBjb25uZWN0ZWQgPyAxIDogMCwgJmNvbm5fYyk7CisgICAgICAgIERpc3Bvc2VDb25uZWN0aW9uSW5mbygmY29ubl9jKTsKKyAgICAgIH0sCisgICAgICBpbW1lZGlhdGVfbm90aWZ5ICE9IDApOworfQorCit2b2lkIE5UX1JlbW92ZUNvbm5lY3Rpb25MaXN0ZW5lcih1bnNpZ25lZCBpbnQgY29ubl9saXN0ZW5lcl91aWQpIHsKKyAgbnQ6OlJlbW92ZUNvbm5lY3Rpb25MaXN0ZW5lcihjb25uX2xpc3RlbmVyX3VpZCk7Cit9CisKK2ludCBOVF9Ob3RpZmllckRlc3Ryb3llZCgpIHsgcmV0dXJuIG50OjpOb3RpZmllckRlc3Ryb3llZCgpOyB9CisKKy8qCisgKiBSZW1vdGUgUHJvY2VkdXJlIENhbGwgRnVuY3Rpb25zCisgKi8KKwordm9pZCBOVF9DcmVhdGVScGMoY29uc3QgY2hhciAqbmFtZSwgc2l6ZV90IG5hbWVfbGVuLCBjb25zdCBjaGFyICpkZWYsCisgICAgICAgICAgICAgICAgICBzaXplX3QgZGVmX2xlbiwgdm9pZCAqZGF0YSwgTlRfUnBjQ2FsbGJhY2sgY2FsbGJhY2spIHsKKyAgbnQ6OkNyZWF0ZVJwYygKKyAgICAgIFN0cmluZ1JlZihuYW1lLCBuYW1lX2xlbiksIFN0cmluZ1JlZihkZWYsIGRlZl9sZW4pLAorICAgICAgWz1dKFN0cmluZ1JlZiBuYW1lLCBTdHJpbmdSZWYgcGFyYW1zKSAtPiBzdGQ6OnN0cmluZyB7CisgICAgICAgIHNpemVfdCByZXN1bHRzX2xlbjsKKyAgICAgICAgY2hhciogcmVzdWx0c19jID0gY2FsbGJhY2soZGF0YSwgbmFtZS5kYXRhKCksIG5hbWUuc2l6ZSgpLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwYXJhbXMuZGF0YSgpLCBwYXJhbXMuc2l6ZSgpLCAmcmVzdWx0c19sZW4pOworICAgICAgICBzdGQ6OnN0cmluZyByZXN1bHRzKHJlc3VsdHNfYywgcmVzdWx0c19sZW4pOworICAgICAgICBzdGQ6OmZyZWUocmVzdWx0c19jKTsKKyAgICAgICAgcmV0dXJuIHJlc3VsdHM7CisgICAgICB9KTsKK30KKwordm9pZCBOVF9DcmVhdGVQb2xsZWRScGMoY29uc3QgY2hhciAqbmFtZSwgc2l6ZV90IG5hbWVfbGVuLCBjb25zdCBjaGFyICpkZWYsCisgICAgICAgICAgICAgICAgICAgICAgICBzaXplX3QgZGVmX2xlbikgeworICBudDo6Q3JlYXRlUG9sbGVkUnBjKFN0cmluZ1JlZihuYW1lLCBuYW1lX2xlbiksIFN0cmluZ1JlZihkZWYsIGRlZl9sZW4pKTsKK30KKworaW50IE5UX1BvbGxScGMoaW50IGJsb2NraW5nLCBOVF9ScGNDYWxsSW5mbyogY2FsbF9pbmZvKSB7CisgIFJwY0NhbGxJbmZvIGNhbGxfaW5mb19jcHA7CisgIGlmICghbnQ6OlBvbGxScGMoYmxvY2tpbmcgIT0gMCwgJmNhbGxfaW5mb19jcHApKQorICAgIHJldHVybiAwOworICBDb252ZXJ0VG9DKGNhbGxfaW5mb19jcHAsIGNhbGxfaW5mbyk7CisgIHJldHVybiAxOworfQorCit2b2lkIE5UX1Bvc3RScGNSZXNwb25zZSh1bnNpZ25lZCBpbnQgcnBjX2lkLCB1bnNpZ25lZCBpbnQgY2FsbF91aWQsCisgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBjaGFyICpyZXN1bHQsIHNpemVfdCByZXN1bHRfbGVuKSB7CisgIG50OjpQb3N0UnBjUmVzcG9uc2UocnBjX2lkLCBjYWxsX3VpZCwgU3RyaW5nUmVmKHJlc3VsdCwgcmVzdWx0X2xlbikpOworfQorCit1bnNpZ25lZCBpbnQgTlRfQ2FsbFJwYyhjb25zdCBjaGFyICpuYW1lLCBzaXplX3QgbmFtZV9sZW4sCisgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBjaGFyICpwYXJhbXMsIHNpemVfdCBwYXJhbXNfbGVuKSB7CisgIHJldHVybiBudDo6Q2FsbFJwYyhTdHJpbmdSZWYobmFtZSwgbmFtZV9sZW4pLCBTdHJpbmdSZWYocGFyYW1zLCBwYXJhbXNfbGVuKSk7Cit9CisKK2NoYXIgKk5UX0dldFJwY1Jlc3VsdChpbnQgYmxvY2tpbmcsIHVuc2lnbmVkIGludCBjYWxsX3VpZCwgc2l6ZV90ICpyZXN1bHRfbGVuKSB7CisgIHN0ZDo6c3RyaW5nIHJlc3VsdDsKKyAgaWYgKCFudDo6R2V0UnBjUmVzdWx0KGJsb2NraW5nICE9IDAsIGNhbGxfdWlkLCAmcmVzdWx0KSkgcmV0dXJuIG51bGxwdHI7CisKKyAgLy8gY29udmVydCByZXN1bHQKKyAgKnJlc3VsdF9sZW4gPSByZXN1bHQuc2l6ZSgpOworICBjaGFyICpyZXN1bHRfY3N0cjsKKyAgQ29udmVydFRvQyhyZXN1bHQsICZyZXN1bHRfY3N0cik7CisgIHJldHVybiByZXN1bHRfY3N0cjsKK30KKworY2hhciAqTlRfUGFja1JwY0RlZmluaXRpb24oY29uc3QgTlRfUnBjRGVmaW5pdGlvbiAqZGVmLCBzaXplX3QgKnBhY2tlZF9sZW4pIHsKKyAgYXV0byBwYWNrZWQgPSBudDo6UGFja1JwY0RlZmluaXRpb24oQ29udmVydEZyb21DKCpkZWYpKTsKKworICAvLyBjb252ZXJ0IHJlc3VsdAorICAqcGFja2VkX2xlbiA9IHBhY2tlZC5zaXplKCk7CisgIGNoYXIgKnBhY2tlZF9jc3RyOworICBDb252ZXJ0VG9DKHBhY2tlZCwgJnBhY2tlZF9jc3RyKTsKKyAgcmV0dXJuIHBhY2tlZF9jc3RyOworfQorCitpbnQgTlRfVW5wYWNrUnBjRGVmaW5pdGlvbihjb25zdCBjaGFyICpwYWNrZWQsIHNpemVfdCBwYWNrZWRfbGVuLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgTlRfUnBjRGVmaW5pdGlvbiAqZGVmKSB7CisgIG50OjpScGNEZWZpbml0aW9uIGRlZl92OworICBpZiAoIW50OjpVbnBhY2tScGNEZWZpbml0aW9uKFN0cmluZ1JlZihwYWNrZWQsIHBhY2tlZF9sZW4pLCAmZGVmX3YpKQorICAgICAgcmV0dXJuIDA7CisKKyAgLy8gY29udmVydCByZXN1bHQKKyAgQ29udmVydFRvQyhkZWZfdiwgZGVmKTsKKyAgcmV0dXJuIDE7Cit9CisKK2NoYXIgKk5UX1BhY2tScGNWYWx1ZXMoY29uc3QgTlRfVmFsdWUgKip2YWx1ZXMsIHNpemVfdCB2YWx1ZXNfbGVuLAorICAgICAgICAgICAgICAgICAgICAgICBzaXplX3QgKnBhY2tlZF9sZW4pIHsKKyAgLy8gY3JlYXRlIGlucHV0IHZlY3RvcgorICBzdGQ6OnZlY3RvcjxzdGQ6OnNoYXJlZF9wdHI8VmFsdWU+PiB2YWx1ZXNfdjsKKyAgdmFsdWVzX3YucmVzZXJ2ZSh2YWx1ZXNfbGVuKTsKKyAgZm9yIChzaXplX3QgaSA9IDA7IGkgPCB2YWx1ZXNfbGVuOyArK2kpCisgICAgdmFsdWVzX3YucHVzaF9iYWNrKENvbnZlcnRGcm9tQygqdmFsdWVzW2ldKSk7CisKKyAgLy8gbWFrZSB0aGUgY2FsbAorICBhdXRvIHBhY2tlZCA9IG50OjpQYWNrUnBjVmFsdWVzKHZhbHVlc192KTsKKworICAvLyBjb252ZXJ0IHJlc3VsdAorICAqcGFja2VkX2xlbiA9IHBhY2tlZC5zaXplKCk7CisgIGNoYXIgKnBhY2tlZF9jc3RyOworICBDb252ZXJ0VG9DKHBhY2tlZCwgJnBhY2tlZF9jc3RyKTsKKyAgcmV0dXJuIHBhY2tlZF9jc3RyOworfQorCitOVF9WYWx1ZSAqKk5UX1VucGFja1JwY1ZhbHVlcyhjb25zdCBjaGFyICpwYWNrZWQsIHNpemVfdCBwYWNrZWRfbGVuLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgTlRfVHlwZSAqdHlwZXMsIHNpemVfdCB0eXBlc19sZW4pIHsKKyAgYXV0byB2YWx1ZXNfdiA9IG50OjpVbnBhY2tScGNWYWx1ZXMoU3RyaW5nUmVmKHBhY2tlZCwgcGFja2VkX2xlbiksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEFycmF5UmVmPE5UX1R5cGU+KHR5cGVzLCB0eXBlc19sZW4pKTsKKyAgaWYgKHZhbHVlc192LnNpemUoKSA9PSAwKSByZXR1cm4gbnVsbHB0cjsKKworICAvLyBjcmVhdGUgYXJyYXkgYW5kIGNvcHkgaW50byBpdAorICBOVF9WYWx1ZSoqIHZhbHVlcyA9IHN0YXRpY19jYXN0PE5UX1ZhbHVlKio+KAorICAgICAgc3RkOjptYWxsb2ModmFsdWVzX3Yuc2l6ZSgpICogc2l6ZW9mKE5UX1ZhbHVlKikpKTsKKyAgZm9yIChzaXplX3QgaSA9IDA7IGkgPCB2YWx1ZXNfdi5zaXplKCk7ICsraSkgeworICAgIHZhbHVlc1tpXSA9IHN0YXRpY19jYXN0PE5UX1ZhbHVlKj4oc3RkOjptYWxsb2Moc2l6ZW9mKE5UX1ZhbHVlKSkpOworICAgIENvbnZlcnRUb0MoKnZhbHVlc192W2ldLCB2YWx1ZXNbaV0pOworICB9CisgIHJldHVybiB2YWx1ZXM7Cit9CisKKy8qCisgKiBDbGllbnQvU2VydmVyIEZ1bmN0aW9ucworICovCisKK3ZvaWQgTlRfU2V0TmV0d29ya0lkZW50aXR5KGNvbnN0IGNoYXIgKm5hbWUsIHNpemVfdCBuYW1lX2xlbikgeworICBudDo6U2V0TmV0d29ya0lkZW50aXR5KFN0cmluZ1JlZihuYW1lLCBuYW1lX2xlbikpOworfQorCit2b2lkIE5UX1N0YXJ0U2VydmVyKGNvbnN0IGNoYXIgKnBlcnNpc3RfZmlsZW5hbWUsIGNvbnN0IGNoYXIgKmxpc3Rlbl9hZGRyZXNzLAorICAgICAgICAgICAgICAgICAgICB1bnNpZ25lZCBpbnQgcG9ydCkgeworICBudDo6U3RhcnRTZXJ2ZXIocGVyc2lzdF9maWxlbmFtZSwgbGlzdGVuX2FkZHJlc3MsIHBvcnQpOworfQorCit2b2lkIE5UX1N0b3BTZXJ2ZXIodm9pZCkgeyBudDo6U3RvcFNlcnZlcigpOyB9CisKK3ZvaWQgTlRfU3RhcnRDbGllbnQoY29uc3QgY2hhciAqc2VydmVyX25hbWUsIHVuc2lnbmVkIGludCBwb3J0KSB7CisgIG50OjpTdGFydENsaWVudChzZXJ2ZXJfbmFtZSwgcG9ydCk7Cit9CisKK3ZvaWQgTlRfU3RvcENsaWVudCh2b2lkKSB7CisgIG50OjpTdG9wQ2xpZW50KCk7Cit9CisKK3ZvaWQgTlRfU3RvcFJwY1NlcnZlcih2b2lkKSB7CisgIG50OjpTdG9wUnBjU2VydmVyKCk7Cit9CisKK3ZvaWQgTlRfU3RvcE5vdGlmaWVyKHZvaWQpIHsKKyAgbnQ6OlN0b3BOb3RpZmllcigpOworfQorCit2b2lkIE5UX1NldFVwZGF0ZVJhdGUoZG91YmxlIGludGVydmFsKSB7CisgIG50OjpTZXRVcGRhdGVSYXRlKGludGVydmFsKTsKK30KKworc3RydWN0IE5UX0Nvbm5lY3Rpb25JbmZvICpOVF9HZXRDb25uZWN0aW9ucyhzaXplX3QgKmNvdW50KSB7CisgIGF1dG8gY29ubl92ID0gbnQ6OkdldENvbm5lY3Rpb25zKCk7CisgICpjb3VudCA9IGNvbm5fdi5zaXplKCk7CisgIGlmIChjb25uX3Yuc2l6ZSgpID09IDApIHJldHVybiBudWxscHRyOworCisgIC8vIGNyZWF0ZSBhcnJheSBhbmQgY29weSBpbnRvIGl0CisgIE5UX0Nvbm5lY3Rpb25JbmZvICpjb25uID0gc3RhdGljX2Nhc3Q8TlRfQ29ubmVjdGlvbkluZm8gKj4oCisgICAgICBzdGQ6Om1hbGxvYyhjb25uX3Yuc2l6ZSgpICogc2l6ZW9mKE5UX0Nvbm5lY3Rpb25JbmZvKSkpOworICBmb3IgKHNpemVfdCBpID0gMDsgaSA8IGNvbm5fdi5zaXplKCk7ICsraSkgQ29udmVydFRvQyhjb25uX3ZbaV0sICZjb25uW2ldKTsKKyAgcmV0dXJuIGNvbm47Cit9CisKKy8qCisgKiBQZXJzaXN0ZW50IEZ1bmN0aW9ucworICovCisKK2NvbnN0IGNoYXIgKk5UX1NhdmVQZXJzaXN0ZW50KGNvbnN0IGNoYXIgKmZpbGVuYW1lKSB7CisgIHJldHVybiBudDo6U2F2ZVBlcnNpc3RlbnQoZmlsZW5hbWUpOworfQorCitjb25zdCBjaGFyICpOVF9Mb2FkUGVyc2lzdGVudChjb25zdCBjaGFyICpmaWxlbmFtZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZvaWQgKCp3YXJuKShzaXplX3QgbGluZSwgY29uc3QgY2hhciAqbXNnKSkgeworICByZXR1cm4gbnQ6OkxvYWRQZXJzaXN0ZW50KGZpbGVuYW1lLCB3YXJuKTsKK30KKworLyoKKyAqIFV0aWxpdHkgRnVuY3Rpb25zCisgKi8KKwordm9pZCBOVF9TZXRMb2dnZXIoTlRfTG9nRnVuYyBmdW5jLCB1bnNpZ25lZCBpbnQgbWluX2xldmVsKSB7CisgIG50OjpTZXRMb2dnZXIoZnVuYywgbWluX2xldmVsKTsKK30KKwordm9pZCBOVF9EaXNwb3NlVmFsdWUoTlRfVmFsdWUgKnZhbHVlKSB7CisgIHN3aXRjaCAodmFsdWUtPnR5cGUpIHsKKyAgICBjYXNlIE5UX1VOQVNTSUdORUQ6CisgICAgY2FzZSBOVF9CT09MRUFOOgorICAgIGNhc2UgTlRfRE9VQkxFOgorICAgICAgYnJlYWs7CisgICAgY2FzZSBOVF9TVFJJTkc6CisgICAgY2FzZSBOVF9SQVc6CisgICAgY2FzZSBOVF9SUEM6CisgICAgICBzdGQ6OmZyZWUodmFsdWUtPmRhdGEudl9zdHJpbmcuc3RyKTsKKyAgICAgIGJyZWFrOworICAgIGNhc2UgTlRfQk9PTEVBTl9BUlJBWToKKyAgICAgIHN0ZDo6ZnJlZSh2YWx1ZS0+ZGF0YS5hcnJfYm9vbGVhbi5hcnIpOworICAgICAgYnJlYWs7CisgICAgY2FzZSBOVF9ET1VCTEVfQVJSQVk6CisgICAgICBzdGQ6OmZyZWUodmFsdWUtPmRhdGEuYXJyX2RvdWJsZS5hcnIpOworICAgICAgYnJlYWs7CisgICAgY2FzZSBOVF9TVFJJTkdfQVJSQVk6IHsKKyAgICAgIGZvciAoc2l6ZV90IGkgPSAwOyBpIDwgdmFsdWUtPmRhdGEuYXJyX3N0cmluZy5zaXplOyBpKyspCisgICAgICAgIHN0ZDo6ZnJlZSh2YWx1ZS0+ZGF0YS5hcnJfc3RyaW5nLmFycltpXS5zdHIpOworICAgICAgc3RkOjpmcmVlKHZhbHVlLT5kYXRhLmFycl9zdHJpbmcuYXJyKTsKKyAgICAgIGJyZWFrOworICAgIH0KKyAgICBkZWZhdWx0OgorICAgICAgYXNzZXJ0KGZhbHNlICYmICJ1bmtub3duIHZhbHVlIHR5cGUiKTsKKyAgfQorICB2YWx1ZS0+dHlwZSA9IE5UX1VOQVNTSUdORUQ7CisgIHZhbHVlLT5sYXN0X2NoYW5nZSA9IDA7Cit9CisKK3ZvaWQgTlRfSW5pdFZhbHVlKE5UX1ZhbHVlICp2YWx1ZSkgeworICB2YWx1ZS0+dHlwZSA9IE5UX1VOQVNTSUdORUQ7CisgIHZhbHVlLT5sYXN0X2NoYW5nZSA9IDA7Cit9CisKK3ZvaWQgTlRfRGlzcG9zZVN0cmluZyhOVF9TdHJpbmcgKnN0cikgeworICBzdGQ6OmZyZWUoc3RyLT5zdHIpOworICBzdHItPnN0ciA9IG51bGxwdHI7CisgIHN0ci0+bGVuID0gMDsKK30KKwordm9pZCBOVF9Jbml0U3RyaW5nKE5UX1N0cmluZyAqc3RyKSB7CisgIHN0ci0+c3RyID0gbnVsbHB0cjsKKyAgc3RyLT5sZW4gPSAwOworfQorCitlbnVtIE5UX1R5cGUgTlRfR2V0VHlwZShjb25zdCBjaGFyICpuYW1lLCBzaXplX3QgbmFtZV9sZW4pIHsKKyAgYXV0byB2ID0gbnQ6OkdldEVudHJ5VmFsdWUoU3RyaW5nUmVmKG5hbWUsIG5hbWVfbGVuKSk7CisgIGlmICghdikgcmV0dXJuIE5UX1R5cGU6Ok5UX1VOQVNTSUdORUQ7CisgIHJldHVybiB2LT50eXBlKCk7Cit9CisKK3ZvaWQgTlRfRGlzcG9zZUNvbm5lY3Rpb25JbmZvQXJyYXkoTlRfQ29ubmVjdGlvbkluZm8gKmFyciwgc2l6ZV90IGNvdW50KSB7CisgIGZvciAoc2l6ZV90IGkgPSAwOyBpIDwgY291bnQ7IGkrKykgRGlzcG9zZUNvbm5lY3Rpb25JbmZvKCZhcnJbaV0pOworICBzdGQ6OmZyZWUoYXJyKTsKK30KKwordm9pZCBOVF9EaXNwb3NlRW50cnlJbmZvQXJyYXkoTlRfRW50cnlJbmZvICphcnIsIHNpemVfdCBjb3VudCl7CisgIGZvciAoc2l6ZV90IGkgPSAwOyBpIDwgY291bnQ7IGkrKykgRGlzcG9zZUVudHJ5SW5mbygmYXJyW2ldKTsKKyAgc3RkOjpmcmVlKGFycik7Cit9CisKK3ZvaWQgTlRfRGlzcG9zZVJwY0RlZmluaXRpb24oTlRfUnBjRGVmaW5pdGlvbiAqZGVmKSB7CisgIE5UX0Rpc3Bvc2VTdHJpbmcoJmRlZi0+bmFtZSk7CisKKyAgZm9yIChzaXplX3QgaSA9IDA7IGkgPCBkZWYtPm51bV9wYXJhbXM7ICsraSkgeworICAgIE5UX0Rpc3Bvc2VTdHJpbmcoJmRlZi0+cGFyYW1zW2ldLm5hbWUpOworICAgIE5UX0Rpc3Bvc2VWYWx1ZSgmZGVmLT5wYXJhbXNbaV0uZGVmX3ZhbHVlKTsKKyAgfQorICBzdGQ6OmZyZWUoZGVmLT5wYXJhbXMpOworICBkZWYtPnBhcmFtcyA9IG51bGxwdHI7CisgIGRlZi0+bnVtX3BhcmFtcyA9IDA7CisKKyAgZm9yIChzaXplX3QgaSA9IDA7IGkgPCBkZWYtPm51bV9yZXN1bHRzOyArK2kpCisgICAgTlRfRGlzcG9zZVN0cmluZygmZGVmLT5yZXN1bHRzW2ldLm5hbWUpOworICBzdGQ6OmZyZWUoZGVmLT5yZXN1bHRzKTsKKyAgZGVmLT5yZXN1bHRzID0gbnVsbHB0cjsKKyAgZGVmLT5udW1fcmVzdWx0cyA9IDA7Cit9CisKK3ZvaWQgTlRfRGlzcG9zZVJwY0NhbGxJbmZvKE5UX1JwY0NhbGxJbmZvICpjYWxsX2luZm8pIHsKKyAgTlRfRGlzcG9zZVN0cmluZygmY2FsbF9pbmZvLT5uYW1lKTsKKyAgTlRfRGlzcG9zZVN0cmluZygmY2FsbF9pbmZvLT5wYXJhbXMpOworfQorCisvKiBJbnRlcm9wIFV0aWxpdHkgRnVuY3Rpb25zICovCisKKy8qIEFycmF5IGFuZCBTdHJ1Y3QgQWxsb2NhdGlvbnMgKi8KKworLyogQWxsb2NhdGVzIGEgY2hhciBhcnJheSBvZiB0aGUgc3BlY2lmaWVkIHNpemUuKi8KK2NoYXIgKk5UX0FsbG9jYXRlQ2hhckFycmF5KHNpemVfdCBzaXplKSB7CisgIGNoYXIgKnJldFZhbCA9IHN0YXRpY19jYXN0PGNoYXIgKj4oc3RkOjptYWxsb2Moc2l6ZSAqIHNpemVvZihjaGFyKSkpOworICByZXR1cm4gcmV0VmFsOworfQorCisvKiBBbGxvY2F0ZXMgYW4gaW50ZWdlciBvciBib29sZWFuIGFycmF5IG9mIHRoZSBzcGVjaWZpZWQgc2l6ZS4gKi8KK2ludCAqTlRfQWxsb2NhdGVCb29sZWFuQXJyYXkoc2l6ZV90IHNpemUpIHsKKyAgaW50ICpyZXRWYWwgPSBzdGF0aWNfY2FzdDxpbnQgKj4oc3RkOjptYWxsb2Moc2l6ZSAqIHNpemVvZihpbnQpKSk7CisgIHJldHVybiByZXRWYWw7Cit9CisKKy8qIEFsbG9jYXRlcyBhIGRvdWJsZSBhcnJheSBvZiB0aGUgc3BlY2lmaWVkIHNpemUuICovCitkb3VibGUgKk5UX0FsbG9jYXRlRG91YmxlQXJyYXkoc2l6ZV90IHNpemUpIHsKKyAgZG91YmxlICpyZXRWYWwgPSBzdGF0aWNfY2FzdDxkb3VibGUgKj4oc3RkOjptYWxsb2Moc2l6ZSAqIHNpemVvZihkb3VibGUpKSk7CisgIHJldHVybiByZXRWYWw7Cit9CisKKy8qIEFsbG9jYXRlcyBhbiBOVF9TdHJpbmcgYXJyYXkgb2YgdGhlIHNwZWNpZmllZCBzaXplLiAqLworc3RydWN0IE5UX1N0cmluZyAqTlRfQWxsb2NhdGVTdHJpbmdBcnJheShzaXplX3Qgc2l6ZSkgeworICBOVF9TdHJpbmcgKnJldFZhbCA9CisgICAgICBzdGF0aWNfY2FzdDxOVF9TdHJpbmcgKj4oc3RkOjptYWxsb2Moc2l6ZSAqIHNpemVvZihOVF9TdHJpbmcpKSk7CisgIHJldHVybiByZXRWYWw7Cit9CisKK3ZvaWQgTlRfRnJlZUNoYXJBcnJheShjaGFyICp2X2NoYXIpIHsgc3RkOjpmcmVlKHZfY2hhcik7IH0KK3ZvaWQgTlRfRnJlZURvdWJsZUFycmF5KGRvdWJsZSAqdl9kb3VibGUpIHsgc3RkOjpmcmVlKHZfZG91YmxlKTsgfQordm9pZCBOVF9GcmVlQm9vbGVhbkFycmF5KGludCAqdl9ib29sZWFuKSB7IHN0ZDo6ZnJlZSh2X2Jvb2xlYW4pOyB9Cit2b2lkIE5UX0ZyZWVTdHJpbmdBcnJheShzdHJ1Y3QgTlRfU3RyaW5nICp2X3N0cmluZywgc2l6ZV90IGFycl9zaXplKSB7CisgIGZvciAoc2l6ZV90IGkgPSAwOyBpIDwgYXJyX3NpemU7IGkrKykgc3RkOjpmcmVlKHZfc3RyaW5nW2ldLnN0cik7CisgIHN0ZDo6ZnJlZSh2X3N0cmluZyk7Cit9CisKK2ludCBOVF9TZXRFbnRyeURvdWJsZShjb25zdCBjaGFyICpuYW1lLCBzaXplX3QgbmFtZV9sZW4sIGRvdWJsZSB2X2RvdWJsZSwKKyAgICAgICAgICAgICAgICAgICAgICBpbnQgZm9yY2UpIHsKKyAgaWYgKGZvcmNlICE9IDApIHsKKyAgICBudDo6U2V0RW50cnlUeXBlVmFsdWUoU3RyaW5nUmVmKG5hbWUsIG5hbWVfbGVuKSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgVmFsdWU6Ok1ha2VEb3VibGUodl9kb3VibGUpKTsKKyAgICByZXR1cm4gMTsKKyAgfSBlbHNlIHsKKyAgICByZXR1cm4gbnQ6OlNldEVudHJ5VmFsdWUoU3RyaW5nUmVmKG5hbWUsIG5hbWVfbGVuKSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVmFsdWU6Ok1ha2VEb3VibGUodl9kb3VibGUpKTsKKyAgfQorfQorCitpbnQgTlRfU2V0RW50cnlCb29sZWFuKGNvbnN0IGNoYXIgKm5hbWUsIHNpemVfdCBuYW1lX2xlbiwgaW50IHZfYm9vbGVhbiwKKyAgICAgICAgICAgICAgICAgICAgICAgaW50IGZvcmNlKSB7CisgIGlmIChmb3JjZSAhPSAwKSB7CisgICAgbnQ6OlNldEVudHJ5VHlwZVZhbHVlKFN0cmluZ1JlZihuYW1lLCBuYW1lX2xlbiksCisgICAgICAgICAgICAgICAgICAgICAgICAgIFZhbHVlOjpNYWtlQm9vbGVhbih2X2Jvb2xlYW4gIT0gMCkpOworICAgIHJldHVybiAxOworICB9IGVsc2UgeworICAgIHJldHVybiBudDo6U2V0RW50cnlWYWx1ZShTdHJpbmdSZWYobmFtZSwgbmFtZV9sZW4pLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICBWYWx1ZTo6TWFrZUJvb2xlYW4odl9ib29sZWFuICE9IDApKTsKKyAgfQorfQorCitpbnQgTlRfU2V0RW50cnlTdHJpbmcoY29uc3QgY2hhciAqbmFtZSwgc2l6ZV90IG5hbWVfbGVuLCBjb25zdCBjaGFyICpzdHIsCisgICAgICAgICAgICAgICAgICAgICAgc2l6ZV90IHN0cl9sZW4sIGludCBmb3JjZSkgeworICBpZiAoZm9yY2UgIT0gMCkgeworICAgIG50OjpTZXRFbnRyeVR5cGVWYWx1ZShTdHJpbmdSZWYobmFtZSwgbmFtZV9sZW4pLAorICAgICAgICAgICAgICAgICAgICAgICAgICBWYWx1ZTo6TWFrZVN0cmluZyhTdHJpbmdSZWYoc3RyLCBzdHJfbGVuKSkpOworICAgIHJldHVybiAxOworICB9IGVsc2UgeworICAgIHJldHVybiBudDo6U2V0RW50cnlWYWx1ZShTdHJpbmdSZWYobmFtZSwgbmFtZV9sZW4pLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICBWYWx1ZTo6TWFrZVN0cmluZyhTdHJpbmdSZWYoc3RyLCBzdHJfbGVuKSkpOworICB9Cit9CisKK2ludCBOVF9TZXRFbnRyeVJhdyhjb25zdCBjaGFyICpuYW1lLCBzaXplX3QgbmFtZV9sZW4sIGNvbnN0IGNoYXIgKnJhdywKKyAgICAgICAgICAgICAgICAgICBzaXplX3QgcmF3X2xlbiwgaW50IGZvcmNlKSB7CisgIGlmIChmb3JjZSAhPSAwKSB7CisgICAgbnQ6OlNldEVudHJ5VHlwZVZhbHVlKFN0cmluZ1JlZihuYW1lLCBuYW1lX2xlbiksCisgICAgICAgICAgICAgICAgICAgICAgICAgIFZhbHVlOjpNYWtlUmF3KFN0cmluZ1JlZihyYXcsIHJhd19sZW4pKSk7CisgICAgcmV0dXJuIDE7CisgIH0gZWxzZSB7CisgICAgcmV0dXJuIG50OjpTZXRFbnRyeVZhbHVlKFN0cmluZ1JlZihuYW1lLCBuYW1lX2xlbiksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFZhbHVlOjpNYWtlUmF3KFN0cmluZ1JlZihyYXcsIHJhd19sZW4pKSk7CisgIH0KK30KKworaW50IE5UX1NldEVudHJ5Qm9vbGVhbkFycmF5KGNvbnN0IGNoYXIgKm5hbWUsIHNpemVfdCBuYW1lX2xlbiwgY29uc3QgaW50ICphcnIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2l6ZV90IHNpemUsIGludCBmb3JjZSkgeworICBpZiAoZm9yY2UgIT0gMCkgeworICAgIG50OjpTZXRFbnRyeVR5cGVWYWx1ZSgKKyAgICAgICAgU3RyaW5nUmVmKG5hbWUsIG5hbWVfbGVuKSwKKyAgICAgICAgVmFsdWU6Ok1ha2VCb29sZWFuQXJyYXkobGx2bTo6bWFrZUFycmF5UmVmKGFyciwgc2l6ZSkpKTsKKyAgICByZXR1cm4gMTsKKyAgfSBlbHNlIHsKKyAgICByZXR1cm4gbnQ6OlNldEVudHJ5VmFsdWUoCisgICAgICAgIFN0cmluZ1JlZihuYW1lLCBuYW1lX2xlbiksCisgICAgICAgIFZhbHVlOjpNYWtlQm9vbGVhbkFycmF5KGxsdm06Om1ha2VBcnJheVJlZihhcnIsIHNpemUpKSk7CisgIH0KK30KKworaW50IE5UX1NldEVudHJ5RG91YmxlQXJyYXkoY29uc3QgY2hhciAqbmFtZSwgc2l6ZV90IG5hbWVfbGVuLCBjb25zdCBkb3VibGUgKmFyciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgIHNpemVfdCBzaXplLCBpbnQgZm9yY2UpIHsKKyAgaWYgKGZvcmNlICE9IDApIHsKKyAgICBudDo6U2V0RW50cnlUeXBlVmFsdWUoCisgICAgICAgIFN0cmluZ1JlZihuYW1lLCBuYW1lX2xlbiksCisgICAgICAgIFZhbHVlOjpNYWtlRG91YmxlQXJyYXkobGx2bTo6bWFrZUFycmF5UmVmKGFyciwgc2l6ZSkpKTsKKyAgICByZXR1cm4gMTsKKyAgfSBlbHNlIHsKKyAgICByZXR1cm4gbnQ6OlNldEVudHJ5VmFsdWUoCisgICAgICAgIFN0cmluZ1JlZihuYW1lLCBuYW1lX2xlbiksCisgICAgICAgIFZhbHVlOjpNYWtlRG91YmxlQXJyYXkobGx2bTo6bWFrZUFycmF5UmVmKGFyciwgc2l6ZSkpKTsKKyAgfQorfQorCitpbnQgTlRfU2V0RW50cnlTdHJpbmdBcnJheShjb25zdCBjaGFyICpuYW1lLCBzaXplX3QgbmFtZV9sZW4sCisgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBzdHJ1Y3QgTlRfU3RyaW5nICphcnIsIHNpemVfdCBzaXplLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50IGZvcmNlKSB7CisgIHN0ZDo6dmVjdG9yPHN0ZDo6c3RyaW5nPiB2OworICB2LnJlc2VydmUoc2l6ZSk7CisgIGZvciAoc2l6ZV90IGkgPSAwOyBpIDwgc2l6ZTsgKytpKSB2LnB1c2hfYmFjayhDb252ZXJ0RnJvbUMoYXJyW2ldKSk7CisKKyAgaWYgKGZvcmNlICE9IDApIHsKKyAgICBudDo6U2V0RW50cnlUeXBlVmFsdWUoU3RyaW5nUmVmKG5hbWUsIG5hbWVfbGVuKSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgVmFsdWU6Ok1ha2VTdHJpbmdBcnJheShzdGQ6Om1vdmUodikpKTsKKyAgICByZXR1cm4gMTsKKyAgfSBlbHNlIHsKKyAgICByZXR1cm4gbnQ6OlNldEVudHJ5VmFsdWUoU3RyaW5nUmVmKG5hbWUsIG5hbWVfbGVuKSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVmFsdWU6Ok1ha2VTdHJpbmdBcnJheShzdGQ6Om1vdmUodikpKTsKKyAgfQorfQorCitlbnVtIE5UX1R5cGUgTlRfR2V0VmFsdWVUeXBlKGNvbnN0IHN0cnVjdCBOVF9WYWx1ZSAqdmFsdWUpIHsKKyAgaWYgKCF2YWx1ZSkgcmV0dXJuIE5UX1R5cGU6Ok5UX1VOQVNTSUdORUQ7CisgIHJldHVybiB2YWx1ZS0+dHlwZTsKK30KKworaW50IE5UX0dldFZhbHVlQm9vbGVhbihjb25zdCBzdHJ1Y3QgTlRfVmFsdWUgKnZhbHVlLAorICAgICAgICAgICAgICAgICAgICAgICB1bnNpZ25lZCBsb25nIGxvbmcgKmxhc3RfY2hhbmdlLCBpbnQgKnZfYm9vbGVhbikgeworICBpZiAoIXZhbHVlIHx8IHZhbHVlLT50eXBlICE9IE5UX1R5cGU6Ok5UX0JPT0xFQU4pIHJldHVybiAwOworICAqdl9ib29sZWFuID0gdmFsdWUtPmRhdGEudl9ib29sZWFuOworICAqbGFzdF9jaGFuZ2UgPSB2YWx1ZS0+bGFzdF9jaGFuZ2U7CisgIHJldHVybiAxOworfQorCitpbnQgTlRfR2V0VmFsdWVEb3VibGUoY29uc3Qgc3RydWN0IE5UX1ZhbHVlICp2YWx1ZSwKKyAgICAgICAgICAgICAgICAgICAgICB1bnNpZ25lZCBsb25nIGxvbmcgKmxhc3RfY2hhbmdlLCBkb3VibGUgKnZfZG91YmxlKSB7CisgIGlmICghdmFsdWUgfHwgdmFsdWUtPnR5cGUgIT0gTlRfVHlwZTo6TlRfRE9VQkxFKSByZXR1cm4gMDsKKyAgKmxhc3RfY2hhbmdlID0gdmFsdWUtPmxhc3RfY2hhbmdlOworICAqdl9kb3VibGUgPSB2YWx1ZS0+ZGF0YS52X2RvdWJsZTsKKyAgcmV0dXJuIDE7Cit9CisKK2NoYXIgKk5UX0dldFZhbHVlU3RyaW5nKGNvbnN0IHN0cnVjdCBOVF9WYWx1ZSAqdmFsdWUsCisgICAgICAgICAgICAgICAgICAgICAgICB1bnNpZ25lZCBsb25nIGxvbmcgKmxhc3RfY2hhbmdlLCBzaXplX3QgKnN0cl9sZW4pIHsKKyAgaWYgKCF2YWx1ZSB8fCB2YWx1ZS0+dHlwZSAhPSBOVF9UeXBlOjpOVF9TVFJJTkcpIHJldHVybiBudWxscHRyOworICAqbGFzdF9jaGFuZ2UgPSB2YWx1ZS0+bGFzdF9jaGFuZ2U7CisgICpzdHJfbGVuID0gdmFsdWUtPmRhdGEudl9zdHJpbmcubGVuOworICBjaGFyICpzdHIgPSAoY2hhciopc3RkOjptYWxsb2ModmFsdWUtPmRhdGEudl9zdHJpbmcubGVuICsgMSk7CisgIHN0ZDo6bWVtY3B5KHN0ciwgdmFsdWUtPmRhdGEudl9zdHJpbmcuc3RyLCB2YWx1ZS0+ZGF0YS52X3N0cmluZy5sZW4gKyAxKTsKKyAgcmV0dXJuIHN0cjsKK30KKworY2hhciAqTlRfR2V0VmFsdWVSYXcoY29uc3Qgc3RydWN0IE5UX1ZhbHVlICp2YWx1ZSwKKyAgICAgICAgICAgICAgICAgICAgIHVuc2lnbmVkIGxvbmcgbG9uZyAqbGFzdF9jaGFuZ2UsIHNpemVfdCAqcmF3X2xlbikgeworICBpZiAoIXZhbHVlIHx8IHZhbHVlLT50eXBlICE9IE5UX1R5cGU6Ok5UX1JBVykgcmV0dXJuIG51bGxwdHI7CisgICpsYXN0X2NoYW5nZSA9IHZhbHVlLT5sYXN0X2NoYW5nZTsKKyAgKnJhd19sZW4gPSB2YWx1ZS0+ZGF0YS52X3N0cmluZy5sZW47CisgIGNoYXIgKnJhdyA9IChjaGFyKilzdGQ6Om1hbGxvYyh2YWx1ZS0+ZGF0YS52X3N0cmluZy5sZW4gKyAxKTsKKyAgc3RkOjptZW1jcHkocmF3LCB2YWx1ZS0+ZGF0YS52X3N0cmluZy5zdHIsIHZhbHVlLT5kYXRhLnZfc3RyaW5nLmxlbiArIDEpOworICByZXR1cm4gcmF3OworfQorCitpbnQgKk5UX0dldFZhbHVlQm9vbGVhbkFycmF5KGNvbnN0IHN0cnVjdCBOVF9WYWx1ZSAqdmFsdWUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVuc2lnbmVkIGxvbmcgbG9uZyAqbGFzdF9jaGFuZ2UsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNpemVfdCAqYXJyX3NpemUpIHsKKyAgaWYgKCF2YWx1ZSB8fCB2YWx1ZS0+dHlwZSAhPSBOVF9UeXBlOjpOVF9CT09MRUFOX0FSUkFZKSByZXR1cm4gbnVsbHB0cjsKKyAgKmxhc3RfY2hhbmdlID0gdmFsdWUtPmxhc3RfY2hhbmdlOworICAqYXJyX3NpemUgPSB2YWx1ZS0+ZGF0YS5hcnJfYm9vbGVhbi5zaXplOworICBpbnQgKmFyciA9IChpbnQqKXN0ZDo6bWFsbG9jKHZhbHVlLT5kYXRhLmFycl9ib29sZWFuLnNpemUgKiBzaXplb2YoaW50KSk7CisgIHN0ZDo6bWVtY3B5KGFyciwgdmFsdWUtPmRhdGEuYXJyX2Jvb2xlYW4uYXJyLAorICAgICAgICAgICAgICB2YWx1ZS0+ZGF0YS5hcnJfYm9vbGVhbi5zaXplICogc2l6ZW9mKGludCkpOworICByZXR1cm4gYXJyOworfQorCitkb3VibGUgKk5UX0dldFZhbHVlRG91YmxlQXJyYXkoY29uc3Qgc3RydWN0IE5UX1ZhbHVlICp2YWx1ZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB1bnNpZ25lZCBsb25nIGxvbmcgKmxhc3RfY2hhbmdlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNpemVfdCAqYXJyX3NpemUpIHsKKyAgaWYgKCF2YWx1ZSB8fCB2YWx1ZS0+dHlwZSAhPSBOVF9UeXBlOjpOVF9ET1VCTEVfQVJSQVkpIHJldHVybiBudWxscHRyOworICAqbGFzdF9jaGFuZ2UgPSB2YWx1ZS0+bGFzdF9jaGFuZ2U7CisgICphcnJfc2l6ZSA9IHZhbHVlLT5kYXRhLmFycl9kb3VibGUuc2l6ZTsKKyAgZG91YmxlICphcnIgPQorICAgICAgKGRvdWJsZSAqKXN0ZDo6bWFsbG9jKHZhbHVlLT5kYXRhLmFycl9kb3VibGUuc2l6ZSAqIHNpemVvZihkb3VibGUpKTsKKyAgc3RkOjptZW1jcHkoYXJyLCB2YWx1ZS0+ZGF0YS5hcnJfZG91YmxlLmFyciwKKyAgICAgICAgICAgICAgdmFsdWUtPmRhdGEuYXJyX2RvdWJsZS5zaXplICogc2l6ZW9mKGRvdWJsZSkpOworICByZXR1cm4gYXJyOworfQorCitOVF9TdHJpbmcgKk5UX0dldFZhbHVlU3RyaW5nQXJyYXkoY29uc3Qgc3RydWN0IE5UX1ZhbHVlICp2YWx1ZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB1bnNpZ25lZCBsb25nIGxvbmcgKmxhc3RfY2hhbmdlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNpemVfdCAqYXJyX3NpemUpIHsKKyAgaWYgKCF2YWx1ZSB8fCB2YWx1ZS0+dHlwZSAhPSBOVF9UeXBlOjpOVF9TVFJJTkdfQVJSQVkpIHJldHVybiBudWxscHRyOworICAqbGFzdF9jaGFuZ2UgPSB2YWx1ZS0+bGFzdF9jaGFuZ2U7CisgICphcnJfc2l6ZSA9IHZhbHVlLT5kYXRhLmFycl9zdHJpbmcuc2l6ZTsKKyAgTlRfU3RyaW5nICphcnIgPSBzdGF0aWNfY2FzdDxOVF9TdHJpbmcgKj4oCisgICAgICBzdGQ6Om1hbGxvYyh2YWx1ZS0+ZGF0YS5hcnJfc3RyaW5nLnNpemUgKiBzaXplb2YoTlRfU3RyaW5nKSkpOworICBmb3IgKHNpemVfdCBpID0gMDsgaSA8IHZhbHVlLT5kYXRhLmFycl9zdHJpbmcuc2l6ZTsgKytpKSB7CisgICAgc2l6ZV90IGxlbiA9IHZhbHVlLT5kYXRhLmFycl9zdHJpbmcuYXJyW2ldLmxlbjsKKyAgICBhcnJbaV0ubGVuID0gbGVuOworICAgIGFycltpXS5zdHIgPSAoY2hhciopc3RkOjptYWxsb2MobGVuICsgMSk7CisgICAgc3RkOjptZW1jcHkoYXJyW2ldLnN0ciwgdmFsdWUtPmRhdGEuYXJyX3N0cmluZy5hcnJbaV0uc3RyLCBsZW4gKyAxKTsKKyAgfQorICByZXR1cm4gYXJyOworfQorCitpbnQgTlRfR2V0RW50cnlCb29sZWFuKGNvbnN0IGNoYXIgKm5hbWUsIHNpemVfdCBuYW1lX2xlbiwKKyAgICAgICAgICAgICAgICAgICAgICAgdW5zaWduZWQgbG9uZyBsb25nICpsYXN0X2NoYW5nZSwgaW50ICp2X2Jvb2xlYW4pIHsKKyAgYXV0byB2ID0gbnQ6OkdldEVudHJ5VmFsdWUoU3RyaW5nUmVmKG5hbWUsIG5hbWVfbGVuKSk7CisgIGlmICghdiB8fCAhdi0+SXNCb29sZWFuKCkpIHJldHVybiAwOworICAqdl9ib29sZWFuID0gdi0+R2V0Qm9vbGVhbigpOworICAqbGFzdF9jaGFuZ2UgPSB2LT5sYXN0X2NoYW5nZSgpOworICByZXR1cm4gMTsKK30KKworaW50IE5UX0dldEVudHJ5RG91YmxlKGNvbnN0IGNoYXIgKm5hbWUsIHNpemVfdCBuYW1lX2xlbiwKKyAgICAgICAgICAgICAgICAgICAgICB1bnNpZ25lZCBsb25nIGxvbmcgKmxhc3RfY2hhbmdlLCBkb3VibGUgKnZfZG91YmxlKSB7CisgIGF1dG8gdiA9IG50OjpHZXRFbnRyeVZhbHVlKFN0cmluZ1JlZihuYW1lLCBuYW1lX2xlbikpOworICBpZiAoIXYgfHwgIXYtPklzRG91YmxlKCkpIHJldHVybiAwOworICAqbGFzdF9jaGFuZ2UgPSB2LT5sYXN0X2NoYW5nZSgpOworICAqdl9kb3VibGUgPSB2LT5HZXREb3VibGUoKTsKKyAgcmV0dXJuIDE7Cit9CisKK2NoYXIgKk5UX0dldEVudHJ5U3RyaW5nKGNvbnN0IGNoYXIgKm5hbWUsIHNpemVfdCBuYW1lX2xlbiwKKyAgICAgICAgICAgICAgICAgICAgICAgIHVuc2lnbmVkIGxvbmcgbG9uZyAqbGFzdF9jaGFuZ2UsIHNpemVfdCAqc3RyX2xlbikgeworICBhdXRvIHYgPSBudDo6R2V0RW50cnlWYWx1ZShTdHJpbmdSZWYobmFtZSwgbmFtZV9sZW4pKTsKKyAgaWYgKCF2IHx8ICF2LT5Jc1N0cmluZygpKSByZXR1cm4gbnVsbHB0cjsKKyAgKmxhc3RfY2hhbmdlID0gdi0+bGFzdF9jaGFuZ2UoKTsKKyAgc3RydWN0IE5UX1N0cmluZyB2X3N0cmluZzsKKyAgbnQ6OkNvbnZlcnRUb0Modi0+R2V0U3RyaW5nKCksICZ2X3N0cmluZyk7CisgICpzdHJfbGVuID0gdl9zdHJpbmcubGVuOworICByZXR1cm4gdl9zdHJpbmcuc3RyOworfQorCitjaGFyICpOVF9HZXRFbnRyeVJhdyhjb25zdCBjaGFyICpuYW1lLCBzaXplX3QgbmFtZV9sZW4sCisgICAgICAgICAgICAgICAgICAgICB1bnNpZ25lZCBsb25nIGxvbmcgKmxhc3RfY2hhbmdlLCBzaXplX3QgKnJhd19sZW4pIHsKKyAgYXV0byB2ID0gbnQ6OkdldEVudHJ5VmFsdWUoU3RyaW5nUmVmKG5hbWUsIG5hbWVfbGVuKSk7CisgIGlmICghdiB8fCAhdi0+SXNSYXcoKSkgcmV0dXJuIG51bGxwdHI7CisgICpsYXN0X2NoYW5nZSA9IHYtPmxhc3RfY2hhbmdlKCk7CisgIHN0cnVjdCBOVF9TdHJpbmcgdl9yYXc7CisgIG50OjpDb252ZXJ0VG9DKHYtPkdldFJhdygpLCAmdl9yYXcpOworICAqcmF3X2xlbiA9IHZfcmF3LmxlbjsKKyAgcmV0dXJuIHZfcmF3LnN0cjsKK30KKworaW50ICpOVF9HZXRFbnRyeUJvb2xlYW5BcnJheShjb25zdCBjaGFyICpuYW1lLCBzaXplX3QgbmFtZV9sZW4sCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVuc2lnbmVkIGxvbmcgbG9uZyAqbGFzdF9jaGFuZ2UsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNpemVfdCAqYXJyX3NpemUpIHsKKyAgYXV0byB2ID0gbnQ6OkdldEVudHJ5VmFsdWUoU3RyaW5nUmVmKG5hbWUsIG5hbWVfbGVuKSk7CisgIGlmICghdiB8fCAhdi0+SXNCb29sZWFuQXJyYXkoKSkgcmV0dXJuIG51bGxwdHI7CisgICpsYXN0X2NoYW5nZSA9IHYtPmxhc3RfY2hhbmdlKCk7CisgIGF1dG8gdkFyciA9IHYtPkdldEJvb2xlYW5BcnJheSgpOworICBpbnQgKmFyciA9IHN0YXRpY19jYXN0PGludCAqPihzdGQ6Om1hbGxvYyh2QXJyLnNpemUoKSAqIHNpemVvZihpbnQpKSk7CisgICphcnJfc2l6ZSA9IHZBcnIuc2l6ZSgpOworICBzdGQ6OmNvcHkodkFyci5iZWdpbigpLCB2QXJyLmVuZCgpLCBhcnIpOworICByZXR1cm4gYXJyOworfQorCitkb3VibGUgKk5UX0dldEVudHJ5RG91YmxlQXJyYXkoY29uc3QgY2hhciAqbmFtZSwgc2l6ZV90IG5hbWVfbGVuLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVuc2lnbmVkIGxvbmcgbG9uZyAqbGFzdF9jaGFuZ2UsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2l6ZV90ICphcnJfc2l6ZSkgeworICBhdXRvIHYgPSBudDo6R2V0RW50cnlWYWx1ZShTdHJpbmdSZWYobmFtZSwgbmFtZV9sZW4pKTsKKyAgaWYgKCF2IHx8ICF2LT5Jc0RvdWJsZUFycmF5KCkpIHJldHVybiBudWxscHRyOworICAqbGFzdF9jaGFuZ2UgPSB2LT5sYXN0X2NoYW5nZSgpOworICBhdXRvIHZBcnIgPSB2LT5HZXREb3VibGVBcnJheSgpOworICBkb3VibGUgKmFyciA9CisgICAgICBzdGF0aWNfY2FzdDxkb3VibGUgKj4oc3RkOjptYWxsb2ModkFyci5zaXplKCkgKiBzaXplb2YoZG91YmxlKSkpOworICAqYXJyX3NpemUgPSB2QXJyLnNpemUoKTsKKyAgc3RkOjpjb3B5KHZBcnIuYmVnaW4oKSwgdkFyci5lbmQoKSwgYXJyKTsKKyAgcmV0dXJuIGFycjsKK30KKworTlRfU3RyaW5nICpOVF9HZXRFbnRyeVN0cmluZ0FycmF5KGNvbnN0IGNoYXIgKm5hbWUsIHNpemVfdCBuYW1lX2xlbiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB1bnNpZ25lZCBsb25nIGxvbmcgKmxhc3RfY2hhbmdlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNpemVfdCAqYXJyX3NpemUpIHsKKyAgYXV0byB2ID0gbnQ6OkdldEVudHJ5VmFsdWUoU3RyaW5nUmVmKG5hbWUsIG5hbWVfbGVuKSk7CisgIGlmICghdiB8fCAhdi0+SXNTdHJpbmdBcnJheSgpKSByZXR1cm4gbnVsbHB0cjsKKyAgKmxhc3RfY2hhbmdlID0gdi0+bGFzdF9jaGFuZ2UoKTsKKyAgYXV0byB2QXJyID0gdi0+R2V0U3RyaW5nQXJyYXkoKTsKKyAgTlRfU3RyaW5nICphcnIgPQorICAgICAgc3RhdGljX2Nhc3Q8TlRfU3RyaW5nICo+KHN0ZDo6bWFsbG9jKHZBcnIuc2l6ZSgpICogc2l6ZW9mKE5UX1N0cmluZykpKTsKKyAgZm9yIChzaXplX3QgaSA9IDA7IGkgPCB2QXJyLnNpemUoKTsgKytpKSB7CisgICAgQ29udmVydFRvQyh2QXJyW2ldLCAmYXJyW2ldKTsKKyAgfQorICAqYXJyX3NpemUgPSB2QXJyLnNpemUoKTsKKyAgcmV0dXJuIGFycjsKK30KKworfSAgLy8gZXh0ZXJuICJDIgpkaWZmIC0tZ2l0IGEvc3JjL250Y29yZV9jcHAuY3BwIGIvc3JjL250Y29yZV9jcHAuY3BwCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmM1MGIzZDQKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvbnRjb3JlX2NwcC5jcHAKQEAgLTAsMCArMSwyNzcgQEAKKy8qLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovCisvKiBDb3B5cmlnaHQgKGMpIEZJUlNUIDIwMTUuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqLworLyogT3BlbiBTb3VyY2UgU29mdHdhcmUgLSBtYXkgYmUgbW9kaWZpZWQgYW5kIHNoYXJlZCBieSBGUkMgdGVhbXMuIFRoZSBjb2RlICAgKi8KKy8qIG11c3QgYmUgYWNjb21wYW5pZWQgYnkgdGhlIEZJUlNUIEJTRCBsaWNlbnNlIGZpbGUgaW4gdGhlIHJvb3QgZGlyZWN0b3J5IG9mICovCisvKiB0aGUgcHJvamVjdC4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqLworLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi8KKworI2luY2x1ZGUgIm50Y29yZS5oIgorCisjaW5jbHVkZSA8Y2Fzc2VydD4KKyNpbmNsdWRlIDxjc3RkaW8+CisjaW5jbHVkZSA8Y3N0ZGxpYj4KKworI2luY2x1ZGUgIkRpc3BhdGNoZXIuaCIKKyNpbmNsdWRlICJMb2cuaCIKKyNpbmNsdWRlICJOb3RpZmllci5oIgorI2luY2x1ZGUgIlJwY1NlcnZlci5oIgorI2luY2x1ZGUgIlN0b3JhZ2UuaCIKKyNpbmNsdWRlICJXaXJlRGVjb2Rlci5oIgorI2luY2x1ZGUgIldpcmVFbmNvZGVyLmgiCisKK25hbWVzcGFjZSBudCB7CisKKy8qCisgKiBUYWJsZSBGdW5jdGlvbnMKKyAqLworCitzdGQ6OnNoYXJlZF9wdHI8VmFsdWU+IEdldEVudHJ5VmFsdWUoU3RyaW5nUmVmIG5hbWUpIHsKKyAgcmV0dXJuIFN0b3JhZ2U6OkdldEluc3RhbmNlKCkuR2V0RW50cnlWYWx1ZShuYW1lKTsKK30KKworYm9vbCBTZXRFbnRyeVZhbHVlKFN0cmluZ1JlZiBuYW1lLCBzdGQ6OnNoYXJlZF9wdHI8VmFsdWU+IHZhbHVlKSB7CisgIHJldHVybiBTdG9yYWdlOjpHZXRJbnN0YW5jZSgpLlNldEVudHJ5VmFsdWUobmFtZSwgdmFsdWUpOworfQorCit2b2lkIFNldEVudHJ5VHlwZVZhbHVlKFN0cmluZ1JlZiBuYW1lLCBzdGQ6OnNoYXJlZF9wdHI8VmFsdWU+IHZhbHVlKSB7CisgIFN0b3JhZ2U6OkdldEluc3RhbmNlKCkuU2V0RW50cnlUeXBlVmFsdWUobmFtZSwgdmFsdWUpOworfQorCit2b2lkIFNldEVudHJ5RmxhZ3MoU3RyaW5nUmVmIG5hbWUsIHVuc2lnbmVkIGludCBmbGFncykgeworICBTdG9yYWdlOjpHZXRJbnN0YW5jZSgpLlNldEVudHJ5RmxhZ3MobmFtZSwgZmxhZ3MpOworfQorCit1bnNpZ25lZCBpbnQgR2V0RW50cnlGbGFncyhTdHJpbmdSZWYgbmFtZSkgeworICByZXR1cm4gU3RvcmFnZTo6R2V0SW5zdGFuY2UoKS5HZXRFbnRyeUZsYWdzKG5hbWUpOworfQorCit2b2lkIERlbGV0ZUVudHJ5KFN0cmluZ1JlZiBuYW1lKSB7CisgIFN0b3JhZ2U6OkdldEluc3RhbmNlKCkuRGVsZXRlRW50cnkobmFtZSk7Cit9CisKK3ZvaWQgRGVsZXRlQWxsRW50cmllcygpIHsKKyAgU3RvcmFnZTo6R2V0SW5zdGFuY2UoKS5EZWxldGVBbGxFbnRyaWVzKCk7Cit9CisKK3N0ZDo6dmVjdG9yPEVudHJ5SW5mbz4gR2V0RW50cnlJbmZvKFN0cmluZ1JlZiBwcmVmaXgsIHVuc2lnbmVkIGludCB0eXBlcykgeworICByZXR1cm4gU3RvcmFnZTo6R2V0SW5zdGFuY2UoKS5HZXRFbnRyeUluZm8ocHJlZml4LCB0eXBlcyk7Cit9CisKK3ZvaWQgRmx1c2goKSB7CisgIERpc3BhdGNoZXI6OkdldEluc3RhbmNlKCkuRmx1c2goKTsKK30KKworLyoKKyAqIENhbGxiYWNrIENyZWF0aW9uIEZ1bmN0aW9ucworICovCisKK3ZvaWQgU2V0TGlzdGVuZXJPblN0YXJ0KHN0ZDo6ZnVuY3Rpb248dm9pZCgpPiBvbl9zdGFydCkgeworICBOb3RpZmllcjo6R2V0SW5zdGFuY2UoKS5TZXRPblN0YXJ0KG9uX3N0YXJ0KTsKK30KKwordm9pZCBTZXRMaXN0ZW5lck9uRXhpdChzdGQ6OmZ1bmN0aW9uPHZvaWQoKT4gb25fZXhpdCkgeworICBOb3RpZmllcjo6R2V0SW5zdGFuY2UoKS5TZXRPbkV4aXQob25fZXhpdCk7Cit9CisKK3Vuc2lnbmVkIGludCBBZGRFbnRyeUxpc3RlbmVyKFN0cmluZ1JlZiBwcmVmaXgsIEVudHJ5TGlzdGVuZXJDYWxsYmFjayBjYWxsYmFjaywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVuc2lnbmVkIGludCBmbGFncykgeworICBOb3RpZmllciYgbm90aWZpZXIgPSBOb3RpZmllcjo6R2V0SW5zdGFuY2UoKTsKKyAgdW5zaWduZWQgaW50IHVpZCA9IG5vdGlmaWVyLkFkZEVudHJ5TGlzdGVuZXIocHJlZml4LCBjYWxsYmFjaywgZmxhZ3MpOworICBub3RpZmllci5TdGFydCgpOworICBpZiAoKGZsYWdzICYgTlRfTk9USUZZX0lNTUVESUFURSkgIT0gMCkKKyAgICBTdG9yYWdlOjpHZXRJbnN0YW5jZSgpLk5vdGlmeUVudHJpZXMocHJlZml4LCBjYWxsYmFjayk7CisgIHJldHVybiB1aWQ7Cit9CisKK3ZvaWQgUmVtb3ZlRW50cnlMaXN0ZW5lcih1bnNpZ25lZCBpbnQgZW50cnlfbGlzdGVuZXJfdWlkKSB7CisgIE5vdGlmaWVyOjpHZXRJbnN0YW5jZSgpLlJlbW92ZUVudHJ5TGlzdGVuZXIoZW50cnlfbGlzdGVuZXJfdWlkKTsKK30KKwordW5zaWduZWQgaW50IEFkZENvbm5lY3Rpb25MaXN0ZW5lcihDb25uZWN0aW9uTGlzdGVuZXJDYWxsYmFjayBjYWxsYmFjaywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYm9vbCBpbW1lZGlhdGVfbm90aWZ5KSB7CisgIE5vdGlmaWVyJiBub3RpZmllciA9IE5vdGlmaWVyOjpHZXRJbnN0YW5jZSgpOworICB1bnNpZ25lZCBpbnQgdWlkID0gbm90aWZpZXIuQWRkQ29ubmVjdGlvbkxpc3RlbmVyKGNhbGxiYWNrKTsKKyAgTm90aWZpZXI6OkdldEluc3RhbmNlKCkuU3RhcnQoKTsKKyAgaWYgKGltbWVkaWF0ZV9ub3RpZnkpIERpc3BhdGNoZXI6OkdldEluc3RhbmNlKCkuTm90aWZ5Q29ubmVjdGlvbnMoY2FsbGJhY2spOworICByZXR1cm4gdWlkOworfQorCit2b2lkIFJlbW92ZUNvbm5lY3Rpb25MaXN0ZW5lcih1bnNpZ25lZCBpbnQgY29ubl9saXN0ZW5lcl91aWQpIHsKKyAgTm90aWZpZXI6OkdldEluc3RhbmNlKCkuUmVtb3ZlQ29ubmVjdGlvbkxpc3RlbmVyKGNvbm5fbGlzdGVuZXJfdWlkKTsKK30KKworYm9vbCBOb3RpZmllckRlc3Ryb3llZCgpIHsgcmV0dXJuIE5vdGlmaWVyOjpkZXN0cm95ZWQoKTsgfQorCisvKgorICogUmVtb3RlIFByb2NlZHVyZSBDYWxsIEZ1bmN0aW9ucworICovCisKK3ZvaWQgQ3JlYXRlUnBjKFN0cmluZ1JlZiBuYW1lLCBTdHJpbmdSZWYgZGVmLCBScGNDYWxsYmFjayBjYWxsYmFjaykgeworICBTdG9yYWdlOjpHZXRJbnN0YW5jZSgpLkNyZWF0ZVJwYyhuYW1lLCBkZWYsIGNhbGxiYWNrKTsKK30KKwordm9pZCBDcmVhdGVQb2xsZWRScGMoU3RyaW5nUmVmIG5hbWUsIFN0cmluZ1JlZiBkZWYpIHsKKyAgU3RvcmFnZTo6R2V0SW5zdGFuY2UoKS5DcmVhdGVQb2xsZWRScGMobmFtZSwgZGVmKTsKK30KKworYm9vbCBQb2xsUnBjKGJvb2wgYmxvY2tpbmcsIFJwY0NhbGxJbmZvKiBjYWxsX2luZm8pIHsKKyAgcmV0dXJuIFJwY1NlcnZlcjo6R2V0SW5zdGFuY2UoKS5Qb2xsUnBjKGJsb2NraW5nLCBjYWxsX2luZm8pOworfQorCit2b2lkIFBvc3RScGNSZXNwb25zZSh1bnNpZ25lZCBpbnQgcnBjX2lkLCB1bnNpZ25lZCBpbnQgY2FsbF91aWQsCisgICAgICAgICAgICAgICAgICAgICBTdHJpbmdSZWYgcmVzdWx0KSB7CisgIFJwY1NlcnZlcjo6R2V0SW5zdGFuY2UoKS5Qb3N0UnBjUmVzcG9uc2UocnBjX2lkLCBjYWxsX3VpZCwgcmVzdWx0KTsKK30KKwordW5zaWduZWQgaW50IENhbGxScGMoU3RyaW5nUmVmIG5hbWUsIFN0cmluZ1JlZiBwYXJhbXMpIHsKKyAgcmV0dXJuIFN0b3JhZ2U6OkdldEluc3RhbmNlKCkuQ2FsbFJwYyhuYW1lLCBwYXJhbXMpOworfQorCitib29sIEdldFJwY1Jlc3VsdChib29sIGJsb2NraW5nLCB1bnNpZ25lZCBpbnQgY2FsbF91aWQsIHN0ZDo6c3RyaW5nKiByZXN1bHQpIHsKKyAgcmV0dXJuIFN0b3JhZ2U6OkdldEluc3RhbmNlKCkuR2V0UnBjUmVzdWx0KGJsb2NraW5nLCBjYWxsX3VpZCwgcmVzdWx0KTsKK30KKworc3RkOjpzdHJpbmcgUGFja1JwY0RlZmluaXRpb24oY29uc3QgUnBjRGVmaW5pdGlvbiYgZGVmKSB7CisgIFdpcmVFbmNvZGVyIGVuYygweDAzMDApOworICBlbmMuV3JpdGU4KGRlZi52ZXJzaW9uKTsKKyAgZW5jLldyaXRlU3RyaW5nKGRlZi5uYW1lKTsKKworICAvLyBwYXJhbWV0ZXJzCisgIHVuc2lnbmVkIGludCBwYXJhbXNfc2l6ZSA9IGRlZi5wYXJhbXMuc2l6ZSgpOworICBpZiAocGFyYW1zX3NpemUgPiAweGZmKSBwYXJhbXNfc2l6ZSA9IDB4ZmY7CisgIGVuYy5Xcml0ZTgocGFyYW1zX3NpemUpOworICBmb3IgKHN0ZDo6c2l6ZV90IGkgPSAwOyBpIDwgcGFyYW1zX3NpemU7ICsraSkgeworICAgIGVuYy5Xcml0ZVR5cGUoZGVmLnBhcmFtc1tpXS5kZWZfdmFsdWUtPnR5cGUoKSk7CisgICAgZW5jLldyaXRlU3RyaW5nKGRlZi5wYXJhbXNbaV0ubmFtZSk7CisgICAgZW5jLldyaXRlVmFsdWUoKmRlZi5wYXJhbXNbaV0uZGVmX3ZhbHVlKTsKKyAgfQorCisgIC8vIHJlc3VsdHMKKyAgdW5zaWduZWQgaW50IHJlc3VsdHNfc2l6ZSA9IGRlZi5yZXN1bHRzLnNpemUoKTsKKyAgaWYgKHJlc3VsdHNfc2l6ZSA+IDB4ZmYpIHJlc3VsdHNfc2l6ZSA9IDB4ZmY7CisgIGVuYy5Xcml0ZTgocmVzdWx0c19zaXplKTsKKyAgZm9yIChzdGQ6OnNpemVfdCBpID0gMDsgaSA8IHJlc3VsdHNfc2l6ZTsgKytpKSB7CisgICAgZW5jLldyaXRlVHlwZShkZWYucmVzdWx0c1tpXS50eXBlKTsKKyAgICBlbmMuV3JpdGVTdHJpbmcoZGVmLnJlc3VsdHNbaV0ubmFtZSk7CisgIH0KKworICByZXR1cm4gZW5jLlRvU3RyaW5nUmVmKCk7Cit9CisKK2Jvb2wgVW5wYWNrUnBjRGVmaW5pdGlvbihTdHJpbmdSZWYgcGFja2VkLCBScGNEZWZpbml0aW9uKiBkZWYpIHsKKyAgcmF3X21lbV9pc3RyZWFtIGlzKHBhY2tlZC5kYXRhKCksIHBhY2tlZC5zaXplKCkpOworICBXaXJlRGVjb2RlciBkZWMoaXMsIDB4MDMwMCk7CisgIGlmICghZGVjLlJlYWQ4KCZkZWYtPnZlcnNpb24pKSByZXR1cm4gZmFsc2U7CisgIGlmICghZGVjLlJlYWRTdHJpbmcoJmRlZi0+bmFtZSkpIHJldHVybiBmYWxzZTsKKworICAvLyBwYXJhbWV0ZXJzCisgIHVuc2lnbmVkIGludCBwYXJhbXNfc2l6ZTsKKyAgaWYgKCFkZWMuUmVhZDgoJnBhcmFtc19zaXplKSkgcmV0dXJuIGZhbHNlOworICBkZWYtPnBhcmFtcy5yZXNpemUoMCk7CisgIGRlZi0+cGFyYW1zLnJlc2VydmUocGFyYW1zX3NpemUpOworICBmb3IgKHN0ZDo6c2l6ZV90IGkgPSAwOyBpIDwgcGFyYW1zX3NpemU7ICsraSkgeworICAgIFJwY1BhcmFtRGVmIHBkZWY7CisgICAgTlRfVHlwZSB0eXBlOworICAgIGlmICghZGVjLlJlYWRUeXBlKCZ0eXBlKSkgcmV0dXJuIGZhbHNlOworICAgIGlmICghZGVjLlJlYWRTdHJpbmcoJnBkZWYubmFtZSkpIHJldHVybiBmYWxzZTsKKyAgICBwZGVmLmRlZl92YWx1ZSA9IGRlYy5SZWFkVmFsdWUodHlwZSk7CisgICAgaWYgKCFwZGVmLmRlZl92YWx1ZSkgcmV0dXJuIGZhbHNlOworICAgIGRlZi0+cGFyYW1zLmVtcGxhY2VfYmFjayhzdGQ6Om1vdmUocGRlZikpOworICB9CisKKyAgLy8gcmVzdWx0cworICB1bnNpZ25lZCBpbnQgcmVzdWx0c19zaXplOworICBpZiAoIWRlYy5SZWFkOCgmcmVzdWx0c19zaXplKSkgcmV0dXJuIGZhbHNlOworICBkZWYtPnJlc3VsdHMucmVzaXplKDApOworICBkZWYtPnJlc3VsdHMucmVzZXJ2ZShyZXN1bHRzX3NpemUpOworICBmb3IgKHN0ZDo6c2l6ZV90IGkgPSAwOyBpIDwgcmVzdWx0c19zaXplOyArK2kpIHsKKyAgICBScGNSZXN1bHREZWYgcmRlZjsKKyAgICBpZiAoIWRlYy5SZWFkVHlwZSgmcmRlZi50eXBlKSkgcmV0dXJuIGZhbHNlOworICAgIGlmICghZGVjLlJlYWRTdHJpbmcoJnJkZWYubmFtZSkpIHJldHVybiBmYWxzZTsKKyAgICBkZWYtPnJlc3VsdHMuZW1wbGFjZV9iYWNrKHN0ZDo6bW92ZShyZGVmKSk7CisgIH0KKworICByZXR1cm4gdHJ1ZTsKK30KKworc3RkOjpzdHJpbmcgUGFja1JwY1ZhbHVlcyhBcnJheVJlZjxzdGQ6OnNoYXJlZF9wdHI8VmFsdWU+PiB2YWx1ZXMpIHsKKyAgV2lyZUVuY29kZXIgZW5jKDB4MDMwMCk7CisgIGZvciAoYXV0byYgdmFsdWUgOiB2YWx1ZXMpIGVuYy5Xcml0ZVZhbHVlKCp2YWx1ZSk7CisgIHJldHVybiBlbmMuVG9TdHJpbmdSZWYoKTsKK30KKworc3RkOjp2ZWN0b3I8c3RkOjpzaGFyZWRfcHRyPFZhbHVlPj4gVW5wYWNrUnBjVmFsdWVzKFN0cmluZ1JlZiBwYWNrZWQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQXJyYXlSZWY8TlRfVHlwZT4gdHlwZXMpIHsKKyAgcmF3X21lbV9pc3RyZWFtIGlzKHBhY2tlZC5kYXRhKCksIHBhY2tlZC5zaXplKCkpOworICBXaXJlRGVjb2RlciBkZWMoaXMsIDB4MDMwMCk7CisgIHN0ZDo6dmVjdG9yPHN0ZDo6c2hhcmVkX3B0cjxWYWx1ZT4+IHZlYzsKKyAgZm9yIChhdXRvIHR5cGUgOiB0eXBlcykgeworICAgIGF1dG8gaXRlbSA9IGRlYy5SZWFkVmFsdWUodHlwZSk7CisgICAgaWYgKCFpdGVtKSByZXR1cm4gc3RkOjp2ZWN0b3I8c3RkOjpzaGFyZWRfcHRyPFZhbHVlPj4oKTsKKyAgICB2ZWMuZW1wbGFjZV9iYWNrKHN0ZDo6bW92ZShpdGVtKSk7CisgIH0KKyAgcmV0dXJuIHZlYzsKK30KKworLyoKKyAqIENsaWVudC9TZXJ2ZXIgRnVuY3Rpb25zCisgKi8KKwordm9pZCBTZXROZXR3b3JrSWRlbnRpdHkoU3RyaW5nUmVmIG5hbWUpIHsKKyAgRGlzcGF0Y2hlcjo6R2V0SW5zdGFuY2UoKS5TZXRJZGVudGl0eShuYW1lKTsKK30KKwordm9pZCBTdGFydFNlcnZlcihTdHJpbmdSZWYgcGVyc2lzdF9maWxlbmFtZSwgY29uc3QgY2hhciAqbGlzdGVuX2FkZHJlc3MsCisgICAgICAgICAgICAgICAgIHVuc2lnbmVkIGludCBwb3J0KSB7CisgIERpc3BhdGNoZXI6OkdldEluc3RhbmNlKCkuU3RhcnRTZXJ2ZXIocGVyc2lzdF9maWxlbmFtZSwgbGlzdGVuX2FkZHJlc3MsIHBvcnQpOworfQorCit2b2lkIFN0b3BTZXJ2ZXIoKSB7CisgIERpc3BhdGNoZXI6OkdldEluc3RhbmNlKCkuU3RvcCgpOworfQorCit2b2lkIFN0YXJ0Q2xpZW50KGNvbnN0IGNoYXIgKnNlcnZlcl9uYW1lLCB1bnNpZ25lZCBpbnQgcG9ydCkgeworICBEaXNwYXRjaGVyOjpHZXRJbnN0YW5jZSgpLlN0YXJ0Q2xpZW50KHNlcnZlcl9uYW1lLCBwb3J0KTsKK30KKwordm9pZCBTdG9wQ2xpZW50KCkgeworICBEaXNwYXRjaGVyOjpHZXRJbnN0YW5jZSgpLlN0b3AoKTsKK30KKwordm9pZCBTdG9wUnBjU2VydmVyKCkgeworICBScGNTZXJ2ZXI6OkdldEluc3RhbmNlKCkuU3RvcCgpOworfQorCit2b2lkIFN0b3BOb3RpZmllcigpIHsKKyAgTm90aWZpZXI6OkdldEluc3RhbmNlKCkuU3RvcCgpOworfQorCit2b2lkIFNldFVwZGF0ZVJhdGUoZG91YmxlIGludGVydmFsKSB7CisgIERpc3BhdGNoZXI6OkdldEluc3RhbmNlKCkuU2V0VXBkYXRlUmF0ZShpbnRlcnZhbCk7Cit9CisKK3N0ZDo6dmVjdG9yPENvbm5lY3Rpb25JbmZvPiBHZXRDb25uZWN0aW9ucygpIHsKKyAgcmV0dXJuIERpc3BhdGNoZXI6OkdldEluc3RhbmNlKCkuR2V0Q29ubmVjdGlvbnMoKTsKK30KKworLyoKKyAqIFBlcnNpc3RlbnQgRnVuY3Rpb25zCisgKi8KKworY29uc3QgY2hhciogU2F2ZVBlcnNpc3RlbnQoU3RyaW5nUmVmIGZpbGVuYW1lKSB7CisgIHJldHVybiBTdG9yYWdlOjpHZXRJbnN0YW5jZSgpLlNhdmVQZXJzaXN0ZW50KGZpbGVuYW1lLCBmYWxzZSk7Cit9CisKK2NvbnN0IGNoYXIqIExvYWRQZXJzaXN0ZW50KAorICAgIFN0cmluZ1JlZiBmaWxlbmFtZSwKKyAgICBzdGQ6OmZ1bmN0aW9uPHZvaWQoc2l6ZV90IGxpbmUsIGNvbnN0IGNoYXIqIG1zZyk+IHdhcm4pIHsKKyAgcmV0dXJuIFN0b3JhZ2U6OkdldEluc3RhbmNlKCkuTG9hZFBlcnNpc3RlbnQoZmlsZW5hbWUsIHdhcm4pOworfQorCit2b2lkIFNldExvZ2dlcihMb2dGdW5jIGZ1bmMsIHVuc2lnbmVkIGludCBtaW5fbGV2ZWwpIHsKKyAgTG9nZ2VyJiBsb2dnZXIgPSBMb2dnZXI6OkdldEluc3RhbmNlKCk7CisgIGxvZ2dlci5TZXRMb2dnZXIoZnVuYyk7CisgIGxvZ2dlci5zZXRfbWluX2xldmVsKG1pbl9sZXZlbCk7Cit9CisKK30gIC8vIG5hbWVzcGFjZSBudApkaWZmIC0tZ2l0IGEvc3JjL3Jhd19pc3RyZWFtLmNwcCBiL3NyYy9yYXdfaXN0cmVhbS5jcHAKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZjMwMGI5ZQotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9yYXdfaXN0cmVhbS5jcHAKQEAgLTAsMCArMSwyMCBAQAorLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi8KKy8qIENvcHlyaWdodCAoYykgRklSU1QgMjAxNS4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICovCisvKiBPcGVuIFNvdXJjZSBTb2Z0d2FyZSAtIG1heSBiZSBtb2RpZmllZCBhbmQgc2hhcmVkIGJ5IEZSQyB0ZWFtcy4gVGhlIGNvZGUgICAqLworLyogbXVzdCBiZSBhY2NvbXBhbmllZCBieSB0aGUgRklSU1QgQlNEIGxpY2Vuc2UgZmlsZSBpbiB0aGUgcm9vdCBkaXJlY3Rvcnkgb2YgKi8KKy8qIHRoZSBwcm9qZWN0LiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICovCisvKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qLworCisjaW5jbHVkZSAicmF3X2lzdHJlYW0uaCIKKworI2luY2x1ZGUgPGNzdHJpbmc+CisKK3VzaW5nIG5hbWVzcGFjZSBudDsKKworYm9vbCByYXdfbWVtX2lzdHJlYW06OnJlYWQodm9pZCogZGF0YSwgc3RkOjpzaXplX3QgbGVuKSB7CisgIGlmIChsZW4gPiBtX2xlZnQpIHJldHVybiBmYWxzZTsKKyAgc3RkOjptZW1jcHkoZGF0YSwgbV9jdXIsIGxlbik7CisgIG1fY3VyICs9IGxlbjsKKyAgbV9sZWZ0IC09IGxlbjsKKyAgcmV0dXJuIHRydWU7Cit9CmRpZmYgLS1naXQgYS9zcmMvcmF3X2lzdHJlYW0uaCBiL3NyYy9yYXdfaXN0cmVhbS5oCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmY4YWRjMjMKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvcmF3X2lzdHJlYW0uaApAQCAtMCwwICsxLDQwIEBACisvKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qLworLyogQ29weXJpZ2h0IChjKSBGSVJTVCAyMDE1LiBBbGwgUmlnaHRzIFJlc2VydmVkLiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKi8KKy8qIE9wZW4gU291cmNlIFNvZnR3YXJlIC0gbWF5IGJlIG1vZGlmaWVkIGFuZCBzaGFyZWQgYnkgRlJDIHRlYW1zLiBUaGUgY29kZSAgICovCisvKiBtdXN0IGJlIGFjY29tcGFuaWVkIGJ5IHRoZSBGSVJTVCBCU0QgbGljZW5zZSBmaWxlIGluIHRoZSByb290IGRpcmVjdG9yeSBvZiAqLworLyogdGhlIHByb2plY3QuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKi8KKy8qLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovCisKKyNpZm5kZWYgTlRfUkFXX0lTVFJFQU1fSF8KKyNkZWZpbmUgTlRfUkFXX0lTVFJFQU1fSF8KKworI2luY2x1ZGUgPGNzdGRkZWY+CisKK25hbWVzcGFjZSBudCB7CisKK2NsYXNzIHJhd19pc3RyZWFtIHsKKyBwdWJsaWM6CisgIHJhd19pc3RyZWFtKCkgPSBkZWZhdWx0OworICB2aXJ0dWFsIH5yYXdfaXN0cmVhbSgpID0gZGVmYXVsdDsKKyAgdmlydHVhbCBib29sIHJlYWQodm9pZCogZGF0YSwgc3RkOjpzaXplX3QgbGVuKSA9IDA7CisgIHZpcnR1YWwgdm9pZCBjbG9zZSgpID0gMDsKKworICByYXdfaXN0cmVhbShjb25zdCByYXdfaXN0cmVhbSYpID0gZGVsZXRlOworICByYXdfaXN0cmVhbSYgb3BlcmF0b3I9KGNvbnN0IHJhd19pc3RyZWFtJikgPSBkZWxldGU7Cit9OworCitjbGFzcyByYXdfbWVtX2lzdHJlYW0gOiBwdWJsaWMgcmF3X2lzdHJlYW0geworIHB1YmxpYzoKKyAgcmF3X21lbV9pc3RyZWFtKGNvbnN0IGNoYXIqIG1lbSwgc3RkOjpzaXplX3QgbGVuKSA6IG1fY3VyKG1lbSksIG1fbGVmdChsZW4pIHt9CisgIHZpcnR1YWwgfnJhd19tZW1faXN0cmVhbSgpID0gZGVmYXVsdDsKKyAgdmlydHVhbCBib29sIHJlYWQodm9pZCogZGF0YSwgc3RkOjpzaXplX3QgbGVuKTsKKyAgdmlydHVhbCB2b2lkIGNsb3NlKCkge30KKworIHByaXZhdGU6CisgIGNvbnN0IGNoYXIqIG1fY3VyOworICBzdGQ6OnNpemVfdCBtX2xlZnQ7Cit9OworCit9ICAvLyBuYW1lc3BhY2UgbnQKKworI2VuZGlmICAvLyBOVF9SQVdfSVNUUkVBTV9IXwpkaWZmIC0tZ2l0IGEvc3JjL3Jhd19zb2NrZXRfaXN0cmVhbS5jcHAgYi9zcmMvcmF3X3NvY2tldF9pc3RyZWFtLmNwcApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5hOGU3MWM1Ci0tLSAvZGV2L251bGwKKysrIGIvc3JjL3Jhd19zb2NrZXRfaXN0cmVhbS5jcHAKQEAgLTAsMCArMSwyNiBAQAorLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi8KKy8qIENvcHlyaWdodCAoYykgRklSU1QgMjAxNS4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICovCisvKiBPcGVuIFNvdXJjZSBTb2Z0d2FyZSAtIG1heSBiZSBtb2RpZmllZCBhbmQgc2hhcmVkIGJ5IEZSQyB0ZWFtcy4gVGhlIGNvZGUgICAqLworLyogbXVzdCBiZSBhY2NvbXBhbmllZCBieSB0aGUgRklSU1QgQlNEIGxpY2Vuc2UgZmlsZSBpbiB0aGUgcm9vdCBkaXJlY3Rvcnkgb2YgKi8KKy8qIHRoZSBwcm9qZWN0LiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICovCisvKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qLworCisjaW5jbHVkZSAicmF3X3NvY2tldF9pc3RyZWFtLmgiCisKK3VzaW5nIG5hbWVzcGFjZSBudDsKKworYm9vbCByYXdfc29ja2V0X2lzdHJlYW06OnJlYWQodm9pZCogZGF0YSwgc3RkOjpzaXplX3QgbGVuKSB7CisgIGNoYXIqIGNkYXRhID0gc3RhdGljX2Nhc3Q8Y2hhcio+KGRhdGEpOworICBzdGQ6OnNpemVfdCBwb3MgPSAwOworCisgIHdoaWxlIChwb3MgPCBsZW4pIHsKKyAgICBOZXR3b3JrU3RyZWFtOjpFcnJvciBlcnI7CisgICAgc3RkOjpzaXplX3QgY291bnQgPQorICAgICAgICBtX3N0cmVhbS5yZWNlaXZlKCZjZGF0YVtwb3NdLCBsZW4gLSBwb3MsICZlcnIsIG1fdGltZW91dCk7CisgICAgaWYgKGNvdW50ID09IDApIHJldHVybiBmYWxzZTsKKyAgICBwb3MgKz0gY291bnQ7CisgIH0KKyAgcmV0dXJuIHRydWU7Cit9CisKK3ZvaWQgcmF3X3NvY2tldF9pc3RyZWFtOjpjbG9zZSgpIHsgbV9zdHJlYW0uY2xvc2UoKTsgfQpkaWZmIC0tZ2l0IGEvc3JjL3Jhd19zb2NrZXRfaXN0cmVhbS5oIGIvc3JjL3Jhd19zb2NrZXRfaXN0cmVhbS5oCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjkxYmNjMWYKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvcmF3X3NvY2tldF9pc3RyZWFtLmgKQEAgLTAsMCArMSwzMiBAQAorLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi8KKy8qIENvcHlyaWdodCAoYykgRklSU1QgMjAxNS4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICovCisvKiBPcGVuIFNvdXJjZSBTb2Z0d2FyZSAtIG1heSBiZSBtb2RpZmllZCBhbmQgc2hhcmVkIGJ5IEZSQyB0ZWFtcy4gVGhlIGNvZGUgICAqLworLyogbXVzdCBiZSBhY2NvbXBhbmllZCBieSB0aGUgRklSU1QgQlNEIGxpY2Vuc2UgZmlsZSBpbiB0aGUgcm9vdCBkaXJlY3Rvcnkgb2YgKi8KKy8qIHRoZSBwcm9qZWN0LiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICovCisvKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qLworCisjaWZuZGVmIE5UX1JBV19TT0NLRVRfSVNUUkVBTV9IXworI2RlZmluZSBOVF9SQVdfU09DS0VUX0lTVFJFQU1fSF8KKworI2luY2x1ZGUgInJhd19pc3RyZWFtLmgiCisKKyNpbmNsdWRlICJ0Y3Bzb2NrZXRzL05ldHdvcmtTdHJlYW0uaCIKKworbmFtZXNwYWNlIG50IHsKKworY2xhc3MgcmF3X3NvY2tldF9pc3RyZWFtIDogcHVibGljIHJhd19pc3RyZWFtIHsKKyBwdWJsaWM6CisgIHJhd19zb2NrZXRfaXN0cmVhbShOZXR3b3JrU3RyZWFtJiBzdHJlYW0sIGludCB0aW1lb3V0ID0gMCkKKyAgICAgIDogbV9zdHJlYW0oc3RyZWFtKSwgbV90aW1lb3V0KHRpbWVvdXQpIHt9CisgIHZpcnR1YWwgfnJhd19zb2NrZXRfaXN0cmVhbSgpID0gZGVmYXVsdDsKKyAgdmlydHVhbCBib29sIHJlYWQodm9pZCogZGF0YSwgc3RkOjpzaXplX3QgbGVuKTsKKyAgdmlydHVhbCB2b2lkIGNsb3NlKCk7CisKKyBwcml2YXRlOgorICBOZXR3b3JrU3RyZWFtJiBtX3N0cmVhbTsKKyAgaW50IG1fdGltZW91dDsKK307CisKK30gIC8vIG5hbWVzcGFjZSBudAorCisjZW5kaWYgIC8vIE5UX1JBV19TT0NLRVRfSVNUUkVBTV9IXwpkaWZmIC0tZ2l0IGEvc3JjL3N1cHBvcnQvQ29uY3VycmVudFF1ZXVlLmggYi9zcmMvc3VwcG9ydC9Db25jdXJyZW50UXVldWUuaApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5mYTk5NDc3Ci0tLSAvZGV2L251bGwKKysrIGIvc3JjL3N1cHBvcnQvQ29uY3VycmVudFF1ZXVlLmgKQEAgLTAsMCArMSw3OSBAQAorLy8KKy8vIENvcHlyaWdodCAoYykgMjAxMyBKdWFuIFBhbGFjaW9zIGp1YW4ucGFsYWNpb3MucHV5YW5hQGdtYWlsLmNvbQorLy8gU3ViamVjdCB0byB0aGUgQlNEIDItQ2xhdXNlIExpY2Vuc2UKKy8vIC0gc2VlIDwgaHR0cDovL29wZW5zb3VyY2Uub3JnL2xpY2Vuc2VzL0JTRC0yLUNsYXVzZT4KKy8vCisKKyNpZm5kZWYgTlRfU1VQUE9SVF9DT05DVVJSRU5UX1FVRVVFX0hfCisjZGVmaW5lIE5UX1NVUFBPUlRfQ09OQ1VSUkVOVF9RVUVVRV9IXworCisjaW5jbHVkZSA8cXVldWU+CisjaW5jbHVkZSA8dGhyZWFkPgorI2luY2x1ZGUgPG11dGV4PgorI2luY2x1ZGUgPGNvbmRpdGlvbl92YXJpYWJsZT4KKwordGVtcGxhdGUgPHR5cGVuYW1lIFQ+CitjbGFzcyBDb25jdXJyZW50UXVldWUgeworIHB1YmxpYzoKKyAgYm9vbCBlbXB0eSgpIGNvbnN0IHsKKyAgICBzdGQ6OnVuaXF1ZV9sb2NrPHN0ZDo6bXV0ZXg+IG1sb2NrKG11dGV4Xyk7CisgICAgcmV0dXJuIHF1ZXVlXy5lbXB0eSgpOworICB9CisKKyAgdHlwZW5hbWUgc3RkOjpxdWV1ZTxUPjo6c2l6ZV90eXBlIHNpemUoKSBjb25zdCB7CisgICAgc3RkOjp1bmlxdWVfbG9jazxzdGQ6Om11dGV4PiBtbG9jayhtdXRleF8pOworICAgIHJldHVybiBxdWV1ZV8uc2l6ZSgpOworICB9CisKKyAgVCBwb3AoKSB7CisgICAgc3RkOjp1bmlxdWVfbG9jazxzdGQ6Om11dGV4PiBtbG9jayhtdXRleF8pOworICAgIHdoaWxlIChxdWV1ZV8uZW1wdHkoKSkgeworICAgICAgY29uZF8ud2FpdChtbG9jayk7CisgICAgfQorICAgIGF1dG8gaXRlbSA9IHN0ZDo6bW92ZShxdWV1ZV8uZnJvbnQoKSk7CisgICAgcXVldWVfLnBvcCgpOworICAgIHJldHVybiBpdGVtOworICB9CisKKyAgdm9pZCBwb3AoVCYgaXRlbSkgeworICAgIHN0ZDo6dW5pcXVlX2xvY2s8c3RkOjptdXRleD4gbWxvY2sobXV0ZXhfKTsKKyAgICB3aGlsZSAocXVldWVfLmVtcHR5KCkpIHsKKyAgICAgIGNvbmRfLndhaXQobWxvY2spOworICAgIH0KKyAgICBpdGVtID0gcXVldWVfLmZyb250KCk7CisgICAgcXVldWVfLnBvcCgpOworICB9CisKKyAgdm9pZCBwdXNoKGNvbnN0IFQmIGl0ZW0pIHsKKyAgICBzdGQ6OnVuaXF1ZV9sb2NrPHN0ZDo6bXV0ZXg+IG1sb2NrKG11dGV4Xyk7CisgICAgcXVldWVfLnB1c2goaXRlbSk7CisgICAgbWxvY2sudW5sb2NrKCk7CisgICAgY29uZF8ubm90aWZ5X29uZSgpOworICB9CisKKyAgdm9pZCBwdXNoKFQmJiBpdGVtKSB7CisgICAgc3RkOjp1bmlxdWVfbG9jazxzdGQ6Om11dGV4PiBtbG9jayhtdXRleF8pOworICAgIHF1ZXVlXy5wdXNoKHN0ZDo6Zm9yd2FyZDxUPihpdGVtKSk7CisgICAgbWxvY2sudW5sb2NrKCk7CisgICAgY29uZF8ubm90aWZ5X29uZSgpOworICB9CisKKyAgdGVtcGxhdGUgPHR5cGVuYW1lLi4uIEFyZ3M+CisgIHZvaWQgZW1wbGFjZShBcmdzJiYuLi4gYXJncykgeworICAgIHN0ZDo6dW5pcXVlX2xvY2s8c3RkOjptdXRleD4gbWxvY2sobXV0ZXhfKTsKKyAgICBxdWV1ZV8uZW1wbGFjZShzdGQ6OmZvcndhcmQ8QXJncz4oYXJncykuLi4pOworICAgIG1sb2NrLnVubG9jaygpOworICAgIGNvbmRfLm5vdGlmeV9vbmUoKTsKKyAgfQorCisgIENvbmN1cnJlbnRRdWV1ZSgpID0gZGVmYXVsdDsKKyAgQ29uY3VycmVudFF1ZXVlKGNvbnN0IENvbmN1cnJlbnRRdWV1ZSYpID0gZGVsZXRlOworICBDb25jdXJyZW50UXVldWUmIG9wZXJhdG9yPShjb25zdCBDb25jdXJyZW50UXVldWUmKSA9IGRlbGV0ZTsKKworIHByaXZhdGU6CisgIHN0ZDo6cXVldWU8VD4gcXVldWVfOworICBtdXRhYmxlIHN0ZDo6bXV0ZXggbXV0ZXhfOworICBzdGQ6OmNvbmRpdGlvbl92YXJpYWJsZSBjb25kXzsKK307CisKKyNlbmRpZiAgLy8gTlRfU1VQUE9SVF9DT05DVVJSRU5UX1FVRVVFX0hfCmRpZmYgLS1naXQgYS9zcmMvc3VwcG9ydC90aW1lc3RhbXAuY3BwIGIvc3JjL3N1cHBvcnQvdGltZXN0YW1wLmNwcApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi42ZGQ0Mzg3Ci0tLSAvZGV2L251bGwKKysrIGIvc3JjL3N1cHBvcnQvdGltZXN0YW1wLmNwcApAQCAtMCwwICsxLDg5IEBACisvKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qLworLyogQ29weXJpZ2h0IChjKSBGSVJTVCAyMDE1LiBBbGwgUmlnaHRzIFJlc2VydmVkLiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKi8KKy8qIE9wZW4gU291cmNlIFNvZnR3YXJlIC0gbWF5IGJlIG1vZGlmaWVkIGFuZCBzaGFyZWQgYnkgRlJDIHRlYW1zLiBUaGUgY29kZSAgICovCisvKiBtdXN0IGJlIGFjY29tcGFuaWVkIGJ5IHRoZSBGSVJTVCBCU0QgbGljZW5zZSBmaWxlIGluIHRoZSByb290IGRpcmVjdG9yeSBvZiAqLworLyogdGhlIHByb2plY3QuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKi8KKy8qLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovCisjaW5jbHVkZSAidGltZXN0YW1wLmgiCisKKyNpZmRlZiBfV0lOMzIKKyNpbmNsdWRlIDxjYXNzZXJ0PgorI2luY2x1ZGUgPGV4Y2VwdGlvbj4KKyNpbmNsdWRlIDx3aW5kb3dzLmg+CisjZWxzZQorI2luY2x1ZGUgPGNocm9ubz4KKyNlbmRpZgorCisvLyBvZmZzZXQgaW4gbWljcm9zZWNvbmRzCitzdGF0aWMgdW5zaWduZWQgbG9uZyBsb25nIHplcm90aW1lKCkgeworI2lmZGVmIF9XSU4zMgorICBGSUxFVElNRSBmdDsKKyAgdW5zaWduZWQgbG9uZyBsb25nIHRtcHJlcyA9IDA7CisgIC8vIDEwMC1uYW5vc2Vjb25kIGludGVydmFscyBzaW5jZSBKYW51YXJ5IDEsIDE2MDEgKFVUQykKKyAgLy8gd2hpY2ggbWVhbnMgMC4xIHVzCisgIEdldFN5c3RlbVRpbWVBc0ZpbGVUaW1lKCZmdCk7CisgIHRtcHJlcyB8PSBmdC5kd0hpZ2hEYXRlVGltZTsKKyAgdG1wcmVzIDw8PSAzMjsKKyAgdG1wcmVzIHw9IGZ0LmR3TG93RGF0ZVRpbWU7CisgIC8vIEphbnVhcnkgMXN0LCAxOTcwIC0gSmFudWFyeSAxc3QsIDE2MDEgVVRDIH4gMzY5IHllYXJzCisgIC8vIG9yIDExNjQ0NDczNjAwMDAwMDAwMCB1cworICBzdGF0aWMgY29uc3QgdW5zaWduZWQgbG9uZyBsb25nIGRlbHRhZXBvY2ggPSAxMTY0NDQ3MzYwMDAwMDAwMDB1bGw7CisgIHRtcHJlcyAtPSBkZWx0YWVwb2NoOworICByZXR1cm4gdG1wcmVzOworI2Vsc2UKKyAgLy8gMTAwLW5zIGludGVydmFscworICB1c2luZyBuYW1lc3BhY2Ugc3RkOjpjaHJvbm87CisgIHJldHVybiBkdXJhdGlvbl9jYXN0PG5hbm9zZWNvbmRzPigKKyAgICBoaWdoX3Jlc29sdXRpb25fY2xvY2s6Om5vdygpLnRpbWVfc2luY2VfZXBvY2goKSkuY291bnQoKSAvIDEwMHU7CisjZW5kaWYKK30KKworc3RhdGljIHVuc2lnbmVkIGxvbmcgbG9uZyB0aW1lc3RhbXAoKSB7CisjaWZkZWYgX1dJTjMyCisgIExBUkdFX0lOVEVHRVIgbGk7CisgIFF1ZXJ5UGVyZm9ybWFuY2VDb3VudGVyKCZsaSk7CisgIC8vIHRoZXJlIGlzIGFuIGltcHJlY2lzaW9uIHdpdGggdGhlIGluaXRpYWwgdmFsdWUsCisgIC8vIGJ1dCB3aGF0IG1hdHRlcnMgaXMgdGhhdCB0aW1lc3RhbXBzIGFyZSBtb25vdG9uaWMgYW5kIGNvbnNpc3RlbnQKKyAgcmV0dXJuIHN0YXRpY19jYXN0PHVuc2lnbmVkIGxvbmcgbG9uZz4obGkuUXVhZFBhcnQpOworI2Vsc2UKKyAgLy8gMTAwLW5zIGludGVydmFscworICB1c2luZyBuYW1lc3BhY2Ugc3RkOjpjaHJvbm87CisgIHJldHVybiBkdXJhdGlvbl9jYXN0PG5hbm9zZWNvbmRzPigKKyAgICBzdGVhZHlfY2xvY2s6Om5vdygpLnRpbWVfc2luY2VfZXBvY2goKSkuY291bnQoKSAvIDEwMHU7CisjZW5kaWYKK30KKworI2lmZGVmIF9XSU4zMgorc3RhdGljIHVuc2lnbmVkIGxvbmcgbG9uZyB1cGRhdGVfZnJlcXVlbmN5KCkgeworICBMQVJHRV9JTlRFR0VSIGxpOworICBpZiAoIVF1ZXJ5UGVyZm9ybWFuY2VGcmVxdWVuY3koJmxpKSB8fCAhbGkuUXVhZFBhcnQpIHsKKyAgICAvLyBsb2cgc29tZXRoaW5nCisgICAgc3RkOjp0ZXJtaW5hdGUoKTsKKyAgfQorICByZXR1cm4gc3RhdGljX2Nhc3Q8dW5zaWduZWQgbG9uZyBsb25nPihsaS5RdWFkUGFydCk7Cit9CisjZW5kaWYKKworc3RhdGljIGNvbnN0IHVuc2lnbmVkIGxvbmcgbG9uZyB6ZXJvdGltZV92YWwgPSB6ZXJvdGltZSgpOworc3RhdGljIGNvbnN0IHVuc2lnbmVkIGxvbmcgbG9uZyBvZmZzZXRfdmFsID0gdGltZXN0YW1wKCk7CisjaWZkZWYgX1dJTjMyCitzdGF0aWMgY29uc3QgdW5zaWduZWQgbG9uZyBsb25nIGZyZXF1ZW5jeV92YWwgPSB1cGRhdGVfZnJlcXVlbmN5KCk7CisjZW5kaWYKKwordW5zaWduZWQgbG9uZyBsb25nIG50OjpOb3coKSB7CisjaWZkZWYgX1dJTjMyCisgIGFzc2VydChvZmZzZXRfdmFsID4gMHUpOworICBhc3NlcnQoZnJlcXVlbmN5X3ZhbCA+IDB1KTsKKyAgdW5zaWduZWQgbG9uZyBsb25nIGRlbHRhID0gdGltZXN0YW1wKCkgLSBvZmZzZXRfdmFsOworICAvLyBiZWNhdXNlIHRoZSBmcmVxdWVuY3kgaXMgaW4gdXBkYXRlIHBlciBzZWNvbmRzLCB3ZSBoYXZlIHRvIG11bHRpcGx5IHRoZQorICAvLyBkZWx0YSBieSAxMCwwMDAsMDAwCisgIHVuc2lnbmVkIGxvbmcgbG9uZyBkZWx0YV9pbl91cyA9IGRlbHRhICogMTAwMDAwMDB1bGwgLyBmcmVxdWVuY3lfdmFsOworICByZXR1cm4gZGVsdGFfaW5fdXMgKyB6ZXJvdGltZV92YWw7CisjZWxzZQorICByZXR1cm4gemVyb3RpbWVfdmFsICsgdGltZXN0YW1wKCkgLSBvZmZzZXRfdmFsOworI2VuZGlmCit9CisKK3Vuc2lnbmVkIGxvbmcgbG9uZyBOVF9Ob3coKSB7CisgIHJldHVybiBudDo6Tm93KCk7Cit9CmRpZmYgLS1naXQgYS9zcmMvc3VwcG9ydC90aW1lc3RhbXAuaCBiL3NyYy9zdXBwb3J0L3RpbWVzdGFtcC5oCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjIxNWFhODgKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvc3VwcG9ydC90aW1lc3RhbXAuaApAQCAtMCwwICsxLDI4IEBACisvKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qLworLyogQ29weXJpZ2h0IChjKSBGSVJTVCAyMDE1LiBBbGwgUmlnaHRzIFJlc2VydmVkLiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKi8KKy8qIE9wZW4gU291cmNlIFNvZnR3YXJlIC0gbWF5IGJlIG1vZGlmaWVkIGFuZCBzaGFyZWQgYnkgRlJDIHRlYW1zLiBUaGUgY29kZSAgICovCisvKiBtdXN0IGJlIGFjY29tcGFuaWVkIGJ5IHRoZSBGSVJTVCBCU0QgbGljZW5zZSBmaWxlIGluIHRoZSByb290IGRpcmVjdG9yeSBvZiAqLworLyogdGhlIHByb2plY3QuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKi8KKy8qLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovCisjaWZuZGVmIE5UX1NVUFBPUlRfVElNRVNUQU1QX0hfCisjZGVmaW5lIE5UX1NVUFBPUlRfVElNRVNUQU1QX0hfCisKKyNpZmRlZiBfX2NwbHVzcGx1cworZXh0ZXJuICJDIiB7CisjZW5kaWYKKwordW5zaWduZWQgbG9uZyBsb25nIE5UX05vdyh2b2lkKTsKKworI2lmZGVmIF9fY3BsdXNwbHVzCit9CisjZW5kaWYKKworI2lmZGVmIF9fY3BsdXNwbHVzCituYW1lc3BhY2UgbnQgeworCit1bnNpZ25lZCBsb25nIGxvbmcgTm93KCk7CisKK30gIC8vIG5hbWVzcGFjZSBudAorI2VuZGlmCisKKyNlbmRpZiAgLy8gTlRfU1VQUE9SVF9USU1FU1RBTVBfSF8KZGlmZiAtLWdpdCBhL3NyYy90YWJsZXMvSVRhYmxlTGlzdGVuZXIuY3BwIGIvc3JjL3RhYmxlcy9JVGFibGVMaXN0ZW5lci5jcHAKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZGYxZjI3MwotLS0gL2Rldi9udWxsCisrKyBiL3NyYy90YWJsZXMvSVRhYmxlTGlzdGVuZXIuY3BwCkBAIC0wLDAgKzEsOSBAQAorI2luY2x1ZGUgInRhYmxlcy9JVGFibGVMaXN0ZW5lci5oIgorCisjaW5jbHVkZSAibnRjb3JlX2MuaCIKKwordm9pZCBJVGFibGVMaXN0ZW5lcjo6VmFsdWVDaGFuZ2VkRXgoSVRhYmxlKiBzb3VyY2UsIGxsdm06OlN0cmluZ1JlZiBrZXksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdGQ6OnNoYXJlZF9wdHI8bnQ6OlZhbHVlPiB2YWx1ZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVuc2lnbmVkIGludCBmbGFncykgeworICBWYWx1ZUNoYW5nZWQoc291cmNlLCBrZXksIHZhbHVlLCAoZmxhZ3MgJiBOVF9OT1RJRllfTkVXKSAhPSAwKTsKK30KZGlmZiAtLWdpdCBhL3NyYy90YWJsZXMvVGFibGVLZXlOb3REZWZpbmVkRXhjZXB0aW9uLmNwcCBiL3NyYy90YWJsZXMvVGFibGVLZXlOb3REZWZpbmVkRXhjZXB0aW9uLmNwcApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4zMGJlZGQwCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL3RhYmxlcy9UYWJsZUtleU5vdERlZmluZWRFeGNlcHRpb24uY3BwCkBAIC0wLDAgKzEsMTkgQEAKKy8qLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovCisvKiBDb3B5cmlnaHQgKGMpIEZJUlNUIDIwMTUuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqLworLyogT3BlbiBTb3VyY2UgU29mdHdhcmUgLSBtYXkgYmUgbW9kaWZpZWQgYW5kIHNoYXJlZCBieSBGUkMgdGVhbXMuIFRoZSBjb2RlICAgKi8KKy8qIG11c3QgYmUgYWNjb21wYW5pZWQgYnkgdGhlIEZJUlNUIEJTRCBsaWNlbnNlIGZpbGUgaW4gdGhlIHJvb3QgZGlyZWN0b3J5IG9mICovCisvKiB0aGUgcHJvamVjdC4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqLworLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi8KKworI2luY2x1ZGUgInRhYmxlcy9UYWJsZUtleU5vdERlZmluZWRFeGNlcHRpb24uaCIKKworVGFibGVLZXlOb3REZWZpbmVkRXhjZXB0aW9uOjpUYWJsZUtleU5vdERlZmluZWRFeGNlcHRpb24obGx2bTo6U3RyaW5nUmVmIGtleSkKKyAgICA6IG1zZygiVW5rbm93biBUYWJsZSBLZXk6ICIpIHsKKyAgbXNnICs9IGtleTsKK30KKworY29uc3QgY2hhciogVGFibGVLZXlOb3REZWZpbmVkRXhjZXB0aW9uOjp3aGF0KCkgY29uc3QgTlRfTk9FWENFUFQgeworICByZXR1cm4gbXNnLmNfc3RyKCk7Cit9CisKK1RhYmxlS2V5Tm90RGVmaW5lZEV4Y2VwdGlvbjo6flRhYmxlS2V5Tm90RGVmaW5lZEV4Y2VwdGlvbigpIE5UX05PRVhDRVBUIHt9CmRpZmYgLS1naXQgYS9zcmMvdGNwc29ja2V0cy9OZXR3b3JrQWNjZXB0b3IuaCBiL3NyYy90Y3Bzb2NrZXRzL05ldHdvcmtBY2NlcHRvci5oCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjQ3MDJiN2YKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvdGNwc29ja2V0cy9OZXR3b3JrQWNjZXB0b3IuaApAQCAtMCwwICsxLDI2IEBACisvKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qLworLyogQ29weXJpZ2h0IChjKSBGSVJTVCAyMDE1LiBBbGwgUmlnaHRzIFJlc2VydmVkLiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKi8KKy8qIE9wZW4gU291cmNlIFNvZnR3YXJlIC0gbWF5IGJlIG1vZGlmaWVkIGFuZCBzaGFyZWQgYnkgRlJDIHRlYW1zLiBUaGUgY29kZSAgICovCisvKiBtdXN0IGJlIGFjY29tcGFuaWVkIGJ5IHRoZSBGSVJTVCBCU0QgbGljZW5zZSBmaWxlIGluIHRoZSByb290IGRpcmVjdG9yeSBvZiAqLworLyogdGhlIHByb2plY3QuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKi8KKy8qLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovCisKKyNpZm5kZWYgVENQU09DS0VUU19ORVRXT1JLQUNDRVBUT1JfSF8KKyNkZWZpbmUgVENQU09DS0VUU19ORVRXT1JLQUNDRVBUT1JfSF8KKworI2luY2x1ZGUgIk5ldHdvcmtTdHJlYW0uaCIKKworY2xhc3MgTmV0d29ya0FjY2VwdG9yIHsKKyBwdWJsaWM6CisgIE5ldHdvcmtBY2NlcHRvcigpID0gZGVmYXVsdDsKKyAgdmlydHVhbCB+TmV0d29ya0FjY2VwdG9yKCkgPSBkZWZhdWx0OworCisgIHZpcnR1YWwgaW50IHN0YXJ0KCkgPSAwOworICB2aXJ0dWFsIHZvaWQgc2h1dGRvd24oKSA9IDA7CisgIHZpcnR1YWwgc3RkOjp1bmlxdWVfcHRyPE5ldHdvcmtTdHJlYW0+IGFjY2VwdCgpID0gMDsKKworICBOZXR3b3JrQWNjZXB0b3IoY29uc3QgTmV0d29ya0FjY2VwdG9yJikgPSBkZWxldGU7CisgIE5ldHdvcmtBY2NlcHRvciYgb3BlcmF0b3I9KGNvbnN0IE5ldHdvcmtBY2NlcHRvciYpID0gZGVsZXRlOworfTsKKworI2VuZGlmICAvLyBUQ1BTT0NLRVRTX05FVFdPUktBQ0NFUFRPUl9IXwpkaWZmIC0tZ2l0IGEvc3JjL3RjcHNvY2tldHMvTmV0d29ya1N0cmVhbS5oIGIvc3JjL3RjcHNvY2tldHMvTmV0d29ya1N0cmVhbS5oCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjYzYWVkYjQKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvdGNwc29ja2V0cy9OZXR3b3JrU3RyZWFtLmgKQEAgLTAsMCArMSwzOSBAQAorLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi8KKy8qIENvcHlyaWdodCAoYykgRklSU1QgMjAxNS4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICovCisvKiBPcGVuIFNvdXJjZSBTb2Z0d2FyZSAtIG1heSBiZSBtb2RpZmllZCBhbmQgc2hhcmVkIGJ5IEZSQyB0ZWFtcy4gVGhlIGNvZGUgICAqLworLyogbXVzdCBiZSBhY2NvbXBhbmllZCBieSB0aGUgRklSU1QgQlNEIGxpY2Vuc2UgZmlsZSBpbiB0aGUgcm9vdCBkaXJlY3Rvcnkgb2YgKi8KKy8qIHRoZSBwcm9qZWN0LiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICovCisvKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qLworCisjaWZuZGVmIFRDUFNPQ0tFVFNfTkVUV09SS1NUUkVBTV9IXworI2RlZmluZSBUQ1BTT0NLRVRTX05FVFdPUktTVFJFQU1fSF8KKworI2luY2x1ZGUgPGNzdGRkZWY+CisKKyNpbmNsdWRlICJsbHZtL1N0cmluZ1JlZi5oIgorCitjbGFzcyBOZXR3b3JrU3RyZWFtIHsKKyBwdWJsaWM6CisgIE5ldHdvcmtTdHJlYW0oKSA9IGRlZmF1bHQ7CisgIHZpcnR1YWwgfk5ldHdvcmtTdHJlYW0oKSA9IGRlZmF1bHQ7CisKKyAgZW51bSBFcnJvciB7CisgICAga0Nvbm5lY3Rpb25DbG9zZWQgPSAwLAorICAgIGtDb25uZWN0aW9uUmVzZXQgPSAtMSwKKyAgICBrQ29ubmVjdGlvblRpbWVkT3V0ID0gLTIKKyAgfTsKKworICB2aXJ0dWFsIHN0ZDo6c2l6ZV90IHNlbmQoY29uc3QgY2hhciogYnVmZmVyLCBzdGQ6OnNpemVfdCBsZW4sIEVycm9yKiBlcnIpID0gMDsKKyAgdmlydHVhbCBzdGQ6OnNpemVfdCByZWNlaXZlKGNoYXIqIGJ1ZmZlciwgc3RkOjpzaXplX3QgbGVuLCBFcnJvciogZXJyLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50IHRpbWVvdXQgPSAwKSA9IDA7CisgIHZpcnR1YWwgdm9pZCBjbG9zZSgpID0gMDsKKworICB2aXJ0dWFsIGxsdm06OlN0cmluZ1JlZiBnZXRQZWVySVAoKSBjb25zdCA9IDA7CisgIHZpcnR1YWwgaW50IGdldFBlZXJQb3J0KCkgY29uc3QgPSAwOworICB2aXJ0dWFsIHZvaWQgc2V0Tm9EZWxheSgpID0gMDsKKworICBOZXR3b3JrU3RyZWFtKGNvbnN0IE5ldHdvcmtTdHJlYW0mKSA9IGRlbGV0ZTsKKyAgTmV0d29ya1N0cmVhbSYgb3BlcmF0b3I9KGNvbnN0IE5ldHdvcmtTdHJlYW0mKSA9IGRlbGV0ZTsKK307CisKKyNlbmRpZiAgLy8gVENQU09DS0VUU19ORVRXT1JLU1RSRUFNX0hfCmRpZmYgLS1naXQgYS9zcmMvdGNwc29ja2V0cy9Tb2NrZXRFcnJvci5jcHAgYi9zcmMvdGNwc29ja2V0cy9Tb2NrZXRFcnJvci5jcHAKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uOTYxOWVkZAotLS0gL2Rldi9udWxsCisrKyBiL3NyYy90Y3Bzb2NrZXRzL1NvY2tldEVycm9yLmNwcApAQCAtMCwwICsxLDMxIEBACisvKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qLworLyogQ29weXJpZ2h0IChjKSBGSVJTVCAyMDE1LiBBbGwgUmlnaHRzIFJlc2VydmVkLiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKi8KKy8qIE9wZW4gU291cmNlIFNvZnR3YXJlIC0gbWF5IGJlIG1vZGlmaWVkIGFuZCBzaGFyZWQgYnkgRlJDIHRlYW1zLiBUaGUgY29kZSAgICovCisvKiBtdXN0IGJlIGFjY29tcGFuaWVkIGJ5IHRoZSBGSVJTVCBCU0QgbGljZW5zZSBmaWxlIGluIHRoZSByb290IGRpcmVjdG9yeSBvZiAqLworLyogdGhlIHByb2plY3QuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKi8KKy8qLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovCisKKyNpbmNsdWRlICJTb2NrZXRFcnJvci5oIgorCisjaWZkZWYgX1dJTjMyCisjaW5jbHVkZSA8d2luZG93cy5oPgorI2Vsc2UKKyNpbmNsdWRlIDxzdHJpbmcuaD4KKyNlbmRpZgorCituYW1lc3BhY2UgdGNwc29ja2V0cyB7CisKK3N0ZDo6c3RyaW5nIFNvY2tldFN0cmVycm9yKGludCBjb2RlKSB7CisjaWZkZWYgX1dJTjMyCisgIExQU1RSIGVycnN0ciA9IG51bGxwdHI7CisgIEZvcm1hdE1lc3NhZ2UoRk9STUFUX01FU1NBR0VfQUxMT0NBVEVfQlVGRkVSIHwgRk9STUFUX01FU1NBR0VfRlJPTV9TWVNURU0sCisgICAgICAgICAgICAgICAgMCwgY29kZSwgMCwgKExQU1RSKSZlcnJzdHIsIDAsIDApOworICBzdGQ6OnN0cmluZyBydihlcnJzdHIpOworICBMb2NhbEZyZWUoZXJyc3RyKTsKKyAgcmV0dXJuIHJ2OworI2Vsc2UKKyAgcmV0dXJuIHN0cmVycm9yKGNvZGUpOworI2VuZGlmCit9CisKK30gIC8vIG5hbWVzcGFjZSB0Y3Bzb2NrZXRzCmRpZmYgLS1naXQgYS9zcmMvdGNwc29ja2V0cy9Tb2NrZXRFcnJvci5oIGIvc3JjL3RjcHNvY2tldHMvU29ja2V0RXJyb3IuaApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4yNjdlOGRhCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL3RjcHNvY2tldHMvU29ja2V0RXJyb3IuaApAQCAtMCwwICsxLDM3IEBACisvKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qLworLyogQ29weXJpZ2h0IChjKSBGSVJTVCAyMDE1LiBBbGwgUmlnaHRzIFJlc2VydmVkLiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKi8KKy8qIE9wZW4gU291cmNlIFNvZnR3YXJlIC0gbWF5IGJlIG1vZGlmaWVkIGFuZCBzaGFyZWQgYnkgRlJDIHRlYW1zLiBUaGUgY29kZSAgICovCisvKiBtdXN0IGJlIGFjY29tcGFuaWVkIGJ5IHRoZSBGSVJTVCBCU0QgbGljZW5zZSBmaWxlIGluIHRoZSByb290IGRpcmVjdG9yeSBvZiAqLworLyogdGhlIHByb2plY3QuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKi8KKy8qLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovCisKKyNpZm5kZWYgVENQU09DS0VUU19TT0NLRVRFUlJPUl9IXworI2RlZmluZSBUQ1BTT0NLRVRTX1NPQ0tFVEVSUk9SX0hfCisKKyNpbmNsdWRlIDxzdHJpbmc+CisKKyNpZmRlZiBfV0lOMzIKKyNpbmNsdWRlIDxXaW5Tb2NrMi5oPgorI2Vsc2UKKyNpbmNsdWRlIDxlcnJuby5oPgorI2VuZGlmCisKK25hbWVzcGFjZSB0Y3Bzb2NrZXRzIHsKKworc3RhdGljIGlubGluZSBpbnQgU29ja2V0RXJybm8oKSB7CisjaWZkZWYgX1dJTjMyCisgIHJldHVybiBXU0FHZXRMYXN0RXJyb3IoKTsKKyNlbHNlCisgIHJldHVybiBlcnJubzsKKyNlbmRpZgorfQorCitzdGQ6OnN0cmluZyBTb2NrZXRTdHJlcnJvcihpbnQgY29kZSk7CisKK3N0YXRpYyBpbmxpbmUgc3RkOjpzdHJpbmcgU29ja2V0U3RyZXJyb3IoKSB7CisgIHJldHVybiBTb2NrZXRTdHJlcnJvcihTb2NrZXRFcnJubygpKTsKK30KKworfSAgLy8gbmFtZXNwYWNlIHRjcHNvY2tldHMKKworI2VuZGlmICAvLyBUQ1BTT0NLRVRTX1NPQ0tFVEVSUk9SX0hfCmRpZmYgLS1naXQgYS9zcmMvdGNwc29ja2V0cy9UQ1BBY2NlcHRvci5jcHAgYi9zcmMvdGNwc29ja2V0cy9UQ1BBY2NlcHRvci5jcHAKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uM2I3ZTE2ZQotLS0gL2Rldi9udWxsCisrKyBiL3NyYy90Y3Bzb2NrZXRzL1RDUEFjY2VwdG9yLmNwcApAQCAtMCwwICsxLDE4MiBAQAorLyoKKyAgIFRDUEFjY2VwdG9yLmNwcAorCisgICBUQ1BBY2NlcHRvciBjbGFzcyBkZWZpbml0aW9uLiBUQ1BBY2NlcHRvciBwcm92aWRlcyBtZXRob2RzIHRvIHBhc3NpdmVseQorICAgZXN0YWJsaXNoIFRDUC9JUCBjb25uZWN0aW9ucyB3aXRoIGNsaWVudHMuCisKKyAgIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCisgICBDb3B5cmlnaHQgqSAyMDEzIFtWaWMgSGFyZ3JhdmUgLSBodHRwOi8vdmljaGFyZ3JhdmUuY29tXQorCisgICBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAgIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAgIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorCisgICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisKKyAgIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAgIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAgIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAgIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorKi8KKworI2luY2x1ZGUgIlRDUEFjY2VwdG9yLmgiCisKKyNpbmNsdWRlIDxjc3RkaW8+CisjaW5jbHVkZSA8Y3N0cmluZz4KKyNpZmRlZiBfV0lOMzIKKyNpbmNsdWRlIDxXaW5Tb2NrMi5oPgorI3ByYWdtYSBjb21tZW50KGxpYiwgIldzMl8zMi5saWIiKQorI2Vsc2UKKyNpbmNsdWRlIDxhcnBhL2luZXQuaD4KKyNpbmNsdWRlIDxuZXRpbmV0L2luLmg+CisjaW5jbHVkZSA8dW5pc3RkLmg+CisjaW5jbHVkZSA8ZmNudGwuaD4KKyNlbmRpZgorCisjaW5jbHVkZSAibGx2bS9TbWFsbFN0cmluZy5oIgorI2luY2x1ZGUgIi4uL0xvZy5oIgorI2luY2x1ZGUgIlNvY2tldEVycm9yLmgiCisKK3VzaW5nIG5hbWVzcGFjZSB0Y3Bzb2NrZXRzOworCitUQ1BBY2NlcHRvcjo6VENQQWNjZXB0b3IoaW50IHBvcnQsIGNvbnN0IGNoYXIqIGFkZHJlc3MpCisgICAgOiBtX2xzZCgwKSwKKyAgICAgIG1fcG9ydChwb3J0KSwKKyAgICAgIG1fYWRkcmVzcyhhZGRyZXNzKSwKKyAgICAgIG1fbGlzdGVuaW5nKGZhbHNlKSB7CisgIG1fc2h1dGRvd24gPSBmYWxzZTsKKyNpZmRlZiBfV0lOMzIKKyAgV1NBRGF0YSB3c2FEYXRhOworICBXT1JEIHdWZXJzaW9uUmVxdWVzdGVkID0gTUFLRVdPUkQoMiwgMik7CisgIFdTQVN0YXJ0dXAod1ZlcnNpb25SZXF1ZXN0ZWQsICZ3c2FEYXRhKTsKKyNlbmRpZgorfQorCitUQ1BBY2NlcHRvcjo6flRDUEFjY2VwdG9yKCkgeworICBpZiAobV9sc2QgPiAwKSB7CisgICAgc2h1dGRvd24oKTsKKyNpZmRlZiBfV0lOMzIKKyAgICBjbG9zZXNvY2tldChtX2xzZCk7CisjZWxzZQorICAgIGNsb3NlKG1fbHNkKTsKKyNlbmRpZgorICB9CisjaWZkZWYgX1dJTjMyCisgIFdTQUNsZWFudXAoKTsKKyNlbmRpZgorfQorCitpbnQgVENQQWNjZXB0b3I6OnN0YXJ0KCkgeworICBpZiAobV9saXN0ZW5pbmcpIHJldHVybiAwOworCisgIG1fbHNkID0gc29ja2V0KFBGX0lORVQsIFNPQ0tfU1RSRUFNLCAwKTsKKyAgc3RydWN0IHNvY2thZGRyX2luIGFkZHJlc3M7CisKKyAgc3RkOjptZW1zZXQoJmFkZHJlc3MsIDAsIHNpemVvZihhZGRyZXNzKSk7CisgIGFkZHJlc3Muc2luX2ZhbWlseSA9IFBGX0lORVQ7CisgIGlmIChtX2FkZHJlc3Muc2l6ZSgpID4gMCkgeworI2lmZGVmIF9XSU4zMgorICAgIGxsdm06OlNtYWxsU3RyaW5nPDEyOD4gYWRkcl9jb3B5KG1fYWRkcmVzcyk7CisgICAgYWRkcl9jb3B5LnB1c2hfYmFjaygnXDAnKTsKKyAgICBpbnQgc2l6ZSA9IHNpemVvZihhZGRyZXNzKTsKKyAgICBXU0FTdHJpbmdUb0FkZHJlc3MoYWRkcl9jb3B5LmRhdGEoKSwgUEZfSU5FVCwgbnVsbHB0ciwgKHN0cnVjdCBzb2NrYWRkciopJmFkZHJlc3MsICZzaXplKTsKKyNlbHNlCisgICAgaW5ldF9wdG9uKFBGX0lORVQsIG1fYWRkcmVzcy5jX3N0cigpLCAmKGFkZHJlc3Muc2luX2FkZHIpKTsKKyNlbmRpZgorICB9IGVsc2UgeworICAgIGFkZHJlc3Muc2luX2FkZHIuc19hZGRyID0gSU5BRERSX0FOWTsKKyAgfQorICBhZGRyZXNzLnNpbl9wb3J0ID0gaHRvbnMobV9wb3J0KTsKKworICBpbnQgb3B0dmFsID0gMTsKKyAgc2V0c29ja29wdChtX2xzZCwgU09MX1NPQ0tFVCwgU09fUkVVU0VBRERSLCAoY2hhciopJm9wdHZhbCwgc2l6ZW9mIG9wdHZhbCk7CisKKyAgaW50IHJlc3VsdCA9IGJpbmQobV9sc2QsIChzdHJ1Y3Qgc29ja2FkZHIqKSZhZGRyZXNzLCBzaXplb2YoYWRkcmVzcykpOworICBpZiAocmVzdWx0ICE9IDApIHsKKyAgICBFUlJPUigiYmluZCgpIGZhaWxlZDogIiA8PCBTb2NrZXRTdHJlcnJvcigpKTsKKyAgICByZXR1cm4gcmVzdWx0OworICB9CisKKyAgcmVzdWx0ID0gbGlzdGVuKG1fbHNkLCA1KTsKKyAgaWYgKHJlc3VsdCAhPSAwKSB7CisgICAgRVJST1IoImxpc3RlbigpIGZhaWxlZDogIiA8PCBTb2NrZXRTdHJlcnJvcigpKTsKKyAgICByZXR1cm4gcmVzdWx0OworICB9CisgIG1fbGlzdGVuaW5nID0gdHJ1ZTsKKyAgcmV0dXJuIHJlc3VsdDsKK30KKwordm9pZCBUQ1BBY2NlcHRvcjo6c2h1dGRvd24oKSB7CisgIG1fc2h1dGRvd24gPSB0cnVlOworI2lmZGVmIF9XSU4zMgorICA6OnNodXRkb3duKG1fbHNkLCBTRF9CT1RIKTsKKworICAvLyB0aGlzIGlzIHVnbHksIGJ1dCB0aGUgZWFzaWVzdCB3YXkgdG8gZG8gdGhpcworICAvLyBmb3JjZSB3YWtldXAgb2YgYWNjZXB0KCkgd2l0aCBhIG5vbi1ibG9ja2luZyBjb25uZWN0IHRvIG91cnNlbHZlcworICBzdHJ1Y3Qgc29ja2FkZHJfaW4gYWRkcmVzczsKKworICBzdGQ6Om1lbXNldCgmYWRkcmVzcywgMCwgc2l6ZW9mKGFkZHJlc3MpKTsKKyAgYWRkcmVzcy5zaW5fZmFtaWx5ID0gUEZfSU5FVDsKKyAgbGx2bTo6U21hbGxTdHJpbmc8MTI4PiBhZGRyX2NvcHk7CisgIGlmIChtX2FkZHJlc3Muc2l6ZSgpID4gMCkKKyAgICBhZGRyX2NvcHkgPSBtX2FkZHJlc3M7CisgIGVsc2UKKyAgICBhZGRyX2NvcHkgPSAiMTI3LjAuMC4xIjsKKyAgYWRkcl9jb3B5LnB1c2hfYmFjaygnXDAnKTsKKyAgaW50IHNpemUgPSBzaXplb2YoYWRkcmVzcyk7CisgIGlmIChXU0FTdHJpbmdUb0FkZHJlc3MoYWRkcl9jb3B5LmRhdGEoKSwgUEZfSU5FVCwgbnVsbHB0ciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAoc3RydWN0IHNvY2thZGRyKikmYWRkcmVzcywgJnNpemUpICE9IDApCisgICAgcmV0dXJuOworICBhZGRyZXNzLnNpbl9wb3J0ID0gaHRvbnMobV9wb3J0KTsKKworICBmZF9zZXQgc2RzZXQ7CisgIHN0cnVjdCB0aW1ldmFsIHR2OworICBpbnQgcmVzdWx0ID0gLTEsIHZhbG9wdCwgc2QgPSBzb2NrZXQoQUZfSU5FVCwgU09DS19TVFJFQU0sIDApOworCisgIC8vIFNldCBzb2NrZXQgdG8gbm9uLWJsb2NraW5nCisgIHVfbG9uZyBtb2RlID0gMTsKKyAgaW9jdGxzb2NrZXQoc2QsIEZJT05CSU8sICZtb2RlKTsKKworICAvLyBUcnkgdG8gY29ubmVjdAorICA6OmNvbm5lY3Qoc2QsIChzdHJ1Y3Qgc29ja2FkZHIqKSZhZGRyZXNzLCBzaXplb2YoYWRkcmVzcykpOworCisgIC8vIENsb3NlCisgIDo6Y2xvc2Vzb2NrZXQoc2QpOworCisjZWxzZQorICA6OnNodXRkb3duKG1fbHNkLCBTSFVUX1JEV1IpOworICBpbnQgbnVsbGZkID0gOjpvcGVuKCIvZGV2L251bGwiLCBPX1JET05MWSk7CisgIGlmIChudWxsZmQgPj0gMCkgeworICAgIDo6ZHVwMihudWxsZmQsIG1fbHNkKTsKKyAgICA6OmNsb3NlKG51bGxmZCk7CisgIH0KKyNlbmRpZgorfQorCitzdGQ6OnVuaXF1ZV9wdHI8TmV0d29ya1N0cmVhbT4gVENQQWNjZXB0b3I6OmFjY2VwdCgpIHsKKyAgaWYgKCFtX2xpc3RlbmluZyB8fCBtX3NodXRkb3duKSByZXR1cm4gbnVsbHB0cjsKKworICBzdHJ1Y3Qgc29ja2FkZHJfaW4gYWRkcmVzczsKKyNpZmRlZiBfV0lOMzIKKyAgaW50IGxlbiA9IHNpemVvZihhZGRyZXNzKTsKKyNlbHNlCisgIHNvY2tsZW5fdCBsZW4gPSBzaXplb2YoYWRkcmVzcyk7CisjZW5kaWYKKyAgc3RkOjptZW1zZXQoJmFkZHJlc3MsIDAsIHNpemVvZihhZGRyZXNzKSk7CisgIGludCBzZCA9IDo6YWNjZXB0KG1fbHNkLCAoc3RydWN0IHNvY2thZGRyKikmYWRkcmVzcywgJmxlbik7CisgIGlmIChzZCA8IDApIHsKKyAgICBpZiAoIW1fc2h1dGRvd24pIEVSUk9SKCJhY2NlcHQoKSBmYWlsZWQ6ICIgPDwgU29ja2V0U3RyZXJyb3IoKSk7CisgICAgcmV0dXJuIG51bGxwdHI7CisgIH0KKyAgaWYgKG1fc2h1dGRvd24pIHsKKyNpZmRlZiBfV0lOMzIKKyAgICBjbG9zZXNvY2tldChzZCk7CisjZWxzZQorICAgIGNsb3NlKHNkKTsKKyNlbmRpZgorICAgIHJldHVybiBudWxscHRyOworICB9CisgIHJldHVybiBzdGQ6OnVuaXF1ZV9wdHI8TmV0d29ya1N0cmVhbT4obmV3IFRDUFN0cmVhbShzZCwgJmFkZHJlc3MpKTsKK30KZGlmZiAtLWdpdCBhL3NyYy90Y3Bzb2NrZXRzL1RDUEFjY2VwdG9yLmggYi9zcmMvdGNwc29ja2V0cy9UQ1BBY2NlcHRvci5oCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmQ2YTZjY2MKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvdGNwc29ja2V0cy9UQ1BBY2NlcHRvci5oCkBAIC0wLDAgKzEsNTAgQEAKKy8qCisgICBUQ1BBY2NlcHRvci5oCisKKyAgIFRDUEFjY2VwdG9yIGNsYXNzIGludGVyZmFjZS4gVENQQWNjZXB0b3IgcHJvdmlkZXMgbWV0aG9kcyB0byBwYXNzaXZlbHkKKyAgIGVzdGFibGlzaCBUQ1AvSVAgY29ubmVjdGlvbnMgd2l0aCBjbGllbnRzLgorCisgICAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworICAgQ29weXJpZ2h0IKkgMjAxMyBbVmljIEhhcmdyYXZlIC0gaHR0cDovL3ZpY2hhcmdyYXZlLmNvbV0KKworICAgTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgICB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKworICAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorCisgICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyovCisKKyNpZm5kZWYgVENQU09DS0VUU19UQ1BBQ0NFUFRPUl9IXworI2RlZmluZSBUQ1BTT0NLRVRTX1RDUEFDQ0VQVE9SX0hfCisKKyNpbmNsdWRlIDxhdG9taWM+CisjaW5jbHVkZSA8bWVtb3J5PgorI2luY2x1ZGUgPHN0cmluZz4KKworI2luY2x1ZGUgIk5ldHdvcmtBY2NlcHRvci5oIgorI2luY2x1ZGUgIlRDUFN0cmVhbS5oIgorCitjbGFzcyBUQ1BBY2NlcHRvciA6IHB1YmxpYyBOZXR3b3JrQWNjZXB0b3IgeworICBpbnQgbV9sc2Q7CisgIGludCBtX3BvcnQ7CisgIHN0ZDo6c3RyaW5nIG1fYWRkcmVzczsKKyAgYm9vbCBtX2xpc3RlbmluZzsKKyAgc3RkOjphdG9taWNfYm9vbCBtX3NodXRkb3duOworCisgcHVibGljOgorICBUQ1BBY2NlcHRvcihpbnQgcG9ydCwgY29uc3QgY2hhciogYWRkcmVzcyk7CisgIH5UQ1BBY2NlcHRvcigpOworCisgIGludCBzdGFydCgpIG92ZXJyaWRlOworICB2b2lkIHNodXRkb3duKCkgb3ZlcnJpZGU7CisgIHN0ZDo6dW5pcXVlX3B0cjxOZXR3b3JrU3RyZWFtPiBhY2NlcHQoKSBvdmVycmlkZTsKK307CisKKyNlbmRpZgpkaWZmIC0tZ2l0IGEvc3JjL3RjcHNvY2tldHMvVENQQ29ubmVjdG9yLmNwcCBiL3NyYy90Y3Bzb2NrZXRzL1RDUENvbm5lY3Rvci5jcHAKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNjY1NTAwZAotLS0gL2Rldi9udWxsCisrKyBiL3NyYy90Y3Bzb2NrZXRzL1RDUENvbm5lY3Rvci5jcHAKQEAgLTAsMCArMSwxNjcgQEAKKy8qCisgICBUQ1BDb25uZWN0b3IuaAorCisgICBUQ1BDb25uZWN0b3IgY2xhc3MgZGVmaW5pdGlvbi4gVENQQ29ubmVjdG9yIHByb3ZpZGVzIG1ldGhvZHMgdG8gYWN0aXZlbHkKKyAgIGVzdGFibGlzaCBUQ1AvSVAgY29ubmVjdGlvbnMgd2l0aCBhIHNlcnZlci4KKworICAgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKKyAgIENvcHlyaWdodCCpIDIwMTMgW1ZpYyBIYXJncmF2ZSAtIGh0dHA6Ly92aWNoYXJncmF2ZS5jb21dCisKKyAgIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICAgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisKKyAgICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKworICAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAgIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UKKyovCisKKyNpbmNsdWRlICJUQ1BDb25uZWN0b3IuaCIKKworI2luY2x1ZGUgPGVycm5vLmg+CisjaW5jbHVkZSA8ZmNudGwuaD4KKyNpbmNsdWRlIDxjc3RkaW8+CisjaW5jbHVkZSA8Y3N0cmluZz4KKyNpZmRlZiBfV0lOMzIKKyNpbmNsdWRlIDxXaW5Tb2NrMi5oPgorI2luY2x1ZGUgPFdTMnRjcGlwLmg+CisjZWxzZQorI2luY2x1ZGUgPG5ldGRiLmg+CisjaW5jbHVkZSA8YXJwYS9pbmV0Lmg+CisjaW5jbHVkZSA8bmV0aW5ldC9pbi5oPgorI2luY2x1ZGUgPHN5cy9zZWxlY3QuaD4KKyNlbmRpZgorCisjaW5jbHVkZSAiVENQU3RyZWFtLmgiCisKKyNpbmNsdWRlICJsbHZtL1NtYWxsU3RyaW5nLmgiCisjaW5jbHVkZSAiLi4vTG9nLmgiCisjaW5jbHVkZSAiU29ja2V0RXJyb3IuaCIKKwordXNpbmcgbmFtZXNwYWNlIHRjcHNvY2tldHM7CisKK3N0YXRpYyBpbnQgUmVzb2x2ZUhvc3ROYW1lKGNvbnN0IGNoYXIqIGhvc3RuYW1lLCBzdHJ1Y3QgaW5fYWRkciogYWRkcikgeworICBzdHJ1Y3QgYWRkcmluZm8gaGludHM7CisgIHN0cnVjdCBhZGRyaW5mbyogcmVzOworCisgIGhpbnRzLmFpX2ZsYWdzID0gMDsKKyAgaGludHMuYWlfZmFtaWx5ID0gQUZfSU5FVDsKKyAgaGludHMuYWlfc29ja3R5cGUgPSBTT0NLX1NUUkVBTTsKKyAgaGludHMuYWlfcHJvdG9jb2wgPSAwOworICBoaW50cy5haV9hZGRybGVuID0gMDsKKyAgaGludHMuYWlfYWRkciA9IG51bGxwdHI7CisgIGhpbnRzLmFpX2Nhbm9ubmFtZSA9IG51bGxwdHI7CisgIGhpbnRzLmFpX25leHQgPSBudWxscHRyOworICBpbnQgcmVzdWx0ID0gZ2V0YWRkcmluZm8oaG9zdG5hbWUsIG51bGxwdHIsICZoaW50cywgJnJlcyk7CisgIGlmIChyZXN1bHQgPT0gMCkgeworICAgIHN0ZDo6bWVtY3B5KGFkZHIsICYoKHN0cnVjdCBzb2NrYWRkcl9pbiopcmVzLT5haV9hZGRyKS0+c2luX2FkZHIsCisgICAgICAgICAgICAgICAgc2l6ZW9mKHN0cnVjdCBpbl9hZGRyKSk7CisgICAgZnJlZWFkZHJpbmZvKHJlcyk7CisgIH0KKyAgcmV0dXJuIHJlc3VsdDsKK30KKworc3RkOjp1bmlxdWVfcHRyPE5ldHdvcmtTdHJlYW0+IFRDUENvbm5lY3Rvcjo6Y29ubmVjdChjb25zdCBjaGFyKiBzZXJ2ZXIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludCBwb3J0LCBpbnQgdGltZW91dCkgeworI2lmZGVmIF9XSU4zMgorICBzdHJ1Y3QgV1NBSGVscGVyIHsKKyAgICBXU0FIZWxwZXIoKSB7CisgICAgICBXU0FEYXRhIHdzYURhdGE7CisgICAgICBXT1JEIHdWZXJzaW9uUmVxdWVzdGVkID0gTUFLRVdPUkQoMiwgMik7CisgICAgICBXU0FTdGFydHVwKHdWZXJzaW9uUmVxdWVzdGVkLCAmd3NhRGF0YSk7CisgICAgfQorICAgIH5XU0FIZWxwZXIoKSB7IFdTQUNsZWFudXAoKTsgfQorICB9OworICBzdGF0aWMgV1NBSGVscGVyIGhlbHBlcjsKKyNlbmRpZgorICBzdHJ1Y3Qgc29ja2FkZHJfaW4gYWRkcmVzczsKKworICBzdGQ6Om1lbXNldCgmYWRkcmVzcywgMCwgc2l6ZW9mKGFkZHJlc3MpKTsKKyAgYWRkcmVzcy5zaW5fZmFtaWx5ID0gQUZfSU5FVDsKKyAgaWYgKFJlc29sdmVIb3N0TmFtZShzZXJ2ZXIsICYoYWRkcmVzcy5zaW5fYWRkcikpICE9IDApIHsKKyNpZmRlZiBfV0lOMzIKKyAgICBsbHZtOjpTbWFsbFN0cmluZzwxMjg+IGFkZHJfY29weShzZXJ2ZXIpOworICAgIGFkZHJfY29weS5wdXNoX2JhY2soJ1wwJyk7CisgICAgaW50IHNpemUgPSBzaXplb2YoYWRkcmVzcyk7CisgICAgaWYgKFdTQVN0cmluZ1RvQWRkcmVzcyhhZGRyX2NvcHkuZGF0YSgpLCBQRl9JTkVULCBudWxscHRyLCAoc3RydWN0IHNvY2thZGRyKikmYWRkcmVzcywgJnNpemUpICE9IDApIHsKKyAgICAgIEVSUk9SKCJjb3VsZCBub3QgcmVzb2x2ZSAiIDw8IHNlcnZlciA8PCAiIGFkZHJlc3MiKTsKKyAgICAgIHJldHVybiBudWxscHRyOworICAgIH0KKyNlbHNlCisgICAgaW5ldF9wdG9uKFBGX0lORVQsIHNlcnZlciwgJihhZGRyZXNzLnNpbl9hZGRyKSk7CisjZW5kaWYKKyAgfQorICBhZGRyZXNzLnNpbl9wb3J0ID0gaHRvbnMocG9ydCk7CisKKyAgaWYgKHRpbWVvdXQgPT0gMCkgeworICAgIGludCBzZCA9IHNvY2tldChBRl9JTkVULCBTT0NLX1NUUkVBTSwgMCk7CisgICAgaWYgKDo6Y29ubmVjdChzZCwgKHN0cnVjdCBzb2NrYWRkciopJmFkZHJlc3MsIHNpemVvZihhZGRyZXNzKSkgIT0gMCkgeworICAgICAgRVJST1IoImNvbm5lY3QoKSB0byAiIDw8IHNlcnZlciA8PCAiIHBvcnQgIiA8PCBwb3J0IDw8ICIgZmFpbGVkOiAiIDw8IFNvY2tldFN0cmVycm9yKCkpOworICAgICAgcmV0dXJuIG51bGxwdHI7CisgICAgfQorICAgIHJldHVybiBzdGQ6OnVuaXF1ZV9wdHI8TmV0d29ya1N0cmVhbT4obmV3IFRDUFN0cmVhbShzZCwgJmFkZHJlc3MpKTsKKyAgfQorCisgIGZkX3NldCBzZHNldDsKKyAgc3RydWN0IHRpbWV2YWwgdHY7CisgIHNvY2tsZW5fdCBsZW47CisgIGludCByZXN1bHQgPSAtMSwgdmFsb3B0LCBzZCA9IHNvY2tldChBRl9JTkVULCBTT0NLX1NUUkVBTSwgMCk7CisKKyAgLy8gU2V0IHNvY2tldCB0byBub24tYmxvY2tpbmcKKyNpZmRlZiBfV0lOMzIKKyAgdV9sb25nIG1vZGUgPSAxOworICBpb2N0bHNvY2tldChzZCwgRklPTkJJTywgJm1vZGUpOworI2Vsc2UKKyAgbG9uZyBhcmc7CisgIGFyZyA9IGZjbnRsKHNkLCBGX0dFVEZMLCBudWxscHRyKTsKKyAgYXJnIHw9IE9fTk9OQkxPQ0s7CisgIGZjbnRsKHNkLCBGX1NFVEZMLCBhcmcpOworI2VuZGlmCisKKyAgLy8gQ29ubmVjdCB3aXRoIHRpbWUgbGltaXQKKyAgaWYgKChyZXN1bHQgPSA6OmNvbm5lY3Qoc2QsIChzdHJ1Y3Qgc29ja2FkZHIqKSZhZGRyZXNzLCBzaXplb2YoYWRkcmVzcykpKSA8CisgICAgICAwKSB7CisgICAgaW50IG15X2Vycm5vID0gU29ja2V0RXJybm8oKTsKKyNpZmRlZiBfV0lOMzIKKyAgICBpZiAobXlfZXJybm8gPT0gV1NBRVdPVUxEQkxPQ0sgfHwgbXlfZXJybm8gPT0gV1NBRUlOUFJPR1JFU1MpIHsKKyNlbHNlCisgICAgaWYgKG15X2Vycm5vID09IEVXT1VMREJMT0NLIHx8IG15X2Vycm5vID09IEVJTlBST0dSRVNTKSB7CisjZW5kaWYKKyAgICAgIHR2LnR2X3NlYyA9IHRpbWVvdXQ7CisgICAgICB0di50dl91c2VjID0gMDsKKyAgICAgIEZEX1pFUk8oJnNkc2V0KTsKKyAgICAgIEZEX1NFVChzZCwgJnNkc2V0KTsKKyAgICAgIGlmIChzZWxlY3Qoc2QgKyAxLCBudWxscHRyLCAmc2RzZXQsIG51bGxwdHIsICZ0dikgPiAwKSB7CisgICAgICAgIGxlbiA9IHNpemVvZihpbnQpOworICAgICAgICBnZXRzb2Nrb3B0KHNkLCBTT0xfU09DS0VULCBTT19FUlJPUiwgKGNoYXIqKSgmdmFsb3B0KSwgJmxlbik7CisgICAgICAgIGlmICh2YWxvcHQpIHsKKyAgICAgICAgICBFUlJPUigic2VsZWN0KCkgdG8gIiA8PCBzZXJ2ZXIgPDwgIiBwb3J0ICIgPDwgcG9ydCA8PCAiIGVycm9yICIgPDwgdmFsb3B0IDw8ICIgLSAiIDw8IFNvY2tldFN0cmVycm9yKHZhbG9wdCkpOworICAgICAgICB9CisgICAgICAgIC8vIGNvbm5lY3Rpb24gZXN0YWJsaXNoZWQKKyAgICAgICAgZWxzZQorICAgICAgICAgIHJlc3VsdCA9IDA7CisgICAgICB9IGVsc2UKKyAgICAgICAgSU5GTygiY29ubmVjdCgpIHRvICIgPDwgc2VydmVyIDw8ICIgcG9ydCAiIDw8IHBvcnQgPDwgIiB0aW1lZCBvdXQiKTsKKyAgICB9IGVsc2UKKyAgICAgIEVSUk9SKCJjb25uZWN0KCkgdG8gIiA8PCBzZXJ2ZXIgPDwgIiBwb3J0ICIgPDwgcG9ydCA8PCAiIGVycm9yICIgPDwgU29ja2V0RXJybm8oKSA8PCAiIC0gIiA8PCBTb2NrZXRTdHJlcnJvcigpKTsKKyAgfQorCisgIC8vIFJldHVybiBzb2NrZXQgdG8gYmxvY2tpbmcgbW9kZQorI2lmZGVmIF9XSU4zMgorICBtb2RlID0gMDsKKyAgaW9jdGxzb2NrZXQoc2QsIEZJT05CSU8sICZtb2RlKTsKKyNlbHNlCisgIGFyZyA9IGZjbnRsKHNkLCBGX0dFVEZMLCBudWxscHRyKTsKKyAgYXJnICY9ICh+T19OT05CTE9DSyk7CisgIGZjbnRsKHNkLCBGX1NFVEZMLCBhcmcpOworI2VuZGlmCisKKyAgLy8gQ3JlYXRlIHN0cmVhbSBvYmplY3QgaWYgY29ubmVjdGVkCisgIGlmIChyZXN1bHQgPT0gLTEpIHJldHVybiBudWxscHRyOworICByZXR1cm4gc3RkOjp1bmlxdWVfcHRyPE5ldHdvcmtTdHJlYW0+KG5ldyBUQ1BTdHJlYW0oc2QsICZhZGRyZXNzKSk7Cit9CmRpZmYgLS1naXQgYS9zcmMvdGNwc29ja2V0cy9UQ1BDb25uZWN0b3IuaCBiL3NyYy90Y3Bzb2NrZXRzL1RDUENvbm5lY3Rvci5oCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmViYWM4NTkKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvdGNwc29ja2V0cy9UQ1BDb25uZWN0b3IuaApAQCAtMCwwICsxLDM3IEBACisvKgorICAgVENQQ29ubmVjdG9yLmgKKworICAgVENQQ29ubmVjdG9yIGNsYXNzIGludGVyZmFjZS4gVENQQ29ubmVjdG9yIHByb3ZpZGVzIG1ldGhvZHMgdG8gYWN0aXZlbHkKKyAgIGVzdGFibGlzaCBUQ1AvSVAgY29ubmVjdGlvbnMgd2l0aCBhIHNlcnZlci4KKworICAgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKKyAgIENvcHlyaWdodCCpIDIwMTMgW1ZpYyBIYXJncmF2ZSAtIGh0dHA6Ly92aWNoYXJncmF2ZS5jb21dCisKKyAgIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICAgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisKKyAgICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKworICAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAgIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UKKyovCisKKyNpZm5kZWYgVENQU09DS0VUU19UQ1BDT05ORUNUT1JfSF8KKyNkZWZpbmUgVENQU09DS0VUU19UQ1BDT05ORUNUT1JfSF8KKworI2luY2x1ZGUgPG1lbW9yeT4KKworI2luY2x1ZGUgIk5ldHdvcmtTdHJlYW0uaCIKKworY2xhc3MgVENQQ29ubmVjdG9yIHsKKyBwdWJsaWM6CisgIHN0YXRpYyBzdGQ6OnVuaXF1ZV9wdHI8TmV0d29ya1N0cmVhbT4gY29ubmVjdChjb25zdCBjaGFyKiBzZXJ2ZXIsIGludCBwb3J0LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50IHRpbWVvdXQgPSAwKTsKK307CisKKyNlbmRpZgpkaWZmIC0tZ2l0IGEvc3JjL3RjcHNvY2tldHMvVENQU3RyZWFtLmNwcCBiL3NyYy90Y3Bzb2NrZXRzL1RDUFN0cmVhbS5jcHAKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMzE0OWJlNgotLS0gL2Rldi9udWxsCisrKyBiL3NyYy90Y3Bzb2NrZXRzL1RDUFN0cmVhbS5jcHAKQEAgLTAsMCArMSwxNTcgQEAKKy8qCisgICBUQ1BTdHJlYW0uaAorCisgICBUQ1BTdHJlYW0gY2xhc3MgZGVmaW5pdGlvbi4gVENQU3RyZWFtIHByb3ZpZGVzIG1ldGhvZHMgdG8gdHJhc25mZXIKKyAgIGRhdGEgYmV0d2VlbiBwZWVycyBvdmVyIGEgVENQL0lQIGNvbm5lY3Rpb24uCisKKyAgIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCisgICBDb3B5cmlnaHQgqSAyMDEzIFtWaWMgSGFyZ3JhdmUgLSBodHRwOi8vdmljaGFyZ3JhdmUuY29tXQorCisgICBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAgIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAgIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorCisgICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisKKyAgIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAgIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAgIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAgIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorKi8KKworI2luY2x1ZGUgIlRDUFN0cmVhbS5oIgorCisjaWZkZWYgX1dJTjMyCisjaW5jbHVkZSA8V2luU29jazIuaD4KKyNlbHNlCisjaW5jbHVkZSA8YXJwYS9pbmV0Lmg+CisjaW5jbHVkZSA8bmV0aW5ldC90Y3AuaD4KKyNpbmNsdWRlIDx1bmlzdGQuaD4KKyNlbmRpZgorCitUQ1BTdHJlYW06OlRDUFN0cmVhbShpbnQgc2QsIHN0cnVjdCBzb2NrYWRkcl9pbiogYWRkcmVzcykgOiBtX3NkKHNkKSB7CisgIGNoYXIgaXBbNTBdOworI2lmZGVmIF9XSU4zMgorICB1bnNpZ25lZCBsb25nIHNpemUgPSBzaXplb2YoaXApIC0gMTsKKyAgV1NBQWRkcmVzc1RvU3RyaW5nKChzdHJ1Y3Qgc29ja2FkZHIqKWFkZHJlc3MsIHNpemVvZiBzb2NrYWRkcl9pbiwgbnVsbHB0ciwgaXAsICZzaXplKTsKKyNlbHNlCisgIGluZXRfbnRvcChQRl9JTkVULCAoc3RydWN0IGluX2FkZHIqKSYoYWRkcmVzcy0+c2luX2FkZHIuc19hZGRyKSwgaXAsCisgICAgICAgICAgICBzaXplb2YoaXApIC0gMSk7CisjZW5kaWYKKyAgbV9wZWVySVAgPSBpcDsKKyAgbV9wZWVyUG9ydCA9IG50b2hzKGFkZHJlc3MtPnNpbl9wb3J0KTsKK30KKworVENQU3RyZWFtOjp+VENQU3RyZWFtKCkgeyBjbG9zZSgpOyB9CisKK3N0ZDo6c2l6ZV90IFRDUFN0cmVhbTo6c2VuZChjb25zdCBjaGFyKiBidWZmZXIsIHN0ZDo6c2l6ZV90IGxlbiwgRXJyb3IqIGVycikgeworICBpZiAobV9zZCA8IDApIHsKKyAgICAqZXJyID0ga0Nvbm5lY3Rpb25DbG9zZWQ7CisgICAgcmV0dXJuIDA7CisgIH0KKyNpZmRlZiBfV0lOMzIKKyAgV1NBQlVGIHdzYUJ1ZjsKKyAgd3NhQnVmLmJ1ZiA9IGNvbnN0X2Nhc3Q8Y2hhcio+KGJ1ZmZlcik7CisgIHdzYUJ1Zi5sZW4gPSAoVUxPTkcpbGVuOworICBEV09SRCBydjsKKyAgYm9vbCByZXN1bHQgPSB0cnVlOworICB3aGlsZSAoV1NBU2VuZChtX3NkLCAmd3NhQnVmLCAxLCAmcnYsIDAsIG51bGxwdHIsIG51bGxwdHIpID09IFNPQ0tFVF9FUlJPUikgeworICAgIGlmIChXU0FHZXRMYXN0RXJyb3IoKSAhPSBXU0FFV09VTERCTE9DSykgeworICAgICAgcmVzdWx0ID0gZmFsc2U7CisgICAgICBicmVhazsKKyAgICB9CisgICAgU2xlZXAoMSk7CisgIH0KKyAgaWYgKCFyZXN1bHQpIHsKKyAgICBjaGFyIEJ1ZmZlclsxMjhdOworI2lmZGVmIF9NU0NfVkVSCisgICAgc3ByaW50Zl9zKEJ1ZmZlciwgIlNlbmQoKSBmYWlsZWQ6IFdTQSBlcnJvcj0lZFxuIiwgV1NBR2V0TGFzdEVycm9yKCkpOworI2Vsc2UKKyAgICBzdGQ6OnNucHJpbnRmKEJ1ZmZlciwgMTI4LCAiU2VuZCgpIGZhaWxlZDogV1NBIGVycm9yPSVkXG4iLCBXU0FHZXRMYXN0RXJyb3IoKSk7CisjZW5kaWYKKyAgICBPdXRwdXREZWJ1Z1N0cmluZ0EoQnVmZmVyKTsKKyAgICAqZXJyID0ga0Nvbm5lY3Rpb25SZXNldDsKKyAgICByZXR1cm4gMDsKKyAgfQorI2Vsc2UKKyAgc3NpemVfdCBydiA9IHdyaXRlKG1fc2QsIGJ1ZmZlciwgbGVuKTsKKyAgaWYgKHJ2IDwgMCkgeworICAgICplcnIgPSBrQ29ubmVjdGlvblJlc2V0OworICAgIHJldHVybiAwOworICB9CisjZW5kaWYKKyAgcmV0dXJuIHN0YXRpY19jYXN0PHN0ZDo6c2l6ZV90Pihydik7Cit9CisKK3N0ZDo6c2l6ZV90IFRDUFN0cmVhbTo6cmVjZWl2ZShjaGFyKiBidWZmZXIsIHN0ZDo6c2l6ZV90IGxlbiwgRXJyb3IqIGVyciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQgdGltZW91dCkgeworICBpZiAobV9zZCA8IDApIHsKKyAgICAqZXJyID0ga0Nvbm5lY3Rpb25DbG9zZWQ7CisgICAgcmV0dXJuIDA7CisgIH0KKyNpZmRlZiBfV0lOMzIKKyAgaW50IHJ2OworI2Vsc2UKKyAgc3NpemVfdCBydjsKKyNlbmRpZgorICBpZiAodGltZW91dCA8PSAwKSB7CisjaWZkZWYgX1dJTjMyCisgICAgcnYgPSByZWN2KG1fc2QsIGJ1ZmZlciwgbGVuLCAwKTsKKyNlbHNlCisgICAgcnYgPSByZWFkKG1fc2QsIGJ1ZmZlciwgbGVuKTsKKyNlbmRpZgorICB9CisgIGVsc2UgaWYgKFdhaXRGb3JSZWFkRXZlbnQodGltZW91dCkpIHsKKyNpZmRlZiBfV0lOMzIKKyAgICBydiA9IHJlY3YobV9zZCwgYnVmZmVyLCBsZW4sIDApOworI2Vsc2UKKyAgICBydiA9IHJlYWQobV9zZCwgYnVmZmVyLCBsZW4pOworI2VuZGlmCisgIH0gZWxzZSB7CisgICAgKmVyciA9IGtDb25uZWN0aW9uVGltZWRPdXQ7CisgICAgcmV0dXJuIDA7CisgIH0KKyAgaWYgKHJ2IDwgMCkgeworICAgICplcnIgPSBrQ29ubmVjdGlvblJlc2V0OworICAgIHJldHVybiAwOworICB9CisgIHJldHVybiBzdGF0aWNfY2FzdDxzdGQ6OnNpemVfdD4ocnYpOworfQorCit2b2lkIFRDUFN0cmVhbTo6Y2xvc2UoKSB7CisgIGlmIChtX3NkID49IDApIHsKKyNpZmRlZiBfV0lOMzIKKyAgICA6OnNodXRkb3duKG1fc2QsIFNEX0JPVEgpOworICAgIGNsb3Nlc29ja2V0KG1fc2QpOworI2Vsc2UKKyAgICA6OnNodXRkb3duKG1fc2QsIFNIVVRfUkRXUik7CisgICAgOjpjbG9zZShtX3NkKTsKKyNlbmRpZgorICB9CisgIG1fc2QgPSAtMTsKK30KKworbGx2bTo6U3RyaW5nUmVmIFRDUFN0cmVhbTo6Z2V0UGVlcklQKCkgY29uc3QgeyByZXR1cm4gbV9wZWVySVA7IH0KKworaW50IFRDUFN0cmVhbTo6Z2V0UGVlclBvcnQoKSBjb25zdCB7IHJldHVybiBtX3BlZXJQb3J0OyB9CisKK3ZvaWQgVENQU3RyZWFtOjpzZXROb0RlbGF5KCkgeworICBpbnQgb3B0dmFsID0gMTsKKyAgc2V0c29ja29wdChtX3NkLCBJUFBST1RPX1RDUCwgVENQX05PREVMQVksIChjaGFyKikmb3B0dmFsLCBzaXplb2Ygb3B0dmFsKTsKK30KKworYm9vbCBUQ1BTdHJlYW06OldhaXRGb3JSZWFkRXZlbnQoaW50IHRpbWVvdXQpIHsKKyAgZmRfc2V0IHNkc2V0OworICBzdHJ1Y3QgdGltZXZhbCB0djsKKworICB0di50dl9zZWMgPSB0aW1lb3V0OworICB0di50dl91c2VjID0gMDsKKyAgRkRfWkVSTygmc2RzZXQpOworICBGRF9TRVQobV9zZCwgJnNkc2V0KTsKKyAgaWYgKHNlbGVjdChtX3NkICsgMSwgJnNkc2V0LCBOVUxMLCBOVUxMLCAmdHYpID4gMCkgeworICAgIHJldHVybiB0cnVlOworICB9CisgIHJldHVybiBmYWxzZTsKK30KZGlmZiAtLWdpdCBhL3NyYy90Y3Bzb2NrZXRzL1RDUFN0cmVhbS5oIGIvc3JjL3RjcHNvY2tldHMvVENQU3RyZWFtLmgKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMjFlZjZmZAotLS0gL2Rldi9udWxsCisrKyBiL3NyYy90Y3Bzb2NrZXRzL1RDUFN0cmVhbS5oCkBAIC0wLDAgKzEsNjcgQEAKKy8qCisgICBUQ1BTdHJlYW0uaAorCisgICBUQ1BTdHJlYW0gY2xhc3MgaW50ZXJmYWNlLiBUQ1BTdHJlYW0gcHJvdmlkZXMgbWV0aG9kcyB0byB0cmFzbmZlcgorICAgZGF0YSBiZXR3ZWVuIHBlZXJzIG92ZXIgYSBUQ1AvSVAgY29ubmVjdGlvbi4KKworICAgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKKyAgIENvcHlyaWdodCCpIDIwMTMgW1ZpYyBIYXJncmF2ZSAtIGh0dHA6Ly92aWNoYXJncmF2ZS5jb21dCisKKyAgIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICAgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisKKyAgICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKworICAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAgIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisqLworCisjaWZuZGVmIFRDUFNPQ0tFVFNfVENQU1RSRUFNX0hfCisjZGVmaW5lIFRDUFNPQ0tFVFNfVENQU1RSRUFNX0hfCisKKyNpbmNsdWRlIDxjc3RkZGVmPgorI2luY2x1ZGUgPHN0cmluZz4KKworI2lmZGVmIF9XSU4zMgorI2luY2x1ZGUgPHdpbnNvY2syLmg+CisjZWxzZQorI2luY2x1ZGUgPHN5cy9zb2NrZXQuaD4KKyNlbmRpZgorCisjaW5jbHVkZSAiTmV0d29ya1N0cmVhbS5oIgorCitjbGFzcyBUQ1BTdHJlYW0gOiBwdWJsaWMgTmV0d29ya1N0cmVhbSB7CisgIGludCBtX3NkOworICBzdGQ6OnN0cmluZyBtX3BlZXJJUDsKKyAgaW50IG1fcGVlclBvcnQ7CisKKyBwdWJsaWM6CisgIGZyaWVuZCBjbGFzcyBUQ1BBY2NlcHRvcjsKKyAgZnJpZW5kIGNsYXNzIFRDUENvbm5lY3RvcjsKKworICB+VENQU3RyZWFtKCk7CisKKyAgc3RkOjpzaXplX3Qgc2VuZChjb25zdCBjaGFyKiBidWZmZXIsIHN0ZDo6c2l6ZV90IGxlbiwgRXJyb3IqIGVycikgb3ZlcnJpZGU7CisgIHN0ZDo6c2l6ZV90IHJlY2VpdmUoY2hhciogYnVmZmVyLCBzdGQ6OnNpemVfdCBsZW4sIEVycm9yKiBlcnIsCisgICAgICAgICAgICAgICAgICAgICAgaW50IHRpbWVvdXQgPSAwKSBvdmVycmlkZTsKKyAgdm9pZCBjbG9zZSgpIG92ZXJyaWRlOworCisgIGxsdm06OlN0cmluZ1JlZiBnZXRQZWVySVAoKSBjb25zdCBvdmVycmlkZTsKKyAgaW50IGdldFBlZXJQb3J0KCkgY29uc3Qgb3ZlcnJpZGU7CisgIHZvaWQgc2V0Tm9EZWxheSgpIG92ZXJyaWRlOworCisgIFRDUFN0cmVhbShjb25zdCBUQ1BTdHJlYW0mIHN0cmVhbSkgPSBkZWxldGU7CisgIFRDUFN0cmVhbSYgb3BlcmF0b3I9KGNvbnN0IFRDUFN0cmVhbSYpID0gZGVsZXRlOworIHByaXZhdGU6CisgIGJvb2wgV2FpdEZvclJlYWRFdmVudChpbnQgdGltZW91dCk7CisKKyAgVENQU3RyZWFtKGludCBzZCwgc3RydWN0IHNvY2thZGRyX2luKiBhZGRyZXNzKTsKKyAgVENQU3RyZWFtKCkgPSBkZWxldGU7Cit9OworCisjZW5kaWYK