LyoKICogKGMpIENvcHlyaWdodCAxOTkzLCBTaWxpY29uIEdyYXBoaWNzLCBJbmMuCiAqIENvcHlyaWdodCCpIDIwMTIgTGluYXJvIExpbWl0ZWQKICoKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgdGhlIGdsbWFyazIgT3BlbkdMIChFUykgMi4wIGJlbmNobWFyay4KICoKICogZ2xtYXJrMiBpcyBmcmVlIHNvZnR3YXJlOiB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5IGl0IHVuZGVyIHRoZQogKiB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgYXMgcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlCiAqIEZvdW5kYXRpb24sIGVpdGhlciB2ZXJzaW9uIDMgb2YgdGhlIExpY2Vuc2UsIG9yIChhdCB5b3VyIG9wdGlvbikgYW55IGxhdGVyCiAqIHZlcnNpb24uCiAqCiAqIGdsbWFyazIgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQgQU5ZCiAqIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MKICogRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBmb3IgbW9yZQogKiBkZXRhaWxzLgogKgogKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBhbG9uZyB3aXRoCiAqIGdsbWFyazIuICBJZiBub3QsIHNlZSA8aHR0cDovL3d3dy5nbnUub3JnL2xpY2Vuc2VzLz4uCiAqCiAqIEF1dGhvcnM6CiAqICBKZXNzZSBCYXJrZXIKICovCiNpbmNsdWRlICJzY2VuZS5oIgojaW5jbHVkZSAic3RhY2suaCIKI2luY2x1ZGUgInNwbGluZXMuaCIKI2luY2x1ZGUgInRhYmxlLmgiCiNpbmNsdWRlICJsb2dvLmgiCiNpbmNsdWRlICJsYW1wLmgiCiNpbmNsdWRlICJ1dGlsLmgiCiNpbmNsdWRlICJsb2cuaCIKI2luY2x1ZGUgPHN5cy90aW1lLmg+Cgp1c2luZyBMaWJNYXRyaXg6OlN0YWNrNDsKdXNpbmcgTGliTWF0cml4OjptYXQ0Owp1c2luZyBMaWJNYXRyaXg6OnZlYzM7CnVzaW5nIExpYk1hdHJpeDo6dmVjNDsKdXNpbmcgTGliTWF0cml4Ojp1dmVjMzsKdXNpbmcgc3RkOjpzdHJpbmc7CnVzaW5nIHN0ZDo6bWFwOwoKY2xhc3MgU2NlbmVJZGVhc1ByaXZhdGUKewpwdWJsaWM6CiAgICBTY2VuZUlkZWFzUHJpdmF0ZSgpIDoKICAgICAgICB2YWxpZF8oZmFsc2UpLAogICAgICAgIGN1cnJlbnRTcGVlZF8oMS4wKSwgLy8gUmVhbCB0aW1lLgogICAgICAgIGN1cnJlbnRUaW1lXyhTVEFSVF9USU1FXyksCiAgICAgICAgdGltZU9mZnNldF8oU1RBUlRfVElNRV8pCiAgICB7CiAgICAgICAgc3RhcnRUaW1lXy50dl9zZWMgPSAwOwogICAgICAgIHN0YXJ0VGltZV8udHZfdXNlYyA9IDA7IAogICAgfQogICAgflNjZW5lSWRlYXNQcml2YXRlKCkKICAgIHsKICAgIH0KICAgIHZvaWQgaW5pdGlhbGl6ZShtYXA8c3RyaW5nLCBTY2VuZTo6T3B0aW9uPiYgb3B0aW9ucyk7CiAgICB2b2lkIHJlc2V0X3RpbWUoKTsKICAgIHZvaWQgdXBkYXRlX3RpbWUoKTsKICAgIHZvaWQgdXBkYXRlX3Byb2plY3Rpb24oY29uc3QgbWF0NCYgcHJvaik7CiAgICB2b2lkIGRyYXcoKTsKICAgIGJvb2wgdmFsaWQoKSB7IHJldHVybiB2YWxpZF87IH0KCnByaXZhdGU6CiAgICB2b2lkIHBvc3RJZGxlKCk7CiAgICB2b2lkIGluaXRMaWdodHMoKTsKICAgIGJvb2wgdmFsaWRfOwogICAgU3RhY2s0IHByb2plY3Rpb25fOwogICAgU3RhY2s0IG1vZGVsdmlld187CiAgICBmbG9hdCBjdXJyZW50U3BlZWRfOwogICAgZmxvYXQgY3VycmVudFRpbWVfOwogICAgZmxvYXQgdGltZU9mZnNldF87CiAgICBzdHJ1Y3QgdGltZXZhbCBzdGFydFRpbWVfOwogICAgc3RhdGljIGNvbnN0IGZsb2F0IENZQ0xFX1RJTUVfOwogICAgc3RhdGljIGNvbnN0IGZsb2F0IFRJTUVfOwogICAgc3RhdGljIGNvbnN0IGZsb2F0IFNUQVJUX1RJTUVfOwogICAgLy8gVGFibGUKICAgIFRhYmxlIHRhYmxlXzsKICAgIC8vIExvZ28KICAgIFNHSUxvZ28gbG9nb187CiAgICAvLyBMYW1wCiAgICBMYW1wIGxhbXBfOwogICAgLy8gTGlnaHQgY29uc3RhbnRzCiAgICBzdGF0aWMgY29uc3QgdmVjNCBsaWdodDBfcG9zaXRpb25fOwogICAgc3RhdGljIGNvbnN0IHZlYzQgbGlnaHQxX3Bvc2l0aW9uXzsKICAgIHN0YXRpYyBjb25zdCB2ZWM0IGxpZ2h0Ml9wb3NpdGlvbl87CiAgICAvLyBPYmplY3QgY29uc3RhbnRzCiAgICBWaWV3RnJvbVNwbGluZSB2aWV3RnJvbVNwbGluZV87CiAgICBWaWV3VG9TcGxpbmUgdmlld1RvU3BsaW5lXzsKICAgIExpZ2h0UG9zaXRpb25TcGxpbmUgbGlnaHRQb3NTcGxpbmVfOwogICAgTG9nb1Bvc2l0aW9uU3BsaW5lIGxvZ29Qb3NTcGxpbmVfOwogICAgTG9nb1JvdGF0aW9uU3BsaW5lIGxvZ29Sb3RTcGxpbmVfOwogICAgdmVjMyB2aWV3RnJvbV87CiAgICB2ZWMzIHZpZXdUb187CiAgICB2ZWMzIGxpZ2h0UG9zXzsKICAgIHZlYzMgbG9nb1Bvc187CiAgICB2ZWMzIGxvZ29Sb3RfOwogICAgdmVjNCBsaWdodFBvc2l0aW9uc19bM107Cn07Cgpjb25zdCBmbG9hdCBTY2VuZUlkZWFzUHJpdmF0ZTo6VElNRV8oMTUuMCk7CmNvbnN0IGZsb2F0IFNjZW5lSWRlYXNQcml2YXRlOjpDWUNMRV9USU1FXyhUSU1FXyAqIDEuMCAtIDMuMCk7CmNvbnN0IGZsb2F0IFNjZW5lSWRlYXNQcml2YXRlOjpTVEFSVF9USU1FXygwLjYpOwpjb25zdCB2ZWM0IFNjZW5lSWRlYXNQcml2YXRlOjpsaWdodDBfcG9zaXRpb25fKDAuMCwgMS4wLCAwLjAsIDAuMCk7CmNvbnN0IHZlYzQgU2NlbmVJZGVhc1ByaXZhdGU6OmxpZ2h0MV9wb3NpdGlvbl8oLTEuMCwgMC4wLCAwLjAsIDAuMCk7CmNvbnN0IHZlYzQgU2NlbmVJZGVhc1ByaXZhdGU6OmxpZ2h0Ml9wb3NpdGlvbl8oMC4wLCAtMS4wLCAwLjAsIDAuMCk7Cgp2b2lkClNjZW5lSWRlYXNQcml2YXRlOjppbml0TGlnaHRzKCkKewogICAgY29uc3QgbWF0NCYgY3VyTVYobW9kZWx2aWV3Xy5nZXRDdXJyZW50KCkpOwogICAgbGlnaHRQb3NpdGlvbnNfWzBdID0gY3VyTVYgKiBsaWdodDBfcG9zaXRpb25fOwogICAgbGlnaHRQb3NpdGlvbnNfWzFdID0gY3VyTVYgKiBsaWdodDFfcG9zaXRpb25fOwogICAgbGlnaHRQb3NpdGlvbnNfWzJdID0gY3VyTVYgKiBsaWdodDJfcG9zaXRpb25fOwp9Cgp2b2lkClNjZW5lSWRlYXNQcml2YXRlOjppbml0aWFsaXplKG1hcDxzdHJpbmcsIFNjZW5lOjpPcHRpb24+JiBvcHRpb25zKQp7CiAgICAvLyBJbml0aWFsaXplIHRoZSBwb3NpdGlvbnMgZm9yIHRoZSBsaWdodHMgd2UnbGwgdXNlLgogICAgaW5pdExpZ2h0cygpOwoKICAgIC8vIFRlbGwgdGhlIG9iamVjdHMgaW4gdGhlIHNjZW5lIHRvIGluaXRpYWxpemUgdGhlbXNlbHZlcy4KICAgIHRhYmxlXy5pbml0KCk7CiAgICBpZiAoIXRhYmxlXy52YWxpZCgpKQogICAgewogICAgICAgIExvZzo6ZGVidWcoIlNjZW5lSWRlYXM6IHRhYmxlIG9iamVjdCBub3QgcHJvcGVybHkgaW5pdGlhbGl6ZWQhXG4iKTsKICAgICAgICByZXR1cm47CiAgICB9CiAgICBsb2dvXy5pbml0KCk7CiAgICBpZiAoIWxvZ29fLnZhbGlkKCkpCiAgICB7CiAgICAgICAgTG9nOjpkZWJ1ZygiU2NlbmVJZGVhczogbG9nbyBvYmplY3Qgbm90IHByb3Blcmx5IGluaXRpYWxpemVkIVxuIik7CiAgICAgICAgcmV0dXJuOwogICAgfQogICAgbGFtcF8uaW5pdCgpOwogICAgaWYgKCFsYW1wXy52YWxpZCgpKQogICAgewogICAgICAgIExvZzo6ZGVidWcoIlNjZW5lSWRlYXM6IGxhbXAgb2JqZWN0IG5vdCBwcm9wZXJseSBpbml0aWFsaXplZCFcbiIpOwogICAgICAgIHJldHVybjsKICAgIH0KCiAgICByZXNldF90aW1lKCk7CgogICAgLy8gSWYgdGhlIG9wdGlvbiBzdHJpbmcgdGVsbHMgdXMgdGhlIHVzZXIgd2FudHMgdGhlIHNwZWVkIHRvIGJlIGEgZnVuY3Rpb24KICAgIC8vIG9mIHRoZSBzY2VuZSBkdXJhdGlvbiwgZG8gaXQuICBPdGhlcndpc2UsIHRha2UgdGhlIHZhbHVlIGV4cGxpY2l0bHkuCiAgICBzdGF0aWMgY29uc3Qgc3RyaW5nIGR1cmF0aW9uTGFiZWwoImR1cmF0aW9uIik7CiAgICBzdGF0aWMgY29uc3Qgc3RyaW5nIHNwZWVkTGFiZWwoInNwZWVkIik7CiAgICBpZiAob3B0aW9uc1tzcGVlZExhYmVsXS52YWx1ZSA9PSBkdXJhdGlvbkxhYmVsKQogICAgewogICAgICAgIGZsb2F0IGR1cmF0aW9uID0gVXRpbDo6ZnJvbVN0cmluZzxmbG9hdD4ob3B0aW9uc1tkdXJhdGlvbkxhYmVsXS52YWx1ZSk7CiAgICAgICAgY3VycmVudFNwZWVkXyA9IChDWUNMRV9USU1FXyAtIFNUQVJUX1RJTUVfKSAvIGR1cmF0aW9uOwogICAgfQogICAgZWxzZQogICAgewogICAgICAgIGN1cnJlbnRTcGVlZF8gPSBVdGlsOjpmcm9tU3RyaW5nPGZsb2F0PihvcHRpb25zW3NwZWVkTGFiZWxdLnZhbHVlKTsKICAgIH0KCiAgICAvLyBJZiB3ZSdyZSBoZXJlLCB3ZSdyZSBva2F5IHRvIHJ1bi4KICAgIHZhbGlkXyA9IHRydWU7Cn0KCnZvaWQKU2NlbmVJZGVhc1ByaXZhdGU6OnJlc2V0X3RpbWUoKQp7CiAgICB0aW1lT2Zmc2V0XyA9IFNUQVJUX1RJTUVfOwogICAgZ2V0dGltZW9mZGF5KCZzdGFydFRpbWVfLCBOVUxMKTsKfQoKdm9pZApTY2VuZUlkZWFzUHJpdmF0ZTo6dXBkYXRlX3RpbWUoKQp7CiAgICAvLyBDb21wdXRlIG5ldyB0aW1lCiAgICBzdHJ1Y3QgdGltZXZhbCBjdXJyZW50ID0gezAsIDB9OwogICAgZ2V0dGltZW9mZGF5KCZjdXJyZW50LCBOVUxMKTsKICAgIGZsb2F0IHRpbWVkaWZmID0gKGN1cnJlbnQudHZfc2VjIC0gc3RhcnRUaW1lXy50dl9zZWMpICsgCiAgICAgICAgc3RhdGljX2Nhc3Q8ZG91YmxlPihjdXJyZW50LnR2X3VzZWMgLSBzdGFydFRpbWVfLnR2X3VzZWMpIC8gMTAwMDAwMC4wOwogICAgZmxvYXQgc2NlbmVUaW1lID0gdGltZWRpZmYgKiBjdXJyZW50U3BlZWRfICsgdGltZU9mZnNldF87CgogICAgLy8gS2VlcCB0aGUgY3VycmVudCB0aW1lIGluIFtTVEFSVF9USU1FXy4uQ1lDTEVfVElNRV8pCiAgICAvLyBFdmVyeSBvdGhlciBjeWNsZSBzdGFydGluZyB3aXRoIDAgc3RhcnQgYXQgdGhlIGJlZ2lubmluZyBhbmQgZ29lcwogICAgLy8gZm9yd2FyZCBpbiB0aW1lLiAgT3RoZXIgY3ljbGVzIHN0YXJ0IGF0IHRoZSBlbmQgYW5kIGdvIGJhY2t3YXJkcy4KICAgIGN1cnJlbnRUaW1lXyA9IHN0ZDo6Zm1vZChzY2VuZVRpbWUsIENZQ0xFX1RJTUVfKTsKICAgIHVuc2lnbmVkIGludCBjeWNsZSA9IHNjZW5lVGltZS9DWUNMRV9USU1FXzsKICAgIGlmIChjeWNsZSAlIDIpCiAgICB7CiAgICAgICAgY3VycmVudFRpbWVfID0gQ1lDTEVfVElNRV8gLSBjdXJyZW50VGltZV87CiAgICB9Cn0KCnZvaWQKU2NlbmVJZGVhc1ByaXZhdGU6OnVwZGF0ZV9wcm9qZWN0aW9uKGNvbnN0IG1hdDQmIHByb2opCnsKICAgIC8vIFByb2plY3Rpb24gaGFzbid0IGNoYW5nZWQgc2luY2UgbGFzdCBmcmFtZS4KICAgIGlmIChwcm9qZWN0aW9uXy5nZXRDdXJyZW50KCkgPT0gcHJvaikKICAgIHsKICAgICAgICByZXR1cm47CiAgICB9CgogICAgcHJvamVjdGlvbl8ubG9hZElkZW50aXR5KCk7CiAgICBwcm9qZWN0aW9uXyAqPSBwcm9qOwp9CgpTY2VuZUlkZWFzOjpTY2VuZUlkZWFzKENhbnZhcyYgY2FudmFzKSA6CiAgICBTY2VuZShjYW52YXMsICJpZGVhcyIpLCBwcml2XygwKQp7CiAgICBvcHRpb25zX1sic3BlZWQiXSA9IFNjZW5lOjpPcHRpb24oInNwZWVkIiwgImR1cmF0aW9uIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiVGltZSBjb2VmZmljaWVudCAoMS4wIGlzIFwid2FsbCBjbG9ja1wiIHNwZWVkLCA8MS4wIGlzIHNsb3dlciwgPjEuMCBpcyBmYXN0ZXIpLiAgQSBzcGVjaWFsIHZhbHVlIG9mIFwiZHVyYXRpb25cIiBjb21wdXRlcyB0aGlzIGFzIGEgZnVuY3Rpb24gb2YgdGhlIFwiZHVyYXRpb25cIiBvcHRpb24iKTsKfQoKU2NlbmVJZGVhczo6flNjZW5lSWRlYXMoKQp7CiAgICBkZWxldGUgcHJpdl87Cn0KCmJvb2wKU2NlbmVJZGVhczo6bG9hZCgpCnsKICAgIHJ1bm5pbmdfID0gZmFsc2U7CiAgICByZXR1cm4gdHJ1ZTsKfQoKdm9pZApTY2VuZUlkZWFzOjp1bmxvYWQoKQp7Cn0KCmJvb2wKU2NlbmVJZGVhczo6c2V0dXAoKQp7CiAgICBpZiAoIVNjZW5lOjpzZXR1cCgpKQogICAgICAgIHJldHVybiBmYWxzZTsKCiAgICBwcml2XyA9IG5ldyBTY2VuZUlkZWFzUHJpdmF0ZSgpOwogICAgcHJpdl8tPmluaXRpYWxpemUob3B0aW9uc18pOwogICAgaWYgKCFwcml2Xy0+dmFsaWQoKSkKICAgICAgICByZXR1cm4gZmFsc2U7CgogICAgcHJpdl8tPnVwZGF0ZV9wcm9qZWN0aW9uKGNhbnZhc18ucHJvamVjdGlvbigpKTsKCiAgICAvLyBDb3JlIFNjZW5lIHN0YXRlCiAgICBjdXJyZW50RnJhbWVfID0gMDsKICAgIHJ1bm5pbmdfID0gdHJ1ZTsKICAgIHN0YXJ0VGltZV8gPSBVdGlsOjpnZXRfdGltZXN0YW1wX3VzKCkgLyAxMDAwMDAwLjA7CiAgICBsYXN0VXBkYXRlVGltZV8gPSBzdGFydFRpbWVfOwoKICAgIHJldHVybiB0cnVlOwp9Cgp2b2lkClNjZW5lSWRlYXM6OnVwZGF0ZSgpCnsKICAgIFNjZW5lOjp1cGRhdGUoKTsKICAgIHByaXZfLT51cGRhdGVfdGltZSgpOwogICAgcHJpdl8tPnVwZGF0ZV9wcm9qZWN0aW9uKGNhbnZhc18ucHJvamVjdGlvbigpKTsKfQoKdm9pZApTY2VuZUlkZWFzUHJpdmF0ZTo6ZHJhdygpCnsKICAgIHZpZXdGcm9tU3BsaW5lXy5nZXRDdXJyZW50VmVjKGN1cnJlbnRUaW1lXywgdmlld0Zyb21fKTsKICAgIHZpZXdUb1NwbGluZV8uZ2V0Q3VycmVudFZlYyhjdXJyZW50VGltZV8sIHZpZXdUb18pOwogICAgbGlnaHRQb3NTcGxpbmVfLmdldEN1cnJlbnRWZWMoY3VycmVudFRpbWVfLCBsaWdodFBvc18pOwogICAgbG9nb1Bvc1NwbGluZV8uZ2V0Q3VycmVudFZlYyhjdXJyZW50VGltZV8sIGxvZ29Qb3NfKTsKICAgIGxvZ29Sb3RTcGxpbmVfLmdldEN1cnJlbnRWZWMoY3VycmVudFRpbWVfLCBsb2dvUm90Xyk7CgogICAgLy8gVGVsbCB0aGUgbG9nbyBpdHMgbmV3IHBvc2l0aW9uCiAgICBsb2dvXy5zZXRQb3NpdGlvbihsb2dvUG9zXyk7CgogICAgdmVjNCBscDQobGlnaHRQb3NfLngoKSwgbGlnaHRQb3NfLnkoKSwgbGlnaHRQb3NfLnooKSwgMC4wKTsKCiAgICAvLwogICAgLy8gU0hBRE9XCiAgICAvLwogICAgbW9kZWx2aWV3Xy5sb2FkSWRlbnRpdHkoKTsKICAgIG1vZGVsdmlld18ubG9va0F0KHZpZXdGcm9tXy54KCksIHZpZXdGcm9tXy55KCksIHZpZXdGcm9tXy56KCksIAogICAgICAgICAgICAgICAgICAgICAgdmlld1RvXy54KCksIHZpZXdUb18ueSgpLCB2aWV3VG9fLnooKSwKICAgICAgICAgICAgICAgICAgICAgIDAuMCwgMS4wLCAwLjApOwoKICAgIGZsb2F0IHBjYSgwLjApOwogICAgaWYgKHZpZXdGcm9tXy55KCkgPiAwLjApCiAgICB7CiAgICAgICAgdGFibGVfLmRyYXcobW9kZWx2aWV3XywgcHJvamVjdGlvbl8sIGxpZ2h0UG9zXywgbG9nb1Bvc18sIGN1cnJlbnRUaW1lXywgcGNhKTsKICAgIH0KCiAgICBnbEVuYWJsZShHTF9DVUxMX0ZBQ0UpOyAKICAgIGdsRGlzYWJsZShHTF9ERVBUSF9URVNUKTsgCgogICAgaWYgKGxvZ29Qb3NfLnkoKSA8IDAuMCkKICAgIHsKICAgICAgICAvLyBTZXQgdGhlIGNvbG9yIGFzc3VtaW5nIHdlJ3JlIHN0aWxsIHVuZGVyIHRoZSB0YWJsZS4KICAgICAgICB1dmVjMyBmbGF0Q29sb3IoMTI4IC8gMiwgIDEwMiAvIDIsICAxNzkgLyAyKTsKICAgICAgICBpZiAobG9nb1Bvc18ueSgpID4gLTAuMzMpCiAgICAgICAgewogICAgICAgICAgICAvLyBXZSdyZSBlbWVyZ2luZyBmcm9tIHRoZSB0YWJsZQogICAgICAgICAgICBmbG9hdCBjKDEuMCAtIGxvZ29Qb3NfLnkoKSAvIC0wLjMzKTsKICAgICAgICAgICAgcGNhIC89IDQuMDsKICAgICAgICAgICAgZmxhdENvbG9yLngoc3RhdGljX2Nhc3Q8dW5zaWduZWQgaW50PigxMjguMCAqICgxLjAgLSBjKSAqIDAuNSArIDI1NS4wICogcGNhICogYykpOwogICAgICAgICAgICBmbGF0Q29sb3IueShzdGF0aWNfY2FzdDx1bnNpZ25lZCBpbnQ+KDEwMi4wICogKDEuMCAtIGMpICogMC41ICsgMjU1LjAgKiBwY2EgKiBjKSk7CiAgICAgICAgICAgIGZsYXRDb2xvci56KHN0YXRpY19jYXN0PHVuc2lnbmVkIGludD4oMTc5LjAgKiAoMS4wIC0gYykgKiAwLjUgKyAyMDAuMCAqIHBjYSAqIGMpKTsKICAgICAgICB9CgogICAgICAgIG1vZGVsdmlld18ucHVzaCgpOwogICAgICAgIG1vZGVsdmlld18uc2NhbGUoMC4wNCwgMC4wLCAwLjA0KTsKICAgICAgICBtb2RlbHZpZXdfLnJvdGF0ZSgtOTAuMCwgMS4wLCAwLjAsIDAuMCk7CiAgICAgICAgbW9kZWx2aWV3Xy5yb3RhdGUoMC4xICogc3RhdGljX2Nhc3Q8aW50PigxMC4wICogbG9nb1JvdF8ueigpKSwgMC4wLCAwLjAsIDEuMCk7CiAgICAgICAgbW9kZWx2aWV3Xy5yb3RhdGUoMC4xICogc3RhdGljX2Nhc3Q8aW50PigxMC4wICogbG9nb1JvdF8ueSgpKSwgMC4wLCAxLjAsIDAuMCk7CiAgICAgICAgbW9kZWx2aWV3Xy5yb3RhdGUoMC4xICogc3RhdGljX2Nhc3Q8aW50PigxMC4wICogbG9nb1JvdF8ueCgpKSwgMS4wLCAwLjAsIDAuMCk7CiAgICAgICAgbW9kZWx2aWV3Xy5yb3RhdGUoMC4xICogMzUzLCAxLjAsIDAuMCwgMC4wKTsKICAgICAgICBtb2RlbHZpZXdfLnJvdGF0ZSgwLjEgKiA0NTAsIDAuMCwgMS4wLCAwLjApOwoKICAgICAgICBsb2dvXy5kcmF3KG1vZGVsdmlld18sIHByb2plY3Rpb25fLCBsaWdodFBvc2l0aW9uc19bMF0sIFNHSUxvZ286OkxPR09fRkxBVCwgZmxhdENvbG9yKTsKCiAgICAgICAgbW9kZWx2aWV3Xy5wb3AoKTsKICAgIH0KICAgIAogICAgaWYgKGxvZ29Qb3NfLnkoKSA+IDAuMCkKICAgIHsKICAgICAgICBtb2RlbHZpZXdfLnB1c2goKTsKICAgICAgICBtb2RlbHZpZXdfLnRyYW5zbGF0ZShsaWdodFBvc18ueCgpLCBsaWdodFBvc18ueSgpLCBsaWdodFBvc18ueigpKTsKICAgICAgICBtYXQ0IHR2OwogICAgICAgIHR2WzNdWzFdID0gLTEuMDsKICAgICAgICB0dlszXVszXSA9IDAuMDsKICAgICAgICB0dlswXVswXSA9IHR2WzFdWzFdID0gdHZbMl1bMl0gPSBsaWdodFBvc18ueSgpOwogICAgICAgIG1vZGVsdmlld18gKj0gdHY7CiAgICAgICAgbW9kZWx2aWV3Xy50cmFuc2xhdGUoLWxpZ2h0UG9zXy54KCkgKyBsb2dvUG9zXy54KCksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLWxpZ2h0UG9zXy55KCkgKyBsb2dvUG9zXy55KCksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLWxpZ2h0UG9zXy56KCkgKyBsb2dvUG9zXy56KCkpOwogICAgICAgIG1vZGVsdmlld18uc2NhbGUoMC4wNCwgMC4wNCwgMC4wNCk7CiAgICAgICAgbW9kZWx2aWV3Xy5yb3RhdGUoLTkwLjAsIDEuMCwgMC4wLCAwLjApOwogICAgICAgIG1vZGVsdmlld18ucm90YXRlKDAuMSAqIHN0YXRpY19jYXN0PGludD4oMTAuMCAqIGxvZ29Sb3RfLnooKSksIDAuMCwgMC4wLCAxLjApOwogICAgICAgIG1vZGVsdmlld18ucm90YXRlKDAuMSAqIHN0YXRpY19jYXN0PGludD4oMTAuMCAqIGxvZ29Sb3RfLnkoKSksIDAuMCwgMS4wLCAwLjApOwogICAgICAgIG1vZGVsdmlld18ucm90YXRlKDAuMSAqIHN0YXRpY19jYXN0PGludD4oMTAuMCAqIGxvZ29Sb3RfLngoKSksIDEuMCwgMC4wLCAwLjApOwogICAgICAgIG1vZGVsdmlld18ucm90YXRlKDM1LjMsIDEuMCwgMC4wLCAwLjApOwogICAgICAgIG1vZGVsdmlld18ucm90YXRlKDQ1LjAsIDAuMCwgMS4wLCAwLjApOwoKICAgICAgICBsb2dvXy5kcmF3KG1vZGVsdmlld18sIHByb2plY3Rpb25fLCBsaWdodFBvc2l0aW9uc19bMF0sIFNHSUxvZ286OkxPR09fU0hBRE9XKTsKCiAgICAgICAgbW9kZWx2aWV3Xy5wb3AoKTsKICAgIH0KICAgIC8vCiAgICAvLyBET05FIFNIQURPVyAKICAgIC8vCgogICAgZ2xFbmFibGUoR0xfREVQVEhfVEVTVCk7CiAgICBnbERpc2FibGUoR0xfQ1VMTF9GQUNFKTsKCiAgICBtb2RlbHZpZXdfLmxvYWRJZGVudGl0eSgpOwogICAgbW9kZWx2aWV3Xy5sb29rQXQodmlld0Zyb21fLngoKSwgdmlld0Zyb21fLnkoKSwgdmlld0Zyb21fLnooKSwKICAgICAgICAgICAgICAgICAgICAgIHZpZXdUb18ueCgpLCB2aWV3VG9fLnkoKSwgdmlld1RvXy56KCksIAogICAgICAgICAgICAgICAgICAgICAgMC4wLCAxLjAsIDAuMCk7CiAgICBtb2RlbHZpZXdfLnB1c2goKTsKICAgIG1vZGVsdmlld18udHJhbnNsYXRlKGxpZ2h0UG9zXy54KCksIGxpZ2h0UG9zXy55KCksIGxpZ2h0UG9zXy56KCkpOwogICAgbW9kZWx2aWV3Xy5zY2FsZSgwLjEsIDAuMSwgMC4xKTsKICAgIGZsb2F0IHgobGlnaHRQb3NfLngoKSAtIGxvZ29Qb3NfLngoKSk7CiAgICBmbG9hdCB5KGxpZ2h0UG9zXy55KCkgLSBsb2dvUG9zXy55KCkpOwogICAgZmxvYXQgeihsaWdodFBvc18ueigpIC0gbG9nb1Bvc18ueigpKTsKICAgIGRvdWJsZSBhMygwLjApOwogICAgaWYgKHggIT0gMC4wKQogICAgewogICAgICAgIGEzID0gLWF0YW4yKHosIHgpICogMTAuMCAqIDE4MC4wIC8gTV9QSTsKICAgIH0KICAgIGRvdWJsZSBhNCgtYXRhbjIoc3FydCh4ICogeCArIHogKiB6KSwgeSkgKiAxMC4wICogMTgwLjAgLyBNX1BJKTsKICAgIG1vZGVsdmlld18ucm90YXRlKDAuMSAqIHN0YXRpY19jYXN0PGludD4oYTMpLCAwLjAsIDEuMCwgMC4wKTsKICAgIG1vZGVsdmlld18ucm90YXRlKDAuMSAqIHN0YXRpY19jYXN0PGludD4oYTQpLCAwLjAsIDAuMCwgMS4wKTsKICAgIG1vZGVsdmlld18ucm90YXRlKC05MC4wLCAxLjAsIDAuMCwgMC4wKTsKCiAgICBsYW1wXy5kcmF3KG1vZGVsdmlld18sIHByb2plY3Rpb25fLCBsaWdodFBvc2l0aW9uc18pOwoKICAgIG1vZGVsdmlld18ucG9wKCk7CiAgICAKICAgIGxpZ2h0UG9zaXRpb25zX1swXSA9IG1vZGVsdmlld18uZ2V0Q3VycmVudCgpICogbHA0OwogICAgCiAgICBpZiAobG9nb1Bvc18ueSgpID4gLTAuMzMpCiAgICB7CiAgICAgICAgbW9kZWx2aWV3Xy5wdXNoKCk7CiAgICAgICAgbW9kZWx2aWV3Xy50cmFuc2xhdGUobG9nb1Bvc18ueCgpLCBsb2dvUG9zXy55KCksIGxvZ29Qb3NfLnooKSk7CiAgICAgICAgbW9kZWx2aWV3Xy5zY2FsZSgwLjA0LCAwLjA0LCAwLjA0KTsKICAgICAgICBtb2RlbHZpZXdfLnJvdGF0ZSgtOTAuMCwgMS4wLCAwLjAsIDAuMCk7CiAgICAgICAgbW9kZWx2aWV3Xy5yb3RhdGUoMC4xICogc3RhdGljX2Nhc3Q8aW50PigxMC4wICogbG9nb1JvdF8ueigpKSwgMC4wLCAwLjAsIDEuMCk7CiAgICAgICAgbW9kZWx2aWV3Xy5yb3RhdGUoMC4xICogc3RhdGljX2Nhc3Q8aW50PigxMC4wICogbG9nb1JvdF8ueSgpKSwgMC4wLCAxLjAsIDAuMCk7CiAgICAgICAgbW9kZWx2aWV3Xy5yb3RhdGUoMC4xICogc3RhdGljX2Nhc3Q8aW50PigxMC4wICogbG9nb1JvdF8ueCgpKSwgMS4wLCAwLjAsIDAuMCk7CiAgICAgICAgbW9kZWx2aWV3Xy5yb3RhdGUoMzUuMywgMS4wLCAwLjAsIDAuMCk7CiAgICAgICAgbW9kZWx2aWV3Xy5yb3RhdGUoNDUuMCwgMC4wLCAxLjAsIDAuMCk7CgogICAgICAgIGxvZ29fLmRyYXcobW9kZWx2aWV3XywgcHJvamVjdGlvbl8sIGxpZ2h0UG9zaXRpb25zX1swXSwgU0dJTG9nbzo6TE9HT19OT1JNQUwpOwoKICAgICAgICBtb2RlbHZpZXdfLnBvcCgpOwogICAgfQogICAgCiAgICBpZiAodmlld0Zyb21fLnkoKSA8IDAuMCkKICAgIHsKICAgICAgICB0YWJsZV8uZHJhd1VuZGVyKG1vZGVsdmlld18sIHByb2plY3Rpb25fKTsKICAgIH0KfQoKdm9pZApTY2VuZUlkZWFzOjpkcmF3KCkKewogICAgcHJpdl8tPmRyYXcoKTsKfQoKU2NlbmU6OlZhbGlkYXRpb25SZXN1bHQKU2NlbmVJZGVhczo6dmFsaWRhdGUoKQp7CiAgICByZXR1cm4gU2NlbmU6OlZhbGlkYXRpb25Vbmtub3duOwp9Cgp2b2lkClNjZW5lSWRlYXM6OnRlYXJkb3duKCkKewogICAgZGVsZXRlIHByaXZfOwogICAgcHJpdl8gPSAwOwogICAgU2NlbmU6OnRlYXJkb3duKCk7Cn0K