<?xml version="1.0" encoding="ISO-8859-1"?>
<gallerytpl>
	<name>Lightbox</name>
	<version>2.05-1</version>
	<galleryversion>1.4.4</galleryversion>
	<about>PHA+VGhpcyBHYWxsZXJ5dGVtcGxhdGUgdXNlcyB0aGUgTGlnaHRib3gyIHN5c3RlbSB2ZXJzaW9uIDIuMDUgYnkgTG9rZXNoIERoYWthcjwvcD4NCjxwPkRvY3VtZW50YXRpb24gY2FuIGJlIGZvdW5kIGF0IDxhIGhyZWY9Imh0dHA6Ly93d3cuaHVkZGxldG9nZXRoZXIuY29tL3Byb2plY3RzL2xpZ2h0Ym94Mi8iIHRhcmdldD0iX2JsYW5rIj53d3cuaHVkZGxldG9nZXRoZXIuY29tL3Byb2plY3RzL2xpZ2h0Ym94MjwvYT48L3A+DQo8cD5GaWxlcyB0aGF0IGNvbWUgd2l0aCBMaWdodGJveCBhcmUgc3RvcmVkIGluIDxlbT5tb2R1bGVzL0dhbGxlcnkvdGVtcGxhdGVzL2xpZ2h0Ym94LzwvZW0+PC9wPg0KPHA+TGljZW5zZWQgdW5kZXIgdGhlIDxhIGhyZWY9Imh0dHA6Ly9jcmVhdGl2ZWNvbW1vbnMub3JnL2xpY2Vuc2VzL2J5LzIuNS8iPkNyZWF0aXZlIENvbW1vbnMgQXR0cmlidXRpb24gMi41IExpY2Vuc2U8L2E+PC9wPg0KPGEgaHJlZj0iaHR0cDovL2RvY3MuanF1ZXJ5LmNvbS9MaWNlbnNpbmciPjwvYT4=</about>
	<thumbwidth></thumbwidth>
	<thumbheight></thumbheight>
	<resizemethod></resizemethod>
	<maxnumber></maxnumber>
	<sortitems>n-isdir/s+file</sortitems>
	<tplcode>PGRpdiBjbGFzcz0iZ2FsbGVyeSI+DQp7aWYgIWVtcHR5KCRtb2R1bGVfbWVzc2FnZSl9PGg0PnskbW9kdWxlX21lc3NhZ2V8ZXNjYXBlfTwvaDQ+ey9pZn0NCntpZiAhZW1wdHkoJGdhbGxlcnl0aXRsZSl9PGgzPnskZ2FsbGVyeXRpdGxlfTwvaDM+ey9pZn0NCntpZiAhZW1wdHkoJGdhbGxlcnljb21tZW50KX08ZGl2IGNsYXNzPSJnYWxsZXJ5Y29tbWVudCI+eyRnYWxsZXJ5Y29tbWVudH08L2Rpdj57L2lmfQ0KPHA+eyRpbWFnZWNvdW50fTwvcD4NCjxkaXYgY2xhc3M9InBhZ2VuYXZpZ2F0aW9uIj4NCntpZiAkcGFnZXMgPiAxfQ0KPGRpdiBjbGFzcz0icHJldnBhZ2UiPnskcHJldnBhZ2V9PC9kaXY+DQo8ZGl2IGNsYXNzPSJuZXh0cGFnZSI+eyRuZXh0cGFnZX08L2Rpdj4NCnsvaWZ9DQp7aWYgISRoaWRlcGFyZW50bGluayAmJiAhZW1wdHkoJHBhcmVudGxpbmspfTxkaXYgY2xhc3M9InBhcmVudGxpbmsiPnskcGFyZW50bGlua308L2Rpdj57L2lmfQ0Ke2lmICRwYWdlcyA+IDF9PGRpdiBjbGFzcz0icGFnZWxpbmtzIj57JHBhZ2VsaW5rc308L2Rpdj57L2lmfQ0KPC9kaXY+DQoNCntmb3JlYWNoIGZyb209JGltYWdlcyBpdGVtPWltYWdlfQ0KCTxkaXYgY2xhc3M9ImltZyI+DQoJe2lmICRpbWFnZS0+aXNkaXJ9DQoJCTxhIGhyZWY9InskaW1hZ2UtPmZpbGV9IiB0aXRsZT0ieyRpbWFnZS0+dGl0bGVuYW1lfSI+PGltZyBzcmM9InskaW1hZ2UtPnRodW1ifGVzY2FwZTondXJsJ3xyZXBsYWNlOiclMkYnOicvJ30iIGFsdD0ieyRpbWFnZS0+dGl0bGVuYW1lfSIgLz48L2E+PGJyIC8+DQoJCXskaW1hZ2UtPnRpdGxlbmFtZX0NCgl7ZWxzZX0NCiAgIDxhIGhyZWY9InskaW1hZ2UtPmZpbGV9IiB0aXRsZT0ieyRpbWFnZS0+dGl0bGVuYW1lfSIgcmVsPSJsaWdodGJveFtnYWxsZXJ5eyRnYWxsZXJ5aWR9XSI+PGltZyBzcmM9InskaW1hZ2UtPnRodW1ifGVzY2FwZTondXJsJ3xyZXBsYWNlOiclMkYnOicvJ30iIGFsdD0ieyRpbWFnZS0+dGl0bGVuYW1lfSIgLz48L2E+DQoJey9pZn0NCgk8L2Rpdj4NCnsvZm9yZWFjaH0NCjxkaXYgY2xhc3M9ImdhbGxlcnljbGVhciI+Jm5ic3A7PC9kaXY+DQo8L2Rpdj4NCg0KDQo=</tplcode>
	<tplcss>LmdhbGxlcnkgLmltZyB7DQoJaGVpZ2h0OiAxMjBweDsNCgkvKndpZHRoOiAxMjBweDsqLw0KCWZsb2F0OiBsZWZ0Ow0KCW1hcmdpbjogMTBweDsNCgl0ZXh0LWFsaWduOiBjZW50ZXI7DQp9DQoNCi5nYWxsZXJ5IC5pbWcgYSB7DQoJZGlzcGxheTogaW5saW5lLWJsb2NrOw0KCWJvcmRlcjogMnB4IHNvbGlkICNkZGQ7DQoJcGFkZGluZzogMXB4Ow0KfQ0KDQouZ2FsbGVyeSAuaW1nIGE6aG92ZXIgew0KCWJvcmRlci1jb2xvcjogIzk5OTsNCn0NCg0KLmdhbGxlcnkgaW1nIHsNCglib3JkZXI6IG5vbmU7DQp9DQoNCi5nYWxsZXJ5IC5wYWdlbmF2aWdhdGlvbiB7DQoJaGVpZ2h0OiA1MHB4Ow0KfQ0KDQouZ2FsbGVyeSAucHJldnBhZ2UgYSwgLmdhbGxlcnkgLnByZXZwYWdlIGVtIHsNCglkaXNwbGF5OiBibG9jazsgDQoJd2lkdGg6IDUwcHg7IA0KCWhlaWdodDogMzlweDsNCglmbG9hdDogbGVmdDsgDQoJbWFyZ2luOiAwOw0KCXRleHQtaW5kZW50OiAtMTAwMHB4Ow0KCWJhY2tncm91bmQ6IHVybCguLi8uLi9pbWFnZXMvcHJldmlvdXMucG5nKSB0cmFuc3BhcmVudCBuby1yZXBlYXQgMCAwOw0KCW92ZXJmbG93OiBoaWRkZW47DQp9DQoNCi5nYWxsZXJ5IC5uZXh0cGFnZSBhLCAuZ2FsbGVyeSAubmV4dHBhZ2UgZW0gew0KCWRpc3BsYXk6IGJsb2NrOyANCgl3aWR0aDogNTBweDsgDQoJaGVpZ2h0OiAzOXB4Ow0KCWZsb2F0OiBsZWZ0OyANCgltYXJnaW46IDAgNnB4IDAgMDsNCgl0ZXh0LWluZGVudDogLTEwMDBweDsNCgliYWNrZ3JvdW5kOiB1cmwoLi4vLi4vaW1hZ2VzL25leHQucG5nKSB0cmFuc3BhcmVudCBuby1yZXBlYXQgMCAwOw0KCW92ZXJmbG93OiBoaWRkZW47DQp9DQoNCi5nYWxsZXJ5IC5wYXJlbnRsaW5rIGEgew0KCWRpc3BsYXk6IGJsb2NrOyANCgl3aWR0aDogNTBweDsgDQoJaGVpZ2h0OiAzOXB4Ow0KCWZsb2F0OiBsZWZ0OyANCgl0ZXh0LWluZGVudDogLTEwMDBweDsNCgliYWNrZ3JvdW5kOiB1cmwoLi4vLi4vaW1hZ2VzL3VwcGFnZS5wbmcpIHRyYW5zcGFyZW50IG5vLXJlcGVhdCAwIDA7DQoJb3ZlcmZsb3c6IGhpZGRlbjsNCn0NCg0KLmdhbGxlcnkgLnBhZ2VuYXZpZ2F0aW9uIGE6aG92ZXIgew0KCWJhY2tncm91bmQtcG9zaXRpb246IDAgLTQwcHg7DQp9DQoNCi5nYWxsZXJ5IC5wcmV2cGFnZSBlbSwgLmdhbGxlcnkgLm5leHRwYWdlIGVtIHsNCgliYWNrZ3JvdW5kLXBvc2l0aW9uOiAwIC04MHB4Ow0KfQ0KDQouZ2FsbGVyeSAucGFnZWxpbmtzIHsNCglmbG9hdDogcmlnaHQ7DQoJYm9yZGVyLXJpZ2h0OiAycHggc29saWQgIzY2NjsNCn0NCg0KLmdhbGxlcnkgLnBhZ2VsaW5rcyBhLCAuZ2FsbGVyeSAucGFnZWxpbmtzIGVtIHsNCgltYXJnaW4tdG9wOiA2cHg7DQoJcGFkZGluZzogMCA2cHg7DQoJYm9yZGVyLWxlZnQ6IDJweCBzb2xpZCAjNjY2Ow0KCXRleHQtYWxpZ246IGNlbnRlcjsNCglmb250OiBib2xkIDExcHggdmVyZGFuYTsgY29sb3I6ICM2NjY7DQp9DQoNCi5nYWxsZXJ5IC5wYWdlbGlua3MgZW0gew0KCWNvbG9yOiAjMDAwOw0KfQ0KDQouZ2FsbGVyeWNsZWFyIHsNCgljbGVhcjogYm90aDsNCn0NCg0KDQovKiBMSUdIVEJPWCAqLw0KDQojbGlnaHRib3h7CXBvc2l0aW9uOiBhYnNvbHV0ZTsJbGVmdDogMDsgd2lkdGg6IDEwMCU7IHotaW5kZXg6IDEwMDsgdGV4dC1hbGlnbjogY2VudGVyOyBsaW5lLWhlaWdodDogMDt9DQojbGlnaHRib3ggaW1neyB3aWR0aDogYXV0bzsgaGVpZ2h0OiBhdXRvO30NCiNsaWdodGJveCBhIGltZ3sgYm9yZGVyOiBub25lOyB9DQoNCiNvdXRlckltYWdlQ29udGFpbmVyeyBwb3NpdGlvbjogcmVsYXRpdmU7IGJhY2tncm91bmQtY29sb3I6ICNmZmY7IHdpZHRoOiAyNTBweDsgaGVpZ2h0OiAyNTBweDsgbWFyZ2luOiAwIGF1dG87IH0NCiNpbWFnZUNvbnRhaW5lcnsgcGFkZGluZzogMTBweDsgfQ0KDQojbG9hZGluZ3sgcG9zaXRpb246IGFic29sdXRlOyB0b3A6IDQwJTsgbGVmdDogMCU7IGhlaWdodDogMjUlOyB3aWR0aDogMTAwJTsgdGV4dC1hbGlnbjogY2VudGVyOyBsaW5lLWhlaWdodDogMDsgfQ0KI2hvdmVyTmF2eyBwb3NpdGlvbjogYWJzb2x1dGU7IHRvcDogMDsgbGVmdDogMDsgaGVpZ2h0OiAxMDAlOyB3aWR0aDogMTAwJTsgei1pbmRleDogMTA7IH0NCiNpbWFnZUNvbnRhaW5lcj4jaG92ZXJOYXZ7IGxlZnQ6IDA7fQ0KI2hvdmVyTmF2IGF7IG91dGxpbmU6IG5vbmU7fQ0KDQojcHJldkxpbmssICNuZXh0TGlua3sgd2lkdGg6IDQ5JTsgaGVpZ2h0OiAxMDAlOyBiYWNrZ3JvdW5kLWltYWdlOiB1cmwoZGF0YTppbWFnZS9naWY7YmFzZTY0LEFBQUEpOyAvKiBUcmljayBJRSBpbnRvIHNob3dpbmcgaG92ZXIgKi8gZGlzcGxheTogYmxvY2s7IH0NCiNwcmV2TGluayB7IGxlZnQ6IDA7IGZsb2F0OiBsZWZ0O30NCiNuZXh0TGluayB7IHJpZ2h0OiAwOyBmbG9hdDogcmlnaHQ7fQ0KI3ByZXZMaW5rOmhvdmVyLCAjcHJldkxpbms6dmlzaXRlZDpob3ZlciB7IGJhY2tncm91bmQ6IHVybCguLi9saWdodGJveC9pbWFnZXMvcHJldmxhYmVsLmdpZikgbGVmdCAxNSUgbm8tcmVwZWF0OyB9DQojbmV4dExpbms6aG92ZXIsICNuZXh0TGluazp2aXNpdGVkOmhvdmVyIHsgYmFja2dyb3VuZDogdXJsKC4uL2xpZ2h0Ym94L2ltYWdlcy9uZXh0bGFiZWwuZ2lmKSByaWdodCAxNSUgbm8tcmVwZWF0OyB9DQoNCiNpbWFnZURhdGFDb250YWluZXJ7IGZvbnQ6IDEwcHggVmVyZGFuYSwgSGVsdmV0aWNhLCBzYW5zLXNlcmlmOyBiYWNrZ3JvdW5kLWNvbG9yOiAjZmZmOyBtYXJnaW46IDAgYXV0bzsgbGluZS1oZWlnaHQ6IDEuNGVtOyBvdmVyZmxvdzogYXV0bzsgd2lkdGg6IDEwMCUJOyB9DQoNCiNpbWFnZURhdGF7CXBhZGRpbmc6MCAxMHB4OyBjb2xvcjogIzY2NjsgfQ0KI2ltYWdlRGF0YSAjaW1hZ2VEZXRhaWxzeyB3aWR0aDogNzAlOyBmbG9hdDogbGVmdDsgdGV4dC1hbGlnbjogbGVmdDsgfQkNCiNpbWFnZURhdGEgI2NhcHRpb257IGZvbnQtd2VpZ2h0OiBib2xkOwl9DQojaW1hZ2VEYXRhICNudW1iZXJEaXNwbGF5eyBkaXNwbGF5OiBibG9jazsgY2xlYXI6IGxlZnQ7IHBhZGRpbmctYm90dG9tOiAxLjBlbTsJfQkJCQ0KI2ltYWdlRGF0YSAjYm90dG9tTmF2Q2xvc2V7IHdpZHRoOiA2NnB4OyBmbG9hdDogcmlnaHQ7ICBwYWRkaW5nLWJvdHRvbTogMC43ZW07IG91dGxpbmU6IG5vbmU7fQkgCQ0KDQojb3ZlcmxheXsgcG9zaXRpb246IGFic29sdXRlOyB0b3A6IDA7IGxlZnQ6IDA7IHotaW5kZXg6IDkwOyB3aWR0aDogMTAwJTsgaGVpZ2h0OiA1MDBweDsgYmFja2dyb3VuZC1jb2xvcjogIzAwMDsgfQ0K</tplcss>
	<tpljs>PHNjcmlwdCB0eXBlPSJ0ZXh0L2phdmFzY3JpcHQiIHNyYz0ibW9kdWxlcy9HYWxsZXJ5L3RlbXBsYXRlcy9saWdodGJveC9qcy9wcm90b3R5cGUuanMiPjwvc2NyaXB0Pg0KPHNjcmlwdCB0eXBlPSJ0ZXh0L2phdmFzY3JpcHQiIHNyYz0ibW9kdWxlcy9HYWxsZXJ5L3RlbXBsYXRlcy9saWdodGJveC9qcy9zY3JpcHRhY3Vsb3VzLmpzP2xvYWQ9ZWZmZWN0cyxidWlsZGVyIj48L3NjcmlwdD4NCjxzY3JpcHQgdHlwZT0idGV4dC9qYXZhc2NyaXB0IiBzcmM9Im1vZHVsZXMvR2FsbGVyeS90ZW1wbGF0ZXMvbGlnaHRib3gvanMvbGlnaHRib3guanMiPjwvc2NyaXB0Pg0K</tpljs>
	<file>
	  <filename>/css/</filename>
	  <isdir>1</isdir>
	</file>
	<file>
	  <filename>/css/lightbox.css</filename>
	  <isdir>0</isdir>
	  <data><![CDATA[I2xpZ2h0Ym94ewlwb3NpdGlvbjogYWJzb2x1dGU7CWxlZnQ6IDA7IHdpZHRoOiAxMDAlOyB6LWluZGV4OiAxMDA7IHRleHQtYWxpZ246IGNlbnRlcjsgbGluZS1oZWlnaHQ6IDA7fQojbGlnaHRib3ggaW1neyB3aWR0aDogYXV0bzsgaGVpZ2h0OiBhdXRvO30KI2xpZ2h0Ym94IGEgaW1neyBib3JkZXI6IG5vbmU7IH0KCiNvdXRlckltYWdlQ29udGFpbmVyeyBwb3NpdGlvbjogcmVsYXRpdmU7IGJhY2tncm91bmQtY29sb3I6ICNmZmY7IHdpZHRoOiAyNTBweDsgaGVpZ2h0OiAyNTBweDsgbWFyZ2luOiAwIGF1dG87IH0KI2ltYWdlQ29udGFpbmVyeyBwYWRkaW5nOiAxMHB4OyB9CgojbG9hZGluZ3sgcG9zaXRpb246IGFic29sdXRlOyB0b3A6IDQwJTsgbGVmdDogMCU7IGhlaWdodDogMjUlOyB3aWR0aDogMTAwJTsgdGV4dC1hbGlnbjogY2VudGVyOyBsaW5lLWhlaWdodDogMDsgfQojaG92ZXJOYXZ7IHBvc2l0aW9uOiBhYnNvbHV0ZTsgdG9wOiAwOyBsZWZ0OiAwOyBoZWlnaHQ6IDEwMCU7IHdpZHRoOiAxMDAlOyB6LWluZGV4OiAxMDsgfQojaW1hZ2VDb250YWluZXI+I2hvdmVyTmF2eyBsZWZ0OiAwO30KI2hvdmVyTmF2IGF7IG91dGxpbmU6IG5vbmU7fQoKI3ByZXZMaW5rLCAjbmV4dExpbmt7IHdpZHRoOiA0OSU7IGhlaWdodDogMTAwJTsgYmFja2dyb3VuZC1pbWFnZTogdXJsKGRhdGE6aW1hZ2UvZ2lmO2Jhc2U2NCxBQUFBKTsgLyogVHJpY2sgSUUgaW50byBzaG93aW5nIGhvdmVyICovIGRpc3BsYXk6IGJsb2NrOyB9CiNwcmV2TGluayB7IGxlZnQ6IDA7IGZsb2F0OiBsZWZ0O30KI25leHRMaW5rIHsgcmlnaHQ6IDA7IGZsb2F0OiByaWdodDt9CiNwcmV2TGluazpob3ZlciwgI3ByZXZMaW5rOnZpc2l0ZWQ6aG92ZXIgeyBiYWNrZ3JvdW5kOiB1cmwoLi4vaW1hZ2VzL3ByZXZsYWJlbC5naWYpIGxlZnQgMTUlIG5vLXJlcGVhdDsgfQojbmV4dExpbms6aG92ZXIsICNuZXh0TGluazp2aXNpdGVkOmhvdmVyIHsgYmFja2dyb3VuZDogdXJsKC4uL2ltYWdlcy9uZXh0bGFiZWwuZ2lmKSByaWdodCAxNSUgbm8tcmVwZWF0OyB9CgojaW1hZ2VEYXRhQ29udGFpbmVyeyBmb250OiAxMHB4IFZlcmRhbmEsIEhlbHZldGljYSwgc2Fucy1zZXJpZjsgYmFja2dyb3VuZC1jb2xvcjogI2ZmZjsgbWFyZ2luOiAwIGF1dG87IGxpbmUtaGVpZ2h0OiAxLjRlbTsgb3ZlcmZsb3c6IGF1dG87IHdpZHRoOiAxMDAlCTsgfQoKI2ltYWdlRGF0YXsJcGFkZGluZzowIDEwcHg7IGNvbG9yOiAjNjY2OyB9CiNpbWFnZURhdGEgI2ltYWdlRGV0YWlsc3sgd2lkdGg6IDcwJTsgZmxvYXQ6IGxlZnQ7IHRleHQtYWxpZ246IGxlZnQ7IH0JCiNpbWFnZURhdGEgI2NhcHRpb257IGZvbnQtd2VpZ2h0OiBib2xkOwl9CiNpbWFnZURhdGEgI251bWJlckRpc3BsYXl7IGRpc3BsYXk6IGJsb2NrOyBjbGVhcjogbGVmdDsgcGFkZGluZy1ib3R0b206IDEuMGVtOwl9CQkJCiNpbWFnZURhdGEgI2JvdHRvbU5hdkNsb3NleyB3aWR0aDogNjZweDsgZmxvYXQ6IHJpZ2h0OyAgcGFkZGluZy1ib3R0b206IDAuN2VtOyBvdXRsaW5lOiBub25lO30JIAkKCiNvdmVybGF5eyBwb3NpdGlvbjogYWJzb2x1dGU7IHRvcDogMDsgbGVmdDogMDsgei1pbmRleDogOTA7IHdpZHRoOiAxMDAlOyBoZWlnaHQ6IDUwMHB4OyBiYWNrZ3JvdW5kLWNvbG9yOiAjMDAwOyB9Cg==]]></data>
	</file>
	<file>
	  <filename>/images/</filename>
	  <isdir>1</isdir>
	</file>
	<file>
	  <filename>/images/prevlabel.gif</filename>
	  <isdir>0</isdir>
	  <data><![CDATA[R0lGODlhPwAgAPeJANzc3P39/fb29rq6utra2v7+/ltbW8HBwfX19fz8/F5eXk1NTV9fX/r6+uDg4NXV1djY2ICAgGBgYFFRUVRUVEpKSt3d3eLi4tnZ2cDAwOPj4/n5+cLCwsPDw/Dw8PLy8ru7u6CgoN/f34ODg0JCQktLS11dXVpaWnJycmpqar6+vpCQkJSUlMzMzPj4+KSkpFJSUmVlZcbGxsTExGxsbIGBgba2tuXl5WNjY3BwcHZ2dmZmZufn5+vr687OztfX18rKysnJyejo6FxcXFBQUKGhoY2NjZubm3h4eHt7e5iYmN7e3tPT00BAQLi4uEdHR39/f3p6evPz89bW1qenp+bm5k9PT3d3d2RkZEhISHl5eby8vPT09HR0dG9vb62traOjo/v7+66urr+/v25ubmFhYWlpadTU1I6OjrW1tb29vaKiourq6p2dnbm5uVVVVZqamqampvHx8ff396qqqtDQ0IyMjMjIyKioqKurq2JiYoaGhklJSVhYWLOzs+Hh4UFBQXFxcc/Pz8vLy3Nzc+/v71dXV+7u7v///zMzMwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAIkALAAAAAA/ACAAAAj/ABEJHEiwoMGDCBMqNJgo0cKHECM+dCixosWLGDNq3Mixo8ePIEOKHEmypMmTKFNubOBjTAYOU1wIJJAhg4oWQgR+6HCg5wEOPAbJKDBwQ5A7IhHUmMCgaRIHiIrAUKCgTIw8iCwYMGTgxAkFddBMADCQgAkjIgVA8SLgQ5oSdhKsMQBgg4UcfX5osLJCBIS/BQ4sCDEQTwUfaSMQSoCowAkdUl4ouCEwDhEOVRZQKeghBQ0EiBBcCUQ0pIAIOTwgsJHFSAAwBrZgUINDgoMLFEaocOOkA2M4FIAgYlIBxEgBI4iYGCIBCQZEL2DEGEIBxQxEAAyYMLMDx4gGiDAszVCCSIkEHsdr7Ogw48ccgUUMAPlSYoBAABNYaBCx5ELpJGQ4gAULjCXWhUEhMNBDAjro8QF2C9BxkAwL7CGBICSdhgJ4BIWgwAWIgFBCG1lNsMIDKJ5xiECF0FBBFAFkqEUKHA50xBsiIMIFEnwE8QcFT5AgZBN+CFTAEYCIUVIAGjhQ2kBsACATIj08IMQGABCgpZYeDCQHBKCpJOZFNxAAwJlonhnjmA+1YMMAcMY5AAhhsPlQAQHkqaeedvbp55+ABiqonxQNulBDAQEAOw==]]></data>
	</file>
	<file>
	  <filename>/images/nextlabel.gif</filename>
	  <isdir>0</isdir>
	  <data><![CDATA[R0lGODlhPwAgAPeDAP39/enp6UdHR6mpqY+Pj+bm5tDQ0MLCwuzs7O/v76qqqvHx8fb29vr6+v7+/lxcXPf39+3t7WdnZ2VlZV9fX0lJSc3Nze7u7ltbW/v7+7y8vKampurq6qenp3BwcPDw8FpaWoCAgLGxsWNjY2BgYPn5+ejo6ExMTFRUVE5OTqOjo9LS0mJiYufn52hoaI6OjldXV2FhYVFRUaioqNXV1d/f38HBwfz8/Pj4+JGRkbS0tF1dXd7e3oODg3p6eoGBgfLy8mZmZoKCgs/Pz1JSUllZWaurq4WFhW1tbWRkZOLi4srKylZWVqSkpLW1tbKysre3t0VFRV5eXqKiovPz88vLy8bGxmtra3V1dcjIyJqamlVVVXh4eIiIiEhISHd3d9jY2I2Njbq6upmZmeDg4G5ubktLS9bW1tzc3FNTU6WlpWpqap2dnU9PT66urr6+voyMjE1NTYaGhuTk5OHh4dfX16ysrOvr68PDw0JCQlhYWH5+fnNzc3l5eZubm+Pj42xsbPT09P///zMzMwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAIMALAAAAAA/ACAAAAj/AAcNEkSwoMGDCBMqXMgQ4cCGECNKnEixosWLGDNq3Mixo8ePIEOKHEmypMmTKEECsDLDQsEbNkQICuREwYCbHZTQaOKSIAIFeOaoGGDEjYIOOiB4BECgQgweBBvseSDIBAsUE0aM2GGhxRUMZAQ5IHCiigEYIzAQIUHiy4KlOVCkOIJDUIMQUgQFeNAjggkTLZQuiQPHQZYUWhyUKMCBTYUVHDgAWErARZg2OgRl+EFBL4gXCcekeeKhTAKDRgQECMl0TQEuRf4I4qw3BhIFalTYYUAQQh8ZIFYcHCCgAGsCEnDU2SIHgpDOAZJg4OMBSYi3ggD08LKjxvDixyUAwXEw5YSCLiT0PjiSIAICBJMFiSCygYUPIAaJG1eJ/IMgBoA8MEEQnuWAEA96hCAIFBV0kB94/EngnyBDMCGDC3pRgIUGHIpBRwlCwICGXT6gAEZB+rH2wgQTCuJHBQQGMMEJAtSYxwYimLFBQTQU4QF2M0SxH0hUJBCfZgicBkB7FzQZAQML3HGkIAsEkAFBDCBwQ0pcVtTAEAaEKaYBFnjXJUQl2HDAmmwe8MYZZ8Yp55x01mnnnQo9hCdEAu0JUUAAOw==]]></data>
	</file>
	<file>
	  <filename>/images/loading.gif</filename>
	  <isdir>0</isdir>
	  <data><![CDATA[R0lGODlhIAAgAPcAAP///7Ozs/v7+9bW1uHh4fLy8rq6uoGBgTQ0NAEBARsbG8TExJeXl/39/VRUVAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH/C05FVFNDQVBFMi4wAwEAAAAh+QQFCgAAACwAAAAAIAAgAAAI+gABCBxIkOCCAwsKKlzIcOCBhwUJFGiocICBgg8PEBzAkSLBAg8DEMw4sADHAR5HPkQpkKTAkwRSDjTwkIFDiAAInJRJkMHDiwBcwuQ5cMABnxMfOsi5c6DOATFfMmCQcGCAnwp1ljwJdeCCqVNZGq3akGvHnmCnRvVodu3GtDZTPnW78CsDlnJ5EgBKtC9RsxxNLjBAuHBfwBwLK+Yr8+QCmAMGL/ZLWSZdipcZzvW4OaXZiQpNcuUJuGBpzHifclyruuvLy6oJdmbq+uVqAE1PgiYqWuzZ2Idv4z47vLbcpsWdIvcsPHlR4szxOneamWEBussrZzVOMSAAIfkEBQoAAAAsAAAAABgAEgAACIAAAQgcSLAggAEGEypkAIAhQQMLFEZUOJDBgQMJGWgs6FDggosYDWrsmBCkgYQLNhLsaAAkxYYMJhIkAFJmxoYEBFps6FIgAQMGEFZUWbBlToEDgAI9SoCB0JdIlUIsADXhT6lVFSY9mVVhgaddw3odQLYs2KpmzYolUHZBWbEBAQAh+QQFCgAAACwBAAAAHQAOAAAIiQABCBxIcOAABgUTKlwoEGHCAQwHEoBIkIFFggEiEjRggGJDAA4BUAzJkKMBAgMthiSpcYDJlApZMlzAceTFAiBFFsSpkIBJnAgRGvg40MCBA0MHDEA5kGYAj00JLjh69KRSpTwLDI14kOpRg1cJMNXo9QBUkVfPLjR6IGNPpWM1MoibUKxGjQEBACH5BAUKAAAALAcAAAAZABEAAAiBAAEIHAiAgAGCCBMqBLDAwAKEDxcWIIDQgEWCDDIuHDCg4sWBGjdyLDDQ4kGQDCImJMCxo0CTAheEXAigJUUAMAkwALCTpkCbOD/OROjyJ8ebBAf0rLk04QCkCpHuDOCTZs+mVSHGzOrTAEmuYMMmPEC27AGVYM2aFQuArAOzCwICACH5BAUKAAAALA4AAAASABgAAAiCAAEsIACgoMGDCAcsQAhgAEGGAhcsNLjAgAGIEScCIGDxIkSJGjsOwAiy4ICOGDMCKNDx4UeJDQMY0CiQAYOUBgoctMmAJkabAICmDBr05tCdRo8edKm0adOkKW9KdXrAIIORTpsaYHrUwIEDAah+/eoT4gAGYw9AxZnWo9IAZAEEBAAh+QQFCgAAACwOAAAAEgAeAAAImQABDCgAoKDBgwgFDkjIsOCAhwcHLFjQ8OFCgxMvJrRoUCLFihALTvzIkCOAkQ0dhswY0YABAgwJaCTg0qXGhgtqGiDZUOfLlB1tAkU4cKhRowySKhUIlAEAp1Cdplya9KjVgwStfjRw1SCDmw0JBDg4lqGBAzAFVm3I4IDbgwacggVAwO0BnkDPvrVql+vRAXav2s161CXDgAAh+QQFCgAAACwPAAEAEQAfAAAIjAABCBwIgEABgggTDhiQsGGBhQ0jLiQQkSCBhQwrCrwIUePGjgM5ehSIcQDFihwxaiyZUSPHkyMJwBxJE6GBmzgXaMTJ00DFngZ01hxKcwADBkI9Hj1ac+nShjpbCjyaVKBPpgN1MhB4oCuAgyQjdj1AEGvCsQO3VkRLk+1UtWcPOFDY0K3HBQeqagwIACH5BAUKAAAALAgADgAYABIAAAh9AAEIHEiwIIABCBMOKGCw4UCFCh06TLggIQGJGDNiHKAxowEDHDsa/EjyosiBBRaQNLBA5AAGJgmsDHnwgIGGDAwO+GgSAIMDB3ISJMCgKMYFQA+YFApgAVOHSW86LNpyZFKCT30aNZi0KsasAq9iPVDQa1mpA3OCPUmzY0AAIfkEBQoAAAAsAgASAB0ADgAACIkAAQgcSLCgQQAEDhIkwEChQQIDBiQ8aODAAQMOCUbcWECjxY8ZNW6MKJDBxwMMBmQkgHHgSJYnWyZcYHCAAQM0B0JUWfFAAII/AWBkQBRAgZsGJj4sqBJAQ6dQAdi8GXLgU4JFBS642bRqVKhXWVINWbQr0asAtrasihatS6UOu2IN6pXt2owBAQAh+QQFCgAAACwAAA8AGQARAAAIgAAXHBhI8ACAgwgTKjxYsODChwkFEnQwEKLFixgxFjCQseOCjg8ZgIQYIGEAAhgHQGTAQOXBlgsJDJiZ0CVHhCxFAjDAE4DMmQUSBlXIEiHPmz9dWmT5cWfPgzMHoHy4oKjRp1BpLk14tKbWhVav3kQ4FWJThAsMnB2p0EDZhAEBACH5BAUKAAAALAEACAARABgAAAh3AAccOGAAgMGDCA8aGDhwQcKHABgOZDAAIsIFEg9YTBhgYMGNHEGKHEmypMmTKDcuYMCgJEuWIF++BLmyJcICHx+ydHhwgQEDFQcINUggIYGfBgoAEFoRItKmTCEOQHow6kOkRQ1aTfizqdahDwl4/ToWpFgAAQEAIfkEBQoAAAAsAAACAA4AHQAACIoAAQgcCGCBAYIIBx44wCAhwoUHBjgcGADiRIULD15cYJFgQ4IQP3qUCIDAgQAEUYokMHHAR5ETFwiUeRFAAY01WzLYyROmwJ49E7rcCYBnzqMISV4cYMCAUoQEmkp1aFDqggJCrQ4kMACrwKhOCQ4Yy1Kg14EFxg4o61At24Rcx9ZUm1NuzgJvAwIAOw==]]></data>
	</file>
	<file>
	  <filename>/images/bullet.gif</filename>
	  <isdir>0</isdir>
	  <data><![CDATA[R0lGODlhBgAGAIAAADs7O1paWiH5BAAAAAAALAAAAAAGAAYAAAIIRB6Gy816QAEAOw==]]></data>
	</file>
	<file>
	  <filename>/images/closelabel.gif</filename>
	  <isdir>0</isdir>
	  <data><![CDATA[R0lGODlhQgAWAOYAAMDAwMHBwZ2dnVlZWdLS0oODg6+vr/X19eTk5FBQULi4uIyMjJSUlFRUVFZWVtzc3FJSUsnJyVFRUVhYWFVVVezs7FNTU/b29v39/erq6vr6+qampldXV6KiokxMTE9PT2ZmZvf3993d3czMzGBgYHt7e6Ghofz8/PDw8N7e3mxsbLW1tfv7+5WVlc3NzcrKynh4eOvr60tLS+Dg4F9fX7m5ud/f37S0tIaGhnBwcGNjY+Xl5ZKSkoiIiKmpqW5ubpeXl29vb9XV1Y6Oju3t7WVlZXZ2dpiYmG1tbXx8fO/v7+fn57GxsbOzs/Hx8Xl5eVpaWmRkZE1NTXNzc2dnZ5aWloeHh+Pj405OTmlpadvb23p6ev////7+/gAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAAAAAAALAAAAABCABYAAAf/gFyCg4SFhoeIiYqLjI2Oj4xdkpOUlZaXl5BcJ42Ynp+YkZJcLEdCXJZcIwIaqKCvoKJdIUAeUSKuXYIuNB5VF5QVWgiwXQjDlwdaWrqLo00yAxZFWq6qJA0DHj6SBAtb4AsEXQBbzJUABeBbBQCUCusFL1wB6+uDoxlbHwMJVDaCRtCwMAALDhRdImxZEEFLhAIGyJmrZGALAwJaCDDYElGigYwbLtDjGKBkAHz5SiQY0EDFDBfYBkixEgJVgQIHJuWUeE4Sgi0CKgmYOJSSoHoPDhmtUIIfBSTYJiToIbKLli3uLJXrybPSVQVdKirYeXRLUkOVuMRIAmGAAw4D/yAMqSlp6yW7k4paAtqlgrotGxCUbSGgsAKURlEYoTBgQoMOrSbhRTcx75ZLfLscAPDN7EjChhFP4qIkCGOWDHRNIoD1bmVJ8MZRYp1VMseRZwulnTElGwUHcU1gcHXg5k5jOSdbzWyZmOZJQHErHZ1ChQRpWUA4mAChw3BJChk6LLBgM0cA6JlVvJhxI9iw7DdsOVnPgMkARARRB3E9AYwrLziwnQTCueJNPOOUY09W6ayzQG0NgnPYSPZ4Zo0IIEAARQIlZCBIDQJOIEEHJ1ByjHOvnHjJMjlFwsUDOqzkXwyoCLKCBBxwIMMNxfSYijNcOMEABB9s4aFRK1iQQDAOIvjo5CjO6MICD09UkAuUTPyww5VPwiILFxpUdQkGS3DZ5SuyNOOJfmf6mGaPgQAAOw==]]></data>
	</file>
	<file>
	  <filename>/images/download-icon.gif</filename>
	  <isdir>0</isdir>
	  <data><![CDATA[R0lGODlhFgAWAPfFAGtra1NTU1JSUmtra46Ojo+Pj8nJyZCQkLi4uLS0tJGRkZOTk4yMjFNTU5SUlI+Pj6GhoYSEhD4+PouLi8LCwoSEhMbGxpmZmVJSUpGRkYWFhZOTk8TExK+vr5+fn66urpiYmFNTU4+Pj5GRkUpKSqGhoYyMjHZ2dr29vZCQkKurq6SkpIODg7q6uqCgoIWFhWlpacjIyI2NjZCQkJCQkLCwsLCwsGpqaomJiampqYqKisPDw2tra4mJiZ6enszMzGhoaKurq46OjqysrKWlpaysrJqamqmpqaioqLm5uZmZmZycnJubm6CgoI6Ojo2NjZKSkpSUlL+/v66urr29vZKSkq+vr8rKyqenp5aWlre3t7q6upaWlqenp7i4uIuLi3Z2dr6+vpGRkYyMjJKSkpGRkampqaSkpIeHh6ampp6enru7u5OTk7+/v7a2tr6+vpKSkoyMjIaGhlFRUbW1tZKSkvn5+aioqLi4uJOTk5CQkImJiYeHh8HBwaysrJKSkp2dnaOjo7a2tn19fZqamqGhoZqamo6OjoiIiJeXl5SUlIaGhoqKik9PT5GRkaGhoYeHh46Ojvz8/IuLi5+fn7Ozs5CQkIiIiIGBgaCgoMXFxaqqqoyMjG5uboaGhomJiaqqqqGhoZiYmKOjo5aWlnp6epGRkbGxsby8vGtra2lpaXd3d8fHx5SUlImJiaKiora2tqenp6SkpJWVlcrKyrS0tKurq3R0dI2NjZ2dnaampqenp5mZmVJSUmtra8LCwmtra97e3mxsbFJSUv///wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAMUALAAAAAAWABYAAAj/AIsJHEiwoMFijYQpXKgQmMOHEB2SABbjhx9btkCZuXNnly4ismSNehUq1BstDmmNisgyYq41woCxCvWrps2bOH8ZwhNTUyZiQIMKHUqMF6yYO9QAtROsqdOnQUXVitknF9GrQUmditmGCVass6zEpGIIqKSnaIMFzeMn5hZeX6/+MRMTT6K4RE3tigmLVKu/ef78MUXYkmERIiJFEiFLYaVWeVYNm0y5MhhcuDhFCqXQRh5Tw0JZqYWHyi8LtDhMGcZp0iROlBRO+WNpGJ0klA38QgXLyjBXjBhNWqLQliURw9pwoLyl1pRdoX67uuTKkEJQiYcZsEDZjy5KvPIMXPN0CRIkUgp3ReI07A0eympEmZr0YtgLT/dbCVNlKhN7G2ZQZokrLAwCxjAVJFiBKcJIoAoulAyTSXiRQIJJKbd0AkwIlghmCifCFCMBEBuGYOKJlYVwg0MKzREQADs=]]></data>
	</file>
	<file>
	  <filename>/images/close.gif</filename>
	  <isdir>0</isdir>
	  <data><![CDATA[R0lGODlhGgAaALMJAHt7e8jIyJycnPT09JiYmL29vWVlZd7e3lpaWv///wAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAkALAAAAAAaABoAAASLMEl5pr0YH1PzDZxmIEjnJQUZThtJmljqrsnovpl8r8HtwigfbqKbmYq/mDCEHCp9AIKwdApOd8DcVZX1NEmA7kmwHFQxA5tPcLYcANtCO9HaIuTV+k6IzxymAgNwPn1uU3h6LoV0h25qiiyNF39CAXSPJIuRPgYUj5qGRiw2oJNckwaWcxticywWEQA7]]></data>
	</file>
	<file>
	  <filename>/js/</filename>
	  <isdir>1</isdir>
	</file>
	<file>
	  <filename>/js/effects.js</filename>
	  <isdir>0</isdir>
	  <data><![CDATA[Ly8gc2NyaXB0LmFjdWxvLnVzIGVmZmVjdHMuanMgdjEuOS4wLCBUaHUgRGVjIDIzIDE2OjU0OjQ4IC0wNTAwIDIwMTAKCi8vIENvcHlyaWdodCAoYykgMjAwNS0yMDEwIFRob21hcyBGdWNocyAoaHR0cDovL3NjcmlwdC5hY3Vsby51cywgaHR0cDovL21pci5hY3Vsby51cykKLy8gQ29udHJpYnV0b3JzOgovLyAgSnVzdGluIFBhbG1lciAoaHR0cDovL2VuY3l0ZW1lZGlhLmNvbS8pCi8vICBNYXJrIFBpbGdyaW0gKGh0dHA6Ly9kaXZlaW50b21hcmsub3JnLykKLy8gIE1hcnRpbiBCaWFsYXNpbmtpCi8vCi8vIHNjcmlwdC5hY3Vsby51cyBpcyBmcmVlbHkgZGlzdHJpYnV0YWJsZSB1bmRlciB0aGUgdGVybXMgb2YgYW4gTUlULXN0eWxlIGxpY2Vuc2UuCi8vIEZvciBkZXRhaWxzLCBzZWUgdGhlIHNjcmlwdC5hY3Vsby51cyB3ZWIgc2l0ZTogaHR0cDovL3NjcmlwdC5hY3Vsby51cy8KCi8vIGNvbnZlcnRzIHJnYigpIGFuZCAjeHh4IHRvICN4eHh4eHggZm9ybWF0LAovLyByZXR1cm5zIHNlbGYgKG9yIGZpcnN0IGFyZ3VtZW50KSBpZiBub3QgY29udmVydGFibGUKU3RyaW5nLnByb3RvdHlwZS5wYXJzZUNvbG9yID0gZnVuY3Rpb24oKSB7CiAgdmFyIGNvbG9yID0gJyMnOwogIGlmICh0aGlzLnNsaWNlKDAsNCkgPT0gJ3JnYignKSB7CiAgICB2YXIgY29scyA9IHRoaXMuc2xpY2UoNCx0aGlzLmxlbmd0aC0xKS5zcGxpdCgnLCcpOwogICAgdmFyIGk9MDsgZG8geyBjb2xvciArPSBwYXJzZUludChjb2xzW2ldKS50b0NvbG9yUGFydCgpIH0gd2hpbGUgKCsraTwzKTsKICB9IGVsc2UgewogICAgaWYgKHRoaXMuc2xpY2UoMCwxKSA9PSAnIycpIHsKICAgICAgaWYgKHRoaXMubGVuZ3RoPT00KSBmb3IodmFyIGk9MTtpPDQ7aSsrKSBjb2xvciArPSAodGhpcy5jaGFyQXQoaSkgKyB0aGlzLmNoYXJBdChpKSkudG9Mb3dlckNhc2UoKTsKICAgICAgaWYgKHRoaXMubGVuZ3RoPT03KSBjb2xvciA9IHRoaXMudG9Mb3dlckNhc2UoKTsKICAgIH0KICB9CiAgcmV0dXJuIChjb2xvci5sZW5ndGg9PTcgPyBjb2xvciA6IChhcmd1bWVudHNbMF0gfHwgdGhpcykpOwp9OwoKLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovCgpFbGVtZW50LmNvbGxlY3RUZXh0Tm9kZXMgPSBmdW5jdGlvbihlbGVtZW50KSB7CiAgcmV0dXJuICRBKCQoZWxlbWVudCkuY2hpbGROb2RlcykuY29sbGVjdCggZnVuY3Rpb24obm9kZSkgewogICAgcmV0dXJuIChub2RlLm5vZGVUeXBlPT0zID8gbm9kZS5ub2RlVmFsdWUgOgogICAgICAobm9kZS5oYXNDaGlsZE5vZGVzKCkgPyBFbGVtZW50LmNvbGxlY3RUZXh0Tm9kZXMobm9kZSkgOiAnJykpOwogIH0pLmZsYXR0ZW4oKS5qb2luKCcnKTsKfTsKCkVsZW1lbnQuY29sbGVjdFRleHROb2Rlc0lnbm9yZUNsYXNzID0gZnVuY3Rpb24oZWxlbWVudCwgY2xhc3NOYW1lKSB7CiAgcmV0dXJuICRBKCQoZWxlbWVudCkuY2hpbGROb2RlcykuY29sbGVjdCggZnVuY3Rpb24obm9kZSkgewogICAgcmV0dXJuIChub2RlLm5vZGVUeXBlPT0zID8gbm9kZS5ub2RlVmFsdWUgOgogICAgICAoKG5vZGUuaGFzQ2hpbGROb2RlcygpICYmICFFbGVtZW50Lmhhc0NsYXNzTmFtZShub2RlLGNsYXNzTmFtZSkpID8KICAgICAgICBFbGVtZW50LmNvbGxlY3RUZXh0Tm9kZXNJZ25vcmVDbGFzcyhub2RlLCBjbGFzc05hbWUpIDogJycpKTsKICB9KS5mbGF0dGVuKCkuam9pbignJyk7Cn07CgpFbGVtZW50LnNldENvbnRlbnRab29tID0gZnVuY3Rpb24oZWxlbWVudCwgcGVyY2VudCkgewogIGVsZW1lbnQgPSAkKGVsZW1lbnQpOwogIGVsZW1lbnQuc2V0U3R5bGUoe2ZvbnRTaXplOiAocGVyY2VudC8xMDApICsgJ2VtJ30pOwogIGlmIChQcm90b3R5cGUuQnJvd3Nlci5XZWJLaXQpIHdpbmRvdy5zY3JvbGxCeSgwLDApOwogIHJldHVybiBlbGVtZW50Owp9OwoKRWxlbWVudC5nZXRJbmxpbmVPcGFjaXR5ID0gZnVuY3Rpb24oZWxlbWVudCl7CiAgcmV0dXJuICQoZWxlbWVudCkuc3R5bGUub3BhY2l0eSB8fCAnJzsKfTsKCkVsZW1lbnQuZm9yY2VSZXJlbmRlcmluZyA9IGZ1bmN0aW9uKGVsZW1lbnQpIHsKICB0cnkgewogICAgZWxlbWVudCA9ICQoZWxlbWVudCk7CiAgICB2YXIgbiA9IGRvY3VtZW50LmNyZWF0ZVRleHROb2RlKCcgJyk7CiAgICBlbGVtZW50LmFwcGVuZENoaWxkKG4pOwogICAgZWxlbWVudC5yZW1vdmVDaGlsZChuKTsKICB9IGNhdGNoKGUpIHsgfQp9OwoKLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovCgp2YXIgRWZmZWN0ID0gewogIF9lbGVtZW50RG9lc05vdEV4aXN0RXJyb3I6IHsKICAgIG5hbWU6ICdFbGVtZW50RG9lc05vdEV4aXN0RXJyb3InLAogICAgbWVzc2FnZTogJ1RoZSBzcGVjaWZpZWQgRE9NIGVsZW1lbnQgZG9lcyBub3QgZXhpc3QsIGJ1dCBpcyByZXF1aXJlZCBmb3IgdGhpcyBlZmZlY3QgdG8gb3BlcmF0ZScKICB9LAogIFRyYW5zaXRpb25zOiB7CiAgICBsaW5lYXI6IFByb3RvdHlwZS5LLAogICAgc2lub2lkYWw6IGZ1bmN0aW9uKHBvcykgewogICAgICByZXR1cm4gKC1NYXRoLmNvcyhwb3MqTWF0aC5QSSkvMikgKyAuNTsKICAgIH0sCiAgICByZXZlcnNlOiBmdW5jdGlvbihwb3MpIHsKICAgICAgcmV0dXJuIDEtcG9zOwogICAgfSwKICAgIGZsaWNrZXI6IGZ1bmN0aW9uKHBvcykgewogICAgICB2YXIgcG9zID0gKCgtTWF0aC5jb3MocG9zKk1hdGguUEkpLzQpICsgLjc1KSArIE1hdGgucmFuZG9tKCkvNDsKICAgICAgcmV0dXJuIHBvcyA+IDEgPyAxIDogcG9zOwogICAgfSwKICAgIHdvYmJsZTogZnVuY3Rpb24ocG9zKSB7CiAgICAgIHJldHVybiAoLU1hdGguY29zKHBvcypNYXRoLlBJKig5KnBvcykpLzIpICsgLjU7CiAgICB9LAogICAgcHVsc2U6IGZ1bmN0aW9uKHBvcywgcHVsc2VzKSB7CiAgICAgIHJldHVybiAoLU1hdGguY29zKChwb3MqKChwdWxzZXN8fDUpLS41KSoyKSpNYXRoLlBJKS8yKSArIC41OwogICAgfSwKICAgIHNwcmluZzogZnVuY3Rpb24ocG9zKSB7CiAgICAgIHJldHVybiAxIC0gKE1hdGguY29zKHBvcyAqIDQuNSAqIE1hdGguUEkpICogTWF0aC5leHAoLXBvcyAqIDYpKTsKICAgIH0sCiAgICBub25lOiBmdW5jdGlvbihwb3MpIHsKICAgICAgcmV0dXJuIDA7CiAgICB9LAogICAgZnVsbDogZnVuY3Rpb24ocG9zKSB7CiAgICAgIHJldHVybiAxOwogICAgfQogIH0sCiAgRGVmYXVsdE9wdGlvbnM6IHsKICAgIGR1cmF0aW9uOiAgIDEuMCwgICAvLyBzZWNvbmRzCiAgICBmcHM6ICAgICAgICAxMDAsICAgLy8gMTAwPSBhc3N1bWUgNjZmcHMgbWF4LgogICAgc3luYzogICAgICAgZmFsc2UsIC8vIHRydWUgZm9yIGNvbWJpbmluZwogICAgZnJvbTogICAgICAgMC4wLAogICAgdG86ICAgICAgICAgMS4wLAogICAgZGVsYXk6ICAgICAgMC4wLAogICAgcXVldWU6ICAgICAgJ3BhcmFsbGVsJwogIH0sCiAgdGFnaWZ5VGV4dDogZnVuY3Rpb24oZWxlbWVudCkgewogICAgdmFyIHRhZ2lmeVN0eWxlID0gJ3Bvc2l0aW9uOnJlbGF0aXZlJzsKICAgIGlmIChQcm90b3R5cGUuQnJvd3Nlci5JRSkgdGFnaWZ5U3R5bGUgKz0gJzt6b29tOjEnOwoKICAgIGVsZW1lbnQgPSAkKGVsZW1lbnQpOwogICAgJEEoZWxlbWVudC5jaGlsZE5vZGVzKS5lYWNoKCBmdW5jdGlvbihjaGlsZCkgewogICAgICBpZiAoY2hpbGQubm9kZVR5cGU9PTMpIHsKICAgICAgICBjaGlsZC5ub2RlVmFsdWUudG9BcnJheSgpLmVhY2goIGZ1bmN0aW9uKGNoYXJhY3RlcikgewogICAgICAgICAgZWxlbWVudC5pbnNlcnRCZWZvcmUoCiAgICAgICAgICAgIG5ldyBFbGVtZW50KCdzcGFuJywge3N0eWxlOiB0YWdpZnlTdHlsZX0pLnVwZGF0ZSgKICAgICAgICAgICAgICBjaGFyYWN0ZXIgPT0gJyAnID8gU3RyaW5nLmZyb21DaGFyQ29kZSgxNjApIDogY2hhcmFjdGVyKSwKICAgICAgICAgICAgICBjaGlsZCk7CiAgICAgICAgfSk7CiAgICAgICAgRWxlbWVudC5yZW1vdmUoY2hpbGQpOwogICAgICB9CiAgICB9KTsKICB9LAogIG11bHRpcGxlOiBmdW5jdGlvbihlbGVtZW50LCBlZmZlY3QpIHsKICAgIHZhciBlbGVtZW50czsKICAgIGlmICgoKHR5cGVvZiBlbGVtZW50ID09ICdvYmplY3QnKSB8fAogICAgICAgIE9iamVjdC5pc0Z1bmN0aW9uKGVsZW1lbnQpKSAmJgogICAgICAgKGVsZW1lbnQubGVuZ3RoKSkKICAgICAgZWxlbWVudHMgPSBlbGVtZW50OwogICAgZWxzZQogICAgICBlbGVtZW50cyA9ICQoZWxlbWVudCkuY2hpbGROb2RlczsKCiAgICB2YXIgb3B0aW9ucyA9IE9iamVjdC5leHRlbmQoewogICAgICBzcGVlZDogMC4xLAogICAgICBkZWxheTogMC4wCiAgICB9LCBhcmd1bWVudHNbMl0gfHwgeyB9KTsKICAgIHZhciBtYXN0ZXJEZWxheSA9IG9wdGlvbnMuZGVsYXk7CgogICAgJEEoZWxlbWVudHMpLmVhY2goIGZ1bmN0aW9uKGVsZW1lbnQsIGluZGV4KSB7CiAgICAgIG5ldyBlZmZlY3QoZWxlbWVudCwgT2JqZWN0LmV4dGVuZChvcHRpb25zLCB7IGRlbGF5OiBpbmRleCAqIG9wdGlvbnMuc3BlZWQgKyBtYXN0ZXJEZWxheSB9KSk7CiAgICB9KTsKICB9LAogIFBBSVJTOiB7CiAgICAnc2xpZGUnOiAgWydTbGlkZURvd24nLCdTbGlkZVVwJ10sCiAgICAnYmxpbmQnOiAgWydCbGluZERvd24nLCdCbGluZFVwJ10sCiAgICAnYXBwZWFyJzogWydBcHBlYXInLCdGYWRlJ10KICB9LAogIHRvZ2dsZTogZnVuY3Rpb24oZWxlbWVudCwgZWZmZWN0LCBvcHRpb25zKSB7CiAgICBlbGVtZW50ID0gJChlbGVtZW50KTsKICAgIGVmZmVjdCAgPSAoZWZmZWN0IHx8ICdhcHBlYXInKS50b0xvd2VyQ2FzZSgpOwogICAgCiAgICByZXR1cm4gRWZmZWN0WyBFZmZlY3QuUEFJUlNbIGVmZmVjdCBdWyBlbGVtZW50LnZpc2libGUoKSA/IDEgOiAwIF0gXShlbGVtZW50LCBPYmplY3QuZXh0ZW5kKHsKICAgICAgcXVldWU6IHsgcG9zaXRpb246J2VuZCcsIHNjb3BlOihlbGVtZW50LmlkIHx8ICdnbG9iYWwnKSwgbGltaXQ6IDEgfQogICAgfSwgb3B0aW9ucyB8fCB7fSkpOwogIH0KfTsKCkVmZmVjdC5EZWZhdWx0T3B0aW9ucy50cmFuc2l0aW9uID0gRWZmZWN0LlRyYW5zaXRpb25zLnNpbm9pZGFsOwoKLyogLS0tLS0tLS0tLS0tLSBjb3JlIGVmZmVjdHMgLS0tLS0tLS0tLS0tLSAqLwoKRWZmZWN0LlNjb3BlZFF1ZXVlID0gQ2xhc3MuY3JlYXRlKEVudW1lcmFibGUsIHsKICBpbml0aWFsaXplOiBmdW5jdGlvbigpIHsKICAgIHRoaXMuZWZmZWN0cyAgPSBbXTsKICAgIHRoaXMuaW50ZXJ2YWwgPSBudWxsOwogIH0sCiAgX2VhY2g6IGZ1bmN0aW9uKGl0ZXJhdG9yKSB7CiAgICB0aGlzLmVmZmVjdHMuX2VhY2goaXRlcmF0b3IpOwogIH0sCiAgYWRkOiBmdW5jdGlvbihlZmZlY3QpIHsKICAgIHZhciB0aW1lc3RhbXAgPSBuZXcgRGF0ZSgpLmdldFRpbWUoKTsKCiAgICB2YXIgcG9zaXRpb24gPSBPYmplY3QuaXNTdHJpbmcoZWZmZWN0Lm9wdGlvbnMucXVldWUpID8KICAgICAgZWZmZWN0Lm9wdGlvbnMucXVldWUgOiBlZmZlY3Qub3B0aW9ucy5xdWV1ZS5wb3NpdGlvbjsKCiAgICBzd2l0Y2gocG9zaXRpb24pIHsKICAgICAgY2FzZSAnZnJvbnQnOgogICAgICAgIC8vIG1vdmUgdW5zdGFydGVkIGVmZmVjdHMgYWZ0ZXIgdGhpcyBlZmZlY3QKICAgICAgICB0aGlzLmVmZmVjdHMuZmluZEFsbChmdW5jdGlvbihlKXsgcmV0dXJuIGUuc3RhdGU9PSdpZGxlJyB9KS5lYWNoKCBmdW5jdGlvbihlKSB7CiAgICAgICAgICAgIGUuc3RhcnRPbiAgKz0gZWZmZWN0LmZpbmlzaE9uOwogICAgICAgICAgICBlLmZpbmlzaE9uICs9IGVmZmVjdC5maW5pc2hPbjsKICAgICAgICAgIH0pOwogICAgICAgIGJyZWFrOwogICAgICBjYXNlICd3aXRoLWxhc3QnOgogICAgICAgIHRpbWVzdGFtcCA9IHRoaXMuZWZmZWN0cy5wbHVjaygnc3RhcnRPbicpLm1heCgpIHx8IHRpbWVzdGFtcDsKICAgICAgICBicmVhazsKICAgICAgY2FzZSAnZW5kJzoKICAgICAgICAvLyBzdGFydCBlZmZlY3QgYWZ0ZXIgbGFzdCBxdWV1ZWQgZWZmZWN0IGhhcyBmaW5pc2hlZAogICAgICAgIHRpbWVzdGFtcCA9IHRoaXMuZWZmZWN0cy5wbHVjaygnZmluaXNoT24nKS5tYXgoKSB8fCB0aW1lc3RhbXA7CiAgICAgICAgYnJlYWs7CiAgICB9CgogICAgZWZmZWN0LnN0YXJ0T24gICs9IHRpbWVzdGFtcDsKICAgIGVmZmVjdC5maW5pc2hPbiArPSB0aW1lc3RhbXA7CgogICAgaWYgKCFlZmZlY3Qub3B0aW9ucy5xdWV1ZS5saW1pdCB8fCAodGhpcy5lZmZlY3RzLmxlbmd0aCA8IGVmZmVjdC5vcHRpb25zLnF1ZXVlLmxpbWl0KSkKICAgICAgdGhpcy5lZmZlY3RzLnB1c2goZWZmZWN0KTsKCiAgICBpZiAoIXRoaXMuaW50ZXJ2YWwpCiAgICAgIHRoaXMuaW50ZXJ2YWwgPSBzZXRJbnRlcnZhbCh0aGlzLmxvb3AuYmluZCh0aGlzKSwgMTUpOwogIH0sCiAgcmVtb3ZlOiBmdW5jdGlvbihlZmZlY3QpIHsKICAgIHRoaXMuZWZmZWN0cyA9IHRoaXMuZWZmZWN0cy5yZWplY3QoZnVuY3Rpb24oZSkgeyByZXR1cm4gZT09ZWZmZWN0IH0pOwogICAgaWYgKHRoaXMuZWZmZWN0cy5sZW5ndGggPT0gMCkgewogICAgICBjbGVhckludGVydmFsKHRoaXMuaW50ZXJ2YWwpOwogICAgICB0aGlzLmludGVydmFsID0gbnVsbDsKICAgIH0KICB9LAogIGxvb3A6IGZ1bmN0aW9uKCkgewogICAgdmFyIHRpbWVQb3MgPSBuZXcgRGF0ZSgpLmdldFRpbWUoKTsKICAgIGZvcih2YXIgaT0wLCBsZW49dGhpcy5lZmZlY3RzLmxlbmd0aDtpPGxlbjtpKyspCiAgICAgIHRoaXMuZWZmZWN0c1tpXSAmJiB0aGlzLmVmZmVjdHNbaV0ubG9vcCh0aW1lUG9zKTsKICB9Cn0pOwoKRWZmZWN0LlF1ZXVlcyA9IHsKICBpbnN0YW5jZXM6ICRIKCksCiAgZ2V0OiBmdW5jdGlvbihxdWV1ZU5hbWUpIHsKICAgIGlmICghT2JqZWN0LmlzU3RyaW5nKHF1ZXVlTmFtZSkpIHJldHVybiBxdWV1ZU5hbWU7CgogICAgcmV0dXJuIHRoaXMuaW5zdGFuY2VzLmdldChxdWV1ZU5hbWUpIHx8CiAgICAgIHRoaXMuaW5zdGFuY2VzLnNldChxdWV1ZU5hbWUsIG5ldyBFZmZlY3QuU2NvcGVkUXVldWUoKSk7CiAgfQp9OwpFZmZlY3QuUXVldWUgPSBFZmZlY3QuUXVldWVzLmdldCgnZ2xvYmFsJyk7CgpFZmZlY3QuQmFzZSA9IENsYXNzLmNyZWF0ZSh7CiAgcG9zaXRpb246IG51bGwsCiAgc3RhcnQ6IGZ1bmN0aW9uKG9wdGlvbnMpIHsKICAgIGlmIChvcHRpb25zICYmIG9wdGlvbnMudHJhbnNpdGlvbiA9PT0gZmFsc2UpIG9wdGlvbnMudHJhbnNpdGlvbiA9IEVmZmVjdC5UcmFuc2l0aW9ucy5saW5lYXI7CiAgICB0aGlzLm9wdGlvbnMgICAgICA9IE9iamVjdC5leHRlbmQoT2JqZWN0LmV4dGVuZCh7IH0sRWZmZWN0LkRlZmF1bHRPcHRpb25zKSwgb3B0aW9ucyB8fCB7IH0pOwogICAgdGhpcy5jdXJyZW50RnJhbWUgPSAwOwogICAgdGhpcy5zdGF0ZSAgICAgICAgPSAnaWRsZSc7CiAgICB0aGlzLnN0YXJ0T24gICAgICA9IHRoaXMub3B0aW9ucy5kZWxheSoxMDAwOwogICAgdGhpcy5maW5pc2hPbiAgICAgPSB0aGlzLnN0YXJ0T24rKHRoaXMub3B0aW9ucy5kdXJhdGlvbioxMDAwKTsKICAgIHRoaXMuZnJvbVRvRGVsdGEgID0gdGhpcy5vcHRpb25zLnRvLXRoaXMub3B0aW9ucy5mcm9tOwogICAgdGhpcy50b3RhbFRpbWUgICAgPSB0aGlzLmZpbmlzaE9uLXRoaXMuc3RhcnRPbjsKICAgIHRoaXMudG90YWxGcmFtZXMgID0gdGhpcy5vcHRpb25zLmZwcyp0aGlzLm9wdGlvbnMuZHVyYXRpb247CgogICAgdGhpcy5yZW5kZXIgPSAoZnVuY3Rpb24oKSB7CiAgICAgIGZ1bmN0aW9uIGRpc3BhdGNoKGVmZmVjdCwgZXZlbnROYW1lKSB7CiAgICAgICAgaWYgKGVmZmVjdC5vcHRpb25zW2V2ZW50TmFtZSArICdJbnRlcm5hbCddKQogICAgICAgICAgZWZmZWN0Lm9wdGlvbnNbZXZlbnROYW1lICsgJ0ludGVybmFsJ10oZWZmZWN0KTsKICAgICAgICBpZiAoZWZmZWN0Lm9wdGlvbnNbZXZlbnROYW1lXSkKICAgICAgICAgIGVmZmVjdC5vcHRpb25zW2V2ZW50TmFtZV0oZWZmZWN0KTsKICAgICAgfQoKICAgICAgcmV0dXJuIGZ1bmN0aW9uKHBvcykgewogICAgICAgIGlmICh0aGlzLnN0YXRlID09PSAiaWRsZSIpIHsKICAgICAgICAgIHRoaXMuc3RhdGUgPSAicnVubmluZyI7CiAgICAgICAgICBkaXNwYXRjaCh0aGlzLCAnYmVmb3JlU2V0dXAnKTsKICAgICAgICAgIGlmICh0aGlzLnNldHVwKSB0aGlzLnNldHVwKCk7CiAgICAgICAgICBkaXNwYXRjaCh0aGlzLCAnYWZ0ZXJTZXR1cCcpOwogICAgICAgIH0KICAgICAgICBpZiAodGhpcy5zdGF0ZSA9PT0gInJ1bm5pbmciKSB7CiAgICAgICAgICBwb3MgPSAodGhpcy5vcHRpb25zLnRyYW5zaXRpb24ocG9zKSAqIHRoaXMuZnJvbVRvRGVsdGEpICsgdGhpcy5vcHRpb25zLmZyb207CiAgICAgICAgICB0aGlzLnBvc2l0aW9uID0gcG9zOwogICAgICAgICAgZGlzcGF0Y2godGhpcywgJ2JlZm9yZVVwZGF0ZScpOwogICAgICAgICAgaWYgKHRoaXMudXBkYXRlKSB0aGlzLnVwZGF0ZShwb3MpOwogICAgICAgICAgZGlzcGF0Y2godGhpcywgJ2FmdGVyVXBkYXRlJyk7CiAgICAgICAgfQogICAgICB9OwogICAgfSkoKTsKCiAgICB0aGlzLmV2ZW50KCdiZWZvcmVTdGFydCcpOwogICAgaWYgKCF0aGlzLm9wdGlvbnMuc3luYykKICAgICAgRWZmZWN0LlF1ZXVlcy5nZXQoT2JqZWN0LmlzU3RyaW5nKHRoaXMub3B0aW9ucy5xdWV1ZSkgPwogICAgICAgICdnbG9iYWwnIDogdGhpcy5vcHRpb25zLnF1ZXVlLnNjb3BlKS5hZGQodGhpcyk7CiAgfSwKICBsb29wOiBmdW5jdGlvbih0aW1lUG9zKSB7CiAgICBpZiAodGltZVBvcyA+PSB0aGlzLnN0YXJ0T24pIHsKICAgICAgaWYgKHRpbWVQb3MgPj0gdGhpcy5maW5pc2hPbikgewogICAgICAgIHRoaXMucmVuZGVyKDEuMCk7CiAgICAgICAgdGhpcy5jYW5jZWwoKTsKICAgICAgICB0aGlzLmV2ZW50KCdiZWZvcmVGaW5pc2gnKTsKICAgICAgICBpZiAodGhpcy5maW5pc2gpIHRoaXMuZmluaXNoKCk7CiAgICAgICAgdGhpcy5ldmVudCgnYWZ0ZXJGaW5pc2gnKTsKICAgICAgICByZXR1cm47CiAgICAgIH0KICAgICAgdmFyIHBvcyAgID0gKHRpbWVQb3MgLSB0aGlzLnN0YXJ0T24pIC8gdGhpcy50b3RhbFRpbWUsCiAgICAgICAgICBmcmFtZSA9IChwb3MgKiB0aGlzLnRvdGFsRnJhbWVzKS5yb3VuZCgpOwogICAgICBpZiAoZnJhbWUgPiB0aGlzLmN1cnJlbnRGcmFtZSkgewogICAgICAgIHRoaXMucmVuZGVyKHBvcyk7CiAgICAgICAgdGhpcy5jdXJyZW50RnJhbWUgPSBmcmFtZTsKICAgICAgfQogICAgfQogIH0sCiAgY2FuY2VsOiBmdW5jdGlvbigpIHsKICAgIGlmICghdGhpcy5vcHRpb25zLnN5bmMpCiAgICAgIEVmZmVjdC5RdWV1ZXMuZ2V0KE9iamVjdC5pc1N0cmluZyh0aGlzLm9wdGlvbnMucXVldWUpID8KICAgICAgICAnZ2xvYmFsJyA6IHRoaXMub3B0aW9ucy5xdWV1ZS5zY29wZSkucmVtb3ZlKHRoaXMpOwogICAgdGhpcy5zdGF0ZSA9ICdmaW5pc2hlZCc7CiAgfSwKICBldmVudDogZnVuY3Rpb24oZXZlbnROYW1lKSB7CiAgICBpZiAodGhpcy5vcHRpb25zW2V2ZW50TmFtZSArICdJbnRlcm5hbCddKSB0aGlzLm9wdGlvbnNbZXZlbnROYW1lICsgJ0ludGVybmFsJ10odGhpcyk7CiAgICBpZiAodGhpcy5vcHRpb25zW2V2ZW50TmFtZV0pIHRoaXMub3B0aW9uc1tldmVudE5hbWVdKHRoaXMpOwogIH0sCiAgaW5zcGVjdDogZnVuY3Rpb24oKSB7CiAgICB2YXIgZGF0YSA9ICRIKCk7CiAgICBmb3IocHJvcGVydHkgaW4gdGhpcykKICAgICAgaWYgKCFPYmplY3QuaXNGdW5jdGlvbih0aGlzW3Byb3BlcnR5XSkpIGRhdGEuc2V0KHByb3BlcnR5LCB0aGlzW3Byb3BlcnR5XSk7CiAgICByZXR1cm4gJyM8RWZmZWN0OicgKyBkYXRhLmluc3BlY3QoKSArICcsb3B0aW9uczonICsgJEgodGhpcy5vcHRpb25zKS5pbnNwZWN0KCkgKyAnPic7CiAgfQp9KTsKCkVmZmVjdC5QYXJhbGxlbCA9IENsYXNzLmNyZWF0ZShFZmZlY3QuQmFzZSwgewogIGluaXRpYWxpemU6IGZ1bmN0aW9uKGVmZmVjdHMpIHsKICAgIHRoaXMuZWZmZWN0cyA9IGVmZmVjdHMgfHwgW107CiAgICB0aGlzLnN0YXJ0KGFyZ3VtZW50c1sxXSk7CiAgfSwKICB1cGRhdGU6IGZ1bmN0aW9uKHBvc2l0aW9uKSB7CiAgICB0aGlzLmVmZmVjdHMuaW52b2tlKCdyZW5kZXInLCBwb3NpdGlvbik7CiAgfSwKICBmaW5pc2g6IGZ1bmN0aW9uKHBvc2l0aW9uKSB7CiAgICB0aGlzLmVmZmVjdHMuZWFjaCggZnVuY3Rpb24oZWZmZWN0KSB7CiAgICAgIGVmZmVjdC5yZW5kZXIoMS4wKTsKICAgICAgZWZmZWN0LmNhbmNlbCgpOwogICAgICBlZmZlY3QuZXZlbnQoJ2JlZm9yZUZpbmlzaCcpOwogICAgICBpZiAoZWZmZWN0LmZpbmlzaCkgZWZmZWN0LmZpbmlzaChwb3NpdGlvbik7CiAgICAgIGVmZmVjdC5ldmVudCgnYWZ0ZXJGaW5pc2gnKTsKICAgIH0pOwogIH0KfSk7CgpFZmZlY3QuVHdlZW4gPSBDbGFzcy5jcmVhdGUoRWZmZWN0LkJhc2UsIHsKICBpbml0aWFsaXplOiBmdW5jdGlvbihvYmplY3QsIGZyb20sIHRvKSB7CiAgICBvYmplY3QgPSBPYmplY3QuaXNTdHJpbmcob2JqZWN0KSA/ICQob2JqZWN0KSA6IG9iamVjdDsKICAgIHZhciBhcmdzID0gJEEoYXJndW1lbnRzKSwgbWV0aG9kID0gYXJncy5sYXN0KCksCiAgICAgIG9wdGlvbnMgPSBhcmdzLmxlbmd0aCA9PSA1ID8gYXJnc1szXSA6IG51bGw7CiAgICB0aGlzLm1ldGhvZCA9IE9iamVjdC5pc0Z1bmN0aW9uKG1ldGhvZCkgPyBtZXRob2QuYmluZChvYmplY3QpIDoKICAgICAgT2JqZWN0LmlzRnVuY3Rpb24ob2JqZWN0W21ldGhvZF0pID8gb2JqZWN0W21ldGhvZF0uYmluZChvYmplY3QpIDoKICAgICAgZnVuY3Rpb24odmFsdWUpIHsgb2JqZWN0W21ldGhvZF0gPSB2YWx1ZSB9OwogICAgdGhpcy5zdGFydChPYmplY3QuZXh0ZW5kKHsgZnJvbTogZnJvbSwgdG86IHRvIH0sIG9wdGlvbnMgfHwgeyB9KSk7CiAgfSwKICB1cGRhdGU6IGZ1bmN0aW9uKHBvc2l0aW9uKSB7CiAgICB0aGlzLm1ldGhvZChwb3NpdGlvbik7CiAgfQp9KTsKCkVmZmVjdC5FdmVudCA9IENsYXNzLmNyZWF0ZShFZmZlY3QuQmFzZSwgewogIGluaXRpYWxpemU6IGZ1bmN0aW9uKCkgewogICAgdGhpcy5zdGFydChPYmplY3QuZXh0ZW5kKHsgZHVyYXRpb246IDAgfSwgYXJndW1lbnRzWzBdIHx8IHsgfSkpOwogIH0sCiAgdXBkYXRlOiBQcm90b3R5cGUuZW1wdHlGdW5jdGlvbgp9KTsKCkVmZmVjdC5PcGFjaXR5ID0gQ2xhc3MuY3JlYXRlKEVmZmVjdC5CYXNlLCB7CiAgaW5pdGlhbGl6ZTogZnVuY3Rpb24oZWxlbWVudCkgewogICAgdGhpcy5lbGVtZW50ID0gJChlbGVtZW50KTsKICAgIGlmICghdGhpcy5lbGVtZW50KSB0aHJvdyhFZmZlY3QuX2VsZW1lbnREb2VzTm90RXhpc3RFcnJvcik7CiAgICAvLyBtYWtlIHRoaXMgd29yayBvbiBJRSBvbiBlbGVtZW50cyB3aXRob3V0ICdsYXlvdXQnCiAgICBpZiAoUHJvdG90eXBlLkJyb3dzZXIuSUUgJiYgKCF0aGlzLmVsZW1lbnQuY3VycmVudFN0eWxlLmhhc0xheW91dCkpCiAgICAgIHRoaXMuZWxlbWVudC5zZXRTdHlsZSh7em9vbTogMX0pOwogICAgdmFyIG9wdGlvbnMgPSBPYmplY3QuZXh0ZW5kKHsKICAgICAgZnJvbTogdGhpcy5lbGVtZW50LmdldE9wYWNpdHkoKSB8fCAwLjAsCiAgICAgIHRvOiAgIDEuMAogICAgfSwgYXJndW1lbnRzWzFdIHx8IHsgfSk7CiAgICB0aGlzLnN0YXJ0KG9wdGlvbnMpOwogIH0sCiAgdXBkYXRlOiBmdW5jdGlvbihwb3NpdGlvbikgewogICAgdGhpcy5lbGVtZW50LnNldE9wYWNpdHkocG9zaXRpb24pOwogIH0KfSk7CgpFZmZlY3QuTW92ZSA9IENsYXNzLmNyZWF0ZShFZmZlY3QuQmFzZSwgewogIGluaXRpYWxpemU6IGZ1bmN0aW9uKGVsZW1lbnQpIHsKICAgIHRoaXMuZWxlbWVudCA9ICQoZWxlbWVudCk7CiAgICBpZiAoIXRoaXMuZWxlbWVudCkgdGhyb3coRWZmZWN0Ll9lbGVtZW50RG9lc05vdEV4aXN0RXJyb3IpOwogICAgdmFyIG9wdGlvbnMgPSBPYmplY3QuZXh0ZW5kKHsKICAgICAgeDogICAgMCwKICAgICAgeTogICAgMCwKICAgICAgbW9kZTogJ3JlbGF0aXZlJwogICAgfSwgYXJndW1lbnRzWzFdIHx8IHsgfSk7CiAgICB0aGlzLnN0YXJ0KG9wdGlvbnMpOwogIH0sCiAgc2V0dXA6IGZ1bmN0aW9uKCkgewogICAgdGhpcy5lbGVtZW50Lm1ha2VQb3NpdGlvbmVkKCk7CiAgICB0aGlzLm9yaWdpbmFsTGVmdCA9IHBhcnNlRmxvYXQodGhpcy5lbGVtZW50LmdldFN0eWxlKCdsZWZ0JykgfHwgJzAnKTsKICAgIHRoaXMub3JpZ2luYWxUb3AgID0gcGFyc2VGbG9hdCh0aGlzLmVsZW1lbnQuZ2V0U3R5bGUoJ3RvcCcpICB8fCAnMCcpOwogICAgaWYgKHRoaXMub3B0aW9ucy5tb2RlID09ICdhYnNvbHV0ZScpIHsKICAgICAgdGhpcy5vcHRpb25zLnggPSB0aGlzLm9wdGlvbnMueCAtIHRoaXMub3JpZ2luYWxMZWZ0OwogICAgICB0aGlzLm9wdGlvbnMueSA9IHRoaXMub3B0aW9ucy55IC0gdGhpcy5vcmlnaW5hbFRvcDsKICAgIH0KICB9LAogIHVwZGF0ZTogZnVuY3Rpb24ocG9zaXRpb24pIHsKICAgIHRoaXMuZWxlbWVudC5zZXRTdHlsZSh7CiAgICAgIGxlZnQ6ICh0aGlzLm9wdGlvbnMueCAgKiBwb3NpdGlvbiArIHRoaXMub3JpZ2luYWxMZWZ0KS5yb3VuZCgpICsgJ3B4JywKICAgICAgdG9wOiAgKHRoaXMub3B0aW9ucy55ICAqIHBvc2l0aW9uICsgdGhpcy5vcmlnaW5hbFRvcCkucm91bmQoKSAgKyAncHgnCiAgICB9KTsKICB9Cn0pOwoKLy8gZm9yIGJhY2t3YXJkcyBjb21wYXRpYmlsaXR5CkVmZmVjdC5Nb3ZlQnkgPSBmdW5jdGlvbihlbGVtZW50LCB0b1RvcCwgdG9MZWZ0KSB7CiAgcmV0dXJuIG5ldyBFZmZlY3QuTW92ZShlbGVtZW50LAogICAgT2JqZWN0LmV4dGVuZCh7IHg6IHRvTGVmdCwgeTogdG9Ub3AgfSwgYXJndW1lbnRzWzNdIHx8IHsgfSkpOwp9OwoKRWZmZWN0LlNjYWxlID0gQ2xhc3MuY3JlYXRlKEVmZmVjdC5CYXNlLCB7CiAgaW5pdGlhbGl6ZTogZnVuY3Rpb24oZWxlbWVudCwgcGVyY2VudCkgewogICAgdGhpcy5lbGVtZW50ID0gJChlbGVtZW50KTsKICAgIGlmICghdGhpcy5lbGVtZW50KSB0aHJvdyhFZmZlY3QuX2VsZW1lbnREb2VzTm90RXhpc3RFcnJvcik7CiAgICB2YXIgb3B0aW9ucyA9IE9iamVjdC5leHRlbmQoewogICAgICBzY2FsZVg6IHRydWUsCiAgICAgIHNjYWxlWTogdHJ1ZSwKICAgICAgc2NhbGVDb250ZW50OiB0cnVlLAogICAgICBzY2FsZUZyb21DZW50ZXI6IGZhbHNlLAogICAgICBzY2FsZU1vZGU6ICdib3gnLCAgICAgICAgLy8gJ2JveCcgb3IgJ2NvbnRlbnRzJyBvciB7IH0gd2l0aCBwcm92aWRlZCB2YWx1ZXMKICAgICAgc2NhbGVGcm9tOiAxMDAuMCwKICAgICAgc2NhbGVUbzogICBwZXJjZW50CiAgICB9LCBhcmd1bWVudHNbMl0gfHwgeyB9KTsKICAgIHRoaXMuc3RhcnQob3B0aW9ucyk7CiAgfSwKICBzZXR1cDogZnVuY3Rpb24oKSB7CiAgICB0aGlzLnJlc3RvcmVBZnRlckZpbmlzaCA9IHRoaXMub3B0aW9ucy5yZXN0b3JlQWZ0ZXJGaW5pc2ggfHwgZmFsc2U7CiAgICB0aGlzLmVsZW1lbnRQb3NpdGlvbmluZyA9IHRoaXMuZWxlbWVudC5nZXRTdHlsZSgncG9zaXRpb24nKTsKCiAgICB0aGlzLm9yaWdpbmFsU3R5bGUgPSB7IH07CiAgICBbJ3RvcCcsJ2xlZnQnLCd3aWR0aCcsJ2hlaWdodCcsJ2ZvbnRTaXplJ10uZWFjaCggZnVuY3Rpb24oaykgewogICAgICB0aGlzLm9yaWdpbmFsU3R5bGVba10gPSB0aGlzLmVsZW1lbnQuc3R5bGVba107CiAgICB9LmJpbmQodGhpcykpOwoKICAgIHRoaXMub3JpZ2luYWxUb3AgID0gdGhpcy5lbGVtZW50Lm9mZnNldFRvcDsKICAgIHRoaXMub3JpZ2luYWxMZWZ0ID0gdGhpcy5lbGVtZW50Lm9mZnNldExlZnQ7CgogICAgdmFyIGZvbnRTaXplID0gdGhpcy5lbGVtZW50LmdldFN0eWxlKCdmb250LXNpemUnKSB8fCAnMTAwJSc7CiAgICBbJ2VtJywncHgnLCclJywncHQnXS5lYWNoKCBmdW5jdGlvbihmb250U2l6ZVR5cGUpIHsKICAgICAgaWYgKGZvbnRTaXplLmluZGV4T2YoZm9udFNpemVUeXBlKT4wKSB7CiAgICAgICAgdGhpcy5mb250U2l6ZSAgICAgPSBwYXJzZUZsb2F0KGZvbnRTaXplKTsKICAgICAgICB0aGlzLmZvbnRTaXplVHlwZSA9IGZvbnRTaXplVHlwZTsKICAgICAgfQogICAgfS5iaW5kKHRoaXMpKTsKCiAgICB0aGlzLmZhY3RvciA9ICh0aGlzLm9wdGlvbnMuc2NhbGVUbyAtIHRoaXMub3B0aW9ucy5zY2FsZUZyb20pLzEwMDsKCiAgICB0aGlzLmRpbXMgPSBudWxsOwogICAgaWYgKHRoaXMub3B0aW9ucy5zY2FsZU1vZGU9PSdib3gnKQogICAgICB0aGlzLmRpbXMgPSBbdGhpcy5lbGVtZW50Lm9mZnNldEhlaWdodCwgdGhpcy5lbGVtZW50Lm9mZnNldFdpZHRoXTsKICAgIGlmICgvXmNvbnRlbnQvLnRlc3QodGhpcy5vcHRpb25zLnNjYWxlTW9kZSkpCiAgICAgIHRoaXMuZGltcyA9IFt0aGlzLmVsZW1lbnQuc2Nyb2xsSGVpZ2h0LCB0aGlzLmVsZW1lbnQuc2Nyb2xsV2lkdGhdOwogICAgaWYgKCF0aGlzLmRpbXMpCiAgICAgIHRoaXMuZGltcyA9IFt0aGlzLm9wdGlvbnMuc2NhbGVNb2RlLm9yaWdpbmFsSGVpZ2h0LAogICAgICAgICAgICAgICAgICAgdGhpcy5vcHRpb25zLnNjYWxlTW9kZS5vcmlnaW5hbFdpZHRoXTsKICB9LAogIHVwZGF0ZTogZnVuY3Rpb24ocG9zaXRpb24pIHsKICAgIHZhciBjdXJyZW50U2NhbGUgPSAodGhpcy5vcHRpb25zLnNjYWxlRnJvbS8xMDAuMCkgKyAodGhpcy5mYWN0b3IgKiBwb3NpdGlvbik7CiAgICBpZiAodGhpcy5vcHRpb25zLnNjYWxlQ29udGVudCAmJiB0aGlzLmZvbnRTaXplKQogICAgICB0aGlzLmVsZW1lbnQuc2V0U3R5bGUoe2ZvbnRTaXplOiB0aGlzLmZvbnRTaXplICogY3VycmVudFNjYWxlICsgdGhpcy5mb250U2l6ZVR5cGUgfSk7CiAgICB0aGlzLnNldERpbWVuc2lvbnModGhpcy5kaW1zWzBdICogY3VycmVudFNjYWxlLCB0aGlzLmRpbXNbMV0gKiBjdXJyZW50U2NhbGUpOwogIH0sCiAgZmluaXNoOiBmdW5jdGlvbihwb3NpdGlvbikgewogICAgaWYgKHRoaXMucmVzdG9yZUFmdGVyRmluaXNoKSB0aGlzLmVsZW1lbnQuc2V0U3R5bGUodGhpcy5vcmlnaW5hbFN0eWxlKTsKICB9LAogIHNldERpbWVuc2lvbnM6IGZ1bmN0aW9uKGhlaWdodCwgd2lkdGgpIHsKICAgIHZhciBkID0geyB9OwogICAgaWYgKHRoaXMub3B0aW9ucy5zY2FsZVgpIGQud2lkdGggPSB3aWR0aC5yb3VuZCgpICsgJ3B4JzsKICAgIGlmICh0aGlzLm9wdGlvbnMuc2NhbGVZKSBkLmhlaWdodCA9IGhlaWdodC5yb3VuZCgpICsgJ3B4JzsKICAgIGlmICh0aGlzLm9wdGlvbnMuc2NhbGVGcm9tQ2VudGVyKSB7CiAgICAgIHZhciB0b3BkICA9IChoZWlnaHQgLSB0aGlzLmRpbXNbMF0pLzI7CiAgICAgIHZhciBsZWZ0ZCA9ICh3aWR0aCAgLSB0aGlzLmRpbXNbMV0pLzI7CiAgICAgIGlmICh0aGlzLmVsZW1lbnRQb3NpdGlvbmluZyA9PSAnYWJzb2x1dGUnKSB7CiAgICAgICAgaWYgKHRoaXMub3B0aW9ucy5zY2FsZVkpIGQudG9wID0gdGhpcy5vcmlnaW5hbFRvcC10b3BkICsgJ3B4JzsKICAgICAgICBpZiAodGhpcy5vcHRpb25zLnNjYWxlWCkgZC5sZWZ0ID0gdGhpcy5vcmlnaW5hbExlZnQtbGVmdGQgKyAncHgnOwogICAgICB9IGVsc2UgewogICAgICAgIGlmICh0aGlzLm9wdGlvbnMuc2NhbGVZKSBkLnRvcCA9IC10b3BkICsgJ3B4JzsKICAgICAgICBpZiAodGhpcy5vcHRpb25zLnNjYWxlWCkgZC5sZWZ0ID0gLWxlZnRkICsgJ3B4JzsKICAgICAgfQogICAgfQogICAgdGhpcy5lbGVtZW50LnNldFN0eWxlKGQpOwogIH0KfSk7CgpFZmZlY3QuSGlnaGxpZ2h0ID0gQ2xhc3MuY3JlYXRlKEVmZmVjdC5CYXNlLCB7CiAgaW5pdGlhbGl6ZTogZnVuY3Rpb24oZWxlbWVudCkgewogICAgdGhpcy5lbGVtZW50ID0gJChlbGVtZW50KTsKICAgIGlmICghdGhpcy5lbGVtZW50KSB0aHJvdyhFZmZlY3QuX2VsZW1lbnREb2VzTm90RXhpc3RFcnJvcik7CiAgICB2YXIgb3B0aW9ucyA9IE9iamVjdC5leHRlbmQoeyBzdGFydGNvbG9yOiAnI2ZmZmY5OScgfSwgYXJndW1lbnRzWzFdIHx8IHsgfSk7CiAgICB0aGlzLnN0YXJ0KG9wdGlvbnMpOwogIH0sCiAgc2V0dXA6IGZ1bmN0aW9uKCkgewogICAgLy8gUHJldmVudCBleGVjdXRpbmcgb24gZWxlbWVudHMgbm90IGluIHRoZSBsYXlvdXQgZmxvdwogICAgaWYgKHRoaXMuZWxlbWVudC5nZXRTdHlsZSgnZGlzcGxheScpPT0nbm9uZScpIHsgdGhpcy5jYW5jZWwoKTsgcmV0dXJuOyB9CiAgICAvLyBEaXNhYmxlIGJhY2tncm91bmQgaW1hZ2UgZHVyaW5nIHRoZSBlZmZlY3QKICAgIHRoaXMub2xkU3R5bGUgPSB7IH07CiAgICBpZiAoIXRoaXMub3B0aW9ucy5rZWVwQmFja2dyb3VuZEltYWdlKSB7CiAgICAgIHRoaXMub2xkU3R5bGUuYmFja2dyb3VuZEltYWdlID0gdGhpcy5lbGVtZW50LmdldFN0eWxlKCdiYWNrZ3JvdW5kLWltYWdlJyk7CiAgICAgIHRoaXMuZWxlbWVudC5zZXRTdHlsZSh7YmFja2dyb3VuZEltYWdlOiAnbm9uZSd9KTsKICAgIH0KICAgIGlmICghdGhpcy5vcHRpb25zLmVuZGNvbG9yKQogICAgICB0aGlzLm9wdGlvbnMuZW5kY29sb3IgPSB0aGlzLmVsZW1lbnQuZ2V0U3R5bGUoJ2JhY2tncm91bmQtY29sb3InKS5wYXJzZUNvbG9yKCcjZmZmZmZmJyk7CiAgICBpZiAoIXRoaXMub3B0aW9ucy5yZXN0b3JlY29sb3IpCiAgICAgIHRoaXMub3B0aW9ucy5yZXN0b3JlY29sb3IgPSB0aGlzLmVsZW1lbnQuZ2V0U3R5bGUoJ2JhY2tncm91bmQtY29sb3InKTsKICAgIC8vIGluaXQgY29sb3IgY2FsY3VsYXRpb25zCiAgICB0aGlzLl9iYXNlICA9ICRSKDAsMikubWFwKGZ1bmN0aW9uKGkpeyByZXR1cm4gcGFyc2VJbnQodGhpcy5vcHRpb25zLnN0YXJ0Y29sb3Iuc2xpY2UoaSoyKzEsaSoyKzMpLDE2KSB9LmJpbmQodGhpcykpOwogICAgdGhpcy5fZGVsdGEgPSAkUigwLDIpLm1hcChmdW5jdGlvbihpKXsgcmV0dXJuIHBhcnNlSW50KHRoaXMub3B0aW9ucy5lbmRjb2xvci5zbGljZShpKjIrMSxpKjIrMyksMTYpLXRoaXMuX2Jhc2VbaV0gfS5iaW5kKHRoaXMpKTsKICB9LAogIHVwZGF0ZTogZnVuY3Rpb24ocG9zaXRpb24pIHsKICAgIHRoaXMuZWxlbWVudC5zZXRTdHlsZSh7YmFja2dyb3VuZENvbG9yOiAkUigwLDIpLmluamVjdCgnIycsZnVuY3Rpb24obSx2LGkpewogICAgICByZXR1cm4gbSsoKHRoaXMuX2Jhc2VbaV0rKHRoaXMuX2RlbHRhW2ldKnBvc2l0aW9uKSkucm91bmQoKS50b0NvbG9yUGFydCgpKTsgfS5iaW5kKHRoaXMpKSB9KTsKICB9LAogIGZpbmlzaDogZnVuY3Rpb24oKSB7CiAgICB0aGlzLmVsZW1lbnQuc2V0U3R5bGUoT2JqZWN0LmV4dGVuZCh0aGlzLm9sZFN0eWxlLCB7CiAgICAgIGJhY2tncm91bmRDb2xvcjogdGhpcy5vcHRpb25zLnJlc3RvcmVjb2xvcgogICAgfSkpOwogIH0KfSk7CgpFZmZlY3QuU2Nyb2xsVG8gPSBmdW5jdGlvbihlbGVtZW50KSB7CiAgdmFyIG9wdGlvbnMgPSBhcmd1bWVudHNbMV0gfHwgeyB9LAogIHNjcm9sbE9mZnNldHMgPSBkb2N1bWVudC52aWV3cG9ydC5nZXRTY3JvbGxPZmZzZXRzKCksCiAgZWxlbWVudE9mZnNldHMgPSAkKGVsZW1lbnQpLmN1bXVsYXRpdmVPZmZzZXQoKTsKCiAgaWYgKG9wdGlvbnMub2Zmc2V0KSBlbGVtZW50T2Zmc2V0c1sxXSArPSBvcHRpb25zLm9mZnNldDsKCiAgcmV0dXJuIG5ldyBFZmZlY3QuVHdlZW4obnVsbCwKICAgIHNjcm9sbE9mZnNldHMudG9wLAogICAgZWxlbWVudE9mZnNldHNbMV0sCiAgICBvcHRpb25zLAogICAgZnVuY3Rpb24ocCl7IHNjcm9sbFRvKHNjcm9sbE9mZnNldHMubGVmdCwgcC5yb3VuZCgpKTsgfQogICk7Cn07CgovKiAtLS0tLS0tLS0tLS0tIGNvbWJpbmF0aW9uIGVmZmVjdHMgLS0tLS0tLS0tLS0tLSAqLwoKRWZmZWN0LkZhZGUgPSBmdW5jdGlvbihlbGVtZW50KSB7CiAgZWxlbWVudCA9ICQoZWxlbWVudCk7CiAgdmFyIG9sZE9wYWNpdHkgPSBlbGVtZW50LmdldElubGluZU9wYWNpdHkoKTsKICB2YXIgb3B0aW9ucyA9IE9iamVjdC5leHRlbmQoewogICAgZnJvbTogZWxlbWVudC5nZXRPcGFjaXR5KCkgfHwgMS4wLAogICAgdG86ICAgMC4wLAogICAgYWZ0ZXJGaW5pc2hJbnRlcm5hbDogZnVuY3Rpb24oZWZmZWN0KSB7CiAgICAgIGlmIChlZmZlY3Qub3B0aW9ucy50byE9MCkgcmV0dXJuOwogICAgICBlZmZlY3QuZWxlbWVudC5oaWRlKCkuc2V0U3R5bGUoe29wYWNpdHk6IG9sZE9wYWNpdHl9KTsKICAgIH0KICB9LCBhcmd1bWVudHNbMV0gfHwgeyB9KTsKICByZXR1cm4gbmV3IEVmZmVjdC5PcGFjaXR5KGVsZW1lbnQsb3B0aW9ucyk7Cn07CgpFZmZlY3QuQXBwZWFyID0gZnVuY3Rpb24oZWxlbWVudCkgewogIGVsZW1lbnQgPSAkKGVsZW1lbnQpOwogIHZhciBvcHRpb25zID0gT2JqZWN0LmV4dGVuZCh7CiAgZnJvbTogKGVsZW1lbnQuZ2V0U3R5bGUoJ2Rpc3BsYXknKSA9PSAnbm9uZScgPyAwLjAgOiBlbGVtZW50LmdldE9wYWNpdHkoKSB8fCAwLjApLAogIHRvOiAgIDEuMCwKICAvLyBmb3JjZSBTYWZhcmkgdG8gcmVuZGVyIGZsb2F0ZWQgZWxlbWVudHMgcHJvcGVybHkKICBhZnRlckZpbmlzaEludGVybmFsOiBmdW5jdGlvbihlZmZlY3QpIHsKICAgIGVmZmVjdC5lbGVtZW50LmZvcmNlUmVyZW5kZXJpbmcoKTsKICB9LAogIGJlZm9yZVNldHVwOiBmdW5jdGlvbihlZmZlY3QpIHsKICAgIGVmZmVjdC5lbGVtZW50LnNldE9wYWNpdHkoZWZmZWN0Lm9wdGlvbnMuZnJvbSkuc2hvdygpOwogIH19LCBhcmd1bWVudHNbMV0gfHwgeyB9KTsKICByZXR1cm4gbmV3IEVmZmVjdC5PcGFjaXR5KGVsZW1lbnQsb3B0aW9ucyk7Cn07CgpFZmZlY3QuUHVmZiA9IGZ1bmN0aW9uKGVsZW1lbnQpIHsKICBlbGVtZW50ID0gJChlbGVtZW50KTsKICB2YXIgb2xkU3R5bGUgPSB7CiAgICBvcGFjaXR5OiBlbGVtZW50LmdldElubGluZU9wYWNpdHkoKSwKICAgIHBvc2l0aW9uOiBlbGVtZW50LmdldFN0eWxlKCdwb3NpdGlvbicpLAogICAgdG9wOiAgZWxlbWVudC5zdHlsZS50b3AsCiAgICBsZWZ0OiBlbGVtZW50LnN0eWxlLmxlZnQsCiAgICB3aWR0aDogZWxlbWVudC5zdHlsZS53aWR0aCwKICAgIGhlaWdodDogZWxlbWVudC5zdHlsZS5oZWlnaHQKICB9OwogIHJldHVybiBuZXcgRWZmZWN0LlBhcmFsbGVsKAogICBbIG5ldyBFZmZlY3QuU2NhbGUoZWxlbWVudCwgMjAwLAogICAgICB7IHN5bmM6IHRydWUsIHNjYWxlRnJvbUNlbnRlcjogdHJ1ZSwgc2NhbGVDb250ZW50OiB0cnVlLCByZXN0b3JlQWZ0ZXJGaW5pc2g6IHRydWUgfSksCiAgICAgbmV3IEVmZmVjdC5PcGFjaXR5KGVsZW1lbnQsIHsgc3luYzogdHJ1ZSwgdG86IDAuMCB9ICkgXSwKICAgICBPYmplY3QuZXh0ZW5kKHsgZHVyYXRpb246IDEuMCwKICAgICAgYmVmb3JlU2V0dXBJbnRlcm5hbDogZnVuY3Rpb24oZWZmZWN0KSB7CiAgICAgICAgUG9zaXRpb24uYWJzb2x1dGl6ZShlZmZlY3QuZWZmZWN0c1swXS5lbGVtZW50KTsKICAgICAgfSwKICAgICAgYWZ0ZXJGaW5pc2hJbnRlcm5hbDogZnVuY3Rpb24oZWZmZWN0KSB7CiAgICAgICAgIGVmZmVjdC5lZmZlY3RzWzBdLmVsZW1lbnQuaGlkZSgpLnNldFN0eWxlKG9sZFN0eWxlKTsgfQogICAgIH0sIGFyZ3VtZW50c1sxXSB8fCB7IH0pCiAgICk7Cn07CgpFZmZlY3QuQmxpbmRVcCA9IGZ1bmN0aW9uKGVsZW1lbnQpIHsKICBlbGVtZW50ID0gJChlbGVtZW50KTsKICBlbGVtZW50Lm1ha2VDbGlwcGluZygpOwogIHJldHVybiBuZXcgRWZmZWN0LlNjYWxlKGVsZW1lbnQsIDAsCiAgICBPYmplY3QuZXh0ZW5kKHsgc2NhbGVDb250ZW50OiBmYWxzZSwKICAgICAgc2NhbGVYOiBmYWxzZSwKICAgICAgcmVzdG9yZUFmdGVyRmluaXNoOiB0cnVlLAogICAgICBhZnRlckZpbmlzaEludGVybmFsOiBmdW5jdGlvbihlZmZlY3QpIHsKICAgICAgICBlZmZlY3QuZWxlbWVudC5oaWRlKCkudW5kb0NsaXBwaW5nKCk7CiAgICAgIH0KICAgIH0sIGFyZ3VtZW50c1sxXSB8fCB7IH0pCiAgKTsKfTsKCkVmZmVjdC5CbGluZERvd24gPSBmdW5jdGlvbihlbGVtZW50KSB7CiAgZWxlbWVudCA9ICQoZWxlbWVudCk7CiAgdmFyIGVsZW1lbnREaW1lbnNpb25zID0gZWxlbWVudC5nZXREaW1lbnNpb25zKCk7CiAgcmV0dXJuIG5ldyBFZmZlY3QuU2NhbGUoZWxlbWVudCwgMTAwLCBPYmplY3QuZXh0ZW5kKHsKICAgIHNjYWxlQ29udGVudDogZmFsc2UsCiAgICBzY2FsZVg6IGZhbHNlLAogICAgc2NhbGVGcm9tOiAwLAogICAgc2NhbGVNb2RlOiB7b3JpZ2luYWxIZWlnaHQ6IGVsZW1lbnREaW1lbnNpb25zLmhlaWdodCwgb3JpZ2luYWxXaWR0aDogZWxlbWVudERpbWVuc2lvbnMud2lkdGh9LAogICAgcmVzdG9yZUFmdGVyRmluaXNoOiB0cnVlLAogICAgYWZ0ZXJTZXR1cDogZnVuY3Rpb24oZWZmZWN0KSB7CiAgICAgIGVmZmVjdC5lbGVtZW50Lm1ha2VDbGlwcGluZygpLnNldFN0eWxlKHtoZWlnaHQ6ICcwcHgnfSkuc2hvdygpOwogICAgfSwKICAgIGFmdGVyRmluaXNoSW50ZXJuYWw6IGZ1bmN0aW9uKGVmZmVjdCkgewogICAgICBlZmZlY3QuZWxlbWVudC51bmRvQ2xpcHBpbmcoKTsKICAgIH0KICB9LCBhcmd1bWVudHNbMV0gfHwgeyB9KSk7Cn07CgpFZmZlY3QuU3dpdGNoT2ZmID0gZnVuY3Rpb24oZWxlbWVudCkgewogIGVsZW1lbnQgPSAkKGVsZW1lbnQpOwogIHZhciBvbGRPcGFjaXR5ID0gZWxlbWVudC5nZXRJbmxpbmVPcGFjaXR5KCk7CiAgcmV0dXJuIG5ldyBFZmZlY3QuQXBwZWFyKGVsZW1lbnQsIE9iamVjdC5leHRlbmQoewogICAgZHVyYXRpb246IDAuNCwKICAgIGZyb206IDAsCiAgICB0cmFuc2l0aW9uOiBFZmZlY3QuVHJhbnNpdGlvbnMuZmxpY2tlciwKICAgIGFmdGVyRmluaXNoSW50ZXJuYWw6IGZ1bmN0aW9uKGVmZmVjdCkgewogICAgICBuZXcgRWZmZWN0LlNjYWxlKGVmZmVjdC5lbGVtZW50LCAxLCB7CiAgICAgICAgZHVyYXRpb246IDAuMywgc2NhbGVGcm9tQ2VudGVyOiB0cnVlLAogICAgICAgIHNjYWxlWDogZmFsc2UsIHNjYWxlQ29udGVudDogZmFsc2UsIHJlc3RvcmVBZnRlckZpbmlzaDogdHJ1ZSwKICAgICAgICBiZWZvcmVTZXR1cDogZnVuY3Rpb24oZWZmZWN0KSB7CiAgICAgICAgICBlZmZlY3QuZWxlbWVudC5tYWtlUG9zaXRpb25lZCgpLm1ha2VDbGlwcGluZygpOwogICAgICAgIH0sCiAgICAgICAgYWZ0ZXJGaW5pc2hJbnRlcm5hbDogZnVuY3Rpb24oZWZmZWN0KSB7CiAgICAgICAgICBlZmZlY3QuZWxlbWVudC5oaWRlKCkudW5kb0NsaXBwaW5nKCkudW5kb1Bvc2l0aW9uZWQoKS5zZXRTdHlsZSh7b3BhY2l0eTogb2xkT3BhY2l0eX0pOwogICAgICAgIH0KICAgICAgfSk7CiAgICB9CiAgfSwgYXJndW1lbnRzWzFdIHx8IHsgfSkpOwp9OwoKRWZmZWN0LkRyb3BPdXQgPSBmdW5jdGlvbihlbGVtZW50KSB7CiAgZWxlbWVudCA9ICQoZWxlbWVudCk7CiAgdmFyIG9sZFN0eWxlID0gewogICAgdG9wOiBlbGVtZW50LmdldFN0eWxlKCd0b3AnKSwKICAgIGxlZnQ6IGVsZW1lbnQuZ2V0U3R5bGUoJ2xlZnQnKSwKICAgIG9wYWNpdHk6IGVsZW1lbnQuZ2V0SW5saW5lT3BhY2l0eSgpIH07CiAgcmV0dXJuIG5ldyBFZmZlY3QuUGFyYWxsZWwoCiAgICBbIG5ldyBFZmZlY3QuTW92ZShlbGVtZW50LCB7eDogMCwgeTogMTAwLCBzeW5jOiB0cnVlIH0pLAogICAgICBuZXcgRWZmZWN0Lk9wYWNpdHkoZWxlbWVudCwgeyBzeW5jOiB0cnVlLCB0bzogMC4wIH0pIF0sCiAgICBPYmplY3QuZXh0ZW5kKAogICAgICB7IGR1cmF0aW9uOiAwLjUsCiAgICAgICAgYmVmb3JlU2V0dXA6IGZ1bmN0aW9uKGVmZmVjdCkgewogICAgICAgICAgZWZmZWN0LmVmZmVjdHNbMF0uZWxlbWVudC5tYWtlUG9zaXRpb25lZCgpOwogICAgICAgIH0sCiAgICAgICAgYWZ0ZXJGaW5pc2hJbnRlcm5hbDogZnVuY3Rpb24oZWZmZWN0KSB7CiAgICAgICAgICBlZmZlY3QuZWZmZWN0c1swXS5lbGVtZW50LmhpZGUoKS51bmRvUG9zaXRpb25lZCgpLnNldFN0eWxlKG9sZFN0eWxlKTsKICAgICAgICB9CiAgICAgIH0sIGFyZ3VtZW50c1sxXSB8fCB7IH0pKTsKfTsKCkVmZmVjdC5TaGFrZSA9IGZ1bmN0aW9uKGVsZW1lbnQpIHsKICBlbGVtZW50ID0gJChlbGVtZW50KTsKICB2YXIgb3B0aW9ucyA9IE9iamVjdC5leHRlbmQoewogICAgZGlzdGFuY2U6IDIwLAogICAgZHVyYXRpb246IDAuNQogIH0sIGFyZ3VtZW50c1sxXSB8fCB7fSk7CiAgdmFyIGRpc3RhbmNlID0gcGFyc2VGbG9hdChvcHRpb25zLmRpc3RhbmNlKTsKICB2YXIgc3BsaXQgPSBwYXJzZUZsb2F0KG9wdGlvbnMuZHVyYXRpb24pIC8gMTAuMDsKICB2YXIgb2xkU3R5bGUgPSB7CiAgICB0b3A6IGVsZW1lbnQuZ2V0U3R5bGUoJ3RvcCcpLAogICAgbGVmdDogZWxlbWVudC5nZXRTdHlsZSgnbGVmdCcpIH07CiAgICByZXR1cm4gbmV3IEVmZmVjdC5Nb3ZlKGVsZW1lbnQsCiAgICAgIHsgeDogIGRpc3RhbmNlLCB5OiAwLCBkdXJhdGlvbjogc3BsaXQsIGFmdGVyRmluaXNoSW50ZXJuYWw6IGZ1bmN0aW9uKGVmZmVjdCkgewogICAgbmV3IEVmZmVjdC5Nb3ZlKGVmZmVjdC5lbGVtZW50LAogICAgICB7IHg6IC1kaXN0YW5jZSoyLCB5OiAwLCBkdXJhdGlvbjogc3BsaXQqMiwgIGFmdGVyRmluaXNoSW50ZXJuYWw6IGZ1bmN0aW9uKGVmZmVjdCkgewogICAgbmV3IEVmZmVjdC5Nb3ZlKGVmZmVjdC5lbGVtZW50LAogICAgICB7IHg6ICBkaXN0YW5jZSoyLCB5OiAwLCBkdXJhdGlvbjogc3BsaXQqMiwgIGFmdGVyRmluaXNoSW50ZXJuYWw6IGZ1bmN0aW9uKGVmZmVjdCkgewogICAgbmV3IEVmZmVjdC5Nb3ZlKGVmZmVjdC5lbGVtZW50LAogICAgICB7IHg6IC1kaXN0YW5jZSoyLCB5OiAwLCBkdXJhdGlvbjogc3BsaXQqMiwgIGFmdGVyRmluaXNoSW50ZXJuYWw6IGZ1bmN0aW9uKGVmZmVjdCkgewogICAgbmV3IEVmZmVjdC5Nb3ZlKGVmZmVjdC5lbGVtZW50LAogICAgICB7IHg6ICBkaXN0YW5jZSoyLCB5OiAwLCBkdXJhdGlvbjogc3BsaXQqMiwgIGFmdGVyRmluaXNoSW50ZXJuYWw6IGZ1bmN0aW9uKGVmZmVjdCkgewogICAgbmV3IEVmZmVjdC5Nb3ZlKGVmZmVjdC5lbGVtZW50LAogICAgICB7IHg6IC1kaXN0YW5jZSwgeTogMCwgZHVyYXRpb246IHNwbGl0LCBhZnRlckZpbmlzaEludGVybmFsOiBmdW5jdGlvbihlZmZlY3QpIHsKICAgICAgICBlZmZlY3QuZWxlbWVudC51bmRvUG9zaXRpb25lZCgpLnNldFN0eWxlKG9sZFN0eWxlKTsKICB9fSk7IH19KTsgfX0pOyB9fSk7IH19KTsgfX0pOwp9OwoKRWZmZWN0LlNsaWRlRG93biA9IGZ1bmN0aW9uKGVsZW1lbnQpIHsKICBlbGVtZW50ID0gJChlbGVtZW50KS5jbGVhbldoaXRlc3BhY2UoKTsKICAvLyBTbGlkZURvd24gbmVlZCB0byBoYXZlIHRoZSBjb250ZW50IG9mIHRoZSBlbGVtZW50IHdyYXBwZWQgaW4gYSBjb250YWluZXIgZWxlbWVudCB3aXRoIGZpeGVkIGhlaWdodCEKICB2YXIgb2xkSW5uZXJCb3R0b20gPSBlbGVtZW50LmRvd24oKS5nZXRTdHlsZSgnYm90dG9tJyk7CiAgdmFyIGVsZW1lbnREaW1lbnNpb25zID0gZWxlbWVudC5nZXREaW1lbnNpb25zKCk7CiAgcmV0dXJuIG5ldyBFZmZlY3QuU2NhbGUoZWxlbWVudCwgMTAwLCBPYmplY3QuZXh0ZW5kKHsKICAgIHNjYWxlQ29udGVudDogZmFsc2UsCiAgICBzY2FsZVg6IGZhbHNlLAogICAgc2NhbGVGcm9tOiB3aW5kb3cub3BlcmEgPyAwIDogMSwKICAgIHNjYWxlTW9kZToge29yaWdpbmFsSGVpZ2h0OiBlbGVtZW50RGltZW5zaW9ucy5oZWlnaHQsIG9yaWdpbmFsV2lkdGg6IGVsZW1lbnREaW1lbnNpb25zLndpZHRofSwKICAgIHJlc3RvcmVBZnRlckZpbmlzaDogdHJ1ZSwKICAgIGFmdGVyU2V0dXA6IGZ1bmN0aW9uKGVmZmVjdCkgewogICAgICBlZmZlY3QuZWxlbWVudC5tYWtlUG9zaXRpb25lZCgpOwogICAgICBlZmZlY3QuZWxlbWVudC5kb3duKCkubWFrZVBvc2l0aW9uZWQoKTsKICAgICAgaWYgKHdpbmRvdy5vcGVyYSkgZWZmZWN0LmVsZW1lbnQuc2V0U3R5bGUoe3RvcDogJyd9KTsKICAgICAgZWZmZWN0LmVsZW1lbnQubWFrZUNsaXBwaW5nKCkuc2V0U3R5bGUoe2hlaWdodDogJzBweCd9KS5zaG93KCk7CiAgICB9LAogICAgYWZ0ZXJVcGRhdGVJbnRlcm5hbDogZnVuY3Rpb24oZWZmZWN0KSB7CiAgICAgIGVmZmVjdC5lbGVtZW50LmRvd24oKS5zZXRTdHlsZSh7Ym90dG9tOgogICAgICAgIChlZmZlY3QuZGltc1swXSAtIGVmZmVjdC5lbGVtZW50LmNsaWVudEhlaWdodCkgKyAncHgnIH0pOwogICAgfSwKICAgIGFmdGVyRmluaXNoSW50ZXJuYWw6IGZ1bmN0aW9uKGVmZmVjdCkgewogICAgICBlZmZlY3QuZWxlbWVudC51bmRvQ2xpcHBpbmcoKS51bmRvUG9zaXRpb25lZCgpOwogICAgICBlZmZlY3QuZWxlbWVudC5kb3duKCkudW5kb1Bvc2l0aW9uZWQoKS5zZXRTdHlsZSh7Ym90dG9tOiBvbGRJbm5lckJvdHRvbX0pOyB9CiAgICB9LCBhcmd1bWVudHNbMV0gfHwgeyB9KQogICk7Cn07CgpFZmZlY3QuU2xpZGVVcCA9IGZ1bmN0aW9uKGVsZW1lbnQpIHsKICBlbGVtZW50ID0gJChlbGVtZW50KS5jbGVhbldoaXRlc3BhY2UoKTsKICB2YXIgb2xkSW5uZXJCb3R0b20gPSBlbGVtZW50LmRvd24oKS5nZXRTdHlsZSgnYm90dG9tJyk7CiAgdmFyIGVsZW1lbnREaW1lbnNpb25zID0gZWxlbWVudC5nZXREaW1lbnNpb25zKCk7CiAgcmV0dXJuIG5ldyBFZmZlY3QuU2NhbGUoZWxlbWVudCwgd2luZG93Lm9wZXJhID8gMCA6IDEsCiAgIE9iamVjdC5leHRlbmQoeyBzY2FsZUNvbnRlbnQ6IGZhbHNlLAogICAgc2NhbGVYOiBmYWxzZSwKICAgIHNjYWxlTW9kZTogJ2JveCcsCiAgICBzY2FsZUZyb206IDEwMCwKICAgIHNjYWxlTW9kZToge29yaWdpbmFsSGVpZ2h0OiBlbGVtZW50RGltZW5zaW9ucy5oZWlnaHQsIG9yaWdpbmFsV2lkdGg6IGVsZW1lbnREaW1lbnNpb25zLndpZHRofSwKICAgIHJlc3RvcmVBZnRlckZpbmlzaDogdHJ1ZSwKICAgIGFmdGVyU2V0dXA6IGZ1bmN0aW9uKGVmZmVjdCkgewogICAgICBlZmZlY3QuZWxlbWVudC5tYWtlUG9zaXRpb25lZCgpOwogICAgICBlZmZlY3QuZWxlbWVudC5kb3duKCkubWFrZVBvc2l0aW9uZWQoKTsKICAgICAgaWYgKHdpbmRvdy5vcGVyYSkgZWZmZWN0LmVsZW1lbnQuc2V0U3R5bGUoe3RvcDogJyd9KTsKICAgICAgZWZmZWN0LmVsZW1lbnQubWFrZUNsaXBwaW5nKCkuc2hvdygpOwogICAgfSwKICAgIGFmdGVyVXBkYXRlSW50ZXJuYWw6IGZ1bmN0aW9uKGVmZmVjdCkgewogICAgICBlZmZlY3QuZWxlbWVudC5kb3duKCkuc2V0U3R5bGUoe2JvdHRvbToKICAgICAgICAoZWZmZWN0LmRpbXNbMF0gLSBlZmZlY3QuZWxlbWVudC5jbGllbnRIZWlnaHQpICsgJ3B4JyB9KTsKICAgIH0sCiAgICBhZnRlckZpbmlzaEludGVybmFsOiBmdW5jdGlvbihlZmZlY3QpIHsKICAgICAgZWZmZWN0LmVsZW1lbnQuaGlkZSgpLnVuZG9DbGlwcGluZygpLnVuZG9Qb3NpdGlvbmVkKCk7CiAgICAgIGVmZmVjdC5lbGVtZW50LmRvd24oKS51bmRvUG9zaXRpb25lZCgpLnNldFN0eWxlKHtib3R0b206IG9sZElubmVyQm90dG9tfSk7CiAgICB9CiAgIH0sIGFyZ3VtZW50c1sxXSB8fCB7IH0pCiAgKTsKfTsKCi8vIEJ1ZyBpbiBvcGVyYSBtYWtlcyB0aGUgVEQgY29udGFpbmluZyB0aGlzIGVsZW1lbnQgZXhwYW5kIGZvciBhIGluc3RhbmNlIGFmdGVyIGZpbmlzaApFZmZlY3QuU3F1aXNoID0gZnVuY3Rpb24oZWxlbWVudCkgewogIHJldHVybiBuZXcgRWZmZWN0LlNjYWxlKGVsZW1lbnQsIHdpbmRvdy5vcGVyYSA/IDEgOiAwLCB7CiAgICByZXN0b3JlQWZ0ZXJGaW5pc2g6IHRydWUsCiAgICBiZWZvcmVTZXR1cDogZnVuY3Rpb24oZWZmZWN0KSB7CiAgICAgIGVmZmVjdC5lbGVtZW50Lm1ha2VDbGlwcGluZygpOwogICAgfSwKICAgIGFmdGVyRmluaXNoSW50ZXJuYWw6IGZ1bmN0aW9uKGVmZmVjdCkgewogICAgICBlZmZlY3QuZWxlbWVudC5oaWRlKCkudW5kb0NsaXBwaW5nKCk7CiAgICB9CiAgfSk7Cn07CgpFZmZlY3QuR3JvdyA9IGZ1bmN0aW9uKGVsZW1lbnQpIHsKICBlbGVtZW50ID0gJChlbGVtZW50KTsKICB2YXIgb3B0aW9ucyA9IE9iamVjdC5leHRlbmQoewogICAgZGlyZWN0aW9uOiAnY2VudGVyJywKICAgIG1vdmVUcmFuc2l0aW9uOiBFZmZlY3QuVHJhbnNpdGlvbnMuc2lub2lkYWwsCiAgICBzY2FsZVRyYW5zaXRpb246IEVmZmVjdC5UcmFuc2l0aW9ucy5zaW5vaWRhbCwKICAgIG9wYWNpdHlUcmFuc2l0aW9uOiBFZmZlY3QuVHJhbnNpdGlvbnMuZnVsbAogIH0sIGFyZ3VtZW50c1sxXSB8fCB7IH0pOwogIHZhciBvbGRTdHlsZSA9IHsKICAgIHRvcDogZWxlbWVudC5zdHlsZS50b3AsCiAgICBsZWZ0OiBlbGVtZW50LnN0eWxlLmxlZnQsCiAgICBoZWlnaHQ6IGVsZW1lbnQuc3R5bGUuaGVpZ2h0LAogICAgd2lkdGg6IGVsZW1lbnQuc3R5bGUud2lkdGgsCiAgICBvcGFjaXR5OiBlbGVtZW50LmdldElubGluZU9wYWNpdHkoKSB9OwoKICB2YXIgZGltcyA9IGVsZW1lbnQuZ2V0RGltZW5zaW9ucygpOwogIHZhciBpbml0aWFsTW92ZVgsIGluaXRpYWxNb3ZlWTsKICB2YXIgbW92ZVgsIG1vdmVZOwoKICBzd2l0Y2ggKG9wdGlvbnMuZGlyZWN0aW9uKSB7CiAgICBjYXNlICd0b3AtbGVmdCc6CiAgICAgIGluaXRpYWxNb3ZlWCA9IGluaXRpYWxNb3ZlWSA9IG1vdmVYID0gbW92ZVkgPSAwOwogICAgICBicmVhazsKICAgIGNhc2UgJ3RvcC1yaWdodCc6CiAgICAgIGluaXRpYWxNb3ZlWCA9IGRpbXMud2lkdGg7CiAgICAgIGluaXRpYWxNb3ZlWSA9IG1vdmVZID0gMDsKICAgICAgbW92ZVggPSAtZGltcy53aWR0aDsKICAgICAgYnJlYWs7CiAgICBjYXNlICdib3R0b20tbGVmdCc6CiAgICAgIGluaXRpYWxNb3ZlWCA9IG1vdmVYID0gMDsKICAgICAgaW5pdGlhbE1vdmVZID0gZGltcy5oZWlnaHQ7CiAgICAgIG1vdmVZID0gLWRpbXMuaGVpZ2h0OwogICAgICBicmVhazsKICAgIGNhc2UgJ2JvdHRvbS1yaWdodCc6CiAgICAgIGluaXRpYWxNb3ZlWCA9IGRpbXMud2lkdGg7CiAgICAgIGluaXRpYWxNb3ZlWSA9IGRpbXMuaGVpZ2h0OwogICAgICBtb3ZlWCA9IC1kaW1zLndpZHRoOwogICAgICBtb3ZlWSA9IC1kaW1zLmhlaWdodDsKICAgICAgYnJlYWs7CiAgICBjYXNlICdjZW50ZXInOgogICAgICBpbml0aWFsTW92ZVggPSBkaW1zLndpZHRoIC8gMjsKICAgICAgaW5pdGlhbE1vdmVZID0gZGltcy5oZWlnaHQgLyAyOwogICAgICBtb3ZlWCA9IC1kaW1zLndpZHRoIC8gMjsKICAgICAgbW92ZVkgPSAtZGltcy5oZWlnaHQgLyAyOwogICAgICBicmVhazsKICB9CgogIHJldHVybiBuZXcgRWZmZWN0Lk1vdmUoZWxlbWVudCwgewogICAgeDogaW5pdGlhbE1vdmVYLAogICAgeTogaW5pdGlhbE1vdmVZLAogICAgZHVyYXRpb246IDAuMDEsCiAgICBiZWZvcmVTZXR1cDogZnVuY3Rpb24oZWZmZWN0KSB7CiAgICAgIGVmZmVjdC5lbGVtZW50LmhpZGUoKS5tYWtlQ2xpcHBpbmcoKS5tYWtlUG9zaXRpb25lZCgpOwogICAgfSwKICAgIGFmdGVyRmluaXNoSW50ZXJuYWw6IGZ1bmN0aW9uKGVmZmVjdCkgewogICAgICBuZXcgRWZmZWN0LlBhcmFsbGVsKAogICAgICAgIFsgbmV3IEVmZmVjdC5PcGFjaXR5KGVmZmVjdC5lbGVtZW50LCB7IHN5bmM6IHRydWUsIHRvOiAxLjAsIGZyb206IDAuMCwgdHJhbnNpdGlvbjogb3B0aW9ucy5vcGFjaXR5VHJhbnNpdGlvbiB9KSwKICAgICAgICAgIG5ldyBFZmZlY3QuTW92ZShlZmZlY3QuZWxlbWVudCwgeyB4OiBtb3ZlWCwgeTogbW92ZVksIHN5bmM6IHRydWUsIHRyYW5zaXRpb246IG9wdGlvbnMubW92ZVRyYW5zaXRpb24gfSksCiAgICAgICAgICBuZXcgRWZmZWN0LlNjYWxlKGVmZmVjdC5lbGVtZW50LCAxMDAsIHsKICAgICAgICAgICAgc2NhbGVNb2RlOiB7IG9yaWdpbmFsSGVpZ2h0OiBkaW1zLmhlaWdodCwgb3JpZ2luYWxXaWR0aDogZGltcy53aWR0aCB9LAogICAgICAgICAgICBzeW5jOiB0cnVlLCBzY2FsZUZyb206IHdpbmRvdy5vcGVyYSA/IDEgOiAwLCB0cmFuc2l0aW9uOiBvcHRpb25zLnNjYWxlVHJhbnNpdGlvbiwgcmVzdG9yZUFmdGVyRmluaXNoOiB0cnVlfSkKICAgICAgICBdLCBPYmplY3QuZXh0ZW5kKHsKICAgICAgICAgICAgIGJlZm9yZVNldHVwOiBmdW5jdGlvbihlZmZlY3QpIHsKICAgICAgICAgICAgICAgZWZmZWN0LmVmZmVjdHNbMF0uZWxlbWVudC5zZXRTdHlsZSh7aGVpZ2h0OiAnMHB4J30pLnNob3coKTsKICAgICAgICAgICAgIH0sCiAgICAgICAgICAgICBhZnRlckZpbmlzaEludGVybmFsOiBmdW5jdGlvbihlZmZlY3QpIHsKICAgICAgICAgICAgICAgZWZmZWN0LmVmZmVjdHNbMF0uZWxlbWVudC51bmRvQ2xpcHBpbmcoKS51bmRvUG9zaXRpb25lZCgpLnNldFN0eWxlKG9sZFN0eWxlKTsKICAgICAgICAgICAgIH0KICAgICAgICAgICB9LCBvcHRpb25zKQogICAgICApOwogICAgfQogIH0pOwp9OwoKRWZmZWN0LlNocmluayA9IGZ1bmN0aW9uKGVsZW1lbnQpIHsKICBlbGVtZW50ID0gJChlbGVtZW50KTsKICB2YXIgb3B0aW9ucyA9IE9iamVjdC5leHRlbmQoewogICAgZGlyZWN0aW9uOiAnY2VudGVyJywKICAgIG1vdmVUcmFuc2l0aW9uOiBFZmZlY3QuVHJhbnNpdGlvbnMuc2lub2lkYWwsCiAgICBzY2FsZVRyYW5zaXRpb246IEVmZmVjdC5UcmFuc2l0aW9ucy5zaW5vaWRhbCwKICAgIG9wYWNpdHlUcmFuc2l0aW9uOiBFZmZlY3QuVHJhbnNpdGlvbnMubm9uZQogIH0sIGFyZ3VtZW50c1sxXSB8fCB7IH0pOwogIHZhciBvbGRTdHlsZSA9IHsKICAgIHRvcDogZWxlbWVudC5zdHlsZS50b3AsCiAgICBsZWZ0OiBlbGVtZW50LnN0eWxlLmxlZnQsCiAgICBoZWlnaHQ6IGVsZW1lbnQuc3R5bGUuaGVpZ2h0LAogICAgd2lkdGg6IGVsZW1lbnQuc3R5bGUud2lkdGgsCiAgICBvcGFjaXR5OiBlbGVtZW50LmdldElubGluZU9wYWNpdHkoKSB9OwoKICB2YXIgZGltcyA9IGVsZW1lbnQuZ2V0RGltZW5zaW9ucygpOwogIHZhciBtb3ZlWCwgbW92ZVk7CgogIHN3aXRjaCAob3B0aW9ucy5kaXJlY3Rpb24pIHsKICAgIGNhc2UgJ3RvcC1sZWZ0JzoKICAgICAgbW92ZVggPSBtb3ZlWSA9IDA7CiAgICAgIGJyZWFrOwogICAgY2FzZSAndG9wLXJpZ2h0JzoKICAgICAgbW92ZVggPSBkaW1zLndpZHRoOwogICAgICBtb3ZlWSA9IDA7CiAgICAgIGJyZWFrOwogICAgY2FzZSAnYm90dG9tLWxlZnQnOgogICAgICBtb3ZlWCA9IDA7CiAgICAgIG1vdmVZID0gZGltcy5oZWlnaHQ7CiAgICAgIGJyZWFrOwogICAgY2FzZSAnYm90dG9tLXJpZ2h0JzoKICAgICAgbW92ZVggPSBkaW1zLndpZHRoOwogICAgICBtb3ZlWSA9IGRpbXMuaGVpZ2h0OwogICAgICBicmVhazsKICAgIGNhc2UgJ2NlbnRlcic6CiAgICAgIG1vdmVYID0gZGltcy53aWR0aCAvIDI7CiAgICAgIG1vdmVZID0gZGltcy5oZWlnaHQgLyAyOwogICAgICBicmVhazsKICB9CgogIHJldHVybiBuZXcgRWZmZWN0LlBhcmFsbGVsKAogICAgWyBuZXcgRWZmZWN0Lk9wYWNpdHkoZWxlbWVudCwgeyBzeW5jOiB0cnVlLCB0bzogMC4wLCBmcm9tOiAxLjAsIHRyYW5zaXRpb246IG9wdGlvbnMub3BhY2l0eVRyYW5zaXRpb24gfSksCiAgICAgIG5ldyBFZmZlY3QuU2NhbGUoZWxlbWVudCwgd2luZG93Lm9wZXJhID8gMSA6IDAsIHsgc3luYzogdHJ1ZSwgdHJhbnNpdGlvbjogb3B0aW9ucy5zY2FsZVRyYW5zaXRpb24sIHJlc3RvcmVBZnRlckZpbmlzaDogdHJ1ZX0pLAogICAgICBuZXcgRWZmZWN0Lk1vdmUoZWxlbWVudCwgeyB4OiBtb3ZlWCwgeTogbW92ZVksIHN5bmM6IHRydWUsIHRyYW5zaXRpb246IG9wdGlvbnMubW92ZVRyYW5zaXRpb24gfSkKICAgIF0sIE9iamVjdC5leHRlbmQoewogICAgICAgICBiZWZvcmVTdGFydEludGVybmFsOiBmdW5jdGlvbihlZmZlY3QpIHsKICAgICAgICAgICBlZmZlY3QuZWZmZWN0c1swXS5lbGVtZW50Lm1ha2VQb3NpdGlvbmVkKCkubWFrZUNsaXBwaW5nKCk7CiAgICAgICAgIH0sCiAgICAgICAgIGFmdGVyRmluaXNoSW50ZXJuYWw6IGZ1bmN0aW9uKGVmZmVjdCkgewogICAgICAgICAgIGVmZmVjdC5lZmZlY3RzWzBdLmVsZW1lbnQuaGlkZSgpLnVuZG9DbGlwcGluZygpLnVuZG9Qb3NpdGlvbmVkKCkuc2V0U3R5bGUob2xkU3R5bGUpOyB9CiAgICAgICB9LCBvcHRpb25zKQogICk7Cn07CgpFZmZlY3QuUHVsc2F0ZSA9IGZ1bmN0aW9uKGVsZW1lbnQpIHsKICBlbGVtZW50ID0gJChlbGVtZW50KTsKICB2YXIgb3B0aW9ucyAgICA9IGFyZ3VtZW50c1sxXSB8fCB7IH0sCiAgICBvbGRPcGFjaXR5ID0gZWxlbWVudC5nZXRJbmxpbmVPcGFjaXR5KCksCiAgICB0cmFuc2l0aW9uID0gb3B0aW9ucy50cmFuc2l0aW9uIHx8IEVmZmVjdC5UcmFuc2l0aW9ucy5saW5lYXIsCiAgICByZXZlcnNlciAgID0gZnVuY3Rpb24ocG9zKXsKICAgICAgcmV0dXJuIDEgLSB0cmFuc2l0aW9uKCgtTWF0aC5jb3MoKHBvcyoob3B0aW9ucy5wdWxzZXN8fDUpKjIpKk1hdGguUEkpLzIpICsgLjUpOwogICAgfTsKCiAgcmV0dXJuIG5ldyBFZmZlY3QuT3BhY2l0eShlbGVtZW50LAogICAgT2JqZWN0LmV4dGVuZChPYmplY3QuZXh0ZW5kKHsgIGR1cmF0aW9uOiAyLjAsIGZyb206IDAsCiAgICAgIGFmdGVyRmluaXNoSW50ZXJuYWw6IGZ1bmN0aW9uKGVmZmVjdCkgeyBlZmZlY3QuZWxlbWVudC5zZXRTdHlsZSh7b3BhY2l0eTogb2xkT3BhY2l0eX0pOyB9CiAgICB9LCBvcHRpb25zKSwge3RyYW5zaXRpb246IHJldmVyc2VyfSkpOwp9OwoKRWZmZWN0LkZvbGQgPSBmdW5jdGlvbihlbGVtZW50KSB7CiAgZWxlbWVudCA9ICQoZWxlbWVudCk7CiAgdmFyIG9sZFN0eWxlID0gewogICAgdG9wOiBlbGVtZW50LnN0eWxlLnRvcCwKICAgIGxlZnQ6IGVsZW1lbnQuc3R5bGUubGVmdCwKICAgIHdpZHRoOiBlbGVtZW50LnN0eWxlLndpZHRoLAogICAgaGVpZ2h0OiBlbGVtZW50LnN0eWxlLmhlaWdodCB9OwogIGVsZW1lbnQubWFrZUNsaXBwaW5nKCk7CiAgcmV0dXJuIG5ldyBFZmZlY3QuU2NhbGUoZWxlbWVudCwgNSwgT2JqZWN0LmV4dGVuZCh7CiAgICBzY2FsZUNvbnRlbnQ6IGZhbHNlLAogICAgc2NhbGVYOiBmYWxzZSwKICAgIGFmdGVyRmluaXNoSW50ZXJuYWw6IGZ1bmN0aW9uKGVmZmVjdCkgewogICAgbmV3IEVmZmVjdC5TY2FsZShlbGVtZW50LCAxLCB7CiAgICAgIHNjYWxlQ29udGVudDogZmFsc2UsCiAgICAgIHNjYWxlWTogZmFsc2UsCiAgICAgIGFmdGVyRmluaXNoSW50ZXJuYWw6IGZ1bmN0aW9uKGVmZmVjdCkgewogICAgICAgIGVmZmVjdC5lbGVtZW50LmhpZGUoKS51bmRvQ2xpcHBpbmcoKS5zZXRTdHlsZShvbGRTdHlsZSk7CiAgICAgIH0gfSk7CiAgfX0sIGFyZ3VtZW50c1sxXSB8fCB7IH0pKTsKfTsKCkVmZmVjdC5Nb3JwaCA9IENsYXNzLmNyZWF0ZShFZmZlY3QuQmFzZSwgewogIGluaXRpYWxpemU6IGZ1bmN0aW9uKGVsZW1lbnQpIHsKICAgIHRoaXMuZWxlbWVudCA9ICQoZWxlbWVudCk7CiAgICBpZiAoIXRoaXMuZWxlbWVudCkgdGhyb3coRWZmZWN0Ll9lbGVtZW50RG9lc05vdEV4aXN0RXJyb3IpOwogICAgdmFyIG9wdGlvbnMgPSBPYmplY3QuZXh0ZW5kKHsKICAgICAgc3R5bGU6IHsgfQogICAgfSwgYXJndW1lbnRzWzFdIHx8IHsgfSk7CgogICAgaWYgKCFPYmplY3QuaXNTdHJpbmcob3B0aW9ucy5zdHlsZSkpIHRoaXMuc3R5bGUgPSAkSChvcHRpb25zLnN0eWxlKTsKICAgIGVsc2UgewogICAgICBpZiAob3B0aW9ucy5zdHlsZS5pbmNsdWRlKCc6JykpCiAgICAgICAgdGhpcy5zdHlsZSA9IG9wdGlvbnMuc3R5bGUucGFyc2VTdHlsZSgpOwogICAgICBlbHNlIHsKICAgICAgICB0aGlzLmVsZW1lbnQuYWRkQ2xhc3NOYW1lKG9wdGlvbnMuc3R5bGUpOwogICAgICAgIHRoaXMuc3R5bGUgPSAkSCh0aGlzLmVsZW1lbnQuZ2V0U3R5bGVzKCkpOwogICAgICAgIHRoaXMuZWxlbWVudC5yZW1vdmVDbGFzc05hbWUob3B0aW9ucy5zdHlsZSk7CiAgICAgICAgdmFyIGNzcyA9IHRoaXMuZWxlbWVudC5nZXRTdHlsZXMoKTsKICAgICAgICB0aGlzLnN0eWxlID0gdGhpcy5zdHlsZS5yZWplY3QoZnVuY3Rpb24oc3R5bGUpIHsKICAgICAgICAgIHJldHVybiBzdHlsZS52YWx1ZSA9PSBjc3Nbc3R5bGUua2V5XTsKICAgICAgICB9KTsKICAgICAgICBvcHRpb25zLmFmdGVyRmluaXNoSW50ZXJuYWwgPSBmdW5jdGlvbihlZmZlY3QpIHsKICAgICAgICAgIGVmZmVjdC5lbGVtZW50LmFkZENsYXNzTmFtZShlZmZlY3Qub3B0aW9ucy5zdHlsZSk7CiAgICAgICAgICBlZmZlY3QudHJhbnNmb3Jtcy5lYWNoKGZ1bmN0aW9uKHRyYW5zZm9ybSkgewogICAgICAgICAgICBlZmZlY3QuZWxlbWVudC5zdHlsZVt0cmFuc2Zvcm0uc3R5bGVdID0gJyc7CiAgICAgICAgICB9KTsKICAgICAgICB9OwogICAgICB9CiAgICB9CiAgICB0aGlzLnN0YXJ0KG9wdGlvbnMpOwogIH0sCgogIHNldHVwOiBmdW5jdGlvbigpewogICAgZnVuY3Rpb24gcGFyc2VDb2xvcihjb2xvcil7CiAgICAgIGlmICghY29sb3IgfHwgWydyZ2JhKDAsIDAsIDAsIDApJywndHJhbnNwYXJlbnQnXS5pbmNsdWRlKGNvbG9yKSkgY29sb3IgPSAnI2ZmZmZmZic7CiAgICAgIGNvbG9yID0gY29sb3IucGFyc2VDb2xvcigpOwogICAgICByZXR1cm4gJFIoMCwyKS5tYXAoZnVuY3Rpb24oaSl7CiAgICAgICAgcmV0dXJuIHBhcnNlSW50KCBjb2xvci5zbGljZShpKjIrMSxpKjIrMyksIDE2ICk7CiAgICAgIH0pOwogICAgfQogICAgdGhpcy50cmFuc2Zvcm1zID0gdGhpcy5zdHlsZS5tYXAoZnVuY3Rpb24ocGFpcil7CiAgICAgIHZhciBwcm9wZXJ0eSA9IHBhaXJbMF0sIHZhbHVlID0gcGFpclsxXSwgdW5pdCA9IG51bGw7CgogICAgICBpZiAodmFsdWUucGFyc2VDb2xvcignI3p6enp6eicpICE9ICcjenp6enp6JykgewogICAgICAgIHZhbHVlID0gdmFsdWUucGFyc2VDb2xvcigpOwogICAgICAgIHVuaXQgID0gJ2NvbG9yJzsKICAgICAgfSBlbHNlIGlmIChwcm9wZXJ0eSA9PSAnb3BhY2l0eScpIHsKICAgICAgICB2YWx1ZSA9IHBhcnNlRmxvYXQodmFsdWUpOwogICAgICAgIGlmIChQcm90b3R5cGUuQnJvd3Nlci5JRSAmJiAoIXRoaXMuZWxlbWVudC5jdXJyZW50U3R5bGUuaGFzTGF5b3V0KSkKICAgICAgICAgIHRoaXMuZWxlbWVudC5zZXRTdHlsZSh7em9vbTogMX0pOwogICAgICB9IGVsc2UgaWYgKEVsZW1lbnQuQ1NTX0xFTkdUSC50ZXN0KHZhbHVlKSkgewogICAgICAgICAgdmFyIGNvbXBvbmVudHMgPSB2YWx1ZS5tYXRjaCgvXihbXCtcLV0/WzAtOVwuXSspKC4qKSQvKTsKICAgICAgICAgIHZhbHVlID0gcGFyc2VGbG9hdChjb21wb25lbnRzWzFdKTsKICAgICAgICAgIHVuaXQgPSAoY29tcG9uZW50cy5sZW5ndGggPT0gMykgPyBjb21wb25lbnRzWzJdIDogbnVsbDsKICAgICAgfQoKICAgICAgdmFyIG9yaWdpbmFsVmFsdWUgPSB0aGlzLmVsZW1lbnQuZ2V0U3R5bGUocHJvcGVydHkpOwogICAgICByZXR1cm4gewogICAgICAgIHN0eWxlOiBwcm9wZXJ0eS5jYW1lbGl6ZSgpLAogICAgICAgIG9yaWdpbmFsVmFsdWU6IHVuaXQ9PSdjb2xvcicgPyBwYXJzZUNvbG9yKG9yaWdpbmFsVmFsdWUpIDogcGFyc2VGbG9hdChvcmlnaW5hbFZhbHVlIHx8IDApLAogICAgICAgIHRhcmdldFZhbHVlOiB1bml0PT0nY29sb3InID8gcGFyc2VDb2xvcih2YWx1ZSkgOiB2YWx1ZSwKICAgICAgICB1bml0OiB1bml0CiAgICAgIH07CiAgICB9LmJpbmQodGhpcykpLnJlamVjdChmdW5jdGlvbih0cmFuc2Zvcm0pewogICAgICByZXR1cm4gKAogICAgICAgICh0cmFuc2Zvcm0ub3JpZ2luYWxWYWx1ZSA9PSB0cmFuc2Zvcm0udGFyZ2V0VmFsdWUpIHx8CiAgICAgICAgKAogICAgICAgICAgdHJhbnNmb3JtLnVuaXQgIT0gJ2NvbG9yJyAmJgogICAgICAgICAgKGlzTmFOKHRyYW5zZm9ybS5vcmlnaW5hbFZhbHVlKSB8fCBpc05hTih0cmFuc2Zvcm0udGFyZ2V0VmFsdWUpKQogICAgICAgICkKICAgICAgKTsKICAgIH0pOwogIH0sCiAgdXBkYXRlOiBmdW5jdGlvbihwb3NpdGlvbikgewogICAgdmFyIHN0eWxlID0geyB9LCB0cmFuc2Zvcm0sIGkgPSB0aGlzLnRyYW5zZm9ybXMubGVuZ3RoOwogICAgd2hpbGUoaS0tKQogICAgICBzdHlsZVsodHJhbnNmb3JtID0gdGhpcy50cmFuc2Zvcm1zW2ldKS5zdHlsZV0gPQogICAgICAgIHRyYW5zZm9ybS51bml0PT0nY29sb3InID8gJyMnKwogICAgICAgICAgKE1hdGgucm91bmQodHJhbnNmb3JtLm9yaWdpbmFsVmFsdWVbMF0rCiAgICAgICAgICAgICh0cmFuc2Zvcm0udGFyZ2V0VmFsdWVbMF0tdHJhbnNmb3JtLm9yaWdpbmFsVmFsdWVbMF0pKnBvc2l0aW9uKSkudG9Db2xvclBhcnQoKSArCiAgICAgICAgICAoTWF0aC5yb3VuZCh0cmFuc2Zvcm0ub3JpZ2luYWxWYWx1ZVsxXSsKICAgICAgICAgICAgKHRyYW5zZm9ybS50YXJnZXRWYWx1ZVsxXS10cmFuc2Zvcm0ub3JpZ2luYWxWYWx1ZVsxXSkqcG9zaXRpb24pKS50b0NvbG9yUGFydCgpICsKICAgICAgICAgIChNYXRoLnJvdW5kKHRyYW5zZm9ybS5vcmlnaW5hbFZhbHVlWzJdKwogICAgICAgICAgICAodHJhbnNmb3JtLnRhcmdldFZhbHVlWzJdLXRyYW5zZm9ybS5vcmlnaW5hbFZhbHVlWzJdKSpwb3NpdGlvbikpLnRvQ29sb3JQYXJ0KCkgOgogICAgICAgICh0cmFuc2Zvcm0ub3JpZ2luYWxWYWx1ZSArCiAgICAgICAgICAodHJhbnNmb3JtLnRhcmdldFZhbHVlIC0gdHJhbnNmb3JtLm9yaWdpbmFsVmFsdWUpICogcG9zaXRpb24pLnRvRml4ZWQoMykgKwogICAgICAgICAgICAodHJhbnNmb3JtLnVuaXQgPT09IG51bGwgPyAnJyA6IHRyYW5zZm9ybS51bml0KTsKICAgIHRoaXMuZWxlbWVudC5zZXRTdHlsZShzdHlsZSwgdHJ1ZSk7CiAgfQp9KTsKCkVmZmVjdC5UcmFuc2Zvcm0gPSBDbGFzcy5jcmVhdGUoewogIGluaXRpYWxpemU6IGZ1bmN0aW9uKHRyYWNrcyl7CiAgICB0aGlzLnRyYWNrcyAgPSBbXTsKICAgIHRoaXMub3B0aW9ucyA9IGFyZ3VtZW50c1sxXSB8fCB7IH07CiAgICB0aGlzLmFkZFRyYWNrcyh0cmFja3MpOwogIH0sCiAgYWRkVHJhY2tzOiBmdW5jdGlvbih0cmFja3MpewogICAgdHJhY2tzLmVhY2goZnVuY3Rpb24odHJhY2spewogICAgICB0cmFjayA9ICRIKHRyYWNrKTsKICAgICAgdmFyIGRhdGEgPSB0cmFjay52YWx1ZXMoKS5maXJzdCgpOwogICAgICB0aGlzLnRyYWNrcy5wdXNoKCRIKHsKICAgICAgICBpZHM6ICAgICB0cmFjay5rZXlzKCkuZmlyc3QoKSwKICAgICAgICBlZmZlY3Q6ICBFZmZlY3QuTW9ycGgsCiAgICAgICAgb3B0aW9uczogeyBzdHlsZTogZGF0YSB9CiAgICAgIH0pKTsKICAgIH0uYmluZCh0aGlzKSk7CiAgICByZXR1cm4gdGhpczsKICB9LAogIHBsYXk6IGZ1bmN0aW9uKCl7CiAgICByZXR1cm4gbmV3IEVmZmVjdC5QYXJhbGxlbCgKICAgICAgdGhpcy50cmFja3MubWFwKGZ1bmN0aW9uKHRyYWNrKXsKICAgICAgICB2YXIgaWRzID0gdHJhY2suZ2V0KCdpZHMnKSwgZWZmZWN0ID0gdHJhY2suZ2V0KCdlZmZlY3QnKSwgb3B0aW9ucyA9IHRyYWNrLmdldCgnb3B0aW9ucycpOwogICAgICAgIHZhciBlbGVtZW50cyA9IFskKGlkcykgfHwgJCQoaWRzKV0uZmxhdHRlbigpOwogICAgICAgIHJldHVybiBlbGVtZW50cy5tYXAoZnVuY3Rpb24oZSl7IHJldHVybiBuZXcgZWZmZWN0KGUsIE9iamVjdC5leHRlbmQoeyBzeW5jOnRydWUgfSwgb3B0aW9ucykpIH0pOwogICAgICB9KS5mbGF0dGVuKCksCiAgICAgIHRoaXMub3B0aW9ucwogICAgKTsKICB9Cn0pOwoKRWxlbWVudC5DU1NfUFJPUEVSVElFUyA9ICR3KAogICdiYWNrZ3JvdW5kQ29sb3IgYmFja2dyb3VuZFBvc2l0aW9uIGJvcmRlckJvdHRvbUNvbG9yIGJvcmRlckJvdHRvbVN0eWxlICcgKwogICdib3JkZXJCb3R0b21XaWR0aCBib3JkZXJMZWZ0Q29sb3IgYm9yZGVyTGVmdFN0eWxlIGJvcmRlckxlZnRXaWR0aCAnICsKICAnYm9yZGVyUmlnaHRDb2xvciBib3JkZXJSaWdodFN0eWxlIGJvcmRlclJpZ2h0V2lkdGggYm9yZGVyU3BhY2luZyAnICsKICAnYm9yZGVyVG9wQ29sb3IgYm9yZGVyVG9wU3R5bGUgYm9yZGVyVG9wV2lkdGggYm90dG9tIGNsaXAgY29sb3IgJyArCiAgJ2ZvbnRTaXplIGZvbnRXZWlnaHQgaGVpZ2h0IGxlZnQgbGV0dGVyU3BhY2luZyBsaW5lSGVpZ2h0ICcgKwogICdtYXJnaW5Cb3R0b20gbWFyZ2luTGVmdCBtYXJnaW5SaWdodCBtYXJnaW5Ub3AgbWFya2VyT2Zmc2V0IG1heEhlaWdodCAnKwogICdtYXhXaWR0aCBtaW5IZWlnaHQgbWluV2lkdGggb3BhY2l0eSBvdXRsaW5lQ29sb3Igb3V0bGluZU9mZnNldCAnICsKICAnb3V0bGluZVdpZHRoIHBhZGRpbmdCb3R0b20gcGFkZGluZ0xlZnQgcGFkZGluZ1JpZ2h0IHBhZGRpbmdUb3AgJyArCiAgJ3JpZ2h0IHRleHRJbmRlbnQgdG9wIHdpZHRoIHdvcmRTcGFjaW5nIHpJbmRleCcpOwoKRWxlbWVudC5DU1NfTEVOR1RIID0gL14oKFtcK1wtXT9bMC05XC5dKykoZW18ZXh8cHh8aW58Y218bW18cHR8cGN8XCUpKXwwJC87CgpTdHJpbmcuX19wYXJzZVN0eWxlRWxlbWVudCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2RpdicpOwpTdHJpbmcucHJvdG90eXBlLnBhcnNlU3R5bGUgPSBmdW5jdGlvbigpewogIHZhciBzdHlsZSwgc3R5bGVSdWxlcyA9ICRIKCk7CiAgaWYgKFByb3RvdHlwZS5Ccm93c2VyLldlYktpdCkKICAgIHN0eWxlID0gbmV3IEVsZW1lbnQoJ2Rpdicse3N0eWxlOnRoaXN9KS5zdHlsZTsKICBlbHNlIHsKICAgIFN0cmluZy5fX3BhcnNlU3R5bGVFbGVtZW50LmlubmVySFRNTCA9ICc8ZGl2IHN0eWxlPSInICsgdGhpcyArICciPjwvZGl2Pic7CiAgICBzdHlsZSA9IFN0cmluZy5fX3BhcnNlU3R5bGVFbGVtZW50LmNoaWxkTm9kZXNbMF0uc3R5bGU7CiAgfQoKICBFbGVtZW50LkNTU19QUk9QRVJUSUVTLmVhY2goZnVuY3Rpb24ocHJvcGVydHkpewogICAgaWYgKHN0eWxlW3Byb3BlcnR5XSkgc3R5bGVSdWxlcy5zZXQocHJvcGVydHksIHN0eWxlW3Byb3BlcnR5XSk7CiAgfSk7CgogIGlmIChQcm90b3R5cGUuQnJvd3Nlci5JRSAmJiB0aGlzLmluY2x1ZGUoJ29wYWNpdHknKSkKICAgIHN0eWxlUnVsZXMuc2V0KCdvcGFjaXR5JywgdGhpcy5tYXRjaCgvb3BhY2l0eTpccyooKD86MHwxKT8oPzpcLlxkKik/KS8pWzFdKTsKCiAgcmV0dXJuIHN0eWxlUnVsZXM7Cn07CgppZiAoZG9jdW1lbnQuZGVmYXVsdFZpZXcgJiYgZG9jdW1lbnQuZGVmYXVsdFZpZXcuZ2V0Q29tcHV0ZWRTdHlsZSkgewogIEVsZW1lbnQuZ2V0U3R5bGVzID0gZnVuY3Rpb24oZWxlbWVudCkgewogICAgdmFyIGNzcyA9IGRvY3VtZW50LmRlZmF1bHRWaWV3LmdldENvbXB1dGVkU3R5bGUoJChlbGVtZW50KSwgbnVsbCk7CiAgICByZXR1cm4gRWxlbWVudC5DU1NfUFJPUEVSVElFUy5pbmplY3QoeyB9LCBmdW5jdGlvbihzdHlsZXMsIHByb3BlcnR5KSB7CiAgICAgIHN0eWxlc1twcm9wZXJ0eV0gPSBjc3NbcHJvcGVydHldOwogICAgICByZXR1cm4gc3R5bGVzOwogICAgfSk7CiAgfTsKfSBlbHNlIHsKICBFbGVtZW50LmdldFN0eWxlcyA9IGZ1bmN0aW9uKGVsZW1lbnQpIHsKICAgIGVsZW1lbnQgPSAkKGVsZW1lbnQpOwogICAgdmFyIGNzcyA9IGVsZW1lbnQuY3VycmVudFN0eWxlLCBzdHlsZXM7CiAgICBzdHlsZXMgPSBFbGVtZW50LkNTU19QUk9QRVJUSUVTLmluamVjdCh7IH0sIGZ1bmN0aW9uKHJlc3VsdHMsIHByb3BlcnR5KSB7CiAgICAgIHJlc3VsdHNbcHJvcGVydHldID0gY3NzW3Byb3BlcnR5XTsKICAgICAgcmV0dXJuIHJlc3VsdHM7CiAgICB9KTsKICAgIGlmICghc3R5bGVzLm9wYWNpdHkpIHN0eWxlcy5vcGFjaXR5ID0gZWxlbWVudC5nZXRPcGFjaXR5KCk7CiAgICByZXR1cm4gc3R5bGVzOwogIH07Cn0KCkVmZmVjdC5NZXRob2RzID0gewogIG1vcnBoOiBmdW5jdGlvbihlbGVtZW50LCBzdHlsZSkgewogICAgZWxlbWVudCA9ICQoZWxlbWVudCk7CiAgICBuZXcgRWZmZWN0Lk1vcnBoKGVsZW1lbnQsIE9iamVjdC5leHRlbmQoeyBzdHlsZTogc3R5bGUgfSwgYXJndW1lbnRzWzJdIHx8IHsgfSkpOwogICAgcmV0dXJuIGVsZW1lbnQ7CiAgfSwKICB2aXN1YWxFZmZlY3Q6IGZ1bmN0aW9uKGVsZW1lbnQsIGVmZmVjdCwgb3B0aW9ucykgewogICAgZWxlbWVudCA9ICQoZWxlbWVudCk7CiAgICB2YXIgcyA9IGVmZmVjdC5kYXNoZXJpemUoKS5jYW1lbGl6ZSgpLCBrbGFzcyA9IHMuY2hhckF0KDApLnRvVXBwZXJDYXNlKCkgKyBzLnN1YnN0cmluZygxKTsKICAgIG5ldyBFZmZlY3Rba2xhc3NdKGVsZW1lbnQsIG9wdGlvbnMpOwogICAgcmV0dXJuIGVsZW1lbnQ7CiAgfSwKICBoaWdobGlnaHQ6IGZ1bmN0aW9uKGVsZW1lbnQsIG9wdGlvbnMpIHsKICAgIGVsZW1lbnQgPSAkKGVsZW1lbnQpOwogICAgbmV3IEVmZmVjdC5IaWdobGlnaHQoZWxlbWVudCwgb3B0aW9ucyk7CiAgICByZXR1cm4gZWxlbWVudDsKICB9Cn07CgokdygnZmFkZSBhcHBlYXIgZ3JvdyBzaHJpbmsgZm9sZCBibGluZFVwIGJsaW5kRG93biBzbGlkZVVwIHNsaWRlRG93biAnKwogICdwdWxzYXRlIHNoYWtlIHB1ZmYgc3F1aXNoIHN3aXRjaE9mZiBkcm9wT3V0JykuZWFjaCgKICBmdW5jdGlvbihlZmZlY3QpIHsKICAgIEVmZmVjdC5NZXRob2RzW2VmZmVjdF0gPSBmdW5jdGlvbihlbGVtZW50LCBvcHRpb25zKXsKICAgICAgZWxlbWVudCA9ICQoZWxlbWVudCk7CiAgICAgIEVmZmVjdFtlZmZlY3QuY2hhckF0KDApLnRvVXBwZXJDYXNlKCkgKyBlZmZlY3Quc3Vic3RyaW5nKDEpXShlbGVtZW50LCBvcHRpb25zKTsKICAgICAgcmV0dXJuIGVsZW1lbnQ7CiAgICB9OwogIH0KKTsKCiR3KCdnZXRJbmxpbmVPcGFjaXR5IGZvcmNlUmVyZW5kZXJpbmcgc2V0Q29udGVudFpvb20gY29sbGVjdFRleHROb2RlcyBjb2xsZWN0VGV4dE5vZGVzSWdub3JlQ2xhc3MgZ2V0U3R5bGVzJykuZWFjaCgKICBmdW5jdGlvbihmKSB7IEVmZmVjdC5NZXRob2RzW2ZdID0gRWxlbWVudFtmXTsgfQopOwoKRWxlbWVudC5hZGRNZXRob2RzKEVmZmVjdC5NZXRob2RzKTs=]]></data>
	</file>
	<file>
	  <filename>/js/scriptaculous.js</filename>
	  <isdir>0</isdir>
	  <data><![CDATA[Ly8gc2NyaXB0LmFjdWxvLnVzIHNjcmlwdGFjdWxvdXMuanMgdjEuOS4wLCBUaHUgRGVjIDIzIDE2OjU0OjQ4IC0wNTAwIDIwMTAKCi8vIENvcHlyaWdodCAoYykgMjAwNS0yMDEwIFRob21hcyBGdWNocyAoaHR0cDovL3NjcmlwdC5hY3Vsby51cywgaHR0cDovL21pci5hY3Vsby51cykKLy8KLy8gUGVybWlzc2lvbiBpcyBoZXJlYnkgZ3JhbnRlZCwgZnJlZSBvZiBjaGFyZ2UsIHRvIGFueSBwZXJzb24gb2J0YWluaW5nCi8vIGEgY29weSBvZiB0aGlzIHNvZnR3YXJlIGFuZCBhc3NvY2lhdGVkIGRvY3VtZW50YXRpb24gZmlsZXMgKHRoZQovLyAiU29mdHdhcmUiKSwgdG8gZGVhbCBpbiB0aGUgU29mdHdhcmUgd2l0aG91dCByZXN0cmljdGlvbiwgaW5jbHVkaW5nCi8vIHdpdGhvdXQgbGltaXRhdGlvbiB0aGUgcmlnaHRzIHRvIHVzZSwgY29weSwgbW9kaWZ5LCBtZXJnZSwgcHVibGlzaCwKLy8gZGlzdHJpYnV0ZSwgc3VibGljZW5zZSwgYW5kL29yIHNlbGwgY29waWVzIG9mIHRoZSBTb2Z0d2FyZSwgYW5kIHRvCi8vIHBlcm1pdCBwZXJzb25zIHRvIHdob20gdGhlIFNvZnR3YXJlIGlzIGZ1cm5pc2hlZCB0byBkbyBzbywgc3ViamVjdCB0bwovLyB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnM6Ci8vCi8vIFRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlIGFuZCB0aGlzIHBlcm1pc3Npb24gbm90aWNlIHNoYWxsIGJlCi8vIGluY2x1ZGVkIGluIGFsbCBjb3BpZXMgb3Igc3Vic3RhbnRpYWwgcG9ydGlvbnMgb2YgdGhlIFNvZnR3YXJlLgovLwovLyBUSEUgU09GVFdBUkUgSVMgUFJPVklERUQgIkFTIElTIiwgV0lUSE9VVCBXQVJSQU5UWSBPRiBBTlkgS0lORCwKLy8gRVhQUkVTUyBPUiBJTVBMSUVELCBJTkNMVURJTkcgQlVUIE5PVCBMSU1JVEVEIFRPIFRIRSBXQVJSQU5USUVTIE9GCi8vIE1FUkNIQU5UQUJJTElUWSwgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQU5ECi8vIE5PTklORlJJTkdFTUVOVC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFVVEhPUlMgT1IgQ09QWVJJR0hUIEhPTERFUlMgQkUKLy8gTElBQkxFIEZPUiBBTlkgQ0xBSU0sIERBTUFHRVMgT1IgT1RIRVIgTElBQklMSVRZLCBXSEVUSEVSIElOIEFOIEFDVElPTgovLyBPRiBDT05UUkFDVCwgVE9SVCBPUiBPVEhFUldJU0UsIEFSSVNJTkcgRlJPTSwgT1VUIE9GIE9SIElOIENPTk5FQ1RJT04KLy8gV0lUSCBUSEUgU09GVFdBUkUgT1IgVEhFIFVTRSBPUiBPVEhFUiBERUFMSU5HUyBJTiBUSEUgU09GVFdBUkUuCi8vCi8vIEZvciBkZXRhaWxzLCBzZWUgdGhlIHNjcmlwdC5hY3Vsby51cyB3ZWIgc2l0ZTogaHR0cDovL3NjcmlwdC5hY3Vsby51cy8KCnZhciBTY3JpcHRhY3Vsb3VzID0gewogIFZlcnNpb246ICcxLjkuMCcsCiAgcmVxdWlyZTogZnVuY3Rpb24obGlicmFyeU5hbWUpIHsKICAgIHRyeXsKICAgICAgLy8gaW5zZXJ0aW5nIHZpYSBET00gZmFpbHMgaW4gU2FmYXJpIDIuMCwgc28gYnJ1dGUgZm9yY2UgYXBwcm9hY2gKICAgICAgZG9jdW1lbnQud3JpdGUoJzxzY3JpcHQgdHlwZT0idGV4dC9qYXZhc2NyaXB0IiBzcmM9IicrbGlicmFyeU5hbWUrJyI+PFwvc2NyaXB0PicpOwogICAgfSBjYXRjaChlKSB7CiAgICAgIC8vIGZvciB4aHRtbCt4bWwgc2VydmVkIGNvbnRlbnQsIGZhbGwgYmFjayB0byBET00gbWV0aG9kcwogICAgICB2YXIgc2NyaXB0ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnc2NyaXB0Jyk7CiAgICAgIHNjcmlwdC50eXBlID0gJ3RleHQvamF2YXNjcmlwdCc7CiAgICAgIHNjcmlwdC5zcmMgPSBsaWJyYXJ5TmFtZTsKICAgICAgZG9jdW1lbnQuZ2V0RWxlbWVudHNCeVRhZ05hbWUoJ2hlYWQnKVswXS5hcHBlbmRDaGlsZChzY3JpcHQpOwogICAgfQogIH0sCiAgUkVRVUlSRURfUFJPVE9UWVBFOiAnMS42LjAuMycsCiAgbG9hZDogZnVuY3Rpb24oKSB7CiAgICBmdW5jdGlvbiBjb252ZXJ0VmVyc2lvblN0cmluZyh2ZXJzaW9uU3RyaW5nKSB7CiAgICAgIHZhciB2ID0gdmVyc2lvblN0cmluZy5yZXBsYWNlKC9fLip8XC4vZywgJycpOwogICAgICB2ID0gcGFyc2VJbnQodiArICcwJy50aW1lcyg0LXYubGVuZ3RoKSk7CiAgICAgIHJldHVybiB2ZXJzaW9uU3RyaW5nLmluZGV4T2YoJ18nKSA+IC0xID8gdi0xIDogdjsKICAgIH0KCiAgICBpZigodHlwZW9mIFByb3RvdHlwZT09J3VuZGVmaW5lZCcpIHx8CiAgICAgICAodHlwZW9mIEVsZW1lbnQgPT0gJ3VuZGVmaW5lZCcpIHx8CiAgICAgICAodHlwZW9mIEVsZW1lbnQuTWV0aG9kcz09J3VuZGVmaW5lZCcpIHx8CiAgICAgICAoY29udmVydFZlcnNpb25TdHJpbmcoUHJvdG90eXBlLlZlcnNpb24pIDwKICAgICAgICBjb252ZXJ0VmVyc2lvblN0cmluZyhTY3JpcHRhY3Vsb3VzLlJFUVVJUkVEX1BST1RPVFlQRSkpKQogICAgICAgdGhyb3coInNjcmlwdC5hY3Vsby51cyByZXF1aXJlcyB0aGUgUHJvdG90eXBlIEphdmFTY3JpcHQgZnJhbWV3b3JrID49ICIgKwogICAgICAgIFNjcmlwdGFjdWxvdXMuUkVRVUlSRURfUFJPVE9UWVBFKTsKCiAgICB2YXIganMgPSAvc2NyaXB0YWN1bG91c1wuanMoXD8uKik/JC87CiAgICAkJCgnc2NyaXB0W3NyY10nKS5maW5kQWxsKGZ1bmN0aW9uKHMpIHsKICAgICAgcmV0dXJuIHMuc3JjLm1hdGNoKGpzKTsKICAgIH0pLmVhY2goZnVuY3Rpb24ocykgewogICAgICB2YXIgcGF0aCA9IHMuc3JjLnJlcGxhY2UoanMsICcnKSwKICAgICAgaW5jbHVkZXMgPSBzLnNyYy5tYXRjaCgvXD8uKmxvYWQ9KFthLXosXSopLyk7CiAgICAgIChpbmNsdWRlcyA/IGluY2x1ZGVzWzFdIDogJ2J1aWxkZXIsZWZmZWN0cyxkcmFnZHJvcCxjb250cm9scyxzbGlkZXIsc291bmQnKS5zcGxpdCgnLCcpLmVhY2goCiAgICAgICBmdW5jdGlvbihpbmNsdWRlKSB7IFNjcmlwdGFjdWxvdXMucmVxdWlyZShwYXRoK2luY2x1ZGUrJy5qcycpIH0pOwogICAgfSk7CiAgfQp9OwoKU2NyaXB0YWN1bG91cy5sb2FkKCk7]]></data>
	</file>
	<file>
	  <filename>/js/builder.js</filename>
	  <isdir>0</isdir>
	  <data><![CDATA[Ly8gc2NyaXB0LmFjdWxvLnVzIGJ1aWxkZXIuanMgdjEuOS4wLCBUaHUgRGVjIDIzIDE2OjU0OjQ4IC0wNTAwIDIwMTAKCi8vIENvcHlyaWdodCAoYykgMjAwNS0yMDEwIFRob21hcyBGdWNocyAoaHR0cDovL3NjcmlwdC5hY3Vsby51cywgaHR0cDovL21pci5hY3Vsby51cykKLy8KLy8gc2NyaXB0LmFjdWxvLnVzIGlzIGZyZWVseSBkaXN0cmlidXRhYmxlIHVuZGVyIHRoZSB0ZXJtcyBvZiBhbiBNSVQtc3R5bGUgbGljZW5zZS4KLy8gRm9yIGRldGFpbHMsIHNlZSB0aGUgc2NyaXB0LmFjdWxvLnVzIHdlYiBzaXRlOiBodHRwOi8vc2NyaXB0LmFjdWxvLnVzLwoKdmFyIEJ1aWxkZXIgPSB7CiAgTk9ERU1BUDogewogICAgQVJFQTogJ21hcCcsCiAgICBDQVBUSU9OOiAndGFibGUnLAogICAgQ09MOiAndGFibGUnLAogICAgQ09MR1JPVVA6ICd0YWJsZScsCiAgICBMRUdFTkQ6ICdmaWVsZHNldCcsCiAgICBPUFRHUk9VUDogJ3NlbGVjdCcsCiAgICBPUFRJT046ICdzZWxlY3QnLAogICAgUEFSQU06ICdvYmplY3QnLAogICAgVEJPRFk6ICd0YWJsZScsCiAgICBURDogJ3RhYmxlJywKICAgIFRGT09UOiAndGFibGUnLAogICAgVEg6ICd0YWJsZScsCiAgICBUSEVBRDogJ3RhYmxlJywKICAgIFRSOiAndGFibGUnCiAgfSwKICAvLyBub3RlOiBGb3IgRmlyZWZveCA8IDEuNSwgT1BUSU9OIGFuZCBPUFRHUk9VUCB0YWdzIGFyZSBjdXJyZW50bHkgYnJva2VuLAogIC8vICAgICAgIGR1ZSB0byBhIEZpcmVmb3ggYnVnCiAgbm9kZTogZnVuY3Rpb24oZWxlbWVudE5hbWUpIHsKICAgIGVsZW1lbnROYW1lID0gZWxlbWVudE5hbWUudG9VcHBlckNhc2UoKTsKCiAgICAvLyB0cnkgaW5uZXJIVE1MIGFwcHJvYWNoCiAgICB2YXIgcGFyZW50VGFnID0gdGhpcy5OT0RFTUFQW2VsZW1lbnROYW1lXSB8fCAnZGl2JzsKICAgIHZhciBwYXJlbnRFbGVtZW50ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudChwYXJlbnRUYWcpOwogICAgdHJ5IHsgLy8gcHJldmVudCBJRSAiZmVhdHVyZSI6IGh0dHA6Ly9kZXYucnVieW9ucmFpbHMub3JnL3RpY2tldC8yNzA3CiAgICAgIHBhcmVudEVsZW1lbnQuaW5uZXJIVE1MID0gIjwiICsgZWxlbWVudE5hbWUgKyAiPjwvIiArIGVsZW1lbnROYW1lICsgIj4iOwogICAgfSBjYXRjaChlKSB7fQogICAgdmFyIGVsZW1lbnQgPSBwYXJlbnRFbGVtZW50LmZpcnN0Q2hpbGQgfHwgbnVsbDsKCiAgICAvLyBzZWUgaWYgYnJvd3NlciBhZGRlZCB3cmFwcGluZyB0YWdzCiAgICBpZihlbGVtZW50ICYmIChlbGVtZW50LnRhZ05hbWUudG9VcHBlckNhc2UoKSAhPSBlbGVtZW50TmFtZSkpCiAgICAgIGVsZW1lbnQgPSBlbGVtZW50LmdldEVsZW1lbnRzQnlUYWdOYW1lKGVsZW1lbnROYW1lKVswXTsKCiAgICAvLyBmYWxsYmFjayB0byBjcmVhdGVFbGVtZW50IGFwcHJvYWNoCiAgICBpZighZWxlbWVudCkgZWxlbWVudCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoZWxlbWVudE5hbWUpOwoKICAgIC8vIGFib3J0IGlmIG5vdGhpbmcgY291bGQgYmUgY3JlYXRlZAogICAgaWYoIWVsZW1lbnQpIHJldHVybjsKCiAgICAvLyBhdHRyaWJ1dGVzIChvciB0ZXh0KQogICAgaWYoYXJndW1lbnRzWzFdKQogICAgICBpZih0aGlzLl9pc1N0cmluZ09yTnVtYmVyKGFyZ3VtZW50c1sxXSkgfHwKICAgICAgICAoYXJndW1lbnRzWzFdIGluc3RhbmNlb2YgQXJyYXkpIHx8CiAgICAgICAgYXJndW1lbnRzWzFdLnRhZ05hbWUpIHsKICAgICAgICAgIHRoaXMuX2NoaWxkcmVuKGVsZW1lbnQsIGFyZ3VtZW50c1sxXSk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHZhciBhdHRycyA9IHRoaXMuX2F0dHJpYnV0ZXMoYXJndW1lbnRzWzFdKTsKICAgICAgICAgIGlmKGF0dHJzLmxlbmd0aCkgewogICAgICAgICAgICB0cnkgeyAvLyBwcmV2ZW50IElFICJmZWF0dXJlIjogaHR0cDovL2Rldi5ydWJ5b25yYWlscy5vcmcvdGlja2V0LzI3MDcKICAgICAgICAgICAgICBwYXJlbnRFbGVtZW50LmlubmVySFRNTCA9ICI8IiArZWxlbWVudE5hbWUgKyAiICIgKwogICAgICAgICAgICAgICAgYXR0cnMgKyAiPjwvIiArIGVsZW1lbnROYW1lICsgIj4iOwogICAgICAgICAgICB9IGNhdGNoKGUpIHt9CiAgICAgICAgICAgIGVsZW1lbnQgPSBwYXJlbnRFbGVtZW50LmZpcnN0Q2hpbGQgfHwgbnVsbDsKICAgICAgICAgICAgLy8gd29ya2Fyb3VuZCBmaXJlZm94IDEuMC5YIGJ1ZwogICAgICAgICAgICBpZighZWxlbWVudCkgewogICAgICAgICAgICAgIGVsZW1lbnQgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KGVsZW1lbnROYW1lKTsKICAgICAgICAgICAgICBmb3IoYXR0ciBpbiBhcmd1bWVudHNbMV0pCiAgICAgICAgICAgICAgICBlbGVtZW50W2F0dHIgPT0gJ2NsYXNzJyA/ICdjbGFzc05hbWUnIDogYXR0cl0gPSBhcmd1bWVudHNbMV1bYXR0cl07CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYoZWxlbWVudC50YWdOYW1lLnRvVXBwZXJDYXNlKCkgIT0gZWxlbWVudE5hbWUpCiAgICAgICAgICAgICAgZWxlbWVudCA9IHBhcmVudEVsZW1lbnQuZ2V0RWxlbWVudHNCeVRhZ05hbWUoZWxlbWVudE5hbWUpWzBdOwogICAgICAgICAgfQogICAgICAgIH0KCiAgICAvLyB0ZXh0LCBvciBhcnJheSBvZiBjaGlsZHJlbgogICAgaWYoYXJndW1lbnRzWzJdKQogICAgICB0aGlzLl9jaGlsZHJlbihlbGVtZW50LCBhcmd1bWVudHNbMl0pOwoKICAgICByZXR1cm4gJChlbGVtZW50KTsKICB9LAogIF90ZXh0OiBmdW5jdGlvbih0ZXh0KSB7CiAgICAgcmV0dXJuIGRvY3VtZW50LmNyZWF0ZVRleHROb2RlKHRleHQpOwogIH0sCgogIEFUVFJfTUFQOiB7CiAgICAnY2xhc3NOYW1lJzogJ2NsYXNzJywKICAgICdodG1sRm9yJzogJ2ZvcicKICB9LAoKICBfYXR0cmlidXRlczogZnVuY3Rpb24oYXR0cmlidXRlcykgewogICAgdmFyIGF0dHJzID0gW107CiAgICBmb3IoYXR0cmlidXRlIGluIGF0dHJpYnV0ZXMpCiAgICAgIGF0dHJzLnB1c2goKGF0dHJpYnV0ZSBpbiB0aGlzLkFUVFJfTUFQID8gdGhpcy5BVFRSX01BUFthdHRyaWJ1dGVdIDogYXR0cmlidXRlKSArCiAgICAgICAgICAnPSInICsgYXR0cmlidXRlc1thdHRyaWJ1dGVdLnRvU3RyaW5nKCkuZXNjYXBlSFRNTCgpLmdzdWIoLyIvLCcmcXVvdDsnKSArICciJyk7CiAgICByZXR1cm4gYXR0cnMuam9pbigiICIpOwogIH0sCiAgX2NoaWxkcmVuOiBmdW5jdGlvbihlbGVtZW50LCBjaGlsZHJlbikgewogICAgaWYoY2hpbGRyZW4udGFnTmFtZSkgewogICAgICBlbGVtZW50LmFwcGVuZENoaWxkKGNoaWxkcmVuKTsKICAgICAgcmV0dXJuOwogICAgfQogICAgaWYodHlwZW9mIGNoaWxkcmVuPT0nb2JqZWN0JykgeyAvLyBhcnJheSBjYW4gaG9sZCBub2RlcyBhbmQgdGV4dAogICAgICBjaGlsZHJlbi5mbGF0dGVuKCkuZWFjaCggZnVuY3Rpb24oZSkgewogICAgICAgIGlmKHR5cGVvZiBlPT0nb2JqZWN0JykKICAgICAgICAgIGVsZW1lbnQuYXBwZW5kQ2hpbGQoZSk7CiAgICAgICAgZWxzZQogICAgICAgICAgaWYoQnVpbGRlci5faXNTdHJpbmdPck51bWJlcihlKSkKICAgICAgICAgICAgZWxlbWVudC5hcHBlbmRDaGlsZChCdWlsZGVyLl90ZXh0KGUpKTsKICAgICAgfSk7CiAgICB9IGVsc2UKICAgICAgaWYoQnVpbGRlci5faXNTdHJpbmdPck51bWJlcihjaGlsZHJlbikpCiAgICAgICAgZWxlbWVudC5hcHBlbmRDaGlsZChCdWlsZGVyLl90ZXh0KGNoaWxkcmVuKSk7CiAgfSwKICBfaXNTdHJpbmdPck51bWJlcjogZnVuY3Rpb24ocGFyYW0pIHsKICAgIHJldHVybih0eXBlb2YgcGFyYW09PSdzdHJpbmcnIHx8IHR5cGVvZiBwYXJhbT09J251bWJlcicpOwogIH0sCiAgYnVpbGQ6IGZ1bmN0aW9uKGh0bWwpIHsKICAgIHZhciBlbGVtZW50ID0gdGhpcy5ub2RlKCdkaXYnKTsKICAgICQoZWxlbWVudCkudXBkYXRlKGh0bWwuc3RyaXAoKSk7CiAgICByZXR1cm4gZWxlbWVudC5kb3duKCk7CiAgfSwKICBkdW1wOiBmdW5jdGlvbihzY29wZSkgewogICAgaWYodHlwZW9mIHNjb3BlICE9ICdvYmplY3QnICYmIHR5cGVvZiBzY29wZSAhPSAnZnVuY3Rpb24nKSBzY29wZSA9IHdpbmRvdzsgLy9nbG9iYWwgc2NvcGUKCiAgICB2YXIgdGFncyA9ICgiQSBBQkJSIEFDUk9OWU0gQUREUkVTUyBBUFBMRVQgQVJFQSBCIEJBU0UgQkFTRUZPTlQgQkRPIEJJRyBCTE9DS1FVT1RFIEJPRFkgIiArCiAgICAgICJCUiBCVVRUT04gQ0FQVElPTiBDRU5URVIgQ0lURSBDT0RFIENPTCBDT0xHUk9VUCBERCBERUwgREZOIERJUiBESVYgREwgRFQgRU0gRklFTERTRVQgIiArCiAgICAgICJGT05UIEZPUk0gRlJBTUUgRlJBTUVTRVQgSDEgSDIgSDMgSDQgSDUgSDYgSEVBRCBIUiBIVE1MIEkgSUZSQU1FIElNRyBJTlBVVCBJTlMgSVNJTkRFWCAiKwogICAgICAiS0JEIExBQkVMIExFR0VORCBMSSBMSU5LIE1BUCBNRU5VIE1FVEEgTk9GUkFNRVMgTk9TQ1JJUFQgT0JKRUNUIE9MIE9QVEdST1VQIE9QVElPTiBQICIrCiAgICAgICJQQVJBTSBQUkUgUSBTIFNBTVAgU0NSSVBUIFNFTEVDVCBTTUFMTCBTUEFOIFNUUklLRSBTVFJPTkcgU1RZTEUgU1VCIFNVUCBUQUJMRSBUQk9EWSBURCAiKwogICAgICAiVEVYVEFSRUEgVEZPT1QgVEggVEhFQUQgVElUTEUgVFIgVFQgVSBVTCBWQVIiKS5zcGxpdCgvXHMrLyk7CgogICAgdGFncy5lYWNoKCBmdW5jdGlvbih0YWcpewogICAgICBzY29wZVt0YWddID0gZnVuY3Rpb24oKSB7CiAgICAgICAgcmV0dXJuIEJ1aWxkZXIubm9kZS5hcHBseShCdWlsZGVyLCBbdGFnXS5jb25jYXQoJEEoYXJndW1lbnRzKSkpOwogICAgICB9OwogICAgfSk7CiAgfQp9Ow==]]></data>
	</file>
	<file>
	  <filename>/js/lightbox.js</filename>
	  <isdir>0</isdir>
	  <data><![CDATA[Ly8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0NCi8vDQovLwlMaWdodGJveCB2Mi4wNQ0KLy8JYnkgTG9rZXNoIERoYWthciAtIGh0dHA6Ly93d3cubG9rZXNoZGhha2FyLmNvbQ0KLy8JTGFzdCBNb2RpZmljYXRpb246IDMvMTgvMTENCi8vDQovLwlGb3IgbW9yZSBpbmZvcm1hdGlvbiwgdmlzaXQ6DQovLwlodHRwOi8vbG9rZXNoZGhha2FyLmNvbS9wcm9qZWN0cy9saWdodGJveDIvDQovLw0KLy8JTGljZW5zZWQgdW5kZXIgdGhlIENyZWF0aXZlIENvbW1vbnMgQXR0cmlidXRpb24gMi41IExpY2Vuc2UgLSBodHRwOi8vY3JlYXRpdmVjb21tb25zLm9yZy9saWNlbnNlcy9ieS8yLjUvDQovLyAgCS0gRnJlZSBmb3IgdXNlIGluIGJvdGggcGVyc29uYWwgYW5kIGNvbW1lcmNpYWwgcHJvamVjdHMNCi8vCQktIEF0dHJpYnV0aW9uIHJlcXVpcmVzIGxlYXZpbmcgYXV0aG9yIG5hbWUsIGF1dGhvciBsaW5rLCBhbmQgdGhlIGxpY2Vuc2UgaW5mbyBpbnRhY3QuDQovLwkNCi8vICBUaGFua3M6IFNjb3R0IFVwdG9uKHVwdG9uaWMuY29tKSwgUGV0ZXItUGF1bCBLb2NoKHF1aXJrc21vZGUuY29tKSwgYW5kIFRob21hcyBGdWNocyhtaXIuYWN1bG8udXMpIGZvciBpZGVhcywgbGlicywgYW5kIHNuaXBwZXRzLg0KLy8gIAkJQXJ0ZW15IFRyZWd1YmVua28gKGFydHkubmFtZSkgZm9yIGNsZWFudXAgYW5kIGhlbHAgaW4gdXBkYXRpbmcgdG8gbGF0ZXN0IHZlciBvZiBwcm90by1hY3Vsb3VzLg0KLy8NCi8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tDQovKg0KDQogICAgVGFibGUgb2YgQ29udGVudHMNCiAgICAtLS0tLS0tLS0tLS0tLS0tLQ0KICAgIENvbmZpZ3VyYXRpb24NCg0KICAgIExpZ2h0Ym94IENsYXNzIERlY2xhcmF0aW9uDQogICAgLSBpbml0aWFsaXplKCkNCiAgICAtIHVwZGF0ZUltYWdlTGlzdCgpDQogICAgLSBzdGFydCgpDQogICAgLSBjaGFuZ2VJbWFnZSgpDQogICAgLSByZXNpemVJbWFnZUNvbnRhaW5lcigpDQogICAgLSBzaG93SW1hZ2UoKQ0KICAgIC0gdXBkYXRlRGV0YWlscygpDQogICAgLSB1cGRhdGVOYXYoKQ0KICAgIC0gZW5hYmxlS2V5Ym9hcmROYXYoKQ0KICAgIC0gZGlzYWJsZUtleWJvYXJkTmF2KCkNCiAgICAtIGtleWJvYXJkQWN0aW9uKCkNCiAgICAtIHByZWxvYWROZWlnaGJvckltYWdlcygpDQogICAgLSBlbmQoKQ0KICAgIA0KICAgIEZ1bmN0aW9uIENhbGxzDQogICAgLSBkb2N1bWVudC5vYnNlcnZlKCkNCiAgIA0KKi8NCi8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tDQoNCi8vDQovLyAgQ29uZmlndXJhdGlvbmwNCi8vDQpMaWdodGJveE9wdGlvbnMgPSBPYmplY3QuZXh0ZW5kKHsNCiAgICBmaWxlTG9hZGluZ0ltYWdlOiAgICAgICAgJ21vZHVsZXMvR2FsbGVyeS90ZW1wbGF0ZXMvbGlnaHRib3gvaW1hZ2VzL2xvYWRpbmcuZ2lmJywgICAgIA0KICAgIGZpbGVCb3R0b21OYXZDbG9zZUltYWdlOiAnbW9kdWxlcy9HYWxsZXJ5L3RlbXBsYXRlcy9saWdodGJveC9pbWFnZXMvY2xvc2VsYWJlbC5naWYnLA0KDQogICAgb3ZlcmxheU9wYWNpdHk6IDAuOCwgICAvLyBjb250cm9scyB0cmFuc3BhcmVuY3kgb2Ygc2hhZG93IG92ZXJsYXkNCg0KICAgIGFuaW1hdGU6IHRydWUsICAgICAgICAgLy8gdG9nZ2xlcyByZXNpemluZyBhbmltYXRpb25zDQogICAgcmVzaXplU3BlZWQ6IDcsICAgICAgICAvLyBjb250cm9scyB0aGUgc3BlZWQgb2YgdGhlIGltYWdlIHJlc2l6aW5nIGFuaW1hdGlvbnMgKDE9c2xvd2VzdCBhbmQgMTA9ZmFzdGVzdCkNCg0KICAgIGJvcmRlclNpemU6IDEwLCAgICAgICAgIC8vaWYgeW91IGFkanVzdCB0aGUgcGFkZGluZyBpbiB0aGUgQ1NTLCB5b3Ugd2lsbCBuZWVkIHRvIHVwZGF0ZSB0aGlzIHZhcmlhYmxlDQoNCgkvLyBXaGVuIGdyb3VwaW5nIGltYWdlcyB0aGlzIGlzIHVzZWQgdG8gd3JpdGU6IEltYWdlICMgb2YgIy4NCgkvLyBDaGFuZ2UgaXQgZm9yIG5vbi1lbmdsaXNoIGxvY2FsaXphdGlvbg0KCWxhYmVsSW1hZ2U6ICJJbWFnZSIsDQoJbGFiZWxPZjogIm9mIg0KfSwgd2luZG93LkxpZ2h0Ym94T3B0aW9ucyB8fCB7fSk7DQoNCi8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tDQoNCnZhciBMaWdodGJveCA9IENsYXNzLmNyZWF0ZSgpOw0KDQpMaWdodGJveC5wcm90b3R5cGUgPSB7DQogICAgaW1hZ2VBcnJheTogW10sDQogICAgYWN0aXZlSW1hZ2U6IHVuZGVmaW5lZCwNCiAgICANCiAgICAvLyBpbml0aWFsaXplKCkNCiAgICAvLyBDb25zdHJ1Y3RvciBydW5zIG9uIGNvbXBsZXRpb24gb2YgdGhlIERPTSBsb2FkaW5nLiBDYWxscyB1cGRhdGVJbWFnZUxpc3QgYW5kIHRoZW4NCiAgICAvLyB0aGUgZnVuY3Rpb24gaW5zZXJ0cyBodG1sIGF0IHRoZSBib3R0b20gb2YgdGhlIHBhZ2Ugd2hpY2ggaXMgdXNlZCB0byBkaXNwbGF5IHRoZSBzaGFkb3cgDQogICAgLy8gb3ZlcmxheSBhbmQgdGhlIGltYWdlIGNvbnRhaW5lci4NCiAgICAvLw0KICAgIGluaXRpYWxpemU6IGZ1bmN0aW9uKCkgeyAgICANCiAgICAgICAgDQogICAgICAgIHRoaXMudXBkYXRlSW1hZ2VMaXN0KCk7DQogICAgICAgIA0KICAgICAgICB0aGlzLmtleWJvYXJkQWN0aW9uID0gdGhpcy5rZXlib2FyZEFjdGlvbi5iaW5kQXNFdmVudExpc3RlbmVyKHRoaXMpOw0KDQogICAgICAgIGlmIChMaWdodGJveE9wdGlvbnMucmVzaXplU3BlZWQgPiAxMCkgTGlnaHRib3hPcHRpb25zLnJlc2l6ZVNwZWVkID0gMTA7DQogICAgICAgIGlmIChMaWdodGJveE9wdGlvbnMucmVzaXplU3BlZWQgPCAxKSAgTGlnaHRib3hPcHRpb25zLnJlc2l6ZVNwZWVkID0gMTsNCg0KCSAgICB0aGlzLnJlc2l6ZUR1cmF0aW9uID0gTGlnaHRib3hPcHRpb25zLmFuaW1hdGUgPyAoKDExIC0gTGlnaHRib3hPcHRpb25zLnJlc2l6ZVNwZWVkKSAqIDAuMTUpIDogMDsNCgkgICAgdGhpcy5vdmVybGF5RHVyYXRpb24gPSBMaWdodGJveE9wdGlvbnMuYW5pbWF0ZSA/IDAuMiA6IDA7ICAvLyBzaGFkb3cgZmFkZSBpbi9vdXQgZHVyYXRpb24NCg0KICAgICAgICAvLyBXaGVuIExpZ2h0Ym94IHN0YXJ0cyBpdCB3aWxsIHJlc2l6ZSBpdHNlbGYgZnJvbSAyNTAgYnkgMjUwIHRvIHRoZSBjdXJyZW50IGltYWdlIGRpbWVuc2lvbi4NCiAgICAgICAgLy8gSWYgYW5pbWF0aW9ucyBhcmUgdHVybmVkIG9mZiwgaXQgd2lsbCBiZSBoaWRkZW4gYXMgdG8gcHJldmVudCBhIGZsaWNrZXIgb2YgYQ0KICAgICAgICAvLyB3aGl0ZSAyNTAgYnkgMjUwIGJveC4NCiAgICAgICAgdmFyIHNpemUgPSAoTGlnaHRib3hPcHRpb25zLmFuaW1hdGUgPyAyNTAgOiAxKSArICdweCc7DQogICAgICAgIA0KDQogICAgICAgIC8vIENvZGUgaW5zZXJ0cyBodG1sIGF0IHRoZSBib3R0b20gb2YgdGhlIHBhZ2UgdGhhdCBsb29rcyBzaW1pbGFyIHRvIHRoaXM6DQogICAgICAgIC8vDQogICAgICAgIC8vICA8ZGl2IGlkPSJvdmVybGF5Ij48L2Rpdj4NCiAgICAgICAgLy8gIDxkaXYgaWQ9ImxpZ2h0Ym94Ij4NCiAgICAgICAgLy8gICAgICA8ZGl2IGlkPSJvdXRlckltYWdlQ29udGFpbmVyIj4NCiAgICAgICAgLy8gICAgICAgICAgPGRpdiBpZD0iaW1hZ2VDb250YWluZXIiPg0KICAgICAgICAvLyAgICAgICAgICAgICAgPGltZyBpZD0ibGlnaHRib3hJbWFnZSI+DQogICAgICAgIC8vICAgICAgICAgICAgICA8ZGl2IHN0eWxlPSIiIGlkPSJob3Zlck5hdiI+DQogICAgICAgIC8vICAgICAgICAgICAgICAgICAgPGEgaHJlZj0iIyIgaWQ9InByZXZMaW5rIj48L2E+DQogICAgICAgIC8vICAgICAgICAgICAgICAgICAgPGEgaHJlZj0iIyIgaWQ9Im5leHRMaW5rIj48L2E+DQogICAgICAgIC8vICAgICAgICAgICAgICA8L2Rpdj4NCiAgICAgICAgLy8gICAgICAgICAgICAgIDxkaXYgaWQ9ImxvYWRpbmciPg0KICAgICAgICAvLyAgICAgICAgICAgICAgICAgIDxhIGhyZWY9IiMiIGlkPSJsb2FkaW5nTGluayI+DQogICAgICAgIC8vICAgICAgICAgICAgICAgICAgICAgIDxpbWcgc3JjPSJpbWFnZXMvbG9hZGluZy5naWYiPg0KICAgICAgICAvLyAgICAgICAgICAgICAgICAgIDwvYT4NCiAgICAgICAgLy8gICAgICAgICAgICAgIDwvZGl2Pg0KICAgICAgICAvLyAgICAgICAgICA8L2Rpdj4NCiAgICAgICAgLy8gICAgICA8L2Rpdj4NCiAgICAgICAgLy8gICAgICA8ZGl2IGlkPSJpbWFnZURhdGFDb250YWluZXIiPg0KICAgICAgICAvLyAgICAgICAgICA8ZGl2IGlkPSJpbWFnZURhdGEiPg0KICAgICAgICAvLyAgICAgICAgICAgICAgPGRpdiBpZD0iaW1hZ2VEZXRhaWxzIj4NCiAgICAgICAgLy8gICAgICAgICAgICAgICAgICA8c3BhbiBpZD0iY2FwdGlvbiI+PC9zcGFuPg0KICAgICAgICAvLyAgICAgICAgICAgICAgICAgIDxzcGFuIGlkPSJudW1iZXJEaXNwbGF5Ij48L3NwYW4+DQogICAgICAgIC8vICAgICAgICAgICAgICA8L2Rpdj4NCiAgICAgICAgLy8gICAgICAgICAgICAgIDxkaXYgaWQ9ImJvdHRvbU5hdiI+DQogICAgICAgIC8vICAgICAgICAgICAgICAgICAgPGEgaHJlZj0iIyIgaWQ9ImJvdHRvbU5hdkNsb3NlIj4NCiAgICAgICAgLy8gICAgICAgICAgICAgICAgICAgICAgPGltZyBzcmM9ImltYWdlcy9jbG9zZS5naWYiPg0KICAgICAgICAvLyAgICAgICAgICAgICAgICAgIDwvYT4NCiAgICAgICAgLy8gICAgICAgICAgICAgIDwvZGl2Pg0KICAgICAgICAvLyAgICAgICAgICA8L2Rpdj4NCiAgICAgICAgLy8gICAgICA8L2Rpdj4NCiAgICAgICAgLy8gIDwvZGl2Pg0KDQoNCiAgICAgICAgdmFyIG9iakJvZHkgPSAkJCgnYm9keScpWzBdOw0KDQoJCW9iakJvZHkuYXBwZW5kQ2hpbGQoQnVpbGRlci5ub2RlKCdkaXYnLHtpZDonb3ZlcmxheSd9KSk7DQoJDQogICAgICAgIG9iakJvZHkuYXBwZW5kQ2hpbGQoQnVpbGRlci5ub2RlKCdkaXYnLHtpZDonbGlnaHRib3gnfSwgWw0KICAgICAgICAgICAgQnVpbGRlci5ub2RlKCdkaXYnLHtpZDonb3V0ZXJJbWFnZUNvbnRhaW5lcid9LCANCiAgICAgICAgICAgICAgICBCdWlsZGVyLm5vZGUoJ2Rpdicse2lkOidpbWFnZUNvbnRhaW5lcid9LCBbDQogICAgICAgICAgICAgICAgICAgIEJ1aWxkZXIubm9kZSgnaW1nJyx7aWQ6J2xpZ2h0Ym94SW1hZ2UnfSksIA0KICAgICAgICAgICAgICAgICAgICBCdWlsZGVyLm5vZGUoJ2Rpdicse2lkOidob3Zlck5hdid9LCBbDQogICAgICAgICAgICAgICAgICAgICAgICBCdWlsZGVyLm5vZGUoJ2EnLHtpZDoncHJldkxpbmsnLCBocmVmOiAnIycgfSksDQogICAgICAgICAgICAgICAgICAgICAgICBCdWlsZGVyLm5vZGUoJ2EnLHtpZDonbmV4dExpbmsnLCBocmVmOiAnIycgfSkNCiAgICAgICAgICAgICAgICAgICAgXSksDQogICAgICAgICAgICAgICAgICAgIEJ1aWxkZXIubm9kZSgnZGl2Jyx7aWQ6J2xvYWRpbmcnfSwgDQogICAgICAgICAgICAgICAgICAgICAgICBCdWlsZGVyLm5vZGUoJ2EnLHtpZDonbG9hZGluZ0xpbmsnLCBocmVmOiAnIycgfSwgDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgQnVpbGRlci5ub2RlKCdpbWcnLCB7c3JjOiBMaWdodGJveE9wdGlvbnMuZmlsZUxvYWRpbmdJbWFnZX0pDQogICAgICAgICAgICAgICAgICAgICAgICApDQogICAgICAgICAgICAgICAgICAgICkNCiAgICAgICAgICAgICAgICBdKQ0KICAgICAgICAgICAgKSwNCiAgICAgICAgICAgIEJ1aWxkZXIubm9kZSgnZGl2Jywge2lkOidpbWFnZURhdGFDb250YWluZXInfSwNCiAgICAgICAgICAgICAgICBCdWlsZGVyLm5vZGUoJ2Rpdicse2lkOidpbWFnZURhdGEnfSwgWw0KICAgICAgICAgICAgICAgICAgICBCdWlsZGVyLm5vZGUoJ2Rpdicse2lkOidpbWFnZURldGFpbHMnfSwgWw0KICAgICAgICAgICAgICAgICAgICAgICAgQnVpbGRlci5ub2RlKCdzcGFuJyx7aWQ6J2NhcHRpb24nfSksDQogICAgICAgICAgICAgICAgICAgICAgICBCdWlsZGVyLm5vZGUoJ3NwYW4nLHtpZDonbnVtYmVyRGlzcGxheSd9KQ0KICAgICAgICAgICAgICAgICAgICBdKSwNCiAgICAgICAgICAgICAgICAgICAgQnVpbGRlci5ub2RlKCdkaXYnLHtpZDonYm90dG9tTmF2J30sDQogICAgICAgICAgICAgICAgICAgICAgICBCdWlsZGVyLm5vZGUoJ2EnLHtpZDonYm90dG9tTmF2Q2xvc2UnLCBocmVmOiAnIycgfSwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBCdWlsZGVyLm5vZGUoJ2ltZycsIHsgc3JjOiBMaWdodGJveE9wdGlvbnMuZmlsZUJvdHRvbU5hdkNsb3NlSW1hZ2UgfSkNCiAgICAgICAgICAgICAgICAgICAgICAgICkNCiAgICAgICAgICAgICAgICAgICAgKQ0KICAgICAgICAgICAgICAgIF0pDQogICAgICAgICAgICApDQogICAgICAgIF0pKTsNCg0KDQoJCSQoJ292ZXJsYXknKS5oaWRlKCkub2JzZXJ2ZSgnY2xpY2snLCAoZnVuY3Rpb24oKSB7IHRoaXMuZW5kKCk7IH0pLmJpbmQodGhpcykpOw0KCQkkKCdsaWdodGJveCcpLmhpZGUoKS5vYnNlcnZlKCdjbGljaycsIChmdW5jdGlvbihldmVudCkgeyBpZiAoZXZlbnQuZWxlbWVudCgpLmlkID09ICdsaWdodGJveCcpIHRoaXMuZW5kKCk7IH0pLmJpbmQodGhpcykpOw0KCQkkKCdvdXRlckltYWdlQ29udGFpbmVyJykuc2V0U3R5bGUoeyB3aWR0aDogc2l6ZSwgaGVpZ2h0OiBzaXplIH0pOw0KCQkkKCdwcmV2TGluaycpLm9ic2VydmUoJ2NsaWNrJywgKGZ1bmN0aW9uKGV2ZW50KSB7IGV2ZW50LnN0b3AoKTsgdGhpcy5jaGFuZ2VJbWFnZSh0aGlzLmFjdGl2ZUltYWdlIC0gMSk7IH0pLmJpbmRBc0V2ZW50TGlzdGVuZXIodGhpcykpOw0KCQkkKCduZXh0TGluaycpLm9ic2VydmUoJ2NsaWNrJywgKGZ1bmN0aW9uKGV2ZW50KSB7IGV2ZW50LnN0b3AoKTsgdGhpcy5jaGFuZ2VJbWFnZSh0aGlzLmFjdGl2ZUltYWdlICsgMSk7IH0pLmJpbmRBc0V2ZW50TGlzdGVuZXIodGhpcykpOw0KCQkkKCdsb2FkaW5nTGluaycpLm9ic2VydmUoJ2NsaWNrJywgKGZ1bmN0aW9uKGV2ZW50KSB7IGV2ZW50LnN0b3AoKTsgdGhpcy5lbmQoKTsgfSkuYmluZCh0aGlzKSk7DQoJCSQoJ2JvdHRvbU5hdkNsb3NlJykub2JzZXJ2ZSgnY2xpY2snLCAoZnVuY3Rpb24oZXZlbnQpIHsgZXZlbnQuc3RvcCgpOyB0aGlzLmVuZCgpOyB9KS5iaW5kKHRoaXMpKTsNCg0KICAgICAgICB2YXIgdGggPSB0aGlzOw0KICAgICAgICAoZnVuY3Rpb24oKXsNCiAgICAgICAgICAgIHZhciBpZHMgPSANCiAgICAgICAgICAgICAgICAnb3ZlcmxheSBsaWdodGJveCBvdXRlckltYWdlQ29udGFpbmVyIGltYWdlQ29udGFpbmVyIGxpZ2h0Ym94SW1hZ2UgaG92ZXJOYXYgcHJldkxpbmsgbmV4dExpbmsgbG9hZGluZyBsb2FkaW5nTGluayAnICsgDQogICAgICAgICAgICAgICAgJ2ltYWdlRGF0YUNvbnRhaW5lciBpbWFnZURhdGEgaW1hZ2VEZXRhaWxzIGNhcHRpb24gbnVtYmVyRGlzcGxheSBib3R0b21OYXYgYm90dG9tTmF2Q2xvc2UnOyAgIA0KICAgICAgICAgICAgJHcoaWRzKS5lYWNoKGZ1bmN0aW9uKGlkKXsgdGhbaWRdID0gJChpZCk7IH0pOw0KICAgICAgICB9KS5kZWZlcigpOw0KICAgIH0sDQoNCiAgICAvLw0KICAgIC8vIHVwZGF0ZUltYWdlTGlzdCgpDQogICAgLy8gTG9vcHMgdGhyb3VnaCBhbmNob3IgdGFncyBsb29raW5nIGZvciAnbGlnaHRib3gnIHJlZmVyZW5jZXMgYW5kIGFwcGxpZXMgb25jbGljaw0KICAgIC8vIGV2ZW50cyB0byBhcHByb3ByaWF0ZSBsaW5rcy4gWW91IGNhbiByZXJ1biBhZnRlciBkeW5hbWljYWxseSBhZGRpbmcgaW1hZ2VzIHcvYWpheC4NCiAgICAvLw0KICAgIHVwZGF0ZUltYWdlTGlzdDogZnVuY3Rpb24oKSB7ICAgDQogICAgICAgIHRoaXMudXBkYXRlSW1hZ2VMaXN0ID0gUHJvdG90eXBlLmVtcHR5RnVuY3Rpb247DQoNCiAgICAgICAgZG9jdW1lbnQub2JzZXJ2ZSgnY2xpY2snLCAoZnVuY3Rpb24oZXZlbnQpew0KICAgICAgICAgICAgdmFyIHRhcmdldCA9IGV2ZW50LmZpbmRFbGVtZW50KCdhW3JlbF49bGlnaHRib3hdJykgfHwgZXZlbnQuZmluZEVsZW1lbnQoJ2FyZWFbcmVsXj1saWdodGJveF0nKTsNCiAgICAgICAgICAgIGlmICh0YXJnZXQpIHsNCiAgICAgICAgICAgICAgICBldmVudC5zdG9wKCk7DQogICAgICAgICAgICAgICAgdGhpcy5zdGFydCh0YXJnZXQpOw0KICAgICAgICAgICAgfQ0KICAgICAgICB9KS5iaW5kKHRoaXMpKTsNCiAgICB9LA0KICAgIA0KICAgIC8vDQogICAgLy8gIHN0YXJ0KCkNCiAgICAvLyAgRGlzcGxheSBvdmVybGF5IGFuZCBsaWdodGJveC4gSWYgaW1hZ2UgaXMgcGFydCBvZiBhIHNldCwgYWRkIHNpYmxpbmdzIHRvIGltYWdlQXJyYXkuDQogICAgLy8NCiAgICBzdGFydDogZnVuY3Rpb24oaW1hZ2VMaW5rKSB7ICAgIA0KDQogICAgICAgICQkKCdzZWxlY3QnLCAnb2JqZWN0JywgJ2VtYmVkJykuZWFjaChmdW5jdGlvbihub2RlKXsgbm9kZS5zdHlsZS52aXNpYmlsaXR5ID0gJ2hpZGRlbicgfSk7DQoNCiAgICAgICAgLy8gc3RyZXRjaCBvdmVybGF5IHRvIGZpbGwgcGFnZSBhbmQgZmFkZSBpbg0KICAgICAgICB2YXIgYXJyYXlQYWdlU2l6ZSA9IHRoaXMuZ2V0UGFnZVNpemUoKTsNCiAgICAgICAgJCgnb3ZlcmxheScpLnNldFN0eWxlKHsgd2lkdGg6IGFycmF5UGFnZVNpemVbMF0gKyAncHgnLCBoZWlnaHQ6IGFycmF5UGFnZVNpemVbMV0gKyAncHgnIH0pOw0KDQogICAgICAgIG5ldyBFZmZlY3QuQXBwZWFyKHRoaXMub3ZlcmxheSwgeyBkdXJhdGlvbjogdGhpcy5vdmVybGF5RHVyYXRpb24sIGZyb206IDAuMCwgdG86IExpZ2h0Ym94T3B0aW9ucy5vdmVybGF5T3BhY2l0eSB9KTsNCg0KICAgICAgICB0aGlzLmltYWdlQXJyYXkgPSBbXTsNCiAgICAgICAgdmFyIGltYWdlTnVtID0gMDsgICAgICAgDQoNCiAgICAgICAgaWYgKChpbWFnZUxpbmsuZ2V0QXR0cmlidXRlKCJyZWwiKSA9PSAnbGlnaHRib3gnKSl7DQogICAgICAgICAgICAvLyBpZiBpbWFnZSBpcyBOT1QgcGFydCBvZiBhIHNldCwgYWRkIHNpbmdsZSBpbWFnZSB0byBpbWFnZUFycmF5DQogICAgICAgICAgICB0aGlzLmltYWdlQXJyYXkucHVzaChbaW1hZ2VMaW5rLmhyZWYsIGltYWdlTGluay50aXRsZV0pOyAgICAgICAgIA0KICAgICAgICB9IGVsc2Ugew0KICAgICAgICAgICAgLy8gaWYgaW1hZ2UgaXMgcGFydCBvZiBhIHNldC4uDQogICAgICAgICAgICB0aGlzLmltYWdlQXJyYXkgPSANCiAgICAgICAgICAgICAgICAkJChpbWFnZUxpbmsudGFnTmFtZSArICdbaHJlZl1bcmVsPSInICsgaW1hZ2VMaW5rLnJlbCArICciXScpLg0KICAgICAgICAgICAgICAgIGNvbGxlY3QoZnVuY3Rpb24oYW5jaG9yKXsgcmV0dXJuIFthbmNob3IuaHJlZiwgYW5jaG9yLnRpdGxlXTsgfSkuDQogICAgICAgICAgICAgICAgdW5pcSgpOw0KICAgICAgICAgICAgDQogICAgICAgICAgICB3aGlsZSAodGhpcy5pbWFnZUFycmF5W2ltYWdlTnVtXVswXSAhPSBpbWFnZUxpbmsuaHJlZikgeyBpbWFnZU51bSsrOyB9DQogICAgICAgIH0NCg0KICAgICAgICAvLyBjYWxjdWxhdGUgdG9wIGFuZCBsZWZ0IG9mZnNldCBmb3IgdGhlIGxpZ2h0Ym94IA0KICAgICAgICB2YXIgYXJyYXlQYWdlU2Nyb2xsID0gZG9jdW1lbnQudmlld3BvcnQuZ2V0U2Nyb2xsT2Zmc2V0cygpOw0KICAgICAgICB2YXIgbGlnaHRib3hUb3AgPSBhcnJheVBhZ2VTY3JvbGxbMV0gKyAoZG9jdW1lbnQudmlld3BvcnQuZ2V0SGVpZ2h0KCkgLyAxMCk7DQogICAgICAgIHZhciBsaWdodGJveExlZnQgPSBhcnJheVBhZ2VTY3JvbGxbMF07DQogICAgICAgIHRoaXMubGlnaHRib3guc2V0U3R5bGUoeyB0b3A6IGxpZ2h0Ym94VG9wICsgJ3B4JywgbGVmdDogbGlnaHRib3hMZWZ0ICsgJ3B4JyB9KS5zaG93KCk7DQogICAgICAgIA0KICAgICAgICB0aGlzLmNoYW5nZUltYWdlKGltYWdlTnVtKTsNCiAgICB9LA0KDQogICAgLy8NCiAgICAvLyAgY2hhbmdlSW1hZ2UoKQ0KICAgIC8vICBIaWRlIG1vc3QgZWxlbWVudHMgYW5kIHByZWxvYWQgaW1hZ2UgaW4gcHJlcGFyYXRpb24gZm9yIHJlc2l6aW5nIGltYWdlIGNvbnRhaW5lci4NCiAgICAvLw0KICAgIGNoYW5nZUltYWdlOiBmdW5jdGlvbihpbWFnZU51bSkgeyAgIA0KICAgICAgICANCiAgICAgICAgdGhpcy5hY3RpdmVJbWFnZSA9IGltYWdlTnVtOyAvLyB1cGRhdGUgZ2xvYmFsIHZhcg0KDQogICAgICAgIC8vIGhpZGUgZWxlbWVudHMgZHVyaW5nIHRyYW5zaXRpb24NCiAgICAgICAgaWYgKExpZ2h0Ym94T3B0aW9ucy5hbmltYXRlKSB0aGlzLmxvYWRpbmcuc2hvdygpOw0KICAgICAgICB0aGlzLmxpZ2h0Ym94SW1hZ2UuaGlkZSgpOw0KICAgICAgICB0aGlzLmhvdmVyTmF2LmhpZGUoKTsNCiAgICAgICAgdGhpcy5wcmV2TGluay5oaWRlKCk7DQogICAgICAgIHRoaXMubmV4dExpbmsuaGlkZSgpOw0KCQkvLyBIQUNLOiBPcGVyYTkgZG9lcyBub3QgY3VycmVudGx5IHN1cHBvcnQgc2NyaXB0YWN1bG91cyBvcGFjaXR5IGFuZCBhcHBlYXIgZngNCiAgICAgICAgdGhpcy5pbWFnZURhdGFDb250YWluZXIuc2V0U3R5bGUoe29wYWNpdHk6IC4wMDAxfSk7DQogICAgICAgIHRoaXMubnVtYmVyRGlzcGxheS5oaWRlKCk7ICAgICAgDQogICAgICAgIA0KICAgICAgICB2YXIgaW1nUHJlbG9hZGVyID0gbmV3IEltYWdlKCk7DQogICAgICAgIA0KICAgICAgICAvLyBvbmNlIGltYWdlIGlzIHByZWxvYWRlZCwgcmVzaXplIGltYWdlIGNvbnRhaW5lcg0KICAgICAgICBpbWdQcmVsb2FkZXIub25sb2FkID0gKGZ1bmN0aW9uKCl7DQogICAgICAgICAgICB0aGlzLmxpZ2h0Ym94SW1hZ2Uuc3JjID0gdGhpcy5pbWFnZUFycmF5W3RoaXMuYWN0aXZlSW1hZ2VdWzBdOw0KICAgICAgICAgICAgLypCdWcgRml4ZWQgYnkgQW5keSBTY290dCovDQogICAgICAgICAgICB0aGlzLmxpZ2h0Ym94SW1hZ2Uud2lkdGggPSBpbWdQcmVsb2FkZXIud2lkdGg7DQogICAgICAgICAgICB0aGlzLmxpZ2h0Ym94SW1hZ2UuaGVpZ2h0ID0gaW1nUHJlbG9hZGVyLmhlaWdodDsNCiAgICAgICAgICAgIC8qRW5kIG9mIEJ1ZyBGaXgqLw0KICAgICAgICAgICAgdGhpcy5yZXNpemVJbWFnZUNvbnRhaW5lcihpbWdQcmVsb2FkZXIud2lkdGgsIGltZ1ByZWxvYWRlci5oZWlnaHQpOw0KICAgICAgICB9KS5iaW5kKHRoaXMpOw0KICAgICAgICBpbWdQcmVsb2FkZXIuc3JjID0gdGhpcy5pbWFnZUFycmF5W3RoaXMuYWN0aXZlSW1hZ2VdWzBdOw0KICAgIH0sDQoNCiAgICAvLw0KICAgIC8vICByZXNpemVJbWFnZUNvbnRhaW5lcigpDQogICAgLy8NCiAgICByZXNpemVJbWFnZUNvbnRhaW5lcjogZnVuY3Rpb24oaW1nV2lkdGgsIGltZ0hlaWdodCkgew0KDQogICAgICAgIC8vIGdldCBjdXJyZW50IHdpZHRoIGFuZCBoZWlnaHQNCiAgICAgICAgdmFyIHdpZHRoQ3VycmVudCAgPSB0aGlzLm91dGVySW1hZ2VDb250YWluZXIuZ2V0V2lkdGgoKTsNCiAgICAgICAgdmFyIGhlaWdodEN1cnJlbnQgPSB0aGlzLm91dGVySW1hZ2VDb250YWluZXIuZ2V0SGVpZ2h0KCk7DQoNCiAgICAgICAgLy8gZ2V0IG5ldyB3aWR0aCBhbmQgaGVpZ2h0DQogICAgICAgIHZhciB3aWR0aE5ldyAgPSAoaW1nV2lkdGggICsgTGlnaHRib3hPcHRpb25zLmJvcmRlclNpemUgKiAyKTsNCiAgICAgICAgdmFyIGhlaWdodE5ldyA9IChpbWdIZWlnaHQgKyBMaWdodGJveE9wdGlvbnMuYm9yZGVyU2l6ZSAqIDIpOw0KDQogICAgICAgIC8vIHNjYWxhcnMgYmFzZWQgb24gY2hhbmdlIGZyb20gb2xkIHRvIG5ldw0KICAgICAgICB2YXIgeFNjYWxlID0gKHdpZHRoTmV3ICAvIHdpZHRoQ3VycmVudCkgICogMTAwOw0KICAgICAgICB2YXIgeVNjYWxlID0gKGhlaWdodE5ldyAvIGhlaWdodEN1cnJlbnQpICogMTAwOw0KDQogICAgICAgIC8vIGNhbGN1bGF0ZSBzaXplIGRpZmZlcmVuY2UgYmV0d2VlbiBuZXcgYW5kIG9sZCBpbWFnZSwgYW5kIHJlc2l6ZSBpZiBuZWNlc3NhcnkNCiAgICAgICAgdmFyIHdEaWZmID0gd2lkdGhDdXJyZW50IC0gd2lkdGhOZXc7DQogICAgICAgIHZhciBoRGlmZiA9IGhlaWdodEN1cnJlbnQgLSBoZWlnaHROZXc7DQoNCiAgICAgICAgaWYgKGhEaWZmICE9IDApIG5ldyBFZmZlY3QuU2NhbGUodGhpcy5vdXRlckltYWdlQ29udGFpbmVyLCB5U2NhbGUsIHtzY2FsZVg6IGZhbHNlLCBkdXJhdGlvbjogdGhpcy5yZXNpemVEdXJhdGlvbiwgcXVldWU6ICdmcm9udCd9KTsgDQogICAgICAgIGlmICh3RGlmZiAhPSAwKSBuZXcgRWZmZWN0LlNjYWxlKHRoaXMub3V0ZXJJbWFnZUNvbnRhaW5lciwgeFNjYWxlLCB7c2NhbGVZOiBmYWxzZSwgZHVyYXRpb246IHRoaXMucmVzaXplRHVyYXRpb24sIGRlbGF5OiB0aGlzLnJlc2l6ZUR1cmF0aW9ufSk7IA0KDQogICAgICAgIC8vIGlmIG5ldyBhbmQgb2xkIGltYWdlIGFyZSBzYW1lIHNpemUgYW5kIG5vIHNjYWxpbmcgdHJhbnNpdGlvbiBpcyBuZWNlc3NhcnksIA0KICAgICAgICAvLyBkbyBhIHF1aWNrIHBhdXNlIHRvIHByZXZlbnQgaW1hZ2UgZmxpY2tlci4NCiAgICAgICAgdmFyIHRpbWVvdXQgPSAwOw0KICAgICAgICBpZiAoKGhEaWZmID09IDApICYmICh3RGlmZiA9PSAwKSl7DQogICAgICAgICAgICB0aW1lb3V0ID0gMTAwOw0KICAgICAgICAgICAgaWYgKFByb3RvdHlwZS5Ccm93c2VyLklFKSB0aW1lb3V0ID0gMjUwOyAgIA0KICAgICAgICB9DQoNCiAgICAgICAgKGZ1bmN0aW9uKCl7DQogICAgICAgICAgICB0aGlzLnByZXZMaW5rLnNldFN0eWxlKHsgaGVpZ2h0OiBpbWdIZWlnaHQgKyAncHgnIH0pOw0KICAgICAgICAgICAgdGhpcy5uZXh0TGluay5zZXRTdHlsZSh7IGhlaWdodDogaW1nSGVpZ2h0ICsgJ3B4JyB9KTsNCiAgICAgICAgICAgIHRoaXMuaW1hZ2VEYXRhQ29udGFpbmVyLnNldFN0eWxlKHsgd2lkdGg6IHdpZHRoTmV3ICsgJ3B4JyB9KTsNCg0KICAgICAgICAgICAgdGhpcy5zaG93SW1hZ2UoKTsNCiAgICAgICAgfSkuYmluZCh0aGlzKS5kZWxheSh0aW1lb3V0IC8gMTAwMCk7DQogICAgfSwNCiAgICANCiAgICAvLw0KICAgIC8vICBzaG93SW1hZ2UoKQ0KICAgIC8vICBEaXNwbGF5IGltYWdlIGFuZCBiZWdpbiBwcmVsb2FkaW5nIG5laWdoYm9ycy4NCiAgICAvLw0KICAgIHNob3dJbWFnZTogZnVuY3Rpb24oKXsNCiAgICAgICAgdGhpcy5sb2FkaW5nLmhpZGUoKTsNCiAgICAgICAgbmV3IEVmZmVjdC5BcHBlYXIodGhpcy5saWdodGJveEltYWdlLCB7IA0KICAgICAgICAgICAgZHVyYXRpb246IHRoaXMucmVzaXplRHVyYXRpb24sIA0KICAgICAgICAgICAgcXVldWU6ICdlbmQnLCANCiAgICAgICAgICAgIGFmdGVyRmluaXNoOiAoZnVuY3Rpb24oKXsgdGhpcy51cGRhdGVEZXRhaWxzKCk7IH0pLmJpbmQodGhpcykgDQogICAgICAgIH0pOw0KICAgICAgICB0aGlzLnByZWxvYWROZWlnaGJvckltYWdlcygpOw0KICAgIH0sDQoNCiAgICAvLw0KICAgIC8vICB1cGRhdGVEZXRhaWxzKCkNCiAgICAvLyAgRGlzcGxheSBjYXB0aW9uLCBpbWFnZSBudW1iZXIsIGFuZCBib3R0b20gbmF2Lg0KICAgIC8vDQogICAgdXBkYXRlRGV0YWlsczogZnVuY3Rpb24oKSB7DQogICAgDQogICAgICAgIHRoaXMuY2FwdGlvbi51cGRhdGUodGhpcy5pbWFnZUFycmF5W3RoaXMuYWN0aXZlSW1hZ2VdWzFdKS5zaG93KCk7DQoNCiAgICAgICAgLy8gaWYgaW1hZ2UgaXMgcGFydCBvZiBzZXQgZGlzcGxheSAnSW1hZ2UgeCBvZiB4JyANCiAgICAgICAgaWYgKHRoaXMuaW1hZ2VBcnJheS5sZW5ndGggPiAxKXsNCiAgICAgICAgICAgIHRoaXMubnVtYmVyRGlzcGxheS51cGRhdGUoIExpZ2h0Ym94T3B0aW9ucy5sYWJlbEltYWdlICsgJyAnICsgKHRoaXMuYWN0aXZlSW1hZ2UgKyAxKSArICcgJyArIExpZ2h0Ym94T3B0aW9ucy5sYWJlbE9mICsgJyAgJyArIHRoaXMuaW1hZ2VBcnJheS5sZW5ndGgpLnNob3coKTsNCiAgICAgICAgfQ0KDQogICAgICAgIG5ldyBFZmZlY3QuUGFyYWxsZWwoDQogICAgICAgICAgICBbIA0KICAgICAgICAgICAgICAgIG5ldyBFZmZlY3QuU2xpZGVEb3duKHRoaXMuaW1hZ2VEYXRhQ29udGFpbmVyLCB7IHN5bmM6IHRydWUsIGR1cmF0aW9uOiB0aGlzLnJlc2l6ZUR1cmF0aW9uLCBmcm9tOiAwLjAsIHRvOiAxLjAgfSksIA0KICAgICAgICAgICAgICAgIG5ldyBFZmZlY3QuQXBwZWFyKHRoaXMuaW1hZ2VEYXRhQ29udGFpbmVyLCB7IHN5bmM6IHRydWUsIGR1cmF0aW9uOiB0aGlzLnJlc2l6ZUR1cmF0aW9uIH0pIA0KICAgICAgICAgICAgXSwgDQogICAgICAgICAgICB7IA0KICAgICAgICAgICAgICAgIGR1cmF0aW9uOiB0aGlzLnJlc2l6ZUR1cmF0aW9uLCANCiAgICAgICAgICAgICAgICBhZnRlckZpbmlzaDogKGZ1bmN0aW9uKCkgew0KCSAgICAgICAgICAgICAgICAvLyB1cGRhdGUgb3ZlcmxheSBzaXplIGFuZCB1cGRhdGUgbmF2DQoJICAgICAgICAgICAgICAgIHZhciBhcnJheVBhZ2VTaXplID0gdGhpcy5nZXRQYWdlU2l6ZSgpOw0KCSAgICAgICAgICAgICAgICB0aGlzLm92ZXJsYXkuc2V0U3R5bGUoeyB3aWR0aDogYXJyYXlQYWdlU2l6ZVswXSArICdweCcsIGhlaWdodDogYXJyYXlQYWdlU2l6ZVsxXSArICdweCcgfSk7DQoJICAgICAgICAgICAgICAgIHRoaXMudXBkYXRlTmF2KCk7DQogICAgICAgICAgICAgICAgfSkuYmluZCh0aGlzKQ0KICAgICAgICAgICAgfSANCiAgICAgICAgKTsNCiAgICB9LA0KDQogICAgLy8NCiAgICAvLyAgdXBkYXRlTmF2KCkNCiAgICAvLyAgRGlzcGxheSBhcHByb3ByaWF0ZSBwcmV2aW91cyBhbmQgbmV4dCBob3ZlciBuYXZpZ2F0aW9uLg0KICAgIC8vDQogICAgdXBkYXRlTmF2OiBmdW5jdGlvbigpIHsNCg0KICAgICAgICB0aGlzLmhvdmVyTmF2LnNob3coKTsgICAgICAgICAgICAgICANCg0KICAgICAgICAvLyBpZiBub3QgZmlyc3QgaW1hZ2UgaW4gc2V0LCBkaXNwbGF5IHByZXYgaW1hZ2UgYnV0dG9uDQogICAgICAgIGlmICh0aGlzLmFjdGl2ZUltYWdlID4gMCkgdGhpcy5wcmV2TGluay5zaG93KCk7DQoNCiAgICAgICAgLy8gaWYgbm90IGxhc3QgaW1hZ2UgaW4gc2V0LCBkaXNwbGF5IG5leHQgaW1hZ2UgYnV0dG9uDQogICAgICAgIGlmICh0aGlzLmFjdGl2ZUltYWdlIDwgKHRoaXMuaW1hZ2VBcnJheS5sZW5ndGggLSAxKSkgdGhpcy5uZXh0TGluay5zaG93KCk7DQogICAgICAgIA0KICAgICAgICB0aGlzLmVuYWJsZUtleWJvYXJkTmF2KCk7DQogICAgfSwNCg0KICAgIC8vDQogICAgLy8gIGVuYWJsZUtleWJvYXJkTmF2KCkNCiAgICAvLw0KICAgIGVuYWJsZUtleWJvYXJkTmF2OiBmdW5jdGlvbigpIHsNCiAgICAgICAgZG9jdW1lbnQub2JzZXJ2ZSgna2V5ZG93bicsIHRoaXMua2V5Ym9hcmRBY3Rpb24pOyANCiAgICB9LA0KDQogICAgLy8NCiAgICAvLyAgZGlzYWJsZUtleWJvYXJkTmF2KCkNCiAgICAvLw0KICAgIGRpc2FibGVLZXlib2FyZE5hdjogZnVuY3Rpb24oKSB7DQogICAgICAgIGRvY3VtZW50LnN0b3BPYnNlcnZpbmcoJ2tleWRvd24nLCB0aGlzLmtleWJvYXJkQWN0aW9uKTsgDQogICAgfSwNCg0KICAgIC8vDQogICAgLy8gIGtleWJvYXJkQWN0aW9uKCkNCiAgICAvLw0KICAgIGtleWJvYXJkQWN0aW9uOiBmdW5jdGlvbihldmVudCkgew0KICAgICAgICB2YXIga2V5Y29kZSA9IGV2ZW50LmtleUNvZGU7DQoNCiAgICAgICAgdmFyIGVzY2FwZUtleTsNCiAgICAgICAgaWYgKGV2ZW50LkRPTV9WS19FU0NBUEUpIHsgIC8vIG1vemlsbGENCiAgICAgICAgICAgIGVzY2FwZUtleSA9IGV2ZW50LkRPTV9WS19FU0NBUEU7DQogICAgICAgIH0gZWxzZSB7IC8vIGllDQogICAgICAgICAgICBlc2NhcGVLZXkgPSAyNzsNCiAgICAgICAgfQ0KDQogICAgICAgIHZhciBrZXkgPSBTdHJpbmcuZnJvbUNoYXJDb2RlKGtleWNvZGUpLnRvTG93ZXJDYXNlKCk7DQogICAgICAgIA0KICAgICAgICBpZiAoa2V5Lm1hdGNoKC94fG98Yy8pIHx8IChrZXljb2RlID09IGVzY2FwZUtleSkpeyAvLyBjbG9zZSBsaWdodGJveA0KICAgICAgICAgICAgdGhpcy5lbmQoKTsNCiAgICAgICAgfSBlbHNlIGlmICgoa2V5ID09ICdwJykgfHwgKGtleWNvZGUgPT0gMzcpKXsgLy8gZGlzcGxheSBwcmV2aW91cyBpbWFnZQ0KICAgICAgICAgICAgaWYgKHRoaXMuYWN0aXZlSW1hZ2UgIT0gMCl7DQogICAgICAgICAgICAgICAgdGhpcy5kaXNhYmxlS2V5Ym9hcmROYXYoKTsNCiAgICAgICAgICAgICAgICB0aGlzLmNoYW5nZUltYWdlKHRoaXMuYWN0aXZlSW1hZ2UgLSAxKTsNCiAgICAgICAgICAgIH0NCiAgICAgICAgfSBlbHNlIGlmICgoa2V5ID09ICduJykgfHwgKGtleWNvZGUgPT0gMzkpKXsgLy8gZGlzcGxheSBuZXh0IGltYWdlDQogICAgICAgICAgICBpZiAodGhpcy5hY3RpdmVJbWFnZSAhPSAodGhpcy5pbWFnZUFycmF5Lmxlbmd0aCAtIDEpKXsNCiAgICAgICAgICAgICAgICB0aGlzLmRpc2FibGVLZXlib2FyZE5hdigpOw0KICAgICAgICAgICAgICAgIHRoaXMuY2hhbmdlSW1hZ2UodGhpcy5hY3RpdmVJbWFnZSArIDEpOw0KICAgICAgICAgICAgfQ0KICAgICAgICB9DQogICAgfSwNCg0KICAgIC8vDQogICAgLy8gIHByZWxvYWROZWlnaGJvckltYWdlcygpDQogICAgLy8gIFByZWxvYWQgcHJldmlvdXMgYW5kIG5leHQgaW1hZ2VzLg0KICAgIC8vDQogICAgcHJlbG9hZE5laWdoYm9ySW1hZ2VzOiBmdW5jdGlvbigpew0KICAgICAgICB2YXIgcHJlbG9hZE5leHRJbWFnZSwgcHJlbG9hZFByZXZJbWFnZTsNCiAgICAgICAgaWYgKHRoaXMuaW1hZ2VBcnJheS5sZW5ndGggPiB0aGlzLmFjdGl2ZUltYWdlICsgMSl7DQogICAgICAgICAgICBwcmVsb2FkTmV4dEltYWdlID0gbmV3IEltYWdlKCk7DQogICAgICAgICAgICBwcmVsb2FkTmV4dEltYWdlLnNyYyA9IHRoaXMuaW1hZ2VBcnJheVt0aGlzLmFjdGl2ZUltYWdlICsgMV1bMF07DQogICAgICAgIH0NCiAgICAgICAgaWYgKHRoaXMuYWN0aXZlSW1hZ2UgPiAwKXsNCiAgICAgICAgICAgIHByZWxvYWRQcmV2SW1hZ2UgPSBuZXcgSW1hZ2UoKTsNCiAgICAgICAgICAgIHByZWxvYWRQcmV2SW1hZ2Uuc3JjID0gdGhpcy5pbWFnZUFycmF5W3RoaXMuYWN0aXZlSW1hZ2UgLSAxXVswXTsNCiAgICAgICAgfQ0KICAgIA0KICAgIH0sDQoNCiAgICAvLw0KICAgIC8vICBlbmQoKQ0KICAgIC8vDQogICAgZW5kOiBmdW5jdGlvbigpIHsNCiAgICAgICAgdGhpcy5kaXNhYmxlS2V5Ym9hcmROYXYoKTsNCiAgICAgICAgdGhpcy5saWdodGJveC5oaWRlKCk7DQogICAgICAgIG5ldyBFZmZlY3QuRmFkZSh0aGlzLm92ZXJsYXksIHsgZHVyYXRpb246IHRoaXMub3ZlcmxheUR1cmF0aW9uIH0pOw0KICAgICAgICAkJCgnc2VsZWN0JywgJ29iamVjdCcsICdlbWJlZCcpLmVhY2goZnVuY3Rpb24obm9kZSl7IG5vZGUuc3R5bGUudmlzaWJpbGl0eSA9ICd2aXNpYmxlJyB9KTsNCiAgICB9LA0KDQogICAgLy8NCiAgICAvLyAgZ2V0UGFnZVNpemUoKQ0KICAgIC8vDQogICAgZ2V0UGFnZVNpemU6IGZ1bmN0aW9uKCkgew0KCSAgICAgICAgDQoJICAgICB2YXIgeFNjcm9sbCwgeVNjcm9sbDsNCgkJDQoJCWlmICh3aW5kb3cuaW5uZXJIZWlnaHQgJiYgd2luZG93LnNjcm9sbE1heFkpIHsJDQoJCQl4U2Nyb2xsID0gd2luZG93LmlubmVyV2lkdGggKyB3aW5kb3cuc2Nyb2xsTWF4WDsNCgkJCXlTY3JvbGwgPSB3aW5kb3cuaW5uZXJIZWlnaHQgKyB3aW5kb3cuc2Nyb2xsTWF4WTsNCgkJfSBlbHNlIGlmIChkb2N1bWVudC5ib2R5LnNjcm9sbEhlaWdodCA+IGRvY3VtZW50LmJvZHkub2Zmc2V0SGVpZ2h0KXsgLy8gYWxsIGJ1dCBFeHBsb3JlciBNYWMNCgkJCXhTY3JvbGwgPSBkb2N1bWVudC5ib2R5LnNjcm9sbFdpZHRoOw0KCQkJeVNjcm9sbCA9IGRvY3VtZW50LmJvZHkuc2Nyb2xsSGVpZ2h0Ow0KCQl9IGVsc2UgeyAvLyBFeHBsb3JlciBNYWMuLi53b3VsZCBhbHNvIHdvcmsgaW4gRXhwbG9yZXIgNiBTdHJpY3QsIE1vemlsbGEgYW5kIFNhZmFyaQ0KCQkJeFNjcm9sbCA9IGRvY3VtZW50LmJvZHkub2Zmc2V0V2lkdGg7DQoJCQl5U2Nyb2xsID0gZG9jdW1lbnQuYm9keS5vZmZzZXRIZWlnaHQ7DQoJCX0NCgkJDQoJCXZhciB3aW5kb3dXaWR0aCwgd2luZG93SGVpZ2h0Ow0KCQkNCgkJaWYgKHNlbGYuaW5uZXJIZWlnaHQpIHsJLy8gYWxsIGV4Y2VwdCBFeHBsb3Jlcg0KCQkJaWYoZG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50LmNsaWVudFdpZHRoKXsNCgkJCQl3aW5kb3dXaWR0aCA9IGRvY3VtZW50LmRvY3VtZW50RWxlbWVudC5jbGllbnRXaWR0aDsgDQoJCQl9IGVsc2Ugew0KCQkJCXdpbmRvd1dpZHRoID0gc2VsZi5pbm5lcldpZHRoOw0KCQkJfQ0KCQkJd2luZG93SGVpZ2h0ID0gc2VsZi5pbm5lckhlaWdodDsNCgkJfSBlbHNlIGlmIChkb2N1bWVudC5kb2N1bWVudEVsZW1lbnQgJiYgZG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50LmNsaWVudEhlaWdodCkgeyAvLyBFeHBsb3JlciA2IFN0cmljdCBNb2RlDQoJCQl3aW5kb3dXaWR0aCA9IGRvY3VtZW50LmRvY3VtZW50RWxlbWVudC5jbGllbnRXaWR0aDsNCgkJCXdpbmRvd0hlaWdodCA9IGRvY3VtZW50LmRvY3VtZW50RWxlbWVudC5jbGllbnRIZWlnaHQ7DQoJCX0gZWxzZSBpZiAoZG9jdW1lbnQuYm9keSkgeyAvLyBvdGhlciBFeHBsb3JlcnMNCgkJCXdpbmRvd1dpZHRoID0gZG9jdW1lbnQuYm9keS5jbGllbnRXaWR0aDsNCgkJCXdpbmRvd0hlaWdodCA9IGRvY3VtZW50LmJvZHkuY2xpZW50SGVpZ2h0Ow0KCQl9CQ0KDQoJCS8vIGZvciBzbWFsbCBwYWdlcyB3aXRoIHRvdGFsIGhlaWdodCBsZXNzIHRoZW4gaGVpZ2h0IG9mIHRoZSB2aWV3cG9ydA0KCQlpZih5U2Nyb2xsIDwgd2luZG93SGVpZ2h0KXsNCgkJCXBhZ2VIZWlnaHQgPSB3aW5kb3dIZWlnaHQ7DQoJCX0gZWxzZSB7IA0KCQkJcGFnZUhlaWdodCA9IHlTY3JvbGw7DQoJCX0NCgkNCgkJLy8gZm9yIHNtYWxsIHBhZ2VzIHdpdGggdG90YWwgd2lkdGggbGVzcyB0aGVuIHdpZHRoIG9mIHRoZSB2aWV3cG9ydA0KCQlpZih4U2Nyb2xsIDwgd2luZG93V2lkdGgpewkNCgkJCXBhZ2VXaWR0aCA9IHhTY3JvbGw7CQkNCgkJfSBlbHNlIHsNCgkJCXBhZ2VXaWR0aCA9IHdpbmRvd1dpZHRoOw0KCQl9DQoNCgkJcmV0dXJuIFtwYWdlV2lkdGgscGFnZUhlaWdodF07DQoJfQ0KfQ0KDQpkb2N1bWVudC5vYnNlcnZlKCdkb206bG9hZGVkJywgZnVuY3Rpb24gKCkgeyBuZXcgTGlnaHRib3goKTsgfSk7]]></data>
	</file>
	<file>
	  <filename>/js/prototype.js</filename>
	  <isdir>0</isdir>
	  <data><![CDATA[LyogIFByb3RvdHlwZSBKYXZhU2NyaXB0IGZyYW1ld29yaywgdmVyc2lvbiAxLjcKICogIChjKSAyMDA1LTIwMTAgU2FtIFN0ZXBoZW5zb24KICoKICogIFByb3RvdHlwZSBpcyBmcmVlbHkgZGlzdHJpYnV0YWJsZSB1bmRlciB0aGUgdGVybXMgb2YgYW4gTUlULXN0eWxlIGxpY2Vuc2UuCiAqICBGb3IgZGV0YWlscywgc2VlIHRoZSBQcm90b3R5cGUgd2ViIHNpdGU6IGh0dHA6Ly93d3cucHJvdG90eXBlanMub3JnLwogKgogKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi8KCnZhciBQcm90b3R5cGUgPSB7CgogIFZlcnNpb246ICcxLjcnLAoKICBCcm93c2VyOiAoZnVuY3Rpb24oKXsKICAgIHZhciB1YSA9IG5hdmlnYXRvci51c2VyQWdlbnQ7CiAgICB2YXIgaXNPcGVyYSA9IE9iamVjdC5wcm90b3R5cGUudG9TdHJpbmcuY2FsbCh3aW5kb3cub3BlcmEpID09ICdbb2JqZWN0IE9wZXJhXSc7CiAgICByZXR1cm4gewogICAgICBJRTogICAgICAgICAgICAgISF3aW5kb3cuYXR0YWNoRXZlbnQgJiYgIWlzT3BlcmEsCiAgICAgIE9wZXJhOiAgICAgICAgICBpc09wZXJhLAogICAgICBXZWJLaXQ6ICAgICAgICAgdWEuaW5kZXhPZignQXBwbGVXZWJLaXQvJykgPiAtMSwKICAgICAgR2Vja286ICAgICAgICAgIHVhLmluZGV4T2YoJ0dlY2tvJykgPiAtMSAmJiB1YS5pbmRleE9mKCdLSFRNTCcpID09PSAtMSwKICAgICAgTW9iaWxlU2FmYXJpOiAgIC9BcHBsZS4qTW9iaWxlLy50ZXN0KHVhKQogICAgfQogIH0pKCksCgogIEJyb3dzZXJGZWF0dXJlczogewogICAgWFBhdGg6ICEhZG9jdW1lbnQuZXZhbHVhdGUsCgogICAgU2VsZWN0b3JzQVBJOiAhIWRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IsCgogICAgRWxlbWVudEV4dGVuc2lvbnM6IChmdW5jdGlvbigpIHsKICAgICAgdmFyIGNvbnN0cnVjdG9yID0gd2luZG93LkVsZW1lbnQgfHwgd2luZG93LkhUTUxFbGVtZW50OwogICAgICByZXR1cm4gISEoY29uc3RydWN0b3IgJiYgY29uc3RydWN0b3IucHJvdG90eXBlKTsKICAgIH0pKCksCiAgICBTcGVjaWZpY0VsZW1lbnRFeHRlbnNpb25zOiAoZnVuY3Rpb24oKSB7CiAgICAgIGlmICh0eXBlb2Ygd2luZG93LkhUTUxEaXZFbGVtZW50ICE9PSAndW5kZWZpbmVkJykKICAgICAgICByZXR1cm4gdHJ1ZTsKCiAgICAgIHZhciBkaXYgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdkaXYnKSwKICAgICAgICAgIGZvcm0gPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdmb3JtJyksCiAgICAgICAgICBpc1N1cHBvcnRlZCA9IGZhbHNlOwoKICAgICAgaWYgKGRpdlsnX19wcm90b19fJ10gJiYgKGRpdlsnX19wcm90b19fJ10gIT09IGZvcm1bJ19fcHJvdG9fXyddKSkgewogICAgICAgIGlzU3VwcG9ydGVkID0gdHJ1ZTsKICAgICAgfQoKICAgICAgZGl2ID0gZm9ybSA9IG51bGw7CgogICAgICByZXR1cm4gaXNTdXBwb3J0ZWQ7CiAgICB9KSgpCiAgfSwKCiAgU2NyaXB0RnJhZ21lbnQ6ICc8c2NyaXB0W14+XSo+KFtcXFNcXHNdKj8pPFwvc2NyaXB0PicsCiAgSlNPTkZpbHRlcjogL15cL1wqLXNlY3VyZS0oW1xzXFNdKilcKlwvXHMqJC8sCgogIGVtcHR5RnVuY3Rpb246IGZ1bmN0aW9uKCkgeyB9LAoKICBLOiBmdW5jdGlvbih4KSB7IHJldHVybiB4IH0KfTsKCmlmIChQcm90b3R5cGUuQnJvd3Nlci5Nb2JpbGVTYWZhcmkpCiAgUHJvdG90eXBlLkJyb3dzZXJGZWF0dXJlcy5TcGVjaWZpY0VsZW1lbnRFeHRlbnNpb25zID0gZmFsc2U7Ci8qIEJhc2VkIG9uIEFsZXggQXJuZWxsJ3MgaW5oZXJpdGFuY2UgaW1wbGVtZW50YXRpb24uICovCgp2YXIgQ2xhc3MgPSAoZnVuY3Rpb24oKSB7CgogIHZhciBJU19ET05URU5VTV9CVUdHWSA9IChmdW5jdGlvbigpewogICAgZm9yICh2YXIgcCBpbiB7IHRvU3RyaW5nOiAxIH0pIHsKICAgICAgaWYgKHAgPT09ICd0b1N0cmluZycpIHJldHVybiBmYWxzZTsKICAgIH0KICAgIHJldHVybiB0cnVlOwogIH0pKCk7CgogIGZ1bmN0aW9uIHN1YmNsYXNzKCkge307CiAgZnVuY3Rpb24gY3JlYXRlKCkgewogICAgdmFyIHBhcmVudCA9IG51bGwsIHByb3BlcnRpZXMgPSAkQShhcmd1bWVudHMpOwogICAgaWYgKE9iamVjdC5pc0Z1bmN0aW9uKHByb3BlcnRpZXNbMF0pKQogICAgICBwYXJlbnQgPSBwcm9wZXJ0aWVzLnNoaWZ0KCk7CgogICAgZnVuY3Rpb24ga2xhc3MoKSB7CiAgICAgIHRoaXMuaW5pdGlhbGl6ZS5hcHBseSh0aGlzLCBhcmd1bWVudHMpOwogICAgfQoKICAgIE9iamVjdC5leHRlbmQoa2xhc3MsIENsYXNzLk1ldGhvZHMpOwogICAga2xhc3Muc3VwZXJjbGFzcyA9IHBhcmVudDsKICAgIGtsYXNzLnN1YmNsYXNzZXMgPSBbXTsKCiAgICBpZiAocGFyZW50KSB7CiAgICAgIHN1YmNsYXNzLnByb3RvdHlwZSA9IHBhcmVudC5wcm90b3R5cGU7CiAgICAgIGtsYXNzLnByb3RvdHlwZSA9IG5ldyBzdWJjbGFzczsKICAgICAgcGFyZW50LnN1YmNsYXNzZXMucHVzaChrbGFzcyk7CiAgICB9CgogICAgZm9yICh2YXIgaSA9IDAsIGxlbmd0aCA9IHByb3BlcnRpZXMubGVuZ3RoOyBpIDwgbGVuZ3RoOyBpKyspCiAgICAgIGtsYXNzLmFkZE1ldGhvZHMocHJvcGVydGllc1tpXSk7CgogICAgaWYgKCFrbGFzcy5wcm90b3R5cGUuaW5pdGlhbGl6ZSkKICAgICAga2xhc3MucHJvdG90eXBlLmluaXRpYWxpemUgPSBQcm90b3R5cGUuZW1wdHlGdW5jdGlvbjsKCiAgICBrbGFzcy5wcm90b3R5cGUuY29uc3RydWN0b3IgPSBrbGFzczsKICAgIHJldHVybiBrbGFzczsKICB9CgogIGZ1bmN0aW9uIGFkZE1ldGhvZHMoc291cmNlKSB7CiAgICB2YXIgYW5jZXN0b3IgICA9IHRoaXMuc3VwZXJjbGFzcyAmJiB0aGlzLnN1cGVyY2xhc3MucHJvdG90eXBlLAogICAgICAgIHByb3BlcnRpZXMgPSBPYmplY3Qua2V5cyhzb3VyY2UpOwoKICAgIGlmIChJU19ET05URU5VTV9CVUdHWSkgewogICAgICBpZiAoc291cmNlLnRvU3RyaW5nICE9IE9iamVjdC5wcm90b3R5cGUudG9TdHJpbmcpCiAgICAgICAgcHJvcGVydGllcy5wdXNoKCJ0b1N0cmluZyIpOwogICAgICBpZiAoc291cmNlLnZhbHVlT2YgIT0gT2JqZWN0LnByb3RvdHlwZS52YWx1ZU9mKQogICAgICAgIHByb3BlcnRpZXMucHVzaCgidmFsdWVPZiIpOwogICAgfQoKICAgIGZvciAodmFyIGkgPSAwLCBsZW5ndGggPSBwcm9wZXJ0aWVzLmxlbmd0aDsgaSA8IGxlbmd0aDsgaSsrKSB7CiAgICAgIHZhciBwcm9wZXJ0eSA9IHByb3BlcnRpZXNbaV0sIHZhbHVlID0gc291cmNlW3Byb3BlcnR5XTsKICAgICAgaWYgKGFuY2VzdG9yICYmIE9iamVjdC5pc0Z1bmN0aW9uKHZhbHVlKSAmJgogICAgICAgICAgdmFsdWUuYXJndW1lbnROYW1lcygpWzBdID09ICIkc3VwZXIiKSB7CiAgICAgICAgdmFyIG1ldGhvZCA9IHZhbHVlOwogICAgICAgIHZhbHVlID0gKGZ1bmN0aW9uKG0pIHsKICAgICAgICAgIHJldHVybiBmdW5jdGlvbigpIHsgcmV0dXJuIGFuY2VzdG9yW21dLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7IH07CiAgICAgICAgfSkocHJvcGVydHkpLndyYXAobWV0aG9kKTsKCiAgICAgICAgdmFsdWUudmFsdWVPZiA9IG1ldGhvZC52YWx1ZU9mLmJpbmQobWV0aG9kKTsKICAgICAgICB2YWx1ZS50b1N0cmluZyA9IG1ldGhvZC50b1N0cmluZy5iaW5kKG1ldGhvZCk7CiAgICAgIH0KICAgICAgdGhpcy5wcm90b3R5cGVbcHJvcGVydHldID0gdmFsdWU7CiAgICB9CgogICAgcmV0dXJuIHRoaXM7CiAgfQoKICByZXR1cm4gewogICAgY3JlYXRlOiBjcmVhdGUsCiAgICBNZXRob2RzOiB7CiAgICAgIGFkZE1ldGhvZHM6IGFkZE1ldGhvZHMKICAgIH0KICB9Owp9KSgpOwooZnVuY3Rpb24oKSB7CgogIHZhciBfdG9TdHJpbmcgPSBPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nLAogICAgICBOVUxMX1RZUEUgPSAnTnVsbCcsCiAgICAgIFVOREVGSU5FRF9UWVBFID0gJ1VuZGVmaW5lZCcsCiAgICAgIEJPT0xFQU5fVFlQRSA9ICdCb29sZWFuJywKICAgICAgTlVNQkVSX1RZUEUgPSAnTnVtYmVyJywKICAgICAgU1RSSU5HX1RZUEUgPSAnU3RyaW5nJywKICAgICAgT0JKRUNUX1RZUEUgPSAnT2JqZWN0JywKICAgICAgRlVOQ1RJT05fQ0xBU1MgPSAnW29iamVjdCBGdW5jdGlvbl0nLAogICAgICBCT09MRUFOX0NMQVNTID0gJ1tvYmplY3QgQm9vbGVhbl0nLAogICAgICBOVU1CRVJfQ0xBU1MgPSAnW29iamVjdCBOdW1iZXJdJywKICAgICAgU1RSSU5HX0NMQVNTID0gJ1tvYmplY3QgU3RyaW5nXScsCiAgICAgIEFSUkFZX0NMQVNTID0gJ1tvYmplY3QgQXJyYXldJywKICAgICAgREFURV9DTEFTUyA9ICdbb2JqZWN0IERhdGVdJywKICAgICAgTkFUSVZFX0pTT05fU1RSSU5HSUZZX1NVUFBPUlQgPSB3aW5kb3cuSlNPTiAmJgogICAgICAgIHR5cGVvZiBKU09OLnN0cmluZ2lmeSA9PT0gJ2Z1bmN0aW9uJyAmJgogICAgICAgIEpTT04uc3RyaW5naWZ5KDApID09PSAnMCcgJiYKICAgICAgICB0eXBlb2YgSlNPTi5zdHJpbmdpZnkoUHJvdG90eXBlLkspID09PSAndW5kZWZpbmVkJzsKCiAgZnVuY3Rpb24gVHlwZShvKSB7CiAgICBzd2l0Y2gobykgewogICAgICBjYXNlIG51bGw6IHJldHVybiBOVUxMX1RZUEU7CiAgICAgIGNhc2UgKHZvaWQgMCk6IHJldHVybiBVTkRFRklORURfVFlQRTsKICAgIH0KICAgIHZhciB0eXBlID0gdHlwZW9mIG87CiAgICBzd2l0Y2godHlwZSkgewogICAgICBjYXNlICdib29sZWFuJzogcmV0dXJuIEJPT0xFQU5fVFlQRTsKICAgICAgY2FzZSAnbnVtYmVyJzogIHJldHVybiBOVU1CRVJfVFlQRTsKICAgICAgY2FzZSAnc3RyaW5nJzogIHJldHVybiBTVFJJTkdfVFlQRTsKICAgIH0KICAgIHJldHVybiBPQkpFQ1RfVFlQRTsKICB9CgogIGZ1bmN0aW9uIGV4dGVuZChkZXN0aW5hdGlvbiwgc291cmNlKSB7CiAgICBmb3IgKHZhciBwcm9wZXJ0eSBpbiBzb3VyY2UpCiAgICAgIGRlc3RpbmF0aW9uW3Byb3BlcnR5XSA9IHNvdXJjZVtwcm9wZXJ0eV07CiAgICByZXR1cm4gZGVzdGluYXRpb247CiAgfQoKICBmdW5jdGlvbiBpbnNwZWN0KG9iamVjdCkgewogICAgdHJ5IHsKICAgICAgaWYgKGlzVW5kZWZpbmVkKG9iamVjdCkpIHJldHVybiAndW5kZWZpbmVkJzsKICAgICAgaWYgKG9iamVjdCA9PT0gbnVsbCkgcmV0dXJuICdudWxsJzsKICAgICAgcmV0dXJuIG9iamVjdC5pbnNwZWN0ID8gb2JqZWN0Lmluc3BlY3QoKSA6IFN0cmluZyhvYmplY3QpOwogICAgfSBjYXRjaCAoZSkgewogICAgICBpZiAoZSBpbnN0YW5jZW9mIFJhbmdlRXJyb3IpIHJldHVybiAnLi4uJzsKICAgICAgdGhyb3cgZTsKICAgIH0KICB9CgogIGZ1bmN0aW9uIHRvSlNPTih2YWx1ZSkgewogICAgcmV0dXJuIFN0cignJywgeyAnJzogdmFsdWUgfSwgW10pOwogIH0KCiAgZnVuY3Rpb24gU3RyKGtleSwgaG9sZGVyLCBzdGFjaykgewogICAgdmFyIHZhbHVlID0gaG9sZGVyW2tleV0sCiAgICAgICAgdHlwZSA9IHR5cGVvZiB2YWx1ZTsKCiAgICBpZiAoVHlwZSh2YWx1ZSkgPT09IE9CSkVDVF9UWVBFICYmIHR5cGVvZiB2YWx1ZS50b0pTT04gPT09ICdmdW5jdGlvbicpIHsKICAgICAgdmFsdWUgPSB2YWx1ZS50b0pTT04oa2V5KTsKICAgIH0KCiAgICB2YXIgX2NsYXNzID0gX3RvU3RyaW5nLmNhbGwodmFsdWUpOwoKICAgIHN3aXRjaCAoX2NsYXNzKSB7CiAgICAgIGNhc2UgTlVNQkVSX0NMQVNTOgogICAgICBjYXNlIEJPT0xFQU5fQ0xBU1M6CiAgICAgIGNhc2UgU1RSSU5HX0NMQVNTOgogICAgICAgIHZhbHVlID0gdmFsdWUudmFsdWVPZigpOwogICAgfQoKICAgIHN3aXRjaCAodmFsdWUpIHsKICAgICAgY2FzZSBudWxsOiByZXR1cm4gJ251bGwnOwogICAgICBjYXNlIHRydWU6IHJldHVybiAndHJ1ZSc7CiAgICAgIGNhc2UgZmFsc2U6IHJldHVybiAnZmFsc2UnOwogICAgfQoKICAgIHR5cGUgPSB0eXBlb2YgdmFsdWU7CiAgICBzd2l0Y2ggKHR5cGUpIHsKICAgICAgY2FzZSAnc3RyaW5nJzoKICAgICAgICByZXR1cm4gdmFsdWUuaW5zcGVjdCh0cnVlKTsKICAgICAgY2FzZSAnbnVtYmVyJzoKICAgICAgICByZXR1cm4gaXNGaW5pdGUodmFsdWUpID8gU3RyaW5nKHZhbHVlKSA6ICdudWxsJzsKICAgICAgY2FzZSAnb2JqZWN0JzoKCiAgICAgICAgZm9yICh2YXIgaSA9IDAsIGxlbmd0aCA9IHN0YWNrLmxlbmd0aDsgaSA8IGxlbmd0aDsgaSsrKSB7CiAgICAgICAgICBpZiAoc3RhY2tbaV0gPT09IHZhbHVlKSB7IHRocm93IG5ldyBUeXBlRXJyb3IoKTsgfQogICAgICAgIH0KICAgICAgICBzdGFjay5wdXNoKHZhbHVlKTsKCiAgICAgICAgdmFyIHBhcnRpYWwgPSBbXTsKICAgICAgICBpZiAoX2NsYXNzID09PSBBUlJBWV9DTEFTUykgewogICAgICAgICAgZm9yICh2YXIgaSA9IDAsIGxlbmd0aCA9IHZhbHVlLmxlbmd0aDsgaSA8IGxlbmd0aDsgaSsrKSB7CiAgICAgICAgICAgIHZhciBzdHIgPSBTdHIoaSwgdmFsdWUsIHN0YWNrKTsKICAgICAgICAgICAgcGFydGlhbC5wdXNoKHR5cGVvZiBzdHIgPT09ICd1bmRlZmluZWQnID8gJ251bGwnIDogc3RyKTsKICAgICAgICAgIH0KICAgICAgICAgIHBhcnRpYWwgPSAnWycgKyBwYXJ0aWFsLmpvaW4oJywnKSArICddJzsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgdmFyIGtleXMgPSBPYmplY3Qua2V5cyh2YWx1ZSk7CiAgICAgICAgICBmb3IgKHZhciBpID0gMCwgbGVuZ3RoID0ga2V5cy5sZW5ndGg7IGkgPCBsZW5ndGg7IGkrKykgewogICAgICAgICAgICB2YXIga2V5ID0ga2V5c1tpXSwgc3RyID0gU3RyKGtleSwgdmFsdWUsIHN0YWNrKTsKICAgICAgICAgICAgaWYgKHR5cGVvZiBzdHIgIT09ICJ1bmRlZmluZWQiKSB7CiAgICAgICAgICAgICAgIHBhcnRpYWwucHVzaChrZXkuaW5zcGVjdCh0cnVlKSsgJzonICsgc3RyKTsKICAgICAgICAgICAgIH0KICAgICAgICAgIH0KICAgICAgICAgIHBhcnRpYWwgPSAneycgKyBwYXJ0aWFsLmpvaW4oJywnKSArICd9JzsKICAgICAgICB9CiAgICAgICAgc3RhY2sucG9wKCk7CiAgICAgICAgcmV0dXJuIHBhcnRpYWw7CiAgICB9CiAgfQoKICBmdW5jdGlvbiBzdHJpbmdpZnkob2JqZWN0KSB7CiAgICByZXR1cm4gSlNPTi5zdHJpbmdpZnkob2JqZWN0KTsKICB9CgogIGZ1bmN0aW9uIHRvUXVlcnlTdHJpbmcob2JqZWN0KSB7CiAgICByZXR1cm4gJEgob2JqZWN0KS50b1F1ZXJ5U3RyaW5nKCk7CiAgfQoKICBmdW5jdGlvbiB0b0hUTUwob2JqZWN0KSB7CiAgICByZXR1cm4gb2JqZWN0ICYmIG9iamVjdC50b0hUTUwgPyBvYmplY3QudG9IVE1MKCkgOiBTdHJpbmcuaW50ZXJwcmV0KG9iamVjdCk7CiAgfQoKICBmdW5jdGlvbiBrZXlzKG9iamVjdCkgewogICAgaWYgKFR5cGUob2JqZWN0KSAhPT0gT0JKRUNUX1RZUEUpIHsgdGhyb3cgbmV3IFR5cGVFcnJvcigpOyB9CiAgICB2YXIgcmVzdWx0cyA9IFtdOwogICAgZm9yICh2YXIgcHJvcGVydHkgaW4gb2JqZWN0KSB7CiAgICAgIGlmIChvYmplY3QuaGFzT3duUHJvcGVydHkocHJvcGVydHkpKSB7CiAgICAgICAgcmVzdWx0cy5wdXNoKHByb3BlcnR5KTsKICAgICAgfQogICAgfQogICAgcmV0dXJuIHJlc3VsdHM7CiAgfQoKICBmdW5jdGlvbiB2YWx1ZXMob2JqZWN0KSB7CiAgICB2YXIgcmVzdWx0cyA9IFtdOwogICAgZm9yICh2YXIgcHJvcGVydHkgaW4gb2JqZWN0KQogICAgICByZXN1bHRzLnB1c2gob2JqZWN0W3Byb3BlcnR5XSk7CiAgICByZXR1cm4gcmVzdWx0czsKICB9CgogIGZ1bmN0aW9uIGNsb25lKG9iamVjdCkgewogICAgcmV0dXJuIGV4dGVuZCh7IH0sIG9iamVjdCk7CiAgfQoKICBmdW5jdGlvbiBpc0VsZW1lbnQob2JqZWN0KSB7CiAgICByZXR1cm4gISEob2JqZWN0ICYmIG9iamVjdC5ub2RlVHlwZSA9PSAxKTsKICB9CgogIGZ1bmN0aW9uIGlzQXJyYXkob2JqZWN0KSB7CiAgICByZXR1cm4gX3RvU3RyaW5nLmNhbGwob2JqZWN0KSA9PT0gQVJSQVlfQ0xBU1M7CiAgfQoKICB2YXIgaGFzTmF0aXZlSXNBcnJheSA9ICh0eXBlb2YgQXJyYXkuaXNBcnJheSA9PSAnZnVuY3Rpb24nKQogICAgJiYgQXJyYXkuaXNBcnJheShbXSkgJiYgIUFycmF5LmlzQXJyYXkoe30pOwoKICBpZiAoaGFzTmF0aXZlSXNBcnJheSkgewogICAgaXNBcnJheSA9IEFycmF5LmlzQXJyYXk7CiAgfQoKICBmdW5jdGlvbiBpc0hhc2gob2JqZWN0KSB7CiAgICByZXR1cm4gb2JqZWN0IGluc3RhbmNlb2YgSGFzaDsKICB9CgogIGZ1bmN0aW9uIGlzRnVuY3Rpb24ob2JqZWN0KSB7CiAgICByZXR1cm4gX3RvU3RyaW5nLmNhbGwob2JqZWN0KSA9PT0gRlVOQ1RJT05fQ0xBU1M7CiAgfQoKICBmdW5jdGlvbiBpc1N0cmluZyhvYmplY3QpIHsKICAgIHJldHVybiBfdG9TdHJpbmcuY2FsbChvYmplY3QpID09PSBTVFJJTkdfQ0xBU1M7CiAgfQoKICBmdW5jdGlvbiBpc051bWJlcihvYmplY3QpIHsKICAgIHJldHVybiBfdG9TdHJpbmcuY2FsbChvYmplY3QpID09PSBOVU1CRVJfQ0xBU1M7CiAgfQoKICBmdW5jdGlvbiBpc0RhdGUob2JqZWN0KSB7CiAgICByZXR1cm4gX3RvU3RyaW5nLmNhbGwob2JqZWN0KSA9PT0gREFURV9DTEFTUzsKICB9CgogIGZ1bmN0aW9uIGlzVW5kZWZpbmVkKG9iamVjdCkgewogICAgcmV0dXJuIHR5cGVvZiBvYmplY3QgPT09ICJ1bmRlZmluZWQiOwogIH0KCiAgZXh0ZW5kKE9iamVjdCwgewogICAgZXh0ZW5kOiAgICAgICAgZXh0ZW5kLAogICAgaW5zcGVjdDogICAgICAgaW5zcGVjdCwKICAgIHRvSlNPTjogICAgICAgIE5BVElWRV9KU09OX1NUUklOR0lGWV9TVVBQT1JUID8gc3RyaW5naWZ5IDogdG9KU09OLAogICAgdG9RdWVyeVN0cmluZzogdG9RdWVyeVN0cmluZywKICAgIHRvSFRNTDogICAgICAgIHRvSFRNTCwKICAgIGtleXM6ICAgICAgICAgIE9iamVjdC5rZXlzIHx8IGtleXMsCiAgICB2YWx1ZXM6ICAgICAgICB2YWx1ZXMsCiAgICBjbG9uZTogICAgICAgICBjbG9uZSwKICAgIGlzRWxlbWVudDogICAgIGlzRWxlbWVudCwKICAgIGlzQXJyYXk6ICAgICAgIGlzQXJyYXksCiAgICBpc0hhc2g6ICAgICAgICBpc0hhc2gsCiAgICBpc0Z1bmN0aW9uOiAgICBpc0Z1bmN0aW9uLAogICAgaXNTdHJpbmc6ICAgICAgaXNTdHJpbmcsCiAgICBpc051bWJlcjogICAgICBpc051bWJlciwKICAgIGlzRGF0ZTogICAgICAgIGlzRGF0ZSwKICAgIGlzVW5kZWZpbmVkOiAgIGlzVW5kZWZpbmVkCiAgfSk7Cn0pKCk7Ck9iamVjdC5leHRlbmQoRnVuY3Rpb24ucHJvdG90eXBlLCAoZnVuY3Rpb24oKSB7CiAgdmFyIHNsaWNlID0gQXJyYXkucHJvdG90eXBlLnNsaWNlOwoKICBmdW5jdGlvbiB1cGRhdGUoYXJyYXksIGFyZ3MpIHsKICAgIHZhciBhcnJheUxlbmd0aCA9IGFycmF5Lmxlbmd0aCwgbGVuZ3RoID0gYXJncy5sZW5ndGg7CiAgICB3aGlsZSAobGVuZ3RoLS0pIGFycmF5W2FycmF5TGVuZ3RoICsgbGVuZ3RoXSA9IGFyZ3NbbGVuZ3RoXTsKICAgIHJldHVybiBhcnJheTsKICB9CgogIGZ1bmN0aW9uIG1lcmdlKGFycmF5LCBhcmdzKSB7CiAgICBhcnJheSA9IHNsaWNlLmNhbGwoYXJyYXksIDApOwogICAgcmV0dXJuIHVwZGF0ZShhcnJheSwgYXJncyk7CiAgfQoKICBmdW5jdGlvbiBhcmd1bWVudE5hbWVzKCkgewogICAgdmFyIG5hbWVzID0gdGhpcy50b1N0cmluZygpLm1hdGNoKC9eW1xzXChdKmZ1bmN0aW9uW14oXSpcKChbXildKilcKS8pWzFdCiAgICAgIC5yZXBsYWNlKC9cL1wvLio/W1xyXG5dfFwvXCooPzoufFtcclxuXSkqP1wqXC8vZywgJycpCiAgICAgIC5yZXBsYWNlKC9ccysvZywgJycpLnNwbGl0KCcsJyk7CiAgICByZXR1cm4gbmFtZXMubGVuZ3RoID09IDEgJiYgIW5hbWVzWzBdID8gW10gOiBuYW1lczsKICB9CgogIGZ1bmN0aW9uIGJpbmQoY29udGV4dCkgewogICAgaWYgKGFyZ3VtZW50cy5sZW5ndGggPCAyICYmIE9iamVjdC5pc1VuZGVmaW5lZChhcmd1bWVudHNbMF0pKSByZXR1cm4gdGhpczsKICAgIHZhciBfX21ldGhvZCA9IHRoaXMsIGFyZ3MgPSBzbGljZS5jYWxsKGFyZ3VtZW50cywgMSk7CiAgICByZXR1cm4gZnVuY3Rpb24oKSB7CiAgICAgIHZhciBhID0gbWVyZ2UoYXJncywgYXJndW1lbnRzKTsKICAgICAgcmV0dXJuIF9fbWV0aG9kLmFwcGx5KGNvbnRleHQsIGEpOwogICAgfQogIH0KCiAgZnVuY3Rpb24gYmluZEFzRXZlbnRMaXN0ZW5lcihjb250ZXh0KSB7CiAgICB2YXIgX19tZXRob2QgPSB0aGlzLCBhcmdzID0gc2xpY2UuY2FsbChhcmd1bWVudHMsIDEpOwogICAgcmV0dXJuIGZ1bmN0aW9uKGV2ZW50KSB7CiAgICAgIHZhciBhID0gdXBkYXRlKFtldmVudCB8fCB3aW5kb3cuZXZlbnRdLCBhcmdzKTsKICAgICAgcmV0dXJuIF9fbWV0aG9kLmFwcGx5KGNvbnRleHQsIGEpOwogICAgfQogIH0KCiAgZnVuY3Rpb24gY3VycnkoKSB7CiAgICBpZiAoIWFyZ3VtZW50cy5sZW5ndGgpIHJldHVybiB0aGlzOwogICAgdmFyIF9fbWV0aG9kID0gdGhpcywgYXJncyA9IHNsaWNlLmNhbGwoYXJndW1lbnRzLCAwKTsKICAgIHJldHVybiBmdW5jdGlvbigpIHsKICAgICAgdmFyIGEgPSBtZXJnZShhcmdzLCBhcmd1bWVudHMpOwogICAgICByZXR1cm4gX19tZXRob2QuYXBwbHkodGhpcywgYSk7CiAgICB9CiAgfQoKICBmdW5jdGlvbiBkZWxheSh0aW1lb3V0KSB7CiAgICB2YXIgX19tZXRob2QgPSB0aGlzLCBhcmdzID0gc2xpY2UuY2FsbChhcmd1bWVudHMsIDEpOwogICAgdGltZW91dCA9IHRpbWVvdXQgKiAxMDAwOwogICAgcmV0dXJuIHdpbmRvdy5zZXRUaW1lb3V0KGZ1bmN0aW9uKCkgewogICAgICByZXR1cm4gX19tZXRob2QuYXBwbHkoX19tZXRob2QsIGFyZ3MpOwogICAgfSwgdGltZW91dCk7CiAgfQoKICBmdW5jdGlvbiBkZWZlcigpIHsKICAgIHZhciBhcmdzID0gdXBkYXRlKFswLjAxXSwgYXJndW1lbnRzKTsKICAgIHJldHVybiB0aGlzLmRlbGF5LmFwcGx5KHRoaXMsIGFyZ3MpOwogIH0KCiAgZnVuY3Rpb24gd3JhcCh3cmFwcGVyKSB7CiAgICB2YXIgX19tZXRob2QgPSB0aGlzOwogICAgcmV0dXJuIGZ1bmN0aW9uKCkgewogICAgICB2YXIgYSA9IHVwZGF0ZShbX19tZXRob2QuYmluZCh0aGlzKV0sIGFyZ3VtZW50cyk7CiAgICAgIHJldHVybiB3cmFwcGVyLmFwcGx5KHRoaXMsIGEpOwogICAgfQogIH0KCiAgZnVuY3Rpb24gbWV0aG9kaXplKCkgewogICAgaWYgKHRoaXMuX21ldGhvZGl6ZWQpIHJldHVybiB0aGlzLl9tZXRob2RpemVkOwogICAgdmFyIF9fbWV0aG9kID0gdGhpczsKICAgIHJldHVybiB0aGlzLl9tZXRob2RpemVkID0gZnVuY3Rpb24oKSB7CiAgICAgIHZhciBhID0gdXBkYXRlKFt0aGlzXSwgYXJndW1lbnRzKTsKICAgICAgcmV0dXJuIF9fbWV0aG9kLmFwcGx5KG51bGwsIGEpOwogICAgfTsKICB9CgogIHJldHVybiB7CiAgICBhcmd1bWVudE5hbWVzOiAgICAgICBhcmd1bWVudE5hbWVzLAogICAgYmluZDogICAgICAgICAgICAgICAgYmluZCwKICAgIGJpbmRBc0V2ZW50TGlzdGVuZXI6IGJpbmRBc0V2ZW50TGlzdGVuZXIsCiAgICBjdXJyeTogICAgICAgICAgICAgICBjdXJyeSwKICAgIGRlbGF5OiAgICAgICAgICAgICAgIGRlbGF5LAogICAgZGVmZXI6ICAgICAgICAgICAgICAgZGVmZXIsCiAgICB3cmFwOiAgICAgICAgICAgICAgICB3cmFwLAogICAgbWV0aG9kaXplOiAgICAgICAgICAgbWV0aG9kaXplCiAgfQp9KSgpKTsKCgoKKGZ1bmN0aW9uKHByb3RvKSB7CgoKICBmdW5jdGlvbiB0b0lTT1N0cmluZygpIHsKICAgIHJldHVybiB0aGlzLmdldFVUQ0Z1bGxZZWFyKCkgKyAnLScgKwogICAgICAodGhpcy5nZXRVVENNb250aCgpICsgMSkudG9QYWRkZWRTdHJpbmcoMikgKyAnLScgKwogICAgICB0aGlzLmdldFVUQ0RhdGUoKS50b1BhZGRlZFN0cmluZygyKSArICdUJyArCiAgICAgIHRoaXMuZ2V0VVRDSG91cnMoKS50b1BhZGRlZFN0cmluZygyKSArICc6JyArCiAgICAgIHRoaXMuZ2V0VVRDTWludXRlcygpLnRvUGFkZGVkU3RyaW5nKDIpICsgJzonICsKICAgICAgdGhpcy5nZXRVVENTZWNvbmRzKCkudG9QYWRkZWRTdHJpbmcoMikgKyAnWic7CiAgfQoKCiAgZnVuY3Rpb24gdG9KU09OKCkgewogICAgcmV0dXJuIHRoaXMudG9JU09TdHJpbmcoKTsKICB9CgogIGlmICghcHJvdG8udG9JU09TdHJpbmcpIHByb3RvLnRvSVNPU3RyaW5nID0gdG9JU09TdHJpbmc7CiAgaWYgKCFwcm90by50b0pTT04pIHByb3RvLnRvSlNPTiA9IHRvSlNPTjsKCn0pKERhdGUucHJvdG90eXBlKTsKCgpSZWdFeHAucHJvdG90eXBlLm1hdGNoID0gUmVnRXhwLnByb3RvdHlwZS50ZXN0OwoKUmVnRXhwLmVzY2FwZSA9IGZ1bmN0aW9uKHN0cikgewogIHJldHVybiBTdHJpbmcoc3RyKS5yZXBsYWNlKC8oWy4qKz9ePSE6JHt9KCl8W1xdXC9cXF0pL2csICdcXCQxJyk7Cn07CnZhciBQZXJpb2RpY2FsRXhlY3V0ZXIgPSBDbGFzcy5jcmVhdGUoewogIGluaXRpYWxpemU6IGZ1bmN0aW9uKGNhbGxiYWNrLCBmcmVxdWVuY3kpIHsKICAgIHRoaXMuY2FsbGJhY2sgPSBjYWxsYmFjazsKICAgIHRoaXMuZnJlcXVlbmN5ID0gZnJlcXVlbmN5OwogICAgdGhpcy5jdXJyZW50bHlFeGVjdXRpbmcgPSBmYWxzZTsKCiAgICB0aGlzLnJlZ2lzdGVyQ2FsbGJhY2soKTsKICB9LAoKICByZWdpc3RlckNhbGxiYWNrOiBmdW5jdGlvbigpIHsKICAgIHRoaXMudGltZXIgPSBzZXRJbnRlcnZhbCh0aGlzLm9uVGltZXJFdmVudC5iaW5kKHRoaXMpLCB0aGlzLmZyZXF1ZW5jeSAqIDEwMDApOwogIH0sCgogIGV4ZWN1dGU6IGZ1bmN0aW9uKCkgewogICAgdGhpcy5jYWxsYmFjayh0aGlzKTsKICB9LAoKICBzdG9wOiBmdW5jdGlvbigpIHsKICAgIGlmICghdGhpcy50aW1lcikgcmV0dXJuOwogICAgY2xlYXJJbnRlcnZhbCh0aGlzLnRpbWVyKTsKICAgIHRoaXMudGltZXIgPSBudWxsOwogIH0sCgogIG9uVGltZXJFdmVudDogZnVuY3Rpb24oKSB7CiAgICBpZiAoIXRoaXMuY3VycmVudGx5RXhlY3V0aW5nKSB7CiAgICAgIHRyeSB7CiAgICAgICAgdGhpcy5jdXJyZW50bHlFeGVjdXRpbmcgPSB0cnVlOwogICAgICAgIHRoaXMuZXhlY3V0ZSgpOwogICAgICAgIHRoaXMuY3VycmVudGx5RXhlY3V0aW5nID0gZmFsc2U7CiAgICAgIH0gY2F0Y2goZSkgewogICAgICAgIHRoaXMuY3VycmVudGx5RXhlY3V0aW5nID0gZmFsc2U7CiAgICAgICAgdGhyb3cgZTsKICAgICAgfQogICAgfQogIH0KfSk7Ck9iamVjdC5leHRlbmQoU3RyaW5nLCB7CiAgaW50ZXJwcmV0OiBmdW5jdGlvbih2YWx1ZSkgewogICAgcmV0dXJuIHZhbHVlID09IG51bGwgPyAnJyA6IFN0cmluZyh2YWx1ZSk7CiAgfSwKICBzcGVjaWFsQ2hhcjogewogICAgJ1xiJzogJ1xcYicsCiAgICAnXHQnOiAnXFx0JywKICAgICdcbic6ICdcXG4nLAogICAgJ1xmJzogJ1xcZicsCiAgICAnXHInOiAnXFxyJywKICAgICdcXCc6ICdcXFxcJwogIH0KfSk7CgpPYmplY3QuZXh0ZW5kKFN0cmluZy5wcm90b3R5cGUsIChmdW5jdGlvbigpIHsKICB2YXIgTkFUSVZFX0pTT05fUEFSU0VfU1VQUE9SVCA9IHdpbmRvdy5KU09OICYmCiAgICB0eXBlb2YgSlNPTi5wYXJzZSA9PT0gJ2Z1bmN0aW9uJyAmJgogICAgSlNPTi5wYXJzZSgneyJ0ZXN0IjogdHJ1ZX0nKS50ZXN0OwoKICBmdW5jdGlvbiBwcmVwYXJlUmVwbGFjZW1lbnQocmVwbGFjZW1lbnQpIHsKICAgIGlmIChPYmplY3QuaXNGdW5jdGlvbihyZXBsYWNlbWVudCkpIHJldHVybiByZXBsYWNlbWVudDsKICAgIHZhciB0ZW1wbGF0ZSA9IG5ldyBUZW1wbGF0ZShyZXBsYWNlbWVudCk7CiAgICByZXR1cm4gZnVuY3Rpb24obWF0Y2gpIHsgcmV0dXJuIHRlbXBsYXRlLmV2YWx1YXRlKG1hdGNoKSB9OwogIH0KCiAgZnVuY3Rpb24gZ3N1YihwYXR0ZXJuLCByZXBsYWNlbWVudCkgewogICAgdmFyIHJlc3VsdCA9ICcnLCBzb3VyY2UgPSB0aGlzLCBtYXRjaDsKICAgIHJlcGxhY2VtZW50ID0gcHJlcGFyZVJlcGxhY2VtZW50KHJlcGxhY2VtZW50KTsKCiAgICBpZiAoT2JqZWN0LmlzU3RyaW5nKHBhdHRlcm4pKQogICAgICBwYXR0ZXJuID0gUmVnRXhwLmVzY2FwZShwYXR0ZXJuKTsKCiAgICBpZiAoIShwYXR0ZXJuLmxlbmd0aCB8fCBwYXR0ZXJuLnNvdXJjZSkpIHsKICAgICAgcmVwbGFjZW1lbnQgPSByZXBsYWNlbWVudCgnJyk7CiAgICAgIHJldHVybiByZXBsYWNlbWVudCArIHNvdXJjZS5zcGxpdCgnJykuam9pbihyZXBsYWNlbWVudCkgKyByZXBsYWNlbWVudDsKICAgIH0KCiAgICB3aGlsZSAoc291cmNlLmxlbmd0aCA+IDApIHsKICAgICAgaWYgKG1hdGNoID0gc291cmNlLm1hdGNoKHBhdHRlcm4pKSB7CiAgICAgICAgcmVzdWx0ICs9IHNvdXJjZS5zbGljZSgwLCBtYXRjaC5pbmRleCk7CiAgICAgICAgcmVzdWx0ICs9IFN0cmluZy5pbnRlcnByZXQocmVwbGFjZW1lbnQobWF0Y2gpKTsKICAgICAgICBzb3VyY2UgID0gc291cmNlLnNsaWNlKG1hdGNoLmluZGV4ICsgbWF0Y2hbMF0ubGVuZ3RoKTsKICAgICAgfSBlbHNlIHsKICAgICAgICByZXN1bHQgKz0gc291cmNlLCBzb3VyY2UgPSAnJzsKICAgICAgfQogICAgfQogICAgcmV0dXJuIHJlc3VsdDsKICB9CgogIGZ1bmN0aW9uIHN1YihwYXR0ZXJuLCByZXBsYWNlbWVudCwgY291bnQpIHsKICAgIHJlcGxhY2VtZW50ID0gcHJlcGFyZVJlcGxhY2VtZW50KHJlcGxhY2VtZW50KTsKICAgIGNvdW50ID0gT2JqZWN0LmlzVW5kZWZpbmVkKGNvdW50KSA/IDEgOiBjb3VudDsKCiAgICByZXR1cm4gdGhpcy5nc3ViKHBhdHRlcm4sIGZ1bmN0aW9uKG1hdGNoKSB7CiAgICAgIGlmICgtLWNvdW50IDwgMCkgcmV0dXJuIG1hdGNoWzBdOwogICAgICByZXR1cm4gcmVwbGFjZW1lbnQobWF0Y2gpOwogICAgfSk7CiAgfQoKICBmdW5jdGlvbiBzY2FuKHBhdHRlcm4sIGl0ZXJhdG9yKSB7CiAgICB0aGlzLmdzdWIocGF0dGVybiwgaXRlcmF0b3IpOwogICAgcmV0dXJuIFN0cmluZyh0aGlzKTsKICB9CgogIGZ1bmN0aW9uIHRydW5jYXRlKGxlbmd0aCwgdHJ1bmNhdGlvbikgewogICAgbGVuZ3RoID0gbGVuZ3RoIHx8IDMwOwogICAgdHJ1bmNhdGlvbiA9IE9iamVjdC5pc1VuZGVmaW5lZCh0cnVuY2F0aW9uKSA/ICcuLi4nIDogdHJ1bmNhdGlvbjsKICAgIHJldHVybiB0aGlzLmxlbmd0aCA+IGxlbmd0aCA/CiAgICAgIHRoaXMuc2xpY2UoMCwgbGVuZ3RoIC0gdHJ1bmNhdGlvbi5sZW5ndGgpICsgdHJ1bmNhdGlvbiA6IFN0cmluZyh0aGlzKTsKICB9CgogIGZ1bmN0aW9uIHN0cmlwKCkgewogICAgcmV0dXJuIHRoaXMucmVwbGFjZSgvXlxzKy8sICcnKS5yZXBsYWNlKC9ccyskLywgJycpOwogIH0KCiAgZnVuY3Rpb24gc3RyaXBUYWdzKCkgewogICAgcmV0dXJuIHRoaXMucmVwbGFjZSgvPFx3KyhccysoIlteIl0qInwnW14nXSonfFtePl0pKyk/Pnw8XC9cdys+L2dpLCAnJyk7CiAgfQoKICBmdW5jdGlvbiBzdHJpcFNjcmlwdHMoKSB7CiAgICByZXR1cm4gdGhpcy5yZXBsYWNlKG5ldyBSZWdFeHAoUHJvdG90eXBlLlNjcmlwdEZyYWdtZW50LCAnaW1nJyksICcnKTsKICB9CgogIGZ1bmN0aW9uIGV4dHJhY3RTY3JpcHRzKCkgewogICAgdmFyIG1hdGNoQWxsID0gbmV3IFJlZ0V4cChQcm90b3R5cGUuU2NyaXB0RnJhZ21lbnQsICdpbWcnKSwKICAgICAgICBtYXRjaE9uZSA9IG5ldyBSZWdFeHAoUHJvdG90eXBlLlNjcmlwdEZyYWdtZW50LCAnaW0nKTsKICAgIHJldHVybiAodGhpcy5tYXRjaChtYXRjaEFsbCkgfHwgW10pLm1hcChmdW5jdGlvbihzY3JpcHRUYWcpIHsKICAgICAgcmV0dXJuIChzY3JpcHRUYWcubWF0Y2gobWF0Y2hPbmUpIHx8IFsnJywgJyddKVsxXTsKICAgIH0pOwogIH0KCiAgZnVuY3Rpb24gZXZhbFNjcmlwdHMoKSB7CiAgICByZXR1cm4gdGhpcy5leHRyYWN0U2NyaXB0cygpLm1hcChmdW5jdGlvbihzY3JpcHQpIHsgcmV0dXJuIGV2YWwoc2NyaXB0KSB9KTsKICB9CgogIGZ1bmN0aW9uIGVzY2FwZUhUTUwoKSB7CiAgICByZXR1cm4gdGhpcy5yZXBsYWNlKC8mL2csJyZhbXA7JykucmVwbGFjZSgvPC9nLCcmbHQ7JykucmVwbGFjZSgvPi9nLCcmZ3Q7Jyk7CiAgfQoKICBmdW5jdGlvbiB1bmVzY2FwZUhUTUwoKSB7CiAgICByZXR1cm4gdGhpcy5zdHJpcFRhZ3MoKS5yZXBsYWNlKC8mbHQ7L2csJzwnKS5yZXBsYWNlKC8mZ3Q7L2csJz4nKS5yZXBsYWNlKC8mYW1wOy9nLCcmJyk7CiAgfQoKCiAgZnVuY3Rpb24gdG9RdWVyeVBhcmFtcyhzZXBhcmF0b3IpIHsKICAgIHZhciBtYXRjaCA9IHRoaXMuc3RyaXAoKS5tYXRjaCgvKFtePyNdKikoIy4qKT8kLyk7CiAgICBpZiAoIW1hdGNoKSByZXR1cm4geyB9OwoKICAgIHJldHVybiBtYXRjaFsxXS5zcGxpdChzZXBhcmF0b3IgfHwgJyYnKS5pbmplY3QoeyB9LCBmdW5jdGlvbihoYXNoLCBwYWlyKSB7CiAgICAgIGlmICgocGFpciA9IHBhaXIuc3BsaXQoJz0nKSlbMF0pIHsKICAgICAgICB2YXIga2V5ID0gZGVjb2RlVVJJQ29tcG9uZW50KHBhaXIuc2hpZnQoKSksCiAgICAgICAgICAgIHZhbHVlID0gcGFpci5sZW5ndGggPiAxID8gcGFpci5qb2luKCc9JykgOiBwYWlyWzBdOwoKICAgICAgICBpZiAodmFsdWUgIT0gdW5kZWZpbmVkKSB2YWx1ZSA9IGRlY29kZVVSSUNvbXBvbmVudCh2YWx1ZSk7CgogICAgICAgIGlmIChrZXkgaW4gaGFzaCkgewogICAgICAgICAgaWYgKCFPYmplY3QuaXNBcnJheShoYXNoW2tleV0pKSBoYXNoW2tleV0gPSBbaGFzaFtrZXldXTsKICAgICAgICAgIGhhc2hba2V5XS5wdXNoKHZhbHVlKTsKICAgICAgICB9CiAgICAgICAgZWxzZSBoYXNoW2tleV0gPSB2YWx1ZTsKICAgICAgfQogICAgICByZXR1cm4gaGFzaDsKICAgIH0pOwogIH0KCiAgZnVuY3Rpb24gdG9BcnJheSgpIHsKICAgIHJldHVybiB0aGlzLnNwbGl0KCcnKTsKICB9CgogIGZ1bmN0aW9uIHN1Y2MoKSB7CiAgICByZXR1cm4gdGhpcy5zbGljZSgwLCB0aGlzLmxlbmd0aCAtIDEpICsKICAgICAgU3RyaW5nLmZyb21DaGFyQ29kZSh0aGlzLmNoYXJDb2RlQXQodGhpcy5sZW5ndGggLSAxKSArIDEpOwogIH0KCiAgZnVuY3Rpb24gdGltZXMoY291bnQpIHsKICAgIHJldHVybiBjb3VudCA8IDEgPyAnJyA6IG5ldyBBcnJheShjb3VudCArIDEpLmpvaW4odGhpcyk7CiAgfQoKICBmdW5jdGlvbiBjYW1lbGl6ZSgpIHsKICAgIHJldHVybiB0aGlzLnJlcGxhY2UoLy0rKC4pPy9nLCBmdW5jdGlvbihtYXRjaCwgY2hyKSB7CiAgICAgIHJldHVybiBjaHIgPyBjaHIudG9VcHBlckNhc2UoKSA6ICcnOwogICAgfSk7CiAgfQoKICBmdW5jdGlvbiBjYXBpdGFsaXplKCkgewogICAgcmV0dXJuIHRoaXMuY2hhckF0KDApLnRvVXBwZXJDYXNlKCkgKyB0aGlzLnN1YnN0cmluZygxKS50b0xvd2VyQ2FzZSgpOwogIH0KCiAgZnVuY3Rpb24gdW5kZXJzY29yZSgpIHsKICAgIHJldHVybiB0aGlzLnJlcGxhY2UoLzo6L2csICcvJykKICAgICAgICAgICAgICAgLnJlcGxhY2UoLyhbQS1aXSspKFtBLVpdW2Etel0pL2csICckMV8kMicpCiAgICAgICAgICAgICAgIC5yZXBsYWNlKC8oW2EtelxkXSkoW0EtWl0pL2csICckMV8kMicpCiAgICAgICAgICAgICAgIC5yZXBsYWNlKC8tL2csICdfJykKICAgICAgICAgICAgICAgLnRvTG93ZXJDYXNlKCk7CiAgfQoKICBmdW5jdGlvbiBkYXNoZXJpemUoKSB7CiAgICByZXR1cm4gdGhpcy5yZXBsYWNlKC9fL2csICctJyk7CiAgfQoKICBmdW5jdGlvbiBpbnNwZWN0KHVzZURvdWJsZVF1b3RlcykgewogICAgdmFyIGVzY2FwZWRTdHJpbmcgPSB0aGlzLnJlcGxhY2UoL1tceDAwLVx4MWZcXF0vZywgZnVuY3Rpb24oY2hhcmFjdGVyKSB7CiAgICAgIGlmIChjaGFyYWN0ZXIgaW4gU3RyaW5nLnNwZWNpYWxDaGFyKSB7CiAgICAgICAgcmV0dXJuIFN0cmluZy5zcGVjaWFsQ2hhcltjaGFyYWN0ZXJdOwogICAgICB9CiAgICAgIHJldHVybiAnXFx1MDAnICsgY2hhcmFjdGVyLmNoYXJDb2RlQXQoKS50b1BhZGRlZFN0cmluZygyLCAxNik7CiAgICB9KTsKICAgIGlmICh1c2VEb3VibGVRdW90ZXMpIHJldHVybiAnIicgKyBlc2NhcGVkU3RyaW5nLnJlcGxhY2UoLyIvZywgJ1xcIicpICsgJyInOwogICAgcmV0dXJuICInIiArIGVzY2FwZWRTdHJpbmcucmVwbGFjZSgvJy9nLCAnXFxcJycpICsgIiciOwogIH0KCiAgZnVuY3Rpb24gdW5maWx0ZXJKU09OKGZpbHRlcikgewogICAgcmV0dXJuIHRoaXMucmVwbGFjZShmaWx0ZXIgfHwgUHJvdG90eXBlLkpTT05GaWx0ZXIsICckMScpOwogIH0KCiAgZnVuY3Rpb24gaXNKU09OKCkgewogICAgdmFyIHN0ciA9IHRoaXM7CiAgICBpZiAoc3RyLmJsYW5rKCkpIHJldHVybiBmYWxzZTsKICAgIHN0ciA9IHN0ci5yZXBsYWNlKC9cXCg/OlsiXFxcL2JmbnJ0XXx1WzAtOWEtZkEtRl17NH0pL2csICdAJyk7CiAgICBzdHIgPSBzdHIucmVwbGFjZSgvIlteIlxcXG5ccl0qInx0cnVlfGZhbHNlfG51bGx8LT9cZCsoPzpcLlxkKik/KD86W2VFXVsrXC1dP1xkKyk/L2csICddJyk7CiAgICBzdHIgPSBzdHIucmVwbGFjZSgvKD86Xnw6fCwpKD86XHMqXFspKy9nLCAnJyk7CiAgICByZXR1cm4gKC9eW1xdLDp7fVxzXSokLykudGVzdChzdHIpOwogIH0KCiAgZnVuY3Rpb24gZXZhbEpTT04oc2FuaXRpemUpIHsKICAgIHZhciBqc29uID0gdGhpcy51bmZpbHRlckpTT04oKSwKICAgICAgICBjeCA9IC9bXHUwMDAwXHUwMGFkXHUwNjAwLVx1MDYwNFx1MDcwZlx1MTdiNFx1MTdiNVx1MjAwYy1cdTIwMGZcdTIwMjgtXHUyMDJmXHUyMDYwLVx1MjA2Zlx1ZmVmZlx1ZmZmMC1cdWZmZmZdL2c7CiAgICBpZiAoY3gudGVzdChqc29uKSkgewogICAgICBqc29uID0ganNvbi5yZXBsYWNlKGN4LCBmdW5jdGlvbiAoYSkgewogICAgICAgIHJldHVybiAnXFx1JyArICgnMDAwMCcgKyBhLmNoYXJDb2RlQXQoMCkudG9TdHJpbmcoMTYpKS5zbGljZSgtNCk7CiAgICAgIH0pOwogICAgfQogICAgdHJ5IHsKICAgICAgaWYgKCFzYW5pdGl6ZSB8fCBqc29uLmlzSlNPTigpKSByZXR1cm4gZXZhbCgnKCcgKyBqc29uICsgJyknKTsKICAgIH0gY2F0Y2ggKGUpIHsgfQogICAgdGhyb3cgbmV3IFN5bnRheEVycm9yKCdCYWRseSBmb3JtZWQgSlNPTiBzdHJpbmc6ICcgKyB0aGlzLmluc3BlY3QoKSk7CiAgfQoKICBmdW5jdGlvbiBwYXJzZUpTT04oKSB7CiAgICB2YXIganNvbiA9IHRoaXMudW5maWx0ZXJKU09OKCk7CiAgICByZXR1cm4gSlNPTi5wYXJzZShqc29uKTsKICB9CgogIGZ1bmN0aW9uIGluY2x1ZGUocGF0dGVybikgewogICAgcmV0dXJuIHRoaXMuaW5kZXhPZihwYXR0ZXJuKSA+IC0xOwogIH0KCiAgZnVuY3Rpb24gc3RhcnRzV2l0aChwYXR0ZXJuKSB7CiAgICByZXR1cm4gdGhpcy5sYXN0SW5kZXhPZihwYXR0ZXJuLCAwKSA9PT0gMDsKICB9CgogIGZ1bmN0aW9uIGVuZHNXaXRoKHBhdHRlcm4pIHsKICAgIHZhciBkID0gdGhpcy5sZW5ndGggLSBwYXR0ZXJuLmxlbmd0aDsKICAgIHJldHVybiBkID49IDAgJiYgdGhpcy5pbmRleE9mKHBhdHRlcm4sIGQpID09PSBkOwogIH0KCiAgZnVuY3Rpb24gZW1wdHkoKSB7CiAgICByZXR1cm4gdGhpcyA9PSAnJzsKICB9CgogIGZ1bmN0aW9uIGJsYW5rKCkgewogICAgcmV0dXJuIC9eXHMqJC8udGVzdCh0aGlzKTsKICB9CgogIGZ1bmN0aW9uIGludGVycG9sYXRlKG9iamVjdCwgcGF0dGVybikgewogICAgcmV0dXJuIG5ldyBUZW1wbGF0ZSh0aGlzLCBwYXR0ZXJuKS5ldmFsdWF0ZShvYmplY3QpOwogIH0KCiAgcmV0dXJuIHsKICAgIGdzdWI6ICAgICAgICAgICBnc3ViLAogICAgc3ViOiAgICAgICAgICAgIHN1YiwKICAgIHNjYW46ICAgICAgICAgICBzY2FuLAogICAgdHJ1bmNhdGU6ICAgICAgIHRydW5jYXRlLAogICAgc3RyaXA6ICAgICAgICAgIFN0cmluZy5wcm90b3R5cGUudHJpbSB8fCBzdHJpcCwKICAgIHN0cmlwVGFnczogICAgICBzdHJpcFRhZ3MsCiAgICBzdHJpcFNjcmlwdHM6ICAgc3RyaXBTY3JpcHRzLAogICAgZXh0cmFjdFNjcmlwdHM6IGV4dHJhY3RTY3JpcHRzLAogICAgZXZhbFNjcmlwdHM6ICAgIGV2YWxTY3JpcHRzLAogICAgZXNjYXBlSFRNTDogICAgIGVzY2FwZUhUTUwsCiAgICB1bmVzY2FwZUhUTUw6ICAgdW5lc2NhcGVIVE1MLAogICAgdG9RdWVyeVBhcmFtczogIHRvUXVlcnlQYXJhbXMsCiAgICBwYXJzZVF1ZXJ5OiAgICAgdG9RdWVyeVBhcmFtcywKICAgIHRvQXJyYXk6ICAgICAgICB0b0FycmF5LAogICAgc3VjYzogICAgICAgICAgIHN1Y2MsCiAgICB0aW1lczogICAgICAgICAgdGltZXMsCiAgICBjYW1lbGl6ZTogICAgICAgY2FtZWxpemUsCiAgICBjYXBpdGFsaXplOiAgICAgY2FwaXRhbGl6ZSwKICAgIHVuZGVyc2NvcmU6ICAgICB1bmRlcnNjb3JlLAogICAgZGFzaGVyaXplOiAgICAgIGRhc2hlcml6ZSwKICAgIGluc3BlY3Q6ICAgICAgICBpbnNwZWN0LAogICAgdW5maWx0ZXJKU09OOiAgIHVuZmlsdGVySlNPTiwKICAgIGlzSlNPTjogICAgICAgICBpc0pTT04sCiAgICBldmFsSlNPTjogICAgICAgTkFUSVZFX0pTT05fUEFSU0VfU1VQUE9SVCA/IHBhcnNlSlNPTiA6IGV2YWxKU09OLAogICAgaW5jbHVkZTogICAgICAgIGluY2x1ZGUsCiAgICBzdGFydHNXaXRoOiAgICAgc3RhcnRzV2l0aCwKICAgIGVuZHNXaXRoOiAgICAgICBlbmRzV2l0aCwKICAgIGVtcHR5OiAgICAgICAgICBlbXB0eSwKICAgIGJsYW5rOiAgICAgICAgICBibGFuaywKICAgIGludGVycG9sYXRlOiAgICBpbnRlcnBvbGF0ZQogIH07Cn0pKCkpOwoKdmFyIFRlbXBsYXRlID0gQ2xhc3MuY3JlYXRlKHsKICBpbml0aWFsaXplOiBmdW5jdGlvbih0ZW1wbGF0ZSwgcGF0dGVybikgewogICAgdGhpcy50ZW1wbGF0ZSA9IHRlbXBsYXRlLnRvU3RyaW5nKCk7CiAgICB0aGlzLnBhdHRlcm4gPSBwYXR0ZXJuIHx8IFRlbXBsYXRlLlBhdHRlcm47CiAgfSwKCiAgZXZhbHVhdGU6IGZ1bmN0aW9uKG9iamVjdCkgewogICAgaWYgKG9iamVjdCAmJiBPYmplY3QuaXNGdW5jdGlvbihvYmplY3QudG9UZW1wbGF0ZVJlcGxhY2VtZW50cykpCiAgICAgIG9iamVjdCA9IG9iamVjdC50b1RlbXBsYXRlUmVwbGFjZW1lbnRzKCk7CgogICAgcmV0dXJuIHRoaXMudGVtcGxhdGUuZ3N1Yih0aGlzLnBhdHRlcm4sIGZ1bmN0aW9uKG1hdGNoKSB7CiAgICAgIGlmIChvYmplY3QgPT0gbnVsbCkgcmV0dXJuIChtYXRjaFsxXSArICcnKTsKCiAgICAgIHZhciBiZWZvcmUgPSBtYXRjaFsxXSB8fCAnJzsKICAgICAgaWYgKGJlZm9yZSA9PSAnXFwnKSByZXR1cm4gbWF0Y2hbMl07CgogICAgICB2YXIgY3R4ID0gb2JqZWN0LCBleHByID0gbWF0Y2hbM10sCiAgICAgICAgICBwYXR0ZXJuID0gL14oW14uW10rfFxbKCg/Oi4qP1teXFxdKT8pXF0pKFwufFxbfCQpLzsKCiAgICAgIG1hdGNoID0gcGF0dGVybi5leGVjKGV4cHIpOwogICAgICBpZiAobWF0Y2ggPT0gbnVsbCkgcmV0dXJuIGJlZm9yZTsKCiAgICAgIHdoaWxlIChtYXRjaCAhPSBudWxsKSB7CiAgICAgICAgdmFyIGNvbXAgPSBtYXRjaFsxXS5zdGFydHNXaXRoKCdbJykgPyBtYXRjaFsyXS5yZXBsYWNlKC9cXFxcXS9nLCAnXScpIDogbWF0Y2hbMV07CiAgICAgICAgY3R4ID0gY3R4W2NvbXBdOwogICAgICAgIGlmIChudWxsID09IGN0eCB8fCAnJyA9PSBtYXRjaFszXSkgYnJlYWs7CiAgICAgICAgZXhwciA9IGV4cHIuc3Vic3RyaW5nKCdbJyA9PSBtYXRjaFszXSA/IG1hdGNoWzFdLmxlbmd0aCA6IG1hdGNoWzBdLmxlbmd0aCk7CiAgICAgICAgbWF0Y2ggPSBwYXR0ZXJuLmV4ZWMoZXhwcik7CiAgICAgIH0KCiAgICAgIHJldHVybiBiZWZvcmUgKyBTdHJpbmcuaW50ZXJwcmV0KGN0eCk7CiAgICB9KTsKICB9Cn0pOwpUZW1wbGF0ZS5QYXR0ZXJuID0gLyhefC58XHJ8XG4pKCNceyguKj8pXH0pLzsKCnZhciAkYnJlYWsgPSB7IH07Cgp2YXIgRW51bWVyYWJsZSA9IChmdW5jdGlvbigpIHsKICBmdW5jdGlvbiBlYWNoKGl0ZXJhdG9yLCBjb250ZXh0KSB7CiAgICB2YXIgaW5kZXggPSAwOwogICAgdHJ5IHsKICAgICAgdGhpcy5fZWFjaChmdW5jdGlvbih2YWx1ZSkgewogICAgICAgIGl0ZXJhdG9yLmNhbGwoY29udGV4dCwgdmFsdWUsIGluZGV4KyspOwogICAgICB9KTsKICAgIH0gY2F0Y2ggKGUpIHsKICAgICAgaWYgKGUgIT0gJGJyZWFrKSB0aHJvdyBlOwogICAgfQogICAgcmV0dXJuIHRoaXM7CiAgfQoKICBmdW5jdGlvbiBlYWNoU2xpY2UobnVtYmVyLCBpdGVyYXRvciwgY29udGV4dCkgewogICAgdmFyIGluZGV4ID0gLW51bWJlciwgc2xpY2VzID0gW10sIGFycmF5ID0gdGhpcy50b0FycmF5KCk7CiAgICBpZiAobnVtYmVyIDwgMSkgcmV0dXJuIGFycmF5OwogICAgd2hpbGUgKChpbmRleCArPSBudW1iZXIpIDwgYXJyYXkubGVuZ3RoKQogICAgICBzbGljZXMucHVzaChhcnJheS5zbGljZShpbmRleCwgaW5kZXgrbnVtYmVyKSk7CiAgICByZXR1cm4gc2xpY2VzLmNvbGxlY3QoaXRlcmF0b3IsIGNvbnRleHQpOwogIH0KCiAgZnVuY3Rpb24gYWxsKGl0ZXJhdG9yLCBjb250ZXh0KSB7CiAgICBpdGVyYXRvciA9IGl0ZXJhdG9yIHx8IFByb3RvdHlwZS5LOwogICAgdmFyIHJlc3VsdCA9IHRydWU7CiAgICB0aGlzLmVhY2goZnVuY3Rpb24odmFsdWUsIGluZGV4KSB7CiAgICAgIHJlc3VsdCA9IHJlc3VsdCAmJiAhIWl0ZXJhdG9yLmNhbGwoY29udGV4dCwgdmFsdWUsIGluZGV4KTsKICAgICAgaWYgKCFyZXN1bHQpIHRocm93ICRicmVhazsKICAgIH0pOwogICAgcmV0dXJuIHJlc3VsdDsKICB9CgogIGZ1bmN0aW9uIGFueShpdGVyYXRvciwgY29udGV4dCkgewogICAgaXRlcmF0b3IgPSBpdGVyYXRvciB8fCBQcm90b3R5cGUuSzsKICAgIHZhciByZXN1bHQgPSBmYWxzZTsKICAgIHRoaXMuZWFjaChmdW5jdGlvbih2YWx1ZSwgaW5kZXgpIHsKICAgICAgaWYgKHJlc3VsdCA9ICEhaXRlcmF0b3IuY2FsbChjb250ZXh0LCB2YWx1ZSwgaW5kZXgpKQogICAgICAgIHRocm93ICRicmVhazsKICAgIH0pOwogICAgcmV0dXJuIHJlc3VsdDsKICB9CgogIGZ1bmN0aW9uIGNvbGxlY3QoaXRlcmF0b3IsIGNvbnRleHQpIHsKICAgIGl0ZXJhdG9yID0gaXRlcmF0b3IgfHwgUHJvdG90eXBlLks7CiAgICB2YXIgcmVzdWx0cyA9IFtdOwogICAgdGhpcy5lYWNoKGZ1bmN0aW9uKHZhbHVlLCBpbmRleCkgewogICAgICByZXN1bHRzLnB1c2goaXRlcmF0b3IuY2FsbChjb250ZXh0LCB2YWx1ZSwgaW5kZXgpKTsKICAgIH0pOwogICAgcmV0dXJuIHJlc3VsdHM7CiAgfQoKICBmdW5jdGlvbiBkZXRlY3QoaXRlcmF0b3IsIGNvbnRleHQpIHsKICAgIHZhciByZXN1bHQ7CiAgICB0aGlzLmVhY2goZnVuY3Rpb24odmFsdWUsIGluZGV4KSB7CiAgICAgIGlmIChpdGVyYXRvci5jYWxsKGNvbnRleHQsIHZhbHVlLCBpbmRleCkpIHsKICAgICAgICByZXN1bHQgPSB2YWx1ZTsKICAgICAgICB0aHJvdyAkYnJlYWs7CiAgICAgIH0KICAgIH0pOwogICAgcmV0dXJuIHJlc3VsdDsKICB9CgogIGZ1bmN0aW9uIGZpbmRBbGwoaXRlcmF0b3IsIGNvbnRleHQpIHsKICAgIHZhciByZXN1bHRzID0gW107CiAgICB0aGlzLmVhY2goZnVuY3Rpb24odmFsdWUsIGluZGV4KSB7CiAgICAgIGlmIChpdGVyYXRvci5jYWxsKGNvbnRleHQsIHZhbHVlLCBpbmRleCkpCiAgICAgICAgcmVzdWx0cy5wdXNoKHZhbHVlKTsKICAgIH0pOwogICAgcmV0dXJuIHJlc3VsdHM7CiAgfQoKICBmdW5jdGlvbiBncmVwKGZpbHRlciwgaXRlcmF0b3IsIGNvbnRleHQpIHsKICAgIGl0ZXJhdG9yID0gaXRlcmF0b3IgfHwgUHJvdG90eXBlLks7CiAgICB2YXIgcmVzdWx0cyA9IFtdOwoKICAgIGlmIChPYmplY3QuaXNTdHJpbmcoZmlsdGVyKSkKICAgICAgZmlsdGVyID0gbmV3IFJlZ0V4cChSZWdFeHAuZXNjYXBlKGZpbHRlcikpOwoKICAgIHRoaXMuZWFjaChmdW5jdGlvbih2YWx1ZSwgaW5kZXgpIHsKICAgICAgaWYgKGZpbHRlci5tYXRjaCh2YWx1ZSkpCiAgICAgICAgcmVzdWx0cy5wdXNoKGl0ZXJhdG9yLmNhbGwoY29udGV4dCwgdmFsdWUsIGluZGV4KSk7CiAgICB9KTsKICAgIHJldHVybiByZXN1bHRzOwogIH0KCiAgZnVuY3Rpb24gaW5jbHVkZShvYmplY3QpIHsKICAgIGlmIChPYmplY3QuaXNGdW5jdGlvbih0aGlzLmluZGV4T2YpKQogICAgICBpZiAodGhpcy5pbmRleE9mKG9iamVjdCkgIT0gLTEpIHJldHVybiB0cnVlOwoKICAgIHZhciBmb3VuZCA9IGZhbHNlOwogICAgdGhpcy5lYWNoKGZ1bmN0aW9uKHZhbHVlKSB7CiAgICAgIGlmICh2YWx1ZSA9PSBvYmplY3QpIHsKICAgICAgICBmb3VuZCA9IHRydWU7CiAgICAgICAgdGhyb3cgJGJyZWFrOwogICAgICB9CiAgICB9KTsKICAgIHJldHVybiBmb3VuZDsKICB9CgogIGZ1bmN0aW9uIGluR3JvdXBzT2YobnVtYmVyLCBmaWxsV2l0aCkgewogICAgZmlsbFdpdGggPSBPYmplY3QuaXNVbmRlZmluZWQoZmlsbFdpdGgpID8gbnVsbCA6IGZpbGxXaXRoOwogICAgcmV0dXJuIHRoaXMuZWFjaFNsaWNlKG51bWJlciwgZnVuY3Rpb24oc2xpY2UpIHsKICAgICAgd2hpbGUoc2xpY2UubGVuZ3RoIDwgbnVtYmVyKSBzbGljZS5wdXNoKGZpbGxXaXRoKTsKICAgICAgcmV0dXJuIHNsaWNlOwogICAgfSk7CiAgfQoKICBmdW5jdGlvbiBpbmplY3QobWVtbywgaXRlcmF0b3IsIGNvbnRleHQpIHsKICAgIHRoaXMuZWFjaChmdW5jdGlvbih2YWx1ZSwgaW5kZXgpIHsKICAgICAgbWVtbyA9IGl0ZXJhdG9yLmNhbGwoY29udGV4dCwgbWVtbywgdmFsdWUsIGluZGV4KTsKICAgIH0pOwogICAgcmV0dXJuIG1lbW87CiAgfQoKICBmdW5jdGlvbiBpbnZva2UobWV0aG9kKSB7CiAgICB2YXIgYXJncyA9ICRBKGFyZ3VtZW50cykuc2xpY2UoMSk7CiAgICByZXR1cm4gdGhpcy5tYXAoZnVuY3Rpb24odmFsdWUpIHsKICAgICAgcmV0dXJuIHZhbHVlW21ldGhvZF0uYXBwbHkodmFsdWUsIGFyZ3MpOwogICAgfSk7CiAgfQoKICBmdW5jdGlvbiBtYXgoaXRlcmF0b3IsIGNvbnRleHQpIHsKICAgIGl0ZXJhdG9yID0gaXRlcmF0b3IgfHwgUHJvdG90eXBlLks7CiAgICB2YXIgcmVzdWx0OwogICAgdGhpcy5lYWNoKGZ1bmN0aW9uKHZhbHVlLCBpbmRleCkgewogICAgICB2YWx1ZSA9IGl0ZXJhdG9yLmNhbGwoY29udGV4dCwgdmFsdWUsIGluZGV4KTsKICAgICAgaWYgKHJlc3VsdCA9PSBudWxsIHx8IHZhbHVlID49IHJlc3VsdCkKICAgICAgICByZXN1bHQgPSB2YWx1ZTsKICAgIH0pOwogICAgcmV0dXJuIHJlc3VsdDsKICB9CgogIGZ1bmN0aW9uIG1pbihpdGVyYXRvciwgY29udGV4dCkgewogICAgaXRlcmF0b3IgPSBpdGVyYXRvciB8fCBQcm90b3R5cGUuSzsKICAgIHZhciByZXN1bHQ7CiAgICB0aGlzLmVhY2goZnVuY3Rpb24odmFsdWUsIGluZGV4KSB7CiAgICAgIHZhbHVlID0gaXRlcmF0b3IuY2FsbChjb250ZXh0LCB2YWx1ZSwgaW5kZXgpOwogICAgICBpZiAocmVzdWx0ID09IG51bGwgfHwgdmFsdWUgPCByZXN1bHQpCiAgICAgICAgcmVzdWx0ID0gdmFsdWU7CiAgICB9KTsKICAgIHJldHVybiByZXN1bHQ7CiAgfQoKICBmdW5jdGlvbiBwYXJ0aXRpb24oaXRlcmF0b3IsIGNvbnRleHQpIHsKICAgIGl0ZXJhdG9yID0gaXRlcmF0b3IgfHwgUHJvdG90eXBlLks7CiAgICB2YXIgdHJ1ZXMgPSBbXSwgZmFsc2VzID0gW107CiAgICB0aGlzLmVhY2goZnVuY3Rpb24odmFsdWUsIGluZGV4KSB7CiAgICAgIChpdGVyYXRvci5jYWxsKGNvbnRleHQsIHZhbHVlLCBpbmRleCkgPwogICAgICAgIHRydWVzIDogZmFsc2VzKS5wdXNoKHZhbHVlKTsKICAgIH0pOwogICAgcmV0dXJuIFt0cnVlcywgZmFsc2VzXTsKICB9CgogIGZ1bmN0aW9uIHBsdWNrKHByb3BlcnR5KSB7CiAgICB2YXIgcmVzdWx0cyA9IFtdOwogICAgdGhpcy5lYWNoKGZ1bmN0aW9uKHZhbHVlKSB7CiAgICAgIHJlc3VsdHMucHVzaCh2YWx1ZVtwcm9wZXJ0eV0pOwogICAgfSk7CiAgICByZXR1cm4gcmVzdWx0czsKICB9CgogIGZ1bmN0aW9uIHJlamVjdChpdGVyYXRvciwgY29udGV4dCkgewogICAgdmFyIHJlc3VsdHMgPSBbXTsKICAgIHRoaXMuZWFjaChmdW5jdGlvbih2YWx1ZSwgaW5kZXgpIHsKICAgICAgaWYgKCFpdGVyYXRvci5jYWxsKGNvbnRleHQsIHZhbHVlLCBpbmRleCkpCiAgICAgICAgcmVzdWx0cy5wdXNoKHZhbHVlKTsKICAgIH0pOwogICAgcmV0dXJuIHJlc3VsdHM7CiAgfQoKICBmdW5jdGlvbiBzb3J0QnkoaXRlcmF0b3IsIGNvbnRleHQpIHsKICAgIHJldHVybiB0aGlzLm1hcChmdW5jdGlvbih2YWx1ZSwgaW5kZXgpIHsKICAgICAgcmV0dXJuIHsKICAgICAgICB2YWx1ZTogdmFsdWUsCiAgICAgICAgY3JpdGVyaWE6IGl0ZXJhdG9yLmNhbGwoY29udGV4dCwgdmFsdWUsIGluZGV4KQogICAgICB9OwogICAgfSkuc29ydChmdW5jdGlvbihsZWZ0LCByaWdodCkgewogICAgICB2YXIgYSA9IGxlZnQuY3JpdGVyaWEsIGIgPSByaWdodC5jcml0ZXJpYTsKICAgICAgcmV0dXJuIGEgPCBiID8gLTEgOiBhID4gYiA/IDEgOiAwOwogICAgfSkucGx1Y2soJ3ZhbHVlJyk7CiAgfQoKICBmdW5jdGlvbiB0b0FycmF5KCkgewogICAgcmV0dXJuIHRoaXMubWFwKCk7CiAgfQoKICBmdW5jdGlvbiB6aXAoKSB7CiAgICB2YXIgaXRlcmF0b3IgPSBQcm90b3R5cGUuSywgYXJncyA9ICRBKGFyZ3VtZW50cyk7CiAgICBpZiAoT2JqZWN0LmlzRnVuY3Rpb24oYXJncy5sYXN0KCkpKQogICAgICBpdGVyYXRvciA9IGFyZ3MucG9wKCk7CgogICAgdmFyIGNvbGxlY3Rpb25zID0gW3RoaXNdLmNvbmNhdChhcmdzKS5tYXAoJEEpOwogICAgcmV0dXJuIHRoaXMubWFwKGZ1bmN0aW9uKHZhbHVlLCBpbmRleCkgewogICAgICByZXR1cm4gaXRlcmF0b3IoY29sbGVjdGlvbnMucGx1Y2soaW5kZXgpKTsKICAgIH0pOwogIH0KCiAgZnVuY3Rpb24gc2l6ZSgpIHsKICAgIHJldHVybiB0aGlzLnRvQXJyYXkoKS5sZW5ndGg7CiAgfQoKICBmdW5jdGlvbiBpbnNwZWN0KCkgewogICAgcmV0dXJuICcjPEVudW1lcmFibGU6JyArIHRoaXMudG9BcnJheSgpLmluc3BlY3QoKSArICc+JzsKICB9CgoKCgoKCgoKCiAgcmV0dXJuIHsKICAgIGVhY2g6ICAgICAgIGVhY2gsCiAgICBlYWNoU2xpY2U6ICBlYWNoU2xpY2UsCiAgICBhbGw6ICAgICAgICBhbGwsCiAgICBldmVyeTogICAgICBhbGwsCiAgICBhbnk6ICAgICAgICBhbnksCiAgICBzb21lOiAgICAgICBhbnksCiAgICBjb2xsZWN0OiAgICBjb2xsZWN0LAogICAgbWFwOiAgICAgICAgY29sbGVjdCwKICAgIGRldGVjdDogICAgIGRldGVjdCwKICAgIGZpbmRBbGw6ICAgIGZpbmRBbGwsCiAgICBzZWxlY3Q6ICAgICBmaW5kQWxsLAogICAgZmlsdGVyOiAgICAgZmluZEFsbCwKICAgIGdyZXA6ICAgICAgIGdyZXAsCiAgICBpbmNsdWRlOiAgICBpbmNsdWRlLAogICAgbWVtYmVyOiAgICAgaW5jbHVkZSwKICAgIGluR3JvdXBzT2Y6IGluR3JvdXBzT2YsCiAgICBpbmplY3Q6ICAgICBpbmplY3QsCiAgICBpbnZva2U6ICAgICBpbnZva2UsCiAgICBtYXg6ICAgICAgICBtYXgsCiAgICBtaW46ICAgICAgICBtaW4sCiAgICBwYXJ0aXRpb246ICBwYXJ0aXRpb24sCiAgICBwbHVjazogICAgICBwbHVjaywKICAgIHJlamVjdDogICAgIHJlamVjdCwKICAgIHNvcnRCeTogICAgIHNvcnRCeSwKICAgIHRvQXJyYXk6ICAgIHRvQXJyYXksCiAgICBlbnRyaWVzOiAgICB0b0FycmF5LAogICAgemlwOiAgICAgICAgemlwLAogICAgc2l6ZTogICAgICAgc2l6ZSwKICAgIGluc3BlY3Q6ICAgIGluc3BlY3QsCiAgICBmaW5kOiAgICAgICBkZXRlY3QKICB9Owp9KSgpOwoKZnVuY3Rpb24gJEEoaXRlcmFibGUpIHsKICBpZiAoIWl0ZXJhYmxlKSByZXR1cm4gW107CiAgaWYgKCd0b0FycmF5JyBpbiBPYmplY3QoaXRlcmFibGUpKSByZXR1cm4gaXRlcmFibGUudG9BcnJheSgpOwogIHZhciBsZW5ndGggPSBpdGVyYWJsZS5sZW5ndGggfHwgMCwgcmVzdWx0cyA9IG5ldyBBcnJheShsZW5ndGgpOwogIHdoaWxlIChsZW5ndGgtLSkgcmVzdWx0c1tsZW5ndGhdID0gaXRlcmFibGVbbGVuZ3RoXTsKICByZXR1cm4gcmVzdWx0czsKfQoKCmZ1bmN0aW9uICR3KHN0cmluZykgewogIGlmICghT2JqZWN0LmlzU3RyaW5nKHN0cmluZykpIHJldHVybiBbXTsKICBzdHJpbmcgPSBzdHJpbmcuc3RyaXAoKTsKICByZXR1cm4gc3RyaW5nID8gc3RyaW5nLnNwbGl0KC9ccysvKSA6IFtdOwp9CgpBcnJheS5mcm9tID0gJEE7CgoKKGZ1bmN0aW9uKCkgewogIHZhciBhcnJheVByb3RvID0gQXJyYXkucHJvdG90eXBlLAogICAgICBzbGljZSA9IGFycmF5UHJvdG8uc2xpY2UsCiAgICAgIF9lYWNoID0gYXJyYXlQcm90by5mb3JFYWNoOyAvLyB1c2UgbmF0aXZlIGJyb3dzZXIgSlMgMS42IGltcGxlbWVudGF0aW9uIGlmIGF2YWlsYWJsZQoKICBmdW5jdGlvbiBlYWNoKGl0ZXJhdG9yLCBjb250ZXh0KSB7CiAgICBmb3IgKHZhciBpID0gMCwgbGVuZ3RoID0gdGhpcy5sZW5ndGggPj4+IDA7IGkgPCBsZW5ndGg7IGkrKykgewogICAgICBpZiAoaSBpbiB0aGlzKSBpdGVyYXRvci5jYWxsKGNvbnRleHQsIHRoaXNbaV0sIGksIHRoaXMpOwogICAgfQogIH0KICBpZiAoIV9lYWNoKSBfZWFjaCA9IGVhY2g7CgogIGZ1bmN0aW9uIGNsZWFyKCkgewogICAgdGhpcy5sZW5ndGggPSAwOwogICAgcmV0dXJuIHRoaXM7CiAgfQoKICBmdW5jdGlvbiBmaXJzdCgpIHsKICAgIHJldHVybiB0aGlzWzBdOwogIH0KCiAgZnVuY3Rpb24gbGFzdCgpIHsKICAgIHJldHVybiB0aGlzW3RoaXMubGVuZ3RoIC0gMV07CiAgfQoKICBmdW5jdGlvbiBjb21wYWN0KCkgewogICAgcmV0dXJuIHRoaXMuc2VsZWN0KGZ1bmN0aW9uKHZhbHVlKSB7CiAgICAgIHJldHVybiB2YWx1ZSAhPSBudWxsOwogICAgfSk7CiAgfQoKICBmdW5jdGlvbiBmbGF0dGVuKCkgewogICAgcmV0dXJuIHRoaXMuaW5qZWN0KFtdLCBmdW5jdGlvbihhcnJheSwgdmFsdWUpIHsKICAgICAgaWYgKE9iamVjdC5pc0FycmF5KHZhbHVlKSkKICAgICAgICByZXR1cm4gYXJyYXkuY29uY2F0KHZhbHVlLmZsYXR0ZW4oKSk7CiAgICAgIGFycmF5LnB1c2godmFsdWUpOwogICAgICByZXR1cm4gYXJyYXk7CiAgICB9KTsKICB9CgogIGZ1bmN0aW9uIHdpdGhvdXQoKSB7CiAgICB2YXIgdmFsdWVzID0gc2xpY2UuY2FsbChhcmd1bWVudHMsIDApOwogICAgcmV0dXJuIHRoaXMuc2VsZWN0KGZ1bmN0aW9uKHZhbHVlKSB7CiAgICAgIHJldHVybiAhdmFsdWVzLmluY2x1ZGUodmFsdWUpOwogICAgfSk7CiAgfQoKICBmdW5jdGlvbiByZXZlcnNlKGlubGluZSkgewogICAgcmV0dXJuIChpbmxpbmUgPT09IGZhbHNlID8gdGhpcy50b0FycmF5KCkgOiB0aGlzKS5fcmV2ZXJzZSgpOwogIH0KCiAgZnVuY3Rpb24gdW5pcShzb3J0ZWQpIHsKICAgIHJldHVybiB0aGlzLmluamVjdChbXSwgZnVuY3Rpb24oYXJyYXksIHZhbHVlLCBpbmRleCkgewogICAgICBpZiAoMCA9PSBpbmRleCB8fCAoc29ydGVkID8gYXJyYXkubGFzdCgpICE9IHZhbHVlIDogIWFycmF5LmluY2x1ZGUodmFsdWUpKSkKICAgICAgICBhcnJheS5wdXNoKHZhbHVlKTsKICAgICAgcmV0dXJuIGFycmF5OwogICAgfSk7CiAgfQoKICBmdW5jdGlvbiBpbnRlcnNlY3QoYXJyYXkpIHsKICAgIHJldHVybiB0aGlzLnVuaXEoKS5maW5kQWxsKGZ1bmN0aW9uKGl0ZW0pIHsKICAgICAgcmV0dXJuIGFycmF5LmRldGVjdChmdW5jdGlvbih2YWx1ZSkgeyByZXR1cm4gaXRlbSA9PT0gdmFsdWUgfSk7CiAgICB9KTsKICB9CgoKICBmdW5jdGlvbiBjbG9uZSgpIHsKICAgIHJldHVybiBzbGljZS5jYWxsKHRoaXMsIDApOwogIH0KCiAgZnVuY3Rpb24gc2l6ZSgpIHsKICAgIHJldHVybiB0aGlzLmxlbmd0aDsKICB9CgogIGZ1bmN0aW9uIGluc3BlY3QoKSB7CiAgICByZXR1cm4gJ1snICsgdGhpcy5tYXAoT2JqZWN0Lmluc3BlY3QpLmpvaW4oJywgJykgKyAnXSc7CiAgfQoKICBmdW5jdGlvbiBpbmRleE9mKGl0ZW0sIGkpIHsKICAgIGkgfHwgKGkgPSAwKTsKICAgIHZhciBsZW5ndGggPSB0aGlzLmxlbmd0aDsKICAgIGlmIChpIDwgMCkgaSA9IGxlbmd0aCArIGk7CiAgICBmb3IgKDsgaSA8IGxlbmd0aDsgaSsrKQogICAgICBpZiAodGhpc1tpXSA9PT0gaXRlbSkgcmV0dXJuIGk7CiAgICByZXR1cm4gLTE7CiAgfQoKICBmdW5jdGlvbiBsYXN0SW5kZXhPZihpdGVtLCBpKSB7CiAgICBpID0gaXNOYU4oaSkgPyB0aGlzLmxlbmd0aCA6IChpIDwgMCA/IHRoaXMubGVuZ3RoICsgaSA6IGkpICsgMTsKICAgIHZhciBuID0gdGhpcy5zbGljZSgwLCBpKS5yZXZlcnNlKCkuaW5kZXhPZihpdGVtKTsKICAgIHJldHVybiAobiA8IDApID8gbiA6IGkgLSBuIC0gMTsKICB9CgogIGZ1bmN0aW9uIGNvbmNhdCgpIHsKICAgIHZhciBhcnJheSA9IHNsaWNlLmNhbGwodGhpcywgMCksIGl0ZW07CiAgICBmb3IgKHZhciBpID0gMCwgbGVuZ3RoID0gYXJndW1lbnRzLmxlbmd0aDsgaSA8IGxlbmd0aDsgaSsrKSB7CiAgICAgIGl0ZW0gPSBhcmd1bWVudHNbaV07CiAgICAgIGlmIChPYmplY3QuaXNBcnJheShpdGVtKSAmJiAhKCdjYWxsZWUnIGluIGl0ZW0pKSB7CiAgICAgICAgZm9yICh2YXIgaiA9IDAsIGFycmF5TGVuZ3RoID0gaXRlbS5sZW5ndGg7IGogPCBhcnJheUxlbmd0aDsgaisrKQogICAgICAgICAgYXJyYXkucHVzaChpdGVtW2pdKTsKICAgICAgfSBlbHNlIHsKICAgICAgICBhcnJheS5wdXNoKGl0ZW0pOwogICAgICB9CiAgICB9CiAgICByZXR1cm4gYXJyYXk7CiAgfQoKICBPYmplY3QuZXh0ZW5kKGFycmF5UHJvdG8sIEVudW1lcmFibGUpOwoKICBpZiAoIWFycmF5UHJvdG8uX3JldmVyc2UpCiAgICBhcnJheVByb3RvLl9yZXZlcnNlID0gYXJyYXlQcm90by5yZXZlcnNlOwoKICBPYmplY3QuZXh0ZW5kKGFycmF5UHJvdG8sIHsKICAgIF9lYWNoOiAgICAgX2VhY2gsCiAgICBjbGVhcjogICAgIGNsZWFyLAogICAgZmlyc3Q6ICAgICBmaXJzdCwKICAgIGxhc3Q6ICAgICAgbGFzdCwKICAgIGNvbXBhY3Q6ICAgY29tcGFjdCwKICAgIGZsYXR0ZW46ICAgZmxhdHRlbiwKICAgIHdpdGhvdXQ6ICAgd2l0aG91dCwKICAgIHJldmVyc2U6ICAgcmV2ZXJzZSwKICAgIHVuaXE6ICAgICAgdW5pcSwKICAgIGludGVyc2VjdDogaW50ZXJzZWN0LAogICAgY2xvbmU6ICAgICBjbG9uZSwKICAgIHRvQXJyYXk6ICAgY2xvbmUsCiAgICBzaXplOiAgICAgIHNpemUsCiAgICBpbnNwZWN0OiAgIGluc3BlY3QKICB9KTsKCiAgdmFyIENPTkNBVF9BUkdVTUVOVFNfQlVHR1kgPSAoZnVuY3Rpb24oKSB7CiAgICByZXR1cm4gW10uY29uY2F0KGFyZ3VtZW50cylbMF1bMF0gIT09IDE7CiAgfSkoMSwyKQoKICBpZiAoQ09OQ0FUX0FSR1VNRU5UU19CVUdHWSkgYXJyYXlQcm90by5jb25jYXQgPSBjb25jYXQ7CgogIGlmICghYXJyYXlQcm90by5pbmRleE9mKSBhcnJheVByb3RvLmluZGV4T2YgPSBpbmRleE9mOwogIGlmICghYXJyYXlQcm90by5sYXN0SW5kZXhPZikgYXJyYXlQcm90by5sYXN0SW5kZXhPZiA9IGxhc3RJbmRleE9mOwp9KSgpOwpmdW5jdGlvbiAkSChvYmplY3QpIHsKICByZXR1cm4gbmV3IEhhc2gob2JqZWN0KTsKfTsKCnZhciBIYXNoID0gQ2xhc3MuY3JlYXRlKEVudW1lcmFibGUsIChmdW5jdGlvbigpIHsKICBmdW5jdGlvbiBpbml0aWFsaXplKG9iamVjdCkgewogICAgdGhpcy5fb2JqZWN0ID0gT2JqZWN0LmlzSGFzaChvYmplY3QpID8gb2JqZWN0LnRvT2JqZWN0KCkgOiBPYmplY3QuY2xvbmUob2JqZWN0KTsKICB9CgoKICBmdW5jdGlvbiBfZWFjaChpdGVyYXRvcikgewogICAgZm9yICh2YXIga2V5IGluIHRoaXMuX29iamVjdCkgewogICAgICB2YXIgdmFsdWUgPSB0aGlzLl9vYmplY3Rba2V5XSwgcGFpciA9IFtrZXksIHZhbHVlXTsKICAgICAgcGFpci5rZXkgPSBrZXk7CiAgICAgIHBhaXIudmFsdWUgPSB2YWx1ZTsKICAgICAgaXRlcmF0b3IocGFpcik7CiAgICB9CiAgfQoKICBmdW5jdGlvbiBzZXQoa2V5LCB2YWx1ZSkgewogICAgcmV0dXJuIHRoaXMuX29iamVjdFtrZXldID0gdmFsdWU7CiAgfQoKICBmdW5jdGlvbiBnZXQoa2V5KSB7CiAgICBpZiAodGhpcy5fb2JqZWN0W2tleV0gIT09IE9iamVjdC5wcm90b3R5cGVba2V5XSkKICAgICAgcmV0dXJuIHRoaXMuX29iamVjdFtrZXldOwogIH0KCiAgZnVuY3Rpb24gdW5zZXQoa2V5KSB7CiAgICB2YXIgdmFsdWUgPSB0aGlzLl9vYmplY3Rba2V5XTsKICAgIGRlbGV0ZSB0aGlzLl9vYmplY3Rba2V5XTsKICAgIHJldHVybiB2YWx1ZTsKICB9CgogIGZ1bmN0aW9uIHRvT2JqZWN0KCkgewogICAgcmV0dXJuIE9iamVjdC5jbG9uZSh0aGlzLl9vYmplY3QpOwogIH0KCgoKICBmdW5jdGlvbiBrZXlzKCkgewogICAgcmV0dXJuIHRoaXMucGx1Y2soJ2tleScpOwogIH0KCiAgZnVuY3Rpb24gdmFsdWVzKCkgewogICAgcmV0dXJuIHRoaXMucGx1Y2soJ3ZhbHVlJyk7CiAgfQoKICBmdW5jdGlvbiBpbmRleCh2YWx1ZSkgewogICAgdmFyIG1hdGNoID0gdGhpcy5kZXRlY3QoZnVuY3Rpb24ocGFpcikgewogICAgICByZXR1cm4gcGFpci52YWx1ZSA9PT0gdmFsdWU7CiAgICB9KTsKICAgIHJldHVybiBtYXRjaCAmJiBtYXRjaC5rZXk7CiAgfQoKICBmdW5jdGlvbiBtZXJnZShvYmplY3QpIHsKICAgIHJldHVybiB0aGlzLmNsb25lKCkudXBkYXRlKG9iamVjdCk7CiAgfQoKICBmdW5jdGlvbiB1cGRhdGUob2JqZWN0KSB7CiAgICByZXR1cm4gbmV3IEhhc2gob2JqZWN0KS5pbmplY3QodGhpcywgZnVuY3Rpb24ocmVzdWx0LCBwYWlyKSB7CiAgICAgIHJlc3VsdC5zZXQocGFpci5rZXksIHBhaXIudmFsdWUpOwogICAgICByZXR1cm4gcmVzdWx0OwogICAgfSk7CiAgfQoKICBmdW5jdGlvbiB0b1F1ZXJ5UGFpcihrZXksIHZhbHVlKSB7CiAgICBpZiAoT2JqZWN0LmlzVW5kZWZpbmVkKHZhbHVlKSkgcmV0dXJuIGtleTsKICAgIHJldHVybiBrZXkgKyAnPScgKyBlbmNvZGVVUklDb21wb25lbnQoU3RyaW5nLmludGVycHJldCh2YWx1ZSkpOwogIH0KCiAgZnVuY3Rpb24gdG9RdWVyeVN0cmluZygpIHsKICAgIHJldHVybiB0aGlzLmluamVjdChbXSwgZnVuY3Rpb24ocmVzdWx0cywgcGFpcikgewogICAgICB2YXIga2V5ID0gZW5jb2RlVVJJQ29tcG9uZW50KHBhaXIua2V5KSwgdmFsdWVzID0gcGFpci52YWx1ZTsKCiAgICAgIGlmICh2YWx1ZXMgJiYgdHlwZW9mIHZhbHVlcyA9PSAnb2JqZWN0JykgewogICAgICAgIGlmIChPYmplY3QuaXNBcnJheSh2YWx1ZXMpKSB7CiAgICAgICAgICB2YXIgcXVlcnlWYWx1ZXMgPSBbXTsKICAgICAgICAgIGZvciAodmFyIGkgPSAwLCBsZW4gPSB2YWx1ZXMubGVuZ3RoLCB2YWx1ZTsgaSA8IGxlbjsgaSsrKSB7CiAgICAgICAgICAgIHZhbHVlID0gdmFsdWVzW2ldOwogICAgICAgICAgICBxdWVyeVZhbHVlcy5wdXNoKHRvUXVlcnlQYWlyKGtleSwgdmFsdWUpKTsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiByZXN1bHRzLmNvbmNhdChxdWVyeVZhbHVlcyk7CiAgICAgICAgfQogICAgICB9IGVsc2UgcmVzdWx0cy5wdXNoKHRvUXVlcnlQYWlyKGtleSwgdmFsdWVzKSk7CiAgICAgIHJldHVybiByZXN1bHRzOwogICAgfSkuam9pbignJicpOwogIH0KCiAgZnVuY3Rpb24gaW5zcGVjdCgpIHsKICAgIHJldHVybiAnIzxIYXNoOnsnICsgdGhpcy5tYXAoZnVuY3Rpb24ocGFpcikgewogICAgICByZXR1cm4gcGFpci5tYXAoT2JqZWN0Lmluc3BlY3QpLmpvaW4oJzogJyk7CiAgICB9KS5qb2luKCcsICcpICsgJ30+JzsKICB9CgogIGZ1bmN0aW9uIGNsb25lKCkgewogICAgcmV0dXJuIG5ldyBIYXNoKHRoaXMpOwogIH0KCiAgcmV0dXJuIHsKICAgIGluaXRpYWxpemU6ICAgICAgICAgICAgIGluaXRpYWxpemUsCiAgICBfZWFjaDogICAgICAgICAgICAgICAgICBfZWFjaCwKICAgIHNldDogICAgICAgICAgICAgICAgICAgIHNldCwKICAgIGdldDogICAgICAgICAgICAgICAgICAgIGdldCwKICAgIHVuc2V0OiAgICAgICAgICAgICAgICAgIHVuc2V0LAogICAgdG9PYmplY3Q6ICAgICAgICAgICAgICAgdG9PYmplY3QsCiAgICB0b1RlbXBsYXRlUmVwbGFjZW1lbnRzOiB0b09iamVjdCwKICAgIGtleXM6ICAgICAgICAgICAgICAgICAgIGtleXMsCiAgICB2YWx1ZXM6ICAgICAgICAgICAgICAgICB2YWx1ZXMsCiAgICBpbmRleDogICAgICAgICAgICAgICAgICBpbmRleCwKICAgIG1lcmdlOiAgICAgICAgICAgICAgICAgIG1lcmdlLAogICAgdXBkYXRlOiAgICAgICAgICAgICAgICAgdXBkYXRlLAogICAgdG9RdWVyeVN0cmluZzogICAgICAgICAgdG9RdWVyeVN0cmluZywKICAgIGluc3BlY3Q6ICAgICAgICAgICAgICAgIGluc3BlY3QsCiAgICB0b0pTT046ICAgICAgICAgICAgICAgICB0b09iamVjdCwKICAgIGNsb25lOiAgICAgICAgICAgICAgICAgIGNsb25lCiAgfTsKfSkoKSk7CgpIYXNoLmZyb20gPSAkSDsKT2JqZWN0LmV4dGVuZChOdW1iZXIucHJvdG90eXBlLCAoZnVuY3Rpb24oKSB7CiAgZnVuY3Rpb24gdG9Db2xvclBhcnQoKSB7CiAgICByZXR1cm4gdGhpcy50b1BhZGRlZFN0cmluZygyLCAxNik7CiAgfQoKICBmdW5jdGlvbiBzdWNjKCkgewogICAgcmV0dXJuIHRoaXMgKyAxOwogIH0KCiAgZnVuY3Rpb24gdGltZXMoaXRlcmF0b3IsIGNvbnRleHQpIHsKICAgICRSKDAsIHRoaXMsIHRydWUpLmVhY2goaXRlcmF0b3IsIGNvbnRleHQpOwogICAgcmV0dXJuIHRoaXM7CiAgfQoKICBmdW5jdGlvbiB0b1BhZGRlZFN0cmluZyhsZW5ndGgsIHJhZGl4KSB7CiAgICB2YXIgc3RyaW5nID0gdGhpcy50b1N0cmluZyhyYWRpeCB8fCAxMCk7CiAgICByZXR1cm4gJzAnLnRpbWVzKGxlbmd0aCAtIHN0cmluZy5sZW5ndGgpICsgc3RyaW5nOwogIH0KCiAgZnVuY3Rpb24gYWJzKCkgewogICAgcmV0dXJuIE1hdGguYWJzKHRoaXMpOwogIH0KCiAgZnVuY3Rpb24gcm91bmQoKSB7CiAgICByZXR1cm4gTWF0aC5yb3VuZCh0aGlzKTsKICB9CgogIGZ1bmN0aW9uIGNlaWwoKSB7CiAgICByZXR1cm4gTWF0aC5jZWlsKHRoaXMpOwogIH0KCiAgZnVuY3Rpb24gZmxvb3IoKSB7CiAgICByZXR1cm4gTWF0aC5mbG9vcih0aGlzKTsKICB9CgogIHJldHVybiB7CiAgICB0b0NvbG9yUGFydDogICAgdG9Db2xvclBhcnQsCiAgICBzdWNjOiAgICAgICAgICAgc3VjYywKICAgIHRpbWVzOiAgICAgICAgICB0aW1lcywKICAgIHRvUGFkZGVkU3RyaW5nOiB0b1BhZGRlZFN0cmluZywKICAgIGFiczogICAgICAgICAgICBhYnMsCiAgICByb3VuZDogICAgICAgICAgcm91bmQsCiAgICBjZWlsOiAgICAgICAgICAgY2VpbCwKICAgIGZsb29yOiAgICAgICAgICBmbG9vcgogIH07Cn0pKCkpOwoKZnVuY3Rpb24gJFIoc3RhcnQsIGVuZCwgZXhjbHVzaXZlKSB7CiAgcmV0dXJuIG5ldyBPYmplY3RSYW5nZShzdGFydCwgZW5kLCBleGNsdXNpdmUpOwp9Cgp2YXIgT2JqZWN0UmFuZ2UgPSBDbGFzcy5jcmVhdGUoRW51bWVyYWJsZSwgKGZ1bmN0aW9uKCkgewogIGZ1bmN0aW9uIGluaXRpYWxpemUoc3RhcnQsIGVuZCwgZXhjbHVzaXZlKSB7CiAgICB0aGlzLnN0YXJ0ID0gc3RhcnQ7CiAgICB0aGlzLmVuZCA9IGVuZDsKICAgIHRoaXMuZXhjbHVzaXZlID0gZXhjbHVzaXZlOwogIH0KCiAgZnVuY3Rpb24gX2VhY2goaXRlcmF0b3IpIHsKICAgIHZhciB2YWx1ZSA9IHRoaXMuc3RhcnQ7CiAgICB3aGlsZSAodGhpcy5pbmNsdWRlKHZhbHVlKSkgewogICAgICBpdGVyYXRvcih2YWx1ZSk7CiAgICAgIHZhbHVlID0gdmFsdWUuc3VjYygpOwogICAgfQogIH0KCiAgZnVuY3Rpb24gaW5jbHVkZSh2YWx1ZSkgewogICAgaWYgKHZhbHVlIDwgdGhpcy5zdGFydCkKICAgICAgcmV0dXJuIGZhbHNlOwogICAgaWYgKHRoaXMuZXhjbHVzaXZlKQogICAgICByZXR1cm4gdmFsdWUgPCB0aGlzLmVuZDsKICAgIHJldHVybiB2YWx1ZSA8PSB0aGlzLmVuZDsKICB9CgogIHJldHVybiB7CiAgICBpbml0aWFsaXplOiBpbml0aWFsaXplLAogICAgX2VhY2g6ICAgICAgX2VhY2gsCiAgICBpbmNsdWRlOiAgICBpbmNsdWRlCiAgfTsKfSkoKSk7CgoKCnZhciBBYnN0cmFjdCA9IHsgfTsKCgp2YXIgVHJ5ID0gewogIHRoZXNlOiBmdW5jdGlvbigpIHsKICAgIHZhciByZXR1cm5WYWx1ZTsKCiAgICBmb3IgKHZhciBpID0gMCwgbGVuZ3RoID0gYXJndW1lbnRzLmxlbmd0aDsgaSA8IGxlbmd0aDsgaSsrKSB7CiAgICAgIHZhciBsYW1iZGEgPSBhcmd1bWVudHNbaV07CiAgICAgIHRyeSB7CiAgICAgICAgcmV0dXJuVmFsdWUgPSBsYW1iZGEoKTsKICAgICAgICBicmVhazsKICAgICAgfSBjYXRjaCAoZSkgeyB9CiAgICB9CgogICAgcmV0dXJuIHJldHVyblZhbHVlOwogIH0KfTsKCnZhciBBamF4ID0gewogIGdldFRyYW5zcG9ydDogZnVuY3Rpb24oKSB7CiAgICByZXR1cm4gVHJ5LnRoZXNlKAogICAgICBmdW5jdGlvbigpIHtyZXR1cm4gbmV3IFhNTEh0dHBSZXF1ZXN0KCl9LAogICAgICBmdW5jdGlvbigpIHtyZXR1cm4gbmV3IEFjdGl2ZVhPYmplY3QoJ01zeG1sMi5YTUxIVFRQJyl9LAogICAgICBmdW5jdGlvbigpIHtyZXR1cm4gbmV3IEFjdGl2ZVhPYmplY3QoJ01pY3Jvc29mdC5YTUxIVFRQJyl9CiAgICApIHx8IGZhbHNlOwogIH0sCgogIGFjdGl2ZVJlcXVlc3RDb3VudDogMAp9OwoKQWpheC5SZXNwb25kZXJzID0gewogIHJlc3BvbmRlcnM6IFtdLAoKICBfZWFjaDogZnVuY3Rpb24oaXRlcmF0b3IpIHsKICAgIHRoaXMucmVzcG9uZGVycy5fZWFjaChpdGVyYXRvcik7CiAgfSwKCiAgcmVnaXN0ZXI6IGZ1bmN0aW9uKHJlc3BvbmRlcikgewogICAgaWYgKCF0aGlzLmluY2x1ZGUocmVzcG9uZGVyKSkKICAgICAgdGhpcy5yZXNwb25kZXJzLnB1c2gocmVzcG9uZGVyKTsKICB9LAoKICB1bnJlZ2lzdGVyOiBmdW5jdGlvbihyZXNwb25kZXIpIHsKICAgIHRoaXMucmVzcG9uZGVycyA9IHRoaXMucmVzcG9uZGVycy53aXRob3V0KHJlc3BvbmRlcik7CiAgfSwKCiAgZGlzcGF0Y2g6IGZ1bmN0aW9uKGNhbGxiYWNrLCByZXF1ZXN0LCB0cmFuc3BvcnQsIGpzb24pIHsKICAgIHRoaXMuZWFjaChmdW5jdGlvbihyZXNwb25kZXIpIHsKICAgICAgaWYgKE9iamVjdC5pc0Z1bmN0aW9uKHJlc3BvbmRlcltjYWxsYmFja10pKSB7CiAgICAgICAgdHJ5IHsKICAgICAgICAgIHJlc3BvbmRlcltjYWxsYmFja10uYXBwbHkocmVzcG9uZGVyLCBbcmVxdWVzdCwgdHJhbnNwb3J0LCBqc29uXSk7CiAgICAgICAgfSBjYXRjaCAoZSkgeyB9CiAgICAgIH0KICAgIH0pOwogIH0KfTsKCk9iamVjdC5leHRlbmQoQWpheC5SZXNwb25kZXJzLCBFbnVtZXJhYmxlKTsKCkFqYXguUmVzcG9uZGVycy5yZWdpc3Rlcih7CiAgb25DcmVhdGU6ICAgZnVuY3Rpb24oKSB7IEFqYXguYWN0aXZlUmVxdWVzdENvdW50KysgfSwKICBvbkNvbXBsZXRlOiBmdW5jdGlvbigpIHsgQWpheC5hY3RpdmVSZXF1ZXN0Q291bnQtLSB9Cn0pOwpBamF4LkJhc2UgPSBDbGFzcy5jcmVhdGUoewogIGluaXRpYWxpemU6IGZ1bmN0aW9uKG9wdGlvbnMpIHsKICAgIHRoaXMub3B0aW9ucyA9IHsKICAgICAgbWV0aG9kOiAgICAgICAncG9zdCcsCiAgICAgIGFzeW5jaHJvbm91czogdHJ1ZSwKICAgICAgY29udGVudFR5cGU6ICAnYXBwbGljYXRpb24veC13d3ctZm9ybS11cmxlbmNvZGVkJywKICAgICAgZW5jb2Rpbmc6ICAgICAnVVRGLTgnLAogICAgICBwYXJhbWV0ZXJzOiAgICcnLAogICAgICBldmFsSlNPTjogICAgIHRydWUsCiAgICAgIGV2YWxKUzogICAgICAgdHJ1ZQogICAgfTsKICAgIE9iamVjdC5leHRlbmQodGhpcy5vcHRpb25zLCBvcHRpb25zIHx8IHsgfSk7CgogICAgdGhpcy5vcHRpb25zLm1ldGhvZCA9IHRoaXMub3B0aW9ucy5tZXRob2QudG9Mb3dlckNhc2UoKTsKCiAgICBpZiAoT2JqZWN0LmlzSGFzaCh0aGlzLm9wdGlvbnMucGFyYW1ldGVycykpCiAgICAgIHRoaXMub3B0aW9ucy5wYXJhbWV0ZXJzID0gdGhpcy5vcHRpb25zLnBhcmFtZXRlcnMudG9PYmplY3QoKTsKICB9Cn0pOwpBamF4LlJlcXVlc3QgPSBDbGFzcy5jcmVhdGUoQWpheC5CYXNlLCB7CiAgX2NvbXBsZXRlOiBmYWxzZSwKCiAgaW5pdGlhbGl6ZTogZnVuY3Rpb24oJHN1cGVyLCB1cmwsIG9wdGlvbnMpIHsKICAgICRzdXBlcihvcHRpb25zKTsKICAgIHRoaXMudHJhbnNwb3J0ID0gQWpheC5nZXRUcmFuc3BvcnQoKTsKICAgIHRoaXMucmVxdWVzdCh1cmwpOwogIH0sCgogIHJlcXVlc3Q6IGZ1bmN0aW9uKHVybCkgewogICAgdGhpcy51cmwgPSB1cmw7CiAgICB0aGlzLm1ldGhvZCA9IHRoaXMub3B0aW9ucy5tZXRob2Q7CiAgICB2YXIgcGFyYW1zID0gT2JqZWN0LmlzU3RyaW5nKHRoaXMub3B0aW9ucy5wYXJhbWV0ZXJzKSA/CiAgICAgICAgICB0aGlzLm9wdGlvbnMucGFyYW1ldGVycyA6CiAgICAgICAgICBPYmplY3QudG9RdWVyeVN0cmluZyh0aGlzLm9wdGlvbnMucGFyYW1ldGVycyk7CgogICAgaWYgKCFbJ2dldCcsICdwb3N0J10uaW5jbHVkZSh0aGlzLm1ldGhvZCkpIHsKICAgICAgcGFyYW1zICs9IChwYXJhbXMgPyAnJicgOiAnJykgKyAiX21ldGhvZD0iICsgdGhpcy5tZXRob2Q7CiAgICAgIHRoaXMubWV0aG9kID0gJ3Bvc3QnOwogICAgfQoKICAgIGlmIChwYXJhbXMgJiYgdGhpcy5tZXRob2QgPT09ICdnZXQnKSB7CiAgICAgIHRoaXMudXJsICs9ICh0aGlzLnVybC5pbmNsdWRlKCc/JykgPyAnJicgOiAnPycpICsgcGFyYW1zOwogICAgfQoKICAgIHRoaXMucGFyYW1ldGVycyA9IHBhcmFtcy50b1F1ZXJ5UGFyYW1zKCk7CgogICAgdHJ5IHsKICAgICAgdmFyIHJlc3BvbnNlID0gbmV3IEFqYXguUmVzcG9uc2UodGhpcyk7CiAgICAgIGlmICh0aGlzLm9wdGlvbnMub25DcmVhdGUpIHRoaXMub3B0aW9ucy5vbkNyZWF0ZShyZXNwb25zZSk7CiAgICAgIEFqYXguUmVzcG9uZGVycy5kaXNwYXRjaCgnb25DcmVhdGUnLCB0aGlzLCByZXNwb25zZSk7CgogICAgICB0aGlzLnRyYW5zcG9ydC5vcGVuKHRoaXMubWV0aG9kLnRvVXBwZXJDYXNlKCksIHRoaXMudXJsLAogICAgICAgIHRoaXMub3B0aW9ucy5hc3luY2hyb25vdXMpOwoKICAgICAgaWYgKHRoaXMub3B0aW9ucy5hc3luY2hyb25vdXMpIHRoaXMucmVzcG9uZFRvUmVhZHlTdGF0ZS5iaW5kKHRoaXMpLmRlZmVyKDEpOwoKICAgICAgdGhpcy50cmFuc3BvcnQub25yZWFkeXN0YXRlY2hhbmdlID0gdGhpcy5vblN0YXRlQ2hhbmdlLmJpbmQodGhpcyk7CiAgICAgIHRoaXMuc2V0UmVxdWVzdEhlYWRlcnMoKTsKCiAgICAgIHRoaXMuYm9keSA9IHRoaXMubWV0aG9kID09ICdwb3N0JyA/ICh0aGlzLm9wdGlvbnMucG9zdEJvZHkgfHwgcGFyYW1zKSA6IG51bGw7CiAgICAgIHRoaXMudHJhbnNwb3J0LnNlbmQodGhpcy5ib2R5KTsKCiAgICAgIC8qIEZvcmNlIEZpcmVmb3ggdG8gaGFuZGxlIHJlYWR5IHN0YXRlIDQgZm9yIHN5bmNocm9ub3VzIHJlcXVlc3RzICovCiAgICAgIGlmICghdGhpcy5vcHRpb25zLmFzeW5jaHJvbm91cyAmJiB0aGlzLnRyYW5zcG9ydC5vdmVycmlkZU1pbWVUeXBlKQogICAgICAgIHRoaXMub25TdGF0ZUNoYW5nZSgpOwoKICAgIH0KICAgIGNhdGNoIChlKSB7CiAgICAgIHRoaXMuZGlzcGF0Y2hFeGNlcHRpb24oZSk7CiAgICB9CiAgfSwKCiAgb25TdGF0ZUNoYW5nZTogZnVuY3Rpb24oKSB7CiAgICB2YXIgcmVhZHlTdGF0ZSA9IHRoaXMudHJhbnNwb3J0LnJlYWR5U3RhdGU7CiAgICBpZiAocmVhZHlTdGF0ZSA+IDEgJiYgISgocmVhZHlTdGF0ZSA9PSA0KSAmJiB0aGlzLl9jb21wbGV0ZSkpCiAgICAgIHRoaXMucmVzcG9uZFRvUmVhZHlTdGF0ZSh0aGlzLnRyYW5zcG9ydC5yZWFkeVN0YXRlKTsKICB9LAoKICBzZXRSZXF1ZXN0SGVhZGVyczogZnVuY3Rpb24oKSB7CiAgICB2YXIgaGVhZGVycyA9IHsKICAgICAgJ1gtUmVxdWVzdGVkLVdpdGgnOiAnWE1MSHR0cFJlcXVlc3QnLAogICAgICAnWC1Qcm90b3R5cGUtVmVyc2lvbic6IFByb3RvdHlwZS5WZXJzaW9uLAogICAgICAnQWNjZXB0JzogJ3RleHQvamF2YXNjcmlwdCwgdGV4dC9odG1sLCBhcHBsaWNhdGlvbi94bWwsIHRleHQveG1sLCAqLyonCiAgICB9OwoKICAgIGlmICh0aGlzLm1ldGhvZCA9PSAncG9zdCcpIHsKICAgICAgaGVhZGVyc1snQ29udGVudC10eXBlJ10gPSB0aGlzLm9wdGlvbnMuY29udGVudFR5cGUgKwogICAgICAgICh0aGlzLm9wdGlvbnMuZW5jb2RpbmcgPyAnOyBjaGFyc2V0PScgKyB0aGlzLm9wdGlvbnMuZW5jb2RpbmcgOiAnJyk7CgogICAgICAvKiBGb3JjZSAiQ29ubmVjdGlvbjogY2xvc2UiIGZvciBvbGRlciBNb3ppbGxhIGJyb3dzZXJzIHRvIHdvcmsKICAgICAgICogYXJvdW5kIGEgYnVnIHdoZXJlIFhNTEh0dHBSZXF1ZXN0IHNlbmRzIGFuIGluY29ycmVjdAogICAgICAgKiBDb250ZW50LWxlbmd0aCBoZWFkZXIuIFNlZSBNb3ppbGxhIEJ1Z3ppbGxhICMyNDY2NTEuCiAgICAgICAqLwogICAgICBpZiAodGhpcy50cmFuc3BvcnQub3ZlcnJpZGVNaW1lVHlwZSAmJgogICAgICAgICAgKG5hdmlnYXRvci51c2VyQWdlbnQubWF0Y2goL0dlY2tvXC8oXGR7NH0pLykgfHwgWzAsMjAwNV0pWzFdIDwgMjAwNSkKICAgICAgICAgICAgaGVhZGVyc1snQ29ubmVjdGlvbiddID0gJ2Nsb3NlJzsKICAgIH0KCiAgICBpZiAodHlwZW9mIHRoaXMub3B0aW9ucy5yZXF1ZXN0SGVhZGVycyA9PSAnb2JqZWN0JykgewogICAgICB2YXIgZXh0cmFzID0gdGhpcy5vcHRpb25zLnJlcXVlc3RIZWFkZXJzOwoKICAgICAgaWYgKE9iamVjdC5pc0Z1bmN0aW9uKGV4dHJhcy5wdXNoKSkKICAgICAgICBmb3IgKHZhciBpID0gMCwgbGVuZ3RoID0gZXh0cmFzLmxlbmd0aDsgaSA8IGxlbmd0aDsgaSArPSAyKQogICAgICAgICAgaGVhZGVyc1tleHRyYXNbaV1dID0gZXh0cmFzW2krMV07CiAgICAgIGVsc2UKICAgICAgICAkSChleHRyYXMpLmVhY2goZnVuY3Rpb24ocGFpcikgeyBoZWFkZXJzW3BhaXIua2V5XSA9IHBhaXIudmFsdWUgfSk7CiAgICB9CgogICAgZm9yICh2YXIgbmFtZSBpbiBoZWFkZXJzKQogICAgICB0aGlzLnRyYW5zcG9ydC5zZXRSZXF1ZXN0SGVhZGVyKG5hbWUsIGhlYWRlcnNbbmFtZV0pOwogIH0sCgogIHN1Y2Nlc3M6IGZ1bmN0aW9uKCkgewogICAgdmFyIHN0YXR1cyA9IHRoaXMuZ2V0U3RhdHVzKCk7CiAgICByZXR1cm4gIXN0YXR1cyB8fCAoc3RhdHVzID49IDIwMCAmJiBzdGF0dXMgPCAzMDApIHx8IHN0YXR1cyA9PSAzMDQ7CiAgfSwKCiAgZ2V0U3RhdHVzOiBmdW5jdGlvbigpIHsKICAgIHRyeSB7CiAgICAgIGlmICh0aGlzLnRyYW5zcG9ydC5zdGF0dXMgPT09IDEyMjMpIHJldHVybiAyMDQ7CiAgICAgIHJldHVybiB0aGlzLnRyYW5zcG9ydC5zdGF0dXMgfHwgMDsKICAgIH0gY2F0Y2ggKGUpIHsgcmV0dXJuIDAgfQogIH0sCgogIHJlc3BvbmRUb1JlYWR5U3RhdGU6IGZ1bmN0aW9uKHJlYWR5U3RhdGUpIHsKICAgIHZhciBzdGF0ZSA9IEFqYXguUmVxdWVzdC5FdmVudHNbcmVhZHlTdGF0ZV0sIHJlc3BvbnNlID0gbmV3IEFqYXguUmVzcG9uc2UodGhpcyk7CgogICAgaWYgKHN0YXRlID09ICdDb21wbGV0ZScpIHsKICAgICAgdHJ5IHsKICAgICAgICB0aGlzLl9jb21wbGV0ZSA9IHRydWU7CiAgICAgICAgKHRoaXMub3B0aW9uc1snb24nICsgcmVzcG9uc2Uuc3RhdHVzXQogICAgICAgICB8fCB0aGlzLm9wdGlvbnNbJ29uJyArICh0aGlzLnN1Y2Nlc3MoKSA/ICdTdWNjZXNzJyA6ICdGYWlsdXJlJyldCiAgICAgICAgIHx8IFByb3RvdHlwZS5lbXB0eUZ1bmN0aW9uKShyZXNwb25zZSwgcmVzcG9uc2UuaGVhZGVySlNPTik7CiAgICAgIH0gY2F0Y2ggKGUpIHsKICAgICAgICB0aGlzLmRpc3BhdGNoRXhjZXB0aW9uKGUpOwogICAgICB9CgogICAgICB2YXIgY29udGVudFR5cGUgPSByZXNwb25zZS5nZXRIZWFkZXIoJ0NvbnRlbnQtdHlwZScpOwogICAgICBpZiAodGhpcy5vcHRpb25zLmV2YWxKUyA9PSAnZm9yY2UnCiAgICAgICAgICB8fCAodGhpcy5vcHRpb25zLmV2YWxKUyAmJiB0aGlzLmlzU2FtZU9yaWdpbigpICYmIGNvbnRlbnRUeXBlCiAgICAgICAgICAmJiBjb250ZW50VHlwZS5tYXRjaCgvXlxzKih0ZXh0fGFwcGxpY2F0aW9uKVwvKHgtKT8oamF2YXxlY21hKXNjcmlwdCg7LiopP1xzKiQvaSkpKQogICAgICAgIHRoaXMuZXZhbFJlc3BvbnNlKCk7CiAgICB9CgogICAgdHJ5IHsKICAgICAgKHRoaXMub3B0aW9uc1snb24nICsgc3RhdGVdIHx8IFByb3RvdHlwZS5lbXB0eUZ1bmN0aW9uKShyZXNwb25zZSwgcmVzcG9uc2UuaGVhZGVySlNPTik7CiAgICAgIEFqYXguUmVzcG9uZGVycy5kaXNwYXRjaCgnb24nICsgc3RhdGUsIHRoaXMsIHJlc3BvbnNlLCByZXNwb25zZS5oZWFkZXJKU09OKTsKICAgIH0gY2F0Y2ggKGUpIHsKICAgICAgdGhpcy5kaXNwYXRjaEV4Y2VwdGlvbihlKTsKICAgIH0KCiAgICBpZiAoc3RhdGUgPT0gJ0NvbXBsZXRlJykgewogICAgICB0aGlzLnRyYW5zcG9ydC5vbnJlYWR5c3RhdGVjaGFuZ2UgPSBQcm90b3R5cGUuZW1wdHlGdW5jdGlvbjsKICAgIH0KICB9LAoKICBpc1NhbWVPcmlnaW46IGZ1bmN0aW9uKCkgewogICAgdmFyIG0gPSB0aGlzLnVybC5tYXRjaCgvXlxzKmh0dHBzPzpcL1wvW15cL10qLyk7CiAgICByZXR1cm4gIW0gfHwgKG1bMF0gPT0gJyN7cHJvdG9jb2x9Ly8je2RvbWFpbn0je3BvcnR9Jy5pbnRlcnBvbGF0ZSh7CiAgICAgIHByb3RvY29sOiBsb2NhdGlvbi5wcm90b2NvbCwKICAgICAgZG9tYWluOiBkb2N1bWVudC5kb21haW4sCiAgICAgIHBvcnQ6IGxvY2F0aW9uLnBvcnQgPyAnOicgKyBsb2NhdGlvbi5wb3J0IDogJycKICAgIH0pKTsKICB9LAoKICBnZXRIZWFkZXI6IGZ1bmN0aW9uKG5hbWUpIHsKICAgIHRyeSB7CiAgICAgIHJldHVybiB0aGlzLnRyYW5zcG9ydC5nZXRSZXNwb25zZUhlYWRlcihuYW1lKSB8fCBudWxsOwogICAgfSBjYXRjaCAoZSkgeyByZXR1cm4gbnVsbDsgfQogIH0sCgogIGV2YWxSZXNwb25zZTogZnVuY3Rpb24oKSB7CiAgICB0cnkgewogICAgICByZXR1cm4gZXZhbCgodGhpcy50cmFuc3BvcnQucmVzcG9uc2VUZXh0IHx8ICcnKS51bmZpbHRlckpTT04oKSk7CiAgICB9IGNhdGNoIChlKSB7CiAgICAgIHRoaXMuZGlzcGF0Y2hFeGNlcHRpb24oZSk7CiAgICB9CiAgfSwKCiAgZGlzcGF0Y2hFeGNlcHRpb246IGZ1bmN0aW9uKGV4Y2VwdGlvbikgewogICAgKHRoaXMub3B0aW9ucy5vbkV4Y2VwdGlvbiB8fCBQcm90b3R5cGUuZW1wdHlGdW5jdGlvbikodGhpcywgZXhjZXB0aW9uKTsKICAgIEFqYXguUmVzcG9uZGVycy5kaXNwYXRjaCgnb25FeGNlcHRpb24nLCB0aGlzLCBleGNlcHRpb24pOwogIH0KfSk7CgpBamF4LlJlcXVlc3QuRXZlbnRzID0KICBbJ1VuaW5pdGlhbGl6ZWQnLCAnTG9hZGluZycsICdMb2FkZWQnLCAnSW50ZXJhY3RpdmUnLCAnQ29tcGxldGUnXTsKCgoKCgoKCgpBamF4LlJlc3BvbnNlID0gQ2xhc3MuY3JlYXRlKHsKICBpbml0aWFsaXplOiBmdW5jdGlvbihyZXF1ZXN0KXsKICAgIHRoaXMucmVxdWVzdCA9IHJlcXVlc3Q7CiAgICB2YXIgdHJhbnNwb3J0ICA9IHRoaXMudHJhbnNwb3J0ICA9IHJlcXVlc3QudHJhbnNwb3J0LAogICAgICAgIHJlYWR5U3RhdGUgPSB0aGlzLnJlYWR5U3RhdGUgPSB0cmFuc3BvcnQucmVhZHlTdGF0ZTsKCiAgICBpZiAoKHJlYWR5U3RhdGUgPiAyICYmICFQcm90b3R5cGUuQnJvd3Nlci5JRSkgfHwgcmVhZHlTdGF0ZSA9PSA0KSB7CiAgICAgIHRoaXMuc3RhdHVzICAgICAgID0gdGhpcy5nZXRTdGF0dXMoKTsKICAgICAgdGhpcy5zdGF0dXNUZXh0ICAgPSB0aGlzLmdldFN0YXR1c1RleHQoKTsKICAgICAgdGhpcy5yZXNwb25zZVRleHQgPSBTdHJpbmcuaW50ZXJwcmV0KHRyYW5zcG9ydC5yZXNwb25zZVRleHQpOwogICAgICB0aGlzLmhlYWRlckpTT04gICA9IHRoaXMuX2dldEhlYWRlckpTT04oKTsKICAgIH0KCiAgICBpZiAocmVhZHlTdGF0ZSA9PSA0KSB7CiAgICAgIHZhciB4bWwgPSB0cmFuc3BvcnQucmVzcG9uc2VYTUw7CiAgICAgIHRoaXMucmVzcG9uc2VYTUwgID0gT2JqZWN0LmlzVW5kZWZpbmVkKHhtbCkgPyBudWxsIDogeG1sOwogICAgICB0aGlzLnJlc3BvbnNlSlNPTiA9IHRoaXMuX2dldFJlc3BvbnNlSlNPTigpOwogICAgfQogIH0sCgogIHN0YXR1czogICAgICAwLAoKICBzdGF0dXNUZXh0OiAnJywKCiAgZ2V0U3RhdHVzOiBBamF4LlJlcXVlc3QucHJvdG90eXBlLmdldFN0YXR1cywKCiAgZ2V0U3RhdHVzVGV4dDogZnVuY3Rpb24oKSB7CiAgICB0cnkgewogICAgICByZXR1cm4gdGhpcy50cmFuc3BvcnQuc3RhdHVzVGV4dCB8fCAnJzsKICAgIH0gY2F0Y2ggKGUpIHsgcmV0dXJuICcnIH0KICB9LAoKICBnZXRIZWFkZXI6IEFqYXguUmVxdWVzdC5wcm90b3R5cGUuZ2V0SGVhZGVyLAoKICBnZXRBbGxIZWFkZXJzOiBmdW5jdGlvbigpIHsKICAgIHRyeSB7CiAgICAgIHJldHVybiB0aGlzLmdldEFsbFJlc3BvbnNlSGVhZGVycygpOwogICAgfSBjYXRjaCAoZSkgeyByZXR1cm4gbnVsbCB9CiAgfSwKCiAgZ2V0UmVzcG9uc2VIZWFkZXI6IGZ1bmN0aW9uKG5hbWUpIHsKICAgIHJldHVybiB0aGlzLnRyYW5zcG9ydC5nZXRSZXNwb25zZUhlYWRlcihuYW1lKTsKICB9LAoKICBnZXRBbGxSZXNwb25zZUhlYWRlcnM6IGZ1bmN0aW9uKCkgewogICAgcmV0dXJuIHRoaXMudHJhbnNwb3J0LmdldEFsbFJlc3BvbnNlSGVhZGVycygpOwogIH0sCgogIF9nZXRIZWFkZXJKU09OOiBmdW5jdGlvbigpIHsKICAgIHZhciBqc29uID0gdGhpcy5nZXRIZWFkZXIoJ1gtSlNPTicpOwogICAgaWYgKCFqc29uKSByZXR1cm4gbnVsbDsKICAgIGpzb24gPSBkZWNvZGVVUklDb21wb25lbnQoZXNjYXBlKGpzb24pKTsKICAgIHRyeSB7CiAgICAgIHJldHVybiBqc29uLmV2YWxKU09OKHRoaXMucmVxdWVzdC5vcHRpb25zLnNhbml0aXplSlNPTiB8fAogICAgICAgICF0aGlzLnJlcXVlc3QuaXNTYW1lT3JpZ2luKCkpOwogICAgfSBjYXRjaCAoZSkgewogICAgICB0aGlzLnJlcXVlc3QuZGlzcGF0Y2hFeGNlcHRpb24oZSk7CiAgICB9CiAgfSwKCiAgX2dldFJlc3BvbnNlSlNPTjogZnVuY3Rpb24oKSB7CiAgICB2YXIgb3B0aW9ucyA9IHRoaXMucmVxdWVzdC5vcHRpb25zOwogICAgaWYgKCFvcHRpb25zLmV2YWxKU09OIHx8IChvcHRpb25zLmV2YWxKU09OICE9ICdmb3JjZScgJiYKICAgICAgISh0aGlzLmdldEhlYWRlcignQ29udGVudC10eXBlJykgfHwgJycpLmluY2x1ZGUoJ2FwcGxpY2F0aW9uL2pzb24nKSkgfHwKICAgICAgICB0aGlzLnJlc3BvbnNlVGV4dC5ibGFuaygpKQogICAgICAgICAgcmV0dXJuIG51bGw7CiAgICB0cnkgewogICAgICByZXR1cm4gdGhpcy5yZXNwb25zZVRleHQuZXZhbEpTT04ob3B0aW9ucy5zYW5pdGl6ZUpTT04gfHwKICAgICAgICAhdGhpcy5yZXF1ZXN0LmlzU2FtZU9yaWdpbigpKTsKICAgIH0gY2F0Y2ggKGUpIHsKICAgICAgdGhpcy5yZXF1ZXN0LmRpc3BhdGNoRXhjZXB0aW9uKGUpOwogICAgfQogIH0KfSk7CgpBamF4LlVwZGF0ZXIgPSBDbGFzcy5jcmVhdGUoQWpheC5SZXF1ZXN0LCB7CiAgaW5pdGlhbGl6ZTogZnVuY3Rpb24oJHN1cGVyLCBjb250YWluZXIsIHVybCwgb3B0aW9ucykgewogICAgdGhpcy5jb250YWluZXIgPSB7CiAgICAgIHN1Y2Nlc3M6IChjb250YWluZXIuc3VjY2VzcyB8fCBjb250YWluZXIpLAogICAgICBmYWlsdXJlOiAoY29udGFpbmVyLmZhaWx1cmUgfHwgKGNvbnRhaW5lci5zdWNjZXNzID8gbnVsbCA6IGNvbnRhaW5lcikpCiAgICB9OwoKICAgIG9wdGlvbnMgPSBPYmplY3QuY2xvbmUob3B0aW9ucyk7CiAgICB2YXIgb25Db21wbGV0ZSA9IG9wdGlvbnMub25Db21wbGV0ZTsKICAgIG9wdGlvbnMub25Db21wbGV0ZSA9IChmdW5jdGlvbihyZXNwb25zZSwganNvbikgewogICAgICB0aGlzLnVwZGF0ZUNvbnRlbnQocmVzcG9uc2UucmVzcG9uc2VUZXh0KTsKICAgICAgaWYgKE9iamVjdC5pc0Z1bmN0aW9uKG9uQ29tcGxldGUpKSBvbkNvbXBsZXRlKHJlc3BvbnNlLCBqc29uKTsKICAgIH0pLmJpbmQodGhpcyk7CgogICAgJHN1cGVyKHVybCwgb3B0aW9ucyk7CiAgfSwKCiAgdXBkYXRlQ29udGVudDogZnVuY3Rpb24ocmVzcG9uc2VUZXh0KSB7CiAgICB2YXIgcmVjZWl2ZXIgPSB0aGlzLmNvbnRhaW5lclt0aGlzLnN1Y2Nlc3MoKSA/ICdzdWNjZXNzJyA6ICdmYWlsdXJlJ10sCiAgICAgICAgb3B0aW9ucyA9IHRoaXMub3B0aW9uczsKCiAgICBpZiAoIW9wdGlvbnMuZXZhbFNjcmlwdHMpIHJlc3BvbnNlVGV4dCA9IHJlc3BvbnNlVGV4dC5zdHJpcFNjcmlwdHMoKTsKCiAgICBpZiAocmVjZWl2ZXIgPSAkKHJlY2VpdmVyKSkgewogICAgICBpZiAob3B0aW9ucy5pbnNlcnRpb24pIHsKICAgICAgICBpZiAoT2JqZWN0LmlzU3RyaW5nKG9wdGlvbnMuaW5zZXJ0aW9uKSkgewogICAgICAgICAgdmFyIGluc2VydGlvbiA9IHsgfTsgaW5zZXJ0aW9uW29wdGlvbnMuaW5zZXJ0aW9uXSA9IHJlc3BvbnNlVGV4dDsKICAgICAgICAgIHJlY2VpdmVyLmluc2VydChpbnNlcnRpb24pOwogICAgICAgIH0KICAgICAgICBlbHNlIG9wdGlvbnMuaW5zZXJ0aW9uKHJlY2VpdmVyLCByZXNwb25zZVRleHQpOwogICAgICB9CiAgICAgIGVsc2UgcmVjZWl2ZXIudXBkYXRlKHJlc3BvbnNlVGV4dCk7CiAgICB9CiAgfQp9KTsKCkFqYXguUGVyaW9kaWNhbFVwZGF0ZXIgPSBDbGFzcy5jcmVhdGUoQWpheC5CYXNlLCB7CiAgaW5pdGlhbGl6ZTogZnVuY3Rpb24oJHN1cGVyLCBjb250YWluZXIsIHVybCwgb3B0aW9ucykgewogICAgJHN1cGVyKG9wdGlvbnMpOwogICAgdGhpcy5vbkNvbXBsZXRlID0gdGhpcy5vcHRpb25zLm9uQ29tcGxldGU7CgogICAgdGhpcy5mcmVxdWVuY3kgPSAodGhpcy5vcHRpb25zLmZyZXF1ZW5jeSB8fCAyKTsKICAgIHRoaXMuZGVjYXkgPSAodGhpcy5vcHRpb25zLmRlY2F5IHx8IDEpOwoKICAgIHRoaXMudXBkYXRlciA9IHsgfTsKICAgIHRoaXMuY29udGFpbmVyID0gY29udGFpbmVyOwogICAgdGhpcy51cmwgPSB1cmw7CgogICAgdGhpcy5zdGFydCgpOwogIH0sCgogIHN0YXJ0OiBmdW5jdGlvbigpIHsKICAgIHRoaXMub3B0aW9ucy5vbkNvbXBsZXRlID0gdGhpcy51cGRhdGVDb21wbGV0ZS5iaW5kKHRoaXMpOwogICAgdGhpcy5vblRpbWVyRXZlbnQoKTsKICB9LAoKICBzdG9wOiBmdW5jdGlvbigpIHsKICAgIHRoaXMudXBkYXRlci5vcHRpb25zLm9uQ29tcGxldGUgPSB1bmRlZmluZWQ7CiAgICBjbGVhclRpbWVvdXQodGhpcy50aW1lcik7CiAgICAodGhpcy5vbkNvbXBsZXRlIHx8IFByb3RvdHlwZS5lbXB0eUZ1bmN0aW9uKS5hcHBseSh0aGlzLCBhcmd1bWVudHMpOwogIH0sCgogIHVwZGF0ZUNvbXBsZXRlOiBmdW5jdGlvbihyZXNwb25zZSkgewogICAgaWYgKHRoaXMub3B0aW9ucy5kZWNheSkgewogICAgICB0aGlzLmRlY2F5ID0gKHJlc3BvbnNlLnJlc3BvbnNlVGV4dCA9PSB0aGlzLmxhc3RUZXh0ID8KICAgICAgICB0aGlzLmRlY2F5ICogdGhpcy5vcHRpb25zLmRlY2F5IDogMSk7CgogICAgICB0aGlzLmxhc3RUZXh0ID0gcmVzcG9uc2UucmVzcG9uc2VUZXh0OwogICAgfQogICAgdGhpcy50aW1lciA9IHRoaXMub25UaW1lckV2ZW50LmJpbmQodGhpcykuZGVsYXkodGhpcy5kZWNheSAqIHRoaXMuZnJlcXVlbmN5KTsKICB9LAoKICBvblRpbWVyRXZlbnQ6IGZ1bmN0aW9uKCkgewogICAgdGhpcy51cGRhdGVyID0gbmV3IEFqYXguVXBkYXRlcih0aGlzLmNvbnRhaW5lciwgdGhpcy51cmwsIHRoaXMub3B0aW9ucyk7CiAgfQp9KTsKCgpmdW5jdGlvbiAkKGVsZW1lbnQpIHsKICBpZiAoYXJndW1lbnRzLmxlbmd0aCA+IDEpIHsKICAgIGZvciAodmFyIGkgPSAwLCBlbGVtZW50cyA9IFtdLCBsZW5ndGggPSBhcmd1bWVudHMubGVuZ3RoOyBpIDwgbGVuZ3RoOyBpKyspCiAgICAgIGVsZW1lbnRzLnB1c2goJChhcmd1bWVudHNbaV0pKTsKICAgIHJldHVybiBlbGVtZW50czsKICB9CiAgaWYgKE9iamVjdC5pc1N0cmluZyhlbGVtZW50KSkKICAgIGVsZW1lbnQgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZChlbGVtZW50KTsKICByZXR1cm4gRWxlbWVudC5leHRlbmQoZWxlbWVudCk7Cn0KCmlmIChQcm90b3R5cGUuQnJvd3NlckZlYXR1cmVzLlhQYXRoKSB7CiAgZG9jdW1lbnQuX2dldEVsZW1lbnRzQnlYUGF0aCA9IGZ1bmN0aW9uKGV4cHJlc3Npb24sIHBhcmVudEVsZW1lbnQpIHsKICAgIHZhciByZXN1bHRzID0gW107CiAgICB2YXIgcXVlcnkgPSBkb2N1bWVudC5ldmFsdWF0ZShleHByZXNzaW9uLCAkKHBhcmVudEVsZW1lbnQpIHx8IGRvY3VtZW50LAogICAgICBudWxsLCBYUGF0aFJlc3VsdC5PUkRFUkVEX05PREVfU05BUFNIT1RfVFlQRSwgbnVsbCk7CiAgICBmb3IgKHZhciBpID0gMCwgbGVuZ3RoID0gcXVlcnkuc25hcHNob3RMZW5ndGg7IGkgPCBsZW5ndGg7IGkrKykKICAgICAgcmVzdWx0cy5wdXNoKEVsZW1lbnQuZXh0ZW5kKHF1ZXJ5LnNuYXBzaG90SXRlbShpKSkpOwogICAgcmV0dXJuIHJlc3VsdHM7CiAgfTsKfQoKLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovCgppZiAoIU5vZGUpIHZhciBOb2RlID0geyB9OwoKaWYgKCFOb2RlLkVMRU1FTlRfTk9ERSkgewogIE9iamVjdC5leHRlbmQoTm9kZSwgewogICAgRUxFTUVOVF9OT0RFOiAxLAogICAgQVRUUklCVVRFX05PREU6IDIsCiAgICBURVhUX05PREU6IDMsCiAgICBDREFUQV9TRUNUSU9OX05PREU6IDQsCiAgICBFTlRJVFlfUkVGRVJFTkNFX05PREU6IDUsCiAgICBFTlRJVFlfTk9ERTogNiwKICAgIFBST0NFU1NJTkdfSU5TVFJVQ1RJT05fTk9ERTogNywKICAgIENPTU1FTlRfTk9ERTogOCwKICAgIERPQ1VNRU5UX05PREU6IDksCiAgICBET0NVTUVOVF9UWVBFX05PREU6IDEwLAogICAgRE9DVU1FTlRfRlJBR01FTlRfTk9ERTogMTEsCiAgICBOT1RBVElPTl9OT0RFOiAxMgogIH0pOwp9CgoKCihmdW5jdGlvbihnbG9iYWwpIHsKICBmdW5jdGlvbiBzaG91bGRVc2VDYWNoZSh0YWdOYW1lLCBhdHRyaWJ1dGVzKSB7CiAgICBpZiAodGFnTmFtZSA9PT0gJ3NlbGVjdCcpIHJldHVybiBmYWxzZTsKICAgIGlmICgndHlwZScgaW4gYXR0cmlidXRlcykgcmV0dXJuIGZhbHNlOwogICAgcmV0dXJuIHRydWU7CiAgfQoKICB2YXIgSEFTX0VYVEVOREVEX0NSRUFURV9FTEVNRU5UX1NZTlRBWCA9IChmdW5jdGlvbigpewogICAgdHJ5IHsKICAgICAgdmFyIGVsID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnPGlucHV0IG5hbWU9IngiPicpOwogICAgICByZXR1cm4gZWwudGFnTmFtZS50b0xvd2VyQ2FzZSgpID09PSAnaW5wdXQnICYmIGVsLm5hbWUgPT09ICd4JzsKICAgIH0KICAgIGNhdGNoKGVycikgewogICAgICByZXR1cm4gZmFsc2U7CiAgICB9CiAgfSkoKTsKCiAgdmFyIGVsZW1lbnQgPSBnbG9iYWwuRWxlbWVudDsKCiAgZ2xvYmFsLkVsZW1lbnQgPSBmdW5jdGlvbih0YWdOYW1lLCBhdHRyaWJ1dGVzKSB7CiAgICBhdHRyaWJ1dGVzID0gYXR0cmlidXRlcyB8fCB7IH07CiAgICB0YWdOYW1lID0gdGFnTmFtZS50b0xvd2VyQ2FzZSgpOwogICAgdmFyIGNhY2hlID0gRWxlbWVudC5jYWNoZTsKCiAgICBpZiAoSEFTX0VYVEVOREVEX0NSRUFURV9FTEVNRU5UX1NZTlRBWCAmJiBhdHRyaWJ1dGVzLm5hbWUpIHsKICAgICAgdGFnTmFtZSA9ICc8JyArIHRhZ05hbWUgKyAnIG5hbWU9IicgKyBhdHRyaWJ1dGVzLm5hbWUgKyAnIj4nOwogICAgICBkZWxldGUgYXR0cmlidXRlcy5uYW1lOwogICAgICByZXR1cm4gRWxlbWVudC53cml0ZUF0dHJpYnV0ZShkb2N1bWVudC5jcmVhdGVFbGVtZW50KHRhZ05hbWUpLCBhdHRyaWJ1dGVzKTsKICAgIH0KCiAgICBpZiAoIWNhY2hlW3RhZ05hbWVdKSBjYWNoZVt0YWdOYW1lXSA9IEVsZW1lbnQuZXh0ZW5kKGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQodGFnTmFtZSkpOwoKICAgIHZhciBub2RlID0gc2hvdWxkVXNlQ2FjaGUodGFnTmFtZSwgYXR0cmlidXRlcykgPwogICAgIGNhY2hlW3RhZ05hbWVdLmNsb25lTm9kZShmYWxzZSkgOiBkb2N1bWVudC5jcmVhdGVFbGVtZW50KHRhZ05hbWUpOwoKICAgIHJldHVybiBFbGVtZW50LndyaXRlQXR0cmlidXRlKG5vZGUsIGF0dHJpYnV0ZXMpOwogIH07CgogIE9iamVjdC5leHRlbmQoZ2xvYmFsLkVsZW1lbnQsIGVsZW1lbnQgfHwgeyB9KTsKICBpZiAoZWxlbWVudCkgZ2xvYmFsLkVsZW1lbnQucHJvdG90eXBlID0gZWxlbWVudC5wcm90b3R5cGU7Cgp9KSh0aGlzKTsKCkVsZW1lbnQuaWRDb3VudGVyID0gMTsKRWxlbWVudC5jYWNoZSA9IHsgfTsKCkVsZW1lbnQuX3B1cmdlRWxlbWVudCA9IGZ1bmN0aW9uKGVsZW1lbnQpIHsKICB2YXIgdWlkID0gZWxlbWVudC5fcHJvdG90eXBlVUlEOwogIGlmICh1aWQpIHsKICAgIEVsZW1lbnQuc3RvcE9ic2VydmluZyhlbGVtZW50KTsKICAgIGVsZW1lbnQuX3Byb3RvdHlwZVVJRCA9IHZvaWQgMDsKICAgIGRlbGV0ZSBFbGVtZW50LlN0b3JhZ2VbdWlkXTsKICB9Cn0KCkVsZW1lbnQuTWV0aG9kcyA9IHsKICB2aXNpYmxlOiBmdW5jdGlvbihlbGVtZW50KSB7CiAgICByZXR1cm4gJChlbGVtZW50KS5zdHlsZS5kaXNwbGF5ICE9ICdub25lJzsKICB9LAoKICB0b2dnbGU6IGZ1bmN0aW9uKGVsZW1lbnQpIHsKICAgIGVsZW1lbnQgPSAkKGVsZW1lbnQpOwogICAgRWxlbWVudFtFbGVtZW50LnZpc2libGUoZWxlbWVudCkgPyAnaGlkZScgOiAnc2hvdyddKGVsZW1lbnQpOwogICAgcmV0dXJuIGVsZW1lbnQ7CiAgfSwKCiAgaGlkZTogZnVuY3Rpb24oZWxlbWVudCkgewogICAgZWxlbWVudCA9ICQoZWxlbWVudCk7CiAgICBlbGVtZW50LnN0eWxlLmRpc3BsYXkgPSAnbm9uZSc7CiAgICByZXR1cm4gZWxlbWVudDsKICB9LAoKICBzaG93OiBmdW5jdGlvbihlbGVtZW50KSB7CiAgICBlbGVtZW50ID0gJChlbGVtZW50KTsKICAgIGVsZW1lbnQuc3R5bGUuZGlzcGxheSA9ICcnOwogICAgcmV0dXJuIGVsZW1lbnQ7CiAgfSwKCiAgcmVtb3ZlOiBmdW5jdGlvbihlbGVtZW50KSB7CiAgICBlbGVtZW50ID0gJChlbGVtZW50KTsKICAgIGVsZW1lbnQucGFyZW50Tm9kZS5yZW1vdmVDaGlsZChlbGVtZW50KTsKICAgIHJldHVybiBlbGVtZW50OwogIH0sCgogIHVwZGF0ZTogKGZ1bmN0aW9uKCl7CgogICAgdmFyIFNFTEVDVF9FTEVNRU5UX0lOTkVSSFRNTF9CVUdHWSA9IChmdW5jdGlvbigpewogICAgICB2YXIgZWwgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCJzZWxlY3QiKSwKICAgICAgICAgIGlzQnVnZ3kgPSB0cnVlOwogICAgICBlbC5pbm5lckhUTUwgPSAiPG9wdGlvbiB2YWx1ZT1cInRlc3RcIj50ZXN0PC9vcHRpb24+IjsKICAgICAgaWYgKGVsLm9wdGlvbnMgJiYgZWwub3B0aW9uc1swXSkgewogICAgICAgIGlzQnVnZ3kgPSBlbC5vcHRpb25zWzBdLm5vZGVOYW1lLnRvVXBwZXJDYXNlKCkgIT09ICJPUFRJT04iOwogICAgICB9CiAgICAgIGVsID0gbnVsbDsKICAgICAgcmV0dXJuIGlzQnVnZ3k7CiAgICB9KSgpOwoKICAgIHZhciBUQUJMRV9FTEVNRU5UX0lOTkVSSFRNTF9CVUdHWSA9IChmdW5jdGlvbigpewogICAgICB0cnkgewogICAgICAgIHZhciBlbCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoInRhYmxlIik7CiAgICAgICAgaWYgKGVsICYmIGVsLnRCb2RpZXMpIHsKICAgICAgICAgIGVsLmlubmVySFRNTCA9ICI8dGJvZHk+PHRyPjx0ZD50ZXN0PC90ZD48L3RyPjwvdGJvZHk+IjsKICAgICAgICAgIHZhciBpc0J1Z2d5ID0gdHlwZW9mIGVsLnRCb2RpZXNbMF0gPT0gInVuZGVmaW5lZCI7CiAgICAgICAgICBlbCA9IG51bGw7CiAgICAgICAgICByZXR1cm4gaXNCdWdneTsKICAgICAgICB9CiAgICAgIH0gY2F0Y2ggKGUpIHsKICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgfQogICAgfSkoKTsKCiAgICB2YXIgTElOS19FTEVNRU5UX0lOTkVSSFRNTF9CVUdHWSA9IChmdW5jdGlvbigpIHsKICAgICAgdHJ5IHsKICAgICAgICB2YXIgZWwgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdkaXYnKTsKICAgICAgICBlbC5pbm5lckhUTUwgPSAiPGxpbms+IjsKICAgICAgICB2YXIgaXNCdWdneSA9IChlbC5jaGlsZE5vZGVzLmxlbmd0aCA9PT0gMCk7CiAgICAgICAgZWwgPSBudWxsOwogICAgICAgIHJldHVybiBpc0J1Z2d5OwogICAgICB9IGNhdGNoKGUpIHsKICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgfQogICAgfSkoKTsKCiAgICB2YXIgQU5ZX0lOTkVSSFRNTF9CVUdHWSA9IFNFTEVDVF9FTEVNRU5UX0lOTkVSSFRNTF9CVUdHWSB8fAogICAgIFRBQkxFX0VMRU1FTlRfSU5ORVJIVE1MX0JVR0dZIHx8IExJTktfRUxFTUVOVF9JTk5FUkhUTUxfQlVHR1k7CgogICAgdmFyIFNDUklQVF9FTEVNRU5UX1JFSkVDVFNfVEVYVE5PREVfQVBQRU5ESU5HID0gKGZ1bmN0aW9uICgpIHsKICAgICAgdmFyIHMgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCJzY3JpcHQiKSwKICAgICAgICAgIGlzQnVnZ3kgPSBmYWxzZTsKICAgICAgdHJ5IHsKICAgICAgICBzLmFwcGVuZENoaWxkKGRvY3VtZW50LmNyZWF0ZVRleHROb2RlKCIiKSk7CiAgICAgICAgaXNCdWdneSA9ICFzLmZpcnN0Q2hpbGQgfHwKICAgICAgICAgIHMuZmlyc3RDaGlsZCAmJiBzLmZpcnN0Q2hpbGQubm9kZVR5cGUgIT09IDM7CiAgICAgIH0gY2F0Y2ggKGUpIHsKICAgICAgICBpc0J1Z2d5ID0gdHJ1ZTsKICAgICAgfQogICAgICBzID0gbnVsbDsKICAgICAgcmV0dXJuIGlzQnVnZ3k7CiAgICB9KSgpOwoKCiAgICBmdW5jdGlvbiB1cGRhdGUoZWxlbWVudCwgY29udGVudCkgewogICAgICBlbGVtZW50ID0gJChlbGVtZW50KTsKICAgICAgdmFyIHB1cmdlRWxlbWVudCA9IEVsZW1lbnQuX3B1cmdlRWxlbWVudDsKCiAgICAgIHZhciBkZXNjZW5kYW50cyA9IGVsZW1lbnQuZ2V0RWxlbWVudHNCeVRhZ05hbWUoJyonKSwKICAgICAgIGkgPSBkZXNjZW5kYW50cy5sZW5ndGg7CiAgICAgIHdoaWxlIChpLS0pIHB1cmdlRWxlbWVudChkZXNjZW5kYW50c1tpXSk7CgogICAgICBpZiAoY29udGVudCAmJiBjb250ZW50LnRvRWxlbWVudCkKICAgICAgICBjb250ZW50ID0gY29udGVudC50b0VsZW1lbnQoKTsKCiAgICAgIGlmIChPYmplY3QuaXNFbGVtZW50KGNvbnRlbnQpKQogICAgICAgIHJldHVybiBlbGVtZW50LnVwZGF0ZSgpLmluc2VydChjb250ZW50KTsKCiAgICAgIGNvbnRlbnQgPSBPYmplY3QudG9IVE1MKGNvbnRlbnQpOwoKICAgICAgdmFyIHRhZ05hbWUgPSBlbGVtZW50LnRhZ05hbWUudG9VcHBlckNhc2UoKTsKCiAgICAgIGlmICh0YWdOYW1lID09PSAnU0NSSVBUJyAmJiBTQ1JJUFRfRUxFTUVOVF9SRUpFQ1RTX1RFWFROT0RFX0FQUEVORElORykgewogICAgICAgIGVsZW1lbnQudGV4dCA9IGNvbnRlbnQ7CiAgICAgICAgcmV0dXJuIGVsZW1lbnQ7CiAgICAgIH0KCiAgICAgIGlmIChBTllfSU5ORVJIVE1MX0JVR0dZKSB7CiAgICAgICAgaWYgKHRhZ05hbWUgaW4gRWxlbWVudC5faW5zZXJ0aW9uVHJhbnNsYXRpb25zLnRhZ3MpIHsKICAgICAgICAgIHdoaWxlIChlbGVtZW50LmZpcnN0Q2hpbGQpIHsKICAgICAgICAgICAgZWxlbWVudC5yZW1vdmVDaGlsZChlbGVtZW50LmZpcnN0Q2hpbGQpOwogICAgICAgICAgfQogICAgICAgICAgRWxlbWVudC5fZ2V0Q29udGVudEZyb21Bbm9ueW1vdXNFbGVtZW50KHRhZ05hbWUsIGNvbnRlbnQuc3RyaXBTY3JpcHRzKCkpCiAgICAgICAgICAgIC5lYWNoKGZ1bmN0aW9uKG5vZGUpIHsKICAgICAgICAgICAgICBlbGVtZW50LmFwcGVuZENoaWxkKG5vZGUpCiAgICAgICAgICAgIH0pOwogICAgICAgIH0gZWxzZSBpZiAoTElOS19FTEVNRU5UX0lOTkVSSFRNTF9CVUdHWSAmJiBPYmplY3QuaXNTdHJpbmcoY29udGVudCkgJiYgY29udGVudC5pbmRleE9mKCc8bGluaycpID4gLTEpIHsKICAgICAgICAgIHdoaWxlIChlbGVtZW50LmZpcnN0Q2hpbGQpIHsKICAgICAgICAgICAgZWxlbWVudC5yZW1vdmVDaGlsZChlbGVtZW50LmZpcnN0Q2hpbGQpOwogICAgICAgICAgfQogICAgICAgICAgdmFyIG5vZGVzID0gRWxlbWVudC5fZ2V0Q29udGVudEZyb21Bbm9ueW1vdXNFbGVtZW50KHRhZ05hbWUsIGNvbnRlbnQuc3RyaXBTY3JpcHRzKCksIHRydWUpOwogICAgICAgICAgbm9kZXMuZWFjaChmdW5jdGlvbihub2RlKSB7IGVsZW1lbnQuYXBwZW5kQ2hpbGQobm9kZSkgfSk7CiAgICAgICAgfQogICAgICAgIGVsc2UgewogICAgICAgICAgZWxlbWVudC5pbm5lckhUTUwgPSBjb250ZW50LnN0cmlwU2NyaXB0cygpOwogICAgICAgIH0KICAgICAgfQogICAgICBlbHNlIHsKICAgICAgICBlbGVtZW50LmlubmVySFRNTCA9IGNvbnRlbnQuc3RyaXBTY3JpcHRzKCk7CiAgICAgIH0KCiAgICAgIGNvbnRlbnQuZXZhbFNjcmlwdHMuYmluZChjb250ZW50KS5kZWZlcigpOwogICAgICByZXR1cm4gZWxlbWVudDsKICAgIH0KCiAgICByZXR1cm4gdXBkYXRlOwogIH0pKCksCgogIHJlcGxhY2U6IGZ1bmN0aW9uKGVsZW1lbnQsIGNvbnRlbnQpIHsKICAgIGVsZW1lbnQgPSAkKGVsZW1lbnQpOwogICAgaWYgKGNvbnRlbnQgJiYgY29udGVudC50b0VsZW1lbnQpIGNvbnRlbnQgPSBjb250ZW50LnRvRWxlbWVudCgpOwogICAgZWxzZSBpZiAoIU9iamVjdC5pc0VsZW1lbnQoY29udGVudCkpIHsKICAgICAgY29udGVudCA9IE9iamVjdC50b0hUTUwoY29udGVudCk7CiAgICAgIHZhciByYW5nZSA9IGVsZW1lbnQub3duZXJEb2N1bWVudC5jcmVhdGVSYW5nZSgpOwogICAgICByYW5nZS5zZWxlY3ROb2RlKGVsZW1lbnQpOwogICAgICBjb250ZW50LmV2YWxTY3JpcHRzLmJpbmQoY29udGVudCkuZGVmZXIoKTsKICAgICAgY29udGVudCA9IHJhbmdlLmNyZWF0ZUNvbnRleHR1YWxGcmFnbWVudChjb250ZW50LnN0cmlwU2NyaXB0cygpKTsKICAgIH0KICAgIGVsZW1lbnQucGFyZW50Tm9kZS5yZXBsYWNlQ2hpbGQoY29udGVudCwgZWxlbWVudCk7CiAgICByZXR1cm4gZWxlbWVudDsKICB9LAoKICBpbnNlcnQ6IGZ1bmN0aW9uKGVsZW1lbnQsIGluc2VydGlvbnMpIHsKICAgIGVsZW1lbnQgPSAkKGVsZW1lbnQpOwoKICAgIGlmIChPYmplY3QuaXNTdHJpbmcoaW5zZXJ0aW9ucykgfHwgT2JqZWN0LmlzTnVtYmVyKGluc2VydGlvbnMpIHx8CiAgICAgICAgT2JqZWN0LmlzRWxlbWVudChpbnNlcnRpb25zKSB8fCAoaW5zZXJ0aW9ucyAmJiAoaW5zZXJ0aW9ucy50b0VsZW1lbnQgfHwgaW5zZXJ0aW9ucy50b0hUTUwpKSkKICAgICAgICAgIGluc2VydGlvbnMgPSB7Ym90dG9tOmluc2VydGlvbnN9OwoKICAgIHZhciBjb250ZW50LCBpbnNlcnQsIHRhZ05hbWUsIGNoaWxkTm9kZXM7CgogICAgZm9yICh2YXIgcG9zaXRpb24gaW4gaW5zZXJ0aW9ucykgewogICAgICBjb250ZW50ICA9IGluc2VydGlvbnNbcG9zaXRpb25dOwogICAgICBwb3NpdGlvbiA9IHBvc2l0aW9uLnRvTG93ZXJDYXNlKCk7CiAgICAgIGluc2VydCA9IEVsZW1lbnQuX2luc2VydGlvblRyYW5zbGF0aW9uc1twb3NpdGlvbl07CgogICAgICBpZiAoY29udGVudCAmJiBjb250ZW50LnRvRWxlbWVudCkgY29udGVudCA9IGNvbnRlbnQudG9FbGVtZW50KCk7CiAgICAgIGlmIChPYmplY3QuaXNFbGVtZW50KGNvbnRlbnQpKSB7CiAgICAgICAgaW5zZXJ0KGVsZW1lbnQsIGNvbnRlbnQpOwogICAgICAgIGNvbnRpbnVlOwogICAgICB9CgogICAgICBjb250ZW50ID0gT2JqZWN0LnRvSFRNTChjb250ZW50KTsKCiAgICAgIHRhZ05hbWUgPSAoKHBvc2l0aW9uID09ICdiZWZvcmUnIHx8IHBvc2l0aW9uID09ICdhZnRlcicpCiAgICAgICAgPyBlbGVtZW50LnBhcmVudE5vZGUgOiBlbGVtZW50KS50YWdOYW1lLnRvVXBwZXJDYXNlKCk7CgogICAgICBjaGlsZE5vZGVzID0gRWxlbWVudC5fZ2V0Q29udGVudEZyb21Bbm9ueW1vdXNFbGVtZW50KHRhZ05hbWUsIGNvbnRlbnQuc3RyaXBTY3JpcHRzKCkpOwoKICAgICAgaWYgKHBvc2l0aW9uID09ICd0b3AnIHx8IHBvc2l0aW9uID09ICdhZnRlcicpIGNoaWxkTm9kZXMucmV2ZXJzZSgpOwogICAgICBjaGlsZE5vZGVzLmVhY2goaW5zZXJ0LmN1cnJ5KGVsZW1lbnQpKTsKCiAgICAgIGNvbnRlbnQuZXZhbFNjcmlwdHMuYmluZChjb250ZW50KS5kZWZlcigpOwogICAgfQoKICAgIHJldHVybiBlbGVtZW50OwogIH0sCgogIHdyYXA6IGZ1bmN0aW9uKGVsZW1lbnQsIHdyYXBwZXIsIGF0dHJpYnV0ZXMpIHsKICAgIGVsZW1lbnQgPSAkKGVsZW1lbnQpOwogICAgaWYgKE9iamVjdC5pc0VsZW1lbnQod3JhcHBlcikpCiAgICAgICQod3JhcHBlcikud3JpdGVBdHRyaWJ1dGUoYXR0cmlidXRlcyB8fCB7IH0pOwogICAgZWxzZSBpZiAoT2JqZWN0LmlzU3RyaW5nKHdyYXBwZXIpKSB3cmFwcGVyID0gbmV3IEVsZW1lbnQod3JhcHBlciwgYXR0cmlidXRlcyk7CiAgICBlbHNlIHdyYXBwZXIgPSBuZXcgRWxlbWVudCgnZGl2Jywgd3JhcHBlcik7CiAgICBpZiAoZWxlbWVudC5wYXJlbnROb2RlKQogICAgICBlbGVtZW50LnBhcmVudE5vZGUucmVwbGFjZUNoaWxkKHdyYXBwZXIsIGVsZW1lbnQpOwogICAgd3JhcHBlci5hcHBlbmRDaGlsZChlbGVtZW50KTsKICAgIHJldHVybiB3cmFwcGVyOwogIH0sCgogIGluc3BlY3Q6IGZ1bmN0aW9uKGVsZW1lbnQpIHsKICAgIGVsZW1lbnQgPSAkKGVsZW1lbnQpOwogICAgdmFyIHJlc3VsdCA9ICc8JyArIGVsZW1lbnQudGFnTmFtZS50b0xvd2VyQ2FzZSgpOwogICAgJEgoeydpZCc6ICdpZCcsICdjbGFzc05hbWUnOiAnY2xhc3MnfSkuZWFjaChmdW5jdGlvbihwYWlyKSB7CiAgICAgIHZhciBwcm9wZXJ0eSA9IHBhaXIuZmlyc3QoKSwKICAgICAgICAgIGF0dHJpYnV0ZSA9IHBhaXIubGFzdCgpLAogICAgICAgICAgdmFsdWUgPSAoZWxlbWVudFtwcm9wZXJ0eV0gfHwgJycpLnRvU3RyaW5nKCk7CiAgICAgIGlmICh2YWx1ZSkgcmVzdWx0ICs9ICcgJyArIGF0dHJpYnV0ZSArICc9JyArIHZhbHVlLmluc3BlY3QodHJ1ZSk7CiAgICB9KTsKICAgIHJldHVybiByZXN1bHQgKyAnPic7CiAgfSwKCiAgcmVjdXJzaXZlbHlDb2xsZWN0OiBmdW5jdGlvbihlbGVtZW50LCBwcm9wZXJ0eSwgbWF4aW11bUxlbmd0aCkgewogICAgZWxlbWVudCA9ICQoZWxlbWVudCk7CiAgICBtYXhpbXVtTGVuZ3RoID0gbWF4aW11bUxlbmd0aCB8fCAtMTsKICAgIHZhciBlbGVtZW50cyA9IFtdOwoKICAgIHdoaWxlIChlbGVtZW50ID0gZWxlbWVudFtwcm9wZXJ0eV0pIHsKICAgICAgaWYgKGVsZW1lbnQubm9kZVR5cGUgPT0gMSkKICAgICAgICBlbGVtZW50cy5wdXNoKEVsZW1lbnQuZXh0ZW5kKGVsZW1lbnQpKTsKICAgICAgaWYgKGVsZW1lbnRzLmxlbmd0aCA9PSBtYXhpbXVtTGVuZ3RoKQogICAgICAgIGJyZWFrOwogICAgfQoKICAgIHJldHVybiBlbGVtZW50czsKICB9LAoKICBhbmNlc3RvcnM6IGZ1bmN0aW9uKGVsZW1lbnQpIHsKICAgIHJldHVybiBFbGVtZW50LnJlY3Vyc2l2ZWx5Q29sbGVjdChlbGVtZW50LCAncGFyZW50Tm9kZScpOwogIH0sCgogIGRlc2NlbmRhbnRzOiBmdW5jdGlvbihlbGVtZW50KSB7CiAgICByZXR1cm4gRWxlbWVudC5zZWxlY3QoZWxlbWVudCwgIioiKTsKICB9LAoKICBmaXJzdERlc2NlbmRhbnQ6IGZ1bmN0aW9uKGVsZW1lbnQpIHsKICAgIGVsZW1lbnQgPSAkKGVsZW1lbnQpLmZpcnN0Q2hpbGQ7CiAgICB3aGlsZSAoZWxlbWVudCAmJiBlbGVtZW50Lm5vZGVUeXBlICE9IDEpIGVsZW1lbnQgPSBlbGVtZW50Lm5leHRTaWJsaW5nOwogICAgcmV0dXJuICQoZWxlbWVudCk7CiAgfSwKCiAgaW1tZWRpYXRlRGVzY2VuZGFudHM6IGZ1bmN0aW9uKGVsZW1lbnQpIHsKICAgIHZhciByZXN1bHRzID0gW10sIGNoaWxkID0gJChlbGVtZW50KS5maXJzdENoaWxkOwogICAgd2hpbGUgKGNoaWxkKSB7CiAgICAgIGlmIChjaGlsZC5ub2RlVHlwZSA9PT0gMSkgewogICAgICAgIHJlc3VsdHMucHVzaChFbGVtZW50LmV4dGVuZChjaGlsZCkpOwogICAgICB9CiAgICAgIGNoaWxkID0gY2hpbGQubmV4dFNpYmxpbmc7CiAgICB9CiAgICByZXR1cm4gcmVzdWx0czsKICB9LAoKICBwcmV2aW91c1NpYmxpbmdzOiBmdW5jdGlvbihlbGVtZW50LCBtYXhpbXVtTGVuZ3RoKSB7CiAgICByZXR1cm4gRWxlbWVudC5yZWN1cnNpdmVseUNvbGxlY3QoZWxlbWVudCwgJ3ByZXZpb3VzU2libGluZycpOwogIH0sCgogIG5leHRTaWJsaW5nczogZnVuY3Rpb24oZWxlbWVudCkgewogICAgcmV0dXJuIEVsZW1lbnQucmVjdXJzaXZlbHlDb2xsZWN0KGVsZW1lbnQsICduZXh0U2libGluZycpOwogIH0sCgogIHNpYmxpbmdzOiBmdW5jdGlvbihlbGVtZW50KSB7CiAgICBlbGVtZW50ID0gJChlbGVtZW50KTsKICAgIHJldHVybiBFbGVtZW50LnByZXZpb3VzU2libGluZ3MoZWxlbWVudCkucmV2ZXJzZSgpCiAgICAgIC5jb25jYXQoRWxlbWVudC5uZXh0U2libGluZ3MoZWxlbWVudCkpOwogIH0sCgogIG1hdGNoOiBmdW5jdGlvbihlbGVtZW50LCBzZWxlY3RvcikgewogICAgZWxlbWVudCA9ICQoZWxlbWVudCk7CiAgICBpZiAoT2JqZWN0LmlzU3RyaW5nKHNlbGVjdG9yKSkKICAgICAgcmV0dXJuIFByb3RvdHlwZS5TZWxlY3Rvci5tYXRjaChlbGVtZW50LCBzZWxlY3Rvcik7CiAgICByZXR1cm4gc2VsZWN0b3IubWF0Y2goZWxlbWVudCk7CiAgfSwKCiAgdXA6IGZ1bmN0aW9uKGVsZW1lbnQsIGV4cHJlc3Npb24sIGluZGV4KSB7CiAgICBlbGVtZW50ID0gJChlbGVtZW50KTsKICAgIGlmIChhcmd1bWVudHMubGVuZ3RoID09IDEpIHJldHVybiAkKGVsZW1lbnQucGFyZW50Tm9kZSk7CiAgICB2YXIgYW5jZXN0b3JzID0gRWxlbWVudC5hbmNlc3RvcnMoZWxlbWVudCk7CiAgICByZXR1cm4gT2JqZWN0LmlzTnVtYmVyKGV4cHJlc3Npb24pID8gYW5jZXN0b3JzW2V4cHJlc3Npb25dIDoKICAgICAgUHJvdG90eXBlLlNlbGVjdG9yLmZpbmQoYW5jZXN0b3JzLCBleHByZXNzaW9uLCBpbmRleCk7CiAgfSwKCiAgZG93bjogZnVuY3Rpb24oZWxlbWVudCwgZXhwcmVzc2lvbiwgaW5kZXgpIHsKICAgIGVsZW1lbnQgPSAkKGVsZW1lbnQpOwogICAgaWYgKGFyZ3VtZW50cy5sZW5ndGggPT0gMSkgcmV0dXJuIEVsZW1lbnQuZmlyc3REZXNjZW5kYW50KGVsZW1lbnQpOwogICAgcmV0dXJuIE9iamVjdC5pc051bWJlcihleHByZXNzaW9uKSA/IEVsZW1lbnQuZGVzY2VuZGFudHMoZWxlbWVudClbZXhwcmVzc2lvbl0gOgogICAgICBFbGVtZW50LnNlbGVjdChlbGVtZW50LCBleHByZXNzaW9uKVtpbmRleCB8fCAwXTsKICB9LAoKICBwcmV2aW91czogZnVuY3Rpb24oZWxlbWVudCwgZXhwcmVzc2lvbiwgaW5kZXgpIHsKICAgIGVsZW1lbnQgPSAkKGVsZW1lbnQpOwogICAgaWYgKE9iamVjdC5pc051bWJlcihleHByZXNzaW9uKSkgaW5kZXggPSBleHByZXNzaW9uLCBleHByZXNzaW9uID0gZmFsc2U7CiAgICBpZiAoIU9iamVjdC5pc051bWJlcihpbmRleCkpIGluZGV4ID0gMDsKCiAgICBpZiAoZXhwcmVzc2lvbikgewogICAgICByZXR1cm4gUHJvdG90eXBlLlNlbGVjdG9yLmZpbmQoZWxlbWVudC5wcmV2aW91c1NpYmxpbmdzKCksIGV4cHJlc3Npb24sIGluZGV4KTsKICAgIH0gZWxzZSB7CiAgICAgIHJldHVybiBlbGVtZW50LnJlY3Vyc2l2ZWx5Q29sbGVjdCgicHJldmlvdXNTaWJsaW5nIiwgaW5kZXggKyAxKVtpbmRleF07CiAgICB9CiAgfSwKCiAgbmV4dDogZnVuY3Rpb24oZWxlbWVudCwgZXhwcmVzc2lvbiwgaW5kZXgpIHsKICAgIGVsZW1lbnQgPSAkKGVsZW1lbnQpOwogICAgaWYgKE9iamVjdC5pc051bWJlcihleHByZXNzaW9uKSkgaW5kZXggPSBleHByZXNzaW9uLCBleHByZXNzaW9uID0gZmFsc2U7CiAgICBpZiAoIU9iamVjdC5pc051bWJlcihpbmRleCkpIGluZGV4ID0gMDsKCiAgICBpZiAoZXhwcmVzc2lvbikgewogICAgICByZXR1cm4gUHJvdG90eXBlLlNlbGVjdG9yLmZpbmQoZWxlbWVudC5uZXh0U2libGluZ3MoKSwgZXhwcmVzc2lvbiwgaW5kZXgpOwogICAgfSBlbHNlIHsKICAgICAgdmFyIG1heGltdW1MZW5ndGggPSBPYmplY3QuaXNOdW1iZXIoaW5kZXgpID8gaW5kZXggKyAxIDogMTsKICAgICAgcmV0dXJuIGVsZW1lbnQucmVjdXJzaXZlbHlDb2xsZWN0KCJuZXh0U2libGluZyIsIGluZGV4ICsgMSlbaW5kZXhdOwogICAgfQogIH0sCgoKICBzZWxlY3Q6IGZ1bmN0aW9uKGVsZW1lbnQpIHsKICAgIGVsZW1lbnQgPSAkKGVsZW1lbnQpOwogICAgdmFyIGV4cHJlc3Npb25zID0gQXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwoYXJndW1lbnRzLCAxKS5qb2luKCcsICcpOwogICAgcmV0dXJuIFByb3RvdHlwZS5TZWxlY3Rvci5zZWxlY3QoZXhwcmVzc2lvbnMsIGVsZW1lbnQpOwogIH0sCgogIGFkamFjZW50OiBmdW5jdGlvbihlbGVtZW50KSB7CiAgICBlbGVtZW50ID0gJChlbGVtZW50KTsKICAgIHZhciBleHByZXNzaW9ucyA9IEFycmF5LnByb3RvdHlwZS5zbGljZS5jYWxsKGFyZ3VtZW50cywgMSkuam9pbignLCAnKTsKICAgIHJldHVybiBQcm90b3R5cGUuU2VsZWN0b3Iuc2VsZWN0KGV4cHJlc3Npb25zLCBlbGVtZW50LnBhcmVudE5vZGUpLndpdGhvdXQoZWxlbWVudCk7CiAgfSwKCiAgaWRlbnRpZnk6IGZ1bmN0aW9uKGVsZW1lbnQpIHsKICAgIGVsZW1lbnQgPSAkKGVsZW1lbnQpOwogICAgdmFyIGlkID0gRWxlbWVudC5yZWFkQXR0cmlidXRlKGVsZW1lbnQsICdpZCcpOwogICAgaWYgKGlkKSByZXR1cm4gaWQ7CiAgICBkbyB7IGlkID0gJ2Fub255bW91c19lbGVtZW50XycgKyBFbGVtZW50LmlkQ291bnRlcisrIH0gd2hpbGUgKCQoaWQpKTsKICAgIEVsZW1lbnQud3JpdGVBdHRyaWJ1dGUoZWxlbWVudCwgJ2lkJywgaWQpOwogICAgcmV0dXJuIGlkOwogIH0sCgogIHJlYWRBdHRyaWJ1dGU6IGZ1bmN0aW9uKGVsZW1lbnQsIG5hbWUpIHsKICAgIGVsZW1lbnQgPSAkKGVsZW1lbnQpOwogICAgaWYgKFByb3RvdHlwZS5Ccm93c2VyLklFKSB7CiAgICAgIHZhciB0ID0gRWxlbWVudC5fYXR0cmlidXRlVHJhbnNsYXRpb25zLnJlYWQ7CiAgICAgIGlmICh0LnZhbHVlc1tuYW1lXSkgcmV0dXJuIHQudmFsdWVzW25hbWVdKGVsZW1lbnQsIG5hbWUpOwogICAgICBpZiAodC5uYW1lc1tuYW1lXSkgbmFtZSA9IHQubmFtZXNbbmFtZV07CiAgICAgIGlmIChuYW1lLmluY2x1ZGUoJzonKSkgewogICAgICAgIHJldHVybiAoIWVsZW1lbnQuYXR0cmlidXRlcyB8fCAhZWxlbWVudC5hdHRyaWJ1dGVzW25hbWVdKSA/IG51bGwgOgogICAgICAgICBlbGVtZW50LmF0dHJpYnV0ZXNbbmFtZV0udmFsdWU7CiAgICAgIH0KICAgIH0KICAgIHJldHVybiBlbGVtZW50LmdldEF0dHJpYnV0ZShuYW1lKTsKICB9LAoKICB3cml0ZUF0dHJpYnV0ZTogZnVuY3Rpb24oZWxlbWVudCwgbmFtZSwgdmFsdWUpIHsKICAgIGVsZW1lbnQgPSAkKGVsZW1lbnQpOwogICAgdmFyIGF0dHJpYnV0ZXMgPSB7IH0sIHQgPSBFbGVtZW50Ll9hdHRyaWJ1dGVUcmFuc2xhdGlvbnMud3JpdGU7CgogICAgaWYgKHR5cGVvZiBuYW1lID09ICdvYmplY3QnKSBhdHRyaWJ1dGVzID0gbmFtZTsKICAgIGVsc2UgYXR0cmlidXRlc1tuYW1lXSA9IE9iamVjdC5pc1VuZGVmaW5lZCh2YWx1ZSkgPyB0cnVlIDogdmFsdWU7CgogICAgZm9yICh2YXIgYXR0ciBpbiBhdHRyaWJ1dGVzKSB7CiAgICAgIG5hbWUgPSB0Lm5hbWVzW2F0dHJdIHx8IGF0dHI7CiAgICAgIHZhbHVlID0gYXR0cmlidXRlc1thdHRyXTsKICAgICAgaWYgKHQudmFsdWVzW2F0dHJdKSBuYW1lID0gdC52YWx1ZXNbYXR0cl0oZWxlbWVudCwgdmFsdWUpOwogICAgICBpZiAodmFsdWUgPT09IGZhbHNlIHx8IHZhbHVlID09PSBudWxsKQogICAgICAgIGVsZW1lbnQucmVtb3ZlQXR0cmlidXRlKG5hbWUpOwogICAgICBlbHNlIGlmICh2YWx1ZSA9PT0gdHJ1ZSkKICAgICAgICBlbGVtZW50LnNldEF0dHJpYnV0ZShuYW1lLCBuYW1lKTsKICAgICAgZWxzZSBlbGVtZW50LnNldEF0dHJpYnV0ZShuYW1lLCB2YWx1ZSk7CiAgICB9CiAgICByZXR1cm4gZWxlbWVudDsKICB9LAoKICBnZXRIZWlnaHQ6IGZ1bmN0aW9uKGVsZW1lbnQpIHsKICAgIHJldHVybiBFbGVtZW50LmdldERpbWVuc2lvbnMoZWxlbWVudCkuaGVpZ2h0OwogIH0sCgogIGdldFdpZHRoOiBmdW5jdGlvbihlbGVtZW50KSB7CiAgICByZXR1cm4gRWxlbWVudC5nZXREaW1lbnNpb25zKGVsZW1lbnQpLndpZHRoOwogIH0sCgogIGNsYXNzTmFtZXM6IGZ1bmN0aW9uKGVsZW1lbnQpIHsKICAgIHJldHVybiBuZXcgRWxlbWVudC5DbGFzc05hbWVzKGVsZW1lbnQpOwogIH0sCgogIGhhc0NsYXNzTmFtZTogZnVuY3Rpb24oZWxlbWVudCwgY2xhc3NOYW1lKSB7CiAgICBpZiAoIShlbGVtZW50ID0gJChlbGVtZW50KSkpIHJldHVybjsKICAgIHZhciBlbGVtZW50Q2xhc3NOYW1lID0gZWxlbWVudC5jbGFzc05hbWU7CiAgICByZXR1cm4gKGVsZW1lbnRDbGFzc05hbWUubGVuZ3RoID4gMCAmJiAoZWxlbWVudENsYXNzTmFtZSA9PSBjbGFzc05hbWUgfHwKICAgICAgbmV3IFJlZ0V4cCgiKF58XFxzKSIgKyBjbGFzc05hbWUgKyAiKFxcc3wkKSIpLnRlc3QoZWxlbWVudENsYXNzTmFtZSkpKTsKICB9LAoKICBhZGRDbGFzc05hbWU6IGZ1bmN0aW9uKGVsZW1lbnQsIGNsYXNzTmFtZSkgewogICAgaWYgKCEoZWxlbWVudCA9ICQoZWxlbWVudCkpKSByZXR1cm47CiAgICBpZiAoIUVsZW1lbnQuaGFzQ2xhc3NOYW1lKGVsZW1lbnQsIGNsYXNzTmFtZSkpCiAgICAgIGVsZW1lbnQuY2xhc3NOYW1lICs9IChlbGVtZW50LmNsYXNzTmFtZSA/ICcgJyA6ICcnKSArIGNsYXNzTmFtZTsKICAgIHJldHVybiBlbGVtZW50OwogIH0sCgogIHJlbW92ZUNsYXNzTmFtZTogZnVuY3Rpb24oZWxlbWVudCwgY2xhc3NOYW1lKSB7CiAgICBpZiAoIShlbGVtZW50ID0gJChlbGVtZW50KSkpIHJldHVybjsKICAgIGVsZW1lbnQuY2xhc3NOYW1lID0gZWxlbWVudC5jbGFzc05hbWUucmVwbGFjZSgKICAgICAgbmV3IFJlZ0V4cCgiKF58XFxzKykiICsgY2xhc3NOYW1lICsgIihcXHMrfCQpIiksICcgJykuc3RyaXAoKTsKICAgIHJldHVybiBlbGVtZW50OwogIH0sCgogIHRvZ2dsZUNsYXNzTmFtZTogZnVuY3Rpb24oZWxlbWVudCwgY2xhc3NOYW1lKSB7CiAgICBpZiAoIShlbGVtZW50ID0gJChlbGVtZW50KSkpIHJldHVybjsKICAgIHJldHVybiBFbGVtZW50W0VsZW1lbnQuaGFzQ2xhc3NOYW1lKGVsZW1lbnQsIGNsYXNzTmFtZSkgPwogICAgICAncmVtb3ZlQ2xhc3NOYW1lJyA6ICdhZGRDbGFzc05hbWUnXShlbGVtZW50LCBjbGFzc05hbWUpOwogIH0sCgogIGNsZWFuV2hpdGVzcGFjZTogZnVuY3Rpb24oZWxlbWVudCkgewogICAgZWxlbWVudCA9ICQoZWxlbWVudCk7CiAgICB2YXIgbm9kZSA9IGVsZW1lbnQuZmlyc3RDaGlsZDsKICAgIHdoaWxlIChub2RlKSB7CiAgICAgIHZhciBuZXh0Tm9kZSA9IG5vZGUubmV4dFNpYmxpbmc7CiAgICAgIGlmIChub2RlLm5vZGVUeXBlID09IDMgJiYgIS9cUy8udGVzdChub2RlLm5vZGVWYWx1ZSkpCiAgICAgICAgZWxlbWVudC5yZW1vdmVDaGlsZChub2RlKTsKICAgICAgbm9kZSA9IG5leHROb2RlOwogICAgfQogICAgcmV0dXJuIGVsZW1lbnQ7CiAgfSwKCiAgZW1wdHk6IGZ1bmN0aW9uKGVsZW1lbnQpIHsKICAgIHJldHVybiAkKGVsZW1lbnQpLmlubmVySFRNTC5ibGFuaygpOwogIH0sCgogIGRlc2NlbmRhbnRPZjogZnVuY3Rpb24oZWxlbWVudCwgYW5jZXN0b3IpIHsKICAgIGVsZW1lbnQgPSAkKGVsZW1lbnQpLCBhbmNlc3RvciA9ICQoYW5jZXN0b3IpOwoKICAgIGlmIChlbGVtZW50LmNvbXBhcmVEb2N1bWVudFBvc2l0aW9uKQogICAgICByZXR1cm4gKGVsZW1lbnQuY29tcGFyZURvY3VtZW50UG9zaXRpb24oYW5jZXN0b3IpICYgOCkgPT09IDg7CgogICAgaWYgKGFuY2VzdG9yLmNvbnRhaW5zKQogICAgICByZXR1cm4gYW5jZXN0b3IuY29udGFpbnMoZWxlbWVudCkgJiYgYW5jZXN0b3IgIT09IGVsZW1lbnQ7CgogICAgd2hpbGUgKGVsZW1lbnQgPSBlbGVtZW50LnBhcmVudE5vZGUpCiAgICAgIGlmIChlbGVtZW50ID09IGFuY2VzdG9yKSByZXR1cm4gdHJ1ZTsKCiAgICByZXR1cm4gZmFsc2U7CiAgfSwKCiAgc2Nyb2xsVG86IGZ1bmN0aW9uKGVsZW1lbnQpIHsKICAgIGVsZW1lbnQgPSAkKGVsZW1lbnQpOwogICAgdmFyIHBvcyA9IEVsZW1lbnQuY3VtdWxhdGl2ZU9mZnNldChlbGVtZW50KTsKICAgIHdpbmRvdy5zY3JvbGxUbyhwb3NbMF0sIHBvc1sxXSk7CiAgICByZXR1cm4gZWxlbWVudDsKICB9LAoKICBnZXRTdHlsZTogZnVuY3Rpb24oZWxlbWVudCwgc3R5bGUpIHsKICAgIGVsZW1lbnQgPSAkKGVsZW1lbnQpOwogICAgc3R5bGUgPSBzdHlsZSA9PSAnZmxvYXQnID8gJ2Nzc0Zsb2F0JyA6IHN0eWxlLmNhbWVsaXplKCk7CiAgICB2YXIgdmFsdWUgPSBlbGVtZW50LnN0eWxlW3N0eWxlXTsKICAgIGlmICghdmFsdWUgfHwgdmFsdWUgPT0gJ2F1dG8nKSB7CiAgICAgIHZhciBjc3MgPSBkb2N1bWVudC5kZWZhdWx0Vmlldy5nZXRDb21wdXRlZFN0eWxlKGVsZW1lbnQsIG51bGwpOwogICAgICB2YWx1ZSA9IGNzcyA/IGNzc1tzdHlsZV0gOiBudWxsOwogICAgfQogICAgaWYgKHN0eWxlID09ICdvcGFjaXR5JykgcmV0dXJuIHZhbHVlID8gcGFyc2VGbG9hdCh2YWx1ZSkgOiAxLjA7CiAgICByZXR1cm4gdmFsdWUgPT0gJ2F1dG8nID8gbnVsbCA6IHZhbHVlOwogIH0sCgogIGdldE9wYWNpdHk6IGZ1bmN0aW9uKGVsZW1lbnQpIHsKICAgIHJldHVybiAkKGVsZW1lbnQpLmdldFN0eWxlKCdvcGFjaXR5Jyk7CiAgfSwKCiAgc2V0U3R5bGU6IGZ1bmN0aW9uKGVsZW1lbnQsIHN0eWxlcykgewogICAgZWxlbWVudCA9ICQoZWxlbWVudCk7CiAgICB2YXIgZWxlbWVudFN0eWxlID0gZWxlbWVudC5zdHlsZSwgbWF0Y2g7CiAgICBpZiAoT2JqZWN0LmlzU3RyaW5nKHN0eWxlcykpIHsKICAgICAgZWxlbWVudC5zdHlsZS5jc3NUZXh0ICs9ICc7JyArIHN0eWxlczsKICAgICAgcmV0dXJuIHN0eWxlcy5pbmNsdWRlKCdvcGFjaXR5JykgPwogICAgICAgIGVsZW1lbnQuc2V0T3BhY2l0eShzdHlsZXMubWF0Y2goL29wYWNpdHk6XHMqKFxkP1wuP1xkKikvKVsxXSkgOiBlbGVtZW50OwogICAgfQogICAgZm9yICh2YXIgcHJvcGVydHkgaW4gc3R5bGVzKQogICAgICBpZiAocHJvcGVydHkgPT0gJ29wYWNpdHknKSBlbGVtZW50LnNldE9wYWNpdHkoc3R5bGVzW3Byb3BlcnR5XSk7CiAgICAgIGVsc2UKICAgICAgICBlbGVtZW50U3R5bGVbKHByb3BlcnR5ID09ICdmbG9hdCcgfHwgcHJvcGVydHkgPT0gJ2Nzc0Zsb2F0JykgPwogICAgICAgICAgKE9iamVjdC5pc1VuZGVmaW5lZChlbGVtZW50U3R5bGUuc3R5bGVGbG9hdCkgPyAnY3NzRmxvYXQnIDogJ3N0eWxlRmxvYXQnKSA6CiAgICAgICAgICAgIHByb3BlcnR5XSA9IHN0eWxlc1twcm9wZXJ0eV07CgogICAgcmV0dXJuIGVsZW1lbnQ7CiAgfSwKCiAgc2V0T3BhY2l0eTogZnVuY3Rpb24oZWxlbWVudCwgdmFsdWUpIHsKICAgIGVsZW1lbnQgPSAkKGVsZW1lbnQpOwogICAgZWxlbWVudC5zdHlsZS5vcGFjaXR5ID0gKHZhbHVlID09IDEgfHwgdmFsdWUgPT09ICcnKSA/ICcnIDoKICAgICAgKHZhbHVlIDwgMC4wMDAwMSkgPyAwIDogdmFsdWU7CiAgICByZXR1cm4gZWxlbWVudDsKICB9LAoKICBtYWtlUG9zaXRpb25lZDogZnVuY3Rpb24oZWxlbWVudCkgewogICAgZWxlbWVudCA9ICQoZWxlbWVudCk7CiAgICB2YXIgcG9zID0gRWxlbWVudC5nZXRTdHlsZShlbGVtZW50LCAncG9zaXRpb24nKTsKICAgIGlmIChwb3MgPT0gJ3N0YXRpYycgfHwgIXBvcykgewogICAgICBlbGVtZW50Ll9tYWRlUG9zaXRpb25lZCA9IHRydWU7CiAgICAgIGVsZW1lbnQuc3R5bGUucG9zaXRpb24gPSAncmVsYXRpdmUnOwogICAgICBpZiAoUHJvdG90eXBlLkJyb3dzZXIuT3BlcmEpIHsKICAgICAgICBlbGVtZW50LnN0eWxlLnRvcCA9IDA7CiAgICAgICAgZWxlbWVudC5zdHlsZS5sZWZ0ID0gMDsKICAgICAgfQogICAgfQogICAgcmV0dXJuIGVsZW1lbnQ7CiAgfSwKCiAgdW5kb1Bvc2l0aW9uZWQ6IGZ1bmN0aW9uKGVsZW1lbnQpIHsKICAgIGVsZW1lbnQgPSAkKGVsZW1lbnQpOwogICAgaWYgKGVsZW1lbnQuX21hZGVQb3NpdGlvbmVkKSB7CiAgICAgIGVsZW1lbnQuX21hZGVQb3NpdGlvbmVkID0gdW5kZWZpbmVkOwogICAgICBlbGVtZW50LnN0eWxlLnBvc2l0aW9uID0KICAgICAgICBlbGVtZW50LnN0eWxlLnRvcCA9CiAgICAgICAgZWxlbWVudC5zdHlsZS5sZWZ0ID0KICAgICAgICBlbGVtZW50LnN0eWxlLmJvdHRvbSA9CiAgICAgICAgZWxlbWVudC5zdHlsZS5yaWdodCA9ICcnOwogICAgfQogICAgcmV0dXJuIGVsZW1lbnQ7CiAgfSwKCiAgbWFrZUNsaXBwaW5nOiBmdW5jdGlvbihlbGVtZW50KSB7CiAgICBlbGVtZW50ID0gJChlbGVtZW50KTsKICAgIGlmIChlbGVtZW50Ll9vdmVyZmxvdykgcmV0dXJuIGVsZW1lbnQ7CiAgICBlbGVtZW50Ll9vdmVyZmxvdyA9IEVsZW1lbnQuZ2V0U3R5bGUoZWxlbWVudCwgJ292ZXJmbG93JykgfHwgJ2F1dG8nOwogICAgaWYgKGVsZW1lbnQuX292ZXJmbG93ICE9PSAnaGlkZGVuJykKICAgICAgZWxlbWVudC5zdHlsZS5vdmVyZmxvdyA9ICdoaWRkZW4nOwogICAgcmV0dXJuIGVsZW1lbnQ7CiAgfSwKCiAgdW5kb0NsaXBwaW5nOiBmdW5jdGlvbihlbGVtZW50KSB7CiAgICBlbGVtZW50ID0gJChlbGVtZW50KTsKICAgIGlmICghZWxlbWVudC5fb3ZlcmZsb3cpIHJldHVybiBlbGVtZW50OwogICAgZWxlbWVudC5zdHlsZS5vdmVyZmxvdyA9IGVsZW1lbnQuX292ZXJmbG93ID09ICdhdXRvJyA/ICcnIDogZWxlbWVudC5fb3ZlcmZsb3c7CiAgICBlbGVtZW50Ll9vdmVyZmxvdyA9IG51bGw7CiAgICByZXR1cm4gZWxlbWVudDsKICB9LAoKICBjbG9uZVBvc2l0aW9uOiBmdW5jdGlvbihlbGVtZW50LCBzb3VyY2UpIHsKICAgIHZhciBvcHRpb25zID0gT2JqZWN0LmV4dGVuZCh7CiAgICAgIHNldExlZnQ6ICAgIHRydWUsCiAgICAgIHNldFRvcDogICAgIHRydWUsCiAgICAgIHNldFdpZHRoOiAgIHRydWUsCiAgICAgIHNldEhlaWdodDogIHRydWUsCiAgICAgIG9mZnNldFRvcDogIDAsCiAgICAgIG9mZnNldExlZnQ6IDAKICAgIH0sIGFyZ3VtZW50c1syXSB8fCB7IH0pOwoKICAgIHNvdXJjZSA9ICQoc291cmNlKTsKICAgIHZhciBwID0gRWxlbWVudC52aWV3cG9ydE9mZnNldChzb3VyY2UpLCBkZWx0YSA9IFswLCAwXSwgcGFyZW50ID0gbnVsbDsKCiAgICBlbGVtZW50ID0gJChlbGVtZW50KTsKCiAgICBpZiAoRWxlbWVudC5nZXRTdHlsZShlbGVtZW50LCAncG9zaXRpb24nKSA9PSAnYWJzb2x1dGUnKSB7CiAgICAgIHBhcmVudCA9IEVsZW1lbnQuZ2V0T2Zmc2V0UGFyZW50KGVsZW1lbnQpOwogICAgICBkZWx0YSA9IEVsZW1lbnQudmlld3BvcnRPZmZzZXQocGFyZW50KTsKICAgIH0KCiAgICBpZiAocGFyZW50ID09IGRvY3VtZW50LmJvZHkpIHsKICAgICAgZGVsdGFbMF0gLT0gZG9jdW1lbnQuYm9keS5vZmZzZXRMZWZ0OwogICAgICBkZWx0YVsxXSAtPSBkb2N1bWVudC5ib2R5Lm9mZnNldFRvcDsKICAgIH0KCiAgICBpZiAob3B0aW9ucy5zZXRMZWZ0KSAgIGVsZW1lbnQuc3R5bGUubGVmdCAgPSAocFswXSAtIGRlbHRhWzBdICsgb3B0aW9ucy5vZmZzZXRMZWZ0KSArICdweCc7CiAgICBpZiAob3B0aW9ucy5zZXRUb3ApICAgIGVsZW1lbnQuc3R5bGUudG9wICAgPSAocFsxXSAtIGRlbHRhWzFdICsgb3B0aW9ucy5vZmZzZXRUb3ApICsgJ3B4JzsKICAgIGlmIChvcHRpb25zLnNldFdpZHRoKSAgZWxlbWVudC5zdHlsZS53aWR0aCA9IHNvdXJjZS5vZmZzZXRXaWR0aCArICdweCc7CiAgICBpZiAob3B0aW9ucy5zZXRIZWlnaHQpIGVsZW1lbnQuc3R5bGUuaGVpZ2h0ID0gc291cmNlLm9mZnNldEhlaWdodCArICdweCc7CiAgICByZXR1cm4gZWxlbWVudDsKICB9Cn07CgpPYmplY3QuZXh0ZW5kKEVsZW1lbnQuTWV0aG9kcywgewogIGdldEVsZW1lbnRzQnlTZWxlY3RvcjogRWxlbWVudC5NZXRob2RzLnNlbGVjdCwKCiAgY2hpbGRFbGVtZW50czogRWxlbWVudC5NZXRob2RzLmltbWVkaWF0ZURlc2NlbmRhbnRzCn0pOwoKRWxlbWVudC5fYXR0cmlidXRlVHJhbnNsYXRpb25zID0gewogIHdyaXRlOiB7CiAgICBuYW1lczogewogICAgICBjbGFzc05hbWU6ICdjbGFzcycsCiAgICAgIGh0bWxGb3I6ICAgJ2ZvcicKICAgIH0sCiAgICB2YWx1ZXM6IHsgfQogIH0KfTsKCmlmIChQcm90b3R5cGUuQnJvd3Nlci5PcGVyYSkgewogIEVsZW1lbnQuTWV0aG9kcy5nZXRTdHlsZSA9IEVsZW1lbnQuTWV0aG9kcy5nZXRTdHlsZS53cmFwKAogICAgZnVuY3Rpb24ocHJvY2VlZCwgZWxlbWVudCwgc3R5bGUpIHsKICAgICAgc3dpdGNoIChzdHlsZSkgewogICAgICAgIGNhc2UgJ2hlaWdodCc6IGNhc2UgJ3dpZHRoJzoKICAgICAgICAgIGlmICghRWxlbWVudC52aXNpYmxlKGVsZW1lbnQpKSByZXR1cm4gbnVsbDsKCiAgICAgICAgICB2YXIgZGltID0gcGFyc2VJbnQocHJvY2VlZChlbGVtZW50LCBzdHlsZSksIDEwKTsKCiAgICAgICAgICBpZiAoZGltICE9PSBlbGVtZW50WydvZmZzZXQnICsgc3R5bGUuY2FwaXRhbGl6ZSgpXSkKICAgICAgICAgICAgcmV0dXJuIGRpbSArICdweCc7CgogICAgICAgICAgdmFyIHByb3BlcnRpZXM7CiAgICAgICAgICBpZiAoc3R5bGUgPT09ICdoZWlnaHQnKSB7CiAgICAgICAgICAgIHByb3BlcnRpZXMgPSBbJ2JvcmRlci10b3Atd2lkdGgnLCAncGFkZGluZy10b3AnLAogICAgICAgICAgICAgJ3BhZGRpbmctYm90dG9tJywgJ2JvcmRlci1ib3R0b20td2lkdGgnXTsKICAgICAgICAgIH0KICAgICAgICAgIGVsc2UgewogICAgICAgICAgICBwcm9wZXJ0aWVzID0gWydib3JkZXItbGVmdC13aWR0aCcsICdwYWRkaW5nLWxlZnQnLAogICAgICAgICAgICAgJ3BhZGRpbmctcmlnaHQnLCAnYm9yZGVyLXJpZ2h0LXdpZHRoJ107CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gcHJvcGVydGllcy5pbmplY3QoZGltLCBmdW5jdGlvbihtZW1vLCBwcm9wZXJ0eSkgewogICAgICAgICAgICB2YXIgdmFsID0gcHJvY2VlZChlbGVtZW50LCBwcm9wZXJ0eSk7CiAgICAgICAgICAgIHJldHVybiB2YWwgPT09IG51bGwgPyBtZW1vIDogbWVtbyAtIHBhcnNlSW50KHZhbCwgMTApOwogICAgICAgICAgfSkgKyAncHgnOwogICAgICAgIGRlZmF1bHQ6IHJldHVybiBwcm9jZWVkKGVsZW1lbnQsIHN0eWxlKTsKICAgICAgfQogICAgfQogICk7CgogIEVsZW1lbnQuTWV0aG9kcy5yZWFkQXR0cmlidXRlID0gRWxlbWVudC5NZXRob2RzLnJlYWRBdHRyaWJ1dGUud3JhcCgKICAgIGZ1bmN0aW9uKHByb2NlZWQsIGVsZW1lbnQsIGF0dHJpYnV0ZSkgewogICAgICBpZiAoYXR0cmlidXRlID09PSAndGl0bGUnKSByZXR1cm4gZWxlbWVudC50aXRsZTsKICAgICAgcmV0dXJuIHByb2NlZWQoZWxlbWVudCwgYXR0cmlidXRlKTsKICAgIH0KICApOwp9CgplbHNlIGlmIChQcm90b3R5cGUuQnJvd3Nlci5JRSkgewogIEVsZW1lbnQuTWV0aG9kcy5nZXRTdHlsZSA9IGZ1bmN0aW9uKGVsZW1lbnQsIHN0eWxlKSB7CiAgICBlbGVtZW50ID0gJChlbGVtZW50KTsKICAgIHN0eWxlID0gKHN0eWxlID09ICdmbG9hdCcgfHwgc3R5bGUgPT0gJ2Nzc0Zsb2F0JykgPyAnc3R5bGVGbG9hdCcgOiBzdHlsZS5jYW1lbGl6ZSgpOwogICAgdmFyIHZhbHVlID0gZWxlbWVudC5zdHlsZVtzdHlsZV07CiAgICBpZiAoIXZhbHVlICYmIGVsZW1lbnQuY3VycmVudFN0eWxlKSB2YWx1ZSA9IGVsZW1lbnQuY3VycmVudFN0eWxlW3N0eWxlXTsKCiAgICBpZiAoc3R5bGUgPT0gJ29wYWNpdHknKSB7CiAgICAgIGlmICh2YWx1ZSA9IChlbGVtZW50LmdldFN0eWxlKCdmaWx0ZXInKSB8fCAnJykubWF0Y2goL2FscGhhXChvcGFjaXR5PSguKilcKS8pKQogICAgICAgIGlmICh2YWx1ZVsxXSkgcmV0dXJuIHBhcnNlRmxvYXQodmFsdWVbMV0pIC8gMTAwOwogICAgICByZXR1cm4gMS4wOwogICAgfQoKICAgIGlmICh2YWx1ZSA9PSAnYXV0bycpIHsKICAgICAgaWYgKChzdHlsZSA9PSAnd2lkdGgnIHx8IHN0eWxlID09ICdoZWlnaHQnKSAmJiAoZWxlbWVudC5nZXRTdHlsZSgnZGlzcGxheScpICE9ICdub25lJykpCiAgICAgICAgcmV0dXJuIGVsZW1lbnRbJ29mZnNldCcgKyBzdHlsZS5jYXBpdGFsaXplKCldICsgJ3B4JzsKICAgICAgcmV0dXJuIG51bGw7CiAgICB9CiAgICByZXR1cm4gdmFsdWU7CiAgfTsKCiAgRWxlbWVudC5NZXRob2RzLnNldE9wYWNpdHkgPSBmdW5jdGlvbihlbGVtZW50LCB2YWx1ZSkgewogICAgZnVuY3Rpb24gc3RyaXBBbHBoYShmaWx0ZXIpewogICAgICByZXR1cm4gZmlsdGVyLnJlcGxhY2UoL2FscGhhXChbXlwpXSpcKS9naSwnJyk7CiAgICB9CiAgICBlbGVtZW50ID0gJChlbGVtZW50KTsKICAgIHZhciBjdXJyZW50U3R5bGUgPSBlbGVtZW50LmN1cnJlbnRTdHlsZTsKICAgIGlmICgoY3VycmVudFN0eWxlICYmICFjdXJyZW50U3R5bGUuaGFzTGF5b3V0KSB8fAogICAgICAoIWN1cnJlbnRTdHlsZSAmJiBlbGVtZW50LnN0eWxlLnpvb20gPT0gJ25vcm1hbCcpKQogICAgICAgIGVsZW1lbnQuc3R5bGUuem9vbSA9IDE7CgogICAgdmFyIGZpbHRlciA9IGVsZW1lbnQuZ2V0U3R5bGUoJ2ZpbHRlcicpLCBzdHlsZSA9IGVsZW1lbnQuc3R5bGU7CiAgICBpZiAodmFsdWUgPT0gMSB8fCB2YWx1ZSA9PT0gJycpIHsKICAgICAgKGZpbHRlciA9IHN0cmlwQWxwaGEoZmlsdGVyKSkgPwogICAgICAgIHN0eWxlLmZpbHRlciA9IGZpbHRlciA6IHN0eWxlLnJlbW92ZUF0dHJpYnV0ZSgnZmlsdGVyJyk7CiAgICAgIHJldHVybiBlbGVtZW50OwogICAgfSBlbHNlIGlmICh2YWx1ZSA8IDAuMDAwMDEpIHZhbHVlID0gMDsKICAgIHN0eWxlLmZpbHRlciA9IHN0cmlwQWxwaGEoZmlsdGVyKSArCiAgICAgICdhbHBoYShvcGFjaXR5PScgKyAodmFsdWUgKiAxMDApICsgJyknOwogICAgcmV0dXJuIGVsZW1lbnQ7CiAgfTsKCiAgRWxlbWVudC5fYXR0cmlidXRlVHJhbnNsYXRpb25zID0gKGZ1bmN0aW9uKCl7CgogICAgdmFyIGNsYXNzUHJvcCA9ICdjbGFzc05hbWUnLAogICAgICAgIGZvclByb3AgPSAnZm9yJywKICAgICAgICBlbCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2RpdicpOwoKICAgIGVsLnNldEF0dHJpYnV0ZShjbGFzc1Byb3AsICd4Jyk7CgogICAgaWYgKGVsLmNsYXNzTmFtZSAhPT0gJ3gnKSB7CiAgICAgIGVsLnNldEF0dHJpYnV0ZSgnY2xhc3MnLCAneCcpOwogICAgICBpZiAoZWwuY2xhc3NOYW1lID09PSAneCcpIHsKICAgICAgICBjbGFzc1Byb3AgPSAnY2xhc3MnOwogICAgICB9CiAgICB9CiAgICBlbCA9IG51bGw7CgogICAgZWwgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdsYWJlbCcpOwogICAgZWwuc2V0QXR0cmlidXRlKGZvclByb3AsICd4Jyk7CiAgICBpZiAoZWwuaHRtbEZvciAhPT0gJ3gnKSB7CiAgICAgIGVsLnNldEF0dHJpYnV0ZSgnaHRtbEZvcicsICd4Jyk7CiAgICAgIGlmIChlbC5odG1sRm9yID09PSAneCcpIHsKICAgICAgICBmb3JQcm9wID0gJ2h0bWxGb3InOwogICAgICB9CiAgICB9CiAgICBlbCA9IG51bGw7CgogICAgcmV0dXJuIHsKICAgICAgcmVhZDogewogICAgICAgIG5hbWVzOiB7CiAgICAgICAgICAnY2xhc3MnOiAgICAgIGNsYXNzUHJvcCwKICAgICAgICAgICdjbGFzc05hbWUnOiAgY2xhc3NQcm9wLAogICAgICAgICAgJ2Zvcic6ICAgICAgICBmb3JQcm9wLAogICAgICAgICAgJ2h0bWxGb3InOiAgICBmb3JQcm9wCiAgICAgICAgfSwKICAgICAgICB2YWx1ZXM6IHsKICAgICAgICAgIF9nZXRBdHRyOiBmdW5jdGlvbihlbGVtZW50LCBhdHRyaWJ1dGUpIHsKICAgICAgICAgICAgcmV0dXJuIGVsZW1lbnQuZ2V0QXR0cmlidXRlKGF0dHJpYnV0ZSk7CiAgICAgICAgICB9LAogICAgICAgICAgX2dldEF0dHIyOiBmdW5jdGlvbihlbGVtZW50LCBhdHRyaWJ1dGUpIHsKICAgICAgICAgICAgcmV0dXJuIGVsZW1lbnQuZ2V0QXR0cmlidXRlKGF0dHJpYnV0ZSwgMik7CiAgICAgICAgICB9LAogICAgICAgICAgX2dldEF0dHJOb2RlOiBmdW5jdGlvbihlbGVtZW50LCBhdHRyaWJ1dGUpIHsKICAgICAgICAgICAgdmFyIG5vZGUgPSBlbGVtZW50LmdldEF0dHJpYnV0ZU5vZGUoYXR0cmlidXRlKTsKICAgICAgICAgICAgcmV0dXJuIG5vZGUgPyBub2RlLnZhbHVlIDogIiI7CiAgICAgICAgICB9LAogICAgICAgICAgX2dldEV2OiAoZnVuY3Rpb24oKXsKCiAgICAgICAgICAgIHZhciBlbCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2RpdicpLCBmOwogICAgICAgICAgICBlbC5vbmNsaWNrID0gUHJvdG90eXBlLmVtcHR5RnVuY3Rpb247CiAgICAgICAgICAgIHZhciB2YWx1ZSA9IGVsLmdldEF0dHJpYnV0ZSgnb25jbGljaycpOwoKICAgICAgICAgICAgaWYgKFN0cmluZyh2YWx1ZSkuaW5kZXhPZigneycpID4gLTEpIHsKICAgICAgICAgICAgICBmID0gZnVuY3Rpb24oZWxlbWVudCwgYXR0cmlidXRlKSB7CiAgICAgICAgICAgICAgICBhdHRyaWJ1dGUgPSBlbGVtZW50LmdldEF0dHJpYnV0ZShhdHRyaWJ1dGUpOwogICAgICAgICAgICAgICAgaWYgKCFhdHRyaWJ1dGUpIHJldHVybiBudWxsOwogICAgICAgICAgICAgICAgYXR0cmlidXRlID0gYXR0cmlidXRlLnRvU3RyaW5nKCk7CiAgICAgICAgICAgICAgICBhdHRyaWJ1dGUgPSBhdHRyaWJ1dGUuc3BsaXQoJ3snKVsxXTsKICAgICAgICAgICAgICAgIGF0dHJpYnV0ZSA9IGF0dHJpYnV0ZS5zcGxpdCgnfScpWzBdOwogICAgICAgICAgICAgICAgcmV0dXJuIGF0dHJpYnV0ZS5zdHJpcCgpOwogICAgICAgICAgICAgIH07CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZWxzZSBpZiAodmFsdWUgPT09ICcnKSB7CiAgICAgICAgICAgICAgZiA9IGZ1bmN0aW9uKGVsZW1lbnQsIGF0dHJpYnV0ZSkgewogICAgICAgICAgICAgICAgYXR0cmlidXRlID0gZWxlbWVudC5nZXRBdHRyaWJ1dGUoYXR0cmlidXRlKTsKICAgICAgICAgICAgICAgIGlmICghYXR0cmlidXRlKSByZXR1cm4gbnVsbDsKICAgICAgICAgICAgICAgIHJldHVybiBhdHRyaWJ1dGUuc3RyaXAoKTsKICAgICAgICAgICAgICB9OwogICAgICAgICAgICB9CiAgICAgICAgICAgIGVsID0gbnVsbDsKICAgICAgICAgICAgcmV0dXJuIGY7CiAgICAgICAgICB9KSgpLAogICAgICAgICAgX2ZsYWc6IGZ1bmN0aW9uKGVsZW1lbnQsIGF0dHJpYnV0ZSkgewogICAgICAgICAgICByZXR1cm4gJChlbGVtZW50KS5oYXNBdHRyaWJ1dGUoYXR0cmlidXRlKSA/IGF0dHJpYnV0ZSA6IG51bGw7CiAgICAgICAgICB9LAogICAgICAgICAgc3R5bGU6IGZ1bmN0aW9uKGVsZW1lbnQpIHsKICAgICAgICAgICAgcmV0dXJuIGVsZW1lbnQuc3R5bGUuY3NzVGV4dC50b0xvd2VyQ2FzZSgpOwogICAgICAgICAgfSwKICAgICAgICAgIHRpdGxlOiBmdW5jdGlvbihlbGVtZW50KSB7CiAgICAgICAgICAgIHJldHVybiBlbGVtZW50LnRpdGxlOwogICAgICAgICAgfQogICAgICAgIH0KICAgICAgfQogICAgfQogIH0pKCk7CgogIEVsZW1lbnQuX2F0dHJpYnV0ZVRyYW5zbGF0aW9ucy53cml0ZSA9IHsKICAgIG5hbWVzOiBPYmplY3QuZXh0ZW5kKHsKICAgICAgY2VsbHBhZGRpbmc6ICdjZWxsUGFkZGluZycsCiAgICAgIGNlbGxzcGFjaW5nOiAnY2VsbFNwYWNpbmcnCiAgICB9LCBFbGVtZW50Ll9hdHRyaWJ1dGVUcmFuc2xhdGlvbnMucmVhZC5uYW1lcyksCiAgICB2YWx1ZXM6IHsKICAgICAgY2hlY2tlZDogZnVuY3Rpb24oZWxlbWVudCwgdmFsdWUpIHsKICAgICAgICBlbGVtZW50LmNoZWNrZWQgPSAhIXZhbHVlOwogICAgICB9LAoKICAgICAgc3R5bGU6IGZ1bmN0aW9uKGVsZW1lbnQsIHZhbHVlKSB7CiAgICAgICAgZWxlbWVudC5zdHlsZS5jc3NUZXh0ID0gdmFsdWUgPyB2YWx1ZSA6ICcnOwogICAgICB9CiAgICB9CiAgfTsKCiAgRWxlbWVudC5fYXR0cmlidXRlVHJhbnNsYXRpb25zLmhhcyA9IHt9OwoKICAkdygnY29sU3BhbiByb3dTcGFuIHZBbGlnbiBkYXRlVGltZSBhY2Nlc3NLZXkgdGFiSW5kZXggJyArCiAgICAgICdlbmNUeXBlIG1heExlbmd0aCByZWFkT25seSBsb25nRGVzYyBmcmFtZUJvcmRlcicpLmVhY2goZnVuY3Rpb24oYXR0cikgewogICAgRWxlbWVudC5fYXR0cmlidXRlVHJhbnNsYXRpb25zLndyaXRlLm5hbWVzW2F0dHIudG9Mb3dlckNhc2UoKV0gPSBhdHRyOwogICAgRWxlbWVudC5fYXR0cmlidXRlVHJhbnNsYXRpb25zLmhhc1thdHRyLnRvTG93ZXJDYXNlKCldID0gYXR0cjsKICB9KTsKCiAgKGZ1bmN0aW9uKHYpIHsKICAgIE9iamVjdC5leHRlbmQodiwgewogICAgICBocmVmOiAgICAgICAgdi5fZ2V0QXR0cjIsCiAgICAgIHNyYzogICAgICAgICB2Ll9nZXRBdHRyMiwKICAgICAgdHlwZTogICAgICAgIHYuX2dldEF0dHIsCiAgICAgIGFjdGlvbjogICAgICB2Ll9nZXRBdHRyTm9kZSwKICAgICAgZGlzYWJsZWQ6ICAgIHYuX2ZsYWcsCiAgICAgIGNoZWNrZWQ6ICAgICB2Ll9mbGFnLAogICAgICByZWFkb25seTogICAgdi5fZmxhZywKICAgICAgbXVsdGlwbGU6ICAgIHYuX2ZsYWcsCiAgICAgIG9ubG9hZDogICAgICB2Ll9nZXRFdiwKICAgICAgb251bmxvYWQ6ICAgIHYuX2dldEV2LAogICAgICBvbmNsaWNrOiAgICAgdi5fZ2V0RXYsCiAgICAgIG9uZGJsY2xpY2s6ICB2Ll9nZXRFdiwKICAgICAgb25tb3VzZWRvd246IHYuX2dldEV2LAogICAgICBvbm1vdXNldXA6ICAgdi5fZ2V0RXYsCiAgICAgIG9ubW91c2VvdmVyOiB2Ll9nZXRFdiwKICAgICAgb25tb3VzZW1vdmU6IHYuX2dldEV2LAogICAgICBvbm1vdXNlb3V0OiAgdi5fZ2V0RXYsCiAgICAgIG9uZm9jdXM6ICAgICB2Ll9nZXRFdiwKICAgICAgb25ibHVyOiAgICAgIHYuX2dldEV2LAogICAgICBvbmtleXByZXNzOiAgdi5fZ2V0RXYsCiAgICAgIG9ua2V5ZG93bjogICB2Ll9nZXRFdiwKICAgICAgb25rZXl1cDogICAgIHYuX2dldEV2LAogICAgICBvbnN1Ym1pdDogICAgdi5fZ2V0RXYsCiAgICAgIG9ucmVzZXQ6ICAgICB2Ll9nZXRFdiwKICAgICAgb25zZWxlY3Q6ICAgIHYuX2dldEV2LAogICAgICBvbmNoYW5nZTogICAgdi5fZ2V0RXYKICAgIH0pOwogIH0pKEVsZW1lbnQuX2F0dHJpYnV0ZVRyYW5zbGF0aW9ucy5yZWFkLnZhbHVlcyk7CgogIGlmIChQcm90b3R5cGUuQnJvd3NlckZlYXR1cmVzLkVsZW1lbnRFeHRlbnNpb25zKSB7CiAgICAoZnVuY3Rpb24oKSB7CiAgICAgIGZ1bmN0aW9uIF9kZXNjZW5kYW50cyhlbGVtZW50KSB7CiAgICAgICAgdmFyIG5vZGVzID0gZWxlbWVudC5nZXRFbGVtZW50c0J5VGFnTmFtZSgnKicpLCByZXN1bHRzID0gW107CiAgICAgICAgZm9yICh2YXIgaSA9IDAsIG5vZGU7IG5vZGUgPSBub2Rlc1tpXTsgaSsrKQogICAgICAgICAgaWYgKG5vZGUudGFnTmFtZSAhPT0gIiEiKSAvLyBGaWx0ZXIgb3V0IGNvbW1lbnQgbm9kZXMuCiAgICAgICAgICAgIHJlc3VsdHMucHVzaChub2RlKTsKICAgICAgICByZXR1cm4gcmVzdWx0czsKICAgICAgfQoKICAgICAgRWxlbWVudC5NZXRob2RzLmRvd24gPSBmdW5jdGlvbihlbGVtZW50LCBleHByZXNzaW9uLCBpbmRleCkgewogICAgICAgIGVsZW1lbnQgPSAkKGVsZW1lbnQpOwogICAgICAgIGlmIChhcmd1bWVudHMubGVuZ3RoID09IDEpIHJldHVybiBlbGVtZW50LmZpcnN0RGVzY2VuZGFudCgpOwogICAgICAgIHJldHVybiBPYmplY3QuaXNOdW1iZXIoZXhwcmVzc2lvbikgPyBfZGVzY2VuZGFudHMoZWxlbWVudClbZXhwcmVzc2lvbl0gOgogICAgICAgICAgRWxlbWVudC5zZWxlY3QoZWxlbWVudCwgZXhwcmVzc2lvbilbaW5kZXggfHwgMF07CiAgICAgIH0KICAgIH0pKCk7CiAgfQoKfQoKZWxzZSBpZiAoUHJvdG90eXBlLkJyb3dzZXIuR2Vja28gJiYgL3J2OjFcLjhcLjAvLnRlc3QobmF2aWdhdG9yLnVzZXJBZ2VudCkpIHsKICBFbGVtZW50Lk1ldGhvZHMuc2V0T3BhY2l0eSA9IGZ1bmN0aW9uKGVsZW1lbnQsIHZhbHVlKSB7CiAgICBlbGVtZW50ID0gJChlbGVtZW50KTsKICAgIGVsZW1lbnQuc3R5bGUub3BhY2l0eSA9ICh2YWx1ZSA9PSAxKSA/IDAuOTk5OTk5IDoKICAgICAgKHZhbHVlID09PSAnJykgPyAnJyA6ICh2YWx1ZSA8IDAuMDAwMDEpID8gMCA6IHZhbHVlOwogICAgcmV0dXJuIGVsZW1lbnQ7CiAgfTsKfQoKZWxzZSBpZiAoUHJvdG90eXBlLkJyb3dzZXIuV2ViS2l0KSB7CiAgRWxlbWVudC5NZXRob2RzLnNldE9wYWNpdHkgPSBmdW5jdGlvbihlbGVtZW50LCB2YWx1ZSkgewogICAgZWxlbWVudCA9ICQoZWxlbWVudCk7CiAgICBlbGVtZW50LnN0eWxlLm9wYWNpdHkgPSAodmFsdWUgPT0gMSB8fCB2YWx1ZSA9PT0gJycpID8gJycgOgogICAgICAodmFsdWUgPCAwLjAwMDAxKSA/IDAgOiB2YWx1ZTsKCiAgICBpZiAodmFsdWUgPT0gMSkKICAgICAgaWYgKGVsZW1lbnQudGFnTmFtZS50b1VwcGVyQ2FzZSgpID09ICdJTUcnICYmIGVsZW1lbnQud2lkdGgpIHsKICAgICAgICBlbGVtZW50LndpZHRoKys7IGVsZW1lbnQud2lkdGgtLTsKICAgICAgfSBlbHNlIHRyeSB7CiAgICAgICAgdmFyIG4gPSBkb2N1bWVudC5jcmVhdGVUZXh0Tm9kZSgnICcpOwogICAgICAgIGVsZW1lbnQuYXBwZW5kQ2hpbGQobik7CiAgICAgICAgZWxlbWVudC5yZW1vdmVDaGlsZChuKTsKICAgICAgfSBjYXRjaCAoZSkgeyB9CgogICAgcmV0dXJuIGVsZW1lbnQ7CiAgfTsKfQoKaWYgKCdvdXRlckhUTUwnIGluIGRvY3VtZW50LmRvY3VtZW50RWxlbWVudCkgewogIEVsZW1lbnQuTWV0aG9kcy5yZXBsYWNlID0gZnVuY3Rpb24oZWxlbWVudCwgY29udGVudCkgewogICAgZWxlbWVudCA9ICQoZWxlbWVudCk7CgogICAgaWYgKGNvbnRlbnQgJiYgY29udGVudC50b0VsZW1lbnQpIGNvbnRlbnQgPSBjb250ZW50LnRvRWxlbWVudCgpOwogICAgaWYgKE9iamVjdC5pc0VsZW1lbnQoY29udGVudCkpIHsKICAgICAgZWxlbWVudC5wYXJlbnROb2RlLnJlcGxhY2VDaGlsZChjb250ZW50LCBlbGVtZW50KTsKICAgICAgcmV0dXJuIGVsZW1lbnQ7CiAgICB9CgogICAgY29udGVudCA9IE9iamVjdC50b0hUTUwoY29udGVudCk7CiAgICB2YXIgcGFyZW50ID0gZWxlbWVudC5wYXJlbnROb2RlLCB0YWdOYW1lID0gcGFyZW50LnRhZ05hbWUudG9VcHBlckNhc2UoKTsKCiAgICBpZiAoRWxlbWVudC5faW5zZXJ0aW9uVHJhbnNsYXRpb25zLnRhZ3NbdGFnTmFtZV0pIHsKICAgICAgdmFyIG5leHRTaWJsaW5nID0gZWxlbWVudC5uZXh0KCksCiAgICAgICAgICBmcmFnbWVudHMgPSBFbGVtZW50Ll9nZXRDb250ZW50RnJvbUFub255bW91c0VsZW1lbnQodGFnTmFtZSwgY29udGVudC5zdHJpcFNjcmlwdHMoKSk7CiAgICAgIHBhcmVudC5yZW1vdmVDaGlsZChlbGVtZW50KTsKICAgICAgaWYgKG5leHRTaWJsaW5nKQogICAgICAgIGZyYWdtZW50cy5lYWNoKGZ1bmN0aW9uKG5vZGUpIHsgcGFyZW50Lmluc2VydEJlZm9yZShub2RlLCBuZXh0U2libGluZykgfSk7CiAgICAgIGVsc2UKICAgICAgICBmcmFnbWVudHMuZWFjaChmdW5jdGlvbihub2RlKSB7IHBhcmVudC5hcHBlbmRDaGlsZChub2RlKSB9KTsKICAgIH0KICAgIGVsc2UgZWxlbWVudC5vdXRlckhUTUwgPSBjb250ZW50LnN0cmlwU2NyaXB0cygpOwoKICAgIGNvbnRlbnQuZXZhbFNjcmlwdHMuYmluZChjb250ZW50KS5kZWZlcigpOwogICAgcmV0dXJuIGVsZW1lbnQ7CiAgfTsKfQoKRWxlbWVudC5fcmV0dXJuT2Zmc2V0ID0gZnVuY3Rpb24obCwgdCkgewogIHZhciByZXN1bHQgPSBbbCwgdF07CiAgcmVzdWx0LmxlZnQgPSBsOwogIHJlc3VsdC50b3AgPSB0OwogIHJldHVybiByZXN1bHQ7Cn07CgpFbGVtZW50Ll9nZXRDb250ZW50RnJvbUFub255bW91c0VsZW1lbnQgPSBmdW5jdGlvbih0YWdOYW1lLCBodG1sLCBmb3JjZSkgewogIHZhciBkaXYgPSBuZXcgRWxlbWVudCgnZGl2JyksCiAgICAgIHQgPSBFbGVtZW50Ll9pbnNlcnRpb25UcmFuc2xhdGlvbnMudGFnc1t0YWdOYW1lXTsKCiAgdmFyIHdvcmthcm91bmQgPSBmYWxzZTsKICBpZiAodCkgd29ya2Fyb3VuZCA9IHRydWU7CiAgZWxzZSBpZiAoZm9yY2UpIHsKICAgIHdvcmthcm91bmQgPSB0cnVlOwogICAgdCA9IFsnJywgJycsIDBdOwogIH0KCiAgaWYgKHdvcmthcm91bmQpIHsKICAgIGRpdi5pbm5lckhUTUwgPSAnJm5ic3A7JyArIHRbMF0gKyBodG1sICsgdFsxXTsKICAgIGRpdi5yZW1vdmVDaGlsZChkaXYuZmlyc3RDaGlsZCk7CiAgICBmb3IgKHZhciBpID0gdFsyXTsgaS0tOyApIHsKICAgICAgZGl2ID0gZGl2LmZpcnN0Q2hpbGQ7CiAgICB9CiAgfQogIGVsc2UgewogICAgZGl2LmlubmVySFRNTCA9IGh0bWw7CiAgfQogIHJldHVybiAkQShkaXYuY2hpbGROb2Rlcyk7Cn07CgpFbGVtZW50Ll9pbnNlcnRpb25UcmFuc2xhdGlvbnMgPSB7CiAgYmVmb3JlOiBmdW5jdGlvbihlbGVtZW50LCBub2RlKSB7CiAgICBlbGVtZW50LnBhcmVudE5vZGUuaW5zZXJ0QmVmb3JlKG5vZGUsIGVsZW1lbnQpOwogIH0sCiAgdG9wOiBmdW5jdGlvbihlbGVtZW50LCBub2RlKSB7CiAgICBlbGVtZW50Lmluc2VydEJlZm9yZShub2RlLCBlbGVtZW50LmZpcnN0Q2hpbGQpOwogIH0sCiAgYm90dG9tOiBmdW5jdGlvbihlbGVtZW50LCBub2RlKSB7CiAgICBlbGVtZW50LmFwcGVuZENoaWxkKG5vZGUpOwogIH0sCiAgYWZ0ZXI6IGZ1bmN0aW9uKGVsZW1lbnQsIG5vZGUpIHsKICAgIGVsZW1lbnQucGFyZW50Tm9kZS5pbnNlcnRCZWZvcmUobm9kZSwgZWxlbWVudC5uZXh0U2libGluZyk7CiAgfSwKICB0YWdzOiB7CiAgICBUQUJMRTogIFsnPHRhYmxlPicsICAgICAgICAgICAgICAgICc8L3RhYmxlPicsICAgICAgICAgICAgICAgICAgIDFdLAogICAgVEJPRFk6ICBbJzx0YWJsZT48dGJvZHk+JywgICAgICAgICAnPC90Ym9keT48L3RhYmxlPicsICAgICAgICAgICAyXSwKICAgIFRSOiAgICAgWyc8dGFibGU+PHRib2R5Pjx0cj4nLCAgICAgJzwvdHI+PC90Ym9keT48L3RhYmxlPicsICAgICAgM10sCiAgICBURDogICAgIFsnPHRhYmxlPjx0Ym9keT48dHI+PHRkPicsICc8L3RkPjwvdHI+PC90Ym9keT48L3RhYmxlPicsIDRdLAogICAgU0VMRUNUOiBbJzxzZWxlY3Q+JywgICAgICAgICAgICAgICAnPC9zZWxlY3Q+JywgICAgICAgICAgICAgICAgICAxXQogIH0KfTsKCihmdW5jdGlvbigpIHsKICB2YXIgdGFncyA9IEVsZW1lbnQuX2luc2VydGlvblRyYW5zbGF0aW9ucy50YWdzOwogIE9iamVjdC5leHRlbmQodGFncywgewogICAgVEhFQUQ6IHRhZ3MuVEJPRFksCiAgICBURk9PVDogdGFncy5UQk9EWSwKICAgIFRIOiAgICB0YWdzLlRECiAgfSk7Cn0pKCk7CgpFbGVtZW50Lk1ldGhvZHMuU2ltdWxhdGVkID0gewogIGhhc0F0dHJpYnV0ZTogZnVuY3Rpb24oZWxlbWVudCwgYXR0cmlidXRlKSB7CiAgICBhdHRyaWJ1dGUgPSBFbGVtZW50Ll9hdHRyaWJ1dGVUcmFuc2xhdGlvbnMuaGFzW2F0dHJpYnV0ZV0gfHwgYXR0cmlidXRlOwogICAgdmFyIG5vZGUgPSAkKGVsZW1lbnQpLmdldEF0dHJpYnV0ZU5vZGUoYXR0cmlidXRlKTsKICAgIHJldHVybiAhIShub2RlICYmIG5vZGUuc3BlY2lmaWVkKTsKICB9Cn07CgpFbGVtZW50Lk1ldGhvZHMuQnlUYWcgPSB7IH07CgpPYmplY3QuZXh0ZW5kKEVsZW1lbnQsIEVsZW1lbnQuTWV0aG9kcyk7CgooZnVuY3Rpb24oZGl2KSB7CgogIGlmICghUHJvdG90eXBlLkJyb3dzZXJGZWF0dXJlcy5FbGVtZW50RXh0ZW5zaW9ucyAmJiBkaXZbJ19fcHJvdG9fXyddKSB7CiAgICB3aW5kb3cuSFRNTEVsZW1lbnQgPSB7IH07CiAgICB3aW5kb3cuSFRNTEVsZW1lbnQucHJvdG90eXBlID0gZGl2WydfX3Byb3RvX18nXTsKICAgIFByb3RvdHlwZS5Ccm93c2VyRmVhdHVyZXMuRWxlbWVudEV4dGVuc2lvbnMgPSB0cnVlOwogIH0KCiAgZGl2ID0gbnVsbDsKCn0pKGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2RpdicpKTsKCkVsZW1lbnQuZXh0ZW5kID0gKGZ1bmN0aW9uKCkgewoKICBmdW5jdGlvbiBjaGVja0RlZmljaWVuY3kodGFnTmFtZSkgewogICAgaWYgKHR5cGVvZiB3aW5kb3cuRWxlbWVudCAhPSAndW5kZWZpbmVkJykgewogICAgICB2YXIgcHJvdG8gPSB3aW5kb3cuRWxlbWVudC5wcm90b3R5cGU7CiAgICAgIGlmIChwcm90bykgewogICAgICAgIHZhciBpZCA9ICdfJyArIChNYXRoLnJhbmRvbSgpKycnKS5zbGljZSgyKSwKICAgICAgICAgICAgZWwgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KHRhZ05hbWUpOwogICAgICAgIHByb3RvW2lkXSA9ICd4JzsKICAgICAgICB2YXIgaXNCdWdneSA9IChlbFtpZF0gIT09ICd4Jyk7CiAgICAgICAgZGVsZXRlIHByb3RvW2lkXTsKICAgICAgICBlbCA9IG51bGw7CiAgICAgICAgcmV0dXJuIGlzQnVnZ3k7CiAgICAgIH0KICAgIH0KICAgIHJldHVybiBmYWxzZTsKICB9CgogIGZ1bmN0aW9uIGV4dGVuZEVsZW1lbnRXaXRoKGVsZW1lbnQsIG1ldGhvZHMpIHsKICAgIGZvciAodmFyIHByb3BlcnR5IGluIG1ldGhvZHMpIHsKICAgICAgdmFyIHZhbHVlID0gbWV0aG9kc1twcm9wZXJ0eV07CiAgICAgIGlmIChPYmplY3QuaXNGdW5jdGlvbih2YWx1ZSkgJiYgIShwcm9wZXJ0eSBpbiBlbGVtZW50KSkKICAgICAgICBlbGVtZW50W3Byb3BlcnR5XSA9IHZhbHVlLm1ldGhvZGl6ZSgpOwogICAgfQogIH0KCiAgdmFyIEhUTUxPQkpFQ1RFTEVNRU5UX1BST1RPVFlQRV9CVUdHWSA9IGNoZWNrRGVmaWNpZW5jeSgnb2JqZWN0Jyk7CgogIGlmIChQcm90b3R5cGUuQnJvd3NlckZlYXR1cmVzLlNwZWNpZmljRWxlbWVudEV4dGVuc2lvbnMpIHsKICAgIGlmIChIVE1MT0JKRUNURUxFTUVOVF9QUk9UT1RZUEVfQlVHR1kpIHsKICAgICAgcmV0dXJuIGZ1bmN0aW9uKGVsZW1lbnQpIHsKICAgICAgICBpZiAoZWxlbWVudCAmJiB0eXBlb2YgZWxlbWVudC5fZXh0ZW5kZWRCeVByb3RvdHlwZSA9PSAndW5kZWZpbmVkJykgewogICAgICAgICAgdmFyIHQgPSBlbGVtZW50LnRhZ05hbWU7CiAgICAgICAgICBpZiAodCAmJiAoL14oPzpvYmplY3R8YXBwbGV0fGVtYmVkKSQvaS50ZXN0KHQpKSkgewogICAgICAgICAgICBleHRlbmRFbGVtZW50V2l0aChlbGVtZW50LCBFbGVtZW50Lk1ldGhvZHMpOwogICAgICAgICAgICBleHRlbmRFbGVtZW50V2l0aChlbGVtZW50LCBFbGVtZW50Lk1ldGhvZHMuU2ltdWxhdGVkKTsKICAgICAgICAgICAgZXh0ZW5kRWxlbWVudFdpdGgoZWxlbWVudCwgRWxlbWVudC5NZXRob2RzLkJ5VGFnW3QudG9VcHBlckNhc2UoKV0pOwogICAgICAgICAgfQogICAgICAgIH0KICAgICAgICByZXR1cm4gZWxlbWVudDsKICAgICAgfQogICAgfQogICAgcmV0dXJuIFByb3RvdHlwZS5LOwogIH0KCiAgdmFyIE1ldGhvZHMgPSB7IH0sIEJ5VGFnID0gRWxlbWVudC5NZXRob2RzLkJ5VGFnOwoKICB2YXIgZXh0ZW5kID0gT2JqZWN0LmV4dGVuZChmdW5jdGlvbihlbGVtZW50KSB7CiAgICBpZiAoIWVsZW1lbnQgfHwgdHlwZW9mIGVsZW1lbnQuX2V4dGVuZGVkQnlQcm90b3R5cGUgIT0gJ3VuZGVmaW5lZCcgfHwKICAgICAgICBlbGVtZW50Lm5vZGVUeXBlICE9IDEgfHwgZWxlbWVudCA9PSB3aW5kb3cpIHJldHVybiBlbGVtZW50OwoKICAgIHZhciBtZXRob2RzID0gT2JqZWN0LmNsb25lKE1ldGhvZHMpLAogICAgICAgIHRhZ05hbWUgPSBlbGVtZW50LnRhZ05hbWUudG9VcHBlckNhc2UoKTsKCiAgICBpZiAoQnlUYWdbdGFnTmFtZV0pIE9iamVjdC5leHRlbmQobWV0aG9kcywgQnlUYWdbdGFnTmFtZV0pOwoKICAgIGV4dGVuZEVsZW1lbnRXaXRoKGVsZW1lbnQsIG1ldGhvZHMpOwoKICAgIGVsZW1lbnQuX2V4dGVuZGVkQnlQcm90b3R5cGUgPSBQcm90b3R5cGUuZW1wdHlGdW5jdGlvbjsKICAgIHJldHVybiBlbGVtZW50OwoKICB9LCB7CiAgICByZWZyZXNoOiBmdW5jdGlvbigpIHsKICAgICAgaWYgKCFQcm90b3R5cGUuQnJvd3NlckZlYXR1cmVzLkVsZW1lbnRFeHRlbnNpb25zKSB7CiAgICAgICAgT2JqZWN0LmV4dGVuZChNZXRob2RzLCBFbGVtZW50Lk1ldGhvZHMpOwogICAgICAgIE9iamVjdC5leHRlbmQoTWV0aG9kcywgRWxlbWVudC5NZXRob2RzLlNpbXVsYXRlZCk7CiAgICAgIH0KICAgIH0KICB9KTsKCiAgZXh0ZW5kLnJlZnJlc2goKTsKICByZXR1cm4gZXh0ZW5kOwp9KSgpOwoKaWYgKGRvY3VtZW50LmRvY3VtZW50RWxlbWVudC5oYXNBdHRyaWJ1dGUpIHsKICBFbGVtZW50Lmhhc0F0dHJpYnV0ZSA9IGZ1bmN0aW9uKGVsZW1lbnQsIGF0dHJpYnV0ZSkgewogICAgcmV0dXJuIGVsZW1lbnQuaGFzQXR0cmlidXRlKGF0dHJpYnV0ZSk7CiAgfTsKfQplbHNlIHsKICBFbGVtZW50Lmhhc0F0dHJpYnV0ZSA9IEVsZW1lbnQuTWV0aG9kcy5TaW11bGF0ZWQuaGFzQXR0cmlidXRlOwp9CgpFbGVtZW50LmFkZE1ldGhvZHMgPSBmdW5jdGlvbihtZXRob2RzKSB7CiAgdmFyIEYgPSBQcm90b3R5cGUuQnJvd3NlckZlYXR1cmVzLCBUID0gRWxlbWVudC5NZXRob2RzLkJ5VGFnOwoKICBpZiAoIW1ldGhvZHMpIHsKICAgIE9iamVjdC5leHRlbmQoRm9ybSwgRm9ybS5NZXRob2RzKTsKICAgIE9iamVjdC5leHRlbmQoRm9ybS5FbGVtZW50LCBGb3JtLkVsZW1lbnQuTWV0aG9kcyk7CiAgICBPYmplY3QuZXh0ZW5kKEVsZW1lbnQuTWV0aG9kcy5CeVRhZywgewogICAgICAiRk9STSI6ICAgICBPYmplY3QuY2xvbmUoRm9ybS5NZXRob2RzKSwKICAgICAgIklOUFVUIjogICAgT2JqZWN0LmNsb25lKEZvcm0uRWxlbWVudC5NZXRob2RzKSwKICAgICAgIlNFTEVDVCI6ICAgT2JqZWN0LmNsb25lKEZvcm0uRWxlbWVudC5NZXRob2RzKSwKICAgICAgIlRFWFRBUkVBIjogT2JqZWN0LmNsb25lKEZvcm0uRWxlbWVudC5NZXRob2RzKSwKICAgICAgIkJVVFRPTiI6ICAgT2JqZWN0LmNsb25lKEZvcm0uRWxlbWVudC5NZXRob2RzKQogICAgfSk7CiAgfQoKICBpZiAoYXJndW1lbnRzLmxlbmd0aCA9PSAyKSB7CiAgICB2YXIgdGFnTmFtZSA9IG1ldGhvZHM7CiAgICBtZXRob2RzID0gYXJndW1lbnRzWzFdOwogIH0KCiAgaWYgKCF0YWdOYW1lKSBPYmplY3QuZXh0ZW5kKEVsZW1lbnQuTWV0aG9kcywgbWV0aG9kcyB8fCB7IH0pOwogIGVsc2UgewogICAgaWYgKE9iamVjdC5pc0FycmF5KHRhZ05hbWUpKSB0YWdOYW1lLmVhY2goZXh0ZW5kKTsKICAgIGVsc2UgZXh0ZW5kKHRhZ05hbWUpOwogIH0KCiAgZnVuY3Rpb24gZXh0ZW5kKHRhZ05hbWUpIHsKICAgIHRhZ05hbWUgPSB0YWdOYW1lLnRvVXBwZXJDYXNlKCk7CiAgICBpZiAoIUVsZW1lbnQuTWV0aG9kcy5CeVRhZ1t0YWdOYW1lXSkKICAgICAgRWxlbWVudC5NZXRob2RzLkJ5VGFnW3RhZ05hbWVdID0geyB9OwogICAgT2JqZWN0LmV4dGVuZChFbGVtZW50Lk1ldGhvZHMuQnlUYWdbdGFnTmFtZV0sIG1ldGhvZHMpOwogIH0KCiAgZnVuY3Rpb24gY29weShtZXRob2RzLCBkZXN0aW5hdGlvbiwgb25seUlmQWJzZW50KSB7CiAgICBvbmx5SWZBYnNlbnQgPSBvbmx5SWZBYnNlbnQgfHwgZmFsc2U7CiAgICBmb3IgKHZhciBwcm9wZXJ0eSBpbiBtZXRob2RzKSB7CiAgICAgIHZhciB2YWx1ZSA9IG1ldGhvZHNbcHJvcGVydHldOwogICAgICBpZiAoIU9iamVjdC5pc0Z1bmN0aW9uKHZhbHVlKSkgY29udGludWU7CiAgICAgIGlmICghb25seUlmQWJzZW50IHx8ICEocHJvcGVydHkgaW4gZGVzdGluYXRpb24pKQogICAgICAgIGRlc3RpbmF0aW9uW3Byb3BlcnR5XSA9IHZhbHVlLm1ldGhvZGl6ZSgpOwogICAgfQogIH0KCiAgZnVuY3Rpb24gZmluZERPTUNsYXNzKHRhZ05hbWUpIHsKICAgIHZhciBrbGFzczsKICAgIHZhciB0cmFucyA9IHsKICAgICAgIk9QVEdST1VQIjogIk9wdEdyb3VwIiwgIlRFWFRBUkVBIjogIlRleHRBcmVhIiwgIlAiOiAiUGFyYWdyYXBoIiwKICAgICAgIkZJRUxEU0VUIjogIkZpZWxkU2V0IiwgIlVMIjogIlVMaXN0IiwgIk9MIjogIk9MaXN0IiwgIkRMIjogIkRMaXN0IiwKICAgICAgIkRJUiI6ICJEaXJlY3RvcnkiLCAiSDEiOiAiSGVhZGluZyIsICJIMiI6ICJIZWFkaW5nIiwgIkgzIjogIkhlYWRpbmciLAogICAgICAiSDQiOiAiSGVhZGluZyIsICJINSI6ICJIZWFkaW5nIiwgIkg2IjogIkhlYWRpbmciLCAiUSI6ICJRdW90ZSIsCiAgICAgICJJTlMiOiAiTW9kIiwgIkRFTCI6ICJNb2QiLCAiQSI6ICJBbmNob3IiLCAiSU1HIjogIkltYWdlIiwgIkNBUFRJT04iOgogICAgICAiVGFibGVDYXB0aW9uIiwgIkNPTCI6ICJUYWJsZUNvbCIsICJDT0xHUk9VUCI6ICJUYWJsZUNvbCIsICJUSEVBRCI6CiAgICAgICJUYWJsZVNlY3Rpb24iLCAiVEZPT1QiOiAiVGFibGVTZWN0aW9uIiwgIlRCT0RZIjogIlRhYmxlU2VjdGlvbiIsICJUUiI6CiAgICAgICJUYWJsZVJvdyIsICJUSCI6ICJUYWJsZUNlbGwiLCAiVEQiOiAiVGFibGVDZWxsIiwgIkZSQU1FU0VUIjoKICAgICAgIkZyYW1lU2V0IiwgIklGUkFNRSI6ICJJRnJhbWUiCiAgICB9OwogICAgaWYgKHRyYW5zW3RhZ05hbWVdKSBrbGFzcyA9ICdIVE1MJyArIHRyYW5zW3RhZ05hbWVdICsgJ0VsZW1lbnQnOwogICAgaWYgKHdpbmRvd1trbGFzc10pIHJldHVybiB3aW5kb3dba2xhc3NdOwogICAga2xhc3MgPSAnSFRNTCcgKyB0YWdOYW1lICsgJ0VsZW1lbnQnOwogICAgaWYgKHdpbmRvd1trbGFzc10pIHJldHVybiB3aW5kb3dba2xhc3NdOwogICAga2xhc3MgPSAnSFRNTCcgKyB0YWdOYW1lLmNhcGl0YWxpemUoKSArICdFbGVtZW50JzsKICAgIGlmICh3aW5kb3dba2xhc3NdKSByZXR1cm4gd2luZG93W2tsYXNzXTsKCiAgICB2YXIgZWxlbWVudCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQodGFnTmFtZSksCiAgICAgICAgcHJvdG8gPSBlbGVtZW50WydfX3Byb3RvX18nXSB8fCBlbGVtZW50LmNvbnN0cnVjdG9yLnByb3RvdHlwZTsKCiAgICBlbGVtZW50ID0gbnVsbDsKICAgIHJldHVybiBwcm90bzsKICB9CgogIHZhciBlbGVtZW50UHJvdG90eXBlID0gd2luZG93LkhUTUxFbGVtZW50ID8gSFRNTEVsZW1lbnQucHJvdG90eXBlIDoKICAgRWxlbWVudC5wcm90b3R5cGU7CgogIGlmIChGLkVsZW1lbnRFeHRlbnNpb25zKSB7CiAgICBjb3B5KEVsZW1lbnQuTWV0aG9kcywgZWxlbWVudFByb3RvdHlwZSk7CiAgICBjb3B5KEVsZW1lbnQuTWV0aG9kcy5TaW11bGF0ZWQsIGVsZW1lbnRQcm90b3R5cGUsIHRydWUpOwogIH0KCiAgaWYgKEYuU3BlY2lmaWNFbGVtZW50RXh0ZW5zaW9ucykgewogICAgZm9yICh2YXIgdGFnIGluIEVsZW1lbnQuTWV0aG9kcy5CeVRhZykgewogICAgICB2YXIga2xhc3MgPSBmaW5kRE9NQ2xhc3ModGFnKTsKICAgICAgaWYgKE9iamVjdC5pc1VuZGVmaW5lZChrbGFzcykpIGNvbnRpbnVlOwogICAgICBjb3B5KFRbdGFnXSwga2xhc3MucHJvdG90eXBlKTsKICAgIH0KICB9CgogIE9iamVjdC5leHRlbmQoRWxlbWVudCwgRWxlbWVudC5NZXRob2RzKTsKICBkZWxldGUgRWxlbWVudC5CeVRhZzsKCiAgaWYgKEVsZW1lbnQuZXh0ZW5kLnJlZnJlc2gpIEVsZW1lbnQuZXh0ZW5kLnJlZnJlc2goKTsKICBFbGVtZW50LmNhY2hlID0geyB9Owp9OwoKCmRvY3VtZW50LnZpZXdwb3J0ID0gewoKICBnZXREaW1lbnNpb25zOiBmdW5jdGlvbigpIHsKICAgIHJldHVybiB7IHdpZHRoOiB0aGlzLmdldFdpZHRoKCksIGhlaWdodDogdGhpcy5nZXRIZWlnaHQoKSB9OwogIH0sCgogIGdldFNjcm9sbE9mZnNldHM6IGZ1bmN0aW9uKCkgewogICAgcmV0dXJuIEVsZW1lbnQuX3JldHVybk9mZnNldCgKICAgICAgd2luZG93LnBhZ2VYT2Zmc2V0IHx8IGRvY3VtZW50LmRvY3VtZW50RWxlbWVudC5zY3JvbGxMZWZ0IHx8IGRvY3VtZW50LmJvZHkuc2Nyb2xsTGVmdCwKICAgICAgd2luZG93LnBhZ2VZT2Zmc2V0IHx8IGRvY3VtZW50LmRvY3VtZW50RWxlbWVudC5zY3JvbGxUb3AgIHx8IGRvY3VtZW50LmJvZHkuc2Nyb2xsVG9wKTsKICB9Cn07CgooZnVuY3Rpb24odmlld3BvcnQpIHsKICB2YXIgQiA9IFByb3RvdHlwZS5Ccm93c2VyLCBkb2MgPSBkb2N1bWVudCwgZWxlbWVudCwgcHJvcGVydHkgPSB7fTsKCiAgZnVuY3Rpb24gZ2V0Um9vdEVsZW1lbnQoKSB7CiAgICBpZiAoQi5XZWJLaXQgJiYgIWRvYy5ldmFsdWF0ZSkKICAgICAgcmV0dXJuIGRvY3VtZW50OwoKICAgIGlmIChCLk9wZXJhICYmIHdpbmRvdy5wYXJzZUZsb2F0KHdpbmRvdy5vcGVyYS52ZXJzaW9uKCkpIDwgOS41KQogICAgICByZXR1cm4gZG9jdW1lbnQuYm9keTsKCiAgICByZXR1cm4gZG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50OwogIH0KCiAgZnVuY3Rpb24gZGVmaW5lKEQpIHsKICAgIGlmICghZWxlbWVudCkgZWxlbWVudCA9IGdldFJvb3RFbGVtZW50KCk7CgogICAgcHJvcGVydHlbRF0gPSAnY2xpZW50JyArIEQ7CgogICAgdmlld3BvcnRbJ2dldCcgKyBEXSA9IGZ1bmN0aW9uKCkgeyByZXR1cm4gZWxlbWVudFtwcm9wZXJ0eVtEXV0gfTsKICAgIHJldHVybiB2aWV3cG9ydFsnZ2V0JyArIERdKCk7CiAgfQoKICB2aWV3cG9ydC5nZXRXaWR0aCAgPSBkZWZpbmUuY3VycnkoJ1dpZHRoJyk7CgogIHZpZXdwb3J0LmdldEhlaWdodCA9IGRlZmluZS5jdXJyeSgnSGVpZ2h0Jyk7Cn0pKGRvY3VtZW50LnZpZXdwb3J0KTsKCgpFbGVtZW50LlN0b3JhZ2UgPSB7CiAgVUlEOiAxCn07CgpFbGVtZW50LmFkZE1ldGhvZHMoewogIGdldFN0b3JhZ2U6IGZ1bmN0aW9uKGVsZW1lbnQpIHsKICAgIGlmICghKGVsZW1lbnQgPSAkKGVsZW1lbnQpKSkgcmV0dXJuOwoKICAgIHZhciB1aWQ7CiAgICBpZiAoZWxlbWVudCA9PT0gd2luZG93KSB7CiAgICAgIHVpZCA9IDA7CiAgICB9IGVsc2UgewogICAgICBpZiAodHlwZW9mIGVsZW1lbnQuX3Byb3RvdHlwZVVJRCA9PT0gInVuZGVmaW5lZCIpCiAgICAgICAgZWxlbWVudC5fcHJvdG90eXBlVUlEID0gRWxlbWVudC5TdG9yYWdlLlVJRCsrOwogICAgICB1aWQgPSBlbGVtZW50Ll9wcm90b3R5cGVVSUQ7CiAgICB9CgogICAgaWYgKCFFbGVtZW50LlN0b3JhZ2VbdWlkXSkKICAgICAgRWxlbWVudC5TdG9yYWdlW3VpZF0gPSAkSCgpOwoKICAgIHJldHVybiBFbGVtZW50LlN0b3JhZ2VbdWlkXTsKICB9LAoKICBzdG9yZTogZnVuY3Rpb24oZWxlbWVudCwga2V5LCB2YWx1ZSkgewogICAgaWYgKCEoZWxlbWVudCA9ICQoZWxlbWVudCkpKSByZXR1cm47CgogICAgaWYgKGFyZ3VtZW50cy5sZW5ndGggPT09IDIpIHsKICAgICAgRWxlbWVudC5nZXRTdG9yYWdlKGVsZW1lbnQpLnVwZGF0ZShrZXkpOwogICAgfSBlbHNlIHsKICAgICAgRWxlbWVudC5nZXRTdG9yYWdlKGVsZW1lbnQpLnNldChrZXksIHZhbHVlKTsKICAgIH0KCiAgICByZXR1cm4gZWxlbWVudDsKICB9LAoKICByZXRyaWV2ZTogZnVuY3Rpb24oZWxlbWVudCwga2V5LCBkZWZhdWx0VmFsdWUpIHsKICAgIGlmICghKGVsZW1lbnQgPSAkKGVsZW1lbnQpKSkgcmV0dXJuOwogICAgdmFyIGhhc2ggPSBFbGVtZW50LmdldFN0b3JhZ2UoZWxlbWVudCksIHZhbHVlID0gaGFzaC5nZXQoa2V5KTsKCiAgICBpZiAoT2JqZWN0LmlzVW5kZWZpbmVkKHZhbHVlKSkgewogICAgICBoYXNoLnNldChrZXksIGRlZmF1bHRWYWx1ZSk7CiAgICAgIHZhbHVlID0gZGVmYXVsdFZhbHVlOwogICAgfQoKICAgIHJldHVybiB2YWx1ZTsKICB9LAoKICBjbG9uZTogZnVuY3Rpb24oZWxlbWVudCwgZGVlcCkgewogICAgaWYgKCEoZWxlbWVudCA9ICQoZWxlbWVudCkpKSByZXR1cm47CiAgICB2YXIgY2xvbmUgPSBlbGVtZW50LmNsb25lTm9kZShkZWVwKTsKICAgIGNsb25lLl9wcm90b3R5cGVVSUQgPSB2b2lkIDA7CiAgICBpZiAoZGVlcCkgewogICAgICB2YXIgZGVzY2VuZGFudHMgPSBFbGVtZW50LnNlbGVjdChjbG9uZSwgJyonKSwKICAgICAgICAgIGkgPSBkZXNjZW5kYW50cy5sZW5ndGg7CiAgICAgIHdoaWxlIChpLS0pIHsKICAgICAgICBkZXNjZW5kYW50c1tpXS5fcHJvdG90eXBlVUlEID0gdm9pZCAwOwogICAgICB9CiAgICB9CiAgICByZXR1cm4gRWxlbWVudC5leHRlbmQoY2xvbmUpOwogIH0sCgogIHB1cmdlOiBmdW5jdGlvbihlbGVtZW50KSB7CiAgICBpZiAoIShlbGVtZW50ID0gJChlbGVtZW50KSkpIHJldHVybjsKICAgIHZhciBwdXJnZUVsZW1lbnQgPSBFbGVtZW50Ll9wdXJnZUVsZW1lbnQ7CgogICAgcHVyZ2VFbGVtZW50KGVsZW1lbnQpOwoKICAgIHZhciBkZXNjZW5kYW50cyA9IGVsZW1lbnQuZ2V0RWxlbWVudHNCeVRhZ05hbWUoJyonKSwKICAgICBpID0gZGVzY2VuZGFudHMubGVuZ3RoOwoKICAgIHdoaWxlIChpLS0pIHB1cmdlRWxlbWVudChkZXNjZW5kYW50c1tpXSk7CgogICAgcmV0dXJuIG51bGw7CiAgfQp9KTsKCihmdW5jdGlvbigpIHsKCiAgZnVuY3Rpb24gdG9EZWNpbWFsKHBjdFN0cmluZykgewogICAgdmFyIG1hdGNoID0gcGN0U3RyaW5nLm1hdGNoKC9eKFxkKyklPyQvaSk7CiAgICBpZiAoIW1hdGNoKSByZXR1cm4gbnVsbDsKICAgIHJldHVybiAoTnVtYmVyKG1hdGNoWzFdKSAvIDEwMCk7CiAgfQoKICBmdW5jdGlvbiBnZXRQaXhlbFZhbHVlKHZhbHVlLCBwcm9wZXJ0eSwgY29udGV4dCkgewogICAgdmFyIGVsZW1lbnQgPSBudWxsOwogICAgaWYgKE9iamVjdC5pc0VsZW1lbnQodmFsdWUpKSB7CiAgICAgIGVsZW1lbnQgPSB2YWx1ZTsKICAgICAgdmFsdWUgPSBlbGVtZW50LmdldFN0eWxlKHByb3BlcnR5KTsKICAgIH0KCiAgICBpZiAodmFsdWUgPT09IG51bGwpIHsKICAgICAgcmV0dXJuIG51bGw7CiAgICB9CgogICAgaWYgKCgvXig/Oi0pP1xkKyhcLlxkKyk/KHB4KT8kL2kpLnRlc3QodmFsdWUpKSB7CiAgICAgIHJldHVybiB3aW5kb3cucGFyc2VGbG9hdCh2YWx1ZSk7CiAgICB9CgogICAgdmFyIGlzUGVyY2VudGFnZSA9IHZhbHVlLmluY2x1ZGUoJyUnKSwgaXNWaWV3cG9ydCA9IChjb250ZXh0ID09PSBkb2N1bWVudC52aWV3cG9ydCk7CgogICAgaWYgKC9cZC8udGVzdCh2YWx1ZSkgJiYgZWxlbWVudCAmJiBlbGVtZW50LnJ1bnRpbWVTdHlsZSAmJiAhKGlzUGVyY2VudGFnZSAmJiBpc1ZpZXdwb3J0KSkgewogICAgICB2YXIgc3R5bGUgPSBlbGVtZW50LnN0eWxlLmxlZnQsIHJTdHlsZSA9IGVsZW1lbnQucnVudGltZVN0eWxlLmxlZnQ7CiAgICAgIGVsZW1lbnQucnVudGltZVN0eWxlLmxlZnQgPSBlbGVtZW50LmN1cnJlbnRTdHlsZS5sZWZ0OwogICAgICBlbGVtZW50LnN0eWxlLmxlZnQgPSB2YWx1ZSB8fCAwOwogICAgICB2YWx1ZSA9IGVsZW1lbnQuc3R5bGUucGl4ZWxMZWZ0OwogICAgICBlbGVtZW50LnN0eWxlLmxlZnQgPSBzdHlsZTsKICAgICAgZWxlbWVudC5ydW50aW1lU3R5bGUubGVmdCA9IHJTdHlsZTsKCiAgICAgIHJldHVybiB2YWx1ZTsKICAgIH0KCiAgICBpZiAoZWxlbWVudCAmJiBpc1BlcmNlbnRhZ2UpIHsKICAgICAgY29udGV4dCA9IGNvbnRleHQgfHwgZWxlbWVudC5wYXJlbnROb2RlOwogICAgICB2YXIgZGVjaW1hbCA9IHRvRGVjaW1hbCh2YWx1ZSk7CiAgICAgIHZhciB3aG9sZSA9IG51bGw7CiAgICAgIHZhciBwb3NpdGlvbiA9IGVsZW1lbnQuZ2V0U3R5bGUoJ3Bvc2l0aW9uJyk7CgogICAgICB2YXIgaXNIb3Jpem9udGFsID0gcHJvcGVydHkuaW5jbHVkZSgnbGVmdCcpIHx8IHByb3BlcnR5LmluY2x1ZGUoJ3JpZ2h0JykgfHwKICAgICAgIHByb3BlcnR5LmluY2x1ZGUoJ3dpZHRoJyk7CgogICAgICB2YXIgaXNWZXJ0aWNhbCA9ICBwcm9wZXJ0eS5pbmNsdWRlKCd0b3AnKSB8fCBwcm9wZXJ0eS5pbmNsdWRlKCdib3R0b20nKSB8fAogICAgICAgIHByb3BlcnR5LmluY2x1ZGUoJ2hlaWdodCcpOwoKICAgICAgaWYgKGNvbnRleHQgPT09IGRvY3VtZW50LnZpZXdwb3J0KSB7CiAgICAgICAgaWYgKGlzSG9yaXpvbnRhbCkgewogICAgICAgICAgd2hvbGUgPSBkb2N1bWVudC52aWV3cG9ydC5nZXRXaWR0aCgpOwogICAgICAgIH0gZWxzZSBpZiAoaXNWZXJ0aWNhbCkgewogICAgICAgICAgd2hvbGUgPSBkb2N1bWVudC52aWV3cG9ydC5nZXRIZWlnaHQoKTsKICAgICAgICB9CiAgICAgIH0gZWxzZSB7CiAgICAgICAgaWYgKGlzSG9yaXpvbnRhbCkgewogICAgICAgICAgd2hvbGUgPSAkKGNvbnRleHQpLm1lYXN1cmUoJ3dpZHRoJyk7CiAgICAgICAgfSBlbHNlIGlmIChpc1ZlcnRpY2FsKSB7CiAgICAgICAgICB3aG9sZSA9ICQoY29udGV4dCkubWVhc3VyZSgnaGVpZ2h0Jyk7CiAgICAgICAgfQogICAgICB9CgogICAgICByZXR1cm4gKHdob2xlID09PSBudWxsKSA/IDAgOiB3aG9sZSAqIGRlY2ltYWw7CiAgICB9CgogICAgcmV0dXJuIDA7CiAgfQoKICBmdW5jdGlvbiB0b0NTU1BpeGVscyhudW1iZXIpIHsKICAgIGlmIChPYmplY3QuaXNTdHJpbmcobnVtYmVyKSAmJiBudW1iZXIuZW5kc1dpdGgoJ3B4JykpIHsKICAgICAgcmV0dXJuIG51bWJlcjsKICAgIH0KICAgIHJldHVybiBudW1iZXIgKyAncHgnOwogIH0KCiAgZnVuY3Rpb24gaXNEaXNwbGF5ZWQoZWxlbWVudCkgewogICAgdmFyIG9yaWdpbmFsRWxlbWVudCA9IGVsZW1lbnQ7CiAgICB3aGlsZSAoZWxlbWVudCAmJiBlbGVtZW50LnBhcmVudE5vZGUpIHsKICAgICAgdmFyIGRpc3BsYXkgPSBlbGVtZW50LmdldFN0eWxlKCdkaXNwbGF5Jyk7CiAgICAgIGlmIChkaXNwbGF5ID09PSAnbm9uZScpIHsKICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgIH0KICAgICAgZWxlbWVudCA9ICQoZWxlbWVudC5wYXJlbnROb2RlKTsKICAgIH0KICAgIHJldHVybiB0cnVlOwogIH0KCiAgdmFyIGhhc0xheW91dCA9IFByb3RvdHlwZS5LOwogIGlmICgnY3VycmVudFN0eWxlJyBpbiBkb2N1bWVudC5kb2N1bWVudEVsZW1lbnQpIHsKICAgIGhhc0xheW91dCA9IGZ1bmN0aW9uKGVsZW1lbnQpIHsKICAgICAgaWYgKCFlbGVtZW50LmN1cnJlbnRTdHlsZS5oYXNMYXlvdXQpIHsKICAgICAgICBlbGVtZW50LnN0eWxlLnpvb20gPSAxOwogICAgICB9CiAgICAgIHJldHVybiBlbGVtZW50OwogICAgfTsKICB9CgogIGZ1bmN0aW9uIGNzc05hbWVGb3Ioa2V5KSB7CiAgICBpZiAoa2V5LmluY2x1ZGUoJ2JvcmRlcicpKSBrZXkgPSBrZXkgKyAnLXdpZHRoJzsKICAgIHJldHVybiBrZXkuY2FtZWxpemUoKTsKICB9CgogIEVsZW1lbnQuTGF5b3V0ID0gQ2xhc3MuY3JlYXRlKEhhc2gsIHsKICAgIGluaXRpYWxpemU6IGZ1bmN0aW9uKCRzdXBlciwgZWxlbWVudCwgcHJlQ29tcHV0ZSkgewogICAgICAkc3VwZXIoKTsKICAgICAgdGhpcy5lbGVtZW50ID0gJChlbGVtZW50KTsKCiAgICAgIEVsZW1lbnQuTGF5b3V0LlBST1BFUlRJRVMuZWFjaCggZnVuY3Rpb24ocHJvcGVydHkpIHsKICAgICAgICB0aGlzLl9zZXQocHJvcGVydHksIG51bGwpOwogICAgICB9LCB0aGlzKTsKCiAgICAgIGlmIChwcmVDb21wdXRlKSB7CiAgICAgICAgdGhpcy5fcHJlQ29tcHV0aW5nID0gdHJ1ZTsKICAgICAgICB0aGlzLl9iZWdpbigpOwogICAgICAgIEVsZW1lbnQuTGF5b3V0LlBST1BFUlRJRVMuZWFjaCggdGhpcy5fY29tcHV0ZSwgdGhpcyApOwogICAgICAgIHRoaXMuX2VuZCgpOwogICAgICAgIHRoaXMuX3ByZUNvbXB1dGluZyA9IGZhbHNlOwogICAgICB9CiAgICB9LAoKICAgIF9zZXQ6IGZ1bmN0aW9uKHByb3BlcnR5LCB2YWx1ZSkgewogICAgICByZXR1cm4gSGFzaC5wcm90b3R5cGUuc2V0LmNhbGwodGhpcywgcHJvcGVydHksIHZhbHVlKTsKICAgIH0sCgogICAgc2V0OiBmdW5jdGlvbihwcm9wZXJ0eSwgdmFsdWUpIHsKICAgICAgdGhyb3cgIlByb3BlcnRpZXMgb2YgRWxlbWVudC5MYXlvdXQgYXJlIHJlYWQtb25seS4iOwogICAgfSwKCiAgICBnZXQ6IGZ1bmN0aW9uKCRzdXBlciwgcHJvcGVydHkpIHsKICAgICAgdmFyIHZhbHVlID0gJHN1cGVyKHByb3BlcnR5KTsKICAgICAgcmV0dXJuIHZhbHVlID09PSBudWxsID8gdGhpcy5fY29tcHV0ZShwcm9wZXJ0eSkgOiB2YWx1ZTsKICAgIH0sCgogICAgX2JlZ2luOiBmdW5jdGlvbigpIHsKICAgICAgaWYgKHRoaXMuX3ByZXBhcmVkKSByZXR1cm47CgogICAgICB2YXIgZWxlbWVudCA9IHRoaXMuZWxlbWVudDsKICAgICAgaWYgKGlzRGlzcGxheWVkKGVsZW1lbnQpKSB7CiAgICAgICAgdGhpcy5fcHJlcGFyZWQgPSB0cnVlOwogICAgICAgIHJldHVybjsKICAgICAgfQoKICAgICAgdmFyIG9yaWdpbmFsU3R5bGVzID0gewogICAgICAgIHBvc2l0aW9uOiAgIGVsZW1lbnQuc3R5bGUucG9zaXRpb24gICB8fCAnJywKICAgICAgICB3aWR0aDogICAgICBlbGVtZW50LnN0eWxlLndpZHRoICAgICAgfHwgJycsCiAgICAgICAgdmlzaWJpbGl0eTogZWxlbWVudC5zdHlsZS52aXNpYmlsaXR5IHx8ICcnLAogICAgICAgIGRpc3BsYXk6ICAgIGVsZW1lbnQuc3R5bGUuZGlzcGxheSAgICB8fCAnJwogICAgICB9OwoKICAgICAgZWxlbWVudC5zdG9yZSgncHJvdG90eXBlX29yaWdpbmFsX3N0eWxlcycsIG9yaWdpbmFsU3R5bGVzKTsKCiAgICAgIHZhciBwb3NpdGlvbiA9IGVsZW1lbnQuZ2V0U3R5bGUoJ3Bvc2l0aW9uJyksCiAgICAgICB3aWR0aCA9IGVsZW1lbnQuZ2V0U3R5bGUoJ3dpZHRoJyk7CgogICAgICBpZiAod2lkdGggPT09ICIwcHgiIHx8IHdpZHRoID09PSBudWxsKSB7CiAgICAgICAgZWxlbWVudC5zdHlsZS5kaXNwbGF5ID0gJ2Jsb2NrJzsKICAgICAgICB3aWR0aCA9IGVsZW1lbnQuZ2V0U3R5bGUoJ3dpZHRoJyk7CiAgICAgIH0KCiAgICAgIHZhciBjb250ZXh0ID0gKHBvc2l0aW9uID09PSAnZml4ZWQnKSA/IGRvY3VtZW50LnZpZXdwb3J0IDoKICAgICAgIGVsZW1lbnQucGFyZW50Tm9kZTsKCiAgICAgIGVsZW1lbnQuc2V0U3R5bGUoewogICAgICAgIHBvc2l0aW9uOiAgICdhYnNvbHV0ZScsCiAgICAgICAgdmlzaWJpbGl0eTogJ2hpZGRlbicsCiAgICAgICAgZGlzcGxheTogICAgJ2Jsb2NrJwogICAgICB9KTsKCiAgICAgIHZhciBwb3NpdGlvbmVkV2lkdGggPSBlbGVtZW50LmdldFN0eWxlKCd3aWR0aCcpOwoKICAgICAgdmFyIG5ld1dpZHRoOwogICAgICBpZiAod2lkdGggJiYgKHBvc2l0aW9uZWRXaWR0aCA9PT0gd2lkdGgpKSB7CiAgICAgICAgbmV3V2lkdGggPSBnZXRQaXhlbFZhbHVlKGVsZW1lbnQsICd3aWR0aCcsIGNvbnRleHQpOwogICAgICB9IGVsc2UgaWYgKHBvc2l0aW9uID09PSAnYWJzb2x1dGUnIHx8IHBvc2l0aW9uID09PSAnZml4ZWQnKSB7CiAgICAgICAgbmV3V2lkdGggPSBnZXRQaXhlbFZhbHVlKGVsZW1lbnQsICd3aWR0aCcsIGNvbnRleHQpOwogICAgICB9IGVsc2UgewogICAgICAgIHZhciBwYXJlbnQgPSBlbGVtZW50LnBhcmVudE5vZGUsIHBMYXlvdXQgPSAkKHBhcmVudCkuZ2V0TGF5b3V0KCk7CgogICAgICAgIG5ld1dpZHRoID0gcExheW91dC5nZXQoJ3dpZHRoJykgLQogICAgICAgICB0aGlzLmdldCgnbWFyZ2luLWxlZnQnKSAtCiAgICAgICAgIHRoaXMuZ2V0KCdib3JkZXItbGVmdCcpIC0KICAgICAgICAgdGhpcy5nZXQoJ3BhZGRpbmctbGVmdCcpIC0KICAgICAgICAgdGhpcy5nZXQoJ3BhZGRpbmctcmlnaHQnKSAtCiAgICAgICAgIHRoaXMuZ2V0KCdib3JkZXItcmlnaHQnKSAtCiAgICAgICAgIHRoaXMuZ2V0KCdtYXJnaW4tcmlnaHQnKTsKICAgICAgfQoKICAgICAgZWxlbWVudC5zZXRTdHlsZSh7IHdpZHRoOiBuZXdXaWR0aCArICdweCcgfSk7CgogICAgICB0aGlzLl9wcmVwYXJlZCA9IHRydWU7CiAgICB9LAoKICAgIF9lbmQ6IGZ1bmN0aW9uKCkgewogICAgICB2YXIgZWxlbWVudCA9IHRoaXMuZWxlbWVudDsKICAgICAgdmFyIG9yaWdpbmFsU3R5bGVzID0gZWxlbWVudC5yZXRyaWV2ZSgncHJvdG90eXBlX29yaWdpbmFsX3N0eWxlcycpOwogICAgICBlbGVtZW50LnN0b3JlKCdwcm90b3R5cGVfb3JpZ2luYWxfc3R5bGVzJywgbnVsbCk7CiAgICAgIGVsZW1lbnQuc2V0U3R5bGUob3JpZ2luYWxTdHlsZXMpOwogICAgICB0aGlzLl9wcmVwYXJlZCA9IGZhbHNlOwogICAgfSwKCiAgICBfY29tcHV0ZTogZnVuY3Rpb24ocHJvcGVydHkpIHsKICAgICAgdmFyIENPTVBVVEFUSU9OUyA9IEVsZW1lbnQuTGF5b3V0LkNPTVBVVEFUSU9OUzsKICAgICAgaWYgKCEocHJvcGVydHkgaW4gQ09NUFVUQVRJT05TKSkgewogICAgICAgIHRocm93ICJQcm9wZXJ0eSBub3QgZm91bmQuIjsKICAgICAgfQoKICAgICAgcmV0dXJuIHRoaXMuX3NldChwcm9wZXJ0eSwgQ09NUFVUQVRJT05TW3Byb3BlcnR5XS5jYWxsKHRoaXMsIHRoaXMuZWxlbWVudCkpOwogICAgfSwKCiAgICB0b09iamVjdDogZnVuY3Rpb24oKSB7CiAgICAgIHZhciBhcmdzID0gJEEoYXJndW1lbnRzKTsKICAgICAgdmFyIGtleXMgPSAoYXJncy5sZW5ndGggPT09IDApID8gRWxlbWVudC5MYXlvdXQuUFJPUEVSVElFUyA6CiAgICAgICBhcmdzLmpvaW4oJyAnKS5zcGxpdCgnICcpOwogICAgICB2YXIgb2JqID0ge307CiAgICAgIGtleXMuZWFjaCggZnVuY3Rpb24oa2V5KSB7CiAgICAgICAgaWYgKCFFbGVtZW50LkxheW91dC5QUk9QRVJUSUVTLmluY2x1ZGUoa2V5KSkgcmV0dXJuOwogICAgICAgIHZhciB2YWx1ZSA9IHRoaXMuZ2V0KGtleSk7CiAgICAgICAgaWYgKHZhbHVlICE9IG51bGwpIG9ialtrZXldID0gdmFsdWU7CiAgICAgIH0sIHRoaXMpOwogICAgICByZXR1cm4gb2JqOwogICAgfSwKCiAgICB0b0hhc2g6IGZ1bmN0aW9uKCkgewogICAgICB2YXIgb2JqID0gdGhpcy50b09iamVjdC5hcHBseSh0aGlzLCBhcmd1bWVudHMpOwogICAgICByZXR1cm4gbmV3IEhhc2gob2JqKTsKICAgIH0sCgogICAgdG9DU1M6IGZ1bmN0aW9uKCkgewogICAgICB2YXIgYXJncyA9ICRBKGFyZ3VtZW50cyk7CiAgICAgIHZhciBrZXlzID0gKGFyZ3MubGVuZ3RoID09PSAwKSA/IEVsZW1lbnQuTGF5b3V0LlBST1BFUlRJRVMgOgogICAgICAgYXJncy5qb2luKCcgJykuc3BsaXQoJyAnKTsKICAgICAgdmFyIGNzcyA9IHt9OwoKICAgICAga2V5cy5lYWNoKCBmdW5jdGlvbihrZXkpIHsKICAgICAgICBpZiAoIUVsZW1lbnQuTGF5b3V0LlBST1BFUlRJRVMuaW5jbHVkZShrZXkpKSByZXR1cm47CiAgICAgICAgaWYgKEVsZW1lbnQuTGF5b3V0LkNPTVBPU0lURV9QUk9QRVJUSUVTLmluY2x1ZGUoa2V5KSkgcmV0dXJuOwoKICAgICAgICB2YXIgdmFsdWUgPSB0aGlzLmdldChrZXkpOwogICAgICAgIGlmICh2YWx1ZSAhPSBudWxsKSBjc3NbY3NzTmFtZUZvcihrZXkpXSA9IHZhbHVlICsgJ3B4JzsKICAgICAgfSwgdGhpcyk7CiAgICAgIHJldHVybiBjc3M7CiAgICB9LAoKICAgIGluc3BlY3Q6IGZ1bmN0aW9uKCkgewogICAgICByZXR1cm4gIiM8RWxlbWVudC5MYXlvdXQ+IjsKICAgIH0KICB9KTsKCiAgT2JqZWN0LmV4dGVuZChFbGVtZW50LkxheW91dCwgewogICAgUFJPUEVSVElFUzogJHcoJ2hlaWdodCB3aWR0aCB0b3AgbGVmdCByaWdodCBib3R0b20gYm9yZGVyLWxlZnQgYm9yZGVyLXJpZ2h0IGJvcmRlci10b3AgYm9yZGVyLWJvdHRvbSBwYWRkaW5nLWxlZnQgcGFkZGluZy1yaWdodCBwYWRkaW5nLXRvcCBwYWRkaW5nLWJvdHRvbSBtYXJnaW4tdG9wIG1hcmdpbi1ib3R0b20gbWFyZ2luLWxlZnQgbWFyZ2luLXJpZ2h0IHBhZGRpbmctYm94LXdpZHRoIHBhZGRpbmctYm94LWhlaWdodCBib3JkZXItYm94LXdpZHRoIGJvcmRlci1ib3gtaGVpZ2h0IG1hcmdpbi1ib3gtd2lkdGggbWFyZ2luLWJveC1oZWlnaHQnKSwKCiAgICBDT01QT1NJVEVfUFJPUEVSVElFUzogJHcoJ3BhZGRpbmctYm94LXdpZHRoIHBhZGRpbmctYm94LWhlaWdodCBtYXJnaW4tYm94LXdpZHRoIG1hcmdpbi1ib3gtaGVpZ2h0IGJvcmRlci1ib3gtd2lkdGggYm9yZGVyLWJveC1oZWlnaHQnKSwKCiAgICBDT01QVVRBVElPTlM6IHsKICAgICAgJ2hlaWdodCc6IGZ1bmN0aW9uKGVsZW1lbnQpIHsKICAgICAgICBpZiAoIXRoaXMuX3ByZUNvbXB1dGluZykgdGhpcy5fYmVnaW4oKTsKCiAgICAgICAgdmFyIGJIZWlnaHQgPSB0aGlzLmdldCgnYm9yZGVyLWJveC1oZWlnaHQnKTsKICAgICAgICBpZiAoYkhlaWdodCA8PSAwKSB7CiAgICAgICAgICBpZiAoIXRoaXMuX3ByZUNvbXB1dGluZykgdGhpcy5fZW5kKCk7CiAgICAgICAgICByZXR1cm4gMDsKICAgICAgICB9CgogICAgICAgIHZhciBiVG9wID0gdGhpcy5nZXQoJ2JvcmRlci10b3AnKSwKICAgICAgICAgYkJvdHRvbSA9IHRoaXMuZ2V0KCdib3JkZXItYm90dG9tJyk7CgogICAgICAgIHZhciBwVG9wID0gdGhpcy5nZXQoJ3BhZGRpbmctdG9wJyksCiAgICAgICAgIHBCb3R0b20gPSB0aGlzLmdldCgncGFkZGluZy1ib3R0b20nKTsKCiAgICAgICAgaWYgKCF0aGlzLl9wcmVDb21wdXRpbmcpIHRoaXMuX2VuZCgpOwoKICAgICAgICByZXR1cm4gYkhlaWdodCAtIGJUb3AgLSBiQm90dG9tIC0gcFRvcCAtIHBCb3R0b207CiAgICAgIH0sCgogICAgICAnd2lkdGgnOiBmdW5jdGlvbihlbGVtZW50KSB7CiAgICAgICAgaWYgKCF0aGlzLl9wcmVDb21wdXRpbmcpIHRoaXMuX2JlZ2luKCk7CgogICAgICAgIHZhciBiV2lkdGggPSB0aGlzLmdldCgnYm9yZGVyLWJveC13aWR0aCcpOwogICAgICAgIGlmIChiV2lkdGggPD0gMCkgewogICAgICAgICAgaWYgKCF0aGlzLl9wcmVDb21wdXRpbmcpIHRoaXMuX2VuZCgpOwogICAgICAgICAgcmV0dXJuIDA7CiAgICAgICAgfQoKICAgICAgICB2YXIgYkxlZnQgPSB0aGlzLmdldCgnYm9yZGVyLWxlZnQnKSwKICAgICAgICAgYlJpZ2h0ID0gdGhpcy5nZXQoJ2JvcmRlci1yaWdodCcpOwoKICAgICAgICB2YXIgcExlZnQgPSB0aGlzLmdldCgncGFkZGluZy1sZWZ0JyksCiAgICAgICAgIHBSaWdodCA9IHRoaXMuZ2V0KCdwYWRkaW5nLXJpZ2h0Jyk7CgogICAgICAgIGlmICghdGhpcy5fcHJlQ29tcHV0aW5nKSB0aGlzLl9lbmQoKTsKCiAgICAgICAgcmV0dXJuIGJXaWR0aCAtIGJMZWZ0IC0gYlJpZ2h0IC0gcExlZnQgLSBwUmlnaHQ7CiAgICAgIH0sCgogICAgICAncGFkZGluZy1ib3gtaGVpZ2h0JzogZnVuY3Rpb24oZWxlbWVudCkgewogICAgICAgIHZhciBoZWlnaHQgPSB0aGlzLmdldCgnaGVpZ2h0JyksCiAgICAgICAgIHBUb3AgPSB0aGlzLmdldCgncGFkZGluZy10b3AnKSwKICAgICAgICAgcEJvdHRvbSA9IHRoaXMuZ2V0KCdwYWRkaW5nLWJvdHRvbScpOwoKICAgICAgICByZXR1cm4gaGVpZ2h0ICsgcFRvcCArIHBCb3R0b207CiAgICAgIH0sCgogICAgICAncGFkZGluZy1ib3gtd2lkdGgnOiBmdW5jdGlvbihlbGVtZW50KSB7CiAgICAgICAgdmFyIHdpZHRoID0gdGhpcy5nZXQoJ3dpZHRoJyksCiAgICAgICAgIHBMZWZ0ID0gdGhpcy5nZXQoJ3BhZGRpbmctbGVmdCcpLAogICAgICAgICBwUmlnaHQgPSB0aGlzLmdldCgncGFkZGluZy1yaWdodCcpOwoKICAgICAgICByZXR1cm4gd2lkdGggKyBwTGVmdCArIHBSaWdodDsKICAgICAgfSwKCiAgICAgICdib3JkZXItYm94LWhlaWdodCc6IGZ1bmN0aW9uKGVsZW1lbnQpIHsKICAgICAgICBpZiAoIXRoaXMuX3ByZUNvbXB1dGluZykgdGhpcy5fYmVnaW4oKTsKICAgICAgICB2YXIgaGVpZ2h0ID0gZWxlbWVudC5vZmZzZXRIZWlnaHQ7CiAgICAgICAgaWYgKCF0aGlzLl9wcmVDb21wdXRpbmcpIHRoaXMuX2VuZCgpOwogICAgICAgIHJldHVybiBoZWlnaHQ7CiAgICAgIH0sCgogICAgICAnYm9yZGVyLWJveC13aWR0aCc6IGZ1bmN0aW9uKGVsZW1lbnQpIHsKICAgICAgICBpZiAoIXRoaXMuX3ByZUNvbXB1dGluZykgdGhpcy5fYmVnaW4oKTsKICAgICAgICB2YXIgd2lkdGggPSBlbGVtZW50Lm9mZnNldFdpZHRoOwogICAgICAgIGlmICghdGhpcy5fcHJlQ29tcHV0aW5nKSB0aGlzLl9lbmQoKTsKICAgICAgICByZXR1cm4gd2lkdGg7CiAgICAgIH0sCgogICAgICAnbWFyZ2luLWJveC1oZWlnaHQnOiBmdW5jdGlvbihlbGVtZW50KSB7CiAgICAgICAgdmFyIGJIZWlnaHQgPSB0aGlzLmdldCgnYm9yZGVyLWJveC1oZWlnaHQnKSwKICAgICAgICAgbVRvcCA9IHRoaXMuZ2V0KCdtYXJnaW4tdG9wJyksCiAgICAgICAgIG1Cb3R0b20gPSB0aGlzLmdldCgnbWFyZ2luLWJvdHRvbScpOwoKICAgICAgICBpZiAoYkhlaWdodCA8PSAwKSByZXR1cm4gMDsKCiAgICAgICAgcmV0dXJuIGJIZWlnaHQgKyBtVG9wICsgbUJvdHRvbTsKICAgICAgfSwKCiAgICAgICdtYXJnaW4tYm94LXdpZHRoJzogZnVuY3Rpb24oZWxlbWVudCkgewogICAgICAgIHZhciBiV2lkdGggPSB0aGlzLmdldCgnYm9yZGVyLWJveC13aWR0aCcpLAogICAgICAgICBtTGVmdCA9IHRoaXMuZ2V0KCdtYXJnaW4tbGVmdCcpLAogICAgICAgICBtUmlnaHQgPSB0aGlzLmdldCgnbWFyZ2luLXJpZ2h0Jyk7CgogICAgICAgIGlmIChiV2lkdGggPD0gMCkgcmV0dXJuIDA7CgogICAgICAgIHJldHVybiBiV2lkdGggKyBtTGVmdCArIG1SaWdodDsKICAgICAgfSwKCiAgICAgICd0b3AnOiBmdW5jdGlvbihlbGVtZW50KSB7CiAgICAgICAgdmFyIG9mZnNldCA9IGVsZW1lbnQucG9zaXRpb25lZE9mZnNldCgpOwogICAgICAgIHJldHVybiBvZmZzZXQudG9wOwogICAgICB9LAoKICAgICAgJ2JvdHRvbSc6IGZ1bmN0aW9uKGVsZW1lbnQpIHsKICAgICAgICB2YXIgb2Zmc2V0ID0gZWxlbWVudC5wb3NpdGlvbmVkT2Zmc2V0KCksCiAgICAgICAgIHBhcmVudCA9IGVsZW1lbnQuZ2V0T2Zmc2V0UGFyZW50KCksCiAgICAgICAgIHBIZWlnaHQgPSBwYXJlbnQubWVhc3VyZSgnaGVpZ2h0Jyk7CgogICAgICAgIHZhciBtSGVpZ2h0ID0gdGhpcy5nZXQoJ2JvcmRlci1ib3gtaGVpZ2h0Jyk7CgogICAgICAgIHJldHVybiBwSGVpZ2h0IC0gbUhlaWdodCAtIG9mZnNldC50b3A7CiAgICAgIH0sCgogICAgICAnbGVmdCc6IGZ1bmN0aW9uKGVsZW1lbnQpIHsKICAgICAgICB2YXIgb2Zmc2V0ID0gZWxlbWVudC5wb3NpdGlvbmVkT2Zmc2V0KCk7CiAgICAgICAgcmV0dXJuIG9mZnNldC5sZWZ0OwogICAgICB9LAoKICAgICAgJ3JpZ2h0JzogZnVuY3Rpb24oZWxlbWVudCkgewogICAgICAgIHZhciBvZmZzZXQgPSBlbGVtZW50LnBvc2l0aW9uZWRPZmZzZXQoKSwKICAgICAgICAgcGFyZW50ID0gZWxlbWVudC5nZXRPZmZzZXRQYXJlbnQoKSwKICAgICAgICAgcFdpZHRoID0gcGFyZW50Lm1lYXN1cmUoJ3dpZHRoJyk7CgogICAgICAgIHZhciBtV2lkdGggPSB0aGlzLmdldCgnYm9yZGVyLWJveC13aWR0aCcpOwoKICAgICAgICByZXR1cm4gcFdpZHRoIC0gbVdpZHRoIC0gb2Zmc2V0LmxlZnQ7CiAgICAgIH0sCgogICAgICAncGFkZGluZy10b3AnOiBmdW5jdGlvbihlbGVtZW50KSB7CiAgICAgICAgcmV0dXJuIGdldFBpeGVsVmFsdWUoZWxlbWVudCwgJ3BhZGRpbmdUb3AnKTsKICAgICAgfSwKCiAgICAgICdwYWRkaW5nLWJvdHRvbSc6IGZ1bmN0aW9uKGVsZW1lbnQpIHsKICAgICAgICByZXR1cm4gZ2V0UGl4ZWxWYWx1ZShlbGVtZW50LCAncGFkZGluZ0JvdHRvbScpOwogICAgICB9LAoKICAgICAgJ3BhZGRpbmctbGVmdCc6IGZ1bmN0aW9uKGVsZW1lbnQpIHsKICAgICAgICByZXR1cm4gZ2V0UGl4ZWxWYWx1ZShlbGVtZW50LCAncGFkZGluZ0xlZnQnKTsKICAgICAgfSwKCiAgICAgICdwYWRkaW5nLXJpZ2h0JzogZnVuY3Rpb24oZWxlbWVudCkgewogICAgICAgIHJldHVybiBnZXRQaXhlbFZhbHVlKGVsZW1lbnQsICdwYWRkaW5nUmlnaHQnKTsKICAgICAgfSwKCiAgICAgICdib3JkZXItdG9wJzogZnVuY3Rpb24oZWxlbWVudCkgewogICAgICAgIHJldHVybiBnZXRQaXhlbFZhbHVlKGVsZW1lbnQsICdib3JkZXJUb3BXaWR0aCcpOwogICAgICB9LAoKICAgICAgJ2JvcmRlci1ib3R0b20nOiBmdW5jdGlvbihlbGVtZW50KSB7CiAgICAgICAgcmV0dXJuIGdldFBpeGVsVmFsdWUoZWxlbWVudCwgJ2JvcmRlckJvdHRvbVdpZHRoJyk7CiAgICAgIH0sCgogICAgICAnYm9yZGVyLWxlZnQnOiBmdW5jdGlvbihlbGVtZW50KSB7CiAgICAgICAgcmV0dXJuIGdldFBpeGVsVmFsdWUoZWxlbWVudCwgJ2JvcmRlckxlZnRXaWR0aCcpOwogICAgICB9LAoKICAgICAgJ2JvcmRlci1yaWdodCc6IGZ1bmN0aW9uKGVsZW1lbnQpIHsKICAgICAgICByZXR1cm4gZ2V0UGl4ZWxWYWx1ZShlbGVtZW50LCAnYm9yZGVyUmlnaHRXaWR0aCcpOwogICAgICB9LAoKICAgICAgJ21hcmdpbi10b3AnOiBmdW5jdGlvbihlbGVtZW50KSB7CiAgICAgICAgcmV0dXJuIGdldFBpeGVsVmFsdWUoZWxlbWVudCwgJ21hcmdpblRvcCcpOwogICAgICB9LAoKICAgICAgJ21hcmdpbi1ib3R0b20nOiBmdW5jdGlvbihlbGVtZW50KSB7CiAgICAgICAgcmV0dXJuIGdldFBpeGVsVmFsdWUoZWxlbWVudCwgJ21hcmdpbkJvdHRvbScpOwogICAgICB9LAoKICAgICAgJ21hcmdpbi1sZWZ0JzogZnVuY3Rpb24oZWxlbWVudCkgewogICAgICAgIHJldHVybiBnZXRQaXhlbFZhbHVlKGVsZW1lbnQsICdtYXJnaW5MZWZ0Jyk7CiAgICAgIH0sCgogICAgICAnbWFyZ2luLXJpZ2h0JzogZnVuY3Rpb24oZWxlbWVudCkgewogICAgICAgIHJldHVybiBnZXRQaXhlbFZhbHVlKGVsZW1lbnQsICdtYXJnaW5SaWdodCcpOwogICAgICB9CiAgICB9CiAgfSk7CgogIGlmICgnZ2V0Qm91bmRpbmdDbGllbnRSZWN0JyBpbiBkb2N1bWVudC5kb2N1bWVudEVsZW1lbnQpIHsKICAgIE9iamVjdC5leHRlbmQoRWxlbWVudC5MYXlvdXQuQ09NUFVUQVRJT05TLCB7CiAgICAgICdyaWdodCc6IGZ1bmN0aW9uKGVsZW1lbnQpIHsKICAgICAgICB2YXIgcGFyZW50ID0gaGFzTGF5b3V0KGVsZW1lbnQuZ2V0T2Zmc2V0UGFyZW50KCkpOwogICAgICAgIHZhciByZWN0ID0gZWxlbWVudC5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKSwKICAgICAgICAgcFJlY3QgPSBwYXJlbnQuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCk7CgogICAgICAgIHJldHVybiAocFJlY3QucmlnaHQgLSByZWN0LnJpZ2h0KS5yb3VuZCgpOwogICAgICB9LAoKICAgICAgJ2JvdHRvbSc6IGZ1bmN0aW9uKGVsZW1lbnQpIHsKICAgICAgICB2YXIgcGFyZW50ID0gaGFzTGF5b3V0KGVsZW1lbnQuZ2V0T2Zmc2V0UGFyZW50KCkpOwogICAgICAgIHZhciByZWN0ID0gZWxlbWVudC5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKSwKICAgICAgICAgcFJlY3QgPSBwYXJlbnQuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCk7CgogICAgICAgIHJldHVybiAocFJlY3QuYm90dG9tIC0gcmVjdC5ib3R0b20pLnJvdW5kKCk7CiAgICAgIH0KICAgIH0pOwogIH0KCiAgRWxlbWVudC5PZmZzZXQgPSBDbGFzcy5jcmVhdGUoewogICAgaW5pdGlhbGl6ZTogZnVuY3Rpb24obGVmdCwgdG9wKSB7CiAgICAgIHRoaXMubGVmdCA9IGxlZnQucm91bmQoKTsKICAgICAgdGhpcy50b3AgID0gdG9wLnJvdW5kKCk7CgogICAgICB0aGlzWzBdID0gdGhpcy5sZWZ0OwogICAgICB0aGlzWzFdID0gdGhpcy50b3A7CiAgICB9LAoKICAgIHJlbGF0aXZlVG86IGZ1bmN0aW9uKG9mZnNldCkgewogICAgICByZXR1cm4gbmV3IEVsZW1lbnQuT2Zmc2V0KAogICAgICAgIHRoaXMubGVmdCAtIG9mZnNldC5sZWZ0LAogICAgICAgIHRoaXMudG9wICAtIG9mZnNldC50b3AKICAgICAgKTsKICAgIH0sCgogICAgaW5zcGVjdDogZnVuY3Rpb24oKSB7CiAgICAgIHJldHVybiAiIzxFbGVtZW50Lk9mZnNldCBsZWZ0OiAje2xlZnR9IHRvcDogI3t0b3B9PiIuaW50ZXJwb2xhdGUodGhpcyk7CiAgICB9LAoKICAgIHRvU3RyaW5nOiBmdW5jdGlvbigpIHsKICAgICAgcmV0dXJuICJbI3tsZWZ0fSwgI3t0b3B9XSIuaW50ZXJwb2xhdGUodGhpcyk7CiAgICB9LAoKICAgIHRvQXJyYXk6IGZ1bmN0aW9uKCkgewogICAgICByZXR1cm4gW3RoaXMubGVmdCwgdGhpcy50b3BdOwogICAgfQogIH0pOwoKICBmdW5jdGlvbiBnZXRMYXlvdXQoZWxlbWVudCwgcHJlQ29tcHV0ZSkgewogICAgcmV0dXJuIG5ldyBFbGVtZW50LkxheW91dChlbGVtZW50LCBwcmVDb21wdXRlKTsKICB9CgogIGZ1bmN0aW9uIG1lYXN1cmUoZWxlbWVudCwgcHJvcGVydHkpIHsKICAgIHJldHVybiAkKGVsZW1lbnQpLmdldExheW91dCgpLmdldChwcm9wZXJ0eSk7CiAgfQoKICBmdW5jdGlvbiBnZXREaW1lbnNpb25zKGVsZW1lbnQpIHsKICAgIGVsZW1lbnQgPSAkKGVsZW1lbnQpOwogICAgdmFyIGRpc3BsYXkgPSBFbGVtZW50LmdldFN0eWxlKGVsZW1lbnQsICdkaXNwbGF5Jyk7CgogICAgaWYgKGRpc3BsYXkgJiYgZGlzcGxheSAhPT0gJ25vbmUnKSB7CiAgICAgIHJldHVybiB7IHdpZHRoOiBlbGVtZW50Lm9mZnNldFdpZHRoLCBoZWlnaHQ6IGVsZW1lbnQub2Zmc2V0SGVpZ2h0IH07CiAgICB9CgogICAgdmFyIHN0eWxlID0gZWxlbWVudC5zdHlsZTsKICAgIHZhciBvcmlnaW5hbFN0eWxlcyA9IHsKICAgICAgdmlzaWJpbGl0eTogc3R5bGUudmlzaWJpbGl0eSwKICAgICAgcG9zaXRpb246ICAgc3R5bGUucG9zaXRpb24sCiAgICAgIGRpc3BsYXk6ICAgIHN0eWxlLmRpc3BsYXkKICAgIH07CgogICAgdmFyIG5ld1N0eWxlcyA9IHsKICAgICAgdmlzaWJpbGl0eTogJ2hpZGRlbicsCiAgICAgIGRpc3BsYXk6ICAgICdibG9jaycKICAgIH07CgogICAgaWYgKG9yaWdpbmFsU3R5bGVzLnBvc2l0aW9uICE9PSAnZml4ZWQnKQogICAgICBuZXdTdHlsZXMucG9zaXRpb24gPSAnYWJzb2x1dGUnOwoKICAgIEVsZW1lbnQuc2V0U3R5bGUoZWxlbWVudCwgbmV3U3R5bGVzKTsKCiAgICB2YXIgZGltZW5zaW9ucyA9IHsKICAgICAgd2lkdGg6ICBlbGVtZW50Lm9mZnNldFdpZHRoLAogICAgICBoZWlnaHQ6IGVsZW1lbnQub2Zmc2V0SGVpZ2h0CiAgICB9OwoKICAgIEVsZW1lbnQuc2V0U3R5bGUoZWxlbWVudCwgb3JpZ2luYWxTdHlsZXMpOwoKICAgIHJldHVybiBkaW1lbnNpb25zOwogIH0KCiAgZnVuY3Rpb24gZ2V0T2Zmc2V0UGFyZW50KGVsZW1lbnQpIHsKICAgIGVsZW1lbnQgPSAkKGVsZW1lbnQpOwoKICAgIGlmIChpc0RvY3VtZW50KGVsZW1lbnQpIHx8IGlzRGV0YWNoZWQoZWxlbWVudCkgfHwgaXNCb2R5KGVsZW1lbnQpIHx8IGlzSHRtbChlbGVtZW50KSkKICAgICAgcmV0dXJuICQoZG9jdW1lbnQuYm9keSk7CgogICAgdmFyIGlzSW5saW5lID0gKEVsZW1lbnQuZ2V0U3R5bGUoZWxlbWVudCwgJ2Rpc3BsYXknKSA9PT0gJ2lubGluZScpOwogICAgaWYgKCFpc0lubGluZSAmJiBlbGVtZW50Lm9mZnNldFBhcmVudCkgcmV0dXJuICQoZWxlbWVudC5vZmZzZXRQYXJlbnQpOwoKICAgIHdoaWxlICgoZWxlbWVudCA9IGVsZW1lbnQucGFyZW50Tm9kZSkgJiYgZWxlbWVudCAhPT0gZG9jdW1lbnQuYm9keSkgewogICAgICBpZiAoRWxlbWVudC5nZXRTdHlsZShlbGVtZW50LCAncG9zaXRpb24nKSAhPT0gJ3N0YXRpYycpIHsKICAgICAgICByZXR1cm4gaXNIdG1sKGVsZW1lbnQpID8gJChkb2N1bWVudC5ib2R5KSA6ICQoZWxlbWVudCk7CiAgICAgIH0KICAgIH0KCiAgICByZXR1cm4gJChkb2N1bWVudC5ib2R5KTsKICB9CgoKICBmdW5jdGlvbiBjdW11bGF0aXZlT2Zmc2V0KGVsZW1lbnQpIHsKICAgIGVsZW1lbnQgPSAkKGVsZW1lbnQpOwogICAgdmFyIHZhbHVlVCA9IDAsIHZhbHVlTCA9IDA7CiAgICBpZiAoZWxlbWVudC5wYXJlbnROb2RlKSB7CiAgICAgIGRvIHsKICAgICAgICB2YWx1ZVQgKz0gZWxlbWVudC5vZmZzZXRUb3AgIHx8IDA7CiAgICAgICAgdmFsdWVMICs9IGVsZW1lbnQub2Zmc2V0TGVmdCB8fCAwOwogICAgICAgIGVsZW1lbnQgPSBlbGVtZW50Lm9mZnNldFBhcmVudDsKICAgICAgfSB3aGlsZSAoZWxlbWVudCk7CiAgICB9CiAgICByZXR1cm4gbmV3IEVsZW1lbnQuT2Zmc2V0KHZhbHVlTCwgdmFsdWVUKTsKICB9CgogIGZ1bmN0aW9uIHBvc2l0aW9uZWRPZmZzZXQoZWxlbWVudCkgewogICAgZWxlbWVudCA9ICQoZWxlbWVudCk7CgogICAgdmFyIGxheW91dCA9IGVsZW1lbnQuZ2V0TGF5b3V0KCk7CgogICAgdmFyIHZhbHVlVCA9IDAsIHZhbHVlTCA9IDA7CiAgICBkbyB7CiAgICAgIHZhbHVlVCArPSBlbGVtZW50Lm9mZnNldFRvcCAgfHwgMDsKICAgICAgdmFsdWVMICs9IGVsZW1lbnQub2Zmc2V0TGVmdCB8fCAwOwogICAgICBlbGVtZW50ID0gZWxlbWVudC5vZmZzZXRQYXJlbnQ7CiAgICAgIGlmIChlbGVtZW50KSB7CiAgICAgICAgaWYgKGlzQm9keShlbGVtZW50KSkgYnJlYWs7CiAgICAgICAgdmFyIHAgPSBFbGVtZW50LmdldFN0eWxlKGVsZW1lbnQsICdwb3NpdGlvbicpOwogICAgICAgIGlmIChwICE9PSAnc3RhdGljJykgYnJlYWs7CiAgICAgIH0KICAgIH0gd2hpbGUgKGVsZW1lbnQpOwoKICAgIHZhbHVlTCAtPSBsYXlvdXQuZ2V0KCdtYXJnaW4tdG9wJyk7CiAgICB2YWx1ZVQgLT0gbGF5b3V0LmdldCgnbWFyZ2luLWxlZnQnKTsKCiAgICByZXR1cm4gbmV3IEVsZW1lbnQuT2Zmc2V0KHZhbHVlTCwgdmFsdWVUKTsKICB9CgogIGZ1bmN0aW9uIGN1bXVsYXRpdmVTY3JvbGxPZmZzZXQoZWxlbWVudCkgewogICAgdmFyIHZhbHVlVCA9IDAsIHZhbHVlTCA9IDA7CiAgICBkbyB7CiAgICAgIHZhbHVlVCArPSBlbGVtZW50LnNjcm9sbFRvcCAgfHwgMDsKICAgICAgdmFsdWVMICs9IGVsZW1lbnQuc2Nyb2xsTGVmdCB8fCAwOwogICAgICBlbGVtZW50ID0gZWxlbWVudC5wYXJlbnROb2RlOwogICAgfSB3aGlsZSAoZWxlbWVudCk7CiAgICByZXR1cm4gbmV3IEVsZW1lbnQuT2Zmc2V0KHZhbHVlTCwgdmFsdWVUKTsKICB9CgogIGZ1bmN0aW9uIHZpZXdwb3J0T2Zmc2V0KGZvckVsZW1lbnQpIHsKICAgIGVsZW1lbnQgPSAkKGVsZW1lbnQpOwogICAgdmFyIHZhbHVlVCA9IDAsIHZhbHVlTCA9IDAsIGRvY0JvZHkgPSBkb2N1bWVudC5ib2R5OwoKICAgIHZhciBlbGVtZW50ID0gZm9yRWxlbWVudDsKICAgIGRvIHsKICAgICAgdmFsdWVUICs9IGVsZW1lbnQub2Zmc2V0VG9wICB8fCAwOwogICAgICB2YWx1ZUwgKz0gZWxlbWVudC5vZmZzZXRMZWZ0IHx8IDA7CiAgICAgIGlmIChlbGVtZW50Lm9mZnNldFBhcmVudCA9PSBkb2NCb2R5ICYmCiAgICAgICAgRWxlbWVudC5nZXRTdHlsZShlbGVtZW50LCAncG9zaXRpb24nKSA9PSAnYWJzb2x1dGUnKSBicmVhazsKICAgIH0gd2hpbGUgKGVsZW1lbnQgPSBlbGVtZW50Lm9mZnNldFBhcmVudCk7CgogICAgZWxlbWVudCA9IGZvckVsZW1lbnQ7CiAgICBkbyB7CiAgICAgIGlmIChlbGVtZW50ICE9IGRvY0JvZHkpIHsKICAgICAgICB2YWx1ZVQgLT0gZWxlbWVudC5zY3JvbGxUb3AgIHx8IDA7CiAgICAgICAgdmFsdWVMIC09IGVsZW1lbnQuc2Nyb2xsTGVmdCB8fCAwOwogICAgICB9CiAgICB9IHdoaWxlIChlbGVtZW50ID0gZWxlbWVudC5wYXJlbnROb2RlKTsKICAgIHJldHVybiBuZXcgRWxlbWVudC5PZmZzZXQodmFsdWVMLCB2YWx1ZVQpOwogIH0KCiAgZnVuY3Rpb24gYWJzb2x1dGl6ZShlbGVtZW50KSB7CiAgICBlbGVtZW50ID0gJChlbGVtZW50KTsKCiAgICBpZiAoRWxlbWVudC5nZXRTdHlsZShlbGVtZW50LCAncG9zaXRpb24nKSA9PT0gJ2Fic29sdXRlJykgewogICAgICByZXR1cm4gZWxlbWVudDsKICAgIH0KCiAgICB2YXIgb2Zmc2V0UGFyZW50ID0gZ2V0T2Zmc2V0UGFyZW50KGVsZW1lbnQpOwogICAgdmFyIGVPZmZzZXQgPSBlbGVtZW50LnZpZXdwb3J0T2Zmc2V0KCksCiAgICAgcE9mZnNldCA9IG9mZnNldFBhcmVudC52aWV3cG9ydE9mZnNldCgpOwoKICAgIHZhciBvZmZzZXQgPSBlT2Zmc2V0LnJlbGF0aXZlVG8ocE9mZnNldCk7CiAgICB2YXIgbGF5b3V0ID0gZWxlbWVudC5nZXRMYXlvdXQoKTsKCiAgICBlbGVtZW50LnN0b3JlKCdwcm90b3R5cGVfYWJzb2x1dGl6ZV9vcmlnaW5hbF9zdHlsZXMnLCB7CiAgICAgIGxlZnQ6ICAgZWxlbWVudC5nZXRTdHlsZSgnbGVmdCcpLAogICAgICB0b3A6ICAgIGVsZW1lbnQuZ2V0U3R5bGUoJ3RvcCcpLAogICAgICB3aWR0aDogIGVsZW1lbnQuZ2V0U3R5bGUoJ3dpZHRoJyksCiAgICAgIGhlaWdodDogZWxlbWVudC5nZXRTdHlsZSgnaGVpZ2h0JykKICAgIH0pOwoKICAgIGVsZW1lbnQuc2V0U3R5bGUoewogICAgICBwb3NpdGlvbjogJ2Fic29sdXRlJywKICAgICAgdG9wOiAgICBvZmZzZXQudG9wICsgJ3B4JywKICAgICAgbGVmdDogICBvZmZzZXQubGVmdCArICdweCcsCiAgICAgIHdpZHRoOiAgbGF5b3V0LmdldCgnd2lkdGgnKSArICdweCcsCiAgICAgIGhlaWdodDogbGF5b3V0LmdldCgnaGVpZ2h0JykgKyAncHgnCiAgICB9KTsKCiAgICByZXR1cm4gZWxlbWVudDsKICB9CgogIGZ1bmN0aW9uIHJlbGF0aXZpemUoZWxlbWVudCkgewogICAgZWxlbWVudCA9ICQoZWxlbWVudCk7CiAgICBpZiAoRWxlbWVudC5nZXRTdHlsZShlbGVtZW50LCAncG9zaXRpb24nKSA9PT0gJ3JlbGF0aXZlJykgewogICAgICByZXR1cm4gZWxlbWVudDsKICAgIH0KCiAgICB2YXIgb3JpZ2luYWxTdHlsZXMgPQogICAgIGVsZW1lbnQucmV0cmlldmUoJ3Byb3RvdHlwZV9hYnNvbHV0aXplX29yaWdpbmFsX3N0eWxlcycpOwoKICAgIGlmIChvcmlnaW5hbFN0eWxlcykgZWxlbWVudC5zZXRTdHlsZShvcmlnaW5hbFN0eWxlcyk7CiAgICByZXR1cm4gZWxlbWVudDsKICB9CgogIGlmIChQcm90b3R5cGUuQnJvd3Nlci5JRSkgewogICAgZ2V0T2Zmc2V0UGFyZW50ID0gZ2V0T2Zmc2V0UGFyZW50LndyYXAoCiAgICAgIGZ1bmN0aW9uKHByb2NlZWQsIGVsZW1lbnQpIHsKICAgICAgICBlbGVtZW50ID0gJChlbGVtZW50KTsKCiAgICAgICAgaWYgKGlzRG9jdW1lbnQoZWxlbWVudCkgfHwgaXNEZXRhY2hlZChlbGVtZW50KSB8fCBpc0JvZHkoZWxlbWVudCkgfHwgaXNIdG1sKGVsZW1lbnQpKQogICAgICAgICAgcmV0dXJuICQoZG9jdW1lbnQuYm9keSk7CgogICAgICAgIHZhciBwb3NpdGlvbiA9IGVsZW1lbnQuZ2V0U3R5bGUoJ3Bvc2l0aW9uJyk7CiAgICAgICAgaWYgKHBvc2l0aW9uICE9PSAnc3RhdGljJykgcmV0dXJuIHByb2NlZWQoZWxlbWVudCk7CgogICAgICAgIGVsZW1lbnQuc2V0U3R5bGUoeyBwb3NpdGlvbjogJ3JlbGF0aXZlJyB9KTsKICAgICAgICB2YXIgdmFsdWUgPSBwcm9jZWVkKGVsZW1lbnQpOwogICAgICAgIGVsZW1lbnQuc2V0U3R5bGUoeyBwb3NpdGlvbjogcG9zaXRpb24gfSk7CiAgICAgICAgcmV0dXJuIHZhbHVlOwogICAgICB9CiAgICApOwoKICAgIHBvc2l0aW9uZWRPZmZzZXQgPSBwb3NpdGlvbmVkT2Zmc2V0LndyYXAoZnVuY3Rpb24ocHJvY2VlZCwgZWxlbWVudCkgewogICAgICBlbGVtZW50ID0gJChlbGVtZW50KTsKICAgICAgaWYgKCFlbGVtZW50LnBhcmVudE5vZGUpIHJldHVybiBuZXcgRWxlbWVudC5PZmZzZXQoMCwgMCk7CiAgICAgIHZhciBwb3NpdGlvbiA9IGVsZW1lbnQuZ2V0U3R5bGUoJ3Bvc2l0aW9uJyk7CiAgICAgIGlmIChwb3NpdGlvbiAhPT0gJ3N0YXRpYycpIHJldHVybiBwcm9jZWVkKGVsZW1lbnQpOwoKICAgICAgdmFyIG9mZnNldFBhcmVudCA9IGVsZW1lbnQuZ2V0T2Zmc2V0UGFyZW50KCk7CiAgICAgIGlmIChvZmZzZXRQYXJlbnQgJiYgb2Zmc2V0UGFyZW50LmdldFN0eWxlKCdwb3NpdGlvbicpID09PSAnZml4ZWQnKQogICAgICAgIGhhc0xheW91dChvZmZzZXRQYXJlbnQpOwoKICAgICAgZWxlbWVudC5zZXRTdHlsZSh7IHBvc2l0aW9uOiAncmVsYXRpdmUnIH0pOwogICAgICB2YXIgdmFsdWUgPSBwcm9jZWVkKGVsZW1lbnQpOwogICAgICBlbGVtZW50LnNldFN0eWxlKHsgcG9zaXRpb246IHBvc2l0aW9uIH0pOwogICAgICByZXR1cm4gdmFsdWU7CiAgICB9KTsKICB9IGVsc2UgaWYgKFByb3RvdHlwZS5Ccm93c2VyLldlYmtpdCkgewogICAgY3VtdWxhdGl2ZU9mZnNldCA9IGZ1bmN0aW9uKGVsZW1lbnQpIHsKICAgICAgZWxlbWVudCA9ICQoZWxlbWVudCk7CiAgICAgIHZhciB2YWx1ZVQgPSAwLCB2YWx1ZUwgPSAwOwogICAgICBkbyB7CiAgICAgICAgdmFsdWVUICs9IGVsZW1lbnQub2Zmc2V0VG9wICB8fCAwOwogICAgICAgIHZhbHVlTCArPSBlbGVtZW50Lm9mZnNldExlZnQgfHwgMDsKICAgICAgICBpZiAoZWxlbWVudC5vZmZzZXRQYXJlbnQgPT0gZG9jdW1lbnQuYm9keSkKICAgICAgICAgIGlmIChFbGVtZW50LmdldFN0eWxlKGVsZW1lbnQsICdwb3NpdGlvbicpID09ICdhYnNvbHV0ZScpIGJyZWFrOwoKICAgICAgICBlbGVtZW50ID0gZWxlbWVudC5vZmZzZXRQYXJlbnQ7CiAgICAgIH0gd2hpbGUgKGVsZW1lbnQpOwoKICAgICAgcmV0dXJuIG5ldyBFbGVtZW50Lk9mZnNldCh2YWx1ZUwsIHZhbHVlVCk7CiAgICB9OwogIH0KCgogIEVsZW1lbnQuYWRkTWV0aG9kcyh7CiAgICBnZXRMYXlvdXQ6ICAgICAgICAgICAgICBnZXRMYXlvdXQsCiAgICBtZWFzdXJlOiAgICAgICAgICAgICAgICBtZWFzdXJlLAogICAgZ2V0RGltZW5zaW9uczogICAgICAgICAgZ2V0RGltZW5zaW9ucywKICAgIGdldE9mZnNldFBhcmVudDogICAgICAgIGdldE9mZnNldFBhcmVudCwKICAgIGN1bXVsYXRpdmVPZmZzZXQ6ICAgICAgIGN1bXVsYXRpdmVPZmZzZXQsCiAgICBwb3NpdGlvbmVkT2Zmc2V0OiAgICAgICBwb3NpdGlvbmVkT2Zmc2V0LAogICAgY3VtdWxhdGl2ZVNjcm9sbE9mZnNldDogY3VtdWxhdGl2ZVNjcm9sbE9mZnNldCwKICAgIHZpZXdwb3J0T2Zmc2V0OiAgICAgICAgIHZpZXdwb3J0T2Zmc2V0LAogICAgYWJzb2x1dGl6ZTogICAgICAgICAgICAgYWJzb2x1dGl6ZSwKICAgIHJlbGF0aXZpemU6ICAgICAgICAgICAgIHJlbGF0aXZpemUKICB9KTsKCiAgZnVuY3Rpb24gaXNCb2R5KGVsZW1lbnQpIHsKICAgIHJldHVybiBlbGVtZW50Lm5vZGVOYW1lLnRvVXBwZXJDYXNlKCkgPT09ICdCT0RZJzsKICB9CgogIGZ1bmN0aW9uIGlzSHRtbChlbGVtZW50KSB7CiAgICByZXR1cm4gZWxlbWVudC5ub2RlTmFtZS50b1VwcGVyQ2FzZSgpID09PSAnSFRNTCc7CiAgfQoKICBmdW5jdGlvbiBpc0RvY3VtZW50KGVsZW1lbnQpIHsKICAgIHJldHVybiBlbGVtZW50Lm5vZGVUeXBlID09PSBOb2RlLkRPQ1VNRU5UX05PREU7CiAgfQoKICBmdW5jdGlvbiBpc0RldGFjaGVkKGVsZW1lbnQpIHsKICAgIHJldHVybiBlbGVtZW50ICE9PSBkb2N1bWVudC5ib2R5ICYmCiAgICAgIUVsZW1lbnQuZGVzY2VuZGFudE9mKGVsZW1lbnQsIGRvY3VtZW50LmJvZHkpOwogIH0KCiAgaWYgKCdnZXRCb3VuZGluZ0NsaWVudFJlY3QnIGluIGRvY3VtZW50LmRvY3VtZW50RWxlbWVudCkgewogICAgRWxlbWVudC5hZGRNZXRob2RzKHsKICAgICAgdmlld3BvcnRPZmZzZXQ6IGZ1bmN0aW9uKGVsZW1lbnQpIHsKICAgICAgICBlbGVtZW50ID0gJChlbGVtZW50KTsKICAgICAgICBpZiAoaXNEZXRhY2hlZChlbGVtZW50KSkgcmV0dXJuIG5ldyBFbGVtZW50Lk9mZnNldCgwLCAwKTsKCiAgICAgICAgdmFyIHJlY3QgPSBlbGVtZW50LmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpLAogICAgICAgICBkb2NFbCA9IGRvY3VtZW50LmRvY3VtZW50RWxlbWVudDsKICAgICAgICByZXR1cm4gbmV3IEVsZW1lbnQuT2Zmc2V0KHJlY3QubGVmdCAtIGRvY0VsLmNsaWVudExlZnQsCiAgICAgICAgIHJlY3QudG9wIC0gZG9jRWwuY2xpZW50VG9wKTsKICAgICAgfQogICAgfSk7CiAgfQp9KSgpOwp3aW5kb3cuJCQgPSBmdW5jdGlvbigpIHsKICB2YXIgZXhwcmVzc2lvbiA9ICRBKGFyZ3VtZW50cykuam9pbignLCAnKTsKICByZXR1cm4gUHJvdG90eXBlLlNlbGVjdG9yLnNlbGVjdChleHByZXNzaW9uLCBkb2N1bWVudCk7Cn07CgpQcm90b3R5cGUuU2VsZWN0b3IgPSAoZnVuY3Rpb24oKSB7CgogIGZ1bmN0aW9uIHNlbGVjdCgpIHsKICAgIHRocm93IG5ldyBFcnJvcignTWV0aG9kICJQcm90b3R5cGUuU2VsZWN0b3Iuc2VsZWN0IiBtdXN0IGJlIGRlZmluZWQuJyk7CiAgfQoKICBmdW5jdGlvbiBtYXRjaCgpIHsKICAgIHRocm93IG5ldyBFcnJvcignTWV0aG9kICJQcm90b3R5cGUuU2VsZWN0b3IubWF0Y2giIG11c3QgYmUgZGVmaW5lZC4nKTsKICB9CgogIGZ1bmN0aW9uIGZpbmQoZWxlbWVudHMsIGV4cHJlc3Npb24sIGluZGV4KSB7CiAgICBpbmRleCA9IGluZGV4IHx8IDA7CiAgICB2YXIgbWF0Y2ggPSBQcm90b3R5cGUuU2VsZWN0b3IubWF0Y2gsIGxlbmd0aCA9IGVsZW1lbnRzLmxlbmd0aCwgbWF0Y2hJbmRleCA9IDAsIGk7CgogICAgZm9yIChpID0gMDsgaSA8IGxlbmd0aDsgaSsrKSB7CiAgICAgIGlmIChtYXRjaChlbGVtZW50c1tpXSwgZXhwcmVzc2lvbikgJiYgaW5kZXggPT0gbWF0Y2hJbmRleCsrKSB7CiAgICAgICAgcmV0dXJuIEVsZW1lbnQuZXh0ZW5kKGVsZW1lbnRzW2ldKTsKICAgICAgfQogICAgfQogIH0KCiAgZnVuY3Rpb24gZXh0ZW5kRWxlbWVudHMoZWxlbWVudHMpIHsKICAgIGZvciAodmFyIGkgPSAwLCBsZW5ndGggPSBlbGVtZW50cy5sZW5ndGg7IGkgPCBsZW5ndGg7IGkrKykgewogICAgICBFbGVtZW50LmV4dGVuZChlbGVtZW50c1tpXSk7CiAgICB9CiAgICByZXR1cm4gZWxlbWVudHM7CiAgfQoKCiAgdmFyIEsgPSBQcm90b3R5cGUuSzsKCiAgcmV0dXJuIHsKICAgIHNlbGVjdDogc2VsZWN0LAogICAgbWF0Y2g6IG1hdGNoLAogICAgZmluZDogZmluZCwKICAgIGV4dGVuZEVsZW1lbnRzOiAoRWxlbWVudC5leHRlbmQgPT09IEspID8gSyA6IGV4dGVuZEVsZW1lbnRzLAogICAgZXh0ZW5kRWxlbWVudDogRWxlbWVudC5leHRlbmQKICB9Owp9KSgpOwovKiEKICogU2l6emxlIENTUyBTZWxlY3RvciBFbmdpbmUgLSB2MS4wCiAqICBDb3B5cmlnaHQgMjAwOSwgVGhlIERvam8gRm91bmRhdGlvbgogKiAgUmVsZWFzZWQgdW5kZXIgdGhlIE1JVCwgQlNELCBhbmQgR1BMIExpY2Vuc2VzLgogKiAgTW9yZSBpbmZvcm1hdGlvbjogaHR0cDovL3NpenpsZWpzLmNvbS8KICovCihmdW5jdGlvbigpewoKdmFyIGNodW5rZXIgPSAvKCg/OlwoKD86XChbXigpXStcKXxbXigpXSspK1wpfFxbKD86XFtbXltcXV0qXF18WyciXVteJyJdKlsnIl18W15bXF0nIl0rKStcXXxcXC58W14gPit+LChcW1xcXSspK3xbPit+XSkoXHMqLFxzKik/KCg/Oi58XHJ8XG4pKikvZywKCWRvbmUgPSAwLAoJdG9TdHJpbmcgPSBPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nLAoJaGFzRHVwbGljYXRlID0gZmFsc2UsCgliYXNlSGFzRHVwbGljYXRlID0gdHJ1ZTsKClswLCAwXS5zb3J0KGZ1bmN0aW9uKCl7CgliYXNlSGFzRHVwbGljYXRlID0gZmFsc2U7CglyZXR1cm4gMDsKfSk7Cgp2YXIgU2l6emxlID0gZnVuY3Rpb24oc2VsZWN0b3IsIGNvbnRleHQsIHJlc3VsdHMsIHNlZWQpIHsKCXJlc3VsdHMgPSByZXN1bHRzIHx8IFtdOwoJdmFyIG9yaWdDb250ZXh0ID0gY29udGV4dCA9IGNvbnRleHQgfHwgZG9jdW1lbnQ7CgoJaWYgKCBjb250ZXh0Lm5vZGVUeXBlICE9PSAxICYmIGNvbnRleHQubm9kZVR5cGUgIT09IDkgKSB7CgkJcmV0dXJuIFtdOwoJfQoKCWlmICggIXNlbGVjdG9yIHx8IHR5cGVvZiBzZWxlY3RvciAhPT0gInN0cmluZyIgKSB7CgkJcmV0dXJuIHJlc3VsdHM7Cgl9CgoJdmFyIHBhcnRzID0gW10sIG0sIHNldCwgY2hlY2tTZXQsIGNoZWNrLCBtb2RlLCBleHRyYSwgcHJ1bmUgPSB0cnVlLCBjb250ZXh0WE1MID0gaXNYTUwoY29udGV4dCksCgkJc29GYXIgPSBzZWxlY3RvcjsKCgl3aGlsZSAoIChjaHVua2VyLmV4ZWMoIiIpLCBtID0gY2h1bmtlci5leGVjKHNvRmFyKSkgIT09IG51bGwgKSB7CgkJc29GYXIgPSBtWzNdOwoKCQlwYXJ0cy5wdXNoKCBtWzFdICk7CgoJCWlmICggbVsyXSApIHsKCQkJZXh0cmEgPSBtWzNdOwoJCQlicmVhazsKCQl9Cgl9CgoJaWYgKCBwYXJ0cy5sZW5ndGggPiAxICYmIG9yaWdQT1MuZXhlYyggc2VsZWN0b3IgKSApIHsKCQlpZiAoIHBhcnRzLmxlbmd0aCA9PT0gMiAmJiBFeHByLnJlbGF0aXZlWyBwYXJ0c1swXSBdICkgewoJCQlzZXQgPSBwb3NQcm9jZXNzKCBwYXJ0c1swXSArIHBhcnRzWzFdLCBjb250ZXh0ICk7CgkJfSBlbHNlIHsKCQkJc2V0ID0gRXhwci5yZWxhdGl2ZVsgcGFydHNbMF0gXSA/CgkJCQlbIGNvbnRleHQgXSA6CgkJCQlTaXp6bGUoIHBhcnRzLnNoaWZ0KCksIGNvbnRleHQgKTsKCgkJCXdoaWxlICggcGFydHMubGVuZ3RoICkgewoJCQkJc2VsZWN0b3IgPSBwYXJ0cy5zaGlmdCgpOwoKCQkJCWlmICggRXhwci5yZWxhdGl2ZVsgc2VsZWN0b3IgXSApCgkJCQkJc2VsZWN0b3IgKz0gcGFydHMuc2hpZnQoKTsKCgkJCQlzZXQgPSBwb3NQcm9jZXNzKCBzZWxlY3Rvciwgc2V0ICk7CgkJCX0KCQl9Cgl9IGVsc2UgewoJCWlmICggIXNlZWQgJiYgcGFydHMubGVuZ3RoID4gMSAmJiBjb250ZXh0Lm5vZGVUeXBlID09PSA5ICYmICFjb250ZXh0WE1MICYmCgkJCQlFeHByLm1hdGNoLklELnRlc3QocGFydHNbMF0pICYmICFFeHByLm1hdGNoLklELnRlc3QocGFydHNbcGFydHMubGVuZ3RoIC0gMV0pICkgewoJCQl2YXIgcmV0ID0gU2l6emxlLmZpbmQoIHBhcnRzLnNoaWZ0KCksIGNvbnRleHQsIGNvbnRleHRYTUwgKTsKCQkJY29udGV4dCA9IHJldC5leHByID8gU2l6emxlLmZpbHRlciggcmV0LmV4cHIsIHJldC5zZXQgKVswXSA6IHJldC5zZXRbMF07CgkJfQoKCQlpZiAoIGNvbnRleHQgKSB7CgkJCXZhciByZXQgPSBzZWVkID8KCQkJCXsgZXhwcjogcGFydHMucG9wKCksIHNldDogbWFrZUFycmF5KHNlZWQpIH0gOgoJCQkJU2l6emxlLmZpbmQoIHBhcnRzLnBvcCgpLCBwYXJ0cy5sZW5ndGggPT09IDEgJiYgKHBhcnRzWzBdID09PSAifiIgfHwgcGFydHNbMF0gPT09ICIrIikgJiYgY29udGV4dC5wYXJlbnROb2RlID8gY29udGV4dC5wYXJlbnROb2RlIDogY29udGV4dCwgY29udGV4dFhNTCApOwoJCQlzZXQgPSByZXQuZXhwciA/IFNpenpsZS5maWx0ZXIoIHJldC5leHByLCByZXQuc2V0ICkgOiByZXQuc2V0OwoKCQkJaWYgKCBwYXJ0cy5sZW5ndGggPiAwICkgewoJCQkJY2hlY2tTZXQgPSBtYWtlQXJyYXkoc2V0KTsKCQkJfSBlbHNlIHsKCQkJCXBydW5lID0gZmFsc2U7CgkJCX0KCgkJCXdoaWxlICggcGFydHMubGVuZ3RoICkgewoJCQkJdmFyIGN1ciA9IHBhcnRzLnBvcCgpLCBwb3AgPSBjdXI7CgoJCQkJaWYgKCAhRXhwci5yZWxhdGl2ZVsgY3VyIF0gKSB7CgkJCQkJY3VyID0gIiI7CgkJCQl9IGVsc2UgewoJCQkJCXBvcCA9IHBhcnRzLnBvcCgpOwoJCQkJfQoKCQkJCWlmICggcG9wID09IG51bGwgKSB7CgkJCQkJcG9wID0gY29udGV4dDsKCQkJCX0KCgkJCQlFeHByLnJlbGF0aXZlWyBjdXIgXSggY2hlY2tTZXQsIHBvcCwgY29udGV4dFhNTCApOwoJCQl9CgkJfSBlbHNlIHsKCQkJY2hlY2tTZXQgPSBwYXJ0cyA9IFtdOwoJCX0KCX0KCglpZiAoICFjaGVja1NldCApIHsKCQljaGVja1NldCA9IHNldDsKCX0KCglpZiAoICFjaGVja1NldCApIHsKCQl0aHJvdyAiU3ludGF4IGVycm9yLCB1bnJlY29nbml6ZWQgZXhwcmVzc2lvbjogIiArIChjdXIgfHwgc2VsZWN0b3IpOwoJfQoKCWlmICggdG9TdHJpbmcuY2FsbChjaGVja1NldCkgPT09ICJbb2JqZWN0IEFycmF5XSIgKSB7CgkJaWYgKCAhcHJ1bmUgKSB7CgkJCXJlc3VsdHMucHVzaC5hcHBseSggcmVzdWx0cywgY2hlY2tTZXQgKTsKCQl9IGVsc2UgaWYgKCBjb250ZXh0ICYmIGNvbnRleHQubm9kZVR5cGUgPT09IDEgKSB7CgkJCWZvciAoIHZhciBpID0gMDsgY2hlY2tTZXRbaV0gIT0gbnVsbDsgaSsrICkgewoJCQkJaWYgKCBjaGVja1NldFtpXSAmJiAoY2hlY2tTZXRbaV0gPT09IHRydWUgfHwgY2hlY2tTZXRbaV0ubm9kZVR5cGUgPT09IDEgJiYgY29udGFpbnMoY29udGV4dCwgY2hlY2tTZXRbaV0pKSApIHsKCQkJCQlyZXN1bHRzLnB1c2goIHNldFtpXSApOwoJCQkJfQoJCQl9CgkJfSBlbHNlIHsKCQkJZm9yICggdmFyIGkgPSAwOyBjaGVja1NldFtpXSAhPSBudWxsOyBpKysgKSB7CgkJCQlpZiAoIGNoZWNrU2V0W2ldICYmIGNoZWNrU2V0W2ldLm5vZGVUeXBlID09PSAxICkgewoJCQkJCXJlc3VsdHMucHVzaCggc2V0W2ldICk7CgkJCQl9CgkJCX0KCQl9Cgl9IGVsc2UgewoJCW1ha2VBcnJheSggY2hlY2tTZXQsIHJlc3VsdHMgKTsKCX0KCglpZiAoIGV4dHJhICkgewoJCVNpenpsZSggZXh0cmEsIG9yaWdDb250ZXh0LCByZXN1bHRzLCBzZWVkICk7CgkJU2l6emxlLnVuaXF1ZVNvcnQoIHJlc3VsdHMgKTsKCX0KCglyZXR1cm4gcmVzdWx0czsKfTsKClNpenpsZS51bmlxdWVTb3J0ID0gZnVuY3Rpb24ocmVzdWx0cyl7CglpZiAoIHNvcnRPcmRlciApIHsKCQloYXNEdXBsaWNhdGUgPSBiYXNlSGFzRHVwbGljYXRlOwoJCXJlc3VsdHMuc29ydChzb3J0T3JkZXIpOwoKCQlpZiAoIGhhc0R1cGxpY2F0ZSApIHsKCQkJZm9yICggdmFyIGkgPSAxOyBpIDwgcmVzdWx0cy5sZW5ndGg7IGkrKyApIHsKCQkJCWlmICggcmVzdWx0c1tpXSA9PT0gcmVzdWx0c1tpLTFdICkgewoJCQkJCXJlc3VsdHMuc3BsaWNlKGktLSwgMSk7CgkJCQl9CgkJCX0KCQl9Cgl9CgoJcmV0dXJuIHJlc3VsdHM7Cn07CgpTaXp6bGUubWF0Y2hlcyA9IGZ1bmN0aW9uKGV4cHIsIHNldCl7CglyZXR1cm4gU2l6emxlKGV4cHIsIG51bGwsIG51bGwsIHNldCk7Cn07CgpTaXp6bGUuZmluZCA9IGZ1bmN0aW9uKGV4cHIsIGNvbnRleHQsIGlzWE1MKXsKCXZhciBzZXQsIG1hdGNoOwoKCWlmICggIWV4cHIgKSB7CgkJcmV0dXJuIFtdOwoJfQoKCWZvciAoIHZhciBpID0gMCwgbCA9IEV4cHIub3JkZXIubGVuZ3RoOyBpIDwgbDsgaSsrICkgewoJCXZhciB0eXBlID0gRXhwci5vcmRlcltpXSwgbWF0Y2g7CgoJCWlmICggKG1hdGNoID0gRXhwci5sZWZ0TWF0Y2hbIHR5cGUgXS5leGVjKCBleHByICkpICkgewoJCQl2YXIgbGVmdCA9IG1hdGNoWzFdOwoJCQltYXRjaC5zcGxpY2UoMSwxKTsKCgkJCWlmICggbGVmdC5zdWJzdHIoIGxlZnQubGVuZ3RoIC0gMSApICE9PSAiXFwiICkgewoJCQkJbWF0Y2hbMV0gPSAobWF0Y2hbMV0gfHwgIiIpLnJlcGxhY2UoL1xcL2csICIiKTsKCQkJCXNldCA9IEV4cHIuZmluZFsgdHlwZSBdKCBtYXRjaCwgY29udGV4dCwgaXNYTUwgKTsKCQkJCWlmICggc2V0ICE9IG51bGwgKSB7CgkJCQkJZXhwciA9IGV4cHIucmVwbGFjZSggRXhwci5tYXRjaFsgdHlwZSBdLCAiIiApOwoJCQkJCWJyZWFrOwoJCQkJfQoJCQl9CgkJfQoJfQoKCWlmICggIXNldCApIHsKCQlzZXQgPSBjb250ZXh0LmdldEVsZW1lbnRzQnlUYWdOYW1lKCIqIik7Cgl9CgoJcmV0dXJuIHtzZXQ6IHNldCwgZXhwcjogZXhwcn07Cn07CgpTaXp6bGUuZmlsdGVyID0gZnVuY3Rpb24oZXhwciwgc2V0LCBpbnBsYWNlLCBub3QpewoJdmFyIG9sZCA9IGV4cHIsIHJlc3VsdCA9IFtdLCBjdXJMb29wID0gc2V0LCBtYXRjaCwgYW55Rm91bmQsCgkJaXNYTUxGaWx0ZXIgPSBzZXQgJiYgc2V0WzBdICYmIGlzWE1MKHNldFswXSk7CgoJd2hpbGUgKCBleHByICYmIHNldC5sZW5ndGggKSB7CgkJZm9yICggdmFyIHR5cGUgaW4gRXhwci5maWx0ZXIgKSB7CgkJCWlmICggKG1hdGNoID0gRXhwci5tYXRjaFsgdHlwZSBdLmV4ZWMoIGV4cHIgKSkgIT0gbnVsbCApIHsKCQkJCXZhciBmaWx0ZXIgPSBFeHByLmZpbHRlclsgdHlwZSBdLCBmb3VuZCwgaXRlbTsKCQkJCWFueUZvdW5kID0gZmFsc2U7CgoJCQkJaWYgKCBjdXJMb29wID09IHJlc3VsdCApIHsKCQkJCQlyZXN1bHQgPSBbXTsKCQkJCX0KCgkJCQlpZiAoIEV4cHIucHJlRmlsdGVyWyB0eXBlIF0gKSB7CgkJCQkJbWF0Y2ggPSBFeHByLnByZUZpbHRlclsgdHlwZSBdKCBtYXRjaCwgY3VyTG9vcCwgaW5wbGFjZSwgcmVzdWx0LCBub3QsIGlzWE1MRmlsdGVyICk7CgoJCQkJCWlmICggIW1hdGNoICkgewoJCQkJCQlhbnlGb3VuZCA9IGZvdW5kID0gdHJ1ZTsKCQkJCQl9IGVsc2UgaWYgKCBtYXRjaCA9PT0gdHJ1ZSApIHsKCQkJCQkJY29udGludWU7CgkJCQkJfQoJCQkJfQoKCQkJCWlmICggbWF0Y2ggKSB7CgkJCQkJZm9yICggdmFyIGkgPSAwOyAoaXRlbSA9IGN1ckxvb3BbaV0pICE9IG51bGw7IGkrKyApIHsKCQkJCQkJaWYgKCBpdGVtICkgewoJCQkJCQkJZm91bmQgPSBmaWx0ZXIoIGl0ZW0sIG1hdGNoLCBpLCBjdXJMb29wICk7CgkJCQkJCQl2YXIgcGFzcyA9IG5vdCBeICEhZm91bmQ7CgoJCQkJCQkJaWYgKCBpbnBsYWNlICYmIGZvdW5kICE9IG51bGwgKSB7CgkJCQkJCQkJaWYgKCBwYXNzICkgewoJCQkJCQkJCQlhbnlGb3VuZCA9IHRydWU7CgkJCQkJCQkJfSBlbHNlIHsKCQkJCQkJCQkJY3VyTG9vcFtpXSA9IGZhbHNlOwoJCQkJCQkJCX0KCQkJCQkJCX0gZWxzZSBpZiAoIHBhc3MgKSB7CgkJCQkJCQkJcmVzdWx0LnB1c2goIGl0ZW0gKTsKCQkJCQkJCQlhbnlGb3VuZCA9IHRydWU7CgkJCQkJCQl9CgkJCQkJCX0KCQkJCQl9CgkJCQl9CgoJCQkJaWYgKCBmb3VuZCAhPT0gdW5kZWZpbmVkICkgewoJCQkJCWlmICggIWlucGxhY2UgKSB7CgkJCQkJCWN1ckxvb3AgPSByZXN1bHQ7CgkJCQkJfQoKCQkJCQlleHByID0gZXhwci5yZXBsYWNlKCBFeHByLm1hdGNoWyB0eXBlIF0sICIiICk7CgoJCQkJCWlmICggIWFueUZvdW5kICkgewoJCQkJCQlyZXR1cm4gW107CgkJCQkJfQoKCQkJCQlicmVhazsKCQkJCX0KCQkJfQoJCX0KCgkJaWYgKCBleHByID09IG9sZCApIHsKCQkJaWYgKCBhbnlGb3VuZCA9PSBudWxsICkgewoJCQkJdGhyb3cgIlN5bnRheCBlcnJvciwgdW5yZWNvZ25pemVkIGV4cHJlc3Npb246ICIgKyBleHByOwoJCQl9IGVsc2UgewoJCQkJYnJlYWs7CgkJCX0KCQl9CgoJCW9sZCA9IGV4cHI7Cgl9CgoJcmV0dXJuIGN1ckxvb3A7Cn07Cgp2YXIgRXhwciA9IFNpenpsZS5zZWxlY3RvcnMgPSB7CglvcmRlcjogWyAiSUQiLCAiTkFNRSIsICJUQUciIF0sCgltYXRjaDogewoJCUlEOiAvIygoPzpbXHdcdTAwYzAtXHVGRkZGLV18XFwuKSspLywKCQlDTEFTUzogL1wuKCg/Oltcd1x1MDBjMC1cdUZGRkYtXXxcXC4pKykvLAoJCU5BTUU6IC9cW25hbWU9WyciXSooKD86W1x3XHUwMGMwLVx1RkZGRi1dfFxcLikrKVsnIl0qXF0vLAoJCUFUVFI6IC9cW1xzKigoPzpbXHdcdTAwYzAtXHVGRkZGLV18XFwuKSspXHMqKD86KFxTPz0pXHMqKFsnIl0qKSguKj8pXDN8KVxzKlxdLywKCQlUQUc6IC9eKCg/Oltcd1x1MDBjMC1cdUZGRkZcKi1dfFxcLikrKS8sCgkJQ0hJTEQ6IC86KG9ubHl8bnRofGxhc3R8Zmlyc3QpLWNoaWxkKD86XCgoZXZlbnxvZGR8W1xkbistXSopXCkpPy8sCgkJUE9TOiAvOihudGh8ZXF8Z3R8bHR8Zmlyc3R8bGFzdHxldmVufG9kZCkoPzpcKChcZCopXCkpPyg/PVteLV18JCkvLAoJCVBTRVVETzogLzooKD86W1x3XHUwMGMwLVx1RkZGRi1dfFxcLikrKSg/OlwoKFsnIl0qKSgoPzpcKFteXCldK1wpfFteXDJcKFwpXSopKylcMlwpKT8vCgl9LAoJbGVmdE1hdGNoOiB7fSwKCWF0dHJNYXA6IHsKCQkiY2xhc3MiOiAiY2xhc3NOYW1lIiwKCQkiZm9yIjogImh0bWxGb3IiCgl9LAoJYXR0ckhhbmRsZTogewoJCWhyZWY6IGZ1bmN0aW9uKGVsZW0pewoJCQlyZXR1cm4gZWxlbS5nZXRBdHRyaWJ1dGUoImhyZWYiKTsKCQl9Cgl9LAoJcmVsYXRpdmU6IHsKCQkiKyI6IGZ1bmN0aW9uKGNoZWNrU2V0LCBwYXJ0LCBpc1hNTCl7CgkJCXZhciBpc1BhcnRTdHIgPSB0eXBlb2YgcGFydCA9PT0gInN0cmluZyIsCgkJCQlpc1RhZyA9IGlzUGFydFN0ciAmJiAhL1xXLy50ZXN0KHBhcnQpLAoJCQkJaXNQYXJ0U3RyTm90VGFnID0gaXNQYXJ0U3RyICYmICFpc1RhZzsKCgkJCWlmICggaXNUYWcgJiYgIWlzWE1MICkgewoJCQkJcGFydCA9IHBhcnQudG9VcHBlckNhc2UoKTsKCQkJfQoKCQkJZm9yICggdmFyIGkgPSAwLCBsID0gY2hlY2tTZXQubGVuZ3RoLCBlbGVtOyBpIDwgbDsgaSsrICkgewoJCQkJaWYgKCAoZWxlbSA9IGNoZWNrU2V0W2ldKSApIHsKCQkJCQl3aGlsZSAoIChlbGVtID0gZWxlbS5wcmV2aW91c1NpYmxpbmcpICYmIGVsZW0ubm9kZVR5cGUgIT09IDEgKSB7fQoKCQkJCQljaGVja1NldFtpXSA9IGlzUGFydFN0ck5vdFRhZyB8fCBlbGVtICYmIGVsZW0ubm9kZU5hbWUgPT09IHBhcnQgPwoJCQkJCQllbGVtIHx8IGZhbHNlIDoKCQkJCQkJZWxlbSA9PT0gcGFydDsKCQkJCX0KCQkJfQoKCQkJaWYgKCBpc1BhcnRTdHJOb3RUYWcgKSB7CgkJCQlTaXp6bGUuZmlsdGVyKCBwYXJ0LCBjaGVja1NldCwgdHJ1ZSApOwoJCQl9CgkJfSwKCQkiPiI6IGZ1bmN0aW9uKGNoZWNrU2V0LCBwYXJ0LCBpc1hNTCl7CgkJCXZhciBpc1BhcnRTdHIgPSB0eXBlb2YgcGFydCA9PT0gInN0cmluZyI7CgoJCQlpZiAoIGlzUGFydFN0ciAmJiAhL1xXLy50ZXN0KHBhcnQpICkgewoJCQkJcGFydCA9IGlzWE1MID8gcGFydCA6IHBhcnQudG9VcHBlckNhc2UoKTsKCgkJCQlmb3IgKCB2YXIgaSA9IDAsIGwgPSBjaGVja1NldC5sZW5ndGg7IGkgPCBsOyBpKysgKSB7CgkJCQkJdmFyIGVsZW0gPSBjaGVja1NldFtpXTsKCQkJCQlpZiAoIGVsZW0gKSB7CgkJCQkJCXZhciBwYXJlbnQgPSBlbGVtLnBhcmVudE5vZGU7CgkJCQkJCWNoZWNrU2V0W2ldID0gcGFyZW50Lm5vZGVOYW1lID09PSBwYXJ0ID8gcGFyZW50IDogZmFsc2U7CgkJCQkJfQoJCQkJfQoJCQl9IGVsc2UgewoJCQkJZm9yICggdmFyIGkgPSAwLCBsID0gY2hlY2tTZXQubGVuZ3RoOyBpIDwgbDsgaSsrICkgewoJCQkJCXZhciBlbGVtID0gY2hlY2tTZXRbaV07CgkJCQkJaWYgKCBlbGVtICkgewoJCQkJCQljaGVja1NldFtpXSA9IGlzUGFydFN0ciA/CgkJCQkJCQllbGVtLnBhcmVudE5vZGUgOgoJCQkJCQkJZWxlbS5wYXJlbnROb2RlID09PSBwYXJ0OwoJCQkJCX0KCQkJCX0KCgkJCQlpZiAoIGlzUGFydFN0ciApIHsKCQkJCQlTaXp6bGUuZmlsdGVyKCBwYXJ0LCBjaGVja1NldCwgdHJ1ZSApOwoJCQkJfQoJCQl9CgkJfSwKCQkiIjogZnVuY3Rpb24oY2hlY2tTZXQsIHBhcnQsIGlzWE1MKXsKCQkJdmFyIGRvbmVOYW1lID0gZG9uZSsrLCBjaGVja0ZuID0gZGlyQ2hlY2s7CgoJCQlpZiAoICEvXFcvLnRlc3QocGFydCkgKSB7CgkJCQl2YXIgbm9kZUNoZWNrID0gcGFydCA9IGlzWE1MID8gcGFydCA6IHBhcnQudG9VcHBlckNhc2UoKTsKCQkJCWNoZWNrRm4gPSBkaXJOb2RlQ2hlY2s7CgkJCX0KCgkJCWNoZWNrRm4oInBhcmVudE5vZGUiLCBwYXJ0LCBkb25lTmFtZSwgY2hlY2tTZXQsIG5vZGVDaGVjaywgaXNYTUwpOwoJCX0sCgkJIn4iOiBmdW5jdGlvbihjaGVja1NldCwgcGFydCwgaXNYTUwpewoJCQl2YXIgZG9uZU5hbWUgPSBkb25lKyssIGNoZWNrRm4gPSBkaXJDaGVjazsKCgkJCWlmICggdHlwZW9mIHBhcnQgPT09ICJzdHJpbmciICYmICEvXFcvLnRlc3QocGFydCkgKSB7CgkJCQl2YXIgbm9kZUNoZWNrID0gcGFydCA9IGlzWE1MID8gcGFydCA6IHBhcnQudG9VcHBlckNhc2UoKTsKCQkJCWNoZWNrRm4gPSBkaXJOb2RlQ2hlY2s7CgkJCX0KCgkJCWNoZWNrRm4oInByZXZpb3VzU2libGluZyIsIHBhcnQsIGRvbmVOYW1lLCBjaGVja1NldCwgbm9kZUNoZWNrLCBpc1hNTCk7CgkJfQoJfSwKCWZpbmQ6IHsKCQlJRDogZnVuY3Rpb24obWF0Y2gsIGNvbnRleHQsIGlzWE1MKXsKCQkJaWYgKCB0eXBlb2YgY29udGV4dC5nZXRFbGVtZW50QnlJZCAhPT0gInVuZGVmaW5lZCIgJiYgIWlzWE1MICkgewoJCQkJdmFyIG0gPSBjb250ZXh0LmdldEVsZW1lbnRCeUlkKG1hdGNoWzFdKTsKCQkJCXJldHVybiBtID8gW21dIDogW107CgkJCX0KCQl9LAoJCU5BTUU6IGZ1bmN0aW9uKG1hdGNoLCBjb250ZXh0LCBpc1hNTCl7CgkJCWlmICggdHlwZW9mIGNvbnRleHQuZ2V0RWxlbWVudHNCeU5hbWUgIT09ICJ1bmRlZmluZWQiICkgewoJCQkJdmFyIHJldCA9IFtdLCByZXN1bHRzID0gY29udGV4dC5nZXRFbGVtZW50c0J5TmFtZShtYXRjaFsxXSk7CgoJCQkJZm9yICggdmFyIGkgPSAwLCBsID0gcmVzdWx0cy5sZW5ndGg7IGkgPCBsOyBpKysgKSB7CgkJCQkJaWYgKCByZXN1bHRzW2ldLmdldEF0dHJpYnV0ZSgibmFtZSIpID09PSBtYXRjaFsxXSApIHsKCQkJCQkJcmV0LnB1c2goIHJlc3VsdHNbaV0gKTsKCQkJCQl9CgkJCQl9CgoJCQkJcmV0dXJuIHJldC5sZW5ndGggPT09IDAgPyBudWxsIDogcmV0OwoJCQl9CgkJfSwKCQlUQUc6IGZ1bmN0aW9uKG1hdGNoLCBjb250ZXh0KXsKCQkJcmV0dXJuIGNvbnRleHQuZ2V0RWxlbWVudHNCeVRhZ05hbWUobWF0Y2hbMV0pOwoJCX0KCX0sCglwcmVGaWx0ZXI6IHsKCQlDTEFTUzogZnVuY3Rpb24obWF0Y2gsIGN1ckxvb3AsIGlucGxhY2UsIHJlc3VsdCwgbm90LCBpc1hNTCl7CgkJCW1hdGNoID0gIiAiICsgbWF0Y2hbMV0ucmVwbGFjZSgvXFwvZywgIiIpICsgIiAiOwoKCQkJaWYgKCBpc1hNTCApIHsKCQkJCXJldHVybiBtYXRjaDsKCQkJfQoKCQkJZm9yICggdmFyIGkgPSAwLCBlbGVtOyAoZWxlbSA9IGN1ckxvb3BbaV0pICE9IG51bGw7IGkrKyApIHsKCQkJCWlmICggZWxlbSApIHsKCQkJCQlpZiAoIG5vdCBeIChlbGVtLmNsYXNzTmFtZSAmJiAoIiAiICsgZWxlbS5jbGFzc05hbWUgKyAiICIpLmluZGV4T2YobWF0Y2gpID49IDApICkgewoJCQkJCQlpZiAoICFpbnBsYWNlICkKCQkJCQkJCXJlc3VsdC5wdXNoKCBlbGVtICk7CgkJCQkJfSBlbHNlIGlmICggaW5wbGFjZSApIHsKCQkJCQkJY3VyTG9vcFtpXSA9IGZhbHNlOwoJCQkJCX0KCQkJCX0KCQkJfQoKCQkJcmV0dXJuIGZhbHNlOwoJCX0sCgkJSUQ6IGZ1bmN0aW9uKG1hdGNoKXsKCQkJcmV0dXJuIG1hdGNoWzFdLnJlcGxhY2UoL1xcL2csICIiKTsKCQl9LAoJCVRBRzogZnVuY3Rpb24obWF0Y2gsIGN1ckxvb3ApewoJCQlmb3IgKCB2YXIgaSA9IDA7IGN1ckxvb3BbaV0gPT09IGZhbHNlOyBpKysgKXt9CgkJCXJldHVybiBjdXJMb29wW2ldICYmIGlzWE1MKGN1ckxvb3BbaV0pID8gbWF0Y2hbMV0gOiBtYXRjaFsxXS50b1VwcGVyQ2FzZSgpOwoJCX0sCgkJQ0hJTEQ6IGZ1bmN0aW9uKG1hdGNoKXsKCQkJaWYgKCBtYXRjaFsxXSA9PSAibnRoIiApIHsKCQkJCXZhciB0ZXN0ID0gLygtPykoXGQqKW4oKD86XCt8LSk/XGQqKS8uZXhlYygKCQkJCQltYXRjaFsyXSA9PSAiZXZlbiIgJiYgIjJuIiB8fCBtYXRjaFsyXSA9PSAib2RkIiAmJiAiMm4rMSIgfHwKCQkJCQkhL1xELy50ZXN0KCBtYXRjaFsyXSApICYmICIwbisiICsgbWF0Y2hbMl0gfHwgbWF0Y2hbMl0pOwoKCQkJCW1hdGNoWzJdID0gKHRlc3RbMV0gKyAodGVzdFsyXSB8fCAxKSkgLSAwOwoJCQkJbWF0Y2hbM10gPSB0ZXN0WzNdIC0gMDsKCQkJfQoKCQkJbWF0Y2hbMF0gPSBkb25lKys7CgoJCQlyZXR1cm4gbWF0Y2g7CgkJfSwKCQlBVFRSOiBmdW5jdGlvbihtYXRjaCwgY3VyTG9vcCwgaW5wbGFjZSwgcmVzdWx0LCBub3QsIGlzWE1MKXsKCQkJdmFyIG5hbWUgPSBtYXRjaFsxXS5yZXBsYWNlKC9cXC9nLCAiIik7CgoJCQlpZiAoICFpc1hNTCAmJiBFeHByLmF0dHJNYXBbbmFtZV0gKSB7CgkJCQltYXRjaFsxXSA9IEV4cHIuYXR0ck1hcFtuYW1lXTsKCQkJfQoKCQkJaWYgKCBtYXRjaFsyXSA9PT0gIn49IiApIHsKCQkJCW1hdGNoWzRdID0gIiAiICsgbWF0Y2hbNF0gKyAiICI7CgkJCX0KCgkJCXJldHVybiBtYXRjaDsKCQl9LAoJCVBTRVVETzogZnVuY3Rpb24obWF0Y2gsIGN1ckxvb3AsIGlucGxhY2UsIHJlc3VsdCwgbm90KXsKCQkJaWYgKCBtYXRjaFsxXSA9PT0gIm5vdCIgKSB7CgkJCQlpZiAoICggY2h1bmtlci5leGVjKG1hdGNoWzNdKSB8fCAiIiApLmxlbmd0aCA+IDEgfHwgL15cdy8udGVzdChtYXRjaFszXSkgKSB7CgkJCQkJbWF0Y2hbM10gPSBTaXp6bGUobWF0Y2hbM10sIG51bGwsIG51bGwsIGN1ckxvb3ApOwoJCQkJfSBlbHNlIHsKCQkJCQl2YXIgcmV0ID0gU2l6emxlLmZpbHRlcihtYXRjaFszXSwgY3VyTG9vcCwgaW5wbGFjZSwgdHJ1ZSBeIG5vdCk7CgkJCQkJaWYgKCAhaW5wbGFjZSApIHsKCQkJCQkJcmVzdWx0LnB1c2guYXBwbHkoIHJlc3VsdCwgcmV0ICk7CgkJCQkJfQoJCQkJCXJldHVybiBmYWxzZTsKCQkJCX0KCQkJfSBlbHNlIGlmICggRXhwci5tYXRjaC5QT1MudGVzdCggbWF0Y2hbMF0gKSB8fCBFeHByLm1hdGNoLkNISUxELnRlc3QoIG1hdGNoWzBdICkgKSB7CgkJCQlyZXR1cm4gdHJ1ZTsKCQkJfQoKCQkJcmV0dXJuIG1hdGNoOwoJCX0sCgkJUE9TOiBmdW5jdGlvbihtYXRjaCl7CgkJCW1hdGNoLnVuc2hpZnQoIHRydWUgKTsKCQkJcmV0dXJuIG1hdGNoOwoJCX0KCX0sCglmaWx0ZXJzOiB7CgkJZW5hYmxlZDogZnVuY3Rpb24oZWxlbSl7CgkJCXJldHVybiBlbGVtLmRpc2FibGVkID09PSBmYWxzZSAmJiBlbGVtLnR5cGUgIT09ICJoaWRkZW4iOwoJCX0sCgkJZGlzYWJsZWQ6IGZ1bmN0aW9uKGVsZW0pewoJCQlyZXR1cm4gZWxlbS5kaXNhYmxlZCA9PT0gdHJ1ZTsKCQl9LAoJCWNoZWNrZWQ6IGZ1bmN0aW9uKGVsZW0pewoJCQlyZXR1cm4gZWxlbS5jaGVja2VkID09PSB0cnVlOwoJCX0sCgkJc2VsZWN0ZWQ6IGZ1bmN0aW9uKGVsZW0pewoJCQllbGVtLnBhcmVudE5vZGUuc2VsZWN0ZWRJbmRleDsKCQkJcmV0dXJuIGVsZW0uc2VsZWN0ZWQgPT09IHRydWU7CgkJfSwKCQlwYXJlbnQ6IGZ1bmN0aW9uKGVsZW0pewoJCQlyZXR1cm4gISFlbGVtLmZpcnN0Q2hpbGQ7CgkJfSwKCQllbXB0eTogZnVuY3Rpb24oZWxlbSl7CgkJCXJldHVybiAhZWxlbS5maXJzdENoaWxkOwoJCX0sCgkJaGFzOiBmdW5jdGlvbihlbGVtLCBpLCBtYXRjaCl7CgkJCXJldHVybiAhIVNpenpsZSggbWF0Y2hbM10sIGVsZW0gKS5sZW5ndGg7CgkJfSwKCQloZWFkZXI6IGZ1bmN0aW9uKGVsZW0pewoJCQlyZXR1cm4gL2hcZC9pLnRlc3QoIGVsZW0ubm9kZU5hbWUgKTsKCQl9LAoJCXRleHQ6IGZ1bmN0aW9uKGVsZW0pewoJCQlyZXR1cm4gInRleHQiID09PSBlbGVtLnR5cGU7CgkJfSwKCQlyYWRpbzogZnVuY3Rpb24oZWxlbSl7CgkJCXJldHVybiAicmFkaW8iID09PSBlbGVtLnR5cGU7CgkJfSwKCQljaGVja2JveDogZnVuY3Rpb24oZWxlbSl7CgkJCXJldHVybiAiY2hlY2tib3giID09PSBlbGVtLnR5cGU7CgkJfSwKCQlmaWxlOiBmdW5jdGlvbihlbGVtKXsKCQkJcmV0dXJuICJmaWxlIiA9PT0gZWxlbS50eXBlOwoJCX0sCgkJcGFzc3dvcmQ6IGZ1bmN0aW9uKGVsZW0pewoJCQlyZXR1cm4gInBhc3N3b3JkIiA9PT0gZWxlbS50eXBlOwoJCX0sCgkJc3VibWl0OiBmdW5jdGlvbihlbGVtKXsKCQkJcmV0dXJuICJzdWJtaXQiID09PSBlbGVtLnR5cGU7CgkJfSwKCQlpbWFnZTogZnVuY3Rpb24oZWxlbSl7CgkJCXJldHVybiAiaW1hZ2UiID09PSBlbGVtLnR5cGU7CgkJfSwKCQlyZXNldDogZnVuY3Rpb24oZWxlbSl7CgkJCXJldHVybiAicmVzZXQiID09PSBlbGVtLnR5cGU7CgkJfSwKCQlidXR0b246IGZ1bmN0aW9uKGVsZW0pewoJCQlyZXR1cm4gImJ1dHRvbiIgPT09IGVsZW0udHlwZSB8fCBlbGVtLm5vZGVOYW1lLnRvVXBwZXJDYXNlKCkgPT09ICJCVVRUT04iOwoJCX0sCgkJaW5wdXQ6IGZ1bmN0aW9uKGVsZW0pewoJCQlyZXR1cm4gL2lucHV0fHNlbGVjdHx0ZXh0YXJlYXxidXR0b24vaS50ZXN0KGVsZW0ubm9kZU5hbWUpOwoJCX0KCX0sCglzZXRGaWx0ZXJzOiB7CgkJZmlyc3Q6IGZ1bmN0aW9uKGVsZW0sIGkpewoJCQlyZXR1cm4gaSA9PT0gMDsKCQl9LAoJCWxhc3Q6IGZ1bmN0aW9uKGVsZW0sIGksIG1hdGNoLCBhcnJheSl7CgkJCXJldHVybiBpID09PSBhcnJheS5sZW5ndGggLSAxOwoJCX0sCgkJZXZlbjogZnVuY3Rpb24oZWxlbSwgaSl7CgkJCXJldHVybiBpICUgMiA9PT0gMDsKCQl9LAoJCW9kZDogZnVuY3Rpb24oZWxlbSwgaSl7CgkJCXJldHVybiBpICUgMiA9PT0gMTsKCQl9LAoJCWx0OiBmdW5jdGlvbihlbGVtLCBpLCBtYXRjaCl7CgkJCXJldHVybiBpIDwgbWF0Y2hbM10gLSAwOwoJCX0sCgkJZ3Q6IGZ1bmN0aW9uKGVsZW0sIGksIG1hdGNoKXsKCQkJcmV0dXJuIGkgPiBtYXRjaFszXSAtIDA7CgkJfSwKCQludGg6IGZ1bmN0aW9uKGVsZW0sIGksIG1hdGNoKXsKCQkJcmV0dXJuIG1hdGNoWzNdIC0gMCA9PSBpOwoJCX0sCgkJZXE6IGZ1bmN0aW9uKGVsZW0sIGksIG1hdGNoKXsKCQkJcmV0dXJuIG1hdGNoWzNdIC0gMCA9PSBpOwoJCX0KCX0sCglmaWx0ZXI6IHsKCQlQU0VVRE86IGZ1bmN0aW9uKGVsZW0sIG1hdGNoLCBpLCBhcnJheSl7CgkJCXZhciBuYW1lID0gbWF0Y2hbMV0sIGZpbHRlciA9IEV4cHIuZmlsdGVyc1sgbmFtZSBdOwoKCQkJaWYgKCBmaWx0ZXIgKSB7CgkJCQlyZXR1cm4gZmlsdGVyKCBlbGVtLCBpLCBtYXRjaCwgYXJyYXkgKTsKCQkJfSBlbHNlIGlmICggbmFtZSA9PT0gImNvbnRhaW5zIiApIHsKCQkJCXJldHVybiAoZWxlbS50ZXh0Q29udGVudCB8fCBlbGVtLmlubmVyVGV4dCB8fCAiIikuaW5kZXhPZihtYXRjaFszXSkgPj0gMDsKCQkJfSBlbHNlIGlmICggbmFtZSA9PT0gIm5vdCIgKSB7CgkJCQl2YXIgbm90ID0gbWF0Y2hbM107CgoJCQkJZm9yICggdmFyIGkgPSAwLCBsID0gbm90Lmxlbmd0aDsgaSA8IGw7IGkrKyApIHsKCQkJCQlpZiAoIG5vdFtpXSA9PT0gZWxlbSApIHsKCQkJCQkJcmV0dXJuIGZhbHNlOwoJCQkJCX0KCQkJCX0KCgkJCQlyZXR1cm4gdHJ1ZTsKCQkJfQoJCX0sCgkJQ0hJTEQ6IGZ1bmN0aW9uKGVsZW0sIG1hdGNoKXsKCQkJdmFyIHR5cGUgPSBtYXRjaFsxXSwgbm9kZSA9IGVsZW07CgkJCXN3aXRjaCAodHlwZSkgewoJCQkJY2FzZSAnb25seSc6CgkJCQljYXNlICdmaXJzdCc6CgkJCQkJd2hpbGUgKCAobm9kZSA9IG5vZGUucHJldmlvdXNTaWJsaW5nKSApICB7CgkJCQkJCWlmICggbm9kZS5ub2RlVHlwZSA9PT0gMSApIHJldHVybiBmYWxzZTsKCQkJCQl9CgkJCQkJaWYgKCB0eXBlID09ICdmaXJzdCcpIHJldHVybiB0cnVlOwoJCQkJCW5vZGUgPSBlbGVtOwoJCQkJY2FzZSAnbGFzdCc6CgkJCQkJd2hpbGUgKCAobm9kZSA9IG5vZGUubmV4dFNpYmxpbmcpICkgIHsKCQkJCQkJaWYgKCBub2RlLm5vZGVUeXBlID09PSAxICkgcmV0dXJuIGZhbHNlOwoJCQkJCX0KCQkJCQlyZXR1cm4gdHJ1ZTsKCQkJCWNhc2UgJ250aCc6CgkJCQkJdmFyIGZpcnN0ID0gbWF0Y2hbMl0sIGxhc3QgPSBtYXRjaFszXTsKCgkJCQkJaWYgKCBmaXJzdCA9PSAxICYmIGxhc3QgPT0gMCApIHsKCQkJCQkJcmV0dXJuIHRydWU7CgkJCQkJfQoKCQkJCQl2YXIgZG9uZU5hbWUgPSBtYXRjaFswXSwKCQkJCQkJcGFyZW50ID0gZWxlbS5wYXJlbnROb2RlOwoKCQkJCQlpZiAoIHBhcmVudCAmJiAocGFyZW50LnNpemNhY2hlICE9PSBkb25lTmFtZSB8fCAhZWxlbS5ub2RlSW5kZXgpICkgewoJCQkJCQl2YXIgY291bnQgPSAwOwoJCQkJCQlmb3IgKCBub2RlID0gcGFyZW50LmZpcnN0Q2hpbGQ7IG5vZGU7IG5vZGUgPSBub2RlLm5leHRTaWJsaW5nICkgewoJCQkJCQkJaWYgKCBub2RlLm5vZGVUeXBlID09PSAxICkgewoJCQkJCQkJCW5vZGUubm9kZUluZGV4ID0gKytjb3VudDsKCQkJCQkJCX0KCQkJCQkJfQoJCQkJCQlwYXJlbnQuc2l6Y2FjaGUgPSBkb25lTmFtZTsKCQkJCQl9CgoJCQkJCXZhciBkaWZmID0gZWxlbS5ub2RlSW5kZXggLSBsYXN0OwoJCQkJCWlmICggZmlyc3QgPT0gMCApIHsKCQkJCQkJcmV0dXJuIGRpZmYgPT0gMDsKCQkJCQl9IGVsc2UgewoJCQkJCQlyZXR1cm4gKCBkaWZmICUgZmlyc3QgPT0gMCAmJiBkaWZmIC8gZmlyc3QgPj0gMCApOwoJCQkJCX0KCQkJfQoJCX0sCgkJSUQ6IGZ1bmN0aW9uKGVsZW0sIG1hdGNoKXsKCQkJcmV0dXJuIGVsZW0ubm9kZVR5cGUgPT09IDEgJiYgZWxlbS5nZXRBdHRyaWJ1dGUoImlkIikgPT09IG1hdGNoOwoJCX0sCgkJVEFHOiBmdW5jdGlvbihlbGVtLCBtYXRjaCl7CgkJCXJldHVybiAobWF0Y2ggPT09ICIqIiAmJiBlbGVtLm5vZGVUeXBlID09PSAxKSB8fCBlbGVtLm5vZGVOYW1lID09PSBtYXRjaDsKCQl9LAoJCUNMQVNTOiBmdW5jdGlvbihlbGVtLCBtYXRjaCl7CgkJCXJldHVybiAoIiAiICsgKGVsZW0uY2xhc3NOYW1lIHx8IGVsZW0uZ2V0QXR0cmlidXRlKCJjbGFzcyIpKSArICIgIikKCQkJCS5pbmRleE9mKCBtYXRjaCApID4gLTE7CgkJfSwKCQlBVFRSOiBmdW5jdGlvbihlbGVtLCBtYXRjaCl7CgkJCXZhciBuYW1lID0gbWF0Y2hbMV0sCgkJCQlyZXN1bHQgPSBFeHByLmF0dHJIYW5kbGVbIG5hbWUgXSA/CgkJCQkJRXhwci5hdHRySGFuZGxlWyBuYW1lIF0oIGVsZW0gKSA6CgkJCQkJZWxlbVsgbmFtZSBdICE9IG51bGwgPwoJCQkJCQllbGVtWyBuYW1lIF0gOgoJCQkJCQllbGVtLmdldEF0dHJpYnV0ZSggbmFtZSApLAoJCQkJdmFsdWUgPSByZXN1bHQgKyAiIiwKCQkJCXR5cGUgPSBtYXRjaFsyXSwKCQkJCWNoZWNrID0gbWF0Y2hbNF07CgoJCQlyZXR1cm4gcmVzdWx0ID09IG51bGwgPwoJCQkJdHlwZSA9PT0gIiE9IiA6CgkJCQl0eXBlID09PSAiPSIgPwoJCQkJdmFsdWUgPT09IGNoZWNrIDoKCQkJCXR5cGUgPT09ICIqPSIgPwoJCQkJdmFsdWUuaW5kZXhPZihjaGVjaykgPj0gMCA6CgkJCQl0eXBlID09PSAifj0iID8KCQkJCSgiICIgKyB2YWx1ZSArICIgIikuaW5kZXhPZihjaGVjaykgPj0gMCA6CgkJCQkhY2hlY2sgPwoJCQkJdmFsdWUgJiYgcmVzdWx0ICE9PSBmYWxzZSA6CgkJCQl0eXBlID09PSAiIT0iID8KCQkJCXZhbHVlICE9IGNoZWNrIDoKCQkJCXR5cGUgPT09ICJePSIgPwoJCQkJdmFsdWUuaW5kZXhPZihjaGVjaykgPT09IDAgOgoJCQkJdHlwZSA9PT0gIiQ9IiA/CgkJCQl2YWx1ZS5zdWJzdHIodmFsdWUubGVuZ3RoIC0gY2hlY2subGVuZ3RoKSA9PT0gY2hlY2sgOgoJCQkJdHlwZSA9PT0gInw9IiA/CgkJCQl2YWx1ZSA9PT0gY2hlY2sgfHwgdmFsdWUuc3Vic3RyKDAsIGNoZWNrLmxlbmd0aCArIDEpID09PSBjaGVjayArICItIiA6CgkJCQlmYWxzZTsKCQl9LAoJCVBPUzogZnVuY3Rpb24oZWxlbSwgbWF0Y2gsIGksIGFycmF5KXsKCQkJdmFyIG5hbWUgPSBtYXRjaFsyXSwgZmlsdGVyID0gRXhwci5zZXRGaWx0ZXJzWyBuYW1lIF07CgoJCQlpZiAoIGZpbHRlciApIHsKCQkJCXJldHVybiBmaWx0ZXIoIGVsZW0sIGksIG1hdGNoLCBhcnJheSApOwoJCQl9CgkJfQoJfQp9OwoKdmFyIG9yaWdQT1MgPSBFeHByLm1hdGNoLlBPUzsKCmZvciAoIHZhciB0eXBlIGluIEV4cHIubWF0Y2ggKSB7CglFeHByLm1hdGNoWyB0eXBlIF0gPSBuZXcgUmVnRXhwKCBFeHByLm1hdGNoWyB0eXBlIF0uc291cmNlICsgLyg/IVteXFtdKlxdKSg/IVteXChdKlwpKS8uc291cmNlICk7CglFeHByLmxlZnRNYXRjaFsgdHlwZSBdID0gbmV3IFJlZ0V4cCggLyheKD86LnxccnxcbikqPykvLnNvdXJjZSArIEV4cHIubWF0Y2hbIHR5cGUgXS5zb3VyY2UgKTsKfQoKdmFyIG1ha2VBcnJheSA9IGZ1bmN0aW9uKGFycmF5LCByZXN1bHRzKSB7CglhcnJheSA9IEFycmF5LnByb3RvdHlwZS5zbGljZS5jYWxsKCBhcnJheSwgMCApOwoKCWlmICggcmVzdWx0cyApIHsKCQlyZXN1bHRzLnB1c2guYXBwbHkoIHJlc3VsdHMsIGFycmF5ICk7CgkJcmV0dXJuIHJlc3VsdHM7Cgl9CgoJcmV0dXJuIGFycmF5Owp9OwoKdHJ5IHsKCUFycmF5LnByb3RvdHlwZS5zbGljZS5jYWxsKCBkb2N1bWVudC5kb2N1bWVudEVsZW1lbnQuY2hpbGROb2RlcywgMCApOwoKfSBjYXRjaChlKXsKCW1ha2VBcnJheSA9IGZ1bmN0aW9uKGFycmF5LCByZXN1bHRzKSB7CgkJdmFyIHJldCA9IHJlc3VsdHMgfHwgW107CgoJCWlmICggdG9TdHJpbmcuY2FsbChhcnJheSkgPT09ICJbb2JqZWN0IEFycmF5XSIgKSB7CgkJCUFycmF5LnByb3RvdHlwZS5wdXNoLmFwcGx5KCByZXQsIGFycmF5ICk7CgkJfSBlbHNlIHsKCQkJaWYgKCB0eXBlb2YgYXJyYXkubGVuZ3RoID09PSAibnVtYmVyIiApIHsKCQkJCWZvciAoIHZhciBpID0gMCwgbCA9IGFycmF5Lmxlbmd0aDsgaSA8IGw7IGkrKyApIHsKCQkJCQlyZXQucHVzaCggYXJyYXlbaV0gKTsKCQkJCX0KCQkJfSBlbHNlIHsKCQkJCWZvciAoIHZhciBpID0gMDsgYXJyYXlbaV07IGkrKyApIHsKCQkJCQlyZXQucHVzaCggYXJyYXlbaV0gKTsKCQkJCX0KCQkJfQoJCX0KCgkJcmV0dXJuIHJldDsKCX07Cn0KCnZhciBzb3J0T3JkZXI7CgppZiAoIGRvY3VtZW50LmRvY3VtZW50RWxlbWVudC5jb21wYXJlRG9jdW1lbnRQb3NpdGlvbiApIHsKCXNvcnRPcmRlciA9IGZ1bmN0aW9uKCBhLCBiICkgewoJCWlmICggIWEuY29tcGFyZURvY3VtZW50UG9zaXRpb24gfHwgIWIuY29tcGFyZURvY3VtZW50UG9zaXRpb24gKSB7CgkJCWlmICggYSA9PSBiICkgewoJCQkJaGFzRHVwbGljYXRlID0gdHJ1ZTsKCQkJfQoJCQlyZXR1cm4gMDsKCQl9CgoJCXZhciByZXQgPSBhLmNvbXBhcmVEb2N1bWVudFBvc2l0aW9uKGIpICYgNCA/IC0xIDogYSA9PT0gYiA/IDAgOiAxOwoJCWlmICggcmV0ID09PSAwICkgewoJCQloYXNEdXBsaWNhdGUgPSB0cnVlOwoJCX0KCQlyZXR1cm4gcmV0OwoJfTsKfSBlbHNlIGlmICggInNvdXJjZUluZGV4IiBpbiBkb2N1bWVudC5kb2N1bWVudEVsZW1lbnQgKSB7Cglzb3J0T3JkZXIgPSBmdW5jdGlvbiggYSwgYiApIHsKCQlpZiAoICFhLnNvdXJjZUluZGV4IHx8ICFiLnNvdXJjZUluZGV4ICkgewoJCQlpZiAoIGEgPT0gYiApIHsKCQkJCWhhc0R1cGxpY2F0ZSA9IHRydWU7CgkJCX0KCQkJcmV0dXJuIDA7CgkJfQoKCQl2YXIgcmV0ID0gYS5zb3VyY2VJbmRleCAtIGIuc291cmNlSW5kZXg7CgkJaWYgKCByZXQgPT09IDAgKSB7CgkJCWhhc0R1cGxpY2F0ZSA9IHRydWU7CgkJfQoJCXJldHVybiByZXQ7Cgl9Owp9IGVsc2UgaWYgKCBkb2N1bWVudC5jcmVhdGVSYW5nZSApIHsKCXNvcnRPcmRlciA9IGZ1bmN0aW9uKCBhLCBiICkgewoJCWlmICggIWEub3duZXJEb2N1bWVudCB8fCAhYi5vd25lckRvY3VtZW50ICkgewoJCQlpZiAoIGEgPT0gYiApIHsKCQkJCWhhc0R1cGxpY2F0ZSA9IHRydWU7CgkJCX0KCQkJcmV0dXJuIDA7CgkJfQoKCQl2YXIgYVJhbmdlID0gYS5vd25lckRvY3VtZW50LmNyZWF0ZVJhbmdlKCksIGJSYW5nZSA9IGIub3duZXJEb2N1bWVudC5jcmVhdGVSYW5nZSgpOwoJCWFSYW5nZS5zZXRTdGFydChhLCAwKTsKCQlhUmFuZ2Uuc2V0RW5kKGEsIDApOwoJCWJSYW5nZS5zZXRTdGFydChiLCAwKTsKCQliUmFuZ2Uuc2V0RW5kKGIsIDApOwoJCXZhciByZXQgPSBhUmFuZ2UuY29tcGFyZUJvdW5kYXJ5UG9pbnRzKFJhbmdlLlNUQVJUX1RPX0VORCwgYlJhbmdlKTsKCQlpZiAoIHJldCA9PT0gMCApIHsKCQkJaGFzRHVwbGljYXRlID0gdHJ1ZTsKCQl9CgkJcmV0dXJuIHJldDsKCX07Cn0KCihmdW5jdGlvbigpewoJdmFyIGZvcm0gPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCJkaXYiKSwKCQlpZCA9ICJzY3JpcHQiICsgKG5ldyBEYXRlKS5nZXRUaW1lKCk7Cglmb3JtLmlubmVySFRNTCA9ICI8YSBuYW1lPSciICsgaWQgKyAiJy8+IjsKCgl2YXIgcm9vdCA9IGRvY3VtZW50LmRvY3VtZW50RWxlbWVudDsKCXJvb3QuaW5zZXJ0QmVmb3JlKCBmb3JtLCByb290LmZpcnN0Q2hpbGQgKTsKCglpZiAoICEhZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoIGlkICkgKSB7CgkJRXhwci5maW5kLklEID0gZnVuY3Rpb24obWF0Y2gsIGNvbnRleHQsIGlzWE1MKXsKCQkJaWYgKCB0eXBlb2YgY29udGV4dC5nZXRFbGVtZW50QnlJZCAhPT0gInVuZGVmaW5lZCIgJiYgIWlzWE1MICkgewoJCQkJdmFyIG0gPSBjb250ZXh0LmdldEVsZW1lbnRCeUlkKG1hdGNoWzFdKTsKCQkJCXJldHVybiBtID8gbS5pZCA9PT0gbWF0Y2hbMV0gfHwgdHlwZW9mIG0uZ2V0QXR0cmlidXRlTm9kZSAhPT0gInVuZGVmaW5lZCIgJiYgbS5nZXRBdHRyaWJ1dGVOb2RlKCJpZCIpLm5vZGVWYWx1ZSA9PT0gbWF0Y2hbMV0gPyBbbV0gOiB1bmRlZmluZWQgOiBbXTsKCQkJfQoJCX07CgoJCUV4cHIuZmlsdGVyLklEID0gZnVuY3Rpb24oZWxlbSwgbWF0Y2gpewoJCQl2YXIgbm9kZSA9IHR5cGVvZiBlbGVtLmdldEF0dHJpYnV0ZU5vZGUgIT09ICJ1bmRlZmluZWQiICYmIGVsZW0uZ2V0QXR0cmlidXRlTm9kZSgiaWQiKTsKCQkJcmV0dXJuIGVsZW0ubm9kZVR5cGUgPT09IDEgJiYgbm9kZSAmJiBub2RlLm5vZGVWYWx1ZSA9PT0gbWF0Y2g7CgkJfTsKCX0KCglyb290LnJlbW92ZUNoaWxkKCBmb3JtICk7Cglyb290ID0gZm9ybSA9IG51bGw7IC8vIHJlbGVhc2UgbWVtb3J5IGluIElFCn0pKCk7CgooZnVuY3Rpb24oKXsKCgl2YXIgZGl2ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgiZGl2Iik7CglkaXYuYXBwZW5kQ2hpbGQoIGRvY3VtZW50LmNyZWF0ZUNvbW1lbnQoIiIpICk7CgoJaWYgKCBkaXYuZ2V0RWxlbWVudHNCeVRhZ05hbWUoIioiKS5sZW5ndGggPiAwICkgewoJCUV4cHIuZmluZC5UQUcgPSBmdW5jdGlvbihtYXRjaCwgY29udGV4dCl7CgkJCXZhciByZXN1bHRzID0gY29udGV4dC5nZXRFbGVtZW50c0J5VGFnTmFtZShtYXRjaFsxXSk7CgoJCQlpZiAoIG1hdGNoWzFdID09PSAiKiIgKSB7CgkJCQl2YXIgdG1wID0gW107CgoJCQkJZm9yICggdmFyIGkgPSAwOyByZXN1bHRzW2ldOyBpKysgKSB7CgkJCQkJaWYgKCByZXN1bHRzW2ldLm5vZGVUeXBlID09PSAxICkgewoJCQkJCQl0bXAucHVzaCggcmVzdWx0c1tpXSApOwoJCQkJCX0KCQkJCX0KCgkJCQlyZXN1bHRzID0gdG1wOwoJCQl9CgoJCQlyZXR1cm4gcmVzdWx0czsKCQl9OwoJfQoKCWRpdi5pbm5lckhUTUwgPSAiPGEgaHJlZj0nIyc+PC9hPiI7CglpZiAoIGRpdi5maXJzdENoaWxkICYmIHR5cGVvZiBkaXYuZmlyc3RDaGlsZC5nZXRBdHRyaWJ1dGUgIT09ICJ1bmRlZmluZWQiICYmCgkJCWRpdi5maXJzdENoaWxkLmdldEF0dHJpYnV0ZSgiaHJlZiIpICE9PSAiIyIgKSB7CgkJRXhwci5hdHRySGFuZGxlLmhyZWYgPSBmdW5jdGlvbihlbGVtKXsKCQkJcmV0dXJuIGVsZW0uZ2V0QXR0cmlidXRlKCJocmVmIiwgMik7CgkJfTsKCX0KCglkaXYgPSBudWxsOyAvLyByZWxlYXNlIG1lbW9yeSBpbiBJRQp9KSgpOwoKaWYgKCBkb2N1bWVudC5xdWVyeVNlbGVjdG9yQWxsICkgKGZ1bmN0aW9uKCl7Cgl2YXIgb2xkU2l6emxlID0gU2l6emxlLCBkaXYgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCJkaXYiKTsKCWRpdi5pbm5lckhUTUwgPSAiPHAgY2xhc3M9J1RFU1QnPjwvcD4iOwoKCWlmICggZGl2LnF1ZXJ5U2VsZWN0b3JBbGwgJiYgZGl2LnF1ZXJ5U2VsZWN0b3JBbGwoIi5URVNUIikubGVuZ3RoID09PSAwICkgewoJCXJldHVybjsKCX0KCglTaXp6bGUgPSBmdW5jdGlvbihxdWVyeSwgY29udGV4dCwgZXh0cmEsIHNlZWQpewoJCWNvbnRleHQgPSBjb250ZXh0IHx8IGRvY3VtZW50OwoKCQlpZiAoICFzZWVkICYmIGNvbnRleHQubm9kZVR5cGUgPT09IDkgJiYgIWlzWE1MKGNvbnRleHQpICkgewoJCQl0cnkgewoJCQkJcmV0dXJuIG1ha2VBcnJheSggY29udGV4dC5xdWVyeVNlbGVjdG9yQWxsKHF1ZXJ5KSwgZXh0cmEgKTsKCQkJfSBjYXRjaChlKXt9CgkJfQoKCQlyZXR1cm4gb2xkU2l6emxlKHF1ZXJ5LCBjb250ZXh0LCBleHRyYSwgc2VlZCk7Cgl9OwoKCWZvciAoIHZhciBwcm9wIGluIG9sZFNpenpsZSApIHsKCQlTaXp6bGVbIHByb3AgXSA9IG9sZFNpenpsZVsgcHJvcCBdOwoJfQoKCWRpdiA9IG51bGw7IC8vIHJlbGVhc2UgbWVtb3J5IGluIElFCn0pKCk7CgppZiAoIGRvY3VtZW50LmdldEVsZW1lbnRzQnlDbGFzc05hbWUgJiYgZG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50LmdldEVsZW1lbnRzQnlDbGFzc05hbWUgKSAoZnVuY3Rpb24oKXsKCXZhciBkaXYgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCJkaXYiKTsKCWRpdi5pbm5lckhUTUwgPSAiPGRpdiBjbGFzcz0ndGVzdCBlJz48L2Rpdj48ZGl2IGNsYXNzPSd0ZXN0Jz48L2Rpdj4iOwoKCWlmICggZGl2LmdldEVsZW1lbnRzQnlDbGFzc05hbWUoImUiKS5sZW5ndGggPT09IDAgKQoJCXJldHVybjsKCglkaXYubGFzdENoaWxkLmNsYXNzTmFtZSA9ICJlIjsKCglpZiAoIGRpdi5nZXRFbGVtZW50c0J5Q2xhc3NOYW1lKCJlIikubGVuZ3RoID09PSAxICkKCQlyZXR1cm47CgoJRXhwci5vcmRlci5zcGxpY2UoMSwgMCwgIkNMQVNTIik7CglFeHByLmZpbmQuQ0xBU1MgPSBmdW5jdGlvbihtYXRjaCwgY29udGV4dCwgaXNYTUwpIHsKCQlpZiAoIHR5cGVvZiBjb250ZXh0LmdldEVsZW1lbnRzQnlDbGFzc05hbWUgIT09ICJ1bmRlZmluZWQiICYmICFpc1hNTCApIHsKCQkJcmV0dXJuIGNvbnRleHQuZ2V0RWxlbWVudHNCeUNsYXNzTmFtZShtYXRjaFsxXSk7CgkJfQoJfTsKCglkaXYgPSBudWxsOyAvLyByZWxlYXNlIG1lbW9yeSBpbiBJRQp9KSgpOwoKZnVuY3Rpb24gZGlyTm9kZUNoZWNrKCBkaXIsIGN1ciwgZG9uZU5hbWUsIGNoZWNrU2V0LCBub2RlQ2hlY2ssIGlzWE1MICkgewoJdmFyIHNpYkRpciA9IGRpciA9PSAicHJldmlvdXNTaWJsaW5nIiAmJiAhaXNYTUw7Cglmb3IgKCB2YXIgaSA9IDAsIGwgPSBjaGVja1NldC5sZW5ndGg7IGkgPCBsOyBpKysgKSB7CgkJdmFyIGVsZW0gPSBjaGVja1NldFtpXTsKCQlpZiAoIGVsZW0gKSB7CgkJCWlmICggc2liRGlyICYmIGVsZW0ubm9kZVR5cGUgPT09IDEgKXsKCQkJCWVsZW0uc2l6Y2FjaGUgPSBkb25lTmFtZTsKCQkJCWVsZW0uc2l6c2V0ID0gaTsKCQkJfQoJCQllbGVtID0gZWxlbVtkaXJdOwoJCQl2YXIgbWF0Y2ggPSBmYWxzZTsKCgkJCXdoaWxlICggZWxlbSApIHsKCQkJCWlmICggZWxlbS5zaXpjYWNoZSA9PT0gZG9uZU5hbWUgKSB7CgkJCQkJbWF0Y2ggPSBjaGVja1NldFtlbGVtLnNpenNldF07CgkJCQkJYnJlYWs7CgkJCQl9CgoJCQkJaWYgKCBlbGVtLm5vZGVUeXBlID09PSAxICYmICFpc1hNTCApewoJCQkJCWVsZW0uc2l6Y2FjaGUgPSBkb25lTmFtZTsKCQkJCQllbGVtLnNpenNldCA9IGk7CgkJCQl9CgoJCQkJaWYgKCBlbGVtLm5vZGVOYW1lID09PSBjdXIgKSB7CgkJCQkJbWF0Y2ggPSBlbGVtOwoJCQkJCWJyZWFrOwoJCQkJfQoKCQkJCWVsZW0gPSBlbGVtW2Rpcl07CgkJCX0KCgkJCWNoZWNrU2V0W2ldID0gbWF0Y2g7CgkJfQoJfQp9CgpmdW5jdGlvbiBkaXJDaGVjayggZGlyLCBjdXIsIGRvbmVOYW1lLCBjaGVja1NldCwgbm9kZUNoZWNrLCBpc1hNTCApIHsKCXZhciBzaWJEaXIgPSBkaXIgPT0gInByZXZpb3VzU2libGluZyIgJiYgIWlzWE1MOwoJZm9yICggdmFyIGkgPSAwLCBsID0gY2hlY2tTZXQubGVuZ3RoOyBpIDwgbDsgaSsrICkgewoJCXZhciBlbGVtID0gY2hlY2tTZXRbaV07CgkJaWYgKCBlbGVtICkgewoJCQlpZiAoIHNpYkRpciAmJiBlbGVtLm5vZGVUeXBlID09PSAxICkgewoJCQkJZWxlbS5zaXpjYWNoZSA9IGRvbmVOYW1lOwoJCQkJZWxlbS5zaXpzZXQgPSBpOwoJCQl9CgkJCWVsZW0gPSBlbGVtW2Rpcl07CgkJCXZhciBtYXRjaCA9IGZhbHNlOwoKCQkJd2hpbGUgKCBlbGVtICkgewoJCQkJaWYgKCBlbGVtLnNpemNhY2hlID09PSBkb25lTmFtZSApIHsKCQkJCQltYXRjaCA9IGNoZWNrU2V0W2VsZW0uc2l6c2V0XTsKCQkJCQlicmVhazsKCQkJCX0KCgkJCQlpZiAoIGVsZW0ubm9kZVR5cGUgPT09IDEgKSB7CgkJCQkJaWYgKCAhaXNYTUwgKSB7CgkJCQkJCWVsZW0uc2l6Y2FjaGUgPSBkb25lTmFtZTsKCQkJCQkJZWxlbS5zaXpzZXQgPSBpOwoJCQkJCX0KCQkJCQlpZiAoIHR5cGVvZiBjdXIgIT09ICJzdHJpbmciICkgewoJCQkJCQlpZiAoIGVsZW0gPT09IGN1ciApIHsKCQkJCQkJCW1hdGNoID0gdHJ1ZTsKCQkJCQkJCWJyZWFrOwoJCQkJCQl9CgoJCQkJCX0gZWxzZSBpZiAoIFNpenpsZS5maWx0ZXIoIGN1ciwgW2VsZW1dICkubGVuZ3RoID4gMCApIHsKCQkJCQkJbWF0Y2ggPSBlbGVtOwoJCQkJCQlicmVhazsKCQkJCQl9CgkJCQl9CgoJCQkJZWxlbSA9IGVsZW1bZGlyXTsKCQkJfQoKCQkJY2hlY2tTZXRbaV0gPSBtYXRjaDsKCQl9Cgl9Cn0KCnZhciBjb250YWlucyA9IGRvY3VtZW50LmNvbXBhcmVEb2N1bWVudFBvc2l0aW9uID8gIGZ1bmN0aW9uKGEsIGIpewoJcmV0dXJuIGEuY29tcGFyZURvY3VtZW50UG9zaXRpb24oYikgJiAxNjsKfSA6IGZ1bmN0aW9uKGEsIGIpewoJcmV0dXJuIGEgIT09IGIgJiYgKGEuY29udGFpbnMgPyBhLmNvbnRhaW5zKGIpIDogdHJ1ZSk7Cn07Cgp2YXIgaXNYTUwgPSBmdW5jdGlvbihlbGVtKXsKCXJldHVybiBlbGVtLm5vZGVUeXBlID09PSA5ICYmIGVsZW0uZG9jdW1lbnRFbGVtZW50Lm5vZGVOYW1lICE9PSAiSFRNTCIgfHwKCQkhIWVsZW0ub3duZXJEb2N1bWVudCAmJiBlbGVtLm93bmVyRG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50Lm5vZGVOYW1lICE9PSAiSFRNTCI7Cn07Cgp2YXIgcG9zUHJvY2VzcyA9IGZ1bmN0aW9uKHNlbGVjdG9yLCBjb250ZXh0KXsKCXZhciB0bXBTZXQgPSBbXSwgbGF0ZXIgPSAiIiwgbWF0Y2gsCgkJcm9vdCA9IGNvbnRleHQubm9kZVR5cGUgPyBbY29udGV4dF0gOiBjb250ZXh0OwoKCXdoaWxlICggKG1hdGNoID0gRXhwci5tYXRjaC5QU0VVRE8uZXhlYyggc2VsZWN0b3IgKSkgKSB7CgkJbGF0ZXIgKz0gbWF0Y2hbMF07CgkJc2VsZWN0b3IgPSBzZWxlY3Rvci5yZXBsYWNlKCBFeHByLm1hdGNoLlBTRVVETywgIiIgKTsKCX0KCglzZWxlY3RvciA9IEV4cHIucmVsYXRpdmVbc2VsZWN0b3JdID8gc2VsZWN0b3IgKyAiKiIgOiBzZWxlY3RvcjsKCglmb3IgKCB2YXIgaSA9IDAsIGwgPSByb290Lmxlbmd0aDsgaSA8IGw7IGkrKyApIHsKCQlTaXp6bGUoIHNlbGVjdG9yLCByb290W2ldLCB0bXBTZXQgKTsKCX0KCglyZXR1cm4gU2l6emxlLmZpbHRlciggbGF0ZXIsIHRtcFNldCApOwp9OwoKCndpbmRvdy5TaXp6bGUgPSBTaXp6bGU7Cgp9KSgpOwoKUHJvdG90eXBlLl9vcmlnaW5hbF9wcm9wZXJ0eSA9IHdpbmRvdy5TaXp6bGU7Cgo7KGZ1bmN0aW9uKGVuZ2luZSkgewogIHZhciBleHRlbmRFbGVtZW50cyA9IFByb3RvdHlwZS5TZWxlY3Rvci5leHRlbmRFbGVtZW50czsKCiAgZnVuY3Rpb24gc2VsZWN0KHNlbGVjdG9yLCBzY29wZSkgewogICAgcmV0dXJuIGV4dGVuZEVsZW1lbnRzKGVuZ2luZShzZWxlY3Rvciwgc2NvcGUgfHwgZG9jdW1lbnQpKTsKICB9CgogIGZ1bmN0aW9uIG1hdGNoKGVsZW1lbnQsIHNlbGVjdG9yKSB7CiAgICByZXR1cm4gZW5naW5lLm1hdGNoZXMoc2VsZWN0b3IsIFtlbGVtZW50XSkubGVuZ3RoID09IDE7CiAgfQoKICBQcm90b3R5cGUuU2VsZWN0b3IuZW5naW5lID0gZW5naW5lOwogIFByb3RvdHlwZS5TZWxlY3Rvci5zZWxlY3QgPSBzZWxlY3Q7CiAgUHJvdG90eXBlLlNlbGVjdG9yLm1hdGNoID0gbWF0Y2g7Cn0pKFNpenpsZSk7Cgp3aW5kb3cuU2l6emxlID0gUHJvdG90eXBlLl9vcmlnaW5hbF9wcm9wZXJ0eTsKZGVsZXRlIFByb3RvdHlwZS5fb3JpZ2luYWxfcHJvcGVydHk7Cgp2YXIgRm9ybSA9IHsKICByZXNldDogZnVuY3Rpb24oZm9ybSkgewogICAgZm9ybSA9ICQoZm9ybSk7CiAgICBmb3JtLnJlc2V0KCk7CiAgICByZXR1cm4gZm9ybTsKICB9LAoKICBzZXJpYWxpemVFbGVtZW50czogZnVuY3Rpb24oZWxlbWVudHMsIG9wdGlvbnMpIHsKICAgIGlmICh0eXBlb2Ygb3B0aW9ucyAhPSAnb2JqZWN0Jykgb3B0aW9ucyA9IHsgaGFzaDogISFvcHRpb25zIH07CiAgICBlbHNlIGlmIChPYmplY3QuaXNVbmRlZmluZWQob3B0aW9ucy5oYXNoKSkgb3B0aW9ucy5oYXNoID0gdHJ1ZTsKICAgIHZhciBrZXksIHZhbHVlLCBzdWJtaXR0ZWQgPSBmYWxzZSwgc3VibWl0ID0gb3B0aW9ucy5zdWJtaXQsIGFjY3VtdWxhdG9yLCBpbml0aWFsOwoKICAgIGlmIChvcHRpb25zLmhhc2gpIHsKICAgICAgaW5pdGlhbCA9IHt9OwogICAgICBhY2N1bXVsYXRvciA9IGZ1bmN0aW9uKHJlc3VsdCwga2V5LCB2YWx1ZSkgewogICAgICAgIGlmIChrZXkgaW4gcmVzdWx0KSB7CiAgICAgICAgICBpZiAoIU9iamVjdC5pc0FycmF5KHJlc3VsdFtrZXldKSkgcmVzdWx0W2tleV0gPSBbcmVzdWx0W2tleV1dOwogICAgICAgICAgcmVzdWx0W2tleV0ucHVzaCh2YWx1ZSk7CiAgICAgICAgfSBlbHNlIHJlc3VsdFtrZXldID0gdmFsdWU7CiAgICAgICAgcmV0dXJuIHJlc3VsdDsKICAgICAgfTsKICAgIH0gZWxzZSB7CiAgICAgIGluaXRpYWwgPSAnJzsKICAgICAgYWNjdW11bGF0b3IgPSBmdW5jdGlvbihyZXN1bHQsIGtleSwgdmFsdWUpIHsKICAgICAgICByZXR1cm4gcmVzdWx0ICsgKHJlc3VsdCA/ICcmJyA6ICcnKSArIGVuY29kZVVSSUNvbXBvbmVudChrZXkpICsgJz0nICsgZW5jb2RlVVJJQ29tcG9uZW50KHZhbHVlKTsKICAgICAgfQogICAgfQoKICAgIHJldHVybiBlbGVtZW50cy5pbmplY3QoaW5pdGlhbCwgZnVuY3Rpb24ocmVzdWx0LCBlbGVtZW50KSB7CiAgICAgIGlmICghZWxlbWVudC5kaXNhYmxlZCAmJiBlbGVtZW50Lm5hbWUpIHsKICAgICAgICBrZXkgPSBlbGVtZW50Lm5hbWU7IHZhbHVlID0gJChlbGVtZW50KS5nZXRWYWx1ZSgpOwogICAgICAgIGlmICh2YWx1ZSAhPSBudWxsICYmIGVsZW1lbnQudHlwZSAhPSAnZmlsZScgJiYgKGVsZW1lbnQudHlwZSAhPSAnc3VibWl0JyB8fCAoIXN1Ym1pdHRlZCAmJgogICAgICAgICAgICBzdWJtaXQgIT09IGZhbHNlICYmICghc3VibWl0IHx8IGtleSA9PSBzdWJtaXQpICYmIChzdWJtaXR0ZWQgPSB0cnVlKSkpKSB7CiAgICAgICAgICByZXN1bHQgPSBhY2N1bXVsYXRvcihyZXN1bHQsIGtleSwgdmFsdWUpOwogICAgICAgIH0KICAgICAgfQogICAgICByZXR1cm4gcmVzdWx0OwogICAgfSk7CiAgfQp9OwoKRm9ybS5NZXRob2RzID0gewogIHNlcmlhbGl6ZTogZnVuY3Rpb24oZm9ybSwgb3B0aW9ucykgewogICAgcmV0dXJuIEZvcm0uc2VyaWFsaXplRWxlbWVudHMoRm9ybS5nZXRFbGVtZW50cyhmb3JtKSwgb3B0aW9ucyk7CiAgfSwKCiAgZ2V0RWxlbWVudHM6IGZ1bmN0aW9uKGZvcm0pIHsKICAgIHZhciBlbGVtZW50cyA9ICQoZm9ybSkuZ2V0RWxlbWVudHNCeVRhZ05hbWUoJyonKSwKICAgICAgICBlbGVtZW50LAogICAgICAgIGFyciA9IFsgXSwKICAgICAgICBzZXJpYWxpemVycyA9IEZvcm0uRWxlbWVudC5TZXJpYWxpemVyczsKICAgIGZvciAodmFyIGkgPSAwOyBlbGVtZW50ID0gZWxlbWVudHNbaV07IGkrKykgewogICAgICBhcnIucHVzaChlbGVtZW50KTsKICAgIH0KICAgIHJldHVybiBhcnIuaW5qZWN0KFtdLCBmdW5jdGlvbihlbGVtZW50cywgY2hpbGQpIHsKICAgICAgaWYgKHNlcmlhbGl6ZXJzW2NoaWxkLnRhZ05hbWUudG9Mb3dlckNhc2UoKV0pCiAgICAgICAgZWxlbWVudHMucHVzaChFbGVtZW50LmV4dGVuZChjaGlsZCkpOwogICAgICByZXR1cm4gZWxlbWVudHM7CiAgICB9KQogIH0sCgogIGdldElucHV0czogZnVuY3Rpb24oZm9ybSwgdHlwZU5hbWUsIG5hbWUpIHsKICAgIGZvcm0gPSAkKGZvcm0pOwogICAgdmFyIGlucHV0cyA9IGZvcm0uZ2V0RWxlbWVudHNCeVRhZ05hbWUoJ2lucHV0Jyk7CgogICAgaWYgKCF0eXBlTmFtZSAmJiAhbmFtZSkgcmV0dXJuICRBKGlucHV0cykubWFwKEVsZW1lbnQuZXh0ZW5kKTsKCiAgICBmb3IgKHZhciBpID0gMCwgbWF0Y2hpbmdJbnB1dHMgPSBbXSwgbGVuZ3RoID0gaW5wdXRzLmxlbmd0aDsgaSA8IGxlbmd0aDsgaSsrKSB7CiAgICAgIHZhciBpbnB1dCA9IGlucHV0c1tpXTsKICAgICAgaWYgKCh0eXBlTmFtZSAmJiBpbnB1dC50eXBlICE9IHR5cGVOYW1lKSB8fCAobmFtZSAmJiBpbnB1dC5uYW1lICE9IG5hbWUpKQogICAgICAgIGNvbnRpbnVlOwogICAgICBtYXRjaGluZ0lucHV0cy5wdXNoKEVsZW1lbnQuZXh0ZW5kKGlucHV0KSk7CiAgICB9CgogICAgcmV0dXJuIG1hdGNoaW5nSW5wdXRzOwogIH0sCgogIGRpc2FibGU6IGZ1bmN0aW9uKGZvcm0pIHsKICAgIGZvcm0gPSAkKGZvcm0pOwogICAgRm9ybS5nZXRFbGVtZW50cyhmb3JtKS5pbnZva2UoJ2Rpc2FibGUnKTsKICAgIHJldHVybiBmb3JtOwogIH0sCgogIGVuYWJsZTogZnVuY3Rpb24oZm9ybSkgewogICAgZm9ybSA9ICQoZm9ybSk7CiAgICBGb3JtLmdldEVsZW1lbnRzKGZvcm0pLmludm9rZSgnZW5hYmxlJyk7CiAgICByZXR1cm4gZm9ybTsKICB9LAoKICBmaW5kRmlyc3RFbGVtZW50OiBmdW5jdGlvbihmb3JtKSB7CiAgICB2YXIgZWxlbWVudHMgPSAkKGZvcm0pLmdldEVsZW1lbnRzKCkuZmluZEFsbChmdW5jdGlvbihlbGVtZW50KSB7CiAgICAgIHJldHVybiAnaGlkZGVuJyAhPSBlbGVtZW50LnR5cGUgJiYgIWVsZW1lbnQuZGlzYWJsZWQ7CiAgICB9KTsKICAgIHZhciBmaXJzdEJ5SW5kZXggPSBlbGVtZW50cy5maW5kQWxsKGZ1bmN0aW9uKGVsZW1lbnQpIHsKICAgICAgcmV0dXJuIGVsZW1lbnQuaGFzQXR0cmlidXRlKCd0YWJJbmRleCcpICYmIGVsZW1lbnQudGFiSW5kZXggPj0gMDsKICAgIH0pLnNvcnRCeShmdW5jdGlvbihlbGVtZW50KSB7IHJldHVybiBlbGVtZW50LnRhYkluZGV4IH0pLmZpcnN0KCk7CgogICAgcmV0dXJuIGZpcnN0QnlJbmRleCA/IGZpcnN0QnlJbmRleCA6IGVsZW1lbnRzLmZpbmQoZnVuY3Rpb24oZWxlbWVudCkgewogICAgICByZXR1cm4gL14oPzppbnB1dHxzZWxlY3R8dGV4dGFyZWEpJC9pLnRlc3QoZWxlbWVudC50YWdOYW1lKTsKICAgIH0pOwogIH0sCgogIGZvY3VzRmlyc3RFbGVtZW50OiBmdW5jdGlvbihmb3JtKSB7CiAgICBmb3JtID0gJChmb3JtKTsKICAgIHZhciBlbGVtZW50ID0gZm9ybS5maW5kRmlyc3RFbGVtZW50KCk7CiAgICBpZiAoZWxlbWVudCkgZWxlbWVudC5hY3RpdmF0ZSgpOwogICAgcmV0dXJuIGZvcm07CiAgfSwKCiAgcmVxdWVzdDogZnVuY3Rpb24oZm9ybSwgb3B0aW9ucykgewogICAgZm9ybSA9ICQoZm9ybSksIG9wdGlvbnMgPSBPYmplY3QuY2xvbmUob3B0aW9ucyB8fCB7IH0pOwoKICAgIHZhciBwYXJhbXMgPSBvcHRpb25zLnBhcmFtZXRlcnMsIGFjdGlvbiA9IGZvcm0ucmVhZEF0dHJpYnV0ZSgnYWN0aW9uJykgfHwgJyc7CiAgICBpZiAoYWN0aW9uLmJsYW5rKCkpIGFjdGlvbiA9IHdpbmRvdy5sb2NhdGlvbi5ocmVmOwogICAgb3B0aW9ucy5wYXJhbWV0ZXJzID0gZm9ybS5zZXJpYWxpemUodHJ1ZSk7CgogICAgaWYgKHBhcmFtcykgewogICAgICBpZiAoT2JqZWN0LmlzU3RyaW5nKHBhcmFtcykpIHBhcmFtcyA9IHBhcmFtcy50b1F1ZXJ5UGFyYW1zKCk7CiAgICAgIE9iamVjdC5leHRlbmQob3B0aW9ucy5wYXJhbWV0ZXJzLCBwYXJhbXMpOwogICAgfQoKICAgIGlmIChmb3JtLmhhc0F0dHJpYnV0ZSgnbWV0aG9kJykgJiYgIW9wdGlvbnMubWV0aG9kKQogICAgICBvcHRpb25zLm1ldGhvZCA9IGZvcm0ubWV0aG9kOwoKICAgIHJldHVybiBuZXcgQWpheC5SZXF1ZXN0KGFjdGlvbiwgb3B0aW9ucyk7CiAgfQp9OwoKLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovCgoKRm9ybS5FbGVtZW50ID0gewogIGZvY3VzOiBmdW5jdGlvbihlbGVtZW50KSB7CiAgICAkKGVsZW1lbnQpLmZvY3VzKCk7CiAgICByZXR1cm4gZWxlbWVudDsKICB9LAoKICBzZWxlY3Q6IGZ1bmN0aW9uKGVsZW1lbnQpIHsKICAgICQoZWxlbWVudCkuc2VsZWN0KCk7CiAgICByZXR1cm4gZWxlbWVudDsKICB9Cn07CgpGb3JtLkVsZW1lbnQuTWV0aG9kcyA9IHsKCiAgc2VyaWFsaXplOiBmdW5jdGlvbihlbGVtZW50KSB7CiAgICBlbGVtZW50ID0gJChlbGVtZW50KTsKICAgIGlmICghZWxlbWVudC5kaXNhYmxlZCAmJiBlbGVtZW50Lm5hbWUpIHsKICAgICAgdmFyIHZhbHVlID0gZWxlbWVudC5nZXRWYWx1ZSgpOwogICAgICBpZiAodmFsdWUgIT0gdW5kZWZpbmVkKSB7CiAgICAgICAgdmFyIHBhaXIgPSB7IH07CiAgICAgICAgcGFpcltlbGVtZW50Lm5hbWVdID0gdmFsdWU7CiAgICAgICAgcmV0dXJuIE9iamVjdC50b1F1ZXJ5U3RyaW5nKHBhaXIpOwogICAgICB9CiAgICB9CiAgICByZXR1cm4gJyc7CiAgfSwKCiAgZ2V0VmFsdWU6IGZ1bmN0aW9uKGVsZW1lbnQpIHsKICAgIGVsZW1lbnQgPSAkKGVsZW1lbnQpOwogICAgdmFyIG1ldGhvZCA9IGVsZW1lbnQudGFnTmFtZS50b0xvd2VyQ2FzZSgpOwogICAgcmV0dXJuIEZvcm0uRWxlbWVudC5TZXJpYWxpemVyc1ttZXRob2RdKGVsZW1lbnQpOwogIH0sCgogIHNldFZhbHVlOiBmdW5jdGlvbihlbGVtZW50LCB2YWx1ZSkgewogICAgZWxlbWVudCA9ICQoZWxlbWVudCk7CiAgICB2YXIgbWV0aG9kID0gZWxlbWVudC50YWdOYW1lLnRvTG93ZXJDYXNlKCk7CiAgICBGb3JtLkVsZW1lbnQuU2VyaWFsaXplcnNbbWV0aG9kXShlbGVtZW50LCB2YWx1ZSk7CiAgICByZXR1cm4gZWxlbWVudDsKICB9LAoKICBjbGVhcjogZnVuY3Rpb24oZWxlbWVudCkgewogICAgJChlbGVtZW50KS52YWx1ZSA9ICcnOwogICAgcmV0dXJuIGVsZW1lbnQ7CiAgfSwKCiAgcHJlc2VudDogZnVuY3Rpb24oZWxlbWVudCkgewogICAgcmV0dXJuICQoZWxlbWVudCkudmFsdWUgIT0gJyc7CiAgfSwKCiAgYWN0aXZhdGU6IGZ1bmN0aW9uKGVsZW1lbnQpIHsKICAgIGVsZW1lbnQgPSAkKGVsZW1lbnQpOwogICAgdHJ5IHsKICAgICAgZWxlbWVudC5mb2N1cygpOwogICAgICBpZiAoZWxlbWVudC5zZWxlY3QgJiYgKGVsZW1lbnQudGFnTmFtZS50b0xvd2VyQ2FzZSgpICE9ICdpbnB1dCcgfHwKICAgICAgICAgICEoL14oPzpidXR0b258cmVzZXR8c3VibWl0KSQvaS50ZXN0KGVsZW1lbnQudHlwZSkpKSkKICAgICAgICBlbGVtZW50LnNlbGVjdCgpOwogICAgfSBjYXRjaCAoZSkgeyB9CiAgICByZXR1cm4gZWxlbWVudDsKICB9LAoKICBkaXNhYmxlOiBmdW5jdGlvbihlbGVtZW50KSB7CiAgICBlbGVtZW50ID0gJChlbGVtZW50KTsKICAgIGVsZW1lbnQuZGlzYWJsZWQgPSB0cnVlOwogICAgcmV0dXJuIGVsZW1lbnQ7CiAgfSwKCiAgZW5hYmxlOiBmdW5jdGlvbihlbGVtZW50KSB7CiAgICBlbGVtZW50ID0gJChlbGVtZW50KTsKICAgIGVsZW1lbnQuZGlzYWJsZWQgPSBmYWxzZTsKICAgIHJldHVybiBlbGVtZW50OwogIH0KfTsKCi8qLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qLwoKdmFyIEZpZWxkID0gRm9ybS5FbGVtZW50OwoKdmFyICRGID0gRm9ybS5FbGVtZW50Lk1ldGhvZHMuZ2V0VmFsdWU7CgovKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi8KCkZvcm0uRWxlbWVudC5TZXJpYWxpemVycyA9IChmdW5jdGlvbigpIHsKICBmdW5jdGlvbiBpbnB1dChlbGVtZW50LCB2YWx1ZSkgewogICAgc3dpdGNoIChlbGVtZW50LnR5cGUudG9Mb3dlckNhc2UoKSkgewogICAgICBjYXNlICdjaGVja2JveCc6CiAgICAgIGNhc2UgJ3JhZGlvJzoKICAgICAgICByZXR1cm4gaW5wdXRTZWxlY3RvcihlbGVtZW50LCB2YWx1ZSk7CiAgICAgIGRlZmF1bHQ6CiAgICAgICAgcmV0dXJuIHZhbHVlU2VsZWN0b3IoZWxlbWVudCwgdmFsdWUpOwogICAgfQogIH0KCiAgZnVuY3Rpb24gaW5wdXRTZWxlY3RvcihlbGVtZW50LCB2YWx1ZSkgewogICAgaWYgKE9iamVjdC5pc1VuZGVmaW5lZCh2YWx1ZSkpCiAgICAgIHJldHVybiBlbGVtZW50LmNoZWNrZWQgPyBlbGVtZW50LnZhbHVlIDogbnVsbDsKICAgIGVsc2UgZWxlbWVudC5jaGVja2VkID0gISF2YWx1ZTsKICB9CgogIGZ1bmN0aW9uIHZhbHVlU2VsZWN0b3IoZWxlbWVudCwgdmFsdWUpIHsKICAgIGlmIChPYmplY3QuaXNVbmRlZmluZWQodmFsdWUpKSByZXR1cm4gZWxlbWVudC52YWx1ZTsKICAgIGVsc2UgZWxlbWVudC52YWx1ZSA9IHZhbHVlOwogIH0KCiAgZnVuY3Rpb24gc2VsZWN0KGVsZW1lbnQsIHZhbHVlKSB7CiAgICBpZiAoT2JqZWN0LmlzVW5kZWZpbmVkKHZhbHVlKSkKICAgICAgcmV0dXJuIChlbGVtZW50LnR5cGUgPT09ICdzZWxlY3Qtb25lJyA/IHNlbGVjdE9uZSA6IHNlbGVjdE1hbnkpKGVsZW1lbnQpOwoKICAgIHZhciBvcHQsIGN1cnJlbnRWYWx1ZSwgc2luZ2xlID0gIU9iamVjdC5pc0FycmF5KHZhbHVlKTsKICAgIGZvciAodmFyIGkgPSAwLCBsZW5ndGggPSBlbGVtZW50Lmxlbmd0aDsgaSA8IGxlbmd0aDsgaSsrKSB7CiAgICAgIG9wdCA9IGVsZW1lbnQub3B0aW9uc1tpXTsKICAgICAgY3VycmVudFZhbHVlID0gdGhpcy5vcHRpb25WYWx1ZShvcHQpOwogICAgICBpZiAoc2luZ2xlKSB7CiAgICAgICAgaWYgKGN1cnJlbnRWYWx1ZSA9PSB2YWx1ZSkgewogICAgICAgICAgb3B0LnNlbGVjdGVkID0gdHJ1ZTsKICAgICAgICAgIHJldHVybjsKICAgICAgICB9CiAgICAgIH0KICAgICAgZWxzZSBvcHQuc2VsZWN0ZWQgPSB2YWx1ZS5pbmNsdWRlKGN1cnJlbnRWYWx1ZSk7CiAgICB9CiAgfQoKICBmdW5jdGlvbiBzZWxlY3RPbmUoZWxlbWVudCkgewogICAgdmFyIGluZGV4ID0gZWxlbWVudC5zZWxlY3RlZEluZGV4OwogICAgcmV0dXJuIGluZGV4ID49IDAgPyBvcHRpb25WYWx1ZShlbGVtZW50Lm9wdGlvbnNbaW5kZXhdKSA6IG51bGw7CiAgfQoKICBmdW5jdGlvbiBzZWxlY3RNYW55KGVsZW1lbnQpIHsKICAgIHZhciB2YWx1ZXMsIGxlbmd0aCA9IGVsZW1lbnQubGVuZ3RoOwogICAgaWYgKCFsZW5ndGgpIHJldHVybiBudWxsOwoKICAgIGZvciAodmFyIGkgPSAwLCB2YWx1ZXMgPSBbXTsgaSA8IGxlbmd0aDsgaSsrKSB7CiAgICAgIHZhciBvcHQgPSBlbGVtZW50Lm9wdGlvbnNbaV07CiAgICAgIGlmIChvcHQuc2VsZWN0ZWQpIHZhbHVlcy5wdXNoKG9wdGlvblZhbHVlKG9wdCkpOwogICAgfQogICAgcmV0dXJuIHZhbHVlczsKICB9CgogIGZ1bmN0aW9uIG9wdGlvblZhbHVlKG9wdCkgewogICAgcmV0dXJuIEVsZW1lbnQuaGFzQXR0cmlidXRlKG9wdCwgJ3ZhbHVlJykgPyBvcHQudmFsdWUgOiBvcHQudGV4dDsKICB9CgogIHJldHVybiB7CiAgICBpbnB1dDogICAgICAgICBpbnB1dCwKICAgIGlucHV0U2VsZWN0b3I6IGlucHV0U2VsZWN0b3IsCiAgICB0ZXh0YXJlYTogICAgICB2YWx1ZVNlbGVjdG9yLAogICAgc2VsZWN0OiAgICAgICAgc2VsZWN0LAogICAgc2VsZWN0T25lOiAgICAgc2VsZWN0T25lLAogICAgc2VsZWN0TWFueTogICAgc2VsZWN0TWFueSwKICAgIG9wdGlvblZhbHVlOiAgIG9wdGlvblZhbHVlLAogICAgYnV0dG9uOiAgICAgICAgdmFsdWVTZWxlY3RvcgogIH07Cn0pKCk7CgovKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi8KCgpBYnN0cmFjdC5UaW1lZE9ic2VydmVyID0gQ2xhc3MuY3JlYXRlKFBlcmlvZGljYWxFeGVjdXRlciwgewogIGluaXRpYWxpemU6IGZ1bmN0aW9uKCRzdXBlciwgZWxlbWVudCwgZnJlcXVlbmN5LCBjYWxsYmFjaykgewogICAgJHN1cGVyKGNhbGxiYWNrLCBmcmVxdWVuY3kpOwogICAgdGhpcy5lbGVtZW50ICAgPSAkKGVsZW1lbnQpOwogICAgdGhpcy5sYXN0VmFsdWUgPSB0aGlzLmdldFZhbHVlKCk7CiAgfSwKCiAgZXhlY3V0ZTogZnVuY3Rpb24oKSB7CiAgICB2YXIgdmFsdWUgPSB0aGlzLmdldFZhbHVlKCk7CiAgICBpZiAoT2JqZWN0LmlzU3RyaW5nKHRoaXMubGFzdFZhbHVlKSAmJiBPYmplY3QuaXNTdHJpbmcodmFsdWUpID8KICAgICAgICB0aGlzLmxhc3RWYWx1ZSAhPSB2YWx1ZSA6IFN0cmluZyh0aGlzLmxhc3RWYWx1ZSkgIT0gU3RyaW5nKHZhbHVlKSkgewogICAgICB0aGlzLmNhbGxiYWNrKHRoaXMuZWxlbWVudCwgdmFsdWUpOwogICAgICB0aGlzLmxhc3RWYWx1ZSA9IHZhbHVlOwogICAgfQogIH0KfSk7CgpGb3JtLkVsZW1lbnQuT2JzZXJ2ZXIgPSBDbGFzcy5jcmVhdGUoQWJzdHJhY3QuVGltZWRPYnNlcnZlciwgewogIGdldFZhbHVlOiBmdW5jdGlvbigpIHsKICAgIHJldHVybiBGb3JtLkVsZW1lbnQuZ2V0VmFsdWUodGhpcy5lbGVtZW50KTsKICB9Cn0pOwoKRm9ybS5PYnNlcnZlciA9IENsYXNzLmNyZWF0ZShBYnN0cmFjdC5UaW1lZE9ic2VydmVyLCB7CiAgZ2V0VmFsdWU6IGZ1bmN0aW9uKCkgewogICAgcmV0dXJuIEZvcm0uc2VyaWFsaXplKHRoaXMuZWxlbWVudCk7CiAgfQp9KTsKCi8qLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qLwoKQWJzdHJhY3QuRXZlbnRPYnNlcnZlciA9IENsYXNzLmNyZWF0ZSh7CiAgaW5pdGlhbGl6ZTogZnVuY3Rpb24oZWxlbWVudCwgY2FsbGJhY2spIHsKICAgIHRoaXMuZWxlbWVudCAgPSAkKGVsZW1lbnQpOwogICAgdGhpcy5jYWxsYmFjayA9IGNhbGxiYWNrOwoKICAgIHRoaXMubGFzdFZhbHVlID0gdGhpcy5nZXRWYWx1ZSgpOwogICAgaWYgKHRoaXMuZWxlbWVudC50YWdOYW1lLnRvTG93ZXJDYXNlKCkgPT0gJ2Zvcm0nKQogICAgICB0aGlzLnJlZ2lzdGVyRm9ybUNhbGxiYWNrcygpOwogICAgZWxzZQogICAgICB0aGlzLnJlZ2lzdGVyQ2FsbGJhY2sodGhpcy5lbGVtZW50KTsKICB9LAoKICBvbkVsZW1lbnRFdmVudDogZnVuY3Rpb24oKSB7CiAgICB2YXIgdmFsdWUgPSB0aGlzLmdldFZhbHVlKCk7CiAgICBpZiAodGhpcy5sYXN0VmFsdWUgIT0gdmFsdWUpIHsKICAgICAgdGhpcy5jYWxsYmFjayh0aGlzLmVsZW1lbnQsIHZhbHVlKTsKICAgICAgdGhpcy5sYXN0VmFsdWUgPSB2YWx1ZTsKICAgIH0KICB9LAoKICByZWdpc3RlckZvcm1DYWxsYmFja3M6IGZ1bmN0aW9uKCkgewogICAgRm9ybS5nZXRFbGVtZW50cyh0aGlzLmVsZW1lbnQpLmVhY2godGhpcy5yZWdpc3RlckNhbGxiYWNrLCB0aGlzKTsKICB9LAoKICByZWdpc3RlckNhbGxiYWNrOiBmdW5jdGlvbihlbGVtZW50KSB7CiAgICBpZiAoZWxlbWVudC50eXBlKSB7CiAgICAgIHN3aXRjaCAoZWxlbWVudC50eXBlLnRvTG93ZXJDYXNlKCkpIHsKICAgICAgICBjYXNlICdjaGVja2JveCc6CiAgICAgICAgY2FzZSAncmFkaW8nOgogICAgICAgICAgRXZlbnQub2JzZXJ2ZShlbGVtZW50LCAnY2xpY2snLCB0aGlzLm9uRWxlbWVudEV2ZW50LmJpbmQodGhpcykpOwogICAgICAgICAgYnJlYWs7CiAgICAgICAgZGVmYXVsdDoKICAgICAgICAgIEV2ZW50Lm9ic2VydmUoZWxlbWVudCwgJ2NoYW5nZScsIHRoaXMub25FbGVtZW50RXZlbnQuYmluZCh0aGlzKSk7CiAgICAgICAgICBicmVhazsKICAgICAgfQogICAgfQogIH0KfSk7CgpGb3JtLkVsZW1lbnQuRXZlbnRPYnNlcnZlciA9IENsYXNzLmNyZWF0ZShBYnN0cmFjdC5FdmVudE9ic2VydmVyLCB7CiAgZ2V0VmFsdWU6IGZ1bmN0aW9uKCkgewogICAgcmV0dXJuIEZvcm0uRWxlbWVudC5nZXRWYWx1ZSh0aGlzLmVsZW1lbnQpOwogIH0KfSk7CgpGb3JtLkV2ZW50T2JzZXJ2ZXIgPSBDbGFzcy5jcmVhdGUoQWJzdHJhY3QuRXZlbnRPYnNlcnZlciwgewogIGdldFZhbHVlOiBmdW5jdGlvbigpIHsKICAgIHJldHVybiBGb3JtLnNlcmlhbGl6ZSh0aGlzLmVsZW1lbnQpOwogIH0KfSk7CihmdW5jdGlvbigpIHsKCiAgdmFyIEV2ZW50ID0gewogICAgS0VZX0JBQ0tTUEFDRTogOCwKICAgIEtFWV9UQUI6ICAgICAgIDksCiAgICBLRVlfUkVUVVJOOiAgIDEzLAogICAgS0VZX0VTQzogICAgICAyNywKICAgIEtFWV9MRUZUOiAgICAgMzcsCiAgICBLRVlfVVA6ICAgICAgIDM4LAogICAgS0VZX1JJR0hUOiAgICAzOSwKICAgIEtFWV9ET1dOOiAgICAgNDAsCiAgICBLRVlfREVMRVRFOiAgIDQ2LAogICAgS0VZX0hPTUU6ICAgICAzNiwKICAgIEtFWV9FTkQ6ICAgICAgMzUsCiAgICBLRVlfUEFHRVVQOiAgIDMzLAogICAgS0VZX1BBR0VET1dOOiAzNCwKICAgIEtFWV9JTlNFUlQ6ICAgNDUsCgogICAgY2FjaGU6IHt9CiAgfTsKCiAgdmFyIGRvY0VsID0gZG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50OwogIHZhciBNT1VTRUVOVEVSX01PVVNFTEVBVkVfRVZFTlRTX1NVUFBPUlRFRCA9ICdvbm1vdXNlZW50ZXInIGluIGRvY0VsCiAgICAmJiAnb25tb3VzZWxlYXZlJyBpbiBkb2NFbDsKCgoKICB2YXIgaXNJRUxlZ2FjeUV2ZW50ID0gZnVuY3Rpb24oZXZlbnQpIHsgcmV0dXJuIGZhbHNlOyB9OwoKICBpZiAod2luZG93LmF0dGFjaEV2ZW50KSB7CiAgICBpZiAod2luZG93LmFkZEV2ZW50TGlzdGVuZXIpIHsKICAgICAgaXNJRUxlZ2FjeUV2ZW50ID0gZnVuY3Rpb24oZXZlbnQpIHsKICAgICAgICByZXR1cm4gIShldmVudCBpbnN0YW5jZW9mIHdpbmRvdy5FdmVudCk7CiAgICAgIH07CiAgICB9IGVsc2UgewogICAgICBpc0lFTGVnYWN5RXZlbnQgPSBmdW5jdGlvbihldmVudCkgeyByZXR1cm4gdHJ1ZTsgfTsKICAgIH0KICB9CgogIHZhciBfaXNCdXR0b247CgogIGZ1bmN0aW9uIF9pc0J1dHRvbkZvckRPTUV2ZW50cyhldmVudCwgY29kZSkgewogICAgcmV0dXJuIGV2ZW50LndoaWNoID8gKGV2ZW50LndoaWNoID09PSBjb2RlICsgMSkgOiAoZXZlbnQuYnV0dG9uID09PSBjb2RlKTsKICB9CgogIHZhciBsZWdhY3lCdXR0b25NYXAgPSB7IDA6IDEsIDE6IDQsIDI6IDIgfTsKICBmdW5jdGlvbiBfaXNCdXR0b25Gb3JMZWdhY3lFdmVudHMoZXZlbnQsIGNvZGUpIHsKICAgIHJldHVybiBldmVudC5idXR0b24gPT09IGxlZ2FjeUJ1dHRvbk1hcFtjb2RlXTsKICB9CgogIGZ1bmN0aW9uIF9pc0J1dHRvbkZvcldlYktpdChldmVudCwgY29kZSkgewogICAgc3dpdGNoIChjb2RlKSB7CiAgICAgIGNhc2UgMDogcmV0dXJuIGV2ZW50LndoaWNoID09IDEgJiYgIWV2ZW50Lm1ldGFLZXk7CiAgICAgIGNhc2UgMTogcmV0dXJuIGV2ZW50LndoaWNoID09IDIgfHwgKGV2ZW50LndoaWNoID09IDEgJiYgZXZlbnQubWV0YUtleSk7CiAgICAgIGNhc2UgMjogcmV0dXJuIGV2ZW50LndoaWNoID09IDM7CiAgICAgIGRlZmF1bHQ6IHJldHVybiBmYWxzZTsKICAgIH0KICB9CgogIGlmICh3aW5kb3cuYXR0YWNoRXZlbnQpIHsKICAgIGlmICghd2luZG93LmFkZEV2ZW50TGlzdGVuZXIpIHsKICAgICAgX2lzQnV0dG9uID0gX2lzQnV0dG9uRm9yTGVnYWN5RXZlbnRzOwogICAgfSBlbHNlIHsKICAgICAgX2lzQnV0dG9uID0gZnVuY3Rpb24oZXZlbnQsIGNvZGUpIHsKICAgICAgICByZXR1cm4gaXNJRUxlZ2FjeUV2ZW50KGV2ZW50KSA/IF9pc0J1dHRvbkZvckxlZ2FjeUV2ZW50cyhldmVudCwgY29kZSkgOgogICAgICAgICBfaXNCdXR0b25Gb3JET01FdmVudHMoZXZlbnQsIGNvZGUpOwogICAgICB9CiAgICB9CiAgfSBlbHNlIGlmIChQcm90b3R5cGUuQnJvd3Nlci5XZWJLaXQpIHsKICAgIF9pc0J1dHRvbiA9IF9pc0J1dHRvbkZvcldlYktpdDsKICB9IGVsc2UgewogICAgX2lzQnV0dG9uID0gX2lzQnV0dG9uRm9yRE9NRXZlbnRzOwogIH0KCiAgZnVuY3Rpb24gaXNMZWZ0Q2xpY2soZXZlbnQpICAgeyByZXR1cm4gX2lzQnV0dG9uKGV2ZW50LCAwKSB9CgogIGZ1bmN0aW9uIGlzTWlkZGxlQ2xpY2soZXZlbnQpIHsgcmV0dXJuIF9pc0J1dHRvbihldmVudCwgMSkgfQoKICBmdW5jdGlvbiBpc1JpZ2h0Q2xpY2soZXZlbnQpICB7IHJldHVybiBfaXNCdXR0b24oZXZlbnQsIDIpIH0KCiAgZnVuY3Rpb24gZWxlbWVudChldmVudCkgewogICAgZXZlbnQgPSBFdmVudC5leHRlbmQoZXZlbnQpOwoKICAgIHZhciBub2RlID0gZXZlbnQudGFyZ2V0LCB0eXBlID0gZXZlbnQudHlwZSwKICAgICBjdXJyZW50VGFyZ2V0ID0gZXZlbnQuY3VycmVudFRhcmdldDsKCiAgICBpZiAoY3VycmVudFRhcmdldCAmJiBjdXJyZW50VGFyZ2V0LnRhZ05hbWUpIHsKICAgICAgaWYgKHR5cGUgPT09ICdsb2FkJyB8fCB0eXBlID09PSAnZXJyb3InIHx8CiAgICAgICAgKHR5cGUgPT09ICdjbGljaycgJiYgY3VycmVudFRhcmdldC50YWdOYW1lLnRvTG93ZXJDYXNlKCkgPT09ICdpbnB1dCcKICAgICAgICAgICYmIGN1cnJlbnRUYXJnZXQudHlwZSA9PT0gJ3JhZGlvJykpCiAgICAgICAgICAgIG5vZGUgPSBjdXJyZW50VGFyZ2V0OwogICAgfQoKICAgIGlmIChub2RlLm5vZGVUeXBlID09IE5vZGUuVEVYVF9OT0RFKQogICAgICBub2RlID0gbm9kZS5wYXJlbnROb2RlOwoKICAgIHJldHVybiBFbGVtZW50LmV4dGVuZChub2RlKTsKICB9CgogIGZ1bmN0aW9uIGZpbmRFbGVtZW50KGV2ZW50LCBleHByZXNzaW9uKSB7CiAgICB2YXIgZWxlbWVudCA9IEV2ZW50LmVsZW1lbnQoZXZlbnQpOwoKICAgIGlmICghZXhwcmVzc2lvbikgcmV0dXJuIGVsZW1lbnQ7CiAgICB3aGlsZSAoZWxlbWVudCkgewogICAgICBpZiAoT2JqZWN0LmlzRWxlbWVudChlbGVtZW50KSAmJiBQcm90b3R5cGUuU2VsZWN0b3IubWF0Y2goZWxlbWVudCwgZXhwcmVzc2lvbikpIHsKICAgICAgICByZXR1cm4gRWxlbWVudC5leHRlbmQoZWxlbWVudCk7CiAgICAgIH0KICAgICAgZWxlbWVudCA9IGVsZW1lbnQucGFyZW50Tm9kZTsKICAgIH0KICB9CgogIGZ1bmN0aW9uIHBvaW50ZXIoZXZlbnQpIHsKICAgIHJldHVybiB7IHg6IHBvaW50ZXJYKGV2ZW50KSwgeTogcG9pbnRlclkoZXZlbnQpIH07CiAgfQoKICBmdW5jdGlvbiBwb2ludGVyWChldmVudCkgewogICAgdmFyIGRvY0VsZW1lbnQgPSBkb2N1bWVudC5kb2N1bWVudEVsZW1lbnQsCiAgICAgYm9keSA9IGRvY3VtZW50LmJvZHkgfHwgeyBzY3JvbGxMZWZ0OiAwIH07CgogICAgcmV0dXJuIGV2ZW50LnBhZ2VYIHx8IChldmVudC5jbGllbnRYICsKICAgICAgKGRvY0VsZW1lbnQuc2Nyb2xsTGVmdCB8fCBib2R5LnNjcm9sbExlZnQpIC0KICAgICAgKGRvY0VsZW1lbnQuY2xpZW50TGVmdCB8fCAwKSk7CiAgfQoKICBmdW5jdGlvbiBwb2ludGVyWShldmVudCkgewogICAgdmFyIGRvY0VsZW1lbnQgPSBkb2N1bWVudC5kb2N1bWVudEVsZW1lbnQsCiAgICAgYm9keSA9IGRvY3VtZW50LmJvZHkgfHwgeyBzY3JvbGxUb3A6IDAgfTsKCiAgICByZXR1cm4gIGV2ZW50LnBhZ2VZIHx8IChldmVudC5jbGllbnRZICsKICAgICAgIChkb2NFbGVtZW50LnNjcm9sbFRvcCB8fCBib2R5LnNjcm9sbFRvcCkgLQogICAgICAgKGRvY0VsZW1lbnQuY2xpZW50VG9wIHx8IDApKTsKICB9CgoKICBmdW5jdGlvbiBzdG9wKGV2ZW50KSB7CiAgICBFdmVudC5leHRlbmQoZXZlbnQpOwogICAgZXZlbnQucHJldmVudERlZmF1bHQoKTsKICAgIGV2ZW50LnN0b3BQcm9wYWdhdGlvbigpOwoKICAgIGV2ZW50LnN0b3BwZWQgPSB0cnVlOwogIH0KCgogIEV2ZW50Lk1ldGhvZHMgPSB7CiAgICBpc0xlZnRDbGljazogICBpc0xlZnRDbGljaywKICAgIGlzTWlkZGxlQ2xpY2s6IGlzTWlkZGxlQ2xpY2ssCiAgICBpc1JpZ2h0Q2xpY2s6ICBpc1JpZ2h0Q2xpY2ssCgogICAgZWxlbWVudDogICAgIGVsZW1lbnQsCiAgICBmaW5kRWxlbWVudDogZmluZEVsZW1lbnQsCgogICAgcG9pbnRlcjogIHBvaW50ZXIsCiAgICBwb2ludGVyWDogcG9pbnRlclgsCiAgICBwb2ludGVyWTogcG9pbnRlclksCgogICAgc3RvcDogc3RvcAogIH07CgogIHZhciBtZXRob2RzID0gT2JqZWN0LmtleXMoRXZlbnQuTWV0aG9kcykuaW5qZWN0KHsgfSwgZnVuY3Rpb24obSwgbmFtZSkgewogICAgbVtuYW1lXSA9IEV2ZW50Lk1ldGhvZHNbbmFtZV0ubWV0aG9kaXplKCk7CiAgICByZXR1cm4gbTsKICB9KTsKCiAgaWYgKHdpbmRvdy5hdHRhY2hFdmVudCkgewogICAgZnVuY3Rpb24gX3JlbGF0ZWRUYXJnZXQoZXZlbnQpIHsKICAgICAgdmFyIGVsZW1lbnQ7CiAgICAgIHN3aXRjaCAoZXZlbnQudHlwZSkgewogICAgICAgIGNhc2UgJ21vdXNlb3Zlcic6CiAgICAgICAgY2FzZSAnbW91c2VlbnRlcic6CiAgICAgICAgICBlbGVtZW50ID0gZXZlbnQuZnJvbUVsZW1lbnQ7CiAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlICdtb3VzZW91dCc6CiAgICAgICAgY2FzZSAnbW91c2VsZWF2ZSc6CiAgICAgICAgICBlbGVtZW50ID0gZXZlbnQudG9FbGVtZW50OwogICAgICAgICAgYnJlYWs7CiAgICAgICAgZGVmYXVsdDoKICAgICAgICAgIHJldHVybiBudWxsOwogICAgICB9CiAgICAgIHJldHVybiBFbGVtZW50LmV4dGVuZChlbGVtZW50KTsKICAgIH0KCiAgICB2YXIgYWRkaXRpb25hbE1ldGhvZHMgPSB7CiAgICAgIHN0b3BQcm9wYWdhdGlvbjogZnVuY3Rpb24oKSB7IHRoaXMuY2FuY2VsQnViYmxlID0gdHJ1ZSB9LAogICAgICBwcmV2ZW50RGVmYXVsdDogIGZ1bmN0aW9uKCkgeyB0aGlzLnJldHVyblZhbHVlID0gZmFsc2UgfSwKICAgICAgaW5zcGVjdDogZnVuY3Rpb24oKSB7IHJldHVybiAnW29iamVjdCBFdmVudF0nIH0KICAgIH07CgogICAgRXZlbnQuZXh0ZW5kID0gZnVuY3Rpb24oZXZlbnQsIGVsZW1lbnQpIHsKICAgICAgaWYgKCFldmVudCkgcmV0dXJuIGZhbHNlOwoKICAgICAgaWYgKCFpc0lFTGVnYWN5RXZlbnQoZXZlbnQpKSByZXR1cm4gZXZlbnQ7CgogICAgICBpZiAoZXZlbnQuX2V4dGVuZGVkQnlQcm90b3R5cGUpIHJldHVybiBldmVudDsKICAgICAgZXZlbnQuX2V4dGVuZGVkQnlQcm90b3R5cGUgPSBQcm90b3R5cGUuZW1wdHlGdW5jdGlvbjsKCiAgICAgIHZhciBwb2ludGVyID0gRXZlbnQucG9pbnRlcihldmVudCk7CgogICAgICBPYmplY3QuZXh0ZW5kKGV2ZW50LCB7CiAgICAgICAgdGFyZ2V0OiBldmVudC5zcmNFbGVtZW50IHx8IGVsZW1lbnQsCiAgICAgICAgcmVsYXRlZFRhcmdldDogX3JlbGF0ZWRUYXJnZXQoZXZlbnQpLAogICAgICAgIHBhZ2VYOiAgcG9pbnRlci54LAogICAgICAgIHBhZ2VZOiAgcG9pbnRlci55CiAgICAgIH0pOwoKICAgICAgT2JqZWN0LmV4dGVuZChldmVudCwgbWV0aG9kcyk7CiAgICAgIE9iamVjdC5leHRlbmQoZXZlbnQsIGFkZGl0aW9uYWxNZXRob2RzKTsKCiAgICAgIHJldHVybiBldmVudDsKICAgIH07CiAgfSBlbHNlIHsKICAgIEV2ZW50LmV4dGVuZCA9IFByb3RvdHlwZS5LOwogIH0KCiAgaWYgKHdpbmRvdy5hZGRFdmVudExpc3RlbmVyKSB7CiAgICBFdmVudC5wcm90b3R5cGUgPSB3aW5kb3cuRXZlbnQucHJvdG90eXBlIHx8IGRvY3VtZW50LmNyZWF0ZUV2ZW50KCdIVE1MRXZlbnRzJykuX19wcm90b19fOwogICAgT2JqZWN0LmV4dGVuZChFdmVudC5wcm90b3R5cGUsIG1ldGhvZHMpOwogIH0KCiAgZnVuY3Rpb24gX2NyZWF0ZVJlc3BvbmRlcihlbGVtZW50LCBldmVudE5hbWUsIGhhbmRsZXIpIHsKICAgIHZhciByZWdpc3RyeSA9IEVsZW1lbnQucmV0cmlldmUoZWxlbWVudCwgJ3Byb3RvdHlwZV9ldmVudF9yZWdpc3RyeScpOwoKICAgIGlmIChPYmplY3QuaXNVbmRlZmluZWQocmVnaXN0cnkpKSB7CiAgICAgIENBQ0hFLnB1c2goZWxlbWVudCk7CiAgICAgIHJlZ2lzdHJ5ID0gRWxlbWVudC5yZXRyaWV2ZShlbGVtZW50LCAncHJvdG90eXBlX2V2ZW50X3JlZ2lzdHJ5JywgJEgoKSk7CiAgICB9CgogICAgdmFyIHJlc3BvbmRlcnNGb3JFdmVudCA9IHJlZ2lzdHJ5LmdldChldmVudE5hbWUpOwogICAgaWYgKE9iamVjdC5pc1VuZGVmaW5lZChyZXNwb25kZXJzRm9yRXZlbnQpKSB7CiAgICAgIHJlc3BvbmRlcnNGb3JFdmVudCA9IFtdOwogICAgICByZWdpc3RyeS5zZXQoZXZlbnROYW1lLCByZXNwb25kZXJzRm9yRXZlbnQpOwogICAgfQoKICAgIGlmIChyZXNwb25kZXJzRm9yRXZlbnQucGx1Y2soJ2hhbmRsZXInKS5pbmNsdWRlKGhhbmRsZXIpKSByZXR1cm4gZmFsc2U7CgogICAgdmFyIHJlc3BvbmRlcjsKICAgIGlmIChldmVudE5hbWUuaW5jbHVkZSgiOiIpKSB7CiAgICAgIHJlc3BvbmRlciA9IGZ1bmN0aW9uKGV2ZW50KSB7CiAgICAgICAgaWYgKE9iamVjdC5pc1VuZGVmaW5lZChldmVudC5ldmVudE5hbWUpKQogICAgICAgICAgcmV0dXJuIGZhbHNlOwoKICAgICAgICBpZiAoZXZlbnQuZXZlbnROYW1lICE9PSBldmVudE5hbWUpCiAgICAgICAgICByZXR1cm4gZmFsc2U7CgogICAgICAgIEV2ZW50LmV4dGVuZChldmVudCwgZWxlbWVudCk7CiAgICAgICAgaGFuZGxlci5jYWxsKGVsZW1lbnQsIGV2ZW50KTsKICAgICAgfTsKICAgIH0gZWxzZSB7CiAgICAgIGlmICghTU9VU0VFTlRFUl9NT1VTRUxFQVZFX0VWRU5UU19TVVBQT1JURUQgJiYKICAgICAgIChldmVudE5hbWUgPT09ICJtb3VzZWVudGVyIiB8fCBldmVudE5hbWUgPT09ICJtb3VzZWxlYXZlIikpIHsKICAgICAgICBpZiAoZXZlbnROYW1lID09PSAibW91c2VlbnRlciIgfHwgZXZlbnROYW1lID09PSAibW91c2VsZWF2ZSIpIHsKICAgICAgICAgIHJlc3BvbmRlciA9IGZ1bmN0aW9uKGV2ZW50KSB7CiAgICAgICAgICAgIEV2ZW50LmV4dGVuZChldmVudCwgZWxlbWVudCk7CgogICAgICAgICAgICB2YXIgcGFyZW50ID0gZXZlbnQucmVsYXRlZFRhcmdldDsKICAgICAgICAgICAgd2hpbGUgKHBhcmVudCAmJiBwYXJlbnQgIT09IGVsZW1lbnQpIHsKICAgICAgICAgICAgICB0cnkgeyBwYXJlbnQgPSBwYXJlbnQucGFyZW50Tm9kZTsgfQogICAgICAgICAgICAgIGNhdGNoKGUpIHsgcGFyZW50ID0gZWxlbWVudDsgfQogICAgICAgICAgICB9CgogICAgICAgICAgICBpZiAocGFyZW50ID09PSBlbGVtZW50KSByZXR1cm47CgogICAgICAgICAgICBoYW5kbGVyLmNhbGwoZWxlbWVudCwgZXZlbnQpOwogICAgICAgICAgfTsKICAgICAgICB9CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmVzcG9uZGVyID0gZnVuY3Rpb24oZXZlbnQpIHsKICAgICAgICAgIEV2ZW50LmV4dGVuZChldmVudCwgZWxlbWVudCk7CiAgICAgICAgICBoYW5kbGVyLmNhbGwoZWxlbWVudCwgZXZlbnQpOwogICAgICAgIH07CiAgICAgIH0KICAgIH0KCiAgICByZXNwb25kZXIuaGFuZGxlciA9IGhhbmRsZXI7CiAgICByZXNwb25kZXJzRm9yRXZlbnQucHVzaChyZXNwb25kZXIpOwogICAgcmV0dXJuIHJlc3BvbmRlcjsKICB9CgogIGZ1bmN0aW9uIF9kZXN0cm95Q2FjaGUoKSB7CiAgICBmb3IgKHZhciBpID0gMCwgbGVuZ3RoID0gQ0FDSEUubGVuZ3RoOyBpIDwgbGVuZ3RoOyBpKyspIHsKICAgICAgRXZlbnQuc3RvcE9ic2VydmluZyhDQUNIRVtpXSk7CiAgICAgIENBQ0hFW2ldID0gbnVsbDsKICAgIH0KICB9CgogIHZhciBDQUNIRSA9IFtdOwoKICBpZiAoUHJvdG90eXBlLkJyb3dzZXIuSUUpCiAgICB3aW5kb3cuYXR0YWNoRXZlbnQoJ29udW5sb2FkJywgX2Rlc3Ryb3lDYWNoZSk7CgogIGlmIChQcm90b3R5cGUuQnJvd3Nlci5XZWJLaXQpCiAgICB3aW5kb3cuYWRkRXZlbnRMaXN0ZW5lcigndW5sb2FkJywgUHJvdG90eXBlLmVtcHR5RnVuY3Rpb24sIGZhbHNlKTsKCgogIHZhciBfZ2V0RE9NRXZlbnROYW1lID0gUHJvdG90eXBlLkssCiAgICAgIHRyYW5zbGF0aW9ucyA9IHsgbW91c2VlbnRlcjogIm1vdXNlb3ZlciIsIG1vdXNlbGVhdmU6ICJtb3VzZW91dCIgfTsKCiAgaWYgKCFNT1VTRUVOVEVSX01PVVNFTEVBVkVfRVZFTlRTX1NVUFBPUlRFRCkgewogICAgX2dldERPTUV2ZW50TmFtZSA9IGZ1bmN0aW9uKGV2ZW50TmFtZSkgewogICAgICByZXR1cm4gKHRyYW5zbGF0aW9uc1tldmVudE5hbWVdIHx8IGV2ZW50TmFtZSk7CiAgICB9OwogIH0KCiAgZnVuY3Rpb24gb2JzZXJ2ZShlbGVtZW50LCBldmVudE5hbWUsIGhhbmRsZXIpIHsKICAgIGVsZW1lbnQgPSAkKGVsZW1lbnQpOwoKICAgIHZhciByZXNwb25kZXIgPSBfY3JlYXRlUmVzcG9uZGVyKGVsZW1lbnQsIGV2ZW50TmFtZSwgaGFuZGxlcik7CgogICAgaWYgKCFyZXNwb25kZXIpIHJldHVybiBlbGVtZW50OwoKICAgIGlmIChldmVudE5hbWUuaW5jbHVkZSgnOicpKSB7CiAgICAgIGlmIChlbGVtZW50LmFkZEV2ZW50TGlzdGVuZXIpCiAgICAgICAgZWxlbWVudC5hZGRFdmVudExpc3RlbmVyKCJkYXRhYXZhaWxhYmxlIiwgcmVzcG9uZGVyLCBmYWxzZSk7CiAgICAgIGVsc2UgewogICAgICAgIGVsZW1lbnQuYXR0YWNoRXZlbnQoIm9uZGF0YWF2YWlsYWJsZSIsIHJlc3BvbmRlcik7CiAgICAgICAgZWxlbWVudC5hdHRhY2hFdmVudCgib25sb3NlY2FwdHVyZSIsIHJlc3BvbmRlcik7CiAgICAgIH0KICAgIH0gZWxzZSB7CiAgICAgIHZhciBhY3R1YWxFdmVudE5hbWUgPSBfZ2V0RE9NRXZlbnROYW1lKGV2ZW50TmFtZSk7CgogICAgICBpZiAoZWxlbWVudC5hZGRFdmVudExpc3RlbmVyKQogICAgICAgIGVsZW1lbnQuYWRkRXZlbnRMaXN0ZW5lcihhY3R1YWxFdmVudE5hbWUsIHJlc3BvbmRlciwgZmFsc2UpOwogICAgICBlbHNlCiAgICAgICAgZWxlbWVudC5hdHRhY2hFdmVudCgib24iICsgYWN0dWFsRXZlbnROYW1lLCByZXNwb25kZXIpOwogICAgfQoKICAgIHJldHVybiBlbGVtZW50OwogIH0KCiAgZnVuY3Rpb24gc3RvcE9ic2VydmluZyhlbGVtZW50LCBldmVudE5hbWUsIGhhbmRsZXIpIHsKICAgIGVsZW1lbnQgPSAkKGVsZW1lbnQpOwoKICAgIHZhciByZWdpc3RyeSA9IEVsZW1lbnQucmV0cmlldmUoZWxlbWVudCwgJ3Byb3RvdHlwZV9ldmVudF9yZWdpc3RyeScpOwogICAgaWYgKCFyZWdpc3RyeSkgcmV0dXJuIGVsZW1lbnQ7CgogICAgaWYgKCFldmVudE5hbWUpIHsKICAgICAgcmVnaXN0cnkuZWFjaCggZnVuY3Rpb24ocGFpcikgewogICAgICAgIHZhciBldmVudE5hbWUgPSBwYWlyLmtleTsKICAgICAgICBzdG9wT2JzZXJ2aW5nKGVsZW1lbnQsIGV2ZW50TmFtZSk7CiAgICAgIH0pOwogICAgICByZXR1cm4gZWxlbWVudDsKICAgIH0KCiAgICB2YXIgcmVzcG9uZGVycyA9IHJlZ2lzdHJ5LmdldChldmVudE5hbWUpOwogICAgaWYgKCFyZXNwb25kZXJzKSByZXR1cm4gZWxlbWVudDsKCiAgICBpZiAoIWhhbmRsZXIpIHsKICAgICAgcmVzcG9uZGVycy5lYWNoKGZ1bmN0aW9uKHIpIHsKICAgICAgICBzdG9wT2JzZXJ2aW5nKGVsZW1lbnQsIGV2ZW50TmFtZSwgci5oYW5kbGVyKTsKICAgICAgfSk7CiAgICAgIHJldHVybiBlbGVtZW50OwogICAgfQoKICAgIHZhciBpID0gcmVzcG9uZGVycy5sZW5ndGgsIHJlc3BvbmRlcjsKICAgIHdoaWxlIChpLS0pIHsKICAgICAgaWYgKHJlc3BvbmRlcnNbaV0uaGFuZGxlciA9PT0gaGFuZGxlcikgewogICAgICAgIHJlc3BvbmRlciA9IHJlc3BvbmRlcnNbaV07CiAgICAgICAgYnJlYWs7CiAgICAgIH0KICAgIH0KICAgIGlmICghcmVzcG9uZGVyKSByZXR1cm4gZWxlbWVudDsKCiAgICBpZiAoZXZlbnROYW1lLmluY2x1ZGUoJzonKSkgewogICAgICBpZiAoZWxlbWVudC5yZW1vdmVFdmVudExpc3RlbmVyKQogICAgICAgIGVsZW1lbnQucmVtb3ZlRXZlbnRMaXN0ZW5lcigiZGF0YWF2YWlsYWJsZSIsIHJlc3BvbmRlciwgZmFsc2UpOwogICAgICBlbHNlIHsKICAgICAgICBlbGVtZW50LmRldGFjaEV2ZW50KCJvbmRhdGFhdmFpbGFibGUiLCByZXNwb25kZXIpOwogICAgICAgIGVsZW1lbnQuZGV0YWNoRXZlbnQoIm9ubG9zZWNhcHR1cmUiLCByZXNwb25kZXIpOwogICAgICB9CiAgICB9IGVsc2UgewogICAgICB2YXIgYWN0dWFsRXZlbnROYW1lID0gX2dldERPTUV2ZW50TmFtZShldmVudE5hbWUpOwogICAgICBpZiAoZWxlbWVudC5yZW1vdmVFdmVudExpc3RlbmVyKQogICAgICAgIGVsZW1lbnQucmVtb3ZlRXZlbnRMaXN0ZW5lcihhY3R1YWxFdmVudE5hbWUsIHJlc3BvbmRlciwgZmFsc2UpOwogICAgICBlbHNlCiAgICAgICAgZWxlbWVudC5kZXRhY2hFdmVudCgnb24nICsgYWN0dWFsRXZlbnROYW1lLCByZXNwb25kZXIpOwogICAgfQoKICAgIHJlZ2lzdHJ5LnNldChldmVudE5hbWUsIHJlc3BvbmRlcnMud2l0aG91dChyZXNwb25kZXIpKTsKCiAgICByZXR1cm4gZWxlbWVudDsKICB9CgogIGZ1bmN0aW9uIGZpcmUoZWxlbWVudCwgZXZlbnROYW1lLCBtZW1vLCBidWJibGUpIHsKICAgIGVsZW1lbnQgPSAkKGVsZW1lbnQpOwoKICAgIGlmIChPYmplY3QuaXNVbmRlZmluZWQoYnViYmxlKSkKICAgICAgYnViYmxlID0gdHJ1ZTsKCiAgICBpZiAoZWxlbWVudCA9PSBkb2N1bWVudCAmJiBkb2N1bWVudC5jcmVhdGVFdmVudCAmJiAhZWxlbWVudC5kaXNwYXRjaEV2ZW50KQogICAgICBlbGVtZW50ID0gZG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50OwoKICAgIHZhciBldmVudDsKICAgIGlmIChkb2N1bWVudC5jcmVhdGVFdmVudCkgewogICAgICBldmVudCA9IGRvY3VtZW50LmNyZWF0ZUV2ZW50KCdIVE1MRXZlbnRzJyk7CiAgICAgIGV2ZW50LmluaXRFdmVudCgnZGF0YWF2YWlsYWJsZScsIGJ1YmJsZSwgdHJ1ZSk7CiAgICB9IGVsc2UgewogICAgICBldmVudCA9IGRvY3VtZW50LmNyZWF0ZUV2ZW50T2JqZWN0KCk7CiAgICAgIGV2ZW50LmV2ZW50VHlwZSA9IGJ1YmJsZSA/ICdvbmRhdGFhdmFpbGFibGUnIDogJ29ubG9zZWNhcHR1cmUnOwogICAgfQoKICAgIGV2ZW50LmV2ZW50TmFtZSA9IGV2ZW50TmFtZTsKICAgIGV2ZW50Lm1lbW8gPSBtZW1vIHx8IHsgfTsKCiAgICBpZiAoZG9jdW1lbnQuY3JlYXRlRXZlbnQpCiAgICAgIGVsZW1lbnQuZGlzcGF0Y2hFdmVudChldmVudCk7CiAgICBlbHNlCiAgICAgIGVsZW1lbnQuZmlyZUV2ZW50KGV2ZW50LmV2ZW50VHlwZSwgZXZlbnQpOwoKICAgIHJldHVybiBFdmVudC5leHRlbmQoZXZlbnQpOwogIH0KCiAgRXZlbnQuSGFuZGxlciA9IENsYXNzLmNyZWF0ZSh7CiAgICBpbml0aWFsaXplOiBmdW5jdGlvbihlbGVtZW50LCBldmVudE5hbWUsIHNlbGVjdG9yLCBjYWxsYmFjaykgewogICAgICB0aGlzLmVsZW1lbnQgICA9ICQoZWxlbWVudCk7CiAgICAgIHRoaXMuZXZlbnROYW1lID0gZXZlbnROYW1lOwogICAgICB0aGlzLnNlbGVjdG9yICA9IHNlbGVjdG9yOwogICAgICB0aGlzLmNhbGxiYWNrICA9IGNhbGxiYWNrOwogICAgICB0aGlzLmhhbmRsZXIgICA9IHRoaXMuaGFuZGxlRXZlbnQuYmluZCh0aGlzKTsKICAgIH0sCgogICAgc3RhcnQ6IGZ1bmN0aW9uKCkgewogICAgICBFdmVudC5vYnNlcnZlKHRoaXMuZWxlbWVudCwgdGhpcy5ldmVudE5hbWUsIHRoaXMuaGFuZGxlcik7CiAgICAgIHJldHVybiB0aGlzOwogICAgfSwKCiAgICBzdG9wOiBmdW5jdGlvbigpIHsKICAgICAgRXZlbnQuc3RvcE9ic2VydmluZyh0aGlzLmVsZW1lbnQsIHRoaXMuZXZlbnROYW1lLCB0aGlzLmhhbmRsZXIpOwogICAgICByZXR1cm4gdGhpczsKICAgIH0sCgogICAgaGFuZGxlRXZlbnQ6IGZ1bmN0aW9uKGV2ZW50KSB7CiAgICAgIHZhciBlbGVtZW50ID0gRXZlbnQuZmluZEVsZW1lbnQoZXZlbnQsIHRoaXMuc2VsZWN0b3IpOwogICAgICBpZiAoZWxlbWVudCkgdGhpcy5jYWxsYmFjay5jYWxsKHRoaXMuZWxlbWVudCwgZXZlbnQsIGVsZW1lbnQpOwogICAgfQogIH0pOwoKICBmdW5jdGlvbiBvbihlbGVtZW50LCBldmVudE5hbWUsIHNlbGVjdG9yLCBjYWxsYmFjaykgewogICAgZWxlbWVudCA9ICQoZWxlbWVudCk7CiAgICBpZiAoT2JqZWN0LmlzRnVuY3Rpb24oc2VsZWN0b3IpICYmIE9iamVjdC5pc1VuZGVmaW5lZChjYWxsYmFjaykpIHsKICAgICAgY2FsbGJhY2sgPSBzZWxlY3Rvciwgc2VsZWN0b3IgPSBudWxsOwogICAgfQoKICAgIHJldHVybiBuZXcgRXZlbnQuSGFuZGxlcihlbGVtZW50LCBldmVudE5hbWUsIHNlbGVjdG9yLCBjYWxsYmFjaykuc3RhcnQoKTsKICB9CgogIE9iamVjdC5leHRlbmQoRXZlbnQsIEV2ZW50Lk1ldGhvZHMpOwoKICBPYmplY3QuZXh0ZW5kKEV2ZW50LCB7CiAgICBmaXJlOiAgICAgICAgICBmaXJlLAogICAgb2JzZXJ2ZTogICAgICAgb2JzZXJ2ZSwKICAgIHN0b3BPYnNlcnZpbmc6IHN0b3BPYnNlcnZpbmcsCiAgICBvbjogICAgICAgICAgICBvbgogIH0pOwoKICBFbGVtZW50LmFkZE1ldGhvZHMoewogICAgZmlyZTogICAgICAgICAgZmlyZSwKCiAgICBvYnNlcnZlOiAgICAgICBvYnNlcnZlLAoKICAgIHN0b3BPYnNlcnZpbmc6IHN0b3BPYnNlcnZpbmcsCgogICAgb246ICAgICAgICAgICAgb24KICB9KTsKCiAgT2JqZWN0LmV4dGVuZChkb2N1bWVudCwgewogICAgZmlyZTogICAgICAgICAgZmlyZS5tZXRob2RpemUoKSwKCiAgICBvYnNlcnZlOiAgICAgICBvYnNlcnZlLm1ldGhvZGl6ZSgpLAoKICAgIHN0b3BPYnNlcnZpbmc6IHN0b3BPYnNlcnZpbmcubWV0aG9kaXplKCksCgogICAgb246ICAgICAgICAgICAgb24ubWV0aG9kaXplKCksCgogICAgbG9hZGVkOiAgICAgICAgZmFsc2UKICB9KTsKCiAgaWYgKHdpbmRvdy5FdmVudCkgT2JqZWN0LmV4dGVuZCh3aW5kb3cuRXZlbnQsIEV2ZW50KTsKICBlbHNlIHdpbmRvdy5FdmVudCA9IEV2ZW50Owp9KSgpOwoKKGZ1bmN0aW9uKCkgewogIC8qIFN1cHBvcnQgZm9yIHRoZSBET01Db250ZW50TG9hZGVkIGV2ZW50IGlzIGJhc2VkIG9uIHdvcmsgYnkgRGFuIFdlYmIsCiAgICAgTWF0dGhpYXMgTWlsbGVyLCBEZWFuIEVkd2FyZHMsIEpvaG4gUmVzaWcsIGFuZCBEaWVnbyBQZXJpbmkuICovCgogIHZhciB0aW1lcjsKCiAgZnVuY3Rpb24gZmlyZUNvbnRlbnRMb2FkZWRFdmVudCgpIHsKICAgIGlmIChkb2N1bWVudC5sb2FkZWQpIHJldHVybjsKICAgIGlmICh0aW1lcikgd2luZG93LmNsZWFyVGltZW91dCh0aW1lcik7CiAgICBkb2N1bWVudC5sb2FkZWQgPSB0cnVlOwogICAgZG9jdW1lbnQuZmlyZSgnZG9tOmxvYWRlZCcpOwogIH0KCiAgZnVuY3Rpb24gY2hlY2tSZWFkeVN0YXRlKCkgewogICAgaWYgKGRvY3VtZW50LnJlYWR5U3RhdGUgPT09ICdjb21wbGV0ZScpIHsKICAgICAgZG9jdW1lbnQuc3RvcE9ic2VydmluZygncmVhZHlzdGF0ZWNoYW5nZScsIGNoZWNrUmVhZHlTdGF0ZSk7CiAgICAgIGZpcmVDb250ZW50TG9hZGVkRXZlbnQoKTsKICAgIH0KICB9CgogIGZ1bmN0aW9uIHBvbGxEb1Njcm9sbCgpIHsKICAgIHRyeSB7IGRvY3VtZW50LmRvY3VtZW50RWxlbWVudC5kb1Njcm9sbCgnbGVmdCcpOyB9CiAgICBjYXRjaChlKSB7CiAgICAgIHRpbWVyID0gcG9sbERvU2Nyb2xsLmRlZmVyKCk7CiAgICAgIHJldHVybjsKICAgIH0KICAgIGZpcmVDb250ZW50TG9hZGVkRXZlbnQoKTsKICB9CgogIGlmIChkb2N1bWVudC5hZGRFdmVudExpc3RlbmVyKSB7CiAgICBkb2N1bWVudC5hZGRFdmVudExpc3RlbmVyKCdET01Db250ZW50TG9hZGVkJywgZmlyZUNvbnRlbnRMb2FkZWRFdmVudCwgZmFsc2UpOwogIH0gZWxzZSB7CiAgICBkb2N1bWVudC5vYnNlcnZlKCdyZWFkeXN0YXRlY2hhbmdlJywgY2hlY2tSZWFkeVN0YXRlKTsKICAgIGlmICh3aW5kb3cgPT0gdG9wKQogICAgICB0aW1lciA9IHBvbGxEb1Njcm9sbC5kZWZlcigpOwogIH0KCiAgRXZlbnQub2JzZXJ2ZSh3aW5kb3csICdsb2FkJywgZmlyZUNvbnRlbnRMb2FkZWRFdmVudCk7Cn0pKCk7CgoKRWxlbWVudC5hZGRNZXRob2RzKCk7Ci8qLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSBERVBSRUNBVEVEIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qLwoKSGFzaC50b1F1ZXJ5U3RyaW5nID0gT2JqZWN0LnRvUXVlcnlTdHJpbmc7Cgp2YXIgVG9nZ2xlID0geyBkaXNwbGF5OiBFbGVtZW50LnRvZ2dsZSB9OwoKRWxlbWVudC5NZXRob2RzLmNoaWxkT2YgPSBFbGVtZW50Lk1ldGhvZHMuZGVzY2VuZGFudE9mOwoKdmFyIEluc2VydGlvbiA9IHsKICBCZWZvcmU6IGZ1bmN0aW9uKGVsZW1lbnQsIGNvbnRlbnQpIHsKICAgIHJldHVybiBFbGVtZW50Lmluc2VydChlbGVtZW50LCB7YmVmb3JlOmNvbnRlbnR9KTsKICB9LAoKICBUb3A6IGZ1bmN0aW9uKGVsZW1lbnQsIGNvbnRlbnQpIHsKICAgIHJldHVybiBFbGVtZW50Lmluc2VydChlbGVtZW50LCB7dG9wOmNvbnRlbnR9KTsKICB9LAoKICBCb3R0b206IGZ1bmN0aW9uKGVsZW1lbnQsIGNvbnRlbnQpIHsKICAgIHJldHVybiBFbGVtZW50Lmluc2VydChlbGVtZW50LCB7Ym90dG9tOmNvbnRlbnR9KTsKICB9LAoKICBBZnRlcjogZnVuY3Rpb24oZWxlbWVudCwgY29udGVudCkgewogICAgcmV0dXJuIEVsZW1lbnQuaW5zZXJ0KGVsZW1lbnQsIHthZnRlcjpjb250ZW50fSk7CiAgfQp9OwoKdmFyICRjb250aW51ZSA9IG5ldyBFcnJvcignInRocm93ICRjb250aW51ZSIgaXMgZGVwcmVjYXRlZCwgdXNlICJyZXR1cm4iIGluc3RlYWQnKTsKCnZhciBQb3NpdGlvbiA9IHsKICBpbmNsdWRlU2Nyb2xsT2Zmc2V0czogZmFsc2UsCgogIHByZXBhcmU6IGZ1bmN0aW9uKCkgewogICAgdGhpcy5kZWx0YVggPSAgd2luZG93LnBhZ2VYT2Zmc2V0CiAgICAgICAgICAgICAgICB8fCBkb2N1bWVudC5kb2N1bWVudEVsZW1lbnQuc2Nyb2xsTGVmdAogICAgICAgICAgICAgICAgfHwgZG9jdW1lbnQuYm9keS5zY3JvbGxMZWZ0CiAgICAgICAgICAgICAgICB8fCAwOwogICAgdGhpcy5kZWx0YVkgPSAgd2luZG93LnBhZ2VZT2Zmc2V0CiAgICAgICAgICAgICAgICB8fCBkb2N1bWVudC5kb2N1bWVudEVsZW1lbnQuc2Nyb2xsVG9wCiAgICAgICAgICAgICAgICB8fCBkb2N1bWVudC5ib2R5LnNjcm9sbFRvcAogICAgICAgICAgICAgICAgfHwgMDsKICB9LAoKICB3aXRoaW46IGZ1bmN0aW9uKGVsZW1lbnQsIHgsIHkpIHsKICAgIGlmICh0aGlzLmluY2x1ZGVTY3JvbGxPZmZzZXRzKQogICAgICByZXR1cm4gdGhpcy53aXRoaW5JbmNsdWRpbmdTY3JvbGxvZmZzZXRzKGVsZW1lbnQsIHgsIHkpOwogICAgdGhpcy54Y29tcCA9IHg7CiAgICB0aGlzLnljb21wID0geTsKICAgIHRoaXMub2Zmc2V0ID0gRWxlbWVudC5jdW11bGF0aXZlT2Zmc2V0KGVsZW1lbnQpOwoKICAgIHJldHVybiAoeSA+PSB0aGlzLm9mZnNldFsxXSAmJgogICAgICAgICAgICB5IDwgIHRoaXMub2Zmc2V0WzFdICsgZWxlbWVudC5vZmZzZXRIZWlnaHQgJiYKICAgICAgICAgICAgeCA+PSB0aGlzLm9mZnNldFswXSAmJgogICAgICAgICAgICB4IDwgIHRoaXMub2Zmc2V0WzBdICsgZWxlbWVudC5vZmZzZXRXaWR0aCk7CiAgfSwKCiAgd2l0aGluSW5jbHVkaW5nU2Nyb2xsb2Zmc2V0czogZnVuY3Rpb24oZWxlbWVudCwgeCwgeSkgewogICAgdmFyIG9mZnNldGNhY2hlID0gRWxlbWVudC5jdW11bGF0aXZlU2Nyb2xsT2Zmc2V0KGVsZW1lbnQpOwoKICAgIHRoaXMueGNvbXAgPSB4ICsgb2Zmc2V0Y2FjaGVbMF0gLSB0aGlzLmRlbHRhWDsKICAgIHRoaXMueWNvbXAgPSB5ICsgb2Zmc2V0Y2FjaGVbMV0gLSB0aGlzLmRlbHRhWTsKICAgIHRoaXMub2Zmc2V0ID0gRWxlbWVudC5jdW11bGF0aXZlT2Zmc2V0KGVsZW1lbnQpOwoKICAgIHJldHVybiAodGhpcy55Y29tcCA+PSB0aGlzLm9mZnNldFsxXSAmJgogICAgICAgICAgICB0aGlzLnljb21wIDwgIHRoaXMub2Zmc2V0WzFdICsgZWxlbWVudC5vZmZzZXRIZWlnaHQgJiYKICAgICAgICAgICAgdGhpcy54Y29tcCA+PSB0aGlzLm9mZnNldFswXSAmJgogICAgICAgICAgICB0aGlzLnhjb21wIDwgIHRoaXMub2Zmc2V0WzBdICsgZWxlbWVudC5vZmZzZXRXaWR0aCk7CiAgfSwKCiAgb3ZlcmxhcDogZnVuY3Rpb24obW9kZSwgZWxlbWVudCkgewogICAgaWYgKCFtb2RlKSByZXR1cm4gMDsKICAgIGlmIChtb2RlID09ICd2ZXJ0aWNhbCcpCiAgICAgIHJldHVybiAoKHRoaXMub2Zmc2V0WzFdICsgZWxlbWVudC5vZmZzZXRIZWlnaHQpIC0gdGhpcy55Y29tcCkgLwogICAgICAgIGVsZW1lbnQub2Zmc2V0SGVpZ2h0OwogICAgaWYgKG1vZGUgPT0gJ2hvcml6b250YWwnKQogICAgICByZXR1cm4gKCh0aGlzLm9mZnNldFswXSArIGVsZW1lbnQub2Zmc2V0V2lkdGgpIC0gdGhpcy54Y29tcCkgLwogICAgICAgIGVsZW1lbnQub2Zmc2V0V2lkdGg7CiAgfSwKCgogIGN1bXVsYXRpdmVPZmZzZXQ6IEVsZW1lbnQuTWV0aG9kcy5jdW11bGF0aXZlT2Zmc2V0LAoKICBwb3NpdGlvbmVkT2Zmc2V0OiBFbGVtZW50Lk1ldGhvZHMucG9zaXRpb25lZE9mZnNldCwKCiAgYWJzb2x1dGl6ZTogZnVuY3Rpb24oZWxlbWVudCkgewogICAgUG9zaXRpb24ucHJlcGFyZSgpOwogICAgcmV0dXJuIEVsZW1lbnQuYWJzb2x1dGl6ZShlbGVtZW50KTsKICB9LAoKICByZWxhdGl2aXplOiBmdW5jdGlvbihlbGVtZW50KSB7CiAgICBQb3NpdGlvbi5wcmVwYXJlKCk7CiAgICByZXR1cm4gRWxlbWVudC5yZWxhdGl2aXplKGVsZW1lbnQpOwogIH0sCgogIHJlYWxPZmZzZXQ6IEVsZW1lbnQuTWV0aG9kcy5jdW11bGF0aXZlU2Nyb2xsT2Zmc2V0LAoKICBvZmZzZXRQYXJlbnQ6IEVsZW1lbnQuTWV0aG9kcy5nZXRPZmZzZXRQYXJlbnQsCgogIHBhZ2U6IEVsZW1lbnQuTWV0aG9kcy52aWV3cG9ydE9mZnNldCwKCiAgY2xvbmU6IGZ1bmN0aW9uKHNvdXJjZSwgdGFyZ2V0LCBvcHRpb25zKSB7CiAgICBvcHRpb25zID0gb3B0aW9ucyB8fCB7IH07CiAgICByZXR1cm4gRWxlbWVudC5jbG9uZVBvc2l0aW9uKHRhcmdldCwgc291cmNlLCBvcHRpb25zKTsKICB9Cn07CgovKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi8KCmlmICghZG9jdW1lbnQuZ2V0RWxlbWVudHNCeUNsYXNzTmFtZSkgZG9jdW1lbnQuZ2V0RWxlbWVudHNCeUNsYXNzTmFtZSA9IGZ1bmN0aW9uKGluc3RhbmNlTWV0aG9kcyl7CiAgZnVuY3Rpb24gaXRlcihuYW1lKSB7CiAgICByZXR1cm4gbmFtZS5ibGFuaygpID8gbnVsbCA6ICJbY29udGFpbnMoY29uY2F0KCcgJywgQGNsYXNzLCAnICcpLCAnICIgKyBuYW1lICsgIiAnKV0iOwogIH0KCiAgaW5zdGFuY2VNZXRob2RzLmdldEVsZW1lbnRzQnlDbGFzc05hbWUgPSBQcm90b3R5cGUuQnJvd3NlckZlYXR1cmVzLlhQYXRoID8KICBmdW5jdGlvbihlbGVtZW50LCBjbGFzc05hbWUpIHsKICAgIGNsYXNzTmFtZSA9IGNsYXNzTmFtZS50b1N0cmluZygpLnN0cmlwKCk7CiAgICB2YXIgY29uZCA9IC9ccy8udGVzdChjbGFzc05hbWUpID8gJHcoY2xhc3NOYW1lKS5tYXAoaXRlcikuam9pbignJykgOiBpdGVyKGNsYXNzTmFtZSk7CiAgICByZXR1cm4gY29uZCA/IGRvY3VtZW50Ll9nZXRFbGVtZW50c0J5WFBhdGgoJy4vLyonICsgY29uZCwgZWxlbWVudCkgOiBbXTsKICB9IDogZnVuY3Rpb24oZWxlbWVudCwgY2xhc3NOYW1lKSB7CiAgICBjbGFzc05hbWUgPSBjbGFzc05hbWUudG9TdHJpbmcoKS5zdHJpcCgpOwogICAgdmFyIGVsZW1lbnRzID0gW10sIGNsYXNzTmFtZXMgPSAoL1xzLy50ZXN0KGNsYXNzTmFtZSkgPyAkdyhjbGFzc05hbWUpIDogbnVsbCk7CiAgICBpZiAoIWNsYXNzTmFtZXMgJiYgIWNsYXNzTmFtZSkgcmV0dXJuIGVsZW1lbnRzOwoKICAgIHZhciBub2RlcyA9ICQoZWxlbWVudCkuZ2V0RWxlbWVudHNCeVRhZ05hbWUoJyonKTsKICAgIGNsYXNzTmFtZSA9ICcgJyArIGNsYXNzTmFtZSArICcgJzsKCiAgICBmb3IgKHZhciBpID0gMCwgY2hpbGQsIGNuOyBjaGlsZCA9IG5vZGVzW2ldOyBpKyspIHsKICAgICAgaWYgKGNoaWxkLmNsYXNzTmFtZSAmJiAoY24gPSAnICcgKyBjaGlsZC5jbGFzc05hbWUgKyAnICcpICYmIChjbi5pbmNsdWRlKGNsYXNzTmFtZSkgfHwKICAgICAgICAgIChjbGFzc05hbWVzICYmIGNsYXNzTmFtZXMuYWxsKGZ1bmN0aW9uKG5hbWUpIHsKICAgICAgICAgICAgcmV0dXJuICFuYW1lLnRvU3RyaW5nKCkuYmxhbmsoKSAmJiBjbi5pbmNsdWRlKCcgJyArIG5hbWUgKyAnICcpOwogICAgICAgICAgfSkpKSkKICAgICAgICBlbGVtZW50cy5wdXNoKEVsZW1lbnQuZXh0ZW5kKGNoaWxkKSk7CiAgICB9CiAgICByZXR1cm4gZWxlbWVudHM7CiAgfTsKCiAgcmV0dXJuIGZ1bmN0aW9uKGNsYXNzTmFtZSwgcGFyZW50RWxlbWVudCkgewogICAgcmV0dXJuICQocGFyZW50RWxlbWVudCB8fCBkb2N1bWVudC5ib2R5KS5nZXRFbGVtZW50c0J5Q2xhc3NOYW1lKGNsYXNzTmFtZSk7CiAgfTsKfShFbGVtZW50Lk1ldGhvZHMpOwoKLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovCgpFbGVtZW50LkNsYXNzTmFtZXMgPSBDbGFzcy5jcmVhdGUoKTsKRWxlbWVudC5DbGFzc05hbWVzLnByb3RvdHlwZSA9IHsKICBpbml0aWFsaXplOiBmdW5jdGlvbihlbGVtZW50KSB7CiAgICB0aGlzLmVsZW1lbnQgPSAkKGVsZW1lbnQpOwogIH0sCgogIF9lYWNoOiBmdW5jdGlvbihpdGVyYXRvcikgewogICAgdGhpcy5lbGVtZW50LmNsYXNzTmFtZS5zcGxpdCgvXHMrLykuc2VsZWN0KGZ1bmN0aW9uKG5hbWUpIHsKICAgICAgcmV0dXJuIG5hbWUubGVuZ3RoID4gMDsKICAgIH0pLl9lYWNoKGl0ZXJhdG9yKTsKICB9LAoKICBzZXQ6IGZ1bmN0aW9uKGNsYXNzTmFtZSkgewogICAgdGhpcy5lbGVtZW50LmNsYXNzTmFtZSA9IGNsYXNzTmFtZTsKICB9LAoKICBhZGQ6IGZ1bmN0aW9uKGNsYXNzTmFtZVRvQWRkKSB7CiAgICBpZiAodGhpcy5pbmNsdWRlKGNsYXNzTmFtZVRvQWRkKSkgcmV0dXJuOwogICAgdGhpcy5zZXQoJEEodGhpcykuY29uY2F0KGNsYXNzTmFtZVRvQWRkKS5qb2luKCcgJykpOwogIH0sCgogIHJlbW92ZTogZnVuY3Rpb24oY2xhc3NOYW1lVG9SZW1vdmUpIHsKICAgIGlmICghdGhpcy5pbmNsdWRlKGNsYXNzTmFtZVRvUmVtb3ZlKSkgcmV0dXJuOwogICAgdGhpcy5zZXQoJEEodGhpcykud2l0aG91dChjbGFzc05hbWVUb1JlbW92ZSkuam9pbignICcpKTsKICB9LAoKICB0b1N0cmluZzogZnVuY3Rpb24oKSB7CiAgICByZXR1cm4gJEEodGhpcykuam9pbignICcpOwogIH0KfTsKCk9iamVjdC5leHRlbmQoRWxlbWVudC5DbGFzc05hbWVzLnByb3RvdHlwZSwgRW51bWVyYWJsZSk7CgovKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi8KCihmdW5jdGlvbigpIHsKICB3aW5kb3cuU2VsZWN0b3IgPSBDbGFzcy5jcmVhdGUoewogICAgaW5pdGlhbGl6ZTogZnVuY3Rpb24oZXhwcmVzc2lvbikgewogICAgICB0aGlzLmV4cHJlc3Npb24gPSBleHByZXNzaW9uLnN0cmlwKCk7CiAgICB9LAoKICAgIGZpbmRFbGVtZW50czogZnVuY3Rpb24ocm9vdEVsZW1lbnQpIHsKICAgICAgcmV0dXJuIFByb3RvdHlwZS5TZWxlY3Rvci5zZWxlY3QodGhpcy5leHByZXNzaW9uLCByb290RWxlbWVudCk7CiAgICB9LAoKICAgIG1hdGNoOiBmdW5jdGlvbihlbGVtZW50KSB7CiAgICAgIHJldHVybiBQcm90b3R5cGUuU2VsZWN0b3IubWF0Y2goZWxlbWVudCwgdGhpcy5leHByZXNzaW9uKTsKICAgIH0sCgogICAgdG9TdHJpbmc6IGZ1bmN0aW9uKCkgewogICAgICByZXR1cm4gdGhpcy5leHByZXNzaW9uOwogICAgfSwKCiAgICBpbnNwZWN0OiBmdW5jdGlvbigpIHsKICAgICAgcmV0dXJuICIjPFNlbGVjdG9yOiAiICsgdGhpcy5leHByZXNzaW9uICsgIj4iOwogICAgfQogIH0pOwoKICBPYmplY3QuZXh0ZW5kKFNlbGVjdG9yLCB7CiAgICBtYXRjaEVsZW1lbnRzOiBmdW5jdGlvbihlbGVtZW50cywgZXhwcmVzc2lvbikgewogICAgICB2YXIgbWF0Y2ggPSBQcm90b3R5cGUuU2VsZWN0b3IubWF0Y2gsCiAgICAgICAgICByZXN1bHRzID0gW107CgogICAgICBmb3IgKHZhciBpID0gMCwgbGVuZ3RoID0gZWxlbWVudHMubGVuZ3RoOyBpIDwgbGVuZ3RoOyBpKyspIHsKICAgICAgICB2YXIgZWxlbWVudCA9IGVsZW1lbnRzW2ldOwogICAgICAgIGlmIChtYXRjaChlbGVtZW50LCBleHByZXNzaW9uKSkgewogICAgICAgICAgcmVzdWx0cy5wdXNoKEVsZW1lbnQuZXh0ZW5kKGVsZW1lbnQpKTsKICAgICAgICB9CiAgICAgIH0KICAgICAgcmV0dXJuIHJlc3VsdHM7CiAgICB9LAoKICAgIGZpbmRFbGVtZW50OiBmdW5jdGlvbihlbGVtZW50cywgZXhwcmVzc2lvbiwgaW5kZXgpIHsKICAgICAgaW5kZXggPSBpbmRleCB8fCAwOwogICAgICB2YXIgbWF0Y2hJbmRleCA9IDAsIGVsZW1lbnQ7CiAgICAgIGZvciAodmFyIGkgPSAwLCBsZW5ndGggPSBlbGVtZW50cy5sZW5ndGg7IGkgPCBsZW5ndGg7IGkrKykgewogICAgICAgIGVsZW1lbnQgPSBlbGVtZW50c1tpXTsKICAgICAgICBpZiAoUHJvdG90eXBlLlNlbGVjdG9yLm1hdGNoKGVsZW1lbnQsIGV4cHJlc3Npb24pICYmIGluZGV4ID09PSBtYXRjaEluZGV4KyspIHsKICAgICAgICAgIHJldHVybiBFbGVtZW50LmV4dGVuZChlbGVtZW50KTsKICAgICAgICB9CiAgICAgIH0KICAgIH0sCgogICAgZmluZENoaWxkRWxlbWVudHM6IGZ1bmN0aW9uKGVsZW1lbnQsIGV4cHJlc3Npb25zKSB7CiAgICAgIHZhciBzZWxlY3RvciA9IGV4cHJlc3Npb25zLnRvQXJyYXkoKS5qb2luKCcsICcpOwogICAgICByZXR1cm4gUHJvdG90eXBlLlNlbGVjdG9yLnNlbGVjdChzZWxlY3RvciwgZWxlbWVudCB8fCBkb2N1bWVudCk7CiAgICB9CiAgfSk7Cn0pKCk7Cg==]]></data>
	</file>
</gallerytpl>
