N6Qw7LAKcipCELASNwcwDMMwDMMwDMPA2bdtmN1SBG2R3XaELCURkhv8uKqaRaNFX2/EMVp89NP+FwR9tLZeWtyqezXaBEmAI3gJswAgAAiHxGKhaEwqHNDLBwTgAAsNip4XlJMNSiTSYDASiHEURUEMxUAQxDAQBBmGGGJKMUIAAER59DTpkDEGAAAAAAAAAAAAAAABAAAABAAAAAgAAAApKTsKICAgICAgICBhc3NlcnQhKENvbnRlbnRMZW5ndGgoMCkgPCAxMjMpOwogICAgICAgIGFzc2VydCEoMCA8IENvbnRlbnRMZW5ndGgoMTIzKSk7CiAgICB9Cn0KdXNlIHN0ZDo6c3luYzo6QXJjOwoKdXNlIGFjdGl4X3V0aWxzOi8vLyBUaGUgIkNvbnRlbnQtTGVuZ3RoIiBoZWFkZXIgZmllbGQgaW5kaWNhdGVzIHRoZSBhc3NvY2lhdGVkIHJlcHJlc2VudGF0aW9uJ3MgZGF0YSBsZW5ndGggYXMgYQovLy8gZGVjaW1hbCBub24tbmVnYXRpdmUgaW50ZWdlciBudW1iZXIgb2Ygb2N0ZXRzLgovLy8KLy8vICMgQUJORgovLy8gYGBgcGxhaW4KLy8vIENvbnRlbnQtTGVuZ3RoID0gMSpESUdJVAovLy8gYGBgCi8vLwovLy8gW1JGQyA5MTEwIMKnOC42XTogaHR0cHM6Ly93d3cucmZjLWVkaXRvci5vcmcvcmZjL3JmYzkxMTAjbmFtZS1jb250ZW50LWxlbmd0aAojW2Rlcml2ZShEZWJ1ZywgQ2xvbmUsIFBhcnRpYWxFcSwgRXEsIFBhcnRpYWxPcmQsIE9yZCldCnB1YiBzdHJ1Y3QgQ29udGVudExlbmd0aCh1c2l6ZSk7CgppbXBsIENvbnRlbnRMZW5ndGggewogICAgLy8vIFJldHVybnMgQ29udGVudC1MZW5ndGggdmFsdWUuCiAgICBwdWIgZm4gaW50b19pbm5lcigmc2VsZikgLT4gdXNpemUgewogICAgICAgIHNlbGYuMAogICAgfQp9CgppbXBsIHN0cjo6RnJvbVN0ciBmb3IgQ29udGVudExlbmd0aCB7CiAgICB0eXBlIEVyciA9IDx1c2l6ZSBhcyBzdHI6OkZyb21TdHI+OjpFcnI7CgogICAgI1tpbmxpbmVdCiAgICBmbiBmcm9tX3N0cih2YWw6ICZzdHIpIC0+IFJlc3VsdDxTZWxmLCBTZWxmOjpFcnI+IHsKICAgICAgICBsZXQgdmFsID0gdmFsLnRyaW0oKTsKCiAgICAgICAgLy8gZGVjb2RlciBwcmV2ZW50cyB0aGlzIGNhc2UKICAgICAgICBkZWJ1Z19hc3NlcnQhKCF2YWwuc3RhcnRzX3dpdGgoJysnKSk7CgogICAgICAgIHZhbC5wYXJzZSgpLm1hcChTZWxmKQogICAgfQp9CgppbXBsIFRyeUludG9IZWFkZXJWYWx1ZSBmb3IgQ29udGVudExlbmd0aCB7CiAgICB0eXBlIEVycm9yID0gSW5mYWxsaWJsZTsKCiAgICBmbiB0cnlfaW50b192YWx1ZShzZWxmKSAtPiBSZXN1bHQ8SGVhZGVyVmFsdWUsIFNlbGY6OkVycm9yPiB7CiAgICAgICAgT2soSGVhZGVyVmFsdWU6OmZyb20oc2VsZi4wKSkKICAgIH0KfQoKaW1wbCBIZWFkZXIgZm9yIEMvCi8vLyBBbHNvIHNlZSB0aGUgW0ZvcndhcmRlZCBoZWFkZXIncyBNRE4gZG9jc11bbWRuXSBmb3IgZmllbGQgc2VtYW50aWNzLgovLy8KLy8vIFtSRkMgNzIzOV06IGh0dHBzOi8vZGF0YXRyYWNrZXIuaWV0Zi5vcmcvZG9jL2h0bWwvcmZjNzIzOQovLy8gW21kbl06IGh0dHBzOi8vZGV2ZWxvcGVyLm1vemlsbGEub3JnL2VuLVVTL2RvY3MvV2ViL0hUVFAvSGVhZGVycy9Gb3J3YXJkZWQKI1tkZXJpdmUoRGVidWcsIENsb25lLCBQYXJ0aWFsRXEsIEVxLCBQYXJ0aWFsT3JkLCBPcmQpXQojW2NmZ19hdHRyKHRlc3QsIGRlcml2ZShEZWZhdWx0KSldCnB1YiBzdHJ1Y3QgRm9yd2FyZGVkIHsKICAgIC8vLyBUaGUgaW50ZXJmYWNlIHdoZXJlIHRoZSByZXF1ZXN0IGNhbWUgaW4gdG8gdGhlIHByb3h5IHNlcnZlci4gVGhlIGlkZW50aWZpZXIgY2FuIGJlOgogICAgLy8vCiAgICAvLy8gLSBhbiBvYmZ1c2NhdGVkIGlkZW50aWZpZXIgKHN1Y2ggYXMgImhpZGRlbiIgb3IgInNlY3JldCIpLiBUaGlzIHNob3VsZCBiZSB0cmVhdGVkIGFzIHRoZQogICAgLy8vICAgZGVmYXVsdC4KICAgIC8vLyAtIGFuIElQIGFkZHJlc3MgKHY0IG9yIHY2LCBvcHRpb25hbGx5IHdpdGggYSBwb3J0LiBJUHY2IGFkZHJlc3MgYXJlIHF1b3RlZCBhbmQgZW5jbG9zZWQgaW4KICAgIC8vLyAgIHNxdWFyZSBicmFja2V0cykKICAgIC8vLyAtICJ1bmtub3duIiB3aGVuIHRoZSBwcmVjZWRpbmcgZW50aXR5IGlzIG5vdCBrbm93biAoYW5kIHlvdSBzdGlsbCB3YW50IHRvIGluZGljYXRlIHRoYXQKICAgIC8vLyAgIGZvcndhcmRpbmcgb2YgdGhlIHJlcXVlc3Qgd2FzIG1hZGUpCiAgICBieTogT3B0aW9uPFN0cmluZz4sCgogICAgLy8vIFRoZSBjbGllbnQgdGhhdCBpbml0aWF0ZWQgdGhlIHJlcXVlc3QgYW5kIHN1YnNlcXVlbnQgcHJveGllcyBpbiBhIGNoYWluIG9mIHByb3hpZXMuIFRoZQogICAgLy8vIGlkZW50aWZpZXIgaGFzIHRoZSBzYW1lIHBvc3NpYmxlIHZhbHVlcyBhcyB0aGUgYnkgZGlyZWN0aXZlLgogICAgciNmb3I6IFZlYzxTLmFzX211dCgpLnByb2plY3QoKSB7CiAgICAgICAgICAgIEJvZHlIYXNoRnV0UHJvajo6UGF5bG9hZE5vbmUgeyBpbm5lcl9mdXQsIGhhc2ggfSA9PiB7CiAgICAgICAgICAgICAgICBsZXQgaW5uZXIgPSByZWFkeSEoaW5uZXJfZnV0LnBvbGwoY3gpKT87CiAgICAgICAgICAgICAgICBQb2xsOjpSZWFkeShPayhCb2R5SGFzaCB7CiAgICAgICAgICAgICAgICAgICAgaW5uZXIsCiAgICAgICAgICAgICAgICAgICAgaGFzaDogbWVtOjp0YWtlKGhhc2gpLAogICAgICAgICAgICAgICAgfSkpCiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIEJvZHlIYXNoRnV0UHJvajo6SW5uZXIgewogICAgICAgICAgICAgICAgaW5uZXJfZnV0LAogICAgICAgICAgICAgICAgaGFzaGVyLAogICAgICAgICAgICAgICAgbXV0IGZvcmtlZF9wYXlsb2FkLAogICAgICAgICAgICB9ID0+IHsKICAgICAgICAgICAgICAgIC8vIHBvbGwgb3JpZ2luYWwgZXh0cmFjdG9yCiAgICAgICAgICAgICAgICBtYXRjaCBpbm5lcl9mdXQucG9sbChjeCk/IHsKICAgICAgICAgICAgICAgICAgICBQb2xsOjpSZWFkeShpbm5lcikgPT4gewogICAgICAgICAgICAgICAgICAgICAgICB0cmFjZSEoImlubmVyIGV4dHJhY3RvciBjb21wbGV0ZSIpOwoKICAgICAgICAgICAgICAgICAgICAgICAgbGV0IG5leHQgPSBCb2R5SGFzaEZ1dDo6SW5uZXJEb25lIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlubmVyOiBTb21lKGlubmVyKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGhhc2hlcjogbWVtOjpyZXBsYWNlKGhhc2hlciwgRDo6bmV3KCkpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgZm9ya2VkX3BheWxvYWQ6IG1lbTo6cmVwbGFjZShmb3JrZWRfcGF5bG9hZCwgZGV2OjpQYXlsb2FkOjpOb25lKSwKICAgICAgICAgICAgICAgICAgICAgICAgfTsKICAgICAgICAgICAgICAgICAgICAgICAgc2VsZi5zZXQobmV4dCk7CgogICAgICAgICAgICAgICAgICAgICAgICAvLyByZS1lbnRlciBwb2xsIGluIGRvbmUgc3RhdGUKICAgIENyZWF0ZSBhIHJlbGF0aXZlIG9yIGFic29sdXRlIHJlZGlyZWN0LgovLy8KLy8vIF9UaGlzIGZlYXR1cmUgaGFzIFtncmFkdWF0ZWQgdG8gQWN0aXggV2ViXVtncmFkdWF0ZWRdLiBGdXJ0aGVyIGRldmVsb3BtZW50IHdpbGwgb2NjdXIgdGhlcmUuXwovLy8KLy8vIFNlZSBbYFJlZGlyZWN0YF0gZG9jcyBmb3IgdXNhZ2UgZGV0YWlscy4KLy8vCi8vLyAjIEV4YW1wbGVzCi8vLyBgYGAKLy8vIHVzZSBhY3RpeF93ZWI6OkFwcDsKLy8vIHVzZSBhY3RpeF93ZWJfbGFiOjp3ZWIgYXMgd2ViX2xhYjsKLy8vCi8vLyBsZXQgYXBwID0gQXBwOjpuZXcoKQovLy8gICAgIC5zZXJ2aWNlKHdlYl9sYWI6OnJlZGlyZWN0KCIvb25lIiwgIi90d28iKSk7Ci8vLyBgYGAKLy8vCi8vLyBbZ3JhZHVhdGVkXTogaHR0cHM6Ly9kb2NzLnJzL2FjdGl4LXdlYi80L2FjdGl4X3dlYi93ZWIvc3RydWN0LlJlZGlyZWN0Lmh0bWwKI1thbGxvdyhkZXByZWNhdGVkKV0KI1tkZXByZWNhdGVkKHNpbmNlID0gIjAuMTkuMCIsIG5vdGUgPSAiVHlwZSBoYXMgZ3JhZHVhdGVkIHRvIEFjdGl4IFdlYi4iKV0KcHViIGZuIHJlZGlyZWN0KGZyb206IGltcGwgSW50bzxDb3c8J3N0YXRpYywgc3RyPj4sIHRvOiBpbXBsIEludG88Q293PCdzdGF0aWMsIHN0cj4+KSAtPiBSZWRpcmVjdCB7CiAgICBSZWRpcmVjdDo6bmV3KGZyb20sIHRvKQp9CgovLy8gQ29uc3RydWN0cyBhIG5ldyBTaW5nbGUtcGFnZSBBcHBsaWNhdGlvbiAoU1BBKSBidWlsZGVyLgovLy8KLy8vIFNlZSBbYFNwYWBdIGRvY3MgZm9yIG1vcmUgZGV0YWlscy4KLy8vCi8vLyAjIEV4YW1wbGVzCi8vLyBgYGAKLy8vICMgdXNlIGFjdGl4X3dlYjo6QXBwOwovLy8gIyB1c2UgYWN0aXhfd2ViX2xhYjo6d2ViOjpzcGE7Ci8vLyBsZXQgYXBwID0gQXBwOjpuZXcoKQovLy8gICAgIC8vIC4uLmFwaSByb3V0ZXMuLi4KLy8vICAgICAuc2VydmljZSgKLy8vICAgICAgICAgc3BhKCkKLy8vICAgICAgICAgICAgIC5pbmRleF9maWxlKCIuL2V4YW1wbGVzL2Fzc2V0cy9zcGEuaHRtbCIpCi8vLyAgICAgICAgICAgICAgICBmdXQ6IENlbGw6Om5ldyhTb21lKEJveDo6cGluKGluaXQoKSkpKSwKICAgICAgICAgICAgfSksCiAgICAgICAgfQogICAgfQoKICAgIC8vLyBSZXR1cm5zIHJlZmVyZW5jZSB0byByZXN1bHQgb2YgbGF6eSBgVGAgdmFsdWUsIGluaXRpYWxpemluZyBpZiBuZWNlc3NhcnkuCiAgICBwdWIgYXN5bmMgZm4gZ2V0KCZzZWxmKSAtPiAmVCB7CiAgICAgICAgc2VsZi5pbm5lcgogICAgICAgICAgICAuY2VsbAogICAgICAgICAgICAuZ2V0X29yX2luaXQofHwgYXN5bmMgbW92ZSB7CiAgICAgICAgICAgICAgICBtYXRjaCBzZWxmLmlubmVyLmZ1dC50YWtlKCkgewogICAgICAgICAgICAgICAgICAgIFNvbWUoZnV0KSA9PiBmdXQuYXdhaXQsCiAgICAgICAgICAgICAgICAgICAgTm9uZSA9PiBwYW5pYyEoIkxhenlEYXRhIGluc3RhbmNlIGhhcyBwcmV2aW91c2x5IGJlZW4gcG9pc29uZWQiKSwKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfSkKICAgICAgICAgICAgLmF3YWl0CiAgICB9Cn0KCmltcGw8VDogJ3N0YXRpYz4gRnJvbVJlcXVlc3QgZm9yIExhenlEYXRhPFQ+IHsKICAgIHR5cGUgRXJyb3IgPSBFcnJvcjsKICAgIHR5cGUgRnV0dXJlID0gUmVhZHk8UmVzdWx0PFNlbGYsIEVycm9yPj47CgogICAgI1tpbmxpbmVdCiAgICBmbiBmcm9tX3JlcXVlc3QocmVxOiAmSHR0cFJlcXVlc3QsIF86ICZtdXQgZGV2OjpQYXlsb2FkKSAtPiBTZWxmOjpGdXR1cmUgewogICAgICAgIGlmIGxldCBTb21lKGxhenkpID0gcmVxLmFwcF9kYXRhOjo8TGF6eURhdGE8VD4+KCkgewogICAgICAgICAgICByZWFkeShPayhsYXp5LmNsb25lKCkpKQogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIGRlYnVnISgKICAgICAgICAgICAgICAgICJGYWlsZWQgdG8gZXh0cmFjdCBgTGF6eURhdGE8e30+YCBmb3IgYHt9YCBoYW5kbGVyLiBGb3IgdGhlIERhdGEgZXh0cmFjdG9yIHRvIHdvcmsgXAogICAgICAgICAgICAgICAgY29ycmVjdGx5LCB3cmFwIHRoZSBkYXRhIHdpdGggYExhenlEYXRhOjpucmVxLmhlYWRlcnMoKS5nZXQoIkxhc3QtRXZlbnQtSUQiKSk7CgogICAgY29tbW9uX2NvdW50ZG93bihuLnRyeV9pbnRvKCkudW53cmFwKCkpCn0KCmZuIGNvbW1vbl9jb3VudGRvd24objogaTMyKSAtPiBpbXBsIFJlc3BvbmRlciB7CiAgICBsZXQgY291bnRkb3duX3N0cmVhbSA9IHN0cmVhbTo6dW5mb2xkKChmYWxzZSwgbiksIHwoc3RhcnRlZCwgbil8IGFzeW5jIG1vdmUgewogICAgICAgIC8vIGFsbG93IGZpcnN0IGNvdW50ZG93biB2YWx1ZSB0byB5aWVsZCBpbW1lZGlhdGVseQogICAgICAgIGlmIHN0YXJ0ZWQgewogICAgICAgICAgICBzbGVlcChEdXJhdGlvbjo6ZnJvbV9zZWNzKDEpKS5hd2FpdDsKICAgICAgICB9CgogICAgICAgIGlmIG4gPiAwIHsKICAgICAgICAgICAgbGV0IGRhdGEgPSBzc2U6OkRhdGE6Om5ldyhuLnRvX3N0cmluZygpKQogICAgICAgICAgICAgICAgLmV2ZW50KCJjb3VudGRvd24iKQogICAgICAgICAgICAgICAgLmlkKG4udG9fc3RyaW5nKCkpOwoKICAgICAgICAgICAgU29tZSgoT2s6OjxfLCBJbmZhbGxpYmxlPihzc2U6OkV2ZW50OjpEYXRhKGRhdGEpKSwgKHRydWUsIG4gLSAxKSkpCiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgTm9uZQogICAgICAgIH0KICAgIH0pOwoKICAgIHNzZTo6U3NlOjpmcm9tX3N0cmVhbShjb3VudGRvd25fc3RyZWFtKS53aXRoX3JldHJ5X2R1cmF0aW9uKER1cmF0aW9uOjpmcm9tX3NlY3MoNSkpCn0KCiNbZ2V0KCIvdGltZSIpXQphc3luYyBmbiB0aW1lc3RhbXAoKSAtPiBpbXBsIFJlc3BvbmRlciB7CiAgICBsZXQgKHNlbmRlciwgc3NlKSA9IHNzZTo6Y2hhbm5lbCgyKTsKCiAgICBhY3RpeF93ZWI6OnJ0OjpzcGF3bihhc3luYyBtb3ZlIHsKICAgICAgICBsb29wIHsKICAgICAgICAgICAgbGV0IHRpbWUgPSB0aW1lOjpPZmZzZXREYXRlVGltZTo6bm93X3V0YygpOwogICAgICAgICAgICBsZXQgbXNnID0gc3NlOjpEYXRhOjpuZXcodGltZS5mb3JtYXQoJlJmYzMzMzkpLnVud3JhcCgpKS5ldmVudCgidGltZXN0YW1wIik7CgogIGRlcigoCiAgICAgICAgICAgICAgICBoZWFkZXI6OkNPTlRFTlRfTEVOR1RILAogICAgICAgICAgICAgICAgaGVhZGVyOjpIZWFkZXJWYWx1ZTo6ZnJvbV9zdGF0aWMoIjkiKSwKICAgICAgICAgICAgKSkKICAgICAgICAgICAgLnNldF9wYXlsb2FkKEJ5dGVzOjpmcm9tX3N0YXRpYyhiIm5hbWU9dGVzdCIpKQogICAgICAgICAgICAudG9faHR0cF9wYXJ0cygpOwogICAgICAgIGxldCBzID0gVXJsRW5jb2RlZEZvcm06OjxNeU9iamVjdCwgOD46OmZyb21fcmVxdWVzdCgmcmVxLCAmbXV0IHBsKS5hd2FpdDsKICAgICAgICBsZXQgZXJyID0gZm9ybWF0ISgie30iLCBzLnVud3JhcF9lcnIoKSk7CiAgICAgICAgYXNzZXJ0ISgKICAgICAgICAgICAgZXJyLmNvbnRhaW5zKCJwYXlsb2FkIGlzIGxhcmdlciIpICYmIGVyci5jb250YWlucygidGhhbiBhbGxvd2VkIiksCiAgICAgICAgICAgICJ1bmV4cGVjdGVkIGVycm9yIHN0cmluZzoge2Vycjo/fSIKICAgICAgICApOwogICAgfQoKICAgICNbYWN0aXhfd2ViOjp0ZXN0XQogICAgYXN5bmMgZm4gdGVzdF9mb3JtX2JvZHkoKSB7CiAgICAgICAgbGV0IChyZXEsIG11dCBwbCkgPSBUZXN0UmVxdWVzdDo6ZGVmYXVsdCgpLnRvX2h0dHBfcGFydHMoKTsKICAgICAgICBsZXQgZm9ybSA9CiAgICAgICAgICAgIFVybEVuY29kZWRGb3JtQm9keTo6PE15T2JqZWN0LCBERUZBVUxUX1VSTF9FTkNPREVEX0ZPUk1fTElNSVQ+OjpuZXcoJnJlcSwgJm11dCBwbCkKICAgICAgICAgICAgICAgIC5hd2FpdDsKICAgICAgICBhc3NlcnQhKGVycl9lcShmb3JtLnVud3JhcF9lcnIoKSwgVXJsZW5jb2RlZEVycm9yOjpDb250ZW50VHlwZSkpOwoKICAgICAgICBsZXQgKHJlcSwgbXV0IHBsKSA9IFRlc3RSZXF1ZXN0OjpkZWZhdWx0KCkKICAgICAgICAgICAgLmluc2VydF9oZWFkZXIoKAogICAgICAgICAgICAgICAgaGVhZGVyOjpDT05URU5UX1RZUEUsCiAgICAgICAgICAgICAgICBoZWFkZXI6OkhlYWRlclZhbHVlOjpmcm9tX3N0YXRpYygiYXBwbGljYXRpb24vdGV4dCIpLAogICBpeF93ZWI6OnRlc3RdCiAgICBhc3luYyBmbiBjb21wYXRfY29tcGF0KCkgewogICAgICAgIGxldCBfID0gQXBwOjpuZXcoKS53cmFwKENvbXBhdDo6bmV3KGZyb21fZm4obm9vcCkpKTsKICAgICAgICBsZXQgXyA9IEFwcDo6bmV3KCkud3JhcChDb21wYXQ6Om5ldyhmcm9tX2ZuKG11dGF0ZV9ib2R5X3R5cGUpKSk7CiAgICB9CgogICAgI1thY3RpeF93ZWI6OnRlc3RdCiAgICBhc3luYyBmbiBmZWVsc19nb29kKCkgewogICAgICAgIGxldCBhcHAgPSB0ZXN0Ojppbml0X3NlcnZpY2UoCiAgICAgICAgICAgIEFwcDo6bmV3KCkKICAgICAgICAgICAgICAgIC53cmFwKGZyb21fZm4obXV0YXRlX2JvZHlfdHlwZSkpCiAgICAgICAgICAgICAgICAud3JhcChmcm9tX2ZuKGFkZF9yZXNfaGVhZGVyKSkKICAgICAgICAgICAgICAgIC53cmFwKExvZ2dlcjo6ZGVmYXVsdCgpKQogICAgICAgICAgICAgICAgLndyYXAoZnJvbV9mbihub29wKSkKICAgICAgICAgICAgICAgIC5kZWZhdWx0X3NlcnZpY2Uod2ViOjp0byhIdHRwUmVzcG9uc2U6Ok5vdEZvdW5kKSksCiAgICAgICAgKQogICAgICAgIC5hd2FpdDsKCiAgICAgICAgbGV0IHJlcSA9IHRlc3Q6OlRlc3RSZXF1ZXN0OjpkZWZhdWx0KCkudG9fcmVxdWVzdCgpOwogICAgICAgIGxldCByZXMgPSB0ZXN0OjpjYWxsX3NlcnZpY2UoJmFwcCwgcmVxKS5hd2FpdDsKICAgICAgICBhc3NlcnQhKHJlcy5oZWFkZXJzKCkuY29udGFpbnNfa2V5KGhlYWRlcjo6V0FSTklORykpOwogICAgfQoKICAgICNbYWN0aXhfd2ViOjp0ZXN0XQogICAgYXN5bmMgZm4gY2xvc3VyZV9jYXB0dXJlX2FuZF9yZXR1cm5fZnJvbV9mbigpIHsKICAgICAgICBsZXQgYXBwID0gdGVzdDo6aW5pdF9zZXJ2aWNlKAogICAgICAgICAgICBBcHA6Om5ldygpCiAgICAgICAgICAgICAgICAud3JhcChMb2dnZXI6OmRlZmF1bHQoKSkKICAgICAgICAgICAgICAgIC53cmFwKE15TXcodHJ1ZSkuaW50b19taWRkbGV3YXJlKCkpCiAgICAgICAgICAgICAgICAud3JhcChMb2dnZXI6OmRlZmF1bHQoKSksCiAgICAgICAgICAgICAgICAgZnV0OiBCb3g6OnBpbihUOjpmcm9tX3JlcXVlc3QocmVxLCBwYXlsb2FkKSksCiAgICAgICAgICAgICAgICBjb3VudGVyX3BsOiBjb3VudGVyLAogICAgICAgICAgICAgICAgc2l6ZTogMCwKICAgICAgICAgICAgfSwKICAgICAgICB9CiAgICB9Cn0KCnB1YiBzdHJ1Y3QgQm9keUxpbWl0RnV0PFQsIGNvbnN0IExJTUlUOiB1c2l6ZT4Kd2hlcmUKICAgIFQ6IEZyb21SZXF1ZXN0ICsgJ3N0YXRpYywKICAgIFQ6OkVycm9yOiBmbXQ6OkRlYnVnICsgZm10OjpEaXNwbGF5LAp7CiAgICBpbm5lcjogSW5uZXI8VCwgTElNSVQ+LAp9CgppbXBsPFQsIGNvbnN0IExJTUlUOiB1c2l6ZT4gQm9keUxpbWl0RnV0PFQsIExJTUlUPgp3aGVyZQogICAgVDogRnJvbVJlcXVlc3QgKyAnc3RhdGljLAogICAgVDo6RXJyb3I6IGZtdDo6RGVidWcgKyBmbXQ6OkRpc3BsYXksCnsKICAgIGZuIG5ld19lcnJvcihlcnI6IEJvZHlMaW1pdEVycm9yPFQ+KSAtPiBTZWxmIHsKICAgICAgICBTZWxmIHsKICAgICAgICAgICAgaW5uZXI6IElubmVyOjpFcnJvciB7IGVycjogU29tZShlcnIpIH0sCiAgICAgICAgfQogICAgfQp9CgplbnVtIElubmVyPFQsIGNvbnN0IExJTUlUOiB1c2l6ZT4Kd2hlcmUKICAgIFQ6IEZyb21SZXF1ZXN0ICsgJ3N0YXRpYywKICAgIFQ6OkVycm9yOiBmbXQ6OkRlYnVnICsgZm10OjpEaXNwbGF5LAp7CiAgICBFcnJvciB7CiAgICAgICAgZXJyOiBPcHRpb248Qm9keUxpbWl0RXJyb3I8VD4+LAogICAgfSwKCiAgICBCb2R5IHsKICAgICAgICAvLy8gV3JhcHBlZCBleHRyYWN0b3IgZnV0dXJlLgogICAgICAgIGZ1dDogUGluPEJveDxUOjpGdXR1cmU+PiwKCiAgICAgICAgLy8vIEZvcmtlZCByZXF1ZXN0IHBheWxvYWQuCiAgICAgICAgY291bnRlcl9wbDogZGV2OjpQYXlsb2FkLAoKICAgICAgICAvLy8gUnVubmluZyBwYXlsb2FkIHNpemUgY291bnQuCiAgICAgICAgc2l6ZTogdXNpemUsCiAgICB9LAp9CgppbXBsPFQsIGNvbnN0IExJTUlUOiB1c2l6ZT4gVW5waW4gZm9yIElubmVyPAp1c2UgY3JhdGU6OnV0aWw6OntJbmZhbGxpYmxlU3RyZWFtLCBNdXRXcml0ZXJ9OwoKcGluX3Byb2plY3QhIHsKICAgIC8vLyBBIGJ1ZmZlcmVkIENTViBzZXJpYWxpemluZyBib2R5IHN0cmVhbS4KICAgIC8vLwogICAgLy8vIFRoaXMgaGFzIHNpZ25pZmljYW50IG1lbW9yeSBlZmZpY2llbmN5IGFkdmFudGFnZXMgb3ZlciByZXR1cm5pbmcgYW4gYXJyYXkgb2YgQ1NWIHJvd3Mgd2hlbgogICAgLy8vIHRoZSBkYXRhIHNldCBpcyB2ZXJ5IGxhcmdlIGJlY2F1c2UgaXQgYXZvaWRzIGJ1ZmZlcmluZyB0aGUgZW50aXJlIHJlc3BvbnNlLgogICAgLy8vCiAgICAvLy8gIyBFeGFtcGxlcwogICAgLy8vIGBgYAogICAgLy8vICMgdXNlIGFjdGl4X3dlYjo6UmVzcG9uZGVyOwogICAgLy8vICMgdXNlIGFjdGl4X3dlYl9sYWI6OnJlc3BvbmQ6OkNzdjsKICAgIC8vLyAjIHVzZSBmdXR1cmVzX2NvcmU6OlN0cmVhbTsKICAgIC8vLyBmbiBzdHJlYW1pbmdfZGF0YV9zb3VyY2UoKSAtPiBpbXBsIFN0cmVhbTxJdGVtID0gW1N0cmluZzsgMl0+IHsKICAgIC8vLyAgICAgLy8gZ2V0IGl0ZW0gc3RyZWFtIGZyb20gc291cmNlCiAgICAvLy8gICAgICMgZnV0dXJlc191dGlsOjpzdHJlYW06OmVtcHR5KCkKICAgIC8vLyB9CiAgICAvLy8KICAgIC8vLyBhc3luYyBmbiBoYW5kbGVyKCkgLT4gaW1wbCBSZXNwb25kZXIgewogICAgLy8vICAgICBsZXQgZGF0YV9zdHJlYW0gPSBzdHJlYW1pbmdfZGF0YV9zb3VyY2UoKTsKICAgIC8vLwogICAgLy8vICAgICBDc3Y6Om5ld19pbmZhbGxpYmxlKGRhdGFfc3RyZWFtKQogICAgLy8vICAgICAgICAgLmludG9fcmVzcG9uZGVyKCkKICAgIC8vLyB9CiAgICAvLy8gYGBgCiAgICBwdWIgc3RydWN0IENzdjxTPiB7CiAgICAgICAgLy8gVGhlIHdyYXBwZWQgaXRlbSBzdHJlYW0uCiAgICAgICAgI1twaW5dCiAgICAgICAgc3RyZWFtOiBTLAogICAgfQp9CgppbXBsPFM+IENzdjxTPiB7CiAgICAvLy8gQ29uc3RydWN0cyBhIG5ldyBgQ3N2YCBmcm9tIGEgc3RyZWFtIG9mIHJvd3MuCiAgICBzdHJpbmcuIEV4YW1wbGU6IGAvdXNlcnM/bj0xMDBgLgovLyEKLy8hIEFsc28gaW5jbHVkZXMgYSBsb3ctZWZmaWNpZW5jeSByb3V0ZSB0byBkZW1vbnN0cmF0ZSB0aGUgZGlmZmVyZW5jZS4KCnVzZSBzdGQ6OmlvOjp7c2VsZiwgV3JpdGUgYXMgX307Cgp1c2UgYWN0aXhfd2ViOjp7CiAgICBnZXQsCiAgICB3ZWI6OntzZWxmLCBCdWZNdXQgYXMgXywgQnl0ZXNNdXR9LAogICAgQXBwLCBIdHRwUmVzcG9uc2UsIEh0dHBTZXJ2ZXIsIFJlc3BvbmRlciwKfTsKdXNlIGFjdGl4X3dlYl9sYWI6OnJlc3BvbmQ6Ok5kSnNvbjsKdXNlIGZ1dHVyZXNfY29yZTo6U3RyZWFtOwp1c2UgZnV0dXJlc191dGlsOjp7c3RyZWFtLCBTdHJlYW1FeHQgYXMgX307CnVzZSByYW5kOjp7ZGlzdHJpYnV0aW9uczo6QWxwaGFudW1lcmljLCBSbmcgYXMgX307CnVzZSBzZXJkZTo6RGVzZXJpYWxpemU7CnVzZSBzZXJkZV9qc29uOjpqc29uOwp1c2UgdHJhY2luZzo6aW5mbzsKCmZuIHN0cmVhbWluZ19kYXRhX3NvdXJjZShuOiB1MzIpIC0+IGltcGwgU3RyZWFtPEl0ZW0gPSBSZXN1bHQ8c2VyZGVfanNvbjo6VmFsdWUsIGlvOjpFcnJvcj4+IHsKICAgIHN0cmVhbTo6cmVwZWF0X3dpdGgofHwgewogICAgICAgIE9rKGpzb24hKHsKICAgICAgICAgICAgImVtYWlsIjogcmFuZG9tX2VtYWlsKCksCiAgICAgICAgICAgICJhZGRyZXNzIjogcmFuZG9tX2FkZHJlc3MoKSwKICAgICAgICB9KSkKICAgIH0pCiAgICAudGFrZShuIGFzIHVzaXplKQp9CgojW2Rlcml2ZShEZWJ1ZywgRGVzZXJpYWxpemUpXQpzdHJ1Y3QgT3B0cyB7CiAgICBuOiBPcHRpb248dTMyPiwKfQoKLy8vIFRoaXMgaGFuZGxlciBzdHJlYW1zIGRhdGEgYXMgTkRKU09OIHRvIHRoZSBjbGllbnQgaW4gYSBmYXN0IGFuZCBtZW1vcnkgZWZmaWNpZW50IHdheS4KLy8vCi8vLyBBIHJlYWwgZGF0YSBzb3VyY2UgbWlnaHQgYmUgYSBkb3duc3RyZWFtIHNlcnZlciwgZGF0YWJhc2UgcXVlcnksIG9yIG90aGVyIGV4dGVybmFsIHJlc291cmNlLgojW2dldCgiL3VzZXJzIildCmFzICAgICBib2R5LAogICAgICAgIGhleCEoCiAgICAgICAgICAgICJjZjgzZTEzNSA3ZWVmYjhiZCBmMTU0Mjg1MCBkNjZkODAwNyBkNjIwZTQwNSAwYjU3MTVkYyA4M2Y0YTkyMSBkMzZjZTljZQogICAgICAgICAgICAgNDdkMGQxM2MgNWQ4NWYyYjAgZmY4MzE4ZDIgODc3ZWVjMmYgNjNiOTMxYmQgNDc0MTdhODEgYTUzODMyN2EgZjkyN2RhM2UiCiAgICAgICAgKQogICAgICAgIC5hc19yZWYoKQogICAgKTsKCiAgICBsZXQgKHJlcSwgXykgPQogICAgICAgIHRlc3Q6OlRlc3RSZXF1ZXN0OjpkZWZhdWx0KCkKICAgICAgICAgICAgLnRvX3JlcXVlc3QoKQogICAgICAgICAgICAucmVwbGFjZV9wYXlsb2FkKGRldjo6UGF5bG9hZDo6U3RyZWFtIHsKICAgICAgICAgICAgICAgIHBheWxvYWQ6IEJveDo6cGluKAogICAgICAgICAgICAgICAgICAgIHN0cmVhbTo6aXRlcihbYiJhIiwgYiJiIiwgYiJjIl0ubWFwKHxifCBCeXRlczo6ZnJvbV9zdGF0aWMoYikpKS5tYXAoT2spLAogICAgICAgICAgICAgICAgKSBhcyBCb3hlZFBheWxvYWRTdHJlYW0sCiAgICAgICAgICAgIH0pOwoKICAgIGxldCBib2R5ID0gdGVzdDo6Y2FsbF9hbmRfcmVhZF9ib2R5KCZhcHAsIHJlcSkuYXdhaXQ7CiAgICBhc3NlcnRfZXEhKAogICAgICAgIGJvZHksCiAgICAgICAgaGV4ISgiYmE3ODE2YmYgOGYwMWNmZWEgNDE0MTQwZGUgNWRhZTIyMjMgYjAwMzYxYTMgOTYxNzdhOWMgYjQxMGZmNjEgZjIwMDE1YWQiKS5hc19yZWYoKQogICAgKTsKfQoKI1thY3RpeF93ZWI6OnRlc3RdCmFzeW5jIGZuIHR5cGVfYWxpYXNfZXF1aXZhbGVuY2UoKSB7CiAgICBsZXQgYXBwID0gdGVzdDo6aW5pdF9zZXJ2aWNlKAogICAgICAgIEFwcDo6bmV3KCkKICAgICAgICAgICAgLnJvdXRlKAogICAgICAgICAgICAgICAgIi9hbGlhcyIsCiAgICAgICAgICAgICAgICB3ZWI6OmdldCgpLnRvKHxib2R5OiBCb2R5U2hhMjU2PEJ5dGVzPnwgYXN5bmMgbW92ZSB7CiAgICAgICAgICAgICAgICAgICAgQnl0ZXM6OmNvcHlfZnJvbV9zbGljZShib2R5Lmhhc2goKXVudCA9IHNlbGYuc3RhdGljX3Jlc291cmNlc19tb3VudC5pbnRvX293bmVkKCk7CgogICAgICAgIGxldCBmaWxlcyA9IHsKICAgICAgICAgICAgbGV0IGluZGV4X2ZpbGUgPSBpbmRleF9maWxlLmNsb25lKCk7CiAgICAgICAgICAgIEZpbGVzOjpuZXcoJnN0YXRpY19yZXNvdXJjZXNfbW91bnQsIHN0YXRpY19yZXNvdXJjZXNfbG9jYXRpb24pCiAgICAgICAgICAgICAgICAvLyBIQUNLOiBGaWxlc1NlcnZpY2Ugd2lsbCB0cnkgdG8gcmVhZCBhIGRpcmVjdG9yeSBsaXN0aW5nIHVubGVzcyBpbmRleF9maWxlIGlzIHByb3ZpZGVkCiAgICAgICAgICAgICAgICAvLyBGaWxlc1NlcnZpY2Ugd2lsbCBmYWlsIHRvIGxvYWQgdGhlIGluZGV4X2ZpbGUgYW5kIHdpbGwgdGhlbiBjYWxsIG91ciBkZWZhdWx0X2hhbmRsZXIKICAgICAgICAgICAgICAgIC5pbmRleF9maWxlKCJleHRyZW1lbHktdW5saWtlbHktdG8tZXhpc3QtIUAkJV4mKi50eHQiKQogICAgICAgICAgICAgICAgLmRlZmF1bHRfaGFuZGxlcihtb3ZlIHxyZXF8IHNlcnZlX2luZGV4KHJlcSwgaW5kZXhfZmlsZS5jbG9uZSgpKSkKICAgICAgICB9OwoKICAgICAgICBTcGFTZXJ2aWNlIHsgaW5kZXhfZmlsZSwgZmlsZXMgfQogICAgfQp9CgojW2Rlcml2ZShEZWJ1ZyldCnN0cnVjdCBTcGFTZXJ2aWNlIHsKICAgIGluZGV4X2ZpbGU6IFN0cmluZywKICAgIGZpbGVzOiBGaWxlcywKfQoKaW1wbCBIdHRwU2VydmljZUZhY3RvcnkgZm9yIFNwYVNlcnZpY2UgewogICAgZm4gcmVnaXN0ZXIoc2VsZiwgY29uZmlnOiAmbXV0IGFjdGl4X3dlYjo6ZGV2OjpBcHBTZXJ2aWNlKSB7CiAgICAgICAgLy8gbGV0IEZpbGVzIHJlZ2lzdGVyIGl0cyBtb3VudCBwYXRoIGFzLWlzCiAgICAgICAgc2VsZi5maWxlcy5yZWdpc3Rlcihjb25maWcpOwoKICAgICAgICAvLyBhbHNvIGRlZmluZSBhIHJvb3QgcHJlZml4IGhhbmRsZXIgZGlyZWN0ZWQgdG93YXJkcyBvdXIgU1BBIGluZGV4CiAgICAgICAgbGV0IHJkZWYgPSBSZXNvdXJjZURlZjo6cm9vdF9wcmVmaXgoIiIpOwogICB0ISgie3N9LCB7czo/fSIpLCAidGVzdCwgUXVlcnkoSWQgeyBpZDogXCJ0ZXN0XCIgfSkiKTsKCiAgICAgICAgcy5pZCA9ICJ0ZXN0MSIudG9fc3RyaW5nKCk7CiAgICAgICAgbGV0IHMgPSBzLmludG9faW5uZXIoKTsKICAgICAgICBhc3NlcnRfZXEhKHMuaWQsICJ0ZXN0MSIpOwogICAgfQoKICAgICNbYWN0aXhfd2ViOjp0ZXN0XQogICAgI1tzaG91bGRfcGFuaWNdCiAgICBhc3luYyBmbiB0ZXN0X3R1cGxlX3BhbmljKCkgewogICAgICAgIGxldCByZXEgPSBUZXN0UmVxdWVzdDo6d2l0aF91cmkoIi8/b25lPTEmdHdvPTIiKS50b19zcnZfcmVxdWVzdCgpOwogICAgICAgIGxldCAocmVxLCBtdXQgcGwpID0gcmVxLmludG9fcGFydHMoKTsKCiAgICAgICAgUXVlcnk6OjwodTMyLCB1MzIpPjo6ZnJvbV9yZXF1ZXN0KCZyZXEsICZtdXQgcGwpCiAgICAgICAgICAgIC5hd2FpdAogICAgICAgICAgICAudW53cmFwKCk7CiAgICB9Cn0KLy8hIEhhc2hpbmcgdXRpbGl0aWVzIGZvciBBY3RpeCBXZWIuCi8vIQovLyEgIyBDcmF0ZSBGZWF0dXJlcwovLyEgQWxsIGZlYXR1cmVzIGFyZSBlbmFibGVkIGJ5IGRlZmF1bHQuCi8vISAtIGBibGFrZTJgOiBCbGFrZTIgdHlwZXMKLy8hIC0gYGJsYWtlM2A6IEJsYWtlMyB0eXBlcwovLyEgLSBgbWQ1YDogTUQ1IHR5cGVzIPCfmqkKLy8hIC0gYG1kNGA6IE1ENCB0eXBlcyDwn5qpCi8vISAtIGBzaGExYDogU0hBLTEgdHlwZXMg8J+aqQovLyEgLSBgc2hhMmA6IFNIQS0yIHR5cGVzCi8vISAtIGBzaGEzYDogU0hBLTMgdHlwZXMKLy8hCi8vISAjIFNlY3VyaXR5IFdhcm5pbmcg8J+aqQovLyEgVGhlIGBtZDRgLCBgbWQ1YCwgYW5kIGBzaGExYCB0eXBlcyBhcmUgaW5jbHVkZWQgZm9yIGNvbXBsZXRlbmVzcyBhbmQgaW50ZXJvcGVyYWJpbGl0eSBidXQgdGhleQovLyEgYXJlIGNvbnNpZGVyZWQgY3J5cHRvZ3JhcGhpY2FsbHkgYnJva2VuIGJ5IG1vZGVybiBzdGFuZGFyZHMuIEZvciBzZWN1cml0eSBjcml0aWNhbCB1c2UgY2FzZXMsCi8vISB5b3Ugc2hvdWxkIG1vdmUgdG8gICAgICAgICBTb21lKGNvZGUpIGlmIHBhdGhfYWx0ZXJlZCA9PiB7CiAgICAgICAgICAgICAgICBsZXQgbXV0IHJlcyA9IEh0dHBSZXNwb25zZTo6d2l0aF9ib2R5KGNvZGUsICgpKTsKICAgICAgICAgICAgICAgIHJlcy5oZWFkZXJzX211dCgpLmluc2VydCgKICAgICAgICAgICAgICAgICAgICBoZWFkZXI6OkxPQ0FUSU9OLAogICAgICAgICAgICAgICAgICAgIHJlcS5oZWFkX211dCgpLnVyaS50b19zdHJpbmcoKS5wYXJzZSgpLnVud3JhcCgpLAogICAgICAgICAgICAgICAgKTsKICAgICAgICAgICAgICAgIE5vcm1hbGl6ZVBhdGhGdXR1cmU6OnJlZGlyZWN0KHJlcS5pbnRvX3Jlc3BvbnNlKHJlcykpCiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIF8gPT4gTm9ybWFsaXplUGF0aEZ1dHVyZTo6c2VydmljZShzZWxmLnNlcnZpY2UuY2FsbChyZXEpKSwKICAgICAgICB9CiAgICB9Cn0KCnBpbl9wcm9qZWN0ISB7CiAgICBwdWIgc3RydWN0IE5vcm1hbGl6ZVBhdGhGdXR1cmU8UzogU2VydmljZTxTZXJ2aWNlUmVxdWVzdD4sIEI+IHsKICAgICAgICAjW3Bpbl0gaW5uZXI6IElubmVyPFMsIEI+LAogICAgfQp9CgppbXBsPFM6IFNlcnZpY2U8U2VydmljZVJlcXVlc3Q+LCBCPiBOb3JtYWxpemVQYXRoRnV0dXJlPFMsIEI+IHsKICAgIGZuIHNlcnZpY2UoZnV0OiBTOjpGdXR1cmUpIC0+IFNlbGYgewogICAgICAgIFNlbGYgewogICAgICAgICAgICBpbm5lcjogSW5uZXI6OlNlcnZpY2UgewogICAgICAgICAgICAgICAgZnV0LAogICAgICAgICAgICAgICAgX2JvZHk6IFBoYW50b21EYXRhLAogICAgICAgICAgICB9LAogICAgICAgIH0KICAgIH0KCiAgICBmbiByZWRpcmVjdChyZXM6IFNlcnZpY2VSZXNwb25zZTwoKT4pIC0+IFNlbGYgewogICAgICAgIFNlbGYgewogICAgICAgICAgICBpbm5lcjogSW5uZXI6OlJlZGlyZWN0IHsgcmVzOiBTb21lKHJlcykgfSwKICAgICAgICB9CiAgICB9Cn0KCnBpbl9wcm9qZWN0ISB7CiAgICAjW3Byb2plY3QgPSBJbm5lclByb2pdCiAgICBlbnVtIElubmVyPFM6IFNlciAgICBsZXQgdXJpID0gZm9ybWF0ISgie3NjaGVtZX06Ly93d3cue2hvc3R9e3BhdGh9Iik7CgogICAgICAgIGxldCByZXMgPSBSZWRpcmVjdDo6dG8odXJpKS5yZXNwb25kX3RvKCZyZXEpOwoKICAgICAgICBkcm9wKGNvbm5faW5mbyk7CiAgICAgICAgcmV0dXJuIE9rKFNlcnZpY2VSZXNwb25zZTo6bmV3KHJlcSwgcmVzKS5tYXBfaW50b19yaWdodF9ib2R5KCkpOwogICAgfQoKICAgIGRyb3AoY29ubl9pbmZvKTsKICAgIGxldCByZXEgPSBTZXJ2aWNlUmVxdWVzdDo6ZnJvbV9wYXJ0cyhyZXEsIHBsKTsKICAgIE9rKG5leHQuY2FsbChyZXEpLmF3YWl0Py5tYXBfaW50b19sZWZ0X2JvZHkoKSkKfQoKI1tjZmcodGVzdCldCm1vZCB0ZXN0X3N1cGVyIHsKICAgIHVzZSBhY3RpeF93ZWI6OnsKICAgICAgICBkZXY6OlNlcnZpY2VGYWN0b3J5LAogICAgICAgIGh0dHA6OntoZWFkZXIsIFN0YXR1c0NvZGV9LAogICAgICAgIHRlc3QsIHdlYiwgQXBwLCBIdHRwUmVzcG9uc2UsCiAgICB9OwoKICAgIHVzZSBzdXBlcjo6KjsKICAgIHVzZSBjcmF0ZTo6bWlkZGxld2FyZTo6ZnJvbV9mbjsKCiAgICBmbiB0ZXN0X2FwcCgpIC0+IEFwcDwKICAgICAgICBpbXBsIFNlcnZpY2VGYWN0b3J5PAogICAgICAgICAgICBTZXJ2aWNlUmVxdWVzdCwKICAgICAgICAgICAgUmVzcG9uc2UgPSBTZXJ2aWNlUmVzcG9uc2U8aW1wbCBNZXNzYWdlQm9keT4sCiAgICAgICAgICAgIENvbmZpZyA9ICgpLAogICAgICAgICAgICBJbml0RXJyb3IgPSAoKSwKICAgICAgICAgICAgRXJyb3IgPSBFcnJvciwKICAgICAgICA+LAogICAgPiB7CiAgICAgICAgQXBwOjpuZXcoKS53cmFwKGZyb21fZm4ocmVkaXJlY3RfdG9fd3d3KSkucm91dGUoCiAgICAgICAgICAgICIvIiwKICAgICAgICAgICAgd2ViOjpnZXQoKS50byh8fCBhc3luYyB7IEh0dHBSZXNwb25zZTo6T2soKS5ib2R5KCJjb250ZW50IikgfSksCiAgICAgICAgKQogICAgfQoKICAgICNbYWN0aXhfd2ViOjp0ZXN0XQogICAgYXN5bmMgZm4gcmVkaXJlY3Rfbm9uX3d3dygpIHsKICBlczsKdXNlIHRva2lvOjp7CiAgICBpbzo6QXN5bmNXcml0ZSwKICAgIHN5bmM6Om1wc2M6OntVbmJvdW5kZWRSZWNlaXZlciwgVW5ib3VuZGVkU2VuZGVyfSwKfTsKCi8vLyBSZXR1cm5zIGFuIGBBc3luY1dyaXRlYCByZXNwb25zZSBib2R5IHdyaXRlciBhbmQgaXRzIGFzc29jaWF0ZWQgYm9keSB0eXBlLgovLy8KLy8vICMgRXhhbXBsZXMKLy8vIGBgYAovLy8gIyB1c2UgYWN0aXhfd2ViOjp7SHR0cFJlc3BvbnNlLCB3ZWJ9OwovLy8gdXNlIHRva2lvOjppbzo6QXN5bmNXcml0ZUV4dCBhcyBfOwovLy8gdXNlIGFjdGl4X3dlYl9sYWI6OmJvZHk7Ci8vLwovLy8gIyBhc3luYyBmbiBpbmRleCgpIHsKLy8vIGxldCAobXV0IHdydCwgYm9keSkgPSBib2R5Ojp3cml0ZXIoKTsKLy8vCi8vLyBsZXQgXyA9IHRva2lvOjpzcGF3bihhc3luYyBtb3ZlIHsKLy8vICAgICB3cnQud3JpdGVfYWxsKGIiYm9keSBmcm9tIGFub3RoZXIgdGhyZWFkIikuYXdhaXQKLy8vIH0pOwovLy8KLy8vIEh0dHBSZXNwb25zZTo6T2soKS5ib2R5KGJvZHkpCi8vLyAjIDt9Ci8vLyBgYGAKcHViIGZuIHdyaXRlcigpIC0+IChXcml0ZXIsIGltcGwgTWVzc2FnZUJvZHkpIHsKICAgIGxldCAodHgsIHJ4KSA9IHRva2lvOjpzeW5jOjptcHNjOjp1bmJvdW5kZWRfY2hhbm5lbCgpOwogICAgKFdyaXRlciB7IHR4IH0sIEJvZHlTdHJlYW0geyByeCB9KQp9CgovLy8gQW4gYEFzeW5jV3JpdGVgIHJlc3BvbnNlIGJvZHkgd3JpdGVyLgojW2Rlcml2ZShEZWJ1ZywgQ2xvbmUpXQpwdWIgc3RydWN0IFdyaXRlciB7CiAgICB0eDogVW5ib3VuZGVkU2VuZGVyPEJ5dGVzPiwKfQoKaW1wbCBBc3luY1dyaXRlIGZvciBXcml0ZXIgewogICAgZm4gcG9sbF93cml0ZSgKICAgICAgICBzZWxmOiBQaW48Jm11dCBTZWxmPiwKICAgICAgICBfY3g6ICZtdXQgQ29udGV4dDwnXz4sCiAgICAgICAgYnVmOiAmW3U4XSwKICAgICkgLT4gUG9sbDxSZXN1bHQ8dXNpemUsIGlvOjpFcnJvcj4+IHsKICAgICAgICBzZWxmLnR4CiAgICAgICAgICAgIC5zZW5kKEJ5dGVzKCksICJkYXRhOiBmb29cblxuIik7CgogICAgICAgIGxldCBzdCA9IHN0cmVhbTo6cmVwZWF0KE9rOjo8XywgSW5mYWxsaWJsZT4oRXZlbnQ6OkRhdGEoRGF0YTo6bmV3KCJmb28iKSkpKS50YWtlKDIpOwogICAgICAgIGxldCBzc2UgPSBTc2U6OmZyb21fc3RyZWFtKHN0KTsKICAgICAgICBhc3NlcnRfZXEhKAogICAgICAgICAgICBib2R5Ojp0b19ieXRlcyhzc2UpLmF3YWl0LnVud3JhcCgpLAogICAgICAgICAgICAiZGF0YTogZm9vXG5cbmRhdGE6IGZvb1xuXG4iLAogICAgICAgICk7CiAgICB9CgogICAgI1thY3RpeF93ZWI6OnRlc3RdCiAgICBhc3luYyBmbiBhcHByb3ByaWF0ZV9oZWFkZXJzX2FyZV9zZXRfb25fcmVzcG9uZGVyKCkgewogICAgICAgIGxldCBzdCA9IHN0cmVhbTo6ZW1wdHk6OjxSZXN1bHQ8XywgSW5mYWxsaWJsZT4+KCk7CiAgICAgICAgbGV0IHNzZSA9IFNzZTo6ZnJvbV9zdHJlYW0oc3QpOwoKICAgICAgICBsZXQgcmVzID0gc3NlLnJlc3BvbmRfdG8oJlRlc3RSZXF1ZXN0OjpkZWZhdWx0KCkudG9faHR0cF9yZXF1ZXN0KCkpOwoKICAgICAgICBhc3NlcnRfcmVzcG9uc2VfbWF0Y2hlcyEocmVzLCBPSzsKICAgICAgICAgICAgImNvbnRlbnQtdHlwZSIgPT4gInRleHQvZXZlbnQtc3RyZWFtIgogICAgICAgICAgICAiY29udGVudC1lbmNvZGluZyIgPT4gImlkZW50aXR5IgogICAgICAgICAgICAiY2FjaGUtY29udHJvbCIgPT4gIm5vLWNhY2hlIgogICAgICAgICk7CiAgICB9CgogICAgI1thY3RpeF93ZWI6OnRlc3RdCiAgICBhc3luYyBmbiBtZXNzYWdlc19hcmVfcmVjZWl2ZWRfZnJvbV9zZW5kZXIoKSB7CiAgICAgICAgbGV0IChzZW5kZXIsIG11dCBzc2UpID0gY2hhbm5lbCg5KTsKCiAgICAgICAgYXNzZXJ0IShwb2xsX2ZuKHxjeHwgUGluOjpuZXcoJm11dCBzc2UpLnBvbGxfbmV4dChjeCkpCiAgICAgICAgICAgIC5ub3dfb3JfbmV2ZXIoKQogICAgICAgICAgICAuaXNfbm9uZSgpKTsKCiAgICAgICAgc2VuZGVyLnNlbmQoRGF0YTo6bmV3KCJiYXIiKS5ldmVudCgiZm9vImFtcGxlcwogICAgLy8vIGBgYAogICAgLy8vICNbYWN0aXhfd2ViOjptYWluXSBhc3luYyBmbiB0ZXN0KCkgewogICAgLy8vIHVzZSBhY3RpeF93ZWJfbGFiOjpzc2U7CiAgICAvLy8KICAgIC8vLyBsZXQgKHNlbmRlciwgc3NlX3N0cmVhbSkgPSBzc2U6OmNoYW5uZWwoNSk7CiAgICAvLy8gc2VuZGVyLnRyeV9zZW5kKHNzZTo6RGF0YTo6bmV3KCJteSBkYXRhIikuZXZlbnQoIm15IGV2ZW50IG5hbWUiKSkudW53cmFwKCk7CiAgICAvLy8gc2VuZGVyLnRyeV9zZW5kKHNzZTo6RXZlbnQ6OkNvbW1lbnQoIm15IGNvbW1lbnQiLmludG8oKSkpLnVud3JhcCgpOwogICAgLy8vICMgfSB0ZXN0KCk7CiAgICAvLy8gYGBgCiAgICBwdWIgZm4gdHJ5X3NlbmQoJnNlbGYsIG1zZzogaW1wbCBJbnRvPEV2ZW50PikgLT4gUmVzdWx0PCgpLCBUcnlTZW5kRXJyb3I+IHsKICAgICAgICBzZWxmLnR4LnRyeV9zZW5kKG1zZy5pbnRvKCkpLm1hcF9lcnIofGVycnwgbWF0Y2ggZXJyIHsKICAgICAgICAgICAgbXBzYzo6ZXJyb3I6OlRyeVNlbmRFcnJvcjo6RnVsbChldikgPT4gVHJ5U2VuZEVycm9yOjpGdWxsKGV2KSwKICAgICAgICAgICAgbXBzYzo6ZXJyb3I6OlRyeVNlbmRFcnJvcjo6Q2xvc2VkKGV2KSA9PiBUcnlTZW5kRXJyb3I6OkNsb3NlZChldiksCiAgICAgICAgfSkKICAgIH0KfQoKcGluX3Byb2plY3QhIHsKICAgIC8vLyBTZXJ2ZXItc2VudCBldmVudHMgKGB0ZXh0L2V2ZW50LXN0cmVhbWApIHJlc3BvbmRlci4KICAgIC8vLwogICAgLy8vIENvbnN0cnVjdGVkIHdpdGggYW4gW1NTRSBjaGFubmVsXShjaGFubmVsKSBvciBbdXNpbmcgeW91ciBvd24gc3RyZWFtXShTZWxmOjpmcm9tX3N0cmVhbSkuCiAgICAjW211c3RfdXNlXQogICAgI1tkZXJpdmUoRGVidWcpXQogICAgcHViIHN0cnVjdCBTc2U8Uz4gewogICAgICAgICNbcGluXQogICAgICAgIHN0cmVhbTogUywKICAgICAgICBrZWVwX2FsaXZlOiBPcHRpb248SW50ZXJ2YWw+LAogICAgICAgIHJldHJ5X2ludGVydmFsOiBPcHRpb248RHVyYXRpb24+LAogICBwX2RhdGEoRGF0YTo6bmV3KEFiY1NpZ25pbmdLZXkoWzA7IDMyXSkpKQogICAgICAgICAgICAucm91dGUoCiAgICAgICAgICAgICAgICAiLyIsCiAgICAgICAgICAgICAgICB3ZWI6OnBvc3QoKS50byh8Ym9keTogUmVxdWVzdFNpZ25hdHVyZTxCeXRlcywgQWJjQXBpPnwgYXN5bmMgbW92ZSB7CiAgICAgICAgICAgICAgICAgICAgbGV0IChib2R5LCBzaWcpID0gYm9keS5pbnRvX3BhcnRzKCk7CiAgICAgICAgICAgICAgICAgICAgbGV0IHNpZyA9IHNpZy5pbnRvX2J5dGVzKCkudG9fdmVjKCk7CiAgICAgICAgICAgICAgICAgICAgZm9ybWF0ISgie2JvZHk6P31cblxue3NpZzp4P30iKQogICAgICAgICAgICAgICAgfSksCiAgICAgICAgICAgICkKICAgIH0pCiAgICAud29ya2VycygxKQogICAgLmJpbmQoKCIxMjcuMC4wLjEiLCA4MDgwKSk/CiAgICAucnVuKCkKICAgIC5hd2FpdAp9Ci8vISBFeHBpcmVtZW50YWwgdGVzdGluZyB1dGlsaXRpZXMuCgojW2RvYyhpbmxpbmUpXQojW2NmZyh0ZXN0KV0KcHViKGNyYXRlKSB1c2UgY3JhdGU6OnRlc3RfaGVhZGVyX21hY3Jvczo6e2hlYWRlcl9yb3VuZF90cmlwX3Rlc3QsIGhlYWRlcl90ZXN0X21vZHVsZX07CiNbZG9jKGlubGluZSldCnB1YiB1c2UgY3JhdGU6OnRlc3RfcmVxdWVzdF9tYWNyb3M6OnRlc3RfcmVxdWVzdDsKI1tkb2MoaW5saW5lKV0KcHViIHVzZSBjcmF0ZTo6dGVzdF9yZXNwb25zZV9tYWNyb3M6OmFzc2VydF9yZXNwb25zZV9tYXRjaGVzOwpwdWIgdXNlIGNyYXRlOjp0ZXN0X3NlcnZpY2VzOjplY2hvX3BhdGhfc2VydmljZTsKLy8hIFNlbWFudGljIHNlcnZlci1zZW50IGV2ZW50cyAoU1NFKSByZXNwb25kZXIgd2l0aCBhIGNoYW5uZWwtbGlrZSBpbnRlcmZhY2UuCi8vIQovLyEgIyBFeGFtcGxlcwovLyEgYGBgbm9fcnVuCi8vISB1c2Ugc3RkOjp7Y29udmVydDo6SW5mYWxsaWJsZSwgdGltZTo6RHVyYXRpb259OwovLyEgdXNlIGFjdGl4X3dlYjo6e1Jlc3BvbmRlciwgZ2V0fTsKLy8hIHVzZSBhY3RpeF93ZWJfbGFiOjpzc2U7Ci8vIQovcmFuZ2VzOiB1bnNhZmUgewogICAgICAgICAgICAgICAgSXBDaWRyQ29tYmluZXI6OmZyb21fY2lkcl92ZWNfdW5jaGVja2VkKGlwdjRfY2lkcl92ZWMsIGlwdjZfY2lkcl92ZWMpCiAgICAgICAgICAgIH0sCiAgICAgICAgfQogICAgfQp9CgovLy8gRmV0Y2hlZCB0cnVzdGVkIENsb3VkZmxhcmUgSVAgYWRkcmVzc2VzIGZyb20gdGhlaXIgQVBJLgojW2NmZyhmZWF0dXJlID0gImZldGNoLWlwcyIpXQpwdWIgYXN5bmMgZm4gZmV0Y2hfdHJ1c3RlZF9jZl9pcHMoKSAtPiBSZXN1bHQ8VHJ1c3RlZElwcywgRXJyPiB7CiAgICBsZXQgY2xpZW50ID0gYXdjOjpDbGllbnQ6Om5ldygpOwoKICAgIHRyYWNpbmc6OmRlYnVnISgiZmV0Y2hpbmcgY2xvdWRmbGFyZSBpcHMiKTsKICAgIGxldCBtdXQgcmVzID0gY2xpZW50LmdldChDRl9VUkxfSVBTKS5zZW5kKCkuYXdhaXQubWFwX2Vycih8ZXJyfCB7CiAgICAgICAgdHJhY2luZzo6ZXJyb3IhKCJ7ZXJyfSIpOwogICAgICAgIEVycjo6RmV0Y2gKICAgIH0pPzsKCiAgICB0cmFjaW5nOjpkZWJ1ZyEoInBhcnNpbmcgcmVzcG9uc2UiKTsKICAgIGxldCByZXMgPSByZXMuanNvbjo6PENmSXBzUmVzcG9uc2U+KCkuYXdhaXQubWFwX2Vycih8ZXJyfCB7CiAgICAgICAgdHJhY2luZzo6ZXJyb3IhKCJ7ZXJyfSIpOwogICAgICAgIEVycjo6RmV0Y2gKICAgIH0pPzsKCiAgICBUcnVzdGVkSXBzOjp0cnlfZnJvbV9yZXNwb25zZShyZXMpCn0KCiNbY2ZnKHRlc3QpXQptb2QgdGVzdHMgewogICAgdXNlIHN1cGVyOjoqOwoKICAgICNbdGVzdF0KICAgIGZuIGNmX2lwc19mcm9tX3Jlc3BvbnNlKCkgewogICAgICAgIGxldCByZXMgPSBDZklwc1Jlc3BvbnNlOjpGYWlsdXJlIHsgc3VjY2VzczogZmFsc2UgfTsKICAgICAgICBhc3NlcnQhKFRydXN0ZWRuc2U6OlN1Y2Nlc3MgeyByZXN1bHQgfSA9PiByZXN1bHQsCiAgICAgICAgICAgIENmSXBzUmVzcG9uc2U6OkZhaWx1cmUgeyAuLiB9ID0+IHsKICAgICAgICAgICAgICAgIHRyYWNpbmc6OmVycm9yISgicGFyc2luZyByZXNwb25zZSByZXR1cm5lZCBzdWNjZXNzOiBmYWxzZSIpOwogICAgICAgICAgICAgICAgcmV0dXJuIEVycihFcnI6OkZldGNoKTsKICAgICAgICAgICAgfQogICAgICAgIH07CgogICAgICAgIGxldCBtdXQgY2lkcl9yYW5nZXMgPSBJcENpZHJDb21iaW5lcjo6bmV3KCk7CgogICAgICAgIGZvciBjaWRyIGluIGlwcy5pcHY0X2NpZHJzIHsKICAgICAgICAgICAgY2lkcl9yYW5nZXMucHVzaChJcENpZHI6OlY0KGNpZHIpKTsKICAgICAgICB9CgogICAgICAgIGZvciBjaWRyIGluIGlwcy5pcHY2X2NpZHJzIHsKICAgICAgICAgICAgY2lkcl9yYW5nZXMucHVzaChJcENpZHI6OlY2KGNpZHIpKTsKICAgICAgICB9CgogICAgICAgIE9rKFNlbGYgeyBjaWRyX3JhbmdlcyB9KQogICAgfQoKICAgIC8vLyBBZGQgdHJ1c3RlZCBJUCByYW5nZSB0byBsaXN0LgogICAgcHViIGZuIHdpdGhfaXBfcmFuZ2UobXV0IHNlbGYsIGNpZHI6IElwQ2lkcikgLT4gU2VsZiB7CiAgICAgICAgc2VsZi5jaWRyX3Jhbmdlcy5wdXNoKGNpZHIpOwogICAgICAgIHNlbGYKICAgIH0KCiAgICAvLy8gUmV0dXJucyB0cnVlIGlmIGBpcGAgaXMgY29udHJvbGxlZCBieSBDbG91ZGZsYXJlLgogICAgcHViIGZuIGNvbnRhaW5zKCZzZWxmLCBpcDogSXBBZGRyKSAtPiBib29sIHsKICAgICAgICBzZWxmLmNpZHJfcmFuZ2VzLmNvbnRhaW5zKGlwKQogICAgfQp9CgppbXBsIENsb25lIGZvciBUcnVzdGVkSXBzIHsKICAgIGZuIGNsb25lKCZzZWxmKSAtPiBTZWxmIHsKICAgICAgICBsZXQgaXB2NF9jaWRyX3ZlYyA9IHNlbGYuY2lkcl9yYW5nZXMuZ2V0X2lwdjRfY2lkcnMoKS50b192ZWMoKTsKICAgICAgICBsZXQgaXB2Nl9jaWRyX3ZlYyA9IHNlbGYuY2lkcl9yYW5nZXMuZ2V0X2lwdjZfY2lkcnMoKS50b192ZWMoKTsKCiAgLy8hIFV0aWxpdGllcyBmb3Igd29ya2luZyB3aXRoIEFjdGl4IFdlYiB0eXBlcy4KCi8vIHN0dWZmIGluIGhlcmUgY29tZXMgaW4gYW5kIG91dCBvZiB1c2FnZQojIVthbGxvdyhkZWFkX2NvZGUpXQoKdXNlIHN0ZDo6ewogICAgY29udmVydDo6SW5mYWxsaWJsZSwKICAgIGlvLAogICAgcGluOjpQaW4sCiAgICB0YXNrOjp7cmVhZHksIENvbnRleHQsIFBvbGx9LAp9OwoKdXNlIGFjdGl4X2h0dHA6OntlcnJvcjo6UGF5bG9hZEVycm9yLCBCb3hlZFBheWxvYWRTdHJlYW19Owp1c2UgYWN0aXhfd2ViOjp7ZGV2LCB3ZWI6OkJ1Zk11dH07CnVzZSBmdXR1cmVzX2NvcmU6OlN0cmVhbTsKdXNlIGZ1dHVyZXNfdXRpbDo6U3RyZWFtRXh0IGFzIF87CnVzZSBsb2NhbF9jaGFubmVsOjptcHNjOwoKLy8vIFJldHVybnMgYW4gZWZmZWN0aXZlbHkgY2xvbmVkIHBheWxvYWQgdGhhdCBzdXBwb3J0cyBzdHJlYW1pbmcgZWZmaWNpZW50bHkuCi8vLwovLy8gVGhlIGNsb25lZCBwYXlsb2FkOgovLy8gLSB5aWVsZHMgaWRlbnRpY2FsIGNodW5rczsKLy8vIC0gZG9lcyBub3QgcG9sbCBhaGVhZCBvZiB0aGUgb3JpZ2luYWw7Ci8vLyAtIGRvZXMgbm90IHBvbGwgc2lnbmlmaWNhbnRseSBzbG93ZXIgdGhhbiB0aGUgb3JpZ2luYWw7Ci8vLyAtIHJlY2VpdmVzIGFuIGVycm9yIHNpZ25hbCBpZiB0aGUgb3JpZ2luYWwgZXJyb3JzLCBidXQgZGV0YWlscyBhcmUgb3BhcXVlIHRvIHRoZSBjb3B5LgovLy8KLy8vIElmIHRoZSBwYXlsb2FkIGlzIGZvcmtlZCBpbiBvbmUgb2YgdGhlIGV4dHJhY3RvcnMgdXNlZCBpbiBhIGhhbmRsZXIsIHRoZW4gdGhlIG9yaWdpbmFsIF9tdXN0XyBiZQovLy8gcmVhZCBpbiBhbm90aGVyIGV4dHJhY3RvciBvciBlbHNlIHRoZSByZXF1ZXN0IHdpbGwgaGFuZy4KcHViIGZuIGZvcmtfcmVxdWVzdF9wYXlsb2FkKG9yaWdfcGF5bG9hZDogJm11dCBkZXY6OlBheWxvYWQpIC0+IGRldjo6UGF5bG9hZCB7CiAgICBjb25zdCBUQVJHRVQ6ICZzdHIgPSBjb25jYXQhKG1vZHVsZV9wYXRoISgpLCAiOjpmb3JrX3EpLnVud3JhcCgpLCBleHBlY3QpOwogICAgfQoKICAgICNbdHJhY2tfY2FsbGVyXQogICAgcHViKGNyYXRlKSBmbiBhc3NlcnRfcGFyc2VfZmFpbDwKICAgICAgICBIOiBIZWFkZXIgKyBmbXQ6OkRlYnVnLAogICAgICAgIEk6IEludG9JdGVyYXRvcjxJdGVtID0gVj4sCiAgICAgICAgVjogQXNSZWY8W3U4XT4sCiAgICA+KAogICAgICAgIGhlYWRlcnM6IEksCiAgICApIHsKICAgICAgICBsZXQgcmVxID0gcmVxX2Zyb21fcmF3X2hlYWRlcnM6OjxILCBfLCBfPihoZWFkZXJzKTsKICAgICAgICBIOjpwYXJzZSgmcmVxKS51bndyYXBfZXJyKCk7CiAgICB9Cn0KCiNbY2ZnKHRlc3QpXQpwdWIoY3JhdGUpIHVzZSBoZWFkZXJfdGVzdF9oZWxwZXJzOjp7YXNzZXJ0X3BhcnNlX2VxLCBhc3NlcnRfcGFyc2VfZmFpbH07CnVzZSBhY3RpeF9jbGllbnRfaXBfY2xvdWRmbGFyZTo6e2ZldGNoX3RydXN0ZWRfY2ZfaXBzLCBDZkNvbm5lY3RpbmdJcCwgVHJ1c3RlZENsaWVudElwfTsKdXNlIGFjdGl4X3dlYjo6e2dldCwgd2ViOjpIZWFkZXIsIEFwcCwgSHR0cFNlcnZlciwgUmVzcG9uZGVyfTsKCiNbZ2V0KCIvcmF3LWhlYWRlciIpXQphc3luYyBmbiBoZWFkZXIoSGVhZGVyKGNsaWVudF9pcCk6IEhlYWRlcjxDZkNvbm5lY3RpbmdJcD4pIC0+IGltcGwgUmVzcG9uZGVyIHsKICAgIG1hdGNoIGNsaWVudF9pcCB7CiAgICAgICAgQ2ZDb25uZWN0aW5nSXA6OlRydXN0ZWQoX2lwKSA9PiB1bnJlYWNoYWJsZSEoKSwKICAgICAgICBDZkNvbm5lY3RpbmdJcDo6VW50cnVzdGVkKGlwKSA9PiBmb3JtYXQhKCJQb3NzaWJseSBmYWtlIGNsaWVudCBJUDoge2lwfSIpLAogICAgfQp9CgojW2dldCgiL2NsaWVudC1pcCIpXQphc3luYyBmbiB0cnVzdGVkX2NsaWVudF9pcChjbGllbnRfaXA6IFRydXN0ZWRDbGllbnRJcCkgLT4gaW1wbCBSZXNwb25kZXIgewogICAgZm9ybWF0ISgiVHJ1c3RlZCBjbGllbnQgSVA6IHtjbGllbnRfaXB9IikKfQoKI1thY3RpeF93ZWI6Om1haW5dCmFzeW5jIGZuIG1haW4oKSAtPiBzdGQ6OmlvOjpSZXMgICBieTogU29tZSgiMjAzLjAuMTEzLjQzIi50b19vd25lZCgpKSwKICAgICAgICAgICAgciNmb3I6IHZlYyFbIjE5Mi4wLjIuNjAiLnRvX293bmVkKCldLAogICAgICAgICAgICBob3N0OiBTb21lKCJydXN0LWxhbmcub3JnIi50b19vd25lZCgpKSwKICAgICAgICAgICAgcHJvdG86IFNvbWUoImh0dHBzIi50b19vd25lZCgpKSwKICAgICAgICB9OwoKICAgICAgICBhc3NlcnRfZXEhKAogICAgICAgICAgICBmd2QudHJ5X2ludG9fdmFsdWUoKS51bndyYXAoKSwKICAgICAgICAgICAgciMiYnk9IjIwMy4wLjExMy40MyI7IGZvcj0iMTkyLjAuMi42MCI7IGhvc3Q9InJ1c3QtbGFuZy5vcmciOyBwcm90bz0iaHR0cHMiIiMKICAgICAgICApOwogICAgfQoKICAgICNbdGVzdF0KICAgIGZuIGNhc2Vfc2Vuc2l0aXZpdHkoKSB7CiAgICAgICAgYXNzZXJ0X3BhcnNlX2VxOjo8Rm9yd2FyZGVkLCBfLCBfPigKICAgICAgICAgICAgWyJGb3I9MTkyLjAuMi42MCJdLAogICAgICAgICAgICBGb3J3YXJkZWQgewogICAgICAgICAgICAgICAgciNmb3I6IHZlYyFbIjE5Mi4wLjIuNjAiLnRvX293bmVkKCldLAogICAgICAgICAgICAgICAgLi5Gb3J3YXJkZWQ6OmRlZmF1bHQoKQogICAgICAgICAgICB9LAogICAgICAgICk7CiAgICB9CgogICAgI1t0ZXN0XQogICAgZm4gd2VpcmRfd2hpdGVzcGFjZSgpIHsKICAgICAgICBhc3NlcnRfcGFyc2VfZXE6OjxGb3J3YXJkZWQsIF8sIF8+KAogICAgICAgICAgICBbImZvcj0gMS4yLjMuNDsgcHJvdG89IGh0dHBzIl0sCiAgICAgICAgICAgIEZvcndhcmRlZCB7CiAgICAgICAgICAgICAgICByI2ZvcjogdmVjIVsiMS4yLjMuNCIudG9fb3duZWQoKV0sCiAgICAgICAgICAgICAgICBwcm90bzogU29tZSgiaHR0cHMiLnRvX293bmVkKCkpLAogICAgICAgICAgICAgICAgLi5Gb3J3YXJkZWQ6OmRlZmF1bHQoKQogICAgICAgICAgICB9LAogICAgICAgICk7CgogICAgICAgIGFzc2VydF9wYXJzZV9lcTo6PEZvcndhcmRlZCwgXywgXz4oCiAgICAgICAgICAgIFsiICBmb3IgPSAxLjIuICAgIGxldCBtdXQgcHJvdG8gPSBOb25lOwogICAgICAgIGxldCBtdXQgciNmb3IgPSB2ZWMhW107CgogICAgICAgIC8vICJmb3I9MS4yLjMuNCwgZm9yPTUuNi43Ljg7IHNjaGVtZT1odHRwcyIKICAgICAgICBmb3IgKG5hbWUsIHZhbCkgaW4gdmFsCiAgICAgICAgICAgIC5zcGxpdCgnOycpCiAgICAgICAgICAgIC8vIFsiZm9yPTEuMi4zLjQsIGZvcj01LjYuNy44IiwgIiBwcm90bz1odHRwcyJdCiAgICAgICAgICAgIC5mbGF0X21hcCh8dmFsc3wgdmFscy5zcGxpdCgnLCcpKQogICAgICAgICAgICAvLyBbImZvcj0xLjIuMy40IiwgIiBmb3I9NS42LjcuOCIsICIgcHJvdG89aHR0cHMiXQogICAgICAgICAgICAuZmxhdF9tYXAofHBhaXJ8IHsKICAgICAgICAgICAgICAgIGxldCBtdXQgaXRlbXMgPSBwYWlyLnRyaW0oKS5zcGxpdG4oMiwgJz0nKTsKICAgICAgICAgICAgICAgIFNvbWUoKGl0ZW1zLm5leHQoKT8sIGl0ZW1zLm5leHQoKT8pKQogICAgICAgICAgICB9KQogICAgICAgIHsKICAgICAgICAgICAgLy8gWyhuYW1lICwgdmFsICAgICAgKSwgLi4uICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXQogICAgICAgICAgICAvLyBbKCJmb3IiLCAiMS4yLjMuNCIpLCAoImZvciIsICI1LjYuNy44IiksICgic2NoZW1lIiwgImh0dHBzIildCgogICAgICAgICAgICBtYXRjaCBuYW1lLnRyaW0oKS50b19sb3dlcmNhc2UoKS5hc19zdHIoKSB7CiAgICAgICAgICAgICAgICAiYnkiID0+IHsKICAgICAgICAgICAgICAgICAgICAvLyBtdWx0aXBsZSB2YWx1ZXMgb24gb3RoZXIgcHJvcGVydGllcyBoYXZlIG5vIGRlZmluZWQgc2VtYW50aWNzCiAgICAgICAgICAgICAgICAgICAgYnkuZ2V0X29yX2luc2VydF93aXRoKHx8IHVucXVvdGUodmFsKSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAiZm9yIiA9PiB7CiAgICAgICAgICAgICAgICAgICAgLy8gcGFyYW1ldGVyIG9yZGVyIGlzIGRlZmluZWQgdG8gYmUgY2xpZW50IGZpcnN0IGFuZCBsYXN0IHByb3h5IGxhc3QKICAgIHRyYWN0b3IgdGhhdAovLy8gX3Rha2VzXyB0aGUgcGF5bG9hZC4gSW4gdGhpcyBjYXNlLCB0aGUgcmVzdWx0aW5nIGhhc2ggd2lsbCBiZSBhcyBpZiBhbiBlbXB0eSBpbnB1dCB3YXMgZ2l2ZW4gdG8KLy8vIHRoZSBoYXNoZXIuCi8vLwovLy8gIyBFeGFtcGxlCi8vLyBgYGAKLy8vIHVzZSBhY3RpeF93ZWI6OntSZXNwb25kZXIsIHdlYn07Ci8vLyB1c2UgYWN0aXhfaGFzaDo6Qm9keUhhc2g7Ci8vLyB1c2Ugc2hhMjo6U2hhMjU2OwovLy8KLy8vICMgdHlwZSBUID0gdTY0OwovLy8gYXN5bmMgZm4gaGFzaF9wYXlsb2FkKGZvcm06IEJvZHlIYXNoPHdlYjo6SnNvbjxUPiwgU2hhMjU2PikgLT4gaW1wbCBSZXNwb25kZXIgewovLy8gICAgIGlmICFmb3JtLnZlcmlmeV9zbGljZShiImNvcnJlY3Qtc2lnbmF0dXJlIikgewovLy8gICAgICAgICAvLyByZXR1cm4gdW5hdXRob3JpemVkIGVycm9yCi8vLyAgICAgfQovLy8KLy8vICAgICAiT2siCi8vLyB9Ci8vLyBgYGAKI1tkZXJpdmUoRGVidWcsIENsb25lKV0KcHViIHN0cnVjdCBCb2R5SGFzaDxULCBEOiBEaWdlc3Q+IHsKICAgIGlubmVyOiBULAogICAgaGFzaDogR2VuZXJpY0FycmF5PHU4LCBEOjpPdXRwdXRTaXplPiwKfQoKaW1wbDxULCBEOiBEaWdlc3Q+IEJvZHlIYXNoPFQsIEQ+IHsKICAgIC8vLyBSZXR1cm5zIGhhc2ggc2xpY2UuCiAgICBwdWIgZm4gaGFzaCgmc2VsZikgLT4gJlt1OF0gewogICAgICAgIHNlbGYuaGFzaC5hc19zbGljZSgpCiAgICB9CgogICAgLy8vIFJldHVybnMgaGFzaCBvdXRwdXQgc2l6ZS4KICAgIHB1YiBmbiBoYXNoX3NpemUoJnNlbGYpIC0+IHVzaXplIHsKICAgICAgICBzZWxmLmhhc2gubGVuKCkKICAgIH0KCiAgICAvLy8gVmVyaWZpZXMgSE1BQyBoYXNoIGFnYWluc3QgcHJvdmlkZWQgYHRhZ2AgdXNpbmcgY29uc3RhbnQtdGltZSBlcXVhbGl0eS4KICAgIHB1YiBmbiB2ZXJpZnlfc2xpY2UoJnNlbGYsIHRhZzogJlt1OF0pIC0+IGJvb2wgewogICAgICAgIHVzZSBzdWJ0bGU6OkNvbnN0YW50VGltZUVxIGFzIF87CiAgICB1c2UgYXN5bmNfdHJhaXQ6OmFzeW5jX3RyYWl0Owp1c2UgYnl0ZXM6OntCdWZNdXQgYXMgXywgQnl0ZXNNdXR9Owp1c2UgZWQyNTUxOV9kYWxlazo6e1B1YmxpY0tleSwgU2lnbmF0dXJlLCBWZXJpZmllciBhcyBffTsKdXNlIGhleF9saXRlcmFsOjpoZXg7CnVzZSBvbmNlX2NlbGw6OnN5bmM6Okxhenk7CnVzZSBydXN0bHM6OntDZXJ0aWZpY2F0ZSwgUHJpdmF0ZUtleSwgU2VydmVyQ29uZmlnfTsKdXNlIHJ1c3Rsc19wZW1maWxlOjp7Y2VydHMsIHBrY3M4X3ByaXZhdGVfa2V5c307CnVzZSB0cmFjaW5nOjppbmZvOwoKY29uc3QgQVBQX1BVQkxJQ19LRVlfQllURVM6ICZbdThdID0KICAgICZoZXghKCJkN2Q5YTE0NzUzYjU5MWJlOTlhMGM1NzIxYmU4MDgzYjFlNDg2YzNmY2RjNmFjMDhiZmI2M2E2ZTVjMjA0NTY5Iik7CgpzdGF0aWMgU0lHX0hEUl9OQU1FOiBIZWFkZXJOYW1lID0gSGVhZGVyTmFtZTo6ZnJvbV9zdGF0aWMoIngtc2lnbmF0dXJlLWVkMjU1MTkiKTsKc3RhdGljIFRTX0hEUl9OQU1FOiBIZWFkZXJOYW1lID0gSGVhZGVyTmFtZTo6ZnJvbV9zdGF0aWMoIngtc2lnbmF0dXJlLXRpbWVzdGFtcCIpOwpzdGF0aWMgQVBQX1BVQkxJQ19LRVk6IExhenk8UHVibGljS2V5PiA9CiAgICBMYXp5OjpuZXcofHwgUHVibGljS2V5Ojpmcm9tX2J5dGVzKEFQUF9QVUJMSUNfS0VZX0JZVEVTKS51bndyYXAoKSk7CgojW2Rlcml2ZShEZWJ1ZyldCnN0cnVjdCBEaXNjb3JkV2ViaG9vayB7CiAgICAvLy8gU2lnbmF0dXJlIHRha2VuIGZyb20gd2ViaG9vayByZXF1ZXN0IGhlYWRlci4KICAgIGNhbmRpZGF0ZV9zaWduYXR1cmU6IFNpZ25hdHVyZSwKCiAgICAvLy8gQ2xvbmVkIHBheWxvYWQgc3RhdGUuCiAgICBjaHVua3M6IFZlYzxCeXRlcz4sCn0KCmltcGwgRGlzY29yZFdlYmhvb2sgewogICAgZm4gZ2V0X3RpbWVzdGFtcChyZXE6ICZIdHRwUmVxdWVzdCkgLT4gUmVzdWx0PCZbdThdLCBFcnJvcj4gewogICAgICAgIHJlcS5oZWFkZXJzKCkKICAgICAgICAgICAgLmdldCgmVFNfSERSX05BTUUpCiAgICAgc19jb3JlOjpyZWFkeTsKdXNlIHBpbl9wcm9qZWN0X2xpdGU6OnBpbl9wcm9qZWN0OwoKLy8vIENyZWF0ZXMgYSBtaWRkbGV3YXJlIGZyb20gYW4gYXN5bmMgZnVuY3Rpb24gdGhhdCBpcyB1c2VkIGFzIGEgbWFwcGluZyBmdW5jdGlvbiBmb3IgYQovLy8gW2BTZXJ2aWNlUmVzcG9uc2VgXS4KLy8vCi8vLyAjIEV4YW1wbGVzCi8vLyBBZGRzIGhlYWRlcjoKLy8vIGBgYAovLy8gIyB1c2UgYWN0aXhfd2ViX2xhYjo6bWlkZGxld2FyZTo6bWFwX3Jlc3BvbnNlOwovLy8gdXNlIGFjdGl4X3dlYjo6e2JvZHk6Ok1lc3NhZ2VCb2R5LCBkZXY6OlNlcnZpY2VSZXNwb25zZSwgaHR0cDo6aGVhZGVyfTsKLy8vCi8vLyBhc3luYyBmbiBhZGRfaGVhZGVyKAovLy8gICAgIG11dCByZXM6IFNlcnZpY2VSZXNwb25zZTxpbXBsIE1lc3NhZ2VCb2R5PiwKLy8vICkgLT4gYWN0aXhfd2ViOjpSZXN1bHQ8U2VydmljZVJlc3BvbnNlPGltcGwgTWVzc2FnZUJvZHk+PiB7Ci8vLyAgICAgcmVzLmhlYWRlcnNfbXV0KCkKLy8vICAgICAgICAgLmluc2VydChoZWFkZXI6OldBUk5JTkcsIGhlYWRlcjo6SGVhZGVyVmFsdWU6OmZyb21fc3RhdGljKCI0MiIpKTsKLy8vCi8vLyAgICAgT2socmVzKQovLy8gfQovLy8gIyBhY3RpeF93ZWI6OkFwcDo6bmV3KCkud3JhcChtYXBfcmVzcG9uc2UoYWRkX2hlYWRlcikpOwovLy8gYGBgCi8vLwovLy8gTWFwcyBib2R5OgovLy8gYGBgCi8vLyAjIHVzZSBhY3RpeF93ZWJfbGFiOjptaWRkbGV3YXJlOjptYXBfcmVzcG9uc2U7Ci8vLyB1c2UgYWN0aXhfd2ViOjp7Ym9keTo6TWVzc2FnZUJvZHksIGRldjo6U2VydmljZVJlc3BvbnNlfTsKLy8vCi8vLyBhc3luYyBmbiBtdXRhdGVfYm9keV90eXBlKAovLy8gICAgIHJlczogU2VydmljZVJlc3BvbnNlPGltcGwgTWVzc2FnZUJvZHkgKyAnc3RhdGljPiwKLy8vICkgLT4gYWN0aXhfd2ViOjpSZXN1bHQ8U2VydmljZVJlc3BvbnNlPGltcGwgTWVzc2FnZUJvZHk+PiB7Ci8vLyAgICAgT2socmVzLm1hcF9pbnRvX2xlZnRfYm9keTo6PCgpPigpKQovLy8gfWIpOwoKICAgICAgICAvLyBjYXRjaCBwYW5pY3MgaW4gc2VydmljZSBjYWxsCiAgICAgICAgQXNzZXJ0VW53aW5kU2FmZShzZWxmLnNlcnZpY2UuY2FsbChyZXEpKQogICAgICAgICAgICAuY2F0Y2hfdW53aW5kKCkKICAgICAgICAgICAgLm1hcChtb3ZlIHxtYXliZV9yZXN8IG1hdGNoIG1heWJlX3JlcyB7CiAgICAgICAgICAgICAgICBPayhyZXMpID0+IHJlcywKICAgICAgICAgICAgICAgIEVycihwYW5pY19lcnIpID0+IHsKICAgICAgICAgICAgICAgICAgICAvLyBpbnZva2UgY2FsbGJhY2sgd2l0aCBwYW5pYyBhcmcKICAgICAgICAgICAgICAgICAgICAoY2IpKCZwYW5pY19lcnIpOwoKICAgICAgICAgICAgICAgICAgICAvLyBjb250aW51ZSB1bndpbmRpbmcKICAgICAgICAgICAgICAgICAgICBwYW5pYzo6cmVzdW1lX3Vud2luZChwYW5pY19lcnIpCiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0pCiAgICAgICAgICAgIC5ib3hlZF9sb2NhbCgpCiAgICB9Cn0KCiNbY2ZnKHRlc3QpXQptb2QgdGVzdHMgewogICAgdXNlIHN0ZDo6c3luYzo6ewogICAgICAgIGF0b21pYzo6e0F0b21pY0Jvb2wsIE9yZGVyaW5nfSwKICAgICAgICBBcmMsCiAgICB9OwoKICAgIHVzZSBhY3RpeF93ZWI6OnsKICAgICAgICBkZXY6OlNlcnZpY2UgYXMgXywKICAgICAgICB0ZXN0LAogICAgICAgIHdlYjo6e3NlbGYsIFNlcnZpY2VDb25maWd9LAogICAgICAgIEFwcCwKICAgIH07CgogICAgdXNlIHN1cGVyOjoqOwoKICAgIGZuIGNvbmZpZ3VyZV90ZXN0X2FwcChjZmc6ICZtdXQgU2VydmljZUNvbmZpZykgewogICAgICAgIGNmZy5yb3V0ZSgiLyIsIHdlYjo6Z2V0KCkudG8ofHwgYXN5bmMgeyAiY29udGVudCIgfSkpLnJvdXRlKAogICAgICAgICAgICAiL2Rpc2NvIiwKICAgICAgICAgICAgI1thbGxvdyh1bnJlYWNoYWJsZV9jb2RlKV0KICAgICAgICAgICAgd2ViOjpnZXQoKS50byh8fCBhc3luYyB7CiAgICAgICAgICAgICAgICBwYW5pYyEoInRoZSBkaXNjbyIpOwogICAgICAgICAgICAgICAgIiIKICAgICAvLwovLy8gLy8vIERlc2VyaWFsaXplIHBheWxvYWQgd2l0aCBhIGhpZ2hlciAzMk1pQiBsaW1pdC4KLy8vICNbcG9zdCgiL2JpZy1wYXlsb2FkIildCi8vLyBhc3luYyBmbiBiaWdfcGF5bG9hZChpbmZvOiBVcmxFbmNvZGVkRm9ybTxJbmZvLCBMSU1JVF8zMl9NQj4pIC0+IFN0cmluZyB7Ci8vLyAgICAgZm9ybWF0ISgiV2VsY29tZSB7fSEiLCBpbmZvLnVzZXJuYW1lKQovLy8gfQovLy8gYGBgCiNbZG9jKGFsaWFzID0gImh0bWxfZm9ybSIsIGFsaWFzID0gImh0bWwgZm9ybSIsIGFsaWFzID0gImZvcm0iKV0KI1tkZXJpdmUoRGVidWcsIERlcmVmLCBEZXJlZk11dCwgRGlzcGxheSldCnB1YiBzdHJ1Y3QgVXJsRW5jb2RlZEZvcm08VCwgY29uc3QgTElNSVQ6IHVzaXplID0gREVGQVVMVF9VUkxfRU5DT0RFRF9GT1JNX0xJTUlUPihwdWIgVCk7CgppbXBsPFQsIGNvbnN0IExJTUlUOiB1c2l6ZT4gVXJsRW5jb2RlZEZvcm08VCwgTElNSVQ+IHsKICAgIC8vLyBVbndyYXBzIGludG8gaW5uZXIgYFRgIHZhbHVlLgogICAgcHViIGZuIGludG9faW5uZXIoc2VsZikgLT4gVCB7CiAgICAgICAgc2VsZi4wCiAgICB9Cn0KCi8vLyBTZWUgW2hlcmVdKCNleHRyYWN0b3IpIGZvciBleGFtcGxlIG9mIHVzYWdlIGFzIGFuIGV4dHJhY3Rvci4KaW1wbDxUOiBEZXNlcmlhbGl6ZU93bmVkLCBjb25zdCBMSU1JVDogdXNpemU+IEZyb21SZXF1ZXN0IGZvciBVcmxFbmNvZGVkRm9ybTxULCBMSU1JVD4gewogICAgdHlwZSBFcnJvciA9IEVycm9yOwogICAgdHlwZSBGdXR1cmUgPSBVcmxFbmNvZGVkRm9ybUV4dHJhY3RGdXQ8VCwgTElNSVQ+OwoKICAgICNbaW5saW5lXQogICAgZm4gZnJvbV9yZXF1ZXN0KHJlcTogJkh0dHBSZXF1ZXN0LCBwYXlsb2FkOiAmbXV0IFBheWxvYWQpIC0+IFNlbGY6OkZ1dHVyZSB7CiAgICAgICAgVXJsRW5jb2RlZEZvcm1FeHRyYWN0RnV0IHsKICAgICAgICAgICAgcmVxOiBTb21lKHJlcS5jbG9uZSgpKSwKICAgICAgICAgICAgZnV0OiBVcmxFbmNvZGVkRm9ybUJvZHk6Om5ldyhyZXEsIHBheWxvaWNlIHsKICAgICAgICAgICAgc2VydmljZTogYm94ZWQ6OnJjX3NlcnZpY2Uoc2VydmljZSksCiAgICAgICAgICAgIG13X2ZuOiBSYzo6Y2xvbmUoJnNlbGYubXdfZm4pLAogICAgICAgICAgICBfcGhhbnRvbTogUGhhbnRvbURhdGEsCiAgICAgICAgfSkpCiAgICB9Cn0KCi8vLyBNaWRkbGV3YXJlIHNlcnZpY2UgZm9yIFtgZnJvbV9mbmBdLgpwdWIgc3RydWN0IE1pZGRsZXdhcmVGblNlcnZpY2U8RiwgQiwgRXM+IHsKICAgIHNlcnZpY2U6IFJjU2VydmljZTxTZXJ2aWNlUmVxdWVzdCwgU2VydmljZVJlc3BvbnNlPEI+LCBFcnJvcj4sCiAgICBtd19mbjogUmM8Rj4sCiAgICBfcGhhbnRvbTogUGhhbnRvbURhdGE8KEIsIEVzKT4sCn0KCmltcGw8RiwgRnV0LCBCLCBCMj4gU2VydmljZTxTZXJ2aWNlUmVxdWVzdD4gZm9yIE1pZGRsZXdhcmVGblNlcnZpY2U8RiwgQiwgKCk+CndoZXJlCiAgICBGOiBGbihTZXJ2aWNlUmVxdWVzdCwgTmV4dDxCPikgLT4gRnV0LAogICAgRnV0OiBGdXR1cmU8T3V0cHV0ID0gUmVzdWx0PFNlcnZpY2VSZXNwb25zZTxCMj4sIEVycm9yPj4sCiAgICBCMjogTWVzc2FnZUJvZHksCnsKICAgIHR5cGUgUmVzcG9uc2UgPSBTZXJ2aWNlUmVzcG9uc2U8QjI+OwogICAgdHlwZSBFcnJvciA9IEVycm9yOwogICAgdHlwZSBGdXR1cmUgPSBGdXQ7CgogICAgZm9yd2FyZF9yZWFkeSEoc2VydmljZSk7CgogICAgZm4gY2FsbCgmc2VsZiwgcmVxOiBTZXJ2aWNlUmVxdWVzdCkgLT4gU2VsZjo6RnV0dXJlIHsKICAgICAgICAoc2VsZi5td19mbikoCiAgICAgICAgICAgIHJlcSwKICAgICAgICAgICAgTmV4dDo6PEI+IHsKICAgICAgICAgICAgICAgIHNlcnZpY2U6IFJjOjpjbG9uZSgmc2VsZi5zZXJ2aWNlKSwKICAgICAgICAgICAgfSwKICAgICAgICApCiAgICB9Cn0KCm1hY3JvX3J1bGVzISBpbXBsX21pZGRsZXdhcmVfZm5fc2VydmljZSB7CiAgICAoJCgkZXh0X3R5cGU6aWRlbnQpLCopID0+IHsKICAgICAgICBpbXBsPFMsIEYsIEZ1dCwgQiwgQjIsICQoJGV4dF90eXBlKSwqPiBUcmFucyAgICAgYXNzZXJ0X2VxIShyZXNwLnN0YXR1cygpLCBTdGF0dXNDb2RlOjpJTlRFUk5BTF9TRVJWRVJfRVJST1IpOwogICAgfQoKICAgICNbYWN0aXhfd2ViOjp0ZXN0XQogICAgYXN5bmMgZm4gdGVzdF9vdmVycmlkZV9kYXRhKCkgewogICAgICAgIGxldCBzcnYgPSBpbml0X3NlcnZpY2UoCiAgICAgICAgICAgIEFwcDo6bmV3KCkuYXBwX2RhdGEoTG9jYWxEYXRhOjpuZXcoMXVzaXplKSkuc2VydmljZSgKICAgICAgICAgICAgICAgIHdlYjo6cmVzb3VyY2UoIi8iKQogICAgICAgICAgICAgICAgICAgIC5hcHBfZGF0YShMb2NhbERhdGE6Om5ldygxMHVzaXplKSkKICAgICAgICAgICAgICAgICAgICAucm91dGUod2ViOjpnZXQoKS50byh8ZGF0YTogTG9jYWxEYXRhPHVzaXplPnwgewogICAgICAgICAgICAgICAgICAgICAgICBhc3NlcnRfZXEhKCpkYXRhLCAxMCk7CiAgICAgICAgICAgICAgICAgICAgICAgIEh0dHBSZXNwb25zZTo6T2soKQogICAgICAgICAgICAgICAgICAgIH0pKSwKICAgICAgICAgICAgKSwKICAgICAgICApCiAgICAgICAgLmF3YWl0OwoKICAgICAgICBsZXQgcmVxID0gVGVzdFJlcXVlc3Q6OmRlZmF1bHQoKS50b19yZXF1ZXN0KCk7CiAgICAgICAgbGV0IHJlc3AgPSBzcnYuY2FsbChyZXEpLmF3YWl0LnVud3JhcCgpOwogICAgICAgIGFzc2VydF9lcSEocmVzcC5zdGF0dXMoKSwgU3RhdHVzQ29kZTo6T0spOwogICAgfQoKICAgICNbYWN0aXhfd2ViOjp0ZXN0XQogICAgYXN5bmMgZm4gdGVzdF9kYXRhX2Zyb21fcmMoKSB7CiAgICAgICAgbGV0IGRhdGFfbmV3ID0gTG9jYWxEYXRhOjpuZXcoU3RyaW5nOjpmcm9tKCJ0ZXN0LTEyMyIpKTsKICAgICAgICBsZXQgZGF0YV9mcm9tX3JjID0gTG9jYWxEYXRhOjpmcm9tKFJjOjpuZXcoU3RyaW5nOjpmcm9tKCJ0ZXN0LTEyMyIpKSk7CiAgICAgICAgYXNzZXJ0X2VxIShkYXRhX25ldy4wLCBkYXRhX2Zyb21fcmMuMCk7CiAgICB9CgogICAgI1thY3RpeF93ZWI6OnRlc3RdCiAgICBhc3luYyBmbiB0ZXN0X2RhdGFfZnJvbV9keW5fcmMoKSBuc3VtZV9jaHVuaygmbXV0IHNlbGYsIF9yZXE6ICZIdHRwUmVxdWVzdCwgY2h1bms6IEJ5dGVzKSAtPiBSZXN1bHQ8KCksIFNlbGY6OkVycm9yPiB7CiAgICAgICAgRGlnZXN0Ojp1cGRhdGUoJm11dCBzZWxmLmhhc2hlciwgJmNodW5rKTsKICAgICAgICBPaygoKSkKICAgIH0KCiAgICBhc3luYyBmbiBmaW5hbGl6ZShzZWxmLCBfcmVxOiAmSHR0cFJlcXVlc3QpIC0+IFJlc3VsdDxTZWxmOjpTaWduYXR1cmUsIFNlbGY6OkVycm9yPiB7CiAgICAgICAgcHJpbnRsbiEoInVzaW5nIGtleTogezpYP30iLCAmc2VsZi5rZXkpOwoKICAgICAgICBsZXQgbXV0IGhtYWMgPSA8U2ltcGxlSG1hYzxTaGE1MTI+Pjo6bmV3X2Zyb21fc2xpY2UoJnNlbGYua2V5KS51bndyYXAoKTsKCiAgICAgICAgbGV0IHBheWxvYWRfaGFzaCA9IHNlbGYuaGFzaGVyLmZpbmFsaXplKCk7CiAgICAgICAgcHJpbnRsbiEoInBheWxvYWQgaGFzaDoge3BheWxvYWRfaGFzaDpYP30iKTsKICAgICAgICBNYWM6OnVwZGF0ZSgmbXV0IGhtYWMsICZwYXlsb2FkX2hhc2gpOwoKICAgICAgICBPayhobWFjLmZpbmFsaXplKCkpCiAgICB9CgogICAgZm4gdmVyaWZ5KAogICAgICAgIHNpZ25hdHVyZTogU2VsZjo6U2lnbmF0dXJlLAogICAgICAgIHJlcTogJkh0dHBSZXF1ZXN0LAogICAgKSAtPiBSZXN1bHQ8U2VsZjo6U2lnbmF0dXJlLCBTZWxmOjpFcnJvcj4gewogICAgICAgIGxldCB1c2VyX3NpZyA9IGdldF91c2VyX3NpZ25hdHVyZShyZXEpPzsKICAgICAgICBsZXQgdXNlcl9zaWcgPSBDdE91dHB1dDo6bmV3KEdlbmVyaWNBcnJheTo6ZnJvbV9zbGljZSgmdXNlcl9zaWcpLnRvX293bmVkKCkpOwoKICAgICAgICBpZiBzaWduYXR1cmUgPT0gdXNlcl9zaWcgewogICAgICAgICAgICBPayhzaWduYXR1cmUpCiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgRXJyKGVycm9yOjpFcnJvclVuYXV0aG9yaXplZCgKICAgICAgICAgICAgICAgICJnaXZlbiBzaWduYXR1cmUgZG9lcyBub3QgbWF0Y2ggY2FsY3VsYXRlZCBzaWduYXR1cmUiLAogICAgICAgZm9ybTogd2ViOjpKc29uPEhhc2hNYXA8U3RyaW5nLCBTdHJpbmc+PiwKfQoKZm4gbWFpbigpIHt9CnVzZSBzdGQ6OmlvOwoKdXNlIGFjdGl4X3dlYjo6ewogICAgZXJyb3IsCiAgICBodHRwOjpoZWFkZXI6OkhlYWRlclZhbHVlLAogICAgbWlkZGxld2FyZTo6TG9nZ2VyLAogICAgd2ViOjp7c2VsZiwgQnl0ZXN9LAogICAgQXBwLCBFcnJvciwgSHR0cFJlcXVlc3QsIEh0dHBTZXJ2ZXIsCn07CnVzZSBhY3RpeF93ZWJfbGFiOjpleHRyYWN0Ojp7UmVxdWVzdFNpZ25hdHVyZSwgUmVxdWVzdFNpZ25hdHVyZVNjaGVtZX07CnVzZSBhc3luY190cmFpdDo6YXN5bmNfdHJhaXQ7CnVzZSBkaWdlc3Q6OntDdE91dHB1dCwgRGlnZXN0LCBNYWN9Owp1c2UgZ2VuZXJpY19hcnJheTo6R2VuZXJpY0FycmF5Owp1c2UgaG1hYzo6U2ltcGxlSG1hYzsKdXNlIHNoYTI6OntTaGEyNTYsIFNoYTUxMn07CnVzZSB0cmFjaW5nOjppbmZvOwoKI1thbGxvdyhub25fdXBwZXJfY2FzZV9nbG9iYWxzKV0KY29uc3QgZGI6ICgpID0gKCk7Cgphc3luYyBmbiBsb29rdXBfcHVibGljX2tleV9pbl9kYjxUPihfZGI6ICYoKSwgdmFsOiBUKSAtPiBUIHsKICAgIHZhbAp9CgovLy8gRXh0cmFjdHMgdXNlcidzIHB1YmxpYyBrZXkgZnJvbSByZXF1ZXN0IGFuZCBwcmV0ZW5kcyB0byBsb29rIHVwIHNlY3JldCBrZXkgaW4gdGhlIERCLgphc3luYyBmbiBnZXRfYmFzZTY0X2FwaV9rZXkocmVxOiAmSHR0cFJlcXVlc3QpIC0+IGFjdGl4X3dlYjo6UmVzdWx0PFZlYzx1OD4+IHsKICAgIC8vIHB1YmxpYyBrZXksIG5vdCBlbmNyeXB0aW9uIGtleQogICAgbGV0IHB1Yl9rZXkgPSByZXEKICAgICAgICAuaGVhZGVycygpCiAgICAgICAgLmdldCgiQXBpLUtleSIpCiAgICAgICAgLm1hcChIZWFkZXJWYWx1ZTo6YXNfYnl0ZXMpCiAgICAgICAgLm1hcChiYXNlNjQ6OmRlY29kZSkKICAgICAgICAudHJhbnNwb3NlKCkKICAgICAgICAubWFwX2Vycih8X3wgZXJyb3I6OkVycm9ySW50ZXJuYWxTZXJ2ZXJFcnJvcigiaW52YWxpZCBhcGkga2V5IikpP2FwcCwgcmVxKS5hd2FpdDsKICAgICAgICBhc3NlcnRfZXEhKHJlcy5zdGF0dXMoKSwgU3RhdHVzQ29kZTo6T0spOwogICAgICAgIGxldCBib2R5ID0gdGVzdDo6cmVhZF9ib2R5KHJlcykuYXdhaXQ7CiAgICAgICAgYXNzZXJ0X2VxIShib2R5LCAiY29udGVudCIpOwogICAgfQoKICAgICNbYWN0aXhfd2ViOjp0ZXN0XQogICAgYXN5bmMgZm4gY2F0Y2hfcGFuaWNfcmV0dXJuX2ludGVybmFsX3NlcnZlcl9lcnJvcl9yZXNwb25zZSgpIHsKICAgICAgICBsZXQgYXBwID0gdGVzdDo6aW5pdF9zZXJ2aWNlKHRlc3RfYXBwKCkpLmF3YWl0OwoKICAgICAgICBsZXQgcmVxID0gdGVzdDo6VGVzdFJlcXVlc3Q6OndpdGhfdXJpKCIvZGlzY28iKS50b19yZXF1ZXN0KCk7CiAgICAgICAgbGV0IGVyciA9IG1hdGNoIGFwcC5jYWxsKHJlcSkuYXdhaXQgewogICAgICAgICAgICBPayhfKSA9PiBwYW5pYyEoInVuZXhwZWN0ZWQgT2sgcmVzcG9uc2UiKSwKICAgICAgICAgICAgRXJyKGVycikgPT4gZXJyLAogICAgICAgIH07CiAgICAgICAgbGV0IHJlcyA9IGVyci5lcnJvcl9yZXNwb25zZSgpOwogICAgICAgIGFzc2VydF9lcSEocmVzLnN0YXR1cygpLCBTdGF0dXNDb2RlOjpJTlRFUk5BTF9TRVJWRVJfRVJST1IpOwogICAgICAgIGxldCBib2R5ID0gdG9fYnl0ZXMocmVzLmludG9fYm9keSgpKS5hd2FpdC51bndyYXAoKTsKICAgICAgICBhc3NlcnQhKGJvZHkuaXNfZW1wdHkoKSk7CiAgICB9Cn0KdXNlIHN0ZDo6ewogICAgcGluOjpQaW4sCiAgICB0YXNrOjp7Q29udGV4dCwgUG9sbH0sCn07Cgp1c2UgYWN0aXhfd2ViOjpib2R5Ojp7Qm9keVNpemUsIE1lc3NhZ2VCb2R5fTsKdXNlIGJ5dGVzOjpCeXRlczsKdXNlIHRva2lvOjpzeW5jOjptcHNjOjp7ZXJyb3I6OlNlbmRFcnJvciwgVW5ib3VuZGVkUmVjZWl2ZXIsIFVuYm91bmRlZFNlbmRlcn07Cgp1c2UgY3JhdGU6OkJveEVycm9yOwoKLy8vIFJldHVybnMgYSBzZW5kZXIgaGFsZiBhbmQgYSByZWNlaXZlciBoYWxmIHRoYXQgY2FuIGJlIHVzZWQgYXMgYSBib2R5IHRvbjogQ293PCdzdGF0aWMsIHN0cj4sCn0KCmltcGwgU3BhIHsKICAgIC8vLyBMb2NhdGlvbiBvZiB0aGUgU1BBIGluZGV4IGZpbGUuCiAgICAvLy8KICAgIC8vLyBUaGlzIGZpbGUgd2lsbCBiZSBzZXJ2ZWQgaWY6CiAgICAvLy8gLSB0aGUgQWN0aXggV2ViIHJvdXRlciBoYXMgcmVhY2hlZCB0aGlzIHNlcnZpY2UsIGluZGljYXRpbmcgdGhhdCBub25lIG9mIHRoZSBBUEkgcm91dGVzCiAgICAvLy8gICBtYXRjaGVkIHRoZSBVUkwgcGF0aDsKICAgIC8vLyAtIGFuZCBub25lIG9mIHRoZSBzdGF0aWMgcmVzb3VyY2VzIGhhbmRsZWQgbWF0Y2hlZC4KICAgIC8vLwogICAgLy8vIFRoZSBkZWZhdWx0IGlzICIuL2luZGV4Lmh0bWwiLiBJLmUuLCB0aGUgYGluZGV4Lmh0bWxgIGZpbGUgbG9jYXRlZCBpbiB0aGUgZGlyZWN0b3J5IHRoYXQKICAgIC8vLyB0aGUgc2VydmVyIGlzIHJ1bm5pbmcgZnJvbS4KICAgIHB1YiBmbiBpbmRleF9maWxlKG11dCBzZWxmLCBpbmRleF9maWxlOiBpbXBsIEludG88Q293PCdzdGF0aWMsIHN0cj4+KSAtPiBTZWxmIHsKICAgICAgICBzZWxmLmluZGV4X2ZpbGUgPSBpbmRleF9maWxlLmludG8oKTsKICAgICAgICBzZWxmCiAgICB9CgogICAgLy8vIFRoZSBVUkwgcGF0aCBwcmVmaXggdGhhdCBzdGF0aWMgZmlsZXMgc2hvdWxkIGJlIHNlcnZlZCBmcm9tLgogICAgLy8vCiAgICAvLy8gVGhlIGRlZmF1bHQgaXMgIi8iLiBJLmUuLCBzdGF0aWMgZmlsZXMgYXJlIHNlcnZlZCBmcm9tIHRoZSByb290IFVSTCBwYXRoLgogICAgcHViIGZuIHN0YXRpY19yZXNvdXJjZXNfbW91bnQoCiAgICAgICAgbXV0IHNlbGYsCiAgICAgICAgc3RhdGljX3Jlc291cmNlc19tb3VudDogaW1wbCBJbnRvPENvdzwnc3RhdGljLCBzdHI+PiwKICAgICkgLT4gU2VsZiB7CiAgICAgICAgc2VsZi5zdGF0aWNfcmVzb3VyY2VzX21vdW50ID0gc3RhdGljX3Jlc291cmNlc19tb3VudC5pbnRvKCk7CiAgICAgICAgc2VsZgogICAgfQoKICAgIC8vLyBUaGUgbG9jYXRpb24gaW4gdGhlIGZpbGVzeXN0ZW0gdG8gc2VyICAgICAjW2RvYyA9IGNvbmNhdCEoIiMgdHlwZSBIYXNoZXIgPSAiLCBzdHJpbmdpZnkhKCRkaWdlc3QpLCAiOyIpXQogICAgICAgICNbZG9jID0gY29uY2F0ISgiIyBjb25zdCBPdXRTaXplOiB1c2l6ZSA9ICIsICRvdXRfc2l6ZSwgIjsiKV0KICAgICAgICAvLy8gIyBhc3NlcnRfZXEhKAogICAgICAgIC8vLyAjICAgICBkaWdlc3Q6OmdlbmVyaWNfYXJyYXk6OkdlbmVyaWNBcnJheTo6PHU4LAogICAgICAgIC8vLyAjICAgICAgICAgPEhhc2hlciBhcyBkaWdlc3Q6Ok91dHB1dFNpemVVc2VyPjo6T3V0cHV0U2l6ZQogICAgICAgIC8vLyAjICAgICA+OjpkZWZhdWx0KCkubGVuKCksCiAgICAgICAgLy8vICMgICAgIE91dFNpemUKICAgICAgICAvLy8gIyApOwogICAgICAgIC8vLyBgYGAKICAgICAgICAjW2NmZyhmZWF0dXJlID0gJGZlYXR1cmUpXQogICAgICAgIHB1YiB0eXBlICRuYW1lPFQ+ID0gQm9keUhhc2g8VCwgJGRpZ2VzdD47CiAgICB9Owp9CgovLyBPYnNvbGV0ZQpib2R5X2hhc2hfYWxpYXMhKEJvZHlNZDQsIG1kNDo6TWQ0LCAibWQ0IiwgIk1ENCIsIDE2KTsKYm9keV9oYXNoX2FsaWFzIShCb2R5TWQ1LCBtZDU6Ok1kNSwgIm1kNSIsICJNRDUiLCAxNik7CmJvZHlfaGFzaF9hbGlhcyEoQm9keVNoYTEsIHNoYTE6OlNoYTEsICJzaGExIiwgIlNIQS0xIiwgMjApOwoKLy8gU0hBLTIKYm9keV9oYXNoX2FsaWFzIShCb2R5U2hhMjI0LCBzaGEyOjpTaGEyMjQsICJzaGEyIiwgIlNIQS0yMjQiLCAyOCk7CmJvZHlfaGFzaF9hbGlhcyEoQm9keVNoYTI1Niwgc2hhMjo6U2hhMjU2LCAic2hhMiIsICJTSEEtMjU2IiwgMzIpOwpib2R5X2hhc2hfYWxpYXMhKEJvZHlTaGEzODQsIHNoYTI6OlNoYTM4NCwgInNoYTIiLCAiU0hBLTM4NCIsIDQ4KTsKYm9keV9oYXNoX2FsaWFzIShCb2R5U2hhNTEyLCBzaGEyOjpTaGE1MTIsICJzaGEyIiwgIlNIQS01MTIiLCA2NCk7CgovLyBTSEEtMwpib2R5X2hhc2hfYWxpYXMhKEJvZHlTaGEzXzIyNCwgc2hhMzo6U2hhM18yMjQsICJzaGEzIiwgIlNIQS0zLTIyNCIsIGVfc2xhc2gucmVwbGFjZV9hbGwoJnBhdGgsICIvIik7CgogICAgICAgICAgICAvLyBFbnN1cmUgcm9vdCBwYXRocyBhcmUgc3RpbGwgcmVzb2x2YWJsZS4gSWYgcmVzdWx0aW5nIHBhdGggaXMgYmxhbmsgYWZ0ZXIgcHJldmlvdXMKICAgICAgICAgICAgLy8gc3RlcCBpdCBtZWFucyB0aGUgcGF0aCB3YXMgb25lIG9yIG1vcmUgc2xhc2hlcy4gUmVkdWNlIHRvIHNpbmdsZSBzbGFzaC4KICAgICAgICAgICAgbGV0IHBhdGggPSBpZiBwYXRoLmlzX2VtcHR5KCkgeyAiLyIgfSBlbHNlIHsgcGF0aC5hc19yZWYoKSB9OwoKICAgICAgICAgICAgLy8gQ2hlY2sgd2hldGhlciB0aGUgcGF0aCBoYXMgYmVlbiBjaGFuZ2VkCiAgICAgICAgICAgIC8vCiAgICAgICAgICAgIC8vIFRoaXMgY2hlY2sgd2FzIHByZXZpb3VzbHkgaW1wbGVtZW50ZWQgYXMgc3RyaW5nIGxlbmd0aCBjb21wYXJpc29uCiAgICAgICAgICAgIC8vCiAgICAgICAgICAgIC8vIFRoYXQgYXBwcm9hY2ggZmFpbHMgd2hlbiBhIHRyYWlsaW5nIHNsYXNoIGlzIGFkZGVkLAogICAgICAgICAgICAvLyBhbmQgYSBkdXBsaWNhdGUgc2xhc2ggaXMgcmVtb3ZlZCwKICAgICAgICAgICAgLy8gc2luY2UgdGhlIGxlbmd0aCBvZiB0aGUgc3RyaW5ncyByZW1haW5zIHRoZSBzYW1lCiAgICAgICAgICAgIC8vCiAgICAgICAgICAgIC8vIEZvciBleGFtcGxlLCB0aGUgcGF0aCAiL3YxLy9zIiB3aWxsIGJlIG5vcm1hbGl6ZWQgdG8gIi92MS9zLyIKICAgICAgICAgICAgLy8gQm90aCBvZiB0aGUgcGF0aHMgaGF2ZSB0aGUgc2FtZSBsZW5ndGgsCiAgICAgICAgICAgIC8vIHNvIHRoZSBjaGFuZ2UgY2FuIG5vdCBiZSBkZWR1Y2VkIGZyb20gdGhlIGxlbmd0aCBjb21wYXJpc29uCiAgICAgICAgICAgIGlmIHBhdGggIT0gb3JpZ2luYWxfcGF0aCB7CiAgICAgICAgICAgICAgICBsZXQgbXV0IHBhcnRzID0gaGVhZC51cmkuY2xvbmUoKS5pbnRvX3BhcnRzKCk7CiAgICAgICAgICAgICAgICBsZXQgcXVlcnkgPSBwYXJ0cy5wYXRoX2FuZF9xdWVyeS5hc19yZWYoKS5hbmQzLCAyMSwgMjQ3LCAwXSkpKTsKICAgIGRiZyEoaXBzLmNvbnRhaW5zKElwQWRkcjo6ZnJvbShbMTAzLCAyMSwgMjQ4LCAwXSkpKTsKfQp1c2UgYWN0aXhfd2ViOjp7CiAgICBib2R5OjpNZXNzYWdlQm9keSwKICAgIGRldjo6e1NlcnZpY2VSZXF1ZXN0LCBTZXJ2aWNlUmVzcG9uc2V9LAogICAgd2ViOjpSZWRpcmVjdCwKICAgIEVycm9yLCBSZXNwb25kZXIsCn07Cgp1c2UgY3JhdGU6Om1pZGRsZXdhcmVfZnJvbV9mbjo6TmV4dDsKCi8vLyBBIGZ1bmN0aW9uIG1pZGRsZXdhcmUgdG8gcmVkaXJlY3QgdHJhZmZpYyB0byBgd3d3LmAgaWYgbm90IGFscmVhZHkgdGhlcmUuCi8vLwovLy8gIyBFeGFtcGxlcwovLy8gYGBgCi8vLyAjIHVzZSBhY3RpeF93ZWI6OkFwcDsKLy8vIHVzZSBhY3RpeF93ZWJfbGFiOjptaWRkbGV3YXJlOjp7ZnJvbV9mbiwgcmVkaXJlY3RfdG9fd3d3fTsKLy8vCi8vLyBBcHA6Om5ldygpCi8vLyAgICAgLndyYXAoZnJvbV9mbihyZWRpcmVjdF90b193d3cpKQovLy8gICAgICMgOwovLy8gYGBgCnB1YiBhc3luYyBmbiByZWRpcmVjdF90b193d3coCiAgICByZXE6IFNlcnZpY2VSZXF1ZXN0LAogICAgbmV4dDogTmV4dDxpbXBsIE1lc3NhZ2VCb2R5ICsgJ3N0YXRpYz4sCikgLT4gUmVzdWx0PFNlcnZpY2VSZXNwb25zZTxpbXBsIE1lc3NhZ2VCb2R5PiwgRXJyb3I+IHsKICAgICMhW2FsbG93KGNsaXBweTo6YXdhaXRfaG9sZGluZ19yZWZjZWxsX3JlZildIC8vIFJlZkNlbGwgaXMgZHJvcHBlZCBiZWZvcmUgYXdhaXQKCiAgICBsZXQgKHJlcSwgcGwpID0gcmVxLmludG9fcGFydHMoKTsKICAgIGxldCBjb25uX2luZm8gPSByZXEuY29ubmVjdGlvbl9pbmZvKCk7CgogICAgaWYgIWNvbm5faW5mby5ob3N0KCkuc3RhcnRzX3dpdGgoInd3dy4iKSB7CiAgICAgICAgbGV0IHNjaGVtZSA9IGNvbm5faW5mby5zY2hlbWUoKTsKICAgICAgICBsZXQgaG9zdCA9IGNvbm5faW5mby5ob3N0KCk7CiAgICAgICAgbGV0IHBhdGggPSByZXEudXJpKCkucGF0aCgpOwogICAgICAgIGxldCB1cmkgPSBmb3JtJGhkcl9uYW1lOmV4cHIgPT4gJGhkcl92YWw6ZXhwcikrOyBAcmF3ICRwYXlsb2FkOmV4cHIpID0+IHt7CiAgICAgICAgYXNzZXJ0X3Jlc3BvbnNlX21hdGNoZXMhKCRyZXMsICRzdGF0dXM7ICQoJGhkcl9uYW1lID0+ICRoZHJfdmFsKSspOwogICAgICAgIGFzc2VydF9lcSEoOjphY3RpeF93ZWI6OnRlc3Q6OnJlYWRfYm9keSgkcmVzKS5hd2FpdCwgJHBheWxvYWQpOwogICAgfX07CgogICAgKCRyZXM6aWRlbnQsICRzdGF0dXM6aWRlbnQ7IEBqc29uICRwYXlsb2FkOnR0KSA9PiB7ewogICAgICAgIGFzc2VydF9yZXNwb25zZV9tYXRjaGVzISgkcmVzLCAkc3RhdHVzKTsKICAgICAgICBhc3NlcnRfZXEhKAogICAgICAgICAgICA6OmFjdGl4X3dlYjo6dGVzdDo6cmVhZF9ib2R5X2pzb246OjwkY3JhdGU6Ol9fcmVleHBvcnRzOjpzZXJkZV9qc29uOjpWYWx1ZSwgXz4oJHJlcykuYXdhaXQsCiAgICAgICAgICAgICRjcmF0ZTo6X19yZWV4cG9ydHM6OnNlcmRlX2pzb246Ompzb24hKCRwYXlsb2FkKSwKICAgICAgICApOwogICAgfX07Cn0KCnB1YiB1c2UgYXNzZXJ0X3Jlc3BvbnNlX21hdGNoZXM7CgojW2NmZyh0ZXN0KV0KbW9kIHRlc3RzIHsKICAgIHVzZSBhY3RpeF93ZWI6OnsKICAgICAgICBkZXY6OlNlcnZpY2VSZXNwb25zZSwgaHR0cDo6aGVhZGVyOjpDb250ZW50VHlwZSwgdGVzdDo6VGVzdFJlcXVlc3QsIEh0dHBSZXNwb25zZSwKICAgIH07CgogICAgdXNlIHN1cGVyOjoqOwoKICAgICNbYWN0aXhfd2ViOjp0ZXN0XQogICAgYXN5bmMgZm4gcmVzcG9uc2VfbWF0Y2hpbmcoKSB7CiAgICAgICAgbGV0IHJlcyA9IFNlcnZpY2VSZXNwb25zZTo6bmV3KAogICAgICAgICAgICBUZXN0UmVxdWVzdDo6ZGVmYXVsdCgpLnRvX2h0dHBfcmVxdWVzdCgpLAogICAgICAgICAgICBIdHRwUmVzcG9uc2U6OkNyZWF0ZWQoKQogICAgICAgICAgICAgICAgLmluc2VydF9oZWFkZXIoKCJkYXRlIiwgInRvZGF5IikpCiAgICAgICAgICAgICAgICAuaW5zZXJ0X2hlYWRlcigoInNldC1jb29raWUiLCAiYT1iIikpCiAgIChTb21lKE9rKEV2ZW50OjpyZXRyeV90b19ieXRlcyhyZXRyeSkpKSk7CiAgICAgICAgfQoKICAgICAgICBpZiBsZXQgUG9sbDo6UmVhZHkobXNnKSA9IHRoaXMuc3RyZWFtLnBvbGxfbmV4dChjeCkgewogICAgICAgICAgICByZXR1cm4gbWF0Y2ggbXNnIHsKICAgICAgICAgICAgICAgIFNvbWUoT2sobXNnKSkgPT4gUG9sbDo6UmVhZHkoU29tZShPayhtc2cuaW50b19ieXRlcygpKSkpLAogICAgICAgICAgICAgICAgU29tZShFcnIoZXJyKSkgPT4gUG9sbDo6UmVhZHkoU29tZShFcnIoZXJyLmludG8oKSkpKSwKICAgICAgICAgICAgICAgIE5vbmUgPT4gUG9sbDo6UmVhZHkoTm9uZSksCiAgICAgICAgICAgIH07CiAgICAgICAgfQoKICAgICAgICBpZiBsZXQgU29tZShyZWYgbXV0IGtlZXBfYWxpdmUpID0gdGhpcy5rZWVwX2FsaXZlIHsKICAgICAgICAgICAgaWYga2VlcF9hbGl2ZS5wb2xsX3RpY2soY3gpLmlzX3JlYWR5KCkgewogICAgICAgICAgICAgICAgcmV0dXJuIFBvbGw6OlJlYWR5KFNvbWUoT2soRXZlbnQ6OmtlZXBfYWxpdmVfYnl0ZXMoKSkpKTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgUG9sbDo6UGVuZGluZwogICAgfQp9CgovLy8gQ3JlYXRlIHNlcnZlci1zZW50IGV2ZW50cyAoU1NFKSBjaGFubmVsIHBhaXIuCi8vLwovLy8gVGhlIGBidWZmZXJgIGFyZ3VtZW50IGNvbnRyb2xzIGhvdyBtYW55IHVuc2VudCBtZXNzYWdlcyBjYW4gYmUgc3RvcmVkIHdpdGhvdXQgd2FpdGluZy4KLy8vCi8vLyBUaGUgZmlyc3QgaXRlbSBpbiB0aGUgdHVwbGUgaXMgdGhlIHNlbmRlciBoYWxmLiBNdWNoIGxpa2UgYSByZWd1bGFyIGNoYW5uZWwsIGl0IGNhbiBiZSBjbG9uZWQsCi8vLyBzZW50IHRvIGFub3RoZXIgdGhyZWFkL3Rhc2ssIGFuZCBzZW5kIGV2ZW50IG1lc3NhZ2VzIHRvIHRoZSByZXNwb25zZSBzdHJlYW0uIEl0IHByb3ZpZGVzIHNldmVyYWwKLy8vIG1ldGhvZHMgdGhhdCByZXByZXNlbnQgdGhlIGV2ZW50LXN0cmVhbSBmb3JtYXQuCi8vLwovLy8gVGhlIHNlY29uZCBpdGUuaW50bygpKTsKICAgICAgICBzZWxmCiAgICB9CgogICAgLy8vIFNldHMgYGlkYCBmaWVsZC4KICAgIHB1YiBmbiBzZXRfaWQoJm11dCBzZWxmLCBpZDogaW1wbCBJbnRvPEJ5dGVTdHJpbmc+KSB7CiAgICAgICAgc2VsZi5pZCA9IFNvbWUoaWQuaW50bygpKTsKICAgIH0KCiAgICAvLy8gU2V0cyBgZXZlbnRgIG5hbWUgZmllbGQsIHJldHVybmluZyBhIG5ldyBkYXRhIG1lc3NhZ2UuCiAgICBwdWIgZm4gZXZlbnQobXV0IHNlbGYsIGV2ZW50OiBpbXBsIEludG88Qnl0ZVN0cmluZz4pIC0+IFNlbGYgewogICAgICAgIHNlbGYuZXZlbnQgPSBTb21lKGV2ZW50LmludG8oKSk7CiAgICAgICAgc2VsZgogICAgfQoKICAgIC8vLyBTZXRzIGBldmVudGAgbmFtZSBmaWVsZC4KICAgIHB1YiBmbiBzZXRfZXZlbnQoJm11dCBzZWxmLCBldmVudDogaW1wbCBJbnRvPEJ5dGVTdHJpbmc+KSB7CiAgICAgICAgc2VsZi5ldmVudCA9IFNvbWUoZXZlbnQuaW50bygpKTsKICAgIH0KfQoKaW1wbCBGcm9tPERhdGE+IGZvciBFdmVudCB7CiAgICBmbiBmcm9tKGRhdGE6IERhdGEpIC0+IFNlbGYgewogICAgICAgIFNlbGY6OkRhdGEoZGF0YSkKICAgIH0KfQoKLy8vIFNlcnZlci1zZW50IGV2ZW50cyBtZXNzYWdlIGNvbnRhaW5pbmcgb25lIG9yIG1vcmUgZmllbGRzLgojW211c3RfdXNlXQojW2Rlcml2ZShEZWJ1ZywgQ2xvbmUpXQpwdWIgZW51bSBFdmVudCB7CiAgICAvLy8gQSBgZGF0YWAgbWVzc2FnZSB3aXRoIG9wdGlvbmFsIElEIGFuZCBldmVudCBuYW1lLgogICAgLy8vCiAgICAvLy8gRGF0YSBtZXNzYWdlcyBsb29rcyBsaWtlIHRoaXMgaW4gdGhlIHJlc3BvbnNlIHN0cmVhbS4KICAgIC8vLyBgYGBwbGFpbgogICAgLy8vIGV2ZW50OiBmb28KICAgIC8vLyBpZDogNDIKICAgIC8vLyBkYXRhOiBteSBkYXRhCiAgICAvLy8KICAgIC8vLyBkYXRhOiB7CiAgICAvLy8gZGF0YTogICAibXVsdGlsaW5lIjogImRhdGEiCiAgICAvLy8gZGF0YTogfQogICAgLy8vIGBgYAogICAgRGF0YShEYXRhKSwKCiAgICAvLy8gQSBjb21tKG5vb3ApKSk7CiAgICAgICAgbGV0IF8gPSBBcHA6Om5ldygpLndyYXAoQ29tcGF0OjpuZXcobWFwX3Jlc3BvbnNlX2JvZHkobXV0YXRlX2JvZHlfdHlwZSkpKTsKICAgIH0KCiAgICAjW2FjdGl4X3dlYjo6dGVzdF0KICAgIGFzeW5jIGZuIGZlZWxzX2dvb2QoKSB7CiAgICAgICAgbGV0IGFwcCA9IHRlc3Q6OmluaXRfc2VydmljZSgKICAgICAgICAgICAgQXBwOjpuZXcoKQogICAgICAgICAgICAgICAgLmRlZmF1bHRfc2VydmljZSh3ZWI6OnRvKEh0dHBSZXNwb25zZTo6T2spKQogICAgICAgICAgICAgICAgLndyYXAobWFwX3Jlc3BvbnNlX2JvZHkofF9yZXEsIGJvZHl8IGFzeW5jIG1vdmUgeyBPayhib2R5KSB9KSkKICAgICAgICAgICAgICAgIC53cmFwKG1hcF9yZXNwb25zZV9ib2R5KG5vb3ApKQogICAgICAgICAgICAgICAgLndyYXAoTG9nZ2VyOjpkZWZhdWx0KCkpCiAgICAgICAgICAgICAgICAud3JhcChtYXBfcmVzcG9uc2VfYm9keShtdXRhdGVfYm9keV90eXBlKSksCiAgICAgICAgKQogICAgICAgIC5hd2FpdDsKCiAgICAgICAgbGV0IHJlcSA9IHRlc3Q6OlRlc3RSZXF1ZXN0OjpkZWZhdWx0KCkudG9fcmVxdWVzdCgpOwogICAgICAgIGxldCBib2R5ID0gdGVzdDo6Y2FsbF9hbmRfcmVhZF9ib2R5KCZhcHAsIHJlcSkuYXdhaXQ7CiAgICAgICAgYXNzZXJ0X2VxIShib2R5LCAiZm9vIik7CiAgICB9Cn0KdXNlIGFjdGl4X3dlYjo6ewogICAgaHR0cDo6e01ldGhvZCwgU3RhdHVzQ29kZX0sCiAgICB3ZWIsIEFwcCwgSHR0cFJlc3BvbnNlLCBSZXNwb25kZXIsCn07CnVzZSBhY3RpeF93ZWJfbGFiX2Rlcml2ZTo6RnJvbVJlcXVlc3Q7CgojW2Rlcml2ZShEZWJ1ZywgRnJvbVJlcXVlc3QpXQpzdHJ1Y3QgUmVxdWVzdFBhcnRzIHsKICAgIG1ldGhvZDogTWV0aG9kLAogICAgcG9vbDogd2ViOjpEYXRhPHUzMj4sCiAgICBib2R5OiBTdHJpbmcsCiAgICBib2R5MjogU3RyaW5nLAoKICAgICNbZnJvbV9yZXF1ZXN0KGNvcHlfZnJvbV9hcHBfZGF0YSldCiAgICBjb3BpZWRfZGF0YTogdTY0LAp9Cgphc3N0ZWRJcHM6OnRyeV9mcm9tX3Jlc3BvbnNlKHJlcykuaXNfZXJyKCkpOwogICAgfQp9Ci8vISBGb3IgcGF0aCBzZWdtZW50IGV4dHJhY3RvciBkb2N1bWVudGF0aW9uLCBzZWUgW2BQYXRoYF0uCgp1c2UgYWN0aXhfcm91dGVyOjpQYXRoRGVzZXJpYWxpemVyOwp1c2UgYWN0aXhfdXRpbHM6OmZ1dHVyZTo6e3JlYWR5LCBSZWFkeX07CnVzZSBhY3RpeF93ZWI6OnsKICAgIGRldjo6UGF5bG9hZCwKICAgIGVycm9yOjp7RXJyb3IsIEVycm9yTm90Rm91bmR9LAogICAgRnJvbVJlcXVlc3QsIEh0dHBSZXF1ZXN0LAp9Owp1c2UgZGVyaXZlX21vcmU6OntBc1JlZiwgRGlzcGxheSwgRnJvbX07CnVzZSBzZXJkZTo6ZGU7CnVzZSB0cmFjaW5nOjpkZWJ1ZzsKCi8vLyBFeHRyYWN0IHR5cGVkIGRhdGEgZnJvbSByZXF1ZXN0IHBhdGggc2VnbWVudHMuCi8vLwovLy8gQWx0ZXJuYXRpdmUgdG8gYHdlYjo6UGF0aGAgZXh0cmFjdG9yIGZyb20gQWN0aXggV2ViIHRoYXQgYWxsb3dzIGRlY29uc3RydWN0aW9uLCBidXQgb21pdHMgdGhlCi8vLyBpbXBsZW1lbnRhdGlvbiBvZiBgRGVyZWZgLgovLy8KLy8vIFVubGlrZSwgW2BIdHRwUmVxdWVzdDo6bWF0Y2hfaW5mb2BdLCB0aGlzIGV4dHJhY3RvciB3aWxsIGZ1bGx5IHBlcmNlbnQtZGVjb2RlIGR5bmFtaWMgc2VnbWVudHMsCi8vLyBpbmNsdWRpbmcgYC9gLCBgJWAsIGFuZCBgK2AuCi8vLwovLy8gIyBFeGFtcGxlcwovLy8gYGBgCi8vLyB1c2UgYWN0aXhfd2ViOjpnZXQ7Ci8vLyB1c2UgYWN0aXhfd2ViX2xhYjo6ZXh0cmFjdDo6UGF0aDsKLy8vCi8vLyAvLyBleHRyYWN0IHBhdGggaW5mbyBmcm9tICIve25hbWV9L3tjb3VudH0vaW5kZXguaHRtbCIgaW50byB0dXBsZQovLy8gLy8ge25hbWV9ICAtIGRlc2VyaWFsaXplIGEgU3RyaW5nCi8vLyAvLyB7Y291bnR9IC0gZGVzZXJpYWxpemUgYSB1MzIKLy8vICNbZ2V0KCIve25hbWV9L3tjb3VudH0vaW5kZXguaHRtbCIpXQovLy8gYXN5bmMgZm4gaW5kZXgoUGF0aCgobmFtZSwgY291bnQpKTogUGF0aDwoU3RyaW5nLCB1MzIgZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBidWYuZXh0ZW5kX2Zyb21fc2xpY2UoJmNodW5rKTsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgTm9uZSA9PiB7CiAgICAgICAgICAgICAgICAgICAgICAgIGxldCBqc29uID0gc2VyZGVfanNvbjo6ZnJvbV9zbGljZTo6PFQ+KGJ1ZikKICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5tYXBfZXJyKEpzb25QYXlsb2FkRXJyb3I6OkRlc2VyaWFsaXplKT87CiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBQb2xsOjpSZWFkeShPayhqc29uKSk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9LAoKICAgICAgICAgICAgSnNvbkJvZHk6OkVycm9yKGUpID0+IFBvbGw6OlJlYWR5KEVycihlLnRha2UoKS51bndyYXAoKSkpLAogICAgICAgIH0KICAgIH0KfQoKI1tjZmcodGVzdCldCm1vZCB0ZXN0cyB7CiAgICB1c2UgYWN0aXhfd2ViOjp7aHR0cDo6aGVhZGVyLCB0ZXN0OjpUZXN0UmVxdWVzdCwgd2ViOjpCeXRlc307CiAgICB1c2Ugc2VyZGU6OntEZXNlcmlhbGl6ZSwgU2VyaWFsaXplfTsKCiAgICB1c2Ugc3VwZXI6Oio7CgogICAgI1tkZXJpdmUoU2VyaWFsaXplLCBEZXNlcmlhbGl6ZSwgUGFydGlhbEVxLCBEZWJ1ZyldCiAgICBzdHJ1Y3QgTXlPYmplY3QgewogICAgICAgIG5hbWU6IFN0cmluZywKICAgIH0KCiAgICBmbiBqc29uX2VxKGVycjogSnNvblBheWxvYWRFcnJvciwgb3RoZXI6IEpzb25QYXlsb2FkRXJyb3IpIC0+IGJvb2wgewogICAgICAgIG1hdGNoIGVyciB7CiAgICAgICAgICAgIEpzb25QYXlsb2FkRXJyb3I6Ok92ZXJmbG93IHsgLi4gfSA9PiB7CiAgICAgICAgICAgICAgICBtYXRjaGVzIShvdGhlciwgSnNvblBheWxvYWRFcnJvcjo6T3ZlcmZsb3cgeyAuLiB9KQogICAgICAgICAgICB9CiAgICAgICAgICAgIEpzb25QYXlsb2FkRXJyb3I6Ok92ZXJmbG93S25vd25MZW5ndGggeyAuLiB9Zm9ybWF0ISgiZXJyb3IgZnJvbSBvcmlnaW5hbCBzdHJlYW06IHtlcnJ9IiksCiAgICAgICAgICAgICAgICApKSkpCiAgICAgICAgICAgICAgICAudW53cmFwKCksCiAgICAgICAgfQogICAgfSkpOwoKICAgIHRyYWNpbmc6OnRyYWNlISh0YXJnZXQ6IFRBUkdFVCwgImNyZWF0aW5nIHByb3h5IHBheWxvYWQiKTsKICAgICpvcmlnX3BheWxvYWQgPSBkZXY6OlBheWxvYWQ6OmZyb20ocHJveHlfc3RyZWFtKTsKCiAgICBkZXY6OlBheWxvYWQ6OlN0cmVhbSB7CiAgICAgICAgcGF5bG9hZDogQm94OjpwaW4ocngpLAogICAgfQp9CgovLy8gQW4gYGlvOjpXcml0ZWByIHRoYXQgb25seSByZXF1aXJlcyBtdXRhYmxlIHJlZmVyZW5jZSBhbmQgYXNzdW1lcyB0aGF0IHRoZXJlIGlzIHNwYWNlIGF2YWlsYWJsZQovLy8gaW4gdGhlIGJ1ZmZlciBmb3IgZXZlcnkgd3JpdGUgb3BlcmF0aW9uIG9yIHRoYXQgaXQgY2FuIGJlIGV4dGVuZGVkIGltcGxpY2l0bHkgKGxpa2UKLy8vIGBieXRlczo6Qnl0ZXNNdXRgLCBmb3IgZXhhbXBsZSkuCi8vLwovLy8gVGhpcyBpcyBzbGlnaHRseSBmYXN0ZXIgKH4xMCUpIHRoYW4gYGJ5dGVzOjpidWY6OldyaXRlcmAgaW4gc3VjaCBjYXNlcyBiZWNhdXNlIGl0IGRvZXMgbm90Ci8vLyBwZXJmb3JtIGEgcmVtYWluaW5nIGxlbmd0aCBjaGVjayBiZWZvcmUgd3JpdGluZy4KcHViKGNyYXRlKSBzdHJ1Y3QgTXV0V3JpdGVyPCdhLCBCPihwdWIoY3JhdGUpICYnYSBtdXQgQik7CgppbXBsPCdhLCBCPiBNdXRXcml0ZXI8J2EsIEI+IHsKICAgIHB1YiBmbiBnZXRfcmVmKCZzZWxmKSAtPiAmQiB7CiAgICAgICAgc2VsZi4wCiAgICB9Cn0KCmltcGw8J2EsIEI6IEJ1Zk11dD4gaW86OldyaXRlIGZvciBNdXRXcml0ZXI8J2EsIEI+IHsKICAgIGZuIHdyaXRlKCZtdXQgc2VsZiwgYnVmOiAmW3U4XSkgLT4gaW86OlJlc3VsdDx1c2l6ZT4gewogICAgICAgIHNlbGYuMC5wdXRfc2xpY2UoYnVmKTsKICAgICAgICBPayhidWYubGVuKCkpCiAgICB9CgogICAgZm4gZmx1c2goJm11dCBzZWxmKSAtPiBpb2YuaW50b19jaHVua19zdHJlYW0oKSkKICAgIH0KCiAgICAvLy8gQ3JlYXRlcyBhIGBSZXNwb25kZXJgIHR5cGUgd2l0aCBhIGxpbmUtYnktbGluZSBzZXJpYWxpemluZyBzdHJlYW0gYW5kIGB0ZXh0L3BsYWluYAogICAgLy8vIGNvbnRlbnQtdHlwZSBoZWFkZXIuCiAgICBwdWIgZm4gaW50b19yZXNwb25kZXIoc2VsZikgLT4gaW1wbCBSZXNwb25kZXIKICAgIHdoZXJlCiAgICAgICAgUzogJ3N0YXRpYywKICAgICAgICBUOiAnc3RhdGljLAogICAgICAgIEU6ICdzdGF0aWMsCiAgICB7CiAgICAgICAgSHR0cFJlc3BvbnNlOjpPaygpCiAgICAgICAgICAgIC5jb250ZW50X3R5cGUobWltZTo6VEVYVF9QTEFJTl9VVEZfOCkKICAgICAgICAgICAgLm1lc3NhZ2VfYm9keShzZWxmLmludG9fYm9keV9zdHJlYW0oKSkKICAgICAgICAgICAgLnVud3JhcCgpCiAgICB9CgogICAgLy8vIENyZWF0ZXMgYSBzdHJlYW0gb2Ygc2VyaWFsaXplZCBjaHVua3MuCiAgICBwdWIgZm4gaW50b19jaHVua19zdHJlYW0oc2VsZikgLT4gaW1wbCBTdHJlYW08SXRlbSA9IFJlc3VsdDxCeXRlcywgRT4+IHsKICAgICAgICBzZWxmLnN0cmVhbS5tYXBfb2sod3JpdGVfZGlzcGxheSkKICAgIH0KfQoKZm4gd3JpdGVfZGlzcGxheShpdGVtOiBpbXBsIGZtdDo6RGlzcGxheSkgLT4gQnl0ZXMgewogICAgbGV0IG11dCBidWYgPSBCeXRlc011dDo6bmV3KCk7CiAgICBsZXQgbXV0IHdydCA9IE11dFdyaXRlcigmbXV0IGJ1Zik7CgogICAgd3JpdGVsbiEod3J0LCAie2l0ZW19IikudW53cmFwKCk7CgogICAgYnVmLmZyZWV6ZSgpCn0KCiNbY2ZnKHRlc3QpXQptb2QgdGVzdHMgewogICAgdXNlIHN0ZDo6ZXJyb3I6OkVycm9yIGFzIFN0ZEVycm9yOwoKICAgIHVzZSBhY3RpeF93ZWI6OmJvZHk7CiAgICB1c2UgZnV0dXJlc191dGlsOjpzdHJlYW07CgogICAgdXNlIHN1cGVyOjoqOwoKICAgICNbYWN0aXhfd2ViOjp0ZXN0XQogICAgYXN5bmMgZm4gc2VyaWFsaXplc19pbnRvX2JvZHkoKSB7CiAgICAgICAgbGV0IG5kanNvbl9ib2R5ID0gRGlvLm1hcCh8cHJvdG98IGZvcm1hdCEoInByb3RvPVwie3Byb3RvfVwiIikpKQogICAgICAgICAgICAuam9pbigiOyAiKQogICAgICAgICAgICAudHJ5X2ludG9fdmFsdWUoKQogICAgfQp9CgppbXBsIEhlYWRlciBmb3IgRm9yd2FyZGVkIHsKICAgIGZuIG5hbWUoKSAtPiBIZWFkZXJOYW1lIHsKICAgICAgICBoZWFkZXI6OkZPUldBUkRFRAogICAgfQoKICAgIGZuIHBhcnNlPE06IEh0dHBNZXNzYWdlPihtc2c6ICZNKSAtPiBSZXN1bHQ8U2VsZiwgUGFyc2VFcnJvcj4gewogICAgICAgIGxldCBjb21iaW5lZCA9IG1zZwogICAgICAgICAgICAuaGVhZGVycygpCiAgICAgICAgICAgIC5nZXRfYWxsKFNlbGY6Om5hbWUoKSkKICAgICAgICAgICAgLmZpbHRlcl9tYXAofGhkcnwgaGRyLnRvX3N0cigpLm9rKCkpCiAgICAgICAgICAgIC5maWx0ZXJfbWFwKHxoZHJfc3RyfCBtYXRjaCBoZHJfc3RyLnRyaW0oKSB7CiAgICAgICAgICAgICAgICAiIiA9PiBOb25lLAogICAgICAgICAgICAgICAgdmFsID0+IFNvbWUodmFsKSwKICAgICAgICAgICAgfSkKICAgICAgICAgICAgLmNvbGxlY3Q6OjxWZWM8Xz4+KCk7CgogICAgICAgIGlmIGNvbWJpbmVkLmlzX2VtcHR5KCkgewogICAgICAgICAgICByZXR1cm4gRXJyKFBhcnNlRXJyb3I6OkhlYWRlcik7CiAgICAgICAgfQoKICAgICAgICAvLyBwYXNzIHRvIEZyb21TdHIgaW1wbCBhcyBpZiBpdCB3ZXJlIG9uZSBjb25jYXRlbmF0ZWQgaGVhZGVyIHdpdGggc2VtaWNvbG9uIGpvaW5lcnMKICAgICAgICAvLyBodHRwczovL2RhdGF0cmFja2VyLmlldGYub3JnL2RvYy9odG1sL3JmYzcyMzkjc2VjdGlvbi03LjEKICAgICAgICBjb21iaW5lZC5qb2luKCI7IikucGFyc2UoKS5tYXBfZXJyKHxffCBQYXJzZUVycm9yOjpIZWFkZXIpCiAgICB9Cn0KCi8vLyBUcmltIHdoaXRlc3BhY2UgdGhlbiBhbnkgcXVvdGUgbWFya3MuCmZuIHVucXVvdGUodmFsOiAmc3RyKSAtPiAmc3RyIHsKICAgIHZhbC50cmltKCkudHJpbV9zdGFydF9tYXRjaGVzKCciJykudHJpbV9lbmRfbWF0Y2hlLy8vIFNob3VsZCBlcXVhbCB0aGUgYEhvc3RgIHJlcXVlc3QgaGVhZGVyIGZpZWxkIGFzIHJlY2VpdmVkIGJ5IHRoZSBwcm94eS4KICAgIHB1YiBmbiBob3N0KCZzZWxmKSAtPiBPcHRpb248JnN0cj4gewogICAgICAgIHNlbGYuaG9zdC5hc19kZXJlZigpCiAgICB9CgogICAgLy8vIFJldHVybnMgdGhlICJwcm90byIgaWRlbnRpZmllciwgaWYgc2V0LgogICAgLy8vCiAgICAvLy8gSW5kaWNhdGVzIHdoaWNoIHByb3RvY29sIHdhcyB1c2VkIHRvIG1ha2UgdGhlIHJlcXVlc3QgKHR5cGljYWxseSAiaHR0cCIgb3IgImh0dHBzIikuCiAgICBwdWIgZm4gcHJvdG8oJnNlbGYpIC0+IE9wdGlvbjwmc3RyPiB7CiAgICAgICAgc2VsZi5wcm90by5hc19kZXJlZigpCiAgICB9CgogICAgLy8vIEFkZHMgYW4gaWRlbnRpZmllciB0byB0aGUgImZvciIgY2hhaW4uCiAgICAvLy8KICAgIC8vLyBVc2VmdWwgd2hlbiByZS1mb3J3YXJkaW5nIGEgcmVxdWVzdCBhbmQgbmVlZGluZyB0byB1cGRhdGUgdGhlIHJlcXVlc3QgaGVhZGVycyB3aXRoIHByZXZpb3VzCiAgICAvLy8gcHJveHkncyBhZGRyZXNzLgogICAgcHViIGZuIHB1c2hfZm9yKCZtdXQgc2VsZiwgaWRlbnRpZmllcjogaW1wbCBJbnRvPFN0cmluZz4pIHsKICAgICAgICBzZWxmLnIjZm9yLnB1c2goaWRlbnRpZmllci5pbnRvKCkpCiAgICB9CgogICAgLy8vIFJldHVybnMgdHJ1ZSBpZiBhbGwgb2YgdGhlIGZpZWxkcyBhcmUgZW1wdHkuCiAgICBmbiBoYXNfbm9faW5mbygmc2VsZikgLT4gYm9vbCB7CiAgICAgICAgc2VsZi5ieS5pc19ub25lKCkgJiYgc2VsZi5yI2Zvci5pc19lbXB0eSgpICYmIHNlbGYuaG9zdC5pc19ub25lKCkgJiYgc2VsZi5wcm90by5pc19ub25lKCkKICAgIH0KCiAgICAvLyBUT0RPOiBwYXJzZSB3aXRoIHRydXN0ZWQgSVAgcmFuZ2VzIGZuCn0KCmltcGwgc3RyOjpGcm9tU3RyIGZvciBGb3J3YXJkZWQgewogICAgdHlwZSBFcnIgPSBJbmZhbGxpYmxlOwoKICAgICNbaW5saW5lXQogICAgZm4gZnJvbV9zdHIodmFsOiAmc3RyKSAtPiBSZSAgICAgICAgICAgICAgICAgICAgIC8vIElnbm9yZSBQZW5kaW5nIGJlY2F1c2UgaXRzIHBvc3NpYmxlIHRoZSBpbm5lciBleHRyYWN0b3IgbmV2ZXIKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBwb2xscyB0aGUgcGF5bG9hZCBzdHJlYW0gYW5kIGlnbm9yZSBlcnJvcnMgYmVjYXVzZSB0aGV5IHdpbGwgYmUKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBwcm9wYWdhdGVkIGJ5IG9yaWdpbmFsIHBheWxvYWQgcG9sbHMuCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUG9sbDo6UmVhZHkoU29tZShFcnIoXykpKSB8IFBvbGw6OlBlbmRpbmcgPT4gYnJlYWssCiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgICAgIFBvbGw6OlBlbmRpbmcKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIEJvZHlIYXNoRnV0UHJvajo6SW5uZXJEb25lIHsKICAgICAgICAgICAgICAgIGlubmVyLAogICAgICAgICAgICAgICAgaGFzaGVyLAogICAgICAgICAgICAgICAgZm9ya2VkX3BheWxvYWQsCiAgICAgICAgICAgIH0gPT4gewogICAgICAgICAgICAgICAgbGV0IG11dCBwbCA9IFBpbjo6bmV3KGZvcmtlZF9wYXlsb2FkKTsKCiAgICAgICAgICAgICAgICAvLyBkcmFpbiBmb3JrZWQgcGF5bG9hZAogICAgICAgICAgICAgICAgbG9vcCB7CiAgICAgICAgICAgICAgICAgICAgbWF0Y2ggcGwuYXNfbXV0KCkucG9sbF9uZXh0KGN4KSB7CiAgICAgICAgICAgICAgICAgICAgICAgIC8vIHVwZGF0ZSBoYXNoZXIgd2l0aCBjaHVua3MKICAgICAgICAgICAgICAgICAgICAgICAgUG9sbDo6UmVhZHkoU29tZShPayhjaHVuaykpKSA9PiBoYXNoZXIudXBkYXRlKCZjaHVuayksCgogICAgICAgICAgICAgICAgICAgICAgICAvLyB3aGVuIGRyYWluIGlzIGNvbXBsZXRlLCBmaW5hbGl6ZSBoYXNoIGFuZCByZXR1cm4gcGFydHMKICAgICBrZXlzOiBWZWM8UHJpdmF0ZUtleT4gPSBwa2NzOF9wcml2YXRlX2tleXMoa2V5X2ZpbGUpCiAgICAgICAgLnVud3JhcCgpCiAgICAgICAgLmludG9faXRlcigpCiAgICAgICAgLm1hcChQcml2YXRlS2V5KQogICAgICAgIC5jb2xsZWN0KCk7CgogICAgLy8gZXhpdCBpZiBubyBrZXlzIGNvdWxkIGJlIHBhcnNlZAogICAgaWYga2V5cy5pc19lbXB0eSgpIHsKICAgICAgICBlcHJpbnRsbiEoIkNvdWxkIG5vdCBsb2NhdGUgUEtDUyA4IHByaXZhdGUga2V5cy4iKTsKICAgICAgICBzdGQ6OnByb2Nlc3M6OmV4aXQoMSk7CiAgICB9CgogICAgY29uZmlnLndpdGhfc2luZ2xlX2NlcnQoY2VydF9jaGFpbiwga2V5cy5yZW1vdmUoMCkpLnVud3JhcCgpCn0KdXNlIHN0ZDo6e2lvLCB0aW1lOjpEdXJhdGlvbn07Cgp1c2UgYWN0aXhfd2ViOjp7CiAgICBnZXQsCiAgICBodHRwOjp7CiAgICAgICAgc2VsZiwKICAgICAgICBoZWFkZXI6OntDb250ZW50RW5jb2RpbmcsIENvbnRlbnRUeXBlfSwKICAgIH0sCiAgICBBcHAsIEh0dHBSZXNwb25zZSwgSHR0cFNlcnZlciwgUmVzcG9uZGVyLAp9Owp1c2UgYWN0aXhfd2ViX2xhYjo6Ym9keTsKdXNlIGFzeW5jX3ppcDo6e3dyaXRlOjpaaXBGaWxlV3JpdGVyLCBaaXBFbnRyeUJ1aWxkZXJ9Owp1c2UgdG9raW86OnsKICAgIGZzLAogICAgaW86OntBc3luY1dyaXRlLCBBc3luY1dyaXRlRXh0IGFzIF99LAp9OwoKZm4gemlwX3RvX2lvX2VycihlcnI6IGFzeW5jX3ppcDo6ZXJyb3I6OlppcEVycm9yKSAtPiBpbzo6RXJyb3IgewogICAgaW86OkVycm9yOjpuZXcoaW86OkVycm9yS2luZDo6T3RoZXIsIGVycikKfQoKYXN5bmMgZm4gcmVhZF9kaXI8Vz4oemlwcGVyOiAmbXV0IFppcEZpbGVXcml0ZXI8Vz4pIC0+IGlvOjpSZXN1bHQ8KCk+CndoZXJlCiAgICBXOiBBc3luY1dyaXRlICsgVW5waW4sCnsKICAgIGxldCBtdXQgcGF0aCA9IGZzOjpjYW5vbmljYWxpemUoZW52ISgiQ0FSR09fTUFOSUZFU1RfRElSIikpLmF3YWl0PzsKICAgIHBhdGgucHVzaCgiZXhhbXBsZXMiKTsKICAgc3luYzo6T25jZUNlbGw7CnVzZSB0cmFjaW5nOjpkZWJ1ZzsKCi8vLyBBIGxhenkgZXh0cmFjdG9yIGZvciB0aHJlYWQtbG9jYWwgZGF0YS4KLy8vCi8vLyBVc2luZyBgTGF6eURhdGFgIGFzIGFuIGV4dHJhY3RvciB3aWxsIG5vdCBpbml0aWFsaXplIHRoZSBkYXRhOyBbYGdldGBdKFNlbGY6OmdldCkgbXVzdCBiZSB1c2VkLgpwdWIgc3RydWN0IExhenlEYXRhPFQ+IHsKICAgIGlubmVyOiBSYzxMYXp5RGF0YUlubmVyPFQ+PiwKfQoKc3RydWN0IExhenlEYXRhSW5uZXI8VD4gewogICAgY2VsbDogT25jZUNlbGw8VD4sCiAgICBmdXQ6IENlbGw8T3B0aW9uPExvY2FsQm94RnV0dXJlPCdzdGF0aWMsIFQ+Pj4sCn0KCmltcGw8VD4gQ2xvbmUgZm9yIExhenlEYXRhPFQ+IHsKICAgIGZuIGNsb25lKCZzZWxmKSAtPiBTZWxmIHsKICAgICAgICBTZWxmIHsKICAgICAgICAgICAgaW5uZXI6IHNlbGYuaW5uZXIuY2xvbmUoKSwKICAgICAgICB9CiAgICB9Cn0KCmltcGw8VDogZm10OjpEZWJ1Zz4gZm10OjpEZWJ1ZyBmb3IgTGF6eURhdGE8VD4gewogICAgZm4gZm10KCZzZWxmLCBmOiAmbXV0IGZtdDo6Rm9ybWF0dGVyPCdfPikgLT4gZm10OjpSZXN1bHQgewogICAgICAgIGYuZGVidWdfc3RydWN0KCJMYXp5IikKICAgICAgICAgICAgLmZpZWxkKCJjZWxsIiwgJnNlbGYuaW5uZXIuY2VsbCkKICAgICAgICAgICAgLmZpZWxkKCJmdXQiLCAmIi4uIikKICAgICAgICAgICAgLmZpbmlzaCgpCiAgICB9Cn0KCmltcGw8VD4gTGF6eURhdGE8VD4gewogICAgLy8vIENvbnN0cnVjdHMgYSBuZXcgYExhenlEYXRhYCBleHRyYWN0b3Igd2l0aCB0aGUgZ2l2ZW4gaW5pdGlhbGl6YXRpb24gZnVuY3Rpb24uCiAgICAvLy8KICAgIC8vLyBJbml0aWFsaXphdGlvbiBmdW5jdGlvbnMgbXVzdCByZXR1cm4gYSBmdXR1cmUgdGhhdCByZXNvbHZlcyB0byBgVGAuCiAgICBwdWIgZm4gbmV3PEYsIEZ1dD4oaW5pdDogRikgLT4gTGF6eURhdGE8VD4KICAgIHdoZXJlCiAgICAgICAgRjogRm5PbmNlKCkgLT4gRnV0LAogICAgICAgIEZ1dCAgICBhc3NlcnQhKHMuaXNfZXJyKCkpOwoKICAgICAgICBsZXQgZXJyX3N0ciA9IHMudW53cmFwX2VycigpLnRvX3N0cmluZygpOwogICAgICAgIGFzc2VydF9lcSEoCiAgICAgICAgICAgIGVycl9zdHIsCiAgICAgICAgICAgICJVUkwgZW5jb2RlZCBwYXlsb2FkIGlzIGxhcmdlciAoOSBieXRlcykgdGhhbiBhbGxvd2VkIChsaW1pdDogOCBieXRlcykuIiwKICAgICAgICApOwogICAgfQp9Ci8vISBQYW5pYyByZXBvcnRlciBtaWRkbGV3YXJlLgovLyEKLy8hIFNlZSBbYFBhbmljUmVwb3J0ZXJgXSBmb3IgZG9jcy4KCnVzZSBzdGQ6OnsKICAgIGFueTo6QW55LAogICAgZnV0dXJlOjp7cmVhZHksIFJlYWR5fSwKICAgIHBhbmljOjp7c2VsZiwgQXNzZXJ0VW53aW5kU2FmZX0sCiAgICByYzo6UmMsCn07Cgp1c2UgYWN0aXhfd2ViOjpkZXY6Ontmb3J3YXJkX3JlYWR5LCBTZXJ2aWNlLCBUcmFuc2Zvcm19Owp1c2UgZnV0dXJlc19jb3JlOjpmdXR1cmU6OkxvY2FsQm94RnV0dXJlOwp1c2UgZnV0dXJlc191dGlsOjpGdXR1cmVFeHQgYXMgXzsKCnR5cGUgUGFuaWNDYWxsYmFjayA9IFJjPGR5biBGbigmKGR5biBBbnkgKyBTZW5kKSk+OwoKLy8vIEEgbWlkZGxld2FyZSB0aGF0IHRyaWdnZXJzIGEgY2FsbGJhY2sgd2hlbiB0aGUgd29ya2VyIGlzIHBhbmlja2luZy4KLy8vCi8vLyBNb3N0bHkgdXNlZnVsIGZvciBsb2dnaW5nIG9yIG1ldHJpY3MgcHVibGlzaGluZy4gVGhlIGNhbGxiYWNrIHJlY2VpdmVkIHRoZSBvYmplY3Qgd2l0aCB3aGljaAovLy8gcGFuaWMgd2FzIG9yaWdpbmFsbHkgaW52b2tlZCB0byBhbGxvdyBkb3duLWNhc3RpbmcuCi8vLwovLy8gIyBFeGFtcGxlcwovLy8gYGBgaWdub3JlCi8vLyAjIHVzZSBhY3RpeF93ZWI6OkFwcDsKLy8vIHVzZSBhY3RpeF93ZWJfbGFiOjptaWRkbGV3YXJlOjpQYW5pY1JlcG9ydGVyOwovLy8gdXNlIG1ldHJpY3M6OmluY3JlbWVudF9jb3VudGVyOwovLy8KLy8vIEFwcDo6bmV3KCkKLy8vICAgICAud3JhcChQYW5pY1JlcG9ydGVyOjpuZXcofF98IGluY3JlbWU6OkJ5dGVzfTsKICAgIHVzZSBzZXJkZTo6e0Rlc2VyaWFsaXplLCBTZXJpYWxpemV9OwoKICAgIHVzZSBzdXBlcjo6KjsKCiAgICAjW2Rlcml2ZShTZXJpYWxpemUsIERlc2VyaWFsaXplLCBQYXJ0aWFsRXEsIERlYnVnKV0KICAgIHN0cnVjdCBNeU9iamVjdCB7CiAgICAgICAgbmFtZTogU3RyaW5nLAogICAgfQoKICAgIGZuIGVycl9lcShlcnI6IFVybGVuY29kZWRFcnJvciwgb3RoZXI6IFVybGVuY29kZWRFcnJvcikgLT4gYm9vbCB7CiAgICAgICAgbWF0Y2ggZXJyIHsKICAgICAgICAgICAgVXJsZW5jb2RlZEVycm9yOjpPdmVyZmxvdyB7IC4uIH0gPT4gewogICAgICAgICAgICAgICAgbWF0Y2hlcyEob3RoZXIsIFVybGVuY29kZWRFcnJvcjo6T3ZlcmZsb3cgeyAuLiB9KQogICAgICAgICAgICB9CgogICAgICAgICAgICBVcmxlbmNvZGVkRXJyb3I6OkNvbnRlbnRUeXBlID0+IG1hdGNoZXMhKG90aGVyLCBVcmxlbmNvZGVkRXJyb3I6OkNvbnRlbnRUeXBlKSwKCiAgICAgICAgICAgIF8gPT4gZmFsc2UsCiAgICAgICAgfQogICAgfQoKICAgICNbYWN0aXhfd2ViOjp0ZXN0XQogICAgYXN5bmMgZm4gdGVzdF9leHRyYWN0KCkgewogICAgICAgIGxldCAocmVxLCBtdXQgcGwpID0gVGVzdFJlcXVlc3Q6OmRlZmF1bHQoKQogICAgICAgICAgICAuaW5zZXJ0X2hlYWRlcihoZWFkZXI6OkNvbnRlbnRUeXBlOjpmb3JtX3VybF9lbmNvZGVkKCkpCiAgICAgICAgICAgIC5pbnNlcnRfaGVhZGVyKCgKICAgICAgICAgICAgICAgIGhlYWRlcjo6Q09OVEVOVF9MRU5HVEgsCiAgICAgICAgICAgICAgICBoZWFkZXI6OkhlYWRlclZhbHVlOjpmcm9tX3N0YXRpYygiOSIpLAogICAgICAgICAgICApKQogICAgICAgICAgICAuc2V0X3BheWxvYWQoQnl0ZXM6OmZyb21fc3RhdGljKGIibmFtZT10ZXN0IikpCiAgICAgICAgICAgIC50b19odHRwX3BhcnRzKCk7CgogICAgICAgIGxldCBzID0KICAgICAgICAgICAgVXJsRW5jb2RlZEZvcm06OjxNeU9iamVjdCwgREVGQVVMVF9VUkxfRU5DT0RFRF9GT1JNX0xJTUlUPjo6ZnJvICAgICAgIGxldCBtd19mbiA9IFJjOjpjbG9uZSgmc2VsZi5td19mbik7CiAgICAgICAgICAgICAgICBsZXQgc2VydmljZSA9IFJjOjpjbG9uZSgmc2VsZi5zZXJ2aWNlKTsKCiAgICAgICAgICAgICAgICBCb3g6OnBpbihhc3luYyBtb3ZlIHsKICAgICAgICAgICAgICAgICAgICBsZXQgKCQoJGV4dF90eXBlLCkqKSA9IHJlcS5leHRyYWN0Ojo8KCQoJGV4dF90eXBlLCkqKT4oKS5hd2FpdD87CgogICAgICAgICAgICAgICAgICAgIChtd19mbikoJCgkZXh0X3R5cGUpLCosIHJlcSwgTmV4dDo6PEI+IHsgc2VydmljZSB9KS5hd2FpdAogICAgICAgICAgICAgICAgfSkKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH07Cn0KCmltcGxfbWlkZGxld2FyZV9mbl9zZXJ2aWNlIShFMSk7CmltcGxfbWlkZGxld2FyZV9mbl9zZXJ2aWNlIShFMSwgRTIpOwppbXBsX21pZGRsZXdhcmVfZm5fc2VydmljZSEoRTEsIEUyLCBFMyk7CmltcGxfbWlkZGxld2FyZV9mbl9zZXJ2aWNlIShFMSwgRTIsIEUzLCBFNCk7CmltcGxfbWlkZGxld2FyZV9mbl9zZXJ2aWNlIShFMSwgRTIsIEUzLCBFNCwgRTUpOwppbXBsX21pZGRsZXdhcmVfZm5fc2VydmljZSEoRTEsIEUyLCBFMywgRTQsIEU1LCBFNik7CmltcGxfbWlkZGxld2FyZV9mbl9zZXJ2aWNlIShFMSwgRTIsIEUzLCBFNCwgRTUsIEU2LCBFNyk7CmltcGxfbWlkZGxld2FyZV9mbl9zZXJ2aWNlIShFMSwgRTIsIEUzLCBFNCwgRTUsIEU2LCBFNywgRTgpOwppbXBsX21pZGRsZXdhcmVfZm5fc2VydmljZSEoRTEsIEUyLCBFMywgRTQsIEU1LCBFNiwgRTcsIEU4LCBFOSk7CgovLy8gV3JhcHMgdGhlICJuZXh0IiBzZXJ2aWNlIGluIHRoZSBtaWRkbGV3YXJlIGNoYWluLgpwdWIgc3RydWN0IE5leHQ8Qj4gewogICAgc2VydmljZTogUmNTZXJ2aWNlPFNlcnZpY2VSZXF1ZXN0LCBTZXJ2aWNlUmVzcG9uc2U8Qj4sIEVycm9yPiwKfQoKaW1wbDxCPiBOZXh0PEI+IHsKICAgIC8vLyBFcXVpdmFsZW50IHRvIGBTZXJ2aWNlOjpjYWxsKHNlbGYsIHJlcSlgLgogICAgcHViIGZuIGNhbC8gVGhpcyB3b3JrcyB3aGVuIFNpemVkIGlzIHJlcXVpcmVkCiAgICAgICAgbGV0IGR5bl9yY19ib3g6IFJjPEJveDxkeW4gVGVzdFRyYWl0Pj4gPSBSYzo6bmV3KEJveDo6bmV3KEEge30pKTsKICAgICAgICBsZXQgZGF0YV9hcmNfYm94ID0gTG9jYWxEYXRhOjpmcm9tKGR5bl9yY19ib3gpOwoKICAgICAgICAvLyBUaGlzIHdvcmtzIHdoZW4gRGF0YSBTaXplZCBCb3VuZCBpcyByZW1vdmVkCiAgICAgICAgbGV0IGR5bl9yYzogUmM8ZHluIFRlc3RUcmFpdD4gPSBSYzo6bmV3KEEge30pOwogICAgICAgIGxldCBkYXRhX2FyYyA9IExvY2FsRGF0YTo6ZnJvbShkeW5fcmMpOwogICAgICAgIGFzc2VydF9lcSEoZGF0YV9hcmNfYm94LmdldF9udW0oKSwgZGF0YV9hcmMuZ2V0X251bSgpKQogICAgfQoKICAgICNbYWN0aXhfd2ViOjp0ZXN0XQogICAgYXN5bmMgZm4gdGVzdF9nZXRfcmVmX2Zyb21fZHluX2RhdGEoKSB7CiAgICAgICAgbGV0IGR5bl9yYzogUmM8ZHluIFRlc3RUcmFpdD4gPSBSYzo6bmV3KEEge30pOwogICAgICAgIGxldCBkYXRhX2FyYyA9IExvY2FsRGF0YTo6ZnJvbShkeW5fcmMpOwogICAgICAgIGxldCByZWZfZGF0YTogJmR5biBUZXN0VHJhaXQgPSAmKmRhdGFfYXJjOwogICAgICAgIGFzc2VydF9lcSEoZGF0YV9hcmMuZ2V0X251bSgpLCByZWZfZGF0YS5nZXRfbnVtKCkpCiAgICB9Cn0KdXNlIHN0ZDo6aW87Cgp1c2UgYWN0aXhfd2ViOjp7Z2V0LCBBcHAsIEh0dHBTZXJ2ZXIsIFJlc3BvbmRlcn07CnVzZSBhY3RpeF93ZWJfbGFiOjpyZXNwb25kOjpDYm9yOwp1c2Ugc2VyZGU6OlNlcmlhbGl6ZTsKdXNlIHRyYWNpbmc6OmluZm87CgojW2Rlcml2ZShEZWJ1ZywgU2VyaWFsaXplKV0Kc3RydWN0IFRlc3QgewogICAgb25lOiB1MzIsCiAgICB0d286IFN0cmluZywKfQoKI1tnZXQoIi8iKV0KYXN5bmMgZm4gaW5kZXgoKSAtPiBpbXBsIFJlc3BvbmRlciB7CiAgICBDYm9yKFRlc3QgewogICAgICAgIG9uZTogNDIsCiAgICAgICAgdHdvOiAidHdvIi50b19vd25lZCgpLAogICAgfSkKfQoKI1sgICAgICAgIFs0NTYsIDc4OV0sCiAgICAgICAgXSkpCiAgICAgICAgLmludG9fYm9keV9zdHJlYW0oKTsKCiAgICAgICAgbGV0IGJvZHlfYnl0ZXMgPSBib2R5Ojp0b19ieXRlcyhuZGpzb25fYm9keSkKICAgICAgICAgICAgLmF3YWl0CiAgICAgICAgICAgIC5tYXBfZXJyKEludG86OjxCb3g8ZHluIFN0ZEVycm9yPj46OmludG8pCiAgICAgICAgICAgIC51bndyYXAoKTsKCiAgICAgICAgY29uc3QgRVhQX0JZVEVTOiAmc3RyID0gIjEyMyw0NTZcblwKICAgICAgICA3ODksMTJcblwKICAgICAgICAzNDUsNjc4XG5cCiAgICAgICAgOTAxLDIzNFxuXAogICAgICAgIDQ1Niw3ODlcbiI7CgogICAgICAgIGFzc2VydF9lcSEoYm9keV9ieXRlcywgRVhQX0JZVEVTKTsKICAgIH0KfQp1c2Ugc3RkOjp7YW55Ojp0eXBlX25hbWUsIG9wczo6RGVyZWYsIHJjOjpSY307Cgp1c2UgYWN0aXhfdXRpbHM6OmZ1dHVyZTo6e2Vyciwgb2ssIFJlYWR5fTsKdXNlIGFjdGl4X3dlYjo6e2Rldjo6UGF5bG9hZCwgZXJyb3IsIEVycm9yLCBGcm9tUmVxdWVzdCwgSHR0cFJlcXVlc3R9Owp1c2UgdHJhY2luZzo6ZGVidWc7CgovLy8gQSB0aHJlYWQtbG9jYWwgZXF1aXZhbGVudCB0byBbYFNoYXJlZERhdGFgXShjcmF0ZTo6ZXh0cmFjdDo6U2hhcmVkRGF0YSkuCiNbZG9jKGFsaWFzID0gInN0YXRlIildCiNbZGVyaXZlKERlYnVnKV0KcHViIHN0cnVjdCBMb2NhbERhdGE8VDogP1NpemVkPihSYzxUPik7CgppbXBsPFQ+IExvY2FsRGF0YTxUPiB7CiAgICAvLy8gQ29uc3RydWN0cyBhIG5ldyBgTG9jYWxEYXRhYCBpbnN0YW5jZS4KICAgIHB1YiBmbiBuZXcoaXRlbTogVCkgLT4gTG9jYWxEYXRhPFQ+IHsKICAgICAgICBMb2NhbERhdGEoUmM6Om5ldyhpdGVtKSkKICAgIH0KfQoKaW1wbDxUOiA/U2l6ZWQ+IERlcmVmIGZvciBMb2NhbERhdGE8VD4gewogICAgdHlwZSBUYXJnZXQgPSBUOwoKICAgIGZuIGRlcmVmKCZzZWxmKSAtPiAmVCB7CiAgICAgICAgJnNlbGYuMAogICAgfQp9CgppbXBsPFQ6ID9TaXplZD4gQ2xvbmUgZm9yIExvLXJlc3VsdHMiLCBuX2l0ZW1zKSkKCiAgICAvLyBhbHRlcm5hdGl2ZSBpZiB5b3UgbmVlZCBtb3JlIGNvbnRyb2wgb2YgdGhlIEh0dHBSZXNwb25zZToKICAgIC8vCiAgICAvLyBIdHRwUmVzcG9uc2U6Ok9rKCkKICAgIC8vICAgICAuaW5zZXJ0X2hlYWRlcigoImNvbnRlbnQtdHlwZSIsIE5kSnNvbjo6bWltZSgpKSkKICAgIC8vICAgICAuaW5zZXJ0X2hlYWRlcigoIm51bS1yZXN1bHRzIiwgbl9pdGVtcykpCiAgICAvLyAgICAgLmJvZHkoTmRKc29uOjpuZXcoZGF0YV9zdHJlYW0pLmludG9fYm9keV9zdHJlYW0oKSkKfQoKLy8vIEEgY29tcGFyaXNvbiByb3V0ZSB0aGF0IGxvYWRzIGFsbCB0aGUgZGF0YSBpbnRvIG1lbW9yeSBiZWZvcmUgc2VuZGluZyBpdCB0byB0aGUgY2xpZW50LgovLy8KLy8vIElmIHlvdSBwcm92aWRlIGEgaGlnaCBudW1iZXIgaW4gdGhlIHF1ZXJ5IHN0cmluZyBsaWtlIGA/bj0zMDAwMDBgIHlvdSBzaG91bGQgYmUgYWJsZSB0byBvYnNlcnZlCi8vLyBpbmNyZWFzaW5nIG1lbW9yeSB1c2FnZSBvZiB0aGUgcHJvY2VzcyBpbiB5b3VyIHByb2Nlc3MgbW9uaXRvci4KI1tnZXQoIi91c2Vycy1oaWdoLW1lbSIpXQphc3luYyBmbiBnZXRfaGlnaF9tZW1fdXNlcl9saXN0KG9wdHM6IHdlYjo6UXVlcnk8T3B0cz4pIC0+IGltcGwgUmVzcG9uZGVyIHsKICAgIGxldCBuX2l0ZW1zID0gb3B0cy5uLnVud3JhcF9vcigxMCk7CiAgICBsZXQgbXV0IHN0cmVhbSA9IHN0cmVhbWluZ19kYXRhX3NvdXJjZShuX2l0ZW1zKTsKCiAgICAvLyBidWZmZXIgYWxsIGRhdGEgZnJvbSB0aGUgc291cmNlIGludG8gYSBCeXRlcyBjb250YWluZXIKICAgIGxldCBtdXQgYnVmID0gQnl0ZXNNdXQ6Om5ldygpLndyaXRlcigpOwogICAgd2hpbGUgbGV0IFNvbWUoT2soaXRlbSkpID0gc3RyZWFtLm5leHQoKS5hd2FpdCB7CiAgICAgICAgc2VyZGVfanNvbjo6dG9fd3JpdGVyKCZtdXQgYnVmLCAmaXRlbSkudW53cmFwKCk7CiAgICAgICAgYnVmLndyaXRlX2FsbChiIlxuIikudW53cmFwKCk7CiAgICB9CgogICAgSHJuIHNlbGYudHguc2VuZChFcnIoZXJyKSkubWFwX2Vycih8U2VuZEVycm9yKGVycil8IG1hdGNoIGVyciB7CiAgICAgICAgICAgICAgICBPayhfKSA9PiB1bnJlYWNoYWJsZSEoKSwKICAgICAgICAgICAgICAgIEVycihlcnIpID0+IGVyciwKICAgICAgICAgICAgfSk7CiAgICAgICAgfQoKICAgICAgICBPaygoKSkKICAgIH0KfQoKI1tkZXJpdmUoRGVidWcpXQpzdHJ1Y3QgUmVjZWl2ZXI8RT4gewogICAgcng6IFVuYm91bmRlZFJlY2VpdmVyPFJlc3VsdDxCeXRlcywgRT4+LAp9CgppbXBsPEU+IFJlY2VpdmVyPEU+IHsKICAgIGZuIG5ldyhyeDogVW5ib3VuZGVkUmVjZWl2ZXI8UmVzdWx0PEJ5dGVzLCBFPj4pIC0+IFNlbGYgewogICAgICAgIFNlbGYgeyByeCB9CiAgICB9Cn0KCmltcGw8RT4gTWVzc2FnZUJvZHkgZm9yIFJlY2VpdmVyPEU+CndoZXJlCiAgICBFOiBJbnRvPEJveEVycm9yPiwKewogICAgdHlwZSBFcnJvciA9IEU7CgogICAgZm4gc2l6ZSgmc2VsZikgLT4gQm9keVNpemUgewogICAgICAgIEJvZHlTaXplOjpTdHJlYW0KICAgIH0KCiAgICBmbiBwb2xsX25leHQoCiAgICAgICAgbXV0IHNlbGY6IFBpbjwmbXV0IFNlbGY+LAogICAgICAgIGN4OiAmbXV0IENvbnRleHQ8J18+LAogICAgKSAtPiBQb2xsPE9wdGlvbjxSZXN1bHQ8Qnl0ZXMsIFNlbGY6OkVycm9yPj4+IHsKICAgICAgICBzZWxmLnJ4LnBvbGxfcmVjdihjeCkKICAgIH0KfQoKI1tjZmcodGVzdCldCm1vZCB0ZXN0cyB7CiAgICB1c2Ugc3RkOjppbzsKCiAgICB1c2Ugc3VwZXI6Oio7CgogICAgc3RhdGljX2Fzc2VydGlvbnM6OmFzc2VydF9pbXBsX2FsbCEoU2VuZGVyPGlvOjpFcnJvcj46IFNlbmQsIFN5bmMsIFVucGluKTsKICAgIHN0YXRpY19hc3NlcnRpb25zOjphc3NlcnRfaW1wbF9hbGwhKFJlY2VpdmVyPGlvOjpFcnJvcj46IFNlbmQsIFN5bmMsIFVucGluLCBNZXNzYWdlQm9keSk7Cn0KdXNlIGFjdGl4X2hhc2g6OntCb2R5SGFzaCwgQm9keVNoYTI1Nn07CnVzZSBhY3RpeF9odHRwOjpCb3hlZFBheWxvYWRTdHJlYW1yZWdpc3Rlcl9zZXJ2aWNlKAogICAgICAgICAgICByZGVmLAogICAgICAgICAgICBOb25lLAogICAgICAgICAgICBmbl9zZXJ2aWNlKG1vdmUgfHJlcXwgc2VydmVfaW5kZXgocmVxLCBzZWxmLmluZGV4X2ZpbGUuY2xvbmUoKSkpLAogICAgICAgICAgICBOb25lLAogICAgICAgICk7CiAgICB9Cn0KCmFzeW5jIGZuIHNlcnZlX2luZGV4KAogICAgcmVxOiBTZXJ2aWNlUmVxdWVzdCwKICAgIGluZGV4X2ZpbGU6IFN0cmluZywKKSAtPiBSZXN1bHQ8U2VydmljZVJlc3BvbnNlLCBhY3RpeF93ZWI6OkVycm9yPiB7CiAgICB0cmFjZSEoInNlcnZpbmcgZGVmYXVsdCBTUEEgcGFnZSIpOwogICAgbGV0IChyZXEsIF8pID0gcmVxLmludG9fcGFydHMoKTsKICAgIGxldCBmaWxlID0gTmFtZWRGaWxlOjpvcGVuX2FzeW5jKCZpbmRleF9maWxlKS5hd2FpdD87CiAgICBsZXQgcmVzID0gZmlsZS5pbnRvX3Jlc3BvbnNlKCZyZXEpOwogICAgT2soU2VydmljZVJlc3BvbnNlOjpuZXcocmVxLCByZXMpKQp9CgppbXBsIERlZmF1bHQgZm9yIFNwYSB7CiAgICBmbiBkZWZhdWx0KCkgLT4gU2VsZiB7CiAgICAgICAgU2VsZiB7CiAgICAgICAgICAgIGluZGV4X2ZpbGU6IENvdzo6Qm9ycm93ZWQoIi4vaW5kZXguaHRtbCIpLAogICAgICAgICAgICBzdGF0aWNfcmVzb3VyY2VzX21vdW50OiBDb3c6OkJvcnJvd2VkKCIvIiksCiAgICAgICAgICAgIHN0YXRpY19yZXNvdXJjZXNfbG9jYXRpb246IENvdzo6Qm9ycm93ZWQoIi4vIiksCiAgICAgICAgfQogICAgfQp9Ci8vIENvZGUgbW9zdGx5IGNvcGllZCBmcm9tIGB0b3dlcmA6Ci8vIGh0dHBzOi8vZ2l0aHViLmNvbS90b3dlci1ycy90b3dlci90cmVlLzUwNjQ5ODdmL3Rvd2VyL3NyYy9sb2FkX3NoZWQKCi8vISBMb2FkLXNoZWRkaW5nIG1pZGRsZXdhcmUuCgp1c2Ugc3RkOjp7CiAgICBjZWxsOjpDZWxsLAogICAgZXJyb3I6OkVycm9yIGFzIFN0ZEVycm9yLAogICAgZm10LAogICAgZnV0dXJlOjpGdXR1cmUsCiAgICBwaW46OlBpbiwKICAgIHRhc2s6OntyZWFkeSwgQ29udGV4cmRlKHJlbmFtZSA9ICJ1c2VyIildCi8vLyAgICB1c2VyczogVmVjPFN0cmluZz4sCi8vLyB9Ci8vLwovLy8gLy8gRGVzZXJpYWxpemUgYExvZ3NQYXJhbXNgIHN0cnVjdCBmcm9tIHF1ZXJ5IHN0cmluZy4KLy8vIC8vIFRoaXMgaGFuZGxlciBnZXRzIGNhbGxlZCBvbmx5IGlmIHRoZSByZXF1ZXN0J3MgcXVlcnkgcGFyYW1ldGVycyBjb250YWluIGJvdGggZmllbGRzLgovLy8gLy8gQSB2YWxpZCByZXF1ZXN0IHBhdGggZm9yIHRoaXMgaGFuZGxlciB3b3VsZCBiZSBgL2xvZ3M/dHlwZT1yZXBvcnRzJnVzZXI9Zm9vJnVzZXI9YmFyImAuCi8vLyAjW2dldCgiL2xvZ3MiKV0KLy8vIGFzeW5jIGZuIGluZGV4KGluZm86IFF1ZXJ5PExvZ3NQYXJhbXM+KSAtPiBpbXBsIFJlc3BvbmRlciB7Ci8vLyAgICAgbGV0IExvZ3NQYXJhbXMgeyBsb2dfdHlwZSwgdXNlcnMgfSA9IGluZm8uaW50b19pbm5lcigpOwovLy8gICAgIGZvcm1hdCEoIkxvZ3MgcmVxdWVzdCBmb3IgdHlwZT17bG9nX3R5cGV9IGFuZCB1c2VyIGxpc3Q9e3VzZXJzOj99ISIpCi8vLyB9Ci8vLwovLy8gLy8gT3IgdXNlIGRlc3RydWN0dXJpbmcsIHdoaWNoIGlzIGVxdWl2YWxlbnQgdG8gYC5pbnRvX2lubmVyKClgLgovLy8gI1tnZXQoIi9kZWJ1ZzIiKV0KLy8vIGFzeW5jIGZuIGRlYnVnMihRdWVyeShpbmZvKTogUXVlcnk8TG9nc1BhcmFtcz4pIC0+IGltcGwgUmVzcG9uZGVyIHsKLy8vICAgICBkYmchKCJBdXRob3JpemF0aW9uIG9iamVjdCA9IHtpbmZvOj99Iik7Ci8vLyAgICAgIk9LIgovLy8gfQovLy8gYGBgCiNbZGVyaXZlKERlYnVnLCBDbG9uZSwgUGFydGlhbEVxLCBFcSwgUGFydGlhbE9yZCwgT3JkKV0KcHViIHN0cnVjdCBRdWVyeTxUPihwdWIgVCk7CgppbXBsX21vcmU6OmltcGxfZGVyZWZfYW5kX211dCEoPFQ+IGluIFF1ZXJ5PFQ+ID0+IFQpOwppbXBsX21vcmU6OmZvcndhcmRfZGlzcGxheSEoPFQ+IGluIFF1ZXJ5PFQ+KTsKCmltcGw8VD4gUXVlcnk8VD4gewogICAgLy8vIFVud3JhcCBpbnRvIGlubmVyIGBUYCB2YWx1ZS4KICAgIHJlZGlyZWN0cywKICAgICAgICB9KSkKICAgIH0KfQoKcHViIHN0cnVjdCBOb3JtYWxpemVQYXRoU2VydmljZTxTPiB7CiAgICBzZXJ2aWNlOiBTLAogICAgbWVyZ2Vfc2xhc2g6IFJlZ2V4LAogICAgdHJhaWxpbmdfc2xhc2hfYmVoYXZpb3I6IFRyYWlsaW5nU2xhc2gsCiAgICB1c2VfcmVkaXJlY3RzOiBPcHRpb248U3RhdHVzQ29kZT4sCn0KCmltcGw8UywgQj4gU2VydmljZTxTZXJ2aWNlUmVxdWVzdD4gZm9yIE5vcm1hbGl6ZVBhdGhTZXJ2aWNlPFM+CndoZXJlCiAgICBTOiBTZXJ2aWNlPFNlcnZpY2VSZXF1ZXN0LCBSZXNwb25zZSA9IFNlcnZpY2VSZXNwb25zZTxCPiwgRXJyb3IgPSBFcnJvcj4sCiAgICBTOjpGdXR1cmU6ICdzdGF0aWMsCnsKICAgIHR5cGUgUmVzcG9uc2UgPSBTZXJ2aWNlUmVzcG9uc2U8RWl0aGVyQm9keTxCLCAoKT4+OwogICAgdHlwZSBFcnJvciA9IEVycm9yOwogICAgdHlwZSBGdXR1cmUgPSBOb3JtYWxpemVQYXRoRnV0dXJlPFMsIEI+OwoKICAgIGFjdGl4X3NlcnZpY2U6OmZvcndhcmRfcmVhZHkhKHNlcnZpY2UpOwoKICAgIGZuIGNhbGwoJnNlbGYsIG11dCByZXE6IFNlcnZpY2VSZXF1ZXN0KSAtPiBTZWxmOjpGdXR1cmUgewogICAgICAgIGxldCBoZWFkID0gcmVxLmhlYWRfbXV0KCk7CgogICAgICAgIGxldCBtdXQgcGF0aF9hbHRlcmVkID0gZmFsc2U7CiAgICAgICAgbGV0IG9yaWdpbmFsX3BhdGggPSBoZWFkLnVyaS5wYXRoKCk7CgogICAgICAgIC8vIEFuIGVtcHR5IHBhdGggaGVyZSBtZWFucyB0aGF0IHRoZSBVUkkgaGFzIG5vIHZhbGlkIHBhdGguIFdlIHNraXAgbm9ybWFsaXphdGlvbiBpbiB0aGlzCiAgICAgICAgLy8gY2FzZSwgYmVjYXVzZSBhZGRpbmcgYSBwYXRoIGNhbiBtYWtlIHRoZSBVUkkgaW52YWxpZAogICAgICAgIGlmICFvcmlnaW5hbF9wYXRoLmlzX2VtcHR5KCkgewogICAgICAgICAgICAvLyBFaXRoZXIgYWRkcyBhIHN0cmluZyB0byB0aGUgZW5kIChkdXBsaWNhdGVzIHdpbGwgYmUgcmVtb3ZlZCBhbnl3YXlzKSBvciB0cmltcyBhbGwKICAgICBseS4KLy8vCi8vLyAjIE5vcm1hbGl6YXRpb24gU3RlcHMKLy8vIC0gTWVyZ2VzIGNvbnNlY3V0aXZlIHNsYXNoZXMgaW50byBvbmUuIChGb3IgZXhhbXBsZSwgYC9wYXRoLy9vbmVgIGFsd2F5cyBiZWNvbWVzIGAvcGF0aC9vbmVgLikKLy8vIC0gQXBwZW5kcyBhIHRyYWlsaW5nIHNsYXNoIGlmIG9uZSBpcyBub3QgcHJlc2VudCwgcmVtb3ZlcyBvbmUgaWYgcHJlc2VudCwgb3Iga2VlcHMgdHJhaWxpbmcKLy8vICAgc2xhc2hlcyBhcy1pcywgZGVwZW5kaW5nIG9uIHdoaWNoIFtgVHJhaWxpbmdTbGFzaGBdIHZhcmlhbnQgaXMgc3VwcGxpZWQKLy8vICAgdG8gW2BuZXdgXShOb3JtYWxpemVQYXRoOjpuZXcoKSkuCi8vLwovLy8gIyBEZWZhdWx0IEJlaGF2aW9yCi8vLyBUaGUgZGVmYXVsdCBjb25zdHJ1Y3RvciBjaG9vc2VzIHRvIHN0cmlwIHRyYWlsaW5nIHNsYXNoZXMgZnJvbSB0aGUgZW5kIG9mIHBhdGhzIHdpdGggdGhlbQovLy8gKFtgVHJhaWxpbmdTbGFzaDo6VHJpbWBdKS4gVGhlIGltcGxpY2F0aW9uIGlzIHRoYXQgcm91dGUgZGVmaW5pdGlvbnMgc2hvdWxkIGJlIGRlZmluZWQgd2l0aG91dAovLy8gdHJhaWxpbmcgc2xhc2hlcyBvciBlbHNlIHRoZXkgd2lsbCBiZSBpbmFjY2Vzc2libGUgKG9yIHZpY2UgdmVyc2Egd2hlbiB1c2luZyB0aGUKLy8vIGBUcmFpbGluZ1NsYXNoOjpBbHdheXNgIGJlaGF2aW9yKSwgYXMgc2hvd24gaW4gdGhlIGV4YW1wbGUgdGVzdHMgYmVsb3cuCi8vLwovLy8gIyBFeGFtcGxlcwovLy8gYGBgCi8vLyB1c2UgYWN0aXhfd2ViOjp7d2ViLCBtaWRkbGV3YXJlLCBBcHB9OwovLy8KLy8vICMgYWN0aXhfd2ViOjpydDo6U3lzdGVtOjpuZXcoKS5ibG9ja19vbihhc3luYyB7Ci8vLyBsZXQgYXBwID0gQXBwOjpuZXcoKQovLy8gICAgIC53cmFwKG1pZGRsZXdhcmU6Ok5vcm1hbGl6ZVBhdGg6OnRyaW0oKSkKLy8vICAgICAucm91dGUoIi90ZXN0Iiwgd2ViOjpnZXQoKS50byh8fCBhc3luYyB7ICJ0ZXN0IiB9KSkKLy8vICAgICAucm91dGUoIi91bm1hdGNoYWJsZS8iLCB3ZWI6ID0gbWF0Y2ggc2VsZi4wIHsKICAgICAgICAgICAgdHJ1ZSA9PiByZXEuaW50b19yZXNwb25zZSgic2hvcnQtY2lyY3VpdGVkIikubWFwX2ludG9fcmlnaHRfYm9keSgpLAogICAgICAgICAgICBmYWxzZSA9PiBuZXh0LmNhbGwocmVxKS5hd2FpdD8ubWFwX2ludG9fbGVmdF9ib2R5KCksCiAgICAgICAgfTsKCiAgICAgICAgcmVzLmhlYWRlcnNfbXV0KCkKICAgICAgICAgICAgLmluc2VydChoZWFkZXI6OldBUk5JTkcsIEhlYWRlclZhbHVlOjpmcm9tX3N0YXRpYygiNDIiKSk7CgogICAgICAgIE9rKHJlcykKICAgIH0KCiAgICBwdWIgZm4gaW50b19taWRkbGV3YXJlPFMsIEI+KAogICAgICAgIHNlbGYsCiAgICApIC0+IGltcGwgVHJhbnNmb3JtPAogICAgICAgIFMsCiAgICAgICAgU2VydmljZVJlcXVlc3QsCiAgICAgICAgUmVzcG9uc2UgPSBTZXJ2aWNlUmVzcG9uc2U8aW1wbCBNZXNzYWdlQm9keT4sCiAgICAgICAgRXJyb3IgPSBFcnJvciwKICAgICAgICBJbml0RXJyb3IgPSAoKSwKICAgID4KICAgIHdoZXJlCiAgICAgICAgUzogU2VydmljZTxTZXJ2aWNlUmVxdWVzdCwgUmVzcG9uc2UgPSBTZXJ2aWNlUmVzcG9uc2U8Qj4sIEVycm9yID0gRXJyb3I+ICsgJ3N0YXRpYywKICAgICAgICBCOiBNZXNzYWdlQm9keSArICdzdGF0aWMsCiAgICB7CiAgICAgICAgbGV0IHRoaXMgPSBSYzo6bmV3KHNlbGYpOwogICAgICAgIGZyb21fZm4obW92ZSB8cmVxLCBuZXh0fCB7CiAgICAgICAgICAgIGxldCB0aGlzID0gUmM6OmNsb25lKCZ0aGlzKTsKICAgICAgICAgICAgYXN5bmMgbW92ZSB7IFNlbGY6Om13X2NiKCZ0aGlzLCByZXEsIG5leHQpLmF3YWl0IH0KICAgICAgICB9KQogICAgfQp9CgojW2FjdGl4X3dlYjo6bWFpbl0KYXN5bmMgZm4gbWFpbigpIC0+IGlvOjpSZXN1bHQ8KCk+IHsKICAgIGVudl9sb2dnZXI6OmluaXRfZnJvbV9lbnYoZW52X2xvZ2dlcjo6RW52OjpuZXcoKS5kZWZhdWx0X2ZpbHRlcl9vcigiaW5mbyIpKTsKCiAgICBsZXQgYmluZCA9ICgiMTI3LjAuMC4xIiwgODA4MCk7CiAgICBpbm9uZCBpdGVtIGlzIHRoZSByZXNwb25kZXIgYW5kIGNhbiwgdGhlcmVmb3JlLCBiZSB1c2VkIGFzIGEgaGFuZGxlciByZXR1cm4gdHlwZSBkaXJlY3RseS4KLy8vIFRoZSBzdHJlYW0gd2lsbCBiZSBjbG9zZWQgYWZ0ZXIgYWxsIFtzZW5kZXJzXShTc2VTZW5kZXIpIGFyZSBkcm9wcGVkLgovLy8KLy8vIFJlYWQgbW9yZSBhYm91dCBzZXJ2ZXItc2VudCBldmVudHMgaW4gW3RoaXMgTUROIGFydGljbGVdW21kbi1zc2VdLgovLy8KLy8vIFNlZSBbbW9kdWxlIGRvY3NdKHNlbGYpIGZvciB1c2FnZSBleGFtcGxlLgovLy8KLy8vIFttZG4tc3NlXTogaHR0cHM6Ly9kZXZlbG9wZXIubW96aWxsYS5vcmcvZW4tVVMvZG9jcy9XZWIvQVBJL1NlcnZlci1zZW50X2V2ZW50cy9Vc2luZ19zZXJ2ZXItc2VudF9ldmVudHMKcHViIGZuIGNoYW5uZWwoYnVmZmVyOiB1c2l6ZSkgLT4gKFNlbmRlciwgU3NlPENoYW5uZWxTdHJlYW0+KSB7CiAgICBsZXQgKHR4LCByeCkgPSBtcHNjOjpjaGFubmVsKGJ1ZmZlcik7CgogICAgKAogICAgICAgIFNlbmRlciB7IHR4IH0sCiAgICAgICAgU3NlIHsKICAgICAgICAgICAgc3RyZWFtOiBDaGFubmVsU3RyZWFtKHJ4KSwKICAgICAgICAgICAga2VlcF9hbGl2ZTogTm9uZSwKICAgICAgICAgICAgcmV0cnlfaW50ZXJ2YWw6IE5vbmUsCiAgICAgICAgfSwKICAgICkKfQoKLy8vIFN0cmVhbSBpbXBsZW1lbnRhdGlvbiBmb3IgY2hhbm5lbC1iYXNlZCBTU0UgW2BTZW5kZXJgXS4KI1tkZXJpdmUoRGVidWcpXQpwdWIgc3RydWN0IENoYW5uZWxTdHJlYW0obXBzYzo6UmVjZWl2ZXI8RXZlbnQ+KTsKCmltcGwgU3RyZWFtIGZvciBDaGFubmVsU3RyZWFtIHsKICAgIHR5cGUgSXRlbSA9IFJlc3VsdDxFdmVudCwgSW5mYWxsaWJsZT47CgogICAgZm4gcG9sbF9uZXh0KG11dCBzZWxmOiBQaW48Jm11dCBTZWxmPiwgY3g6ICZtdXQgQ29udGV4dDwnXz4pIC0+IFBvbGw8T3B0aW9uPFNlbGY6Okl0ZW0+PiB7CiAgICAgICAgc2VsZi4wLnBvbGxfcmVjdihjeCkubWFwKHxldnwgZXYubWFwKE9rKSkKICAgQSBjb21tZW50IG1lc3NhZ2UuCiAgICAvLy8KICAgIC8vLyBDb21tZW50cyBsb29rIGxpa2UgdGhpcyBpbiB0aGUgcmVzcG9uc2Ugc3RyZWFtLgogICAgLy8vIGBgYHBsYWluCiAgICAvLy8gOiBteSBjb21tZW50CiAgICAvLy8KICAgIC8vLyA6IGFub3RoZXIgY29tbWVudAogICAgLy8vIGBgYAogICAgQ29tbWVudChCeXRlU3RyaW5nKSwKfQoKI1tkb2MoaGlkZGVuKV0KI1tkZXByZWNhdGVkKHNpbmNlID0gIjAuMTcuMCIsIG5vdGUgPSAiUmVuYW1lZCB0byBgRXZlbnRgLiBQcmVmZXIgYHNzZTo6RXZlbnRgLiIpXQpwdWIgdHlwZSBTc2VNZXNzYWdlID0gRXZlbnQ7CgppbXBsIEV2ZW50IHsKICAgIC8vLyBTcGxpdHMgZGF0YSBpbnRvIGxpbmVzIGFuZCBwcmVwZW5kIGVhY2ggbGluZSB3aXRoIGBwcmVmaXhgLgogICAgZm4gbGluZV9zcGxpdF93aXRoX3ByZWZpeChidWY6ICZtdXQgQnl0ZXNNdXQsIHByZWZpeDogJidzdGF0aWMgc3RyLCBkYXRhOiBCeXRlU3RyaW5nKSB7CiAgICAgICAgLy8gaW5pdGlhbCBidWZmZXIgc2l6ZSBndWVzcyBpcyBsZW4oZGF0YSkgKyAxMCBsaW5lcyBvZiBwcmVmaXggKyBFT0xzICsgRU9GCiAgICAgICAgYnVmLnJlc2VydmUoZGF0YS5sZW4oKSArICgxMCAqIChwcmVmaXgubGVuKCkgKyAxKSkgKyAxKTsKCiAgICAgICAgLy8gYXBwZW5kIHByZWZpeCArIHNwYWNlICsgbGluZSB0byBidWZmZXIKICAgICAgICBmb3IgbGluZSBpbiBkYXRhLnNwbGl0KCdcbicpIHsKICAgICAgICAgICAgYnVmLnB1dF9zbGljZShwcmVmaXguYXNfYnl0ZXMoKSk7CiAgICAgICAgICAgIGJ1Zi5wdXRfc2xpY2UobGluZS5hc19ieXRlcygpKTsKICAgICAgICAgICAgYnVmLnB1dF91OChiJ1xuJyk7CiAgICAgICAgfQogICAgfQoKICAgIC8vLyBTZXJpYWxpemVzIG1lc3NhZ2UgaW50byBldmVudC1zdHJlYW0gZm9ybWF0LgogICAgZm4gaW50b19ieXRlcyhzZWxmKSAtPiBCeXRlcyB7CiAgICAgICAgbGV0IG11dCBidWYgPSBCeXRlc011dDo6bmV3KCk7CgogICAgICAgIG1hdGNoIHNlbGYgewogZV9zdHJlYW0pID0gc3NlOjpjaGFubmVsKDEwKTsKLy8hCi8vISAgICAgLy8gbm90ZTogc2VuZGVyIHdpbGwgdHlwaWNhbGx5IGJlIHNwYXduZWQgb3IgaGFuZGVkIG9mZiBzb21ld2hlcmUgZWxzZQovLyEgICAgIGxldCBfID0gc2VuZGVyLnNlbmQoc3NlOjpFdmVudDo6Q29tbWVudCgibXkgY29tbWVudCIuaW50bygpKSkuYXdhaXQ7Ci8vISAgICAgbGV0IF8gPSBzZW5kZXIuc2VuZChzc2U6OkRhdGE6Om5ldygibXkgZGF0YSIpLmV2ZW50KCJjaGF0X21zZyIpKS5hd2FpdDsKLy8hCi8vISAgICAgc3NlX3N0cmVhbS53aXRoX3JldHJ5X2R1cmF0aW9uKER1cmF0aW9uOjpmcm9tX3NlY3MoMTApKQovLyEgfQovLyEKLy8hICNbZ2V0KCIvZnJvbS1zdHJlYW0iKV0KLy8hIGFzeW5jIGZuIGZyb21fc3RyZWFtKCkgLT4gaW1wbCBSZXNwb25kZXIgewovLyEgICAgIGxldCBldmVudF9zdHJlYW0gPSBmdXR1cmVzX3V0aWw6OnN0cmVhbTo6aXRlcihbCi8vISAgICAgICAgIE9rOjo8XywgSW5mYWxsaWJsZT4oc3NlOjpFdmVudDo6RGF0YShzc2U6OkRhdGE6Om5ldygiZm9vIikpKSwKLy8hICAgICBdKTsKLy8hCi8vISAgICAgc3NlOjpTc2U6OmZyb21fc3RyZWFtKGV2ZW50X3N0cmVhbSkKLy8hICAgICAgICAgLndpdGhfa2VlcF9hbGl2ZShEdXJhdGlvbjo6ZnJvbV9zZWNzKDUpKQovLyEgfQovLyEgYGBgCi8vIQovLyEgQ29tcGxldGUgdXNhZ2UgZXhhbXBsZXMgY2FuIGJlIGZvdW5kIGluIHRoZSBleGFtcGxlcyBkaXJlY3Rvcnkgb2YgdGhlIHNvdXJjZSBjb2RlIHJlcG8uCgojIVtkb2MoCiAgICBhbGlhcyA9ICJzZXJ2ZXIgc2VudCIsCiAgICBhbGlhcyA9ICJzZXJ2ZXItc2VudCIsCiAgICBhbGlhcyA9ICJzZXJ2ZXIgc2VudCBldmVudHMiLAogICAgYWxpYXMgPSAic2VydmVyLXNlbnQgZXZlbnRzIiwKICAgIGFsaWFzID0gImV2ZW50LXN0cmVhbSIKKV0KCnVzZSBzdGQ6OnsKICAgIGNvbnZlcnQ6OkluZmFsbGlibGUsCiAgICBwaW46OlBpbiwKICAgIHRhc2s6OntDb250ZXh0LCBQb2xsfSwKICAgIHRpbWU6OnAoKTsKICAgIH0KCiAgICAjW2FjdGl4X3dlYjo6dGVzdF0KICAgIGFzeW5jIGZuIHRlc3RfcmVxdWVzdF9leHRyYWN0KCkgewogICAgICAgIGxldCBtdXQgcmVxID0gVGVzdFJlcXVlc3Q6OndpdGhfdXJpKCIvbmFtZS91c2VyMS8/aWQ9dGVzdCIpLnRvX3Nydl9yZXF1ZXN0KCk7CgogICAgICAgIGxldCByZXNvdXJjZSA9IFJlc291cmNlRGVmOjpuZXcoIi97a2V5fS97dmFsdWV9LyIpOwogICAgICAgIHJlc291cmNlLmNhcHR1cmVfbWF0Y2hfaW5mbyhyZXEubWF0Y2hfaW5mb19tdXQoKSk7CgogICAgICAgIGxldCAocmVxLCBtdXQgcGwpID0gcmVxLmludG9fcGFydHMoKTsKICAgICAgICBsZXQgcyA9IFBhdGg6OjxNeVN0cnVjdD46OmZyb21fcmVxdWVzdCgmcmVxLCAmbXV0IHBsKS5hd2FpdC51bndyYXAoKTsKICAgICAgICBhc3NlcnRfZXEhKGZvcm1hdCEoIntzfSIpLCAiTXlTdHJ1Y3QobmFtZSwgdXNlcjEpIik7CiAgICAgICAgYXNzZXJ0X2VxISgKICAgICAgICAgICAgZm9ybWF0ISgie3M6P30iKSwKICAgICAgICAgICAgIlBhdGgoTXlTdHJ1Y3QgeyBrZXk6IFwibmFtZVwiLCB2YWx1ZTogXCJ1c2VyMVwiIH0pIgogICAgICAgICk7CiAgICAgICAgbGV0IG11dCBzID0gcy5pbnRvX2lubmVyKCk7CiAgICAgICAgYXNzZXJ0X2VxIShzLmtleSwgIm5hbWUiKTsKICAgICAgICBhc3NlcnRfZXEhKHMudmFsdWUsICJ1c2VyMSIpOwogICAgICAgIHMudmFsdWUgPSAidXNlcjIiLnRvX3N0cmluZygpOwogICAgICAgIGFzc2VydF9lcSEocy52YWx1ZSwgInVzZXIyIik7CgogICAgICAgIGxldCBQYXRoKHMpID0gUGF0aDo6PChTdHJpbmcsIFN0cmluZyk+Ojpmcm9tX3JlcXVlc3QoJnJlcSwgJm11dCBwbCkKICAgICAgICAgICAgLmF3YWl0CiAgICAgICAgICAgIC51bndyYXAoKTsKICAgICAgICBhc3NlcnRfZXEhKHMuMCwgIm5hbWUiKTsKICAgICAgICBhc3NlcnRfZXEhKHMuMSwgInVzZXIxIik7CgogICAgICAgIGxldCBtdXQgcmVxID0gVGVzdFJlcXVlc3Q6OndpdGhfdXJpKCIvbmFtZS8zMi8iKS50b19iIGVudW0gRXJyIHsKICAgIEZldGNoLAp9CgppbXBsX21vcmU6OmltcGxfZGlzcGxheV9lbnVtIShFcnIsIEZldGNoID0+ICJmYWlsZWQgdG8gZmV0Y2giKTsKCmltcGwgc3RkOjplcnJvcjo6RXJyb3IgZm9yIEVyciB7fQoKI1tkZXJpdmUoRGVidWcsIERlc2VyaWFsaXplKV0KcHViIHN0cnVjdCBDZklwc1Jlc3VsdCB7CiAgICBpcHY0X2NpZHJzOiBWZWM8Y2lkcl91dGlsczo6Y2lkcjo6SXB2NENpZHI+LAogICAgaXB2Nl9jaWRyczogVmVjPGNpZHJfdXRpbHM6OmNpZHI6OklwdjZDaWRyPiwKfQoKI1tkZXJpdmUoRGVidWcsIERlc2VyaWFsaXplKV0KI1tzZXJkZSh1bnRhZ2dlZCldCnB1YiBlbnVtIENmSXBzUmVzcG9uc2UgewogICAgU3VjY2VzcyB7IHJlc3VsdDogQ2ZJcHNSZXN1bHQgfSwKICAgIEZhaWx1cmUgeyBzdWNjZXNzOiBib29sIH0sCn0KCi8vLyBUcnVzdGVkIElQIHJhbmdlcy4KI1tkZXJpdmUoRGVidWcpXQpwdWIgc3RydWN0IFRydXN0ZWRJcHMgewogICAgY2lkcl9yYW5nZXM6IElwQ2lkckNvbWJpbmVyLAp9CgppbXBsIFRydXN0ZWRJcHMgewogICAgcHViIGZuIHRyeV9mcm9tX3Jlc3BvbnNlKHJlczogQ2ZJcHNSZXNwb25zZSkgLT4gUmVzdWx0PFNlbGYsIEVycj4gewogICAgICAgIGxldCBpcHMgPSBtYXRjaCByZXMgewogICAgICAgICAgICBDZklwc1Jlc3BvbnNlOjpTdWNjZXNzIHsgcmVzdWx0IH0gPT4gcmVzdWx0LAogICAgICAgICAgICBDZklwc1Jlc3BvbnNlOjpGYWlsdXJlIHsgLi4gfSA9PiB7CiAgICAgICAgICAgICAgICB0cmFjaW5nOjplcnJvciEoInBhcnNpbmcgcmVzcG9uc2UgcmV0dXJuZWQgc3VjY2VzczogZmFsc2UiKTsKICAgICAgICAgICAgICAgIHJldHVybiBFcnIoRXJyOjpGZXRjaCk7CiAgICAgICAgICAgIH0KICAgICAgICB9OwoKICAgICAgICBsZXQgbXV0IGNpZHJfcmFuZ2VzID0gSXBDaWRyQ29tYmluZXI6Om5ldygpOwoKICAgICAgICBmb3IgY2lkciBpbiBpcHMuaXB2NF9jaWRycyB7CiAgICAgICAgICAgIGNpZHJfcmFuZ2VzLnB1c2goSXBDaWRyOjpWZXQgcmVxID0gdGhpcy5yZXEudGFrZSgpLnVud3JhcCgpOwogICAgICAgICAgICAgICAgZGVidWchKAogICAgICAgICAgICAgICAgICAgICJGYWlsZWQgdG8gZGVzZXJpYWxpemUgSnNvbjx7fT4gZnJvbSBwYXlsb2FkIGluIGhhbmRsZXI6IHt9IiwKICAgICAgICAgICAgICAgICAgICBjb3JlOjphbnk6OnR5cGVfbmFtZTo6PFQ+KCksCiAgICAgICAgICAgICAgICAgICAgcmVxLm1hdGNoX25hbWUoKS51bndyYXBfb3JfZWxzZSh8fCByZXEucGF0aCgpKQogICAgICAgICAgICAgICAgKTsKCiAgICAgICAgICAgICAgICBFcnIoZXJyLmludG8oKSkKICAgICAgICAgICAgfQogICAgICAgICAgICBPayhkYXRhKSA9PiBPayhKc29uKGRhdGEpKSwKICAgICAgICB9OwoKICAgICAgICBQb2xsOjpSZWFkeShyZXMpCiAgICB9Cn0KCi8vLyBGdXR1cmUgdGhhdCByZXNvbHZlcyB0byBzb21lIGBUYCB3aGVuIHBhcnNlZCBmcm9tIGEgSlNPTiBwYXlsb2FkLgovLy8KLy8vIENhbiBkZXNlcmlhbGl6ZSBhbnkgdHlwZSBgVGAgdGhhdCBpbXBsZW1lbnRzIFtgRGVzZXJpYWxpemVgXVtzZXJkZTo6RGVzZXJpYWxpemVdLgovLy8KLy8vIFJldHVybnMgZXJyb3IgaWY6Ci8vLyAtIGBDb250ZW50LVR5cGVgIGlzIG5vdCBgYXBwbGljYXRpb24vanNvbmAuCi8vLyAtIGBDb250ZW50LUxlbmd0aGAgaXMgZ3JlYXRlciB0aGFuIGBMSU1JVGAuCi8vLyAtIFRoZSBwYXlsb2FkLCB3aGVuIGNvbnN1bWVkLCBpcyBub3QgdmFsaWQgSlNPTi4KcHViIGVudW0gSnNvbkJvZHk8VCwgY29uc3QgTElNSVQ6IHVzaXplPiB7CiAgICBFcnJvcihPcHRpb248SnNvblBheWxvYWRFcnJvcj4pLAogICAgQm9keSB7CiAgICAgICAgLy8vIExlbmd0aCBhcyByZXBvcnRlZCBieSBgQ29udGVudC1MZW5ndGhgIGhlYWRlciwgaWYgcHJlc2VudC4KICAgICAgICBsZW5ndGg6IE9wdGlvbjx1c2l6ZT4sCiAgICAgICAgLy8gI1tjZmcoZmVhdHVyZSA9ICJfX2NvbXByZXNzIildCiAgICAgICAgLy8gcGF5bG9hZDogRGVjb21wcmVzczxQYXlsb2FkPiwKICAgICAgIC8vIG5leHQgbG9hZCBpbiBoYW5kbGVyIGxvYWRzIG5ldyB2YWx1ZQogICAgICAgIGxldCBleHRyYWN0ZWRfZGF0YSA9IFN3YXBEYXRhOjo8Tm9uQ29weT46OmV4dHJhY3QoJnJlcSkuYXdhaXQudW53cmFwKCk7CiAgICAgICAgYXNzZXJ0X2VxISgqKmV4dHJhY3RlZF9kYXRhLmxvYWQoKSwgTm9uQ29weSg4MCkpOwoKICAgICAgICAvLyBpbml0aWFsIGV4dHJhY3RlZCBkYXRhIHN0YXlzIHRoZSBzYW1lCiAgICAgICAgYXNzZXJ0X2VxISgqaW5pdGlhbF9kYXRhLCBOb25Db3B5KDQyKSk7CiAgICB9Cn0KLy8hIEV4cGVyaW1lbnRhbCBib2R5IHR5cGVzLgovLyEKLy8hIEFuYWxvZ291cyB0byB0aGUgYGJvZHlgIG1vZHVsZSBpbiBBY3RpeCBXZWIuCgpwdWIgdXNlIGNyYXRlOjp7CiAgICBib2R5X2FzeW5jX3dyaXRlOjp7d3JpdGVyLCBXcml0ZXJ9LAogICAgYm9keV9jaGFubmVsOjp7Y2hhbm5lbCwgU2VuZGVyfSwKICAgIGluZmFsbGlibGVfYm9keV9zdHJlYW06OntuZXdfaW5mYWxsaWJsZV9ib2R5X3N0cmVhbSwgbmV3X2luZmFsbGlibGVfc2l6ZWRfc3RyZWFtfSwKfTsKLy8hIEV4cGVyaW1lbnRhbCB0eXBlZCBoZWFkZXJzLgoKcHViIHVzZSBjcmF0ZTo6ewogICAgY2FjaGVfY29udHJvbDo6e0NhY2hlQ29udHJvbCwgQ2FjaGVEaXJlY3RpdmV9LAogICAgY29udGVudF9sZW5ndGg6OkNvbnRlbnRMZW5ndGgsCiAgICBmb3J3YXJkZWQ6OkZvcndhcmRlZCwKICAgIHN0cmljdF90cmFuc3BvcnRfc2VjdXJpdHk6OlN0cmljdFRyYW5zcG9ydFNlY3VyaXR5LAp9OwoKI1tjZmcodGVzdCldCm1vZCBoZWFkZXJfdGVzdF9oZWxwZXJzIHsKICAgIHVzZSBzdGQ6OmZtdDsKCiAgICB1c2UgYWN0aXhfaHR0cDo6aGVhZGVyOjpIZWFkZXI7CiAgICB1c2UgYWN0aXhfd2ViOjp7dGVzdCwgSHR0cFJlcXVlc3R9OwoKICAgIGZuIHJlcV9mcm9tX3Jhd19oZWFkZXJzPEg6IEhlYWRlciwgSTogSW50b0l0ZXJhdG9yPEl0ZW0gPSBWPiwgVjogQXNSZWY8W3U4XT4+KAogICAgICAgIGhlYWRlcl9saW5lczogSSwKICAgICllIHsKICAgIGZuIGVxKCZzZWxmLCBvdGhlcjogJkNvbnRlbnRMZW5ndGgpIC0+IGJvb2wgewogICAgICAgICpzZWxmID09IG90aGVyLjAKICAgIH0KfQoKaW1wbCBQYXJ0aWFsT3JkPHVzaXplPiBmb3IgQ29udGVudExlbmd0aCB7CiAgICBmbiBwYXJ0aWFsX2NtcCgmc2VsZiwgb3RoZXI6ICZ1c2l6ZSkgLT4gT3B0aW9uPHN0ZDo6Y21wOjpPcmRlcmluZz4gewogICAgICAgIHNlbGYuMC5wYXJ0aWFsX2NtcChvdGhlcikKICAgIH0KfQoKaW1wbCBQYXJ0aWFsT3JkPENvbnRlbnRMZW5ndGg+IGZvciB1c2l6ZSB7CiAgICBmbiBwYXJ0aWFsX2NtcCgmc2VsZiwgb3RoZXI6ICZDb250ZW50TGVuZ3RoKSAtPiBPcHRpb248c3RkOjpjbXA6Ok9yZGVyaW5nPiB7CiAgICAgICAgc2VsZi5wYXJ0aWFsX2NtcCgmb3RoZXIuMCkKICAgIH0KfQoKI1tjZmcodGVzdCldCm1vZCB0ZXN0cyB7CiAgICB1c2Ugc3VwZXI6Oio7CiAgICB1c2UgY3JhdGU6OmhlYWRlcjo6e2Fzc2VydF9wYXJzZV9lcSwgYXNzZXJ0X3BhcnNlX2ZhaWx9OwoKICAgICNbdGVzdF0KICAgIGZuIG1pc3NpbmdfaGVhZGVyKCkgewogICAgICAgIGFzc2VydF9wYXJzZV9mYWlsOjo8Q29udGVudExlbmd0aCwgXywgXz4oWyIiOyAwXSk7CiAgICAgICAgYXNzZXJ0X3BhcnNlX2ZhaWw6OjxDb250ZW50TGVuZ3RoLCBfLCBfPihbIiJdKTsKICAgIH0KCiAgICAjW3Rlc3RdCiAgICBmbiBiYWRfaGVhZGVyKCkgewogICAgICAgIGFzc2VydF9wYXJzZV9mYWlsOjo8Q29udGVudExlbmd0aCwgXywgXz4oWyItMTIzIl0pOwogICAgICAgIGFzc2VydF9wYXJzZV9mYWlsOjo8Q29udGVudExlbmd0aCwgXywgXz4oWyIxMjNfNDU2Il0pOwogICAgICAgIGFzc2VydF9wYXJzZV9mYWlsOjo8Q29udGVudExlbmd0aCwgXywgXz4oWyIxMjMuNDU2Il0pOwoKICAgICAgICAvLyB0b28gbGFyZ2UgZm9yIHU2NCAoMl42NCwgMl42NCArIDEpCiAgICAgICAgYXNzZXJ0X3BhcnNlX2ZhaWw6OjxDb250ZW50TGVuZ3RoLCBfLCBfPihbIjE4NDQ2NzQ0MDczNzA5NTUxNjE2Il0pOwogLy8hIEV4cGVyaW1lbnRhbCByb3V0ZSBndWFyZHMuCi8vIQovLyEgQW5hbG9nb3VzIHRvIHRoZSBgZ3VhcmRgIG1vZHVsZSBpbiBBY3RpeCBXZWIuCgojW2FsbG93KGRlcHJlY2F0ZWQpXQpwdWIgdXNlIGNyYXRlOjphY2NlcHRhYmxlOjpBY2NlcHRhYmxlOwovLyEgRXh0cmFjdG9yIGZvciBjbGllbnQgSVAgYWRkcmVzc2VzIHdoZW4gcHJveGllZCB0aHJvdWdoIENsb3VkZmxhcmUuCgovLyAjIVtmb3JiaWQodW5zYWZlX2NvZGUpXSAvLyB1cmdoIHdoeSBjaWRyLXV0aWxzCiMhW2RlbnkocnVzdF8yMDE4X2lkaW9tcywgbm9uc3RhbmRhcmRfc3R5bGUpXQojIVt3YXJuKGZ1dHVyZV9pbmNvbXBhdGlibGUpXQovLyAjIVt3YXJuKG1pc3NpbmdfZG9jcyldCiMhW2NmZ19hdHRyKGRvY3NycywgZmVhdHVyZShkb2NfYXV0b19jZmcpKV0KCm1vZCBleHRyYWN0Owptb2QgZmV0Y2hfY2ZfaXBzOwptb2QgaGVhZGVyX3Y0OwovLyBtb2QgaGVhZGVyX3Y2OwoKcHViIHVzZSBzZWxmOjpleHRyYWN0OjpUcnVzdGVkQ2xpZW50SXA7CiNbY2ZnKGZlYXR1cmUgPSAiZmV0Y2gtaXBzIildCnB1YiB1c2Ugc2VsZjo6ZmV0Y2hfY2ZfaXBzOjpmZXRjaF90cnVzdGVkX2NmX2lwczsKcHViIHVzZSBzZWxmOjpmZXRjaF9jZl9pcHM6OntUcnVzdGVkSXBzLCBDRl9VUkxfSVBTfTsKcHViIHVzZSBzZWxmOjpoZWFkZXJfdjQ6OkNmQ29ubmVjdGluZ0lwOwovLyEgRm9yd2FyZGVkIHR5cGVkIGhlYWRlci4KLy8hCi8vISBTZWUgW2BGb3J3YXJkZWRgXSBkb2NzLgoKdXNlIHN0ZDo6e2NvbnZlcnQ6OkluZmFsbGlibGUsIHN0cn07Cgp1c2UgYWN0aXhfd2ViOjp7CiAgICBlcnJvcjo6UGFyc2VFcnJvciwKICAgIGh0dHA6OmhlYWRlcjo6e3NlbGYsIEhlYWRlciwgSGVhZGVyTmFtZSwgSGVhZGVyVmFsdWUsIFRyeUludG9IZWFkZXJWYWx1ZX0sCiAgICBIdHRwTWVzc2FnZSwKfTsKdXNlIGl0ZXJ0b29sczo6SXRlcnRvb2xzIGFzIF87CgovLyBUT0RPOiBpbXBsZW1lbnQgdHlwZWQgcGFyc2luZyBvZiBOb2RlIGlkZW50aWZpZXJzIGFzIHBlcmdlc3Q6OntnZW5lcmljX2FycmF5OjpHZW5lcmljQXJyYXksIERpZ2VzdH07CnVzZSBmdXR1cmVzX2NvcmU6OlN0cmVhbSBhcyBfOwp1c2UgcGluX3Byb2plY3RfbGl0ZTo6cGluX3Byb2plY3Q7CnVzZSB0cmFjaW5nOjp0cmFjZTsKCi8vLyBQYXJ0cyBvZiB0aGUgcmVzdWx0aW5nIGJvZHkgaGFzaCBleHRyYWN0b3IuCnB1YiBzdHJ1Y3QgQm9keUhhc2hQYXJ0czxUPiB7CiAgICAvLy8gRXh0cmFjdGVkIGl0ZW0uCiAgICBwdWIgaW5uZXI6IFQsCgogICAgLy8vIEJ5dGVzIG9mIHRoZSBjYWxjdWxhdGVkIGhhc2guCiAgICBwdWIgaGFzaF9ieXRlczogVmVjPHU4PiwKfQoKLy8vIFdyYXBzIGFuIGV4dHJhY3RvciBhbmQgY2FsY3VsYXRlcyBhIGJvZHkgY2hlY2tzdW0gaGFzaCBhbG9uZ3NpZGUuCi8vLwovLy8gSWYgeW91ciBleHRyYWN0b3Igd291bGQgdXN1YWxseSBiZSBgVGAgYW5kIHlvdSB3YW50IHRvIGNyZWF0ZSBhIGhhc2ggb2YgdHlwZSBgRGAgdGhlbiB5b3UgbmVlZAovLy8gdG8gdXNlIGBCb2R5SGFzaDxULCBEPmAuIEUuZy4sIGBCb2R5SGFzaDxTdHJpbmcsIFNoYTI1Nj5gLgovLy8KLy8vIEFueSBoYXNoZXIgdGhhdCBpbXBsZW1lbnRzIFtgRGlnZXN0YF0gY2FuIGJlIHVzZWQuIFR5cGUgYWxpYXNlcyBmb3IgY29tbW9uIGhhc2hpbmcgYWxnb3JpdGhtcwovLy8gYXJlIGF2YWlsYWJsZSBhdCB0aGUgY3JhdGUgcm9vdC4KLy8vCi8vLyAjIEVycm9ycwovLy8gVGhpcyBleHRyYWN0b3IgcHJvZHVjZXMgbm8gZXJyb3JzIG9mIGl0cyBvd24gYW5kIGFsbCBlcnJvcnMgZnJvbSB0aGUgdW5kZXJseWluZyBleHRyYWN0b3IgYXJlCi8vLyBwcm9wYWdhdGVkIGNvcnJlY3RseTsgZm9yIGV4YW1wbGUsIGlmIHRoZSBwYXlsb2FkIGxpbWl0cyBhcmUgZXhjZWVkZWQuCi8vLwovLy8gIyBXaGVuIFVzZWQgT24gVGhlIFdyb25nIEV4dHJhY3RvcgovLy8gVXNlIG9uIGEgbm9uLWJvZHkgZXh0cmFjdG9yIGlzIHRvbGVyYXRlZCB1bmxlc3MgaXQgaXMgdXNlZCBhZnRlciBhIGRpZmZlcmVudCBleHRyYWN0b3IgdGhpZ25hdHVyZSIpKT8KICAgICAgICAgICAgLm9rX29yX2Vsc2UofHwgZXJyb3I6OkVycm9yVW5hdXRob3JpemVkKCJzaWduYXR1cmUgbm90IHByb3ZpZGVkIikpPwogICAgICAgICAgICAudHJ5X2ludG8oKQogICAgICAgICAgICAubWFwX2Vycih8X3wgZXJyb3I6OkVycm9ySW50ZXJuYWxTZXJ2ZXJFcnJvcigiaW52YWxpZCBzaWduYXR1cmUiKSk/OwoKICAgICAgICBPayhTaWduYXR1cmU6OmZyb20oc2lnKSkKICAgIH0KfQoKI1thc3luY190cmFpdCg/U2VuZCldCmltcGwgUmVxdWVzdFNpZ25hdHVyZVNjaGVtZSBmb3IgRGlzY29yZFdlYmhvb2sgewogICAgdHlwZSBTaWduYXR1cmUgPSAoQnl0ZXNNdXQsIFNpZ25hdHVyZSk7CgogICAgdHlwZSBFcnJvciA9IEVycm9yOwoKICAgIGFzeW5jIGZuIGluaXQocmVxOiAmSHR0cFJlcXVlc3QpIC0+IFJlc3VsdDxTZWxmLCBTZWxmOjpFcnJvcj4gewogICAgICAgIGxldCB0cyA9IFNlbGY6OmdldF90aW1lc3RhbXAocmVxKT8udG9fb3duZWQoKTsKICAgICAgICBsZXQgY2FuZGlkYXRlX3NpZ25hdHVyZSA9IFNlbGY6OmdldF9zaWduYXR1cmUocmVxKT87CgogICAgICAgIE9rKFNlbGYgewogICAgICAgICAgICBjYW5kaWRhdGVfc2lnbmF0dXJlLAogICAgICAgICAgICBjaHVua3M6IHZlYyFbQnl0ZXM6OmZyb20odHMpXSwKICAgICAgICB9KQogICAgfQoKICAgIGFzeW5jIGZuIGNvbnN1bWVfY2h1bmsoJm11dCBzZWxmLCBfcmVxOiAmSHR0cFJlcXVlc3QsIGNodW5rOiBCeXRlcykgLT4gUmVzdWx0PCgpLCBTZWxmOjpFcnJvcj4gewogICAgICAgIHNlbGYuY2h1bmtzLnB1c2goY2h1bmspOwogICAgICAgIE9rKCgpKQogICAgfQoKICAgIGFzeW5jIGZuIGZpbmFsaXplKHNlbGYsIF9yZXE6ICZIdHRwUmVxdWVzdCkgLT4gUmVzdWx0PFNlbGY6OlNpZ25hdHVyZSwgU2VsZjo6RXJyb3I+IHsKICAgICAgICBsZXQgYnVmX2xlbiA9IHNlbGYuY2h1bmtzLml0ZXIoKS5tYXAofGNodW5rfCBjaHVuay5sZW4oKSkuc3VtKCk7CiAgICAgICAgbGV0IG11dCBidWYgPSBCeXRlUmM8Rj4sCiAgICAgICAgI1twaW5dCiAgICAgICAgc3RhdGU6IE1hcFJlc0Z1dFN0YXRlPFN2Y0Z1dCwgRm5GdXQ+LAogICAgfQp9CgpwaW5fcHJvamVjdCEgewogICAgI1twcm9qZWN0ID0gTWFwUmVzRnV0U3RhdGVQcm9qXQogICAgZW51bSBNYXBSZXNGdXRTdGF0ZTxTdmNGdXQsIEZuRnV0PiB7CiAgICAgICAgU3ZjIHsgI1twaW5dIGZ1dDogU3ZjRnV0IH0sCiAgICAgICAgRm4geyAjW3Bpbl0gZnV0OiBGbkZ1dCB9LAogICAgfQp9CgppbXBsPFN2Y0Z1dCwgQiwgRiwgRm5GdXQsIEIyPiBGdXR1cmUgZm9yIE1hcFJlc0Z1dDxTdmNGdXQsIEYsIEZuRnV0Pgp3aGVyZQogICAgU3ZjRnV0OiBGdXR1cmU8T3V0cHV0ID0gUmVzdWx0PFNlcnZpY2VSZXNwb25zZTxCPiwgRXJyb3I+PiwKICAgIEY6IEZuKFNlcnZpY2VSZXNwb25zZTxCPikgLT4gRm5GdXQsCiAgICBGbkZ1dDogRnV0dXJlPE91dHB1dCA9IFJlc3VsdDxTZXJ2aWNlUmVzcG9uc2U8QjI+LCBFcnJvcj4+LAp7CiAgICB0eXBlIE91dHB1dCA9IFJlc3VsdDxTZXJ2aWNlUmVzcG9uc2U8QjI+LCBFcnJvcj47CgogICAgZm4gcG9sbChtdXQgc2VsZjogUGluPCZtdXQgU2VsZj4sIGN4OiAmbXV0IENvbnRleHQ8J18+KSAtPiBQb2xsPFNlbGY6Ok91dHB1dD4gewogICAgICAgIGxldCBtdXQgdGhpcyA9IHNlbGYuYXNfbXV0KCkucHJvamVjdCgpOwoKICAgICAgICBtYXRjaCB0aGlzLnN0YXRlLmFzX211dCgpLnByb2plY3QoKSB7CiAgICAgICAgICAgIE1hcFJlc0Z1dFN0YXRlUHJvajo6U3ZjIHsgZnV0IH0gPT4gewogICAgICAgICAgICAgICAgbGV0IHJlcyA9IHJlYWR5IShmdXQucG9sbChjeCkpPzsKCiAgICAgICAgICAgICAgICBsZXQgZnV0ID0gKHRoaXMubXdfZm4pKHJlcyk7CiAgICAgICAgICAgICAgICB0aGlzLnN0YXRlLnNldChNYXBSZXNGdXRTdGF0ZTo6Rm4geyBmdXQgfSk7CiAgICAgICAgICAgICAgICBzZWxmLnBvbGwoY3gpCiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIE1hcFJlc0Z1dFN0YXRlUHJvajo6Rm4geyBmdXQgfSA9PiBmdSBjaHVuayBzdHJlYW0uCi8vLwovLy8gVGhpcyBjb3VsZCBiZSBzdGFiaWxpemVkIGludG8gQWN0aXggV2ViIGFzIGBTaXplZFN0cmVhbTo6ZnJvbV9pbmZhbGxpYmxlKClgLgpwdWIgZm4gbmV3X2luZmFsbGlibGVfc2l6ZWRfc3RyZWFtPFM6IFN0cmVhbTxJdGVtID0gQnl0ZXM+PigKICAgIHNpemU6IHU2NCwKICAgIHN0cmVhbTogUywKKSAtPiBTaXplZFN0cmVhbTxJbmZhbGxpYmxlU3RyZWFtPFM+PiB7CiAgICBTaXplZFN0cmVhbTo6bmV3KHNpemUsIEluZmFsbGlibGVTdHJlYW06Om5ldyhzdHJlYW0pKQp9CnVzZSBzdGQ6Ontjb252ZXJ0OjpJbmZhbGxpYmxlLCBpbywgdGltZTo6RHVyYXRpb259OwoKdXNlIGFjdGl4X3dlYjo6e2dldCwgbWlkZGxld2FyZTo6TG9nZ2VyLCBBcHAsIEh0dHBSZXF1ZXN0LCBIdHRwU2VydmVyLCBSZXNwb25kZXJ9Owp1c2UgYWN0aXhfd2ViX2xhYjo6e2V4dHJhY3Q6OlBhdGgsIHJlc3BvbmQ6Okh0bWwsIHNzZX07CnVzZSBmdXR1cmVzX3V0aWw6OnN0cmVhbTsKdXNlIHRpbWU6OmZvcm1hdF9kZXNjcmlwdGlvbjo6d2VsbF9rbm93bjo6UmZjMzMzOTsKdXNlIHRva2lvOjp0aW1lOjpzbGVlcDsKCiNbZ2V0KCIvIildCmFzeW5jIGZuIGluZGV4KCkgLT4gaW1wbCBSZXNwb25kZXIgewogICAgSHRtbChpbmNsdWRlX3N0ciEoIi4vYXNzZXRzL3NzZS5odG1sIikudG9fc3RyaW5nKCkpCn0KCi8vLyBDb3VudGRvd24gZXZlbnQgc3RyZWFtIHN0YXJ0aW5nIGZyb20gOC4KI1tnZXQoIi9jb3VudGRvd24iKV0KYXN5bmMgZm4gY291bnRkb3duKHJlcTogSHR0cFJlcXVlc3QpIC0+IGltcGwgUmVzcG9uZGVyIHsKICAgIC8vIG5vdGU6IGEgbW9yZSBwcm9kdWN0aW9uLXJlYWR5IGltcGxlbWVudGF0aW9uIG1pZ2h0IHdhbnQgdG8gdXNlIHRoZSBsYXN0RXZlbnRJZCBoZWFkZXIKICAgIC8vIHNlbnQgYnkgdGhlIHJlY29ubmVjdGluZyBicm93c2VyIGFmdGVyIHRoZSBfcmV0cnlfIHBlcmlvZAogICAgdHJhY2luZzo6ZGVidWchKCJsYXN0RXZlbnRJZDogezo/fSIsIHJlcS5oZWFkZXJlPiBVcmxFbmNvZGVkRm9ybUJvZHk8VCwgTElNSVQ+IHsKICAgIC8vLyBDcmVhdGUgYSBuZXcgZnV0dXJlIHRvIGRlY29kZSBhIFVSTC1lbmNvZGVkIHJlcXVlc3QgcGF5bG9hZC4KICAgIHB1YiBmbiBuZXcocmVxOiAmSHR0cFJlcXVlc3QsIHBheWxvYWQ6ICZtdXQgUGF5bG9hZCkgLT4gU2VsZiB7CiAgICAgICAgLy8gY2hlY2sgY29udGVudC10eXBlCiAgICAgICAgbGV0IGNhbl9wYXJzZV9mb3JtID0gaWYgbGV0IE9rKFNvbWUobWltZSkpID0gcmVxLm1pbWVfdHlwZSgpIHsKICAgICAgICAgICAgbWltZSA9PSBtaW1lOjpBUFBMSUNBVElPTl9XV1dfRk9STV9VUkxFTkNPREVECiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgZmFsc2UKICAgICAgICB9OwoKICAgICAgICBpZiAhY2FuX3BhcnNlX2Zvcm0gewogICAgICAgICAgICByZXR1cm4gVXJsRW5jb2RlZEZvcm1Cb2R5OjpFcnJvcihTb21lKFVybGVuY29kZWRFcnJvcjo6Q29udGVudFR5cGUpKTsKICAgICAgICB9CgogICAgICAgIGxldCBsZW5ndGggPSByZXEKICAgICAgICAgICAgLmhlYWRlcnMoKQogICAgICAgICAgICAuZ2V0KCZoZWFkZXI6OkNPTlRFTlRfTEVOR1RIKQogICAgICAgICAgICAuYW5kX3RoZW4ofGx8IGwudG9fc3RyKCkub2soKSkKICAgICAgICAgICAgLmFuZF90aGVuKHxzfCBzLnBhcnNlOjo8dXNpemU+KCkub2soKSk7CgogICAgICAgIC8vIE5vdGljZSB0aGUgY29udGVudC1sZW5ndGggaXMgbm90IGNoZWNrZWQgYWdhaW5zdCBjb25maWcgbGltaXQgaGVyZS4KICAgICAgICAvLyBBcyB0aGUgaW50ZXJuYWwgdXNhZ2UgYWx3YXlzIGNhbGwgVXJsRW5jb2RlZEJvZHk6OmxpbWl0IGFmdGVyIFVybEVuY29kZWRCb2R5OjpuZXcuCiAgICAgICAgLy8gQW5kIGxpbWl0IGNoZWNrIHRvIHJldHVybiBhbiBlcnJvciB2YXJpYW50IG9mIFVybEVuY29kZWRCb2R5IGhhcHBlbnMgdGhlcmUuCgogICAgICAgIGxldCBwYXlsb2FkID0gcGF5bG9hZC50YWtlKCk7CgogICAgICAgIGlmIGxldCBTb21lKGxlbikgPSBsZW5ndGggewogICAgbmV3KCkKLy8vICAgICAud3JhcChmcm9tX2ZuKG15X213KSkKLy8vICMgOwovLy8gYGBgCi8vLwovLy8gSXQgaXMgYWxzbyBwb3NzaWJsZSB0byB3cml0ZSBhIG1pZGRsZXdhcmUgdGhhdCBhdXRvbWF0aWNhbGx5IHVzZXMgZXh0cmFjdG9ycywgc2ltaWxhciB0byByZXF1ZXN0Ci8vLyBoYW5kbGVycywgYnkgZGVjbGFyaW5nIHRoZW0gYXMgdGhlIGZpcnN0IHBhcmFtZXRlcnM6Ci8vLyBgYGAKLy8vICMgdXNlIHN0ZDo6Y29sbGVjdGlvbnM6Okhhc2hNYXA7Ci8vLyAjIHVzZSBhY3RpeF93ZWI6OnsKLy8vICMgICAgIEFwcCwgRXJyb3IsCi8vLyAjICAgICBib2R5OjpNZXNzYWdlQm9keSwKLy8vICMgICAgIGRldjo6e1NlcnZpY2VSZXF1ZXN0LCBTZXJ2aWNlUmVzcG9uc2UsIFNlcnZpY2UgYXMgX30sCi8vLyAjICAgICB3ZWIsCi8vLyAjIH07Ci8vLyB1c2UgYWN0aXhfd2ViX2xhYjo6bWlkZGxld2FyZTo6TmV4dDsKLy8vCi8vLyBhc3luYyBmbiBteV9leHRyYWN0aW5nX213KAovLy8gICAgIHN0cmluZ19ib2R5OiBTdHJpbmcsCi8vLyAgICAgcXVlcnk6IHdlYjo6UXVlcnk8SGFzaE1hcDxTdHJpbmcsIFN0cmluZz4+LAovLy8gICAgIHJlcTogU2VydmljZVJlcXVlc3QsCi8vLyAgICAgbmV4dDogTmV4dDxpbXBsIE1lc3NhZ2VCb2R5PiwKLy8vICkgLT4gUmVzdWx0PFNlcnZpY2VSZXNwb25zZTxpbXBsIE1lc3NhZ2VCb2R5PiwgRXJyb3I+IHsKLy8vICAgICAvLyBwcmUtcHJvY2Vzc2luZwovLy8gICAgIG5leHQuY2FsbChyZXEpLmF3YWl0Ci8vLyAgICAgLy8gcG9zdC1wcm9jZXNzaW5nCi8vLyB9Ci8vLyAjIGFjdGl4X3dlYjo6QXBwOjpuZXcoKS53cmFwKGFjdGl4X3dlYl9sYWI6Om1pZGRsZXdhcmU6OmZyb21fZm4obXlfZXh0cmFjdGluZ19tdykpOwpwdWIgZm4gZnJvbV9mbjxGLCBFcz4obXdfZm46IEYpIC0+IE1pZGRsZXdhcmVGbjxGLCBFcz4gewogICAgTWlkZGxld2FyZUZuIHsKICAgICAgICBtd19mbjogUmM6Om5ldyhtd19mbiksCiAgICAgICAgX3BoYW50b206IFBoYW50b21EYXRhLAogICAgfWcsIFBhcnRpYWxFcSwgRXEsIEFzUmVmLCBEaXNwbGF5LCBGcm9tKV0KcHViIHN0cnVjdCBCb2R5TGltaXQ8VCwgY29uc3QgTElNSVQ6IHVzaXplID0gREVGQVVMVF9CT0RZX0xJTUlUPiB7CiAgICBpbm5lcjogVCwKfQoKaW1wbDxULCBjb25zdCBMSU1JVDogdXNpemU+IEJvZHlMaW1pdDxULCBMSU1JVD4gewogICAgLy8vIFJldHVybnMgaW5uZXIgZXh0cmFjdGVkIHR5cGUuCiAgICBwdWIgZm4gaW50b19pbm5lcihzZWxmKSAtPiBUIHsKICAgICAgICBzZWxmLmlubmVyCiAgICB9Cn0KCmltcGw8VCwgY29uc3QgTElNSVQ6IHVzaXplPiBGcm9tUmVxdWVzdCBmb3IgQm9keUxpbWl0PFQsIExJTUlUPgp3aGVyZQogICAgVDogRnJvbVJlcXVlc3QgKyAnc3RhdGljLAogICAgVDo6RXJyb3I6IGZtdDo6RGVidWcgKyBmbXQ6OkRpc3BsYXksCnsKICAgIHR5cGUgRXJyb3IgPSBCb2R5TGltaXRFcnJvcjxUPjsKICAgIHR5cGUgRnV0dXJlID0gQm9keUxpbWl0RnV0PFQsIExJTUlUPjsKCiAgICBmbiBmcm9tX3JlcXVlc3QocmVxOiAmSHR0cFJlcXVlc3QsIHBheWxvYWQ6ICZtdXQgUGF5bG9hZCkgLT4gU2VsZjo6RnV0dXJlIHsKICAgICAgICAvLyBmYXN0IGNoZWNrIG9mIENvbnRlbnQtTGVuZ3RoIGhlYWRlcgogICAgICAgIG1hdGNoIHJlcS5nZXRfaGVhZGVyOjo8Q29udGVudExlbmd0aD4oKSB7CiAgICAgICAgICAgIC8vIENMIGhlYWRlciBpbmRpY2F0ZWQgdGhhdCBwYXlsb2FkIHdvdWxkIGJlIHRvbyBsYXJnZQogICAgICAgICAgICBTb21lKGxlbikgaWYgbGVuID4gTElNSVQgPT4gcmV0dXJuIEJvZHlMaW1pdEZ1dDo6bmV3X2Vycm9yKEJvZHlMaW1pdEVycm9yOjpPdmVyZmxvdyksCiAgICAgICAgICAgIF8gPT4ge30KICAgICAgICB9CgogICAgICAgIGxldCBjb3VudGVyID0gY3JhdGU6OnV0aWw6OmZvcmtfcmVxdWVzdF9wYXlsb2FkKHBheWxvYWQpOwoKICAgICAgICBCb2R5TGltaXRGdXQgewogICAgICAgICAgICBpbm5lcjogSW5uZXI6OkJvZHkgewogICAgICAgICAgICAgICAgZnV0OiBCb3g6OnBpbiggIGlmIGxldCBTb21lKHN0KSA9IHJlcS5hcHBfZGF0YTo6PExvY2FsRGF0YTxUPj4oKSB7CiAgICAgICAgICAgIG9rKHN0LmNsb25lKCkpCiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgZGVidWchKAogICAgICAgICAgICAgICAgIkZhaWxlZCB0byBleHRyYWN0IGBMb2NhbERhdGE8e30+YCBmb3IgYHt9YCBoYW5kbGVyLiBGb3IgdGhlIExvY2FsRGF0YSBleHRyYWN0b3IgXAogICAgICAgICAgICAgICAgdG8gd29yayBjb3JyZWN0bHksIHdyYXAgdGhlIGRhdGEgd2l0aCBgTG9jYWxEYXRhOjpuZXcoKWAgYW5kIHBhc3MgaXQgdG8gXAogICAgICAgICAgICAgICAgYEFwcDo6YXBwX2RhdGEoKWAuIEVuc3VyZSB0aGF0IHR5cGVzIGFsaWduIGluIGJvdGggdGhlIHNldCBhbmQgcmV0cmlldmUgY2FsbHMuIiwKICAgICAgICAgICAgICAgIHR5cGVfbmFtZTo6PFQ+KCksCiAgICAgICAgICAgICAgICByZXEubWF0Y2hfbmFtZSgpLnVud3JhcF9vcl9lbHNlKHx8IHJlcS5wYXRoKCkpCiAgICAgICAgICAgICk7CgogICAgICAgICAgICBlcnIoZXJyb3I6OkVycm9ySW50ZXJuYWxTZXJ2ZXJFcnJvcigKICAgICAgICAgICAgICAgICJSZXF1ZXN0ZWQgYXBwbGljYXRpb24gZGF0YSBpcyBub3QgY29uZmlndXJlZCBjb3JyZWN0bHkuIFwKICAgICAgICAgICAgICAgIFZpZXcvZW5hYmxlIGRlYnVnIGxvZ3MgZm9yIG1vcmUgZGV0YWlscy4iLAogICAgICAgICAgICApKQogICAgICAgIH0KICAgIH0KfQoKI1tjZmcodGVzdCldCm1vZCB0ZXN0cyB7CiAgICB1c2UgYWN0aXhfd2ViOjp7CiAgICAgICAgZGV2OjpTZXJ2aWNlLAogICAgICAgIGh0dHA6OlN0YXR1c0NvZGUsCiAgICAgICAgdGVzdDo6e2luaXRfc2VydmljZSwgVGVzdFJlcXVlc3R9LAogICAgICAgIHdlYiwgQXBwLCBIdHRwUmVzcG9uc2UsCiAgICB9OwoKICAgIHVzZSBzdXBlcjo6KjsKCiAgICB0cmFpdCBUZXN0VHJhaXQgewogICAgICAgIGZuIGdldF9udW0oJnNlbGYpIC0+IGkzMjsKICAgIH0KCiAgICBzdHJ1Y3QgQSB7fQoKICAgIGltcGwgVGVzdFRyaHR0cDovL3t9Ont9IiwgJmJpbmQuMCwgJmJpbmQuMSk7CgogICAgSHR0cFNlcnZlcjo6bmV3KHx8IHsKICAgICAgICBBcHA6Om5ldygpCiAgICAgICAgICAgIC5zZXJ2aWNlKGdldF91c2VyX2xpc3QpCiAgICAgICAgICAgIC5zZXJ2aWNlKGdldF9oaWdoX21lbV91c2VyX2xpc3QpCiAgICB9KQogICAgLndvcmtlcnMoMSkKICAgIC5iaW5kKGJpbmQpPwogICAgLnJ1bigpCiAgICAuYXdhaXQKfQoKZm4gcmFuZG9tX2VtYWlsKCkgLT4gU3RyaW5nIHsKICAgIGxldCBybmcgPSByYW5kOjp0aHJlYWRfcm5nKCk7CgogICAgbGV0IGlkOiBTdHJpbmcgPSBybmcKICAgICAgICAuc2FtcGxlX2l0ZXIoQWxwaGFudW1lcmljKQogICAgICAgIC50YWtlKDEwKQogICAgICAgIC5tYXAoY2hhcjo6ZnJvbSkKICAgICAgICAuY29sbGVjdCgpOwoKICAgIGZvcm1hdCEoInVzZXJfe2lkfUBleGFtcGxlLmNvbSIpCn0KCmZuIHJhbmRvbV9hZGRyZXNzKCkgLT4gU3RyaW5nIHsKICAgIGxldCBtdXQgcm5nID0gcmFuZDo6dGhyZWFkX3JuZygpOwogICAgbGV0IHN0cmVldF9ubzogdTE2ID0gcm5nLmdlbl9yYW5nZSgxMC4uOTkpOwogICAgZm9ybWF0ISgie3N0cmVldF9ub30gUmFuZG9tIFN0cmVldCIpCn0KLy8vIENyZWF0ZSBhIGBUZXN0UmVxdWVzdGAgdXNpbmcgYSBEU0wgdGhhdCBsb29rcyBraW5kYSBsaWtlIG9uLXRoZS13aXJlIEhUVFAvMS54IHJlcXVlc3RzLgovLy8KLy8vICMgRXhhbXBsZXMKLy8vIGBgYAovLy8gdXNlIGFjdGl4X3dlYjo6dGVzdDo6VGVzdFJlcXVlc3Q7Ci8vLyB1c2UgYWN0aXhfd2ViX2xhYjo6dGVzdF9yZXF1ZXN0OwovLy8KLy8vIGxldCBfcmVxOiBUZXN0UmVxdWVzdCA9IHRlc3RfcmVxdWVzdCEgewovLy8gICAgIFBPU1QgIi8iOwovLy8gICAgICJPcmlnaW4iID0+ICJleGFtcGxlLmNvbSIKLy8vICAgICAiQWNjZXNzLUNvbnRyb2wtUmVxdWVzdC1NZXRob2QiID0+ICJQT1NUIgovLy8gICAgICJBY2Nlc3MtQ29udHJvbC1SZXF1ZXN0LUhlYWRlcnMiID0+ICJDb250ZW50LVR5cGUsIFgtQ1NSRnhGdXR1cmU7CnVzZSBmdXR1cmVzX3V0aWw6OkZ1dHVyZUV4dCBhcyBfOwoKLy8vIEEgbWlkZGxld2FyZSB0byBjYXRjaCBwYW5pY3MgaW4gd3JhcHBlZCBoYW5kbGVycyBhbmQgbWlkZGxld2FyZSwgcmV0dXJuaW5nIGVtcHR5IDUwMCByZXNwb25zZXMuCi8vLwovLy8gKipUaGlzIG1pZGRsZXdhcmUgc2hvdWxkIG5ldmVyIGJlIHVzZWQgYXMgcmVwbGFjZW1lbnQgZm9yIHByb3BlciBlcnJvciBoYW5kbGluZy4qKiBTZWUgW3RoaXMKLy8vIHRocmVhZF0oaHR0cHM6Ly9naXRodWIuY29tL2FjdGl4L2FjdGl4LXdlYi9pc3N1ZXMvMTUwMSNpc3N1ZWNvbW1lbnQtNjI3NTE3NzgzKSBmb3IgaGlzdG9yaWNhbAovLy8gZGlzY3Vzc2lvbiBvbiB3aHkgQWN0aXggV2ViIGRvZXMgbm90IGRvIHRoaXMgYnkgZGVmYXVsdC4KLy8vCi8vLyBJdCBpcyByZWNvbW1lbmRlZCB0aGF0IHRoaXMgbWlkZGxld2FyZSBiZSByZWdpc3RlcmVkIGxhc3QuIFRoYXQgaXMsIGB3cmFwYGVkIGFmdGVyIGV2ZXJ5dGhpbmcKLy8vIGVsc2UgZXhjZXB0IGBMb2dnZXJgLgovLy8KLy8vICMgRXhhbXBsZXMKLy8vIGBgYAovLy8gIyB1c2UgYWN0aXhfd2ViOjpBcHA7Ci8vLyB1c2UgYWN0aXhfd2ViX2xhYjo6bWlkZGxld2FyZTo6Q2F0Y2hQYW5pYzsKLy8vCi8vLyBBcHA6Om5ldygpCi8vLyAgICAgLndyYXAoQ2F0Y2hQYW5pYzo6ZGVmYXVsdCgpKQovLy8gICAgICMgOwovLy8gYGBgCi8vLwovLy8gYGBgaWdub3JlCi8vLyAvLyByZWNvbW1lbmRlZCB3cmFwIG9yZGVyCi8vLyBBcHA6Om5ldygpCi8vLyAgICAgLndyYXAoTm9ybWFsaXplUGF0aDo6ZGVmYXVsdCgpKQovLy8gICAgIC53cmFwKENhdGNoUGFuaWM6OmRlZmF1bHQoKSkgLy8gPC0gYWZ0ZXIgZXZlcnl0aGluZyBleGNlcHQgbG9nZ2VyCi8vLyAgICAgLndyYXAoTG9nZ2VyOjpkZWZhdWx0KCkpCi8vLyAgICAgIyA7Ci8vLyBgYGAKI1tkZXJpdmUoRGVidWcsIENsb25lLCBEZWZhdWx0KV0KI1tub25fZXhoYXVzdGl2ZV0KcHViIHN0cnVjdCBDYXRjaFBhbmljOwoKaW1wbDxTLCBCPiBycihlcnIpKSA9PiByZXR1cm4gUG9sbDo6UmVhZHkoRXJyKE92ZXJsb2FkZWQ6OlNlcnZpY2UoZXJyKSkpLAogICAgICAgICAgICByZXMgPT4gcmVzLmlzX3JlYWR5KCksCiAgICAgICAgfTsKCiAgICAgICAgc2VsZi5pc19yZWFkeS5zZXQoaXNfcmVhZHkpOwoKICAgICAgICAvLyBCdXQgd2UgYWx3YXlzIHJlcG9ydCBSZWFkeSwgc28gdGhhdCBsYXllcnMgYWJvdmUgZG9uJ3Qgd2FpdCB1bnRpbAogICAgICAgIC8vIHRoZSBpbm5lciBzZXJ2aWNlIGlzIHJlYWR5ICh0aGUgZW50aXJlIHBvaW50IG9mIHRoaXMgbGF5ZXIhKQogICAgICAgIFBvbGw6OlJlYWR5KE9rKCgpKSkKICAgIH0KCiAgICBmbiBjYWxsKCZzZWxmLCByZXE6IFJlcSkgLT4gU2VsZjo6RnV0dXJlIHsKICAgICAgICBpZiBzZWxmLmlzX3JlYWR5LmdldCgpIHsKICAgICAgICAgICAgLy8gcmVhZGluZXNzIG9ubHkgY291bnRzIG9uY2UsIHlvdSBuZWVkIHRvIGNoZWNrIGFnYWluIQogICAgICAgICAgICBzZWxmLmlzX3JlYWR5LnNldChmYWxzZSk7CiAgICAgICAgICAgIExvYWRTaGVkRnV0dXJlOjpjYWxsZWQoc2VsZi5pbm5lci5jYWxsKHJlcSkpCiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgTG9hZFNoZWRGdXR1cmU6Om92ZXJsb2FkZWQoKQogICAgICAgIH0KICAgIH0KfQoKcGluX3Byb2plY3QhIHsKICAgIC8vLyBGdXR1cmUgZm9yIFtgTG9hZFNoZWRTZXJ2aWNlYF0uCiAgICBwdWIgc3RydWN0IExvYWRTaGVkRnV0dXJlPEY+IHsKICAgICAgICAjW3Bpbl0KICAgICAgICBzdGF0ZTogTG9hZFNoZWRGdXR1cmVTdGF0ZTxGPiwKICAgIH0KfQoKcGluX3Byb2plY3QhIHsKICAgICNbcHJvamVjdCA9IExvYWRTaGVkRnV0dXJlU3RhdGVQcm9qXQogICAgZW51bSBMb2FkU2hlZEZ1dHVyZVN0YXRlPEY+IHsKICAgICAgICBDYWxsZWQgeyAjW3Bpbl0gZnV0OiBGIH0sCiAgICAgICAgT3ZlcmxvYWRlZCwKICAgIH0KfQoKaW1wbDxGPiBMb2FkU2hlZEZ1dHVyZTxGPiB7CiAgICBwdWIoY3JhdGUpIGZuIGNhbGxlZChmdXQ6IEYpIC0+IFNlOkJsYWtlMnMyNTYsICJibGFrZTIiLCAiQmxha2UycyIsIDMyKTsKCi8vIEJsYWtlMwpib2R5X2hhc2hfYWxpYXMhKEJvZHlCbGFrZTMsIGJsYWtlMzo6SGFzaGVyLCAiYmxha2UzIiwgIkJsYWtlMyIsIDMyKTsKLy8hIERlbW9uc3RyYXRlcyBmb3JraW5nIGEgcmVxdWVzdCBwYXlsb2FkIHNvIHRoYXQgbXVsdGlwbGUgZXh0cmFjdG9ycyBjYW4gZGVyaXZlIGRhdGEgZnJvbSBhIGJvZHkuCi8vIQovLyEgYGBgc2gKLy8hIGN1cmwgLVggUE9TVCBsb2NhbGhvc3Q6ODA4MC8gLWQgJ2ZvbycKLy8hCi8vISAjIG9yIHVzaW5nIEhUVFBpZQovLyEgaHR0cCBQT1NUIDo4MDgwLyAtLXJhdyBmb28KLy8hIGBgYAoKdXNlIHN0ZDo6aW87Cgp1c2UgYWN0aXhfd2ViOjp7ZGV2LCBtaWRkbGV3YXJlLCB3ZWIsIEFwcCwgRnJvbVJlcXVlc3QsIEh0dHBSZXF1ZXN0LCBIdHRwU2VydmVyfTsKdXNlIGFjdGl4X3dlYl9sYWI6OnV0aWw6OmZvcmtfcmVxdWVzdF9wYXlsb2FkOwp1c2UgZnV0dXJlc191dGlsOjp7ZnV0dXJlOjpMb2NhbEJveEZ1dHVyZSwgVHJ5RnV0dXJlRXh0IGFzIF99Owp1c2UgdG9raW86OnRyeV9qb2luOwp1c2UgdHJhY2luZzo6aW5mbzsKCnN0cnVjdCBUd29Cb2RpZXM8VCwgVT4oVCwgVSk7CgppbXBsPFQsIFU+IFR3b0JvZGllczxULCBVPiB7CiAgICBmbiBpbnRvX3BhcnRzKHNlbGYpIC0+IChULCBVKSB7CiAgICAgICAgKHNlbGYuMCwgc2VsZi4xKQogICAgfQp9CgppbXBsPFQsIFU+IEZyb21SZXF1ZXN0IGZvciBUd29Cb2RpZXM8VCwgVT4Kd2hlcmUKICAgIFQ6IEZyb21SZXF1ZXN0LAogICAgVDo6RnV0dXJlOiAnc3RhdGljLAogICAgVTogRnJvbVJlcXVlc3QsCiAgICBVOjpGdXR1cmU6ICdzdGF0aWMsCnsKICAgIHR5cGUgRXJyb3IgPSBhY3RpeF93ZWI6OkVycm9yOwogICAgdHlwZSBGdXR1cmUgPSBMb2NhbEJveEZ1dHVyZTwnc3RhdGljLCBSZXN1bHQ8U2VsZiwgU2VsZjo6RXJyb3I+PjsKCiAgICBmbiBmcm9tX3JlcXVlc3QocmVxOiAmSHR0cFJlcXVlc3QsIHBsOiAmbXV0IGRldjo6UGF5bG9hZC8vLy9zb21ldGhpbmc/cXVlcnk9dGVzdCIsCiAgICAgICAgXTsKCiAgICAgICAgZm9yIHVyaSBpbiB0ZXN0X3VyaXMgewogICAgICAgICAgICBsZXQgcmVxID0gVGVzdFJlcXVlc3Q6OndpdGhfdXJpKHVyaSkudG9fcmVxdWVzdCgpOwogICAgICAgICAgICBsZXQgcmVzID0gY2FsbF9zZXJ2aWNlKCZhcHAsIHJlcSkuYXdhaXQ7CiAgICAgICAgICAgIGFzc2VydCEocmVzLnN0YXR1cygpLmlzX3N1Y2Nlc3MoKSwgIkZhaWxlZCB1cmk6IHt1cml9Iik7CiAgICAgICAgfQogICAgfQoKICAgICNbYWN0aXhfd2ViOjp0ZXN0XQogICAgYXN5bmMgZm4gYWx3YXlzX3RyYWlsaW5nX3NsYXNoZXMoKSB7CiAgICAgICAgbGV0IGFwcCA9IGluaXRfc2VydmljZSgKICAgICAgICAgICAgQXBwOjpuZXcoKQogICAgICAgICAgICAgICAgLndyYXAoTm9ybWFsaXplUGF0aDo6bmV3KFRyYWlsaW5nU2xhc2g6OkFsd2F5cykpCiAgICAgICAgICAgICAgICAuc2VydmljZSh3ZWI6OnJlc291cmNlKCIvIikudG8oSHR0cFJlc3BvbnNlOjpPaykpCiAgICAgICAgICAgICAgICAuc2VydmljZSh3ZWI6OnJlc291cmNlKCIvdjEvc29tZXRoaW5nLyIpLnRvKEh0dHBSZXNwb25zZTo6T2spKQogICAgICAgICAgICAgICAgLnNlcnZpY2UoCiAgICAgICAgICAgICAgICAgICAgd2ViOjpyZXNvdXJjZSgiL3YyL3NvbWV0aGluZy8iKQogICAgICAgICAgICAgICAgICAgICAgICAuZ3VhcmQoZm5fZ3VhcmQofGN0eHwgY3R4LmhlYWQoKS51cmkucXVlcnkoKSA9PSBTb21lKCJxdWVyeT10ZXN0IikpKQogICAgICAgICAgICAgICAgICAgICAgICAudG8oSHR0cFJlc3BvbnNlOjpPayksCiAgICAgICAgICAgICAgICApLAogICAgICAgICkKICAgICAgICAuYXdhaXQ7CgogICAgICAgIGxldCB0ZXN0X3VyaXMgPSB2ZWMhWwogICAgICAgICAgICAiLyIsCiAgICAgICAgICAgICIvLy8iLAogICAgICAgICAgICAiL3YxL3NvbWV0aGluZyIsCiAgICAgICAgICAgICIvdjEvc29tZXRoaW5nLyIsCiAgICAgICAgICAgICIvdjEvc29tZXRoaW5nLy8vLyIsCiBoYCBtaWRkbGV3YXJlIHdpdGggdGhlIHNwZWNpZmllZCB0cmFpbGluZyBzbGFzaCBzdHlsZS4KICAgIHB1YiBmbiBuZXcoYmVoYXZpb3I6IFRyYWlsaW5nU2xhc2gpIC0+IFNlbGYgewogICAgICAgIFNlbGYgewogICAgICAgICAgICB0cmFpbGluZ19zbGFzaF9iZWhhdmlvcjogYmVoYXZpb3IsCiAgICAgICAgICAgIHVzZV9yZWRpcmVjdHM6IE5vbmUsCiAgICAgICAgfQogICAgfQoKICAgIC8vLyBDb25zdHJ1Y3RzIGEgbmV3IGBOb3JtYWxpemVQYXRoYCBtaWRkbGV3YXJlIHdpdGggW3RyaW1dKFRyYWlsaW5nU2xhc2g6OlRyaW0pIHNlbWFudGljcy4KICAgIC8vLwogICAgLy8vIFVzZSB0aGlzIGluc3RlYWQgb2YgYE5vcm1hbGl6ZVBhdGg6OmRlZmF1bHQoKWAgdG8gYXZvaWQgZGVwcmVjYXRpb24gd2FybmluZy4KICAgIHB1YiBmbiB0cmltKCkgLT4gU2VsZiB7CiAgICAgICAgU2VsZjo6bmV3KFRyYWlsaW5nU2xhc2g6OlRyaW0pCiAgICB9CgogICAgLy8vIENvbmZpZ3VyZXMgbWlkZGxld2FyZSB0byByZXNwb25kIHRvIHJlcXVlc3RzIHdpdGggbm9uLW5vcm1hbGl6ZWQgcGF0aHMgd2l0aCBhIDMwNyByZWRpcmVjdC4KICAgIC8vLwogICAgLy8vIElmIGNvbmZpZ3VyZWQKICAgIC8vLwogICAgLy8vIEZvciBleGFtcGxlLCBhIHJlcXVlc3Qgd2l0aCB0aGUgcGF0aCBgL2FwaS8vdjEvZm9vL2Agd291bGQgcmVjZWl2ZSBhIHJlc3BvbnNlIHdpdGggYQogICAgLy8vIGBMb2NhdGlvbjogL2FwaS92MS9mb29gIGhlYWRlciAoYXNzdW1pbmcgYFRyaW1gIHRyYWlsaW5nIHNsYXNoIGJlaGF2aW9yLikKICAgIC8vLwogICAgLy8vIFRvIGN1c3RvbWl6ZSB0aGUgc3RhdHVzIGNvZGUsIHVzZSBbYHVzZV9yZWRpcmVjdHNfd2l0aGBdKFNlbGY6OnVzZV9yZWRpcmVjdHNfd2l0aCkuCiAgICBwdWIgZm4gdXNlX3JlZGlyZWN0cyhtdXQgc2VsZikgLT4gU2VsZiB7CiAgICAgICAgc2VsZi51c2VfcmVkaXJlY3RzID0gU29tZShTdGF0dXNDb2RlOjpURU1QT1JBUllfUkVESVJFQ1QpOwogICAgICAgIHNlbGYKICAgIH0KICAgICAgIC5ib2R5KCJIZWxsbyBXb3JsZCEiKSwKLy8vICk7Ci8vLwovLy8gYXNzZXJ0X3Jlc3BvbnNlX21hdGNoZXMhKHJlcywgQ1JFQVRFRDsKLy8vICAgICAiZGF0ZSIgPT4gInRvZGF5IgovLy8gICAgICJzZXQtY29va2llIiA9PiAiYT1iIjsKLy8vICAgICBAcmF3ICJIZWxsbyBXb3JsZCEiCi8vLyApOwovLy8KLy8vIGxldCByZXMgPSBTZXJ2aWNlUmVzcG9uc2U6Om5ldygKLy8vICAgICBUZXN0UmVxdWVzdDo6ZGVmYXVsdCgpLnRvX2h0dHBfcmVxdWVzdCgpLAovLy8gICAgIEh0dHBSZXNwb25zZTo6Q3JlYXRlZCgpCi8vLyAgICAgICAgIC5jb250ZW50X3R5cGUoQ29udGVudFR5cGU6Ompzb24oKSkKLy8vICAgICAgICAgLmluc2VydF9oZWFkZXIoKCJkYXRlIiwgInRvZGF5IikpCi8vLyAgICAgICAgIC5pbnNlcnRfaGVhZGVyKCgic2V0LWNvb2tpZSIsICJhPWIiKSkKLy8vICAgICAgICAgLmJvZHkociMieyJhYmMiOiIxMjMifSIjKSwKLy8vICk7Ci8vLwovLy8gYXNzZXJ0X3Jlc3BvbnNlX21hdGNoZXMhKHJlcywgQ1JFQVRFRDsgQGpzb24geyAiYWJjIjogIjEyMyIgfSk7Ci8vLyAjIH0pOwovLy8gYGBgCiNbbWFjcm9fZXhwb3J0XQptYWNyb19ydWxlcyEgYXNzZXJ0X3Jlc3BvbnNlX21hdGNoZXMgewogICAgKCRyZXM6aWRlbnQsICRzdGF0dXM6aWRlbnQpID0+IHt7CiAgICAgICAgYXNzZXJ0X2VxISgkcmVzLnN0YXR1cygpLCA6OmFjdGl4X3dlYjo6aHR0cDo6U3RhdHVzQ29kZTo6JHN0YXR1cykKICAgIH19OwoKICAgICgkcmVzOmlkZW50LCAkc3RhdHVzOmlkZW50OyAkKCRoZHJfbmFtZTpleHByID0+ICRoZHJfdmFsOmV4cHIpKykgPT4ge3sKICAgICAgICBhc3NlcnRfcmVzcG9uc2VfbWF0Y2hlcyEoJHJlcywgJHN0YXR1cyk7CgogICAgICAgICQoCiAgICAgICAgICAgIGFzc2VydF9lcSEoCiAgICAgICAgICAgICAgICAkcmVzLmhlYWRlcnMoKS5nZXQoOjphY3RpeF93ZWI6Omh0dHA6OmhlYWRlcjo6SGVhZGVyTmFtZTo6ZnJvbV9zdGF0aWMoJGhkcl9uYW1lKSkudW53cmFwKCksCiAgICAgIGFzc2VydF9lcSEoCiAgICAgICAgICAgIEV2ZW50OjpEYXRhKERhdGEgewogICAgICAgICAgICAgICAgaWQ6IFNvbWUoIjQyIi5pbnRvKCkpLAogICAgICAgICAgICAgICAgZXZlbnQ6IFNvbWUoImJhciIuaW50bygpKSwKICAgICAgICAgICAgICAgIGRhdGE6ICJmb28iLmludG8oKQogICAgICAgICAgICB9KQogICAgICAgICAgICAuaW50b19ieXRlcygpLAogICAgICAgICAgICAiaWQ6IDQyXG5ldmVudDogYmFyXG5kYXRhOiBmb29cblxuIgogICAgICAgICk7CiAgICB9CgogICAgI1t0ZXN0XQogICAgZm4gcmV0cnlfaXNfZmlyc3RfbXNnKCkgewogICAgICAgIGxldCB3YWtlciA9IG5vb3Bfd2FrZXIoKTsKICAgICAgICBsZXQgbXV0IGN4ID0gQ29udGV4dDo6ZnJvbV93YWtlcigmd2FrZXIpOwoKICAgICAgICB7CiAgICAgICAgICAgIGxldCAoX3NlbmRlciwgbXV0IHNzZSkgPSBjaGFubmVsKDkpOwogICAgICAgICAgICBhc3NlcnQhKFBpbjo6bmV3KCZtdXQgc3NlKS5wb2xsX25leHQoJm11dCBjeCkuaXNfcGVuZGluZygpKTsKICAgICAgICB9CgogICAgICAgIHsKICAgICAgICAgICAgbGV0IChfc2VuZGVyLCBzc2UpID0gY2hhbm5lbCg5KTsKICAgICAgICAgICAgbGV0IG11dCBzc2UgPSBzc2Uud2l0aF9yZXRyeV9kdXJhdGlvbihEdXJhdGlvbjo6ZnJvbV9taWxsaXMoNDIpKTsKICAgICAgICAgICAgbWF0Y2ggUGluOjpuZXcoJm11dCBzc2UpLnBvbGxfbmV4dCgmbXV0IGN4KSB7CiAgICAgICAgICAgICAgICBQb2xsOjpSZWFkeShTb21lKE9rKGJ5dGVzKSkpID0+IGFzc2VydF9lcSEoYnl0ZXMsICJyZXRyeTogNDJcblxuIiksCiAgICAgICAgICAgICAgICByZXMgPT4gcGFuaWMhKCJwb2xsIHNob3VsZCByZXR1cm4gcmV0cnkgbWVzc2FnZSwgZ290IHtyZXM6P30iKSwKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0KCiAgICAjW2FjdGl4X3dlYjo6dGVzdF0KICAgIGFzeW5jIGZuIGRyb3BwaW5nX3Jlc3BvbmRlcl9jYXVzZXNfc2VuZF9mYWlscygpIHsKICAgICAgICBsZXQgKHNlbmRlciwoc291cmNlKSldIEV2ZW50KSwKCiAgICAvLy8gVGhlIHJlY2VpdmluZyAoW2BTc2VgXSkgaGFzIGJlZW4gZHJvcHBlZCwgbGlrZWx5IGJlY2F1c2UgdGhlIGNsaWVudCBkaXNjb25uZWN0ZWQuCiAgICAjW2Rpc3BsYXkoZm10ID0gImNoYW5uZWwgY2xvc2VkIildCiAgICBDbG9zZWQoI1tlcnJvcihub3Qoc291cmNlKSldIEV2ZW50KSwKfQoKI1tkb2MoaGlkZGVuKV0KI1tkZXByZWNhdGVkKAogICAgc2luY2UgPSAiMC4xNy4wIiwKICAgIG5vdGUgPSAiUmVuYW1lZCB0byBgVHJ5U2VuZEVycm9yYC4gUHJlZmVyIGBzc2U6OlRyeVNlbmRFcnJvcmAuIgopXQpwdWIgdHlwZSBTc2VUcnlTZW5kRXJyb3IgPSBUcnlTZW5kRXJyb3I7CgovLy8gU2VydmVyLXNlbnQgZXZlbnRzIGRhdGEgbWVzc2FnZSBjb250YWluaW5nIGEgYGRhdGFgIGZpZWxkIGFuZCBvcHRpb25hbCBgaWRgIGFuZCBgZXZlbnRgIGZpZWxkcy4KLy8vCi8vLyBTaW5jZSBpdCBpbXBsZW1lbnRzIGBJbnRvPFNzZU1lc3NhZ2U+YCwgdGhpcyBjYW4gYmUgcGFzc2VkIGRpcmVjdGx5IHRvIFtgc2VuZGBdKFNzZVNlbmRlcjo6c2VuZCkKLy8vIG9yIFtgdHJ5X3NlbmRgXShTc2VTZW5kZXI6OnRyeV9zZW5kKS4KLy8vCi8vLyAjIEV4YW1wbGVzCi8vLyBgYGAKLy8vICMgI1thY3RpeF93ZWI6Om1haW5dIGFzeW5jIGZuIHRlc3QoKSB7Ci8vLyB1c2Ugc3RkOjpjb252ZXJ0OjpJbmZhbGxpYmxlOwovLy8gdXNlIGFjdGl4X3dlYjo6Ym9keTsKLy8vIHVzZSBzZXJkZTo6U2VyaWFsaXplOwovLy8gdXNlIGZ1dHVyZXNfdXRpbDo6c3RyZWFtOwovLy8gdXNlIGFjdGl4X3dlYl9sYWI6OnNzZTsKLy8vCi8vLyAjW2Rlcml2ZShzZXJkZTo6U2VyaWFsaXplKV0KLy8vIHN0cnVjdCBGb28gewovLy8gICAgIGJhcjogdTMyLAovLy8gfQovLy8KLy8vIGxldCBzc2UgPSBzc2U6OlNzZTo6ZnJvbV9zdHJlYW0oc3RyZWFtOjppdGVyKFsKLy8vICAgICBPazo6PF8sIEluZmFsbGlibGU+KHNzZTo6RXZlbnQ6OkRhdGEoc3NlOjpEYXRhOjpuZXcoImZvbyIpKSksCi8vLyAgICAgICAuYXBwX2RhdGEod2ViOjpEYXRhOjpuZXcoNDJ1MzIpKQogICAgICAgICAgICAuZGVmYXVsdF9zZXJ2aWNlKHdlYjo6dG8oaGFuZGxlcikpCiAgICB9KTsKCiAgICBsZXQgcmVzID0gc3J2LnBvc3QoIi8iKS5zZW5kX2JvZHkoImZvbyIpLmF3YWl0LnVud3JhcCgpOwogICAgYXNzZXJ0X2VxIShyZXMuc3RhdHVzKCksIFN0YXR1c0NvZGU6Ok9LKTsKfQovLyEgQWx0ZXJuYXRpdmUgYXBwcm9hY2ggdG8gdXNpbmcgYEJvZHlIbWFjYCB0eXBlIHVzaW5nIG1vcmUgZmxleGlibGUgYFJlcXVlc3RTaWduYXR1cmVgIHR5cGUuCgp1c2Ugc3RkOjppbzsKCnVzZSBhY3RpeF93ZWI6OnsKICAgIG1pZGRsZXdhcmU6OkxvZ2dlciwKICAgIHdlYjo6e3NlbGYsIEJ5dGVzLCBEYXRhfSwKICAgIEFwcCwgRXJyb3IsIEZyb21SZXF1ZXN0LCBIdHRwUmVxdWVzdCwgSHR0cFNlcnZlciwKfTsKdXNlIGFjdGl4X3dlYl9sYWI6OmV4dHJhY3Q6OntSZXF1ZXN0U2lnbmF0dXJlLCBSZXF1ZXN0U2lnbmF0dXJlU2NoZW1lfTsKdXNlIGFzeW5jX3RyYWl0Ojphc3luY190cmFpdDsKdXNlIGRpZ2VzdDo6e0N0T3V0cHV0LCBNYWN9Owp1c2UgaG1hYzo6U2ltcGxlSG1hYzsKdXNlIHNoYTI6OlNoYTI1NjsKdXNlIHRyYWNpbmc6OmluZm87CgpzdHJ1Y3QgQWJjU2lnbmluZ0tleShbdTg7IDMyXSk7CgovLy8gR3JhYnMgdmFyaWFibGUgc2lnbmluZyBrZXkgZnJvbSBhcHAgZGF0YS4KYXN5bmMgZm4gZ2V0X3NpZ25pbmdfa2V5PEtleT4ocmVxOiAmSHR0cFJlcXVlc3QpIC0+IGFjdGl4X3dlYjo6UmVzdWx0PFt1ODsgMzJdPiB7CiAgICBsZXQga2V5ID0gRGF0YTo6PEFiY1NpZ25pbmdLZXk+OjpleHRyYWN0KHJlcSkuaW50b19pbm5lcigpPy4wOwogICAgT2soa2V5KQp9CgojW2Rlcml2ZShEZWJ1ZyldCnN0cnVjdCBBYmNBcGkgewogICAgLy8vIFBheWxvYWQgaGFzaCBzdGF0ZS4KICAgIGhtYWM6IFNpbXBsZUhtYWM8U2hhMjU2PiwKfQoKI1thc3luY190cmFpdCg/U2VuZCldCmltcGwgUmVxdWVzdFNpZ25hdHVyZVNjaGVtZSBmb3IgQW9keX0sCi8vLyAgICAgd2ViOjp7QnVmTXV0IGFzIF8sIEJ5dGVzTXV0fSwKLy8vICAgICBIdHRwUmVxdWVzdCwKLy8vIH07Ci8vLwovLy8gYXN5bmMgZm4gYXBwZW5kX2J5dGVzKAovLy8gICAgIF9yZXE6IEh0dHBSZXF1ZXN0LAovLy8gICAgIGJvZHk6IGltcGwgTWVzc2FnZUJvZHkKLy8vICkgLT4gYWN0aXhfd2ViOjpSZXN1bHQ8aW1wbCBNZXNzYWdlQm9keT4gewovLy8gICAgIGxldCBidWYgPSBib2R5Ojp0b19ieXRlcyhib2R5KS5hd2FpdC5vaygpLnVud3JhcCgpOwovLy8KLy8vICAgICBsZXQgbXV0IGJvZHkgPSBCeXRlc011dDo6ZnJvbSgmYnVmWy4uXSk7Ci8vLyAgICAgYm9keS5wdXRfc2xpY2UoYiIgLSBob3BlIHlvdSBsaWtlIHRoaW5ncyBydWluaW5nIHlvdXIgcGF5bG9hZCBmb3JtYXQiKTsKLy8vCi8vLyAgICAgT2soYm9keSkKLy8vIH0KLy8vICMgYWN0aXhfd2ViOjpBcHA6Om5ldygpLndyYXAobWFwX3Jlc3BvbnNlX2JvZHkoYXBwZW5kX2J5dGVzKSk7Ci8vLyBgYGAKcHViIGZuIG1hcF9yZXNwb25zZV9ib2R5PEY+KG1hcHBlcl9mbjogRikgLT4gTWFwUmVzQm9keU1pZGRsZXdhcmU8Rj4gewogICAgTWFwUmVzQm9keU1pZGRsZXdhcmUgewogICAgICAgIG13X2ZuOiBSYzo6bmV3KG1hcHBlcl9mbiksCiAgICB9Cn0KCi8vLyBNaWRkbGV3YXJlIHRyYW5zZm9ybSBmb3IgW2BtYXBfcmVzcG9uc2VfYm9keWBdLgpwdWIgc3RydWN0IE1hcFJlc0JvZHlNaWRkbGV3YXJlPEY+IHsKICAgIG13X2ZuOiBSYzxGPiwKfQoKaW1wbDxTLCBGLCBGdXQsIEIsIEIyPiBUcmFuc2Zvcm08UywgU2VydmljZVJlcXVlc3Q+IGZvciBNYXBSZXNCb2R5TWlkZGxld2FyZTxGPgp3aGVyZQogICAgUzogU2VydmljZTxTZXJ2aWNlUmVxdWVzdCwgUmVzcG9uc2UgPSBTZXJ2aWNlUmVzcG9uc2U8Qj4sIEVycm9yID0gRXJyb3I+LAogICAgRjogRm4oSHR0cFJlcXVlc3QsIEIpIC0+IEZ1dCwKICAgIEZ1dDogRnV0dXJlPE91dHB1dCA9IFJlc3VsdDxCMiwgRXJyb3I+PiwKICAgIEIyOiBNZXNzYWdlQm9keSwKewogICB0YWlucygiSlNPTiBwYXlsb2FkICgxNiBieXRlcykgaXMgbGFyZ2VyIHRoYW4gYWxsb3dlZCAobGltaXQ6IDEwIGJ5dGVzKS4iKSwKICAgICAgICAgICAgInVuZXhwZWN0ZWQgZXJyb3Igc3RyaW5nOiB7ZXJyOj99IgogICAgICAgICk7CgogICAgICAgIGxldCAocmVxLCBtdXQgcGwpID0gVGVzdFJlcXVlc3Q6OmRlZmF1bHQoKQogICAgICAgICAgICAuaW5zZXJ0X2hlYWRlcihoZWFkZXI6OkNvbnRlbnRUeXBlOjpqc29uKCkpCiAgICAgICAgICAgIC5pbnNlcnRfaGVhZGVyKCgKICAgICAgICAgICAgICAgIGhlYWRlcjo6Q09OVEVOVF9MRU5HVEgsCiAgICAgICAgICAgICAgICBoZWFkZXI6OkhlYWRlclZhbHVlOjpmcm9tX3N0YXRpYygiMTYiKSwKICAgICAgICAgICAgKSkKICAgICAgICAgICAgLnNldF9wYXlsb2FkKEJ5dGVzOjpmcm9tX3N0YXRpYyhiIntcIm5hbWVcIjogXCJ0ZXN0XCJ9IikpCiAgICAgICAgICAgIC50b19odHRwX3BhcnRzKCk7CiAgICAgICAgbGV0IHMgPSBKc29uOjo8TXlPYmplY3QsIDEwPjo6ZnJvbV9yZXF1ZXN0KCZyZXEsICZtdXQgcGwpLmF3YWl0OwogICAgICAgIGxldCBlcnIgPSBmb3JtYXQhKCJ7fSIsIHMudW53cmFwX2VycigpKTsKICAgICAgICBhc3NlcnQhKAogICAgICAgICAgICBlcnIuY29udGFpbnMoImxhcmdlciB0aGFuIGFsbG93ZWQiKSwKICAgICAgICAgICAgInVuZXhwZWN0ZWQgZXJyb3Igc3RyaW5nOiB7ZXJyOj99IgogICAgICAgICk7CiAgICB9CgogICAgI1thY3RpeF93ZWI6OnRlc3RdCiAgICBhc3luYyBmbiB0ZXN0X2pzb25fYm9keSgpIHsKICAgICAgICBsZXQgKHJlcSwgbXV0IHBsKSA9IFRlc3RSZXF1ZXN0OjpkZWZhdWx0KCkudG9faHR0cF9wYXJ0cygpOwogICAgICAgIGxldCBqc29uID0gSnNvbkJvZHk6OjxNeU9iamVjdCwgREVGQVVMVF9KU09OX0xJTUlUPjo6bmV3KCZyZXEsICZtdXQgcGwpLmF3YWl0OwogICAgICAgIGFzc2VydCEoanNvbl9lcShqc29uLnVud3JhcF9lcnIoKSwgSnNvblBheWxvYWRFcnJvcjo6Q29udGVudFR5cGUpKTsKCiAgemVPd25lZDsKdXNlIHRyYWNpbmc6OmRlYnVnOwoKLy8vIERlZmF1bHQgSlNPTiBwYXlsb2FkIHNpemUgbGltaXQgb2YgMk1pQi4KcHViIGNvbnN0IERFRkFVTFRfSlNPTl9MSU1JVDogdXNpemUgPSAyXzA5N18xNTI7CgovLy8gSlNPTiBleHRyYWN0b3Igd2l0aCBjb25zdC1nZW5lcmljIHBheWxvYWQgc2l6ZSBsaW1pdC4KLy8vCi8vLyBgSnNvbmAgaXMgdXNlZCB0byBleHRyYWN0IHR5cGVkIGRhdGEgZnJvbSBKU09OIHJlcXVlc3QgcGF5bG9hZHMuCi8vLwovLy8gIyBFeHRyYWN0b3IKLy8vIFRvIGV4dHJhY3QgdHlwZWQgZGF0YSBmcm9tIGEgcmVxdWVzdCBib2R5LCB0aGUgaW5uZXIgdHlwZSBgVGAgbXVzdCBpbXBsZW1lbnQgdGhlCi8vLyBbYHNlcmRlOjpEZXNlcmlhbGl6ZWBdIHRyYWl0LgovLy8KLy8vIFVzZSB0aGUgYExJTUlUYCBjb25zdCBnZW5lcmljIHBhcmFtZXRlciB0byBjb250cm9sIHRoZSBwYXlsb2FkIHNpemUgbGltaXQuIFRoZSBkZWZhdWx0IGxpbWl0Ci8vLyB0aGF0IGlzIGV4cG9ydGVkIChgREVGQVVMVF9MSU1JVGApIGlzIDJNaUIuCi8vLwovLy8gYGBgCi8vLyB1c2UgYWN0aXhfd2ViOjp7cG9zdCwgQXBwfTsKLy8vIHVzZSBhY3RpeF93ZWJfbGFiOjpleHRyYWN0Ojp7REVGQVVMVF9KU09OX0xJTUlULCBKc29ufTsKLy8vIHVzZSBzZXJkZTo6RGVzZXJpYWxpemU7Ci8vLwovLy8gI1tkZXJpdmUoRGVzZXJpYWxpemUpXQovLy8gc3RydWN0IEluZm8gewovLy8gICAgIHVzZXJuYW1lOiBTdHJpbmcsCi8vLyB9Ci8vLwovLy8gLy8vIERlc2VyaWFsaXplIGBJbmZvYCBmcm9tIHJlcXVlc3QncyBib2R5LgovLy8gI1twb3N0KCIvIildCi8vLyBhc3luYyBmbiBpbmRleChpbmZvOiBKc29uPEluZm8+KSAtPiBTdHJpbmcgewovLy8gICAgIGZvcm1hdCEoIldlbGNvbWUge30hIiwgaW5mby51c2VybmFtZSkKLy8vIH0KLy8vCi8vLyBjb25zdCBMSU1JVF8zMl9NQjogdXNpemUgPSAzM181NTRfNDMyOwovLy8KLy8vIC8vLyBEZXNlcmlhbGl6ZSBwYXlsb2FkIHdpdGggYSBoaWdoZXIgMzJNaSAgIC8vLyBhc3luYyBmbiBoYW5kbGVyKCkgLT4gaW1wbCBSZXNwb25kZXIgewogICAgLy8vICAgICBsZXQgZGF0YV9zdHJlYW0gPSBzdHJlYW1pbmdfZGF0YV9zb3VyY2UoKTsKICAgIC8vLwogICAgLy8vICAgICBEaXNwbGF5U3RyZWFtOjpuZXdfaW5mYWxsaWJsZShkYXRhX3N0cmVhbSkKICAgIC8vLyAgICAgICAgIC5pbnRvX3Jlc3BvbmRlcigpCiAgICAvLy8gfQogICAgLy8vIGBgYAogICAgcHViIHN0cnVjdCBEaXNwbGF5U3RyZWFtPFM+IHsKICAgICAgICAvLyBUaGUgd3JhcHBlZCBpdGVtIHN0cmVhbS4KICAgICAgICAjW3Bpbl0KICAgICAgICBzdHJlYW06IFMsCiAgICB9Cn0KCmltcGw8Uz4gRGlzcGxheVN0cmVhbTxTPiB7CiAgICAvLy8gQ29uc3RydWN0cyBhIG5ldyBgRGlzcGxheVN0cmVhbWAgZnJvbSBhIHN0cmVhbSBvZiBsaW5lcy4KICAgIHB1YiBmbiBuZXcoc3RyZWFtOiBTKSAtPiBTZWxmIHsKICAgICAgICBTZWxmIHsgc3RyZWFtIH0KICAgIH0KfQoKaW1wbDxTPiBEaXNwbGF5U3RyZWFtPFM+IHsKICAgIC8vLyBDb25zdHJ1Y3RzIGEgbmV3IGBEaXNwbGF5U3RyZWFtYCBmcm9tIGFuIGluZmFsbGlibGUgc3RyZWFtIG9mIGxpbmVzLgogICAgcHViIGZuIG5ld19pbmZhbGxpYmxlKHN0cmVhbTogUykgLT4gRGlzcGxheVN0cmVhbTxJbmZhbGxpYmxlU3RyZWFtPFM+PiB7CiAgICAgICAgRGlzcGxheVN0cmVhbTo6bmV3KEluZmFsbGlibGVTdHJlYW06Om5ldyhzdHJlYW0pKQogICAgfQp9CgppbXBsPFMsIFQsIEU+IERpc3BsYXlTdHJlYW08Uz4Kd2hlcmUKICAgIFM6IFN0cmVhbTxJdGVtID0gUmVzdWx0PFQsIEU+PiwKICAgIFQ6IGZtdDo6RGlzcGxheSwKICAgIEU6IEludG88Qm94PGR5biBTdGRFcnJvcj4+ICsgJ3N0YXRpYywKewogICAgLy8vIENyZWF0ZXMgYSBjaHVua2VkIGJvZHkgc3RyZWFtIHRoYXQgc2VyaWFsaXplcyBhcyBDU1Ygb24tdGhlLWZseS4KICAgIHB1YiBmbiBpbnRvX2JvZHlfc3RyZWFtKHNlbGYpIC0+IGltcGwgTWVzc2FnZUJvZHkgewogICAgICAgIEJvZHlTdHIKICAgICNbdGVzdF0KICAgIGZuIGZvcl9tdWx0aXBsZSgpIHsKICAgICAgICBsZXQgZndkID0gRm9yd2FyZGVkIHsKICAgICAgICAgICAgciNmb3I6IHZlYyFbIjE5Mi4wLjIuNjAiLnRvX293bmVkKCksICIxOTguNTEuMTAwLjE3Ii50b19vd25lZCgpXSwKICAgICAgICAgICAgLi5Gb3J3YXJkZWQ6OmRlZmF1bHQoKQogICAgICAgIH07CgogICAgICAgIGFzc2VydF9lcSEoZndkLmZvcl9jbGllbnQoKS51bndyYXAoKSwgIjE5Mi4wLjIuNjAiKTsKCiAgICAgICAgYXNzZXJ0X3BhcnNlX2VxOjo8Rm9yd2FyZGVkLCBfLCBfPihbImZvcj0xOTIuMC4yLjYwLCBmb3I9MTk4LjUxLjEwMC4xNyJdLCBmd2QpOwogICAgfQp9Ci8vISBFeHBpcmVtZW50YWwgcmVzcG9uZGVycyBhbmQgcmVzcG9uc2UgaGVscGVycy4KCnB1YiB1c2UgY3JhdGU6Ontjc3Y6OkNzdiwgZGlzcGxheV9zdHJlYW06OkRpc3BsYXlTdHJlYW0sIGh0bWw6Okh0bWwsIG5kanNvbjo6TmRKc29ufTsKCiNbY2ZnKGZlYXR1cmUgPSAiY2JvciIpXQpwdWIgdXNlIGNyYXRlOjpjYm9yOjpDYm9yOwoKI1tjZmcoZmVhdHVyZSA9ICJtc2dwYWNrIildCnB1YiB1c2UgY3JhdGU6Om1zZ3BhY2s6OntNZXNzYWdlUGFjaywgTWVzc2FnZVBhY2tOYW1lZH07Ci8vISBDb250ZW50LUxlbmd0aCB0eXBlZCBoZWFkZXIuCi8vIQovLyEgU2VlIFtgQ29udGVudExlbmd0aGBdIGRvY3MuCgp1c2Ugc3RkOjp7Y29udmVydDo6SW5mYWxsaWJsZSwgc3RyfTsKCnVzZSBhY3RpeF93ZWI6OnsKICAgIGVycm9yOjpQYXJzZUVycm9yLAogICAgaHR0cDo6aGVhZGVyOjp7CiAgICAgICAgZnJvbV9vbmVfcmF3X3N0ciwgSGVhZGVyLCBIZWFkZXJOYW1lLCBIZWFkZXJWYWx1ZSwgVHJ5SW50b0hlYWRlclZhbHVlLCBDT05URU5UX0xFTkdUSCwKICAgIH0sCiAgICBIdHRwTWVzc2FnZSwKfTsKCi8vLyBgQ29udGVudC1MZW5ndGhgIGhlYWRlciwgZGVmaW5lZCBpbiBbUkZDIDkxMTAgwqc4LjZdLgovLy8KLy8vIFRoZSAiQ29udGVudC1MZW5ndGgiIGhlYWRlciBmaWVsZCBpbmRpY2F0dyBgRm9yd2FyZGVkYCBoZWFkZXIgZnJvbSBhIHNpbmdsZSAiZm9yIiBpZGVudGlmaWVyLgogICAgcHViIGZuIG5ld19mb3IociNmb3I6IGltcGwgSW50bzxTdHJpbmc+KSAtPiBTZWxmIHsKICAgICAgICBTZWxmIHsKICAgICAgICAgICAgYnk6IE5vbmUsCiAgICAgICAgICAgIHIjZm9yOiB2ZWMhW3IjZm9yLmludG8oKV0sCiAgICAgICAgICAgIGhvc3Q6IE5vbmUsCiAgICAgICAgICAgIHByb3RvOiBOb25lLAogICAgICAgIH0KICAgIH0KCiAgICAvLy8gUmV0dXJucyBmaXJzdCAiZm9yIiBwYXJhbWV0ZXIgd2hpY2ggaXMgdHlwaWNhbGx5IHRoZSBjbGllbnQncyBpZGVudGlmaWVyLgogICAgcHViIGZuIGZvcl9jbGllbnQoJnNlbGYpIC0+IE9wdGlvbjwmc3RyPiB7CiAgICAgICAgLy8gVGFraW5nIHRoZSBmaXJzdCB2YWx1ZSBmb3IgZWFjaCBwcm9wZXJ0eSBpcyBjb3JyZWN0IGJlY2F1c2Ugc3BlYyBzdGF0ZXMgdGhhdCBmaXJzdCAiZm9yIgogICAgICAgIC8vIHZhbHVlIGlzIGNsaWVudCBhbmQgcmVzdCBhcmUgcHJveGllcy4gV2UgY29sbGVjdCB0aGVtIGluIHRoZSBvcmRlciB0aGV5IGFyZSByZWFkLgogICAgICAgIC8vCiAgICAgICAgLy8gYGBgcGxhaW4KICAgICAgICAvLyA+IEluIGEgY2hhaW4gb2YgcHJveHkgc2VydmVycyB3aGVyZSB0aGlzIGlzIGZ1bGx5IHV0aWxpemVkLCB0aGUgZmlyc3QKICAgICAgICAvLyA+ICJmb3IiIHBhcmFtZXRlciB3aWxsIGRpc2Nsb3NlIHRoZSBjbGllbnQgd2hlcmUgdGhlIHJlcXVlc3Qgd2FzIGZpcnN0CiAgICAgICAgLy8gPiBtYWRlLCBmb2xsb3dlZCBieSBhbnkgc3Vic2VxdWVudCBwcm94eSBpZGVudGlmaWVycy4KICAgICAgICAvLyAtIGh0dHBzOi8vZGF0YXRyYWNrZXIuaWV0Zi5vcmcvZG9jL2h0bWwvcmZjNzIzOSNzZWN0aW9uLTUuMgogICAgICAgIC8vIGBgYAoKICAgICAgICBzZWxmLnIjZm9yLmZpcnN0KCkubWFwKFN0cmluZzo6YXNfc3RyKQogICAgfQoKICAgIC8vLyBSZXR1cm5zIGl0ZXJhdG9yIG92ZXIgdGhlICJmb3IiIGNoYWluLgogICAgL251ZSwgLy8gd2UgY2FuJ3QgcmVhZCB0aGUgZmlsZQogICAgICAgIH07CgogICAgICAgIGxldCBmaWxlbmFtZSA9IG1hdGNoIGVudHJ5LmZpbGVfbmFtZSgpLmludG9fc3RyaW5nKCkgewogICAgICAgICAgICBPayhmaWxlbmFtZSkgPT4gZmlsZW5hbWUsCiAgICAgICAgICAgIEVycihfKSA9PiBjb250aW51ZSwgLy8gdGhlIGZpbGUgaGFzIGEgbm9uIFVURi04IG5hbWUKICAgICAgICB9OwoKICAgICAgICBsZXQgbXV0IGVudHJ5ID0gemlwcGVyCiAgICAgICAgICAgIC53cml0ZV9lbnRyeV9zdHJlYW0oWmlwRW50cnlCdWlsZGVyOjpuZXcoCiAgICAgICAgICAgICAgICBmaWxlbmFtZSwKICAgICAgICAgICAgICAgIGFzeW5jX3ppcDo6Q29tcHJlc3Npb246OkRlZmxhdGUsCiAgICAgICAgICAgICkpCiAgICAgICAgICAgIC5hd2FpdAogICAgICAgICAgICAubWFwX2Vycih6aXBfdG9faW9fZXJyKT87CgogICAgICAgIHRva2lvOjppbzo6Y29weSgmbXV0IGZpbGUsICZtdXQgZW50cnkpLmF3YWl0PzsKICAgICAgICBlbnRyeS5jbG9zZSgpLmF3YWl0Lm1hcF9lcnIoemlwX3RvX2lvX2Vycik/OwogICAgfQoKICAgIE9rKCgpKQp9CgojW2dldCgiLyIpXQphc3luYyBmbiBpbmRleCgpIC0+IGltcGwgUmVzcG9uZGVyIHsKICAgIGxldCAod3J0LCBib2R5KSA9IGJvZHk6OndyaXRlcigpOwoKICAgIC8vIGFsbG93IHJlc3BvbnNlIHRvIGJlIHN0YXJ0ZWQgd2hpbGUgdGhpcyBpcyBwcm9jZXNzaW5nCiAgICAjW2FsbG93KGNsaXBweTo6bGV0X3VuZGVyc2NvcmVfZnV0dXJlKV0KICAgIGxldCBfID0gdG9raW86OnNwYXduKGFzeW5jIG1vdmUgewogICAgICAgIGxldCBtdXQgemlwcGVyID0gYXN5bmNfemlwOjp3cml0ZTo6WmlwRmlsZVdyaXRlcjo6bmV3KHdydCk7CgogICAgICAgIGlmIGxldCBFcnIoZXJyKSA9IHJlYWRfZGlyKCZtdXQgemlwcGVyKS5hd2FpdCB7CiAgICAgICAgICAgIHRyYWNpbmc6Ondhcm4hKCJGYWlsZWQgdG8gd3JpdGUgZmlsZXMgZnJvbSBkaXJlY3RvcnkgdG8gemlwOiB7ZXJyfSIpCiAgICB0YXRpYyIpCi8vLyAgICAgICAgICAgICAuc3RhdGljX3Jlc291cmNlc19sb2NhdGlvbigiLi9leGFtcGxlcy9hc3NldHMiKQovLy8gICAgICAgICAgICAgLmZpbmlzaCgpCi8vLyAgICAgKTsKLy8vIGBgYAojW2NmZyhmZWF0dXJlID0gInNwYSIpXQpwdWIgZm4gc3BhKCkgLT4gU3BhIHsKICAgIFNwYTo6ZGVmYXVsdCgpCn0KLy8hIE1lc3NhZ2VQYWNrIHJlc3BvbmRlci4KCnVzZSBhY3RpeF93ZWI6OntIdHRwUmVxdWVzdCwgSHR0cFJlc3BvbnNlLCBSZXNwb25kZXJ9Owp1c2UgYnl0ZXM6OkJ5dGVzOwp1c2UgZGVyaXZlX21vcmU6OntEZXJlZiwgRGVyZWZNdXQsIERpc3BsYXl9Owp1c2UgbWltZTo6TWltZTsKdXNlIG9uY2VfY2VsbDo6c3luYzo6TGF6eTsKdXNlIHNlcmRlOjpTZXJpYWxpemU7CgpzdGF0aWMgTVNHUEFDS19NSU1FOiBMYXp5PE1pbWU+ID0gTGF6eTo6bmV3KHx8ICJhcHBsaWNhdGlvbi9tc2dwYWNrIi5wYXJzZSgpLnVud3JhcCgpKTsKCi8vLyBNZXNzYWdlUGFjayByZXNwb25kZXIuCi8vLwovLy8gSWYgeW91IHJlcXVpcmUgdGhlIGZpZWxkcyB0byBiZSBuYW1lZCwgdXNlIFtgTWVzc2FnZVBhY2tOYW1lZGBdLgojW2Rlcml2ZShEZWJ1ZywgRGVyZWYsIERlcmVmTXV0LCBEaXNwbGF5KV0KcHViIHN0cnVjdCBNZXNzYWdlUGFjazxUPihwdWIgVCk7CgppbXBsPFQ6IFNlcmlhbGl6ZT4gUmVzcG9uZGVyIGZvciBNZXNzYWdlUGFjazxUPiB7CiAgICB0eXBlIEJvZHkgPSBCeXRlczsKCiAgICBmbiByZXNwb25kX3RvKHNlbGYsIF9yZXE6ICZIdHRwUmVxdWVzdCkgLT4gSHR0cFJlc3BvbnNlPFNlbGY6OkJvZHk+IHsKICAgICAgICBsZXQgYm9keSA9IEJ5dGVzOjpmcm9tKHJtcF9zZXJkZTo6dG9fdmVjKCZzZWxmLjApLnVud3JhcCgpKTsKCiAgICAgICAgSHR0cFJlc3BvbnNlOjpPaygpCiAgICAgICAgICAgIC5jb250ZW50X3R5cGUoTVNHUEFDS19NSU1FLmNsb25lKCkpCiAgICAgICAgICAgIC5tZXNzYWdlX2JvZHkoYm9keSkKICAgICAgICAgICAgLnVud3JhcCgpCiAgICB9Cn0KCi8vLyBNYWNpbmc6Ondhcm4hKCJjbGllbnQgZGlzY29ubmVjdGVkOyBjb3VsZCBub3Qgc2VuZCBTU0UgbWVzc2FnZSIpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHNsZWVwKER1cmF0aW9uOjpmcm9tX3NlY3MoMTApKS5hd2FpdDsKICAgICAgICB9CiAgICB9KTsKCiAgICBzc2Uud2l0aF9rZWVwX2FsaXZlKER1cmF0aW9uOjpmcm9tX3NlY3MoMykpCn0KCiNbYWN0aXhfd2ViOjptYWluXQphc3luYyBmbiBtYWluKCkgLT4gaW86OlJlc3VsdDwoKT4gewogICAgZW52X2xvZ2dlcjo6aW5pdF9mcm9tX2VudihlbnZfbG9nZ2VyOjpFbnY6Om5ldygpLmRlZmF1bHRfZmlsdGVyX29yKCJpbmZvIikpOwoKICAgIHRyYWNpbmc6OmluZm8hKCJzdGFydGluZyBIVFRQIHNlcnZlciBhdCBodHRwOi8vbG9jYWxob3N0OjgwODAiKTsKCiAgICBIdHRwU2VydmVyOjpuZXcofHwgewogICAgICAgIEFwcDo6bmV3KCkKICAgICAgICAgICAgLnNlcnZpY2UoaW5kZXgpCiAgICAgICAgICAgIC5zZXJ2aWNlKGNvdW50ZG93bikKICAgICAgICAgICAgLnNlcnZpY2UoY291bnRkb3duX2Zyb20pCiAgICAgICAgICAgIC5zZXJ2aWNlKHRpbWVzdGFtcCkKICAgICAgICAgICAgLndyYXAoTG9nZ2VyOjpkZWZhdWx0KCkpCiAgICB9KQogICAgLndvcmtlcnMoMikKICAgIC5iaW5kKCgiMTI3LjAuMC4xIiwgODA4MCkpPwogICAgLnJ1bigpCiAgICAuYXdhaXQKfQp1c2Ugc3RkOjp7CiAgICBmdXR1cmU6OntyZWFkeSwgRnV0dXJlLCBSZWFkeX0sCiAgICBtYXJrZXI6OlBoYW50b21EYXRhLAogICAgcGluOjpQaW4sCiAgICByYzo6UmMsCiAgICB0YXNrOjp7Q29udGV4dCwgUG9sbH0sCn07Cgp1c2UgYWN0aXhfc2VydmljZTo6e2ZvcndhcmRfcmVhZHksIFNlcnZpY2UsIFRyYW5zZm9ybX07CnVzZSBhY3RpeF93ZWI6OnsKICAgIGJvZHk6Ok1lc3NhZ2VCb2R5LAogICAgZGV2Ojp7U2VydmljZVJlcXVlc3QsIFNlcnZpY2VSZXNwb25zZX0sCiAgICBFcnJvciwKfTsKdXNlIGZ1dHVyZXNfY29yZTo6cmVhZAogICAgLy8vIENvbnN0cnVjdHMgbmV3IHBhbmljIHJlcG9ydGVyIG1pZGRsZXdhcmUgd2l0aCBgY2FsbGJhY2tgLgogICAgcHViIGZuIG5ldyhjYWxsYmFjazogaW1wbCBGbigmKGR5biBBbnkgKyBTZW5kKSkgKyAnc3RhdGljKSAtPiBTZWxmIHsKICAgICAgICBTZWxmIHsKICAgICAgICAgICAgY2I6IFJjOjpuZXcoY2FsbGJhY2spLAogICAgICAgIH0KICAgIH0KfQoKaW1wbCBzdGQ6OmZtdDo6RGVidWcgZm9yIFBhbmljUmVwb3J0ZXIgewogICAgZm4gZm10KCZzZWxmLCBmOiAmbXV0IHN0ZDo6Zm10OjpGb3JtYXR0ZXI8J18+KSAtPiBzdGQ6OmZtdDo6UmVzdWx0IHsKICAgICAgICBmLmRlYnVnX3N0cnVjdCgiUGFuaWNSZXBvcnRlciIpCiAgICAgICAgICAgIC5maWVsZCgiY2IiLCAmIjxjYWxsYmFjaz4iKQogICAgICAgICAgICAuZmluaXNoKCkKICAgIH0KfQoKaW1wbDxTLCBSZXE+IFRyYW5zZm9ybTxTLCBSZXE+IGZvciBQYW5pY1JlcG9ydGVyCndoZXJlCiAgICBTOiBTZXJ2aWNlPFJlcT4sCiAgICBTOjpGdXR1cmU6ICdzdGF0aWMsCnsKICAgIHR5cGUgUmVzcG9uc2UgPSBTOjpSZXNwb25zZTsKICAgIHR5cGUgRXJyb3IgPSBTOjpFcnJvcjsKICAgIHR5cGUgVHJhbnNmb3JtID0gUGFuaWNSZXBvcnRlck1pZGRsZXdhcmU8Uz47CiAgICB0eXBlIEluaXRFcnJvciA9ICgpOwogICAgdHlwZSBGdXR1cmUgPSBSZWFkeTxSZXN1bHQ8U2VsZjo6VHJhbnNmb3JtLCBTZWxmOjpJbml0RXJyb3I+PjsKCiAgICBmbiBuZXdfdHJhbnNmb3JtKCZzZWxmLCBzZXJ2aWNlOiBTKSAtPiBTZWxmOjpGdXR1cmUgewogICAgICAgIHJlYWR5KE9rKFBhbmljUmVwb3J0ZXJNaWRkbGV3YXJlIHsKICAgICAgICAgICAgc2VydmljZTogUmM6Om5ldyhzZXJ2aWNlKSwKICAgICAgICAgICAgY2I6IFJjOjpjbG9uZSgmc2VsZi5jYiksCiAgICAgICAgfSkpCiAgICB9Cn0KCnB1YiBzdHJ1Y3QgUGFuaWNSZXBvcnRlck1pZGRsZXdhcmU8Uz4gewogICAgc2VydmljZTogUmM8Uz4sCiAgICBjYjogUGFuaWNDYWxsYmFjaywKfQoKaW1tQm9keTo6RXJyb3IoU29tZShVcmxlbmNvZGVkRXJyb3I6Ok92ZXJmbG93IHsKICAgICAgICAgICAgICAgICAgICBzaXplOiBsZW4sCiAgICAgICAgICAgICAgICAgICAgbGltaXQ6IExJTUlULAogICAgICAgICAgICAgICAgfSkpOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBVcmxFbmNvZGVkRm9ybUJvZHk6OkJvZHkgewogICAgICAgICAgICBsZW5ndGgsCiAgICAgICAgICAgIHBheWxvYWQsCiAgICAgICAgICAgIGJ1Zjogd2ViOjpCeXRlc011dDo6d2l0aF9jYXBhY2l0eSg4MTkyKSwKICAgICAgICAgICAgX3JlczogUGhhbnRvbURhdGEsCiAgICAgICAgfQogICAgfQp9CgppbXBsPFQ6IERlc2VyaWFsaXplT3duZWQsIGNvbnN0IExJTUlUOiB1c2l6ZT4gRnV0dXJlIGZvciBVcmxFbmNvZGVkRm9ybUJvZHk8VCwgTElNSVQ+IHsKICAgIHR5cGUgT3V0cHV0ID0gUmVzdWx0PFQsIFVybGVuY29kZWRFcnJvcj47CgogICAgZm4gcG9sbChzZWxmOiBQaW48Jm11dCBTZWxmPiwgY3g6ICZtdXQgQ29udGV4dDwnXz4pIC0+IFBvbGw8U2VsZjo6T3V0cHV0PiB7CiAgICAgICAgbGV0IHRoaXMgPSBzZWxmLmdldF9tdXQoKTsKCiAgICAgICAgbWF0Y2ggdGhpcyB7CiAgICAgICAgICAgIFVybEVuY29kZWRGb3JtQm9keTo6Qm9keSB7IGJ1ZiwgcGF5bG9hZCwgLi4gfSA9PiBsb29wIHsKICAgICAgICAgICAgICAgIGxldCByZXMgPSByZWFkeSEoUGluOjpuZXcoJm11dCAqcGF5bG9hZCkucG9sbF9uZXh0KGN4KSk7CgogICAgICAgICAgICAgICAgbWF0Y2ggcmVzIHsKICAgICAgICAgICAgICAgICAgICBTb21lKGNodW5rKSA9PiB7CiAgICAgICAgICAgICAgICAgICAgICAgIGxldCBjaHVuayA9IGNodW5rPzsKICAgICAgICAgICAgICAgICAgICAgICAgbGV0IGJ1Zl9sZW4gPSBidWYubGVuKCkgKyBjaHVuay5sZW4oKTsKICAgICAgICAgICAgICAgICAgICAgICAgaWYgYnVmX2xlbiA+IExJTUlUIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBQb2xsOjpSZWFkeShFcnIoVXJsZW5jbHQ8U2VsZjo6UmVzcG9uc2UsIFNlbGY6OkVycm9yPj47CgogICAgZm9yd2FyZF9yZWFkeSEoc2VydmljZSk7CgogICAgZm4gY2FsbCgmc2VsZiwgcmVxOiBTZXJ2aWNlUmVxdWVzdCkgLT4gU2VsZjo6RnV0dXJlIHsKICAgICAgICBzZWxmLnNlcnZpY2UuY2FsbChyZXEpCiAgICB9Cn0KCiNbY2ZnKHRlc3QpXQptb2QgdGVzdHMgewogICAgdXNlIGFjdGl4X3dlYjo6ewogICAgICAgIGh0dHA6OmhlYWRlcjo6e3NlbGYsIEhlYWRlclZhbHVlfSwKICAgICAgICBtaWRkbGV3YXJlOjp7Q29tcGF0LCBMb2dnZXJ9LAogICAgICAgIHRlc3QsIHdlYiwgQXBwLCBIdHRwUmVzcG9uc2UsCiAgICB9OwoKICAgIHVzZSBzdXBlcjo6KjsKCiAgICBhc3luYyBmbiBub29wPEI+KHJlcTogU2VydmljZVJlcXVlc3QsIG5leHQ6IE5leHQ8Qj4pIC0+IFJlc3VsdDxTZXJ2aWNlUmVzcG9uc2U8Qj4sIEVycm9yPiB7CiAgICAgICAgbmV4dC5jYWxsKHJlcSkuYXdhaXQKICAgIH0KCiAgICBhc3luYyBmbiBhZGRfcmVzX2hlYWRlcjxCPigKICAgICAgICByZXE6IFNlcnZpY2VSZXF1ZXN0LAogICAgICAgIG5leHQ6IE5leHQ8Qj4sCiAgICApIC0+IFJlc3VsdDxTZXJ2aWNlUmVzcG9uc2U8Qj4sIEVycm9yPiB7CiAgICAgICAgbGV0IG11dCByZXMgPSBuZXh0LmNhbGwocmVxKS5hd2FpdD87CiAgICAgICAgcmVzLmhlYWRlcnNfbXV0KCkKICAgICAgICAgICAgLmluc2VydChoZWFkZXI6OldBUk5JTkcsIEhlYWRlclZhbHVlOjpmcm9tX3N0YXRpYygiNDIiKSk7CiAgICAgICAgT2socmVzKQogICAgfQoKICAgIGFzeW5jIGZuIG11dGF0ZV9ib2R5X3R5cGUoCiAgICAgICAgcmVxOiBTZXJ2aWNlUmVxdWVzdCwKICAgICAgICBuZXh0OiBOZXh0PGltcGwgTWVzc2FnZUJvZHkgKyAnc3RhdGljPiwKICAgICkgLT4gUmVzdWx0PFNlcnZpY2VSZXNwb25zZTxpbXBsIE1lc3NhZ2VCb2R5PiwgRXJyb3I+IHsKICAgICAgICBsZXQgcmVzID0gbmV4dC5jYWxsKHJlcSkuYXdhaXQ/OwogICAgICAgIE9rKHJlcy5tYXBfaW50b19sZWZ0X2JvZHk6OjpPdmVyZmxvdyIpLAogICAgICAgIH0KICAgIH0KfQoKaW1wbDxUPiBSZXNwb25zZUVycm9yIGZvciBCb2R5TGltaXRFcnJvcjxUPgp3aGVyZQogICAgVDogRnJvbVJlcXVlc3QgKyAnc3RhdGljLAogICAgVDo6RXJyb3I6IGZtdDo6RGVidWcgKyBmbXQ6OkRpc3BsYXksCnsKfQoKI1tjZmcodGVzdCldCm1vZCB0ZXN0cyB7CiAgICB1c2UgYWN0aXhfd2ViOjp7aHR0cDo6aGVhZGVyLCB0ZXN0OjpUZXN0UmVxdWVzdH07CiAgICB1c2UgYnl0ZXM6OkJ5dGVzOwoKICAgIHVzZSBzdXBlcjo6KjsKCiAgICBzdGF0aWNfYXNzZXJ0aW9uczo6YXNzZXJ0X2ltcGxfYWxsIShCb2R5TGltaXRGdXQ8KCksIDEwMD46IFVucGluKTsKICAgIHN0YXRpY19hc3NlcnRpb25zOjphc3NlcnRfaW1wbF9hbGwhKEJvZHlMaW1pdEZ1dDxCeXRlcywgMTAwPjogVW5waW4pOwoKICAgICNbYWN0aXhfd2ViOjp0ZXN0XQogICAgYXN5bmMgZm4gd2l0aGluX2xpbWl0KCkgewogICAgICAgIGxldCAocmVxLCBtdXQgcGwpID0gVGVzdFJlcXVlc3Q6OmRlZmF1bHQoKQogICAgICAgICAgICAuaW5zZXJ0X2hlYWRlcihoZWFkZXI6OkNvbnRlbnRUeXBlOjpwbGFpbnRleHQoKSkKICAgICAgICAgICAgLmluc2VydF9oZWFkZXIoKAogICAgICAgICAgICAgICAgaGVhZGVyOjpDT05URU5UX0xFTkdUSCwKICAgICAgICAgICAgICAgIGhlYWRlcjo6SGVhZGVyVmFsdWU6OmZyb21fc3RhdGljKCI5IiksCiAgICAgICAgICAgICkpCiAgICAgICAgICAgIC5zZXRfcGF5bG9hZChCeXRlczo6ZnJvbV9zdGF0aWMoYiIxMjM0NTY3ODkiKSkKICAgICAgICAgICAgLnRvX2h0dHBfcGFydHMoKTsKCiAgICAgICAgbGV0IGJvZHkgPSBCb2R5TGltaXQ6OjxCeXRlcywgMTA+Ojpmcm9tX3JlcXVlc3QoJnJlcSwgJm11dCBwbCkuYXdhaXQ7CiAgICAgICAgYXNzZXJ0X2VxISgKICAgICAgICAgICAgYm9keS5vaygpLnVud3JhcCgpLmludG9faW5uZXIoKSwKICAgICAgICAgICAgQnl0ZXM6OmZyb21fc3RhdGljKGIiMTIzNDU2Nzg5IikKICAgICAgICApOwogICAgfQogYWN0aXhfdXRpbHM6OmZ1dHVyZTo6b2s7CnVzZSBhY3RpeF93ZWI6OnsKICAgIGJvZHk6OkJveEJvZHksCiAgICBkZXY6Ontmbl9zZXJ2aWNlLCBTZXJ2aWNlLCBTZXJ2aWNlUmVxdWVzdCwgU2VydmljZVJlc3BvbnNlfSwKICAgIGh0dHA6OlN0YXR1c0NvZGUsCiAgICBFcnJvciwgSHR0cFJlc3BvbnNlQnVpbGRlciwKfTsKCi8vLyBDcmVhdGVzIHNlcnZpY2UgdGhhdCBhbHdheXMgcmVzcG9uZHMgd2l0aCBnaXZlbiBzdGF0dXMgY29kZSBhbmQgZWNob2VzIHJlcXVlc3QgcGF0aCBhcyByZXNwb25zZQovLy8gYm9keS4KcHViIGZuIGVjaG9fcGF0aF9zZXJ2aWNlKAogICAgc3RhdHVzX2NvZGU6IFN0YXR1c0NvZGUsCikgLT4gaW1wbCBTZXJ2aWNlPFNlcnZpY2VSZXF1ZXN0LCBSZXNwb25zZSA9IFNlcnZpY2VSZXNwb25zZTxCb3hCb2R5PiwgRXJyb3IgPSBFcnJvcj4gewogICAgZm5fc2VydmljZShtb3ZlIHxyZXE6IFNlcnZpY2VSZXF1ZXN0fCB7CiAgICAgICAgbGV0IHBhdGggPSByZXEucGF0aCgpLnRvX293bmVkKCk7CiAgICAgICAgb2socmVxLmludG9fcmVzcG9uc2UoSHR0cFJlc3BvbnNlQnVpbGRlcjo6bmV3KHN0YXR1c19jb2RlKS5ib2R5KHBhdGgpKSkKICAgIH0pCn0KdXNlIHN0ZDo6e2NvbnZlcnQ6OkluZmFsbGlibGUsIGVycm9yOjpFcnJvciBhcyBTdGRFcnJvcn07Cgp1c2UgYWN0aXhfd2ViOjp7CiAgICBib2R5Ojp7Qm9keVN0cmVhbSwgTWVzc2FnZUJvZHl9LAogICAgSHR0cFJlc3BvbnNlLCBSZXNwb25kZXIsCn07CnVzZSBieXRlczo6e0J5dGVzLCBCeXRlc011dH07CnVzZSBmdXR1cmVzX2NvcmU6OlN0cmVhbTsKdXNlIGZ1dHVyZXNfdXRpbDo6VHJ5U3RyZWFtRXh0IGFzIF87CnVzZSBtaW1lOjpNaW1lOwp1c2UgcGluX3Byb2plY3RfbGl0ZTo6cGluX3Byb2plY3Q7CnVzZSBzZXJkZTo6U2VyaWFsaXplOwoKdXNlIGNyYXRlOjp1dGlsOjp7SW5mYWxsaWJsZVN0cmVhbSwgTXV0V3JpdGVyfTsKCnBpbl9wcm9qZWN0ISB7CiAgICAvLy8gQSBidWZmZXJlZCBDU1Ygc2VyaWFsaXppbmcgIGhleCEoIjAzYWM2NzQyIDE2ZjNlMTVjIDc2MWVlMWE1IGUyNTVmMDY3IDk1MzYyM2M4IGIzODhiNDQ1IDllMTNmOTc4IGQ3Yzg0NmY0IikuYXNfcmVmKCkKICAgICk7Cn0KCiNbYWN0aXhfd2ViOjp0ZXN0XQphc3luYyBmbiB1c2Vfb25fd3JvbmdfZXh0cmFjdG9yX2luX3dyb25nX29yZGVyKCkgewogICAgbGV0IGFwcCA9IHRlc3Q6OmluaXRfc2VydmljZShBcHA6Om5ldygpLnJvdXRlKAogICAgICAgICIvIiwKICAgICAgICB3ZWI6OmdldCgpLnRvKAogICAgICAgICAgICB8X2JvZHk6IEpzb248dTY0LCA0PiwgbnVsbDogQm9keUhhc2g8KCksIFNoYTI1Nj58IGFzeW5jIG1vdmUgewogICAgICAgICAgICAgICAgQnl0ZXM6OmNvcHlfZnJvbV9zbGljZShudWxsLmhhc2goKSkKICAgICAgICAgICAgfSwKICAgICAgICApLAogICAgKSkKICAgIC5hd2FpdDsKCiAgICBsZXQgcmVxID0gdGVzdDo6VGVzdFJlcXVlc3Q6OmRlZmF1bHQoKS5zZXRfanNvbigxMjM0KS50b19yZXF1ZXN0KCk7CiAgICBsZXQgcmVzID0gdGVzdDo6Y2FsbF9zZXJ2aWNlKCZhcHAsIHJlcSkuYXdhaXQ7CiAgICBhc3NlcnRfZXEhKHJlcy5zdGF0dXMoKSwgU3RhdHVzQ29kZTo6T0spOwogICAgbGV0IGJvZHkgPSB0ZXN0OjpyZWFkX2JvZHkocmVzKS5hd2FpdDsKICAgIC8vIGlmIHRoZSBoYXNoIHdyYXBwZXIgaXMgb24gYSBub24tYm9keSBleHRyYWN0b3IgX2FuZF8gYSBib2R5IGV4dHJhY3RvciBoYXMgYWxyZWFkeSB0YWtlbiB0aGUKICAgIC8vIHBheWxvYWQsIHRoaXMgc2hvdWxkIHJldHVybiB0aGUgZW1wdHkgaW5wdXQgaGFzaAogICAgYXNzZXJ0X2VxISgKICAgICAgICBib2R5LAogICAgICAgIGhleCEoImUzYjBjNDQyIDk4ZmMxYzE0IDlhZmJmNGM4IDk5NmZiOTI0IDI3YWU0MWU0IDY0OWI5MzRjIGE0OTU5OTFiIDc4NTJiODU1IikuYXNfcmVmKCkKICAgICk7Cn0KLy8hIEhvdyB0byB1c2UgYE5kSnNvbmAgYXMgYW4gZWZmaWNpZW50IHN0cmVhbWluZyByZXNwb25zZSB0eXBlLgovLyEKLy8hIFRoZSBzYW1lIHRlY2huaXF1ZWR5IHR5cGUuCi8vLwovLy8gIyBFeGFtcGxlcwovLy8gYGBgCi8vLyAjIHVzZSBhY3RpeF93ZWI6OntIdHRwUmVzcG9uc2UsIHdlYn07Ci8vLyB1c2Ugc3RkOjpjb252ZXJ0OjpJbmZhbGxpYmxlOwovLy8gdXNlIGFjdGl4X3dlYl9sYWI6OmJvZHk7Ci8vLwovLy8gIyBhc3luYyBmbiBpbmRleCgpIHsKLy8vIGxldCAobXV0IGJvZHlfdHgsIGJvZHkpID0gYm9keTo6Y2hhbm5lbDo6PEluZmFsbGlibGU+KCk7Ci8vLwovLy8gbGV0IF8gPSB3ZWI6OmJsb2NrKG1vdmUgfHwgewovLy8gICAgIGJvZHlfdHguc2VuZCh3ZWI6OkJ5dGVzOjpmcm9tX3N0YXRpYyhiImJvZHkgZnJvbSBhbm90aGVyIHRocmVhZCIpKS51bndyYXAoKTsKLy8vIH0pOwovLy8KLy8vIEh0dHBSZXNwb25zZTo6T2soKS5ib2R5KGJvZHkpCi8vLyAjIDt9Ci8vLyBgYGAKcHViIGZuIGNoYW5uZWw8RTogSW50bzxCb3hFcnJvcj4+KCkgLT4gKFNlbmRlcjxFPiwgaW1wbCBNZXNzYWdlQm9keSkgewogICAgbGV0ICh0eCwgcngpID0gdG9raW86OnN5bmM6Om1wc2M6OnVuYm91bmRlZF9jaGFubmVsKCk7CiAgICAoU2VuZGVyOjpuZXcodHgpLCBSZWNlaXZlcjo6bmV3KHJ4KSkKfQoKLy8vIEEgY2hhbm5lbC1saWtlIHNlbmRlciBmb3IgYm9keSBjaHVua3MuCiNbZGVyaXZlKERlYnVnLCBDbG9uZSldCnB1YiBzdHJ1Y3QgU2VuZGVyPEU+IHsKICAgIHR4OiBVbmJvdW5kZWRTZW5kZXI8UmVzdWx0PEJ5dGVzLCBFPj4sCn0KCmltcGw8RT4gU2VuZGVyPEU+IHsKICAgIGZuIG5ldyh0eDogVW5ib3VuZGVkU2VuZGVyPFJlc3VsdDxCeXRlcywgRT4+KSAtPiBTZWxmIHsKICAgICAgICBTZWxmIHsgdHggfQogICAgfQoKICAgIC8vLyBTdWJtaXRzIGEgY2h1bmsgb2YgYnl0ZXMgdG8gdGhlIHJlc3BvbnNlIGJvZHkgc3RyZWFtLgogICAgLy8vCiAgICAvLy8gIyBFcnJvcnMKICAgIC8vLyBFcnJvcnMgaWYgb3RoZXIgc2lkZSBvZiBjaGFubmVsIGJvZHkgd2FzIGRyb3BwZWQsIHJldHVybmluZyBgY2h1bmtgLgogICAgcHViIGZuIHNlbmQoJm11dCBzZWxmLCBfZW52KGVudl9sb2dnZXI6OkVudjo6bmV3KCkuZGVmYXVsdF9maWx0ZXJfb3IoImluZm8iKSk7CgogICAgaW5mbyEoInN0YXJpbmcgc2VydmVyIGF0IGh0dHA6Ly9sb2NhbGhvc3Q6ODA4MCIpOwoKICAgIEh0dHBTZXJ2ZXI6Om5ldyh8fCB7CiAgICAgICAgQXBwOjpuZXcoKQogICAgICAgICAgICAud3JhcChtaWRkbGV3YXJlOjpMb2dnZXI6OmRlZmF1bHQoKS5sb2dfdGFyZ2V0KCJAIikpCiAgICAgICAgICAgIC5yb3V0ZSgKICAgICAgICAgICAgICAgICIvIiwKICAgICAgICAgICAgICAgIHdlYjo6cG9zdCgpLnRvKHxib2R5OiBUd29Cb2RpZXM8U3RyaW5nLCB3ZWI6OkJ5dGVzPnwgYXN5bmMgbW92ZSB7CiAgICAgICAgICAgICAgICAgICAgbGV0IChzdHJpbmcsIGJ5dGVzKSA9IGJvZHkuaW50b19wYXJ0cygpOwoKICAgICAgICAgICAgICAgICAgICAvLyBwcm92ZXMgdGhhdCBib2R5IHdhcyBleHRyYWN0ZWQgdHdpY2Ugc2luY2UgdGhlIGJ5dGVzIGV4dHJhY3RlZCBhcmUgYnl0ZS1lcXVhbCB0bwogICAgICAgICAgICAgICAgICAgIC8vIHRoZSBzdHJpbmcsIHdpdGhvdXQgZm9ya2luZyB0aGUgcmVxdWVzdCBwYXlsb2FkLCB0aGUgYnl0ZXMgcGFydHMgd291bGQgYmUgZW1wdHkKICAgICAgICAgICAgICAgICAgICBhc3NlcnRfZXEhKHN0cmluZy5hc19ieXRlcygpLCAmYnl0ZXMpOwoKICAgICAgICAgICAgICAgICAgICAvLyBlY2hvIHN0cmluZwogICAgICAgICAgICAgICAgICAgIHN0cmluZwogICAgICAgICAgICAgICAgfSksCiAgICAgICAgICAgICkKICAgIH0pCiAgICAud29ya2VycygxKQogICAgLmJpbmQoKCIxMjcuMC4wLjEiLCA4MDgwKSk/CiAgICAucnVuKCkKICAgIC5hd2FpdAp9CnVzZSBzdGQ6OmJvcnJvdzo6Q293OwoKdXNlIGFjdGl4X2ZpbGVzOjp7RmlsZXMsIE5hbWVkRmlsZX07CnVzZSBhY3RpeF9zZXJ2aWNlOjpmbl9zZXJ2aWNlOwp1c2UgYWN0aXhfd2ViOjpkZXY6OntIdHRwU2VydmljZUZhY3RvcnksIFJlc291cmNlRGVmLCBTZXJ2aWNlUmVxdWVzdCwgU2VydmljZVJlc3BvbnNlZXF1ZXN0IGZvciBRdWVyeTxUPiB7CiAgICB0eXBlIEVycm9yID0gRXJyb3I7CiAgICB0eXBlIEZ1dHVyZSA9IFJlYWR5PFJlc3VsdDxTZWxmLCBFcnJvcj4+OwoKICAgICNbaW5saW5lXQogICAgZm4gZnJvbV9yZXF1ZXN0KHJlcTogJkh0dHBSZXF1ZXN0LCBfOiAmbXV0IFBheWxvYWQpIC0+IFNlbGY6OkZ1dHVyZSB7CiAgICAgICAgc2VyZGVfaHRtbF9mb3JtOjpmcm9tX3N0cjo6PFQ+KHJlcS5xdWVyeV9zdHJpbmcoKSkKICAgICAgICAgICAgLm1hcCh8dmFsfCByZWFkeShPayhRdWVyeSh2YWwpKSkpCiAgICAgICAgICAgIC51bndyYXBfb3JfZWxzZShtb3ZlIHxlfCB7CiAgICAgICAgICAgICAgICBsZXQgZXJyID0gUXVlcnlQYXlsb2FkRXJyb3I6OkRlc2VyaWFsaXplKGUpOwoKICAgICAgICAgICAgICAgIGRlYnVnISgKICAgICAgICAgICAgICAgICAgICAiRmFpbGVkIGR1cmluZyBRdWVyeSBleHRyYWN0b3IgZGVzZXJpYWxpemF0aW9uLiBcCiAgICAgICAgICAgICAgICAgICAgIFJlcXVlc3QgcGF0aDogezo/fSIsCiAgICAgICAgICAgICAgICAgICAgcmVxLnBhdGgoKQogICAgICAgICAgICAgICAgKTsKCiAgICAgICAgICAgICAgICByZWFkeShFcnIoZXJyLmludG8oKSkpCiAgICAgICAgICAgIH0pCiAgICB9Cn0KCiNbY2ZnKHRlc3QpXQptb2QgdGVzdHMgewogICAgdXNlIGFjdGl4X3dlYjo6dGVzdDo6VGVzdFJlcXVlc3Q7CiAgICB1c2UgZGVyaXZlX21vcmU6OkRpc3BsYXk7CiAgICB1c2Ugc2VyZGU6OkRlc2VyaWFsaXplOwoKICAgIHVzZSBzdXBlcjo6KjsKCiAgICAjW2Rlcml2ZShEZXNlcmlhbGl6ZSwgRGVidWcsIERpc3BsYXkpXQogICAgc3RydWN0IElkIHsKICAgICAgICBpZDogU3RyaW5nLAogICAgfQo=