LyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIAogKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lCiAqIG9yIG1vcmUgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZQogKiBkaXN0cmlidXRlZCB3aXRoIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbgogKiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4gIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlCiAqIHRvIHlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUKICogIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZQogKiB3aXRoIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqIAogKiAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKiAKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLAogKiBzb2Z0d2FyZSBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbgogKiAiQVMgSVMiIEJBU0lTLCBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkKICogS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4gIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlCiAqIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQgbGltaXRhdGlvbnMKICogdW5kZXIgdGhlIExpY2Vuc2UuCiAqIAogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KCgoKLy8gTUFSS0VSKHVwZGF0ZV9wcmVjb21wLnB5KTogYXV0b2dlbiBpbmNsdWRlIHN0YXRlbWVudCwgZG8gbm90IHJlbW92ZQojaW5jbHVkZSAicHJlY29tcGlsZWRfc3Z4Lmh4eCIKCiNpbmNsdWRlICJmbWNvbnRyb2xib3JkZXJtYW5hZ2VyLmh4eCIKI2luY2x1ZGUgImZtY29udHJvbGxheW91dC5oeHgiCiNpbmNsdWRlICJmb3JtY29udHJvbGxlci5oeHgiCiNpbmNsdWRlICJmb3JtZmVhdHVyZWRpc3BhdGNoZXIuaHh4IgojaW5jbHVkZSAiZm1kb2N1bWVudGNsYXNzaWZpY2F0aW9uLmh4eCIKI2luY2x1ZGUgImZvcm1jb250cm9sbGluZy5oeHgiCiNpbmNsdWRlICJmbXByb3AuaHJjIgojaW5jbHVkZSAic3Z4L2RpYWxtZ3IuaHh4IgojaW5jbHVkZSAic3Z4L2ZtcmVzaWRzLmhyYyIKI2luY2x1ZGUgImZtc2VydnMuaHh4IgojaW5jbHVkZSAic3Z4L2ZtdG9vbHMuaHh4IgojaW5jbHVkZSAiZm11cmwuaHh4IgoKLyoqID09PSBiZWdpbiBVTk8gaW5jbHVkZXMgPT09ICoqLwojaW5jbHVkZSA8Y29tL3N1bi9zdGFyL2F3dC9Gb2N1c0NoYW5nZVJlYXNvbi5ocHA+CiNpbmNsdWRlIDxjb20vc3VuL3N0YXIvYXd0L1hDaGVja0JveC5ocHA+CiNpbmNsdWRlIDxjb20vc3VuL3N0YXIvYXd0L1hDb21ib0JveC5ocHA+CiNpbmNsdWRlIDxjb20vc3VuL3N0YXIvYXd0L1hMaXN0Qm94LmhwcD4KI2luY2x1ZGUgPGNvbS9zdW4vc3Rhci9hd3QvWFZjbFdpbmRvd1BlZXIuaHBwPgojaW5jbHVkZSA8Y29tL3N1bi9zdGFyL2JlYW5zL05hbWVkVmFsdWUuaHBwPgojaW5jbHVkZSA8Y29tL3N1bi9zdGFyL2JlYW5zL1Byb3BlcnR5QXR0cmlidXRlLmhwcD4KI2luY2x1ZGUgPGNvbS9zdW4vc3Rhci9jb250YWluZXIvWElkZW50aWZpZXJSZXBsYWNlLmhwcD4KI2luY2x1ZGUgPGNvbS9zdW4vc3Rhci9mb3JtL1RhYnVsYXRvckN5Y2xlLmhwcD4KI2luY2x1ZGUgPGNvbS9zdW4vc3Rhci9mb3JtL3ZhbGlkYXRpb24vWFZhbGlkYXRhYmxlRm9ybUNvbXBvbmVudC5ocHA+CiNpbmNsdWRlIDxjb20vc3VuL3N0YXIvZm9ybS9YQm91bmRDb21wb25lbnQuaHBwPgojaW5jbHVkZSA8Y29tL3N1bi9zdGFyL2Zvcm0vWEJvdW5kQ29udHJvbC5ocHA+CiNpbmNsdWRlIDxjb20vc3VuL3N0YXIvZm9ybS9YR3JpZENvbnRyb2wuaHBwPgojaW5jbHVkZSA8Y29tL3N1bi9zdGFyL2Zvcm0vWExvYWRhYmxlLmhwcD4KI2luY2x1ZGUgPGNvbS9zdW4vc3Rhci9mb3JtL1hSZXNldC5ocHA+CiNpbmNsdWRlIDxjb20vc3VuL3N0YXIvZnJhbWUvWENvbnRyb2xsZXIuaHBwPgojaW5jbHVkZSA8Y29tL3N1bi9zdGFyL3NkYi9QYXJhbWV0ZXJzUmVxdWVzdC5ocHA+CiNpbmNsdWRlIDxjb20vc3VuL3N0YXIvc2RiL1Jvd0NoYW5nZUFjdGlvbi5ocHA+CiNpbmNsdWRlIDxjb20vc3VuL3N0YXIvc2RiL1hJbnRlcmFjdGlvblN1cHBseVBhcmFtZXRlcnMuaHBwPgojaW5jbHVkZSA8Y29tL3N1bi9zdGFyL3NkYmMvQ29sdW1uVmFsdWUuaHBwPgojaW5jbHVkZSA8Y29tL3N1bi9zdGFyL3NkYmMvRGF0YVR5cGUuaHBwPgojaW5jbHVkZSA8Y29tL3N1bi9zdGFyL3V0aWwvWFVSTFRyYW5zZm9ybWVyLmhwcD4KI2luY2x1ZGUgPGNvbS9zdW4vc3Rhci9mb3JtL3J1bnRpbWUvRm9ybU9wZXJhdGlvbnMuaHBwPgojaW5jbHVkZSA8Y29tL3N1bi9zdGFyL2Zvcm0vcnVudGltZS9Gb3JtRmVhdHVyZS5ocHA+CiNpbmNsdWRlIDxjb20vc3VuL3N0YXIvY29udGFpbmVyL1hDb250YWluZXIuaHBwPgojaW5jbHVkZSA8Y29tL3N1bi9zdGFyL3NkYmN4L1hDb2x1bW5zU3VwcGxpZXIuaHBwPgojaW5jbHVkZSA8Y29tL3N1bi9zdGFyL3V0aWwvWE51bWJlckZvcm1hdHRlci5ocHA+CiNpbmNsdWRlIDxjb20vc3VuL3N0YXIvc2RiL1NRTENvbnRleHQuaHBwPgojaW5jbHVkZSA8Y29tL3N1bi9zdGFyL3NkYi9YQ29sdW1uLmhwcD4KLyoqID09PSBlbmQgVU5PIGluY2x1ZGVzID09PSAqKi8KCiNpbmNsdWRlIDxjb21waGVscGVyL2VudW1oZWxwZXIuaHh4PgojaW5jbHVkZSA8Y29tcGhlbHBlci9leHRyYWN0Lmh4eD4KI2luY2x1ZGUgPGNvbXBoZWxwZXIvaW50ZXJhY3Rpb24uaHh4PgojaW5jbHVkZSA8Y29tcGhlbHBlci9uYW1lZHZhbHVlY29sbGVjdGlvbi5oeHg+CiNpbmNsdWRlIDxjb21waGVscGVyL3Byb3BhZ2cuaHh4PgojaW5jbHVkZSA8Y29tcGhlbHBlci9wcm9wZXJ0eS5oeHg+CiNpbmNsdWRlIDxjb21waGVscGVyL3NlcXVlbmNlLmh4eD4KI2luY2x1ZGUgPGNvbXBoZWxwZXIvdW5vMy5oeHg+CiNpbmNsdWRlIDxjb21waGVscGVyL2ZsYWdndWFyZC5oeHg+CiNpbmNsdWRlIDxjcHB1aGVscGVyL3F1ZXJ5aW50ZXJmYWNlLmh4eD4KI2luY2x1ZGUgPGNwcHVoZWxwZXIvdHlwZXByb3ZpZGVyLmh4eD4KI2luY2x1ZGUgPHRvb2xraXQvY29udHJvbHMvdW5vY29udHJvbC5oeHg+CiNpbmNsdWRlIDx0b29sa2l0L2hlbHBlci92Y2x1bm9oZWxwZXIuaHh4PgojaW5jbHVkZSA8dG9vbHMvZGVidWcuaHh4PgojaW5jbHVkZSA8dG9vbHMvZGlhZ25vc2VfZXguaD4KI2luY2x1ZGUgPHRvb2xzL3NobC5oeHg+CiNpbmNsdWRlIDx2Y2wvbXNnYm94Lmh4eD4KI2luY2x1ZGUgPHZjbC9zdmFwcC5oeHg+CiNpbmNsdWRlIDx2b3MvbXV0ZXguaHh4PgojaW5jbHVkZSA8cnRsL2xvZ2ZpbGUuaHh4PgoKI2luY2x1ZGUgPGFsZ29yaXRobT4KI2luY2x1ZGUgPGZ1bmN0aW9uYWw+Cgp1c2luZyBuYW1lc3BhY2UgOjpjb206OnN1bjo6c3RhcjsKdXNpbmcgbmFtZXNwYWNlIDo6Y29tcGhlbHBlcjsKdXNpbmcgbmFtZXNwYWNlIDo6Y29ubmVjdGl2aXR5Owp1c2luZyBuYW1lc3BhY2UgOjpjb25uZWN0aXZpdHk6OnNpbXBsZTsKCi8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCjo6Y29tOjpzdW46OnN0YXI6OnVubzo6UmVmZXJlbmNlPCA6OmNvbTo6c3VuOjpzdGFyOjp1bm86OlhJbnRlcmZhY2UgPiBTQUxfQ0FMTAogICAgRm9ybUNvbnRyb2xsZXJfTmV3SW5zdGFuY2VfSW1wbCggY29uc3QgOjpjb206OnN1bjo6c3Rhcjo6dW5vOjpSZWZlcmVuY2U8IDo6Y29tOjpzdW46OnN0YXI6Omxhbmc6OlhNdWx0aVNlcnZpY2VGYWN0b3J5ID4gJiBfcnhPUkIgKQp7CiAgICByZXR1cm4gKiggbmV3IDo6c3Z4Zm9ybTo6Rm9ybUNvbnRyb2xsZXIoIF9yeE9SQiApICk7Cn0KCm5hbWVzcGFjZSBzdnhmb3JtCnsKCiAgICAvKiogPT09IGJlZ2luIFVOTyB1c2luZyA9PT0gKiovCiAgICB1c2luZyA6OmNvbTo6c3VuOjpzdGFyOjpzZGI6OlhDb2x1bW47CiAgICB1c2luZyA6OmNvbTo6c3VuOjpzdGFyOjphd3Q6OlhDb250cm9sOwogICAgdXNpbmcgOjpjb206OnN1bjo6c3Rhcjo6YXd0OjpYVGFiQ29udHJvbGxlcjsKICAgIHVzaW5nIDo6Y29tOjpzdW46OnN0YXI6OmF3dDo6WFRvb2xraXQ7CiAgICB1c2luZyA6OmNvbTo6c3VuOjpzdGFyOjphd3Q6OlhXaW5kb3dQZWVyOwogICAgdXNpbmcgOjpjb206OnN1bjo6c3Rhcjo6Zm9ybTo6WEdyaWQ7CiAgICB1c2luZyA6OmNvbTo6c3VuOjpzdGFyOjpiZWFuczo6WFByb3BlcnR5U2V0OwogICAgdXNpbmcgOjpjb206OnN1bjo6c3Rhcjo6dW5vOjpVTk9fU0VUX1RIUk9XOwogICAgdXNpbmcgOjpjb206OnN1bjo6c3Rhcjo6dW5vOjpVTk9fUVVFUllfVEhST1c7CiAgICB1c2luZyA6OmNvbTo6c3VuOjpzdGFyOjpjb250YWluZXI6OlhJbmRleEFjY2VzczsKICAgIHVzaW5nIDo6Y29tOjpzdW46OnN0YXI6OnVubzo6RXhjZXB0aW9uOwogICAgdXNpbmcgOjpjb206OnN1bjo6c3Rhcjo6dW5vOjpYSW50ZXJmYWNlOwogICAgdXNpbmcgOjpjb206OnN1bjo6c3Rhcjo6dW5vOjpVTk9fUVVFUlk7CiAgICB1c2luZyA6OmNvbTo6c3VuOjpzdGFyOjp1bm86OlNlcXVlbmNlOwogICAgdXNpbmcgOjpjb206OnN1bjo6c3Rhcjo6dW5vOjpSZWZlcmVuY2U7CiAgICB1c2luZyA6OmNvbTo6c3VuOjpzdGFyOjpiZWFuczo6WFByb3BlcnR5U2V0SW5mbzsKICAgIHVzaW5nIDo6Y29tOjpzdW46OnN0YXI6OmJlYW5zOjpQcm9wZXJ0eVZhbHVlOwogICAgdXNpbmcgOjpjb206OnN1bjo6c3Rhcjo6dW5vOjpSdW50aW1lRXhjZXB0aW9uOwogICAgdXNpbmcgOjpjb206OnN1bjo6c3Rhcjo6bGFuZzo6SW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbjsKICAgIHVzaW5nIDo6Y29tOjpzdW46OnN0YXI6OnNkYjo6WEludGVyYWN0aW9uU3VwcGx5UGFyYW1ldGVyczsKICAgIHVzaW5nIDo6Y29tOjpzdW46OnN0YXI6OmF3dDo6WFRleHRDb21wb25lbnQ7CiAgICB1c2luZyA6OmNvbTo6c3VuOjpzdGFyOjphd3Q6OlhUZXh0TGlzdGVuZXI7CiAgICB1c2luZyA6OmNvbTo6c3VuOjpzdGFyOjp1bm86OkFueTsKICAgIHVzaW5nIDo6Y29tOjpzdW46OnN0YXI6OmZyYW1lOjpYRGlzcGF0Y2g7CiAgICB1c2luZyA6OmNvbTo6c3VuOjpzdGFyOjpsYW5nOjpYTXVsdGlTZXJ2aWNlRmFjdG9yeTsKICAgIHVzaW5nIDo6Y29tOjpzdW46OnN0YXI6OnVubzo6WEFnZ3JlZ2F0aW9uOwogICAgdXNpbmcgOjpjb206OnN1bjo6c3Rhcjo6dW5vOjpUeXBlOwogICAgdXNpbmcgOjpjb206OnN1bjo6c3Rhcjo6bGFuZzo6SWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uOwogICAgdXNpbmcgOjpjb206OnN1bjo6c3Rhcjo6c2RiYzo6WENvbm5lY3Rpb247CiAgICB1c2luZyA6OmNvbTo6c3VuOjpzdGFyOjpzZGJjOjpYUm93U2V0OwogICAgdXNpbmcgOjpjb206OnN1bjo6c3Rhcjo6c2RiYzo6WERhdGFiYXNlTWV0YURhdGE7CiAgICB1c2luZyA6OmNvbTo6c3VuOjpzdGFyOjp1dGlsOjpYTnVtYmVyRm9ybWF0c1N1cHBsaWVyOwogICAgdXNpbmcgOjpjb206OnN1bjo6c3Rhcjo6dXRpbDo6WE51bWJlckZvcm1hdHRlcjsKICAgIHVzaW5nIDo6Y29tOjpzdW46OnN0YXI6OnNkYmN4OjpYQ29sdW1uc1N1cHBsaWVyOwogICAgdXNpbmcgOjpjb206OnN1bjo6c3Rhcjo6Y29udGFpbmVyOjpYTmFtZUFjY2VzczsKICAgIHVzaW5nIDo6Y29tOjpzdW46OnN0YXI6Omxhbmc6OkV2ZW50T2JqZWN0OwogICAgdXNpbmcgOjpjb206OnN1bjo6c3Rhcjo6YmVhbnM6OlByb3BlcnR5OwogICAgdXNpbmcgOjpjb206OnN1bjo6c3Rhcjo6Y29udGFpbmVyOjpYRW51bWVyYXRpb247CiAgICB1c2luZyA6OmNvbTo6c3VuOjpzdGFyOjpmb3JtOjpYRm9ybUNvbXBvbmVudDsKICAgIHVzaW5nIDo6Y29tOjpzdW46OnN0YXI6OmZvcm06OnJ1bnRpbWU6OlhGb3JtT3BlcmF0aW9uczsKICAgIHVzaW5nIDo6Y29tOjpzdW46OnN0YXI6OmZvcm06OnJ1bnRpbWU6OkZpbHRlckV2ZW50OwogICAgdXNpbmcgOjpjb206OnN1bjo6c3Rhcjo6Zm9ybTo6cnVudGltZTo6WEZpbHRlckNvbnRyb2xsZXJMaXN0ZW5lcjsKICAgIHVzaW5nIDo6Y29tOjpzdW46OnN0YXI6OmF3dDo6WENvbnRyb2xDb250YWluZXI7CiAgICB1c2luZyA6OmNvbTo6c3VuOjpzdGFyOjpjb250YWluZXI6OlhJZGVudGlmaWVyUmVwbGFjZTsKICAgIHVzaW5nIDo6Y29tOjpzdW46OnN0YXI6Omxhbmc6OldyYXBwZWRUYXJnZXRFeGNlcHRpb247CiAgICB1c2luZyA6OmNvbTo6c3VuOjpzdGFyOjpmb3JtOjpYRm9ybUNvbnRyb2xsZXJMaXN0ZW5lcjsKICAgIHVzaW5nIDo6Y29tOjpzdW46OnN0YXI6OmF3dDo6WFdpbmRvdzsKICAgIHVzaW5nIDo6Y29tOjpzdW46OnN0YXI6OnNkYmM6OlhSZXN1bHRTZXQ7CiAgICB1c2luZyA6OmNvbTo6c3VuOjpzdGFyOjphd3Q6OlhDb250cm9sTW9kZWw7CiAgICB1c2luZyA6OmNvbTo6c3VuOjpzdGFyOjphd3Q6OlhUYWJDb250cm9sbGVyTW9kZWw7CiAgICB1c2luZyA6OmNvbTo6c3VuOjpzdGFyOjpiZWFuczo6UHJvcGVydHlDaGFuZ2VFdmVudDsKICAgIHVzaW5nIDo6Y29tOjpzdW46OnN0YXI6OmZvcm06OnZhbGlkYXRpb246OlhWYWxpZGF0YWJsZUZvcm1Db21wb25lbnQ7CiAgICB1c2luZyA6OmNvbTo6c3VuOjpzdGFyOjpmb3JtOjpYTG9hZGFibGU7CiAgICB1c2luZyA6OmNvbTo6c3VuOjpzdGFyOjpzY3JpcHQ6OlhFdmVudEF0dGFjaGVyTWFuYWdlcjsKICAgIHVzaW5nIDo6Y29tOjpzdW46OnN0YXI6OmZvcm06OlhCb3VuZENvbnRyb2w7CiAgICB1c2luZyA6OmNvbTo6c3VuOjpzdGFyOjpiZWFuczo6WFByb3BlcnR5Q2hhbmdlTGlzdGVuZXI7CiAgICB1c2luZyA6OmNvbTo6c3VuOjpzdGFyOjphd3Q6OlRleHRFdmVudDsKICAgIHVzaW5nIDo6Y29tOjpzdW46OnN0YXI6OmZvcm06OlhCb3VuZENvbXBvbmVudDsKICAgIHVzaW5nIDo6Y29tOjpzdW46OnN0YXI6OmF3dDo6WENoZWNrQm94OwogICAgdXNpbmcgOjpjb206OnN1bjo6c3Rhcjo6YXd0OjpYQ29tYm9Cb3g7CiAgICB1c2luZyA6OmNvbTo6c3VuOjpzdGFyOjphd3Q6OlhMaXN0Qm94OwogICAgdXNpbmcgOjpjb206OnN1bjo6c3Rhcjo6YXd0OjpJdGVtRXZlbnQ7CiAgICB1c2luZyA6OmNvbTo6c3VuOjpzdGFyOjp1dGlsOjpYTW9kaWZ5TGlzdGVuZXI7CiAgICB1c2luZyA6OmNvbTo6c3VuOjpzdGFyOjpmb3JtOjpYUmVzZXQ7CiAgICB1c2luZyA6OmNvbTo6c3VuOjpzdGFyOjpmcmFtZTo6WERpc3BhdGNoUHJvdmlkZXJJbnRlcmNlcHRpb247CiAgICB1c2luZyA6OmNvbTo6c3VuOjpzdGFyOjpmb3JtOjpYR3JpZENvbnRyb2w7CiAgICB1c2luZyA6OmNvbTo6c3VuOjpzdGFyOjphd3Q6OlhWY2xXaW5kb3dQZWVyOwogICAgdXNpbmcgOjpjb206OnN1bjo6c3Rhcjo6Zm9ybTo6dmFsaWRhdGlvbjo6WFZhbGlkYXRvcjsKICAgIHVzaW5nIDo6Y29tOjpzdW46OnN0YXI6OmF3dDo6Rm9jdXNFdmVudDsKICAgIHVzaW5nIDo6Y29tOjpzdW46OnN0YXI6OnNkYjo6U1FMQ29udGV4dDsKICAgIHVzaW5nIDo6Y29tOjpzdW46OnN0YXI6OmNvbnRhaW5lcjo6WENoaWxkOwogICAgdXNpbmcgOjpjb206OnN1bjo6c3Rhcjo6Zm9ybTo6VGFidWxhdG9yQ3ljbGVfUkVDT1JEUzsKICAgIHVzaW5nIDo6Y29tOjpzdW46OnN0YXI6OmNvbnRhaW5lcjo6Q29udGFpbmVyRXZlbnQ7CiAgICB1c2luZyA6OmNvbTo6c3VuOjpzdGFyOjpsYW5nOjpEaXNwb3NlZEV4Y2VwdGlvbjsKICAgIHVzaW5nIDo6Y29tOjpzdW46OnN0YXI6Omxhbmc6OkxvY2FsZTsKICAgIHVzaW5nIDo6Y29tOjpzdW46OnN0YXI6OmJlYW5zOjpOYW1lZFZhbHVlOwogICAgdXNpbmcgOjpjb206OnN1bjo6c3Rhcjo6bGFuZzo6Tm9TdXBwb3J0RXhjZXB0aW9uOwogICAgdXNpbmcgOjpjb206OnN1bjo6c3Rhcjo6c2RiOjpSb3dDaGFuZ2VFdmVudDsKICAgIHVzaW5nIDo6Y29tOjpzdW46OnN0YXI6OmZyYW1lOjpYU3RhdHVzTGlzdGVuZXI7CiAgICB1c2luZyA6OmNvbTo6c3VuOjpzdGFyOjpmcmFtZTo6WERpc3BhdGNoUHJvdmlkZXJJbnRlcmNlcHRvcjsKICAgIHVzaW5nIDo6Y29tOjpzdW46OnN0YXI6OnNkYjo6U1FMRXJyb3JFdmVudDsKICAgIHVzaW5nIDo6Y29tOjpzdW46OnN0YXI6OmZvcm06OkRhdGFiYXNlUGFyYW1ldGVyRXZlbnQ7CiAgICB1c2luZyA6OmNvbTo6c3VuOjpzdGFyOjpzZGI6OlBhcmFtZXRlcnNSZXF1ZXN0OwogICAgdXNpbmcgOjpjb206OnN1bjo6c3Rhcjo6dGFzazo6WEludGVyYWN0aW9uUmVxdWVzdDsKICAgIHVzaW5nIDo6Y29tOjpzdW46OnN0YXI6OnV0aWw6OlVSTDsKICAgIHVzaW5nIDo6Y29tOjpzdW46OnN0YXI6OmZyYW1lOjpGZWF0dXJlU3RhdGVFdmVudDsKICAgIHVzaW5nIDo6Y29tOjpzdW46OnN0YXI6OmZvcm06OnJ1bnRpbWU6OlhGb3JtQ29udHJvbGxlckNvbnRleHQ7CiAgICB1c2luZyA6OmNvbTo6c3VuOjpzdGFyOjp0YXNrOjpYSW50ZXJhY3Rpb25IYW5kbGVyOwogICAgdXNpbmcgOjpjb206OnN1bjo6c3Rhcjo6Zm9ybTo6cnVudGltZTo6Rm9ybU9wZXJhdGlvbnM7CiAgICB1c2luZyA6OmNvbTo6c3VuOjpzdGFyOjpjb250YWluZXI6OlhDb250YWluZXI7CiAgICB1c2luZyA6OmNvbTo6c3VuOjpzdGFyOjpzZGJjOjpTUUxXYXJuaW5nOwogICAgLyoqID09PSBlbmQgVU5PIHVzaW5nID09PSAqKi8KICAgIG5hbWVzcGFjZSBDb2x1bW5WYWx1ZSA9IDo6Y29tOjpzdW46OnN0YXI6OnNkYmM6OkNvbHVtblZhbHVlOwogICAgbmFtZXNwYWNlIFByb3BlcnR5QXR0cmlidXRlID0gOjpjb206OnN1bjo6c3Rhcjo6YmVhbnM6OlByb3BlcnR5QXR0cmlidXRlOwogICAgbmFtZXNwYWNlIEZvY3VzQ2hhbmdlUmVhc29uID0gOjpjb206OnN1bjo6c3Rhcjo6YXd0OjpGb2N1c0NoYW5nZVJlYXNvbjsKICAgIG5hbWVzcGFjZSBSb3dDaGFuZ2VBY3Rpb24gPSA6OmNvbTo6c3VuOjpzdGFyOjpzZGI6OlJvd0NoYW5nZUFjdGlvbjsKICAgIG5hbWVzcGFjZSBGb3JtRmVhdHVyZSA9IDo6Y29tOjpzdW46OnN0YXI6OmZvcm06OnJ1bnRpbWU6OkZvcm1GZWF0dXJlOwogICAgbmFtZXNwYWNlIERhdGFUeXBlID0gOjpjb206OnN1bjo6c3Rhcjo6c2RiYzo6RGF0YVR5cGU7CgovLz09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQovLyBDb2x1bW5JbmZvCi8vPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CnN0cnVjdCBDb2x1bW5JbmZvCnsKICAgIC8vIGluZm9ybWF0aW9uIGFib3V0IHRoZSBjb2x1bW4gaXRzZWxmCiAgICBSZWZlcmVuY2U8IFhDb2x1bW4gPiAgICB4Q29sdW1uOwogICAgc2FsX0ludDMyICAgICAgICAgICAgICAgbk51bGxhYmxlOwogICAgc2FsX0Jvb2wgICAgICAgICAgICAgICAgYkF1dG9JbmNyZW1lbnQ7CiAgICBzYWxfQm9vbCAgICAgICAgICAgICAgICBiUmVhZE9ubHk7CiAgICA6OnJ0bDo6T1VTdHJpbmcgICAgICAgICBzTmFtZTsKCiAgICAvLyBpbmZvcm1hdGlvbiBhYm91dCB0aGUgY29udHJvbChzKSBib3VuZCB0byB0aGlzIGNvbHVtbgoKICAgIC8vLyB0aGUgZmlyc3QgY29udHJvbCB3aGljaCBpcyBib3VuZCB0byB0aGUgZ2l2ZW4gY29sdW1uLCBhbmQgd2hpY2ggcmVxdWlyZXMgaW5wdXQKICAgIFJlZmVyZW5jZTwgWENvbnRyb2wgPiAgIHhGaXJzdENvbnRyb2xXaXRoSW5wdXRSZXF1aXJlZDsKICAgIC8qKiB0aGUgZmlyc3QgZ3JpZCBjb250cm9sIHdoaWNoIGNvbnRhaW5zIGEgY29sdW1uIHdoaWNoIGlzIGJvdW5kIHRvIHRoZSBnaXZlbiBkYXRhYmFzZSBjb2x1bW4sIGFuZCByZXF1aXJlcwogICAgICAgIGlucHV0CiAgICAqLwogICAgUmVmZXJlbmNlPCBYR3JpZCA+ICAgICAgeEZpcnN0R3JpZFdpdGhJbnB1dFJlcXVpcmVkQ29sdW1uOwogICAgLyoqIGlmIHhGaXJzdENvbnRyb2xXaXRoSW5wdXRSZXF1aXJlZCBpcyBhIGdyaWQgY29udHJvbCwgdGhlbiBuUmVxdWlyZWRHcmlkQ29sdW1uIHNwZWNpZmllcyB0aGUgcG9zaXRpb24KICAgICAgICBvZiB0aGUgZ3JpZCBjb2x1bW4gd2hpY2ggaXMgYWN0dWFsbHkgYm91bmQKICAgICovCiAgICBzYWxfSW50MzIgICAgICAgICAgICAgICBuUmVxdWlyZWRHcmlkQ29sdW1uOwoKICAgIENvbHVtbkluZm8oKQogICAgICAgIDp4Q29sdW1uKCkKICAgICAgICAsbk51bGxhYmxlKCBDb2x1bW5WYWx1ZTo6TlVMTEFCTEVfVU5LTk9XTiApCiAgICAgICAgLGJBdXRvSW5jcmVtZW50KCBzYWxfRmFsc2UgKQogICAgICAgICxiUmVhZE9ubHkoIHNhbF9GYWxzZSApCiAgICAgICAgLHNOYW1lKCkKICAgICAgICAseEZpcnN0Q29udHJvbFdpdGhJbnB1dFJlcXVpcmVkKCkKICAgICAgICAseEZpcnN0R3JpZFdpdGhJbnB1dFJlcXVpcmVkQ29sdW1uKCkKICAgICAgICAsblJlcXVpcmVkR3JpZENvbHVtbiggLTEgKQogICAgewogICAgfQp9OwoKLy89PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLy89IENvbHVtbkluZm9DYWNoZQovLz09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQpjbGFzcyBDb2x1bW5JbmZvQ2FjaGUKewpwdWJsaWM6CiAgICBDb2x1bW5JbmZvQ2FjaGUoIGNvbnN0IFJlZmVyZW5jZTwgWENvbHVtbnNTdXBwbGllciA+JiBfcnhDb2xTdXBwbGllciApOwoKICAgIHNpemVfdCAgICAgICAgZ2V0Q29sdW1uQ291bnQoKSBjb25zdCB7IHJldHVybiBtX2FDb2x1bW5zLnNpemUoKTsgfQogICAgY29uc3QgQ29sdW1uSW5mbyYgICBnZXRDb2x1bW5JbmZvKCBzaXplX3QgX3BvcyApOwoKICAgIGJvb2wgICAgY29udHJvbHNJbml0aWFsaXplZCgpIGNvbnN0IHsgcmV0dXJuIG1fYkNvbnRyb2xzSW5pdGlhbGl6ZWQ7IH0KICAgIHZvaWQgICAgaW5pdGlhbGl6ZUNvbnRyb2xzKCBjb25zdCBTZXF1ZW5jZTwgUmVmZXJlbmNlPCBYQ29udHJvbCA+ID4mIF9yQ29udHJvbHMgKTsKICAgIHZvaWQgICAgZGVpbml0aWFsaXplQ29udHJvbHMoKTsKCnByaXZhdGU6CiAgICB0eXBlZGVmIDo6c3RkOjp2ZWN0b3I8IENvbHVtbkluZm8gPiBDb2x1bW5JbmZvczsKICAgIENvbHVtbkluZm9zICAgICAgICAgICAgICAgICAgICAgICAgIG1fYUNvbHVtbnM7CiAgICBib29sICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtX2JDb250cm9sc0luaXRpYWxpemVkOwp9OwoKLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KQ29sdW1uSW5mb0NhY2hlOjpDb2x1bW5JbmZvQ2FjaGUoIGNvbnN0IFJlZmVyZW5jZTwgWENvbHVtbnNTdXBwbGllciA+JiBfcnhDb2xTdXBwbGllciApCiAgICA6bV9hQ29sdW1ucygpCiAgICAsbV9iQ29udHJvbHNJbml0aWFsaXplZCggZmFsc2UgKQp7CiAgICB0cnkKICAgIHsKICAgICAgICBtX2FDb2x1bW5zLmNsZWFyKCk7CgogICAgICAgIFJlZmVyZW5jZTwgWENvbHVtbnNTdXBwbGllciA+IHhTdXBwbHlDb2xzKCBfcnhDb2xTdXBwbGllciwgVU5PX1NFVF9USFJPVyApOwogICAgICAgIFJlZmVyZW5jZTwgWEluZGV4QWNjZXNzID4geENvbHVtbnMoIHhTdXBwbHlDb2xzLT5nZXRDb2x1bW5zKCksIFVOT19RVUVSWV9USFJPVyApOwogICAgICAgIHNhbF9JbnQzMiBuQ29sdW1uQ291bnQgPSB4Q29sdW1ucy0+Z2V0Q291bnQoKTsKICAgICAgICBtX2FDb2x1bW5zLnJlc2VydmUoIG5Db2x1bW5Db3VudCApOwoKICAgICAgICBSZWZlcmVuY2U8IFhQcm9wZXJ0eVNldCA+ICAgeENvbHVtblByb3BzOwogICAgICAgIGZvciAoIHNhbF9JbnQzMiBpID0gMDsgaSA8IG5Db2x1bW5Db3VudDsgKytpICkKICAgICAgICB7CiAgICAgICAgICAgIENvbHVtbkluZm8gYUNvbEluZm87CiAgICAgICAgICAgIGFDb2xJbmZvLnhDb2x1bW4uc2V0KCB4Q29sdW1ucy0+Z2V0QnlJbmRleChpKSwgVU5PX1FVRVJZX1RIUk9XICk7CgogICAgICAgICAgICB4Q29sdW1uUHJvcHMuc2V0KCBhQ29sSW5mby54Q29sdW1uLCBVTk9fUVVFUllfVEhST1cgKTsKICAgICAgICAgICAgT1NMX1ZFUklGWSggeENvbHVtblByb3BzLT5nZXRQcm9wZXJ0eVZhbHVlKCBGTV9QUk9QX0lTTlVMTEFCTEUgKSA+Pj0gYUNvbEluZm8ubk51bGxhYmxlICk7CiAgICAgICAgICAgIE9TTF9WRVJJRlkoIHhDb2x1bW5Qcm9wcy0+Z2V0UHJvcGVydHlWYWx1ZSggRk1fUFJPUF9BVVRPSU5DUkVNRU5UICkgPj49IGFDb2xJbmZvLmJBdXRvSW5jcmVtZW50ICk7CiAgICAgICAgICAgIE9TTF9WRVJJRlkoIHhDb2x1bW5Qcm9wcy0+Z2V0UHJvcGVydHlWYWx1ZSggRk1fUFJPUF9OQU1FICkgPj49IGFDb2xJbmZvLnNOYW1lICk7CiAgICAgICAgICAgIE9TTF9WRVJJRlkoIHhDb2x1bW5Qcm9wcy0+Z2V0UHJvcGVydHlWYWx1ZSggRk1fUFJPUF9JU1JFQURPTkxZICkgPj49IGFDb2xJbmZvLmJSZWFkT25seSApOwoKICAgICAgICAgICAgbV9hQ29sdW1ucy5wdXNoX2JhY2soIGFDb2xJbmZvICk7CiAgICAgICAgfQogICAgfQogICAgY2F0Y2goIGNvbnN0IEV4Y2VwdGlvbiYgKQogICAgewogICAgCURCR19VTkhBTkRMRURfRVhDRVBUSU9OKCk7CiAgICB9Cn0KCi8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCm5hbWVzcGFjZQp7CiAgICBib29sIGxjbF9pc0JvdW5kVG8oIGNvbnN0IFJlZmVyZW5jZTwgWFByb3BlcnR5U2V0ID4mIF9yeENvbnRyb2xNb2RlbCwgY29uc3QgUmVmZXJlbmNlPCBYSW50ZXJmYWNlID4mIF9yeE5vcm1EQkZpZWxkICkKICAgIHsKICAgICAgICBSZWZlcmVuY2U8IFhJbnRlcmZhY2UgPiB4Tm9ybUJvdW5kRmllbGQoIF9yeENvbnRyb2xNb2RlbC0+Z2V0UHJvcGVydHlWYWx1ZSggRk1fUFJPUF9CT1VOREZJRUxEICksIFVOT19RVUVSWSApOwogICAgICAgIHJldHVybiAoIHhOb3JtQm91bmRGaWVsZC5nZXQoKSA9PSBfcnhOb3JtREJGaWVsZC5nZXQoKSApOwogICAgfQoKICAgIGJvb2wgbGNsX2lzSW5wdXRSZXF1aXJlZCggY29uc3QgUmVmZXJlbmNlPCBYUHJvcGVydHlTZXQgPiYgX3J4Q29udHJvbE1vZGVsICkKICAgIHsKICAgICAgICBzYWxfQm9vbCBiSW5wdXRSZXF1aXJlZCA9IHNhbF9UcnVlOwogICAgICAgIE9TTF9WRVJJRlkoIF9yeENvbnRyb2xNb2RlbC0+Z2V0UHJvcGVydHlWYWx1ZSggRk1fUFJPUF9JTlBVVF9SRVFVSVJFRCApID4+PSBiSW5wdXRSZXF1aXJlZCApOwogICAgICAgIHJldHVybiAoIGJJbnB1dFJlcXVpcmVkICE9IHNhbF9GYWxzZSApOwogICAgfQoKICAgIHZvaWQgbGNsX3Jlc2V0Q29sdW1uQ29udHJvbEluZm8oIENvbHVtbkluZm8mIF9yQ29sSW5mbyApCiAgICB7CiAgICAgICAgX3JDb2xJbmZvLnhGaXJzdENvbnRyb2xXaXRoSW5wdXRSZXF1aXJlZC5jbGVhcigpOwogICAgICAgIF9yQ29sSW5mby54Rmlyc3RHcmlkV2l0aElucHV0UmVxdWlyZWRDb2x1bW4uY2xlYXIoKTsKICAgICAgICBfckNvbEluZm8ublJlcXVpcmVkR3JpZENvbHVtbiA9IC0xOwogICAgfQp9CgovLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQp2b2lkIENvbHVtbkluZm9DYWNoZTo6ZGVpbml0aWFsaXplQ29udHJvbHMoKQp7CiAgICBmb3IgKCAgIENvbHVtbkluZm9zOjppdGVyYXRvciBjb2wgPSBtX2FDb2x1bW5zLmJlZ2luKCk7CiAgICAgICAgICAgIGNvbCAhPSBtX2FDb2x1bW5zLmVuZCgpOwogICAgICAgICAgICArK2NvbAogICAgICAgICkKICAgIHsKICAgICAgICBsY2xfcmVzZXRDb2x1bW5Db250cm9sSW5mbyggKmNvbCApOwogICAgfQp9CgovLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQp2b2lkIENvbHVtbkluZm9DYWNoZTo6aW5pdGlhbGl6ZUNvbnRyb2xzKCBjb25zdCBTZXF1ZW5jZTwgUmVmZXJlbmNlPCBYQ29udHJvbCA+ID4mIF9yQ29udHJvbHMgKQp7CiAgICB0cnkKICAgIHsKICAgICAgICAvLyBmb3IgZXZlcnkgb2Ygb3VyIGtub3duIGNvbHVtbnMsIGZpbmQgdGhlIGNvbnRyb2xzIHdoaWNoIGFyZSBib3VuZCB0byB0aGlzIGNvbHVtbgogICAgICAgIGZvciAoICAgQ29sdW1uSW5mb3M6Oml0ZXJhdG9yIGNvbCA9IG1fYUNvbHVtbnMuYmVnaW4oKTsKICAgICAgICAgICAgICAgIGNvbCAhPSBtX2FDb2x1bW5zLmVuZCgpOwogICAgICAgICAgICAgICAgKytjb2wKICAgICAgICAgICAgKQogICAgICAgIHsKICAgICAgICAgICAgT1NMX0VOU1VSRSggIWNvbC0+eEZpcnN0Q29udHJvbFdpdGhJbnB1dFJlcXVpcmVkLmlzKCkgJiYgIWNvbC0+eEZpcnN0R3JpZFdpdGhJbnB1dFJlcXVpcmVkQ29sdW1uLmlzKCkKICAgICAgICAgICAgICAgICYmICggY29sLT5uUmVxdWlyZWRHcmlkQ29sdW1uID09IC0xICksICJDb2x1bW5JbmZvQ2FjaGU6OmluaXRpYWxpemVDb250cm9sczogY2FsbGVkIG1lIHR3aWNlPyIgKTsKCiAgICAgICAgICAgIGxjbF9yZXNldENvbHVtbkNvbnRyb2xJbmZvKCAqY29sICk7CgogICAgICAgICAgICBSZWZlcmVuY2U8IFhJbnRlcmZhY2UgPiB4Tm9ybUNvbHVtbiggY29sLT54Q29sdW1uLCBVTk9fUVVFUllfVEhST1cgKTsKCiAgICAgICAgICAgIGNvbnN0IFJlZmVyZW5jZTwgWENvbnRyb2wgPiogcENvbnRyb2woIF9yQ29udHJvbHMuZ2V0Q29uc3RBcnJheSgpICk7CiAgICAgICAgICAgIGNvbnN0IFJlZmVyZW5jZTwgWENvbnRyb2wgPiogcENvbnRyb2xFbmQoIHBDb250cm9sICsgX3JDb250cm9scy5nZXRMZW5ndGgoKSApOwogICAgICAgICAgICBmb3IgKCA7IHBDb250cm9sICE9IHBDb250cm9sRW5kOyArK3BDb250cm9sICkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgaWYgKCAhcENvbnRyb2wtPmlzKCkgKQogICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlOwoKICAgICAgICAgICAgICAgIFJlZmVyZW5jZTwgWFByb3BlcnR5U2V0ID4geE1vZGVsKCAoKnBDb250cm9sKS0+Z2V0TW9kZWwoKSwgVU5PX1FVRVJZX1RIUk9XICk7CiAgICAgICAgICAgICAgICBSZWZlcmVuY2U8IFhQcm9wZXJ0eVNldEluZm8gPiB4TW9kZWxQU0koIHhNb2RlbC0+Z2V0UHJvcGVydHlTZXRJbmZvKCksIFVOT19TRVRfVEhST1cgKTsKCiAgICAgICAgICAgICAgICAvLyBzcGVjaWFsIGhhbmRsaW5nIGZvciBncmlkIGNvbnRyb2xzCiAgICAgICAgICAgICAgICBSZWZlcmVuY2U8IFhHcmlkID4geEdyaWQoICpwQ29udHJvbCwgVU5PX1FVRVJZICk7CiAgICAgICAgICAgICAgICBpZiAoIHhHcmlkLmlzKCkgKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIFJlZmVyZW5jZTwgWEluZGV4QWNjZXNzID4geEdyaWRDb2xBY2Nlc3MoIHhNb2RlbCwgVU5PX1FVRVJZX1RIUk9XICk7CiAgICAgICAgICAgICAgICAgICAgc2FsX0ludDMyIGdyaWRDb2xDb3VudCA9IHhHcmlkQ29sQWNjZXNzLT5nZXRDb3VudCgpOwogICAgICAgICAgICAgICAgICAgIHNhbF9JbnQzMiBncmlkQ29sID0gMDsKICAgICAgICAgICAgICAgICAgICBmb3IgKCBncmlkQ29sID0gMDsgZ3JpZENvbCA8IGdyaWRDb2xDb3VudDsgKytncmlkQ29sICkKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIFJlZmVyZW5jZTwgWFByb3BlcnR5U2V0ID4geEdyaWRDb2x1bW5Nb2RlbCggeEdyaWRDb2xBY2Nlc3MtPmdldEJ5SW5kZXgoIGdyaWRDb2wgKSwgVU5PX1FVRVJZX1RIUk9XICk7CgogICAgICAgICAgICAgICAgICAgICAgICBpZiAgKCAgICFsY2xfaXNCb3VuZFRvKCB4R3JpZENvbHVtbk1vZGVsLCB4Tm9ybUNvbHVtbiApCiAgICAgICAgICAgICAgICAgICAgICAgICAgICB8fCAgIWxjbF9pc0lucHV0UmVxdWlyZWQoIHhHcmlkQ29sdW1uTW9kZWwgKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgY29udGludWU7ICAgLy8gd2l0aCBuZXh0IGdyaWQgY29sdW1uCgogICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgIGlmICggZ3JpZENvbCA8IGdyaWRDb2xDb3VudCApCiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAvLyBmb3VuZCBhIGdyaWQgY29sdW1uIHdoaWNoIGlzIGJvdW5kIHRvIHRoZSBnaXZlbgogICAgICAgICAgICAgICAgICAgICAgICBjb2wtPnhGaXJzdEdyaWRXaXRoSW5wdXRSZXF1aXJlZENvbHVtbiA9IHhHcmlkOwogICAgICAgICAgICAgICAgICAgICAgICBjb2wtPm5SZXF1aXJlZEdyaWRDb2x1bW4gPSBncmlkQ29sOwogICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlOyAgIC8vIHdpdGggbmV4dCBjb250cm9sCiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgaWYgICggICAheE1vZGVsUFNJLT5oYXNQcm9wZXJ0eUJ5TmFtZSggRk1fUFJPUF9CT1VOREZJRUxEICkKICAgICAgICAgICAgICAgICAgICB8fCAgIWxjbF9pc0JvdW5kVG8oIHhNb2RlbCwgeE5vcm1Db2x1bW4gKQogICAgICAgICAgICAgICAgICAgIHx8ICAhbGNsX2lzSW5wdXRSZXF1aXJlZCggeE1vZGVsICkKICAgICAgICAgICAgICAgICAgICApCiAgICAgICAgICAgICAgICAgICAgY29udGludWU7ICAgLy8gd2l0aCBuZXh0IGNvbnRyb2wKCiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgaWYgKCBwQ29udHJvbCA9PSBwQ29udHJvbEVuZCApCiAgICAgICAgICAgICAgICAvLyBkaWQgbm90IGZpbmQgYSBjb250cm9sIHdoaWNoIGlzIGJvdW5kIHRvIHRoaXMgcGFydGljdWxhciBjb2x1bW4sIGFuZCBmb3Igd2hpY2ggdGhlIGlucHV0IGlzIHJlcXVpcmVkCiAgICAgICAgICAgICAgICBjb250aW51ZTsgICAvLyB3aXRoIG5leHQgREIgY29sdW1uCgogICAgICAgICAgICBjb2wtPnhGaXJzdENvbnRyb2xXaXRoSW5wdXRSZXF1aXJlZCA9ICpwQ29udHJvbDsKICAgICAgICB9CiAgICB9CiAgICBjYXRjaCggY29uc3QgRXhjZXB0aW9uJiApCiAgICB7CiAgICAJREJHX1VOSEFORExFRF9FWENFUFRJT04oKTsKICAgIH0KCiAgICBtX2JDb250cm9sc0luaXRpYWxpemVkID0gdHJ1ZTsKfQoKLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KY29uc3QgQ29sdW1uSW5mbyYgQ29sdW1uSW5mb0NhY2hlOjpnZXRDb2x1bW5JbmZvKCBzaXplX3QgX3BvcyApCnsKICAgIGlmICggX3BvcyA+PSBtX2FDb2x1bW5zLnNpemUoKSApCiAgICAgICAgdGhyb3cgSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbigpOwoKICAgIHJldHVybiBtX2FDb2x1bW5zWyBfcG9zIF07Cn0KCi8vPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci8vIE9QYXJhbWV0ZXJDb250aW51YXRpb24KLy89PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KY2xhc3MgT1BhcmFtZXRlckNvbnRpbnVhdGlvbiA6IHB1YmxpYyBPSW50ZXJhY3Rpb248IFhJbnRlcmFjdGlvblN1cHBseVBhcmFtZXRlcnMgPgp7CiAgICBTZXF1ZW5jZTwgUHJvcGVydHlWYWx1ZSA+ICAgICAgIG1fYVZhbHVlczsKCnB1YmxpYzoKICAgIE9QYXJhbWV0ZXJDb250aW51YXRpb24oKSB7IH0KCiAgICBTZXF1ZW5jZTwgUHJvcGVydHlWYWx1ZSA+ICAgZ2V0VmFsdWVzKCkgY29uc3QgeyByZXR1cm4gbV9hVmFsdWVzOyB9CgovLyBYSW50ZXJhY3Rpb25TdXBwbHlQYXJhbWV0ZXJzCiAgICB2aXJ0dWFsIHZvaWQgU0FMX0NBTEwgc2V0UGFyYW1ldGVycyggY29uc3QgU2VxdWVuY2U8IFByb3BlcnR5VmFsdWUgPiYgX3JWYWx1ZXMgKSB0aHJvdyhSdW50aW1lRXhjZXB0aW9uKTsKfTsKCi8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCnZvaWQgU0FMX0NBTEwgT1BhcmFtZXRlckNvbnRpbnVhdGlvbjo6c2V0UGFyYW1ldGVycyggY29uc3QgU2VxdWVuY2U8IFByb3BlcnR5VmFsdWUgPiYgX3JWYWx1ZXMgKSB0aHJvdyhSdW50aW1lRXhjZXB0aW9uKQp7CiAgICBtX2FWYWx1ZXMgPSBfclZhbHVlczsKfQoKLy89PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLy8gRm1YQXV0b0NvbnRyb2wKLy89PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0Kc3RydWN0IEZtRmllbGRJbmZvCnsKICAgIHJ0bDo6T1VTdHJpbmcgICAgICAgYUZpZWxkTmFtZTsKICAgIFJlZmVyZW5jZTwgWFByb3BlcnR5U2V0ID4gICB4RmllbGQ7CiAgICBSZWZlcmVuY2U8IFhUZXh0Q29tcG9uZW50ID4gIHhUZXh0OwoKICAgIEZtRmllbGRJbmZvKGNvbnN0IFJlZmVyZW5jZTwgWFByb3BlcnR5U2V0ID4mIF94RmllbGQsIGNvbnN0IFJlZmVyZW5jZTwgWFRleHRDb21wb25lbnQgPiYgX3hUZXh0KQogICAgICAgIDp4RmllbGQoX3hGaWVsZCkKICAgICAgICAseFRleHQoX3hUZXh0KQogICAge3hGaWVsZC0+Z2V0UHJvcGVydHlWYWx1ZShGTV9QUk9QX05BTUUpID4+PSBhRmllbGROYW1lO30KfTsKCi8vPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci8vIEZtWEF1dG9Db250cm9sCi8vPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CmNsYXNzIEZtWEF1dG9Db250cm9sOiBwdWJsaWMgVW5vQ29udHJvbAoKewogICAgZnJpZW5kIFJlZmVyZW5jZTwgWEludGVyZmFjZSA+IFNBTF9DQUxMIEZtWEF1dG9Db250cm9sX05ld0luc3RhbmNlX0ltcGwoKTsKCnB1YmxpYzoKICAgIEZtWEF1dG9Db250cm9sKCBjb25zdCA6OmNvbXBoZWxwZXI6OkNvbXBvbmVudENvbnRleHQmIGlfY29udGV4dCApCiAgICAgICAgOlVub0NvbnRyb2woIGlfY29udGV4dC5nZXRMZWdhY3lTZXJ2aWNlRmFjdG9yeSgpICkKICAgIHsKICAgIH0KCiAgICB2aXJ0dWFsIDo6cnRsOjpPVVN0cmluZyBHZXRDb21wb25lbnRTZXJ2aWNlTmFtZSgpIHtyZXR1cm4gOjpydGw6Ok9VU3RyaW5nOjpjcmVhdGVGcm9tQXNjaWkoIkVkaXQiKTt9CiAgICB2aXJ0dWFsIHZvaWQgU0FMX0NBTEwgY3JlYXRlUGVlciggY29uc3QgUmVmZXJlbmNlPCBYVG9vbGtpdCA+ICYgcnhUb29sa2l0LCBjb25zdCBSZWZlcmVuY2U8IFhXaW5kb3dQZWVyID4gICYgclBhcmVudFBlZXIgKSB0aHJvdyggUnVudGltZUV4Y2VwdGlvbiApOwoKcHJvdGVjdGVkOgogICAgdmlydHVhbCB2b2lkIEltcGxTZXRQZWVyUHJvcGVydHkoIGNvbnN0IDo6cnRsOjpPVVN0cmluZyYgclByb3BOYW1lLCBjb25zdCBBbnkmIHJWYWwgKTsKfTsKCi8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCnZvaWQgRm1YQXV0b0NvbnRyb2w6OmNyZWF0ZVBlZXIoIGNvbnN0IFJlZmVyZW5jZTwgWFRvb2xraXQgPiAmIHJ4VG9vbGtpdCwgY29uc3QgUmVmZXJlbmNlPCBYV2luZG93UGVlciA+ICAmIHJQYXJlbnRQZWVyICkgdGhyb3coIFJ1bnRpbWVFeGNlcHRpb24gKQp7CiAgICBVbm9Db250cm9sOjpjcmVhdGVQZWVyKCByeFRvb2xraXQsIHJQYXJlbnRQZWVyICk7CgogICAgUmVmZXJlbmNlPCBYVGV4dENvbXBvbmVudCA+ICB4VGV4dChnZXRQZWVyKCkgLCBVTk9fUVVFUlkpOwogICAgaWYgKHhUZXh0LmlzKCkpCiAgICB7CiAgICAgICAgeFRleHQtPnNldFRleHQoOjpydGw6Ok9VU3RyaW5nKFN0cmluZyhTVlhfUkVTKFJJRF9TVFJfQVVUT0ZJRUxEKSkpKTsKICAgICAgICB4VGV4dC0+c2V0RWRpdGFibGUoc2FsX0ZhbHNlKTsKICAgIH0KfQoKLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0Kdm9pZCBGbVhBdXRvQ29udHJvbDo6SW1wbFNldFBlZXJQcm9wZXJ0eSggY29uc3QgOjpydGw6Ok9VU3RyaW5nJiByUHJvcE5hbWUsIGNvbnN0IEFueSYgclZhbCApCnsKICAgIC8vIHRoZXNlIHByb3BlcnRpZXMgYXJlIGlnbm9yZWQKICAgIGlmIChyUHJvcE5hbWUgPT0gRk1fUFJPUF9URVhUKQogICAgICAgIHJldHVybjsKCiAgICBVbm9Db250cm9sOjpJbXBsU2V0UGVlclByb3BlcnR5KCByUHJvcE5hbWUsIHJWYWwgKTsKfQoKLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KSU1QTF9MSU5LKCBGb3JtQ29udHJvbGxlciwgT25BY3RpdmF0ZVRhYk9yZGVyLCB2b2lkKiwgLypFTVBUWVRBRyovICkKewogICAgYWN0aXZhdGVUYWJPcmRlcigpOwogICAgcmV0dXJuIDE7Cn0KCi8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCnN0cnVjdCBVcGRhdGVBbGxMaXN0ZW5lcnMgOiBwdWJsaWMgOjpzdGQ6OnVuYXJ5X2Z1bmN0aW9uPCBSZWZlcmVuY2U8IFhEaXNwYXRjaCA+LCBib29sID4KewogICAgYm9vbCBvcGVyYXRvcigpKCBjb25zdCBSZWZlcmVuY2U8IFhEaXNwYXRjaCA+JiBfcnhEaXNwYXRjaGVyICkgY29uc3QKICAgIHsKICAgICAgICBzdGF0aWNfY2FzdDwgOjpzdng6Ok9TaW5nbGVGZWF0dXJlRGlzcGF0Y2hlciogPiggX3J4RGlzcGF0Y2hlci5nZXQoKSApLT51cGRhdGVBbGxMaXN0ZW5lcnMoKTsKICAgICAgICAvLyB0aGUgcmV0dXJuIGlzIGEgZHVtbXkgb25seSBzbyB3ZSBjYW4gdXNlIHRoaXMgc3RydWN0IGluIGEgc3RkOjpjb21wb3NlMSBjYWxsCiAgICAgICAgcmV0dXJuIHRydWU7CiAgICB9Cn07Ci8vLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uCklNUExfTElOSyggRm9ybUNvbnRyb2xsZXIsIE9uSW52YWxpZGF0ZUZlYXR1cmVzLCB2b2lkKiwgLypfcE5vdEludGVyZXN0ZWRJblRoaXNQYXJhbSovICkKewogICAgOjpvc2w6Ok11dGV4R3VhcmQgYUd1YXJkKCBtX2FNdXRleCApOwogICAgZm9yICggOjpzdGQ6OnNldDwgc2FsX0ludDE2ID46OmNvbnN0X2l0ZXJhdG9yIGFMb29wID0gbV9hSW52YWxpZEZlYXR1cmVzLmJlZ2luKCk7CiAgICAgICAgICBhTG9vcCAhPSBtX2FJbnZhbGlkRmVhdHVyZXMuZW5kKCk7CiAgICAgICAgICArK2FMb29wCiAgICAgICAgKQogICAgewogICAgICAgIERpc3BhdGNoZXJDb250YWluZXI6OmNvbnN0X2l0ZXJhdG9yIGFEaXNwYXRjaGVyUG9zID0gbV9hRmVhdHVyZURpc3BhdGNoZXJzLmZpbmQoICphTG9vcCApOwogICAgICAgIGlmICggYURpc3BhdGNoZXJQb3MgIT0gbV9hRmVhdHVyZURpc3BhdGNoZXJzLmVuZCgpICkKICAgICAgICB7CiAgICAgICAgICAgIC8vIFRPRE86IGZvciB0aGUgcmVhbCBhbmQgYWN0dWFsIGxpc3RlbmVyIG5vdGlmaWNhdGlvbnMsIHdlIHNob3VsZCByZWxlYXNlCiAgICAgICAgICAgIC8vIG91ciBtdXRleAogICAgICAgICAgICBVcGRhdGVBbGxMaXN0ZW5lcnMoICkoIGFEaXNwYXRjaGVyUG9zLT5zZWNvbmQgKTsKICAgICAgICB9CiAgICB9CiAgICByZXR1cm4gMTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCgpEQkdfTkFNRSggRm9ybUNvbnRyb2xsZXIgKQovLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQpGb3JtQ29udHJvbGxlcjo6Rm9ybUNvbnRyb2xsZXIoY29uc3QgUmVmZXJlbmNlPCBYTXVsdGlTZXJ2aWNlRmFjdG9yeSA+ICYgX3J4T1JCICkKCQkJCSAgOkZvcm1Db250cm9sbGVyX0JBU0UoIG1fYU11dGV4ICkKCQkJCSAgLE9Qcm9wZXJ0eVNldEhlbHBlciggRm9ybUNvbnRyb2xsZXJfQkFTRTo6ckJIZWxwZXIgKQogICAgICAgICAgICAgICAgICAsT1NRTFBhcnNlckNsaWVudCggX3J4T1JCICkKCQkJCSAgLG1fYUNvbnRleHQoIF9yeE9SQiApCgkJCQkgICxtX2FBY3RpdmF0ZUxpc3RlbmVycyhtX2FNdXRleCkKCQkJCSAgLG1fYU1vZGlmeUxpc3RlbmVycyhtX2FNdXRleCkKCQkJCSAgLG1fYUVycm9yTGlzdGVuZXJzKG1fYU11dGV4KQoJCQkJICAsbV9hRGVsZXRlTGlzdGVuZXJzKG1fYU11dGV4KQoJCQkJICAsbV9hUm93U2V0QXBwcm92ZUxpc3RlbmVycyhtX2FNdXRleCkKCQkJCSAgLG1fYVBhcmFtZXRlckxpc3RlbmVycyhtX2FNdXRleCkKICAgICAgICAgICAgICAgICAgLG1fYUZpbHRlckxpc3RlbmVycyhtX2FNdXRleCkKICAgICAgICAgICAgICAgICAgLG1fcENvbnRyb2xCb3JkZXJNYW5hZ2VyKCBuZXcgOjpzdnhmb3JtOjpDb250cm9sQm9yZGVyTWFuYWdlciApCiAgICAgICAgICAgICAgICAgICxtX3hGb3JtT3BlcmF0aW9ucygpCgkJCQkgICxtX2FNb2RlKCA6OnJ0bDo6T1VTdHJpbmcoIFJUTF9DT05TVEFTQ0lJX1VTVFJJTkdQQVJBTSggIkRhdGFNb2RlIiApICkgKQoJCQkJICAsbV9hTG9hZEV2ZW50KCBMSU5LKCB0aGlzLCBGb3JtQ29udHJvbGxlciwgT25Mb2FkICkgKQoJCQkJICAsbV9hVG9nZ2xlRXZlbnQoIExJTksoIHRoaXMsIEZvcm1Db250cm9sbGVyLCBPblRvZ2dsZUF1dG9GaWVsZHMgKSApCiAgICAgICAgICAgICAgICAgICxtX2FBY3RpdmF0aW9uRXZlbnQoIExJTksoIHRoaXMsIEZvcm1Db250cm9sbGVyLCBPbkFjdGl2YXRlZCApICkKICAgICAgICAgICAgICAgICAgLG1fYURlYWN0aXZhdGlvbkV2ZW50KCBMSU5LKCB0aGlzLCBGb3JtQ29udHJvbGxlciwgT25EZWFjdGl2YXRlZCApICkKCQkJCSAgLG1fbkN1cnJlbnRGaWx0ZXJQb3NpdGlvbigtMSkKCQkJCSAgLG1fYkN1cnJlbnRSZWNvcmRNb2RpZmllZChzYWxfRmFsc2UpCgkJCQkgICxtX2JDdXJyZW50UmVjb3JkTmV3KHNhbF9GYWxzZSkKCQkJCSAgLG1fYkxvY2tlZChzYWxfRmFsc2UpCgkJCQkgICxtX2JEQkNvbm5lY3Rpb24oc2FsX0ZhbHNlKQoJCQkJICAsbV9iQ3ljbGUoc2FsX0ZhbHNlKQoJCQkJICAsbV9iQ2FuSW5zZXJ0KHNhbF9GYWxzZSkKCQkJCSAgLG1fYkNhblVwZGF0ZShzYWxfRmFsc2UpCgkJCQkgICxtX2JDb21taXRMb2NrKHNhbF9GYWxzZSkKCQkJCSAgLG1fYk1vZGlmaWVkKHNhbF9GYWxzZSkKICAgICAgICAgICAgICAgICAgLG1fYkNvbnRyb2xzU29ydGVkKHNhbF9GYWxzZSkKICAgICAgICAgICAgICAgICAgLG1fYkZpbHRlcmluZyhzYWxfRmFsc2UpCgkJCQkgICxtX2JBdHRhY2hFdmVudHMoc2FsX1RydWUpCgkJCQkgICxtX2JEZXRhY2hFdmVudHMoc2FsX1RydWUpCiAgICAgICAgICAgICAgICAgICxtX2JBdHRlbXB0ZWRIYW5kbGVyQ3JlYXRpb24oIGZhbHNlICkKICAgICAgICAgICAgICAgICAgLG1fYlN1c3BlbmRGaWx0ZXJUZXh0TGlzdGVuaW5nKCBmYWxzZSApCnsKCURCR19DVE9SKCBGb3JtQ29udHJvbGxlciwgTlVMTCApOwoKCTo6Y29tcGhlbHBlcjo6aW5jcmVtZW50KG1fcmVmQ291bnQpOwoJewogICAgICAgIHsKCQkgICAgbV94QWdncmVnYXRlID0gUmVmZXJlbmNlPCBYQWdncmVnYXRpb24gPigKICAgICAgICAgICAgICAgIG1fYUNvbnRleHQuY3JlYXRlQ29tcG9uZW50KCAiY29tLnN1bi5zdGFyLmF3dC5UYWJDb250cm9sbGVyIiApLAogICAgICAgICAgICAgICAgVU5PX1FVRVJZCiAgICAgICAgICAgICk7CgkJICAgIERCR19BU1NFUlQoIG1feEFnZ3JlZ2F0ZS5pcygpLCAiRm9ybUNvbnRyb2xsZXI6OkZvcm1Db250cm9sbGVyIDogY291bGQgbm90IGNyZWF0ZSBteSBhZ2dyZWdhdGUgISIgKTsKCQkgICAgbV94VGFiQ29udHJvbGxlciA9IFJlZmVyZW5jZTwgWFRhYkNvbnRyb2xsZXIgPiggbV94QWdncmVnYXRlLCBVTk9fUVVFUlkgKTsKICAgICAgICB9CgogICAgCWlmICggbV94QWdncmVnYXRlLmlzKCkgKQoJICAgICAgICBtX3hBZ2dyZWdhdGUtPnNldERlbGVnYXRvciggKnRoaXMgKTsKICAgIH0KICAgIDo6Y29tcGhlbHBlcjo6ZGVjcmVtZW50KG1fcmVmQ291bnQpOwoKICAgIG1fYVRhYkFjdGl2YXRpb25UaW1lci5TZXRUaW1lb3V0KCA1MDAgKTsKICAgIG1fYVRhYkFjdGl2YXRpb25UaW1lci5TZXRUaW1lb3V0SGRsKCBMSU5LKCB0aGlzLCBGb3JtQ29udHJvbGxlciwgT25BY3RpdmF0ZVRhYk9yZGVyICkgKTsKCiAgICBtX2FGZWF0dXJlSW52YWxpZGF0aW9uVGltZXIuU2V0VGltZW91dCggMjAwICk7CiAgICBtX2FGZWF0dXJlSW52YWxpZGF0aW9uVGltZXIuU2V0VGltZW91dEhkbCggTElOSyggdGhpcywgRm9ybUNvbnRyb2xsZXIsIE9uSW52YWxpZGF0ZUZlYXR1cmVzICkgKTsKfQoKLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KRm9ybUNvbnRyb2xsZXI6On5Gb3JtQ29udHJvbGxlcigpCnsKICAgIHsKCSAgICA6Om9zbDo6TXV0ZXhHdWFyZCBhR3VhcmQoIG1fYU11dGV4ICk7CgogICAgICAgIG1fYUxvYWRFdmVudC5DYW5jZWxQZW5kaW5nQ2FsbCgpOwogICAgICAgIG1fYVRvZ2dsZUV2ZW50LkNhbmNlbFBlbmRpbmdDYWxsKCk7CiAgICAgICAgbV9hQWN0aXZhdGlvbkV2ZW50LkNhbmNlbFBlbmRpbmdDYWxsKCk7CiAgICAgICAgbV9hRGVhY3RpdmF0aW9uRXZlbnQuQ2FuY2VsUGVuZGluZ0NhbGwoKTsKCiAgICAgICAgaWYgKCBtX2FUYWJBY3RpdmF0aW9uVGltZXIuSXNBY3RpdmUoKSApCiAgICAgICAgICAgIG1fYVRhYkFjdGl2YXRpb25UaW1lci5TdG9wKCk7CiAgICB9CgogICAgaWYgKCBtX2FGZWF0dXJlSW52YWxpZGF0aW9uVGltZXIuSXNBY3RpdmUoKSApCiAgICAgICAgbV9hRmVhdHVyZUludmFsaWRhdGlvblRpbWVyLlN0b3AoKTsKCiAgICBkaXNwb3NlQWxsRmVhdHVyZXNBbmREaXNwYXRjaGVycygpOwoKICAgIGlmICggbV94Rm9ybU9wZXJhdGlvbnMuaXMoKSApCiAgICAgICAgbV94Rm9ybU9wZXJhdGlvbnMtPmRpc3Bvc2UoKTsKICAgIG1feEZvcm1PcGVyYXRpb25zLmNsZWFyKCk7CgogICAgLy8gRnJlaWdlYmVuIGRlciBBZ2dyZWdhdGlvbgogICAgaWYgKCBtX3hBZ2dyZWdhdGUuaXMoKSApCiAgICB7CiAgICAgICAgbV94QWdncmVnYXRlLT5zZXREZWxlZ2F0b3IoIE5VTEwgKTsKICAgICAgICBtX3hBZ2dyZWdhdGUuY2xlYXIoKTsKICAgIH0KCiAgICBERUxFVEVaKCBtX3BDb250cm9sQm9yZGVyTWFuYWdlciApOwoKCURCR19EVE9SKCBGb3JtQ29udHJvbGxlciwgTlVMTCApOwp9CgovLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQp2b2lkIFNBTF9DQUxMIEZvcm1Db250cm9sbGVyOjphY3F1aXJlKCkgdGhyb3cgKCkKewogICAgRm9ybUNvbnRyb2xsZXJfQkFTRTo6YWNxdWlyZSgpOwp9CgovLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQp2b2lkIFNBTF9DQUxMIEZvcm1Db250cm9sbGVyOjpyZWxlYXNlKCkgdGhyb3cgKCkKewogICAgRm9ybUNvbnRyb2xsZXJfQkFTRTo6cmVsZWFzZSgpOwp9CgovLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQpBbnkgU0FMX0NBTEwgRm9ybUNvbnRyb2xsZXI6OnF1ZXJ5SW50ZXJmYWNlKCBjb25zdCBUeXBlJiBfclR5cGUgKSB0aHJvdyhSdW50aW1lRXhjZXB0aW9uKQp7CiAgICBBbnkgYVJldCA9IEZvcm1Db250cm9sbGVyX0JBU0U6OnF1ZXJ5SW50ZXJmYWNlKCBfclR5cGUgKTsKICAgIGlmICggIWFSZXQuaGFzVmFsdWUoKSApCiAgICAgICAgYVJldCA9IE9Qcm9wZXJ0eVNldEhlbHBlcjo6cXVlcnlJbnRlcmZhY2UoIF9yVHlwZSApOwogICAgaWYgKCAhYVJldC5oYXNWYWx1ZSgpICkKICAgICAgICBhUmV0ID0gbV94QWdncmVnYXRlLT5xdWVyeUFnZ3JlZ2F0aW9uKCBfclR5cGUgKTsKICAgIHJldHVybiBhUmV0Owp9CgovLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQpTZXF1ZW5jZTwgc2FsX0ludDggPiBTQUxfQ0FMTCBGb3JtQ29udHJvbGxlcjo6Z2V0SW1wbGVtZW50YXRpb25JZCgpIHRocm93KCBSdW50aW1lRXhjZXB0aW9uICkKewogICAgc3RhdGljIDo6Y3BwdTo6T0ltcGxlbWVudGF0aW9uSWQqIHBJZCA9IE5VTEw7CglpZiAgKCAhcElkICkKCXsKICAgICAgICA6Om9zbDo6TXV0ZXhHdWFyZCBhR3VhcmQoIDo6b3NsOjpNdXRleDo6Z2V0R2xvYmFsTXV0ZXgoKSApOwoJCWlmICggIXBJZCApCgkJewoJCQlzdGF0aWMgOjpjcHB1OjpPSW1wbGVtZW50YXRpb25JZCBhSWQ7CgkJCXBJZCA9ICZhSWQ7CgkJfQoJfQoJcmV0dXJuIHBJZC0+Z2V0SW1wbGVtZW50YXRpb25JZCgpOwp9CgovLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQpTZXF1ZW5jZTwgVHlwZSA+IFNBTF9DQUxMIEZvcm1Db250cm9sbGVyOjpnZXRUeXBlcyggICkgdGhyb3coUnVudGltZUV4Y2VwdGlvbikKewogICAgcmV0dXJuIGNvbXBoZWxwZXI6OmNvbmNhdFNlcXVlbmNlcygKICAgICAgICBGb3JtQ29udHJvbGxlcl9CQVNFOjpnZXRUeXBlcygpLAogICAgICAgIDo6Y3BwdTo6T1Byb3BlcnR5U2V0SGVscGVyOjpnZXRUeXBlcygpCiAgICApOwp9CgovLyBYU2VydmljZUluZm8KLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0Kc2FsX0Jvb2wgU0FMX0NBTEwgRm9ybUNvbnRyb2xsZXI6OnN1cHBvcnRzU2VydmljZShjb25zdCA6OnJ0bDo6T1VTdHJpbmcmIFNlcnZpY2VOYW1lKSB0aHJvdyggUnVudGltZUV4Y2VwdGlvbiApCnsKICAgIFNlcXVlbmNlPCA6OnJ0bDo6T1VTdHJpbmc+IGFTTkwoZ2V0U3VwcG9ydGVkU2VydmljZU5hbWVzKCkpOwogICAgY29uc3QgOjpydGw6Ok9VU3RyaW5nICogcEFycmF5ID0gYVNOTC5nZXRDb25zdEFycmF5KCk7CiAgICBmb3IoIHNhbF9JbnQzMiBpID0gMDsgaSA8IGFTTkwuZ2V0TGVuZ3RoKCk7IGkrKyApCiAgICAgICAgaWYoIHBBcnJheVtpXSA9PSBTZXJ2aWNlTmFtZSApCiAgICAgICAgICAgIHJldHVybiBzYWxfVHJ1ZTsKICAgIHJldHVybiBzYWxfRmFsc2U7Cn0KCi8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCjo6cnRsOjpPVVN0cmluZyBTQUxfQ0FMTCBGb3JtQ29udHJvbGxlcjo6Z2V0SW1wbGVtZW50YXRpb25OYW1lKCkgdGhyb3coIFJ1bnRpbWVFeGNlcHRpb24gKQp7CiAgICByZXR1cm4gOjpydGw6Ok9VU3RyaW5nOjpjcmVhdGVGcm9tQXNjaWkoICJvcmcub3Blbm9mZmljZS5jb21wLnN2eC5Gb3JtQ29udHJvbGxlciIgKTsKfQoKLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KU2VxdWVuY2U8IDo6cnRsOjpPVVN0cmluZz4gU0FMX0NBTEwgRm9ybUNvbnRyb2xsZXI6OmdldFN1cHBvcnRlZFNlcnZpY2VOYW1lcyh2b2lkKSB0aHJvdyggUnVudGltZUV4Y2VwdGlvbiApCnsKICAgIC8vIHNlcnZpY2UgbmFtZXMgd2hpY2ggYXJlIHN1cHBvcnRlZCBvbmx5LCBidXQgY2Fubm90IGJlIHVzZWQgdG8gY3JlYXRlZCBhbgogICAgLy8gaW5zdGFuY2UgYXQgYSBzZXJ2aWNlIGZhY3RvcnkKICAgIFNlcXVlbmNlPCA6OnJ0bDo6T1VTdHJpbmcgPiBhTm9uQ3JlYXRhYmxlU2VydmljZU5hbWVzKCAxICk7CiAgICBhTm9uQ3JlYXRhYmxlU2VydmljZU5hbWVzWyAwIF0gPSA6OnJ0bDo6T1VTdHJpbmcoIFJUTF9DT05TVEFTQ0lJX1VTVFJJTkdQQVJBTSggImNvbS5zdW4uc3Rhci5mb3JtLkZvcm1Db250cm9sbGVyRGlzcGF0Y2hlciIgKSApOwoKICAgIC8vIHNlcnZpY2VzIHdoaWNoIGNhbiBiZSB1c2VkIHRvIGNyZWF0ZWQgYW4gaW5zdGFuY2UgYXQgYSBzZXJ2aWNlIGZhY3RvcnkKICAgIFNlcXVlbmNlPCA6OnJ0bDo6T1VTdHJpbmcgPiBhQ3JlYXRhYmxlU2VydmljZU5hbWVzKCBnZXRTdXBwb3J0ZWRTZXJ2aWNlTmFtZXNfU3RhdGljKCkgKTsKICAgIHJldHVybiA6OmNvbXBoZWxwZXI6OmNvbmNhdFNlcXVlbmNlcyggYUNyZWF0YWJsZVNlcnZpY2VOYW1lcywgYU5vbkNyZWF0YWJsZVNlcnZpY2VOYW1lcyApOwp9CgovLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQpzYWxfQm9vbCBTQUxfQ0FMTCBGb3JtQ29udHJvbGxlcjo6YXBwcm92ZVJlc2V0KGNvbnN0IEV2ZW50T2JqZWN0JiAvKnJFdmVudCovKSB0aHJvdyggUnVudGltZUV4Y2VwdGlvbiApCnsKICAgIHJldHVybiBzYWxfVHJ1ZTsKfQoKLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0Kdm9pZCBTQUxfQ0FMTCBGb3JtQ29udHJvbGxlcjo6cmVzZXR0ZWQoY29uc3QgRXZlbnRPYmplY3QmIHJFdmVudCkgdGhyb3coIFJ1bnRpbWVFeGNlcHRpb24gKQp7CiAgICA6Om9zbDo6TXV0ZXhHdWFyZCBhR3VhcmQobV9hTXV0ZXgpOwogICAgaWYgKGdldEN1cnJlbnRDb250cm9sKCkuaXMoKSAmJiAgKGdldEN1cnJlbnRDb250cm9sKCktPmdldE1vZGVsKCkgPT0gckV2ZW50LlNvdXJjZSkpCiAgICAgICAgbV9iTW9kaWZpZWQgPSBzYWxfRmFsc2U7Cn0KCi8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tClNlcXVlbmNlPCA6OnJ0bDo6T1VTdHJpbmc+IEZvcm1Db250cm9sbGVyOjpnZXRTdXBwb3J0ZWRTZXJ2aWNlTmFtZXNfU3RhdGljKHZvaWQpCnsKICAgIHN0YXRpYyBTZXF1ZW5jZTwgOjpydGw6Ok9VU3RyaW5nPiBhU2VydmljZXM7CiAgICBpZiAoIWFTZXJ2aWNlcy5nZXRMZW5ndGgoKSkKICAgIHsKICAgICAgICBhU2VydmljZXMucmVhbGxvYygyKTsKICAgICAgICBhU2VydmljZXMuZ2V0QXJyYXkoKVswXSA9IEZNX0ZPUk1fQ09OVFJPTExFUjsKICAgICAgICBhU2VydmljZXMuZ2V0QXJyYXkoKVsxXSA9IDo6cnRsOjpPVVN0cmluZzo6Y3JlYXRlRnJvbUFzY2lpKCJjb20uc3VuLnN0YXIuYXd0LmNvbnRyb2wuVGFiQ29udHJvbGxlciIpOwogICAgfQogICAgcmV0dXJuIGFTZXJ2aWNlczsKfQoKLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KbmFtZXNwYWNlCnsKICAgIHN0cnVjdCBSZXNldENvbXBvbmVudFRleHQgOiBwdWJsaWMgOjpzdGQ6OnVuYXJ5X2Z1bmN0aW9uPCBSZWZlcmVuY2U8IFhUZXh0Q29tcG9uZW50ID4sIHZvaWQgPgogICAgewogICAgICAgIHZvaWQgb3BlcmF0b3IoKSggY29uc3QgUmVmZXJlbmNlPCBYVGV4dENvbXBvbmVudCA+JiBfcnhUZXh0ICkKICAgICAgICB7CiAgICAgICAgICAgIF9yeFRleHQtPnNldFRleHQoIDo6cnRsOjpPVVN0cmluZygpICk7CiAgICAgICAgfQogICAgfTsKCiAgICBzdHJ1Y3QgUmVtb3ZlQ29tcG9uZW50VGV4dExpc3RlbmVyIDogcHVibGljIDo6c3RkOjp1bmFyeV9mdW5jdGlvbjwgUmVmZXJlbmNlPCBYVGV4dENvbXBvbmVudCA+LCB2b2lkID4KICAgIHsKICAgICAgICBSZW1vdmVDb21wb25lbnRUZXh0TGlzdGVuZXIoIGNvbnN0IFJlZmVyZW5jZTwgWFRleHRMaXN0ZW5lciA+JiBfcnhMaXN0ZW5lciApCiAgICAgICAgICAgIDptX3hMaXN0ZW5lciggX3J4TGlzdGVuZXIgKQogICAgICAgIHsKICAgICAgICB9CgogICAgICAgIHZvaWQgb3BlcmF0b3IoKSggY29uc3QgUmVmZXJlbmNlPCBYVGV4dENvbXBvbmVudCA+JiBfcnhUZXh0ICkKICAgICAgICB7CiAgICAgICAgICAgIF9yeFRleHQtPnJlbW92ZVRleHRMaXN0ZW5lciggbV94TGlzdGVuZXIgKTsKICAgICAgICB9CgogICAgcHJpdmF0ZToKICAgICAgICBSZWZlcmVuY2U8IFhUZXh0TGlzdGVuZXIgPiAgbV94TGlzdGVuZXI7CiAgICB9Owp9CgovLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQp2b2lkIEZvcm1Db250cm9sbGVyOjppbXBsX3NldFRleHRPbkFsbEZpbHRlcl90aHJvdygpCnsKICAgIG1fYlN1c3BlbmRGaWx0ZXJUZXh0TGlzdGVuaW5nID0gdHJ1ZTsKICAgIDo6Y29tcGhlbHBlcjo6RmxhZ0d1YXJkIGFSZXNldEZsYWcoIG1fYlN1c3BlbmRGaWx0ZXJUZXh0TGlzdGVuaW5nICk7CgogICAgLy8gcmVzZXQgdGhlIHRleHQgZm9yIGFsbCBjb250cm9scwogICAgOjpzdGQ6OmZvcl9lYWNoKCBtX2FGaWx0ZXJDb21wb25lbnRzLmJlZ2luKCksIG1fYUZpbHRlckNvbXBvbmVudHMuZW5kKCksIFJlc2V0Q29tcG9uZW50VGV4dCgpICk7CgogICAgaWYgKCBtX2FGaWx0ZXJSb3dzLmVtcHR5KCkgKQogICAgICAgIC8vIG5vdGhpbmcgdG8gZG8gYW55bW9yZQogICAgICAgIHJldHVybjsKCiAgICBpZiAoIG1fbkN1cnJlbnRGaWx0ZXJQb3NpdGlvbiA8IDAgKQogICAgICAgIHJldHVybjsKCiAgICAvLyBzZXQgdGhlIHRleHQgZm9yIGFsbCBmaWx0ZXJzCiAgICBPU0xfRU5TVVJFKCBtX2FGaWx0ZXJSb3dzLnNpemUoKSA+IChzaXplX3QpbV9uQ3VycmVudEZpbHRlclBvc2l0aW9uLAogICAgICAgICJGb3JtQ29udHJvbGxlcjo6aW1wbF9zZXRUZXh0T25BbGxGaWx0ZXJfdGhyb3c6IG1fbkN1cnJlbnRGaWx0ZXJQb3NpdGlvbiB0b28gYmlnIiApOwoKCWlmICggKHNpemVfdCltX25DdXJyZW50RmlsdGVyUG9zaXRpb24gPCBtX2FGaWx0ZXJSb3dzLnNpemUoKSApCgl7CiAgICAgICAgRm1GaWx0ZXJSb3cmIHJSb3cgPSBtX2FGaWx0ZXJSb3dzWyBtX25DdXJyZW50RmlsdGVyUG9zaXRpb24gXTsKICAgICAgICBmb3IgKCAgIEZtRmlsdGVyUm93Ojpjb25zdF9pdGVyYXRvciBpdGVyMiA9IHJSb3cuYmVnaW4oKTsKICAgICAgICAgICAgICAgIGl0ZXIyICE9IHJSb3cuZW5kKCk7CiAgICAgICAgICAgICAgICArK2l0ZXIyCiAgICAgICAgICAgICkKICAgICAgICB7CiAgICAgICAgICAgIGl0ZXIyLT5maXJzdC0+c2V0VGV4dCggaXRlcjItPnNlY29uZCApOwogICAgICAgIH0KICAgIH0KfQovLyBPUHJvcGVydHlTZXRIZWxwZXIKLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0Kc2FsX0Jvb2wgRm9ybUNvbnRyb2xsZXI6OmNvbnZlcnRGYXN0UHJvcGVydHlWYWx1ZSggQW55ICYgLypyQ29udmVydGVkVmFsdWUqLywgQW55ICYgLypyT2xkVmFsdWUqLywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzYWxfSW50MzIgLypuSGFuZGxlKi8sIGNvbnN0IEFueSYgLypyVmFsdWUqLyApCiAgICAgICAgICAgICAgICB0aHJvdyggSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uICkKewogICAgcmV0dXJuIHNhbF9GYWxzZTsKfQoKLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0Kdm9pZCBGb3JtQ29udHJvbGxlcjo6c2V0RmFzdFByb3BlcnR5VmFsdWVfTm9Ccm9hZGNhc3QoIHNhbF9JbnQzMiAvKm5IYW5kbGUqLywgY29uc3QgQW55JiAvKnJWYWx1ZSovICkKICAgICAgICAgICAgICAgICAgICAgICAgIHRocm93KCBFeGNlcHRpb24gKQp7Cn0KCi8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCnZvaWQgRm9ybUNvbnRyb2xsZXI6OmdldEZhc3RQcm9wZXJ0eVZhbHVlKCBBbnkmIHJWYWx1ZSwgc2FsX0ludDMyIG5IYW5kbGUgKSBjb25zdAp7CiAgICBzd2l0Y2ggKG5IYW5kbGUpCiAgICB7CiAgICAgICAgY2FzZSBGTV9BVFRSX0ZJTFRFUjoKICAgICAgICB7CiAgICAgICAgICAgIDo6cnRsOjpPVVN0cmluZ0J1ZmZlciBhRmlsdGVyOwoJCQlPU3RhdGljRGF0YUFjY2Vzc1Rvb2xzIGFTdGF0aWNUb29sczsKICAgICAgICAgICAgUmVmZXJlbmNlPFhDb25uZWN0aW9uPiB4Q29ubmVjdGlvbihhU3RhdGljVG9vbHMuZ2V0Um93U2V0Q29ubmVjdGlvbihSZWZlcmVuY2U8IFhSb3dTZXQ+KG1feE1vZGVsQXNJbmRleCwgVU5PX1FVRVJZKSkpOwogICAgICAgICAgICBpZiAoeENvbm5lY3Rpb24uaXMoKSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgUmVmZXJlbmNlPCBYRGF0YWJhc2VNZXRhRGF0YT4geE1ldGFEYXRhKHhDb25uZWN0aW9uLT5nZXRNZXRhRGF0YSgpKTsKICAgICAgICAgICAgICAgIFJlZmVyZW5jZTwgWE51bWJlckZvcm1hdHNTdXBwbGllcj4geEZvcm1hdFN1cHBsaWVyKCBhU3RhdGljVG9vbHMuZ2V0TnVtYmVyRm9ybWF0cyggeENvbm5lY3Rpb24sIHNhbF9UcnVlICkgKTsKICAgICAgICAgICAgICAgIFJlZmVyZW5jZTwgWE51bWJlckZvcm1hdHRlcj4geEZvcm1hdHRlciggbV9hQ29udGV4dC5jcmVhdGVDb21wb25lbnQoICJjb20uc3VuLnN0YXIudXRpbC5OdW1iZXJGb3JtYXR0ZXIiICksIFVOT19RVUVSWV9USFJPVyApOwogICAgICAgICAgICAgICAgeEZvcm1hdHRlci0+YXR0YWNoTnVtYmVyRm9ybWF0c1N1cHBsaWVyKHhGb3JtYXRTdXBwbGllcik7CgogICAgICAgICAgICAgICAgUmVmZXJlbmNlPCBYQ29sdW1uc1N1cHBsaWVyPiB4U3VwcGx5Q29scyhtX3hNb2RlbEFzSW5kZXgsIFVOT19RVUVSWSk7CiAgICAgICAgICAgICAgICBSZWZlcmVuY2U8IFhOYW1lQWNjZXNzPiB4RmllbGRzKHhTdXBwbHlDb2xzLT5nZXRDb2x1bW5zKCksIFVOT19RVUVSWSk7CgogICAgICAgICAgICAgICAgOjpydGw6Ok9VU3RyaW5nIGFRdW90ZSggeE1ldGFEYXRhLT5nZXRJZGVudGlmaWVyUXVvdGVTdHJpbmcoKSApOwoKICAgICAgICAgICAgICAgIC8vIG5vdyBhZGQgdGhlIGZpbHRlciByb3dzCiAgICAgICAgICAgICAgICB0cnkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBmb3IgKCBGbUZpbHRlclJvd3M6OmNvbnN0X2l0ZXJhdG9yIHJvdyA9IG1fYUZpbHRlclJvd3MuYmVnaW4oKTsgcm93ICE9IG1fYUZpbHRlclJvd3MuZW5kKCk7ICsrcm93ICkKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IEZtRmlsdGVyUm93JiByUm93ID0gKnJvdzsKCiAgICAgICAgICAgICAgICAgICAgICAgIGlmICggclJvdy5lbXB0eSgpICkKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlOwoKICAgICAgICAgICAgICAgICAgICAgICAgOjpydGw6Ok9VU3RyaW5nQnVmZmVyIGFSb3dGaWx0ZXI7CiAgICAgICAgICAgICAgICAgICAgICAgIGZvciAoIEZtRmlsdGVyUm93Ojpjb25zdF9pdGVyYXRvciBjb25kaXRpb24gPSByUm93LmJlZ2luKCk7IGNvbmRpdGlvbiAhPSByUm93LmVuZCgpOyArK2NvbmRpdGlvbiApCiAgICAgICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIGdldCB0aGUgZmllbGQgb2YgdGhlIGNvbnRyb2xzIG1hcAogICAgICAgICAgICAgICAgICAgICAgICAgICAgUmVmZXJlbmNlPCBYQ29udHJvbCA+IHhDb250cm9sKCBjb25kaXRpb24tPmZpcnN0LCBVTk9fUVVFUllfVEhST1cgKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIFJlZmVyZW5jZTwgWFByb3BlcnR5U2V0ID4geE1vZGVsUHJvcHMoIHhDb250cm9sLT5nZXRNb2RlbCgpLCBVTk9fUVVFUllfVEhST1cgKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIFJlZmVyZW5jZTwgWFByb3BlcnR5U2V0ID4geEZpZWxkKCB4TW9kZWxQcm9wcy0+Z2V0UHJvcGVydHlWYWx1ZSggRk1fUFJPUF9CT1VOREZJRUxEICksIFVOT19RVUVSWV9USFJPVyApOwoKICAgICAgICAgICAgICAgICAgICAgICAgICAgIDo6cnRsOjpPVVN0cmluZyBzRmlsdGVyVmFsdWUoIGNvbmRpdGlvbi0+c2Vjb25kICk7CgogICAgICAgICAgICAgICAgICAgICAgICAgICAgOjpydGw6Ok9VU3RyaW5nIHNFcnJvck1zZywgc0NyaXRlcmlhOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgOjpydGw6OlJlZmVyZW5jZTwgSVNRTFBhcnNlTm9kZSA+IHhQYXJzZU5vZGUgPQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHByZWRpY2F0ZVRyZWUoIHNFcnJvck1zZywgc0ZpbHRlclZhbHVlLCB4Rm9ybWF0dGVyLCB4RmllbGQgKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIE9TTF9FTlNVUkUoIHhQYXJzZU5vZGUuaXMoKSwgIkZvcm1Db250cm9sbGVyOjpnZXRGYXN0UHJvcGVydHlWYWx1ZTogY291bGQgbm90IHBhcnNlIHRoZSBmaWVsZCB2YWx1ZSBwcmVkaWNhdGUhIiApOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCB4UGFyc2VOb2RlLmlzKCkgKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIGRvbid0IHVzZSBhIHBhcnNlIGNvbnRleHQgaGVyZSwgd2UgbmVlZCBpdCB1bmxvY2FsaXplZAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHhQYXJzZU5vZGUtPnBhcnNlTm9kZVRvU3RyKCBzQ3JpdGVyaWEsIHhDb25uZWN0aW9uLCBOVUxMICk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCBjb25kaXRpb24gIT0gclJvdy5iZWdpbigpICkKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYVJvd0ZpbHRlci5hcHBlbmRBc2NpaSggIiBBTkQgIiApOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFSb3dGaWx0ZXIuYXBwZW5kKCBzQ3JpdGVyaWEgKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICBpZiAoIGFSb3dGaWx0ZXIuZ2V0TGVuZ3RoKCkgPiAwICkKICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCBhRmlsdGVyLmdldExlbmd0aCgpICkKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhRmlsdGVyLmFwcGVuZEFzY2lpKCAiIE9SICIgKTsKCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBhRmlsdGVyLmFwcGVuZEFzY2lpKCAiKCAiICk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBhRmlsdGVyLmFwcGVuZCggYVJvd0ZpbHRlci5tYWtlU3RyaW5nQW5kQ2xlYXIoKSApOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgYUZpbHRlci5hcHBlbmRBc2NpaSggIiApIiApOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgY2F0Y2goIGNvbnN0IEV4Y2VwdGlvbiYgKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIERCR19VTkhBTkRMRURfRVhDRVBUSU9OKCk7CiAgICAgICAgICAgICAgICAgICAgYUZpbHRlci5zZXRMZW5ndGgoMCk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgclZhbHVlIDw8PSBhRmlsdGVyLm1ha2VTdHJpbmdBbmRDbGVhcigpOwogICAgICAgIH0KICAgICAgICBicmVhazsKCiAgICAgICAgY2FzZSBGTV9BVFRSX0ZPUk1fT1BFUkFUSU9OUzoKICAgICAgICAgICAgclZhbHVlIDw8PSBtX3hGb3JtT3BlcmF0aW9uczsKICAgICAgICAgICAgYnJlYWs7CiAgICB9Cn0KCi8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tClJlZmVyZW5jZTwgWFByb3BlcnR5U2V0SW5mbyA+ICBGb3JtQ29udHJvbGxlcjo6Z2V0UHJvcGVydHlTZXRJbmZvKCkgdGhyb3coIFJ1bnRpbWVFeGNlcHRpb24gKQp7CiAgICBzdGF0aWMgUmVmZXJlbmNlPCBYUHJvcGVydHlTZXRJbmZvID4gIHhJbmZvKCBjcmVhdGVQcm9wZXJ0eVNldEluZm8oIGdldEluZm9IZWxwZXIoKSApICk7CiAgICByZXR1cm4geEluZm87Cn0KCi8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiNkZWZpbmUgREVDTF9QUk9QX0NPUkUodmFybmFtZSwgdHlwZSkgXApwRGVzY1tuUG9zKytdID0gUHJvcGVydHkoRk1fUFJPUF8jI3Zhcm5hbWUsIEZNX0FUVFJfIyN2YXJuYW1lLCA6OmdldENwcHVUeXBlKChjb25zdCB0eXBlKikwKSwKCgojZGVmaW5lIERFQ0xfUFJPUDEodmFybmFtZSwgdHlwZSwgYXR0cmliMSkgIFwKICAgIERFQ0xfUFJPUF9DT1JFKHZhcm5hbWUsIHR5cGUpIFByb3BlcnR5QXR0cmlidXRlOjphdHRyaWIxKQoKLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0Kdm9pZCBGb3JtQ29udHJvbGxlcjo6ZmlsbFByb3BlcnRpZXMoCiAgICAgICAgU2VxdWVuY2U8IFByb3BlcnR5ID4mIC8qIFtvdXRdICovIF9yUHJvcHMsCiAgICAgICAgU2VxdWVuY2U8IFByb3BlcnR5ID4mIC8qIFtvdXRdICovIC8qX3JBZ2dyZWdhdGVQcm9wcyovCiAgICAgICAgKSBjb25zdAp7CiAgICBfclByb3BzLnJlYWxsb2MoMik7CiAgICBzYWxfSW50MzIgblBvcyA9IDA7CiAgICBQcm9wZXJ0eSogcERlc2MgPSBfclByb3BzLmdldEFycmF5KCk7CiAgICBERUNMX1BST1AxKEZJTFRFUiwgcnRsOjpPVVN0cmluZywgUkVBRE9OTFkpOwogICAgREVDTF9QUk9QMShGT1JNX09QRVJBVElPTlMsIFJlZmVyZW5jZTwgWEZvcm1PcGVyYXRpb25zID4sIFJFQURPTkxZKTsKfQoKLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KOjpjcHB1OjpJUHJvcGVydHlBcnJheUhlbHBlciYgRm9ybUNvbnRyb2xsZXI6OmdldEluZm9IZWxwZXIoKQp7CiAgICByZXR1cm4gKmdldEFycmF5SGVscGVyKCk7Cn0KCi8vIFhGaWx0ZXJDb250cm9sbGVyCi8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCnZvaWQgU0FMX0NBTEwgRm9ybUNvbnRyb2xsZXI6OmFkZEZpbHRlckNvbnRyb2xsZXJMaXN0ZW5lciggY29uc3QgUmVmZXJlbmNlPCBYRmlsdGVyQ29udHJvbGxlckxpc3RlbmVyID4mIF9MaXN0ZW5lciApIHRocm93KCBSdW50aW1lRXhjZXB0aW9uICkKewogICAgbV9hRmlsdGVyTGlzdGVuZXJzLmFkZEludGVyZmFjZSggX0xpc3RlbmVyICk7Cn0KCi8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCnZvaWQgU0FMX0NBTEwgRm9ybUNvbnRyb2xsZXI6OnJlbW92ZUZpbHRlckNvbnRyb2xsZXJMaXN0ZW5lciggY29uc3QgUmVmZXJlbmNlPCBYRmlsdGVyQ29udHJvbGxlckxpc3RlbmVyID4mIF9MaXN0ZW5lciApIHRocm93KCBSdW50aW1lRXhjZXB0aW9uICkKewogICAgbV9hRmlsdGVyTGlzdGVuZXJzLnJlbW92ZUludGVyZmFjZSggX0xpc3RlbmVyICk7Cn0KCi8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCjo6c2FsX0ludDMyIFNBTF9DQUxMIEZvcm1Db250cm9sbGVyOjpnZXRGaWx0ZXJDb21wb25lbnRzKCkgdGhyb3coIDo6Y29tOjpzdW46OnN0YXI6OnVubzo6UnVudGltZUV4Y2VwdGlvbiApCnsKICAgIDo6b3NsOjpNdXRleEd1YXJkIGFHdWFyZCggbV9hTXV0ZXggKTsKICAgIGltcGxfY2hlY2tEaXNwb3NlZF90aHJvdygpOwoKICAgIHJldHVybiBtX2FGaWx0ZXJDb21wb25lbnRzLnNpemUoKTsKfQoKLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KOjpzYWxfSW50MzIgU0FMX0NBTEwgRm9ybUNvbnRyb2xsZXI6OmdldERpc2p1bmN0aXZlVGVybXMoKSB0aHJvdyggOjpjb206OnN1bjo6c3Rhcjo6dW5vOjpSdW50aW1lRXhjZXB0aW9uICkKewogICAgOjpvc2w6Ok11dGV4R3VhcmQgYUd1YXJkKCBtX2FNdXRleCApOwogICAgaW1wbF9jaGVja0Rpc3Bvc2VkX3Rocm93KCk7CgogICAgcmV0dXJuIG1fYUZpbHRlclJvd3Muc2l6ZSgpOwp9CgovLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQp2b2lkIFNBTF9DQUxMIEZvcm1Db250cm9sbGVyOjpzZXRQcmVkaWNhdGVFeHByZXNzaW9uKCA6OnNhbF9JbnQzMiBfQ29tcG9uZW50LCA6OnNhbF9JbnQzMiBfVGVybSwgY29uc3QgOjpydGw6Ok9VU3RyaW5nJiBfUHJlZGljYXRlRXhwcmVzc2lvbiApIHRocm93KCBSdW50aW1lRXhjZXB0aW9uLCBJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uICkKewogICAgOjpvc2w6Ok11dGV4R3VhcmQgYUd1YXJkKCBtX2FNdXRleCApOwogICAgaW1wbF9jaGVja0Rpc3Bvc2VkX3Rocm93KCk7CgogICAgaWYgKCAoIF9Db21wb25lbnQgPCAwICkgfHwgKCBfQ29tcG9uZW50ID49IGdldEZpbHRlckNvbXBvbmVudHMoKSApIHx8ICggX1Rlcm0gPCAwICkgfHwgKCBfVGVybSA+PSBnZXREaXNqdW5jdGl2ZVRlcm1zKCkgKSApCiAgICAgICAgdGhyb3cgSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiggOjpydGw6Ok9VU3RyaW5nKCksICp0aGlzICk7CgogICAgUmVmZXJlbmNlPCBYVGV4dENvbXBvbmVudCA+IHhUZXh0KCBtX2FGaWx0ZXJDb21wb25lbnRzWyBfQ29tcG9uZW50IF0gKTsKICAgIHhUZXh0LT5zZXRUZXh0KCBfUHJlZGljYXRlRXhwcmVzc2lvbiApOwoKICAgIEZtRmlsdGVyUm93JiByRmlsdGVyUm93ID0gbV9hRmlsdGVyUm93c1sgX1Rlcm0gXTsKICAgIGlmICggX1ByZWRpY2F0ZUV4cHJlc3Npb24uZ2V0TGVuZ3RoKCkgKQogICAgICAgIHJGaWx0ZXJSb3dbIHhUZXh0IF0gPSBfUHJlZGljYXRlRXhwcmVzc2lvbjsKICAgIGVsc2UKICAgICAgICByRmlsdGVyUm93LmVyYXNlKCB4VGV4dCApOwp9CgovLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQpSZWZlcmVuY2U8IFhDb250cm9sID4gRm9ybUNvbnRyb2xsZXI6OmdldEZpbHRlckNvbXBvbmVudCggOjpzYWxfSW50MzIgX0NvbXBvbmVudCApIHRocm93KCBSdW50aW1lRXhjZXB0aW9uLCBJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uICkKewogICAgOjpvc2w6Ok11dGV4R3VhcmQgYUd1YXJkKCBtX2FNdXRleCApOwogICAgaW1wbF9jaGVja0Rpc3Bvc2VkX3Rocm93KCk7CgogICAgaWYgKCAoIF9Db21wb25lbnQgPCAwICkgfHwgKCBfQ29tcG9uZW50ID49IGdldEZpbHRlckNvbXBvbmVudHMoKSApICkKICAgICAgICB0aHJvdyBJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uKCA6OnJ0bDo6T1VTdHJpbmcoKSwgKnRoaXMgKTsKCiAgICByZXR1cm4gUmVmZXJlbmNlPCBYQ29udHJvbCA+KCBtX2FGaWx0ZXJDb21wb25lbnRzWyBfQ29tcG9uZW50IF0sIFVOT19RVUVSWSApOwp9CgovLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQpTZXF1ZW5jZTwgU2VxdWVuY2U8IDo6cnRsOjpPVVN0cmluZyA+ID4gRm9ybUNvbnRyb2xsZXI6OmdldFByZWRpY2F0ZUV4cHJlc3Npb25zKCkgdGhyb3coIFJ1bnRpbWVFeGNlcHRpb24gKQp7CiAgICA6Om9zbDo6TXV0ZXhHdWFyZCBhR3VhcmQoIG1fYU11dGV4ICk7CiAgICBpbXBsX2NoZWNrRGlzcG9zZWRfdGhyb3coKTsKCiAgICBTZXF1ZW5jZTwgU2VxdWVuY2U8IDo6cnRsOjpPVVN0cmluZyA+ID4gYUV4cHJlc3Npb25zKCBtX2FGaWx0ZXJSb3dzLnNpemUoKSApOwogICAgc2FsX0ludDMyIHRlcm1JbmRleCA9IDA7CiAgICBmb3IgKCAgIEZtRmlsdGVyUm93czo6Y29uc3RfaXRlcmF0b3Igcm93ID0gbV9hRmlsdGVyUm93cy5iZWdpbigpOwogICAgICAgICAgICByb3cgIT0gbV9hRmlsdGVyUm93cy5lbmQoKTsKICAgICAgICAgICAgKytyb3csICsrdGVybUluZGV4CiAgICAgICAgKQogICAgewogICAgICAgIGNvbnN0IEZtRmlsdGVyUm93JiByUm93KCAqcm93ICk7CgogICAgICAgIFNlcXVlbmNlPCA6OnJ0bDo6T1VTdHJpbmcgPiBhQ29uanVuY3Rpb24oIG1fYUZpbHRlckNvbXBvbmVudHMuc2l6ZSgpICk7CiAgICAgICAgc2FsX0ludDMyIGNvbXBvbmVudEluZGV4ID0gMDsKICAgICAgICBmb3IgKCAgIEZpbHRlckNvbXBvbmVudHM6OmNvbnN0X2l0ZXJhdG9yIGNvbXAgPSBtX2FGaWx0ZXJDb21wb25lbnRzLmJlZ2luKCk7CiAgICAgICAgICAgICAgICBjb21wICE9IG1fYUZpbHRlckNvbXBvbmVudHMuZW5kKCk7CiAgICAgICAgICAgICAgICArK2NvbXAsICsrY29tcG9uZW50SW5kZXgKICAgICAgICAgICAgKQogICAgICAgIHsKICAgICAgICAgICAgRm1GaWx0ZXJSb3c6OmNvbnN0X2l0ZXJhdG9yIHByZWRpY2F0ZSA9IHJSb3cuZmluZCggKmNvbXAgKTsKICAgICAgICAgICAgaWYgKCBwcmVkaWNhdGUgIT0gclJvdy5lbmQoKSApCiAgICAgICAgICAgICAgICBhQ29uanVuY3Rpb25bIGNvbXBvbmVudEluZGV4IF0gPSBwcmVkaWNhdGUtPnNlY29uZDsKICAgICAgICB9CgogICAgICAgIGFFeHByZXNzaW9uc1sgdGVybUluZGV4IF0gPSBhQ29uanVuY3Rpb247CiAgICB9CgogICAgcmV0dXJuIGFFeHByZXNzaW9uczsKfQoKLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0Kdm9pZCBTQUxfQ0FMTCBGb3JtQ29udHJvbGxlcjo6cmVtb3ZlRGlzanVuY3RpdmVUZXJtKCA6OnNhbF9JbnQzMiBfVGVybSApIHRocm93IChJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uLCBSdW50aW1lRXhjZXB0aW9uKQp7CiAgICAvLyBTWU5DSFJPTklaRUQgLS0+CiAgICA6Om9zbDo6Q2xlYXJhYmxlTXV0ZXhHdWFyZCBhR3VhcmQoIG1fYU11dGV4ICk7CiAgICBpbXBsX2NoZWNrRGlzcG9zZWRfdGhyb3coKTsKCiAgICBpZiAoICggX1Rlcm0gPCAwICkgfHwgKCBfVGVybSA+PSBnZXREaXNqdW5jdGl2ZVRlcm1zKCkgKSApCiAgICAgICAgdGhyb3cgSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiggOjpydGw6Ok9VU3RyaW5nKCksICp0aGlzICk7CgogICAgLy8gaWYgdGhlIHRvLWJlLWRlbGV0ZWQgcm93IGlzIG91ciBjdXJyZW50IHJvdywgd2UgbmVlZCB0byBzaGlmdAogICAgaWYgKCBfVGVybSA9PSBtX25DdXJyZW50RmlsdGVyUG9zaXRpb24gKQogICAgewogICAgICAgIGlmICggbV9uQ3VycmVudEZpbHRlclBvc2l0aW9uIDwgc2FsX0ludDMyKCBtX2FGaWx0ZXJSb3dzLnNpemUoKSAtIDEgKSApCiAgICAgICAgICAgICsrbV9uQ3VycmVudEZpbHRlclBvc2l0aW9uOwogICAgICAgIGVsc2UKICAgICAgICAgICAgLS1tX25DdXJyZW50RmlsdGVyUG9zaXRpb247CiAgICB9CgogICAgRm1GaWx0ZXJSb3dzOjppdGVyYXRvciBwb3MgPSBtX2FGaWx0ZXJSb3dzLmJlZ2luKCkgKyBfVGVybTsKICAgIG1fYUZpbHRlclJvd3MuZXJhc2UoIHBvcyApOwoKICAgIC8vIGFkanVzdCBtX25DdXJyZW50RmlsdGVyUG9zaXRpb24gaWYgdGhlIHJlbW92ZWQgcm93IHByZWNlZWRlZCBpdAogICAgaWYgKCBfVGVybSA8IG1fbkN1cnJlbnRGaWx0ZXJQb3NpdGlvbiApCiAgICAgICAgLS1tX25DdXJyZW50RmlsdGVyUG9zaXRpb247CgogICAgT1NMX1BPU1RDT05EKCAoIG1fbkN1cnJlbnRGaWx0ZXJQb3NpdGlvbiA8IDAgKSA9PSAoIG1fYUZpbHRlclJvd3MuZW1wdHkoKSApLAogICAgICAgICJGb3JtQ29udHJvbGxlcjo6cmVtb3ZlRGlzanVuY3RpdmVUZXJtOiBpbmNvbnNpc3RlbmN5ISIgKTsKCiAgICAvLyB1cGRhdGUgdGhlIHRleHRzIGluIHRoZSBmaWx0ZXIgY29udHJvbHMKICAgIGltcGxfc2V0VGV4dE9uQWxsRmlsdGVyX3Rocm93KCk7CgogICAgRmlsdGVyRXZlbnQgYUV2ZW50OwogICAgYUV2ZW50LlNvdXJjZSA9ICp0aGlzOwogICAgYUV2ZW50LkRpc2p1bmN0aXZlVGVybSA9IF9UZXJtOwogICAgYUd1YXJkLmNsZWFyKCk7CiAgICAvLyA8LS0gU1lOQ0hST05JWkVECgogICAgbV9hRmlsdGVyTGlzdGVuZXJzLm5vdGlmeUVhY2goICZYRmlsdGVyQ29udHJvbGxlckxpc3RlbmVyOjpkaXNqdW5jdGl2ZVRlcm1SZW1vdmVkLCBhRXZlbnQgKTsKfQoKLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0Kdm9pZCBTQUxfQ0FMTCBGb3JtQ29udHJvbGxlcjo6YXBwZW5kRW1wdHlEaXNqdW5jdGl2ZVRlcm0oKSB0aHJvdyAoUnVudGltZUV4Y2VwdGlvbikKewogICAgLy8gU1lOQ0hST05JWkVEIC0tPgogICAgOjpvc2w6OkNsZWFyYWJsZU11dGV4R3VhcmQgYUd1YXJkKCBtX2FNdXRleCApOwogICAgaW1wbF9jaGVja0Rpc3Bvc2VkX3Rocm93KCk7CgogICAgaW1wbF9hcHBlbmRFbXB0eUZpbHRlclJvdyggYUd1YXJkICk7CiAgICAvLyA8LS0gU1lOQ0hST05JWkVECn0KCi8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCjo6c2FsX0ludDMyIFNBTF9DQUxMIEZvcm1Db250cm9sbGVyOjpnZXRBY3RpdmVUZXJtKCkgdGhyb3cgKFJ1bnRpbWVFeGNlcHRpb24pCnsKICAgIDo6b3NsOjpNdXRleEd1YXJkIGFHdWFyZCggbV9hTXV0ZXggKTsKICAgIGltcGxfY2hlY2tEaXNwb3NlZF90aHJvdygpOwoKICAgIHJldHVybiBtX25DdXJyZW50RmlsdGVyUG9zaXRpb247Cn0KCi8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCnZvaWQgU0FMX0NBTEwgRm9ybUNvbnRyb2xsZXI6OnNldEFjdGl2ZVRlcm0oIDo6c2FsX0ludDMyIF9BY3RpdmVUZXJtICkgdGhyb3cgKEluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24sIFJ1bnRpbWVFeGNlcHRpb24pCnsKICAgIDo6b3NsOjpNdXRleEd1YXJkIGFHdWFyZCggbV9hTXV0ZXggKTsKICAgIGltcGxfY2hlY2tEaXNwb3NlZF90aHJvdygpOwoKICAgIGlmICggKCBfQWN0aXZlVGVybSA8IDAgKSB8fCAoIF9BY3RpdmVUZXJtID49IGdldERpc2p1bmN0aXZlVGVybXMoKSApICkKICAgICAgICB0aHJvdyBJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uKCA6OnJ0bDo6T1VTdHJpbmcoKSwgKnRoaXMgKTsKCiAgICBpZiAoIF9BY3RpdmVUZXJtID09IGdldEFjdGl2ZVRlcm0oKSApCiAgICAgICAgcmV0dXJuOwoKICAgIG1fbkN1cnJlbnRGaWx0ZXJQb3NpdGlvbiA9IF9BY3RpdmVUZXJtOwogICAgaW1wbF9zZXRUZXh0T25BbGxGaWx0ZXJfdGhyb3coKTsKfQoKLy8gWEVsZW1lbnRBY2Nlc3MKLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0Kc2FsX0Jvb2wgU0FMX0NBTEwgRm9ybUNvbnRyb2xsZXI6Omhhc0VsZW1lbnRzKHZvaWQpIHRocm93KCBSdW50aW1lRXhjZXB0aW9uICkKewogICAgOjpvc2w6Ok11dGV4R3VhcmQgYUd1YXJkKCBtX2FNdXRleCApOwogICAgcmV0dXJuICFtX2FDaGlsZHMuZW1wdHkoKTsKfQoKLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KVHlwZSBTQUxfQ0FMTCAgRm9ybUNvbnRyb2xsZXI6OmdldEVsZW1lbnRUeXBlKHZvaWQpIHRocm93KCBSdW50aW1lRXhjZXB0aW9uICkKewogICAgcmV0dXJuIDo6Z2V0Q3BwdVR5cGUoKGNvbnN0IFJlZmVyZW5jZTwgWEZvcm1Db250cm9sbGVyPiopMCk7Cgp9CgovLyBYRW51bWVyYXRpb25BY2Nlc3MKLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KUmVmZXJlbmNlPCBYRW51bWVyYXRpb24gPiBTQUxfQ0FMTCAgRm9ybUNvbnRyb2xsZXI6OmNyZWF0ZUVudW1lcmF0aW9uKHZvaWQpIHRocm93KCBSdW50aW1lRXhjZXB0aW9uICkKewogICAgOjpvc2w6Ok11dGV4R3VhcmQgYUd1YXJkKCBtX2FNdXRleCApOwogICAgcmV0dXJuIG5ldyA6OmNvbXBoZWxwZXI6Ok9FbnVtZXJhdGlvbkJ5SW5kZXgodGhpcyk7Cn0KCi8vIFhJbmRleEFjY2VzcwovLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQpzYWxfSW50MzIgU0FMX0NBTEwgRm9ybUNvbnRyb2xsZXI6OmdldENvdW50KHZvaWQpIHRocm93KCBSdW50aW1lRXhjZXB0aW9uICkKewoJOjpvc2w6Ok11dGV4R3VhcmQgYUd1YXJkKCBtX2FNdXRleCApOwogICAgcmV0dXJuIG1fYUNoaWxkcy5zaXplKCk7Cn0KCi8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCkFueSBTQUxfQ0FMTCBGb3JtQ29udHJvbGxlcjo6Z2V0QnlJbmRleChzYWxfSW50MzIgSW5kZXgpIHRocm93KCBJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uLCBXcmFwcGVkVGFyZ2V0RXhjZXB0aW9uLCBSdW50aW1lRXhjZXB0aW9uICkKewoJOjpvc2w6Ok11dGV4R3VhcmQgYUd1YXJkKCBtX2FNdXRleCApOwoJaWYgKEluZGV4IDwgMCB8fAoJCUluZGV4ID49IChzYWxfSW50MzIpbV9hQ2hpbGRzLnNpemUoKSkKCQl0aHJvdyBJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uKCk7CgogICAgcmV0dXJuIG1ha2VBbnkoIG1fYUNoaWxkc1sgSW5kZXggXSApOwp9CgovLyAgRXZlbnRMaXN0ZW5lcgovLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQp2b2lkIFNBTF9DQUxMIEZvcm1Db250cm9sbGVyOjpkaXNwb3NpbmcoY29uc3QgRXZlbnRPYmplY3QmIGUpIHRocm93KCBSdW50aW1lRXhjZXB0aW9uICkKewogICAgLy8gSXN0IGRlciBDb250YWluZXIgZGlzcG9zZWQgd29yZGVuCgk6Om9zbDo6TXV0ZXhHdWFyZCBhR3VhcmQoIG1fYU11dGV4ICk7CiAgICBSZWZlcmVuY2U8IFhDb250cm9sQ29udGFpbmVyID4gIHhDb250YWluZXIoZS5Tb3VyY2UsIFVOT19RVUVSWSk7CiAgICBpZiAoeENvbnRhaW5lci5pcygpKQogICAgewogICAgICAgIHNldENvbnRhaW5lcihSZWZlcmVuY2U8IFhDb250cm9sQ29udGFpbmVyID4gKCkpOwogICAgfQogICAgZWxzZQogICAgewogICAgICAgIC8vIGlzdCBlaW4gQ29udHJvbCBkaXNwb3NlZCB3b3JkZW4KICAgICAgICBSZWZlcmVuY2U8IFhDb250cm9sID4gIHhDb250cm9sKGUuU291cmNlLCBVTk9fUVVFUlkpOwogICAgICAgIGlmICh4Q29udHJvbC5pcygpKQogICAgICAgIHsKICAgICAgICAgICAgaWYgKGdldENvbnRhaW5lcigpLmlzKCkpCiAgICAgICAgICAgICAgICByZW1vdmVDb250cm9sKHhDb250cm9sKTsKICAgICAgICB9CiAgICB9Cn0KCi8vIE9Db21wb25lbnRIZWxwZXIKLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQp2b2lkIEZvcm1Db250cm9sbGVyOjpkaXNwb3NlQWxsRmVhdHVyZXNBbmREaXNwYXRjaGVycygpIFNBTF9USFJPVygoKSkKewogICAgZm9yICggRGlzcGF0Y2hlckNvbnRhaW5lcjo6aXRlcmF0b3IgYURpc3BhdGNoZXIgPSBtX2FGZWF0dXJlRGlzcGF0Y2hlcnMuYmVnaW4oKTsKICAgICAgICAgIGFEaXNwYXRjaGVyICE9IG1fYUZlYXR1cmVEaXNwYXRjaGVycy5lbmQoKTsKICAgICAgICAgICsrYURpc3BhdGNoZXIKICAgICAgICApCiAgICB7CiAgICAgICAgdHJ5CiAgICAgICAgewogICAgICAgICAgICA6OmNvbXBoZWxwZXI6OmRpc3Bvc2VDb21wb25lbnQoIGFEaXNwYXRjaGVyLT5zZWNvbmQgKTsKICAgICAgICB9CiAgICAgICAgY2F0Y2goIGNvbnN0IEV4Y2VwdGlvbiYgKQogICAgICAgIHsKICAgICAgICAgICAgREJHX1VOSEFORExFRF9FWENFUFRJT04oKTsKICAgICAgICB9CiAgICB9CiAgICBtX2FGZWF0dXJlRGlzcGF0Y2hlcnMuY2xlYXIoKTsKfQoKLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQp2b2lkIEZvcm1Db250cm9sbGVyOjpkaXNwb3Npbmcodm9pZCkKewogICAgRXZlbnRPYmplY3QgYUV2dCggKnRoaXMgKTsKCiAgICAvLyBpZiB3ZSdyZSBzdGlsbCBhY3RpdmUsIHNpbXVsYXRlIGEgImRlYWN0aXZhdGVkIiBldmVudAogICAgaWYgKCBtX3hBY3RpdmVDb250cm9sLmlzKCkgKQogICAgICAgIG1fYUFjdGl2YXRlTGlzdGVuZXJzLm5vdGlmeUVhY2goICZYRm9ybUNvbnRyb2xsZXJMaXN0ZW5lcjo6Zm9ybURlYWN0aXZhdGVkLCBhRXZ0ICk7CgogICAgLy8gbm90aWZ5IGFsbCBvdXIgbGlzdGVuZXJzCiAgICBtX2FBY3RpdmF0ZUxpc3RlbmVycy5kaXNwb3NlQW5kQ2xlYXIoYUV2dCk7CiAgICBtX2FNb2RpZnlMaXN0ZW5lcnMuZGlzcG9zZUFuZENsZWFyKGFFdnQpOwogICAgbV9hRXJyb3JMaXN0ZW5lcnMuZGlzcG9zZUFuZENsZWFyKGFFdnQpOwogICAgbV9hRGVsZXRlTGlzdGVuZXJzLmRpc3Bvc2VBbmRDbGVhcihhRXZ0KTsKICAgIG1fYVJvd1NldEFwcHJvdmVMaXN0ZW5lcnMuZGlzcG9zZUFuZENsZWFyKGFFdnQpOwogICAgbV9hUGFyYW1ldGVyTGlzdGVuZXJzLmRpc3Bvc2VBbmRDbGVhcihhRXZ0KTsKICAgIG1fYUZpbHRlckxpc3RlbmVycy5kaXNwb3NlQW5kQ2xlYXIoYUV2dCk7CgoJcmVtb3ZlQm91bmRGaWVsZExpc3RlbmVyKCk7CglzdG9wRmlsdGVyaW5nKCk7CgogICAgbV9wQ29udHJvbEJvcmRlck1hbmFnZXItPnJlc3RvcmVBbGwoKTsKICAgIAogICAgbV9hRmlsdGVyUm93cy5jbGVhcigpOwoKICAgIDo6b3NsOjpNdXRleEd1YXJkIGFHdWFyZCggbV9hTXV0ZXggKTsKICAgIG1feEFjdGl2ZUNvbnRyb2wgPSBOVUxMOwogICAgaW1wbFNldEN1cnJlbnRDb250cm9sKCBOVUxMICk7CgogICAgLy8gY2xlYW4gdXAgb3VyIGNoaWxkcmVuCiAgICBmb3IgKEZtRm9ybUNvbnRyb2xsZXJzOjpjb25zdF9pdGVyYXRvciBpID0gbV9hQ2hpbGRzLmJlZ2luKCk7CiAgICAgICAgaSAhPSBtX2FDaGlsZHMuZW5kKCk7IGkrKykKICAgIHsKICAgICAgICAvLyBzZWFyY2ggdGhlIHBvc2l0aW9uIG9mIHRoZSBtb2RlbCB3aXRoaW4gdGhlIGZvcm0KICAgICAgICBSZWZlcmVuY2U8IFhGb3JtQ29tcG9uZW50ID4gIHhGb3JtKCgqaSktPmdldE1vZGVsKCksIFVOT19RVUVSWSk7CiAgICAgICAgc2FsX3VJbnQzMiBuUG9zID0gbV94TW9kZWxBc0luZGV4LT5nZXRDb3VudCgpOwogICAgICAgIFJlZmVyZW5jZTwgWEZvcm1Db21wb25lbnQgPiB4VGVtcDsKICAgICAgICBmb3IoIDsgblBvczsgKQogICAgICAgIHsKCiAgICAgICAgICAgIG1feE1vZGVsQXNJbmRleC0+Z2V0QnlJbmRleCggLS1uUG9zICkgPj49IHhUZW1wOwogICAgICAgICAgICBpZiAoIHhGb3JtLmdldCgpID09IHhUZW1wLmdldCgpICkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgUmVmZXJlbmNlPCBYSW50ZXJmYWNlID4geElmYyggKmksIFVOT19RVUVSWSApOwogICAgICAgICAgICAgICAgbV94TW9kZWxBc01hbmFnZXItPmRldGFjaCggblBvcywgeElmYyApOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIFJlZmVyZW5jZTwgWENvbXBvbmVudCA+ICgqaSwgVU5PX1FVRVJZKS0+ZGlzcG9zZSgpOwogICAgfQogICAgbV9hQ2hpbGRzLmNsZWFyKCk7CgogICAgZGlzcG9zZUFsbEZlYXR1cmVzQW5kRGlzcGF0Y2hlcnMoKTsKCiAgICBpZiAoIG1feEZvcm1PcGVyYXRpb25zLmlzKCkgKQogICAgICAgIG1feEZvcm1PcGVyYXRpb25zLT5kaXNwb3NlKCk7CiAgICBtX3hGb3JtT3BlcmF0aW9ucy5jbGVhcigpOwoKICAgIGlmIChtX2JEQkNvbm5lY3Rpb24pCiAgICAgICAgdW5sb2FkKCk7CgogICAgc2V0Q29udGFpbmVyKCBOVUxMICk7CiAgICBzZXRNb2RlbCggTlVMTCApOwogICAgc2V0UGFyZW50KCBOVUxMICk7CgogICAgOjpjb21waGVscGVyOjpkaXNwb3NlQ29tcG9uZW50KCBtX3hDb21wb3NlciApOwoKICAgIG1fYkRCQ29ubmVjdGlvbiA9IHNhbF9GYWxzZTsKfQoKLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KbmFtZXNwYWNlCnsKICAgIHN0YXRpYyBib29sIGxjbF9zaG91bGRVc2VEeW5hbWljQ29udHJvbEJvcmRlciggY29uc3QgUmVmZXJlbmNlPCBYSW50ZXJmYWNlID4mIF9yeEZvcm0sIGNvbnN0IEFueSYgX3JEeW5hbWljQ29sb3JQcm9wICkKICAgIHsKICAgICAgICBib29sIGJEb1VzZSA9IGZhbHNlOwogICAgICAgIGlmICggISggX3JEeW5hbWljQ29sb3JQcm9wID4+PSBiRG9Vc2UgKSApCiAgICAgICAgewogICAgICAgICAgICBEb2N1bWVudFR5cGUgZURvY1R5cGUgPSBEb2N1bWVudENsYXNzaWZpY2F0aW9uOjpjbGFzc2lmeUhvc3REb2N1bWVudCggX3J4Rm9ybSApOwogICAgICAgICAgICByZXR1cm4gQ29udHJvbExheW91dGVyOjp1c2VEeW5hbWljQm9yZGVyQ29sb3IoIGVEb2NUeXBlICk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBiRG9Vc2U7CiAgICB9Cn0KCi8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCnZvaWQgU0FMX0NBTEwgRm9ybUNvbnRyb2xsZXI6OnByb3BlcnR5Q2hhbmdlKGNvbnN0IFByb3BlcnR5Q2hhbmdlRXZlbnQmIGV2dCkgdGhyb3coIFJ1bnRpbWVFeGNlcHRpb24gKQp7CiAgICBPU0xfRU5TVVJFKCAhaW1wbF9pc0Rpc3Bvc2VkX25vZmFpbCgpLCAiRm9ybUNvbnRyb2xsZXI6IGFscmVhZHkgZGlzcG9zZWQhIiApOwogICAgaWYgKCBldnQuUHJvcGVydHlOYW1lID09IEZNX1BST1BfQk9VTkRGSUVMRCApCiAgICB7CgkJUmVmZXJlbmNlPFhQcm9wZXJ0eVNldD4geE9sZEJvdW5kOwoJCWV2dC5PbGRWYWx1ZSA+Pj0geE9sZEJvdW5kOwoJCWlmICggIXhPbGRCb3VuZC5pcygpICYmIGV2dC5OZXdWYWx1ZS5oYXNWYWx1ZSgpICkKCQl7CgkJCVJlZmVyZW5jZTwgWENvbnRyb2xNb2RlbCA+IHhDb250cm9sTW9kZWwoZXZ0LlNvdXJjZSxVTk9fUVVFUlkpOwoJCQlSZWZlcmVuY2U8IFhDb250cm9sID4geENvbnRyb2wgPSBmaW5kQ29udHJvbChtX2FDb250cm9scyx4Q29udHJvbE1vZGVsLHNhbF9GYWxzZSxzYWxfRmFsc2UpOwoJCQlpZiAoIHhDb250cm9sLmlzKCkgKQoJCQl7CgkJCQlzdGFydENvbnRyb2xNb2RpZnlMaXN0ZW5pbmcoIHhDb250cm9sICk7CgkJCQlSZWZlcmVuY2U8WFByb3BlcnR5U2V0PiB4UHJvcCh4Q29udHJvbE1vZGVsLFVOT19RVUVSWSk7CgkJCQlpZiAoIHhQcm9wLmlzKCkgKQoJCQkJCXhQcm9wLT5yZW1vdmVQcm9wZXJ0eUNoYW5nZUxpc3RlbmVyKEZNX1BST1BfQk9VTkRGSUVMRCwgdGhpcyk7CgkJCX0KCQl9CiAgICB9CiAgICBlbHNlCiAgICB7CgkJc2FsX0Jvb2wgYk1vZGlmaWVkQ2hhbmdlZCA9IChldnQuUHJvcGVydHlOYW1lID09IEZNX1BST1BfSVNNT0RJRklFRCk7CgkJc2FsX0Jvb2wgYk5ld0NoYW5nZWQgPSAoZXZ0LlByb3BlcnR5TmFtZSA9PSBGTV9QUk9QX0lTTkVXKTsKCQlpZiAoYk1vZGlmaWVkQ2hhbmdlZCB8fCBiTmV3Q2hhbmdlZCkKCQl7CgkJCTo6b3NsOjpNdXRleEd1YXJkIGFHdWFyZCggbV9hTXV0ZXggKTsKCQkJaWYgKGJNb2RpZmllZENoYW5nZWQpCgkJCQltX2JDdXJyZW50UmVjb3JkTW9kaWZpZWQgPSA6OmNvbXBoZWxwZXI6OmdldEJPT0woZXZ0Lk5ld1ZhbHVlKTsKCQkJZWxzZQoJCQkJbV9iQ3VycmVudFJlY29yZE5ldyA9IDo6Y29tcGhlbHBlcjo6Z2V0Qk9PTChldnQuTmV3VmFsdWUpOwoKCQkJLy8gdG9nZ2xlIHRoZSBsb2NraW5nCgkJCWlmIChtX2JMb2NrZWQgIT0gZGV0ZXJtaW5lTG9ja1N0YXRlKCkpCgkJCXsKCQkJCW1fYkxvY2tlZCA9ICFtX2JMb2NrZWQ7CgkJCQlzZXRMb2NrcygpOwoJCQkJaWYgKGlzTGlzdGVuaW5nRm9yQ2hhbmdlcygpKQoJCQkJCXN0YXJ0TGlzdGVuaW5nKCk7CgkJCQllbHNlCgkJCQkJc3RvcExpc3RlbmluZygpOwoJCQl9CgoJCQlpZiAoIGJOZXdDaGFuZ2VkICkKCQkJCW1fYVRvZ2dsZUV2ZW50LkNhbGwoKTsKCgkJCWlmICghbV9iQ3VycmVudFJlY29yZE1vZGlmaWVkKQoJCQkJbV9iTW9kaWZpZWQgPSBzYWxfRmFsc2U7CgkJfQogICAgICAgIGVsc2UgaWYgKCBldnQuUHJvcGVydHlOYW1lID09IEZNX1BST1BfRFlOQU1JQ19DT05UUk9MX0JPUkRFUiApCiAgICAgICAgewogICAgICAgICAgICBib29sIGJFbmFibGUgPSBsY2xfc2hvdWxkVXNlRHluYW1pY0NvbnRyb2xCb3JkZXIoIGV2dC5Tb3VyY2UsIGV2dC5OZXdWYWx1ZSApOwogICAgICAgICAgICBpZiAoIGJFbmFibGUgKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBtX3BDb250cm9sQm9yZGVyTWFuYWdlci0+ZW5hYmxlRHluYW1pY0JvcmRlckNvbG9yKCk7CiAgICAgICAgICAgICAgICBpZiAoIG1feEFjdGl2ZUNvbnRyb2wuaXMoKSApCiAgICAgICAgICAgICAgICAgICAgbV9wQ29udHJvbEJvcmRlck1hbmFnZXItPmZvY3VzR2FpbmVkKCBtX3hBY3RpdmVDb250cm9sLmdldCgpICk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZWxzZQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBtX3BDb250cm9sQm9yZGVyTWFuYWdlci0+ZGlzYWJsZUR5bmFtaWNCb3JkZXJDb2xvcigpOwogICAgICAgICAgICB9CiAgICAgICAgfQoJfQp9CgovLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQpib29sIEZvcm1Db250cm9sbGVyOjpyZXBsYWNlQ29udHJvbCggY29uc3QgUmVmZXJlbmNlPCBYQ29udHJvbCA+JiBfcnhFeGlzdGVudENvbnRyb2wsIGNvbnN0IFJlZmVyZW5jZTwgWENvbnRyb2wgPiYgX3J4TmV3Q29udHJvbCApCnsKICAgIGJvb2wgYlN1Y2Nlc3MgPSBmYWxzZTsKICAgIHRyeQogICAgewogICAgICAgIFJlZmVyZW5jZTwgWElkZW50aWZpZXJSZXBsYWNlID4geENvbnRhaW5lciggZ2V0Q29udGFpbmVyKCksIFVOT19RVUVSWSApOwogICAgICAgIERCR19BU1NFUlQoIHhDb250YWluZXIuaXMoKSwgIkZvcm1Db250cm9sbGVyOjpyZXBsYWNlQ29udHJvbDogeWVzLCBpdCdzIG5vdCByZXF1aXJlZCBieSB0aGUgc2VydmljZSBkZXNjcmlwdGlvbiwgYnV0IFhJdGVudGlmaWVyUmVwbGFjZXMgd291bGQgYmUgbmljZSEiICk7CiAgICAgICAgaWYgKCB4Q29udGFpbmVyLmlzKCkgKQogICAgICAgIHsKICAgICAgICAgICAgLy8gbG9vayB1cCB0aGUgSUQgb2YgX3J4RXhpc3RlbnRDb250cm9sCiAgICAgICAgICAgIFNlcXVlbmNlPCBzYWxfSW50MzIgPiBhSWRlbnRpZmllcnMoIHhDb250YWluZXItPmdldElkZW50aWZpZXJzKCkgKTsKICAgICAgICAgICAgY29uc3Qgc2FsX0ludDMyKiBwSWRlbnRpZmllcnMgPSBhSWRlbnRpZmllcnMuZ2V0Q29uc3RBcnJheSgpOwogICAgICAgICAgICBjb25zdCBzYWxfSW50MzIqIHBJZGVudGlmaWVyc0VuZCA9IGFJZGVudGlmaWVycy5nZXRDb25zdEFycmF5KCkgKyBhSWRlbnRpZmllcnMuZ2V0TGVuZ3RoKCk7CiAgICAgICAgICAgIGZvciAoIDsgcElkZW50aWZpZXJzICE9IHBJZGVudGlmaWVyc0VuZDsgKytwSWRlbnRpZmllcnMgKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBSZWZlcmVuY2U8IFhDb250cm9sID4geENoZWNrKCB4Q29udGFpbmVyLT5nZXRCeUlkZW50aWZpZXIoICpwSWRlbnRpZmllcnMgKSwgVU5PX1FVRVJZICk7CiAgICAgICAgICAgICAgICBpZiAoIHhDaGVjayA9PSBfcnhFeGlzdGVudENvbnRyb2wgKQogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICB9CiAgICAgICAgICAgIERCR19BU1NFUlQoIHBJZGVudGlmaWVycyAhPSBwSWRlbnRpZmllcnNFbmQsICJGb3JtQ29udHJvbGxlcjo6cmVwbGFjZUNvbnRyb2w6IGRpZCBub3QgZmluZCB0aGUgY29udHJvbCBpbiB0aGUgY29udGFpbmVyISIgKTsKICAgICAgICAgICAgaWYgKCBwSWRlbnRpZmllcnMgIT0gcElkZW50aWZpZXJzRW5kICkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgYm9vbCBiUmVwbGFjZWRXYXNBY3RpdmUgPSAoIG1feEFjdGl2ZUNvbnRyb2wuZ2V0KCkgPT0gX3J4RXhpc3RlbnRDb250cm9sLmdldCgpICk7CiAgICAgICAgICAgICAgICBib29sIGJSZXBsYWNlZFdhc0N1cnJlbnQgPSAoIG1feEN1cnJlbnRDb250cm9sLmdldCgpID09IF9yeEV4aXN0ZW50Q29udHJvbC5nZXQoKSApOwoKICAgICAgICAgICAgICAgIGlmICggYlJlcGxhY2VkV2FzQWN0aXZlICkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBtX3hBY3RpdmVDb250cm9sID0gTlVMTDsKICAgICAgICAgICAgICAgICAgICBpbXBsU2V0Q3VycmVudENvbnRyb2woIE5VTEwgKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGVsc2UgaWYgKCBiUmVwbGFjZWRXYXNDdXJyZW50ICkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBpbXBsU2V0Q3VycmVudENvbnRyb2woIF9yeE5ld0NvbnRyb2wgKTsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAvLyBjYXJyeSBvdmVyIHRoZSBtb2RlbAogICAgICAgICAgICAgICAgX3J4TmV3Q29udHJvbC0+c2V0TW9kZWwoIF9yeEV4aXN0ZW50Q29udHJvbC0+Z2V0TW9kZWwoKSApOwoKICAgICAgICAgICAgICAgIHhDb250YWluZXItPnJlcGxhY2VCeUlkZW50aWZlciggKnBJZGVudGlmaWVycywgbWFrZUFueSggX3J4TmV3Q29udHJvbCApICk7CiAgICAgICAgICAgICAgICBiU3VjY2VzcyA9IHRydWU7CgogICAgICAgICAgICAgICAgaWYgKCBiUmVwbGFjZWRXYXNBY3RpdmUgKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIFJlZmVyZW5jZTwgWFdpbmRvdyA+IHhDb250cm9sV2luZG93KCBfcnhOZXdDb250cm9sLCBVTk9fUVVFUlkgKTsKICAgICAgICAgICAgICAgICAgICBpZiAoIHhDb250cm9sV2luZG93LmlzKCkgKQogICAgICAgICAgICAgICAgICAgICAgICB4Q29udHJvbFdpbmRvdy0+c2V0Rm9jdXMoKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0KICAgIGNhdGNoKCBjb25zdCBFeGNlcHRpb24mICkKICAgIHsKICAgICAgICBEQkdfVU5IQU5ETEVEX0VYQ0VQVElPTigpOwogICAgfQogIAogICAgUmVmZXJlbmNlPCBYQ29udHJvbCA+IHhEaXNwb3NlSXQoIGJTdWNjZXNzID8gX3J4RXhpc3RlbnRDb250cm9sIDogX3J4TmV3Q29udHJvbCApOwogICAgOjpjb21waGVscGVyOjpkaXNwb3NlQ29tcG9uZW50KCB4RGlzcG9zZUl0ICk7CiAgICByZXR1cm4gYlN1Y2Nlc3M7Cn0KICAKLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0Kdm9pZCBGb3JtQ29udHJvbGxlcjo6dG9nZ2xlQXV0b0ZpZWxkcyhzYWxfQm9vbCBiQXV0b0ZpZWxkcykKewogICAgT1NMX0VOU1VSRSggIWltcGxfaXNEaXNwb3NlZF9ub2ZhaWwoKSwgIkZvcm1Db250cm9sbGVyOiBhbHJlYWR5IGRpc3Bvc2VkISIgKTsKCgogICAgU2VxdWVuY2U8IFJlZmVyZW5jZTwgWENvbnRyb2wgPiA+IGFDb250cm9sc0NvcHkoIG1fYUNvbnRyb2xzICk7CiAgICBjb25zdCBSZWZlcmVuY2U8IFhDb250cm9sID4qIHBDb250cm9scyA9IGFDb250cm9sc0NvcHkuZ2V0Q29uc3RBcnJheSgpOwogICAgc2FsX0ludDMyIG5Db250cm9scyA9IGFDb250cm9sc0NvcHkuZ2V0TGVuZ3RoKCk7CgogICAgaWYgKGJBdXRvRmllbGRzKQogICAgewogICAgICAgIC8vIGFzIHdlIGRvbid0IHdhbnQgbmV3IGNvbnRyb2xzIHRvIGJlIGF0dGFjaGVkIHRvIHRoZSBzY3JpcHRpbmcgZW52aXJvbm1lbnQKICAgICAgICAvLyB3ZSBjaGFuZ2UgYXR0YWNoIGZsYWdzCiAgICAgICAgbV9iQXR0YWNoRXZlbnRzID0gc2FsX0ZhbHNlOwogICAgICAgIGZvciAoc2FsX0ludDMyIGkgPSBuQ29udHJvbHM7IGkgPiAwOykKICAgICAgICB7CiAgICAgICAgICAgIFJlZmVyZW5jZTwgWENvbnRyb2wgPiB4Q29udHJvbCA9IHBDb250cm9sc1stLWldOwogICAgICAgICAgICBpZiAoeENvbnRyb2wuaXMoKSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgUmVmZXJlbmNlPCBYUHJvcGVydHlTZXQgPiAgeFNldCh4Q29udHJvbC0+Z2V0TW9kZWwoKSwgVU5PX1FVRVJZKTsKICAgICAgICAgICAgICAgIGlmICh4U2V0LmlzKCkgJiYgOjpjb21waGVscGVyOjpoYXNQcm9wZXJ0eShGTV9QUk9QX0JPVU5ERklFTEQsIHhTZXQpKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIC8vIGRvZXMgdGhlIG1vZGVsIHVzZSBhIGJvdW5kIGZpZWxkID8KICAgICAgICAgICAgICAgICAgICBSZWZlcmVuY2U8IFhQcm9wZXJ0eVNldCA+ICB4RmllbGQ7CiAgICAgICAgICAgICAgICAgICAgeFNldC0+Z2V0UHJvcGVydHlWYWx1ZShGTV9QUk9QX0JPVU5ERklFTEQpID4+PSB4RmllbGQ7CgogICAgICAgICAgICAgICAgICAgIC8vIGlzIGl0IGEgYXV0b2ZpZWxkPwogICAgICAgICAgICAgICAgICAgIGlmICAoICAgeEZpZWxkLmlzKCkKICAgICAgICAgICAgICAgICAgICAgICAgJiYgIDo6Y29tcGhlbHBlcjo6aGFzUHJvcGVydHkoIEZNX1BST1BfQVVUT0lOQ1JFTUVOVCwgeEZpZWxkICkKICAgICAgICAgICAgICAgICAgICAgICAgJiYgIDo6Y29tcGhlbHBlcjo6Z2V0Qk9PTCggeEZpZWxkLT5nZXRQcm9wZXJ0eVZhbHVlKCBGTV9QUk9QX0FVVE9JTkNSRU1FTlQgKSApCiAgICAgICAgICAgICAgICAgICAgICAgICkKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIHJlcGxhY2VDb250cm9sKCB4Q29udHJvbCwgbmV3IEZtWEF1dG9Db250cm9sKCBtX2FDb250ZXh0ICkgKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgbV9iQXR0YWNoRXZlbnRzID0gc2FsX1RydWU7CiAgICB9CiAgICBlbHNlCiAgICB7CiAgICAgICAgbV9iRGV0YWNoRXZlbnRzID0gc2FsX0ZhbHNlOwogICAgICAgIGZvciAoc2FsX0ludDMyIGkgPSBuQ29udHJvbHM7IGkgPiAwOykKICAgICAgICB7CiAgICAgICAgICAgIFJlZmVyZW5jZTwgWENvbnRyb2wgPiB4Q29udHJvbCA9IHBDb250cm9sc1stLWldOwogICAgICAgICAgICBpZiAoeENvbnRyb2wuaXMoKSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgUmVmZXJlbmNlPCBYUHJvcGVydHlTZXQgPiAgeFNldCh4Q29udHJvbC0+Z2V0TW9kZWwoKSwgVU5PX1FVRVJZKTsKICAgICAgICAgICAgICAgIGlmICh4U2V0LmlzKCkgJiYgOjpjb21waGVscGVyOjpoYXNQcm9wZXJ0eShGTV9QUk9QX0JPVU5ERklFTEQsIHhTZXQpKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIC8vIGRvZXMgdGhlIG1vZGVsIHVzZSBhIGJvdW5kIGZpZWxkID8KICAgICAgICAgICAgICAgICAgICBSZWZlcmVuY2U8IFhQcm9wZXJ0eVNldCA+ICB4RmllbGQ7CiAgICAgICAgICAgICAgICAgICAgeFNldC0+Z2V0UHJvcGVydHlWYWx1ZShGTV9QUk9QX0JPVU5ERklFTEQpID4+PSB4RmllbGQ7CgogICAgICAgICAgICAgICAgICAgIC8vIGlzIGl0IGEgYXV0b2ZpZWxkPwogICAgICAgICAgICAgICAgICAgIGlmICAoICAgeEZpZWxkLmlzKCkKICAgICAgICAgICAgICAgICAgICAgICAgJiYgIDo6Y29tcGhlbHBlcjo6aGFzUHJvcGVydHkoIEZNX1BST1BfQVVUT0lOQ1JFTUVOVCwgeEZpZWxkICkKICAgICAgICAgICAgICAgICAgICAgICAgJiYgIDo6Y29tcGhlbHBlcjo6Z2V0Qk9PTCggeEZpZWxkLT5nZXRQcm9wZXJ0eVZhbHVlKEZNX1BST1BfQVVUT0lOQ1JFTUVOVCApICkKICAgICAgICAgICAgICAgICAgICAgICAgKQogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgOjpydGw6Ok9VU3RyaW5nIHNTZXJ2aWNlTmFtZTsKICAgICAgICAgICAgICAgICAgICAgICAgT1NMX1ZFUklGWSggeFNldC0+Z2V0UHJvcGVydHlWYWx1ZSggRk1fUFJPUF9ERUZBVUxUQ09OVFJPTCApID4+PSBzU2VydmljZU5hbWUgKTsKICAgICAgICAgICAgICAgICAgICAgICAgUmVmZXJlbmNlPCBYQ29udHJvbCA+IHhOZXdDb250cm9sKCBtX2FDb250ZXh0LmNyZWF0ZUNvbXBvbmVudCggc1NlcnZpY2VOYW1lICksIFVOT19RVUVSWSApOwogICAgICAgICAgICAgICAgICAgICAgICByZXBsYWNlQ29udHJvbCggeENvbnRyb2wsIHhOZXdDb250cm9sICk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIG1fYkRldGFjaEV2ZW50cyA9IHNhbF9UcnVlOwogICAgfQp9CgovLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQpJTVBMX0xJTksoRm9ybUNvbnRyb2xsZXIsIE9uVG9nZ2xlQXV0b0ZpZWxkcywgdm9pZCosIEVNUFRZQVJHKQp7CiAgICBPU0xfRU5TVVJFKCAhaW1wbF9pc0Rpc3Bvc2VkX25vZmFpbCgpLCAiRm9ybUNvbnRyb2xsZXI6IGFscmVhZHkgZGlzcG9zZWQhIiApOwoKICAgIHRvZ2dsZUF1dG9GaWVsZHMobV9iQ3VycmVudFJlY29yZE5ldyk7CiAgICByZXR1cm4gMUw7Cn0KCi8vIFhUZXh0TGlzdGVuZXIKLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0Kdm9pZCBTQUxfQ0FMTCBGb3JtQ29udHJvbGxlcjo6dGV4dENoYW5nZWQoY29uc3QgVGV4dEV2ZW50JiBlKSB0aHJvdyggUnVudGltZUV4Y2VwdGlvbiApCnsKICAgIC8vIFNZTkNIUk9OSVpFRCAtLT4KICAgIDo6b3NsOjpDbGVhcmFibGVNdXRleEd1YXJkIGFHdWFyZCggbV9hTXV0ZXggKTsKICAgIE9TTF9FTlNVUkUoICFpbXBsX2lzRGlzcG9zZWRfbm9mYWlsKCksICJGb3JtQ29udHJvbGxlcjogYWxyZWFkeSBkaXNwb3NlZCEiICk7CiAgICBpZiAoICFtX2JGaWx0ZXJpbmcgKQogICAgewogICAgICAgIGltcGxfb25Nb2RpZnkoKTsKICAgICAgICByZXR1cm47CiAgICB9CgogICAgaWYgKCBtX2JTdXNwZW5kRmlsdGVyVGV4dExpc3RlbmluZyApCiAgICAgICAgcmV0dXJuOwoKICAgIFJlZmVyZW5jZTwgWFRleHRDb21wb25lbnQgPiAgeFRleHQoZS5Tb3VyY2UsVU5PX1FVRVJZKTsKICAgIDo6cnRsOjpPVVN0cmluZyBhVGV4dCA9IHhUZXh0LT5nZXRUZXh0KCk7CgogICAgaWYgKCBtX2FGaWx0ZXJSb3dzLmVtcHR5KCkgKQogICAgICAgIGFwcGVuZEVtcHR5RGlzanVuY3RpdmVUZXJtKCk7CgogICAgLy8gU3VjaGVuIGRlciBha3R1ZWxsZW4gUm93CiAgICBpZiAoICggKHNpemVfdCltX25DdXJyZW50RmlsdGVyUG9zaXRpb24gPj0gbV9hRmlsdGVyUm93cy5zaXplKCkgKSB8fCAoIG1fbkN1cnJlbnRGaWx0ZXJQb3NpdGlvbiA8IDAgKSApCiAgICB7CgkgICAgT1NMX0VOU1VSRSggZmFsc2UsICJGb3JtQ29udHJvbGxlcjo6dGV4dENoYW5nZWQ6IG1fbkN1cnJlbnRGaWx0ZXJQb3NpdGlvbiBpcyB3cm9uZyEiICk7CiAgICAgICAgcmV0dXJuOwogICAgfQoKCUZtRmlsdGVyUm93JiByUm93ID0gbV9hRmlsdGVyUm93c1sgbV9uQ3VycmVudEZpbHRlclBvc2l0aW9uIF07CgoJLy8gZG8gd2UgaGF2ZSBhIG5ldyBmaWx0ZXIKCWlmIChhVGV4dC5nZXRMZW5ndGgoKSkKCQlyUm93W3hUZXh0XSA9IGFUZXh0OwoJZWxzZQoJewoJCS8vIGRvIHdlIGhhdmUgdGhlIGNvbnRyb2wgaW4gdGhlIHJvdwoJCUZtRmlsdGVyUm93OjppdGVyYXRvciBpdGVyID0gclJvdy5maW5kKHhUZXh0KTsKCQkvLyBlcmFzZSB0aGUgZW50cnkgb3V0IG9mIHRoZSByb3cKCQlpZiAoaXRlciAhPSByUm93LmVuZCgpKQoJCQlyUm93LmVyYXNlKGl0ZXIpOwoJfQoKICAgIC8vIG11bHRpcGxleCB0aGUgZXZlbnQgdG8gb3VyIEZpbHRlckNvbnRyb2xsZXJMaXN0ZW5lcnMKICAgIEZpbHRlckV2ZW50IGFFdmVudDsKICAgIGFFdmVudC5Tb3VyY2UgPSAqdGhpczsKICAgIGFFdmVudC5GaWx0ZXJDb21wb25lbnQgPSA6OnN0ZDo6ZmluZCggbV9hRmlsdGVyQ29tcG9uZW50cy5iZWdpbigpLCBtX2FGaWx0ZXJDb21wb25lbnRzLmVuZCgpLCB4VGV4dCApIC0gbV9hRmlsdGVyQ29tcG9uZW50cy5iZWdpbigpOwogICAgYUV2ZW50LkRpc2p1bmN0aXZlVGVybSA9IGdldEFjdGl2ZVRlcm0oKTsKICAgIGFFdmVudC5QcmVkaWNhdGVFeHByZXNzaW9uID0gYVRleHQ7CgogICAgYUd1YXJkLmNsZWFyKCk7CiAgICAvLyA8LS0gU1lOQ0hST05JWkVECgogICAgLy8gbm90aWZ5IHRoZSBjaGFuZ2VkIGZpbHRlciBleHByZXNzaW9uCiAgICBtX2FGaWx0ZXJMaXN0ZW5lcnMubm90aWZ5RWFjaCggJlhGaWx0ZXJDb250cm9sbGVyTGlzdGVuZXI6OnByZWRpY2F0ZUV4cHJlc3Npb25DaGFuZ2VkLCBhRXZlbnQgKTsKfQoKLy8gWEl0ZW1MaXN0ZW5lcgovLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQp2b2lkIFNBTF9DQUxMIEZvcm1Db250cm9sbGVyOjppdGVtU3RhdGVDaGFuZ2VkKGNvbnN0IEl0ZW1FdmVudCYgLypyRXZlbnQqLykgdGhyb3coIFJ1bnRpbWVFeGNlcHRpb24gKQp7CiAgICBPU0xfRU5TVVJFKCAhaW1wbF9pc0Rpc3Bvc2VkX25vZmFpbCgpLCAiRm9ybUNvbnRyb2xsZXI6IGFscmVhZHkgZGlzcG9zZWQhIiApOwogICAgaW1wbF9vbk1vZGlmeSgpOwp9CgovLyBYTW9kaWZpY2F0aW9uQnJvYWRjYXN0ZXIKLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0Kdm9pZCBTQUxfQ0FMTCBGb3JtQ29udHJvbGxlcjo6YWRkTW9kaWZ5TGlzdGVuZXIoY29uc3QgUmVmZXJlbmNlPCBYTW9kaWZ5TGlzdGVuZXIgPiAmIGwpIHRocm93KCBSdW50aW1lRXhjZXB0aW9uICkKewogICAgOjpvc2w6Ok11dGV4R3VhcmQgYUd1YXJkKCBtX2FNdXRleCApOwogICAgaW1wbF9jaGVja0Rpc3Bvc2VkX3Rocm93KCk7CiAgICBtX2FNb2RpZnlMaXN0ZW5lcnMuYWRkSW50ZXJmYWNlKCBsICk7Cn0KCi8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCnZvaWQgRm9ybUNvbnRyb2xsZXI6OnJlbW92ZU1vZGlmeUxpc3RlbmVyKGNvbnN0IFJlZmVyZW5jZTwgWE1vZGlmeUxpc3RlbmVyID4gJiBsKSB0aHJvdyggUnVudGltZUV4Y2VwdGlvbiApCnsKICAgIDo6b3NsOjpNdXRleEd1YXJkIGFHdWFyZCggbV9hTXV0ZXggKTsKICAgIGltcGxfY2hlY2tEaXNwb3NlZF90aHJvdygpOwogICAgbV9hTW9kaWZ5TGlzdGVuZXJzLnJlbW92ZUludGVyZmFjZSggbCApOwp9CgovLyBYTW9kaWZpY2F0aW9uTGlzdGVuZXIKLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0Kdm9pZCBGb3JtQ29udHJvbGxlcjo6bW9kaWZpZWQoIGNvbnN0IEV2ZW50T2JqZWN0JiBfckV2ZW50ICkgdGhyb3coIFJ1bnRpbWVFeGNlcHRpb24gKQp7CiAgICBPU0xfRU5TVVJFKCAhaW1wbF9pc0Rpc3Bvc2VkX25vZmFpbCgpLCAiRm9ybUNvbnRyb2xsZXI6IGFscmVhZHkgZGlzcG9zZWQhIiApOwoKICAgIHRyeQogICAgewogICAgICAgIGlmICggX3JFdmVudC5Tb3VyY2UgIT0gbV94QWN0aXZlQ29udHJvbCApCiAgICAgICAgewkvLyBsZXQgdGhpcyBjb250cm9sIGdyYWIgdGhlIGZvY3VzCiAgICAgICAgICAgIC8vICh0aGlzIGNhc2UgbWF5IGhhcHBlbiBpZiBzb21lYm9keSBtb3ZlcyB0aGUgc2Nyb2xsIHdoZWVsIG9mIHRoZSBtb3VzZSBvdmVyIGEgY29udHJvbAogICAgICAgICAgICAvLyB3aGljaCBkb2VzIG5vdCBoYXZlIHRoZSBmb2N1cykKICAgICAgICAgICAgLy8gODU1MTEgLSAyOS4wNS4yMDAxIC0gZnJhbmsuc2Nob2VuaGVpdEBnZXJtYW55LnN1bi5jb20KICAgICAgICAgICAgLy8KICAgICAgICAgICAgLy8gYWxzbywgaXQgaGFwcGVucyB3aGVuIGFuIGltYWdlIGNvbnRyb2wgZ2V0cyBhIG5ldyBpbWFnZSBieSBkb3VibGUtY2xpY2tpbmcgaXQKICAgICAgICAgICAgLy8gI2k4ODQ1OCMgLyAyMDA5LTAxLTEyIC8gZnJhbmsuc2Nob2VuaGVpdEBzdW4uY29tCiAgICAgICAgICAgIFJlZmVyZW5jZTwgWFdpbmRvdyA+IHhDb250cm9sV2luZG93KCBfckV2ZW50LlNvdXJjZSwgVU5PX1FVRVJZX1RIUk9XICk7CiAgICAgICAgICAgIHhDb250cm9sV2luZG93LT5zZXRGb2N1cygpOwogICAgICAgIH0KICAgIH0KICAgIGNhdGNoKCBjb25zdCBFeGNlcHRpb24mICkKICAgIHsKICAgIAlEQkdfVU5IQU5ETEVEX0VYQ0VQVElPTigpOwogICAgfQoKICAgIGltcGxfb25Nb2RpZnkoKTsKfQoKLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0Kdm9pZCBGb3JtQ29udHJvbGxlcjo6aW1wbF9jaGVja0Rpc3Bvc2VkX3Rocm93KCkgY29uc3QKewogICAgaWYgKCBpbXBsX2lzRGlzcG9zZWRfbm9mYWlsKCkgKQogICAgICAgIHRocm93IERpc3Bvc2VkRXhjZXB0aW9uKCA6OnJ0bDo6T1VTdHJpbmcoKSwgKmNvbnN0X2Nhc3Q8IEZvcm1Db250cm9sbGVyKiA+KCB0aGlzICkgKTsKfQoKLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0Kdm9pZCBGb3JtQ29udHJvbGxlcjo6aW1wbF9vbk1vZGlmeSgpCnsKICAgIE9TTF9FTlNVUkUoICFpbXBsX2lzRGlzcG9zZWRfbm9mYWlsKCksICJGb3JtQ29udHJvbGxlcjogYWxyZWFkeSBkaXNwb3NlZCEiICk7CgogICAgewogICAgICAgIDo6b3NsOjpNdXRleEd1YXJkIGFHdWFyZCggbV9hTXV0ZXggKTsKICAgICAgICBpZiAoICFtX2JNb2RpZmllZCApCiAgICAgICAgICAgIG1fYk1vZGlmaWVkID0gc2FsX1RydWU7CiAgICB9CgoJRXZlbnRPYmplY3QgYUV2dChzdGF0aWNfY2FzdDxjcHB1OjpPV2Vha09iamVjdCo+KHRoaXMpKTsKICAgIG1fYU1vZGlmeUxpc3RlbmVycy5ub3RpZnlFYWNoKCAmWE1vZGlmeUxpc3RlbmVyOjptb2RpZmllZCwgYUV2dCApOwp9CgovLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQp2b2lkIEZvcm1Db250cm9sbGVyOjppbXBsX2FkZEZpbHRlclJvdyggY29uc3QgRm1GaWx0ZXJSb3cmIF9yb3cgKQp7CiAgICBtX2FGaWx0ZXJSb3dzLnB1c2hfYmFjayggX3JvdyApOwoKICAgIGlmICggbV9hRmlsdGVyUm93cy5zaXplKCkgPT0gMSApCiAgICB7ICAgLy8gdGhhdCdzIHRoZSBmaXJzdCByb3cgZXZlcgogICAgICAgIE9TTF9FTlNVUkUoIG1fbkN1cnJlbnRGaWx0ZXJQb3NpdGlvbiA9PSAtMSwgIkZvcm1Db250cm9sbGVyOjppbXBsX2FkZEZpbHRlclJvdzogaW5jb25zaXN0ZW5jeSEiICk7CiAgICAgICAgbV9uQ3VycmVudEZpbHRlclBvc2l0aW9uID0gMDsKICAgIH0KfQoKLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0Kdm9pZCBGb3JtQ29udHJvbGxlcjo6aW1wbF9hcHBlbmRFbXB0eUZpbHRlclJvdyggOjpvc2w6OkNsZWFyYWJsZU11dGV4R3VhcmQmIF9yQ2xlYXJCZWZvcmVOb3RpZnkgKQp7CiAgICAvLyBTWU5DSFJPTklaRUQgLS0+CiAgICBpbXBsX2FkZEZpbHRlclJvdyggRm1GaWx0ZXJSb3coKSApOwoKICAgIC8vIG5vdGlmeSB0aGUgbGlzdGVuZXJzCiAgICBGaWx0ZXJFdmVudCBhRXZlbnQ7CiAgICBhRXZlbnQuU291cmNlID0gKnRoaXM7CiAgICBhRXZlbnQuRGlzanVuY3RpdmVUZXJtID0gKHNhbF9JbnQzMiltX2FGaWx0ZXJSb3dzLnNpemUoKSAtIDE7CiAgICBfckNsZWFyQmVmb3JlTm90aWZ5LmNsZWFyKCk7CiAgICAvLyA8LS0gU1lOQ0hST05JWkVECiAgICBtX2FGaWx0ZXJMaXN0ZW5lcnMubm90aWZ5RWFjaCggJlhGaWx0ZXJDb250cm9sbGVyTGlzdGVuZXI6OmRpc2p1bmN0aXZlVGVybUFkZGVkLCBhRXZlbnQgKTsKfQoKLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0Kc2FsX0Jvb2wgRm9ybUNvbnRyb2xsZXI6OmRldGVybWluZUxvY2tTdGF0ZSgpIGNvbnN0CnsKICAgIE9TTF9FTlNVUkUoICFpbXBsX2lzRGlzcG9zZWRfbm9mYWlsKCksICJGb3JtQ29udHJvbGxlcjogYWxyZWFkeSBkaXNwb3NlZCEiICk7CiAgICAvLyBhLikgaW4gZmlsdGVyIG1vZGUgd2UgYXJlIGFsd2F5cyBsb2NrZWQKICAgIC8vIGIuKSBpZiB3ZSBoYXZlIG5vIHZhbGlkIG1vZGVsIG9yIG91ciBtb2RlbCAoYSByZXN1bHQgc2V0KSBpcyBub3QgYWxpdmUgLT4gd2UncmUgbG9ja2VkCiAgICAvLyBjLikgaWYgd2UgYXJlIGluc2VydGluZyBldmVyeXRoaW5nIGlzIE9LIGFuZCB3ZSBhcmUgbm90IGxvY2tlZAogICAgLy8gZC4pIGlmIGFyZSBub3QgdXBkYXRhYmxlIG9yIG9uIGludmFsaWQgcG9zaXRpb24KICAgIFJlZmVyZW5jZTwgWFJlc3VsdFNldCA+ICB4UmVzdWx0U2V0KG1feE1vZGVsQXNJbmRleCwgVU5PX1FVRVJZKTsKICAgIGlmIChtX2JGaWx0ZXJpbmcgfHwgIXhSZXN1bHRTZXQuaXMoKSB8fCAhaXNSb3dTZXRBbGl2ZSh4UmVzdWx0U2V0KSkKICAgICAgICByZXR1cm4gc2FsX1RydWU7CiAgICBlbHNlCiAgICAgICAgcmV0dXJuIChtX2JDYW5JbnNlcnQgJiYgbV9iQ3VycmVudFJlY29yZE5ldykgPyBzYWxfRmFsc2UKICAgICAgICA6ICB4UmVzdWx0U2V0LT5pc0JlZm9yZUZpcnN0KCkgfHwgeFJlc3VsdFNldC0+aXNBZnRlckxhc3QoKSB8fCB4UmVzdWx0U2V0LT5yb3dEZWxldGVkKCkgfHwgIW1fYkNhblVwZGF0ZTsKfQoKLy8gIEZvY3VzTGlzdGVuZXIKLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0Kdm9pZCBGb3JtQ29udHJvbGxlcjo6Zm9jdXNHYWluZWQoY29uc3QgRm9jdXNFdmVudCYgZSkgdGhyb3coIFJ1bnRpbWVFeGNlcHRpb24gKQp7CiAgICAvLyBTWU5DSFJPTklaRUQgLS0+CiAgICA6Om9zbDo6Q2xlYXJhYmxlTXV0ZXhHdWFyZCBhR3VhcmQoIG1fYU11dGV4ICk7CiAgICBpbXBsX2NoZWNrRGlzcG9zZWRfdGhyb3coKTsKCiAgICBtX3BDb250cm9sQm9yZGVyTWFuYWdlci0+Zm9jdXNHYWluZWQoIGUuU291cmNlICk7CgogICAgUmVmZXJlbmNlPCBYQ29udHJvbCA+ICB4Q29udHJvbChlLlNvdXJjZSwgVU5PX1FVRVJZKTsKICAgIGlmIChtX2JEQkNvbm5lY3Rpb24pCiAgICB7CiAgICAgICAgLy8gZG8gd2UgbmVlZCB0byBrZWVwIHRoZSBsb2NraW5nIG9mIHRoZSBjb21taXQKICAgICAgICAvLyB3ZSBob2xkIHRoZSBsb2NrIGFzIGxvbmcgYXMgdGhlIGNvbnRyb2wgZGlmZmVycyBmcm9tIHRoZSBjdXJyZW50CiAgICAgICAgLy8gb3RoZXJ3aGlzZSB3ZSBkaXNhYmxlZCB0aGUgbG9jawogICAgICAgIG1fYkNvbW1pdExvY2sgPSBtX2JDb21taXRMb2NrICYmIChYQ29udHJvbCopeENvbnRyb2wuZ2V0KCkgIT0gKFhDb250cm9sKiltX3hDdXJyZW50Q29udHJvbC5nZXQoKTsKICAgICAgICBpZiAobV9iQ29tbWl0TG9jaykKICAgICAgICAgICAgcmV0dXJuOwoKICAgICAgICAvLyB3aGVuIGRvIHdlIGhhdmUgdG8gY29tbWl0IGEgdmFsdWUgdG8gZm9ybSBvciBhIGZpbHRlcgogICAgICAgIC8vIGEuKSBpZiB0aGUgY3VycmVudCB2YWx1ZSBpcyBtb2RpZmllZAogICAgICAgIC8vIGIuKSB0aGVyZSBtdXN0IGJlIGEgY3VycmVudCBjb250cm9sCiAgICAgICAgLy8gYy4pIGFuZCBpdCBtdXN0IGJlIGRpZmZlcmVudCBmcm9tIHRoZSBuZXcgZm9jdXMgb3duaW5nIGNvbnRyb2wgb3IKICAgICAgICAvLyBkLikgdGhlIGZvY3VzIGlzIG1vdmluZyBhcm91bmQgKHNvIHdlIGhhdmUgb25seSBvbmUgY29udHJvbCkKCiAgICAgICAgaWYgICggICAoIG1fYk1vZGlmaWVkIHx8IG1fYkZpbHRlcmluZyApCiAgICAgICAgICAgICYmICBtX3hDdXJyZW50Q29udHJvbC5pcygpCiAgICAgICAgICAgICYmICAoICAgKCB4Q29udHJvbC5nZXQoKSAhPSBtX3hDdXJyZW50Q29udHJvbC5nZXQoKSApCiAgICAgICAgICAgICAgICB8fCAgKCAgICggZS5Gb2N1c0ZsYWdzICYgRm9jdXNDaGFuZ2VSZWFzb246OkFST1VORCApCiAgICAgICAgICAgICAgICAgICAgJiYgICggbV9iQ3ljbGUgfHwgbV9iRmlsdGVyaW5nICkKICAgICAgICAgICAgICAgICAgICApCiAgICAgICAgICAgICAgICApCiAgICAgICAgICAgICkKICAgICAgICB7CiAgICAgICAgICAgIC8vIGNoZWNrIHRoZSBvbGQgY29udHJvbCBpZiB0aGUgY29udGVudCBpcyBvawojaWYgKE9TTF9ERUJVR19MRVZFTCA+IDEpIHx8IGRlZmluZWQgREJHX1VUSUwKCQkJUmVmZXJlbmNlPCBYQm91bmRDb250cm9sID4gIHhMb2NraW5nVGVzdChtX3hDdXJyZW50Q29udHJvbCwgVU5PX1FVRVJZKTsKCQkJc2FsX0Jvb2wgYkNvbnRyb2xJc0xvY2tlZCA9IHhMb2NraW5nVGVzdC5pcygpICYmIHhMb2NraW5nVGVzdC0+Z2V0TG9jaygpOwoJCQlPU0xfRU5TVVJFKCFiQ29udHJvbElzTG9ja2VkLCAiRm9ybUNvbnRyb2xsZXI6OkdhaW5lZDogSSdtIG1vZGlmaWVkIGFuZCB0aGUgY3VycmVudCBjb250cm9sIGlzIGxvY2tlZCA/IEhvdyB0aGlzID8iKTsKCQkJLy8gbm9ybWFsZXJ3ZWlzZSBzb2xsdGUgZWluIGdlbG9ja3RlcyBDb250cm9sIG5pY2h0IG1vZGlmaWVkIHNlaW4sIGFsc28gbXVzcyB3b2hsIG1laW4gYk1vZGlmaWVkIGF1cyBlaW5lbSBhbmRlcmVuIEtvbnRleHQKCQkJLy8gZ2VzZXR6dCB3b3JkZW4gc2Vpbiwgd2FzIGljaCBuaWNodCB2ZXJzdGVoZW4gd3VlcmRlIC4uLgojZW5kaWYKCQkJREJHX0FTU0VSVChtX3hDdXJyZW50Q29udHJvbC5pcygpLCAia2VpbiBDdXJyZW50Q29udHJvbCBnZXNldHp0Iik7CgkJCS8vIHp1bmFlY2hzdCBkYXMgQ29udHJvbCBmcmFnZW4gb2IgZXMgZGFzIElGYWNlIHVudGVyc3R1ZXR6dAoJCQlSZWZlcmVuY2U8IFhCb3VuZENvbXBvbmVudCA+ICB4Qm91bmQobV94Q3VycmVudENvbnRyb2wsIFVOT19RVUVSWSk7CgkJCWlmICgheEJvdW5kLmlzKCkgJiYgbV94Q3VycmVudENvbnRyb2wuaXMoKSkKCQkJCXhCb3VuZCAgPSBSZWZlcmVuY2U8IFhCb3VuZENvbXBvbmVudCA+IChtX3hDdXJyZW50Q29udHJvbC0+Z2V0TW9kZWwoKSwgVU5PX1FVRVJZKTsKCgkJCS8vIGxvY2sgaWYgd2UgbG9zZSB0aGUgZm9jdXMgZHVyaW5nIGNvbW1pdAoJCQltX2JDb21taXRMb2NrID0gc2FsX1RydWU7CgoJCQkvLyBDb21taXQgbmljaHQgZXJmb2xncmVpY2gsIEZvY3VzIHp1cnVlY2tzZXR6ZW4KCQkJaWYgKHhCb3VuZC5pcygpICYmICF4Qm91bmQtPmNvbW1pdCgpKQoJCQl7CgkJCQkvLyB0aGUgY29tbWl0IGZhaWxlZCBhbmQgd2UgZG9uJ3QgY29tbWl0IGFnYWluIHVudGlsIHRoZSBjdXJyZW50IGNvbnRyb2wKCQkJCS8vIHdoaWNoIGNvdWxkbid0IGJlIGNvbW1pdCBnYWlucyB0aGUgZm9jdXMgYWdhaW4KCQkJCVJlZmVyZW5jZTwgWFdpbmRvdyA+ICB4V2luZG93KG1feEN1cnJlbnRDb250cm9sLCBVTk9fUVVFUlkpOwoJCQkJaWYgKHhXaW5kb3cuaXMoKSkKCQkJCQl4V2luZG93LT5zZXRGb2N1cygpOwoJCQkJcmV0dXJuOwoJCQl9CgkJCWVsc2UKCQkJewoJCQkJbV9iTW9kaWZpZWQgPSBzYWxfRmFsc2U7CgkJCQltX2JDb21taXRMb2NrID0gc2FsX0ZhbHNlOwoJCQl9CgkJfQoKCQlpZiAoIW1fYkZpbHRlcmluZyAmJiBtX2JDeWNsZSAmJiAoZS5Gb2N1c0ZsYWdzICYgRm9jdXNDaGFuZ2VSZWFzb246OkFST1VORCkgJiYgbV94Q3VycmVudENvbnRyb2wuaXMoKSkKCQl7CiAgICAgICAgICAgIFNRTEVycm9yRXZlbnQgYUVycm9yRXZlbnQ7CiAgICAgICAgICAgIE9TTF9FTlNVUkUoIG1feEZvcm1PcGVyYXRpb25zLmlzKCksICJGb3JtQ29udHJvbGxlcjo6Zm9jdXNHYWluZWQ6IGhtbT8iICk7CiAgICAgICAgICAgICAgICAvLyBzaG91bGQgaGF2ZSBiZWVuIGNyZWF0ZWQgaW4gc2V0TW9kZWwKICAgICAgICAgICAgdHJ5CiAgICAgICAgICAgIHsKCQkJICAgIGlmICggZS5Gb2N1c0ZsYWdzICYgRm9jdXNDaGFuZ2VSZWFzb246OkZPUldBUkQgKQoJCSAgICAgICAgewogICAgICAgICAgICAgICAgICAgIGlmICggbV94Rm9ybU9wZXJhdGlvbnMuaXMoKSAmJiBtX3hGb3JtT3BlcmF0aW9ucy0+aXNFbmFibGVkKCBGb3JtRmVhdHVyZTo6TW92ZVRvTmV4dCApICkKICAgICAgICAgICAgICAgICAgICAgICAgbV94Rm9ybU9wZXJhdGlvbnMtPmV4ZWN1dGUoIEZvcm1GZWF0dXJlOjpNb3ZlVG9OZXh0ICk7CiAgICAgICAgICAgICAgICB9CgkJCSAgICBlbHNlIC8vIGJhY2t3YXJkCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgaWYgKCBtX3hGb3JtT3BlcmF0aW9ucy5pcygpICYmIG1feEZvcm1PcGVyYXRpb25zLT5pc0VuYWJsZWQoIEZvcm1GZWF0dXJlOjpNb3ZlVG9QcmV2aW91cyApICkKICAgICAgICAgICAgICAgICAgICAgICAgbV94Rm9ybU9wZXJhdGlvbnMtPmV4ZWN1dGUoIEZvcm1GZWF0dXJlOjpNb3ZlVG9QcmV2aW91cyApOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIGNhdGNoICggY29uc3QgRXhjZXB0aW9uJiApCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIC8vIGRvbid0IGhhbmRsZSB0aGlzIGFueSBmdXJ0aGVyLiBUaGF0J3MgYW4gLi4uIGFkbWlzc2libGUgZXJyb3IuCiAgICAgICAgICAgICAgICBEQkdfVU5IQU5ETEVEX0VYQ0VQVElPTigpOwogICAgICAgICAgICB9CgkJfQoJfQoKCS8vIEltbWVyIG5vY2ggZWluIHVuZCBkYXNzZWxiZSBDb250cm9sCglpZgkoCSggbV94QWN0aXZlQ29udHJvbCA9PSB4Q29udHJvbCApCgkJJiYJKCB4Q29udHJvbCA9PSBtX3hDdXJyZW50Q29udHJvbCApCgkJKQoJewoJCURCR19BU1NFUlQobV94Q3VycmVudENvbnRyb2wuaXMoKSwgIktlaW4gQ3VycmVudENvbnRyb2wgc2VsZWt0aWVydCIpOwoJCXJldHVybjsKCX0KCglzYWxfQm9vbCBiQWN0aXZhdGVkID0gIW1feEFjdGl2ZUNvbnRyb2wuaXMoKSAmJiB4Q29udHJvbC5pcygpOwoKCW1feEFjdGl2ZUNvbnRyb2wgID0geENvbnRyb2w7CgogICAgaW1wbFNldEN1cnJlbnRDb250cm9sKCB4Q29udHJvbCApOwoJT1NMX1BPU1RDT05EKCBtX3hDdXJyZW50Q29udHJvbC5pcygpLCAiaW1wbFNldEN1cnJlbnRDb250cm9sIGRpZCBub25zZW5zZSEiICk7CgoJaWYgKCBiQWN0aXZhdGVkICkKICAgIHsKICAgICAgICAvLyAoYXN5bmNocm9ub3VzbHkpIGNhbGwgYWN0aXZhdGlvbiBoYW5kbGVycwogICAgICAgIG1fYUFjdGl2YXRpb25FdmVudC5DYWxsKCk7CgogICAgICAgIC8vIGNhbGwgbW9kaWZ5IGxpc3RlbmVycwogICAgICAgIGlmICggbV9iTW9kaWZpZWQgKQogICAgICAgICAgICBtX2FNb2RpZnlMaXN0ZW5lcnMubm90aWZ5RWFjaCggJlhNb2RpZnlMaXN0ZW5lcjo6bW9kaWZpZWQsIEV2ZW50T2JqZWN0KCAqdGhpcyApICk7CiAgICB9CgogICAgLy8gaW52YWxpZGF0ZSBhbGwgZmVhdHVyZXMgd2hpY2ggZGVwZW5kIG9uIHRoZSBjdXJyZW50bHkgZm9jdXNlZCBjb250cm9sCglpZiAoIG1fYkRCQ29ubmVjdGlvbiAmJiAhbV9iRmlsdGVyaW5nICkKICAgICAgICBpbXBsSW52YWxpZGF0ZUN1cnJlbnRDb250cm9sRGVwZW5kZW50RmVhdHVyZXMoKTsKCglpZiAoICFtX3hDdXJyZW50Q29udHJvbC5pcygpICkKICAgICAgICByZXR1cm47CgoJLy8gQ29udHJvbCBlcmhhZWx0IEZvY3VzLCBkYW5uIGV2ZW50dWVsbCBpbiBkZW4gc2ljaHRiYXJlbiBCZXJlaWNoCiAgICBSZWZlcmVuY2U8IFhGb3JtQ29udHJvbGxlckNvbnRleHQgPiB4Q29udGV4dCggbV94Q29udGV4dCApOwogICAgUmVmZXJlbmNlPCBYQ29udHJvbCA+IHhDdXJyZW50Q29udHJvbCggbV94Q3VycmVudENvbnRyb2wgKTsKICAgIGFHdWFyZC5jbGVhcigpOwogICAgLy8gPC0tIFNZTkNIUk9OSVpFRAoKICAgIGlmICggeENvbnRleHQuaXMoKSApCiAgICAgICAgeENvbnRleHQtPm1ha2VWaXNpYmxlKCB4Q3VycmVudENvbnRyb2wgKTsKfQoKLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KSU1QTF9MSU5LKCBGb3JtQ29udHJvbGxlciwgT25BY3RpdmF0ZWQsIHZvaWQqLCAvKiovICkKewogICAgRXZlbnRPYmplY3QgYUV2ZW50OwogICAgYUV2ZW50LlNvdXJjZSA9ICp0aGlzOwogICAgbV9hQWN0aXZhdGVMaXN0ZW5lcnMubm90aWZ5RWFjaCggJlhGb3JtQ29udHJvbGxlckxpc3RlbmVyOjpmb3JtQWN0aXZhdGVkLCBhRXZlbnQgKTsKCiAgICByZXR1cm4gMEw7Cn0KCi8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCklNUExfTElOSyggRm9ybUNvbnRyb2xsZXIsIE9uRGVhY3RpdmF0ZWQsIHZvaWQqLCAvKiovICkKewogICAgRXZlbnRPYmplY3QgYUV2ZW50OwogICAgYUV2ZW50LlNvdXJjZSA9ICp0aGlzOwogICAgbV9hQWN0aXZhdGVMaXN0ZW5lcnMubm90aWZ5RWFjaCggJlhGb3JtQ29udHJvbGxlckxpc3RlbmVyOjpmb3JtRGVhY3RpdmF0ZWQsIGFFdmVudCApOwoKICAgIHJldHVybiAwTDsKfQoKLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0Kdm9pZCBGb3JtQ29udHJvbGxlcjo6Zm9jdXNMb3N0KGNvbnN0IEZvY3VzRXZlbnQmIGUpIHRocm93KCBSdW50aW1lRXhjZXB0aW9uICkKewogICAgT1NMX0VOU1VSRSggIWltcGxfaXNEaXNwb3NlZF9ub2ZhaWwoKSwgIkZvcm1Db250cm9sbGVyOiBhbHJlYWR5IGRpc3Bvc2VkISIgKTsKCiAgICBtX3BDb250cm9sQm9yZGVyTWFuYWdlci0+Zm9jdXNMb3N0KCBlLlNvdXJjZSApOwoKICAgIFJlZmVyZW5jZTwgWENvbnRyb2wgPiAgeENvbnRyb2woZS5Tb3VyY2UsIFVOT19RVUVSWSk7CiAgICBSZWZlcmVuY2U8IFhXaW5kb3dQZWVyID4gIHhOZXh0KGUuTmV4dEZvY3VzLCBVTk9fUVVFUlkpOwogICAgUmVmZXJlbmNlPCBYQ29udHJvbCA+ICB4TmV4dENvbnRyb2wgPSBpc0luTGlzdCh4TmV4dCk7CiAgICBpZiAoIXhOZXh0Q29udHJvbC5pcygpKQogICAgewogICAgICAgIG1feEFjdGl2ZUNvbnRyb2wgPSBOVUxMOwogICAgICAgIG1fYURlYWN0aXZhdGlvbkV2ZW50LkNhbGwoKTsKICAgIH0KfQoKLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQp2b2lkIFNBTF9DQUxMIEZvcm1Db250cm9sbGVyOjptb3VzZVByZXNzZWQoIGNvbnN0IGF3dDo6TW91c2VFdmVudCYgLypfckV2ZW50Ki8gKSB0aHJvdyAoUnVudGltZUV4Y2VwdGlvbikKewogICAgLy8gbm90IGludGVyZXN0ZWQgaW4KfQoKLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQp2b2lkIFNBTF9DQUxMIEZvcm1Db250cm9sbGVyOjptb3VzZVJlbGVhc2VkKCBjb25zdCBhd3Q6Ok1vdXNlRXZlbnQmIC8qX3JFdmVudCovICkgdGhyb3cgKFJ1bnRpbWVFeGNlcHRpb24pCnsKICAgIC8vIG5vdCBpbnRlcmVzdGVkIGluCn0KCi8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0Kdm9pZCBTQUxfQ0FMTCBGb3JtQ29udHJvbGxlcjo6bW91c2VFbnRlcmVkKCBjb25zdCBhd3Q6Ok1vdXNlRXZlbnQmIF9yRXZlbnQgKSB0aHJvdyAoUnVudGltZUV4Y2VwdGlvbikKewogICAgbV9wQ29udHJvbEJvcmRlck1hbmFnZXItPm1vdXNlRW50ZXJlZCggX3JFdmVudC5Tb3VyY2UgKTsKfQoKLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQp2b2lkIFNBTF9DQUxMIEZvcm1Db250cm9sbGVyOjptb3VzZUV4aXRlZCggY29uc3QgYXd0OjpNb3VzZUV2ZW50JiBfckV2ZW50ICkgdGhyb3cgKFJ1bnRpbWVFeGNlcHRpb24pCnsKICAgIG1fcENvbnRyb2xCb3JkZXJNYW5hZ2VyLT5tb3VzZUV4aXRlZCggX3JFdmVudC5Tb3VyY2UgKTsKfQoKLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQp2b2lkIFNBTF9DQUxMIEZvcm1Db250cm9sbGVyOjpjb21wb25lbnRWYWxpZGl0eUNoYW5nZWQoIGNvbnN0IEV2ZW50T2JqZWN0JiBfclNvdXJjZSApIHRocm93IChSdW50aW1lRXhjZXB0aW9uKQp7CiAgICBSZWZlcmVuY2U8IFhDb250cm9sID4geENvbnRyb2woIGZpbmRDb250cm9sKCBtX2FDb250cm9scywgUmVmZXJlbmNlPCBYQ29udHJvbE1vZGVsID4oIF9yU291cmNlLlNvdXJjZSwgVU5PX1FVRVJZICksIHNhbF9GYWxzZSwgc2FsX0ZhbHNlICkgKTsKICAgIFJlZmVyZW5jZTwgWFZhbGlkYXRhYmxlRm9ybUNvbXBvbmVudCA+IHhWYWxpZGF0YWJsZSggX3JTb3VyY2UuU291cmNlLCBVTk9fUVVFUlkgKTsKCiAgICBPU0xfRU5TVVJFKCB4Q29udHJvbC5pcygpICYmIHhWYWxpZGF0YWJsZS5pcygpLCAiRm9ybUNvbnRyb2xsZXI6OmNvbXBvbmVudFZhbGlkaXR5Q2hhbmdlZDogaHVoPyIgKTsKCiAgICBpZiAoIHhDb250cm9sLmlzKCkgJiYgeFZhbGlkYXRhYmxlLmlzKCkgKQogICAgICAgIG1fcENvbnRyb2xCb3JkZXJNYW5hZ2VyLT52YWxpZGl0eUNoYW5nZWQoIHhDb250cm9sLCB4VmFsaWRhdGFibGUgKTsKfQoKLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQp2b2lkIEZvcm1Db250cm9sbGVyOjpzZXRNb2RlbChjb25zdCBSZWZlcmVuY2U8IFhUYWJDb250cm9sbGVyTW9kZWwgPiAmIE1vZGVsKSB0aHJvdyggUnVudGltZUV4Y2VwdGlvbiApCnsKICAgIDo6b3NsOjpNdXRleEd1YXJkIGFHdWFyZCggbV9hTXV0ZXggKTsKICAgIGltcGxfY2hlY2tEaXNwb3NlZF90aHJvdygpOwoKICAgIERCR19BU1NFUlQobV94VGFiQ29udHJvbGxlci5pcygpLCAiRm9ybUNvbnRyb2xsZXI6OnNldE1vZGVsIDogaW52YWxpZCBhZ2dyZWdhdGUgISIpOwoKICAgIHRyeQogICAgewogICAgICAgIC8vIGRpc2Nvbm5lY3QgZnJvbSB0aGUgb2xkIG1vZGVsCiAgICAgICAgaWYgKG1feE1vZGVsQXNJbmRleC5pcygpKQogICAgICAgIHsKICAgICAgICAgICAgaWYgKG1fYkRCQ29ubmVjdGlvbikKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgLy8gd2UgYXJlIGN1cnJlbnRseSB3b3JraW5nIG9uIHRoZSBtb2RlbAogICAgICAgICAgICAgICAgRXZlbnRPYmplY3QgYUV2dChtX3hNb2RlbEFzSW5kZXgpOwogICAgICAgICAgICAgICAgdW5sb2FkZWQoYUV2dCk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIFJlZmVyZW5jZTwgWExvYWRhYmxlID4gIHhGb3JtKG1feE1vZGVsQXNJbmRleCwgVU5PX1FVRVJZKTsKICAgICAgICAgICAgaWYgKHhGb3JtLmlzKCkpCiAgICAgICAgICAgICAgICB4Rm9ybS0+cmVtb3ZlTG9hZExpc3RlbmVyKHRoaXMpOwoKICAgICAgICAgICAgUmVmZXJlbmNlPCBYU1FMRXJyb3JCcm9hZGNhc3RlciA+ICB4QnJvYWRjYXN0ZXIobV94TW9kZWxBc0luZGV4LCBVTk9fUVVFUlkpOwogICAgICAgICAgICBpZiAoeEJyb2FkY2FzdGVyLmlzKCkpCiAgICAgICAgICAgICAgICB4QnJvYWRjYXN0ZXItPnJlbW92ZVNRTEVycm9yTGlzdGVuZXIodGhpcyk7CgogICAgICAgICAgICBSZWZlcmVuY2U8IFhEYXRhYmFzZVBhcmFtZXRlckJyb2FkY2FzdGVyID4gIHhQYXJhbUJyb2FkY2FzdGVyKG1feE1vZGVsQXNJbmRleCwgVU5PX1FVRVJZKTsKICAgICAgICAgICAgaWYgKHhQYXJhbUJyb2FkY2FzdGVyLmlzKCkpCiAgICAgICAgICAgICAgICB4UGFyYW1Ccm9hZGNhc3Rlci0+cmVtb3ZlUGFyYW1ldGVyTGlzdGVuZXIodGhpcyk7CgogICAgICAgIH0KCiAgICAgICAgZGlzcG9zZUFsbEZlYXR1cmVzQW5kRGlzcGF0Y2hlcnMoKTsKCiAgICAgICAgaWYgKCBtX3hGb3JtT3BlcmF0aW9ucy5pcygpICkKICAgICAgICAgICAgbV94Rm9ybU9wZXJhdGlvbnMtPmRpc3Bvc2UoKTsKICAgICAgICBtX3hGb3JtT3BlcmF0aW9ucy5jbGVhcigpOwoKICAgICAgICAvLyBzZXQgdGhlIG5ldyBtb2RlbCB3YWl0IGZvciB0aGUgbG9hZCBldmVudAogICAgICAgIGlmIChtX3hUYWJDb250cm9sbGVyLmlzKCkpCiAgICAgICAgICAgIG1feFRhYkNvbnRyb2xsZXItPnNldE1vZGVsKE1vZGVsKTsKICAgICAgICBtX3hNb2RlbEFzSW5kZXggPSBSZWZlcmVuY2U8IFhJbmRleEFjY2VzcyA+IChNb2RlbCwgVU5PX1FVRVJZKTsKICAgICAgICBtX3hNb2RlbEFzTWFuYWdlciA9IFJlZmVyZW5jZTwgWEV2ZW50QXR0YWNoZXJNYW5hZ2VyID4gKE1vZGVsLCBVTk9fUVVFUlkpOwoKICAgICAgICAvLyBvbmx5IGlmIGJvdGggaWZhY2VzIGV4aXQsIHRoZSBjb250cm9sbGVyIHdpbGwgd29yayBzdWNjZXNzZnVsCiAgICAgICAgaWYgKCFtX3hNb2RlbEFzSW5kZXguaXMoKSB8fCAhbV94TW9kZWxBc01hbmFnZXIuaXMoKSkKICAgICAgICB7CiAgICAgICAgICAgIG1feE1vZGVsQXNNYW5hZ2VyID0gTlVMTDsKICAgICAgICAgICAgbV94TW9kZWxBc0luZGV4ID0gTlVMTDsKICAgICAgICB9CgogICAgICAgIGlmIChtX3hNb2RlbEFzSW5kZXguaXMoKSkKICAgICAgICB7CiAgICAgICAgICAgIC8vIHJlLWNyZWF0ZSBtX3hGb3JtT3BlcmF0aW9ucwogICAgICAgICAgICBtX3hGb3JtT3BlcmF0aW9ucy5zZXQoIEZvcm1PcGVyYXRpb25zOjpjcmVhdGVXaXRoRm9ybUNvbnRyb2xsZXIoIG1fYUNvbnRleHQuZ2V0VU5PQ29udGV4dCgpLCB0aGlzICksIFVOT19TRVRfVEhST1cgKTsKICAgICAgICAgICAgbV94Rm9ybU9wZXJhdGlvbnMtPnNldEZlYXR1cmVJbnZhbGlkYXRpb24oIHRoaXMgKTsKCiAgICAgICAgICAgIC8vIGFkZGluZyBsb2FkIGFuZCB1aSBpbnRlcmFjdGlvbiBsaXN0ZW5lcnMKICAgICAgICAgICAgUmVmZXJlbmNlPCBYTG9hZGFibGUgPiAgeEZvcm0oTW9kZWwsIFVOT19RVUVSWSk7CiAgICAgICAgICAgIGlmICh4Rm9ybS5pcygpKQogICAgICAgICAgICAgICAgeEZvcm0tPmFkZExvYWRMaXN0ZW5lcih0aGlzKTsKCiAgICAgICAgICAgIFJlZmVyZW5jZTwgWFNRTEVycm9yQnJvYWRjYXN0ZXIgPiAgeEJyb2FkY2FzdGVyKE1vZGVsLCBVTk9fUVVFUlkpOwogICAgICAgICAgICBpZiAoeEJyb2FkY2FzdGVyLmlzKCkpCiAgICAgICAgICAgICAgICB4QnJvYWRjYXN0ZXItPmFkZFNRTEVycm9yTGlzdGVuZXIodGhpcyk7CgogICAgICAgICAgICBSZWZlcmVuY2U8IFhEYXRhYmFzZVBhcmFtZXRlckJyb2FkY2FzdGVyID4gIHhQYXJhbUJyb2FkY2FzdGVyKE1vZGVsLCBVTk9fUVVFUlkpOwogICAgICAgICAgICBpZiAoeFBhcmFtQnJvYWRjYXN0ZXIuaXMoKSkKICAgICAgICAgICAgICAgIHhQYXJhbUJyb2FkY2FzdGVyLT5hZGRQYXJhbWV0ZXJMaXN0ZW5lcih0aGlzKTsKCiAgICAgICAgICAgIC8vIHdlbGwsIGlzIHRoZSBkYXRhYmFzZSBhbHJlYWR5IGxvYWRlZD8KICAgICAgICAgICAgLy8gdGhlbiB3ZSBoYXZlIHRvIHNpbXVsYXRlIGEgbG9hZCBldmVudAogICAgICAgICAgICBSZWZlcmVuY2U8IFhMb2FkYWJsZSA+ICB4Q3Vyc29yKG1feE1vZGVsQXNJbmRleCwgVU5PX1FVRVJZKTsKICAgICAgICAgICAgaWYgKHhDdXJzb3IuaXMoKSAmJiB4Q3Vyc29yLT5pc0xvYWRlZCgpKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBFdmVudE9iamVjdCBhRXZ0KHhDdXJzb3IpOwogICAgICAgICAgICAgICAgbG9hZGVkKGFFdnQpOwogICAgICAgICAgICB9CgogICAgICAgICAgICBSZWZlcmVuY2U8IFhQcm9wZXJ0eVNldCA+IHhNb2RlbFByb3BzKCBtX3hNb2RlbEFzSW5kZXgsIFVOT19RVUVSWSApOwogICAgICAgICAgICBSZWZlcmVuY2U8IFhQcm9wZXJ0eVNldEluZm8gPiB4UHJvcEluZm8oIHhNb2RlbFByb3BzLT5nZXRQcm9wZXJ0eVNldEluZm8oKSApOwogICAgICAgICAgICBpZiAoICB4UHJvcEluZm8uaXMoKQogICAgICAgICAgICAgICAmJiB4UHJvcEluZm8tPmhhc1Byb3BlcnR5QnlOYW1lKCBGTV9QUk9QX0RZTkFNSUNfQ09OVFJPTF9CT1JERVIgKQogICAgICAgICAgICAgICAmJiB4UHJvcEluZm8tPmhhc1Byb3BlcnR5QnlOYW1lKCBGTV9QUk9QX0NPTlRST0xfQk9SREVSX0NPTE9SX0ZPQ1VTICkKICAgICAgICAgICAgICAgJiYgeFByb3BJbmZvLT5oYXNQcm9wZXJ0eUJ5TmFtZSggRk1fUFJPUF9DT05UUk9MX0JPUkRFUl9DT0xPUl9NT1VTRSApCiAgICAgICAgICAgICAgICYmIHhQcm9wSW5mby0+aGFzUHJvcGVydHlCeU5hbWUoIEZNX1BST1BfQ09OVFJPTF9CT1JERVJfQ09MT1JfSU5WQUxJRCApCiAgICAgICAgICAgICAgICkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgYm9vbCBiRW5hYmxlRHluYW1pY0NvbnRyb2xCb3JkZXIgPSBsY2xfc2hvdWxkVXNlRHluYW1pY0NvbnRyb2xCb3JkZXIoCiAgICAgICAgICAgICAgICAgICAgeE1vZGVsUHJvcHMuZ2V0KCksIHhNb2RlbFByb3BzLT5nZXRQcm9wZXJ0eVZhbHVlKCBGTV9QUk9QX0RZTkFNSUNfQ09OVFJPTF9CT1JERVIgKSApOwogICAgICAgICAgICAgICAgaWYgKCBiRW5hYmxlRHluYW1pY0NvbnRyb2xCb3JkZXIgKQogICAgICAgICAgICAgICAgICAgIG1fcENvbnRyb2xCb3JkZXJNYW5hZ2VyLT5lbmFibGVEeW5hbWljQm9yZGVyQ29sb3IoKTsKICAgICAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgICAgICBtX3BDb250cm9sQm9yZGVyTWFuYWdlci0+ZGlzYWJsZUR5bmFtaWNCb3JkZXJDb2xvcigpOwoKICAgICAgICAgICAgICAgIHNhbF9JbnQzMiBuQ29sb3IgPSAwOwogICAgICAgICAgICAgICAgaWYgKCB4TW9kZWxQcm9wcy0+Z2V0UHJvcGVydHlWYWx1ZSggRk1fUFJPUF9DT05UUk9MX0JPUkRFUl9DT0xPUl9GT0NVUyApID4+PSBuQ29sb3IgKQogICAgICAgICAgICAgICAgICAgIG1fcENvbnRyb2xCb3JkZXJNYW5hZ2VyLT5zZXRTdGF0dXNDb2xvciggQ09OVFJPTF9TVEFUVVNfRk9DVVNFRCwgbkNvbG9yICk7CiAgICAgICAgICAgICAgICBpZiAoIHhNb2RlbFByb3BzLT5nZXRQcm9wZXJ0eVZhbHVlKCBGTV9QUk9QX0NPTlRST0xfQk9SREVSX0NPTE9SX01PVVNFICkgPj49IG5Db2xvciApCiAgICAgICAgICAgICAgICAgICAgbV9wQ29udHJvbEJvcmRlck1hbmFnZXItPnNldFN0YXR1c0NvbG9yKCBDT05UUk9MX1NUQVRVU19NT1VTRV9IT1ZFUiwgbkNvbG9yICk7CiAgICAgICAgICAgICAgICBpZiAoIHhNb2RlbFByb3BzLT5nZXRQcm9wZXJ0eVZhbHVlKCBGTV9QUk9QX0NPTlRST0xfQk9SREVSX0NPTE9SX0lOVkFMSUQgKSA+Pj0gbkNvbG9yICkKICAgICAgICAgICAgICAgICAgICBtX3BDb250cm9sQm9yZGVyTWFuYWdlci0+c2V0U3RhdHVzQ29sb3IoIENPTlRST0xfU1RBVFVTX0lOVkFMSUQsIG5Db2xvciApOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfQogICAgY2F0Y2goIGNvbnN0IEV4Y2VwdGlvbiYgKQogICAgewogICAgICAgIERCR19VTkhBTkRMRURfRVhDRVBUSU9OKCk7CiAgICB9Cn0KCi8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tClJlZmVyZW5jZTwgWFRhYkNvbnRyb2xsZXJNb2RlbCA+ICBGb3JtQ29udHJvbGxlcjo6Z2V0TW9kZWwoKSB0aHJvdyggUnVudGltZUV4Y2VwdGlvbiApCnsKICAgIDo6b3NsOjpNdXRleEd1YXJkIGFHdWFyZCggbV9hTXV0ZXggKTsKICAgIGltcGxfY2hlY2tEaXNwb3NlZF90aHJvdygpOwoKICAgIERCR19BU1NFUlQobV94VGFiQ29udHJvbGxlci5pcygpLCAiRm9ybUNvbnRyb2xsZXI6OmdldE1vZGVsIDogaW52YWxpZCBhZ2dyZWdhdGUgISIpOwogICAgaWYgKCFtX3hUYWJDb250cm9sbGVyLmlzKCkpCiAgICAgICAgcmV0dXJuIFJlZmVyZW5jZTwgWFRhYkNvbnRyb2xsZXJNb2RlbCA+ICgpOwogICAgcmV0dXJuIG1feFRhYkNvbnRyb2xsZXItPmdldE1vZGVsKCk7Cn0KCi8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCnZvaWQgRm9ybUNvbnRyb2xsZXI6OmFkZFRvRXZlbnRBdHRhY2hlcihjb25zdCBSZWZlcmVuY2U8IFhDb250cm9sID4gJiB4Q29udHJvbCkKewogICAgT1NMX0VOU1VSRSggIWltcGxfaXNEaXNwb3NlZF9ub2ZhaWwoKSwgIkZvcm1Db250cm9sbGVyOiBhbHJlYWR5IGRpc3Bvc2VkISIgKTsKICAgIE9TTF9FTlNVUkUoIHhDb250cm9sLmlzKCksICJGb3JtQ29udHJvbGxlcjo6YWRkVG9FdmVudEF0dGFjaGVyOiBpbnZhbGlkIGNvbnRyb2wgLSBob3cgZGlkIHlvdSByZWFjaCB0aGlzPyIgKTsKICAgIGlmICggIXhDb250cm9sLmlzKCkgKQogICAgICAgIHJldHVybjsgLyogdGhyb3cgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7ICovCgogICAgLy8gYW5tZWxkZW4gYmVpbSBFdmVudGF0dGFjaGVyCiAgICBSZWZlcmVuY2U8IFhGb3JtQ29tcG9uZW50ID4gIHhDb21wKHhDb250cm9sLT5nZXRNb2RlbCgpLCBVTk9fUVVFUlkpOwogICAgaWYgKHhDb21wLmlzKCkgJiYgbV94TW9kZWxBc0luZGV4LmlzKCkpCiAgICB7CiAgICAgICAgLy8gVW5kIGRpZSBQb3NpdGlvbiBkZXMgQ29udHJvbE1vZGVsIGRhcmluIHN1Y2hlbgogICAgICAgIHNhbF91SW50MzIgblBvcyA9IG1feE1vZGVsQXNJbmRleC0+Z2V0Q291bnQoKTsKICAgICAgICBSZWZlcmVuY2U8IFhGb3JtQ29tcG9uZW50ID4geFRlbXA7CiAgICAgICAgZm9yKCA7IG5Qb3M7ICkKICAgICAgICB7CiAgICAgICAgICAgIG1feE1vZGVsQXNJbmRleC0+Z2V0QnlJbmRleCgtLW5Qb3MpID4+PSB4VGVtcDsKICAgICAgICAgICAgaWYgKChYRm9ybUNvbXBvbmVudCopeENvbXAuZ2V0KCkgPT0gKFhGb3JtQ29tcG9uZW50Kil4VGVtcC5nZXQoKSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgUmVmZXJlbmNlPCBYSW50ZXJmYWNlID4gIHhJZmMoeENvbnRyb2wsIFVOT19RVUVSWSk7CiAgICAgICAgICAgICAgICBtX3hNb2RlbEFzTWFuYWdlci0+YXR0YWNoKCBuUG9zLCB4SWZjLCBtYWtlQW55KHhDb250cm9sKSApOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9Cn0KCi8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCnZvaWQgRm9ybUNvbnRyb2xsZXI6OnJlbW92ZUZyb21FdmVudEF0dGFjaGVyKGNvbnN0IFJlZmVyZW5jZTwgWENvbnRyb2wgPiAmIHhDb250cm9sKQp7CiAgICBPU0xfRU5TVVJFKCAhaW1wbF9pc0Rpc3Bvc2VkX25vZmFpbCgpLCAiRm9ybUNvbnRyb2xsZXI6IGFscmVhZHkgZGlzcG9zZWQhIiApOwogICAgT1NMX0VOU1VSRSggeENvbnRyb2wuaXMoKSwgIkZvcm1Db250cm9sbGVyOjpyZW1vdmVGcm9tRXZlbnRBdHRhY2hlcjogaW52YWxpZCBjb250cm9sIC0gaG93IGRpZCB5b3UgcmVhY2ggdGhpcz8iICk7CiAgICBpZiAoICF4Q29udHJvbC5pcygpICkKICAgICAgICByZXR1cm47IC8qIHRocm93IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOyAqLwoKICAgIC8vIGFibWVsZGVuIGJlaW0gRXZlbnRhdHRhY2hlcgogICAgUmVmZXJlbmNlPCBYRm9ybUNvbXBvbmVudCA+ICB4Q29tcCh4Q29udHJvbC0+Z2V0TW9kZWwoKSwgVU5PX1FVRVJZKTsKICAgIGlmICggeENvbXAuaXMoKSAmJiBtX3hNb2RlbEFzSW5kZXguaXMoKSApCiAgICB7CiAgICAgICAgLy8gVW5kIGRpZSBQb3NpdGlvbiBkZXMgQ29udHJvbE1vZGVsIGRhcmluIHN1Y2hlbgogICAgICAgIHNhbF91SW50MzIgblBvcyA9IG1feE1vZGVsQXNJbmRleC0+Z2V0Q291bnQoKTsKICAgICAgICBSZWZlcmVuY2U8IFhGb3JtQ29tcG9uZW50ID4geFRlbXA7CiAgICAgICAgZm9yKCA7IG5Qb3M7ICkKICAgICAgICB7CiAgICAgICAgICAgIG1feE1vZGVsQXNJbmRleC0+Z2V0QnlJbmRleCgtLW5Qb3MpID4+PSB4VGVtcDsKICAgICAgICAgICAgaWYgKChYRm9ybUNvbXBvbmVudCopeENvbXAuZ2V0KCkgPT0gKFhGb3JtQ29tcG9uZW50Kil4VGVtcC5nZXQoKSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgUmVmZXJlbmNlPCBYSW50ZXJmYWNlID4gIHhJZmMoeENvbnRyb2wsIFVOT19RVUVSWSk7CiAgICAgICAgICAgICAgICBtX3hNb2RlbEFzTWFuYWdlci0+ZGV0YWNoKCBuUG9zLCB4SWZjICk7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0KfQoKLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0Kdm9pZCBGb3JtQ29udHJvbGxlcjo6c2V0Q29udGFpbmVyKGNvbnN0IFJlZmVyZW5jZTwgWENvbnRyb2xDb250YWluZXIgPiAmIHhDb250YWluZXIpIHRocm93KCBSdW50aW1lRXhjZXB0aW9uICkKewogICAgT1NMX0VOU1VSRSggIWltcGxfaXNEaXNwb3NlZF9ub2ZhaWwoKSwgIkZvcm1Db250cm9sbGVyOiBhbHJlYWR5IGRpc3Bvc2VkISIgKTsKICAgIFJlZmVyZW5jZTwgWFRhYkNvbnRyb2xsZXJNb2RlbCA+ICB4VGFiTW9kZWwoZ2V0TW9kZWwoKSk7CiAgICBEQkdfQVNTRVJUKHhUYWJNb2RlbC5pcygpIHx8ICF4Q29udGFpbmVyLmlzKCksICJObyBNb2RlbCBkZWZpbmVkIik7CiAgICAgICAgLy8gaWYgd2UgaGF2ZSBhIG5ldyBjb250YWluZXIgd2UgbmVlZCBhIG1vZGVsCiAgICBEQkdfQVNTRVJUKG1feFRhYkNvbnRyb2xsZXIuaXMoKSwgIkZvcm1Db250cm9sbGVyOjpzZXRDb250YWluZXIgOiBpbnZhbGlkIGFnZ3JlZ2F0ZSAhIik7CgogICAgOjpvc2w6Ok11dGV4R3VhcmQgYUd1YXJkKCBtX2FNdXRleCApOwogICAgUmVmZXJlbmNlPCBYQ29udGFpbmVyID4gIHhDdXJyZW50Q29udGFpbmVyOwogICAgaWYgKG1feFRhYkNvbnRyb2xsZXIuaXMoKSkKICAgICAgICB4Q3VycmVudENvbnRhaW5lciA9IFJlZmVyZW5jZTwgWENvbnRhaW5lciA+IChtX3hUYWJDb250cm9sbGVyLT5nZXRDb250YWluZXIoKSwgVU5PX1FVRVJZKTsKICAgIGlmICh4Q3VycmVudENvbnRhaW5lci5pcygpKQogICAgewogICAgICAgIHhDdXJyZW50Q29udGFpbmVyLT5yZW1vdmVDb250YWluZXJMaXN0ZW5lcih0aGlzKTsKCiAgICAgICAgaWYgKCBtX2FUYWJBY3RpdmF0aW9uVGltZXIuSXNBY3RpdmUoKSApCiAgICAgICAgICAgIG1fYVRhYkFjdGl2YXRpb25UaW1lci5TdG9wKCk7CgogICAgICAgIC8vIGNsZWFyIHRoZSBmaWx0ZXIgbWFwCiAgICAgICAgOjpzdGQ6OmZvcl9lYWNoKCBtX2FGaWx0ZXJDb21wb25lbnRzLmJlZ2luKCksIG1fYUZpbHRlckNvbXBvbmVudHMuZW5kKCksIFJlbW92ZUNvbXBvbmVudFRleHRMaXN0ZW5lciggdGhpcyApICk7CiAgICAgICAgbV9hRmlsdGVyQ29tcG9uZW50cy5jbGVhcigpOwoKICAgICAgICAvLyBlaW5zYW1tZWxuIGRlciBDb250cm9scwogICAgICAgIGNvbnN0IFJlZmVyZW5jZTwgWENvbnRyb2wgPiogcENvbnRyb2xzID0gbV9hQ29udHJvbHMuZ2V0Q29uc3RBcnJheSgpOwogICAgICAgIGNvbnN0IFJlZmVyZW5jZTwgWENvbnRyb2wgPiogcENvbnRyb2xzRW5kID0gcENvbnRyb2xzICsgbV9hQ29udHJvbHMuZ2V0TGVuZ3RoKCk7CiAgICAgICAgd2hpbGUgKCBwQ29udHJvbHMgIT0gcENvbnRyb2xzRW5kICkKICAgICAgICAgICAgaW1wbENvbnRyb2xSZW1vdmVkKCAqcENvbnRyb2xzKyssIHRydWUgKTsKCiAgICAgICAgLy8gRGF0ZW5iYW5rIHNwZXppZmlzY2hlIERpbmdlIHZvcm5laG1lbgogICAgICAgIGlmIChtX2JEQkNvbm5lY3Rpb24gJiYgaXNMaXN0ZW5pbmdGb3JDaGFuZ2VzKCkpCiAgICAgICAgICAgIHN0b3BMaXN0ZW5pbmcoKTsKCiAgICAgICAgbV9hQ29udHJvbHMucmVhbGxvYyggMCApOwogICAgfQoKICAgIGlmIChtX3hUYWJDb250cm9sbGVyLmlzKCkpCiAgICAgICAgbV94VGFiQ29udHJvbGxlci0+c2V0Q29udGFpbmVyKHhDb250YWluZXIpOwoKICAgIC8vIFdlbGNoZSBDb250cm9scyBnZWhvZXJlbiB6dW0gQ29udGFpbmVyID8KICAgIGlmICh4Q29udGFpbmVyLmlzKCkgJiYgeFRhYk1vZGVsLmlzKCkpCiAgICB7CiAgICAgICAgU2VxdWVuY2U8IFJlZmVyZW5jZTwgWENvbnRyb2xNb2RlbCA+ID4gYU1vZGVscyA9IHhUYWJNb2RlbC0+Z2V0Q29udHJvbE1vZGVscygpOwogICAgICAgIGNvbnN0IFJlZmVyZW5jZTwgWENvbnRyb2xNb2RlbCA+ICogcE1vZGVscyA9IGFNb2RlbHMuZ2V0Q29uc3RBcnJheSgpOwogICAgICAgIFNlcXVlbmNlPCBSZWZlcmVuY2U8IFhDb250cm9sID4gPiBhQWxsQ29udHJvbHMgPSB4Q29udGFpbmVyLT5nZXRDb250cm9scygpOwoKICAgICAgICBzYWxfSW50MzIgbkNvdW50ID0gYU1vZGVscy5nZXRMZW5ndGgoKTsKICAgICAgICBtX2FDb250cm9scyA9IFNlcXVlbmNlPCBSZWZlcmVuY2U8IFhDb250cm9sID4gPiggbkNvdW50ICk7CiAgICAgICAgUmVmZXJlbmNlPCBYQ29udHJvbCA+ICogcENvbnRyb2xzID0gbV9hQ29udHJvbHMuZ2V0QXJyYXkoKTsKCiAgICAgICAgLy8gZWluc2FtbWVsbiBkZXIgQ29udHJvbHMKICAgICAgICBzYWxfSW50MzIgaSwgajsKICAgICAgICBmb3IgKGkgPSAwLCBqID0gMDsgaSA8IG5Db3VudDsgKytpLCArK3BNb2RlbHMgKQogICAgICAgIHsKICAgICAgICAgICAgUmVmZXJlbmNlPCBYQ29udHJvbCA+IHhDb250cm9sID0gZmluZENvbnRyb2woIGFBbGxDb250cm9scywgKnBNb2RlbHMsIHNhbF9GYWxzZSwgc2FsX1RydWUgKTsKICAgICAgICAgICAgaWYgKCB4Q29udHJvbC5pcygpICkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgcENvbnRyb2xzW2orK10gPSB4Q29udHJvbDsKICAgICAgICAgICAgICAgIGltcGxDb250cm9sSW5zZXJ0ZWQoIHhDb250cm9sLCB0cnVlICk7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIC8vIG5vdCBldmVyeSBtb2RlbCBoYWQgYW4gYXNzb2NpYXRlZCBjb250cm9sCiAgICAgICAgaWYgKGogIT0gaSkKICAgICAgICAgICAgbV9hQ29udHJvbHMucmVhbGxvYyhqKTsKCiAgICAgICAgLy8gYW0gQ29udGFpbmVyIGhvcmNoZW4KICAgICAgICBSZWZlcmVuY2U8IFhDb250YWluZXIgPiAgeE5ld0NvbnRhaW5lcih4Q29udGFpbmVyLCBVTk9fUVVFUlkpOwogICAgICAgIGlmICh4TmV3Q29udGFpbmVyLmlzKCkpCiAgICAgICAgICAgIHhOZXdDb250YWluZXItPmFkZENvbnRhaW5lckxpc3RlbmVyKHRoaXMpOwoKICAgICAgICAvLyBEYXRlbmJhbmsgc3BlemlmaXNjaGUgRGluZ2Ugdm9ybmVobWVuCiAgICAgICAgaWYgKG1fYkRCQ29ubmVjdGlvbikKICAgICAgICB7CiAgICAgICAgICAgIG1fYkxvY2tlZCA9IGRldGVybWluZUxvY2tTdGF0ZSgpOwogICAgICAgICAgICBzZXRMb2NrcygpOwogICAgICAgICAgICBpZiAoIWlzTG9ja2VkKCkpCiAgICAgICAgICAgICAgICBzdGFydExpc3RlbmluZygpOwogICAgICAgIH0KICAgIH0KICAgIC8vIGJlZmluZGVuIHNpY2ggZGllIENvbnRyb2xzIGluIGRlciByaWNodGlnZW4gUmVpaGVuZm9sZ2UKICAgIG1fYkNvbnRyb2xzU29ydGVkID0gc2FsX1RydWU7Cn0KCi8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tClJlZmVyZW5jZTwgWENvbnRyb2xDb250YWluZXIgPiAgRm9ybUNvbnRyb2xsZXI6OmdldENvbnRhaW5lcigpIHRocm93KCBSdW50aW1lRXhjZXB0aW9uICkKewoJOjpvc2w6Ok11dGV4R3VhcmQgYUd1YXJkKCBtX2FNdXRleCApOwogICAgaW1wbF9jaGVja0Rpc3Bvc2VkX3Rocm93KCk7CgogICAgREJHX0FTU0VSVChtX3hUYWJDb250cm9sbGVyLmlzKCksICJGb3JtQ29udHJvbGxlcjo6Z2V0Q29udGFpbmVyIDogaW52YWxpZCBhZ2dyZWdhdGUgISIpOwogICAgaWYgKCFtX3hUYWJDb250cm9sbGVyLmlzKCkpCiAgICAgICAgcmV0dXJuIFJlZmVyZW5jZTwgWENvbnRyb2xDb250YWluZXIgPiAoKTsKICAgIHJldHVybiBtX3hUYWJDb250cm9sbGVyLT5nZXRDb250YWluZXIoKTsKfQoKLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KU2VxdWVuY2U8IFJlZmVyZW5jZTwgWENvbnRyb2wgPiA+IEZvcm1Db250cm9sbGVyOjpnZXRDb250cm9scyh2b2lkKSB0aHJvdyggUnVudGltZUV4Y2VwdGlvbiApCnsKICAgIDo6b3NsOjpNdXRleEd1YXJkIGFHdWFyZCggbV9hTXV0ZXggKTsKICAgIGltcGxfY2hlY2tEaXNwb3NlZF90aHJvdygpOwoKICAgIGlmICghbV9iQ29udHJvbHNTb3J0ZWQpCiAgICB7CiAgICAgICAgUmVmZXJlbmNlPCBYVGFiQ29udHJvbGxlck1vZGVsID4gIHhNb2RlbCA9IGdldE1vZGVsKCk7CiAgICAgICAgaWYgKCF4TW9kZWwuaXMoKSkKICAgICAgICAgICAgcmV0dXJuIG1fYUNvbnRyb2xzOwoKICAgICAgICBTZXF1ZW5jZTwgUmVmZXJlbmNlPCBYQ29udHJvbE1vZGVsID4gPiBhQ29udHJvbE1vZGVscyA9IHhNb2RlbC0+Z2V0Q29udHJvbE1vZGVscygpOwogICAgICAgIGNvbnN0IFJlZmVyZW5jZTwgWENvbnRyb2xNb2RlbCA+ICogcE1vZGVscyA9IGFDb250cm9sTW9kZWxzLmdldENvbnN0QXJyYXkoKTsKICAgICAgICBzYWxfSW50MzIgbk1vZGVscyA9IGFDb250cm9sTW9kZWxzLmdldExlbmd0aCgpOwoKICAgICAgICBTZXF1ZW5jZTwgUmVmZXJlbmNlPCBYQ29udHJvbCA+ID4gYU5ld0NvbnRyb2xzKG5Nb2RlbHMpOwoKICAgICAgICBSZWZlcmVuY2U8IFhDb250cm9sID4gKiBwQ29udHJvbHMgPSBhTmV3Q29udHJvbHMuZ2V0QXJyYXkoKTsKICAgICAgICBSZWZlcmVuY2U8IFhDb250cm9sID4gIHhDb250cm9sOwoKICAgICAgICAvLyBVbXNvcnRpZXJlbiBkZXIgQ29udHJvbHMgZW50c3ByZWNoZW5kIGRlciBUYWJSZWloZW5mb2xnZQoJICAgIHNhbF9JbnQzMiBqID0gMDsKICAgICAgICBmb3IgKHNhbF9JbnQzMiBpID0gMDsgaSA8IG5Nb2RlbHM7ICsraSwgKytwTW9kZWxzICkKICAgICAgICB7CiAgICAgICAgICAgIHhDb250cm9sID0gZmluZENvbnRyb2woIG1fYUNvbnRyb2xzLCAqcE1vZGVscywgc2FsX1RydWUsIHNhbF9UcnVlICk7CiAgICAgICAgICAgIGlmICggeENvbnRyb2wuaXMoKSApCiAgICAgICAgICAgICAgICBwQ29udHJvbHNbaisrXSA9IHhDb250cm9sOwogICAgICAgIH0KCiAgICAgICAgLy8gbm90IGV2ZXJ5IG1vZGVsIGhhZCBhbiBhc3NvY2lhdGVkIGNvbnRyb2wKICAgICAgICBpZiAoIGogIT0gbk1vZGVscyApCiAgICAgICAgICAgIGFOZXdDb250cm9scy5yZWFsbG9jKCBqICk7CgogICAgICAgIG1fYUNvbnRyb2xzID0gYU5ld0NvbnRyb2xzOwogICAgICAgIG1fYkNvbnRyb2xzU29ydGVkID0gc2FsX1RydWU7CiAgICB9CiAgICByZXR1cm4gbV9hQ29udHJvbHM7Cn0KCi8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCnZvaWQgRm9ybUNvbnRyb2xsZXI6OmF1dG9UYWJPcmRlcigpIHRocm93KCBSdW50aW1lRXhjZXB0aW9uICkKewogICAgOjpvc2w6Ok11dGV4R3VhcmQgYUd1YXJkKCBtX2FNdXRleCApOwogICAgaW1wbF9jaGVja0Rpc3Bvc2VkX3Rocm93KCk7CgogICAgREJHX0FTU0VSVChtX3hUYWJDb250cm9sbGVyLmlzKCksICJGb3JtQ29udHJvbGxlcjo6YXV0b1RhYk9yZGVyIDogaW52YWxpZCBhZ2dyZWdhdGUgISIpOwogICAgaWYgKG1feFRhYkNvbnRyb2xsZXIuaXMoKSkKICAgICAgICBtX3hUYWJDb250cm9sbGVyLT5hdXRvVGFiT3JkZXIoKTsKfQoKLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0Kdm9pZCBGb3JtQ29udHJvbGxlcjo6YWN0aXZhdGVUYWJPcmRlcigpIHRocm93KCBSdW50aW1lRXhjZXB0aW9uICkKewogICAgOjpvc2w6Ok11dGV4R3VhcmQgYUd1YXJkKCBtX2FNdXRleCApOwogICAgaW1wbF9jaGVja0Rpc3Bvc2VkX3Rocm93KCk7CgogICAgREJHX0FTU0VSVChtX3hUYWJDb250cm9sbGVyLmlzKCksICJGb3JtQ29udHJvbGxlcjo6YWN0aXZhdGVUYWJPcmRlciA6IGludmFsaWQgYWdncmVnYXRlICEiKTsKICAgIGlmIChtX3hUYWJDb250cm9sbGVyLmlzKCkpCiAgICAgICAgbV94VGFiQ29udHJvbGxlci0+YWN0aXZhdGVUYWJPcmRlcigpOwp9CgovLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQp2b2lkIEZvcm1Db250cm9sbGVyOjpzZXRDb250cm9sTG9jayhjb25zdCBSZWZlcmVuY2U8IFhDb250cm9sID4gJiB4Q29udHJvbCkKewogICAgT1NMX0VOU1VSRSggIWltcGxfaXNEaXNwb3NlZF9ub2ZhaWwoKSwgIkZvcm1Db250cm9sbGVyOiBhbHJlYWR5IGRpc3Bvc2VkISIgKTsKICAgIHNhbF9Cb29sIGJMb2NrZWQgPSBpc0xvY2tlZCgpOwoKICAgIC8vIGVzIHdpcmQgZ2Vsb2NrdAogICAgLy8gYS4pIHdlbm4gZGVyIGdhbnplIERhdGVuc2F0eiBnZXNwZXJydCBpc3QKICAgIC8vIGIuKSB3ZW5uIGRhcyB6dWdlaG9lcmlnZSBGZWxkIGdlc3BlZXJ0IGlzdAogICAgUmVmZXJlbmNlPCBYQm91bmRDb250cm9sID4gIHhCb3VuZCh4Q29udHJvbCwgVU5PX1FVRVJZKTsKICAgIGlmICh4Qm91bmQuaXMoKSAmJiAoKCAoYkxvY2tlZCAmJiBiTG9ja2VkICE9IHhCb3VuZC0+Z2V0TG9jaygpKSB8fAogICAgICAgICAgICAgICAgICAgICAgICAgIWJMb2NrZWQpKSkgICAgLy8gYmVpbSBlbnRsb2NrZW4gaW1tZXIgZWluemVsbmUgRmVsZGVyIHVlYmVycHL8ZmVuCiAgICB7CiAgICAgICAgLy8gZ2lidCBlcyBlaW5lIERhdGVucXVlbGxlCiAgICAgICAgUmVmZXJlbmNlPCBYUHJvcGVydHlTZXQgPiAgeFNldCh4Q29udHJvbC0+Z2V0TW9kZWwoKSwgVU5PX1FVRVJZKTsKICAgICAgICBpZiAoeFNldC5pcygpICYmIDo6Y29tcGhlbHBlcjo6aGFzUHJvcGVydHkoRk1fUFJPUF9CT1VOREZJRUxELCB4U2V0KSkKICAgICAgICB7CiAgICAgICAgICAgIC8vIHdpZSBzaWVodCBtaXQgZGVuIFByb3BlcnRpZXMgUmVhZE9ubHkgdW5kIEVuYWJsZSBhdXMKICAgICAgICAgICAgc2FsX0Jvb2wgYlRvdWNoID0gc2FsX1RydWU7CiAgICAgICAgICAgIGlmICg6OmNvbXBoZWxwZXI6Omhhc1Byb3BlcnR5KEZNX1BST1BfRU5BQkxFRCwgeFNldCkpCiAgICAgICAgICAgICAgICBiVG91Y2ggPSA6OmNvbXBoZWxwZXI6OmdldEJPT0woeFNldC0+Z2V0UHJvcGVydHlWYWx1ZShGTV9QUk9QX0VOQUJMRUQpKTsKICAgICAgICAgICAgaWYgKDo6Y29tcGhlbHBlcjo6aGFzUHJvcGVydHkoRk1fUFJPUF9SRUFET05MWSwgeFNldCkpCiAgICAgICAgICAgICAgICBiVG91Y2ggPSAhOjpjb21waGVscGVyOjpnZXRCT09MKHhTZXQtPmdldFByb3BlcnR5VmFsdWUoRk1fUFJPUF9SRUFET05MWSkpOwoKICAgICAgICAgICAgaWYgKGJUb3VjaCkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgUmVmZXJlbmNlPCBYUHJvcGVydHlTZXQgPiAgeEZpZWxkOwogICAgICAgICAgICAgICAgeFNldC0+Z2V0UHJvcGVydHlWYWx1ZShGTV9QUk9QX0JPVU5ERklFTEQpID4+PSB4RmllbGQ7CiAgICAgICAgICAgICAgICBpZiAoeEZpZWxkLmlzKCkpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgaWYgKGJMb2NrZWQpCiAgICAgICAgICAgICAgICAgICAgICAgIHhCb3VuZC0+c2V0TG9jayhiTG9ja2VkKTsKICAgICAgICAgICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICB0cnkKICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgQW55IGFWYWwgPSB4RmllbGQtPmdldFByb3BlcnR5VmFsdWUoRk1fUFJPUF9JU1JFQURPTkxZKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChhVmFsLmhhc1ZhbHVlKCkgJiYgOjpjb21waGVscGVyOjpnZXRCT09MKGFWYWwpKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHhCb3VuZC0+c2V0TG9jayhzYWxfVHJ1ZSk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeEJvdW5kLT5zZXRMb2NrKGJMb2NrZWQpOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIGNhdGNoKCBjb25zdCBFeGNlcHRpb24mICkKICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgREJHX1VOSEFORExFRF9FWENFUFRJT04oKTsKICAgICAgICAgICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9Cn0KCi8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCnZvaWQgRm9ybUNvbnRyb2xsZXI6OnNldExvY2tzKCkKewogICAgT1NMX0VOU1VSRSggIWltcGxfaXNEaXNwb3NlZF9ub2ZhaWwoKSwgIkZvcm1Db250cm9sbGVyOiBhbHJlYWR5IGRpc3Bvc2VkISIgKTsKICAgIC8vIGFsbGUgQ29udHJvbHMsIGRpZSBtaXQgZWluZXIgRGF0ZW5xdWVsbGUgdmVyYnVuZGVuIHNpbmQgbG9ja2VuL3VubG9ja2VuCiAgICBjb25zdCBSZWZlcmVuY2U8IFhDb250cm9sID4qIHBDb250cm9scyA9IG1fYUNvbnRyb2xzLmdldENvbnN0QXJyYXkoKTsKICAgIGNvbnN0IFJlZmVyZW5jZTwgWENvbnRyb2wgPiogcENvbnRyb2xzRW5kID0gcENvbnRyb2xzICsgbV9hQ29udHJvbHMuZ2V0TGVuZ3RoKCk7CiAgICB3aGlsZSAoIHBDb250cm9scyAhPSBwQ29udHJvbHNFbmQgKQogICAgICAgIHNldENvbnRyb2xMb2NrKCAqcENvbnRyb2xzKysgKTsKfQoKLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KbmFtZXNwYWNlCnsKICAgIGJvb2wgbGNsX3Nob3VsZExpc3RlbkZvck1vZGlmaWNhdGlvbnMoIGNvbnN0IFJlZmVyZW5jZTwgWENvbnRyb2wgPiYgX3J4Q29udHJvbCwgY29uc3QgUmVmZXJlbmNlPCBYUHJvcGVydHlDaGFuZ2VMaXN0ZW5lciA+JiBfcnhCb3VuZEZpZWxkTGlzdGVuZXIgKQogICAgewogICAgICAgIGJvb2wgYlNob3VsZCA9IGZhbHNlOwoKICAgICAgICBSZWZlcmVuY2U8IFhCb3VuZENvbXBvbmVudCA+IHhCb3VuZCggX3J4Q29udHJvbCwgVU5PX1FVRVJZICk7CiAgICAgICAgaWYgKCB4Qm91bmQuaXMoKSApCiAgICAgICAgewogICAgICAgICAgICBiU2hvdWxkID0gdHJ1ZTsKICAgICAgICB9CiAgICAgICAgZWxzZSBpZiAoIF9yeENvbnRyb2wuaXMoKSApCiAgICAgICAgewogICAgICAgICAgICBSZWZlcmVuY2U8IFhQcm9wZXJ0eVNldCA+IHhNb2RlbFByb3BzKCBfcnhDb250cm9sLT5nZXRNb2RlbCgpLCBVTk9fUVVFUlkgKTsKICAgICAgICAgICAgaWYgKCB4TW9kZWxQcm9wcy5pcygpICYmIDo6Y29tcGhlbHBlcjo6aGFzUHJvcGVydHkoIEZNX1BST1BfQk9VTkRGSUVMRCwgeE1vZGVsUHJvcHMgKSApCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIFJlZmVyZW5jZTwgWFByb3BlcnR5U2V0ID4geEZpZWxkOwogICAgICAgICAgICAgICAgeE1vZGVsUHJvcHMtPmdldFByb3BlcnR5VmFsdWUoIEZNX1BST1BfQk9VTkRGSUVMRCApID4+PSB4RmllbGQ7CiAgICAgICAgICAgICAgICBiU2hvdWxkID0geEZpZWxkLmlzKCk7CgogICAgICAgICAgICAgICAgaWYgKCAhYlNob3VsZCAmJiBfcnhCb3VuZEZpZWxkTGlzdGVuZXIuaXMoKSApCgkJCQkgICAgeE1vZGVsUHJvcHMtPmFkZFByb3BlcnR5Q2hhbmdlTGlzdGVuZXIoIEZNX1BST1BfQk9VTkRGSUVMRCwgX3J4Qm91bmRGaWVsZExpc3RlbmVyICk7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIHJldHVybiBiU2hvdWxkOwogICAgfQp9CgovLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQp2b2lkIEZvcm1Db250cm9sbGVyOjpzdGFydENvbnRyb2xNb2RpZnlMaXN0ZW5pbmcoY29uc3QgUmVmZXJlbmNlPCBYQ29udHJvbCA+ICYgeENvbnRyb2wpCnsKICAgIE9TTF9FTlNVUkUoICFpbXBsX2lzRGlzcG9zZWRfbm9mYWlsKCksICJGb3JtQ29udHJvbGxlcjogYWxyZWFkeSBkaXNwb3NlZCEiICk7CgogICAgYm9vbCBiTW9kaWZ5TGlzdGVuaW5nID0gbGNsX3Nob3VsZExpc3RlbkZvck1vZGlmaWNhdGlvbnMoIHhDb250cm9sLCB0aGlzICk7CgogICAgLy8gYXJ0aWZpY2lhbCB3aGlsZQogICAgd2hpbGUgKCBiTW9kaWZ5TGlzdGVuaW5nICkKICAgIHsKICAgICAgICBSZWZlcmVuY2U8IFhNb2RpZnlCcm9hZGNhc3RlciA+ICB4TW9kKHhDb250cm9sLCBVTk9fUVVFUlkpOwogICAgICAgIGlmICh4TW9kLmlzKCkpCiAgICAgICAgewogICAgICAgICAgICB4TW9kLT5hZGRNb2RpZnlMaXN0ZW5lcih0aGlzKTsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgfQoKICAgICAgICAvLyBhbGxlIGRpZSBUZXh0IHVtIHZvcnplaXRpZyBlaW4gbW9kaWZpZWQgenUgZXJrZW5uZW4KICAgICAgICBSZWZlcmVuY2U8IFhUZXh0Q29tcG9uZW50ID4gIHhUZXh0KHhDb250cm9sLCBVTk9fUVVFUlkpOwogICAgICAgIGlmICh4VGV4dC5pcygpKQogICAgICAgIHsKICAgICAgICAgICAgeFRleHQtPmFkZFRleHRMaXN0ZW5lcih0aGlzKTsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgfQoKICAgICAgICBSZWZlcmVuY2U8IFhDaGVja0JveCA+ICB4Qm94KHhDb250cm9sLCBVTk9fUVVFUlkpOwogICAgICAgIGlmICh4Qm94LmlzKCkpCiAgICAgICAgewogICAgICAgICAgICB4Qm94LT5hZGRJdGVtTGlzdGVuZXIodGhpcyk7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIH0KCiAgICAgICAgUmVmZXJlbmNlPCBYQ29tYm9Cb3ggPiAgeENiQm94KHhDb250cm9sLCBVTk9fUVVFUlkpOwogICAgICAgIGlmICh4Q2JCb3guaXMoKSkKICAgICAgICB7CiAgICAgICAgICAgIHhDYkJveC0+YWRkSXRlbUxpc3RlbmVyKHRoaXMpOwogICAgICAgICAgICBicmVhazsKICAgICAgICB9CgogICAgICAgIFJlZmVyZW5jZTwgWExpc3RCb3ggPiAgeExpc3RCb3goeENvbnRyb2wsIFVOT19RVUVSWSk7CiAgICAgICAgaWYgKHhMaXN0Qm94LmlzKCkpCiAgICAgICAgewogICAgICAgICAgICB4TGlzdEJveC0+YWRkSXRlbUxpc3RlbmVyKHRoaXMpOwogICAgICAgICAgICBicmVhazsKICAgICAgICB9CiAgICAgICAgYnJlYWs7CiAgICB9Cn0KCi8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCnZvaWQgRm9ybUNvbnRyb2xsZXI6OnN0b3BDb250cm9sTW9kaWZ5TGlzdGVuaW5nKGNvbnN0IFJlZmVyZW5jZTwgWENvbnRyb2wgPiAmIHhDb250cm9sKQp7CiAgICBPU0xfRU5TVVJFKCAhaW1wbF9pc0Rpc3Bvc2VkX25vZmFpbCgpLCAiRm9ybUNvbnRyb2xsZXI6IGFscmVhZHkgZGlzcG9zZWQhIiApOwoKICAgIGJvb2wgYk1vZGlmeUxpc3RlbmluZyA9IGxjbF9zaG91bGRMaXN0ZW5Gb3JNb2RpZmljYXRpb25zKCB4Q29udHJvbCwgTlVMTCApOwoKICAgIC8vIGt1ZW5zdGxpY2hlcyB3aGlsZQogICAgd2hpbGUgKGJNb2RpZnlMaXN0ZW5pbmcpCiAgICB7CiAgICAgICAgUmVmZXJlbmNlPCBYTW9kaWZ5QnJvYWRjYXN0ZXIgPiAgeE1vZCh4Q29udHJvbCwgVU5PX1FVRVJZKTsKICAgICAgICBpZiAoeE1vZC5pcygpKQogICAgICAgIHsKICAgICAgICAgICAgeE1vZC0+cmVtb3ZlTW9kaWZ5TGlzdGVuZXIodGhpcyk7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIH0KICAgICAgICAvLyBhbGxlIGRpZSBUZXh0IHVtIHZvcnplaXRpZyBlaW4gbW9kaWZpZWQgenUgZXJrZW5uZW4KICAgICAgICBSZWZlcmVuY2U8IFhUZXh0Q29tcG9uZW50ID4gIHhUZXh0KHhDb250cm9sLCBVTk9fUVVFUlkpOwogICAgICAgIGlmICh4VGV4dC5pcygpKQogICAgICAgIHsKICAgICAgICAgICAgeFRleHQtPnJlbW92ZVRleHRMaXN0ZW5lcih0aGlzKTsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgfQoKICAgICAgICBSZWZlcmVuY2U8IFhDaGVja0JveCA+ICB4Qm94KHhDb250cm9sLCBVTk9fUVVFUlkpOwogICAgICAgIGlmICh4Qm94LmlzKCkpCiAgICAgICAgewogICAgICAgICAgICB4Qm94LT5yZW1vdmVJdGVtTGlzdGVuZXIodGhpcyk7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIH0KCiAgICAgICAgUmVmZXJlbmNlPCBYQ29tYm9Cb3ggPiAgeENiQm94KHhDb250cm9sLCBVTk9fUVVFUlkpOwogICAgICAgIGlmICh4Q2JCb3guaXMoKSkKICAgICAgICB7CiAgICAgICAgICAgIHhDYkJveC0+cmVtb3ZlSXRlbUxpc3RlbmVyKHRoaXMpOwogICAgICAgICAgICBicmVhazsKICAgICAgICB9CgogICAgICAgIFJlZmVyZW5jZTwgWExpc3RCb3ggPiAgeExpc3RCb3goeENvbnRyb2wsIFVOT19RVUVSWSk7CiAgICAgICAgaWYgKHhMaXN0Qm94LmlzKCkpCiAgICAgICAgewogICAgICAgICAgICB4TGlzdEJveC0+cmVtb3ZlSXRlbUxpc3RlbmVyKHRoaXMpOwogICAgICAgICAgICBicmVhazsKICAgICAgICB9CiAgICAgICAgYnJlYWs7CiAgICB9Cn0KCi8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCnZvaWQgRm9ybUNvbnRyb2xsZXI6OnN0YXJ0TGlzdGVuaW5nKCkKewogICAgT1NMX0VOU1VSRSggIWltcGxfaXNEaXNwb3NlZF9ub2ZhaWwoKSwgIkZvcm1Db250cm9sbGVyOiBhbHJlYWR5IGRpc3Bvc2VkISIgKTsKICAgIG1fYk1vZGlmaWVkICA9IHNhbF9GYWxzZTsKCiAgICAvLyBqZXR6dCBhbm1lbGRlbiBiZWkgZ2VidW5kZW5lbiBmZWxkZXJuCiAgICBjb25zdCBSZWZlcmVuY2U8IFhDb250cm9sID4qIHBDb250cm9scyA9IG1fYUNvbnRyb2xzLmdldENvbnN0QXJyYXkoKTsKICAgIGNvbnN0IFJlZmVyZW5jZTwgWENvbnRyb2wgPiogcENvbnRyb2xzRW5kID0gcENvbnRyb2xzICsgbV9hQ29udHJvbHMuZ2V0TGVuZ3RoKCk7CiAgICB3aGlsZSAoIHBDb250cm9scyAhPSBwQ29udHJvbHNFbmQgKQogICAgICAgIHN0YXJ0Q29udHJvbE1vZGlmeUxpc3RlbmluZyggKnBDb250cm9scysrICk7Cn0KCi8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCnZvaWQgRm9ybUNvbnRyb2xsZXI6OnN0b3BMaXN0ZW5pbmcoKQp7CiAgICBPU0xfRU5TVVJFKCAhaW1wbF9pc0Rpc3Bvc2VkX25vZmFpbCgpLCAiRm9ybUNvbnRyb2xsZXI6IGFscmVhZHkgZGlzcG9zZWQhIiApOwogICAgbV9iTW9kaWZpZWQgID0gc2FsX0ZhbHNlOwoKICAgIC8vIGpldHp0IGFubWVsZGVuIGJlaSBnZWJ1bmRlbmVuIGZlbGRlcm4KICAgIGNvbnN0IFJlZmVyZW5jZTwgWENvbnRyb2wgPiogcENvbnRyb2xzID0gbV9hQ29udHJvbHMuZ2V0Q29uc3RBcnJheSgpOwogICAgY29uc3QgUmVmZXJlbmNlPCBYQ29udHJvbCA+KiBwQ29udHJvbHNFbmQgPSBwQ29udHJvbHMgKyBtX2FDb250cm9scy5nZXRMZW5ndGgoKTsKICAgIHdoaWxlICggcENvbnRyb2xzICE9IHBDb250cm9sc0VuZCApCiAgICAgICAgc3RvcENvbnRyb2xNb2RpZnlMaXN0ZW5pbmcoICpwQ29udHJvbHMrKyApOwp9CgoKLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KUmVmZXJlbmNlPCBYQ29udHJvbCA+ICBGb3JtQ29udHJvbGxlcjo6ZmluZENvbnRyb2woU2VxdWVuY2U8IFJlZmVyZW5jZTwgWENvbnRyb2wgPiA+JiBfckNvbnRyb2xzLCBjb25zdCBSZWZlcmVuY2U8IFhDb250cm9sTW9kZWwgPiAmIHhDdHJsTW9kZWwgLHNhbF9Cb29sIF9iUmVtb3ZlLHNhbF9Cb29sIF9iT3ZlcldyaXRlKSBjb25zdAp7CiAgICBPU0xfRU5TVVJFKCAhaW1wbF9pc0Rpc3Bvc2VkX25vZmFpbCgpLCAiRm9ybUNvbnRyb2xsZXI6IGFscmVhZHkgZGlzcG9zZWQhIiApOwogICAgREJHX0FTU0VSVCggeEN0cmxNb2RlbC5pcygpLCAiZmluZENvbnRyb2wgLSB3ZWxjaGVzID8hIiApOwoKICAgIFJlZmVyZW5jZTwgWENvbnRyb2wgPiogcENvbnRyb2xzID0gX3JDb250cm9scy5nZXRBcnJheSgpOwogICAgUmVmZXJlbmNlPCBYQ29udHJvbE1vZGVsID4gIHhNb2RlbDsKICAgIGZvciAoIHNhbF9JbnQzMiBpID0gMCwgbkNvdW50ID0gX3JDb250cm9scy5nZXRMZW5ndGgoKTsgaSA8IG5Db3VudDsgKytpLCArK3BDb250cm9scyApCiAgICB7CiAgICAgICAgaWYgKCBwQ29udHJvbHMtPmlzKCkgKQogICAgICAgIHsKICAgICAgICAgICAgeE1vZGVsID0gKCpwQ29udHJvbHMpLT5nZXRNb2RlbCgpOwogICAgICAgICAgICBpZiAoIHhNb2RlbC5nZXQoKSA9PSB4Q3RybE1vZGVsLmdldCgpICkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgUmVmZXJlbmNlPCBYQ29udHJvbCA+IHhDb250cm9sKCAqcENvbnRyb2xzICk7CgkJCQlpZiAoIF9iUmVtb3ZlICkKCQkJCQk6OmNvbXBoZWxwZXI6OnJlbW92ZUVsZW1lbnRBdCggX3JDb250cm9scywgaSApOwoJCQkJZWxzZSBpZiAoIF9iT3ZlcldyaXRlICkKCQkJCQkqcENvbnRyb2xzID0gUmVmZXJlbmNlPCBYQ29udHJvbCA+KCk7CiAgICAgICAgICAgICAgICByZXR1cm4geENvbnRyb2w7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9CiAgICByZXR1cm4gUmVmZXJlbmNlPCBYQ29udHJvbCA+ICgpOwp9CgovLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQp2b2lkIEZvcm1Db250cm9sbGVyOjppbXBsQ29udHJvbEluc2VydGVkKCBjb25zdCBSZWZlcmVuY2U8IFhDb250cm9sPiYgX3J4Q29udHJvbCwgYm9vbCBfYkFkZFRvRXZlbnRBdHRhY2hlciApCnsKICAgIFJlZmVyZW5jZTwgWFdpbmRvdyA+IHhXaW5kb3coIF9yeENvbnRyb2wsIFVOT19RVUVSWSApOwogICAgaWYgKCB4V2luZG93LmlzKCkgKQogICAgewogICAgICAgIHhXaW5kb3ctPmFkZEZvY3VzTGlzdGVuZXIoIHRoaXMgKTsKICAgICAgICB4V2luZG93LT5hZGRNb3VzZUxpc3RlbmVyKCB0aGlzICk7CgogICAgICAgIGlmICggX2JBZGRUb0V2ZW50QXR0YWNoZXIgKQogICAgICAgICAgICBhZGRUb0V2ZW50QXR0YWNoZXIoIF9yeENvbnRyb2wgKTsKICAgIH0KCiAgICAvLyBhZGQgYSBkaXNwYXRjaCBpbnRlcmNlcHRvciB0byB0aGUgY29udHJvbCAoaWYgc3VwcG9ydGVkKQogICAgUmVmZXJlbmNlPCBYRGlzcGF0Y2hQcm92aWRlckludGVyY2VwdGlvbiA+IHhJbnRlcmNlcHRpb24oIF9yeENvbnRyb2wsIFVOT19RVUVSWSApOwogICAgaWYgKCB4SW50ZXJjZXB0aW9uLmlzKCkgKQogICAgICAgIGNyZWF0ZUludGVyY2VwdG9yKCB4SW50ZXJjZXB0aW9uICk7CgogICAgaWYgKCBfcnhDb250cm9sLmlzKCkgKQogICAgewogICAgICAgIFJlZmVyZW5jZTwgWENvbnRyb2xNb2RlbCA+IHhNb2RlbCggX3J4Q29udHJvbC0+Z2V0TW9kZWwoKSApOwoKICAgICAgICAvLyB3ZSB3YW50IHRvIGtub3cgYWJvdXQgdGhlIHJlc2V0IG9mIHRoZSB0aGUgbW9kZWwgb2Ygb3VyIGNvbnRyb2xzCiAgICAgICAgLy8gKGZvciBjb3JyZWN0bHkgcmVzZXR0aW5nIG1fYk1vZGlmaWVkKQogICAgICAgIFJlZmVyZW5jZTwgWFJlc2V0ID4gIHhSZXNldCggeE1vZGVsLCBVTk9fUVVFUlkgKTsKCQlpZiAoIHhSZXNldC5pcygpICkKCQkJeFJlc2V0LT5hZGRSZXNldExpc3RlbmVyKCB0aGlzICk7CgogICAgICAgIC8vIGFuZCB3ZSB3YW50IHRvIGtub3cgYWJvdXQgdGhlIHZhbGlkaXR5LCB0byB2aXN1YWxseSBpbmRpY2F0ZSBpdAogICAgICAgIFJlZmVyZW5jZTwgWFZhbGlkYXRhYmxlRm9ybUNvbXBvbmVudCA+IHhWYWxpZGF0YWJsZSggeE1vZGVsLCBVTk9fUVVFUlkgKTsKICAgICAgICBpZiAoIHhWYWxpZGF0YWJsZS5pcygpICkKICAgICAgICB7CiAgICAgICAgICAgIHhWYWxpZGF0YWJsZS0+YWRkRm9ybUNvbXBvbmVudFZhbGlkaXR5TGlzdGVuZXIoIHRoaXMgKTsKICAgICAgICAgICAgbV9wQ29udHJvbEJvcmRlck1hbmFnZXItPnZhbGlkaXR5Q2hhbmdlZCggX3J4Q29udHJvbCwgeFZhbGlkYXRhYmxlICk7CiAgICAgICAgfQogICAgfQoKfQoKLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0Kdm9pZCBGb3JtQ29udHJvbGxlcjo6aW1wbENvbnRyb2xSZW1vdmVkKCBjb25zdCBSZWZlcmVuY2U8IFhDb250cm9sPiYgX3J4Q29udHJvbCwgYm9vbCBfYlJlbW92ZUZyb21FdmVudEF0dGFjaGVyICkKewoJUmVmZXJlbmNlPCBYV2luZG93ID4geFdpbmRvdyggX3J4Q29udHJvbCwgVU5PX1FVRVJZICk7CglpZiAoIHhXaW5kb3cuaXMoKSApCgl7CiAgICAgICAgeFdpbmRvdy0+cmVtb3ZlRm9jdXNMaXN0ZW5lciggdGhpcyApOwogICAgICAgIHhXaW5kb3ctPnJlbW92ZU1vdXNlTGlzdGVuZXIoIHRoaXMgKTsKCiAgICAgICAgaWYgKCBfYlJlbW92ZUZyb21FdmVudEF0dGFjaGVyICkKCQkJcmVtb3ZlRnJvbUV2ZW50QXR0YWNoZXIoIF9yeENvbnRyb2wgKTsKCX0KCglSZWZlcmVuY2U8IFhEaXNwYXRjaFByb3ZpZGVySW50ZXJjZXB0aW9uID4geEludGVyY2VwdGlvbiggX3J4Q29udHJvbCwgVU5PX1FVRVJZKTsKCWlmICggeEludGVyY2VwdGlvbi5pcygpICkKCQlkZWxldGVJbnRlcmNlcHRvciggeEludGVyY2VwdGlvbiApOwoKCWlmICggX3J4Q29udHJvbC5pcygpICkKCXsKICAgICAgICBSZWZlcmVuY2U8IFhDb250cm9sTW9kZWwgPiB4TW9kZWwoIF9yeENvbnRyb2wtPmdldE1vZGVsKCkgKTsKCiAgICAgICAgUmVmZXJlbmNlPCBYUmVzZXQgPiAgeFJlc2V0KCB4TW9kZWwsIFVOT19RVUVSWSApOwoJCWlmICggeFJlc2V0LmlzKCkgKQoJCQl4UmVzZXQtPnJlbW92ZVJlc2V0TGlzdGVuZXIoIHRoaXMgKTsKCiAgICAgICAgUmVmZXJlbmNlPCBYVmFsaWRhdGFibGVGb3JtQ29tcG9uZW50ID4geFZhbGlkYXRhYmxlKCB4TW9kZWwsIFVOT19RVUVSWSApOwogICAgICAgIGlmICggeFZhbGlkYXRhYmxlLmlzKCkgKQogICAgICAgICAgICB4VmFsaWRhdGFibGUtPnJlbW92ZUZvcm1Db21wb25lbnRWYWxpZGl0eUxpc3RlbmVyKCB0aGlzICk7Cgl9Cn0KCi8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCnZvaWQgRm9ybUNvbnRyb2xsZXI6OmltcGxTZXRDdXJyZW50Q29udHJvbCggY29uc3QgUmVmZXJlbmNlPCBYQ29udHJvbCA+JiBfcnhDb250cm9sICkKewogICAgaWYgKCBtX3hDdXJyZW50Q29udHJvbC5nZXQoKSA9PSBfcnhDb250cm9sLmdldCgpICkKICAgICAgICByZXR1cm47CgogICAgUmVmZXJlbmNlPCBYR3JpZENvbnRyb2wgPiB4R3JpZENvbnRyb2woIG1feEN1cnJlbnRDb250cm9sLCBVTk9fUVVFUlkgKTsKICAgIGlmICggeEdyaWRDb250cm9sLmlzKCkgKQogICAgICAgIHhHcmlkQ29udHJvbC0+cmVtb3ZlR3JpZENvbnRyb2xMaXN0ZW5lciggdGhpcyApOwoKICAgIG1feEN1cnJlbnRDb250cm9sID0gX3J4Q29udHJvbDsKCiAgICB4R3JpZENvbnRyb2wuc2V0KCBtX3hDdXJyZW50Q29udHJvbCwgVU5PX1FVRVJZICk7CiAgICBpZiAoIHhHcmlkQ29udHJvbC5pcygpICkKICAgICAgICB4R3JpZENvbnRyb2wtPmFkZEdyaWRDb250cm9sTGlzdGVuZXIoIHRoaXMgKTsKfQoKLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0Kdm9pZCBGb3JtQ29udHJvbGxlcjo6aW5zZXJ0Q29udHJvbChjb25zdCBSZWZlcmVuY2U8IFhDb250cm9sID4gJiB4Q29udHJvbCkKewogICAgT1NMX0VOU1VSRSggIWltcGxfaXNEaXNwb3NlZF9ub2ZhaWwoKSwgIkZvcm1Db250cm9sbGVyOiBhbHJlYWR5IGRpc3Bvc2VkISIgKTsKICAgIG1fYkNvbnRyb2xzU29ydGVkID0gc2FsX0ZhbHNlOwogICAgbV9hQ29udHJvbHMucmVhbGxvYyhtX2FDb250cm9scy5nZXRMZW5ndGgoKSArIDEpOwogICAgbV9hQ29udHJvbHMuZ2V0QXJyYXkoKVttX2FDb250cm9scy5nZXRMZW5ndGgoKSAtIDFdID0geENvbnRyb2w7CgogICAgaWYgKCBtX3BDb2x1bW5JbmZvQ2FjaGUuZ2V0KCkgKQogICAgICAgIG1fcENvbHVtbkluZm9DYWNoZS0+ZGVpbml0aWFsaXplQ29udHJvbHMoKTsKCiAgICBpbXBsQ29udHJvbEluc2VydGVkKCB4Q29udHJvbCwgbV9iQXR0YWNoRXZlbnRzICk7CgogICAgaWYgKG1fYkRCQ29ubmVjdGlvbiAmJiAhbV9iRmlsdGVyaW5nKQogICAgICAgIHNldENvbnRyb2xMb2NrKHhDb250cm9sKTsKCiAgICBpZiAoaXNMaXN0ZW5pbmdGb3JDaGFuZ2VzKCkgJiYgbV9iQXR0YWNoRXZlbnRzKQogICAgICAgIHN0YXJ0Q29udHJvbE1vZGlmeUxpc3RlbmluZyggeENvbnRyb2wgKTsKfQoKLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0Kdm9pZCBGb3JtQ29udHJvbGxlcjo6cmVtb3ZlQ29udHJvbChjb25zdCBSZWZlcmVuY2U8IFhDb250cm9sID4gJiB4Q29udHJvbCkKewoJT1NMX0VOU1VSRSggIWltcGxfaXNEaXNwb3NlZF9ub2ZhaWwoKSwgIkZvcm1Db250cm9sbGVyOiBhbHJlYWR5IGRpc3Bvc2VkISIgKTsKCWNvbnN0IFJlZmVyZW5jZTwgWENvbnRyb2wgPiogcENvbnRyb2xzID0gbV9hQ29udHJvbHMuZ2V0Q29uc3RBcnJheSgpOwoJY29uc3QgUmVmZXJlbmNlPCBYQ29udHJvbCA+KiBwQ29udHJvbHNFbmQgPSBwQ29udHJvbHMgKyBtX2FDb250cm9scy5nZXRMZW5ndGgoKTsKICAgIHdoaWxlICggcENvbnRyb2xzICE9IHBDb250cm9sc0VuZCApCgl7CgkJaWYgKCB4Q29udHJvbC5nZXQoKSA9PSAoKnBDb250cm9scysrKS5nZXQoKSApCgkJewoJCQk6OmNvbXBoZWxwZXI6OnJlbW92ZUVsZW1lbnRBdCggbV9hQ29udHJvbHMsIHBDb250cm9scyAtIG1fYUNvbnRyb2xzLmdldENvbnN0QXJyYXkoKSAtIDEgKTsKCQkJYnJlYWs7CgkJfQoJfQoKICAgIEZpbHRlckNvbXBvbmVudHM6Oml0ZXJhdG9yIGNvbXBvbmVudFBvcyA9IDo6c3RkOjpmaW5kKCBtX2FGaWx0ZXJDb21wb25lbnRzLmJlZ2luKCksIG1fYUZpbHRlckNvbXBvbmVudHMuZW5kKCksIHhDb250cm9sICk7CiAgICBpZiAoIGNvbXBvbmVudFBvcyAhPSBtX2FGaWx0ZXJDb21wb25lbnRzLmVuZCgpICkKICAgICAgICBtX2FGaWx0ZXJDb21wb25lbnRzLmVyYXNlKCBjb21wb25lbnRQb3MgKTsKCiAgICBpbXBsQ29udHJvbFJlbW92ZWQoIHhDb250cm9sLCBtX2JEZXRhY2hFdmVudHMgKTsKCiAgICBpZiAoIGlzTGlzdGVuaW5nRm9yQ2hhbmdlcygpICYmIG1fYkRldGFjaEV2ZW50cyApCiAgICAgICAgc3RvcENvbnRyb2xNb2RpZnlMaXN0ZW5pbmcoIHhDb250cm9sICk7Cn0KCi8vIFhMb2FkTGlzdGVuZXIKLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0Kdm9pZCBGb3JtQ29udHJvbGxlcjo6bG9hZGVkKGNvbnN0IEV2ZW50T2JqZWN0JiByRXZlbnQpIHRocm93KCBSdW50aW1lRXhjZXB0aW9uICkKewoJT1NMX0VOU1VSRSggckV2ZW50LlNvdXJjZSA9PSBtX3hNb2RlbEFzSW5kZXgsICJGb3JtQ29udHJvbGxlcjo6bG9hZGVkOiB3aGVyZSBkaWQgdGhpcyBjb21lIGZyb20/IiApOwoKCU9TTF9FTlNVUkUoICFpbXBsX2lzRGlzcG9zZWRfbm9mYWlsKCksICJGb3JtQ29udHJvbGxlcjogYWxyZWFkeSBkaXNwb3NlZCEiICk7CiAgICA6Om9zbDo6TXV0ZXhHdWFyZCBhR3VhcmQoIG1fYU11dGV4ICk7CiAgICBSZWZlcmVuY2U8IFhSb3dTZXQgPiAgeEZvcm0ockV2ZW50LlNvdXJjZSwgVU5PX1FVRVJZKTsKICAgIC8vIGRvIHdlIGhhdmUgYSBjb25uZWN0ZWQgZGF0YSBzb3VyY2UKCU9TdGF0aWNEYXRhQWNjZXNzVG9vbHMgYVN0YXRpY1Rvb2xzOwogICAgaWYgKHhGb3JtLmlzKCkgJiYgYVN0YXRpY1Rvb2xzLmdldFJvd1NldENvbm5lY3Rpb24oeEZvcm0pLmlzKCkpCiAgICB7CiAgICAgICAgUmVmZXJlbmNlPCBYUHJvcGVydHlTZXQgPiAgeFNldCh4Rm9ybSwgVU5PX1FVRVJZKTsKICAgICAgICBpZiAoeFNldC5pcygpKQogICAgICAgIHsKICAgICAgICAgICAgQW55IGFWYWwgICAgICAgID0geFNldC0+Z2V0UHJvcGVydHlWYWx1ZShGTV9QUk9QX0NZQ0xFKTsKICAgICAgICAgICAgc2FsX0ludDMyIGFWYWwyID0gMDsKICAgICAgICAgICAgOjpjcHB1OjplbnVtMmludChhVmFsMixhVmFsKTsKICAgICAgICAgICAgbV9iQ3ljbGUgICAgICAgID0gIWFWYWwuaGFzVmFsdWUoKSB8fCBhVmFsMiA9PSBUYWJ1bGF0b3JDeWNsZV9SRUNPUkRTOwogICAgICAgICAgICBtX2JDYW5VcGRhdGUgICAgPSBhU3RhdGljVG9vbHMuY2FuVXBkYXRlKHhTZXQpOwogICAgICAgICAgICBtX2JDYW5JbnNlcnQgICAgPSBhU3RhdGljVG9vbHMuY2FuSW5zZXJ0KHhTZXQpOwogICAgICAgICAgICBtX2JDdXJyZW50UmVjb3JkTW9kaWZpZWQgPSA6OmNvbXBoZWxwZXI6OmdldEJPT0woeFNldC0+Z2V0UHJvcGVydHlWYWx1ZShGTV9QUk9QX0lTTU9ESUZJRUQpKTsKICAgICAgICAgICAgbV9iQ3VycmVudFJlY29yZE5ldyAgICAgID0gOjpjb21waGVscGVyOjpnZXRCT09MKHhTZXQtPmdldFByb3BlcnR5VmFsdWUoRk1fUFJPUF9JU05FVykpOwoKCQkJc3RhcnRGb3JtTGlzdGVuaW5nKCB4U2V0LCBzYWxfRmFsc2UgKTsKCiAgICAgICAgICAgIC8vIHNldCB0aGUgbG9ja3MgZm9yIHRoZSBjdXJyZW50IGNvbnRyb2xzCiAgICAgICAgICAgIGlmIChnZXRDb250YWluZXIoKS5pcygpKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBtX2FMb2FkRXZlbnQuQ2FsbCgpOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIGVsc2UKICAgICAgICB7CiAgICAgICAgICAgIG1fYkNhbkluc2VydCA9IG1fYkNhblVwZGF0ZSA9IG1fYkN5Y2xlID0gc2FsX0ZhbHNlOwogICAgICAgICAgICBtX2JDdXJyZW50UmVjb3JkTW9kaWZpZWQgPSBzYWxfRmFsc2U7CiAgICAgICAgICAgIG1fYkN1cnJlbnRSZWNvcmROZXcgPSBzYWxfRmFsc2U7CiAgICAgICAgICAgIG1fYkxvY2tlZCA9IHNhbF9GYWxzZTsKICAgICAgICB9CiAgICAgICAgbV9iREJDb25uZWN0aW9uID0gc2FsX1RydWU7CiAgICB9CiAgICBlbHNlCiAgICB7CiAgICAgICAgbV9iREJDb25uZWN0aW9uID0gc2FsX0ZhbHNlOwogICAgICAgIG1fYkNhbkluc2VydCA9IG1fYkNhblVwZGF0ZSA9IG1fYkN5Y2xlID0gc2FsX0ZhbHNlOwogICAgICAgIG1fYkN1cnJlbnRSZWNvcmRNb2RpZmllZCA9IHNhbF9GYWxzZTsKICAgICAgICBtX2JDdXJyZW50UmVjb3JkTmV3ID0gc2FsX0ZhbHNlOwogICAgICAgIG1fYkxvY2tlZCA9IHNhbF9GYWxzZTsKICAgIH0KCiAgICBSZWZlcmVuY2U8IFhDb2x1bW5zU3VwcGxpZXIgPiB4Rm9ybUNvbHVtbnMoIHhGb3JtLCBVTk9fUVVFUlkgKTsKICAgIG1fcENvbHVtbkluZm9DYWNoZS5yZXNldCggeEZvcm1Db2x1bW5zLmlzKCkgPyBuZXcgQ29sdW1uSW5mb0NhY2hlKCB4Rm9ybUNvbHVtbnMgKSA6IE5VTEwgKTsKCiAgICB1cGRhdGVBbGxEaXNwYXRjaGVycygpOwp9CgovLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQp2b2lkIEZvcm1Db250cm9sbGVyOjp1cGRhdGVBbGxEaXNwYXRjaGVycygpIGNvbnN0CnsKICAgIDo6c3RkOjpmb3JfZWFjaCgKICAgICAgICBtX2FGZWF0dXJlRGlzcGF0Y2hlcnMuYmVnaW4oKSwKICAgICAgICBtX2FGZWF0dXJlRGlzcGF0Y2hlcnMuZW5kKCksCiAgICAgICAgOjpzdGQ6OmNvbXBvc2UxKAogICAgICAgICAgICBVcGRhdGVBbGxMaXN0ZW5lcnMoKSwKICAgICAgICAgICAgOjpzdGQ6OnNlbGVjdDJuZDwgRGlzcGF0Y2hlckNvbnRhaW5lcjo6dmFsdWVfdHlwZSA+KCkKICAgICAgICApCiAgICApOwp9CgovLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQpJTVBMX0xJTksoRm9ybUNvbnRyb2xsZXIsIE9uTG9hZCwgdm9pZCosIEVNUFRZQVJHKQp7CiAgICBPU0xfRU5TVVJFKCAhaW1wbF9pc0Rpc3Bvc2VkX25vZmFpbCgpLCAiRm9ybUNvbnRyb2xsZXI6IGFscmVhZHkgZGlzcG9zZWQhIiApOwogICAgbV9iTG9ja2VkID0gZGV0ZXJtaW5lTG9ja1N0YXRlKCk7CgogICAgc2V0TG9ja3MoKTsKCiAgICBpZiAoIW1fYkxvY2tlZCkKICAgICAgICBzdGFydExpc3RlbmluZygpOwoKICAgIC8vIGp1c3Qgb25lIGV4Y2VwdGlvbiB0b2dnbGUgdGhlIGF1dG8gdmFsdWVzCiAgICBpZiAobV9iQ3VycmVudFJlY29yZE5ldykKICAgICAgICB0b2dnbGVBdXRvRmllbGRzKHNhbF9UcnVlKTsKCiAgICByZXR1cm4gMUw7Cn0KCi8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCnZvaWQgRm9ybUNvbnRyb2xsZXI6OnVubG9hZGVkKGNvbnN0IEV2ZW50T2JqZWN0JiAvKnJFdmVudCovKSB0aHJvdyggUnVudGltZUV4Y2VwdGlvbiApCnsKICAgIDo6b3NsOjpNdXRleEd1YXJkIGFHdWFyZCggbV9hTXV0ZXggKTsKICAgIGltcGxfY2hlY2tEaXNwb3NlZF90aHJvdygpOwoKICAgIHVwZGF0ZUFsbERpc3BhdGNoZXJzKCk7Cn0KCi8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCnZvaWQgRm9ybUNvbnRyb2xsZXI6OnJlbG9hZGluZyhjb25zdCBFdmVudE9iamVjdCYgLyphRXZlbnQqLykgdGhyb3coIFJ1bnRpbWVFeGNlcHRpb24gKQp7CiAgICA6Om9zbDo6TXV0ZXhHdWFyZCBhR3VhcmQoIG1fYU11dGV4ICk7CiAgICBpbXBsX2NoZWNrRGlzcG9zZWRfdGhyb3coKTsKCiAgICAvLyBkbyB0aGUgc2FtZSBsaWtlIGluIHVubG9hZGluZwogICAgLy8ganVzdCBvbmUgZXhjZXB0aW9uIHRvZ2dsZSB0aGUgYXV0byB2YWx1ZXMKICAgIG1fYVRvZ2dsZUV2ZW50LkNhbmNlbFBlbmRpbmdDYWxsKCk7CiAgICB1bmxvYWQoKTsKfQoKLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0Kdm9pZCBGb3JtQ29udHJvbGxlcjo6cmVsb2FkZWQoY29uc3QgRXZlbnRPYmplY3QmIGFFdmVudCkgdGhyb3coIFJ1bnRpbWVFeGNlcHRpb24gKQp7CiAgICA6Om9zbDo6TXV0ZXhHdWFyZCBhR3VhcmQoIG1fYU11dGV4ICk7CiAgICBpbXBsX2NoZWNrRGlzcG9zZWRfdGhyb3coKTsKCiAgICBsb2FkZWQoYUV2ZW50KTsKfQoKLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0Kdm9pZCBGb3JtQ29udHJvbGxlcjo6dW5sb2FkaW5nKGNvbnN0IEV2ZW50T2JqZWN0JiAvKmFFdmVudCovKSB0aHJvdyggUnVudGltZUV4Y2VwdGlvbiApCnsKICAgIDo6b3NsOjpNdXRleEd1YXJkIGFHdWFyZCggbV9hTXV0ZXggKTsKICAgIGltcGxfY2hlY2tEaXNwb3NlZF90aHJvdygpOwoKICAgIHVubG9hZCgpOwp9CgovLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQp2b2lkIEZvcm1Db250cm9sbGVyOjp1bmxvYWQoKSB0aHJvdyggUnVudGltZUV4Y2VwdGlvbiApCnsKICAgIDo6b3NsOjpNdXRleEd1YXJkIGFHdWFyZCggbV9hTXV0ZXggKTsKICAgIGltcGxfY2hlY2tEaXNwb3NlZF90aHJvdygpOwoKICAgIG1fYUxvYWRFdmVudC5DYW5jZWxQZW5kaW5nQ2FsbCgpOwoKICAgIC8vIGJlIHN1cmUgbm90IHRvIGhhdmUgYXV0b2ZpZWxkcwogICAgaWYgKG1fYkN1cnJlbnRSZWNvcmROZXcpCiAgICAgICAgdG9nZ2xlQXV0b0ZpZWxkcyhzYWxfRmFsc2UpOwoKCS8vIHJlbW92ZSBib3VuZCBmaWVsZCBsaXN0aW5nIGFnYWluCglyZW1vdmVCb3VuZEZpZWxkTGlzdGVuZXIoKTsKCQogICAgaWYgKG1fYkRCQ29ubmVjdGlvbiAmJiBpc0xpc3RlbmluZ0ZvckNoYW5nZXMoKSkKICAgICAgICBzdG9wTGlzdGVuaW5nKCk7CgogICAgUmVmZXJlbmNlPCBYUHJvcGVydHlTZXQgPiAgeFNldCggbV94TW9kZWxBc0luZGV4LCBVTk9fUVVFUlkgKTsKICAgIGlmICggbV9iREJDb25uZWN0aW9uICYmIHhTZXQuaXMoKSApCgkJc3RvcEZvcm1MaXN0ZW5pbmcoIHhTZXQsIHNhbF9GYWxzZSApOwoKICAgIG1fYkRCQ29ubmVjdGlvbiA9IHNhbF9GYWxzZTsKICAgIG1fYkNhbkluc2VydCA9IG1fYkNhblVwZGF0ZSA9IG1fYkN5Y2xlID0gc2FsX0ZhbHNlOwogICAgbV9iQ3VycmVudFJlY29yZE1vZGlmaWVkID0gbV9iQ3VycmVudFJlY29yZE5ldyA9IG1fYkxvY2tlZCA9IHNhbF9GYWxzZTsKCiAgICBtX3BDb2x1bW5JbmZvQ2FjaGUucmVzZXQoKTsKfQoKLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0Kdm9pZCBGb3JtQ29udHJvbGxlcjo6cmVtb3ZlQm91bmRGaWVsZExpc3RlbmVyKCkKewoJY29uc3QgUmVmZXJlbmNlPCBYQ29udHJvbCA+KiBwQ29udHJvbHMgPSBtX2FDb250cm9scy5nZXRDb25zdEFycmF5KCk7Cgljb25zdCBSZWZlcmVuY2U8IFhDb250cm9sID4qIHBDb250cm9sc0VuZCA9IHBDb250cm9scyArIG1fYUNvbnRyb2xzLmdldExlbmd0aCgpOwogICAgd2hpbGUgKCBwQ29udHJvbHMgIT0gcENvbnRyb2xzRW5kICkKICAgIHsKCQlSZWZlcmVuY2U8IFhQcm9wZXJ0eVNldCA+IHhQcm9wKCAqcENvbnRyb2xzKyssIFVOT19RVUVSWSApOwoJCWlmICggeFByb3AuaXMoKSApCgkJCXhQcm9wLT5yZW1vdmVQcm9wZXJ0eUNoYW5nZUxpc3RlbmVyKCBGTV9QUk9QX0JPVU5ERklFTEQsIHRoaXMgKTsKCX0KfQoKLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0Kdm9pZCBGb3JtQ29udHJvbGxlcjo6c3RhcnRGb3JtTGlzdGVuaW5nKCBjb25zdCBSZWZlcmVuY2U8IFhQcm9wZXJ0eVNldCA+JiBfcnhGb3JtLCBzYWxfQm9vbCBfYlByb3BlcnRpZXNPbmx5ICkKewogICAgdHJ5CiAgICB7CiAgICAgICAgaWYgKCBtX2JDYW5JbnNlcnQgfHwgbV9iQ2FuVXBkYXRlICkgICAvLyBmb3JtIGNhbiBiZSBtb2RpZmllZAogICAgICAgIHsKICAgICAgICAgICAgX3J4Rm9ybS0+YWRkUHJvcGVydHlDaGFuZ2VMaXN0ZW5lciggRk1fUFJPUF9JU05FVywgdGhpcyApOwogICAgICAgICAgICBfcnhGb3JtLT5hZGRQcm9wZXJ0eUNoYW5nZUxpc3RlbmVyKCBGTV9QUk9QX0lTTU9ESUZJRUQsIHRoaXMgKTsKCgkJICAgIGlmICggIV9iUHJvcGVydGllc09ubHkgKQoJCSAgICB7CgkJCSAgICAvLyBzZXQgdGhlIExpc3RlbmVyIGZvciBVSSBpbnRlcmFjdGlvbgoJCQkgICAgUmVmZXJlbmNlPCBYUm93U2V0QXBwcm92ZUJyb2FkY2FzdGVyID4geEFwcHJvdmUoIF9yeEZvcm0sIFVOT19RVUVSWSApOwoJCQkgICAgaWYgKCB4QXBwcm92ZS5pcygpICkKCQkJCSAgICB4QXBwcm92ZS0+YWRkUm93U2V0QXBwcm92ZUxpc3RlbmVyKCB0aGlzICk7CgoJCQkgICAgLy8gbGlzdGVuZXIgZm9yIHJvdyBzZXQgY2hhbmdlcwoJCQkgICAgUmVmZXJlbmNlPCBYUm93U2V0ID4geFJvd1NldCggX3J4Rm9ybSwgVU5PX1FVRVJZICk7CgkJCSAgICBpZiAoIHhSb3dTZXQuaXMoKSApCgkJCQkgICAgeFJvd1NldC0+YWRkUm93U2V0TGlzdGVuZXIoIHRoaXMgKTsKCQkgICAgfQogICAgICAgIH0KCiAgICAgICAgUmVmZXJlbmNlPCBYUHJvcGVydHlTZXRJbmZvID4geEluZm8gPSBfcnhGb3JtLT5nZXRQcm9wZXJ0eVNldEluZm8oKTsKICAgICAgICBpZiAoIHhJbmZvLmlzKCkgJiYgeEluZm8tPmhhc1Byb3BlcnR5QnlOYW1lKCBGTV9QUk9QX0RZTkFNSUNfQ09OVFJPTF9CT1JERVIgKSApCiAgICAgICAgICAgIF9yeEZvcm0tPmFkZFByb3BlcnR5Q2hhbmdlTGlzdGVuZXIoIEZNX1BST1BfRFlOQU1JQ19DT05UUk9MX0JPUkRFUiwgdGhpcyApOwogICAgfQogICAgY2F0Y2goIGNvbnN0IEV4Y2VwdGlvbiYgKQogICAgewogICAgICAgIERCR19VTkhBTkRMRURfRVhDRVBUSU9OKCk7CiAgICB9Cn0KCi8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCnZvaWQgRm9ybUNvbnRyb2xsZXI6OnN0b3BGb3JtTGlzdGVuaW5nKCBjb25zdCBSZWZlcmVuY2U8IFhQcm9wZXJ0eVNldCA+JiBfcnhGb3JtLCBzYWxfQm9vbCBfYlByb3BlcnRpZXNPbmx5ICkKewogICAgdHJ5CiAgICB7CiAgICAgICAgaWYgKCBtX2JDYW5JbnNlcnQgfHwgbV9iQ2FuVXBkYXRlICkKICAgICAgICB7CiAgICAgICAgICAgIF9yeEZvcm0tPnJlbW92ZVByb3BlcnR5Q2hhbmdlTGlzdGVuZXIoIEZNX1BST1BfSVNORVcsIHRoaXMgKTsKICAgICAgICAgICAgX3J4Rm9ybS0+cmVtb3ZlUHJvcGVydHlDaGFuZ2VMaXN0ZW5lciggRk1fUFJPUF9JU01PRElGSUVELCB0aGlzICk7CgoJCSAgICBpZiAoICFfYlByb3BlcnRpZXNPbmx5ICkKCQkgICAgewoJCQkgICAgUmVmZXJlbmNlPCBYUm93U2V0QXBwcm92ZUJyb2FkY2FzdGVyID4geEFwcHJvdmUoIF9yeEZvcm0sIFVOT19RVUVSWSApOwoJCQkgICAgaWYgKHhBcHByb3ZlLmlzKCkpCgkJCQkgICAgeEFwcHJvdmUtPnJlbW92ZVJvd1NldEFwcHJvdmVMaXN0ZW5lcih0aGlzKTsKCgkJCSAgICBSZWZlcmVuY2U8IFhSb3dTZXQgPiB4Um93U2V0KCBfcnhGb3JtLCBVTk9fUVVFUlkgKTsKCQkJICAgIGlmICggeFJvd1NldC5pcygpICkKCQkJCSAgICB4Um93U2V0LT5yZW1vdmVSb3dTZXRMaXN0ZW5lciggdGhpcyApOwoJCSAgICB9CiAgICAgICAgfQoKICAgICAgICBSZWZlcmVuY2U8IFhQcm9wZXJ0eVNldEluZm8gPiB4SW5mbyA9IF9yeEZvcm0tPmdldFByb3BlcnR5U2V0SW5mbygpOwogICAgICAgIGlmICggeEluZm8uaXMoKSAmJiB4SW5mby0+aGFzUHJvcGVydHlCeU5hbWUoIEZNX1BST1BfRFlOQU1JQ19DT05UUk9MX0JPUkRFUiApICkKICAgICAgICAgICAgX3J4Rm9ybS0+cmVtb3ZlUHJvcGVydHlDaGFuZ2VMaXN0ZW5lciggRk1fUFJPUF9EWU5BTUlDX0NPTlRST0xfQk9SREVSLCB0aGlzICk7CiAgICB9CiAgICBjYXRjaCggY29uc3QgRXhjZXB0aW9uJiApCiAgICB7CiAgICAgICAgREJHX1VOSEFORExFRF9FWENFUFRJT04oKTsKICAgIH0KfQoKLy8gY29tOjpzdW46OnN0YXI6OnNkYmM6OlhSb3dTZXRMaXN0ZW5lcgovLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQp2b2lkIEZvcm1Db250cm9sbGVyOjpjdXJzb3JNb3ZlZChjb25zdCBFdmVudE9iamVjdCYgLypldmVudCovKSB0aHJvdyggUnVudGltZUV4Y2VwdGlvbiApCnsKICAgIDo6b3NsOjpNdXRleEd1YXJkIGFHdWFyZCggbV9hTXV0ZXggKTsKICAgIGltcGxfY2hlY2tEaXNwb3NlZF90aHJvdygpOwoKICAgIC8vIHRvZ2dsZSB0aGUgbG9ja2luZyA/CiAgICBpZiAobV9iTG9ja2VkICE9IGRldGVybWluZUxvY2tTdGF0ZSgpKQogICAgewogICAgICAgIG1fYkxvY2tlZCA9ICFtX2JMb2NrZWQ7CiAgICAgICAgc2V0TG9ja3MoKTsKICAgICAgICBpZiAoaXNMaXN0ZW5pbmdGb3JDaGFuZ2VzKCkpCiAgICAgICAgICAgIHN0YXJ0TGlzdGVuaW5nKCk7CiAgICAgICAgZWxzZQogICAgICAgICAgICBzdG9wTGlzdGVuaW5nKCk7CiAgICB9CgoJLy8gbmVpdGhlciB0aGUgY3VycmVudCBjb250cm9sIG5vciB0aGUgY3VycmVudCByZWNvcmQgYXJlIG1vZGlmaWVkIGFueW1vcmUKCW1fYkN1cnJlbnRSZWNvcmRNb2RpZmllZCA9IG1fYk1vZGlmaWVkID0gc2FsX0ZhbHNlOwp9CgovLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQp2b2lkIEZvcm1Db250cm9sbGVyOjpyb3dDaGFuZ2VkKGNvbnN0IEV2ZW50T2JqZWN0JiAvKmV2ZW50Ki8pIHRocm93KCBSdW50aW1lRXhjZXB0aW9uICkKewogICAgLy8gbm90IGludGVyZXN0ZWQgaW4gLi4uCn0KLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0Kdm9pZCBGb3JtQ29udHJvbGxlcjo6cm93U2V0Q2hhbmdlZChjb25zdCBFdmVudE9iamVjdCYgLypldmVudCovKSB0aHJvdyggUnVudGltZUV4Y2VwdGlvbiApCnsKICAgIC8vIG5vdCBpbnRlcmVzdGVkIGluIC4uLgp9CgoKLy8gWENvbnRhaW5lckxpc3RlbmVyCi8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCnZvaWQgU0FMX0NBTEwgRm9ybUNvbnRyb2xsZXI6OmVsZW1lbnRJbnNlcnRlZChjb25zdCBDb250YWluZXJFdmVudCYgZXZ0KSB0aHJvdyggUnVudGltZUV4Y2VwdGlvbiApCnsKICAgIDo6b3NsOjpNdXRleEd1YXJkIGFHdWFyZCggbV9hTXV0ZXggKTsKICAgIGltcGxfY2hlY2tEaXNwb3NlZF90aHJvdygpOwoKICAgIFJlZmVyZW5jZTwgWENvbnRyb2wgPiB4Q29udHJvbCggZXZ0LkVsZW1lbnQsIFVOT19RVUVSWSApOwogICAgaWYgKCAheENvbnRyb2wuaXMoKSApCiAgICAgICAgcmV0dXJuOwoKICAgIFJlZmVyZW5jZTwgWEZvcm1Db21wb25lbnQgPiAgeE1vZGVsKHhDb250cm9sLT5nZXRNb2RlbCgpLCBVTk9fUVVFUlkpOwogICAgaWYgKHhNb2RlbC5pcygpICYmIG1feE1vZGVsQXNJbmRleCA9PSB4TW9kZWwtPmdldFBhcmVudCgpKQogICAgewogICAgICAgIGluc2VydENvbnRyb2woeENvbnRyb2wpOwoKICAgICAgICBpZiAoIG1fYVRhYkFjdGl2YXRpb25UaW1lci5Jc0FjdGl2ZSgpICkKICAgICAgICAgICAgbV9hVGFiQWN0aXZhdGlvblRpbWVyLlN0b3AoKTsKCiAgICAgICAgbV9hVGFiQWN0aXZhdGlvblRpbWVyLlN0YXJ0KCk7CiAgICB9CiAgICAvLyBhcmUgd2UgaW4gZmlsdGVybW9kZSBhbmQgYSBYTW9kZVNlbGVjdG9yIGhhcyBpbnNlcnRlZCBhbiBlbGVtZW50CiAgICBlbHNlIGlmIChtX2JGaWx0ZXJpbmcgJiYgUmVmZXJlbmNlPCBYTW9kZVNlbGVjdG9yID4gKGV2dC5Tb3VyY2UsIFVOT19RVUVSWSkuaXMoKSkKICAgIHsKICAgICAgICB4TW9kZWwgPSBSZWZlcmVuY2U8IFhGb3JtQ29tcG9uZW50ID4gKGV2dC5Tb3VyY2UsIFVOT19RVUVSWSk7CiAgICAgICAgaWYgKHhNb2RlbC5pcygpICYmIG1feE1vZGVsQXNJbmRleCA9PSB4TW9kZWwtPmdldFBhcmVudCgpKQogICAgICAgIHsKICAgICAgICAgICAgUmVmZXJlbmNlPCBYUHJvcGVydHlTZXQgPiAgeFNldCh4Q29udHJvbC0+Z2V0TW9kZWwoKSwgVU5PX1FVRVJZKTsKICAgICAgICAgICAgaWYgKHhTZXQuaXMoKSAmJiA6OmNvbXBoZWxwZXI6Omhhc1Byb3BlcnR5KEZNX1BST1BfQk9VTkRGSUVMRCwgeFNldCkpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIC8vIGRvZXMgdGhlIG1vZGVsIHVzZSBhIGJvdW5kIGZpZWxkID8KICAgICAgICAgICAgICAgIFJlZmVyZW5jZTwgWFByb3BlcnR5U2V0ID4gIHhGaWVsZDsKICAgICAgICAgICAgICAgIHhTZXQtPmdldFByb3BlcnR5VmFsdWUoRk1fUFJPUF9CT1VOREZJRUxEKSA+Pj0geEZpZWxkOwoKICAgICAgICAgICAgICAgIFJlZmVyZW5jZTwgWFRleHRDb21wb25lbnQgPiAgeFRleHQoeENvbnRyb2wsIFVOT19RVUVSWSk7CiAgICAgICAgICAgICAgICAvLyBtYXkgd2UgZmlsdGVyIHRoZSBmaWVsZD8KICAgICAgICAgICAgICAgIGlmICh4VGV4dC5pcygpICYmIHhGaWVsZC5pcygpICYmIDo6Y29tcGhlbHBlcjo6aGFzUHJvcGVydHkoRk1fUFJPUF9TRUFSQ0hBQkxFLCB4RmllbGQpICYmCiAgICAgICAgICAgICAgICAgICAgOjpjb21waGVscGVyOjpnZXRCT09MKHhGaWVsZC0+Z2V0UHJvcGVydHlWYWx1ZShGTV9QUk9QX1NFQVJDSEFCTEUpKSkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBtX2FGaWx0ZXJDb21wb25lbnRzLnB1c2hfYmFjayggeFRleHQgKTsKICAgICAgICAgICAgICAgICAgICB4VGV4dC0+YWRkVGV4dExpc3RlbmVyKCB0aGlzICk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9Cn0KCi8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCnZvaWQgU0FMX0NBTEwgRm9ybUNvbnRyb2xsZXI6OmVsZW1lbnRSZXBsYWNlZChjb25zdCBDb250YWluZXJFdmVudCYgZXZ0KSB0aHJvdyggUnVudGltZUV4Y2VwdGlvbiApCnsKICAgIC8vIHNpbXVsYXRlIGFuIGVsZW1lbnRSZW1vdmVkCiAgICBDb250YWluZXJFdmVudCBhUmVtb3ZlRXZlbnQoIGV2dCApOwogICAgYVJlbW92ZUV2ZW50LkVsZW1lbnQgPSBldnQuUmVwbGFjZWRFbGVtZW50OwogICAgYVJlbW92ZUV2ZW50LlJlcGxhY2VkRWxlbWVudCA9IEFueSgpOwogICAgZWxlbWVudFJlbW92ZWQoIGFSZW1vdmVFdmVudCApOwoKICAgIC8vIHNpbXVsYXRlIGFuIGVsZW1lbnRJbnNlcnRlZAogICAgQ29udGFpbmVyRXZlbnQgYUluc2VydEV2ZW50KCBldnQgKTsKICAgIGFJbnNlcnRFdmVudC5SZXBsYWNlZEVsZW1lbnQgPSBBbnkoKTsKICAgIGVsZW1lbnRJbnNlcnRlZCggYUluc2VydEV2ZW50ICk7Cn0KCi8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCnZvaWQgU0FMX0NBTEwgRm9ybUNvbnRyb2xsZXI6OmVsZW1lbnRSZW1vdmVkKGNvbnN0IENvbnRhaW5lckV2ZW50JiBldnQpIHRocm93KCBSdW50aW1lRXhjZXB0aW9uICkKewogICAgOjpvc2w6Ok11dGV4R3VhcmQgYUd1YXJkKCBtX2FNdXRleCApOwogICAgaW1wbF9jaGVja0Rpc3Bvc2VkX3Rocm93KCk7CgogICAgUmVmZXJlbmNlPCBYQ29udHJvbCA+ICB4Q29udHJvbDsKICAgIGV2dC5FbGVtZW50ID4+PSB4Q29udHJvbDsKICAgIGlmICgheENvbnRyb2wuaXMoKSkKICAgICAgICByZXR1cm47CgogICAgUmVmZXJlbmNlPCBYRm9ybUNvbXBvbmVudCA+ICB4TW9kZWwoeENvbnRyb2wtPmdldE1vZGVsKCksIFVOT19RVUVSWSk7CiAgICBpZiAoeE1vZGVsLmlzKCkgJiYgbV94TW9kZWxBc0luZGV4ID09IHhNb2RlbC0+Z2V0UGFyZW50KCkpCiAgICB7CiAgICAgICAgcmVtb3ZlQ29udHJvbCh4Q29udHJvbCk7CiAgICAgICAgLy8gVGFiT3JkZXIgbmljaHQgbmV1IGJlcmVjaG5lbiwgZGEgZGFzIGludGVybiBzY2hvbiBmdW5rdGlvbmllcmVuIG113yEKICAgIH0KICAgIC8vIGFyZSB3ZSBpbiBmaWx0ZXJtb2RlIGFuZCBhIFhNb2RlU2VsZWN0b3IgaGFzIGluc2VydGVkIGFuIGVsZW1lbnQKICAgIGVsc2UgaWYgKG1fYkZpbHRlcmluZyAmJiBSZWZlcmVuY2U8IFhNb2RlU2VsZWN0b3IgPiAoZXZ0LlNvdXJjZSwgVU5PX1FVRVJZKS5pcygpKQogICAgewogICAgICAgIEZpbHRlckNvbXBvbmVudHM6Oml0ZXJhdG9yIGNvbXBvbmVudFBvcyA9IDo6c3RkOjpmaW5kKAogICAgICAgICAgICBtX2FGaWx0ZXJDb21wb25lbnRzLmJlZ2luKCksIG1fYUZpbHRlckNvbXBvbmVudHMuZW5kKCksIHhDb250cm9sICk7CiAgICAgICAgaWYgKCBjb21wb25lbnRQb3MgIT0gbV9hRmlsdGVyQ29tcG9uZW50cy5lbmQoKSApCiAgICAgICAgICAgIG1fYUZpbHRlckNvbXBvbmVudHMuZXJhc2UoIGNvbXBvbmVudFBvcyApOwogICAgfQp9CgovLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQpSZWZlcmVuY2U8IFhDb250cm9sID4gIEZvcm1Db250cm9sbGVyOjppc0luTGlzdChjb25zdCBSZWZlcmVuY2U8IFhXaW5kb3dQZWVyID4gJiB4UGVlcikgY29uc3QKewogICAgT1NMX0VOU1VSRSggIWltcGxfaXNEaXNwb3NlZF9ub2ZhaWwoKSwgIkZvcm1Db250cm9sbGVyOiBhbHJlYWR5IGRpc3Bvc2VkISIgKTsKICAgIGNvbnN0IFJlZmVyZW5jZTwgWENvbnRyb2wgPiogcENvbnRyb2xzID0gbV9hQ29udHJvbHMuZ2V0Q29uc3RBcnJheSgpOwoKICAgIHNhbF91SW50MzIgbkN0cmxzID0gbV9hQ29udHJvbHMuZ2V0TGVuZ3RoKCk7CiAgICBmb3IgKCBzYWxfdUludDMyIG4gPSAwOyBuIDwgbkN0cmxzICYmIHhQZWVyLmlzKCk7ICsrbiwgKytwQ29udHJvbHMgKQogICAgewogICAgICAgIGlmICggcENvbnRyb2xzLT5pcygpICkKICAgICAgICB7CiAgICAgICAgICAgIFJlZmVyZW5jZTwgWFZjbFdpbmRvd1BlZXIgPiAgeEN0cmxQZWVyKCAoKnBDb250cm9scyktPmdldFBlZXIoKSwgVU5PX1FVRVJZKTsKICAgICAgICAgICAgaWYgKCAoIHhDdHJsUGVlci5nZXQoKSA9PSB4UGVlci5nZXQoKSApIHx8IHhDdHJsUGVlci0+aXNDaGlsZCggeFBlZXIgKSApCiAgICAgICAgICAgICAgICByZXR1cm4gKnBDb250cm9sczsKICAgICAgICB9CiAgICB9CiAgICByZXR1cm4gUmVmZXJlbmNlPCBYQ29udHJvbCA+ICgpOwp9CgovLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQp2b2lkIEZvcm1Db250cm9sbGVyOjphY3RpdmF0ZUZpcnN0KCkgdGhyb3coIFJ1bnRpbWVFeGNlcHRpb24gKQp7CiAgICA6Om9zbDo6TXV0ZXhHdWFyZCBhR3VhcmQoIG1fYU11dGV4ICk7CiAgICBpbXBsX2NoZWNrRGlzcG9zZWRfdGhyb3coKTsKCiAgICBEQkdfQVNTRVJUKG1feFRhYkNvbnRyb2xsZXIuaXMoKSwgIkZvcm1Db250cm9sbGVyOjphY3RpdmF0ZUZpcnN0IDogaW52YWxpZCBhZ2dyZWdhdGUgISIpOwogICAgaWYgKG1feFRhYkNvbnRyb2xsZXIuaXMoKSkKICAgICAgICBtX3hUYWJDb250cm9sbGVyLT5hY3RpdmF0ZUZpcnN0KCk7Cn0KCi8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCnZvaWQgRm9ybUNvbnRyb2xsZXI6OmFjdGl2YXRlTGFzdCgpIHRocm93KCBSdW50aW1lRXhjZXB0aW9uICkKewogICAgOjpvc2w6Ok11dGV4R3VhcmQgYUd1YXJkKCBtX2FNdXRleCApOwogICAgaW1wbF9jaGVja0Rpc3Bvc2VkX3Rocm93KCk7CgogICAgREJHX0FTU0VSVChtX3hUYWJDb250cm9sbGVyLmlzKCksICJGb3JtQ29udHJvbGxlcjo6YWN0aXZhdGVMYXN0IDogaW52YWxpZCBhZ2dyZWdhdGUgISIpOwogICAgaWYgKG1feFRhYkNvbnRyb2xsZXIuaXMoKSkKICAgICAgICBtX3hUYWJDb250cm9sbGVyLT5hY3RpdmF0ZUxhc3QoKTsKfQoKLy8gWEZvcm1Db250cm9sbGVyCi8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tClJlZmVyZW5jZTwgWEZvcm1PcGVyYXRpb25zID4gU0FMX0NBTEwgRm9ybUNvbnRyb2xsZXI6OmdldEZvcm1PcGVyYXRpb25zKCkgdGhyb3cgKFJ1bnRpbWVFeGNlcHRpb24pCnsKICAgIDo6b3NsOjpNdXRleEd1YXJkIGFHdWFyZCggbV9hTXV0ZXggKTsKICAgIGltcGxfY2hlY2tEaXNwb3NlZF90aHJvdygpOwoKICAgIHJldHVybiBtX3hGb3JtT3BlcmF0aW9uczsKfQoKLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KUmVmZXJlbmNlPCBYQ29udHJvbD4gU0FMX0NBTEwgRm9ybUNvbnRyb2xsZXI6OmdldEN1cnJlbnRDb250cm9sKHZvaWQpIHRocm93KCBSdW50aW1lRXhjZXB0aW9uICkKewoJOjpvc2w6Ok11dGV4R3VhcmQgYUd1YXJkKCBtX2FNdXRleCApOwogICAgaW1wbF9jaGVja0Rpc3Bvc2VkX3Rocm93KCk7CglyZXR1cm4gbV94Q3VycmVudENvbnRyb2w7Cn0KCi8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCnZvaWQgU0FMX0NBTEwgRm9ybUNvbnRyb2xsZXI6OmFkZEFjdGl2YXRlTGlzdGVuZXIoY29uc3QgUmVmZXJlbmNlPCBYRm9ybUNvbnRyb2xsZXJMaXN0ZW5lciA+ICYgbCkgdGhyb3coIFJ1bnRpbWVFeGNlcHRpb24gKQp7Cgk6Om9zbDo6TXV0ZXhHdWFyZCBhR3VhcmQoIG1fYU11dGV4ICk7CiAgICBpbXBsX2NoZWNrRGlzcG9zZWRfdGhyb3coKTsKCW1fYUFjdGl2YXRlTGlzdGVuZXJzLmFkZEludGVyZmFjZShsKTsKfQovLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQp2b2lkIFNBTF9DQUxMIEZvcm1Db250cm9sbGVyOjpyZW1vdmVBY3RpdmF0ZUxpc3RlbmVyKGNvbnN0IFJlZmVyZW5jZTwgWEZvcm1Db250cm9sbGVyTGlzdGVuZXIgPiAmIGwpIHRocm93KCBSdW50aW1lRXhjZXB0aW9uICkKewoJOjpvc2w6Ok11dGV4R3VhcmQgYUd1YXJkKCBtX2FNdXRleCApOwogICAgaW1wbF9jaGVja0Rpc3Bvc2VkX3Rocm93KCk7CgltX2FBY3RpdmF0ZUxpc3RlbmVycy5yZW1vdmVJbnRlcmZhY2UobCk7Cn0KCi8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCnZvaWQgU0FMX0NBTEwgRm9ybUNvbnRyb2xsZXI6OmFkZENoaWxkQ29udHJvbGxlciggY29uc3QgUmVmZXJlbmNlPCBYRm9ybUNvbnRyb2xsZXIgPiYgX0NoaWxkQ29udHJvbGxlciApIHRocm93KCBSdW50aW1lRXhjZXB0aW9uLCBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gKQp7CiAgICA6Om9zbDo6TXV0ZXhHdWFyZCBhR3VhcmQoIG1fYU11dGV4ICk7CiAgICBpbXBsX2NoZWNrRGlzcG9zZWRfdGhyb3coKTsKCiAgICBpZiAoICFfQ2hpbGRDb250cm9sbGVyLmlzKCkgKQogICAgICAgIHRocm93IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiggOjpydGw6Ok9VU3RyaW5nKCksICp0aGlzLCAxICk7CiAgICAgICAgLy8gVE9ETzogKGxvY2FsaXplZCkgZXJyb3IgbWVzc2FnZQoKICAgIC8vIHRoZSBwYXJlbnQgb2Ygb3VyICh0by1iZS0pY2hpbGQgbXVzdCBiZSBvdXIgb3duIG1vZGVsCiAgICBSZWZlcmVuY2U8IFhGb3JtQ29tcG9uZW50ID4geEZvcm1PZkNoaWxkKCBfQ2hpbGRDb250cm9sbGVyLT5nZXRNb2RlbCgpLCBVTk9fUVVFUlkgKTsKICAgIGlmICggIXhGb3JtT2ZDaGlsZC5pcygpICkKICAgICAgICB0aHJvdyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oIDo6cnRsOjpPVVN0cmluZygpLCAqdGhpcywgMSApOwogICAgICAgIC8vIFRPRE86IChsb2NhbGl6ZWQpIGVycm9yIG1lc3NhZ2UKCiAgICBpZiAoIHhGb3JtT2ZDaGlsZC0+Z2V0UGFyZW50KCkgIT0gbV94TW9kZWxBc0luZGV4ICkKICAgICAgICB0aHJvdyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oIDo6cnRsOjpPVVN0cmluZygpLCAqdGhpcywgMSApOwogICAgICAgIC8vIFRPRE86IChsb2NhbGl6ZWQpIGVycm9yIG1lc3NhZ2UKCiAgICBtX2FDaGlsZHMucHVzaF9iYWNrKCBfQ2hpbGRDb250cm9sbGVyICk7CiAgICBfQ2hpbGRDb250cm9sbGVyLT5zZXRQYXJlbnQoICp0aGlzICk7CgogICAgLy8gc2VhcmNoIHRoZSBwb3NpdGlvbiBvZiB0aGUgbW9kZWwgd2l0aGluIHRoZSBmb3JtCiAgICBzYWxfdUludDMyIG5Qb3MgPSBtX3hNb2RlbEFzSW5kZXgtPmdldENvdW50KCk7CiAgICBSZWZlcmVuY2U8IFhGb3JtQ29tcG9uZW50ID4geFRlbXA7CiAgICBmb3IoIDsgblBvczsgKQogICAgewogICAgICAgIG1feE1vZGVsQXNJbmRleC0+Z2V0QnlJbmRleCgtLW5Qb3MpID4+PSB4VGVtcDsKICAgICAgICBpZiAoIHhGb3JtT2ZDaGlsZCA9PSB4VGVtcCApCiAgICAgICAgewogICAgICAgICAgICBSZWZlcmVuY2U8IFhJbnRlcmZhY2UgPiAgeElmYyggX0NoaWxkQ29udHJvbGxlciwgVU5PX1FVRVJZICk7CiAgICAgICAgICAgIG1feE1vZGVsQXNNYW5hZ2VyLT5hdHRhY2goIG5Qb3MsIHhJZmMsIG1ha2VBbnkoIF9DaGlsZENvbnRyb2xsZXIpICk7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIH0KICAgIH0KfQoKLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KUmVmZXJlbmNlPCBYRm9ybUNvbnRyb2xsZXJDb250ZXh0ID4gU0FMX0NBTEwgRm9ybUNvbnRyb2xsZXI6OmdldENvbnRleHQoKSB0aHJvdyAoUnVudGltZUV4Y2VwdGlvbikKewoJOjpvc2w6Ok11dGV4R3VhcmQgYUd1YXJkKCBtX2FNdXRleCApOwogICAgaW1wbF9jaGVja0Rpc3Bvc2VkX3Rocm93KCk7CiAgICByZXR1cm4gbV94Q29udGV4dDsKfQoKLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0Kdm9pZCBTQUxfQ0FMTCBGb3JtQ29udHJvbGxlcjo6c2V0Q29udGV4dCggY29uc3QgUmVmZXJlbmNlPCBYRm9ybUNvbnRyb2xsZXJDb250ZXh0ID4mIF9jb250ZXh0ICkgdGhyb3cgKFJ1bnRpbWVFeGNlcHRpb24pCnsKCTo6b3NsOjpNdXRleEd1YXJkIGFHdWFyZCggbV9hTXV0ZXggKTsKICAgIGltcGxfY2hlY2tEaXNwb3NlZF90aHJvdygpOwogICAgbV94Q29udGV4dCA9IF9jb250ZXh0Owp9CgovLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQpSZWZlcmVuY2U8IFhJbnRlcmFjdGlvbkhhbmRsZXIgPiBTQUxfQ0FMTCBGb3JtQ29udHJvbGxlcjo6Z2V0SW50ZXJhY3Rpb25IYW5kbGVyKCkgdGhyb3cgKFJ1bnRpbWVFeGNlcHRpb24pCnsKCTo6b3NsOjpNdXRleEd1YXJkIGFHdWFyZCggbV9hTXV0ZXggKTsKICAgIGltcGxfY2hlY2tEaXNwb3NlZF90aHJvdygpOwogICAgcmV0dXJuIG1feEludGVyYWN0aW9uSGFuZGxlcjsKfQoKLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0Kdm9pZCBTQUxfQ0FMTCBGb3JtQ29udHJvbGxlcjo6c2V0SW50ZXJhY3Rpb25IYW5kbGVyKCBjb25zdCBSZWZlcmVuY2U8IFhJbnRlcmFjdGlvbkhhbmRsZXIgPiYgX2ludGVyYWN0aW9uSGFuZGxlciApIHRocm93IChSdW50aW1lRXhjZXB0aW9uKQp7Cgk6Om9zbDo6TXV0ZXhHdWFyZCBhR3VhcmQoIG1fYU11dGV4ICk7CiAgICBpbXBsX2NoZWNrRGlzcG9zZWRfdGhyb3coKTsKICAgIG1feEludGVyYWN0aW9uSGFuZGxlciA9IF9pbnRlcmFjdGlvbkhhbmRsZXI7Cn0KCi8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCnZvaWQgRm9ybUNvbnRyb2xsZXI6OnNldEZpbHRlcig6OnN0ZDo6dmVjdG9yPEZtRmllbGRJbmZvPiYgckZpZWxkSW5mb3MpCnsKCU9TTF9FTlNVUkUoICFpbXBsX2lzRGlzcG9zZWRfbm9mYWlsKCksICJGb3JtQ29udHJvbGxlcjogYWxyZWFkeSBkaXNwb3NlZCEiICk7CgkvLyBjcmVhdGUgdGhlIGNvbXBvc2VyCglSZWZlcmVuY2U8IFhSb3dTZXQgPiB4Rm9ybShtX3hNb2RlbEFzSW5kZXgsIFVOT19RVUVSWSk7CglSZWZlcmVuY2U8IFhDb25uZWN0aW9uID4geENvbm5lY3Rpb24oT1N0YXRpY0RhdGFBY2Nlc3NUb29scygpLmdldFJvd1NldENvbm5lY3Rpb24oeEZvcm0pKTsKCWlmICh4Rm9ybS5pcygpKQoJewogICAgICAgIHRyeQogICAgICAgIHsKICAgICAgICAgICAgUmVmZXJlbmNlPCBYTXVsdGlTZXJ2aWNlRmFjdG9yeSA+IHhGYWN0b3J5KCB4Q29ubmVjdGlvbiwgVU5PX1FVRVJZX1RIUk9XICk7CiAgICAgICAgICAgIG1feENvbXBvc2VyLnNldCgKICAgICAgICAgICAgICAgIHhGYWN0b3J5LT5jcmVhdGVJbnN0YW5jZSggOjpydGw6Ok9VU3RyaW5nKCBSVExfQ09OU1RBU0NJSV9VU1RSSU5HUEFSQU0oICJjb20uc3VuLnN0YXIuc2RiLlNpbmdsZVNlbGVjdFF1ZXJ5Q29tcG9zZXIiICkgKSApLAogICAgICAgICAgICAgICAgVU5PX1FVRVJZX1RIUk9XICk7CgogICAgICAgICAgICBSZWZlcmVuY2U8IFhQcm9wZXJ0eVNldCA+IHhTZXQoIHhGb3JtLCBVTk9fUVVFUlkgKTsKCQkJOjpydGw6Ok9VU3RyaW5nCXNTdGF0ZW1lbnQJPSA6OmNvbXBoZWxwZXI6OmdldFN0cmluZyggeFNldC0+Z2V0UHJvcGVydHlWYWx1ZSggRk1fUFJPUF9BQ1RJVkVDT01NQU5EICkgKTsKCQkJOjpydGw6Ok9VU3RyaW5nIHNGaWx0ZXIJCT0gOjpjb21waGVscGVyOjpnZXRTdHJpbmcoIHhTZXQtPmdldFByb3BlcnR5VmFsdWUoIEZNX1BST1BfRklMVEVSICkgKTsKCQkJbV94Q29tcG9zZXItPnNldEVsZW1lbnRhcnlRdWVyeSggc1N0YXRlbWVudCApOwoJCQltX3hDb21wb3Nlci0+c2V0RmlsdGVyKCBzRmlsdGVyICk7CiAgICAgICAgfQogICAgICAgIGNhdGNoKCBjb25zdCBFeGNlcHRpb24mICkKICAgICAgICB7CiAgICAgICAgCURCR19VTkhBTkRMRURfRVhDRVBUSU9OKCk7CiAgICAgICAgfQoJfQoKCWlmIChtX3hDb21wb3Nlci5pcygpKQoJewoJCVNlcXVlbmNlIDwgUHJvcGVydHlWYWx1ZT4gYUxldmVsOwoJCVNlcXVlbmNlPCBTZXF1ZW5jZSA8IFByb3BlcnR5VmFsdWUgPiA+IGFGaWx0ZXJSb3dzID0gbV94Q29tcG9zZXItPmdldFN0cnVjdHVyZWRGaWx0ZXIoKTsKCgkJLy8gb2ssIHdlIHJlY2lldmUgdGhlIGxpc3Qgb2YgZmlsdGVycyBhcyBzZXF1ZW5jZSBvZiBmaWVsZG5hbWVzLCB2YWx1ZQoJCS8vIG5vdyB3ZSBoYXZlIHRvIHRyYW5zZm9ybSB0aGUgZmllbGRuYW1lIGludG8gVUkgbmFtZXMsIHRoYXQgY291bGQgYmUgYSBsYWJlbCBvZiB0aGUgZmllbGQgb3IKCQkvLyBhIGFsaWFzbmFtZSBvciB0aGUgZmllbGRuYW1lIGl0c2VsZgoKCQkvLyBmaXJzdCBhZGp1c3QgdGhlIGZpZWxkIG5hbWVzIGlmIG5lY2Vzc2FyeQoJCVJlZmVyZW5jZTwgWE5hbWVBY2Nlc3MgPiB4UXVlcnlDb2x1bW5zID0KICAgICAgICAgICAgUmVmZXJlbmNlPCBYQ29sdW1uc1N1cHBsaWVyID4oIG1feENvbXBvc2VyLCBVTk9fUVVFUllfVEhST1cgKS0+Z2V0Q29sdW1ucygpOwoKCQlmb3IgKDo6c3RkOjp2ZWN0b3I8Rm1GaWVsZEluZm8+OjppdGVyYXRvciBpdGVyID0gckZpZWxkSW5mb3MuYmVnaW4oKTsKCQkJaXRlciAhPSByRmllbGRJbmZvcy5lbmQoKTsgaXRlcisrKQoJCXsKCQkJaWYgKCB4UXVlcnlDb2x1bW5zLT5oYXNCeU5hbWUoKCppdGVyKS5hRmllbGROYW1lKSApIAoJCQl7CgkJCQlpZiAoICh4UXVlcnlDb2x1bW5zLT5nZXRCeU5hbWUoKCppdGVyKS5hRmllbGROYW1lKSA+Pj0gKCppdGVyKS54RmllbGQpICYmICgqaXRlcikueEZpZWxkLmlzKCkgKQoJCQkJCSgqaXRlcikueEZpZWxkLT5nZXRQcm9wZXJ0eVZhbHVlKEZNX1BST1BfUkVBTE5BTUUpID4+PSAoKml0ZXIpLmFGaWVsZE5hbWU7CgkJCX0KCQl9CgoJCVJlZmVyZW5jZTwgWERhdGFiYXNlTWV0YURhdGE+IHhNZXRhRGF0YSh4Q29ubmVjdGlvbi0+Z2V0TWV0YURhdGEoKSk7CgkJLy8gbm93IHRyYW5zZmVyIHRoZSBmaWx0ZXJzIGludG8gVmFsdWUvVGV4dENvbXBvbmVudCBwYWlycwoJCTo6Y29tcGhlbHBlcjo6VVN0cmluZ01peEVxdWFsIGFDb21wYXJlKHhNZXRhRGF0YS0+c3RvcmVzTWl4ZWRDYXNlUXVvdGVkSWRlbnRpZmllcnMoKSk7CgoJCS8vIG5lZWQgdG8gcGFyc2UgY3JpdGVyaWEgbG9jYWxpemVkCgkJT1N0YXRpY0RhdGFBY2Nlc3NUb29scyBhU3RhdGljVG9vbHM7CgkJUmVmZXJlbmNlPCBYTnVtYmVyRm9ybWF0c1N1cHBsaWVyPiB4Rm9ybWF0U3VwcGxpZXIoIGFTdGF0aWNUb29scy5nZXROdW1iZXJGb3JtYXRzKHhDb25uZWN0aW9uLCBzYWxfVHJ1ZSkpOwogICAgICAgIFJlZmVyZW5jZTwgWE51bWJlckZvcm1hdHRlcj4geEZvcm1hdHRlciggbV9hQ29udGV4dC5jcmVhdGVDb21wb25lbnQoICJjb20uc3VuLnN0YXIudXRpbC5OdW1iZXJGb3JtYXR0ZXIiICksIFVOT19RVUVSWSApOwogICAgICAgIHhGb3JtYXR0ZXItPmF0dGFjaE51bWJlckZvcm1hdHNTdXBwbGllcih4Rm9ybWF0U3VwcGxpZXIpOwoJCUxvY2FsZSBhQXBwTG9jYWxlID0gQXBwbGljYXRpb246OkdldFNldHRpbmdzKCkuR2V0VUlMb2NhbGUoKTsKCQlMb2NhbGVEYXRhV3JhcHBlciBhTG9jYWxlV3JhcHBlciggbV9hQ29udGV4dC5nZXRMZWdhY3lTZXJ2aWNlRmFjdG9yeSgpLCBhQXBwTG9jYWxlICk7CgoJCS8vIHJldHJpZXZpbmcgdGhlIGZpbHRlcgoJCWNvbnN0IFNlcXVlbmNlIDwgUHJvcGVydHlWYWx1ZSA+KiBwUm93ID0gYUZpbHRlclJvd3MuZ2V0Q29uc3RBcnJheSgpOwoJCWZvciAoc2FsX0ludDMyIGkgPSAwLCBuTGVuID0gYUZpbHRlclJvd3MuZ2V0TGVuZ3RoKCk7IGkgPCBuTGVuOyArK2kpCgkJewoJCQlGbUZpbHRlclJvdyBhUm93OwoKCQkJLy8gc2VhcmNoIGEgZmllbGQgZm9yIHRoZSBnaXZlbiBuYW1lCgkJCWNvbnN0IFByb3BlcnR5VmFsdWUqIHBSZWZWYWx1ZXMgPSBwUm93W2ldLmdldENvbnN0QXJyYXkoKTsKCQkJZm9yIChzYWxfSW50MzIgaiA9IDAsIG5MZW4xID0gcFJvd1tpXS5nZXRMZW5ndGgoKTsgaiA8IG5MZW4xOyBqKyspCgkJCXsKCQkJCS8vIGxvb2sgZm9yIHRoZSB0ZXh0IGNvbXBvbmVudAoJCQkJUmVmZXJlbmNlPCBYUHJvcGVydHlTZXQgPiB4RmllbGQ7CgkJCQl0cnkKCQkJCXsKCQkJCQlSZWZlcmVuY2U8IFhQcm9wZXJ0eVNldCA+IHhTZXQ7CgkJCQkJOjpydGw6Ok9VU3RyaW5nIGFSZWFsTmFtZTsKCgkJCQkJLy8gZmlyc3QgbG9vayB3aXRoIHRoZSBnaXZlbiBuYW1lCgkJCQkJaWYgKHhRdWVyeUNvbHVtbnMtPmhhc0J5TmFtZShwUmVmVmFsdWVzW2pdLk5hbWUpKQoJCQkJCXsKCQkJCQkJeFF1ZXJ5Q29sdW1ucy0+Z2V0QnlOYW1lKHBSZWZWYWx1ZXNbal0uTmFtZSkgPj49IHhTZXQ7CgoJCQkJCQkvLyBnZXQgdGhlIFJlYWxOYW1lCgkJCQkJCXhTZXQtPmdldFByb3BlcnR5VmFsdWUoOjpydGw6Ok9VU3RyaW5nOjpjcmVhdGVGcm9tQXNjaWkoIlJlYWxOYW1lIikpID4+PSBhUmVhbE5hbWU7CgoJCQkJCQkvLyBjb21wYXJlIHRoZSBjb25kaXRpb24gZmllbGQgbmFtZSBhbmQgdGhlIFJlYWxOYW1lCgkJCQkJCWlmIChhQ29tcGFyZShhUmVhbE5hbWUsIHBSZWZWYWx1ZXNbal0uTmFtZSkpCgkJCQkJCQl4RmllbGQgPSB4U2V0OwoJCQkJCX0KCQkJCQlpZiAoIXhGaWVsZC5pcygpKQoJCQkJCXsKCQkJCQkJLy8gbm8gd2UgaGF2ZSB0byBjaGVjayBldmVyeSBjb2x1bW4gdG8gZmluZCB0aGUgcmVhbG5hbWUKCQkJCQkJUmVmZXJlbmNlPCBYSW5kZXhBY2Nlc3MgPiB4Q29sdW1uc0J5SW5kZXgoeFF1ZXJ5Q29sdW1ucywgVU5PX1FVRVJZKTsKCQkJCQkJZm9yIChzYWxfSW50MzIgbiA9IDAsIG5Db3VudCA9IHhDb2x1bW5zQnlJbmRleC0+Z2V0Q291bnQoKTsgbiA8IG5Db3VudDsgbisrKQoJCQkJCQl7CgkJCQkJCQl4Q29sdW1uc0J5SW5kZXgtPmdldEJ5SW5kZXgobikgPj49IHhTZXQ7CgkJCQkJCQl4U2V0LT5nZXRQcm9wZXJ0eVZhbHVlKDo6cnRsOjpPVVN0cmluZzo6Y3JlYXRlRnJvbUFzY2lpKCJSZWFsTmFtZSIpKSA+Pj0gYVJlYWxOYW1lOwoJCQkJCQkJaWYgKGFDb21wYXJlKGFSZWFsTmFtZSwgcFJlZlZhbHVlc1tqXS5OYW1lKSkKCQkJCQkJCXsKCQkJCQkJCQkvLyBnZXQgdGhlIGNvbHVtbiBieSBpdHMgYWxpYXMKCQkJCQkJCQl4RmllbGQgPSB4U2V0OwoJCQkJCQkJCWJyZWFrOwoJCQkJCQkJfQoJCQkJCQl9CgkJCQkJfQoJCQkJCWlmICgheEZpZWxkLmlzKCkpCgkJCQkJCWNvbnRpbnVlOwoJCQkJfQoJCQkJY2F0Y2ggKGNvbnN0IEV4Y2VwdGlvbiYpCgkJCQl7CgkJCQkJY29udGludWU7CgkJCQl9CgoJCQkJLy8gZmluZCB0aGUgdGV4dCBjb21wb25lbnQKCQkJCWZvciAoOjpzdGQ6OnZlY3RvcjxGbUZpZWxkSW5mbz46Oml0ZXJhdG9yIGl0ZXIgPSByRmllbGRJbmZvcy5iZWdpbigpOwoJCQkJCWl0ZXIgIT0gckZpZWxkSW5mb3MuZW5kKCk7IGl0ZXIrKykKCQkJCXsKCQkJCQkvLyB3ZSBmb3VuZCB0aGUgZmllbGQgc28gaW5zZXJ0IGEgbmV3IGVudHJ5IHRvIHRoZSBmaWx0ZXIgcm93CgkJCQkJaWYgKCgqaXRlcikueEZpZWxkID09IHhGaWVsZCkKCQkJCQl7CgkJCQkJCS8vIGRvIHdlIGFscmVhZHkgaGF2ZSB0aGUgY29udHJvbCA/CgkJCQkJCWlmIChhUm93LmZpbmQoKCppdGVyKS54VGV4dCkgIT0gYVJvdy5lbmQoKSkKCQkJCQkJewoJCQkJCQkJOjpydGw6Ok9VU3RyaW5nIGFDb21wVGV4dCA9IGFSb3dbKCppdGVyKS54VGV4dF07CgkJCQkJCQlhQ29tcFRleHQgKz0gOjpydGw6Ok9VU3RyaW5nOjpjcmVhdGVGcm9tQXNjaWkoIiAiKTsKCQkJCQkJCTo6cnRsOjpPU3RyaW5nIGFWYWwgPSBtX3hQYXJzZXItPmdldENvbnRleHQoKS5nZXRJbnRsS2V5d29yZEFzY2lpKE9QYXJzZUNvbnRleHQ6OktFWV9BTkQpOwoJCQkJCQkJYUNvbXBUZXh0ICs9IDo6cnRsOjpPVVN0cmluZyhhVmFsLmdldFN0cigpLGFWYWwuZ2V0TGVuZ3RoKCksUlRMX1RFWFRFTkNPRElOR19BU0NJSV9VUyk7CgkJCQkJCQlhQ29tcFRleHQgKz0gOjpydGw6Ok9VU3RyaW5nOjpjcmVhdGVGcm9tQXNjaWkoIiAiKTsKCQkJCQkJCWFDb21wVGV4dCArPSA6OmNvbXBoZWxwZXI6OmdldFN0cmluZyhwUmVmVmFsdWVzW2pdLlZhbHVlKTsKCQkJCQkJCWFSb3dbKCppdGVyKS54VGV4dF0gPSBhQ29tcFRleHQ7CgkJCQkJCX0KCQkJCQkJZWxzZQoJCQkJCQl7CgkJCQkJCQk6OnJ0bDo6T1VTdHJpbmcgc1ByZWRpY2F0ZSxzRXJyb3JNc2c7CgkJCQkJCQlwUmVmVmFsdWVzW2pdLlZhbHVlID4+PSBzUHJlZGljYXRlOwoJCQkJCQkJOjpydGw6OlJlZmVyZW5jZTwgSVNRTFBhcnNlTm9kZSA+IHhQYXJzZU5vZGUgPSBwcmVkaWNhdGVUcmVlKHNFcnJvck1zZywgc1ByZWRpY2F0ZSwgeEZvcm1hdHRlciwgeEZpZWxkKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICggeFBhcnNlTm9kZS5pcygpICkKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHsKCQkJCQkJCQk6OnJ0bDo6T1VTdHJpbmcgc0NyaXRlcmlhOwoJCQkJCQkJCXhQYXJzZU5vZGUtPnBhcnNlTm9kZVRvUHJlZGljYXRlU3RyKCBzQ3JpdGVyaWEKCQkJCQkJCQkJCQkJCQkJCQkseENvbm5lY3Rpb24KCQkJCQkJCQkJCQkJCQkJCQkseEZvcm1hdHRlcgoJCQkJCQkJCQkJCQkJCQkJCSx4RmllbGQKCQkJCQkJCQkJCQkJCQkJCQksYUFwcExvY2FsZQoJCQkJCQkJCQkJCQkJCQkJCSwoc2FsX0NoYXIpYUxvY2FsZVdyYXBwZXIuZ2V0TnVtRGVjaW1hbFNlcCgpLkdldENoYXIoMCkKCQkJCQkJCQkJCQkJCQkJCQksZ2V0UGFyc2VDb250ZXh0KCkpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFSb3dbKCppdGVyKS54VGV4dF0gPSBzQ3JpdGVyaWE7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CgkJCQkJCX0KCQkJCQl9CgkJCQl9CgkJCX0KCgkJCWlmIChhUm93LmVtcHR5KCkpCgkJCQljb250aW51ZTsKCiAgICAgICAgICAgIGltcGxfYWRkRmlsdGVyUm93KCBhUm93ICk7CgkJfQoJfQoKCS8vIG5vdyBzZXQgdGhlIGZpbHRlciBjb250cm9scwogICAgZm9yICggICA6OnN0ZDo6dmVjdG9yPEZtRmllbGRJbmZvPjo6aXRlcmF0b3IgZmllbGQgPSByRmllbGRJbmZvcy5iZWdpbigpOwogICAgICAgICAgICBmaWVsZCAhPSByRmllbGRJbmZvcy5lbmQoKTsKICAgICAgICAgICAgKytmaWVsZAogICAgICAgICkKICAgIHsKICAgICAgICBtX2FGaWx0ZXJDb21wb25lbnRzLnB1c2hfYmFjayggZmllbGQtPnhUZXh0ICk7CiAgICB9Cn0KCi8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCnZvaWQgRm9ybUNvbnRyb2xsZXI6OnN0YXJ0RmlsdGVyaW5nKCkKewogICAgT1NMX0VOU1VSRSggIWltcGxfaXNEaXNwb3NlZF9ub2ZhaWwoKSwgIkZvcm1Db250cm9sbGVyOiBhbHJlYWR5IGRpc3Bvc2VkISIgKTsKCglPU3RhdGljRGF0YUFjY2Vzc1Rvb2xzIGFTdGF0aWNUb29sczsKICAgIFJlZmVyZW5jZTwgWENvbm5lY3Rpb24gPiAgeENvbm5lY3Rpb24oIGFTdGF0aWNUb29scy5nZXRSb3dTZXRDb25uZWN0aW9uKCBSZWZlcmVuY2U8IFhSb3dTZXQgPiggbV94TW9kZWxBc0luZGV4LCBVTk9fUVVFUlkgKSApICk7CglpZiAoICF4Q29ubmVjdGlvbi5pcygpICkKCQkvLyBub3RoaW5nIHRvIGRvIC0gY2FuJ3QgZmlsdGVyIGEgZm9ybSB3aGljaCBpcyBub3QgY29ubmVjdGVkCgkJLy8gOTgwMjMgLSAxOS4wMy4yMDAyIC0gZnNAb3Blbm9mZmljZS5vcmcKCQlyZXR1cm47CgogICAgLy8gc3RvcCBsaXN0ZW5pbmcgZm9yIGNvbnRyb2xzCiAgICBpZiAoaXNMaXN0ZW5pbmdGb3JDaGFuZ2VzKCkpCiAgICAgICAgc3RvcExpc3RlbmluZygpOwoKICAgIG1fYkZpbHRlcmluZyA9IHNhbF9UcnVlOwoKICAgIC8vIGFzIHdlIGRvbid0IHdhbnQgbmV3IGNvbnRyb2xzIHRvIGJlIGF0dGFjaGVkIHRvIHRoZSBzY3JpcHRpbmcgZW52aXJvbm1lbnQKICAgIC8vIHdlIGNoYW5nZSBhdHRhY2ggZmxhZ3MKICAgIG1fYkF0dGFjaEV2ZW50cyA9IHNhbF9GYWxzZTsKCiAgICAvLyBBdXN0YXVzY2hlbiBkZXIgS29udHJvbHMgZnVlciBkYXMgYWt0dWVsbGUgRm9ybXVsYXIKICAgIFNlcXVlbmNlPCBSZWZlcmVuY2U8IFhDb250cm9sID4gPiBhQ29udHJvbHNDb3B5KCBtX2FDb250cm9scyApOwogICAgY29uc3QgUmVmZXJlbmNlPCBYQ29udHJvbCA+KiBwQ29udHJvbHMgPSBhQ29udHJvbHNDb3B5LmdldENvbnN0QXJyYXkoKTsKICAgIHNhbF9JbnQzMiBuQ29udHJvbENvdW50ID0gYUNvbnRyb2xzQ29weS5nZXRMZW5ndGgoKTsKCiAgICAvLyB0aGUgY29udHJvbCB3ZSBoYXZlIHRvIGFjdGl2YXRlIGFmdGVyIHJlcGxhY2VtZW50CiAgICBSZWZlcmVuY2U8IFhEYXRhYmFzZU1ldGFEYXRhID4gIHhNZXRhRGF0YSh4Q29ubmVjdGlvbi0+Z2V0TWV0YURhdGEoKSk7CiAgICBSZWZlcmVuY2U8IFhOdW1iZXJGb3JtYXRzU3VwcGxpZXIgPiAgeEZvcm1hdFN1cHBsaWVyID0gYVN0YXRpY1Rvb2xzLmdldE51bWJlckZvcm1hdHMoeENvbm5lY3Rpb24sIHNhbF9UcnVlKTsKICAgIFJlZmVyZW5jZTwgWE51bWJlckZvcm1hdHRlciA+ICB4Rm9ybWF0dGVyKCBtX2FDb250ZXh0LmNyZWF0ZUNvbXBvbmVudCggImNvbS5zdW4uc3Rhci51dGlsLk51bWJlckZvcm1hdHRlciIgKSwgVU5PX1FVRVJZICk7CiAgICB4Rm9ybWF0dGVyLT5hdHRhY2hOdW1iZXJGb3JtYXRzU3VwcGxpZXIoeEZvcm1hdFN1cHBsaWVyKTsKCiAgICAvLyBzdHJ1Y3R1cmUgZm9yIHN0b3JpbmcgdGhlIGZpZWxkIGluZm8KICAgIDo6c3RkOjp2ZWN0b3I8Rm1GaWVsZEluZm8+IGFGaWVsZEluZm9zOwoKICAgIGZvciAoc2FsX0ludDMyIGkgPSBuQ29udHJvbENvdW50OyBpID4gMDspCiAgICB7CiAgICAgICAgUmVmZXJlbmNlPCBYQ29udHJvbCA+IHhDb250cm9sID0gcENvbnRyb2xzWy0taV07CiAgICAgICAgaWYgKHhDb250cm9sLmlzKCkpCiAgICAgICAgewogICAgICAgICAgICAvLyBubyBldmVudHMgZm9yIHRoZSBjb250cm9sIGFueW1vcmUKICAgICAgICAgICAgcmVtb3ZlRnJvbUV2ZW50QXR0YWNoZXIoeENvbnRyb2wpOwoKICAgICAgICAgICAgLy8gZG8gd2UgaGF2ZSBhIG1vZGUgc2VsZWN0b3IKICAgICAgICAgICAgUmVmZXJlbmNlPCBYTW9kZVNlbGVjdG9yID4gIHhTZWxlY3Rvcih4Q29udHJvbCwgVU5PX1FVRVJZKTsKICAgICAgICAgICAgaWYgKHhTZWxlY3Rvci5pcygpKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICB4U2VsZWN0b3ItPnNldE1vZGUoIDo6cnRsOjpPVVN0cmluZyggUlRMX0NPTlNUQVNDSUlfVVNUUklOR1BBUkFNKCAiRmlsdGVyTW9kZSIgKSApICk7CgogICAgICAgICAgICAgICAgLy8gbGlzdGVuaW5nIGZvciBuZXcgY29udHJvbHMgb2YgdGhlIHNlbGVjdG9yCiAgICAgICAgICAgICAgICBSZWZlcmVuY2U8IFhDb250YWluZXIgPiAgeENvbnRhaW5lcih4U2VsZWN0b3IsIFVOT19RVUVSWSk7CiAgICAgICAgICAgICAgICBpZiAoeENvbnRhaW5lci5pcygpKQogICAgICAgICAgICAgICAgICAgIHhDb250YWluZXItPmFkZENvbnRhaW5lckxpc3RlbmVyKHRoaXMpOwoKICAgICAgICAgICAgICAgIFJlZmVyZW5jZTwgWEVudW1lcmF0aW9uQWNjZXNzID4gIHhFbGVtZW50QWNjZXNzKHhTZWxlY3RvciwgVU5PX1FVRVJZKTsKICAgICAgICAgICAgICAgIGlmICh4RWxlbWVudEFjY2Vzcy5pcygpKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIFJlZmVyZW5jZTwgWEVudW1lcmF0aW9uID4gIHhFbnVtZXJhdGlvbih4RWxlbWVudEFjY2Vzcy0+Y3JlYXRlRW51bWVyYXRpb24oKSk7CiAgICAgICAgICAgICAgICAgICAgUmVmZXJlbmNlPCBYQ29udHJvbCA+ICB4U3ViQ29udHJvbDsKICAgICAgICAgICAgICAgICAgICB3aGlsZSAoeEVudW1lcmF0aW9uLT5oYXNNb3JlRWxlbWVudHMoKSkKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIHhFbnVtZXJhdGlvbi0+bmV4dEVsZW1lbnQoKSA+Pj0geFN1YkNvbnRyb2w7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmICh4U3ViQ29udHJvbC5pcygpKQogICAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBSZWZlcmVuY2U8IFhQcm9wZXJ0eVNldCA+ICB4U2V0KHhTdWJDb250cm9sLT5nZXRNb2RlbCgpLCBVTk9fUVVFUlkpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHhTZXQuaXMoKSAmJiA6OmNvbXBoZWxwZXI6Omhhc1Byb3BlcnR5KEZNX1BST1BfQk9VTkRGSUVMRCwgeFNldCkpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gZG9lcyB0aGUgbW9kZWwgdXNlIGEgYm91bmQgZmllbGQgPwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFJlZmVyZW5jZTwgWFByb3BlcnR5U2V0ID4gIHhGaWVsZDsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB4U2V0LT5nZXRQcm9wZXJ0eVZhbHVlKEZNX1BST1BfQk9VTkRGSUVMRCkgPj49IHhGaWVsZDsKCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUmVmZXJlbmNlPCBYVGV4dENvbXBvbmVudCA+ICB4VGV4dCh4U3ViQ29udHJvbCwgVU5PX1FVRVJZKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBtYXkgd2UgZmlsdGVyIHRoZSBmaWVsZD8KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoeFRleHQuaXMoKSAmJiB4RmllbGQuaXMoKSAmJiA6OmNvbXBoZWxwZXI6Omhhc1Byb3BlcnR5KEZNX1BST1BfU0VBUkNIQUJMRSwgeEZpZWxkKSAmJgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA6OmNvbXBoZWxwZXI6OmdldEJPT0woeEZpZWxkLT5nZXRQcm9wZXJ0eVZhbHVlKEZNX1BST1BfU0VBUkNIQUJMRSkpKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYUZpZWxkSW5mb3MucHVzaF9iYWNrKEZtRmllbGRJbmZvKHhGaWVsZCwgeFRleHQpKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeFRleHQtPmFkZFRleHRMaXN0ZW5lcih0aGlzKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgUmVmZXJlbmNlPCBYUHJvcGVydHlTZXQgPiAgeE1vZGVsKCB4Q29udHJvbC0+Z2V0TW9kZWwoKSwgVU5PX1FVRVJZICk7CiAgICAgICAgICAgIGlmICh4TW9kZWwuaXMoKSAmJiA6OmNvbXBoZWxwZXI6Omhhc1Byb3BlcnR5KEZNX1BST1BfQk9VTkRGSUVMRCwgeE1vZGVsKSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgLy8gZG9lcyB0aGUgbW9kZWwgdXNlIGEgYm91bmQgZmllbGQgPwogICAgICAgICAgICAgICAgQW55IGFWYWwgPSB4TW9kZWwtPmdldFByb3BlcnR5VmFsdWUoRk1fUFJPUF9CT1VOREZJRUxEKTsKICAgICAgICAgICAgICAgIFJlZmVyZW5jZTwgWFByb3BlcnR5U2V0ID4gIHhGaWVsZDsKICAgICAgICAgICAgICAgIGFWYWwgPj49IHhGaWVsZDsKCiAgICAgICAgICAgICAgICAvLyBtYXkgd2UgZmlsdGVyIHRoZSBmaWVsZD8KCiAgICAgICAgICAgICAgICBpZiAgKCAgIHhGaWVsZC5pcygpCiAgICAgICAgICAgICAgICAgICAgJiYgIDo6Y29tcGhlbHBlcjo6aGFzUHJvcGVydHkoIEZNX1BST1BfU0VBUkNIQUJMRSwgeEZpZWxkICkKICAgICAgICAgICAgICAgICAgICAmJiA6OmNvbXBoZWxwZXI6OmdldEJPT0woIHhGaWVsZC0+Z2V0UHJvcGVydHlWYWx1ZSggRk1fUFJPUF9TRUFSQ0hBQkxFICkgKQogICAgICAgICAgICAgICAgICAgICkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAvLyBjcmVhdGUgYSBmaWx0ZXIgY29udHJvbAogICAgICAgICAgICAgICAgICAgIFNlcXVlbmNlPCBBbnkgPiBhQ3JlYXRpb25BcmdzKCAzICk7CiAgICAgICAgICAgICAgICAgICAgYUNyZWF0aW9uQXJnc1sgMCBdIDw8PSBOYW1lZFZhbHVlKCA6OnJ0bDo6T1VTdHJpbmc6OmNyZWF0ZUZyb21Bc2NpaSggIk1lc3NhZ2VQYXJlbnQiICksIG1ha2VBbnkoIFZDTFVub0hlbHBlcjo6R2V0SW50ZXJmYWNlKCBnZXREaWFsb2dQYXJlbnRXaW5kb3coKSApICkgKTsKICAgICAgICAgICAgICAgICAgICBhQ3JlYXRpb25BcmdzWyAxIF0gPDw9IE5hbWVkVmFsdWUoIDo6cnRsOjpPVVN0cmluZzo6Y3JlYXRlRnJvbUFzY2lpKCAiTnVtYmVyRm9ybWF0dGVyIiApLCBtYWtlQW55KCB4Rm9ybWF0dGVyICkgKTsKICAgICAgICAgICAgICAgICAgICBhQ3JlYXRpb25BcmdzWyAyIF0gPDw9IE5hbWVkVmFsdWUoIDo6cnRsOjpPVVN0cmluZzo6Y3JlYXRlRnJvbUFzY2lpKCAiQ29udHJvbE1vZGVsIiApLCBtYWtlQW55KCB4TW9kZWwgKSApOwogICAgICAgICAgICAgICAgICAgIFJlZmVyZW5jZTwgWENvbnRyb2wgPiB4RmlsdGVyQ29udHJvbCgKICAgICAgICAgICAgICAgICAgICAgICAgbV9hQ29udGV4dC5jcmVhdGVDb21wb25lbnRXaXRoQXJndW1lbnRzKCAiY29tLnN1bi5zdGFyLmZvcm0uY29udHJvbC5GaWx0ZXJDb250cm9sIiwgYUNyZWF0aW9uQXJncyApLAogICAgICAgICAgICAgICAgICAgICAgICBVTk9fUVVFUlkKICAgICAgICAgICAgICAgICAgICApOwogICAgICAgICAgICAgICAgICAgIERCR19BU1NFUlQoIHhGaWx0ZXJDb250cm9sLmlzKCksICJGb3JtQ29udHJvbGxlcjo6c3RhcnRGaWx0ZXJpbmc6IGNvdWxkIG5vdCBjcmVhdGUgYSBmaWx0ZXIgY29udHJvbCEiICk7CgogICAgICAgICAgICAgICAgICAgIGlmICggcmVwbGFjZUNvbnRyb2woIHhDb250cm9sLCB4RmlsdGVyQ29udHJvbCApICkKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIFJlZmVyZW5jZTwgWFRleHRDb21wb25lbnQgPiB4RmlsdGVyVGV4dCggeEZpbHRlckNvbnRyb2wsIFVOT19RVUVSWSApOwogICAgICAgICAgICAgICAgICAgICAgICBhRmllbGRJbmZvcy5wdXNoX2JhY2soIEZtRmllbGRJbmZvKCB4RmllbGQsIHhGaWx0ZXJUZXh0ICkgKTsKICAgICAgICAgICAgICAgICAgICAgICAgeEZpbHRlclRleHQtPmFkZFRleHRMaXN0ZW5lcih0aGlzKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZWxzZQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAvLyBhYm1lbGRlbiB2b20gRXZlbnRNYW5hZ2VyCiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9CgogICAgLy8gd2UgaGF2ZSBhbGwgZmlsdGVyIGNvbnRyb2xzIG5vdywgc28gdGhlIG5leHQgc3RlcCBpcyB0byByZWFkIHRoZSBmaWx0ZXJzIGZyb20gdGhlIGZvcm0KICAgIC8vIHJlc29sdmUgYWxsIGFsaWFzZXMgYW5kIHNldCB0aGUgY3VycmVudCBmaWx0ZXIgdG8gdGhlIGFjY29yZGluZyBzdHJ1Y3R1cmUKICAgIHNldEZpbHRlcihhRmllbGRJbmZvcyk7CgogICAgUmVmZXJlbmNlPCBYUHJvcGVydHlTZXQgPiB4U2V0KCBtX3hNb2RlbEFzSW5kZXgsIFVOT19RVUVSWSApOwoJaWYgKCB4U2V0LmlzKCkgKQoJCXN0b3BGb3JtTGlzdGVuaW5nKCB4U2V0LCBzYWxfVHJ1ZSApOwoKICAgIGltcGxfc2V0VGV4dE9uQWxsRmlsdGVyX3Rocm93KCk7CgogICAgLy8gbG9jayBhbGwgY29udHJvbHMgd2hpY2ggYXJlIG5vdCB1c2VkIGZvciBmaWx0ZXJpbmcKICAgIG1fYkxvY2tlZCA9IGRldGVybWluZUxvY2tTdGF0ZSgpOwogICAgc2V0TG9ja3MoKTsKICAgIG1fYkF0dGFjaEV2ZW50cyA9IHNhbF9UcnVlOwp9CgovLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQp2b2lkIEZvcm1Db250cm9sbGVyOjpzdG9wRmlsdGVyaW5nKCkKewogICAgT1NMX0VOU1VSRSggIWltcGxfaXNEaXNwb3NlZF9ub2ZhaWwoKSwgIkZvcm1Db250cm9sbGVyOiBhbHJlYWR5IGRpc3Bvc2VkISIgKTsKCWlmICggIW1fYkZpbHRlcmluZyApIC8vICMxMDQ2OTMjIE9KCgl7CS8vIG5vdGhpbmcgdG8gZG8KCQlyZXR1cm47Cgl9CgogICAgbV9iRmlsdGVyaW5nID0gc2FsX0ZhbHNlOwogICAgbV9iRGV0YWNoRXZlbnRzID0gc2FsX0ZhbHNlOwoKICAgIDo6Y29tcGhlbHBlcjo6ZGlzcG9zZUNvbXBvbmVudChtX3hDb21wb3Nlcik7CgogICAgLy8gQXVzdGF1c2NoZW4gZGVyIEtvbnRyb2xzIGZ1ZXIgZGFzIGFrdHVlbGxlIEZvcm11bGFyCiAgICBTZXF1ZW5jZTwgUmVmZXJlbmNlPCBYQ29udHJvbCA+ID4gYUNvbnRyb2xzQ29weSggbV9hQ29udHJvbHMgKTsKICAgIGNvbnN0IFJlZmVyZW5jZTwgWENvbnRyb2wgPiAqIHBDb250cm9scyA9IGFDb250cm9sc0NvcHkuZ2V0Q29uc3RBcnJheSgpOwogICAgc2FsX0ludDMyIG5Db250cm9sQ291bnQgPSBhQ29udHJvbHNDb3B5LmdldExlbmd0aCgpOwoKICAgIC8vIGNsZWFyIHRoZSBmaWx0ZXIgY29udHJvbCBtYXAKICAgIDo6c3RkOjpmb3JfZWFjaCggbV9hRmlsdGVyQ29tcG9uZW50cy5iZWdpbigpLCBtX2FGaWx0ZXJDb21wb25lbnRzLmVuZCgpLCBSZW1vdmVDb21wb25lbnRUZXh0TGlzdGVuZXIoIHRoaXMgKSApOwogICAgbV9hRmlsdGVyQ29tcG9uZW50cy5jbGVhcigpOwoKICAgIGZvciAoIHNhbF9JbnQzMiBpID0gbkNvbnRyb2xDb3VudDsgaSA+IDA7ICkKICAgIHsKICAgICAgICBSZWZlcmVuY2U8IFhDb250cm9sID4geENvbnRyb2wgPSBwQ29udHJvbHNbLS1pXTsKICAgICAgICBpZiAoeENvbnRyb2wuaXMoKSkKICAgICAgICB7CiAgICAgICAgICAgIC8vIG5vdyBlbmFibGUgZXZlbnRoYW5kbGluZyBhZ2FpbgogICAgICAgICAgICBhZGRUb0V2ZW50QXR0YWNoZXIoeENvbnRyb2wpOwoKICAgICAgICAgICAgUmVmZXJlbmNlPCBYTW9kZVNlbGVjdG9yID4gIHhTZWxlY3Rvcih4Q29udHJvbCwgVU5PX1FVRVJZKTsKICAgICAgICAgICAgaWYgKHhTZWxlY3Rvci5pcygpKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICB4U2VsZWN0b3ItPnNldE1vZGUoIDo6cnRsOjpPVVN0cmluZyggUlRMX0NPTlNUQVNDSUlfVVNUUklOR1BBUkFNKCAiRGF0YU1vZGUiICkgKSApOwoKICAgICAgICAgICAgICAgIC8vIGxpc3RlbmluZyBmb3IgbmV3IGNvbnRyb2xzIG9mIHRoZSBzZWxlY3RvcgogICAgICAgICAgICAgICAgUmVmZXJlbmNlPCBYQ29udGFpbmVyID4gIHhDb250YWluZXIoeFNlbGVjdG9yLCBVTk9fUVVFUlkpOwogICAgICAgICAgICAgICAgaWYgKHhDb250YWluZXIuaXMoKSkKICAgICAgICAgICAgICAgICAgICB4Q29udGFpbmVyLT5yZW1vdmVDb250YWluZXJMaXN0ZW5lcih0aGlzKTsKICAgICAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgICB9CgogICAgICAgICAgICBSZWZlcmVuY2U8IFhQcm9wZXJ0eVNldCA+ICB4U2V0KHhDb250cm9sLT5nZXRNb2RlbCgpLCBVTk9fUVVFUlkpOwogICAgICAgICAgICBpZiAoeFNldC5pcygpICYmIDo6Y29tcGhlbHBlcjo6aGFzUHJvcGVydHkoRk1fUFJPUF9CT1VOREZJRUxELCB4U2V0KSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgLy8gZG9lcyB0aGUgbW9kZWwgdXNlIGEgYm91bmQgZmllbGQgPwogICAgICAgICAgICAgICAgUmVmZXJlbmNlPCBYUHJvcGVydHlTZXQgPiAgeEZpZWxkOwogICAgICAgICAgICAgICAgeFNldC0+Z2V0UHJvcGVydHlWYWx1ZShGTV9QUk9QX0JPVU5ERklFTEQpID4+PSB4RmllbGQ7CgogICAgICAgICAgICAgICAgLy8gbWF5IHdlIGZpbHRlciB0aGUgZmllbGQ/CiAgICAgICAgICAgICAgICBpZiAgKCAgIHhGaWVsZC5pcygpCiAgICAgICAgICAgICAgICAgICAgJiYgIDo6Y29tcGhlbHBlcjo6aGFzUHJvcGVydHkoIEZNX1BST1BfU0VBUkNIQUJMRSwgeEZpZWxkICkKICAgICAgICAgICAgICAgICAgICAmJiAgOjpjb21waGVscGVyOjpnZXRCT09MKCB4RmllbGQtPmdldFByb3BlcnR5VmFsdWUoIEZNX1BST1BfU0VBUkNIQUJMRSApICkKICAgICAgICAgICAgICAgICAgICApCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgOjpydGw6Ok9VU3RyaW5nIHNTZXJ2aWNlTmFtZTsKICAgICAgICAgICAgICAgICAgICBPU0xfVkVSSUZZKCB4U2V0LT5nZXRQcm9wZXJ0eVZhbHVlKCBGTV9QUk9QX0RFRkFVTFRDT05UUk9MICkgPj49IHNTZXJ2aWNlTmFtZSApOwogICAgICAgICAgICAgICAgICAgIFJlZmVyZW5jZTwgWENvbnRyb2wgPiB4TmV3Q29udHJvbCggbV9hQ29udGV4dC5jcmVhdGVDb21wb25lbnQoIHNTZXJ2aWNlTmFtZSApLCBVTk9fUVVFUlkgKTsKICAgICAgICAgICAgICAgICAgICByZXBsYWNlQ29udHJvbCggeENvbnRyb2wsIHhOZXdDb250cm9sICk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9CgogICAgUmVmZXJlbmNlPCBYUHJvcGVydHlTZXQgPiAgeFNldCggbV94TW9kZWxBc0luZGV4LCBVTk9fUVVFUlkgKTsKICAgIGlmICggeFNldC5pcygpICkKCQlzdGFydEZvcm1MaXN0ZW5pbmcoIHhTZXQsIHNhbF9UcnVlICk7CgogICAgbV9iRGV0YWNoRXZlbnRzID0gc2FsX1RydWU7CgogICAgbV9hRmlsdGVyUm93cy5jbGVhcigpOwogICAgbV9uQ3VycmVudEZpbHRlclBvc2l0aW9uID0gLTE7CgogICAgLy8gcmVsZWFzZSB0aGUgbG9ja3MgaWYgcG9zc2libGUKICAgIC8vIGxvY2sgYWxsIGNvbnRyb2xzIHdoaWNoIGFyZSBub3QgdXNlZCBmb3IgZmlsdGVyaW5nCiAgICBtX2JMb2NrZWQgPSBkZXRlcm1pbmVMb2NrU3RhdGUoKTsKICAgIHNldExvY2tzKCk7CgogICAgLy8gcmVzdGFydCBsaXN0ZW5pbmcgZm9yIGNvbnRyb2wgbW9kaWZpY2F0aW9ucwogICAgaWYgKGlzTGlzdGVuaW5nRm9yQ2hhbmdlcygpKQogICAgICAgIHN0YXJ0TGlzdGVuaW5nKCk7Cn0KCi8vIFhNb2RlU2VsZWN0b3IKLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0Kdm9pZCBGb3JtQ29udHJvbGxlcjo6c2V0TW9kZShjb25zdCA6OnJ0bDo6T1VTdHJpbmcmIE1vZGUpIHRocm93KCBOb1N1cHBvcnRFeGNlcHRpb24sIFJ1bnRpbWVFeGNlcHRpb24gKQp7CiAgICA6Om9zbDo6TXV0ZXhHdWFyZCBhR3VhcmQoIG1fYU11dGV4ICk7CiAgICBpbXBsX2NoZWNrRGlzcG9zZWRfdGhyb3coKTsKCiAgICBpZiAoIXN1cHBvcnRzTW9kZShNb2RlKSkKICAgICAgICB0aHJvdyBOb1N1cHBvcnRFeGNlcHRpb24oKTsKCiAgICBpZiAoTW9kZSA9PSBtX2FNb2RlKQogICAgICAgIHJldHVybjsKCiAgICBtX2FNb2RlID0gTW9kZTsKCiAgICBpZiAoIE1vZGUuZXF1YWxzQXNjaWkoICJGaWx0ZXJNb2RlIiApICkKICAgICAgICBzdGFydEZpbHRlcmluZygpOwogICAgZWxzZQogICAgICAgIHN0b3BGaWx0ZXJpbmcoKTsKCiAgICBmb3IgKEZtRm9ybUNvbnRyb2xsZXJzOjpjb25zdF9pdGVyYXRvciBpID0gbV9hQ2hpbGRzLmJlZ2luKCk7CiAgICAgICAgaSAhPSBtX2FDaGlsZHMuZW5kKCk7ICsraSkKICAgIHsKCQlSZWZlcmVuY2U8IFhNb2RlU2VsZWN0b3IgPiB4TW9kZSgqaSwgVU5PX1FVRVJZKTsKCQlpZiAoIHhNb2RlLmlzKCkgKQoJCQl4TW9kZS0+c2V0TW9kZShNb2RlKTsKICAgIH0KfQoKLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KOjpydGw6Ok9VU3RyaW5nIFNBTF9DQUxMIEZvcm1Db250cm9sbGVyOjpnZXRNb2RlKHZvaWQpIHRocm93KCBSdW50aW1lRXhjZXB0aW9uICkKewogICAgOjpvc2w6Ok11dGV4R3VhcmQgYUd1YXJkKCBtX2FNdXRleCApOwogICAgaW1wbF9jaGVja0Rpc3Bvc2VkX3Rocm93KCk7CgogICAgcmV0dXJuIG1fYU1vZGU7Cn0KCi8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tClNlcXVlbmNlPCA6OnJ0bDo6T1VTdHJpbmcgPiBTQUxfQ0FMTCBGb3JtQ29udHJvbGxlcjo6Z2V0U3VwcG9ydGVkTW9kZXModm9pZCkgdGhyb3coIFJ1bnRpbWVFeGNlcHRpb24gKQp7CiAgICA6Om9zbDo6TXV0ZXhHdWFyZCBhR3VhcmQoIG1fYU11dGV4ICk7CiAgICBpbXBsX2NoZWNrRGlzcG9zZWRfdGhyb3coKTsKCiAgICBzdGF0aWMgU2VxdWVuY2U8IDo6cnRsOjpPVVN0cmluZyA+IGFNb2RlczsKICAgIGlmICghYU1vZGVzLmdldExlbmd0aCgpKQogICAgewogICAgICAgIGFNb2Rlcy5yZWFsbG9jKDIpOwogICAgICAgIDo6cnRsOjpPVVN0cmluZyogcE1vZGVzID0gYU1vZGVzLmdldEFycmF5KCk7CiAgICAgICAgcE1vZGVzWzBdID0gOjpydGw6Ok9VU3RyaW5nKCBSVExfQ09OU1RBU0NJSV9VU1RSSU5HUEFSQU0oICJEYXRhTW9kZSIgKSApOwogICAgICAgIHBNb2Rlc1sxXSA9IDo6cnRsOjpPVVN0cmluZyggUlRMX0NPTlNUQVNDSUlfVVNUUklOR1BBUkFNKCAiRmlsdGVyTW9kZSIgKSApOwogICAgfQogICAgcmV0dXJuIGFNb2RlczsKfQoKLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0Kc2FsX0Jvb2wgU0FMX0NBTEwgRm9ybUNvbnRyb2xsZXI6OnN1cHBvcnRzTW9kZShjb25zdCA6OnJ0bDo6T1VTdHJpbmcmIE1vZGUpIHRocm93KCBSdW50aW1lRXhjZXB0aW9uICkKewogICAgOjpvc2w6Ok11dGV4R3VhcmQgYUd1YXJkKCBtX2FNdXRleCApOwogICAgaW1wbF9jaGVja0Rpc3Bvc2VkX3Rocm93KCk7CgogICAgU2VxdWVuY2U8IDo6cnRsOjpPVVN0cmluZyA+IGFNb2RlcyhnZXRTdXBwb3J0ZWRNb2RlcygpKTsKICAgIGNvbnN0IDo6cnRsOjpPVVN0cmluZyogcE1vZGVzID0gYU1vZGVzLmdldENvbnN0QXJyYXkoKTsKICAgIGZvciAoc2FsX0ludDMyIGkgPSBhTW9kZXMuZ2V0TGVuZ3RoKCk7IGkgPiAwOyApCiAgICB7CiAgICAgICAgaWYgKHBNb2Rlc1stLWldID09IE1vZGUpCiAgICAgICAgICAgIHJldHVybiBzYWxfVHJ1ZTsKICAgIH0KICAgIHJldHVybiBzYWxfRmFsc2U7Cn0KCi8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCldpbmRvdyogRm9ybUNvbnRyb2xsZXI6OmdldERpYWxvZ1BhcmVudFdpbmRvdygpCnsKICAgIE9TTF9FTlNVUkUoICFpbXBsX2lzRGlzcG9zZWRfbm9mYWlsKCksICJGb3JtQ29udHJvbGxlcjogYWxyZWFkeSBkaXNwb3NlZCEiICk7CiAgICBXaW5kb3cqIHBQYXJlbnRXaW5kb3cgPSBOVUxMOwogICAgdHJ5CiAgICB7CiAgICAgICAgUmVmZXJlbmNlPCBYQ29udHJvbCA+IHhDb250YWluZXJDb250cm9sKCBnZXRDb250YWluZXIoKSwgVU5PX1FVRVJZX1RIUk9XICk7CiAgICAgICAgUmVmZXJlbmNlPCBYV2luZG93UGVlciA+IHhDb250YWluZXJQZWVyKCB4Q29udGFpbmVyQ29udHJvbC0+Z2V0UGVlcigpLCBVTk9fUVVFUllfVEhST1cgKTsKICAgICAgICBwUGFyZW50V2luZG93ID0gVkNMVW5vSGVscGVyOjpHZXRXaW5kb3coIHhDb250YWluZXJQZWVyICk7CiAgICB9CiAgICBjYXRjaCggY29uc3QgRXhjZXB0aW9uJiApCiAgICB7CgkgICAgREJHX1VOSEFORExFRF9FWENFUFRJT04oKTsKICAgIH0KICAgIHJldHVybiBwUGFyZW50V2luZG93Owp9Ci8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCmJvb2wgRm9ybUNvbnRyb2xsZXI6OmNoZWNrRm9ybUNvbXBvbmVudFZhbGlkaXR5KCA6OnJ0bDo6T1VTdHJpbmcmIC8qIFtvdXRdICovIF9yRmlyc3RJbnZhbGlkaXR5RXhwbGFuYXRpb24sIFJlZmVyZW5jZTwgWENvbnRyb2xNb2RlbCA+JiAvKiBbb3V0XSAqLyBfcnhGaXJzdEludmFsaWRNb2RlbCApIFNBTF9USFJPVygoKSkKewogICAgdHJ5CiAgICB7CiAgICAgICAgUmVmZXJlbmNlPCBYRW51bWVyYXRpb25BY2Nlc3MgPiB4Q29udHJvbEVudW1BY2MoIGdldE1vZGVsKCksIFVOT19RVUVSWSApOwogICAgICAgIFJlZmVyZW5jZTwgWEVudW1lcmF0aW9uID4geENvbnRyb2xFbnVtZXJhdGlvbjsKICAgICAgICBpZiAoIHhDb250cm9sRW51bUFjYy5pcygpICkKICAgICAgICAgICAgeENvbnRyb2xFbnVtZXJhdGlvbiA9IHhDb250cm9sRW51bUFjYy0+Y3JlYXRlRW51bWVyYXRpb24oKTsKICAgICAgICBPU0xfRU5TVVJFKCB4Q29udHJvbEVudW1lcmF0aW9uLmlzKCksICJGb3JtQ29udHJvbGxlcjo6Y2hlY2tGb3JtQ29tcG9uZW50VmFsaWRpdHk6IGNhbm5vdCBlbnVtZXJhdGUgdGhlIGNvbnRyb2xzISIgKTsKICAgICAgICBpZiAoICF4Q29udHJvbEVudW1lcmF0aW9uLmlzKCkgKQogICAgICAgICAgICAvLyBhc3N1bWUgYWxsIHZhbGlkCiAgICAgICAgICAgIHJldHVybiB0cnVlOwoKICAgICAgICBSZWZlcmVuY2U8IFhWYWxpZGF0YWJsZUZvcm1Db21wb25lbnQgPiB4VmFsaWRhdGFibGU7CiAgICAgICAgd2hpbGUgKCB4Q29udHJvbEVudW1lcmF0aW9uLT5oYXNNb3JlRWxlbWVudHMoKSApCiAgICAgICAgewogICAgICAgICAgICBpZiAoICEoIHhDb250cm9sRW51bWVyYXRpb24tPm5leHRFbGVtZW50KCkgPj49IHhWYWxpZGF0YWJsZSApICkKICAgICAgICAgICAgICAgIC8vIGNvbnRyb2wgZG9lcyBub3Qgc3VwcG9ydCB2YWxpZGF0aW9uCiAgICAgICAgICAgICAgICBjb250aW51ZTsKCiAgICAgICAgICAgIGlmICggeFZhbGlkYXRhYmxlLT5pc1ZhbGlkKCkgKQogICAgICAgICAgICAgICAgY29udGludWU7CgogICAgICAgICAgICBSZWZlcmVuY2U8IFhWYWxpZGF0b3IgPiB4VmFsaWRhdG9yKCB4VmFsaWRhdGFibGUtPmdldFZhbGlkYXRvcigpICk7CiAgICAgICAgICAgIE9TTF9FTlNVUkUoIHhWYWxpZGF0b3IuaXMoKSwgIkZvcm1Db250cm9sbGVyOjpjaGVja0Zvcm1Db21wb25lbnRWYWxpZGl0eTogaW52YWxpZCwgYnV0IG5vIHZhbGlkYXRvcj8iICk7CiAgICAgICAgICAgIGlmICggIXhWYWxpZGF0b3IuaXMoKSApCiAgICAgICAgICAgICAgICAvLyB0aGlzIHZpb2xhdGVzIHRoZSBpbnRlcmZhY2UgZGVmaW5pdGlvbiBvZiBjc3MuZm9ybS52YWxpZGF0aW9uLlhWYWxpZGF0YWJsZUZvcm1Db21wb25lbnQgLi4uCiAgICAgICAgICAgICAgICBjb250aW51ZTsKCiAgICAgICAgICAgIF9yRmlyc3RJbnZhbGlkaXR5RXhwbGFuYXRpb24gPSB4VmFsaWRhdG9yLT5leHBsYWluSW52YWxpZCggeFZhbGlkYXRhYmxlLT5nZXRDdXJyZW50VmFsdWUoKSApOwogICAgICAgICAgICBfcnhGaXJzdEludmFsaWRNb2RlbCA9IF9yeEZpcnN0SW52YWxpZE1vZGVsLnF1ZXJ5KCB4VmFsaWRhdGFibGUgKTsKICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgIH0KICAgIH0KICAgIGNhdGNoKCBjb25zdCBFeGNlcHRpb24mICkKICAgIHsKICAgICAgICBEQkdfVU5IQU5ETEVEX0VYQ0VQVElPTigpOwogICAgfQogICAgcmV0dXJuIHRydWU7Cn0KCi8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tClJlZmVyZW5jZTwgWENvbnRyb2wgPiBGb3JtQ29udHJvbGxlcjo6bG9jYXRlQ29udHJvbCggY29uc3QgUmVmZXJlbmNlPCBYQ29udHJvbE1vZGVsID4mIF9yeE1vZGVsICkgU0FMX1RIUk9XKCgpKQp7CiAgICB0cnkKICAgIHsKICAgICAgICBTZXF1ZW5jZTwgUmVmZXJlbmNlPCBYQ29udHJvbCA+ID4gYUNvbnRyb2xzKCBnZXRDb250cm9scygpICk7CiAgICAgICAgY29uc3QgUmVmZXJlbmNlPCBYQ29udHJvbCA+KiBwQ29udHJvbHMgPSBhQ29udHJvbHMuZ2V0Q29uc3RBcnJheSgpOwogICAgICAgIGNvbnN0IFJlZmVyZW5jZTwgWENvbnRyb2wgPiogcENvbnRyb2xzRW5kID0gYUNvbnRyb2xzLmdldENvbnN0QXJyYXkoKSArIGFDb250cm9scy5nZXRMZW5ndGgoKTsKCiAgICAgICAgZm9yICggOyBwQ29udHJvbHMgIT0gcENvbnRyb2xzRW5kOyArK3BDb250cm9scyApCiAgICAgICAgewogICAgICAgICAgICBPU0xfRU5TVVJFKCBwQ29udHJvbHMtPmlzKCksICJGb3JtQ29udHJvbGxlcjo6bG9jYXRlQ29udHJvbDogTlVMTC1jb250cm9sPyIgKTsKICAgICAgICAgICAgaWYgKCBwQ29udHJvbHMtPmlzKCkgKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBpZiAoICggKnBDb250cm9scyktPmdldE1vZGVsKCkgPT0gX3J4TW9kZWwgKQogICAgICAgICAgICAgICAgICAgIHJldHVybiAqcENvbnRyb2xzOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIE9TTF9FTlNVUkUoIHNhbF9GYWxzZSwgIkZvcm1Db250cm9sbGVyOjpsb2NhdGVDb250cm9sOiBkaWQgbm90IGZpbmQgYSBjb250cm9sIGZvciB0aGlzIG1vZGVsISIgKTsKICAgIH0KICAgIGNhdGNoKCBjb25zdCBFeGNlcHRpb24mICkKICAgIHsKICAgICAgICBEQkdfVU5IQU5ETEVEX0VYQ0VQVElPTigpOwogICAgfQogICAgcmV0dXJuIE5VTEw7Cn0KCi8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCm5hbWVzcGFjZQp7CiAgICB2b2lkIGRpc3BsYXlFcnJvclNldEZvY3VzKCBjb25zdCBTdHJpbmcmIF9yTWVzc2FnZSwgY29uc3QgUmVmZXJlbmNlPCBYQ29udHJvbCA+JiBfcnhGb2N1c0NvbnRyb2wsIFdpbmRvdyogX3BEaWFsb2dQYXJlbnQgKQogICAgewoJICAgIFNRTENvbnRleHQgYUVycm9yOwoJICAgIGFFcnJvci5NZXNzYWdlID0gU3RyaW5nKCBTVlhfUkVTKCBSSURfU1RSX1dSSVRFRVJST1IgKSApOwoJICAgIGFFcnJvci5EZXRhaWxzID0gX3JNZXNzYWdlOwoJICAgIGRpc3BsYXlFeGNlcHRpb24oIGFFcnJvciwgX3BEaWFsb2dQYXJlbnQgKTsKCiAgICAgICAgaWYgKCBfcnhGb2N1c0NvbnRyb2wuaXMoKSApCiAgICAgICAgewogICAgICAgICAgICBSZWZlcmVuY2U8IFhXaW5kb3cgPiB4Q29udHJvbFdpbmRvdyggX3J4Rm9jdXNDb250cm9sLCBVTk9fUVVFUlkgKTsKICAgICAgICAgICAgT1NMX0VOU1VSRSggeENvbnRyb2xXaW5kb3cuaXMoKSwgImRpc3BsYXlFcnJvclNldEZvY3VzOiBpbnZhbGlkIGNvbnRyb2whIiApOwogICAgICAgICAgICBpZiAoIHhDb250cm9sV2luZG93LmlzKCkgKQogICAgICAgICAgICAgICAgeENvbnRyb2xXaW5kb3ctPnNldEZvY3VzKCk7CiAgICAgICAgfQogICAgfQoKICAgIHNhbF9Cb29sIGxjbF9zaG91bGRWYWxpZGF0ZVJlcXVpcmVkRmllbGRzX25vdGhyb3coIGNvbnN0IFJlZmVyZW5jZTwgWEludGVyZmFjZSA+JiBfcnhGb3JtICkKICAgIHsKICAgICAgICB0cnkKICAgICAgICB7CiAgICAgICAgICAgIHN0YXRpYyA6OnJ0bDo6T1VTdHJpbmcgc19zRm9ybXNDaGVja1JlcXVpcmVkRmllbGRzKCBSVExfQ09OU1RBU0NJSV9VU1RSSU5HUEFSQU0oICJGb3Jtc0NoZWNrUmVxdWlyZWRGaWVsZHMiICkgKTsKCiAgICAgICAgICAgIC8vIGZpcnN0LCBjaGVjayB3aGV0aGVyIHRoZSBmb3JtIGhhcyBhIHByb3BlcnR5IHRlbGxpbmcgdXMgdGhlIGFuc3dlcgogICAgICAgICAgICAvLyB0aGlzIGFsbG93cyBwZW9wbGUgdG8gdXNlIHRoZSBYUHJvcGVydHlDb250YWluZXIgaW50ZXJmYWNlIG9mIGEgZm9ybSB0byBjb250cm9sCiAgICAgICAgICAgIC8vIHRoZSBiZWhhdmlvdXIgb24gYSBwZXItZm9ybSBiYXNpcy4KICAgICAgICAgICAgUmVmZXJlbmNlPCBYUHJvcGVydHlTZXQgPiB4Rm9ybVByb3BzKCBfcnhGb3JtLCBVTk9fUVVFUllfVEhST1cgKTsKICAgICAgICAgICAgUmVmZXJlbmNlPCBYUHJvcGVydHlTZXRJbmZvID4geFBTSSggeEZvcm1Qcm9wcy0+Z2V0UHJvcGVydHlTZXRJbmZvKCkgKTsKICAgICAgICAgICAgaWYgKCB4UFNJLT5oYXNQcm9wZXJ0eUJ5TmFtZSggc19zRm9ybXNDaGVja1JlcXVpcmVkRmllbGRzICkgKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBzYWxfQm9vbCBiU2hvdWxkVmFsaWRhdGUgPSB0cnVlOwogICAgICAgICAgICAgICAgT1NMX1ZFUklGWSggeEZvcm1Qcm9wcy0+Z2V0UHJvcGVydHlWYWx1ZSggc19zRm9ybXNDaGVja1JlcXVpcmVkRmllbGRzICkgPj49IGJTaG91bGRWYWxpZGF0ZSApOwogICAgICAgICAgICAgICAgcmV0dXJuIGJTaG91bGRWYWxpZGF0ZTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgLy8gbmV4dCwgY2hlY2sgdGhlIGRhdGEgc291cmNlIHdoaWNoIGNyZWF0ZWQgdGhlIGNvbm5lY3Rpb24KICAgICAgICAgICAgUmVmZXJlbmNlPCBYQ2hpbGQgPiB4Q29ubmVjdGlvbkFzQ2hpbGQoIHhGb3JtUHJvcHMtPmdldFByb3BlcnR5VmFsdWUoIEZNX1BST1BfQUNUSVZFX0NPTk5FQ1RJT04gKSwgVU5PX1FVRVJZX1RIUk9XICk7CiAgICAgICAgICAgIFJlZmVyZW5jZTwgWFByb3BlcnR5U2V0ID4geERhdGFTb3VyY2UoIHhDb25uZWN0aW9uQXNDaGlsZC0+Z2V0UGFyZW50KCksIFVOT19RVUVSWSApOwogICAgICAgICAgICBpZiAoICF4RGF0YVNvdXJjZS5pcygpICkKICAgICAgICAgICAgICAgIC8vIHNlbGRvbSAoYnV0IHBvc3NpYmxlKTogdGhpcyBpcyBub3QgYSBjb25uZWN0aW9uIGNyZWF0ZWQgYnkgYSBkYXRhIHNvdXJjZQogICAgICAgICAgICAgICAgcmV0dXJuIHNhbF9UcnVlOwoKICAgICAgICAgICAgUmVmZXJlbmNlPCBYUHJvcGVydHlTZXQgPiB4RGF0YVNvdXJjZVNldHRpbmdzKAogICAgICAgICAgICAgICAgeERhdGFTb3VyY2UtPmdldFByb3BlcnR5VmFsdWUoIDo6cnRsOjpPVVN0cmluZyggUlRMX0NPTlNUQVNDSUlfVVNUUklOR1BBUkFNKCAiU2V0dGluZ3MiICkgKSApLAogICAgICAgICAgICAgICAgVU5PX1FVRVJZX1RIUk9XICk7CgogICAgICAgICAgICBzYWxfQm9vbCBiU2hvdWxkVmFsaWRhdGUgPSB0cnVlOwogICAgICAgICAgICBPU0xfVkVSSUZZKCB4RGF0YVNvdXJjZVNldHRpbmdzLT5nZXRQcm9wZXJ0eVZhbHVlKCBzX3NGb3Jtc0NoZWNrUmVxdWlyZWRGaWVsZHMgKSA+Pj0gYlNob3VsZFZhbGlkYXRlICk7CiAgICAgICAgICAgIHJldHVybiBiU2hvdWxkVmFsaWRhdGU7CiAgICAgICAgfQogICAgICAgIGNhdGNoKCBjb25zdCBFeGNlcHRpb24mICkKICAgICAgICB7CiAgICAgICAgCURCR19VTkhBTkRMRURfRVhDRVBUSU9OKCk7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gc2FsX1RydWU7CiAgICB9Cn0KCi8vIFhSb3dTZXRBcHByb3ZlTGlzdGVuZXIKLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0Kc2FsX0Jvb2wgU0FMX0NBTEwgRm9ybUNvbnRyb2xsZXI6OmFwcHJvdmVSb3dDaGFuZ2UoY29uc3QgUm93Q2hhbmdlRXZlbnQmIF9yRXZlbnQpIHRocm93KCBSdW50aW1lRXhjZXB0aW9uICkKewogICAgOjpvc2w6OkNsZWFyYWJsZU11dGV4R3VhcmQgYUd1YXJkKCBtX2FNdXRleCApOwogICAgaW1wbF9jaGVja0Rpc3Bvc2VkX3Rocm93KCk7CgogICAgOjpjcHB1OjpPSW50ZXJmYWNlSXRlcmF0b3JIZWxwZXIgYUl0ZXIobV9hUm93U2V0QXBwcm92ZUxpc3RlbmVycyk7CiAgICBzYWxfQm9vbCBiVmFsaWQgPSBzYWxfVHJ1ZTsKICAgIGlmIChhSXRlci5oYXNNb3JlRWxlbWVudHMoKSkKICAgIHsKICAgICAgICBSb3dDaGFuZ2VFdmVudCBhRXZ0KCBfckV2ZW50ICk7CiAgICAgICAgYUV2dC5Tb3VyY2UgPSAqdGhpczsKICAgICAgICBiVmFsaWQgPSAoKFhSb3dTZXRBcHByb3ZlTGlzdGVuZXIqKWFJdGVyLm5leHQoKSktPmFwcHJvdmVSb3dDaGFuZ2UoYUV2dCk7CiAgICB9CgogICAgaWYgKCAhYlZhbGlkICkKICAgICAgICByZXR1cm4gYlZhbGlkOwoKICAgIGlmICAoICAgKCBfckV2ZW50LkFjdGlvbiAhPSBSb3dDaGFuZ2VBY3Rpb246OklOU0VSVCApCiAgICAgICAgJiYgICggX3JFdmVudC5BY3Rpb24gIT0gUm93Q2hhbmdlQWN0aW9uOjpVUERBVEUgKQogICAgICAgICkKICAgICAgICByZXR1cm4gYlZhbGlkOwoKICAgIC8vIGlmIHNvbWUgb2YgdGhlIGNvbnRyb2wgbW9kZWxzIGFyZSBib3VuZCB0byB2YWxpZGF0b3JzLCBjaGVjayB0aGVtCiAgICA6OnJ0bDo6T1VTdHJpbmcgc0ludmFsaWRpdHlFeHBsYW5hdGlvbjsKICAgIFJlZmVyZW5jZTwgWENvbnRyb2xNb2RlbCA+IHhJbnZhbGlkTW9kZWw7CiAgICBpZiAoICFjaGVja0Zvcm1Db21wb25lbnRWYWxpZGl0eSggc0ludmFsaWRpdHlFeHBsYW5hdGlvbiwgeEludmFsaWRNb2RlbCApICkKICAgIHsKICAgICAgICBSZWZlcmVuY2U8IFhDb250cm9sID4geENvbnRyb2woIGxvY2F0ZUNvbnRyb2woIHhJbnZhbGlkTW9kZWwgKSApOwogICAgICAgIGFHdWFyZC5jbGVhcigpOwogICAgICAgIGRpc3BsYXlFcnJvclNldEZvY3VzKCBzSW52YWxpZGl0eUV4cGxhbmF0aW9uLCB4Q29udHJvbCwgZ2V0RGlhbG9nUGFyZW50V2luZG93KCkgKTsKICAgICAgICByZXR1cm4gZmFsc2U7CiAgICB9CgogICAgLy8gY2hlY2sgdmFsdWVzIG9uIE5VTEwgYW5kIHJlcXVpcmVkIGZsYWcKICAgIGlmICggIWxjbF9zaG91bGRWYWxpZGF0ZVJlcXVpcmVkRmllbGRzX25vdGhyb3coIF9yRXZlbnQuU291cmNlICkgKQogICAgICAgIHJldHVybiBzYWxfVHJ1ZTsKCiAgICBPU0xfRU5TVVJFKCBtX3BDb2x1bW5JbmZvQ2FjaGUuZ2V0KCksICJGb3JtQ29udHJvbGxlcjo6YXBwcm92ZVJvd0NoYW5nZTogbm8gY29sdW1uIGluZm9zISIgKTsKICAgIGlmICggIW1fcENvbHVtbkluZm9DYWNoZS5nZXQoKSApCiAgICAgICAgcmV0dXJuIHNhbF9UcnVlOwoKICAgIHRyeQogICAgewogICAgICAgIGlmICggIW1fcENvbHVtbkluZm9DYWNoZS0+Y29udHJvbHNJbml0aWFsaXplZCgpICkKICAgICAgICAgICAgbV9wQ29sdW1uSW5mb0NhY2hlLT5pbml0aWFsaXplQ29udHJvbHMoIGdldENvbnRyb2xzKCkgKTsKCiAgICAgICAgc2l6ZV90IGNvbENvdW50ID0gbV9wQ29sdW1uSW5mb0NhY2hlLT5nZXRDb2x1bW5Db3VudCgpOwogICAgICAgIGZvciAoIHNpemVfdCBjb2wgPSAwOyBjb2wgPCBjb2xDb3VudDsgKytjb2wgKQogICAgICAgIHsKICAgICAgICAgICAgY29uc3QgQ29sdW1uSW5mbyYgckNvbEluZm8gPSBtX3BDb2x1bW5JbmZvQ2FjaGUtPmdldENvbHVtbkluZm8oIGNvbCApOwogICAgICAgICAgICBpZiAoIHJDb2xJbmZvLm5OdWxsYWJsZSAhPSBDb2x1bW5WYWx1ZTo6Tk9fTlVMTFMgKQogICAgICAgICAgICAgICAgY29udGludWU7CgogICAgICAgICAgICBpZiAoIHJDb2xJbmZvLmJBdXRvSW5jcmVtZW50ICkKICAgICAgICAgICAgICAgIGNvbnRpbnVlOwoKICAgICAgICAgICAgaWYgKCByQ29sSW5mby5iUmVhZE9ubHkgKQogICAgICAgICAgICAgICAgY29udGludWU7CgogICAgICAgICAgICBpZiAoICFyQ29sSW5mby54Rmlyc3RDb250cm9sV2l0aElucHV0UmVxdWlyZWQuaXMoKSAmJiAhckNvbEluZm8ueEZpcnN0R3JpZFdpdGhJbnB1dFJlcXVpcmVkQ29sdW1uLmlzKCkgKQogICAgICAgICAgICAgICAgY29udGludWU7CgogICAgICAgICAgICAvLyBUT0RPOiBpbiBjYXNlIG9mIGJpbmFyeSBmaWVsZHMsIHRoaXMgImdldFN0cmluZyIgYmVsb3cgaXMgZXh0cmVtZWx5IGV4cGVuc2l2ZQogICAgICAgICAgICBpZiAoIHJDb2xJbmZvLnhDb2x1bW4tPmdldFN0cmluZygpLmdldExlbmd0aCgpIHx8ICFyQ29sSW5mby54Q29sdW1uLT53YXNOdWxsKCkgKQogICAgICAgICAgICAgICAgY29udGludWU7CgogICAgICAgICAgICBTdHJpbmcgc01lc3NhZ2UoIFNWWF9SRVMoIFJJRF9FUlJfRklFTERSRVFVSVJFRCApICk7CiAgICAgICAgICAgIHNNZXNzYWdlLlNlYXJjaEFuZFJlcGxhY2UoICcjJywgckNvbEluZm8uc05hbWUgKTsKCiAgICAgICAgICAgIC8vIHRoZSBjb250cm9sIHRvIGZvY3VzCiAgICAgICAgICAgIFJlZmVyZW5jZTwgWENvbnRyb2wgPiB4Q29udHJvbCggckNvbEluZm8ueEZpcnN0Q29udHJvbFdpdGhJbnB1dFJlcXVpcmVkICk7CiAgICAgICAgICAgIGlmICggIXhDb250cm9sLmlzKCkgKQogICAgICAgICAgICAgICAgeENvbnRyb2wuc2V0KCByQ29sSW5mby54Rmlyc3RHcmlkV2l0aElucHV0UmVxdWlyZWRDb2x1bW4sIFVOT19RVUVSWSApOwoKICAgICAgICAgICAgYUd1YXJkLmNsZWFyKCk7CiAgICAgICAgICAgIGRpc3BsYXlFcnJvclNldEZvY3VzKCBzTWVzc2FnZSwgckNvbEluZm8ueEZpcnN0Q29udHJvbFdpdGhJbnB1dFJlcXVpcmVkLCBnZXREaWFsb2dQYXJlbnRXaW5kb3coKSApOwogICAgICAgICAgICByZXR1cm4gc2FsX0ZhbHNlOwogICAgICAgIH0KICAgIH0KICAgIGNhdGNoKCBjb25zdCBFeGNlcHRpb24mICkKICAgIHsKICAgIAlEQkdfVU5IQU5ETEVEX0VYQ0VQVElPTigpOwogICAgfQoKICAgIHJldHVybiB0cnVlOwp9CgovLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQpzYWxfQm9vbCBTQUxfQ0FMTCBGb3JtQ29udHJvbGxlcjo6YXBwcm92ZUN1cnNvck1vdmUoY29uc3QgRXZlbnRPYmplY3QmIGV2ZW50KSB0aHJvdyggUnVudGltZUV4Y2VwdGlvbiApCnsKICAgIDo6b3NsOjpNdXRleEd1YXJkIGFHdWFyZCggbV9hTXV0ZXggKTsKICAgIGltcGxfY2hlY2tEaXNwb3NlZF90aHJvdygpOwoKICAgIDo6Y3BwdTo6T0ludGVyZmFjZUl0ZXJhdG9ySGVscGVyIGFJdGVyKG1fYVJvd1NldEFwcHJvdmVMaXN0ZW5lcnMpOwogICAgaWYgKGFJdGVyLmhhc01vcmVFbGVtZW50cygpKQogICAgewogICAgICAgIEV2ZW50T2JqZWN0IGFFdnQoZXZlbnQpOwogICAgICAgIGFFdnQuU291cmNlID0gKnRoaXM7CiAgICAgICAgcmV0dXJuICgoWFJvd1NldEFwcHJvdmVMaXN0ZW5lciopYUl0ZXIubmV4dCgpKS0+YXBwcm92ZUN1cnNvck1vdmUoYUV2dCk7CiAgICB9CgogICAgcmV0dXJuIHNhbF9UcnVlOwp9CgovLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQpzYWxfQm9vbCBTQUxfQ0FMTCBGb3JtQ29udHJvbGxlcjo6YXBwcm92ZVJvd1NldENoYW5nZShjb25zdCBFdmVudE9iamVjdCYgZXZlbnQpIHRocm93KCBSdW50aW1lRXhjZXB0aW9uICkKewogICAgOjpvc2w6Ok11dGV4R3VhcmQgYUd1YXJkKCBtX2FNdXRleCApOwogICAgaW1wbF9jaGVja0Rpc3Bvc2VkX3Rocm93KCk7CgogICAgOjpjcHB1OjpPSW50ZXJmYWNlSXRlcmF0b3JIZWxwZXIgYUl0ZXIobV9hUm93U2V0QXBwcm92ZUxpc3RlbmVycyk7CiAgICBpZiAoYUl0ZXIuaGFzTW9yZUVsZW1lbnRzKCkpCiAgICB7CiAgICAgICAgRXZlbnRPYmplY3QgYUV2dChldmVudCk7CiAgICAgICAgYUV2dC5Tb3VyY2UgPSAqdGhpczsKICAgICAgICByZXR1cm4gKChYUm93U2V0QXBwcm92ZUxpc3RlbmVyKilhSXRlci5uZXh0KCkpLT5hcHByb3ZlUm93U2V0Q2hhbmdlKGFFdnQpOwogICAgfQoKICAgIHJldHVybiBzYWxfVHJ1ZTsKfQoKLy8gWFJvd1NldEFwcHJvdmVCcm9hZGNhc3RlcgovLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQp2b2lkIFNBTF9DQUxMIEZvcm1Db250cm9sbGVyOjphZGRSb3dTZXRBcHByb3ZlTGlzdGVuZXIoY29uc3QgUmVmZXJlbmNlPCBYUm93U2V0QXBwcm92ZUxpc3RlbmVyID4gJiBfcnhMaXN0ZW5lcikgdGhyb3coIFJ1bnRpbWVFeGNlcHRpb24gKQp7CiAgICA6Om9zbDo6TXV0ZXhHdWFyZCBhR3VhcmQoIG1fYU11dGV4ICk7CiAgICBpbXBsX2NoZWNrRGlzcG9zZWRfdGhyb3coKTsKCiAgICBtX2FSb3dTZXRBcHByb3ZlTGlzdGVuZXJzLmFkZEludGVyZmFjZShfcnhMaXN0ZW5lcik7Cn0KCi8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCnZvaWQgU0FMX0NBTEwgRm9ybUNvbnRyb2xsZXI6OnJlbW92ZVJvd1NldEFwcHJvdmVMaXN0ZW5lcihjb25zdCBSZWZlcmVuY2U8IFhSb3dTZXRBcHByb3ZlTGlzdGVuZXIgPiAmIF9yeExpc3RlbmVyKSB0aHJvdyggUnVudGltZUV4Y2VwdGlvbiApCnsKICAgIDo6b3NsOjpNdXRleEd1YXJkIGFHdWFyZCggbV9hTXV0ZXggKTsKICAgIGltcGxfY2hlY2tEaXNwb3NlZF90aHJvdygpOwoKICAgIG1fYVJvd1NldEFwcHJvdmVMaXN0ZW5lcnMucmVtb3ZlSW50ZXJmYWNlKF9yeExpc3RlbmVyKTsKfQoKLy8gWEVycm9yTGlzdGVuZXIKLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0Kdm9pZCBTQUxfQ0FMTCBGb3JtQ29udHJvbGxlcjo6ZXJyb3JPY2N1cmVkKGNvbnN0IFNRTEVycm9yRXZlbnQmIGFFdmVudCkgdGhyb3coIFJ1bnRpbWVFeGNlcHRpb24gKQp7CiAgICA6Om9zbDo6Q2xlYXJhYmxlTXV0ZXhHdWFyZCBhR3VhcmQoIG1fYU11dGV4ICk7CiAgICBpbXBsX2NoZWNrRGlzcG9zZWRfdGhyb3coKTsKCiAgICA6OmNwcHU6Ok9JbnRlcmZhY2VJdGVyYXRvckhlbHBlciBhSXRlcihtX2FFcnJvckxpc3RlbmVycyk7CiAgICBpZiAoYUl0ZXIuaGFzTW9yZUVsZW1lbnRzKCkpCiAgICB7CiAgICAgICAgU1FMRXJyb3JFdmVudCBhRXZ0KGFFdmVudCk7CiAgICAgICAgYUV2dC5Tb3VyY2UgPSAqdGhpczsKICAgICAgICAoKFhTUUxFcnJvckxpc3RlbmVyKilhSXRlci5uZXh0KCkpLT5lcnJvck9jY3VyZWQoYUV2dCk7CiAgICB9CiAgICBlbHNlCiAgICB7CiAgICAgICAgYUd1YXJkLmNsZWFyKCk7CiAgICAgICAgZGlzcGxheUV4Y2VwdGlvbiggYUV2ZW50ICk7CiAgICB9Cn0KCi8vIFhFcnJvckJyb2FkY2FzdGVyCi8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCnZvaWQgU0FMX0NBTEwgRm9ybUNvbnRyb2xsZXI6OmFkZFNRTEVycm9yTGlzdGVuZXIoY29uc3QgUmVmZXJlbmNlPCBYU1FMRXJyb3JMaXN0ZW5lciA+ICYgYUxpc3RlbmVyKSB0aHJvdyggUnVudGltZUV4Y2VwdGlvbiApCnsKICAgIDo6b3NsOjpNdXRleEd1YXJkIGFHdWFyZCggbV9hTXV0ZXggKTsKICAgIGltcGxfY2hlY2tEaXNwb3NlZF90aHJvdygpOwoKICAgIG1fYUVycm9yTGlzdGVuZXJzLmFkZEludGVyZmFjZShhTGlzdGVuZXIpOwp9CgovLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQp2b2lkIFNBTF9DQUxMIEZvcm1Db250cm9sbGVyOjpyZW1vdmVTUUxFcnJvckxpc3RlbmVyKGNvbnN0IFJlZmVyZW5jZTwgWFNRTEVycm9yTGlzdGVuZXIgPiAmIGFMaXN0ZW5lcikgdGhyb3coIFJ1bnRpbWVFeGNlcHRpb24gKQp7CiAgICA6Om9zbDo6TXV0ZXhHdWFyZCBhR3VhcmQoIG1fYU11dGV4ICk7CiAgICBpbXBsX2NoZWNrRGlzcG9zZWRfdGhyb3coKTsKCiAgICBtX2FFcnJvckxpc3RlbmVycy5yZW1vdmVJbnRlcmZhY2UoYUxpc3RlbmVyKTsKfQoKLy8gWERhdGFiYXNlUGFyYW1ldGVyQnJvYWRjYXN0ZXIyCi8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCnZvaWQgU0FMX0NBTEwgRm9ybUNvbnRyb2xsZXI6OmFkZERhdGFiYXNlUGFyYW1ldGVyTGlzdGVuZXIoY29uc3QgUmVmZXJlbmNlPCBYRGF0YWJhc2VQYXJhbWV0ZXJMaXN0ZW5lciA+ICYgYUxpc3RlbmVyKSB0aHJvdyggUnVudGltZUV4Y2VwdGlvbiApCnsKICAgIDo6b3NsOjpNdXRleEd1YXJkIGFHdWFyZCggbV9hTXV0ZXggKTsKICAgIGltcGxfY2hlY2tEaXNwb3NlZF90aHJvdygpOwoKICAgIG1fYVBhcmFtZXRlckxpc3RlbmVycy5hZGRJbnRlcmZhY2UoYUxpc3RlbmVyKTsKfQoKLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0Kdm9pZCBTQUxfQ0FMTCBGb3JtQ29udHJvbGxlcjo6cmVtb3ZlRGF0YWJhc2VQYXJhbWV0ZXJMaXN0ZW5lcihjb25zdCBSZWZlcmVuY2U8IFhEYXRhYmFzZVBhcmFtZXRlckxpc3RlbmVyID4gJiBhTGlzdGVuZXIpIHRocm93KCBSdW50aW1lRXhjZXB0aW9uICkKewogICAgOjpvc2w6Ok11dGV4R3VhcmQgYUd1YXJkKCBtX2FNdXRleCApOwogICAgaW1wbF9jaGVja0Rpc3Bvc2VkX3Rocm93KCk7CgogICAgbV9hUGFyYW1ldGVyTGlzdGVuZXJzLnJlbW92ZUludGVyZmFjZShhTGlzdGVuZXIpOwp9CgovLyBYRGF0YWJhc2VQYXJhbWV0ZXJCcm9hZGNhc3RlcgovLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQp2b2lkIFNBTF9DQUxMIEZvcm1Db250cm9sbGVyOjphZGRQYXJhbWV0ZXJMaXN0ZW5lcihjb25zdCBSZWZlcmVuY2U8IFhEYXRhYmFzZVBhcmFtZXRlckxpc3RlbmVyID4gJiBhTGlzdGVuZXIpIHRocm93KCBSdW50aW1lRXhjZXB0aW9uICkKewogICAgRm9ybUNvbnRyb2xsZXI6OmFkZERhdGFiYXNlUGFyYW1ldGVyTGlzdGVuZXIoIGFMaXN0ZW5lciApOwp9CgovLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQp2b2lkIFNBTF9DQUxMIEZvcm1Db250cm9sbGVyOjpyZW1vdmVQYXJhbWV0ZXJMaXN0ZW5lcihjb25zdCBSZWZlcmVuY2U8IFhEYXRhYmFzZVBhcmFtZXRlckxpc3RlbmVyID4gJiBhTGlzdGVuZXIpIHRocm93KCBSdW50aW1lRXhjZXB0aW9uICkKewogICAgRm9ybUNvbnRyb2xsZXI6OnJlbW92ZURhdGFiYXNlUGFyYW1ldGVyTGlzdGVuZXIoIGFMaXN0ZW5lciApOwp9CgovLyBYRGF0YWJhc2VQYXJhbWV0ZXJMaXN0ZW5lcgovLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQpzYWxfQm9vbCBTQUxfQ0FMTCBGb3JtQ29udHJvbGxlcjo6YXBwcm92ZVBhcmFtZXRlcihjb25zdCBEYXRhYmFzZVBhcmFtZXRlckV2ZW50JiBhRXZlbnQpIHRocm93KCBSdW50aW1lRXhjZXB0aW9uICkKewogICAgOjp2b3M6Ok9HdWFyZCBhU29sYXJHdWFyZChBcHBsaWNhdGlvbjo6R2V0U29sYXJNdXRleCgpKTsKICAgIDo6b3NsOjpNdXRleEd1YXJkIGFHdWFyZCggbV9hTXV0ZXggKTsKICAgIGltcGxfY2hlY2tEaXNwb3NlZF90aHJvdygpOwoKICAgIDo6Y3BwdTo6T0ludGVyZmFjZUl0ZXJhdG9ySGVscGVyIGFJdGVyKG1fYVBhcmFtZXRlckxpc3RlbmVycyk7CiAgICBpZiAoYUl0ZXIuaGFzTW9yZUVsZW1lbnRzKCkpCiAgICB7CiAgICAgICAgRGF0YWJhc2VQYXJhbWV0ZXJFdmVudCBhRXZ0KGFFdmVudCk7CiAgICAgICAgYUV2dC5Tb3VyY2UgPSAqdGhpczsKICAgICAgICByZXR1cm4gKChYRGF0YWJhc2VQYXJhbWV0ZXJMaXN0ZW5lciopYUl0ZXIubmV4dCgpKS0+YXBwcm92ZVBhcmFtZXRlcihhRXZ0KTsKICAgIH0KICAgIGVsc2UKICAgIHsKICAgICAgICAvLyBkZWZhdWx0IGhhbmRsaW5nOiBpbnN0YW50aWF0ZSBhbiBpbnRlcmFjdGlvbiBoYW5kbGVyIGFuZCBsZXQgaXQgaGFuZGxlIHRoZSBwYXJhbWV0ZXIgcmVxdWVzdAogICAgICAgIHRyeQogICAgICAgIHsKICAgICAgICAgICAgaWYgKCAhZW5zdXJlSW50ZXJhY3Rpb25IYW5kbGVyKCkgKQogICAgICAgICAgICAgICAgcmV0dXJuIHNhbF9GYWxzZTsKCiAgICAgICAgICAgIC8vIHR3byBjb250aW51YXRpb25zIGFsbG93ZWQ6IE9LIGFuZCBDYW5jZWwKICAgICAgICAgICAgT1BhcmFtZXRlckNvbnRpbnVhdGlvbiogcFBhcmFtVmFsdWVzID0gbmV3IE9QYXJhbWV0ZXJDb250aW51YXRpb247CiAgICAgICAgICAgIE9JbnRlcmFjdGlvbkFib3J0KiBwQWJvcnQgPSBuZXcgT0ludGVyYWN0aW9uQWJvcnQ7CiAgICAgICAgICAgIC8vIHRoZSByZXF1ZXN0CiAgICAgICAgICAgIFBhcmFtZXRlcnNSZXF1ZXN0IGFSZXF1ZXN0OwogICAgICAgICAgICBhUmVxdWVzdC5QYXJhbWV0ZXJzID0gYUV2ZW50LlBhcmFtZXRlcnM7CiAgICAgICAgICAgIGFSZXF1ZXN0LkNvbm5lY3Rpb24gPSBPU3RhdGljRGF0YUFjY2Vzc1Rvb2xzKCkuZ2V0Um93U2V0Q29ubmVjdGlvbihSZWZlcmVuY2U8IFhSb3dTZXQgPihhRXZlbnQuU291cmNlLCBVTk9fUVVFUlkpKTsKICAgICAgICAgICAgT0ludGVyYWN0aW9uUmVxdWVzdCogcFBhcmFtUmVxdWVzdCA9IG5ldyBPSW50ZXJhY3Rpb25SZXF1ZXN0KG1ha2VBbnkoYVJlcXVlc3QpKTsKICAgICAgICAgICAgUmVmZXJlbmNlPCBYSW50ZXJhY3Rpb25SZXF1ZXN0ID4geFBhcmFtUmVxdWVzdChwUGFyYW1SZXF1ZXN0KTsKICAgICAgICAgICAgLy8gc29tZSBrbml0dGluZ3MKICAgICAgICAgICAgcFBhcmFtUmVxdWVzdC0+YWRkQ29udGludWF0aW9uKHBQYXJhbVZhbHVlcyk7CiAgICAgICAgICAgIHBQYXJhbVJlcXVlc3QtPmFkZENvbnRpbnVhdGlvbihwQWJvcnQpOwoKICAgICAgICAgICAgLy8gaGFuZGxlIHRoZSByZXF1ZXN0CiAgICAgICAgICAgIG1feEludGVyYWN0aW9uSGFuZGxlci0+aGFuZGxlKHhQYXJhbVJlcXVlc3QpOwoKICAgICAgICAgICAgaWYgKCFwUGFyYW1WYWx1ZXMtPndhc1NlbGVjdGVkKCkpCiAgICAgICAgICAgICAgICAvLyBjYW5jZWxlZAogICAgICAgICAgICAgICAgcmV0dXJuIHNhbF9GYWxzZTsKCiAgICAgICAgICAgIC8vIHRyYW5zZmVyIHRoZSB2YWx1ZXMgaW50byB0aGUgcGFyYW1ldGVyIHN1cHBsaWVyCiAgICAgICAgICAgIFNlcXVlbmNlPCBQcm9wZXJ0eVZhbHVlID4gYUZpbmFsVmFsdWVzID0gcFBhcmFtVmFsdWVzLT5nZXRWYWx1ZXMoKTsKICAgICAgICAgICAgaWYgKGFGaW5hbFZhbHVlcy5nZXRMZW5ndGgoKSAhPSBhUmVxdWVzdC5QYXJhbWV0ZXJzLT5nZXRDb3VudCgpKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBEQkdfRVJST1IoIkZvcm1Db250cm9sbGVyOjphcHByb3ZlUGFyYW1ldGVyOiB0aGUgSW50ZXJhY3Rpb25IYW5kbGVyIHJldHVybmVkIG5vbnNlbnNlISIpOwogICAgICAgICAgICAgICAgcmV0dXJuIHNhbF9GYWxzZTsKICAgICAgICAgICAgfQogICAgICAgICAgICBjb25zdCBQcm9wZXJ0eVZhbHVlKiBwRmluYWxWYWx1ZXMgPSBhRmluYWxWYWx1ZXMuZ2V0Q29uc3RBcnJheSgpOwogICAgICAgICAgICBmb3IgKHNhbF9JbnQzMiBpPTA7IGk8YUZpbmFsVmFsdWVzLmdldExlbmd0aCgpOyArK2ksICsrcEZpbmFsVmFsdWVzKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBSZWZlcmVuY2U8IFhQcm9wZXJ0eVNldCA+IHhQYXJhbTsKICAgICAgICAgICAgICAgIDo6Y3BwdTo6ZXh0cmFjdEludGVyZmFjZSh4UGFyYW0sIGFSZXF1ZXN0LlBhcmFtZXRlcnMtPmdldEJ5SW5kZXgoaSkpOwogICAgICAgICAgICAgICAgaWYgKHhQYXJhbS5pcygpKQogICAgICAgICAgICAgICAgewojaWZkZWYgREJHX1VUSUwKICAgICAgICAgICAgICAgICAgICA6OnJ0bDo6T1VTdHJpbmcgc05hbWU7CiAgICAgICAgICAgICAgICAgICAgeFBhcmFtLT5nZXRQcm9wZXJ0eVZhbHVlKEZNX1BST1BfTkFNRSkgPj49IHNOYW1lOwogICAgICAgICAgICAgICAgICAgIERCR19BU1NFUlQoc05hbWUuZXF1YWxzKHBGaW5hbFZhbHVlcy0+TmFtZSksICJGb3JtQ29udHJvbGxlcjo6YXBwcm92ZVBhcmFtZXRlcjogc3VzcGljaW91cyB2YWx1ZSBuYW1lcyEiKTsKI2VuZGlmCiAgICAgICAgICAgICAgICAgICAgdHJ5IHsgeFBhcmFtLT5zZXRQcm9wZXJ0eVZhbHVlKEZNX1BST1BfVkFMVUUsIHBGaW5hbFZhbHVlcy0+VmFsdWUpOyB9CiAgICAgICAgICAgICAgICAgICAgY2F0Y2goRXhjZXB0aW9uJikKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIERCR19FUlJPUigiRm9ybUNvbnRyb2xsZXI6OmFwcHJvdmVQYXJhbWV0ZXI6IHNldHRpbmcgb25lIG9mIHRoZSBwcm9wZXJ0aWVzIGZhaWxlZCEiKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgY2F0Y2goRXhjZXB0aW9uJikKICAgICAgICB7CiAgICAgICAgICAgIERCR19VTkhBTkRMRURfRVhDRVBUSU9OKCk7CiAgICAgICAgfQogICAgfQogICAgcmV0dXJuIHNhbF9UcnVlOwp9CgovLyBYQ29uZmlybURlbGV0ZUJyb2FkY2FzdGVyCi8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCnZvaWQgU0FMX0NBTEwgRm9ybUNvbnRyb2xsZXI6OmFkZENvbmZpcm1EZWxldGVMaXN0ZW5lcihjb25zdCBSZWZlcmVuY2U8IFhDb25maXJtRGVsZXRlTGlzdGVuZXIgPiAmIGFMaXN0ZW5lcikgdGhyb3coIFJ1bnRpbWVFeGNlcHRpb24gKQp7CiAgICA6Om9zbDo6TXV0ZXhHdWFyZCBhR3VhcmQoIG1fYU11dGV4ICk7CiAgICBpbXBsX2NoZWNrRGlzcG9zZWRfdGhyb3coKTsKCiAgICBtX2FEZWxldGVMaXN0ZW5lcnMuYWRkSW50ZXJmYWNlKGFMaXN0ZW5lcik7Cn0KCi8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCnZvaWQgU0FMX0NBTEwgRm9ybUNvbnRyb2xsZXI6OnJlbW92ZUNvbmZpcm1EZWxldGVMaXN0ZW5lcihjb25zdCBSZWZlcmVuY2U8IFhDb25maXJtRGVsZXRlTGlzdGVuZXIgPiAmIGFMaXN0ZW5lcikgdGhyb3coIFJ1bnRpbWVFeGNlcHRpb24gKQp7CiAgICA6Om9zbDo6TXV0ZXhHdWFyZCBhR3VhcmQoIG1fYU11dGV4ICk7CiAgICBpbXBsX2NoZWNrRGlzcG9zZWRfdGhyb3coKTsKCiAgICBtX2FEZWxldGVMaXN0ZW5lcnMucmVtb3ZlSW50ZXJmYWNlKGFMaXN0ZW5lcik7Cn0KCi8vIFhDb25maXJtRGVsZXRlTGlzdGVuZXIKLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0Kc2FsX0Jvb2wgU0FMX0NBTEwgRm9ybUNvbnRyb2xsZXI6OmNvbmZpcm1EZWxldGUoY29uc3QgUm93Q2hhbmdlRXZlbnQmIGFFdmVudCkgdGhyb3coIFJ1bnRpbWVFeGNlcHRpb24gKQp7CiAgICA6Om9zbDo6TXV0ZXhHdWFyZCBhR3VhcmQoIG1fYU11dGV4ICk7CiAgICBpbXBsX2NoZWNrRGlzcG9zZWRfdGhyb3coKTsKCiAgICA6OmNwcHU6Ok9JbnRlcmZhY2VJdGVyYXRvckhlbHBlciBhSXRlcihtX2FEZWxldGVMaXN0ZW5lcnMpOwogICAgaWYgKGFJdGVyLmhhc01vcmVFbGVtZW50cygpKQogICAgewogICAgICAgIFJvd0NoYW5nZUV2ZW50IGFFdnQoYUV2ZW50KTsKICAgICAgICBhRXZ0LlNvdXJjZSA9ICp0aGlzOwogICAgICAgIHJldHVybiAoKFhDb25maXJtRGVsZXRlTGlzdGVuZXIqKWFJdGVyLm5leHQoKSktPmNvbmZpcm1EZWxldGUoYUV2dCk7CiAgICB9CiAgICAvLyBkZWZhdWx0IGhhbmRsaW5nOiBpbnN0YW50aWF0ZSBhbiBpbnRlcmFjdGlvbiBoYW5kbGVyIGFuZCBsZXQgaXQgaGFuZGxlIHRoZSByZXF1ZXN0CgogICAgU3RyaW5nIHNUaXRsZTsKICAgIHNhbF9JbnQzMiBuTGVuZ3RoID0gYUV2ZW50LlJvd3M7CiAgICBpZiAoIG5MZW5ndGggPiAxICkKICAgIHsKICAgICAgICBzVGl0bGUgPSBTVlhfUkVTKCBSSURfU1RSX0RFTEVURUNPTkZJUk1fUkVDT1JEUyApOwogICAgICAgIHNUaXRsZS5TZWFyY2hBbmRSZXBsYWNlKCAnIycsIFN0cmluZzo6Q3JlYXRlRnJvbUludDMyKCBuTGVuZ3RoICkgKTsKICAgIH0KICAgIGVsc2UKICAgICAgICBzVGl0bGUgPSBTVlhfUkVTKCBSSURfU1RSX0RFTEVURUNPTkZJUk1fUkVDT1JEICk7CgogICAgdHJ5CiAgICB7CiAgICAgICAgaWYgKCAhZW5zdXJlSW50ZXJhY3Rpb25IYW5kbGVyKCkgKQogICAgICAgICAgICByZXR1cm4gc2FsX0ZhbHNlOwoKICAgICAgICAvLyB0d28gY29udGludWF0aW9ucyBhbGxvd2VkOiBZZXMgYW5kIE5vCiAgICAgICAgT0ludGVyYWN0aW9uQXBwcm92ZSogcEFwcHJvdmUgPSBuZXcgT0ludGVyYWN0aW9uQXBwcm92ZTsKICAgICAgICBPSW50ZXJhY3Rpb25EaXNhcHByb3ZlKiBwRGlzYXBwcm92ZSA9IG5ldyBPSW50ZXJhY3Rpb25EaXNhcHByb3ZlOwoKICAgICAgICAvLyB0aGUgcmVxdWVzdAogICAgICAgIFNRTFdhcm5pbmcgYVdhcm5pbmc7CiAgICAgICAgYVdhcm5pbmcuTWVzc2FnZSA9IHNUaXRsZTsKICAgICAgICBTUUxXYXJuaW5nIGFEZXRhaWxzOwogICAgICAgIGFEZXRhaWxzLk1lc3NhZ2UgPSBTdHJpbmcoIFNWWF9SRVMoIFJJRF9TVFJfREVMRVRFQ09ORklSTSApICk7CiAgICAgICAgYVdhcm5pbmcuTmV4dEV4Y2VwdGlvbiA8PD0gYURldGFpbHM7CgogICAgICAgIE9JbnRlcmFjdGlvblJlcXVlc3QqIHBSZXF1ZXN0ID0gbmV3IE9JbnRlcmFjdGlvblJlcXVlc3QoIG1ha2VBbnkoIGFXYXJuaW5nICkgKTsKICAgICAgICBSZWZlcmVuY2U8IFhJbnRlcmFjdGlvblJlcXVlc3QgPiB4UmVxdWVzdCggcFJlcXVlc3QgKTsKCiAgICAgICAgLy8gc29tZSBrbml0dGluZ3MKICAgICAgICBwUmVxdWVzdC0+YWRkQ29udGludWF0aW9uKCBwQXBwcm92ZSApOwogICAgICAgIHBSZXF1ZXN0LT5hZGRDb250aW51YXRpb24oIHBEaXNhcHByb3ZlICk7CgogICAgICAgIC8vIGhhbmRsZSB0aGUgcmVxdWVzdAogICAgICAgIG1feEludGVyYWN0aW9uSGFuZGxlci0+aGFuZGxlKCB4UmVxdWVzdCApOwoKICAgICAgICBpZiAoIHBBcHByb3ZlLT53YXNTZWxlY3RlZCgpICkKICAgICAgICAgICAgcmV0dXJuIHNhbF9UcnVlOwogICAgfQogICAgY2F0Y2goIGNvbnN0IEV4Y2VwdGlvbiYgKQogICAgewogICAgCURCR19VTkhBTkRMRURfRVhDRVBUSU9OKCk7CiAgICB9CgogICAgcmV0dXJuIHNhbF9GYWxzZTsKfQoKLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0Kdm9pZCBTQUxfQ0FMTCBGb3JtQ29udHJvbGxlcjo6aW52YWxpZGF0ZUZlYXR1cmVzKCBjb25zdCBTZXF1ZW5jZTwgOjpzYWxfSW50MTYgPiYgX0ZlYXR1cmVzICkgdGhyb3cgKFJ1bnRpbWVFeGNlcHRpb24pCnsKICAgIDo6b3NsOjpNdXRleEd1YXJkIGFHdWFyZCggbV9hTXV0ZXggKTsKICAgIC8vIGZvciBub3csIGp1c3QgY29weSB0aGUgaWRzIG9mIHRoZSBmZWF0dXJlcywgYmVjYXVzZSAuLi4uCiAgICA6OnN0ZDo6Y29weSggX0ZlYXR1cmVzLmdldENvbnN0QXJyYXkoKSwgX0ZlYXR1cmVzLmdldENvbnN0QXJyYXkoKSArIF9GZWF0dXJlcy5nZXRMZW5ndGgoKSwKICAgICAgICA6OnN0ZDo6aW5zZXJ0X2l0ZXJhdG9yPCA6OnN0ZDo6c2V0PCBzYWxfSW50MTYgPiA+KCBtX2FJbnZhbGlkRmVhdHVyZXMsIG1fYUludmFsaWRGZWF0dXJlcy5iZWdpbigpICkKICAgICk7CgogICAgLy8gLi4uIHdlIHdpbGwgZG8gdGhlIHJlYWwgaW52YWxpZGF0aW9uIGFzeW5jaHJvbm91c2x5CiAgICBpZiAoICFtX2FGZWF0dXJlSW52YWxpZGF0aW9uVGltZXIuSXNBY3RpdmUoKSApCiAgICAgICAgbV9hRmVhdHVyZUludmFsaWRhdGlvblRpbWVyLlN0YXJ0KCk7Cn0KCi8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCnZvaWQgU0FMX0NBTEwgRm9ybUNvbnRyb2xsZXI6OmludmFsaWRhdGVBbGxGZWF0dXJlcyggICkgdGhyb3cgKFJ1bnRpbWVFeGNlcHRpb24pCnsKICAgIDo6b3NsOjpDbGVhcmFibGVNdXRleEd1YXJkIGFHdWFyZCggbV9hTXV0ZXggKTsKCiAgICBTZXF1ZW5jZTwgc2FsX0ludDE2ID4gYUludGVyY2VwdGVkRmVhdHVyZXMoIG1fYUZlYXR1cmVEaXNwYXRjaGVycy5zaXplKCkgKTsKICAgIDo6c3RkOjp0cmFuc2Zvcm0oCiAgICAgICAgbV9hRmVhdHVyZURpc3BhdGNoZXJzLmJlZ2luKCksCiAgICAgICAgbV9hRmVhdHVyZURpc3BhdGNoZXJzLmVuZCgpLAogICAgICAgIGFJbnRlcmNlcHRlZEZlYXR1cmVzLmdldEFycmF5KCksCiAgICAgICAgOjpzdGQ6OnNlbGVjdDFzdDwgRGlzcGF0Y2hlckNvbnRhaW5lcjo6dmFsdWVfdHlwZSA+KCkKICAgICk7CgogICAgYUd1YXJkLmNsZWFyKCk7CiAgICBpZiAoIGFJbnRlcmNlcHRlZEZlYXR1cmVzLmdldExlbmd0aCgpICkKICAgICAgICBpbnZhbGlkYXRlRmVhdHVyZXMoIGFJbnRlcmNlcHRlZEZlYXR1cmVzICk7Cn0KCi8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tClJlZmVyZW5jZTwgWERpc3BhdGNoID4KRm9ybUNvbnRyb2xsZXI6OmludGVyY2VwdGVkUXVlcnlEaXNwYXRjaCggY29uc3QgVVJMJiBhVVJMLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IDo6cnRsOjpPVVN0cmluZyYgLyphVGFyZ2V0RnJhbWVOYW1lKi8sIHNhbF9JbnQzMiAvKm5TZWFyY2hGbGFncyovKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRocm93KCBSdW50aW1lRXhjZXB0aW9uICkKewogICAgT1NMX0VOU1VSRSggIWltcGxfaXNEaXNwb3NlZF9ub2ZhaWwoKSwgIkZvcm1Db250cm9sbGVyOiBhbHJlYWR5IGRpc3Bvc2VkISIgKTsKICAgIFJlZmVyZW5jZTwgWERpc3BhdGNoID4gIHhSZXR1cm47CiAgICAvLyBkaXNwYXRjaGVzIGhhbmRsZWQgYnkgb3Vyc2VsZgogICAgaWYgICggICAoIGFVUkwuQ29tcGxldGUgPT0gRk1VUkxfQ09ORklSTV9ERUxFVElPTiApCiAgICAgICAgfHwgICggICAoIGFVUkwuQ29tcGxldGUuZXF1YWxzQXNjaWkoICJwcml2YXRlOi9JbnRlcmFjdGlvbkhhbmRsZXIiICkgKQogICAgICAgICAgICAmJiAgZW5zdXJlSW50ZXJhY3Rpb25IYW5kbGVyKCkKICAgICAgICAgICAgKQogICAgICAgICkKCQl4UmV0dXJuID0gc3RhdGljX2Nhc3Q8IFhEaXNwYXRjaCogPiggdGhpcyApOwoKICAgIC8vIGRpc3BhdGNoZXMgb2YgRm9ybVNsb3QtVVJMcyB3ZSBoYXZlIHRvIHRyYW5zbGF0ZQogICAgaWYgKCAheFJldHVybi5pcygpICYmIG1feEZvcm1PcGVyYXRpb25zLmlzKCkgKQogICAgewogICAgICAgIC8vIGZpbmQgdGhlIHNsb3QgaWQgd2hpY2ggY29ycmVzcG9uZHMgdG8gdGhlIFVSTAogICAgICAgIHNhbF9JbnQzMiBuRmVhdHVyZVNsb3RJZCA9IDo6c3Z4OjpGZWF0dXJlU2xvdFRyYW5zbGF0aW9uOjpnZXRDb250cm9sbGVyRmVhdHVyZVNsb3RJZEZvclVSTCggYVVSTC5NYWluICk7CiAgICAgICAgc2FsX0ludDE2IG5Gb3JtRmVhdHVyZSA9ICggbkZlYXR1cmVTbG90SWQgIT0gLTEgKSA/IDo6c3Z4OjpGZWF0dXJlU2xvdFRyYW5zbGF0aW9uOjpnZXRGb3JtRmVhdHVyZUZvclNsb3RJZCggbkZlYXR1cmVTbG90SWQgKSA6IC0xOwogICAgICAgIGlmICggbkZvcm1GZWF0dXJlID4gMCApCiAgICAgICAgewogICAgICAgICAgICAvLyBnZXQgdGhlIGRpc3BhdGNoZXIgZm9yIHRoaXMgZmVhdHVyZSwgY3JlYXRlIGlmIG5lY2Vzc2FyeQogICAgICAgICAgICBEaXNwYXRjaGVyQ29udGFpbmVyOjpjb25zdF9pdGVyYXRvciBhRGlzcGF0Y2hlclBvcyA9IG1fYUZlYXR1cmVEaXNwYXRjaGVycy5maW5kKCBuRm9ybUZlYXR1cmUgKTsKICAgICAgICAgICAgaWYgKCBhRGlzcGF0Y2hlclBvcyA9PSBtX2FGZWF0dXJlRGlzcGF0Y2hlcnMuZW5kKCkgKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBhRGlzcGF0Y2hlclBvcyA9IG1fYUZlYXR1cmVEaXNwYXRjaGVycy5pbnNlcnQoCiAgICAgICAgICAgICAgICAgICAgRGlzcGF0Y2hlckNvbnRhaW5lcjo6dmFsdWVfdHlwZSggbkZvcm1GZWF0dXJlLCBuZXcgOjpzdng6Ok9TaW5nbGVGZWF0dXJlRGlzcGF0Y2hlciggYVVSTCwgbkZvcm1GZWF0dXJlLCBtX3hGb3JtT3BlcmF0aW9ucywgbV9hTXV0ZXggKSApCiAgICAgICAgICAgICAgICApLmZpcnN0OwogICAgICAgICAgICB9CgogICAgICAgICAgICBPU0xfRU5TVVJFKCBhRGlzcGF0Y2hlclBvcy0+c2Vjb25kLmlzKCksICJGb3JtQ29udHJvbGxlcjo6aW50ZXJjZXB0ZWRRdWVyeURpc3BhdGNoOiBzaG91bGQgaGF2ZSBhIGRpc3BhdGNoZXIgYnkgbm93ISIgKTsKICAgICAgICAgICAgcmV0dXJuIGFEaXNwYXRjaGVyUG9zLT5zZWNvbmQ7CiAgICAgICAgfQogICAgfQoKICAgIC8vIG5vIG1vcmUgdG8gb2ZmZXIKICAgIHJldHVybiB4UmV0dXJuOwp9CgovLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQp2b2lkIFNBTF9DQUxMIEZvcm1Db250cm9sbGVyOjpkaXNwYXRjaCggY29uc3QgVVJMJiBfclVSTCwgY29uc3QgU2VxdWVuY2U8IFByb3BlcnR5VmFsdWUgPiYgX3JBcmdzICkgdGhyb3cgKFJ1bnRpbWVFeGNlcHRpb24pCnsKICAgIGlmICggX3JBcmdzLmdldExlbmd0aCgpICE9IDEgKQogICAgewogICAgICAgIERCR19FUlJPUiggIkZvcm1Db250cm9sbGVyOjpkaXNwYXRjaDogbm8gYXJndW1lbnRzIC0+IG5vIGRpc3BhdGNoISIgKTsKICAgICAgICByZXR1cm47CiAgICB9CgogICAgaWYgKCBfclVSTC5Db21wbGV0ZS5lcXVhbHNBc2NpaSggInByaXZhdGU6L0ludGVyYWN0aW9uSGFuZGxlciIgKSApCiAgICB7CiAgICAgICAgUmVmZXJlbmNlPCBYSW50ZXJhY3Rpb25SZXF1ZXN0ID4geFJlcXVlc3Q7CiAgICAgICAgT1NMX1ZFUklGWSggX3JBcmdzWzBdLlZhbHVlID4+PSB4UmVxdWVzdCApOwogICAgICAgIGlmICggeFJlcXVlc3QuaXMoKSApCiAgICAgICAgICAgIGhhbmRsZSggeFJlcXVlc3QgKTsKICAgICAgICByZXR1cm47CiAgICB9CgogICAgaWYgICggX3JVUkwuQ29tcGxldGUgPT0gRk1VUkxfQ09ORklSTV9ERUxFVElPTiApCiAgICB7CiAgICAgICAgREJHX0VSUk9SKCAiRm9ybUNvbnRyb2xsZXI6OmRpc3BhdGNoOiBIb3cgZG8geW91IGV4cGVjdCBtZSB0byByZXR1cm4gc29tZXRoaW5nIHZpYSB0aGlzIGNhbGw/IiApOwogICAgICAgICAgICAvLyBjb25maXJtRGVsZXRlIGhhcyBhIHJldHVybiB2YWx1ZSAtIGRpc3BhdGNoIGhhc24ndAogICAgICAgIHJldHVybjsKICAgIH0KCglEQkdfRVJST1IoICJGb3JtQ29udHJvbGxlcjo6ZGlzcGF0Y2g6IHVua25vd24gVVJMISIgKTsKfQoKLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0Kdm9pZCBTQUxfQ0FMTCBGb3JtQ29udHJvbGxlcjo6YWRkU3RhdHVzTGlzdGVuZXIoIGNvbnN0IFJlZmVyZW5jZTwgWFN0YXR1c0xpc3RlbmVyID4mIF9yeExpc3RlbmVyLCBjb25zdCBVUkwmIF9yVVJMICkgdGhyb3cgKFJ1bnRpbWVFeGNlcHRpb24pCnsKICAgIGlmIChfclVSTC5Db21wbGV0ZSA9PSBGTVVSTF9DT05GSVJNX0RFTEVUSU9OKQoJewoJCWlmIChfcnhMaXN0ZW5lci5pcygpKQoJCXsJLy8gc2VuZCBhbiBpbml0aWFsIHN0YXR1c0NoYW5nZWQgZXZlbnQKCQkJRmVhdHVyZVN0YXRlRXZlbnQgYUV2ZW50OwoJCQlhRXZlbnQuRmVhdHVyZVVSTCA9IF9yVVJMOwoJCQlhRXZlbnQuSXNFbmFibGVkID0gc2FsX1RydWU7CgkJCV9yeExpc3RlbmVyLT5zdGF0dXNDaGFuZ2VkKGFFdmVudCk7CgkJCS8vIGFuZCBkb24ndCBhZGQgdGhlIGxpc3RlbmVyIGF0IGFsbCAodGhlIHN0YXR1cyB3aWxsIG5ldmVyIGNoYW5nZSkKCQl9Cgl9CgllbHNlCgkJT1NMX0VOU1VSRShzYWxfRmFsc2UsICJGb3JtQ29udHJvbGxlcjo6YWRkU3RhdHVzTGlzdGVuZXI6IGludmFsaWQgKHVuc3VwcG9ydGVkKSBVUkwhIik7Cn0KCi8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tClJlZmVyZW5jZTwgWEludGVyZmFjZSA+IFNBTF9DQUxMIEZvcm1Db250cm9sbGVyOjpnZXRQYXJlbnQoKSB0aHJvdyggUnVudGltZUV4Y2VwdGlvbiApCnsKICAgIHJldHVybiBtX3hQYXJlbnQ7Cn0KCi8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCnZvaWQgU0FMX0NBTEwgRm9ybUNvbnRyb2xsZXI6OnNldFBhcmVudCggY29uc3QgUmVmZXJlbmNlPCBYSW50ZXJmYWNlID4mIFBhcmVudCkgdGhyb3coIE5vU3VwcG9ydEV4Y2VwdGlvbiwgUnVudGltZUV4Y2VwdGlvbiApCnsKICAgIG1feFBhcmVudCA9IFBhcmVudDsKfQoKLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0Kdm9pZCBTQUxfQ0FMTCBGb3JtQ29udHJvbGxlcjo6cmVtb3ZlU3RhdHVzTGlzdGVuZXIoIGNvbnN0IFJlZmVyZW5jZTwgWFN0YXR1c0xpc3RlbmVyID4mIC8qX3J4TGlzdGVuZXIqLywgY29uc3QgVVJMJiBfclVSTCApIHRocm93IChSdW50aW1lRXhjZXB0aW9uKQp7CiAgICAodm9pZClfclVSTDsKCU9TTF9FTlNVUkUoX3JVUkwuQ29tcGxldGUgPT0gRk1VUkxfQ09ORklSTV9ERUxFVElPTiwgIkZvcm1Db250cm9sbGVyOjpyZW1vdmVTdGF0dXNMaXN0ZW5lcjogaW52YWxpZCAodW5zdXBwb3J0ZWQpIFVSTCEiKTsKCS8vIHdlIG5ldmVyIHJlYWxseSBhZGRlZCB0aGUgbGlzdGVuZXIsIHNvIHdlIGRvbid0IG5lZWQgdG8gcmVtb3ZlIGl0Cn0KCi8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tClJlZmVyZW5jZTwgWERpc3BhdGNoUHJvdmlkZXJJbnRlcmNlcHRvciA+ICBGb3JtQ29udHJvbGxlcjo6Y3JlYXRlSW50ZXJjZXB0b3IoY29uc3QgUmVmZXJlbmNlPCBYRGlzcGF0Y2hQcm92aWRlckludGVyY2VwdGlvbiA+ICYgX3hJbnRlcmNlcHRpb24pCnsKICAgIE9TTF9FTlNVUkUoICFpbXBsX2lzRGlzcG9zZWRfbm9mYWlsKCksICJGb3JtQ29udHJvbGxlcjogYWxyZWFkeSBkaXNwb3NlZCEiICk7CiNpZmRlZiBEQkdfVVRJTAogICAgLy8gY2hlY2sgaWYgd2UgYWxyZWFkeSBoYXZlIGEgaW50ZXJjZXB0b3IgZm9yIHRoZSBnaXZlbiBvYmplY3QKICAgIGZvciAoICAgQ29uc3RJbnRlcmNlcHRvcnNJdGVyYXRvciBhSXRlciA9IG1fYUNvbnRyb2xEaXNwYXRjaEludGVyY2VwdG9ycy5iZWdpbigpOwogICAgICAgICAgICBhSXRlciAhPSBtX2FDb250cm9sRGlzcGF0Y2hJbnRlcmNlcHRvcnMuZW5kKCk7CiAgICAgICAgICAgICsrYUl0ZXIKICAgICAgICApCiAgICB7CiAgICAgICAgaWYgKCgqYUl0ZXIpLT5nZXRJbnRlcmNlcHRlZCgpID09IF94SW50ZXJjZXB0aW9uKQogICAgICAgICAgICBEQkdfRVJST1IoIkZvcm1Db250cm9sbGVyOjpjcmVhdGVJbnRlcmNlcHRvciA6IHdlIGFscmVhZHkgZG8gaW50ZXJjZXB0IHRoaXMgb2JqZWN0cyBkaXNwYXRjaGVzICEiKTsKICAgIH0KI2VuZGlmCgogICAgRGlzcGF0Y2hJbnRlcmNlcHRpb25NdWx0aXBsZXhlciogcEludGVyY2VwdG9yID0gbmV3IERpc3BhdGNoSW50ZXJjZXB0aW9uTXVsdGlwbGV4ZXIoIF94SW50ZXJjZXB0aW9uLCB0aGlzICk7CiAgICBwSW50ZXJjZXB0b3ItPmFjcXVpcmUoKTsKICAgIG1fYUNvbnRyb2xEaXNwYXRjaEludGVyY2VwdG9ycy5pbnNlcnQoIG1fYUNvbnRyb2xEaXNwYXRjaEludGVyY2VwdG9ycy5lbmQoKSwgcEludGVyY2VwdG9yICk7CgogICAgcmV0dXJuIHBJbnRlcmNlcHRvcjsKfQoKLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KYm9vbCBGb3JtQ29udHJvbGxlcjo6ZW5zdXJlSW50ZXJhY3Rpb25IYW5kbGVyKCkKewogICAgaWYgKCBtX3hJbnRlcmFjdGlvbkhhbmRsZXIuaXMoKSApCiAgICAgICAgcmV0dXJuIHRydWU7CiAgICBpZiAoIG1fYkF0dGVtcHRlZEhhbmRsZXJDcmVhdGlvbiApCiAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgbV9iQXR0ZW1wdGVkSGFuZGxlckNyZWF0aW9uID0gdHJ1ZTsKCiAgICBtX3hJbnRlcmFjdGlvbkhhbmRsZXIuc2V0KCBtX2FDb250ZXh0LmNyZWF0ZUNvbXBvbmVudCggOjpydGw6Ok9VU3RyaW5nKCBSVExfQ09OU1RBU0NJSV9VU1RSSU5HUEFSQU0oICJjb20uc3VuLnN0YXIudGFzay5JbnRlcmFjdGlvbkhhbmRsZXIiICkgKSApLCBVTk9fUVVFUlkgKTsKICAgIE9TTF9FTlNVUkUoIG1feEludGVyYWN0aW9uSGFuZGxlci5pcygpLCAiRm9ybUNvbnRyb2xsZXI6OmVuc3VyZUludGVyYWN0aW9uSGFuZGxlcjogY291bGQgbm90IGNyZWF0ZSBhbiBpbnRlcmFjdGlvbiBoYW5kbGVyISIgKTsKICAgIHJldHVybiBtX3hJbnRlcmFjdGlvbkhhbmRsZXIuaXMoKTsKfQoKLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0Kdm9pZCBTQUxfQ0FMTCBGb3JtQ29udHJvbGxlcjo6aGFuZGxlKCBjb25zdCBSZWZlcmVuY2U8IFhJbnRlcmFjdGlvblJlcXVlc3QgPiYgX3JSZXF1ZXN0ICkgdGhyb3cgKFJ1bnRpbWVFeGNlcHRpb24pCnsKICAgIGlmICggIWVuc3VyZUludGVyYWN0aW9uSGFuZGxlcigpICkKICAgICAgICByZXR1cm47CiAgICBtX3hJbnRlcmFjdGlvbkhhbmRsZXItPmhhbmRsZSggX3JSZXF1ZXN0ICk7Cn0KCi8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCnZvaWQgRm9ybUNvbnRyb2xsZXI6OmRlbGV0ZUludGVyY2VwdG9yKGNvbnN0IFJlZmVyZW5jZTwgWERpc3BhdGNoUHJvdmlkZXJJbnRlcmNlcHRpb24gPiAmIF94SW50ZXJjZXB0aW9uKQp7CiAgICBPU0xfRU5TVVJFKCAhaW1wbF9pc0Rpc3Bvc2VkX25vZmFpbCgpLCAiRm9ybUNvbnRyb2xsZXI6IGFscmVhZHkgZGlzcG9zZWQhIiApOwogICAgLy8gc2VhcmNoIHRoZSBpbnRlcmNlcHRvciByZXNwb25zaWJsZSBmb3IgdGhlIGdpdmVuIG9iamVjdAogICAgSW50ZXJjZXB0b3JzSXRlcmF0b3IgYUl0ZXI7CiAgICBmb3IgKCAgIGFJdGVyID0gbV9hQ29udHJvbERpc3BhdGNoSW50ZXJjZXB0b3JzLmJlZ2luKCk7CiAgICAgICAgICAgIGFJdGVyICE9IG1fYUNvbnRyb2xEaXNwYXRjaEludGVyY2VwdG9ycy5lbmQoKTsKICAgICAgICAgICAgKythSXRlcgogICAgICAgICkKICAgIHsKICAgICAgICBpZiAoKCphSXRlciktPmdldEludGVyY2VwdGVkKCkgPT0gX3hJbnRlcmNlcHRpb24pCiAgICAgICAgICAgIGJyZWFrOwogICAgfQogICAgaWYgKGFJdGVyID09IG1fYUNvbnRyb2xEaXNwYXRjaEludGVyY2VwdG9ycy5lbmQoKSkKICAgIHsKICAgICAgICByZXR1cm47CiAgICB9CgogICAgLy8gbG9nIG9mZiB0aGUgaW50ZXJjZXB0aW9uIGZyb20gaXQncyBpbnRlcmNlcHRpb24gb2JqZWN0CiAgICBEaXNwYXRjaEludGVyY2VwdGlvbk11bHRpcGxleGVyKiBwSW50ZXJjZXB0b3JJbXBsID0gKmFJdGVyOwogICAgcEludGVyY2VwdG9ySW1wbC0+ZGlzcG9zZSgpOwogICAgcEludGVyY2VwdG9ySW1wbC0+cmVsZWFzZSgpOwoKICAgIC8vIHJlbW92ZSB0aGUgaW50ZXJjZXB0b3IgZnJvbSBvdXIgYXJyYXkKICAgIG1fYUNvbnRyb2xEaXNwYXRjaEludGVyY2VwdG9ycy5lcmFzZShhSXRlcik7Cn0KCi8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0Kdm9pZCBGb3JtQ29udHJvbGxlcjo6aW1wbEludmFsaWRhdGVDdXJyZW50Q29udHJvbERlcGVuZGVudEZlYXR1cmVzKCkKewogICAgU2VxdWVuY2U8IHNhbF9JbnQxNiA+IGFDdXJyZW50Q29udHJvbERlcGVuZGVudEZlYXR1cmVzKDQpOwoKICAgIGFDdXJyZW50Q29udHJvbERlcGVuZGVudEZlYXR1cmVzWzBdID0gRm9ybUZlYXR1cmU6OlNvcnRBc2NlbmRpbmc7CiAgICBhQ3VycmVudENvbnRyb2xEZXBlbmRlbnRGZWF0dXJlc1sxXSA9IEZvcm1GZWF0dXJlOjpTb3J0RGVzY2VuZGluZzsKICAgIGFDdXJyZW50Q29udHJvbERlcGVuZGVudEZlYXR1cmVzWzJdID0gRm9ybUZlYXR1cmU6OkF1dG9GaWx0ZXI7CiAgICBhQ3VycmVudENvbnRyb2xEZXBlbmRlbnRGZWF0dXJlc1szXSA9IEZvcm1GZWF0dXJlOjpSZWZyZXNoQ3VycmVudENvbnRyb2w7CgogICAgaW52YWxpZGF0ZUZlYXR1cmVzKCBhQ3VycmVudENvbnRyb2xEZXBlbmRlbnRGZWF0dXJlcyApOwp9CgovLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCnZvaWQgU0FMX0NBTEwgRm9ybUNvbnRyb2xsZXI6OmNvbHVtbkNoYW5nZWQoIGNvbnN0IEV2ZW50T2JqZWN0JiAvKl9ldmVudCovICkgdGhyb3cgKFJ1bnRpbWVFeGNlcHRpb24pCnsKICAgIGltcGxJbnZhbGlkYXRlQ3VycmVudENvbnRyb2xEZXBlbmRlbnRGZWF0dXJlcygpOwp9Cgp9ICAgLy8gbmFtZXNwYWNlIHN2eGZvcm0K