LyoNCiAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQ0KICogY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSBkaXN0cmlidXRlZCB3aXRoDQogKiB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuDQogKiBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSB0byBZb3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMA0KICogKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGgNCiAqIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0DQogKg0KICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMA0KICoNCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUNCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsDQogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4NCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQNCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLg0KICovDQoNCiNpZm5kZWYgX19ERUZBVUxUTVFQVUxMQ09OU1VNRVJfSF9fDQojZGVmaW5lIF9fREVGQVVMVE1RUFVMTENPTlNVTUVSX0hfXw0KDQojaW5jbHVkZSA8c2V0Pg0KI2luY2x1ZGUgPHN0cmluZz4NCiNpbmNsdWRlICJNUUNvbnN1bWVyLmgiDQojaW5jbHVkZSAiTVFNZXNzYWdlUXVldWUuaCINCiNpbmNsdWRlICJNUXVldWVMaXN0ZW5lci5oIg0KI2luY2x1ZGUgIlJvY2tldE1RQ2xpZW50LmgiDQoNCm5hbWVzcGFjZSByb2NrZXRtcSB7DQpjbGFzcyBSZWJhbGFuY2U7DQpjbGFzcyBTdWJzY3JpcHRpb25EYXRhOw0KY2xhc3MgT2Zmc2V0U3RvcmU7DQpjbGFzcyBQdWxsQVBJV3JhcHBlcjsNCmNsYXNzIENvbnN1bWVyUnVubmluZ0luZm87DQovLzwhKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqDQpjbGFzcyBST0NLRVRNUUNMSUVOVF9BUEkgRGVmYXVsdE1RUHVsbENvbnN1bWVyIDogcHVibGljIE1RQ29uc3VtZXIgew0KIHB1YmxpYzoNCiAgRGVmYXVsdE1RUHVsbENvbnN1bWVyKGNvbnN0IHN0ZDo6c3RyaW5nJiBncm91cG5hbWUpOw0KICB2aXJ0dWFsIH5EZWZhdWx0TVFQdWxsQ29uc3VtZXIoKTsNCg0KICAvLzwhYmVnaW4gbXFhZG1pbjsNCiAgdmlydHVhbCB2b2lkIHN0YXJ0KCk7DQogIHZpcnR1YWwgdm9pZCBzaHV0ZG93bigpOw0KICAvLzwhZW5kIG1xYWRtaW47DQoNCiAgLy88IWJlZ2luIE1RQ29uc3VtZXINCiAgdmlydHVhbCB2b2lkIHNlbmRNZXNzYWdlQmFjayhNUU1lc3NhZ2VFeHQmIG1zZywgaW50IGRlbGF5TGV2ZWwpOw0KICB2aXJ0dWFsIHZvaWQgZmV0Y2hTdWJzY3JpYmVNZXNzYWdlUXVldWVzKGNvbnN0IHN0ZDo6c3RyaW5nJiB0b3BpYywNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdGQ6OnZlY3RvcjxNUU1lc3NhZ2VRdWV1ZT4mIG1xcyk7DQogIHZpcnR1YWwgdm9pZCBkb1JlYmFsYW5jZSgpOw0KICB2aXJ0dWFsIHZvaWQgcGVyc2lzdENvbnN1bWVyT2Zmc2V0KCk7DQogIHZpcnR1YWwgdm9pZCBwZXJzaXN0Q29uc3VtZXJPZmZzZXRCeVJlc2V0T2Zmc2V0KCk7DQogIHZpcnR1YWwgdm9pZCB1cGRhdGVUb3BpY1N1YnNjcmliZUluZm8oY29uc3Qgc3RkOjpzdHJpbmcmIHRvcGljLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0ZDo6dmVjdG9yPE1RTWVzc2FnZVF1ZXVlPiYgaW5mbyk7DQogIHZpcnR1YWwgQ29uc3VtZVR5cGUgZ2V0Q29uc3VtZVR5cGUoKTsNCiAgdmlydHVhbCBDb25zdW1lRnJvbVdoZXJlIGdldENvbnN1bWVGcm9tV2hlcmUoKTsNCiAgdmlydHVhbCB2b2lkIGdldFN1YnNjcmlwdGlvbnMoc3RkOjp2ZWN0b3I8U3Vic2NyaXB0aW9uRGF0YT4mKTsNCiAgdmlydHVhbCB2b2lkIHVwZGF0ZUNvbnN1bWVPZmZzZXQoY29uc3QgTVFNZXNzYWdlUXVldWUmIG1xLCBpbnQ2NCBvZmZzZXQpOw0KICB2aXJ0dWFsIHZvaWQgcmVtb3ZlQ29uc3VtZU9mZnNldChjb25zdCBNUU1lc3NhZ2VRdWV1ZSYgbXEpOw0KICB2aXJ0dWFsIHZvaWQgcHJvZHVjZVB1bGxNc2dUYXNrKFB1bGxSZXF1ZXN0Kik7DQogIHZpcnR1YWwgUmViYWxhbmNlKiBnZXRSZWJhbGFuY2UoKSBjb25zdDsNCiAgLy88IWVuZCBNUUNvbnN1bWVyOw0KDQogIHZvaWQgcmVnaXN0ZXJNZXNzYWdlUXVldWVMaXN0ZW5lcihjb25zdCBzdGQ6OnN0cmluZyYgdG9waWMsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBNUXVldWVMaXN0ZW5lciogcExpc3RlbmVyKTsNCiAgLyoqDQogICogcHVsbCBtc2cgZnJvbSBzcGVjaWZpZWQgcXVldWUsIGlmIG5vIG1zZyBpbiBxdWV1ZSwgcmV0dXJuIGRpcmVjdGx5DQogICoNCiAgKiBAcGFyYW0gbXENCiAgKiAgICAgICAgICAgIHNwZWNpZnkgdGhlIHB1bGxlZCBxdWV1ZQ0KICAqIEBwYXJhbSBzdWJFeHByZXNzaW9uDQogICogICAgICAgICAgICBzZXQgZmlsdGVyIGV4cHJlc3Npb24gZm9yIHB1bGxlZCBtc2csIGJyb2tlciB3aWxsIGZpbHRlciBtc2cgYWN0aXZlbHkNCiAgKiAgICAgICAgICAgIE5vdyBvbmx5IE9SIG9wZXJhdGlvbiBpcyBzdXBwb3J0ZWQsIGVnOiAidGFnMSB8fCB0YWcyIHx8IHRhZzMiDQogICogICAgICAgICAgICBpZiBzdWJFeHByZXNzaW9uIGlzIHNldHRlZCB0byAibnVsbCIgb3IgIioio6xhbGwgbXNnIHdpbGwgYmUgc3Vic2NyaWJlZA0KICAqIEBwYXJhbSBvZmZzZXQNCiAgKiAgICAgICAgICAgIHNwZWNpZnkgdGhlIHN0YXJ0ZWQgcHVsbCBvZmZzZXQNCiAgKiBAcGFyYW0gbWF4TnVtcw0KICAqICAgICAgICAgICAgc3BlY2lmeSBtYXggbXNnIG51bSBieSBwZXIgcHVsbA0KICAqIEByZXR1cm4gIA0KICAqICAgICAgICAgICAgYWNjcm9kaW5nIHRvIFB1bGxSZXN1bHQNCiAgKi8NCiAgdmlydHVhbCBQdWxsUmVzdWx0IHB1bGwoY29uc3QgTVFNZXNzYWdlUXVldWUmIG1xLCBjb25zdCBzdGQ6OnN0cmluZyYgc3ViRXhwcmVzc2lvbiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgaW50NjQgb2Zmc2V0LCBpbnQgbWF4TnVtcyk7DQogIHZpcnR1YWwgdm9pZCBwdWxsKGNvbnN0IE1RTWVzc2FnZVF1ZXVlJiBtcSwgY29uc3Qgc3RkOjpzdHJpbmcmIHN1YkV4cHJlc3Npb24sDQogICAgICAgICAgICAgICAgICAgIGludDY0IG9mZnNldCwgaW50IG1heE51bXMsIFB1bGxDYWxsYmFjayogcFB1bGxDYWxsYmFjayk7DQoNCiAgLyoqDQogICogcHVsbCBtc2cgZnJvbSBzcGVjaWZpZWQgcXVldWUsIGlmIG5vIG1zZywgYnJva2VyIHdpbGwgc3VzcGVuZCB0aGUgcHVsbCByZXF1ZXN0IDIwcw0KICAqDQogICogQHBhcmFtIG1xDQogICogICAgICAgICAgICBzcGVjaWZ5IHRoZSBwdWxsZWQgcXVldWUNCiAgKiBAcGFyYW0gc3ViRXhwcmVzc2lvbg0KICAqICAgICAgICAgICAgc2V0IGZpbHRlciBleHByZXNzaW9uIGZvciBwdWxsZWQgbXNnLCBicm9rZXIgd2lsbCBmaWx0ZXIgbXNnIGFjdGl2ZWx5DQogICogICAgICAgICAgICBOb3cgb25seSBPUiBvcGVyYXRpb24gaXMgc3VwcG9ydGVkLCBlZzogInRhZzEgfHwgdGFnMiB8fCB0YWczIg0KICAqICAgICAgICAgICAgaWYgc3ViRXhwcmVzc2lvbiBpcyBzZXR0ZWQgdG8gIm51bGwiIG9yICIqIqOsYWxsIG1zZyB3aWxsIGJlIHN1YnNjcmliZWQNCiAgKiBAcGFyYW0gb2Zmc2V0DQogICogICAgICAgICAgICBzcGVjaWZ5IHRoZSBzdGFydGVkIHB1bGwgb2Zmc2V0DQogICogQHBhcmFtIG1heE51bXMNCiAgKiAgICAgICAgICAgIHNwZWNpZnkgbWF4IG1zZyBudW0gYnkgcGVyIHB1bGwNCiAgKiBAcmV0dXJuICANCiAgKiAgICAgICAgICAgIGFjY3JvZGluZyB0byBQdWxsUmVzdWx0DQogICovDQogIFB1bGxSZXN1bHQgcHVsbEJsb2NrSWZOb3RGb3VuZChjb25zdCBNUU1lc3NhZ2VRdWV1ZSYgbXEsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBzdGQ6OnN0cmluZyYgc3ViRXhwcmVzc2lvbiwgaW50NjQgb2Zmc2V0LA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50IG1heE51bXMpOw0KICB2b2lkIHB1bGxCbG9ja0lmTm90Rm91bmQoY29uc3QgTVFNZXNzYWdlUXVldWUmIG1xLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3Qgc3RkOjpzdHJpbmcmIHN1YkV4cHJlc3Npb24sIGludDY0IG9mZnNldCwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgIGludCBtYXhOdW1zLCBQdWxsQ2FsbGJhY2sqIHBQdWxsQ2FsbGJhY2spOw0KDQogIHZpcnR1YWwgQ29uc3VtZXJSdW5uaW5nSW5mbyogZ2V0Q29uc3VtZXJSdW5uaW5nSW5mbygpIHsgcmV0dXJuIE5VTEw7IH0NCiAgLyoqDQogICogu/HIoc/7t9G9+LbIo6y3tbvYLTGx7cq+s/a07Q0KICAqDQogICogQHBhcmFtIG1xDQogICogQHBhcmFtIGZyb21TdG9yZQ0KICAqIEByZXR1cm4NCiAgKi8NCiAgaW50NjQgZmV0Y2hDb25zdW1lT2Zmc2V0KGNvbnN0IE1RTWVzc2FnZVF1ZXVlJiBtcSwgYm9vbCBmcm9tU3RvcmUpOw0KICAvKioNCiAgKiC4+b7ddG9waWO78cihTWVzc2FnZVF1ZXVlo6zS1L75uuK3vcq91NrX6cTatuC49rPJ1LHWrrzkt9bF5A0KICAqDQogICogQHBhcmFtIHRvcGljDQogICogICAgICAgICAgICDP+8+iVG9waWMNCiAgKiBAcmV0dXJuILe1u9i208HQvK+6zw0KICAqLw0KICB2b2lkIGZldGNoTWVzc2FnZVF1ZXVlc0luQmFsYW5jZShjb25zdCBzdGQ6OnN0cmluZyYgdG9waWMsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0ZDo6dmVjdG9yPE1RTWVzc2FnZVF1ZXVlPiBtcXMpOw0KDQogIC8vIHRlbXAgcGVyc2lzdCBjb25zdW1lciBvZmZzZXQgaW50ZXJmYWNlLCBvbmx5IHZhbGlkIHdpdGgNCiAgLy8gUmVtb3RlQnJva2VyT2Zmc2V0U3RvcmUsIHVwZGF0ZUNvbnN1bWVPZmZzZXQgc2hvdWxkIGJlIGNhbGxlZCBiZWZvcmUuDQogIHZvaWQgcGVyc2lzdENvbnN1bWVyT2Zmc2V0NFB1bGxDb25zdW1lcihjb25zdCBNUU1lc3NhZ2VRdWV1ZSYgbXEpOw0KDQogcHJpdmF0ZToNCiAgdm9pZCBjaGVja0NvbmZpZygpOw0KICB2b2lkIGNvcHlTdWJzY3JpcHRpb24oKTsNCg0KICBQdWxsUmVzdWx0IHB1bGxTeW5jSW1wbChjb25zdCBNUU1lc3NhZ2VRdWV1ZSYgbXEsIGNvbnN0IHN0ZDo6c3RyaW5nJiBzdWJFeHByZXNzaW9uLA0KICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQ2NCBvZmZzZXQsIGludCBtYXhOdW1zLCBib29sIGJsb2NrKTsNCg0KICB2b2lkIHB1bGxBc3luY0ltcGwoY29uc3QgTVFNZXNzYWdlUXVldWUmIG1xLCBjb25zdCBzdGQ6OnN0cmluZyYgc3ViRXhwcmVzc2lvbiwNCiAgICAgICAgICAgICAgICAgICAgIGludDY0IG9mZnNldCwgaW50IG1heE51bXMsIGJvb2wgYmxvY2ssDQogICAgICAgICAgICAgICAgICAgICBQdWxsQ2FsbGJhY2sqIHBQdWxsQ2FsbGJhY2spOw0KDQogIHZvaWQgc3Vic2NyaXB0aW9uQXV0b21hdGljYWxseShjb25zdCBzdGQ6OnN0cmluZyYgdG9waWMpOw0KDQogcHJpdmF0ZToNCiAgc3RkOjpzZXQ8c3RkOjpzdHJpbmc+IG1fcmVnaXN0ZXJUb3BpY3M7DQoNCiAgTVF1ZXVlTGlzdGVuZXIqIG1fcE1lc3NhZ2VRdWV1ZUxpc3RlbmVyOw0KICBPZmZzZXRTdG9yZSogbV9wT2Zmc2V0U3RvcmU7DQogIFJlYmFsYW5jZSogbV9wUmViYWxhbmNlOw0KICBQdWxsQVBJV3JhcHBlciogbV9wUHVsbEFQSVdyYXBwZXI7DQp9Ow0KLy88ISoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKg0KfSAgLy88IWVuZCBuYW1lc3BhY2U7DQojZW5kaWYNCg==