IyAtKi0gY29kaW5nOiBsYXRpbi0xIC0qLQ0KIiIiVGVzdHMgZm9yIGNvb2tpZWxpYi5weS4iIiINCg0KaW1wb3J0IGNvb2tpZWxpYg0KaW1wb3J0IG9zDQppbXBvcnQgcmUNCmltcG9ydCB0aW1lDQoNCmZyb20gdW5pdHRlc3QgaW1wb3J0IFRlc3RDYXNlDQoNCmZyb20gdGVzdCBpbXBvcnQgdGVzdF9zdXBwb3J0DQoNCg0KY2xhc3MgRGF0ZVRpbWVUZXN0cyhUZXN0Q2FzZSk6DQoNCiAgICBkZWYgdGVzdF90aW1lMmlzb3ooc2VsZik6DQogICAgICAgIGZyb20gY29va2llbGliIGltcG9ydCB0aW1lMmlzb3oNCg0KICAgICAgICBiYXNlID0gMTAxOTIyNzAwMA0KICAgICAgICBkYXkgPSAyNCozNjAwDQogICAgICAgIHNlbGYuYXNzZXJ0RXF1YWwodGltZTJpc296KGJhc2UpLCAiMjAwMi0wNC0xOSAxNDozNjo0MFoiKQ0KICAgICAgICBzZWxmLmFzc2VydEVxdWFsKHRpbWUyaXNveihiYXNlK2RheSksICIyMDAyLTA0LTIwIDE0OjM2OjQwWiIpDQogICAgICAgIHNlbGYuYXNzZXJ0RXF1YWwodGltZTJpc296KGJhc2UrMipkYXkpLCAiMjAwMi0wNC0yMSAxNDozNjo0MFoiKQ0KICAgICAgICBzZWxmLmFzc2VydEVxdWFsKHRpbWUyaXNveihiYXNlKzMqZGF5KSwgIjIwMDItMDQtMjIgMTQ6MzY6NDBaIikNCg0KICAgICAgICBheiA9IHRpbWUyaXNveigpDQogICAgICAgIGJ6ID0gdGltZTJpc296KDUwMDAwMCkNCiAgICAgICAgZm9yIHRleHQgaW4gKGF6LCBieik6DQogICAgICAgICAgICBzZWxmLmFzc2VydFRydWUocmUuc2VhcmNoKHIiXlxkezR9LVxkXGQtXGRcZCBcZFxkOlxkXGQ6XGRcZFokIiwgdGV4dCksDQogICAgICAgICAgICAgICAgICAgICAgICAgImJhZCB0aW1lMmlzb3ogZm9ybWF0OiAlcyAlcyIgJSAoYXosIGJ6KSkNCg0KICAgIGRlZiB0ZXN0X2h0dHAydGltZShzZWxmKToNCiAgICAgICAgZnJvbSBjb29raWVsaWIgaW1wb3J0IGh0dHAydGltZQ0KDQogICAgICAgIGRlZiBwYXJzZV9kYXRlKHRleHQpOg0KICAgICAgICAgICAgcmV0dXJuIHRpbWUuZ210aW1lKGh0dHAydGltZSh0ZXh0KSlbOjZdDQoNCiAgICAgICAgc2VsZi5hc3NlcnRFcXVhbChwYXJzZV9kYXRlKCIwMSBKYW4gMjAwMSIpLCAoMjAwMSwgMSwgMSwgMCwgMCwgMC4wKSkNCg0KICAgICAgICAjIHRoaXMgdGVzdCB3aWxsIGJyZWFrIGFyb3VuZCB5ZWFyIDIwNzANCiAgICAgICAgc2VsZi5hc3NlcnRFcXVhbChwYXJzZV9kYXRlKCIwMy1GZWItMjAiKSwgKDIwMjAsIDIsIDMsIDAsIDAsIDAuMCkpDQoNCiAgICAgICAgIyB0aGlzIHRlc3Qgd2lsbCBicmVhayBhcm91bmQgeWVhciAyMDQ4DQogICAgICAgIHNlbGYuYXNzZXJ0RXF1YWwocGFyc2VfZGF0ZSgiMDMtRmViLTk4IiksICgxOTk4LCAyLCAzLCAwLCAwLCAwLjApKQ0KDQogICAgZGVmIHRlc3RfaHR0cDJ0aW1lX2Zvcm1hdHMoc2VsZik6DQogICAgICAgIGZyb20gY29va2llbGliIGltcG9ydCBodHRwMnRpbWUsIHRpbWUyaXNveg0KDQogICAgICAgICMgdGVzdCBodHRwMnRpbWUgZm9yIHN1cHBvcnRlZCBkYXRlcy4gIFRlc3QgY2FzZXMgd2l0aCAyIGRpZ2l0IHllYXINCiAgICAgICAgIyB3aWxsIHByb2JhYmx5IGJyZWFrIGluIHllYXIgMjA0NC4NCiAgICAgICAgdGVzdHMgPSBbDQogICAgICAgICAnVGh1LCAwMyBGZWIgMTk5NCAwMDowMDowMCBHTVQnLCAgIyBwcm9wb3NlZCBuZXcgSFRUUCBmb3JtYXQNCiAgICAgICAgICdUaHVyc2RheSwgMDMtRmViLTk0IDAwOjAwOjAwIEdNVCcsICAjIG9sZCByZmM4NTAgSFRUUCBmb3JtYXQNCiAgICAgICAgICdUaHVyc2RheSwgMDMtRmViLTE5OTQgMDA6MDA6MDAgR01UJywgICMgYnJva2VuIHJmYzg1MCBIVFRQIGZvcm1hdA0KDQogICAgICAgICAnMDMgRmViIDE5OTQgMDA6MDA6MDAgR01UJywgICMgSFRUUCBmb3JtYXQgKG5vIHdlZWtkYXkpDQogICAgICAgICAnMDMtRmViLTk0IDAwOjAwOjAwIEdNVCcsICAjIG9sZCByZmM4NTAgKG5vIHdlZWtkYXkpDQogICAgICAgICAnMDMtRmViLTE5OTQgMDA6MDA6MDAgR01UJywgICMgYnJva2VuIHJmYzg1MCAobm8gd2Vla2RheSkNCiAgICAgICAgICcwMy1GZWItMTk5NCAwMDowMCBHTVQnLCAgIyBicm9rZW4gcmZjODUwIChubyB3ZWVrZGF5LCBubyBzZWNvbmRzKQ0KICAgICAgICAgJzAzLUZlYi0xOTk0IDAwOjAwJywgICMgYnJva2VuIHJmYzg1MCAobm8gd2Vla2RheSwgbm8gc2Vjb25kcywgbm8gdHopDQoNCiAgICAgICAgICcwMy1GZWItOTQnLCAgIyBvbGQgcmZjODUwIEhUVFAgZm9ybWF0IChubyB3ZWVrZGF5LCBubyB0aW1lKQ0KICAgICAgICAgJzAzLUZlYi0xOTk0JywgICMgYnJva2VuIHJmYzg1MCBIVFRQIGZvcm1hdCAobm8gd2Vla2RheSwgbm8gdGltZSkNCiAgICAgICAgICcwMyBGZWIgMTk5NCcsICAjIHByb3Bvc2VkIG5ldyBIVFRQIGZvcm1hdCAobm8gd2Vla2RheSwgbm8gdGltZSkNCg0KICAgICAgICAgIyBBIGZldyB0ZXN0cyB3aXRoIGV4dHJhIHNwYWNlIGF0IHZhcmlvdXMgcGxhY2VzDQogICAgICAgICAnICAwMyAgIEZlYiAgIDE5OTQgIDA6MDAgICcsDQogICAgICAgICAnICAwMy1GZWItMTk5NCAgJywNCiAgICAgICAgXQ0KDQogICAgICAgIHRlc3RfdCA9IDc2MDIzMzYwMCAgIyBhc3N1bWUgYnJva2VuIFBPU0lYIGNvdW50aW5nIG9mIHNlY29uZHMNCiAgICAgICAgcmVzdWx0ID0gdGltZTJpc296KHRlc3RfdCkNCiAgICAgICAgZXhwZWN0ZWQgPSAiMTk5NC0wMi0wMyAwMDowMDowMFoiDQogICAgICAgIHNlbGYuYXNzZXJ0RXF1YWwocmVzdWx0LCBleHBlY3RlZCwNCiAgICAgICAgICAgICAgICAgICAgICAgICAiJXMgID0+ICAnJXMnICglcykiICUgKHRlc3RfdCwgcmVzdWx0LCBleHBlY3RlZCkpDQoNCiAgICAgICAgZm9yIHMgaW4gdGVzdHM6DQogICAgICAgICAgICB0ID0gaHR0cDJ0aW1lKHMpDQogICAgICAgICAgICB0MiA9IGh0dHAydGltZShzLmxvd2VyKCkpDQogICAgICAgICAgICB0MyA9IGh0dHAydGltZShzLnVwcGVyKCkpDQoNCiAgICAgICAgICAgIHNlbGYuYXNzZXJ0VHJ1ZSh0ID09IHQyID09IHQzID09IHRlc3RfdCwNCiAgICAgICAgICAgICAgICAgICAgICAgICAiJyVzJyAgPT4gICVzLCAlcywgJXMgKCVzKSIgJSAocywgdCwgdDIsIHQzLCB0ZXN0X3QpKQ0KDQogICAgZGVmIHRlc3RfaHR0cDJ0aW1lX2dhcmJhZ2Uoc2VsZik6DQogICAgICAgIGZyb20gY29va2llbGliIGltcG9ydCBodHRwMnRpbWUNCg0KICAgICAgICBmb3IgdGVzdCBpbiBbDQogICAgICAgICAgICAnJywNCiAgICAgICAgICAgICdHYXJiYWdlJywNCiAgICAgICAgICAgICdNYW5kYWcgMTYuIFNlcHRlbWJlciAxOTk2JywNCiAgICAgICAgICAgICcwMS0wMC0xOTgwJywNCiAgICAgICAgICAgICcwMS0xMy0xOTgwJywNCiAgICAgICAgICAgICcwMC0wMS0xOTgwJywNCiAgICAgICAgICAgICczMi0wMS0xOTgwJywNCiAgICAgICAgICAgICcwMS0wMS0xOTgwIDI1OjAwOjAwJywNCiAgICAgICAgICAgICcwMS0wMS0xOTgwIDAwOjYxOjAwJywNCiAgICAgICAgICAgICcwMS0wMS0xOTgwIDAwOjAwOjYyJywNCiAgICAgICAgICAgIF06DQogICAgICAgICAgICBzZWxmLmFzc2VydFRydWUoaHR0cDJ0aW1lKHRlc3QpIGlzIE5vbmUsDQogICAgICAgICAgICAgICAgICAgICAgICAgImh0dHAydGltZSglcykgaXMgbm90IE5vbmVcbiINCiAgICAgICAgICAgICAgICAgICAgICAgICAiaHR0cDJ0aW1lKHRlc3QpICVzIiAlICh0ZXN0LCBodHRwMnRpbWUodGVzdCkpDQogICAgICAgICAgICAgICAgICAgICAgICAgKQ0KDQoNCmNsYXNzIEhlYWRlclRlc3RzKFRlc3RDYXNlKToNCg0KICAgIGRlZiB0ZXN0X3BhcnNlX25zX2hlYWRlcnNfZXhwaXJlcyhzZWxmKToNCiAgICAgICAgZnJvbSBjb29raWVsaWIgaW1wb3J0IHBhcnNlX25zX2hlYWRlcnMNCg0KICAgICAgICAjIHF1b3RlcyBzaG91bGQgYmUgc3RyaXBwZWQNCiAgICAgICAgZXhwZWN0ZWQgPSBbWygnZm9vJywgJ2JhcicpLCAoJ2V4cGlyZXMnLCAyMjA5MDY5NDEyTCksICgndmVyc2lvbicsICcwJyldXQ0KICAgICAgICBmb3IgaGRyIGluIFsNCiAgICAgICAgICAgICdmb289YmFyOyBleHBpcmVzPTAxIEphbiAyMDQwIDIyOjIzOjMyIEdNVCcsDQogICAgICAgICAgICAnZm9vPWJhcjsgZXhwaXJlcz0iMDEgSmFuIDIwNDAgMjI6MjM6MzIgR01UIicsDQogICAgICAgICAgICBdOg0KICAgICAgICAgICAgc2VsZi5hc3NlcnRFcXVhbChwYXJzZV9uc19oZWFkZXJzKFtoZHJdKSwgZXhwZWN0ZWQpDQoNCiAgICBkZWYgdGVzdF9wYXJzZV9uc19oZWFkZXJzX3ZlcnNpb24oc2VsZik6DQogICAgICAgIGZyb20gY29va2llbGliIGltcG9ydCBwYXJzZV9uc19oZWFkZXJzDQoNCiAgICAgICAgIyBxdW90ZXMgc2hvdWxkIGJlIHN0cmlwcGVkDQogICAgICAgIGV4cGVjdGVkID0gW1soJ2ZvbycsICdiYXInKSwgKCd2ZXJzaW9uJywgJzEnKV1dDQogICAgICAgIGZvciBoZHIgaW4gWw0KICAgICAgICAgICAgJ2Zvbz1iYXI7IHZlcnNpb249IjEiJywNCiAgICAgICAgICAgICdmb289YmFyOyBWZXJzaW9uPSIxIicsDQogICAgICAgICAgICBdOg0KICAgICAgICAgICAgc2VsZi5hc3NlcnRFcXVhbChwYXJzZV9uc19oZWFkZXJzKFtoZHJdKSwgZXhwZWN0ZWQpDQoNCiAgICBkZWYgdGVzdF9wYXJzZV9uc19oZWFkZXJzX3NwZWNpYWxfbmFtZXMoc2VsZik6DQogICAgICAgICMgbmFtZXMgc3VjaCBhcyAnZXhwaXJlcycgYXJlIG5vdCBzcGVjaWFsIGluIGZpcnN0IG5hbWU9dmFsdWUgcGFpcg0KICAgICAgICAjIG9mIFNldC1Db29raWU6IGhlYWRlcg0KICAgICAgICBmcm9tIGNvb2tpZWxpYiBpbXBvcnQgcGFyc2VfbnNfaGVhZGVycw0KDQogICAgICAgICMgQ29va2llIHdpdGggbmFtZSAnZXhwaXJlcycNCiAgICAgICAgaGRyID0gJ2V4cGlyZXM9MDEgSmFuIDIwNDAgMjI6MjM6MzIgR01UJw0KICAgICAgICBleHBlY3RlZCA9IFtbKCJleHBpcmVzIiwgIjAxIEphbiAyMDQwIDIyOjIzOjMyIEdNVCIpLCAoInZlcnNpb24iLCAiMCIpXV0NCiAgICAgICAgc2VsZi5hc3NlcnRFcXVhbChwYXJzZV9uc19oZWFkZXJzKFtoZHJdKSwgZXhwZWN0ZWQpDQoNCiAgICBkZWYgdGVzdF9qb2luX2hlYWRlcl93b3JkcyhzZWxmKToNCiAgICAgICAgZnJvbSBjb29raWVsaWIgaW1wb3J0IGpvaW5faGVhZGVyX3dvcmRzDQoNCiAgICAgICAgam9pbmVkID0gam9pbl9oZWFkZXJfd29yZHMoW1soImZvbyIsIE5vbmUpLCAoImJhciIsICJiYXoiKV1dKQ0KICAgICAgICBzZWxmLmFzc2VydEVxdWFsKGpvaW5lZCwgImZvbzsgYmFyPWJheiIpDQoNCiAgICAgICAgc2VsZi5hc3NlcnRFcXVhbChqb2luX2hlYWRlcl93b3JkcyhbW11dKSwgIiIpDQoNCiAgICBkZWYgdGVzdF9zcGxpdF9oZWFkZXJfd29yZHMoc2VsZik6DQogICAgICAgIGZyb20gY29va2llbGliIGltcG9ydCBzcGxpdF9oZWFkZXJfd29yZHMNCg0KICAgICAgICB0ZXN0cyA9IFsNCiAgICAgICAgICAgICgiZm9vIiwgW1soImZvbyIsIE5vbmUpXV0pLA0KICAgICAgICAgICAgKCJmb289YmFyIiwgW1soImZvbyIsICJiYXIiKV1dKSwNCiAgICAgICAgICAgICgiICAgZm9vICAgIiwgW1soImZvbyIsIE5vbmUpXV0pLA0KICAgICAgICAgICAgKCIgICBmb289ICAgIiwgW1soImZvbyIsICIiKV1dKSwNCiAgICAgICAgICAgICgiICAgZm9vPSIsIFtbKCJmb28iLCAiIildXSksDQogICAgICAgICAgICAoIiAgIGZvbz0gICA7ICIsIFtbKCJmb28iLCAiIildXSksDQogICAgICAgICAgICAoIiAgIGZvbz0gICA7IGJhcj0gYmF6ICIsIFtbKCJmb28iLCAiIiksICgiYmFyIiwgImJheiIpXV0pLA0KICAgICAgICAgICAgKCJmb289YmFyIGJhcj1iYXoiLCBbWygiZm9vIiwgImJhciIpLCAoImJhciIsICJiYXoiKV1dKSwNCiAgICAgICAgICAgICMgZG9lc24ndCByZWFsbHkgbWF0dGVyIGlmIHRoaXMgbmV4dCBmYWlscywgYnV0IGl0IHdvcmtzIEFUTQ0KICAgICAgICAgICAgKCJmb289IGJhcj1iYXoiLCBbWygiZm9vIiwgImJhcj1iYXoiKV1dKSwNCiAgICAgICAgICAgICgiZm9vPWJhcjtiYXI9YmF6IiwgW1soImZvbyIsICJiYXIiKSwgKCJiYXIiLCAiYmF6IildXSksDQogICAgICAgICAgICAoJ2ZvbyBiYXIgYmF6JywgW1soImZvbyIsIE5vbmUpLCAoImJhciIsIE5vbmUpLCAoImJheiIsIE5vbmUpXV0pLA0KICAgICAgICAgICAgKCJhLCBiLCBjIiwgW1soImEiLCBOb25lKV0sIFsoImIiLCBOb25lKV0sIFsoImMiLCBOb25lKV1dKSwNCiAgICAgICAgICAgIChyJ2ZvbzsgYmFyPWJheiwgc3BhbT0sIGZvbz0iXCxcO1wiIiwgYmFyPSAnLA0KICAgICAgICAgICAgIFtbKCJmb28iLCBOb25lKSwgKCJiYXIiLCAiYmF6IildLA0KICAgICAgICAgICAgICBbKCJzcGFtIiwgIiIpXSwgWygiZm9vIiwgJyw7IicpXSwgWygiYmFyIiwgIiIpXV0pLA0KICAgICAgICAgICAgXQ0KDQogICAgICAgIGZvciBhcmcsIGV4cGVjdCBpbiB0ZXN0czoNCiAgICAgICAgICAgIHRyeToNCiAgICAgICAgICAgICAgICByZXN1bHQgPSBzcGxpdF9oZWFkZXJfd29yZHMoW2FyZ10pDQogICAgICAgICAgICBleGNlcHQ6DQogICAgICAgICAgICAgICAgaW1wb3J0IHRyYWNlYmFjaywgU3RyaW5nSU8NCiAgICAgICAgICAgICAgICBmID0gU3RyaW5nSU8uU3RyaW5nSU8oKQ0KICAgICAgICAgICAgICAgIHRyYWNlYmFjay5wcmludF9leGMoTm9uZSwgZikNCiAgICAgICAgICAgICAgICByZXN1bHQgPSAiKGVycm9yIC0tIHRyYWNlYmFjayBmb2xsb3dzKVxuXG4lcyIgJSBmLmdldHZhbHVlKCkNCiAgICAgICAgICAgIHNlbGYuYXNzZXJ0RXF1YWwocmVzdWx0LCAgZXhwZWN0LCAiIiINCldoZW4gcGFyc2luZzogJyVzJw0KRXhwZWN0ZWQ6ICAgICAnJXMnDQpHb3Q6ICAgICAgICAgICclcycNCiIiIiAlIChhcmcsIGV4cGVjdCwgcmVzdWx0KSkNCg0KICAgIGRlZiB0ZXN0X3JvdW5kdHJpcChzZWxmKToNCiAgICAgICAgZnJvbSBjb29raWVsaWIgaW1wb3J0IHNwbGl0X2hlYWRlcl93b3Jkcywgam9pbl9oZWFkZXJfd29yZHMNCg0KICAgICAgICB0ZXN0cyA9IFsNCiAgICAgICAgICAgICgiZm9vIiwgImZvbyIpLA0KICAgICAgICAgICAgKCJmb289YmFyIiwgImZvbz1iYXIiKSwNCiAgICAgICAgICAgICgiICAgZm9vICAgIiwgImZvbyIpLA0KICAgICAgICAgICAgKCJmb289IiwgJ2Zvbz0iIicpLA0KICAgICAgICAgICAgKCJmb289YmFyIGJhcj1iYXoiLCAiZm9vPWJhcjsgYmFyPWJheiIpLA0KICAgICAgICAgICAgKCJmb289YmFyO2Jhcj1iYXoiLCAiZm9vPWJhcjsgYmFyPWJheiIpLA0KICAgICAgICAgICAgKCdmb28gYmFyIGJheicsICJmb287IGJhcjsgYmF6IiksDQogICAgICAgICAgICAocidmb289IlwiIiBiYXI9IlxcIicsIHInZm9vPSJcIiI7IGJhcj0iXFwiJyksDQogICAgICAgICAgICAoJ2ZvbywsLGJhcicsICdmb28sIGJhcicpLA0KICAgICAgICAgICAgKCdmb289YmFyLGJhcj1iYXonLCAnZm9vPWJhciwgYmFyPWJheicpLA0KDQogICAgICAgICAgICAoJ3RleHQvaHRtbDsgY2hhcnNldD1pc28tODg1OS0xJywNCiAgICAgICAgICAgICAndGV4dC9odG1sOyBjaGFyc2V0PSJpc28tODg1OS0xIicpLA0KDQogICAgICAgICAgICAoJ2Zvbz0iYmFyIjsgcG9ydD0iODAsODEiOyBkaXNjYXJkLCBiYXI9YmF6JywNCiAgICAgICAgICAgICAnZm9vPWJhcjsgcG9ydD0iODAsODEiOyBkaXNjYXJkLCBiYXI9YmF6JyksDQoNCiAgICAgICAgICAgIChyJ0Jhc2ljIHJlYWxtPSJcImZvb1xcXFxiYXJcIiInLA0KICAgICAgICAgICAgIHInQmFzaWM7IHJlYWxtPSJcImZvb1xcXFxiYXJcIiInKQ0KICAgICAgICAgICAgXQ0KDQogICAgICAgIGZvciBhcmcsIGV4cGVjdCBpbiB0ZXN0czoNCiAgICAgICAgICAgIGlucHV0ID0gc3BsaXRfaGVhZGVyX3dvcmRzKFthcmddKQ0KICAgICAgICAgICAgcmVzID0gam9pbl9oZWFkZXJfd29yZHMoaW5wdXQpDQogICAgICAgICAgICBzZWxmLmFzc2VydEVxdWFsKHJlcywgZXhwZWN0LCAiIiINCldoZW4gcGFyc2luZzogJyVzJw0KRXhwZWN0ZWQ6ICAgICAnJXMnDQpHb3Q6ICAgICAgICAgICclcycNCklucHV0IHdhczogICAgJyVzJw0KIiIiICUgKGFyZywgZXhwZWN0LCByZXMsIGlucHV0KSkNCg0KDQpjbGFzcyBGYWtlUmVzcG9uc2U6DQogICAgZGVmIF9faW5pdF9fKHNlbGYsIGhlYWRlcnM9W10sIHVybD1Ob25lKToNCiAgICAgICAgIiIiDQogICAgICAgIGhlYWRlcnM6IGxpc3Qgb2YgUkZDODIyLXN0eWxlICdLZXk6IHZhbHVlJyBzdHJpbmdzDQogICAgICAgICIiIg0KICAgICAgICBpbXBvcnQgbWltZXRvb2xzLCBTdHJpbmdJTw0KICAgICAgICBmID0gU3RyaW5nSU8uU3RyaW5nSU8oIlxuIi5qb2luKGhlYWRlcnMpKQ0KICAgICAgICBzZWxmLl9oZWFkZXJzID0gbWltZXRvb2xzLk1lc3NhZ2UoZikNCiAgICAgICAgc2VsZi5fdXJsID0gdXJsDQogICAgZGVmIGluZm8oc2VsZik6IHJldHVybiBzZWxmLl9oZWFkZXJzDQoNCmRlZiBpbnRlcmFjdF8yOTY1KGNvb2tpZWphciwgdXJsLCAqc2V0X2Nvb2tpZV9oZHJzKToNCiAgICByZXR1cm4gX2ludGVyYWN0KGNvb2tpZWphciwgdXJsLCBzZXRfY29va2llX2hkcnMsICJTZXQtQ29va2llMiIpDQoNCmRlZiBpbnRlcmFjdF9uZXRzY2FwZShjb29raWVqYXIsIHVybCwgKnNldF9jb29raWVfaGRycyk6DQogICAgcmV0dXJuIF9pbnRlcmFjdChjb29raWVqYXIsIHVybCwgc2V0X2Nvb2tpZV9oZHJzLCAiU2V0LUNvb2tpZSIpDQoNCmRlZiBfaW50ZXJhY3QoY29va2llamFyLCB1cmwsIHNldF9jb29raWVfaGRycywgaGRyX25hbWUpOg0KICAgICIiIlBlcmZvcm0gYSBzaW5nbGUgcmVxdWVzdCAvIHJlc3BvbnNlIGN5Y2xlLCByZXR1cm5pbmcgQ29va2llOiBoZWFkZXIuIiIiDQogICAgZnJvbSB1cmxsaWIyIGltcG9ydCBSZXF1ZXN0DQogICAgcmVxID0gUmVxdWVzdCh1cmwpDQogICAgY29va2llamFyLmFkZF9jb29raWVfaGVhZGVyKHJlcSkNCiAgICBjb29raWVfaGRyID0gcmVxLmdldF9oZWFkZXIoIkNvb2tpZSIsICIiKQ0KICAgIGhlYWRlcnMgPSBbXQ0KICAgIGZvciBoZHIgaW4gc2V0X2Nvb2tpZV9oZHJzOg0KICAgICAgICBoZWFkZXJzLmFwcGVuZCgiJXM6ICVzIiAlIChoZHJfbmFtZSwgaGRyKSkNCiAgICByZXMgPSBGYWtlUmVzcG9uc2UoaGVhZGVycywgdXJsKQ0KICAgIGNvb2tpZWphci5leHRyYWN0X2Nvb2tpZXMocmVzLCByZXEpDQogICAgcmV0dXJuIGNvb2tpZV9oZHINCg0KDQpjbGFzcyBGaWxlQ29va2llSmFyVGVzdHMoVGVzdENhc2UpOg0KICAgIGRlZiB0ZXN0X2x3cF92YWx1ZWxlc3NfY29va2llKHNlbGYpOg0KICAgICAgICAjIGNvb2tpZXMgd2l0aCBubyB2YWx1ZSBzaG91bGQgYmUgc2F2ZWQgYW5kIGxvYWRlZCBjb25zaXN0ZW50bHkNCiAgICAgICAgZnJvbSBjb29raWVsaWIgaW1wb3J0IExXUENvb2tpZUphcg0KICAgICAgICBmaWxlbmFtZSA9IHRlc3Rfc3VwcG9ydC5URVNURk4NCiAgICAgICAgYyA9IExXUENvb2tpZUphcigpDQogICAgICAgIGludGVyYWN0X25ldHNjYXBlKGMsICJodHRwOi8vd3d3LmFjbWUuY29tLyIsICdib28nKQ0KICAgICAgICBzZWxmLmFzc2VydEVxdWFsKGMuX2Nvb2tpZXNbInd3dy5hY21lLmNvbSJdWyIvIl1bImJvbyJdLnZhbHVlLCBOb25lKQ0KICAgICAgICB0cnk6DQogICAgICAgICAgICBjLnNhdmUoZmlsZW5hbWUsIGlnbm9yZV9kaXNjYXJkPVRydWUpDQogICAgICAgICAgICBjID0gTFdQQ29va2llSmFyKCkNCiAgICAgICAgICAgIGMubG9hZChmaWxlbmFtZSwgaWdub3JlX2Rpc2NhcmQ9VHJ1ZSkNCiAgICAgICAgZmluYWxseToNCiAgICAgICAgICAgIHRyeTogb3MudW5saW5rKGZpbGVuYW1lKQ0KICAgICAgICAgICAgZXhjZXB0IE9TRXJyb3I6IHBhc3MNCiAgICAgICAgc2VsZi5hc3NlcnRFcXVhbChjLl9jb29raWVzWyJ3d3cuYWNtZS5jb20iXVsiLyJdWyJib28iXS52YWx1ZSwgTm9uZSkNCg0KICAgIGRlZiB0ZXN0X2JhZF9tYWdpYyhzZWxmKToNCiAgICAgICAgZnJvbSBjb29raWVsaWIgaW1wb3J0IExXUENvb2tpZUphciwgTW96aWxsYUNvb2tpZUphciwgTG9hZEVycm9yDQogICAgICAgICMgSU9FcnJvcnMgKGVnLiBmaWxlIGRvZXNuJ3QgZXhpc3QpIGFyZSBhbGxvd2VkIHRvIHByb3BhZ2F0ZQ0KICAgICAgICBmaWxlbmFtZSA9IHRlc3Rfc3VwcG9ydC5URVNURk4NCiAgICAgICAgZm9yIGNvb2tpZWphcl9jbGFzcyBpbiBMV1BDb29raWVKYXIsIE1vemlsbGFDb29raWVKYXI6DQogICAgICAgICAgICBjID0gY29va2llamFyX2NsYXNzKCkNCiAgICAgICAgICAgIHRyeToNCiAgICAgICAgICAgICAgICBjLmxvYWQoZmlsZW5hbWU9ImZvciB0aGlzIHRlc3QgdG8gd29yaywgYSBmaWxlIHdpdGggdGhpcyAiDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJmaWxlbmFtZSBzaG91bGQgbm90IGV4aXN0IikNCiAgICAgICAgICAgIGV4Y2VwdCBJT0Vycm9yLCBleGM6DQogICAgICAgICAgICAgICAgIyBleGFjdGx5IElPRXJyb3IsIG5vdCBMb2FkRXJyb3INCiAgICAgICAgICAgICAgICBzZWxmLmFzc2VydEVxdWFsKGV4Yy5fX2NsYXNzX18sIElPRXJyb3IpDQogICAgICAgICAgICBlbHNlOg0KICAgICAgICAgICAgICAgIHNlbGYuZmFpbCgiZXhwZWN0ZWQgSU9FcnJvciBmb3IgaW52YWxpZCBmaWxlbmFtZSIpDQogICAgICAgICMgSW52YWxpZCBjb250ZW50cyBvZiBjb29raWVzIGZpbGUgKGVnLiBiYWQgbWFnaWMgc3RyaW5nKQ0KICAgICAgICAjIGNhdXNlcyBhIExvYWRFcnJvci4NCiAgICAgICAgdHJ5Og0KICAgICAgICAgICAgZiA9IG9wZW4oZmlsZW5hbWUsICJ3IikNCiAgICAgICAgICAgIGYud3JpdGUoIm9vcHNcbiIpDQogICAgICAgICAgICBmb3IgY29va2llamFyX2NsYXNzIGluIExXUENvb2tpZUphciwgTW96aWxsYUNvb2tpZUphcjoNCiAgICAgICAgICAgICAgICBjID0gY29va2llamFyX2NsYXNzKCkNCiAgICAgICAgICAgICAgICBzZWxmLmFzc2VydFJhaXNlcyhMb2FkRXJyb3IsIGMubG9hZCwgZmlsZW5hbWUpDQogICAgICAgIGZpbmFsbHk6DQogICAgICAgICAgICB0cnk6IG9zLnVubGluayhmaWxlbmFtZSkNCiAgICAgICAgICAgIGV4Y2VwdCBPU0Vycm9yOiBwYXNzDQoNCmNsYXNzIENvb2tpZVRlc3RzKFRlc3RDYXNlKToNCiAgICAjIFhYWA0KICAgICMgR2V0IHJpZCBvZiBzdHJpbmcgY29tcGFyaXNvbnMgd2hlcmUgbm90IGFjdHVhbGx5IHRlc3Rpbmcgc3RyIC8gcmVwci4NCiAgICAjIC5jbGVhcigpIGV0Yy4NCiAgICAjIElQIGFkZHJlc3NlcyBsaWtlIDUwIChzaW5nbGUgbnVtYmVyLCBubyBkb3QpIGFuZCBkb21haW4tbWF0Y2hpbmcNCiAgICAjICBmdW5jdGlvbnMgKGFuZCBpc19IRE4pPyAgU2VlIGRyYWZ0IFJGQyAyOTY1IGVycmF0YS4NCiAgICAjIFN0cmljdG5lc3Mgc3dpdGNoZXMNCiAgICAjIGlzX3RoaXJkX3BhcnR5KCkNCiAgICAjIHVudmVyaWZpYWJpbGl0eSAvIHRoaXJkLXBhcnR5IGJsb2NraW5nDQogICAgIyBOZXRzY2FwZSBjb29raWVzIHdvcmsgdGhlIHNhbWUgYXMgUkZDIDI5NjUgd2l0aCByZWdhcmQgdG8gcG9ydC4NCiAgICAjIFNldC1Db29raWUgd2l0aCBuZWdhdGl2ZSBtYXggYWdlLg0KICAgICMgSWYgdHVybiBSRkMgMjk2NSBoYW5kbGluZyBvZmYsIFNldC1Db29raWUyIGNvb2tpZXMgc2hvdWxkIG5vdCBjbG9iYmVyDQogICAgIyAgU2V0LUNvb2tpZSBjb29raWVzLg0KICAgICMgQ29va2llMiBzaG91bGQgYmUgc2VudCBpZiAqYW55KiBjb29raWVzIGFyZSBub3QgVjEgKGllLiBWMCBPUiBWMiBldGMuKS4NCiAgICAjIENvb2tpZXMgKFYxIGFuZCBWMCkgd2l0aCBubyBleHBpcnkgZGF0ZSBzaG91bGQgYmUgc2V0IHRvIGJlIGRpc2NhcmRlZC4NCiAgICAjIFJGQyAyOTY1IFF1b3Rpbmc6DQogICAgIyAgU2hvdWxkIGFjY2VwdCB1bnF1b3RlZCBjb29raWUtYXR0cmlidXRlIHZhbHVlcz8gIGNoZWNrIGVycmF0YSBkcmFmdC4NCiAgICAjICAgV2hpY2ggYXJlIHJlcXVpcmVkIG9uIHRoZSB3YXkgaW4gYW5kIG91dD8NCiAgICAjICBTaG91bGQgYWx3YXlzIHJldHVybiBxdW90ZWQgY29va2llLWF0dHJpYnV0ZSB2YWx1ZXM/DQogICAgIyBQcm9wZXIgdGVzdGluZyBvZiB3aGVuIFJGQyAyOTY1IGNsb2JiZXJzIE5ldHNjYXBlICh3YWl0aW5nIGZvciBlcnJhdGEpLg0KICAgICMgUGF0aC1tYXRjaCBvbiByZXR1cm4gKHNhbWUgZm9yIFYwIGFuZCBWMSkuDQogICAgIyBSRkMgMjk2NSBhY2NlcHRhbmNlIGFuZCByZXR1cm5pbmcgcnVsZXMNCiAgICAjICBTZXQtQ29va2llMiB3aXRob3V0IHZlcnNpb24gYXR0cmlidXRlIGlzIHJlamVjdGVkLg0KDQogICAgIyBOZXRzY2FwZSBwZWN1bGlhcml0aWVzIGxpc3QgZnJvbSBSb25hbGQgVHNjaGFsYXIuDQogICAgIyBUaGUgZmlyc3QgdHdvIHN0aWxsIG5lZWQgdGVzdHMsIHRoZSByZXN0IGFyZSBjb3ZlcmVkLg0KIyMgLSBRdW90aW5nOiBvbmx5IHF1b3RlcyBhcm91bmQgdGhlIGV4cGlyZXMgdmFsdWUgYXJlIHJlY29nbml6ZWQgYXMgc3VjaA0KIyMgICAoYW5kIHllcywgc29tZSBmb2xrcyBxdW90ZSB0aGUgZXhwaXJlcyB2YWx1ZSk7IHF1b3RlcyBhcm91bmQgYW55IG90aGVyDQojIyAgIHZhbHVlIGFyZSB0cmVhdGVkIGFzIHBhcnQgb2YgdGhlIHZhbHVlLg0KIyMgLSBXaGl0ZSBzcGFjZTogd2hpdGUgc3BhY2UgYXJvdW5kIG5hbWVzIGFuZCB2YWx1ZXMgaXMgaWdub3JlZA0KIyMgLSBEZWZhdWx0IHBhdGg6IGlmIG5vIHBhdGggcGFyYW1ldGVyIGlzIGdpdmVuLCB0aGUgcGF0aCBkZWZhdWx0cyB0byB0aGUNCiMjICAgcGF0aCBpbiB0aGUgcmVxdWVzdC11cmkgdXAgdG8sIGJ1dCBub3QgaW5jbHVkaW5nLCB0aGUgbGFzdCAnLycuIE5vdGUNCiMjICAgdGhhdCB0aGlzIGlzIGVudGlyZWx5IGRpZmZlcmVudCBmcm9tIHdoYXQgdGhlIHNwZWMgc2F5cy4NCiMjIC0gQ29tbWFzIGFuZCBvdGhlciBkZWxpbWl0ZXJzOiBOZXRzY2FwZSBqdXN0IHBhcnNlcyB1bnRpbCB0aGUgbmV4dCAnOycuDQojIyAgIFRoaXMgbWVhbnMgaXQgd2lsbCBhbGxvdyBjb21tYXMgZXRjIGluc2lkZSB2YWx1ZXMgKGFuZCB5ZXMsIGJvdGgNCiMjICAgY29tbWFzIGFuZCBlcXVhbHMgYXJlIGNvbW1vbmx5IGFwcGVhciBpbiB0aGUgY29va2llIHZhbHVlKS4gVGhpcyBhbHNvDQojIyAgIG1lYW5zIHRoYXQgaWYgeW91IGZvbGQgbXVsdGlwbGUgU2V0LUNvb2tpZSBoZWFkZXIgZmllbGRzIGludG8gb25lLA0KIyMgICBjb21tYS1zZXBhcmF0ZWQgbGlzdCwgaXQnbGwgYmUgYSBoZWFkYWNoZSB0byBwYXJzZSAoYXQgbGVhc3QgbXkgaGVhZA0KIyMgICBzdGFydHMgaHVydGluZyBldmVyeXRpbWUgSSB0aGluayBvZiB0aGF0IGNvZGUpLg0KIyMgLSBFeHBpcmVzOiBZb3UnbGwgZ2V0IGFsbCBzb3J0cyBvZiBkYXRlIGZvcm1hdHMgaW4gdGhlIGV4cGlyZXMsDQojIyAgIGluY2x1ZGluZyBlbXRweSBleHBpcmVzIGF0dHJpYnV0ZXMgKCJleHBpcmVzPSIpLiBCZSBhcyBmbGV4aWJsZSBhcyB5b3UNCiMjICAgY2FuLCBhbmQgY2VydGFpbmx5IGRvbid0IGV4cGVjdCB0aGUgd2Vla2RheSB0byBiZSB0aGVyZTsgaWYgeW91IGNhbid0DQojIyAgIHBhcnNlIGl0LCBqdXN0IGlnbm9yZSBpdCBhbmQgcHJldGVuZCBpdCdzIGEgc2Vzc2lvbiBjb29raWUuDQojIyAtIERvbWFpbi1tYXRjaGluZzogTmV0c2NhcGUgdXNlcyB0aGUgMi1kb3QgcnVsZSBmb3IgX2FsbF8gZG9tYWlucywgbm90DQojIyAgIGp1c3QgdGhlIDcgc3BlY2lhbCBUTEQncyBsaXN0ZWQgaW4gdGhlaXIgc3BlYy4gQW5kIGZvbGtzIHJlbHkgb24NCiMjICAgdGhhdC4uLg0KDQogICAgZGVmIHRlc3RfZG9tYWluX3JldHVybl9vayhzZWxmKToNCiAgICAgICAgIyB0ZXN0IG9wdGltaXphdGlvbjogLmRvbWFpbl9yZXR1cm5fb2soKSBzaG91bGQgZmlsdGVyIG91dCBtb3N0DQogICAgICAgICMgZG9tYWlucyBpbiB0aGUgQ29va2llSmFyIGJlZm9yZSB3ZSB0cnkgdG8gYWNjZXNzIHRoZW0gKGJlY2F1c2UgdGhhdA0KICAgICAgICAjIG1heSByZXF1aXJlIGRpc2sgYWNjZXNzIC0tIGluIHBhcnRpY3VsYXIsIHdpdGggTVNJRUNvb2tpZUphcikNCiAgICAgICAgIyBUaGlzIGlzIG9ubHkgYSByb3VnaCBjaGVjayBmb3IgcGVyZm9ybWFuY2UgcmVhc29ucywgc28gaXQncyBub3QgdG9vDQogICAgICAgICMgY3JpdGljYWwgYXMgbG9uZyBhcyBpdCdzIHN1ZmZpY2llbnRseSBsaWJlcmFsLg0KICAgICAgICBpbXBvcnQgY29va2llbGliLCB1cmxsaWIyDQogICAgICAgIHBvbCA9IGNvb2tpZWxpYi5EZWZhdWx0Q29va2llUG9saWN5KCkNCiAgICAgICAgZm9yIHVybCwgZG9tYWluLCBvayBpbiBbDQogICAgICAgICAgICAoImh0dHA6Ly9mb28uYmFyLmNvbS8iLCAiYmxhaC5jb20iLCBGYWxzZSksDQogICAgICAgICAgICAoImh0dHA6Ly9mb28uYmFyLmNvbS8iLCAicmh1YmFyYi5ibGFoLmNvbSIsIEZhbHNlKSwNCiAgICAgICAgICAgICgiaHR0cDovL2Zvby5iYXIuY29tLyIsICJyaHViYXJiLmZvby5iYXIuY29tIiwgRmFsc2UpLA0KICAgICAgICAgICAgKCJodHRwOi8vZm9vLmJhci5jb20vIiwgIi5mb28uYmFyLmNvbSIsIFRydWUpLA0KICAgICAgICAgICAgKCJodHRwOi8vZm9vLmJhci5jb20vIiwgImZvby5iYXIuY29tIiwgVHJ1ZSksDQogICAgICAgICAgICAoImh0dHA6Ly9mb28uYmFyLmNvbS8iLCAiLmJhci5jb20iLCBUcnVlKSwNCiAgICAgICAgICAgICgiaHR0cDovL2Zvby5iYXIuY29tLyIsICJjb20iLCBUcnVlKSwNCiAgICAgICAgICAgICgiaHR0cDovL2Zvby5jb20vIiwgInJodWJhcmIuZm9vLmNvbSIsIEZhbHNlKSwNCiAgICAgICAgICAgICgiaHR0cDovL2Zvby5jb20vIiwgIi5mb28uY29tIiwgVHJ1ZSksDQogICAgICAgICAgICAoImh0dHA6Ly9mb28uY29tLyIsICJmb28uY29tIiwgVHJ1ZSksDQogICAgICAgICAgICAoImh0dHA6Ly9mb28uY29tLyIsICJjb20iLCBUcnVlKSwNCiAgICAgICAgICAgICgiaHR0cDovL2Zvby8iLCAicmh1YmFyYi5mb28iLCBGYWxzZSksDQogICAgICAgICAgICAoImh0dHA6Ly9mb28vIiwgIi5mb28iLCBUcnVlKSwNCiAgICAgICAgICAgICgiaHR0cDovL2Zvby8iLCAiZm9vIiwgVHJ1ZSksDQogICAgICAgICAgICAoImh0dHA6Ly9mb28vIiwgImZvby5sb2NhbCIsIFRydWUpLA0KICAgICAgICAgICAgKCJodHRwOi8vZm9vLyIsICIubG9jYWwiLCBUcnVlKSwNCiAgICAgICAgICAgIF06DQogICAgICAgICAgICByZXF1ZXN0ID0gdXJsbGliMi5SZXF1ZXN0KHVybCkNCiAgICAgICAgICAgIHIgPSBwb2wuZG9tYWluX3JldHVybl9vayhkb21haW4sIHJlcXVlc3QpDQogICAgICAgICAgICBpZiBvazogc2VsZi5hc3NlcnRUcnVlKHIpDQogICAgICAgICAgICBlbHNlOiBzZWxmLmFzc2VydFRydWUobm90IHIpDQoNCiAgICBkZWYgdGVzdF9taXNzaW5nX3ZhbHVlKHNlbGYpOg0KICAgICAgICBmcm9tIGNvb2tpZWxpYiBpbXBvcnQgTW96aWxsYUNvb2tpZUphciwgbHdwX2Nvb2tpZV9zdHINCg0KICAgICAgICAjIG1pc3NpbmcgPSBzaWduIGluIENvb2tpZTogaGVhZGVyIGlzIHJlZ2FyZGVkIGJ5IE1vemlsbGEgYXMgYSBtaXNzaW5nDQogICAgICAgICMgbmFtZSwgYW5kIGJ5IGNvb2tpZWxpYiBhcyBhIG1pc3NpbmcgdmFsdWUNCiAgICAgICAgZmlsZW5hbWUgPSB0ZXN0X3N1cHBvcnQuVEVTVEZODQogICAgICAgIGMgPSBNb3ppbGxhQ29va2llSmFyKGZpbGVuYW1lKQ0KICAgICAgICBpbnRlcmFjdF9uZXRzY2FwZShjLCAiaHR0cDovL3d3dy5hY21lLmNvbS8iLCAnZWdncycpDQogICAgICAgIGludGVyYWN0X25ldHNjYXBlKGMsICJodHRwOi8vd3d3LmFjbWUuY29tLyIsICcic3BhbSI7IHBhdGg9L2Zvby8nKQ0KICAgICAgICBjb29raWUgPSBjLl9jb29raWVzWyJ3d3cuYWNtZS5jb20iXVsiLyJdWyJlZ2dzIl0NCiAgICAgICAgc2VsZi5hc3NlcnRUcnVlKGNvb2tpZS52YWx1ZSBpcyBOb25lKQ0KICAgICAgICBzZWxmLmFzc2VydEVxdWFsKGNvb2tpZS5uYW1lLCAiZWdncyIpDQogICAgICAgIGNvb2tpZSA9IGMuX2Nvb2tpZXNbInd3dy5hY21lLmNvbSJdWycvZm9vLyddWycic3BhbSInXQ0KICAgICAgICBzZWxmLmFzc2VydFRydWUoY29va2llLnZhbHVlIGlzIE5vbmUpDQogICAgICAgIHNlbGYuYXNzZXJ0RXF1YWwoY29va2llLm5hbWUsICcic3BhbSInKQ0KICAgICAgICBzZWxmLmFzc2VydEVxdWFsKGx3cF9jb29raWVfc3RyKGNvb2tpZSksICgNCiAgICAgICAgICAgIHInInNwYW0iOyBwYXRoPSIvZm9vLyI7IGRvbWFpbj0id3d3LmFjbWUuY29tIjsgJw0KICAgICAgICAgICAgJ3BhdGhfc3BlYzsgZGlzY2FyZDsgdmVyc2lvbj0wJykpDQogICAgICAgIG9sZF9zdHIgPSByZXByKGMpDQogICAgICAgIGMuc2F2ZShpZ25vcmVfZXhwaXJlcz1UcnVlLCBpZ25vcmVfZGlzY2FyZD1UcnVlKQ0KICAgICAgICB0cnk6DQogICAgICAgICAgICBjID0gTW96aWxsYUNvb2tpZUphcihmaWxlbmFtZSkNCiAgICAgICAgICAgIGMucmV2ZXJ0KGlnbm9yZV9leHBpcmVzPVRydWUsIGlnbm9yZV9kaXNjYXJkPVRydWUpDQogICAgICAgIGZpbmFsbHk6DQogICAgICAgICAgICBvcy51bmxpbmsoYy5maWxlbmFtZSkNCiAgICAgICAgIyBjb29raWVzIHVuY2hhbmdlZCBhcGFydCBmcm9tIGxvc3QgaW5mbyByZS4gd2hldGhlciBwYXRoIHdhcyBzcGVjaWZpZWQNCiAgICAgICAgc2VsZi5hc3NlcnRFcXVhbCgNCiAgICAgICAgICAgIHJlcHIoYyksDQogICAgICAgICAgICByZS5zdWIoInBhdGhfc3BlY2lmaWVkPSVzIiAlIFRydWUsICJwYXRoX3NwZWNpZmllZD0lcyIgJSBGYWxzZSwNCiAgICAgICAgICAgICAgICAgICBvbGRfc3RyKQ0KICAgICAgICAgICAgKQ0KICAgICAgICBzZWxmLmFzc2VydEVxdWFsKGludGVyYWN0X25ldHNjYXBlKGMsICJodHRwOi8vd3d3LmFjbWUuY29tL2Zvby8iKSwNCiAgICAgICAgICAgICAgICAgICAgICAgICAnInNwYW0iOyBlZ2dzJykNCg0KICAgIGRlZiB0ZXN0X3JmYzIxMDlfaGFuZGxpbmcoc2VsZik6DQogICAgICAgICMgUkZDIDIxMDkgY29va2llcyBhcmUgaGFuZGxlZCBhcyBSRkMgMjk2NSBvciBOZXRzY2FwZSBjb29raWVzLA0KICAgICAgICAjIGRlcGVuZGVudCBvbiBwb2xpY3kgc2V0dGluZ3MNCiAgICAgICAgZnJvbSBjb29raWVsaWIgaW1wb3J0IENvb2tpZUphciwgRGVmYXVsdENvb2tpZVBvbGljeQ0KDQogICAgICAgIGZvciByZmMyMTA5X2FzX25ldHNjYXBlLCByZmMyOTY1LCB2ZXJzaW9uIGluIFsNCiAgICAgICAgICAgICMgZGVmYXVsdCBhY2NvcmRpbmcgdG8gcmZjMjk2NSBpZiBub3QgZXhwbGljaXRseSBzcGVjaWZpZWQNCiAgICAgICAgICAgIChOb25lLCBGYWxzZSwgMCksDQogICAgICAgICAgICAoTm9uZSwgVHJ1ZSwgMSksDQogICAgICAgICAgICAjIGV4cGxpY2l0IHJmYzIxMDlfYXNfbmV0c2NhcGUNCiAgICAgICAgICAgIChGYWxzZSwgRmFsc2UsIE5vbmUpLCAgIyB2ZXJzaW9uIE5vbmUgaGVyZSBtZWFucyBubyBjb29raWUgc3RvcmVkDQogICAgICAgICAgICAoRmFsc2UsIFRydWUsIDEpLA0KICAgICAgICAgICAgKFRydWUsIEZhbHNlLCAwKSwNCiAgICAgICAgICAgIChUcnVlLCBUcnVlLCAwKSwNCiAgICAgICAgICAgIF06DQogICAgICAgICAgICBwb2xpY3kgPSBEZWZhdWx0Q29va2llUG9saWN5KA0KICAgICAgICAgICAgICAgIHJmYzIxMDlfYXNfbmV0c2NhcGU9cmZjMjEwOV9hc19uZXRzY2FwZSwNCiAgICAgICAgICAgICAgICByZmMyOTY1PXJmYzI5NjUpDQogICAgICAgICAgICBjID0gQ29va2llSmFyKHBvbGljeSkNCiAgICAgICAgICAgIGludGVyYWN0X25ldHNjYXBlKGMsICJodHRwOi8vd3d3LmV4YW1wbGUuY29tLyIsICJuaT1uaTsgVmVyc2lvbj0xIikNCiAgICAgICAgICAgIHRyeToNCiAgICAgICAgICAgICAgICBjb29raWUgPSBjLl9jb29raWVzWyJ3d3cuZXhhbXBsZS5jb20iXVsiLyJdWyJuaSJdDQogICAgICAgICAgICBleGNlcHQgS2V5RXJyb3I6DQogICAgICAgICAgICAgICAgc2VsZi5hc3NlcnRUcnVlKHZlcnNpb24gaXMgTm9uZSkgICMgZGlkbid0IGV4cGVjdCBhIHN0b3JlZCBjb29raWUNCiAgICAgICAgICAgIGVsc2U6DQogICAgICAgICAgICAgICAgc2VsZi5hc3NlcnRFcXVhbChjb29raWUudmVyc2lvbiwgdmVyc2lvbikNCiAgICAgICAgICAgICAgICAjIDI5NjUgY29va2llcyBhcmUgdW5hZmZlY3RlZA0KICAgICAgICAgICAgICAgIGludGVyYWN0XzI5NjUoYywgImh0dHA6Ly93d3cuZXhhbXBsZS5jb20vIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJmb289YmFyOyBWZXJzaW9uPTEiKQ0KICAgICAgICAgICAgICAgIGlmIHJmYzI5NjU6DQogICAgICAgICAgICAgICAgICAgIGNvb2tpZTI5NjUgPSBjLl9jb29raWVzWyJ3d3cuZXhhbXBsZS5jb20iXVsiLyJdWyJmb28iXQ0KICAgICAgICAgICAgICAgICAgICBzZWxmLmFzc2VydEVxdWFsKGNvb2tpZTI5NjUudmVyc2lvbiwgMSkNCg0KICAgIGRlZiB0ZXN0X25zX3BhcnNlcihzZWxmKToNCiAgICAgICAgZnJvbSBjb29raWVsaWIgaW1wb3J0IENvb2tpZUphciwgREVGQVVMVF9IVFRQX1BPUlQNCg0KICAgICAgICBjID0gQ29va2llSmFyKCkNCiAgICAgICAgaW50ZXJhY3RfbmV0c2NhcGUoYywgImh0dHA6Ly93d3cuYWNtZS5jb20vIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgJ3NwYW09ZWdnczsgRG9NYWluPS5hY21lLmNvbTsgcG9ydDsgYmxBcmdoPSJmZWVwIicpDQogICAgICAgIGludGVyYWN0X25ldHNjYXBlKGMsICJodHRwOi8vd3d3LmFjbWUuY29tLyIsICduaT1uaTsgcG9ydD04MCw4MDgwJykNCiAgICAgICAgaW50ZXJhY3RfbmV0c2NhcGUoYywgImh0dHA6Ly93d3cuYWNtZS5jb206ODAvIiwgJ25pbmk9bmknKQ0KICAgICAgICBpbnRlcmFjdF9uZXRzY2FwZShjLCAiaHR0cDovL3d3dy5hY21lLmNvbTo4MC8iLCAnZm9vPWJhcjsgZXhwaXJlcz0nKQ0KICAgICAgICBpbnRlcmFjdF9uZXRzY2FwZShjLCAiaHR0cDovL3d3dy5hY21lLmNvbTo4MC8iLCAnc3BhbT1lZ2dzOyAnDQogICAgICAgICAgICAgICAgICAgICAgICAgICdleHBpcmVzPSJGb28gQmFyIDI1IDMzOjIyOjExIDMwMjIiJykNCg0KICAgICAgICBjb29raWUgPSBjLl9jb29raWVzWyIuYWNtZS5jb20iXVsiLyJdWyJzcGFtIl0NCiAgICAgICAgc2VsZi5hc3NlcnRFcXVhbChjb29raWUuZG9tYWluLCAiLmFjbWUuY29tIikNCiAgICAgICAgc2VsZi5hc3NlcnRUcnVlKGNvb2tpZS5kb21haW5fc3BlY2lmaWVkKQ0KICAgICAgICBzZWxmLmFzc2VydEVxdWFsKGNvb2tpZS5wb3J0LCBERUZBVUxUX0hUVFBfUE9SVCkNCiAgICAgICAgc2VsZi5hc3NlcnRUcnVlKG5vdCBjb29raWUucG9ydF9zcGVjaWZpZWQpDQogICAgICAgICMgY2FzZSBpcyBwcmVzZXJ2ZWQNCiAgICAgICAgc2VsZi5hc3NlcnRUcnVlKGNvb2tpZS5oYXNfbm9uc3RhbmRhcmRfYXR0cigiYmxBcmdoIikgYW5kDQogICAgICAgICAgICAgICAgICAgICBub3QgY29va2llLmhhc19ub25zdGFuZGFyZF9hdHRyKCJibGFyZ2giKSkNCg0KICAgICAgICBjb29raWUgPSBjLl9jb29raWVzWyJ3d3cuYWNtZS5jb20iXVsiLyJdWyJuaSJdDQogICAgICAgIHNlbGYuYXNzZXJ0RXF1YWwoY29va2llLmRvbWFpbiwgInd3dy5hY21lLmNvbSIpDQogICAgICAgIHNlbGYuYXNzZXJ0VHJ1ZShub3QgY29va2llLmRvbWFpbl9zcGVjaWZpZWQpDQogICAgICAgIHNlbGYuYXNzZXJ0RXF1YWwoY29va2llLnBvcnQsICI4MCw4MDgwIikNCiAgICAgICAgc2VsZi5hc3NlcnRUcnVlKGNvb2tpZS5wb3J0X3NwZWNpZmllZCkNCg0KICAgICAgICBjb29raWUgPSBjLl9jb29raWVzWyJ3d3cuYWNtZS5jb20iXVsiLyJdWyJuaW5pIl0NCiAgICAgICAgc2VsZi5hc3NlcnRUcnVlKGNvb2tpZS5wb3J0IGlzIE5vbmUpDQogICAgICAgIHNlbGYuYXNzZXJ0VHJ1ZShub3QgY29va2llLnBvcnRfc3BlY2lmaWVkKQ0KDQogICAgICAgICMgaW52YWxpZCBleHBpcmVzIHNob3VsZCBub3QgY2F1c2UgY29va2llIHRvIGJlIGRyb3BwZWQNCiAgICAgICAgZm9vID0gYy5fY29va2llc1sid3d3LmFjbWUuY29tIl1bIi8iXVsiZm9vIl0NCiAgICAgICAgc3BhbSA9IGMuX2Nvb2tpZXNbInd3dy5hY21lLmNvbSJdWyIvIl1bImZvbyJdDQogICAgICAgIHNlbGYuYXNzZXJ0VHJ1ZShmb28uZXhwaXJlcyBpcyBOb25lKQ0KICAgICAgICBzZWxmLmFzc2VydFRydWUoc3BhbS5leHBpcmVzIGlzIE5vbmUpDQoNCiAgICBkZWYgdGVzdF9uc19wYXJzZXJfc3BlY2lhbF9uYW1lcyhzZWxmKToNCiAgICAgICAgIyBuYW1lcyBzdWNoIGFzICdleHBpcmVzJyBhcmUgbm90IHNwZWNpYWwgaW4gZmlyc3QgbmFtZT12YWx1ZSBwYWlyDQogICAgICAgICMgb2YgU2V0LUNvb2tpZTogaGVhZGVyDQogICAgICAgIGZyb20gY29va2llbGliIGltcG9ydCBDb29raWVKYXINCg0KICAgICAgICBjID0gQ29va2llSmFyKCkNCiAgICAgICAgaW50ZXJhY3RfbmV0c2NhcGUoYywgImh0dHA6Ly93d3cuYWNtZS5jb20vIiwgJ2V4cGlyZXM9ZWdncycpDQogICAgICAgIGludGVyYWN0X25ldHNjYXBlKGMsICJodHRwOi8vd3d3LmFjbWUuY29tLyIsICd2ZXJzaW9uPWVnZ3M7IHNwYW09ZWdncycpDQoNCiAgICAgICAgY29va2llcyA9IGMuX2Nvb2tpZXNbInd3dy5hY21lLmNvbSJdWyIvIl0NCiAgICAgICAgc2VsZi5hc3NlcnRUcnVlKCdleHBpcmVzJyBpbiBjb29raWVzKQ0KICAgICAgICBzZWxmLmFzc2VydFRydWUoJ3ZlcnNpb24nIGluIGNvb2tpZXMpDQoNCiAgICBkZWYgdGVzdF9leHBpcmVzKHNlbGYpOg0KICAgICAgICBmcm9tIGNvb2tpZWxpYiBpbXBvcnQgdGltZTJuZXRzY2FwZSwgQ29va2llSmFyDQoNCiAgICAgICAgIyBpZiBleHBpcmVzIGlzIGluIGZ1dHVyZSwga2VlcCBjb29raWUuLi4NCiAgICAgICAgYyA9IENvb2tpZUphcigpDQogICAgICAgIGZ1dHVyZSA9IHRpbWUybmV0c2NhcGUodGltZS50aW1lKCkrMzYwMCkNCiAgICAgICAgaW50ZXJhY3RfbmV0c2NhcGUoYywgImh0dHA6Ly93d3cuYWNtZS5jb20vIiwgJ3NwYW09ImJhciI7IGV4cGlyZXM9JXMnICUNCiAgICAgICAgICAgICAgICAgICAgICAgICAgZnV0dXJlKQ0KICAgICAgICBzZWxmLmFzc2VydEVxdWFsKGxlbihjKSwgMSkNCiAgICAgICAgbm93ID0gdGltZTJuZXRzY2FwZSh0aW1lLnRpbWUoKS0xKQ0KICAgICAgICAjIC4uLiBhbmQgaWYgaW4gcGFzdCBvciBwcmVzZW50LCBkaXNjYXJkIGl0DQogICAgICAgIGludGVyYWN0X25ldHNjYXBlKGMsICJodHRwOi8vd3d3LmFjbWUuY29tLyIsICdmb289ImVnZ3MiOyBleHBpcmVzPSVzJyAlDQogICAgICAgICAgICAgICAgICAgICAgICAgIG5vdykNCiAgICAgICAgaCA9IGludGVyYWN0X25ldHNjYXBlKGMsICJodHRwOi8vd3d3LmFjbWUuY29tLyIpDQogICAgICAgIHNlbGYuYXNzZXJ0RXF1YWwobGVuKGMpLCAxKQ0KICAgICAgICBzZWxmLmFzc2VydFRydWUoJ3NwYW09ImJhciInIGluIGggYW5kICJmb28iIG5vdCBpbiBoKQ0KDQogICAgICAgICMgbWF4LWFnZSB0YWtlcyBwcmVjZWRlbmNlIG92ZXIgZXhwaXJlcywgYW5kIHplcm8gbWF4LWFnZSBpcyByZXF1ZXN0IHRvDQogICAgICAgICMgZGVsZXRlIGJvdGggbmV3IGNvb2tpZSBhbmQgYW55IG9sZCBtYXRjaGluZyBjb29raWUNCiAgICAgICAgaW50ZXJhY3RfbmV0c2NhcGUoYywgImh0dHA6Ly93d3cuYWNtZS5jb20vIiwgJ2VnZ3M9ImJhciI7IGV4cGlyZXM9JXMnICUNCiAgICAgICAgICAgICAgICAgICAgICAgICAgZnV0dXJlKQ0KICAgICAgICBpbnRlcmFjdF9uZXRzY2FwZShjLCAiaHR0cDovL3d3dy5hY21lLmNvbS8iLCAnYmFyPSJiYXIiOyBleHBpcmVzPSVzJyAlDQogICAgICAgICAgICAgICAgICAgICAgICAgIGZ1dHVyZSkNCiAgICAgICAgc2VsZi5hc3NlcnRFcXVhbChsZW4oYyksIDMpDQogICAgICAgIGludGVyYWN0X25ldHNjYXBlKGMsICJodHRwOi8vd3d3LmFjbWUuY29tLyIsICdlZ2dzPSJiYXIiOyAnDQogICAgICAgICAgICAgICAgICAgICAgICAgICdleHBpcmVzPSVzOyBtYXgtYWdlPTAnICUgZnV0dXJlKQ0KICAgICAgICBpbnRlcmFjdF9uZXRzY2FwZShjLCAiaHR0cDovL3d3dy5hY21lLmNvbS8iLCAnYmFyPSJiYXIiOyAnDQogICAgICAgICAgICAgICAgICAgICAgICAgICdtYXgtYWdlPTA7IGV4cGlyZXM9JXMnICUgZnV0dXJlKQ0KICAgICAgICBoID0gaW50ZXJhY3RfbmV0c2NhcGUoYywgImh0dHA6Ly93d3cuYWNtZS5jb20vIikNCiAgICAgICAgc2VsZi5hc3NlcnRFcXVhbChsZW4oYyksIDEpDQoNCiAgICAgICAgIyB0ZXN0IGV4cGlyeSBhdCBlbmQgb2Ygc2Vzc2lvbiBmb3IgY29va2llcyB3aXRoIG5vIGV4cGlyZXMgYXR0cmlidXRlDQogICAgICAgIGludGVyYWN0X25ldHNjYXBlKGMsICJodHRwOi8vd3d3LnJodWJhcmIubmV0LyIsICd3aHVtPSJmaXp6IicpDQogICAgICAgIHNlbGYuYXNzZXJ0RXF1YWwobGVuKGMpLCAyKQ0KICAgICAgICBjLmNsZWFyX3Nlc3Npb25fY29va2llcygpDQogICAgICAgIHNlbGYuYXNzZXJ0RXF1YWwobGVuKGMpLCAxKQ0KICAgICAgICBzZWxmLmFzc2VydEluKCdzcGFtPSJiYXIiJywgaCkNCg0KICAgICAgICAjIFhYWCBSRkMgMjk2NSBleHBpcnkgcnVsZXMgKHNvbWUgYXBwbHkgdG8gVjAgdG9vKQ0KDQogICAgZGVmIHRlc3RfZGVmYXVsdF9wYXRoKHNlbGYpOg0KICAgICAgICBmcm9tIGNvb2tpZWxpYiBpbXBvcnQgQ29va2llSmFyLCBEZWZhdWx0Q29va2llUG9saWN5DQoNCiAgICAgICAgIyBSRkMgMjk2NQ0KICAgICAgICBwb2wgPSBEZWZhdWx0Q29va2llUG9saWN5KHJmYzI5NjU9VHJ1ZSkNCg0KICAgICAgICBjID0gQ29va2llSmFyKHBvbCkNCiAgICAgICAgaW50ZXJhY3RfMjk2NShjLCAiaHR0cDovL3d3dy5hY21lLmNvbS8iLCAnc3BhbT0iYmFyIjsgVmVyc2lvbj0iMSInKQ0KICAgICAgICBzZWxmLmFzc2VydEluKCIvIiwgYy5fY29va2llc1sid3d3LmFjbWUuY29tIl0pDQoNCiAgICAgICAgYyA9IENvb2tpZUphcihwb2wpDQogICAgICAgIGludGVyYWN0XzI5NjUoYywgImh0dHA6Ly93d3cuYWNtZS5jb20vYmxhaCIsICdlZ2dzPSJiYXIiOyBWZXJzaW9uPSIxIicpDQogICAgICAgIHNlbGYuYXNzZXJ0SW4oIi8iLCBjLl9jb29raWVzWyJ3d3cuYWNtZS5jb20iXSkNCg0KICAgICAgICBjID0gQ29va2llSmFyKHBvbCkNCiAgICAgICAgaW50ZXJhY3RfMjk2NShjLCAiaHR0cDovL3d3dy5hY21lLmNvbS9ibGFoL3JodWJhcmIiLA0KICAgICAgICAgICAgICAgICAgICAgICdlZ2dzPSJiYXIiOyBWZXJzaW9uPSIxIicpDQogICAgICAgIHNlbGYuYXNzZXJ0SW4oIi9ibGFoLyIsIGMuX2Nvb2tpZXNbInd3dy5hY21lLmNvbSJdKQ0KDQogICAgICAgIGMgPSBDb29raWVKYXIocG9sKQ0KICAgICAgICBpbnRlcmFjdF8yOTY1KGMsICJodHRwOi8vd3d3LmFjbWUuY29tL2JsYWgvcmh1YmFyYi8iLA0KICAgICAgICAgICAgICAgICAgICAgICdlZ2dzPSJiYXIiOyBWZXJzaW9uPSIxIicpDQogICAgICAgIHNlbGYuYXNzZXJ0SW4oIi9ibGFoL3JodWJhcmIvIiwgYy5fY29va2llc1sid3d3LmFjbWUuY29tIl0pDQoNCiAgICAgICAgIyBOZXRzY2FwZQ0KDQogICAgICAgIGMgPSBDb29raWVKYXIoKQ0KICAgICAgICBpbnRlcmFjdF9uZXRzY2FwZShjLCAiaHR0cDovL3d3dy5hY21lLmNvbS8iLCAnc3BhbT0iYmFyIicpDQogICAgICAgIHNlbGYuYXNzZXJ0SW4oIi8iLCBjLl9jb29raWVzWyJ3d3cuYWNtZS5jb20iXSkNCg0KICAgICAgICBjID0gQ29va2llSmFyKCkNCiAgICAgICAgaW50ZXJhY3RfbmV0c2NhcGUoYywgImh0dHA6Ly93d3cuYWNtZS5jb20vYmxhaCIsICdlZ2dzPSJiYXIiJykNCiAgICAgICAgc2VsZi5hc3NlcnRJbigiLyIsIGMuX2Nvb2tpZXNbInd3dy5hY21lLmNvbSJdKQ0KDQogICAgICAgIGMgPSBDb29raWVKYXIoKQ0KICAgICAgICBpbnRlcmFjdF9uZXRzY2FwZShjLCAiaHR0cDovL3d3dy5hY21lLmNvbS9ibGFoL3JodWJhcmIiLCAnZWdncz0iYmFyIicpDQogICAgICAgIHNlbGYuYXNzZXJ0SW4oIi9ibGFoIiwgYy5fY29va2llc1sid3d3LmFjbWUuY29tIl0pDQoNCiAgICAgICAgYyA9IENvb2tpZUphcigpDQogICAgICAgIGludGVyYWN0X25ldHNjYXBlKGMsICJodHRwOi8vd3d3LmFjbWUuY29tL2JsYWgvcmh1YmFyYi8iLCAnZWdncz0iYmFyIicpDQogICAgICAgIHNlbGYuYXNzZXJ0SW4oIi9ibGFoL3JodWJhcmIiLCBjLl9jb29raWVzWyJ3d3cuYWNtZS5jb20iXSkNCg0KICAgIGRlZiB0ZXN0X2RlZmF1bHRfcGF0aF93aXRoX3F1ZXJ5KHNlbGYpOg0KICAgICAgICBjaiA9IGNvb2tpZWxpYi5Db29raWVKYXIoKQ0KICAgICAgICB1cmkgPSAiaHR0cDovL2V4YW1wbGUuY29tLz9zcGFtL2VnZ3MiDQogICAgICAgIHZhbHVlID0gJ2VnZ3M9ImJhciInDQogICAgICAgIGludGVyYWN0X25ldHNjYXBlKGNqLCB1cmksIHZhbHVlKQ0KICAgICAgICAjIGRlZmF1bHQgcGF0aCBkb2VzIG5vdCBpbmNsdWRlIHF1ZXJ5LCBzbyBpcyAiLyIsIG5vdCAiLz9zcGFtIg0KICAgICAgICBzZWxmLmFzc2VydEluKCIvIiwgY2ouX2Nvb2tpZXNbImV4YW1wbGUuY29tIl0pDQogICAgICAgICMgY29va2llIGlzIHNlbnQgYmFjayB0byB0aGUgc2FtZSBVUkkNCiAgICAgICAgc2VsZi5hc3NlcnRFcXVhbChpbnRlcmFjdF9uZXRzY2FwZShjaiwgdXJpKSwgdmFsdWUpDQoNCiAgICBkZWYgdGVzdF9lc2NhcGVfcGF0aChzZWxmKToNCiAgICAgICAgZnJvbSBjb29raWVsaWIgaW1wb3J0IGVzY2FwZV9wYXRoDQogICAgICAgIGNhc2VzID0gWw0KICAgICAgICAgICAgIyBxdW90ZWQgc2FmZQ0KICAgICAgICAgICAgKCIvZm9vJTJmL2JhciIsICIvZm9vJTJGL2JhciIpLA0KICAgICAgICAgICAgKCIvZm9vJTJGL2JhciIsICIvZm9vJTJGL2JhciIpLA0KICAgICAgICAgICAgIyBxdW90ZWQgJQ0KICAgICAgICAgICAgKCIvZm9vJSUvYmFyIiwgIi9mb28lJS9iYXIiKSwNCiAgICAgICAgICAgICMgcXVvdGVkIHVuc2FmZQ0KICAgICAgICAgICAgKCIvZm8lMTlvL2JhciIsICIvZm8lMTlvL2JhciIpLA0KICAgICAgICAgICAgKCIvZm8lN2RvL2JhciIsICIvZm8lN0RvL2JhciIpLA0KICAgICAgICAgICAgIyB1bnF1b3RlZCBzYWZlDQogICAgICAgICAgICAoIi9mb28vYmFyJiIsICIvZm9vL2JhciYiKSwNCiAgICAgICAgICAgICgiL2Zvby8vYmFyIiwgIi9mb28vL2JhciIpLA0KICAgICAgICAgICAgKCJcMTc2L2Zvby9iYXIiLCAiXDE3Ni9mb28vYmFyIiksDQogICAgICAgICAgICAjIHVucXVvdGVkIHVuc2FmZQ0KICAgICAgICAgICAgKCIvZm9vXDAzMS9iYXIiLCAiL2ZvbyUxOS9iYXIiKSwNCiAgICAgICAgICAgICgiL1wxNzVmb28vYmFyIiwgIi8lN0Rmb28vYmFyIiksDQogICAgICAgICAgICAjIHVuaWNvZGUNCiAgICAgICAgICAgICh1Ii9mb28vYmFyXHVhYmNkIiwgIi9mb28vYmFyJUVBJUFGJThEIiksICAjIFVURi04IGVuY29kZWQNCiAgICAgICAgICAgIF0NCiAgICAgICAgZm9yIGFyZywgcmVzdWx0IGluIGNhc2VzOg0KICAgICAgICAgICAgc2VsZi5hc3NlcnRFcXVhbChlc2NhcGVfcGF0aChhcmcpLCByZXN1bHQpDQoNCiAgICBkZWYgdGVzdF9yZXF1ZXN0X3BhdGgoc2VsZik6DQogICAgICAgIGZyb20gdXJsbGliMiBpbXBvcnQgUmVxdWVzdA0KICAgICAgICBmcm9tIGNvb2tpZWxpYiBpbXBvcnQgcmVxdWVzdF9wYXRoDQogICAgICAgICMgd2l0aCBwYXJhbWV0ZXJzDQogICAgICAgIHJlcSA9IFJlcXVlc3QoImh0dHA6Ly93d3cuZXhhbXBsZS5jb20vcmhldW0vcmhhcG9udGljdW07Ig0KICAgICAgICAgICAgICAgICAgICAgICJmb289YmFyO3Npbmc9c29uZz9hcHBsZXM9cGVhcnMmc3BhbT1lZ2dzI25pIikNCiAgICAgICAgc2VsZi5hc3NlcnRFcXVhbChyZXF1ZXN0X3BhdGgocmVxKSwNCiAgICAgICAgICAgICAgICAgICAgICAgICAiL3JoZXVtL3JoYXBvbnRpY3VtO2Zvbz1iYXI7c2luZz1zb25nIikNCiAgICAgICAgIyB3aXRob3V0IHBhcmFtZXRlcnMNCiAgICAgICAgcmVxID0gUmVxdWVzdCgiaHR0cDovL3d3dy5leGFtcGxlLmNvbS9yaGV1bS9yaGFwb250aWN1bT8iDQogICAgICAgICAgICAgICAgICAgICAgImFwcGxlcz1wZWFycyZzcGFtPWVnZ3MjbmkiKQ0KICAgICAgICBzZWxmLmFzc2VydEVxdWFsKHJlcXVlc3RfcGF0aChyZXEpLCAiL3JoZXVtL3JoYXBvbnRpY3VtIikNCiAgICAgICAgIyBtaXNzaW5nIGZpbmFsIHNsYXNoDQogICAgICAgIHJlcSA9IFJlcXVlc3QoImh0dHA6Ly93d3cuZXhhbXBsZS5jb20iKQ0KICAgICAgICBzZWxmLmFzc2VydEVxdWFsKHJlcXVlc3RfcGF0aChyZXEpLCAiLyIpDQoNCiAgICBkZWYgdGVzdF9yZXF1ZXN0X3BvcnQoc2VsZik6DQogICAgICAgIGZyb20gdXJsbGliMiBpbXBvcnQgUmVxdWVzdA0KICAgICAgICBmcm9tIGNvb2tpZWxpYiBpbXBvcnQgcmVxdWVzdF9wb3J0LCBERUZBVUxUX0hUVFBfUE9SVA0KICAgICAgICByZXEgPSBSZXF1ZXN0KCJodHRwOi8vd3d3LmFjbWUuY29tOjEyMzQvIiwNCiAgICAgICAgICAgICAgICAgICAgICBoZWFkZXJzPXsiSG9zdCI6ICJ3d3cuYWNtZS5jb206NDMyMSJ9KQ0KICAgICAgICBzZWxmLmFzc2VydEVxdWFsKHJlcXVlc3RfcG9ydChyZXEpLCAiMTIzNCIpDQogICAgICAgIHJlcSA9IFJlcXVlc3QoImh0dHA6Ly93d3cuYWNtZS5jb20vIiwNCiAgICAgICAgICAgICAgICAgICAgICBoZWFkZXJzPXsiSG9zdCI6ICJ3d3cuYWNtZS5jb206NDMyMSJ9KQ0KICAgICAgICBzZWxmLmFzc2VydEVxdWFsKHJlcXVlc3RfcG9ydChyZXEpLCBERUZBVUxUX0hUVFBfUE9SVCkNCg0KICAgIGRlZiB0ZXN0X3JlcXVlc3RfaG9zdChzZWxmKToNCiAgICAgICAgZnJvbSB1cmxsaWIyIGltcG9ydCBSZXF1ZXN0DQogICAgICAgIGZyb20gY29va2llbGliIGltcG9ydCByZXF1ZXN0X2hvc3QNCiAgICAgICAgIyB0aGlzIHJlcXVlc3QgaXMgaWxsZWdhbCAoUkZDMjYxNiwgMTQuMi4zKQ0KICAgICAgICByZXEgPSBSZXF1ZXN0KCJodHRwOi8vMS4xLjEuMS8iLA0KICAgICAgICAgICAgICAgICAgICAgIGhlYWRlcnM9eyJIb3N0IjogInd3dy5hY21lLmNvbTo4MCJ9KQ0KICAgICAgICAjIGxpYnd3dy1wZXJsIHdhbnRzIHRoaXMgcmVzcG9uc2UsIGJ1dCB0aGF0IHNlZW1zIHdyb25nIChSRkMgMjYxNiwNCiAgICAgICAgIyBzZWN0aW9uIDUuMiwgcG9pbnQgMS4sIGFuZCBSRkMgMjk2NSBzZWN0aW9uIDEsIHBhcmFncmFwaCAzKQ0KICAgICAgICAjc2VsZi5hc3NlcnRFcXVhbChyZXF1ZXN0X2hvc3QocmVxKSwgInd3dy5hY21lLmNvbSIpDQogICAgICAgIHNlbGYuYXNzZXJ0RXF1YWwocmVxdWVzdF9ob3N0KHJlcSksICIxLjEuMS4xIikNCiAgICAgICAgcmVxID0gUmVxdWVzdCgiaHR0cDovL3d3dy5hY21lLmNvbS8iLA0KICAgICAgICAgICAgICAgICAgICAgIGhlYWRlcnM9eyJIb3N0IjogImlycmVsZXZhbnQuY29tIn0pDQogICAgICAgIHNlbGYuYXNzZXJ0RXF1YWwocmVxdWVzdF9ob3N0KHJlcSksICJ3d3cuYWNtZS5jb20iKQ0KICAgICAgICAjIG5vdCBhY3R1YWxseSBzdXJlIHRoaXMgb25lIGlzIHZhbGlkIFJlcXVlc3Qgb2JqZWN0LCBzbyBtYXliZSBzaG91bGQNCiAgICAgICAgIyByZW1vdmUgdGVzdCBmb3Igbm8gaG9zdCBpbiB1cmwgaW4gcmVxdWVzdF9ob3N0IGZ1bmN0aW9uPw0KICAgICAgICByZXEgPSBSZXF1ZXN0KCIvcmVzb3VyY2UuaHRtbCIsDQogICAgICAgICAgICAgICAgICAgICAgaGVhZGVycz17Ikhvc3QiOiAid3d3LmFjbWUuY29tIn0pDQogICAgICAgIHNlbGYuYXNzZXJ0RXF1YWwocmVxdWVzdF9ob3N0KHJlcSksICJ3d3cuYWNtZS5jb20iKQ0KICAgICAgICAjIHBvcnQgc2hvdWxkbid0IGJlIGluIHJlcXVlc3QtaG9zdA0KICAgICAgICByZXEgPSBSZXF1ZXN0KCJodHRwOi8vd3d3LmFjbWUuY29tOjIzNDUvcmVzb3VyY2UuaHRtbCIsDQogICAgICAgICAgICAgICAgICAgICAgaGVhZGVycz17Ikhvc3QiOiAid3d3LmFjbWUuY29tOjU0MzIifSkNCiAgICAgICAgc2VsZi5hc3NlcnRFcXVhbChyZXF1ZXN0X2hvc3QocmVxKSwgInd3dy5hY21lLmNvbSIpDQoNCiAgICBkZWYgdGVzdF9pc19IRE4oc2VsZik6DQogICAgICAgIGZyb20gY29va2llbGliIGltcG9ydCBpc19IRE4NCiAgICAgICAgc2VsZi5hc3NlcnRUcnVlKGlzX0hETigiZm9vLmJhci5jb20iKSkNCiAgICAgICAgc2VsZi5hc3NlcnRUcnVlKGlzX0hETigiMWZvbzIuM2JhcjQuNWNvbSIpKQ0KICAgICAgICBzZWxmLmFzc2VydFRydWUobm90IGlzX0hETigiMTkyLjE2OC4xLjEiKSkNCiAgICAgICAgc2VsZi5hc3NlcnRUcnVlKG5vdCBpc19IRE4oIiIpKQ0KICAgICAgICBzZWxmLmFzc2VydFRydWUobm90IGlzX0hETigiLiIpKQ0KICAgICAgICBzZWxmLmFzc2VydFRydWUobm90IGlzX0hETigiLmZvby5iYXIuY29tIikpDQogICAgICAgIHNlbGYuYXNzZXJ0VHJ1ZShub3QgaXNfSEROKCIuLmZvbyIpKQ0KICAgICAgICBzZWxmLmFzc2VydFRydWUobm90IGlzX0hETigiZm9vLiIpKQ0KDQogICAgZGVmIHRlc3RfcmVhY2goc2VsZik6DQogICAgICAgIGZyb20gY29va2llbGliIGltcG9ydCByZWFjaA0KICAgICAgICBzZWxmLmFzc2VydEVxdWFsKHJlYWNoKCJ3d3cuYWNtZS5jb20iKSwgIi5hY21lLmNvbSIpDQogICAgICAgIHNlbGYuYXNzZXJ0RXF1YWwocmVhY2goImFjbWUuY29tIiksICJhY21lLmNvbSIpDQogICAgICAgIHNlbGYuYXNzZXJ0RXF1YWwocmVhY2goImFjbWUubG9jYWwiKSwgIi5sb2NhbCIpDQogICAgICAgIHNlbGYuYXNzZXJ0RXF1YWwocmVhY2goIi5sb2NhbCIpLCAiLmxvY2FsIikNCiAgICAgICAgc2VsZi5hc3NlcnRFcXVhbChyZWFjaCgiLmNvbSIpLCAiLmNvbSIpDQogICAgICAgIHNlbGYuYXNzZXJ0RXF1YWwocmVhY2goIi4iKSwgIi4iKQ0KICAgICAgICBzZWxmLmFzc2VydEVxdWFsKHJlYWNoKCIiKSwgIiIpDQogICAgICAgIHNlbGYuYXNzZXJ0RXF1YWwocmVhY2goIjE5Mi4xNjguMC4xIiksICIxOTIuMTY4LjAuMSIpDQoNCiAgICBkZWYgdGVzdF9kb21haW5fbWF0Y2goc2VsZik6DQogICAgICAgIGZyb20gY29va2llbGliIGltcG9ydCBkb21haW5fbWF0Y2gsIHVzZXJfZG9tYWluX21hdGNoDQogICAgICAgIHNlbGYuYXNzZXJ0VHJ1ZShkb21haW5fbWF0Y2goIjE5Mi4xNjguMS4xIiwgIjE5Mi4xNjguMS4xIikpDQogICAgICAgIHNlbGYuYXNzZXJ0VHJ1ZShub3QgZG9tYWluX21hdGNoKCIxOTIuMTY4LjEuMSIsICIuMTY4LjEuMSIpKQ0KICAgICAgICBzZWxmLmFzc2VydFRydWUoZG9tYWluX21hdGNoKCJ4LnkuY29tIiwgInguWS5jb20iKSkNCiAgICAgICAgc2VsZi5hc3NlcnRUcnVlKGRvbWFpbl9tYXRjaCgieC55LmNvbSIsICIuWS5jb20iKSkNCiAgICAgICAgc2VsZi5hc3NlcnRUcnVlKG5vdCBkb21haW5fbWF0Y2goIngueS5jb20iLCAiWS5jb20iKSkNCiAgICAgICAgc2VsZi5hc3NlcnRUcnVlKGRvbWFpbl9tYXRjaCgiYS5iLmMuY29tIiwgIi5jLmNvbSIpKQ0KICAgICAgICBzZWxmLmFzc2VydFRydWUobm90IGRvbWFpbl9tYXRjaCgiLmMuY29tIiwgImEuYi5jLmNvbSIpKQ0KICAgICAgICBzZWxmLmFzc2VydFRydWUoZG9tYWluX21hdGNoKCJleGFtcGxlLmxvY2FsIiwgIi5sb2NhbCIpKQ0KICAgICAgICBzZWxmLmFzc2VydFRydWUobm90IGRvbWFpbl9tYXRjaCgiYmxhaC5ibGFoIiwgIiIpKQ0KICAgICAgICBzZWxmLmFzc2VydFRydWUobm90IGRvbWFpbl9tYXRjaCgiIiwgIi5yaHViYXJiLnJodWJhcmIiKSkNCiAgICAgICAgc2VsZi5hc3NlcnRUcnVlKGRvbWFpbl9tYXRjaCgiIiwgIiIpKQ0KDQogICAgICAgIHNlbGYuYXNzZXJ0VHJ1ZSh1c2VyX2RvbWFpbl9tYXRjaCgiYWNtZS5jb20iLCAiYWNtZS5jb20iKSkNCiAgICAgICAgc2VsZi5hc3NlcnRUcnVlKG5vdCB1c2VyX2RvbWFpbl9tYXRjaCgiYWNtZS5jb20iLCAiLmFjbWUuY29tIikpDQogICAgICAgIHNlbGYuYXNzZXJ0VHJ1ZSh1c2VyX2RvbWFpbl9tYXRjaCgicmh1YmFyYi5hY21lLmNvbSIsICIuYWNtZS5jb20iKSkNCiAgICAgICAgc2VsZi5hc3NlcnRUcnVlKHVzZXJfZG9tYWluX21hdGNoKCJ3d3cucmh1YmFyYi5hY21lLmNvbSIsICIuYWNtZS5jb20iKSkNCiAgICAgICAgc2VsZi5hc3NlcnRUcnVlKHVzZXJfZG9tYWluX21hdGNoKCJ4LnkuY29tIiwgInguWS5jb20iKSkNCiAgICAgICAgc2VsZi5hc3NlcnRUcnVlKHVzZXJfZG9tYWluX21hdGNoKCJ4LnkuY29tIiwgIi5ZLmNvbSIpKQ0KICAgICAgICBzZWxmLmFzc2VydFRydWUobm90IHVzZXJfZG9tYWluX21hdGNoKCJ4LnkuY29tIiwgIlkuY29tIikpDQogICAgICAgIHNlbGYuYXNzZXJ0VHJ1ZSh1c2VyX2RvbWFpbl9tYXRjaCgieS5jb20iLCAiWS5jb20iKSkNCiAgICAgICAgc2VsZi5hc3NlcnRUcnVlKG5vdCB1c2VyX2RvbWFpbl9tYXRjaCgiLnkuY29tIiwgIlkuY29tIikpDQogICAgICAgIHNlbGYuYXNzZXJ0VHJ1ZSh1c2VyX2RvbWFpbl9tYXRjaCgiLnkuY29tIiwgIi5ZLmNvbSIpKQ0KICAgICAgICBzZWxmLmFzc2VydFRydWUodXNlcl9kb21haW5fbWF0Y2goIngueS5jb20iLCAiLmNvbSIpKQ0KICAgICAgICBzZWxmLmFzc2VydFRydWUobm90IHVzZXJfZG9tYWluX21hdGNoKCJ4LnkuY29tIiwgImNvbSIpKQ0KICAgICAgICBzZWxmLmFzc2VydFRydWUobm90IHVzZXJfZG9tYWluX21hdGNoKCJ4LnkuY29tIiwgIm0iKSkNCiAgICAgICAgc2VsZi5hc3NlcnRUcnVlKG5vdCB1c2VyX2RvbWFpbl9tYXRjaCgieC55LmNvbSIsICIubSIpKQ0KICAgICAgICBzZWxmLmFzc2VydFRydWUobm90IHVzZXJfZG9tYWluX21hdGNoKCJ4LnkuY29tIiwgIiIpKQ0KICAgICAgICBzZWxmLmFzc2VydFRydWUobm90IHVzZXJfZG9tYWluX21hdGNoKCJ4LnkuY29tIiwgIi4iKSkNCiAgICAgICAgc2VsZi5hc3NlcnRUcnVlKHVzZXJfZG9tYWluX21hdGNoKCIxOTIuMTY4LjEuMSIsICIxOTIuMTY4LjEuMSIpKQ0KICAgICAgICAjIG5vdCBib3RoIEhETnMsIHNvIG11c3Qgc3RyaW5nLWNvbXBhcmUgZXF1YWwgdG8gbWF0Y2gNCiAgICAgICAgc2VsZi5hc3NlcnRUcnVlKG5vdCB1c2VyX2RvbWFpbl9tYXRjaCgiMTkyLjE2OC4xLjEiLCAiLjE2OC4xLjEiKSkNCiAgICAgICAgc2VsZi5hc3NlcnRUcnVlKG5vdCB1c2VyX2RvbWFpbl9tYXRjaCgiMTkyLjE2OC4xLjEiLCAiLiIpKQ0KICAgICAgICAjIGVtcHR5IHN0cmluZyBpcyBhIHNwZWNpYWwgY2FzZQ0KICAgICAgICBzZWxmLmFzc2VydFRydWUobm90IHVzZXJfZG9tYWluX21hdGNoKCIxOTIuMTY4LjEuMSIsICIiKSkNCg0KICAgIGRlZiB0ZXN0X3dyb25nX2RvbWFpbihzZWxmKToNCiAgICAgICAgIyBDb29raWVzIHdob3NlIGVmZmVjdGl2ZSByZXF1ZXN0LWhvc3QgbmFtZSBkb2VzIG5vdCBkb21haW4tbWF0Y2ggdGhlDQogICAgICAgICMgZG9tYWluIGFyZSByZWplY3RlZC4NCg0KICAgICAgICAjIFhYWCBmYXIgZnJvbSBjb21wbGV0ZQ0KICAgICAgICBmcm9tIGNvb2tpZWxpYiBpbXBvcnQgQ29va2llSmFyDQogICAgICAgIGMgPSBDb29raWVKYXIoKQ0KICAgICAgICBpbnRlcmFjdF8yOTY1KGMsICJodHRwOi8vd3d3Lm5hc3R5LmNvbS8iLA0KICAgICAgICAgICAgICAgICAgICAgICdmb289YmFyOyBkb21haW49ZnJpZW5kbHkub3JnOyBWZXJzaW9uPSIxIicpDQogICAgICAgIHNlbGYuYXNzZXJ0RXF1YWwobGVuKGMpLCAwKQ0KDQogICAgZGVmIHRlc3Rfc3RyaWN0X2RvbWFpbihzZWxmKToNCiAgICAgICAgIyBDb29raWVzIHdob3NlIGRvbWFpbiBpcyBhIGNvdW50cnktY29kZSB0bGQgbGlrZSAuY28udWsgc2hvdWxkDQogICAgICAgICMgbm90IGJlIHNldCBpZiBDb29raWVQb2xpY3kuc3RyaWN0X2RvbWFpbiBpcyB0cnVlLg0KICAgICAgICBmcm9tIGNvb2tpZWxpYiBpbXBvcnQgQ29va2llSmFyLCBEZWZhdWx0Q29va2llUG9saWN5DQoNCiAgICAgICAgY3AgPSBEZWZhdWx0Q29va2llUG9saWN5KHN0cmljdF9kb21haW49VHJ1ZSkNCiAgICAgICAgY2ogPSBDb29raWVKYXIocG9saWN5PWNwKQ0KICAgICAgICBpbnRlcmFjdF9uZXRzY2FwZShjaiwgImh0dHA6Ly9leGFtcGxlLmNvLnVrLyIsICdubz1wcm9ibGVtbycpDQogICAgICAgIGludGVyYWN0X25ldHNjYXBlKGNqLCAiaHR0cDovL2V4YW1wbGUuY28udWsvIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgJ29rZXk9ZG9rZXk7IERvbWFpbj0uZXhhbXBsZS5jby51aycpDQogICAgICAgIHNlbGYuYXNzZXJ0RXF1YWwobGVuKGNqKSwgMikNCiAgICAgICAgZm9yIHBzZXVkb190bGQgaW4gWyIuY28udWsiLCAiLm9yZy56YSIsICIudHgudXMiLCAiLm5hbWUudXMiXToNCiAgICAgICAgICAgIGludGVyYWN0X25ldHNjYXBlKGNqLCAiaHR0cDovL2V4YW1wbGUuJXMvIiAlIHBzZXVkb190bGQsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnc3BhbT1lZ2dzOyBEb21haW49LmNvLnVrJykNCiAgICAgICAgICAgIHNlbGYuYXNzZXJ0RXF1YWwobGVuKGNqKSwgMikNCg0KICAgIGRlZiB0ZXN0X3R3b19jb21wb25lbnRfZG9tYWluX25zKHNlbGYpOg0KICAgICAgICAjIE5ldHNjYXBlOiAud3d3LmJhci5jb20sIHd3dy5iYXIuY29tLCAuYmFyLmNvbSwgYmFyLmNvbSwgbm8gZG9tYWluDQogICAgICAgICMgc2hvdWxkIGFsbCBnZXQgYWNjZXB0ZWQsIGFzIHNob3VsZCAuYWNtZS5jb20sIGFjbWUuY29tIGFuZCBubyBkb21haW4NCiAgICAgICAgIyBmb3IgMi1jb21wb25lbnQgZG9tYWlucyBsaWtlIGFjbWUuY29tLg0KICAgICAgICBmcm9tIGNvb2tpZWxpYiBpbXBvcnQgQ29va2llSmFyLCBEZWZhdWx0Q29va2llUG9saWN5DQoNCiAgICAgICAgYyA9IENvb2tpZUphcigpDQoNCiAgICAgICAgIyB0d28tY29tcG9uZW50IFYwIGRvbWFpbiBpcyBPSw0KICAgICAgICBpbnRlcmFjdF9uZXRzY2FwZShjLCAiaHR0cDovL2Zvby5uZXQvIiwgJ25zPWJhcicpDQogICAgICAgIHNlbGYuYXNzZXJ0RXF1YWwobGVuKGMpLCAxKQ0KICAgICAgICBzZWxmLmFzc2VydEVxdWFsKGMuX2Nvb2tpZXNbImZvby5uZXQiXVsiLyJdWyJucyJdLnZhbHVlLCAiYmFyIikNCiAgICAgICAgc2VsZi5hc3NlcnRFcXVhbChpbnRlcmFjdF9uZXRzY2FwZShjLCAiaHR0cDovL2Zvby5uZXQvIiksICJucz1iYXIiKQ0KICAgICAgICAjICp3aWxsKiBiZSByZXR1cm5lZCB0byBhbnkgb3RoZXIgZG9tYWluICh1bmxpa2UgUkZDIDI5NjUpLi4uDQogICAgICAgIHNlbGYuYXNzZXJ0RXF1YWwoaW50ZXJhY3RfbmV0c2NhcGUoYywgImh0dHA6Ly93d3cuZm9vLm5ldC8iKSwNCiAgICAgICAgICAgICAgICAgICAgICAgICAibnM9YmFyIikNCiAgICAgICAgIyAuLi51bmxlc3MgcmVxdWVzdGVkIG90aGVyd2lzZQ0KICAgICAgICBwb2wgPSBEZWZhdWx0Q29va2llUG9saWN5KA0KICAgICAgICAgICAgc3RyaWN0X25zX2RvbWFpbj1EZWZhdWx0Q29va2llUG9saWN5LkRvbWFpblN0cmljdE5vbkRvbWFpbikNCiAgICAgICAgYy5zZXRfcG9saWN5KHBvbCkNCiAgICAgICAgc2VsZi5hc3NlcnRFcXVhbChpbnRlcmFjdF9uZXRzY2FwZShjLCAiaHR0cDovL3d3dy5mb28ubmV0LyIpLCAiIikNCg0KICAgICAgICAjIHVubGlrZSBSRkMgMjk2NSwgZXZlbiBleHBsaWNpdCB0d28tY29tcG9uZW50IGRvbWFpbiBpcyBPSywNCiAgICAgICAgIyBiZWNhdXNlIC5mb28ubmV0IG1hdGNoZXMgZm9vLm5ldA0KICAgICAgICBpbnRlcmFjdF9uZXRzY2FwZShjLCAiaHR0cDovL2Zvby5uZXQvZm9vLyIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICdzcGFtMT1lZ2dzOyBkb21haW49Zm9vLm5ldCcpDQogICAgICAgICMgZXZlbiBpZiBzdGFydHMgd2l0aCBhIGRvdCAtLSBpbiBOUyBydWxlcywgLmZvby5uZXQgbWF0Y2hlcyBmb28ubmV0IQ0KICAgICAgICBpbnRlcmFjdF9uZXRzY2FwZShjLCAiaHR0cDovL2Zvby5uZXQvZm9vL2Jhci8iLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAnc3BhbTI9ZWdnczsgZG9tYWluPS5mb28ubmV0JykNCiAgICAgICAgc2VsZi5hc3NlcnRFcXVhbChsZW4oYyksIDMpDQogICAgICAgIHNlbGYuYXNzZXJ0RXF1YWwoYy5fY29va2llc1siLmZvby5uZXQiXVsiL2ZvbyJdWyJzcGFtMSJdLnZhbHVlLA0KICAgICAgICAgICAgICAgICAgICAgICAgICJlZ2dzIikNCiAgICAgICAgc2VsZi5hc3NlcnRFcXVhbChjLl9jb29raWVzWyIuZm9vLm5ldCJdWyIvZm9vL2JhciJdWyJzcGFtMiJdLnZhbHVlLA0KICAgICAgICAgICAgICAgICAgICAgICAgICJlZ2dzIikNCiAgICAgICAgc2VsZi5hc3NlcnRFcXVhbChpbnRlcmFjdF9uZXRzY2FwZShjLCAiaHR0cDovL2Zvby5uZXQvZm9vL2Jhci8iKSwNCiAgICAgICAgICAgICAgICAgICAgICAgICAic3BhbTI9ZWdnczsgc3BhbTE9ZWdnczsgbnM9YmFyIikNCg0KICAgICAgICAjIHRvcC1sZXZlbCBkb21haW4gaXMgdG9vIGdlbmVyYWwNCiAgICAgICAgaW50ZXJhY3RfbmV0c2NhcGUoYywgImh0dHA6Ly9mb28ubmV0LyIsICduaW5pPSJuaSI7IGRvbWFpbj0ubmV0JykNCiAgICAgICAgc2VsZi5hc3NlcnRFcXVhbChsZW4oYyksIDMpDQoNCiMjICAgICAgICAgIyBOZXRzY2FwZSBwcm90b2NvbCBkb2Vzbid0IGFsbG93IG5vbi1zcGVjaWFsIHRvcCBsZXZlbCBkb21haW5zIChzdWNoDQojIyAgICAgICAgICMgYXMgY28udWspIGluIHRoZSBkb21haW4gYXR0cmlidXRlIHVubGVzcyB0aGVyZSBhcmUgYXQgbGVhc3QgdGhyZWUNCiMjICAgICAgICAgIyBkb3RzIGluIGl0Lg0KICAgICAgICAjIE9oIHllcyBpdCBkb2VzISAgUmVhbCBpbXBsZW1lbnRhdGlvbnMgZG9uJ3QgY2hlY2sgdGhpcywgYW5kIHJlYWwNCiAgICAgICAgIyBjb29raWVzIChvZiBjb3Vyc2UpIHJlbHkgb24gdGhhdCBiZWhhdmlvdXIuDQogICAgICAgIGludGVyYWN0X25ldHNjYXBlKGMsICJodHRwOi8vZm9vLmNvLnVrIiwgJ25hc3R5PXRyaWNrOyBkb21haW49LmNvLnVrJykNCiMjICAgICAgICAgc2VsZi5hc3NlcnRFcXVhbChsZW4oYyksIDIpDQogICAgICAgIHNlbGYuYXNzZXJ0RXF1YWwobGVuKGMpLCA0KQ0KDQogICAgZGVmIHRlc3RfdHdvX2NvbXBvbmVudF9kb21haW5fcmZjMjk2NShzZWxmKToNCiAgICAgICAgZnJvbSBjb29raWVsaWIgaW1wb3J0IENvb2tpZUphciwgRGVmYXVsdENvb2tpZVBvbGljeQ0KDQogICAgICAgIHBvbCA9IERlZmF1bHRDb29raWVQb2xpY3kocmZjMjk2NT1UcnVlKQ0KICAgICAgICBjID0gQ29va2llSmFyKHBvbCkNCg0KICAgICAgICAjIHR3by1jb21wb25lbnQgVjEgZG9tYWluIGlzIE9LDQogICAgICAgIGludGVyYWN0XzI5NjUoYywgImh0dHA6Ly9mb28ubmV0LyIsICdmb289YmFyOyBWZXJzaW9uPSIxIicpDQogICAgICAgIHNlbGYuYXNzZXJ0RXF1YWwobGVuKGMpLCAxKQ0KICAgICAgICBzZWxmLmFzc2VydEVxdWFsKGMuX2Nvb2tpZXNbImZvby5uZXQiXVsiLyJdWyJmb28iXS52YWx1ZSwgImJhciIpDQogICAgICAgIHNlbGYuYXNzZXJ0RXF1YWwoaW50ZXJhY3RfMjk2NShjLCAiaHR0cDovL2Zvby5uZXQvIiksDQogICAgICAgICAgICAgICAgICAgICAgICAgIiRWZXJzaW9uPTE7IGZvbz1iYXIiKQ0KICAgICAgICAjIHdvbid0IGJlIHJldHVybmVkIHRvIGFueSBvdGhlciBkb21haW4gKGJlY2F1c2UgZG9tYWluIHdhcyBpbXBsaWVkKQ0KICAgICAgICBzZWxmLmFzc2VydEVxdWFsKGludGVyYWN0XzI5NjUoYywgImh0dHA6Ly93d3cuZm9vLm5ldC8iKSwgIiIpDQoNCiAgICAgICAgIyB1bmxlc3MgZG9tYWluIGlzIGdpdmVuIGV4cGxpY2l0bHksIGJlY2F1c2UgdGhlbiBpdCBtdXN0IGJlDQogICAgICAgICMgcmV3cml0dGVuIHRvIHN0YXJ0IHdpdGggYSBkb3Q6IGZvby5uZXQgLS0+IC5mb28ubmV0LCB3aGljaCBkb2VzDQogICAgICAgICMgbm90IGRvbWFpbi1tYXRjaCBmb28ubmV0DQogICAgICAgIGludGVyYWN0XzI5NjUoYywgImh0dHA6Ly9mb28ubmV0L2ZvbyIsDQogICAgICAgICAgICAgICAgICAgICAgJ3NwYW09ZWdnczsgZG9tYWluPWZvby5uZXQ7IHBhdGg9L2ZvbzsgVmVyc2lvbj0iMSInKQ0KICAgICAgICBzZWxmLmFzc2VydEVxdWFsKGxlbihjKSwgMSkNCiAgICAgICAgc2VsZi5hc3NlcnRFcXVhbChpbnRlcmFjdF8yOTY1KGMsICJodHRwOi8vZm9vLm5ldC9mb28iKSwNCiAgICAgICAgICAgICAgICAgICAgICAgICAiJFZlcnNpb249MTsgZm9vPWJhciIpDQoNCiAgICAgICAgIyBleHBsaWNpdCBmb28ubmV0IGZyb20gdGhyZWUtY29tcG9uZW50IGRvbWFpbiB3d3cuZm9vLm5ldCAqZG9lcyogZ2V0DQogICAgICAgICMgc2V0LCBiZWNhdXNlIC5mb28ubmV0IGRvbWFpbi1tYXRjaGVzIC5mb28ubmV0DQogICAgICAgIGludGVyYWN0XzI5NjUoYywgImh0dHA6Ly93d3cuZm9vLm5ldC9mb28vIiwNCiAgICAgICAgICAgICAgICAgICAgICAnc3BhbT1lZ2dzOyBkb21haW49Zm9vLm5ldDsgVmVyc2lvbj0iMSInKQ0KICAgICAgICBzZWxmLmFzc2VydEVxdWFsKGMuX2Nvb2tpZXNbIi5mb28ubmV0Il1bIi9mb28vIl1bInNwYW0iXS52YWx1ZSwNCiAgICAgICAgICAgICAgICAgICAgICAgICAiZWdncyIpDQogICAgICAgIHNlbGYuYXNzZXJ0RXF1YWwobGVuKGMpLCAyKQ0KICAgICAgICBzZWxmLmFzc2VydEVxdWFsKGludGVyYWN0XzI5NjUoYywgImh0dHA6Ly9mb28ubmV0L2Zvby8iKSwNCiAgICAgICAgICAgICAgICAgICAgICAgICAiJFZlcnNpb249MTsgZm9vPWJhciIpDQogICAgICAgIHNlbGYuYXNzZXJ0RXF1YWwoaW50ZXJhY3RfMjk2NShjLCAiaHR0cDovL3d3dy5mb28ubmV0L2Zvby8iKSwNCiAgICAgICAgICAgICAgICAgICAgICAgICAnJFZlcnNpb249MTsgc3BhbT1lZ2dzOyAkRG9tYWluPSJmb28ubmV0IicpDQoNCiAgICAgICAgIyB0b3AtbGV2ZWwgZG9tYWluIGlzIHRvbyBnZW5lcmFsDQogICAgICAgIGludGVyYWN0XzI5NjUoYywgImh0dHA6Ly9mb28ubmV0LyIsDQogICAgICAgICAgICAgICAgICAgICAgJ25pPSJuaSI7IGRvbWFpbj0iLm5ldCI7IFZlcnNpb249IjEiJykNCiAgICAgICAgc2VsZi5hc3NlcnRFcXVhbChsZW4oYyksIDIpDQoNCiAgICAgICAgIyBSRkMgMjk2NSBkb2Vzbid0IHJlcXVpcmUgYmxvY2tpbmcgdGhpcw0KICAgICAgICBpbnRlcmFjdF8yOTY1KGMsICJodHRwOi8vZm9vLmNvLnVrLyIsDQogICAgICAgICAgICAgICAgICAgICAgJ25hc3R5PXRyaWNrOyBkb21haW49LmNvLnVrOyBWZXJzaW9uPSIxIicpDQogICAgICAgIHNlbGYuYXNzZXJ0RXF1YWwobGVuKGMpLCAzKQ0KDQogICAgZGVmIHRlc3RfZG9tYWluX2FsbG93KHNlbGYpOg0KICAgICAgICBmcm9tIGNvb2tpZWxpYiBpbXBvcnQgQ29va2llSmFyLCBEZWZhdWx0Q29va2llUG9saWN5DQogICAgICAgIGZyb20gdXJsbGliMiBpbXBvcnQgUmVxdWVzdA0KDQogICAgICAgIGMgPSBDb29raWVKYXIocG9saWN5PURlZmF1bHRDb29raWVQb2xpY3koDQogICAgICAgICAgICBibG9ja2VkX2RvbWFpbnM9WyJhY21lLmNvbSJdLA0KICAgICAgICAgICAgYWxsb3dlZF9kb21haW5zPVsid3d3LmFjbWUuY29tIl0pKQ0KDQogICAgICAgIHJlcSA9IFJlcXVlc3QoImh0dHA6Ly9hY21lLmNvbS8iKQ0KICAgICAgICBoZWFkZXJzID0gWyJTZXQtQ29va2llOiBDVVNUT01FUj1XSUxFX0VfQ09ZT1RFOyBwYXRoPS8iXQ0KICAgICAgICByZXMgPSBGYWtlUmVzcG9uc2UoaGVhZGVycywgImh0dHA6Ly9hY21lLmNvbS8iKQ0KICAgICAgICBjLmV4dHJhY3RfY29va2llcyhyZXMsIHJlcSkNCiAgICAgICAgc2VsZi5hc3NlcnRFcXVhbChsZW4oYyksIDApDQoNCiAgICAgICAgcmVxID0gUmVxdWVzdCgiaHR0cDovL3d3dy5hY21lLmNvbS8iKQ0KICAgICAgICByZXMgPSBGYWtlUmVzcG9uc2UoaGVhZGVycywgImh0dHA6Ly93d3cuYWNtZS5jb20vIikNCiAgICAgICAgYy5leHRyYWN0X2Nvb2tpZXMocmVzLCByZXEpDQogICAgICAgIHNlbGYuYXNzZXJ0RXF1YWwobGVuKGMpLCAxKQ0KDQogICAgICAgIHJlcSA9IFJlcXVlc3QoImh0dHA6Ly93d3cuY295b3RlLmNvbS8iKQ0KICAgICAgICByZXMgPSBGYWtlUmVzcG9uc2UoaGVhZGVycywgImh0dHA6Ly93d3cuY295b3RlLmNvbS8iKQ0KICAgICAgICBjLmV4dHJhY3RfY29va2llcyhyZXMsIHJlcSkNCiAgICAgICAgc2VsZi5hc3NlcnRFcXVhbChsZW4oYyksIDEpDQoNCiAgICAgICAgIyBzZXQgYSBjb29raWUgd2l0aCBub24tYWxsb3dlZCBkb21haW4uLi4NCiAgICAgICAgcmVxID0gUmVxdWVzdCgiaHR0cDovL3d3dy5jb3lvdGUuY29tLyIpDQogICAgICAgIHJlcyA9IEZha2VSZXNwb25zZShoZWFkZXJzLCAiaHR0cDovL3d3dy5jb3lvdGUuY29tLyIpDQogICAgICAgIGNvb2tpZXMgPSBjLm1ha2VfY29va2llcyhyZXMsIHJlcSkNCiAgICAgICAgYy5zZXRfY29va2llKGNvb2tpZXNbMF0pDQogICAgICAgIHNlbGYuYXNzZXJ0RXF1YWwobGVuKGMpLCAyKQ0KICAgICAgICAjIC4uLiBhbmQgY2hlY2sgaXMgZG9lc24ndCBnZXQgcmV0dXJuZWQNCiAgICAgICAgYy5hZGRfY29va2llX2hlYWRlcihyZXEpDQogICAgICAgIHNlbGYuYXNzZXJ0VHJ1ZShub3QgcmVxLmhhc19oZWFkZXIoIkNvb2tpZSIpKQ0KDQogICAgZGVmIHRlc3RfZG9tYWluX2Jsb2NrKHNlbGYpOg0KICAgICAgICBmcm9tIGNvb2tpZWxpYiBpbXBvcnQgQ29va2llSmFyLCBEZWZhdWx0Q29va2llUG9saWN5DQogICAgICAgIGZyb20gdXJsbGliMiBpbXBvcnQgUmVxdWVzdA0KDQogICAgICAgIHBvbCA9IERlZmF1bHRDb29raWVQb2xpY3koDQogICAgICAgICAgICByZmMyOTY1PVRydWUsIGJsb2NrZWRfZG9tYWlucz1bIi5hY21lLmNvbSJdKQ0KICAgICAgICBjID0gQ29va2llSmFyKHBvbGljeT1wb2wpDQogICAgICAgIGhlYWRlcnMgPSBbIlNldC1Db29raWU6IENVU1RPTUVSPVdJTEVfRV9DT1lPVEU7IHBhdGg9LyJdDQoNCiAgICAgICAgcmVxID0gUmVxdWVzdCgiaHR0cDovL3d3dy5hY21lLmNvbS8iKQ0KICAgICAgICByZXMgPSBGYWtlUmVzcG9uc2UoaGVhZGVycywgImh0dHA6Ly93d3cuYWNtZS5jb20vIikNCiAgICAgICAgYy5leHRyYWN0X2Nvb2tpZXMocmVzLCByZXEpDQogICAgICAgIHNlbGYuYXNzZXJ0RXF1YWwobGVuKGMpLCAwKQ0KDQogICAgICAgIHAgPSBwb2wuc2V0X2Jsb2NrZWRfZG9tYWlucyhbImFjbWUuY29tIl0pDQogICAgICAgIGMuZXh0cmFjdF9jb29raWVzKHJlcywgcmVxKQ0KICAgICAgICBzZWxmLmFzc2VydEVxdWFsKGxlbihjKSwgMSkNCg0KICAgICAgICBjLmNsZWFyKCkNCiAgICAgICAgcmVxID0gUmVxdWVzdCgiaHR0cDovL3d3dy5yb2FkcnVubmVyLm5ldC8iKQ0KICAgICAgICByZXMgPSBGYWtlUmVzcG9uc2UoaGVhZGVycywgImh0dHA6Ly93d3cucm9hZHJ1bm5lci5uZXQvIikNCiAgICAgICAgYy5leHRyYWN0X2Nvb2tpZXMocmVzLCByZXEpDQogICAgICAgIHNlbGYuYXNzZXJ0RXF1YWwobGVuKGMpLCAxKQ0KICAgICAgICByZXEgPSBSZXF1ZXN0KCJodHRwOi8vd3d3LnJvYWRydW5uZXIubmV0LyIpDQogICAgICAgIGMuYWRkX2Nvb2tpZV9oZWFkZXIocmVxKQ0KICAgICAgICBzZWxmLmFzc2VydFRydWUoKHJlcS5oYXNfaGVhZGVyKCJDb29raWUiKSBhbmQNCiAgICAgICAgICAgICAgICAgICAgICByZXEuaGFzX2hlYWRlcigiQ29va2llMiIpKSkNCg0KICAgICAgICBjLmNsZWFyKCkNCiAgICAgICAgcG9sLnNldF9ibG9ja2VkX2RvbWFpbnMoWyIuYWNtZS5jb20iXSkNCiAgICAgICAgYy5leHRyYWN0X2Nvb2tpZXMocmVzLCByZXEpDQogICAgICAgIHNlbGYuYXNzZXJ0RXF1YWwobGVuKGMpLCAxKQ0KDQogICAgICAgICMgc2V0IGEgY29va2llIHdpdGggYmxvY2tlZCBkb21haW4uLi4NCiAgICAgICAgcmVxID0gUmVxdWVzdCgiaHR0cDovL3d3dy5hY21lLmNvbS8iKQ0KICAgICAgICByZXMgPSBGYWtlUmVzcG9uc2UoaGVhZGVycywgImh0dHA6Ly93d3cuYWNtZS5jb20vIikNCiAgICAgICAgY29va2llcyA9IGMubWFrZV9jb29raWVzKHJlcywgcmVxKQ0KICAgICAgICBjLnNldF9jb29raWUoY29va2llc1swXSkNCiAgICAgICAgc2VsZi5hc3NlcnRFcXVhbChsZW4oYyksIDIpDQogICAgICAgICMgLi4uIGFuZCBjaGVjayBpcyBkb2Vzbid0IGdldCByZXR1cm5lZA0KICAgICAgICBjLmFkZF9jb29raWVfaGVhZGVyKHJlcSkNCiAgICAgICAgc2VsZi5hc3NlcnRUcnVlKG5vdCByZXEuaGFzX2hlYWRlcigiQ29va2llIikpDQoNCiAgICBkZWYgdGVzdF9zZWN1cmUoc2VsZik6DQogICAgICAgIGZyb20gY29va2llbGliIGltcG9ydCBDb29raWVKYXIsIERlZmF1bHRDb29raWVQb2xpY3kNCg0KICAgICAgICBmb3IgbnMgaW4gVHJ1ZSwgRmFsc2U6DQogICAgICAgICAgICBmb3Igd2hpdGVzcGFjZSBpbiAiICIsICIiOg0KICAgICAgICAgICAgICAgIGMgPSBDb29raWVKYXIoKQ0KICAgICAgICAgICAgICAgIGlmIG5zOg0KICAgICAgICAgICAgICAgICAgICBwb2wgPSBEZWZhdWx0Q29va2llUG9saWN5KHJmYzI5NjU9RmFsc2UpDQogICAgICAgICAgICAgICAgICAgIGludCA9IGludGVyYWN0X25ldHNjYXBlDQogICAgICAgICAgICAgICAgICAgIHZzID0gIiINCiAgICAgICAgICAgICAgICBlbHNlOg0KICAgICAgICAgICAgICAgICAgICBwb2wgPSBEZWZhdWx0Q29va2llUG9saWN5KHJmYzI5NjU9VHJ1ZSkNCiAgICAgICAgICAgICAgICAgICAgaW50ID0gaW50ZXJhY3RfMjk2NQ0KICAgICAgICAgICAgICAgICAgICB2cyA9ICI7IFZlcnNpb249MSINCiAgICAgICAgICAgICAgICBjLnNldF9wb2xpY3kocG9sKQ0KICAgICAgICAgICAgICAgIHVybCA9ICJodHRwOi8vd3d3LmFjbWUuY29tLyINCiAgICAgICAgICAgICAgICBpbnQoYywgdXJsLCAiZm9vMT1iYXIlcyVzIiAlICh2cywgd2hpdGVzcGFjZSkpDQogICAgICAgICAgICAgICAgaW50KGMsIHVybCwgImZvbzI9YmFyJXM7IHNlY3VyZSVzIiAlICAodnMsIHdoaXRlc3BhY2UpKQ0KICAgICAgICAgICAgICAgIHNlbGYuYXNzZXJ0VHJ1ZSgNCiAgICAgICAgICAgICAgICAgICAgbm90IGMuX2Nvb2tpZXNbInd3dy5hY21lLmNvbSJdWyIvIl1bImZvbzEiXS5zZWN1cmUsDQogICAgICAgICAgICAgICAgICAgICJub24tc2VjdXJlIGNvb2tpZSByZWdpc3RlcmVkIHNlY3VyZSIpDQogICAgICAgICAgICAgICAgc2VsZi5hc3NlcnRUcnVlKA0KICAgICAgICAgICAgICAgICAgICBjLl9jb29raWVzWyJ3d3cuYWNtZS5jb20iXVsiLyJdWyJmb28yIl0uc2VjdXJlLA0KICAgICAgICAgICAgICAgICAgICAic2VjdXJlIGNvb2tpZSByZWdpc3RlcmVkIG5vbi1zZWN1cmUiKQ0KDQogICAgZGVmIHRlc3RfcXVvdGVfY29va2llX3ZhbHVlKHNlbGYpOg0KICAgICAgICBmcm9tIGNvb2tpZWxpYiBpbXBvcnQgQ29va2llSmFyLCBEZWZhdWx0Q29va2llUG9saWN5DQogICAgICAgIGMgPSBDb29raWVKYXIocG9saWN5PURlZmF1bHRDb29raWVQb2xpY3kocmZjMjk2NT1UcnVlKSkNCiAgICAgICAgaW50ZXJhY3RfMjk2NShjLCAiaHR0cDovL3d3dy5hY21lLmNvbS8iLCByJ2Zvbz1cYiJhInI7IFZlcnNpb249MScpDQogICAgICAgIGggPSBpbnRlcmFjdF8yOTY1KGMsICJodHRwOi8vd3d3LmFjbWUuY29tLyIpDQogICAgICAgIHNlbGYuYXNzZXJ0RXF1YWwoaCwgcickVmVyc2lvbj0xOyBmb289XFxiXCJhXCJyJykNCg0KICAgIGRlZiB0ZXN0X21pc3NpbmdfZmluYWxfc2xhc2goc2VsZik6DQogICAgICAgICMgTWlzc2luZyBzbGFzaCBmcm9tIHJlcXVlc3QgVVJMJ3MgYWJzX3BhdGggc2hvdWxkIGJlIGFzc3VtZWQgcHJlc2VudC4NCiAgICAgICAgZnJvbSBjb29raWVsaWIgaW1wb3J0IENvb2tpZUphciwgRGVmYXVsdENvb2tpZVBvbGljeQ0KICAgICAgICBmcm9tIHVybGxpYjIgaW1wb3J0IFJlcXVlc3QNCiAgICAgICAgdXJsID0gImh0dHA6Ly93d3cuYWNtZS5jb20iDQogICAgICAgIGMgPSBDb29raWVKYXIoRGVmYXVsdENvb2tpZVBvbGljeShyZmMyOTY1PVRydWUpKQ0KICAgICAgICBpbnRlcmFjdF8yOTY1KGMsIHVybCwgImZvbz1iYXI7IFZlcnNpb249MSIpDQogICAgICAgIHJlcSA9IFJlcXVlc3QodXJsKQ0KICAgICAgICBzZWxmLmFzc2VydEVxdWFsKGxlbihjKSwgMSkNCiAgICAgICAgYy5hZGRfY29va2llX2hlYWRlcihyZXEpDQogICAgICAgIHNlbGYuYXNzZXJ0VHJ1ZShyZXEuaGFzX2hlYWRlcigiQ29va2llIikpDQoNCiAgICBkZWYgdGVzdF9kb21haW5fbWlycm9yKHNlbGYpOg0KICAgICAgICBmcm9tIGNvb2tpZWxpYiBpbXBvcnQgQ29va2llSmFyLCBEZWZhdWx0Q29va2llUG9saWN5DQoNCiAgICAgICAgcG9sID0gRGVmYXVsdENvb2tpZVBvbGljeShyZmMyOTY1PVRydWUpDQoNCiAgICAgICAgYyA9IENvb2tpZUphcihwb2wpDQogICAgICAgIHVybCA9ICJodHRwOi8vZm9vLmJhci5jb20vIg0KICAgICAgICBpbnRlcmFjdF8yOTY1KGMsIHVybCwgInNwYW09ZWdnczsgVmVyc2lvbj0xIikNCiAgICAgICAgaCA9IGludGVyYWN0XzI5NjUoYywgdXJsKQ0KICAgICAgICBzZWxmLmFzc2VydE5vdEluKCJEb21haW4iLCBoLA0KICAgICAgICAgICAgICAgICAgICAgICAgICJhYnNlbnQgZG9tYWluIHJldHVybmVkIHdpdGggZG9tYWluIHByZXNlbnQiKQ0KDQogICAgICAgIGMgPSBDb29raWVKYXIocG9sKQ0KICAgICAgICB1cmwgPSAiaHR0cDovL2Zvby5iYXIuY29tLyINCiAgICAgICAgaW50ZXJhY3RfMjk2NShjLCB1cmwsICdzcGFtPWVnZ3M7IFZlcnNpb249MTsgRG9tYWluPS5iYXIuY29tJykNCiAgICAgICAgaCA9IGludGVyYWN0XzI5NjUoYywgdXJsKQ0KICAgICAgICBzZWxmLmFzc2VydEluKCckRG9tYWluPSIuYmFyLmNvbSInLCBoLCAiZG9tYWluIG5vdCByZXR1cm5lZCIpDQoNCiAgICAgICAgYyA9IENvb2tpZUphcihwb2wpDQogICAgICAgIHVybCA9ICJodHRwOi8vZm9vLmJhci5jb20vIg0KICAgICAgICAjIG5vdGUgbWlzc2luZyBpbml0aWFsIGRvdCBpbiBEb21haW4NCiAgICAgICAgaW50ZXJhY3RfMjk2NShjLCB1cmwsICdzcGFtPWVnZ3M7IFZlcnNpb249MTsgRG9tYWluPWJhci5jb20nKQ0KICAgICAgICBoID0gaW50ZXJhY3RfMjk2NShjLCB1cmwpDQogICAgICAgIHNlbGYuYXNzZXJ0SW4oJyREb21haW49ImJhci5jb20iJywgaCwgImRvbWFpbiBub3QgcmV0dXJuZWQiKQ0KDQogICAgZGVmIHRlc3RfcGF0aF9taXJyb3Ioc2VsZik6DQogICAgICAgIGZyb20gY29va2llbGliIGltcG9ydCBDb29raWVKYXIsIERlZmF1bHRDb29raWVQb2xpY3kNCg0KICAgICAgICBwb2wgPSBEZWZhdWx0Q29va2llUG9saWN5KHJmYzI5NjU9VHJ1ZSkNCg0KICAgICAgICBjID0gQ29va2llSmFyKHBvbCkNCiAgICAgICAgdXJsID0gImh0dHA6Ly9mb28uYmFyLmNvbS8iDQogICAgICAgIGludGVyYWN0XzI5NjUoYywgdXJsLCAic3BhbT1lZ2dzOyBWZXJzaW9uPTEiKQ0KICAgICAgICBoID0gaW50ZXJhY3RfMjk2NShjLCB1cmwpDQogICAgICAgIHNlbGYuYXNzZXJ0Tm90SW4oIlBhdGgiLCBoLCAiYWJzZW50IHBhdGggcmV0dXJuZWQgd2l0aCBwYXRoIHByZXNlbnQiKQ0KDQogICAgICAgIGMgPSBDb29raWVKYXIocG9sKQ0KICAgICAgICB1cmwgPSAiaHR0cDovL2Zvby5iYXIuY29tLyINCiAgICAgICAgaW50ZXJhY3RfMjk2NShjLCB1cmwsICdzcGFtPWVnZ3M7IFZlcnNpb249MTsgUGF0aD0vJykNCiAgICAgICAgaCA9IGludGVyYWN0XzI5NjUoYywgdXJsKQ0KICAgICAgICBzZWxmLmFzc2VydEluKCckUGF0aD0iLyInLCBoLCAicGF0aCBub3QgcmV0dXJuZWQiKQ0KDQogICAgZGVmIHRlc3RfcG9ydF9taXJyb3Ioc2VsZik6DQogICAgICAgIGZyb20gY29va2llbGliIGltcG9ydCBDb29raWVKYXIsIERlZmF1bHRDb29raWVQb2xpY3kNCg0KICAgICAgICBwb2wgPSBEZWZhdWx0Q29va2llUG9saWN5KHJmYzI5NjU9VHJ1ZSkNCg0KICAgICAgICBjID0gQ29va2llSmFyKHBvbCkNCiAgICAgICAgdXJsID0gImh0dHA6Ly9mb28uYmFyLmNvbS8iDQogICAgICAgIGludGVyYWN0XzI5NjUoYywgdXJsLCAic3BhbT1lZ2dzOyBWZXJzaW9uPTEiKQ0KICAgICAgICBoID0gaW50ZXJhY3RfMjk2NShjLCB1cmwpDQogICAgICAgIHNlbGYuYXNzZXJ0Tm90SW4oIlBvcnQiLCBoLCAiYWJzZW50IHBvcnQgcmV0dXJuZWQgd2l0aCBwb3J0IHByZXNlbnQiKQ0KDQogICAgICAgIGMgPSBDb29raWVKYXIocG9sKQ0KICAgICAgICB1cmwgPSAiaHR0cDovL2Zvby5iYXIuY29tLyINCiAgICAgICAgaW50ZXJhY3RfMjk2NShjLCB1cmwsICJzcGFtPWVnZ3M7IFZlcnNpb249MTsgUG9ydCIpDQogICAgICAgIGggPSBpbnRlcmFjdF8yOTY1KGMsIHVybCkNCiAgICAgICAgc2VsZi5hc3NlcnRUcnVlKHJlLnNlYXJjaCgiXCRQb3J0KFtePV18JCkiLCBoKSwNCiAgICAgICAgICAgICAgICAgICAgICJwb3J0IHdpdGggbm8gdmFsdWUgbm90IHJldHVybmVkIHdpdGggbm8gdmFsdWUiKQ0KDQogICAgICAgIGMgPSBDb29raWVKYXIocG9sKQ0KICAgICAgICB1cmwgPSAiaHR0cDovL2Zvby5iYXIuY29tLyINCiAgICAgICAgaW50ZXJhY3RfMjk2NShjLCB1cmwsICdzcGFtPWVnZ3M7IFZlcnNpb249MTsgUG9ydD0iODAiJykNCiAgICAgICAgaCA9IGludGVyYWN0XzI5NjUoYywgdXJsKQ0KICAgICAgICBzZWxmLmFzc2VydEluKCckUG9ydD0iODAiJywgaCwNCiAgICAgICAgICAgICAgICAgICAgICAicG9ydCB3aXRoIHNpbmdsZSB2YWx1ZSBub3QgcmV0dXJuZWQgd2l0aCBzaW5nbGUgdmFsdWUiKQ0KDQogICAgICAgIGMgPSBDb29raWVKYXIocG9sKQ0KICAgICAgICB1cmwgPSAiaHR0cDovL2Zvby5iYXIuY29tLyINCiAgICAgICAgaW50ZXJhY3RfMjk2NShjLCB1cmwsICdzcGFtPWVnZ3M7IFZlcnNpb249MTsgUG9ydD0iODAsODA4MCInKQ0KICAgICAgICBoID0gaW50ZXJhY3RfMjk2NShjLCB1cmwpDQogICAgICAgIHNlbGYuYXNzZXJ0SW4oJyRQb3J0PSI4MCw4MDgwIicsIGgsDQogICAgICAgICAgICAgICAgICAgICAgInBvcnQgd2l0aCBtdWx0aXBsZSB2YWx1ZXMgbm90IHJldHVybmVkIHdpdGggbXVsdGlwbGUgIg0KICAgICAgICAgICAgICAgICAgICAgICJ2YWx1ZXMiKQ0KDQogICAgZGVmIHRlc3Rfbm9fcmV0dXJuX2NvbW1lbnQoc2VsZik6DQogICAgICAgIGZyb20gY29va2llbGliIGltcG9ydCBDb29raWVKYXIsIERlZmF1bHRDb29raWVQb2xpY3kNCg0KICAgICAgICBjID0gQ29va2llSmFyKERlZmF1bHRDb29raWVQb2xpY3kocmZjMjk2NT1UcnVlKSkNCiAgICAgICAgdXJsID0gImh0dHA6Ly9mb28uYmFyLmNvbS8iDQogICAgICAgIGludGVyYWN0XzI5NjUoYywgdXJsLCAnc3BhbT1lZ2dzOyBWZXJzaW9uPTE7ICcNCiAgICAgICAgICAgICAgICAgICAgICAnQ29tbWVudD0iZG9lcyBhbnlib2R5IHJlYWQgdGhlc2U/IjsgJw0KICAgICAgICAgICAgICAgICAgICAgICdDb21tZW50VVJMPSJodHRwOi8vZm9vLmJhci5uZXQvY29tbWVudC5odG1sIicpDQogICAgICAgIGggPSBpbnRlcmFjdF8yOTY1KGMsIHVybCkNCiAgICAgICAgc2VsZi5hc3NlcnRUcnVlKA0KICAgICAgICAgICAgIkNvbW1lbnQiIG5vdCBpbiBoLA0KICAgICAgICAgICAgIkNvbW1lbnQgb3IgQ29tbWVudFVSTCBjb29raWUtYXR0cmlidXRlcyByZXR1cm5lZCB0byBzZXJ2ZXIiKQ0KDQogICAgZGVmIHRlc3RfQ29va2llX2l0ZXJhdG9yKHNlbGYpOg0KICAgICAgICBmcm9tIGNvb2tpZWxpYiBpbXBvcnQgQ29va2llSmFyLCBDb29raWUsIERlZmF1bHRDb29raWVQb2xpY3kNCg0KICAgICAgICBjcyA9IENvb2tpZUphcihEZWZhdWx0Q29va2llUG9saWN5KHJmYzI5NjU9VHJ1ZSkpDQogICAgICAgICMgYWRkIHNvbWUgcmFuZG9tIGNvb2tpZXMNCiAgICAgICAgaW50ZXJhY3RfMjk2NShjcywgImh0dHA6Ly9ibGFoLnNwYW0ub3JnLyIsICdmb289ZWdnczsgVmVyc2lvbj0xOyAnDQogICAgICAgICAgICAgICAgICAgICAgJ0NvbW1lbnQ9ImRvZXMgYW55Ym9keSByZWFkIHRoZXNlPyI7ICcNCiAgICAgICAgICAgICAgICAgICAgICAnQ29tbWVudFVSTD0iaHR0cDovL2Zvby5iYXIubmV0L2NvbW1lbnQuaHRtbCInKQ0KICAgICAgICBpbnRlcmFjdF9uZXRzY2FwZShjcywgImh0dHA6Ly93d3cuYWNtZS5jb20vYmxhaC8iLCAic3BhbT1iYXI7IHNlY3VyZSIpDQogICAgICAgIGludGVyYWN0XzI5NjUoY3MsICJodHRwOi8vd3d3LmFjbWUuY29tL2JsYWgvIiwNCiAgICAgICAgICAgICAgICAgICAgICAiZm9vPWJhcjsgc2VjdXJlOyBWZXJzaW9uPTEiKQ0KICAgICAgICBpbnRlcmFjdF8yOTY1KGNzLCAiaHR0cDovL3d3dy5hY21lLmNvbS9ibGFoLyIsDQogICAgICAgICAgICAgICAgICAgICAgImZvbz1iYXI7IHBhdGg9LzsgVmVyc2lvbj0xIikNCiAgICAgICAgaW50ZXJhY3RfMjk2NShjcywgImh0dHA6Ly93d3cuc29sLm5vIiwNCiAgICAgICAgICAgICAgICAgICAgICByJ2Jhbmc9d2FsbG9wOyB2ZXJzaW9uPTE7IGRvbWFpbj0iLnNvbC5ubyI7ICcNCiAgICAgICAgICAgICAgICAgICAgICByJ3BvcnQ9IjkwLDEwMCwgODAsODA4MCI7ICcNCiAgICAgICAgICAgICAgICAgICAgICByJ21heC1hZ2U9MTAwOyBDb21tZW50ID0gIkp1c3Qga2lkZGluZyEgKFwifFxcXFwpICInKQ0KDQogICAgICAgIHZlcnNpb25zID0gWzEsIDEsIDEsIDAsIDFdDQogICAgICAgIG5hbWVzID0gWyJiYW5nIiwgImZvbyIsICJmb28iLCAic3BhbSIsICJmb28iXQ0KICAgICAgICBkb21haW5zID0gWyIuc29sLm5vIiwgImJsYWguc3BhbS5vcmciLCAid3d3LmFjbWUuY29tIiwNCiAgICAgICAgICAgICAgICAgICAid3d3LmFjbWUuY29tIiwgInd3dy5hY21lLmNvbSJdDQogICAgICAgIHBhdGhzID0gWyIvIiwgIi8iLCAiLyIsICIvYmxhaCIsICIvYmxhaC8iXQ0KDQogICAgICAgIGZvciBpIGluIHJhbmdlKDQpOg0KICAgICAgICAgICAgaSA9IDANCiAgICAgICAgICAgIGZvciBjIGluIGNzOg0KICAgICAgICAgICAgICAgIHNlbGYuYXNzZXJ0SXNJbnN0YW5jZShjLCBDb29raWUpDQogICAgICAgICAgICAgICAgc2VsZi5hc3NlcnRFcXVhbChjLnZlcnNpb24sIHZlcnNpb25zW2ldKQ0KICAgICAgICAgICAgICAgIHNlbGYuYXNzZXJ0RXF1YWwoYy5uYW1lLCBuYW1lc1tpXSkNCiAgICAgICAgICAgICAgICBzZWxmLmFzc2VydEVxdWFsKGMuZG9tYWluLCBkb21haW5zW2ldKQ0KICAgICAgICAgICAgICAgIHNlbGYuYXNzZXJ0RXF1YWwoYy5wYXRoLCBwYXRoc1tpXSkNCiAgICAgICAgICAgICAgICBpID0gaSArIDENCg0KICAgIGRlZiB0ZXN0X3BhcnNlX25zX2hlYWRlcnMoc2VsZik6DQogICAgICAgIGZyb20gY29va2llbGliIGltcG9ydCBwYXJzZV9uc19oZWFkZXJzDQoNCiAgICAgICAgIyBtaXNzaW5nIGRvbWFpbiB2YWx1ZSAoaW52YWxpZCBjb29raWUpDQogICAgICAgIHNlbGYuYXNzZXJ0RXF1YWwoDQogICAgICAgICAgICBwYXJzZV9uc19oZWFkZXJzKFsiZm9vPWJhcjsgcGF0aD0vOyBkb21haW4iXSksDQogICAgICAgICAgICBbWygiZm9vIiwgImJhciIpLA0KICAgICAgICAgICAgICAoInBhdGgiLCAiLyIpLCAoImRvbWFpbiIsIE5vbmUpLCAoInZlcnNpb24iLCAiMCIpXV0NCiAgICAgICAgICAgICkNCiAgICAgICAgIyBpbnZhbGlkIGV4cGlyZXMgdmFsdWUNCiAgICAgICAgc2VsZi5hc3NlcnRFcXVhbCgNCiAgICAgICAgICAgIHBhcnNlX25zX2hlYWRlcnMoWyJmb289YmFyOyBleHBpcmVzPUZvbyBCYXIgMTIgMzM6MjI6MTEgMjAwMCJdKSwNCiAgICAgICAgICAgIFtbKCJmb28iLCAiYmFyIiksICgiZXhwaXJlcyIsIE5vbmUpLCAoInZlcnNpb24iLCAiMCIpXV0NCiAgICAgICAgICAgICkNCiAgICAgICAgIyBtaXNzaW5nIGNvb2tpZSB2YWx1ZSAodmFsaWQgY29va2llKQ0KICAgICAgICBzZWxmLmFzc2VydEVxdWFsKA0KICAgICAgICAgICAgcGFyc2VfbnNfaGVhZGVycyhbImZvbyJdKSwNCiAgICAgICAgICAgIFtbKCJmb28iLCBOb25lKSwgKCJ2ZXJzaW9uIiwgIjAiKV1dDQogICAgICAgICAgICApDQogICAgICAgICMgc2hvdWxkbid0IGFkZCB2ZXJzaW9uIGlmIGhlYWRlciBpcyBlbXB0eQ0KICAgICAgICBzZWxmLmFzc2VydEVxdWFsKHBhcnNlX25zX2hlYWRlcnMoWyIiXSksIFtdKQ0KDQogICAgZGVmIHRlc3RfYmFkX2Nvb2tpZV9oZWFkZXIoc2VsZik6DQoNCiAgICAgICAgZGVmIGNvb2tpZWphcl9mcm9tX2Nvb2tpZV9oZWFkZXJzKGhlYWRlcnMpOg0KICAgICAgICAgICAgZnJvbSBjb29raWVsaWIgaW1wb3J0IENvb2tpZUphcg0KICAgICAgICAgICAgZnJvbSB1cmxsaWIyIGltcG9ydCBSZXF1ZXN0DQogICAgICAgICAgICBjID0gQ29va2llSmFyKCkNCiAgICAgICAgICAgIHJlcSA9IFJlcXVlc3QoImh0dHA6Ly93d3cuZXhhbXBsZS5jb20vIikNCiAgICAgICAgICAgIHIgPSBGYWtlUmVzcG9uc2UoaGVhZGVycywgImh0dHA6Ly93d3cuZXhhbXBsZS5jb20vIikNCiAgICAgICAgICAgIGMuZXh0cmFjdF9jb29raWVzKHIsIHJlcSkNCiAgICAgICAgICAgIHJldHVybiBjDQoNCiAgICAgICAgIyBub25lIG9mIHRoZXNlIGJhZCBoZWFkZXJzIHNob3VsZCBjYXVzZSBhbiBleGNlcHRpb24gdG8gYmUgcmFpc2VkDQogICAgICAgIGZvciBoZWFkZXJzIGluIFsNCiAgICAgICAgICAgIFsiU2V0LUNvb2tpZTogIl0sICAjIGFjdHVhbGx5LCBub3RoaW5nIHdyb25nIHdpdGggdGhpcw0KICAgICAgICAgICAgWyJTZXQtQ29va2llMjogIl0sICAjIGRpdHRvDQogICAgICAgICAgICAjIG1pc3NpbmcgZG9tYWluIHZhbHVlDQogICAgICAgICAgICBbIlNldC1Db29raWUyOiBhPWZvbzsgcGF0aD0vOyBWZXJzaW9uPTE7IGRvbWFpbiJdLA0KICAgICAgICAgICAgIyBiYWQgbWF4LWFnZQ0KICAgICAgICAgICAgWyJTZXQtQ29va2llOiBiPWZvbzsgbWF4LWFnZT1vb3BzIl0sDQogICAgICAgICAgICAjIGJhZCB2ZXJzaW9uDQogICAgICAgICAgICBbIlNldC1Db29raWU6IGI9Zm9vOyB2ZXJzaW9uPXNwYW0iXSwNCiAgICAgICAgICAgIF06DQogICAgICAgICAgICBjID0gY29va2llamFyX2Zyb21fY29va2llX2hlYWRlcnMoaGVhZGVycykNCiAgICAgICAgICAgICMgdGhlc2UgYmFkIGNvb2tpZXMgc2hvdWxkbid0IGJlIHNldA0KICAgICAgICAgICAgc2VsZi5hc3NlcnRFcXVhbChsZW4oYyksIDApDQoNCiAgICAgICAgIyBjb29raWUgd2l0aCBpbnZhbGlkIGV4cGlyZXMgaXMgdHJlYXRlZCBhcyBzZXNzaW9uIGNvb2tpZQ0KICAgICAgICBoZWFkZXJzID0gWyJTZXQtQ29va2llOiBjPWZvbzsgZXhwaXJlcz1Gb28gQmFyIDEyIDMzOjIyOjExIDIwMDAiXQ0KICAgICAgICBjID0gY29va2llamFyX2Zyb21fY29va2llX2hlYWRlcnMoaGVhZGVycykNCiAgICAgICAgY29va2llID0gYy5fY29va2llc1sid3d3LmV4YW1wbGUuY29tIl1bIi8iXVsiYyJdDQogICAgICAgIHNlbGYuYXNzZXJ0VHJ1ZShjb29raWUuZXhwaXJlcyBpcyBOb25lKQ0KDQoNCmNsYXNzIExXUENvb2tpZVRlc3RzKFRlc3RDYXNlKToNCiAgICAjIFRlc3RzIHRha2VuIGZyb20gbGlid3d3LXBlcmwsIHdpdGggYSBmZXcgbW9kaWZpY2F0aW9ucyBhbmQgYWRkaXRpb25zLg0KDQogICAgZGVmIHRlc3RfbmV0c2NhcGVfZXhhbXBsZV8xKHNlbGYpOg0KICAgICAgICBmcm9tIGNvb2tpZWxpYiBpbXBvcnQgQ29va2llSmFyLCBEZWZhdWx0Q29va2llUG9saWN5DQogICAgICAgIGZyb20gdXJsbGliMiBpbXBvcnQgUmVxdWVzdA0KDQogICAgICAgICMtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tDQogICAgICAgICMgRmlyc3Qgd2UgY2hlY2sgdGhhdCBpdCB3b3JrcyBmb3IgdGhlIG9yaWdpbmFsIGV4YW1wbGUgYXQNCiAgICAgICAgIyBodHRwOi8vd3d3Lm5ldHNjYXBlLmNvbS9uZXdzcmVmL3N0ZC9jb29raWVfc3BlYy5odG1sDQoNCiAgICAgICAgIyBDbGllbnQgcmVxdWVzdHMgYSBkb2N1bWVudCwgYW5kIHJlY2VpdmVzIGluIHRoZSByZXNwb25zZToNCiAgICAgICAgIw0KICAgICAgICAjICAgICAgIFNldC1Db29raWU6IENVU1RPTUVSPVdJTEVfRV9DT1lPVEU7IHBhdGg9LzsgZXhwaXJlcz1XZWRuZXNkYXksIDA5LU5vdi05OSAyMzoxMjo0MCBHTVQNCiAgICAgICAgIw0KICAgICAgICAjIFdoZW4gY2xpZW50IHJlcXVlc3RzIGEgVVJMIGluIHBhdGggIi8iIG9uIHRoaXMgc2VydmVyLCBpdCBzZW5kczoNCiAgICAgICAgIw0KICAgICAgICAjICAgICAgIENvb2tpZTogQ1VTVE9NRVI9V0lMRV9FX0NPWU9URQ0KICAgICAgICAjDQogICAgICAgICMgQ2xpZW50IHJlcXVlc3RzIGEgZG9jdW1lbnQsIGFuZCByZWNlaXZlcyBpbiB0aGUgcmVzcG9uc2U6DQogICAgICAgICMNCiAgICAgICAgIyAgICAgICBTZXQtQ29va2llOiBQQVJUX05VTUJFUj1ST0NLRVRfTEFVTkNIRVJfMDAwMTsgcGF0aD0vDQogICAgICAgICMNCiAgICAgICAgIyBXaGVuIGNsaWVudCByZXF1ZXN0cyBhIFVSTCBpbiBwYXRoICIvIiBvbiB0aGlzIHNlcnZlciwgaXQgc2VuZHM6DQogICAgICAgICMNCiAgICAgICAgIyAgICAgICBDb29raWU6IENVU1RPTUVSPVdJTEVfRV9DT1lPVEU7IFBBUlRfTlVNQkVSPVJPQ0tFVF9MQVVOQ0hFUl8wMDAxDQogICAgICAgICMNCiAgICAgICAgIyBDbGllbnQgcmVjZWl2ZXM6DQogICAgICAgICMNCiAgICAgICAgIyAgICAgICBTZXQtQ29va2llOiBTSElQUElORz1GRURFWDsgcGF0aD0vZm8NCiAgICAgICAgIw0KICAgICAgICAjIFdoZW4gY2xpZW50IHJlcXVlc3RzIGEgVVJMIGluIHBhdGggIi8iIG9uIHRoaXMgc2VydmVyLCBpdCBzZW5kczoNCiAgICAgICAgIw0KICAgICAgICAjICAgICAgIENvb2tpZTogQ1VTVE9NRVI9V0lMRV9FX0NPWU9URTsgUEFSVF9OVU1CRVI9Uk9DS0VUX0xBVU5DSEVSXzAwMDENCiAgICAgICAgIw0KICAgICAgICAjIFdoZW4gY2xpZW50IHJlcXVlc3RzIGEgVVJMIGluIHBhdGggIi9mb28iIG9uIHRoaXMgc2VydmVyLCBpdCBzZW5kczoNCiAgICAgICAgIw0KICAgICAgICAjICAgICAgIENvb2tpZTogQ1VTVE9NRVI9V0lMRV9FX0NPWU9URTsgUEFSVF9OVU1CRVI9Uk9DS0VUX0xBVU5DSEVSXzAwMDE7IFNISVBQSU5HPUZFREVYDQogICAgICAgICMNCiAgICAgICAgIyBUaGUgbGFzdCBDb29raWUgaXMgYnVnZ3ksIGJlY2F1c2UgYm90aCBzcGVjaWZpY2F0aW9ucyBzYXkgdGhhdCB0aGUNCiAgICAgICAgIyBtb3N0IHNwZWNpZmljIGNvb2tpZSBtdXN0IGJlIHNlbnQgZmlyc3QuICBTSElQUElORz1GRURFWCBpcyB0aGUNCiAgICAgICAgIyBtb3N0IHNwZWNpZmljIGFuZCBzaG91bGQgdGh1cyBiZSBmaXJzdC4NCg0KICAgICAgICB5ZWFyX3BsdXNfb25lID0gdGltZS5sb2NhbHRpbWUoKVswXSArIDENCg0KICAgICAgICBoZWFkZXJzID0gW10NCg0KICAgICAgICBjID0gQ29va2llSmFyKERlZmF1bHRDb29raWVQb2xpY3kocmZjMjk2NSA9IFRydWUpKQ0KDQogICAgICAgICNyZXEgPSBSZXF1ZXN0KCJodHRwOi8vMS4xLjEuMS8iLA0KICAgICAgICAjICAgICAgICAgICAgICBoZWFkZXJzPXsiSG9zdCI6ICJ3d3cuYWNtZS5jb206ODAifSkNCiAgICAgICAgcmVxID0gUmVxdWVzdCgiaHR0cDovL3d3dy5hY21lLmNvbTo4MC8iLA0KICAgICAgICAgICAgICAgICAgICAgIGhlYWRlcnM9eyJIb3N0IjogInd3dy5hY21lLmNvbTo4MCJ9KQ0KDQogICAgICAgIGhlYWRlcnMuYXBwZW5kKA0KICAgICAgICAgICAgIlNldC1Db29raWU6IENVU1RPTUVSPVdJTEVfRV9DT1lPVEU7IHBhdGg9LyA7ICINCiAgICAgICAgICAgICJleHBpcmVzPVdlZG5lc2RheSwgMDktTm92LSVkIDIzOjEyOjQwIEdNVCIgJSB5ZWFyX3BsdXNfb25lKQ0KICAgICAgICByZXMgPSBGYWtlUmVzcG9uc2UoaGVhZGVycywgImh0dHA6Ly93d3cuYWNtZS5jb20vIikNCiAgICAgICAgYy5leHRyYWN0X2Nvb2tpZXMocmVzLCByZXEpDQoNCiAgICAgICAgcmVxID0gUmVxdWVzdCgiaHR0cDovL3d3dy5hY21lLmNvbS8iKQ0KICAgICAgICBjLmFkZF9jb29raWVfaGVhZGVyKHJlcSkNCg0KICAgICAgICBzZWxmLmFzc2VydEVxdWFsKHJlcS5nZXRfaGVhZGVyKCJDb29raWUiKSwgIkNVU1RPTUVSPVdJTEVfRV9DT1lPVEUiKQ0KICAgICAgICBzZWxmLmFzc2VydEVxdWFsKHJlcS5nZXRfaGVhZGVyKCJDb29raWUyIiksICckVmVyc2lvbj0iMSInKQ0KDQogICAgICAgIGhlYWRlcnMuYXBwZW5kKCJTZXQtQ29va2llOiBQQVJUX05VTUJFUj1ST0NLRVRfTEFVTkNIRVJfMDAwMTsgcGF0aD0vIikNCiAgICAgICAgcmVzID0gRmFrZVJlc3BvbnNlKGhlYWRlcnMsICJodHRwOi8vd3d3LmFjbWUuY29tLyIpDQogICAgICAgIGMuZXh0cmFjdF9jb29raWVzKHJlcywgcmVxKQ0KDQogICAgICAgIHJlcSA9IFJlcXVlc3QoImh0dHA6Ly93d3cuYWNtZS5jb20vZm9vL2JhciIpDQogICAgICAgIGMuYWRkX2Nvb2tpZV9oZWFkZXIocmVxKQ0KDQogICAgICAgIGggPSByZXEuZ2V0X2hlYWRlcigiQ29va2llIikNCiAgICAgICAgc2VsZi5hc3NlcnRJbigiUEFSVF9OVU1CRVI9Uk9DS0VUX0xBVU5DSEVSXzAwMDEiLCBoKQ0KICAgICAgICBzZWxmLmFzc2VydEluKCJDVVNUT01FUj1XSUxFX0VfQ09ZT1RFIiwgaCkNCg0KICAgICAgICBoZWFkZXJzLmFwcGVuZCgnU2V0LUNvb2tpZTogU0hJUFBJTkc9RkVERVg7IHBhdGg9L2ZvbycpDQogICAgICAgIHJlcyA9IEZha2VSZXNwb25zZShoZWFkZXJzLCAiaHR0cDovL3d3dy5hY21lLmNvbSIpDQogICAgICAgIGMuZXh0cmFjdF9jb29raWVzKHJlcywgcmVxKQ0KDQogICAgICAgIHJlcSA9IFJlcXVlc3QoImh0dHA6Ly93d3cuYWNtZS5jb20vIikNCiAgICAgICAgYy5hZGRfY29va2llX2hlYWRlcihyZXEpDQoNCiAgICAgICAgaCA9IHJlcS5nZXRfaGVhZGVyKCJDb29raWUiKQ0KICAgICAgICBzZWxmLmFzc2VydEluKCJQQVJUX05VTUJFUj1ST0NLRVRfTEFVTkNIRVJfMDAwMSIsIGgpDQogICAgICAgIHNlbGYuYXNzZXJ0SW4oIkNVU1RPTUVSPVdJTEVfRV9DT1lPVEUiLCBoKQ0KICAgICAgICBzZWxmLmFzc2VydE5vdEluKCJTSElQUElORz1GRURFWCIsIGgpDQoNCiAgICAgICAgcmVxID0gUmVxdWVzdCgiaHR0cDovL3d3dy5hY21lLmNvbS9mb28vIikNCiAgICAgICAgYy5hZGRfY29va2llX2hlYWRlcihyZXEpDQoNCiAgICAgICAgaCA9IHJlcS5nZXRfaGVhZGVyKCJDb29raWUiKQ0KICAgICAgICBzZWxmLmFzc2VydEluKCJQQVJUX05VTUJFUj1ST0NLRVRfTEFVTkNIRVJfMDAwMSIsIGgpDQogICAgICAgIHNlbGYuYXNzZXJ0SW4oIkNVU1RPTUVSPVdJTEVfRV9DT1lPVEUiLCBoKQ0KICAgICAgICBzZWxmLmFzc2VydFRydWUoaC5zdGFydHN3aXRoKCJTSElQUElORz1GRURFWDsiKSkNCg0KICAgIGRlZiB0ZXN0X25ldHNjYXBlX2V4YW1wbGVfMihzZWxmKToNCiAgICAgICAgZnJvbSBjb29raWVsaWIgaW1wb3J0IENvb2tpZUphcg0KICAgICAgICBmcm9tIHVybGxpYjIgaW1wb3J0IFJlcXVlc3QNCg0KICAgICAgICAjIFNlY29uZCBFeGFtcGxlIHRyYW5zYWN0aW9uIHNlcXVlbmNlOg0KICAgICAgICAjDQogICAgICAgICMgQXNzdW1lIGFsbCBtYXBwaW5ncyBmcm9tIGFib3ZlIGhhdmUgYmVlbiBjbGVhcmVkLg0KICAgICAgICAjDQogICAgICAgICMgQ2xpZW50IHJlY2VpdmVzOg0KICAgICAgICAjDQogICAgICAgICMgICAgICAgU2V0LUNvb2tpZTogUEFSVF9OVU1CRVI9Uk9DS0VUX0xBVU5DSEVSXzAwMDE7IHBhdGg9Lw0KICAgICAgICAjDQogICAgICAgICMgV2hlbiBjbGllbnQgcmVxdWVzdHMgYSBVUkwgaW4gcGF0aCAiLyIgb24gdGhpcyBzZXJ2ZXIsIGl0IHNlbmRzOg0KICAgICAgICAjDQogICAgICAgICMgICAgICAgQ29va2llOiBQQVJUX05VTUJFUj1ST0NLRVRfTEFVTkNIRVJfMDAwMQ0KICAgICAgICAjDQogICAgICAgICMgQ2xpZW50IHJlY2VpdmVzOg0KICAgICAgICAjDQogICAgICAgICMgICAgICAgU2V0LUNvb2tpZTogUEFSVF9OVU1CRVI9UklESU5HX1JPQ0tFVF8wMDIzOyBwYXRoPS9hbW1vDQogICAgICAgICMNCiAgICAgICAgIyBXaGVuIGNsaWVudCByZXF1ZXN0cyBhIFVSTCBpbiBwYXRoICIvYW1tbyIgb24gdGhpcyBzZXJ2ZXIsIGl0IHNlbmRzOg0KICAgICAgICAjDQogICAgICAgICMgICAgICAgQ29va2llOiBQQVJUX05VTUJFUj1SSURJTkdfUk9DS0VUXzAwMjM7IFBBUlRfTlVNQkVSPVJPQ0tFVF9MQVVOQ0hFUl8wMDAxDQogICAgICAgICMNCiAgICAgICAgIyAgICAgICBOT1RFOiBUaGVyZSBhcmUgdHdvIG5hbWUvdmFsdWUgcGFpcnMgbmFtZWQgIlBBUlRfTlVNQkVSIiBkdWUgdG8NCiAgICAgICAgIyAgICAgICB0aGUgaW5oZXJpdGFuY2Ugb2YgdGhlICIvIiBtYXBwaW5nIGluIGFkZGl0aW9uIHRvIHRoZSAiL2FtbW8iIG1hcHBpbmcuDQoNCiAgICAgICAgYyA9IENvb2tpZUphcigpDQogICAgICAgIGhlYWRlcnMgPSBbXQ0KDQogICAgICAgIHJlcSA9IFJlcXVlc3QoImh0dHA6Ly93d3cuYWNtZS5jb20vIikNCiAgICAgICAgaGVhZGVycy5hcHBlbmQoIlNldC1Db29raWU6IFBBUlRfTlVNQkVSPVJPQ0tFVF9MQVVOQ0hFUl8wMDAxOyBwYXRoPS8iKQ0KICAgICAgICByZXMgPSBGYWtlUmVzcG9uc2UoaGVhZGVycywgImh0dHA6Ly93d3cuYWNtZS5jb20vIikNCg0KICAgICAgICBjLmV4dHJhY3RfY29va2llcyhyZXMsIHJlcSkNCg0KICAgICAgICByZXEgPSBSZXF1ZXN0KCJodHRwOi8vd3d3LmFjbWUuY29tLyIpDQogICAgICAgIGMuYWRkX2Nvb2tpZV9oZWFkZXIocmVxKQ0KDQogICAgICAgIHNlbGYuYXNzZXJ0RXF1YWwocmVxLmdldF9oZWFkZXIoIkNvb2tpZSIpLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAiUEFSVF9OVU1CRVI9Uk9DS0VUX0xBVU5DSEVSXzAwMDEiKQ0KDQogICAgICAgIGhlYWRlcnMuYXBwZW5kKA0KICAgICAgICAgICAgIlNldC1Db29raWU6IFBBUlRfTlVNQkVSPVJJRElOR19ST0NLRVRfMDAyMzsgcGF0aD0vYW1tbyIpDQogICAgICAgIHJlcyA9IEZha2VSZXNwb25zZShoZWFkZXJzLCAiaHR0cDovL3d3dy5hY21lLmNvbS8iKQ0KICAgICAgICBjLmV4dHJhY3RfY29va2llcyhyZXMsIHJlcSkNCg0KICAgICAgICByZXEgPSBSZXF1ZXN0KCJodHRwOi8vd3d3LmFjbWUuY29tL2FtbW8iKQ0KICAgICAgICBjLmFkZF9jb29raWVfaGVhZGVyKHJlcSkNCg0KICAgICAgICBzZWxmLmFzc2VydFRydWUocmUuc2VhcmNoKHIiUEFSVF9OVU1CRVI9UklESU5HX1JPQ0tFVF8wMDIzO1xzKiINCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiUEFSVF9OVU1CRVI9Uk9DS0VUX0xBVU5DSEVSXzAwMDEiLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlcS5nZXRfaGVhZGVyKCJDb29raWUiKSkpDQoNCiAgICBkZWYgdGVzdF9pZXRmX2V4YW1wbGVfMShzZWxmKToNCiAgICAgICAgZnJvbSBjb29raWVsaWIgaW1wb3J0IENvb2tpZUphciwgRGVmYXVsdENvb2tpZVBvbGljeQ0KICAgICAgICAjLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQ0KICAgICAgICAjIFRoZW4gd2UgdGVzdCB3aXRoIHRoZSBleGFtcGxlcyBmcm9tIGRyYWZ0LWlldGYtaHR0cC1zdGF0ZS1tYW4tbWVjLTAzLnR4dA0KICAgICAgICAjDQogICAgICAgICMgNS4gIEVYQU1QTEVTDQoNCiAgICAgICAgYyA9IENvb2tpZUphcihEZWZhdWx0Q29va2llUG9saWN5KHJmYzI5NjU9VHJ1ZSkpDQoNCiAgICAgICAgIw0KICAgICAgICAjIDUuMSAgRXhhbXBsZSAxDQogICAgICAgICMNCiAgICAgICAgIyBNb3N0IGRldGFpbCBvZiByZXF1ZXN0IGFuZCByZXNwb25zZSBoZWFkZXJzIGhhcyBiZWVuIG9taXR0ZWQuICBBc3N1bWUNCiAgICAgICAgIyB0aGUgdXNlciBhZ2VudCBoYXMgbm8gc3RvcmVkIGNvb2tpZXMuDQogICAgICAgICMNCiAgICAgICAgIyAgIDEuICBVc2VyIEFnZW50IC0+IFNlcnZlcg0KICAgICAgICAjDQogICAgICAgICMgICAgICAgUE9TVCAvYWNtZS9sb2dpbiBIVFRQLzEuMQ0KICAgICAgICAjICAgICAgIFtmb3JtIGRhdGFdDQogICAgICAgICMNCiAgICAgICAgIyAgICAgICBVc2VyIGlkZW50aWZpZXMgc2VsZiB2aWEgYSBmb3JtLg0KICAgICAgICAjDQogICAgICAgICMgICAyLiAgU2VydmVyIC0+IFVzZXIgQWdlbnQNCiAgICAgICAgIw0KICAgICAgICAjICAgICAgIEhUVFAvMS4xIDIwMCBPSw0KICAgICAgICAjICAgICAgIFNldC1Db29raWUyOiBDdXN0b21lcj0iV0lMRV9FX0NPWU9URSI7IFZlcnNpb249IjEiOyBQYXRoPSIvYWNtZSINCiAgICAgICAgIw0KICAgICAgICAjICAgICAgIENvb2tpZSByZWZsZWN0cyB1c2VyJ3MgaWRlbnRpdHkuDQoNCiAgICAgICAgY29va2llID0gaW50ZXJhY3RfMjk2NSgNCiAgICAgICAgICAgIGMsICdodHRwOi8vd3d3LmFjbWUuY29tL2FjbWUvbG9naW4nLA0KICAgICAgICAgICAgJ0N1c3RvbWVyPSJXSUxFX0VfQ09ZT1RFIjsgVmVyc2lvbj0iMSI7IFBhdGg9Ii9hY21lIicpDQogICAgICAgIHNlbGYuYXNzZXJ0VHJ1ZShub3QgY29va2llKQ0KDQogICAgICAgICMNCiAgICAgICAgIyAgIDMuICBVc2VyIEFnZW50IC0+IFNlcnZlcg0KICAgICAgICAjDQogICAgICAgICMgICAgICAgUE9TVCAvYWNtZS9waWNraXRlbSBIVFRQLzEuMQ0KICAgICAgICAjICAgICAgIENvb2tpZTogJFZlcnNpb249IjEiOyBDdXN0b21lcj0iV0lMRV9FX0NPWU9URSI7ICRQYXRoPSIvYWNtZSINCiAgICAgICAgIyAgICAgICBbZm9ybSBkYXRhXQ0KICAgICAgICAjDQogICAgICAgICMgICAgICAgVXNlciBzZWxlY3RzIGFuIGl0ZW0gZm9yIGBgc2hvcHBpbmcgYmFza2V0LicnDQogICAgICAgICMNCiAgICAgICAgIyAgIDQuICBTZXJ2ZXIgLT4gVXNlciBBZ2VudA0KICAgICAgICAjDQogICAgICAgICMgICAgICAgSFRUUC8xLjEgMjAwIE9LDQogICAgICAgICMgICAgICAgU2V0LUNvb2tpZTI6IFBhcnRfTnVtYmVyPSJSb2NrZXRfTGF1bmNoZXJfMDAwMSI7IFZlcnNpb249IjEiOw0KICAgICAgICAjICAgICAgICAgICAgICAgUGF0aD0iL2FjbWUiDQogICAgICAgICMNCiAgICAgICAgIyAgICAgICBTaG9wcGluZyBiYXNrZXQgY29udGFpbnMgYW4gaXRlbS4NCg0KICAgICAgICBjb29raWUgPSBpbnRlcmFjdF8yOTY1KGMsICdodHRwOi8vd3d3LmFjbWUuY29tL2FjbWUvcGlja2l0ZW0nLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICdQYXJ0X051bWJlcj0iUm9ja2V0X0xhdW5jaGVyXzAwMDEiOyAnDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ1ZlcnNpb249IjEiOyBQYXRoPSIvYWNtZSInKTsNCiAgICAgICAgc2VsZi5hc3NlcnRUcnVlKHJlLnNlYXJjaCgNCiAgICAgICAgICAgIHInXlwkVmVyc2lvbj0iPzEiPzsgQ3VzdG9tZXI9Ij9XSUxFX0VfQ09ZT1RFIj87IFwkUGF0aD0iL2FjbWUiJCcsDQogICAgICAgICAgICBjb29raWUpKQ0KDQogICAgICAgICMNCiAgICAgICAgIyAgIDUuICBVc2VyIEFnZW50IC0+IFNlcnZlcg0KICAgICAgICAjDQogICAgICAgICMgICAgICAgUE9TVCAvYWNtZS9zaGlwcGluZyBIVFRQLzEuMQ0KICAgICAgICAjICAgICAgIENvb2tpZTogJFZlcnNpb249IjEiOw0KICAgICAgICAjICAgICAgICAgICAgICAgQ3VzdG9tZXI9IldJTEVfRV9DT1lPVEUiOyAkUGF0aD0iL2FjbWUiOw0KICAgICAgICAjICAgICAgICAgICAgICAgUGFydF9OdW1iZXI9IlJvY2tldF9MYXVuY2hlcl8wMDAxIjsgJFBhdGg9Ii9hY21lIg0KICAgICAgICAjICAgICAgIFtmb3JtIGRhdGFdDQogICAgICAgICMNCiAgICAgICAgIyAgICAgICBVc2VyIHNlbGVjdHMgc2hpcHBpbmcgbWV0aG9kIGZyb20gZm9ybS4NCiAgICAgICAgIw0KICAgICAgICAjICAgNi4gIFNlcnZlciAtPiBVc2VyIEFnZW50DQogICAgICAgICMNCiAgICAgICAgIyAgICAgICBIVFRQLzEuMSAyMDAgT0sNCiAgICAgICAgIyAgICAgICBTZXQtQ29va2llMjogU2hpcHBpbmc9IkZlZEV4IjsgVmVyc2lvbj0iMSI7IFBhdGg9Ii9hY21lIg0KICAgICAgICAjDQogICAgICAgICMgICAgICAgTmV3IGNvb2tpZSByZWZsZWN0cyBzaGlwcGluZyBtZXRob2QuDQoNCiAgICAgICAgY29va2llID0gaW50ZXJhY3RfMjk2NShjLCAiaHR0cDovL3d3dy5hY21lLmNvbS9hY21lL3NoaXBwaW5nIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnU2hpcHBpbmc9IkZlZEV4IjsgVmVyc2lvbj0iMSI7IFBhdGg9Ii9hY21lIicpDQoNCiAgICAgICAgc2VsZi5hc3NlcnRUcnVlKHJlLnNlYXJjaChyJ15cJFZlcnNpb249Ij8xIj87JywgY29va2llKSkNCiAgICAgICAgc2VsZi5hc3NlcnRUcnVlKHJlLnNlYXJjaChyJ1BhcnRfTnVtYmVyPSI/Um9ja2V0X0xhdW5jaGVyXzAwMDEiPzsnDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ1xzKlwkUGF0aD0iXC9hY21lIicsIGNvb2tpZSkpDQogICAgICAgIHNlbGYuYXNzZXJ0VHJ1ZShyZS5zZWFyY2gocidDdXN0b21lcj0iP1dJTEVfRV9DT1lPVEUiPztccypcJFBhdGg9IlwvYWNtZSInLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvb2tpZSkpDQoNCiAgICAgICAgIw0KICAgICAgICAjICAgNy4gIFVzZXIgQWdlbnQgLT4gU2VydmVyDQogICAgICAgICMNCiAgICAgICAgIyAgICAgICBQT1NUIC9hY21lL3Byb2Nlc3MgSFRUUC8xLjENCiAgICAgICAgIyAgICAgICBDb29raWU6ICRWZXJzaW9uPSIxIjsNCiAgICAgICAgIyAgICAgICAgICAgICAgIEN1c3RvbWVyPSJXSUxFX0VfQ09ZT1RFIjsgJFBhdGg9Ii9hY21lIjsNCiAgICAgICAgIyAgICAgICAgICAgICAgIFBhcnRfTnVtYmVyPSJSb2NrZXRfTGF1bmNoZXJfMDAwMSI7ICRQYXRoPSIvYWNtZSI7DQogICAgICAgICMgICAgICAgICAgICAgICBTaGlwcGluZz0iRmVkRXgiOyAkUGF0aD0iL2FjbWUiDQogICAgICAgICMgICAgICAgW2Zvcm0gZGF0YV0NCiAgICAgICAgIw0KICAgICAgICAjICAgICAgIFVzZXIgY2hvb3NlcyB0byBwcm9jZXNzIG9yZGVyLg0KICAgICAgICAjDQogICAgICAgICMgICA4LiAgU2VydmVyIC0+IFVzZXIgQWdlbnQNCiAgICAgICAgIw0KICAgICAgICAjICAgICAgIEhUVFAvMS4xIDIwMCBPSw0KICAgICAgICAjDQogICAgICAgICMgICAgICAgVHJhbnNhY3Rpb24gaXMgY29tcGxldGUuDQoNCiAgICAgICAgY29va2llID0gaW50ZXJhY3RfMjk2NShjLCAiaHR0cDovL3d3dy5hY21lLmNvbS9hY21lL3Byb2Nlc3MiKQ0KICAgICAgICBzZWxmLmFzc2VydFRydWUoDQogICAgICAgICAgICByZS5zZWFyY2gocidTaGlwcGluZz0iP0ZlZEV4Ij87XHMqXCRQYXRoPSJcL2FjbWUiJywgY29va2llKSBhbmQNCiAgICAgICAgICAgICJXSUxFX0VfQ09ZT1RFIiBpbiBjb29raWUpDQoNCiAgICAgICAgIw0KICAgICAgICAjIFRoZSB1c2VyIGFnZW50IG1ha2VzIGEgc2VyaWVzIG9mIHJlcXVlc3RzIG9uIHRoZSBvcmlnaW4gc2VydmVyLCBhZnRlcg0KICAgICAgICAjIGVhY2ggb2Ygd2hpY2ggaXQgcmVjZWl2ZXMgYSBuZXcgY29va2llLiAgQWxsIHRoZSBjb29raWVzIGhhdmUgdGhlIHNhbWUNCiAgICAgICAgIyBQYXRoIGF0dHJpYnV0ZSBhbmQgKGRlZmF1bHQpIGRvbWFpbi4gIEJlY2F1c2UgdGhlIHJlcXVlc3QgVVJMcyBhbGwgaGF2ZQ0KICAgICAgICAjIC9hY21lIGFzIGEgcHJlZml4LCBhbmQgdGhhdCBtYXRjaGVzIHRoZSBQYXRoIGF0dHJpYnV0ZSwgZWFjaCByZXF1ZXN0DQogICAgICAgICMgY29udGFpbnMgYWxsIHRoZSBjb29raWVzIHJlY2VpdmVkIHNvIGZhci4NCg0KICAgIGRlZiB0ZXN0X2lldGZfZXhhbXBsZV8yKHNlbGYpOg0KICAgICAgICBmcm9tIGNvb2tpZWxpYiBpbXBvcnQgQ29va2llSmFyLCBEZWZhdWx0Q29va2llUG9saWN5DQoNCiAgICAgICAgIyA1LjIgIEV4YW1wbGUgMg0KICAgICAgICAjDQogICAgICAgICMgVGhpcyBleGFtcGxlIGlsbHVzdHJhdGVzIHRoZSBlZmZlY3Qgb2YgdGhlIFBhdGggYXR0cmlidXRlLiAgQWxsIGRldGFpbA0KICAgICAgICAjIG9mIHJlcXVlc3QgYW5kIHJlc3BvbnNlIGhlYWRlcnMgaGFzIGJlZW4gb21pdHRlZC4gIEFzc3VtZSB0aGUgdXNlciBhZ2VudA0KICAgICAgICAjIGhhcyBubyBzdG9yZWQgY29va2llcy4NCg0KICAgICAgICBjID0gQ29va2llSmFyKERlZmF1bHRDb29raWVQb2xpY3kocmZjMjk2NT1UcnVlKSkNCg0KICAgICAgICAjIEltYWdpbmUgdGhlIHVzZXIgYWdlbnQgaGFzIHJlY2VpdmVkLCBpbiByZXNwb25zZSB0byBlYXJsaWVyIHJlcXVlc3RzLA0KICAgICAgICAjIHRoZSByZXNwb25zZSBoZWFkZXJzDQogICAgICAgICMNCiAgICAgICAgIyBTZXQtQ29va2llMjogUGFydF9OdW1iZXI9IlJvY2tldF9MYXVuY2hlcl8wMDAxIjsgVmVyc2lvbj0iMSI7DQogICAgICAgICMgICAgICAgICBQYXRoPSIvYWNtZSINCiAgICAgICAgIw0KICAgICAgICAjIGFuZA0KICAgICAgICAjDQogICAgICAgICMgU2V0LUNvb2tpZTI6IFBhcnRfTnVtYmVyPSJSaWRpbmdfUm9ja2V0XzAwMjMiOyBWZXJzaW9uPSIxIjsNCiAgICAgICAgIyAgICAgICAgIFBhdGg9Ii9hY21lL2FtbW8iDQoNCiAgICAgICAgaW50ZXJhY3RfMjk2NSgNCiAgICAgICAgICAgIGMsICJodHRwOi8vd3d3LmFjbWUuY29tL2FjbWUvYW1tby9zcGVjaWZpYyIsDQogICAgICAgICAgICAnUGFydF9OdW1iZXI9IlJvY2tldF9MYXVuY2hlcl8wMDAxIjsgVmVyc2lvbj0iMSI7IFBhdGg9Ii9hY21lIicsDQogICAgICAgICAgICAnUGFydF9OdW1iZXI9IlJpZGluZ19Sb2NrZXRfMDAyMyI7IFZlcnNpb249IjEiOyBQYXRoPSIvYWNtZS9hbW1vIicpDQoNCiAgICAgICAgIyBBIHN1YnNlcXVlbnQgcmVxdWVzdCBieSB0aGUgdXNlciBhZ2VudCB0byB0aGUgKHNhbWUpIHNlcnZlciBmb3IgVVJMcyBvZg0KICAgICAgICAjIHRoZSBmb3JtIC9hY21lL2FtbW8vLi4uICB3b3VsZCBpbmNsdWRlIHRoZSBmb2xsb3dpbmcgcmVxdWVzdCBoZWFkZXI6DQogICAgICAgICMNCiAgICAgICAgIyBDb29raWU6ICRWZXJzaW9uPSIxIjsNCiAgICAgICAgIyAgICAgICAgIFBhcnRfTnVtYmVyPSJSaWRpbmdfUm9ja2V0XzAwMjMiOyAkUGF0aD0iL2FjbWUvYW1tbyI7DQogICAgICAgICMgICAgICAgICBQYXJ0X051bWJlcj0iUm9ja2V0X0xhdW5jaGVyXzAwMDEiOyAkUGF0aD0iL2FjbWUiDQogICAgICAgICMNCiAgICAgICAgIyBOb3RlIHRoYXQgdGhlIE5BTUU9VkFMVUUgcGFpciBmb3IgdGhlIGNvb2tpZSB3aXRoIHRoZSBtb3JlIHNwZWNpZmljIFBhdGgNCiAgICAgICAgIyBhdHRyaWJ1dGUsIC9hY21lL2FtbW8sIGNvbWVzIGJlZm9yZSB0aGUgb25lIHdpdGggdGhlIGxlc3Mgc3BlY2lmaWMgUGF0aA0KICAgICAgICAjIGF0dHJpYnV0ZSwgL2FjbWUuICBGdXJ0aGVyIG5vdGUgdGhhdCB0aGUgc2FtZSBjb29raWUgbmFtZSBhcHBlYXJzIG1vcmUNCiAgICAgICAgIyB0aGFuIG9uY2UuDQoNCiAgICAgICAgY29va2llID0gaW50ZXJhY3RfMjk2NShjLCAiaHR0cDovL3d3dy5hY21lLmNvbS9hY21lL2FtbW8vLi4uIikNCiAgICAgICAgc2VsZi5hc3NlcnRUcnVlKA0KICAgICAgICAgICAgcmUuc2VhcmNoKHIiUmlkaW5nX1JvY2tldF8wMDIzLipSb2NrZXRfTGF1bmNoZXJfMDAwMSIsIGNvb2tpZSkpDQoNCiAgICAgICAgIyBBIHN1YnNlcXVlbnQgcmVxdWVzdCBieSB0aGUgdXNlciBhZ2VudCB0byB0aGUgKHNhbWUpIHNlcnZlciBmb3IgYSBVUkwgb2YNCiAgICAgICAgIyB0aGUgZm9ybSAvYWNtZS9wYXJ0cy8gd291bGQgaW5jbHVkZSB0aGUgZm9sbG93aW5nIHJlcXVlc3QgaGVhZGVyOg0KICAgICAgICAjDQogICAgICAgICMgQ29va2llOiAkVmVyc2lvbj0iMSI7IFBhcnRfTnVtYmVyPSJSb2NrZXRfTGF1bmNoZXJfMDAwMSI7ICRQYXRoPSIvYWNtZSINCiAgICAgICAgIw0KICAgICAgICAjIEhlcmUsIHRoZSBzZWNvbmQgY29va2llJ3MgUGF0aCBhdHRyaWJ1dGUgL2FjbWUvYW1tbyBpcyBub3QgYSBwcmVmaXggb2YNCiAgICAgICAgIyB0aGUgcmVxdWVzdCBVUkwsIC9hY21lL3BhcnRzLywgc28gdGhlIGNvb2tpZSBkb2VzIG5vdCBnZXQgZm9yd2FyZGVkIHRvDQogICAgICAgICMgdGhlIHNlcnZlci4NCg0KICAgICAgICBjb29raWUgPSBpbnRlcmFjdF8yOTY1KGMsICJodHRwOi8vd3d3LmFjbWUuY29tL2FjbWUvcGFydHMvIikNCiAgICAgICAgc2VsZi5hc3NlcnRJbigiUm9ja2V0X0xhdW5jaGVyXzAwMDEiLCBjb29raWUpDQogICAgICAgIHNlbGYuYXNzZXJ0Tm90SW4oIlJpZGluZ19Sb2NrZXRfMDAyMyIsIGNvb2tpZSkNCg0KICAgIGRlZiB0ZXN0X3JlamVjdGlvbihzZWxmKToNCiAgICAgICAgIyBUZXN0IHJlamVjdGlvbiBvZiBTZXQtQ29va2llMiByZXNwb25zZXMgYmFzZWQgb24gZG9tYWluLCBwYXRoLCBwb3J0Lg0KICAgICAgICBmcm9tIGNvb2tpZWxpYiBpbXBvcnQgRGVmYXVsdENvb2tpZVBvbGljeSwgTFdQQ29va2llSmFyDQoNCiAgICAgICAgcG9sID0gRGVmYXVsdENvb2tpZVBvbGljeShyZmMyOTY1PVRydWUpDQoNCiAgICAgICAgYyA9IExXUENvb2tpZUphcihwb2xpY3k9cG9sKQ0KDQogICAgICAgIG1heF9hZ2UgPSAibWF4LWFnZT0zNjAwIg0KDQogICAgICAgICMgaWxsZWdhbCBkb21haW4gKG5vIGVtYmVkZGVkIGRvdHMpDQogICAgICAgIGNvb2tpZSA9IGludGVyYWN0XzI5NjUoYywgImh0dHA6Ly93d3cuYWNtZS5jb20iLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICdmb289YmFyOyBkb21haW49Ii5jb20iOyB2ZXJzaW9uPTEnKQ0KICAgICAgICBzZWxmLmFzc2VydFRydWUobm90IGMpDQoNCiAgICAgICAgIyBsZWdhbCBkb21haW4NCiAgICAgICAgY29va2llID0gaW50ZXJhY3RfMjk2NShjLCAiaHR0cDovL3d3dy5hY21lLmNvbSIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ3Bpbmc9cG9uZzsgZG9tYWluPSJhY21lLmNvbSI7IHZlcnNpb249MScpDQogICAgICAgIHNlbGYuYXNzZXJ0RXF1YWwobGVuKGMpLCAxKQ0KDQogICAgICAgICMgaWxsZWdhbCBkb21haW4gKGhvc3QgcHJlZml4ICJ3d3cuYSIgY29udGFpbnMgYSBkb3QpDQogICAgICAgIGNvb2tpZSA9IGludGVyYWN0XzI5NjUoYywgImh0dHA6Ly93d3cuYS5hY21lLmNvbSIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ3doaXo9YmFuZzsgZG9tYWluPSJhY21lLmNvbSI7IHZlcnNpb249MScpDQogICAgICAgIHNlbGYuYXNzZXJ0RXF1YWwobGVuKGMpLCAxKQ0KDQogICAgICAgICMgbGVnYWwgZG9tYWluDQogICAgICAgIGNvb2tpZSA9IGludGVyYWN0XzI5NjUoYywgImh0dHA6Ly93d3cuYS5hY21lLmNvbSIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ3dvdz1mbHV0dGVyOyBkb21haW49Ii5hLmFjbWUuY29tIjsgdmVyc2lvbj0xJykNCiAgICAgICAgc2VsZi5hc3NlcnRFcXVhbChsZW4oYyksIDIpDQoNCiAgICAgICAgIyBjYW4ndCBwYXJ0aWFsbHkgbWF0Y2ggYW4gSVAtYWRkcmVzcw0KICAgICAgICBjb29raWUgPSBpbnRlcmFjdF8yOTY1KGMsICJodHRwOi8vMTI1LjEyNS4xMjUuMTI1IiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnenp6ej1waW5nOyBkb21haW49IjEyNS4xMjUuMTI1IjsgdmVyc2lvbj0xJykNCiAgICAgICAgc2VsZi5hc3NlcnRFcXVhbChsZW4oYyksIDIpDQoNCiAgICAgICAgIyBpbGxlZ2FsIHBhdGggKG11c3QgYmUgcHJlZml4IG9mIHJlcXVlc3QgcGF0aCkNCiAgICAgICAgY29va2llID0gaW50ZXJhY3RfMjk2NShjLCAiaHR0cDovL3d3dy5zb2wubm8iLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICdibGFoPXJodWJhcmI7IGRvbWFpbj0iLnNvbC5ubyI7IHBhdGg9Ii9mb28iOyAnDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ3ZlcnNpb249MScpDQogICAgICAgIHNlbGYuYXNzZXJ0RXF1YWwobGVuKGMpLCAyKQ0KDQogICAgICAgICMgbGVnYWwgcGF0aA0KICAgICAgICBjb29raWUgPSBpbnRlcmFjdF8yOTY1KGMsICJodHRwOi8vd3d3LnNvbC5uby9mb28vYmFyIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnYmluZz1ib25nOyBkb21haW49Ii5zb2wubm8iOyBwYXRoPSIvZm9vIjsgJw0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICd2ZXJzaW9uPTEnKQ0KICAgICAgICBzZWxmLmFzc2VydEVxdWFsKGxlbihjKSwgMykNCg0KICAgICAgICAjIGlsbGVnYWwgcG9ydCAocmVxdWVzdC1wb3J0IG5vdCBpbiBsaXN0KQ0KICAgICAgICBjb29raWUgPSBpbnRlcmFjdF8yOTY1KGMsICJodHRwOi8vd3d3LnNvbC5ubyIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ3doaXo9ZmZmdDsgZG9tYWluPSIuc29sLm5vIjsgcG9ydD0iOTAsMTAwIjsgJw0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICd2ZXJzaW9uPTEnKQ0KICAgICAgICBzZWxmLmFzc2VydEVxdWFsKGxlbihjKSwgMykNCg0KICAgICAgICAjIGxlZ2FsIHBvcnQNCiAgICAgICAgY29va2llID0gaW50ZXJhY3RfMjk2NSgNCiAgICAgICAgICAgIGMsICJodHRwOi8vd3d3LnNvbC5ubyIsDQogICAgICAgICAgICByJ2Jhbmc9d2FsbG9wOyB2ZXJzaW9uPTE7IGRvbWFpbj0iLnNvbC5ubyI7ICcNCiAgICAgICAgICAgIHIncG9ydD0iOTAsMTAwLCA4MCw4MDgwIjsgJw0KICAgICAgICAgICAgcidtYXgtYWdlPTEwMDsgQ29tbWVudCA9ICJKdXN0IGtpZGRpbmchIChcInxcXFxcKSAiJykNCiAgICAgICAgc2VsZi5hc3NlcnRFcXVhbChsZW4oYyksIDQpDQoNCiAgICAgICAgIyBwb3J0IGF0dHJpYnV0ZSB3aXRob3V0IGFueSB2YWx1ZSAoY3VycmVudCBwb3J0KQ0KICAgICAgICBjb29raWUgPSBpbnRlcmFjdF8yOTY1KGMsICJodHRwOi8vd3d3LnNvbC5ubyIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ2Zvbzk9YmFyOyB2ZXJzaW9uPTE7IGRvbWFpbj0iLnNvbC5ubyI7IHBvcnQ7ICcNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnbWF4LWFnZT0xMDA7JykNCiAgICAgICAgc2VsZi5hc3NlcnRFcXVhbChsZW4oYyksIDUpDQoNCiAgICAgICAgIyBlbmNvZGVkIHBhdGgNCiAgICAgICAgIyBMV1AgaGFzIHRoaXMgdGVzdCwgYnV0IHVuZXNjYXBpbmcgYWxsb3dlZCBwYXRoIGNoYXJhY3RlcnMgc2VlbXMNCiAgICAgICAgIyBsaWtlIGEgYmFkIGlkZWEsIHNvIEkgdGhpbmsgdGhpcyBzaG91bGQgZmFpbDoNCiMjICAgICAgICAgY29va2llID0gaW50ZXJhY3RfMjk2NShjLCAiaHR0cDovL3d3dy5zb2wubm8vZm9vLyIsDQojIyAgICAgICAgICAgICAgICAgICAgICAgICAgIHInZm9vOD1iYXI7IHZlcnNpb249MTsgcGF0aD0iLyU2Nm9vIicpDQogICAgICAgICMgYnV0IHRoaXMgaXMgT0ssIGJlY2F1c2UgJzwnIGlzIG5vdCBhbiBhbGxvd2VkIEhUVFAgVVJMIHBhdGgNCiAgICAgICAgIyBjaGFyYWN0ZXI6DQogICAgICAgIGNvb2tpZSA9IGludGVyYWN0XzI5NjUoYywgImh0dHA6Ly93d3cuc29sLm5vLzxvby8iLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHInZm9vOD1iYXI7IHZlcnNpb249MTsgcGF0aD0iLyUzY29vIicpDQogICAgICAgIHNlbGYuYXNzZXJ0RXF1YWwobGVuKGMpLCA2KQ0KDQogICAgICAgICMgc2F2ZSBhbmQgcmVzdG9yZQ0KICAgICAgICBmaWxlbmFtZSA9IHRlc3Rfc3VwcG9ydC5URVNURk4NCg0KICAgICAgICB0cnk6DQogICAgICAgICAgICBjLnNhdmUoZmlsZW5hbWUsIGlnbm9yZV9kaXNjYXJkPVRydWUpDQogICAgICAgICAgICBvbGQgPSByZXByKGMpDQoNCiAgICAgICAgICAgIGMgPSBMV1BDb29raWVKYXIocG9saWN5PXBvbCkNCiAgICAgICAgICAgIGMubG9hZChmaWxlbmFtZSwgaWdub3JlX2Rpc2NhcmQ9VHJ1ZSkNCiAgICAgICAgZmluYWxseToNCiAgICAgICAgICAgIHRyeTogb3MudW5saW5rKGZpbGVuYW1lKQ0KICAgICAgICAgICAgZXhjZXB0IE9TRXJyb3I6IHBhc3MNCg0KICAgICAgICBzZWxmLmFzc2VydEVxdWFsKG9sZCwgcmVwcihjKSkNCg0KICAgIGRlZiB0ZXN0X3VybF9lbmNvZGluZyhzZWxmKToNCiAgICAgICAgIyBUcnkgc29tZSBVUkwgZW5jb2RpbmdzIG9mIHRoZSBQQVRIcy4NCiAgICAgICAgIyAodGhlIGJlaGF2aW91ciBoZXJlIGhhcyBjaGFuZ2VkIGZyb20gbGlid3d3LXBlcmwpDQogICAgICAgIGZyb20gY29va2llbGliIGltcG9ydCBDb29raWVKYXIsIERlZmF1bHRDb29raWVQb2xpY3kNCg0KICAgICAgICBjID0gQ29va2llSmFyKERlZmF1bHRDb29raWVQb2xpY3kocmZjMjk2NT1UcnVlKSkNCiAgICAgICAgaW50ZXJhY3RfMjk2NShjLCAiaHR0cDovL3d3dy5hY21lLmNvbS9mb28lMmYlMjUvJTNjJTNjJTBBbmV3JUU1LyVFNSIsDQogICAgICAgICAgICAgICAgICAgICAgImZvbyAgPSAgIGJhcjsgdmVyc2lvbiAgICA9ICAgMSIpDQoNCiAgICAgICAgY29va2llID0gaW50ZXJhY3RfMjk2NSgNCiAgICAgICAgICAgIGMsICJodHRwOi8vd3d3LmFjbWUuY29tL2ZvbyUyZiUyNS88PCUwYW5ld+Uv5vjlIiwNCiAgICAgICAgICAgICdiYXI9YmF6OyBwYXRoPSIvZm9vLyI7IHZlcnNpb249MScpOw0KICAgICAgICB2ZXJzaW9uX3JlID0gcmUuY29tcGlsZShyJ15cJHZlcnNpb249XCI/MVwiPycsIHJlLkkpDQogICAgICAgIHNlbGYuYXNzZXJ0VHJ1ZSgiZm9vPWJhciIgaW4gY29va2llIGFuZCB2ZXJzaW9uX3JlLnNlYXJjaChjb29raWUpKQ0KDQogICAgICAgIGNvb2tpZSA9IGludGVyYWN0XzI5NjUoDQogICAgICAgICAgICBjLCAiaHR0cDovL3d3dy5hY21lLmNvbS9mb28vJTI1Lzw8JTBhbmV35S/m+OUiKQ0KICAgICAgICBzZWxmLmFzc2VydFRydWUobm90IGNvb2tpZSkNCg0KICAgICAgICAjIHVuaWNvZGUgVVJMIGRvZXNuJ3QgcmFpc2UgZXhjZXB0aW9uDQogICAgICAgIGNvb2tpZSA9IGludGVyYWN0XzI5NjUoYywgdSJodHRwOi8vd3d3LmFjbWUuY29tL1x4ZmMiKQ0KDQogICAgZGVmIHRlc3RfbW96aWxsYShzZWxmKToNCiAgICAgICAgIyBTYXZlIC8gbG9hZCBNb3ppbGxhL05ldHNjYXBlIGNvb2tpZSBmaWxlIGZvcm1hdC4NCiAgICAgICAgZnJvbSBjb29raWVsaWIgaW1wb3J0IE1vemlsbGFDb29raWVKYXIsIERlZmF1bHRDb29raWVQb2xpY3kNCg0KICAgICAgICB5ZWFyX3BsdXNfb25lID0gdGltZS5sb2NhbHRpbWUoKVswXSArIDENCg0KICAgICAgICBmaWxlbmFtZSA9IHRlc3Rfc3VwcG9ydC5URVNURk4NCg0KICAgICAgICBjID0gTW96aWxsYUNvb2tpZUphcihmaWxlbmFtZSwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcG9saWN5PURlZmF1bHRDb29raWVQb2xpY3kocmZjMjk2NT1UcnVlKSkNCiAgICAgICAgaW50ZXJhY3RfMjk2NShjLCAiaHR0cDovL3d3dy5hY21lLmNvbS8iLA0KICAgICAgICAgICAgICAgICAgICAgICJmb28xPWJhcjsgbWF4LWFnZT0xMDA7IFZlcnNpb249MSIpDQogICAgICAgIGludGVyYWN0XzI5NjUoYywgImh0dHA6Ly93d3cuYWNtZS5jb20vIiwNCiAgICAgICAgICAgICAgICAgICAgICAnZm9vMj1iYXI7IHBvcnQ9IjgwIjsgbWF4LWFnZT0xMDA7IERpc2NhcmQ7IFZlcnNpb249MScpDQogICAgICAgIGludGVyYWN0XzI5NjUoYywgImh0dHA6Ly93d3cuYWNtZS5jb20vIiwgImZvbzM9YmFyOyBzZWN1cmU7IFZlcnNpb249MSIpDQoNCiAgICAgICAgZXhwaXJlcyA9ICJleHBpcmVzPTA5LU5vdi0lZCAyMzoxMjo0MCBHTVQiICUgKHllYXJfcGx1c19vbmUsKQ0KICAgICAgICBpbnRlcmFjdF9uZXRzY2FwZShjLCAiaHR0cDovL3d3dy5mb28uY29tLyIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICJmb29hPWJhcjsgJXMiICUgZXhwaXJlcykNCiAgICAgICAgaW50ZXJhY3RfbmV0c2NhcGUoYywgImh0dHA6Ly93d3cuZm9vLmNvbS8iLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAiZm9vYj1iYXI7IERvbWFpbj0uZm9vLmNvbTsgJXMiICUgZXhwaXJlcykNCiAgICAgICAgaW50ZXJhY3RfbmV0c2NhcGUoYywgImh0dHA6Ly93d3cuZm9vLmNvbS8iLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAiZm9vYz1iYXI7IERvbWFpbj13d3cuZm9vLmNvbTsgJXMiICUgZXhwaXJlcykNCg0KICAgICAgICBkZWYgc2F2ZV9hbmRfcmVzdG9yZShjaiwgaWdub3JlX2Rpc2NhcmQpOg0KICAgICAgICAgICAgdHJ5Og0KICAgICAgICAgICAgICAgIGNqLnNhdmUoaWdub3JlX2Rpc2NhcmQ9aWdub3JlX2Rpc2NhcmQpDQogICAgICAgICAgICAgICAgbmV3X2MgPSBNb3ppbGxhQ29va2llSmFyKGZpbGVuYW1lLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEZWZhdWx0Q29va2llUG9saWN5KHJmYzI5NjU9VHJ1ZSkpDQogICAgICAgICAgICAgICAgbmV3X2MubG9hZChpZ25vcmVfZGlzY2FyZD1pZ25vcmVfZGlzY2FyZCkNCiAgICAgICAgICAgIGZpbmFsbHk6DQogICAgICAgICAgICAgICAgdHJ5OiBvcy51bmxpbmsoZmlsZW5hbWUpDQogICAgICAgICAgICAgICAgZXhjZXB0IE9TRXJyb3I6IHBhc3MNCiAgICAgICAgICAgIHJldHVybiBuZXdfYw0KDQogICAgICAgIG5ld19jID0gc2F2ZV9hbmRfcmVzdG9yZShjLCBUcnVlKQ0KICAgICAgICBzZWxmLmFzc2VydEVxdWFsKGxlbihuZXdfYyksIDYpICAjIG5vbmUgZGlzY2FyZGVkDQogICAgICAgIHNlbGYuYXNzZXJ0SW4oIm5hbWU9J2ZvbzEnLCB2YWx1ZT0nYmFyJyIsIHJlcHIobmV3X2MpKQ0KDQogICAgICAgIG5ld19jID0gc2F2ZV9hbmRfcmVzdG9yZShjLCBGYWxzZSkNCiAgICAgICAgc2VsZi5hc3NlcnRFcXVhbChsZW4obmV3X2MpLCA0KSAgIyAyIG9mIHRoZW0gZGlzY2FyZGVkIG9uIHNhdmUNCiAgICAgICAgc2VsZi5hc3NlcnRJbigibmFtZT0nZm9vMScsIHZhbHVlPSdiYXInIiwgcmVwcihuZXdfYykpDQoNCiAgICBkZWYgdGVzdF9uZXRzY2FwZV9taXNjKHNlbGYpOg0KICAgICAgICAjIFNvbWUgYWRkaXRpb25hbCBOZXRzY2FwZSBjb29raWVzIHRlc3RzLg0KICAgICAgICBmcm9tIGNvb2tpZWxpYiBpbXBvcnQgQ29va2llSmFyDQogICAgICAgIGZyb20gdXJsbGliMiBpbXBvcnQgUmVxdWVzdA0KDQogICAgICAgIGMgPSBDb29raWVKYXIoKQ0KICAgICAgICBoZWFkZXJzID0gW10NCiAgICAgICAgcmVxID0gUmVxdWVzdCgiaHR0cDovL2Zvby5iYXIuYWNtZS5jb20vZm9vIikNCg0KICAgICAgICAjIE5ldHNjYXBlIGFsbG93cyBhIGhvc3QgcGFydCB0aGF0IGNvbnRhaW5zIGRvdHMNCiAgICAgICAgaGVhZGVycy5hcHBlbmQoIlNldC1Db29raWU6IEN1c3RvbWVyPVdJTEVfRV9DT1lPVEU7IGRvbWFpbj0uYWNtZS5jb20iKQ0KICAgICAgICByZXMgPSBGYWtlUmVzcG9uc2UoaGVhZGVycywgImh0dHA6Ly93d3cuYWNtZS5jb20vZm9vIikNCiAgICAgICAgYy5leHRyYWN0X2Nvb2tpZXMocmVzLCByZXEpDQoNCiAgICAgICAgIyBhbmQgdGhhdCB0aGUgZG9tYWluIGlzIHRoZSBzYW1lIGFzIHRoZSBob3N0IHdpdGhvdXQgYWRkaW5nIGEgbGVhZGluZw0KICAgICAgICAjIGRvdCB0byB0aGUgZG9tYWluLiAgU2hvdWxkIG5vdCBxdW90ZSBldmVuIGlmIHN0cmFuZ2UgY2hhcnMgYXJlIHVzZWQNCiAgICAgICAgIyBpbiB0aGUgY29va2llIHZhbHVlLg0KICAgICAgICBoZWFkZXJzLmFwcGVuZCgiU2V0LUNvb2tpZTogUEFSVF9OVU1CRVI9Myw0OyBkb21haW49Zm9vLmJhci5hY21lLmNvbSIpDQogICAgICAgIHJlcyA9IEZha2VSZXNwb25zZShoZWFkZXJzLCAiaHR0cDovL3d3dy5hY21lLmNvbS9mb28iKQ0KICAgICAgICBjLmV4dHJhY3RfY29va2llcyhyZXMsIHJlcSkNCg0KICAgICAgICByZXEgPSBSZXF1ZXN0KCJodHRwOi8vZm9vLmJhci5hY21lLmNvbS9mb28iKQ0KICAgICAgICBjLmFkZF9jb29raWVfaGVhZGVyKHJlcSkNCiAgICAgICAgc2VsZi5hc3NlcnRUcnVlKA0KICAgICAgICAgICAgIlBBUlRfTlVNQkVSPTMsNCIgaW4gcmVxLmdldF9oZWFkZXIoIkNvb2tpZSIpIGFuZA0KICAgICAgICAgICAgIkN1c3RvbWVyPVdJTEVfRV9DT1lPVEUiIGluIHJlcS5nZXRfaGVhZGVyKCJDb29raWUiKSkNCg0KICAgIGRlZiB0ZXN0X2ludHJhbmV0X2RvbWFpbnNfMjk2NShzZWxmKToNCiAgICAgICAgIyBUZXN0IGhhbmRsaW5nIG9mIGxvY2FsIGludHJhbmV0IGhvc3RuYW1lcyB3aXRob3V0IGEgZG90Lg0KICAgICAgICBmcm9tIGNvb2tpZWxpYiBpbXBvcnQgQ29va2llSmFyLCBEZWZhdWx0Q29va2llUG9saWN5DQoNCiAgICAgICAgYyA9IENvb2tpZUphcihEZWZhdWx0Q29va2llUG9saWN5KHJmYzI5NjU9VHJ1ZSkpDQogICAgICAgIGludGVyYWN0XzI5NjUoYywgImh0dHA6Ly9leGFtcGxlLyIsDQogICAgICAgICAgICAgICAgICAgICAgImZvbzE9YmFyOyBQT1JUOyBEaXNjYXJkOyBWZXJzaW9uPTE7IikNCiAgICAgICAgY29va2llID0gaW50ZXJhY3RfMjk2NShjLCAiaHR0cDovL2V4YW1wbGUvIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnZm9vMj1iYXI7IGRvbWFpbj0iLmxvY2FsIjsgVmVyc2lvbj0xJykNCiAgICAgICAgc2VsZi5hc3NlcnRJbigiZm9vMT1iYXIiLCBjb29raWUpDQoNCiAgICAgICAgaW50ZXJhY3RfMjk2NShjLCAiaHR0cDovL2V4YW1wbGUvIiwgJ2ZvbzM9YmFyOyBWZXJzaW9uPTEnKQ0KICAgICAgICBjb29raWUgPSBpbnRlcmFjdF8yOTY1KGMsICJodHRwOi8vZXhhbXBsZS8iKQ0KICAgICAgICBzZWxmLmFzc2VydEluKCJmb28yPWJhciIsIGNvb2tpZSkNCiAgICAgICAgc2VsZi5hc3NlcnRFcXVhbChsZW4oYyksIDMpDQoNCiAgICBkZWYgdGVzdF9pbnRyYW5ldF9kb21haW5zX25zKHNlbGYpOg0KICAgICAgICBmcm9tIGNvb2tpZWxpYiBpbXBvcnQgQ29va2llSmFyLCBEZWZhdWx0Q29va2llUG9saWN5DQoNCiAgICAgICAgYyA9IENvb2tpZUphcihEZWZhdWx0Q29va2llUG9saWN5KHJmYzI5NjUgPSBGYWxzZSkpDQogICAgICAgIGludGVyYWN0X25ldHNjYXBlKGMsICJodHRwOi8vZXhhbXBsZS8iLCAiZm9vMT1iYXIiKQ0KICAgICAgICBjb29raWUgPSBpbnRlcmFjdF9uZXRzY2FwZShjLCAiaHR0cDovL2V4YW1wbGUvIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ2ZvbzI9YmFyOyBkb21haW49LmxvY2FsJykNCiAgICAgICAgc2VsZi5hc3NlcnRFcXVhbChsZW4oYyksIDIpDQogICAgICAgIHNlbGYuYXNzZXJ0SW4oImZvbzE9YmFyIiwgY29va2llKQ0KDQogICAgICAgIGNvb2tpZSA9IGludGVyYWN0X25ldHNjYXBlKGMsICJodHRwOi8vZXhhbXBsZS8iKQ0KICAgICAgICBzZWxmLmFzc2VydEluKCJmb28yPWJhciIsIGNvb2tpZSkNCiAgICAgICAgc2VsZi5hc3NlcnRFcXVhbChsZW4oYyksIDIpDQoNCiAgICBkZWYgdGVzdF9lbXB0eV9wYXRoKHNlbGYpOg0KICAgICAgICBmcm9tIGNvb2tpZWxpYiBpbXBvcnQgQ29va2llSmFyLCBEZWZhdWx0Q29va2llUG9saWN5DQogICAgICAgIGZyb20gdXJsbGliMiBpbXBvcnQgUmVxdWVzdA0KDQogICAgICAgICMgVGVzdCBmb3IgZW1wdHkgcGF0aA0KICAgICAgICAjIEJyb2tlbiB3ZWItc2VydmVyIE9SSU9OLzEuMy4zOCByZXR1cm5zIHRvIHRoZSBjbGllbnQgcmVzcG9uc2UgbGlrZQ0KICAgICAgICAjDQogICAgICAgICMgICAgICAgU2V0LUNvb2tpZTogSlNFU1NJT05JRD1BQkNERVJBTkRPTTEyMzsgUGF0aD0NCiAgICAgICAgIw0KICAgICAgICAjIGllLiB3aXRoIFBhdGggc2V0IHRvIG5vdGhpbmcuDQogICAgICAgICMgSW4gdGhpcyBjYXNlLCBleHRyYWN0X2Nvb2tpZXMoKSBtdXN0IHNldCBjb29raWUgdG8gLyAocm9vdCkNCiAgICAgICAgYyA9IENvb2tpZUphcihEZWZhdWx0Q29va2llUG9saWN5KHJmYzI5NjUgPSBUcnVlKSkNCiAgICAgICAgaGVhZGVycyA9IFtdDQoNCiAgICAgICAgcmVxID0gUmVxdWVzdCgiaHR0cDovL3d3dy5hbnRzLmNvbS8iKQ0KICAgICAgICBoZWFkZXJzLmFwcGVuZCgiU2V0LUNvb2tpZTogSlNFU1NJT05JRD1BQkNERVJBTkRPTTEyMzsgUGF0aD0iKQ0KICAgICAgICByZXMgPSBGYWtlUmVzcG9uc2UoaGVhZGVycywgImh0dHA6Ly93d3cuYW50cy5jb20vIikNCiAgICAgICAgYy5leHRyYWN0X2Nvb2tpZXMocmVzLCByZXEpDQoNCiAgICAgICAgcmVxID0gUmVxdWVzdCgiaHR0cDovL3d3dy5hbnRzLmNvbS8iKQ0KICAgICAgICBjLmFkZF9jb29raWVfaGVhZGVyKHJlcSkNCg0KICAgICAgICBzZWxmLmFzc2VydEVxdWFsKHJlcS5nZXRfaGVhZGVyKCJDb29raWUiKSwNCiAgICAgICAgICAgICAgICAgICAgICAgICAiSlNFU1NJT05JRD1BQkNERVJBTkRPTTEyMyIpDQogICAgICAgIHNlbGYuYXNzZXJ0RXF1YWwocmVxLmdldF9oZWFkZXIoIkNvb2tpZTIiKSwgJyRWZXJzaW9uPSIxIicpDQoNCiAgICAgICAgIyBtaXNzaW5nIHBhdGggaW4gdGhlIHJlcXVlc3QgVVJJDQogICAgICAgIHJlcSA9IFJlcXVlc3QoImh0dHA6Ly93d3cuYW50cy5jb206ODA4MCIpDQogICAgICAgIGMuYWRkX2Nvb2tpZV9oZWFkZXIocmVxKQ0KDQogICAgICAgIHNlbGYuYXNzZXJ0RXF1YWwocmVxLmdldF9oZWFkZXIoIkNvb2tpZSIpLA0KICAgICAgICAgICAgICAgICAgICAgICAgICJKU0VTU0lPTklEPUFCQ0RFUkFORE9NMTIzIikNCiAgICAgICAgc2VsZi5hc3NlcnRFcXVhbChyZXEuZ2V0X2hlYWRlcigiQ29va2llMiIpLCAnJFZlcnNpb249IjEiJykNCg0KICAgIGRlZiB0ZXN0X3Nlc3Npb25fY29va2llcyhzZWxmKToNCiAgICAgICAgZnJvbSBjb29raWVsaWIgaW1wb3J0IENvb2tpZUphcg0KICAgICAgICBmcm9tIHVybGxpYjIgaW1wb3J0IFJlcXVlc3QNCg0KICAgICAgICB5ZWFyX3BsdXNfb25lID0gdGltZS5sb2NhbHRpbWUoKVswXSArIDENCg0KICAgICAgICAjIENoZWNrIHNlc3Npb24gY29va2llcyBhcmUgZGVsZXRlZCBwcm9wZXJseSBieQ0KICAgICAgICAjIENvb2tpZUphci5jbGVhcl9zZXNzaW9uX2Nvb2tpZXMgbWV0aG9kDQoNCiAgICAgICAgcmVxID0gUmVxdWVzdCgnaHR0cDovL3d3dy5wZXJsbWVpc3Rlci5jb20vc2NyaXB0cycpDQogICAgICAgIGhlYWRlcnMgPSBbXQ0KICAgICAgICBoZWFkZXJzLmFwcGVuZCgiU2V0LUNvb2tpZTogczE9c2Vzc2lvbjtQYXRoPS9zY3JpcHRzIikNCiAgICAgICAgaGVhZGVycy5hcHBlbmQoIlNldC1Db29raWU6IHAxPXBlcm07IERvbWFpbj0ucGVybG1laXN0ZXIuY29tOyINCiAgICAgICAgICAgICAgICAgICAgICAgIlBhdGg9LztleHBpcmVzPUZyaSwgMDItRmViLSVkIDIzOjI0OjIwIEdNVCIgJQ0KICAgICAgICAgICAgICAgICAgICAgICB5ZWFyX3BsdXNfb25lKQ0KICAgICAgICBoZWFkZXJzLmFwcGVuZCgiU2V0LUNvb2tpZTogcDI9cGVybTtQYXRoPS87ZXhwaXJlcz1GcmksICINCiAgICAgICAgICAgICAgICAgICAgICAgIjAyLUZlYi0lZCAyMzoyNDoyMCBHTVQiICUgeWVhcl9wbHVzX29uZSkNCiAgICAgICAgaGVhZGVycy5hcHBlbmQoIlNldC1Db29raWU6IHMyPXNlc3Npb247UGF0aD0vc2NyaXB0czsiDQogICAgICAgICAgICAgICAgICAgICAgICJEb21haW49LnBlcmxtZWlzdGVyLmNvbSIpDQogICAgICAgIGhlYWRlcnMuYXBwZW5kKCdTZXQtQ29va2llMjogczM9c2Vzc2lvbjtWZXJzaW9uPTE7RGlzY2FyZDtQYXRoPSIvIicpDQogICAgICAgIHJlcyA9IEZha2VSZXNwb25zZShoZWFkZXJzLCAnaHR0cDovL3d3dy5wZXJsbWVpc3Rlci5jb20vc2NyaXB0cycpDQoNCiAgICAgICAgYyA9IENvb2tpZUphcigpDQogICAgICAgIGMuZXh0cmFjdF9jb29raWVzKHJlcywgcmVxKQ0KICAgICAgICAjIEhvdyBtYW55IHNlc3Npb24vcGVybWFuZW50IGNvb2tpZXMgZG8gd2UgaGF2ZT8NCiAgICAgICAgY291bnRlciA9IHsic2Vzc2lvbl9hZnRlciI6IDAsDQogICAgICAgICAgICAgICAgICAgInBlcm1fYWZ0ZXIiOiAwLA0KICAgICAgICAgICAgICAgICAgICJzZXNzaW9uX2JlZm9yZSI6IDAsDQogICAgICAgICAgICAgICAgICAgInBlcm1fYmVmb3JlIjogMH0NCiAgICAgICAgZm9yIGNvb2tpZSBpbiBjOg0KICAgICAgICAgICAga2V5ID0gIiVzX2JlZm9yZSIgJSBjb29raWUudmFsdWUNCiAgICAgICAgICAgIGNvdW50ZXJba2V5XSA9IGNvdW50ZXJba2V5XSArIDENCiAgICAgICAgYy5jbGVhcl9zZXNzaW9uX2Nvb2tpZXMoKQ0KICAgICAgICAjIEhvdyBtYW55IG5vdz8NCiAgICAgICAgZm9yIGNvb2tpZSBpbiBjOg0KICAgICAgICAgICAga2V5ID0gIiVzX2FmdGVyIiAlIGNvb2tpZS52YWx1ZQ0KICAgICAgICAgICAgY291bnRlcltrZXldID0gY291bnRlcltrZXldICsgMQ0KDQogICAgICAgIHNlbGYuYXNzZXJ0VHJ1ZShub3QgKA0KICAgICAgICAgICAgIyBhIHBlcm1hbmVudCBjb29raWUgZ290IGxvc3QgYWNjaWRlbnRhbGx5DQogICAgICAgICAgICBjb3VudGVyWyJwZXJtX2FmdGVyIl0gIT0gY291bnRlclsicGVybV9iZWZvcmUiXSBvcg0KICAgICAgICAgICAgIyBhIHNlc3Npb24gY29va2llIGhhc24ndCBiZWVuIGNsZWFyZWQNCiAgICAgICAgICAgIGNvdW50ZXJbInNlc3Npb25fYWZ0ZXIiXSAhPSAwIG9yDQogICAgICAgICAgICAjIHdlIGRpZG4ndCBoYXZlIHNlc3Npb24gY29va2llcyBpbiB0aGUgZmlyc3QgcGxhY2UNCiAgICAgICAgICAgIGNvdW50ZXJbInNlc3Npb25fYmVmb3JlIl0gPT0gMCkpDQoNCg0KZGVmIHRlc3RfbWFpbih2ZXJib3NlPU5vbmUpOg0KICAgIHRlc3Rfc3VwcG9ydC5ydW5fdW5pdHRlc3QoDQogICAgICAgIERhdGVUaW1lVGVzdHMsDQogICAgICAgIEhlYWRlclRlc3RzLA0KICAgICAgICBDb29raWVUZXN0cywNCiAgICAgICAgRmlsZUNvb2tpZUphclRlc3RzLA0KICAgICAgICBMV1BDb29raWVUZXN0cywNCiAgICAgICAgKQ0KDQppZiBfX25hbWVfXyA9PSAiX19tYWluX18iOg0KICAgIHRlc3RfbWFpbih2ZXJib3NlPVRydWUpDQo=