LyoNCiAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQ0KICogY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoDQogKiB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuDQogKiBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMA0KICogKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgNCiAqIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0DQogKg0KICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMA0KICoNCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUNCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsDQogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4NCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQNCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLg0KICovDQoNCiNpZm5kZWYgX19ERUZBVUxUTVFQVUxMQ09OU1VNRVJfSF9fDQojZGVmaW5lIF9fREVGQVVMVE1RUFVMTENPTlNVTUVSX0hfXw0KDQojaW5jbHVkZSA8c2V0Pg0KI2luY2x1ZGUgPHN0cmluZz4NCiNpbmNsdWRlICJNUUNvbnN1bWVyLmgiDQojaW5jbHVkZSAiTVFNZXNzYWdlUXVldWUuaCINCiNpbmNsdWRlICJNUXVldWVMaXN0ZW5lci5oIg0KI2luY2x1ZGUgIlJvY2tldE1RQ2xpZW50LmgiDQoNCm5hbWVzcGFjZSByb2NrZXRtcSB7DQpjbGFzcyBSZWJhbGFuY2U7DQpjbGFzcyBTdWJzY3JpcHRpb25EYXRhOw0KY2xhc3MgT2Zmc2V0U3RvcmU7DQpjbGFzcyBQdWxsQVBJV3JhcHBlcjsNCmNsYXNzIENvbnN1bWVyUnVubmluZ0luZm87DQovLzwhKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqDQpjbGFzcyBST0NLRVRNUUNMSUVOVF9BUEkgRGVmYXVsdE1RUHVsbENvbnN1bWVyIDogcHVibGljIE1RQ29uc3VtZXIgew0KIHB1YmxpYzoNCiAgRGVmYXVsdE1RUHVsbENvbnN1bWVyKGNvbnN0IHN0ZDo6c3RyaW5nJiBncm91cG5hbWUpOw0KICB2aXJ0dWFsIH5EZWZhdWx0TVFQdWxsQ29uc3VtZXIoKTsNCg0KICAvLzwhYmVnaW4gbXFhZG1pbjsNCiAgdmlydHVhbCB2b2lkIHN0YXJ0KCk7DQogIHZpcnR1YWwgdm9pZCBzaHV0ZG93bigpOw0KICAvLzwhZW5kIG1xYWRtaW47DQoNCiAgLy88IWJlZ2luIE1RQ29uc3VtZXINCiAgdmlydHVhbCB2b2lkIHNlbmRNZXNzYWdlQmFjayhNUU1lc3NhZ2VFeHQmIG1zZywgaW50IGRlbGF5TGV2ZWwpOw0KICB2aXJ0dWFsIHZvaWQgZmV0Y2hTdWJzY3JpYmVNZXNzYWdlUXVldWVzKGNvbnN0IHN0ZDo6c3RyaW5nJiB0b3BpYywgc3RkOjp2ZWN0b3I8TVFNZXNzYWdlUXVldWU+JiBtcXMpOw0KICB2aXJ0dWFsIHZvaWQgZG9SZWJhbGFuY2UoKTsNCiAgdmlydHVhbCB2b2lkIHBlcnNpc3RDb25zdW1lck9mZnNldCgpOw0KICB2aXJ0dWFsIHZvaWQgcGVyc2lzdENvbnN1bWVyT2Zmc2V0QnlSZXNldE9mZnNldCgpOw0KICB2aXJ0dWFsIHZvaWQgdXBkYXRlVG9waWNTdWJzY3JpYmVJbmZvKGNvbnN0IHN0ZDo6c3RyaW5nJiB0b3BpYywgc3RkOjp2ZWN0b3I8TVFNZXNzYWdlUXVldWU+JiBpbmZvKTsNCiAgdmlydHVhbCBDb25zdW1lVHlwZSBnZXRDb25zdW1lVHlwZSgpOw0KICB2aXJ0dWFsIENvbnN1bWVGcm9tV2hlcmUgZ2V0Q29uc3VtZUZyb21XaGVyZSgpOw0KICB2aXJ0dWFsIHZvaWQgZ2V0U3Vic2NyaXB0aW9ucyhzdGQ6OnZlY3RvcjxTdWJzY3JpcHRpb25EYXRhPiYpOw0KICB2aXJ0dWFsIHZvaWQgdXBkYXRlQ29uc3VtZU9mZnNldChjb25zdCBNUU1lc3NhZ2VRdWV1ZSYgbXEsIGludDY0IG9mZnNldCk7DQogIHZpcnR1YWwgdm9pZCByZW1vdmVDb25zdW1lT2Zmc2V0KGNvbnN0IE1RTWVzc2FnZVF1ZXVlJiBtcSk7DQogIHZpcnR1YWwgdm9pZCBwcm9kdWNlUHVsbE1zZ1Rhc2soUHVsbFJlcXVlc3QqKTsNCiAgdmlydHVhbCBSZWJhbGFuY2UqIGdldFJlYmFsYW5jZSgpIGNvbnN0Ow0KICAvLzwhZW5kIE1RQ29uc3VtZXI7DQoNCiAgdm9pZCByZWdpc3Rlck1lc3NhZ2VRdWV1ZUxpc3RlbmVyKGNvbnN0IHN0ZDo6c3RyaW5nJiB0b3BpYywgTVF1ZXVlTGlzdGVuZXIqIHBMaXN0ZW5lcik7DQogIC8qKg0KICAgKiBwdWxsIG1zZyBmcm9tIHNwZWNpZmllZCBxdWV1ZSwgaWYgbm8gbXNnIGluIHF1ZXVlLCByZXR1cm4gZGlyZWN0bHkNCiAgICoNCiAgICogQHBhcmFtIG1xDQogICAqICAgICAgICAgICAgc3BlY2lmeSB0aGUgcHVsbGVkIHF1ZXVlDQogICAqIEBwYXJhbSBzdWJFeHByZXNzaW9uDQogICAqICAgICAgICAgICAgc2V0IGZpbHRlciBleHByZXNzaW9uIGZvciBwdWxsZWQgbXNnLCBicm9rZXIgd2lsbCBmaWx0ZXIgbXNnIGFjdGl2ZWx5DQogICAqICAgICAgICAgICAgTm93IG9ubHkgT1Igb3BlcmF0aW9uIGlzIHN1cHBvcnRlZCwgZWc6ICJ0YWcxIHx8IHRhZzIgfHwgdGFnMyINCiAgICogICAgICAgICAgICBpZiBzdWJFeHByZXNzaW9uIGlzIHNldHRlZCB0byAibnVsbCIgb3IgIioio6xhbGwgbXNnIHdpbGwgYmUgc3Vic2NyaWJlZA0KICAgKiBAcGFyYW0gb2Zmc2V0DQogICAqICAgICAgICAgICAgc3BlY2lmeSB0aGUgc3RhcnRlZCBwdWxsIG9mZnNldA0KICAgKiBAcGFyYW0gbWF4TnVtcw0KICAgKiAgICAgICAgICAgIHNwZWNpZnkgbWF4IG1zZyBudW0gYnkgcGVyIHB1bGwNCiAgICogQHJldHVybg0KICAgKiAgICAgICAgICAgIGFjY3JvZGluZyB0byBQdWxsUmVzdWx0DQogICAqLw0KICB2aXJ0dWFsIFB1bGxSZXN1bHQgcHVsbChjb25zdCBNUU1lc3NhZ2VRdWV1ZSYgbXEsIGNvbnN0IHN0ZDo6c3RyaW5nJiBzdWJFeHByZXNzaW9uLCBpbnQ2NCBvZmZzZXQsIGludCBtYXhOdW1zKTsNCiAgdmlydHVhbCB2b2lkIHB1bGwoY29uc3QgTVFNZXNzYWdlUXVldWUmIG1xLA0KICAgICAgICAgICAgICAgICAgICBjb25zdCBzdGQ6OnN0cmluZyYgc3ViRXhwcmVzc2lvbiwNCiAgICAgICAgICAgICAgICAgICAgaW50NjQgb2Zmc2V0LA0KICAgICAgICAgICAgICAgICAgICBpbnQgbWF4TnVtcywNCiAgICAgICAgICAgICAgICAgICAgUHVsbENhbGxiYWNrKiBwUHVsbENhbGxiYWNrKTsNCg0KICAvKioNCiAgICogcHVsbCBtc2cgZnJvbSBzcGVjaWZpZWQgcXVldWUsIGlmIG5vIG1zZywgYnJva2VyIHdpbGwgc3VzcGVuZCB0aGUgcHVsbCByZXF1ZXN0IDIwcw0KICAgKg0KICAgKiBAcGFyYW0gbXENCiAgICogICAgICAgICAgICBzcGVjaWZ5IHRoZSBwdWxsZWQgcXVldWUNCiAgICogQHBhcmFtIHN1YkV4cHJlc3Npb24NCiAgICogICAgICAgICAgICBzZXQgZmlsdGVyIGV4cHJlc3Npb24gZm9yIHB1bGxlZCBtc2csIGJyb2tlciB3aWxsIGZpbHRlciBtc2cgYWN0aXZlbHkNCiAgICogICAgICAgICAgICBOb3cgb25seSBPUiBvcGVyYXRpb24gaXMgc3VwcG9ydGVkLCBlZzogInRhZzEgfHwgdGFnMiB8fCB0YWczIg0KICAgKiAgICAgICAgICAgIGlmIHN1YkV4cHJlc3Npb24gaXMgc2V0dGVkIHRvICJudWxsIiBvciAiKiKjrGFsbCBtc2cgd2lsbCBiZSBzdWJzY3JpYmVkDQogICAqIEBwYXJhbSBvZmZzZXQNCiAgICogICAgICAgICAgICBzcGVjaWZ5IHRoZSBzdGFydGVkIHB1bGwgb2Zmc2V0DQogICAqIEBwYXJhbSBtYXhOdW1zDQogICAqICAgICAgICAgICAgc3BlY2lmeSBtYXggbXNnIG51bSBieSBwZXIgcHVsbA0KICAgKiBAcmV0dXJuDQogICAqICAgICAgICAgICAgYWNjcm9kaW5nIHRvIFB1bGxSZXN1bHQNCiAgICovDQogIFB1bGxSZXN1bHQgcHVsbEJsb2NrSWZOb3RGb3VuZChjb25zdCBNUU1lc3NhZ2VRdWV1ZSYgbXEsIGNvbnN0IHN0ZDo6c3RyaW5nJiBzdWJFeHByZXNzaW9uLCBpbnQ2NCBvZmZzZXQsIGludCBtYXhOdW1zKTsNCiAgdm9pZCBwdWxsQmxvY2tJZk5vdEZvdW5kKGNvbnN0IE1RTWVzc2FnZVF1ZXVlJiBtcSwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHN0ZDo6c3RyaW5nJiBzdWJFeHByZXNzaW9uLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50NjQgb2Zmc2V0LA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50IG1heE51bXMsDQogICAgICAgICAgICAgICAgICAgICAgICAgICBQdWxsQ2FsbGJhY2sqIHBQdWxsQ2FsbGJhY2spOw0KDQogIHZpcnR1YWwgQ29uc3VtZXJSdW5uaW5nSW5mbyogZ2V0Q29uc3VtZXJSdW5uaW5nSW5mbygpIHsgcmV0dXJuIE5VTEw7IH0NCiAgLyoqDQogICAqILvxyKHP+7fRvfi2yKOst7W72C0xse3KvrP2tO0NCiAgICoNCiAgICogQHBhcmFtIG1xDQogICAqIEBwYXJhbSBmcm9tU3RvcmUNCiAgICogQHJldHVybg0KICAgKi8NCiAgaW50NjQgZmV0Y2hDb25zdW1lT2Zmc2V0KGNvbnN0IE1RTWVzc2FnZVF1ZXVlJiBtcSwgYm9vbCBmcm9tU3RvcmUpOw0KICAvKioNCiAgICoguPm+3XRvcGlju/HIoU1lc3NhZ2VRdWV1ZaOs0tS++brit73KvdTa1+nE2rbguPazydSx1q685LfWxeQNCiAgICoNCiAgICogQHBhcmFtIHRvcGljDQogICAqICAgICAgICAgICAgz/vPolRvcGljDQogICAqIEByZXR1cm4gt7W72LbTwdC8r7rPDQogICAqLw0KICB2b2lkIGZldGNoTWVzc2FnZVF1ZXVlc0luQmFsYW5jZShjb25zdCBzdGQ6OnN0cmluZyYgdG9waWMsIHN0ZDo6dmVjdG9yPE1RTWVzc2FnZVF1ZXVlPiBtcXMpOw0KDQogIC8vIHRlbXAgcGVyc2lzdCBjb25zdW1lciBvZmZzZXQgaW50ZXJmYWNlLCBvbmx5IHZhbGlkIHdpdGgNCiAgLy8gUmVtb3RlQnJva2VyT2Zmc2V0U3RvcmUsIHVwZGF0ZUNvbnN1bWVPZmZzZXQgc2hvdWxkIGJlIGNhbGxlZCBiZWZvcmUuDQogIHZvaWQgcGVyc2lzdENvbnN1bWVyT2Zmc2V0NFB1bGxDb25zdW1lcihjb25zdCBNUU1lc3NhZ2VRdWV1ZSYgbXEpOw0KDQogcHJpdmF0ZToNCiAgdm9pZCBjaGVja0NvbmZpZygpOw0KICB2b2lkIGNvcHlTdWJzY3JpcHRpb24oKTsNCg0KICBQdWxsUmVzdWx0IHB1bGxTeW5jSW1wbChjb25zdCBNUU1lc3NhZ2VRdWV1ZSYgbXEsDQogICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHN0ZDo6c3RyaW5nJiBzdWJFeHByZXNzaW9uLA0KICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQ2NCBvZmZzZXQsDQogICAgICAgICAgICAgICAgICAgICAgICAgIGludCBtYXhOdW1zLA0KICAgICAgICAgICAgICAgICAgICAgICAgICBib29sIGJsb2NrKTsNCg0KICB2b2lkIHB1bGxBc3luY0ltcGwoY29uc3QgTVFNZXNzYWdlUXVldWUmIG1xLA0KICAgICAgICAgICAgICAgICAgICAgY29uc3Qgc3RkOjpzdHJpbmcmIHN1YkV4cHJlc3Npb24sDQogICAgICAgICAgICAgICAgICAgICBpbnQ2NCBvZmZzZXQsDQogICAgICAgICAgICAgICAgICAgICBpbnQgbWF4TnVtcywNCiAgICAgICAgICAgICAgICAgICAgIGJvb2wgYmxvY2ssDQogICAgICAgICAgICAgICAgICAgICBQdWxsQ2FsbGJhY2sqIHBQdWxsQ2FsbGJhY2spOw0KDQogIHZvaWQgc3Vic2NyaXB0aW9uQXV0b21hdGljYWxseShjb25zdCBzdGQ6OnN0cmluZyYgdG9waWMpOw0KDQogcHJpdmF0ZToNCiAgc3RkOjpzZXQ8c3RkOjpzdHJpbmc+IG1fcmVnaXN0ZXJUb3BpY3M7DQoNCiAgTVF1ZXVlTGlzdGVuZXIqIG1fcE1lc3NhZ2VRdWV1ZUxpc3RlbmVyOw0KICBPZmZzZXRTdG9yZSogbV9wT2Zmc2V0U3RvcmU7DQogIFJlYmFsYW5jZSogbV9wUmViYWxhbmNlOw0KICBQdWxsQVBJV3JhcHBlciogbV9wUHVsbEFQSVdyYXBwZXI7DQp9Ow0KLy88ISoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKg0KfSAgLy8gbmFtZXNwYWNlIHJvY2tldG1xDQojZW5kaWYNCg==