LyoNCiAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQ0KICogY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoDQogKiB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuDQogKiBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMA0KICogKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgNCiAqIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0DQogKg0KICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMA0KICoNCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUNCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsDQogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4NCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQNCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLg0KICovDQoNCiNpZm5kZWYgX19ERUZBVUxUTVFQVUxMQ09OU1VNRVJfSF9fDQojZGVmaW5lIF9fREVGQVVMVE1RUFVMTENPTlNVTUVSX0hfXw0KDQojaW5jbHVkZSA8c2V0Pg0KI2luY2x1ZGUgPHN0cmluZz4NCiNpbmNsdWRlICJNUUNvbnN1bWVyLmgiDQojaW5jbHVkZSAiTVFNZXNzYWdlUXVldWUuaCINCiNpbmNsdWRlICJNUXVldWVMaXN0ZW5lci5oIg0KI2luY2x1ZGUgIlJvY2tldE1RQ2xpZW50LmgiDQoNCm5hbWVzcGFjZSByb2NrZXRtcSB7DQpjbGFzcyBSZWJhbGFuY2U7DQpjbGFzcyBTdWJzY3JpcHRpb25EYXRhOw0KY2xhc3MgT2Zmc2V0U3RvcmU7DQpjbGFzcyBQdWxsQVBJV3JhcHBlcjsNCmNsYXNzIENvbnN1bWVyUnVubmluZ0luZm87DQovLzwhKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqDQpjbGFzcyBST0NLRVRNUUNMSUVOVF9BUEkgRGVmYXVsdE1RUHVsbENvbnN1bWVyIDogcHVibGljIE1RQ29uc3VtZXIgew0KIHB1YmxpYzoNCiAgRGVmYXVsdE1RUHVsbENvbnN1bWVyKGNvbnN0IHN0ZDo6c3RyaW5nJiBncm91cG5hbWUpOw0KICB2aXJ0dWFsIH5EZWZhdWx0TVFQdWxsQ29uc3VtZXIoKTsNCg0KICAvLzwhYmVnaW4gbXFhZG1pbjsNCiAgdmlydHVhbCB2b2lkIHN0YXJ0KCk7DQogIHZpcnR1YWwgdm9pZCBzaHV0ZG93bigpOw0KICAvLzwhZW5kIG1xYWRtaW47DQoNCiAgLy88IWJlZ2luIE1RQ29uc3VtZXINCiAgdmlydHVhbCB2b2lkIHNlbmRNZXNzYWdlQmFjayhNUU1lc3NhZ2VFeHQmIG1zZywgaW50IGRlbGF5TGV2ZWwpOw0KICB2aXJ0dWFsIHZvaWQgZmV0Y2hTdWJzY3JpYmVNZXNzYWdlUXVldWVzKGNvbnN0IHN0ZDo6c3RyaW5nJiB0b3BpYywgc3RkOjp2ZWN0b3I8TVFNZXNzYWdlUXVldWU+JiBtcXMpOw0KICB2aXJ0dWFsIHZvaWQgZG9SZWJhbGFuY2UoKTsNCiAgdmlydHVhbCB2b2lkIHBlcnNpc3RDb25zdW1lck9mZnNldCgpOw0KICB2aXJ0dWFsIHZvaWQgcGVyc2lzdENvbnN1bWVyT2Zmc2V0QnlSZXNldE9mZnNldCgpOw0KICB2aXJ0dWFsIHZvaWQgdXBkYXRlVG9waWNTdWJzY3JpYmVJbmZvKGNvbnN0IHN0ZDo6c3RyaW5nJiB0b3BpYywgc3RkOjp2ZWN0b3I8TVFNZXNzYWdlUXVldWU+JiBpbmZvKTsNCiAgdmlydHVhbCBDb25zdW1lVHlwZSBnZXRDb25zdW1lVHlwZSgpOw0KICB2aXJ0dWFsIENvbnN1bWVGcm9tV2hlcmUgZ2V0Q29uc3VtZUZyb21XaGVyZSgpOw0KICB2aXJ0dWFsIHZvaWQgZ2V0U3Vic2NyaXB0aW9ucyhzdGQ6OnZlY3RvcjxTdWJzY3JpcHRpb25EYXRhPiYpOw0KICB2aXJ0dWFsIHZvaWQgdXBkYXRlQ29uc3VtZU9mZnNldChjb25zdCBNUU1lc3NhZ2VRdWV1ZSYgbXEsIGludDY0IG9mZnNldCk7DQogIHZpcnR1YWwgdm9pZCByZW1vdmVDb25zdW1lT2Zmc2V0KGNvbnN0IE1RTWVzc2FnZVF1ZXVlJiBtcSk7DQogIHZpcnR1YWwgdm9pZCBwcm9kdWNlUHVsbE1zZ1Rhc2soUHVsbFJlcXVlc3QqKTsNCiAgdmlydHVhbCBSZWJhbGFuY2UqIGdldFJlYmFsYW5jZSgpIGNvbnN0Ow0KICAvLzwhZW5kIE1RQ29uc3VtZXI7DQoNCiAgdm9pZCByZWdpc3Rlck1lc3NhZ2VRdWV1ZUxpc3RlbmVyKGNvbnN0IHN0ZDo6c3RyaW5nJiB0b3BpYywgTVF1ZXVlTGlzdGVuZXIqIHBMaXN0ZW5lcik7DQogIC8qKg0KICAqIHB1bGwgbXNnIGZyb20gc3BlY2lmaWVkIHF1ZXVlLCBpZiBubyBtc2cgaW4gcXVldWUsIHJldHVybiBkaXJlY3RseQ0KICAqDQogICogQHBhcmFtIG1xDQogICogICAgICAgICAgICBzcGVjaWZ5IHRoZSBwdWxsZWQgcXVldWUNCiAgKiBAcGFyYW0gc3ViRXhwcmVzc2lvbg0KICAqICAgICAgICAgICAgc2V0IGZpbHRlciBleHByZXNzaW9uIGZvciBwdWxsZWQgbXNnLCBicm9rZXIgd2lsbCBmaWx0ZXIgbXNnIGFjdGl2ZWx5DQogICogICAgICAgICAgICBOb3cgb25seSBPUiBvcGVyYXRpb24gaXMgc3VwcG9ydGVkLCBlZzogInRhZzEgfHwgdGFnMiB8fCB0YWczIg0KICAqICAgICAgICAgICAgaWYgc3ViRXhwcmVzc2lvbiBpcyBzZXR0ZWQgdG8gIm51bGwiIG9yICIqIqOsYWxsIG1zZyB3aWxsIGJlIHN1YnNjcmliZWQNCiAgKiBAcGFyYW0gb2Zmc2V0DQogICogICAgICAgICAgICBzcGVjaWZ5IHRoZSBzdGFydGVkIHB1bGwgb2Zmc2V0DQogICogQHBhcmFtIG1heE51bXMNCiAgKiAgICAgICAgICAgIHNwZWNpZnkgbWF4IG1zZyBudW0gYnkgcGVyIHB1bGwNCiAgKiBAcmV0dXJuDQogICogICAgICAgICAgICBhY2Nyb2RpbmcgdG8gUHVsbFJlc3VsdA0KICAqLw0KICB2aXJ0dWFsIFB1bGxSZXN1bHQgcHVsbChjb25zdCBNUU1lc3NhZ2VRdWV1ZSYgbXEsIGNvbnN0IHN0ZDo6c3RyaW5nJiBzdWJFeHByZXNzaW9uLCBpbnQ2NCBvZmZzZXQsIGludCBtYXhOdW1zKTsNCiAgdmlydHVhbCB2b2lkIHB1bGwoY29uc3QgTVFNZXNzYWdlUXVldWUmIG1xLA0KICAgICAgICAgICAgICAgICAgICBjb25zdCBzdGQ6OnN0cmluZyYgc3ViRXhwcmVzc2lvbiwNCiAgICAgICAgICAgICAgICAgICAgaW50NjQgb2Zmc2V0LA0KICAgICAgICAgICAgICAgICAgICBpbnQgbWF4TnVtcywNCiAgICAgICAgICAgICAgICAgICAgUHVsbENhbGxiYWNrKiBwUHVsbENhbGxiYWNrKTsNCg0KICAvKioNCiAgKiBwdWxsIG1zZyBmcm9tIHNwZWNpZmllZCBxdWV1ZSwgaWYgbm8gbXNnLCBicm9rZXIgd2lsbCBzdXNwZW5kIHRoZSBwdWxsIHJlcXVlc3QgMjBzDQogICoNCiAgKiBAcGFyYW0gbXENCiAgKiAgICAgICAgICAgIHNwZWNpZnkgdGhlIHB1bGxlZCBxdWV1ZQ0KICAqIEBwYXJhbSBzdWJFeHByZXNzaW9uDQogICogICAgICAgICAgICBzZXQgZmlsdGVyIGV4cHJlc3Npb24gZm9yIHB1bGxlZCBtc2csIGJyb2tlciB3aWxsIGZpbHRlciBtc2cgYWN0aXZlbHkNCiAgKiAgICAgICAgICAgIE5vdyBvbmx5IE9SIG9wZXJhdGlvbiBpcyBzdXBwb3J0ZWQsIGVnOiAidGFnMSB8fCB0YWcyIHx8IHRhZzMiDQogICogICAgICAgICAgICBpZiBzdWJFeHByZXNzaW9uIGlzIHNldHRlZCB0byAibnVsbCIgb3IgIioio6xhbGwgbXNnIHdpbGwgYmUgc3Vic2NyaWJlZA0KICAqIEBwYXJhbSBvZmZzZXQNCiAgKiAgICAgICAgICAgIHNwZWNpZnkgdGhlIHN0YXJ0ZWQgcHVsbCBvZmZzZXQNCiAgKiBAcGFyYW0gbWF4TnVtcw0KICAqICAgICAgICAgICAgc3BlY2lmeSBtYXggbXNnIG51bSBieSBwZXIgcHVsbA0KICAqIEByZXR1cm4NCiAgKiAgICAgICAgICAgIGFjY3JvZGluZyB0byBQdWxsUmVzdWx0DQogICovDQogIFB1bGxSZXN1bHQgcHVsbEJsb2NrSWZOb3RGb3VuZChjb25zdCBNUU1lc3NhZ2VRdWV1ZSYgbXEsIGNvbnN0IHN0ZDo6c3RyaW5nJiBzdWJFeHByZXNzaW9uLCBpbnQ2NCBvZmZzZXQsIGludCBtYXhOdW1zKTsNCiAgdm9pZCBwdWxsQmxvY2tJZk5vdEZvdW5kKGNvbnN0IE1RTWVzc2FnZVF1ZXVlJiBtcSwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHN0ZDo6c3RyaW5nJiBzdWJFeHByZXNzaW9uLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50NjQgb2Zmc2V0LA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50IG1heE51bXMsDQogICAgICAgICAgICAgICAgICAgICAgICAgICBQdWxsQ2FsbGJhY2sqIHBQdWxsQ2FsbGJhY2spOw0KDQogIHZpcnR1YWwgQ29uc3VtZXJSdW5uaW5nSW5mbyogZ2V0Q29uc3VtZXJSdW5uaW5nSW5mbygpIHsgcmV0dXJuIE5VTEw7IH0NCiAgLyoqDQogICogu/HIoc/7t9G9+LbIo6y3tbvYLTGx7cq+s/a07Q0KICAqDQogICogQHBhcmFtIG1xDQogICogQHBhcmFtIGZyb21TdG9yZQ0KICAqIEByZXR1cm4NCiAgKi8NCiAgaW50NjQgZmV0Y2hDb25zdW1lT2Zmc2V0KGNvbnN0IE1RTWVzc2FnZVF1ZXVlJiBtcSwgYm9vbCBmcm9tU3RvcmUpOw0KICAvKioNCiAgKiC4+b7ddG9waWO78cihTWVzc2FnZVF1ZXVlo6zS1L75uuK3vcq91NrX6cTatuC49rPJ1LHWrrzkt9bF5A0KICAqDQogICogQHBhcmFtIHRvcGljDQogICogICAgICAgICAgICDP+8+iVG9waWMNCiAgKiBAcmV0dXJuILe1u9i208HQvK+6zw0KICAqLw0KICB2b2lkIGZldGNoTWVzc2FnZVF1ZXVlc0luQmFsYW5jZShjb25zdCBzdGQ6OnN0cmluZyYgdG9waWMsIHN0ZDo6dmVjdG9yPE1RTWVzc2FnZVF1ZXVlPiBtcXMpOw0KDQogIC8vIHRlbXAgcGVyc2lzdCBjb25zdW1lciBvZmZzZXQgaW50ZXJmYWNlLCBvbmx5IHZhbGlkIHdpdGgNCiAgLy8gUmVtb3RlQnJva2VyT2Zmc2V0U3RvcmUsIHVwZGF0ZUNvbnN1bWVPZmZzZXQgc2hvdWxkIGJlIGNhbGxlZCBiZWZvcmUuDQogIHZvaWQgcGVyc2lzdENvbnN1bWVyT2Zmc2V0NFB1bGxDb25zdW1lcihjb25zdCBNUU1lc3NhZ2VRdWV1ZSYgbXEpOw0KDQogcHJpdmF0ZToNCiAgdm9pZCBjaGVja0NvbmZpZygpOw0KICB2b2lkIGNvcHlTdWJzY3JpcHRpb24oKTsNCg0KICBQdWxsUmVzdWx0IHB1bGxTeW5jSW1wbChjb25zdCBNUU1lc3NhZ2VRdWV1ZSYgbXEsDQogICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHN0ZDo6c3RyaW5nJiBzdWJFeHByZXNzaW9uLA0KICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQ2NCBvZmZzZXQsDQogICAgICAgICAgICAgICAgICAgICAgICAgIGludCBtYXhOdW1zLA0KICAgICAgICAgICAgICAgICAgICAgICAgICBib29sIGJsb2NrKTsNCg0KICB2b2lkIHB1bGxBc3luY0ltcGwoY29uc3QgTVFNZXNzYWdlUXVldWUmIG1xLA0KICAgICAgICAgICAgICAgICAgICAgY29uc3Qgc3RkOjpzdHJpbmcmIHN1YkV4cHJlc3Npb24sDQogICAgICAgICAgICAgICAgICAgICBpbnQ2NCBvZmZzZXQsDQogICAgICAgICAgICAgICAgICAgICBpbnQgbWF4TnVtcywNCiAgICAgICAgICAgICAgICAgICAgIGJvb2wgYmxvY2ssDQogICAgICAgICAgICAgICAgICAgICBQdWxsQ2FsbGJhY2sqIHBQdWxsQ2FsbGJhY2spOw0KDQogIHZvaWQgc3Vic2NyaXB0aW9uQXV0b21hdGljYWxseShjb25zdCBzdGQ6OnN0cmluZyYgdG9waWMpOw0KDQogcHJpdmF0ZToNCiAgc3RkOjpzZXQ8c3RkOjpzdHJpbmc+IG1fcmVnaXN0ZXJUb3BpY3M7DQoNCiAgTVF1ZXVlTGlzdGVuZXIqIG1fcE1lc3NhZ2VRdWV1ZUxpc3RlbmVyOw0KICBPZmZzZXRTdG9yZSogbV9wT2Zmc2V0U3RvcmU7DQogIFJlYmFsYW5jZSogbV9wUmViYWxhbmNlOw0KICBQdWxsQVBJV3JhcHBlciogbV9wUHVsbEFQSVdyYXBwZXI7DQp9Ow0KLy88ISoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKg0KfSAgLy88IWVuZCBuYW1lc3BhY2U7DQojZW5kaWYNCg==