LyoNClRoZSBNSVQgTGljZW5zZQ0KDQpDb3B5cmlnaHQgKGMpIDIwMTAtMjAxNSBHb29nbGUsIEluYy4gaHR0cDovL2FuZ3VsYXJqcy5vcmcNCg0KUGVybWlzc2lvbiBpcyBoZXJlYnkgZ3JhbnRlZCwgZnJlZSBvZiBjaGFyZ2UsIHRvIGFueSBwZXJzb24gb2J0YWluaW5nIGEgY29weQ0Kb2YgdGhpcyBzb2Z0d2FyZSBhbmQgYXNzb2NpYXRlZCBkb2N1bWVudGF0aW9uIGZpbGVzICh0aGUgIlNvZnR3YXJlIiksIHRvIGRlYWwNCmluIHRoZSBTb2Z0d2FyZSB3aXRob3V0IHJlc3RyaWN0aW9uLCBpbmNsdWRpbmcgd2l0aG91dCBsaW1pdGF0aW9uIHRoZSByaWdodHMNCnRvIHVzZSwgY29weSwgbW9kaWZ5LCBtZXJnZSwgcHVibGlzaCwgZGlzdHJpYnV0ZSwgc3VibGljZW5zZSwgYW5kL29yIHNlbGwNCmNvcGllcyBvZiB0aGUgU29mdHdhcmUsIGFuZCB0byBwZXJtaXQgcGVyc29ucyB0byB3aG9tIHRoZSBTb2Z0d2FyZSBpcw0KZnVybmlzaGVkIHRvIGRvIHNvLCBzdWJqZWN0IHRvIHRoZSBmb2xsb3dpbmcgY29uZGl0aW9uczoNCg0KVGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UgYW5kIHRoaXMgcGVybWlzc2lvbiBub3RpY2Ugc2hhbGwgYmUgaW5jbHVkZWQgaW4NCmFsbCBjb3BpZXMgb3Igc3Vic3RhbnRpYWwgcG9ydGlvbnMgb2YgdGhlIFNvZnR3YXJlLg0KDQpUSEUgU09GVFdBUkUgSVMgUFJPVklERUQgIkFTIElTIiwgV0lUSE9VVCBXQVJSQU5UWSBPRiBBTlkgS0lORCwgRVhQUkVTUyBPUg0KSU1QTElFRCwgSU5DTFVESU5HIEJVVCBOT1QgTElNSVRFRCBUTyBUSEUgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFksDQpGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBTkQgTk9OSU5GUklOR0VNRU5ULiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUNCkFVVEhPUlMgT1IgQ09QWVJJR0hUIEhPTERFUlMgQkUgTElBQkxFIEZPUiBBTlkgQ0xBSU0sIERBTUFHRVMgT1IgT1RIRVINCkxJQUJJTElUWSwgV0hFVEhFUiBJTiBBTiBBQ1RJT04gT0YgQ09OVFJBQ1QsIFRPUlQgT1IgT1RIRVJXSVNFLCBBUklTSU5HIEZST00sDQpPVVQgT0YgT1IgSU4gQ09OTkVDVElPTiBXSVRIIFRIRSBTT0ZUV0FSRSBPUiBUSEUgVVNFIE9SIE9USEVSIERFQUxJTkdTIElODQpUSEUgU09GVFdBUkUuDQoqLw0KLyoqDQogKiBAbGljZW5zZSBBbmd1bGFySlMgdjEuMy44DQogKiAoYykgMjAxMC0yMDE0IEdvb2dsZSwgSW5jLiBodHRwOi8vYW5ndWxhcmpzLm9yZw0KICogTGljZW5zZTogTUlUDQogKi8NCihmdW5jdGlvbih3aW5kb3csIGFuZ3VsYXIsIHVuZGVmaW5lZCkgeyd1c2Ugc3RyaWN0JzsNCg0KLyoqDQogKiBAbmdkb2MgbW9kdWxlDQogKiBAbmFtZSBuZ1JvdXRlDQogKiBAZGVzY3JpcHRpb24NCiAqDQogKiAjIG5nUm91dGUNCiAqDQogKiBUaGUgYG5nUm91dGVgIG1vZHVsZSBwcm92aWRlcyByb3V0aW5nIGFuZCBkZWVwbGlua2luZyBzZXJ2aWNlcyBhbmQgZGlyZWN0aXZlcyBmb3IgYW5ndWxhciBhcHBzLg0KICoNCiAqICMjIEV4YW1wbGUNCiAqIFNlZSB7QGxpbmsgbmdSb3V0ZS4kcm91dGUjZXhhbXBsZSAkcm91dGV9IGZvciBhbiBleGFtcGxlIG9mIGNvbmZpZ3VyaW5nIGFuZCB1c2luZyBgbmdSb3V0ZWAuDQogKg0KICoNCiAqIDxkaXYgZG9jLW1vZHVsZS1jb21wb25lbnRzPSJuZ1JvdXRlIj48L2Rpdj4NCiAqLw0KIC8qIGdsb2JhbCAtbmdSb3V0ZU1vZHVsZSAqLw0KdmFyIG5nUm91dGVNb2R1bGUgPSBhbmd1bGFyLm1vZHVsZSgnbmdSb3V0ZScsIFsnbmcnXSkuDQogICAgICAgICAgICAgICAgICAgICAgICBwcm92aWRlcignJHJvdXRlJywgJFJvdXRlUHJvdmlkZXIpLA0KICAgICRyb3V0ZU1pbkVyciA9IGFuZ3VsYXIuJCRtaW5FcnIoJ25nUm91dGUnKTsNCg0KLyoqDQogKiBAbmdkb2MgcHJvdmlkZXINCiAqIEBuYW1lICRyb3V0ZVByb3ZpZGVyDQogKg0KICogQGRlc2NyaXB0aW9uDQogKg0KICogVXNlZCBmb3IgY29uZmlndXJpbmcgcm91dGVzLg0KICoNCiAqICMjIEV4YW1wbGUNCiAqIFNlZSB7QGxpbmsgbmdSb3V0ZS4kcm91dGUjZXhhbXBsZSAkcm91dGV9IGZvciBhbiBleGFtcGxlIG9mIGNvbmZpZ3VyaW5nIGFuZCB1c2luZyBgbmdSb3V0ZWAuDQogKg0KICogIyMgRGVwZW5kZW5jaWVzDQogKiBSZXF1aXJlcyB0aGUge0BsaW5rIG5nUm91dGUgYG5nUm91dGVgfSBtb2R1bGUgdG8gYmUgaW5zdGFsbGVkLg0KICovDQpmdW5jdGlvbiAkUm91dGVQcm92aWRlcigpIHsNCiAgZnVuY3Rpb24gaW5oZXJpdChwYXJlbnQsIGV4dHJhKSB7DQogICAgcmV0dXJuIGFuZ3VsYXIuZXh0ZW5kKE9iamVjdC5jcmVhdGUocGFyZW50KSwgZXh0cmEpOw0KICB9DQoNCiAgdmFyIHJvdXRlcyA9IHt9Ow0KDQogIC8qKg0KICAgKiBAbmdkb2MgbWV0aG9kDQogICAqIEBuYW1lICRyb3V0ZVByb3ZpZGVyI3doZW4NCiAgICoNCiAgICogQHBhcmFtIHtzdHJpbmd9IHBhdGggUm91dGUgcGF0aCAobWF0Y2hlZCBhZ2FpbnN0IGAkbG9jYXRpb24ucGF0aGApLiBJZiBgJGxvY2F0aW9uLnBhdGhgDQogICAqICAgIGNvbnRhaW5zIHJlZHVuZGFudCB0cmFpbGluZyBzbGFzaCBvciBpcyBtaXNzaW5nIG9uZSwgdGhlIHJvdXRlIHdpbGwgc3RpbGwgbWF0Y2ggYW5kIHRoZQ0KICAgKiAgICBgJGxvY2F0aW9uLnBhdGhgIHdpbGwgYmUgdXBkYXRlZCB0byBhZGQgb3IgZHJvcCB0aGUgdHJhaWxpbmcgc2xhc2ggdG8gZXhhY3RseSBtYXRjaCB0aGUNCiAgICogICAgcm91dGUgZGVmaW5pdGlvbi4NCiAgICoNCiAgICogICAgKiBgcGF0aGAgY2FuIGNvbnRhaW4gbmFtZWQgZ3JvdXBzIHN0YXJ0aW5nIHdpdGggYSBjb2xvbjogZS5nLiBgOm5hbWVgLiBBbGwgY2hhcmFjdGVycyB1cA0KICAgKiAgICAgICAgdG8gdGhlIG5leHQgc2xhc2ggYXJlIG1hdGNoZWQgYW5kIHN0b3JlZCBpbiBgJHJvdXRlUGFyYW1zYCB1bmRlciB0aGUgZ2l2ZW4gYG5hbWVgDQogICAqICAgICAgICB3aGVuIHRoZSByb3V0ZSBtYXRjaGVzLg0KICAgKiAgICAqIGBwYXRoYCBjYW4gY29udGFpbiBuYW1lZCBncm91cHMgc3RhcnRpbmcgd2l0aCBhIGNvbG9uIGFuZCBlbmRpbmcgd2l0aCBhIHN0YXI6DQogICAqICAgICAgICBlLmcuYDpuYW1lKmAuIEFsbCBjaGFyYWN0ZXJzIGFyZSBlYWdlcmx5IHN0b3JlZCBpbiBgJHJvdXRlUGFyYW1zYCB1bmRlciB0aGUgZ2l2ZW4gYG5hbWVgDQogICAqICAgICAgICB3aGVuIHRoZSByb3V0ZSBtYXRjaGVzLg0KICAgKiAgICAqIGBwYXRoYCBjYW4gY29udGFpbiBvcHRpb25hbCBuYW1lZCBncm91cHMgd2l0aCBhIHF1ZXN0aW9uIG1hcms6IGUuZy5gOm5hbWU/YC4NCiAgICoNCiAgICogICAgRm9yIGV4YW1wbGUsIHJvdXRlcyBsaWtlIGAvY29sb3IvOmNvbG9yL2xhcmdlY29kZS86bGFyZ2Vjb2RlKlwvZWRpdGAgd2lsbCBtYXRjaA0KICAgKiAgICBgL2NvbG9yL2Jyb3duL2xhcmdlY29kZS9jb2RlL3dpdGgvc2xhc2hlcy9lZGl0YCBhbmQgZXh0cmFjdDoNCiAgICoNCiAgICogICAgKiBgY29sb3I6IGJyb3duYA0KICAgKiAgICAqIGBsYXJnZWNvZGU6IGNvZGUvd2l0aC9zbGFzaGVzYC4NCiAgICoNCiAgICoNCiAgICogQHBhcmFtIHtPYmplY3R9IHJvdXRlIE1hcHBpbmcgaW5mb3JtYXRpb24gdG8gYmUgYXNzaWduZWQgdG8gYCRyb3V0ZS5jdXJyZW50YCBvbiByb3V0ZQ0KICAgKiAgICBtYXRjaC4NCiAgICoNCiAgICogICAgT2JqZWN0IHByb3BlcnRpZXM6DQogICAqDQogICAqICAgIC0gYGNvbnRyb2xsZXJgIOKAPyBgeyhzdHJpbmd8ZnVuY3Rpb24oKT19YCDigD8gQ29udHJvbGxlciBmbiB0aGF0IHNob3VsZCBiZSBhc3NvY2lhdGVkIHdpdGgNCiAgICogICAgICBuZXdseSBjcmVhdGVkIHNjb3BlIG9yIHRoZSBuYW1lIG9mIGEge0BsaW5rIGFuZ3VsYXIuTW9kdWxlI2NvbnRyb2xsZXIgcmVnaXN0ZXJlZA0KICAgKiAgICAgIGNvbnRyb2xsZXJ9IGlmIHBhc3NlZCBhcyBhIHN0cmluZy4NCiAgICogICAgLSBgY29udHJvbGxlckFzYCDigD8gYHtzdHJpbmc9fWAg4oA/IEEgY29udHJvbGxlciBhbGlhcyBuYW1lLiBJZiBwcmVzZW50IHRoZSBjb250cm9sbGVyIHdpbGwgYmUNCiAgICogICAgICBwdWJsaXNoZWQgdG8gc2NvcGUgdW5kZXIgdGhlIGBjb250cm9sbGVyQXNgIG5hbWUuDQogICAqICAgIC0gYHRlbXBsYXRlYCDigD8gYHtzdHJpbmc9fGZ1bmN0aW9uKCk9fWAg4oA/IGh0bWwgdGVtcGxhdGUgYXMgYSBzdHJpbmcgb3IgYSBmdW5jdGlvbiB0aGF0DQogICAqICAgICAgcmV0dXJucyBhbiBodG1sIHRlbXBsYXRlIGFzIGEgc3RyaW5nIHdoaWNoIHNob3VsZCBiZSB1c2VkIGJ5IHtAbGluaw0KICAgKiAgICAgIG5nUm91dGUuZGlyZWN0aXZlOm5nVmlldyBuZ1ZpZXd9IG9yIHtAbGluayBuZy5kaXJlY3RpdmU6bmdJbmNsdWRlIG5nSW5jbHVkZX0gZGlyZWN0aXZlcy4NCiAgICogICAgICBUaGlzIHByb3BlcnR5IHRha2VzIHByZWNlZGVuY2Ugb3ZlciBgdGVtcGxhdGVVcmxgLg0KICAgKg0KICAgKiAgICAgIElmIGB0ZW1wbGF0ZWAgaXMgYSBmdW5jdGlvbiwgaXQgd2lsbCBiZSBjYWxsZWQgd2l0aCB0aGUgZm9sbG93aW5nIHBhcmFtZXRlcnM6DQogICAqDQogICAqICAgICAgLSBge0FycmF5LjxPYmplY3Q+fWAgLSByb3V0ZSBwYXJhbWV0ZXJzIGV4dHJhY3RlZCBmcm9tIHRoZSBjdXJyZW50DQogICAqICAgICAgICBgJGxvY2F0aW9uLnBhdGgoKWAgYnkgYXBwbHlpbmcgdGhlIGN1cnJlbnQgcm91dGUNCiAgICoNCiAgICogICAgLSBgdGVtcGxhdGVVcmxgIOKAPyBge3N0cmluZz18ZnVuY3Rpb24oKT19YCDigD8gcGF0aCBvciBmdW5jdGlvbiB0aGF0IHJldHVybnMgYSBwYXRoIHRvIGFuIGh0bWwNCiAgICogICAgICB0ZW1wbGF0ZSB0aGF0IHNob3VsZCBiZSB1c2VkIGJ5IHtAbGluayBuZ1JvdXRlLmRpcmVjdGl2ZTpuZ1ZpZXcgbmdWaWV3fS4NCiAgICoNCiAgICogICAgICBJZiBgdGVtcGxhdGVVcmxgIGlzIGEgZnVuY3Rpb24sIGl0IHdpbGwgYmUgY2FsbGVkIHdpdGggdGhlIGZvbGxvd2luZyBwYXJhbWV0ZXJzOg0KICAgKg0KICAgKiAgICAgIC0gYHtBcnJheS48T2JqZWN0Pn1gIC0gcm91dGUgcGFyYW1ldGVycyBleHRyYWN0ZWQgZnJvbSB0aGUgY3VycmVudA0KICAgKiAgICAgICAgYCRsb2NhdGlvbi5wYXRoKClgIGJ5IGFwcGx5aW5nIHRoZSBjdXJyZW50IHJvdXRlDQogICAqDQogICAqICAgIC0gYHJlc29sdmVgIC0gYHtPYmplY3QuPHN0cmluZywgZnVuY3Rpb24+PX1gIC0gQW4gb3B0aW9uYWwgbWFwIG9mIGRlcGVuZGVuY2llcyB3aGljaCBzaG91bGQNCiAgICogICAgICBiZSBpbmplY3RlZCBpbnRvIHRoZSBjb250cm9sbGVyLiBJZiBhbnkgb2YgdGhlc2UgZGVwZW5kZW5jaWVzIGFyZSBwcm9taXNlcywgdGhlIHJvdXRlcg0KICAgKiAgICAgIHdpbGwgd2FpdCBmb3IgdGhlbSBhbGwgdG8gYmUgcmVzb2x2ZWQgb3Igb25lIHRvIGJlIHJlamVjdGVkIGJlZm9yZSB0aGUgY29udHJvbGxlciBpcw0KICAgKiAgICAgIGluc3RhbnRpYXRlZC4NCiAgICogICAgICBJZiBhbGwgdGhlIHByb21pc2VzIGFyZSByZXNvbHZlZCBzdWNjZXNzZnVsbHksIHRoZSB2YWx1ZXMgb2YgdGhlIHJlc29sdmVkIHByb21pc2VzIGFyZQ0KICAgKiAgICAgIGluamVjdGVkIGFuZCB7QGxpbmsgbmdSb3V0ZS4kcm91dGUjJHJvdXRlQ2hhbmdlU3VjY2VzcyAkcm91dGVDaGFuZ2VTdWNjZXNzfSBldmVudCBpcw0KICAgKiAgICAgIGZpcmVkLiBJZiBhbnkgb2YgdGhlIHByb21pc2VzIGFyZSByZWplY3RlZCB0aGUNCiAgICogICAgICB7QGxpbmsgbmdSb3V0ZS4kcm91dGUjJHJvdXRlQ2hhbmdlRXJyb3IgJHJvdXRlQ2hhbmdlRXJyb3J9IGV2ZW50IGlzIGZpcmVkLiBUaGUgbWFwIG9iamVjdA0KICAgKiAgICAgIGlzOg0KICAgKg0KICAgKiAgICAgIC0gYGtleWAg4oA/IGB7c3RyaW5nfWA6IGEgbmFtZSBvZiBhIGRlcGVuZGVuY3kgdG8gYmUgaW5qZWN0ZWQgaW50byB0aGUgY29udHJvbGxlci4NCiAgICogICAgICAtIGBmYWN0b3J5YCAtIGB7c3RyaW5nfGZ1bmN0aW9ufWA6IElmIGBzdHJpbmdgIHRoZW4gaXQgaXMgYW4gYWxpYXMgZm9yIGEgc2VydmljZS4NCiAgICogICAgICAgIE90aGVyd2lzZSBpZiBmdW5jdGlvbiwgdGhlbiBpdCBpcyB7QGxpbmsgYXV0by4kaW5qZWN0b3IjaW52b2tlIGluamVjdGVkfQ0KICAgKiAgICAgICAgYW5kIHRoZSByZXR1cm4gdmFsdWUgaXMgdHJlYXRlZCBhcyB0aGUgZGVwZW5kZW5jeS4gSWYgdGhlIHJlc3VsdCBpcyBhIHByb21pc2UsIGl0IGlzDQogICAqICAgICAgICByZXNvbHZlZCBiZWZvcmUgaXRzIHZhbHVlIGlzIGluamVjdGVkIGludG8gdGhlIGNvbnRyb2xsZXIuIEJlIGF3YXJlIHRoYXQNCiAgICogICAgICAgIGBuZ1JvdXRlLiRyb3V0ZVBhcmFtc2Agd2lsbCBzdGlsbCByZWZlciB0byB0aGUgcHJldmlvdXMgcm91dGUgd2l0aGluIHRoZXNlIHJlc29sdmUNCiAgICogICAgICAgIGZ1bmN0aW9ucy4gIFVzZSBgJHJvdXRlLmN1cnJlbnQucGFyYW1zYCB0byBhY2Nlc3MgdGhlIG5ldyByb3V0ZSBwYXJhbWV0ZXJzLCBpbnN0ZWFkLg0KICAgKg0KICAgKiAgICAtIGByZWRpcmVjdFRvYCDigD8geyhzdHJpbmd8ZnVuY3Rpb24oKSk9fSDigD8gdmFsdWUgdG8gdXBkYXRlDQogICAqICAgICAge0BsaW5rIG5nLiRsb2NhdGlvbiAkbG9jYXRpb259IHBhdGggd2l0aCBhbmQgdHJpZ2dlciByb3V0ZSByZWRpcmVjdGlvbi4NCiAgICoNCiAgICogICAgICBJZiBgcmVkaXJlY3RUb2AgaXMgYSBmdW5jdGlvbiwgaXQgd2lsbCBiZSBjYWxsZWQgd2l0aCB0aGUgZm9sbG93aW5nIHBhcmFtZXRlcnM6DQogICAqDQogICAqICAgICAgLSBge09iamVjdC48c3RyaW5nPn1gIC0gcm91dGUgcGFyYW1ldGVycyBleHRyYWN0ZWQgZnJvbSB0aGUgY3VycmVudA0KICAgKiAgICAgICAgYCRsb2NhdGlvbi5wYXRoKClgIGJ5IGFwcGx5aW5nIHRoZSBjdXJyZW50IHJvdXRlIHRlbXBsYXRlVXJsLg0KICAgKiAgICAgIC0gYHtzdHJpbmd9YCAtIGN1cnJlbnQgYCRsb2NhdGlvbi5wYXRoKClgDQogICAqICAgICAgLSBge09iamVjdH1gIC0gY3VycmVudCBgJGxvY2F0aW9uLnNlYXJjaCgpYA0KICAgKg0KICAgKiAgICAgIFRoZSBjdXN0b20gYHJlZGlyZWN0VG9gIGZ1bmN0aW9uIGlzIGV4cGVjdGVkIHRvIHJldHVybiBhIHN0cmluZyB3aGljaCB3aWxsIGJlIHVzZWQNCiAgICogICAgICB0byB1cGRhdGUgYCRsb2NhdGlvbi5wYXRoKClgIGFuZCBgJGxvY2F0aW9uLnNlYXJjaCgpYC4NCiAgICoNCiAgICogICAgLSBgW3JlbG9hZE9uU2VhcmNoPXRydWVdYCAtIHtib29sZWFuPX0gLSByZWxvYWQgcm91dGUgd2hlbiBvbmx5IGAkbG9jYXRpb24uc2VhcmNoKClgDQogICAqICAgICAgb3IgYCRsb2NhdGlvbi5oYXNoKClgIGNoYW5nZXMuDQogICAqDQogICAqICAgICAgSWYgdGhlIG9wdGlvbiBpcyBzZXQgdG8gYGZhbHNlYCBhbmQgdXJsIGluIHRoZSBicm93c2VyIGNoYW5nZXMsIHRoZW4NCiAgICogICAgICBgJHJvdXRlVXBkYXRlYCBldmVudCBpcyBicm9hZGNhc3RlZCBvbiB0aGUgcm9vdCBzY29wZS4NCiAgICoNCiAgICogICAgLSBgW2Nhc2VJbnNlbnNpdGl2ZU1hdGNoPWZhbHNlXWAgLSB7Ym9vbGVhbj19IC0gbWF0Y2ggcm91dGVzIHdpdGhvdXQgYmVpbmcgY2FzZSBzZW5zaXRpdmUNCiAgICoNCiAgICogICAgICBJZiB0aGUgb3B0aW9uIGlzIHNldCB0byBgdHJ1ZWAsIHRoZW4gdGhlIHBhcnRpY3VsYXIgcm91dGUgY2FuIGJlIG1hdGNoZWQgd2l0aG91dCBiZWluZw0KICAgKiAgICAgIGNhc2Ugc2Vuc2l0aXZlDQogICAqDQogICAqIEByZXR1cm5zIHtPYmplY3R9IHNlbGYNCiAgICoNCiAgICogQGRlc2NyaXB0aW9uDQogICAqIEFkZHMgYSBuZXcgcm91dGUgZGVmaW5pdGlvbiB0byB0aGUgYCRyb3V0ZWAgc2VydmljZS4NCiAgICovDQogIHRoaXMud2hlbiA9IGZ1bmN0aW9uKHBhdGgsIHJvdXRlKSB7DQogICAgLy9jb3B5IG9yaWdpbmFsIHJvdXRlIG9iamVjdCB0byBwcmVzZXJ2ZSBwYXJhbXMgaW5oZXJpdGVkIGZyb20gcHJvdG8gY2hhaW4NCiAgICB2YXIgcm91dGVDb3B5ID0gYW5ndWxhci5jb3B5KHJvdXRlKTsNCiAgICBpZiAoYW5ndWxhci5pc1VuZGVmaW5lZChyb3V0ZUNvcHkucmVsb2FkT25TZWFyY2gpKSB7DQogICAgICByb3V0ZUNvcHkucmVsb2FkT25TZWFyY2ggPSB0cnVlOw0KICAgIH0NCiAgICBpZiAoYW5ndWxhci5pc1VuZGVmaW5lZChyb3V0ZUNvcHkuY2FzZUluc2Vuc2l0aXZlTWF0Y2gpKSB7DQogICAgICByb3V0ZUNvcHkuY2FzZUluc2Vuc2l0aXZlTWF0Y2ggPSB0aGlzLmNhc2VJbnNlbnNpdGl2ZU1hdGNoOw0KICAgIH0NCiAgICByb3V0ZXNbcGF0aF0gPSBhbmd1bGFyLmV4dGVuZCgNCiAgICAgIHJvdXRlQ29weSwNCiAgICAgIHBhdGggJiYgcGF0aFJlZ0V4cChwYXRoLCByb3V0ZUNvcHkpDQogICAgKTsNCg0KICAgIC8vIGNyZWF0ZSByZWRpcmVjdGlvbiBmb3IgdHJhaWxpbmcgc2xhc2hlcw0KICAgIGlmIChwYXRoKSB7DQogICAgICB2YXIgcmVkaXJlY3RQYXRoID0gKHBhdGhbcGF0aC5sZW5ndGggLSAxXSA9PSAnLycpDQogICAgICAgICAgICA/IHBhdGguc3Vic3RyKDAsIHBhdGgubGVuZ3RoIC0gMSkNCiAgICAgICAgICAgIDogcGF0aCArICcvJzsNCg0KICAgICAgcm91dGVzW3JlZGlyZWN0UGF0aF0gPSBhbmd1bGFyLmV4dGVuZCgNCiAgICAgICAge3JlZGlyZWN0VG86IHBhdGh9LA0KICAgICAgICBwYXRoUmVnRXhwKHJlZGlyZWN0UGF0aCwgcm91dGVDb3B5KQ0KICAgICAgKTsNCiAgICB9DQoNCiAgICByZXR1cm4gdGhpczsNCiAgfTsNCg0KICAvKioNCiAgICogQG5nZG9jIHByb3BlcnR5DQogICAqIEBuYW1lICRyb3V0ZVByb3ZpZGVyI2Nhc2VJbnNlbnNpdGl2ZU1hdGNoDQogICAqIEBkZXNjcmlwdGlvbg0KICAgKg0KICAgKiBBIGJvb2xlYW4gcHJvcGVydHkgaW5kaWNhdGluZyBpZiByb3V0ZXMgZGVmaW5lZA0KICAgKiB1c2luZyB0aGlzIHByb3ZpZGVyIHNob3VsZCBiZSBtYXRjaGVkIHVzaW5nIGEgY2FzZSBpbnNlbnNpdGl2ZQ0KICAgKiBhbGdvcml0aG0uIERlZmF1bHRzIHRvIGBmYWxzZWAuDQogICAqLw0KICB0aGlzLmNhc2VJbnNlbnNpdGl2ZU1hdGNoID0gZmFsc2U7DQoNCiAgIC8qKg0KICAgICogQHBhcmFtIHBhdGgge3N0cmluZ30gcGF0aA0KICAgICogQHBhcmFtIG9wdHMge09iamVjdH0gb3B0aW9ucw0KICAgICogQHJldHVybiB7P09iamVjdH0NCiAgICAqDQogICAgKiBAZGVzY3JpcHRpb24NCiAgICAqIE5vcm1hbGl6ZXMgdGhlIGdpdmVuIHBhdGgsIHJldHVybmluZyBhIHJlZ3VsYXIgZXhwcmVzc2lvbg0KICAgICogYW5kIHRoZSBvcmlnaW5hbCBwYXRoLg0KICAgICoNCiAgICAqIEluc3BpcmVkIGJ5IHBhdGhSZXhwIGluIHZpc2lvbm1lZGlhL2V4cHJlc3MvbGliL3V0aWxzLmpzLg0KICAgICovDQogIGZ1bmN0aW9uIHBhdGhSZWdFeHAocGF0aCwgb3B0cykgew0KICAgIHZhciBpbnNlbnNpdGl2ZSA9IG9wdHMuY2FzZUluc2Vuc2l0aXZlTWF0Y2gsDQogICAgICAgIHJldCA9IHsNCiAgICAgICAgICBvcmlnaW5hbFBhdGg6IHBhdGgsDQogICAgICAgICAgcmVnZXhwOiBwYXRoDQogICAgICAgIH0sDQogICAgICAgIGtleXMgPSByZXQua2V5cyA9IFtdOw0KDQogICAgcGF0aCA9IHBhdGgNCiAgICAgIC5yZXBsYWNlKC8oWygpLl0pL2csICdcXCQxJykNCiAgICAgIC5yZXBsYWNlKC8oXC8pPzooXHcrKShbXD9cKl0pPy9nLCBmdW5jdGlvbihfLCBzbGFzaCwga2V5LCBvcHRpb24pIHsNCiAgICAgICAgdmFyIG9wdGlvbmFsID0gb3B0aW9uID09PSAnPycgPyBvcHRpb24gOiBudWxsOw0KICAgICAgICB2YXIgc3RhciA9IG9wdGlvbiA9PT0gJyonID8gb3B0aW9uIDogbnVsbDsNCiAgICAgICAga2V5cy5wdXNoKHsgbmFtZToga2V5LCBvcHRpb25hbDogISFvcHRpb25hbCB9KTsNCiAgICAgICAgc2xhc2ggPSBzbGFzaCB8fCAnJzsNCiAgICAgICAgcmV0dXJuICcnDQogICAgICAgICAgKyAob3B0aW9uYWwgPyAnJyA6IHNsYXNoKQ0KICAgICAgICAgICsgJyg/OicNCiAgICAgICAgICArIChvcHRpb25hbCA/IHNsYXNoIDogJycpDQogICAgICAgICAgKyAoc3RhciAmJiAnKC4rPyknIHx8ICcoW14vXSspJykNCiAgICAgICAgICArIChvcHRpb25hbCB8fCAnJykNCiAgICAgICAgICArICcpJw0KICAgICAgICAgICsgKG9wdGlvbmFsIHx8ICcnKTsNCiAgICAgIH0pDQogICAgICAucmVwbGFjZSgvKFtcLyRcKl0pL2csICdcXCQxJyk7DQoNCiAgICByZXQucmVnZXhwID0gbmV3IFJlZ0V4cCgnXicgKyBwYXRoICsgJyQnLCBpbnNlbnNpdGl2ZSA/ICdpJyA6ICcnKTsNCiAgICByZXR1cm4gcmV0Ow0KICB9DQoNCiAgLyoqDQogICAqIEBuZ2RvYyBtZXRob2QNCiAgICogQG5hbWUgJHJvdXRlUHJvdmlkZXIjb3RoZXJ3aXNlDQogICAqDQogICAqIEBkZXNjcmlwdGlvbg0KICAgKiBTZXRzIHJvdXRlIGRlZmluaXRpb24gdGhhdCB3aWxsIGJlIHVzZWQgb24gcm91dGUgY2hhbmdlIHdoZW4gbm8gb3RoZXIgcm91dGUgZGVmaW5pdGlvbg0KICAgKiBpcyBtYXRjaGVkLg0KICAgKg0KICAgKiBAcGFyYW0ge09iamVjdHxzdHJpbmd9IHBhcmFtcyBNYXBwaW5nIGluZm9ybWF0aW9uIHRvIGJlIGFzc2lnbmVkIHRvIGAkcm91dGUuY3VycmVudGAuDQogICAqIElmIGNhbGxlZCB3aXRoIGEgc3RyaW5nLCB0aGUgdmFsdWUgbWFwcyB0byBgcmVkaXJlY3RUb2AuDQogICAqIEByZXR1cm5zIHtPYmplY3R9IHNlbGYNCiAgICovDQogIHRoaXMub3RoZXJ3aXNlID0gZnVuY3Rpb24ocGFyYW1zKSB7DQogICAgaWYgKHR5cGVvZiBwYXJhbXMgPT09ICdzdHJpbmcnKSB7DQogICAgICBwYXJhbXMgPSB7cmVkaXJlY3RUbzogcGFyYW1zfTsNCiAgICB9DQogICAgdGhpcy53aGVuKG51bGwsIHBhcmFtcyk7DQogICAgcmV0dXJuIHRoaXM7DQogIH07DQoNCg0KICB0aGlzLiRnZXQgPSBbJyRyb290U2NvcGUnLA0KICAgICAgICAgICAgICAgJyRsb2NhdGlvbicsDQogICAgICAgICAgICAgICAnJHJvdXRlUGFyYW1zJywNCiAgICAgICAgICAgICAgICckcScsDQogICAgICAgICAgICAgICAnJGluamVjdG9yJywNCiAgICAgICAgICAgICAgICckdGVtcGxhdGVSZXF1ZXN0JywNCiAgICAgICAgICAgICAgICckc2NlJywNCiAgICAgIGZ1bmN0aW9uKCRyb290U2NvcGUsICRsb2NhdGlvbiwgJHJvdXRlUGFyYW1zLCAkcSwgJGluamVjdG9yLCAkdGVtcGxhdGVSZXF1ZXN0LCAkc2NlKSB7DQoNCiAgICAvKioNCiAgICAgKiBAbmdkb2Mgc2VydmljZQ0KICAgICAqIEBuYW1lICRyb3V0ZQ0KICAgICAqIEByZXF1aXJlcyAkbG9jYXRpb24NCiAgICAgKiBAcmVxdWlyZXMgJHJvdXRlUGFyYW1zDQogICAgICoNCiAgICAgKiBAcHJvcGVydHkge09iamVjdH0gY3VycmVudCBSZWZlcmVuY2UgdG8gdGhlIGN1cnJlbnQgcm91dGUgZGVmaW5pdGlvbi4NCiAgICAgKiBUaGUgcm91dGUgZGVmaW5pdGlvbiBjb250YWluczoNCiAgICAgKg0KICAgICAqICAgLSBgY29udHJvbGxlcmA6IFRoZSBjb250cm9sbGVyIGNvbnN0cnVjdG9yIGFzIGRlZmluZSBpbiByb3V0ZSBkZWZpbml0aW9uLg0KICAgICAqICAgLSBgbG9jYWxzYDogQSBtYXAgb2YgbG9jYWxzIHdoaWNoIGlzIHVzZWQgYnkge0BsaW5rIG5nLiRjb250cm9sbGVyICRjb250cm9sbGVyfSBzZXJ2aWNlIGZvcg0KICAgICAqICAgICBjb250cm9sbGVyIGluc3RhbnRpYXRpb24uIFRoZSBgbG9jYWxzYCBjb250YWluDQogICAgICogICAgIHRoZSByZXNvbHZlZCB2YWx1ZXMgb2YgdGhlIGByZXNvbHZlYCBtYXAuIEFkZGl0aW9uYWxseSB0aGUgYGxvY2Fsc2AgYWxzbyBjb250YWluOg0KICAgICAqDQogICAgICogICAgIC0gYCRzY29wZWAgLSBUaGUgY3VycmVudCByb3V0ZSBzY29wZS4NCiAgICAgKiAgICAgLSBgJHRlbXBsYXRlYCAtIFRoZSBjdXJyZW50IHJvdXRlIHRlbXBsYXRlIEhUTUwuDQogICAgICoNCiAgICAgKiBAcHJvcGVydHkge09iamVjdH0gcm91dGVzIE9iamVjdCB3aXRoIGFsbCByb3V0ZSBjb25maWd1cmF0aW9uIE9iamVjdHMgYXMgaXRzIHByb3BlcnRpZXMuDQogICAgICoNCiAgICAgKiBAZGVzY3JpcHRpb24NCiAgICAgKiBgJHJvdXRlYCBpcyB1c2VkIGZvciBkZWVwLWxpbmtpbmcgVVJMcyB0byBjb250cm9sbGVycyBhbmQgdmlld3MgKEhUTUwgcGFydGlhbHMpLg0KICAgICAqIEl0IHdhdGNoZXMgYCRsb2NhdGlvbi51cmwoKWAgYW5kIHRyaWVzIHRvIG1hcCB0aGUgcGF0aCB0byBhbiBleGlzdGluZyByb3V0ZSBkZWZpbml0aW9uLg0KICAgICAqDQogICAgICogUmVxdWlyZXMgdGhlIHtAbGluayBuZ1JvdXRlIGBuZ1JvdXRlYH0gbW9kdWxlIHRvIGJlIGluc3RhbGxlZC4NCiAgICAgKg0KICAgICAqIFlvdSBjYW4gZGVmaW5lIHJvdXRlcyB0aHJvdWdoIHtAbGluayBuZ1JvdXRlLiRyb3V0ZVByb3ZpZGVyICRyb3V0ZVByb3ZpZGVyfSdzIEFQSS4NCiAgICAgKg0KICAgICAqIFRoZSBgJHJvdXRlYCBzZXJ2aWNlIGlzIHR5cGljYWxseSB1c2VkIGluIGNvbmp1bmN0aW9uIHdpdGggdGhlDQogICAgICoge0BsaW5rIG5nUm91dGUuZGlyZWN0aXZlOm5nVmlldyBgbmdWaWV3YH0gZGlyZWN0aXZlIGFuZCB0aGUNCiAgICAgKiB7QGxpbmsgbmdSb3V0ZS4kcm91dGVQYXJhbXMgYCRyb3V0ZVBhcmFtc2B9IHNlcnZpY2UuDQogICAgICoNCiAgICAgKiBAZXhhbXBsZQ0KICAgICAqIFRoaXMgZXhhbXBsZSBzaG93cyBob3cgY2hhbmdpbmcgdGhlIFVSTCBoYXNoIGNhdXNlcyB0aGUgYCRyb3V0ZWAgdG8gbWF0Y2ggYSByb3V0ZSBhZ2FpbnN0IHRoZQ0KICAgICAqIFVSTCwgYW5kIHRoZSBgbmdWaWV3YCBwdWxscyBpbiB0aGUgcGFydGlhbC4NCiAgICAgKg0KICAgICAqIDxleGFtcGxlIG5hbWU9IiRyb3V0ZS1zZXJ2aWNlIiBtb2R1bGU9Im5nUm91dGVFeGFtcGxlIg0KICAgICAqICAgICAgICAgIGRlcHM9ImFuZ3VsYXItcm91dGUuanMiIGZpeEJhc2U9InRydWUiPg0KICAgICAqICAgPGZpbGUgbmFtZT0iaW5kZXguaHRtbCI+DQogICAgICogICAgIDxkaXYgbmctY29udHJvbGxlcj0iTWFpbkNvbnRyb2xsZXIiPg0KICAgICAqICAgICAgIENob29zZToNCiAgICAgKiAgICAgICA8YSBocmVmPSJCb29rL01vYnkiPk1vYnk8L2E+IHwNCiAgICAgKiAgICAgICA8YSBocmVmPSJCb29rL01vYnkvY2gvMSI+TW9ieTogQ2gxPC9hPiB8DQogICAgICogICAgICAgPGEgaHJlZj0iQm9vay9HYXRzYnkiPkdhdHNieTwvYT4gfA0KICAgICAqICAgICAgIDxhIGhyZWY9IkJvb2svR2F0c2J5L2NoLzQ/a2V5PXZhbHVlIj5HYXRzYnk6IENoNDwvYT4gfA0KICAgICAqICAgICAgIDxhIGhyZWY9IkJvb2svU2NhcmxldCI+U2NhcmxldCBMZXR0ZXI8L2E+PGJyLz4NCiAgICAgKg0KICAgICAqICAgICAgIDxkaXYgbmctdmlldz48L2Rpdj4NCiAgICAgKg0KICAgICAqICAgICAgIDxociAvPg0KICAgICAqDQogICAgICogICAgICAgPHByZT4kbG9jYXRpb24ucGF0aCgpID0ge3skbG9jYXRpb24ucGF0aCgpfX08L3ByZT4NCiAgICAgKiAgICAgICA8cHJlPiRyb3V0ZS5jdXJyZW50LnRlbXBsYXRlVXJsID0ge3skcm91dGUuY3VycmVudC50ZW1wbGF0ZVVybH19PC9wcmU+DQogICAgICogICAgICAgPHByZT4kcm91dGUuY3VycmVudC5wYXJhbXMgPSB7eyRyb3V0ZS5jdXJyZW50LnBhcmFtc319PC9wcmU+DQogICAgICogICAgICAgPHByZT4kcm91dGUuY3VycmVudC5zY29wZS5uYW1lID0ge3skcm91dGUuY3VycmVudC5zY29wZS5uYW1lfX08L3ByZT4NCiAgICAgKiAgICAgICA8cHJlPiRyb3V0ZVBhcmFtcyA9IHt7JHJvdXRlUGFyYW1zfX08L3ByZT4NCiAgICAgKiAgICAgPC9kaXY+DQogICAgICogICA8L2ZpbGU+DQogICAgICoNCiAgICAgKiAgIDxmaWxlIG5hbWU9ImJvb2suaHRtbCI+DQogICAgICogICAgIGNvbnRyb2xsZXI6IHt7bmFtZX19PGJyIC8+DQogICAgICogICAgIEJvb2sgSWQ6IHt7cGFyYW1zLmJvb2tJZH19PGJyIC8+DQogICAgICogICA8L2ZpbGU+DQogICAgICoNCiAgICAgKiAgIDxmaWxlIG5hbWU9ImNoYXB0ZXIuaHRtbCI+DQogICAgICogICAgIGNvbnRyb2xsZXI6IHt7bmFtZX19PGJyIC8+DQogICAgICogICAgIEJvb2sgSWQ6IHt7cGFyYW1zLmJvb2tJZH19PGJyIC8+DQogICAgICogICAgIENoYXB0ZXIgSWQ6IHt7cGFyYW1zLmNoYXB0ZXJJZH19DQogICAgICogICA8L2ZpbGU+DQogICAgICoNCiAgICAgKiAgIDxmaWxlIG5hbWU9InNjcmlwdC5qcyI+DQogICAgICogICAgIGFuZ3VsYXIubW9kdWxlKCduZ1JvdXRlRXhhbXBsZScsIFsnbmdSb3V0ZSddKQ0KICAgICAqDQogICAgICogICAgICAuY29udHJvbGxlcignTWFpbkNvbnRyb2xsZXInLCBmdW5jdGlvbigkc2NvcGUsICRyb3V0ZSwgJHJvdXRlUGFyYW1zLCAkbG9jYXRpb24pIHsNCiAgICAgKiAgICAgICAgICAkc2NvcGUuJHJvdXRlID0gJHJvdXRlOw0KICAgICAqICAgICAgICAgICRzY29wZS4kbG9jYXRpb24gPSAkbG9jYXRpb247DQogICAgICogICAgICAgICAgJHNjb3BlLiRyb3V0ZVBhcmFtcyA9ICRyb3V0ZVBhcmFtczsNCiAgICAgKiAgICAgIH0pDQogICAgICoNCiAgICAgKiAgICAgIC5jb250cm9sbGVyKCdCb29rQ29udHJvbGxlcicsIGZ1bmN0aW9uKCRzY29wZSwgJHJvdXRlUGFyYW1zKSB7DQogICAgICogICAgICAgICAgJHNjb3BlLm5hbWUgPSAiQm9va0NvbnRyb2xsZXIiOw0KICAgICAqICAgICAgICAgICRzY29wZS5wYXJhbXMgPSAkcm91dGVQYXJhbXM7DQogICAgICogICAgICB9KQ0KICAgICAqDQogICAgICogICAgICAuY29udHJvbGxlcignQ2hhcHRlckNvbnRyb2xsZXInLCBmdW5jdGlvbigkc2NvcGUsICRyb3V0ZVBhcmFtcykgew0KICAgICAqICAgICAgICAgICRzY29wZS5uYW1lID0gIkNoYXB0ZXJDb250cm9sbGVyIjsNCiAgICAgKiAgICAgICAgICAkc2NvcGUucGFyYW1zID0gJHJvdXRlUGFyYW1zOw0KICAgICAqICAgICAgfSkNCiAgICAgKg0KICAgICAqICAgICAuY29uZmlnKGZ1bmN0aW9uKCRyb3V0ZVByb3ZpZGVyLCAkbG9jYXRpb25Qcm92aWRlcikgew0KICAgICAqICAgICAgICRyb3V0ZVByb3ZpZGVyDQogICAgICogICAgICAgIC53aGVuKCcvQm9vay86Ym9va0lkJywgew0KICAgICAqICAgICAgICAgdGVtcGxhdGVVcmw6ICdib29rLmh0bWwnLA0KICAgICAqICAgICAgICAgY29udHJvbGxlcjogJ0Jvb2tDb250cm9sbGVyJywNCiAgICAgKiAgICAgICAgIHJlc29sdmU6IHsNCiAgICAgKiAgICAgICAgICAgLy8gSSB3aWxsIGNhdXNlIGEgMSBzZWNvbmQgZGVsYXkNCiAgICAgKiAgICAgICAgICAgZGVsYXk6IGZ1bmN0aW9uKCRxLCAkdGltZW91dCkgew0KICAgICAqICAgICAgICAgICAgIHZhciBkZWxheSA9ICRxLmRlZmVyKCk7DQogICAgICogICAgICAgICAgICAgJHRpbWVvdXQoZGVsYXkucmVzb2x2ZSwgMTAwMCk7DQogICAgICogICAgICAgICAgICAgcmV0dXJuIGRlbGF5LnByb21pc2U7DQogICAgICogICAgICAgICAgIH0NCiAgICAgKiAgICAgICAgIH0NCiAgICAgKiAgICAgICB9KQ0KICAgICAqICAgICAgIC53aGVuKCcvQm9vay86Ym9va0lkL2NoLzpjaGFwdGVySWQnLCB7DQogICAgICogICAgICAgICB0ZW1wbGF0ZVVybDogJ2NoYXB0ZXIuaHRtbCcsDQogICAgICogICAgICAgICBjb250cm9sbGVyOiAnQ2hhcHRlckNvbnRyb2xsZXInDQogICAgICogICAgICAgfSk7DQogICAgICoNCiAgICAgKiAgICAgICAvLyBjb25maWd1cmUgaHRtbDUgdG8gZ2V0IGxpbmtzIHdvcmtpbmcgb24ganNmaWRkbGUNCiAgICAgKiAgICAgICAkbG9jYXRpb25Qcm92aWRlci5odG1sNU1vZGUodHJ1ZSk7DQogICAgICogICAgIH0pOw0KICAgICAqDQogICAgICogICA8L2ZpbGU+DQogICAgICoNCiAgICAgKiAgIDxmaWxlIG5hbWU9InByb3RyYWN0b3IuanMiIHR5cGU9InByb3RyYWN0b3IiPg0KICAgICAqICAgICBpdCgnc2hvdWxkIGxvYWQgYW5kIGNvbXBpbGUgY29ycmVjdCB0ZW1wbGF0ZScsIGZ1bmN0aW9uKCkgew0KICAgICAqICAgICAgIGVsZW1lbnQoYnkubGlua1RleHQoJ01vYnk6IENoMScpKS5jbGljaygpOw0KICAgICAqICAgICAgIHZhciBjb250ZW50ID0gZWxlbWVudChieS5jc3MoJ1tuZy12aWV3XScpKS5nZXRUZXh0KCk7DQogICAgICogICAgICAgZXhwZWN0KGNvbnRlbnQpLnRvTWF0Y2goL2NvbnRyb2xsZXJcOiBDaGFwdGVyQ29udHJvbGxlci8pOw0KICAgICAqICAgICAgIGV4cGVjdChjb250ZW50KS50b01hdGNoKC9Cb29rIElkXDogTW9ieS8pOw0KICAgICAqICAgICAgIGV4cGVjdChjb250ZW50KS50b01hdGNoKC9DaGFwdGVyIElkXDogMS8pOw0KICAgICAqDQogICAgICogICAgICAgZWxlbWVudChieS5wYXJ0aWFsTGlua1RleHQoJ1NjYXJsZXQnKSkuY2xpY2soKTsNCiAgICAgKg0KICAgICAqICAgICAgIGNvbnRlbnQgPSBlbGVtZW50KGJ5LmNzcygnW25nLXZpZXddJykpLmdldFRleHQoKTsNCiAgICAgKiAgICAgICBleHBlY3QoY29udGVudCkudG9NYXRjaCgvY29udHJvbGxlclw6IEJvb2tDb250cm9sbGVyLyk7DQogICAgICogICAgICAgZXhwZWN0KGNvbnRlbnQpLnRvTWF0Y2goL0Jvb2sgSWRcOiBTY2FybGV0Lyk7DQogICAgICogICAgIH0pOw0KICAgICAqICAgPC9maWxlPg0KICAgICAqIDwvZXhhbXBsZT4NCiAgICAgKi8NCg0KICAgIC8qKg0KICAgICAqIEBuZ2RvYyBldmVudA0KICAgICAqIEBuYW1lICRyb3V0ZSMkcm91dGVDaGFuZ2VTdGFydA0KICAgICAqIEBldmVudFR5cGUgYnJvYWRjYXN0IG9uIHJvb3Qgc2NvcGUNCiAgICAgKiBAZGVzY3JpcHRpb24NCiAgICAgKiBCcm9hZGNhc3RlZCBiZWZvcmUgYSByb3V0ZSBjaGFuZ2UuIEF0IHRoaXMgIHBvaW50IHRoZSByb3V0ZSBzZXJ2aWNlcyBzdGFydHMNCiAgICAgKiByZXNvbHZpbmcgYWxsIG9mIHRoZSBkZXBlbmRlbmNpZXMgbmVlZGVkIGZvciB0aGUgcm91dGUgY2hhbmdlIHRvIG9jY3VyLg0KICAgICAqIFR5cGljYWxseSB0aGlzIGludm9sdmVzIGZldGNoaW5nIHRoZSB2aWV3IHRlbXBsYXRlIGFzIHdlbGwgYXMgYW55IGRlcGVuZGVuY2llcw0KICAgICAqIGRlZmluZWQgaW4gYHJlc29sdmVgIHJvdXRlIHByb3BlcnR5LiBPbmNlICBhbGwgb2YgdGhlIGRlcGVuZGVuY2llcyBhcmUgcmVzb2x2ZWQNCiAgICAgKiBgJHJvdXRlQ2hhbmdlU3VjY2Vzc2AgaXMgZmlyZWQuDQogICAgICoNCiAgICAgKiBUaGUgcm91dGUgY2hhbmdlIChhbmQgdGhlIGAkbG9jYXRpb25gIGNoYW5nZSB0aGF0IHRyaWdnZXJlZCBpdCkgY2FuIGJlIHByZXZlbnRlZA0KICAgICAqIGJ5IGNhbGxpbmcgYHByZXZlbnREZWZhdWx0YCBtZXRob2Qgb2YgdGhlIGV2ZW50LiBTZWUge0BsaW5rIG5nLiRyb290U2NvcGUuU2NvcGUjJG9ufQ0KICAgICAqIGZvciBtb3JlIGRldGFpbHMgYWJvdXQgZXZlbnQgb2JqZWN0Lg0KICAgICAqDQogICAgICogQHBhcmFtIHtPYmplY3R9IGFuZ3VsYXJFdmVudCBTeW50aGV0aWMgZXZlbnQgb2JqZWN0Lg0KICAgICAqIEBwYXJhbSB7Um91dGV9IG5leHQgRnV0dXJlIHJvdXRlIGluZm9ybWF0aW9uLg0KICAgICAqIEBwYXJhbSB7Um91dGV9IGN1cnJlbnQgQ3VycmVudCByb3V0ZSBpbmZvcm1hdGlvbi4NCiAgICAgKi8NCg0KICAgIC8qKg0KICAgICAqIEBuZ2RvYyBldmVudA0KICAgICAqIEBuYW1lICRyb3V0ZSMkcm91dGVDaGFuZ2VTdWNjZXNzDQogICAgICogQGV2ZW50VHlwZSBicm9hZGNhc3Qgb24gcm9vdCBzY29wZQ0KICAgICAqIEBkZXNjcmlwdGlvbg0KICAgICAqIEJyb2FkY2FzdGVkIGFmdGVyIGEgcm91dGUgZGVwZW5kZW5jaWVzIGFyZSByZXNvbHZlZC4NCiAgICAgKiB7QGxpbmsgbmdSb3V0ZS5kaXJlY3RpdmU6bmdWaWV3IG5nVmlld30gbGlzdGVucyBmb3IgdGhlIGRpcmVjdGl2ZQ0KICAgICAqIHRvIGluc3RhbnRpYXRlIHRoZSBjb250cm9sbGVyIGFuZCByZW5kZXIgdGhlIHZpZXcuDQogICAgICoNCiAgICAgKiBAcGFyYW0ge09iamVjdH0gYW5ndWxhckV2ZW50IFN5bnRoZXRpYyBldmVudCBvYmplY3QuDQogICAgICogQHBhcmFtIHtSb3V0ZX0gY3VycmVudCBDdXJyZW50IHJvdXRlIGluZm9ybWF0aW9uLg0KICAgICAqIEBwYXJhbSB7Um91dGV8VW5kZWZpbmVkfSBwcmV2aW91cyBQcmV2aW91cyByb3V0ZSBpbmZvcm1hdGlvbiwgb3IgdW5kZWZpbmVkIGlmIGN1cnJlbnQgaXMNCiAgICAgKiBmaXJzdCByb3V0ZSBlbnRlcmVkLg0KICAgICAqLw0KDQogICAgLyoqDQogICAgICogQG5nZG9jIGV2ZW50DQogICAgICogQG5hbWUgJHJvdXRlIyRyb3V0ZUNoYW5nZUVycm9yDQogICAgICogQGV2ZW50VHlwZSBicm9hZGNhc3Qgb24gcm9vdCBzY29wZQ0KICAgICAqIEBkZXNjcmlwdGlvbg0KICAgICAqIEJyb2FkY2FzdGVkIGlmIGFueSBvZiB0aGUgcmVzb2x2ZSBwcm9taXNlcyBhcmUgcmVqZWN0ZWQuDQogICAgICoNCiAgICAgKiBAcGFyYW0ge09iamVjdH0gYW5ndWxhckV2ZW50IFN5bnRoZXRpYyBldmVudCBvYmplY3QNCiAgICAgKiBAcGFyYW0ge1JvdXRlfSBjdXJyZW50IEN1cnJlbnQgcm91dGUgaW5mb3JtYXRpb24uDQogICAgICogQHBhcmFtIHtSb3V0ZX0gcHJldmlvdXMgUHJldmlvdXMgcm91dGUgaW5mb3JtYXRpb24uDQogICAgICogQHBhcmFtIHtSb3V0ZX0gcmVqZWN0aW9uIFJlamVjdGlvbiBvZiB0aGUgcHJvbWlzZS4gVXN1YWxseSB0aGUgZXJyb3Igb2YgdGhlIGZhaWxlZCBwcm9taXNlLg0KICAgICAqLw0KDQogICAgLyoqDQogICAgICogQG5nZG9jIGV2ZW50DQogICAgICogQG5hbWUgJHJvdXRlIyRyb3V0ZVVwZGF0ZQ0KICAgICAqIEBldmVudFR5cGUgYnJvYWRjYXN0IG9uIHJvb3Qgc2NvcGUNCiAgICAgKiBAZGVzY3JpcHRpb24NCiAgICAgKg0KICAgICAqIFRoZSBgcmVsb2FkT25TZWFyY2hgIHByb3BlcnR5IGhhcyBiZWVuIHNldCB0byBmYWxzZSwgYW5kIHdlIGFyZSByZXVzaW5nIHRoZSBzYW1lDQogICAgICogaW5zdGFuY2Ugb2YgdGhlIENvbnRyb2xsZXIuDQogICAgICovDQoNCiAgICB2YXIgZm9yY2VSZWxvYWQgPSBmYWxzZSwNCiAgICAgICAgcHJlcGFyZWRSb3V0ZSwNCiAgICAgICAgcHJlcGFyZWRSb3V0ZUlzVXBkYXRlT25seSwNCiAgICAgICAgJHJvdXRlID0gew0KICAgICAgICAgIHJvdXRlczogcm91dGVzLA0KDQogICAgICAgICAgLyoqDQogICAgICAgICAgICogQG5nZG9jIG1ldGhvZA0KICAgICAgICAgICAqIEBuYW1lICRyb3V0ZSNyZWxvYWQNCiAgICAgICAgICAgKg0KICAgICAgICAgICAqIEBkZXNjcmlwdGlvbg0KICAgICAgICAgICAqIENhdXNlcyBgJHJvdXRlYCBzZXJ2aWNlIHRvIHJlbG9hZCB0aGUgY3VycmVudCByb3V0ZSBldmVuIGlmDQogICAgICAgICAgICoge0BsaW5rIG5nLiRsb2NhdGlvbiAkbG9jYXRpb259IGhhc24ndCBjaGFuZ2VkLg0KICAgICAgICAgICAqDQogICAgICAgICAgICogQXMgYSByZXN1bHQgb2YgdGhhdCwge0BsaW5rIG5nUm91dGUuZGlyZWN0aXZlOm5nVmlldyBuZ1ZpZXd9DQogICAgICAgICAgICogY3JlYXRlcyBuZXcgc2NvcGUgYW5kIHJlaW5zdGFudGlhdGVzIHRoZSBjb250cm9sbGVyLg0KICAgICAgICAgICAqLw0KICAgICAgICAgIHJlbG9hZDogZnVuY3Rpb24oKSB7DQogICAgICAgICAgICBmb3JjZVJlbG9hZCA9IHRydWU7DQogICAgICAgICAgICAkcm9vdFNjb3BlLiRldmFsQXN5bmMoZnVuY3Rpb24oKSB7DQogICAgICAgICAgICAgIC8vIERvbid0IHN1cHBvcnQgY2FuY2VsbGF0aW9uIG9mIGEgcmVsb2FkIGZvciBub3cuLi4NCiAgICAgICAgICAgICAgcHJlcGFyZVJvdXRlKCk7DQogICAgICAgICAgICAgIGNvbW1pdFJvdXRlKCk7DQogICAgICAgICAgICB9KTsNCiAgICAgICAgICB9LA0KDQogICAgICAgICAgLyoqDQogICAgICAgICAgICogQG5nZG9jIG1ldGhvZA0KICAgICAgICAgICAqIEBuYW1lICRyb3V0ZSN1cGRhdGVQYXJhbXMNCiAgICAgICAgICAgKg0KICAgICAgICAgICAqIEBkZXNjcmlwdGlvbg0KICAgICAgICAgICAqIENhdXNlcyBgJHJvdXRlYCBzZXJ2aWNlIHRvIHVwZGF0ZSB0aGUgY3VycmVudCBVUkwsIHJlcGxhY2luZw0KICAgICAgICAgICAqIGN1cnJlbnQgcm91dGUgcGFyYW1ldGVycyB3aXRoIHRob3NlIHNwZWNpZmllZCBpbiBgbmV3UGFyYW1zYC4NCiAgICAgICAgICAgKiBQcm92aWRlZCBwcm9wZXJ0eSBuYW1lcyB0aGF0IG1hdGNoIHRoZSByb3V0ZSdzIHBhdGggc2VnbWVudA0KICAgICAgICAgICAqIGRlZmluaXRpb25zIHdpbGwgYmUgaW50ZXJwb2xhdGVkIGludG8gdGhlIGxvY2F0aW9uJ3MgcGF0aCwgd2hpbGUNCiAgICAgICAgICAgKiByZW1haW5pbmcgcHJvcGVydGllcyB3aWxsIGJlIHRyZWF0ZWQgYXMgcXVlcnkgcGFyYW1zLg0KICAgICAgICAgICAqDQogICAgICAgICAgICogQHBhcmFtIHtPYmplY3R9IG5ld1BhcmFtcyBtYXBwaW5nIG9mIFVSTCBwYXJhbWV0ZXIgbmFtZXMgdG8gdmFsdWVzDQogICAgICAgICAgICovDQogICAgICAgICAgdXBkYXRlUGFyYW1zOiBmdW5jdGlvbihuZXdQYXJhbXMpIHsNCiAgICAgICAgICAgIGlmICh0aGlzLmN1cnJlbnQgJiYgdGhpcy5jdXJyZW50LiQkcm91dGUpIHsNCiAgICAgICAgICAgICAgdmFyIHNlYXJjaFBhcmFtcyA9IHt9LCBzZWxmPXRoaXM7DQoNCiAgICAgICAgICAgICAgYW5ndWxhci5mb3JFYWNoKE9iamVjdC5rZXlzKG5ld1BhcmFtcyksIGZ1bmN0aW9uKGtleSkgew0KICAgICAgICAgICAgICAgIGlmICghc2VsZi5jdXJyZW50LnBhdGhQYXJhbXNba2V5XSkgc2VhcmNoUGFyYW1zW2tleV0gPSBuZXdQYXJhbXNba2V5XTsNCiAgICAgICAgICAgICAgfSk7DQoNCiAgICAgICAgICAgICAgbmV3UGFyYW1zID0gYW5ndWxhci5leHRlbmQoe30sIHRoaXMuY3VycmVudC5wYXJhbXMsIG5ld1BhcmFtcyk7DQogICAgICAgICAgICAgICRsb2NhdGlvbi5wYXRoKGludGVycG9sYXRlKHRoaXMuY3VycmVudC4kJHJvdXRlLm9yaWdpbmFsUGF0aCwgbmV3UGFyYW1zKSk7DQogICAgICAgICAgICAgICRsb2NhdGlvbi5zZWFyY2goYW5ndWxhci5leHRlbmQoe30sICRsb2NhdGlvbi5zZWFyY2goKSwgc2VhcmNoUGFyYW1zKSk7DQogICAgICAgICAgICB9DQogICAgICAgICAgICBlbHNlIHsNCiAgICAgICAgICAgICAgdGhyb3cgJHJvdXRlTWluRXJyKCdub3JvdXQnLCAnVHJpZWQgdXBkYXRpbmcgcm91dGUgd2hlbiB3aXRoIG5vIGN1cnJlbnQgcm91dGUnKTsNCiAgICAgICAgICAgIH0NCiAgICAgICAgICB9DQogICAgICAgIH07DQoNCiAgICAkcm9vdFNjb3BlLiRvbignJGxvY2F0aW9uQ2hhbmdlU3RhcnQnLCBwcmVwYXJlUm91dGUpOw0KICAgICRyb290U2NvcGUuJG9uKCckbG9jYXRpb25DaGFuZ2VTdWNjZXNzJywgY29tbWl0Um91dGUpOw0KDQogICAgcmV0dXJuICRyb3V0ZTsNCg0KICAgIC8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vDQoNCiAgICAvKioNCiAgICAgKiBAcGFyYW0gb24ge3N0cmluZ30gY3VycmVudCB1cmwNCiAgICAgKiBAcGFyYW0gcm91dGUge09iamVjdH0gcm91dGUgcmVnZXhwIHRvIG1hdGNoIHRoZSB1cmwgYWdhaW5zdA0KICAgICAqIEByZXR1cm4gez9PYmplY3R9DQogICAgICoNCiAgICAgKiBAZGVzY3JpcHRpb24NCiAgICAgKiBDaGVjayBpZiB0aGUgcm91dGUgbWF0Y2hlcyB0aGUgY3VycmVudCB1cmwuDQogICAgICoNCiAgICAgKiBJbnNwaXJlZCBieSBtYXRjaCBpbg0KICAgICAqIHZpc2lvbm1lZGlhL2V4cHJlc3MvbGliL3JvdXRlci9yb3V0ZXIuanMuDQogICAgICovDQogICAgZnVuY3Rpb24gc3dpdGNoUm91dGVNYXRjaGVyKG9uLCByb3V0ZSkgew0KICAgICAgdmFyIGtleXMgPSByb3V0ZS5rZXlzLA0KICAgICAgICAgIHBhcmFtcyA9IHt9Ow0KDQogICAgICBpZiAoIXJvdXRlLnJlZ2V4cCkgcmV0dXJuIG51bGw7DQoNCiAgICAgIHZhciBtID0gcm91dGUucmVnZXhwLmV4ZWMob24pOw0KICAgICAgaWYgKCFtKSByZXR1cm4gbnVsbDsNCg0KICAgICAgZm9yICh2YXIgaSA9IDEsIGxlbiA9IG0ubGVuZ3RoOyBpIDwgbGVuOyArK2kpIHsNCiAgICAgICAgdmFyIGtleSA9IGtleXNbaSAtIDFdOw0KDQogICAgICAgIHZhciB2YWwgPSBtW2ldOw0KDQogICAgICAgIGlmIChrZXkgJiYgdmFsKSB7DQogICAgICAgICAgcGFyYW1zW2tleS5uYW1lXSA9IHZhbDsNCiAgICAgICAgfQ0KICAgICAgfQ0KICAgICAgcmV0dXJuIHBhcmFtczsNCiAgICB9DQoNCiAgICBmdW5jdGlvbiBwcmVwYXJlUm91dGUoJGxvY2F0aW9uRXZlbnQpIHsNCiAgICAgIHZhciBsYXN0Um91dGUgPSAkcm91dGUuY3VycmVudDsNCg0KICAgICAgcHJlcGFyZWRSb3V0ZSA9IHBhcnNlUm91dGUoKTsNCiAgICAgIHByZXBhcmVkUm91dGVJc1VwZGF0ZU9ubHkgPSBwcmVwYXJlZFJvdXRlICYmIGxhc3RSb3V0ZSAmJiBwcmVwYXJlZFJvdXRlLiQkcm91dGUgPT09IGxhc3RSb3V0ZS4kJHJvdXRlDQogICAgICAgICAgJiYgYW5ndWxhci5lcXVhbHMocHJlcGFyZWRSb3V0ZS5wYXRoUGFyYW1zLCBsYXN0Um91dGUucGF0aFBhcmFtcykNCiAgICAgICAgICAmJiAhcHJlcGFyZWRSb3V0ZS5yZWxvYWRPblNlYXJjaCAmJiAhZm9yY2VSZWxvYWQ7DQoNCiAgICAgIGlmICghcHJlcGFyZWRSb3V0ZUlzVXBkYXRlT25seSAmJiAobGFzdFJvdXRlIHx8IHByZXBhcmVkUm91dGUpKSB7DQogICAgICAgIGlmICgkcm9vdFNjb3BlLiRicm9hZGNhc3QoJyRyb3V0ZUNoYW5nZVN0YXJ0JywgcHJlcGFyZWRSb3V0ZSwgbGFzdFJvdXRlKS5kZWZhdWx0UHJldmVudGVkKSB7DQogICAgICAgICAgaWYgKCRsb2NhdGlvbkV2ZW50KSB7DQogICAgICAgICAgICAkbG9jYXRpb25FdmVudC5wcmV2ZW50RGVmYXVsdCgpOw0KICAgICAgICAgIH0NCiAgICAgICAgfQ0KICAgICAgfQ0KICAgIH0NCg0KICAgIGZ1bmN0aW9uIGNvbW1pdFJvdXRlKCkgew0KICAgICAgdmFyIGxhc3RSb3V0ZSA9ICRyb3V0ZS5jdXJyZW50Ow0KICAgICAgdmFyIG5leHRSb3V0ZSA9IHByZXBhcmVkUm91dGU7DQoNCiAgICAgIGlmIChwcmVwYXJlZFJvdXRlSXNVcGRhdGVPbmx5KSB7DQogICAgICAgIGxhc3RSb3V0ZS5wYXJhbXMgPSBuZXh0Um91dGUucGFyYW1zOw0KICAgICAgICBhbmd1bGFyLmNvcHkobGFzdFJvdXRlLnBhcmFtcywgJHJvdXRlUGFyYW1zKTsNCiAgICAgICAgJHJvb3RTY29wZS4kYnJvYWRjYXN0KCckcm91dGVVcGRhdGUnLCBsYXN0Um91dGUpOw0KICAgICAgfSBlbHNlIGlmIChuZXh0Um91dGUgfHwgbGFzdFJvdXRlKSB7DQogICAgICAgIGZvcmNlUmVsb2FkID0gZmFsc2U7DQogICAgICAgICRyb3V0ZS5jdXJyZW50ID0gbmV4dFJvdXRlOw0KICAgICAgICBpZiAobmV4dFJvdXRlKSB7DQogICAgICAgICAgaWYgKG5leHRSb3V0ZS5yZWRpcmVjdFRvKSB7DQogICAgICAgICAgICBpZiAoYW5ndWxhci5pc1N0cmluZyhuZXh0Um91dGUucmVkaXJlY3RUbykpIHsNCiAgICAgICAgICAgICAgJGxvY2F0aW9uLnBhdGgoaW50ZXJwb2xhdGUobmV4dFJvdXRlLnJlZGlyZWN0VG8sIG5leHRSb3V0ZS5wYXJhbXMpKS5zZWFyY2gobmV4dFJvdXRlLnBhcmFtcykNCiAgICAgICAgICAgICAgICAgICAgICAgLnJlcGxhY2UoKTsNCiAgICAgICAgICAgIH0gZWxzZSB7DQogICAgICAgICAgICAgICRsb2NhdGlvbi51cmwobmV4dFJvdXRlLnJlZGlyZWN0VG8obmV4dFJvdXRlLnBhdGhQYXJhbXMsICRsb2NhdGlvbi5wYXRoKCksICRsb2NhdGlvbi5zZWFyY2goKSkpDQogICAgICAgICAgICAgICAgICAgICAgIC5yZXBsYWNlKCk7DQogICAgICAgICAgICB9DQogICAgICAgICAgfQ0KICAgICAgICB9DQoNCiAgICAgICAgJHEud2hlbihuZXh0Um91dGUpLg0KICAgICAgICAgIHRoZW4oZnVuY3Rpb24oKSB7DQogICAgICAgICAgICBpZiAobmV4dFJvdXRlKSB7DQogICAgICAgICAgICAgIHZhciBsb2NhbHMgPSBhbmd1bGFyLmV4dGVuZCh7fSwgbmV4dFJvdXRlLnJlc29sdmUpLA0KICAgICAgICAgICAgICAgICAgdGVtcGxhdGUsIHRlbXBsYXRlVXJsOw0KDQogICAgICAgICAgICAgIGFuZ3VsYXIuZm9yRWFjaChsb2NhbHMsIGZ1bmN0aW9uKHZhbHVlLCBrZXkpIHsNCiAgICAgICAgICAgICAgICBsb2NhbHNba2V5XSA9IGFuZ3VsYXIuaXNTdHJpbmcodmFsdWUpID8NCiAgICAgICAgICAgICAgICAgICAgJGluamVjdG9yLmdldCh2YWx1ZSkgOiAkaW5qZWN0b3IuaW52b2tlKHZhbHVlLCBudWxsLCBudWxsLCBrZXkpOw0KICAgICAgICAgICAgICB9KTsNCg0KICAgICAgICAgICAgICBpZiAoYW5ndWxhci5pc0RlZmluZWQodGVtcGxhdGUgPSBuZXh0Um91dGUudGVtcGxhdGUpKSB7DQogICAgICAgICAgICAgICAgaWYgKGFuZ3VsYXIuaXNGdW5jdGlvbih0ZW1wbGF0ZSkpIHsNCiAgICAgICAgICAgICAgICAgIHRlbXBsYXRlID0gdGVtcGxhdGUobmV4dFJvdXRlLnBhcmFtcyk7DQogICAgICAgICAgICAgICAgfQ0KICAgICAgICAgICAgICB9IGVsc2UgaWYgKGFuZ3VsYXIuaXNEZWZpbmVkKHRlbXBsYXRlVXJsID0gbmV4dFJvdXRlLnRlbXBsYXRlVXJsKSkgew0KICAgICAgICAgICAgICAgIGlmIChhbmd1bGFyLmlzRnVuY3Rpb24odGVtcGxhdGVVcmwpKSB7DQogICAgICAgICAgICAgICAgICB0ZW1wbGF0ZVVybCA9IHRlbXBsYXRlVXJsKG5leHRSb3V0ZS5wYXJhbXMpOw0KICAgICAgICAgICAgICAgIH0NCiAgICAgICAgICAgICAgICB0ZW1wbGF0ZVVybCA9ICRzY2UuZ2V0VHJ1c3RlZFJlc291cmNlVXJsKHRlbXBsYXRlVXJsKTsNCiAgICAgICAgICAgICAgICBpZiAoYW5ndWxhci5pc0RlZmluZWQodGVtcGxhdGVVcmwpKSB7DQogICAgICAgICAgICAgICAgICBuZXh0Um91dGUubG9hZGVkVGVtcGxhdGVVcmwgPSB0ZW1wbGF0ZVVybDsNCiAgICAgICAgICAgICAgICAgIHRlbXBsYXRlID0gJHRlbXBsYXRlUmVxdWVzdCh0ZW1wbGF0ZVVybCk7DQogICAgICAgICAgICAgICAgfQ0KICAgICAgICAgICAgICB9DQogICAgICAgICAgICAgIGlmIChhbmd1bGFyLmlzRGVmaW5lZCh0ZW1wbGF0ZSkpIHsNCiAgICAgICAgICAgICAgICBsb2NhbHNbJyR0ZW1wbGF0ZSddID0gdGVtcGxhdGU7DQogICAgICAgICAgICAgIH0NCiAgICAgICAgICAgICAgcmV0dXJuICRxLmFsbChsb2NhbHMpOw0KICAgICAgICAgICAgfQ0KICAgICAgICAgIH0pLg0KICAgICAgICAgIC8vIGFmdGVyIHJvdXRlIGNoYW5nZQ0KICAgICAgICAgIHRoZW4oZnVuY3Rpb24obG9jYWxzKSB7DQogICAgICAgICAgICBpZiAobmV4dFJvdXRlID09ICRyb3V0ZS5jdXJyZW50KSB7DQogICAgICAgICAgICAgIGlmIChuZXh0Um91dGUpIHsNCiAgICAgICAgICAgICAgICBuZXh0Um91dGUubG9jYWxzID0gbG9jYWxzOw0KICAgICAgICAgICAgICAgIGFuZ3VsYXIuY29weShuZXh0Um91dGUucGFyYW1zLCAkcm91dGVQYXJhbXMpOw0KICAgICAgICAgICAgICB9DQogICAgICAgICAgICAgICRyb290U2NvcGUuJGJyb2FkY2FzdCgnJHJvdXRlQ2hhbmdlU3VjY2VzcycsIG5leHRSb3V0ZSwgbGFzdFJvdXRlKTsNCiAgICAgICAgICAgIH0NCiAgICAgICAgICB9LCBmdW5jdGlvbihlcnJvcikgew0KICAgICAgICAgICAgaWYgKG5leHRSb3V0ZSA9PSAkcm91dGUuY3VycmVudCkgew0KICAgICAgICAgICAgICAkcm9vdFNjb3BlLiRicm9hZGNhc3QoJyRyb3V0ZUNoYW5nZUVycm9yJywgbmV4dFJvdXRlLCBsYXN0Um91dGUsIGVycm9yKTsNCiAgICAgICAgICAgIH0NCiAgICAgICAgICB9KTsNCiAgICAgIH0NCiAgICB9DQoNCg0KICAgIC8qKg0KICAgICAqIEByZXR1cm5zIHtPYmplY3R9IHRoZSBjdXJyZW50IGFjdGl2ZSByb3V0ZSwgYnkgbWF0Y2hpbmcgaXQgYWdhaW5zdCB0aGUgVVJMDQogICAgICovDQogICAgZnVuY3Rpb24gcGFyc2VSb3V0ZSgpIHsNCiAgICAgIC8vIE1hdGNoIGEgcm91dGUNCiAgICAgIHZhciBwYXJhbXMsIG1hdGNoOw0KICAgICAgYW5ndWxhci5mb3JFYWNoKHJvdXRlcywgZnVuY3Rpb24ocm91dGUsIHBhdGgpIHsNCiAgICAgICAgaWYgKCFtYXRjaCAmJiAocGFyYW1zID0gc3dpdGNoUm91dGVNYXRjaGVyKCRsb2NhdGlvbi5wYXRoKCksIHJvdXRlKSkpIHsNCiAgICAgICAgICBtYXRjaCA9IGluaGVyaXQocm91dGUsIHsNCiAgICAgICAgICAgIHBhcmFtczogYW5ndWxhci5leHRlbmQoe30sICRsb2NhdGlvbi5zZWFyY2goKSwgcGFyYW1zKSwNCiAgICAgICAgICAgIHBhdGhQYXJhbXM6IHBhcmFtc30pOw0KICAgICAgICAgIG1hdGNoLiQkcm91dGUgPSByb3V0ZTsNCiAgICAgICAgfQ0KICAgICAgfSk7DQogICAgICAvLyBObyByb3V0ZSBtYXRjaGVkOyBmYWxsYmFjayB0byAib3RoZXJ3aXNlIiByb3V0ZQ0KICAgICAgcmV0dXJuIG1hdGNoIHx8IHJvdXRlc1tudWxsXSAmJiBpbmhlcml0KHJvdXRlc1tudWxsXSwge3BhcmFtczoge30sIHBhdGhQYXJhbXM6e319KTsNCiAgICB9DQoNCiAgICAvKioNCiAgICAgKiBAcmV0dXJucyB7c3RyaW5nfSBpbnRlcnBvbGF0aW9uIG9mIHRoZSByZWRpcmVjdCBwYXRoIHdpdGggdGhlIHBhcmFtZXRlcnMNCiAgICAgKi8NCiAgICBmdW5jdGlvbiBpbnRlcnBvbGF0ZShzdHJpbmcsIHBhcmFtcykgew0KICAgICAgdmFyIHJlc3VsdCA9IFtdOw0KICAgICAgYW5ndWxhci5mb3JFYWNoKChzdHJpbmcgfHwgJycpLnNwbGl0KCc6JyksIGZ1bmN0aW9uKHNlZ21lbnQsIGkpIHsNCiAgICAgICAgaWYgKGkgPT09IDApIHsNCiAgICAgICAgICByZXN1bHQucHVzaChzZWdtZW50KTsNCiAgICAgICAgfSBlbHNlIHsNCiAgICAgICAgICB2YXIgc2VnbWVudE1hdGNoID0gc2VnbWVudC5tYXRjaCgvKFx3KykoPzpbPypdKT8oLiopLyk7DQogICAgICAgICAgdmFyIGtleSA9IHNlZ21lbnRNYXRjaFsxXTsNCiAgICAgICAgICByZXN1bHQucHVzaChwYXJhbXNba2V5XSk7DQogICAgICAgICAgcmVzdWx0LnB1c2goc2VnbWVudE1hdGNoWzJdIHx8ICcnKTsNCiAgICAgICAgICBkZWxldGUgcGFyYW1zW2tleV07DQogICAgICAgIH0NCiAgICAgIH0pOw0KICAgICAgcmV0dXJuIHJlc3VsdC5qb2luKCcnKTsNCiAgICB9DQogIH1dOw0KfQ0KDQpuZ1JvdXRlTW9kdWxlLnByb3ZpZGVyKCckcm91dGVQYXJhbXMnLCAkUm91dGVQYXJhbXNQcm92aWRlcik7DQoNCg0KLyoqDQogKiBAbmdkb2Mgc2VydmljZQ0KICogQG5hbWUgJHJvdXRlUGFyYW1zDQogKiBAcmVxdWlyZXMgJHJvdXRlDQogKg0KICogQGRlc2NyaXB0aW9uDQogKiBUaGUgYCRyb3V0ZVBhcmFtc2Agc2VydmljZSBhbGxvd3MgeW91IHRvIHJldHJpZXZlIHRoZSBjdXJyZW50IHNldCBvZiByb3V0ZSBwYXJhbWV0ZXJzLg0KICoNCiAqIFJlcXVpcmVzIHRoZSB7QGxpbmsgbmdSb3V0ZSBgbmdSb3V0ZWB9IG1vZHVsZSB0byBiZSBpbnN0YWxsZWQuDQogKg0KICogVGhlIHJvdXRlIHBhcmFtZXRlcnMgYXJlIGEgY29tYmluYXRpb24gb2Yge0BsaW5rIG5nLiRsb2NhdGlvbiBgJGxvY2F0aW9uYH0ncw0KICoge0BsaW5rIG5nLiRsb2NhdGlvbiNzZWFyY2ggYHNlYXJjaCgpYH0gYW5kIHtAbGluayBuZy4kbG9jYXRpb24jcGF0aCBgcGF0aCgpYH0uDQogKiBUaGUgYHBhdGhgIHBhcmFtZXRlcnMgYXJlIGV4dHJhY3RlZCB3aGVuIHRoZSB7QGxpbmsgbmdSb3V0ZS4kcm91dGUgYCRyb3V0ZWB9IHBhdGggaXMgbWF0Y2hlZC4NCiAqDQogKiBJbiBjYXNlIG9mIHBhcmFtZXRlciBuYW1lIGNvbGxpc2lvbiwgYHBhdGhgIHBhcmFtcyB0YWtlIHByZWNlZGVuY2Ugb3ZlciBgc2VhcmNoYCBwYXJhbXMuDQogKg0KICogVGhlIHNlcnZpY2UgZ3VhcmFudGVlcyB0aGF0IHRoZSBpZGVudGl0eSBvZiB0aGUgYCRyb3V0ZVBhcmFtc2Agb2JqZWN0IHdpbGwgcmVtYWluIHVuY2hhbmdlZA0KICogKGJ1dCBpdHMgcHJvcGVydGllcyB3aWxsIGxpa2VseSBjaGFuZ2UpIGV2ZW4gd2hlbiBhIHJvdXRlIGNoYW5nZSBvY2N1cnMuDQogKg0KICogTm90ZSB0aGF0IHRoZSBgJHJvdXRlUGFyYW1zYCBhcmUgb25seSB1cGRhdGVkICphZnRlciogYSByb3V0ZSBjaGFuZ2UgY29tcGxldGVzIHN1Y2Nlc3NmdWxseS4NCiAqIFRoaXMgbWVhbnMgdGhhdCB5b3UgY2Fubm90IHJlbHkgb24gYCRyb3V0ZVBhcmFtc2AgYmVpbmcgY29ycmVjdCBpbiByb3V0ZSByZXNvbHZlIGZ1bmN0aW9ucy4NCiAqIEluc3RlYWQgeW91IGNhbiB1c2UgYCRyb3V0ZS5jdXJyZW50LnBhcmFtc2AgdG8gYWNjZXNzIHRoZSBuZXcgcm91dGUncyBwYXJhbWV0ZXJzLg0KICoNCiAqIEBleGFtcGxlDQogKiBgYGBqcw0KICogIC8vIEdpdmVuOg0KICogIC8vIFVSTDogaHR0cDovL3NlcnZlci5jb20vaW5kZXguaHRtbCMvQ2hhcHRlci8xL1NlY3Rpb24vMj9zZWFyY2g9bW9ieQ0KICogIC8vIFJvdXRlOiAvQ2hhcHRlci86Y2hhcHRlcklkL1NlY3Rpb24vOnNlY3Rpb25JZA0KICogIC8vDQogKiAgLy8gVGhlbg0KICogICRyb3V0ZVBhcmFtcyA9PT4ge2NoYXB0ZXJJZDonMScsIHNlY3Rpb25JZDonMicsIHNlYXJjaDonbW9ieSd9DQogKiBgYGANCiAqLw0KZnVuY3Rpb24gJFJvdXRlUGFyYW1zUHJvdmlkZXIoKSB7DQogIHRoaXMuJGdldCA9IGZ1bmN0aW9uKCkgeyByZXR1cm4ge307IH07DQp9DQoNCm5nUm91dGVNb2R1bGUuZGlyZWN0aXZlKCduZ1ZpZXcnLCBuZ1ZpZXdGYWN0b3J5KTsNCm5nUm91dGVNb2R1bGUuZGlyZWN0aXZlKCduZ1ZpZXcnLCBuZ1ZpZXdGaWxsQ29udGVudEZhY3RvcnkpOw0KDQoNCi8qKg0KICogQG5nZG9jIGRpcmVjdGl2ZQ0KICogQG5hbWUgbmdWaWV3DQogKiBAcmVzdHJpY3QgRUNBDQogKg0KICogQGRlc2NyaXB0aW9uDQogKiAjIE92ZXJ2aWV3DQogKiBgbmdWaWV3YCBpcyBhIGRpcmVjdGl2ZSB0aGF0IGNvbXBsZW1lbnRzIHRoZSB7QGxpbmsgbmdSb3V0ZS4kcm91dGUgJHJvdXRlfSBzZXJ2aWNlIGJ5DQogKiBpbmNsdWRpbmcgdGhlIHJlbmRlcmVkIHRlbXBsYXRlIG9mIHRoZSBjdXJyZW50IHJvdXRlIGludG8gdGhlIG1haW4gbGF5b3V0IChgaW5kZXguaHRtbGApIGZpbGUuDQogKiBFdmVyeSB0aW1lIHRoZSBjdXJyZW50IHJvdXRlIGNoYW5nZXMsIHRoZSBpbmNsdWRlZCB2aWV3IGNoYW5nZXMgd2l0aCBpdCBhY2NvcmRpbmcgdG8gdGhlDQogKiBjb25maWd1cmF0aW9uIG9mIHRoZSBgJHJvdXRlYCBzZXJ2aWNlLg0KICoNCiAqIFJlcXVpcmVzIHRoZSB7QGxpbmsgbmdSb3V0ZSBgbmdSb3V0ZWB9IG1vZHVsZSB0byBiZSBpbnN0YWxsZWQuDQogKg0KICogQGFuaW1hdGlvbnMNCiAqIGVudGVyIC0gYW5pbWF0aW9uIGlzIHVzZWQgdG8gYnJpbmcgbmV3IGNvbnRlbnQgaW50byB0aGUgYnJvd3Nlci4NCiAqIGxlYXZlIC0gYW5pbWF0aW9uIGlzIHVzZWQgdG8gYW5pbWF0ZSBleGlzdGluZyBjb250ZW50IGF3YXkuDQogKg0KICogVGhlIGVudGVyIGFuZCBsZWF2ZSBhbmltYXRpb24gb2NjdXIgY29uY3VycmVudGx5Lg0KICoNCiAqIEBzY29wZQ0KICogQHByaW9yaXR5IDQwMA0KICogQHBhcmFtIHtzdHJpbmc9fSBvbmxvYWQgRXhwcmVzc2lvbiB0byBldmFsdWF0ZSB3aGVuZXZlciB0aGUgdmlldyB1cGRhdGVzLg0KICoNCiAqIEBwYXJhbSB7c3RyaW5nPX0gYXV0b3Njcm9sbCBXaGV0aGVyIGBuZ1ZpZXdgIHNob3VsZCBjYWxsIHtAbGluayBuZy4kYW5jaG9yU2Nyb2xsDQogKiAgICAgICAgICAgICAgICAgICRhbmNob3JTY3JvbGx9IHRvIHNjcm9sbCB0aGUgdmlld3BvcnQgYWZ0ZXIgdGhlIHZpZXcgaXMgdXBkYXRlZC4NCiAqDQogKiAgICAgICAgICAgICAgICAgIC0gSWYgdGhlIGF0dHJpYnV0ZSBpcyBub3Qgc2V0LCBkaXNhYmxlIHNjcm9sbGluZy4NCiAqICAgICAgICAgICAgICAgICAgLSBJZiB0aGUgYXR0cmlidXRlIGlzIHNldCB3aXRob3V0IHZhbHVlLCBlbmFibGUgc2Nyb2xsaW5nLg0KICogICAgICAgICAgICAgICAgICAtIE90aGVyd2lzZSBlbmFibGUgc2Nyb2xsaW5nIG9ubHkgaWYgdGhlIGBhdXRvc2Nyb2xsYCBhdHRyaWJ1dGUgdmFsdWUgZXZhbHVhdGVkDQogKiAgICAgICAgICAgICAgICAgICAgYXMgYW4gZXhwcmVzc2lvbiB5aWVsZHMgYSB0cnV0aHkgdmFsdWUuDQogKiBAZXhhbXBsZQ0KICAgIDxleGFtcGxlIG5hbWU9Im5nVmlldy1kaXJlY3RpdmUiIG1vZHVsZT0ibmdWaWV3RXhhbXBsZSINCiAgICAgICAgICAgICBkZXBzPSJhbmd1bGFyLXJvdXRlLmpzO2FuZ3VsYXItYW5pbWF0ZS5qcyINCiAgICAgICAgICAgICBhbmltYXRpb25zPSJ0cnVlIiBmaXhCYXNlPSJ0cnVlIj4NCiAgICAgIDxmaWxlIG5hbWU9ImluZGV4Lmh0bWwiPg0KICAgICAgICA8ZGl2IG5nLWNvbnRyb2xsZXI9Ik1haW5DdHJsIGFzIG1haW4iPg0KICAgICAgICAgIENob29zZToNCiAgICAgICAgICA8YSBocmVmPSJCb29rL01vYnkiPk1vYnk8L2E+IHwNCiAgICAgICAgICA8YSBocmVmPSJCb29rL01vYnkvY2gvMSI+TW9ieTogQ2gxPC9hPiB8DQogICAgICAgICAgPGEgaHJlZj0iQm9vay9HYXRzYnkiPkdhdHNieTwvYT4gfA0KICAgICAgICAgIDxhIGhyZWY9IkJvb2svR2F0c2J5L2NoLzQ/a2V5PXZhbHVlIj5HYXRzYnk6IENoNDwvYT4gfA0KICAgICAgICAgIDxhIGhyZWY9IkJvb2svU2NhcmxldCI+U2NhcmxldCBMZXR0ZXI8L2E+PGJyLz4NCg0KICAgICAgICAgIDxkaXYgY2xhc3M9InZpZXctYW5pbWF0ZS1jb250YWluZXIiPg0KICAgICAgICAgICAgPGRpdiBuZy12aWV3IGNsYXNzPSJ2aWV3LWFuaW1hdGUiPjwvZGl2Pg0KICAgICAgICAgIDwvZGl2Pg0KICAgICAgICAgIDxociAvPg0KDQogICAgICAgICAgPHByZT4kbG9jYXRpb24ucGF0aCgpID0ge3ttYWluLiRsb2NhdGlvbi5wYXRoKCl9fTwvcHJlPg0KICAgICAgICAgIDxwcmU+JHJvdXRlLmN1cnJlbnQudGVtcGxhdGVVcmwgPSB7e21haW4uJHJvdXRlLmN1cnJlbnQudGVtcGxhdGVVcmx9fTwvcHJlPg0KICAgICAgICAgIDxwcmU+JHJvdXRlLmN1cnJlbnQucGFyYW1zID0ge3ttYWluLiRyb3V0ZS5jdXJyZW50LnBhcmFtc319PC9wcmU+DQogICAgICAgICAgPHByZT4kcm91dGVQYXJhbXMgPSB7e21haW4uJHJvdXRlUGFyYW1zfX08L3ByZT4NCiAgICAgICAgPC9kaXY+DQogICAgICA8L2ZpbGU+DQoNCiAgICAgIDxmaWxlIG5hbWU9ImJvb2suaHRtbCI+DQogICAgICAgIDxkaXY+DQogICAgICAgICAgY29udHJvbGxlcjoge3tib29rLm5hbWV9fTxiciAvPg0KICAgICAgICAgIEJvb2sgSWQ6IHt7Ym9vay5wYXJhbXMuYm9va0lkfX08YnIgLz4NCiAgICAgICAgPC9kaXY+DQogICAgICA8L2ZpbGU+DQoNCiAgICAgIDxmaWxlIG5hbWU9ImNoYXB0ZXIuaHRtbCI+DQogICAgICAgIDxkaXY+DQogICAgICAgICAgY29udHJvbGxlcjoge3tjaGFwdGVyLm5hbWV9fTxiciAvPg0KICAgICAgICAgIEJvb2sgSWQ6IHt7Y2hhcHRlci5wYXJhbXMuYm9va0lkfX08YnIgLz4NCiAgICAgICAgICBDaGFwdGVyIElkOiB7e2NoYXB0ZXIucGFyYW1zLmNoYXB0ZXJJZH19DQogICAgICAgIDwvZGl2Pg0KICAgICAgPC9maWxlPg0KDQogICAgICA8ZmlsZSBuYW1lPSJhbmltYXRpb25zLmNzcyI+DQogICAgICAgIC52aWV3LWFuaW1hdGUtY29udGFpbmVyIHsNCiAgICAgICAgICBwb3NpdGlvbjpyZWxhdGl2ZTsNCiAgICAgICAgICBoZWlnaHQ6MTAwcHghaW1wb3J0YW50Ow0KICAgICAgICAgIGJhY2tncm91bmQ6d2hpdGU7DQogICAgICAgICAgYm9yZGVyOjFweCBzb2xpZCBibGFjazsNCiAgICAgICAgICBoZWlnaHQ6NDBweDsNCiAgICAgICAgICBvdmVyZmxvdzpoaWRkZW47DQogICAgICAgIH0NCg0KICAgICAgICAudmlldy1hbmltYXRlIHsNCiAgICAgICAgICBwYWRkaW5nOjEwcHg7DQogICAgICAgIH0NCg0KICAgICAgICAudmlldy1hbmltYXRlLm5nLWVudGVyLCAudmlldy1hbmltYXRlLm5nLWxlYXZlIHsNCiAgICAgICAgICAtd2Via2l0LXRyYW5zaXRpb246YWxsIGN1YmljLWJlemllcigwLjI1MCwgMC40NjAsIDAuNDUwLCAwLjk0MCkgMS41czsNCiAgICAgICAgICB0cmFuc2l0aW9uOmFsbCBjdWJpYy1iZXppZXIoMC4yNTAsIDAuNDYwLCAwLjQ1MCwgMC45NDApIDEuNXM7DQoNCiAgICAgICAgICBkaXNwbGF5OmJsb2NrOw0KICAgICAgICAgIHdpZHRoOjEwMCU7DQogICAgICAgICAgYm9yZGVyLWxlZnQ6MXB4IHNvbGlkIGJsYWNrOw0KDQogICAgICAgICAgcG9zaXRpb246YWJzb2x1dGU7DQogICAgICAgICAgdG9wOjA7DQogICAgICAgICAgbGVmdDowOw0KICAgICAgICAgIHJpZ2h0OjA7DQogICAgICAgICAgYm90dG9tOjA7DQogICAgICAgICAgcGFkZGluZzoxMHB4Ow0KICAgICAgICB9DQoNCiAgICAgICAgLnZpZXctYW5pbWF0ZS5uZy1lbnRlciB7DQogICAgICAgICAgbGVmdDoxMDAlOw0KICAgICAgICB9DQogICAgICAgIC52aWV3LWFuaW1hdGUubmctZW50ZXIubmctZW50ZXItYWN0aXZlIHsNCiAgICAgICAgICBsZWZ0OjA7DQogICAgICAgIH0NCiAgICAgICAgLnZpZXctYW5pbWF0ZS5uZy1sZWF2ZS5uZy1sZWF2ZS1hY3RpdmUgew0KICAgICAgICAgIGxlZnQ6LTEwMCU7DQogICAgICAgIH0NCiAgICAgIDwvZmlsZT4NCg0KICAgICAgPGZpbGUgbmFtZT0ic2NyaXB0LmpzIj4NCiAgICAgICAgYW5ndWxhci5tb2R1bGUoJ25nVmlld0V4YW1wbGUnLCBbJ25nUm91dGUnLCAnbmdBbmltYXRlJ10pDQogICAgICAgICAgLmNvbmZpZyhbJyRyb3V0ZVByb3ZpZGVyJywgJyRsb2NhdGlvblByb3ZpZGVyJywNCiAgICAgICAgICAgIGZ1bmN0aW9uKCRyb3V0ZVByb3ZpZGVyLCAkbG9jYXRpb25Qcm92aWRlcikgew0KICAgICAgICAgICAgICAkcm91dGVQcm92aWRlcg0KICAgICAgICAgICAgICAgIC53aGVuKCcvQm9vay86Ym9va0lkJywgew0KICAgICAgICAgICAgICAgICAgdGVtcGxhdGVVcmw6ICdib29rLmh0bWwnLA0KICAgICAgICAgICAgICAgICAgY29udHJvbGxlcjogJ0Jvb2tDdHJsJywNCiAgICAgICAgICAgICAgICAgIGNvbnRyb2xsZXJBczogJ2Jvb2snDQogICAgICAgICAgICAgICAgfSkNCiAgICAgICAgICAgICAgICAud2hlbignL0Jvb2svOmJvb2tJZC9jaC86Y2hhcHRlcklkJywgew0KICAgICAgICAgICAgICAgICAgdGVtcGxhdGVVcmw6ICdjaGFwdGVyLmh0bWwnLA0KICAgICAgICAgICAgICAgICAgY29udHJvbGxlcjogJ0NoYXB0ZXJDdHJsJywNCiAgICAgICAgICAgICAgICAgIGNvbnRyb2xsZXJBczogJ2NoYXB0ZXInDQogICAgICAgICAgICAgICAgfSk7DQoNCiAgICAgICAgICAgICAgJGxvY2F0aW9uUHJvdmlkZXIuaHRtbDVNb2RlKHRydWUpOw0KICAgICAgICAgIH1dKQ0KICAgICAgICAgIC5jb250cm9sbGVyKCdNYWluQ3RybCcsIFsnJHJvdXRlJywgJyRyb3V0ZVBhcmFtcycsICckbG9jYXRpb24nLA0KICAgICAgICAgICAgZnVuY3Rpb24oJHJvdXRlLCAkcm91dGVQYXJhbXMsICRsb2NhdGlvbikgew0KICAgICAgICAgICAgICB0aGlzLiRyb3V0ZSA9ICRyb3V0ZTsNCiAgICAgICAgICAgICAgdGhpcy4kbG9jYXRpb24gPSAkbG9jYXRpb247DQogICAgICAgICAgICAgIHRoaXMuJHJvdXRlUGFyYW1zID0gJHJvdXRlUGFyYW1zOw0KICAgICAgICAgIH1dKQ0KICAgICAgICAgIC5jb250cm9sbGVyKCdCb29rQ3RybCcsIFsnJHJvdXRlUGFyYW1zJywgZnVuY3Rpb24oJHJvdXRlUGFyYW1zKSB7DQogICAgICAgICAgICB0aGlzLm5hbWUgPSAiQm9va0N0cmwiOw0KICAgICAgICAgICAgdGhpcy5wYXJhbXMgPSAkcm91dGVQYXJhbXM7DQogICAgICAgICAgfV0pDQogICAgICAgICAgLmNvbnRyb2xsZXIoJ0NoYXB0ZXJDdHJsJywgWyckcm91dGVQYXJhbXMnLCBmdW5jdGlvbigkcm91dGVQYXJhbXMpIHsNCiAgICAgICAgICAgIHRoaXMubmFtZSA9ICJDaGFwdGVyQ3RybCI7DQogICAgICAgICAgICB0aGlzLnBhcmFtcyA9ICRyb3V0ZVBhcmFtczsNCiAgICAgICAgICB9XSk7DQoNCiAgICAgIDwvZmlsZT4NCg0KICAgICAgPGZpbGUgbmFtZT0icHJvdHJhY3Rvci5qcyIgdHlwZT0icHJvdHJhY3RvciI+DQogICAgICAgIGl0KCdzaG91bGQgbG9hZCBhbmQgY29tcGlsZSBjb3JyZWN0IHRlbXBsYXRlJywgZnVuY3Rpb24oKSB7DQogICAgICAgICAgZWxlbWVudChieS5saW5rVGV4dCgnTW9ieTogQ2gxJykpLmNsaWNrKCk7DQogICAgICAgICAgdmFyIGNvbnRlbnQgPSBlbGVtZW50KGJ5LmNzcygnW25nLXZpZXddJykpLmdldFRleHQoKTsNCiAgICAgICAgICBleHBlY3QoY29udGVudCkudG9NYXRjaCgvY29udHJvbGxlclw6IENoYXB0ZXJDdHJsLyk7DQogICAgICAgICAgZXhwZWN0KGNvbnRlbnQpLnRvTWF0Y2goL0Jvb2sgSWRcOiBNb2J5Lyk7DQogICAgICAgICAgZXhwZWN0KGNvbnRlbnQpLnRvTWF0Y2goL0NoYXB0ZXIgSWRcOiAxLyk7DQoNCiAgICAgICAgICBlbGVtZW50KGJ5LnBhcnRpYWxMaW5rVGV4dCgnU2NhcmxldCcpKS5jbGljaygpOw0KDQogICAgICAgICAgY29udGVudCA9IGVsZW1lbnQoYnkuY3NzKCdbbmctdmlld10nKSkuZ2V0VGV4dCgpOw0KICAgICAgICAgIGV4cGVjdChjb250ZW50KS50b01hdGNoKC9jb250cm9sbGVyXDogQm9va0N0cmwvKTsNCiAgICAgICAgICBleHBlY3QoY29udGVudCkudG9NYXRjaCgvQm9vayBJZFw6IFNjYXJsZXQvKTsNCiAgICAgICAgfSk7DQogICAgICA8L2ZpbGU+DQogICAgPC9leGFtcGxlPg0KICovDQoNCg0KLyoqDQogKiBAbmdkb2MgZXZlbnQNCiAqIEBuYW1lIG5nVmlldyMkdmlld0NvbnRlbnRMb2FkZWQNCiAqIEBldmVudFR5cGUgZW1pdCBvbiB0aGUgY3VycmVudCBuZ1ZpZXcgc2NvcGUNCiAqIEBkZXNjcmlwdGlvbg0KICogRW1pdHRlZCBldmVyeSB0aW1lIHRoZSBuZ1ZpZXcgY29udGVudCBpcyByZWxvYWRlZC4NCiAqLw0KbmdWaWV3RmFjdG9yeS4kaW5qZWN0ID0gWyckcm91dGUnLCAnJGFuY2hvclNjcm9sbCcsICckYW5pbWF0ZSddOw0KZnVuY3Rpb24gbmdWaWV3RmFjdG9yeSgkcm91dGUsICRhbmNob3JTY3JvbGwsICRhbmltYXRlKSB7DQogIHJldHVybiB7DQogICAgcmVzdHJpY3Q6ICdFQ0EnLA0KICAgIHRlcm1pbmFsOiB0cnVlLA0KICAgIHByaW9yaXR5OiA0MDAsDQogICAgdHJhbnNjbHVkZTogJ2VsZW1lbnQnLA0KICAgIGxpbms6IGZ1bmN0aW9uKHNjb3BlLCAkZWxlbWVudCwgYXR0ciwgY3RybCwgJHRyYW5zY2x1ZGUpIHsNCiAgICAgICAgdmFyIGN1cnJlbnRTY29wZSwNCiAgICAgICAgICAgIGN1cnJlbnRFbGVtZW50LA0KICAgICAgICAgICAgcHJldmlvdXNMZWF2ZUFuaW1hdGlvbiwNCiAgICAgICAgICAgIGF1dG9TY3JvbGxFeHAgPSBhdHRyLmF1dG9zY3JvbGwsDQogICAgICAgICAgICBvbmxvYWRFeHAgPSBhdHRyLm9ubG9hZCB8fCAnJzsNCg0KICAgICAgICBzY29wZS4kb24oJyRyb3V0ZUNoYW5nZVN1Y2Nlc3MnLCB1cGRhdGUpOw0KICAgICAgICB1cGRhdGUoKTsNCg0KICAgICAgICBmdW5jdGlvbiBjbGVhbnVwTGFzdFZpZXcoKSB7DQogICAgICAgICAgaWYgKHByZXZpb3VzTGVhdmVBbmltYXRpb24pIHsNCiAgICAgICAgICAgICRhbmltYXRlLmNhbmNlbChwcmV2aW91c0xlYXZlQW5pbWF0aW9uKTsNCiAgICAgICAgICAgIHByZXZpb3VzTGVhdmVBbmltYXRpb24gPSBudWxsOw0KICAgICAgICAgIH0NCg0KICAgICAgICAgIGlmIChjdXJyZW50U2NvcGUpIHsNCiAgICAgICAgICAgIGN1cnJlbnRTY29wZS4kZGVzdHJveSgpOw0KICAgICAgICAgICAgY3VycmVudFNjb3BlID0gbnVsbDsNCiAgICAgICAgICB9DQogICAgICAgICAgaWYgKGN1cnJlbnRFbGVtZW50KSB7DQogICAgICAgICAgICBwcmV2aW91c0xlYXZlQW5pbWF0aW9uID0gJGFuaW1hdGUubGVhdmUoY3VycmVudEVsZW1lbnQpOw0KICAgICAgICAgICAgcHJldmlvdXNMZWF2ZUFuaW1hdGlvbi50aGVuKGZ1bmN0aW9uKCkgew0KICAgICAgICAgICAgICBwcmV2aW91c0xlYXZlQW5pbWF0aW9uID0gbnVsbDsNCiAgICAgICAgICAgIH0pOw0KICAgICAgICAgICAgY3VycmVudEVsZW1lbnQgPSBudWxsOw0KICAgICAgICAgIH0NCiAgICAgICAgfQ0KDQogICAgICAgIGZ1bmN0aW9uIHVwZGF0ZSgpIHsNCiAgICAgICAgICB2YXIgbG9jYWxzID0gJHJvdXRlLmN1cnJlbnQgJiYgJHJvdXRlLmN1cnJlbnQubG9jYWxzLA0KICAgICAgICAgICAgICB0ZW1wbGF0ZSA9IGxvY2FscyAmJiBsb2NhbHMuJHRlbXBsYXRlOw0KDQogICAgICAgICAgaWYgKGFuZ3VsYXIuaXNEZWZpbmVkKHRlbXBsYXRlKSkgew0KICAgICAgICAgICAgdmFyIG5ld1Njb3BlID0gc2NvcGUuJG5ldygpOw0KICAgICAgICAgICAgdmFyIGN1cnJlbnQgPSAkcm91dGUuY3VycmVudDsNCg0KICAgICAgICAgICAgLy8gTm90ZTogVGhpcyB3aWxsIGFsc28gbGluayBhbGwgY2hpbGRyZW4gb2YgbmctdmlldyB0aGF0IHdlcmUgY29udGFpbmVkIGluIHRoZSBvcmlnaW5hbA0KICAgICAgICAgICAgLy8gaHRtbC4gSWYgdGhhdCBjb250ZW50IGNvbnRhaW5zIGNvbnRyb2xsZXJzLCAuLi4gdGhleSBjb3VsZCBwb2xsdXRlL2NoYW5nZSB0aGUgc2NvcGUuDQogICAgICAgICAgICAvLyBIb3dldmVyLCB1c2luZyBuZy12aWV3IG9uIGFuIGVsZW1lbnQgd2l0aCBhZGRpdGlvbmFsIGNvbnRlbnQgZG9lcyBub3QgbWFrZSBzZW5zZS4uLg0KICAgICAgICAgICAgLy8gTm90ZTogV2UgY2FuJ3QgcmVtb3ZlIHRoZW0gaW4gdGhlIGNsb25lQXR0Y2hGbiBvZiAkdHJhbnNjbHVkZSBhcyB0aGF0DQogICAgICAgICAgICAvLyBmdW5jdGlvbiBpcyBjYWxsZWQgYmVmb3JlIGxpbmtpbmcgdGhlIGNvbnRlbnQsIHdoaWNoIHdvdWxkIGFwcGx5IGNoaWxkDQogICAgICAgICAgICAvLyBkaXJlY3RpdmVzIHRvIG5vbiBleGlzdGluZyBlbGVtZW50cy4NCiAgICAgICAgICAgIHZhciBjbG9uZSA9ICR0cmFuc2NsdWRlKG5ld1Njb3BlLCBmdW5jdGlvbihjbG9uZSkgew0KICAgICAgICAgICAgICAkYW5pbWF0ZS5lbnRlcihjbG9uZSwgbnVsbCwgY3VycmVudEVsZW1lbnQgfHwgJGVsZW1lbnQpLnRoZW4oZnVuY3Rpb24gb25OZ1ZpZXdFbnRlcigpIHsNCiAgICAgICAgICAgICAgICBpZiAoYW5ndWxhci5pc0RlZmluZWQoYXV0b1Njcm9sbEV4cCkNCiAgICAgICAgICAgICAgICAgICYmICghYXV0b1Njcm9sbEV4cCB8fCBzY29wZS4kZXZhbChhdXRvU2Nyb2xsRXhwKSkpIHsNCiAgICAgICAgICAgICAgICAgICRhbmNob3JTY3JvbGwoKTsNCiAgICAgICAgICAgICAgICB9DQogICAgICAgICAgICAgIH0pOw0KICAgICAgICAgICAgICBjbGVhbnVwTGFzdFZpZXcoKTsNCiAgICAgICAgICAgIH0pOw0KDQogICAgICAgICAgICBjdXJyZW50RWxlbWVudCA9IGNsb25lOw0KICAgICAgICAgICAgY3VycmVudFNjb3BlID0gY3VycmVudC5zY29wZSA9IG5ld1Njb3BlOw0KICAgICAgICAgICAgY3VycmVudFNjb3BlLiRlbWl0KCckdmlld0NvbnRlbnRMb2FkZWQnKTsNCiAgICAgICAgICAgIGN1cnJlbnRTY29wZS4kZXZhbChvbmxvYWRFeHApOw0KICAgICAgICAgIH0gZWxzZSB7DQogICAgICAgICAgICBjbGVhbnVwTGFzdFZpZXcoKTsNCiAgICAgICAgICB9DQogICAgICAgIH0NCiAgICB9DQogIH07DQp9DQoNCi8vIFRoaXMgZGlyZWN0aXZlIGlzIGNhbGxlZCBkdXJpbmcgdGhlICR0cmFuc2NsdWRlIGNhbGwgb2YgdGhlIGZpcnN0IGBuZ1ZpZXdgIGRpcmVjdGl2ZS4NCi8vIEl0IHdpbGwgcmVwbGFjZSBhbmQgY29tcGlsZSB0aGUgY29udGVudCBvZiB0aGUgZWxlbWVudCB3aXRoIHRoZSBsb2FkZWQgdGVtcGxhdGUuDQovLyBXZSBuZWVkIHRoaXMgZGlyZWN0aXZlIHNvIHRoYXQgdGhlIGVsZW1lbnQgY29udGVudCBpcyBhbHJlYWR5IGZpbGxlZCB3aGVuDQovLyB0aGUgbGluayBmdW5jdGlvbiBvZiBhbm90aGVyIGRpcmVjdGl2ZSBvbiB0aGUgc2FtZSBlbGVtZW50IGFzIG5nVmlldw0KLy8gaXMgY2FsbGVkLg0KbmdWaWV3RmlsbENvbnRlbnRGYWN0b3J5LiRpbmplY3QgPSBbJyRjb21waWxlJywgJyRjb250cm9sbGVyJywgJyRyb3V0ZSddOw0KZnVuY3Rpb24gbmdWaWV3RmlsbENvbnRlbnRGYWN0b3J5KCRjb21waWxlLCAkY29udHJvbGxlciwgJHJvdXRlKSB7DQogIHJldHVybiB7DQogICAgcmVzdHJpY3Q6ICdFQ0EnLA0KICAgIHByaW9yaXR5OiAtNDAwLA0KICAgIGxpbms6IGZ1bmN0aW9uKHNjb3BlLCAkZWxlbWVudCkgew0KICAgICAgdmFyIGN1cnJlbnQgPSAkcm91dGUuY3VycmVudCwNCiAgICAgICAgICBsb2NhbHMgPSBjdXJyZW50LmxvY2FsczsNCg0KICAgICAgJGVsZW1lbnQuaHRtbChsb2NhbHMuJHRlbXBsYXRlKTsNCg0KICAgICAgdmFyIGxpbmsgPSAkY29tcGlsZSgkZWxlbWVudC5jb250ZW50cygpKTsNCg0KICAgICAgaWYgKGN1cnJlbnQuY29udHJvbGxlcikgew0KICAgICAgICBsb2NhbHMuJHNjb3BlID0gc2NvcGU7DQogICAgICAgIHZhciBjb250cm9sbGVyID0gJGNvbnRyb2xsZXIoY3VycmVudC5jb250cm9sbGVyLCBsb2NhbHMpOw0KICAgICAgICBpZiAoY3VycmVudC5jb250cm9sbGVyQXMpIHsNCiAgICAgICAgICBzY29wZVtjdXJyZW50LmNvbnRyb2xsZXJBc10gPSBjb250cm9sbGVyOw0KICAgICAgICB9DQogICAgICAgICRlbGVtZW50LmRhdGEoJyRuZ0NvbnRyb2xsZXJDb250cm9sbGVyJywgY29udHJvbGxlcik7DQogICAgICAgICRlbGVtZW50LmNoaWxkcmVuKCkuZGF0YSgnJG5nQ29udHJvbGxlckNvbnRyb2xsZXInLCBjb250cm9sbGVyKTsNCiAgICAgIH0NCg0KICAgICAgbGluayhzY29wZSk7DQogICAgfQ0KICB9Ow0KfQ0KDQoNCn0pKHdpbmRvdywgd2luZG93LmFuZ3VsYXIpOw0K