LyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIAogKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lCiAqIG9yIG1vcmUgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZQogKiBkaXN0cmlidXRlZCB3aXRoIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbgogKiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4gIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlCiAqIHRvIHlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUKICogIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZQogKiB3aXRoIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqIAogKiAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKiAKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLAogKiBzb2Z0d2FyZSBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbgogKiAiQVMgSVMiIEJBU0lTLCBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkKICogS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4gIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlCiAqIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQgbGltaXRhdGlvbnMKICogdW5kZXIgdGhlIExpY2Vuc2UuCiAqIAogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KCgoKLy8gTUFSS0VSKHVwZGF0ZV9wcmVjb21wLnB5KTogYXV0b2dlbiBpbmNsdWRlIHN0YXRlbWVudCwgZG8gbm90IHJlbW92ZQojaW5jbHVkZSAicHJlY29tcGlsZWRfc2QuaHh4IgoKI2luY2x1ZGUgIkVkaXRXaW5kb3cuaHh4IgoKI2luY2x1ZGUgInNkbW9kLmh4eCIKI2luY2x1ZGUgPGkxOG5wb29sL21zbGFuZ2lkLmh4eD4KI2luY2x1ZGUgPGNvbS9zdW4vc3Rhci9pMThuL1NjcmlwdFR5cGUuaHBwPgojaW5jbHVkZSA8ZWRpdGVuZy9lZGl0ZW5nLmh4eD4KI2luY2x1ZGUgPGVkaXRlbmcvZWRpdHZpZXcuaHh4PgojaW5jbHVkZSA8dmNsL3NjcmJhci5oeHg+CiNpbmNsdWRlIDxlZGl0ZW5nL2VlaXRlbS5oeHg+CiNpbmNsdWRlICJzZHJlc2lkLmh4eCIKI2luY2x1ZGUgPHN2bC9pdGVtcG9vbC5oeHg+CiNpbmNsdWRlIDxlZGl0ZW5nL2ZoZ3RpdGVtLmh4eD4KI2luY2x1ZGUgPHZvcy9tdXRleC5oeHg+CiNpbmNsdWRlIDx2Y2wvc3ZhcHAuaHh4PgojaW5jbHVkZSA8dW5vdG9vbHMvbGluZ3Vwcm9wcy5oeHg+CiNpbmNsdWRlIDx1bm90b29scy9saW5ndWNmZy5oeHg+CiNpbmNsdWRlIDxlZGl0ZW5nL2ZvbnRpdGVtLmh4eD4KI2luY2x1ZGUgPGVkaXRlbmcvZWRpdHN0YXQuaHh4PgoKI2RlZmluZSBTQ1JPTExfTElORSAJCTI0Cgp1c2luZyBuYW1lc3BhY2UgY29tOjpzdW46OnN0YXI6OmFjY2Vzc2liaWxpdHk7CnVzaW5nIG5hbWVzcGFjZSBjb206OnN1bjo6c3RhcjsKdXNpbmcgbmFtZXNwYWNlIGNvbTo6c3VuOjpzdGFyOjp1bm87CgpuYW1lc3BhY2Ugc2QgeyBuYW1lc3BhY2Ugbm90ZXMgewoKRWRpdFdpbmRvdzo6RWRpdFdpbmRvdyAoV2luZG93KiBwUGFyZW50V2luZG93LCBTZnhJdGVtUG9vbCogcEl0ZW1Qb29sKQogICAgOiBXaW5kb3cgKHBQYXJlbnRXaW5kb3csIFdpbkJpdHMoKSksCiAgICAgIERyb3BUYXJnZXRIZWxwZXIodGhpcyksCiAgICAgIG1wRWRpdFZpZXcoTlVMTCksCiAgICAgIG1wRWRpdEVuZ2luZShOVUxMKSwKICAgICAgbXBIb3Jpem9udGFsU2Nyb2xsQmFyKE5VTEwpLAogICAgICBtcFZlcnRpY2FsU2Nyb2xsQmFyKE5VTEwpLAogICAgICBtcFNjcm9sbEJveChOVUxMKQp7CglTZXRNYXBNb2RlKE1BUF9QSVhFTCk7CgogICAgLy8gY29tcGFyZSBEYXRhQ2hhbmdlZAoJU2V0QmFja2dyb3VuZCAoR2V0U2V0dGluZ3MoKS5HZXRTdHlsZVNldHRpbmdzKCkuR2V0V2luZG93Q29sb3IoKSk7CgoJbWFNb2RpZnlUaW1lci5TZXRUaW1lb3V0KDIwMDApOwoJbWFNb2RpZnlUaW1lci5TdGFydCgpOwoKCW1hQ3Vyc29yTW92ZVRpbWVyLlNldFRpbWVvdXQoNTAwKTsKCiAgICBDcmVhdGVFZGl0VmlldygpOwoKICAgIFN2eEZvbnRIZWlnaHRJdGVtIGFJdGVtIChHZXRGb250KCkuR2V0U2l6ZSgpLkhlaWdodCgpLCAxMDAsCiAgICAgICAgRUVfQ0hBUl9GT05USEVJR0hUKTsKICAgIHBJdGVtUG9vbC0+U2V0UG9vbERlZmF1bHRJdGVtIChhSXRlbSk7CiAgICBhSXRlbS5TZXRXaGljaChFRV9DSEFSX0ZPTlRIRUlHSFRfQ0pLKTsKICAgIHBJdGVtUG9vbC0+U2V0UG9vbERlZmF1bHRJdGVtIChhSXRlbSk7CiAgICBhSXRlbS5TZXRXaGljaChFRV9DSEFSX0ZPTlRIRUlHSFRfQ1RMKTsKICAgIHBJdGVtUG9vbC0+U2V0UG9vbERlZmF1bHRJdGVtIChhSXRlbSk7CgogICAgSW5zZXJ0VGV4dCAoVW5pU3RyaW5nOjpDcmVhdGVGcm9tQXNjaWkoIkVkaXRXaW5kb3cgY3JlYXRlZCBhbmQgcmVhZHkuXG4iKSk7Cn0KCgpFZGl0V2luZG93Ojp+RWRpdFdpbmRvdyAodm9pZCkKewoJbWFDdXJzb3JNb3ZlVGltZXIuU3RvcCgpOwoJbWFNb2RpZnlUaW1lci5TdG9wKCk7CgogICAgaWYgKG1wRWRpdFZpZXcgIT0gTlVMTCkKICAgIHsKICAgICAgICBFZGl0RW5naW5lICpwRWRpdEVuZ2luZSA9IG1wRWRpdFZpZXctPkdldEVkaXRFbmdpbmUoKTsKICAgICAgICBpZiAocEVkaXRFbmdpbmUpCiAgICAgICAgewogICAgICAgICAgICBwRWRpdEVuZ2luZS0+U2V0U3RhdHVzRXZlbnRIZGwoTGluaygpKTsKICAgICAgICAgICAgcEVkaXRFbmdpbmUtPlJlbW92ZVZpZXcgKG1wRWRpdFZpZXcpOwogICAgICAgIH0KICAgIH0KCWRlbGV0ZSBtcEVkaXRWaWV3OwoJZGVsZXRlIG1wSG9yaXpvbnRhbFNjcm9sbEJhcjsKCWRlbGV0ZSBtcFZlcnRpY2FsU2Nyb2xsQmFyOwoJZGVsZXRlIG1wU2Nyb2xsQm94OwoKfQoKLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLwoKCnZvaWQgU21HZXRMZWZ0U2VsZWN0aW9uUGFydChjb25zdCBFU2VsZWN0aW9uIGFTZWwsCgkJCQkJCQlzYWxfdUludDE2ICZuUGFyYSwgc2FsX3VJbnQxNiAmblBvcykKCS8vIHJldHVybnMgcGFyYWdyYXBoIG51bWJlciBhbmQgcG9zaXRpb24gb2YgdGhlIHNlbGVjdGlvbnMgbGVmdCBwYXJ0CnsKCS8vIGNvbXBhcmUgc3RhcnQgYW5kIGVuZCBvZiBzZWxlY3Rpb24gYW5kIHVzZSB0aGUgb25lIHRoYXQgY29tZXMgZmlyc3QKCWlmICgKICAgICAgICAoYVNlbC5uU3RhcnRQYXJhIDwgIGFTZWwubkVuZFBhcmEpIHx8CiAgICAgICAgKGFTZWwublN0YXJ0UGFyYSA9PSBhU2VsLm5FbmRQYXJhICYmIGFTZWwublN0YXJ0UG9zIDwgYVNlbC5uRW5kUG9zKQogICAgICAgKQoJewluUGFyYSA9IGFTZWwublN0YXJ0UGFyYTsKCQluUG9zICA9IGFTZWwublN0YXJ0UG9zOwoJfQoJZWxzZQoJewluUGFyYSA9IGFTZWwubkVuZFBhcmE7CgkJblBvcyAgPSBhU2VsLm5FbmRQb3M7Cgl9Cn0KCgoKCkVkaXRFbmdpbmUgKiBFZGl0V2luZG93OjpHZXRFZGl0RW5naW5lICh2b2lkKQp7CiAgICBpZiAobXBFZGl0RW5naW5lID09IE5VTEwpCiAgICAgICAgbXBFZGl0RW5naW5lID0gQ3JlYXRlRWRpdEVuZ2luZSAoKTsKICAgIHJldHVybiBtcEVkaXRFbmdpbmU7Cn0KCgoKCkVkaXRFbmdpbmUqIEVkaXRXaW5kb3c6OkNyZWF0ZUVkaXRFbmdpbmUgKHZvaWQpCnsKICAgIEVkaXRFbmdpbmUqIHBFZGl0RW5naW5lID0gbXBFZGl0RW5naW5lOwoJaWYgKHBFZGl0RW5naW5lID09IE5VTEwpCgl7CgkJbXBFZGl0RW5naW5lSXRlbVBvb2wgPSBFZGl0RW5naW5lOjpDcmVhdGVQb29sKCk7CgogICAgICAgIC8vCiAgICAgICAgLy8gc2V0IGZvbnRzIHRvIGJlIHVzZWQKICAgICAgICAvLwogICAgICAgIFN2dExpbmd1T3B0aW9ucyBhT3B0OwogICAgICAgIFN2dExpbmd1Q29uZmlnKCkuR2V0T3B0aW9ucyggYU9wdCApOwogICAgICAgIC8vCiAgICAgICAgc3RydWN0IEZvbnREdGEgewogICAgICAgICAgICBzYWxfSW50MTYgICAgICAgbkZhbGxiYWNrTGFuZzsKICAgICAgICAgICAgc2FsX0ludDE2ICAgICAgIG5MYW5nOwogICAgICAgICAgICBzYWxfdUludDE2ICAgICAgbkZvbnRUeXBlOwogICAgICAgICAgICBzYWxfdUludDE2ICAgICAgbkZvbnRJbmZvSWQ7CiAgICAgICAgICAgIH0gYVRhYmxlWzNdID0KICAgICAgICB7CiAgICAgICAgICAgIC8vIGluZm8gdG8gZ2V0IHdlc3Rlcm4gZm9udCB0byBiZSB1c2VkCiAgICAgICAgICAgIHsgICBMQU5HVUFHRV9FTkdMSVNIX1VTLCAgICBMQU5HVUFHRV9OT05FLAogICAgICAgICAgICAgICAgREVGQVVMVEZPTlRfU0VSSUYsICAgICAgRUVfQ0hBUl9GT05USU5GTyB9LAogICAgICAgICAgICAvLyBpbmZvIHRvIGdldCBDSksgZm9udCB0byBiZSB1c2VkCiAgICAgICAgICAgIHsgICBMQU5HVUFHRV9KQVBBTkVTRSwgICAgICBMQU5HVUFHRV9OT05FLAogICAgICAgICAgICAgICAgREVGQVVMVEZPTlRfQ0pLX1RFWFQsICAgRUVfQ0hBUl9GT05USU5GT19DSksgfSwKICAgICAgICAgICAgLy8gaW5mbyB0byBnZXQgQ1RMIGZvbnQgdG8gYmUgdXNlZAogICAgICAgICAgICB7ICAgTEFOR1VBR0VfQVJBQklDX1NBVURJX0FSQUJJQSwgIExBTkdVQUdFX05PTkUsCiAgICAgICAgICAgICAgICBERUZBVUxURk9OVF9DVExfVEVYVCwgICBFRV9DSEFSX0ZPTlRJTkZPX0NUTCB9CiAgICAgICAgfTsKICAgICAgICBhVGFibGVbMF0ubkxhbmcgPSBNc0xhbmdJZDo6cmVzb2x2ZVN5c3RlbUxhbmd1YWdlQnlTY3JpcHRUeXBlKGFPcHQubkRlZmF1bHRMYW5ndWFnZSwgOjpjb206OnN1bjo6c3Rhcjo6aTE4bjo6U2NyaXB0VHlwZTo6TEFUSU4pOwogICAgICAgIGFUYWJsZVsxXS5uTGFuZyA9IE1zTGFuZ0lkOjpyZXNvbHZlU3lzdGVtTGFuZ3VhZ2VCeVNjcmlwdFR5cGUoYU9wdC5uRGVmYXVsdExhbmd1YWdlX0NKSywgOjpjb206OnN1bjo6c3Rhcjo6aTE4bjo6U2NyaXB0VHlwZTo6QVNJQU4pOwogICAgICAgIGFUYWJsZVsyXS5uTGFuZyA9IE1zTGFuZ0lkOjpyZXNvbHZlU3lzdGVtTGFuZ3VhZ2VCeVNjcmlwdFR5cGUoYU9wdC5uRGVmYXVsdExhbmd1YWdlX0NUTCwgOjpjb206OnN1bjo6c3Rhcjo6aTE4bjo6U2NyaXB0VHlwZTo6Q09NUExFWCk7CiAgICAgICAgLy8KICAgICAgICBmb3IgKGludCBpID0gMDsgIGkgPCAzOyAgKytpKQogICAgICAgIHsKICAgICAgICAgICAgY29uc3QgRm9udER0YSAmckZudER0YSA9IGFUYWJsZVtpXTsKICAgICAgICAgICAgTGFuZ3VhZ2VUeXBlIG5MYW5nID0gKExBTkdVQUdFX05PTkUgPT0gckZudER0YS5uTGFuZykgPwogICAgICAgICAgICAgICAgckZudER0YS5uRmFsbGJhY2tMYW5nIDogckZudER0YS5uTGFuZzsKICAgICAgICAgICAgRm9udCBhRm9udCA9IEFwcGxpY2F0aW9uOjpHZXREZWZhdWx0RGV2aWNlKCktPkdldERlZmF1bHRGb250KAogICAgICAgICAgICAgICAgckZudER0YS5uRm9udFR5cGUsIG5MYW5nLCBERUZBVUxURk9OVF9GTEFHU19PTkxZT05FKTsKICAgICAgICAgICAgbXBFZGl0RW5naW5lSXRlbVBvb2wtPlNldFBvb2xEZWZhdWx0SXRlbSgKICAgICAgICAgICAgICAgIFN2eEZvbnRJdGVtKAogICAgICAgICAgICAgICAgICAgIGFGb250LkdldEZhbWlseSgpLAogICAgICAgICAgICAgICAgICAgIGFGb250LkdldE5hbWUoKSwKICAgICAgICAgICAgICAgICAgICBhRm9udC5HZXRTdHlsZU5hbWUoKSwKICAgICAgICAgICAgICAgICAgICBhRm9udC5HZXRQaXRjaCgpLAogICAgICAgICAgICAgICAgICAgIGFGb250LkdldENoYXJTZXQoKSwKICAgICAgICAgICAgICAgICAgICByRm50RHRhLm5Gb250SW5mb0lkKSk7CiAgICAgICAgfQoKICAgICAgICAvLyBzZXQgZm9udCBoZWlnaHRzCgkJU3Z4Rm9udEhlaWdodEl0ZW0gYUZvbnRIZWlndCgKICAgICAgICAgICAgQXBwbGljYXRpb246OkdldERlZmF1bHREZXZpY2UoKS0+TG9naWNUb1BpeGVsKAogICAgICAgICAgICAgICAgU2l6ZSAoMCwgMTApLCBNYXBNb2RlIChNQVBfUE9JTlQpKS5IZWlnaHQoKSwgMTAwLAogICAgICAgICAgICBFRV9DSEFSX0ZPTlRIRUlHSFQgKTsKCQltcEVkaXRFbmdpbmVJdGVtUG9vbC0+U2V0UG9vbERlZmF1bHRJdGVtKCBhRm9udEhlaWd0KTsKCQlhRm9udEhlaWd0LlNldFdoaWNoIChFRV9DSEFSX0ZPTlRIRUlHSFRfQ0pLKTsKCQltcEVkaXRFbmdpbmVJdGVtUG9vbC0+U2V0UG9vbERlZmF1bHRJdGVtKCBhRm9udEhlaWd0KTsKCQlhRm9udEhlaWd0LlNldFdoaWNoIChFRV9DSEFSX0ZPTlRIRUlHSFRfQ1RMKTsKCQltcEVkaXRFbmdpbmVJdGVtUG9vbC0+U2V0UG9vbERlZmF1bHRJdGVtKCBhRm9udEhlaWd0KTsKCgkJcEVkaXRFbmdpbmUgPSBuZXcgRWRpdEVuZ2luZSAobXBFZGl0RW5naW5lSXRlbVBvb2wpOwoKCQlwRWRpdEVuZ2luZS0+RW5hYmxlVW5kbyAoc2FsX1RydWUpOwoJCXBFZGl0RW5naW5lLT5TZXREZWZUYWIgKHNhbF91SW50MTYoCgkJCUFwcGxpY2F0aW9uOjpHZXREZWZhdWx0RGV2aWNlKCktPkdldFRleHRXaWR0aCgKICAgICAgICAgICAgICAgIFVuaVN0cmluZzo6Q3JlYXRlRnJvbUFzY2lpKCJYWFhYIikpKSk7CgoJCXBFZGl0RW5naW5lLT5TZXRDb250cm9sV29yZCgKCQkJCShwRWRpdEVuZ2luZS0+R2V0Q29udHJvbFdvcmQoKQogICAgICAgICAgICAgICAgICAgIHwgRUVfQ05UUkxfQVVUT0lOREVOVElORykgJgoJCQkJKH5FRV9DTlRSTF9VTkRPQVRUUklCUykgJgoJCQkJKH5FRV9DTlRSTF9QQVNURVNQRUNJQUwpKTsKCgkJcEVkaXRFbmdpbmUtPlNldFdvcmREZWxpbWl0ZXJzICgKICAgICAgICAgICAgVW5pU3RyaW5nOjpDcmVhdGVGcm9tQXNjaWkoIiAuPSstKi8oKXt9W107XCIiKSk7CgkJcEVkaXRFbmdpbmUtPlNldFJlZk1hcE1vZGUgKE1BUF9QSVhFTCk7CgkJcEVkaXRFbmdpbmUtPlNldFBhcGVyU2l6ZSAoU2l6ZSg4MDAsIDApKTsKCQlwRWRpdEVuZ2luZS0+RXJhc2VWaXJ0dWFsRGV2aWNlKCk7CgkJcEVkaXRFbmdpbmUtPkNsZWFyTW9kaWZ5RmxhZygpOwoJfQoKCXJldHVybiBwRWRpdEVuZ2luZTsKfQoKCgoKdm9pZCBFZGl0V2luZG93OjpEYXRhQ2hhbmdlZCAoY29uc3QgRGF0YUNoYW5nZWRFdmVudCYpCnsKICAgIGNvbnN0IFN0eWxlU2V0dGluZ3MgYVNldHRpbmdzIChHZXRTZXR0aW5ncygpLkdldFN0eWxlU2V0dGluZ3MoKSk7CgogICAgU2V0QmFja2dyb3VuZCggYVNldHRpbmdzLkdldFdpbmRvd0NvbG9yKCkgKTsKCiAgICAvLyBlZGl0IGZpZWxkcyBpbiBvdGhlciBBcHBsaWNhdGlvbnMgdXNlIHRoaXMgZm9udCBpbnN0ZWFkIG9mCiAgICAvLyB0aGUgYXBwbGljYXRpb24gZm9udCB0aHVzIHdlIHVzZSB0aGlzIG9uZSB0b28KICAgIFNldFBvaW50Rm9udCggYVNldHRpbmdzLkdldEZpZWxkRm9udCgpICk7CiAgICBFZGl0RW5naW5lKiBwRWRpdEVuZ2luZSA9IEdldEVkaXRFbmdpbmUoKTsKCglpZiAocEVkaXRFbmdpbmUhPU5VTEwgJiYgbXBFZGl0RW5naW5lSXRlbVBvb2whPU5VTEwpCgl7CiAgICAgICAgLy8hCiAgICAgICAgLy8hIHNlZSBhbHNvIFNtRG9jU2hlbGw6OkdldEVkaXRFbmdpbmUoKSAhCiAgICAgICAgLy8hCgogICAgICAgIC8vCQlwRWRpdEVuZ2luZS0+U2V0RGVmVGFiKCBzYWxfdUludDE2KCBHZXRUZXh0V2lkdGgoIEMyUygiWFhYWCIpICkgKSApOwoKICAgICAgICBzYWxfdUludDE2IGFGbnRJbmZvSWRbM10gPSB7CiAgICAgICAgICAgICAgICBFRV9DSEFSX0ZPTlRJTkZPLCBFRV9DSEFSX0ZPTlRJTkZPX0NKSywgRUVfQ0hBUl9GT05USU5GT19DVEwgfTsKICAgICAgICBmb3IgKGludCBpID0gMDsgIGkgPCAzOyAgKytpKQogICAgICAgIHsKICAgICAgICAgICAgY29uc3QgU2Z4UG9vbEl0ZW0gKnBJdGVtID0gbXBFZGl0RW5naW5lSXRlbVBvb2wtPkdldFBvb2xEZWZhdWx0SXRlbSggIGFGbnRJbmZvSWRbaV0gKTsKICAgICAgICAgICAgaWYoIHBJdGVtICkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgY29uc3QgU3Z4Rm9udEl0ZW0gKnBGbnRJdGVtID0gKChjb25zdCBTdnhGb250SXRlbSAqKSBwSXRlbSk7CiAgICAgICAgICAgICAgICBjb25zdCBGb250ICZyRm50ID0gYVNldHRpbmdzLkdldEZpZWxkRm9udCgpOwogICAgICAgICAgICAgICAgU3Z4Rm9udEl0ZW0gYUZudEl0ZW0oIHJGbnQuR2V0RmFtaWx5KCksIHJGbnQuR2V0TmFtZSgpLAogICAgICAgICAgICAgICAgICAgICAgICByRm50LkdldFN0eWxlTmFtZSgpLCByRm50LkdldFBpdGNoKCksCiAgICAgICAgICAgICAgICAgICAgICAgIHBGbnRJdGVtLT5HZXRDaGFyU2V0KCksCiAgICAgICAgICAgICAgICAgICAgICAgIGFGbnRJbmZvSWRbaV0gKTsKICAgICAgICAgICAgICAgIG1wRWRpdEVuZ2luZUl0ZW1Qb29sLT5TZXRQb29sRGVmYXVsdEl0ZW0oIGFGbnRJdGVtICk7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIFN2eEZvbnRIZWlnaHRJdGVtIGFJdGVtKCBHZXRGb250KCkuR2V0U2l6ZSgpLkhlaWdodCgpLCAxMDAsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEVFX0NIQVJfRk9OVEhFSUdIVCApOwogICAgICAgIG1wRWRpdEVuZ2luZUl0ZW1Qb29sLT5TZXRQb29sRGVmYXVsdEl0ZW0oIGFJdGVtICk7CiAgICAgICAgYUl0ZW0uU2V0V2hpY2goIEVFX0NIQVJfRk9OVEhFSUdIVF9DSksgKTsKICAgICAgICBtcEVkaXRFbmdpbmVJdGVtUG9vbC0+U2V0UG9vbERlZmF1bHRJdGVtKCBhSXRlbSApOwogICAgICAgIGFJdGVtLlNldFdoaWNoKCBFRV9DSEFSX0ZPTlRIRUlHSFRfQ1RMICk7CiAgICAgICAgbXBFZGl0RW5naW5lSXRlbVBvb2wtPlNldFBvb2xEZWZhdWx0SXRlbSggYUl0ZW0gKTsKCgkJLy8gZm9yY2VzIG5ldyBzZXR0aW5ncyB0byBiZSB1c2VkCiAgICAgICAgLy8gdW5mb3J0dW5hdGVseSB0aGlzIHJlc2V0cyB0aGUgd2hvbGUgZWRpdCBlbmdpbmUKICAgICAgICAvLyB0aHVzIHdlIG5lZWQgdG8gc2F2ZSBhdCBsZWFzdCB0aGUgdGV4dAogICAgICAgIFN0cmluZyBhVHh0KCBwRWRpdEVuZ2luZS0+R2V0VGV4dCggTElORUVORF9MRiApICk7CgkJcEVkaXRFbmdpbmUtPkNsZWFyKCk7CS8vIzc3OTU3IGluY29ycmVjdCBmb250IHNpemUKICAgICAgICBwRWRpdEVuZ2luZS0+U2V0VGV4dCggYVR4dCApOwoJfQoKICAgIFN0cmluZyBhVGV4dCAobXBFZGl0RW5naW5lLT5HZXRUZXh0IChMSU5FRU5EX0xGKSk7CiAgICBtcEVkaXRFbmdpbmUtPkNsZWFyKCk7CiAgICBtcEVkaXRFbmdpbmUtPlNldFRleHQgKGFUZXh0KTsKCglBZGp1c3RTY3JvbGxCYXJzKCk7CglSZXNpemUoKTsKfQoKCgoKdm9pZCBFZGl0V2luZG93OjpSZXNpemUgKHZvaWQpCnsKCWlmICghbXBFZGl0VmlldykKCQlDcmVhdGVFZGl0VmlldygpOwoKCWlmIChtcEVkaXRWaWV3ICE9IE5VTEwpCgl7CgkJbXBFZGl0Vmlldy0+U2V0T3V0cHV0QXJlYShBZGp1c3RTY3JvbGxCYXJzKCkpOwoJCW1wRWRpdFZpZXctPlNob3dDdXJzb3IoKTsKCiAgICAgICAgREJHX0FTU0VSVCggbXBFZGl0Vmlldy0+R2V0RWRpdEVuZ2luZSgpLCAiRWRpdEVuZ2luZSBtaXNzaW5nIiApOwoJCWNvbnN0IGxvbmcgbk1heFZpc0FyZWFTdGFydCA9IG1wRWRpdFZpZXctPkdldEVkaXRFbmdpbmUoKS0+R2V0VGV4dEhlaWdodCgpIC0KCQkJCQkJCQkJICBtcEVkaXRWaWV3LT5HZXRPdXRwdXRBcmVhKCkuR2V0SGVpZ2h0KCk7CgkJaWYgKG1wRWRpdFZpZXctPkdldFZpc0FyZWEoKS5Ub3AoKSA+IG5NYXhWaXNBcmVhU3RhcnQpCgkJewoJCQlSZWN0YW5nbGUgYVZpc0FyZWEobXBFZGl0Vmlldy0+R2V0VmlzQXJlYSgpICk7CgkJCWFWaXNBcmVhLlRvcCgpID0gKG5NYXhWaXNBcmVhU3RhcnQgPiAwICkgPyBuTWF4VmlzQXJlYVN0YXJ0IDogMDsKCQkJYVZpc0FyZWEuU2V0U2l6ZShtcEVkaXRWaWV3LT5HZXRPdXRwdXRBcmVhKCkuR2V0U2l6ZSgpKTsKCQkJbXBFZGl0Vmlldy0+U2V0VmlzQXJlYShhVmlzQXJlYSk7CgkJCW1wRWRpdFZpZXctPlNob3dDdXJzb3IoKTsKCQl9CgkJSW5pdFNjcm9sbEJhcnMoKTsKCX0KCUludmFsaWRhdGUoKTsKfQoKCgoKdm9pZCBFZGl0V2luZG93OjpNb3VzZUJ1dHRvblVwKGNvbnN0IE1vdXNlRXZlbnQgJnJFdnQpCnsKCWlmIChtcEVkaXRWaWV3ICE9IE5VTEwpCgkJbXBFZGl0Vmlldy0+TW91c2VCdXR0b25VcChyRXZ0KTsKCWVsc2UKCQlXaW5kb3c6Ok1vdXNlQnV0dG9uVXAgKHJFdnQpOwoKCS8vIGdnZiBGb3JtdWxhQ3Vyc29yIG5ldSBwb3NpdGlvbmllcmVuCiAgICAvLwlDdXJzb3JNb3ZlVGltZXJIZGwoJmFDdXJzb3JNb3ZlVGltZXIpOwp9CgoKCgp2b2lkIEVkaXRXaW5kb3c6Ok1vdXNlQnV0dG9uRG93bihjb25zdCBNb3VzZUV2ZW50ICZyRXZ0KQp7CglpZiAobXBFZGl0VmlldyAhPSBOVUxMKQoJCW1wRWRpdFZpZXctPk1vdXNlQnV0dG9uRG93bihyRXZ0KTsKCWVsc2UKCQlXaW5kb3c6Ok1vdXNlQnV0dG9uRG93biAockV2dCk7CgoJR3JhYkZvY3VzKCk7Cn0KCgoKCnZvaWQgRWRpdFdpbmRvdzo6Q29tbWFuZChjb25zdCBDb21tYW5kRXZlbnQmIHJDRXZ0KQp7CiAgICAvKglpZiAockNFdnQuR2V0Q29tbWFuZCgpID09IENPTU1BTkRfQ09OVEVYVE1FTlUpCgl7CgkJR2V0UGFyZW50KCktPlRvVG9wKCk7CgogICAgICAgIFBvaW50IGFQb2ludCA9IHJDRXZ0LkdldE1vdXNlUG9zUGl4ZWwoKTsKCQlQb3B1cE1lbnUqIHBQb3B1cE1lbnUgPSBuZXcgUG9wdXBNZW51KFNtUmVzSWQoUklEX0NPTU1BTkRNRU5VKSk7CgogICAgICAgIC8vIGFkZGVkIGZvciByZXBsYWNlYWJpbGl0eSBvZiBjb250ZXh0IG1lbnVzICM5NjA4NSwgIzkzNzgyCiAgICAgICAgTWVudSogcE1lbnUgPSBOVUxMOwogICAgICAgIDo6Y29tOjpzdW46OnN0YXI6OnVpOjpDb250ZXh0TWVudUV4ZWN1dGVFdmVudCBhRXZlbnQ7CiAgICAgICAgYUV2ZW50LlNvdXJjZVdpbmRvdyA9IFZDTFVub0hlbHBlcjo6R2V0SW50ZXJmYWNlKCB0aGlzICk7CiAgICAgICAgYUV2ZW50LkV4ZWN1dGVQb3NpdGlvbi5YID0gYVBvaW50LlgoKTsKICAgICAgICBhRXZlbnQuRXhlY3V0ZVBvc2l0aW9uLlkgPSBhUG9pbnQuWSgpOwogICAgICAgIGlmICggR2V0VmlldygpLT5UcnlDb250ZXh0TWVudUludGVyY2VwdGlvbiggKnBQb3B1cE1lbnUsIHBNZW51LCBhRXZlbnQgKSApCiAgICAgICAgewogICAgICAgICAgICBpZiAoIHBNZW51ICkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgZGVsZXRlIHBQb3B1cE1lbnU7CiAgICAgICAgICAgICAgICBwUG9wdXBNZW51ID0gKFBvcHVwTWVudSopIHBNZW51OwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBwUG9wdXBNZW51LT5TZXRTZWxlY3RIZGwoTElOSyh0aGlzLCBFZGl0V2luZG93LCBNZW51U2VsZWN0SGRsKSk7CgogICAgICAgIHBQb3B1cE1lbnUtPkV4ZWN1dGUoIHRoaXMsIGFQb2ludCApOwoJCWRlbGV0ZSBwUG9wdXBNZW51OwoJfQoJZWxzZSovIGlmIChtcEVkaXRWaWV3KQoJCW1wRWRpdFZpZXctPkNvbW1hbmQoIHJDRXZ0ICk7CgllbHNlCgkJV2luZG93OjpDb21tYW5kIChyQ0V2dCk7Cgp9CklNUExfTElOS19JTkxJTkVfU1RBUlQoIEVkaXRXaW5kb3csIE1lbnVTZWxlY3RIZGwsIE1lbnUgKiwgRU1QVFlBUkcgKQp7CiAgICAvKiAgICBTbVZpZXdTaGVsbCAqcFZpZXdTaCA9IHJDbWRCb3guR2V0VmlldygpOwoJaWYgKHBWaWV3U2gpCgkJcFZpZXdTaC0+R2V0Vmlld0ZyYW1lKCktPkdldERpc3BhdGNoZXIoKS0+RXhlY3V0ZSgKCQkJCVNJRF9JTlNFUlRDT01NQU5ELCBTRlhfQ0FMTE1PREVfU1RBTkRBUkQsCgkJCQluZXcgU2Z4SW50MTZJdGVtKFNJRF9JTlNFUlRDT01NQU5ELCBwTWVudS0+R2V0Q3VySXRlbUlkKCkpLCAwTCk7CiovCglyZXR1cm4gMDsKfQpJTVBMX0xJTktfSU5MSU5FX0VORCggRWRpdFdpbmRvdywgTWVudVNlbGVjdEhkbCwgTWVudSAqLCBFTVBUWUFSRyApCgp2b2lkIEVkaXRXaW5kb3c6OktleUlucHV0KGNvbnN0IEtleUV2ZW50JiApCnsKICAgIC8qCWlmIChyS0V2dC5HZXRLZXlDb2RlKCkuR2V0Q29kZSgpID09IEtFWV9FU0NBUEUpCgl7CgkJc2FsX0Jvb2wgYkNhbGxCYXNlID0gc2FsX1RydWU7CgkJU2Z4Vmlld1NoZWxsKiBwVmlld1NoZWxsID0gU2Z4Vmlld1NoZWxsOjpDdXJyZW50KCk7CgkJaWYgKCBwVmlld1NoZWxsICYmIHBWaWV3U2hlbGwtPklTQShTbVZpZXdTaGVsbCkgKQoJCXsKCQkJU21Eb2NTaGVsbCogcERvY1NoID0gKFNtRG9jU2hlbGwqKSBwVmlld1NoZWxsLT5HZXRWaWV3RnJhbWUoKS0+R2V0T2JqZWN0U2hlbGwoKTsKCQkJaWYgKHBEb2NTaCkKCQkJewogICAgLy8gZnVlcnQgenVtIChzb2ZvcnRpZ2VuKSBaZXJzdG9lcmVuIHZvbiB0aGlzIQoJCQkJcERvY1NoLT5Eb0luUGxhY2VBY3RpdmF0ZSggc2FsX0ZhbHNlICk7CgkJCQliQ2FsbEJhc2UgPSBzYWxfRmFsc2U7CgkJCX0KCQl9CgkJaWYgKCBiQ2FsbEJhc2UgKQoJCQlXaW5kb3c6OktleUlucHV0KCByS0V2dCApOwoJfQoJZWxzZQoJewoJCS8vIFRpbWVyIG5ldSBzdGFydGVuLCB1bSBkZW4gSGFuZGxlciAoYXVjaCBiZWkgbORuZ2VyZW4gRWluZ2FiZW4pCgkJLy8gbfZnbGljaHN0IG51ciBlaW5tYWwgYW0gRW5kZSBhdWZ6dXJ1ZmVuLgoJCWFDdXJzb3JNb3ZlVGltZXIuU3RhcnQoKTsKCiAgICAgICAgREJHX0FTU0VSVCggbXBFZGl0VmlldywgIkVkaXRWaWV3IG1pc3NpbmcgKE5VTEwgcG9pbnRlcikiICk7CiAgICAgICAgaWYgKCFtcEVkaXRWaWV3KQogICAgICAgICAgICBDcmVhdGVFZGl0VmlldygpOwoJCWlmICggIW1wRWRpdFZpZXctPlBvc3RLZXlFdmVudChyS0V2dCkgKQoJCXsKCQkJaWYgKCAhU2Z4Vmlld1NoZWxsOjpDdXJyZW50KCktPktleUlucHV0KHJLRXZ0KSApCgkJCXsKICAgIC8vIGZ1ZXJ0IGJlaSBGMSAoSGlsZmUpIHp1bSBaZXJzdG9lcmVuIHZvbiB0aGlzIQoJCQkJRmx1c2goKTsKCQkJCWlmICggYU1vZGlmeVRpbWVyLklzQWN0aXZlKCkgKQoJCQkJCWFNb2RpZnlUaW1lci5TdG9wKCk7CgkJCQlXaW5kb3c6OktleUlucHV0KHJLRXZ0KTsKCQkJfQoJCQllbHNlCgkJCXsKCQkJCS8vU0ZYIGhhdCBldnRsLiBTbG90IGFuIGRlciBWaWV3IGdlY2FsbHQgdW5kIGRhYmVpICh3Zy4gSGFjawoJCQkJLy9pbSBTRlgpIGRlbiBGb2N1cyBhdWYgZGllIFZpZXcgZ2VzZXR6dAoJCQkJU2Z4Vmlld1NoZWxsKiBwVlNoZWxsID0gU2Z4Vmlld1NoZWxsOjpDdXJyZW50KCk7CgkJCQlpZiAoIHBWU2hlbGwgJiYgcFZTaGVsbC0+SVNBKFNtVmlld1NoZWxsKSAmJgoJCQkJCSAoKFNtVmlld1NoZWxsKilwVlNoZWxsKS0+R2V0R3JhcGhpY1dpbmRvdygpLkhhc0ZvY3VzKCkgKQoJCQkJewoJCQkJCUdyYWJGb2N1cygpOwoJCQkJfQoJCQl9CgkJfQoJCWVsc2UKICAgICAgICB7CiAgICAgICAgICAgIC8vIGhhdmUgZG9jLXNoZWxsIG1vZGlmaWVkIG9ubHkgZm9yIGZvcm11bGEgaW5wdXQvY2hhbmdlIGFuZCBub3QKICAgICAgICAgICAgLy8gY3Vyc29yIHRyYXZlbGxpbmcgYW5kIHN1Y2ggdGhpbmdzLi4uCiAgICAgICAgICAgIFNtRG9jU2hlbGwgKnBEb2NTaGVsbCA9IEdldERvYygpOwogICAgICAgICAgICBpZiAocERvY1NoZWxsKQogICAgICAgICAgICAgICAgcERvY1NoZWxsLT5TZXRNb2RpZmllZCggR2V0RWRpdEVuZ2luZSgpLT5Jc01vZGlmaWVkKCkgKTsKCiAgICAgICAgICAgIGFNb2RpZnlUaW1lci5TdGFydCgpOwogICAgICAgIH0KCX0KICAgICovCn0KCgoKCnZvaWQgRWRpdFdpbmRvdzo6UGFpbnQoY29uc3QgUmVjdGFuZ2xlJiByUmVjdCkKewoJaWYgKCFtcEVkaXRWaWV3KQoJCUNyZWF0ZUVkaXRWaWV3KCk7CgltcEVkaXRWaWV3LT5QYWludChyUmVjdCk7Cn0KCgoKCnZvaWQgRWRpdFdpbmRvdzo6Q3JlYXRlRWRpdFZpZXcgKHZvaWQpCnsKICAgIEVkaXRFbmdpbmUqIHBFZGl0RW5naW5lID0gR2V0RWRpdEVuZ2luZSgpOwoKICAgIC8vISBwRWRpdEVuZ2luZSBhbmQgbXBFZGl0VmlldyBtYXkgYmUgMC4KICAgIC8vISBGb3IgZXhhbXBsZSB3aGVuIHRoZSBwcm9ncmFtIGlzIHVzZWQgYnkgdGhlIGRvY3VtZW50LWNvbnZlcnRlcgoJaWYgKG1wRWRpdFZpZXc9PU5VTEwgJiYgcEVkaXRFbmdpbmUhPU5VTEwpCgl7CgkJbXBFZGl0VmlldyA9IG5ldyBFZGl0VmlldyAocEVkaXRFbmdpbmUsIHRoaXMpOwoJCXBFZGl0RW5naW5lLT5JbnNlcnRWaWV3IChtcEVkaXRWaWV3KTsKCiAgICAgICAgaWYgKG1wVmVydGljYWxTY3JvbGxCYXIgPT0gTlVMTCkKICAgICAgICAgICAgbXBWZXJ0aWNhbFNjcm9sbEJhciA9IG5ldyBTY3JvbGxCYXIgKAogICAgICAgICAgICAgICAgdGhpcywgV2luQml0cyhXQl9WU0NST0xMIHwgV0JfRFJBRykpOwogICAgICAgIGlmIChtcEhvcml6b250YWxTY3JvbGxCYXIgPT0gTlVMTCkKICAgICAgICAgICAgbXBIb3Jpem9udGFsU2Nyb2xsQmFyID0gbmV3IFNjcm9sbEJhciAoCiAgICAgICAgICAgICAgICB0aGlzLCBXaW5CaXRzKFdCX0hTQ1JPTEwgfCBXQl9EUkFHKSk7CiAgICAgICAgaWYgKG1wU2Nyb2xsQm94ID09IE5VTEwpCiAgICAgICAgICAgIG1wU2Nyb2xsQm94ICA9IG5ldyBTY3JvbGxCYXJCb3ggKHRoaXMpOwoJCW1wVmVydGljYWxTY3JvbGxCYXItPlNldFNjcm9sbEhkbChMSU5LKHRoaXMsIEVkaXRXaW5kb3csIFNjcm9sbEhkbCkpOwoJCW1wSG9yaXpvbnRhbFNjcm9sbEJhci0+U2V0U2Nyb2xsSGRsKExJTksodGhpcywgRWRpdFdpbmRvdywgU2Nyb2xsSGRsKSk7CgoJCW1wRWRpdFZpZXctPlNldE91dHB1dEFyZWEoQWRqdXN0U2Nyb2xsQmFycygpKTsKCgkJRVNlbGVjdGlvbiBlU2VsZWN0aW9uOwoKCQltcEVkaXRWaWV3LT5TZXRTZWxlY3Rpb24oZVNlbGVjdGlvbik7CgkJVXBkYXRlKCk7CgkJbXBFZGl0Vmlldy0+U2hvd0N1cnNvcihzYWxfVHJ1ZSwgc2FsX1RydWUpOwoKCQlwRWRpdEVuZ2luZS0+U2V0U3RhdHVzRXZlbnRIZGwoCiAgICAgICAgICAgIExJTksodGhpcywgRWRpdFdpbmRvdywgRWRpdFN0YXR1c0hkbCkpOwoJCVNldFBvaW50ZXIobXBFZGl0Vmlldy0+R2V0UG9pbnRlcigpKTsKCgkJU2V0U2Nyb2xsQmFyUmFuZ2VzKCk7Cgl9Cn0KCgoKCklNUExfTElOSyggRWRpdFdpbmRvdywgRWRpdFN0YXR1c0hkbCwgRWRpdFN0YXR1cyAqLCBFTVBUWUFSRyApCnsKICAgIGlmICghbXBFZGl0VmlldykKCQlyZXR1cm4gMTsKCWVsc2UKCXsKCQlTZXRTY3JvbGxCYXJSYW5nZXMoKTsKCQlyZXR1cm4gMDsKCX0KfQoKSU1QTF9MSU5LX0lOTElORV9TVEFSVCggRWRpdFdpbmRvdywgU2Nyb2xsSGRsLCBTY3JvbGxCYXIgKiwgRU1QVFlBUkcgKQp7CiAgICBEQkdfQVNTRVJUKG1wRWRpdFZpZXcsICJFZGl0VmlldyBtaXNzaW5nIik7CiAgICBpZiAobXBFZGl0VmlldykKICAgIHsKICAgICAgICBtcEVkaXRWaWV3LT5TZXRWaXNBcmVhKFJlY3RhbmdsZShQb2ludChtcEhvcml6b250YWxTY3JvbGxCYXItPkdldFRodW1iUG9zKCksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbXBWZXJ0aWNhbFNjcm9sbEJhci0+R2V0VGh1bWJQb3MoKSksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtcEVkaXRWaWV3LT5HZXRWaXNBcmVhKCkuR2V0U2l6ZSgpKSk7CiAgICAgICAgbXBFZGl0Vmlldy0+SW52YWxpZGF0ZSgpOwogICAgfQoJcmV0dXJuIDA7Cn0KSU1QTF9MSU5LX0lOTElORV9FTkQoIEVkaXRXaW5kb3csIFNjcm9sbEhkbCwgU2Nyb2xsQmFyICosIEVNUFRZQVJHICkKClJlY3RhbmdsZSBFZGl0V2luZG93OjpBZGp1c3RTY3JvbGxCYXJzKCkKewoJY29uc3QgU2l6ZSBhT3V0KCBHZXRPdXRwdXRTaXplUGl4ZWwoKSApOwoJUG9pbnQgYVBvaW50OwoJUmVjdGFuZ2xlIGFSZWN0KCBhUG9pbnQsIGFPdXQgKTsKCglpZiAobXBWZXJ0aWNhbFNjcm9sbEJhciAmJiBtcEhvcml6b250YWxTY3JvbGxCYXIgJiYgbXBTY3JvbGxCb3gpCgl7CgkJY29uc3QgbG9uZyBuVG1wID0gR2V0U2V0dGluZ3MoKS5HZXRTdHlsZVNldHRpbmdzKCkuR2V0U2Nyb2xsQmFyU2l6ZSgpOwoJCVBvaW50IGFQdCggYVJlY3QuVG9wUmlnaHQoKSApOyBhUHQuWCgpIC09IG5UbXAgLTFMOwoJCW1wVmVydGljYWxTY3JvbGxCYXItPlNldFBvc1NpemVQaXhlbCggYVB0LCBTaXplKG5UbXAsIGFPdXQuSGVpZ2h0KCkgLSBuVG1wKSk7CgoJCWFQdCA9IGFSZWN0LkJvdHRvbUxlZnQoKTsgYVB0LlkoKSAtPSBuVG1wIC0gMUw7CgkJbXBIb3Jpem9udGFsU2Nyb2xsQmFyLT5TZXRQb3NTaXplUGl4ZWwoIGFQdCwgU2l6ZShhT3V0LldpZHRoKCkgLSBuVG1wLCBuVG1wKSk7CgoJCWFQdC5YKCkgPSBtcEhvcml6b250YWxTY3JvbGxCYXItPkdldFNpemVQaXhlbCgpLldpZHRoKCk7CgkJYVB0LlkoKSA9IG1wVmVydGljYWxTY3JvbGxCYXItPkdldFNpemVQaXhlbCgpLkhlaWdodCgpOwoJCW1wU2Nyb2xsQm94LT5TZXRQb3NTaXplUGl4ZWwoYVB0LCBTaXplKG5UbXAsIG5UbXAgKSk7CgoJCWFSZWN0LlJpZ2h0KCkgID0gYVB0LlgoKSAtIDI7CgkJYVJlY3QuQm90dG9tKCkgPSBhUHQuWSgpIC0gMjsKCX0KCXJldHVybiBhUmVjdDsKfQoKdm9pZCBFZGl0V2luZG93OjpTZXRTY3JvbGxCYXJSYW5nZXMoKQp7CiAgICBFZGl0RW5naW5lKiBwRWRpdEVuZ2luZSA9IEdldEVkaXRFbmdpbmUoKTsKICAgIGlmIChtcEVkaXRWaWV3ICE9IE5VTEwgJiYgcEVkaXRFbmdpbmUgIT0gTlVMTCkKICAgIHsKICAgICAgICBpZiAobXBWZXJ0aWNhbFNjcm9sbEJhciAhPSBOVUxMKQogICAgICAgIHsKICAgICAgICAgICAgbG9uZyBuVG1wID0gcEVkaXRFbmdpbmUtPkdldFRleHRIZWlnaHQoKTsKICAgICAgICAgICAgbXBWZXJ0aWNhbFNjcm9sbEJhci0+U2V0UmFuZ2UoUmFuZ2UoMCwgblRtcCkpOwogICAgICAgICAgICBtcFZlcnRpY2FsU2Nyb2xsQmFyLT5TZXRUaHVtYlBvcyhtcEVkaXRWaWV3LT5HZXRWaXNBcmVhKCkuVG9wKCkpOwogICAgICAgIH0KICAgICAgICBpZiAobXBIb3Jpem9udGFsU2Nyb2xsQmFyICE9IE5VTEwpCiAgICAgICAgewogICAgICAgICAgICBsb25nIG5UbXAgPSBwRWRpdEVuZ2luZS0+R2V0UGFwZXJTaXplKCkuV2lkdGgoKTsKICAgICAgICAgICAgbXBIb3Jpem9udGFsU2Nyb2xsQmFyLT5TZXRSYW5nZShSYW5nZSgwLG5UbXApKTsKICAgICAgICAgICAgbXBIb3Jpem9udGFsU2Nyb2xsQmFyLT5TZXRUaHVtYlBvcyhtcEVkaXRWaWV3LT5HZXRWaXNBcmVhKCkuTGVmdCgpKTsKICAgICAgICB9Cgl9Cn0KCnZvaWQgRWRpdFdpbmRvdzo6SW5pdFNjcm9sbEJhcnMoKQp7CiAgICBpZiAobXBFZGl0VmlldyAhPSBOVUxMKQoJewoJCWNvbnN0IFNpemUgYU91dCggbXBFZGl0Vmlldy0+R2V0T3V0cHV0QXJlYSgpLkdldFNpemUoKSApOwogICAgICAgIGlmIChtcFZlcnRpY2FsU2Nyb2xsQmFyICE9IE5VTEwpCiAgICAgICAgewogICAgICAgICAgICBtcFZlcnRpY2FsU2Nyb2xsQmFyLT5TZXRWaXNpYmxlU2l6ZShhT3V0LkhlaWdodCgpKTsKICAgICAgICAgICAgbXBWZXJ0aWNhbFNjcm9sbEJhci0+U2V0UGFnZVNpemUoYU91dC5IZWlnaHQoKSAqIDggLyAxMCk7CiAgICAgICAgICAgIG1wVmVydGljYWxTY3JvbGxCYXItPlNldExpbmVTaXplKGFPdXQuSGVpZ2h0KCkgKiAyIC8gMTApOwogICAgICAgIH0KCiAgICAgICAgaWYgKG1wSG9yaXpvbnRhbFNjcm9sbEJhciAhPSBOVUxMKQogICAgICAgIHsKICAgICAgICAgICAgbXBIb3Jpem9udGFsU2Nyb2xsQmFyLT5TZXRWaXNpYmxlU2l6ZShhT3V0LldpZHRoKCkpOwogICAgICAgICAgICBtcEhvcml6b250YWxTY3JvbGxCYXItPlNldFBhZ2VTaXplKGFPdXQuV2lkdGgoKSAqIDggLyAxMCk7CiAgICAgICAgICAgIG1wSG9yaXpvbnRhbFNjcm9sbEJhci0+U2V0TGluZVNpemUoU0NST0xMX0xJTkUgKTsKICAgICAgICB9CgoJCVNldFNjcm9sbEJhclJhbmdlcygpOwoKICAgICAgICBpZiAobXBWZXJ0aWNhbFNjcm9sbEJhciAhPSBOVUxMKQogICAgICAgICAgICBtcFZlcnRpY2FsU2Nyb2xsQmFyLT5TaG93KCk7CiAgICAgICAgaWYgKG1wSG9yaXpvbnRhbFNjcm9sbEJhciAhPSBOVUxMKQogICAgICAgICAgICBtcEhvcml6b250YWxTY3JvbGxCYXItPlNob3coKTsKICAgICAgICBpZiAobXBTY3JvbGxCb3ggIT0gTlVMTCkKICAgICAgICAgICAgbXBTY3JvbGxCb3gtPlNob3coKTsKCX0KfQoKClh1YlN0cmluZyBFZGl0V2luZG93OjpHZXRUZXh0KCkKewoJU3RyaW5nIGFUZXh0OwogICAgRWRpdEVuZ2luZSAqcEVkaXRFbmdpbmUgPSBHZXRFZGl0RW5naW5lKCk7CglEQkdfQVNTRVJUKCBwRWRpdEVuZ2luZSwgIkVkaXRFbmdpbmUgbWlzc2luZyIgKTsKCWlmIChwRWRpdEVuZ2luZSkKCQlhVGV4dCA9IHBFZGl0RW5naW5lLT5HZXRUZXh0KCBMSU5FRU5EX0xGICk7CglyZXR1cm4gYVRleHQ7Cn0KCgp2b2lkIEVkaXRXaW5kb3c6OlNldFRleHQoY29uc3QgWHViU3RyaW5nJiByVGV4dCkKewogICAgRWRpdEVuZ2luZSAqcEVkaXRFbmdpbmUgPSBHZXRFZGl0RW5naW5lKCk7CglEQkdfQVNTRVJUKCBwRWRpdEVuZ2luZSwgIkVkaXRFbmdpbmUgbWlzc2luZyIgKTsKCWlmIChwRWRpdEVuZ2luZSAgJiYgICFwRWRpdEVuZ2luZS0+SXNNb2RpZmllZCgpKQoJewoJCWlmICghbXBFZGl0VmlldykKCQkJQ3JlYXRlRWRpdFZpZXcoKTsKCgkJRVNlbGVjdGlvbiBlU2VsZWN0aW9uID0gbXBFZGl0Vmlldy0+R2V0U2VsZWN0aW9uKCk7CgoJCXBFZGl0RW5naW5lLT5TZXRUZXh0KHJUZXh0KTsKCQlwRWRpdEVuZ2luZS0+Q2xlYXJNb2RpZnlGbGFnKCk7CgoJCS8vISBIaWVyIGRpZSBUaW1lciBuZXUgenUgc3RhcnRlbiB2ZXJoaW5kZXJ0LCBkYXNzIGRpZSBIYW5kbGVyIGb8ciBhbmRlcmUKCQkvLyEgKGltIEF1Z2VuYmxpY2sgbmljaHQgbWVociBha3RpdmUpIE1hdGggVGFza3MgYXVmZ2VydWZlbiB3ZXJkZW4uCgkJbWFNb2RpZnlUaW1lci5TdGFydCgpOwoJCW1hQ3Vyc29yTW92ZVRpbWVyLlN0YXJ0KCk7CgoJCW1wRWRpdFZpZXctPlNldFNlbGVjdGlvbihlU2VsZWN0aW9uKTsKCX0KfQoKCnZvaWQgRWRpdFdpbmRvdzo6R2V0Rm9jdXMoKQp7CglXaW5kb3c6OkdldEZvY3VzKCk7CgogICAgaWYgKCFtcEVkaXRWaWV3KQogICAgICAgICBDcmVhdGVFZGl0VmlldygpOwoJaWYgKG1wRWRpdEVuZ2luZSAhPSBOVUxMKQoJCW1wRWRpdEVuZ2luZS0+U2V0U3RhdHVzRXZlbnRIZGwoCiAgICAgICAgICAgIExJTksodGhpcywgRWRpdFdpbmRvdywgRWRpdFN0YXR1c0hkbCkpOwp9CgoKdm9pZCBFZGl0V2luZG93OjpMb3NlRm9jdXMoKQp7CglpZiAobXBFZGl0RW5naW5lICE9IE5VTEwpCgkJbXBFZGl0RW5naW5lLT5TZXRTdGF0dXNFdmVudEhkbCAoTGluaygpKTsKCglXaW5kb3c6Okxvc2VGb2N1cygpOwp9CgoKc2FsX0Jvb2wgRWRpdFdpbmRvdzo6SXNBbGxTZWxlY3RlZCgpIGNvbnN0CnsKICAgIHNhbF9Cb29sIGJSZXMgPSBzYWxfRmFsc2U7CiAgICBFZGl0RW5naW5lICpwRWRpdEVuZ2luZSA9ICgoRWRpdFdpbmRvdyAqKSB0aGlzKS0+R2V0RWRpdEVuZ2luZSgpOwoJREJHX0FTU0VSVCggbXBFZGl0VmlldywgIk5VTEwgcG9pbnRlciIgKTsKICAgIERCR19BU1NFUlQoIHBFZGl0RW5naW5lLCAiTlVMTCBwb2ludGVyIiApOwogICAgaWYgKHBFZGl0RW5naW5lICAmJiAgbXBFZGl0VmlldykKICAgIHsKICAgICAgICBFU2VsZWN0aW9uIGVTZWxlY3Rpb24oIG1wRWRpdFZpZXctPkdldFNlbGVjdGlvbigpICk7CiAgICAgICAgc2FsX0ludDMyIG5QYXJhQ250ID0gcEVkaXRFbmdpbmUtPkdldFBhcmFncmFwaENvdW50KCk7CiAgICAgICAgaWYgKCEoblBhcmFDbnQgLSAxKSkKICAgICAgICB7CiAgICAgICAgICAgIFN0cmluZyBUZXh0KCBwRWRpdEVuZ2luZS0+R2V0VGV4dCggTElORUVORF9MRiApICk7CiAgICAgICAgICAgIGJSZXMgPSAhZVNlbGVjdGlvbi5uU3RhcnRQb3MgJiYgKGVTZWxlY3Rpb24ubkVuZFBvcyA9PSBUZXh0LkxlbiAoKSAtIDEpOwogICAgICAgIH0KICAgICAgICBlbHNlCiAgICAgICAgewogICAgICAgICAgICBiUmVzID0gIWVTZWxlY3Rpb24ublN0YXJ0UGFyYSAmJiAoZVNlbGVjdGlvbi5uRW5kUGFyYSA9PSBuUGFyYUNudCAtIDEpOwogICAgICAgIH0KICAgIH0KICAgIHJldHVybiBiUmVzOwp9Cgp2b2lkIEVkaXRXaW5kb3c6OlNlbGVjdEFsbCgpCnsKCURCR19BU1NFUlQoIG1wRWRpdFZpZXcsICJOVUxMIHBvaW50ZXIiICk7CglpZiAobXBFZGl0VmlldykKCXsKCQkvLyAweEZGRkYgYXMgbGFzdCB0d28gcGFyYW1ldGVycyByZWZlcnMgdG8gdGhlIGVuZCBvZiB0aGUgdGV4dAoJCW1wRWRpdFZpZXctPlNldFNlbGVjdGlvbiggRVNlbGVjdGlvbiggMCwgMCwgMHhGRkZGLCAweEZGRkYgKSApOwoJfQp9CgoKdm9pZCBFZGl0V2luZG93OjpNYXJrRXJyb3IoY29uc3QgUG9pbnQgJnJQb3MpCnsKICAgIERCR19BU1NFUlQoIG1wRWRpdFZpZXcsICJFZGl0VmlldyBtaXNzaW5nIiApOwogICAgaWYgKG1wRWRpdFZpZXcpCiAgICB7CiAgICAgICAgY29uc3QgaW50IENvbCA9IHJQb3MuWCgpOwogICAgICAgIGNvbnN0IGludCBSb3cgPSByUG9zLlkoKSAtIDE7CgogICAgICAgIG1wRWRpdFZpZXctPlNldFNlbGVjdGlvbihFU2VsZWN0aW9uICggKHNhbF91SW50MTYpUm93LCAoc2FsX3VJbnQxNikoQ29sIC0gMSksIChzYWxfdUludDE2KVJvdywgKHNhbF91SW50MTYpQ29sKSk7CiAgICAgICAgR3JhYkZvY3VzKCk7CiAgICB9Cn0KCnZvaWQgRWRpdFdpbmRvdzo6U2VsTmV4dE1hcmsoKQp7CiAgICBFZGl0RW5naW5lICpwRWRpdEVuZ2luZSA9IEdldEVkaXRFbmdpbmUoKTsKCURCR19BU1NFUlQoIG1wRWRpdFZpZXcsICJOVUxMIHBvaW50ZXIiICk7CglEQkdfQVNTRVJUKCBwRWRpdEVuZ2luZSwgIk5VTEwgcG9pbnRlciIgKTsKICAgIGlmIChwRWRpdEVuZ2luZSAgJiYgIG1wRWRpdFZpZXcpCiAgICB7CiAgICAgICAgRVNlbGVjdGlvbiBlU2VsZWN0aW9uID0gbXBFZGl0Vmlldy0+R2V0U2VsZWN0aW9uKCk7CiAgICAgICAgc2FsX3VJbnQxNiAgICAgUG9zICAgICAgICA9IGVTZWxlY3Rpb24ubkVuZFBvczsKICAgICAgICBTdHJpbmcgICAgIGFNYXJrIChVbmlTdHJpbmc6OkNyZWF0ZUZyb21Bc2NpaSgiPD8+IikpOwogICAgICAgIFN0cmluZyAgICAgYVRleHQ7CiAgICAgICAgc2FsX3VJbnQxNiAgICAgbkNvdW50cyAgICA9IHBFZGl0RW5naW5lLT5HZXRQYXJhZ3JhcGhDb3VudCgpOwoKICAgICAgICB3aGlsZSAoZVNlbGVjdGlvbi5uRW5kUGFyYSA8IG5Db3VudHMpCiAgICAgICAgewogICAgICAgICAgICBhVGV4dCA9IHBFZGl0RW5naW5lLT5HZXRUZXh0KCBlU2VsZWN0aW9uLm5FbmRQYXJhICk7CiAgICAgICAgICAgIFBvcyAgID0gYVRleHQuU2VhcmNoKGFNYXJrLCBQb3MpOwoKICAgICAgICAgICAgaWYgKFBvcyAhPSBTVFJJTkdfTk9URk9VTkQpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIG1wRWRpdFZpZXctPlNldFNlbGVjdGlvbihFU2VsZWN0aW9uIChlU2VsZWN0aW9uLm5FbmRQYXJhLCBQb3MsIGVTZWxlY3Rpb24ubkVuZFBhcmEsIFBvcyArIDMpKTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICB9CgogICAgICAgICAgICBQb3MgPSAwOwogICAgICAgICAgICBlU2VsZWN0aW9uLm5FbmRQYXJhKys7CiAgICAgICAgfQogICAgfQp9Cgp2b2lkIEVkaXRXaW5kb3c6OlNlbFByZXZNYXJrKCkKewogICAgRWRpdEVuZ2luZSAqcEVkaXRFbmdpbmUgPSBHZXRFZGl0RW5naW5lKCk7CglEQkdfQVNTRVJUKCBwRWRpdEVuZ2luZSwgIk5VTEwgcG9pbnRlciIgKTsKCURCR19BU1NFUlQoIG1wRWRpdFZpZXcsICJOVUxMIHBvaW50ZXIiICk7CiAgICBpZiAocEVkaXRFbmdpbmUgICYmICBtcEVkaXRWaWV3KQogICAgewogICAgICAgIEVTZWxlY3Rpb24gZVNlbGVjdGlvbiA9IG1wRWRpdFZpZXctPkdldFNlbGVjdGlvbigpOwogICAgICAgIHNhbF91SW50MTYgICAgIFBvcyAgICAgICAgPSBTVFJJTkdfTk9URk9VTkQ7CiAgICAgICAgeHViX1N0ckxlbiBNYXggICAgICAgID0gZVNlbGVjdGlvbi5uU3RhcnRQb3M7CiAgICAgICAgU3RyaW5nICAgICBUZXh0KCBwRWRpdEVuZ2luZS0+R2V0VGV4dCggZVNlbGVjdGlvbi5uU3RhcnRQYXJhICkgKTsKICAgICAgICBTdHJpbmcgICAgIGFNYXJrIChVbmlTdHJpbmc6OkNyZWF0ZUZyb21Bc2NpaSgiPD8+IikpOwogICAgICAgIHNhbF91SW50MTYgICAgIG5Db3VudHMgICAgPSBwRWRpdEVuZ2luZS0+R2V0UGFyYWdyYXBoQ291bnQoKTsKCiAgICAgICAgZG8KICAgICAgICB7CiAgICAgICAgICAgIHNhbF91SW50MTYgRm5kID0gVGV4dC5TZWFyY2goYU1hcmssIDApOwoKICAgICAgICAgICAgd2hpbGUgKChGbmQgPCBNYXgpICYmIChGbmQgIT0gU1RSSU5HX05PVEZPVU5EKSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgUG9zID0gRm5kOwogICAgICAgICAgICAgICAgRm5kID0gVGV4dC5TZWFyY2goYU1hcmssIEZuZCArIDEpOwogICAgICAgICAgICB9CgogICAgICAgICAgICBpZiAoUG9zID09IFNUUklOR19OT1RGT1VORCkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgZVNlbGVjdGlvbi5uU3RhcnRQYXJhLS07CiAgICAgICAgICAgICAgICBUZXh0ID0gcEVkaXRFbmdpbmUtPkdldFRleHQoIGVTZWxlY3Rpb24ublN0YXJ0UGFyYSApOwogICAgICAgICAgICAgICAgTWF4ID0gVGV4dC5MZW4oKTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICB3aGlsZSAoKGVTZWxlY3Rpb24ublN0YXJ0UGFyYSA8IG5Db3VudHMpICYmCiAgICAgICAgICAgIChQb3MgPT0gU1RSSU5HX05PVEZPVU5EKSk7CgogICAgICAgIGlmIChQb3MgIT0gU1RSSU5HX05PVEZPVU5EKQogICAgICAgIHsKICAgICAgICAgICAgbXBFZGl0Vmlldy0+U2V0U2VsZWN0aW9uKEVTZWxlY3Rpb24gKGVTZWxlY3Rpb24ublN0YXJ0UGFyYSwgUG9zLCBlU2VsZWN0aW9uLm5TdGFydFBhcmEsIFBvcyArIDMpKTsKICAgICAgICB9CiAgICB9Cn0KCnNhbF9Cb29sIEVkaXRXaW5kb3c6Okhhc01hcmsoY29uc3QgU3RyaW5nJiByVGV4dCkgY29uc3QKCS8vIHJldHVybnMgdHJ1ZSBpZmYgJ3JUZXh0JyBjb250YWlucyBhIG1hcmsKewoJcmV0dXJuIHJUZXh0LlNlYXJjaEFzY2lpKCI8Pz4iLCAwKSAhPSBTVFJJTkdfTk9URk9VTkQ7Cn0KCnZvaWQgRWRpdFdpbmRvdzo6TW91c2VNb3ZlKGNvbnN0IE1vdXNlRXZlbnQgJnJFdnQpCnsKCWlmIChtcEVkaXRWaWV3KQoJCW1wRWRpdFZpZXctPk1vdXNlTW92ZShyRXZ0KTsKfQoKc2FsX0ludDggRWRpdFdpbmRvdzo6QWNjZXB0RHJvcCggY29uc3QgQWNjZXB0RHJvcEV2ZW50JiApCnsKCXJldHVybiBtcEVkaXRWaWV3ID8gLyptcEVkaXRWaWV3LT5RdWVyeURyb3AoIHJFdnQgKSovRE5EX0FDVElPTl9OT05FOiBETkRfQUNUSU9OX05PTkU7Cn0KCnNhbF9JbnQ4IEVkaXRXaW5kb3c6OkV4ZWN1dGVEcm9wKCBjb25zdCBFeGVjdXRlRHJvcEV2ZW50JiApCnsKCXJldHVybiBtcEVkaXRWaWV3ID8gLyptcEVkaXRWaWV3LT5Ecm9wKCByRXZ0ICkqL0RORF9BQ1RJT05fTk9ORSA6IERORF9BQ1RJT05fTk9ORTsKfQoKRVNlbGVjdGlvbiBFZGl0V2luZG93OjpHZXRTZWxlY3Rpb24oKSBjb25zdAp7CiAgICAvLyBwb2ludGVyIG1heSBiZSAwIHdoZW4gcmVsb2FkaW5nIGEgZG9jdW1lbnQgYW5kIHRoZSBvbGQgdmlldwogICAgLy8gd2FzIGFscmVhZHkgZGVzdHJveWVkCiAgICAvLyhEQkdfQVNTRVJUKCBtcEVkaXRWaWV3LCAiTlVMTCBwb2ludGVyIiApOwoJRVNlbGVjdGlvbiBlU2VsOwoJaWYgKG1wRWRpdFZpZXcpCgkJZVNlbCA9IG1wRWRpdFZpZXctPkdldFNlbGVjdGlvbigpOwoJcmV0dXJuIGVTZWw7Cn0KCnZvaWQgRWRpdFdpbmRvdzo6U2V0U2VsZWN0aW9uKGNvbnN0IEVTZWxlY3Rpb24gJnJTZWwpCnsKCURCR19BU1NFUlQoIG1wRWRpdFZpZXcsICJOVUxMIHBvaW50ZXIiICk7CiAgICBpZiAobXBFZGl0VmlldykKICAgICAgICBtcEVkaXRWaWV3LT5TZXRTZWxlY3Rpb24oclNlbCk7Cn0KCnNhbF9Cb29sIEVkaXRXaW5kb3c6OklzRW1wdHkoKSBjb25zdAp7CiAgICBFZGl0RW5naW5lICpwRWRpdEVuZ2luZSA9ICgoRWRpdFdpbmRvdyAqKSB0aGlzKS0+R2V0RWRpdEVuZ2luZSgpOwogICAgcmV0dXJuIChwRWRpdEVuZ2luZSAmJiAocEVkaXRFbmdpbmUtPkdldFRleHRMZW4oKSA9PSAwKSkgPyBzYWxfVHJ1ZSA6IHNhbF9GYWxzZTsKfQoKc2FsX0Jvb2wgRWRpdFdpbmRvdzo6SXNTZWxlY3RlZCgpIGNvbnN0CnsKICAgIHJldHVybiBtcEVkaXRWaWV3ID8gbXBFZGl0Vmlldy0+SGFzU2VsZWN0aW9uKCkgOiBzYWxfRmFsc2U7Cn0KCnZvaWQgRWRpdFdpbmRvdzo6Q3V0KCkKewogICAgREJHX0FTU0VSVCggbXBFZGl0VmlldywgIkVkaXRWaWV3IG1pc3NpbmciICk7CiAgICBpZiAobXBFZGl0VmlldykKICAgICAgICBtcEVkaXRWaWV3LT5DdXQoKTsKfQoKdm9pZCBFZGl0V2luZG93OjpDb3B5KCkKewogICAgREJHX0FTU0VSVCggbXBFZGl0VmlldywgIkVkaXRWaWV3IG1pc3NpbmciICk7CiAgICBpZiAobXBFZGl0VmlldykKICAgICAgICBtcEVkaXRWaWV3LT5Db3B5KCk7Cn0KCnZvaWQgRWRpdFdpbmRvdzo6UGFzdGUoKQp7CiAgICBEQkdfQVNTRVJUKCBtcEVkaXRWaWV3LCAiRWRpdFZpZXcgbWlzc2luZyIgKTsKICAgIGlmIChtcEVkaXRWaWV3KQogICAgICAgIG1wRWRpdFZpZXctPlBhc3RlKCk7Cn0KCnZvaWQgRWRpdFdpbmRvdzo6RGVsZXRlKCkKewogICAgREJHX0FTU0VSVCggbXBFZGl0VmlldywgIkVkaXRWaWV3IG1pc3NpbmciICk7CiAgICBpZiAobXBFZGl0VmlldykKICAgICAgICBtcEVkaXRWaWV3LT5EZWxldGVTZWxlY3RlZCgpOwp9Cgp2b2lkIEVkaXRXaW5kb3c6Okluc2VydFRleHQoY29uc3QgU3RyaW5nJiBUZXh0KQp7CiAgICBEQkdfQVNTRVJUKCBtcEVkaXRWaWV3LCAiRWRpdFZpZXcgbWlzc2luZyIgKTsKICAgIDo6dm9zOjpPR3VhcmQgYUd1YXJkICg6OkFwcGxpY2F0aW9uOjpHZXRTb2xhck11dGV4KCkpOwogICAgaWYgKG1wRWRpdFZpZXcpCiAgICAgICAgbXBFZGl0Vmlldy0+SW5zZXJ0VGV4dChUZXh0KTsKfQoKCgp9IH0gLy8gZW5kIG9mIG5hbWVzcGFjZSA6OnNkOjpub3Rlcwo=