Ly8KLy8gQ29weXJpZ2h0IKkgMjAxMiBMaW5hcm8gTGltaXRlZAovLwovLyBUaGlzIGZpbGUgaXMgcGFydCBvZiB0aGUgZ2xtYXJrMiBPcGVuR0wgKEVTKSAyLjAgYmVuY2htYXJrLgovLwovLyBnbG1hcmsyIGlzIGZyZWUgc29mdHdhcmU6IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnkgaXQgdW5kZXIgdGhlCi8vIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBhcyBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUKLy8gRm91bmRhdGlvbiwgZWl0aGVyIHZlcnNpb24gMyBvZiB0aGUgTGljZW5zZSwgb3IgKGF0IHlvdXIgb3B0aW9uKSBhbnkgbGF0ZXIKLy8gdmVyc2lvbi4KLy8KLy8gZ2xtYXJrMiBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkKLy8gV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUwovLyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGZvciBtb3JlCi8vIGRldGFpbHMuCi8vCi8vIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGFsb25nIHdpdGgKLy8gZ2xtYXJrMi4gIElmIG5vdCwgc2VlIDxodHRwOi8vd3d3LmdudS5vcmcvbGljZW5zZXMvPi4KLy8KLy8gQXV0aG9yczoKLy8gIEFsZWtzYW5kYXIgUm9kaWMgLSBDcmVhdG9yIGFuZCBXZWJHTCBpbXBsZW1lbnRhdGlvbiAKLy8gIEplc3NlIEJhcmtlciAtIGdsbWFyazIgcG9ydAovLwojaW5jbHVkZSA8c3RyaW5nPgojaW5jbHVkZSA8ZnN0cmVhbT4KI2luY2x1ZGUgPG1lbW9yeT4KI2luY2x1ZGUgPGlvbWFuaXA+CiNpbmNsdWRlICJzY2VuZS5oIgojaW5jbHVkZSAic2NlbmUtamVsbHlmaXNoLmgiCiNpbmNsdWRlICJsb2cuaCIKI2luY2x1ZGUgInV0aWwuaCIKI2luY2x1ZGUgInRleHR1cmUuaCIKI2luY2x1ZGUgInNoYWRlci1zb3VyY2UuaCIKClNjZW5lSmVsbHlmaXNoOjpTY2VuZUplbGx5ZmlzaChDYW52YXMmIGNhbnZhcykgOgogICAgU2NlbmUoY2FudmFzLCAiamVsbHlmaXNoIiksIHByaXZfKDApCnsKCn0KClNjZW5lSmVsbHlmaXNoOjp+U2NlbmVKZWxseWZpc2goKQp7CiAgICBkZWxldGUgcHJpdl87Cn0KCmJvb2wKU2NlbmVKZWxseWZpc2g6OmxvYWQoKQp7CiAgICBydW5uaW5nXyA9IGZhbHNlOwogICAgcmV0dXJuIHRydWU7Cn0KCnZvaWQKU2NlbmVKZWxseWZpc2g6OnVubG9hZCgpCnsKfQoKYm9vbApTY2VuZUplbGx5ZmlzaDo6c2V0dXAoKQp7CiAgICBpZiAoIVNjZW5lOjpzZXR1cCgpKQogICAgICAgIHJldHVybiBmYWxzZTsKCiAgICAvLyBTZXQgdXAgb3VyIHByaXZhdGUgb2JqZWN0IHRoYXQgZG9lcyBhbGwgb2YgdGhlIGxpZnRpbmcKICAgIHByaXZfID0gbmV3IEplbGx5ZmlzaFByaXZhdGUoKTsKICAgIGlmICghcHJpdl8tPmluaXRpYWxpemUoKSkKICAgICAgICByZXR1cm4gZmFsc2U7CgogICAgLy8gU2V0IGNvcmUgc2NlbmUgdGltaW5nIGFmdGVyIGFjdHVhbCBpbml0aWFsaXphdGlvbiBzbyB3ZSBkb24ndCBtZWFzdXJlCiAgICAvLyBzZXQgdXAgdGltZS4KICAgIHN0YXJ0VGltZV8gPSBVdGlsOjpnZXRfdGltZXN0YW1wX3VzKCkgLyAxMDAwMDAwLjA7CiAgICBsYXN0VXBkYXRlVGltZV8gPSBzdGFydFRpbWVfOwogICAgcnVubmluZ18gPSB0cnVlOwoKICAgIHJldHVybiB0cnVlOwp9Cgp2b2lkClNjZW5lSmVsbHlmaXNoOjp0ZWFyZG93bigpCnsKICAgIHByaXZfLT5jbGVhbnVwKCk7CiAgICBTY2VuZTo6dGVhcmRvd24oKTsKfQoKdm9pZApTY2VuZUplbGx5ZmlzaDo6dXBkYXRlKCkKewogICAgU2NlbmU6OnVwZGF0ZSgpOwogICAgcHJpdl8tPnVwZGF0ZV92aWV3cG9ydChMaWJNYXRyaXg6OnZlYzIoY2FudmFzXy53aWR0aCgpLCBjYW52YXNfLmhlaWdodCgpKSk7CiAgICBwcml2Xy0+dXBkYXRlX3RpbWUoKTsKfQoKdm9pZApTY2VuZUplbGx5ZmlzaDo6ZHJhdygpCnsKICAgIHByaXZfLT5kcmF3KCk7Cn0KClNjZW5lOjpWYWxpZGF0aW9uUmVzdWx0ClNjZW5lSmVsbHlmaXNoOjp2YWxpZGF0ZSgpCnsKICAgIHJldHVybiBTY2VuZTo6VmFsaWRhdGlvblVua25vd247Cn0KCgovLwovLyBKZWxseWZpc2hQcml2YXRlIGltcGxlbWVudGF0aW9uCi8vCnVzaW5nIExpYk1hdHJpeDo6bWF0NDsKdXNpbmcgTGliTWF0cml4Ojp2ZWMzOwp1c2luZyBMaWJNYXRyaXg6OnZlYzI7CnVzaW5nIHN0ZDo6c3RyaW5nOwp1c2luZyBzdGQ6OnZlY3RvcjsKCmJvb2wKR3JhZGllbnRSZW5kZXJlcjo6aW5pdCgpCnsKICAgIC8vIFByb2dyYW0gc2V0IHVwCiAgICBzdGF0aWMgY29uc3Qgc3RyaW5nIHZ0eF9zaGFkZXJfZmlsZW5hbWUoR0xNQVJLX0RBVEFfUEFUSCIvc2hhZGVycy9ncmFkaWVudC52ZXJ0Iik7CiAgICBzdGF0aWMgY29uc3Qgc3RyaW5nIGZyZ19zaGFkZXJfZmlsZW5hbWUoR0xNQVJLX0RBVEFfUEFUSCIvc2hhZGVycy9ncmFkaWVudC5mcmFnIik7CiAgICBTaGFkZXJTb3VyY2UgdnR4X3NvdXJjZSh2dHhfc2hhZGVyX2ZpbGVuYW1lKTsKICAgIFNoYWRlclNvdXJjZSBmcmdfc291cmNlKGZyZ19zaGFkZXJfZmlsZW5hbWUpOwogICAgaWYgKCFTY2VuZTo6bG9hZF9zaGFkZXJzX2Zyb21fc3RyaW5ncyhwcm9ncmFtXywgdnR4X3NvdXJjZS5zdHIoKSwKICAgICAgICBmcmdfc291cmNlLnN0cigpKSkKICAgIHsKICAgICAgICByZXR1cm4gZmFsc2U7CiAgICB9CiAgICBwb3NpdGlvbkxvY2F0aW9uXyA9IHByb2dyYW1fWyJwb3NpdGlvbiJdLmxvY2F0aW9uKCk7CiAgICB1dkxvY2F0aW9uXyA9IHByb2dyYW1fWyJ1dkluIl0ubG9jYXRpb24oKTsKCiAgICAvLyBTZXQgdXAgdGhlIHBvc2l0aW9uIGRhdGEgZm9yIG91ciAicXVhZCIuCiAgICB2ZXJ0aWNlc18ucHVzaF9iYWNrKHZlYzIoLTEuMCwgLTEuMCkpOwogICAgdmVydGljZXNfLnB1c2hfYmFjayh2ZWMyKDEuMCwgLTEuMCkpOwogICAgdmVydGljZXNfLnB1c2hfYmFjayh2ZWMyKC0xLjAsIDEuMCkpOwogICAgdmVydGljZXNfLnB1c2hfYmFjayh2ZWMyKDEuMCwgMS4wKSk7CiAgICB1dnNfLnB1c2hfYmFjayh2ZWMyKDEuMCwgMS4wKSk7CiAgICB1dnNfLnB1c2hfYmFjayh2ZWMyKDEuMCwgMS4wKSk7CiAgICB1dnNfLnB1c2hfYmFjayh2ZWMyKDAuMCwgMC4wKSk7CiAgICB1dnNfLnB1c2hfYmFjayh2ZWMyKDAuMCwgMC4wKSk7CiAgICB1dk9mZnNldF8gPSB2ZXJ0aWNlc18uc2l6ZSgpICogc2l6ZW9mKHZlYzIpOwoKICAgIC8vIFNldCB1cCB0aGUgVkJPIGFuZCBzdGFzaCBvdXIgcG9zaXRpb24gZGF0YSBpbiBpdC4KICAgIGdsR2VuQnVmZmVycygxLCAmYnVmZmVyT2JqZWN0Xyk7CiAgICBnbEJpbmRCdWZmZXIoR0xfQVJSQVlfQlVGRkVSLCBidWZmZXJPYmplY3RfKTsKICAgIGdsQnVmZmVyRGF0YShHTF9BUlJBWV9CVUZGRVIsICh2ZXJ0aWNlc18uc2l6ZSgpICsgdXZzXy5zaXplKCkpICogc2l6ZW9mKHZlYzIpLAogICAgICAgICAgICAgICAgIDAsIEdMX1NUQVRJQ19EUkFXKTsKICAgIGdsQnVmZmVyU3ViRGF0YShHTF9BUlJBWV9CVUZGRVIsIDAsIHZlcnRpY2VzXy5zaXplKCkgKiBzaXplb2YodmVjMiksCiAgICAgICAgICAgICAgICAgICAgJnZlcnRpY2VzXy5mcm9udCgpKTsKICAgIGdsQnVmZmVyU3ViRGF0YShHTF9BUlJBWV9CVUZGRVIsIHV2T2Zmc2V0XywgdXZzXy5zaXplKCkgKiBzaXplb2YodmVjMiksCiAgICAgICAgICAgICAgICAgICAgJnV2c18uZnJvbnQoKSk7CiAgICBnbEJpbmRCdWZmZXIoR0xfQVJSQVlfQlVGRkVSLCAwKTsKCiAgICByZXR1cm4gdHJ1ZTsKfQoKdm9pZApHcmFkaWVudFJlbmRlcmVyOjpjbGVhbnVwKCkKewogICAgcHJvZ3JhbV8uc3RvcCgpOwogICAgcHJvZ3JhbV8ucmVsZWFzZSgpOwogICAgZ2xCaW5kQnVmZmVyKEdMX0FSUkFZX0JVRkZFUiwgMCk7CiAgICBnbERlbGV0ZUJ1ZmZlcnMoMSwgJmJ1ZmZlck9iamVjdF8pOwp9Cgp2b2lkCkdyYWRpZW50UmVuZGVyZXI6OmRyYXcoKQp7CiAgICBzdGF0aWMgY29uc3QgdmVjMyBsaWdodEJsdWUoMC4zNjA3ODQzMTQsIDAuNTg0MzEzNzI1LCAxLjApOwogICAgc3RhdGljIGNvbnN0IHZlYzMgZGFya0JsdWUoMC4wNzQ1MDk4MDQsIDAuMTU2ODYyNzQ1LCAwLjYxOTYwNzg0Myk7CiAgICBnbEJpbmRCdWZmZXIoR0xfQVJSQVlfQlVGRkVSLCBidWZmZXJPYmplY3RfKTsKICAgIHByb2dyYW1fLnN0YXJ0KCk7CiAgICBwcm9ncmFtX1siY29sb3IxIl0gPSBsaWdodEJsdWU7CiAgICBwcm9ncmFtX1siY29sb3IyIl0gPSBkYXJrQmx1ZTsKICAgIGdsRW5hYmxlVmVydGV4QXR0cmliQXJyYXkocG9zaXRpb25Mb2NhdGlvbl8pOwogICAgZ2xFbmFibGVWZXJ0ZXhBdHRyaWJBcnJheSh1dkxvY2F0aW9uXyk7CiAgICBnbFZlcnRleEF0dHJpYlBvaW50ZXIocG9zaXRpb25Mb2NhdGlvbl8sIDIsIEdMX0ZMT0FULCBHTF9GQUxTRSwgMCwgMCk7CiAgICBnbFZlcnRleEF0dHJpYlBvaW50ZXIodXZMb2NhdGlvbl8sIDIsIEdMX0ZMT0FULCBHTF9GQUxTRSwgMCwKICAgICAgICAgICAgICAgICAgICAgICAgICByZWludGVycHJldF9jYXN0PEdMdm9pZCo+KHV2T2Zmc2V0XykpOwogICAgZ2xEcmF3QXJyYXlzKEdMX1RSSUFOR0xFX1NUUklQLCAwLCA0KTsKICAgIGdsRGlzYWJsZVZlcnRleEF0dHJpYkFycmF5KHBvc2l0aW9uTG9jYXRpb25fKTsKICAgIGdsRGlzYWJsZVZlcnRleEF0dHJpYkFycmF5KHV2TG9jYXRpb25fKTsKICAgIHByb2dyYW1fLnN0b3AoKTsKICAgIGdsQmluZEJ1ZmZlcihHTF9BUlJBWV9CVUZGRVIsIDApOwp9CgovLyEKLy8gUGFyc2UgaW5kZXggdmFsdWVzIGZyb20gYW4gT0JKIGZpbGUuCi8vCi8vIEBwYXJhbSBzb3VyY2UgdGhlIHNvdXJjZSBsaW5lIHRvIHBhcnNlCi8vIEBwYXJhbSBpZHggdGhlIHVuc2lnbmVkIHNob3J0IHRvIHBvcHVsYXRlCi8vCnN0YXRpYyB2b2lkCm9ial9nZXRfaW5kZXgoY29uc3Qgc3RyaW5nJiBzb3VyY2UsIHVuc2lnbmVkIHNob3J0JiBpZHgpCnsKICAgICAvLyBTa2lwIHRoZSBkZWZpbml0aW9uIHR5cGUuLi4KICAgIHN0cmluZzo6c2l6ZV90eXBlIGVuZFBvcyA9IHNvdXJjZS5maW5kKCIgIik7CiAgICBzdHJpbmc6OnNpemVfdHlwZSBzdGFydFBvcygwKTsKICAgIGlmIChlbmRQb3MgPT0gc3RyaW5nOjpucG9zKQogICAgewogICAgICAgIExvZzo6ZXJyb3IoIkJhZCBlbGVtZW50ICclcydcbiIsIHNvdXJjZS5jX3N0cigpKTsKICAgICAgICByZXR1cm47CiAgICB9CiAgICAvLyBGaW5kIHRoZSBmaXJzdCB2YWx1ZS4uLgogICAgc3RhcnRQb3MgPSBlbmRQb3MgKyAxOwogICAgc3RyaW5nIGlzKHNvdXJjZSwgc3RhcnRQb3MpOwogICAgaWR4ID0gVXRpbDo6ZnJvbVN0cmluZzx1bnNpZ25lZCBzaG9ydD4oaXMpOyAgIAp9CgovLyEKLy8gUGFyc2UgdmVjMyB2YWx1ZXMgZnJvbSBhbiBPQkogZmlsZS4KLy8KLy8gQHBhcmFtIHNvdXJjZSB0aGUgc291cmNlIGxpbmUgdG8gcGFyc2UKLy8gQHBhcmFtIHYgdGhlIHZlYzMgdG8gcG9wdWxhdGUKLy8Kc3RhdGljIHZvaWQKb2JqX2dldF92YWx1ZXMoY29uc3Qgc3RyaW5nJiBzb3VyY2UsIHZlYzMmIHYpCnsKICAgIC8vIFNraXAgdGhlIGRlZmluaXRpb24gdHlwZS4uLgogICAgc3RyaW5nOjpzaXplX3R5cGUgZW5kUG9zID0gc291cmNlLmZpbmQoIiAiKTsKICAgIHN0cmluZzo6c2l6ZV90eXBlIHN0YXJ0UG9zKDApOwogICAgaWYgKGVuZFBvcyA9PSBzdHJpbmc6Om5wb3MpCiAgICB7CiAgICAgICAgTG9nOjplcnJvcigiQmFkIGVsZW1lbnQgJyVzJ1xuIiwgc291cmNlLmNfc3RyKCkpOwogICAgICAgIHJldHVybjsKICAgIH0KICAgIC8vIEZpbmQgdGhlIGZpcnN0IHZhbHVlLi4uCiAgICBzdGFydFBvcyA9IGVuZFBvcyArIDE7CiAgICBlbmRQb3MgPSBzb3VyY2UuZmluZCgiICIsIHN0YXJ0UG9zKTsKICAgIGlmIChlbmRQb3MgPT0gc3RyaW5nOjpucG9zKQogICAgewogICAgICAgIExvZzo6ZXJyb3IoIkJhZCBlbGVtZW50ICclcydcbiIsIHNvdXJjZS5jX3N0cigpKTsKICAgICAgICByZXR1cm47CiAgICB9CiAgICBzdHJpbmc6OnNpemVfdHlwZSBudW1DaGFycyhlbmRQb3MgLSBzdGFydFBvcyk7CiAgICBzdHJpbmcgeHMoc291cmNlLCBzdGFydFBvcywgbnVtQ2hhcnMpOwogICAgZmxvYXQgeCA9IFV0aWw6OmZyb21TdHJpbmc8ZmxvYXQ+KHhzKTsKICAgIC8vIFRoZW4gdGhlIHNlY29uZCB2YWx1ZS4uLgogICAgc3RhcnRQb3MgPSBlbmRQb3MgKyAxOwogICAgZW5kUG9zID0gc291cmNlLmZpbmQoIiAiLCBzdGFydFBvcyk7CiAgICBpZiAoZW5kUG9zID09IHN0cmluZzo6bnBvcykKICAgIHsKICAgICAgICBMb2c6OmVycm9yKCJCYWQgZWxlbWVudCAnJXMnXG4iLCBzb3VyY2UuY19zdHIoKSk7CiAgICAgICAgcmV0dXJuOwogICAgfQogICAgbnVtQ2hhcnMgPSBlbmRQb3MgLSBzdGFydFBvczsKICAgIHN0cmluZyB5cyhzb3VyY2UsIHN0YXJ0UG9zLCBudW1DaGFycyk7CiAgICBmbG9hdCB5ID0gVXRpbDo6ZnJvbVN0cmluZzxmbG9hdD4oeXMpOwogICAgLy8gQW5kIHRoZSB0aGlyZCB2YWx1ZSAodGhlcmUgbWlnaHQgYmUgYSBmb3VydGgsIGJ1dCB3ZSBkb24ndCBjYXJlKS4uLgogICAgc3RhcnRQb3MgPSBlbmRQb3MgKyAxOwogICAgZW5kUG9zID0gc291cmNlLmZpbmQoIiAiLCBzdGFydFBvcyk7CiAgICBpZiAoZW5kUG9zID09IHN0cmluZzo6bnBvcykKICAgIHsKICAgICAgICBudW1DaGFycyA9IGVuZFBvczsKICAgIH0KICAgIGVsc2UKICAgIHsKICAgICAgICBudW1DaGFycyA9IGVuZFBvcyAtIHN0YXJ0UG9zOwogICAgfQogICAgc3RyaW5nIHpzKHNvdXJjZSwgc3RhcnRQb3MsIGVuZFBvcyAtIHN0YXJ0UG9zKTsKICAgIGZsb2F0IHogPSBVdGlsOjpmcm9tU3RyaW5nPGZsb2F0Pih6cyk7CiAgICB2LngoeCk7CiAgICB2LnkoeSk7CiAgICB2Lnooeik7Cn0KCi8vIEN1c3RvbSBPQkogbG9hZGVyLgovLwovLyBUbyBzdXBwb3J0IHRoZSBqZWxseWZpc2ggbW9kZWwsIHNvbWUgYW1lbmRtZW50cyB0byB0aGUgT0JKIGZvcm1hdCBhcmUKLy8gbmVjZXNzYXJ5LiAgSW4gcGFydGljdWxhciwgYSB2ZXJ0ZXggY29sb3IgYXR0cmlidXRlIGlzIHJlcXVpcmVkLCBhbmQKLy8gaXQgY29udGFpbnMgYW4gaW5kZXggbGlzdCByYXRoZXIgdGhhbiBhIGZhY2UgbGlzdC4KYm9vbApKZWxseWZpc2hQcml2YXRlOjpsb2FkX29iaihjb25zdCBzdGQ6OnN0cmluZyAmZmlsZW5hbWUpCnsKICAgIExvZzo6ZGVidWcoIkxvYWRpbmcgbW9kZWwgZnJvbSBmaWxlICclcydcbiIsIGZpbGVuYW1lLmNfc3RyKCkpOwoKICAgIGNvbnN0IHN0ZDo6YXV0b19wdHI8c3RkOjppc3RyZWFtPiBpbnB1dF9maWxlX3B0cihVdGlsOjpnZXRfcmVzb3VyY2UoZmlsZW5hbWUpKTsKICAgIHN0ZDo6aXN0cmVhbSYgaW5wdXRGaWxlKCppbnB1dF9maWxlX3B0cik7CiAgICBpZiAoIWlucHV0RmlsZSkKICAgIHsKICAgICAgICBMb2c6OmVycm9yKCJGYWlsZWQgdG8gb3BlbiAnJXMnXG4iLCBmaWxlbmFtZS5jX3N0cigpKTsKICAgICAgICByZXR1cm4gZmFsc2U7CiAgICB9CgogICAgdmVjdG9yPHN0cmluZz4gc291cmNlVmVjOwogICAgc3RyaW5nIGN1ckxpbmU7CiAgICB3aGlsZSAoZ2V0bGluZShpbnB1dEZpbGUsIGN1ckxpbmUpKQogICAgewogICAgICAgIHNvdXJjZVZlYy5wdXNoX2JhY2soY3VyTGluZSk7CiAgICB9CgogICAgc3RhdGljIGNvbnN0IHN0cmluZyB2ZXJ0ZXhfZGVmaW5pdGlvbigidiIpOwogICAgc3RhdGljIGNvbnN0IHN0cmluZyBub3JtYWxfZGVmaW5pdGlvbigidm4iKTsKICAgIHN0YXRpYyBjb25zdCBzdHJpbmcgdGV4Y29vcmRfZGVmaW5pdGlvbigidnQiKTsKICAgIHN0YXRpYyBjb25zdCBzdHJpbmcgY29sb3JfZGVmaW5pdGlvbigidmMiKTsKICAgIHN0YXRpYyBjb25zdCBzdHJpbmcgaW5kZXhfZGVmaW5pdGlvbigiaSIpOwogICAgZm9yICh2ZWN0b3I8c3RyaW5nPjo6Y29uc3RfaXRlcmF0b3IgbGluZUl0ID0gc291cmNlVmVjLmJlZ2luKCk7CiAgICAgICAgIGxpbmVJdCAhPSBzb3VyY2VWZWMuZW5kKCk7CiAgICAgICAgIGxpbmVJdCsrKQogICAgewogICAgICAgIGNvbnN0IHN0cmluZyYgY3VyU3JjID0gKmxpbmVJdDsKICAgICAgICAvLyBJcyBpdCBhIHZlcnRleCBhdHRyaWJ1dGUsIGEgZmFjZSBkZXNjcmlwdGlvbiwgY29tbWVudCBvciBvdGhlcj8KICAgICAgICAvLyBXZSBvbmx5IGNhcmUgYWJvdXQgdGhlIGZpcnN0IHR3bywgd2UgaWdub3JlIGNvbW1lbnRzLCBvYmplY3QgbmFtZXMsCiAgICAgICAgLy8gZ3JvdXAgbmFtZXMsIHNtb290aGluZyBncm91cHMsIGV0Yy4KICAgICAgICBzdHJpbmc6OnNpemVfdHlwZSBzdGFydFBvcygwKTsKICAgICAgICBzdHJpbmc6OnNpemVfdHlwZSBzcGFjZVBvcyA9IGN1clNyYy5maW5kKCIgIiwgc3RhcnRQb3MpOwogICAgICAgIHN0cmluZyBkZWZpbml0aW9uVHlwZShjdXJTcmMsIHN0YXJ0UG9zLCBzcGFjZVBvcyAtIHN0YXJ0UG9zKTsKICAgICAgICBpZiAoZGVmaW5pdGlvblR5cGUgPT0gdmVydGV4X2RlZmluaXRpb24pCiAgICAgICAgewogICAgICAgICAgICB2ZWMzIHY7CiAgICAgICAgICAgIG9ial9nZXRfdmFsdWVzKGN1clNyYywgdik7CiAgICAgICAgICAgIHBvc2l0aW9uc18ucHVzaF9iYWNrKHYpOwogICAgICAgIH0KICAgICAgICBlbHNlIGlmIChkZWZpbml0aW9uVHlwZSA9PSBub3JtYWxfZGVmaW5pdGlvbikKICAgICAgICB7CiAgICAgICAgICAgIHZlYzMgdjsKICAgICAgICAgICAgb2JqX2dldF92YWx1ZXMoY3VyU3JjLCB2KTsKICAgICAgICAgICAgbm9ybWFsc18ucHVzaF9iYWNrKHYpOwogICAgICAgIH0KICAgICAgICBlbHNlIGlmIChkZWZpbml0aW9uVHlwZSA9PSBjb2xvcl9kZWZpbml0aW9uKQogICAgICAgIHsKICAgICAgICAgICAgdmVjMyB2OwogICAgICAgICAgICBvYmpfZ2V0X3ZhbHVlcyhjdXJTcmMsIHYpOwogICAgICAgICAgICBjb2xvcnNfLnB1c2hfYmFjayh2KTsKICAgICAgICB9CiAgICAgICAgZWxzZSBpZiAoZGVmaW5pdGlvblR5cGUgPT0gdGV4Y29vcmRfZGVmaW5pdGlvbikKICAgICAgICB7CiAgICAgICAgICAgIHZlYzMgdjsKICAgICAgICAgICAgb2JqX2dldF92YWx1ZXMoY3VyU3JjLCB2KTsKICAgICAgICAgICAgdGV4Y29vcmRzXy5wdXNoX2JhY2sodik7CiAgICAgICAgfQogICAgICAgIGVsc2UgaWYgKGRlZmluaXRpb25UeXBlID09IGluZGV4X2RlZmluaXRpb24pCiAgICAgICAgewogICAgICAgICAgICB1bnNpZ25lZCBzaG9ydCBpZHgoMCk7CiAgICAgICAgICAgIG9ial9nZXRfaW5kZXgoY3VyU3JjLCBpZHgpOwogICAgICAgICAgICBpbmRpY2VzXy5wdXNoX2JhY2soaWR4KTsKICAgICAgICB9CiAgICB9CgogICAgTG9nOjpkZWJ1ZygiT2JqZWN0IHBvcHVsYXRlZCB3aXRoICV1IHZlcnRpY2VzICV1IG5vcm1hbHMgJXUgY29sb3JzICV1IHRleGNvb3JkcyBhbmQgJXUgaW5kaWNlcy5cbiIsCiAgICAgICAgcG9zaXRpb25zXy5zaXplKCksIG5vcm1hbHNfLnNpemUoKSwgY29sb3JzXy5zaXplKCksIHRleGNvb3Jkc18uc2l6ZSgpLCBpbmRpY2VzXy5zaXplKCkpOwogICAgcmV0dXJuIHRydWU7Cn0KCkplbGx5ZmlzaFByaXZhdGU6OkplbGx5ZmlzaFByaXZhdGUoKSA6CiAgICBwb3NpdGlvbkxvY2F0aW9uXygwKSwKICAgIG5vcm1hbExvY2F0aW9uXygwKSwKICAgIGNvbG9yTG9jYXRpb25fKDApLAogICAgdGV4Y29vcmRMb2NhdGlvbl8oMCksCiAgICB2aWV3cG9ydF8oNTEyLjAsIDUxMi4wKSwKICAgIGxpZ2h0UG9zaXRpb25fKDEwLjAsIDQwLjAsIC02MC4wKSwKICAgIGxpZ2h0Q29sb3JfKDAuOCwgMS4zLCAxLjEsIDEuMCksCiAgICBsaWdodFJhZGl1c18oMjAwLjApLAogICAgYW1iaWVudENvbG9yXygwLjMsIDAuMiwgMS4wLCAxLjApLAogICAgZnJlc25lbENvbG9yXygwLjgsIDAuNywgMC42LCAxLjEpLAogICAgZnJlc25lbFBvd2VyXygxLjApLAogICAgcm90YXRpb25fKDAuMCksCiAgICBjdXJyZW50VGltZV8oMC4wKSwKICAgIGxhc3RVcGRhdGVUaW1lXygwLjApLAogICAgY3VsbEZhY2VfKDApLAogICAgZGVwdGhUZXN0XygwKSwKICAgIGJsZW5kXygwKSwKICAgIGJsZW5kRnVuY1NyY18oMCksCiAgICBibGVuZEZ1bmNEc3RfKDApCnsKfQoKSmVsbHlmaXNoUHJpdmF0ZTo6fkplbGx5ZmlzaFByaXZhdGUoKQp7CiAgICBwb3NpdGlvbnNfLmNsZWFyKCk7CiAgICBub3JtYWxzXy5jbGVhcigpOwogICAgY29sb3JzXy5jbGVhcigpOwogICAgdGV4Y29vcmRzXy5jbGVhcigpOwogICAgaW5kaWNlc18uY2xlYXIoKTsKfQoKYm9vbApKZWxseWZpc2hQcml2YXRlOjppbml0aWFsaXplKCkKewogICAgc3RhdGljIGNvbnN0IHN0cmluZyBtb2RlbEZpbGVuYW1lKEdMTUFSS19EQVRBX1BBVEgiL21vZGVscy9qZWxseWZpc2guam9iaiIpOwogICAgaWYgKCFsb2FkX29iaihtb2RlbEZpbGVuYW1lKSkKICAgIHsKICAgICAgICByZXR1cm4gZmFsc2U7CiAgICB9CgogICAgLy8gTm93IHRoYXQgd2UndmUgc2V0dXAgdGhlIHZlcnRleCBkYXRhLCB3ZSBjYW4gc2V0dXAgdGhlIG1hcCBvZiBob3cKICAgIC8vIHRoYXQgZGF0YSB3aWxsIGJlIGxhaWQgb3V0IGluIHRoZSBidWZmZXIgb2JqZWN0LgogICAgc3RhdGljIGNvbnN0IHVuc2lnbmVkIGludCBzdjMoc2l6ZW9mKHZlYzMpKTsKICAgIGRhdGFNYXBfLnBvc2l0aW9uT2Zmc2V0ID0gMDsKICAgIGRhdGFNYXBfLnBvc2l0aW9uU2l6ZSA9IHBvc2l0aW9uc18uc2l6ZSgpICogc3YzOwogICAgZGF0YU1hcF8udG90YWxTaXplID0gZGF0YU1hcF8ucG9zaXRpb25TaXplOwogICAgZGF0YU1hcF8ubm9ybWFsT2Zmc2V0ID0gZGF0YU1hcF8ucG9zaXRpb25PZmZzZXQgKyBkYXRhTWFwXy5wb3NpdGlvblNpemU7CiAgICBkYXRhTWFwXy5ub3JtYWxTaXplID0gbm9ybWFsc18uc2l6ZSgpICogc3YzOwogICAgZGF0YU1hcF8udG90YWxTaXplICs9IGRhdGFNYXBfLm5vcm1hbFNpemU7CiAgICBkYXRhTWFwXy5jb2xvck9mZnNldCA9IGRhdGFNYXBfLm5vcm1hbE9mZnNldCArIGRhdGFNYXBfLm5vcm1hbFNpemU7CiAgICBkYXRhTWFwXy5jb2xvclNpemUgPSBjb2xvcnNfLnNpemUoKSAqIHN2MzsKICAgIGRhdGFNYXBfLnRvdGFsU2l6ZSArPSBkYXRhTWFwXy5jb2xvclNpemU7CiAgICBkYXRhTWFwXy50ZXhjb29yZE9mZnNldCA9IGRhdGFNYXBfLmNvbG9yT2Zmc2V0ICsgZGF0YU1hcF8uY29sb3JTaXplOwogICAgZGF0YU1hcF8udGV4Y29vcmRTaXplID0gdGV4Y29vcmRzXy5zaXplKCkgKiBzdjM7CiAgICBkYXRhTWFwXy50b3RhbFNpemUgKz0gZGF0YU1hcF8udGV4Y29vcmRTaXplOwoKICAgIGxhc3RVcGRhdGVUaW1lXyA9IFV0aWw6OmdldF90aW1lc3RhbXBfdXMoKSAvIDEwMDAuMDsKICAgIGN1cnJlbnRUaW1lXyA9IHN0YXRpY19jYXN0PHVpbnQ2NF90PihsYXN0VXBkYXRlVGltZV8pICUgMTAwMDAwMDAwIC8gMTAwMC4wOwogICAgd2hpY2hDYXVzdGljXyA9IHN0YXRpY19jYXN0PHVpbnQ2NF90PihjdXJyZW50VGltZV8gKiAzMCkgJSAzMiArIDE7CiAgICByb3RhdGlvbl8gPSAwLjA7CgogICAgaWYgKCFncmFkaWVudF8uaW5pdCgpKQogICAgewogICAgICAgIHJldHVybiBmYWxzZTsKICAgIH0KCiAgICAvLyBTZXQgdXAgcHJvZ3JhbSBmaXJzdCBzbyB3ZSBjYW4gc3RvcmUgYXR0cmlidXRlIGFuZCB1bmlmb3JtIGxvY2F0aW9ucwogICAgLy8gYXdheSBmb3IgdGhlIAogICAgdXNpbmcgc3RkOjpzdHJpbmc7CiAgICBzdGF0aWMgY29uc3Qgc3RyaW5nIHZ0eF9zaGFkZXJfZmlsZW5hbWUoR0xNQVJLX0RBVEFfUEFUSCIvc2hhZGVycy9qZWxseWZpc2gudmVydCIpOwogICAgc3RhdGljIGNvbnN0IHN0cmluZyBmcmdfc2hhZGVyX2ZpbGVuYW1lKEdMTUFSS19EQVRBX1BBVEgiL3NoYWRlcnMvamVsbHlmaXNoLmZyYWciKTsKCiAgICBTaGFkZXJTb3VyY2UgdnR4X3NvdXJjZSh2dHhfc2hhZGVyX2ZpbGVuYW1lKTsKICAgIFNoYWRlclNvdXJjZSBmcmdfc291cmNlKGZyZ19zaGFkZXJfZmlsZW5hbWUpOwoKICAgIGlmICghU2NlbmU6OmxvYWRfc2hhZGVyc19mcm9tX3N0cmluZ3MocHJvZ3JhbV8sIHZ0eF9zb3VyY2Uuc3RyKCksCiAgICAgICAgZnJnX3NvdXJjZS5zdHIoKSkpCiAgICB7CiAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgfQoKICAgIC8vIFN0YXNoIGF3YXkgYXR0cmlidXRlIGFuZCB1bmlmb3JtIGxvY2F0aW9ucyBmb3IgaGFuZHkgdXNlLgogICAgcG9zaXRpb25Mb2NhdGlvbl8gPSBwcm9ncmFtX1siYVZlcnRleFBvc2l0aW9uIl0ubG9jYXRpb24oKTsKICAgIG5vcm1hbExvY2F0aW9uXyA9IHByb2dyYW1fWyJhVmVydGV4Tm9ybWFsIl0ubG9jYXRpb24oKTsKICAgIGNvbG9yTG9jYXRpb25fID0gcHJvZ3JhbV9bImFWZXJ0ZXhDb2xvciJdLmxvY2F0aW9uKCk7CiAgICB0ZXhjb29yZExvY2F0aW9uXyA9IHByb2dyYW1fWyJhVGV4dHVyZUNvb3JkIl0ubG9jYXRpb24oKTsKCiAgICAvLyBXZSBuZWVkIDIgYnVmZmVycyBmb3Igb3VyIHdvcmsgaGVyZS4gIE9uZSBmb3IgdGhlIHZlcnRleCBkYXRhLgogICAgLy8gYW5kIG9uZSBmb3IgdGhlIGluZGV4IGRhdGEuCiAgICBnbEdlbkJ1ZmZlcnMoMiwgJmJ1ZmZlck9iamVjdHNfWzBdKTsKCiAgICAvLyBGaXJzdCwgc2V0dXAgdGhlIHZlcnRleCBkYXRhIGJ5IGJpbmRpbmcgdGhlIGZpcnN0IGJ1ZmZlciBvYmplY3QsIAogICAgLy8gYWxsb2NhdGluZyBpdHMgZGF0YSBzdG9yZSwgYW5kIGZpbGxpbmcgaXQgaW4gd2l0aCBvdXIgdmVydGV4IGRhdGEuCiAgICBnbEJpbmRCdWZmZXIoR0xfQVJSQVlfQlVGRkVSLCBidWZmZXJPYmplY3RzX1swXSk7CiAgICBnbEJ1ZmZlckRhdGEoR0xfQVJSQVlfQlVGRkVSLCBkYXRhTWFwXy50b3RhbFNpemUsIDAsIEdMX1NUQVRJQ19EUkFXKTsKICAgIGdsQnVmZmVyU3ViRGF0YShHTF9BUlJBWV9CVUZGRVIsIGRhdGFNYXBfLnBvc2l0aW9uT2Zmc2V0LAogICAgICAgICAgICAgICAgICAgIGRhdGFNYXBfLnBvc2l0aW9uU2l6ZSwgJnBvc2l0aW9uc18uZnJvbnQoKSk7CiAgICBnbEJ1ZmZlclN1YkRhdGEoR0xfQVJSQVlfQlVGRkVSLCBkYXRhTWFwXy5ub3JtYWxPZmZzZXQsCiAgICAgICAgICAgICAgICAgICAgZGF0YU1hcF8ubm9ybWFsU2l6ZSwgJm5vcm1hbHNfLmZyb250KCkpOwogICAgZ2xCdWZmZXJTdWJEYXRhKEdMX0FSUkFZX0JVRkZFUiwgZGF0YU1hcF8uY29sb3JPZmZzZXQsCiAgICAgICAgICAgICAgICAgICAgZGF0YU1hcF8uY29sb3JTaXplLCAmY29sb3JzXy5mcm9udCgpKTsKICAgIGdsQnVmZmVyU3ViRGF0YShHTF9BUlJBWV9CVUZGRVIsIGRhdGFNYXBfLnRleGNvb3JkT2Zmc2V0LAogICAgICAgICAgICAgICAgICAgIGRhdGFNYXBfLnRleGNvb3JkU2l6ZSwgJnRleGNvb3Jkc18uZnJvbnQoKSk7CgogICAgLy8gTm93IHJlcGVhdCBmb3Igb3VyIGluZGV4IGRhdGEuCiAgICBnbEJpbmRCdWZmZXIoR0xfRUxFTUVOVF9BUlJBWV9CVUZGRVIsIGJ1ZmZlck9iamVjdHNfWzFdKTsKICAgIGdsQnVmZmVyRGF0YShHTF9FTEVNRU5UX0FSUkFZX0JVRkZFUiwgaW5kaWNlc18uc2l6ZSgpICogc2l6ZW9mKHVuc2lnbmVkIHNob3J0KSwKICAgICAgICAgICAgICAgICAmaW5kaWNlc18uZnJvbnQoKSwgR0xfU1RBVElDX0RSQVcpOwoKICAgIC8vICJVbmJpbmQiIG91ciBidWZmZXIgb2JqZWN0cyB0byBtYWtlIHN1cmUgdGhlIHN0YXRlIGlzIGNvbnNpc3RlbnQuCiAgICBnbEJpbmRCdWZmZXIoR0xfQVJSQVlfQlVGRkVSLCAwKTsKICAgIGdsQmluZEJ1ZmZlcihHTF9FTEVNRU5UX0FSUkFZX0JVRkZFUiwgMCk7CgogICAgLy8gRmluYWxseSwgc2V0IHVwIG91ciB0ZXh0dXJlcy4KICAgIC8vCiAgICAvLyBGaXJzdCwgdGhlIG1haW4gamVsbHlmaXNoIHRleHR1cmUKICAgIGJvb2wgZ290VGV4ID0gVGV4dHVyZTo6bG9hZCgiamVsbHlmaXNoMjU2IiwgJnRleHR1cmVPYmplY3RzX1swXSwgR0xfTElORUFSLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEdMX0xJTkVBUiwgMCk7CiAgICBpZiAoIWdvdFRleCB8fCB0ZXh0dXJlT2JqZWN0c19bMF0gPT0gMCkKICAgIHsKICAgICAgICBMb2c6OmVycm9yKCJKZWxseWZpc2ggdGV4dHVyZSBzZXQgdXAgZmFpbGVkISEhXG4iKTsKICAgICAgICByZXR1cm4gZmFsc2U7CiAgICB9CiAgICBnbEJpbmRUZXh0dXJlKEdMX1RFWFRVUkVfMkQsIDApOwogICAgLy8gVGhlbiwgdGhlIGNhdXN0aWNzIHRleHR1cmVzCiAgICBzdGF0aWMgY29uc3Qgc3RyaW5nIGJhc2VOYW1lKCJqZWxseWZpc2gtY2F1c3RpY3MtIik7CiAgICBmb3IgKHVuc2lnbmVkIGludCBpID0gMTsgaSA8IDMzOyBpKyspCiAgICB7CiAgICAgICAgc3RkOjpzdHJpbmdzdHJlYW0gc3M7CiAgICAgICAgc3MgPDwgc3RkOjpzZXR3KDIpIDw8IHN0ZDo6c2V0ZmlsbCgnMCcpIDw8IGk7CiAgICAgICAgc3RyaW5nIGN1ck5hbWUoYmFzZU5hbWUpOwogICAgICAgIGN1ck5hbWUgKz0gc3Muc3RyKCk7CiAgICAgICAgZ290VGV4ID0gVGV4dHVyZTo6bG9hZChjdXJOYW1lLCAmdGV4dHVyZU9iamVjdHNfW2ldLCBHTF9MSU5FQVIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBHTF9MSU5FQVIsIDApOwogICAgICAgIGlmICghZ290VGV4IHx8IHRleHR1cmVPYmplY3RzX1tpXSA9PSAwKQogICAgICAgIHsKICAgICAgICAgICAgTG9nOjplcnJvcigiQ2F1c3RpY3MgdGV4dHVyZVsldV0gc2V0IHVwIGZhaWxlZCEhIVxuIiwgaSk7CiAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICB9CiAgICAgICAgZ2xUZXhQYXJhbWV0ZXJpKEdMX1RFWFRVUkVfMkQsIEdMX1RFWFRVUkVfV1JBUF9TLCBHTF9SRVBFQVQpOwogICAgICAgIGdsVGV4UGFyYW1ldGVyaShHTF9URVhUVVJFXzJELCBHTF9URVhUVVJFX1dSQVBfVCwgR0xfUkVQRUFUKTsKICAgICAgICBnbEJpbmRUZXh0dXJlKEdMX1RFWFRVUkVfMkQsIDApOwogICAgfQoKICAgIC8vIFNhdmUgdGhlIEdMIHN0YXRlIHdlIGFyZSBjaGFuZ2luZyBzbyB3ZSBjYW4gcmVzdG9yZSBpdCBsYXRlci4KICAgIGN1bGxGYWNlXyA9IGdsSXNFbmFibGVkKEdMX0NVTExfRkFDRSk7CiAgICBkZXB0aFRlc3RfID0gZ2xJc0VuYWJsZWQoR0xfREVQVEhfVEVTVCk7CiAgICBibGVuZF8gPSBnbElzRW5hYmxlZChHTF9CTEVORCk7CiAgICBnbEdldEludGVnZXJ2KEdMX0JMRU5EX1NSQ19SR0IsICZibGVuZEZ1bmNTcmNfKTsKICAgIGdsR2V0SW50ZWdlcnYoR0xfQkxFTkRfRFNUX1JHQiwgJmJsZW5kRnVuY0RzdF8pOwoKICAgIGdsQmxlbmRGdW5jKEdMX1NSQ19BTFBIQSwgR0xfT05FX01JTlVTX1NSQ19BTFBIQSk7CiAgICBnbEVuYWJsZShHTF9CTEVORCk7CiAgICBnbERpc2FibGUoR0xfQ1VMTF9GQUNFKTsKICAgIGdsRGlzYWJsZShHTF9ERVBUSF9URVNUKTsKCiAgICByZXR1cm4gdHJ1ZTsKfQoKdm9pZApKZWxseWZpc2hQcml2YXRlOjp1cGRhdGVfdmlld3BvcnQoY29uc3QgdmVjMiYgdnApCnsKICAgIGlmICh2aWV3cG9ydF8ueCgpID09IHZwLngoKSAmJiB2aWV3cG9ydF8ueSgpID09IHZwLnkoKSkKICAgIHsKICAgICAgICByZXR1cm47CiAgICB9CiAgICB2aWV3cG9ydF8gPSB2cDsKICAgIHByb2plY3Rpb25fLmxvYWRJZGVudGl0eSgpOwogICAgcHJvamVjdGlvbl8ucGVyc3BlY3RpdmUoMzAuMCwgdmlld3BvcnRfLngoKS92aWV3cG9ydF8ueSgpLCAyMC4wLCAxMjAuMCk7ICAgIAp9Cgp2b2lkCkplbGx5ZmlzaFByaXZhdGU6OnVwZGF0ZV90aW1lKCkKewogICAgZG91YmxlIG5vdyA9IFV0aWw6OmdldF90aW1lc3RhbXBfdXMoKSAvIDEwMDAuMDsKICAgIGRvdWJsZSBlbGFwc2VkVGltZSA9IG5vdyAtIGxhc3RVcGRhdGVUaW1lXzsKICAgIHJvdGF0aW9uXyArPSAoMi4wICogZWxhcHNlZFRpbWUpIC8gMTAwMC4wOwogICAgY3VycmVudFRpbWVfID0gc3RhdGljX2Nhc3Q8dWludDY0X3Q+KG5vdykgJSAxMDAwMDAwMDAgLyAxMDAwLjA7CiAgICB3aGljaENhdXN0aWNfID0gc3RhdGljX2Nhc3Q8dWludDY0X3Q+KGN1cnJlbnRUaW1lXyAqIDMwKSAlIDMyICsgMTsKICAgIGxhc3RVcGRhdGVUaW1lXyA9IG5vdzsKfQoKdm9pZApKZWxseWZpc2hQcml2YXRlOjpjbGVhbnVwKCkKewogICAgLy8gUmVzdG9yZSB0aGUgR0wgc3RhdGUgd2UgY2hhbmdlZCBmb3IgdGhlIHNjZW5lLgogICAgZ2xCbGVuZEZ1bmMoYmxlbmRGdW5jU3JjXywgYmxlbmRGdW5jRHN0Xyk7CiAgICBpZiAoR0xfRkFMU0UgPT0gYmxlbmRfKQogICAgewogICAgICAgIGdsRGlzYWJsZShHTF9CTEVORCk7CiAgICB9CiAgICBpZiAoR0xfVFJVRSA9PSBjdWxsRmFjZV8pCiAgICB7CiAgICAgICAgZ2xFbmFibGUoR0xfQ1VMTF9GQUNFKTsKICAgIH0KICAgIGlmIChHTF9UUlVFID09IGRlcHRoVGVzdF8pCiAgICB7CiAgICAgICAgZ2xFbmFibGUoR0xfREVQVEhfVEVTVCk7CiAgICB9CgogICAgcHJvZ3JhbV8uc3RvcCgpOwogICAgcHJvZ3JhbV8ucmVsZWFzZSgpOwoKICAgIGdsQmluZEJ1ZmZlcihHTF9BUlJBWV9CVUZGRVIsIDApOwogICAgZ2xCaW5kQnVmZmVyKEdMX0VMRU1FTlRfQVJSQVlfQlVGRkVSLCAwKTsKCiAgICBnbERlbGV0ZVRleHR1cmVzKDMzLCAmdGV4dHVyZU9iamVjdHNfWzBdKTsKICAgIGdsRGVsZXRlQnVmZmVycygyLCAmYnVmZmVyT2JqZWN0c19bMF0pOwoKICAgIGdyYWRpZW50Xy5jbGVhbnVwKCk7Cn0KCnZvaWQKSmVsbHlmaXNoUHJpdmF0ZTo6ZHJhdygpCnsKICAgIC8vICJDbGVhciIgdGhlIGJhY2tncm91bmQgdG8gdGhlIGRlc2lyZWQgZ3JhZGllbnQuCiAgICBncmFkaWVudF8uZHJhdygpOwoKICAgIC8vIFdlIG5lZWQgIndvcmxkIiwgIndvcmxkIHZpZXcgcHJvamVjdGlvbiIsIGFuZCAid29ybGQgaW52ZXJzZSB0cmFuc3Bvc2UiCiAgICAvLyBtYXRyaXggdW5pZm9ybXMgZm9yIHRoZSBjdXJyZW50IHNoYWRlci4KICAgIC8vCiAgICAvLyBOT1RFOiBTb21lIG9mIHRoaXMgc2VlbXMgYSBiaXQgb2YgYSBuby1vcCAoZS5nLiwgbXVsdGlweWluZyBieSBhbmQKICAgIC8vICAgICAgIGludmVydGluZyBpZGVudGl0eSBtYXRyaWNlcyksIGJ1dCBsZWF2ZSBpdCBsaWtlIHRoZSBvcmlnaW5hbAogICAgLy8gICAgICAgV2ViR0wgZmlsZXMgZm9yIHRoZSB0aW1lIGJlaW5nLiAgV29ydGggcmV2aXNpdGluZyBub3QgZG9pbmcgYWxsCiAgICAvLyAgICAgICBvZiB0aGF0IG1hdGggZXZlcnkgZHJhdyBjYWxsIChtaWdodCBldmVuIGJlIGdvb2QgdG8gYmUgZG9pbmcKICAgIC8vICAgICAgIHNvbWUgb2YgaXQgaW4gdGhlIHNoYWRlciBhcyB3ZWxsKS4KICAgIHdvcmxkXy5wdXNoKCk7CiAgICB3b3JsZF8udHJhbnNsYXRlKDAuMCwgNS4wLCAtNzUuMCk7CiAgICB3b3JsZF8ucm90YXRlKHNpbihyb3RhdGlvbl8gLyAxMC4wKSAqIDMwLjAsIDAuMCwgMS4wLCAwLjApOwogICAgd29ybGRfLnJvdGF0ZShzaW4ocm90YXRpb25fIC8gMjAuMCkgKiAzMC4wLCAxLjAsIDAuMCwgMC4wKTsKICAgIHdvcmxkXy5zY2FsZSg1LjAsIDUuMCwgNS4wKTsKICAgIHdvcmxkXy50cmFuc2xhdGUoMC4wLCBzaW4ocm90YXRpb25fIC8gMTAuMCkgKiAyLjUsIDAuMCk7CiAgICBtYXQ0IHdvcmxkVmlld1Byb2plY3Rpb24ocHJvamVjdGlvbl8uZ2V0Q3VycmVudCgpKTsKICAgIHdvcmxkVmlld1Byb2plY3Rpb24gKj0gd29ybGRfLmdldEN1cnJlbnQoKTs7CiAgICBtYXQ0IHdvcmxkSW52ZXJzZVRyYW5zcG9zZSh3b3JsZF8uZ2V0Q3VycmVudCgpKTsKICAgIHdvcmxkSW52ZXJzZVRyYW5zcG9zZS5pbnZlcnNlKCkudHJhbnNwb3NlKCk7CgogICAgLy8gTG9hZCB1cCB0aGUgdW5pZm9ybXMKICAgIHByb2dyYW1fLnN0YXJ0KCk7CiAgICBwcm9ncmFtX1sidVdvcmxkIl0gPSB3b3JsZF8uZ2V0Q3VycmVudCgpOwogICAgcHJvZ3JhbV9bInVXb3JsZFZpZXdQcm9qIl0gPSB3b3JsZFZpZXdQcm9qZWN0aW9uOwogICAgcHJvZ3JhbV9bInVXb3JsZEludlRyYW5zcG9zZSJdID0gd29ybGRJbnZlcnNlVHJhbnNwb3NlOwogICAgcHJvZ3JhbV9bInVDdXJyZW50VGltZSJdID0gY3VycmVudFRpbWVfOwogICAgLy8gUmV2aXNpdCBtYWtpbmcgdGhlc2UgY29uc3RhbnRzIHJhdGhlciB0aGFuIHVuaWZvcm1zIGFzIHRoZXkgYXBwZWFyIG5ldmVyCiAgICAvLyB0byBjaGFuZ2UKICAgIHByb2dyYW1fWyJ1TGlnaHRQb3MiXSA9IGxpZ2h0UG9zaXRpb25fOwogICAgcHJvZ3JhbV9bInVMaWdodFJhZGl1cyJdID0gbGlnaHRSYWRpdXNfOwogICAgcHJvZ3JhbV9bInVMaWdodENvbCJdID0gbGlnaHRDb2xvcl87CiAgICBwcm9ncmFtX1sidUFtYmllbnRDb2wiXSA9IGFtYmllbnRDb2xvcl87CiAgICBwcm9ncmFtX1sidUZyZXNuZWxDb2wiXSA9IGZyZXNuZWxDb2xvcl87CiAgICBwcm9ncmFtX1sidUZyZXNuZWxQb3dlciJdID0gZnJlc25lbFBvd2VyXzsKICAgIC8vIFNldCB1cCB0ZXh0dXJlcyBmb3IgdGhpcyBmcmFtZS4KICAgIGdsQWN0aXZlVGV4dHVyZShHTF9URVhUVVJFMCk7CiAgICBnbEJpbmRUZXh0dXJlKEdMX1RFWFRVUkVfMkQsIHRleHR1cmVPYmplY3RzX1swXSk7CiAgICBwcm9ncmFtX1sidVNhbXBsZXIiXSA9IDA7CiAgICBnbEFjdGl2ZVRleHR1cmUoR0xfVEVYVFVSRTEpOwogICAgZ2xCaW5kVGV4dHVyZShHTF9URVhUVVJFXzJELCB0ZXh0dXJlT2JqZWN0c19bd2hpY2hDYXVzdGljX10pOwogICAgcHJvZ3JhbV9bInVTYW1wbGVyMSJdID0gMTsKCiAgICBnbEJpbmRCdWZmZXIoR0xfQVJSQVlfQlVGRkVSLCBidWZmZXJPYmplY3RzX1swXSk7CiAgICBnbEJpbmRCdWZmZXIoR0xfRUxFTUVOVF9BUlJBWV9CVUZGRVIsIGJ1ZmZlck9iamVjdHNfWzFdKTsKCiAgICBnbEVuYWJsZVZlcnRleEF0dHJpYkFycmF5KHBvc2l0aW9uTG9jYXRpb25fKTsKICAgIGdsRW5hYmxlVmVydGV4QXR0cmliQXJyYXkobm9ybWFsTG9jYXRpb25fKTsKICAgIGdsRW5hYmxlVmVydGV4QXR0cmliQXJyYXkoY29sb3JMb2NhdGlvbl8pOwogICAgZ2xFbmFibGVWZXJ0ZXhBdHRyaWJBcnJheSh0ZXhjb29yZExvY2F0aW9uXyk7CiAgICBnbFZlcnRleEF0dHJpYlBvaW50ZXIocG9zaXRpb25Mb2NhdGlvbl8gLCAzLCBHTF9GTE9BVCwgR0xfRkFMU0UsIDAsCiAgICAgICAgcmVpbnRlcnByZXRfY2FzdDxjb25zdCBHTHZvaWQqPihkYXRhTWFwXy5wb3NpdGlvbk9mZnNldCkpOwogICAgZ2xWZXJ0ZXhBdHRyaWJQb2ludGVyKG5vcm1hbExvY2F0aW9uXyAsIDMsIEdMX0ZMT0FULCBHTF9GQUxTRSwgMCwKICAgICAgICByZWludGVycHJldF9jYXN0PGNvbnN0IEdMdm9pZCo+KGRhdGFNYXBfLm5vcm1hbE9mZnNldCkpOwogICAgZ2xWZXJ0ZXhBdHRyaWJQb2ludGVyKGNvbG9yTG9jYXRpb25fICwgMywgR0xfRkxPQVQsIEdMX0ZBTFNFLCAwLAogICAgICAgIHJlaW50ZXJwcmV0X2Nhc3Q8Y29uc3QgR0x2b2lkKj4oZGF0YU1hcF8uY29sb3JPZmZzZXQpKTsKICAgIGdsVmVydGV4QXR0cmliUG9pbnRlcih0ZXhjb29yZExvY2F0aW9uXyAsIDMsIEdMX0ZMT0FULCBHTF9GQUxTRSwgMCwKICAgICAgICByZWludGVycHJldF9jYXN0PGNvbnN0IEdMdm9pZCo+KGRhdGFNYXBfLnRleGNvb3JkT2Zmc2V0KSk7CgogICAgZ2xEcmF3RWxlbWVudHMoR0xfVFJJQU5HTEVTLCBpbmRpY2VzXy5zaXplKCksIEdMX1VOU0lHTkVEX1NIT1JULCAwKTsKCiAgICBnbERpc2FibGVWZXJ0ZXhBdHRyaWJBcnJheShwb3NpdGlvbkxvY2F0aW9uXyk7CiAgICBnbERpc2FibGVWZXJ0ZXhBdHRyaWJBcnJheShub3JtYWxMb2NhdGlvbl8pOwogICAgZ2xEaXNhYmxlVmVydGV4QXR0cmliQXJyYXkoY29sb3JMb2NhdGlvbl8pOwogICAgZ2xEaXNhYmxlVmVydGV4QXR0cmliQXJyYXkodGV4Y29vcmRMb2NhdGlvbl8pOwoKICAgIGdsQmluZEJ1ZmZlcihHTF9BUlJBWV9CVUZGRVIsIDApOwogICAgZ2xCaW5kQnVmZmVyKEdMX0VMRU1FTlRfQVJSQVlfQlVGRkVSLCAwKTsKCiAgICBwcm9ncmFtXy5zdG9wKCk7CiAgICB3b3JsZF8ucG9wKCk7Cn0K