Ly8gTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSAgICoNCi8vIG9yIG1vcmUgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZSAqDQovLyBkaXN0cmlidXRlZCB3aXRoIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiAgICAgICAgKg0KLy8gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZSAgICoNCi8vIHRvIHlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgICAgICAgICAgICAqDQovLyAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlICAgKg0KLy8gd2l0aCB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdCAgICoNCi8vICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqDQovLyAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMCAgICAgICAgICAgICAgICAgKg0KLy8gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICoNCi8vIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgICAqDQovLyBzb2Z0d2FyZSBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAgKg0KLy8gIkFTIElTIiBCQVNJUywgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZICAgICAgICoNCi8vIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSAgICAqDQovLyBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kIGxpbWl0YXRpb25zICAgICAgKg0KLy8gdW5kZXIgdGhlIExpY2Vuc2UuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICoNCnVzaW5nIFN5c3RlbS5SZWZsZWN0aW9uOw0KdXNpbmcgU3lzdGVtLlJ1bnRpbWUuQ29tcGlsZXJTZXJ2aWNlczsNCg0KLy8NCi8vIEdlbmVyYWwgSW5mb3JtYXRpb24gYWJvdXQgYW4gYXNzZW1ibHkgaXMgY29udHJvbGxlZCB0aHJvdWdoIHRoZSBmb2xsb3dpbmcgDQovLyBzZXQgb2YgYXR0cmlidXRlcy4gQ2hhbmdlIHRoZXNlIGF0dHJpYnV0ZSB2YWx1ZXMgdG8gbW9kaWZ5IHRoZSBpbmZvcm1hdGlvbg0KLy8gYXNzb2NpYXRlZCB3aXRoIGFuIGFzc2VtYmx5Lg0KLy8NClthc3NlbWJseTogQXNzZW1ibHlUaXRsZSgiVmlzdWFsIFN0dWRpbyBQbHVnaW4gRm9yIEV0Y2giKV0NClthc3NlbWJseTogQXNzZW1ibHlEZXNjcmlwdGlvbigiVmlzdWFsIFN0dWRpbyBQbHVnaW4gRm9yIEV0Y2giKV0NClthc3NlbWJseTogQXNzZW1ibHlDb25maWd1cmF0aW9uKCIiKV0NClthc3NlbWJseTogQXNzZW1ibHlDb21wYW55KCJDaXNjbyBTeXN0ZW1zLCBJbmMiKV0NClthc3NlbWJseTogQXNzZW1ibHlQcm9kdWN0KCJFdGNoIildDQpbYXNzZW1ibHk6IEFzc2VtYmx5Q29weXJpZ2h0KCJDb3B5cmlnaHQgqSBDaXNjbyBTeXN0ZW1zIDIwMDgiKV0NClthc3NlbWJseTogQXNzZW1ibHlUcmFkZW1hcmsoIiIpXQ0KW2Fzc2VtYmx5OiBBc3NlbWJseUN1bHR1cmUoIiIpXQ0KDQovLw0KLy8gVmVyc2lvbiBpbmZvcm1hdGlvbiBmb3IgYW4gYXNzZW1ibHkgY29uc2lzdHMgb2YgdGhlIGZvbGxvd2luZyBmb3VyIHZhbHVlczoNCi8vDQovLyAgICAgIE1ham9yIFZlcnNpb24NCi8vICAgICAgTWlub3IgVmVyc2lvbiANCi8vICAgICAgUmV2aXNpb24NCi8vICAgICAgQnVpbGQgTnVtYmVyDQovLw0KLy8gWW91IGNhbiBzcGVjaWZ5IGFsbCB0aGUgdmFsdWUgb3IgeW91IGNhbiBkZWZhdWx0IHRoZSBSZXZpc2lvbiBhbmQgQnVpbGQgTnVtYmVycyANCi8vIGJ5IHVzaW5nIHRoZSAnKicgYXMgc2hvd24gYmVsb3c6DQoNClthc3NlbWJseTogQXNzZW1ibHlWZXJzaW9uKCIxLjAuKiIpXQ0KDQovLw0KLy8gSW4gb3JkZXIgdG8gc2lnbiB5b3VyIGFzc2VtYmx5IHlvdSBtdXN0IHNwZWNpZnkgYSBrZXkgdG8gdXNlLiBSZWZlciB0byB0aGUgDQovLyBNaWNyb3NvZnQgLk5FVCBGcmFtZXdvcmsgZG9jdW1lbnRhdGlvbiBmb3IgbW9yZSBpbmZvcm1hdGlvbiBvbiBhc3NlbWJseSBzaWduaW5nLg0KLy8NCi8vIFVzZSB0aGUgYXR0cmlidXRlcyBiZWxvdyB0byBjb250cm9sIHdoaWNoIGtleSBpcyB1c2VkIGZvciBzaWduaW5nLiANCi8vDQovLyBOb3RlczogDQovLyAgICgqKSBJZiBubyBrZXkgaXMgc3BlY2lmaWVkIC0gdGhlIGFzc2VtYmx5IGNhbm5vdCBiZSBzaWduZWQuDQovLyAgICgqKSBLZXlOYW1lIHJlZmVycyB0byBhIGtleSB0aGF0IGhhcyBiZWVuIGluc3RhbGxlZCBpbiB0aGUgQ3J5cHRvIFNlcnZpY2UNCi8vICAgICAgIFByb3ZpZGVyIChDU1ApIG9uIHlvdXIgbWFjaGluZS4gDQovLyAgICgqKSBJZiB0aGUga2V5IGZpbGUgYW5kIGEga2V5IG5hbWUgYXR0cmlidXRlcyBhcmUgYm90aCBzcGVjaWZpZWQsIHRoZSANCi8vICAgICAgIGZvbGxvd2luZyBwcm9jZXNzaW5nIG9jY3VyczoNCi8vICAgICAgICgxKSBJZiB0aGUgS2V5TmFtZSBjYW4gYmUgZm91bmQgaW4gdGhlIENTUCAtIHRoYXQga2V5IGlzIHVzZWQuDQovLyAgICAgICAoMikgSWYgdGhlIEtleU5hbWUgZG9lcyBub3QgZXhpc3QgYW5kIHRoZSBLZXlGaWxlIGRvZXMgZXhpc3QsIHRoZSBrZXkgDQovLyAgICAgICAgICAgaW4gdGhlIGZpbGUgaXMgaW5zdGFsbGVkIGludG8gdGhlIENTUCBhbmQgdXNlZC4NCi8vICAgKCopIERlbGF5IFNpZ25pbmcgaXMgYW4gYWR2YW5jZWQgb3B0aW9uIC0gc2VlIHRoZSBNaWNyb3NvZnQgLk5FVCBGcmFtZXdvcmsNCi8vICAgICAgIGRvY3VtZW50YXRpb24gZm9yIG1vcmUgaW5mb3JtYXRpb24gb24gdGhpcy4NCi8vDQpbYXNzZW1ibHk6IEFzc2VtYmx5RGVsYXlTaWduKGZhbHNlKV0NClthc3NlbWJseTogQXNzZW1ibHlLZXlGaWxlKCIiKV0NClthc3NlbWJseTogQXNzZW1ibHlLZXlOYW1lKCIiKV0NCg==