Ly8NCi8vIENlIGZpY2hpZXIgYSDpdOkgZ+lu6XLpIHBhciBsJ2ltcGzpbWVudGF0aW9uIGRlIHLpZulyZW5jZSBKYXZhVE0gQXJjaGl0ZWN0dXJlIGZvciBYTUwgQmluZGluZyAoSkFYQiksIHYyLjIuOC1iMTMwOTExLjE4MDIgDQovLyBWb2lyIDxhIGhyZWY9Imh0dHA6Ly9qYXZhLnN1bi5jb20veG1sL2pheGIiPmh0dHA6Ly9qYXZhLnN1bi5jb20veG1sL2pheGI8L2E+IA0KLy8gVG91dGUgbW9kaWZpY2F0aW9uIGFwcG9ydOllIOAgY2UgZmljaGllciBzZXJhIHBlcmR1ZSBsb3JzIGRlIGxhIHJlY29tcGlsYXRpb24gZHUgc2No6W1hIHNvdXJjZS4gDQovLyBH6W7pcukgbGUgOiAyMDE3LjAzLjIxIOAgMDY6NTI6NDUgUE0gQ0VUIA0KLy8NCg0KDQpwYWNrYWdlIG9yZy5lY2xpcHNlLm9tMm0uY29tbW9ucy5yZXNvdXJjZTsNCg0KaW1wb3J0IGphdmEubWF0aC5CaWdJbnRlZ2VyOw0KaW1wb3J0IGphdmEudXRpbC5BcnJheUxpc3Q7DQppbXBvcnQgamF2YS51dGlsLkxpc3Q7DQoNCmltcG9ydCBqYXZheC54bWwuYmluZC5hbm5vdGF0aW9uLlhtbEFjY2Vzc1R5cGU7DQppbXBvcnQgamF2YXgueG1sLmJpbmQuYW5ub3RhdGlvbi5YbWxBY2Nlc3NvclR5cGU7DQppbXBvcnQgamF2YXgueG1sLmJpbmQuYW5ub3RhdGlvbi5YbWxFbGVtZW50Ow0KaW1wb3J0IGphdmF4LnhtbC5iaW5kLmFubm90YXRpb24uWG1sTGlzdDsNCmltcG9ydCBqYXZheC54bWwuYmluZC5hbm5vdGF0aW9uLlhtbFNjaGVtYVR5cGU7DQppbXBvcnQgamF2YXgueG1sLmJpbmQuYW5ub3RhdGlvbi5YbWxUeXBlOw0KaW1wb3J0IGphdmF4LnhtbC5iaW5kLmFubm90YXRpb24uYWRhcHRlcnMuQ29sbGFwc2VkU3RyaW5nQWRhcHRlcjsNCmltcG9ydCBqYXZheC54bWwuYmluZC5hbm5vdGF0aW9uLmFkYXB0ZXJzLlhtbEphdmFUeXBlQWRhcHRlcjsNCg0KDQovKioNCiAqIDxwPkNsYXNzZSBKYXZhIHBvdXIgcmVjZWl2ZXJFU1ByaW1SYW5kT2JqZWN0IGNvbXBsZXggdHlwZS4NCiAqIA0KICogPHA+TGUgZnJhZ21lbnQgZGUgc2No6W1hIHN1aXZhbnQgaW5kaXF1ZSBsZSBjb250ZW51IGF0dGVuZHUgZmlndXJhbnQgZGFucyBjZXR0ZSBjbGFzc2UuDQogKiANCiAqIDxwcmU+DQogKiAmbHQ7Y29tcGxleFR5cGUgbmFtZT0icmVjZWl2ZXJFU1ByaW1SYW5kT2JqZWN0Ij4NCiAqICAgJmx0O2NvbXBsZXhDb250ZW50Pg0KICogICAgICZsdDtyZXN0cmljdGlvbiBiYXNlPSJ7aHR0cDovL3d3dy53My5vcmcvMjAwMS9YTUxTY2hlbWF9YW55VHlwZSI+DQogKiAgICAgICAmbHQ7c2VxdWVuY2U+DQogKiAgICAgICAgICZsdDtlbGVtZW50IG5hbWU9ImVzcHJpbVJhbmRJRCIgdHlwZT0ie2h0dHA6Ly93d3cudzMub3JnLzIwMDEvWE1MU2NoZW1hfU5DTmFtZSIvPg0KICogICAgICAgICAmbHQ7ZWxlbWVudCBuYW1lPSJlc3ByaW1SYW5kVmFsdWUiIHR5cGU9IntodHRwOi8vd3d3LnczLm9yZy8yMDAxL1hNTFNjaGVtYX1OQ05hbWUiLz4NCiAqICAgICAgICAgJmx0O2VsZW1lbnQgbmFtZT0iZXNwcmltUmFuZEV4cGlyeSIgdHlwZT0ie2h0dHA6Ly93d3cub25lbTJtLm9yZy94bWwvcHJvdG9jb2xzfWFic1JlbFRpbWVzdGFtcCIvPg0KICogICAgICAgICAmbHQ7ZWxlbWVudCBuYW1lPSJlc3ByaW1LZXlHZW5BbGdJRHMiPg0KICogICAgICAgICAgICZsdDtzaW1wbGVUeXBlPg0KICogICAgICAgICAgICAgJmx0O3Jlc3RyaWN0aW9uPg0KICogICAgICAgICAgICAgICAmbHQ7c2ltcGxlVHlwZT4NCiAqICAgICAgICAgICAgICAgICAmbHQ7bGlzdCBpdGVtVHlwZT0ie2h0dHA6Ly93d3cub25lbTJtLm9yZy94bWwvcHJvdG9jb2xzfWVzcHJpbUtleUdlbkFsZ0lEIiAvPg0KICogICAgICAgICAgICAgICAmbHQ7L3NpbXBsZVR5cGU+DQogKiAgICAgICAgICAgICAgICZsdDttaW5MZW5ndGggdmFsdWU9IjEiLz4NCiAqICAgICAgICAgICAgICZsdDsvcmVzdHJpY3Rpb24+DQogKiAgICAgICAgICAgJmx0Oy9zaW1wbGVUeXBlPg0KICogICAgICAgICAmbHQ7L2VsZW1lbnQ+DQogKiAgICAgICAgICZsdDtlbGVtZW50IG5hbWU9ImVzcHJpbVByb3RvY29sQW5kQWxnSURzIj4NCiAqICAgICAgICAgICAmbHQ7c2ltcGxlVHlwZT4NCiAqICAgICAgICAgICAgICZsdDtyZXN0cmljdGlvbj4NCiAqICAgICAgICAgICAgICAgJmx0O3NpbXBsZVR5cGU+DQogKiAgICAgICAgICAgICAgICAgJmx0O2xpc3QgaXRlbVR5cGU9IntodHRwOi8vd3d3Lm9uZW0ybS5vcmcveG1sL3Byb3RvY29sc31lc3ByaW1Qcm90b2NvbEFuZEFsZ0lEIiAvPg0KICogICAgICAgICAgICAgICAmbHQ7L3NpbXBsZVR5cGU+DQogKiAgICAgICAgICAgICAgICZsdDttaW5MZW5ndGggdmFsdWU9IjEiLz4NCiAqICAgICAgICAgICAgICZsdDsvcmVzdHJpY3Rpb24+DQogKiAgICAgICAgICAgJmx0Oy9zaW1wbGVUeXBlPg0KICogICAgICAgICAmbHQ7L2VsZW1lbnQ+DQogKiAgICAgICAmbHQ7L3NlcXVlbmNlPg0KICogICAgICZsdDsvcmVzdHJpY3Rpb24+DQogKiAgICZsdDsvY29tcGxleENvbnRlbnQ+DQogKiAmbHQ7L2NvbXBsZXhUeXBlPg0KICogPC9wcmU+DQogKiANCiAqIA0KICovDQpAWG1sQWNjZXNzb3JUeXBlKFhtbEFjY2Vzc1R5cGUuRklFTEQpDQpAWG1sVHlwZShuYW1lID0gInJlY2VpdmVyRVNQcmltUmFuZE9iamVjdCIsIHByb3BPcmRlciA9IHsNCiAgICAiZXNwcmltUmFuZElEIiwNCiAgICAiZXNwcmltUmFuZFZhbHVlIiwNCiAgICAiZXNwcmltUmFuZEV4cGlyeSIsDQogICAgImVzcHJpbUtleUdlbkFsZ0lEcyIsDQogICAgImVzcHJpbVByb3RvY29sQW5kQWxnSURzIg0KfSkNCnB1YmxpYyBjbGFzcyBSZWNlaXZlckVTUHJpbVJhbmRPYmplY3Qgew0KDQogICAgQFhtbEVsZW1lbnQocmVxdWlyZWQgPSB0cnVlKQ0KICAgIEBYbWxKYXZhVHlwZUFkYXB0ZXIoQ29sbGFwc2VkU3RyaW5nQWRhcHRlci5jbGFzcykNCiAgICBAWG1sU2NoZW1hVHlwZShuYW1lID0gIk5DTmFtZSIpDQogICAgcHJvdGVjdGVkIFN0cmluZyBlc3ByaW1SYW5kSUQ7DQogICAgQFhtbEVsZW1lbnQocmVxdWlyZWQgPSB0cnVlKQ0KICAgIEBYbWxKYXZhVHlwZUFkYXB0ZXIoQ29sbGFwc2VkU3RyaW5nQWRhcHRlci5jbGFzcykNCiAgICBAWG1sU2NoZW1hVHlwZShuYW1lID0gIk5DTmFtZSIpDQogICAgcHJvdGVjdGVkIFN0cmluZyBlc3ByaW1SYW5kVmFsdWU7DQogICAgQFhtbEVsZW1lbnQocmVxdWlyZWQgPSB0cnVlKQ0KICAgIEBYbWxTY2hlbWFUeXBlKG5hbWUgPSAiYW55U2ltcGxlVHlwZSIpDQogICAgcHJvdGVjdGVkIFN0cmluZyBlc3ByaW1SYW5kRXhwaXJ5Ow0KICAgIEBYbWxMaXN0DQogICAgQFhtbEVsZW1lbnQocmVxdWlyZWQgPSB0cnVlKQ0KICAgIHByb3RlY3RlZCBMaXN0PEJpZ0ludGVnZXI+IGVzcHJpbUtleUdlbkFsZ0lEczsNCiAgICBAWG1sTGlzdA0KICAgIEBYbWxFbGVtZW50KHJlcXVpcmVkID0gdHJ1ZSkNCiAgICBwcm90ZWN0ZWQgTGlzdDxCaWdJbnRlZ2VyPiBlc3ByaW1Qcm90b2NvbEFuZEFsZ0lEczsNCg0KICAgIC8qKg0KICAgICAqIE9idGllbnQgbGEgdmFsZXVyIGRlIGxhIHByb3Byael06SBlc3ByaW1SYW5kSUQuDQogICAgICogDQogICAgICogQHJldHVybg0KICAgICAqICAgICBwb3NzaWJsZSBvYmplY3QgaXMNCiAgICAgKiAgICAge0BsaW5rIFN0cmluZyB9DQogICAgICogICAgIA0KICAgICAqLw0KICAgIHB1YmxpYyBTdHJpbmcgZ2V0RXNwcmltUmFuZElEKCkgew0KICAgICAgICByZXR1cm4gZXNwcmltUmFuZElEOw0KICAgIH0NCg0KICAgIC8qKg0KICAgICAqIETpZmluaXQgbGEgdmFsZXVyIGRlIGxhIHByb3Byael06SBlc3ByaW1SYW5kSUQuDQogICAgICogDQogICAgICogQHBhcmFtIHZhbHVlDQogICAgICogICAgIGFsbG93ZWQgb2JqZWN0IGlzDQogICAgICogICAgIHtAbGluayBTdHJpbmcgfQ0KICAgICAqICAgICANCiAgICAgKi8NCiAgICBwdWJsaWMgdm9pZCBzZXRFc3ByaW1SYW5kSUQoU3RyaW5nIHZhbHVlKSB7DQogICAgICAgIHRoaXMuZXNwcmltUmFuZElEID0gdmFsdWU7DQogICAgfQ0KDQogICAgLyoqDQogICAgICogT2J0aWVudCBsYSB2YWxldXIgZGUgbGEgcHJvcHJp6XTpIGVzcHJpbVJhbmRWYWx1ZS4NCiAgICAgKiANCiAgICAgKiBAcmV0dXJuDQogICAgICogICAgIHBvc3NpYmxlIG9iamVjdCBpcw0KICAgICAqICAgICB7QGxpbmsgU3RyaW5nIH0NCiAgICAgKiAgICAgDQogICAgICovDQogICAgcHVibGljIFN0cmluZyBnZXRFc3ByaW1SYW5kVmFsdWUoKSB7DQogICAgICAgIHJldHVybiBlc3ByaW1SYW5kVmFsdWU7DQogICAgfQ0KDQogICAgLyoqDQogICAgICogROlmaW5pdCBsYSB2YWxldXIgZGUgbGEgcHJvcHJp6XTpIGVzcHJpbVJhbmRWYWx1ZS4NCiAgICAgKiANCiAgICAgKiBAcGFyYW0gdmFsdWUNCiAgICAgKiAgICAgYWxsb3dlZCBvYmplY3QgaXMNCiAgICAgKiAgICAge0BsaW5rIFN0cmluZyB9DQogICAgICogICAgIA0KICAgICAqLw0KICAgIHB1YmxpYyB2b2lkIHNldEVzcHJpbVJhbmRWYWx1ZShTdHJpbmcgdmFsdWUpIHsNCiAgICAgICAgdGhpcy5lc3ByaW1SYW5kVmFsdWUgPSB2YWx1ZTsNCiAgICB9DQoNCiAgICAvKioNCiAgICAgKiBPYnRpZW50IGxhIHZhbGV1ciBkZSBsYSBwcm9wcmnpdOkgZXNwcmltUmFuZEV4cGlyeS4NCiAgICAgKiANCiAgICAgKiBAcmV0dXJuDQogICAgICogICAgIHBvc3NpYmxlIG9iamVjdCBpcw0KICAgICAqICAgICB7QGxpbmsgU3RyaW5nIH0NCiAgICAgKiAgICAgDQogICAgICovDQogICAgcHVibGljIFN0cmluZyBnZXRFc3ByaW1SYW5kRXhwaXJ5KCkgew0KICAgICAgICByZXR1cm4gZXNwcmltUmFuZEV4cGlyeTsNCiAgICB9DQoNCiAgICAvKioNCiAgICAgKiBE6WZpbml0IGxhIHZhbGV1ciBkZSBsYSBwcm9wcmnpdOkgZXNwcmltUmFuZEV4cGlyeS4NCiAgICAgKiANCiAgICAgKiBAcGFyYW0gdmFsdWUNCiAgICAgKiAgICAgYWxsb3dlZCBvYmplY3QgaXMNCiAgICAgKiAgICAge0BsaW5rIFN0cmluZyB9DQogICAgICogICAgIA0KICAgICAqLw0KICAgIHB1YmxpYyB2b2lkIHNldEVzcHJpbVJhbmRFeHBpcnkoU3RyaW5nIHZhbHVlKSB7DQogICAgICAgIHRoaXMuZXNwcmltUmFuZEV4cGlyeSA9IHZhbHVlOw0KICAgIH0NCg0KICAgIC8qKg0KICAgICAqIEdldHMgdGhlIHZhbHVlIG9mIHRoZSBlc3ByaW1LZXlHZW5BbGdJRHMgcHJvcGVydHkuDQogICAgICogDQogICAgICogPHA+DQogICAgICogVGhpcyBhY2Nlc3NvciBtZXRob2QgcmV0dXJucyBhIHJlZmVyZW5jZSB0byB0aGUgbGl2ZSBsaXN0LA0KICAgICAqIG5vdCBhIHNuYXBzaG90LiBUaGVyZWZvcmUgYW55IG1vZGlmaWNhdGlvbiB5b3UgbWFrZSB0byB0aGUNCiAgICAgKiByZXR1cm5lZCBsaXN0IHdpbGwgYmUgcHJlc2VudCBpbnNpZGUgdGhlIEpBWEIgb2JqZWN0Lg0KICAgICAqIFRoaXMgaXMgd2h5IHRoZXJlIGlzIG5vdCBhIDxDT0RFPnNldDwvQ09ERT4gbWV0aG9kIGZvciB0aGUgZXNwcmltS2V5R2VuQWxnSURzIHByb3BlcnR5Lg0KICAgICAqIA0KICAgICAqIDxwPg0KICAgICAqIEZvciBleGFtcGxlLCB0byBhZGQgYSBuZXcgaXRlbSwgZG8gYXMgZm9sbG93czoNCiAgICAgKiA8cHJlPg0KICAgICAqICAgIGdldEVzcHJpbUtleUdlbkFsZ0lEcygpLmFkZChuZXdJdGVtKTsNCiAgICAgKiA8L3ByZT4NCiAgICAgKiANCiAgICAgKiANCiAgICAgKiA8cD4NCiAgICAgKiBPYmplY3RzIG9mIHRoZSBmb2xsb3dpbmcgdHlwZShzKSBhcmUgYWxsb3dlZCBpbiB0aGUgbGlzdA0KICAgICAqIHtAbGluayBCaWdJbnRlZ2VyIH0NCiAgICAgKiANCiAgICAgKiANCiAgICAgKi8NCiAgICBwdWJsaWMgTGlzdDxCaWdJbnRlZ2VyPiBnZXRFc3ByaW1LZXlHZW5BbGdJRHMoKSB7DQogICAgICAgIGlmIChlc3ByaW1LZXlHZW5BbGdJRHMgPT0gbnVsbCkgew0KICAgICAgICAgICAgZXNwcmltS2V5R2VuQWxnSURzID0gbmV3IEFycmF5TGlzdDxCaWdJbnRlZ2VyPigpOw0KICAgICAgICB9DQogICAgICAgIHJldHVybiB0aGlzLmVzcHJpbUtleUdlbkFsZ0lEczsNCiAgICB9DQoNCiAgICAvKioNCiAgICAgKiBHZXRzIHRoZSB2YWx1ZSBvZiB0aGUgZXNwcmltUHJvdG9jb2xBbmRBbGdJRHMgcHJvcGVydHkuDQogICAgICogDQogICAgICogPHA+DQogICAgICogVGhpcyBhY2Nlc3NvciBtZXRob2QgcmV0dXJucyBhIHJlZmVyZW5jZSB0byB0aGUgbGl2ZSBsaXN0LA0KICAgICAqIG5vdCBhIHNuYXBzaG90LiBUaGVyZWZvcmUgYW55IG1vZGlmaWNhdGlvbiB5b3UgbWFrZSB0byB0aGUNCiAgICAgKiByZXR1cm5lZCBsaXN0IHdpbGwgYmUgcHJlc2VudCBpbnNpZGUgdGhlIEpBWEIgb2JqZWN0Lg0KICAgICAqIFRoaXMgaXMgd2h5IHRoZXJlIGlzIG5vdCBhIDxDT0RFPnNldDwvQ09ERT4gbWV0aG9kIGZvciB0aGUgZXNwcmltUHJvdG9jb2xBbmRBbGdJRHMgcHJvcGVydHkuDQogICAgICogDQogICAgICogPHA+DQogICAgICogRm9yIGV4YW1wbGUsIHRvIGFkZCBhIG5ldyBpdGVtLCBkbyBhcyBmb2xsb3dzOg0KICAgICAqIDxwcmU+DQogICAgICogICAgZ2V0RXNwcmltUHJvdG9jb2xBbmRBbGdJRHMoKS5hZGQobmV3SXRlbSk7DQogICAgICogPC9wcmU+DQogICAgICogDQogICAgICogDQogICAgICogPHA+DQogICAgICogT2JqZWN0cyBvZiB0aGUgZm9sbG93aW5nIHR5cGUocykgYXJlIGFsbG93ZWQgaW4gdGhlIGxpc3QNCiAgICAgKiB7QGxpbmsgQmlnSW50ZWdlciB9DQogICAgICogDQogICAgICogDQogICAgICovDQogICAgcHVibGljIExpc3Q8QmlnSW50ZWdlcj4gZ2V0RXNwcmltUHJvdG9jb2xBbmRBbGdJRHMoKSB7DQogICAgICAgIGlmIChlc3ByaW1Qcm90b2NvbEFuZEFsZ0lEcyA9PSBudWxsKSB7DQogICAgICAgICAgICBlc3ByaW1Qcm90b2NvbEFuZEFsZ0lEcyA9IG5ldyBBcnJheUxpc3Q8QmlnSW50ZWdlcj4oKTsNCiAgICAgICAgfQ0KICAgICAgICByZXR1cm4gdGhpcy5lc3ByaW1Qcm90b2NvbEFuZEFsZ0lEczsNCiAgICB9DQoNCn0NCg==