{"js":"PCFkb2N0eXBlIGh0bWw+CjxodG1sIGxhbmc9ImVuIj4KPGhlYWQ+CiAgPG1ldGEgY2hhcnNldD0idXRmLTgiLz4KICA8bWV0YSBuYW1lPSJ2aWV3cG9ydCIgY29udGVudD0id2lkdGg9ZGV2aWNlLXdpZHRoLGluaXRpYWwtc2NhbGU9MSIvPgogIDx0aXRsZT5LZXl3b3JkIFJhbmsgSGVhdG1hcCBTdWl0ZSAoT2ZmbGluZSk8L3RpdGxlPgogIDxzdHlsZT4KICAgIDpyb290e2NvbG9yLXNjaGVtZTpsaWdodCBkYXJrfQogICAgYm9keXtmb250LWZhbWlseTpzeXN0ZW0tdWksLWFwcGxlLXN5c3RlbSxTZWdvZSBVSSxSb2JvdG8sQXJpYWwsc2Fucy1zZXJpZjttYXJnaW46MH0KICAgIGhlYWRlcntwYWRkaW5nOjE2cHggMThweDtib3JkZXItYm90dG9tOjFweCBzb2xpZCAjY2NjM30KICAgIGhlYWRlciBoMXttYXJnaW46MCAwIDZweDtmb250LXNpemU6MThweH0KICAgIGhlYWRlciBwe21hcmdpbjowO29wYWNpdHk6LjgyO2ZvbnQtc2l6ZToxM3B4O2xpbmUtaGVpZ2h0OjEuMzV9CiAgICBtYWlue2Rpc3BsYXk6Z3JpZDtncmlkLXRlbXBsYXRlLWNvbHVtbnM6NTYwcHggMWZyO2dhcDoxMnB4O3BhZGRpbmc6MTJweH0KICAgIEBtZWRpYSAobWF4LXdpZHRoOjEyMDBweCl7bWFpbntncmlkLXRlbXBsYXRlLWNvbHVtbnM6MWZyfX0KICAgIC5jYXJke2JvcmRlcjoxcHggc29saWQgI2NjYzM7Ym9yZGVyLXJhZGl1czoxMnB4O3BhZGRpbmc6MTJweDtiYWNrZ3JvdW5kOiNmZmYxfQogICAgLnN1YmNhcmR7Ym9yZGVyOjFweCBzb2xpZCAjY2NjMztib3JkZXItcmFkaXVzOjEycHg7cGFkZGluZzoxMHB4O21hcmdpbi10b3A6MTBweDtiYWNrZ3JvdW5kOiMwMDAwfQogICAgLnJvd3tkaXNwbGF5OmdyaWQ7Z3JpZC10ZW1wbGF0ZS1jb2x1bW5zOjFmciAxZnI7Z2FwOjEwcHh9CiAgICAucm93M3tkaXNwbGF5OmdyaWQ7Z3JpZC10ZW1wbGF0ZS1jb2x1bW5zOjFmciAxZnIgMWZyO2dhcDoxMHB4fQogICAgLnJvdzR7ZGlzcGxheTpncmlkO2dyaWQtdGVtcGxhdGUtY29sdW1uczpyZXBlYXQoNCwxZnIpO2dhcDoxMHB4fQogICAgbGFiZWx7ZGlzcGxheTpibG9jaztmb250LXNpemU6MTJweDtvcGFjaXR5Oi44NTttYXJnaW46MTBweCAwIDZweH0KICAgIGlucHV0LHNlbGVjdCx0ZXh0YXJlYSxidXR0b257d2lkdGg6MTAwJTtib3gtc2l6aW5nOmJvcmRlci1ib3h9CiAgICBpbnB1dCxzZWxlY3QsdGV4dGFyZWF7cGFkZGluZzoxMHB4O2JvcmRlci1yYWRpdXM6MTBweDtib3JkZXI6MXB4IHNvbGlkICNjY2M2O2JhY2tncm91bmQ6I2ZmZjJ9CiAgICB0ZXh0YXJlYXttaW4taGVpZ2h0OjE0MHB4O3Jlc2l6ZTp2ZXJ0aWNhbDtmb250LWZhbWlseTp1aS1tb25vc3BhY2UsU0ZNb25vLVJlZ3VsYXIsTWVubG8sTW9uYWNvLENvbnNvbGFzLCJMaWJlcmF0aW9uIE1vbm8iLCJDb3VyaWVyIE5ldyIsbW9ub3NwYWNlO2ZvbnQtc2l6ZToxMnB4fQogICAgYnV0dG9ue3BhZGRpbmc6MTBweCAxMnB4O2JvcmRlci1yYWRpdXM6MTBweDtib3JkZXI6MXB4IHNvbGlkICNjY2M2O2JhY2tncm91bmQ6IzFmNmZlYjIyO2N1cnNvcjpwb2ludGVyfQogICAgYnV0dG9uOmhvdmVye2ZpbHRlcjpicmlnaHRuZXNzKDEuMDgpfQogICAgYnV0dG9uOmRpc2FibGVke29wYWNpdHk6LjU1O2N1cnNvcjpub3QtYWxsb3dlZH0KICAgIC5idG5yb3d7ZGlzcGxheTpncmlkO2dyaWQtdGVtcGxhdGUtY29sdW1uczoxZnIgMWZyO2dhcDoxMHB4O21hcmdpbi10b3A6MTBweH0KICAgIC5idG5yb3cze2Rpc3BsYXk6Z3JpZDtncmlkLXRlbXBsYXRlLWNvbHVtbnM6MWZyIDFmciAxZnI7Z2FwOjEwcHg7bWFyZ2luLXRvcDoxMHB4fQogICAgLmJ0bnJvdzR7ZGlzcGxheTpncmlkO2dyaWQtdGVtcGxhdGUtY29sdW1uczpyZXBlYXQoNCwxZnIpO2dhcDoxMHB4O21hcmdpbi10b3A6MTBweH0KICAgIC5waWxse2Rpc3BsYXk6aW5saW5lLWJsb2NrO3BhZGRpbmc6NHB4IDhweDtib3JkZXItcmFkaXVzOjk5OXB4O2JvcmRlcjoxcHggc29saWQgI2NjYzY7Zm9udC1zaXplOjEycHg7b3BhY2l0eTouOTttYXJnaW4tbGVmdDo4cHh9CiAgICAuc21hbGx7Zm9udC1zaXplOjEycHg7b3BhY2l0eTouNzg7bGluZS1oZWlnaHQ6MS4zNX0KICAgIC5zdGF0dXN7bWFyZ2luLXRvcDoxMHB4O2ZvbnQtc2l6ZToxMnB4O29wYWNpdHk6Ljg4O2xpbmUtaGVpZ2h0OjEuMzU7d2hpdGUtc3BhY2U6cHJlLXdyYXB9CiAgICAuY2FudmFzV3JhcHtkaXNwbGF5OmdyaWQ7Z3JpZC10ZW1wbGF0ZS1yb3dzOmF1dG8gMWZyO2dhcDoxMHB4fQogICAgLnRvb2xiYXJ7ZGlzcGxheTpncmlkO2dyaWQtdGVtcGxhdGUtY29sdW1uczpyZXBlYXQoNCwxZnIpO2dhcDoxMHB4O2FsaWduLWl0ZW1zOmVuZH0KICAgIEBtZWRpYSAobWF4LXdpZHRoOjEyMDBweCl7LnRvb2xiYXJ7Z3JpZC10ZW1wbGF0ZS1jb2x1bW5zOjFmciAxZnJ9fQogICAgY2FudmFze3dpZHRoOjEwMCU7aGVpZ2h0OjY0MHB4O2JvcmRlci1yYWRpdXM6MTJweDtib3JkZXI6MXB4IHNvbGlkICNjY2MzO2JhY2tncm91bmQ6IzBiMTAyMDtjdXJzb3I6Y3Jvc3NoYWlyfQogICAgdGFibGV7d2lkdGg6MTAwJTtib3JkZXItY29sbGFwc2U6Y29sbGFwc2U7Zm9udC1zaXplOjEycHh9CiAgICB0aCx0ZHtwYWRkaW5nOjZweDtib3JkZXItYm90dG9tOjFweCBzb2xpZCAjY2NjMzt0ZXh0LWFsaWduOmxlZnR9CiAgICB0aHtwb3NpdGlvbjpzdGlja3k7dG9wOjA7YmFja2dyb3VuZDojMDAwMDtiYWNrZHJvcC1maWx0ZXI6Ymx1cig2cHgpO3otaW5kZXg6MX0KICAgIC5zY3JvbGx7bWF4LWhlaWdodDoyNDBweDtvdmVyZmxvdzphdXRvO2JvcmRlcjoxcHggc29saWQgI2NjYzM7Ym9yZGVyLXJhZGl1czoxMHB4fQogICAgLm1vbm97Zm9udC1mYW1pbHk6dWktbW9ub3NwYWNlLFNGTW9uby1SZWd1bGFyLE1lbmxvLE1vbmFjbyxDb25zb2xhcywiTGliZXJhdGlvbiBNb25vIiwiQ291cmllciBOZXciLG1vbm9zcGFjZX0KICAgIC50YWJze2Rpc3BsYXk6Z3JpZDtncmlkLXRlbXBsYXRlLWNvbHVtbnM6cmVwZWF0KDQsMWZyKTtnYXA6OHB4O21hcmdpbi10b3A6MTBweH0KICAgIC50YWJidG57cGFkZGluZzoxMHB4O2JvcmRlci1yYWRpdXM6MTBweDtib3JkZXI6MXB4IHNvbGlkICNjY2M2O2JhY2tncm91bmQ6IzAwMDB9CiAgICAudGFiYnRuLmFjdGl2ZXtiYWNrZ3JvdW5kOiMxZjZmZWIyMn0KICAgIC50YWJwYW5lbHtkaXNwbGF5Om5vbmV9CiAgICAudGFicGFuZWwuYWN0aXZle2Rpc3BsYXk6YmxvY2t9CiAgPC9zdHlsZT4KPC9oZWFkPgo8Ym9keT4KPGhlYWRlcj4KICA8aDE+S2V5d29yZCBSYW5rIEhlYXRtYXAgU3VpdGUgKE9mZmxpbmUsIFNpbmdsZS1GaWxlKTwvaDE+CiAgPHA+CiAgICBJbXBvcnQgQ1NWKHMpIOKGkiBub3JtYWxpemUg4oaSIGZpbHRlciBieSBidXNpbmVzcy9kYXRlIOKGkiBoZWF0bWFwICsgYm91bmRhcmllcyArIHBvbHlnb24gZHJhdy9ob2xlcyArIHN0YXRzICsgb3Bwb3J0dW5pdGllcyArIGV4cG9ydHMgKyBwcm9qZWN0IHNhdmUvbG9hZC4KICAgIDxzcGFuIGNsYXNzPSJwaWxsIiBpZD0ibWV0YVBpbGwiPk5vIGRhdGE8L3NwYW4+CiAgICA8c3BhbiBjbGFzcz0icGlsbCIgaWQ9Imdlb1BpbGwiPk5vIEdlb0pTT048L3NwYW4+CiAgICA8c3BhbiBjbGFzcz0icGlsbCIgaWQ9ImRyYXdQaWxsIj5EcmF3OiBvZmY8L3NwYW4+CiAgICA8c3BhbiBjbGFzcz0icGlsbCIgaWQ9InBpbnNQaWxsIj5QaW5zOiAwPC9zcGFuPgogIDwvcD4KPC9oZWFkZXI+Cgo8bWFpbj4KICA8c2VjdGlvbiBjbGFzcz0iY2FyZCI+CiAgICA8ZGl2IGNsYXNzPSJyb3ciPgogICAgICA8ZGl2PgogICAgICAgIDxsYWJlbCBmb3I9InByb2plY3ROYW1lIj5Qcm9qZWN0IG5hbWU8L2xhYmVsPgogICAgICAgIDxpbnB1dCBpZD0icHJvamVjdE5hbWUiIHBsYWNlaG9sZGVyPSJlLmcuLCBBY21lIERlbnRhbCBMb2NhbCBSYW5rIi8+CiAgICAgIDwvZGl2PgogICAgICA8ZGl2PgogICAgICAgIDxsYWJlbCBmb3I9InVuaXRzIj5Db29yZGluYXRlIHVuaXRzPC9sYWJlbD4KICAgICAgICA8c2VsZWN0IGlkPSJ1bml0cyI+CiAgICAgICAgICA8b3B0aW9uIHZhbHVlPSJsYXRsbmciIHNlbGVjdGVkPkxhdC9Mbmc8L29wdGlvbj4KICAgICAgICAgIDxvcHRpb24gdmFsdWU9Inh5Ij5YL1kgKGN1c3RvbSk8L29wdGlvbj4KICAgICAgICA8L3NlbGVjdD4KICAgICAgPC9kaXY+CiAgICA8L2Rpdj4KCiAgICA8ZGl2IGNsYXNzPSJzdWJjYXJkIj4KICAgICAgPGxhYmVsPkltcG9ydDwvbGFiZWw+CiAgICAgIDxkaXYgY2xhc3M9ImJ0bnJvdzQiPgogICAgICAgIDxidXR0b24gaWQ9InBhc3RlQnRuIj5QYXN0ZSBDU1Y8L2J1dHRvbj4KICAgICAgICA8YnV0dG9uIGlkPSJhZGRDc3ZCdG4iPkFkZCBDU1YgZmlsZShzKTwvYnV0dG9uPgogICAgICAgIDxidXR0b24gaWQ9ImNsZWFySW1wb3J0c0J0biI+Q2xlYXIgaW1wb3J0czwvYnV0dG9uPgogICAgICAgIDxidXR0b24gaWQ9ImxvYWRTYW1wbGVCdG4iPkxvYWQgc2FtcGxlPC9idXR0b24+CiAgICAgIDwvZGl2PgogICAgICA8aW5wdXQgaWQ9ImNzdkZpbGVzIiB0eXBlPSJmaWxlIiBhY2NlcHQ9Ii5jc3YsdGV4dC9jc3YiIG11bHRpcGxlIHN0eWxlPSJkaXNwbGF5Om5vbmUiLz4KICAgICAgPGxhYmVsIGZvcj0iY3N2VGV4dCI+Q1NWIHN0YWdpbmcgKG9wdGlvbmFsKTwvbGFiZWw+CiAgICAgIDx0ZXh0YXJlYSBpZD0iY3N2VGV4dCIgc3BlbGxjaGVjaz0iZmFsc2UiPjwvdGV4dGFyZWE+CiAgICAgIDxkaXYgY2xhc3M9InNtYWxsIj4KICAgICAgICBTdXBwb3J0cyA8Yj5sb25nPC9iPiAoa2V5d29yZC9sb2NhdGlvbi9sYXQvbG5nL3JhbmspIGFuZCA8Yj53aWRlPC9iPiAoa2V5d29yZHMgYXMgY29sdW1ucykuIE9wdGlvbmFsOiA8Y29kZT5idXNpbmVzczwvY29kZT4sIDxjb2RlPmRhdGU8L2NvZGU+LCA8Y29kZT52b2x1bWU8L2NvZGU+LgogICAgICAgIENsaXBib2FyZCByZXF1aXJlcyA8Yj5odHRwOi8vbG9jYWxob3N0PC9iPiBvciA8Yj5odHRwczwvYj4gKG5vdCA8Y29kZT5maWxlOi8vPC9jb2RlPikuCiAgICAgIDwvZGl2PgogICAgICA8ZGl2IGNsYXNzPSJidG5yb3czIj4KICAgICAgICA8YnV0dG9uIGlkPSJkZXRlY3RGb3JtYXRCdG4iPkRldGVjdCBmb3JtYXQ8L2J1dHRvbj4KICAgICAgICA8YnV0dG9uIGlkPSJhdXRvTWFwQnRuIj5BdXRvLW1hcDwvYnV0dG9uPgogICAgICAgIDxidXR0b24gaWQ9ImJ1aWxkQnRuIj5CdWlsZCBkYXRhc2V0PC9idXR0b24+CiAgICAgIDwvZGl2PgogICAgICA8ZGl2IGNsYXNzPSJyb3ciPgogICAgICAgIDxkaXY+CiAgICAgICAgICA8bGFiZWwgZm9yPSJjc3ZGb3JtYXQiPkNTViBmb3JtYXQ8L2xhYmVsPgogICAgICAgICAgPHNlbGVjdCBpZD0iY3N2Rm9ybWF0Ij4KICAgICAgICAgICAgPG9wdGlvbiB2YWx1ZT0iYXV0byIgc2VsZWN0ZWQ+QXV0bzwvb3B0aW9uPgogICAgICAgICAgICA8b3B0aW9uIHZhbHVlPSJsb25nIj5Mb25nPC9vcHRpb24+CiAgICAgICAgICAgIDxvcHRpb24gdmFsdWU9IndpZGUiPldpZGU8L29wdGlvbj4KICAgICAgICAgIDwvc2VsZWN0PgogICAgICAgIDwvZGl2PgogICAgICAgIDxkaXYgY2xhc3M9InNtYWxsIiBpZD0iZm9ybWF0SGludCIgc3R5bGU9ImFsaWduLXNlbGY6Y2VudGVyOyI+QXV0byBkZXRlY3RzIGxvbmcgdnMgd2lkZS48L2Rpdj4KICAgICAgPC9kaXY+CgogICAgICA8ZGl2IGlkPSJtYXBwaW5nTG9uZ0Jsb2NrIiBjbGFzcz0ic3ViY2FyZCI+CiAgICAgICAgPGRpdiBjbGFzcz0ic21hbGwiPk1hcHBpbmcgKGxvbmcpPC9kaXY+CiAgICAgICAgPGRpdiBjbGFzcz0icm93MyI+CiAgICAgICAgICA8ZGl2PjxsYWJlbD5rZXl3b3JkPC9sYWJlbD48c2VsZWN0IGlkPSJtS2V5d29yZCI+PC9zZWxlY3Q+PC9kaXY+CiAgICAgICAgICA8ZGl2PjxsYWJlbD5sb2NhdGlvbjwvbGFiZWw+PHNlbGVjdCBpZD0ibUxvY2F0aW9uIj48L3NlbGVjdD48L2Rpdj4KICAgICAgICAgIDxkaXY+PGxhYmVsPnJhbms8L2xhYmVsPjxzZWxlY3QgaWQ9Im1SYW5rIj48L3NlbGVjdD48L2Rpdj4KICAgICAgICA8L2Rpdj4KICAgICAgICA8ZGl2IGNsYXNzPSJyb3czIj4KICAgICAgICAgIDxkaXY+PGxhYmVsPmxhdC94PC9sYWJlbD48c2VsZWN0IGlkPSJtWCI+PC9zZWxlY3Q+PC9kaXY+CiAgICAgICAgICA8ZGl2PjxsYWJlbD5sbmcveTwvbGFiZWw+PHNlbGVjdCBpZD0ibVkiPjwvc2VsZWN0PjwvZGl2PgogICAgICAgICAgPGRpdj48bGFiZWw+YnVzaW5lc3MgKG9wdCk8L2xhYmVsPjxzZWxlY3QgaWQ9Im1CdXNpbmVzcyI+PC9zZWxlY3Q+PC9kaXY+CiAgICAgICAgPC9kaXY+CiAgICAgICAgPGRpdiBjbGFzcz0icm93MyI+CiAgICAgICAgICA8ZGl2PjxsYWJlbD5kYXRlIChvcHQpPC9sYWJlbD48c2VsZWN0IGlkPSJtRGF0ZSI+PC9zZWxlY3Q+PC9kaXY+CiAgICAgICAgICA8ZGl2PjxsYWJlbD52b2x1bWUgKG9wdCk8L2xhYmVsPjxzZWxlY3QgaWQ9Im1Wb2x1bWUiPjwvc2VsZWN0PjwvZGl2PgogICAgICAgICAgPGRpdj48L2Rpdj4KICAgICAgICA8L2Rpdj4KICAgICAgPC9kaXY+CgogICAgICA8ZGl2IGlkPSJtYXBwaW5nV2lkZUJsb2NrIiBjbGFzcz0ic3ViY2FyZCIgc3R5bGU9ImRpc3BsYXk6bm9uZTsiPgogICAgICAgIDxkaXYgY2xhc3M9InNtYWxsIj5NYXBwaW5nICh3aWRlKTwvZGl2PgogICAgICAgIDxkaXYgY2xhc3M9InJvdzMiPgogICAgICAgICAgPGRpdj48bGFiZWw+bG9jYXRpb248L2xhYmVsPjxzZWxlY3QgaWQ9IndMb2NhdGlvbiI+PC9zZWxlY3Q+PC9kaXY+CiAgICAgICAgICA8ZGl2PjxsYWJlbD5sYXQveDwvbGFiZWw+PHNlbGVjdCBpZD0id1giPjwvc2VsZWN0PjwvZGl2PgogICAgICAgICAgPGRpdj48bGFiZWw+bG5nL3k8L2xhYmVsPjxzZWxlY3QgaWQ9IndZIj48L3NlbGVjdD48L2Rpdj4KICAgICAgICA8L2Rpdj4KICAgICAgICA8ZGl2IGNsYXNzPSJyb3czIj4KICAgICAgICAgIDxkaXY+PGxhYmVsPmJ1c2luZXNzIChvcHQpPC9sYWJlbD48c2VsZWN0IGlkPSJ3QnVzaW5lc3MiPjwvc2VsZWN0PjwvZGl2PgogICAgICAgICAgPGRpdj48bGFiZWw+ZGF0ZSAob3B0KTwvbGFiZWw+PHNlbGVjdCBpZD0id0RhdGUiPjwvc2VsZWN0PjwvZGl2PgogICAgICAgICAgPGRpdj4KICAgICAgICAgICAgPGxhYmVsPlZvbHVtZSBtb2RlPC9sYWJlbD4KICAgICAgICAgICAgPHNlbGVjdCBpZD0id1ZvbHVtZU1vZGUiPgogICAgICAgICAgICAgIDxvcHRpb24gdmFsdWU9Im5vbmUiIHNlbGVjdGVkPk5vbmU8L29wdGlvbj4KICAgICAgICAgICAgICA8b3B0aW9uIHZhbHVlPSJwZXJfa2V5d29yZF9jb2wiPlBlciBrZXl3b3JkIGNvbCBzdWZmaXggKGt3fHZvbD0xMjMpPC9vcHRpb24+CiAgICAgICAgICAgICAgPG9wdGlvbiB2YWx1ZT0ic2luZ2xlX2NvbCI+U2luZ2xlIGNvbHVtbiBhcHBsaWVzIHRvIGFsbCBrZXl3b3Jkczwvb3B0aW9uPgogICAgICAgICAgICA8L3NlbGVjdD4KICAgICAgICAgIDwvZGl2PgogICAgICAgIDwvZGl2PgogICAgICAgIDxsYWJlbCBmb3I9IndLZXl3b3JkQ29scyI+S2V5d29yZCBjb2x1bW5zIChjb21tYSBoZWFkZXJzLCBibGFuaz1hdXRvKTwvbGFiZWw+CiAgICAgICAgPGlucHV0IGlkPSJ3S2V5d29yZENvbHMiIHBsYWNlaG9sZGVyPSJibGFuayA9IGFsbCBub24tYmFzZSBjb2x1bW5zIi8+CiAgICAgICAgPGxhYmVsIGlkPSJ3Vm9sdW1lQ29sTGFiZWwiIGZvcj0id1ZvbHVtZUNvbCIgc3R5bGU9ImRpc3BsYXk6bm9uZTsiPlZvbHVtZSBjb2x1bW4gKHNpbmdsZV9jb2wpPC9sYWJlbD4KICAgICAgICA8c2VsZWN0IGlkPSJ3Vm9sdW1lQ29sIiBzdHlsZT0iZGlzcGxheTpub25lOyI+PC9zZWxlY3Q+CiAgICAgIDwvZGl2PgoKICAgICAgPGRpdiBjbGFzcz0ic3ViY2FyZCI+CiAgICAgICAgPGxhYmVsPlZhbGlkYXRpb248L2xhYmVsPgogICAgICAgIDxkaXYgY2xhc3M9ImJ0bnJvdzMiPgogICAgICAgICAgPGJ1dHRvbiBpZD0ic2hvd0Vycm9yc0J0biIgZGlzYWJsZWQ+U2hvdyBlcnJvcnM8L2J1dHRvbj4KICAgICAgICAgIDxidXR0b24gaWQ9ImRvd25sb2FkRXJyb3JzQnRuIiBkaXNhYmxlZD5Eb3dubG9hZCBlcnJvciByb3dzIENTVjwvYnV0dG9uPgogICAgICAgICAgPGJ1dHRvbiBpZD0iZG93bmxvYWROb3JtYWxpemVkQnRuIiBkaXNhYmxlZD5Eb3dubG9hZCBub3JtYWxpemVkIENTVjwvYnV0dG9uPgogICAgICAgIDwvZGl2PgogICAgICAgIDxkaXYgY2xhc3M9InNtYWxsIiBpZD0idmFsaWRhdGlvblN1bW1hcnkiPk5vIHZhbGlkYXRpb24geWV0LjwvZGl2PgogICAgICA8L2Rpdj4KICAgIDwvZGl2PgoKICAgIDxkaXYgY2xhc3M9InN1YmNhcmQiPgogICAgICA8bGFiZWw+RmlsdGVyczwvbGFiZWw+CiAgICAgIDxkaXYgY2xhc3M9InJvdzMiPgogICAgICAgIDxkaXY+PGxhYmVsIGZvcj0iYnVzaW5lc3NGaWx0ZXIiPkJ1c2luZXNzPC9sYWJlbD48c2VsZWN0IGlkPSJidXNpbmVzc0ZpbHRlciIgZGlzYWJsZWQ+PC9zZWxlY3Q+PC9kaXY+CiAgICAgICAgPGRpdj48bGFiZWwgZm9yPSJkYXRlRmlsdGVyIj5EYXRlPC9sYWJlbD48c2VsZWN0IGlkPSJkYXRlRmlsdGVyIiBkaXNhYmxlZD48L3NlbGVjdD48L2Rpdj4KICAgICAgICA8ZGl2PjxsYWJlbCBmb3I9ImtleXdvcmRTZWxlY3QiPktleXdvcmQ8L2xhYmVsPjxzZWxlY3QgaWQ9ImtleXdvcmRTZWxlY3QiIGRpc2FibGVkPjwvc2VsZWN0PjwvZGl2PgogICAgICA8L2Rpdj4KCiAgICAgIDxkaXYgY2xhc3M9InJvdzMiPgogICAgICAgIDxkaXY+PGxhYmVsIGZvcj0ibWF4UmFuayI+V29yc3QgcmFuazwvbGFiZWw+PGlucHV0IGlkPSJtYXhSYW5rIiB0eXBlPSJudW1iZXIiIG1pbj0iMiIgdmFsdWU9IjIwIi8+PC9kaXY+CiAgICAgICAgPGRpdj48bGFiZWwgZm9yPSJncmlkU2l6ZSI+UmVzb2x1dGlvbjwvbGFiZWw+CiAgICAgICAgICA8c2VsZWN0IGlkPSJncmlkU2l6ZSI+CiAgICAgICAgICAgIDxvcHRpb24gdmFsdWU9IjMwIj5Mb3cgKDMwKTwvb3B0aW9uPgogICAgICAgICAgICA8b3B0aW9uIHZhbHVlPSI0NSIgc2VsZWN0ZWQ+TWVkaXVtICg0NSk8L29wdGlvbj4KICAgICAgICAgICAgPG9wdGlvbiB2YWx1ZT0iNzAiPkhpZ2ggKDcwKTwvb3B0aW9uPgogICAgICAgICAgICA8b3B0aW9uIHZhbHVlPSIxMDAiPlVsdHJhICgxMDApPC9vcHRpb24+CiAgICAgICAgICA8L3NlbGVjdD4KICAgICAgICA8L2Rpdj4KICAgICAgICA8ZGl2PjxsYWJlbCBmb3I9InBvd2VyIj5JRFcgcG93ZXI8L2xhYmVsPjxpbnB1dCBpZD0icG93ZXIiIHR5cGU9Im51bWJlciIgc3RlcD0iMC4yNSIgbWluPSIwLjUiIG1heD0iOCIgdmFsdWU9IjIiLz48L2Rpdj4KICAgICAgPC9kaXY+CgogICAgICA8ZGl2IGNsYXNzPSJyb3czIj4KICAgICAgICA8ZGl2PjxsYWJlbCBmb3I9InJhZGl1c1B4Ij5JbmZsdWVuY2UgcmFkaXVzIChweCk8L2xhYmVsPjxpbnB1dCBpZD0icmFkaXVzUHgiIHR5cGU9Im51bWJlciIgbWluPSI0MCIgbWF4PSI1MDAwIiB2YWx1ZT0iMjgwIi8+PC9kaXY+CiAgICAgICAgPGRpdj48bGFiZWwgZm9yPSJpbnRlcnBNb2RlIj5JbnRlcnBvbGF0aW9uPC9sYWJlbD4KICAgICAgICAgIDxzZWxlY3QgaWQ9ImludGVycE1vZGUiPgogICAgICAgICAgICA8b3B0aW9uIHZhbHVlPSJpZHciIHNlbGVjdGVkPklEVzwvb3B0aW9uPgogICAgICAgICAgICA8b3B0aW9uIHZhbHVlPSJuZWFyZXN0Ij5OZWFyZXN0PC9vcHRpb24+CiAgICAgICAgICAgIDxvcHRpb24gdmFsdWU9ImdhdXNzIj5HYXVzc2lhbjwvb3B0aW9uPgogICAgICAgICAgPC9zZWxlY3Q+CiAgICAgICAgPC9kaXY+CiAgICAgICAgPGRpdj48bGFiZWwgZm9yPSJnYXVzc1NpZ21hIj5HYXVzc2lhbiBzaWdtYSAocHgpPC9sYWJlbD48aW5wdXQgaWQ9ImdhdXNzU2lnbWEiIHR5cGU9Im51bWJlciIgbWluPSIxMCIgbWF4PSIyMDAwIiB2YWx1ZT0iMjIwIi8+PC9kaXY+CiAgICAgIDwvZGl2PgoKICAgICAgPGRpdiBjbGFzcz0icm93MyI+CiAgICAgICAgPGRpdj48bGFiZWwgZm9yPSJjb2xvck1vZGUiPkNvbG9yPC9sYWJlbD4KICAgICAgICAgIDxzZWxlY3QgaWQ9ImNvbG9yTW9kZSIgZGlzYWJsZWQ+CiAgICAgICAgICAgIDxvcHRpb24gdmFsdWU9ImdyYWRpZW50IiBzZWxlY3RlZD5HcmFkaWVudDwvb3B0aW9uPgogICAgICAgICAgICA8b3B0aW9uIHZhbHVlPSJidWNrZXRzIj5CdWNrZXRzPC9vcHRpb24+CiAgICAgICAgICA8L3NlbGVjdD4KICAgICAgICA8L2Rpdj4KICAgICAgICA8ZGl2PjxsYWJlbCBmb3I9ImJ1Y2tldEN1dHMiPkJ1Y2tldCBjdXRzPC9sYWJlbD48aW5wdXQgaWQ9ImJ1Y2tldEN1dHMiIGRpc2FibGVkIHZhbHVlPSIzLDEwLDIwIi8+PC9kaXY+CiAgICAgICAgPGRpdj48bGFiZWwgZm9yPSJtaXNzaW5nUG9saWN5Ij5NaXNzaW5nIHJhbmtzPC9sYWJlbD4KICAgICAgICAgIDxzZWxlY3QgaWQ9Im1pc3NpbmdQb2xpY3kiPgogICAgICAgICAgICA8b3B0aW9uIHZhbHVlPSJkcm9wIiBzZWxlY3RlZD5Ecm9wPC9vcHRpb24+CiAgICAgICAgICAgIDxvcHRpb24gdmFsdWU9ImNhcCI+Q2FwIHRvIChtYXhSYW5rKzEpPC9vcHRpb24+CiAgICAgICAgICA8L3NlbGVjdD4KICAgICAgICA8L2Rpdj4KICAgICAgPC9kaXY+CgogICAgICA8ZGl2IGNsYXNzPSJyb3czIj4KICAgICAgICA8ZGl2PjxsYWJlbCBmb3I9Im1hc2tNb2RlIj5NYXNrIGhlYXRtYXA8L2xhYmVsPgogICAgICAgICAgPHNlbGVjdCBpZD0ibWFza01vZGUiIGRpc2FibGVkPgogICAgICAgICAgICA8b3B0aW9uIHZhbHVlPSJvZmYiIHNlbGVjdGVkPk9mZjwvb3B0aW9uPgogICAgICAgICAgICA8b3B0aW9uIHZhbHVlPSJnZW9qc29uIj5HZW9KU09OIHBvbHlnb248L29wdGlvbj4KICAgICAgICAgICAgPG9wdGlvbiB2YWx1ZT0iZHJhd24iPkRyYXduIHBvbHlnb248L29wdGlvbj4KICAgICAgICAgIDwvc2VsZWN0PgogICAgICAgIDwvZGl2PgogICAgICAgIDxkaXY+PGxhYmVsIGZvcj0iYmdNb2RlIj5CYWNrZ3JvdW5kPC9sYWJlbD4KICAgICAgICAgIDxzZWxlY3QgaWQ9ImJnTW9kZSIgZGlzYWJsZWQ+CiAgICAgICAgICAgIDxvcHRpb24gdmFsdWU9ImRhcmsiIHNlbGVjdGVkPkRhcms8L29wdGlvbj4KICAgICAgICAgICAgPG9wdGlvbiB2YWx1ZT0ibGlnaHQiPkxpZ2h0PC9vcHRpb24+CiAgICAgICAgICA8L3NlbGVjdD4KICAgICAgICA8L2Rpdj4KICAgICAgICA8ZGl2PjxsYWJlbCBmb3I9ImxhYmVsc01vZGUiPkxhYmVsczwvbGFiZWw+CiAgICAgICAgICA8c2VsZWN0IGlkPSJsYWJlbHNNb2RlIiBkaXNhYmxlZD4KICAgICAgICAgICAgPG9wdGlvbiB2YWx1ZT0ib24iIHNlbGVjdGVkPk9uPC9vcHRpb24+CiAgICAgICAgICAgIDxvcHRpb24gdmFsdWU9Im9mZiI+T2ZmPC9vcHRpb24+CiAgICAgICAgICA8L3NlbGVjdD4KICAgICAgICA8L2Rpdj4KICAgICAgPC9kaXY+CgogICAgICA8ZGl2IGNsYXNzPSJidG5yb3czIj4KICAgICAgICA8YnV0dG9uIGlkPSJyZW5kZXJCdG4iIGRpc2FibGVkPlJlbmRlcjwvYnV0dG9uPgogICAgICAgIDxidXR0b24gaWQ9ImV4cG9ydFBuZ0J0biIgZGlzYWJsZWQ+RXhwb3J0IFBORzwvYnV0dG9uPgogICAgICAgIDxidXR0b24gaWQ9InJlcG9ydEJ0biIgZGlzYWJsZWQ+T25lLXBhZ2UgcmVwb3J0PC9idXR0b24+CiAgICAgIDwvZGl2PgoKICAgICAgPGRpdiBjbGFzcz0iYnRucm93MyI+CiAgICAgICAgPGJ1dHRvbiBpZD0iZXhwb3J0UGluc0J0biIgZGlzYWJsZWQ+RXhwb3J0IHBpbnMgQ1NWPC9idXR0b24+CiAgICAgICAgPGJ1dHRvbiBpZD0iY2xlYXJQaW5zQnRuIiBkaXNhYmxlZD5DbGVhciBwaW5zPC9idXR0b24+CiAgICAgICAgPGJ1dHRvbiBpZD0iZXhwb3J0U3ZnQnRuIiBkaXNhYmxlZD5FeHBvcnQgU1ZHPC9idXR0b24+CiAgICAgIDwvZGl2PgogICAgPC9kaXY+CgogICAgPGRpdiBjbGFzcz0ic3ViY2FyZCI+CiAgICAgIDxsYWJlbD5CdXNpbmVzcyBwb2ludCAmIGRpc3RhbmNlIHJpbmdzPC9sYWJlbD4KICAgICAgPGRpdiBjbGFzcz0icm93MyI+CiAgICAgICAgPGRpdj48bGFiZWwgZm9yPSJiaXpMYXQiPkJ1c2luZXNzIGxhdC94PC9sYWJlbD48aW5wdXQgaWQ9ImJpekxhdCIgdHlwZT0ibnVtYmVyIiBzdGVwPSIwLjAwMDAwMSIvPjwvZGl2PgogICAgICAgIDxkaXY+PGxhYmVsIGZvcj0iYml6TG5nIj5CdXNpbmVzcyBsbmcveTwvbGFiZWw+PGlucHV0IGlkPSJiaXpMbmciIHR5cGU9Im51bWJlciIgc3RlcD0iMC4wMDAwMDEiLz48L2Rpdj4KICAgICAgICA8ZGl2PjxsYWJlbCBmb3I9InJpbmdzIj5SaW5ncyAobWlsZXMsIGNvbW1hKTwvbGFiZWw+PGlucHV0IGlkPSJyaW5ncyIgdmFsdWU9IjEsMyw1Ii8+PC9kaXY+CiAgICAgIDwvZGl2PgogICAgICA8ZGl2IGNsYXNzPSJzbWFsbCI+TGF0L0xuZyByaW5ncyBhcHByb3hpbWF0ZSBtaWxlcy4gWC9ZIG1vZGUgdXNlcyB5b3VyIHVuaXRzLjwvZGl2PgogICAgPC9kaXY+CgogICAgPGRpdiBjbGFzcz0ic3ViY2FyZCI+CiAgICAgIDxsYWJlbD5Cb3VuZGFyaWVzICYgRHJhd2luZzwvbGFiZWw+CiAgICAgIDxkaXYgY2xhc3M9InJvdzMiPgogICAgICAgIDxkaXY+PGxhYmVsIGZvcj0iZ2VvRmlsZSI+VXBsb2FkIEdlb0pTT048L2xhYmVsPjxpbnB1dCBpZD0iZ2VvRmlsZSIgdHlwZT0iZmlsZSIgYWNjZXB0PSIuZ2VvanNvbiwuanNvbixhcHBsaWNhdGlvbi9nZW8ranNvbixhcHBsaWNhdGlvbi9qc29uIi8+PC9kaXY+CiAgICAgICAgPGRpdj48bGFiZWwgZm9yPSJnZW9TdHlsZSI+R2VvSlNPTiBzdHlsZTwvbGFiZWw+CiAgICAgICAgICA8c2VsZWN0IGlkPSJnZW9TdHlsZSIgZGlzYWJsZWQ+CiAgICAgICAgICAgIDxvcHRpb24gdmFsdWU9Im91dGxpbmUiIHNlbGVjdGVkPk91dGxpbmU8L29wdGlvbj4KICAgICAgICAgICAgPG9wdGlvbiB2YWx1ZT0iZmlsbCI+RmlsbCtPdXRsaW5lPC9vcHRpb24+CiAgICAgICAgICAgIDxvcHRpb24gdmFsdWU9Im9mZiI+T2ZmPC9vcHRpb24+CiAgICAgICAgICA8L3NlbGVjdD4KICAgICAgICA8L2Rpdj4KICAgICAgICA8ZGl2PjxsYWJlbD5HZW9KU09OPC9sYWJlbD48YnV0dG9uIGlkPSJjbGVhckdlb0J0biIgZGlzYWJsZWQ+Q2xlYXIgR2VvSlNPTjwvYnV0dG9uPjwvZGl2PgogICAgICA8L2Rpdj4KCiAgICAgIDxsYWJlbD5EcmF3IHBvbHlnb24gKHdpdGggaG9sZXMpIG9uIGNhbnZhcyAoTGF0L0xuZyBvbmx5KTwvbGFiZWw+CiAgICAgIDxkaXYgY2xhc3M9ImJ0bnJvdzQiPgogICAgICAgIDxidXR0b24gaWQ9ImRyYXdUb2dnbGVCdG4iIGRpc2FibGVkPlN0YXJ0IGRyYXdpbmc8L2J1dHRvbj4KICAgICAgICA8YnV0dG9uIGlkPSJkcmF3VW5kb0J0biIgZGlzYWJsZWQ+VW5kbzwvYnV0dG9uPgogICAgICAgIDxidXR0b24gaWQ9ImRyYXdBZGRIb2xlQnRuIiBkaXNhYmxlZD5BZGQgaG9sZTwvYnV0dG9uPgogICAgICAgIDxidXR0b24gaWQ9ImRyYXdGaW5pc2hCdG4iIGRpc2FibGVkPkZpbmlzaDwvYnV0dG9uPgogICAgICA8L2Rpdj4KCiAgICAgIDxkaXYgY2xhc3M9ImJ0bnJvdzMiPgogICAgICAgIDxidXR0b24gaWQ9ImNvcHlHZW9CdG4iIGRpc2FibGVkPkNvcHkgR2VvSlNPTjwvYnV0dG9uPgogICAgICAgIDxidXR0b24gaWQ9InNhdmVQcm9qZWN0QnRuIiBkaXNhYmxlZD5TYXZlIHByb2plY3Q8L2J1dHRvbj4KICAgICAgICA8YnV0dG9uIGlkPSJsb2FkUHJvamVjdEJ0biI+TG9hZCBwcm9qZWN0PC9idXR0b24+CiAgICAgIDwvZGl2PgogICAgICA8aW5wdXQgaWQ9InByb2plY3RGaWxlIiB0eXBlPSJmaWxlIiBhY2NlcHQ9Ii5qc29uLGFwcGxpY2F0aW9uL2pzb24iIHN0eWxlPSJkaXNwbGF5Om5vbmUiLz4KICAgIDwvZGl2PgoKICAgIDxkaXYgY2xhc3M9InRhYnMiPgogICAgICA8YnV0dG9uIGNsYXNzPSJ0YWJidG4gYWN0aXZlIiBkYXRhLXRhYj0idGFiU3RhdHMiPlN0YXRzPC9idXR0b24+CiAgICAgIDxidXR0b24gY2xhc3M9InRhYmJ0biIgZGF0YS10YWI9InRhYkxvY2F0aW9ucyI+TG9jYXRpb25zPC9idXR0b24+CiAgICAgIDxidXR0b24gY2xhc3M9InRhYmJ0biIgZGF0YS10YWI9InRhYk9wcHMiPk9wcG9ydHVuaXRpZXM8L2J1dHRvbj4KICAgICAgPGJ1dHRvbiBjbGFzcz0idGFiYnRuIiBkYXRhLXRhYj0idGFiRXJyb3JzIj5FcnJvcnM8L2J1dHRvbj4KICAgIDwvZGl2PgoKICAgIDxkaXYgaWQ9InRhYlN0YXRzIiBjbGFzcz0idGFicGFuZWwgYWN0aXZlIHN1YmNhcmQiPgogICAgICA8bGFiZWw+S2V5d29yZCBzdGF0czwvbGFiZWw+CiAgICAgIDxkaXYgY2xhc3M9InJvdyI+CiAgICAgICAgPGRpdj48bGFiZWwgZm9yPSJzdGF0c0ZpbHRlciI+RmlsdGVyPC9sYWJlbD48aW5wdXQgaWQ9InN0YXRzRmlsdGVyIiBwbGFjZWhvbGRlcj0idHlwZSB0byBmaWx0ZXLigKYiLz48L2Rpdj4KICAgICAgICA8ZGl2PjxsYWJlbCBmb3I9InN0YXRzU29ydCI+U29ydDwvbGFiZWw+CiAgICAgICAgICA8c2VsZWN0IGlkPSJzdGF0c1NvcnQiPgogICAgICAgICAgICA8b3B0aW9uIHZhbHVlPSJhdmciIHNlbGVjdGVkPkF2ZyByYW5rIChhc2MpPC9vcHRpb24+CiAgICAgICAgICAgIDxvcHRpb24gdmFsdWU9InRvcDMiPlRvcDMlIChkZXNjKTwvb3B0aW9uPgogICAgICAgICAgICA8b3B0aW9uIHZhbHVlPSJjb3VudCI+Q291bnQgKGRlc2MpPC9vcHRpb24+CiAgICAgICAgICAgIDxvcHRpb24gdmFsdWU9ImJlc3QiPkJlc3QgcmFuayAoYXNjKTwvb3B0aW9uPgogICAgICAgICAgPC9zZWxlY3Q+CiAgICAgICAgPC9kaXY+CiAgICAgIDwvZGl2PgogICAgICA8ZGl2IGNsYXNzPSJzbWFsbCBtb25vIiBpZD0ic2VsZWN0ZWRTdGF0cyI+Tm8gZGF0YS48L2Rpdj4KICAgICAgPGRpdiBjbGFzcz0ic2Nyb2xsIiBzdHlsZT0ibWFyZ2luLXRvcDoxMHB4OyI+CiAgICAgICAgPHRhYmxlPgogICAgICAgICAgPHRoZWFkPjx0cj4KICAgICAgICAgICAgPHRoPktleXdvcmQ8L3RoPjx0aD5Db3VudDwvdGg+PHRoPkF2ZzwvdGg+PHRoPk1lZDwvdGg+PHRoPkJlc3Q8L3RoPjx0aD5Xb3JzdDwvdGg+PHRoPlRvcDMlPC90aD48dGg+VG9wMTAlPC90aD48dGg+VG9wMjAlPC90aD4KICAgICAgICAgIDwvdHI+PC90aGVhZD4KICAgICAgICAgIDx0Ym9keSBpZD0ic3RhdHNCb2R5Ij48L3Rib2R5PgogICAgICAgIDwvdGFibGU+CiAgICAgIDwvZGl2PgogICAgICA8ZGl2IGNsYXNzPSJidG5yb3ciPgogICAgICAgIDxidXR0b24gaWQ9ImNvcHlTdGF0c0J0biIgZGlzYWJsZWQ+Q29weSBzdGF0cyBDU1Y8L2J1dHRvbj4KICAgICAgICA8YnV0dG9uIGlkPSJkb3dubG9hZFN0YXRzQnRuIiBkaXNhYmxlZD5Eb3dubG9hZCBzdGF0cyBDU1Y8L2J1dHRvbj4KICAgICAgPC9kaXY+CiAgICA8L2Rpdj4KCiAgICA8ZGl2IGlkPSJ0YWJMb2NhdGlvbnMiIGNsYXNzPSJ0YWJwYW5lbCBzdWJjYXJkIj4KICAgICAgPGxhYmVsPkxvY2F0aW9uIHJvbGx1cHM8L2xhYmVsPgogICAgICA8ZGl2IGNsYXNzPSJyb3ciPgogICAgICAgIDxkaXY+PGxhYmVsIGZvcj0ibG9jRmlsdGVyIj5GaWx0ZXI8L2xhYmVsPjxpbnB1dCBpZD0ibG9jRmlsdGVyIiBwbGFjZWhvbGRlcj0idHlwZSB0byBmaWx0ZXLigKYiLz48L2Rpdj4KICAgICAgICA8ZGl2PjxsYWJlbCBmb3I9ImxvY1NvcnQiPlNvcnQ8L2xhYmVsPgogICAgICAgICAgPHNlbGVjdCBpZD0ibG9jU29ydCI+CiAgICAgICAgICAgIDxvcHRpb24gdmFsdWU9ImF2ZyIgc2VsZWN0ZWQ+QXZnIHJhbmsgKGFzYyk8L29wdGlvbj4KICAgICAgICAgICAgPG9wdGlvbiB2YWx1ZT0idG9wMyI+VG9wMyUgKGRlc2MpPC9vcHRpb24+CiAgICAgICAgICAgIDxvcHRpb24gdmFsdWU9InRvcDEwIj5Ub3AxMCUgKGRlc2MpPC9vcHRpb24+CiAgICAgICAgICAgIDxvcHRpb24gdmFsdWU9ImNvdW50Ij5Db3VudCAoZGVzYyk8L29wdGlvbj4KICAgICAgICAgIDwvc2VsZWN0PgogICAgICAgIDwvZGl2PgogICAgICA8L2Rpdj4KICAgICAgPGRpdiBjbGFzcz0ic2Nyb2xsIiBzdHlsZT0ibWFyZ2luLXRvcDoxMHB4OyI+CiAgICAgICAgPHRhYmxlPgogICAgICAgICAgPHRoZWFkPjx0cj48dGg+TG9jYXRpb248L3RoPjx0aD5Db3VudDwvdGg+PHRoPkF2ZzwvdGg+PHRoPlRvcDMlPC90aD48dGg+VG9wMTAlPC90aD48dGg+VG9wMjAlPC90aD48dGg+V29yc3Qga2V5d29yZDwvdGg+PC90cj48L3RoZWFkPgogICAgICAgICAgPHRib2R5IGlkPSJsb2NCb2R5Ij48L3Rib2R5PgogICAgICAgIDwvdGFibGU+CiAgICAgIDwvZGl2PgogICAgICA8ZGl2IGNsYXNzPSJidG5yb3ciPgogICAgICAgIDxidXR0b24gaWQ9ImNvcHlMb2NCdG4iIGRpc2FibGVkPkNvcHkgbG9jYXRpb25zIENTVjwvYnV0dG9uPgogICAgICAgIDxidXR0b24gaWQ9ImRvd25sb2FkTG9jQnRuIiBkaXNhYmxlZD5Eb3dubG9hZCBsb2NhdGlvbnMgQ1NWPC9idXR0b24+CiAgICAgIDwvZGl2PgogICAgPC9kaXY+CgogICAgPGRpdiBpZD0idGFiT3BwcyIgY2xhc3M9InRhYnBhbmVsIHN1YmNhcmQiPgogICAgICA8bGFiZWw+T3Bwb3J0dW5pdGllczwvbGFiZWw+CiAgICAgIDxkaXYgY2xhc3M9InJvdyI+CiAgICAgICAgPGRpdj48bGFiZWwgZm9yPSJvcHBNb2RlIj5Hb2FsPC9sYWJlbD4KICAgICAgICAgIDxzZWxlY3QgaWQ9Im9wcE1vZGUiPgogICAgICAgICAgICA8b3B0aW9uIHZhbHVlPSJ0b3AzIiBzZWxlY3RlZD5Ub3AgMzwvb3B0aW9uPgogICAgICAgICAgICA8b3B0aW9uIHZhbHVlPSJ0b3AxMCI+VG9wIDEwPC9vcHRpb24+CiAgICAgICAgICAgIDxvcHRpb24gdmFsdWU9InRvcDIwIj5Ub3AgMjA8L29wdGlvbj4KICAgICAgICAgIDwvc2VsZWN0PgogICAgICAgIDwvZGl2PgogICAgICAgIDxkaXY+PGxhYmVsIGZvcj0ib3BwTWluQ291bnQiPk1pbiBsb2NhdGlvbnM8L2xhYmVsPjxpbnB1dCBpZD0ib3BwTWluQ291bnQiIHR5cGU9Im51bWJlciIgbWluPSIxIiB2YWx1ZT0iNiIvPjwvZGl2PgogICAgICA8L2Rpdj4KICAgICAgPGRpdiBjbGFzcz0ic2Nyb2xsIiBzdHlsZT0ibWFyZ2luLXRvcDoxMHB4OyI+CiAgICAgICAgPHRhYmxlPgogICAgICAgICAgPHRoZWFkPjx0cj48dGg+S2V5d29yZDwvdGg+PHRoPkF2ZzwvdGg+PHRoPlRvcCU8L3RoPjx0aD5KdXN0LW1pc3MlPC90aD48dGg+Vm9sdW1lPC90aD48dGg+U2NvcmU8L3RoPjwvdHI+PC90aGVhZD4KICAgICAgICAgIDx0Ym9keSBpZD0ib3BwQm9keSI+PC90Ym9keT4KICAgICAgICA8L3RhYmxlPgogICAgICA8L2Rpdj4KICAgICAgPGRpdiBjbGFzcz0iYnRucm93Ij4KICAgICAgICA8YnV0dG9uIGlkPSJjb3B5T3BwQnRuIiBkaXNhYmxlZD5Db3B5IG9wcG9ydHVuaXRpZXMgQ1NWPC9idXR0b24+CiAgICAgICAgPGJ1dHRvbiBpZD0iZG93bmxvYWRPcHBCdG4iIGRpc2FibGVkPkRvd25sb2FkIG9wcG9ydHVuaXRpZXMgQ1NWPC9idXR0b24+CiAgICAgIDwvZGl2PgogICAgPC9kaXY+CgogICAgPGRpdiBpZD0idGFiRXJyb3JzIiBjbGFzcz0idGFicGFuZWwgc3ViY2FyZCI+CiAgICAgIDxsYWJlbD5WYWxpZGF0aW9uIGVycm9yczwvbGFiZWw+CiAgICAgIDxkaXYgY2xhc3M9InNtYWxsIG1vbm8iIGlkPSJlcnJvcnNUZXh0Ij5ObyBlcnJvcnMuPC9kaXY+CiAgICA8L2Rpdj4KCiAgICA8ZGl2IGNsYXNzPSJzdGF0dXMiIGlkPSJzdGF0dXMiPjwvZGl2PgogIDwvc2VjdGlvbj4KCiAgPHNlY3Rpb24gY2xhc3M9ImNhbnZhc1dyYXAgY2FyZCI+CiAgICA8ZGl2IGNsYXNzPSJ0b29sYmFyIj4KICAgICAgPGRpdj48bGFiZWw+VmlldzwvbGFiZWw+CiAgICAgICAgPHNlbGVjdCBpZD0idmlld01vZGUiIGRpc2FibGVkPgogICAgICAgICAgPG9wdGlvbiB2YWx1ZT0iaGVhdCtwb2ludHMiIHNlbGVjdGVkPkhlYXQgKyBwb2ludHM8L29wdGlvbj4KICAgICAgICAgIDxvcHRpb24gdmFsdWU9ImhlYXQiPkhlYXQgb25seTwvb3B0aW9uPgogICAgICAgICAgPG9wdGlvbiB2YWx1ZT0icG9pbnRzIj5Qb2ludHMgb25seTwvb3B0aW9uPgogICAgICAgIDwvc2VsZWN0PgogICAgICA8L2Rpdj4KICAgICAgPGRpdj48bGFiZWw+TGVnZW5kPC9sYWJlbD4KICAgICAgICA8c2VsZWN0IGlkPSJsZWdlbmRNb2RlIiBkaXNhYmxlZD4KICAgICAgICAgIDxvcHRpb24gdmFsdWU9Im9uIiBzZWxlY3RlZD5Pbjwvb3B0aW9uPgogICAgICAgICAgPG9wdGlvbiB2YWx1ZT0ib2ZmIj5PZmY8L29wdGlvbj4KICAgICAgICA8L3NlbGVjdD4KICAgICAgPC9kaXY+CiAgICAgIDxkaXY+PGxhYmVsPkluc3BlY3RvcjwvbGFiZWw+CiAgICAgICAgPHNlbGVjdCBpZD0iaW5zcGVjdE1vZGUiIGRpc2FibGVkPgogICAgICAgICAgPG9wdGlvbiB2YWx1ZT0ib24iIHNlbGVjdGVkPk9uPC9vcHRpb24+CiAgICAgICAgICA8b3B0aW9uIHZhbHVlPSJvZmYiPk9mZjwvb3B0aW9uPgogICAgICAgIDwvc2VsZWN0PgogICAgICA8L2Rpdj4KICAgICAgPGRpdj48bGFiZWw+UHJldmlldzwvbGFiZWw+CiAgICAgICAgPHNlbGVjdCBpZD0icHJldmlld01vZGUiIGRpc2FibGVkPgogICAgICAgICAgPG9wdGlvbiB2YWx1ZT0ib24iIHNlbGVjdGVkPk9uPC9vcHRpb24+CiAgICAgICAgICA8b3B0aW9uIHZhbHVlPSJvZmYiPk9mZjwvb3B0aW9uPgogICAgICAgIDwvc2VsZWN0PgogICAgICA8L2Rpdj4KICAgIDwvZGl2PgogICAgPGNhbnZhcyBpZD0ibWFwIiB3aWR0aD0iMTIwMCIgaGVpZ2h0PSI4MDAiPjwvY2FudmFzPgogICAgPGRpdiBjbGFzcz0ic21hbGwiIGlkPSJob3ZlclJlYWRvdXQiPkhvdmVyOiDigJQ8L2Rpdj4KICA8L3NlY3Rpb24+CjwvbWFpbj4KCjxzY3JpcHQ+CigoKSA9PiB7CiAgInVzZSBzdHJpY3QiOwoKICBjb25zdCAkID0gKGlkKSA9PiBkb2N1bWVudC5nZXRFbGVtZW50QnlJZChpZCk7CiAgY29uc3QgZWwgPSB7CiAgICBwcm9qZWN0TmFtZTogJCgicHJvamVjdE5hbWUiKSwgdW5pdHM6ICQoInVuaXRzIiksCiAgICBwYXN0ZUJ0bjogJCgicGFzdGVCdG4iKSwgYWRkQ3N2QnRuOiAkKCJhZGRDc3ZCdG4iKSwgY3N2RmlsZXM6ICQoImNzdkZpbGVzIiksCiAgICBjbGVhckltcG9ydHNCdG46ICQoImNsZWFySW1wb3J0c0J0biIpLCBsb2FkU2FtcGxlQnRuOiAkKCJsb2FkU2FtcGxlQnRuIiksIGNzdlRleHQ6ICQoImNzdlRleHQiKSwKICAgIGRldGVjdEZvcm1hdEJ0bjogJCgiZGV0ZWN0Rm9ybWF0QnRuIiksIGF1dG9NYXBCdG46ICQoImF1dG9NYXBCdG4iKSwgYnVpbGRCdG46ICQoImJ1aWxkQnRuIiksCiAgICBjc3ZGb3JtYXQ6ICQoImNzdkZvcm1hdCIpLCBmb3JtYXRIaW50OiAkKCJmb3JtYXRIaW50IiksCiAgICBtYXBwaW5nTG9uZ0Jsb2NrOiAkKCJtYXBwaW5nTG9uZ0Jsb2NrIiksIG1hcHBpbmdXaWRlQmxvY2s6ICQoIm1hcHBpbmdXaWRlQmxvY2siKSwKICAgIG1LZXl3b3JkOiAkKCJtS2V5d29yZCIpLCBtTG9jYXRpb246ICQoIm1Mb2NhdGlvbiIpLCBtUmFuazogJCgibVJhbmsiKSwgbVg6ICQoIm1YIiksIG1ZOiAkKCJtWSIpLAogICAgbUJ1c2luZXNzOiAkKCJtQnVzaW5lc3MiKSwgbURhdGU6ICQoIm1EYXRlIiksIG1Wb2x1bWU6ICQoIm1Wb2x1bWUiKSwKICAgIHdMb2NhdGlvbjogJCgid0xvY2F0aW9uIiksIHdYOiAkKCJ3WCIpLCB3WTogJCgid1kiKSwgd0J1c2luZXNzOiAkKCJ3QnVzaW5lc3MiKSwgd0RhdGU6ICQoIndEYXRlIiksCiAgICB3S2V5d29yZENvbHM6ICQoIndLZXl3b3JkQ29scyIpLCB3Vm9sdW1lTW9kZTogJCgid1ZvbHVtZU1vZGUiKSwgd1ZvbHVtZUNvbDogJCgid1ZvbHVtZUNvbCIpLCB3Vm9sdW1lQ29sTGFiZWw6ICQoIndWb2x1bWVDb2xMYWJlbCIpLAogICAgc2hvd0Vycm9yc0J0bjogJCgic2hvd0Vycm9yc0J0biIpLCBkb3dubG9hZEVycm9yc0J0bjogJCgiZG93bmxvYWRFcnJvcnNCdG4iKSwgZG93bmxvYWROb3JtYWxpemVkQnRuOiAkKCJkb3dubG9hZE5vcm1hbGl6ZWRCdG4iKSwKICAgIHZhbGlkYXRpb25TdW1tYXJ5OiAkKCJ2YWxpZGF0aW9uU3VtbWFyeSIpLAogICAgYnVzaW5lc3NGaWx0ZXI6ICQoImJ1c2luZXNzRmlsdGVyIiksIGRhdGVGaWx0ZXI6ICQoImRhdGVGaWx0ZXIiKSwga2V5d29yZFNlbGVjdDogJCgia2V5d29yZFNlbGVjdCIpLAogICAgbWF4UmFuazogJCgibWF4UmFuayIpLCBncmlkU2l6ZTogJCgiZ3JpZFNpemUiKSwgcG93ZXI6ICQoInBvd2VyIiksIHJhZGl1c1B4OiAkKCJyYWRpdXNQeCIpLAogICAgaW50ZXJwTW9kZTogJCgiaW50ZXJwTW9kZSIpLCBnYXVzc1NpZ21hOiAkKCJnYXVzc1NpZ21hIiksCiAgICBjb2xvck1vZGU6ICQoImNvbG9yTW9kZSIpLCBidWNrZXRDdXRzOiAkKCJidWNrZXRDdXRzIiksIG1pc3NpbmdQb2xpY3k6ICQoIm1pc3NpbmdQb2xpY3kiKSwKICAgIG1hc2tNb2RlOiAkKCJtYXNrTW9kZSIpLCBiZ01vZGU6ICQoImJnTW9kZSIpLCBsYWJlbHNNb2RlOiAkKCJsYWJlbHNNb2RlIiksCiAgICByZW5kZXJCdG46ICQoInJlbmRlckJ0biIpLCBleHBvcnRQbmdCdG46ICQoImV4cG9ydFBuZ0J0biIpLCByZXBvcnRCdG46ICQoInJlcG9ydEJ0biIpLAogICAgZXhwb3J0UGluc0J0bjogJCgiZXhwb3J0UGluc0J0biIpLCBjbGVhclBpbnNCdG46ICQoImNsZWFyUGluc0J0biIpLCBleHBvcnRTdmdCdG46ICQoImV4cG9ydFN2Z0J0biIpLAogICAgYml6TGF0OiAkKCJiaXpMYXQiKSwgYml6TG5nOiAkKCJiaXpMbmciKSwgcmluZ3M6ICQoInJpbmdzIiksCiAgICBnZW9GaWxlOiAkKCJnZW9GaWxlIiksIGdlb1N0eWxlOiAkKCJnZW9TdHlsZSIpLCBjbGVhckdlb0J0bjogJCgiY2xlYXJHZW9CdG4iKSwKICAgIGRyYXdUb2dnbGVCdG46ICQoImRyYXdUb2dnbGVCdG4iKSwgZHJhd1VuZG9CdG46ICQoImRyYXdVbmRvQnRuIiksIGRyYXdBZGRIb2xlQnRuOiAkKCJkcmF3QWRkSG9sZUJ0biIpLCBkcmF3RmluaXNoQnRuOiAkKCJkcmF3RmluaXNoQnRuIiksCiAgICBjb3B5R2VvQnRuOiAkKCJjb3B5R2VvQnRuIiksIHNhdmVQcm9qZWN0QnRuOiAkKCJzYXZlUHJvamVjdEJ0biIpLCBsb2FkUHJvamVjdEJ0bjogJCgibG9hZFByb2plY3RCdG4iKSwgcHJvamVjdEZpbGU6ICQoInByb2plY3RGaWxlIiksCiAgICBtZXRhUGlsbDogJCgibWV0YVBpbGwiKSwgZ2VvUGlsbDogJCgiZ2VvUGlsbCIpLCBkcmF3UGlsbDogJCgiZHJhd1BpbGwiKSwgcGluc1BpbGw6ICQoInBpbnNQaWxsIiksCiAgICB0YWJCdG5zOiBBcnJheS5mcm9tKGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3JBbGwoIi50YWJidG4iKSksCiAgICBwYW5lbHM6IFsidGFiU3RhdHMiLCJ0YWJMb2NhdGlvbnMiLCJ0YWJPcHBzIiwidGFiRXJyb3JzIl0ubWFwKCQpLAogICAgc2VsZWN0ZWRTdGF0czogJCgic2VsZWN0ZWRTdGF0cyIpLAogICAgc3RhdHNGaWx0ZXI6ICQoInN0YXRzRmlsdGVyIiksIHN0YXRzU29ydDogJCgic3RhdHNTb3J0IiksIHN0YXRzQm9keTogJCgic3RhdHNCb2R5IiksCiAgICBjb3B5U3RhdHNCdG46ICQoImNvcHlTdGF0c0J0biIpLCBkb3dubG9hZFN0YXRzQnRuOiAkKCJkb3dubG9hZFN0YXRzQnRuIiksCiAgICBsb2NGaWx0ZXI6ICQoImxvY0ZpbHRlciIpLCBsb2NTb3J0OiAkKCJsb2NTb3J0IiksIGxvY0JvZHk6ICQoImxvY0JvZHkiKSwKICAgIGNvcHlMb2NCdG46ICQoImNvcHlMb2NCdG4iKSwgZG93bmxvYWRMb2NCdG46ICQoImRvd25sb2FkTG9jQnRuIiksCiAgICBvcHBNb2RlOiAkKCJvcHBNb2RlIiksIG9wcE1pbkNvdW50OiAkKCJvcHBNaW5Db3VudCIpLCBvcHBCb2R5OiAkKCJvcHBCb2R5IiksCiAgICBjb3B5T3BwQnRuOiAkKCJjb3B5T3BwQnRuIiksIGRvd25sb2FkT3BwQnRuOiAkKCJkb3dubG9hZE9wcEJ0biIpLAogICAgZXJyb3JzVGV4dDogJCgiZXJyb3JzVGV4dCIpLAogICAgc3RhdHVzOiAkKCJzdGF0dXMiKSwKICAgIHZpZXdNb2RlOiAkKCJ2aWV3TW9kZSIpLCBsZWdlbmRNb2RlOiAkKCJsZWdlbmRNb2RlIiksIGluc3BlY3RNb2RlOiAkKCJpbnNwZWN0TW9kZSIpLCBwcmV2aWV3TW9kZTogJCgicHJldmlld01vZGUiKSwKICAgIGhvdmVyUmVhZG91dDogJCgiaG92ZXJSZWFkb3V0IiksCiAgICBjYW52YXM6ICQoIm1hcCIpLAogIH07CiAgY29uc3QgY3R4ID0gZWwuY2FudmFzLmdldENvbnRleHQoIjJkIiwgeyBhbHBoYTogZmFsc2UgfSk7CgogIC8vIFN0YXRlCiAgbGV0IGltcG9ydEJsb2JzID0gW107IC8vIHtuYW1lLHRleHR9W10KICBsZXQgY3VycmVudEhlYWRlcnMgPSBbXTsKICBsZXQgZ2VvanNvbiA9IG51bGwsIGdlb0JCb3ggPSBudWxsOwogIGxldCByb3dzQWxsID0gW10sIHJvd3NGaWx0ZXJlZCA9IFtdOwogIGxldCBieUtleXdvcmQgPSBuZXcgTWFwKCk7CiAgbGV0IHZhbGlkYXRpb24gPSB7IGVycm9yczogW10sIGVycm9yQ3N2OiBudWxsLCBub3JtYWxpemVkQ3N2OiBudWxsIH07CgogIGxldCBwaW5zID0gW107CiAgbGV0IGhvdmVyU3RhdGUgPSBudWxsOwogIGxldCBsYXN0UmVuZGVyQkJveCA9IG51bGw7CiAgbGV0IHJlbmRlclRpbWVyID0gbnVsbCwgbGFzdEludGVyYWN0aW9uQXQgPSAwOwoKICAvLyBkcmF3aW5nIHJpbmdzCiAgbGV0IGRyYXdBY3RpdmUgPSBmYWxzZTsKICBsZXQgZHJhd1JpbmdzID0gW107IC8vIFt7bGF0LGxuZ31dW10gICh4PWxhdCwgeT1sbmcpCiAgbGV0IGFjdGl2ZVJpbmdJbmRleCA9IDA7CiAgbGV0IGRyYXdIb3ZlciA9IG51bGwsIHNuYXBIb3ZlciA9IG51bGw7CiAgY29uc3QgU05BUF9QWCA9IDEyOwoKICAvLyBzdGF0cwogIGxldCBrZXl3b3JkU3RhdHMgPSBbXSwgbG9jYXRpb25TdGF0cyA9IFtdOwogIGxldCBzdGF0c0NzdiA9IG51bGwsIGxvY0NzdiA9IG51bGwsIG9wcENzdiA9IG51bGw7CgogIC8vIG1hcHBpbmcKICBsZXQgbWFwTG9uZyA9IHsga2V5d29yZDoiIiwgbG9jYXRpb246IiIsIHJhbms6IiIsIHg6IiIsIHk6IiIsIGJ1c2luZXNzOiIiLCBkYXRlOiIiLCB2b2x1bWU6IiIgfTsKICBsZXQgbWFwV2lkZSA9IHsgbG9jYXRpb246IiIsIHg6IiIsIHk6IiIsIGJ1c2luZXNzOiIiLCBkYXRlOiIiLCBrZXl3b3JkQ29sczpbXSwgdm9sdW1lTW9kZToibm9uZSIsIHZvbHVtZUNvbDoiIiB9OwoKICAvLyB1dGlscwogIGNvbnN0IGNsYW1wID0gKG4sYSxiKT0+TWF0aC5tYXgoYSxNYXRoLm1pbihiLG4pKTsKICBjb25zdCBub3cgPSAoKT0+cGVyZm9ybWFuY2Uubm93KCk7CiAgY29uc3Qgc2V0U3RhdHVzID0gKG0pPT57IGVsLnN0YXR1cy50ZXh0Q29udGVudCA9IG07IH07CiAgY29uc3Qgc2FmZU51bWJlciA9ICh2KT0+eyBjb25zdCBuPU51bWJlcih2KTsgcmV0dXJuIE51bWJlci5pc0Zpbml0ZShuKT9uOm51bGw7IH07CiAgY29uc3Qgbm9ybWFsaXplSGVhZGVyID0gKGgpPT5TdHJpbmcoaD8/IiIpLnRyaW0oKS50b0xvd2VyQ2FzZSgpLnJlcGxhY2UoL1x1RkVGRi9nLCIiKS5yZXBsYWNlKC9bXlx3XSsvZywiXyIpLnJlcGxhY2UoL15fK3xfKyQvZywiIik7CiAgY29uc3QgY3N2RXNjYXBlID0gKHMpPT57IGNvbnN0IHY9U3RyaW5nKHM/PyIiKTsgcmV0dXJuIC9bIixcblxyXS8udGVzdCh2KT9gIiR7di5yZXBsYWNlKC8iL2csJyIiJyl9ImA6djsgfTsKICBjb25zdCBlc2NhcGVIVE1MID0gKHMpPT5TdHJpbmcocykucmVwbGFjZSgvWyY8PiInXS9nLGM9Pih7ICImIjoiJmFtcDsiLCI8IjoiJmx0OyIsIj4iOiImZ3Q7IiwnIic6IiZxdW90OyIsIiciOiImIzM5OyIgfVtjXSkpOwogIGNvbnN0IGVzY2FwZVhNTCA9IChzKT0+U3RyaW5nKHMpLnJlcGxhY2UoL1s8PiYnIl0vZyxjPT4oeyAiPCI6IiZsdDsiLCI+IjoiJmd0OyIsIiYiOiImYW1wOyIsIiciOiImYXBvczsiLCciJzoiJnF1b3Q7IiB9W2NdKSk7CgogIGZ1bmN0aW9uIGRvd25sb2FkVGV4dChmaWxlbmFtZSwgdGV4dCwgbWltZT0idGV4dC9wbGFpbjtjaGFyc2V0PXV0Zi04Iil7CiAgICBjb25zdCBibG9iID0gbmV3IEJsb2IoW3RleHRdLCB7dHlwZTptaW1lfSk7CiAgICBjb25zdCB1cmwgPSBVUkwuY3JlYXRlT2JqZWN0VVJMKGJsb2IpOwogICAgY29uc3QgYT1kb2N1bWVudC5jcmVhdGVFbGVtZW50KCJhIik7CiAgICBhLmhyZWY9dXJsOyBhLmRvd25sb2FkPWZpbGVuYW1lOwogICAgZG9jdW1lbnQuYm9keS5hcHBlbmRDaGlsZChhKTsgYS5jbGljaygpOyBhLnJlbW92ZSgpOwogICAgVVJMLnJldm9rZU9iamVjdFVSTCh1cmwpOwogIH0KICBhc3luYyBmdW5jdGlvbiBjb3B5VGV4dCh0ZXh0KXsKICAgIGlmKCFuYXZpZ2F0b3IuY2xpcGJvYXJkPy53cml0ZVRleHQpIHRocm93IG5ldyBFcnJvcigiQ2xpcGJvYXJkIEFQSSBub3QgYXZhaWxhYmxlICh1c2UgSFRUUFMgb3IgbG9jYWxob3N0KS4iKTsKICAgIGF3YWl0IG5hdmlnYXRvci5jbGlwYm9hcmQud3JpdGVUZXh0KHRleHQpOwogIH0KICBhc3luYyBmdW5jdGlvbiByZWFkRmlsZUFzVGV4dChmaWxlKXsKICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSxyZWplY3QpPT57CiAgICAgIGNvbnN0IGZyPW5ldyBGaWxlUmVhZGVyKCk7CiAgICAgIGZyLm9ubG9hZD0oKT0+cmVzb2x2ZShTdHJpbmcoZnIucmVzdWx0fHwiIikpOwogICAgICBmci5vbmVycm9yPSgpPT5yZWplY3QoZnIuZXJyb3J8fG5ldyBFcnJvcigiRmlsZSByZWFkIGZhaWxlZCIpKTsKICAgICAgZnIucmVhZEFzVGV4dChmaWxlKTsKICAgIH0pOwogIH0KCiAgLy8gQ1NWIHBhcnNpbmcgKHNpbXBsZSBxdW90ZWQpCiAgZnVuY3Rpb24gcGFyc2VDU1YodGV4dCl7CiAgICBjb25zdCBvdXQ9W107IGxldCByb3c9W107IGxldCBmaWVsZD0iIjsgbGV0IGk9MDsgbGV0IGluUXVvdGVzPWZhbHNlOwogICAgd2hpbGUoaTx0ZXh0Lmxlbmd0aCl7CiAgICAgIGNvbnN0IGM9dGV4dFtpXTsKICAgICAgaWYoaW5RdW90ZXMpewogICAgICAgIGlmKGM9PT0nIicpewogICAgICAgICAgY29uc3QgbmV4dD10ZXh0W2krMV07CiAgICAgICAgICBpZihuZXh0PT09JyInKXsgZmllbGQrPSciJzsgaSs9MjsgY29udGludWU7IH0KICAgICAgICAgIGluUXVvdGVzPWZhbHNlOyBpKys7IGNvbnRpbnVlOwogICAgICAgIH0KICAgICAgICBmaWVsZCs9YzsgaSsrOyBjb250aW51ZTsKICAgICAgfQogICAgICBpZihjPT09JyInKXsgaW5RdW90ZXM9dHJ1ZTsgaSsrOyBjb250aW51ZTsgfQogICAgICBpZihjPT09JywnKXsgcm93LnB1c2goZmllbGQpOyBmaWVsZD0iIjsgaSsrOyBjb250aW51ZTsgfQogICAgICBpZihjPT09J1xuJyB8fCBjPT09J1xyJyl7CiAgICAgICAgaWYoYz09PSdccicgJiYgdGV4dFtpKzFdPT09J1xuJykgaSsrOwogICAgICAgIHJvdy5wdXNoKGZpZWxkKTsgZmllbGQ9IiI7CiAgICAgICAgaWYocm93LnNvbWUodj0+U3RyaW5nKHYpLnRyaW0oKSE9PSIiKSkgb3V0LnB1c2gocm93KTsKICAgICAgICByb3c9W107IGkrKzsgY29udGludWU7CiAgICAgIH0KICAgICAgZmllbGQrPWM7IGkrKzsKICAgIH0KICAgIHJvdy5wdXNoKGZpZWxkKTsKICAgIGlmKHJvdy5zb21lKHY9PlN0cmluZyh2KS50cmltKCkhPT0iIikpIG91dC5wdXNoKHJvdyk7CiAgICByZXR1cm4gb3V0OwogIH0KCiAgZnVuY3Rpb24gZGV0ZWN0Q1NWRm9ybWF0KHBhcnNlZCl7CiAgICBpZighcGFyc2VkLmxlbmd0aCB8fCBwYXJzZWQubGVuZ3RoPDIpIHJldHVybiB7a2luZDoidW5rbm93biIsIHJlYXNvbjoiZW1wdHkvdG9vIHNob3J0In07CiAgICBjb25zdCBoZWFkZXJzPShwYXJzZWRbMF18fFtdKS5tYXAocz0+U3RyaW5nKHM/PyIiKS50cmltKCkpLmZpbHRlcihCb29sZWFuKTsKICAgIGNvbnN0IGhuPWhlYWRlcnMubWFwKG5vcm1hbGl6ZUhlYWRlcik7CiAgICBjb25zdCBoYXNLZXl3b3JkQ29sPWhuLnNvbWUoaD0+WyJrZXl3b3JkIiwia3ciLCJxdWVyeSIsInNlYXJjaF90ZXJtIiwidGVybSIsInBocmFzZSJdLmluY2x1ZGVzKGgpKTsKICAgIGNvbnN0IGhhc0xvY0NvbD1obi5zb21lKGg9PlsibG9jYXRpb24iLCJsb2MiLCJwbGFjZSIsImFyZWEiLCJuZWlnaGJvcmhvb2QiLCJuZWlnaGJvdXJob29kIiwiY2l0eSIsInRvd24iLCJ6aXAiLCJwb3N0YWxfY29kZSIsInBvc3Rjb2RlIiwiYWRkcmVzcyJdLmluY2x1ZGVzKGgpKTsKICAgIGNvbnN0IGlzTGF0TG5nPWVsLnVuaXRzLnZhbHVlPT09ImxhdGxuZyI7CiAgICBjb25zdCBoYXNDb29yZD1pc0xhdExuZwogICAgICA/IChobi5pbmNsdWRlcygibGF0Iil8fGhuLmluY2x1ZGVzKCJsYXRpdHVkZSIpKSAmJiAoaG4uaW5jbHVkZXMoImxuZyIpfHxobi5pbmNsdWRlcygibG9uIil8fGhuLmluY2x1ZGVzKCJsb25naXR1ZGUiKXx8aG4uaW5jbHVkZXMoImxvbmciKSkKICAgICAgOiBobi5pbmNsdWRlcygieCIpICYmIGhuLmluY2x1ZGVzKCJ5Iik7CiAgICBpZighaGFzS2V5d29yZENvbCAmJiBoYXNDb29yZCAmJiBoYXNMb2NDb2wgJiYgaGVhZGVycy5sZW5ndGg+PTYpewogICAgICBjb25zdCByb3cxPXBhcnNlZFsxXXx8W107CiAgICAgIGxldCBudW1lcmljQ291bnQ9MDsKICAgICAgZm9yKGxldCBpPTA7aTxoZWFkZXJzLmxlbmd0aDtpKyspIGlmKHNhZmVOdW1iZXIocm93MVtpXSkhPW51bGwpIG51bWVyaWNDb3VudCsrOwogICAgICBpZihudW1lcmljQ291bnQ+PTQpIHJldHVybiB7a2luZDoid2lkZSIsIHJlYXNvbjoibWFueSBudW1lcmljIGNvbHVtbnMgYW5kIG5vIGtleXdvcmQgY29sdW1uIn07CiAgICB9CiAgICBpZihoYXNLZXl3b3JkQ29sICYmIGhhc0Nvb3JkICYmIGhhc0xvY0NvbCkgcmV0dXJuIHtraW5kOiJsb25nIiwgcmVhc29uOiJrZXl3b3JkIGNvbHVtbiBwcmVzZW50In07CiAgICBpZihoYXNLZXl3b3JkQ29sKSByZXR1cm4ge2tpbmQ6ImxvbmciLCByZWFzb246ImtleXdvcmQtbGlrZSBjb2x1bW4gcHJlc2VudCJ9OwogICAgcmV0dXJuIHtraW5kOiJ1bmtub3duIiwgcmVhc29uOiJjb3VsZCBub3QgaW5mZXIifTsKICB9CgogIGZ1bmN0aW9uIHBpY2tIZWFkZXIoaGVhZGVycywgY2FuZGlkYXRlcyl7CiAgICBjb25zdCBobj1oZWFkZXJzLm1hcChub3JtYWxpemVIZWFkZXIpOwogICAgZm9yKGNvbnN0IGNhbmQgb2YgY2FuZGlkYXRlcyl7CiAgICAgIGNvbnN0IGlkeD1obi5pbmRleE9mKGNhbmQpOwogICAgICBpZihpZHg+PTApIHJldHVybiBoZWFkZXJzW2lkeF07CiAgICB9CiAgICByZXR1cm4gIiI7CiAgfQoKICBmdW5jdGlvbiBhdXRvTWFwKGhlYWRlcnMpewogICAgY29uc3QgaXNMYXRMbmc9ZWwudW5pdHMudmFsdWU9PT0ibGF0bG5nIjsKICAgIGNvbnN0IHhDYW5kaWRhdGVzPWlzTGF0TG5nP1sibGF0IiwibGF0aXR1ZGUiLCJncHNfbGF0IiwiY2VudGVyX2xhdCJdOlsieCIsInhfY29vcmQiLCJ4Y29vcmQiLCJlYXN0aW5nIiwiZWFzdCJdOwogICAgY29uc3QgeUNhbmRpZGF0ZXM9aXNMYXRMbmc/WyJsbmciLCJsb24iLCJsb25naXR1ZGUiLCJsb25nIiwiZ3BzX2xuZyIsImNlbnRlcl9sbmciXTpbInkiLCJ5X2Nvb3JkIiwieWNvb3JkIiwibm9ydGhpbmciLCJub3J0aCJdOwogICAgbWFwTG9uZz17CiAgICAgIGtleXdvcmQ6IHBpY2tIZWFkZXIoaGVhZGVycywgWyJrZXl3b3JkIiwia3ciLCJxdWVyeSIsInNlYXJjaF90ZXJtIiwidGVybSIsInBocmFzZSJdKSwKICAgICAgbG9jYXRpb246IHBpY2tIZWFkZXIoaGVhZGVycywgWyJsb2NhdGlvbiIsImxvYyIsInBsYWNlIiwiYXJlYSIsIm5laWdoYm9yaG9vZCIsIm5laWdoYm91cmhvb2QiLCJjaXR5IiwidG93biIsInppcCIsInBvc3RhbF9jb2RlIiwicG9zdGNvZGUiLCJhZGRyZXNzIl0pLAogICAgICByYW5rOiBwaWNrSGVhZGVyKGhlYWRlcnMsIFsicmFuayIsInBvc2l0aW9uIiwicG9zIiwic2VycF9yYW5rIiwibG9jYWxfcmFuayIsInJhbmtpbmciXSksCiAgICAgIHg6IHBpY2tIZWFkZXIoaGVhZGVycywgeENhbmRpZGF0ZXMpLAogICAgICB5OiBwaWNrSGVhZGVyKGhlYWRlcnMsIHlDYW5kaWRhdGVzKSwKICAgICAgYnVzaW5lc3M6IHBpY2tIZWFkZXIoaGVhZGVycywgWyJidXNpbmVzcyIsImVudGl0eSIsImJyYW5kIiwiY29tcGFueSIsImdicCIsImxpc3RpbmciXSksCiAgICAgIGRhdGU6IHBpY2tIZWFkZXIoaGVhZGVycywgWyJkYXRlIiwiZGF5IiwidGltZXN0YW1wIiwiYXNfb2YiLCJyZXBvcnRfZGF0ZSJdKSwKICAgICAgdm9sdW1lOiBwaWNrSGVhZGVyKGhlYWRlcnMsIFsidm9sdW1lIiwic2VhcmNoX3ZvbHVtZSIsInN2IiwibXN2Il0pLAogICAgfTsKICAgIG1hcFdpZGU9ewogICAgICBsb2NhdGlvbjogcGlja0hlYWRlcihoZWFkZXJzLCBbImxvY2F0aW9uIiwibG9jIiwicGxhY2UiLCJhcmVhIiwibmVpZ2hib3Job29kIiwibmVpZ2hib3VyaG9vZCIsImNpdHkiLCJ0b3duIiwiemlwIiwicG9zdGFsX2NvZGUiLCJwb3N0Y29kZSIsImFkZHJlc3MiXSksCiAgICAgIHg6IHBpY2tIZWFkZXIoaGVhZGVycywgeENhbmRpZGF0ZXMpLAogICAgICB5OiBwaWNrSGVhZGVyKGhlYWRlcnMsIHlDYW5kaWRhdGVzKSwKICAgICAgYnVzaW5lc3M6IHBpY2tIZWFkZXIoaGVhZGVycywgWyJidXNpbmVzcyIsImVudGl0eSIsImJyYW5kIiwiY29tcGFueSIsImdicCIsImxpc3RpbmciXSksCiAgICAgIGRhdGU6IHBpY2tIZWFkZXIoaGVhZGVycywgWyJkYXRlIiwiZGF5IiwidGltZXN0YW1wIiwiYXNfb2YiLCJyZXBvcnRfZGF0ZSJdKSwKICAgICAga2V5d29yZENvbHM6IFtdLAogICAgICB2b2x1bWVNb2RlOiBlbC53Vm9sdW1lTW9kZS52YWx1ZSwKICAgICAgdm9sdW1lQ29sOiAiIiwKICAgIH07CiAgfQoKICBmdW5jdGlvbiBwb3B1bGF0ZVNlbGVjdChzZWxlY3QsIGhlYWRlcnMsIHZhbHVlKXsKICAgIGNvbnN0IG9wdHM9WyIiLC4uLmhlYWRlcnNdOwogICAgc2VsZWN0LmlubmVySFRNTD0iIjsKICAgIGZvcihjb25zdCBvIG9mIG9wdHMpewogICAgICBjb25zdCBvcHQ9ZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgib3B0aW9uIik7CiAgICAgIG9wdC52YWx1ZT1vOyBvcHQudGV4dENvbnRlbnQ9bz09PSIiPyIobm9uZSkiOm87CiAgICAgIHNlbGVjdC5hcHBlbmRDaGlsZChvcHQpOwogICAgfQogICAgc2VsZWN0LnZhbHVlPW9wdHMuaW5jbHVkZXModmFsdWUpP3ZhbHVlOiIiOwogIH0KCiAgZnVuY3Rpb24gcmVuZGVyTWFwcGluZ1VJKGhlYWRlcnMpewogICAgcG9wdWxhdGVTZWxlY3QoZWwubUtleXdvcmQsIGhlYWRlcnMsIG1hcExvbmcua2V5d29yZCk7CiAgICBwb3B1bGF0ZVNlbGVjdChlbC5tTG9jYXRpb24sIGhlYWRlcnMsIG1hcExvbmcubG9jYXRpb24pOwogICAgcG9wdWxhdGVTZWxlY3QoZWwubVJhbmssIGhlYWRlcnMsIG1hcExvbmcucmFuayk7CiAgICBwb3B1bGF0ZVNlbGVjdChlbC5tWCwgaGVhZGVycywgbWFwTG9uZy54KTsKICAgIHBvcHVsYXRlU2VsZWN0KGVsLm1ZLCBoZWFkZXJzLCBtYXBMb25nLnkpOwogICAgcG9wdWxhdGVTZWxlY3QoZWwubUJ1c2luZXNzLCBoZWFkZXJzLCBtYXBMb25nLmJ1c2luZXNzKTsKICAgIHBvcHVsYXRlU2VsZWN0KGVsLm1EYXRlLCBoZWFkZXJzLCBtYXBMb25nLmRhdGUpOwogICAgcG9wdWxhdGVTZWxlY3QoZWwubVZvbHVtZSwgaGVhZGVycywgbWFwTG9uZy52b2x1bWUpOwoKICAgIHBvcHVsYXRlU2VsZWN0KGVsLndMb2NhdGlvbiwgaGVhZGVycywgbWFwV2lkZS5sb2NhdGlvbik7CiAgICBwb3B1bGF0ZVNlbGVjdChlbC53WCwgaGVhZGVycywgbWFwV2lkZS54KTsKICAgIHBvcHVsYXRlU2VsZWN0KGVsLndZLCBoZWFkZXJzLCBtYXBXaWRlLnkpOwogICAgcG9wdWxhdGVTZWxlY3QoZWwud0J1c2luZXNzLCBoZWFkZXJzLCBtYXBXaWRlLmJ1c2luZXNzKTsKICAgIHBvcHVsYXRlU2VsZWN0KGVsLndEYXRlLCBoZWFkZXJzLCBtYXBXaWRlLmRhdGUpOwogICAgcG9wdWxhdGVTZWxlY3QoZWwud1ZvbHVtZUNvbCwgaGVhZGVycywgbWFwV2lkZS52b2x1bWVDb2wpOwoKICAgIGVsLndWb2x1bWVNb2RlLnZhbHVlID0gbWFwV2lkZS52b2x1bWVNb2RlIHx8ICJub25lIjsKICAgIHRvZ2dsZVdpZGVWb2x1bWVVSSgpOwogIH0KCiAgZnVuY3Rpb24gcmVhZE1hcHBpbmdGcm9tVUkoKXsKICAgIG1hcExvbmc9ewogICAgICBrZXl3b3JkOiBlbC5tS2V5d29yZC52YWx1ZSwKICAgICAgbG9jYXRpb246IGVsLm1Mb2NhdGlvbi52YWx1ZSwKICAgICAgcmFuazogZWwubVJhbmsudmFsdWUsCiAgICAgIHg6IGVsLm1YLnZhbHVlLAogICAgICB5OiBlbC5tWS52YWx1ZSwKICAgICAgYnVzaW5lc3M6IGVsLm1CdXNpbmVzcy52YWx1ZSwKICAgICAgZGF0ZTogZWwubURhdGUudmFsdWUsCiAgICAgIHZvbHVtZTogZWwubVZvbHVtZS52YWx1ZSwKICAgIH07CiAgICBtYXBXaWRlPXsKICAgICAgbG9jYXRpb246IGVsLndMb2NhdGlvbi52YWx1ZSwKICAgICAgeDogZWwud1gudmFsdWUsCiAgICAgIHk6IGVsLndZLnZhbHVlLAogICAgICBidXNpbmVzczogZWwud0J1c2luZXNzLnZhbHVlLAogICAgICBkYXRlOiBlbC53RGF0ZS52YWx1ZSwKICAgICAga2V5d29yZENvbHM6IChlbC53S2V5d29yZENvbHMudmFsdWV8fCIiKS50cmltKCkKICAgICAgICA/IChlbC53S2V5d29yZENvbHMudmFsdWV8fCIiKS5zcGxpdCgiLCIpLm1hcChzPT5zLnRyaW0oKSkuZmlsdGVyKEJvb2xlYW4pCiAgICAgICAgOiBbXSwKICAgICAgdm9sdW1lTW9kZTogZWwud1ZvbHVtZU1vZGUudmFsdWUsCiAgICAgIHZvbHVtZUNvbDogZWwud1ZvbHVtZUNvbC52YWx1ZSwKICAgIH07CiAgfQoKICBmdW5jdGlvbiB0b2dnbGVXaWRlQmxvY2tzKCl7CiAgICBjb25zdCBzaG93V2lkZT1lbC5jc3ZGb3JtYXQudmFsdWU9PT0id2lkZSI7CiAgICBlbC5tYXBwaW5nV2lkZUJsb2NrLnN0eWxlLmRpc3BsYXk9c2hvd1dpZGU/ImJsb2NrIjoibm9uZSI7CiAgICBlbC5tYXBwaW5nTG9uZ0Jsb2NrLnN0eWxlLmRpc3BsYXk9c2hvd1dpZGU/Im5vbmUiOiJibG9jayI7CiAgfQogIGZ1bmN0aW9uIHRvZ2dsZVdpZGVWb2x1bWVVSSgpewogICAgY29uc3Qgc2hvdz1lbC53Vm9sdW1lTW9kZS52YWx1ZT09PSJzaW5nbGVfY29sIjsKICAgIGVsLndWb2x1bWVDb2wuc3R5bGUuZGlzcGxheT1zaG93PyJibG9jayI6Im5vbmUiOwogICAgZWwud1ZvbHVtZUNvbExhYmVsLnN0eWxlLmRpc3BsYXk9c2hvdz8iYmxvY2siOiJub25lIjsKICB9CgogIC8vIEdlb0pTT04KICBmdW5jdGlvbiBnZW9qc29uVG9HZW9tZXRyaWVzKGdqKXsKICAgIGNvbnN0IGdlb21zPVtdOwogICAgaWYoIWdqfHx0eXBlb2YgZ2ohPT0ib2JqZWN0IikgcmV0dXJuIGdlb21zOwogICAgaWYoZ2oudHlwZT09PSJGZWF0dXJlQ29sbGVjdGlvbiIgJiYgQXJyYXkuaXNBcnJheShnai5mZWF0dXJlcykpewogICAgICBmb3IoY29uc3QgZiBvZiBnai5mZWF0dXJlcykgaWYoZj8uZ2VvbWV0cnkpIGdlb21zLnB1c2goZi5nZW9tZXRyeSk7CiAgICAgIHJldHVybiBnZW9tczsKICAgIH0KICAgIGlmKGdqLnR5cGU9PT0iRmVhdHVyZSIgJiYgZ2ouZ2VvbWV0cnkpIHJldHVybiBbZ2ouZ2VvbWV0cnldOwogICAgaWYoZ2oudHlwZSAmJiBnai5jb29yZGluYXRlcykgcmV0dXJuIFtnal07CiAgICByZXR1cm4gZ2VvbXM7CiAgfQogIGZ1bmN0aW9uIHNjYW5HZW9CQm94KGdqKXsKICAgIGNvbnN0IGdlb21zPWdlb2pzb25Ub0dlb21ldHJpZXMoZ2opOwogICAgbGV0IG1pblg9SW5maW5pdHksbWluWT1JbmZpbml0eSxtYXhYPS1JbmZpbml0eSxtYXhZPS1JbmZpbml0eTsKICAgIGNvbnN0IGNvbnNpZGVyPSh4LHkpPT57IGlmKCFOdW1iZXIuaXNGaW5pdGUoeCl8fCFOdW1iZXIuaXNGaW5pdGUoeSkpIHJldHVybjsgbWluWD1NYXRoLm1pbihtaW5YLHgpOyBtaW5ZPU1hdGgubWluKG1pblkseSk7IG1heFg9TWF0aC5tYXgobWF4WCx4KTsgbWF4WT1NYXRoLm1heChtYXhZLHkpOyB9OwogICAgY29uc3Qgd2Fsaz0oY29vcmRzKT0+ewogICAgICBpZighQXJyYXkuaXNBcnJheShjb29yZHMpfHwhY29vcmRzLmxlbmd0aCkgcmV0dXJuOwogICAgICBpZih0eXBlb2YgY29vcmRzWzBdPT09Im51bWJlciIgJiYgdHlwZW9mIGNvb3Jkc1sxXT09PSJudW1iZXIiKXsgY29uc2lkZXIoY29vcmRzWzBdLGNvb3Jkc1sxXSk7IHJldHVybjsgfQogICAgICBmb3IoY29uc3QgYyBvZiBjb29yZHMpIHdhbGsoYyk7CiAgICB9OwogICAgZm9yKGNvbnN0IGcgb2YgZ2VvbXMpIHdhbGsoZy5jb29yZGluYXRlcyk7CiAgICBpZighTnVtYmVyLmlzRmluaXRlKG1pblgpKSByZXR1cm4gbnVsbDsKICAgIHJldHVybiB7bWluWCxtaW5ZLG1heFgsbWF4WX07IC8vIGxvbi9sYXQKICB9CiAgZnVuY3Rpb24gc2V0R2VvSlNPTihvYmopewogICAgY29uc3QgYmJveD1zY2FuR2VvQkJveChvYmopOwogICAgaWYoIWJib3gpIHRocm93IG5ldyBFcnJvcigiQ291bGQgbm90IGNvbXB1dGUgR2VvSlNPTiBib3VuZHMuIik7CiAgICBnZW9qc29uPW9iajsgZ2VvQkJveD1iYm94OwogICAgZWwuZ2VvU3R5bGUuZGlzYWJsZWQ9ZmFsc2U7IGVsLmNsZWFyR2VvQnRuLmRpc2FibGVkPWZhbHNlOyBlbC5jb3B5R2VvQnRuLmRpc2FibGVkPWZhbHNlOwogICAgZWwubWFza01vZGUuZGlzYWJsZWQ9ZmFsc2U7CiAgICBlbC5nZW9QaWxsLnRleHRDb250ZW50PSJHZW9KU09OIGxvYWRlZCI7CiAgfQogIGZ1bmN0aW9uIGNsZWFyR2VvKCl7CiAgICBnZW9qc29uPW51bGw7IGdlb0JCb3g9bnVsbDsgZWwuZ2VvRmlsZS52YWx1ZT0iIjsKICAgIGVsLmdlb1N0eWxlLmRpc2FibGVkPXRydWU7IGVsLmNsZWFyR2VvQnRuLmRpc2FibGVkPXRydWU7IGVsLmNvcHlHZW9CdG4uZGlzYWJsZWQ9dHJ1ZTsKICAgIGVsLmdlb1BpbGwudGV4dENvbnRlbnQ9Ik5vIEdlb0pTT04iOwogICAgaWYoZWwubWFza01vZGUudmFsdWU9PT0iZ2VvanNvbiIpIGVsLm1hc2tNb2RlLnZhbHVlPSJvZmYiOwogICAgcmVuZGVyKCk7CiAgfQoKICAvLyBNYXNrIGhlbHBlcnMKICBmdW5jdGlvbiBwb2ludEluUmluZyh4LHkscmluZyl7CiAgICBsZXQgaW5zaWRlPWZhbHNlOwogICAgZm9yKGxldCBpPTAsaj1yaW5nLmxlbmd0aC0xO2k8cmluZy5sZW5ndGg7aj1pKyspewogICAgICBjb25zdCB4aT1yaW5nW2ldLmxhdCwgeWk9cmluZ1tpXS5sbmc7CiAgICAgIGNvbnN0IHhqPXJpbmdbal0ubGF0LCB5aj1yaW5nW2pdLmxuZzsKICAgICAgY29uc3QgaW50ZXJzZWN0PSgoeWk+eSkhPT0oeWo+eSkpICYmICh4IDwgKHhqLXhpKSooeS15aSkvKCh5ai15aSl8fDFlLTEyKSt4aSk7CiAgICAgIGlmKGludGVyc2VjdCkgaW5zaWRlPSFpbnNpZGU7CiAgICB9CiAgICByZXR1cm4gaW5zaWRlOwogIH0KICBmdW5jdGlvbiBwb2ludEluUG9seWdvblJpbmdzKHgseSxyaW5ncyl7CiAgICBpZighcmluZ3MubGVuZ3RoKSByZXR1cm4gZmFsc2U7CiAgICBpZighcG9pbnRJblJpbmcoeCx5LHJpbmdzWzBdKSkgcmV0dXJuIGZhbHNlOwogICAgZm9yKGxldCBpPTE7aTxyaW5ncy5sZW5ndGg7aSsrKSBpZihwb2ludEluUmluZyh4LHkscmluZ3NbaV0pKSByZXR1cm4gZmFsc2U7CiAgICByZXR1cm4gdHJ1ZTsKICB9CiAgZnVuY3Rpb24gcG9seWdvbkNvb3Jkc1RvUmluZ3MocG9seUNvb3Jkcyl7CiAgICBjb25zdCByaW5ncz1bXTsKICAgIGZvcihjb25zdCByaW5nIG9mIHBvbHlDb29yZHMpewogICAgICBpZighQXJyYXkuaXNBcnJheShyaW5nKXx8cmluZy5sZW5ndGg8MykgY29udGludWU7CiAgICAgIGNvbnN0IHJyPVtdOwogICAgICBmb3IoY29uc3QgcHQgb2YgcmluZyl7CiAgICAgICAgY29uc3QgbG5nPU51bWJlcihwdD8uWzBdKTsgY29uc3QgbGF0PU51bWJlcihwdD8uWzFdKTsKICAgICAgICBpZighTnVtYmVyLmlzRmluaXRlKGxhdCl8fCFOdW1iZXIuaXNGaW5pdGUobG5nKSkgY29udGludWU7CiAgICAgICAgcnIucHVzaCh7bGF0LGxuZ30pOwogICAgICB9CiAgICAgIGlmKHJyLmxlbmd0aD49Mil7CiAgICAgICAgY29uc3QgYT1yclswXSwgYj1ycltyci5sZW5ndGgtMV07CiAgICAgICAgaWYoTWF0aC5hYnMoYS5sYXQtYi5sYXQpPDFlLTEyICYmIE1hdGguYWJzKGEubG5nLWIubG5nKTwxZS0xMikgcnIucG9wKCk7CiAgICAgIH0KICAgICAgaWYocnIubGVuZ3RoPj0zKSByaW5ncy5wdXNoKHJyKTsKICAgIH0KICAgIHJldHVybiByaW5nczsKICB9CiAgZnVuY3Rpb24gZ2VvanNvblRvUmluZ3NMYXRMbmcoZ2opewogICAgY29uc3QgZ2VvbXM9Z2VvanNvblRvR2VvbWV0cmllcyhnaik7CiAgICBmb3IoY29uc3QgZyBvZiBnZW9tcyl7CiAgICAgIGlmKGcudHlwZT09PSJQb2x5Z29uIikgcmV0dXJuIHBvbHlnb25Db29yZHNUb1JpbmdzKGcuY29vcmRpbmF0ZXMpOwogICAgICBpZihnLnR5cGU9PT0iTXVsdGlQb2x5Z29uIiAmJiBBcnJheS5pc0FycmF5KGcuY29vcmRpbmF0ZXMpICYmIGcuY29vcmRpbmF0ZXMubGVuZ3RoKSByZXR1cm4gcG9seWdvbkNvb3Jkc1RvUmluZ3MoZy5jb29yZGluYXRlc1swXSk7CiAgICB9CiAgICByZXR1cm4gW107CiAgfQoKICAvLyBiYm94IC8gdHJhbnNmb3JtcwogIGZ1bmN0aW9uIG5pY2VQYWRkaW5nKG1pbixtYXgpeyBjb25zdCBzcGFuPShtYXgtbWluKXx8MTsgY29uc3QgcGFkPXNwYW4qMC4xMjsgcmV0dXJuIFttaW4tcGFkLG1heCtwYWRdOyB9CiAgZnVuY3Rpb24gY29tcHV0ZUJCb3gocG9pbnRzKXsKICAgIGxldCBtaW5YPUluZmluaXR5LG1pblk9SW5maW5pdHksbWF4WD0tSW5maW5pdHksbWF4WT0tSW5maW5pdHk7CiAgICBmb3IoY29uc3QgcCBvZiBwb2ludHMpeyBtaW5YPU1hdGgubWluKG1pblgscC54KTsgbWluWT1NYXRoLm1pbihtaW5ZLHAueSk7IG1heFg9TWF0aC5tYXgobWF4WCxwLngpOyBtYXhZPU1hdGgubWF4KG1heFkscC55KTsgfQogICAgaWYoZ2VvQkJveCAmJiBlbC51bml0cy52YWx1ZT09PSJsYXRsbmciKXsKICAgICAgbWluWD1NYXRoLm1pbihtaW5YLCBnZW9CQm94Lm1pblkpOyBtYXhYPU1hdGgubWF4KG1heFgsIGdlb0JCb3gubWF4WSk7IC8vIGxhdAogICAgICBtaW5ZPU1hdGgubWluKG1pblksIGdlb0JCb3gubWluWCk7IG1heFk9TWF0aC5tYXgobWF4WSwgZ2VvQkJveC5tYXhYKTsgLy8gbG5nCiAgICB9CiAgICBjb25zdCBbcE1pblgscE1heFhdPW5pY2VQYWRkaW5nKG1pblgsbWF4WCk7CiAgICBjb25zdCBbcE1pblkscE1heFldPW5pY2VQYWRkaW5nKG1pblksbWF4WSk7CiAgICByZXR1cm4gW3BNaW5YLHBNaW5ZLHBNYXhYLHBNYXhZXTsKICB9CiAgZnVuY3Rpb24gd29ybGRUb0NhbnZhcyh4LHksYmJveCl7CiAgICBjb25zdCBbbWluWCxtaW5ZLG1heFgsbWF4WV09YmJveDsKICAgIGNvbnN0IG54PSh4LW1pblgpLygobWF4WC1taW5YKXx8MSk7CiAgICBjb25zdCBueT0oeS1taW5ZKS8oKG1heFktbWluWSl8fDEpOwogICAgcmV0dXJuIHtjeDpueCplbC5jYW52YXMud2lkdGgsIGN5OigxLW55KSplbC5jYW52YXMuaGVpZ2h0fTsKICB9CiAgZnVuY3Rpb24gY2FudmFzVG9Xb3JsZChjeCxjeSxiYm94KXsKICAgIGNvbnN0IFttaW5YLG1pblksbWF4WCxtYXhZXT1iYm94OwogICAgY29uc3Qgbng9Y3gvZWwuY2FudmFzLndpZHRoOwogICAgY29uc3Qgbnk9MS0oY3kvZWwuY2FudmFzLmhlaWdodCk7CiAgICByZXR1cm4ge3g6bWluWCtueCoobWF4WC1taW5YKSwgeTptaW5ZK255KihtYXhZLW1pblkpfTsKICB9CgogIC8vIGRyYXdpbmcgYmFja2dyb3VuZC9sZWdlbmQKICBmdW5jdGlvbiByb3VuZFJlY3QoY3R4Mix4LHksdyxoLHIpewogICAgY29uc3QgcnI9TWF0aC5taW4ocix3LzIsaC8yKTsKICAgIGN0eDIuYmVnaW5QYXRoKCk7CiAgICBjdHgyLm1vdmVUbyh4K3JyLHkpOwogICAgY3R4Mi5hcmNUbyh4K3cseSx4K3cseStoLHJyKTsKICAgIGN0eDIuYXJjVG8oeCt3LHkraCx4LHkraCxycik7CiAgICBjdHgyLmFyY1RvKHgseStoLHgseSxycik7CiAgICBjdHgyLmFyY1RvKHgseSx4K3cseSxycik7CiAgICBjdHgyLmNsb3NlUGF0aCgpOwogIH0KICBmdW5jdGlvbiBkcmF3QmFja2dyb3VuZChtb2RlKXsKICAgIGlmKG1vZGU9PT0ibGlnaHQiKXsgY3R4LmZpbGxTdHlsZT0iI2Y2ZjdmYiI7IGN0eC5maWxsUmVjdCgwLDAsZWwuY2FudmFzLndpZHRoLGVsLmNhbnZhcy5oZWlnaHQpOyBjdHguZ2xvYmFsQWxwaGE9MC4wNjsgY3R4LnN0cm9rZVN0eWxlPSIjMDAwIjsgfQogICAgZWxzZSB7IGN0eC5maWxsU3R5bGU9IiMwYjEwMjAiOyBjdHguZmlsbFJlY3QoMCwwLGVsLmNhbnZhcy53aWR0aCxlbC5jYW52YXMuaGVpZ2h0KTsgY3R4Lmdsb2JhbEFscGhhPTAuMTA7IGN0eC5zdHJva2VTdHlsZT0iI2ZmZiI7IH0KICAgIGNvbnN0IHN0ZXA9ODA7IGN0eC5saW5lV2lkdGg9MTsKICAgIGZvcihsZXQgeD0wO3g8PWVsLmNhbnZhcy53aWR0aDt4Kz1zdGVwKXsgY3R4LmJlZ2luUGF0aCgpOyBjdHgubW92ZVRvKHgsMCk7IGN0eC5saW5lVG8oeCxlbC5jYW52YXMuaGVpZ2h0KTsgY3R4LnN0cm9rZSgpOyB9CiAgICBmb3IobGV0IHk9MDt5PD1lbC5jYW52YXMuaGVpZ2h0O3krPXN0ZXApeyBjdHguYmVnaW5QYXRoKCk7IGN0eC5tb3ZlVG8oMCx5KTsgY3R4LmxpbmVUbyhlbC5jYW52YXMud2lkdGgseSk7IGN0eC5zdHJva2UoKTsgfQogICAgY3R4Lmdsb2JhbEFscGhhPTE7CiAgfQogIGZ1bmN0aW9uIGhzbFRvUmdiKGgscyxsKXsKICAgIGNvbnN0IEM9KDEtTWF0aC5hYnMoMipsLTEpKSpzOwogICAgY29uc3QgSHA9aC82MDsKICAgIGNvbnN0IFg9QyooMS1NYXRoLmFicygoSHAlMiktMSkpOwogICAgbGV0IHIxPTAsZzE9MCxiMT0wOwogICAgaWYoMDw9SHAmJkhwPDEpW3IxLGcxLGIxXT1bQyxYLDBdOwogICAgZWxzZSBpZigxPD1IcCYmSHA8MilbcjEsZzEsYjFdPVtYLEMsMF07CiAgICBlbHNlIGlmKDI8PUhwJiZIcDwzKVtyMSxnMSxiMV09WzAsQyxYXTsKICAgIGVsc2UgaWYoMzw9SHAmJkhwPDQpW3IxLGcxLGIxXT1bMCxYLENdOwogICAgZWxzZSBpZig0PD1IcCYmSHA8NSlbcjEsZzEsYjFdPVtYLDAsQ107CiAgICBlbHNlIGlmKDU8PUhwJiZIcDw2KVtyMSxnMSxiMV09W0MsMCxYXTsKICAgIGNvbnN0IG09bC1DLzI7CiAgICByZXR1cm4ge3I6TWF0aC5yb3VuZCgocjErbSkqMjU1KSwgZzpNYXRoLnJvdW5kKChnMSttKSoyNTUpLCBiOk1hdGgucm91bmQoKGIxK20pKjI1NSl9OwogIH0KICBmdW5jdGlvbiBwYXJzZUJ1Y2tldEN1dHMoKXsKICAgIGNvbnN0IHJhdz0oZWwuYnVja2V0Q3V0cy52YWx1ZXx8IiIpLnRyaW0oKTsKICAgIGlmKCFyYXcpIHJldHVybiBbMywxMCwyMF07CiAgICBjb25zdCBwYXJ0cz1yYXcuc3BsaXQoIiwiKS5tYXAocz0+TnVtYmVyKHMudHJpbSgpKSkuZmlsdGVyKE51bWJlci5pc0Zpbml0ZSk7CiAgICBjb25zdCB1bmlxPUFycmF5LmZyb20obmV3IFNldChwYXJ0cykpLnNvcnQoKGEsYik9PmEtYik7CiAgICByZXR1cm4gdW5pcS5sZW5ndGg/dW5pcTpbMywxMCwyMF07CiAgfQogIGZ1bmN0aW9uIGJ1Y2tldEluZGV4KHJhbmssY3V0cyl7IGZvcihsZXQgaT0wO2k8Y3V0cy5sZW5ndGg7aSsrKSBpZihyYW5rPD1jdXRzW2ldKSByZXR1cm4gaTsgcmV0dXJuIGN1dHMubGVuZ3RoOyB9CiAgZnVuY3Rpb24gYnVja2V0UGFsZXR0ZShuKXsKICAgIGNvbnN0IGNvbG9ycz1bXTsKICAgIGZvcihsZXQgaT0wO2k8bjtpKyspewogICAgICBjb25zdCB0PW48PTE/MTppLyhuLTEpOwogICAgICBjb25zdCBodWU9MTIwKigxLXQpOwogICAgICBjb25zdCB7cixnLGJ9PWhzbFRvUmdiKGh1ZSwwLjkyLDAuNDgpOwogICAgICBjb2xvcnMucHVzaCh7cixnLGIsYTowLjkwfSk7CiAgICB9CiAgICByZXR1cm4gY29sb3JzOwogIH0KICBmdW5jdGlvbiByYW5rVG9Db2xvcihyYW5rLG1heFJhbmspewogICAgaWYoZWwuY29sb3JNb2RlLnZhbHVlPT09ImJ1Y2tldHMiKXsKICAgICAgY29uc3QgY3V0cz1wYXJzZUJ1Y2tldEN1dHMoKTsKICAgICAgY29uc3QgaWR4PWJ1Y2tldEluZGV4KHJhbmssY3V0cyk7CiAgICAgIGNvbnN0IHBhbD1idWNrZXRQYWxldHRlKGN1dHMubGVuZ3RoKzEpOwogICAgICByZXR1cm4gcGFsW2lkeF18fHBhbFtwYWwubGVuZ3RoLTFdOwogICAgfQogICAgY29uc3QgdD1jbGFtcCgocmFuay0xKS9NYXRoLm1heCgxLChtYXhSYW5rLTEpKSwwLDEpOwogICAgY29uc3QgaHVlPTEyMCooMS10KTsKICAgIGNvbnN0IHtyLGcsYn09aHNsVG9SZ2IoaHVlLDAuOTAsMC40OCk7CiAgICByZXR1cm4ge3IsZyxiLGE6MC44OH07CiAgfQogIGZ1bmN0aW9uIGRyYXdUaXRsZShrdyxiaXosZGF0ZSl7CiAgICBjb25zdCBuYW1lPShlbC5wcm9qZWN0TmFtZS52YWx1ZXx8IiIpLnRyaW0oKTsKICAgIGNvbnN0IHBhcnRzPVtdOwogICAgaWYobmFtZSkgcGFydHMucHVzaChuYW1lKTsKICAgIGlmKGJpeikgcGFydHMucHVzaChiaXopOwogICAgaWYoa3cpIHBhcnRzLnB1c2goYCIke2t3fSJgKTsKICAgIGlmKGRhdGUpIHBhcnRzLnB1c2goZGF0ZSk7CiAgICBjb25zdCB0aXRsZT1wYXJ0cy5qb2luKCIg4oCUICIpOwogICAgY3R4LnNhdmUoKTsKICAgIGN0eC5mb250PSIxNnB4IHN5c3RlbS11aSwtYXBwbGUtc3lzdGVtLFNlZ29lIFVJLFJvYm90byxBcmlhbCI7CiAgICBjdHgudGV4dEFsaWduPSJsZWZ0IjsgY3R4LnRleHRCYXNlbGluZT0idG9wIjsKICAgIGNvbnN0IGJnPWVsLmJnTW9kZS52YWx1ZTsKICAgIGNvbnN0IHRleHRDb2xvcj1iZz09PSJsaWdodCI/IiMxMTEiOiIjZmZmIjsKICAgIGNvbnN0IGJveEZpbGw9Ymc9PT0ibGlnaHQiPyJyZ2JhKDI1NSwyNTUsMjU1LDAuODgpIjoicmdiYSgwLDAsMCwwLjYwKSI7CiAgICBjb25zdCBzdHJva2U9Ymc9PT0ibGlnaHQiPyJyZ2JhKDAsMCwwLDAuMTgpIjoicmdiYSgyNTUsMjU1LDI1NSwwLjE4KSI7CiAgICBjb25zdCB4PTE4LHk9MTgscGFkWD0xMixwYWRZPTEwOwogICAgY29uc3QgdHc9Y3R4Lm1lYXN1cmVUZXh0KHRpdGxlKS53aWR0aDsKICAgIGNvbnN0IGJ3PU1hdGgubWluKGVsLmNhbnZhcy53aWR0aC0zNix0dytwYWRYKjIpLCBiaD00MDsKICAgIGN0eC5maWxsU3R5bGU9Ym94RmlsbDsgY3R4LnN0cm9rZVN0eWxlPXN0cm9rZTsgY3R4LmxpbmVXaWR0aD0xOwogICAgcm91bmRSZWN0KGN0eCx4LHksYncsYmgsMTIpOyBjdHguZmlsbCgpOyBjdHguc3Ryb2tlKCk7CiAgICBjdHguZmlsbFN0eWxlPXRleHRDb2xvcjsgY3R4LmZpbGxUZXh0KHRpdGxlLHgrcGFkWCx5K3BhZFkpOwogICAgY3R4LnJlc3RvcmUoKTsKICB9CiAgZnVuY3Rpb24gZHJhd0xlZ2VuZChtYXhSYW5rKXsKICAgIGlmKGVsLmxlZ2VuZE1vZGUudmFsdWUhPT0ib24iKSByZXR1cm47CiAgICBjb25zdCBiZz1lbC5iZ01vZGUudmFsdWU7CiAgICBjb25zdCB3PTMyMCxoPTcyLHg9MTgseT1lbC5jYW52YXMuaGVpZ2h0LWgtMTg7CiAgICBjdHguc2F2ZSgpOwogICAgY3R4LmZpbGxTdHlsZT1iZz09PSJsaWdodCI/InJnYmEoMjU1LDI1NSwyNTUsMC44NikiOiJyZ2JhKDAsMCwwLDAuNTUpIjsKICAgIGN0eC5zdHJva2VTdHlsZT1iZz09PSJsaWdodCI/InJnYmEoMCwwLDAsMC4xOCkiOiJyZ2JhKDI1NSwyNTUsMjU1LDAuMTgpIjsKICAgIGN0eC5saW5lV2lkdGg9MTsKICAgIHJvdW5kUmVjdChjdHgseCx5LHcsaCwxMik7IGN0eC5maWxsKCk7IGN0eC5zdHJva2UoKTsKICAgIGN0eC5mb250PSIxMnB4IHN5c3RlbS11aSwtYXBwbGUtc3lzdGVtLFNlZ29lIFVJLFJvYm90byxBcmlhbCI7CiAgICBjdHguZmlsbFN0eWxlPWJnPT09ImxpZ2h0Ij8iIzExMSI6IiNmZmYiOwogICAgY3R4LnRleHRCYXNlbGluZT0idG9wIjsgY3R4LnRleHRBbGlnbj0ibGVmdCI7CiAgICBpZihlbC5jb2xvck1vZGUudmFsdWU9PT0iYnVja2V0cyIpewogICAgICBjb25zdCBjdXRzPXBhcnNlQnVja2V0Q3V0cygpOwogICAgICBjb25zdCByYW5nZXM9W107IGxldCBzdGFydD0xOwogICAgICBmb3IoY29uc3QgYyBvZiBjdXRzKXsgaWYoYz49c3RhcnQpeyByYW5nZXMucHVzaChbc3RhcnQsY10pOyBzdGFydD1jKzE7IH0gfQogICAgICByYW5nZXMucHVzaChbc3RhcnQsSW5maW5pdHldKTsKICAgICAgY29uc3QgcGFsPWJ1Y2tldFBhbGV0dGUocmFuZ2VzLmxlbmd0aCk7CiAgICAgIGNvbnN0IGJhclg9eCsxMiwgYmFyWT15KzI2LCBiYXJXPXctMjQsIGJhckg9MTYsIHNlZ1c9YmFyVy9yYW5nZXMubGVuZ3RoOwogICAgICBmb3IobGV0IGk9MDtpPHJhbmdlcy5sZW5ndGg7aSsrKXsKICAgICAgICBjb25zdCBjPXBhbFtpXTsgY3R4LmZpbGxTdHlsZT1gcmdiKCR7Yy5yfSwke2MuZ30sJHtjLmJ9KWA7CiAgICAgICAgY3R4LmZpbGxSZWN0KGJhclgraSpzZWdXLGJhclksTWF0aC5jZWlsKHNlZ1cpLGJhckgpOwogICAgICB9CiAgICAgIGN0eC5maWxsU3R5bGU9Ymc9PT0ibGlnaHQiPyIjMTExIjoiI2ZmZiI7CiAgICAgIGN0eC5maWxsVGV4dCgiQnVja2V0cyIseCsxMix5KzEwKTsKICAgICAgY3R4LnRleHRBbGlnbj0ibGVmdCI7IGN0eC5maWxsVGV4dChgQmVzdDogJHtyYW5nZXNbMF1bMF194oCTJHtyYW5nZXNbMF1bMV19YCxiYXJYLGJhclkrYmFySCs2KTsKICAgICAgY29uc3Qgcj1yYW5nZXNbcmFuZ2VzLmxlbmd0aC0xXTsgY3R4LnRleHRBbGlnbj0icmlnaHQiOyBjdHguZmlsbFRleHQoYFdvcnN0OiAke3JbMF19K2AsYmFyWCtiYXJXLGJhclkrYmFySCs2KTsKICAgIH0gZWxzZSB7CiAgICAgIGNvbnN0IGJhclg9eCsxMiwgYmFyWT15KzI2LCBiYXJXPXctMjQsIGJhckg9MTY7CiAgICAgIGNvbnN0IGdyYWQ9Y3R4LmNyZWF0ZUxpbmVhckdyYWRpZW50KGJhclgsMCxiYXJYK2JhclcsMCk7CiAgICAgIGZvcihsZXQgaT0wO2k8PTIwO2krKyl7CiAgICAgICAgY29uc3QgdD1pLzIwOwogICAgICAgIGNvbnN0IHJhbms9MSt0KihtYXhSYW5rLTEpOwogICAgICAgIGNvbnN0IGM9cmFua1RvQ29sb3IocmFuayxtYXhSYW5rKTsKICAgICAgICBncmFkLmFkZENvbG9yU3RvcCh0LGByZ2IoJHtjLnJ9LCR7Yy5nfSwke2MuYn0pYCk7CiAgICAgIH0KICAgICAgY3R4LmZpbGxUZXh0KCJHcmFkaWVudCIseCsxMix5KzEwKTsKICAgICAgY3R4LmZpbGxTdHlsZT1ncmFkOyBjdHguZmlsbFJlY3QoYmFyWCxiYXJZLGJhclcsYmFySCk7CiAgICAgIGN0eC5maWxsU3R5bGU9Ymc9PT0ibGlnaHQiPyIjMTExIjoiI2ZmZiI7CiAgICAgIGN0eC50ZXh0QWxpZ249ImxlZnQiOyBjdHguZmlsbFRleHQoIkJlc3QgKFJhbmsgMSkiLGJhclgsYmFyWStiYXJIKzYpOwogICAgICBjdHgudGV4dEFsaWduPSJyaWdodCI7IGN0eC5maWxsVGV4dChgV29yc3QgKFJhbmsgJHttYXhSYW5rfSlgLGJhclgrYmFyVyxiYXJZK2JhckgrNik7CiAgICB9CiAgICBjdHgucmVzdG9yZSgpOwogIH0KCiAgLy8gR2VvSlNPTiBvdmVybGF5CiAgZnVuY3Rpb24gZHJhd0dlb0pTT05PdmVybGF5KGJib3gpewogICAgaWYoIWdlb2pzb24gfHwgIWdlb0JCb3gpIHJldHVybjsKICAgIGlmKGVsLmdlb1N0eWxlLnZhbHVlPT09Im9mZiIpIHJldHVybjsKICAgIGlmKGVsLnVuaXRzLnZhbHVlIT09ImxhdGxuZyIpIHJldHVybjsKICAgIGNvbnN0IGJnPWVsLmJnTW9kZS52YWx1ZTsKICAgIGNvbnN0IG91dGxpbmU9Ymc9PT0ibGlnaHQiPyJyZ2JhKDAsMCwwLDAuMzUpIjoicmdiYSgyNTUsMjU1LDI1NSwwLjMwKSI7CiAgICBjb25zdCBmaWxsPWJnPT09ImxpZ2h0Ij8icmdiYSgwLDAsMCwwLjA1KSI6InJnYmEoMjU1LDI1NSwyNTUsMC4wNikiOwogICAgY29uc3QgZ2VvbXM9Z2VvanNvblRvR2VvbWV0cmllcyhnZW9qc29uKTsKICAgIGN0eC5zYXZlKCk7CiAgICBjdHgubGluZVdpZHRoPTEuNTsKICAgIGN0eC5zdHJva2VTdHlsZT1vdXRsaW5lOwogICAgY3R4LmZpbGxTdHlsZT1maWxsOwogICAgY29uc3QgbW92ZUxpbmVUbz0oY29vcmRzKT0+ewogICAgICBmb3IobGV0IGk9MDtpPGNvb3Jkcy5sZW5ndGg7aSsrKXsKICAgICAgICBjb25zdCBsb249TnVtYmVyKGNvb3Jkc1tpXT8uWzBdKTsgY29uc3QgbGF0PU51bWJlcihjb29yZHNbaV0/LlsxXSk7CiAgICAgICAgaWYoIU51bWJlci5pc0Zpbml0ZShsb24pfHwhTnVtYmVyLmlzRmluaXRlKGxhdCkpIGNvbnRpbnVlOwogICAgICAgIGNvbnN0IHA9d29ybGRUb0NhbnZhcyhsYXQsbG9uLGJib3gpOwogICAgICAgIGlmKGk9PT0wKSBjdHgubW92ZVRvKHAuY3gscC5jeSk7IGVsc2UgY3R4LmxpbmVUbyhwLmN4LHAuY3kpOwogICAgICB9CiAgICB9OwogICAgY29uc3QgZHJhd1BvbHlnb249KHBvbHkpPT57CiAgICAgIGN0eC5iZWdpblBhdGgoKTsKICAgICAgZm9yKGNvbnN0IHJpbmcgb2YgcG9seSl7CiAgICAgICAgaWYoIUFycmF5LmlzQXJyYXkocmluZyl8fHJpbmcubGVuZ3RoPDIpIGNvbnRpbnVlOwogICAgICAgIG1vdmVMaW5lVG8ocmluZyk7CiAgICAgICAgY3R4LmNsb3NlUGF0aCgpOwogICAgICB9CiAgICAgIGlmKGVsLmdlb1N0eWxlLnZhbHVlPT09ImZpbGwiKSBjdHguZmlsbCgiZXZlbm9kZCIpOwogICAgICBjdHguc3Ryb2tlKCk7CiAgICB9OwogICAgZm9yKGNvbnN0IGcgb2YgZ2VvbXMpewogICAgICBpZighZz8udHlwZSkgY29udGludWU7CiAgICAgIGlmKGcudHlwZT09PSJQb2x5Z29uIikgZHJhd1BvbHlnb24oZy5jb29yZGluYXRlcyk7CiAgICAgIGVsc2UgaWYoZy50eXBlPT09Ik11bHRpUG9seWdvbiIpIGZvcihjb25zdCBwb2x5IG9mIGcuY29vcmRpbmF0ZXMpIGRyYXdQb2x5Z29uKHBvbHkpOwogICAgICBlbHNlIGlmKGcudHlwZT09PSJMaW5lU3RyaW5nIil7IGN0eC5iZWdpblBhdGgoKTsgbW92ZUxpbmVUbyhnLmNvb3JkaW5hdGVzKTsgY3R4LnN0cm9rZSgpOyB9CiAgICAgIGVsc2UgaWYoZy50eXBlPT09Ik11bHRpTGluZVN0cmluZyIpIGZvcihjb25zdCBsaW5lIG9mIGcuY29vcmRpbmF0ZXMpeyBjdHguYmVnaW5QYXRoKCk7IG1vdmVMaW5lVG8obGluZSk7IGN0eC5zdHJva2UoKTsgfQogICAgfQogICAgY3R4LnJlc3RvcmUoKTsKICB9CgogIC8vIGRpc3RhbmNlIHJpbmdzIChsYXQvbG5nIGFwcHJveCkKICBmdW5jdGlvbiBtaWxlc1RvRGVncmVlc0xhdChtaSl7IHJldHVybiBtaS82OS4wOyB9CiAgZnVuY3Rpb24gbWlsZXNUb0RlZ3JlZXNMbmcobWksIGF0TGF0KXsgcmV0dXJuIG1pLyg2OS4xNzIqTWF0aC5jb3MoKGF0TGF0Kk1hdGguUEkpLzE4MCl8fDFlLTEyKTsgfQogIGZ1bmN0aW9uIGRyYXdCdXNpbmVzc0FuZFJpbmdzKGJib3gpewogICAgY29uc3QgYng9c2FmZU51bWJlcihlbC5iaXpMYXQudmFsdWUpLCBieT1zYWZlTnVtYmVyKGVsLmJpekxuZy52YWx1ZSk7CiAgICBpZihieD09bnVsbHx8Ynk9PW51bGwpIHJldHVybjsKICAgIGNvbnN0IGJnPWVsLmJnTW9kZS52YWx1ZTsKICAgIGNvbnN0IHN0cm9rZT1iZz09PSJsaWdodCI/InJnYmEoMCwwLDAsMC4zNSkiOiJyZ2JhKDI1NSwyNTUsMjU1LDAuMjgpIjsKICAgIGNvbnN0IGZpbGw9Ymc9PT0ibGlnaHQiPyJyZ2JhKDAsMCwwLDAuNzApIjoicmdiYSgyNTUsMjU1LDI1NSwwLjgwKSI7CiAgICBjb25zdCBjPXdvcmxkVG9DYW52YXMoYngsYnksYmJveCk7CiAgICBjdHguc2F2ZSgpOwogICAgY3R4LmxpbmVXaWR0aD0yOyBjdHguc3Ryb2tlU3R5bGU9c3Ryb2tlOyBjdHguZmlsbFN0eWxlPWZpbGw7CiAgICBjdHguYmVnaW5QYXRoKCk7IGN0eC5hcmMoYy5jeCxjLmN5LDYsMCxNYXRoLlBJKjIpOyBjdHguZmlsbCgpOyBjdHguc3Ryb2tlKCk7CiAgICBjb25zdCBwYXJ0cz0oZWwucmluZ3MudmFsdWV8fCIiKS5zcGxpdCgiLCIpLm1hcChzPT5OdW1iZXIocy50cmltKCkpKS5maWx0ZXIoTnVtYmVyLmlzRmluaXRlKS5zb3J0KChhLGIpPT5hLWIpOwogICAgaWYoIXBhcnRzLmxlbmd0aCl7IGN0eC5yZXN0b3JlKCk7IHJldHVybjsgfQogICAgY3R4Lmdsb2JhbEFscGhhPTAuNjU7CiAgICBmb3IoY29uc3QgciBvZiBwYXJ0cyl7CiAgICAgIGxldCByeCwgcnk7CiAgICAgIGlmKGVsLnVuaXRzLnZhbHVlPT09ImxhdGxuZyIpeyByeD1NYXRoLmFicyhtaWxlc1RvRGVncmVlc0xhdChyKSk7IHJ5PU1hdGguYWJzKG1pbGVzVG9EZWdyZWVzTG5nKHIsYngpKTsgfQogICAgICBlbHNlIHsgcng9cjsgcnk9cjsgfQogICAgICBjdHguYmVnaW5QYXRoKCk7CiAgICAgIGNvbnN0IHN0ZXBzPTEyMDsKICAgICAgZm9yKGxldCBpPTA7aTw9c3RlcHM7aSsrKXsKICAgICAgICBjb25zdCB0PShpL3N0ZXBzKSpNYXRoLlBJKjI7CiAgICAgICAgY29uc3Qgd3g9YngrcngqTWF0aC5jb3ModCk7CiAgICAgICAgY29uc3Qgd3k9YnkrcnkqTWF0aC5zaW4odCk7CiAgICAgICAgY29uc3QgcD13b3JsZFRvQ2FudmFzKHd4LHd5LGJib3gpOwogICAgICAgIGlmKGk9PT0wKSBjdHgubW92ZVRvKHAuY3gscC5jeSk7IGVsc2UgY3R4LmxpbmVUbyhwLmN4LHAuY3kpOwogICAgICB9CiAgICAgIGN0eC5zdHJva2UoKTsKICAgIH0KICAgIGN0eC5yZXN0b3JlKCk7CiAgfQoKICAvLyBJbnRlcnBvbGF0aW9uCiAgZnVuY3Rpb24gaWR3QXQoY3gsY3kscHRzLHBvd2VyLHJhZGl1c1B4KXsKICAgIGxldCBudW09MCwgZGVuPTA7CiAgICBjb25zdCByMj1yYWRpdXNQeD4wP3JhZGl1c1B4KnJhZGl1c1B4OkluZmluaXR5OwogICAgZm9yKGNvbnN0IHAgb2YgcHRzKXsKICAgICAgY29uc3QgZHg9Y3gtcC5jeCwgZHk9Y3ktcC5jeTsKICAgICAgY29uc3QgZDI9ZHgqZHgrZHkqZHk7CiAgICAgIGlmKGQyPDFlLTkpIHJldHVybiBwLnJhbms7CiAgICAgIGlmKGQyPnIyKSBjb250aW51ZTsKICAgICAgY29uc3Qgdz0xL01hdGgucG93KE1hdGguc3FydChkMikscG93ZXIpOwogICAgICBudW0rPXcqcC5yYW5rOyBkZW4rPXc7CiAgICB9CiAgICByZXR1cm4gZGVuPjA/KG51bS9kZW4pOm51bGw7CiAgfQogIGZ1bmN0aW9uIG5lYXJlc3RBdChjeCxjeSxwdHMscmFkaXVzUHgpewogICAgbGV0IGJlc3Q9bnVsbCwgYmQyPUluZmluaXR5OwogICAgZm9yKGNvbnN0IHAgb2YgcHRzKXsKICAgICAgY29uc3QgZHg9Y3gtcC5jeCwgZHk9Y3ktcC5jeTsKICAgICAgY29uc3QgZDI9ZHgqZHgrZHkqZHk7CiAgICAgIGlmKGQyPGJkMil7IGJkMj1kMjsgYmVzdD1wOyB9CiAgICB9CiAgICBpZighYmVzdCkgcmV0dXJuIG51bGw7CiAgICBjb25zdCByMj1yYWRpdXNQeD4wP3JhZGl1c1B4KnJhZGl1c1B4OkluZmluaXR5OwogICAgaWYocmFkaXVzUHg8PTAgfHwgYmQyPD1yMikgcmV0dXJuIGJlc3QucmFuazsKICAgIHJldHVybiBudWxsOwogIH0KICBmdW5jdGlvbiBnYXVzc0F0KGN4LGN5LHB0cyxzaWdtYSxyYWRpdXNQeCl7CiAgICBsZXQgbnVtPTAsIGRlbj0wOwogICAgY29uc3QgcjI9cmFkaXVzUHg+MD9yYWRpdXNQeCpyYWRpdXNQeDpJbmZpbml0eTsKICAgIGNvbnN0IHMyPShzaWdtYSpzaWdtYSl8fDE7CiAgICBmb3IoY29uc3QgcCBvZiBwdHMpewogICAgICBjb25zdCBkeD1jeC1wLmN4LCBkeT1jeS1wLmN5OwogICAgICBjb25zdCBkMj1keCpkeCtkeSpkeTsKICAgICAgaWYoZDI8MWUtOSkgcmV0dXJuIHAucmFuazsKICAgICAgaWYoZDI+cjIpIGNvbnRpbnVlOwogICAgICBjb25zdCB3PU1hdGguZXhwKC1kMi8oMipzMikpOwogICAgICBudW0rPXcqcC5yYW5rOyBkZW4rPXc7CiAgICB9CiAgICByZXR1cm4gZGVuPjA/KG51bS9kZW4pOm51bGw7CiAgfQogIGZ1bmN0aW9uIHByZWRpY3RBdChjeCxjeSxwdHMse3Bvd2VyLHJhZGl1c1B4LHNpZ21hfSl7CiAgICBjb25zdCBtb2RlPWVsLmludGVycE1vZGUudmFsdWU7CiAgICBpZihtb2RlPT09Im5lYXJlc3QiKSByZXR1cm4gbmVhcmVzdEF0KGN4LGN5LHB0cyxyYWRpdXNQeCk7CiAgICBpZihtb2RlPT09ImdhdXNzIikgcmV0dXJuIGdhdXNzQXQoY3gsY3kscHRzLHNpZ21hLHJhZGl1c1B4KTsKICAgIHJldHVybiBpZHdBdChjeCxjeSxwdHMscG93ZXIscmFkaXVzUHgpOwogIH0KCiAgZnVuY3Rpb24gZHJhd0hlYXRtYXAocG9pbnRzLGJib3gse2dyaWQsbWF4UmFuayxwb3dlcixyYWRpdXNQeCxzaWdtYX0pewogICAgY29uc3QgcHRzPXBvaW50cy5tYXAocD0+ewogICAgICBjb25zdCBjPXdvcmxkVG9DYW52YXMocC54LHAueSxiYm94KTsKICAgICAgcmV0dXJuIHsuLi5wLGN4OmMuY3gsY3k6Yy5jeX07CiAgICB9KTsKICAgIGNvbnN0IHRpbGVXPWVsLmNhbnZhcy53aWR0aC9ncmlkOwogICAgY29uc3QgdGlsZUg9ZWwuY2FudmFzLmhlaWdodC9ncmlkOwogICAgY29uc3QgaW1nPWN0eC5jcmVhdGVJbWFnZURhdGEoZWwuY2FudmFzLndpZHRoLGVsLmNhbnZhcy5oZWlnaHQpOwogICAgY29uc3QgZGF0YT1pbWcuZGF0YTsKCiAgICBsZXQgbWFza1JpbmdzPVtdOwogICAgaWYoZWwubWFza01vZGUudmFsdWU9PT0iZHJhd24iKSBtYXNrUmluZ3M9ZHJhd1JpbmdzOwogICAgaWYoZWwubWFza01vZGUudmFsdWU9PT0iZ2VvanNvbiIgJiYgZ2VvanNvbiAmJiBlbC51bml0cy52YWx1ZT09PSJsYXRsbmciKSBtYXNrUmluZ3M9Z2VvanNvblRvUmluZ3NMYXRMbmcoZ2VvanNvbik7CgogICAgZm9yKGxldCBneT0wO2d5PGdyaWQ7Z3krKyl7CiAgICAgIGZvcihsZXQgZ3g9MDtneDxncmlkO2d4KyspewogICAgICAgIGNvbnN0IGN4PShneCswLjUpKnRpbGVXLCBjeT0oZ3krMC41KSp0aWxlSDsKCiAgICAgICAgaWYobWFza1JpbmdzLmxlbmd0aCl7CiAgICAgICAgICBjb25zdCB3PWNhbnZhc1RvV29ybGQoY3gsY3ksYmJveCk7CiAgICAgICAgICBpZighcG9pbnRJblBvbHlnb25SaW5ncyh3Lngsdy55LG1hc2tSaW5ncykpIGNvbnRpbnVlOwogICAgICAgIH0KCiAgICAgICAgY29uc3Qgcj1wcmVkaWN0QXQoY3gsY3kscHRzLHtwb3dlcixyYWRpdXNQeCxzaWdtYX0pOwogICAgICAgIGlmKHI9PW51bGwpIGNvbnRpbnVlOwogICAgICAgIGNvbnN0IGNvbD1yYW5rVG9Db2xvcihyLG1heFJhbmspOwoKICAgICAgICAvLyBmYWRlIGJ5IG5lYXJlc3QKICAgICAgICBsZXQgbmVhcmVzdD1JbmZpbml0eTsKICAgICAgICBmb3IoY29uc3QgcCBvZiBwdHMpewogICAgICAgICAgY29uc3QgZHg9Y3gtcC5jeCwgZHk9Y3ktcC5jeTsKICAgICAgICAgIG5lYXJlc3Q9TWF0aC5taW4obmVhcmVzdCwgTWF0aC5zcXJ0KGR4KmR4K2R5KmR5KSk7CiAgICAgICAgfQogICAgICAgIGNvbnN0IGZhZGU9cmFkaXVzUHg+MD9jbGFtcCgxLShuZWFyZXN0L3JhZGl1c1B4KSwwLDEpOjE7CiAgICAgICAgY29uc3QgYT1jb2wuYSooMC4yNSswLjc1KmZhZGUpOwoKICAgICAgICBjb25zdCB4MD1NYXRoLmZsb29yKGd4KnRpbGVXKSwgeTA9TWF0aC5mbG9vcihneSp0aWxlSCk7CiAgICAgICAgY29uc3QgeDE9TWF0aC5taW4oZWwuY2FudmFzLndpZHRoLCBNYXRoLmZsb29yKChneCsxKSp0aWxlVykpOwogICAgICAgIGNvbnN0IHkxPU1hdGgubWluKGVsLmNhbnZhcy5oZWlnaHQsIE1hdGguZmxvb3IoKGd5KzEpKnRpbGVIKSk7CgogICAgICAgIGZvcihsZXQgcHk9eTA7cHk8eTE7cHkrKyl7CiAgICAgICAgICBmb3IobGV0IHB4PXgwO3B4PHgxO3B4KyspewogICAgICAgICAgICBjb25zdCBpZHg9KHB5KmVsLmNhbnZhcy53aWR0aCtweCkqNDsKICAgICAgICAgICAgY29uc3QgYmdSPWRhdGFbaWR4XSwgYmdHPWRhdGFbaWR4KzFdLCBiZ0I9ZGF0YVtpZHgrMl07CiAgICAgICAgICAgIGRhdGFbaWR4XT1NYXRoLnJvdW5kKGNvbC5yKmEgKyBiZ1IqKDEtYSkpOwogICAgICAgICAgICBkYXRhW2lkeCsxXT1NYXRoLnJvdW5kKGNvbC5nKmEgKyBiZ0cqKDEtYSkpOwogICAgICAgICAgICBkYXRhW2lkeCsyXT1NYXRoLnJvdW5kKGNvbC5iKmEgKyBiZ0IqKDEtYSkpOwogICAgICAgICAgICBkYXRhW2lkeCszXT0yNTU7CiAgICAgICAgICB9CiAgICAgICAgfQogICAgICB9CiAgICB9CiAgICBjdHgucHV0SW1hZ2VEYXRhKGltZywwLDApOwogIH0KCiAgZnVuY3Rpb24gZHJhd1BvaW50cyhwb2ludHMsYmJveCx7bWF4UmFuayxzaG93TGFiZWxzfSl7CiAgICBjb25zdCBiZz1lbC5iZ01vZGUudmFsdWU7CiAgICBjb25zdCB0ZXh0Q29sb3I9Ymc9PT0ibGlnaHQiPyIjMTExIjoiI2ZmZiI7CiAgICBjb25zdCBzdHJva2VDb2xvcj1iZz09PSJsaWdodCI/InJnYmEoMCwwLDAsMC4yNSkiOiJyZ2JhKDI1NSwyNTUsMjU1LDAuMjgpIjsKICAgIGZvcihjb25zdCBwIG9mIHBvaW50cyl7CiAgICAgIGNvbnN0IGM9d29ybGRUb0NhbnZhcyhwLngscC55LGJib3gpOwogICAgICBjb25zdCBjb2w9cmFua1RvQ29sb3IocC5yYW5rLG1heFJhbmspOwogICAgICBjdHguYmVnaW5QYXRoKCk7IGN0eC5hcmMoYy5jeCxjLmN5LDEwLDAsTWF0aC5QSSoyKTsKICAgICAgY3R4LmZpbGxTdHlsZT1gcmdiYSgke2NvbC5yfSwke2NvbC5nfSwke2NvbC5ifSwwLjk1KWA7IGN0eC5maWxsKCk7CiAgICAgIGN0eC5saW5lV2lkdGg9MjsgY3R4LnN0cm9rZVN0eWxlPXN0cm9rZUNvbG9yOyBjdHguc3Ryb2tlKCk7CiAgICAgIGN0eC5iZWdpblBhdGgoKTsgY3R4LmFyYyhjLmN4LGMuY3ksMy41LDAsTWF0aC5QSSoyKTsKICAgICAgY3R4LmZpbGxTdHlsZT0icmdiYSgwLDAsMCwwLjM1KSI7IGN0eC5maWxsKCk7CgogICAgICBpZihzaG93TGFiZWxzKXsKICAgICAgICBjb25zdCBsYWJlbD1gIyR7TWF0aC5yb3VuZChwLnJhbmspfSDigKIgJHtwLmxvY2F0aW9ufWA7CiAgICAgICAgY3R4LmZvbnQ9IjEycHggc3lzdGVtLXVpLC1hcHBsZS1zeXN0ZW0sU2Vnb2UgVUksUm9ib3RvLEFyaWFsIjsKICAgICAgICBjb25zdCBwYWQ9NiwgdHc9Y3R4Lm1lYXN1cmVUZXh0KGxhYmVsKS53aWR0aDsKICAgICAgICBjb25zdCBieD1jLmN4KzE0LCBieT1jLmN5LCBidz10dytwYWQqMiwgYmg9MjA7CiAgICAgICAgY3R4LmZpbGxTdHlsZT1iZz09PSJsaWdodCI/InJnYmEoMjU1LDI1NSwyNTUsMC44MikiOiJyZ2JhKDAsMCwwLDAuNTUpIjsKICAgICAgICBjdHguc3Ryb2tlU3R5bGU9c3Ryb2tlQ29sb3I7IGN0eC5saW5lV2lkdGg9MTsKICAgICAgICByb3VuZFJlY3QoY3R4LGJ4LGJ5LWJoLzIsYncsYmgsOCk7IGN0eC5maWxsKCk7IGN0eC5zdHJva2UoKTsKICAgICAgICBjdHguZmlsbFN0eWxlPXRleHRDb2xvcjsgY3R4LnRleHRBbGlnbj0ibGVmdCI7IGN0eC50ZXh0QmFzZWxpbmU9Im1pZGRsZSI7CiAgICAgICAgY3R4LmZpbGxUZXh0KGxhYmVsLGJ4K3BhZCxieSk7CiAgICAgIH0KICAgIH0KICB9CgogIC8vIEluc3BlY3RvciBwaW5zCiAgZnVuY3Rpb24gbmVhcmVzdFBvaW50SW5mbyh3b3JsZFgsd29ybGRZLHBvaW50cyl7CiAgICBsZXQgYmVzdD1udWxsLCBiZDI9SW5maW5pdHk7CiAgICBmb3IoY29uc3QgcCBvZiBwb2ludHMpewogICAgICBjb25zdCBkeD13b3JsZFgtcC54LCBkeT13b3JsZFktcC55OyBjb25zdCBkMj1keCpkeCtkeSpkeTsKICAgICAgaWYoZDI8YmQyKXsgYmQyPWQyOyBiZXN0PXA7IH0KICAgIH0KICAgIHJldHVybiBiZXN0P2AjJHtiZXN0LnJhbmt9IEAgJHtiZXN0LmxvY2F0aW9ufWA6bnVsbDsKICB9CiAgZnVuY3Rpb24gdXBkYXRlUGluc1BpbGwoKXsKICAgIGVsLnBpbnNQaWxsLnRleHRDb250ZW50PWBQaW5zOiAke3BpbnMubGVuZ3RofWA7CiAgICBlbC5leHBvcnRQaW5zQnRuLmRpc2FibGVkPXBpbnMubGVuZ3RoPT09MDsKICAgIGVsLmNsZWFyUGluc0J0bi5kaXNhYmxlZD1waW5zLmxlbmd0aD09PTA7CiAgfQogIGZ1bmN0aW9uIHBpbnNUb0NTVihhcnIpewogICAgY29uc3QgbGluZXM9W1siaWQiLCJidXNpbmVzcyIsImRhdGUiLCJrZXl3b3JkIiwieCIsInkiLCJwcmVkIiwibmVhcmVzdCIsIm5vdGUiXS5qb2luKCIsIildOwogICAgZm9yKGNvbnN0IHAgb2YgYXJyKXsKICAgICAgbGluZXMucHVzaChbCiAgICAgICAgY3N2RXNjYXBlKHAuaWQpLCBjc3ZFc2NhcGUocC5idXNpbmVzcyksIGNzdkVzY2FwZShwLmRhdGUpLCBjc3ZFc2NhcGUocC5rZXl3b3JkKSwKICAgICAgICBTdHJpbmcocC54KSwgU3RyaW5nKHAueSksIHAucHJlZC50b0ZpeGVkKDQpLCBjc3ZFc2NhcGUocC5uZWFyZXN0fHwiIiksIGNzdkVzY2FwZShwLm5vdGV8fCIiKQogICAgICBdLmpvaW4oIiwiKSk7CiAgICB9CiAgICByZXR1cm4gbGluZXMuam9pbigiXG4iKTsKICB9CgogIC8vIERyYXdpbmcgY29udHJvbHMKICBmdW5jdGlvbiBlbnN1cmVEcmF3QXZhaWxhYmxlKCl7CiAgICBpZihlbC51bml0cy52YWx1ZSE9PSJsYXRsbmciKSByZXR1cm4ge29rOmZhbHNlLCBlcnJvcjoiRHJhd2luZyBvbmx5IHdvcmtzIGluIExhdC9MbmcgbW9kZS4ifTsKICAgIGlmKCFsYXN0UmVuZGVyQkJveCkgcmV0dXJuIHtvazpmYWxzZSwgZXJyb3I6IlJlbmRlciBvbmNlIGJlZm9yZSBkcmF3aW5nICh0byBzZXQgdmlldyBib3VuZHMpLiJ9OwogICAgcmV0dXJuIHtvazp0cnVlfTsKICB9CiAgZnVuY3Rpb24gdXBkYXRlRHJhd1VJKCl7CiAgICBlbC5kcmF3UGlsbC50ZXh0Q29udGVudD1gRHJhdzogJHtkcmF3QWN0aXZlPyJvbiI6Im9mZiJ9YDsKICAgIGVsLmRyYXdUb2dnbGVCdG4udGV4dENvbnRlbnQ9ZHJhd0FjdGl2ZT8iU3RvcCBkcmF3aW5nIjoiU3RhcnQgZHJhd2luZyI7CiAgICBjb25zdCBvdXRlck9rPShkcmF3UmluZ3NbMF0/Lmxlbmd0aD8/MCk+PTM7CiAgICBjb25zdCByaW5nPWRyYXdSaW5nc1thY3RpdmVSaW5nSW5kZXhdfHxbXTsKICAgIGNvbnN0IGNhblVuZG89ZHJhd0FjdGl2ZSAmJiAocmluZy5sZW5ndGg+MCB8fCBkcmF3UmluZ3MubGVuZ3RoPjEpOwogICAgZWwuZHJhd1VuZG9CdG4uZGlzYWJsZWQ9IWNhblVuZG87CiAgICBlbC5kcmF3QWRkSG9sZUJ0bi5kaXNhYmxlZD0hZHJhd0FjdGl2ZSB8fCAhb3V0ZXJPayB8fCBhY3RpdmVSaW5nSW5kZXghPT0wOwogICAgZWwuZHJhd0ZpbmlzaEJ0bi5kaXNhYmxlZD0hZHJhd0FjdGl2ZSB8fCAhb3V0ZXJPazsKICB9CiAgZnVuY3Rpb24gc3RhcnREcmF3aW5nKCl7CiAgICBjb25zdCBjaGs9ZW5zdXJlRHJhd0F2YWlsYWJsZSgpOwogICAgaWYoIWNoay5vayl7IHNldFN0YXR1cyhjaGsuZXJyb3IpOyByZXR1cm47IH0KICAgIGRyYXdBY3RpdmU9dHJ1ZTsgZHJhd1JpbmdzPVtbXV07IGFjdGl2ZVJpbmdJbmRleD0wOyBkcmF3SG92ZXI9bnVsbDsgc25hcEhvdmVyPW51bGw7CiAgICB1cGRhdGVEcmF3VUkoKTsgcmVuZGVyKCk7CiAgfQogIGZ1bmN0aW9uIHN0b3BEcmF3aW5nKG5vdGU9IiIpewogICAgZHJhd0FjdGl2ZT1mYWxzZTsgZHJhd1JpbmdzPVtdOyBhY3RpdmVSaW5nSW5kZXg9MDsgZHJhd0hvdmVyPW51bGw7IHNuYXBIb3Zlcj1udWxsOwogICAgdXBkYXRlRHJhd1VJKCk7IHJlbmRlcigpOyBpZihub3RlKSBzZXRTdGF0dXMobm90ZSk7CiAgfQogIGZ1bmN0aW9uIHVuZG9EcmF3KCl7CiAgICBpZighZHJhd0FjdGl2ZSkgcmV0dXJuOwogICAgY29uc3QgcmluZz1kcmF3UmluZ3NbYWN0aXZlUmluZ0luZGV4XTsKICAgIGlmKHJpbmcgJiYgcmluZy5sZW5ndGgpIHJpbmcucG9wKCk7CiAgICBlbHNlIGlmKGRyYXdSaW5ncy5sZW5ndGg+MSl7IGRyYXdSaW5ncy5wb3AoKTsgYWN0aXZlUmluZ0luZGV4PWRyYXdSaW5ncy5sZW5ndGgtMTsgfQogICAgdXBkYXRlRHJhd1VJKCk7IHJlbmRlcigpOwogIH0KICBmdW5jdGlvbiBhZGRIb2xlKCl7CiAgICBpZighZHJhd0FjdGl2ZSkgcmV0dXJuOwogICAgaWYoKGRyYXdSaW5nc1swXT8ubGVuZ3RoPz8wKTwzKXsgc2V0U3RhdHVzKCJOZWVkIDMrIHBvaW50cyBmb3Igb3V0ZXIgcmluZyBmaXJzdC4iKTsgcmV0dXJuOyB9CiAgICBkcmF3UmluZ3MucHVzaChbXSk7IGFjdGl2ZVJpbmdJbmRleD1kcmF3UmluZ3MubGVuZ3RoLTE7CiAgICBzZXRTdGF0dXMoIkhvbGUgZHJhd2luZyBzdGFydGVkLiBBZGQgMysgcG9pbnRzLCB0aGVuIGRvdWJsZS1jbGljayB0byBjbG9zZSByaW5nLiIpOwogICAgdXBkYXRlRHJhd1VJKCk7IHJlbmRlcigpOwogIH0KICBmdW5jdGlvbiBidWlsZEdlb0pTT05Gcm9tUmluZ3MocmluZ3MpewogICAgY29uc3QgY29vcmRzPXJpbmdzLm1hcChyaW5nPT57CiAgICAgIGNvbnN0IG91dD1yaW5nLm1hcChwPT5bcC5sbmcscC5sYXRdKTsKICAgICAgaWYob3V0Lmxlbmd0aCkgb3V0LnB1c2goW3JpbmdbMF0ubG5nLHJpbmdbMF0ubGF0XSk7CiAgICAgIHJldHVybiBvdXQ7CiAgICB9KTsKICAgIHJldHVybiB7dHlwZToiRmVhdHVyZUNvbGxlY3Rpb24iLGZlYXR1cmVzOlt7dHlwZToiRmVhdHVyZSIscHJvcGVydGllczp7bmFtZToiZHJhd25fcG9seWdvbiJ9LGdlb21ldHJ5Ont0eXBlOiJQb2x5Z29uIixjb29yZGluYXRlczpjb29yZHN9fV19OwogIH0KICBmdW5jdGlvbiBmaW5pc2hEcmF3KCl7CiAgICBjb25zdCBjaGs9ZW5zdXJlRHJhd0F2YWlsYWJsZSgpOwogICAgaWYoIWNoay5vayl7IHNldFN0YXR1cyhjaGsuZXJyb3IpOyByZXR1cm47IH0KICAgIGlmKChkcmF3UmluZ3NbMF0/Lmxlbmd0aD8/MCk8Myl7IHNldFN0YXR1cygiT3V0ZXIgcmluZyBuZWVkcyAzKyBwb2ludHMuIik7IHJldHVybjsgfQogICAgZm9yKGxldCBpPTE7aTxkcmF3UmluZ3MubGVuZ3RoO2krKykgaWYoKGRyYXdSaW5nc1tpXT8ubGVuZ3RoPz8wKTwzKXsgc2V0U3RhdHVzKGBIb2xlICR7aX0gbmVlZHMgMysgcG9pbnRzICh1bmRvIGl0KS5gKTsgcmV0dXJuOyB9CiAgICB0cnl7CiAgICAgIHNldEdlb0pTT04oYnVpbGRHZW9KU09ORnJvbVJpbmdzKGRyYXdSaW5ncykpOwogICAgICBzdG9wRHJhd2luZygiRHJhd24gcG9seWdvbiBzYXZlZCBhcyBHZW9KU09OLiIpOwogICAgICBpZihlbC5tYXNrTW9kZS52YWx1ZT09PSJvZmYiKSBlbC5tYXNrTW9kZS52YWx1ZT0iZ2VvanNvbiI7CiAgICAgIHJlbmRlcigpOwogICAgfSBjYXRjaChlKXsgc2V0U3RhdHVzKCJGaW5pc2ggZmFpbGVkOiAiKyhlPy5tZXNzYWdlfHxTdHJpbmcoZSkpKTsgfQogIH0KICBmdW5jdGlvbiBjb21wdXRlU25hcEhvdmVyKGJib3gsY3gsY3kpewogICAgY29uc3QgcmluZz1kcmF3UmluZ3NbYWN0aXZlUmluZ0luZGV4XXx8W107CiAgICBpZihyaW5nLmxlbmd0aDwzKSByZXR1cm4gbnVsbDsKICAgIGNvbnN0IHAwPXJpbmdbMF07CiAgICBjb25zdCBmaXJzdD13b3JsZFRvQ2FudmFzKHAwLmxhdCxwMC5sbmcsYmJveCk7CiAgICBjb25zdCBkeD1jeC1maXJzdC5jeCwgZHk9Y3ktZmlyc3QuY3k7CiAgICBpZihkeCpkeCtkeSpkeSA8PSBTTkFQX1BYKlNOQVBfUFgpIHJldHVybiBmaXJzdDsKICAgIHJldHVybiBudWxsOwogIH0KICBmdW5jdGlvbiBkcmF3RHJhd2luZ092ZXJsYXkoYmJveCl7CiAgICBpZighZHJhd0FjdGl2ZSkgcmV0dXJuOwogICAgY29uc3QgYmc9ZWwuYmdNb2RlLnZhbHVlOwogICAgY29uc3Qgb3V0bGluZT1iZz09PSJsaWdodCI/InJnYmEoMCwwLDAsMC43MCkiOiJyZ2JhKDI1NSwyNTUsMjU1LDAuODApIjsKICAgIGNvbnN0IGZpbGw9Ymc9PT0ibGlnaHQiPyJyZ2JhKDAsMCwwLDAuMDgpIjoicmdiYSgyNTUsMjU1LDI1NSwwLjA4KSI7CiAgICBjb25zdCBwb2ludEZpbGw9Ymc9PT0ibGlnaHQiPyJyZ2JhKDAsMCwwLDAuODUpIjoicmdiYSgyNTUsMjU1LDI1NSwwLjkwKSI7CiAgICBjb25zdCBzbmFwQ29sb3I9InJnYmEoMTAsMTEwLDI1NSwwLjg1KSI7CiAgICBjdHguc2F2ZSgpOwogICAgY3R4LmxpbmVXaWR0aD0yOyBjdHguc3Ryb2tlU3R5bGU9b3V0bGluZTsgY3R4LmZpbGxTdHlsZT1maWxsOwoKICAgIGZvcihsZXQgcmk9MDtyaTxkcmF3UmluZ3MubGVuZ3RoO3JpKyspewogICAgICBjb25zdCByaW5nPWRyYXdSaW5nc1tyaV07IGlmKCFyaW5nLmxlbmd0aCkgY29udGludWU7CiAgICAgIGN0eC5iZWdpblBhdGgoKTsKICAgICAgZm9yKGxldCBpPTA7aTxyaW5nLmxlbmd0aDtpKyspewogICAgICAgIGNvbnN0IHA9cmluZ1tpXTsgY29uc3QgYz13b3JsZFRvQ2FudmFzKHAubGF0LHAubG5nLGJib3gpOwogICAgICAgIGlmKGk9PT0wKSBjdHgubW92ZVRvKGMuY3gsYy5jeSk7IGVsc2UgY3R4LmxpbmVUbyhjLmN4LGMuY3kpOwogICAgICB9CiAgICAgIGlmKHJpPT09YWN0aXZlUmluZ0luZGV4ICYmIGRyYXdIb3ZlcikgY3R4LmxpbmVUbyhkcmF3SG92ZXIuY3gsZHJhd0hvdmVyLmN5KTsKICAgICAgY3R4LnN0cm9rZSgpOwogICAgfQoKICAgIGlmKChkcmF3UmluZ3NbMF0/Lmxlbmd0aD8/MCk+PTMpewogICAgICBjdHguYmVnaW5QYXRoKCk7CiAgICAgIGZvcihjb25zdCByaW5nIG9mIGRyYXdSaW5ncyl7CiAgICAgICAgZm9yKGxldCBpPTA7aTxyaW5nLmxlbmd0aDtpKyspewogICAgICAgICAgY29uc3QgcD1yaW5nW2ldOyBjb25zdCBjPXdvcmxkVG9DYW52YXMocC5sYXQscC5sbmcsYmJveCk7CiAgICAgICAgICBpZihpPT09MCkgY3R4Lm1vdmVUbyhjLmN4LGMuY3kpOyBlbHNlIGN0eC5saW5lVG8oYy5jeCxjLmN5KTsKICAgICAgICB9CiAgICAgICAgY3R4LmNsb3NlUGF0aCgpOwogICAgICB9CiAgICAgIGN0eC5maWxsKCJldmVub2RkIik7IGN0eC5zdHJva2UoKTsKICAgIH0KCiAgICBmb3IoY29uc3QgcmluZyBvZiBkcmF3UmluZ3MpewogICAgICBmb3IoY29uc3QgcCBvZiByaW5nKXsKICAgICAgICBjb25zdCBjPXdvcmxkVG9DYW52YXMocC5sYXQscC5sbmcsYmJveCk7CiAgICAgICAgY3R4LmJlZ2luUGF0aCgpOyBjdHguYXJjKGMuY3gsYy5jeSw1LjUsMCxNYXRoLlBJKjIpOwogICAgICAgIGN0eC5maWxsU3R5bGU9cG9pbnRGaWxsOyBjdHguZmlsbCgpOwogICAgICB9CiAgICB9CiAgICBpZihzbmFwSG92ZXIpewogICAgICBjdHguYmVnaW5QYXRoKCk7IGN0eC5hcmMoc25hcEhvdmVyLmN4LHNuYXBIb3Zlci5jeSwxMCwwLE1hdGguUEkqMik7CiAgICAgIGN0eC5zdHJva2VTdHlsZT1zbmFwQ29sb3I7IGN0eC5saW5lV2lkdGg9MzsgY3R4LnN0cm9rZSgpOwogICAgfQoKICAgIGNvbnN0IGJveFc9NTIwLCBib3hIPTYyLCB4PTE4LCB5PTY2OwogICAgY29uc3QgYm94RmlsbD1iZz09PSJsaWdodCI/InJnYmEoMjU1LDI1NSwyNTUsMC45MCkiOiJyZ2JhKDAsMCwwLDAuNjUpIjsKICAgIGNvbnN0IHN0cm9rZT1iZz09PSJsaWdodCI/InJnYmEoMCwwLDAsMC4xOCkiOiJyZ2JhKDI1NSwyNTUsMjU1LDAuMTgpIjsKICAgIGN0eC5maWxsU3R5bGU9Ym94RmlsbDsgY3R4LnN0cm9rZVN0eWxlPXN0cm9rZTsgY3R4LmxpbmVXaWR0aD0xOwogICAgcm91bmRSZWN0KGN0eCx4LHksYm94Vyxib3hILDEyKTsgY3R4LmZpbGwoKTsgY3R4LnN0cm9rZSgpOwogICAgY3R4LmZpbGxTdHlsZT1iZz09PSJsaWdodCI/IiMxMTEiOiIjZmZmIjsKICAgIGN0eC5mb250PSIxMnB4IHN5c3RlbS11aSwtYXBwbGUtc3lzdGVtLFNlZ29lIFVJLFJvYm90byxBcmlhbCI7CiAgICBjdHgudGV4dEFsaWduPSJsZWZ0IjsgY3R4LnRleHRCYXNlbGluZT0idG9wIjsKICAgIGNvbnN0IHJpbmdOYW1lPWFjdGl2ZVJpbmdJbmRleD09PTA/Im91dGVyIHJpbmciOmBob2xlICR7YWN0aXZlUmluZ0luZGV4fWA7CiAgICBjdHguZmlsbFRleHQoYERyYXdpbmcgJHtyaW5nTmFtZX06IGNsaWNrIHZlcnRpY2VzIOKAoiBzbmFwIHRvIGZpcnN0IHBvaW50IOKAoiBkb3VibGUtY2xpY2sgY2xvc2VzIHJpbmdgLHgrMTIseSsxMCk7CiAgICBjdHguZmlsbFRleHQoYEFmdGVyIG91dGVyIHJpbmc6IEFkZCBob2xlIChvcHRpb25hbCkg4oaSIEZpbmlzaC4gRXNjIGNhbmNlbHMuIEN0cmwvQ21kK1ogdW5kby5gLHgrMTIseSszMCk7CiAgICBjdHgucmVzdG9yZSgpOwogIH0KCiAgLy8gVmFsaWRhdGlvbiArIGJ1aWxkaW5nIHJvd3MKICBmdW5jdGlvbiBlcnJvcnNUb0NTVihlcnJvcnMpewogICAgY29uc3QgbGluZXM9W1sic3JjIiwicm93IiwicmVhc29uIiwicmF3Il0uam9pbigiLCIpXTsKICAgIGZvcihjb25zdCBlIG9mIGVycm9ycykgbGluZXMucHVzaChbY3N2RXNjYXBlKGUuc3JjKSwgZS5yb3csIGNzdkVzY2FwZShlLnJlYXNvbiksIGNzdkVzY2FwZShlLnJhdyldLmpvaW4oIiwiKSk7CiAgICByZXR1cm4gbGluZXMuam9pbigiXG4iKTsKICB9CiAgZnVuY3Rpb24gcm93c1RvTm9ybWFsaXplZENTVihycyl7CiAgICBjb25zdCBpc0xhdExuZz1lbC51bml0cy52YWx1ZT09PSJsYXRsbmciOwogICAgY29uc3QgeE5hbWU9aXNMYXRMbmc/ImxhdCI6IngiOwogICAgY29uc3QgeU5hbWU9aXNMYXRMbmc/ImxuZyI6InkiOwogICAgY29uc3QgY29scz1bImtleXdvcmQiLCJsb2NhdGlvbiIseE5hbWUseU5hbWUsInJhbmsiLCJidXNpbmVzcyIsImRhdGUiLCJ2b2x1bWUiXTsKICAgIGNvbnN0IGxpbmVzPVtjb2xzLmpvaW4oIiwiKV07CiAgICBmb3IoY29uc3QgciBvZiBycyl7CiAgICAgIGxpbmVzLnB1c2goWwogICAgICAgIGNzdkVzY2FwZShyLmtleXdvcmQpLCBjc3ZFc2NhcGUoci5sb2NhdGlvbiksCiAgICAgICAgU3RyaW5nKHIueCksIFN0cmluZyhyLnkpLCBTdHJpbmcoci5yYW5rKSwKICAgICAgICBjc3ZFc2NhcGUoci5idXNpbmVzc3x8IiIpLCBjc3ZFc2NhcGUoci5kYXRlfHwiIiksIHIudm9sdW1lPT1udWxsPyIiOlN0cmluZyhyLnZvbHVtZSkKICAgICAgXS5qb2luKCIsIikpOwogICAgfQogICAgcmV0dXJuIGxpbmVzLmpvaW4oIlxuIik7CiAgfQogIGZ1bmN0aW9uIG5vcm1hbGl6ZURhdGUocyl7CiAgICBjb25zdCB0PVN0cmluZyhzfHwiIikudHJpbSgpOwogICAgaWYoIXQpIHJldHVybiAiIjsKICAgIGlmKC9eXGR7NH0tXGR7Mn0tXGR7Mn0kLy50ZXN0KHQpKSByZXR1cm4gdDsKICAgIGNvbnN0IG0xPXQubWF0Y2goL14oXGR7NH0pW1wvLl0oXGR7MSwyfSlbXC8uXShcZHsxLDJ9KSQvKTsKICAgIGlmKG0xKXsgY29uc3QgeT1tMVsxXSwgbW89U3RyaW5nKG0xWzJdKS5wYWRTdGFydCgyLCIwIiksIGQ9U3RyaW5nKG0xWzNdKS5wYWRTdGFydCgyLCIwIik7IHJldHVybiBgJHt5fS0ke21vfS0ke2R9YDsgfQogICAgY29uc3QgbTI9dC5tYXRjaCgvXihcZHsxLDJ9KVtcLy5dKFxkezEsMn0pW1wvLl0oXGR7NH0pJC8pOwogICAgaWYobTIpeyBjb25zdCB5PW0yWzNdLCBtbz1TdHJpbmcobTJbMV0pLnBhZFN0YXJ0KDIsIjAiKSwgZD1TdHJpbmcobTJbMl0pLnBhZFN0YXJ0KDIsIjAiKTsgcmV0dXJuIGAke3l9LSR7bW99LSR7ZH1gOyB9CiAgICByZXR1cm4gdDsKICB9CgogIGZ1bmN0aW9uIGJ1aWxkRnJvbUxvbmcocGFyc2VkLCBzcmNOYW1lKXsKICAgIHJlYWRNYXBwaW5nRnJvbVVJKCk7CiAgICBjb25zdCBoZWFkZXJzPShwYXJzZWRbMF18fFtdKS5tYXAocz0+U3RyaW5nKHM/PyIiKS50cmltKCkpLmZpbHRlcihCb29sZWFuKTsKICAgIGNvbnN0IGlkeD1uZXcgTWFwKCk7IGhlYWRlcnMuZm9yRWFjaCgoaCxpKT0+aWR4LnNldChoLGkpKTsKICAgIGNvbnN0IHJlcT1bbWFwTG9uZy5rZXl3b3JkLG1hcExvbmcubG9jYXRpb24sbWFwTG9uZy5yYW5rLG1hcExvbmcueCxtYXBMb25nLnldOwogICAgaWYocmVxLnNvbWUodj0+IXYpKSByZXR1cm4ge3Jvd3M6W10sIGVycm9yczpbe3NyYzpzcmNOYW1lLHJvdzowLHJlYXNvbjoiTWFwcGluZyBpbmNvbXBsZXRlIChsb25nKSIscmF3OiIifV19OwogICAgY29uc3Qga0k9aWR4LmdldChtYXBMb25nLmtleXdvcmQpLCBsST1pZHguZ2V0KG1hcExvbmcubG9jYXRpb24pLCByST1pZHguZ2V0KG1hcExvbmcucmFuayksIHhJPWlkeC5nZXQobWFwTG9uZy54KSwgeUk9aWR4LmdldChtYXBMb25nLnkpOwogICAgY29uc3QgYkk9bWFwTG9uZy5idXNpbmVzcz9pZHguZ2V0KG1hcExvbmcuYnVzaW5lc3MpOm51bGw7CiAgICBjb25zdCBkST1tYXBMb25nLmRhdGU/aWR4LmdldChtYXBMb25nLmRhdGUpOm51bGw7CiAgICBjb25zdCB2ST1tYXBMb25nLnZvbHVtZT9pZHguZ2V0KG1hcExvbmcudm9sdW1lKTpudWxsOwogICAgY29uc3Qgb3V0PVtdLCBlcnJzPVtdOwogICAgZm9yKGxldCBpPTE7aTxwYXJzZWQubGVuZ3RoO2krKyl7CiAgICAgIGNvbnN0IGxpbmU9cGFyc2VkW2ldfHxbXTsKICAgICAgY29uc3QgcmF3PWxpbmUuam9pbigiLCIpOwogICAgICBjb25zdCBrZXl3b3JkPVN0cmluZyhsaW5lW2tJXT8/IiIpLnRyaW0oKTsKICAgICAgY29uc3QgbG9jYXRpb249U3RyaW5nKGxpbmVbbEldPz8iIikudHJpbSgpOwogICAgICBsZXQgcmFuaz1zYWZlTnVtYmVyKGxpbmVbckldKTsKICAgICAgY29uc3QgeD1zYWZlTnVtYmVyKGxpbmVbeEldKTsgY29uc3QgeT1zYWZlTnVtYmVyKGxpbmVbeUldKTsKICAgICAgY29uc3QgYnVzaW5lc3M9YkkhPW51bGw/U3RyaW5nKGxpbmVbYkldPz8iIikudHJpbSgpOiIiOwogICAgICBjb25zdCBkYXRlPWRJIT1udWxsP25vcm1hbGl6ZURhdGUoU3RyaW5nKGxpbmVbZEldPz8iIikpOiIiOwogICAgICBjb25zdCB2b2x1bWU9dkkhPW51bGw/c2FmZU51bWJlcihsaW5lW3ZJXSk6bnVsbDsKICAgICAgaWYoIWtleXdvcmR8fCFsb2NhdGlvbil7IGVycnMucHVzaCh7c3JjOnNyY05hbWUscm93OmkrMSxyZWFzb246Ik1pc3Npbmcga2V5d29yZC9sb2NhdGlvbiIscmF3fSk7IGNvbnRpbnVlOyB9CiAgICAgIGlmKHg9PW51bGx8fHk9PW51bGwpeyBlcnJzLnB1c2goe3NyYzpzcmNOYW1lLHJvdzppKzEscmVhc29uOiJJbnZhbGlkIGNvb3JkcyIscmF3fSk7IGNvbnRpbnVlOyB9CiAgICAgIGlmKHJhbms9PW51bGwpewogICAgICAgIGlmKGVsLm1pc3NpbmdQb2xpY3kudmFsdWU9PT0iY2FwIikgcmFuaz0oTnVtYmVyKGVsLm1heFJhbmsudmFsdWUpfHwyMCkrMTsKICAgICAgICBlbHNlIHsgZXJycy5wdXNoKHtzcmM6c3JjTmFtZSxyb3c6aSsxLHJlYXNvbjoiTWlzc2luZy9pbnZhbGlkIHJhbmsiLHJhd30pOyBjb250aW51ZTsgfQogICAgICB9CiAgICAgIGlmKHJhbms8PTApeyBlcnJzLnB1c2goe3NyYzpzcmNOYW1lLHJvdzppKzEscmVhc29uOiJSYW5rIDw9IDAiLHJhd30pOyBjb250aW51ZTsgfQogICAgICBvdXQucHVzaCh7a2V5d29yZCxsb2NhdGlvbix4LHkscmFuayxidXNpbmVzczpidXNpbmVzc3x8ImRlZmF1bHQiLGRhdGU6ZGF0ZXx8ImxhdGVzdCIsdm9sdW1lOnZvbHVtZT09bnVsbD91bmRlZmluZWQ6dm9sdW1lLF9zcmM6c3JjTmFtZSxfcm93OmkrMX0pOwogICAgfQogICAgcmV0dXJuIHtyb3dzOm91dCwgZXJyb3JzOmVycnN9OwogIH0KCiAgZnVuY3Rpb24gYnVpbGRGcm9tV2lkZShwYXJzZWQsIHNyY05hbWUpewogICAgcmVhZE1hcHBpbmdGcm9tVUkoKTsKICAgIGNvbnN0IGhlYWRlcnM9KHBhcnNlZFswXXx8W10pLm1hcChzPT5TdHJpbmcocz8/IiIpLnRyaW0oKSkuZmlsdGVyKEJvb2xlYW4pOwogICAgY29uc3QgaWR4PW5ldyBNYXAoKTsgaGVhZGVycy5mb3JFYWNoKChoLGkpPT5pZHguc2V0KGgsaSkpOwogICAgY29uc3QgcmVxPVttYXBXaWRlLmxvY2F0aW9uLG1hcFdpZGUueCxtYXBXaWRlLnldOwogICAgaWYocmVxLnNvbWUodj0+IXYpKSByZXR1cm4ge3Jvd3M6W10sIGVycm9yczpbe3NyYzpzcmNOYW1lLHJvdzowLHJlYXNvbjoiTWFwcGluZyBpbmNvbXBsZXRlICh3aWRlKSIscmF3OiIifV19OwogICAgY29uc3QgbG9jST1pZHguZ2V0KG1hcFdpZGUubG9jYXRpb24pLCB4ST1pZHguZ2V0KG1hcFdpZGUueCksIHlJPWlkeC5nZXQobWFwV2lkZS55KTsKICAgIGNvbnN0IGJJPW1hcFdpZGUuYnVzaW5lc3M/aWR4LmdldChtYXBXaWRlLmJ1c2luZXNzKTpudWxsOwogICAgY29uc3QgZEk9bWFwV2lkZS5kYXRlP2lkeC5nZXQobWFwV2lkZS5kYXRlKTpudWxsOwoKICAgIGxldCBrZXl3b3JkQ29scz1tYXBXaWRlLmtleXdvcmRDb2xzLnNsaWNlKCk7CiAgICBpZigha2V5d29yZENvbHMubGVuZ3RoKXsKICAgICAgY29uc3QgYmFzZT1uZXcgU2V0KFttYXBXaWRlLmxvY2F0aW9uLG1hcFdpZGUueCxtYXBXaWRlLnksbWFwV2lkZS5idXNpbmVzcyxtYXBXaWRlLmRhdGUsbWFwV2lkZS52b2x1bWVDb2xdLmZpbHRlcihCb29sZWFuKSk7CiAgICAgIGtleXdvcmRDb2xzPWhlYWRlcnMuZmlsdGVyKGg9PiFiYXNlLmhhcyhoKSk7CiAgICB9CiAgICBjb25zdCBtaXNzaW5nPWtleXdvcmRDb2xzLmZpbHRlcihrPT4haWR4LmhhcyhrKSk7CiAgICBpZihtaXNzaW5nLmxlbmd0aCkgcmV0dXJuIHtyb3dzOltdLCBlcnJvcnM6W3tzcmM6c3JjTmFtZSxyb3c6MCxyZWFzb246Ik1pc3Npbmcga2V5d29yZCBjb2xzOiAiK21pc3Npbmcuam9pbigiLCAiKSxyYXc6IiJ9XX07CgogICAgY29uc3Qgb3V0PVtdLCBlcnJzPVtdOwogICAgZm9yKGxldCByPTE7cjxwYXJzZWQubGVuZ3RoO3IrKyl7CiAgICAgIGNvbnN0IGxpbmU9cGFyc2VkW3JdfHxbXTsKICAgICAgY29uc3QgcmF3PWxpbmUuam9pbigiLCIpOwogICAgICBjb25zdCBsb2NhdGlvbj1TdHJpbmcobGluZVtsb2NJXT8/IiIpLnRyaW0oKTsKICAgICAgY29uc3QgeD1zYWZlTnVtYmVyKGxpbmVbeEldKTsgY29uc3QgeT1zYWZlTnVtYmVyKGxpbmVbeUldKTsKICAgICAgY29uc3QgYnVzaW5lc3M9YkkhPW51bGw/U3RyaW5nKGxpbmVbYkldPz8iIikudHJpbSgpOiIiOwogICAgICBjb25zdCBkYXRlPWRJIT1udWxsP25vcm1hbGl6ZURhdGUoU3RyaW5nKGxpbmVbZEldPz8iIikpOiIiOwogICAgICBpZighbG9jYXRpb24peyBlcnJzLnB1c2goe3NyYzpzcmNOYW1lLHJvdzpyKzEscmVhc29uOiJNaXNzaW5nIGxvY2F0aW9uIixyYXd9KTsgY29udGludWU7IH0KICAgICAgaWYoeD09bnVsbHx8eT09bnVsbCl7IGVycnMucHVzaCh7c3JjOnNyY05hbWUscm93OnIrMSxyZWFzb246IkludmFsaWQgY29vcmRzIixyYXd9KTsgY29udGludWU7IH0KCiAgICAgIGNvbnN0IGJhc2VWb2x1bWU9KG1hcFdpZGUudm9sdW1lTW9kZT09PSJzaW5nbGVfY29sIiAmJiBtYXBXaWRlLnZvbHVtZUNvbCAmJiBpZHguaGFzKG1hcFdpZGUudm9sdW1lQ29sKSkKICAgICAgICA/IHNhZmVOdW1iZXIobGluZVtpZHguZ2V0KG1hcFdpZGUudm9sdW1lQ29sKV0pCiAgICAgICAgOiBudWxsOwoKICAgICAgZm9yKGNvbnN0IGt3Q29sIG9mIGtleXdvcmRDb2xzKXsKICAgICAgICBsZXQgcmFuaz1zYWZlTnVtYmVyKGxpbmVbaWR4LmdldChrd0NvbCldKTsKICAgICAgICBpZihyYW5rPT1udWxsKXsKICAgICAgICAgIGlmKGVsLm1pc3NpbmdQb2xpY3kudmFsdWU9PT0iY2FwIikgcmFuaz0oTnVtYmVyKGVsLm1heFJhbmsudmFsdWUpfHwyMCkrMTsKICAgICAgICAgIGVsc2UgeyBlcnJzLnB1c2goe3NyYzpzcmNOYW1lLHJvdzpyKzEscmVhc29uOmBNaXNzaW5nL2ludmFsaWQgcmFuayBmb3IgIiR7a3dDb2x9ImAscmF3fSk7IGNvbnRpbnVlOyB9CiAgICAgICAgfQogICAgICAgIGlmKHJhbms8PTApeyBlcnJzLnB1c2goe3NyYzpzcmNOYW1lLHJvdzpyKzEscmVhc29uOmBSYW5rIDw9IDAgZm9yICIke2t3Q29sfSJgLHJhd30pOyBjb250aW51ZTsgfQoKICAgICAgICBsZXQgdm9sdW1lPWJhc2VWb2x1bWU7CiAgICAgICAgaWYobWFwV2lkZS52b2x1bWVNb2RlPT09InBlcl9rZXl3b3JkX2NvbCIpewogICAgICAgICAgY29uc3QgbT1TdHJpbmcoa3dDb2wpLm1hdGNoKC9cfHZvbCg/Oj18OikoXGQrKD86XC5cZCspPykkL2kpOwogICAgICAgICAgaWYobSkgdm9sdW1lPU51bWJlcihtWzFdKTsKICAgICAgICB9CgogICAgICAgIG91dC5wdXNoKHtrZXl3b3JkOmt3Q29sLnJlcGxhY2UoL1x8dm9sKD86PXw6KS4qJC9pLCIiKS50cmltKCksbG9jYXRpb24seCx5LHJhbmssYnVzaW5lc3M6YnVzaW5lc3N8fCJkZWZhdWx0IixkYXRlOmRhdGV8fCJsYXRlc3QiLHZvbHVtZTp2b2x1bWU9PW51bGw/dW5kZWZpbmVkOnZvbHVtZSxfc3JjOnNyY05hbWUsX3JvdzpyKzF9KTsKICAgICAgfQogICAgfQogICAgcmV0dXJuIHtyb3dzOm91dCwgZXJyb3JzOmVycnN9OwogIH0KCiAgZnVuY3Rpb24gdmFsaWRhdGVBbmREZWR1cChycyl7CiAgICBjb25zdCBlcnJzPVtdLCBvdXQ9W107CiAgICBjb25zdCBpc0xhdExuZz1lbC51bml0cy52YWx1ZT09PSJsYXRsbmciOwogICAgY29uc3QgYmVzdEJ5S2V5PW5ldyBNYXAoKTsKICAgIGZvcihjb25zdCByIG9mIHJzKXsKICAgICAgaWYoIXIua2V5d29yZHx8IXIubG9jYXRpb24peyBlcnJzLnB1c2goe3NyYzpyLl9zcmN8fCIiLHJvdzpyLl9yb3d8fDAscmVhc29uOiJNaXNzaW5nIGtleXdvcmQvbG9jYXRpb24iLHJhdzpKU09OLnN0cmluZ2lmeShyKX0pOyBjb250aW51ZTsgfQogICAgICBpZighTnVtYmVyLmlzRmluaXRlKHIueCl8fCFOdW1iZXIuaXNGaW5pdGUoci55KSl7IGVycnMucHVzaCh7c3JjOnIuX3NyY3x8IiIscm93OnIuX3Jvd3x8MCxyZWFzb246IkludmFsaWQgY29vcmRzIixyYXc6SlNPTi5zdHJpbmdpZnkocil9KTsgY29udGludWU7IH0KICAgICAgaWYoaXNMYXRMbmcgJiYgKHIueDwtOTB8fHIueD45MHx8ci55PC0xODB8fHIueT4xODApKXsgZXJycy5wdXNoKHtzcmM6ci5fc3JjfHwiIixyb3c6ci5fcm93fHwwLHJlYXNvbjoiQ29vcmRzIG91dCBvZiBsYXQvbG5nIHJhbmdlIixyYXc6SlNPTi5zdHJpbmdpZnkocil9KTsgY29udGludWU7IH0KICAgICAgaWYoIU51bWJlci5pc0Zpbml0ZShyLnJhbmspfHxyLnJhbms8PTApeyBlcnJzLnB1c2goe3NyYzpyLl9zcmN8fCIiLHJvdzpyLl9yb3d8fDAscmVhc29uOiJJbnZhbGlkIHJhbmsiLHJhdzpKU09OLnN0cmluZ2lmeShyKX0pOyBjb250aW51ZTsgfQogICAgICBjb25zdCBiPXIuYnVzaW5lc3N8fCJkZWZhdWx0IiwgZD1yLmRhdGV8fCJsYXRlc3QiOwogICAgICBjb25zdCBrZXk9YCR7Yn18fCR7ZH18fCR7ci5rZXl3b3JkfXx8JHtyLmxvY2F0aW9ufWA7CiAgICAgIGNvbnN0IGV4PWJlc3RCeUtleS5nZXQoa2V5KTsKICAgICAgaWYoIWV4fHxyLnJhbms8ZXgucmFuaykgYmVzdEJ5S2V5LnNldChrZXkscik7CiAgICB9CiAgICBmb3IoY29uc3QgdiBvZiBiZXN0QnlLZXkudmFsdWVzKCkpIG91dC5wdXNoKHYpOwogICAgcmV0dXJuIHtyb3dzOm91dCwgZXJyb3JzOmVycnN9OwogIH0KCiAgZnVuY3Rpb24gYnVpbGREYXRhc2V0KCl7CiAgICBjb25zdCBzdGFnZWQ9KGVsLmNzdlRleHQudmFsdWV8fCIiKS50cmltKCk7CiAgICBjb25zdCB0ZXh0cz1pbXBvcnRCbG9icy5tYXAoYj0+KHtuYW1lOmIubmFtZSx0ZXh0OmIudGV4dH0pKTsKICAgIGlmKHN0YWdlZCkgdGV4dHMucHVzaCh7bmFtZToic3RhZ2luZyIsdGV4dDpzdGFnZWR9KTsKICAgIGlmKCF0ZXh0cy5sZW5ndGgpeyBzZXRTdGF0dXMoIk5vIENTViBwcm92aWRlZC4iKTsgcmV0dXJuOyB9CgogICAgbGV0IGFsbD1bXSwgZXJycz1bXTsKICAgIGZvcihjb25zdCB0IG9mIHRleHRzKXsKICAgICAgY29uc3QgcGFyc2VkPXBhcnNlQ1NWKHQudGV4dCk7CiAgICAgIGlmKHBhcnNlZC5sZW5ndGg8Mil7IGVycnMucHVzaCh7c3JjOnQubmFtZSxyb3c6MCxyZWFzb246IkNTViB0b28gc2hvcnQiLHJhdzoiIn0pOyBjb250aW51ZTsgfQogICAgICBjb25zdCBoZWFkZXJzPShwYXJzZWRbMF18fFtdKS5tYXAocz0+U3RyaW5nKHM/PyIiKS50cmltKCkpLmZpbHRlcihCb29sZWFuKTsKICAgICAgaWYoIWhlYWRlcnMubGVuZ3RoKXsgZXJycy5wdXNoKHtzcmM6dC5uYW1lLHJvdzowLHJlYXNvbjoiTWlzc2luZyBoZWFkZXJzIixyYXc6IiJ9KTsgY29udGludWU7IH0KCiAgICAgIGNvbnN0IGZtdD0oZWwuY3N2Rm9ybWF0LnZhbHVlPT09ImF1dG8iKSA/IChkZXRlY3RDU1ZGb3JtYXQocGFyc2VkKS5raW5kPT09IndpZGUiPyJ3aWRlIjoibG9uZyIpIDogZWwuY3N2Rm9ybWF0LnZhbHVlOwogICAgICBjb25zdCBidWlsdD0oZm10PT09IndpZGUiKT9idWlsZEZyb21XaWRlKHBhcnNlZCx0Lm5hbWUpOmJ1aWxkRnJvbUxvbmcocGFyc2VkLHQubmFtZSk7CiAgICAgIGFsbD1hbGwuY29uY2F0KGJ1aWx0LnJvd3MpOwogICAgICBlcnJzPWVycnMuY29uY2F0KGJ1aWx0LmVycm9ycyk7CiAgICB9CgogICAgY29uc3QgZGVkPXZhbGlkYXRlQW5kRGVkdXAoYWxsKTsKICAgIHJvd3NBbGw9ZGVkLnJvd3M7CiAgICBlcnJzPWVycnMuY29uY2F0KGRlZC5lcnJvcnMpOwoKICAgIHZhbGlkYXRpb24uZXJyb3JzPWVycnM7CiAgICB2YWxpZGF0aW9uLmVycm9yQ3N2PWVycnMubGVuZ3RoP2Vycm9yc1RvQ1NWKGVycnMpOm51bGw7CiAgICB2YWxpZGF0aW9uLm5vcm1hbGl6ZWRDc3Y9cm93c0FsbC5sZW5ndGg/cm93c1RvTm9ybWFsaXplZENTVihyb3dzQWxsKTpudWxsOwoKICAgIGVsLnNob3dFcnJvcnNCdG4uZGlzYWJsZWQ9ZXJycy5sZW5ndGg9PT0wOwogICAgZWwuZG93bmxvYWRFcnJvcnNCdG4uZGlzYWJsZWQ9ZXJycy5sZW5ndGg9PT0wOwogICAgZWwuZG93bmxvYWROb3JtYWxpemVkQnRuLmRpc2FibGVkPXJvd3NBbGwubGVuZ3RoPT09MDsKCiAgICBlbC52YWxpZGF0aW9uU3VtbWFyeS50ZXh0Q29udGVudD1gUm93cyBpbjogJHthbGwubGVuZ3RofSDigKIgS2VwdDogJHtyb3dzQWxsLmxlbmd0aH0g4oCiIEVycm9yczogJHtlcnJzLmxlbmd0aH1gOwogICAgZWwubWV0YVBpbGwudGV4dENvbnRlbnQ9cm93c0FsbC5sZW5ndGg/YCR7cm93c0FsbC5sZW5ndGh9IHJvd3NgOiJObyBkYXRhIjsKCiAgICByZWJ1aWxkRmlsdGVycygpOwogICAgYXBwbHlGaWx0ZXJzQW5kUmVjb21wdXRlKCk7CiAgICBlbmFibGVDb250cm9scyhyb3dzQWxsLmxlbmd0aD4wKTsKCiAgICBzZXRTdGF0dXMoIkRhdGFzZXQgYnVpbHQuIFBpY2sgZmlsdGVycy9rZXl3b3JkIGFuZCBSZW5kZXIuIik7CiAgfQoKICBmdW5jdGlvbiBlbmFibGVDb250cm9scyhlbmFibGVkKXsKICAgIGVsLmJ1c2luZXNzRmlsdGVyLmRpc2FibGVkPSFlbmFibGVkOwogICAgZWwuZGF0ZUZpbHRlci5kaXNhYmxlZD0hZW5hYmxlZDsKICAgIGVsLmtleXdvcmRTZWxlY3QuZGlzYWJsZWQ9IWVuYWJsZWQ7CgogICAgZWwuY29sb3JNb2RlLmRpc2FibGVkPSFlbmFibGVkOwogICAgZWwuYmdNb2RlLmRpc2FibGVkPSFlbmFibGVkOwogICAgZWwubGFiZWxzTW9kZS5kaXNhYmxlZD0hZW5hYmxlZDsKICAgIGVsLnZpZXdNb2RlLmRpc2FibGVkPSFlbmFibGVkOwogICAgZWwubGVnZW5kTW9kZS5kaXNhYmxlZD0hZW5hYmxlZDsKICAgIGVsLmluc3BlY3RNb2RlLmRpc2FibGVkPSFlbmFibGVkOwogICAgZWwucHJldmlld01vZGUuZGlzYWJsZWQ9IWVuYWJsZWQ7CiAgICBlbC5tYXNrTW9kZS5kaXNhYmxlZD0hZW5hYmxlZDsKCiAgICBlbC5yZW5kZXJCdG4uZGlzYWJsZWQ9IWVuYWJsZWQ7CiAgICBlbC5leHBvcnRQbmdCdG4uZGlzYWJsZWQ9IWVuYWJsZWQ7CiAgICBlbC5leHBvcnRTdmdCdG4uZGlzYWJsZWQ9IWVuYWJsZWQ7CiAgICBlbC5yZXBvcnRCdG4uZGlzYWJsZWQ9IWVuYWJsZWQ7CgogICAgZWwuc2F2ZVByb2plY3RCdG4uZGlzYWJsZWQ9IWVuYWJsZWQ7CgogICAgZWwuZHJhd1RvZ2dsZUJ0bi5kaXNhYmxlZD0hZW5hYmxlZCB8fCBlbC51bml0cy52YWx1ZSE9PSJsYXRsbmciOwogICAgdXBkYXRlRHJhd1VJKCk7CiAgfQoKICBmdW5jdGlvbiByZWJ1aWxkRmlsdGVycygpewogICAgY29uc3QgYml6PW5ldyBTZXQoKSwgZGF0ZXM9bmV3IFNldCgpLCBrd3M9bmV3IFNldCgpOwogICAgZm9yKGNvbnN0IHIgb2Ygcm93c0FsbCl7CiAgICAgIGJpei5hZGQoci5idXNpbmVzc3x8ImRlZmF1bHQiKTsKICAgICAgZGF0ZXMuYWRkKHIuZGF0ZXx8ImxhdGVzdCIpOwogICAgICBrd3MuYWRkKHIua2V5d29yZCk7CiAgICB9CiAgICBjb25zdCBiaXpBcnI9QXJyYXkuZnJvbShiaXopLnNvcnQoKGEsYik9PmEubG9jYWxlQ29tcGFyZShiKSk7CiAgICBjb25zdCBkYXRlQXJyPUFycmF5LmZyb20oZGF0ZXMpLnNvcnQoKGEsYik9PmEubG9jYWxlQ29tcGFyZShiKSk7CiAgICBjb25zdCBrd0Fycj1BcnJheS5mcm9tKGt3cykuc29ydCgoYSxiKT0+YS5sb2NhbGVDb21wYXJlKGIpKTsKCiAgICBlbC5idXNpbmVzc0ZpbHRlci5pbm5lckhUTUw9IiI7CiAgICBiaXpBcnIuZm9yRWFjaCh2PT57IGNvbnN0IG89ZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgib3B0aW9uIik7IG8udmFsdWU9djsgby50ZXh0Q29udGVudD12OyBlbC5idXNpbmVzc0ZpbHRlci5hcHBlbmRDaGlsZChvKTsgfSk7CiAgICBlbC5kYXRlRmlsdGVyLmlubmVySFRNTD0iIjsKICAgIGRhdGVBcnIuZm9yRWFjaCh2PT57IGNvbnN0IG89ZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgib3B0aW9uIik7IG8udmFsdWU9djsgby50ZXh0Q29udGVudD12OyBlbC5kYXRlRmlsdGVyLmFwcGVuZENoaWxkKG8pOyB9KTsKICAgIGVsLmtleXdvcmRTZWxlY3QuaW5uZXJIVE1MPSIiOwogICAga3dBcnIuZm9yRWFjaCh2PT57IGNvbnN0IG89ZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgib3B0aW9uIik7IG8udmFsdWU9djsgby50ZXh0Q29udGVudD12OyBlbC5rZXl3b3JkU2VsZWN0LmFwcGVuZENoaWxkKG8pOyB9KTsKCiAgICBpZihiaXpBcnIubGVuZ3RoKSBlbC5idXNpbmVzc0ZpbHRlci52YWx1ZT1iaXpBcnJbMF07CiAgICBpZihkYXRlQXJyLmxlbmd0aCkgZWwuZGF0ZUZpbHRlci52YWx1ZT1kYXRlQXJyW2RhdGVBcnIubGVuZ3RoLTFdOwogICAgaWYoa3dBcnIubGVuZ3RoKSBlbC5rZXl3b3JkU2VsZWN0LnZhbHVlPWt3QXJyWzBdOwogIH0KCiAgZnVuY3Rpb24gYXBwbHlGaWx0ZXJzQW5kUmVjb21wdXRlKCl7CiAgICBjb25zdCBiaXo9ZWwuYnVzaW5lc3NGaWx0ZXIudmFsdWV8fCJkZWZhdWx0IjsKICAgIGNvbnN0IGRhdGU9ZWwuZGF0ZUZpbHRlci52YWx1ZXx8ImxhdGVzdCI7CiAgICByb3dzRmlsdGVyZWQ9cm93c0FsbC5maWx0ZXIocj0+KHIuYnVzaW5lc3N8fCJkZWZhdWx0Iik9PT1iaXogJiYgKHIuZGF0ZXx8ImxhdGVzdCIpPT09ZGF0ZSk7CgogICAgYnlLZXl3b3JkPW5ldyBNYXAoKTsKICAgIGZvcihjb25zdCByIG9mIHJvd3NGaWx0ZXJlZCl7CiAgICAgIGlmKCFieUtleXdvcmQuaGFzKHIua2V5d29yZCkpIGJ5S2V5d29yZC5zZXQoci5rZXl3b3JkLFtdKTsKICAgICAgYnlLZXl3b3JkLmdldChyLmtleXdvcmQpLnB1c2gocik7CiAgICB9CiAgICBjb21wdXRlS2V5d29yZFN0YXRzKCk7CiAgICBjb21wdXRlTG9jYXRpb25TdGF0cygpOwogICAgY29tcHV0ZU9wcG9ydHVuaXRpZXMoKTsKICAgIHJlbmRlclN0YXRzVGFibGUoKTsKICAgIHJlbmRlckxvY2F0aW9uc1RhYmxlKCk7CiAgICByZW5kZXJPcHBUYWJsZSgpOwogICAgcmVuZGVyU2VsZWN0ZWRTdGF0cygpOwoKICAgIGVsLmNvcHlTdGF0c0J0bi5kaXNhYmxlZD0hc3RhdHNDc3Y7CiAgICBlbC5kb3dubG9hZFN0YXRzQnRuLmRpc2FibGVkPSFzdGF0c0NzdjsKICAgIGVsLmNvcHlMb2NCdG4uZGlzYWJsZWQ9IWxvY0NzdjsKICAgIGVsLmRvd25sb2FkTG9jQnRuLmRpc2FibGVkPSFsb2NDc3Y7CiAgICBlbC5jb3B5T3BwQnRuLmRpc2FibGVkPSFvcHBDc3Y7CiAgICBlbC5kb3dubG9hZE9wcEJ0bi5kaXNhYmxlZD0hb3BwQ3N2OwogIH0KCiAgLy8gU3RhdHMKICBmdW5jdGlvbiBtZWRpYW5PZihzb3J0ZWQpewogICAgY29uc3Qgbj1zb3J0ZWQubGVuZ3RoOyBpZighbikgcmV0dXJuIE5hTjsKICAgIGNvbnN0IG1pZD1NYXRoLmZsb29yKG4vMik7CiAgICByZXR1cm4gbiUyP3NvcnRlZFttaWRdOihzb3J0ZWRbbWlkLTFdK3NvcnRlZFttaWRdKS8yOwogIH0KICBmdW5jdGlvbiBjb21wdXRlS2V5d29yZFN0YXRzKCl7CiAgICBrZXl3b3JkU3RhdHM9W107CiAgICBmb3IoY29uc3QgW2t3LHB0c10gb2YgYnlLZXl3b3JkLmVudHJpZXMoKSl7CiAgICAgIGNvbnN0IHJhbmtzPXB0cy5tYXAocD0+cC5yYW5rKS5zbGljZSgpLnNvcnQoKGEsYik9PmEtYik7CiAgICAgIGNvbnN0IGF2Zz1yYW5rcy5yZWR1Y2UoKGEsYik9PmErYiwwKS8ocmFua3MubGVuZ3RofHwxKTsKICAgICAgY29uc3QgbWVkaWFuPW1lZGlhbk9mKHJhbmtzKTsKICAgICAgbGV0IGJlc3Q9SW5maW5pdHksd29yc3Q9LUluZmluaXR5LGJlc3RMb2M9IiIsd29yc3RMb2M9IiI7CiAgICAgIGxldCB0Mz0wLHQxMD0wLHQyMD0wOwogICAgICBsZXQgdm9sU3VtPTAsdm9sQ291bnQ9MDsKICAgICAgZm9yKGNvbnN0IHAgb2YgcHRzKXsKICAgICAgICBpZihwLnJhbms8YmVzdCl7IGJlc3Q9cC5yYW5rOyBiZXN0TG9jPXAubG9jYXRpb247IH0KICAgICAgICBpZihwLnJhbms+d29yc3QpeyB3b3JzdD1wLnJhbms7IHdvcnN0TG9jPXAubG9jYXRpb247IH0KICAgICAgICBpZihwLnJhbms8PTMpIHQzKys7CiAgICAgICAgaWYocC5yYW5rPD0xMCkgdDEwKys7CiAgICAgICAgaWYocC5yYW5rPD0yMCkgdDIwKys7CiAgICAgICAgaWYocC52b2x1bWUhPW51bGwgJiYgTnVtYmVyLmlzRmluaXRlKHAudm9sdW1lKSl7IHZvbFN1bSs9cC52b2x1bWU7IHZvbENvdW50Kys7IH0KICAgICAgfQogICAgICBjb25zdCB2b2x1bWU9dm9sQ291bnQ/KHZvbFN1bS92b2xDb3VudCk6MDsKICAgICAga2V5d29yZFN0YXRzLnB1c2goewogICAgICAgIGtleXdvcmQ6IGt3LCBjb3VudDogcHRzLmxlbmd0aCwgYXZnLCBtZWRpYW4sIGJlc3QsIHdvcnN0LCBiZXN0TG9jLCB3b3JzdExvYywKICAgICAgICB0b3AzOiAodDMvcHRzLmxlbmd0aCkqMTAwLCB0b3AxMDoodDEwL3B0cy5sZW5ndGgpKjEwMCwgdG9wMjA6KHQyMC9wdHMubGVuZ3RoKSoxMDAsIHZvbHVtZQogICAgICB9KTsKICAgIH0KICAgIHN0YXRzQ3N2ID0ga2V5d29yZFN0YXRzLmxlbmd0aCA/ICgoKSA9PiB7CiAgICAgIGNvbnN0IGxpbmVzPVtbImtleXdvcmQiLCJjb3VudCIsImF2ZyIsIm1lZGlhbiIsImJlc3QiLCJ3b3JzdCIsImJlc3RfbG9jYXRpb24iLCJ3b3JzdF9sb2NhdGlvbiIsInRvcDNfcGN0IiwidG9wMTBfcGN0IiwidG9wMjBfcGN0Iiwidm9sdW1lIl0uam9pbigiLCIpXTsKICAgICAgZm9yKGNvbnN0IHMgb2Yga2V5d29yZFN0YXRzKXsKICAgICAgICBsaW5lcy5wdXNoKFsKICAgICAgICAgIGNzdkVzY2FwZShzLmtleXdvcmQpLCBzLmNvdW50LCBzLmF2Zy50b0ZpeGVkKDIpLCBzLm1lZGlhbi50b0ZpeGVkKDIpLCBzLmJlc3QsIHMud29yc3QsCiAgICAgICAgICBjc3ZFc2NhcGUocy5iZXN0TG9jKSwgY3N2RXNjYXBlKHMud29yc3RMb2MpLAogICAgICAgICAgcy50b3AzLnRvRml4ZWQoMSksIHMudG9wMTAudG9GaXhlZCgxKSwgcy50b3AyMC50b0ZpeGVkKDEpLCBzLnZvbHVtZS50b0ZpeGVkKDIpCiAgICAgICAgXS5qb2luKCIsIikpOwogICAgICB9CiAgICAgIHJldHVybiBsaW5lcy5qb2luKCJcbiIpOwogICAgfSkoKSA6IG51bGw7CiAgfQoKICBmdW5jdGlvbiBjb21wdXRlTG9jYXRpb25TdGF0cygpewogICAgY29uc3QgbWFwPW5ldyBNYXAoKTsgLy8gbG9jIC0+IHtyYW5rczpbXSwgdDMsdDEwLHQyMCwgd29yc3RSYW5rLCB3b3JzdEtleXdvcmR9CiAgICBmb3IoY29uc3QgciBvZiByb3dzRmlsdGVyZWQpewogICAgICBpZighbWFwLmhhcyhyLmxvY2F0aW9uKSkgbWFwLnNldChyLmxvY2F0aW9uLHtyYW5rczpbXSx0MzowLHQxMDowLHQyMDowLHdvcnN0UmFuazotSW5maW5pdHksd29yc3RLZXl3b3JkOiIifSk7CiAgICAgIGNvbnN0IHY9bWFwLmdldChyLmxvY2F0aW9uKTsKICAgICAgdi5yYW5rcy5wdXNoKHIucmFuayk7CiAgICAgIGlmKHIucmFuazw9Mykgdi50MysrOwogICAgICBpZihyLnJhbms8PTEwKSB2LnQxMCsrOwogICAgICBpZihyLnJhbms8PTIwKSB2LnQyMCsrOwogICAgICBpZihyLnJhbms+di53b3JzdFJhbmspeyB2LndvcnN0UmFuaz1yLnJhbms7IHYud29yc3RLZXl3b3JkPXIua2V5d29yZDsgfQogICAgfQogICAgbG9jYXRpb25TdGF0cz1bXTsKICAgIGZvcihjb25zdCBbbG9jLHZdIG9mIG1hcC5lbnRyaWVzKCkpewogICAgICBjb25zdCByYW5rcz12LnJhbmtzLnNsaWNlKCkuc29ydCgoYSxiKT0+YS1iKTsKICAgICAgY29uc3QgYXZnPXJhbmtzLnJlZHVjZSgoYSxiKT0+YStiLDApLyhyYW5rcy5sZW5ndGh8fDEpOwogICAgICBsb2NhdGlvblN0YXRzLnB1c2goewogICAgICAgIGxvY2F0aW9uOiBsb2MsIGNvdW50OiByYW5rcy5sZW5ndGgsIGF2ZywKICAgICAgICB0b3AzOiAodi50My9yYW5rcy5sZW5ndGgpKjEwMCwgdG9wMTA6KHYudDEwL3JhbmtzLmxlbmd0aCkqMTAwLCB0b3AyMDoodi50MjAvcmFua3MubGVuZ3RoKSoxMDAsCiAgICAgICAgd29yc3RLZXl3b3JkOiB2LndvcnN0S2V5d29yZAogICAgICB9KTsKICAgIH0KICAgIGxvY0NzdiA9IGxvY2F0aW9uU3RhdHMubGVuZ3RoID8gKCgpID0+IHsKICAgICAgY29uc3QgbGluZXM9W1sibG9jYXRpb24iLCJjb3VudCIsImF2ZyIsInRvcDNfcGN0IiwidG9wMTBfcGN0IiwidG9wMjBfcGN0Iiwid29yc3Rfa2V5d29yZCJdLmpvaW4oIiwiKV07CiAgICAgIGZvcihjb25zdCBzIG9mIGxvY2F0aW9uU3RhdHMpewogICAgICAgIGxpbmVzLnB1c2goW2NzdkVzY2FwZShzLmxvY2F0aW9uKSwgcy5jb3VudCwgcy5hdmcudG9GaXhlZCgyKSwgcy50b3AzLnRvRml4ZWQoMSksIHMudG9wMTAudG9GaXhlZCgxKSwgcy50b3AyMC50b0ZpeGVkKDEpLCBjc3ZFc2NhcGUocy53b3JzdEtleXdvcmQpXS5qb2luKCIsIikpOwogICAgICB9CiAgICAgIHJldHVybiBsaW5lcy5qb2luKCJcbiIpOwogICAgfSkoKSA6IG51bGw7CiAgfQoKICBmdW5jdGlvbiBjb21wdXRlT3Bwb3J0dW5pdGllcygpewogICAgY29uc3QgZ29hbD1lbC5vcHBNb2RlLnZhbHVlOwogICAgY29uc3QgbWluQ291bnQ9Y2xhbXAoTnVtYmVyKGVsLm9wcE1pbkNvdW50LnZhbHVlKXx8MSwxLDk5OTk5KTsKICAgIGNvbnN0IHRhcmdldHM9e3RvcDM6Myx0b3AxMDoxMCx0b3AyMDoyMH1bZ29hbF18fDM7CiAgICBjb25zdCBqdXN0TG93PXRhcmdldHMrMSwganVzdEhpZ2g9dGFyZ2V0cyoyOwoKICAgIGNvbnN0IG9wcHM9W107CiAgICBmb3IoY29uc3QgcyBvZiBrZXl3b3JkU3RhdHMpewogICAgICBpZihzLmNvdW50PG1pbkNvdW50KSBjb250aW51ZTsKICAgICAgY29uc3QgdG9wUGN0ID0gKHRhcmdldHM9PT0zKT9zLnRvcDM6KHRhcmdldHM9PT0xMCk/cy50b3AxMDpzLnRvcDIwOwogICAgICBpZih0b3BQY3Q+PTYwKSBjb250aW51ZTsKCiAgICAgIGxldCBtaXNzPTA7CiAgICAgIGNvbnN0IHB0cz1ieUtleXdvcmQuZ2V0KHMua2V5d29yZCl8fFtdOwogICAgICBmb3IoY29uc3QgcCBvZiBwdHMpIGlmKHAucmFuaz49anVzdExvdyAmJiBwLnJhbms8PWp1c3RIaWdoKSBtaXNzKys7CiAgICAgIGNvbnN0IG1pc3NQY3Q9KG1pc3MvKHB0cy5sZW5ndGh8fDEpKSoxMDA7CgogICAgICBjb25zdCB2b2wgPSBzLnZvbHVtZT4wP3Mudm9sdW1lOjE7CiAgICAgIGNvbnN0IGdhcD1NYXRoLm1heCgwLjEsIChzLmF2Zy10YXJnZXRzKSk7CiAgICAgIGNvbnN0IHNjb3JlPXZvbCoobWlzc1BjdC8xMDArMC4wNSkqKDEvZ2FwKTsKCiAgICAgIG9wcHMucHVzaCh7a2V5d29yZDpzLmtleXdvcmQsIGF2ZzpzLmF2ZywgdG9wUGN0LCBtaXNzUGN0LCB2b2w6KHMudm9sdW1lPjA/cy52b2x1bWU6MCksIHNjb3JlfSk7CiAgICB9CiAgICBvcHBzLnNvcnQoKGEsYik9PmIuc2NvcmUtYS5zY29yZSk7CiAgICBlbC5vcHBCb2R5Ll9vcHBzID0gb3BwczsKCiAgICBvcHBDc3YgPSBvcHBzLmxlbmd0aCA/ICgoKSA9PiB7CiAgICAgIGNvbnN0IGxpbmVzPVtbImtleXdvcmQiLCJhdmdfcmFuayIsInRvcF9wY3QiLCJqdXN0X21pc3NfcGN0Iiwidm9sdW1lIiwic2NvcmUiXS5qb2luKCIsIildOwogICAgICBmb3IoY29uc3QgbyBvZiBvcHBzKXsKICAgICAgICBsaW5lcy5wdXNoKFtjc3ZFc2NhcGUoby5rZXl3b3JkKSwgby5hdmcudG9GaXhlZCgyKSwgby50b3BQY3QudG9GaXhlZCgxKSwgby5taXNzUGN0LnRvRml4ZWQoMSksIG8udm9sP28udm9sLnRvRml4ZWQoMik6IiIsIG8uc2NvcmUudG9GaXhlZCg0KV0uam9pbigiLCIpKTsKICAgICAgfQogICAgICByZXR1cm4gbGluZXMuam9pbigiXG4iKTsKICAgIH0pKCkgOiBudWxsOwogIH0KCiAgZnVuY3Rpb24gcmVuZGVyU2VsZWN0ZWRTdGF0cygpewogICAgY29uc3Qga3c9ZWwua2V5d29yZFNlbGVjdC52YWx1ZTsKICAgIGNvbnN0IHM9a2V5d29yZFN0YXRzLmZpbmQoeD0+eC5rZXl3b3JkPT09a3cpOwogICAgaWYoIXMpeyBlbC5zZWxlY3RlZFN0YXRzLnRleHRDb250ZW50PSJObyBkYXRhLiI7IHJldHVybjsgfQogICAgZWwuc2VsZWN0ZWRTdGF0cy50ZXh0Q29udGVudCA9CmBLZXl3b3JkOiAke3Mua2V5d29yZH0KQ291bnQ6ICR7cy5jb3VudH0KQXZnOiAke3MuYXZnLnRvRml4ZWQoMil9IOKAoiBNZWRpYW46ICR7cy5tZWRpYW4udG9GaXhlZCgyKX0KQmVzdDogJHtzLmJlc3R9ICgke3MuYmVzdExvY30pIOKAoiBXb3JzdDogJHtzLndvcnN0fSAoJHtzLndvcnN0TG9jfSkKVG9wMzogJHtzLnRvcDMudG9GaXhlZCgxKX0lIOKAoiBUb3AxMDogJHtzLnRvcDEwLnRvRml4ZWQoMSl9JSDigKIgVG9wMjA6ICR7cy50b3AyMC50b0ZpeGVkKDEpfSUKVm9sdW1lOiAke3Mudm9sdW1lPyBzLnZvbHVtZS50b0ZpeGVkKDIpIDogIuKAlCJ9YDsKICB9CgogIGZ1bmN0aW9uIHJlbmRlclN0YXRzVGFibGUoKXsKICAgIGNvbnN0IHE9KGVsLnN0YXRzRmlsdGVyLnZhbHVlfHwiIikudHJpbSgpLnRvTG93ZXJDYXNlKCk7CiAgICBjb25zdCBmaWx0ZXJlZD1xP2tleXdvcmRTdGF0cy5maWx0ZXIocz0+cy5rZXl3b3JkLnRvTG93ZXJDYXNlKCkuaW5jbHVkZXMocSkpOmtleXdvcmRTdGF0cy5zbGljZSgpOwogICAgY29uc3QgbW9kZT1lbC5zdGF0c1NvcnQudmFsdWU7CiAgICBjb25zdCBhcnI9ZmlsdGVyZWQuc2xpY2UoKTsKICAgIGlmKG1vZGU9PT0iYXZnIikgYXJyLnNvcnQoKGEsYik9PmEuYXZnLWIuYXZnKTsKICAgIGVsc2UgaWYobW9kZT09PSJ0b3AzIikgYXJyLnNvcnQoKGEsYik9PmIudG9wMy1hLnRvcDMpOwogICAgZWxzZSBpZihtb2RlPT09ImNvdW50IikgYXJyLnNvcnQoKGEsYik9PmIuY291bnQtYS5jb3VudCk7CiAgICBlbHNlIGlmKG1vZGU9PT0iYmVzdCIpIGFyci5zb3J0KChhLGIpPT5hLmJlc3QtYi5iZXN0KTsKCiAgICBlbC5zdGF0c0JvZHkuaW5uZXJIVE1MPSIiOwogICAgZm9yKGNvbnN0IHMgb2YgYXJyKXsKICAgICAgY29uc3QgdHI9ZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgidHIiKTsKICAgICAgdHIuc3R5bGUuY3Vyc29yPSJwb2ludGVyIjsKICAgICAgdHIuaW5uZXJIVE1MPWA8dGQ+JHtlc2NhcGVIVE1MKHMua2V5d29yZCl9PC90ZD48dGQ+JHtzLmNvdW50fTwvdGQ+PHRkPiR7cy5hdmcudG9GaXhlZCgyKX08L3RkPjx0ZD4ke3MubWVkaWFuLnRvRml4ZWQoMil9PC90ZD48dGQ+JHtzLmJlc3R9PC90ZD48dGQ+JHtzLndvcnN0fTwvdGQ+PHRkPiR7cy50b3AzLnRvRml4ZWQoMSl9PC90ZD48dGQ+JHtzLnRvcDEwLnRvRml4ZWQoMSl9PC90ZD48dGQ+JHtzLnRvcDIwLnRvRml4ZWQoMSl9PC90ZD5gOwogICAgICB0ci5hZGRFdmVudExpc3RlbmVyKCJjbGljayIsKCk9PnsgZWwua2V5d29yZFNlbGVjdC52YWx1ZT1zLmtleXdvcmQ7IHJlbmRlcigpOyB9KTsKICAgICAgZWwuc3RhdHNCb2R5LmFwcGVuZENoaWxkKHRyKTsKICAgIH0KICB9CgogIGZ1bmN0aW9uIHJlbmRlckxvY2F0aW9uc1RhYmxlKCl7CiAgICBjb25zdCBxPShlbC5sb2NGaWx0ZXIudmFsdWV8fCIiKS50cmltKCkudG9Mb3dlckNhc2UoKTsKICAgIGNvbnN0IGZpbHRlcmVkPXE/bG9jYXRpb25TdGF0cy5maWx0ZXIocz0+cy5sb2NhdGlvbi50b0xvd2VyQ2FzZSgpLmluY2x1ZGVzKHEpKTpsb2NhdGlvblN0YXRzLnNsaWNlKCk7CiAgICBjb25zdCBtb2RlPWVsLmxvY1NvcnQudmFsdWU7CiAgICBjb25zdCBhcnI9ZmlsdGVyZWQuc2xpY2UoKTsKICAgIGlmKG1vZGU9PT0iYXZnIikgYXJyLnNvcnQoKGEsYik9PmEuYXZnLWIuYXZnKTsKICAgIGVsc2UgaWYobW9kZT09PSJ0b3AzIikgYXJyLnNvcnQoKGEsYik9PmIudG9wMy1hLnRvcDMpOwogICAgZWxzZSBpZihtb2RlPT09InRvcDEwIikgYXJyLnNvcnQoKGEsYik9PmIudG9wMTAtYS50b3AxMCk7CiAgICBlbHNlIGlmKG1vZGU9PT0iY291bnQiKSBhcnIuc29ydCgoYSxiKT0+Yi5jb3VudC1hLmNvdW50KTsKCiAgICBlbC5sb2NCb2R5LmlubmVySFRNTD0iIjsKICAgIGZvcihjb25zdCBzIG9mIGFycil7CiAgICAgIGNvbnN0IHRyPWRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoInRyIik7CiAgICAgIHRyLmlubmVySFRNTD1gPHRkPiR7ZXNjYXBlSFRNTChzLmxvY2F0aW9uKX08L3RkPjx0ZD4ke3MuY291bnR9PC90ZD48dGQ+JHtzLmF2Zy50b0ZpeGVkKDIpfTwvdGQ+PHRkPiR7cy50b3AzLnRvRml4ZWQoMSl9PC90ZD48dGQ+JHtzLnRvcDEwLnRvRml4ZWQoMSl9PC90ZD48dGQ+JHtzLnRvcDIwLnRvRml4ZWQoMSl9PC90ZD48dGQ+JHtlc2NhcGVIVE1MKHMud29yc3RLZXl3b3JkKX08L3RkPmA7CiAgICAgIGVsLmxvY0JvZHkuYXBwZW5kQ2hpbGQodHIpOwogICAgfQogIH0KCiAgZnVuY3Rpb24gcmVuZGVyT3BwVGFibGUoKXsKICAgIGNvbnN0IG9wcHM9ZWwub3BwQm9keS5fb3BwcyB8fCBbXTsKICAgIGVsLm9wcEJvZHkuaW5uZXJIVE1MPSIiOwogICAgZm9yKGNvbnN0IG8gb2Ygb3Bwcy5zbGljZSgwLDEwMCkpewogICAgICBjb25zdCB0cj1kb2N1bWVudC5jcmVhdGVFbGVtZW50KCJ0ciIpOwogICAgICB0ci5zdHlsZS5jdXJzb3I9InBvaW50ZXIiOwogICAgICB0ci5pbm5lckhUTUw9YDx0ZD4ke2VzY2FwZUhUTUwoby5rZXl3b3JkKX08L3RkPjx0ZD4ke28uYXZnLnRvRml4ZWQoMil9PC90ZD48dGQ+JHtvLnRvcFBjdC50b0ZpeGVkKDEpfTwvdGQ+PHRkPiR7by5taXNzUGN0LnRvRml4ZWQoMSl9PC90ZD48dGQ+JHtvLnZvbD9vLnZvbC50b0ZpeGVkKDIpOiIifTwvdGQ+PHRkPiR7by5zY29yZS50b0ZpeGVkKDMpfTwvdGQ+YDsKICAgICAgdHIuYWRkRXZlbnRMaXN0ZW5lcigiY2xpY2siLCgpPT57IGVsLmtleXdvcmRTZWxlY3QudmFsdWU9by5rZXl3b3JkOyByZW5kZXIoKTsgfSk7CiAgICAgIGVsLm9wcEJvZHkuYXBwZW5kQ2hpbGQodHIpOwogICAgfQogIH0KCiAgLy8gcmVuZGVyIG9yY2hlc3RyYXRpb24KICBmdW5jdGlvbiByZW5kZXIoKXsKICAgIGNvbnN0IGt3PWVsLmtleXdvcmRTZWxlY3QudmFsdWV8fCIiOwogICAgY29uc3QgYml6PWVsLmJ1c2luZXNzRmlsdGVyLnZhbHVlfHwiZGVmYXVsdCI7CiAgICBjb25zdCBkYXRlPWVsLmRhdGVGaWx0ZXIudmFsdWV8fCJsYXRlc3QiOwogICAgY29uc3QgcG9pbnRzPWJ5S2V5d29yZC5nZXQoa3cpfHxbXTsKCiAgICBkcmF3QmFja2dyb3VuZChlbC5iZ01vZGUudmFsdWUpOwogICAgaWYoIXBvaW50cy5sZW5ndGgpeyBsYXN0UmVuZGVyQkJveD1udWxsOyBlbC5ob3ZlclJlYWRvdXQudGV4dENvbnRlbnQ9IkhvdmVyOiDigJQiOyB1cGRhdGVEcmF3VUkoKTsgcmV0dXJuOyB9CgogICAgY29uc3QgYmJveD1jb21wdXRlQkJveChwb2ludHMpOwogICAgbGFzdFJlbmRlckJCb3g9YmJveDsKCiAgICBkcmF3R2VvSlNPTk92ZXJsYXkoYmJveCk7CiAgICBkcmF3QnVzaW5lc3NBbmRSaW5ncyhiYm94KTsKCiAgICBjb25zdCBtYXhSYW5rPWNsYW1wKE51bWJlcihlbC5tYXhSYW5rLnZhbHVlKXx8MjAsMiw5OTkpOwogICAgY29uc3QgZ3JpZD1jbGFtcChOdW1iZXIoZWwuZ3JpZFNpemUudmFsdWUpfHw0NSwxMCwyMjApOwogICAgY29uc3QgcG93ZXI9Y2xhbXAoTnVtYmVyKGVsLnBvd2VyLnZhbHVlKXx8MiwwLjUsMTApOwogICAgY29uc3QgcmFkaXVzUHg9Y2xhbXAoTnVtYmVyKGVsLnJhZGl1c1B4LnZhbHVlKXx8MjgwLDEwLDUwMDApOwogICAgY29uc3Qgc2lnbWE9Y2xhbXAoTnVtYmVyKGVsLmdhdXNzU2lnbWEudmFsdWUpfHwyMjAsMTAsNTAwMCk7CgogICAgY29uc3Qgdmlldz1lbC52aWV3TW9kZS52YWx1ZTsKICAgIGNvbnN0IHNob3dMYWJlbHM9ZWwubGFiZWxzTW9kZS52YWx1ZT09PSJvbiI7CgogICAgaWYodmlldz09PSJoZWF0K3BvaW50cyIgfHwgdmlldz09PSJoZWF0Iil7CiAgICAgIGRyYXdIZWF0bWFwKHBvaW50cyxiYm94LHtncmlkLG1heFJhbmsscG93ZXIscmFkaXVzUHgsc2lnbWF9KTsKICAgIH0KICAgIGlmKHZpZXc9PT0iaGVhdCtwb2ludHMiIHx8IHZpZXc9PT0icG9pbnRzIil7CiAgICAgIGRyYXdQb2ludHMocG9pbnRzLGJib3gse21heFJhbmssc2hvd0xhYmVsc30pOwogICAgfQoKICAgIC8vIHBpbnMgb3ZlcmxheQogICAgZHJhd1BpbnMoYmJveCwga3csIGJpeiwgZGF0ZSk7CgogICAgZHJhd0RyYXdpbmdPdmVybGF5KGJib3gpOwogICAgZHJhd1RpdGxlKGt3LGJpeixkYXRlKTsKICAgIGRyYXdMZWdlbmQobWF4UmFuayk7CgogICAgcmVuZGVyU2VsZWN0ZWRTdGF0cygpOwogICAgdXBkYXRlUGluc1BpbGwoKTsKICAgIHVwZGF0ZURyYXdVSSgpOwogIH0KCiAgZnVuY3Rpb24gZHJhd1BpbnMoYmJveCwga3csIGJpeiwgZGF0ZSl7CiAgICBpZihlbC5pbnNwZWN0TW9kZS52YWx1ZSE9PSJvbiIpIHJldHVybjsKICAgIGNvbnN0IGJnPWVsLmJnTW9kZS52YWx1ZTsKICAgIGNvbnN0IHN0cm9rZT1iZz09PSJsaWdodCI/InJnYmEoMCwwLDAsMC4yNSkiOiJyZ2JhKDI1NSwyNTUsMjU1LDAuMjgpIjsKICAgIGNvbnN0IHRleHRDb2xvcj1iZz09PSJsaWdodCI/IiMxMTEiOiIjZmZmIjsKCiAgICBjdHguc2F2ZSgpOwogICAgZm9yKGNvbnN0IHBpbiBvZiBwaW5zKXsKICAgICAgaWYocGluLmtleXdvcmQhPT1rdyB8fCBwaW4uYnVzaW5lc3MhPT1iaXogfHwgcGluLmRhdGUhPT1kYXRlKSBjb250aW51ZTsKICAgICAgY29uc3QgYz13b3JsZFRvQ2FudmFzKHBpbi54LHBpbi55LGJib3gpOwogICAgICBjdHguYmVnaW5QYXRoKCk7IGN0eC5hcmMoYy5jeCxjLmN5LDcsMCxNYXRoLlBJKjIpOwogICAgICBjdHguZmlsbFN0eWxlPSJyZ2JhKDEwLDExMCwyNTUsMC44NSkiOyBjdHguZmlsbCgpOwogICAgICBjdHgubGluZVdpZHRoPTI7IGN0eC5zdHJva2VTdHlsZT1zdHJva2U7IGN0eC5zdHJva2UoKTsKCiAgICAgIGNvbnN0IGxhYmVsPWAke3Bpbi5wcmVkLnRvRml4ZWQoMil9IOKAoiAke3Bpbi5uZWFyZXN0fHwiIn1gOwogICAgICBjdHguZm9udD0iMTJweCBzeXN0ZW0tdWksLWFwcGxlLXN5c3RlbSxTZWdvZSBVSSxSb2JvdG8sQXJpYWwiOwogICAgICBjb25zdCBwYWQ9NiwgdHc9Y3R4Lm1lYXN1cmVUZXh0KGxhYmVsKS53aWR0aDsKICAgICAgY29uc3QgYng9Yy5jeCsxMiwgYnk9Yy5jeSwgYnc9dHcrcGFkKjIsIGJoPTIwOwogICAgICBjdHguZmlsbFN0eWxlPWJnPT09ImxpZ2h0Ij8icmdiYSgyNTUsMjU1LDI1NSwwLjg1KSI6InJnYmEoMCwwLDAsMC42MCkiOwogICAgICBjdHguc3Ryb2tlU3R5bGU9c3Ryb2tlOyBjdHgubGluZVdpZHRoPTE7CiAgICAgIHJvdW5kUmVjdChjdHgsYngsYnktYmgvMixidyxiaCw4KTsgY3R4LmZpbGwoKTsgY3R4LnN0cm9rZSgpOwogICAgICBjdHguZmlsbFN0eWxlPXRleHRDb2xvcjsgY3R4LnRleHRBbGlnbj0ibGVmdCI7IGN0eC50ZXh0QmFzZWxpbmU9Im1pZGRsZSI7CiAgICAgIGN0eC5maWxsVGV4dChsYWJlbCxieCtwYWQsYnkpOwogICAgfQogICAgLy8gaG92ZXIgdG9vbHRpcAogICAgaWYoaG92ZXJTdGF0ZSAmJiBob3ZlclN0YXRlLnByZWQhPW51bGwpewogICAgICBjb25zdCBsYWJlbD1gcHJlZCAke2hvdmVyU3RhdGUucHJlZC50b0ZpeGVkKDIpfSDigKIgJHtob3ZlclN0YXRlLm5lYXJlc3R8fCLigJQifWA7CiAgICAgIGN0eC5mb250PSIxMnB4IHN5c3RlbS11aSwtYXBwbGUtc3lzdGVtLFNlZ29lIFVJLFJvYm90byxBcmlhbCI7CiAgICAgIGNvbnN0IHBhZD02LCB0dz1jdHgubWVhc3VyZVRleHQobGFiZWwpLndpZHRoOwogICAgICBjb25zdCBieD1jbGFtcChob3ZlclN0YXRlLmN4KzE0LDEwLGVsLmNhbnZhcy53aWR0aC0odHcrcGFkKjIpLTEwKTsKICAgICAgY29uc3QgYnk9Y2xhbXAoaG92ZXJTdGF0ZS5jeS0xOCwxMCxlbC5jYW52YXMuaGVpZ2h0LTMwKTsKICAgICAgY29uc3QgYnc9dHcrcGFkKjIsIGJoPTIwOwogICAgICBjdHguZmlsbFN0eWxlPWJnPT09ImxpZ2h0Ij8icmdiYSgyNTUsMjU1LDI1NSwwLjkyKSI6InJnYmEoMCwwLDAsMC43MikiOwogICAgICBjdHguc3Ryb2tlU3R5bGU9c3Ryb2tlOyBjdHgubGluZVdpZHRoPTE7CiAgICAgIHJvdW5kUmVjdChjdHgsYngsYnksYncsYmgsOCk7IGN0eC5maWxsKCk7IGN0eC5zdHJva2UoKTsKICAgICAgY3R4LmZpbGxTdHlsZT10ZXh0Q29sb3I7IGN0eC50ZXh0QWxpZ249ImxlZnQiOyBjdHgudGV4dEJhc2VsaW5lPSJtaWRkbGUiOwogICAgICBjdHguZmlsbFRleHQobGFiZWwsYngrcGFkLGJ5K2JoLzIpOwogICAgfQogICAgY3R4LnJlc3RvcmUoKTsKICB9CgogIGZ1bmN0aW9uIHNjaGVkdWxlUmVuZGVyKCl7CiAgICBsYXN0SW50ZXJhY3Rpb25BdD1ub3coKTsKICAgIGlmKGVsLnByZXZpZXdNb2RlLnZhbHVlIT09Im9uIil7IHJlbmRlcigpOyByZXR1cm47IH0KICAgIGNvbnN0IG9yaWc9ZWwuZ3JpZFNpemUudmFsdWU7CiAgICBjb25zdCBnPU51bWJlcihvcmlnKXx8NDU7CiAgICBjb25zdCBwcmV2aWV3PU1hdGgubWluKDM1LGcpOwogICAgZWwuZ3JpZFNpemUudmFsdWU9U3RyaW5nKHByZXZpZXcpOwogICAgcmVuZGVyKCk7CiAgICBlbC5ncmlkU2l6ZS52YWx1ZT1vcmlnOwogICAgaWYocmVuZGVyVGltZXIpIHdpbmRvdy5jbGVhclRpbWVvdXQocmVuZGVyVGltZXIpOwogICAgcmVuZGVyVGltZXI9d2luZG93LnNldFRpbWVvdXQoKCk9PnsgaWYobm93KCktbGFzdEludGVyYWN0aW9uQXQ+PTI2MCkgcmVuZGVyKCk7IH0sMzIwKTsKICB9CgogIC8vIEhvdmVyIGluc3BlY3RvcgogIGZ1bmN0aW9uIG9uQ2FudmFzTW92ZShldil7CiAgICBpZihlbC5pbnNwZWN0TW9kZS52YWx1ZSE9PSJvbiIgfHwgIWxhc3RSZW5kZXJCQm94KXsKICAgICAgaG92ZXJTdGF0ZT1udWxsOyBlbC5ob3ZlclJlYWRvdXQudGV4dENvbnRlbnQ9IkhvdmVyOiDigJQiOwogICAgICBpZihkcmF3QWN0aXZlKXsgZHJhd0hvdmVyPW51bGw7IHNuYXBIb3Zlcj1udWxsOyB9CiAgICAgIHJldHVybjsKICAgIH0KICAgIGNvbnN0IGt3PWVsLmtleXdvcmRTZWxlY3QudmFsdWV8fCIiOwogICAgY29uc3QgcG9pbnRzPWJ5S2V5d29yZC5nZXQoa3cpfHxbXTsKICAgIGlmKCFwb2ludHMubGVuZ3RoKSByZXR1cm47CgogICAgY29uc3QgcmVjdD1lbC5jYW52YXMuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCk7CiAgICBjb25zdCBjeD0oKGV2LmNsaWVudFgtcmVjdC5sZWZ0KS9yZWN0LndpZHRoKSplbC5jYW52YXMud2lkdGg7CiAgICBjb25zdCBjeT0oKGV2LmNsaWVudFktcmVjdC50b3ApL3JlY3QuaGVpZ2h0KSplbC5jYW52YXMuaGVpZ2h0OwogICAgY29uc3Qgdz1jYW52YXNUb1dvcmxkKGN4LGN5LGxhc3RSZW5kZXJCQm94KTsKCiAgICBjb25zdCBwb3dlcj1jbGFtcChOdW1iZXIoZWwucG93ZXIudmFsdWUpfHwyLDAuNSwxMCk7CiAgICBjb25zdCByYWRpdXNQeD1jbGFtcChOdW1iZXIoZWwucmFkaXVzUHgudmFsdWUpfHwyODAsMTAsNTAwMCk7CiAgICBjb25zdCBzaWdtYT1jbGFtcChOdW1iZXIoZWwuZ2F1c3NTaWdtYS52YWx1ZSl8fDIyMCwxMCw1MDAwKTsKCiAgICBjb25zdCBwdHNDYW52YXM9cG9pbnRzLm1hcChwPT57IGNvbnN0IGM9d29ybGRUb0NhbnZhcyhwLngscC55LGxhc3RSZW5kZXJCQm94KTsgcmV0dXJuIHsuLi5wLGN4OmMuY3gsY3k6Yy5jeX07IH0pOwoKICAgIGxldCBtYXNrUmluZ3M9W107CiAgICBpZihlbC5tYXNrTW9kZS52YWx1ZT09PSJkcmF3biIpIG1hc2tSaW5ncz1kcmF3UmluZ3M7CiAgICBpZihlbC5tYXNrTW9kZS52YWx1ZT09PSJnZW9qc29uIiAmJiBnZW9qc29uICYmIGVsLnVuaXRzLnZhbHVlPT09ImxhdGxuZyIpIG1hc2tSaW5ncz1nZW9qc29uVG9SaW5nc0xhdExuZyhnZW9qc29uKTsKICAgIGlmKG1hc2tSaW5ncy5sZW5ndGggJiYgIXBvaW50SW5Qb2x5Z29uUmluZ3Mody54LHcueSxtYXNrUmluZ3MpKXsKICAgICAgaG92ZXJTdGF0ZT17Y3gsY3kseDp3LngseTp3LnkscHJlZDpudWxsLG5lYXJlc3Q6bnVsbH07CiAgICAgIGVsLmhvdmVyUmVhZG91dC50ZXh0Q29udGVudD1gSG92ZXI6IG91dHNpZGUgbWFzayDigKIgeD0ke3cueC50b0ZpeGVkKDYpfSB5PSR7dy55LnRvRml4ZWQoNil9YDsKICAgICAgcmVuZGVyKCk7CiAgICAgIHJldHVybjsKICAgIH0KCiAgICBjb25zdCBwcmVkPXByZWRpY3RBdChjeCxjeSxwdHNDYW52YXMse3Bvd2VyLHJhZGl1c1B4LHNpZ21hfSk7CiAgICBjb25zdCBuZWFyZXN0PW5lYXJlc3RQb2ludEluZm8ody54LHcueSxwb2ludHMpOwogICAgaG92ZXJTdGF0ZT17Y3gsY3kseDp3LngseTp3LnkscHJlZDpwcmVkPT1udWxsP251bGw6cHJlZCxuZWFyZXN0fTsKCiAgICBjb25zdCBwcmVkVGV4dD1wcmVkPT1udWxsPyLigJQiOnByZWQudG9GaXhlZCgyKTsKICAgIGVsLmhvdmVyUmVhZG91dC50ZXh0Q29udGVudD1gSG92ZXI6IHByZWQ9JHtwcmVkVGV4dH0g4oCiICR7bmVhcmVzdHx8IuKAlCJ9IOKAoiB4PSR7dy54LnRvRml4ZWQoNil9IHk9JHt3LnkudG9GaXhlZCg2KX1gOwoKICAgIGlmKGRyYXdBY3RpdmUpewogICAgICBkcmF3SG92ZXI9e2N4LGN5fTsKICAgICAgc25hcEhvdmVyPWNvbXB1dGVTbmFwSG92ZXIobGFzdFJlbmRlckJCb3gsY3gsY3kpOwogICAgfQogICAgcmVuZGVyKCk7CiAgfQogIGZ1bmN0aW9uIG9uQ2FudmFzTGVhdmUoKXsKICAgIGhvdmVyU3RhdGU9bnVsbDsgZWwuaG92ZXJSZWFkb3V0LnRleHRDb250ZW50PSJIb3Zlcjog4oCUIjsKICAgIGlmKGRyYXdBY3RpdmUpeyBkcmF3SG92ZXI9bnVsbDsgc25hcEhvdmVyPW51bGw7IH0KICAgIHJlbmRlcigpOwogIH0KICBmdW5jdGlvbiBvbkNhbnZhc0NsaWNrKGV2KXsKICAgIGlmKCFsYXN0UmVuZGVyQkJveCkgcmV0dXJuOwogICAgY29uc3Qga3c9ZWwua2V5d29yZFNlbGVjdC52YWx1ZXx8IiI7CiAgICBjb25zdCBiaXo9ZWwuYnVzaW5lc3NGaWx0ZXIudmFsdWV8fCJkZWZhdWx0IjsKICAgIGNvbnN0IGRhdGU9ZWwuZGF0ZUZpbHRlci52YWx1ZXx8ImxhdGVzdCI7CiAgICBjb25zdCBwb2ludHM9YnlLZXl3b3JkLmdldChrdyl8fFtdOwogICAgaWYoIXBvaW50cy5sZW5ndGgpIHJldHVybjsKCiAgICBjb25zdCByZWN0PWVsLmNhbnZhcy5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKTsKICAgIGNvbnN0IGN4PSgoZXYuY2xpZW50WC1yZWN0LmxlZnQpL3JlY3Qud2lkdGgpKmVsLmNhbnZhcy53aWR0aDsKICAgIGNvbnN0IGN5PSgoZXYuY2xpZW50WS1yZWN0LnRvcCkvcmVjdC5oZWlnaHQpKmVsLmNhbnZhcy5oZWlnaHQ7CiAgICBjb25zdCB3PWNhbnZhc1RvV29ybGQoY3gsY3ksbGFzdFJlbmRlckJCb3gpOwoKICAgIGlmKGRyYXdBY3RpdmUpewogICAgICBjb25zdCBjaGs9ZW5zdXJlRHJhd0F2YWlsYWJsZSgpOwogICAgICBpZighY2hrLm9rKXsgc2V0U3RhdHVzKGNoay5lcnJvcik7IHJldHVybjsgfQogICAgICBjb25zdCByaW5nPWRyYXdSaW5nc1thY3RpdmVSaW5nSW5kZXhdOwogICAgICBjb25zdCBzbmFwPWNvbXB1dGVTbmFwSG92ZXIobGFzdFJlbmRlckJCb3gsY3gsY3kpOwogICAgICBpZihzbmFwICYmIHJpbmcubGVuZ3RoPj0zKXsKICAgICAgICBzZXRTdGF0dXMoYENsb3NlZCAke2FjdGl2ZVJpbmdJbmRleD09PTA/Im91dGVyIHJpbmciOmBob2xlICR7YWN0aXZlUmluZ0luZGV4fWB9LmApOwogICAgICAgIHNuYXBIb3Zlcj1udWxsOyB1cGRhdGVEcmF3VUkoKTsgcmVuZGVyKCk7IHJldHVybjsKICAgICAgfQogICAgICByaW5nLnB1c2goe2xhdDp3LngsbG5nOncueX0pOwogICAgICB1cGRhdGVEcmF3VUkoKTsgcmVuZGVyKCk7IHJldHVybjsKICAgIH0KCiAgICBpZihlbC5pbnNwZWN0TW9kZS52YWx1ZSE9PSJvbiIpIHJldHVybjsKICAgIGlmKCFob3ZlclN0YXRlIHx8IGhvdmVyU3RhdGUucHJlZD09bnVsbCkgcmV0dXJuOwoKICAgIGNvbnN0IG5lYXJlc3Q9bmVhcmVzdFBvaW50SW5mbyh3Lngsdy55LHBvaW50cyl8fCIiOwogICAgY29uc3QgaWQ9YCR7RGF0ZS5ub3coKX1fJHtNYXRoLnJhbmRvbSgpLnRvU3RyaW5nKDE2KS5zbGljZSgyLDgpfWA7CiAgICBwaW5zLnB1c2goe2lkLGtleXdvcmQ6a3csYnVzaW5lc3M6Yml6LGRhdGUseDp3LngseTp3LnkscHJlZDpob3ZlclN0YXRlLnByZWQsbmVhcmVzdCxub3RlOiIifSk7CiAgICB1cGRhdGVQaW5zUGlsbCgpOwogICAgcmVuZGVyKCk7CiAgfQogIGZ1bmN0aW9uIG9uQ2FudmFzRGJsQ2xpY2soZXYpewogICAgaWYoIWRyYXdBY3RpdmUpIHJldHVybjsKICAgIGV2LnByZXZlbnREZWZhdWx0KCk7CiAgICBjb25zdCByaW5nPWRyYXdSaW5nc1thY3RpdmVSaW5nSW5kZXhdfHxbXTsKICAgIGlmKHJpbmcubGVuZ3RoPDMpeyBzZXRTdGF0dXMoIk5lZWQgMysgcG9pbnRzIHRvIGNsb3NlIGEgcmluZy4iKTsgcmV0dXJuOyB9CiAgICBzZXRTdGF0dXMoYENsb3NlZCAke2FjdGl2ZVJpbmdJbmRleD09PTA/Im91dGVyIHJpbmciOmBob2xlICR7YWN0aXZlUmluZ0luZGV4fWB9LmApOwogICAgdXBkYXRlRHJhd1VJKCk7IHJlbmRlcigpOwogIH0KCiAgLy8gRXhwb3J0cwogIGZ1bmN0aW9uIGRhdGFVUkxUb0J5dGVzKGRhdGFVUkwpewogICAgY29uc3QgYmFzZTY0PWRhdGFVUkwuc3BsaXQoIiwiKVsxXXx8IiI7CiAgICBjb25zdCBiaW49YXRvYihiYXNlNjQpOwogICAgY29uc3QgYnl0ZXM9bmV3IFVpbnQ4QXJyYXkoYmluLmxlbmd0aCk7CiAgICBmb3IobGV0IGk9MDtpPGJpbi5sZW5ndGg7aSsrKSBieXRlc1tpXT1iaW4uY2hhckNvZGVBdChpKTsKICAgIHJldHVybiBieXRlczsKICB9CiAgZnVuY3Rpb24gZXhwb3J0UE5HKCl7CiAgICBjb25zdCBrdz1lbC5rZXl3b3JkU2VsZWN0LnZhbHVlfHwiaGVhdG1hcCI7CiAgICBjb25zdCBiaXo9ZWwuYnVzaW5lc3NGaWx0ZXIudmFsdWV8fCJkZWZhdWx0IjsKICAgIGNvbnN0IGRhdGU9ZWwuZGF0ZUZpbHRlci52YWx1ZXx8ImxhdGVzdCI7CiAgICBjb25zdCBuYW1lPShlbC5wcm9qZWN0TmFtZS52YWx1ZXx8InByb2plY3QiKS50cmltKCkucmVwbGFjZSgvW15cd1wtXSsvZywiXyIpfHwicHJvamVjdCI7CiAgICBjb25zdCBieXRlcz1kYXRhVVJMVG9CeXRlcyhlbC5jYW52YXMudG9EYXRhVVJMKCJpbWFnZS9wbmciKSk7CiAgICBkb3dubG9hZFRleHQoYCR7bmFtZX1fJHtiaXp9XyR7a3d9XyR7ZGF0ZX0ucG5nYCwgYnl0ZXMsICJhcHBsaWNhdGlvbi9vY3RldC1zdHJlYW0iKTsKICB9CgogIGZ1bmN0aW9uIGV4cG9ydFNWRygpewogICAgaWYoIWxhc3RSZW5kZXJCQm94KXsgc2V0U3RhdHVzKCJSZW5kZXIgZmlyc3QuIik7IHJldHVybjsgfQogICAgY29uc3QgYmJveD1sYXN0UmVuZGVyQkJveDsKICAgIGNvbnN0IGt3PWVsLmtleXdvcmRTZWxlY3QudmFsdWV8fCJoZWF0bWFwIjsKICAgIGNvbnN0IGJpej1lbC5idXNpbmVzc0ZpbHRlci52YWx1ZXx8ImRlZmF1bHQiOwogICAgY29uc3QgZGF0ZT1lbC5kYXRlRmlsdGVyLnZhbHVlfHwibGF0ZXN0IjsKICAgIGNvbnN0IG5hbWU9KGVsLnByb2plY3ROYW1lLnZhbHVlfHwicHJvamVjdCIpLnRyaW0oKS5yZXBsYWNlKC9bXlx3XC1dKy9nLCJfIil8fCJwcm9qZWN0IjsKICAgIGNvbnN0IHBuZz1lbC5jYW52YXMudG9EYXRhVVJMKCJpbWFnZS9wbmciKTsKICAgIGNvbnN0IHBvaW50cz1ieUtleXdvcmQuZ2V0KGt3KXx8W107CiAgICBjb25zdCBtYXhSYW5rPWNsYW1wKE51bWJlcihlbC5tYXhSYW5rLnZhbHVlKXx8MjAsMiw5OTkpOwoKICAgIGNvbnN0IHBhdGhzPVtdOwogICAgaWYoZ2VvanNvbiAmJiBlbC51bml0cy52YWx1ZT09PSJsYXRsbmciICYmIGVsLmdlb1N0eWxlLnZhbHVlIT09Im9mZiIpewogICAgICBjb25zdCBnZW9tcz1nZW9qc29uVG9HZW9tZXRyaWVzKGdlb2pzb24pOwogICAgICBmb3IoY29uc3QgZyBvZiBnZW9tcyl7CiAgICAgICAgaWYoZy50eXBlPT09IlBvbHlnb24iKSBwYXRocy5wdXNoKHN2Z1BhdGhGcm9tUG9seWdvbkNvb3JkcyhnLmNvb3JkaW5hdGVzLGJib3gpKTsKICAgICAgICBpZihnLnR5cGU9PT0iTXVsdGlQb2x5Z29uIikgZm9yKGNvbnN0IHBvbHkgb2YgZy5jb29yZGluYXRlcykgcGF0aHMucHVzaChzdmdQYXRoRnJvbVBvbHlnb25Db29yZHMocG9seSxiYm94KSk7CiAgICAgIH0KICAgIH0KICAgIGlmKGRyYXdSaW5ncy5sZW5ndGgpIHBhdGhzLnB1c2goc3ZnUGF0aEZyb21SaW5ncyhkcmF3UmluZ3MsYmJveCkpOwoKICAgIGNvbnN0IGNpcmNsZXM9cG9pbnRzLm1hcChwPT57CiAgICAgIGNvbnN0IGM9d29ybGRUb0NhbnZhcyhwLngscC55LGJib3gpOwogICAgICBjb25zdCBjb2w9cmFua1RvQ29sb3IocC5yYW5rLG1heFJhbmspOwogICAgICByZXR1cm4gYDxjaXJjbGUgY3g9IiR7Yy5jeC50b0ZpeGVkKDIpfSIgY3k9IiR7Yy5jeS50b0ZpeGVkKDIpfSIgcj0iNyIgZmlsbD0icmdiKCR7Y29sLnJ9LCR7Y29sLmd9LCR7Y29sLmJ9KSIgZmlsbC1vcGFjaXR5PSIwLjk1IiBzdHJva2U9InJnYmEoMjU1LDI1NSwyNTUsMC4zNSkiIHN0cm9rZS13aWR0aD0iMS4yIi8+YDsKICAgIH0pLmpvaW4oIlxuIik7CgogICAgY29uc3Qgc3ZnVz1lbC5jYW52YXMud2lkdGgsIHN2Z0g9ZWwuY2FudmFzLmhlaWdodDsKICAgIGNvbnN0IHN2ZyA9IGAKPHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIke3N2Z1d9IiBoZWlnaHQ9IiR7c3ZnSH0iIHZpZXdCb3g9IjAgMCAke3N2Z1d9ICR7c3ZnSH0iPgogIDxpbWFnZSBocmVmPSIke3BuZ30iIHg9IjAiIHk9IjAiIHdpZHRoPSIke3N2Z1d9IiBoZWlnaHQ9IiR7c3ZnSH0iIC8+CiAgPGcgZmlsbD0ibm9uZSIgc3Ryb2tlPSJyZ2JhKDI1NSwyNTUsMjU1LDAuMzUpIiBzdHJva2Utd2lkdGg9IjEuNSI+JHtwYXRocy5qb2luKCJcbiIpfTwvZz4KICA8Zz4ke2NpcmNsZXN9PC9nPgogIDx0ZXh0IHg9IjE4IiB5PSIyOCIgZm9udC1mYW1pbHk9InN5c3RlbS11aSwtYXBwbGUtc3lzdGVtLFNlZ29lIFVJLFJvYm90byxBcmlhbCIgZm9udC1zaXplPSIxNiIgZmlsbD0id2hpdGUiPiR7ZXNjYXBlWE1MKGAke25hbWV9IOKAlCAke2Jpen0g4oCUICIke2t3fSIg4oCUICR7ZGF0ZX1gKX08L3RleHQ+Cjwvc3ZnPmAudHJpbSgpOwogICAgZG93bmxvYWRUZXh0KGAke25hbWV9XyR7Yml6fV8ke2t3fV8ke2RhdGV9LnN2Z2AsIHN2ZywgImltYWdlL3N2Zyt4bWw7Y2hhcnNldD11dGYtOCIpOwogIH0KICBmdW5jdGlvbiBzdmdQYXRoRnJvbVBvbHlnb25Db29yZHMocG9seUNvb3JkcyxiYm94KXsKICAgIGxldCBkPSIiOwogICAgZm9yKGNvbnN0IHJpbmcgb2YgcG9seUNvb3Jkcyl7CiAgICAgIGlmKCFBcnJheS5pc0FycmF5KHJpbmcpfHxyaW5nLmxlbmd0aDwyKSBjb250aW51ZTsKICAgICAgZm9yKGxldCBpPTA7aTxyaW5nLmxlbmd0aDtpKyspewogICAgICAgIGNvbnN0IGxvbj1OdW1iZXIocmluZ1tpXT8uWzBdKTsgY29uc3QgbGF0PU51bWJlcihyaW5nW2ldPy5bMV0pOwogICAgICAgIGlmKCFOdW1iZXIuaXNGaW5pdGUobGF0KXx8IU51bWJlci5pc0Zpbml0ZShsb24pKSBjb250aW51ZTsKICAgICAgICBjb25zdCBjPXdvcmxkVG9DYW52YXMobGF0LGxvbixiYm94KTsKICAgICAgICBkICs9IChpPT09MD9gTSAke2MuY3gudG9GaXhlZCgyKX0gJHtjLmN5LnRvRml4ZWQoMil9IGA6YEwgJHtjLmN4LnRvRml4ZWQoMil9ICR7Yy5jeS50b0ZpeGVkKDIpfSBgKTsKICAgICAgfQogICAgICBkICs9ICJaICI7CiAgICB9CiAgICByZXR1cm4gYDxwYXRoIGQ9IiR7ZC50cmltKCl9IiAvPmA7CiAgfQogIGZ1bmN0aW9uIHN2Z1BhdGhGcm9tUmluZ3MocmluZ3MsYmJveCl7CiAgICBsZXQgZD0iIjsKICAgIGZvcihjb25zdCByaW5nIG9mIHJpbmdzKXsKICAgICAgaWYoIXJpbmcubGVuZ3RoKSBjb250aW51ZTsKICAgICAgZm9yKGxldCBpPTA7aTxyaW5nLmxlbmd0aDtpKyspewogICAgICAgIGNvbnN0IHA9cmluZ1tpXTsKICAgICAgICBjb25zdCBjPXdvcmxkVG9DYW52YXMocC5sYXQscC5sbmcsYmJveCk7CiAgICAgICAgZCArPSAoaT09PTA/YE0gJHtjLmN4LnRvRml4ZWQoMil9ICR7Yy5jeS50b0ZpeGVkKDIpfSBgOmBMICR7Yy5jeC50b0ZpeGVkKDIpfSAke2MuY3kudG9GaXhlZCgyKX0gYCk7CiAgICAgIH0KICAgICAgZCArPSAiWiAiOwogICAgfQogICAgcmV0dXJuIGA8cGF0aCBkPSIke2QudHJpbSgpfSIgLz5gOwogIH0KCiAgZnVuY3Rpb24gb3BlblJlcG9ydCgpewogICAgY29uc3Qga3c9ZWwua2V5d29yZFNlbGVjdC52YWx1ZXx8IiI7CiAgICBjb25zdCBiaXo9ZWwuYnVzaW5lc3NGaWx0ZXIudmFsdWV8fCJkZWZhdWx0IjsKICAgIGNvbnN0IGRhdGU9ZWwuZGF0ZUZpbHRlci52YWx1ZXx8ImxhdGVzdCI7CiAgICBjb25zdCBuYW1lPShlbC5wcm9qZWN0TmFtZS52YWx1ZXx8InByb2plY3QiKS50cmltKCl8fCJwcm9qZWN0IjsKICAgIGNvbnN0IHBuZz1lbC5jYW52YXMudG9EYXRhVVJMKCJpbWFnZS9wbmciKTsKICAgIGNvbnN0IG9wcHM9KGVsLm9wcEJvZHkuX29wcHN8fFtdKS5zbGljZSgwLDE1KTsKICAgIGNvbnN0IGtzPWtleXdvcmRTdGF0cy5maW5kKHM9PnMua2V5d29yZD09PWt3KTsKCiAgICBjb25zdCBodG1sID0gYAo8IWRvY3R5cGUgaHRtbD48aHRtbD48aGVhZD48bWV0YSBjaGFyc2V0PSJ1dGYtOCIvPgo8dGl0bGU+JHtlc2NhcGVYTUwobmFtZSl9IFJlcG9ydDwvdGl0bGU+CjxzdHlsZT4KICBib2R5e2ZvbnQtZmFtaWx5OnN5c3RlbS11aSwtYXBwbGUtc3lzdGVtLFNlZ29lIFVJLFJvYm90byxBcmlhbDttYXJnaW46MjRweH0KICBoMXttYXJnaW46MCAwIDhweDtmb250LXNpemU6MjJweH0KICAubWV0YXtvcGFjaXR5Oi44O21hcmdpbi1ib3R0b206MTRweH0KICBpbWd7d2lkdGg6MTAwJTttYXgtd2lkdGg6MTEwMHB4O2JvcmRlcjoxcHggc29saWQgI2RkZDtib3JkZXItcmFkaXVzOjEycHh9CiAgdGFibGV7Ym9yZGVyLWNvbGxhcHNlOmNvbGxhcHNlO3dpZHRoOjEwMCU7bWF4LXdpZHRoOjExMDBweDttYXJnaW4tdG9wOjE0cHg7Zm9udC1zaXplOjEycHh9CiAgdGgsdGR7Ym9yZGVyLWJvdHRvbToxcHggc29saWQgI2RkZDtwYWRkaW5nOjZweDt0ZXh0LWFsaWduOmxlZnR9CiAgLmdyaWR7ZGlzcGxheTpncmlkO2dyaWQtdGVtcGxhdGUtY29sdW1uczoxZnIgMWZyO2dhcDoxNnB4O21heC13aWR0aDoxMTAwcHh9CiAgQG1lZGlhIHByaW50e2J1dHRvbntkaXNwbGF5Om5vbmV9fQo8L3N0eWxlPjwvaGVhZD48Ym9keT4KPGJ1dHRvbiBvbmNsaWNrPSJ3aW5kb3cucHJpbnQoKSI+UHJpbnQgLyBTYXZlIFBERjwvYnV0dG9uPgo8aDE+JHtlc2NhcGVYTUwobmFtZSl9IOKAlCAke2VzY2FwZVhNTChiaXopfSDigJQgJHtlc2NhcGVYTUwoZGF0ZSl9PC9oMT4KPGRpdiBjbGFzcz0ibWV0YSI+S2V5d29yZDogPGI+JHtlc2NhcGVYTUwoa3cpfTwvYj48L2Rpdj4KPGltZyBzcmM9IiR7cG5nfSIgYWx0PSJIZWF0bWFwIi8+CjxkaXYgY2xhc3M9ImdyaWQiPgogIDxkaXY+CiAgICA8aDM+U2VsZWN0ZWQga2V5d29yZCBzdW1tYXJ5PC9oMz4KICAgIDxkaXY+JHtrcz9gCiAgICAgIENvdW50OiAke2tzLmNvdW50fTxici8+CiAgICAgIEF2ZzogJHtrcy5hdmcudG9GaXhlZCgyKX0g4oCiIE1lZGlhbjogJHtrcy5tZWRpYW4udG9GaXhlZCgyKX08YnIvPgogICAgICBCZXN0OiAke2tzLmJlc3R9ICgke2VzY2FwZVhNTChrcy5iZXN0TG9jKX0pPGJyLz4KICAgICAgV29yc3Q6ICR7a3Mud29yc3R9ICgke2VzY2FwZVhNTChrcy53b3JzdExvYyl9KTxici8+CiAgICAgIFRvcDM6ICR7a3MudG9wMy50b0ZpeGVkKDEpfSUg4oCiIFRvcDEwOiAke2tzLnRvcDEwLnRvRml4ZWQoMSl9JSDigKIgVG9wMjA6ICR7a3MudG9wMjAudG9GaXhlZCgxKX0lCiAgICBgOiJObyBzdGF0cy4ifTwvZGl2PgogIDwvZGl2PgogIDxkaXY+CiAgICA8aDM+VG9wIG9wcG9ydHVuaXRpZXMgKCR7ZXNjYXBlWE1MKGVsLm9wcE1vZGUudmFsdWUpfSk8L2gzPgogICAgPHRhYmxlPjx0aGVhZD48dHI+PHRoPktleXdvcmQ8L3RoPjx0aD5Bdmc8L3RoPjx0aD5Ub3AlPC90aD48dGg+SnVzdC1taXNzJTwvdGg+PHRoPlNjb3JlPC90aD48L3RyPjwvdGhlYWQ+CiAgICA8dGJvZHk+JHtvcHBzLm1hcChvPT5gPHRyPjx0ZD4ke2VzY2FwZVhNTChvLmtleXdvcmQpfTwvdGQ+PHRkPiR7by5hdmcudG9GaXhlZCgyKX08L3RkPjx0ZD4ke28udG9wUGN0LnRvRml4ZWQoMSl9PC90ZD48dGQ+JHtvLm1pc3NQY3QudG9GaXhlZCgxKX08L3RkPjx0ZD4ke28uc2NvcmUudG9GaXhlZCgzKX08L3RkPjwvdHI+YCkuam9pbigiIil9PC90Ym9keT48L3RhYmxlPgogIDwvZGl2Pgo8L2Rpdj4KPC9ib2R5PjwvaHRtbD5gLnRyaW0oKTsKCiAgICBjb25zdCB3PXdpbmRvdy5vcGVuKCIiLCJfYmxhbmsiKTsKICAgIGlmKCF3KXsgc2V0U3RhdHVzKCJQb3B1cCBibG9ja2VkOyBhbGxvdyBwb3B1cHMgZm9yIHJlcG9ydC4iKTsgcmV0dXJuOyB9CiAgICB3LmRvY3VtZW50Lm9wZW4oKTsgdy5kb2N1bWVudC53cml0ZShodG1sKTsgdy5kb2N1bWVudC5jbG9zZSgpOwogIH0KCiAgLy8gUHJvamVjdCBzYXZlL2xvYWQKICBmdW5jdGlvbiBzYXZlUHJvamVjdCgpewogICAgY29uc3QgcGF5bG9hZD17CiAgICAgIHZlcnNpb246MSwKICAgICAgbmFtZTogZWwucHJvamVjdE5hbWUudmFsdWV8fCIiLAogICAgICB1bml0czogZWwudW5pdHMudmFsdWUsCiAgICAgIGltcG9ydHM6IGltcG9ydEJsb2JzLAogICAgICBzdGFnaW5nOiBlbC5jc3ZUZXh0LnZhbHVlfHwiIiwKICAgICAgY3N2Rm9ybWF0OiBlbC5jc3ZGb3JtYXQudmFsdWUsCiAgICAgIG1hcExvbmcsIG1hcFdpZGUsCiAgICAgIHNldHRpbmdzOnsKICAgICAgICBtYXhSYW5rOiBlbC5tYXhSYW5rLnZhbHVlLCBncmlkU2l6ZTogZWwuZ3JpZFNpemUudmFsdWUsIHBvd2VyOiBlbC5wb3dlci52YWx1ZSwKICAgICAgICByYWRpdXNQeDogZWwucmFkaXVzUHgudmFsdWUsIGludGVycE1vZGU6IGVsLmludGVycE1vZGUudmFsdWUsIGdhdXNzU2lnbWE6IGVsLmdhdXNzU2lnbWEudmFsdWUsCiAgICAgICAgY29sb3JNb2RlOiBlbC5jb2xvck1vZGUudmFsdWUsIGJ1Y2tldEN1dHM6IGVsLmJ1Y2tldEN1dHMudmFsdWUsIG1pc3NpbmdQb2xpY3k6IGVsLm1pc3NpbmdQb2xpY3kudmFsdWUsCiAgICAgICAgbWFza01vZGU6IGVsLm1hc2tNb2RlLnZhbHVlLCBiZ01vZGU6IGVsLmJnTW9kZS52YWx1ZSwgbGFiZWxzTW9kZTogZWwubGFiZWxzTW9kZS52YWx1ZSwKICAgICAgICB2aWV3TW9kZTogZWwudmlld01vZGUudmFsdWUsIGxlZ2VuZE1vZGU6IGVsLmxlZ2VuZE1vZGUudmFsdWUsIGluc3BlY3RNb2RlOiBlbC5pbnNwZWN0TW9kZS52YWx1ZSwgcHJldmlld01vZGU6IGVsLnByZXZpZXdNb2RlLnZhbHVlLAogICAgICAgIGJpekxhdDogZWwuYml6TGF0LnZhbHVlLCBiaXpMbmc6IGVsLmJpekxuZy52YWx1ZSwgcmluZ3M6IGVsLnJpbmdzLnZhbHVlCiAgICAgIH0sCiAgICAgIGdlb2pzb24sCiAgICAgIHBpbnMsCiAgICAgIHJvd3NBbGwKICAgIH07CiAgICBjb25zdCBzYWZlPShlbC5wcm9qZWN0TmFtZS52YWx1ZXx8InByb2plY3QiKS50cmltKCkucmVwbGFjZSgvW15cd1wtXSsvZywiXyIpfHwicHJvamVjdCI7CiAgICBkb3dubG9hZFRleHQoYCR7c2FmZX0ucHJvamVjdC5qc29uYCwgSlNPTi5zdHJpbmdpZnkocGF5bG9hZCxudWxsLDIpLCAiYXBwbGljYXRpb24vanNvbjtjaGFyc2V0PXV0Zi04Iik7CiAgfQoKICBmdW5jdGlvbiBsb2FkUHJvamVjdChwYXlsb2FkKXsKICAgIGVsLnByb2plY3ROYW1lLnZhbHVlPXBheWxvYWQubmFtZXx8IiI7CiAgICBlbC51bml0cy52YWx1ZT1wYXlsb2FkLnVuaXRzfHwibGF0bG5nIjsKICAgIGltcG9ydEJsb2JzPUFycmF5LmlzQXJyYXkocGF5bG9hZC5pbXBvcnRzKT9wYXlsb2FkLmltcG9ydHM6W107CiAgICBlbC5jc3ZUZXh0LnZhbHVlPXBheWxvYWQuc3RhZ2luZ3x8IiI7CiAgICBlbC5jc3ZGb3JtYXQudmFsdWU9cGF5bG9hZC5jc3ZGb3JtYXR8fCJhdXRvIjsKICAgIG1hcExvbmc9cGF5bG9hZC5tYXBMb25nfHxtYXBMb25nOwogICAgbWFwV2lkZT1wYXlsb2FkLm1hcFdpZGV8fG1hcFdpZGU7CgogICAgY29uc3Qgcz1wYXlsb2FkLnNldHRpbmdzfHx7fTsKICAgIGlmKHMubWF4UmFuayE9bnVsbCkgZWwubWF4UmFuay52YWx1ZT1zLm1heFJhbms7CiAgICBpZihzLmdyaWRTaXplIT1udWxsKSBlbC5ncmlkU2l6ZS52YWx1ZT1zLmdyaWRTaXplOwogICAgaWYocy5wb3dlciE9bnVsbCkgZWwucG93ZXIudmFsdWU9cy5wb3dlcjsKICAgIGlmKHMucmFkaXVzUHghPW51bGwpIGVsLnJhZGl1c1B4LnZhbHVlPXMucmFkaXVzUHg7CiAgICBpZihzLmludGVycE1vZGUhPW51bGwpIGVsLmludGVycE1vZGUudmFsdWU9cy5pbnRlcnBNb2RlOwogICAgaWYocy5nYXVzc1NpZ21hIT1udWxsKSBlbC5nYXVzc1NpZ21hLnZhbHVlPXMuZ2F1c3NTaWdtYTsKICAgIGlmKHMuY29sb3JNb2RlIT1udWxsKSBlbC5jb2xvck1vZGUudmFsdWU9cy5jb2xvck1vZGU7CiAgICBpZihzLmJ1Y2tldEN1dHMhPW51bGwpIGVsLmJ1Y2tldEN1dHMudmFsdWU9cy5idWNrZXRDdXRzOwogICAgaWYocy5taXNzaW5nUG9saWN5IT1udWxsKSBlbC5taXNzaW5nUG9saWN5LnZhbHVlPXMubWlzc2luZ1BvbGljeTsKICAgIGlmKHMubWFza01vZGUhPW51bGwpIGVsLm1hc2tNb2RlLnZhbHVlPXMubWFza01vZGU7CiAgICBpZihzLmJnTW9kZSE9bnVsbCkgZWwuYmdNb2RlLnZhbHVlPXMuYmdNb2RlOwogICAgaWYocy5sYWJlbHNNb2RlIT1udWxsKSBlbC5sYWJlbHNNb2RlLnZhbHVlPXMubGFiZWxzTW9kZTsKICAgIGlmKHMudmlld01vZGUhPW51bGwpIGVsLnZpZXdNb2RlLnZhbHVlPXMudmlld01vZGU7CiAgICBpZihzLmxlZ2VuZE1vZGUhPW51bGwpIGVsLmxlZ2VuZE1vZGUudmFsdWU9cy5sZWdlbmRNb2RlOwogICAgaWYocy5pbnNwZWN0TW9kZSE9bnVsbCkgZWwuaW5zcGVjdE1vZGUudmFsdWU9cy5pbnNwZWN0TW9kZTsKICAgIGlmKHMucHJldmlld01vZGUhPW51bGwpIGVsLnByZXZpZXdNb2RlLnZhbHVlPXMucHJldmlld01vZGU7CiAgICBpZihzLmJpekxhdCE9bnVsbCkgZWwuYml6TGF0LnZhbHVlPXMuYml6TGF0OwogICAgaWYocy5iaXpMbmchPW51bGwpIGVsLmJpekxuZy52YWx1ZT1zLmJpekxuZzsKICAgIGlmKHMucmluZ3MhPW51bGwpIGVsLnJpbmdzLnZhbHVlPXMucmluZ3M7CgogICAgcGlucz1BcnJheS5pc0FycmF5KHBheWxvYWQucGlucyk/cGF5bG9hZC5waW5zOltdOwogICAgdXBkYXRlUGluc1BpbGwoKTsKCiAgICBnZW9qc29uPXBheWxvYWQuZ2VvanNvbnx8bnVsbDsKICAgIGdlb0JCb3g9Z2VvanNvbj9zY2FuR2VvQkJveChnZW9qc29uKTpudWxsOwogICAgaWYoZ2VvanNvbiAmJiBnZW9CQm94KXsKICAgICAgZWwuZ2VvU3R5bGUuZGlzYWJsZWQ9ZmFsc2U7IGVsLmNsZWFyR2VvQnRuLmRpc2FibGVkPWZhbHNlOyBlbC5jb3B5R2VvQnRuLmRpc2FibGVkPWZhbHNlOwogICAgICBlbC5tYXNrTW9kZS5kaXNhYmxlZD1mYWxzZTsKICAgICAgZWwuZ2VvUGlsbC50ZXh0Q29udGVudD0iR2VvSlNPTiBsb2FkZWQiOwogICAgfSBlbHNlIHsKICAgICAgY2xlYXJHZW8oKTsKICAgIH0KCiAgICBpZihBcnJheS5pc0FycmF5KHBheWxvYWQucm93c0FsbCkgJiYgcGF5bG9hZC5yb3dzQWxsLmxlbmd0aCl7CiAgICAgIHJvd3NBbGw9cGF5bG9hZC5yb3dzQWxsOwogICAgICB2YWxpZGF0aW9uLmVycm9ycz1bXTsgdmFsaWRhdGlvbi5lcnJvckNzdj1udWxsOyB2YWxpZGF0aW9uLm5vcm1hbGl6ZWRDc3Y9cm93c1RvTm9ybWFsaXplZENTVihyb3dzQWxsKTsKICAgICAgZWwudmFsaWRhdGlvblN1bW1hcnkudGV4dENvbnRlbnQ9YFJvd3Mga2VwdDogJHtyb3dzQWxsLmxlbmd0aH0g4oCiIEVycm9yczogMCAocmVzdG9yZWQpYDsKICAgICAgZWwuZG93bmxvYWROb3JtYWxpemVkQnRuLmRpc2FibGVkPWZhbHNlOwogICAgICBlbC5zaG93RXJyb3JzQnRuLmRpc2FibGVkPXRydWU7IGVsLmRvd25sb2FkRXJyb3JzQnRuLmRpc2FibGVkPXRydWU7CiAgICAgIGVsLm1ldGFQaWxsLnRleHRDb250ZW50PWAke3Jvd3NBbGwubGVuZ3RofSByb3dzYDsKICAgICAgcmVidWlsZEZpbHRlcnMoKTsKICAgICAgYXBwbHlGaWx0ZXJzQW5kUmVjb21wdXRlKCk7CiAgICAgIGVuYWJsZUNvbnRyb2xzKHRydWUpOwogICAgICByZW5kZXIoKTsKICAgIH0gZWxzZSB7CiAgICAgIGJ1aWxkRGF0YXNldCgpOwogICAgfQoKICAgIHNldFN0YXR1cygiUHJvamVjdCBsb2FkZWQuIik7CiAgfQoKICAvLyBUYWJzCiAgZnVuY3Rpb24gc2V0VGFiKGlkKXsKICAgIGZvcihjb25zdCBiIG9mIGVsLnRhYkJ0bnMpIGIuY2xhc3NMaXN0LnRvZ2dsZSgiYWN0aXZlIiwgYi5kYXRhc2V0LnRhYj09PWlkKTsKICAgIGZvcihjb25zdCBwIG9mIGVsLnBhbmVscykgcC5jbGFzc0xpc3QudG9nZ2xlKCJhY3RpdmUiLCBwLmlkPT09aWQpOwogIH0KCiAgLy8gRXZlbnRzCiAgZWwudGFiQnRucy5mb3JFYWNoKGI9PmIuYWRkRXZlbnRMaXN0ZW5lcigiY2xpY2siLCgpPT5zZXRUYWIoYi5kYXRhc2V0LnRhYikpKTsKICBlbC5jc3ZGb3JtYXQuYWRkRXZlbnRMaXN0ZW5lcigiY2hhbmdlIiwoKT0+eyB0b2dnbGVXaWRlQmxvY2tzKCk7IHRvZ2dsZVdpZGVWb2x1bWVVSSgpOyB9KTsKICBlbC53Vm9sdW1lTW9kZS5hZGRFdmVudExpc3RlbmVyKCJjaGFuZ2UiLHRvZ2dsZVdpZGVWb2x1bWVVSSk7CgogIGVsLnBhc3RlQnRuLmFkZEV2ZW50TGlzdGVuZXIoImNsaWNrIiwgYXN5bmMgKCk9PnsKICAgIHRyeXsKICAgICAgaWYoIW5hdmlnYXRvci5jbGlwYm9hcmQ/LnJlYWRUZXh0KSB0aHJvdyBuZXcgRXJyb3IoIkNsaXBib2FyZCBBUEkgbm90IGF2YWlsYWJsZSAodXNlIEhUVFBTIG9yIGxvY2FsaG9zdCkuIik7CiAgICAgIGNvbnN0IHQ9YXdhaXQgbmF2aWdhdG9yLmNsaXBib2FyZC5yZWFkVGV4dCgpOwogICAgICBpZighdC50cmltKCkpIHsgc2V0U3RhdHVzKCJDbGlwYm9hcmQgZW1wdHkuIik7IHJldHVybjsgfQogICAgICBlbC5jc3ZUZXh0LnZhbHVlPXQ7CiAgICAgIHNldFN0YXR1cygiUGFzdGVkIGludG8gc3RhZ2luZy4gQ2xpY2sgRGV0ZWN0L0F1dG8tbWFwL0J1aWxkLiIpOwogICAgfSBjYXRjaChlKXsgc2V0U3RhdHVzKCJQYXN0ZSBmYWlsZWQ6ICIrKGU/Lm1lc3NhZ2V8fFN0cmluZyhlKSkpOyB9CiAgfSk7CiAgZWwuYWRkQ3N2QnRuLmFkZEV2ZW50TGlzdGVuZXIoImNsaWNrIiwoKT0+ZWwuY3N2RmlsZXMuY2xpY2soKSk7CiAgZWwuY3N2RmlsZXMuYWRkRXZlbnRMaXN0ZW5lcigiY2hhbmdlIiwgYXN5bmMgKCk9PnsKICAgIGNvbnN0IGZpbGVzPUFycmF5LmZyb20oZWwuY3N2RmlsZXMuZmlsZXN8fFtdKTsKICAgIGlmKCFmaWxlcy5sZW5ndGgpIHJldHVybjsKICAgIGZvcihjb25zdCBmIG9mIGZpbGVzKXsKICAgICAgY29uc3QgdGV4dD1hd2FpdCByZWFkRmlsZUFzVGV4dChmKTsKICAgICAgaW1wb3J0QmxvYnMucHVzaCh7bmFtZTpmLm5hbWUsdGV4dH0pOwogICAgfQogICAgc2V0U3RhdHVzKGBBZGRlZCAke2ZpbGVzLmxlbmd0aH0gZmlsZShzKS4gVG90YWwgaW1wb3J0czogJHtpbXBvcnRCbG9icy5sZW5ndGh9LmApOwogIH0pOwogIGVsLmNsZWFySW1wb3J0c0J0bi5hZGRFdmVudExpc3RlbmVyKCJjbGljayIsKCk9PnsgaW1wb3J0QmxvYnM9W107IGVsLmNzdlRleHQudmFsdWU9IiI7IHNldFN0YXR1cygiSW1wb3J0cyBjbGVhcmVkLiIpOyB9KTsKCiAgY29uc3QgU0FNUExFID0gYGtleXdvcmQsbG9jYXRpb24sbGF0LGxuZyxyYW5rLGJ1c2luZXNzLGRhdGUsdm9sdW1lCmJlc3QgZGVudGlzdCxNaWR0b3duLDQwLjc1NDksLTczLjk4NDAsMyxBY21lIERlbnRhbCwyMDI2LTAyLTAxLDEyMDAKYmVzdCBkZW50aXN0LFVwcGVyIEVhc3QgU2lkZSw0MC43NzM2LC03My45NTY2LDYsQWNtZSBEZW50YWwsMjAyNi0wMi0wMSwxMjAwCmJlc3QgZGVudGlzdCxVcHBlciBXZXN0IFNpZGUsNDAuNzg3MCwtNzMuOTc1NCw5LEFjbWUgRGVudGFsLDIwMjYtMDItMDEsMTIwMApiZXN0IGRlbnRpc3QsU29Ibyw0MC43MjMzLC03NC4wMDMwLDQsQWNtZSBEZW50YWwsMjAyNi0wMi0wMSwxMjAwCnRlZXRoIHdoaXRlbmluZyxNaWR0b3duLDQwLjc1NDksLTczLjk4NDAsNSxBY21lIERlbnRhbCwyMDI2LTAyLTAxLDkwMAp0ZWV0aCB3aGl0ZW5pbmcsVXBwZXIgRWFzdCBTaWRlLDQwLjc3MzYsLTczLjk1NjYsOCxBY21lIERlbnRhbCwyMDI2LTAyLTAxLDkwMApiZXN0IGRlbnRpc3QsTWlkdG93biw0MC43NTQ5LC03My45ODQwLDQsQWNtZSBEZW50YWwsMjAyNi0wMS0wMSwxMjAwCnRlZXRoIHdoaXRlbmluZyxNaWR0b3duLDQwLjc1NDksLTczLjk4NDAsNixBY21lIERlbnRhbCwyMDI2LTAxLTAxLDkwMApgOwogIGVsLmxvYWRTYW1wbGVCdG4uYWRkRXZlbnRMaXN0ZW5lcigiY2xpY2siLCgpPT57CiAgICBlbC51bml0cy52YWx1ZT0ibGF0bG5nIjsKICAgIGVsLnByb2plY3ROYW1lLnZhbHVlPSJBY21lIERlbnRhbCBMb2NhbCBSYW5rIjsKICAgIGVsLmNzdlRleHQudmFsdWU9U0FNUExFOwogICAgc2V0U3RhdHVzKCJTYW1wbGUgbG9hZGVkLiBDbGljayBEZXRlY3QvQXV0by1tYXAvQnVpbGQuIik7CiAgfSk7CgogIGVsLmRldGVjdEZvcm1hdEJ0bi5hZGRFdmVudExpc3RlbmVyKCJjbGljayIsKCk9PnsKICAgIGNvbnN0IHRleHQ9KGVsLmNzdlRleHQudmFsdWV8fCIiKS50cmltKCkgfHwgKGltcG9ydEJsb2JzWzBdPy50ZXh0fHwiIikudHJpbSgpOwogICAgaWYoIXRleHQpeyBzZXRTdGF0dXMoIk5vIENTViB0byBkZXRlY3QuIik7IHJldHVybjsgfQogICAgY29uc3QgcGFyc2VkPXBhcnNlQ1NWKHRleHQpOwogICAgY29uc3QgZGV0PWRldGVjdENTVkZvcm1hdChwYXJzZWQpOwogICAgZWwuZm9ybWF0SGludC50ZXh0Q29udGVudD1gRGV0ZWN0ZWQ6ICR7ZGV0LmtpbmQudG9VcHBlckNhc2UoKX0gKCR7ZGV0LnJlYXNvbn0pYDsKICAgIGlmKGRldC5raW5kIT09InVua25vd24iKSBlbC5jc3ZGb3JtYXQudmFsdWU9ZGV0LmtpbmQ7CiAgICB0b2dnbGVXaWRlQmxvY2tzKCk7CiAgICBjb25zdCBoZWFkZXJzPShwYXJzZWRbMF18fFtdKS5tYXAocz0+U3RyaW5nKHM/PyIiKS50cmltKCkpLmZpbHRlcihCb29sZWFuKTsKICAgIGN1cnJlbnRIZWFkZXJzPWhlYWRlcnM7CiAgICBhdXRvTWFwKGhlYWRlcnMpOwogICAgcmVuZGVyTWFwcGluZ1VJKGhlYWRlcnMpOwogICAgc2V0U3RhdHVzKCJEZXRlY3RlZCAmIGF1dG8tbWFwcGVkLiBBZGp1c3QgbWFwcGluZyBpZiBuZWVkZWQsIHRoZW4gQnVpbGQgZGF0YXNldC4iKTsKICB9KTsKCiAgZWwuYXV0b01hcEJ0bi5hZGRFdmVudExpc3RlbmVyKCJjbGljayIsKCk9PnsKICAgIGNvbnN0IHRleHQ9KGVsLmNzdlRleHQudmFsdWV8fCIiKS50cmltKCkgfHwgKGltcG9ydEJsb2JzWzBdPy50ZXh0fHwiIikudHJpbSgpOwogICAgaWYoIXRleHQpeyBzZXRTdGF0dXMoIk5vIENTViBhdmFpbGFibGUuIik7IHJldHVybjsgfQogICAgY29uc3QgcGFyc2VkPXBhcnNlQ1NWKHRleHQpOwogICAgY29uc3QgaGVhZGVycz0ocGFyc2VkWzBdfHxbXSkubWFwKHM9PlN0cmluZyhzPz8iIikudHJpbSgpKS5maWx0ZXIoQm9vbGVhbik7CiAgICBpZighaGVhZGVycy5sZW5ndGgpeyBzZXRTdGF0dXMoIk5vIGhlYWRlcnMgZm91bmQuIik7IHJldHVybjsgfQogICAgY3VycmVudEhlYWRlcnM9aGVhZGVyczsKICAgIGF1dG9NYXAoaGVhZGVycyk7CiAgICByZW5kZXJNYXBwaW5nVUkoaGVhZGVycyk7CiAgICBzZXRTdGF0dXMoIkF1dG8tbWFwcGVkIGhlYWRlcnMuIik7CiAgfSk7CgogIC8vIG1hcHBpbmcgY2hhbmdlcwogIFsKICAgIGVsLm1LZXl3b3JkLCBlbC5tTG9jYXRpb24sIGVsLm1SYW5rLCBlbC5tWCwgZWwubVksIGVsLm1CdXNpbmVzcywgZWwubURhdGUsIGVsLm1Wb2x1bWUsCiAgICBlbC53TG9jYXRpb24sIGVsLndYLCBlbC53WSwgZWwud0J1c2luZXNzLCBlbC53RGF0ZSwgZWwud1ZvbHVtZUNvbAogIF0uZm9yRWFjaChzZWw9PnNlbC5hZGRFdmVudExpc3RlbmVyKCJjaGFuZ2UiLHJlYWRNYXBwaW5nRnJvbVVJKSk7CiAgZWwud0tleXdvcmRDb2xzLmFkZEV2ZW50TGlzdGVuZXIoImlucHV0IixyZWFkTWFwcGluZ0Zyb21VSSk7CgogIGVsLmJ1aWxkQnRuLmFkZEV2ZW50TGlzdGVuZXIoImNsaWNrIiwoKT0+eyB0b2dnbGVXaWRlQmxvY2tzKCk7IHRvZ2dsZVdpZGVWb2x1bWVVSSgpOyBidWlsZERhdGFzZXQoKTsgfSk7CgogIGVsLnNob3dFcnJvcnNCdG4uYWRkRXZlbnRMaXN0ZW5lcigiY2xpY2siLCgpPT57CiAgICBzZXRUYWIoInRhYkVycm9ycyIpOwogICAgY29uc3QgZXJycz12YWxpZGF0aW9uLmVycm9yc3x8W107CiAgICBlbC5lcnJvcnNUZXh0LnRleHRDb250ZW50PWVycnMubGVuZ3RoID8gZXJycy5zbGljZSgwLDQwMCkubWFwKGU9PmAke2Uuc3JjfToke2Uucm93fSDigJQgJHtlLnJlYXNvbn1gKS5qb2luKCJcbiIpICsgKGVycnMubGVuZ3RoPjQwMD9gXG7igKYgKCR7ZXJycy5sZW5ndGgtNDAwfSBtb3JlKWA6IiIpIDogIk5vIGVycm9ycy4iOwogIH0pOwogIGVsLmRvd25sb2FkRXJyb3JzQnRuLmFkZEV2ZW50TGlzdGVuZXIoImNsaWNrIiwoKT0+ewogICAgaWYoIXZhbGlkYXRpb24uZXJyb3JDc3YpIHJldHVybjsKICAgIGNvbnN0IG5hbWU9KGVsLnByb2plY3ROYW1lLnZhbHVlfHwicHJvamVjdCIpLnRyaW0oKS5yZXBsYWNlKC9bXlx3XC1dKy9nLCJfIil8fCJwcm9qZWN0IjsKICAgIGRvd25sb2FkVGV4dChgJHtuYW1lfV9lcnJvcnMuY3N2YCwgdmFsaWRhdGlvbi5lcnJvckNzdiwgInRleHQvY3N2O2NoYXJzZXQ9dXRmLTgiKTsKICB9KTsKICBlbC5kb3dubG9hZE5vcm1hbGl6ZWRCdG4uYWRkRXZlbnRMaXN0ZW5lcigiY2xpY2siLCgpPT57CiAgICBpZighdmFsaWRhdGlvbi5ub3JtYWxpemVkQ3N2KSByZXR1cm47CiAgICBjb25zdCBuYW1lPShlbC5wcm9qZWN0TmFtZS52YWx1ZXx8InByb2plY3QiKS50cmltKCkucmVwbGFjZSgvW15cd1wtXSsvZywiXyIpfHwicHJvamVjdCI7CiAgICBkb3dubG9hZFRleHQoYCR7bmFtZX1fbm9ybWFsaXplZC5jc3ZgLCB2YWxpZGF0aW9uLm5vcm1hbGl6ZWRDc3YsICJ0ZXh0L2NzdjtjaGFyc2V0PXV0Zi04Iik7CiAgfSk7CgogIGVsLmJ1c2luZXNzRmlsdGVyLmFkZEV2ZW50TGlzdGVuZXIoImNoYW5nZSIsKCk9PnsgYXBwbHlGaWx0ZXJzQW5kUmVjb21wdXRlKCk7IHJlbmRlcigpOyB9KTsKICBlbC5kYXRlRmlsdGVyLmFkZEV2ZW50TGlzdGVuZXIoImNoYW5nZSIsKCk9PnsgYXBwbHlGaWx0ZXJzQW5kUmVjb21wdXRlKCk7IHJlbmRlcigpOyB9KTsKICBlbC5rZXl3b3JkU2VsZWN0LmFkZEV2ZW50TGlzdGVuZXIoImNoYW5nZSIscmVuZGVyKTsKCiAgLy8gcmVuZGVyIGNvbnRyb2xzCiAgW2VsLm1heFJhbmssIGVsLmdyaWRTaXplLCBlbC5wb3dlciwgZWwucmFkaXVzUHgsIGVsLmdhdXNzU2lnbWFdLmZvckVhY2goaW5wPT5pbnAuYWRkRXZlbnRMaXN0ZW5lcigiY2hhbmdlIixzY2hlZHVsZVJlbmRlcikpOwogIFsKICAgIGVsLmludGVycE1vZGUsIGVsLmNvbG9yTW9kZSwgZWwuYnVja2V0Q3V0cywgZWwubWFza01vZGUsIGVsLmJnTW9kZSwgZWwubGFiZWxzTW9kZSwKICAgIGVsLnZpZXdNb2RlLCBlbC5sZWdlbmRNb2RlLCBlbC5pbnNwZWN0TW9kZSwgZWwucHJldmlld01vZGUsIGVsLm1pc3NpbmdQb2xpY3kKICBdLmZvckVhY2goc2VsPT5zZWwuYWRkRXZlbnRMaXN0ZW5lcigiY2hhbmdlIiwoKT0+eyBlbC5idWNrZXRDdXRzLmRpc2FibGVkID0gZWwuY29sb3JNb2RlLnZhbHVlIT09ImJ1Y2tldHMiOyBzY2hlZHVsZVJlbmRlcigpOyB9KSk7CiAgW2VsLmJpekxhdCwgZWwuYml6TG5nLCBlbC5yaW5nc10uZm9yRWFjaChpbnA9PmlucC5hZGRFdmVudExpc3RlbmVyKCJjaGFuZ2UiLHNjaGVkdWxlUmVuZGVyKSk7CgogIGVsLnJlbmRlckJ0bi5hZGRFdmVudExpc3RlbmVyKCJjbGljayIscmVuZGVyKTsKICBlbC5leHBvcnRQbmdCdG4uYWRkRXZlbnRMaXN0ZW5lcigiY2xpY2siLGV4cG9ydFBORyk7CiAgZWwuZXhwb3J0U3ZnQnRuLmFkZEV2ZW50TGlzdGVuZXIoImNsaWNrIixleHBvcnRTVkcpOwogIGVsLnJlcG9ydEJ0bi5hZGRFdmVudExpc3RlbmVyKCJjbGljayIsb3BlblJlcG9ydCk7CgogIGVsLmV4cG9ydFBpbnNCdG4uYWRkRXZlbnRMaXN0ZW5lcigiY2xpY2siLCgpPT57CiAgICBjb25zdCBuYW1lPShlbC5wcm9qZWN0TmFtZS52YWx1ZXx8InByb2plY3QiKS50cmltKCkucmVwbGFjZSgvW15cd1wtXSsvZywiXyIpfHwicHJvamVjdCI7CiAgICBkb3dubG9hZFRleHQoYCR7bmFtZX1fcGlucy5jc3ZgLCBwaW5zVG9DU1YocGlucyksICJ0ZXh0L2NzdjtjaGFyc2V0PXV0Zi04Iik7CiAgfSk7CiAgZWwuY2xlYXJQaW5zQnRuLmFkZEV2ZW50TGlzdGVuZXIoImNsaWNrIiwoKT0+eyBwaW5zPVtdOyB1cGRhdGVQaW5zUGlsbCgpOyByZW5kZXIoKTsgfSk7CgogIC8vIEdlb0pTT04KICBlbC5nZW9GaWxlLmFkZEV2ZW50TGlzdGVuZXIoImNoYW5nZSIsIGFzeW5jICgpPT57CiAgICBjb25zdCBmPWVsLmdlb0ZpbGUuZmlsZXM/LlswXTsgaWYoIWYpIHJldHVybjsKICAgIHRyeXsKICAgICAgY29uc3QgdGV4dD1hd2FpdCByZWFkRmlsZUFzVGV4dChmKTsKICAgICAgc2V0R2VvSlNPTihKU09OLnBhcnNlKHRleHQpKTsKICAgICAgaWYoZWwubWFza01vZGUudmFsdWU9PT0ib2ZmIikgZWwubWFza01vZGUudmFsdWU9Imdlb2pzb24iOwogICAgICBzZXRTdGF0dXMoYEdlb0pTT04gbG9hZGVkOiAke2YubmFtZX1gKTsKICAgICAgcmVuZGVyKCk7CiAgICB9IGNhdGNoKGUpeyBzZXRTdGF0dXMoIkdlb0pTT04gbG9hZCBmYWlsZWQ6ICIrKGU/Lm1lc3NhZ2V8fFN0cmluZyhlKSkpOyB9CiAgfSk7CiAgZWwuY2xlYXJHZW9CdG4uYWRkRXZlbnRMaXN0ZW5lcigiY2xpY2siLGNsZWFyR2VvKTsKICBlbC5jb3B5R2VvQnRuLmFkZEV2ZW50TGlzdGVuZXIoImNsaWNrIiwgYXN5bmMgKCk9PnsKICAgIHRyeXsKICAgICAgaWYoIWdlb2pzb24pIHRocm93IG5ldyBFcnJvcigiTm8gR2VvSlNPTi4iKTsKICAgICAgYXdhaXQgY29weVRleHQoSlNPTi5zdHJpbmdpZnkoZ2VvanNvbixudWxsLDIpKTsKICAgICAgc2V0U3RhdHVzKCJDb3BpZWQgR2VvSlNPTi4iKTsKICAgIH0gY2F0Y2goZSl7IHNldFN0YXR1cygiQ29weSBmYWlsZWQ6ICIrKGU/Lm1lc3NhZ2V8fFN0cmluZyhlKSkpOyB9CiAgfSk7CgogIC8vIERyYXdpbmcgYnV0dG9ucwogIGVsLmRyYXdUb2dnbGVCdG4uYWRkRXZlbnRMaXN0ZW5lcigiY2xpY2siLCgpPT57IGlmKGRyYXdBY3RpdmUpIHN0b3BEcmF3aW5nKCJEcmF3aW5nIGNhbmNlbGxlZC4iKTsgZWxzZSBzdGFydERyYXdpbmcoKTsgfSk7CiAgZWwuZHJhd1VuZG9CdG4uYWRkRXZlbnRMaXN0ZW5lcigiY2xpY2siLHVuZG9EcmF3KTsKICBlbC5kcmF3QWRkSG9sZUJ0bi5hZGRFdmVudExpc3RlbmVyKCJjbGljayIsYWRkSG9sZSk7CiAgZWwuZHJhd0ZpbmlzaEJ0bi5hZGRFdmVudExpc3RlbmVyKCJjbGljayIsZmluaXNoRHJhdyk7CgogIC8vIFByb2plY3QKICBlbC5zYXZlUHJvamVjdEJ0bi5hZGRFdmVudExpc3RlbmVyKCJjbGljayIsc2F2ZVByb2plY3QpOwogIGVsLmxvYWRQcm9qZWN0QnRuLmFkZEV2ZW50TGlzdGVuZXIoImNsaWNrIiwoKT0+ZWwucHJvamVjdEZpbGUuY2xpY2soKSk7CiAgZWwucHJvamVjdEZpbGUuYWRkRXZlbnRMaXN0ZW5lcigiY2hhbmdlIiwgYXN5bmMgKCk9PnsKICAgIGNvbnN0IGY9ZWwucHJvamVjdEZpbGUuZmlsZXM/LlswXTsgaWYoIWYpIHJldHVybjsKICAgIHRyeXsKICAgICAgY29uc3QgdHh0PWF3YWl0IHJlYWRGaWxlQXNUZXh0KGYpOwogICAgICBsb2FkUHJvamVjdChKU09OLnBhcnNlKHR4dCkpOwogICAgfSBjYXRjaChlKXsgc2V0U3RhdHVzKCJMb2FkIGZhaWxlZDogIisoZT8ubWVzc2FnZXx8U3RyaW5nKGUpKSk7IH0KICB9KTsKCiAgLy8gU3RhdHMgZXhwb3J0cwogIGVsLmNvcHlTdGF0c0J0bi5hZGRFdmVudExpc3RlbmVyKCJjbGljayIsIGFzeW5jICgpPT57CiAgICB0cnl7IGlmKCFzdGF0c0NzdikgdGhyb3cgbmV3IEVycm9yKCJObyBzdGF0cy4iKTsgYXdhaXQgY29weVRleHQoc3RhdHNDc3YpOyBzZXRTdGF0dXMoIkNvcGllZCBzdGF0cyBDU1YuIik7IH0KICAgIGNhdGNoKGUpeyBzZXRTdGF0dXMoIkNvcHkgZmFpbGVkOiAiKyhlPy5tZXNzYWdlfHxTdHJpbmcoZSkpKTsgfQogIH0pOwogIGVsLmRvd25sb2FkU3RhdHNCdG4uYWRkRXZlbnRMaXN0ZW5lcigiY2xpY2siLCgpPT57CiAgICBpZighc3RhdHNDc3YpIHJldHVybjsKICAgIGNvbnN0IG5hbWU9KGVsLnByb2plY3ROYW1lLnZhbHVlfHwicHJvamVjdCIpLnRyaW0oKS5yZXBsYWNlKC9bXlx3XC1dKy9nLCJfIil8fCJwcm9qZWN0IjsKICAgIGRvd25sb2FkVGV4dChgJHtuYW1lfV9rZXl3b3JkX3N0YXRzLmNzdmAsIHN0YXRzQ3N2LCAidGV4dC9jc3Y7Y2hhcnNldD11dGYtOCIpOwogIH0pOwoKICAvLyBMb2NhdGlvbiBleHBvcnRzCiAgZWwuY29weUxvY0J0bi5hZGRFdmVudExpc3RlbmVyKCJjbGljayIsIGFzeW5jICgpPT57CiAgICB0cnl7IGlmKCFsb2NDc3YpIHRocm93IG5ldyBFcnJvcigiTm8gbG9jYXRpb25zLiIpOyBhd2FpdCBjb3B5VGV4dChsb2NDc3YpOyBzZXRTdGF0dXMoIkNvcGllZCBsb2NhdGlvbnMgQ1NWLiIpOyB9CiAgICBjYXRjaChlKXsgc2V0U3RhdHVzKCJDb3B5IGZhaWxlZDogIisoZT8ubWVzc2FnZXx8U3RyaW5nKGUpKSk7IH0KICB9KTsKICBlbC5kb3dubG9hZExvY0J0bi5hZGRFdmVudExpc3RlbmVyKCJjbGljayIsKCk9PnsKICAgIGlmKCFsb2NDc3YpIHJldHVybjsKICAgIGNvbnN0IG5hbWU9KGVsLnByb2plY3ROYW1lLnZhbHVlfHwicHJvamVjdCIpLnRyaW0oKS5yZXBsYWNlKC9bXlx3XC1dKy9nLCJfIil8fCJwcm9qZWN0IjsKICAgIGRvd25sb2FkVGV4dChgJHtuYW1lfV9sb2NhdGlvbl9yb2xsdXBzLmNzdmAsIGxvY0NzdiwgInRleHQvY3N2O2NoYXJzZXQ9dXRmLTgiKTsKICB9KTsKCiAgLy8gT3BwIGV4cG9ydHMKICBlbC5jb3B5T3BwQnRuLmFkZEV2ZW50TGlzdGVuZXIoImNsaWNrIiwgYXN5bmMgKCk9PnsKICAgIHRyeXsgaWYoIW9wcENzdikgdGhyb3cgbmV3IEVycm9yKCJObyBvcHBzLiIpOyBhd2FpdCBjb3B5VGV4dChvcHBDc3YpOyBzZXRTdGF0dXMoIkNvcGllZCBvcHBvcnR1bml0aWVzIENTVi4iKTsgfQogICAgY2F0Y2goZSl7IHNldFN0YXR1cygiQ29weSBmYWlsZWQ6ICIrKGU/Lm1lc3NhZ2V8fFN0cmluZyhlKSkpOyB9CiAgfSk7CiAgZWwuZG93bmxvYWRPcHBCdG4uYWRkRXZlbnRMaXN0ZW5lcigiY2xpY2siLCgpPT57CiAgICBpZighb3BwQ3N2KSByZXR1cm47CiAgICBjb25zdCBuYW1lPShlbC5wcm9qZWN0TmFtZS52YWx1ZXx8InByb2plY3QiKS50cmltKCkucmVwbGFjZSgvW15cd1wtXSsvZywiXyIpfHwicHJvamVjdCI7CiAgICBkb3dubG9hZFRleHQoYCR7bmFtZX1fb3Bwb3J0dW5pdGllcy5jc3ZgLCBvcHBDc3YsICJ0ZXh0L2NzdjtjaGFyc2V0PXV0Zi04Iik7CiAgfSk7CgogIGVsLnN0YXRzRmlsdGVyLmFkZEV2ZW50TGlzdGVuZXIoImlucHV0IixyZW5kZXJTdGF0c1RhYmxlKTsKICBlbC5zdGF0c1NvcnQuYWRkRXZlbnRMaXN0ZW5lcigiY2hhbmdlIixyZW5kZXJTdGF0c1RhYmxlKTsKICBlbC5sb2NGaWx0ZXIuYWRkRXZlbnRMaXN0ZW5lcigiaW5wdXQiLHJlbmRlckxvY2F0aW9uc1RhYmxlKTsKICBlbC5sb2NTb3J0LmFkZEV2ZW50TGlzdGVuZXIoImNoYW5nZSIscmVuZGVyTG9jYXRpb25zVGFibGUpOwogIGVsLm9wcE1vZGUuYWRkRXZlbnRMaXN0ZW5lcigiY2hhbmdlIiwoKT0+eyBjb21wdXRlT3Bwb3J0dW5pdGllcygpOyByZW5kZXJPcHBUYWJsZSgpOyB9KTsKICBlbC5vcHBNaW5Db3VudC5hZGRFdmVudExpc3RlbmVyKCJjaGFuZ2UiLCgpPT57IGNvbXB1dGVPcHBvcnR1bml0aWVzKCk7IHJlbmRlck9wcFRhYmxlKCk7IH0pOwoKICAvLyBDYW52YXMgZXZlbnRzCiAgZWwuY2FudmFzLmFkZEV2ZW50TGlzdGVuZXIoIm1vdXNlbW92ZSIsb25DYW52YXNNb3ZlKTsKICBlbC5jYW52YXMuYWRkRXZlbnRMaXN0ZW5lcigibW91c2VsZWF2ZSIsb25DYW52YXNMZWF2ZSk7CiAgZWwuY2FudmFzLmFkZEV2ZW50TGlzdGVuZXIoImNsaWNrIixvbkNhbnZhc0NsaWNrKTsKICBlbC5jYW52YXMuYWRkRXZlbnRMaXN0ZW5lcigiZGJsY2xpY2siLG9uQ2FudmFzRGJsQ2xpY2spOwogIHdpbmRvdy5hZGRFdmVudExpc3RlbmVyKCJrZXlkb3duIiwoZXYpPT57CiAgICBpZighZHJhd0FjdGl2ZSkgcmV0dXJuOwogICAgaWYoZXYua2V5PT09IkVzY2FwZSIpIHN0b3BEcmF3aW5nKCJEcmF3aW5nIGNhbmNlbGxlZC4iKTsKICAgIGlmKChldi5jdHJsS2V5fHxldi5tZXRhS2V5KSAmJiBldi5rZXkudG9Mb3dlckNhc2UoKT09PSJ6IikgdW5kb0RyYXcoKTsKICB9KTsKCiAgLy8gUHJldmlldyBpbml0CiAgZnVuY3Rpb24gaW5pdCgpewogICAgZWwuY3N2VGV4dC52YWx1ZSA9CmAjIFBhc3RlIENTViBoZXJlIE9SIGFkZCBDU1YgZmlsZXMuCiMgTG9uZyBleGFtcGxlOgojIGtleXdvcmQsbG9jYXRpb24sbGF0LGxuZyxyYW5rLGJ1c2luZXNzLGRhdGUsdm9sdW1lCiMgYmVzdCBkZW50aXN0LE1pZHRvd24sNDAuNzU0OSwtNzMuOTg0MCwzLEFjbWUgRGVudGFsLDIwMjYtMDItMDEsMTIwMAojCiMgV2lkZSBleGFtcGxlOgojIGxvY2F0aW9uLGxhdCxsbmcsYmVzdCBkZW50aXN0LHRlZXRoIHdoaXRlbmluZyxidXNpbmVzcyxkYXRlCiMgTWlkdG93biw0MC43NTQ5LC03My45ODQwLDMsNSxBY21lIERlbnRhbCwyMDI2LTAyLTAxCmA7CiAgICBlbC5nZW9QaWxsLnRleHRDb250ZW50PSJObyBHZW9KU09OIjsKICAgIGVsLmJ1Y2tldEN1dHMuZGlzYWJsZWQgPSBlbC5jb2xvck1vZGUudmFsdWUgIT09ICJidWNrZXRzIjsKICAgIHRvZ2dsZVdpZGVCbG9ja3MoKTsKICAgIHRvZ2dsZVdpZGVWb2x1bWVVSSgpOwogICAgdXBkYXRlUGluc1BpbGwoKTsKICAgIGRyYXdCYWNrZ3JvdW5kKCJkYXJrIik7CiAgICBlbmFibGVDb250cm9scyhmYWxzZSk7CiAgICBzZXRTdGF0dXMoIlBhc3RlL2FkZCBDU1Yg4oaSIERldGVjdC9BdXRvLW1hcCDihpIgQnVpbGQgZGF0YXNldCDihpIgUmVuZGVyLiIpOwogIH0KICBpbml0KCk7Cn0pKCk7Cjwvc2NyaXB0Pgo8L2JvZHk+CjwvaHRtbD4=","embed":""}
Keyword Rank Heatmap Suite (Offline, Single-File)
Import CSV(s) → normalize → filter by business/date → heatmap + boundaries + polygon draw/holes + stats + opportunities + exports + project save/load. No data No GeoJSON Draw: off Pins: 0
Supports long (keyword/location/lat/lng/rank) and wide (keywords as columns). Optional:
business, date, volume.
Clipboard requires http://localhost or https (not file://).
Auto detects long vs wide.
Mapping (long)
Mapping (wide)
No validation yet.
Lat/Lng rings approximate miles. X/Y mode uses your units.
No data.
| Keyword | Count | Avg | Med | Best | Worst | Top3% | Top10% | Top20% |
|---|
| Location | Count | Avg | Top3% | Top10% | Top20% | Worst keyword |
|---|
| Keyword | Avg | Top% | Just-miss% | Volume | Score |
|---|
No errors.
Hover: —