Li4gQWxnb3JpdGhtcy9UcmFuc2Zvcm1hdGlvbiBBbGdvcml0aG1zLy9zb3J0IHw5NQoKc29ydAo9PT09CgpTeW5vcHNpcwotLS0tLS0tLQoKLi4gcGFyc2VkLWxpdGVyYWw6OgogICAgCiAgICB0ZW1wbGF0ZTwKICAgICAgICAgIHR5cGVuYW1lIFNlcQogICAgICAgICwgdHlwZW5hbWUgUHJlZCA9IGxlc3M8XzEsXzI+CiAgICAgICAgLCB0eXBlbmFtZSBJbiA9IHx1bnNwZWNpZmllZHwKICAgICAgICA+CiAgICBzdHJ1Y3Qgc29ydAogICAgewogICAgICAgIHR5cGVkZWYgfHVuc3BlY2lmaWVkfCB0eXBlOwogICAgfTsKCgpEZXNjcmlwdGlvbgotLS0tLS0tLS0tLQoKUmV0dXJucyBhIG5ldyBzZXF1ZW5jZSBvZiBhbGwgZWxlbWVudHMgaW4gdGhlIHJhbmdlIHxiZWdpbi9lbmQ8U2VxPnwgc29ydGVkIGFjY29yZGluZwp0byB0aGUgb3JkZXJpbmcgcmVsYXRpb24gYGBQcmVkYGAuIAoKfHRyYW5zZm9ybWF0aW9uIGFsZ29yaXRobSBkaXNjbGFpbWVyfAoKCkhlYWRlcgotLS0tLS0KCi4uIHBhcnNlZC1saXRlcmFsOjoKICAgIAogICAgI2luY2x1ZGUgPGJvb3N0L21wbC9zb3J0LmhwcD4KCgpNb2RlbCBvZgotLS0tLS0tLQoKfFJldmVyc2libGUgQWxnb3JpdGhtfAoKClBhcmFtZXRlcnMKLS0tLS0tLS0tLQoKKy0tLS0tLS0tLS0tLS0tLS0tLS0rLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0rLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSsKfCBQYXJhbWV0ZXIgICAgICAgICB8IFJlcXVpcmVtZW50ICAgICAgICAgICAgICAgICAgICAgICB8IERlc2NyaXB0aW9uICAgICAgICAgICAgICAgICAgIHwKKz09PT09PT09PT09PT09PT09PT0rPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0rPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PSsKfCBgYFNlcWBgICAgICAgICAgICB8IHxGb3J3YXJkIFNlcXVlbmNlfCAgICAgICAgICAgICAgICB8IEFuIG9yaWdpbmFsIHNlcXVlbmNlLiAgICAgICAgIHwKKy0tLS0tLS0tLS0tLS0tLS0tLS0rLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0rLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSsKfCBgYFByZWRgYCAgICAgICAgICB8IEJpbmFyeSB8TGFtYmRhIEV4cHJlc3Npb258ICAgICAgICB8IEFuIG9yZGVyaW5nIHJlbGF0aW9uLiAgICAgICAgIHwKKy0tLS0tLS0tLS0tLS0tLS0tLS0rLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0rLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSsKfCBgYEluYGAgICAgICAgICAgICB8IHxJbnNlcnRlcnwgICAgICAgICAgICAgICAgICAgICAgICB8IEFuIGluc2VydGVyLiAgICAgICAgICAgICAgICAgIHwKKy0tLS0tLS0tLS0tLS0tLS0tLS0rLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0rLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSsKCgpFeHByZXNzaW9uIHNlbWFudGljcwotLS0tLS0tLS0tLS0tLS0tLS0tLQoKfFNlbWFudGljcyBkaXNjbGFpbWVyLi4ufCB8UmV2ZXJzaWJsZSBBbGdvcml0aG18LgoKRm9yIGFueSB8Rm9yd2FyZCBTZXF1ZW5jZXwgYGBzYGAsIGEgYmluYXJ5IHxMYW1iZGEgRXhwcmVzc2lvbnwgYGBwcmVkYGAsIGFuZCBhbiAKfEluc2VydGVyfCBgYGluYGA6CgoKLi4gcGFyc2VkLWxpdGVyYWw6OgoKICAgIHR5cGVkZWYgc29ydDxzLHByZWQsaW4+Ojp0eXBlIHI7Cgo6UmV0dXJuIHR5cGU6CiAgICBBIHR5cGUuCiAgICAKOlNlbWFudGljczoKICAgIElmIGBgc2l6ZTxzPjo6dmFsdWUgPD0gMWBgLCBlcXVpdmFsZW50IHRvCgogICAgLi4gcGFyc2VkLWxpdGVyYWw6OgoKICAgICAgICB0eXBlZGVmIGNvcHk8cyxpbj46OnR5cGUgcjsKICAgIAogICAgCiAgICBvdGhlcndpc2UgZXF1aXZhbGVudCB0byAKICAgIAogICAgLi4gcGFyc2VkLWxpdGVyYWw6OgoKICAgICAgICB0eXBlZGVmIGJhY2tfaW5zZXJ0ZXI8IHZlY3Rvcjw+ID4gYXV4X2luOwogICAgICAgIHR5cGVkZWYgbGFtYmRhPHByZWQ+Ojp0eXBlIHA7CgogICAgICAgIHR5cGVkZWYgYmVnaW48cz46OnR5cGUgcGl2b3Q7CiAgICAgICAgdHlwZWRlZiBwYXJ0aXRpb248CiAgICAgICAgICAgICAgaXRlcmF0b3JfcmFuZ2U8IG5leHQ8cGl2b3Q+Ojp0eXBlLCBlbmQ8cz46OnR5cGUgPgogICAgICAgICAgICAsIGFwcGx5X3dyYXAyPHAsXzEsZGVyZWY8cGl2b3Q+Ojp0eXBlPgogICAgICAgICAgICAsIGF1eF9pbgogICAgICAgICAgICAsIGF1eF9pbgogICAgICAgICAgICA+Ojp0eXBlIHBhcnRpdGlvbmVkOwoKICAgICAgICB0eXBlZGVmIHNvcnQ8cGFydGl0aW9uZWQ6OmZpcnN0LHAsYXV4X2luID46OnR5cGUgcGFydDE7CiAgICAgICAgdHlwZWRlZiBzb3J0PHBhcnRpdGlvbmVkOjpzZWNvbmQscCxhdXhfaW4gPjo6dHlwZSBwYXJ0MjsKICAgICAgICAKICAgICAgICB0eXBlZGVmIGNvcHk8CiAgICAgICAgICAgICAgam9pbnRfdmlldzwgCiAgICAgICAgICAgICAgICAgIGpvaW50X3ZpZXc8cGFydDEsc2luZ2xlX3ZpZXc8IGRlcmVmPHBpdm90Pjo6dHlwZSA+ID4KICAgICAgICAgICAgICAgICwgcGFydDIKICAgICAgICAgICAgICAgID4KICAgICAgICAgICAgLCBpbgogICAgICAgICAgICA+Ojp0eXBlIHI7CgoKQ29tcGxleGl0eQotLS0tLS0tLS0tCgpBdmVyYWdlICpPKG4gbG9nKG4pKSogd2hlcmUgKm4qID09IGBgc2l6ZTxzPjo6dmFsdWVgYCwgcXVhZHJhdGljIGF0IHdvcnN0LgoKRXhhbXBsZQotLS0tLS0tCgouLiBwYXJzZWQtbGl0ZXJhbDo6CiAgICAKICAgIHR5cGVkZWYgdmVjdG9yX2M8aW50LDMsNCwwLC01LDgsLTEsNz4gbnVtYmVyczsKICAgIHR5cGVkZWYgdmVjdG9yX2M8aW50LC01LC0xLDAsMyw0LDcsOD4gZXhwZWN0ZWQ7CiAgICB0eXBlZGVmIHNvcnQ8bnVtYmVycz46OnR5cGUgcmVzdWx0OwoKICAgIEJPT1NUX01QTF9BU1NFUlQoKCBlcXVhbDwgcmVzdWx0LCBleHBlY3RlZCwgZXF1YWxfdG88XyxfPiA+ICkpOwoKClNlZSBhbHNvCi0tLS0tLS0tCgp8VHJhbnNmb3JtYXRpb24gQWxnb3JpdGhtc3wsIHxSZXZlcnNpYmxlIEFsZ29yaXRobXwsIHxwYXJ0aXRpb258CgoKLi4gY29weXJpZ2h0OjogQ29weXJpZ2h0IKkgIDIwMDEtMjAwOSBBbGVrc2V5IEd1cnRvdm95IGFuZCBEYXZpZCBBYnJhaGFtcwogICBEaXN0cmlidXRlZCB1bmRlciB0aGUgQm9vc3QgU29mdHdhcmUgTGljZW5zZSwgVmVyc2lvbiAxLjAuIChTZWUgYWNjb21wYW55aW5nCiAgIGZpbGUgTElDRU5TRV8xXzAudHh0IG9yIGNvcHkgYXQgaHR0cDovL3d3dy5ib29zdC5vcmcvTElDRU5TRV8xXzAudHh0KQo=