LyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIAogKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lCiAqIG9yIG1vcmUgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZQogKiBkaXN0cmlidXRlZCB3aXRoIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbgogKiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4gIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlCiAqIHRvIHlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUKICogIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZQogKiB3aXRoIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqIAogKiAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKiAKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLAogKiBzb2Z0d2FyZSBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbgogKiAiQVMgSVMiIEJBU0lTLCBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkKICogS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4gIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlCiAqIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQgbGltaXRhdGlvbnMKICogdW5kZXIgdGhlIExpY2Vuc2UuCiAqIAogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KCgoKLy8gTUFSS0VSKHVwZGF0ZV9wcmVjb21wLnB5KTogYXV0b2dlbiBpbmNsdWRlIHN0YXRlbWVudCwgZG8gbm90IHJlbW92ZQojaW5jbHVkZSAicHJlY29tcGlsZWRfZGJ1aS5oeHgiCgojaW5jbHVkZSAiYWR0YWJkbGcuaHh4IgojaW5jbHVkZSAiYnJvd3Nlcmlkcy5oeHgiCiNpbmNsdWRlICJkYnVfcXJ5LmhyYyIKI2luY2x1ZGUgImRidV9yZWdoZWxwZXIuaHh4IgojaW5jbHVkZSAiZGJ1c3RyaW5ncy5ocmMiCiNpbmNsdWRlICJkZWZhdWx0b2JqZWN0bmFtZWNoZWNrLmh4eCIKI2luY2x1ZGUgImRsZ3NhdmUuaHh4IgojaW5jbHVkZSAibG9jYWxyZXNhY2Nlc3MuaHh4IgojaW5jbHVkZSAiUVRhYmxlV2luZG93Lmh4eCIKI2luY2x1ZGUgIlFUYWJsZVdpbmRvd0RhdGEuaHh4IgojaW5jbHVkZSAicXVlcnljb250YWluZXJ3aW5kb3cuaHh4IgojaW5jbHVkZSAicXVlcnljb250cm9sbGVyLmh4eCIKI2luY2x1ZGUgIlF1ZXJ5RGVzaWduVmlldy5oeHgiCiNpbmNsdWRlICJRdWVyeVRhYmxlVmlldy5oeHgiCiNpbmNsdWRlICJRdWVyeVRleHRWaWV3Lmh4eCIKI2luY2x1ZGUgInF1ZXJ5dmlldy5oeHgiCiNpbmNsdWRlICJRdWVyeVZpZXdTd2l0Y2guaHh4IgojaW5jbHVkZSAic3FsbWVzc2FnZS5oeHgiCiNpbmNsdWRlICJUYWJsZUNvbm5lY3Rpb25EYXRhLmh4eCIKI2luY2x1ZGUgIlRhYmxlRmllbGREZXNjcmlwdGlvbi5oeHgiCiNpbmNsdWRlICJVSVRvb2xzLmh4eCIKCi8qKiA9PT0gYmVnaW4gVU5PIGluY2x1ZGVzID09PSAqKi8KI2luY2x1ZGUgPGNvbS9zdW4vc3Rhci9iZWFucy9Qcm9wZXJ0eUF0dHJpYnV0ZS5ocHA+CiNpbmNsdWRlIDxjb20vc3VuL3N0YXIvY29udGFpbmVyL1hDaGlsZC5ocHA+CiNpbmNsdWRlIDxjb20vc3VuL3N0YXIvY29udGFpbmVyL1hOYW1lQ29udGFpbmVyLmhwcD4KI2luY2x1ZGUgPGNvbS9zdW4vc3Rhci9mcmFtZS9GcmFtZVNlYXJjaEZsYWcuaHBwPgojaW5jbHVkZSA8Y29tL3N1bi9zdGFyL2ZyYW1lL1hMb2FkRXZlbnRMaXN0ZW5lci5ocHA+CiNpbmNsdWRlIDxjb20vc3VuL3N0YXIvaW8vWEFjdGl2ZURhdGFTaW5rLmhwcD4KI2luY2x1ZGUgPGNvbS9zdW4vc3Rhci9pby9YQWN0aXZlRGF0YVNvdXJjZS5ocHA+CiNpbmNsdWRlIDxjb20vc3VuL3N0YXIvc2RiL0NvbW1hbmRUeXBlLmhwcD4KI2luY2x1ZGUgPGNvbS9zdW4vc3Rhci9zZGIvU1FMQ29udGV4dC5ocHA+CiNpbmNsdWRlIDxjb20vc3VuL3N0YXIvc2RiL1hRdWVyaWVzU3VwcGxpZXIuaHBwPgojaW5jbHVkZSA8Y29tL3N1bi9zdGFyL3NkYi9YUXVlcnlEZWZpbml0aW9uc1N1cHBsaWVyLmhwcD4KI2luY2x1ZGUgPGNvbS9zdW4vc3Rhci9zZGIvWFNRTFF1ZXJ5Q29tcG9zZXJGYWN0b3J5LmhwcD4KI2luY2x1ZGUgPGNvbS9zdW4vc3Rhci9zZGJjL1NRTFdhcm5pbmcuaHBwPgojaW5jbHVkZSA8Y29tL3N1bi9zdGFyL3NkYmMvWFJvdy5ocHA+CiNpbmNsdWRlIDxjb20vc3VuL3N0YXIvc2RiY3gvWEFwcGVuZC5ocHA+CiNpbmNsdWRlIDxjb20vc3VuL3N0YXIvc2RiY3gvWERhdGFEZXNjcmlwdG9yRmFjdG9yeS5ocHA+CiNpbmNsdWRlIDxjb20vc3VuL3N0YXIvc2RiY3gvWERyb3AuaHBwPgojaW5jbHVkZSA8Y29tL3N1bi9zdGFyL3NkYmN4L1hUYWJsZXNTdXBwbGllci5ocHA+CiNpbmNsdWRlIDxjb20vc3VuL3N0YXIvc2RiY3gvWFZpZXdzU3VwcGxpZXIuaHBwPgojaW5jbHVkZSA8Y29tL3N1bi9zdGFyL3VpL2RpYWxvZ3MvWEV4ZWN1dGFibGVEaWFsb2cuaHBwPgojaW5jbHVkZSA8Y29tL3N1bi9zdGFyL3V0aWwvWENsb3NlYWJsZS5ocHA+CiNpbmNsdWRlIDxjb20vc3VuL3N0YXIvdXRpbC9WZXRvRXhjZXB0aW9uLmhwcD4KI2luY2x1ZGUgPGNvbS9zdW4vc3Rhci9mcmFtZS9YVW50aXRsZWROdW1iZXJzLmhwcD4KLyoqID09PSBlbmQgVU5PIGluY2x1ZGVzID09PSAqKi8KCiNpbmNsdWRlIDxjb21waGVscGVyL2Jhc2ljaW8uaHh4PgojaW5jbHVkZSA8Y29tcGhlbHBlci9leHRyYWN0Lmh4eD4KI2luY2x1ZGUgPGNvbXBoZWxwZXIvcHJvcGVydHkuaHh4PgojaW5jbHVkZSA8Y29tcGhlbHBlci9zZXFzdHJlYW0uaHh4PgojaW5jbHVkZSA8Y29tcGhlbHBlci9zdHJlYW1zZWN0aW9uLmh4eD4KI2luY2x1ZGUgPGNvbXBoZWxwZXIvdHlwZXMuaHh4PgojaW5jbHVkZSA8Y29ubmVjdGl2aXR5L2RiZXhjZXB0aW9uLmh4eD4KI2luY2x1ZGUgPGNvbm5lY3Rpdml0eS9kYnRvb2xzLmh4eD4KI2luY2x1ZGUgPGNwcHVoZWxwZXIvZXhjX2hscC5oeHg+CiNpbmNsdWRlIDxzZngyL3NmeHNpZHMuaHJjPgojaW5jbHVkZSA8c3Z0b29scy9sb2NhbHJlc2FjY2Vzcy5oeHg+CiNpbmNsdWRlIDx0b29sa2l0L2hlbHBlci92Y2x1bm9oZWxwZXIuaHh4PgojaW5jbHVkZSA8dG9vbHMvZGlhZ25vc2VfZXguaD4KI2luY2x1ZGUgPHZjbC9tc2dib3guaHh4PgojaW5jbHVkZSA8dmNsL3N2YXBwLmh4eD4KI2luY2x1ZGUgPHZvcy9tdXRleC5oeHg+CgpleHRlcm4gIkMiIHZvaWQgU0FMX0NBTEwgY3JlYXRlUmVnaXN0cnlJbmZvX09RdWVyeUNvbnRyb2woKQp7CglzdGF0aWMgOjpkYmF1aTo6T011bHRpSW5zdGFuY2VBdXRvUmVnaXN0cmF0aW9uPCA6OmRiYXVpOjpPUXVlcnlDb250cm9sbGVyID4gYUF1dG9SZWdpc3RyYXRpb247Cn0KbmFtZXNwYWNlIGRiYXVpCnsKICAgIHVzaW5nIG5hbWVzcGFjZSA6OmNvbTo6c3VuOjpzdGFyOjp1bm87CiAgICB1c2luZyBuYW1lc3BhY2UgOjpjb206OnN1bjo6c3Rhcjo6YmVhbnM7CiAgICB1c2luZyBuYW1lc3BhY2UgOjpjb206OnN1bjo6c3Rhcjo6ZnJhbWU7CiAgICB1c2luZyBuYW1lc3BhY2UgOjpjb206OnN1bjo6c3Rhcjo6dXRpbDsKICAgIHVzaW5nIG5hbWVzcGFjZSA6OmNvbTo6c3VuOjpzdGFyOjpsYW5nOwoKICAgIGNsYXNzIE9WaWV3Q29udHJvbGxlciA6IHB1YmxpYyBPUXVlcnlDb250cm9sbGVyCiAgICB7CiAgICAgICAgLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KICAgICAgICB2aXJ0dWFsIDo6cnRsOjpPVVN0cmluZyBTQUxfQ0FMTCBnZXRJbXBsZW1lbnRhdGlvbk5hbWUoKSB0aHJvdyggUnVudGltZUV4Y2VwdGlvbiApCiAgICAgICAgewoJICAgICAgICByZXR1cm4gZ2V0SW1wbGVtZW50YXRpb25OYW1lX1N0YXRpYygpOwogICAgICAgIH0KICAgICAgICAvLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KICAgICAgICB2aXJ0dWFsIFNlcXVlbmNlPCA6OnJ0bDo6T1VTdHJpbmc+IFNBTF9DQUxMIGdldFN1cHBvcnRlZFNlcnZpY2VOYW1lcygpIHRocm93KFJ1bnRpbWVFeGNlcHRpb24pCiAgICAgICAgewoJICAgICAgICByZXR1cm4gZ2V0U3VwcG9ydGVkU2VydmljZU5hbWVzX1N0YXRpYygpOwogICAgICAgIH0KICAgIHB1YmxpYzoKICAgICAgICBPVmlld0NvbnRyb2xsZXIoY29uc3QgUmVmZXJlbmNlPCBYTXVsdGlTZXJ2aWNlRmFjdG9yeSA+JiBfck0pIDogT1F1ZXJ5Q29udHJvbGxlcihfck0pe30KCiAgICAgICAgLy8gbmVlZCBieSByZWdpc3RyYXRpb24KCSAgICBzdGF0aWMgOjpydGw6Ok9VU3RyaW5nIGdldEltcGxlbWVudGF0aW9uTmFtZV9TdGF0aWMoKSB0aHJvdyggUnVudGltZUV4Y2VwdGlvbiApCiAgICAgICAgewoJICAgICAgICByZXR1cm4gOjpydGw6Ok9VU3RyaW5nOjpjcmVhdGVGcm9tQXNjaWkoIm9yZy5vcGVub2ZmaWNlLmNvbXAuZGJ1Lk9WaWV3RGVzaWduIik7CiAgICAgICAgfQoJICAgIHN0YXRpYyBTZXF1ZW5jZTwgOjpydGw6Ok9VU3RyaW5nID4gZ2V0U3VwcG9ydGVkU2VydmljZU5hbWVzX1N0YXRpYyh2b2lkKSB0aHJvdyggUnVudGltZUV4Y2VwdGlvbiApCiAgICAgICAgewogICAgICAgICAgICBTZXF1ZW5jZTwgOjpydGw6Ok9VU3RyaW5nPiBhU3VwcG9ydGVkKDEpOwoJICAgICAgICBhU3VwcG9ydGVkLmdldEFycmF5KClbMF0gPSA6OnJ0bDo6T1VTdHJpbmc6OmNyZWF0ZUZyb21Bc2NpaSgiY29tLnN1bi5zdGFyLnNkYi5WaWV3RGVzaWduIik7CgkgICAgICAgIHJldHVybiBhU3VwcG9ydGVkOwogICAgICAgIH0KCSAgICBzdGF0aWMgUmVmZXJlbmNlPCBYSW50ZXJmYWNlID4gU0FMX0NBTEwgQ3JlYXRlKGNvbnN0IFJlZmVyZW5jZTwgWE11bHRpU2VydmljZUZhY3RvcnkgPiYgX3JNKQogICAgICAgIHsKICAgICAgICAgICAgcmV0dXJuICoobmV3IE9WaWV3Q29udHJvbGxlcihfck0pKTsKICAgICAgICB9CiAgICB9Owp9CmV4dGVybiAiQyIgdm9pZCBTQUxfQ0FMTCBjcmVhdGVSZWdpc3RyeUluZm9fT1ZpZXdDb250cm9sKCkKewoJc3RhdGljIDo6ZGJhdWk6Ok9NdWx0aUluc3RhbmNlQXV0b1JlZ2lzdHJhdGlvbjwgOjpkYmF1aTo6T1ZpZXdDb250cm9sbGVyID4gYUF1dG9SZWdpc3RyYXRpb247Cn0KCm5hbWVzcGFjZSBkYmF1aQp7Cgl1c2luZyBuYW1lc3BhY2UgOjpjb25uZWN0aXZpdHk7CiNpZiBPU0xfREVCVUdfTEVWRUwgPiAxCgluYW1lc3BhY2UKCXsKCQkvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoJCXZvaWQgaW5zZXJ0UGFyc2VUcmVlKFN2VHJlZUxpc3RCb3gqIF9wQm94LDo6Y29ubmVjdGl2aXR5OjpPU1FMUGFyc2VOb2RlKiBfcE5vZGUsU3ZMQm94RW50cnkqIF9wUGFyZW50ID0gTlVMTCkKCQl7CgkJCTo6cnRsOjpPVVN0cmluZyByU3RyaW5nOwoJCQlpZiAoIV9wTm9kZS0+aXNUb2tlbigpKQoJCQl7CgkJCQkvLyBSZWdlbG5hbWVuIGFscyBydWxlOiAuLi4KCQkJCXJTdHJpbmcgPSA6OnJ0bDo6T1VTdHJpbmc6OmNyZWF0ZUZyb21Bc2NpaSgiUlVMRV9JRDogIik7CgkJCQlyU3RyaW5nICs9IDo6cnRsOjpPVVN0cmluZzo6dmFsdWVPZiggKHNhbF9JbnQzMilfcE5vZGUtPmdldFJ1bGVJRCgpKTsKCQkJCXJTdHJpbmcrPSA6OnJ0bDo6T1VTdHJpbmc6OmNyZWF0ZUZyb21Bc2NpaSgiKCIpOwoJCQkJclN0cmluZyArPSBPU1FMUGFyc2VyOjpSdWxlSURUb1N0cihfcE5vZGUtPmdldFJ1bGVJRCgpKTsKCQkJCXJTdHJpbmcrPSA6OnJ0bDo6T1VTdHJpbmc6OmNyZWF0ZUZyb21Bc2NpaSgiKSIpOwoKCgkJCQlfcFBhcmVudCA9IF9wQm94LT5JbnNlcnRFbnRyeShyU3RyaW5nLF9wUGFyZW50KTsKCgkJCQkvLyBlaW5tYWwgYXVzd2VydGVuIHdpZXZpZWwgU3VidHJlZXMgZGllc2VyIEtub3RlbiBiZXNpdHp0CgkJCQlzYWxfdUludDMyIG5TdG9wID0gX3BOb2RlLT5jb3VudCgpOwoJCQkJLy8gaG9sIGRpciBkZW4gZXJzdGVuIFN1YnRyZWUKCQkJCWZvcihzYWxfdUludDMyIGk9MDtpPG5TdG9wOysraSkKCQkJCQlpbnNlcnRQYXJzZVRyZWUoX3BCb3gsX3BOb2RlLT5nZXRDaGlsZChpKSxfcFBhcmVudCk7CgkJCX0KCQkJZWxzZQoJCQl7CgkJCQkvLyBlaW4gVG9rZW4gZ2VmdW5kZW4KCQkJCS8vIHRhYnMgZnVlciBkYXMgRWlucnVlY2tlbiBlbnRzcHJlY2hlbmQgbkxldmVsCgoJCQkJc3dpdGNoIChfcE5vZGUtPmdldE5vZGVUeXBlKCkpCgkJCQl7CgoJCQkJY2FzZSBTUUxfTk9ERV9LRVlXT1JEOgoJCQkJCXsKCQkJCQkJclN0cmluZys9IDo6cnRsOjpPVVN0cmluZzo6Y3JlYXRlRnJvbUFzY2lpKCJTUUxfS0VZV09SRDoiKTsKCQkJCQkJOjpydGw6Ok9TdHJpbmcgc1QgPSBPU1FMUGFyc2VyOjpUb2tlbklEVG9TdHIoX3BOb2RlLT5nZXRUb2tlbklEKCkpOwoJCQkJCQlyU3RyaW5nICs9IDo6cnRsOjpPVVN0cmluZyhzVCxzVC5nZXRMZW5ndGgoKSxSVExfVEVYVEVOQ09ESU5HX1VURjgpOwoJCQkJCSBicmVhazt9CgoJCQkJY2FzZSBTUUxfTk9ERV9DT01QQVJJU09OOgoJCQkJCXtyU3RyaW5nKz0gOjpydGw6Ok9VU3RyaW5nOjpjcmVhdGVGcm9tQXNjaWkoIlNRTF9DT01QQVJJU09OOiIpOwoJCQkJCXJTdHJpbmcgKz0gX3BOb2RlLT5nZXRUb2tlblZhbHVlKCk7CS8vIGhhZW5nZSBOb2RldmFsdWUgYW4KCQkJCQkJCS8vIHVuZCBiZWdpbm5lIG5ldSBaZWlsZQoJCQkJCWJyZWFrO30KCgkJCQljYXNlIFNRTF9OT0RFX05BTUU6CgkJCQkJe3JTdHJpbmcrPSA6OnJ0bDo6T1VTdHJpbmc6OmNyZWF0ZUZyb21Bc2NpaSgiU1FMX05BTUU6Iik7CgkJCQkJIHJTdHJpbmcrPSA6OnJ0bDo6T1VTdHJpbmc6OmNyZWF0ZUZyb21Bc2NpaSgiXCIiKTsKCQkJCQkgclN0cmluZyArPSBfcE5vZGUtPmdldFRva2VuVmFsdWUoKTsKCQkJCQkgclN0cmluZys9IDo6cnRsOjpPVVN0cmluZzo6Y3JlYXRlRnJvbUFzY2lpKCJcIiIpOwoKCQkJCQkgYnJlYWs7fQoKCQkJCWNhc2UgU1FMX05PREVfU1RSSU5HOgoJCQkJCXtyU3RyaW5nICs9IDo6cnRsOjpPVVN0cmluZzo6Y3JlYXRlRnJvbUFzY2lpKCJTUUxfU1RSSU5HOiciKTsKCQkJCQkgclN0cmluZyArPSBfcE5vZGUtPmdldFRva2VuVmFsdWUoKTsKCQkJCQkgYnJlYWs7fQoKCQkJCWNhc2UgU1FMX05PREVfSU5UTlVNOgoJCQkJCXtyU3RyaW5nICs9IDo6cnRsOjpPVVN0cmluZzo6Y3JlYXRlRnJvbUFzY2lpKCJTUUxfSU5UTlVNOiIpOwoJCQkJCSByU3RyaW5nICs9IF9wTm9kZS0+Z2V0VG9rZW5WYWx1ZSgpOwoJCQkJCSBicmVhazt9CgoJCQkJY2FzZSBTUUxfTk9ERV9BUFBST1hOVU06CgkJCQkJe3JTdHJpbmcgKz0gOjpydGw6Ok9VU3RyaW5nOjpjcmVhdGVGcm9tQXNjaWkoIlNRTF9BUFBST1hOVU06Iik7CgkJCQkJIHJTdHJpbmcgKz0gX3BOb2RlLT5nZXRUb2tlblZhbHVlKCk7CgkJCQkJIGJyZWFrO30KCgkJCQljYXNlIFNRTF9OT0RFX1BVTkNUVUFUSU9OOgoJCQkJCXtyU3RyaW5nICs9IDo6cnRsOjpPVVN0cmluZzo6Y3JlYXRlRnJvbUFzY2lpKCJTUUxfUFVOQ1RVQVRJT046Iik7CgkJCQkJclN0cmluZyArPSBfcE5vZGUtPmdldFRva2VuVmFsdWUoKTsJLy8gaGFlbmdlIE5vZGV2YWx1ZSBhbgoJCQkJCWJyZWFrO30KCgkJCQljYXNlIFNRTF9OT0RFX0FNTVNDOgoJCQkJCXtyU3RyaW5nICs9IDo6cnRsOjpPVVN0cmluZzo6Y3JlYXRlRnJvbUFzY2lpKCJTUUxfQU1NU0M6Iik7CgkJCQkJclN0cmluZyArPSBfcE5vZGUtPmdldFRva2VuVmFsdWUoKTsJLy8gaGFlbmdlIE5vZGV2YWx1ZSBhbgoKCQkJCQlicmVhazt9CgoJCQkJZGVmYXVsdDoKCQkJCQlPU0xfQVNTRVJUKCJPU1FMUGFyc2VyOjpTaG93UGFyc2VUcmVlOiB1bnp1bGFlc3NpZ2VyIE5vZGVUeXBlIik7CgkJCQkJclN0cmluZyArPSBfcE5vZGUtPmdldFRva2VuVmFsdWUoKTsKCQkJCX0KCQkJCV9wQm94LT5JbnNlcnRFbnRyeShyU3RyaW5nLF9wUGFyZW50KTsKCQkJfQoJCX0KCX0KI2VuZGlmIC8vIE9TTF9ERUJVR19MRVZFTAoKICAgIG5hbWVzcGFjZQogICAgewoJCS8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiAgICAgICAgU3RyaW5nIGxjbF9nZXRPYmplY3RSZXNvdXJjZVN0cmluZyggc2FsX3VJbnQxNiBfblJlc0lkLCBzYWxfSW50MzIgX25Db21tYW5kVHlwZSApCiAgICAgICAgewogICAgICAgICAgICBTdHJpbmcgc01lc3NhZ2VUZXh0ID0gU3RyaW5nKCBNb2R1bGVSZXMoIF9uUmVzSWQgKSApOwogICAgICAgICAgICBTdHJpbmcgc09iamVjdFR5cGU7CiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIExvY2FsUmVzb3VyY2VBY2Nlc3MgYUxvY2FsUmVzKCBSU0NfUVVFUllfT0JKRUNUX1RZUEUsIFJTQ19SRVNPVVJDRSApOwogICAgICAgICAgICAgICAgc09iamVjdFR5cGUgPSBTdHJpbmcoIE1vZHVsZVJlcyggKHNhbF91SW50MTYpKCBfbkNvbW1hbmRUeXBlICsgMSApICkgKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBzTWVzc2FnZVRleHQuU2VhcmNoQW5kUmVwbGFjZSggU3RyaW5nOjpDcmVhdGVGcm9tQXNjaWkoICIkb2JqZWN0JCIgKSwgc09iamVjdFR5cGUgKTsKICAgICAgICAgICAgcmV0dXJuIHNNZXNzYWdlVGV4dDsKICAgICAgICB9CiAgICB9Cgp1c2luZyBuYW1lc3BhY2UgOjpjb206OnN1bjo6c3Rhcjo6dW5vOwp1c2luZyBuYW1lc3BhY2UgOjpjb206OnN1bjo6c3Rhcjo6aW87CnVzaW5nIG5hbWVzcGFjZSA6OmNvbTo6c3VuOjpzdGFyOjpiZWFuczsKdXNpbmcgbmFtZXNwYWNlIDo6Y29tOjpzdW46OnN0YXI6OmZyYW1lOwp1c2luZyBuYW1lc3BhY2UgOjpjb206OnN1bjo6c3Rhcjo6dXRpbDsKdXNpbmcgbmFtZXNwYWNlIDo6Y29tOjpzdW46OnN0YXI6Omxhbmc7CnVzaW5nIG5hbWVzcGFjZSA6OmNvbTo6c3VuOjpzdGFyOjpjb250YWluZXI7CnVzaW5nIG5hbWVzcGFjZSA6OmNvbTo6c3VuOjpzdGFyOjpzZGJjeDsKdXNpbmcgbmFtZXNwYWNlIDo6Y29tOjpzdW46OnN0YXI6OnNkYmM7CnVzaW5nIG5hbWVzcGFjZSA6OmNvbTo6c3VuOjpzdGFyOjpzZGI7CnVzaW5nIG5hbWVzcGFjZSA6OmNvbTo6c3VuOjpzdGFyOjp1aTo6ZGlhbG9nczsKdXNpbmcgbmFtZXNwYWNlIDo6Y29tOjpzdW46OnN0YXI6OmF3dDsKdXNpbmcgbmFtZXNwYWNlIDo6ZGJ0b29sczsKCnVzaW5nIG5hbWVzcGFjZSA6OmNvbXBoZWxwZXI7CgpuYW1lc3BhY2UKewoJdm9pZCBlbnN1cmVUb29sYmFycyggT1F1ZXJ5Q29udHJvbGxlciYgX3JDb250cm9sbGVyLCBzYWxfQm9vbCBfYkRlc2lnbiApCiAgICB7CiAgICAgICAgUmVmZXJlbmNlPCA6OmNvbTo6c3VuOjpzdGFyOjpmcmFtZTo6WExheW91dE1hbmFnZXIgPiB4TGF5b3V0TWFuYWdlciA9IF9yQ29udHJvbGxlci5nZXRMYXlvdXRNYW5hZ2VyKCBfckNvbnRyb2xsZXIuZ2V0RnJhbWUoKSApOwoJCWlmICggeExheW91dE1hbmFnZXIuaXMoKSApCgkJewoJCQl4TGF5b3V0TWFuYWdlci0+bG9jaygpOwoJCQlzdGF0aWMgOjpydGw6Ok9VU3RyaW5nIHNfc0Rlc2lnblRvb2xiYXIoUlRMX0NPTlNUQVNDSUlfVVNUUklOR1BBUkFNKCJwcml2YXRlOnJlc291cmNlL3Rvb2xiYXIvZGVzaWdub2JqZWN0YmFyIikpOwoJCQlzdGF0aWMgOjpydGw6Ok9VU3RyaW5nIHNfc1NxbFRvb2xiYXIoUlRMX0NPTlNUQVNDSUlfVVNUUklOR1BBUkFNKCJwcml2YXRlOnJlc291cmNlL3Rvb2xiYXIvc3Fsb2JqZWN0YmFyIikpOwoJCQlpZiAoIF9iRGVzaWduICkKCQkJewoJCQkJeExheW91dE1hbmFnZXItPmRlc3Ryb3lFbGVtZW50KCBzX3NTcWxUb29sYmFyICk7CgkJCQl4TGF5b3V0TWFuYWdlci0+Y3JlYXRlRWxlbWVudCggc19zRGVzaWduVG9vbGJhciApOwoJCQl9CgkJCWVsc2UKCQkJewoJCQkJeExheW91dE1hbmFnZXItPmRlc3Ryb3lFbGVtZW50KCBzX3NEZXNpZ25Ub29sYmFyICk7CgkJCQl4TGF5b3V0TWFuYWdlci0+Y3JlYXRlRWxlbWVudCggc19zU3FsVG9vbGJhciApOwoJCQl9CgkJCXhMYXlvdXRNYW5hZ2VyLT51bmxvY2soKTsKICAgICAgICAgICAgeExheW91dE1hbmFnZXItPmRvTGF5b3V0KCk7CgkJfQogICAgfQp9CgovLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQo6OnJ0bDo6T1VTdHJpbmcgU0FMX0NBTEwgT1F1ZXJ5Q29udHJvbGxlcjo6Z2V0SW1wbGVtZW50YXRpb25OYW1lKCkgdGhyb3coIFJ1bnRpbWVFeGNlcHRpb24gKQp7CglyZXR1cm4gZ2V0SW1wbGVtZW50YXRpb25OYW1lX1N0YXRpYygpOwp9CgovLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQo6OnJ0bDo6T1VTdHJpbmcgT1F1ZXJ5Q29udHJvbGxlcjo6Z2V0SW1wbGVtZW50YXRpb25OYW1lX1N0YXRpYygpIHRocm93KCBSdW50aW1lRXhjZXB0aW9uICkKewoJcmV0dXJuIDo6cnRsOjpPVVN0cmluZzo6Y3JlYXRlRnJvbUFzY2lpKCJvcmcub3Blbm9mZmljZS5jb21wLmRidS5PUXVlcnlEZXNpZ24iKTsKfQovLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQpTZXF1ZW5jZTwgOjpydGw6Ok9VU3RyaW5nPiBPUXVlcnlDb250cm9sbGVyOjpnZXRTdXBwb3J0ZWRTZXJ2aWNlTmFtZXNfU3RhdGljKHZvaWQpIHRocm93KCBSdW50aW1lRXhjZXB0aW9uICkKewoJU2VxdWVuY2U8IDo6cnRsOjpPVVN0cmluZz4gYVN1cHBvcnRlZCgxKTsKCWFTdXBwb3J0ZWQuZ2V0QXJyYXkoKVswXSA9IDo6cnRsOjpPVVN0cmluZzo6Y3JlYXRlRnJvbUFzY2lpKCJjb20uc3VuLnN0YXIuc2RiLlF1ZXJ5RGVzaWduIik7CglyZXR1cm4gYVN1cHBvcnRlZDsKfQovLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KU2VxdWVuY2U8IDo6cnRsOjpPVVN0cmluZz4gU0FMX0NBTEwgT1F1ZXJ5Q29udHJvbGxlcjo6Z2V0U3VwcG9ydGVkU2VydmljZU5hbWVzKCkgdGhyb3coUnVudGltZUV4Y2VwdGlvbikKewoJcmV0dXJuIGdldFN1cHBvcnRlZFNlcnZpY2VOYW1lc19TdGF0aWMoKTsKfQovLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tClJlZmVyZW5jZTwgWEludGVyZmFjZSA+IFNBTF9DQUxMIE9RdWVyeUNvbnRyb2xsZXI6OkNyZWF0ZShjb25zdCBSZWZlcmVuY2U8WE11bHRpU2VydmljZUZhY3RvcnkgPiYgX3J4RmFjdG9yeSkKewoJcmV0dXJuICoobmV3IE9RdWVyeUNvbnRyb2xsZXIoX3J4RmFjdG9yeSkpOwp9CkRCR19OQU1FKE9RdWVyeUNvbnRyb2xsZXIpOwovLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQpPUXVlcnlDb250cm9sbGVyOjpPUXVlcnlDb250cm9sbGVyKGNvbnN0IFJlZmVyZW5jZTwgWE11bHRpU2VydmljZUZhY3RvcnkgPiYgX3JNKQogICAgOk9Kb2luQ29udHJvbGxlcihfck0pCiAgICAsT1F1ZXJ5Q29udHJvbGxlcl9QQmFzZSggZ2V0QnJvYWRjYXN0SGVscGVyKCkgKQogICAgLG1fcFBhcnNlQ29udGV4dCggbmV3IHN2eGZvcm06Ok9TeXN0ZW1QYXJzZUNvbnRleHQgKQogICAgLG1fYVNxbFBhcnNlciggX3JNLCBtX3BQYXJzZUNvbnRleHQgKQoJLG1fcFNxbEl0ZXJhdG9yKE5VTEwpCgksbV9uVmlzaWJsZVJvd3MoMHg0MDApCgksbV9uU3BsaXRQb3MoLTEpCiAgICAsbV9uQ29tbWFuZFR5cGUoIENvbW1hbmRUeXBlOjpRVUVSWSApCiAgICAsbV9iR3JhcGhpY2FsRGVzaWduKHNhbF9GYWxzZSkKCSxtX2JEaXN0aW5jdChzYWxfRmFsc2UpCgksbV9iVmlld0FsaWFzKHNhbF9GYWxzZSkKICAgICxtX2JWaWV3VGFibGUoc2FsX0ZhbHNlKQoJLG1fYlZpZXdGdW5jdGlvbihzYWxfRmFsc2UpCgksbV9iRXNjYXBlUHJvY2Vzc2luZyhzYWxfVHJ1ZSkKewoJREJHX0NUT1IoT1F1ZXJ5Q29udHJvbGxlcixOVUxMKTsKCUludmFsaWRhdGVBbGwoKTsKCglyZWdpc3RlclByb3BlcnR5KCBQUk9QRVJUWV9BQ1RJVkVDT01NQU5ELCBQUk9QRVJUWV9JRF9BQ1RJVkVDT01NQU5ELCBQcm9wZXJ0eUF0dHJpYnV0ZTo6UkVBRE9OTFkgfCBQcm9wZXJ0eUF0dHJpYnV0ZTo6Qk9VTkQsCgkJJm1fc1N0YXRlbWVudCwgOjpnZXRDcHB1VHlwZSggJm1fc1N0YXRlbWVudCApICk7CglyZWdpc3RlclByb3BlcnR5KCBQUk9QRVJUWV9FU0NBUEVfUFJPQ0VTU0lORywgUFJPUEVSVFlfSURfRVNDQVBFX1BST0NFU1NJTkcsIFByb3BlcnR5QXR0cmlidXRlOjpSRUFET05MWSB8IFByb3BlcnR5QXR0cmlidXRlOjpCT1VORCwKCQkmbV9iRXNjYXBlUHJvY2Vzc2luZywgOjpnZXRDcHB1VHlwZSggJm1fYkVzY2FwZVByb2Nlc3NpbmcgKSApOwp9CgovLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQpPUXVlcnlDb250cm9sbGVyOjp+T1F1ZXJ5Q29udHJvbGxlcigpCnsKCURCR19EVE9SKE9RdWVyeUNvbnRyb2xsZXIsTlVMTCk7CglpZiAoICFnZXRCcm9hZGNhc3RIZWxwZXIoKS5iRGlzcG9zZWQgJiYgIWdldEJyb2FkY2FzdEhlbHBlcigpLmJJbkRpc3Bvc2UgKQoJewoJCU9TTF9FTlNVUkUoMCwiUGxlYXNlIGNoZWNrIHdobyBkb2Vzbid0IGRpc3Bvc2UgdGhpcyBjb21wb25lbnQhIik7CiAgICAgICAgLy8gaW5jcmVtZW50IHJlZiBjb3VudCB0byBwcmV2ZW50IGRvdWJsZSBjYWxsIG9mIER0b3IKICAgICAgICBvc2xfaW5jcmVtZW50SW50ZXJsb2NrZWRDb3VudCggJm1fcmVmQ291bnQgKTsKICAgICAgICBkaXNwb3NlKCk7Cgl9Cn0KCklNUExFTUVOVF9GT1JXQVJEX1hJTlRFUkZBQ0UyKCBPUXVlcnlDb250cm9sbGVyLCBPSm9pbkNvbnRyb2xsZXIsIE9RdWVyeUNvbnRyb2xsZXJfUEJhc2UgKQpJTVBMRU1FTlRfRk9SV0FSRF9YVFlQRVBST1ZJREVSMiggT1F1ZXJ5Q29udHJvbGxlciwgT0pvaW5Db250cm9sbGVyLCBPUXVlcnlDb250cm9sbGVyX1BCYXNlICkKCi8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQpSZWZlcmVuY2U8IFhQcm9wZXJ0eVNldEluZm8gPiBTQUxfQ0FMTCBPUXVlcnlDb250cm9sbGVyOjpnZXRQcm9wZXJ0eVNldEluZm8oKSB0aHJvdyhSdW50aW1lRXhjZXB0aW9uKQp7CglSZWZlcmVuY2U8IFhQcm9wZXJ0eVNldEluZm8gPiB4SW5mbyggY3JlYXRlUHJvcGVydHlTZXRJbmZvKCBnZXRJbmZvSGVscGVyKCkgKSApOwoJcmV0dXJuIHhJbmZvOwp9CgovLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0Kc2FsX0Jvb2wgU0FMX0NBTEwgT1F1ZXJ5Q29udHJvbGxlcjo6Y29udmVydEZhc3RQcm9wZXJ0eVZhbHVlKCBBbnkmIG9fckNvbnZlcnRlZFZhbHVlLCBBbnkmIG9fck9sZFZhbHVlLCBzYWxfSW50MzIgaV9uSGFuZGxlLCBjb25zdCBBbnkmIGlfclZhbHVlICkgdGhyb3cgKElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbikKewogICAgcmV0dXJuIE9Qcm9wZXJ0eUNvbnRhaW5lcjo6Y29udmVydEZhc3RQcm9wZXJ0eVZhbHVlKCBvX3JDb252ZXJ0ZWRWYWx1ZSwgb19yT2xkVmFsdWUsIGlfbkhhbmRsZSwgaV9yVmFsdWUgKTsKfQoKLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCnZvaWQgU0FMX0NBTEwgT1F1ZXJ5Q29udHJvbGxlcjo6c2V0RmFzdFByb3BlcnR5VmFsdWVfTm9Ccm9hZGNhc3QoIHNhbF9JbnQzMiBpX25IYW5kbGUsIGNvbnN0IEFueSYgaV9yVmFsdWUgKSB0aHJvdyAoIEV4Y2VwdGlvbiApCnsKICAgIE9Qcm9wZXJ0eUNvbnRhaW5lcjo6c2V0RmFzdFByb3BlcnR5VmFsdWVfTm9Ccm9hZGNhc3QoIGlfbkhhbmRsZSwgaV9yVmFsdWUgKTsKfQoKLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCnZvaWQgU0FMX0NBTEwgT1F1ZXJ5Q29udHJvbGxlcjo6Z2V0RmFzdFByb3BlcnR5VmFsdWUoIEFueSYgb19yVmFsdWUsIHNhbF9JbnQzMiBpX25IYW5kbGUgKSBjb25zdAp7CiAgICBzd2l0Y2ggKCBpX25IYW5kbGUgKQogICAgewogICAgY2FzZSBQUk9QRVJUWV9JRF9DVVJSRU5UX1FVRVJZX0RFU0lHTjoKICAgIHsKICAgICAgICA6OmNvbXBoZWxwZXI6Ok5hbWVkVmFsdWVDb2xsZWN0aW9uIGFDdXJyZW50RGVzaWduOwogICAgICAgIGFDdXJyZW50RGVzaWduLnB1dCggIkdyYXBoaWNhbERlc2lnbiIsIGlzR3JhcGhpY2FsRGVzaWduKCkgKTsKICAgICAgICBhQ3VycmVudERlc2lnbi5wdXQoICg6OnJ0bDo6T1VTdHJpbmcpUFJPUEVSVFlfRVNDQVBFX1BST0NFU1NJTkcsIG1fYkVzY2FwZVByb2Nlc3NpbmcgKTsKCiAgICAgICAgaWYgKCBpc0dyYXBoaWNhbERlc2lnbigpICkKICAgICAgICB7CiAgICAgICAgICAgIGdldENvbnRhaW5lcigpLT5TYXZlVUlDb25maWcoKTsKCSAgICAgICAgc2F2ZVZpZXdTZXR0aW5ncyggYUN1cnJlbnREZXNpZ24sIHRydWUgKTsKICAgICAgICAgICAgYUN1cnJlbnREZXNpZ24ucHV0KCAiU3RhdGVtZW50IiwgbV9zU3RhdGVtZW50ICk7CiAgICAgICAgfQogICAgICAgIGVsc2UKICAgICAgICB7CiAgICAgICAgICAgIGFDdXJyZW50RGVzaWduLnB1dCggIlN0YXRlbWVudCIsIGdldENvbnRhaW5lcigpLT5nZXRTdGF0ZW1lbnQoKSApOwogICAgICAgIH0KCiAgICAgICAgb19yVmFsdWUgPDw9IGFDdXJyZW50RGVzaWduLmdldFByb3BlcnR5VmFsdWVzKCk7CiAgICB9CiAgICBicmVhazsKCiAgICBkZWZhdWx0OgogICAgICAgIE9Qcm9wZXJ0eUNvbnRhaW5lcjo6Z2V0RmFzdFByb3BlcnR5VmFsdWUoIG9fclZhbHVlLCBpX25IYW5kbGUgKTsKICAgICAgICBicmVhazsKICAgIH0KfQoKLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCjo6Y3BwdTo6SVByb3BlcnR5QXJyYXlIZWxwZXImIE9RdWVyeUNvbnRyb2xsZXI6OmdldEluZm9IZWxwZXIoKQp7CglyZXR1cm4gKmNvbnN0X2Nhc3Q8IE9RdWVyeUNvbnRyb2xsZXIqID4oIHRoaXMgKS0+Z2V0QXJyYXlIZWxwZXIoKTsKfQoKLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQo6OmNwcHU6OklQcm9wZXJ0eUFycmF5SGVscGVyKiBPUXVlcnlDb250cm9sbGVyOjpjcmVhdGVBcnJheUhlbHBlciggKSBjb25zdAp7CglTZXF1ZW5jZTwgUHJvcGVydHkgPiBhUHJvcHM7CglkZXNjcmliZVByb3BlcnRpZXMoIGFQcm9wcyApOwoKICAgIC8vIG9uZSBhZGRpdGlvbmFsIHByb3BlcnR5OgogICAgY29uc3Qgc2FsX0ludDMyIG5MZW5ndGggPSBhUHJvcHMuZ2V0TGVuZ3RoKCk7CiAgICBhUHJvcHMucmVhbGxvYyggbkxlbmd0aCArIDEgKTsKICAgIGFQcm9wc1sgbkxlbmd0aCBdID0gUHJvcGVydHkoCiAgICAgICAgOjpydGw6Ok9VU3RyaW5nKCBSVExfQ09OU1RBU0NJSV9VU1RSSU5HUEFSQU0oICJDdXJyZW50UXVlcnlEZXNpZ24iICkgKSwKICAgICAgICBQUk9QRVJUWV9JRF9DVVJSRU5UX1FVRVJZX0RFU0lHTiwKICAgICAgICA6OmNwcHU6OlVub1R5cGU8IFNlcXVlbmNlPCBQcm9wZXJ0eVZhbHVlID4gPjo6Z2V0KCksCiAgICAgICAgUHJvcGVydHlBdHRyaWJ1dGU6OlJFQURPTkxZCiAgICApOwoKICAgIDo6c3RkOjpzb3J0KAogICAgICAgIGFQcm9wcy5nZXRBcnJheSgpLAogICAgICAgIGFQcm9wcy5nZXRBcnJheSgpICsgYVByb3BzLmdldExlbmd0aCgpLAogICAgICAgIDo6Y29tcGhlbHBlcjo6UHJvcGVydHlDb21wYXJlQnlOYW1lKCkKICAgICk7CgoJcmV0dXJuIG5ldyA6OmNwcHU6Ok9Qcm9wZXJ0eUFycmF5SGVscGVyKGFQcm9wcyk7Cn0KCi8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCnZvaWQgT1F1ZXJ5Q29udHJvbGxlcjo6ZGVsZXRlSXRlcmF0b3IoKQp7CglpZihtX3BTcWxJdGVyYXRvcikKCXsKCQlkZWxldGUgbV9wU3FsSXRlcmF0b3ItPmdldFBhcnNlVHJlZSgpOwoJCW1fcFNxbEl0ZXJhdG9yLT5kaXNwb3NlKCk7CgkJZGVsZXRlIG1fcFNxbEl0ZXJhdG9yOwoJCW1fcFNxbEl0ZXJhdG9yID0gTlVMTDsKCX0KfQovLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQp2b2lkIE9RdWVyeUNvbnRyb2xsZXI6OmRpc3Bvc2luZygpCnsKICAgIE9RdWVyeUNvbnRyb2xsZXJfUEJhc2U6OmRpc3Bvc2luZygpOwoKCWRlbGV0ZUl0ZXJhdG9yKCk7CgoJZGVsZXRlIG1fcFBhcnNlQ29udGV4dDsKCgljbGVhckZpZWxkcygpOwoJT1RhYmxlRmllbGRzKCkuc3dhcChtX3ZVblVzZWRGaWVsZHNEZXNjKTsKCgk6OmNvbXBoZWxwZXI6OmRpc3Bvc2VDb21wb25lbnQobV94Q29tcG9zZXIpOwoJT0pvaW5Db250cm9sbGVyOjpkaXNwb3NpbmcoKTsKICAgIE9RdWVyeUNvbnRyb2xsZXJfUEJhc2U6OmRpc3Bvc2luZygpOwp9Ci8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCnZvaWQgT1F1ZXJ5Q29udHJvbGxlcjo6Y2xlYXJGaWVsZHMoKQp7CglPVGFibGVGaWVsZHMoKS5zd2FwKG1fdlRhYmxlRmllbGREZXNjKTsKfQovLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQpGZWF0dXJlU3RhdGUgT1F1ZXJ5Q29udHJvbGxlcjo6R2V0U3RhdGUoc2FsX3VJbnQxNiBfbklkKSBjb25zdAp7CglGZWF0dXJlU3RhdGUgYVJldHVybjsKCWFSZXR1cm4uYkVuYWJsZWQgPSBzYWxfVHJ1ZTsKCQkvLyAoZGlzYWJsZWQgYXV0b21hdGljYWxseSkKCglzd2l0Y2ggKF9uSWQpCgl7CiAgICAgICAgY2FzZSBJRF9CUk9XU0VSX0VESVRET0M6CiAgICAgICAgICAgIGlmICggZWRpdGluZ0NvbW1hbmQoKSApCiAgICAgICAgICAgICAgICBhUmV0dXJuLmJFbmFibGVkID0gc2FsX0ZhbHNlOwogICAgICAgICAgICBlbHNlIGlmICggZWRpdGluZ1ZpZXcoKSAmJiAhbV94QWx0ZXJWaWV3LmlzKCkgKQogICAgICAgICAgICAgICAgYVJldHVybi5iRW5hYmxlZCA9IHNhbF9GYWxzZTsKICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgYVJldHVybiA9IE9Kb2luQ29udHJvbGxlcjo6R2V0U3RhdGUoIF9uSWQgKTsKICAgICAgICAgICAgYnJlYWs7CgoJCWNhc2UgSURfQlJPV1NFUl9FU0FDUEVQUk9DRVNTSU5HOgoJCQlhUmV0dXJuLmJDaGVja2VkID0gIW1fYkVzY2FwZVByb2Nlc3Npbmc7CgkJCWFSZXR1cm4uYkVuYWJsZWQgPSAoIG1fcFNxbEl0ZXJhdG9yICE9IE5VTEwgKSAmJiAhbV9iR3JhcGhpY2FsRGVzaWduOwoJCQlicmVhazsKCQljYXNlIFNJRF9SRUxBVElPTl9BRERfUkVMQVRJT046CgkJCWFSZXR1cm4uYkVuYWJsZWQgPSBpc0VkaXRhYmxlKCkgJiYgbV9iR3JhcGhpY2FsRGVzaWduICYmIG1fdlRhYmxlRGF0YS5zaXplKCkgPiAxOwoJCQlicmVhazsKCQljYXNlIElEX0JST1dTRVJfU0FWRUFTRE9DOgoJCQlhUmV0dXJuLmJFbmFibGVkID0gIWVkaXRpbmdDb21tYW5kKCkgJiYgIWVkaXRpbmdWaWV3KCkgJiYgKCFtX2JHcmFwaGljYWxEZXNpZ24gfHwgIShtX3ZUYWJsZUZpZWxkRGVzYy5lbXB0eSgpIHx8IG1fdlRhYmxlRGF0YS5lbXB0eSgpKSk7CgkJCWJyZWFrOwoJCWNhc2UgSURfQlJPV1NFUl9TQVZFRE9DOgoJCQlhUmV0dXJuLmJFbmFibGVkID0gaW1wbF9pc01vZGlmaWVkKCkgJiYgKCFtX2JHcmFwaGljYWxEZXNpZ24gfHwgIShtX3ZUYWJsZUZpZWxkRGVzYy5lbXB0eSgpIHx8IG1fdlRhYmxlRGF0YS5lbXB0eSgpKSk7CgkJCWJyZWFrOwoJCWNhc2UgU0lEX1BSSU5URE9DRElSRUNUOgoJCQlicmVhazsKCQljYXNlIElEX0JST1dTRVJfQ1VUOgoJCQlhUmV0dXJuLmJFbmFibGVkID0gaXNFZGl0YWJsZSgpICYmIGdldENvbnRhaW5lcigpICYmIGdldENvbnRhaW5lcigpLT5pc0N1dEFsbG93ZWQoKTsKCQkJYnJlYWs7CgkJY2FzZSBJRF9CUk9XU0VSX0NPUFk6CgkJCWFSZXR1cm4uYkVuYWJsZWQgPSBnZXRDb250YWluZXIoKSAmJiBnZXRDb250YWluZXIoKS0+aXNDb3B5QWxsb3dlZCgpOwoJCQlicmVhazsKCQljYXNlIElEX0JST1dTRVJfUEFTVEU6CgkJCWFSZXR1cm4uYkVuYWJsZWQgPSBpc0VkaXRhYmxlKCkgJiYgZ2V0Q29udGFpbmVyKCkgJiYgZ2V0Q29udGFpbmVyKCktPmlzUGFzdGVBbGxvd2VkKCk7CgkJCWJyZWFrOwoJCWNhc2UgSURfQlJPV1NFUl9TUUw6CgkJCWFSZXR1cm4uYkVuYWJsZWQgPSBtX2JFc2NhcGVQcm9jZXNzaW5nICYmIG1fcFNxbEl0ZXJhdG9yOwoJCQlhUmV0dXJuLmJDaGVja2VkID0gbV9iR3JhcGhpY2FsRGVzaWduOwoJCQlicmVhazsKCQljYXNlIFNJRF9CUk9XU0VSX0NMRUFSX1FVRVJZOgoJCQlhUmV0dXJuLmJFbmFibGVkID0gaXNFZGl0YWJsZSgpICYmIChtX3NTdGF0ZW1lbnQuZ2V0TGVuZ3RoKCkgfHwgIW1fdlRhYmxlRGF0YS5lbXB0eSgpKTsKCQkJYnJlYWs7CgkJY2FzZSBTSURfUVVFUllfVklFV19GVU5DVElPTlM6CgkJY2FzZSBTSURfUVVFUllfVklFV19UQUJMRVM6CgkJY2FzZSBTSURfUVVFUllfVklFV19BTElBU0VTOgoJCQlhUmV0dXJuLmJDaGVja2VkID0gZ2V0Q29udGFpbmVyKCkgJiYgZ2V0Q29udGFpbmVyKCktPmlzU2xvdEVuYWJsZWQoX25JZCk7CgkJCWFSZXR1cm4uYkVuYWJsZWQgPSBtX2JHcmFwaGljYWxEZXNpZ247CgkJCWJyZWFrOwoJCWNhc2UgU0lEX1FVRVJZX0RJU1RJTkNUX1ZBTFVFUzoKCQkJYVJldHVybi5iRW5hYmxlZCA9IG1fYkdyYXBoaWNhbERlc2lnbiAmJiBpc0VkaXRhYmxlKCk7CgkJCWFSZXR1cm4uYkNoZWNrZWQgPSBtX2JEaXN0aW5jdDsKCQkJYnJlYWs7CgkJY2FzZSBJRF9CUk9XU0VSX1FVRVJZX0VYRUNVVEU6CgkJCWFSZXR1cm4uYkVuYWJsZWQgPSBzYWxfVHJ1ZTsKCQkJYnJlYWs7CgkJY2FzZSBTSURfREJfUVVFUllfUFJFVklFVzoKCQkJYVJldHVybi5iRW5hYmxlZCA9IHNhbF9UcnVlOwoJCQlhUmV0dXJuLmJDaGVja2VkID0gZ2V0Q29udGFpbmVyKCkgJiYgZ2V0Q29udGFpbmVyKCktPmdldFByZXZpZXdGcmFtZSgpLmlzKCk7CgkJCWJyZWFrOwojaWYgT1NMX0RFQlVHX0xFVkVMID4gMQoJCWNhc2UgSURfRURJVF9RVUVSWV9TUUw6CgkJCWJyZWFrOwoJCWNhc2UgSURfRURJVF9RVUVSWV9ERVNJR046CgkJCWJyZWFrOwojZW5kaWYKCQljYXNlIElEX0JST1dTRVJfQUREVEFCTEU6CgkJCWlmICggIW1fYkdyYXBoaWNhbERlc2lnbiApCgkJCXsKCQkJCWFSZXR1cm4uYkVuYWJsZWQgPSBzYWxfRmFsc2U7CgkJCQlicmVhazsKCQkJfQoJCQkvLyBydW4gdGhyb3VnaAoJCWRlZmF1bHQ6CgkJCWFSZXR1cm4gPSBPSm9pbkNvbnRyb2xsZXI6OkdldFN0YXRlKF9uSWQpOwoJCQlicmVhazsKCX0KCXJldHVybiBhUmV0dXJuOwp9Ci8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCnZvaWQgT1F1ZXJ5Q29udHJvbGxlcjo6RXhlY3V0ZShzYWxfdUludDE2IF9uSWQsIGNvbnN0IFNlcXVlbmNlPCBQcm9wZXJ0eVZhbHVlID4mIGFBcmdzKQp7Cglzd2l0Y2goX25JZCkKCXsKCQljYXNlIElEX0JST1dTRVJfRVNBQ1BFUFJPQ0VTU0lORzoKICAgICAgICAgICAgc2V0RXNjYXBlUHJvY2Vzc2luZ19maXJlRXZlbnQoICFtX2JFc2NhcGVQcm9jZXNzaW5nICk7CiAgICAgICAgICAgIGlmICggIWVkaXRpbmdWaWV3KCkgKQoJCQkgICAgc2V0TW9kaWZpZWQoc2FsX1RydWUpOwoJCQlJbnZhbGlkYXRlRmVhdHVyZShJRF9CUk9XU0VSX1NRTCk7CgkJCWJyZWFrOwoJCWNhc2UgSURfQlJPV1NFUl9TQVZFQVNET0M6CgkJY2FzZSBJRF9CUk9XU0VSX1NBVkVET0M6CgkJCWRvU2F2ZUFzRG9jKElEX0JST1dTRVJfU0FWRUFTRE9DID09IF9uSWQpOwoJCQlicmVhazsKCQljYXNlIFNJRF9SRUxBVElPTl9BRERfUkVMQVRJT046CgkJCXsKCQkJCU9Kb2luRGVzaWduVmlldyogcFZpZXcgPSBnZXRKb2luVmlldygpOwoJCQkJaWYoIHBWaWV3ICkKCQkJCQlzdGF0aWNfY2FzdDxPUXVlcnlUYWJsZVZpZXcqPihwVmlldy0+Z2V0VGFibGVWaWV3KCkpLT5jcmVhdGVOZXdDb25uZWN0aW9uKCk7CgkJCX0KCQkJYnJlYWs7CgkJY2FzZSBTSURfUFJJTlRET0NESVJFQ1Q6CgkJCWJyZWFrOwoJCWNhc2UgSURfQlJPV1NFUl9DVVQ6CgkJCWdldENvbnRhaW5lcigpLT5jdXQoKTsKCQkJYnJlYWs7CgkJY2FzZSBJRF9CUk9XU0VSX0NPUFk6CgkJCWdldENvbnRhaW5lcigpLT5jb3B5KCk7CgkJCWJyZWFrOwoJCWNhc2UgSURfQlJPV1NFUl9QQVNURToKCQkJZ2V0Q29udGFpbmVyKCktPnBhc3RlKCk7CgkJCWJyZWFrOwoJCWNhc2UgSURfQlJPV1NFUl9TUUw6CiAgICAgICAgewoJCQlpZiAoICFnZXRDb250YWluZXIoKS0+Y2hlY2tTdGF0ZW1lbnQoKSApCiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgU1FMRXhjZXB0aW9uSW5mbyBhRXJyb3I7CgkJCXRyeQoJCQl7CiAgICAgICAgICAgICAgICA6OnJ0bDo6T1VTdHJpbmcgYUVycm9yTXNnOwogICAgICAgICAgICAgICAgc2V0U3RhdGVtZW50X2ZpcmVFdmVudCggZ2V0Q29udGFpbmVyKCktPmdldFN0YXRlbWVudCgpICk7CgkJCQlpZighbV9zU3RhdGVtZW50LmdldExlbmd0aCgpICYmIG1fcFNxbEl0ZXJhdG9yKQoJCQkJewoJCQkJCS8vIGNoYW5nZSB0aGUgdmlldyBvZiB0aGUgZGF0YQoJCQkJCWRlbGV0ZSBtX3BTcWxJdGVyYXRvci0+Z2V0UGFyc2VUcmVlKCk7CgkJCQkJbV9wU3FsSXRlcmF0b3ItPnNldFBhcnNlVHJlZShOVUxMKTsKCQkJCQltX2JHcmFwaGljYWxEZXNpZ24gPSAhbV9iR3JhcGhpY2FsRGVzaWduOwoJCQkJCWltcGxfc2V0Vmlld01vZGUoICZhRXJyb3IgKTsKCQkJCX0KCQkJCWVsc2UKCQkJCXsKICAgICAgICAgICAgICAgICAgICA6OmNvbm5lY3Rpdml0eTo6T1NRTFBhcnNlTm9kZSogcE5vZGUgPSBtX2FTcWxQYXJzZXIucGFyc2VUcmVlKGFFcnJvck1zZyxtX3NTdGF0ZW1lbnQsbV9iR3JhcGhpY2FsRGVzaWduKTsKCQkJCQlpZiAoIHBOb2RlICkKCQkJCQl7CgkJCQkJCWRlbGV0ZSBtX3BTcWxJdGVyYXRvci0+Z2V0UGFyc2VUcmVlKCk7CgkJCQkJCW1fcFNxbEl0ZXJhdG9yLT5zZXRQYXJzZVRyZWUocE5vZGUpOwoJCQkJCQltX3BTcWxJdGVyYXRvci0+dHJhdmVyc2VBbGwoKTsKCiAgICAgICAgICAgICAgICAgICAgICAgIGlmICggbV9wU3FsSXRlcmF0b3ItPmhhc0Vycm9ycygpICkKICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgYUVycm9yID0gbV9wU3FsSXRlcmF0b3ItPmdldEVycm9ycygpOwogICAgICAgICAgICAgICAgICAgICAgICB9CgkJCQkJCWVsc2UKCQkJCQkJewoJCQkJCQkJY29uc3QgT1NRTFRhYmxlcyYgeFRhYnMgPSBtX3BTcWxJdGVyYXRvci0+Z2V0VGFibGVzKCk7CgkJCQkJCQlpZiAoIG1fcFNxbEl0ZXJhdG9yLT5nZXRTdGF0ZW1lbnRUeXBlKCkgIT0gU1FMX1NUQVRFTUVOVF9TRUxFQ1QgfHwgeFRhYnMuYmVnaW4oKSA9PSB4VGFicy5lbmQoKSApCgkJCQkJCQl7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYUVycm9yID0gU1FMRXhjZXB0aW9uKAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTdHJpbmcoIE1vZHVsZVJlcyggU1RSX1FSWV9OT1NFTEVDVCApICksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE5VTEwsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDo6cnRsOjpPVVN0cmluZyggUlRMX0NPTlNUQVNDSUlfVVNUUklOR1BBUkFNKCAiUzEwMDAiICkgKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgMTAwMCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQW55KCkKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICApOwoJCQkJCQkJfQoJCQkJCQkJZWxzZQoJCQkJCQkJewoJCQkJCQkJCS8vIGNoYW5nZSB0aGUgdmlldyBvZiB0aGUgZGF0YQoJCQkJCQkJCW1fYkdyYXBoaWNhbERlc2lnbiA9ICFtX2JHcmFwaGljYWxEZXNpZ247CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgOjpydGw6Ok9VU3RyaW5nIHNOZXdTdGF0ZW1lbnQ7CgkJCQkJCQkJcE5vZGUtPnBhcnNlTm9kZVRvU3RyKCBzTmV3U3RhdGVtZW50LCBnZXRDb25uZWN0aW9uKCkgKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZXRTdGF0ZW1lbnRfZmlyZUV2ZW50KCBzTmV3U3RhdGVtZW50ICk7CgkJCQkJCQkJZ2V0Q29udGFpbmVyKCktPlNhdmVVSUNvbmZpZygpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1fdlRhYmxlQ29ubmVjdGlvbkRhdGEuY2xlYXIoKTsKCQkJCQkJCQlpbXBsX3NldFZpZXdNb2RlKCAmYUVycm9yICk7CgkJCQkJCQl9CgkJCQkJCX0KCQkJCQl9CgkJCQkJZWxzZQoJCQkJCXsKICAgICAgICAgICAgICAgICAgICAgICAgYUVycm9yID0gU1FMRXhjZXB0aW9uKAogICAgICAgICAgICAgICAgICAgICAgICAgICAgU3RyaW5nKCBNb2R1bGVSZXMoIFNUUl9RUllfU1lOVEFYICkgKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIE5VTEwsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICA6OnJ0bDo6T1VTdHJpbmcoIFJUTF9DT05TVEFTQ0lJX1VTVFJJTkdQQVJBTSggIlMxMDAwIiApICksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAxMDAwLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgQW55KCkKICAgICAgICAgICAgICAgICAgICAgICAgKTsKCQkJCQl9CgkJCQl9CgkJCX0KCQkJY2F0Y2goY29uc3QgU1FMRXhjZXB0aW9uJiBlKQoJCQl7CiAgICAgICAgICAgICAgICBhRXJyb3IgPSA6OmNwcHU6OmdldENhdWdodEV4Y2VwdGlvbigpOwoJCQl9CgkJCWNhdGNoKGNvbnN0IEV4Y2VwdGlvbiYpCgkJCXsKICAgICAgICAgICAgICAgIERCR19VTkhBTkRMRURfRVhDRVBUSU9OKCk7CgkJCX0KCiAgICAgICAgICAgIGlmICggYUVycm9yLmlzVmFsaWQoKSApCiAgICAgICAgICAgICAgICBzaG93RXJyb3IoIGFFcnJvciApOwoKCQkJaWYobV9iR3JhcGhpY2FsRGVzaWduKQoJCQl7CgkJCQlJbnZhbGlkYXRlRmVhdHVyZShJRF9CUk9XU0VSX0FERFRBQkxFKTsKCQkJCUludmFsaWRhdGVGZWF0dXJlKFNJRF9SRUxBVElPTl9BRERfUkVMQVRJT04pOwoJCQl9CiAgICAgICAgfQogICAgICAgIGJyZWFrOwoJCWNhc2UgU0lEX0JST1dTRVJfQ0xFQVJfUVVFUlk6CgkJCXsKCQkJCUdldFVuZG9NYW5hZ2VyKCkuRW50ZXJMaXN0QWN0aW9uKCBTdHJpbmcoIE1vZHVsZVJlcyhTVFJfUVVFUllfVU5ET19UQUJXSU5ERUxFVEUpICksIFN0cmluZygpICk7CgkJCQlnZXRDb250YWluZXIoKS0+Y2xlYXIoKTsKCQkJCUdldFVuZG9NYW5hZ2VyKCkuTGVhdmVMaXN0QWN0aW9uKCk7CgogICAgICAgICAgICAgICAgc2V0U3RhdGVtZW50X2ZpcmVFdmVudCggOjpydGw6Ok9VU3RyaW5nKCkgKTsKCQkJCWlmKG1fYkdyYXBoaWNhbERlc2lnbikKCQkJCQlJbnZhbGlkYXRlRmVhdHVyZShJRF9CUk9XU0VSX0FERFRBQkxFKTsKCQkJfQoJCQkvLwlJbnZhbGlkYXRlRmVhdHVyZShJRF9CUk9XU0VSX1FVRVJZX0VYRUNVVEUpOwoJCQlicmVhazsKCQljYXNlIFNJRF9RVUVSWV9WSUVXX0ZVTkNUSU9OUzoKCQljYXNlIFNJRF9RVUVSWV9WSUVXX1RBQkxFUzoKCQljYXNlIFNJRF9RVUVSWV9WSUVXX0FMSUFTRVM6CgkJCWdldENvbnRhaW5lcigpLT5zZXRTbG90RW5hYmxlZChfbklkLCFnZXRDb250YWluZXIoKS0+aXNTbG90RW5hYmxlZChfbklkKSk7CgkJCXNldE1vZGlmaWVkKHNhbF9UcnVlKTsKCQkJYnJlYWs7CgkJY2FzZSBTSURfUVVFUllfRElTVElOQ1RfVkFMVUVTOgoJCQltX2JEaXN0aW5jdCA9ICFtX2JEaXN0aW5jdDsKCQkJc2V0TW9kaWZpZWQoc2FsX1RydWUpOwoJCQlicmVhazsKCQljYXNlIElEX0JST1dTRVJfUVVFUllfRVhFQ1VURToKCQkJaWYgKCBnZXRDb250YWluZXIoKS0+Y2hlY2tTdGF0ZW1lbnQoKSApCgkJCQlleGVjdXRlUXVlcnkoKTsKCQkJYnJlYWs7CgkJY2FzZSBTSURfREJfUVVFUllfUFJFVklFVzoKCQkJdHJ5CgkJCXsKICAgICAgICAgICAgICAgIFJlZmVyZW5jZTwgOjpjb206OnN1bjo6c3Rhcjo6dXRpbDo6WENsb3NlYWJsZSA+IHhDbG9zZUZyYW1lKCBnZXRDb250YWluZXIoKS0+Z2V0UHJldmlld0ZyYW1lKCksIFVOT19RVUVSWSApOwoJCQkJaWYgKCB4Q2xvc2VGcmFtZS5pcygpICkKCQkJCXsKICAgICAgICAgICAgICAgICAgICB0cnkKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIHhDbG9zZUZyYW1lLT5jbG9zZSggc2FsX1RydWUgKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgY2F0Y2goIGNvbnN0IEV4Y2VwdGlvbiYgKQogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAJT1NMX0VOU1VSRSggc2FsX0ZhbHNlLCAiT1F1ZXJ5Q29udHJvbGxlcjo6RXhlY3V0ZShTSURfREJfUVVFUllfUFJFVklFVyk6ICpub2JvZHkqIGlzIGV4cGVjdGVkIHRvIHZldG8gY2xvc2luZyB0aGUgcHJldmlldyBmcmFtZSEiICk7CiAgICAgICAgICAgICAgICAgICAgfQoJCQkJfQoJCQkJZWxzZQoJCQkJCUV4ZWN1dGUoSURfQlJPV1NFUl9RVUVSWV9FWEVDVVRFLFNlcXVlbmNlPCBQcm9wZXJ0eVZhbHVlID4oKSk7CgkJCX0KCQkJY2F0Y2goRXhjZXB0aW9uJikKCQkJewoJCQl9CgkJCWJyZWFrOwoJCWNhc2UgSURfUVVFUllfWk9PTV9JTjoKCQkJewovLwkJCQltX2Fab29tICo9IEZyYWN0aW9uKDEsMTApOwovLwkJCQlzdGF0aWNfY2FzdDxPUXVlcnlWaWV3U3dpdGNoKj4oZ2V0VmlldygpKS0+em9vbVRhYmxlVmlldyhtX2Fab29tKTsKCQkJfQoJCQlicmVhazsKCQljYXNlIElEX1FVRVJZX1pPT01fT1VUOgoJCQl7Ci8vCQkJCWlmKG1fYVpvb20gIT0gRnJhY3Rpb24oMSwxKSkKLy8JCQkJCW1fYVpvb20gLz0gRnJhY3Rpb24oMSwxMCk7Ci8vCQkJCXN0YXRpY19jYXN0PE9RdWVyeVZpZXdTd2l0Y2gqPihnZXRWaWV3KCkpLT56b29tVGFibGVWaWV3KG1fYVpvb20pOwoJCQl9CgkJCWJyZWFrOwojaWYgT1NMX0RFQlVHX0xFVkVMID4gMQoJCWNhc2UgSURfRURJVF9RVUVSWV9ERVNJR046CgkJY2FzZSBJRF9FRElUX1FVRVJZX1NRTDoKCQkJewoJCQkJOjpydGw6Ok9VU3RyaW5nIGFFcnJvck1zZzsKICAgICAgICAgICAgICAgIHNldFN0YXRlbWVudF9maXJlRXZlbnQoIGdldENvbnRhaW5lcigpLT5nZXRTdGF0ZW1lbnQoKSApOwoJCQkJOjpjb25uZWN0aXZpdHk6Ok9TUUxQYXJzZU5vZGUqIHBOb2RlID0gbV9hU3FsUGFyc2VyLnBhcnNlVHJlZSggYUVycm9yTXNnLCBtX3NTdGF0ZW1lbnQsIG1fYkdyYXBoaWNhbERlc2lnbiApOwoJCQkJaWYgKCBwTm9kZSApCgkJCQl7CgkJCQkJV2luZG93KiBwVmlldyA9IGdldFZpZXcoKTsKCQkJCQlNb2RhbERpYWxvZyogcFdpbmRvdyA9IG5ldyBNb2RhbERpYWxvZyggcFZpZXcsIFdCX1NURE1PREFMIHwgV0JfU0laRU1PVkUgfCBXQl9DRU5URVIgKTsKICAgICAgICAgICAgICAgICAgICBwV2luZG93LT5TZXRTaXplUGl4ZWwoIDo6U2l6ZSggcFZpZXctPkdldFNpemVQaXhlbCgpLldpZHRoKCkgLyAyLCBwVmlldy0+R2V0U2l6ZVBpeGVsKCkuSGVpZ2h0KCkgLyAyICkgKTsKCQkJCQlTdlRyZWVMaXN0Qm94KiBwVHJlZUJveCA9IG5ldyBTdlRyZWVMaXN0Qm94KCBwV2luZG93LCBXQl9CT1JERVIgfCBXQl9IQVNMSU5FUyB8IFdCX0hBU0JVVFRPTlMgfCBXQl9IQVNCVVRUT05TQVRST09UIHwgV0JfSEFTTElORVNBVFJPT1QgfCBXQl9WU0NST0xMICk7CiAgICAgICAgICAgICAgICAgICAgcFRyZWVCb3gtPlNldFBvc1NpemVQaXhlbCggOjpQb2ludCggNiwgNiApLCA6OlNpemUoIHBXaW5kb3ctPkdldFNpemVQaXhlbCgpLldpZHRoKCkgLSAxMiwgcFdpbmRvdy0+R2V0U2l6ZVBpeGVsKCkuSGVpZ2h0KCkgLSAxMiApKTsKICAgICAgICAgICAgICAgICAgICBwVHJlZUJveC0+U2V0Tm9kZURlZmF1bHRJbWFnZXMoKTsKCgkJCQkJaWYgKCBfbklkID09IElEX0VESVRfUVVFUllfREVTSUdOICkKCQkJCQl7CgkJCQkJCTo6Y29ubmVjdGl2aXR5OjpPU1FMUGFyc2VOb2RlKiBwVGVtcCA9IHBOb2RlID8gcE5vZGUtPmdldENoaWxkKDMpLT5nZXRDaGlsZCgxKSA6IE5VTEw7CgkJCQkJCS8vIG5vIHdoZXJlIGNsYXVzZSBmb3VuZAoJCQkJCQlpZiAoIHBUZW1wICYmICFwVGVtcC0+aXNMZWFmKCkgKQoJCQkJCQl7CgkJCQkJCQk6OmNvbm5lY3Rpdml0eTo6T1NRTFBhcnNlTm9kZSAqIHBDb25kaXRpb24gPSBwVGVtcC0+Z2V0Q2hpbGQoMSk7CgkJCQkJCQlpZiAoIHBDb25kaXRpb24gKSAvLyBubyB3aGVyZSBjbGF1c2UKCQkJCQkJCXsKCQkJCQkJCQk6OmNvbm5lY3Rpdml0eTo6T1NRTFBhcnNlTm9kZTo6bmVnYXRlU2VhcmNoQ29uZGl0aW9uKHBDb25kaXRpb24pOwoJCQkJCQkJCTo6Y29ubmVjdGl2aXR5OjpPU1FMUGFyc2VOb2RlICpwTm9kZVRtcCA9IHBUZW1wLT5nZXRDaGlsZCgxKTsKCgkJCQkJCQkJOjpjb25uZWN0aXZpdHk6Ok9TUUxQYXJzZU5vZGU6OmRpc2p1bmN0aXZlTm9ybWFsRm9ybShwTm9kZVRtcCk7CgkJCQkJCQkJcE5vZGVUbXAgPSBwVGVtcC0+Z2V0Q2hpbGQoMSk7CgkJCQkJCQkJOjpjb25uZWN0aXZpdHk6Ok9TUUxQYXJzZU5vZGU6OmFic29ycHRpb25zKHBOb2RlVG1wKTsKCQkJCQkJCQlwTm9kZVRtcCA9IHBUZW1wLT5nZXRDaGlsZCgxKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBPU1FMUGFyc2VOb2RlOjpjb21wcmVzcyhwTm9kZVRtcCk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcE5vZGVUbXAgPSBwVGVtcC0+Z2V0Q2hpbGQoMSk7CgkJCQkJCQl9IC8vIGlmICggcENvbmRpdGlvbiApIC8vIG5vIHdoZXJlIGNsYXVzZQogICAgICAgICAgICAgICAgICAgICAgICAgICAgOjpydGw6Ok9VU3RyaW5nIHNUZW1wOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgcE5vZGUtPnBhcnNlTm9kZVRvU3RyKHNUZW1wLGdldENvbm5lY3Rpb24oKSk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBnZXRDb250YWluZXIoKS0+c2V0U3RhdGVtZW50KHNUZW1wKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIAoJCQkJCQl9CgkJCQkJfQoKCQkJCQlpbnNlcnRQYXJzZVRyZWUocFRyZWVCb3gscE5vZGUpOwoKCQkJCQlwVHJlZUJveC0+U2hvdygpOwoJCQkJCXBXaW5kb3ctPkV4ZWN1dGUoKTsKCgkJCQkJZGVsZXRlIHBUcmVlQm94OwoJCQkJCWRlbGV0ZSBwV2luZG93OwoJCQkJCWRlbGV0ZSBwTm9kZTsKCQkJCX0KCQkJCWJyZWFrOwoJCQl9CiNlbmRpZgoJCWRlZmF1bHQ6CgkJCU9Kb2luQ29udHJvbGxlcjo6RXhlY3V0ZShfbklkLGFBcmdzKTsKCQkJcmV0dXJuOyAvLyBlbHNlIHdlIHdvdWxkIGludmFsaWRhdGUgdHdpY2UKCX0KCUludmFsaWRhdGVGZWF0dXJlKF9uSWQpOwp9CgovLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQp2b2lkIE9RdWVyeUNvbnRyb2xsZXI6OmltcGxfc2hvd0F1dG9TUUxWaWV3RXJyb3IoIGNvbnN0IDo6Y29tOjpzdW46OnN0YXI6OnVubzo6QW55JiBfckVycm9yRGV0YWlscyApCnsKICAgIFNRTENvbnRleHQgYUVycm9yQ29udGV4dDsKICAgIGFFcnJvckNvbnRleHQuTWVzc2FnZSA9IGxjbF9nZXRPYmplY3RSZXNvdXJjZVN0cmluZyggU1RSX0VSUk9SX1BBUlNJTkdfU1RBVEVNRU5ULCBtX25Db21tYW5kVHlwZSApOwogICAgYUVycm9yQ29udGV4dC5Db250ZXh0ID0gKnRoaXM7CiAgICBhRXJyb3JDb250ZXh0LkRldGFpbHMgPSBsY2xfZ2V0T2JqZWN0UmVzb3VyY2VTdHJpbmcoIFNUUl9JTkZPX09QRU5JTkdfSU5fU1FMX1ZJRVcsIG1fbkNvbW1hbmRUeXBlICk7CiAgICBhRXJyb3JDb250ZXh0Lk5leHRFeGNlcHRpb24gPSBfckVycm9yRGV0YWlsczsKICAgIHNob3dFcnJvciggYUVycm9yQ29udGV4dCApOwp9CgovLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQpib29sIE9RdWVyeUNvbnRyb2xsZXI6OmltcGxfc2V0Vmlld01vZGUoIDo6ZGJ0b29sczo6U1FMRXhjZXB0aW9uSW5mbyogX3BFcnJvckluZm8gKQp7CiAgICBPU0xfUFJFQ09ORCggZ2V0Q29udGFpbmVyKCksICJPUXVlcnlDb250cm9sbGVyOjppbXBsX3NldFZpZXdNb2RlOiBpbGxlZ2FsIGNhbGwhIiApOwoKICAgIGJvb2wgd2FzTW9kaWZpZWQgPSBpc01vZGlmaWVkKCk7CgogICAgU1FMRXhjZXB0aW9uSW5mbyBhRXJyb3I7CiAgICBib29sIGJTdWNjZXNzID0gZ2V0Q29udGFpbmVyKCktPnN3aXRjaFZpZXcoICZhRXJyb3IgKTsKICAgIGlmICggIWJTdWNjZXNzICkKCXsKCQltX2JHcmFwaGljYWxEZXNpZ24gPSAhbV9iR3JhcGhpY2FsRGVzaWduOwogICAgICAgIC8vIHJlc3RvcmUgb2xkIHN0YXRlCgkJZ2V0Q29udGFpbmVyKCktPnN3aXRjaFZpZXcoIE5VTEwgKTsKICAgICAgICAgICAgLy8gZG9uJ3QgcGFzcyAmYUVycm9yIGhlcmUsIHRoaXMgd291bGQgb3ZlcndyaXRlIHRoZSBlcnJvciB3aGljaCB0aGUgZmlyc3Qgc3dpdGNoVmlldyBjYWxsCiAgICAgICAgICAgIC8vIHJldHVybmVkIGluIHRoaXMgbG9jYXRpb24uCiAgICAgICAgaWYgKCBfcEVycm9ySW5mbyApCiAgICAgICAgICAgICpfcEVycm9ySW5mbyA9IGFFcnJvcjsKICAgICAgICBlbHNlCiAgICAgICAgICAgIHNob3dFcnJvciggYUVycm9yICk7Cgl9CgllbHNlCiAgICB7CiAgICAgICAgZW5zdXJlVG9vbGJhcnMoICp0aGlzLCBtX2JHcmFwaGljYWxEZXNpZ24gKTsKICAgIH0KCiAgICBzZXRNb2RpZmllZCggd2FzTW9kaWZpZWQgKTsKICAgIHJldHVybiBiU3VjY2VzczsKfQoKLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0Kdm9pZCBPUXVlcnlDb250cm9sbGVyOjppbXBsX2luaXRpYWxpemUoKQp7CglPSm9pbkNvbnRyb2xsZXI6OmltcGxfaW5pdGlhbGl6ZSgpOwoKICAgIGNvbnN0IE5hbWVkVmFsdWVDb2xsZWN0aW9uJiByQXJndW1lbnRzKCBnZXRJbml0UGFyYW1zKCkgKTsKCiAgICA6OnJ0bDo6T1VTdHJpbmcgc0NvbW1hbmQ7CiAgICBtX25Db21tYW5kVHlwZSA9IENvbW1hbmRUeXBlOjpRVUVSWTsKCiAgICAvLyCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsAogICAgLy8gsCByZWFkaW5nIHBhcmFtZXRlcnMKICAgIC8vILCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwCiAgICAvLyBsZWdhY3kgcGFyYW1ldGVycyBmaXJzdCAobGF0ZXIgb3ZlcndyaXR0ZW4gYnkgcmVndWxhciBwYXJhbWV0ZXJzKQogICAgOjpydGw6Ok9VU3RyaW5nIHNJbmRlcGVuZGVudFNRTENvbW1hbmQ7CiAgICBpZiAoIHJBcmd1bWVudHMuZ2V0X2Vuc3VyZVR5cGUoICJJbmRlcGVuZGVudFNRTENvbW1hbmQiLCBzSW5kZXBlbmRlbnRTUUxDb21tYW5kICkgKQogICAgewogICAgICAgIE9TTF9FTlNVUkUoIGZhbHNlLCAiT1F1ZXJ5Q29udHJvbGxlcjo6aW1wbF9pbml0aWFsaXplOiBJbmRlcGVuZGVudFNRTENvbW1hbmQgaXMgcmVnb2duaXplZCBmb3IgY29tcGF0aWJpbGl0eSBvbmx5ISIgKTsKICAgICAgICBzQ29tbWFuZCA9IHNJbmRlcGVuZGVudFNRTENvbW1hbmQ7CiAgICAgICAgbV9uQ29tbWFuZFR5cGUgPSBDb21tYW5kVHlwZTo6Q09NTUFORDsKICAgIH0KCiAgICA6OnJ0bDo6T1VTdHJpbmcgc0N1cnJlbnRRdWVyeTsKICAgIGlmICggckFyZ3VtZW50cy5nZXRfZW5zdXJlVHlwZSggIkN1cnJlbnRRdWVyeSIsIHNDdXJyZW50UXVlcnkgKSApCiAgICB7CiAgICAgICAgT1NMX0VOU1VSRSggZmFsc2UsICJPUXVlcnlDb250cm9sbGVyOjppbXBsX2luaXRpYWxpemU6IEN1cnJlbnRRdWVyeSBpcyByZWdvZ25pemVkIGZvciBjb21wYXRpYmlsaXR5IG9ubHkhIiApOwogICAgICAgIHNDb21tYW5kID0gc0N1cnJlbnRRdWVyeTsKICAgICAgICBtX25Db21tYW5kVHlwZSA9IENvbW1hbmRUeXBlOjpRVUVSWTsKICAgIH0KCiAgICBzYWxfQm9vbCBiQ3JlYXRlVmlldyggc2FsX0ZhbHNlICk7CiAgICBpZiAoIHJBcmd1bWVudHMuZ2V0X2Vuc3VyZVR5cGUoICJDcmVhdGVWaWV3IiwgYkNyZWF0ZVZpZXcgKSAmJiBiQ3JlYXRlVmlldyApCiAgICB7CiAgICAgICAgT1NMX0VOU1VSRSggZmFsc2UsICJPUXVlcnlDb250cm9sbGVyOjppbXBsX2luaXRpYWxpemU6IEN1cnJlbnRRdWVyeSBpcyByZWdvZ25pemVkIGZvciBjb21wYXRpYmlsaXR5IG9ubHkhIiApOwogICAgICAgIG1fbkNvbW1hbmRUeXBlID0gQ29tbWFuZFR5cGU6OlRBQkxFOwogICAgfQoKICAgIC8vIG5vbi1sZWdhY3kgcGFyYW1ldGVycyB3aGljaCBvdmVyd3JpdGUgdGhlIGxlZ2FjeSBwYXJhbWV0ZXJzCiAgICByQXJndW1lbnRzLmdldF9lbnN1cmVUeXBlKCAoOjpydGw6Ok9VU3RyaW5nKVBST1BFUlRZX0NPTU1BTkQsIHNDb21tYW5kICk7CiAgICByQXJndW1lbnRzLmdldF9lbnN1cmVUeXBlKCAoOjpydGw6Ok9VU3RyaW5nKVBST1BFUlRZX0NPTU1BTkRfVFlQRSwgbV9uQ29tbWFuZFR5cGUgKTsKCiAgICAvLyB0cmFuc2xhdGUgQ29tbWFuZC9UeXBlIGludG8gcHJvcGVyIG1lbWJlcnMKICAgIC8vIFRPRE8vTGF0ZXI6IGFsbCB0aGlzIChpbmNsdWRpbmcgdGhvc2UgbWVtYmVycykgc2hvdWxkIGJlIGhpZGRlbiBiZWhpbmQgc29tZSBhYnN0YWN0IGludGVyZmFjZSwKICAgIC8vIHdoaWNoIGlzIGltcGxlbWVudGVkIGZvciBhbGwgdGhlIHRocmVlIGNvbW1hbmRzCiAgICBzd2l0Y2ggKCBtX25Db21tYW5kVHlwZSApCiAgICB7CiAgICBjYXNlIENvbW1hbmRUeXBlOjpRVUVSWToKICAgICAgICBtX3NOYW1lID0gc0NvbW1hbmQ7CiAgICAgICAgYnJlYWs7CiAgICBjYXNlIENvbW1hbmRUeXBlOjpUQUJMRToKICAgICAgICBtX3NOYW1lID0gc0NvbW1hbmQ7CiAgICAgICAgYnJlYWs7CiAgICBjYXNlIENvbW1hbmRUeXBlOjpDT01NQU5EOgogICAgICAgIHNldFN0YXRlbWVudF9maXJlRXZlbnQoIHNDb21tYW5kICk7CiAgICAgICAgbV9zTmFtZSA9IDo6cnRsOjpPVVN0cmluZygpOwogICAgICAgIGJyZWFrOwogICAgZGVmYXVsdDoKICAgICAgICBPU0xfRU5TVVJFKCBmYWxzZSwgIk9RdWVyeUNvbnRyb2xsZXI6OmltcGxfaW5pdGlhbGl6ZTogbG9naWMgZXJyb3IgaW4gY29kZSEiICk7CiAgICAgICAgdGhyb3cgUnVudGltZUV4Y2VwdGlvbigpOwogICAgfQoKICAgIC8vIG1vcmUgbGVnYWN5IHBhcmFtZXRlcnMKICAgIHNhbF9Cb29sIGJHcmFwaGljYWxEZXNpZ24oIHNhbF9UcnVlICk7CiAgICBpZiAoIHJBcmd1bWVudHMuZ2V0X2Vuc3VyZVR5cGUoICg6OnJ0bDo6T1VTdHJpbmcpUFJPUEVSVFlfUVVFUllERVNJR05WSUVXLCBiR3JhcGhpY2FsRGVzaWduICkgKQogICAgewogICAgICAgIE9TTF9FTlNVUkUoIGZhbHNlLCAiT1F1ZXJ5Q29udHJvbGxlcjo6aW1wbF9pbml0aWFsaXplOiBRdWVyeURlc2lnblZpZXcgaXMgcmVnb2duaXplZCBmb3IgY29tcGF0aWJpbGl0eSBvbmx5ISIgKTsKICAgICAgICBtX2JHcmFwaGljYWxEZXNpZ24gPSBiR3JhcGhpY2FsRGVzaWduOwogICAgfQoKICAgIC8vIG1vcmUgbm9uLWxlZ2FjeQogICAgckFyZ3VtZW50cy5nZXRfZW5zdXJlVHlwZSggKDo6cnRsOjpPVVN0cmluZylQUk9QRVJUWV9HUkFQSElDQUxfREVTSUdOLCBtX2JHcmFwaGljYWxEZXNpZ24gKTsKCiAgICBib29sIGJFc2NhcGVQcm9jZXNzaW5nKCBzYWxfVHJ1ZSApOwogICAgaWYgKCByQXJndW1lbnRzLmdldF9lbnN1cmVUeXBlKCAoOjpydGw6Ok9VU3RyaW5nKVBST1BFUlRZX0VTQ0FQRV9QUk9DRVNTSU5HLCBiRXNjYXBlUHJvY2Vzc2luZyApICkKICAgIHsKICAgICAgICBzZXRFc2NhcGVQcm9jZXNzaW5nX2ZpcmVFdmVudCggYkVzY2FwZVByb2Nlc3NpbmcgKTsKCiAgICAgICAgT1NMX0VOU1VSRSggbV9iRXNjYXBlUHJvY2Vzc2luZyB8fCAhbV9iR3JhcGhpY2FsRGVzaWduLCAiT1F1ZXJ5Q29udHJvbGxlcjo6aW1wbF9pbml0aWFsaXplOiBjYW4ndCBkbyB0aGUgZ3JhcGhpY2FsIGRlc2lnbiB3aXRob3V0IGVzY2FwZSBwcm9jZXNzaW5nISIgKTsKICAgICAgICBpZiAoICFtX2JFc2NhcGVQcm9jZXNzaW5nICkKICAgICAgICAgICAgbV9iR3JhcGhpY2FsRGVzaWduID0gZmFsc2U7CiAgICB9CgogICAgLy8gLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4KICAgIC8vIC4gaW5pdGlhbCBkZXNpZ24KICAgIGJvb2wgYkZvcmNlSW5pdGlhbERlc2lnbiA9IGZhbHNlOwogICAgU2VxdWVuY2U8IFByb3BlcnR5VmFsdWUgPiBhQ3VycmVudFF1ZXJ5RGVzaWduUHJvcHM7CiAgICBhQ3VycmVudFF1ZXJ5RGVzaWduUHJvcHMgPSByQXJndW1lbnRzLmdldE9yRGVmYXVsdCggIkN1cnJlbnRRdWVyeURlc2lnbiIsIGFDdXJyZW50UXVlcnlEZXNpZ25Qcm9wcyApOwoKICAgIGlmICggYUN1cnJlbnRRdWVyeURlc2lnblByb3BzLmdldExlbmd0aCgpICkKICAgIHsKICAgICAgICA6OmNvbXBoZWxwZXI6Ok5hbWVkVmFsdWVDb2xsZWN0aW9uIGFDdXJyZW50UXVlcnlEZXNpZ24oIGFDdXJyZW50UXVlcnlEZXNpZ25Qcm9wcyApOwogICAgICAgIGlmICggYUN1cnJlbnRRdWVyeURlc2lnbi5oYXMoICg6OnJ0bDo6T1VTdHJpbmcpUFJPUEVSVFlfR1JBUEhJQ0FMX0RFU0lHTiApICkKICAgICAgICB7CiAgICAgICAgICAgIGFDdXJyZW50UXVlcnlEZXNpZ24uZ2V0X2Vuc3VyZVR5cGUoICg6OnJ0bDo6T1VTdHJpbmcpUFJPUEVSVFlfR1JBUEhJQ0FMX0RFU0lHTiwgbV9iR3JhcGhpY2FsRGVzaWduICk7CiAgICAgICAgfQogICAgICAgIGlmICggYUN1cnJlbnRRdWVyeURlc2lnbi5oYXMoICg6OnJ0bDo6T1VTdHJpbmcpUFJPUEVSVFlfRVNDQVBFX1BST0NFU1NJTkcgKSApCiAgICAgICAgewogICAgICAgICAgICBhQ3VycmVudFF1ZXJ5RGVzaWduLmdldF9lbnN1cmVUeXBlKCAoOjpydGw6Ok9VU3RyaW5nKVBST1BFUlRZX0VTQ0FQRV9QUk9DRVNTSU5HLCBtX2JFc2NhcGVQcm9jZXNzaW5nICk7CiAgICAgICAgfQogICAgICAgIGlmICggYUN1cnJlbnRRdWVyeURlc2lnbi5oYXMoICJTdGF0ZW1lbnQiICkgKQogICAgICAgIHsKICAgICAgICAgICAgOjpydGw6Ok9VU3RyaW5nIHNTdGF0ZW1lbnQ7CiAgICAgICAgICAgIGFDdXJyZW50UXVlcnlEZXNpZ24uZ2V0X2Vuc3VyZVR5cGUoICJTdGF0ZW1lbnQiLCBzU3RhdGVtZW50ICk7CiAgICAgICAgICAgIGFDdXJyZW50UXVlcnlEZXNpZ24ucmVtb3ZlKCAiU3RhdGVtZW50IiApOwogICAgICAgICAgICBzZXRTdGF0ZW1lbnRfZmlyZUV2ZW50KCBzU3RhdGVtZW50ICk7CiAgICAgICAgfQoKICAgICAgICBsb2FkVmlld1NldHRpbmdzKCBhQ3VycmVudFF1ZXJ5RGVzaWduICk7CgogICAgICAgIGJGb3JjZUluaXRpYWxEZXNpZ24gPSB0cnVlOwogICAgfQoKICAgIC8vILCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwCglpZiAoICFlbnN1cmVDb25uZWN0ZWQoIHNhbF9GYWxzZSApICkKCXsJLy8gd2UgaGF2ZSBubyBjb25uZWN0aW9uIHNvIHdoYXQgZWxzZSBzaG91bGQgd2UgZG8KCQltX2JHcmFwaGljYWxEZXNpZ24gPSBzYWxfRmFsc2U7CgkJaWYgKCBlZGl0aW5nVmlldygpICkKCQl7CgkJCWNvbm5lY3Rpb25Mb3N0TWVzc2FnZSgpOwoJCQl0aHJvdyBTUUxFeGNlcHRpb24oKTsKCQl9Cgl9CgogICAgLy8gY2hlY2sgdGhlIHZpZXcgY2FwYWJpbGl0aWVzCglpZiAoIGlzQ29ubmVjdGVkKCkgJiYgZWRpdGluZ1ZpZXcoKSApCgl7CgkJUmVmZXJlbmNlPCBYVmlld3NTdXBwbGllciA+IHhWaWV3c1N1cCggZ2V0Q29ubmVjdGlvbigpLCBVTk9fUVVFUlkgKTsKICAgICAgICBSZWZlcmVuY2U8IFhOYW1lQWNjZXNzID4geFZpZXdzOwogICAgICAgIGlmICggeFZpZXdzU3VwLmlzKCkgKQogICAgICAgICAgICB4Vmlld3MgPSB4Vmlld3NTdXAtPmdldFZpZXdzKCk7CgogICAgICAgIGlmICggIXhWaWV3cy5pcygpICkKCQl7CS8vIHdlIGNhbid0IGNyZWF0ZSB2aWV3cyBzbyB3ZSBhc2sgaWYgdGhlIHVzZXIgd2FudHMgdG8gY3JlYXRlIGEgcXVlcnkgaW5zdGVhZAogICAgICAgICAgICBtX25Db21tYW5kVHlwZSA9IENvbW1hbmRUeXBlOjpRVUVSWTsKCQkJc2FsX0Jvb2wgYkNsb3NlID0gc2FsX0ZhbHNlOwoJCQl7CgkJCQlTdHJpbmcgYVRpdGxlKCBNb2R1bGVSZXMoIFNUUl9RVUVSWURFU0lHTl9OT19WSUVXX1NVUFBPUlQgKSApOwoJCQkJU3RyaW5nIGFNZXNzYWdlKCBNb2R1bGVSZXMoIFNUUl9RVUVSWURFU0lHTl9OT19WSUVXX0FTSyApICk7CgkJCQlPRGF0YVZpZXcqIHBXaW5kb3cgPSBnZXRWaWV3KCk7CgkJCQlPU1FMTWVzc2FnZUJveCBhRGxnKCBwV2luZG93LCBhVGl0bGUsIGFNZXNzYWdlLCBXQl9ZRVNfTk8gfCBXQl9ERUZfWUVTLCBPU1FMTWVzc2FnZUJveDo6UXVlcnkgKTsKCQkJCWJDbG9zZSA9IGFEbGcuRXhlY3V0ZSgpID09IFJFVF9OTzsKCQkJfQoJCQlpZiAoIGJDbG9zZSApCgkJCQl0aHJvdyBWZXRvRXhjZXB0aW9uKCk7CgkJfQoKICAgICAgICAvLyBub3cgaWYgd2UgYXJlIHRvIGVkaXQgYW4gZXhpc3RpbmcgdmlldywgY2hlY2sgd2hldGhlciB0aGlzIGlzIHBvc3NpYmxlCiAgICAgICAgaWYgKCBtX3NOYW1lLmdldExlbmd0aCgpICkKICAgICAgICB7CiAgICAgICAgICAgIEFueSBhVmlldyggeFZpZXdzLT5nZXRCeU5hbWUoIG1fc05hbWUgKSApOwogICAgICAgICAgICAgICAgLy8gd2lsbCB0aHJvdyBpZiB0aGVyZSBpcyBubyBzdWNoIHZpZXcKICAgICAgICAgICAgaWYgKCAhKCBhVmlldyA+Pj0gbV94QWx0ZXJWaWV3ICkgKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICB0aHJvdyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oCiAgICAgICAgICAgICAgICAgICAgOjpydGw6Ok9VU3RyaW5nKCBTdHJpbmcoIE1vZHVsZVJlcyggU1RSX05PX0FMVEVSX1ZJRVdfU1VQUE9SVCApICkgKSwKICAgICAgICAgICAgICAgICAgICAqdGhpcywKICAgICAgICAgICAgICAgICAgICAxCiAgICAgICAgICAgICAgICApOwogICAgICAgICAgICB9CiAgICAgICAgfQoJfQoKCU9TTF9FTlNVUkUoZ2V0RGF0YVNvdXJjZSgpLmlzKCksIk9RdWVyeUNvbnRyb2xsZXI6OmltcGxfaW5pdGlhbGl6ZTogbmVlZCBhIGRhdGFzb3VyY2UhIik7CgoJdHJ5Cgl7CgkJZ2V0Q29udGFpbmVyKCktPmluaXRpYWxpemUoKTsKICAgICAgICBpbXBsX3Jlc2V0KCBiRm9yY2VJbml0aWFsRGVzaWduICk7CgogICAgICAgIFNRTEV4Y2VwdGlvbkluZm8gYUVycm9yOwogICAgICAgIGNvbnN0IGJvb2wgYkF0dGVtcHRlZEdyYXBoaWNhbERlc2lnbiA9IG1fYkdyYXBoaWNhbERlc2lnbjsKCiAgICAgICAgaWYgKCBiRm9yY2VJbml0aWFsRGVzaWduICkKICAgICAgICB7CiAgICAgICAgICAgIGdldENvbnRhaW5lcigpLT5mb3JjZUluaXRpYWxWaWV3KCk7CiAgICAgICAgfQogICAgICAgIGVsc2UKICAgICAgICB7CiAgICAgICAgICAgIGltcGxfc2V0Vmlld01vZGUoICZhRXJyb3IgKTsKICAgICAgICB9CgogICAgICAgIGlmICggYUVycm9yLmlzVmFsaWQoKSAmJiBiQXR0ZW1wdGVkR3JhcGhpY2FsRGVzaWduICYmICFtX2JHcmFwaGljYWxEZXNpZ24gKQogICAgICAgIHsKICAgICAgICAgICAgLy8gd2UgdHJpZWQgaW5pdGlhbGl6aW5nIHRoZSBncmFwaGljYWwgdmlldywgdGhpcyBmYWlsZWQsIGFuZCB3ZSB3ZXJlIGF1dG9tYXRpY2FsbHkgc3dpdGNoZWQgdG8gU1FMCiAgICAgICAgICAgIC8vIHZpZXcgPT4gdGVsbCB0aGlzIHRvIHRoZSB1c2VyCiAgICAgICAgICAgIGlmICggIWVkaXRpbmdWaWV3KCkgKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBpbXBsX3Nob3dBdXRvU1FMVmlld0Vycm9yKCBhRXJyb3IuZ2V0KCkgKTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICAKCQlDbGVhclVuZG9NYW5hZ2VyKCk7CgoJCWlmICAoICAoIG1fYkdyYXBoaWNhbERlc2lnbiApCiAgICAgICAgICAgICYmICggICggIW1fc05hbWUuZ2V0TGVuZ3RoKCkgJiYgIWVkaXRpbmdDb21tYW5kKCkgKQogICAgICAgICAgICAgICB8fCAoICFtX3NTdGF0ZW1lbnQuZ2V0TGVuZ3RoKCkgJiYgZWRpdGluZ0NvbW1hbmQoKSApCiAgICAgICAgICAgICAgICkKICAgICAgICAgICAgKQogICAgICAgIHsKICAgICAgICAgICAgQXBwbGljYXRpb246OlBvc3RVc2VyRXZlbnQoIExJTksoIHRoaXMsIE9RdWVyeUNvbnRyb2xsZXIsIE9uRXhlY3V0ZUFkZFRhYmxlICkgKTsKICAgICAgICB9CgoJCXNldE1vZGlmaWVkKHNhbF9GYWxzZSk7Cgl9CgljYXRjaChTUUxFeGNlcHRpb24mIGUpCgl7CgkJREJHX1VOSEFORExFRF9FWENFUFRJT04oKTsKCQkvLyB3ZSBjYXVnaHQgYW4gZXhjZXB0aW9uIHNvIHdlIHN3aXRjaCB0byB0ZXh0IG9ubHkgbW9kZQoJCXsKCQkJbV9iR3JhcGhpY2FsRGVzaWduID0gc2FsX0ZhbHNlOwoJCQlnZXRDb250YWluZXIoKS0+aW5pdGlhbGl6ZSgpOwoJCQlPRGF0YVZpZXcqIHBXaW5kb3cgPSBnZXRWaWV3KCk7CgkJCU9TUUxNZXNzYWdlQm94KHBXaW5kb3csZSkuRXhlY3V0ZSgpOwoJCX0KCQl0aHJvdzsKCX0KfQoKLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0Kdm9pZCBPUXVlcnlDb250cm9sbGVyOjpvbkxvYWRlZE1lbnUoY29uc3QgUmVmZXJlbmNlPCA6OmNvbTo6c3VuOjpzdGFyOjpmcmFtZTo6WExheW91dE1hbmFnZXIgPiYgLypfeExheW91dE1hbmFnZXIqLykKewogICAgZW5zdXJlVG9vbGJhcnMoICp0aGlzLCBtX2JHcmFwaGljYWxEZXNpZ24gKTsKfQoKLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KOjpydGw6Ok9VU3RyaW5nIE9RdWVyeUNvbnRyb2xsZXI6OmdldFByaXZhdGVUaXRsZSggKSBjb25zdAp7Cgk6OnJ0bDo6T1VTdHJpbmcgc05hbWUgPSBtX3NOYW1lOwoJaWYgKCAhc05hbWUuZ2V0TGVuZ3RoKCkgKQoJewogICAgICAgIGlmICggIWVkaXRpbmdDb21tYW5kKCkgKQogICAgICAgIHsKCQkJOjp2b3M6Ok9HdWFyZCBhU29sYXJHdWFyZChBcHBsaWNhdGlvbjo6R2V0U29sYXJNdXRleCgpKTsKCQkJOjpvc2w6Ok11dGV4R3VhcmQgYUd1YXJkKCBnZXRNdXRleCgpICk7CiAgICAgICAgICAgIFN0cmluZyBhRGVmYXVsdE5hbWUgPSBTdHJpbmcoIE1vZHVsZVJlcyggZWRpdGluZ1ZpZXcoKSA/IFNUUl9WSUVXX1RJVExFIDogU1RSX1FSWV9USVRMRSApICk7CgkJCXNOYW1lID0gYURlZmF1bHROYW1lLkdldFRva2VuKDAsJyAnKTsKICAgICAgICAgICAgc05hbWUgKz0gOjpydGw6Ok9VU3RyaW5nOjp2YWx1ZU9mKGdldEN1cnJlbnRTdGFydE51bWJlcigpKTsKICAgICAgICB9Cgl9CiAgICByZXR1cm4gc05hbWU7Cn0KLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0Kdm9pZCBPUXVlcnlDb250cm9sbGVyOjpzZXRRdWVyeUNvbXBvc2VyKCkKewoJaWYoaXNDb25uZWN0ZWQoKSkKCXsKCQlSZWZlcmVuY2U8IFhTUUxRdWVyeUNvbXBvc2VyRmFjdG9yeSA+ICB4RmFjdG9yeShnZXRDb25uZWN0aW9uKCksIFVOT19RVUVSWSk7CgkJT1NMX0VOU1VSRSh4RmFjdG9yeS5pcygpLCJDb25uZWN0aW9uIGRvZXNuJ3Qgc3VwcG9ydCBhIHF1ZXJ5Y29tcG9zZXIiKTsKCQlpZiAoIHhGYWN0b3J5LmlzKCkgJiYgZ2V0Q29udGFpbmVyKCkgKQoJCXsKCQkJdHJ5CgkJCXsKCQkJCW1feENvbXBvc2VyID0geEZhY3RvcnktPmNyZWF0ZVF1ZXJ5Q29tcG9zZXIoKTsKCQkJCWdldENvbnRhaW5lcigpLT5zZXRTdGF0ZW1lbnQobV9zU3RhdGVtZW50KTsKCQkJfQoJCQljYXRjaCAoRXhjZXB0aW9uJikKCQkJewoJCQkJbV94Q29tcG9zZXIgPSBOVUxMOwoJCQl9CgkJCU9TTF9FTlNVUkUobV94Q29tcG9zZXIuaXMoKSwiTm8gcXVlcnljb21wb3NlciBhdmFpbGFibGUhIik7CgkJCVJlZmVyZW5jZTxYVGFibGVzU3VwcGxpZXI+IHhUYWJsZXNTdXAoZ2V0Q29ubmVjdGlvbigpLCBVTk9fUVVFUlkpOwoJCQlkZWxldGVJdGVyYXRvcigpOwoJCQltX3BTcWxJdGVyYXRvciA9IG5ldyA6OmNvbm5lY3Rpdml0eTo6T1NRTFBhcnNlVHJlZUl0ZXJhdG9yKCBnZXRDb25uZWN0aW9uKCksIHhUYWJsZXNTdXAtPmdldFRhYmxlcygpLCBtX2FTcWxQYXJzZXIsIE5VTEwgKTsKCQl9Cgl9Cn0KLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0Kc2FsX0Jvb2wgT1F1ZXJ5Q29udHJvbGxlcjo6Q29uc3RydWN0KFdpbmRvdyogcFBhcmVudCkKewoJLy8gVE9ETzogd2UgaGF2ZSB0byBjaGVjayBpZiB3ZSBzaG91bGQgY3JlYXRlIHRoZSB0ZXh0LSBvciB0aGUgZGVzaWduLSB2aWV3CgoJc2V0VmlldyggKiBuZXcgT1F1ZXJ5Q29udGFpbmVyV2luZG93KCBwUGFyZW50LCAqdGhpcywgZ2V0T1JCKCkgKSApOwoKCXJldHVybiBPSm9pbkNvbnRyb2xsZXI6OkNvbnN0cnVjdChwUGFyZW50KTsKfQoKLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KT0pvaW5EZXNpZ25WaWV3KiBPUXVlcnlDb250cm9sbGVyOjpnZXRKb2luVmlldygpCnsKCXJldHVybiBnZXRDb250YWluZXIoKS0+Z2V0RGVzaWduVmlldygpOwp9Ci8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCnZvaWQgT1F1ZXJ5Q29udHJvbGxlcjo6ZGVzY3JpYmVTdXBwb3J0ZWRGZWF0dXJlcygpCnsKCU9Kb2luQ29udHJvbGxlcjo6ZGVzY3JpYmVTdXBwb3J0ZWRGZWF0dXJlcygpOwogICAgaW1wbERlc2NyaWJlU3VwcG9ydGVkRmVhdHVyZSggIi51bm86U2F2ZUFzIiwgICAgICAgICAgICBJRF9CUk9XU0VSX1NBVkVBU0RPQywgICAgICAgQ29tbWFuZEdyb3VwOjpET0NVTUVOVCApOwogICAgaW1wbERlc2NyaWJlU3VwcG9ydGVkRmVhdHVyZSggIi51bm86U2JhTmF0aXZlU3FsIiwgICAgICBJRF9CUk9XU0VSX0VTQUNQRVBST0NFU1NJTkcsQ29tbWFuZEdyb3VwOjpGT1JNQVQgKTsKICAgIGltcGxEZXNjcmliZVN1cHBvcnRlZEZlYXR1cmUoICIudW5vOkRCVmlld0Z1bmN0aW9ucyIsICAgU0lEX1FVRVJZX1ZJRVdfRlVOQ1RJT05TLCAgIENvbW1hbmRHcm91cDo6VklFVyApOwogICAgaW1wbERlc2NyaWJlU3VwcG9ydGVkRmVhdHVyZSggIi51bm86REJWaWV3VGFibGVOYW1lcyIsICBTSURfUVVFUllfVklFV19UQUJMRVMsICAgICAgQ29tbWFuZEdyb3VwOjpWSUVXICk7CiAgICBpbXBsRGVzY3JpYmVTdXBwb3J0ZWRGZWF0dXJlKCAiLnVubzpEQlZpZXdBbGlhc2VzIiwgICAgIFNJRF9RVUVSWV9WSUVXX0FMSUFTRVMsICAgICBDb21tYW5kR3JvdXA6OlZJRVcgKTsKICAgIGltcGxEZXNjcmliZVN1cHBvcnRlZEZlYXR1cmUoICIudW5vOkRCRGlzdGluY3RWYWx1ZXMiLCAgU0lEX1FVRVJZX0RJU1RJTkNUX1ZBTFVFUywgIENvbW1hbmRHcm91cDo6Rk9STUFUICk7CiAgICBpbXBsRGVzY3JpYmVTdXBwb3J0ZWRGZWF0dXJlKCAiLnVubzpEQkNoYW5nZURlc2lnbk1vZGUiLElEX0JST1dTRVJfU1FMLCAgICAgICAgICAgICBDb21tYW5kR3JvdXA6OlZJRVcgKTsKICAgIGltcGxEZXNjcmliZVN1cHBvcnRlZEZlYXR1cmUoICIudW5vOkRCQ2xlYXJRdWVyeSIsICAgICAgU0lEX0JST1dTRVJfQ0xFQVJfUVVFUlksICAgIENvbW1hbmRHcm91cDo6RURJVCApOwogICAgaW1wbERlc2NyaWJlU3VwcG9ydGVkRmVhdHVyZSggIi51bm86U2JhRXhlY3V0ZVNxbCIsICAgICBJRF9CUk9XU0VSX1FVRVJZX0VYRUNVVEUsICAgQ29tbWFuZEdyb3VwOjpWSUVXICk7CiAgICBpbXBsRGVzY3JpYmVTdXBwb3J0ZWRGZWF0dXJlKCAiLnVubzpEQkFkZFJlbGF0aW9uIiwgICAgIFNJRF9SRUxBVElPTl9BRERfUkVMQVRJT04sICBDb21tYW5kR3JvdXA6OkVESVQgKTsKICAgIGltcGxEZXNjcmliZVN1cHBvcnRlZEZlYXR1cmUoICIudW5vOkRCUXVlcnlQcmV2aWV3IiwgICAgU0lEX0RCX1FVRVJZX1BSRVZJRVcsICAgICAgIENvbW1hbmRHcm91cDo6VklFVyApOwoKI2lmIE9TTF9ERUJVR19MRVZFTCA+IDEKICAgIGltcGxEZXNjcmliZVN1cHBvcnRlZEZlYXR1cmUoICIudW5vOkRCU2hvd1BhcnNlVHJlZSIsICAgSURfRURJVF9RVUVSWV9TUUwgKTsKICAgIGltcGxEZXNjcmliZVN1cHBvcnRlZEZlYXR1cmUoICIudW5vOkRCTWFrZURpc2p1bmN0IiwgICAgSURfRURJVF9RVUVSWV9ERVNJR04gKTsKI2VuZGlmCn0KLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0Kdm9pZCBPUXVlcnlDb250cm9sbGVyOjppbXBsX29uTW9kaWZ5Q2hhbmdlZCgpCnsKCU9Kb2luQ29udHJvbGxlcjo6aW1wbF9vbk1vZGlmeUNoYW5nZWQoKTsKCUludmFsaWRhdGVGZWF0dXJlKFNJRF9CUk9XU0VSX0NMRUFSX1FVRVJZKTsKCUludmFsaWRhdGVGZWF0dXJlKElEX0JST1dTRVJfU0FWRUFTRE9DKTsKCUludmFsaWRhdGVGZWF0dXJlKElEX0JST1dTRVJfUVVFUllfRVhFQ1VURSk7Cn0KLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0Kdm9pZCBTQUxfQ0FMTCBPUXVlcnlDb250cm9sbGVyOjpkaXNwb3NpbmcoIGNvbnN0IEV2ZW50T2JqZWN0JiBTb3VyY2UgKSB0aHJvdyhSdW50aW1lRXhjZXB0aW9uKQp7Cgk6OnZvczo6T0d1YXJkIGFHdWFyZChBcHBsaWNhdGlvbjo6R2V0U29sYXJNdXRleCgpKTsKCglpZiAoIGdldENvbnRhaW5lcigpICYmIFNvdXJjZS5Tb3VyY2UuaXMoKSApCgl7CgkJaWYgKCBTb3VyY2UuU291cmNlID09IG1fYUN1cnJlbnRGcmFtZS5nZXRGcmFtZSgpICkKCQl7CS8vIG91ciBmcmFtZSBpcyBiZWVpbmcgZGlzcG9zZWQgLT4gY2xvc2UgdGhlIHByZXZpZXcgd2luZG93IChpZiB3ZSBoYXZlIG9uZSkKICAgICAgICAgICAgUmVmZXJlbmNlPCBYRnJhbWUgPiB4UHJldmlld0ZyYW1lKCBnZXRDb250YWluZXIoKS0+Z2V0UHJldmlld0ZyYW1lKCkgKTsKCQkJOjpjb21waGVscGVyOjpkaXNwb3NlQ29tcG9uZW50KCB4UHJldmlld0ZyYW1lICk7CgkJfQoJCWVsc2UgaWYgKCBTb3VyY2UuU291cmNlID09IGdldENvbnRhaW5lcigpLT5nZXRQcmV2aWV3RnJhbWUoKSApCgkJewoJCQlnZXRDb250YWluZXIoKS0+ZGlzcG9zaW5nUHJldmlldygpOwoJCX0KCX0KCglPSm9pbkNvbnRyb2xsZXI6OmRpc3Bvc2luZyhTb3VyY2UpOwp9Ci8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCnZvaWQgT1F1ZXJ5Q29udHJvbGxlcjo6cmVjb25uZWN0KHNhbF9Cb29sIF9iVUkpCnsKCWRlbGV0ZUl0ZXJhdG9yKCk7Cgk6OmNvbXBoZWxwZXI6OmRpc3Bvc2VDb21wb25lbnQobV94Q29tcG9zZXIpOwoKCU9Kb2luQ29udHJvbGxlcjo6cmVjb25uZWN0KCBfYlVJICk7CgoJaWYgKGlzQ29ubmVjdGVkKCkpCgl7CgkJc2V0UXVlcnlDb21wb3NlcigpOwoJfQoJZWxzZQoJewoJCWlmKG1fYkdyYXBoaWNhbERlc2lnbikKCQl7CgkJCW1fYkdyYXBoaWNhbERlc2lnbiA9IHNhbF9GYWxzZTsKCQkJLy8gZG9uJ3QgY2FsbCBFeGVjdXRlKFNRTCkgYmVjYXVzZSB0aGlzIGNoYW5nZXMgdGhlIHNxbCBzdGF0ZW1lbnQKCQkJaW1wbF9zZXRWaWV3TW9kZSggTlVMTCApOwoJCX0KCQlJbnZhbGlkYXRlQWxsKCk7Cgl9Cn0KCi8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCnZvaWQgT1F1ZXJ5Q29udHJvbGxlcjo6c2F2ZVZpZXdTZXR0aW5ncyggOjpjb21waGVscGVyOjpOYW1lZFZhbHVlQ29sbGVjdGlvbiYgb19yVmlld1NldHRpbmdzLCBjb25zdCBib29sIGlfaW5jbHVkaW5nQ3JpdGVyaWEgKSBjb25zdAp7CglzYXZlVGFibGVXaW5kb3dzKCBvX3JWaWV3U2V0dGluZ3MgKTsKCiAgICBPVGFibGVGaWVsZHM6OmNvbnN0X2l0ZXJhdG9yIGZpZWxkID0gbV92VGFibGVGaWVsZERlc2MuYmVnaW4oKTsKICAgIE9UYWJsZUZpZWxkczo6Y29uc3RfaXRlcmF0b3IgZmllbGRFbmQgPSBtX3ZUYWJsZUZpZWxkRGVzYy5lbmQoKTsKCiAgICA6OmNvbXBoZWxwZXI6Ok5hbWVkVmFsdWVDb2xsZWN0aW9uIGFBbGxGaWVsZHNEYXRhOwogICAgOjpjb21waGVscGVyOjpOYW1lZFZhbHVlQ29sbGVjdGlvbiBhRmllbGREYXRhOwoJZm9yICggc2FsX0ludDMyIGkgPSAxOyBmaWVsZCAhPSBmaWVsZEVuZDsgKytmaWVsZCwgKytpICkKCXsKCQlpZiAoICEoKmZpZWxkKS0+SXNFbXB0eSgpICkKCQl7CiAgICAgICAgICAgIGFGaWVsZERhdGEuY2xlYXIoKTsKCQkJKCpmaWVsZCktPlNhdmUoIGFGaWVsZERhdGEsIGlfaW5jbHVkaW5nQ3JpdGVyaWEgKTsKCiAgICAgICAgICAgIGNvbnN0IDo6cnRsOjpPVVN0cmluZyBzRmllbGRTZXR0aW5nTmFtZSA9IDo6cnRsOjpPVVN0cmluZyggUlRMX0NPTlNUQVNDSUlfVVNUUklOR1BBUkFNKCAiRmllbGQiICkgKSArIDo6cnRsOjpPVVN0cmluZzo6dmFsdWVPZiggaSApOwogICAgICAgICAgICBhQWxsRmllbGRzRGF0YS5wdXQoIHNGaWVsZFNldHRpbmdOYW1lLCBhRmllbGREYXRhLmdldFByb3BlcnR5VmFsdWVzKCkgKTsKCQl9Cgl9CgogICAgb19yVmlld1NldHRpbmdzLnB1dCggIkZpZWxkcyIsIGFBbGxGaWVsZHNEYXRhLmdldFByb3BlcnR5VmFsdWVzKCkgKTsKICAgIG9fclZpZXdTZXR0aW5ncy5wdXQoICJTcGxpdHRlclBvc2l0aW9uIiwgbV9uU3BsaXRQb3MgKTsKICAgIG9fclZpZXdTZXR0aW5ncy5wdXQoICJWaXNpYmxlUm93cyIsIG1fblZpc2libGVSb3dzICk7Cn0KLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0Kdm9pZCBPUXVlcnlDb250cm9sbGVyOjpsb2FkVmlld1NldHRpbmdzKCBjb25zdCA6OmNvbXBoZWxwZXI6Ok5hbWVkVmFsdWVDb2xsZWN0aW9uJiBvX3JWaWV3U2V0dGluZ3MgKQp7Cglsb2FkVGFibGVXaW5kb3dzKCBvX3JWaWV3U2V0dGluZ3MgKTsKCiAgICBtX25TcGxpdFBvcyA9IG9fclZpZXdTZXR0aW5ncy5nZXRPckRlZmF1bHQoICJTcGxpdHRlclBvc2l0aW9uIiwgbV9uU3BsaXRQb3MgKTsKICAgIG1fblZpc2libGVSb3dzID0gb19yVmlld1NldHRpbmdzLmdldE9yRGVmYXVsdCggIlZpc2libGVSb3dzIiwgbV9uVmlzaWJsZVJvd3MgKTsKICAgIG1fYUZpZWxkSW5mb3JtYXRpb24gPSBvX3JWaWV3U2V0dGluZ3MuZ2V0T3JEZWZhdWx0KCAiRmllbGRzIiwgbV9hRmllbGRJbmZvcm1hdGlvbiApOwp9Ci8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCnNhbF9JbnQzMiBPUXVlcnlDb250cm9sbGVyOjpnZXRDb2xXaWR0aChzYWxfdUludDE2IF9uQ29sUG9zKSAgY29uc3QKewogICAgaWYgKCBfbkNvbFBvcyA8IG1fYUZpZWxkSW5mb3JtYXRpb24uZ2V0TGVuZ3RoKCkgKQogICAgewogICAgICAgIDo6c3RkOjphdXRvX3B0cjxPVGFibGVGaWVsZERlc2M+IHBGaWVsZCggbmV3IE9UYWJsZUZpZWxkRGVzYygpKTsKICAgICAgICBwRmllbGQtPkxvYWQoIG1fYUZpZWxkSW5mb3JtYXRpb25bIF9uQ29sUG9zIF0sIGZhbHNlICk7CiAgICAgICAgcmV0dXJuIHBGaWVsZC0+R2V0Q29sV2lkdGgoKTsKICAgIH0KICAgIHJldHVybiAwOwp9Ci8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tClJlZmVyZW5jZTxYTmFtZUFjY2Vzcz4gT1F1ZXJ5Q29udHJvbGxlcjo6Z2V0T2JqZWN0Q29udGFpbmVyKCkgIGNvbnN0CnsKCVJlZmVyZW5jZTwgWE5hbWVBY2Nlc3MgPiB4RWxlbWVudHM7CglpZiAoIGVkaXRpbmdWaWV3KCkgKQoJewoJCVJlZmVyZW5jZTwgWFZpZXdzU3VwcGxpZXIgPiB4Vmlld3NTdXBwKCBnZXRDb25uZWN0aW9uKCksIFVOT19RVUVSWSApOwoJCWlmICggeFZpZXdzU3VwcC5pcygpICkKCQkJeEVsZW1lbnRzID0geFZpZXdzU3VwcC0+Z2V0Vmlld3MoKTsKCX0KCWVsc2UKCXsKCQlSZWZlcmVuY2U8IFhRdWVyaWVzU3VwcGxpZXIgPiB4UXVlcmllc1N1cHAoIGdldENvbm5lY3Rpb24oKSwgVU5PX1FVRVJZICk7CgkJaWYgKCB4UXVlcmllc1N1cHAuaXMoKSApCgkJCXhFbGVtZW50cyA9IHhRdWVyaWVzU3VwcC0+Z2V0UXVlcmllcygpOwoJCWVsc2UKCQl7CgkJCVJlZmVyZW5jZTwgWFF1ZXJ5RGVmaW5pdGlvbnNTdXBwbGllciA+IHhRdWVyeURlZnNTdXBwKCBnZXREYXRhU291cmNlKCksIFVOT19RVUVSWSApOwoJCQlpZiAoIHhRdWVyeURlZnNTdXBwLmlzKCkgKQoJCQkJeEVsZW1lbnRzID0geFF1ZXJ5RGVmc1N1cHAtPmdldFF1ZXJ5RGVmaW5pdGlvbnMoKTsKCQl9Cgl9CgogICAgT1NMX0VOU1VSRSggeEVsZW1lbnRzLmlzKCksICJPUXVlcnlDb250cm9sbGVyOjpnZXRPYmplY3RDb250YWluZXI6IHVuYWJsZSB0byBvYnRhaW4gdGhlIGNvbnRhaW5lciEiICk7CglyZXR1cm4geEVsZW1lbnRzOwp9CgovLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQp2b2lkIE9RdWVyeUNvbnRyb2xsZXI6OmV4ZWN1dGVRdWVyeSgpCnsKCS8vIHdlIGRvbid0IG5lZWQgdG8gY2hlY2sgdGhlIGNvbm5lY3Rpb24gaGVyZSBiZWNhdXNlIHdlIGFscmVhZHkgY2hlY2sgdGhlIGNvbXBvc2VyCgkvLyB3aGljaCBjYW4ndCBsaXZlIHdpdGhvdXQgaGlzIGNvbm5lY3Rpb24KCTo6cnRsOjpPVVN0cmluZyBzVHJhbnNsYXRlZFN0bXQgPSB0cmFuc2xhdGVTdGF0ZW1lbnQoIGZhbHNlICk7CgoJOjpydGw6Ok9VU3RyaW5nIHNEYXRhU291cmNlTmFtZSA9IGdldERhdGFTb3VyY2VOYW1lKCk7CglpZiAoIHNEYXRhU291cmNlTmFtZS5nZXRMZW5ndGgoKSAmJiBzVHJhbnNsYXRlZFN0bXQuZ2V0TGVuZ3RoKCkgKQoJewoJCXRyeQoJCXsKCQkJZ2V0Q29udGFpbmVyKCktPnNob3dQcmV2aWV3KCBnZXRGcmFtZSgpICk7CgkJCUludmFsaWRhdGVGZWF0dXJlKFNJRF9EQl9RVUVSWV9QUkVWSUVXKTsKCgkJCVVSTCBhV2FudFRvRGlzcGF0Y2g7CgkJCWFXYW50VG9EaXNwYXRjaC5Db21wbGV0ZSA9IDo6cnRsOjpPVVN0cmluZzo6Y3JlYXRlRnJvbUFzY2lpKCIuY29tcG9uZW50OkRCL0RhdGFTb3VyY2VCcm93c2VyIik7CgoJCQk6OnJ0bDo6T1VTdHJpbmcgc0ZyYW1lTmFtZSggRlJBTUVfTkFNRV9RVUVSWV9QUkVWSUVXICk7CgkJCXNhbF9JbnQzMiBuU2VhcmNoRmxhZ3MgPSBGcmFtZVNlYXJjaEZsYWc6OkNISUxEUkVOOwoKCQkJUmVmZXJlbmNlPCBYRGlzcGF0Y2g+IHhEaXNwOwoJCQlSZWZlcmVuY2U8IFhEaXNwYXRjaFByb3ZpZGVyPiB4UHJvdiggZ2V0RnJhbWUoKS0+ZmluZEZyYW1lKCBzRnJhbWVOYW1lLCBuU2VhcmNoRmxhZ3MgKSwgVU5PX1FVRVJZICk7CgkJCWlmKCF4UHJvdi5pcygpKQoJCQl7CgkJCQl4UHJvdi5zZXQoIGdldEZyYW1lKCksIFVOT19RVUVSWSApOwoJCQkJaWYgKHhQcm92LmlzKCkpCgkJCQkJeERpc3AgPSB4UHJvdi0+cXVlcnlEaXNwYXRjaChhV2FudFRvRGlzcGF0Y2gsIHNGcmFtZU5hbWUsIG5TZWFyY2hGbGFncyk7CgkJCX0KCQkJZWxzZQoJCQl7CgkJCQl4RGlzcCA9IHhQcm92LT5xdWVyeURpc3BhdGNoKGFXYW50VG9EaXNwYXRjaCwgc0ZyYW1lTmFtZSwgRnJhbWVTZWFyY2hGbGFnOjpTRUxGKTsKCQkJfQoJCQlpZiAoeERpc3AuaXMoKSkKCQkJewoJCQkJU2VxdWVuY2U8IFByb3BlcnR5VmFsdWU+IGFQcm9wcyg5KTsKCQkJCWFQcm9wc1swXS5OYW1lID0gUFJPUEVSVFlfREFUQVNPVVJDRU5BTUU7CgkJCQlhUHJvcHNbMF0uVmFsdWUgPDw9IHNEYXRhU291cmNlTmFtZTsKCgkJCQlhUHJvcHNbMV0uTmFtZSA9IFBST1BFUlRZX0NPTU1BTkRfVFlQRTsKCQkJCWFQcm9wc1sxXS5WYWx1ZSA8PD0gQ29tbWFuZFR5cGU6OkNPTU1BTkQ7CgoJCQkJYVByb3BzWzJdLk5hbWUgPSBQUk9QRVJUWV9DT01NQU5EOwoJCQkJYVByb3BzWzJdLlZhbHVlIDw8PSBzVHJhbnNsYXRlZFN0bXQ7CgoJCQkJYVByb3BzWzNdLk5hbWUgPSBQUk9QRVJUWV9FTkFCTEVfQlJPV1NFUjsKCQkJCWFQcm9wc1szXS5WYWx1ZSA9IDo6Y3BwdTo6Ym9vbDJhbnkoc2FsX0ZhbHNlKTsKCgkJCQlhUHJvcHNbNF0uTmFtZSA9IFBST1BFUlRZX0FDVElWRV9DT05ORUNUSU9OOwoJCQkJYVByb3BzWzRdLlZhbHVlIDw8PSBnZXRDb25uZWN0aW9uKCk7CgoJCQkJYVByb3BzWzVdLk5hbWUgPSBQUk9QRVJUWV9VUERBVEVfQ0FUQUxPR05BTUU7CgkJCQlhUHJvcHNbNV0uVmFsdWUgPDw9IG1fc1VwZGF0ZUNhdGFsb2dOYW1lOwoKCQkJCWFQcm9wc1s2XS5OYW1lID0gUFJPUEVSVFlfVVBEQVRFX1NDSEVNQU5BTUU7CgkJCQlhUHJvcHNbNl0uVmFsdWUgPDw9IG1fc1VwZGF0ZVNjaGVtYU5hbWU7CgoJCQkJYVByb3BzWzddLk5hbWUgPSBQUk9QRVJUWV9VUERBVEVfVEFCTEVOQU1FOwoJCQkJYVByb3BzWzddLlZhbHVlIDw8PSBtX3NVcGRhdGVUYWJsZU5hbWU7CgoJCQkJYVByb3BzWzhdLk5hbWUgPSBQUk9QRVJUWV9FU0NBUEVfUFJPQ0VTU0lORzsKCQkJCWFQcm9wc1s4XS5WYWx1ZSA9IDo6Y3BwdTo6Ym9vbDJhbnkobV9iRXNjYXBlUHJvY2Vzc2luZyk7CgoJCQkJeERpc3AtPmRpc3BhdGNoKGFXYW50VG9EaXNwYXRjaCwgYVByb3BzKTsKCQkJCS8vIGNoZWNrIHRoZSBzdGF0ZSBvZiB0aGUgYmVhbWVyCgkJCQkvLyBiZSBub3RpZmllZCB3aGVuIHRoZSBiZWFtZXIgZnJhbWUgaXMgY2xvc2VkCgkJCQlSZWZlcmVuY2U8IFhDb21wb25lbnQgPiAgeENvbXBvbmVudCggZ2V0RnJhbWUoKS0+ZmluZEZyYW1lKCBzRnJhbWVOYW1lLCBuU2VhcmNoRmxhZ3MgKSwgVU5PX1FVRVJZICk7CgkJCQlpZiAoeENvbXBvbmVudC5pcygpKQoJCQkJewoJCQkJCU9TTF9FTlNVUkUoUmVmZXJlbmNlPCBYRnJhbWUgPih4Q29tcG9uZW50LCBVTk9fUVVFUlkpLmdldCgpID09IGdldENvbnRhaW5lcigpLT5nZXRQcmV2aWV3RnJhbWUoKS5nZXQoKSwKCQkJCQkJIk9RdWVyeUNvbnRyb2xsZXI6OmV4ZWN1dGVRdWVyeTogb29wcyAuLi4gd2hpY2ggd2luZG93IGRvIEkgaGF2ZSBoZXJlPyIpOwoJCQkJCVJlZmVyZW5jZTwgWEV2ZW50TGlzdGVuZXI+IHhFdnRMKCg6OmNwcHU6Ok9XZWFrT2JqZWN0Kil0aGlzLFVOT19RVUVSWSk7CgkJCQkJeENvbXBvbmVudC0+YWRkRXZlbnRMaXN0ZW5lcih4RXZ0TCk7CgkJCQl9CgkJCX0KCQkJZWxzZQoJCQl7CgkJCQlPU0xfRU5TVVJFKDAsIkNvdWxkbid0IGNyZWF0ZSBhIGJlYW1lciB3aW5kb3chIik7CgkJCX0KCQl9CgkJY2F0Y2goY29uc3QgRXhjZXB0aW9uJikKCQl7CgkJCU9TTF9FTlNVUkUoMCwiQ291bGRuJ3QgY3JlYXRlIGEgYmVhbWVyIHdpbmRvdyEiKTsKCQl9Cgl9Cn0KLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0Kc2FsX0Jvb2wgT1F1ZXJ5Q29udHJvbGxlcjo6YXNrRm9yTmV3TmFtZShjb25zdCBSZWZlcmVuY2U8WE5hbWVBY2Nlc3M+JiBfeEVsZW1lbnRzLHNhbF9Cb29sIF9iU2F2ZUFzKQp7CiAgICBPU0xfRU5TVVJFKCAhZWRpdGluZ0NvbW1hbmQoKSwgIk9RdWVyeUNvbnRyb2xsZXI6OmFza0Zvck5ld05hbWU6IG5vdCB0byBiZSBjYWxsZWQgd2hlbiBkZXNpZ25pbmcgYW4gaW5kZXBlbmRlbnQgc3RhdGVtZW50ISIgKTsKICAgIGlmICggZWRpdGluZ0NvbW1hbmQoKSApCiAgICAgICAgcmV0dXJuIHNhbF9GYWxzZTsKCiAgICBPU0xfUFJFQ09ORCggX3hFbGVtZW50cy5pcygpLCAiT1F1ZXJ5Q29udHJvbGxlcjo6YXNrRm9yTmV3TmFtZTogaW52YWxpZCBjb250YWluZXIhIiApOwogICAgaWYgICggIV94RWxlbWVudHMuaXMoKSApCiAgICAgICAgcmV0dXJuIHNhbF9GYWxzZTsKCglzYWxfQm9vbCBiUmV0ID0gc2FsX1RydWU7CglzYWxfQm9vbCBiTmV3ID0gX2JTYXZlQXMgfHwgIV94RWxlbWVudHMtPmhhc0J5TmFtZSggbV9zTmFtZSApOwoJaWYoYk5ldykKCXsKCQlTdHJpbmcgYURlZmF1bHROYW1lOwoJCWlmICggKCBfYlNhdmVBcyAmJiAhYk5ldyApIHx8ICggYk5ldyAmJiBtX3NOYW1lLmdldExlbmd0aCgpICkgKQoJCQlhRGVmYXVsdE5hbWUgPSBTdHJpbmcoIG1fc05hbWUgKTsKCQllbHNlCiAgICAgICAgewogICAgICAgICAgICBTdHJpbmcgc05hbWUgPSBTdHJpbmcoIE1vZHVsZVJlcyggZWRpdGluZ1ZpZXcoKSA/IFNUUl9WSUVXX1RJVExFIDogU1RSX1FSWV9USVRMRSApICk7CgkJCWFEZWZhdWx0TmFtZSA9IHNOYW1lLkdldFRva2VuKDAsJyAnKTsKICAgICAgICAgICAgLy9hRGVmYXVsdE5hbWUgPSBnZXRQcml2YXRlVGl0bGUoICk7CiAgICAgICAgICAgIGFEZWZhdWx0TmFtZSA9IDo6ZGJ0b29sczo6Y3JlYXRlVW5pcXVlTmFtZShfeEVsZW1lbnRzLGFEZWZhdWx0TmFtZSk7CiAgICAgICAgfQoKICAgICAgICBEeW5hbWljVGFibGVPclF1ZXJ5TmFtZUNoZWNrIGFOYW1lQ2hlY2tlciggZ2V0Q29ubmVjdGlvbigpLCBDb21tYW5kVHlwZTo6UVVFUlkgKTsKCQlPU2F2ZUFzRGxnIGFEbGcoCgkJCQlnZXRWaWV3KCksCiAgICAgICAgICAgICAgICBtX25Db21tYW5kVHlwZSwKICAgICAgICAgICAgICAgIGdldE9SQigpLAoJCQkJZ2V0Q29ubmVjdGlvbigpLAoJCQkJYURlZmF1bHROYW1lLAogICAgICAgICAgICAgICAgYU5hbWVDaGVja2VyLAoJCQkJU0FEX0RFRkFVTFQgKTsKCiAgICAgICAgYlJldCA9ICggYURsZy5FeGVjdXRlKCkgPT0gUkVUX09LICk7CgkJaWYgKCBiUmV0ICkKCQl7CgkJCW1fc05hbWUgPSBhRGxnLmdldE5hbWUoKTsKCQkJaWYgKCBlZGl0aW5nVmlldygpICkKCQkJewoJCQkJbV9zVXBkYXRlQ2F0YWxvZ05hbWUJPSBhRGxnLmdldENhdGFsb2coKTsKCQkJCW1fc1VwZGF0ZVNjaGVtYU5hbWUJCT0gYURsZy5nZXRTY2hlbWEoKTsKCQkJfQoJCX0KCX0KCXJldHVybiBiUmV0Owp9Ci8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCmJvb2wgT1F1ZXJ5Q29udHJvbGxlcjo6ZG9TYXZlQXNEb2Moc2FsX0Jvb2wgX2JTYXZlQXMpCnsKCU9TTF9FTlNVUkUoaXNFZGl0YWJsZSgpLCJTbG90IElEX0JST1dTRVJfU0FWRURPQyBzaG91bGQgbm90IGJlIGVuYWJsZWQhIik7CglpZiAoICFlZGl0aW5nQ29tbWFuZCgpICYmICFoYXZlRGF0YVNvdXJjZSgpICkKCXsKCQlTdHJpbmcgYU1lc3NhZ2UoTW9kdWxlUmVzKFNUUl9EQVRBU09VUkNFX0RFTEVURUQpKTsKCQlPU1FMV2FybmluZ0JveCggZ2V0VmlldygpLCBhTWVzc2FnZSApLkV4ZWN1dGUoKTsKICAgICAgICByZXR1cm4gZmFsc2U7Cgl9CgoJUmVmZXJlbmNlPCBYTmFtZUFjY2VzcyA+IHhFbGVtZW50cyA9IGdldE9iamVjdENvbnRhaW5lcigpOwoJaWYgKCAheEVsZW1lbnRzLmlzKCkgKQogICAgICAgIHJldHVybiBmYWxzZTsKCiAgICBpZiAoICFnZXRDb250YWluZXIoKS0+Y2hlY2tTdGF0ZW1lbnQoKSApCgkJcmV0dXJuIGZhbHNlOwoKCTo6cnRsOjpPVVN0cmluZyBzVHJhbnNsYXRlZFN0bXQgPSB0cmFuc2xhdGVTdGF0ZW1lbnQoKTsKICAgIGlmICggZWRpdGluZ0NvbW1hbmQoKSApCiAgICB7CiAgICAgICAgc2V0TW9kaWZpZWQoIHNhbF9GYWxzZSApOwogICAgICAgIC8vIHRoaXMgaXMgYWxsIHdlIG5lZWQgdG8gZG8gaGVyZS4gdHJhbnNsYXRlU3RhdGVtZW50IGltcGxpY2l0bHkgc2V0IG91ciBtX3NTdGF0ZW1lbnQsIGFuZAogICAgICAgIC8vIG5vdGlmaWVkIGl0LCBhbmQgdGhhdCdzIGFsbAogICAgICAgIHJldHVybiB0cnVlOwogICAgfQoKCWlmICggIXNUcmFuc2xhdGVkU3RtdC5nZXRMZW5ndGgoKSApCiAgICAgICAgcmV0dXJuIGZhbHNlOwoKICAgIC8vIGZpcnN0IHdlIG5lZWQgYSBuYW1lIGZvciBvdXIgcXVlcnkgc28gYXNrIHRoZSB1c2VyCgkvLyBkaWQgd2UgZ2V0IGEgbmFtZQogICAgOjpydGw6Ok9VU3RyaW5nIHNPcmlnaW5hbE5hbWUoIG1fc05hbWUgKTsKICAgIGlmICggIWFza0Zvck5ld05hbWUoIHhFbGVtZW50cywgX2JTYXZlQXMgKSB8fCAhbV9zTmFtZS5nZXRMZW5ndGgoKSApCiAgICAgICAgcmV0dXJuIGZhbHNlOwoKICAgIFNRTEV4Y2VwdGlvbkluZm8gYUluZm87CiAgICBib29sIGJTdWNjZXNzID0gZmFsc2U7CiAgICBib29sIGJOZXcgPSBmYWxzZTsKCXRyeQoJewogICAgICAgIGJOZXcgPSAoIF9iU2F2ZUFzICkKICAgICAgICAgICAgfHwgKCAheEVsZW1lbnRzLT5oYXNCeU5hbWUoIG1fc05hbWUgKSApOwoKICAgICAgICBSZWZlcmVuY2U8WFByb3BlcnR5U2V0PiB4UXVlcnk7CgkJaWYgKCBiTmV3ICkgLy8ganVzdCB0byBtYWtlIHN1cmUgdGhlIHF1ZXJ5IGFscmVhZHkgZXhpc3RzCgkJewogICAgICAgICAgICAvLyBkcm9wIHRoZSBxdWVyeSwgaW4gY2FzZSBpdCBhbHJlYWR5IGV4aXN0cwoJCQlpZiAoIHhFbGVtZW50cy0+aGFzQnlOYW1lKCBtX3NOYW1lICkgKQoJCQl7CgkJCQlSZWZlcmVuY2U8IFhEcm9wID4geE5hbWVDb250KCB4RWxlbWVudHMsIFVOT19RVUVSWSApOwoJCQkJaWYgKCB4TmFtZUNvbnQuaXMoKSApCgkJCQkJeE5hbWVDb250LT5kcm9wQnlOYW1lKCBtX3NOYW1lICk7CgkJCQllbHNlCgkJCQl7CgkJCQkJUmVmZXJlbmNlPCBYTmFtZUNvbnRhaW5lciA+IHhDb250KCB4RWxlbWVudHMsIFVOT19RVUVSWSApOwoJCQkJCWlmICggeENvbnQuaXMoKSApCgkJCQkJCXhDb250LT5yZW1vdmVCeU5hbWUoIG1fc05hbWUgKTsKCQkJCX0KCQkJfQoKICAgICAgICAgICAgLy8gY3JlYXRlIGEgbmV3IChlbXB0eSwgdW5pbml0aWFsaXplZCkgcXVlcnkgcmVzcC4gdmlldwoJCQlSZWZlcmVuY2U8IFhEYXRhRGVzY3JpcHRvckZhY3RvcnkgPiB4RmFjdCggeEVsZW1lbnRzLCBVTk9fUVVFUlkgKTsKCQkJaWYgKCB4RmFjdC5pcygpICkKCQkJewoJCQkJeFF1ZXJ5ID0geEZhY3QtPmNyZWF0ZURhdGFEZXNjcmlwdG9yKCk7CgkJCQkvLyB0byBzZXQgdGhlIG5hbWUgaXMgb25seSBhbGxvd2VkIHdoZW4gdGhlIHF1ZXJ5IGlzIG5ldwoJCQkJeFF1ZXJ5LT5zZXRQcm9wZXJ0eVZhbHVlKCBQUk9QRVJUWV9OQU1FLCBtYWtlQW55KCBtX3NOYW1lICkgKTsKCQkJfQoJCQllbHNlCgkJCXsKCQkJCVJlZmVyZW5jZTwgWFNpbmdsZVNlcnZpY2VGYWN0b3J5ID4geFNpbmdsZUZhYyggeEVsZW1lbnRzLCBVTk9fUVVFUlkgKTsKICAgICAgICAgICAgICAgIGlmICggeFNpbmdsZUZhYy5pcygpICkKCQkJCQl4UXVlcnkgPSB4UXVlcnkucXVlcnkoIHhTaW5nbGVGYWMtPmNyZWF0ZUluc3RhbmNlKCkgKTsKCQkJfQoJCX0KCQllbHNlCgkJewoJCQl4RWxlbWVudHMtPmdldEJ5TmFtZSggbV9zTmFtZSApID4+PSB4UXVlcnk7CgkJfQogICAgICAgIGlmICggIXhRdWVyeS5pcygpICkKICAgICAgICAgICAgdGhyb3cgUnVudGltZUV4Y2VwdGlvbigpOwoKICAgICAgICAvLyB0aGUgbmV3IGNvbW1hbmRzCiAgICAgICAgaWYgKCBlZGl0aW5nVmlldygpICYmICFiTmV3ICkKICAgICAgICB7CiAgICAgICAgICAgIE9TTF9FTlNVUkUoIHhRdWVyeSA9PSBtX3hBbHRlclZpZXcsICJPUXVlcnlDb250cm9sbGVyOjpkb1NhdmVBc0RvYzogYWxyZWFkeSBoYXZlIGFub3RoZXIgYWx0ZXJhYmxlIHZpZXcgLi4uIT8iICk7CiAgICAgICAgICAgIG1feEFsdGVyVmlldy5zZXQoIHhRdWVyeSwgVU5PX1FVRVJZX1RIUk9XICk7CiAgICAgICAgICAgIG1feEFsdGVyVmlldy0+YWx0ZXJDb21tYW5kKCBzVHJhbnNsYXRlZFN0bXQgKTsKICAgICAgICB9CiAgICAgICAgZWxzZQogICAgICAgIHsgICAvLyB3ZSdyZSBjcmVhdGluZyBhIHF1ZXJ5LCBvciBhICpuZXcqIHZpZXcKICAgICAgICAgICAgeFF1ZXJ5LT5zZXRQcm9wZXJ0eVZhbHVlKCBQUk9QRVJUWV9DT01NQU5ELCBtYWtlQW55KCBzVHJhbnNsYXRlZFN0bXQgKSApOwoKICAgICAgICAgICAgaWYgKCBlZGl0aW5nVmlldygpICkKICAgICAgICAgICAgewoJCQkgICAgeFF1ZXJ5LT5zZXRQcm9wZXJ0eVZhbHVlKCBQUk9QRVJUWV9DQVRBTE9HTkFNRSwgbWFrZUFueSggbV9zVXBkYXRlQ2F0YWxvZ05hbWUgKSApOwoJCQkgICAgeFF1ZXJ5LT5zZXRQcm9wZXJ0eVZhbHVlKCBQUk9QRVJUWV9TQ0hFTUFOQU1FLCBtYWtlQW55KCBtX3NVcGRhdGVTY2hlbWFOYW1lICkgKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgaWYgKCBlZGl0aW5nUXVlcnkoKSApCgkJCXsKCQkJCXhRdWVyeS0+c2V0UHJvcGVydHlWYWx1ZSggUFJPUEVSVFlfVVBEQVRFX1RBQkxFTkFNRSwgbWFrZUFueSggbV9zVXBkYXRlVGFibGVOYW1lICkgKTsKCQkJCXhRdWVyeS0+c2V0UHJvcGVydHlWYWx1ZSggUFJPUEVSVFlfRVNDQVBFX1BST0NFU1NJTkcsOjpjcHB1Ojpib29sMmFueSggbV9iRXNjYXBlUHJvY2Vzc2luZyApICk7CgoJCQkJeFF1ZXJ5LT5zZXRQcm9wZXJ0eVZhbHVlKCBQUk9QRVJUWV9MQVlPVVRJTkZPUk1BVElPTiwgZ2V0Vmlld0RhdGEoKSApOwoJCQl9CiAgICAgICAgfQoKCQlpZiAoIGJOZXcgKQoJCXsKCQkJUmVmZXJlbmNlPCBYQXBwZW5kID4geEFwcGVuZCggeEVsZW1lbnRzLCBVTk9fUVVFUlkgKTsKCQkJaWYgKCB4QXBwZW5kLmlzKCkgKQoJCQl7CgkJCQl4QXBwZW5kLT5hcHBlbmRCeURlc2NyaXB0b3IoIHhRdWVyeSApOwoJCQl9CgkJCWVsc2UKCQkJewoJCQkJUmVmZXJlbmNlPCBYTmFtZUNvbnRhaW5lciA+IHhDb250KCB4RWxlbWVudHMsIFVOT19RVUVSWSApOwoJCQkJaWYgKCB4Q29udC5pcygpICkKCQkJCQl4Q29udC0+aW5zZXJ0QnlOYW1lKCBtX3NOYW1lLCBtYWtlQW55KCB4UXVlcnkgKSApOwoJCQl9CgoJCQlpZiAoIGVkaXRpbmdWaWV3KCkgKQoJCQl7CgkJCQlSZWZlcmVuY2U8IFhQcm9wZXJ0eVNldCA+IHhWaWV3UHJvcHM7CgkJCQlpZiAoIHhFbGVtZW50cy0+aGFzQnlOYW1lKCBtX3NOYW1lICkgKQoJCQkJCXhWaWV3UHJvcHMuc2V0KCB4RWxlbWVudHMtPmdldEJ5TmFtZSggbV9zTmFtZSApLCBVTk9fUVVFUlkgKTsKCgkJCQlpZiAoICF4Vmlld1Byb3BzLmlzKCkgKSAvLyBjb3JyZWN0IG5hbWUgYW5kIHRyeSBhZ2FpbgoJCQkJCW1fc05hbWUgPSA6OmRidG9vbHM6OmNvbXBvc2VUYWJsZU5hbWUoIGdldE1ldGFEYXRhKCksIHhRdWVyeSwgOjpkYnRvb2xzOjplSW5EYXRhTWFuaXB1bGF0aW9uLCBmYWxzZSwgZmFsc2UsIGZhbHNlICk7CgogICAgICAgICAgICAgICAgT1NMX0VOU1VSRSggeEVsZW1lbnRzLT5oYXNCeU5hbWUoIG1fc05hbWUgKSwgIk9RdWVyeUNvbnRyb2xsZXI6OmRvU2F2ZUFzRG9jOiBuZXdseSBjcmVhZWQgdmlldyBkb2VzIG5vdCBleGlzdCEiICk7CgogICAgICAgICAgICAgICAgaWYgKCB4RWxlbWVudHMtPmhhc0J5TmFtZSggbV9zTmFtZSApICkKICAgICAgICAgICAgICAgICAgICBtX3hBbHRlclZpZXcuc2V0KCB4RWxlbWVudHMtPmdldEJ5TmFtZSggbV9zTmFtZSApLCBVTk9fUVVFUlkgKTsKCiAgICAgICAgICAgICAgICAvLyBub3cgY2hlY2sgaWYgb3VyIGRhdGFzb3VyY2UgaGFzIHNldCBhIHRhYmxlZmlsdGVyIGFuZCBpZiBzbywgYXBwZW5kIHRoZSBuZXcgdGFibGUgbmFtZSB0byBpdAoJCQkJOjpkYmF1aTo6YXBwZW5kVG9GaWx0ZXIoIGdldENvbm5lY3Rpb24oKSwgbV9zTmFtZSwgZ2V0T1JCKCksIGdldFZpZXcoKSApOwoJCQl9IC8vIGlmICggZWRpdGluZ1ZpZXcoKSApCiAgICAgICAgICAgIFJlZmVyZW5jZTwgWFRpdGxlQ2hhbmdlTGlzdGVuZXI+IHhFdmVudExpc3RlbmVyKGltcGxfZ2V0VGl0bGVIZWxwZXJfdGhyb3coKSxVTk9fUVVFUlkpOwogICAgICAgICAgICBpZiAoIHhFdmVudExpc3RlbmVyLmlzKCkgKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBUaXRsZUNoYW5nZWRFdmVudCBhRXZlbnQ7CiAgICAgICAgICAgICAgICB4RXZlbnRMaXN0ZW5lci0+dGl0bGVDaGFuZ2VkKGFFdmVudCk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgcmVsZWFzZU51bWJlckZvckNvbXBvbmVudCgpOwoJCX0KCgkJc2V0TW9kaWZpZWQoIHNhbF9GYWxzZSApOwogICAgICAgIGJTdWNjZXNzID0gdHJ1ZTsKICAgICAgICAKCX0KCWNhdGNoKCBjb25zdCBTUUxFeGNlcHRpb24mICkKCXsKICAgICAgICBpZiAoICFiTmV3ICkKICAgICAgICAgICAgbV9zTmFtZSA9IHNPcmlnaW5hbE5hbWU7CiAgICAgICAgYUluZm8gPSBTUUxFeGNlcHRpb25JbmZvKCA6OmNwcHU6OmdldENhdWdodEV4Y2VwdGlvbigpICk7Cgl9CgljYXRjaChFeGNlcHRpb24mKQoJewogICAgICAgIGlmICggIWJOZXcgKQogICAgICAgICAgICBtX3NOYW1lID0gc09yaWdpbmFsTmFtZTsKICAgICAgICBEQkdfVU5IQU5ETEVEX0VYQ0VQVElPTigpOwoJfQoKCXNob3dFcnJvciggYUluZm8gKTsKCiAgICAvLyB1cGRhdGUgdGhlIHRpdGxlIG9mIG91ciB3aW5kb3cKCS8vdXBkYXRlVGl0bGUoKTsKCiAgICAvLyBpZiB3ZSBzdWNjZXNzZnVsbHkgc2F2ZWQgYSB2aWV3IHdlIHdlcmUgY3JlYXRpbmcsIHRoZW4gY2xvc2UgdGhlIGRlc2lnbmVyCiAgICBpZiAoIGJTdWNjZXNzICYmIGVkaXRpbmdWaWV3KCkgJiYgIW1feEFsdGVyVmlldy5pcygpICkKICAgIHsKCQljbG9zZVRhc2soKTsKICAgIH0KCiAgICBpZiAoIGJTdWNjZXNzICYmIGVkaXRpbmdWaWV3KCkgKQogICAgICAgIEludmFsaWRhdGVGZWF0dXJlKCBJRF9CUk9XU0VSX0VESVRET0MgKTsKCiAgICByZXR1cm4gYlN1Y2Nlc3M7Cn0KLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KOjpydGw6Ok9VU3RyaW5nIE9RdWVyeUNvbnRyb2xsZXI6OnRyYW5zbGF0ZVN0YXRlbWVudCggYm9vbCBfYkZpcmVTdGF0ZW1lbnRDaGFuZ2UgKQp7CgkvLyBub3cgc2V0IHRoZSBwcm9wZXJ0aWVzCglzZXRTdGF0ZW1lbnRfZmlyZUV2ZW50KCBnZXRDb250YWluZXIoKS0+Z2V0U3RhdGVtZW50KCksIF9iRmlyZVN0YXRlbWVudENoYW5nZSApOwoJOjpydGw6Ok9VU3RyaW5nIHNUcmFuc2xhdGVkU3RtdDsKCWlmKG1fc1N0YXRlbWVudC5nZXRMZW5ndGgoKSAmJiBtX3hDb21wb3Nlci5pcygpICYmIG1fYkVzY2FwZVByb2Nlc3NpbmcpCgl7CgkJdHJ5CgkJewoJCQk6OnJ0bDo6T1VTdHJpbmcgYUVycm9yTXNnOwoKCQkJOjpjb25uZWN0aXZpdHk6Ok9TUUxQYXJzZU5vZGUqIHBOb2RlID0gbV9hU3FsUGFyc2VyLnBhcnNlVHJlZSggYUVycm9yTXNnLCBtX3NTdGF0ZW1lbnQsIG1fYkdyYXBoaWNhbERlc2lnbiApOwoJCQlpZihwTm9kZSkKCQkJewogICAgICAgICAgICAgICAgcE5vZGUtPnBhcnNlTm9kZVRvU3RyKCBzVHJhbnNsYXRlZFN0bXQsIGdldENvbm5lY3Rpb24oKSApOwoJCQkJZGVsZXRlIHBOb2RlOwoJCQl9CgogICAgICAgICAgICBtX3hDb21wb3Nlci0+c2V0UXVlcnkoc1RyYW5zbGF0ZWRTdG10KTsKCQkJc1RyYW5zbGF0ZWRTdG10ID0gbV94Q29tcG9zZXItPmdldENvbXBvc2VkUXVlcnkoKTsKCQl9CgkJY2F0Y2goU1FMRXhjZXB0aW9uJiBlKQoJCXsKCQkJOjpkYnRvb2xzOjpTUUxFeGNlcHRpb25JbmZvIGFJbmZvKGUpOwoJCQlzaG93RXJyb3IoYUluZm8pOwoJCQkvLyBhbiBlcnJvciBvY2N1cmVkIHNvIHdlIGNsZWFyIHRoZSBzdGF0ZW1lbnQKCQkJc1RyYW5zbGF0ZWRTdG10ID0gOjpydGw6Ok9VU3RyaW5nKCk7CgkJfQoJfQoJZWxzZSBpZighbV9zU3RhdGVtZW50LmdldExlbmd0aCgpKQoJewogICAgICAgIE1vZHVsZVJlcyBhTW9kdWxlUmVzKFNUUl9RUllfTk9TRUxFQ1QpOwogICAgICAgIFN0cmluZyBzVG1wU3RyKGFNb2R1bGVSZXMpOwoJCTo6cnRsOjpPVVN0cmluZyBzRXJyb3Ioc1RtcFN0cik7CgkJc2hvd0Vycm9yKFNRTEV4Y2VwdGlvbihzRXJyb3IsTlVMTCw6OnJ0bDo6T1VTdHJpbmcoUlRMX0NPTlNUQVNDSUlfVVNUUklOR1BBUkFNKCJTMTAwMCIpICksMTAwMCxBbnkoKSkpOwoJfQoJZWxzZQoJCXNUcmFuc2xhdGVkU3RtdCA9IG1fc1N0YXRlbWVudDsKCglyZXR1cm4gc1RyYW5zbGF0ZWRTdG10Owp9Ci8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCnNob3J0IE9RdWVyeUNvbnRyb2xsZXI6OnNhdmVNb2RpZmllZCgpCnsKCXZvczo6T0d1YXJkIGFTb2xhckd1YXJkKCBBcHBsaWNhdGlvbjo6R2V0U29sYXJNdXRleCgpICk7Cgk6Om9zbDo6TXV0ZXhHdWFyZCBhR3VhcmQoIGdldE11dGV4KCkgKTsKCXNob3J0IG5SZXQgPSBSRVRfWUVTOwogICAgaWYgKCAhaXNDb25uZWN0ZWQoKSB8fCAhaXNNb2RpZmllZCgpICkKICAgICAgICByZXR1cm4gblJldDsKCglpZiAgKCAgIW1fYkdyYXBoaWNhbERlc2lnbgogICAgICAgIHx8ICggICFtX3ZUYWJsZUZpZWxkRGVzYy5lbXB0eSgpCiAgICAgICAgICAgJiYgIW1fdlRhYmxlRGF0YS5lbXB0eSgpCiAgICAgICAgICAgKQogICAgICAgICkKCXsKICAgICAgICBTdHJpbmcgc01lc3NhZ2VUZXh0KCBsY2xfZ2V0T2JqZWN0UmVzb3VyY2VTdHJpbmcoIFNUUl9RVUVSWV9TQVZFTU9ESUZJRUQsIG1fbkNvbW1hbmRUeXBlICkgKTsKICAgICAgICBRdWVyeUJveCBhUXJ5KCBnZXRWaWV3KCksIFdCX1lFU19OT19DQU5DRUwgfCBXQl9ERUZfWUVTLCBzTWVzc2FnZVRleHQgKTsKCiAgICAgICAgblJldCA9IGFRcnkuRXhlY3V0ZSgpOwoJCWlmICAoICAgKCBuUmV0ID09IFJFVF9ZRVMgKQogICAgICAgICAgICAmJiAgIWRvU2F2ZUFzRG9jKCBzYWxfRmFsc2UgKQogICAgICAgICAgICApCiAgICAgICAgewogICAgICAgICAgICBuUmV0ID0gUkVUX0NBTkNFTDsKCQl9Cgl9CglyZXR1cm4gblJldDsKfQovLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQp2b2lkIE9RdWVyeUNvbnRyb2xsZXI6OmltcGxfcmVzZXQoIGNvbnN0IGJvb2wgaV9iRm9yY2VDdXJyZW50Q29udHJvbGxlclNldHRpbmdzICkKewogICAgYm9vbCBiVmFsaWQgPSBmYWxzZTsKCiAgICBTZXF1ZW5jZTwgUHJvcGVydHlWYWx1ZSA+IGFMYXlvdXRJbmZvcm1hdGlvbjsKCS8vIGdldCBjb21tYW5kIGZyb20gdGhlIHF1ZXJ5IGlmIGEgcXVlcnkgbmFtZSB3YXMgc3VwcGxpZWQKICAgIGlmICggIWlfYkZvcmNlQ3VycmVudENvbnRyb2xsZXJTZXR0aW5ncyAmJiAhZWRpdGluZ0NvbW1hbmQoKSApCiAgICB7CgkgICAgaWYgKCBtX3NOYW1lLmdldExlbmd0aCgpICkKCSAgICB7CiAgICAgICAgICAgIFJlZmVyZW5jZTwgWE5hbWVBY2Nlc3MgPiB4UXVlcmllcyA9IGdldE9iamVjdENvbnRhaW5lcigpOwoJCSAgICBpZiAoIHhRdWVyaWVzLmlzKCkgKQoJCSAgICB7CiAgICAgICAgICAgICAgICBSZWZlcmVuY2U8IFhQcm9wZXJ0eVNldCA+IHhQcm9wOwoJCQkgICAgaWYoIHhRdWVyaWVzLT5oYXNCeU5hbWUoIG1fc05hbWUgKSAmJiAoIHhRdWVyaWVzLT5nZXRCeU5hbWUoIG1fc05hbWUgKSA+Pj0geFByb3AgKSAmJiB4UHJvcC5pcygpICkKCQkJICAgIHsKICAgICAgICAgICAgICAgICAgICA6OnJ0bDo6T1VTdHJpbmcgc05ld1N0YXRlbWVudDsKCQkJCSAgICB4UHJvcC0+Z2V0UHJvcGVydHlWYWx1ZSggUFJPUEVSVFlfQ09NTUFORCApID4+PSBzTmV3U3RhdGVtZW50OwogICAgICAgICAgICAgICAgICAgIHNldFN0YXRlbWVudF9maXJlRXZlbnQoIHNOZXdTdGF0ZW1lbnQgKTsKCiAgICAgICAgICAgICAgICAgICAgc2FsX0Jvb2wgYk5ld0VzY2FwZVByb2Nlc3NpbmcoIHNhbF9UcnVlICk7CiAgICAgICAgICAgICAgICAgICAgaWYgKCBlZGl0aW5nUXVlcnkoKSApCiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICB4UHJvcC0+Z2V0UHJvcGVydHlWYWx1ZSggUFJPUEVSVFlfRVNDQVBFX1BST0NFU1NJTkcgKSA+Pj0gYk5ld0VzY2FwZVByb2Nlc3Npbmc7CiAgICAgICAgICAgICAgICAgICAgICAgIHNldEVzY2FwZVByb2Nlc3NpbmdfZmlyZUV2ZW50KCBiTmV3RXNjYXBlUHJvY2Vzc2luZyApOwogICAgICAgICAgICAgICAgICAgIH0KCgkJCQkgICAgbV9iR3JhcGhpY2FsRGVzaWduID0gbV9iR3JhcGhpY2FsRGVzaWduICYmIG1fYkVzY2FwZVByb2Nlc3Npbmc7CiAgICAgICAgICAgICAgICAgICAgYlZhbGlkID0gdHJ1ZTsKCiAgICAgICAgICAgICAgICAgICAgdHJ5CiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICBpZiAoIGVkaXRpbmdRdWVyeSgpICkKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHhQcm9wLT5nZXRQcm9wZXJ0eVZhbHVlKCBQUk9QRVJUWV9MQVlPVVRJTkZPUk1BVElPTiApID4+PSBhTGF5b3V0SW5mb3JtYXRpb247CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGNhdGNoKCBjb25zdCBFeGNlcHRpb24mICkKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgCU9TTF9FTlNVUkUoIHNhbF9GYWxzZSwgIk9RdWVyeUNvbnRyb2xsZXI6OmltcGxfcmVzZXQ6IGNvdWxkIG5vdCByZXRyaWV2ZSB0aGUgbGF5b3V0IGluZm9ybWF0aW9uIGZyb20gdGhlIHF1ZXJ5ISIgKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9CiAgICBlbHNlCiAgICB7CiAgICAgICAgYlZhbGlkID0gdHJ1ZTsKICAgICAgICAvLyBhc3N1bWUgdGhhdCB3ZSBnb3QgYWxsIG5lY2Vzc2FyeSBpbmZvcm1hdGlvbiBkdXJpbmcgaW5pdGlhbGl6YXRpb24KICAgIH0KCglpZiAoIGJWYWxpZCApCgl7CiAgICAgICAgLy8gbG9hZCB0aGUgbGF5b3V0SW5mb3JtYXRpb24KICAgICAgICBpZiAoIGFMYXlvdXRJbmZvcm1hdGlvbi5nZXRMZW5ndGgoKSApCiAgICAgICAgewoJCSAgICB0cnkKCQkgICAgewoJCQkJbG9hZFZpZXdTZXR0aW5ncyggYUxheW91dEluZm9ybWF0aW9uICk7CgkJICAgIH0KCQkgICAgY2F0Y2goIGNvbnN0IEV4Y2VwdGlvbiYgKQoJCSAgICB7CiAgICAgICAgICAgICAgICBEQkdfVU5IQU5ETEVEX0VYQ0VQVElPTigpOwoJCSAgICB9CiAgICAgICAgfQoKICAgICAgICBpZiAoIG1fc1N0YXRlbWVudC5nZXRMZW5ndGgoKSApCiAgICAgICAgewogICAgICAgICAgICBzZXRRdWVyeUNvbXBvc2VyKCk7CgogICAgICAgICAgICBib29sIGJFcnJvciggZmFsc2UgKTsKCiAgICAgICAgICAgIGlmICggIW1fcFNxbEl0ZXJhdG9yICkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgYkVycm9yID0gdHJ1ZTsKICAgICAgICAgICAgfQoJCSAgICBlbHNlIGlmICggbV9iRXNjYXBlUHJvY2Vzc2luZyApCgkJICAgIHsKCQkJICAgIDo6cnRsOjpPVVN0cmluZyBhRXJyb3JNc2c7CiAgICAgICAgICAgICAgICA6OnN0ZDo6YXV0b19wdHI8IDo6Y29ubmVjdGl2aXR5OjpPU1FMUGFyc2VOb2RlID4gcE5vZGUoCiAgICAgICAgICAgICAgICAgICAgbV9hU3FsUGFyc2VyLnBhcnNlVHJlZSggYUVycm9yTXNnLCBtX3NTdGF0ZW1lbnQsIG1fYkdyYXBoaWNhbERlc2lnbiApICk7CgogICAgICAgICAgICAgICAgaWYgKCBwTm9kZS5nZXQoKSApCgkJCSAgICB7CgkJCQkgICAgZGVsZXRlIG1fcFNxbEl0ZXJhdG9yLT5nZXRQYXJzZVRyZWUoKTsKCQkJCSAgICBtX3BTcWxJdGVyYXRvci0+c2V0UGFyc2VUcmVlKCBwTm9kZS5yZWxlYXNlKCkgKTsKCQkJCSAgICBtX3BTcWxJdGVyYXRvci0+dHJhdmVyc2VBbGwoKTsKICAgICAgICAgICAgICAgICAgICBpZiAoIG1fcFNxbEl0ZXJhdG9yLT5oYXNFcnJvcnMoKSApCiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICBpZiAoICFpX2JGb3JjZUN1cnJlbnRDb250cm9sbGVyU2V0dGluZ3MgJiYgbV9iR3JhcGhpY2FsRGVzaWduICYmICFlZGl0aW5nVmlldygpICkKICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgaW1wbF9zaG93QXV0b1NRTFZpZXdFcnJvciggbWFrZUFueSggbV9wU3FsSXRlcmF0b3ItPmdldEVycm9ycygpICkgKTsKICAgICAgICAgICAgICAgICAgICAgICAgfQoJCQkJCSAgICBiRXJyb3IgPSB0cnVlOwoJCQkJICAgIH0KCQkJICAgIH0KCQkJICAgIGVsc2UKCQkJICAgIHsKICAgICAgICAgICAgICAgICAgICBpZiAoICFpX2JGb3JjZUN1cnJlbnRDb250cm9sbGVyU2V0dGluZ3MgJiYgIWVkaXRpbmdWaWV3KCkgKQogICAgICAgICAgICAgICAgICAgIHsKCQkJCSAgICAgICAgU3RyaW5nIGFUaXRsZShNb2R1bGVSZXMoU1RSX1NWVF9TUUxfU1lOVEFYX0VSUk9SKSk7CgkJCQkgICAgICAgIE9TUUxNZXNzYWdlQm94IGFEbGcoZ2V0VmlldygpLGFUaXRsZSxhRXJyb3JNc2cpOwoJCQkJICAgICAgICBhRGxnLkV4ZWN1dGUoKTsKICAgICAgICAgICAgICAgICAgICB9CgkJCQkgICAgYkVycm9yID0gdHJ1ZTsKCQkJICAgIH0KICAgICAgICAgICAgfQoKICAgICAgICAgICAgaWYgKCBiRXJyb3IgKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBtX2JHcmFwaGljYWxEZXNpZ24gPSBzYWxfRmFsc2U7CiAgICAgICAgICAgICAgICBpZiAoIGVkaXRpbmdWaWV3KCkgKQogICAgICAgICAgICAgICAgICAgIC8vIGlmIHdlJ3JlIGVkaXRpbmcgYSB2aWV3IHdob3NlIHN0YXRlbWVudCBjb3VsZCBub3QgYmUgcGFyc2VkLCBkZWZhdWx0IHRvICJubyBlc2NhcGUgcHJvY2Vzc2luZyIKICAgICAgICAgICAgICAgICAgICBzZXRFc2NhcGVQcm9jZXNzaW5nX2ZpcmVFdmVudCggc2FsX0ZhbHNlICk7CiAgICAgICAgICAgIH0KICAgICAgICB9Cgl9CgoJaWYoIW1fcFNxbEl0ZXJhdG9yKQoJCXNldFF1ZXJ5Q29tcG9zZXIoKTsKCU9TTF9FTlNVUkUobV9wU3FsSXRlcmF0b3IsIk5vIFNRTEl0ZXJhdG9yIHNldCEiKTsKCglnZXRDb250YWluZXIoKS0+c2V0Tm9uZVZpc2JsZVJvdyhtX25WaXNpYmxlUm93cyk7Cn0KCi8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCnZvaWQgT1F1ZXJ5Q29udHJvbGxlcjo6cmVzZXQoKQp7CglpbXBsX3Jlc2V0KCk7CglnZXRDb250YWluZXIoKS0+cmVzZXQoIE5VTEwgKTsKCUNsZWFyVW5kb01hbmFnZXIoKTsKfQoKLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0Kdm9pZCBPUXVlcnlDb250cm9sbGVyOjpzZXRTdGF0ZW1lbnRfZmlyZUV2ZW50KCBjb25zdCA6OnJ0bDo6T1VTdHJpbmcmIF9yTmV3U3RhdGVtZW50LCBib29sIF9iRmlyZVN0YXRlbWVudENoYW5nZSApCnsKICAgIEFueSBhT2xkVmFsdWUgPSBtYWtlQW55KCBtX3NTdGF0ZW1lbnQgKTsKICAgIG1fc1N0YXRlbWVudCA9IF9yTmV3U3RhdGVtZW50OwogICAgQW55IGFOZXdWYWx1ZSA9IG1ha2VBbnkoIG1fc1N0YXRlbWVudCApOwoKICAgIHNhbF9JbnQzMiBuSGFuZGxlID0gUFJPUEVSVFlfSURfQUNUSVZFQ09NTUFORDsKICAgIGlmICggX2JGaXJlU3RhdGVtZW50Q2hhbmdlICkKICAgICAgICBmaXJlKCAmbkhhbmRsZSwgJmFOZXdWYWx1ZSwgJmFPbGRWYWx1ZSwgMSwgc2FsX0ZhbHNlICk7Cn0KCi8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCnZvaWQgT1F1ZXJ5Q29udHJvbGxlcjo6c2V0RXNjYXBlUHJvY2Vzc2luZ19maXJlRXZlbnQoIGNvbnN0IHNhbF9Cb29sIF9iRXNjYXBlUHJvY2Vzc2luZyApCnsKICAgIGlmICggX2JFc2NhcGVQcm9jZXNzaW5nID09IG1fYkVzY2FwZVByb2Nlc3NpbmcgKQogICAgICAgIHJldHVybjsKCiAgICBBbnkgYU9sZFZhbHVlID0gbWFrZUFueSggbV9iRXNjYXBlUHJvY2Vzc2luZyApOwogICAgbV9iRXNjYXBlUHJvY2Vzc2luZyA9IF9iRXNjYXBlUHJvY2Vzc2luZzsKICAgIEFueSBhTmV3VmFsdWUgPSBtYWtlQW55KCBtX2JFc2NhcGVQcm9jZXNzaW5nICk7CgogICAgc2FsX0ludDMyIG5IYW5kbGUgPSBQUk9QRVJUWV9JRF9FU0NBUEVfUFJPQ0VTU0lORzsKICAgIGZpcmUoICZuSGFuZGxlLCAmYU5ld1ZhbHVlLCAmYU9sZFZhbHVlLCAxLCBzYWxfRmFsc2UgKTsKfQoKLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KSU1QTF9MSU5LKCBPUXVlcnlDb250cm9sbGVyLCBPbkV4ZWN1dGVBZGRUYWJsZSwgdm9pZCosIC8qcE5vdEludGVyZXN0ZWRJbiovICkKewogICAgRXhlY3V0ZSggSURfQlJPV1NFUl9BRERUQUJMRSxTZXF1ZW5jZTxQcm9wZXJ0eVZhbHVlPigpICk7CiAgICByZXR1cm4gMEw7Cn0KCi8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCmJvb2wgT1F1ZXJ5Q29udHJvbGxlcjo6YWxsb3dWaWV3cygpIGNvbnN0CnsKICAgIHJldHVybiB0cnVlOwp9CgovLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQpib29sIE9RdWVyeUNvbnRyb2xsZXI6OmFsbG93UXVlcmllcygpIGNvbnN0CnsKICAgIERCR19BU1NFUlQoIGdldFNkYk1ldGFEYXRhKCkuaXNDb25uZWN0ZWQoKSwgIk9RdWVyeUNvbnRyb2xsZXI6OmFsbG93UXVlcmllczogaWxsZWdhbCBjYWxsISIgKTsKICAgIGlmICggIWdldFNkYk1ldGFEYXRhKCkuc3VwcG9ydHNTdWJxdWVyaWVzSW5Gcm9tKCkgKQogICAgICAgIHJldHVybiBmYWxzZTsKCiAgICBjb25zdCBOYW1lZFZhbHVlQ29sbGVjdGlvbiYgckFyZ3VtZW50cyggZ2V0SW5pdFBhcmFtcygpICk7CiAgICBzYWxfSW50MzIgbkNvbW1hbmRUeXBlID0gckFyZ3VtZW50cy5nZXRPckRlZmF1bHQoICg6OnJ0bDo6T1VTdHJpbmcpUFJPUEVSVFlfQ09NTUFORF9UWVBFLCAoc2FsX0ludDMyKUNvbW1hbmRUeXBlOjpRVUVSWSApOwogICAgc2FsX0Jvb2wgYkNyZWF0aW5nVmlldyA9ICggbkNvbW1hbmRUeXBlID09IENvbW1hbmRUeXBlOjpUQUJMRSApOwogICAgcmV0dXJuICFiQ3JlYXRpbmdWaWV3Owp9CgovLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQpBbnkgU0FMX0NBTEwgT1F1ZXJ5Q29udHJvbGxlcjo6Z2V0Vmlld0RhdGEoKSB0aHJvdyggUnVudGltZUV4Y2VwdGlvbiApCnsKCTo6b3NsOjpNdXRleEd1YXJkIGFHdWFyZCggZ2V0TXV0ZXgoKSApOwoKICAgIGdldENvbnRhaW5lcigpLT5TYXZlVUlDb25maWcoKTsKCiAgICA6OmNvbXBoZWxwZXI6Ok5hbWVkVmFsdWVDb2xsZWN0aW9uIGFWaWV3U2V0dGluZ3M7CglzYXZlVmlld1NldHRpbmdzKCBhVmlld1NldHRpbmdzLCBmYWxzZSApOwoKCXJldHVybiBtYWtlQW55KCBhVmlld1NldHRpbmdzLmdldFByb3BlcnR5VmFsdWVzKCkgKTsKfQovLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQp2b2lkIFNBTF9DQUxMIE9RdWVyeUNvbnRyb2xsZXI6OnJlc3RvcmVWaWV3RGF0YShjb25zdCBBbnkmIC8qRGF0YSovKSB0aHJvdyggUnVudGltZUV4Y2VwdGlvbiApCnsKICAgIC8vIFRPRE8KfQoKLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KfSAvLyBuYW1lc3BhY2UgZGJhdWkKLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCg==