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ZD4KICAgIDxtZXRhIGNoYXJzZXQ9InV0Zi04Ij4KICAgIDxtZXRhIG5hbWU9InZpZXdwb3J0IiBjb250ZW50PSJ3aWR0aD1kZXZpY2Utd2lkdGgsIHVzZXItc2NhbGFibGU9bm8iPgogICAgCiAgICAgIDxzY3JpcHQ+CiAgICAgICAgZnVuY3Rpb24gc2V0TWVzc2FnZShtc2cpIHsKICAgICAgICAgIGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdtZXNzYWdlJykudGV4dENvbnRlbnQgPSBtc2c7CiAgICAgICAgfQogICAgICAgIGZ1bmN0aW9uIG5vdGlmeURpZEZpbmlzaExvYWRpbmcoKSB7CiAgICAgICAgICBpZiAocGx1Z2luLmRpZEZpbmlzaExvYWRpbmcpCiAgICAgICAgICAgIHBsdWdpbi5kaWRGaW5pc2hMb2FkaW5nKCk7CgogICAgICAgICAgaWYgKHBsdWdpbi5kaWRGaW5pc2hJY29uUmVwb3NpdGlvbkZvclRlc3RpbmcpCiAgICAgICAgICAgIHBsdWdpbi5kaWRGaW5pc2hJY29uUmVwb3NpdGlvbkZvclRlc3RpbmcoKTsKICAgICAgICB9CiAgICAgIDwvc2NyaXB0PgogICAgCiAgICAKICAgIDxzdHlsZT4vKiBDb3B5cmlnaHQgKGMpIDIwMTIgVGhlIENocm9taXVtIEF1dGhvcnMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCiAqIFVzZSBvZiB0aGlzIHNvdXJjZSBjb2RlIGlzIGdvdmVybmVkIGJ5IGEgQlNELXN0eWxlIGxpY2Vuc2UgdGhhdCBjYW4gYmUKICogZm91bmQgaW4gdGhlIExJQ0VOU0UgZmlsZS4gKi8KCmh0bWwsIGJvZHkgewogIC13ZWJraXQtdXNlci1zZWxlY3Q6IG5vbmU7CiAgZm9udC1mYW1pbHk6IHNhbnMtc2VyaWY7CiAgaGVpZ2h0OiAxMDAlOwogIG1hcmdpbjogMDsKICBvdmVyZmxvdzogaGlkZGVuOwogIHRleHQtYWxpZ246IGNlbnRlcjsKICB3aWR0aDogMTAwJTsKfQoKaDEgewogIGRpc3BsYXk6IG5vbmU7CiAgZm9udC1zaXplOiAxMHB0OwogIGZvbnQtd2VpZ2h0OiBub3JtYWw7CiAgcGFkZGluZzogMHB0IDEwcHQ7Cn0KCnAgewogIGZvbnQtc2l6ZTogOHB0OwogIHBhZGRpbmc6IDBwdCAxNHB0Owp9CgojdCB7CiAgYmFja2dyb3VuZC1jb2xvcjogI2Y3ZjdmNzsKICBjb2xvcjogIzY0NjQ2NDsKfQoKI291dGVyIHsKICBhbGlnbi1pdGVtczogY2VudGVyOwogIGJveC1zaXppbmc6IGJvcmRlci1ib3g7CiAgZGlzcGxheTogZmxleDsKICBoZWlnaHQ6IDEwMCU7CiAganVzdGlmeS1jb250ZW50OiBjZW50ZXI7CiAgcG9zaXRpb246IGFic29sdXRlOwogIHdpZHRoOiAxMDAlOwogIGZsZXgtZGlyZWN0aW9uOiBjb2x1bW47Cn0KCi5pY29uIHsKICBtYXgtaGVpZ2h0OiAxMDAlOwogIG1heC13aWR0aDogMTAwJTsKICBvcGFjaXR5OiAuMzsKfQoKQG1lZGlhIChvcmllbnRhdGlvbjogbGFuZHNjYXBlKSBhbmQgKG1pbi1oZWlnaHQ6IDJlbSkgYW5kIChtaW4td2lkdGg6IDE0ZW0pIHsKICAjb3V0ZXIgewogICAgZmxleC1kaXJlY3Rpb246IHJvdzsKICB9CiAgLmljb24gewogICAgbWF4LWhlaWdodDogMTAwJTsKICAgIG1heC13aWR0aDogNTAlOwogIH0KICBoMSB7CiAgICBkaXNwbGF5OiBibG9jazsKICB9Cn0KCkBtZWRpYSAobWluLWhlaWdodDogN2VtKSBhbmQgKG1pbi13aWR0aDogNmVtKSB7CiAgI291dGVyIHsKICAgIGZsZXgtZGlyZWN0aW9uOiBjb2x1bW47CiAgfQogIC5pY29uIHsKICAgIG1heC1oZWlnaHQ6IDUwJTsKICAgIG1heC13aWR0aDogMTAwJTsKICB9CiAgaDEgewogICAgZGlzcGxheTogYmxvY2s7CiAgfQp9Cjwvc3R5bGU+CiAgPC9oZWFkPgogIDxib2R5IGlkPSJ0IiBvbmxvYWQ9Im5vdGlmeURpZEZpbmlzaExvYWRpbmcoKTsiPgogICAgPGRpdiBpMThuLXZhbHVlcz0idGl0bGU6bmFtZSIgaWQ9Im91dGVyIj4KICAgICAgPGltZyBjbGFzcz0iaWNvbiIKICAgICAgICAgICBzcmM9ImRhdGE6aW1hZ2Uvc3ZnK3htbDtiYXNlNjQsUEhOMlp5QjRiV3h1Y3owaWFIUjBjRG92TDNkM2R5NTNNeTV2Y21jdk1qQXdNQzl6ZG1jaUlIZHBaSFJvUFNJME9IQjRJaUJvWldsbmFIUTlJalE0Y0hnaUlIWnBaWGRDYjNnOUlqQWdNQ0EwT0NBME9DSWdabWxzYkQwaUl6WXlOakkyTWlJK0NpQWdJQ0E4Y0dGMGFDQmtQU0pOTUNBd2FEUTRkalE0U0RCNklpQm1hV3hzUFNKdWIyNWxJaTgrQ2lBZ0lDQThjR0YwYUNCa1BTSk5OREVnTWpKb0xUTjJMVGhqTUMweUxqSXhMVEV1TnprdE5DMDBMVFJvTFRoV04yTXdMVEl1TnpZdE1pNHlOQzAxTFRVdE5YTXROU0F5TGpJMExUVWdOWFl6U0RoakxUSXVNakVnTUMwekxqazRJREV1TnprdE15NDVPQ0EwYkMwdU1ERWdOeTQyU0Rkak1pNDVPQ0F3SURVdU5DQXlMalF5SURVdU5DQTFMalJUT1M0NU9DQXpNaTQwSURjZ016SXVORWcwTGpBeFREUWdOREJqTUNBeUxqSXhJREV1TnprZ05DQTBJRFJvTnk0MmRpMHpZekF0TWk0NU9DQXlMalF5TFRVdU5DQTFMalF0TlM0MElESXVPVGdnTUNBMUxqUWdNaTQwTWlBMUxqUWdOUzQwZGpOSU16UmpNaTR5TVNBd0lEUXRNUzQzT1NBMExUUjJMVGhvTTJNeUxqYzJJREFnTlMweUxqSTBJRFV0TlhNdE1pNHlOQzAxTFRVdE5Yb2lMejRLUEM5emRtYytDZz09Ij4KICAgICAgPGgxIGlkPSJtZXNzYWdlIj4kaTE4bnttZXNzYWdlfTwvaDE+CiAgICA8L2Rpdj4KICA8L2JvZHk+CjwvaHRtbD4KPCFkb2N0eXBlIGh0bWw+CjxodG1sPgogIDxoZWFkPgogICAgPG1ldGEgY2hhcnNldD0idXRmLTgiPgogICAgPG1ldGEgbmFtZT0idmlld3BvcnQiIGNvbnRlbnQ9IndpZHRoPWRldmljZS13aWR0aCwgdXNlci1zY2FsYWJsZT1ubyI+CiAgICA8c3R5bGU+LyogQ29weXJpZ2h0IChjKSAyMDEyIFRoZSBDaHJvbWl1bSBBdXRob3JzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgogKiBVc2Ugb2YgdGhpcyBzb3VyY2UgY29kZSBpcyBnb3Zlcm5lZCBieSBhIEJTRC1zdHlsZSBsaWNlbnNlIHRoYXQgY2FuIGJlCiAqIGZvdW5kIGluIHRoZSBMSUNFTlNFIGZpbGUuICovCgpodG1sLCBib2R5IHsKICAtd2Via2l0LXVzZXItc2VsZWN0OiBub25lOwogIGZvbnQtZmFtaWx5OiBzYW5zLXNlcmlmOwogIGhlaWdodDogMTAwJTsKICBtYXJnaW46IDA7CiAgb3ZlcmZsb3c6IGhpZGRlbjsKICB0ZXh0LWFsaWduOiBjZW50ZXI7CiAgd2lkdGg6IDEwMCU7Cn0KCmgxIHsKICBkaXNwbGF5OiBub25lOwogIGZvbnQtc2l6ZTogMTBwdDsKICBmb250LXdlaWdodDogbm9ybWFsOwogIHBhZGRpbmc6IDBwdCAxMHB0Owp9CgpwIHsKICBmb250LXNpemU6IDhwdDsKICBwYWRkaW5nOiAwcHQgMTRwdDsKfQoKI3QgewogIGJhY2tncm91bmQtY29sb3I6ICNmN2Y3Zjc7CiAgY29sb3I6ICM2NDY0NjQ7Cn0KCiNvdXRlciB7CiAgYWxpZ24taXRlbXM6IGNlbnRlcjsKICBib3gtc2l6aW5nOiBib3JkZXItYm94OwogIGRpc3BsYXk6IGZsZXg7CiAgaGVpZ2h0OiAxMDAlOwogIGp1c3RpZnktY29udGVudDogY2VudGVyOwogIHBvc2l0aW9uOiBhYnNvbHV0ZTsKICB3aWR0aDogMTAwJTsKICBmbGV4LWRpcmVjdGlvbjogY29sdW1uOwp9CgouaWNvbiB7CiAgbWF4LWhlaWdodDogMTAwJTsKICBtYXgtd2lkdGg6IDEwMCU7CiAgb3BhY2l0eTogLjM7Cn0KCkBtZWRpYSAob3JpZW50YXRpb246IGxhbmRzY2FwZSkgYW5kIChtaW4taGVpZ2h0OiAyZW0pIGFuZCAobWluLXdpZHRoOiAxNGVtKSB7CiAgI291dGVyIHsKICAgIGZsZXgtZGlyZWN0aW9uOiByb3c7CiAgfQogIC5pY29uIHsKICAgIG1heC1oZWlnaHQ6IDEwMCU7CiAgICBtYXgtd2lkdGg6IDUwJTsKICB9CiAgaDEgewogICAgZGlzcGxheTogYmxvY2s7CiAgfQp9CgpAbWVkaWEgKG1pbi1oZWlnaHQ6IDdlbSkgYW5kIChtaW4td2lkdGg6IDZlbSkgewogICNvdXRlciB7CiAgICBmbGV4LWRpcmVjdGlvbjogY29sdW1uOwogIH0KICAuaWNvbiB7CiAgICBtYXgtaGVpZ2h0OiA1MCU7CiAgICBtYXgtd2lkdGg6IDEwMCU7CiAgfQogIGgxIHsKICAgIGRpc3BsYXk6IGJsb2NrOwogIH0KfQo8L3N0eWxlPgogIDwvaGVhZD4KICA8Ym9keSBpZD0idCIgb25Mb2FkPSJpbnNlcnRMaW5rKCkiPgogICAgPGRpdiBpMThuLXZhbHVlcz0idGl0bGU6bmFtZSIgaWQ9Im91dGVyIj4KICAgICAgPGltZyBjbGFzcz0iaWNvbiIKICAgICAgICAgICBzcmM9ImRhdGE6aW1hZ2Uvc3ZnK3htbDtiYXNlNjQsUEhOMlp5QjRiV3h1Y3owaWFIUjBjRG92TDNkM2R5NTNNeTV2Y21jdk1qQXdNQzl6ZG1jaUlIZHBaSFJvUFNJME9IQjRJaUJvWldsbmFIUTlJalE0Y0hnaUlIWnBaWGRDYjNnOUlqQWdNQ0EwT0NBME9DSWdabWxzYkQwaUl6WXlOakkyTWlJK0NpQWdJQ0E4Y0dGMGFDQmtQU0pOTUNBd2FEUTRkalE0U0RCNklpQm1hV3hzUFNKdWIyNWxJaTgrQ2lBZ0lDQThjR0YwYUNCa1BTSk5OREVnTWpKb0xUTjJMVGhqTUMweUxqSXhMVEV1TnprdE5DMDBMVFJvTFRoV04yTXdMVEl1TnpZdE1pNHlOQzAxTFRVdE5YTXROU0F5TGpJMExUVWdOWFl6U0RoakxUSXVNakVnTUMwekxqazRJREV1TnprdE15NDVPQ0EwYkMwdU1ERWdOeTQyU0Rkak1pNDVPQ0F3SURVdU5DQXlMalF5SURVdU5DQTFMalJUT1M0NU9DQXpNaTQwSURjZ016SXVORWcwTGpBeFREUWdOREJqTUNBeUxqSXhJREV1TnprZ05DQTBJRFJvTnk0MmRpMHpZekF0TWk0NU9DQXlMalF5TFRVdU5DQTFMalF0TlM0MElESXVPVGdnTUNBMUxqUWdNaTQwTWlBMUxqUWdOUzQwZGpOSU16UmpNaTR5TVNBd0lEUXRNUzQzT1NBMExUUjJMVGhvTTJNeUxqYzJJREFnTlMweUxqSTBJRFV0TlhNdE1pNHlOQzAxTFRVdE5Yb2lMejRLUEM5emRtYytDZz09Ij4KICAgICAgPGgxIGlkPSJtZXNzYWdlIj4kaTE4bnttZXNzYWdlfTwvaDE+CiAgICA8L2Rpdj4KICA8L2JvZHk+CjwvaHRtbD4KPCFkb2N0eXBlIGh0bWw+CjxodG1sPgogIDxoZWFkPgogICAgPG1ldGEgY2hhcnNldD0idXRmLTgiPgogICAgPG1ldGEgbmFtZT0idmlld3BvcnQiIGNvbnRlbnQ9IndpZHRoPWRldmljZS13aWR0aCwgdXNlci1zY2FsYWJsZT1ubyI+CiAgICA8c3R5bGU+CiAgICAgIGh0bWwsCiAgICAgIGJvZHkgewogICAgICAgIGhlaWdodDogMTAwJTsKICAgICAgICB3aWR0aDogMTAwJTsKICAgICAgfQoKICAgICAgYm9keSB7CiAgICAgICAgYmFja2dyb3VuZC1jb2xvcjogI2Y1ZjVmNTsgIC8qIGdvb2dsZS1ncmV5LTEwMCAqLwogICAgICAgIG1hcmdpbjogMDsKICAgICAgfQoKICAgICAgc3ZnIHsKICAgICAgICBoZWlnaHQ6IDQwcHg7CiAgICAgICAgd2lkdGg6IDQwcHg7CiAgICAgIH0KCiAgICAgIHBhdGggewogICAgICAgIGZpbGw6ICNiZGJkYmQ7ICAvKiBnb29nbGUtZ3JleS00MDAgKi8KICAgICAgfQoKICAgICAgI2ljb24tY29udGFpbmVyIHsKICAgICAgICBhbGlnbi1pdGVtczogY2VudGVyOwogICAgICAgIGRpc3BsYXk6IGZsZXg7CiAgICAgICAgaGVpZ2h0OiAxMDAlOwogICAgICAgIGp1c3RpZnktY29udGVudDogY2VudGVyOwogICAgICAgIHdpZHRoOiAxMDAlOwogICAgICB9CgogICAgICAjZm9vdGVyIHsKICAgICAgICBhbGlnbi1pdGVtczogY2VudGVyOwogICAgICAgIGJhY2tncm91bmQtY29sb3I6ICM0Mjg1ZjQ7ICAvKiBnb29nbGUtYmx1ZS01MDAgKi8KICAgICAgICBib3JkZXItcmFkaXVzOiAycHg7CiAgICAgICAgYm90dG9tOiAwOwogICAgICAgIGNvbG9yOiB3aGl0ZTsKICAgICAgICBkaXNwbGF5OiBmbGV4OwogICAgICAgIGZvbnQtc2l6ZTogMTRweDsKICAgICAgICBqdXN0aWZ5LWNvbnRlbnQ6IHNwYWNlLWJldHdlZW47CiAgICAgICAgbGVmdDogMDsKICAgICAgICBtYXgtaGVpZ2h0OiA1MnB4OwogICAgICAgIG1pbi1oZWlnaHQ6IDIwcHg7CiAgICAgICAgcGFkZGluZzogMTRweCAyNHB4OwogICAgICAgIHBvc2l0aW9uOiBhYnNvbHV0ZTsKICAgICAgICByaWdodDogMDsKICAgICAgfQoKICAgICAgcCwKICAgICAgYSB7CiAgICAgICAgbGluZS1oZWlnaHQ6IDIwcHg7CiAgICAgIH0KCiAgICAgIHAgewogICAgICAgIGZvbnQtZmFtaWx5OiBSb2JvdG87CiAgICAgICAgbWFyZ2luOiAwOwogICAgICB9CgogICAgICBhIHsKICAgICAgICBmb250LWZhbWlseTogUm9ib3RvIE1lZGl1bTsKICAgICAgICBtYXJnaW4tbGVmdDogNDhweDsKICAgICAgICB0ZXh0LXRyYW5zZm9ybTogdXBwZXJjYXNlOwogICAgICB9CgogICAgICBhOmxpbmssCiAgICAgIGE6dmlzaXRlZCB7CiAgICAgICAgY29sb3I6IHdoaXRlOwogICAgICAgIHRleHQtZGVjb3JhdGlvbjogbm9uZTsKICAgICAgfQoKICAgIDwvc3R5bGU+CiAgPC9oZWFkPgogIDxib2R5PgogICAgPGRpdiBpZD0iaWNvbi1jb250YWluZXIiPgogICAgICA8IS0tIE1hdGVyaWFsIERlc2lnbiBQREYgaWNvbiAtLT4KICAgICAgPHN2ZyB2aWV3Ym94PSIwIDAgMjQgMjQiPgogICAgICAgIDxwYXRoIGQ9Ik03IDExLjVoMXYtMUg3djF6TTE5IDNINWMtMS4xIDAtMiAuOS0yIDJ2MTRjMCAxLjEuOSAyIDIgMmgxNGMxLjEgMCAyLS45IDItMlY1YzAtMS4xLS45LTItMi0yem0tOS41IDguNWMwIC44My0uNjcgMS41LTEuNSAxLjVIN3YySDUuNVY5SDhjLjgzIDAgMS41LjY3IDEuNSAxLjV2MXptMTAtMUgxN3YxaDEuNVYxM0gxN3YyaC0xLjVWOWg0djEuNXptLTUgM2MwIC44My0uNjcgMS41LTEuNSAxLjVoLTIuNVY5SDEzYy44MyAwIDEuNS42NyAxLjUgMS41djN6bS0yLjUgMGgxdi0zaC0xdjN6Ij48L3BhdGg+CiAgICAgIDwvc3ZnPgogICAgPC9kaXY+CiAgICA8ZGl2IGlkPSJmb290ZXIiIGkxOG4tdmFsdWVzPSJ0aXRsZTpuYW1lIj4KICAgICAgPHA+JGkxOG57ZmlsZU5hbWV9PC9wPgogICAgICA8YSBocmVmPSIjIiBvbmNsaWNrPSJwbHVnaW4ub3BlblBERigpIj5WaWV3IFBERjwvYT4KICAgIDwvZGl2PgogIDwvYm9keT4KPC9odG1sPgo8IWRvY3R5cGUgaHRtbD4KPGh0bWw+CjxoZWFkPgogIDxtZXRhIGNoYXJzZXQ9InV0Zi04Ij4KICA8bWV0YSBuYW1lPSJ2aWV3cG9ydCIgY29udGVudD0id2lkdGg9ZGV2aWNlLXdpZHRoLCB1c2VyLXNjYWxhYmxlPW5vIj4KICA8c2NyaXB0PgogICAgZnVuY3Rpb24gc2V0TWVzc2FnZShtc2cpIHsKICAgICAgZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ21lc3NhZ2UnKS50ZXh0Q29udGVudCA9IG1zZzsKICAgIH0KICAgIGZ1bmN0aW9uIG5vdGlmeURpZEZpbmlzaExvYWRpbmcoKSB7CiAgICAgIGlmIChwbHVnaW4uZGlkRmluaXNoTG9hZGluZykKICAgICAgICBwbHVnaW4uZGlkRmluaXNoTG9hZGluZygpOwoKICAgICAgaWYgKHBsdWdpbi5kaWRGaW5pc2hJY29uUmVwb3NpdGlvbkZvclRlc3RpbmcpCiAgICAgICAgcGx1Z2luLmRpZEZpbmlzaEljb25SZXBvc2l0aW9uRm9yVGVzdGluZygpOwogICAgfQogIDwvc2NyaXB0PgogIDxzdHlsZT4vKiBDb3B5cmlnaHQgKGMpIDIwMTIgVGhlIENocm9taXVtIEF1dGhvcnMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCiAqIFVzZSBvZiB0aGlzIHNvdXJjZSBjb2RlIGlzIGdvdmVybmVkIGJ5IGEgQlNELXN0eWxlIGxpY2Vuc2UgdGhhdCBjYW4gYmUKICogZm91bmQgaW4gdGhlIExJQ0VOU0UgZmlsZS4gKi8KCmh0bWwsIGJvZHkgewogIC13ZWJraXQtdXNlci1zZWxlY3Q6IG5vbmU7CiAgZm9udC1mYW1pbHk6IHNhbnMtc2VyaWY7CiAgaGVpZ2h0OiAxMDAlOwogIG1hcmdpbjogMDsKICBvdmVyZmxvdzogaGlkZGVuOwogIHRleHQtYWxpZ246IGNlbnRlcjsKICB3aWR0aDogMTAwJTsKfQoKaDEgewogIGRpc3BsYXk6IG5vbmU7CiAgZm9udC1zaXplOiAxMHB0OwogIGZvbnQtd2VpZ2h0OiBub3JtYWw7CiAgcGFkZGluZzogMHB0IDEwcHQ7Cn0KCnAgewogIGZvbnQtc2l6ZTogOHB0OwogIHBhZGRpbmc6IDBwdCAxNHB0Owp9CgojdCB7CiAgYmFja2dyb3VuZC1jb2xvcjogI2Y3ZjdmNzsKICBjb2xvcjogIzY0NjQ2NDsKfQoKI291dGVyIHsKICBhbGlnbi1pdGVtczogY2VudGVyOwogIGJveC1zaXppbmc6IGJvcmRlci1ib3g7CiAgZGlzcGxheTogZmxleDsKICBoZWlnaHQ6IDEwMCU7CiAganVzdGlmeS1jb250ZW50OiBjZW50ZXI7CiAgcG9zaXRpb246IGFic29sdXRlOwogIHdpZHRoOiAxMDAlOwogIGZsZXgtZGlyZWN0aW9uOiBjb2x1bW47Cn0KCi5pY29uIHsKICBtYXgtaGVpZ2h0OiAxMDAlOwogIG1heC13aWR0aDogMTAwJTsKICBvcGFjaXR5OiAuMzsKfQoKQG1lZGlhIChvcmllbnRhdGlvbjogbGFuZHNjYXBlKSBhbmQgKG1pbi1oZWlnaHQ6IDJlbSkgYW5kIChtaW4td2lkdGg6IDE0ZW0pIHsKICAjb3V0ZXIgewogICAgZmxleC1kaXJlY3Rpb246IHJvdzsKICB9CiAgLmljb24gewogICAgbWF4LWhlaWdodDogMTAwJTsKICAgIG1heC13aWR0aDogNTAlOwogIH0KICBoMSB7CiAgICBkaXNwbGF5OiBibG9jazsKICB9Cn0KCkBtZWRpYSAobWluLWhlaWdodDogN2VtKSBhbmQgKG1pbi13aWR0aDogNmVtKSB7CiAgI291dGVyIHsKICAgIGZsZXgtZGlyZWN0aW9uOiBjb2x1bW47CiAgfQogIC5pY29uIHsKICAgIG1heC1oZWlnaHQ6IDUwJTsKICAgIG1heC13aWR0aDogMTAwJTsKICB9CiAgaDEgewogICAgZGlzcGxheTogYmxvY2s7CiAgfQp9Cjwvc3R5bGU+CiAgPHN0eWxlPgogICNvdXRlciB7CiAgICBjdXJzb3I6IHBvaW50ZXI7CiAgfQogIDwvc3R5bGU+CjwvaGVhZD4KPGJvZHkgaWQ9InQiIG9ubG9hZD0ibm90aWZ5RGlkRmluaXNoTG9hZGluZygpOyI+CiAgPGRpdiBpMThuLXZhbHVlcz0idGl0bGU6bmFtZSIgaWQ9Im91dGVyIj4KICAgIDxpbWcgY2xhc3M9Imljb24iCiAgICAgICAgIHNyYz0iZGF0YTppbWFnZS9zdmcreG1sO2Jhc2U2NCxQSE4yWnlCNGJXeHVjejBpYUhSMGNEb3ZMM2QzZHk1M015NXZjbWN2TWpBd01DOXpkbWNpSUhkcFpIUm9QU0kwT0hCNElpQm9aV2xuYUhROUlqUTRjSGdpSUhacFpYZENiM2c5SWpBZ01DQTBPQ0EwT0NJZ1ptbHNiRDBpSXpZeU5qSTJNaUkrQ2lBZ0lDQThjR0YwYUNCa1BTSk5NQ0F3YURRNGRqUTRTREI2SWlCbWFXeHNQU0p1YjI1bElpOCtDaUFnSUNBOGNHRjBhQ0JrUFNKTk5ERWdNakpvTFROMkxUaGpNQzB5TGpJeExURXVOemt0TkMwMExUUm9MVGhXTjJNd0xUSXVOell0TWk0eU5DMDFMVFV0TlhNdE5TQXlMakkwTFRVZ05YWXpTRGhqTFRJdU1qRWdNQzB6TGprNElERXVOemt0TXk0NU9DQTBiQzB1TURFZ055NDJTRGRqTWk0NU9DQXdJRFV1TkNBeUxqUXlJRFV1TkNBMUxqUlRPUzQ1T0NBek1pNDBJRGNnTXpJdU5FZzBMakF4VERRZ05EQmpNQ0F5TGpJeElERXVOemtnTkNBMElEUm9OeTQyZGkwell6QXRNaTQ1T0NBeUxqUXlMVFV1TkNBMUxqUXROUzQwSURJdU9UZ2dNQ0ExTGpRZ01pNDBNaUExTGpRZ05TNDBkak5JTXpSak1pNHlNU0F3SURRdE1TNDNPU0EwTFRSMkxUaG9NMk15TGpjMklEQWdOUzB5TGpJMElEVXROWE10TWk0eU5DMDFMVFV0TlhvaUx6NEtQQzl6ZG1jK0NnPT0iPgogICAgPGgxIGlkPSJtZXNzYWdlIj4kaTE4bnttZXNzYWdlfTwvaDE+CiAgPC9kaXY+CiAgPHNjcmlwdD4KICAgIHdpbmRvdy5vbmtleWRvd24gPSBmdW5jdGlvbihlKSB7CiAgICAgIGlmIChlLmtleSA9PSAnRW50ZXInIHx8IGUua2V5ID09ICcgJykgewogICAgICAgIHBsdWdpbi5zaG93UGVybWlzc2lvbkJ1YmJsZSgpOwogICAgICAgIGUucHJldmVudERlZmF1bHQoKTsKICAgICAgfQogICAgfTsKCiAgICBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnb3V0ZXInKS5vbmNsaWNrID0gZnVuY3Rpb24oKSB7CiAgICAgIHBsdWdpbi5zaG93UGVybWlzc2lvbkJ1YmJsZSgpOwogICAgfTsKICA8L3NjcmlwdD4KPC9ib2R5Pgo8L2h0bWw+CjwhZG9jdHlwZSBodG1sPgo8aHRtbD4KPGhlYWQ+CjxtZXRhIGNoYXJzZXQ9InV0Zi04Ij4KPG1ldGEgbmFtZT0idmlld3BvcnQiIGNvbnRlbnQ9IndpZHRoPWRldmljZS13aWR0aCwgdXNlci1zY2FsYWJsZT1ubyI+CjxzY3JpcHQ+CiAgd2luZG93Lm9ubG9hZCA9IGZ1bmN0aW9uKCkgewogICAgaWYgKHBsdWdpbi5kaWRGaW5pc2hMb2FkaW5nKQogICAgICBwbHVnaW4uZGlkRmluaXNoTG9hZGluZygpOwogIH07CgogIHdpbmRvdy5vbmtleWRvd24gPSBmdW5jdGlvbihlKSB7CiAgICBpZiAoZS5rZXkgPT0gJ0VudGVyJyB8fCBlLmtleSA9PSAnICcpIHsKICAgICAgcGx1Z2luLmxvYWQoKTsKICAgICAgZS5wcmV2ZW50RGVmYXVsdCgpOwogICAgfQogIH07Cjwvc2NyaXB0Pgo8c3R5bGU+LyogQ29weXJpZ2h0IChjKSAyMDEyIFRoZSBDaHJvbWl1bSBBdXRob3JzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgogKiBVc2Ugb2YgdGhpcyBzb3VyY2UgY29kZSBpcyBnb3Zlcm5lZCBieSBhIEJTRC1zdHlsZSBsaWNlbnNlIHRoYXQgY2FuIGJlCiAqIGZvdW5kIGluIHRoZSBMSUNFTlNFIGZpbGUuICovCgpodG1sLCBib2R5IHsKICAtd2Via2l0LXVzZXItc2VsZWN0OiBub25lOwogIGZvbnQtZmFtaWx5OiBzYW5zLXNlcmlmOwogIGhlaWdodDogMTAwJTsKICBtYXJnaW46IDA7CiAgb3ZlcmZsb3c6IGhpZGRlbjsKICB0ZXh0LWFsaWduOiBjZW50ZXI7CiAgd2lkdGg6IDEwMCU7Cn0KCmgxIHsKICBkaXNwbGF5OiBub25lOwogIGZvbnQtc2l6ZTogMTBwdDsKICBmb250LXdlaWdodDogbm9ybWFsOwogIHBhZGRpbmc6IDBwdCAxMHB0Owp9CgpwIHsKICBmb250LXNpemU6IDhwdDsKICBwYWRkaW5nOiAwcHQgMTRwdDsKfQoKI3QgewogIGJhY2tncm91bmQtY29sb3I6ICNmN2Y3Zjc7CiAgY29sb3I6ICM2NDY0NjQ7Cn0KCiNvdXRlciB7CiAgYWxpZ24taXRlbXM6IGNlbnRlcjsKICBib3gtc2l6aW5nOiBib3JkZXItYm94OwogIGRpc3BsYXk6IGZsZXg7CiAgaGVpZ2h0OiAxMDAlOwogIGp1c3RpZnktY29udGVudDogY2VudGVyOwogIHBvc2l0aW9uOiBhYnNvbHV0ZTsKICB3aWR0aDogMTAwJTsKICBmbGV4LWRpcmVjdGlvbjogY29sdW1uOwp9CgouaWNvbiB7CiAgbWF4LWhlaWdodDogMTAwJTsKICBtYXgtd2lkdGg6IDEwMCU7CiAgb3BhY2l0eTogLjM7Cn0KCkBtZWRpYSAob3JpZW50YXRpb246IGxhbmRzY2FwZSkgYW5kIChtaW4taGVpZ2h0OiAyZW0pIGFuZCAobWluLXdpZHRoOiAxNGVtKSB7CiAgI291dGVyIHsKICAgIGZsZXgtZGlyZWN0aW9uOiByb3c7CiAgfQogIC5pY29uIHsKICAgIG1heC1oZWlnaHQ6IDEwMCU7CiAgICBtYXgtd2lkdGg6IDUwJTsKICB9CiAgaDEgewogICAgZGlzcGxheTogYmxvY2s7CiAgfQp9CgpAbWVkaWEgKG1pbi1oZWlnaHQ6IDdlbSkgYW5kIChtaW4td2lkdGg6IDZlbSkgewogICNvdXRlciB7CiAgICBmbGV4LWRpcmVjdGlvbjogY29sdW1uOwogIH0KICAuaWNvbiB7CiAgICBtYXgtaGVpZ2h0OiA1MCU7CiAgICBtYXgtd2lkdGg6IDEwMCU7CiAgfQogIGgxIHsKICAgIGRpc3BsYXk6IGJsb2NrOwogIH0KfQo8L3N0eWxlPgo8c3R5bGU+CiNvdXRlciB7CiAgYm9yZGVyOiBub25lOwogIGZsZXgtZGlyZWN0aW9uOiByb3c7CiAgY3Vyc29yOiBwb2ludGVyOwp9Cgojc2hpZWxkaW5nIHsKICBiYWNrZ3JvdW5kLWNvbG9yOiByZ2JhKDAsIDAsIDAsIDAuNSk7CiAgaGVpZ2h0OiAxMDAlOwogIGxlZnQ6IDBweDsKICBwb3NpdGlvbjogYWJzb2x1dGU7CiAgdG9wOiAwcHg7CiAgd2lkdGg6IDEwMCU7CiAgei1pbmRleDogMjsKfQoKI3BsdWdpbi1pY29uIHsKICBvcGFjaXR5OiAwLjg7CiAgbWF4LWhlaWdodDogMTAwJTsKICBtYXgtd2lkdGg6IDEwMCU7CiAgbWluLXdpZHRoOiAwOwogIG1pbi1oZWlnaHQ6IDA7Cn0KCiNwbHVnaW4taWNvbjpob3ZlciB7CiAgb3BhY2l0eTogMC45NTsKfQoKI3Bvc3RlciB7CiAgaGVpZ2h0OiAxMDAlOwogIG9iamVjdC1maXQ6IGNvbnRhaW47CiAgd2lkdGg6IDEwMCU7CiAgei1pbmRleDogMTsKfQoKI2lubmVyLWNvbnRhaW5lciB7CiAgYWxpZ24taXRlbXM6IGNlbnRlcjsKICBkaXNwbGF5OiBmbGV4OwogIGhlaWdodDogMTAwJTsKICBqdXN0aWZ5LWNvbnRlbnQ6IGNlbnRlcjsKICBsZWZ0OiAwcHg7CiAgbWF4LWhlaWdodDogMTAwJTsKICBtYXgtd2lkdGg6IDEwMCU7CiAgcG9zaXRpb246IGFic29sdXRlOwogIHRvcDogMHB4OwogIHdpZHRoOiAxMDAlOwogIHotaW5kZXg6IDI7Cn0KPC9zdHlsZT4KPGJhc2UgaTE4bi12YWx1ZXM9ImhyZWY6YmFzZXVybCI+CjwvaGVhZD4KCjxib2R5PgogIDxkaXYgaTE4bi12YWx1ZXM9InRpdGxlOm5hbWUiIGlkPSJvdXRlciI+CiAgICA8aW1nIGlkPSJwb3N0ZXIiIGkxOG4tdmFsdWVzPSJzcmNzZXQ6cG9zdGVyIj4KICAgIDxkaXYgaWQ9InNoaWVsZGluZyI+PC9kaXY+CiAgICA8ZGl2IGlkPSJpbm5lci1jb250YWluZXIiCiAgICAgICAgIGkxOG4tdmFsdWVzPSIuc3R5bGUud2lkdGg6dmlzaWJsZVdpZHRoOy5zdHlsZS5oZWlnaHQ6dmlzaWJsZUhlaWdodCI+CiAgICAgIDxpbWcgaWQ9InBsdWdpbi1pY29uIiBzcmM9ImRhdGE6aW1hZ2UvcG5nO2Jhc2U2NCxpVkJPUncwS0dnb0FBQUFOU1VoRVVnQUFBRElBQUFBeUNBWUFBQUFlUDRpeEFBQUFBWE5TUjBJQXJzNGM2UUFBQThkSlJFRlVhQVhkV3M5dkVrRVVaa3ZaUWxvTnhKb1k0MGt4SnNETm85R0RpZitCZjRDSHBqRW1KUG9QZU1jZTFGNDA4ZFlqUWVQQmd5Y3YzdlJHNEdCTVBSRVBMU2xwQ1VXZ2dOKzNuY1ZsNlBKclo1YTZrMHgyWjJmbnZlL2JlZlBtemN3YUliVnBHZUxDeUVzaUc1TDRQc285a2J1NG5rajFDeXNTYUFRNXRybTV1VjZwVkI0ZUh4Ky9iclZhbjN1OTNzOSt2MTlGYm9sYzVUUFc4UjIreXpac0syVElwUEZZZjZMUzZQYjI5clg5L2YwTmdQc0lzQTNrV1ZPRGJTbURzaWdUMlRkQ1pqYWJ2Vnl2MTU4RDllR3N5TWU4ZjBpWmxBMHlKcksyRkU0bWt4ZXIxZW9UbU1qdk1ZQThWVkUyZFZBWG1IQzhLVTFtUHA5UGRqcWQ3NTVRenRDWXVxZ1RMSlQxVHJSWUxON1QyUXR1L0tpVHVrR0dZOGRUaXUzdDdUMkNvcWFiTWgrZU40a0JMT2pkNWtwUlFjSUhySk5WQ0RJejk0ekpMb1g0UmZhRXpLNHB6R3pxTVJQbUlGdkVtSkNSeTJWaUVnNWdzamVqMi9QVE84bGdKNVdKVGJqbXNlUEZwQStmSkd6UjljUUlGcTRtWm5CV1BZOG1KWDg0WWhRUndKbmhURlNFSFhLN21jck5adk1kR2pCUTFKcUlGYjB5NHNVTUJtM1E3RGwyS3BWS2Q1angxWGExTWdGV0VXZ085VXFFRWFnS3hTU0JMN1dTeStXdUlySjlyMEttbXd4aWhpNHVJd1lwSmtKeHR6WlRQeGRFN0lYVmFxMVdlNGJHV2t5Tm1NSEFtdkdwTUlRRnpxcHBtZzhHdE5UY2NDWFlTQ1FTYjhybDhuMlErYVZHN0Q4cHhFenM5cE5scnRhbS91UVRYblQwaUMyZjE0Z3VVeU4yeU9jU083VENwZWNFZkZOWHV4Q2hIdlkrVGUwcGhDa3pOV0luQjh1V3crSHdMV3JTbkd4VGU2dlMxQVQySll0SUpCSzVvWm1FVS95ZlRDYnpiV3RyNjI2NzNmN2dySmpuWG1DM3h2b2F1cHE3SFVyU0dOT1NjYW95dFNvRXIxbE1jSE5CMXVKRFdaV3BXZGh0SWo3ZzFxdkNjbHRRVVVlK3BGZlZpSFIreEJpODJFWThIbitCZTlkb2RxVGw4QU5pdDF3aXgwWnR1RTU3aWZQS0Zjek1PeUR4Q3RybUpSRVMyUHZza1I0V0s3dVlKWlBhNFo4cWlNSWgzRTZsVWp1R1lWejNxcFBZeVlIZDIrdDJ1eis4Q3B5aVBYVnhRbnljVHFlL3FDQkJuUUs3UmFSN2NIRHdkUW9nWGw1eG10SkxDSnJibEdRUUFqdDM5cTJnY1IyMk5zOG1OTWZYVURwakhxRXA2VnFmTk1TTy9vQ2Z6akJlYVd6bC9Hb2pZVHpvbkJ3ZEhYMGEwUEorbzgyVW5OQUU1cUhEb3NBc2RVazBFSnNQSkJLWTdTQ1NDY1FHSFltRWdySmxTaTdCMk1RbUU2UkFIQ3VjVW9FWEM4SkJqMDBtRUVkdk5wbEFISWJhWk14Q29YRFR6d01nNmxKOVBHMlRDY1FQQXpZWlh2LzdYemljWkFMeFU0MU02Rno4NWpSMDJ1TkVPT2M5TnpONGRNejFPYk1zWDl1UFozOEJ2d1p3Nno5MlBJNEFBQUFBU1VWT1JLNUNZSUk9IiAvPgogICAgPC9kaXY+CiAgPC9kaXY+CiAgPHNjcmlwdD4KICAgIGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdwb3N0ZXInKS5vbmVycm9yID0gZnVuY3Rpb24oKSB7CiAgICAgIHRoaXMuaGlkZGVuID0gdHJ1ZTsKICAgIH07CgogICAgZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ291dGVyJykub25jbGljayA9IGZ1bmN0aW9uKCkgewogICAgICBwbHVnaW4ubG9hZCgpOwogICAgfTsKCiAgICB3aW5kb3cucmVzaXplUG9zdGVyID0gZnVuY3Rpb24obWFyZ2luTGVmdCwgbWFyZ2luVG9wLCB3aWR0aCwgaGVpZ2h0KSB7CiAgICAgIHZhciBjb250YWluZXIgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnaW5uZXItY29udGFpbmVyJyk7CiAgICAgIGNvbnRhaW5lci5zdHlsZS5tYXJnaW5MZWZ0ID0gbWFyZ2luTGVmdDsKICAgICAgY29udGFpbmVyLnN0eWxlLm1hcmdpblRvcCA9IG1hcmdpblRvcDsKICAgICAgY29udGFpbmVyLnN0eWxlLndpZHRoID0gd2lkdGg7CiAgICAgIGNvbnRhaW5lci5zdHlsZS5oZWlnaHQgPSBoZWlnaHQ7CgogICAgICBpZiAocGx1Z2luLmRpZEZpbmlzaEljb25SZXBvc2l0aW9uRm9yVGVzdGluZykgewogICAgICAgIC8vIERlZmVyIHVudGlsIHJlZmxvdyBjb21wbGV0ZS4KICAgICAgICB3aW5kb3cuc2V0VGltZW91dChmdW5jdGlvbigpIHsKICAgICAgICAgIHBsdWdpbi5kaWRGaW5pc2hJY29uUmVwb3NpdGlvbkZvclRlc3RpbmcoKTsKICAgICAgICB9KTsKICAgICAgfQogICAgfTsKICA8L3NjcmlwdD4KPC9ib2R5Pgo8L2h0bWw+Ci8vIENvcHlyaWdodCAoYykgMjAxMiBUaGUgQ2hyb21pdW0gQXV0aG9ycy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KLy8gVXNlIG9mIHRoaXMgc291cmNlIGNvZGUgaXMgZ292ZXJuZWQgYnkgYSBCU0Qtc3R5bGUgbGljZW5zZSB0aGF0IGNhbiBiZQovLyBmb3VuZCBpbiB0aGUgTElDRU5TRSBmaWxlLgoKLy8gQ3VzdG9tIGJpbmRpbmcgZm9yIHRoZSBhcHAgQVBJLgoKdmFyIGFwcE5hdGl2ZXMgPSByZXF1aXJlTmF0aXZlKCdhcHAnKTsKdmFyIHByb2Nlc3MgPSByZXF1aXJlTmF0aXZlKCdwcm9jZXNzJyk7CnZhciBleHRlbnNpb25JZCA9IHByb2Nlc3MuR2V0RXh0ZW5zaW9uSWQoKTsKdmFyIGxvZ0FjdGl2aXR5ID0gcmVxdWlyZU5hdGl2ZSgnYWN0aXZpdHlMb2dnZXInKTsKCmZ1bmN0aW9uIHdyYXBGb3JMb2dnaW5nKGZ1bikgewogIGlmICghZXh0ZW5zaW9uSWQpCiAgICByZXR1cm4gZnVuOyAgLy8gbm90aGluZyBpbnRlcmVzdGluZyB0byBsb2cgd2l0aG91dCBhbiBleHRlbnNpb24KCiAgcmV0dXJuIGZ1bmN0aW9uKCkgewogICAgLy8gVE9ETyhhdGFseSk6IFdlIG5lZWQgdG8gbWFrZSBzdXJlIHdlIHVzZSB0aGUgcmlnaHQgcHJvdG90eXBlIGZvcgogICAgLy8gZnVuLmFwcGx5LiBBcnJheSBzbGljZSBjYW4gZWl0aGVyIGJlIHJld3JpdHRlbiBvciBzaW1pbGFybHkgZGVmaW5lZC4KICAgIGxvZ0FjdGl2aXR5LkxvZ0FQSUNhbGwoZXh0ZW5zaW9uSWQsICJhcHAuIiArIGZ1bi5uYW1lLAogICAgICAgICRBcnJheS5zbGljZShhcmd1bWVudHMpKTsKICAgIHJldHVybiAkRnVuY3Rpb24uYXBwbHkoZnVuLCB0aGlzLCBhcmd1bWVudHMpOwogIH07Cn0KCi8vIFRoaXMgYmVjb21lcyBjaHJvbWUuYXBwCnZhciBhcHAgPSB7CiAgZ2V0SXNJbnN0YWxsZWQ6IHdyYXBGb3JMb2dnaW5nKGFwcE5hdGl2ZXMuR2V0SXNJbnN0YWxsZWQpLAogIGdldERldGFpbHM6IHdyYXBGb3JMb2dnaW5nKGFwcE5hdGl2ZXMuR2V0RGV0YWlscyksCiAgcnVubmluZ1N0YXRlOiB3cmFwRm9yTG9nZ2luZyhhcHBOYXRpdmVzLkdldFJ1bm5pbmdTdGF0ZSkKfTsKCi8vIFRyaWNreTsgImdldElzSW5zdGFsbGVkIiBpcyBhY3R1YWxseSBleHBvc2VkIGFzIHRoZSBnZXR0ZXIgImlzSW5zdGFsbGVkIiwKLy8gYnV0IHdlIGRvbid0IGhhdmUgYSB3YXkgdG8gZXhwcmVzcyB0aGlzIGluIHRoZSBzY2hlbWEgSlNPTiAobm9yIGlzIGl0Ci8vIHdvcnRoIGl0IGZvciB0aGlzIG9uZSBzcGVjaWFsIGNhc2UpLgovLwovLyBTbywgZGVmaW5lIGl0IG1hbnVhbGx5LCBhbmQgbGV0IHRoZSBnZXRJc0luc3RhbGxlZCBmdW5jdGlvbiBhY3QgYXMgaXRzCi8vIGRvY3VtZW50YXRpb24uCnZhciBpc0luc3RhbGxlZCA9IHdyYXBGb3JMb2dnaW5nKGFwcE5hdGl2ZXMuR2V0SXNJbnN0YWxsZWQpOwokT2JqZWN0LmRlZmluZVByb3BlcnR5KAogICAgYXBwLCAnaXNJbnN0YWxsZWQnLAogICAgewogICAgICBfX3Byb3RvX186IG51bGwsCiAgICAgIGNvbmZpZ3VyYWJsZTogdHJ1ZSwKICAgICAgZW51bWVyYWJsZTogdHJ1ZSwKICAgICAgZ2V0OiBmdW5jdGlvbigpIHsgcmV0dXJuIGlzSW5zdGFsbGVkKCk7IH0sCiAgICB9KTsKCi8vIENhbGxlZCBieSBhcHBfYmluZGluZ3MuY2MuCmZ1bmN0aW9uIG9uSW5zdGFsbFN0YXRlUmVzcG9uc2Uoc3RhdGUsIGNhbGxiYWNrSWQpIHsKICB2YXIgY2FsbGJhY2sgPSBjYWxsYmFja3NbY2FsbGJhY2tJZF07CiAgZGVsZXRlIGNhbGxiYWNrc1tjYWxsYmFja0lkXTsKICBpZiAodHlwZW9mIGNhbGxiYWNrID09ICdmdW5jdGlvbicpIHsKICAgIHRyeSB7CiAgICAgIGNhbGxiYWNrKHN0YXRlKTsKICAgIH0gY2F0Y2ggKGUpIHsKICAgICAgY29uc29sZS5lcnJvcignRXhjZXB0aW9uIGluIGNocm9tZS5hcHAuaW5zdGFsbFN0YXRlIHJlc3BvbnNlIGhhbmRsZXI6ICcgKwogICAgICAgICAgICAgICAgICAgIGUuc3RhY2spOwogICAgfQogIH0KfQoKLy8gVE9ETyhrYWxtYW4pOiBtb3ZlIHRoaXMgc3R1ZmYgdG8gaXRzIG93biBjdXN0b20gYmluZGluZ3MuCnZhciBjYWxsYmFja3MgPSB7IF9fcHJvdG9fXzogbnVsbCB9Owp2YXIgbmV4dENhbGxiYWNrSWQgPSAxOwoKZnVuY3Rpb24gZ2V0SW5zdGFsbFN0YXRlKGNhbGxiYWNrKSB7CiAgdmFyIGNhbGxiYWNrSWQgPSBuZXh0Q2FsbGJhY2tJZCsrOwogIGNhbGxiYWNrc1tjYWxsYmFja0lkXSA9IGNhbGxiYWNrOwogIGFwcE5hdGl2ZXMuR2V0SW5zdGFsbFN0YXRlKGNhbGxiYWNrSWQpOwp9CgokT2JqZWN0LmRlZmluZVByb3BlcnR5KAogICAgYXBwLCAnaW5zdGFsbFN0YXRlJywKICAgIHsKICAgICAgX19wcm90b19fOiBudWxsLAogICAgICBjb25maWd1cmFibGU6IHRydWUsCiAgICAgIGVudW1lcmFibGU6IHRydWUsCiAgICAgIHZhbHVlOiB3cmFwRm9yTG9nZ2luZyhnZXRJbnN0YWxsU3RhdGUpLAogICAgICB3cml0YWJsZTogdHJ1ZSwKICAgIH0pOwoKZXhwb3J0cy4kc2V0KCdiaW5kaW5nJywgYXBwKTsKZXhwb3J0cy4kc2V0KCdvbkluc3RhbGxTdGF0ZVJlc3BvbnNlJywgb25JbnN0YWxsU3RhdGVSZXNwb25zZSk7Ci8vIENvcHlyaWdodCAyMDE0IFRoZSBDaHJvbWl1bSBBdXRob3JzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgovLyBVc2Ugb2YgdGhpcyBzb3VyY2UgY29kZSBpcyBnb3Zlcm5lZCBieSBhIEJTRC1zdHlsZSBsaWNlbnNlIHRoYXQgY2FuIGJlCi8vIGZvdW5kIGluIHRoZSBMSUNFTlNFIGZpbGUuCgovLyBDdXN0b20gYmluZGluZ3MgZm9yIHRoZSBhdXRvbWF0aW9uIEFQSS4KdmFyIEF1dG9tYXRpb25Ob2RlID0gcmVxdWlyZSgnYXV0b21hdGlvbk5vZGUnKS5BdXRvbWF0aW9uTm9kZTsKdmFyIEF1dG9tYXRpb25Sb290Tm9kZSA9IHJlcXVpcmUoJ2F1dG9tYXRpb25Ob2RlJykuQXV0b21hdGlvblJvb3ROb2RlOwp2YXIgYXV0b21hdGlvbiA9IGFwaUJyaWRnZSB8fCByZXF1aXJlKCdiaW5kaW5nJykuQmluZGluZy5jcmVhdGUoJ2F1dG9tYXRpb24nKTsKdmFyIGF1dG9tYXRpb25JbnRlcm5hbCA9CiAgICBnZXRJbnRlcm5hbEFwaSA/CiAgICAgICAgZ2V0SW50ZXJuYWxBcGkoJ2F1dG9tYXRpb25JbnRlcm5hbCcpIDoKICAgICAgICByZXF1aXJlKCdiaW5kaW5nJykuQmluZGluZy5jcmVhdGUoJ2F1dG9tYXRpb25JbnRlcm5hbCcpLmdlbmVyYXRlKCk7CnZhciBleGNlcHRpb25IYW5kbGVyID0gcmVxdWlyZSgndW5jYXVnaHRfZXhjZXB0aW9uX2hhbmRsZXInKTsKdmFyIGxvZ2dpbmcgPSByZXF1aXJlTmF0aXZlKCdsb2dnaW5nJyk7CnZhciBuYXRpdmVBdXRvbWF0aW9uSW50ZXJuYWwgPSByZXF1aXJlTmF0aXZlKCdhdXRvbWF0aW9uSW50ZXJuYWwnKTsKdmFyIERlc3Ryb3lBY2Nlc3NpYmlsaXR5VHJlZSA9CiAgICBuYXRpdmVBdXRvbWF0aW9uSW50ZXJuYWwuRGVzdHJveUFjY2Vzc2liaWxpdHlUcmVlOwp2YXIgR2V0SW50QXR0cmlidXRlID0gbmF0aXZlQXV0b21hdGlvbkludGVybmFsLkdldEludEF0dHJpYnV0ZTsKdmFyIFN0YXJ0Q2FjaGluZ0FjY2Vzc2liaWxpdHlUcmVlcyA9CiAgICBuYXRpdmVBdXRvbWF0aW9uSW50ZXJuYWwuU3RhcnRDYWNoaW5nQWNjZXNzaWJpbGl0eVRyZWVzOwp2YXIgQWRkVHJlZUNoYW5nZU9ic2VydmVyID0gbmF0aXZlQXV0b21hdGlvbkludGVybmFsLkFkZFRyZWVDaGFuZ2VPYnNlcnZlcjsKdmFyIFJlbW92ZVRyZWVDaGFuZ2VPYnNlcnZlciA9CiAgICBuYXRpdmVBdXRvbWF0aW9uSW50ZXJuYWwuUmVtb3ZlVHJlZUNoYW5nZU9ic2VydmVyOwp2YXIgR2V0Rm9jdXNOYXRpdmUgPSBuYXRpdmVBdXRvbWF0aW9uSW50ZXJuYWwuR2V0Rm9jdXM7Cgp2YXIganNMYXN0RXJyb3IgPSBiaW5kaW5nVXRpbCA/IHVuZGVmaW5lZCA6IHJlcXVpcmUoJ2xhc3RFcnJvcicpOwpmdW5jdGlvbiBoYXNMYXN0RXJyb3IoKSB7CiAgcmV0dXJuIGJpbmRpbmdVdGlsID8KICAgICAgYmluZGluZ1V0aWwuaGFzTGFzdEVycm9yKCkgOiBqc0xhc3RFcnJvci5oYXNFcnJvcihjaHJvbWUpOwp9CgovKioKICogQSBuYW1lc3BhY2UgdG8gZXhwb3J0IHV0aWxpdHkgZnVuY3Rpb25zIHRvIG90aGVyIGZpbGVzIGluIGF1dG9tYXRpb24uCiAqLwp3aW5kb3cuYXV0b21hdGlvblV0aWwgPSBmdW5jdGlvbigpIHt9OwoKLy8gVE9ETyhhYm94aGFsbCk6IExvb2sgaW50byB1c2luZyBXZWFrTWFwCnZhciBpZFRvQ2FsbGJhY2sgPSB7fTsKCnZhciBERVNLVE9QX1RSRUVfSUQgPSAwOwoKYXV0b21hdGlvblV0aWwuc3RvcmVUcmVlQ2FsbGJhY2sgPSBmdW5jdGlvbihpZCwgY2FsbGJhY2spIHsKICBpZiAoIWNhbGxiYWNrKQogICAgcmV0dXJuOwoKICB2YXIgdGFyZ2V0VHJlZSA9IEF1dG9tYXRpb25Sb290Tm9kZS5nZXQoaWQpOwogIGlmICghdGFyZ2V0VHJlZSkgewogICAgLy8gSWYgd2UgaGF2ZW4ndCBjYWNoZWQgdGhlIHRyZWUsIGhvbGQgdGhlIGNhbGxiYWNrIHVudGlsIHRoZSB0cmVlIGlzCiAgICAvLyBwb3B1bGF0ZWQgYnkgdGhlIGluaXRpYWwgb25BY2Nlc3NpYmlsaXR5RXZlbnQgY2FsbC4KICAgIGlmIChpZCBpbiBpZFRvQ2FsbGJhY2spCiAgICAgIGlkVG9DYWxsYmFja1tpZF0ucHVzaChjYWxsYmFjayk7CiAgICBlbHNlCiAgICAgIGlkVG9DYWxsYmFja1tpZF0gPSBbY2FsbGJhY2tdOwogIH0gZWxzZSB7CiAgICBjYWxsYmFjayh0YXJnZXRUcmVlKTsKICB9Cn07CgovKioKICogR2xvYmFsIGxpc3Qgb2YgdHJlZSBjaGFuZ2Ugb2JzZXJ2ZXJzLgogKiBAdHlwZSB7T2JqZWN0PG51bWJlciwgVHJlZUNoYW5nZU9ic2VydmVyPn0KICovCmF1dG9tYXRpb25VdGlsLnRyZWVDaGFuZ2VPYnNlcnZlck1hcCA9IHt9OwoKLyoqCiAqIFRoZSBpZCBvZiB0aGUgbmV4dCB0cmVlIGNoYW5nZSBvYnNlcnZlci4KICogQHR5cGUge251bWJlcn0KICovCmF1dG9tYXRpb25VdGlsLm5leHRUcmVlQ2hhbmdlT2JzZXJ2ZXJJZCA9IDE7CgovKioKICogQHR5cGUge0F1dG9tYXRpb25Ob2RlfSBUaGUgY3VycmVudCBmb2N1c2VkIG5vZGUuIFRoaXMgaXMgb25seSB1cGRhdGVkCiAqICAgd2hlbiBjYWxsaW5nIGF1dG9tYXRpb25VdGlsLnVwZGF0ZUZvY3VzZWROb2RlLgogKi8KYXV0b21hdGlvblV0aWwuZm9jdXNlZE5vZGUgPSBudWxsOwoKLyoqCiAqIEdldHMgdGhlIGN1cnJlbnRseSBmb2N1c2VkIEF1dG9tYXRpb25Ob2RlLgogKiBAcmV0dXJuIHtBdXRvbWF0aW9uTm9kZX0KICovCmF1dG9tYXRpb25VdGlsLmdldEZvY3VzID0gZnVuY3Rpb24oKSB7CiAgdmFyIGZvY3VzZWROb2RlSW5mbyA9IEdldEZvY3VzTmF0aXZlKERFU0tUT1BfVFJFRV9JRCk7CiAgaWYgKCFmb2N1c2VkTm9kZUluZm8pCiAgICByZXR1cm4gbnVsbDsKICB2YXIgdHJlZSA9IEF1dG9tYXRpb25Sb290Tm9kZS5nZXRPckNyZWF0ZShmb2N1c2VkTm9kZUluZm8udHJlZUlkKTsKICBpZiAodHJlZSkKICAgIHJldHVybiBwcml2YXRlcyh0cmVlKS5pbXBsLmdldChmb2N1c2VkTm9kZUluZm8ubm9kZUlkKTsKfTsKCi8qKgogKiBVcGRhdGUgYXV0b21hdGlvblV0aWwuZm9jdXNlZE5vZGUgdG8gYmUgdGhlIG5vZGUgdGhhdCBjdXJyZW50bHkgaGFzIGZvY3VzLgogKi8KYXV0b21hdGlvblV0aWwudXBkYXRlRm9jdXNlZE5vZGUgPSBmdW5jdGlvbigpIHsKICBhdXRvbWF0aW9uVXRpbC5mb2N1c2VkTm9kZSA9IGF1dG9tYXRpb25VdGlsLmdldEZvY3VzKCk7Cn07CgovKioKICogVXBkYXRlcyB0aGUgZm9jdXMgb24gYmx1ci4KICovCmF1dG9tYXRpb25VdGlsLnVwZGF0ZUZvY3VzZWROb2RlT25CbHVyID0gZnVuY3Rpb24oKSB7CiAgdmFyIGZvY3VzID0gYXV0b21hdGlvblV0aWwuZ2V0Rm9jdXMoKTsKICBhdXRvbWF0aW9uVXRpbC5mb2N1c2VkTm9kZSA9IGZvY3VzID8gZm9jdXMucm9vdCA6IG51bGw7Cn07CgphdXRvbWF0aW9uLnJlZ2lzdGVyQ3VzdG9tSG9vayhmdW5jdGlvbihiaW5kaW5nc0FQSSkgewogIHZhciBhcGlGdW5jdGlvbnMgPSBiaW5kaW5nc0FQSS5hcGlGdW5jdGlvbnM7CgogIC8vIFRPRE8oYWJveGhhbGwsIGR0c2VuZyk6IE1ha2UgdGhpcyByZXR1cm4gdGhlIHNwZWNlZCBBdXRvbWF0aW9uUm9vdE5vZGUgb2JqLgogIGFwaUZ1bmN0aW9ucy5zZXRIYW5kbGVSZXF1ZXN0KCdnZXRUcmVlJywgZnVuY3Rpb24gZ2V0VHJlZSh0YWJJRCwgY2FsbGJhY2spIHsKICAgIFN0YXJ0Q2FjaGluZ0FjY2Vzc2liaWxpdHlUcmVlcygpOwoKICAgIC8vIGVuYWJsZVRhYigpIGVuc3VyZXMgdGhlIHJlbmRlcmVyIGZvciB0aGUgYWN0aXZlIG9yIHNwZWNpZmllZCB0YWIgaGFzCiAgICAvLyBhY2Nlc3NpYmlsaXR5IGVuYWJsZWQsIGFuZCBmZXRjaGVzIGl0cyBheCB0cmVlIGlkIHRvIHVzZSBhcwogICAgLy8gYSBrZXkgaW4gdGhlIGlkVG9BdXRvbWF0aW9uUm9vdE5vZGUgbWFwLiBUaGUgY2FsbGJhY2sgdG8KICAgIC8vIGVuYWJsZVRhYiBpcyBib3VuZCB0byB0aGUgY2FsbGJhY2sgcGFzc2VkIGluIHRvIGdldFRyZWUoKSwgc28gdGhhdCBvbmNlCiAgICAvLyB0aGUgdHJlZSBpcyBhdmFpbGFibGUgKGVpdGhlciBkdWUgdG8gaGF2aW5nIGJlZW4gY2FjaGVkIGVhcmxpZXIsIG9yIGFmdGVyCiAgICAvLyBhbiBhY2Nlc3NpYmlsaXR5IGV2ZW50IG9jY3VycyB3aGljaCBjYXVzZXMgdGhlIHRyZWUgdG8gYmUgcG9wdWxhdGVkKSwgdGhlCiAgICAvLyBjYWxsYmFjayBjYW4gYmUgY2FsbGVkLgogICAgdmFyIHBhcmFtcyA9IHsgdGFiSUQ6IHRhYklEIH07CiAgICBhdXRvbWF0aW9uSW50ZXJuYWwuZW5hYmxlVGFiKHBhcmFtcywKICAgICAgICBmdW5jdGlvbiBvbkVuYWJsZShpZCkgewogICAgICAgICAgaWYgKGhhc0xhc3RFcnJvcigpKSB7CiAgICAgICAgICAgIGNhbGxiYWNrKCk7CiAgICAgICAgICAgIHJldHVybjsKICAgICAgICAgIH0KICAgICAgICAgIGF1dG9tYXRpb25VdGlsLnN0b3JlVHJlZUNhbGxiYWNrKGlkLCBjYWxsYmFjayk7CiAgICAgICAgfSk7CiAgfSk7CgogIHZhciBkZXNrdG9wVHJlZSA9IG51bGw7CiAgYXBpRnVuY3Rpb25zLnNldEhhbmRsZVJlcXVlc3QoJ2dldERlc2t0b3AnLCBmdW5jdGlvbihjYWxsYmFjaykgewogICAgU3RhcnRDYWNoaW5nQWNjZXNzaWJpbGl0eVRyZWVzKCk7CiAgICBkZXNrdG9wVHJlZSA9IEF1dG9tYXRpb25Sb290Tm9kZS5nZXQoREVTS1RPUF9UUkVFX0lEKTsKICAgIGlmICghZGVza3RvcFRyZWUpIHsKICAgICAgaWYgKERFU0tUT1BfVFJFRV9JRCBpbiBpZFRvQ2FsbGJhY2spCiAgICAgICAgaWRUb0NhbGxiYWNrW0RFU0tUT1BfVFJFRV9JRF0ucHVzaChjYWxsYmFjayk7CiAgICAgIGVsc2UKICAgICAgICBpZFRvQ2FsbGJhY2tbREVTS1RPUF9UUkVFX0lEXSA9IFtjYWxsYmFja107CgogICAgICAvLyBUT0RPKGR0c2VuZyk6IERpc2FibGUgZGVza3RvcCB0cmVlIG9uY2UgZGVza3RvcCBvYmplY3QgZ29lcyBvdXQgb2YKICAgICAgLy8gc2NvcGUuCiAgICAgIGF1dG9tYXRpb25JbnRlcm5hbC5lbmFibGVEZXNrdG9wKGZ1bmN0aW9uKCkgewogICAgICAgIGlmIChoYXNMYXN0RXJyb3IoKSkgewogICAgICAgICAgQXV0b21hdGlvblJvb3ROb2RlLmRlc3Ryb3koREVTS1RPUF9UUkVFX0lEKTsKICAgICAgICAgIGNhbGxiYWNrKCk7CiAgICAgICAgICByZXR1cm47CiAgICAgICAgfQogICAgICB9KTsKICAgIH0gZWxzZSB7CiAgICAgIGNhbGxiYWNrKGRlc2t0b3BUcmVlKTsKICAgIH0KICB9KTsKCiAgYXBpRnVuY3Rpb25zLnNldEhhbmRsZVJlcXVlc3QoJ2dldEZvY3VzJywgZnVuY3Rpb24oY2FsbGJhY2spIHsKICAgIGNhbGxiYWNrKGF1dG9tYXRpb25VdGlsLmdldEZvY3VzKCkpOwogIH0pOwoKICBmdW5jdGlvbiByZW1vdmVUcmVlQ2hhbmdlT2JzZXJ2ZXIob2JzZXJ2ZXIpIHsKICAgIGZvciAodmFyIGlkIGluIGF1dG9tYXRpb25VdGlsLnRyZWVDaGFuZ2VPYnNlcnZlck1hcCkgewogICAgICBpZiAoYXV0b21hdGlvblV0aWwudHJlZUNoYW5nZU9ic2VydmVyTWFwW2lkXSA9PSBvYnNlcnZlcikgewogICAgICAgIFJlbW92ZVRyZWVDaGFuZ2VPYnNlcnZlcihpZCk7CiAgICAgICAgZGVsZXRlIGF1dG9tYXRpb25VdGlsLnRyZWVDaGFuZ2VPYnNlcnZlck1hcFtpZF07CiAgICAgICAgcmV0dXJuOwogICAgICB9CiAgICB9CiAgfQogIGFwaUZ1bmN0aW9ucy5zZXRIYW5kbGVSZXF1ZXN0KCdyZW1vdmVUcmVlQ2hhbmdlT2JzZXJ2ZXInLCBmdW5jdGlvbihvYnNlcnZlcikgewogICAgcmVtb3ZlVHJlZUNoYW5nZU9ic2VydmVyKG9ic2VydmVyKTsKICB9KTsKCiAgZnVuY3Rpb24gYWRkVHJlZUNoYW5nZU9ic2VydmVyKGZpbHRlciwgb2JzZXJ2ZXIpIHsKICAgIHJlbW92ZVRyZWVDaGFuZ2VPYnNlcnZlcihvYnNlcnZlcik7CiAgICB2YXIgaWQgPSBhdXRvbWF0aW9uVXRpbC5uZXh0VHJlZUNoYW5nZU9ic2VydmVySWQrKzsKICAgIEFkZFRyZWVDaGFuZ2VPYnNlcnZlcihpZCwgZmlsdGVyKTsKICAgIGF1dG9tYXRpb25VdGlsLnRyZWVDaGFuZ2VPYnNlcnZlck1hcFtpZF0gPSBvYnNlcnZlcjsKICB9CiAgYXBpRnVuY3Rpb25zLnNldEhhbmRsZVJlcXVlc3QoJ2FkZFRyZWVDaGFuZ2VPYnNlcnZlcicsCiAgICAgIGZ1bmN0aW9uKGZpbHRlciwgb2JzZXJ2ZXIpIHsKICAgIGFkZFRyZWVDaGFuZ2VPYnNlcnZlcihmaWx0ZXIsIG9ic2VydmVyKTsKICB9KTsKCiAgYXBpRnVuY3Rpb25zLnNldEhhbmRsZVJlcXVlc3QoJ3NldERvY3VtZW50U2VsZWN0aW9uJywgZnVuY3Rpb24ocGFyYW1zKSB7CiAgICB2YXIgYW5jaG9yTm9kZUltcGwgPSBwcml2YXRlcyhwYXJhbXMuYW5jaG9yT2JqZWN0KS5pbXBsOwogICAgdmFyIGZvY3VzTm9kZUltcGwgPSBwcml2YXRlcyhwYXJhbXMuZm9jdXNPYmplY3QpLmltcGw7CiAgICBpZiAoYW5jaG9yTm9kZUltcGwudHJlZUlEICE9PSBmb2N1c05vZGVJbXBsLnRyZWVJRCkKICAgICAgdGhyb3cgbmV3IEVycm9yKCdTZWxlY3Rpb24gYW5jaG9yIGFuZCBmb2N1cyBtdXN0IGJlIGluIHRoZSBzYW1lIHRyZWUuJyk7CiAgICBpZiAoYW5jaG9yTm9kZUltcGwudHJlZUlEID09PSBERVNLVE9QX1RSRUVfSUQpIHsKICAgICAgdGhyb3cgbmV3IEVycm9yKCdVc2UgQXV0b21hdGlvbk5vZGUuc2V0U2VsZWN0aW9uIHRvIHNldCB0aGUgc2VsZWN0aW9uICcgKwogICAgICAgICAgJ2luIHRoZSBkZXNrdG9wIHRyZWUuJyk7CiAgICB9CiAgICBhdXRvbWF0aW9uSW50ZXJuYWwucGVyZm9ybUFjdGlvbih7IHRyZWVJRDogYW5jaG9yTm9kZUltcGwudHJlZUlELAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhdXRvbWF0aW9uTm9kZUlEOiBhbmNob3JOb2RlSW1wbC5pZCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYWN0aW9uVHlwZTogJ3NldFNlbGVjdGlvbid9LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeyBmb2N1c05vZGVJRDogZm9jdXNOb2RlSW1wbC5pZCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYW5jaG9yT2Zmc2V0OiBwYXJhbXMuYW5jaG9yT2Zmc2V0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmb2N1c09mZnNldDogcGFyYW1zLmZvY3VzT2Zmc2V0IH0pOwogIH0pOwoKfSk7CgphdXRvbWF0aW9uSW50ZXJuYWwub25DaGlsZFRyZWVJRC5hZGRMaXN0ZW5lcihmdW5jdGlvbih0cmVlSUQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5vZGVJRCkgewogIHZhciB0cmVlID0gQXV0b21hdGlvblJvb3ROb2RlLmdldE9yQ3JlYXRlKHRyZWVJRCk7CiAgaWYgKCF0cmVlKQogICAgcmV0dXJuOwoKICB2YXIgbm9kZSA9IHByaXZhdGVzKHRyZWUpLmltcGwuZ2V0KG5vZGVJRCk7CiAgaWYgKCFub2RlKQogICAgcmV0dXJuOwoKICAvLyBBIFdlYlZpZXcgaW4gdGhlIGRlc2t0b3AgdHJlZSBoYXMgYSBkaWZmZXJlbnQgQVggdHJlZSBhcyBpdHMgY2hpbGQuCiAgLy8gV2hlbiB3ZSBlbmNvdW50ZXIgYSBXZWJWaWV3IHdpdGggYSBjaGlsZCBBWCB0cmVlIGlkIHRoYXQgd2UgZG9uJ3QKICAvLyBjdXJyZW50bHkgaGF2ZSBjYWNoZWQsIGV4cGxpY2l0bHkgcmVxdWVzdCB0aGF0IEFYIHRyZWUgZnJvbSB0aGUKICAvLyBicm93c2VyIHByb2Nlc3MgYW5kIHNldCB1cCBhIGNhbGxiYWNrIHdoZW4gaXQgbG9hZHMgdG8gYXR0YWNoIHRoYXQKICAvLyB0cmVlIGFzIGEgY2hpbGQgb2YgdGhpcyBub2RlIGFuZCBmaXJlIGFwcHJvcHJpYXRlIGV2ZW50cy4KICB2YXIgY2hpbGRUcmVlSUQgPSBHZXRJbnRBdHRyaWJ1dGUodHJlZUlELCBub2RlSUQsICdjaGlsZFRyZWVJZCcpOwogIGlmICghY2hpbGRUcmVlSUQpCiAgICByZXR1cm47CgogIHZhciBzdWJyb290ID0gQXV0b21hdGlvblJvb3ROb2RlLmdldChjaGlsZFRyZWVJRCk7CiAgaWYgKCFzdWJyb290IHx8IHN1YnJvb3Qucm9sZSA9PSAndW5rbm93bicpIHsKICAgIGF1dG9tYXRpb25VdGlsLnN0b3JlVHJlZUNhbGxiYWNrKGNoaWxkVHJlZUlELCBmdW5jdGlvbihyb290KSB7CiAgICAgIC8vIFJldHVybiBlYXJseSBpZiB0aGUgcm9vdCBoYXMgYWxyZWFkeSBiZWVuIGF0dGFjaGVkLgogICAgICBpZiAocm9vdC5wYXJlbnQpCiAgICAgICAgcmV0dXJuOwoKICAgICAgcHJpdmF0ZXMocm9vdCkuaW1wbC5zZXRIb3N0Tm9kZShub2RlKTsKCiAgICAgIGlmIChyb290LmRvY0xvYWRlZCkgewogICAgICAgIHByaXZhdGVzKHJvb3QpLmltcGwuZGlzcGF0Y2hFdmVudCgnbG9hZENvbXBsZXRlJywgJ3BhZ2UnKTsKICAgICAgfQoKICAgICAgcHJpdmF0ZXMobm9kZSkuaW1wbC5kaXNwYXRjaEV2ZW50KCdjaGlsZHJlbkNoYW5nZWQnLCAnbm9uZScpOwogICAgfSk7CgogICAgYXV0b21hdGlvbkludGVybmFsLmVuYWJsZUZyYW1lKGNoaWxkVHJlZUlEKTsKICB9IGVsc2UgewogICAgcHJpdmF0ZXMoc3Vicm9vdCkuaW1wbC5zZXRIb3N0Tm9kZShub2RlKTsKICB9Cn0pOwoKYXV0b21hdGlvbkludGVybmFsLm9uVHJlZUNoYW5nZS5hZGRMaXN0ZW5lcihmdW5jdGlvbihvYnNlcnZlcklELAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRyZWVJRCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBub2RlSUQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2hhbmdlVHlwZSkgewogIHZhciB0cmVlID0gQXV0b21hdGlvblJvb3ROb2RlLmdldE9yQ3JlYXRlKHRyZWVJRCk7CiAgaWYgKCF0cmVlKQogICAgcmV0dXJuOwoKICB2YXIgbm9kZSA9IHByaXZhdGVzKHRyZWUpLmltcGwuZ2V0KG5vZGVJRCk7CiAgaWYgKCFub2RlKQogICAgcmV0dXJuOwoKICB2YXIgb2JzZXJ2ZXIgPSBhdXRvbWF0aW9uVXRpbC50cmVlQ2hhbmdlT2JzZXJ2ZXJNYXBbb2JzZXJ2ZXJJRF07CiAgaWYgKCFvYnNlcnZlcikKICAgIHJldHVybjsKCiAgdHJ5IHsKICAgIG9ic2VydmVyKHt0YXJnZXQ6IG5vZGUsIHR5cGU6IGNoYW5nZVR5cGV9KTsKICB9IGNhdGNoIChlKSB7CiAgICBleGNlcHRpb25IYW5kbGVyLmhhbmRsZSgnRXJyb3IgaW4gdHJlZSBjaGFuZ2Ugb2JzZXJ2ZXIgZm9yICcgKwogICAgICAgIHRyZWVDaGFuZ2UudHlwZSwgZSk7CiAgfQp9KTsKCmF1dG9tYXRpb25JbnRlcm5hbC5vbk5vZGVzUmVtb3ZlZC5hZGRMaXN0ZW5lcihmdW5jdGlvbih0cmVlSUQsIG5vZGVJRHMpIHsKICB2YXIgdHJlZSA9IEF1dG9tYXRpb25Sb290Tm9kZS5nZXRPckNyZWF0ZSh0cmVlSUQpOwogIGlmICghdHJlZSkKICAgIHJldHVybjsKCiAgZm9yICh2YXIgaSA9IDA7IGkgPCBub2RlSURzLmxlbmd0aDsgaSsrKSB7CiAgICBwcml2YXRlcyh0cmVlKS5pbXBsLnJlbW92ZShub2RlSURzW2ldKTsKICB9Cn0pOwoKLyoqCiAqIERpc3BhdGNoIGFjY2Vzc2liaWxpdHkgZXZlbnRzIGZpcmVkIG9uIGluZGl2aWR1YWwgbm9kZXMgdG8gaXRzCiAqIGNvcnJlc3BvbmRpbmcgQXV0b21hdGlvbk5vZGUuIEhhbmRsZSBmb2N1cyBldmVudHMgc3BlY2lhbGx5CiAqIChzZWUgYmVsb3cpLgogKi8KYXV0b21hdGlvbkludGVybmFsLm9uQWNjZXNzaWJpbGl0eUV2ZW50LmFkZExpc3RlbmVyKGZ1bmN0aW9uKGV2ZW50UGFyYW1zKSB7CiAgdmFyIGlkID0gZXZlbnRQYXJhbXMudHJlZUlEOwogIHZhciB0YXJnZXRUcmVlID0gQXV0b21hdGlvblJvb3ROb2RlLmdldE9yQ3JlYXRlKGlkKTsKICBpZiAoZXZlbnRQYXJhbXMuZXZlbnRUeXBlID09ICdibHVyJykgewogICAgLy8gV29yayBhcm91bmQgYW4gaXNzdWUgd2hlcmUgQ2hyb21lIHNlbmRzIHVzICdibHVyJyBldmVudHMgb24gdGhlCiAgICAvLyByb290IG5vZGUgd2hlbiBub3RoaW5nIGhhcyBmb2N1cywgd2UgbmVlZCB0byB0cmVhdCB0aG9zZSBhcyBmb2N1cwogICAgLy8gZXZlbnRzIGJ1dCBvdGhlcndpc2Ugbm90IGhhbmRsZSBibHVyIGV2ZW50cyBzcGVjaWFsbHkuCiAgICB2YXIgbm9kZSA9IHByaXZhdGVzKHRhcmdldFRyZWUpLmltcGwuZ2V0KGV2ZW50UGFyYW1zLnRhcmdldElEKTsKICAgIGlmIChub2RlID09IG5vZGUucm9vdCkKICAgICAgYXV0b21hdGlvblV0aWwudXBkYXRlRm9jdXNlZE5vZGVPbkJsdXIoKTsKICB9IGVsc2UgaWYgKGV2ZW50UGFyYW1zLmV2ZW50VHlwZSA9PSAnbWVkaWFTdGFydGVkUGxheWluZycgfHwKICAgICAgZXZlbnRQYXJhbXMuZXZlbnRUeXBlID09ICdtZWRpYVN0b3BwZWRQbGF5aW5nJykgewogICAgLy8gVGhlc2UgZXZlbnRzIGFyZSBnbG9iYWwgdG8gdGhlIHRyZWUuCiAgICBldmVudFBhcmFtcy50YXJnZXRJRCA9IHByaXZhdGVzKHRhcmdldFRyZWUpLmltcGwuaWQ7CiAgfSBlbHNlIHsKICAgIHZhciBwcmV2aW91c0ZvY3VzZWROb2RlID0gYXV0b21hdGlvblV0aWwuZm9jdXNlZE5vZGU7CiAgICBhdXRvbWF0aW9uVXRpbC51cGRhdGVGb2N1c2VkTm9kZSgpOwoKICAgIC8vIEZpcmUgZm9jdXMgZXZlbnRzIGlmIG5lY2Vzc2FyeS4KICAgIGlmIChhdXRvbWF0aW9uVXRpbC5mb2N1c2VkTm9kZSAmJgogICAgICAgIGF1dG9tYXRpb25VdGlsLmZvY3VzZWROb2RlICE9IHByZXZpb3VzRm9jdXNlZE5vZGUpIHsKICAgICAgdmFyIGV2ZW50UGFyYW1zQ29weSA9IHt9OwogICAgICBmb3IgKHZhciBrZXkgaW4gZXZlbnRQYXJhbXMpCiAgICAgICAgZXZlbnRQYXJhbXNDb3B5W2tleV0gPSBldmVudFBhcmFtc1trZXldOwogICAgICBldmVudFBhcmFtc0NvcHlbJ2V2ZW50VHlwZSddID0gJ2ZvY3VzJzsKICAgICAgZXZlbnRQYXJhbXNDb3B5Wyd0cmVlSUQnXSA9CiAgICAgICAgICBwcml2YXRlcyhhdXRvbWF0aW9uVXRpbC5mb2N1c2VkTm9kZS5yb290KS5pbXBsLnRyZWVJRDsKICAgICAgZXZlbnRQYXJhbXNDb3B5Wyd0YXJnZXRJRCddID0KICAgICAgICAgIHByaXZhdGVzKGF1dG9tYXRpb25VdGlsLmZvY3VzZWROb2RlKS5pbXBsLmlkOwogICAgICBwcml2YXRlcyhhdXRvbWF0aW9uVXRpbC5mb2N1c2VkTm9kZS5yb290KQogICAgICAgICAgLmltcGwub25BY2Nlc3NpYmlsaXR5RXZlbnQoZXZlbnRQYXJhbXNDb3B5KTsKICAgIH0KICB9CgogIC8vIE5vdGUgdGhhdCBmb2N1cyB0eXBlIGV2ZW50cyBoYXZlIGFscmVhZHkgYmVlbiBoYW5kbGVkIGFib3ZlIGlmIHRoZXJlIHdhcyBhCiAgLy8gZm9jdXNlZCBub2RlLiBBbGwgb3RoZXIgZXZlbnRzLCBldmVuIG5vbi1mb2N1cyBldmVudHMgdGhhdCB0cmlnZ2VyZWQgYQogIC8vIGZvY3VzIGRpc3BhdGNoLCBzdGlsbCBuZWVkIHRvIGhhdmUgdGhlaXIgb3JpZ2luYWwgZXZlbnQgZmlyZWQuCiAgaWYgKCghYXV0b21hdGlvblV0aWwuZm9jdXNlZE5vZGUgfHwgZXZlbnRQYXJhbXMuZXZlbnRUeXBlICE9ICdmb2N1cycpICYmCiAgICAgICFwcml2YXRlcyh0YXJnZXRUcmVlKS5pbXBsLm9uQWNjZXNzaWJpbGl0eUV2ZW50KGV2ZW50UGFyYW1zKSkKICAgIHJldHVybjsKCiAgLy8gSWYgd2UncmUgbm90IHdhaXRpbmcgb24gYSBjYWxsYmFjayB0byBnZXRUcmVlKCksIHdlIGNhbiBlYXJseSBvdXQgaGVyZS4KICBpZiAoIShpZCBpbiBpZFRvQ2FsbGJhY2spKQogICAgcmV0dXJuOwoKICAvLyBXZSB1c3VhbGx5IGdldCBhICdwbGFjZWhvbGRlcicgdHJlZSBmaXJzdCwgd2hpY2ggZG9lc24ndCBoYXZlIGFueSB1cmwKICAvLyBhdHRyaWJ1dGUgb3IgY2hpbGQgbm9kZXMuIElmIHdlJ3ZlIGdvdCB0aGF0LCB3YWl0IGZvciB0aGUgZnVsbCB0cmVlIGJlZm9yZQogIC8vIGNhbGxpbmcgdGhlIGNhbGxiYWNrLgogIC8vIFRPRE8oZG1henpvbmkpOiBEb24ndCBzZW5kIGRvd24gcGxhY2Vob2xkZXIgKGNyYnVnLmNvbS8zOTc1NTMpCiAgaWYgKGlkICE9IERFU0tUT1BfVFJFRV9JRCAmJiAhdGFyZ2V0VHJlZS51cmwgJiYKICAgICAgdGFyZ2V0VHJlZS5jaGlsZHJlbi5sZW5ndGggPT0gMCkKICAgIHJldHVybjsKCiAgLy8gSWYgdGhlIHRyZWUgd2Fzbid0IGF2YWlsYWJsZSB3aGVuIGdldFRyZWUoKSB3YXMgY2FsbGVkLCB0aGUgY2FsbGJhY2sgd2lsbAogIC8vIGhhdmUgYmVlbiBjYWNoZWQgaW4gaWRUb0NhbGxiYWNrLCBzbyBjYWxsIGFuZCBkZWxldGUgaXQgbm93IHRoYXQgd2UKICAvLyBoYXZlIHRoZSBjb21wbGV0ZSB0cmVlLgogIGZvciAodmFyIGkgPSAwOyBpIDwgaWRUb0NhbGxiYWNrW2lkXS5sZW5ndGg7IGkrKykgewogICAgdmFyIGNhbGxiYWNrID0gaWRUb0NhbGxiYWNrW2lkXVtpXTsKICAgIGNhbGxiYWNrKHRhcmdldFRyZWUpOwogIH0KICBkZWxldGUgaWRUb0NhbGxiYWNrW2lkXTsKfSk7CgphdXRvbWF0aW9uSW50ZXJuYWwub25BY2Nlc3NpYmlsaXR5VHJlZURlc3Ryb3llZC5hZGRMaXN0ZW5lcihmdW5jdGlvbihpZCkgewogIC8vIERlc3Ryb3kgdGhlIEF1dG9tYXRpb25Sb290Tm9kZS4KICB2YXIgdGFyZ2V0VHJlZSA9IEF1dG9tYXRpb25Sb290Tm9kZS5nZXQoaWQpOwogIGlmICh0YXJnZXRUcmVlKSB7CiAgICBwcml2YXRlcyh0YXJnZXRUcmVlKS5pbXBsLmRlc3Ryb3koKTsKICAgIEF1dG9tYXRpb25Sb290Tm9kZS5kZXN0cm95KGlkKTsKICB9IGVsc2UgewogICAgbG9nZ2luZy5XQVJOSU5HKCdubyB0YXJnZXRUcmVlIHRvIGRlc3Ryb3knKTsKICB9CgogIC8vIERlc3Ryb3kgdGhlIG5hdGl2ZSBjYWNoZSBvZiB0aGUgYWNjZXNzaWJpbGl0eSB0cmVlLgogIERlc3Ryb3lBY2Nlc3NpYmlsaXR5VHJlZShpZCk7Cn0pOwoKYXV0b21hdGlvbkludGVybmFsLm9uQWNjZXNzaWJpbGl0eVRyZWVTZXJpYWxpemF0aW9uRXJyb3IuYWRkTGlzdGVuZXIoCiAgICBmdW5jdGlvbihpZCkgewogIGF1dG9tYXRpb25JbnRlcm5hbC5lbmFibGVGcmFtZShpZCk7Cn0pOwoKYXV0b21hdGlvbkludGVybmFsLm9uQWN0aW9uUmVzdWx0LmFkZExpc3RlbmVyKAogICAgZnVuY3Rpb24odHJlZUlELCByZXF1ZXN0SUQsIHJlc3VsdCkgewogIHZhciB0YXJnZXRUcmVlID0gQXV0b21hdGlvblJvb3ROb2RlLmdldCh0cmVlSUQpOwogIGlmICghdGFyZ2V0VHJlZSkKICAgIHJldHVybjsKCiAgcHJpdmF0ZXModGFyZ2V0VHJlZSkuaW1wbC5vbkFjdGlvblJlc3VsdChyZXF1ZXN0SUQsIHJlc3VsdCk7CiAgICB9KTsKCmlmICghYXBpQnJpZGdlKQogIGV4cG9ydHMuJHNldCgnYmluZGluZycsIGF1dG9tYXRpb24uZ2VuZXJhdGUoKSk7Ci8vIENvcHlyaWdodCAyMDE0IFRoZSBDaHJvbWl1bSBBdXRob3JzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgovLyBVc2Ugb2YgdGhpcyBzb3VyY2UgY29kZSBpcyBnb3Zlcm5lZCBieSBhIEJTRC1zdHlsZSBsaWNlbnNlIHRoYXQgY2FuIGJlCi8vIGZvdW5kIGluIHRoZSBMSUNFTlNFIGZpbGUuCgp2YXIgdXRpbHMgPSByZXF1aXJlKCd1dGlscycpOwoKZnVuY3Rpb24gQXV0b21hdGlvbkV2ZW50SW1wbCh0eXBlLCB0YXJnZXQsIGV2ZW50RnJvbSkgewogIHRoaXMucHJvcGFnYXRpb25TdG9wcGVkID0gZmFsc2U7CiAgdGhpcy50eXBlID0gdHlwZTsKICB0aGlzLnRhcmdldCA9IHRhcmdldDsKICB0aGlzLmV2ZW50UGhhc2UgPSBFdmVudC5OT05FOwogIHRoaXMuZXZlbnRGcm9tID0gZXZlbnRGcm9tOwp9CgpBdXRvbWF0aW9uRXZlbnRJbXBsLnByb3RvdHlwZSA9IHsKICBfX3Byb3RvX186IG51bGwsCiAgc3RvcFByb3BhZ2F0aW9uOiBmdW5jdGlvbigpIHsKICAgIHRoaXMucHJvcGFnYXRpb25TdG9wcGVkID0gdHJ1ZTsKICB9LAp9OwoKZnVuY3Rpb24gQXV0b21hdGlvbkV2ZW50KCkgewogIHByaXZhdGVzKEF1dG9tYXRpb25FdmVudCkuY29uc3RydWN0UHJpdmF0ZSh0aGlzLCBhcmd1bWVudHMpOwp9CnV0aWxzLmV4cG9zZShBdXRvbWF0aW9uRXZlbnQsIEF1dG9tYXRpb25FdmVudEltcGwsIHsKICBmdW5jdGlvbnM6IFsKICAgICdzdG9wUHJvcGFnYXRpb24nLAogIF0sCiAgcmVhZG9ubHk6IFsKICAgICd0eXBlJywKICAgICd0YXJnZXQnLAogICAgJ2V2ZW50UGhhc2UnLAogICAgJ2V2ZW50RnJvbScsCiAgXSwKfSk7CgpleHBvcnRzLiRzZXQoJ0F1dG9tYXRpb25FdmVudCcsIEF1dG9tYXRpb25FdmVudCk7Ci8vIENvcHlyaWdodCAyMDE0IFRoZSBDaHJvbWl1bSBBdXRob3JzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgovLyBVc2Ugb2YgdGhpcyBzb3VyY2UgY29kZSBpcyBnb3Zlcm5lZCBieSBhIEJTRC1zdHlsZSBsaWNlbnNlIHRoYXQgY2FuIGJlCi8vIGZvdW5kIGluIHRoZSBMSUNFTlNFIGZpbGUuCgp2YXIgQXV0b21hdGlvbkV2ZW50ID0gcmVxdWlyZSgnYXV0b21hdGlvbkV2ZW50JykuQXV0b21hdGlvbkV2ZW50Owp2YXIgYXV0b21hdGlvbkludGVybmFsID0KICAgIGdldEludGVybmFsQXBpID8KICAgICAgICBnZXRJbnRlcm5hbEFwaSgnYXV0b21hdGlvbkludGVybmFsJykgOgogICAgICAgIHJlcXVpcmUoJ2JpbmRpbmcnKS5CaW5kaW5nLmNyZWF0ZSgnYXV0b21hdGlvbkludGVybmFsJykuZ2VuZXJhdGUoKTsKdmFyIGV4Y2VwdGlvbkhhbmRsZXIgPSByZXF1aXJlKCd1bmNhdWdodF9leGNlcHRpb25faGFuZGxlcicpOwoKdmFyIG5hdGl2ZXMgPSByZXF1aXJlTmF0aXZlKCdhdXRvbWF0aW9uSW50ZXJuYWwnKTsKCnZhciBJc0ludGVyYWN0UGVybWl0dGVkID0gbmF0aXZlcy5Jc0ludGVyYWN0UGVybWl0dGVkOwoKLyoqCiAqIEBwYXJhbSB7bnVtYmVyfSBheFRyZWVJRCBUaGUgaWQgb2YgdGhlIGFjY2Vzc2liaWxpdHkgdHJlZS4KICogQHJldHVybiB7P251bWJlcn0gVGhlIGlkIG9mIHRoZSByb290IG5vZGUuCiAqLwp2YXIgR2V0Um9vdElEID0gbmF0aXZlcy5HZXRSb290SUQ7CgovKioKICogQHBhcmFtIHtudW1iZXJ9IGF4VHJlZUlEIFRoZSBpZCBvZiB0aGUgYWNjZXNzaWJpbGl0eSB0cmVlLgogKiBAcmV0dXJuIHs/c3RyaW5nfSBUaGUgdGl0bGUgb2YgdGhlIGRvY3VtZW50LgogKi8KdmFyIEdldERvY1RpdGxlID0gbmF0aXZlcy5HZXREb2NUaXRsZTsKCi8qKgogKiBAcGFyYW0ge251bWJlcn0gYXhUcmVlSUQgVGhlIGlkIG9mIHRoZSBhY2Nlc3NpYmlsaXR5IHRyZWUuCiAqIEByZXR1cm4gez9zdHJpbmd9IFRoZSB1cmwgb2YgdGhlIGRvY3VtZW50LgogKi8KdmFyIEdldERvY1VSTCA9IG5hdGl2ZXMuR2V0RG9jVVJMOwoKLyoqCiAqIEBwYXJhbSB7bnVtYmVyfSBheFRyZWVJRCBUaGUgaWQgb2YgdGhlIGFjY2Vzc2liaWxpdHkgdHJlZS4KICogQHJldHVybiB7P2Jvb2xlYW59IFRydWUgaWYgdGhlIGRvY3VtZW50IGhhcyBmaW5pc2hlZCBsb2FkaW5nLgogKi8KdmFyIEdldERvY0xvYWRlZCA9IG5hdGl2ZXMuR2V0RG9jTG9hZGVkOwoKLyoqCiAqIEBwYXJhbSB7bnVtYmVyfSBheFRyZWVJRCBUaGUgaWQgb2YgdGhlIGFjY2Vzc2liaWxpdHkgdHJlZS4KICogQHJldHVybiB7P251bWJlcn0gVGhlIGxvYWRpbmcgcHJvZ3Jlc3MsIGZyb20gMC4wIHRvIDEuMCAoZnVsbHkgbG9hZGVkKS4KICovCnZhciBHZXREb2NMb2FkaW5nUHJvZ3Jlc3MgPQogICAgbmF0aXZlcy5HZXREb2NMb2FkaW5nUHJvZ3Jlc3M7CgovKioKICogQHBhcmFtIHtudW1iZXJ9IGF4VHJlZUlEIFRoZSBpZCBvZiB0aGUgYWNjZXNzaWJpbGl0eSB0cmVlLgogKiBAcmV0dXJuIHs/bnVtYmVyfSBUaGUgSUQgb2YgdGhlIHNlbGVjdGlvbiBhbmNob3Igb2JqZWN0LgogKi8KdmFyIEdldEFuY2hvck9iamVjdElEID0gbmF0aXZlcy5HZXRBbmNob3JPYmplY3RJRDsKCi8qKgogKiBAcGFyYW0ge251bWJlcn0gYXhUcmVlSUQgVGhlIGlkIG9mIHRoZSBhY2Nlc3NpYmlsaXR5IHRyZWUuCiAqIEByZXR1cm4gez9udW1iZXJ9IFRoZSBzZWxlY3Rpb24gYW5jaG9yIG9mZnNldC4KICovCnZhciBHZXRBbmNob3JPZmZzZXQgPSBuYXRpdmVzLkdldEFuY2hvck9mZnNldDsKCi8qKgogKiBAcGFyYW0ge251bWJlcn0gYXhUcmVlSUQgVGhlIGlkIG9mIHRoZSBhY2Nlc3NpYmlsaXR5IHRyZWUuCiAqIEByZXR1cm4gez9zdHJpbmd9IFRoZSBzZWxlY3Rpb24gYW5jaG9yIGFmZmluaXR5LgogKi8KdmFyIEdldEFuY2hvckFmZmluaXR5ID0gbmF0aXZlcy5HZXRBbmNob3JBZmZpbml0eTsKCi8qKgogKiBAcGFyYW0ge251bWJlcn0gYXhUcmVlSUQgVGhlIGlkIG9mIHRoZSBhY2Nlc3NpYmlsaXR5IHRyZWUuCiAqIEByZXR1cm4gez9udW1iZXJ9IFRoZSBJRCBvZiB0aGUgc2VsZWN0aW9uIGZvY3VzIG9iamVjdC4KICovCnZhciBHZXRGb2N1c09iamVjdElEID0gbmF0aXZlcy5HZXRGb2N1c09iamVjdElEOwoKLyoqCiAqIEBwYXJhbSB7bnVtYmVyfSBheFRyZWVJRCBUaGUgaWQgb2YgdGhlIGFjY2Vzc2liaWxpdHkgdHJlZS4KICogQHJldHVybiB7P251bWJlcn0gVGhlIHNlbGVjdGlvbiBmb2N1cyBvZmZzZXQuCiAqLwp2YXIgR2V0Rm9jdXNPZmZzZXQgPSBuYXRpdmVzLkdldEZvY3VzT2Zmc2V0OwoKLyoqCiAqIEBwYXJhbSB7bnVtYmVyfSBheFRyZWVJRCBUaGUgaWQgb2YgdGhlIGFjY2Vzc2liaWxpdHkgdHJlZS4KICogQHJldHVybiB7P3N0cmluZ30gVGhlIHNlbGVjdGlvbiBmb2N1cyBhZmZpbml0eS4KICovCnZhciBHZXRGb2N1c0FmZmluaXR5ID0gbmF0aXZlcy5HZXRGb2N1c0FmZmluaXR5OwoKLyoqCiAqIEBwYXJhbSB7bnVtYmVyfSBheFRyZWVJRCBUaGUgaWQgb2YgdGhlIGFjY2Vzc2liaWxpdHkgdHJlZS4KICogQHBhcmFtIHtudW1iZXJ9IG5vZGVJRCBUaGUgaWQgb2YgYSBub2RlLgogKiBAcmV0dXJuIHs/bnVtYmVyfSBUaGUgaWQgb2YgdGhlIG5vZGUncyBwYXJlbnQsIG9yIHVuZGVmaW5lZCBpZiBpdCdzIHRoZQogKiAgICByb290IG9mIGl0cyB0cmVlIG9yIGlmIHRoZSB0cmVlIG9yIG5vZGUgd2Fzbid0IGZvdW5kLgogKi8KdmFyIEdldFBhcmVudElEID0gbmF0aXZlcy5HZXRQYXJlbnRJRDsKCi8qKgogKiBAcGFyYW0ge251bWJlcn0gYXhUcmVlSUQgVGhlIGlkIG9mIHRoZSBhY2Nlc3NpYmlsaXR5IHRyZWUuCiAqIEBwYXJhbSB7bnVtYmVyfSBub2RlSUQgVGhlIGlkIG9mIGEgbm9kZS4KICogQHJldHVybiB7P251bWJlcn0gVGhlIG51bWJlciBvZiBjaGlsZHJlbiBvZiB0aGUgbm9kZSwgb3IgdW5kZWZpbmVkIGlmCiAqICAgICB0aGUgdHJlZSBvciBub2RlIHdhc24ndCBmb3VuZC4KICovCnZhciBHZXRDaGlsZENvdW50ID0gbmF0aXZlcy5HZXRDaGlsZENvdW50OwoKLyoqCiAqIEBwYXJhbSB7bnVtYmVyfSBheFRyZWVJRCBUaGUgaWQgb2YgdGhlIGFjY2Vzc2liaWxpdHkgdHJlZS4KICogQHBhcmFtIHtudW1iZXJ9IG5vZGVJRCBUaGUgaWQgb2YgYSBub2RlLgogKiBAcGFyYW0ge251bWJlcn0gY2hpbGRJbmRleCBBbiBpbmRleCBvZiBhIGNoaWxkIG9mIHRoaXMgbm9kZS4KICogQHJldHVybiB7P251bWJlcn0gVGhlIGlkIG9mIHRoZSBjaGlsZCBhdCB0aGUgZ2l2ZW4gaW5kZXgsIG9yIHVuZGVmaW5lZAogKiAgICAgaWYgdGhlIHRyZWUgb3Igbm9kZSBvciBjaGlsZCBhdCB0aGF0IGluZGV4IHdhc24ndCBmb3VuZC4KICovCnZhciBHZXRDaGlsZElEQXRJbmRleCA9IG5hdGl2ZXMuR2V0Q2hpbGRJREF0SW5kZXg7CgovKioKICogQHBhcmFtIHtudW1iZXJ9IGF4VHJlZUlEIFRoZSBpZCBvZiB0aGUgYWNjZXNzaWJpbGl0eSB0cmVlLgogKiBAcGFyYW0ge251bWJlcn0gbm9kZUlEIFRoZSBpZCBvZiBhIG5vZGUuCiAqIEByZXR1cm4gez9udW1iZXJ9IFRoZSBpZHMgb2YgdGhlIGNoaWxkcmVuIG9mIHRoZSBub2RlLCBvciB1bmRlZmluZWQKICogICAgIGlmIHRoZSB0cmVlIG9yIG5vZGUgd2Fzbid0IGZvdW5kLgogKi8KdmFyIEdldENoaWxkSWRzID0gbmF0aXZlcy5HZXRDaGlsZElEczsKCi8qKgogKiBAcGFyYW0ge251bWJlcn0gYXhUcmVlSUQgVGhlIGlkIG9mIHRoZSBhY2Nlc3NpYmlsaXR5IHRyZWUuCiAqIEBwYXJhbSB7bnVtYmVyfSBub2RlSUQgVGhlIGlkIG9mIGEgbm9kZS4KICogQHJldHVybiB7P09iamVjdH0gQW4gb2JqZWN0IG1hcHBpbmcgaHRtbCBhdHRyaWJ1dGVzIHRvIHZhbHVlcy4KICovCnZhciBHZXRIdG1sQXR0cmlidXRlcyA9IG5hdGl2ZXMuR2V0SHRtbEF0dHJpYnV0ZXM7CgovKioKICogQHBhcmFtIHtudW1iZXJ9IGF4VHJlZUlEIFRoZSBpZCBvZiB0aGUgYWNjZXNzaWJpbGl0eSB0cmVlLgogKiBAcGFyYW0ge251bWJlcn0gbm9kZUlEIFRoZSBpZCBvZiBhIG5vZGUuCiAqIEByZXR1cm4gez9udW1iZXJ9IFRoZSBpbmRleCBvZiB0aGlzIG5vZGUgaW4gaXRzIHBhcmVudCwgb3IgdW5kZWZpbmVkIGlmCiAqICAgICB0aGUgdHJlZSBvciBub2RlIG9yIG5vZGUgcGFyZW50IHdhc24ndCBmb3VuZC4KICovCnZhciBHZXRJbmRleEluUGFyZW50ID0gbmF0aXZlcy5HZXRJbmRleEluUGFyZW50OwoKLyoqCiAqIEBwYXJhbSB7bnVtYmVyfSBheFRyZWVJRCBUaGUgaWQgb2YgdGhlIGFjY2Vzc2liaWxpdHkgdHJlZS4KICogQHBhcmFtIHtudW1iZXJ9IG5vZGVJRCBUaGUgaWQgb2YgYSBub2RlLgogKiBAcmV0dXJuIHs/T2JqZWN0fSBBbiBvYmplY3Qgd2l0aCBhIHN0cmluZyBrZXkgZm9yIGV2ZXJ5IHN0YXRlIGZsYWcgc2V0LAogKiAgICAgb3IgdW5kZWZpbmVkIGlmIHRoZSB0cmVlIG9yIG5vZGUgb3Igbm9kZSBwYXJlbnQgd2Fzbid0IGZvdW5kLgogKi8KdmFyIEdldFN0YXRlID0gbmF0aXZlcy5HZXRTdGF0ZTsKCi8qKgogKiBAcGFyYW0ge251bWJlcn0gYXhUcmVlSUQgVGhlIGlkIG9mIHRoZSBhY2Nlc3NpYmlsaXR5IHRyZWUuCiAqIEBwYXJhbSB7bnVtYmVyfSBub2RlSUQgVGhlIGlkIG9mIGEgbm9kZS4KICogQHJldHVybiB7c3RyaW5nfSBUaGUgcmVzdHJpY3Rpb24sIG9uZSBvZgogKiAiZGlzYWJsZWQiLCAicmVhZE9ubHkiIG9yIHVuZGVmaW5lZCBpZiBlbmFibGVkIG9yIG90aGVyIG9iamVjdCBub3QgZGlzYWJsZWQKICovCnZhciBHZXRSZXN0cmljdGlvbiA9IG5hdGl2ZXMuR2V0UmVzdHJpY3Rpb247CgovKioKICogQHBhcmFtIHtudW1iZXJ9IGF4VHJlZUlEIFRoZSBpZCBvZiB0aGUgYWNjZXNzaWJpbGl0eSB0cmVlLgogKiBAcGFyYW0ge251bWJlcn0gbm9kZUlEIFRoZSBpZCBvZiBhIG5vZGUuCiAqIEByZXR1cm4ge3N0cmluZ30gVGhlIGNoZWNrZWQgc3RhdGUsIGFzIHVuZGVmaW5lZCwgInRydWUiLCAiZmFsc2UiIG9yICJtaXhlZCIuCiAqLwp2YXIgR2V0Q2hlY2tlZCA9IG5hdGl2ZXMuR2V0Q2hlY2tlZDsKCi8qKgogKiBAcGFyYW0ge251bWJlcn0gYXhUcmVlSUQgVGhlIGlkIG9mIHRoZSBhY2Nlc3NpYmlsaXR5IHRyZWUuCiAqIEBwYXJhbSB7bnVtYmVyfSBub2RlSUQgVGhlIGlkIG9mIGEgbm9kZS4KICogQHJldHVybiB7c3RyaW5nfSBUaGUgcm9sZSBvZiB0aGUgbm9kZSwgb3IgdW5kZWZpbmVkIGlmIHRoZSB0cmVlIG9yCiAqICAgICBub2RlIHdhc24ndCBmb3VuZC4KICovCnZhciBHZXRSb2xlID0gbmF0aXZlcy5HZXRSb2xlOwoKLyoqCiAqIEBwYXJhbSB7bnVtYmVyfSBheFRyZWVJRCBUaGUgaWQgb2YgdGhlIGFjY2Vzc2liaWxpdHkgdHJlZS4KICogQHBhcmFtIHtudW1iZXJ9IG5vZGVJRCBUaGUgaWQgb2YgYSBub2RlLgogKiBAcmV0dXJuIHs/YXV0b21hdGlvbi5SZWN0fSBUaGUgbG9jYXRpb24gb2YgdGhlIG5vZGUsIG9yIHVuZGVmaW5lZCBpZgogKiAgICAgdGhlIHRyZWUgb3Igbm9kZSB3YXNuJ3QgZm91bmQuCiAqLwp2YXIgR2V0TG9jYXRpb24gPSBuYXRpdmVzLkdldExvY2F0aW9uOwoKLyoqCiAqIEBwYXJhbSB7bnVtYmVyfSBheFRyZWVJRCBUaGUgaWQgb2YgdGhlIGFjY2Vzc2liaWxpdHkgdHJlZS4KICogQHBhcmFtIHtudW1iZXJ9IG5vZGVJRCBUaGUgaWQgb2YgYSBub2RlLgogKiBAcGFyYW0ge251bWJlcn0gc3RhcnRJbmRleCBUaGUgc3RhcnQgaW5kZXggb2YgdGhlIHJhbmdlLgogKiBAcGFyYW0ge251bWJlcn0gZW5kSW5kZXggVGhlIGVuZCBpbmRleCBvZiB0aGUgcmFuZ2UuCiAqIEByZXR1cm4gez9hdXRvbWF0aW9uLlJlY3R9IFRoZSBib3VuZGluZyBib3ggb2YgdGhlIHN1YnJhbmdlIG9mIHRoaXMgbm9kZSwKICogICAgIG9yIHRoZSBsb2NhdGlvbiBpZiB0aGVyZSBhcmUgbm8gc3VicmFuZ2VzLCBvciB1bmRlZmluZWQgaWYKICogICAgIHRoZSB0cmVlIG9yIG5vZGUgd2Fzbid0IGZvdW5kLgogKi8KdmFyIEdldEJvdW5kc0ZvclJhbmdlID0gbmF0aXZlcy5HZXRCb3VuZHNGb3JSYW5nZTsKCi8qKgogKiBAcGFyYW0ge251bWJlcn0gYXhUcmVlSUQgVGhlIGlkIG9mIHRoZSBhY2Nlc3NpYmlsaXR5IHRyZWUuCiAqIEBwYXJhbSB7bnVtYmVyfSBub2RlSUQgVGhlIGlkIG9mIGEgbm9kZS4KICogQHJldHVybiB7P2F1dG9tYXRpb24uUmVjdH0gVGhlIHVuY2xpcHBlZCBsb2NhdGlvbiBvZiB0aGUgbm9kZSwgb3IKICogdW5kZWZpbmVkIGlmIHRoZSB0cmVlIG9yIG5vZGUgd2Fzbid0IGZvdW5kLgogKi8KdmFyIEdldFVuY2xpcHBlZExvY2F0aW9uID0gbmF0aXZlcy5HZXRVbmNsaXBwZWRMb2NhdGlvbjsKCi8qKgogKiBAcGFyYW0ge251bWJlcn0gYXhUcmVlSUQgVGhlIGlkIG9mIHRoZSBhY2Nlc3NpYmlsaXR5IHRyZWUuCiAqIEBwYXJhbSB7bnVtYmVyfSBub2RlSUQgVGhlIGlkIG9mIGEgbm9kZS4KICogQHJldHVybiB7IUFycmF5LjxudW1iZXI+fSBUaGUgdGV4dCBvZmZzZXQgd2hlcmUgZWFjaCBsaW5lIHN0YXJ0cywgb3IgYW4gZW1wdHkKICogICAgIGFycmF5IGlmIHRoaXMgbm9kZSBoYXMgbm8gdGV4dCBjb250ZW50LCBvciB1bmRlZmluZWQgaWYgdGhlIHRyZWUgb3Igbm9kZQogKiAgICAgd2FzIG5vdCBmb3VuZC4KICovCnZhciBHZXRMaW5lU3RhcnRPZmZzZXRzID0gcmVxdWlyZU5hdGl2ZSgKICAgICdhdXRvbWF0aW9uSW50ZXJuYWwnKS5HZXRMaW5lU3RhcnRPZmZzZXRzOwoKLyoqCiAqIEBwYXJhbSB7bnVtYmVyfSBheFRyZWVJRCBUaGUgaWQgb2YgdGhlIGFjY2Vzc2liaWxpdHkgdHJlZS4KICogQHBhcmFtIHtudW1iZXJ9IG5vZGVJRCBUaGUgaWQgb2YgYSBub2RlLgogKiBAcGFyYW0ge3N0cmluZ30gYXR0ciBUaGUgbmFtZSBvZiBhIHN0cmluZyBhdHRyaWJ1dGUuCiAqIEByZXR1cm4gez9zdHJpbmd9IFRoZSB2YWx1ZSBvZiB0aGlzIGF0dHJpYnV0ZSwgb3IgdW5kZWZpbmVkIGlmIHRoZSB0cmVlLAogKiAgICAgbm9kZSwgb3IgYXR0cmlidXRlIHdhc24ndCBmb3VuZC4KICovCnZhciBHZXRTdHJpbmdBdHRyaWJ1dGUgPSBuYXRpdmVzLkdldFN0cmluZ0F0dHJpYnV0ZTsKCi8qKgogKiBAcGFyYW0ge251bWJlcn0gYXhUcmVlSUQgVGhlIGlkIG9mIHRoZSBhY2Nlc3NpYmlsaXR5IHRyZWUuCiAqIEBwYXJhbSB7bnVtYmVyfSBub2RlSUQgVGhlIGlkIG9mIGEgbm9kZS4KICogQHBhcmFtIHtzdHJpbmd9IGF0dHIgVGhlIG5hbWUgb2YgYW4gYXR0cmlidXRlLgogKiBAcmV0dXJuIHs/Ym9vbGVhbn0gVGhlIHZhbHVlIG9mIHRoaXMgYXR0cmlidXRlLCBvciB1bmRlZmluZWQgaWYgdGhlIHRyZWUsCiAqICAgICBub2RlLCBvciBhdHRyaWJ1dGUgd2Fzbid0IGZvdW5kLgogKi8KdmFyIEdldEJvb2xBdHRyaWJ1dGUgPSBuYXRpdmVzLkdldEJvb2xBdHRyaWJ1dGU7CgovKioKICogQHBhcmFtIHtudW1iZXJ9IGF4VHJlZUlEIFRoZSBpZCBvZiB0aGUgYWNjZXNzaWJpbGl0eSB0cmVlLgogKiBAcGFyYW0ge251bWJlcn0gbm9kZUlEIFRoZSBpZCBvZiBhIG5vZGUuCiAqIEBwYXJhbSB7c3RyaW5nfSBhdHRyIFRoZSBuYW1lIG9mIGFuIGF0dHJpYnV0ZS4KICogQHJldHVybiB7P251bWJlcn0gVGhlIHZhbHVlIG9mIHRoaXMgYXR0cmlidXRlLCBvciB1bmRlZmluZWQgaWYgdGhlIHRyZWUsCiAqICAgICBub2RlLCBvciBhdHRyaWJ1dGUgd2Fzbid0IGZvdW5kLgogKi8KdmFyIEdldEludEF0dHJpYnV0ZSA9IG5hdGl2ZXMuR2V0SW50QXR0cmlidXRlOwoKLyoqCiAqIEBwYXJhbSB7bnVtYmVyfSBheFRyZWVJRCBUaGUgaWQgb2YgdGhlIGFjY2Vzc2liaWxpdHkgdHJlZS4KICogQHBhcmFtIHtudW1iZXJ9IG5vZGVJRCBUaGUgaWQgb2YgYSBub2RlLgogKiBAcGFyYW0ge3N0cmluZ30gYXR0ciBUaGUgbmFtZSBvZiBhbiBhdHRyaWJ1dGUuCiAqIEByZXR1cm4gez9udW1iZXJ9IFRoZSB2YWx1ZSBvZiB0aGlzIGF0dHJpYnV0ZSwgb3IgdW5kZWZpbmVkIGlmIHRoZSB0cmVlLAogKiAgICAgbm9kZSwgb3IgYXR0cmlidXRlIHdhc24ndCBmb3VuZC4KICovCnZhciBHZXRGbG9hdEF0dHJpYnV0ZSA9IG5hdGl2ZXMuR2V0RmxvYXRBdHRyaWJ1dGU7CgovKioKICogQHBhcmFtIHtudW1iZXJ9IGF4VHJlZUlEIFRoZSBpZCBvZiB0aGUgYWNjZXNzaWJpbGl0eSB0cmVlLgogKiBAcGFyYW0ge251bWJlcn0gbm9kZUlEIFRoZSBpZCBvZiBhIG5vZGUuCiAqIEBwYXJhbSB7c3RyaW5nfSBhdHRyIFRoZSBuYW1lIG9mIGFuIGF0dHJpYnV0ZS4KICogQHJldHVybiB7P0FycmF5LjxudW1iZXI+fSBUaGUgdmFsdWUgb2YgdGhpcyBhdHRyaWJ1dGUsIG9yIHVuZGVmaW5lZAogKiAgICAgaWYgdGhlIHRyZWUsIG5vZGUsIG9yIGF0dHJpYnV0ZSB3YXNuJ3QgZm91bmQuCiAqLwp2YXIgR2V0SW50TGlzdEF0dHJpYnV0ZSA9CiAgICBuYXRpdmVzLkdldEludExpc3RBdHRyaWJ1dGU7CgovKioKICogQHBhcmFtIHtudW1iZXJ9IGF4VHJlZUlEIFRoZSBpZCBvZiB0aGUgYWNjZXNzaWJpbGl0eSB0cmVlLgogKiBAcGFyYW0ge251bWJlcn0gbm9kZUlEIFRoZSBpZCBvZiBhIG5vZGUuCiAqIEBwYXJhbSB7c3RyaW5nfSBhdHRyIFRoZSBuYW1lIG9mIGFuIEhUTUwgYXR0cmlidXRlLgogKiBAcmV0dXJuIHs/c3RyaW5nfSBUaGUgdmFsdWUgb2YgdGhpcyBhdHRyaWJ1dGUsIG9yIHVuZGVmaW5lZCBpZiB0aGUgdHJlZSwKICogICAgIG5vZGUsIG9yIGF0dHJpYnV0ZSB3YXNuJ3QgZm91bmQuCiAqLwp2YXIgR2V0SHRtbEF0dHJpYnV0ZSA9IG5hdGl2ZXMuR2V0SHRtbEF0dHJpYnV0ZTsKCi8qKgogKiBAcGFyYW0ge251bWJlcn0gYXhUcmVlSUQgVGhlIGlkIG9mIHRoZSBhY2Nlc3NpYmlsaXR5IHRyZWUuCiAqIEBwYXJhbSB7bnVtYmVyfSBub2RlSUQgVGhlIGlkIG9mIGEgbm9kZS4KICogQHJldHVybiB7YXV0b21hdGlvbi5OYW1lRnJvbVR5cGV9IFRoZSBzb3VyY2Ugb2YgdGhlIG5vZGUncyBuYW1lLgogKi8KdmFyIEdldE5hbWVGcm9tID0gbmF0aXZlcy5HZXROYW1lRnJvbTsKCi8qKgogKiBAcGFyYW0ge251bWJlcn0gYXhUcmVlSUQgVGhlIGlkIG9mIHRoZSBhY2Nlc3NpYmlsaXR5IHRyZWUuCiAqIEBwYXJhbSB7bnVtYmVyfSBub2RlSUQgVGhlIGlkIG9mIGEgbm9kZS4KICogQHJldHVybiB7Ym9vbGVhbn0KICovCnZhciBHZXRCb2xkID0gbmF0aXZlcy5HZXRCb2xkOwoKLyoqCiAqIEBwYXJhbSB7bnVtYmVyfSBheFRyZWVJRCBUaGUgaWQgb2YgdGhlIGFjY2Vzc2liaWxpdHkgdHJlZS4KICogQHBhcmFtIHtudW1iZXJ9IG5vZGVJRCBUaGUgaWQgb2YgYSBub2RlLgogKiBAcmV0dXJuIHtib29sZWFufQogKi8KdmFyIEdldEl0YWxpYyA9IG5hdGl2ZXMuR2V0SXRhbGljOwoKLyoqCiAqIEBwYXJhbSB7bnVtYmVyfSBheFRyZWVJRCBUaGUgaWQgb2YgdGhlIGFjY2Vzc2liaWxpdHkgdHJlZS4KICogQHBhcmFtIHtudW1iZXJ9IG5vZGVJRCBUaGUgaWQgb2YgYSBub2RlLgogKiBAcmV0dXJuIHtib29sZWFufQogKi8KdmFyIEdldFVuZGVybGluZSA9IG5hdGl2ZXMuR2V0VW5kZXJsaW5lOwoKLyoqCiAqIEBwYXJhbSB7bnVtYmVyfSBheFRyZWVJRCBUaGUgaWQgb2YgdGhlIGFjY2Vzc2liaWxpdHkgdHJlZS4KICogQHBhcmFtIHtudW1iZXJ9IG5vZGVJRCBUaGUgaWQgb2YgYSBub2RlLgogKiBAcmV0dXJuIHtib29sZWFufQogKi8KdmFyIEdldExpbmVUaHJvdWdoID0gbmF0aXZlcy5HZXRMaW5lVGhyb3VnaDsKCi8qKgogKiBAcGFyYW0ge251bWJlcn0gYXhUcmVlSUQgVGhlIGlkIG9mIHRoZSBhY2Nlc3NpYmlsaXR5IHRyZWUuCiAqIEBwYXJhbSB7bnVtYmVyfSBub2RlSUQgVGhlIGlkIG9mIGEgbm9kZS4KICogQHJldHVybiB7P0FycmF5LjxhdXRvbWF0aW9uLkN1c3RvbUFjdGlvbj59IExpc3Qgb2YgY3VzdG9tIGFjdGlvbnMgb2YgdGhlCiAqICAgICBub2RlLgogKi8KdmFyIEdldEN1c3RvbUFjdGlvbnMgPSBuYXRpdmVzLkdldEN1c3RvbUFjdGlvbnM7Cgp2YXIgbG9nZ2luZyA9IHJlcXVpcmVOYXRpdmUoJ2xvZ2dpbmcnKTsKdmFyIHV0aWxzID0gcmVxdWlyZSgndXRpbHMnKTsKCi8qKgogKiBBIHNpbmdsZSBub2RlIGluIHRoZSBBdXRvbWF0aW9uIHRyZWUuCiAqIEBwYXJhbSB7QXV0b21hdGlvblJvb3ROb2RlSW1wbH0gcm9vdCBUaGUgcm9vdCBvZiB0aGUgdHJlZS4KICogQGNvbnN0cnVjdG9yCiAqLwpmdW5jdGlvbiBBdXRvbWF0aW9uTm9kZUltcGwocm9vdCkgewogIHRoaXMucm9vdEltcGwgPSByb290OwogIHRoaXMuaG9zdE5vZGVfID0gbnVsbDsKICB0aGlzLmxpc3RlbmVycyA9IHtfX3Byb3RvX186IG51bGx9Owp9CgpBdXRvbWF0aW9uTm9kZUltcGwucHJvdG90eXBlID0gewogIF9fcHJvdG9fXzogbnVsbCwKICB0cmVlSUQ6IC0xLAogIGlkOiAtMSwKICBpc1Jvb3ROb2RlOiBmYWxzZSwKCiAgZGV0YWNoOiBmdW5jdGlvbigpIHsKICAgIHRoaXMucm9vdEltcGwgPSBudWxsOwogICAgdGhpcy5ob3N0Tm9kZV8gPSBudWxsOwogICAgdGhpcy5saXN0ZW5lcnMgPSB7X19wcm90b19fOiBudWxsfTsKICB9LAoKICBnZXQgcm9vdCgpIHsKICAgIHJldHVybiB0aGlzLnJvb3RJbXBsICYmIHRoaXMucm9vdEltcGwud3JhcHBlcjsKICB9LAoKICBnZXQgcGFyZW50KCkgewogICAgaWYgKCF0aGlzLnJvb3RJbXBsKQogICAgICByZXR1cm4gdW5kZWZpbmVkOwogICAgaWYgKHRoaXMuaG9zdE5vZGVfKQogICAgICByZXR1cm4gdGhpcy5ob3N0Tm9kZV87CiAgICB2YXIgcGFyZW50SUQgPSBHZXRQYXJlbnRJRCh0aGlzLnRyZWVJRCwgdGhpcy5pZCk7CiAgICByZXR1cm4gdGhpcy5yb290SW1wbC5nZXQocGFyZW50SUQpOwogIH0sCgogIGdldCBodG1sQXR0cmlidXRlcygpIHsKICAgIHJldHVybiBHZXRIdG1sQXR0cmlidXRlcyh0aGlzLnRyZWVJRCwgdGhpcy5pZCkgfHwge307CiAgfSwKCiAgZ2V0IHN0YXRlKCkgewogICAgcmV0dXJuIEdldFN0YXRlKHRoaXMudHJlZUlELCB0aGlzLmlkKSB8fCB7fTsKICB9LAoKICBnZXQgcm9sZSgpIHsKICAgIHJldHVybiBHZXRSb2xlKHRoaXMudHJlZUlELCB0aGlzLmlkKTsKICB9LAoKICBnZXQgcmVzdHJpY3Rpb24oKSB7CiAgICByZXR1cm4gR2V0UmVzdHJpY3Rpb24odGhpcy50cmVlSUQsIHRoaXMuaWQpOwogIH0sCgogIGdldCBjaGVja2VkKCkgewogICAgcmV0dXJuIEdldENoZWNrZWQodGhpcy50cmVlSUQsIHRoaXMuaWQpOwogIH0sCgogIGdldCBsb2NhdGlvbigpIHsKICAgIHJldHVybiBHZXRMb2NhdGlvbih0aGlzLnRyZWVJRCwgdGhpcy5pZCk7CiAgfSwKCiAgYm91bmRzRm9yUmFuZ2U6IGZ1bmN0aW9uKHN0YXJ0SW5kZXgsIGVuZEluZGV4KSB7CiAgICByZXR1cm4gR2V0Qm91bmRzRm9yUmFuZ2UodGhpcy50cmVlSUQsIHRoaXMuaWQsIHN0YXJ0SW5kZXgsIGVuZEluZGV4KTsKICB9LAoKICBnZXQgdW5jbGlwcGVkTG9jYXRpb24oKSB7CiAgICB2YXIgcmVzdWx0ID0gR2V0VW5jbGlwcGVkTG9jYXRpb24odGhpcy50cmVlSUQsIHRoaXMuaWQpOwogICAgaWYgKHJlc3VsdCA9PT0gdW5kZWZpbmVkKQogICAgICByZXN1bHQgPSBHZXRMb2NhdGlvbih0aGlzLnRyZWVJRCwgdGhpcy5pZCk7CiAgICByZXR1cm4gcmVzdWx0OwogIH0sCgogIGdldCBpbmRleEluUGFyZW50KCkgewogICAgcmV0dXJuIEdldEluZGV4SW5QYXJlbnQodGhpcy50cmVlSUQsIHRoaXMuaWQpOwogIH0sCgogIGdldCBsaW5lU3RhcnRPZmZzZXRzKCkgewogICAgcmV0dXJuIEdldExpbmVTdGFydE9mZnNldHModGhpcy50cmVlSUQsIHRoaXMuaWQpOwogIH0sCgogIGdldCBjaGlsZFRyZWUoKSB7CiAgICB2YXIgY2hpbGRUcmVlSUQgPSBHZXRJbnRBdHRyaWJ1dGUodGhpcy50cmVlSUQsIHRoaXMuaWQsICdjaGlsZFRyZWVJZCcpOwogICAgaWYgKGNoaWxkVHJlZUlEKQogICAgICByZXR1cm4gQXV0b21hdGlvblJvb3ROb2RlSW1wbC5nZXQoY2hpbGRUcmVlSUQpOwogIH0sCgogIGdldCBmaXJzdENoaWxkKCkgewogICAgaWYgKCF0aGlzLnJvb3RJbXBsKQogICAgICByZXR1cm4gdW5kZWZpbmVkOwogICAgaWYgKHRoaXMuY2hpbGRUcmVlKQogICAgICByZXR1cm4gdGhpcy5jaGlsZFRyZWU7CiAgICBpZiAoIUdldENoaWxkQ291bnQodGhpcy50cmVlSUQsIHRoaXMuaWQpKQogICAgICByZXR1cm4gdW5kZWZpbmVkOwogICAgdmFyIGZpcnN0Q2hpbGRJRCA9IEdldENoaWxkSURBdEluZGV4KHRoaXMudHJlZUlELCB0aGlzLmlkLCAwKTsKICAgIHJldHVybiB0aGlzLnJvb3RJbXBsLmdldChmaXJzdENoaWxkSUQpOwogIH0sCgogIGdldCBsYXN0Q2hpbGQoKSB7CiAgICBpZiAoIXRoaXMucm9vdEltcGwpCiAgICAgIHJldHVybiB1bmRlZmluZWQ7CiAgICBpZiAodGhpcy5jaGlsZFRyZWUpCiAgICAgIHJldHVybiB0aGlzLmNoaWxkVHJlZTsKICAgIHZhciBjb3VudCA9IEdldENoaWxkQ291bnQodGhpcy50cmVlSUQsIHRoaXMuaWQpOwogICAgaWYgKCFjb3VudCkKICAgICAgcmV0dXJuIHVuZGVmaW5lZDsKICAgIHZhciBsYXN0Q2hpbGRJRCA9IEdldENoaWxkSURBdEluZGV4KHRoaXMudHJlZUlELCB0aGlzLmlkLCBjb3VudCAtIDEpOwogICAgcmV0dXJuIHRoaXMucm9vdEltcGwuZ2V0KGxhc3RDaGlsZElEKTsKICB9LAoKICBnZXQgY2hpbGRyZW4oKSB7CiAgICBpZiAoIXRoaXMucm9vdEltcGwpCiAgICAgIHJldHVybiBbXTsKCiAgICBpZiAodGhpcy5jaGlsZFRyZWUpCiAgICAgIHJldHVybiBbdGhpcy5jaGlsZFRyZWVdOwoKICAgIHZhciBjaGlsZHJlbiA9IFtdOwogICAgdmFyIGNoaWxkSWRzID0gR2V0Q2hpbGRJZHModGhpcy50cmVlSUQsIHRoaXMuaWQpOwogICAgZm9yICh2YXIgaSA9IDA7IGkgPCBjaGlsZElkcy5sZW5ndGg7ICsraSkgewogICAgICB2YXIgY2hpbGRJRCA9IGNoaWxkSWRzW2ldOwogICAgICB2YXIgY2hpbGQgPSB0aGlzLnJvb3RJbXBsLmdldChjaGlsZElEKTsKICAgICAgJEFycmF5LnB1c2goY2hpbGRyZW4sIGNoaWxkKTsKICAgIH0KICAgIHJldHVybiBjaGlsZHJlbjsKICB9LAoKICBnZXQgcHJldmlvdXNTaWJsaW5nKCkgewogICAgdmFyIHBhcmVudCA9IHRoaXMucGFyZW50OwogICAgaWYgKCFwYXJlbnQpCiAgICAgIHJldHVybiB1bmRlZmluZWQ7CiAgICBwYXJlbnQgPSBwcml2YXRlcyhwYXJlbnQpLmltcGw7CiAgICB2YXIgaW5kZXhJblBhcmVudCA9IEdldEluZGV4SW5QYXJlbnQodGhpcy50cmVlSUQsIHRoaXMuaWQpOwogICAgcmV0dXJuIHRoaXMucm9vdEltcGwuZ2V0KAogICAgICAgIEdldENoaWxkSURBdEluZGV4KHBhcmVudC50cmVlSUQsIHBhcmVudC5pZCwgaW5kZXhJblBhcmVudCAtIDEpKTsKICB9LAoKICBnZXQgbmV4dFNpYmxpbmcoKSB7CiAgICB2YXIgcGFyZW50ID0gdGhpcy5wYXJlbnQ7CiAgICBpZiAoIXBhcmVudCkKICAgICAgcmV0dXJuIHVuZGVmaW5lZDsKICAgIHBhcmVudCA9IHByaXZhdGVzKHBhcmVudCkuaW1wbDsKICAgIHZhciBpbmRleEluUGFyZW50ID0gR2V0SW5kZXhJblBhcmVudCh0aGlzLnRyZWVJRCwgdGhpcy5pZCk7CiAgICByZXR1cm4gdGhpcy5yb290SW1wbC5nZXQoCiAgICAgICAgR2V0Q2hpbGRJREF0SW5kZXgocGFyZW50LnRyZWVJRCwgcGFyZW50LmlkLCBpbmRleEluUGFyZW50ICsgMSkpOwogIH0sCgogIGdldCBuYW1lRnJvbSgpIHsKICAgIHJldHVybiBHZXROYW1lRnJvbSh0aGlzLnRyZWVJRCwgdGhpcy5pZCk7CiAgfSwKCiAgZ2V0IGJvbGQoKSB7CiAgICByZXR1cm4gR2V0Qm9sZCh0aGlzLnRyZWVJRCwgdGhpcy5pZCk7CiAgfSwKCiAgZ2V0IGl0YWxpYygpIHsKICAgIHJldHVybiBHZXRJdGFsaWModGhpcy50cmVlSUQsIHRoaXMuaWQpOwogIH0sCgogIGdldCB1bmRlcmxpbmUoKSB7CiAgICByZXR1cm4gR2V0VW5kZXJsaW5lKHRoaXMudHJlZUlELCB0aGlzLmlkKTsKICB9LAoKICBnZXQgbGluZVRocm91Z2goKSB7CiAgICByZXR1cm4gR2V0TGluZVRocm91Z2godGhpcy50cmVlSUQsIHRoaXMuaWQpOwogIH0sCgogIGdldCBjdXN0b21BY3Rpb25zKCkgewogICAgcmV0dXJuIEdldEN1c3RvbUFjdGlvbnModGhpcy50cmVlSUQsIHRoaXMuaWQpOwogIH0sCgogIGRvRGVmYXVsdDogZnVuY3Rpb24oKSB7CiAgICB0aGlzLnBlcmZvcm1BY3Rpb25fKCdkb0RlZmF1bHQnKTsKICB9LAoKICBmb2N1czogZnVuY3Rpb24oKSB7CiAgICB0aGlzLnBlcmZvcm1BY3Rpb25fKCdmb2N1cycpOwogIH0sCgogIGdldEltYWdlRGF0YTogZnVuY3Rpb24obWF4V2lkdGgsIG1heEhlaWdodCkgewogICAgdGhpcy5wZXJmb3JtQWN0aW9uXygnZ2V0SW1hZ2VEYXRhJywKICAgICAgICAgICAgICAgICAgICAgICAgeyBtYXhXaWR0aDogbWF4V2lkdGgsCiAgICAgICAgICAgICAgICAgICAgICAgICAgbWF4SGVpZ2h0OiBtYXhIZWlnaHQgfSk7CiAgfSwKCiAgaGl0VGVzdDogZnVuY3Rpb24oeCwgeSwgZXZlbnRUb0ZpcmUpIHsKICAgIHRoaXMuaGl0VGVzdEludGVybmFsKHgsIHksIGV2ZW50VG9GaXJlKTsKICB9LAoKICBoaXRUZXN0V2l0aFJlcGx5OiBmdW5jdGlvbih4LCB5LCBvcHRfY2FsbGJhY2spIHsKICAgIHRoaXMuaGl0VGVzdEludGVybmFsKHgsIHksICdoaXRUZXN0UmVzdWx0Jywgb3B0X2NhbGxiYWNrKTsKICB9LAoKICBoaXRUZXN0SW50ZXJuYWw6IGZ1bmN0aW9uKHgsIHksIGV2ZW50VG9GaXJlLCBvcHRfY2FsbGJhY2spIHsKICAgIC8vIENvbnZlcnQgZnJvbSBnbG9iYWwgdG8gdHJlZS1yZWxhdGl2ZSBjb29yZGluYXRlcy4KICAgIHZhciBsb2NhdGlvbiA9IEdldExvY2F0aW9uKHRoaXMudHJlZUlELCBHZXRSb290SUQodGhpcy50cmVlSUQpKTsKICAgIHRoaXMucGVyZm9ybUFjdGlvbl8oJ2hpdFRlc3QnLAogICAgICAgICAgICAgICAgICAgICAgICB7IHg6IE1hdGguZmxvb3IoeCAtIGxvY2F0aW9uLmxlZnQpLAogICAgICAgICAgICAgICAgICAgICAgICAgIHk6IE1hdGguZmxvb3IoeSAtIGxvY2F0aW9uLnRvcCksCiAgICAgICAgICAgICAgICAgICAgICAgICAgZXZlbnRUb0ZpcmU6IGV2ZW50VG9GaXJlIH0sCiAgICAgICAgICAgICAgICAgICAgICAgIG9wdF9jYWxsYmFjayk7CiAgfSwKCiAgbWFrZVZpc2libGU6IGZ1bmN0aW9uKCkgewogICAgdGhpcy5wZXJmb3JtQWN0aW9uXygnbWFrZVZpc2libGUnKTsKICB9LAoKICBwZXJmb3JtQ3VzdG9tQWN0aW9uOiBmdW5jdGlvbihjdXN0b21BY3Rpb25JZCkgewogICAgdGhpcy5wZXJmb3JtQWN0aW9uXygnY3VzdG9tQWN0aW9uJywgeyBjdXN0b21BY3Rpb25JRDogY3VzdG9tQWN0aW9uSWQgfSk7CiAgfSwKCiAgcmVzdW1lTWVkaWE6IGZ1bmN0aW9uKCkgewogICAgdGhpcy5wZXJmb3JtQWN0aW9uXygncmVzdW1lTWVkaWEnKTsKICB9LAoKICBzY3JvbGxCYWNrd2FyZDogZnVuY3Rpb24ob3B0X2NhbGxiYWNrKSB7CiAgICB0aGlzLnBlcmZvcm1BY3Rpb25fKCdzY3JvbGxCYWNrd2FyZCcsIHt9LCBvcHRfY2FsbGJhY2spOwogIH0sCgogIHNjcm9sbEZvcndhcmQ6IGZ1bmN0aW9uKG9wdF9jYWxsYmFjaykgewogICAgdGhpcy5wZXJmb3JtQWN0aW9uXygnc2Nyb2xsRm9yd2FyZCcsIHt9LCBvcHRfY2FsbGJhY2spOwogIH0sCgogIHNjcm9sbFVwOiBmdW5jdGlvbihvcHRfY2FsbGJhY2spIHsKICAgIHRoaXMucGVyZm9ybUFjdGlvbl8oJ3Njcm9sbFVwJywge30sIG9wdF9jYWxsYmFjayk7CiAgfSwKCiAgc2Nyb2xsRG93bjogZnVuY3Rpb24ob3B0X2NhbGxiYWNrKSB7CiAgICB0aGlzLnBlcmZvcm1BY3Rpb25fKCdzY3JvbGxEb3duJywge30sIG9wdF9jYWxsYmFjayk7CiAgfSwKCiAgc2Nyb2xsTGVmdDogZnVuY3Rpb24ob3B0X2NhbGxiYWNrKSB7CiAgICB0aGlzLnBlcmZvcm1BY3Rpb25fKCdzY3JvbGxMZWZ0Jywge30sIG9wdF9jYWxsYmFjayk7CiAgfSwKCiAgc2Nyb2xsUmlnaHQ6IGZ1bmN0aW9uKG9wdF9jYWxsYmFjaykgewogICAgdGhpcy5wZXJmb3JtQWN0aW9uXygnc2Nyb2xsUmlnaHQnLCB7fSwgb3B0X2NhbGxiYWNrKTsKICB9LAoKICBzZXRTZWxlY3Rpb246IGZ1bmN0aW9uKHN0YXJ0SW5kZXgsIGVuZEluZGV4KSB7CiAgICBpZiAodGhpcy5zdGF0ZS5lZGl0YWJsZSkgewogICAgICB0aGlzLnBlcmZvcm1BY3Rpb25fKCdzZXRTZWxlY3Rpb24nLAogICAgICAgICAgICAgICAgICAgICAgICAgIHsgZm9jdXNOb2RlSUQ6IHRoaXMuaWQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBhbmNob3JPZmZzZXQ6IHN0YXJ0SW5kZXgsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBmb2N1c09mZnNldDogZW5kSW5kZXggfSk7CiAgICB9CiAgfSwKCiAgc2V0U2VxdWVudGlhbEZvY3VzTmF2aWdhdGlvblN0YXJ0aW5nUG9pbnQ6IGZ1bmN0aW9uKCkgewogICAgdGhpcy5wZXJmb3JtQWN0aW9uXygnc2V0U2VxdWVudGlhbEZvY3VzTmF2aWdhdGlvblN0YXJ0aW5nUG9pbnQnKTsKICB9LAoKICBzaG93Q29udGV4dE1lbnU6IGZ1bmN0aW9uKCkgewogICAgdGhpcy5wZXJmb3JtQWN0aW9uXygnc2hvd0NvbnRleHRNZW51Jyk7CiAgfSwKCiAgc3RhcnREdWNraW5nTWVkaWE6IGZ1bmN0aW9uKCkgewogICAgdGhpcy5wZXJmb3JtQWN0aW9uXygnc3RhcnREdWNraW5nTWVkaWEnKTsKICB9LAoKICBzdG9wRHVja2luZ01lZGlhOiBmdW5jdGlvbigpIHsKICAgIHRoaXMucGVyZm9ybUFjdGlvbl8oJ3N0b3BEdWNraW5nTWVkaWEnKTsKICB9LAoKICBzdXNwZW5kTWVkaWE6IGZ1bmN0aW9uKCkgewogICAgdGhpcy5wZXJmb3JtQWN0aW9uXygnc3VzcGVuZE1lZGlhJyk7CiAgfSwKCiAgZG9tUXVlcnlTZWxlY3RvcjogZnVuY3Rpb24oc2VsZWN0b3IsIGNhbGxiYWNrKSB7CiAgICBpZiAoIXRoaXMucm9vdEltcGwpCiAgICAgIGNhbGxiYWNrKCk7CiAgICBhdXRvbWF0aW9uSW50ZXJuYWwucXVlcnlTZWxlY3RvcigKICAgICAgeyB0cmVlSUQ6IHRoaXMucm9vdEltcGwudHJlZUlELAogICAgICAgIGF1dG9tYXRpb25Ob2RlSUQ6IHRoaXMuaWQsCiAgICAgICAgc2VsZWN0b3I6IHNlbGVjdG9yIH0sCiAgICAgICRGdW5jdGlvbi5iaW5kKHRoaXMuZG9tUXVlcnlTZWxlY3RvckNhbGxiYWNrXywgdGhpcywgY2FsbGJhY2spKTsKICB9LAoKICBmaW5kOiBmdW5jdGlvbihwYXJhbXMpIHsKICAgIHJldHVybiB0aGlzLmZpbmRJbnRlcm5hbF8ocGFyYW1zKTsKICB9LAoKICBmaW5kQWxsOiBmdW5jdGlvbihwYXJhbXMpIHsKICAgIHJldHVybiB0aGlzLmZpbmRJbnRlcm5hbF8ocGFyYW1zLCBbXSk7CiAgfSwKCiAgbWF0Y2hlczogZnVuY3Rpb24ocGFyYW1zKSB7CiAgICByZXR1cm4gdGhpcy5tYXRjaEludGVybmFsXyhwYXJhbXMpOwogIH0sCgogIGFkZEV2ZW50TGlzdGVuZXI6IGZ1bmN0aW9uKGV2ZW50VHlwZSwgY2FsbGJhY2ssIGNhcHR1cmUpIHsKICAgIHRoaXMucmVtb3ZlRXZlbnRMaXN0ZW5lcihldmVudFR5cGUsIGNhbGxiYWNrKTsKICAgIGlmICghdGhpcy5saXN0ZW5lcnNbZXZlbnRUeXBlXSkKICAgICAgdGhpcy5saXN0ZW5lcnNbZXZlbnRUeXBlXSA9IFtdOwogICAgJEFycmF5LnB1c2godGhpcy5saXN0ZW5lcnNbZXZlbnRUeXBlXSwgewogICAgICBfX3Byb3RvX186IG51bGwsCiAgICAgIGNhbGxiYWNrOiBjYWxsYmFjaywKICAgICAgY2FwdHVyZTogISFjYXB0dXJlLAogICAgfSk7CiAgfSwKCiAgLy8gVE9ETyhkdHNlbmcvYWJveGhhbGwpOiBDaGVjayB0aGlzIGltcGwgYWdhaW5zdCBzcGVjLgogIHJlbW92ZUV2ZW50TGlzdGVuZXI6IGZ1bmN0aW9uKGV2ZW50VHlwZSwgY2FsbGJhY2spIHsKICAgIGlmICh0aGlzLmxpc3RlbmVyc1tldmVudFR5cGVdKSB7CiAgICAgIHZhciBsaXN0ZW5lcnMgPSB0aGlzLmxpc3RlbmVyc1tldmVudFR5cGVdOwogICAgICBmb3IgKHZhciBpID0gMDsgaSA8IGxpc3RlbmVycy5sZW5ndGg7IGkrKykgewogICAgICAgIGlmIChjYWxsYmFjayA9PT0gbGlzdGVuZXJzW2ldLmNhbGxiYWNrKQogICAgICAgICAgJEFycmF5LnNwbGljZShsaXN0ZW5lcnMsIGksIDEpOwogICAgICB9CiAgICB9CiAgfSwKCiAgdG9KU09OOiBmdW5jdGlvbigpIHsKICAgIHJldHVybiB7IHRyZWVJRDogdGhpcy50cmVlSUQsCiAgICAgICAgICAgICBpZDogdGhpcy5pZCwKICAgICAgICAgICAgIHJvbGU6IHRoaXMucm9sZSwKICAgICAgICAgICAgIGF0dHJpYnV0ZXM6IHRoaXMuYXR0cmlidXRlcyB9OwogIH0sCgogIGRpc3BhdGNoRXZlbnQ6IGZ1bmN0aW9uKGV2ZW50VHlwZSwgZXZlbnRGcm9tLCBtb3VzZVgsIG1vdXNlWSkgewogICAgdmFyIHBhdGggPSBbXTsKICAgIHZhciBwYXJlbnQgPSB0aGlzLnBhcmVudDsKICAgIHdoaWxlIChwYXJlbnQpIHsKICAgICAgJEFycmF5LnB1c2gocGF0aCwgcGFyZW50KTsKICAgICAgcGFyZW50ID0gcGFyZW50LnBhcmVudDsKICAgIH0KICAgIHZhciBldmVudCA9IG5ldyBBdXRvbWF0aW9uRXZlbnQoZXZlbnRUeXBlLCB0aGlzLndyYXBwZXIsIGV2ZW50RnJvbSk7CiAgICBldmVudC5tb3VzZVggPSBtb3VzZVg7CiAgICBldmVudC5tb3VzZVkgPSBtb3VzZVk7CgogICAgLy8gRGlzcGF0Y2ggdGhlIGV2ZW50IHRocm91Z2ggdGhlIHByb3BhZ2F0aW9uIHBhdGggaW4gdGhyZWUgcGhhc2VzOgogICAgLy8gLSBjYXB0dXJpbmc6IHN0YXJ0aW5nIGZyb20gdGhlIHJvb3QgYW5kIGdvaW5nIGRvd24gdG8gdGhlIHRhcmdldCdzIHBhcmVudAogICAgLy8gLSB0YXJnZXRpbmc6IGRpc3BhdGNoaW5nIHRoZSBldmVudCBvbiB0aGUgdGFyZ2V0IGl0c2VsZgogICAgLy8gLSBidWJibGluZzogc3RhcnRpbmcgZnJvbSB0aGUgdGFyZ2V0J3MgcGFyZW50LCBnb2luZyBiYWNrIHVwIHRvIHRoZSByb290LgogICAgLy8gQXQgYW55IHN0YWdlLCBhIGxpc3RlbmVyIG1heSBjYWxsIHN0b3BQcm9wYWdhdGlvbigpIG9uIHRoZSBldmVudCwgd2hpY2gKICAgIC8vIHdpbGwgaW1tZWRpYXRlbHkgc3RvcCBldmVudCBwcm9wYWdhdGlvbiB0aHJvdWdoIHRoaXMgcGF0aC4KICAgIGlmICh0aGlzLmRpc3BhdGNoRXZlbnRBdENhcHR1cmluZ18oZXZlbnQsIHBhdGgpKSB7CiAgICAgIGlmICh0aGlzLmRpc3BhdGNoRXZlbnRBdFRhcmdldGluZ18oZXZlbnQsIHBhdGgpKQogICAgICAgIHRoaXMuZGlzcGF0Y2hFdmVudEF0QnViYmxpbmdfKGV2ZW50LCBwYXRoKTsKICAgIH0KICB9LAoKICB0b1N0cmluZzogZnVuY3Rpb24oKSB7CiAgICB2YXIgcGFyZW50SUQgPSBHZXRQYXJlbnRJRCh0aGlzLnRyZWVJRCwgdGhpcy5pZCk7CiAgICB2YXIgY2hpbGRUcmVlSUQgPSBHZXRJbnRBdHRyaWJ1dGUodGhpcy50cmVlSUQsIHRoaXMuaWQsICdjaGlsZFRyZWVJZCcpOwogICAgdmFyIGNvdW50ID0gR2V0Q2hpbGRDb3VudCh0aGlzLnRyZWVJRCwgdGhpcy5pZCk7CiAgICB2YXIgY2hpbGRJRHMgPSBbXTsKICAgIGZvciAodmFyIGkgPSAwOyBpIDwgY291bnQ7ICsraSkgewogICAgICB2YXIgY2hpbGRJRCA9IEdldENoaWxkSURBdEluZGV4KHRoaXMudHJlZUlELCB0aGlzLmlkLCBpKTsKICAgICAgJEFycmF5LnB1c2goY2hpbGRJRHMsIGNoaWxkSUQpOwogICAgfQoKICAgIHZhciByZXN1bHQgPSAnbm9kZSBpZD0nICsgdGhpcy5pZCArCiAgICAgICAgJyByb2xlPScgKyB0aGlzLnJvbGUgKwogICAgICAgICcgc3RhdGU9JyArICRKU09OLnN0cmluZ2lmeSh0aGlzLnN0YXRlKSArCiAgICAgICAgJyBwYXJlbnRJRD0nICsgcGFyZW50SUQgKwogICAgICAgICcgY2hpbGRJZHM9JyArICRKU09OLnN0cmluZ2lmeShjaGlsZElEcyk7CiAgICBpZiAodGhpcy5ob3N0Tm9kZV8pIHsKICAgICAgdmFyIGhvc3ROb2RlSW1wbCA9IHByaXZhdGVzKHRoaXMuaG9zdE5vZGVfKS5pbXBsOwogICAgICByZXN1bHQgKz0gJyBob3N0IHRyZWVJRD0nICsgaG9zdE5vZGVJbXBsLnRyZWVJRCArCiAgICAgICAgICAnIGhvc3Qgbm9kZUlEPScgKyBob3N0Tm9kZUltcGwuaWQ7CiAgICB9CiAgICBpZiAoY2hpbGRUcmVlSUQpCiAgICAgIHJlc3VsdCArPSAnIGNoaWxkVHJlZUlEPScgKyBjaGlsZFRyZWVJRDsKICAgIHJldHVybiByZXN1bHQ7CiAgfSwKCiAgZGlzcGF0Y2hFdmVudEF0Q2FwdHVyaW5nXzogZnVuY3Rpb24oZXZlbnQsIHBhdGgpIHsKICAgIHByaXZhdGVzKGV2ZW50KS5pbXBsLmV2ZW50UGhhc2UgPSBFdmVudC5DQVBUVVJJTkdfUEhBU0U7CiAgICBmb3IgKHZhciBpID0gcGF0aC5sZW5ndGggLSAxOyBpID49IDA7IGktLSkgewogICAgICB0aGlzLmZpcmVFdmVudExpc3RlbmVyc18ocGF0aFtpXSwgZXZlbnQpOwogICAgICBpZiAocHJpdmF0ZXMoZXZlbnQpLmltcGwucHJvcGFnYXRpb25TdG9wcGVkKQogICAgICAgIHJldHVybiBmYWxzZTsKICAgIH0KICAgIHJldHVybiB0cnVlOwogIH0sCgogIGRpc3BhdGNoRXZlbnRBdFRhcmdldGluZ186IGZ1bmN0aW9uKGV2ZW50KSB7CiAgICBwcml2YXRlcyhldmVudCkuaW1wbC5ldmVudFBoYXNlID0gRXZlbnQuQVRfVEFSR0VUOwogICAgdGhpcy5maXJlRXZlbnRMaXN0ZW5lcnNfKHRoaXMud3JhcHBlciwgZXZlbnQpOwogICAgcmV0dXJuICFwcml2YXRlcyhldmVudCkuaW1wbC5wcm9wYWdhdGlvblN0b3BwZWQ7CiAgfSwKCiAgZGlzcGF0Y2hFdmVudEF0QnViYmxpbmdfOiBmdW5jdGlvbihldmVudCwgcGF0aCkgewogICAgcHJpdmF0ZXMoZXZlbnQpLmltcGwuZXZlbnRQaGFzZSA9IEV2ZW50LkJVQkJMSU5HX1BIQVNFOwogICAgZm9yICh2YXIgaSA9IDA7IGkgPCBwYXRoLmxlbmd0aDsgaSsrKSB7CiAgICAgIHRoaXMuZmlyZUV2ZW50TGlzdGVuZXJzXyhwYXRoW2ldLCBldmVudCk7CiAgICAgIGlmIChwcml2YXRlcyhldmVudCkuaW1wbC5wcm9wYWdhdGlvblN0b3BwZWQpCiAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgfQogICAgcmV0dXJuIHRydWU7CiAgfSwKCiAgZmlyZUV2ZW50TGlzdGVuZXJzXzogZnVuY3Rpb24obm9kZSwgZXZlbnQpIHsKICAgIHZhciBub2RlSW1wbCA9IHByaXZhdGVzKG5vZGUpLmltcGw7CiAgICBpZiAoIW5vZGVJbXBsLnJvb3RJbXBsKQogICAgICByZXR1cm47CgogICAgdmFyIGxpc3RlbmVycyA9IG5vZGVJbXBsLmxpc3RlbmVyc1tldmVudC50eXBlXTsKICAgIGlmICghbGlzdGVuZXJzKQogICAgICByZXR1cm47CiAgICB2YXIgZXZlbnRQaGFzZSA9IGV2ZW50LmV2ZW50UGhhc2U7CiAgICBmb3IgKHZhciBpID0gMDsgaSA8IGxpc3RlbmVycy5sZW5ndGg7IGkrKykgewogICAgICBpZiAoZXZlbnRQaGFzZSA9PSBFdmVudC5DQVBUVVJJTkdfUEhBU0UgJiYgIWxpc3RlbmVyc1tpXS5jYXB0dXJlKQogICAgICAgIGNvbnRpbnVlOwogICAgICBpZiAoZXZlbnRQaGFzZSA9PSBFdmVudC5CVUJCTElOR19QSEFTRSAmJiBsaXN0ZW5lcnNbaV0uY2FwdHVyZSkKICAgICAgICBjb250aW51ZTsKCiAgICAgIHRyeSB7CiAgICAgICAgbGlzdGVuZXJzW2ldLmNhbGxiYWNrKGV2ZW50KTsKICAgICAgfSBjYXRjaCAoZSkgewogICAgICAgIGV4Y2VwdGlvbkhhbmRsZXIuaGFuZGxlKCdFcnJvciBpbiBldmVudCBoYW5kbGVyIGZvciAnICsgZXZlbnQudHlwZSArCiAgICAgICAgICAgICcgZHVyaW5nIHBoYXNlICcgKyBldmVudFBoYXNlLCBlKTsKICAgICAgfQogICAgfQogIH0sCgogIHBlcmZvcm1BY3Rpb25fOiBmdW5jdGlvbihhY3Rpb25UeXBlLCBvcHRfYXJncywgb3B0X2NhbGxiYWNrKSB7CiAgICBpZiAoIXRoaXMucm9vdEltcGwpCiAgICAgIHJldHVybjsKCiAgICAvLyBOb3QgeWV0IGluaXRpYWxpemVkLgogICAgaWYgKHRoaXMucm9vdEltcGwudHJlZUlEID09PSB1bmRlZmluZWQgfHwKICAgICAgICB0aGlzLmlkID09PSB1bmRlZmluZWQpIHsKICAgICAgcmV0dXJuOwogICAgfQoKICAgIC8vIENoZWNrIHBlcm1pc3Npb25zLgogICAgaWYgKCFJc0ludGVyYWN0UGVybWl0dGVkKCkpIHsKICAgICAgdGhyb3cgbmV3IEVycm9yKGFjdGlvblR5cGUgKyAnIHJlcXVpcmVzIHsiZGVza3RvcCI6IHRydWV9IG9yJyArCiAgICAgICAgICAnIHsiaW50ZXJhY3QiOiB0cnVlfSBpbiB0aGUgImF1dG9tYXRpb24iIG1hbmlmZXN0IGtleS4nKTsKICAgIH0KICAgIHZhciByZXF1ZXN0SUQgPSAtMTsKICAgIGlmIChvcHRfY2FsbGJhY2spIHsKICAgICAgcmVxdWVzdElEID0gdGhpcy5yb290SW1wbC5hZGRBY3Rpb25SZXN1bHRDYWxsYmFjayhvcHRfY2FsbGJhY2spOwogICAgfQoKICAgIGF1dG9tYXRpb25JbnRlcm5hbC5wZXJmb3JtQWN0aW9uKHsgdHJlZUlEOiB0aGlzLnJvb3RJbXBsLnRyZWVJRCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYXV0b21hdGlvbk5vZGVJRDogdGhpcy5pZCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYWN0aW9uVHlwZTogYWN0aW9uVHlwZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVxdWVzdElEOiByZXF1ZXN0SUR9LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb3B0X2FyZ3MgfHwge30pOwogIH0sCgogIGRvbVF1ZXJ5U2VsZWN0b3JDYWxsYmFja186IGZ1bmN0aW9uKHVzZXJDYWxsYmFjaywgcmVzdWx0QXV0b21hdGlvbk5vZGVJRCkgewogICAgLy8gcmVzdWx0QXV0b21hdGlvbk5vZGVJRCBjb3VsZCBiZSB6ZXJvIG9yIHVuZGVmaW5lZCBvciAodW5saWtlbHkpIG51bGw7CiAgICAvLyB0aGV5IGFsbCBhbW91bnQgdG8gdGhlIHNhbWUgdGhpbmcgaGVyZSwgd2hpY2ggaXMgdGhhdCBubyBub2RlIHdhcwogICAgLy8gcmV0dXJuZWQuCiAgICBpZiAoIXJlc3VsdEF1dG9tYXRpb25Ob2RlSUQgfHwgIXRoaXMucm9vdEltcGwpIHsKICAgICAgdXNlckNhbGxiYWNrKG51bGwpOwogICAgICByZXR1cm47CiAgICB9CiAgICB2YXIgcmVzdWx0Tm9kZSA9IHRoaXMucm9vdEltcGwuZ2V0KHJlc3VsdEF1dG9tYXRpb25Ob2RlSUQpOwogICAgaWYgKCFyZXN1bHROb2RlKSB7CiAgICAgIGxvZ2dpbmcuV0FSTklORygnUXVlcnkgc2VsZWN0b3IgcmVzdWx0IG5vdCBpbiB0cmVlOiAnICsKICAgICAgICAgICAgICAgICAgICAgIHJlc3VsdEF1dG9tYXRpb25Ob2RlSUQpOwogICAgICB1c2VyQ2FsbGJhY2sobnVsbCk7CiAgICB9CiAgICB1c2VyQ2FsbGJhY2socmVzdWx0Tm9kZSk7CiAgfSwKCiAgZmluZEludGVybmFsXzogZnVuY3Rpb24ocGFyYW1zLCBvcHRfcmVzdWx0cykgewogICAgdmFyIHJlc3VsdCA9IG51bGw7CiAgICB0aGlzLmZvckFsbERlc2NlbmRhbnRzXyhmdW5jdGlvbihub2RlKSB7CiAgICAgIGlmIChwcml2YXRlcyhub2RlKS5pbXBsLm1hdGNoSW50ZXJuYWxfKHBhcmFtcykpIHsKICAgICAgICBpZiAob3B0X3Jlc3VsdHMpCiAgICAgICAgICAkQXJyYXkucHVzaChvcHRfcmVzdWx0cywgbm9kZSk7CiAgICAgICAgZWxzZQogICAgICAgICAgcmVzdWx0ID0gbm9kZTsKICAgICAgICByZXR1cm4gIW9wdF9yZXN1bHRzOwogICAgICB9CiAgICB9KTsKICAgIGlmIChvcHRfcmVzdWx0cykKICAgICAgcmV0dXJuIG9wdF9yZXN1bHRzOwogICAgcmV0dXJuIHJlc3VsdDsKICB9LAoKICAvKioKICAgKiBFeGVjdXRlcyBhIGNsb3N1cmUgZm9yIGFsbCBvZiB0aGlzIG5vZGUncyBkZXNjZW5kYW50cywgaW4gcHJlLW9yZGVyLgogICAqIEVhcmx5LW91dHMgaWYgdGhlIGNsb3N1cmUgcmV0dXJucyB0cnVlLgogICAqIEBwYXJhbSB7RnVuY3Rpb24oQXV0b21hdGlvbk5vZGUpOmJvb2xlYW59IGNsb3N1cmUgQ2xvc3VyZSB0byBiZSBleGVjdXRlZAogICAqICAgICBmb3IgZWFjaCBub2RlLiBSZXR1cm4gdHJ1ZSB0byBlYXJseS1vdXQgdGhlIHRyYXZlcnNhbC4KICAgKi8KICBmb3JBbGxEZXNjZW5kYW50c186IGZ1bmN0aW9uKGNsb3N1cmUpIHsKICAgIHZhciBzdGFjayA9ICRBcnJheS5yZXZlcnNlKHRoaXMud3JhcHBlci5jaGlsZHJlbik7CiAgICB3aGlsZSAoc3RhY2subGVuZ3RoID4gMCkgewogICAgICB2YXIgbm9kZSA9ICRBcnJheS5wb3Aoc3RhY2spOwogICAgICBpZiAoY2xvc3VyZShub2RlKSkKICAgICAgICByZXR1cm47CgogICAgICB2YXIgY2hpbGRyZW4gPSBub2RlLmNoaWxkcmVuOwogICAgICBmb3IgKHZhciBpID0gY2hpbGRyZW4ubGVuZ3RoIC0gMTsgaSA+PSAwOyBpLS0pCiAgICAgICAgJEFycmF5LnB1c2goc3RhY2ssIGNoaWxkcmVuW2ldKTsKICAgIH0KICB9LAoKICBtYXRjaEludGVybmFsXzogZnVuY3Rpb24ocGFyYW1zKSB7CiAgICBpZiAoJE9iamVjdC5rZXlzKHBhcmFtcykubGVuZ3RoID09PSAwKQogICAgICByZXR1cm4gZmFsc2U7CgogICAgaWYgKCdyb2xlJyBpbiBwYXJhbXMgJiYgdGhpcy5yb2xlICE9IHBhcmFtcy5yb2xlKQogICAgICAgIHJldHVybiBmYWxzZTsKCiAgICBpZiAoJ3N0YXRlJyBpbiBwYXJhbXMpIHsKICAgICAgZm9yICh2YXIgc3RhdGUgaW4gcGFyYW1zLnN0YXRlKSB7CiAgICAgICAgaWYgKHBhcmFtcy5zdGF0ZVtzdGF0ZV0gIT0gKHN0YXRlIGluIHRoaXMuc3RhdGUpKQogICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICB9CiAgICB9CiAgICBpZiAoJ2F0dHJpYnV0ZXMnIGluIHBhcmFtcykgewogICAgICBmb3IgKHZhciBhdHRyaWJ1dGUgaW4gcGFyYW1zLmF0dHJpYnV0ZXMpIHsKICAgICAgICB2YXIgYXR0clZhbHVlID0gcGFyYW1zLmF0dHJpYnV0ZXNbYXR0cmlidXRlXTsKICAgICAgICBpZiAodHlwZW9mIGF0dHJWYWx1ZSAhPSAnb2JqZWN0JykgewogICAgICAgICAgaWYgKHRoaXNbYXR0cmlidXRlXSAhPT0gYXR0clZhbHVlKQogICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgfSBlbHNlIGlmIChhdHRyVmFsdWUgaW5zdGFuY2VvZiAkUmVnRXhwLnNlbGYpIHsKICAgICAgICAgIGlmICh0eXBlb2YgdGhpc1thdHRyaWJ1dGVdICE9ICdzdHJpbmcnKQogICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgICBpZiAoIWF0dHJWYWx1ZS50ZXN0KHRoaXNbYXR0cmlidXRlXSkpCiAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgLy8gVE9ETyhhYm94aGFsbCk6IGhhbmRsZSBpbnRsaXN0IGNhc2UuCiAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgfQogICAgICB9CiAgICB9CiAgICByZXR1cm4gdHJ1ZTsKICB9Cn07Cgp2YXIgc3RyaW5nQXR0cmlidXRlcyA9IFsKICAgICdhY2Nlc3NLZXknLAogICAgJ2FyaWFJbnZhbGlkVmFsdWUnLAogICAgJ2F1dG9Db21wbGV0ZScsCiAgICAnY2xhc3NOYW1lJywKICAgICdjb250YWluZXJMaXZlUmVsZXZhbnQnLAogICAgJ2NvbnRhaW5lckxpdmVTdGF0dXMnLAogICAgJ2Rlc2NyaXB0aW9uJywKICAgICdkaXNwbGF5JywKICAgICdodG1sVGFnJywKICAgICdpbWFnZURhdGFVcmwnLAogICAgJ2xhbmd1YWdlJywKICAgICdsaXZlUmVsZXZhbnQnLAogICAgJ2xpdmVTdGF0dXMnLAogICAgJ25hbWUnLAogICAgJ3BsYWNlaG9sZGVyJywKICAgICdyb2xlRGVzY3JpcHRpb24nLAogICAgJ3RleHRJbnB1dFR5cGUnLAogICAgJ3VybCcsCiAgICAndmFsdWUnXTsKCnZhciBib29sQXR0cmlidXRlcyA9IFsKICAgICdidXN5JywKICAgICdjbGlja2FibGUnLAogICAgJ2NvbnRhaW5lckxpdmVBdG9taWMnLAogICAgJ2NvbnRhaW5lckxpdmVCdXN5JywKICAgICdsaXZlQXRvbWljJywKICAgICdzY3JvbGxhYmxlJwpdOwoKdmFyIGludEF0dHJpYnV0ZXMgPSBbCiAgICAnYmFja2dyb3VuZENvbG9yJywKICAgICdjb2xvcicsCiAgICAnY29sb3JWYWx1ZScsCiAgICAnaGllcmFyY2hpY2FsTGV2ZWwnLAogICAgJ3Bvc0luU2V0JywKICAgICdzY3JvbGxYJywKICAgICdzY3JvbGxYTWF4JywKICAgICdzY3JvbGxYTWluJywKICAgICdzY3JvbGxZJywKICAgICdzY3JvbGxZTWF4JywKICAgICdzY3JvbGxZTWluJywKICAgICdzZXRTaXplJywKICAgICd0YWJsZUNlbGxDb2x1bW5JbmRleCcsCiAgICAnYXJpYUNlbGxDb2x1bW5JbmRleCcsCiAgICAndGFibGVDZWxsQ29sdW1uU3BhbicsCiAgICAndGFibGVDZWxsUm93SW5kZXgnLAogICAgJ2FyaWFDZWxsUm93SW5kZXgnLAogICAgJ3RhYmxlQ2VsbFJvd1NwYW4nLAogICAgJ3RhYmxlQ29sdW1uQ291bnQnLAogICAgJ2FyaWFDb2x1bW5Db3VudCcsCiAgICAndGFibGVDb2x1bW5JbmRleCcsCiAgICAndGFibGVSb3dDb3VudCcsCiAgICAnYXJpYVJvd0NvdW50JywKICAgICd0YWJsZVJvd0luZGV4JywKICAgICd0ZXh0U2VsRW5kJywKICAgICd0ZXh0U2VsU3RhcnQnXTsKCnZhciBub2RlUmVmQXR0cmlidXRlcyA9IFsKICAgIFsnYWN0aXZlZGVzY2VuZGFudElkJywgJ2FjdGl2ZURlc2NlbmRhbnQnXSwKICAgIFsnaW5QYWdlTGlua1RhcmdldElkJywgJ2luUGFnZUxpbmtUYXJnZXQnXSwKICAgIFsnbmV4dEZvY3VzSWQnLCAnbmV4dEZvY3VzJ10sCiAgICBbJ25leHRPbkxpbmVJZCcsICduZXh0T25MaW5lJ10sCiAgICBbJ3ByZXZpb3VzRm9jdXNJZCcsICdwcmV2aW91c0ZvY3VzJ10sCiAgICBbJ3ByZXZpb3VzT25MaW5lSWQnLCAncHJldmlvdXNPbkxpbmUnXSwKICAgIFsndGFibGVDb2x1bW5IZWFkZXJJZCcsICd0YWJsZUNvbHVtbkhlYWRlciddLAogICAgWyd0YWJsZUhlYWRlcklkJywgJ3RhYmxlSGVhZGVyJ10sCiAgICBbJ3RhYmxlUm93SGVhZGVySWQnLCAndGFibGVSb3dIZWFkZXInXV07Cgp2YXIgaW50TGlzdEF0dHJpYnV0ZXMgPSBbCiAgICAnbGluZUJyZWFrcycsCiAgICAnbWFya2VyRW5kcycsCiAgICAnbWFya2VyU3RhcnRzJywKICAgICdtYXJrZXJUeXBlcycsCiAgICAnd29yZEVuZHMnLAogICAgJ3dvcmRTdGFydHMnXTsKCnZhciBub2RlUmVmTGlzdEF0dHJpYnV0ZXMgPSBbCiAgICBbJ2NvbnRyb2xzSWRzJywgJ2NvbnRyb2xzJ10sCiAgICBbJ2Rlc2NyaWJlZGJ5SWRzJywgJ2Rlc2NyaWJlZEJ5J10sCiAgICBbJ2Zsb3d0b0lkcycsICdmbG93VG8nXSwKICAgIFsnbGFiZWxsZWRieUlkcycsICdsYWJlbGxlZEJ5J11dOwoKdmFyIGZsb2F0QXR0cmlidXRlcyA9IFsKICAgICd2YWx1ZUZvclJhbmdlJywKICAgICdtaW5WYWx1ZUZvclJhbmdlJywKICAgICdtYXhWYWx1ZUZvclJhbmdlJ107Cgp2YXIgaHRtbEF0dHJpYnV0ZXMgPSBbCiAgICBbJ3R5cGUnLCAnaW5wdXRUeXBlJ11dOwoKdmFyIHB1YmxpY0F0dHJpYnV0ZXMgPSBbXTsKCiRBcnJheS5mb3JFYWNoKHN0cmluZ0F0dHJpYnV0ZXMsIGZ1bmN0aW9uKGF0dHJpYnV0ZU5hbWUpIHsKICAkQXJyYXkucHVzaChwdWJsaWNBdHRyaWJ1dGVzLCBhdHRyaWJ1dGVOYW1lKTsKICAkT2JqZWN0LmRlZmluZVByb3BlcnR5KEF1dG9tYXRpb25Ob2RlSW1wbC5wcm90b3R5cGUsIGF0dHJpYnV0ZU5hbWUsIHsKICAgIF9fcHJvdG9fXzogbnVsbCwKICAgIGdldDogZnVuY3Rpb24oKSB7CiAgICAgIHJldHVybiBHZXRTdHJpbmdBdHRyaWJ1dGUodGhpcy50cmVlSUQsIHRoaXMuaWQsIGF0dHJpYnV0ZU5hbWUpOwogICAgfQogIH0pOwp9KTsKCiRBcnJheS5mb3JFYWNoKGJvb2xBdHRyaWJ1dGVzLCBmdW5jdGlvbihhdHRyaWJ1dGVOYW1lKSB7CiAgJEFycmF5LnB1c2gocHVibGljQXR0cmlidXRlcywgYXR0cmlidXRlTmFtZSk7CiAgJE9iamVjdC5kZWZpbmVQcm9wZXJ0eShBdXRvbWF0aW9uTm9kZUltcGwucHJvdG90eXBlLCBhdHRyaWJ1dGVOYW1lLCB7CiAgICBfX3Byb3RvX186IG51bGwsCiAgICBnZXQ6IGZ1bmN0aW9uKCkgewogICAgICByZXR1cm4gR2V0Qm9vbEF0dHJpYnV0ZSh0aGlzLnRyZWVJRCwgdGhpcy5pZCwgYXR0cmlidXRlTmFtZSk7CiAgICB9CiAgfSk7Cn0pOwoKJEFycmF5LmZvckVhY2goaW50QXR0cmlidXRlcywgZnVuY3Rpb24oYXR0cmlidXRlTmFtZSkgewogICRBcnJheS5wdXNoKHB1YmxpY0F0dHJpYnV0ZXMsIGF0dHJpYnV0ZU5hbWUpOwogICRPYmplY3QuZGVmaW5lUHJvcGVydHkoQXV0b21hdGlvbk5vZGVJbXBsLnByb3RvdHlwZSwgYXR0cmlidXRlTmFtZSwgewogICAgX19wcm90b19fOiBudWxsLAogICAgZ2V0OiBmdW5jdGlvbigpIHsKICAgICAgcmV0dXJuIEdldEludEF0dHJpYnV0ZSh0aGlzLnRyZWVJRCwgdGhpcy5pZCwgYXR0cmlidXRlTmFtZSk7CiAgICB9CiAgfSk7Cn0pOwoKJEFycmF5LmZvckVhY2gobm9kZVJlZkF0dHJpYnV0ZXMsIGZ1bmN0aW9uKHBhcmFtcykgewogIHZhciBzcmNBdHRyaWJ1dGVOYW1lID0gcGFyYW1zWzBdOwogIHZhciBkc3RBdHRyaWJ1dGVOYW1lID0gcGFyYW1zWzFdOwogICRBcnJheS5wdXNoKHB1YmxpY0F0dHJpYnV0ZXMsIGRzdEF0dHJpYnV0ZU5hbWUpOwogICRPYmplY3QuZGVmaW5lUHJvcGVydHkoQXV0b21hdGlvbk5vZGVJbXBsLnByb3RvdHlwZSwgZHN0QXR0cmlidXRlTmFtZSwgewogICAgX19wcm90b19fOiBudWxsLAogICAgZ2V0OiBmdW5jdGlvbigpIHsKICAgICAgdmFyIGlkID0gR2V0SW50QXR0cmlidXRlKHRoaXMudHJlZUlELCB0aGlzLmlkLCBzcmNBdHRyaWJ1dGVOYW1lKTsKICAgICAgaWYgKGlkICYmIHRoaXMucm9vdEltcGwpCiAgICAgICAgcmV0dXJuIHRoaXMucm9vdEltcGwuZ2V0KGlkKTsKICAgICAgZWxzZQogICAgICAgIHJldHVybiB1bmRlZmluZWQ7CiAgICB9CiAgfSk7Cn0pOwoKJEFycmF5LmZvckVhY2goaW50TGlzdEF0dHJpYnV0ZXMsIGZ1bmN0aW9uKGF0dHJpYnV0ZU5hbWUpIHsKICAkQXJyYXkucHVzaChwdWJsaWNBdHRyaWJ1dGVzLCBhdHRyaWJ1dGVOYW1lKTsKICAkT2JqZWN0LmRlZmluZVByb3BlcnR5KEF1dG9tYXRpb25Ob2RlSW1wbC5wcm90b3R5cGUsIGF0dHJpYnV0ZU5hbWUsIHsKICAgIF9fcHJvdG9fXzogbnVsbCwKICAgIGdldDogZnVuY3Rpb24oKSB7CiAgICAgIHJldHVybiBHZXRJbnRMaXN0QXR0cmlidXRlKHRoaXMudHJlZUlELCB0aGlzLmlkLCBhdHRyaWJ1dGVOYW1lKTsKICAgIH0KICB9KTsKfSk7CgokQXJyYXkuZm9yRWFjaChub2RlUmVmTGlzdEF0dHJpYnV0ZXMsIGZ1bmN0aW9uKHBhcmFtcykgewogIHZhciBzcmNBdHRyaWJ1dGVOYW1lID0gcGFyYW1zWzBdOwogIHZhciBkc3RBdHRyaWJ1dGVOYW1lID0gcGFyYW1zWzFdOwogICRBcnJheS5wdXNoKHB1YmxpY0F0dHJpYnV0ZXMsIGRzdEF0dHJpYnV0ZU5hbWUpOwogICRPYmplY3QuZGVmaW5lUHJvcGVydHkoQXV0b21hdGlvbk5vZGVJbXBsLnByb3RvdHlwZSwgZHN0QXR0cmlidXRlTmFtZSwgewogICAgX19wcm90b19fOiBudWxsLAogICAgZ2V0OiBmdW5jdGlvbigpIHsKICAgICAgdmFyIGlkcyA9IEdldEludExpc3RBdHRyaWJ1dGUodGhpcy50cmVlSUQsIHRoaXMuaWQsIHNyY0F0dHJpYnV0ZU5hbWUpOwogICAgICBpZiAoIWlkcyB8fCAhdGhpcy5yb290SW1wbCkKICAgICAgICByZXR1cm4gdW5kZWZpbmVkOwogICAgICB2YXIgcmVzdWx0ID0gW107CiAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgaWRzLmxlbmd0aDsgKytpKSB7CiAgICAgICAgdmFyIG5vZGUgPSB0aGlzLnJvb3RJbXBsLmdldChpZHNbaV0pOwogICAgICAgIGlmIChub2RlKQogICAgICAgICAgJEFycmF5LnB1c2gocmVzdWx0LCBub2RlKTsKICAgICAgfQogICAgICByZXR1cm4gcmVzdWx0OwogICAgfQogIH0pOwp9KTsKCiRBcnJheS5mb3JFYWNoKGZsb2F0QXR0cmlidXRlcywgZnVuY3Rpb24oYXR0cmlidXRlTmFtZSkgewogICRBcnJheS5wdXNoKHB1YmxpY0F0dHJpYnV0ZXMsIGF0dHJpYnV0ZU5hbWUpOwogICRPYmplY3QuZGVmaW5lUHJvcGVydHkoQXV0b21hdGlvbk5vZGVJbXBsLnByb3RvdHlwZSwgYXR0cmlidXRlTmFtZSwgewogICAgX19wcm90b19fOiBudWxsLAogICAgZ2V0OiBmdW5jdGlvbigpIHsKICAgICAgcmV0dXJuIEdldEZsb2F0QXR0cmlidXRlKHRoaXMudHJlZUlELCB0aGlzLmlkLCBhdHRyaWJ1dGVOYW1lKTsKICAgIH0KICB9KTsKfSk7CgokQXJyYXkuZm9yRWFjaChodG1sQXR0cmlidXRlcywgZnVuY3Rpb24ocGFyYW1zKSB7CiAgdmFyIHNyY0F0dHJpYnV0ZU5hbWUgPSBwYXJhbXNbMF07CiAgdmFyIGRzdEF0dHJpYnV0ZU5hbWUgPSBwYXJhbXNbMV07CiAgJEFycmF5LnB1c2gocHVibGljQXR0cmlidXRlcywgZHN0QXR0cmlidXRlTmFtZSk7CiAgJE9iamVjdC5kZWZpbmVQcm9wZXJ0eShBdXRvbWF0aW9uTm9kZUltcGwucHJvdG90eXBlLCBkc3RBdHRyaWJ1dGVOYW1lLCB7CiAgICBfX3Byb3RvX186IG51bGwsCiAgICBnZXQ6IGZ1bmN0aW9uKCkgewogICAgICByZXR1cm4gR2V0SHRtbEF0dHJpYnV0ZSh0aGlzLnRyZWVJRCwgdGhpcy5pZCwgc3JjQXR0cmlidXRlTmFtZSk7CiAgICB9CiAgfSk7Cn0pOwoKLyoqCiAqIEF1dG9tYXRpb25Sb290Tm9kZS4KICoKICogQW4gQXV0b21hdGlvblJvb3ROb2RlIGlzIHRoZSBqYXZhc2NyaXB0IGVuZCBvZiBhbiBBWFRyZWUgbGl2aW5nIGluIHRoZQogKiBicm93c2VyLiBBdXRvbWF0aW9uUm9vdE5vZGUgaGFuZGxlcyB1bnNlcmlhbGl6aW5nIGluY3JlbWVudGFsIHVwZGF0ZXMgZnJvbQogKiB0aGUgc291cmNlIEFYVHJlZS4gRWFjaCB1cGRhdGUgY29udGFpbnMgbm9kZSBkYXRhIHRoYXQgZm9ybSBhIGNvbXBsZXRlIHRyZWUKICogYWZ0ZXIgYXBwbHlpbmcgdGhlIHVwZGF0ZS4KICoKICogQSBicmllZiBub3RlIGFib3V0IGlkcyB1c2VkIHRocm91Z2ggdGhpcyBjbGFzcy4gVGhlIHNvdXJjZSBBWFRyZWUgYXNzaWducwogKiB1bmlxdWUgaWRzIHBlciBub2RlIGFuZCB3ZSB1c2UgdGhlc2UgaWRzIHRvIGJ1aWxkIGEgaGFzaCB0byB0aGUgYWN0dWFsCiAqIEF1dG9tYXRpb25Ob2RlIG9iamVjdC4KICogVGh1cywgdHJlZSB0cmF2ZXJzYWxzIGFtb3VudCB0byBhIGxvb2t1cCBpbiBvdXIgaGFzaC4KICoKICogVGhlIHRyZWUgaXRzZWxmIGlzIGlkZW50aWZpZWQgYnkgdGhlIGFjY2Vzc2liaWxpdHkgdHJlZSBpZCBvZiB0aGUKICogcmVuZGVyZXIgd2lkZ2V0IGhvc3QuCiAqIEBjb25zdHJ1Y3RvcgogKi8KZnVuY3Rpb24gQXV0b21hdGlvblJvb3ROb2RlSW1wbCh0cmVlSUQpIHsKICAkRnVuY3Rpb24uY2FsbChBdXRvbWF0aW9uTm9kZUltcGwsIHRoaXMsIHRoaXMpOwogIHRoaXMudHJlZUlEID0gdHJlZUlEOwogIHRoaXMuYXhOb2RlRGF0YUNhY2hlXyA9IHtfX3Byb3RvX186IG51bGx9OwogIHRoaXMuYWN0aW9uUmVxdWVzdElEVG9DYWxsYmFja18gPSB7X19wcm90b19fOiBudWxsfTsKfQoKdXRpbHMuZGVmaW5lUHJvcGVydHkoQXV0b21hdGlvblJvb3ROb2RlSW1wbCwgJ2lkVG9BdXRvbWF0aW9uUm9vdE5vZGVfJywKICAgIHtfX3Byb3RvX186IG51bGx9KTsKCnV0aWxzLmRlZmluZVByb3BlcnR5KEF1dG9tYXRpb25Sb290Tm9kZUltcGwsICdnZXQnLCBmdW5jdGlvbih0cmVlSUQpIHsKICB2YXIgcmVzdWx0ID0gQXV0b21hdGlvblJvb3ROb2RlSW1wbC5pZFRvQXV0b21hdGlvblJvb3ROb2RlX1t0cmVlSURdOwogIHJldHVybiByZXN1bHQgfHwgdW5kZWZpbmVkOwp9KTsKCnV0aWxzLmRlZmluZVByb3BlcnR5KEF1dG9tYXRpb25Sb290Tm9kZUltcGwsICdnZXRPckNyZWF0ZScsIGZ1bmN0aW9uKHRyZWVJRCkgewogIGlmIChBdXRvbWF0aW9uUm9vdE5vZGVJbXBsLmlkVG9BdXRvbWF0aW9uUm9vdE5vZGVfW3RyZWVJRF0pCiAgICByZXR1cm4gQXV0b21hdGlvblJvb3ROb2RlSW1wbC5pZFRvQXV0b21hdGlvblJvb3ROb2RlX1t0cmVlSURdOwogIHZhciByZXN1bHQgPSBuZXcgQXV0b21hdGlvblJvb3ROb2RlKHRyZWVJRCk7CiAgQXV0b21hdGlvblJvb3ROb2RlSW1wbC5pZFRvQXV0b21hdGlvblJvb3ROb2RlX1t0cmVlSURdID0gcmVzdWx0OwogIHJldHVybiByZXN1bHQ7Cn0pOwoKdXRpbHMuZGVmaW5lUHJvcGVydHkoQXV0b21hdGlvblJvb3ROb2RlSW1wbCwgJ2Rlc3Ryb3knLCBmdW5jdGlvbih0cmVlSUQpIHsKICBkZWxldGUgQXV0b21hdGlvblJvb3ROb2RlSW1wbC5pZFRvQXV0b21hdGlvblJvb3ROb2RlX1t0cmVlSURdOwp9KTsKCkF1dG9tYXRpb25Sb290Tm9kZUltcGwucHJvdG90eXBlID0gewogIF9fcHJvdG9fXzogQXV0b21hdGlvbk5vZGVJbXBsLnByb3RvdHlwZSwKCiAgLyoqCiAgICogQHR5cGUge2Jvb2xlYW59CiAgICovCiAgaXNSb290Tm9kZTogdHJ1ZSwKCiAgLyoqCiAgICogQHR5cGUge251bWJlcn0KICAgKi8KICB0cmVlSUQ6IC0xLAoKICAvKioKICAgKiBUaGUgcGFyZW50IG9mIHRoaXMgbm9kZSBmcm9tIGEgZGlmZmVyZW50IHRyZWUuCiAgICogQHR5cGUgez9BdXRvbWF0aW9uTm9kZX0KICAgKiBAcHJpdmF0ZQogICAqLwogIGhvc3ROb2RlXzogbnVsbCwKCiAgLyoqCiAgICogQSBtYXAgZnJvbSBpZCB0byBBdXRvbWF0aW9uTm9kZS4KICAgKiBAdHlwZSB7T2JqZWN0LjxudW1iZXIsIEF1dG9tYXRpb25Ob2RlPn0KICAgKiBAcHJpdmF0ZQogICAqLwogIGF4Tm9kZURhdGFDYWNoZV86IG51bGwsCgogIGFjdGlvblJlcXVlc3RDb3VudGVyXzogMCwKCiAgYWN0aW9uUmVxdWVzdElEVG9DYWxsYmFja186IG51bGwsCgogIGdldCBpZCgpIHsKICAgIHZhciByZXN1bHQgPSBHZXRSb290SUQodGhpcy50cmVlSUQpOwoKICAgIC8vIERvbid0IHJldHVybiB1bmRlZmluZWQsIGJlY2F1c2UgdGhlIGlkIGlzIG9mdGVuIHBhc3NlZCBkaXJlY3RseQogICAgLy8gYXMgYW4gYXJndW1lbnQgdG8gYSBuYXRpdmUgYmluZGluZyB0aGF0IGV4cGVjdHMgb25seSBhIHZhbGlkIG51bWJlci4KICAgIGlmIChyZXN1bHQgPT09IHVuZGVmaW5lZCkKICAgICAgcmV0dXJuIC0xOwoKICAgIHJldHVybiByZXN1bHQ7CiAgfSwKCiAgZ2V0IGNocm9tZUNoYW5uZWwoKSB7CiAgICByZXR1cm4gR2V0U3RyaW5nQXR0cmlidXRlKHRoaXMudHJlZUlELCB0aGlzLmlkLCAnY2hyb21lQ2hhbm5lbCcpOwogIH0sCgogIGdldCBkb2NVcmwoKSB7CiAgICByZXR1cm4gR2V0RG9jVVJMKHRoaXMudHJlZUlEKTsKICB9LAoKICBnZXQgZG9jVGl0bGUoKSB7CiAgICByZXR1cm4gR2V0RG9jVGl0bGUodGhpcy50cmVlSUQpOwogIH0sCgogIGdldCBkb2NMb2FkZWQoKSB7CiAgICByZXR1cm4gR2V0RG9jTG9hZGVkKHRoaXMudHJlZUlEKTsKICB9LAoKICBnZXQgZG9jTG9hZGluZ1Byb2dyZXNzKCkgewogICAgcmV0dXJuIEdldERvY0xvYWRpbmdQcm9ncmVzcyh0aGlzLnRyZWVJRCk7CiAgfSwKCiAgZ2V0IGFuY2hvck9iamVjdCgpIHsKICAgIHZhciBpZCA9IEdldEFuY2hvck9iamVjdElEKHRoaXMudHJlZUlEKTsKICAgIGlmIChpZCAmJiBpZCAhPSAtMSkKICAgICAgcmV0dXJuIHRoaXMuZ2V0KGlkKTsKICAgIGVsc2UKICAgICAgcmV0dXJuIHVuZGVmaW5lZDsKICB9LAoKICBnZXQgYW5jaG9yT2Zmc2V0KCkgewogICAgdmFyIGlkID0gR2V0QW5jaG9yT2JqZWN0SUQodGhpcy50cmVlSUQpOwogICAgaWYgKGlkICYmIGlkICE9IC0xKQogICAgICByZXR1cm4gR2V0QW5jaG9yT2Zmc2V0KHRoaXMudHJlZUlEKTsKICB9LAoKICBnZXQgYW5jaG9yQWZmaW5pdHkoKSB7CiAgICB2YXIgaWQgPSBHZXRBbmNob3JPYmplY3RJRCh0aGlzLnRyZWVJRCk7CiAgICBpZiAoaWQgJiYgaWQgIT0gLTEpCiAgICAgIHJldHVybiBHZXRBbmNob3JBZmZpbml0eSh0aGlzLnRyZWVJRCk7CiAgfSwKCiAgZ2V0IGZvY3VzT2JqZWN0KCkgewogICAgdmFyIGlkID0gR2V0Rm9jdXNPYmplY3RJRCh0aGlzLnRyZWVJRCk7CiAgICBpZiAoaWQgJiYgaWQgIT0gLTEpCiAgICAgIHJldHVybiB0aGlzLmdldChpZCk7CiAgICBlbHNlCiAgICAgIHJldHVybiB1bmRlZmluZWQ7CiAgfSwKCiAgZ2V0IGZvY3VzT2Zmc2V0KCkgewogICAgdmFyIGlkID0gR2V0Rm9jdXNPYmplY3RJRCh0aGlzLnRyZWVJRCk7CiAgICBpZiAoaWQgJiYgaWQgIT0gLTEpCiAgICAgIHJldHVybiBHZXRGb2N1c09mZnNldCh0aGlzLnRyZWVJRCk7CiAgfSwKCiAgZ2V0IGZvY3VzQWZmaW5pdHkoKSB7CiAgICB2YXIgaWQgPSBHZXRGb2N1c09iamVjdElEKHRoaXMudHJlZUlEKTsKICAgIGlmIChpZCAmJiBpZCAhPSAtMSkKICAgICAgcmV0dXJuIEdldEZvY3VzQWZmaW5pdHkodGhpcy50cmVlSUQpOwogIH0sCgogIGdldDogZnVuY3Rpb24oaWQpIHsKICAgIGlmIChpZCA9PSB1bmRlZmluZWQpCiAgICAgIHJldHVybiB1bmRlZmluZWQ7CgogICAgaWYgKGlkID09IHRoaXMuaWQpCiAgICAgIHJldHVybiB0aGlzLndyYXBwZXI7CgogICAgdmFyIG9iaiA9IHRoaXMuYXhOb2RlRGF0YUNhY2hlX1tpZF07CiAgICBpZiAob2JqKQogICAgICByZXR1cm4gb2JqOwoKICAgIG9iaiA9IG5ldyBBdXRvbWF0aW9uTm9kZSh0aGlzKTsKICAgIHByaXZhdGVzKG9iaikuaW1wbC50cmVlSUQgPSB0aGlzLnRyZWVJRDsKICAgIHByaXZhdGVzKG9iaikuaW1wbC5pZCA9IGlkOwogICAgdGhpcy5heE5vZGVEYXRhQ2FjaGVfW2lkXSA9IG9iajsKCiAgICByZXR1cm4gb2JqOwogIH0sCgogIHJlbW92ZTogZnVuY3Rpb24oaWQpIHsKICAgIGlmICh0aGlzLmF4Tm9kZURhdGFDYWNoZV9baWRdKQogICAgICBwcml2YXRlcyh0aGlzLmF4Tm9kZURhdGFDYWNoZV9baWRdKS5pbXBsLmRldGFjaCgpOwogICAgZGVsZXRlIHRoaXMuYXhOb2RlRGF0YUNhY2hlX1tpZF07CiAgfSwKCiAgZGVzdHJveTogZnVuY3Rpb24oKSB7CiAgICB0aGlzLmRpc3BhdGNoRXZlbnQoJ2Rlc3Ryb3llZCcsICdub25lJyk7CiAgICBmb3IgKHZhciBpZCBpbiB0aGlzLmF4Tm9kZURhdGFDYWNoZV8pCiAgICAgIHRoaXMucmVtb3ZlKGlkKTsKICAgIHRoaXMuZGV0YWNoKCk7CiAgfSwKCiAgc2V0SG9zdE5vZGUoaG9zdE5vZGUpIHsKICAgIHRoaXMuaG9zdE5vZGVfID0gaG9zdE5vZGU7CiAgfSwKCiAgb25BY2Nlc3NpYmlsaXR5RXZlbnQ6IGZ1bmN0aW9uKGV2ZW50UGFyYW1zKSB7CiAgICB2YXIgdGFyZ2V0Tm9kZSA9IHRoaXMuZ2V0KGV2ZW50UGFyYW1zLnRhcmdldElEKTsKICAgIGlmICh0YXJnZXROb2RlKSB7CiAgICAgIHZhciB0YXJnZXROb2RlSW1wbCA9IHByaXZhdGVzKHRhcmdldE5vZGUpLmltcGw7CiAgICAgIHRhcmdldE5vZGVJbXBsLmRpc3BhdGNoRXZlbnQoCiAgICAgICAgICBldmVudFBhcmFtcy5ldmVudFR5cGUsIGV2ZW50UGFyYW1zLmV2ZW50RnJvbSwKICAgICAgICAgIGV2ZW50UGFyYW1zLm1vdXNlWCwgZXZlbnRQYXJhbXMubW91c2VZKTsKCiAgICAgIGlmIChldmVudFBhcmFtcy5hY3Rpb25SZXF1ZXN0SUQgIT0gLTEpIHsKICAgICAgICB0aGlzLm9uQWN0aW9uUmVzdWx0KGV2ZW50UGFyYW1zLmFjdGlvblJlcXVlc3RJRCwgdGFyZ2V0Tm9kZSk7CiAgICAgIH0KICAgIH0gZWxzZSB7CiAgICAgIGxvZ2dpbmcuV0FSTklORygnR290ICcgKyBldmVudFBhcmFtcy5ldmVudFR5cGUgKwogICAgICAgICAgICAgICAgICAgICAgJyBldmVudCBvbiB1bmtub3duIG5vZGU6ICcgKyBldmVudFBhcmFtcy50YXJnZXRJRCArCiAgICAgICAgICAgICAgICAgICAgICAnOyB0aGlzOiAnICsgdGhpcy5pZCk7CiAgICB9CiAgICByZXR1cm4gdHJ1ZTsKICB9LAoKICBhZGRBY3Rpb25SZXN1bHRDYWxsYmFjazogZnVuY3Rpb24oY2FsbGJhY2spIHsKICAgIHRoaXMuYWN0aW9uUmVxdWVzdElEVG9DYWxsYmFja19bKyt0aGlzLmFjdGlvblJlcXVlc3RDb3VudGVyX10gPSBjYWxsYmFjazsKICAgIHJldHVybiB0aGlzLmFjdGlvblJlcXVlc3RDb3VudGVyXzsKICB9LAoKICBvbkFjdGlvblJlc3VsdDogZnVuY3Rpb24ocmVxdWVzdElELCByZXN1bHQpIHsKICAgIGlmIChyZXF1ZXN0SUQgaW4gdGhpcy5hY3Rpb25SZXF1ZXN0SURUb0NhbGxiYWNrXykgewogICAgICB0aGlzLmFjdGlvblJlcXVlc3RJRFRvQ2FsbGJhY2tfW3JlcXVlc3RJRF0ocmVzdWx0KTsKICAgICAgZGVsZXRlIHRoaXMuYWN0aW9uUmVxdWVzdElEVG9DYWxsYmFja19bcmVxdWVzdElEXTsKICAgIH0KICB9LAoKICB0b1N0cmluZzogZnVuY3Rpb24oKSB7CiAgICBmdW5jdGlvbiB0b1N0cmluZ0ludGVybmFsKG5vZGVJbXBsLCBpbmRlbnQpIHsKICAgICAgaWYgKCFub2RlSW1wbCkKICAgICAgICByZXR1cm4gJyc7CiAgICAgIHZhciBvdXRwdXQgPSAnJzsKICAgICAgaWYgKG5vZGVJbXBsLmlzUm9vdE5vZGUpCiAgICAgICAgb3V0cHV0ICs9IGluZGVudCArICd0cmVlIGlkPScgKyBub2RlSW1wbC50cmVlSUQgKyAnXG4nOwogICAgICBvdXRwdXQgKz0gaW5kZW50ICsKICAgICAgICAkRnVuY3Rpb24uY2FsbChBdXRvbWF0aW9uTm9kZUltcGwucHJvdG90eXBlLnRvU3RyaW5nLCBub2RlSW1wbCkgKyAnXG4nOwogICAgICBpbmRlbnQgKz0gJyAgJzsKICAgICAgdmFyIGNoaWxkcmVuID0gbm9kZUltcGwuY2hpbGRyZW47CiAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgY2hpbGRyZW4ubGVuZ3RoOyArK2kpCiAgICAgICAgb3V0cHV0ICs9IHRvU3RyaW5nSW50ZXJuYWwocHJpdmF0ZXMoY2hpbGRyZW5baV0pLmltcGwsIGluZGVudCk7CiAgICAgIHJldHVybiBvdXRwdXQ7CiAgICB9CiAgICByZXR1cm4gdG9TdHJpbmdJbnRlcm5hbCh0aGlzLCAnJyk7CiAgfSwKfTsKCmZ1bmN0aW9uIEF1dG9tYXRpb25Ob2RlKCkgewogIHByaXZhdGVzKEF1dG9tYXRpb25Ob2RlKS5jb25zdHJ1Y3RQcml2YXRlKHRoaXMsIGFyZ3VtZW50cyk7Cn0KdXRpbHMuZXhwb3NlKEF1dG9tYXRpb25Ob2RlLCBBdXRvbWF0aW9uTm9kZUltcGwsIHsKICBmdW5jdGlvbnM6IFsKICAgICdkb0RlZmF1bHQnLAogICAgJ2ZpbmQnLAogICAgJ2ZpbmRBbGwnLAogICAgJ2ZvY3VzJywKICAgICdnZXRJbWFnZURhdGEnLAogICAgJ2hpdFRlc3QnLAogICAgJ2hpdFRlc3RXaXRoUmVwbHknLAogICAgJ21ha2VWaXNpYmxlJywKICAgICdtYXRjaGVzJywKICAgICdwZXJmb3JtQ3VzdG9tQWN0aW9uJywKICAgICdyZXN1bWVNZWRpYScsCiAgICAnc2Nyb2xsQmFja3dhcmQnLAogICAgJ3Njcm9sbEZvcndhcmQnLAogICAgJ3Njcm9sbFVwJywKICAgICdzY3JvbGxEb3duJywKICAgICdzY3JvbGxMZWZ0JywKICAgICdzY3JvbGxSaWdodCcsCiAgICAnc2V0U2VsZWN0aW9uJywKICAgICdzZXRTZXF1ZW50aWFsRm9jdXNOYXZpZ2F0aW9uU3RhcnRpbmdQb2ludCcsCiAgICAnc2hvd0NvbnRleHRNZW51JywKICAgICdzdGFydER1Y2tpbmdNZWRpYScsCiAgICAnc3RvcER1Y2tpbmdNZWRpYScsCiAgICAnc3VzcGVuZE1lZGlhJywKICAgICdhZGRFdmVudExpc3RlbmVyJywKICAgICdyZW1vdmVFdmVudExpc3RlbmVyJywKICAgICdkb21RdWVyeVNlbGVjdG9yJywKICAgICd0b1N0cmluZycsCiAgICAnYm91bmRzRm9yUmFuZ2UnLAogIF0sCiAgcmVhZG9ubHk6ICRBcnJheS5jb25jYXQocHVibGljQXR0cmlidXRlcywgWwogICAgICAncGFyZW50JywKICAgICAgJ2ZpcnN0Q2hpbGQnLAogICAgICAnbGFzdENoaWxkJywKICAgICAgJ2NoaWxkcmVuJywKICAgICAgJ3ByZXZpb3VzU2libGluZycsCiAgICAgICduZXh0U2libGluZycsCiAgICAgICdpc1Jvb3ROb2RlJywKICAgICAgJ3JvbGUnLAogICAgICAnY2hlY2tlZCcsCiAgICAgICdyZXN0cmljdGlvbicsCiAgICAgICdzdGF0ZScsCiAgICAgICdsb2NhdGlvbicsCiAgICAgICdpbmRleEluUGFyZW50JywKICAgICAgJ2xpbmVTdGFydE9mZnNldHMnLAogICAgICAncm9vdCcsCiAgICAgICdodG1sQXR0cmlidXRlcycsCiAgICAgICduYW1lRnJvbScsCiAgICAgICdib2xkJywKICAgICAgJ2l0YWxpYycsCiAgICAgICd1bmRlcmxpbmUnLAogICAgICAnbGluZVRocm91Z2gnLAogICAgICAnY3VzdG9tQWN0aW9ucycsCiAgICAgICd1bmNsaXBwZWRMb2NhdGlvbicsCiAgXSksCn0pOwoKZnVuY3Rpb24gQXV0b21hdGlvblJvb3ROb2RlKCkgewogIHByaXZhdGVzKEF1dG9tYXRpb25Sb290Tm9kZSkuY29uc3RydWN0UHJpdmF0ZSh0aGlzLCBhcmd1bWVudHMpOwp9CnV0aWxzLmV4cG9zZShBdXRvbWF0aW9uUm9vdE5vZGUsIEF1dG9tYXRpb25Sb290Tm9kZUltcGwsIHsKICBzdXBlcmNsYXNzOiBBdXRvbWF0aW9uTm9kZSwKICByZWFkb25seTogWwogICAgJ2Nocm9tZUNoYW5uZWwnLAogICAgJ2RvY1RpdGxlJywKICAgICdkb2NVcmwnLAogICAgJ2RvY0xvYWRlZCcsCiAgICAnZG9jTG9hZGluZ1Byb2dyZXNzJywKICAgICdhbmNob3JPYmplY3QnLAogICAgJ2FuY2hvck9mZnNldCcsCiAgICAnYW5jaG9yQWZmaW5pdHknLAogICAgJ2ZvY3VzT2JqZWN0JywKICAgICdmb2N1c09mZnNldCcsCiAgICAnZm9jdXNBZmZpbml0eScsCiAgXSwKfSk7Cgp1dGlscy5kZWZpbmVQcm9wZXJ0eShBdXRvbWF0aW9uUm9vdE5vZGUsICdnZXQnLCBmdW5jdGlvbih0cmVlSUQpIHsKICByZXR1cm4gQXV0b21hdGlvblJvb3ROb2RlSW1wbC5nZXQodHJlZUlEKTsKfSk7Cgp1dGlscy5kZWZpbmVQcm9wZXJ0eShBdXRvbWF0aW9uUm9vdE5vZGUsICdnZXRPckNyZWF0ZScsIGZ1bmN0aW9uKHRyZWVJRCkgewogIHJldHVybiBBdXRvbWF0aW9uUm9vdE5vZGVJbXBsLmdldE9yQ3JlYXRlKHRyZWVJRCk7Cn0pOwoKdXRpbHMuZGVmaW5lUHJvcGVydHkoQXV0b21hdGlvblJvb3ROb2RlLCAnZGVzdHJveScsIGZ1bmN0aW9uKHRyZWVJRCkgewogIEF1dG9tYXRpb25Sb290Tm9kZUltcGwuZGVzdHJveSh0cmVlSUQpOwp9KTsKCmV4cG9ydHMuJHNldCgnQXV0b21hdGlvbk5vZGUnLCBBdXRvbWF0aW9uTm9kZSk7CmV4cG9ydHMuJHNldCgnQXV0b21hdGlvblJvb3ROb2RlJywgQXV0b21hdGlvblJvb3ROb2RlKTsKLy8gQ29weXJpZ2h0IChjKSAyMDEyIFRoZSBDaHJvbWl1bSBBdXRob3JzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgovLyBVc2Ugb2YgdGhpcyBzb3VyY2UgY29kZSBpcyBnb3Zlcm5lZCBieSBhIEJTRC1zdHlsZSBsaWNlbnNlIHRoYXQgY2FuIGJlCi8vIGZvdW5kIGluIHRoZSBMSUNFTlNFIGZpbGUuCgovLyBDdXN0b20gYmluZGluZyBmb3IgdGhlIGJyb3dzZXJBY3Rpb24gQVBJLgoKdmFyIGJpbmRpbmcgPSBhcGlCcmlkZ2UgfHwgcmVxdWlyZSgnYmluZGluZycpLkJpbmRpbmcuY3JlYXRlKCdicm93c2VyQWN0aW9uJyk7Cgp2YXIgc2V0SWNvbiA9IHJlcXVpcmUoJ3NldEljb24nKS5zZXRJY29uOwp2YXIgZ2V0RXh0ZW5zaW9uVmlld3MgPSByZXF1aXJlTmF0aXZlKCdydW50aW1lJykuR2V0RXh0ZW5zaW9uVmlld3M7CnZhciBzZW5kUmVxdWVzdCA9IGJpbmRpbmdVdGlsID8KICAgICRGdW5jdGlvbi5iaW5kKGJpbmRpbmdVdGlsLnNlbmRSZXF1ZXN0LCBiaW5kaW5nVXRpbCkgOgogICAgcmVxdWlyZSgnc2VuZFJlcXVlc3QnKS5zZW5kUmVxdWVzdDsKCnZhciBqc0xhc3RFcnJvciA9IGJpbmRpbmdVdGlsID8gdW5kZWZpbmVkIDogcmVxdWlyZSgnbGFzdEVycm9yJyk7CmZ1bmN0aW9uIGhhc0xhc3RFcnJvcigpIHsKICByZXR1cm4gYmluZGluZ1V0aWwgPwogICAgICBiaW5kaW5nVXRpbC5oYXNMYXN0RXJyb3IoKSA6IGpzTGFzdEVycm9yLmhhc0Vycm9yKGNocm9tZSk7Cn0KCmJpbmRpbmcucmVnaXN0ZXJDdXN0b21Ib29rKGZ1bmN0aW9uKGJpbmRpbmdzQVBJKSB7CiAgdmFyIGFwaUZ1bmN0aW9ucyA9IGJpbmRpbmdzQVBJLmFwaUZ1bmN0aW9uczsKCiAgYXBpRnVuY3Rpb25zLnNldEhhbmRsZVJlcXVlc3QoJ3NldEljb24nLCBmdW5jdGlvbihkZXRhaWxzLCBjYWxsYmFjaykgewogICAgc2V0SWNvbihkZXRhaWxzLCBmdW5jdGlvbihhcmdzKSB7CiAgICAgIHNlbmRSZXF1ZXN0KCdicm93c2VyQWN0aW9uLnNldEljb24nLAogICAgICAgICAgICAgICAgICBbYXJncywgY2FsbGJhY2tdLAogICAgICAgICAgICAgICAgICBhcGlCcmlkZ2UgPyB1bmRlZmluZWQgOiB0aGlzLmRlZmluaXRpb24ucGFyYW1ldGVycywKICAgICAgICAgICAgICAgICAgdW5kZWZpbmVkKTsKICAgIH0uYmluZCh0aGlzKSk7CiAgfSk7CgogIGFwaUZ1bmN0aW9ucy5zZXRDdXN0b21DYWxsYmFjaygnb3BlblBvcHVwJywKICAgICAgZnVuY3Rpb24obmFtZSwgcmVxdWVzdCwgY2FsbGJhY2ssIHJlc3BvbnNlKSB7CiAgICBpZiAoIWNhbGxiYWNrKQogICAgICByZXR1cm47CgogICAgaWYgKGhhc0xhc3RFcnJvcigpKSB7CiAgICAgIGNhbGxiYWNrKCk7CiAgICB9IGVsc2UgewogICAgICB2YXIgdmlld3MgPSBnZXRFeHRlbnNpb25WaWV3cygtMSwgLTEsICdQT1BVUCcpOwogICAgICBjYWxsYmFjayh2aWV3cy5sZW5ndGggPiAwID8gdmlld3NbMF0gOiBudWxsKTsKICAgIH0KICB9KTsKfSk7CgppZiAoIWFwaUJyaWRnZSkKICBleHBvcnRzLiRzZXQoJ2JpbmRpbmcnLCBiaW5kaW5nLmdlbmVyYXRlKCkpOwovLyBDb3B5cmlnaHQgMjAxMyBUaGUgQ2hyb21pdW0gQXV0aG9ycy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KLy8gVXNlIG9mIHRoaXMgc291cmNlIGNvZGUgaXMgZ292ZXJuZWQgYnkgYSBCU0Qtc3R5bGUgbGljZW5zZSB0aGF0IGNhbiBiZQovLyBmb3VuZCBpbiB0aGUgTElDRU5TRSBmaWxlLgoKLy8gQ3VzdG9tIGJpbmRpbmcgZm9yIHRoZSBDYXN0IFN0cmVhbWluZyBSdHBTdHJlYW0gQVBJLgoKdmFyIGJpbmRpbmcgPSBhcGlCcmlkZ2UgfHwKICAgICAgICAgICAgICByZXF1aXJlKCdiaW5kaW5nJykuQmluZGluZy5jcmVhdGUoJ2Nhc3Quc3RyZWFtaW5nLnJ0cFN0cmVhbScpOwp2YXIgbmF0aXZlcyA9IHJlcXVpcmVOYXRpdmUoJ2Nhc3Rfc3RyZWFtaW5nX25hdGl2ZXMnKTsKCmJpbmRpbmcucmVnaXN0ZXJDdXN0b21Ib29rKGZ1bmN0aW9uKGJpbmRpbmdzQVBJLCBleHRlbnNpb25JZCkgewogIHZhciBhcGlGdW5jdGlvbnMgPSBiaW5kaW5nc0FQSS5hcGlGdW5jdGlvbnM7CgogIGFwaUZ1bmN0aW9ucy5zZXRIYW5kbGVSZXF1ZXN0KCdkZXN0cm95JywKICAgICAgZnVuY3Rpb24odHJhbnNwb3J0SWQpIHsKICAgICAgICBuYXRpdmVzLkRlc3Ryb3lDYXN0UnRwU3RyZWFtKHRyYW5zcG9ydElkKTsKICB9KTsKICBhcGlGdW5jdGlvbnMuc2V0SGFuZGxlUmVxdWVzdCgnZ2V0U3VwcG9ydGVkUGFyYW1zJywKICAgICAgZnVuY3Rpb24odHJhbnNwb3J0SWQpIHsKICAgICAgICByZXR1cm4gbmF0aXZlcy5HZXRTdXBwb3J0ZWRQYXJhbXNDYXN0UnRwU3RyZWFtKHRyYW5zcG9ydElkKTsKICB9KTsKICBhcGlGdW5jdGlvbnMuc2V0SGFuZGxlUmVxdWVzdCgnc3RhcnQnLAogICAgICBmdW5jdGlvbih0cmFuc3BvcnRJZCwgcGFyYW1zKSB7CiAgICAgICAgbmF0aXZlcy5TdGFydENhc3RSdHBTdHJlYW0odHJhbnNwb3J0SWQsIHBhcmFtcyk7CiAgfSk7CiAgYXBpRnVuY3Rpb25zLnNldEhhbmRsZVJlcXVlc3QoJ3N0b3AnLAogICAgICBmdW5jdGlvbih0cmFuc3BvcnRJZCkgewogICAgICAgIG5hdGl2ZXMuU3RvcENhc3RSdHBTdHJlYW0odHJhbnNwb3J0SWQpOwogIH0pOwogIGFwaUZ1bmN0aW9ucy5zZXRIYW5kbGVSZXF1ZXN0KCd0b2dnbGVMb2dnaW5nJywKICAgICAgZnVuY3Rpb24odHJhbnNwb3J0SWQsIGVuYWJsZSkgewogICAgICAgIG5hdGl2ZXMuVG9nZ2xlTG9nZ2luZyh0cmFuc3BvcnRJZCwgZW5hYmxlKTsKICB9KTsKICBhcGlGdW5jdGlvbnMuc2V0SGFuZGxlUmVxdWVzdCgnZ2V0UmF3RXZlbnRzJywKICAgICAgZnVuY3Rpb24odHJhbnNwb3J0SWQsIGV4dHJhRGF0YSwgY2FsbGJhY2spIHsKICAgICAgICBuYXRpdmVzLkdldFJhd0V2ZW50cyh0cmFuc3BvcnRJZCwgZXh0cmFEYXRhLCBjYWxsYmFjayk7CiAgfSk7CiAgYXBpRnVuY3Rpb25zLnNldEhhbmRsZVJlcXVlc3QoJ2dldFN0YXRzJywKICAgICAgZnVuY3Rpb24odHJhbnNwb3J0SWQsIGNhbGxiYWNrKSB7CiAgICAgICAgbmF0aXZlcy5HZXRTdGF0cyh0cmFuc3BvcnRJZCwgY2FsbGJhY2spOwogIH0pOwp9KTsKCmlmICghYXBpQnJpZGdlKQogIGV4cG9ydHMuJHNldCgnYmluZGluZycsIGJpbmRpbmcuZ2VuZXJhdGUoKSk7Ci8vIENvcHlyaWdodCAyMDEzIFRoZSBDaHJvbWl1bSBBdXRob3JzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgovLyBVc2Ugb2YgdGhpcyBzb3VyY2UgY29kZSBpcyBnb3Zlcm5lZCBieSBhIEJTRC1zdHlsZSBsaWNlbnNlIHRoYXQgY2FuIGJlCi8vIGZvdW5kIGluIHRoZSBMSUNFTlNFIGZpbGUuCgovLyBDdXN0b20gYmluZGluZyBmb3IgdGhlIENhc3QgU3RyZWFtaW5nIFNlc3Npb24gQVBJLgoKdmFyIGJpbmRpbmcgPSBhcGlCcmlkZ2UgfHwKICAgICAgICAgICAgICByZXF1aXJlKCdiaW5kaW5nJykuQmluZGluZy5jcmVhdGUoJ2Nhc3Quc3RyZWFtaW5nLnNlc3Npb24nKTsKdmFyIG5hdGl2ZXMgPSByZXF1aXJlTmF0aXZlKCdjYXN0X3N0cmVhbWluZ19uYXRpdmVzJyk7CgpiaW5kaW5nLnJlZ2lzdGVyQ3VzdG9tSG9vayhmdW5jdGlvbihiaW5kaW5nc0FQSSwgZXh0ZW5zaW9uSWQpIHsKICB2YXIgYXBpRnVuY3Rpb25zID0gYmluZGluZ3NBUEkuYXBpRnVuY3Rpb25zOwogIGFwaUZ1bmN0aW9ucy5zZXRIYW5kbGVSZXF1ZXN0KCdjcmVhdGUnLAogICAgICBmdW5jdGlvbihhdWRpb1RyYWNrLCB2aWRlb1RyYWNrLCBjYWxsYmFjaykgewogICAgICAgIG5hdGl2ZXMuQ3JlYXRlU2Vzc2lvbihhdWRpb1RyYWNrLCB2aWRlb1RyYWNrLCBjYWxsYmFjayk7CiAgfSk7Cn0pOwoKaWYgKCFhcGlCcmlkZ2UpCiAgZXhwb3J0cy4kc2V0KCdiaW5kaW5nJywgYmluZGluZy5nZW5lcmF0ZSgpKTsKLy8gQ29weXJpZ2h0IDIwMTMgVGhlIENocm9taXVtIEF1dGhvcnMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCi8vIFVzZSBvZiB0aGlzIHNvdXJjZSBjb2RlIGlzIGdvdmVybmVkIGJ5IGEgQlNELXN0eWxlIGxpY2Vuc2UgdGhhdCBjYW4gYmUKLy8gZm91bmQgaW4gdGhlIExJQ0VOU0UgZmlsZS4KCi8vIEN1c3RvbSBiaW5kaW5nIGZvciB0aGUgQ2FzdCBTdHJlYW1pbmcgVWRwVHJhbnNwb3J0IEFQSS4KCnZhciBiaW5kaW5nID0gYXBpQnJpZGdlIHx8CiAgICAgICAgICAgICAgcmVxdWlyZSgnYmluZGluZycpLkJpbmRpbmcuY3JlYXRlKCdjYXN0LnN0cmVhbWluZy51ZHBUcmFuc3BvcnQnKTsKdmFyIG5hdGl2ZXMgPSByZXF1aXJlTmF0aXZlKCdjYXN0X3N0cmVhbWluZ19uYXRpdmVzJyk7CgpiaW5kaW5nLnJlZ2lzdGVyQ3VzdG9tSG9vayhmdW5jdGlvbihiaW5kaW5nc0FQSSwgZXh0ZW5zaW9uSWQpIHsKICB2YXIgYXBpRnVuY3Rpb25zID0gYmluZGluZ3NBUEkuYXBpRnVuY3Rpb25zOwoKICBhcGlGdW5jdGlvbnMuc2V0SGFuZGxlUmVxdWVzdCgnZGVzdHJveScsIGZ1bmN0aW9uKHRyYW5zcG9ydElkKSB7CiAgICBuYXRpdmVzLkRlc3Ryb3lDYXN0VWRwVHJhbnNwb3J0KHRyYW5zcG9ydElkKTsKICB9KTsKICBhcGlGdW5jdGlvbnMuc2V0SGFuZGxlUmVxdWVzdCgnc2V0RGVzdGluYXRpb24nLAogICAgZnVuY3Rpb24odHJhbnNwb3J0SWQsIGRlc3RpbmF0aW9uKSB7CiAgICAgIG5hdGl2ZXMuU2V0RGVzdGluYXRpb25DYXN0VWRwVHJhbnNwb3J0KHRyYW5zcG9ydElkLCBkZXN0aW5hdGlvbik7CiAgfSk7CiAgYXBpRnVuY3Rpb25zLnNldEhhbmRsZVJlcXVlc3QoJ3NldE9wdGlvbnMnLAogICAgZnVuY3Rpb24odHJhbnNwb3J0SWQsIG9wdGlvbnMpIHsKICAgICAgbmF0aXZlcy5TZXRPcHRpb25zQ2FzdFVkcFRyYW5zcG9ydCh0cmFuc3BvcnRJZCwgb3B0aW9ucyk7CiAgfSk7Cn0pOwoKaWYgKCFhcGlCcmlkZ2UpCiAgZXhwb3J0cy4kc2V0KCdiaW5kaW5nJywgYmluZGluZy5nZW5lcmF0ZSgpKTsKLy8gQ29weXJpZ2h0IDIwMTMgVGhlIENocm9taXVtIEF1dGhvcnMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCi8vIFVzZSBvZiB0aGlzIHNvdXJjZSBjb2RlIGlzIGdvdmVybmVkIGJ5IGEgQlNELXN0eWxlIGxpY2Vuc2UgdGhhdCBjYW4gYmUKLy8gZm91bmQgaW4gdGhlIExJQ0VOU0UgZmlsZS4KCi8vIEN1c3RvbSBiaW5kaW5nIGZvciB0aGUgQ2FzdCBTdHJlYW1pbmcgU2Vzc2lvbiBBUEkuCgp2YXIgYmluZGluZyA9CiAgICBhcGlCcmlkZ2UgfHwKICAgIHJlcXVpcmUoJ2JpbmRpbmcnKS5CaW5kaW5nLmNyZWF0ZSgnY2FzdC5zdHJlYW1pbmcucmVjZWl2ZXJTZXNzaW9uJyk7CnZhciBuYXRpdmVzID0gcmVxdWlyZU5hdGl2ZSgnY2FzdF9zdHJlYW1pbmdfbmF0aXZlcycpOwoKYmluZGluZy5yZWdpc3RlckN1c3RvbUhvb2soZnVuY3Rpb24oYmluZGluZ3NBUEksIGV4dGVuc2lvbklkKSB7CiAgdmFyIGFwaUZ1bmN0aW9ucyA9IGJpbmRpbmdzQVBJLmFwaUZ1bmN0aW9uczsKICBhcGlGdW5jdGlvbnMuc2V0SGFuZGxlUmVxdWVzdCgKICAgICAgJ2NyZWF0ZUFuZEJpbmQnLAogICAgICBmdW5jdGlvbihhcCwgdnAsIGxvY2FsLCB3ZWlkZ3RoLCBoZWlnaHQsIGZyLCB1cmwsIGNiLCBvcCkgewogICAgICAgIG5hdGl2ZXMuU3RhcnRDYXN0UnRwUmVjZWl2ZXIoCiAgICAgICAgICAgIGFwLCB2cCwgbG9jYWwsIHdlaWRndGgsIGhlaWdodCwgZnIsIHVybCwgY2IsIG9wKTsKICB9KTsKfSk7CgppZiAoIWFwaUJyaWRnZSkKICBleHBvcnRzLiRzZXQoJ2JpbmRpbmcnLCBiaW5kaW5nLmdlbmVyYXRlKCkpOwovLyBDb3B5cmlnaHQgKGMpIDIwMTIgVGhlIENocm9taXVtIEF1dGhvcnMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCi8vIFVzZSBvZiB0aGlzIHNvdXJjZSBjb2RlIGlzIGdvdmVybmVkIGJ5IGEgQlNELXN0eWxlIGxpY2Vuc2UgdGhhdCBjYW4gYmUKLy8gZm91bmQgaW4gdGhlIExJQ0VOU0UgZmlsZS4KCnZhciBFdmVudCA9IHJlcXVpcmUoJ2V2ZW50X2JpbmRpbmdzJykuRXZlbnQ7CnZhciBzZW5kUmVxdWVzdCA9IHJlcXVpcmUoJ3NlbmRSZXF1ZXN0Jykuc2VuZFJlcXVlc3Q7CnZhciB2YWxpZGF0ZSA9IHJlcXVpcmUoJ3NjaGVtYVV0aWxzJykudmFsaWRhdGU7CgpmdW5jdGlvbiBleHRlbmRTY2hlbWEoc2NoZW1hKSB7CiAgdmFyIGV4dGVuZGVkU2NoZW1hID0gJEFycmF5LnNsaWNlKHNjaGVtYSk7CiAgJEFycmF5LnVuc2hpZnQoZXh0ZW5kZWRTY2hlbWEsIHsndHlwZSc6ICdzdHJpbmcnfSk7CiAgcmV0dXJuIGV4dGVuZGVkU2NoZW1hOwp9CgovLyBUT0RPKGRldmxpbik6IE1heWJlIGZpbmQgYSB3YXkgdG8gY29tYmluZSB0aGlzIGFuZCBDb250ZW50U2V0dGluZy4KZnVuY3Rpb24gQ2hyb21lU2V0dGluZyhwcmVmS2V5LCB2YWx1ZVNjaGVtYSwgc2NoZW1hKSB7CiAgdmFyIGdldEZ1bmN0aW9uUGFyYW1ldGVycyA9IGZ1bmN0aW9uKG5hbWUpIHsKICAgIHZhciBmID0gJEFycmF5LmZpbHRlcigKICAgICAgICAgICAgICAgIHNjaGVtYS5mdW5jdGlvbnMsIGZ1bmN0aW9uKGYpIHsgcmV0dXJuIGYubmFtZSA9PT0gbmFtZTsgfSlbMF07CiAgICByZXR1cm4gZi5wYXJhbWV0ZXJzOwogIH07CiAgdGhpcy5nZXQgPSBmdW5jdGlvbihkZXRhaWxzLCBjYWxsYmFjaykgewogICAgdmFyIGdldFNjaGVtYSA9IGdldEZ1bmN0aW9uUGFyYW1ldGVycygnZ2V0Jyk7CiAgICB2YWxpZGF0ZShbZGV0YWlscywgY2FsbGJhY2tdLCBnZXRTY2hlbWEpOwogICAgcmV0dXJuIHNlbmRSZXF1ZXN0KCd0eXBlcy5DaHJvbWVTZXR0aW5nLmdldCcsCiAgICAgICAgICAgICAgICAgICAgICAgW3ByZWZLZXksIGRldGFpbHMsIGNhbGxiYWNrXSwKICAgICAgICAgICAgICAgICAgICAgICBleHRlbmRTY2hlbWEoZ2V0U2NoZW1hKSk7CiAgfTsKICB0aGlzLnNldCA9IGZ1bmN0aW9uKGRldGFpbHMsIGNhbGxiYWNrKSB7CiAgICAvLyBUaGUgc2V0IHNjaGVtYSBpbmNsdWRlZCBpbiB0aGUgU2NoZW1hIG9iamVjdCBpcyBnZW5lcmljLCBzaW5jZSBpdCB2YXJpZXMKICAgIC8vIHBlci1zZXR0aW5nLiBIb3dldmVyLCB0aGlzIGlzIG9ubHkgZXZlciBmb3IgYSBzaW5nbGUgc2V0dGluZywgc28gd2UgY2FuCiAgICAvLyBlbmZvcmNlIHRoZSB0eXBlcyBtb3JlIHRob3JvdWdobHkuCiAgICB2YXIgcmF3U2V0U2NoZW1hID0gZ2V0RnVuY3Rpb25QYXJhbWV0ZXJzKCdzZXQnKTsKICAgIHZhciByYXdTZXR0aW5nUGFyYW0gPSByYXdTZXRTY2hlbWFbMF07CiAgICB2YXIgcHJvcHMgPSAkT2JqZWN0LmFzc2lnbih7fSwgcmF3U2V0dGluZ1BhcmFtLnByb3BlcnRpZXMpOwogICAgcHJvcHMudmFsdWUgPSB2YWx1ZVNjaGVtYTsKICAgIHZhciBtb2RTZXR0aW5nUGFyYW0gPSB7CiAgICAgIG5hbWU6IHJhd1NldHRpbmdQYXJhbS5uYW1lLAogICAgICB0eXBlOiByYXdTZXR0aW5nUGFyYW0udHlwZSwKICAgICAgcHJvcGVydGllczogcHJvcHMsCiAgICB9OwogICAgdmFyIG1vZFNldFNjaGVtYSA9ICRBcnJheS5zbGljZShyYXdTZXRTY2hlbWEpOwogICAgbW9kU2V0U2NoZW1hWzBdID0gbW9kU2V0dGluZ1BhcmFtOwogICAgdmFsaWRhdGUoW2RldGFpbHMsIGNhbGxiYWNrXSwgbW9kU2V0U2NoZW1hKTsKICAgIHJldHVybiBzZW5kUmVxdWVzdCgndHlwZXMuQ2hyb21lU2V0dGluZy5zZXQnLAogICAgICAgICAgICAgICAgICAgICAgIFtwcmVmS2V5LCBkZXRhaWxzLCBjYWxsYmFja10sCiAgICAgICAgICAgICAgICAgICAgICAgZXh0ZW5kU2NoZW1hKG1vZFNldFNjaGVtYSkpOwogIH07CiAgdGhpcy5jbGVhciA9IGZ1bmN0aW9uKGRldGFpbHMsIGNhbGxiYWNrKSB7CiAgICB2YXIgY2xlYXJTY2hlbWEgPSBnZXRGdW5jdGlvblBhcmFtZXRlcnMoJ2NsZWFyJyk7CiAgICB2YWxpZGF0ZShbZGV0YWlscywgY2FsbGJhY2tdLCBjbGVhclNjaGVtYSk7CiAgICByZXR1cm4gc2VuZFJlcXVlc3QoJ3R5cGVzLkNocm9tZVNldHRpbmcuY2xlYXInLAogICAgICAgICAgICAgICAgICAgICAgIFtwcmVmS2V5LCBkZXRhaWxzLCBjYWxsYmFja10sCiAgICAgICAgICAgICAgICAgICAgICAgZXh0ZW5kU2NoZW1hKGNsZWFyU2NoZW1hKSk7CiAgfTsKICB0aGlzLm9uQ2hhbmdlID0gbmV3IEV2ZW50KCd0eXBlcy5DaHJvbWVTZXR0aW5nLicgKyBwcmVmS2V5ICsgJy5vbkNoYW5nZScpOwp9OwoKZXhwb3J0cy4kc2V0KCdDaHJvbWVTZXR0aW5nJywgQ2hyb21lU2V0dGluZyk7Ci8vIENvcHlyaWdodCAyMDE0IFRoZSBDaHJvbWl1bSBBdXRob3JzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgovLyBVc2Ugb2YgdGhpcyBzb3VyY2UgY29kZSBpcyBnb3Zlcm5lZCBieSBhIEJTRC1zdHlsZSBsaWNlbnNlIHRoYXQgY2FuIGJlCi8vIGZvdW5kIGluIHRoZSBMSUNFTlNFIGZpbGUuCgp2YXIgYmluZGluZyA9IGFwaUJyaWRnZSB8fAogICAgICAgICAgICAgIHJlcXVpcmUoJ2JpbmRpbmcnKS5CaW5kaW5nLmNyZWF0ZSgnY2hyb21lV2ViVmlld0ludGVybmFsJyk7CnZhciBjb250ZXh0TWVudXNIYW5kbGVycyA9IHJlcXVpcmUoJ2NvbnRleHRNZW51c0hhbmRsZXJzJyk7CgpiaW5kaW5nLnJlZ2lzdGVyQ3VzdG9tSG9vayhmdW5jdGlvbihiaW5kaW5nc0FQSSkgewogIHZhciBhcGlGdW5jdGlvbnMgPSBiaW5kaW5nc0FQSS5hcGlGdW5jdGlvbnM7CgogIHZhciBoYW5kbGVycyA9IGNvbnRleHRNZW51c0hhbmRsZXJzLmNyZWF0ZSh0cnVlIC8qIGlzV2VidmlldyAqLyk7CgogIGFwaUZ1bmN0aW9ucy5zZXRIYW5kbGVSZXF1ZXN0KAogICAgICAnY29udGV4dE1lbnVzQ3JlYXRlJywgaGFuZGxlcnMucmVxdWVzdEhhbmRsZXJzLmNyZWF0ZSk7CgogIGFwaUZ1bmN0aW9ucy5zZXRIYW5kbGVSZXF1ZXN0KAogICAgICAnY29udGV4dE1lbnVzVXBkYXRlJywgaGFuZGxlcnMucmVxdWVzdEhhbmRsZXJzLnVwZGF0ZSk7CgogIGFwaUZ1bmN0aW9ucy5zZXRIYW5kbGVSZXF1ZXN0KAogICAgICAnY29udGV4dE1lbnVzUmVtb3ZlJywgaGFuZGxlcnMucmVxdWVzdEhhbmRsZXJzLnJlbW92ZSk7CgogIGFwaUZ1bmN0aW9ucy5zZXRIYW5kbGVSZXF1ZXN0KAogICAgICAnY29udGV4dE1lbnVzUmVtb3ZlQWxsJywgaGFuZGxlcnMucmVxdWVzdEhhbmRsZXJzLnJlbW92ZUFsbCk7Cn0pOwoKaWYgKCFhcGlCcmlkZ2UpCiAgZXhwb3J0cy4kc2V0KCdDaHJvbWVXZWJWaWV3JywgYmluZGluZy5nZW5lcmF0ZSgpKTsKLy8gQ29weXJpZ2h0IDIwMTQgVGhlIENocm9taXVtIEF1dGhvcnMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCi8vIFVzZSBvZiB0aGlzIHNvdXJjZSBjb2RlIGlzIGdvdmVybmVkIGJ5IGEgQlNELXN0eWxlIGxpY2Vuc2UgdGhhdCBjYW4gYmUKLy8gZm91bmQgaW4gdGhlIExJQ0VOU0UgZmlsZS4KCi8vIFRoaXMgbW9kdWxlIGltcGxlbWVudHMgY2hyb21lLXNwZWNpZmljIDx3ZWJ2aWV3PiBBUEkuCi8vIFNlZSB3ZWJfdmlld19hcGlfbWV0aG9kcy5qcyBmb3IgZGV0YWlscy4KCnZhciBDaHJvbWVXZWJWaWV3ID0gZ2V0SW50ZXJuYWxBcGkgPwogICAgZ2V0SW50ZXJuYWxBcGkoJ2Nocm9tZVdlYlZpZXdJbnRlcm5hbCcpIDoKICAgIHJlcXVpcmUoJ2Nocm9tZVdlYlZpZXdJbnRlcm5hbCcpLkNocm9tZVdlYlZpZXc7CnZhciBDaHJvbWVXZWJWaWV3U2NoZW1hID0KICAgIHJlcXVpcmVOYXRpdmUoJ3NjaGVtYV9yZWdpc3RyeScpLkdldFNjaGVtYSgnY2hyb21lV2ViVmlld0ludGVybmFsJyk7CnZhciBDcmVhdGVFdmVudCA9IHJlcXVpcmUoJ2d1ZXN0Vmlld0V2ZW50cycpLkNyZWF0ZUV2ZW50Owp2YXIgR3Vlc3RWaWV3SW50ZXJuYWxOYXRpdmVzID0gcmVxdWlyZU5hdGl2ZSgnZ3Vlc3Rfdmlld19pbnRlcm5hbCcpOwp2YXIgaWRHZW5lcmF0b3JOYXRpdmVzID0gcmVxdWlyZU5hdGl2ZSgnaWRfZ2VuZXJhdG9yJyk7CnZhciB1dGlscyA9IHJlcXVpcmUoJ3V0aWxzJyk7CnZhciBXZWJWaWV3SW1wbCA9IHJlcXVpcmUoJ3dlYlZpZXcnKS5XZWJWaWV3SW1wbDsKCi8vIFRoaXMgaXMgdGhlIG9ubHkgIndlYlZpZXdJbnRlcm5hbC5vbkNsaWNrZWQiIG5hbWVkIGV2ZW50IGZvciB0aGlzIHJlbmRlcmVyLgovLwovLyBTaW5jZSB3ZSBuZWVkIGFuIGV2ZW50IHBlciA8d2Vidmlldz4sIHdlIGRlZmluZSBldmVudHMgd2l0aCBzdWZmaXgKLy8gKHN1YkV2ZW50TmFtZSkgaW4gZWFjaCBvZiB0aGUgPHdlYnZpZXc+LiBCZWhpbmQgdGhlIHNjZW5lcywgdGhpcyBldmVudCBpcwovLyByZWdpc3RlcmVkIGFzIGEgQ29udGV4dE1lbnVzRXZlbnQsIHdpdGggZmlsdGVyIHNldCB0byB0aGUgd2VidmlldydzCi8vIHx2aWV3SW5zdGFuY2VJZHwuIEFueSB0aW1lIGEgQ29udGV4dE1lbnVzRXZlbnQgaXMgZGlzcGF0Y2hlZCwgd2UgcmUtZGlzcGF0Y2gKLy8gaXQgdG8gdGhlIHN1YkV2ZW50J3MgbGlzdGVuZXJzLiBUaGlzIHdheQovLyA8d2Vidmlldz4uY29udGV4dE1lbnVzLm9uQ2xpY2tlZCBiZWhhdmUgYXMgYSByZWd1bGFyIGNocm9tZSBFdmVudCB0eXBlLgp2YXIgQ29udGV4dE1lbnVzRXZlbnQgPSBDcmVhdGVFdmVudCgnY2hyb21lV2ViVmlld0ludGVybmFsLm9uQ2xpY2tlZCcpOwovLyBTZWUgY29tbWVudCBhYm92ZS4KdmFyIENvbnRleHRNZW51c0hhbmRsZXJFdmVudCA9CiAgICBDcmVhdGVFdmVudCgnY2hyb21lV2ViVmlld0ludGVybmFsLm9uQ29udGV4dE1lbnVTaG93Jyk7Cgp2YXIganNFdmVudDsKZnVuY3Rpb24gY3JlYXRlQ3VzdG9tRXZlbnQobmFtZSwgc2NoZW1hLCBvcHRpb25zLCB3ZWJ2aWV3SWQpIHsKICBpZiAoYmluZGluZ1V0aWwpCiAgICByZXR1cm4gYmluZGluZ1V0aWwuY3JlYXRlQ3VzdG9tRXZlbnQobmFtZSwgdW5kZWZpbmVkLCBmYWxzZSwgZmFsc2UpOwogIGlmICghanNFdmVudCkKICAgIGpzRXZlbnQgPSByZXF1aXJlKCdldmVudF9iaW5kaW5ncycpLkV2ZW50OwogIHJldHVybiBuZXcganNFdmVudChuYW1lLCBzY2hlbWEsIG9wdGlvbnMsIHdlYnZpZXdJZCk7Cn0KCi8vIFRoaXMgZXZlbnQgaXMgZXhwb3NlZCBhcyA8d2Vidmlldz4uY29udGV4dE1lbnVzLm9uQ2xpY2tlZC4KZnVuY3Rpb24gY3JlYXRlQ29udGV4dE1lbnVzT25DbGlja2VkRXZlbnQod2ViVmlld0luc3RhbmNlSWQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9wdF9ldmVudE5hbWUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9wdF9hcmdTY2hlbWFzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvcHRfZXZlbnRPcHRpb25zKSB7CiAgdmFyIHN1YkV2ZW50TmFtZSA9IEdldFVuaXF1ZVN1YkV2ZW50TmFtZShvcHRfZXZlbnROYW1lKTsKICB2YXIgbmV3RXZlbnQgPSBjcmVhdGVDdXN0b21FdmVudChzdWJFdmVudE5hbWUsIG9wdF9hcmdTY2hlbWFzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9wdF9ldmVudE9wdGlvbnMsIHdlYlZpZXdJbnN0YW5jZUlkKTsKCiAgdmFyIHZpZXcgPSBHdWVzdFZpZXdJbnRlcm5hbE5hdGl2ZXMuR2V0Vmlld0Zyb21JRCh3ZWJWaWV3SW5zdGFuY2VJZCk7CiAgaWYgKHZpZXcpIHsKICAgIHZpZXcuZXZlbnRzLmFkZFNjb3BlZExpc3RlbmVyKAogICAgICAgIENvbnRleHRNZW51c0V2ZW50LAogICAgICAgICRGdW5jdGlvbi5iaW5kKGZ1bmN0aW9uKCkgewogICAgICAgICAgLy8gUmUtZGlzcGF0Y2ggdG8gc3ViRXZlbnQncyBsaXN0ZW5lcnMuCiAgICAgICAgICAkRnVuY3Rpb24uYXBwbHkobmV3RXZlbnQuZGlzcGF0Y2gsIG5ld0V2ZW50LCAkQXJyYXkuc2xpY2UoYXJndW1lbnRzKSk7CiAgICAgICAgfSwgbmV3RXZlbnQpLAogICAgICAgIHtpbnN0YW5jZUlkOiB3ZWJWaWV3SW5zdGFuY2VJZH0pOwogIH0KICByZXR1cm4gbmV3RXZlbnQ7Cn0KCi8vIFRoaXMgZXZlbnQgaXMgZXhwb3NlZCBhcyA8d2Vidmlldz4uY29udGV4dE1lbnVzLm9uU2hvdy4KZnVuY3Rpb24gY3JlYXRlQ29udGV4dE1lbnVzT25Db250ZXh0TWVudUV2ZW50KHdlYlZpZXdJbnN0YW5jZUlkLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb3B0X2V2ZW50TmFtZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9wdF9hcmdTY2hlbWFzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb3B0X2V2ZW50T3B0aW9ucykgewogIHZhciBzdWJFdmVudE5hbWUgPSBHZXRVbmlxdWVTdWJFdmVudE5hbWUob3B0X2V2ZW50TmFtZSk7CiAgdmFyIG5ld0V2ZW50ID0gY3JlYXRlQ3VzdG9tRXZlbnQoc3ViRXZlbnROYW1lLCBvcHRfYXJnU2NoZW1hcywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvcHRfZXZlbnRPcHRpb25zLCB3ZWJWaWV3SW5zdGFuY2VJZCk7CgogIHZhciB2aWV3ID0gR3Vlc3RWaWV3SW50ZXJuYWxOYXRpdmVzLkdldFZpZXdGcm9tSUQod2ViVmlld0luc3RhbmNlSWQpOwogIGlmICh2aWV3KSB7CiAgICB2aWV3LmV2ZW50cy5hZGRTY29wZWRMaXN0ZW5lcigKICAgICAgICBDb250ZXh0TWVudXNIYW5kbGVyRXZlbnQsCiAgICAgICAgJEZ1bmN0aW9uLmJpbmQoZnVuY3Rpb24oZSkgewogICAgICAgICAgdmFyIGRlZmF1bHRQcmV2ZW50ZWQgPSBmYWxzZTsKICAgICAgICAgIHZhciBldmVudCA9IHsKICAgICAgICAgICAgcHJldmVudERlZmF1bHQ6IGZ1bmN0aW9uKCkgeyBkZWZhdWx0UHJldmVudGVkID0gdHJ1ZTsgfQogICAgICAgICAgfTsKCiAgICAgICAgICAvLyBSZS1kaXNwYXRjaCB0byBzdWJFdmVudCdzIGxpc3RlbmVycy4KICAgICAgICAgICRGdW5jdGlvbi5hcHBseShuZXdFdmVudC5kaXNwYXRjaCwgbmV3RXZlbnQsIFtldmVudF0pOwoKICAgICAgICAgIGlmICghZGVmYXVsdFByZXZlbnRlZCkgewogICAgICAgICAgLy8gVE9ETyhsYXp5Ym95KTogUmVtb3ZlIHxpdGVtc3wgcGFyYW1ldGVyIGNvbXBsZXRlbHkgZnJvbQogICAgICAgICAgLy8gQ2hyb21lV2ViVmlldy5zaG93Q29udGV4dE1lbnUgYXMgd2UgZG9uJ3QgZG8gYW55dGhpbmcgdXNlZnVsIHdpdGgKICAgICAgICAgIC8vIGl0IGN1cnJlbnRseS4KICAgICAgICAgIHZhciBpdGVtcyA9IFtdOwogICAgICAgICAgdmFyIGd1ZXN0SW5zdGFuY2VJZCA9IEd1ZXN0Vmlld0ludGVybmFsTmF0aXZlcy4KICAgICAgICAgICAgICBHZXRWaWV3RnJvbUlEKHdlYlZpZXdJbnN0YW5jZUlkKS5ndWVzdC5nZXRJZCgpOwogICAgICAgICAgQ2hyb21lV2ViVmlldy5zaG93Q29udGV4dE1lbnUoZ3Vlc3RJbnN0YW5jZUlkLCBlLnJlcXVlc3RJZCwgaXRlbXMpOwogICAgICAgIH0KICAgICAgfSwgbmV3RXZlbnQpLAogICAgICB7aW5zdGFuY2VJZDogd2ViVmlld0luc3RhbmNlSWR9KTsKICB9CgogIHJldHVybiBuZXdFdmVudDsKfQoKLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KLy8gV2ViVmlld0NvbnRleHRNZW51c0ltcGwgb2JqZWN0LgoKLy8gQW4gaW5zdGFuY2Ugb2YgdGhpcyBjbGFzcyBpcyBleHBvc2VkIGFzIDx3ZWJ2aWV3Pi5jb250ZXh0TWVudXMuCmZ1bmN0aW9uIFdlYlZpZXdDb250ZXh0TWVudXNJbXBsKHZpZXdJbnN0YW5jZUlkKSB7CiAgdGhpcy52aWV3SW5zdGFuY2VJZF8gPSB2aWV3SW5zdGFuY2VJZDsKfQokT2JqZWN0LnNldFByb3RvdHlwZU9mKFdlYlZpZXdDb250ZXh0TWVudXNJbXBsLnByb3RvdHlwZSwgbnVsbCk7CgpXZWJWaWV3Q29udGV4dE1lbnVzSW1wbC5wcm90b3R5cGUuY3JlYXRlID0gZnVuY3Rpb24oKSB7CiAgdmFyIGFyZ3MgPSAkQXJyYXkuY29uY2F0KFt0aGlzLnZpZXdJbnN0YW5jZUlkX10sICRBcnJheS5zbGljZShhcmd1bWVudHMpKTsKICByZXR1cm4gJEZ1bmN0aW9uLmFwcGx5KENocm9tZVdlYlZpZXcuY29udGV4dE1lbnVzQ3JlYXRlLCBudWxsLCBhcmdzKTsKfTsKCldlYlZpZXdDb250ZXh0TWVudXNJbXBsLnByb3RvdHlwZS5yZW1vdmUgPSBmdW5jdGlvbigpIHsKICB2YXIgYXJncyA9ICRBcnJheS5jb25jYXQoW3RoaXMudmlld0luc3RhbmNlSWRfXSwgJEFycmF5LnNsaWNlKGFyZ3VtZW50cykpOwogIHJldHVybiAkRnVuY3Rpb24uYXBwbHkoQ2hyb21lV2ViVmlldy5jb250ZXh0TWVudXNSZW1vdmUsIG51bGwsIGFyZ3MpOwp9OwoKV2ViVmlld0NvbnRleHRNZW51c0ltcGwucHJvdG90eXBlLnJlbW92ZUFsbCA9IGZ1bmN0aW9uKCkgewogIHZhciBhcmdzID0gJEFycmF5LmNvbmNhdChbdGhpcy52aWV3SW5zdGFuY2VJZF9dLCAkQXJyYXkuc2xpY2UoYXJndW1lbnRzKSk7CiAgcmV0dXJuICRGdW5jdGlvbi5hcHBseShDaHJvbWVXZWJWaWV3LmNvbnRleHRNZW51c1JlbW92ZUFsbCwgbnVsbCwgYXJncyk7Cn07CgpXZWJWaWV3Q29udGV4dE1lbnVzSW1wbC5wcm90b3R5cGUudXBkYXRlID0gZnVuY3Rpb24oKSB7CiAgdmFyIGFyZ3MgPSAkQXJyYXkuY29uY2F0KFt0aGlzLnZpZXdJbnN0YW5jZUlkX10sICRBcnJheS5zbGljZShhcmd1bWVudHMpKTsKICByZXR1cm4gJEZ1bmN0aW9uLmFwcGx5KENocm9tZVdlYlZpZXcuY29udGV4dE1lbnVzVXBkYXRlLCBudWxsLCBhcmdzKTsKfTsKCmZ1bmN0aW9uIFdlYlZpZXdDb250ZXh0TWVudXMoKSB7CiAgcHJpdmF0ZXMoV2ViVmlld0NvbnRleHRNZW51cykuY29uc3RydWN0UHJpdmF0ZSh0aGlzLCBhcmd1bWVudHMpOwp9CnV0aWxzLmV4cG9zZShXZWJWaWV3Q29udGV4dE1lbnVzLCBXZWJWaWV3Q29udGV4dE1lbnVzSW1wbCwgewogIGZ1bmN0aW9uczogWwogICAgJ2NyZWF0ZScsCiAgICAncmVtb3ZlJywKICAgICdyZW1vdmVBbGwnLAogICAgJ3VwZGF0ZScsCiAgXSwKfSk7CgovLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKV2ViVmlld0ltcGwucHJvdG90eXBlLm1heWJlU2V0dXBDb250ZXh0TWVudXMgPSBmdW5jdGlvbigpIHsKICBpZiAoIXRoaXMuY29udGV4dE1lbnVzT25Db250ZXh0TWVudUV2ZW50XykgewogICAgdmFyIGV2ZW50TmFtZSA9ICdjaHJvbWVXZWJWaWV3SW50ZXJuYWwub25Db250ZXh0TWVudVNob3cnOwogICAgdmFyIGV2ZW50U2NoZW1hID0KICAgICAgICB1dGlscy5sb29rdXAoQ2hyb21lV2ViVmlld1NjaGVtYS5ldmVudHMsICduYW1lJywgJ29uU2hvdycpOwogICAgdmFyIGV2ZW50T3B0aW9ucyA9IHtzdXBwb3J0c0xpc3RlbmVyczogdHJ1ZSwgc3VwcG9ydHNMYXp5TGlzdGVuZXJzOiBmYWxzZX07CiAgICB0aGlzLmNvbnRleHRNZW51c09uQ29udGV4dE1lbnVFdmVudF8gPSBjcmVhdGVDb250ZXh0TWVudXNPbkNvbnRleHRNZW51RXZlbnQoCiAgICAgICAgdGhpcy52aWV3SW5zdGFuY2VJZCwgZXZlbnROYW1lLCBldmVudFNjaGVtYSwgZXZlbnRPcHRpb25zKTsKICB9CgogIHZhciBjcmVhdGVDb250ZXh0TWVudXMgPSAkRnVuY3Rpb24uYmluZChmdW5jdGlvbigpIHsKICAgIHJldHVybiB0aGlzLndlYWtXcmFwcGVyKGZ1bmN0aW9uKCkgewogICAgICBpZiAodGhpcy5jb250ZXh0TWVudXNfKSB7CiAgICAgICAgcmV0dXJuIHRoaXMuY29udGV4dE1lbnVzXzsKICAgICAgfQoKICAgICAgdGhpcy5jb250ZXh0TWVudXNfID0gbmV3IFdlYlZpZXdDb250ZXh0TWVudXModGhpcy52aWV3SW5zdGFuY2VJZCk7CgogICAgICAvLyBEZWZpbmUgJ29uQ2xpY2tlZCcgZXZlbnQgcHJvcGVydHkgb24gfHRoaXMuY29udGV4dE1lbnVzX3wuCiAgICAgIHZhciBnZXRPbkNsaWNrZWRFdmVudCA9ICRGdW5jdGlvbi5iaW5kKGZ1bmN0aW9uKCkgewogICAgICAgIHJldHVybiB0aGlzLndlYWtXcmFwcGVyKGZ1bmN0aW9uKCkgewogICAgICAgICAgaWYgKCF0aGlzLmNvbnRleHRNZW51c09uQ2xpY2tlZEV2ZW50XykgewogICAgICAgICAgICB2YXIgZXZlbnROYW1lID0gJ2Nocm9tZVdlYlZpZXdJbnRlcm5hbC5vbkNsaWNrZWQnOwogICAgICAgICAgICB2YXIgZXZlbnRTY2hlbWEgPQogICAgICAgICAgICAgICAgdXRpbHMubG9va3VwKENocm9tZVdlYlZpZXdTY2hlbWEuZXZlbnRzLCAnbmFtZScsICdvbkNsaWNrZWQnKTsKICAgICAgICAgICAgdmFyIGV2ZW50T3B0aW9ucyA9CiAgICAgICAgICAgICAgICB7c3VwcG9ydHNMaXN0ZW5lcnM6IHRydWUsIHN1cHBvcnRzTGF6eUxpc3RlbmVyczogZmFsc2V9OwogICAgICAgICAgICB2YXIgb25DbGlja2VkRXZlbnQgPSBjcmVhdGVDb250ZXh0TWVudXNPbkNsaWNrZWRFdmVudCgKICAgICAgICAgICAgICAgIHRoaXMudmlld0luc3RhbmNlSWQsIGV2ZW50TmFtZSwgZXZlbnRTY2hlbWEsIGV2ZW50T3B0aW9ucyk7CiAgICAgICAgICAgIHRoaXMuY29udGV4dE1lbnVzT25DbGlja2VkRXZlbnRfID0gb25DbGlja2VkRXZlbnQ7CiAgICAgICAgICAgIHJldHVybiBvbkNsaWNrZWRFdmVudDsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiB0aGlzLmNvbnRleHRNZW51c09uQ2xpY2tlZEV2ZW50XzsKICAgICAgICB9KTsKICAgICAgfSwgdGhpcyk7CiAgICAgICRPYmplY3QuZGVmaW5lUHJvcGVydHkoCiAgICAgICAgICB0aGlzLmNvbnRleHRNZW51c18sCiAgICAgICAgICAnb25DbGlja2VkJywKICAgICAgICAgIHtnZXQ6IGdldE9uQ2xpY2tlZEV2ZW50KCksIGVudW1lcmFibGU6IHRydWV9KTsKICAgICAgJE9iamVjdC5kZWZpbmVQcm9wZXJ0eSgKICAgICAgICAgIHRoaXMuY29udGV4dE1lbnVzXywKICAgICAgICAgICdvblNob3cnLAogICAgICAgICAgewogICAgICAgICAgICBnZXQ6IHRoaXMud2Vha1dyYXBwZXIoZnVuY3Rpb24oKSB7CiAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuY29udGV4dE1lbnVzT25Db250ZXh0TWVudUV2ZW50XzsKICAgICAgICAgICAgfSksCiAgICAgICAgICAgIGVudW1lcmFibGU6IHRydWUKICAgICAgICAgIH0pOwogICAgICByZXR1cm4gdGhpcy5jb250ZXh0TWVudXNfOwogICAgfSk7CiAgfSwgdGhpcyk7CgogIC8vIEV4cG9zZSA8d2Vidmlldz4uY29udGV4dE1lbnVzIG9iamVjdC4KICAkT2JqZWN0LmRlZmluZVByb3BlcnR5KAogICAgICB0aGlzLmVsZW1lbnQsCiAgICAgICdjb250ZXh0TWVudXMnLAogICAgICB7CiAgICAgICAgZ2V0OiBjcmVhdGVDb250ZXh0TWVudXMoKSwKICAgICAgICBlbnVtZXJhYmxlOiB0cnVlCiAgICAgIH0pOwp9OwoKZnVuY3Rpb24gR2V0VW5pcXVlU3ViRXZlbnROYW1lKGV2ZW50TmFtZSkgewogIHJldHVybiBldmVudE5hbWUgKyAnLycgKyBpZEdlbmVyYXRvck5hdGl2ZXMuR2V0TmV4dElkKCk7Cn0KLy8gQ29weXJpZ2h0IChjKSAyMDEyIFRoZSBDaHJvbWl1bSBBdXRob3JzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgovLyBVc2Ugb2YgdGhpcyBzb3VyY2UgY29kZSBpcyBnb3Zlcm5lZCBieSBhIEJTRC1zdHlsZSBsaWNlbnNlIHRoYXQgY2FuIGJlCi8vIGZvdW5kIGluIHRoZSBMSUNFTlNFIGZpbGUuCgovLyBDdXN0b20gYmluZGluZyBmb3IgdGhlIGNvbnRlbnRTZXR0aW5ncyBBUEkuCgp2YXIgc2VuZFJlcXVlc3QgPSByZXF1aXJlKCdzZW5kUmVxdWVzdCcpLnNlbmRSZXF1ZXN0Owp2YXIgdmFsaWRhdGUgPSByZXF1aXJlKCdzY2hlbWFVdGlscycpLnZhbGlkYXRlOwoKLy8gU29tZSBjb250ZW50IHR5cGVzIGhhdmUgYmVlbiByZW1vdmVkIGFuZCBubyBsb25nZXIgY29ycmVzcG9uZCB0byBhIHJlYWwKLy8gY29udGVudCBzZXR0aW5nLiBJbnN0ZWFkLCB0aGVzZSBhbHdheXMgcmV0dXJuIGEgZml4ZWQgZHVtbXkgdmFsdWUsIGFuZCBpc3N1ZQovLyBhIHdhcm5pbmcgd2hlbiBhY2Nlc3NlZC4gVGhpcyBtYXBzIHRoZSBjb250ZW50IHR5cGUgbmFtZSB0byB0aGUgZHVtbXkgdmFsdWUuCnZhciBERVBSRUNBVEVEX0NPTlRFTlRfVFlQRVMgPSB7CiAgX19wcm90b19fOiBudWxsLAoKICBmdWxsc2NyZWVuOiAnYWxsb3cnLAogIG1vdXNlbG9jazogJ2FsbG93JywKfTsKCmZ1bmN0aW9uIGV4dGVuZFNjaGVtYShzY2hlbWEpIHsKICB2YXIgZXh0ZW5kZWRTY2hlbWEgPSAkQXJyYXkuc2xpY2Uoc2NoZW1hKTsKICAkQXJyYXkudW5zaGlmdChleHRlbmRlZFNjaGVtYSwgeyd0eXBlJzogJ3N0cmluZyd9KTsKICByZXR1cm4gZXh0ZW5kZWRTY2hlbWE7Cn0KCmZ1bmN0aW9uIENvbnRlbnRTZXR0aW5nKGNvbnRlbnRUeXBlLCBzZXR0aW5nU2NoZW1hLCBzY2hlbWEpIHsKICB2YXIgZ2V0RnVuY3Rpb25QYXJhbWV0ZXJzID0gZnVuY3Rpb24obmFtZSkgewogICAgdmFyIGYgPSAkQXJyYXkuZmlsdGVyKAogICAgICAgICAgICAgICAgc2NoZW1hLmZ1bmN0aW9ucywgZnVuY3Rpb24oZikgeyByZXR1cm4gZi5uYW1lID09PSBuYW1lOyB9KVswXTsKICAgIHJldHVybiBmLnBhcmFtZXRlcnM7CiAgfTsKICB0aGlzLmdldCA9IGZ1bmN0aW9uKGRldGFpbHMsIGNhbGxiYWNrKSB7CiAgICB2YXIgZ2V0U2NoZW1hID0gZ2V0RnVuY3Rpb25QYXJhbWV0ZXJzKCdnZXQnKTsKICAgIHZhbGlkYXRlKFtkZXRhaWxzLCBjYWxsYmFja10sIGdldFNjaGVtYSk7CgogICAgdmFyIGR1bW15U2V0dGluZyA9IERFUFJFQ0FURURfQ09OVEVOVF9UWVBFU1tjb250ZW50VHlwZV07CiAgICBpZiAoZHVtbXlTZXR0aW5nICE9PSB1bmRlZmluZWQpIHsKICAgICAgY29uc29sZS53YXJuKCdjb250ZW50U2V0dGluZ3MuJyArIGNvbnRlbnRUeXBlICsgJyBpcyBkZXByZWNhdGVkOyBpdCB3aWxsICcKICAgICAgICAgICAgICAgICAgICsgJ2Fsd2F5cyByZXR1cm4gXCcnICsgZHVtbXlTZXR0aW5nICsgJ1wnLicpOwogICAgICAkRnVuY3Rpb24uYXBwbHkoY2FsbGJhY2ssIHVuZGVmaW5lZCwgW3tzZXR0aW5nOiBkdW1teVNldHRpbmd9XSk7CiAgICAgIHJldHVybjsKICAgIH0KCiAgICByZXR1cm4gc2VuZFJlcXVlc3QoJ2NvbnRlbnRTZXR0aW5ncy5nZXQnLAogICAgICAgICAgICAgICAgICAgICAgIFtjb250ZW50VHlwZSwgZGV0YWlscywgY2FsbGJhY2tdLAogICAgICAgICAgICAgICAgICAgICAgIGV4dGVuZFNjaGVtYShnZXRTY2hlbWEpKTsKICB9OwoKICB0aGlzLnNldCA9IGZ1bmN0aW9uKGRldGFpbHMsIGNhbGxiYWNrKSB7CiAgICAvLyBXZSBjaGVjayBpZiB0aGUgc2V0dGluZyBpcyBkZXByZWNhdGVkIGZpcnN0LCBzaW5jZSB0aGUgdmFsaWRhdGlvbiB3aWxsCiAgICAvLyBmYWlsIGZvciBkZXByZWNhdGVkIHR5cGVzLgogICAgaWYgKCRPYmplY3QuaGFzT3duUHJvcGVydHkoREVQUkVDQVRFRF9DT05URU5UX1RZUEVTLCBjb250ZW50VHlwZSkpIHsKICAgICAgY29uc29sZS53YXJuKCdjb250ZW50U2V0dGluZ3MuJyArIGNvbnRlbnRUeXBlICsgJyBpcyBkZXByZWNhdGVkOyBzZXR0aW5nICcKICAgICAgICAgICAgICAgICAgICsgJ2l0IGhhcyBubyBlZmZlY3QuJyk7CiAgICAgICRGdW5jdGlvbi5hcHBseShjYWxsYmFjaywgdW5kZWZpbmVkLCBbXSk7CiAgICAgIHJldHVybjsKICAgIH0KCiAgICAvLyBUaGUgc2V0IHNjaGVtYSBpbmNsdWRlZCBpbiB0aGUgU2NoZW1hIG9iamVjdCBpcyBnZW5lcmljLCBzaW5jZSBpdCB2YXJpZXMKICAgIC8vIHBlci1zZXR0aW5nLiBIb3dldmVyLCB0aGlzIGlzIG9ubHkgZXZlciBmb3IgYSBzaW5nbGUgc2V0dGluZywgc28gd2UgY2FuCiAgICAvLyBlbmZvcmNlIHRoZSB0eXBlcyBtb3JlIHRob3JvdWdobHkuCiAgICB2YXIgcmF3U2V0U2NoZW1hID0gZ2V0RnVuY3Rpb25QYXJhbWV0ZXJzKCdzZXQnKTsKICAgIHZhciByYXdTZXR0aW5nUGFyYW0gPSByYXdTZXRTY2hlbWFbMF07CiAgICB2YXIgcHJvcHMgPSAkT2JqZWN0LmFzc2lnbih7fSwgcmF3U2V0dGluZ1BhcmFtLnByb3BlcnRpZXMpOwogICAgcHJvcHMuc2V0dGluZyA9IHNldHRpbmdTY2hlbWE7CiAgICB2YXIgbW9kU2V0dGluZ1BhcmFtID0gewogICAgICBuYW1lOiByYXdTZXR0aW5nUGFyYW0ubmFtZSwKICAgICAgdHlwZTogcmF3U2V0dGluZ1BhcmFtLnR5cGUsCiAgICAgIHByb3BlcnRpZXM6IHByb3BzLAogICAgfTsKICAgIHZhciBtb2RTZXRTY2hlbWEgPSAkQXJyYXkuc2xpY2UocmF3U2V0U2NoZW1hKTsKICAgIG1vZFNldFNjaGVtYVswXSA9IG1vZFNldHRpbmdQYXJhbTsKICAgIHZhbGlkYXRlKFtkZXRhaWxzLCBjYWxsYmFja10sIG1vZFNldFNjaGVtYSk7CgogICAgcmV0dXJuIHNlbmRSZXF1ZXN0KCdjb250ZW50U2V0dGluZ3Muc2V0JywKICAgICAgICAgICAgICAgICAgICAgICBbY29udGVudFR5cGUsIGRldGFpbHMsIGNhbGxiYWNrXSwKICAgICAgICAgICAgICAgICAgICAgICBleHRlbmRTY2hlbWEobW9kU2V0U2NoZW1hKSk7CiAgfTsKCiAgdGhpcy5jbGVhciA9IGZ1bmN0aW9uKGRldGFpbHMsIGNhbGxiYWNrKSB7CiAgICB2YXIgY2xlYXJTY2hlbWEgPSBnZXRGdW5jdGlvblBhcmFtZXRlcnMoJ2NsZWFyJyk7CiAgICB2YWxpZGF0ZShbZGV0YWlscywgY2FsbGJhY2tdLCBjbGVhclNjaGVtYSk7CgogICAgaWYgKCRPYmplY3QuaGFzT3duUHJvcGVydHkoREVQUkVDQVRFRF9DT05URU5UX1RZUEVTLCBjb250ZW50VHlwZSkpIHsKICAgICAgY29uc29sZS53YXJuKCdjb250ZW50U2V0dGluZ3MuJyArIGNvbnRlbnRUeXBlICsgJyBpcyBkZXByZWNhdGVkOyAnCiAgICAgICAgICAgICAgICAgICArICdjbGVhcmluZyBpdCBoYXMgbm8gZWZmZWN0LicpOwogICAgICAkRnVuY3Rpb24uYXBwbHkoY2FsbGJhY2ssIHVuZGVmaW5lZCwgW10pOwogICAgICByZXR1cm47CiAgICB9CgogICAgcmV0dXJuIHNlbmRSZXF1ZXN0KCdjb250ZW50U2V0dGluZ3MuY2xlYXInLAogICAgICAgICAgICAgICAgICAgICAgIFtjb250ZW50VHlwZSwgZGV0YWlscywgY2FsbGJhY2tdLAogICAgICAgICAgICAgICAgICAgICAgIGV4dGVuZFNjaGVtYShjbGVhclNjaGVtYSkpOwogIH07CgogIHRoaXMuZ2V0UmVzb3VyY2VJZGVudGlmaWVycyA9IGZ1bmN0aW9uKGNhbGxiYWNrKSB7CiAgICB2YXIgc2NoZW1hID0gZ2V0RnVuY3Rpb25QYXJhbWV0ZXJzKCdnZXRSZXNvdXJjZUlkZW50aWZpZXJzJyk7CiAgICB2YWxpZGF0ZShbY2FsbGJhY2tdLCBzY2hlbWEpOwoKICAgIGlmICgkT2JqZWN0Lmhhc093blByb3BlcnR5KERFUFJFQ0FURURfQ09OVEVOVF9UWVBFUywgY29udGVudFR5cGUpKSB7CiAgICAgICRGdW5jdGlvbi5hcHBseShjYWxsYmFjaywgdW5kZWZpbmVkLCBbXSk7CiAgICAgIHJldHVybjsKICAgIH0KCiAgICByZXR1cm4gc2VuZFJlcXVlc3QoCiAgICAgICAgJ2NvbnRlbnRTZXR0aW5ncy5nZXRSZXNvdXJjZUlkZW50aWZpZXJzJywKICAgICAgICBbY29udGVudFR5cGUsIGNhbGxiYWNrXSwKICAgICAgICBleHRlbmRTY2hlbWEoc2NoZW1hKSk7CiAgfTsKfQoKZXhwb3J0cy4kc2V0KCdDb250ZW50U2V0dGluZycsIENvbnRlbnRTZXR0aW5nKTsKLy8gQ29weXJpZ2h0IChjKSAyMDEyIFRoZSBDaHJvbWl1bSBBdXRob3JzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgovLyBVc2Ugb2YgdGhpcyBzb3VyY2UgY29kZSBpcyBnb3Zlcm5lZCBieSBhIEJTRC1zdHlsZSBsaWNlbnNlIHRoYXQgY2FuIGJlCi8vIGZvdW5kIGluIHRoZSBMSUNFTlNFIGZpbGUuCgovLyBDdXN0b20gYmluZGluZyBmb3IgdGhlIGRlY2xhcmF0aXZlQ29udGVudCBBUEkuCgp2YXIgYmluZGluZyA9CiAgICBhcGlCcmlkZ2UgfHwgcmVxdWlyZSgnYmluZGluZycpLkJpbmRpbmcuY3JlYXRlKCdkZWNsYXJhdGl2ZUNvbnRlbnQnKTsKCmlmICghYXBpQnJpZGdlKSB7CiAgdmFyIHV0aWxzID0gcmVxdWlyZSgndXRpbHMnKTsKICB2YXIgdmFsaWRhdGUgPSByZXF1aXJlKCdzY2hlbWFVdGlscycpLnZhbGlkYXRlOwogIHZhciBjYW5vbmljYWxpemVDb21wb3VuZFNlbGVjdG9yID0KICAgICAgcmVxdWlyZU5hdGl2ZSgnY3NzX25hdGl2ZXMnKS5DYW5vbmljYWxpemVDb21wb3VuZFNlbGVjdG9yOwp9Cgp2YXIgc2V0SWNvbiA9IHJlcXVpcmUoJ3NldEljb24nKS5zZXRJY29uOwoKYmluZGluZy5yZWdpc3RlckN1c3RvbUhvb2soZnVuY3Rpb24oYXBpKSB7CiAgdmFyIGRlY2xhcmF0aXZlQ29udGVudCA9IGFwaS5jb21waWxlZEFwaTsKCiAgaWYgKGFwaUJyaWRnZSkgewogICAgLy8gVmFsaWRhdGlvbiBmb3IgbW9zdCB0eXBlcyBpcyBkb25lIGluIHRoZSBuYXRpdmUgQysrIHdpdGggbmF0aXZlIGJpbmRpbmdzLAogICAgLy8gYnV0IHNldEljb24gaXMgZnVubnkgKGFuZCBzYWRseSBicm9rZW4pLiBJZGVhbGx5LCB3ZSBjYW4gbW92ZSB0aGlzCiAgICAvLyB2YWxpZGF0aW9uIGVudGlyZWx5IGludG8gdGhlIG5hdGl2ZSBjb2RlLCBhbmQgdGhpcyB3aG9sZSBmaWxlIGNhbiBnbwogICAgLy8gYXdheS4KICAgIHZhciBuYXRpdmVTZXRJY29uID0gZGVjbGFyYXRpdmVDb250ZW50LlNldEljb247CiAgICBkZWNsYXJhdGl2ZUNvbnRlbnQuU2V0SWNvbiA9IGZ1bmN0aW9uKHBhcmFtZXRlcnMpIHsKICAgICAgLy8gVE9ETyhkZXZsaW4pOiBUaGlzIGlzIHZlcnksIHZlcnkgd3JvbmcuIHNldEljb24oKSBpcyBwb3RlbnRpYWxseQogICAgICAvLyBhc3luY2hyb25vdXMgKGluIHRoZSBjYXNlIG9mIGEgcGF0aCBiZWluZyBzcGVjaWZpZWQpLCB3aGljaCBtZWFucyB0aGlzCiAgICAgIC8vIGJlY29tZXMgYW4gImFzeW5jaHJvbm91cyBjb25zdHJ1Y3RvciIuIEVycm9ycyBjYW4gYmUgdGhyb3duICphZnRlciogdGhlCiAgICAgIC8vIGBuZXcgZGVjbGFyYXRpdmVDb250ZW50LlNldEljb24oLi4uKWAgY2FsbCwgYW5kIGluIHRoZSBhc3luYyBjYXNlcywKICAgICAgLy8gdGhpcyB3b3VsZG4ndCB3b3JrIHdoZW4gd2UgaW1tZWRpYXRlbHkgYWRkIHRoZSBhY3Rpb24gdmlhIGFuIEFQSSBjYWxsCiAgICAgIC8vIChlLmcuLAogICAgICAvLyAgIGNocm9tZS5kZWNsYXJhdGl2ZUNvbnRlbnQub25QYWdlQ2hhbmdlLmFkZFJ1bGVzKAogICAgICAvLyAgICAgICBbe2NvbmRpdGlvbnM6IC4uLiwgYWN0aW9uczogWyBuZXcgU2V0SWNvbiguLi4pIF19XSk7CiAgICAgIC8vICkuIFNvbWUgb2YgdGhpcyBpcyB0cmFja2VkIGluIGh0dHA6Ly9jcmJ1Zy5jb20vNDE1MzE1LgogICAgICBzZXRJY29uKHBhcmFtZXRlcnMsICRGdW5jdGlvbi5iaW5kKGZ1bmN0aW9uKGRhdGEpIHsKICAgICAgICAvLyBGYWtlIGNhbGxpbmcgdGhlIG9yaWdpbmFsIGZ1bmN0aW9uIGFzIGEgY29uc3RydWN0b3IuCiAgICAgICAgJE9iamVjdC5zZXRQcm90b3R5cGVPZih0aGlzLCBuYXRpdmVTZXRJY29uLnByb3RvdHlwZSk7CiAgICAgICAgJEZ1bmN0aW9uLmFwcGx5KG5hdGl2ZVNldEljb24sIHRoaXMsIFtkYXRhXSk7CiAgICAgIH0sIHRoaXMpKTsKICAgIH07CiAgICByZXR1cm47CiAgfQoKICAvLyBSZXR1cm5zIHRoZSBzY2hlbWEgZGVmaW5pdGlvbiBvZiB0eXBlIHx0eXBlSWR8IGRlZmluZWQgaW4gfG5hbWVzcGFjZXwuCiAgZnVuY3Rpb24gZ2V0U2NoZW1hKHR5cGVJZCkgewogICAgcmV0dXJuIHV0aWxzLmxvb2t1cChhcGkuc2NoZW1hLnR5cGVzLAogICAgICAgICAgICAgICAgICAgICAgICAnaWQnLAogICAgICAgICAgICAgICAgICAgICAgICAnZGVjbGFyYXRpdmVDb250ZW50LicgKyB0eXBlSWQpOwogIH0KCiAgLy8gSGVscGVyIGZ1bmN0aW9uIGZvciB0aGUgY29uc3RydWN0b3Igb2YgY29uY3JldGUgZGF0YXR5cGVzIG9mIHRoZQogIC8vIGRlY2xhcmF0aXZlIGNvbnRlbnQgQVBJLgogIC8vIE1ha2VzIHN1cmUgdGhhdCB8dGhpc3wgY29udGFpbnMgdGhlIHVuaW9uIG9mIHBhcmFtZXRlcnMgYW5kCiAgLy8geydpbnN0YW5jZVR5cGUnOiAnZGVjbGFyYXRpdmVDb250ZW50LicgKyB0eXBlSWR9IGFuZCB2YWxpZGF0ZXMgdGhlCiAgLy8gZ2VuZXJhdGVkIHVuaW9uIGRpY3Rpb25hcnkgYWdhaW5zdCB0aGUgc2NoZW1hIGZvciB8dHlwZUlkfC4KICBmdW5jdGlvbiBzZXR1cEluc3RhbmNlKGluc3RhbmNlLCBwYXJhbWV0ZXJzLCB0eXBlSWQpIHsKICAgIGZvciAodmFyIGtleSBpbiBwYXJhbWV0ZXJzKSB7CiAgICAgIGlmICgkT2JqZWN0Lmhhc093blByb3BlcnR5KHBhcmFtZXRlcnMsIGtleSkpIHsKICAgICAgICBpbnN0YW5jZVtrZXldID0gcGFyYW1ldGVyc1trZXldOwogICAgICB9CiAgICB9CiAgICBpbnN0YW5jZS5pbnN0YW5jZVR5cGUgPSAnZGVjbGFyYXRpdmVDb250ZW50LicgKyB0eXBlSWQ7CiAgICB2YXIgc2NoZW1hID0gZ2V0U2NoZW1hKHR5cGVJZCk7CiAgICB2YWxpZGF0ZShbaW5zdGFuY2VdLCBbc2NoZW1hXSk7CiAgfQoKICBmdW5jdGlvbiBjYW5vbmljYWxpemVDc3NTZWxlY3RvcnMoc2VsZWN0b3JzKSB7CiAgICBmb3IgKHZhciBpID0gMDsgaSA8IHNlbGVjdG9ycy5sZW5ndGg7IGkrKykgewogICAgICB2YXIgY2Fub25pY2FsaXplZFNlbGVjdG9yID0gY2Fub25pY2FsaXplQ29tcG91bmRTZWxlY3RvcihzZWxlY3RvcnNbaV0pOwogICAgICBpZiAoY2Fub25pY2FsaXplZFNlbGVjdG9yID09ICcnKSB7CiAgICAgICAgdGhyb3cgbmV3IEVycm9yKAogICAgICAgICAgICAnRWxlbWVudCBvZiBcJ2Nzc1wnIGFycmF5IG11c3QgYmUgYSAnICsKICAgICAgICAgICAgJ2xpc3Qgb2YgdmFsaWQgY29tcG91bmQgc2VsZWN0b3JzOiAnICsKICAgICAgICAgICAgc2VsZWN0b3JzW2ldKTsKICAgICAgfQogICAgICBzZWxlY3RvcnNbaV0gPSBjYW5vbmljYWxpemVkU2VsZWN0b3I7CiAgICB9CiAgfQoKICAvLyBTZXR1cCBhbGwgZGF0YSB0eXBlcyBmb3IgdGhlIGRlY2xhcmF0aXZlIGNvbnRlbnQgQVBJLgogIGRlY2xhcmF0aXZlQ29udGVudC5QYWdlU3RhdGVNYXRjaGVyID0gZnVuY3Rpb24ocGFyYW1ldGVycykgewogICAgc2V0dXBJbnN0YW5jZSh0aGlzLCBwYXJhbWV0ZXJzLCAnUGFnZVN0YXRlTWF0Y2hlcicpOwogICAgaWYgKCRPYmplY3QuaGFzT3duUHJvcGVydHkodGhpcywgJ2NzcycpKSB7CiAgICAgIGNhbm9uaWNhbGl6ZUNzc1NlbGVjdG9ycyh0aGlzLmNzcyk7CiAgICB9CiAgfTsKICBkZWNsYXJhdGl2ZUNvbnRlbnQuU2hvd1BhZ2VBY3Rpb24gPSBmdW5jdGlvbihwYXJhbWV0ZXJzKSB7CiAgICBzZXR1cEluc3RhbmNlKHRoaXMsIHBhcmFtZXRlcnMsICdTaG93UGFnZUFjdGlvbicpOwogIH07CiAgZGVjbGFyYXRpdmVDb250ZW50LlJlcXVlc3RDb250ZW50U2NyaXB0ID0gZnVuY3Rpb24ocGFyYW1ldGVycykgewogICAgc2V0dXBJbnN0YW5jZSh0aGlzLCBwYXJhbWV0ZXJzLCAnUmVxdWVzdENvbnRlbnRTY3JpcHQnKTsKICB9OwogIC8vIFRPRE8ocm9ja290KTogRG8gbm90IGV4cG9zZSB0aGlzIGluIE0zOSBzdGFibGUuIE1ha2luZyB0aGlzIHJlc3RyaWN0aW9uCiAgLy8gcG9zc2libGUgd2lsbCB0YWtlIHNvbWUgZXh0cmEgd29yay4gU2VlIGh0dHA6Ly9jcmJ1Zy5jb20vNDE1MzE1CiAgLy8gTm90ZTogU2VlIGFsc28gdGhlIFNldEljb24gd3JhcHBlciBhYm92ZSBmb3IgbW9yZSBpc3N1ZXMuCiAgZGVjbGFyYXRpdmVDb250ZW50LlNldEljb24gPSBmdW5jdGlvbihwYXJhbWV0ZXJzKSB7CiAgICBzZXRJY29uKHBhcmFtZXRlcnMsICRGdW5jdGlvbi5iaW5kKGZ1bmN0aW9uKGRhdGEpIHsKICAgICAgc2V0dXBJbnN0YW5jZSh0aGlzLCBkYXRhLCAnU2V0SWNvbicpOwogICAgfSwgdGhpcykpOwogIH07Cn0pOwoKaWYgKCFhcGlCcmlkZ2UpCiAgZXhwb3J0cy4kc2V0KCdiaW5kaW5nJywgYmluZGluZy5nZW5lcmF0ZSgpKTsKLy8gQ29weXJpZ2h0IDIwMTMgVGhlIENocm9taXVtIEF1dGhvcnMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCi8vIFVzZSBvZiB0aGlzIHNvdXJjZSBjb2RlIGlzIGdvdmVybmVkIGJ5IGEgQlNELXN0eWxlIGxpY2Vuc2UgdGhhdCBjYW4gYmUKLy8gZm91bmQgaW4gdGhlIExJQ0VOU0UgZmlsZS4KCi8vIEN1c3RvbSBiaW5kaW5nIGZvciB0aGUgZGVza3RvcENhcHR1cmUgQVBJLgoKdmFyIGJpbmRpbmcgPSBhcGlCcmlkZ2UgfHwgcmVxdWlyZSgnYmluZGluZycpLkJpbmRpbmcuY3JlYXRlKCdkZXNrdG9wQ2FwdHVyZScpOwp2YXIgc2VuZFJlcXVlc3QgPSBiaW5kaW5nVXRpbCA/CiAgICAkRnVuY3Rpb24uYmluZChiaW5kaW5nVXRpbC5zZW5kUmVxdWVzdCwgYmluZGluZ1V0aWwpIDoKICAgIHJlcXVpcmUoJ3NlbmRSZXF1ZXN0Jykuc2VuZFJlcXVlc3Q7CnZhciBpZEdlbmVyYXRvciA9IHJlcXVpcmVOYXRpdmUoJ2lkX2dlbmVyYXRvcicpOwoKYmluZGluZy5yZWdpc3RlckN1c3RvbUhvb2soZnVuY3Rpb24oYmluZGluZ3NBUEkpIHsKICB2YXIgYXBpRnVuY3Rpb25zID0gYmluZGluZ3NBUEkuYXBpRnVuY3Rpb25zOwoKICB2YXIgcGVuZGluZ1JlcXVlc3RzID0ge307CgogIGZ1bmN0aW9uIG9uUmVxdWVzdFJlc3VsdChpZCwgcmVzdWx0LCBvcHRpb25zKSB7CiAgICBpZiAoaWQgaW4gcGVuZGluZ1JlcXVlc3RzKSB7CiAgICAgIHZhciBjYWxsYmFjayA9IHBlbmRpbmdSZXF1ZXN0c1tpZF07CiAgICAgIGRlbGV0ZSBwZW5kaW5nUmVxdWVzdHNbaWRdOwogICAgICBjYWxsYmFjayhyZXN1bHQsIG9wdGlvbnMpOwogICAgfQogIH0KCiAgYXBpRnVuY3Rpb25zLnNldEhhbmRsZVJlcXVlc3QoJ2Nob29zZURlc2t0b3BNZWRpYScsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZnVuY3Rpb24oc291cmNlcywgdGFyZ2V0X3RhYiwgY2FsbGJhY2spIHsKICAgIC8vIHx0YXJnZXRfdGFifCBpcyBhbiBvcHRpb25hbCBwYXJhbWV0ZXIuCiAgICBpZiAoY2FsbGJhY2sgPT09IHVuZGVmaW5lZCkgewogICAgICBjYWxsYmFjayA9IHRhcmdldF90YWI7CiAgICAgIHRhcmdldF90YWIgPSB1bmRlZmluZWQ7CiAgICB9CiAgICB2YXIgaWQgPSBpZEdlbmVyYXRvci5HZXROZXh0SWQoKTsKICAgIHBlbmRpbmdSZXF1ZXN0c1tpZF0gPSBjYWxsYmFjazsKICAgIHNlbmRSZXF1ZXN0KCdkZXNrdG9wQ2FwdHVyZS5jaG9vc2VEZXNrdG9wTWVkaWEnLAogICAgICAgICAgICAgICAgW2lkLCBzb3VyY2VzLCB0YXJnZXRfdGFiLAogICAgICAgICAgICAgICAgICRGdW5jdGlvbi5iaW5kKG9uUmVxdWVzdFJlc3VsdCwgbnVsbCwgaWQpXSwKICAgICAgICAgICAgICAgIGFwaUJyaWRnZSA/IHVuZGVmaW5lZCA6IHRoaXMuZGVmaW5pdGlvbi5wYXJhbWV0ZXJzLAogICAgICAgICAgICAgICAgdW5kZWZpbmVkKTsKICAgIHJldHVybiBpZDsKICB9KTsKCiAgYXBpRnVuY3Rpb25zLnNldEhhbmRsZVJlcXVlc3QoJ2NhbmNlbENob29zZURlc2t0b3BNZWRpYScsIGZ1bmN0aW9uKGlkKSB7CiAgICBpZiAoaWQgaW4gcGVuZGluZ1JlcXVlc3RzKSB7CiAgICAgIGRlbGV0ZSBwZW5kaW5nUmVxdWVzdHNbaWRdOwogICAgICBzZW5kUmVxdWVzdCgnZGVza3RvcENhcHR1cmUuY2FuY2VsQ2hvb3NlRGVza3RvcE1lZGlhJywKICAgICAgICAgICAgICAgICAgW2lkXSwgYXBpQnJpZGdlID8gdW5kZWZpbmVkIDogdGhpcy5kZWZpbml0aW9uLnBhcmFtZXRlcnMsCiAgICAgICAgICAgICAgICAgIHVuZGVmaW5lZCk7CiAgICB9CiAgfSk7Cn0pOwoKaWYgKCFhcGlCcmlkZ2UpCiAgZXhwb3J0cy4kc2V0KCdiaW5kaW5nJywgYmluZGluZy5nZW5lcmF0ZSgpKTsKLy8gQ29weXJpZ2h0IDIwMTQgVGhlIENocm9taXVtIEF1dGhvcnMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCi8vIFVzZSBvZiB0aGlzIHNvdXJjZSBjb2RlIGlzIGdvdmVybmVkIGJ5IGEgQlNELXN0eWxlIGxpY2Vuc2UgdGhhdCBjYW4gYmUKLy8gZm91bmQgaW4gdGhlIExJQ0VOU0UgZmlsZS4KCi8vIEN1c3RvbSBiaW5kaW5nIGZvciB0aGUgZGV2ZWxvcGVyUHJpdmF0ZSBBUEkuCgp2YXIgYmluZGluZyA9CiAgICBhcGlCcmlkZ2UgfHwgcmVxdWlyZSgnYmluZGluZycpLkJpbmRpbmcuY3JlYXRlKCdkZXZlbG9wZXJQcml2YXRlJyk7CgpiaW5kaW5nLnJlZ2lzdGVyQ3VzdG9tSG9vayhmdW5jdGlvbihiaW5kaW5nc0FQSSkgewogIHZhciBhcGlGdW5jdGlvbnMgPSBiaW5kaW5nc0FQSS5hcGlGdW5jdGlvbnM7CgogIC8vIENvbnZlcnRzIHRoZSBhcmd1bWVudCBvZiB8ZnVuY3Rpb25OYW1lfCBmcm9tIERpcmVjdG9yeUVudHJ5IHRvIFVSTC4KICBmdW5jdGlvbiBiaW5kRmlsZVN5c3RlbUZ1bmN0aW9uKGZ1bmN0aW9uTmFtZSkgewogICAgYXBpRnVuY3Rpb25zLnNldFVwZGF0ZUFyZ3VtZW50c1Bvc3RWYWxpZGF0ZSgKICAgICAgICBmdW5jdGlvbk5hbWUsIGZ1bmN0aW9uKGRpcmVjdG9yeUVudHJ5LCBjYWxsYmFjaykgewogICAgICAgICAgdmFyIGZpbGVTeXN0ZW1OYW1lID0gZGlyZWN0b3J5RW50cnkuZmlsZXN5c3RlbS5uYW1lOwogICAgICAgICAgdmFyIHJlbGF0aXZlUGF0aCA9ICRTdHJpbmcuc2xpY2UoZGlyZWN0b3J5RW50cnkuZnVsbFBhdGgsIDEpOwogICAgICAgICAgdmFyIHVybCA9IGRpcmVjdG9yeUVudHJ5LnRvVVJMKCk7CiAgICAgICAgICByZXR1cm4gW2ZpbGVTeXN0ZW1OYW1lLCByZWxhdGl2ZVBhdGgsIHVybCwgY2FsbGJhY2tdOwogICAgfSk7CiAgfQoKICBiaW5kRmlsZVN5c3RlbUZ1bmN0aW9uKCdsb2FkRGlyZWN0b3J5Jyk7CgogIC8vIGRldmVsb3BlclByaXZhdGUuZW5hYmxlIGlzIHRoZSBzYW1lIGFzIGNocm9tZS5tYW5hZ2VtZW50LnNldEVuYWJsZWQuCiAgLy8gVE9ETyhkZXZsaW4pOiBNaWdyYXRlIGNhbGxlcnMgb2ZmIGRldmVsb3BlclByaXZhdGUuZW5hYmxlLgogIGJpbmRpbmdzQVBJLmNvbXBpbGVkQXBpLmVuYWJsZSA9IGNocm9tZS5tYW5hZ2VtZW50LnNldEVuYWJsZWQ7CgogIGFwaUZ1bmN0aW9ucy5zZXRIYW5kbGVSZXF1ZXN0KCdhbGxvd0ZpbGVBY2Nlc3MnLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZ1bmN0aW9uKGlkLCBhbGxvdywgY2FsbGJhY2spIHsKICAgIGNocm9tZS5kZXZlbG9wZXJQcml2YXRlLnVwZGF0ZUV4dGVuc2lvbkNvbmZpZ3VyYXRpb24oCiAgICAgICAge2V4dGVuc2lvbklkOiBpZCwgZmlsZUFjY2VzczogYWxsb3d9LCBjYWxsYmFjayk7CiAgfSk7CgogIGFwaUZ1bmN0aW9ucy5zZXRIYW5kbGVSZXF1ZXN0KCdhbGxvd0luY29nbml0bycsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZnVuY3Rpb24oaWQsIGFsbG93LCBjYWxsYmFjaykgewogICAgY2hyb21lLmRldmVsb3BlclByaXZhdGUudXBkYXRlRXh0ZW5zaW9uQ29uZmlndXJhdGlvbigKICAgICAgICB7ZXh0ZW5zaW9uSWQ6IGlkLCBpbmNvZ25pdG9BY2Nlc3M6IGFsbG93fSwgY2FsbGJhY2spOwogIH0pOwoKICBhcGlGdW5jdGlvbnMuc2V0SGFuZGxlUmVxdWVzdCgnaW5zcGVjdCcsIGZ1bmN0aW9uKG9wdGlvbnMsIGNhbGxiYWNrKSB7CiAgICB2YXIgcmVuZGVyVmlld0lkID0gb3B0aW9ucy5yZW5kZXJfdmlld19pZDsKICAgIGlmICh0eXBlb2YgcmVuZGVyVmlld0lkID09ICdzdHJpbmcnKSB7CiAgICAgIHJlbmRlclZpZXdJZCA9IHBhcnNlSW50KHJlbmRlclZpZXdJZCk7CiAgICAgIGlmIChpc05hTihyZW5kZXJWaWV3SWQpKQogICAgICAgIHRocm93IG5ldyBFcnJvcignSW52YWxpZCB2YWx1ZSBmb3IgcmVuZGVyX3ZpZXdfaWQnKTsKICAgIH0KICAgIHZhciByZW5kZXJQcm9jZXNzSWQgPSBvcHRpb25zLnJlbmRlcl9wcm9jZXNzX2lkOwogICAgaWYgKHR5cGVvZiByZW5kZXJQcm9jZXNzSWQgPT0gJ3N0cmluZycpIHsKICAgICAgcmVuZGVyUHJvY2Vzc0lkID0gcGFyc2VJbnQocmVuZGVyUHJvY2Vzc0lkKTsKICAgICAgaWYgKGlzTmFOKHJlbmRlclByb2Nlc3NJZCkpCiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdJbnZhbGlkIHZhbHVlIGZvciByZW5kZXJfcHJvY2Vzc19pZCcpOwogICAgfQogICAgY2hyb21lLmRldmVsb3BlclByaXZhdGUub3BlbkRldlRvb2xzKHsKICAgICAgICBleHRlbnNpb25JZDogb3B0aW9ucy5leHRlbnNpb25faWQsCiAgICAgICAgcmVuZGVyUHJvY2Vzc0lkOiByZW5kZXJQcm9jZXNzSWQsCiAgICAgICAgcmVuZGVyVmlld0lkOiByZW5kZXJWaWV3SWQsCiAgICAgICAgaW5jb2duaXRvOiBvcHRpb25zLmluY29nbml0bwogICAgfSwgY2FsbGJhY2spOwogIH0pOwp9KTsKCmlmICghYXBpQnJpZGdlKQogIGV4cG9ydHMuJHNldCgnYmluZGluZycsIGJpbmRpbmcuZ2VuZXJhdGUoKSk7Ci8vIENvcHlyaWdodCAoYykgMjAxMyBUaGUgQ2hyb21pdW0gQXV0aG9ycy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KLy8gVXNlIG9mIHRoaXMgc291cmNlIGNvZGUgaXMgZ292ZXJuZWQgYnkgYSBCU0Qtc3R5bGUgbGljZW5zZSB0aGF0IGNhbiBiZQovLyBmb3VuZCBpbiB0aGUgTElDRU5TRSBmaWxlLgoKLy8gQ3VzdG9tIGJpbmRpbmdzIGZvciB0aGUgZG93bmxvYWRzIEFQSS4KCnZhciBiaW5kaW5nID0gYXBpQnJpZGdlIHx8IHJlcXVpcmUoJ2JpbmRpbmcnKS5CaW5kaW5nLmNyZWF0ZSgnZG93bmxvYWRzJyk7CnZhciBkb3dubG9hZHNJbnRlcm5hbCA9CiAgICBnZXRJbnRlcm5hbEFwaSA/CiAgICAgICAgZ2V0SW50ZXJuYWxBcGkoJ2Rvd25sb2Fkc0ludGVybmFsJykgOgogICAgICAgIHJlcXVpcmUoJ2JpbmRpbmcnKS5CaW5kaW5nLmNyZWF0ZSgnZG93bmxvYWRzSW50ZXJuYWwnKS5nZW5lcmF0ZSgpOwp2YXIgcmVnaXN0ZXJBcmd1bWVudE1hc3NhZ2VyID0gYmluZGluZ1V0aWwgPwogICAgJEZ1bmN0aW9uLmJpbmQoYmluZGluZ1V0aWwucmVnaXN0ZXJFdmVudEFyZ3VtZW50TWFzc2FnZXIsIGJpbmRpbmdVdGlsKSA6CiAgICByZXF1aXJlKCdldmVudF9iaW5kaW5ncycpLnJlZ2lzdGVyQXJndW1lbnRNYXNzYWdlcjsKCnJlZ2lzdGVyQXJndW1lbnRNYXNzYWdlcignZG93bmxvYWRzLm9uRGV0ZXJtaW5pbmdGaWxlbmFtZScsCiAgICAgICAgICAgICAgICAgICAgICAgICBmdW5jdGlvbihhcmdzLCBkaXNwYXRjaCkgewogIHZhciBkb3dubG9hZEl0ZW0gPSBhcmdzWzBdOwogIC8vIENvcHkgdGhlIGlkIHNvIHRoYXQgZXh0ZW5zaW9ucyBjYW4ndCBjaGFuZ2UgaXQuCiAgdmFyIGRvd25sb2FkSWQgPSBkb3dubG9hZEl0ZW0uaWQ7CiAgdmFyIHN1Z2dlc3RhYmxlID0gdHJ1ZTsKICBmdW5jdGlvbiBpc1ZhbGlkUmVzdWx0KHJlc3VsdCkgewogICAgaWYgKHJlc3VsdCA9PT0gdW5kZWZpbmVkKQogICAgICByZXR1cm4gZmFsc2U7CiAgICBpZiAodHlwZW9mKHJlc3VsdCkgIT0gJ29iamVjdCcpIHsKICAgICAgY29uc29sZS5lcnJvcignRXJyb3I6IEludm9jYXRpb24gb2YgZm9ybSBzdWdnZXN0KCcgKyB0eXBlb2YocmVzdWx0KSArCiAgICAgICAgICAgICAgICAgICAgJykgZG9lc25cJ3QgbWF0Y2ggZGVmaW5pdGlvbiBzdWdnZXN0KHtmaWxlbmFtZTogc3RyaW5nLCAnICsKICAgICAgICAgICAgICAgICAgICAnY29uZmxpY3RBY3Rpb246IHN0cmluZ30pJyk7CiAgICAgIHJldHVybiBmYWxzZTsKICAgIH0gZWxzZSBpZiAoKHR5cGVvZihyZXN1bHQuZmlsZW5hbWUpICE9ICdzdHJpbmcnKSB8fAogICAgICAgICAgICAgICAocmVzdWx0LmZpbGVuYW1lLmxlbmd0aCA9PSAwKSkgewogICAgICBjb25zb2xlLmVycm9yKCdFcnJvcjogImZpbGVuYW1lIiBwYXJhbWV0ZXIgdG8gc3VnZ2VzdCgpIG11c3QgYmUgYSAnICsKICAgICAgICAgICAgICAgICAgICAnbm9uLWVtcHR5IHN0cmluZycpOwogICAgICByZXR1cm4gZmFsc2U7CiAgICB9IGVsc2UgaWYgKFt1bmRlZmluZWQsICd1bmlxdWlmeScsICdvdmVyd3JpdGUnLCAncHJvbXB0J10uaW5kZXhPZigKICAgICAgICAgICAgICAgICByZXN1bHQuY29uZmxpY3RBY3Rpb24pIDwgMCkgewogICAgICBjb25zb2xlLmVycm9yKCdFcnJvcjogImNvbmZsaWN0QWN0aW9uIiBwYXJhbWV0ZXIgdG8gc3VnZ2VzdCgpIG11c3QgYmUgJyArCiAgICAgICAgICAgICAgICAgICAgJ29uZSBvZiB1bmRlZmluZWQsICJ1bmlxdWlmeSIsICJvdmVyd3JpdGUiLCAicHJvbXB0IicpOwogICAgICByZXR1cm4gZmFsc2U7CiAgICB9CiAgICByZXR1cm4gdHJ1ZTsKICB9CiAgZnVuY3Rpb24gc3VnZ2VzdENhbGxiYWNrKHJlc3VsdCkgewogICAgaWYgKCFzdWdnZXN0YWJsZSkgewogICAgICBjb25zb2xlLmVycm9yKCdzdWdnZXN0Q2FsbGJhY2sgbWF5IG5vdCBiZSBjYWxsZWQgbW9yZSB0aGFuIG9uY2UuJyk7CiAgICAgIHJldHVybjsKICAgIH0KICAgIHN1Z2dlc3RhYmxlID0gZmFsc2U7CiAgICBpZiAoaXNWYWxpZFJlc3VsdChyZXN1bHQpKSB7CiAgICAgIGRvd25sb2Fkc0ludGVybmFsLmRldGVybWluZUZpbGVuYW1lKAogICAgICAgICAgZG93bmxvYWRJZCwgcmVzdWx0LmZpbGVuYW1lLCByZXN1bHQuY29uZmxpY3RBY3Rpb24gfHwgIiIpOwogICAgfSBlbHNlIHsKICAgICAgZG93bmxvYWRzSW50ZXJuYWwuZGV0ZXJtaW5lRmlsZW5hbWUoZG93bmxvYWRJZCwgIiIsICIiKTsKICAgIH0KICB9CiAgdHJ5IHsKICAgIHZhciByZXN1bHRzID0gZGlzcGF0Y2goW2Rvd25sb2FkSXRlbSwgc3VnZ2VzdENhbGxiYWNrXSk7CiAgICB2YXIgYXN5bmMgPSAocmVzdWx0cyAmJgogICAgICAgICAgICAgICAgIHJlc3VsdHMucmVzdWx0cyAmJgogICAgICAgICAgICAgICAgIChyZXN1bHRzLnJlc3VsdHMubGVuZ3RoICE9IDApICYmCiAgICAgICAgICAgICAgICAgKHJlc3VsdHMucmVzdWx0c1swXSA9PT0gdHJ1ZSkpOwogICAgaWYgKHN1Z2dlc3RhYmxlICYmICFhc3luYykKICAgICAgc3VnZ2VzdENhbGxiYWNrKCk7CiAgfSBjYXRjaCAoZSkgewogICAgc3VnZ2VzdENhbGxiYWNrKCk7CiAgICB0aHJvdyBlOwogIH0KfSk7CgppZiAoIWFwaUJyaWRnZSkKICBleHBvcnRzLiRzZXQoJ2JpbmRpbmcnLCBiaW5kaW5nLmdlbmVyYXRlKCkpOwovLyBDb3B5cmlnaHQgMjAxNyBUaGUgQ2hyb21pdW0gQXV0aG9ycy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KLy8gVXNlIG9mIHRoaXMgc291cmNlIGNvZGUgaXMgZ292ZXJuZWQgYnkgYSBCU0Qtc3R5bGUgbGljZW5zZSB0aGF0IGNhbiBiZQovLyBmb3VuZCBpbiB0aGUgTElDRU5TRSBmaWxlLgoKdmFyIEV2ZW50ID0gcmVxdWlyZSgnZXZlbnRfYmluZGluZ3MnKS5FdmVudDsKCi8vIFRoZSBFYXN5VW5sb2NrUHJveGltaXR5UmVxdWlyZWQgb2JqZWN0IGlzIGp1c3QgYSBzdHViIHRoYXQgaGFzIGFuIG9uQ2hhbmdlCi8vIGV2ZW50LCB3aGljaCBpcyBuZXZlciB0cmlnZ2VyZWQuCi8vIFRPRE8oZGV2bGluKTogUmVtb3ZlIHRoaXMgb25jZSB0aGUgcHJlZmVyZW5jZXNQcml2YXRlIEFQSSBpcyBmdWxseSByZW1vdmVkLgovLyBodHRwczovL2NyYnVnLmNvbS81OTMxNjYKZnVuY3Rpb24gRWFzeVVubG9ja1Byb3hpbWl0eVJlcXVpcmVkKHByZWZLZXksIHZhbHVlU2NoZW1hLCBzY2hlbWEpIHsKICAvLyBOb3RlOiB0ZWNobmljYWxseSwgZXh0ZW5zaW9ucyBjb3VsZCBpbnRlcmNlcHQgdGhpcyB0aHJvdWdoIGEgc2V0dGVyIG9uCiAgLy8gT2JqZWN0LnByb3RvdHlwZSgpLiBXZSBkb24ndCByZWFsbHkgY2FyZSwgYmVjYXVzZSBhKSB0aGlzIGlzIG9ubHkgZm9yIGEKICAvLyBwcml2YXRlIEFQSSwgc28gd2Ugc2hvdWxkbid0IGhhdmUgdG8gd29ycnkgYWJvdXQgdW50cnVzdGVkIGNvZGUsIGFuZCBiKQogIC8vIHRoaXMgaXMgYW4gYW5vbnltb3VzIGV2ZW50LCB3aGljaCBleHBvc2VzIG5vIGF0dGFjayBzdXJmYWNlIGFuZCB3aWxsIGJlCiAgLy8gZXhwb3NlZCB0byB0aGUgZXh0ZW5zaW9uIGFueXdheS4KICB0aGlzLm9uQ2hhbmdlID0gbmV3IEV2ZW50KCk7Cn07CgpleHBvcnRzLiRzZXQoJ0Vhc3lVbmxvY2tQcm94aW1pdHlSZXF1aXJlZCcsIEVhc3lVbmxvY2tQcm94aW1pdHlSZXF1aXJlZCk7Ci8vIENvcHlyaWdodCAyMDEzIFRoZSBDaHJvbWl1bSBBdXRob3JzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgovLyBVc2Ugb2YgdGhpcyBzb3VyY2UgY29kZSBpcyBnb3Zlcm5lZCBieSBhIEJTRC1zdHlsZSBsaWNlbnNlIHRoYXQgY2FuIGJlCi8vIGZvdW5kIGluIHRoZSBMSUNFTlNFIGZpbGUuCgovLyBDdXN0b20gYmluZGluZ3MgZm9yIHRoZSBmZWVkYmFja1ByaXZhdGUgQVBJLgoKdmFyIGJpbmRpbmcgPSBhcGlCcmlkZ2UgfHwgcmVxdWlyZSgnYmluZGluZycpLkJpbmRpbmcuY3JlYXRlKCdmZWVkYmFja1ByaXZhdGUnKTsKCnZhciBibG9iTmF0aXZlcyA9IHJlcXVpcmVOYXRpdmUoJ2Jsb2JfbmF0aXZlcycpOwoKYmluZGluZy5yZWdpc3RlckN1c3RvbUhvb2soZnVuY3Rpb24oYmluZGluZ3NBUEkpIHsKICB2YXIgYXBpRnVuY3Rpb25zID0gYmluZGluZ3NBUEkuYXBpRnVuY3Rpb25zOwogIGFwaUZ1bmN0aW9ucy5zZXRVcGRhdGVBcmd1bWVudHNQb3N0VmFsaWRhdGUoCiAgICAgICJzZW5kRmVlZGJhY2siLCBmdW5jdGlvbihmZWVkYmFja0luZm8sIGNhbGxiYWNrKSB7CiAgICB2YXIgYXR0YWNoZWRGaWxlQmxvYlV1aWQgPSAnJzsKICAgIHZhciBzY3JlZW5zaG90QmxvYlV1aWQgPSAnJzsKCiAgICBpZiAoZmVlZGJhY2tJbmZvLmF0dGFjaGVkRmlsZSkKICAgICAgYXR0YWNoZWRGaWxlQmxvYlV1aWQgPQogICAgICAgICAgYmxvYk5hdGl2ZXMuR2V0QmxvYlV1aWQoZmVlZGJhY2tJbmZvLmF0dGFjaGVkRmlsZS5kYXRhKTsKICAgIGlmIChmZWVkYmFja0luZm8uc2NyZWVuc2hvdCkKICAgICAgc2NyZWVuc2hvdEJsb2JVdWlkID0KICAgICAgICAgIGJsb2JOYXRpdmVzLkdldEJsb2JVdWlkKGZlZWRiYWNrSW5mby5zY3JlZW5zaG90KTsKCiAgICBmZWVkYmFja0luZm8uYXR0YWNoZWRGaWxlQmxvYlV1aWQgPSBhdHRhY2hlZEZpbGVCbG9iVXVpZDsKICAgIGZlZWRiYWNrSW5mby5zY3JlZW5zaG90QmxvYlV1aWQgPSBzY3JlZW5zaG90QmxvYlV1aWQ7CgogICAgcmV0dXJuIFtmZWVkYmFja0luZm8sIGNhbGxiYWNrXTsKICB9KTsKfSk7CgppZiAoIWFwaUJyaWRnZSkKICBleHBvcnRzLiRzZXQoJ2JpbmRpbmcnLCBiaW5kaW5nLmdlbmVyYXRlKCkpOwovLyBDb3B5cmlnaHQgMjAxMyBUaGUgQ2hyb21pdW0gQXV0aG9ycy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KLy8gVXNlIG9mIHRoaXMgc291cmNlIGNvZGUgaXMgZ292ZXJuZWQgYnkgYSBCU0Qtc3R5bGUgbGljZW5zZSB0aGF0IGNhbiBiZQovLyBmb3VuZCBpbiB0aGUgTElDRU5TRSBmaWxlLgoKLy8gQ3VzdG9tIGJpbmRpbmcgZm9yIHRoZSBHQ00gQVBJLgoKdmFyIGJpbmRpbmcgPSBhcGlCcmlkZ2UgfHwgcmVxdWlyZSgnYmluZGluZycpLkJpbmRpbmcuY3JlYXRlKCdnY20nKTsKdmFyIGZvckVhY2ggPSByZXF1aXJlKCd1dGlscycpLmZvckVhY2g7CgpiaW5kaW5nLnJlZ2lzdGVyQ3VzdG9tSG9vayhmdW5jdGlvbihiaW5kaW5nc0FQSSkgewogIHZhciBhcGlGdW5jdGlvbnMgPSBiaW5kaW5nc0FQSS5hcGlGdW5jdGlvbnM7CiAgdmFyIGdjbSA9IGJpbmRpbmdzQVBJLmNvbXBpbGVkQXBpOwoKICBhcGlGdW5jdGlvbnMuc2V0VXBkYXRlQXJndW1lbnRzUG9zdFZhbGlkYXRlKAogICAgJ3NlbmQnLCBmdW5jdGlvbihtZXNzYWdlLCBjYWxsYmFjaykgewogICAgICAvLyBWYWxpZGF0ZSBtZXNzYWdlLmRhdGEuCiAgICAgIHZhciBwYXlsb2FkU2l6ZSA9IDA7CiAgICAgIGZvckVhY2gobWVzc2FnZS5kYXRhLCBmdW5jdGlvbihwcm9wZXJ0eSwgdmFsdWUpIHsKICAgICAgICBpZiAocHJvcGVydHkubGVuZ3RoID09IDApCiAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoIk9uZSBvZiBkYXRhIGtleXMgaXMgZW1wdHkuIik7CgogICAgICAgIHZhciBsb3dlckNhc2VkUHJvcGVydHkgPSBwcm9wZXJ0eS50b0xvd2VyQ2FzZSgpOwogICAgICAgIC8vIElzc3VlIGFuIGVycm9yIGZvciBmb3JiaWRkZW4gcHJlZml4ZXMgb2YgcHJvcGVydHkgbmFtZXMuCiAgICAgICAgaWYgKGxvd2VyQ2FzZWRQcm9wZXJ0eS5zdGFydHNXaXRoKCJnb29nLiIpIHx8CiAgICAgICAgICAgIGxvd2VyQ2FzZWRQcm9wZXJ0eS5zdGFydHNXaXRoKCJnb29nbGUiKSB8fAogICAgICAgICAgICBwcm9wZXJ0eS5zdGFydHNXaXRoKCJjb2xsYXBzZV9rZXkiKSkgewogICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCJJbnZhbGlkIGRhdGEga2V5OiAiICsgcHJvcGVydHkpOwogICAgICAgIH0KCiAgICAgICAgcGF5bG9hZFNpemUgKz0gcHJvcGVydHkubGVuZ3RoICsgdmFsdWUubGVuZ3RoOwogICAgICB9KTsKCiAgICAgIGlmIChwYXlsb2FkU2l6ZSA+IGdjbS5NQVhfTUVTU0FHRV9TSVpFKQogICAgICAgIHRocm93IG5ldyBFcnJvcigiUGF5bG9hZCBleGNlZWRlZCBhbGxvd2VkIHNpemUgbGltaXQuIFBheWxvYWQgc2l6ZSBpczogIgogICAgICAgICAgICArIHBheWxvYWRTaXplKTsKCiAgICAgIGlmIChwYXlsb2FkU2l6ZSA9PSAwKQogICAgICAgIHRocm93IG5ldyBFcnJvcigiTm8gZGF0YSB0byBzZW5kLiIpOwoKICAgICAgcmV0dXJuIGFyZ3VtZW50czsKICAgIH0pOwp9KTsKCmlmICghYXBpQnJpZGdlKQogIGV4cG9ydHMuJHNldCgnYmluZGluZycsIGJpbmRpbmcuZ2VuZXJhdGUoKSk7Ci8vIENvcHlyaWdodCAyMDEzIFRoZSBDaHJvbWl1bSBBdXRob3JzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgovLyBVc2Ugb2YgdGhpcyBzb3VyY2UgY29kZSBpcyBnb3Zlcm5lZCBieSBhIEJTRC1zdHlsZSBsaWNlbnNlIHRoYXQgY2FuIGJlCi8vIGZvdW5kIGluIHRoZSBMSUNFTlNFIGZpbGUuCgovLyBDdXN0b20gYmluZGluZyBmb3IgdGhlIElkZW50aXR5IEFQSS4KCnZhciBiaW5kaW5nID0gYXBpQnJpZGdlIHx8IHJlcXVpcmUoJ2JpbmRpbmcnKS5CaW5kaW5nLmNyZWF0ZSgnaWRlbnRpdHknKTsKCmJpbmRpbmcucmVnaXN0ZXJDdXN0b21Ib29rKGZ1bmN0aW9uKGJpbmRpbmcsIGlkLCBjb250ZXh0VHlwZSkgewogIHZhciBhcGlGdW5jdGlvbnMgPSBiaW5kaW5nLmFwaUZ1bmN0aW9uczsKCiAgYXBpRnVuY3Rpb25zLnNldEhhbmRsZVJlcXVlc3QoJ2dldFJlZGlyZWN0VVJMJywgZnVuY3Rpb24ocGF0aCkgewogICAgaWYgKHBhdGggPT09IG51bGwgfHwgcGF0aCA9PT0gdW5kZWZpbmVkKQogICAgICBwYXRoID0gJy8nOwogICAgZWxzZQogICAgICBwYXRoID0gU3RyaW5nKHBhdGgpOwogICAgaWYgKHBhdGhbMF0gIT0gJy8nKQogICAgICBwYXRoID0gJy8nICsgcGF0aDsKICAgIHJldHVybiAnaHR0cHM6Ly8nICsgaWQgKyAnLmNocm9taXVtYXBwLm9yZycgKyBwYXRoOwogIH0pOwp9KTsKCmlmICghYXBpQnJpZGdlKQogIGV4cG9ydHMuJHNldCgnYmluZGluZycsIGJpbmRpbmcuZ2VuZXJhdGUoKSk7Ci8vIENvcHlyaWdodCAyMDEzIFRoZSBDaHJvbWl1bSBBdXRob3JzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgovLyBVc2Ugb2YgdGhpcyBzb3VyY2UgY29kZSBpcyBnb3Zlcm5lZCBieSBhIEJTRC1zdHlsZSBsaWNlbnNlIHRoYXQgY2FuIGJlCi8vIGZvdW5kIGluIHRoZSBMSUNFTlNFIGZpbGUuCgovLyBDdXN0b20gYmluZGluZyBmb3IgdGhlIGltYWdlIHdyaXRlciBwcml2YXRlIEFQSS4KCnZhciBiaW5kaW5nID0KICAgIGFwaUJyaWRnZSB8fCByZXF1aXJlKCdiaW5kaW5nJykuQmluZGluZy5jcmVhdGUoJ2ltYWdlV3JpdGVyUHJpdmF0ZScpOwoKYmluZGluZy5yZWdpc3RlckN1c3RvbUhvb2soZnVuY3Rpb24oYmluZGluZ3NBUEkpIHsKICB2YXIgYXBpRnVuY3Rpb25zID0gYmluZGluZ3NBUEkuYXBpRnVuY3Rpb25zOwoKICBhcGlGdW5jdGlvbnMuc2V0VXBkYXRlQXJndW1lbnRzUG9zdFZhbGlkYXRlKAogICAgICAnd3JpdGVGcm9tRmlsZScsIGZ1bmN0aW9uKGRldmljZSwgZmlsZUVudHJ5LCBvcHRpb25zLCBjYWxsYmFjaykgewogICAgdmFyIGZpbGVTeXN0ZW1OYW1lID0gZmlsZUVudHJ5LmZpbGVzeXN0ZW0ubmFtZTsKICAgIHZhciByZWxhdGl2ZVBhdGggPSAkU3RyaW5nLnNsaWNlKGZpbGVFbnRyeS5mdWxsUGF0aCwgMSk7CiAgICByZXR1cm4gW2RldmljZSwgZmlsZVN5c3RlbU5hbWUsIHJlbGF0aXZlUGF0aCwgY2FsbGJhY2tdOwogIH0pOwp9KTsKCmlmICghYXBpQnJpZGdlKQogIGV4cG9ydHMuJHNldCgnYmluZGluZycsIGJpbmRpbmcuZ2VuZXJhdGUoKSk7Ci8vIENvcHlyaWdodCAoYykgMjAxMiBUaGUgQ2hyb21pdW0gQXV0aG9ycy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KLy8gVXNlIG9mIHRoaXMgc291cmNlIGNvZGUgaXMgZ292ZXJuZWQgYnkgYSBCU0Qtc3R5bGUgbGljZW5zZSB0aGF0IGNhbiBiZQovLyBmb3VuZCBpbiB0aGUgTElDRU5TRSBmaWxlLgoKLy8gQ3VzdG9tIGJpbmRpbmcgZm9yIHRoZSBpbnB1dCBpbWUgQVBJLiBPbmx5IGluamVjdGVkIGludG8gdGhlCi8vIHY4IGNvbnRleHRzIGZvciBleHRlbnNpb25zIHdoaWNoIGhhdmUgcGVybWlzc2lvbiBmb3IgdGhlIEFQSS4KCnZhciBiaW5kaW5nID0gYXBpQnJpZGdlIHx8IHJlcXVpcmUoJ2JpbmRpbmcnKS5CaW5kaW5nLmNyZWF0ZSgnaW5wdXQuaW1lJyk7CnZhciBhcHBXaW5kb3dOYXRpdmVzID0gcmVxdWlyZU5hdGl2ZSgnYXBwX3dpbmRvd19uYXRpdmVzJyk7CnZhciByZWdpc3RlckFyZ3VtZW50TWFzc2FnZXIgPSBiaW5kaW5nVXRpbCA/CiAgICAkRnVuY3Rpb24uYmluZChiaW5kaW5nVXRpbC5yZWdpc3RlckV2ZW50QXJndW1lbnRNYXNzYWdlciwgYmluZGluZ1V0aWwpIDoKICAgIHJlcXVpcmUoJ2V2ZW50X2JpbmRpbmdzJykucmVnaXN0ZXJBcmd1bWVudE1hc3NhZ2VyOwoKLy8gVE9ETyhjcmJ1Zy5jb20vNzMzODI1KTogVGhlc2UgYmluZGluZ3MgaGF2ZSBzb21lIGlzc3Vlcy4KCnZhciBpbnB1dEltZTsKcmVnaXN0ZXJBcmd1bWVudE1hc3NhZ2VyKCdpbnB1dC5pbWUub25LZXlFdmVudCcsCiAgICAgICAgICAgICAgICAgICAgICAgICBmdW5jdGlvbihhcmdzLCBkaXNwYXRjaCkgewogIHZhciBrZXlEYXRhID0gYXJnc1sxXTsKICB2YXIgcmVzdWx0ID0gZmFsc2U7CiAgdHJ5IHsKICAgIC8vIGRpc3BhdGNoKCkgaXMgd2VpcmQgLSBpdCByZXR1cm5zIGFuIG9iamVjdCB7cmVzdWx0czogYXJyYXk8cmVzdWx0cz59IGlmZgogICAgLy8gdGhlcmUgaXMgYXQgbGVhc3Qgb25lIHJlc3VsdCB2YWx1ZSB0aGF0ICE9PSB1bmRlZmluZWQuIFNpbmNlIG9uS2V5RXZlbnQKICAgIC8vIGhhcyBhIG1heGltdW0gb2Ygb25lIGxpc3RlbmVyLCB3ZSBrbm93IHRoYXQgYW55IHJlc3VsdCB3ZSBmaW5kIGlzIHRoZSBvbmUKICAgIC8vIHdlJ3JlIGludGVyZXN0ZWQgaW4uCiAgICB2YXIgZGlzcGF0Y2hSZXN1bHQgPSBkaXNwYXRjaChhcmdzKTsKICAgIGlmIChkaXNwYXRjaFJlc3VsdCAmJiBkaXNwYXRjaFJlc3VsdC5yZXN1bHRzKQogICAgICByZXN1bHQgPSBkaXNwYXRjaFJlc3VsdC5yZXN1bHRzWzBdOwogIH0gY2F0Y2ggKGUpIHsKICAgIGNvbnNvbGUuZXJyb3IoJ0Vycm9yIGluIGV2ZW50IGhhbmRsZXIgZm9yIG9uS2V5RXZlbnQ6ICcgKyBlLnN0YWNrKTsKICB9CiAgaWYgKCFpbnB1dEltZS5vbktleUV2ZW50LmFzeW5jKQogICAgaW5wdXRJbWUua2V5RXZlbnRIYW5kbGVkKGtleURhdGEucmVxdWVzdElkLCByZXN1bHQpOwp9KTsKCmJpbmRpbmcucmVnaXN0ZXJDdXN0b21Ib29rKGZ1bmN0aW9uKGFwaSkgewogaW5wdXRJbWUgPSBhcGkuY29tcGlsZWRBcGk7CgogIHZhciBvcmlnaW5hbEFkZExpc3RlbmVyID0gaW5wdXRJbWUub25LZXlFdmVudC5hZGRMaXN0ZW5lcjsKICBpbnB1dEltZS5vbktleUV2ZW50LmFkZExpc3RlbmVyID0gZnVuY3Rpb24oY2IsIG9wdF9leHRyYUluZm8pIHsKICAgIGlucHV0SW1lLm9uS2V5RXZlbnQuYXN5bmMgPSBmYWxzZTsKICAgIGlmIChvcHRfZXh0cmFJbmZvIGluc3RhbmNlb2YgQXJyYXkpIHsKICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBvcHRfZXh0cmFJbmZvLmxlbmd0aDsgKytpKSB7CiAgICAgICAgaWYgKG9wdF9leHRyYUluZm9baV0gPT0gJ2FzeW5jJykgewogICAgICAgICAgaW5wdXRJbWUub25LZXlFdmVudC5hc3luYyA9IHRydWU7CiAgICAgICAgfQogICAgICB9CiAgICB9CiAgICAkRnVuY3Rpb24uY2FsbChvcmlnaW5hbEFkZExpc3RlbmVyLCB0aGlzLCBjYik7CiAgfTsKCiAgYXBpLmFwaUZ1bmN0aW9ucy5zZXRDdXN0b21DYWxsYmFjaygnY3JlYXRlV2luZG93JywKICAgICAgZnVuY3Rpb24obmFtZSwgcmVxdWVzdCwgY2FsbGJhY2ssIHdpbmRvd1BhcmFtcykgewogICAgaWYgKCFjYWxsYmFjaykgewogICAgICByZXR1cm47CiAgICB9CiAgICB2YXIgdmlldzsKICAgIGlmICh3aW5kb3dQYXJhbXMgJiYgd2luZG93UGFyYW1zLmZyYW1lSWQpIHsKICAgICAgdmlldyA9IGFwcFdpbmRvd05hdGl2ZXMuR2V0RnJhbWUoCiAgICAgICAgICB3aW5kb3dQYXJhbXMuZnJhbWVJZCwgZmFsc2UgLyogbm90aWZ5QnJvd3NlciAqLyk7CiAgICAgIHZpZXcuaWQgPSB3aW5kb3dQYXJhbXMuZnJhbWVJZDsKICAgIH0KICAgIGNhbGxiYWNrKHZpZXcpOwogIH0pOwp9KTsKCmlmICghYXBpQnJpZGdlKQogIGV4cG9ydHMuJHNldCgnYmluZGluZycsIGJpbmRpbmcuZ2VuZXJhdGUoKSk7Ci8vIENvcHlyaWdodCAoYykgMjAxMiBUaGUgQ2hyb21pdW0gQXV0aG9ycy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KLy8gVXNlIG9mIHRoaXMgc291cmNlIGNvZGUgaXMgZ292ZXJuZWQgYnkgYSBCU0Qtc3R5bGUgbGljZW5zZSB0aGF0IGNhbiBiZQovLyBmb3VuZCBpbiB0aGUgTElDRU5TRSBmaWxlLgoKLy8gQ3VzdG9tIGJpbmRpbmcgZm9yIHRoZSBNZWRpYSBHYWxsZXJ5IEFQSS4KCnZhciBiaW5kaW5nID0gYXBpQnJpZGdlIHx8IHJlcXVpcmUoJ2JpbmRpbmcnKS5CaW5kaW5nLmNyZWF0ZSgnbWVkaWFHYWxsZXJpZXMnKTsKdmFyIGJsb2JOYXRpdmVzID0gcmVxdWlyZU5hdGl2ZSgnYmxvYl9uYXRpdmVzJyk7CnZhciBtZWRpYUdhbGxlcmllc05hdGl2ZXMgPSByZXF1aXJlTmF0aXZlKCdtZWRpYUdhbGxlcmllcycpOwp2YXIgc2VuZFJlcXVlc3QgPSBiaW5kaW5nVXRpbCA/CiAgICAkRnVuY3Rpb24uYmluZChiaW5kaW5nVXRpbC5zZW5kUmVxdWVzdCwgYmluZGluZ1V0aWwpIDoKICAgIHJlcXVpcmUoJ3NlbmRSZXF1ZXN0Jykuc2VuZFJlcXVlc3Q7Cgp2YXIgYmxvYnNBd2FpdGluZ01ldGFkYXRhID0ge307CnZhciBtZWRpYUdhbGxlcmllc01ldGFkYXRhID0ge307CgpmdW5jdGlvbiBjcmVhdGVGaWxlU3lzdGVtT2JqZWN0c0FuZFVwZGF0ZU1ldGFkYXRhKHJlc3BvbnNlKSB7CiAgdmFyIHJlc3VsdCA9IFtdOwogIG1lZGlhR2FsbGVyaWVzTWV0YWRhdGEgPSB7fTsgIC8vIENsZWFyIGFueSBwcmV2aW91cyBtZXRhZGF0YS4KICBpZiAocmVzcG9uc2UpIHsKICAgIGZvciAodmFyIGkgPSAwOyBpIDwgcmVzcG9uc2UubGVuZ3RoOyBpKyspIHsKICAgICAgdmFyIGZpbGVzeXN0ZW0gPSBtZWRpYUdhbGxlcmllc05hdGl2ZXMuR2V0TWVkaWFGaWxlU3lzdGVtT2JqZWN0KAogICAgICAgICAgcmVzcG9uc2VbaV0uZnNpZCk7CiAgICAgICRBcnJheS5wdXNoKHJlc3VsdCwgZmlsZXN5c3RlbSk7CiAgICAgIHZhciBtZXRhZGF0YSA9IHJlc3BvbnNlW2ldOwogICAgICBkZWxldGUgbWV0YWRhdGEuZnNpZDsKICAgICAgbWVkaWFHYWxsZXJpZXNNZXRhZGF0YVtmaWxlc3lzdGVtLm5hbWVdID0gbWV0YWRhdGE7CiAgICB9CiAgfQogIHJldHVybiByZXN1bHQ7Cn0KCmJpbmRpbmcucmVnaXN0ZXJDdXN0b21Ib29rKGZ1bmN0aW9uKGJpbmRpbmdzQVBJLCBleHRlbnNpb25JZCkgewogIHZhciBhcGlGdW5jdGlvbnMgPSBiaW5kaW5nc0FQSS5hcGlGdW5jdGlvbnM7CgogIC8vIGdldE1lZGlhRmlsZVN5c3RlbXMgYW5kIGFkZFVzZXJTZWxlY3RlZEZvbGRlciB1c2UgYSBjdXN0b20gY2FsbGJhY2sgc28gdGhhdAogIC8vIHRoZXkgY2FuIGluc3RhbnRpYXRlIGFuZCByZXR1cm4gYW4gYXJyYXkgb2YgZmlsZSBzeXN0ZW0gb2JqZWN0cy4KICBhcGlGdW5jdGlvbnMuc2V0Q3VzdG9tQ2FsbGJhY2soJ2dldE1lZGlhRmlsZVN5c3RlbXMnLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmdW5jdGlvbihuYW1lLCByZXF1ZXN0LCBjYWxsYmFjaywgcmVzcG9uc2UpIHsKICAgIHZhciByZXN1bHQgPSBjcmVhdGVGaWxlU3lzdGVtT2JqZWN0c0FuZFVwZGF0ZU1ldGFkYXRhKHJlc3BvbnNlKTsKICAgIGlmIChjYWxsYmFjaykKICAgICAgY2FsbGJhY2socmVzdWx0KTsKICB9KTsKCiAgYXBpRnVuY3Rpb25zLnNldEN1c3RvbUNhbGxiYWNrKCdhZGRVc2VyU2VsZWN0ZWRGb2xkZXInLAogICAgICBmdW5jdGlvbihuYW1lLCByZXF1ZXN0LCBjYWxsYmFjaywgcmVzcG9uc2UpIHsKICAgIHZhciBmaWxlU3lzdGVtcyA9IFtdOwogICAgdmFyIHNlbGVjdGVkRmlsZVN5c3RlbU5hbWUgPSAiIjsKICAgIGlmIChyZXNwb25zZSAmJiAnbWVkaWFGaWxlU3lzdGVtcycgaW4gcmVzcG9uc2UgJiYKICAgICAgICAnc2VsZWN0ZWRGaWxlU3lzdGVtSW5kZXgnIGluIHJlc3BvbnNlKSB7CiAgICAgIGZpbGVTeXN0ZW1zID0gY3JlYXRlRmlsZVN5c3RlbU9iamVjdHNBbmRVcGRhdGVNZXRhZGF0YSgKICAgICAgICAgIHJlc3BvbnNlWydtZWRpYUZpbGVTeXN0ZW1zJ10pOwogICAgICB2YXIgc2VsZWN0ZWRGaWxlU3lzdGVtSW5kZXggPSByZXNwb25zZVsnc2VsZWN0ZWRGaWxlU3lzdGVtSW5kZXgnXTsKICAgICAgaWYgKHNlbGVjdGVkRmlsZVN5c3RlbUluZGV4ID49IDApIHsKICAgICAgICBzZWxlY3RlZEZpbGVTeXN0ZW1OYW1lID0gZmlsZVN5c3RlbXNbc2VsZWN0ZWRGaWxlU3lzdGVtSW5kZXhdLm5hbWU7CiAgICAgIH0KICAgIH0KICAgIGlmIChjYWxsYmFjaykKICAgICAgY2FsbGJhY2soZmlsZVN5c3RlbXMsIHNlbGVjdGVkRmlsZVN5c3RlbU5hbWUpOwogIH0pOwoKICBhcGlGdW5jdGlvbnMuc2V0SGFuZGxlUmVxdWVzdCgnZ2V0TWVkaWFGaWxlU3lzdGVtTWV0YWRhdGEnLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZ1bmN0aW9uKGZpbGVzeXN0ZW0pIHsKICAgIGlmIChmaWxlc3lzdGVtICYmIGZpbGVzeXN0ZW0ubmFtZSAmJgogICAgICAgIGZpbGVzeXN0ZW0ubmFtZSBpbiBtZWRpYUdhbGxlcmllc01ldGFkYXRhKSB7CiAgICAgIHJldHVybiBtZWRpYUdhbGxlcmllc01ldGFkYXRhW2ZpbGVzeXN0ZW0ubmFtZV07CiAgICB9CiAgICByZXR1cm4gewogICAgICAnbmFtZSc6ICcnLAogICAgICAnZ2FsbGVyeUlkJzogJycsCiAgICAgICdpc1JlbW92YWJsZSc6IGZhbHNlLAogICAgICAnaXNNZWRpYURldmljZSc6IGZhbHNlLAogICAgICAnaXNBdmFpbGFibGUnOiBmYWxzZSwKICAgIH07CiAgfSk7CgogIGZ1bmN0aW9uIGdldE1ldGFkYXRhQ2FsbGJhY2sodXVpZCwgbmFtZSwgcmVxdWVzdCwgY2FsbGJhY2ssIHJlc3BvbnNlKSB7CiAgICBpZiAocmVzcG9uc2UgJiYgcmVzcG9uc2UuYXR0YWNoZWRJbWFnZXNCbG9iSW5mbykgewogICAgICBmb3IgKHZhciBpID0gMDsgaSA8IHJlc3BvbnNlLmF0dGFjaGVkSW1hZ2VzQmxvYkluZm8ubGVuZ3RoOyBpKyspIHsKICAgICAgICB2YXIgYmxvYkluZm8gPSByZXNwb25zZS5hdHRhY2hlZEltYWdlc0Jsb2JJbmZvW2ldOwogICAgICAgIHZhciBibG9iID0gYmxvYk5hdGl2ZXMuVGFrZUJyb3dzZXJQcm9jZXNzQmxvYigKICAgICAgICAgICAgYmxvYkluZm8uYmxvYlVVSUQsIGJsb2JJbmZvLnR5cGUsIGJsb2JJbmZvLnNpemUpOwogICAgICAgIHJlc3BvbnNlLm1ldGFkYXRhLmF0dGFjaGVkSW1hZ2VzLnB1c2goYmxvYik7CiAgICAgIH0KICAgIH0KCiAgICBpZiAoY2FsbGJhY2spCiAgICAgIGNhbGxiYWNrKHJlc3BvbnNlID8gcmVzcG9uc2UubWV0YWRhdGEgOiBudWxsKTsKCiAgICBkZWxldGUgYmxvYnNBd2FpdGluZ01ldGFkYXRhW3V1aWRdOwogIH0KCiAgYXBpRnVuY3Rpb25zLnNldEhhbmRsZVJlcXVlc3QoJ2dldE1ldGFkYXRhJywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmdW5jdGlvbihtZWRpYUZpbGUsIG9wdGlvbnMsIGNhbGxiYWNrKSB7CiAgICB2YXIgYmxvYlV1aWQgPSBibG9iTmF0aXZlcy5HZXRCbG9iVXVpZChtZWRpYUZpbGUpCiAgICAvLyBTdG9yZSB0aGUgYmxvYiBpbiBhIGdsb2JhbCBvYmplY3QgdG8ga2VlcCBpdHMgcmVmY291bnQgbm9uemVybyAtLSB0aGlzCiAgICAvLyBwcmV2ZW50cyB0aGUgb2JqZWN0IGZyb20gYmVpbmcgZ2FyYmFnZSBjb2xsZWN0ZWQgYmVmb3JlIGFueSBtZXRhZGF0YQogICAgLy8gcGFyc2luZyBnZXRzIHRvIG9jY3VyIChzZWUgY3JidWcuY29tLzQxNTc5MikuCiAgICBibG9ic0F3YWl0aW5nTWV0YWRhdGFbYmxvYlV1aWRdID0gbWVkaWFGaWxlOwoKICAgIHZhciBvcHRBcmdzID0gewogICAgICBfX3Byb3RvX186IG51bGwsCiAgICAgIGN1c3RvbUNhbGxiYWNrOiAkRnVuY3Rpb24uYmluZChnZXRNZXRhZGF0YUNhbGxiYWNrLCBudWxsLCBibG9iVXVpZCksCiAgICB9OwoKICAgIHNlbmRSZXF1ZXN0KCdtZWRpYUdhbGxlcmllcy5nZXRNZXRhZGF0YScsIFtibG9iVXVpZCwgb3B0aW9ucywgY2FsbGJhY2tdLAogICAgICAgICAgICAgICAgYmluZGluZ1V0aWwgPyB1bmRlZmluZWQgOiB0aGlzLmRlZmluaXRpb24ucGFyYW1ldGVycywgb3B0QXJncyk7CiAgfSk7Cn0pOwoKaWYgKCFhcGlCcmlkZ2UpCiAgZXhwb3J0cy4kc2V0KCdiaW5kaW5nJywgYmluZGluZy5nZW5lcmF0ZSgpKTsKLy8gQ29weXJpZ2h0IDIwMTMgVGhlIENocm9taXVtIEF1dGhvcnMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCi8vIFVzZSBvZiB0aGlzIHNvdXJjZSBjb2RlIGlzIGdvdmVybmVkIGJ5IGEgQlNELXN0eWxlIGxpY2Vuc2UgdGhhdCBjYW4gYmUKLy8gZm91bmQgaW4gdGhlIExJQ0VOU0UgZmlsZS4KCi8vIEN1c3RvbSBiaW5kaW5ncyBmb3IgdGhlIG5vdGlmaWNhdGlvbnMgQVBJLgovLwp2YXIgYmluZGluZyA9IGFwaUJyaWRnZSB8fCByZXF1aXJlKCdiaW5kaW5nJykuQmluZGluZy5jcmVhdGUoJ25vdGlmaWNhdGlvbnMnKTsKCnZhciBzZW5kUmVxdWVzdCA9IGJpbmRpbmdVdGlsID8KICAgICRGdW5jdGlvbi5iaW5kKGJpbmRpbmdVdGlsLnNlbmRSZXF1ZXN0LCBiaW5kaW5nVXRpbCkgOgogICAgcmVxdWlyZSgnc2VuZFJlcXVlc3QnKS5zZW5kUmVxdWVzdDsKdmFyIGV4Y2VwdGlvbkhhbmRsZXIgPSByZXF1aXJlKCd1bmNhdWdodF9leGNlcHRpb25faGFuZGxlcicpOwp2YXIgaW1hZ2VVdGlsID0gcmVxdWlyZSgnaW1hZ2VVdGlsJyk7CnZhciBub3RpZmljYXRpb25zUHJpdmF0ZSA9IHJlcXVpcmVOYXRpdmUoJ25vdGlmaWNhdGlvbnNfcHJpdmF0ZScpOwoKdmFyIGpzTGFzdEVycm9yID0gYmluZGluZ1V0aWwgPyB1bmRlZmluZWQgOiByZXF1aXJlKCdsYXN0RXJyb3InKTsKZnVuY3Rpb24gcnVuQ2FsbGJhY2tXaXRoTGFzdEVycm9yKG5hbWUsIG1lc3NhZ2UsIHN0YWNrLCBjYWxsYmFjaywgYXJncykgewogIGlmIChiaW5kaW5nVXRpbCkgewogICAgYmluZGluZ1V0aWwucnVuQ2FsbGJhY2tXaXRoTGFzdEVycm9yKG1lc3NhZ2UsIGZ1bmN0aW9uKCkgewogICAgICAkRnVuY3Rpb24uYXBwbHkoY2FsbGJhY2ssIG51bGwsIGFyZ3MpOwogICAgfSk7CiAgfSBlbHNlIHsKICAgIGpzTGFzdEVycm9yLnJ1bihuYW1lLCBtZXNzYWdlLCBzdGFjaywgY2FsbGJhY2ssIGFyZ3MpOwogIH0KfQoKZnVuY3Rpb24gaW1hZ2VEYXRhU2V0dGVyKGNvbnRleHQsIGtleSkgewogIHZhciBmID0gZnVuY3Rpb24odmFsKSB7CiAgICB0aGlzW2tleV0gPSB2YWw7CiAgfTsKICByZXR1cm4gJEZ1bmN0aW9uLmJpbmQoZiwgY29udGV4dCk7Cn0KCi8vIEEgVVJMIFNwZWMgaXMgYW4gb2JqZWN0IHdpdGggdGhlIGZvbGxvd2luZyBrZXlzOgovLyAgcGF0aDogVGhlIHJlc291cmNlIHRvIGJlIGRvd25sb2FkZWQuCi8vICB3aWR0aDogKG9wdGlvbmFsKSBUaGUgbWF4aW11bSB3aWR0aCBvZiB0aGUgaW1hZ2UgdG8gYmUgZG93bmxvYWRlZCBpbiBkZXZpY2UKLy8gICAgICAgICBwaXhlbHMuCi8vICBoZWlnaHQ6IChvcHRpb25hbCkgVGhlIG1heGltdW0gaGVpZ2h0IG9mIHRoZSBpbWFnZSB0byBiZSBkb3dubG9hZGVkIGluCi8vICAgICAgICAgIGRldmljZSBwaXhlbHMuCi8vICBjYWxsYmFjazogQSBmdW5jdGlvbiB0byBiZSBjYWxsZWQgd2hlbiB0aGUgVVJMIGlzIGNvbXBsZXRlLiBJdAovLyAgICBzaG91bGQgYWNjZXB0IGFuIEltYWdlRGF0YSBvYmplY3QgYW5kIHNldCB0aGUgYXBwcm9wcmlhdGUKLy8gICAgZmllbGQgaW4gfG5vdGlmaWNhdGlvbkRldGFpbHN8LgpmdW5jdGlvbiBnZXRVcmxTcGVjcyhpbWFnZVNpemVzLCBub3RpZmljYXRpb25EZXRhaWxzKSB7CiAgdmFyIHVybFNwZWNzID0gW107CgogIC8vIHxpY29uVXJsfCBtaWdodCBiZSBvcHRpb25hbCBmb3Igbm90aWZpY2F0aW9uIHVwZGF0ZXMuCiAgaWYgKG5vdGlmaWNhdGlvbkRldGFpbHMuaWNvblVybCkgewogICAgJEFycmF5LnB1c2godXJsU3BlY3MsIHsKICAgICAgcGF0aDogbm90aWZpY2F0aW9uRGV0YWlscy5pY29uVXJsLAogICAgICB3aWR0aDogaW1hZ2VTaXplcy5pY29uLndpZHRoICogaW1hZ2VTaXplcy5zY2FsZUZhY3RvciwKICAgICAgaGVpZ2h0OiBpbWFnZVNpemVzLmljb24uaGVpZ2h0ICogaW1hZ2VTaXplcy5zY2FsZUZhY3RvciwKICAgICAgY2FsbGJhY2s6IGltYWdlRGF0YVNldHRlcihub3RpZmljYXRpb25EZXRhaWxzLCAnaWNvbkJpdG1hcCcpCiAgICB9KTsKICB9CgogIC8vIHxhcHBJY29uTWFza1VybHwgaXMgb3B0aW9uYWwuCiAgaWYgKG5vdGlmaWNhdGlvbkRldGFpbHMuYXBwSWNvbk1hc2tVcmwpIHsKICAgICRBcnJheS5wdXNoKHVybFNwZWNzLCB7CiAgICAgIHBhdGg6IG5vdGlmaWNhdGlvbkRldGFpbHMuYXBwSWNvbk1hc2tVcmwsCiAgICAgIHdpZHRoOiBpbWFnZVNpemVzLmFwcEljb25NYXNrLndpZHRoICogaW1hZ2VTaXplcy5zY2FsZUZhY3RvciwKICAgICAgaGVpZ2h0OiBpbWFnZVNpemVzLmFwcEljb25NYXNrLmhlaWdodCAqIGltYWdlU2l6ZXMuc2NhbGVGYWN0b3IsCiAgICAgIGNhbGxiYWNrOiBpbWFnZURhdGFTZXR0ZXIobm90aWZpY2F0aW9uRGV0YWlscywgJ2FwcEljb25NYXNrQml0bWFwJykKICAgIH0pOwogIH0KCiAgLy8gfGltYWdlVXJsfCBpcyBvcHRpb25hbC4KICBpZiAobm90aWZpY2F0aW9uRGV0YWlscy5pbWFnZVVybCkgewogICAgJEFycmF5LnB1c2godXJsU3BlY3MsIHsKICAgICAgcGF0aDogbm90aWZpY2F0aW9uRGV0YWlscy5pbWFnZVVybCwKICAgICAgd2lkdGg6IGltYWdlU2l6ZXMuaW1hZ2Uud2lkdGggKiBpbWFnZVNpemVzLnNjYWxlRmFjdG9yLAogICAgICBoZWlnaHQ6IGltYWdlU2l6ZXMuaW1hZ2UuaGVpZ2h0ICogaW1hZ2VTaXplcy5zY2FsZUZhY3RvciwKICAgICAgY2FsbGJhY2s6IGltYWdlRGF0YVNldHRlcihub3RpZmljYXRpb25EZXRhaWxzLCAnaW1hZ2VCaXRtYXAnKQogICAgfSk7CiAgfQoKICAvLyBFYWNoIGJ1dHRvbiBoYXMgYW4gb3B0aW9uYWwgaWNvbi4KICB2YXIgYnV0dG9uTGlzdCA9IG5vdGlmaWNhdGlvbkRldGFpbHMuYnV0dG9uczsKICBpZiAoYnV0dG9uTGlzdCAmJiB0eXBlb2YgYnV0dG9uTGlzdC5sZW5ndGggPT09ICdudW1iZXInKSB7CiAgICB2YXIgbnVtQnV0dG9ucyA9IGJ1dHRvbkxpc3QubGVuZ3RoOwogICAgZm9yICh2YXIgaSA9IDA7IGkgPCBudW1CdXR0b25zOyBpKyspIHsKICAgICAgaWYgKGJ1dHRvbkxpc3RbaV0uaWNvblVybCkgewogICAgICAgICRBcnJheS5wdXNoKHVybFNwZWNzLCB7CiAgICAgICAgICBwYXRoOiBidXR0b25MaXN0W2ldLmljb25VcmwsCiAgICAgICAgICB3aWR0aDogaW1hZ2VTaXplcy5idXR0b25JY29uLndpZHRoICogaW1hZ2VTaXplcy5zY2FsZUZhY3RvciwKICAgICAgICAgIGhlaWdodDogaW1hZ2VTaXplcy5idXR0b25JY29uLmhlaWdodCAqIGltYWdlU2l6ZXMuc2NhbGVGYWN0b3IsCiAgICAgICAgICBjYWxsYmFjazogaW1hZ2VEYXRhU2V0dGVyKGJ1dHRvbkxpc3RbaV0sICdpY29uQml0bWFwJykKICAgICAgICB9KTsKICAgICAgfQogICAgfQogIH0KCiAgcmV0dXJuIHVybFNwZWNzOwp9CgpmdW5jdGlvbiByZXBsYWNlTm90aWZpY2F0aW9uT3B0aW9uVVJMcyhub3RpZmljYXRpb25fZGV0YWlscywgY2FsbGJhY2spIHsKICB2YXIgaW1hZ2VTaXplcyA9IG5vdGlmaWNhdGlvbnNQcml2YXRlLkdldE5vdGlmaWNhdGlvbkltYWdlU2l6ZXMoKTsKICB2YXIgdXJsX3NwZWNzID0gZ2V0VXJsU3BlY3MoaW1hZ2VTaXplcywgbm90aWZpY2F0aW9uX2RldGFpbHMpOwogIGlmICghdXJsX3NwZWNzLmxlbmd0aCkgewogICAgY2FsbGJhY2sodHJ1ZSk7CiAgICByZXR1cm47CiAgfQoKICB2YXIgZXJyb3JzID0gMDsKCiAgaW1hZ2VVdGlsLmxvYWRBbGxJbWFnZXModXJsX3NwZWNzLCB7CiAgICBvbmVycm9yOiBmdW5jdGlvbihpbmRleCkgewogICAgICBlcnJvcnMrKzsKICAgIH0sCiAgICBvbmNvbXBsZXRlOiBmdW5jdGlvbihpbWFnZURhdGEpIHsKICAgICAgaWYgKGVycm9ycyA+IDApIHsKICAgICAgICBjYWxsYmFjayhmYWxzZSk7CiAgICAgICAgcmV0dXJuOwogICAgICB9CiAgICAgIGZvciAodmFyIGluZGV4ID0gMDsgaW5kZXggPCB1cmxfc3BlY3MubGVuZ3RoOyBpbmRleCsrKSB7CiAgICAgICAgdmFyIHVybF9zcGVjID0gdXJsX3NwZWNzW2luZGV4XTsKICAgICAgICB1cmxfc3BlYy5jYWxsYmFjayhpbWFnZURhdGFbaW5kZXhdKTsKICAgICAgfQogICAgICBjYWxsYmFjayh0cnVlKTsKICAgIH0KICB9KTsKfQoKZnVuY3Rpb24gZ2VuSGFuZGxlKG5hbWUsIGZhaWx1cmVfZnVuY3Rpb24pIHsKICByZXR1cm4gZnVuY3Rpb24oaWQsIGlucHV0X25vdGlmaWNhdGlvbl9kZXRhaWxzLCBjYWxsYmFjaykgewogICAgLy8gVE9ETyhkZXdpdHRqKTogUmVtb3ZlIHRoaXMgaGFjay4gVGhpcyBpcyB1c2VkIGFzIGEgd2F5IHRvIGRlZXAKICAgIC8vIGNvcHkgYSBjb21wbGV4IEpTT04gb2JqZWN0LgogICAgdmFyIG5vdGlmaWNhdGlvbl9kZXRhaWxzID0gJEpTT04ucGFyc2UoCiAgICAgICAgJEpTT04uc3RyaW5naWZ5KGlucHV0X25vdGlmaWNhdGlvbl9kZXRhaWxzKSk7CiAgICB2YXIgdGhhdCA9IHRoaXM7CiAgICB2YXIgc3RhY2sgPSBleGNlcHRpb25IYW5kbGVyLmdldEV4dGVuc2lvblN0YWNrVHJhY2UoKTsKICAgIHJlcGxhY2VOb3RpZmljYXRpb25PcHRpb25VUkxzKG5vdGlmaWNhdGlvbl9kZXRhaWxzLCBmdW5jdGlvbihzdWNjZXNzKSB7CiAgICAgIGlmIChzdWNjZXNzKSB7CiAgICAgICAgc2VuZFJlcXVlc3QoCiAgICAgICAgICAgIG5hbWUsIFtpZCwgbm90aWZpY2F0aW9uX2RldGFpbHMsIGNhbGxiYWNrXSwKICAgICAgICAgICAgYmluZGluZ1V0aWwgPyB1bmRlZmluZWQgOiB0aGF0LmRlZmluaXRpb24ucGFyYW1ldGVycywKICAgICAgICAgICAgYmluZGluZ1V0aWwgPyB1bmRlZmluZWQgOiB7X19wcm90b19fOiBudWxsLCBzdGFjazogc3RhY2t9KTsKICAgICAgICByZXR1cm47CiAgICAgIH0KICAgICAgcnVuQ2FsbGJhY2tXaXRoTGFzdEVycm9yKAogICAgICAgICAgbmFtZSwgJ1VuYWJsZSB0byBkb3dubG9hZCBhbGwgc3BlY2lmaWVkIGltYWdlcy4nLAogICAgICAgICAgc3RhY2ssIGZhaWx1cmVfZnVuY3Rpb24sIFtjYWxsYmFjayB8fCBmdW5jdGlvbigpIHt9LCBpZF0pOwogICAgfSk7CiAgfTsKfQoKdmFyIGhhbmRsZUNyZWF0ZSA9IGdlbkhhbmRsZSgnbm90aWZpY2F0aW9ucy5jcmVhdGUnLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZ1bmN0aW9uKGNhbGxiYWNrLCBpZCkgeyBjYWxsYmFjayhpZCk7IH0pOwp2YXIgaGFuZGxlVXBkYXRlID0gZ2VuSGFuZGxlKCdub3RpZmljYXRpb25zLnVwZGF0ZScsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZnVuY3Rpb24oY2FsbGJhY2ssIGlkKSB7IGNhbGxiYWNrKGZhbHNlKTsgfSk7Cgp2YXIgbm90aWZpY2F0aW9uc0N1c3RvbUhvb2sgPSBmdW5jdGlvbihiaW5kaW5nc0FQSSwgZXh0ZW5zaW9uSWQpIHsKICB2YXIgYXBpRnVuY3Rpb25zID0gYmluZGluZ3NBUEkuYXBpRnVuY3Rpb25zOwogIGFwaUZ1bmN0aW9ucy5zZXRIYW5kbGVSZXF1ZXN0KCdjcmVhdGUnLCBoYW5kbGVDcmVhdGUpOwogIGFwaUZ1bmN0aW9ucy5zZXRIYW5kbGVSZXF1ZXN0KCd1cGRhdGUnLCBoYW5kbGVVcGRhdGUpOwp9OwoKYmluZGluZy5yZWdpc3RlckN1c3RvbUhvb2sobm90aWZpY2F0aW9uc0N1c3RvbUhvb2spOwoKaWYgKCFhcGlCcmlkZ2UpCiAgZXhwb3J0cy4kc2V0KCdiaW5kaW5nJywgYmluZGluZy5nZW5lcmF0ZSgpKTsKLy8gQ29weXJpZ2h0IChjKSAyMDEyIFRoZSBDaHJvbWl1bSBBdXRob3JzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgovLyBVc2Ugb2YgdGhpcyBzb3VyY2UgY29kZSBpcyBnb3Zlcm5lZCBieSBhIEJTRC1zdHlsZSBsaWNlbnNlIHRoYXQgY2FuIGJlCi8vIGZvdW5kIGluIHRoZSBMSUNFTlNFIGZpbGUuCgovLyBDdXN0b20gYmluZGluZyBmb3IgdGhlIG9tbmlib3ggQVBJLiBPbmx5IGluamVjdGVkIGludG8gdGhlIHY4IGNvbnRleHRzCi8vIGZvciBleHRlbnNpb25zIHdoaWNoIGhhdmUgcGVybWlzc2lvbiBmb3IgdGhlIG9tbmlib3ggQVBJLgoKdmFyIGJpbmRpbmcgPSBhcGlCcmlkZ2UgfHwgcmVxdWlyZSgnYmluZGluZycpLkJpbmRpbmcuY3JlYXRlKCdvbW5pYm94Jyk7Cgp2YXIgcmVnaXN0ZXJBcmd1bWVudE1hc3NhZ2VyID0gYmluZGluZ1V0aWwgPwogICAgJEZ1bmN0aW9uLmJpbmQoYmluZGluZ1V0aWwucmVnaXN0ZXJFdmVudEFyZ3VtZW50TWFzc2FnZXIsIGJpbmRpbmdVdGlsKSA6CiAgICByZXF1aXJlKCdldmVudF9iaW5kaW5ncycpLnJlZ2lzdGVyQXJndW1lbnRNYXNzYWdlcjsKCnZhciBzZW5kUmVxdWVzdCA9IGJpbmRpbmdVdGlsID8KICAgICRGdW5jdGlvbi5iaW5kKGJpbmRpbmdVdGlsLnNlbmRSZXF1ZXN0LCBiaW5kaW5nVXRpbCkgOgogICAgcmVxdWlyZSgnc2VuZFJlcXVlc3QnKS5zZW5kUmVxdWVzdDsKCi8vIFJlbW92ZSBpbnZhbGlkIGNoYXJhY3RlcnMgZnJvbSB8dGV4dHwgc28gdGhhdCBpdCBpcyBzdWl0YWJsZSB0byB1c2UKLy8gZm9yIHxBdXRvY29tcGxldGVNYXRjaDo6Y29udGVudHN8LgpmdW5jdGlvbiBzYW5pdGl6ZVN0cmluZyh0ZXh0LCBzaG91bGRUcmltKSB7CiAgLy8gTk9URTogVGhpcyBsb2dpYyBtaXJyb3JzIHxBdXRvY29tcGxldGVNYXRjaDo6U2FuaXRpemVTdHJpbmcoKXwuCiAgLy8gMHgyMDI4ID0gbGluZSBzZXBhcmF0b3I7IDB4MjAyOSA9IHBhcmFncmFwaCBzZXBhcmF0b3IuCiAgdmFyIGtSZW1vdmVDaGFycyA9IC8oXHJ8XG58XHR8XHUyMDI4fFx1MjAyOSkvZ207CiAgaWYgKHNob3VsZFRyaW0pCiAgICB0ZXh0ID0gdGV4dC50cmltTGVmdCgpOwogIHJldHVybiB0ZXh0LnJlcGxhY2Uoa1JlbW92ZUNoYXJzLCAnJyk7Cn0KCi8vIFBhcnNlcyB0aGUgeG1sIHN5bnRheCBzdXBwb3J0ZWQgYnkgb21uaWJveCBzdWdnZXN0aW9uIHJlc3VsdHMuIFJldHVybnMgYW4KLy8gb2JqZWN0IHdpdGggdHdvIHByb3BlcnRpZXM6ICdkZXNjcmlwdGlvbicsIHdoaWNoIGlzIGp1c3QgdGhlIHRleHQgY29udGVudCwKLy8gYW5kICdkZXNjcmlwdGlvblN0eWxlcycsIHdoaWNoIGlzIGFuIGFycmF5IG9mIHN0eWxlIG9iamVjdHMgaW4gYSBmb3JtYXQKLy8gdW5kZXJzdG9vZCBieSB0aGUgQysrIGJhY2tlbmQuCmZ1bmN0aW9uIHBhcnNlT21uaWJveERlc2NyaXB0aW9uKGlucHV0KSB7CiAgdmFyIGRvbVBhcnNlciA9IG5ldyBET01QYXJzZXIoKTsKCiAgLy8gVGhlIFhNTCBwYXJzZXIgcmVxdWlyZXMgYSBzaW5nbGUgdG9wLWxldmVsIGVsZW1lbnQsIGJ1dCB3ZSB3YW50IHRvCiAgLy8gc3VwcG9ydCB0aGluZ3MgbGlrZSAnaGVsbG8sIDxtYXRjaD53b3JsZDwvbWF0Y2g+IScuIFNvIHdlIHdyYXAgdGhlCiAgLy8gcHJvdmlkZWQgdGV4dCBpbiBnZW5lcmF0ZWQgcm9vdCBsZXZlbCBlbGVtZW50LgogIHZhciByb290ID0gZG9tUGFyc2VyLnBhcnNlRnJvbVN0cmluZygKICAgICAgJzxmcmFnbWVudD4nICsgaW5wdXQgKyAnPC9mcmFnbWVudD4nLCAndGV4dC94bWwnKTsKCiAgLy8gRE9NUGFyc2VyIGhhcyBhIHRlcnJpYmxlIGVycm9yIHJlcG9ydGluZyBmYWNpbGl0eS4gRXJyb3JzIGNvbWUgb3V0IG5lc3RlZAogIC8vIGluc2lkZSB0aGUgcmV0dXJuZWQgZG9jdW1lbnQuCiAgdmFyIGVycm9yID0gcm9vdC5xdWVyeVNlbGVjdG9yKCdwYXJzZXJlcnJvciBkaXYnKTsKICBpZiAoZXJyb3IpIHsKICAgIHRocm93IG5ldyBFcnJvcihlcnJvci50ZXh0Q29udGVudCk7CiAgfQoKICAvLyBPdGhlcndpc2UsIGl0J3MgdmFsaWQsIHNvIGJ1aWxkIHVwIHRoZSByZXN1bHQuCiAgdmFyIHJlc3VsdCA9IHsKICAgIGRlc2NyaXB0aW9uOiAnJywKICAgIGRlc2NyaXB0aW9uU3R5bGVzOiBbXQogIH07CgogIC8vIFJlY3Vyc2l2ZWx5IHdhbGsgdGhlIHRyZWUuCiAgZnVuY3Rpb24gd2Fsayhub2RlKSB7CiAgICBmb3IgKHZhciBpID0gMCwgY2hpbGQ7IGNoaWxkID0gbm9kZS5jaGlsZE5vZGVzW2ldOyBpKyspIHsKICAgICAgLy8gQXBwZW5kIHRleHQgbm9kZXMgdG8gb3VyIGRlc2NyaXB0aW9uLgogICAgICBpZiAoY2hpbGQubm9kZVR5cGUgPT0gTm9kZS5URVhUX05PREUpIHsKICAgICAgICB2YXIgc2hvdWxkVHJpbSA9IHJlc3VsdC5kZXNjcmlwdGlvbi5sZW5ndGggPT0gMDsKICAgICAgICByZXN1bHQuZGVzY3JpcHRpb24gKz0gc2FuaXRpemVTdHJpbmcoY2hpbGQubm9kZVZhbHVlLCBzaG91bGRUcmltKTsKICAgICAgICBjb250aW51ZTsKICAgICAgfQoKICAgICAgLy8gUHJvY2VzcyBhbmQgZGVzY2VuZCBpbnRvIGEgc3Vic2V0IG9mIHJlY29nbml6ZWQgdGFncy4KICAgICAgaWYgKGNoaWxkLm5vZGVUeXBlID09IE5vZGUuRUxFTUVOVF9OT0RFICYmCiAgICAgICAgICAoY2hpbGQubm9kZU5hbWUgPT0gJ2RpbScgfHwgY2hpbGQubm9kZU5hbWUgPT0gJ21hdGNoJyB8fAogICAgICAgICAgIGNoaWxkLm5vZGVOYW1lID09ICd1cmwnKSkgewogICAgICAgIHZhciBzdHlsZSA9IHsKICAgICAgICAgICd0eXBlJzogY2hpbGQubm9kZU5hbWUsCiAgICAgICAgICAnb2Zmc2V0JzogcmVzdWx0LmRlc2NyaXB0aW9uLmxlbmd0aAogICAgICAgIH07CiAgICAgICAgJEFycmF5LnB1c2gocmVzdWx0LmRlc2NyaXB0aW9uU3R5bGVzLCBzdHlsZSk7CiAgICAgICAgd2FsayhjaGlsZCk7CiAgICAgICAgc3R5bGUubGVuZ3RoID0gcmVzdWx0LmRlc2NyaXB0aW9uLmxlbmd0aCAtIHN0eWxlLm9mZnNldDsKICAgICAgICBjb250aW51ZTsKICAgICAgfQoKICAgICAgLy8gRGVzY2VuZCBpbnRvIGFsbCBvdGhlciBub2RlcywgZXZlbiBpZiB0aGV5IGFyZSB1bnJlY29nbml6ZWQsIGZvcgogICAgICAvLyBmb3J3YXJkIGNvbXBhdC4KICAgICAgd2FsayhjaGlsZCk7CiAgICB9CiAgfTsKICB3YWxrKHJvb3QpOwoKICByZXR1cm4gcmVzdWx0Owp9CgpiaW5kaW5nLnJlZ2lzdGVyQ3VzdG9tSG9vayhmdW5jdGlvbihiaW5kaW5nc0FQSSkgewogIHZhciBhcGlGdW5jdGlvbnMgPSBiaW5kaW5nc0FQSS5hcGlGdW5jdGlvbnM7CgogIGFwaUZ1bmN0aW9ucy5zZXRVcGRhdGVBcmd1bWVudHNQcmVWYWxpZGF0ZSgnc2V0RGVmYXVsdFN1Z2dlc3Rpb24nLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmdW5jdGlvbihzdWdnZXN0UmVzdWx0KSB7CiAgICBpZiAoc3VnZ2VzdFJlc3VsdC5jb250ZW50ICE9IHVuZGVmaW5lZCkgeyAgLy8gbnVsbCwgZXRjLgogICAgICB0aHJvdyBuZXcgRXJyb3IoCiAgICAgICAgICAnc2V0RGVmYXVsdFN1Z2dlc3Rpb24gY2Fubm90IGNvbnRhaW4gdGhlICJjb250ZW50IiBmaWVsZCcpOwogICAgfQogICAgcmV0dXJuIFtzdWdnZXN0UmVzdWx0XTsKICB9KTsKCiAgYXBpRnVuY3Rpb25zLnNldEhhbmRsZVJlcXVlc3QoJ3NldERlZmF1bHRTdWdnZXN0aW9uJywgZnVuY3Rpb24oZGV0YWlscykgewogICAgdmFyIHBhcnNlUmVzdWx0ID0gcGFyc2VPbW5pYm94RGVzY3JpcHRpb24oZGV0YWlscy5kZXNjcmlwdGlvbik7CiAgICBzZW5kUmVxdWVzdCgnb21uaWJveC5zZXREZWZhdWx0U3VnZ2VzdGlvbicsIFtwYXJzZVJlc3VsdF0sCiAgICAgICAgICAgICAgICBiaW5kaW5nVXRpbCA/IHVuZGVmaW5lZCA6IHRoaXMuZGVmaW5pdGlvbi5wYXJhbWV0ZXJzLAogICAgICAgICAgICAgICAgdW5kZWZpbmVkKTsKICB9KTsKCiAgYXBpRnVuY3Rpb25zLnNldFVwZGF0ZUFyZ3VtZW50c1Bvc3RWYWxpZGF0ZSgKICAgICAgJ3NlbmRTdWdnZXN0aW9ucycsIGZ1bmN0aW9uKHJlcXVlc3RJZCwgdXNlclN1Z2dlc3Rpb25zKSB7CiAgICB2YXIgc3VnZ2VzdGlvbnMgPSBbXTsKICAgIGZvciAodmFyIGkgPSAwOyBpIDwgdXNlclN1Z2dlc3Rpb25zLmxlbmd0aDsgaSsrKSB7CiAgICAgIHZhciBwYXJzZVJlc3VsdCA9IHBhcnNlT21uaWJveERlc2NyaXB0aW9uKAogICAgICAgICAgdXNlclN1Z2dlc3Rpb25zW2ldLmRlc2NyaXB0aW9uKTsKICAgICAgcGFyc2VSZXN1bHQuY29udGVudCA9IHVzZXJTdWdnZXN0aW9uc1tpXS5jb250ZW50OwogICAgICBwYXJzZVJlc3VsdC5kZWxldGFibGUgPSB1c2VyU3VnZ2VzdGlvbnNbaV0uZGVsZXRhYmxlOwogICAgICAkQXJyYXkucHVzaChzdWdnZXN0aW9ucywgcGFyc2VSZXN1bHQpOwogICAgfQogICAgcmV0dXJuIFtyZXF1ZXN0SWQsIHN1Z2dlc3Rpb25zXTsKICB9KTsKfSk7CgpyZWdpc3RlckFyZ3VtZW50TWFzc2FnZXIoJ29tbmlib3gub25JbnB1dENoYW5nZWQnLCBmdW5jdGlvbihhcmdzLCBkaXNwYXRjaCkgewogIHZhciB0ZXh0ID0gYXJnc1swXTsKICB2YXIgcmVxdWVzdElkID0gYXJnc1sxXTsKICB2YXIgc3VnZ2VzdENhbGxiYWNrID0gZnVuY3Rpb24oc3VnZ2VzdGlvbnMpIHsKICAgIGNocm9tZS5vbW5pYm94LnNlbmRTdWdnZXN0aW9ucyhyZXF1ZXN0SWQsIHN1Z2dlc3Rpb25zKTsKICB9OwogIGRpc3BhdGNoKFt0ZXh0LCBzdWdnZXN0Q2FsbGJhY2tdKTsKfSk7CgppZiAoIWFwaUJyaWRnZSkKICBleHBvcnRzLiRzZXQoJ2JpbmRpbmcnLCBiaW5kaW5nLmdlbmVyYXRlKCkpOwovLyBDb3B5cmlnaHQgKGMpIDIwMTIgVGhlIENocm9taXVtIEF1dGhvcnMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCi8vIFVzZSBvZiB0aGlzIHNvdXJjZSBjb2RlIGlzIGdvdmVybmVkIGJ5IGEgQlNELXN0eWxlIGxpY2Vuc2UgdGhhdCBjYW4gYmUKLy8gZm91bmQgaW4gdGhlIExJQ0VOU0UgZmlsZS4KCi8vIEN1c3RvbSBiaW5kaW5nIGZvciB0aGUgcGFnZUFjdGlvbiBBUEkuCgp2YXIgYmluZGluZyA9IGFwaUJyaWRnZSB8fCByZXF1aXJlKCdiaW5kaW5nJykuQmluZGluZy5jcmVhdGUoJ3BhZ2VBY3Rpb24nKTsKdmFyIHNldEljb24gPSByZXF1aXJlKCdzZXRJY29uJykuc2V0SWNvbjsKdmFyIHNlbmRSZXF1ZXN0ID0gYmluZGluZ1V0aWwgPwogICAgJEZ1bmN0aW9uLmJpbmQoYmluZGluZ1V0aWwuc2VuZFJlcXVlc3QsIGJpbmRpbmdVdGlsKSA6CiAgICByZXF1aXJlKCdzZW5kUmVxdWVzdCcpLnNlbmRSZXF1ZXN0OwoKYmluZGluZy5yZWdpc3RlckN1c3RvbUhvb2soZnVuY3Rpb24oYmluZGluZ3NBUEkpIHsKICB2YXIgYXBpRnVuY3Rpb25zID0gYmluZGluZ3NBUEkuYXBpRnVuY3Rpb25zOwoKICBhcGlGdW5jdGlvbnMuc2V0SGFuZGxlUmVxdWVzdCgnc2V0SWNvbicsIGZ1bmN0aW9uKGRldGFpbHMsIGNhbGxiYWNrKSB7CiAgICBzZXRJY29uKGRldGFpbHMsICRGdW5jdGlvbi5iaW5kKGZ1bmN0aW9uKGFyZ3MpIHsKICAgICAgc2VuZFJlcXVlc3QoJ3BhZ2VBY3Rpb24uc2V0SWNvbicsIFthcmdzLCBjYWxsYmFja10sCiAgICAgICAgICAgICAgICAgIGJpbmRpbmdVdGlsID8gdW5kZWZpbmVkIDogdGhpcy5kZWZpbml0aW9uLnBhcmFtZXRlcnMsCiAgICAgICAgICAgICAgICAgIHVuZGVmaW5lZCk7CiAgICB9LCB0aGlzKSk7CiAgfSk7Cn0pOwoKaWYgKCFhcGlCcmlkZ2UpCiAgZXhwb3J0cy4kc2V0KCdiaW5kaW5nJywgYmluZGluZy5nZW5lcmF0ZSgpKTsKLy8gQ29weXJpZ2h0IChjKSAyMDEyIFRoZSBDaHJvbWl1bSBBdXRob3JzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgovLyBVc2Ugb2YgdGhpcyBzb3VyY2UgY29kZSBpcyBnb3Zlcm5lZCBieSBhIEJTRC1zdHlsZSBsaWNlbnNlIHRoYXQgY2FuIGJlCi8vIGZvdW5kIGluIHRoZSBMSUNFTlNFIGZpbGUuCgovLyBDdXN0b20gYmluZGluZyBmb3IgdGhlIHBhZ2VDYXB0dXJlIEFQSS4KCnZhciBiaW5kaW5nID0gYXBpQnJpZGdlIHx8IHJlcXVpcmUoJ2JpbmRpbmcnKS5CaW5kaW5nLmNyZWF0ZSgncGFnZUNhcHR1cmUnKTsKCnZhciBoYW5kbGVVbmNhdWdodEV4Y2VwdGlvbiA9IHJlcXVpcmUoJ3VuY2F1Z2h0X2V4Y2VwdGlvbl9oYW5kbGVyJykuaGFuZGxlOwp2YXIgcGFnZUNhcHR1cmVOYXRpdmVzID0gcmVxdWlyZU5hdGl2ZSgncGFnZV9jYXB0dXJlJyk7CnZhciBDcmVhdGVCbG9iID0gcGFnZUNhcHR1cmVOYXRpdmVzLkNyZWF0ZUJsb2I7CnZhciBTZW5kUmVzcG9uc2VBY2sgPSBwYWdlQ2FwdHVyZU5hdGl2ZXMuU2VuZFJlc3BvbnNlQWNrOwoKYmluZGluZy5yZWdpc3RlckN1c3RvbUhvb2soZnVuY3Rpb24oYmluZGluZ3NBUEkpIHsKICB2YXIgYXBpRnVuY3Rpb25zID0gYmluZGluZ3NBUEkuYXBpRnVuY3Rpb25zOwoKICBhcGlGdW5jdGlvbnMuc2V0Q3VzdG9tQ2FsbGJhY2soJ3NhdmVBc01IVE1MJywKICAgICAgZnVuY3Rpb24obmFtZSwgcmVxdWVzdCwgY2FsbGJhY2ssIHJlc3BvbnNlKSB7CiAgICBpZiAocmVzcG9uc2UpCiAgICAgIHJlc3BvbnNlID0gQ3JlYXRlQmxvYihyZXNwb25zZS5taHRtbEZpbGVQYXRoLCByZXNwb25zZS5taHRtbEZpbGVMZW5ndGgpOwoKICAgIHRyeSB7CiAgICAgIGNhbGxiYWNrKHJlc3BvbnNlKTsKICAgIH0gY2F0Y2ggKGUpIHsKICAgICAgaGFuZGxlVW5jYXVnaHRFeGNlcHRpb24oCiAgICAgICAgICAnRXJyb3IgaW4gY2hyb21lLnBhZ2VDYXB0dXJlLnNhdmVBc01IVE1MIGNhbGxiYWNrJywgZSwgcmVxdWVzdC5zdGFjayk7CiAgICB9IGZpbmFsbHkgewogICAgICAvLyBOb3RpZnkgdGhlIGJyb3dzZXIuIE5vdyB0aGF0IHRoZSBibG9iIGlzIHJlZmVyZW5jZWQgZnJvbSBKYXZhU2NyaXB0LAogICAgICAvLyB0aGUgYnJvd3NlciBjYW4gZHJvcCBpdHMgcmVmZXJlbmNlIHRvIGl0LgogICAgICBTZW5kUmVzcG9uc2VBY2socmVxdWVzdC5pZCk7CiAgICB9CiAgfSk7Cn0pOwoKaWYgKCFhcGlCcmlkZ2UpCiAgZXhwb3J0cy4kc2V0KCdiaW5kaW5nJywgYmluZGluZy5nZW5lcmF0ZSgpKTsKLy8gQ29weXJpZ2h0IChjKSAyMDEyIFRoZSBDaHJvbWl1bSBBdXRob3JzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgovLyBVc2Ugb2YgdGhpcyBzb3VyY2UgY29kZSBpcyBnb3Zlcm5lZCBieSBhIEJTRC1zdHlsZSBsaWNlbnNlIHRoYXQgY2FuIGJlCi8vIGZvdW5kIGluIHRoZSBMSUNFTlNFIGZpbGUuCgovLyBDdXN0b20gYmluZGluZyBmb3IgdGhlIHN5bmNGaWxlU3lzdGVtIEFQSS4KCnZhciBiaW5kaW5nID0KICAgIGFwaUJyaWRnZSB8fCByZXF1aXJlKCdiaW5kaW5nJykuQmluZGluZy5jcmVhdGUoJ3N5bmNGaWxlU3lzdGVtJyk7Cgp2YXIgcmVnaXN0ZXJBcmd1bWVudE1hc3NhZ2VyID0gYmluZGluZ1V0aWwgPwogICAgJEZ1bmN0aW9uLmJpbmQoYmluZGluZ1V0aWwucmVnaXN0ZXJFdmVudEFyZ3VtZW50TWFzc2FnZXIsIGJpbmRpbmdVdGlsKSA6CiAgICByZXF1aXJlKCdldmVudF9iaW5kaW5ncycpLnJlZ2lzdGVyQXJndW1lbnRNYXNzYWdlcjsKCnZhciBmaWxlU3lzdGVtTmF0aXZlcyA9IHJlcXVpcmVOYXRpdmUoJ2ZpbGVfc3lzdGVtX25hdGl2ZXMnKTsKdmFyIHN5bmNGaWxlU3lzdGVtTmF0aXZlcyA9IHJlcXVpcmVOYXRpdmUoJ3N5bmNfZmlsZV9zeXN0ZW0nKTsKCmJpbmRpbmcucmVnaXN0ZXJDdXN0b21Ib29rKGZ1bmN0aW9uKGJpbmRpbmdzQVBJKSB7CiAgdmFyIGFwaUZ1bmN0aW9ucyA9IGJpbmRpbmdzQVBJLmFwaUZ1bmN0aW9uczsKCiAgLy8gRnVuY3Rpb25zIHdoaWNoIHRha2UgaW4gYW4gW2luc3RhbmNlT2Y9RmlsZUVudHJ5XS4KICBmdW5jdGlvbiBiaW5kRmlsZUVudHJ5RnVuY3Rpb24oZnVuY3Rpb25OYW1lKSB7CiAgICBhcGlGdW5jdGlvbnMuc2V0VXBkYXRlQXJndW1lbnRzUG9zdFZhbGlkYXRlKAogICAgICAgIGZ1bmN0aW9uTmFtZSwgZnVuY3Rpb24oZW50cnksIGNhbGxiYWNrKSB7CiAgICAgIHZhciBmaWxlU3lzdGVtVXJsID0gZW50cnkudG9VUkwoKTsKICAgICAgcmV0dXJuIFtmaWxlU3lzdGVtVXJsLCBjYWxsYmFja107CiAgICB9KTsKICB9CiAgJEFycmF5LmZvckVhY2goWydnZXRGaWxlU3RhdHVzJ10sIGJpbmRGaWxlRW50cnlGdW5jdGlvbik7CgogIC8vIEZ1bmN0aW9ucyB3aGljaCB0YWtlIGluIGEgRmlsZUVudHJ5IGFycmF5LgogIGZ1bmN0aW9uIGJpbmRGaWxlRW50cnlBcnJheUZ1bmN0aW9uKGZ1bmN0aW9uTmFtZSkgewogICAgYXBpRnVuY3Rpb25zLnNldFVwZGF0ZUFyZ3VtZW50c1Bvc3RWYWxpZGF0ZSgKICAgICAgICBmdW5jdGlvbk5hbWUsIGZ1bmN0aW9uKGVudHJpZXMsIGNhbGxiYWNrKSB7CiAgICAgIHZhciBmaWxlU3lzdGVtVXJsQXJyYXkgPSBbXTsKICAgICAgZm9yICh2YXIgaT0wOyBpIDwgZW50cmllcy5sZW5ndGg7IGkrKykgewogICAgICAgICRBcnJheS5wdXNoKGZpbGVTeXN0ZW1VcmxBcnJheSwgZW50cmllc1tpXS50b1VSTCgpKTsKICAgICAgfQogICAgICByZXR1cm4gW2ZpbGVTeXN0ZW1VcmxBcnJheSwgY2FsbGJhY2tdOwogICAgfSk7CiAgfQogICRBcnJheS5mb3JFYWNoKFsnZ2V0RmlsZVN0YXR1c2VzJ10sIGJpbmRGaWxlRW50cnlBcnJheUZ1bmN0aW9uKTsKCiAgLy8gRnVuY3Rpb25zIHdoaWNoIHRha2UgaW4gYW4gW2luc3RhbmNlT2Y9RE9NRmlsZVN5c3RlbV0uCiAgZnVuY3Rpb24gYmluZEZpbGVTeXN0ZW1GdW5jdGlvbihmdW5jdGlvbk5hbWUpIHsKICAgIGFwaUZ1bmN0aW9ucy5zZXRVcGRhdGVBcmd1bWVudHNQb3N0VmFsaWRhdGUoCiAgICAgICAgZnVuY3Rpb25OYW1lLCBmdW5jdGlvbihmaWxlc3lzdGVtLCBjYWxsYmFjaykgewogICAgICB2YXIgZmlsZVN5c3RlbVVybCA9IGZpbGVzeXN0ZW0ucm9vdC50b1VSTCgpOwogICAgICByZXR1cm4gW2ZpbGVTeXN0ZW1VcmwsIGNhbGxiYWNrXTsKICAgIH0pOwogIH0KICAkQXJyYXkuZm9yRWFjaChbJ2dldFVzYWdlQW5kUXVvdGEnXSwgYmluZEZpbGVTeXN0ZW1GdW5jdGlvbik7CgogIC8vIEZ1bmN0aW9ucyB3aGljaCByZXR1cm4gYW4gW2luc3RhbmNlT2Y9RE9NRmlsZVN5c3RlbV0uCiAgYXBpRnVuY3Rpb25zLnNldEN1c3RvbUNhbGxiYWNrKCdyZXF1ZXN0RmlsZVN5c3RlbScsCiAgICAgIGZ1bmN0aW9uKG5hbWUsIHJlcXVlc3QsIGNhbGxiYWNrLCByZXNwb25zZSkgewogICAgdmFyIHJlc3VsdCA9IG51bGw7CiAgICBpZiAocmVzcG9uc2UpIHsKICAgICAgcmVzdWx0ID0gc3luY0ZpbGVTeXN0ZW1OYXRpdmVzLkdldFN5bmNGaWxlU3lzdGVtT2JqZWN0KAogICAgICAgICAgcmVzcG9uc2UubmFtZSwgcmVzcG9uc2Uucm9vdCk7CiAgICB9CiAgICBpZiAoY2FsbGJhY2spCiAgICAgIGNhbGxiYWNrKHJlc3VsdCk7CiAgfSk7CgogIC8vIEZ1bmN0aW9ucyB3aGljaCByZXR1cm4gYW4gYXJyYXkgb2YgRmlsZVN0YXR1c0luZm8gb2JqZWN0CiAgLy8gd2hpY2ggaGFzIFtpbnN0YW5jZU9mPUZpbGVFbnRyeV0uCiAgYXBpRnVuY3Rpb25zLnNldEN1c3RvbUNhbGxiYWNrKCdnZXRGaWxlU3RhdHVzZXMnLAogICAgICBmdW5jdGlvbihuYW1lLCByZXF1ZXN0LCBjYWxsYmFjaywgcmVzcG9uc2UpIHsKICAgIHZhciByZXN1bHRzID0gW107CiAgICBpZiAocmVzcG9uc2UpIHsKICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCByZXNwb25zZS5sZW5ndGg7IGkrKykgewogICAgICAgIHZhciByZXN1bHQgPSB7fTsKICAgICAgICB2YXIgZW50cnkgPSByZXNwb25zZVtpXS5lbnRyeTsKICAgICAgICByZXN1bHQuZmlsZUVudHJ5ID0gZmlsZVN5c3RlbU5hdGl2ZXMuR2V0RmlsZUVudHJ5KAogICAgICAgICAgICBlbnRyeS5maWxlU3lzdGVtVHlwZSwKICAgICAgICAgICAgZW50cnkuZmlsZVN5c3RlbU5hbWUsCiAgICAgICAgICAgIGVudHJ5LnJvb3RVcmwsCiAgICAgICAgICAgIGVudHJ5LmZpbGVQYXRoLAogICAgICAgICAgICBlbnRyeS5pc0RpcmVjdG9yeSk7CiAgICAgICAgcmVzdWx0LnN0YXR1cyA9IHJlc3BvbnNlW2ldLnN0YXR1czsKICAgICAgICByZXN1bHQuZXJyb3IgPSByZXNwb25zZVtpXS5lcnJvcjsKICAgICAgICAkQXJyYXkucHVzaChyZXN1bHRzLCByZXN1bHQpOwogICAgICB9CiAgICB9CiAgICBpZiAoY2FsbGJhY2spCiAgICAgIGNhbGxiYWNrKHJlc3VsdHMpOwogIH0pOwp9KTsKCnJlZ2lzdGVyQXJndW1lbnRNYXNzYWdlcignc3luY0ZpbGVTeXN0ZW0ub25GaWxlU3RhdHVzQ2hhbmdlZCcsCiAgICAgICAgICAgICAgICAgICAgICAgICBmdW5jdGlvbihhcmdzLCBkaXNwYXRjaCkgewogIC8vIE1ha2UgRmlsZUVudHJ5IG9iamVjdCB1c2luZyBhbGwgdGhlIGJhc2Ugc3RyaW5nIGZpZWxkcy4KICB2YXIgZmlsZUVudHJ5ID0gZmlsZVN5c3RlbU5hdGl2ZXMuR2V0RmlsZUVudHJ5KAogICAgICBhcmdzWzBdLmZpbGVTeXN0ZW1UeXBlLAogICAgICBhcmdzWzBdLmZpbGVTeXN0ZW1OYW1lLAogICAgICBhcmdzWzBdLnJvb3RVcmwsCiAgICAgIGFyZ3NbMF0uZmlsZVBhdGgsCiAgICAgIGFyZ3NbMF0uaXNEaXJlY3RvcnkpOwoKICAvLyBDb21iaW5lIGludG8gYSBzaW5nbGUgZGljdGlvbmFyeS4KICB2YXIgZmlsZUluZm8gPSBuZXcgT2JqZWN0KCk7CiAgZmlsZUluZm8uZmlsZUVudHJ5ID0gZmlsZUVudHJ5OwogIGZpbGVJbmZvLnN0YXR1cyA9IGFyZ3NbMV07CiAgaWYgKGZpbGVJbmZvLnN0YXR1cyA9PSAic3luY2VkIikgewogICAgZmlsZUluZm8uYWN0aW9uID0gYXJnc1syXTsKICAgIGZpbGVJbmZvLmRpcmVjdGlvbiA9IGFyZ3NbM107CiAgfQogIGRpc3BhdGNoKFtmaWxlSW5mb10pOwp9KTsKCmlmICghYXBpQnJpZGdlKQogIGV4cG9ydHMuJHNldCgnYmluZGluZycsIGJpbmRpbmcuZ2VuZXJhdGUoKSk7Ci8vIENvcHlyaWdodCAoYykgMjAxMiBUaGUgQ2hyb21pdW0gQXV0aG9ycy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KLy8gVXNlIG9mIHRoaXMgc291cmNlIGNvZGUgaXMgZ292ZXJuZWQgYnkgYSBCU0Qtc3R5bGUgbGljZW5zZSB0aGF0IGNhbiBiZQovLyBmb3VuZCBpbiB0aGUgTElDRU5TRSBmaWxlLgoKLy8gQ3VzdG9tIGJpbmRpbmcgZm9yIHRoZSBzeXN0ZW1JbmRpY2F0b3IgQVBJLgovLyBUT0RPKGRld2l0dGopIFJlZmFjdG9yIGN1c3RvbSBiaW5kaW5nIHRvIHJlZHVjZSByZWR1bmRhbmN5IGJldHdlZW4gdGhlCi8vIGV4dGVuc2lvbiBhY3Rpb24gQVBJcy4KCnZhciBiaW5kaW5nID0KICAgIGFwaUJyaWRnZSB8fCByZXF1aXJlKCdiaW5kaW5nJykuQmluZGluZy5jcmVhdGUoJ3N5c3RlbUluZGljYXRvcicpOwoKdmFyIHNldEljb24gPSByZXF1aXJlKCdzZXRJY29uJykuc2V0SWNvbjsKdmFyIHNlbmRSZXF1ZXN0ID0gYmluZGluZ1V0aWwgPwogICAgJEZ1bmN0aW9uLmJpbmQoYmluZGluZ1V0aWwuc2VuZFJlcXVlc3QsIGJpbmRpbmdVdGlsKSA6CiAgICByZXF1aXJlKCdzZW5kUmVxdWVzdCcpLnNlbmRSZXF1ZXN0OwoKYmluZGluZy5yZWdpc3RlckN1c3RvbUhvb2soZnVuY3Rpb24oYmluZGluZ3NBUEkpIHsKICB2YXIgYXBpRnVuY3Rpb25zID0gYmluZGluZ3NBUEkuYXBpRnVuY3Rpb25zOwoKICBhcGlGdW5jdGlvbnMuc2V0SGFuZGxlUmVxdWVzdCgnc2V0SWNvbicsIGZ1bmN0aW9uKGRldGFpbHMsIGNhbGxiYWNrKSB7CiAgICBzZXRJY29uKGRldGFpbHMsICRGdW5jdGlvbi5iaW5kKGZ1bmN0aW9uKGFyZ3MpIHsKICAgICAgc2VuZFJlcXVlc3QoJ3N5c3RlbUluZGljYXRvci5zZXRJY29uJywgW2FyZ3MsIGNhbGxiYWNrXSwKICAgICAgICAgICAgICAgICAgYmluZGluZ1V0aWwgPyB1bmRlZmluZWQgOiB0aGlzLmRlZmluaXRpb24ucGFyYW1ldGVycywKICAgICAgICAgICAgICAgICAgdW5kZWZpbmVkKTsKICAgIH0sIHRoaXMpKTsKICB9KTsKfSk7CgppZiAoIWFwaUJyaWRnZSkKICBleHBvcnRzLiRzZXQoJ2JpbmRpbmcnLCBiaW5kaW5nLmdlbmVyYXRlKCkpOwovLyBDb3B5cmlnaHQgKGMpIDIwMTIgVGhlIENocm9taXVtIEF1dGhvcnMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCi8vIFVzZSBvZiB0aGlzIHNvdXJjZSBjb2RlIGlzIGdvdmVybmVkIGJ5IGEgQlNELXN0eWxlIGxpY2Vuc2UgdGhhdCBjYW4gYmUKLy8gZm91bmQgaW4gdGhlIExJQ0VOU0UgZmlsZS4KCi8vIEN1c3RvbSBiaW5kaW5nIGZvciB0aGUgVGFiIENhcHR1cmUgQVBJLgoKdmFyIGJpbmRpbmcgPSBhcGlCcmlkZ2UgfHwgcmVxdWlyZSgnYmluZGluZycpLkJpbmRpbmcuY3JlYXRlKCd0YWJDYXB0dXJlJyk7Cgp2YXIganNMYXN0RXJyb3IgPSBiaW5kaW5nVXRpbCA/IHVuZGVmaW5lZCA6IHJlcXVpcmUoJ2xhc3RFcnJvcicpOwpmdW5jdGlvbiBydW5DYWxsYmFja1dpdGhMYXN0RXJyb3IobmFtZSwgbWVzc2FnZSwgc3RhY2ssIGNhbGxiYWNrLCBhcmdzKSB7CiAgaWYgKGJpbmRpbmdVdGlsKSB7CiAgICBiaW5kaW5nVXRpbC5ydW5DYWxsYmFja1dpdGhMYXN0RXJyb3IobWVzc2FnZSwgZnVuY3Rpb24oKSB7CiAgICAgICRGdW5jdGlvbi5hcHBseShjYWxsYmFjaywgbnVsbCwgYXJncyk7CiAgICB9KTsKICB9IGVsc2UgewogICAganNMYXN0RXJyb3IucnVuKG5hbWUsIG1lc3NhZ2UsIHN0YWNrLCBjYWxsYmFjaywgYXJncyk7CiAgfQp9CgpiaW5kaW5nLnJlZ2lzdGVyQ3VzdG9tSG9vayhmdW5jdGlvbihiaW5kaW5nc0FQSSwgZXh0ZW5zaW9uSWQpIHsKICB2YXIgYXBpRnVuY3Rpb25zID0gYmluZGluZ3NBUEkuYXBpRnVuY3Rpb25zOwoKICBmdW5jdGlvbiBwcm94eVRvR2V0VXNlck1lZGlhKG5hbWUsIHJlcXVlc3QsIGNhbGxiYWNrLCByZXNwb25zZSkgewogICAgaWYgKCFjYWxsYmFjaykKICAgICAgcmV0dXJuOwoKICAgIGlmICghcmVzcG9uc2UpIHsKICAgICAgLy8gV2hlbiB0aGUgcmVzcG9uc2UgaXMgbWlzc2luZywgcnVudGltZS5sYXN0RXJyb3IgaGFzIGFscmVhZHkgYmVlbiBzZXQuCiAgICAgIC8vIFNlZSBjaHJvbWUvYnJvd3Nlci9leHRlbnNpb25zL2FwaS90YWJfY2FwdHVyZS90YWJfY2FwdHVyZV9hcGkuY2MuCiAgICAgIGNhbGxiYWNrKG51bGwpOwogICAgICByZXR1cm47CiAgICB9CgogICAgLy8gQ29udmVuaWVuY2UgZnVuY3Rpb24gZm9yIHByb2Nlc3Npbmcgd2Via2l0R2V0VXNlck1lZGlhKCkgZXJyb3Igb2JqZWN0cyB0bwogICAgLy8gcHJvdmlkZSBydW50aW1lLmxhc3RFcnJvciBtZXNzYWdlcyBmb3IgdGhlIHRhYiBjYXB0dXJlIEFQSS4KICAgIGZ1bmN0aW9uIGdldEVycm9yTWVzc2FnZShlcnJvciwgZmFsbGJhY2tNZXNzYWdlKSB7CiAgICAgIGlmICghZXJyb3IgfHwgKHR5cGVvZiBlcnJvci5tZXNzYWdlICE9ICdzdHJpbmcnKSkKICAgICAgICByZXR1cm4gZmFsbGJhY2tNZXNzYWdlOwogICAgICByZXR1cm4gZXJyb3IubWVzc2FnZS5yZXBsYWNlKC8obmF2aWdhdG9yXC4pPyh3ZWJraXQpP0dldFVzZXJNZWRpYS9naSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuYW1lKTsKICAgIH0KCiAgICB2YXIgb3B0aW9ucyA9IHt9OwogICAgaWYgKHJlc3BvbnNlLmF1ZGlvQ29uc3RyYWludHMpCiAgICAgIG9wdGlvbnMuYXVkaW8gPSByZXNwb25zZS5hdWRpb0NvbnN0cmFpbnRzOwogICAgaWYgKHJlc3BvbnNlLnZpZGVvQ29uc3RyYWludHMpCiAgICAgIG9wdGlvbnMudmlkZW8gPSByZXNwb25zZS52aWRlb0NvbnN0cmFpbnRzOwogICAgdHJ5IHsKICAgICAgbmF2aWdhdG9yLndlYmtpdEdldFVzZXJNZWRpYSgKICAgICAgICAgIG9wdGlvbnMsCiAgICAgICAgICBmdW5jdGlvbiBvblN1Y2Nlc3MobWVkaWFfc3RyZWFtKSB7CiAgICAgICAgICAgIGNhbGxiYWNrKG1lZGlhX3N0cmVhbSk7CiAgICAgICAgICB9LAogICAgICAgICAgZnVuY3Rpb24gb25FcnJvcihlcnJvcikgewogICAgICAgICAgICBydW5DYWxsYmFja1dpdGhMYXN0RXJyb3IoCiAgICAgICAgICAgICAgICBuYW1lLAogICAgICAgICAgICAgICAgZ2V0RXJyb3JNZXNzYWdlKGVycm9yLCAiRmFpbGVkIHRvIHN0YXJ0IE1lZGlhU3RyZWFtLiIpLAogICAgICAgICAgICAgICAgcmVxdWVzdC5zdGFjaywKICAgICAgICAgICAgICAgIGZ1bmN0aW9uKCkgeyBjYWxsYmFjayhudWxsKTsgfSk7CiAgICAgICAgICB9KTsKICAgIH0gY2F0Y2ggKGVycm9yKSB7CiAgICAgIHJ1bkNhbGxiYWNrV2l0aExhc3RFcnJvcigKICAgICAgICAgIG5hbWUsIGdldEVycm9yTWVzc2FnZShlcnJvciwgIkludmFsaWQgYXJndW1lbnQocykuIiksIHJlcXVlc3Quc3RhY2ssCiAgICAgICAgICBmdW5jdGlvbigpIHsgY2FsbGJhY2sobnVsbCk7IH0pOwogICAgfQogIH0KCiAgYXBpRnVuY3Rpb25zLnNldEN1c3RvbUNhbGxiYWNrKCdjYXB0dXJlJywgcHJveHlUb0dldFVzZXJNZWRpYSk7CiAgYXBpRnVuY3Rpb25zLnNldEN1c3RvbUNhbGxiYWNrKCdjYXB0dXJlT2Zmc2NyZWVuVGFiJywgcHJveHlUb0dldFVzZXJNZWRpYSk7Cn0pOwoKaWYgKCFhcGlCcmlkZ2UpCiAgZXhwb3J0cy4kc2V0KCdiaW5kaW5nJywgYmluZGluZy5nZW5lcmF0ZSgpKTsKLy8gQ29weXJpZ2h0IChjKSAyMDEyIFRoZSBDaHJvbWl1bSBBdXRob3JzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgovLyBVc2Ugb2YgdGhpcyBzb3VyY2UgY29kZSBpcyBnb3Zlcm5lZCBieSBhIEJTRC1zdHlsZSBsaWNlbnNlIHRoYXQgY2FuIGJlCi8vIGZvdW5kIGluIHRoZSBMSUNFTlNFIGZpbGUuCgovLyBDdXN0b20gYmluZGluZyBmb3IgdGhlIHRhYnMgQVBJLgoKdmFyIGJpbmRpbmcgPSBhcGlCcmlkZ2UgfHwgcmVxdWlyZSgnYmluZGluZycpLkJpbmRpbmcuY3JlYXRlKCd0YWJzJyk7Cgp2YXIgbWVzc2FnaW5nID0gcmVxdWlyZSgnbWVzc2FnaW5nJyk7CnZhciBPcGVuQ2hhbm5lbFRvVGFiID0gcmVxdWlyZU5hdGl2ZSgnbWVzc2FnaW5nX25hdGl2ZXMnKS5PcGVuQ2hhbm5lbFRvVGFiOwp2YXIgc2VuZFJlcXVlc3RJc0Rpc2FibGVkID0gcmVxdWlyZU5hdGl2ZSgncHJvY2VzcycpLklzU2VuZFJlcXVlc3REaXNhYmxlZCgpOwp2YXIgZm9yRWFjaCA9IHJlcXVpcmUoJ3V0aWxzJykuZm9yRWFjaDsKCmJpbmRpbmcucmVnaXN0ZXJDdXN0b21Ib29rKGZ1bmN0aW9uKGJpbmRpbmdzQVBJLCBleHRlbnNpb25JZCkgewogIHZhciBhcGlGdW5jdGlvbnMgPSBiaW5kaW5nc0FQSS5hcGlGdW5jdGlvbnM7CiAgdmFyIHRhYnMgPSBiaW5kaW5nc0FQSS5jb21waWxlZEFwaTsKCiAgYXBpRnVuY3Rpb25zLnNldEhhbmRsZVJlcXVlc3QoJ2Nvbm5lY3QnLCBmdW5jdGlvbih0YWJJZCwgY29ubmVjdEluZm8pIHsKICAgIHZhciBuYW1lID0gJyc7CiAgICB2YXIgZnJhbWVJZCA9IC0xOwogICAgaWYgKGNvbm5lY3RJbmZvKSB7CiAgICAgIG5hbWUgPSBjb25uZWN0SW5mby5uYW1lIHx8IG5hbWU7CiAgICAgIGZyYW1lSWQgPSBjb25uZWN0SW5mby5mcmFtZUlkOwogICAgICBpZiAodHlwZW9mIGZyYW1lSWQgPT0gJ3VuZGVmaW5lZCcgfHwgZnJhbWVJZCA8IDApCiAgICAgICAgZnJhbWVJZCA9IC0xOwogICAgfQogICAgdmFyIHBvcnRJZCA9IE9wZW5DaGFubmVsVG9UYWIodGFiSWQsIGZyYW1lSWQsIGV4dGVuc2lvbklkLCBuYW1lKTsKICAgIHJldHVybiBtZXNzYWdpbmcuY3JlYXRlUG9ydChwb3J0SWQsIG5hbWUpOwogIH0pOwoKICBhcGlGdW5jdGlvbnMuc2V0SGFuZGxlUmVxdWVzdCgnc2VuZFJlcXVlc3QnLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZ1bmN0aW9uKHRhYklkLCByZXF1ZXN0LCByZXNwb25zZUNhbGxiYWNrKSB7CiAgICBpZiAoc2VuZFJlcXVlc3RJc0Rpc2FibGVkKQogICAgICB0aHJvdyBuZXcgRXJyb3Ioc2VuZFJlcXVlc3RJc0Rpc2FibGVkKTsKICAgIHZhciBwb3J0ID0gdGFicy5jb25uZWN0KHRhYklkLCB7bmFtZTogbWVzc2FnaW5nLmtSZXF1ZXN0Q2hhbm5lbH0pOwogICAgbWVzc2FnaW5nLnNlbmRNZXNzYWdlSW1wbChwb3J0LCByZXF1ZXN0LCByZXNwb25zZUNhbGxiYWNrKTsKICB9KTsKCiAgYXBpRnVuY3Rpb25zLnNldEhhbmRsZVJlcXVlc3QoJ3NlbmRNZXNzYWdlJywKICAgICAgZnVuY3Rpb24odGFiSWQsIG1lc3NhZ2UsIG9wdGlvbnMsIHJlc3BvbnNlQ2FsbGJhY2spIHsKICAgIHZhciBjb25uZWN0SW5mbyA9IHsKICAgICAgbmFtZTogbWVzc2FnaW5nLmtNZXNzYWdlQ2hhbm5lbAogICAgfTsKICAgIGlmIChvcHRpb25zKSB7CiAgICAgIGZvckVhY2gob3B0aW9ucywgZnVuY3Rpb24oaywgdikgewogICAgICAgIGNvbm5lY3RJbmZvW2tdID0gdjsKICAgICAgfSk7CiAgICB9CgogICAgdmFyIHBvcnQgPSB0YWJzLmNvbm5lY3QodGFiSWQsIGNvbm5lY3RJbmZvKTsKICAgIG1lc3NhZ2luZy5zZW5kTWVzc2FnZUltcGwocG9ydCwgbWVzc2FnZSwgcmVzcG9uc2VDYWxsYmFjayk7CiAgfSk7Cn0pOwoKaWYgKCFhcGlCcmlkZ2UpCiAgZXhwb3J0cy4kc2V0KCdiaW5kaW5nJywgYmluZGluZy5nZW5lcmF0ZSgpKTsKLy8gQ29weXJpZ2h0IChjKSAyMDEyIFRoZSBDaHJvbWl1bSBBdXRob3JzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgovLyBVc2Ugb2YgdGhpcyBzb3VyY2UgY29kZSBpcyBnb3Zlcm5lZCBieSBhIEJTRC1zdHlsZSBsaWNlbnNlIHRoYXQgY2FuIGJlCi8vIGZvdW5kIGluIHRoZSBMSUNFTlNFIGZpbGUuCgovLyBDdXN0b20gYmluZGluZyBmb3IgdGhlIHR0cyBBUEkuCgp2YXIgYmluZGluZyA9IGFwaUJyaWRnZSB8fCByZXF1aXJlKCdiaW5kaW5nJykuQmluZGluZy5jcmVhdGUoJ3R0cycpOwoKdmFyIGlkR2VuZXJhdG9yID0gcmVxdWlyZU5hdGl2ZSgnaWRfZ2VuZXJhdG9yJyk7CnZhciBzZW5kUmVxdWVzdCA9IGJpbmRpbmdVdGlsID8KICAgICRGdW5jdGlvbi5iaW5kKGJpbmRpbmdVdGlsLnNlbmRSZXF1ZXN0LCBiaW5kaW5nVXRpbCkgOgogICAgcmVxdWlyZSgnc2VuZFJlcXVlc3QnKS5zZW5kUmVxdWVzdDsKdmFyIGxhenlCRyA9IHJlcXVpcmVOYXRpdmUoJ2xhenlfYmFja2dyb3VuZF9wYWdlJyk7CgpiaW5kaW5nLnJlZ2lzdGVyQ3VzdG9tSG9vayhmdW5jdGlvbihhcGkpIHsKICB2YXIgYXBpRnVuY3Rpb25zID0gYXBpLmFwaUZ1bmN0aW9uczsKICB2YXIgdHRzID0gYXBpLmNvbXBpbGVkQXBpOwogIHZhciBoYW5kbGVycyA9IHt9OwoKICBmdW5jdGlvbiB0dHNFdmVudExpc3RlbmVyKGV2ZW50KSB7CiAgICB2YXIgZXZlbnRIYW5kbGVyID0gaGFuZGxlcnNbZXZlbnQuc3JjSWRdOwogICAgaWYgKGV2ZW50SGFuZGxlcikgewogICAgICBldmVudEhhbmRsZXIoewogICAgICAgICAgICAgICAgICAgICB0eXBlOiBldmVudC50eXBlLAogICAgICAgICAgICAgICAgICAgICBjaGFySW5kZXg6IGV2ZW50LmNoYXJJbmRleCwKICAgICAgICAgICAgICAgICAgICAgZXJyb3JNZXNzYWdlOiBldmVudC5lcnJvck1lc3NhZ2UKICAgICAgICAgICAgICAgICAgIH0pOwogICAgICBpZiAoZXZlbnQuaXNGaW5hbEV2ZW50KSB7CiAgICAgICAgZGVsZXRlIGhhbmRsZXJzW2V2ZW50LnNyY0lkXTsKICAgICAgICAvLyBCYWxhbmNlZCBpbiAnc3BlYWsnIGhhbmRsZXIuCiAgICAgICAgbGF6eUJHLkRlY3JlbWVudEtlZXBhbGl2ZUNvdW50KCk7CiAgICAgIH0KICAgIH0KICB9CgogIC8vIFRoaXMgZmlsZSB3aWxsIGdldCBydW4gaWYgYW4gZXh0ZW5zaW9uIG5lZWRzIHRoZSB0dHNFbmdpbmUgcGVybWlzc2lvbiwgYnV0CiAgLy8gaXQgZG9lc24ndCBuZWNlc3NhcmlseSBoYXZlIHRoZSB0dHMgcGVybWlzc2lvbi4gSWYgaXQgZG9lc24ndCwgdHJ5aW5nIHRvCiAgLy8gYWRkIGEgbGlzdGVuZXIgdG8gY2hyb21lLnR0cy5vbkV2ZW50IHdpbGwgZmFpbC4KICAvLyBTZWUgaHR0cDovL2NyYnVnLmNvbS8xMjI0NzQuCiAgdHJ5IHsKICAgIHR0cy5vbkV2ZW50LmFkZExpc3RlbmVyKHR0c0V2ZW50TGlzdGVuZXIpOwogIH0gY2F0Y2ggKGUpIHt9CgogIGFwaUZ1bmN0aW9ucy5zZXRIYW5kbGVSZXF1ZXN0KCdzcGVhaycsIGZ1bmN0aW9uKCkgewogICAgdmFyIGFyZ3MgPSAkQXJyYXkuZnJvbShhcmd1bWVudHMpOwogICAgaWYgKGFyZ3MubGVuZ3RoID4gMSAmJiBhcmdzWzFdICYmIGFyZ3NbMV0ub25FdmVudCkgewogICAgICB2YXIgaWQgPSBpZEdlbmVyYXRvci5HZXROZXh0SWQoKTsKICAgICAgYXJnc1sxXS5zcmNJZCA9IGlkOwogICAgICBoYW5kbGVyc1tpZF0gPSBhcmdzWzFdLm9uRXZlbnQ7CiAgICAgIC8vIEtlZXAgdGhlIHBhZ2UgYWxpdmUgdW50aWwgdGhlIGV2ZW50IGZpbmlzaGVzLgogICAgICAvLyBCYWxhbmNlZCBpbiBldmVudEhhbmRsZXIuCiAgICAgIGxhenlCRy5JbmNyZW1lbnRLZWVwYWxpdmVDb3VudCgpOwogICAgfQogICAgc2VuZFJlcXVlc3QoJ3R0cy5zcGVhaycsIGFyZ3MsCiAgICAgICAgICAgICAgICBiaW5kaW5nVXRpbCA/IHVuZGVmaW5lZCA6IHRoaXMuZGVmaW5pdGlvbi5wYXJhbWV0ZXJzLAogICAgICAgICAgICAgICAgdW5kZWZpbmVkKTsKICAgIHJldHVybiBpZDsKICB9KTsKfSk7CgppZiAoIWFwaUJyaWRnZSkKICBleHBvcnRzLiRzZXQoJ2JpbmRpbmcnLCBiaW5kaW5nLmdlbmVyYXRlKCkpOwovLyBDb3B5cmlnaHQgKGMpIDIwMTIgVGhlIENocm9taXVtIEF1dGhvcnMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCi8vIFVzZSBvZiB0aGlzIHNvdXJjZSBjb2RlIGlzIGdvdmVybmVkIGJ5IGEgQlNELXN0eWxlIGxpY2Vuc2UgdGhhdCBjYW4gYmUKLy8gZm91bmQgaW4gdGhlIExJQ0VOU0UgZmlsZS4KCi8vIEN1c3RvbSBiaW5kaW5nIGZvciB0aGUgdHRzRW5naW5lIEFQSS4KCnZhciBiaW5kaW5nID0gYXBpQnJpZGdlIHx8IHJlcXVpcmUoJ2JpbmRpbmcnKS5CaW5kaW5nLmNyZWF0ZSgndHRzRW5naW5lJyk7CnZhciByZWdpc3RlckFyZ3VtZW50TWFzc2FnZXIgPSBiaW5kaW5nVXRpbCA/CiAgICAkRnVuY3Rpb24uYmluZChiaW5kaW5nVXRpbC5yZWdpc3RlckV2ZW50QXJndW1lbnRNYXNzYWdlciwgYmluZGluZ1V0aWwpIDoKICAgIHJlcXVpcmUoJ2V2ZW50X2JpbmRpbmdzJykucmVnaXN0ZXJBcmd1bWVudE1hc3NhZ2VyOwoKcmVnaXN0ZXJBcmd1bWVudE1hc3NhZ2VyKCd0dHNFbmdpbmUub25TcGVhaycsIGZ1bmN0aW9uKGFyZ3MsIGRpc3BhdGNoKSB7CiAgdmFyIHRleHQgPSBhcmdzWzBdOwogIHZhciBvcHRpb25zID0gYXJnc1sxXTsKICB2YXIgcmVxdWVzdElkID0gYXJnc1syXTsKICB2YXIgc2VuZFR0c0V2ZW50ID0gZnVuY3Rpb24oZXZlbnQpIHsKICAgIGNocm9tZS50dHNFbmdpbmUuc2VuZFR0c0V2ZW50KHJlcXVlc3RJZCwgZXZlbnQpOwogIH07CiAgZGlzcGF0Y2goW3RleHQsIG9wdGlvbnMsIHNlbmRUdHNFdmVudF0pOwp9KTsKCmlmICghYXBpQnJpZGdlKQogIGV4cG9ydHMuJHNldCgnYmluZGluZycsIGJpbmRpbmcuZ2VuZXJhdGUoKSk7Ci8vIENvcHlyaWdodCAyMDE1IFRoZSBDaHJvbWl1bSBBdXRob3JzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgovLyBVc2Ugb2YgdGhpcyBzb3VyY2UgY29kZSBpcyBnb3Zlcm5lZCBieSBhIEJTRC1zdHlsZSBsaWNlbnNlIHRoYXQgY2FuIGJlCi8vIGZvdW5kIGluIHRoZSBMSUNFTlNFIGZpbGUuCgovLyBDdXN0b20gYmluZGluZyBmb3IgdGhlIHdlYnJ0Y0Rlc2t0b3BDYXB0dXJlUHJpdmF0ZSBBUEkuCgp2YXIgYmluZGluZyA9IGFwaUJyaWRnZSB8fAogICAgICAgICAgICAgIHJlcXVpcmUoJ2JpbmRpbmcnKS5CaW5kaW5nLmNyZWF0ZSgnd2VicnRjRGVza3RvcENhcHR1cmVQcml2YXRlJyk7CnZhciBzZW5kUmVxdWVzdCA9IGJpbmRpbmdVdGlsID8KICAgICRGdW5jdGlvbi5iaW5kKGJpbmRpbmdVdGlsLnNlbmRSZXF1ZXN0LCBiaW5kaW5nVXRpbCkgOgogICAgcmVxdWlyZSgnc2VuZFJlcXVlc3QnKS5zZW5kUmVxdWVzdDsKdmFyIGlkR2VuZXJhdG9yID0gcmVxdWlyZU5hdGl2ZSgnaWRfZ2VuZXJhdG9yJyk7CgpiaW5kaW5nLnJlZ2lzdGVyQ3VzdG9tSG9vayhmdW5jdGlvbihiaW5kaW5nc0FQSSkgewogIHZhciBhcGlGdW5jdGlvbnMgPSBiaW5kaW5nc0FQSS5hcGlGdW5jdGlvbnM7CgogIHZhciBwZW5kaW5nUmVxdWVzdHMgPSB7fTsKCiAgZnVuY3Rpb24gb25SZXF1ZXN0UmVzdWx0KGlkLCByZXN1bHQpIHsKICAgIGlmIChpZCBpbiBwZW5kaW5nUmVxdWVzdHMpIHsKICAgICAgdmFyIGNhbGxiYWNrID0gcGVuZGluZ1JlcXVlc3RzW2lkXTsKICAgICAgZGVsZXRlIHBlbmRpbmdSZXF1ZXN0c1tpZF07CiAgICAgIGNhbGxiYWNrKHJlc3VsdCk7CiAgICB9CiAgfQoKICBhcGlGdW5jdGlvbnMuc2V0SGFuZGxlUmVxdWVzdCgnY2hvb3NlRGVza3RvcE1lZGlhJywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmdW5jdGlvbihzb3VyY2VzLCByZXF1ZXN0LCBjYWxsYmFjaykgewogICAgdmFyIGlkID0gaWRHZW5lcmF0b3IuR2V0TmV4dElkKCk7CiAgICBwZW5kaW5nUmVxdWVzdHNbaWRdID0gY2FsbGJhY2s7CiAgICBzZW5kUmVxdWVzdCgnd2VicnRjRGVza3RvcENhcHR1cmVQcml2YXRlLmNob29zZURlc2t0b3BNZWRpYScsCiAgICAgICAgICAgICAgICBbaWQsIHNvdXJjZXMsIHJlcXVlc3QsCiAgICAgICAgICAgICAgICAgJEZ1bmN0aW9uLmJpbmQob25SZXF1ZXN0UmVzdWx0LCBudWxsLCBpZCldLAogICAgICAgICAgICAgICAgYmluZGluZ1V0aWwgPyB1bmRlZmluZWQgOiB0aGlzLmRlZmluaXRpb24ucGFyYW1ldGVycywKICAgICAgICAgICAgICAgIHVuZGVmaW5lZCk7CiAgICByZXR1cm4gaWQ7CiAgfSk7CgogIGFwaUZ1bmN0aW9ucy5zZXRIYW5kbGVSZXF1ZXN0KCdjYW5jZWxDaG9vc2VEZXNrdG9wTWVkaWEnLCBmdW5jdGlvbihpZCkgewogICAgaWYgKGlkIGluIHBlbmRpbmdSZXF1ZXN0cykgewogICAgICBkZWxldGUgcGVuZGluZ1JlcXVlc3RzW2lkXTsKICAgICAgc2VuZFJlcXVlc3QoJ3dlYnJ0Y0Rlc2t0b3BDYXB0dXJlUHJpdmF0ZS5jYW5jZWxDaG9vc2VEZXNrdG9wTWVkaWEnLCBbaWRdLAogICAgICAgICAgICAgICAgICBiaW5kaW5nVXRpbCA/IHVuZGVmaW5lZCA6IHRoaXMuZGVmaW5pdGlvbi5wYXJhbWV0ZXJzLAogICAgICAgICAgICAgICAgICB1bmRlZmluZWQpOwogICAgfQogIH0pOwp9KTsKCmlmICghYXBpQnJpZGdlKQogIGV4cG9ydHMuJHNldCgnYmluZGluZycsIGJpbmRpbmcuZ2VuZXJhdGUoKSk7Ci8vIENvcHlyaWdodCAyMDE3IFRoZSBDaHJvbWl1bSBBdXRob3JzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgovLyBVc2Ugb2YgdGhpcyBzb3VyY2UgY29kZSBpcyBnb3Zlcm5lZCBieSBhIEJTRC1zdHlsZSBsaWNlbnNlIHRoYXQgY2FuIGJlCi8vIGZvdW5kIGluIHRoZSBMSUNFTlNFIGZpbGUuCgovLyBDdXN0b20gYmluZGluZyBmb3IgdGhlIHdlYnJ0Y0xvZ2dpbmdQcml2YXRlIEFQSS4KCnZhciBiaW5kaW5nID0gYXBpQnJpZGdlIHx8CiAgICAgICAgICAgICAgcmVxdWlyZSgnYmluZGluZycpLkJpbmRpbmcuY3JlYXRlKCd3ZWJydGNMb2dnaW5nUHJpdmF0ZScpOwoKdmFyIGdldEJpbmREaXJlY3RvcnlFbnRyeUNhbGxiYWNrID0KICAgIHJlcXVpcmUoJ2ZpbGVFbnRyeUJpbmRpbmdVdGlsJykuZ2V0QmluZERpcmVjdG9yeUVudHJ5Q2FsbGJhY2s7CgpiaW5kaW5nLnJlZ2lzdGVyQ3VzdG9tSG9vayhmdW5jdGlvbihiaW5kaW5nLCBpZCwgY29udGV4dFR5cGUpIHsKICB2YXIgYXBpRnVuY3Rpb25zID0gYmluZGluZy5hcGlGdW5jdGlvbnM7CiAgYXBpRnVuY3Rpb25zLnNldEN1c3RvbUNhbGxiYWNrKCdnZXRMb2dzRGlyZWN0b3J5JywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZ2V0QmluZERpcmVjdG9yeUVudHJ5Q2FsbGJhY2soKSk7Cn0pOwoKaWYgKCFhcGlCcmlkZ2UpCiAgZXhwb3J0cy4kc2V0KCdiaW5kaW5nJywgYmluZGluZy5nZW5lcmF0ZSgpKTsKLy8gQ29weXJpZ2h0IChjKSAyMDEyIFRoZSBDaHJvbWl1bSBBdXRob3JzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgovLyBVc2Ugb2YgdGhpcyBzb3VyY2UgY29kZSBpcyBnb3Zlcm5lZCBieSBhIEJTRC1zdHlsZSBsaWNlbnNlIHRoYXQgY2FuIGJlCi8vIGZvdW5kIGluIHRoZSBMSUNFTlNFIGZpbGUuCgovLyBDdXN0b20gYmluZGluZyBmb3IgdGhlIHdlYnN0b3JlIEFQSS4KCnZhciB3ZWJzdG9yZU5hdGl2ZXMgPSByZXF1aXJlTmF0aXZlKCd3ZWJzdG9yZScpOwoKdmFyIG9uSW5zdGFsbFN0YWdlQ2hhbmdlZDsKdmFyIG9uRG93bmxvYWRQcm9ncmVzczsKCmZ1bmN0aW9uIEluc3RhbGxlcigpIHsKICB0aGlzLl9wZW5kaW5nSW5zdGFsbCA9IG51bGw7Cn0KCkluc3RhbGxlci5wcm90b3R5cGUuaW5zdGFsbCA9IGZ1bmN0aW9uKHVybCwgb25TdWNjZXNzLCBvbkZhaWx1cmUpIHsKICBpZiAodGhpcy5fcGVuZGluZ0luc3RhbGwpCiAgICB0aHJvdyBuZXcgRXJyb3IoJ0EgQ2hyb21lIFdlYiBTdG9yZSBpbnN0YWxsYXRpb24gaXMgYWxyZWFkeSBwZW5kaW5nLicpOwoKICAvLyBXaXRoIG5hdGl2ZSBiaW5kaW5ncywgdGhlc2UgY2FsbHMgZ28gdGhyb3VnaCBhcmd1bWVudCB2YWxpZGF0aW9uLCB3aGljaAogIC8vIHNldHMgb3B0aW9uYWwvbWlzc2luZyBhcmd1bWVudHMgdG8gbnVsbC4gVGhlIG5hdGl2ZSB3ZWJzdG9yZSBiaW5kaW5ncwogIC8vIGV4cGVjdCBlaXRoZXIgcHJlc2VudCBvciB1bmRlZmluZWQsIHNvIHRyYW5zZm9ybSBudWxsIHRvIHVuZGVmaW5lZC4KICBpZiAodXJsID09PSBudWxsKQogICAgdXJsID0gdW5kZWZpbmVkOwogIGlmIChvblN1Y2Nlc3MgPT09IG51bGwpCiAgICBvblN1Y2Nlc3MgPSB1bmRlZmluZWQ7CiAgaWYgKG9uRmFpbHVyZSA9PT0gbnVsbCkKICAgIG9uRmFpbHVyZSA9IHVuZGVmaW5lZDsKCiAgaWYgKHVybCAhPT0gdW5kZWZpbmVkICYmIHR5cGVvZiB1cmwgIT09ICdzdHJpbmcnKSB7CiAgICB0aHJvdyBuZXcgRXJyb3IoCiAgICAgICAgJ1RoZSBDaHJvbWUgV2ViIFN0b3JlIGl0ZW0gbGluayBVUkwgcGFyYW1ldGVyIG11c3QgYmUgYSBzdHJpbmcuJyk7CiAgfQogIGlmIChvblN1Y2Nlc3MgIT09IHVuZGVmaW5lZCAmJiB0eXBlb2Ygb25TdWNjZXNzICE9PSAnZnVuY3Rpb24nKSB7CiAgICB0aHJvdyBuZXcgRXJyb3IoJ1RoZSBzdWNjZXNzIGNhbGxiYWNrIHBhcmFtZXRlciBtdXN0IGJlIGEgZnVuY3Rpb24uJyk7CiAgfQogIGlmIChvbkZhaWx1cmUgIT09IHVuZGVmaW5lZCAmJiB0eXBlb2Ygb25GYWlsdXJlICE9PSAnZnVuY3Rpb24nKSB7CiAgICB0aHJvdyBuZXcgRXJyb3IoJ1RoZSBmYWlsdXJlIGNhbGxiYWNrIHBhcmFtZXRlciBtdXN0IGJlIGEgZnVuY3Rpb24uJyk7CiAgfQoKICAvLyBTaW5jZSB3ZSBjYWxsIEluc3RhbGwoKSB3aXRoIGEgYm9vbCBmb3IgaWYgd2UgaGF2ZSBsaXN0ZW5lcnMsIGxpc3RlbmVycwogIC8vIG11c3QgYmUgc2V0IHByaW9yIHRvIHRoZSBpbmxpbmUgaW5zdGFsbGF0aW9uIHN0YXJ0aW5nICh0aGlzIGlzIGFsc28KICAvLyBub3RlZCBpbiB0aGUgRXZlbnQgZG9jdW1lbnRhdGlvbiBpbgogIC8vIGNocm9tZS9jb21tb24vZXh0ZW5zaW9ucy9hcGkvd2Vic3RvcmUuanNvbikuCiAgdmFyIGluc3RhbGxJZCA9IHdlYnN0b3JlTmF0aXZlcy5JbnN0YWxsKAogICAgICBvbkluc3RhbGxTdGFnZUNoYW5nZWQuaGFzTGlzdGVuZXJzKCksCiAgICAgIG9uRG93bmxvYWRQcm9ncmVzcy5oYXNMaXN0ZW5lcnMoKSwKICAgICAgdXJsLAogICAgICBvblN1Y2Nlc3MsCiAgICAgIG9uRmFpbHVyZSk7CiAgaWYgKGluc3RhbGxJZCAhPT0gdW5kZWZpbmVkKSB7CiAgICB0aGlzLl9wZW5kaW5nSW5zdGFsbCA9IHsKICAgICAgaW5zdGFsbElkOiBpbnN0YWxsSWQsCiAgICAgIG9uU3VjY2Vzczogb25TdWNjZXNzLAogICAgICBvbkZhaWx1cmU6IG9uRmFpbHVyZQogICAgfTsKICB9Cn07CgpJbnN0YWxsZXIucHJvdG90eXBlLm9uSW5zdGFsbFJlc3BvbnNlID0KICAgIGZ1bmN0aW9uKGluc3RhbGxJZCwgc3VjY2VzcywgZXJyb3IsIHJlc3VsdENvZGUpIHsKICB2YXIgcGVuZGluZ0luc3RhbGwgPSB0aGlzLl9wZW5kaW5nSW5zdGFsbDsKICBpZiAoIXBlbmRpbmdJbnN0YWxsIHx8IHBlbmRpbmdJbnN0YWxsLmluc3RhbGxJZCAhPSBpbnN0YWxsSWQpIHsKICAgIC8vIFRPRE8oa2FsbWFuKTogc2hvdWxkIHRoaXMgYmUgYW4gZXJyb3I/CiAgICByZXR1cm47CiAgfQoKICB0cnkgewogICAgaWYgKHN1Y2Nlc3MgJiYgcGVuZGluZ0luc3RhbGwub25TdWNjZXNzKQogICAgICBwZW5kaW5nSW5zdGFsbC5vblN1Y2Nlc3MoKTsKICAgIGVsc2UgaWYgKCFzdWNjZXNzICYmIHBlbmRpbmdJbnN0YWxsLm9uRmFpbHVyZSkKICAgICAgcGVuZGluZ0luc3RhbGwub25GYWlsdXJlKGVycm9yLCByZXN1bHRDb2RlKTsKICB9IGNhdGNoIChlKSB7CiAgICBjb25zb2xlLmVycm9yKCdFeGNlcHRpb24gaW4gY2hyb21lLndlYnN0b3JlLmluc3RhbGwgcmVzcG9uc2UgaGFuZGxlcjogJyArCiAgICAgICAgICAgICAgICAgIGUuc3RhY2spOwogIH0gZmluYWxseSB7CiAgICB0aGlzLl9wZW5kaW5nSW5zdGFsbCA9IG51bGw7CiAgfQp9OwoKSW5zdGFsbGVyLnByb3RvdHlwZS5vbkluc3RhbGxTdGFnZUNoYW5nZWQgPSBmdW5jdGlvbihpbnN0YWxsU3RhZ2UpIHsKICBvbkluc3RhbGxTdGFnZUNoYW5nZWQuZGlzcGF0Y2goaW5zdGFsbFN0YWdlKTsKfTsKCkluc3RhbGxlci5wcm90b3R5cGUub25Eb3dubG9hZFByb2dyZXNzID0gZnVuY3Rpb24ocHJvZ3Jlc3MpIHsKICBvbkRvd25sb2FkUHJvZ3Jlc3MuZGlzcGF0Y2gocHJvZ3Jlc3MpOwp9OwoKdmFyIGluc3RhbGxlciA9IG5ldyBJbnN0YWxsZXIoKTsKCgppZiAoYXBpQnJpZGdlKSB7CiAgYXBpQnJpZGdlLnJlZ2lzdGVyQ3VzdG9tSG9vayhmdW5jdGlvbihhcGkpIHsKICAgIGFwaS5hcGlGdW5jdGlvbnMuc2V0SGFuZGxlUmVxdWVzdCgnaW5zdGFsbCcsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZnVuY3Rpb24odXJsLCBvblN1Y2Nlc3MsIG9uRmFpbHVyZSkgewogICAgICBpbnN0YWxsZXIuaW5zdGFsbCh1cmwsIG9uU3VjY2Vzcywgb25GYWlsdXJlKTsKICAgIH0pOwoKICAgIG9uSW5zdGFsbFN0YWdlQ2hhbmdlZCA9IGFwaS5jb21waWxlZEFwaS5vbkluc3RhbGxTdGFnZUNoYW5nZWQ7CiAgICBvbkRvd25sb2FkUHJvZ3Jlc3MgPSBhcGkuY29tcGlsZWRBcGkub25Eb3dubG9hZFByb2dyZXNzOwogIH0pOwp9IGVsc2UgewogIHZhciBFdmVudCA9IHJlcXVpcmUoJ2V2ZW50X2JpbmRpbmdzJykuRXZlbnQ7CiAgb25JbnN0YWxsU3RhZ2VDaGFuZ2VkID0KICAgICAgbmV3IEV2ZW50KG51bGwsIFt7bmFtZTogJ3N0YWdlJywgdHlwZTogJ3N0cmluZyd9XSwge3VubWFuYWdlZDogdHJ1ZX0pOwogIG9uRG93bmxvYWRQcm9ncmVzcyA9CiAgICAgIG5ldyBFdmVudChudWxsLCBbe25hbWU6ICdwcm9ncmVzcycsIHR5cGU6ICdudW1iZXInfV0sIHt1bm1hbmFnZWQ6IHRydWV9KTsKCiAgdmFyIGNocm9tZVdlYnN0b3JlID0gewogICAgaW5zdGFsbDogZnVuY3Rpb24gKHVybCwgb25TdWNjZXNzLCBvbkZhaWx1cmUpIHsKICAgICAgaW5zdGFsbGVyLmluc3RhbGwodXJsLCBvblN1Y2Nlc3MsIG9uRmFpbHVyZSk7CiAgICB9LAogICAgb25JbnN0YWxsU3RhZ2VDaGFuZ2VkOiBvbkluc3RhbGxTdGFnZUNoYW5nZWQsCiAgICBvbkRvd25sb2FkUHJvZ3Jlc3M6IG9uRG93bmxvYWRQcm9ncmVzcywKICB9OwogIGV4cG9ydHMuJHNldCgnYmluZGluZycsIGNocm9tZVdlYnN0b3JlKTsKfQoKLy8gQ2FsbGVkIGJ5IHdlYnN0b3JlX2JpbmRpbmdzLmNjLgpleHBvcnRzLiRzZXQoJ29uSW5zdGFsbFJlc3BvbnNlJywKICAgICAgICAgICAgICRGdW5jdGlvbi5iaW5kKEluc3RhbGxlci5wcm90b3R5cGUub25JbnN0YWxsUmVzcG9uc2UsIGluc3RhbGxlcikpOwpleHBvcnRzLiRzZXQoJ29uSW5zdGFsbFN0YWdlQ2hhbmdlZCcsCiAgICAgICAgICAgICAkRnVuY3Rpb24uYmluZChJbnN0YWxsZXIucHJvdG90eXBlLm9uSW5zdGFsbFN0YWdlQ2hhbmdlZCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGluc3RhbGxlcikpOwpleHBvcnRzLiRzZXQoJ29uRG93bmxvYWRQcm9ncmVzcycsCiAgICAgICAgICAgICAkRnVuY3Rpb24uYmluZChJbnN0YWxsZXIucHJvdG90eXBlLm9uRG93bmxvYWRQcm9ncmVzcywgaW5zdGFsbGVyKSk7Ci8vIENvcHlyaWdodCAyMDE0IFRoZSBDaHJvbWl1bSBBdXRob3JzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgovLyBVc2Ugb2YgdGhpcyBzb3VyY2UgY29kZSBpcyBnb3Zlcm5lZCBieSBhIEJTRC1zdHlsZSBsaWNlbnNlIHRoYXQgY2FuIGJlCi8vIGZvdW5kIGluIHRoZSBMSUNFTlNFIGZpbGUuCgondXNlIHN0cmljdCc7CgooZnVuY3Rpb24oKSB7CiAgdmFyIG1vam9tSWQgPSAnY2hyb21lL2NvbW1vbi9tZWRpYV9yb3V0ZXIvbW9qby9tZWRpYV9jb250cm9sbGVyLm1vam9tJzsKICBpZiAobW9qby5pbnRlcm5hbC5pc01vam9tTG9hZGVkKG1vam9tSWQpKSB7CiAgICBjb25zb2xlLndhcm4oJ1RoZSBmb2xsb3dpbmcgbW9qb20gaXMgbG9hZGVkIG11bHRpcGxlIHRpbWVzOiAnICsgbW9qb21JZCk7CiAgICByZXR1cm47CiAgfQogIG1vam8uaW50ZXJuYWwubWFya01vam9tTG9hZGVkKG1vam9tSWQpOwogIHZhciBiaW5kaW5ncyA9IG1vam87CiAgdmFyIGFzc29jaWF0ZWRCaW5kaW5ncyA9IG1vam87CiAgdmFyIGNvZGVjID0gbW9qby5pbnRlcm5hbDsKICB2YXIgdmFsaWRhdG9yID0gbW9qby5pbnRlcm5hbDsKCiAgdmFyIGV4cG9ydHMgPSBtb2pvLmludGVybmFsLmV4cG9zZU5hbWVzcGFjZSgnbWVkaWFSb3V0ZXIubW9qb20nKTsKICB2YXIgbWVkaWFfc3RhdHVzJCA9CiAgICAgIG1vam8uaW50ZXJuYWwuZXhwb3NlTmFtZXNwYWNlKCdtZWRpYVJvdXRlci5tb2pvbScpOwogIGlmIChtb2pvLmNvbmZpZy5hdXRvTG9hZE1vam9tRGVwcykgewogICAgbW9qby5pbnRlcm5hbC5sb2FkTW9qb21JZk5lY2Vzc2FyeSgKICAgICAgICAnY2hyb21lL2NvbW1vbi9tZWRpYV9yb3V0ZXIvbW9qby9tZWRpYV9zdGF0dXMubW9qb20nLCAnbWVkaWFfc3RhdHVzLm1vam9tLmpzJyk7CiAgfQogIHZhciB0aW1lJCA9CiAgICAgIG1vam8uaW50ZXJuYWwuZXhwb3NlTmFtZXNwYWNlKCdtb2pvLmNvbW1vbi5tb2pvbScpOwogIGlmIChtb2pvLmNvbmZpZy5hdXRvTG9hZE1vam9tRGVwcykgewogICAgbW9qby5pbnRlcm5hbC5sb2FkTW9qb21JZk5lY2Vzc2FyeSgKICAgICAgICAnbW9qby9jb21tb24vdGltZS5tb2pvbScsICcuLi8uLi8uLi8uLi9tb2pvL2NvbW1vbi90aW1lLm1vam9tLmpzJyk7CiAgfQoKCgogIGZ1bmN0aW9uIE1lZGlhQ29udHJvbGxlcl9QbGF5X1BhcmFtcyh2YWx1ZXMpIHsKICAgIHRoaXMuaW5pdERlZmF1bHRzXygpOwogICAgdGhpcy5pbml0RmllbGRzXyh2YWx1ZXMpOwogIH0KCgogIE1lZGlhQ29udHJvbGxlcl9QbGF5X1BhcmFtcy5wcm90b3R5cGUuaW5pdERlZmF1bHRzXyA9IGZ1bmN0aW9uKCkgewogIH07CiAgTWVkaWFDb250cm9sbGVyX1BsYXlfUGFyYW1zLnByb3RvdHlwZS5pbml0RmllbGRzXyA9IGZ1bmN0aW9uKGZpZWxkcykgewogICAgZm9yKHZhciBmaWVsZCBpbiBmaWVsZHMpIHsKICAgICAgICBpZiAodGhpcy5oYXNPd25Qcm9wZXJ0eShmaWVsZCkpCiAgICAgICAgICB0aGlzW2ZpZWxkXSA9IGZpZWxkc1tmaWVsZF07CiAgICB9CiAgfTsKCiAgTWVkaWFDb250cm9sbGVyX1BsYXlfUGFyYW1zLnZhbGlkYXRlID0gZnVuY3Rpb24obWVzc2FnZVZhbGlkYXRvciwgb2Zmc2V0KSB7CiAgICB2YXIgZXJyOwogICAgZXJyID0gbWVzc2FnZVZhbGlkYXRvci52YWxpZGF0ZVN0cnVjdEhlYWRlcihvZmZzZXQsIGNvZGVjLmtTdHJ1Y3RIZWFkZXJTaXplKTsKICAgIGlmIChlcnIgIT09IHZhbGlkYXRvci52YWxpZGF0aW9uRXJyb3IuTk9ORSkKICAgICAgICByZXR1cm4gZXJyOwoKICAgIHZhciBrVmVyc2lvblNpemVzID0gWwogICAgICB7dmVyc2lvbjogMCwgbnVtQnl0ZXM6IDh9CiAgICBdOwogICAgZXJyID0gbWVzc2FnZVZhbGlkYXRvci52YWxpZGF0ZVN0cnVjdFZlcnNpb24ob2Zmc2V0LCBrVmVyc2lvblNpemVzKTsKICAgIGlmIChlcnIgIT09IHZhbGlkYXRvci52YWxpZGF0aW9uRXJyb3IuTk9ORSkKICAgICAgICByZXR1cm4gZXJyOwoKICAgIHJldHVybiB2YWxpZGF0b3IudmFsaWRhdGlvbkVycm9yLk5PTkU7CiAgfTsKCiAgTWVkaWFDb250cm9sbGVyX1BsYXlfUGFyYW1zLmVuY29kZWRTaXplID0gY29kZWMua1N0cnVjdEhlYWRlclNpemUgKyAwOwoKICBNZWRpYUNvbnRyb2xsZXJfUGxheV9QYXJhbXMuZGVjb2RlID0gZnVuY3Rpb24oZGVjb2RlcikgewogICAgdmFyIHBhY2tlZDsKICAgIHZhciB2YWwgPSBuZXcgTWVkaWFDb250cm9sbGVyX1BsYXlfUGFyYW1zKCk7CiAgICB2YXIgbnVtYmVyT2ZCeXRlcyA9IGRlY29kZXIucmVhZFVpbnQzMigpOwogICAgdmFyIHZlcnNpb24gPSBkZWNvZGVyLnJlYWRVaW50MzIoKTsKICAgIHJldHVybiB2YWw7CiAgfTsKCiAgTWVkaWFDb250cm9sbGVyX1BsYXlfUGFyYW1zLmVuY29kZSA9IGZ1bmN0aW9uKGVuY29kZXIsIHZhbCkgewogICAgdmFyIHBhY2tlZDsKICAgIGVuY29kZXIud3JpdGVVaW50MzIoTWVkaWFDb250cm9sbGVyX1BsYXlfUGFyYW1zLmVuY29kZWRTaXplKTsKICAgIGVuY29kZXIud3JpdGVVaW50MzIoMCk7CiAgfTsKICBmdW5jdGlvbiBNZWRpYUNvbnRyb2xsZXJfUGF1c2VfUGFyYW1zKHZhbHVlcykgewogICAgdGhpcy5pbml0RGVmYXVsdHNfKCk7CiAgICB0aGlzLmluaXRGaWVsZHNfKHZhbHVlcyk7CiAgfQoKCiAgTWVkaWFDb250cm9sbGVyX1BhdXNlX1BhcmFtcy5wcm90b3R5cGUuaW5pdERlZmF1bHRzXyA9IGZ1bmN0aW9uKCkgewogIH07CiAgTWVkaWFDb250cm9sbGVyX1BhdXNlX1BhcmFtcy5wcm90b3R5cGUuaW5pdEZpZWxkc18gPSBmdW5jdGlvbihmaWVsZHMpIHsKICAgIGZvcih2YXIgZmllbGQgaW4gZmllbGRzKSB7CiAgICAgICAgaWYgKHRoaXMuaGFzT3duUHJvcGVydHkoZmllbGQpKQogICAgICAgICAgdGhpc1tmaWVsZF0gPSBmaWVsZHNbZmllbGRdOwogICAgfQogIH07CgogIE1lZGlhQ29udHJvbGxlcl9QYXVzZV9QYXJhbXMudmFsaWRhdGUgPSBmdW5jdGlvbihtZXNzYWdlVmFsaWRhdG9yLCBvZmZzZXQpIHsKICAgIHZhciBlcnI7CiAgICBlcnIgPSBtZXNzYWdlVmFsaWRhdG9yLnZhbGlkYXRlU3RydWN0SGVhZGVyKG9mZnNldCwgY29kZWMua1N0cnVjdEhlYWRlclNpemUpOwogICAgaWYgKGVyciAhPT0gdmFsaWRhdG9yLnZhbGlkYXRpb25FcnJvci5OT05FKQogICAgICAgIHJldHVybiBlcnI7CgogICAgdmFyIGtWZXJzaW9uU2l6ZXMgPSBbCiAgICAgIHt2ZXJzaW9uOiAwLCBudW1CeXRlczogOH0KICAgIF07CiAgICBlcnIgPSBtZXNzYWdlVmFsaWRhdG9yLnZhbGlkYXRlU3RydWN0VmVyc2lvbihvZmZzZXQsIGtWZXJzaW9uU2l6ZXMpOwogICAgaWYgKGVyciAhPT0gdmFsaWRhdG9yLnZhbGlkYXRpb25FcnJvci5OT05FKQogICAgICAgIHJldHVybiBlcnI7CgogICAgcmV0dXJuIHZhbGlkYXRvci52YWxpZGF0aW9uRXJyb3IuTk9ORTsKICB9OwoKICBNZWRpYUNvbnRyb2xsZXJfUGF1c2VfUGFyYW1zLmVuY29kZWRTaXplID0gY29kZWMua1N0cnVjdEhlYWRlclNpemUgKyAwOwoKICBNZWRpYUNvbnRyb2xsZXJfUGF1c2VfUGFyYW1zLmRlY29kZSA9IGZ1bmN0aW9uKGRlY29kZXIpIHsKICAgIHZhciBwYWNrZWQ7CiAgICB2YXIgdmFsID0gbmV3IE1lZGlhQ29udHJvbGxlcl9QYXVzZV9QYXJhbXMoKTsKICAgIHZhciBudW1iZXJPZkJ5dGVzID0gZGVjb2Rlci5yZWFkVWludDMyKCk7CiAgICB2YXIgdmVyc2lvbiA9IGRlY29kZXIucmVhZFVpbnQzMigpOwogICAgcmV0dXJuIHZhbDsKICB9OwoKICBNZWRpYUNvbnRyb2xsZXJfUGF1c2VfUGFyYW1zLmVuY29kZSA9IGZ1bmN0aW9uKGVuY29kZXIsIHZhbCkgewogICAgdmFyIHBhY2tlZDsKICAgIGVuY29kZXIud3JpdGVVaW50MzIoTWVkaWFDb250cm9sbGVyX1BhdXNlX1BhcmFtcy5lbmNvZGVkU2l6ZSk7CiAgICBlbmNvZGVyLndyaXRlVWludDMyKDApOwogIH07CiAgZnVuY3Rpb24gTWVkaWFDb250cm9sbGVyX1NldE11dGVfUGFyYW1zKHZhbHVlcykgewogICAgdGhpcy5pbml0RGVmYXVsdHNfKCk7CiAgICB0aGlzLmluaXRGaWVsZHNfKHZhbHVlcyk7CiAgfQoKCiAgTWVkaWFDb250cm9sbGVyX1NldE11dGVfUGFyYW1zLnByb3RvdHlwZS5pbml0RGVmYXVsdHNfID0gZnVuY3Rpb24oKSB7CiAgICB0aGlzLm11dGUgPSBmYWxzZTsKICB9OwogIE1lZGlhQ29udHJvbGxlcl9TZXRNdXRlX1BhcmFtcy5wcm90b3R5cGUuaW5pdEZpZWxkc18gPSBmdW5jdGlvbihmaWVsZHMpIHsKICAgIGZvcih2YXIgZmllbGQgaW4gZmllbGRzKSB7CiAgICAgICAgaWYgKHRoaXMuaGFzT3duUHJvcGVydHkoZmllbGQpKQogICAgICAgICAgdGhpc1tmaWVsZF0gPSBmaWVsZHNbZmllbGRdOwogICAgfQogIH07CgogIE1lZGlhQ29udHJvbGxlcl9TZXRNdXRlX1BhcmFtcy52YWxpZGF0ZSA9IGZ1bmN0aW9uKG1lc3NhZ2VWYWxpZGF0b3IsIG9mZnNldCkgewogICAgdmFyIGVycjsKICAgIGVyciA9IG1lc3NhZ2VWYWxpZGF0b3IudmFsaWRhdGVTdHJ1Y3RIZWFkZXIob2Zmc2V0LCBjb2RlYy5rU3RydWN0SGVhZGVyU2l6ZSk7CiAgICBpZiAoZXJyICE9PSB2YWxpZGF0b3IudmFsaWRhdGlvbkVycm9yLk5PTkUpCiAgICAgICAgcmV0dXJuIGVycjsKCiAgICB2YXIga1ZlcnNpb25TaXplcyA9IFsKICAgICAge3ZlcnNpb246IDAsIG51bUJ5dGVzOiAxNn0KICAgIF07CiAgICBlcnIgPSBtZXNzYWdlVmFsaWRhdG9yLnZhbGlkYXRlU3RydWN0VmVyc2lvbihvZmZzZXQsIGtWZXJzaW9uU2l6ZXMpOwogICAgaWYgKGVyciAhPT0gdmFsaWRhdG9yLnZhbGlkYXRpb25FcnJvci5OT05FKQogICAgICAgIHJldHVybiBlcnI7CgoKICAgIHJldHVybiB2YWxpZGF0b3IudmFsaWRhdGlvbkVycm9yLk5PTkU7CiAgfTsKCiAgTWVkaWFDb250cm9sbGVyX1NldE11dGVfUGFyYW1zLmVuY29kZWRTaXplID0gY29kZWMua1N0cnVjdEhlYWRlclNpemUgKyA4OwoKICBNZWRpYUNvbnRyb2xsZXJfU2V0TXV0ZV9QYXJhbXMuZGVjb2RlID0gZnVuY3Rpb24oZGVjb2RlcikgewogICAgdmFyIHBhY2tlZDsKICAgIHZhciB2YWwgPSBuZXcgTWVkaWFDb250cm9sbGVyX1NldE11dGVfUGFyYW1zKCk7CiAgICB2YXIgbnVtYmVyT2ZCeXRlcyA9IGRlY29kZXIucmVhZFVpbnQzMigpOwogICAgdmFyIHZlcnNpb24gPSBkZWNvZGVyLnJlYWRVaW50MzIoKTsKICAgIHBhY2tlZCA9IGRlY29kZXIucmVhZFVpbnQ4KCk7CiAgICB2YWwubXV0ZSA9IChwYWNrZWQgPj4gMCkgJiAxID8gdHJ1ZSA6IGZhbHNlOwogICAgZGVjb2Rlci5za2lwKDEpOwogICAgZGVjb2Rlci5za2lwKDEpOwogICAgZGVjb2Rlci5za2lwKDEpOwogICAgZGVjb2Rlci5za2lwKDEpOwogICAgZGVjb2Rlci5za2lwKDEpOwogICAgZGVjb2Rlci5za2lwKDEpOwogICAgZGVjb2Rlci5za2lwKDEpOwogICAgcmV0dXJuIHZhbDsKICB9OwoKICBNZWRpYUNvbnRyb2xsZXJfU2V0TXV0ZV9QYXJhbXMuZW5jb2RlID0gZnVuY3Rpb24oZW5jb2RlciwgdmFsKSB7CiAgICB2YXIgcGFja2VkOwogICAgZW5jb2Rlci53cml0ZVVpbnQzMihNZWRpYUNvbnRyb2xsZXJfU2V0TXV0ZV9QYXJhbXMuZW5jb2RlZFNpemUpOwogICAgZW5jb2Rlci53cml0ZVVpbnQzMigwKTsKICAgIHBhY2tlZCA9IDA7CiAgICBwYWNrZWQgfD0gKHZhbC5tdXRlICYgMSkgPDwgMAogICAgZW5jb2Rlci53cml0ZVVpbnQ4KHBhY2tlZCk7CiAgICBlbmNvZGVyLnNraXAoMSk7CiAgICBlbmNvZGVyLnNraXAoMSk7CiAgICBlbmNvZGVyLnNraXAoMSk7CiAgICBlbmNvZGVyLnNraXAoMSk7CiAgICBlbmNvZGVyLnNraXAoMSk7CiAgICBlbmNvZGVyLnNraXAoMSk7CiAgICBlbmNvZGVyLnNraXAoMSk7CiAgfTsKICBmdW5jdGlvbiBNZWRpYUNvbnRyb2xsZXJfU2V0Vm9sdW1lX1BhcmFtcyh2YWx1ZXMpIHsKICAgIHRoaXMuaW5pdERlZmF1bHRzXygpOwogICAgdGhpcy5pbml0RmllbGRzXyh2YWx1ZXMpOwogIH0KCgogIE1lZGlhQ29udHJvbGxlcl9TZXRWb2x1bWVfUGFyYW1zLnByb3RvdHlwZS5pbml0RGVmYXVsdHNfID0gZnVuY3Rpb24oKSB7CiAgICB0aGlzLnZvbHVtZSA9IDA7CiAgfTsKICBNZWRpYUNvbnRyb2xsZXJfU2V0Vm9sdW1lX1BhcmFtcy5wcm90b3R5cGUuaW5pdEZpZWxkc18gPSBmdW5jdGlvbihmaWVsZHMpIHsKICAgIGZvcih2YXIgZmllbGQgaW4gZmllbGRzKSB7CiAgICAgICAgaWYgKHRoaXMuaGFzT3duUHJvcGVydHkoZmllbGQpKQogICAgICAgICAgdGhpc1tmaWVsZF0gPSBmaWVsZHNbZmllbGRdOwogICAgfQogIH07CgogIE1lZGlhQ29udHJvbGxlcl9TZXRWb2x1bWVfUGFyYW1zLnZhbGlkYXRlID0gZnVuY3Rpb24obWVzc2FnZVZhbGlkYXRvciwgb2Zmc2V0KSB7CiAgICB2YXIgZXJyOwogICAgZXJyID0gbWVzc2FnZVZhbGlkYXRvci52YWxpZGF0ZVN0cnVjdEhlYWRlcihvZmZzZXQsIGNvZGVjLmtTdHJ1Y3RIZWFkZXJTaXplKTsKICAgIGlmIChlcnIgIT09IHZhbGlkYXRvci52YWxpZGF0aW9uRXJyb3IuTk9ORSkKICAgICAgICByZXR1cm4gZXJyOwoKICAgIHZhciBrVmVyc2lvblNpemVzID0gWwogICAgICB7dmVyc2lvbjogMCwgbnVtQnl0ZXM6IDE2fQogICAgXTsKICAgIGVyciA9IG1lc3NhZ2VWYWxpZGF0b3IudmFsaWRhdGVTdHJ1Y3RWZXJzaW9uKG9mZnNldCwga1ZlcnNpb25TaXplcyk7CiAgICBpZiAoZXJyICE9PSB2YWxpZGF0b3IudmFsaWRhdGlvbkVycm9yLk5PTkUpCiAgICAgICAgcmV0dXJuIGVycjsKCgogICAgcmV0dXJuIHZhbGlkYXRvci52YWxpZGF0aW9uRXJyb3IuTk9ORTsKICB9OwoKICBNZWRpYUNvbnRyb2xsZXJfU2V0Vm9sdW1lX1BhcmFtcy5lbmNvZGVkU2l6ZSA9IGNvZGVjLmtTdHJ1Y3RIZWFkZXJTaXplICsgODsKCiAgTWVkaWFDb250cm9sbGVyX1NldFZvbHVtZV9QYXJhbXMuZGVjb2RlID0gZnVuY3Rpb24oZGVjb2RlcikgewogICAgdmFyIHBhY2tlZDsKICAgIHZhciB2YWwgPSBuZXcgTWVkaWFDb250cm9sbGVyX1NldFZvbHVtZV9QYXJhbXMoKTsKICAgIHZhciBudW1iZXJPZkJ5dGVzID0gZGVjb2Rlci5yZWFkVWludDMyKCk7CiAgICB2YXIgdmVyc2lvbiA9IGRlY29kZXIucmVhZFVpbnQzMigpOwogICAgdmFsLnZvbHVtZSA9IGRlY29kZXIuZGVjb2RlU3RydWN0KGNvZGVjLkZsb2F0KTsKICAgIGRlY29kZXIuc2tpcCgxKTsKICAgIGRlY29kZXIuc2tpcCgxKTsKICAgIGRlY29kZXIuc2tpcCgxKTsKICAgIGRlY29kZXIuc2tpcCgxKTsKICAgIHJldHVybiB2YWw7CiAgfTsKCiAgTWVkaWFDb250cm9sbGVyX1NldFZvbHVtZV9QYXJhbXMuZW5jb2RlID0gZnVuY3Rpb24oZW5jb2RlciwgdmFsKSB7CiAgICB2YXIgcGFja2VkOwogICAgZW5jb2Rlci53cml0ZVVpbnQzMihNZWRpYUNvbnRyb2xsZXJfU2V0Vm9sdW1lX1BhcmFtcy5lbmNvZGVkU2l6ZSk7CiAgICBlbmNvZGVyLndyaXRlVWludDMyKDApOwogICAgZW5jb2Rlci5lbmNvZGVTdHJ1Y3QoY29kZWMuRmxvYXQsIHZhbC52b2x1bWUpOwogICAgZW5jb2Rlci5za2lwKDEpOwogICAgZW5jb2Rlci5za2lwKDEpOwogICAgZW5jb2Rlci5za2lwKDEpOwogICAgZW5jb2Rlci5za2lwKDEpOwogIH07CiAgZnVuY3Rpb24gTWVkaWFDb250cm9sbGVyX1NlZWtfUGFyYW1zKHZhbHVlcykgewogICAgdGhpcy5pbml0RGVmYXVsdHNfKCk7CiAgICB0aGlzLmluaXRGaWVsZHNfKHZhbHVlcyk7CiAgfQoKCiAgTWVkaWFDb250cm9sbGVyX1NlZWtfUGFyYW1zLnByb3RvdHlwZS5pbml0RGVmYXVsdHNfID0gZnVuY3Rpb24oKSB7CiAgICB0aGlzLnRpbWUgPSBudWxsOwogIH07CiAgTWVkaWFDb250cm9sbGVyX1NlZWtfUGFyYW1zLnByb3RvdHlwZS5pbml0RmllbGRzXyA9IGZ1bmN0aW9uKGZpZWxkcykgewogICAgZm9yKHZhciBmaWVsZCBpbiBmaWVsZHMpIHsKICAgICAgICBpZiAodGhpcy5oYXNPd25Qcm9wZXJ0eShmaWVsZCkpCiAgICAgICAgICB0aGlzW2ZpZWxkXSA9IGZpZWxkc1tmaWVsZF07CiAgICB9CiAgfTsKCiAgTWVkaWFDb250cm9sbGVyX1NlZWtfUGFyYW1zLnZhbGlkYXRlID0gZnVuY3Rpb24obWVzc2FnZVZhbGlkYXRvciwgb2Zmc2V0KSB7CiAgICB2YXIgZXJyOwogICAgZXJyID0gbWVzc2FnZVZhbGlkYXRvci52YWxpZGF0ZVN0cnVjdEhlYWRlcihvZmZzZXQsIGNvZGVjLmtTdHJ1Y3RIZWFkZXJTaXplKTsKICAgIGlmIChlcnIgIT09IHZhbGlkYXRvci52YWxpZGF0aW9uRXJyb3IuTk9ORSkKICAgICAgICByZXR1cm4gZXJyOwoKICAgIHZhciBrVmVyc2lvblNpemVzID0gWwogICAgICB7dmVyc2lvbjogMCwgbnVtQnl0ZXM6IDE2fQogICAgXTsKICAgIGVyciA9IG1lc3NhZ2VWYWxpZGF0b3IudmFsaWRhdGVTdHJ1Y3RWZXJzaW9uKG9mZnNldCwga1ZlcnNpb25TaXplcyk7CiAgICBpZiAoZXJyICE9PSB2YWxpZGF0b3IudmFsaWRhdGlvbkVycm9yLk5PTkUpCiAgICAgICAgcmV0dXJuIGVycjsKCgogICAgLy8gdmFsaWRhdGUgTWVkaWFDb250cm9sbGVyX1NlZWtfUGFyYW1zLnRpbWUKICAgIGVyciA9IG1lc3NhZ2VWYWxpZGF0b3IudmFsaWRhdGVTdHJ1Y3RQb2ludGVyKG9mZnNldCArIGNvZGVjLmtTdHJ1Y3RIZWFkZXJTaXplICsgMCwgdGltZSQuVGltZURlbHRhLCBmYWxzZSk7CiAgICBpZiAoZXJyICE9PSB2YWxpZGF0b3IudmFsaWRhdGlvbkVycm9yLk5PTkUpCiAgICAgICAgcmV0dXJuIGVycjsKCiAgICByZXR1cm4gdmFsaWRhdG9yLnZhbGlkYXRpb25FcnJvci5OT05FOwogIH07CgogIE1lZGlhQ29udHJvbGxlcl9TZWVrX1BhcmFtcy5lbmNvZGVkU2l6ZSA9IGNvZGVjLmtTdHJ1Y3RIZWFkZXJTaXplICsgODsKCiAgTWVkaWFDb250cm9sbGVyX1NlZWtfUGFyYW1zLmRlY29kZSA9IGZ1bmN0aW9uKGRlY29kZXIpIHsKICAgIHZhciBwYWNrZWQ7CiAgICB2YXIgdmFsID0gbmV3IE1lZGlhQ29udHJvbGxlcl9TZWVrX1BhcmFtcygpOwogICAgdmFyIG51bWJlck9mQnl0ZXMgPSBkZWNvZGVyLnJlYWRVaW50MzIoKTsKICAgIHZhciB2ZXJzaW9uID0gZGVjb2Rlci5yZWFkVWludDMyKCk7CiAgICB2YWwudGltZSA9IGRlY29kZXIuZGVjb2RlU3RydWN0UG9pbnRlcih0aW1lJC5UaW1lRGVsdGEpOwogICAgcmV0dXJuIHZhbDsKICB9OwoKICBNZWRpYUNvbnRyb2xsZXJfU2Vla19QYXJhbXMuZW5jb2RlID0gZnVuY3Rpb24oZW5jb2RlciwgdmFsKSB7CiAgICB2YXIgcGFja2VkOwogICAgZW5jb2Rlci53cml0ZVVpbnQzMihNZWRpYUNvbnRyb2xsZXJfU2Vla19QYXJhbXMuZW5jb2RlZFNpemUpOwogICAgZW5jb2Rlci53cml0ZVVpbnQzMigwKTsKICAgIGVuY29kZXIuZW5jb2RlU3RydWN0UG9pbnRlcih0aW1lJC5UaW1lRGVsdGEsIHZhbC50aW1lKTsKICB9OwogIGZ1bmN0aW9uIE1lZGlhQ29udHJvbGxlcl9Db25uZWN0SGFuZ291dHNNZWRpYVJvdXRlQ29udHJvbGxlcl9QYXJhbXModmFsdWVzKSB7CiAgICB0aGlzLmluaXREZWZhdWx0c18oKTsKICAgIHRoaXMuaW5pdEZpZWxkc18odmFsdWVzKTsKICB9CgoKICBNZWRpYUNvbnRyb2xsZXJfQ29ubmVjdEhhbmdvdXRzTWVkaWFSb3V0ZUNvbnRyb2xsZXJfUGFyYW1zLnByb3RvdHlwZS5pbml0RGVmYXVsdHNfID0gZnVuY3Rpb24oKSB7CiAgICB0aGlzLmNvbnRyb2xsZXJSZXF1ZXN0ID0gbmV3IGJpbmRpbmdzLkludGVyZmFjZVJlcXVlc3QoKTsKICB9OwogIE1lZGlhQ29udHJvbGxlcl9Db25uZWN0SGFuZ291dHNNZWRpYVJvdXRlQ29udHJvbGxlcl9QYXJhbXMucHJvdG90eXBlLmluaXRGaWVsZHNfID0gZnVuY3Rpb24oZmllbGRzKSB7CiAgICBmb3IodmFyIGZpZWxkIGluIGZpZWxkcykgewogICAgICAgIGlmICh0aGlzLmhhc093blByb3BlcnR5KGZpZWxkKSkKICAgICAgICAgIHRoaXNbZmllbGRdID0gZmllbGRzW2ZpZWxkXTsKICAgIH0KICB9OwoKICBNZWRpYUNvbnRyb2xsZXJfQ29ubmVjdEhhbmdvdXRzTWVkaWFSb3V0ZUNvbnRyb2xsZXJfUGFyYW1zLnZhbGlkYXRlID0gZnVuY3Rpb24obWVzc2FnZVZhbGlkYXRvciwgb2Zmc2V0KSB7CiAgICB2YXIgZXJyOwogICAgZXJyID0gbWVzc2FnZVZhbGlkYXRvci52YWxpZGF0ZVN0cnVjdEhlYWRlcihvZmZzZXQsIGNvZGVjLmtTdHJ1Y3RIZWFkZXJTaXplKTsKICAgIGlmIChlcnIgIT09IHZhbGlkYXRvci52YWxpZGF0aW9uRXJyb3IuTk9ORSkKICAgICAgICByZXR1cm4gZXJyOwoKICAgIHZhciBrVmVyc2lvblNpemVzID0gWwogICAgICB7dmVyc2lvbjogMCwgbnVtQnl0ZXM6IDE2fQogICAgXTsKICAgIGVyciA9IG1lc3NhZ2VWYWxpZGF0b3IudmFsaWRhdGVTdHJ1Y3RWZXJzaW9uKG9mZnNldCwga1ZlcnNpb25TaXplcyk7CiAgICBpZiAoZXJyICE9PSB2YWxpZGF0b3IudmFsaWRhdGlvbkVycm9yLk5PTkUpCiAgICAgICAgcmV0dXJuIGVycjsKCgogICAgLy8gdmFsaWRhdGUgTWVkaWFDb250cm9sbGVyX0Nvbm5lY3RIYW5nb3V0c01lZGlhUm91dGVDb250cm9sbGVyX1BhcmFtcy5jb250cm9sbGVyUmVxdWVzdAogICAgZXJyID0gbWVzc2FnZVZhbGlkYXRvci52YWxpZGF0ZUludGVyZmFjZVJlcXVlc3Qob2Zmc2V0ICsgY29kZWMua1N0cnVjdEhlYWRlclNpemUgKyAwLCBmYWxzZSkKICAgIGlmIChlcnIgIT09IHZhbGlkYXRvci52YWxpZGF0aW9uRXJyb3IuTk9ORSkKICAgICAgICByZXR1cm4gZXJyOwoKICAgIHJldHVybiB2YWxpZGF0b3IudmFsaWRhdGlvbkVycm9yLk5PTkU7CiAgfTsKCiAgTWVkaWFDb250cm9sbGVyX0Nvbm5lY3RIYW5nb3V0c01lZGlhUm91dGVDb250cm9sbGVyX1BhcmFtcy5lbmNvZGVkU2l6ZSA9IGNvZGVjLmtTdHJ1Y3RIZWFkZXJTaXplICsgODsKCiAgTWVkaWFDb250cm9sbGVyX0Nvbm5lY3RIYW5nb3V0c01lZGlhUm91dGVDb250cm9sbGVyX1BhcmFtcy5kZWNvZGUgPSBmdW5jdGlvbihkZWNvZGVyKSB7CiAgICB2YXIgcGFja2VkOwogICAgdmFyIHZhbCA9IG5ldyBNZWRpYUNvbnRyb2xsZXJfQ29ubmVjdEhhbmdvdXRzTWVkaWFSb3V0ZUNvbnRyb2xsZXJfUGFyYW1zKCk7CiAgICB2YXIgbnVtYmVyT2ZCeXRlcyA9IGRlY29kZXIucmVhZFVpbnQzMigpOwogICAgdmFyIHZlcnNpb24gPSBkZWNvZGVyLnJlYWRVaW50MzIoKTsKICAgIHZhbC5jb250cm9sbGVyUmVxdWVzdCA9IGRlY29kZXIuZGVjb2RlU3RydWN0KGNvZGVjLkludGVyZmFjZVJlcXVlc3QpOwogICAgZGVjb2Rlci5za2lwKDEpOwogICAgZGVjb2Rlci5za2lwKDEpOwogICAgZGVjb2Rlci5za2lwKDEpOwogICAgZGVjb2Rlci5za2lwKDEpOwogICAgcmV0dXJuIHZhbDsKICB9OwoKICBNZWRpYUNvbnRyb2xsZXJfQ29ubmVjdEhhbmdvdXRzTWVkaWFSb3V0ZUNvbnRyb2xsZXJfUGFyYW1zLmVuY29kZSA9IGZ1bmN0aW9uKGVuY29kZXIsIHZhbCkgewogICAgdmFyIHBhY2tlZDsKICAgIGVuY29kZXIud3JpdGVVaW50MzIoTWVkaWFDb250cm9sbGVyX0Nvbm5lY3RIYW5nb3V0c01lZGlhUm91dGVDb250cm9sbGVyX1BhcmFtcy5lbmNvZGVkU2l6ZSk7CiAgICBlbmNvZGVyLndyaXRlVWludDMyKDApOwogICAgZW5jb2Rlci5lbmNvZGVTdHJ1Y3QoY29kZWMuSW50ZXJmYWNlUmVxdWVzdCwgdmFsLmNvbnRyb2xsZXJSZXF1ZXN0KTsKICAgIGVuY29kZXIuc2tpcCgxKTsKICAgIGVuY29kZXIuc2tpcCgxKTsKICAgIGVuY29kZXIuc2tpcCgxKTsKICAgIGVuY29kZXIuc2tpcCgxKTsKICB9OwogIGZ1bmN0aW9uIEhhbmdvdXRzTWVkaWFSb3V0ZUNvbnRyb2xsZXJfU2V0TG9jYWxQcmVzZW50X1BhcmFtcyh2YWx1ZXMpIHsKICAgIHRoaXMuaW5pdERlZmF1bHRzXygpOwogICAgdGhpcy5pbml0RmllbGRzXyh2YWx1ZXMpOwogIH0KCgogIEhhbmdvdXRzTWVkaWFSb3V0ZUNvbnRyb2xsZXJfU2V0TG9jYWxQcmVzZW50X1BhcmFtcy5wcm90b3R5cGUuaW5pdERlZmF1bHRzXyA9IGZ1bmN0aW9uKCkgewogICAgdGhpcy5sb2NhbFByZXNlbnQgPSBmYWxzZTsKICB9OwogIEhhbmdvdXRzTWVkaWFSb3V0ZUNvbnRyb2xsZXJfU2V0TG9jYWxQcmVzZW50X1BhcmFtcy5wcm90b3R5cGUuaW5pdEZpZWxkc18gPSBmdW5jdGlvbihmaWVsZHMpIHsKICAgIGZvcih2YXIgZmllbGQgaW4gZmllbGRzKSB7CiAgICAgICAgaWYgKHRoaXMuaGFzT3duUHJvcGVydHkoZmllbGQpKQogICAgICAgICAgdGhpc1tmaWVsZF0gPSBmaWVsZHNbZmllbGRdOwogICAgfQogIH07CgogIEhhbmdvdXRzTWVkaWFSb3V0ZUNvbnRyb2xsZXJfU2V0TG9jYWxQcmVzZW50X1BhcmFtcy52YWxpZGF0ZSA9IGZ1bmN0aW9uKG1lc3NhZ2VWYWxpZGF0b3IsIG9mZnNldCkgewogICAgdmFyIGVycjsKICAgIGVyciA9IG1lc3NhZ2VWYWxpZGF0b3IudmFsaWRhdGVTdHJ1Y3RIZWFkZXIob2Zmc2V0LCBjb2RlYy5rU3RydWN0SGVhZGVyU2l6ZSk7CiAgICBpZiAoZXJyICE9PSB2YWxpZGF0b3IudmFsaWRhdGlvbkVycm9yLk5PTkUpCiAgICAgICAgcmV0dXJuIGVycjsKCiAgICB2YXIga1ZlcnNpb25TaXplcyA9IFsKICAgICAge3ZlcnNpb246IDAsIG51bUJ5dGVzOiAxNn0KICAgIF07CiAgICBlcnIgPSBtZXNzYWdlVmFsaWRhdG9yLnZhbGlkYXRlU3RydWN0VmVyc2lvbihvZmZzZXQsIGtWZXJzaW9uU2l6ZXMpOwogICAgaWYgKGVyciAhPT0gdmFsaWRhdG9yLnZhbGlkYXRpb25FcnJvci5OT05FKQogICAgICAgIHJldHVybiBlcnI7CgoKICAgIHJldHVybiB2YWxpZGF0b3IudmFsaWRhdGlvbkVycm9yLk5PTkU7CiAgfTsKCiAgSGFuZ291dHNNZWRpYVJvdXRlQ29udHJvbGxlcl9TZXRMb2NhbFByZXNlbnRfUGFyYW1zLmVuY29kZWRTaXplID0gY29kZWMua1N0cnVjdEhlYWRlclNpemUgKyA4OwoKICBIYW5nb3V0c01lZGlhUm91dGVDb250cm9sbGVyX1NldExvY2FsUHJlc2VudF9QYXJhbXMuZGVjb2RlID0gZnVuY3Rpb24oZGVjb2RlcikgewogICAgdmFyIHBhY2tlZDsKICAgIHZhciB2YWwgPSBuZXcgSGFuZ291dHNNZWRpYVJvdXRlQ29udHJvbGxlcl9TZXRMb2NhbFByZXNlbnRfUGFyYW1zKCk7CiAgICB2YXIgbnVtYmVyT2ZCeXRlcyA9IGRlY29kZXIucmVhZFVpbnQzMigpOwogICAgdmFyIHZlcnNpb24gPSBkZWNvZGVyLnJlYWRVaW50MzIoKTsKICAgIHBhY2tlZCA9IGRlY29kZXIucmVhZFVpbnQ4KCk7CiAgICB2YWwubG9jYWxQcmVzZW50ID0gKHBhY2tlZCA+PiAwKSAmIDEgPyB0cnVlIDogZmFsc2U7CiAgICBkZWNvZGVyLnNraXAoMSk7CiAgICBkZWNvZGVyLnNraXAoMSk7CiAgICBkZWNvZGVyLnNraXAoMSk7CiAgICBkZWNvZGVyLnNraXAoMSk7CiAgICBkZWNvZGVyLnNraXAoMSk7CiAgICBkZWNvZGVyLnNraXAoMSk7CiAgICBkZWNvZGVyLnNraXAoMSk7CiAgICByZXR1cm4gdmFsOwogIH07CgogIEhhbmdvdXRzTWVkaWFSb3V0ZUNvbnRyb2xsZXJfU2V0TG9jYWxQcmVzZW50X1BhcmFtcy5lbmNvZGUgPSBmdW5jdGlvbihlbmNvZGVyLCB2YWwpIHsKICAgIHZhciBwYWNrZWQ7CiAgICBlbmNvZGVyLndyaXRlVWludDMyKEhhbmdvdXRzTWVkaWFSb3V0ZUNvbnRyb2xsZXJfU2V0TG9jYWxQcmVzZW50X1BhcmFtcy5lbmNvZGVkU2l6ZSk7CiAgICBlbmNvZGVyLndyaXRlVWludDMyKDApOwogICAgcGFja2VkID0gMDsKICAgIHBhY2tlZCB8PSAodmFsLmxvY2FsUHJlc2VudCAmIDEpIDw8IDAKICAgIGVuY29kZXIud3JpdGVVaW50OChwYWNrZWQpOwogICAgZW5jb2Rlci5za2lwKDEpOwogICAgZW5jb2Rlci5za2lwKDEpOwogICAgZW5jb2Rlci5za2lwKDEpOwogICAgZW5jb2Rlci5za2lwKDEpOwogICAgZW5jb2Rlci5za2lwKDEpOwogICAgZW5jb2Rlci5za2lwKDEpOwogICAgZW5jb2Rlci5za2lwKDEpOwogIH07CiAgdmFyIGtNZWRpYUNvbnRyb2xsZXJfUGxheV9OYW1lID0gODMwNjE5OTYyOwogIHZhciBrTWVkaWFDb250cm9sbGVyX1BhdXNlX05hbWUgPSAzMTgzODkzMzE7CiAgdmFyIGtNZWRpYUNvbnRyb2xsZXJfU2V0TXV0ZV9OYW1lID0gODY5MTQwNDcyOwogIHZhciBrTWVkaWFDb250cm9sbGVyX1NldFZvbHVtZV9OYW1lID0gMTAzMzcxMjA3OwogIHZhciBrTWVkaWFDb250cm9sbGVyX1NlZWtfTmFtZSA9IDEyNTgzMjg3MTQ7CiAgdmFyIGtNZWRpYUNvbnRyb2xsZXJfQ29ubmVjdEhhbmdvdXRzTWVkaWFSb3V0ZUNvbnRyb2xsZXJfTmFtZSA9IDIwODc0MDM4NjI7CgogIGZ1bmN0aW9uIE1lZGlhQ29udHJvbGxlclB0cihoYW5kbGVPclB0ckluZm8pIHsKICAgIHRoaXMucHRyID0gbmV3IGJpbmRpbmdzLkludGVyZmFjZVB0ckNvbnRyb2xsZXIoTWVkaWFDb250cm9sbGVyLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBoYW5kbGVPclB0ckluZm8pOwogIH0KCiAgZnVuY3Rpb24gTWVkaWFDb250cm9sbGVyQXNzb2NpYXRlZFB0cihhc3NvY2lhdGVkSW50ZXJmYWNlUHRySW5mbykgewogICAgdGhpcy5wdHIgPSBuZXcgYXNzb2NpYXRlZEJpbmRpbmdzLkFzc29jaWF0ZWRJbnRlcmZhY2VQdHJDb250cm9sbGVyKAogICAgICAgIE1lZGlhQ29udHJvbGxlciwgYXNzb2NpYXRlZEludGVyZmFjZVB0ckluZm8pOwogIH0KCiAgTWVkaWFDb250cm9sbGVyQXNzb2NpYXRlZFB0ci5wcm90b3R5cGUgPQogICAgICBPYmplY3QuY3JlYXRlKE1lZGlhQ29udHJvbGxlclB0ci5wcm90b3R5cGUpOwogIE1lZGlhQ29udHJvbGxlckFzc29jaWF0ZWRQdHIucHJvdG90eXBlLmNvbnN0cnVjdG9yID0KICAgICAgTWVkaWFDb250cm9sbGVyQXNzb2NpYXRlZFB0cjsKCiAgZnVuY3Rpb24gTWVkaWFDb250cm9sbGVyUHJveHkocmVjZWl2ZXIpIHsKICAgIHRoaXMucmVjZWl2ZXJfID0gcmVjZWl2ZXI7CiAgfQogIE1lZGlhQ29udHJvbGxlclB0ci5wcm90b3R5cGUucGxheSA9IGZ1bmN0aW9uKCkgewogICAgcmV0dXJuIE1lZGlhQ29udHJvbGxlclByb3h5LnByb3RvdHlwZS5wbGF5CiAgICAgICAgLmFwcGx5KHRoaXMucHRyLmdldFByb3h5KCksIGFyZ3VtZW50cyk7CiAgfTsKCiAgTWVkaWFDb250cm9sbGVyUHJveHkucHJvdG90eXBlLnBsYXkgPSBmdW5jdGlvbigpIHsKICAgIHZhciBwYXJhbXMgPSBuZXcgTWVkaWFDb250cm9sbGVyX1BsYXlfUGFyYW1zKCk7CiAgICB2YXIgYnVpbGRlciA9IG5ldyBjb2RlYy5NZXNzYWdlVjBCdWlsZGVyKAogICAgICAgIGtNZWRpYUNvbnRyb2xsZXJfUGxheV9OYW1lLAogICAgICAgIGNvZGVjLmFsaWduKE1lZGlhQ29udHJvbGxlcl9QbGF5X1BhcmFtcy5lbmNvZGVkU2l6ZSkpOwogICAgYnVpbGRlci5lbmNvZGVTdHJ1Y3QoTWVkaWFDb250cm9sbGVyX1BsYXlfUGFyYW1zLCBwYXJhbXMpOwogICAgdmFyIG1lc3NhZ2UgPSBidWlsZGVyLmZpbmlzaCgpOwogICAgdGhpcy5yZWNlaXZlcl8uYWNjZXB0KG1lc3NhZ2UpOwogIH07CiAgTWVkaWFDb250cm9sbGVyUHRyLnByb3RvdHlwZS5wYXVzZSA9IGZ1bmN0aW9uKCkgewogICAgcmV0dXJuIE1lZGlhQ29udHJvbGxlclByb3h5LnByb3RvdHlwZS5wYXVzZQogICAgICAgIC5hcHBseSh0aGlzLnB0ci5nZXRQcm94eSgpLCBhcmd1bWVudHMpOwogIH07CgogIE1lZGlhQ29udHJvbGxlclByb3h5LnByb3RvdHlwZS5wYXVzZSA9IGZ1bmN0aW9uKCkgewogICAgdmFyIHBhcmFtcyA9IG5ldyBNZWRpYUNvbnRyb2xsZXJfUGF1c2VfUGFyYW1zKCk7CiAgICB2YXIgYnVpbGRlciA9IG5ldyBjb2RlYy5NZXNzYWdlVjBCdWlsZGVyKAogICAgICAgIGtNZWRpYUNvbnRyb2xsZXJfUGF1c2VfTmFtZSwKICAgICAgICBjb2RlYy5hbGlnbihNZWRpYUNvbnRyb2xsZXJfUGF1c2VfUGFyYW1zLmVuY29kZWRTaXplKSk7CiAgICBidWlsZGVyLmVuY29kZVN0cnVjdChNZWRpYUNvbnRyb2xsZXJfUGF1c2VfUGFyYW1zLCBwYXJhbXMpOwogICAgdmFyIG1lc3NhZ2UgPSBidWlsZGVyLmZpbmlzaCgpOwogICAgdGhpcy5yZWNlaXZlcl8uYWNjZXB0KG1lc3NhZ2UpOwogIH07CiAgTWVkaWFDb250cm9sbGVyUHRyLnByb3RvdHlwZS5zZXRNdXRlID0gZnVuY3Rpb24oKSB7CiAgICByZXR1cm4gTWVkaWFDb250cm9sbGVyUHJveHkucHJvdG90eXBlLnNldE11dGUKICAgICAgICAuYXBwbHkodGhpcy5wdHIuZ2V0UHJveHkoKSwgYXJndW1lbnRzKTsKICB9OwoKICBNZWRpYUNvbnRyb2xsZXJQcm94eS5wcm90b3R5cGUuc2V0TXV0ZSA9IGZ1bmN0aW9uKG11dGUpIHsKICAgIHZhciBwYXJhbXMgPSBuZXcgTWVkaWFDb250cm9sbGVyX1NldE11dGVfUGFyYW1zKCk7CiAgICBwYXJhbXMubXV0ZSA9IG11dGU7CiAgICB2YXIgYnVpbGRlciA9IG5ldyBjb2RlYy5NZXNzYWdlVjBCdWlsZGVyKAogICAgICAgIGtNZWRpYUNvbnRyb2xsZXJfU2V0TXV0ZV9OYW1lLAogICAgICAgIGNvZGVjLmFsaWduKE1lZGlhQ29udHJvbGxlcl9TZXRNdXRlX1BhcmFtcy5lbmNvZGVkU2l6ZSkpOwogICAgYnVpbGRlci5lbmNvZGVTdHJ1Y3QoTWVkaWFDb250cm9sbGVyX1NldE11dGVfUGFyYW1zLCBwYXJhbXMpOwogICAgdmFyIG1lc3NhZ2UgPSBidWlsZGVyLmZpbmlzaCgpOwogICAgdGhpcy5yZWNlaXZlcl8uYWNjZXB0KG1lc3NhZ2UpOwogIH07CiAgTWVkaWFDb250cm9sbGVyUHRyLnByb3RvdHlwZS5zZXRWb2x1bWUgPSBmdW5jdGlvbigpIHsKICAgIHJldHVybiBNZWRpYUNvbnRyb2xsZXJQcm94eS5wcm90b3R5cGUuc2V0Vm9sdW1lCiAgICAgICAgLmFwcGx5KHRoaXMucHRyLmdldFByb3h5KCksIGFyZ3VtZW50cyk7CiAgfTsKCiAgTWVkaWFDb250cm9sbGVyUHJveHkucHJvdG90eXBlLnNldFZvbHVtZSA9IGZ1bmN0aW9uKHZvbHVtZSkgewogICAgdmFyIHBhcmFtcyA9IG5ldyBNZWRpYUNvbnRyb2xsZXJfU2V0Vm9sdW1lX1BhcmFtcygpOwogICAgcGFyYW1zLnZvbHVtZSA9IHZvbHVtZTsKICAgIHZhciBidWlsZGVyID0gbmV3IGNvZGVjLk1lc3NhZ2VWMEJ1aWxkZXIoCiAgICAgICAga01lZGlhQ29udHJvbGxlcl9TZXRWb2x1bWVfTmFtZSwKICAgICAgICBjb2RlYy5hbGlnbihNZWRpYUNvbnRyb2xsZXJfU2V0Vm9sdW1lX1BhcmFtcy5lbmNvZGVkU2l6ZSkpOwogICAgYnVpbGRlci5lbmNvZGVTdHJ1Y3QoTWVkaWFDb250cm9sbGVyX1NldFZvbHVtZV9QYXJhbXMsIHBhcmFtcyk7CiAgICB2YXIgbWVzc2FnZSA9IGJ1aWxkZXIuZmluaXNoKCk7CiAgICB0aGlzLnJlY2VpdmVyXy5hY2NlcHQobWVzc2FnZSk7CiAgfTsKICBNZWRpYUNvbnRyb2xsZXJQdHIucHJvdG90eXBlLnNlZWsgPSBmdW5jdGlvbigpIHsKICAgIHJldHVybiBNZWRpYUNvbnRyb2xsZXJQcm94eS5wcm90b3R5cGUuc2VlawogICAgICAgIC5hcHBseSh0aGlzLnB0ci5nZXRQcm94eSgpLCBhcmd1bWVudHMpOwogIH07CgogIE1lZGlhQ29udHJvbGxlclByb3h5LnByb3RvdHlwZS5zZWVrID0gZnVuY3Rpb24odGltZSkgewogICAgdmFyIHBhcmFtcyA9IG5ldyBNZWRpYUNvbnRyb2xsZXJfU2Vla19QYXJhbXMoKTsKICAgIHBhcmFtcy50aW1lID0gdGltZTsKICAgIHZhciBidWlsZGVyID0gbmV3IGNvZGVjLk1lc3NhZ2VWMEJ1aWxkZXIoCiAgICAgICAga01lZGlhQ29udHJvbGxlcl9TZWVrX05hbWUsCiAgICAgICAgY29kZWMuYWxpZ24oTWVkaWFDb250cm9sbGVyX1NlZWtfUGFyYW1zLmVuY29kZWRTaXplKSk7CiAgICBidWlsZGVyLmVuY29kZVN0cnVjdChNZWRpYUNvbnRyb2xsZXJfU2Vla19QYXJhbXMsIHBhcmFtcyk7CiAgICB2YXIgbWVzc2FnZSA9IGJ1aWxkZXIuZmluaXNoKCk7CiAgICB0aGlzLnJlY2VpdmVyXy5hY2NlcHQobWVzc2FnZSk7CiAgfTsKICBNZWRpYUNvbnRyb2xsZXJQdHIucHJvdG90eXBlLmNvbm5lY3RIYW5nb3V0c01lZGlhUm91dGVDb250cm9sbGVyID0gZnVuY3Rpb24oKSB7CiAgICByZXR1cm4gTWVkaWFDb250cm9sbGVyUHJveHkucHJvdG90eXBlLmNvbm5lY3RIYW5nb3V0c01lZGlhUm91dGVDb250cm9sbGVyCiAgICAgICAgLmFwcGx5KHRoaXMucHRyLmdldFByb3h5KCksIGFyZ3VtZW50cyk7CiAgfTsKCiAgTWVkaWFDb250cm9sbGVyUHJveHkucHJvdG90eXBlLmNvbm5lY3RIYW5nb3V0c01lZGlhUm91dGVDb250cm9sbGVyID0gZnVuY3Rpb24oY29udHJvbGxlclJlcXVlc3QpIHsKICAgIHZhciBwYXJhbXMgPSBuZXcgTWVkaWFDb250cm9sbGVyX0Nvbm5lY3RIYW5nb3V0c01lZGlhUm91dGVDb250cm9sbGVyX1BhcmFtcygpOwogICAgcGFyYW1zLmNvbnRyb2xsZXJSZXF1ZXN0ID0gY29udHJvbGxlclJlcXVlc3Q7CiAgICB2YXIgYnVpbGRlciA9IG5ldyBjb2RlYy5NZXNzYWdlVjBCdWlsZGVyKAogICAgICAgIGtNZWRpYUNvbnRyb2xsZXJfQ29ubmVjdEhhbmdvdXRzTWVkaWFSb3V0ZUNvbnRyb2xsZXJfTmFtZSwKICAgICAgICBjb2RlYy5hbGlnbihNZWRpYUNvbnRyb2xsZXJfQ29ubmVjdEhhbmdvdXRzTWVkaWFSb3V0ZUNvbnRyb2xsZXJfUGFyYW1zLmVuY29kZWRTaXplKSk7CiAgICBidWlsZGVyLmVuY29kZVN0cnVjdChNZWRpYUNvbnRyb2xsZXJfQ29ubmVjdEhhbmdvdXRzTWVkaWFSb3V0ZUNvbnRyb2xsZXJfUGFyYW1zLCBwYXJhbXMpOwogICAgdmFyIG1lc3NhZ2UgPSBidWlsZGVyLmZpbmlzaCgpOwogICAgdGhpcy5yZWNlaXZlcl8uYWNjZXB0KG1lc3NhZ2UpOwogIH07CgogIGZ1bmN0aW9uIE1lZGlhQ29udHJvbGxlclN0dWIoZGVsZWdhdGUpIHsKICAgIHRoaXMuZGVsZWdhdGVfID0gZGVsZWdhdGU7CiAgfQogIE1lZGlhQ29udHJvbGxlclN0dWIucHJvdG90eXBlLnBsYXkgPSBmdW5jdGlvbigpIHsKICAgIHJldHVybiB0aGlzLmRlbGVnYXRlXyAmJiB0aGlzLmRlbGVnYXRlXy5wbGF5ICYmIHRoaXMuZGVsZWdhdGVfLnBsYXkoKTsKICB9CiAgTWVkaWFDb250cm9sbGVyU3R1Yi5wcm90b3R5cGUucGF1c2UgPSBmdW5jdGlvbigpIHsKICAgIHJldHVybiB0aGlzLmRlbGVnYXRlXyAmJiB0aGlzLmRlbGVnYXRlXy5wYXVzZSAmJiB0aGlzLmRlbGVnYXRlXy5wYXVzZSgpOwogIH0KICBNZWRpYUNvbnRyb2xsZXJTdHViLnByb3RvdHlwZS5zZXRNdXRlID0gZnVuY3Rpb24obXV0ZSkgewogICAgcmV0dXJuIHRoaXMuZGVsZWdhdGVfICYmIHRoaXMuZGVsZWdhdGVfLnNldE11dGUgJiYgdGhpcy5kZWxlZ2F0ZV8uc2V0TXV0ZShtdXRlKTsKICB9CiAgTWVkaWFDb250cm9sbGVyU3R1Yi5wcm90b3R5cGUuc2V0Vm9sdW1lID0gZnVuY3Rpb24odm9sdW1lKSB7CiAgICByZXR1cm4gdGhpcy5kZWxlZ2F0ZV8gJiYgdGhpcy5kZWxlZ2F0ZV8uc2V0Vm9sdW1lICYmIHRoaXMuZGVsZWdhdGVfLnNldFZvbHVtZSh2b2x1bWUpOwogIH0KICBNZWRpYUNvbnRyb2xsZXJTdHViLnByb3RvdHlwZS5zZWVrID0gZnVuY3Rpb24odGltZSkgewogICAgcmV0dXJuIHRoaXMuZGVsZWdhdGVfICYmIHRoaXMuZGVsZWdhdGVfLnNlZWsgJiYgdGhpcy5kZWxlZ2F0ZV8uc2Vlayh0aW1lKTsKICB9CiAgTWVkaWFDb250cm9sbGVyU3R1Yi5wcm90b3R5cGUuY29ubmVjdEhhbmdvdXRzTWVkaWFSb3V0ZUNvbnRyb2xsZXIgPSBmdW5jdGlvbihjb250cm9sbGVyUmVxdWVzdCkgewogICAgcmV0dXJuIHRoaXMuZGVsZWdhdGVfICYmIHRoaXMuZGVsZWdhdGVfLmNvbm5lY3RIYW5nb3V0c01lZGlhUm91dGVDb250cm9sbGVyICYmIHRoaXMuZGVsZWdhdGVfLmNvbm5lY3RIYW5nb3V0c01lZGlhUm91dGVDb250cm9sbGVyKGNvbnRyb2xsZXJSZXF1ZXN0KTsKICB9CgogIE1lZGlhQ29udHJvbGxlclN0dWIucHJvdG90eXBlLmFjY2VwdCA9IGZ1bmN0aW9uKG1lc3NhZ2UpIHsKICAgIHZhciByZWFkZXIgPSBuZXcgY29kZWMuTWVzc2FnZVJlYWRlcihtZXNzYWdlKTsKICAgIHN3aXRjaCAocmVhZGVyLm1lc3NhZ2VOYW1lKSB7CiAgICBjYXNlIGtNZWRpYUNvbnRyb2xsZXJfUGxheV9OYW1lOgogICAgICB2YXIgcGFyYW1zID0gcmVhZGVyLmRlY29kZVN0cnVjdChNZWRpYUNvbnRyb2xsZXJfUGxheV9QYXJhbXMpOwogICAgICB0aGlzLnBsYXkoKTsKICAgICAgcmV0dXJuIHRydWU7CiAgICBjYXNlIGtNZWRpYUNvbnRyb2xsZXJfUGF1c2VfTmFtZToKICAgICAgdmFyIHBhcmFtcyA9IHJlYWRlci5kZWNvZGVTdHJ1Y3QoTWVkaWFDb250cm9sbGVyX1BhdXNlX1BhcmFtcyk7CiAgICAgIHRoaXMucGF1c2UoKTsKICAgICAgcmV0dXJuIHRydWU7CiAgICBjYXNlIGtNZWRpYUNvbnRyb2xsZXJfU2V0TXV0ZV9OYW1lOgogICAgICB2YXIgcGFyYW1zID0gcmVhZGVyLmRlY29kZVN0cnVjdChNZWRpYUNvbnRyb2xsZXJfU2V0TXV0ZV9QYXJhbXMpOwogICAgICB0aGlzLnNldE11dGUocGFyYW1zLm11dGUpOwogICAgICByZXR1cm4gdHJ1ZTsKICAgIGNhc2Uga01lZGlhQ29udHJvbGxlcl9TZXRWb2x1bWVfTmFtZToKICAgICAgdmFyIHBhcmFtcyA9IHJlYWRlci5kZWNvZGVTdHJ1Y3QoTWVkaWFDb250cm9sbGVyX1NldFZvbHVtZV9QYXJhbXMpOwogICAgICB0aGlzLnNldFZvbHVtZShwYXJhbXMudm9sdW1lKTsKICAgICAgcmV0dXJuIHRydWU7CiAgICBjYXNlIGtNZWRpYUNvbnRyb2xsZXJfU2Vla19OYW1lOgogICAgICB2YXIgcGFyYW1zID0gcmVhZGVyLmRlY29kZVN0cnVjdChNZWRpYUNvbnRyb2xsZXJfU2Vla19QYXJhbXMpOwogICAgICB0aGlzLnNlZWsocGFyYW1zLnRpbWUpOwogICAgICByZXR1cm4gdHJ1ZTsKICAgIGNhc2Uga01lZGlhQ29udHJvbGxlcl9Db25uZWN0SGFuZ291dHNNZWRpYVJvdXRlQ29udHJvbGxlcl9OYW1lOgogICAgICB2YXIgcGFyYW1zID0gcmVhZGVyLmRlY29kZVN0cnVjdChNZWRpYUNvbnRyb2xsZXJfQ29ubmVjdEhhbmdvdXRzTWVkaWFSb3V0ZUNvbnRyb2xsZXJfUGFyYW1zKTsKICAgICAgdGhpcy5jb25uZWN0SGFuZ291dHNNZWRpYVJvdXRlQ29udHJvbGxlcihwYXJhbXMuY29udHJvbGxlclJlcXVlc3QpOwogICAgICByZXR1cm4gdHJ1ZTsKICAgIGRlZmF1bHQ6CiAgICAgIHJldHVybiBmYWxzZTsKICAgIH0KICB9OwoKICBNZWRpYUNvbnRyb2xsZXJTdHViLnByb3RvdHlwZS5hY2NlcHRXaXRoUmVzcG9uZGVyID0KICAgICAgZnVuY3Rpb24obWVzc2FnZSwgcmVzcG9uZGVyKSB7CiAgICB2YXIgcmVhZGVyID0gbmV3IGNvZGVjLk1lc3NhZ2VSZWFkZXIobWVzc2FnZSk7CiAgICBzd2l0Y2ggKHJlYWRlci5tZXNzYWdlTmFtZSkgewogICAgZGVmYXVsdDoKICAgICAgcmV0dXJuIGZhbHNlOwogICAgfQogIH07CgogIGZ1bmN0aW9uIHZhbGlkYXRlTWVkaWFDb250cm9sbGVyUmVxdWVzdChtZXNzYWdlVmFsaWRhdG9yKSB7CiAgICB2YXIgbWVzc2FnZSA9IG1lc3NhZ2VWYWxpZGF0b3IubWVzc2FnZTsKICAgIHZhciBwYXJhbXNDbGFzcyA9IG51bGw7CiAgICBzd2l0Y2ggKG1lc3NhZ2UuZ2V0TmFtZSgpKSB7CiAgICAgIGNhc2Uga01lZGlhQ29udHJvbGxlcl9QbGF5X05hbWU6CiAgICAgICAgaWYgKCFtZXNzYWdlLmV4cGVjdHNSZXNwb25zZSgpICYmICFtZXNzYWdlLmlzUmVzcG9uc2UoKSkKICAgICAgICAgIHBhcmFtc0NsYXNzID0gTWVkaWFDb250cm9sbGVyX1BsYXlfUGFyYW1zOwogICAgICBicmVhazsKICAgICAgY2FzZSBrTWVkaWFDb250cm9sbGVyX1BhdXNlX05hbWU6CiAgICAgICAgaWYgKCFtZXNzYWdlLmV4cGVjdHNSZXNwb25zZSgpICYmICFtZXNzYWdlLmlzUmVzcG9uc2UoKSkKICAgICAgICAgIHBhcmFtc0NsYXNzID0gTWVkaWFDb250cm9sbGVyX1BhdXNlX1BhcmFtczsKICAgICAgYnJlYWs7CiAgICAgIGNhc2Uga01lZGlhQ29udHJvbGxlcl9TZXRNdXRlX05hbWU6CiAgICAgICAgaWYgKCFtZXNzYWdlLmV4cGVjdHNSZXNwb25zZSgpICYmICFtZXNzYWdlLmlzUmVzcG9uc2UoKSkKICAgICAgICAgIHBhcmFtc0NsYXNzID0gTWVkaWFDb250cm9sbGVyX1NldE11dGVfUGFyYW1zOwogICAgICBicmVhazsKICAgICAgY2FzZSBrTWVkaWFDb250cm9sbGVyX1NldFZvbHVtZV9OYW1lOgogICAgICAgIGlmICghbWVzc2FnZS5leHBlY3RzUmVzcG9uc2UoKSAmJiAhbWVzc2FnZS5pc1Jlc3BvbnNlKCkpCiAgICAgICAgICBwYXJhbXNDbGFzcyA9IE1lZGlhQ29udHJvbGxlcl9TZXRWb2x1bWVfUGFyYW1zOwogICAgICBicmVhazsKICAgICAgY2FzZSBrTWVkaWFDb250cm9sbGVyX1NlZWtfTmFtZToKICAgICAgICBpZiAoIW1lc3NhZ2UuZXhwZWN0c1Jlc3BvbnNlKCkgJiYgIW1lc3NhZ2UuaXNSZXNwb25zZSgpKQogICAgICAgICAgcGFyYW1zQ2xhc3MgPSBNZWRpYUNvbnRyb2xsZXJfU2Vla19QYXJhbXM7CiAgICAgIGJyZWFrOwogICAgICBjYXNlIGtNZWRpYUNvbnRyb2xsZXJfQ29ubmVjdEhhbmdvdXRzTWVkaWFSb3V0ZUNvbnRyb2xsZXJfTmFtZToKICAgICAgICBpZiAoIW1lc3NhZ2UuZXhwZWN0c1Jlc3BvbnNlKCkgJiYgIW1lc3NhZ2UuaXNSZXNwb25zZSgpKQogICAgICAgICAgcGFyYW1zQ2xhc3MgPSBNZWRpYUNvbnRyb2xsZXJfQ29ubmVjdEhhbmdvdXRzTWVkaWFSb3V0ZUNvbnRyb2xsZXJfUGFyYW1zOwogICAgICBicmVhazsKICAgIH0KICAgIGlmIChwYXJhbXNDbGFzcyA9PT0gbnVsbCkKICAgICAgcmV0dXJuIHZhbGlkYXRvci52YWxpZGF0aW9uRXJyb3IuTk9ORTsKICAgIHJldHVybiBwYXJhbXNDbGFzcy52YWxpZGF0ZShtZXNzYWdlVmFsaWRhdG9yLCBtZXNzYWdlVmFsaWRhdG9yLm1lc3NhZ2UuZ2V0SGVhZGVyTnVtQnl0ZXMoKSk7CiAgfQoKICBmdW5jdGlvbiB2YWxpZGF0ZU1lZGlhQ29udHJvbGxlclJlc3BvbnNlKG1lc3NhZ2VWYWxpZGF0b3IpIHsKICAgIHJldHVybiB2YWxpZGF0b3IudmFsaWRhdGlvbkVycm9yLk5PTkU7CiAgfQoKICB2YXIgTWVkaWFDb250cm9sbGVyID0gewogICAgbmFtZTogJ21lZGlhX3JvdXRlcjo6bW9qb206Ok1lZGlhQ29udHJvbGxlcicsCiAgICBrVmVyc2lvbjogMCwKICAgIHB0ckNsYXNzOiBNZWRpYUNvbnRyb2xsZXJQdHIsCiAgICBwcm94eUNsYXNzOiBNZWRpYUNvbnRyb2xsZXJQcm94eSwKICAgIHN0dWJDbGFzczogTWVkaWFDb250cm9sbGVyU3R1YiwKICAgIHZhbGlkYXRlUmVxdWVzdDogdmFsaWRhdGVNZWRpYUNvbnRyb2xsZXJSZXF1ZXN0LAogICAgdmFsaWRhdGVSZXNwb25zZTogbnVsbCwKICB9OwogIE1lZGlhQ29udHJvbGxlclN0dWIucHJvdG90eXBlLnZhbGlkYXRvciA9IHZhbGlkYXRlTWVkaWFDb250cm9sbGVyUmVxdWVzdDsKICBNZWRpYUNvbnRyb2xsZXJQcm94eS5wcm90b3R5cGUudmFsaWRhdG9yID0gbnVsbDsKICB2YXIga0hhbmdvdXRzTWVkaWFSb3V0ZUNvbnRyb2xsZXJfU2V0TG9jYWxQcmVzZW50X05hbWUgPSAxMTAyODkwNTk4OwoKICBmdW5jdGlvbiBIYW5nb3V0c01lZGlhUm91dGVDb250cm9sbGVyUHRyKGhhbmRsZU9yUHRySW5mbykgewogICAgdGhpcy5wdHIgPSBuZXcgYmluZGluZ3MuSW50ZXJmYWNlUHRyQ29udHJvbGxlcihIYW5nb3V0c01lZGlhUm91dGVDb250cm9sbGVyLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBoYW5kbGVPclB0ckluZm8pOwogIH0KCiAgZnVuY3Rpb24gSGFuZ291dHNNZWRpYVJvdXRlQ29udHJvbGxlckFzc29jaWF0ZWRQdHIoYXNzb2NpYXRlZEludGVyZmFjZVB0ckluZm8pIHsKICAgIHRoaXMucHRyID0gbmV3IGFzc29jaWF0ZWRCaW5kaW5ncy5Bc3NvY2lhdGVkSW50ZXJmYWNlUHRyQ29udHJvbGxlcigKICAgICAgICBIYW5nb3V0c01lZGlhUm91dGVDb250cm9sbGVyLCBhc3NvY2lhdGVkSW50ZXJmYWNlUHRySW5mbyk7CiAgfQoKICBIYW5nb3V0c01lZGlhUm91dGVDb250cm9sbGVyQXNzb2NpYXRlZFB0ci5wcm90b3R5cGUgPQogICAgICBPYmplY3QuY3JlYXRlKEhhbmdvdXRzTWVkaWFSb3V0ZUNvbnRyb2xsZXJQdHIucHJvdG90eXBlKTsKICBIYW5nb3V0c01lZGlhUm91dGVDb250cm9sbGVyQXNzb2NpYXRlZFB0ci5wcm90b3R5cGUuY29uc3RydWN0b3IgPQogICAgICBIYW5nb3V0c01lZGlhUm91dGVDb250cm9sbGVyQXNzb2NpYXRlZFB0cjsKCiAgZnVuY3Rpb24gSGFuZ291dHNNZWRpYVJvdXRlQ29udHJvbGxlclByb3h5KHJlY2VpdmVyKSB7CiAgICB0aGlzLnJlY2VpdmVyXyA9IHJlY2VpdmVyOwogIH0KICBIYW5nb3V0c01lZGlhUm91dGVDb250cm9sbGVyUHRyLnByb3RvdHlwZS5zZXRMb2NhbFByZXNlbnQgPSBmdW5jdGlvbigpIHsKICAgIHJldHVybiBIYW5nb3V0c01lZGlhUm91dGVDb250cm9sbGVyUHJveHkucHJvdG90eXBlLnNldExvY2FsUHJlc2VudAogICAgICAgIC5hcHBseSh0aGlzLnB0ci5nZXRQcm94eSgpLCBhcmd1bWVudHMpOwogIH07CgogIEhhbmdvdXRzTWVkaWFSb3V0ZUNvbnRyb2xsZXJQcm94eS5wcm90b3R5cGUuc2V0TG9jYWxQcmVzZW50ID0gZnVuY3Rpb24obG9jYWxQcmVzZW50KSB7CiAgICB2YXIgcGFyYW1zID0gbmV3IEhhbmdvdXRzTWVkaWFSb3V0ZUNvbnRyb2xsZXJfU2V0TG9jYWxQcmVzZW50X1BhcmFtcygpOwogICAgcGFyYW1zLmxvY2FsUHJlc2VudCA9IGxvY2FsUHJlc2VudDsKICAgIHZhciBidWlsZGVyID0gbmV3IGNvZGVjLk1lc3NhZ2VWMEJ1aWxkZXIoCiAgICAgICAga0hhbmdvdXRzTWVkaWFSb3V0ZUNvbnRyb2xsZXJfU2V0TG9jYWxQcmVzZW50X05hbWUsCiAgICAgICAgY29kZWMuYWxpZ24oSGFuZ291dHNNZWRpYVJvdXRlQ29udHJvbGxlcl9TZXRMb2NhbFByZXNlbnRfUGFyYW1zLmVuY29kZWRTaXplKSk7CiAgICBidWlsZGVyLmVuY29kZVN0cnVjdChIYW5nb3V0c01lZGlhUm91dGVDb250cm9sbGVyX1NldExvY2FsUHJlc2VudF9QYXJhbXMsIHBhcmFtcyk7CiAgICB2YXIgbWVzc2FnZSA9IGJ1aWxkZXIuZmluaXNoKCk7CiAgICB0aGlzLnJlY2VpdmVyXy5hY2NlcHQobWVzc2FnZSk7CiAgfTsKCiAgZnVuY3Rpb24gSGFuZ291dHNNZWRpYVJvdXRlQ29udHJvbGxlclN0dWIoZGVsZWdhdGUpIHsKICAgIHRoaXMuZGVsZWdhdGVfID0gZGVsZWdhdGU7CiAgfQogIEhhbmdvdXRzTWVkaWFSb3V0ZUNvbnRyb2xsZXJTdHViLnByb3RvdHlwZS5zZXRMb2NhbFByZXNlbnQgPSBmdW5jdGlvbihsb2NhbFByZXNlbnQpIHsKICAgIHJldHVybiB0aGlzLmRlbGVnYXRlXyAmJiB0aGlzLmRlbGVnYXRlXy5zZXRMb2NhbFByZXNlbnQgJiYgdGhpcy5kZWxlZ2F0ZV8uc2V0TG9jYWxQcmVzZW50KGxvY2FsUHJlc2VudCk7CiAgfQoKICBIYW5nb3V0c01lZGlhUm91dGVDb250cm9sbGVyU3R1Yi5wcm90b3R5cGUuYWNjZXB0ID0gZnVuY3Rpb24obWVzc2FnZSkgewogICAgdmFyIHJlYWRlciA9IG5ldyBjb2RlYy5NZXNzYWdlUmVhZGVyKG1lc3NhZ2UpOwogICAgc3dpdGNoIChyZWFkZXIubWVzc2FnZU5hbWUpIHsKICAgIGNhc2Uga0hhbmdvdXRzTWVkaWFSb3V0ZUNvbnRyb2xsZXJfU2V0TG9jYWxQcmVzZW50X05hbWU6CiAgICAgIHZhciBwYXJhbXMgPSByZWFkZXIuZGVjb2RlU3RydWN0KEhhbmdvdXRzTWVkaWFSb3V0ZUNvbnRyb2xsZXJfU2V0TG9jYWxQcmVzZW50X1BhcmFtcyk7CiAgICAgIHRoaXMuc2V0TG9jYWxQcmVzZW50KHBhcmFtcy5sb2NhbFByZXNlbnQpOwogICAgICByZXR1cm4gdHJ1ZTsKICAgIGRlZmF1bHQ6CiAgICAgIHJldHVybiBmYWxzZTsKICAgIH0KICB9OwoKICBIYW5nb3V0c01lZGlhUm91dGVDb250cm9sbGVyU3R1Yi5wcm90b3R5cGUuYWNjZXB0V2l0aFJlc3BvbmRlciA9CiAgICAgIGZ1bmN0aW9uKG1lc3NhZ2UsIHJlc3BvbmRlcikgewogICAgdmFyIHJlYWRlciA9IG5ldyBjb2RlYy5NZXNzYWdlUmVhZGVyKG1lc3NhZ2UpOwogICAgc3dpdGNoIChyZWFkZXIubWVzc2FnZU5hbWUpIHsKICAgIGRlZmF1bHQ6CiAgICAgIHJldHVybiBmYWxzZTsKICAgIH0KICB9OwoKICBmdW5jdGlvbiB2YWxpZGF0ZUhhbmdvdXRzTWVkaWFSb3V0ZUNvbnRyb2xsZXJSZXF1ZXN0KG1lc3NhZ2VWYWxpZGF0b3IpIHsKICAgIHZhciBtZXNzYWdlID0gbWVzc2FnZVZhbGlkYXRvci5tZXNzYWdlOwogICAgdmFyIHBhcmFtc0NsYXNzID0gbnVsbDsKICAgIHN3aXRjaCAobWVzc2FnZS5nZXROYW1lKCkpIHsKICAgICAgY2FzZSBrSGFuZ291dHNNZWRpYVJvdXRlQ29udHJvbGxlcl9TZXRMb2NhbFByZXNlbnRfTmFtZToKICAgICAgICBpZiAoIW1lc3NhZ2UuZXhwZWN0c1Jlc3BvbnNlKCkgJiYgIW1lc3NhZ2UuaXNSZXNwb25zZSgpKQogICAgICAgICAgcGFyYW1zQ2xhc3MgPSBIYW5nb3V0c01lZGlhUm91dGVDb250cm9sbGVyX1NldExvY2FsUHJlc2VudF9QYXJhbXM7CiAgICAgIGJyZWFrOwogICAgfQogICAgaWYgKHBhcmFtc0NsYXNzID09PSBudWxsKQogICAgICByZXR1cm4gdmFsaWRhdG9yLnZhbGlkYXRpb25FcnJvci5OT05FOwogICAgcmV0dXJuIHBhcmFtc0NsYXNzLnZhbGlkYXRlKG1lc3NhZ2VWYWxpZGF0b3IsIG1lc3NhZ2VWYWxpZGF0b3IubWVzc2FnZS5nZXRIZWFkZXJOdW1CeXRlcygpKTsKICB9CgogIGZ1bmN0aW9uIHZhbGlkYXRlSGFuZ291dHNNZWRpYVJvdXRlQ29udHJvbGxlclJlc3BvbnNlKG1lc3NhZ2VWYWxpZGF0b3IpIHsKICAgIHJldHVybiB2YWxpZGF0b3IudmFsaWRhdGlvbkVycm9yLk5PTkU7CiAgfQoKICB2YXIgSGFuZ291dHNNZWRpYVJvdXRlQ29udHJvbGxlciA9IHsKICAgIG5hbWU6ICdtZWRpYV9yb3V0ZXI6Om1vam9tOjpIYW5nb3V0c01lZGlhUm91dGVDb250cm9sbGVyJywKICAgIGtWZXJzaW9uOiAwLAogICAgcHRyQ2xhc3M6IEhhbmdvdXRzTWVkaWFSb3V0ZUNvbnRyb2xsZXJQdHIsCiAgICBwcm94eUNsYXNzOiBIYW5nb3V0c01lZGlhUm91dGVDb250cm9sbGVyUHJveHksCiAgICBzdHViQ2xhc3M6IEhhbmdvdXRzTWVkaWFSb3V0ZUNvbnRyb2xsZXJTdHViLAogICAgdmFsaWRhdGVSZXF1ZXN0OiB2YWxpZGF0ZUhhbmdvdXRzTWVkaWFSb3V0ZUNvbnRyb2xsZXJSZXF1ZXN0LAogICAgdmFsaWRhdGVSZXNwb25zZTogbnVsbCwKICB9OwogIEhhbmdvdXRzTWVkaWFSb3V0ZUNvbnRyb2xsZXJTdHViLnByb3RvdHlwZS52YWxpZGF0b3IgPSB2YWxpZGF0ZUhhbmdvdXRzTWVkaWFSb3V0ZUNvbnRyb2xsZXJSZXF1ZXN0OwogIEhhbmdvdXRzTWVkaWFSb3V0ZUNvbnRyb2xsZXJQcm94eS5wcm90b3R5cGUudmFsaWRhdG9yID0gbnVsbDsKICBleHBvcnRzLk1lZGlhQ29udHJvbGxlciA9IE1lZGlhQ29udHJvbGxlcjsKICBleHBvcnRzLk1lZGlhQ29udHJvbGxlclB0ciA9IE1lZGlhQ29udHJvbGxlclB0cjsKICBleHBvcnRzLk1lZGlhQ29udHJvbGxlckFzc29jaWF0ZWRQdHIgPSBNZWRpYUNvbnRyb2xsZXJBc3NvY2lhdGVkUHRyOwogIGV4cG9ydHMuSGFuZ291dHNNZWRpYVJvdXRlQ29udHJvbGxlciA9IEhhbmdvdXRzTWVkaWFSb3V0ZUNvbnRyb2xsZXI7CiAgZXhwb3J0cy5IYW5nb3V0c01lZGlhUm91dGVDb250cm9sbGVyUHRyID0gSGFuZ291dHNNZWRpYVJvdXRlQ29udHJvbGxlclB0cjsKICBleHBvcnRzLkhhbmdvdXRzTWVkaWFSb3V0ZUNvbnRyb2xsZXJBc3NvY2lhdGVkUHRyID0gSGFuZ291dHNNZWRpYVJvdXRlQ29udHJvbGxlckFzc29jaWF0ZWRQdHI7Cn0pKCk7Ly8gQ29weXJpZ2h0IDIwMTQgVGhlIENocm9taXVtIEF1dGhvcnMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCi8vIFVzZSBvZiB0aGlzIHNvdXJjZSBjb2RlIGlzIGdvdmVybmVkIGJ5IGEgQlNELXN0eWxlIGxpY2Vuc2UgdGhhdCBjYW4gYmUKLy8gZm91bmQgaW4gdGhlIExJQ0VOU0UgZmlsZS4KCid1c2Ugc3RyaWN0JzsKCihmdW5jdGlvbigpIHsKICB2YXIgbW9qb21JZCA9ICdjaHJvbWUvY29tbW9uL21lZGlhX3JvdXRlci9tb2pvL21lZGlhX3JvdXRlci5tb2pvbSc7CiAgaWYgKG1vam8uaW50ZXJuYWwuaXNNb2pvbUxvYWRlZChtb2pvbUlkKSkgewogICAgY29uc29sZS53YXJuKCdUaGUgZm9sbG93aW5nIG1vam9tIGlzIGxvYWRlZCBtdWx0aXBsZSB0aW1lczogJyArIG1vam9tSWQpOwogICAgcmV0dXJuOwogIH0KICBtb2pvLmludGVybmFsLm1hcmtNb2pvbUxvYWRlZChtb2pvbUlkKTsKICB2YXIgYmluZGluZ3MgPSBtb2pvOwogIHZhciBhc3NvY2lhdGVkQmluZGluZ3MgPSBtb2pvOwogIHZhciBjb2RlYyA9IG1vam8uaW50ZXJuYWw7CiAgdmFyIHZhbGlkYXRvciA9IG1vam8uaW50ZXJuYWw7CgogIHZhciBleHBvcnRzID0gbW9qby5pbnRlcm5hbC5leHBvc2VOYW1lc3BhY2UoJ21lZGlhUm91dGVyLm1vam9tJyk7CiAgdmFyIG1lZGlhX2NvbnRyb2xsZXIkID0KICAgICAgbW9qby5pbnRlcm5hbC5leHBvc2VOYW1lc3BhY2UoJ21lZGlhUm91dGVyLm1vam9tJyk7CiAgaWYgKG1vam8uY29uZmlnLmF1dG9Mb2FkTW9qb21EZXBzKSB7CiAgICBtb2pvLmludGVybmFsLmxvYWRNb2pvbUlmTmVjZXNzYXJ5KAogICAgICAgICdjaHJvbWUvY29tbW9uL21lZGlhX3JvdXRlci9tb2pvL21lZGlhX2NvbnRyb2xsZXIubW9qb20nLCAnbWVkaWFfY29udHJvbGxlci5tb2pvbS5qcycpOwogIH0KICB2YXIgbWVkaWFfc3RhdHVzJCA9CiAgICAgIG1vam8uaW50ZXJuYWwuZXhwb3NlTmFtZXNwYWNlKCdtZWRpYVJvdXRlci5tb2pvbScpOwogIGlmIChtb2pvLmNvbmZpZy5hdXRvTG9hZE1vam9tRGVwcykgewogICAgbW9qby5pbnRlcm5hbC5sb2FkTW9qb21JZk5lY2Vzc2FyeSgKICAgICAgICAnY2hyb21lL2NvbW1vbi9tZWRpYV9yb3V0ZXIvbW9qby9tZWRpYV9zdGF0dXMubW9qb20nLCAnbWVkaWFfc3RhdHVzLm1vam9tLmpzJyk7CiAgfQogIHZhciBtaXJyb3Jfc2VydmljZV9yZW1vdGluZyQgPQogICAgICBtb2pvLmludGVybmFsLmV4cG9zZU5hbWVzcGFjZSgnbWVkaWEubW9qb20nKTsKICBpZiAobW9qby5jb25maWcuYXV0b0xvYWRNb2pvbURlcHMpIHsKICAgIG1vam8uaW50ZXJuYWwubG9hZE1vam9tSWZOZWNlc3NhcnkoCiAgICAgICAgJ21lZGlhL21vam8vaW50ZXJmYWNlcy9taXJyb3Jfc2VydmljZV9yZW1vdGluZy5tb2pvbScsICcuLi8uLi8uLi8uLi9tZWRpYS9tb2pvL2ludGVyZmFjZXMvbWlycm9yX3NlcnZpY2VfcmVtb3RpbmcubW9qb20uanMnKTsKICB9CiAgdmFyIHRpbWUkID0KICAgICAgbW9qby5pbnRlcm5hbC5leHBvc2VOYW1lc3BhY2UoJ21vam8uY29tbW9uLm1vam9tJyk7CiAgaWYgKG1vam8uY29uZmlnLmF1dG9Mb2FkTW9qb21EZXBzKSB7CiAgICBtb2pvLmludGVybmFsLmxvYWRNb2pvbUlmTmVjZXNzYXJ5KAogICAgICAgICdtb2pvL2NvbW1vbi90aW1lLm1vam9tJywgJy4uLy4uLy4uLy4uL21vam8vY29tbW9uL3RpbWUubW9qb20uanMnKTsKICB9CiAgdmFyIGlwX2FkZHJlc3MkID0KICAgICAgbW9qby5pbnRlcm5hbC5leHBvc2VOYW1lc3BhY2UoJ25ldC5pbnRlcmZhY2VzJyk7CiAgaWYgKG1vam8uY29uZmlnLmF1dG9Mb2FkTW9qb21EZXBzKSB7CiAgICBtb2pvLmludGVybmFsLmxvYWRNb2pvbUlmTmVjZXNzYXJ5KAogICAgICAgICduZXQvaW50ZXJmYWNlcy9pcF9hZGRyZXNzLm1vam9tJywgJy4uLy4uLy4uLy4uL25ldC9pbnRlcmZhY2VzL2lwX2FkZHJlc3MubW9qb20uanMnKTsKICB9CiAgdmFyIGlwX2VuZHBvaW50JCA9CiAgICAgIG1vam8uaW50ZXJuYWwuZXhwb3NlTmFtZXNwYWNlKCduZXQuaW50ZXJmYWNlcycpOwogIGlmIChtb2pvLmNvbmZpZy5hdXRvTG9hZE1vam9tRGVwcykgewogICAgbW9qby5pbnRlcm5hbC5sb2FkTW9qb21JZk5lY2Vzc2FyeSgKICAgICAgICAnbmV0L2ludGVyZmFjZXMvaXBfZW5kcG9pbnQubW9qb20nLCAnLi4vLi4vLi4vLi4vbmV0L2ludGVyZmFjZXMvaXBfZW5kcG9pbnQubW9qb20uanMnKTsKICB9CiAgdmFyIG9yaWdpbiQgPQogICAgICBtb2pvLmludGVybmFsLmV4cG9zZU5hbWVzcGFjZSgndXJsLm1vam9tJyk7CiAgaWYgKG1vam8uY29uZmlnLmF1dG9Mb2FkTW9qb21EZXBzKSB7CiAgICBtb2pvLmludGVybmFsLmxvYWRNb2pvbUlmTmVjZXNzYXJ5KAogICAgICAgICd1cmwvbW9qby9vcmlnaW4ubW9qb20nLCAnLi4vLi4vLi4vLi4vdXJsL21vam8vb3JpZ2luLm1vam9tLmpzJyk7CiAgfQogIHZhciB1cmwkID0KICAgICAgbW9qby5pbnRlcm5hbC5leHBvc2VOYW1lc3BhY2UoJ3VybC5tb2pvbScpOwogIGlmIChtb2pvLmNvbmZpZy5hdXRvTG9hZE1vam9tRGVwcykgewogICAgbW9qby5pbnRlcm5hbC5sb2FkTW9qb21JZk5lY2Vzc2FyeSgKICAgICAgICAndXJsL21vam8vdXJsLm1vam9tJywgJy4uLy4uLy4uLy4uL3VybC9tb2pvL3VybC5tb2pvbS5qcycpOwogIH0KCgogIHZhciBTaW5rSWNvblR5cGUgPSB7fTsKICBTaW5rSWNvblR5cGUuQ0FTVCA9IDA7CiAgU2lua0ljb25UeXBlLkNBU1RfQVVESU9fR1JPVVAgPSBTaW5rSWNvblR5cGUuQ0FTVCArIDE7CiAgU2lua0ljb25UeXBlLkNBU1RfQVVESU8gPSBTaW5rSWNvblR5cGUuQ0FTVF9BVURJT19HUk9VUCArIDE7CiAgU2lua0ljb25UeXBlLk1FRVRJTkcgPSBTaW5rSWNvblR5cGUuQ0FTVF9BVURJTyArIDE7CiAgU2lua0ljb25UeXBlLkhBTkdPVVQgPSBTaW5rSWNvblR5cGUuTUVFVElORyArIDE7CiAgU2lua0ljb25UeXBlLkVEVUNBVElPTiA9IFNpbmtJY29uVHlwZS5IQU5HT1VUICsgMTsKICBTaW5rSWNvblR5cGUuV0lSRURfRElTUExBWSA9IFNpbmtJY29uVHlwZS5FRFVDQVRJT04gKyAxOwogIFNpbmtJY29uVHlwZS5HRU5FUklDID0gU2lua0ljb25UeXBlLldJUkVEX0RJU1BMQVkgKyAxOwoKICBTaW5rSWNvblR5cGUuaXNLbm93bkVudW1WYWx1ZSA9IGZ1bmN0aW9uKHZhbHVlKSB7CiAgICBzd2l0Y2ggKHZhbHVlKSB7CiAgICBjYXNlIDA6CiAgICBjYXNlIDE6CiAgICBjYXNlIDI6CiAgICBjYXNlIDM6CiAgICBjYXNlIDQ6CiAgICBjYXNlIDU6CiAgICBjYXNlIDY6CiAgICBjYXNlIDc6CiAgICAgIHJldHVybiB0cnVlOwogICAgfQogICAgcmV0dXJuIGZhbHNlOwogIH07CgogIFNpbmtJY29uVHlwZS52YWxpZGF0ZSA9IGZ1bmN0aW9uKGVudW1WYWx1ZSkgewogICAgdmFyIGlzRXh0ZW5zaWJsZSA9IGZhbHNlOwogICAgaWYgKGlzRXh0ZW5zaWJsZSB8fCB0aGlzLmlzS25vd25FbnVtVmFsdWUoZW51bVZhbHVlKSkKICAgICAgcmV0dXJuIHZhbGlkYXRvci52YWxpZGF0aW9uRXJyb3IuTk9ORTsKCiAgICByZXR1cm4gdmFsaWRhdG9yLnZhbGlkYXRpb25FcnJvci5VTktOT1dOX0VOVU1fVkFMVUU7CiAgfTsKICB2YXIgUm91dGVDb250cm9sbGVyVHlwZSA9IHt9OwogIFJvdXRlQ29udHJvbGxlclR5cGUua05vbmUgPSAwOwogIFJvdXRlQ29udHJvbGxlclR5cGUua0dlbmVyaWMgPSBSb3V0ZUNvbnRyb2xsZXJUeXBlLmtOb25lICsgMTsKICBSb3V0ZUNvbnRyb2xsZXJUeXBlLmtIYW5nb3V0cyA9IFJvdXRlQ29udHJvbGxlclR5cGUua0dlbmVyaWMgKyAxOwogIFJvdXRlQ29udHJvbGxlclR5cGUua01pcnJvcmluZyA9IFJvdXRlQ29udHJvbGxlclR5cGUua0hhbmdvdXRzICsgMTsKCiAgUm91dGVDb250cm9sbGVyVHlwZS5pc0tub3duRW51bVZhbHVlID0gZnVuY3Rpb24odmFsdWUpIHsKICAgIHN3aXRjaCAodmFsdWUpIHsKICAgIGNhc2UgMDoKICAgIGNhc2UgMToKICAgIGNhc2UgMjoKICAgIGNhc2UgMzoKICAgICAgcmV0dXJuIHRydWU7CiAgICB9CiAgICByZXR1cm4gZmFsc2U7CiAgfTsKCiAgUm91dGVDb250cm9sbGVyVHlwZS52YWxpZGF0ZSA9IGZ1bmN0aW9uKGVudW1WYWx1ZSkgewogICAgdmFyIGlzRXh0ZW5zaWJsZSA9IGZhbHNlOwogICAgaWYgKGlzRXh0ZW5zaWJsZSB8fCB0aGlzLmlzS25vd25FbnVtVmFsdWUoZW51bVZhbHVlKSkKICAgICAgcmV0dXJuIHZhbGlkYXRvci52YWxpZGF0aW9uRXJyb3IuTk9ORTsKCiAgICByZXR1cm4gdmFsaWRhdG9yLnZhbGlkYXRpb25FcnJvci5VTktOT1dOX0VOVU1fVkFMVUU7CiAgfTsKICB2YXIgUm91dGVSZXF1ZXN0UmVzdWx0Q29kZSA9IHt9OwogIFJvdXRlUmVxdWVzdFJlc3VsdENvZGUuVU5LTk9XTl9FUlJPUiA9IDA7CiAgUm91dGVSZXF1ZXN0UmVzdWx0Q29kZS5PSyA9IFJvdXRlUmVxdWVzdFJlc3VsdENvZGUuVU5LTk9XTl9FUlJPUiArIDE7CiAgUm91dGVSZXF1ZXN0UmVzdWx0Q29kZS5USU1FRF9PVVQgPSBSb3V0ZVJlcXVlc3RSZXN1bHRDb2RlLk9LICsgMTsKICBSb3V0ZVJlcXVlc3RSZXN1bHRDb2RlLlJPVVRFX05PVF9GT1VORCA9IFJvdXRlUmVxdWVzdFJlc3VsdENvZGUuVElNRURfT1VUICsgMTsKICBSb3V0ZVJlcXVlc3RSZXN1bHRDb2RlLlNJTktfTk9UX0ZPVU5EID0gUm91dGVSZXF1ZXN0UmVzdWx0Q29kZS5ST1VURV9OT1RfRk9VTkQgKyAxOwogIFJvdXRlUmVxdWVzdFJlc3VsdENvZGUuSU5WQUxJRF9PUklHSU4gPSBSb3V0ZVJlcXVlc3RSZXN1bHRDb2RlLlNJTktfTk9UX0ZPVU5EICsgMTsKICBSb3V0ZVJlcXVlc3RSZXN1bHRDb2RlLklOQ09HTklUT19NSVNNQVRDSCA9IFJvdXRlUmVxdWVzdFJlc3VsdENvZGUuSU5WQUxJRF9PUklHSU4gKyAxOwogIFJvdXRlUmVxdWVzdFJlc3VsdENvZGUuTk9fU1VQUE9SVEVEX1BST1ZJREVSID0gUm91dGVSZXF1ZXN0UmVzdWx0Q29kZS5JTkNPR05JVE9fTUlTTUFUQ0ggKyAxOwogIFJvdXRlUmVxdWVzdFJlc3VsdENvZGUuQ0FOQ0VMTEVEID0gUm91dGVSZXF1ZXN0UmVzdWx0Q29kZS5OT19TVVBQT1JURURfUFJPVklERVIgKyAxOwoKICBSb3V0ZVJlcXVlc3RSZXN1bHRDb2RlLmlzS25vd25FbnVtVmFsdWUgPSBmdW5jdGlvbih2YWx1ZSkgewogICAgc3dpdGNoICh2YWx1ZSkgewogICAgY2FzZSAwOgogICAgY2FzZSAxOgogICAgY2FzZSAyOgogICAgY2FzZSAzOgogICAgY2FzZSA0OgogICAgY2FzZSA1OgogICAgY2FzZSA2OgogICAgY2FzZSA3OgogICAgY2FzZSA4OgogICAgICByZXR1cm4gdHJ1ZTsKICAgIH0KICAgIHJldHVybiBmYWxzZTsKICB9OwoKICBSb3V0ZVJlcXVlc3RSZXN1bHRDb2RlLnZhbGlkYXRlID0gZnVuY3Rpb24oZW51bVZhbHVlKSB7CiAgICB2YXIgaXNFeHRlbnNpYmxlID0gZmFsc2U7CiAgICBpZiAoaXNFeHRlbnNpYmxlIHx8IHRoaXMuaXNLbm93bkVudW1WYWx1ZShlbnVtVmFsdWUpKQogICAgICByZXR1cm4gdmFsaWRhdG9yLnZhbGlkYXRpb25FcnJvci5OT05FOwoKICAgIHJldHVybiB2YWxpZGF0b3IudmFsaWRhdGlvbkVycm9yLlVOS05PV05fRU5VTV9WQUxVRTsKICB9OwoKICBmdW5jdGlvbiBNZWRpYVNpbmsodmFsdWVzKSB7CiAgICB0aGlzLmluaXREZWZhdWx0c18oKTsKICAgIHRoaXMuaW5pdEZpZWxkc18odmFsdWVzKTsKICB9CgoKICBNZWRpYVNpbmsucHJvdG90eXBlLmluaXREZWZhdWx0c18gPSBmdW5jdGlvbigpIHsKICAgIHRoaXMuc2lua0lkID0gbnVsbDsKICAgIHRoaXMubmFtZSA9IG51bGw7CiAgICB0aGlzLmRlc2NyaXB0aW9uID0gbnVsbDsKICAgIHRoaXMuZG9tYWluID0gbnVsbDsKICAgIHRoaXMuaWNvblR5cGUgPSAwOwogICAgdGhpcy5wcm92aWRlcklkID0gMDsKICAgIHRoaXMuZXh0cmFEYXRhID0gbnVsbDsKICB9OwogIE1lZGlhU2luay5wcm90b3R5cGUuaW5pdEZpZWxkc18gPSBmdW5jdGlvbihmaWVsZHMpIHsKICAgIGZvcih2YXIgZmllbGQgaW4gZmllbGRzKSB7CiAgICAgICAgaWYgKHRoaXMuaGFzT3duUHJvcGVydHkoZmllbGQpKQogICAgICAgICAgdGhpc1tmaWVsZF0gPSBmaWVsZHNbZmllbGRdOwogICAgfQogIH07CgogIE1lZGlhU2luay52YWxpZGF0ZSA9IGZ1bmN0aW9uKG1lc3NhZ2VWYWxpZGF0b3IsIG9mZnNldCkgewogICAgdmFyIGVycjsKICAgIGVyciA9IG1lc3NhZ2VWYWxpZGF0b3IudmFsaWRhdGVTdHJ1Y3RIZWFkZXIob2Zmc2V0LCBjb2RlYy5rU3RydWN0SGVhZGVyU2l6ZSk7CiAgICBpZiAoZXJyICE9PSB2YWxpZGF0b3IudmFsaWRhdGlvbkVycm9yLk5PTkUpCiAgICAgICAgcmV0dXJuIGVycjsKCiAgICB2YXIga1ZlcnNpb25TaXplcyA9IFsKICAgICAge3ZlcnNpb246IDAsIG51bUJ5dGVzOiA2NH0KICAgIF07CiAgICBlcnIgPSBtZXNzYWdlVmFsaWRhdG9yLnZhbGlkYXRlU3RydWN0VmVyc2lvbihvZmZzZXQsIGtWZXJzaW9uU2l6ZXMpOwogICAgaWYgKGVyciAhPT0gdmFsaWRhdG9yLnZhbGlkYXRpb25FcnJvci5OT05FKQogICAgICAgIHJldHVybiBlcnI7CgoKICAgIC8vIHZhbGlkYXRlIE1lZGlhU2luay5zaW5rSWQKICAgIGVyciA9IG1lc3NhZ2VWYWxpZGF0b3IudmFsaWRhdGVTdHJpbmdQb2ludGVyKG9mZnNldCArIGNvZGVjLmtTdHJ1Y3RIZWFkZXJTaXplICsgMCwgZmFsc2UpCiAgICBpZiAoZXJyICE9PSB2YWxpZGF0b3IudmFsaWRhdGlvbkVycm9yLk5PTkUpCiAgICAgICAgcmV0dXJuIGVycjsKCgogICAgLy8gdmFsaWRhdGUgTWVkaWFTaW5rLm5hbWUKICAgIGVyciA9IG1lc3NhZ2VWYWxpZGF0b3IudmFsaWRhdGVTdHJpbmdQb2ludGVyKG9mZnNldCArIGNvZGVjLmtTdHJ1Y3RIZWFkZXJTaXplICsgOCwgZmFsc2UpCiAgICBpZiAoZXJyICE9PSB2YWxpZGF0b3IudmFsaWRhdGlvbkVycm9yLk5PTkUpCiAgICAgICAgcmV0dXJuIGVycjsKCgogICAgLy8gdmFsaWRhdGUgTWVkaWFTaW5rLmRlc2NyaXB0aW9uCiAgICBlcnIgPSBtZXNzYWdlVmFsaWRhdG9yLnZhbGlkYXRlU3RyaW5nUG9pbnRlcihvZmZzZXQgKyBjb2RlYy5rU3RydWN0SGVhZGVyU2l6ZSArIDE2LCB0cnVlKQogICAgaWYgKGVyciAhPT0gdmFsaWRhdG9yLnZhbGlkYXRpb25FcnJvci5OT05FKQogICAgICAgIHJldHVybiBlcnI7CgoKICAgIC8vIHZhbGlkYXRlIE1lZGlhU2luay5kb21haW4KICAgIGVyciA9IG1lc3NhZ2VWYWxpZGF0b3IudmFsaWRhdGVTdHJpbmdQb2ludGVyKG9mZnNldCArIGNvZGVjLmtTdHJ1Y3RIZWFkZXJTaXplICsgMjQsIHRydWUpCiAgICBpZiAoZXJyICE9PSB2YWxpZGF0b3IudmFsaWRhdGlvbkVycm9yLk5PTkUpCiAgICAgICAgcmV0dXJuIGVycjsKCgogICAgLy8gdmFsaWRhdGUgTWVkaWFTaW5rLmljb25UeXBlCiAgICBlcnIgPSBtZXNzYWdlVmFsaWRhdG9yLnZhbGlkYXRlRW51bShvZmZzZXQgKyBjb2RlYy5rU3RydWN0SGVhZGVyU2l6ZSArIDMyLCBTaW5rSWNvblR5cGUpOwogICAgaWYgKGVyciAhPT0gdmFsaWRhdG9yLnZhbGlkYXRpb25FcnJvci5OT05FKQogICAgICAgIHJldHVybiBlcnI7CgoKICAgIC8vIHZhbGlkYXRlIE1lZGlhU2luay5wcm92aWRlcklkCiAgICBlcnIgPSBtZXNzYWdlVmFsaWRhdG9yLnZhbGlkYXRlRW51bShvZmZzZXQgKyBjb2RlYy5rU3RydWN0SGVhZGVyU2l6ZSArIDM2LCBNZWRpYVJvdXRlUHJvdmlkZXIuSWQpOwogICAgaWYgKGVyciAhPT0gdmFsaWRhdG9yLnZhbGlkYXRpb25FcnJvci5OT05FKQogICAgICAgIHJldHVybiBlcnI7CgoKICAgIC8vIHZhbGlkYXRlIE1lZGlhU2luay5leHRyYURhdGEKICAgIGVyciA9IG1lc3NhZ2VWYWxpZGF0b3IudmFsaWRhdGVVbmlvbihvZmZzZXQgKyBjb2RlYy5rU3RydWN0SGVhZGVyU2l6ZSArIDQwLCBNZWRpYVNpbmtFeHRyYURhdGEsIHRydWUpOwogICAgaWYgKGVyciAhPT0gdmFsaWRhdG9yLnZhbGlkYXRpb25FcnJvci5OT05FKQogICAgICAgIHJldHVybiBlcnI7CgogICAgcmV0dXJuIHZhbGlkYXRvci52YWxpZGF0aW9uRXJyb3IuTk9ORTsKICB9OwoKICBNZWRpYVNpbmsuZW5jb2RlZFNpemUgPSBjb2RlYy5rU3RydWN0SGVhZGVyU2l6ZSArIDU2OwoKICBNZWRpYVNpbmsuZGVjb2RlID0gZnVuY3Rpb24oZGVjb2RlcikgewogICAgdmFyIHBhY2tlZDsKICAgIHZhciB2YWwgPSBuZXcgTWVkaWFTaW5rKCk7CiAgICB2YXIgbnVtYmVyT2ZCeXRlcyA9IGRlY29kZXIucmVhZFVpbnQzMigpOwogICAgdmFyIHZlcnNpb24gPSBkZWNvZGVyLnJlYWRVaW50MzIoKTsKICAgIHZhbC5zaW5rSWQgPSBkZWNvZGVyLmRlY29kZVN0cnVjdChjb2RlYy5TdHJpbmcpOwogICAgdmFsLm5hbWUgPSBkZWNvZGVyLmRlY29kZVN0cnVjdChjb2RlYy5TdHJpbmcpOwogICAgdmFsLmRlc2NyaXB0aW9uID0gZGVjb2Rlci5kZWNvZGVTdHJ1Y3QoY29kZWMuTnVsbGFibGVTdHJpbmcpOwogICAgdmFsLmRvbWFpbiA9IGRlY29kZXIuZGVjb2RlU3RydWN0KGNvZGVjLk51bGxhYmxlU3RyaW5nKTsKICAgIHZhbC5pY29uVHlwZSA9IGRlY29kZXIuZGVjb2RlU3RydWN0KGNvZGVjLkludDMyKTsKICAgIHZhbC5wcm92aWRlcklkID0gZGVjb2Rlci5kZWNvZGVTdHJ1Y3QoY29kZWMuSW50MzIpOwogICAgdmFsLmV4dHJhRGF0YSA9IGRlY29kZXIuZGVjb2RlU3RydWN0KE1lZGlhU2lua0V4dHJhRGF0YSk7CiAgICByZXR1cm4gdmFsOwogIH07CgogIE1lZGlhU2luay5lbmNvZGUgPSBmdW5jdGlvbihlbmNvZGVyLCB2YWwpIHsKICAgIHZhciBwYWNrZWQ7CiAgICBlbmNvZGVyLndyaXRlVWludDMyKE1lZGlhU2luay5lbmNvZGVkU2l6ZSk7CiAgICBlbmNvZGVyLndyaXRlVWludDMyKDApOwogICAgZW5jb2Rlci5lbmNvZGVTdHJ1Y3QoY29kZWMuU3RyaW5nLCB2YWwuc2lua0lkKTsKICAgIGVuY29kZXIuZW5jb2RlU3RydWN0KGNvZGVjLlN0cmluZywgdmFsLm5hbWUpOwogICAgZW5jb2Rlci5lbmNvZGVTdHJ1Y3QoY29kZWMuTnVsbGFibGVTdHJpbmcsIHZhbC5kZXNjcmlwdGlvbik7CiAgICBlbmNvZGVyLmVuY29kZVN0cnVjdChjb2RlYy5OdWxsYWJsZVN0cmluZywgdmFsLmRvbWFpbik7CiAgICBlbmNvZGVyLmVuY29kZVN0cnVjdChjb2RlYy5JbnQzMiwgdmFsLmljb25UeXBlKTsKICAgIGVuY29kZXIuZW5jb2RlU3RydWN0KGNvZGVjLkludDMyLCB2YWwucHJvdmlkZXJJZCk7CiAgICBlbmNvZGVyLmVuY29kZVN0cnVjdChNZWRpYVNpbmtFeHRyYURhdGEsIHZhbC5leHRyYURhdGEpOwogIH07CiAgZnVuY3Rpb24gRGlhbE1lZGlhU2luayh2YWx1ZXMpIHsKICAgIHRoaXMuaW5pdERlZmF1bHRzXygpOwogICAgdGhpcy5pbml0RmllbGRzXyh2YWx1ZXMpOwogIH0KCgogIERpYWxNZWRpYVNpbmsucHJvdG90eXBlLmluaXREZWZhdWx0c18gPSBmdW5jdGlvbigpIHsKICAgIHRoaXMuaXBBZGRyZXNzID0gbnVsbDsKICAgIHRoaXMubW9kZWxOYW1lID0gbnVsbDsKICAgIHRoaXMuYXBwVXJsID0gbnVsbDsKICB9OwogIERpYWxNZWRpYVNpbmsucHJvdG90eXBlLmluaXRGaWVsZHNfID0gZnVuY3Rpb24oZmllbGRzKSB7CiAgICBmb3IodmFyIGZpZWxkIGluIGZpZWxkcykgewogICAgICAgIGlmICh0aGlzLmhhc093blByb3BlcnR5KGZpZWxkKSkKICAgICAgICAgIHRoaXNbZmllbGRdID0gZmllbGRzW2ZpZWxkXTsKICAgIH0KICB9OwoKICBEaWFsTWVkaWFTaW5rLnZhbGlkYXRlID0gZnVuY3Rpb24obWVzc2FnZVZhbGlkYXRvciwgb2Zmc2V0KSB7CiAgICB2YXIgZXJyOwogICAgZXJyID0gbWVzc2FnZVZhbGlkYXRvci52YWxpZGF0ZVN0cnVjdEhlYWRlcihvZmZzZXQsIGNvZGVjLmtTdHJ1Y3RIZWFkZXJTaXplKTsKICAgIGlmIChlcnIgIT09IHZhbGlkYXRvci52YWxpZGF0aW9uRXJyb3IuTk9ORSkKICAgICAgICByZXR1cm4gZXJyOwoKICAgIHZhciBrVmVyc2lvblNpemVzID0gWwogICAgICB7dmVyc2lvbjogMCwgbnVtQnl0ZXM6IDMyfQogICAgXTsKICAgIGVyciA9IG1lc3NhZ2VWYWxpZGF0b3IudmFsaWRhdGVTdHJ1Y3RWZXJzaW9uKG9mZnNldCwga1ZlcnNpb25TaXplcyk7CiAgICBpZiAoZXJyICE9PSB2YWxpZGF0b3IudmFsaWRhdGlvbkVycm9yLk5PTkUpCiAgICAgICAgcmV0dXJuIGVycjsKCgogICAgLy8gdmFsaWRhdGUgRGlhbE1lZGlhU2luay5pcEFkZHJlc3MKICAgIGVyciA9IG1lc3NhZ2VWYWxpZGF0b3IudmFsaWRhdGVTdHJ1Y3RQb2ludGVyKG9mZnNldCArIGNvZGVjLmtTdHJ1Y3RIZWFkZXJTaXplICsgMCwgaXBfYWRkcmVzcyQuSVBBZGRyZXNzLCBmYWxzZSk7CiAgICBpZiAoZXJyICE9PSB2YWxpZGF0b3IudmFsaWRhdGlvbkVycm9yLk5PTkUpCiAgICAgICAgcmV0dXJuIGVycjsKCgogICAgLy8gdmFsaWRhdGUgRGlhbE1lZGlhU2luay5tb2RlbE5hbWUKICAgIGVyciA9IG1lc3NhZ2VWYWxpZGF0b3IudmFsaWRhdGVTdHJpbmdQb2ludGVyKG9mZnNldCArIGNvZGVjLmtTdHJ1Y3RIZWFkZXJTaXplICsgOCwgZmFsc2UpCiAgICBpZiAoZXJyICE9PSB2YWxpZGF0b3IudmFsaWRhdGlvbkVycm9yLk5PTkUpCiAgICAgICAgcmV0dXJuIGVycjsKCgogICAgLy8gdmFsaWRhdGUgRGlhbE1lZGlhU2luay5hcHBVcmwKICAgIGVyciA9IG1lc3NhZ2VWYWxpZGF0b3IudmFsaWRhdGVTdHJ1Y3RQb2ludGVyKG9mZnNldCArIGNvZGVjLmtTdHJ1Y3RIZWFkZXJTaXplICsgMTYsIHVybCQuVXJsLCBmYWxzZSk7CiAgICBpZiAoZXJyICE9PSB2YWxpZGF0b3IudmFsaWRhdGlvbkVycm9yLk5PTkUpCiAgICAgICAgcmV0dXJuIGVycjsKCiAgICByZXR1cm4gdmFsaWRhdG9yLnZhbGlkYXRpb25FcnJvci5OT05FOwogIH07CgogIERpYWxNZWRpYVNpbmsuZW5jb2RlZFNpemUgPSBjb2RlYy5rU3RydWN0SGVhZGVyU2l6ZSArIDI0OwoKICBEaWFsTWVkaWFTaW5rLmRlY29kZSA9IGZ1bmN0aW9uKGRlY29kZXIpIHsKICAgIHZhciBwYWNrZWQ7CiAgICB2YXIgdmFsID0gbmV3IERpYWxNZWRpYVNpbmsoKTsKICAgIHZhciBudW1iZXJPZkJ5dGVzID0gZGVjb2Rlci5yZWFkVWludDMyKCk7CiAgICB2YXIgdmVyc2lvbiA9IGRlY29kZXIucmVhZFVpbnQzMigpOwogICAgdmFsLmlwQWRkcmVzcyA9IGRlY29kZXIuZGVjb2RlU3RydWN0UG9pbnRlcihpcF9hZGRyZXNzJC5JUEFkZHJlc3MpOwogICAgdmFsLm1vZGVsTmFtZSA9IGRlY29kZXIuZGVjb2RlU3RydWN0KGNvZGVjLlN0cmluZyk7CiAgICB2YWwuYXBwVXJsID0gZGVjb2Rlci5kZWNvZGVTdHJ1Y3RQb2ludGVyKHVybCQuVXJsKTsKICAgIHJldHVybiB2YWw7CiAgfTsKCiAgRGlhbE1lZGlhU2luay5lbmNvZGUgPSBmdW5jdGlvbihlbmNvZGVyLCB2YWwpIHsKICAgIHZhciBwYWNrZWQ7CiAgICBlbmNvZGVyLndyaXRlVWludDMyKERpYWxNZWRpYVNpbmsuZW5jb2RlZFNpemUpOwogICAgZW5jb2Rlci53cml0ZVVpbnQzMigwKTsKICAgIGVuY29kZXIuZW5jb2RlU3RydWN0UG9pbnRlcihpcF9hZGRyZXNzJC5JUEFkZHJlc3MsIHZhbC5pcEFkZHJlc3MpOwogICAgZW5jb2Rlci5lbmNvZGVTdHJ1Y3QoY29kZWMuU3RyaW5nLCB2YWwubW9kZWxOYW1lKTsKICAgIGVuY29kZXIuZW5jb2RlU3RydWN0UG9pbnRlcih1cmwkLlVybCwgdmFsLmFwcFVybCk7CiAgfTsKICBmdW5jdGlvbiBDYXN0TWVkaWFTaW5rKHZhbHVlcykgewogICAgdGhpcy5pbml0RGVmYXVsdHNfKCk7CiAgICB0aGlzLmluaXRGaWVsZHNfKHZhbHVlcyk7CiAgfQoKCiAgQ2FzdE1lZGlhU2luay5wcm90b3R5cGUuaW5pdERlZmF1bHRzXyA9IGZ1bmN0aW9uKCkgewogICAgdGhpcy5pcEVuZHBvaW50ID0gbnVsbDsKICAgIHRoaXMubW9kZWxOYW1lID0gbnVsbDsKICAgIHRoaXMuY2FwYWJpbGl0aWVzID0gMDsKICAgIHRoaXMuY2FzdENoYW5uZWxJZCA9IDA7CiAgfTsKICBDYXN0TWVkaWFTaW5rLnByb3RvdHlwZS5pbml0RmllbGRzXyA9IGZ1bmN0aW9uKGZpZWxkcykgewogICAgZm9yKHZhciBmaWVsZCBpbiBmaWVsZHMpIHsKICAgICAgICBpZiAodGhpcy5oYXNPd25Qcm9wZXJ0eShmaWVsZCkpCiAgICAgICAgICB0aGlzW2ZpZWxkXSA9IGZpZWxkc1tmaWVsZF07CiAgICB9CiAgfTsKCiAgQ2FzdE1lZGlhU2luay52YWxpZGF0ZSA9IGZ1bmN0aW9uKG1lc3NhZ2VWYWxpZGF0b3IsIG9mZnNldCkgewogICAgdmFyIGVycjsKICAgIGVyciA9IG1lc3NhZ2VWYWxpZGF0b3IudmFsaWRhdGVTdHJ1Y3RIZWFkZXIob2Zmc2V0LCBjb2RlYy5rU3RydWN0SGVhZGVyU2l6ZSk7CiAgICBpZiAoZXJyICE9PSB2YWxpZGF0b3IudmFsaWRhdGlvbkVycm9yLk5PTkUpCiAgICAgICAgcmV0dXJuIGVycjsKCiAgICB2YXIga1ZlcnNpb25TaXplcyA9IFsKICAgICAge3ZlcnNpb246IDAsIG51bUJ5dGVzOiAzMn0KICAgIF07CiAgICBlcnIgPSBtZXNzYWdlVmFsaWRhdG9yLnZhbGlkYXRlU3RydWN0VmVyc2lvbihvZmZzZXQsIGtWZXJzaW9uU2l6ZXMpOwogICAgaWYgKGVyciAhPT0gdmFsaWRhdG9yLnZhbGlkYXRpb25FcnJvci5OT05FKQogICAgICAgIHJldHVybiBlcnI7CgoKICAgIC8vIHZhbGlkYXRlIENhc3RNZWRpYVNpbmsuaXBFbmRwb2ludAogICAgZXJyID0gbWVzc2FnZVZhbGlkYXRvci52YWxpZGF0ZVN0cnVjdFBvaW50ZXIob2Zmc2V0ICsgY29kZWMua1N0cnVjdEhlYWRlclNpemUgKyAwLCBpcF9lbmRwb2ludCQuSVBFbmRQb2ludCwgZmFsc2UpOwogICAgaWYgKGVyciAhPT0gdmFsaWRhdG9yLnZhbGlkYXRpb25FcnJvci5OT05FKQogICAgICAgIHJldHVybiBlcnI7CgoKICAgIC8vIHZhbGlkYXRlIENhc3RNZWRpYVNpbmsubW9kZWxOYW1lCiAgICBlcnIgPSBtZXNzYWdlVmFsaWRhdG9yLnZhbGlkYXRlU3RyaW5nUG9pbnRlcihvZmZzZXQgKyBjb2RlYy5rU3RydWN0SGVhZGVyU2l6ZSArIDgsIGZhbHNlKQogICAgaWYgKGVyciAhPT0gdmFsaWRhdG9yLnZhbGlkYXRpb25FcnJvci5OT05FKQogICAgICAgIHJldHVybiBlcnI7CgoKCiAgICByZXR1cm4gdmFsaWRhdG9yLnZhbGlkYXRpb25FcnJvci5OT05FOwogIH07CgogIENhc3RNZWRpYVNpbmsuZW5jb2RlZFNpemUgPSBjb2RlYy5rU3RydWN0SGVhZGVyU2l6ZSArIDI0OwoKICBDYXN0TWVkaWFTaW5rLmRlY29kZSA9IGZ1bmN0aW9uKGRlY29kZXIpIHsKICAgIHZhciBwYWNrZWQ7CiAgICB2YXIgdmFsID0gbmV3IENhc3RNZWRpYVNpbmsoKTsKICAgIHZhciBudW1iZXJPZkJ5dGVzID0gZGVjb2Rlci5yZWFkVWludDMyKCk7CiAgICB2YXIgdmVyc2lvbiA9IGRlY29kZXIucmVhZFVpbnQzMigpOwogICAgdmFsLmlwRW5kcG9pbnQgPSBkZWNvZGVyLmRlY29kZVN0cnVjdFBvaW50ZXIoaXBfZW5kcG9pbnQkLklQRW5kUG9pbnQpOwogICAgdmFsLm1vZGVsTmFtZSA9IGRlY29kZXIuZGVjb2RlU3RydWN0KGNvZGVjLlN0cmluZyk7CiAgICB2YWwuY2FwYWJpbGl0aWVzID0gZGVjb2Rlci5kZWNvZGVTdHJ1Y3QoY29kZWMuVWludDgpOwogICAgZGVjb2Rlci5za2lwKDEpOwogICAgZGVjb2Rlci5za2lwKDEpOwogICAgZGVjb2Rlci5za2lwKDEpOwogICAgdmFsLmNhc3RDaGFubmVsSWQgPSBkZWNvZGVyLmRlY29kZVN0cnVjdChjb2RlYy5JbnQzMik7CiAgICByZXR1cm4gdmFsOwogIH07CgogIENhc3RNZWRpYVNpbmsuZW5jb2RlID0gZnVuY3Rpb24oZW5jb2RlciwgdmFsKSB7CiAgICB2YXIgcGFja2VkOwogICAgZW5jb2Rlci53cml0ZVVpbnQzMihDYXN0TWVkaWFTaW5rLmVuY29kZWRTaXplKTsKICAgIGVuY29kZXIud3JpdGVVaW50MzIoMCk7CiAgICBlbmNvZGVyLmVuY29kZVN0cnVjdFBvaW50ZXIoaXBfZW5kcG9pbnQkLklQRW5kUG9pbnQsIHZhbC5pcEVuZHBvaW50KTsKICAgIGVuY29kZXIuZW5jb2RlU3RydWN0KGNvZGVjLlN0cmluZywgdmFsLm1vZGVsTmFtZSk7CiAgICBlbmNvZGVyLmVuY29kZVN0cnVjdChjb2RlYy5VaW50OCwgdmFsLmNhcGFiaWxpdGllcyk7CiAgICBlbmNvZGVyLnNraXAoMSk7CiAgICBlbmNvZGVyLnNraXAoMSk7CiAgICBlbmNvZGVyLnNraXAoMSk7CiAgICBlbmNvZGVyLmVuY29kZVN0cnVjdChjb2RlYy5JbnQzMiwgdmFsLmNhc3RDaGFubmVsSWQpOwogIH07CiAgZnVuY3Rpb24gTWVkaWFSb3V0ZSh2YWx1ZXMpIHsKICAgIHRoaXMuaW5pdERlZmF1bHRzXygpOwogICAgdGhpcy5pbml0RmllbGRzXyh2YWx1ZXMpOwogIH0KCgogIE1lZGlhUm91dGUucHJvdG90eXBlLmluaXREZWZhdWx0c18gPSBmdW5jdGlvbigpIHsKICAgIHRoaXMubWVkaWFSb3V0ZUlkID0gbnVsbDsKICAgIHRoaXMucHJlc2VudGF0aW9uSWQgPSBudWxsOwogICAgdGhpcy5tZWRpYVNvdXJjZSA9IG51bGw7CiAgICB0aGlzLm1lZGlhU2lua0lkID0gbnVsbDsKICAgIHRoaXMuZGVzY3JpcHRpb24gPSBudWxsOwogICAgdGhpcy5pc0xvY2FsID0gZmFsc2U7CiAgICB0aGlzLmZvckRpc3BsYXkgPSBmYWxzZTsKICAgIHRoaXMuaXNJbmNvZ25pdG8gPSBmYWxzZTsKICAgIHRoaXMuaXNMb2NhbFByZXNlbnRhdGlvbiA9IGZhbHNlOwogICAgdGhpcy5jb250cm9sbGVyVHlwZSA9IDA7CiAgfTsKICBNZWRpYVJvdXRlLnByb3RvdHlwZS5pbml0RmllbGRzXyA9IGZ1bmN0aW9uKGZpZWxkcykgewogICAgZm9yKHZhciBmaWVsZCBpbiBmaWVsZHMpIHsKICAgICAgICBpZiAodGhpcy5oYXNPd25Qcm9wZXJ0eShmaWVsZCkpCiAgICAgICAgICB0aGlzW2ZpZWxkXSA9IGZpZWxkc1tmaWVsZF07CiAgICB9CiAgfTsKCiAgTWVkaWFSb3V0ZS52YWxpZGF0ZSA9IGZ1bmN0aW9uKG1lc3NhZ2VWYWxpZGF0b3IsIG9mZnNldCkgewogICAgdmFyIGVycjsKICAgIGVyciA9IG1lc3NhZ2VWYWxpZGF0b3IudmFsaWRhdGVTdHJ1Y3RIZWFkZXIob2Zmc2V0LCBjb2RlYy5rU3RydWN0SGVhZGVyU2l6ZSk7CiAgICBpZiAoZXJyICE9PSB2YWxpZGF0b3IudmFsaWRhdGlvbkVycm9yLk5PTkUpCiAgICAgICAgcmV0dXJuIGVycjsKCiAgICB2YXIga1ZlcnNpb25TaXplcyA9IFsKICAgICAge3ZlcnNpb246IDAsIG51bUJ5dGVzOiA1Nn0KICAgIF07CiAgICBlcnIgPSBtZXNzYWdlVmFsaWRhdG9yLnZhbGlkYXRlU3RydWN0VmVyc2lvbihvZmZzZXQsIGtWZXJzaW9uU2l6ZXMpOwogICAgaWYgKGVyciAhPT0gdmFsaWRhdG9yLnZhbGlkYXRpb25FcnJvci5OT05FKQogICAgICAgIHJldHVybiBlcnI7CgoKICAgIC8vIHZhbGlkYXRlIE1lZGlhUm91dGUubWVkaWFSb3V0ZUlkCiAgICBlcnIgPSBtZXNzYWdlVmFsaWRhdG9yLnZhbGlkYXRlU3RyaW5nUG9pbnRlcihvZmZzZXQgKyBjb2RlYy5rU3RydWN0SGVhZGVyU2l6ZSArIDAsIGZhbHNlKQogICAgaWYgKGVyciAhPT0gdmFsaWRhdG9yLnZhbGlkYXRpb25FcnJvci5OT05FKQogICAgICAgIHJldHVybiBlcnI7CgoKICAgIC8vIHZhbGlkYXRlIE1lZGlhUm91dGUucHJlc2VudGF0aW9uSWQKICAgIGVyciA9IG1lc3NhZ2VWYWxpZGF0b3IudmFsaWRhdGVTdHJpbmdQb2ludGVyKG9mZnNldCArIGNvZGVjLmtTdHJ1Y3RIZWFkZXJTaXplICsgOCwgZmFsc2UpCiAgICBpZiAoZXJyICE9PSB2YWxpZGF0b3IudmFsaWRhdGlvbkVycm9yLk5PTkUpCiAgICAgICAgcmV0dXJuIGVycjsKCgogICAgLy8gdmFsaWRhdGUgTWVkaWFSb3V0ZS5tZWRpYVNvdXJjZQogICAgZXJyID0gbWVzc2FnZVZhbGlkYXRvci52YWxpZGF0ZVN0cmluZ1BvaW50ZXIob2Zmc2V0ICsgY29kZWMua1N0cnVjdEhlYWRlclNpemUgKyAxNiwgdHJ1ZSkKICAgIGlmIChlcnIgIT09IHZhbGlkYXRvci52YWxpZGF0aW9uRXJyb3IuTk9ORSkKICAgICAgICByZXR1cm4gZXJyOwoKCiAgICAvLyB2YWxpZGF0ZSBNZWRpYVJvdXRlLm1lZGlhU2lua0lkCiAgICBlcnIgPSBtZXNzYWdlVmFsaWRhdG9yLnZhbGlkYXRlU3RyaW5nUG9pbnRlcihvZmZzZXQgKyBjb2RlYy5rU3RydWN0SGVhZGVyU2l6ZSArIDI0LCBmYWxzZSkKICAgIGlmIChlcnIgIT09IHZhbGlkYXRvci52YWxpZGF0aW9uRXJyb3IuTk9ORSkKICAgICAgICByZXR1cm4gZXJyOwoKCiAgICAvLyB2YWxpZGF0ZSBNZWRpYVJvdXRlLmRlc2NyaXB0aW9uCiAgICBlcnIgPSBtZXNzYWdlVmFsaWRhdG9yLnZhbGlkYXRlU3RyaW5nUG9pbnRlcihvZmZzZXQgKyBjb2RlYy5rU3RydWN0SGVhZGVyU2l6ZSArIDMyLCBmYWxzZSkKICAgIGlmIChlcnIgIT09IHZhbGlkYXRvci52YWxpZGF0aW9uRXJyb3IuTk9ORSkKICAgICAgICByZXR1cm4gZXJyOwoKCgogICAgLy8gdmFsaWRhdGUgTWVkaWFSb3V0ZS5jb250cm9sbGVyVHlwZQogICAgZXJyID0gbWVzc2FnZVZhbGlkYXRvci52YWxpZGF0ZUVudW0ob2Zmc2V0ICsgY29kZWMua1N0cnVjdEhlYWRlclNpemUgKyA0NCwgUm91dGVDb250cm9sbGVyVHlwZSk7CiAgICBpZiAoZXJyICE9PSB2YWxpZGF0b3IudmFsaWRhdGlvbkVycm9yLk5PTkUpCiAgICAgICAgcmV0dXJuIGVycjsKCgoKCiAgICByZXR1cm4gdmFsaWRhdG9yLnZhbGlkYXRpb25FcnJvci5OT05FOwogIH07CgogIE1lZGlhUm91dGUuZW5jb2RlZFNpemUgPSBjb2RlYy5rU3RydWN0SGVhZGVyU2l6ZSArIDQ4OwoKICBNZWRpYVJvdXRlLmRlY29kZSA9IGZ1bmN0aW9uKGRlY29kZXIpIHsKICAgIHZhciBwYWNrZWQ7CiAgICB2YXIgdmFsID0gbmV3IE1lZGlhUm91dGUoKTsKICAgIHZhciBudW1iZXJPZkJ5dGVzID0gZGVjb2Rlci5yZWFkVWludDMyKCk7CiAgICB2YXIgdmVyc2lvbiA9IGRlY29kZXIucmVhZFVpbnQzMigpOwogICAgdmFsLm1lZGlhUm91dGVJZCA9IGRlY29kZXIuZGVjb2RlU3RydWN0KGNvZGVjLlN0cmluZyk7CiAgICB2YWwucHJlc2VudGF0aW9uSWQgPSBkZWNvZGVyLmRlY29kZVN0cnVjdChjb2RlYy5TdHJpbmcpOwogICAgdmFsLm1lZGlhU291cmNlID0gZGVjb2Rlci5kZWNvZGVTdHJ1Y3QoY29kZWMuTnVsbGFibGVTdHJpbmcpOwogICAgdmFsLm1lZGlhU2lua0lkID0gZGVjb2Rlci5kZWNvZGVTdHJ1Y3QoY29kZWMuU3RyaW5nKTsKICAgIHZhbC5kZXNjcmlwdGlvbiA9IGRlY29kZXIuZGVjb2RlU3RydWN0KGNvZGVjLlN0cmluZyk7CiAgICBwYWNrZWQgPSBkZWNvZGVyLnJlYWRVaW50OCgpOwogICAgdmFsLmlzTG9jYWwgPSAocGFja2VkID4+IDApICYgMSA/IHRydWUgOiBmYWxzZTsKICAgIHZhbC5mb3JEaXNwbGF5ID0gKHBhY2tlZCA+PiAxKSAmIDEgPyB0cnVlIDogZmFsc2U7CiAgICB2YWwuaXNJbmNvZ25pdG8gPSAocGFja2VkID4+IDIpICYgMSA/IHRydWUgOiBmYWxzZTsKICAgIHZhbC5pc0xvY2FsUHJlc2VudGF0aW9uID0gKHBhY2tlZCA+PiAzKSAmIDEgPyB0cnVlIDogZmFsc2U7CiAgICBkZWNvZGVyLnNraXAoMSk7CiAgICBkZWNvZGVyLnNraXAoMSk7CiAgICBkZWNvZGVyLnNraXAoMSk7CiAgICB2YWwuY29udHJvbGxlclR5cGUgPSBkZWNvZGVyLmRlY29kZVN0cnVjdChjb2RlYy5JbnQzMik7CiAgICByZXR1cm4gdmFsOwogIH07CgogIE1lZGlhUm91dGUuZW5jb2RlID0gZnVuY3Rpb24oZW5jb2RlciwgdmFsKSB7CiAgICB2YXIgcGFja2VkOwogICAgZW5jb2Rlci53cml0ZVVpbnQzMihNZWRpYVJvdXRlLmVuY29kZWRTaXplKTsKICAgIGVuY29kZXIud3JpdGVVaW50MzIoMCk7CiAgICBlbmNvZGVyLmVuY29kZVN0cnVjdChjb2RlYy5TdHJpbmcsIHZhbC5tZWRpYVJvdXRlSWQpOwogICAgZW5jb2Rlci5lbmNvZGVTdHJ1Y3QoY29kZWMuU3RyaW5nLCB2YWwucHJlc2VudGF0aW9uSWQpOwogICAgZW5jb2Rlci5lbmNvZGVTdHJ1Y3QoY29kZWMuTnVsbGFibGVTdHJpbmcsIHZhbC5tZWRpYVNvdXJjZSk7CiAgICBlbmNvZGVyLmVuY29kZVN0cnVjdChjb2RlYy5TdHJpbmcsIHZhbC5tZWRpYVNpbmtJZCk7CiAgICBlbmNvZGVyLmVuY29kZVN0cnVjdChjb2RlYy5TdHJpbmcsIHZhbC5kZXNjcmlwdGlvbik7CiAgICBwYWNrZWQgPSAwOwogICAgcGFja2VkIHw9ICh2YWwuaXNMb2NhbCAmIDEpIDw8IDAKICAgIHBhY2tlZCB8PSAodmFsLmZvckRpc3BsYXkgJiAxKSA8PCAxCiAgICBwYWNrZWQgfD0gKHZhbC5pc0luY29nbml0byAmIDEpIDw8IDIKICAgIHBhY2tlZCB8PSAodmFsLmlzTG9jYWxQcmVzZW50YXRpb24gJiAxKSA8PCAzCiAgICBlbmNvZGVyLndyaXRlVWludDgocGFja2VkKTsKICAgIGVuY29kZXIuc2tpcCgxKTsKICAgIGVuY29kZXIuc2tpcCgxKTsKICAgIGVuY29kZXIuc2tpcCgxKTsKICAgIGVuY29kZXIuZW5jb2RlU3RydWN0KGNvZGVjLkludDMyLCB2YWwuY29udHJvbGxlclR5cGUpOwogIH07CiAgZnVuY3Rpb24gSXNzdWUodmFsdWVzKSB7CiAgICB0aGlzLmluaXREZWZhdWx0c18oKTsKICAgIHRoaXMuaW5pdEZpZWxkc18odmFsdWVzKTsKICB9CgogIElzc3VlLlNldmVyaXR5ID0ge307CiAgSXNzdWUuU2V2ZXJpdHkuRkFUQUwgPSAwOwogIElzc3VlLlNldmVyaXR5LldBUk5JTkcgPSBJc3N1ZS5TZXZlcml0eS5GQVRBTCArIDE7CiAgSXNzdWUuU2V2ZXJpdHkuTk9USUZJQ0FUSU9OID0gSXNzdWUuU2V2ZXJpdHkuV0FSTklORyArIDE7CgogIElzc3VlLlNldmVyaXR5LmlzS25vd25FbnVtVmFsdWUgPSBmdW5jdGlvbih2YWx1ZSkgewogICAgc3dpdGNoICh2YWx1ZSkgewogICAgY2FzZSAwOgogICAgY2FzZSAxOgogICAgY2FzZSAyOgogICAgICByZXR1cm4gdHJ1ZTsKICAgIH0KICAgIHJldHVybiBmYWxzZTsKICB9OwoKICBJc3N1ZS5TZXZlcml0eS52YWxpZGF0ZSA9IGZ1bmN0aW9uKGVudW1WYWx1ZSkgewogICAgdmFyIGlzRXh0ZW5zaWJsZSA9IGZhbHNlOwogICAgaWYgKGlzRXh0ZW5zaWJsZSB8fCB0aGlzLmlzS25vd25FbnVtVmFsdWUoZW51bVZhbHVlKSkKICAgICAgcmV0dXJuIHZhbGlkYXRvci52YWxpZGF0aW9uRXJyb3IuTk9ORTsKCiAgICByZXR1cm4gdmFsaWRhdG9yLnZhbGlkYXRpb25FcnJvci5VTktOT1dOX0VOVU1fVkFMVUU7CiAgfTsKICBJc3N1ZS5BY3Rpb25UeXBlID0ge307CiAgSXNzdWUuQWN0aW9uVHlwZS5ESVNNSVNTID0gMDsKICBJc3N1ZS5BY3Rpb25UeXBlLkxFQVJOX01PUkUgPSBJc3N1ZS5BY3Rpb25UeXBlLkRJU01JU1MgKyAxOwoKICBJc3N1ZS5BY3Rpb25UeXBlLmlzS25vd25FbnVtVmFsdWUgPSBmdW5jdGlvbih2YWx1ZSkgewogICAgc3dpdGNoICh2YWx1ZSkgewogICAgY2FzZSAwOgogICAgY2FzZSAxOgogICAgICByZXR1cm4gdHJ1ZTsKICAgIH0KICAgIHJldHVybiBmYWxzZTsKICB9OwoKICBJc3N1ZS5BY3Rpb25UeXBlLnZhbGlkYXRlID0gZnVuY3Rpb24oZW51bVZhbHVlKSB7CiAgICB2YXIgaXNFeHRlbnNpYmxlID0gZmFsc2U7CiAgICBpZiAoaXNFeHRlbnNpYmxlIHx8IHRoaXMuaXNLbm93bkVudW1WYWx1ZShlbnVtVmFsdWUpKQogICAgICByZXR1cm4gdmFsaWRhdG9yLnZhbGlkYXRpb25FcnJvci5OT05FOwoKICAgIHJldHVybiB2YWxpZGF0b3IudmFsaWRhdGlvbkVycm9yLlVOS05PV05fRU5VTV9WQUxVRTsKICB9OwoKICBJc3N1ZS5wcm90b3R5cGUuaW5pdERlZmF1bHRzXyA9IGZ1bmN0aW9uKCkgewogICAgdGhpcy5yb3V0ZUlkID0gbnVsbDsKICAgIHRoaXMuc2V2ZXJpdHkgPSAwOwogICAgdGhpcy5pc0Jsb2NraW5nID0gZmFsc2U7CiAgICB0aGlzLnRpdGxlID0gbnVsbDsKICAgIHRoaXMubWVzc2FnZSA9IG51bGw7CiAgICB0aGlzLmRlZmF1bHRBY3Rpb24gPSAwOwogICAgdGhpcy5oZWxwUGFnZUlkID0gMDsKICAgIHRoaXMuc2Vjb25kYXJ5QWN0aW9ucyA9IG51bGw7CiAgfTsKICBJc3N1ZS5wcm90b3R5cGUuaW5pdEZpZWxkc18gPSBmdW5jdGlvbihmaWVsZHMpIHsKICAgIGZvcih2YXIgZmllbGQgaW4gZmllbGRzKSB7CiAgICAgICAgaWYgKHRoaXMuaGFzT3duUHJvcGVydHkoZmllbGQpKQogICAgICAgICAgdGhpc1tmaWVsZF0gPSBmaWVsZHNbZmllbGRdOwogICAgfQogIH07CgogIElzc3VlLnZhbGlkYXRlID0gZnVuY3Rpb24obWVzc2FnZVZhbGlkYXRvciwgb2Zmc2V0KSB7CiAgICB2YXIgZXJyOwogICAgZXJyID0gbWVzc2FnZVZhbGlkYXRvci52YWxpZGF0ZVN0cnVjdEhlYWRlcihvZmZzZXQsIGNvZGVjLmtTdHJ1Y3RIZWFkZXJTaXplKTsKICAgIGlmIChlcnIgIT09IHZhbGlkYXRvci52YWxpZGF0aW9uRXJyb3IuTk9ORSkKICAgICAgICByZXR1cm4gZXJyOwoKICAgIHZhciBrVmVyc2lvblNpemVzID0gWwogICAgICB7dmVyc2lvbjogMCwgbnVtQnl0ZXM6IDU2fQogICAgXTsKICAgIGVyciA9IG1lc3NhZ2VWYWxpZGF0b3IudmFsaWRhdGVTdHJ1Y3RWZXJzaW9uKG9mZnNldCwga1ZlcnNpb25TaXplcyk7CiAgICBpZiAoZXJyICE9PSB2YWxpZGF0b3IudmFsaWRhdGlvbkVycm9yLk5PTkUpCiAgICAgICAgcmV0dXJuIGVycjsKCgogICAgLy8gdmFsaWRhdGUgSXNzdWUucm91dGVJZAogICAgZXJyID0gbWVzc2FnZVZhbGlkYXRvci52YWxpZGF0ZVN0cmluZ1BvaW50ZXIob2Zmc2V0ICsgY29kZWMua1N0cnVjdEhlYWRlclNpemUgKyAwLCB0cnVlKQogICAgaWYgKGVyciAhPT0gdmFsaWRhdG9yLnZhbGlkYXRpb25FcnJvci5OT05FKQogICAgICAgIHJldHVybiBlcnI7CgoKICAgIC8vIHZhbGlkYXRlIElzc3VlLnNldmVyaXR5CiAgICBlcnIgPSBtZXNzYWdlVmFsaWRhdG9yLnZhbGlkYXRlRW51bShvZmZzZXQgKyBjb2RlYy5rU3RydWN0SGVhZGVyU2l6ZSArIDgsIElzc3VlLlNldmVyaXR5KTsKICAgIGlmIChlcnIgIT09IHZhbGlkYXRvci52YWxpZGF0aW9uRXJyb3IuTk9ORSkKICAgICAgICByZXR1cm4gZXJyOwoKCgogICAgLy8gdmFsaWRhdGUgSXNzdWUudGl0bGUKICAgIGVyciA9IG1lc3NhZ2VWYWxpZGF0b3IudmFsaWRhdGVTdHJpbmdQb2ludGVyKG9mZnNldCArIGNvZGVjLmtTdHJ1Y3RIZWFkZXJTaXplICsgMTYsIGZhbHNlKQogICAgaWYgKGVyciAhPT0gdmFsaWRhdG9yLnZhbGlkYXRpb25FcnJvci5OT05FKQogICAgICAgIHJldHVybiBlcnI7CgoKICAgIC8vIHZhbGlkYXRlIElzc3VlLm1lc3NhZ2UKICAgIGVyciA9IG1lc3NhZ2VWYWxpZGF0b3IudmFsaWRhdGVTdHJpbmdQb2ludGVyKG9mZnNldCArIGNvZGVjLmtTdHJ1Y3RIZWFkZXJTaXplICsgMjQsIHRydWUpCiAgICBpZiAoZXJyICE9PSB2YWxpZGF0b3IudmFsaWRhdGlvbkVycm9yLk5PTkUpCiAgICAgICAgcmV0dXJuIGVycjsKCgogICAgLy8gdmFsaWRhdGUgSXNzdWUuZGVmYXVsdEFjdGlvbgogICAgZXJyID0gbWVzc2FnZVZhbGlkYXRvci52YWxpZGF0ZUVudW0ob2Zmc2V0ICsgY29kZWMua1N0cnVjdEhlYWRlclNpemUgKyAzMiwgSXNzdWUuQWN0aW9uVHlwZSk7CiAgICBpZiAoZXJyICE9PSB2YWxpZGF0b3IudmFsaWRhdGlvbkVycm9yLk5PTkUpCiAgICAgICAgcmV0dXJuIGVycjsKCgogICAgLy8gdmFsaWRhdGUgSXNzdWUuc2Vjb25kYXJ5QWN0aW9ucwogICAgZXJyID0gbWVzc2FnZVZhbGlkYXRvci52YWxpZGF0ZUFycmF5UG9pbnRlcihvZmZzZXQgKyBjb2RlYy5rU3RydWN0SGVhZGVyU2l6ZSArIDQwLCA0LCBuZXcgY29kZWMuRW51bShJc3N1ZS5BY3Rpb25UeXBlKSwgZmFsc2UsIFswXSwgMCk7CiAgICBpZiAoZXJyICE9PSB2YWxpZGF0b3IudmFsaWRhdGlvbkVycm9yLk5PTkUpCiAgICAgICAgcmV0dXJuIGVycjsKCgogICAgcmV0dXJuIHZhbGlkYXRvci52YWxpZGF0aW9uRXJyb3IuTk9ORTsKICB9OwoKICBJc3N1ZS5lbmNvZGVkU2l6ZSA9IGNvZGVjLmtTdHJ1Y3RIZWFkZXJTaXplICsgNDg7CgogIElzc3VlLmRlY29kZSA9IGZ1bmN0aW9uKGRlY29kZXIpIHsKICAgIHZhciBwYWNrZWQ7CiAgICB2YXIgdmFsID0gbmV3IElzc3VlKCk7CiAgICB2YXIgbnVtYmVyT2ZCeXRlcyA9IGRlY29kZXIucmVhZFVpbnQzMigpOwogICAgdmFyIHZlcnNpb24gPSBkZWNvZGVyLnJlYWRVaW50MzIoKTsKICAgIHZhbC5yb3V0ZUlkID0gZGVjb2Rlci5kZWNvZGVTdHJ1Y3QoY29kZWMuTnVsbGFibGVTdHJpbmcpOwogICAgdmFsLnNldmVyaXR5ID0gZGVjb2Rlci5kZWNvZGVTdHJ1Y3QoY29kZWMuSW50MzIpOwogICAgcGFja2VkID0gZGVjb2Rlci5yZWFkVWludDgoKTsKICAgIHZhbC5pc0Jsb2NraW5nID0gKHBhY2tlZCA+PiAwKSAmIDEgPyB0cnVlIDogZmFsc2U7CiAgICBkZWNvZGVyLnNraXAoMSk7CiAgICBkZWNvZGVyLnNraXAoMSk7CiAgICBkZWNvZGVyLnNraXAoMSk7CiAgICB2YWwudGl0bGUgPSBkZWNvZGVyLmRlY29kZVN0cnVjdChjb2RlYy5TdHJpbmcpOwogICAgdmFsLm1lc3NhZ2UgPSBkZWNvZGVyLmRlY29kZVN0cnVjdChjb2RlYy5OdWxsYWJsZVN0cmluZyk7CiAgICB2YWwuZGVmYXVsdEFjdGlvbiA9IGRlY29kZXIuZGVjb2RlU3RydWN0KGNvZGVjLkludDMyKTsKICAgIHZhbC5oZWxwUGFnZUlkID0gZGVjb2Rlci5kZWNvZGVTdHJ1Y3QoY29kZWMuSW50MzIpOwogICAgdmFsLnNlY29uZGFyeUFjdGlvbnMgPSBkZWNvZGVyLmRlY29kZUFycmF5UG9pbnRlcihuZXcgY29kZWMuRW51bShJc3N1ZS5BY3Rpb25UeXBlKSk7CiAgICByZXR1cm4gdmFsOwogIH07CgogIElzc3VlLmVuY29kZSA9IGZ1bmN0aW9uKGVuY29kZXIsIHZhbCkgewogICAgdmFyIHBhY2tlZDsKICAgIGVuY29kZXIud3JpdGVVaW50MzIoSXNzdWUuZW5jb2RlZFNpemUpOwogICAgZW5jb2Rlci53cml0ZVVpbnQzMigwKTsKICAgIGVuY29kZXIuZW5jb2RlU3RydWN0KGNvZGVjLk51bGxhYmxlU3RyaW5nLCB2YWwucm91dGVJZCk7CiAgICBlbmNvZGVyLmVuY29kZVN0cnVjdChjb2RlYy5JbnQzMiwgdmFsLnNldmVyaXR5KTsKICAgIHBhY2tlZCA9IDA7CiAgICBwYWNrZWQgfD0gKHZhbC5pc0Jsb2NraW5nICYgMSkgPDwgMAogICAgZW5jb2Rlci53cml0ZVVpbnQ4KHBhY2tlZCk7CiAgICBlbmNvZGVyLnNraXAoMSk7CiAgICBlbmNvZGVyLnNraXAoMSk7CiAgICBlbmNvZGVyLnNraXAoMSk7CiAgICBlbmNvZGVyLmVuY29kZVN0cnVjdChjb2RlYy5TdHJpbmcsIHZhbC50aXRsZSk7CiAgICBlbmNvZGVyLmVuY29kZVN0cnVjdChjb2RlYy5OdWxsYWJsZVN0cmluZywgdmFsLm1lc3NhZ2UpOwogICAgZW5jb2Rlci5lbmNvZGVTdHJ1Y3QoY29kZWMuSW50MzIsIHZhbC5kZWZhdWx0QWN0aW9uKTsKICAgIGVuY29kZXIuZW5jb2RlU3RydWN0KGNvZGVjLkludDMyLCB2YWwuaGVscFBhZ2VJZCk7CiAgICBlbmNvZGVyLmVuY29kZUFycmF5UG9pbnRlcihuZXcgY29kZWMuRW51bShJc3N1ZS5BY3Rpb25UeXBlKSwgdmFsLnNlY29uZGFyeUFjdGlvbnMpOwogIH07CiAgZnVuY3Rpb24gUm91dGVNZXNzYWdlKHZhbHVlcykgewogICAgdGhpcy5pbml0RGVmYXVsdHNfKCk7CiAgICB0aGlzLmluaXRGaWVsZHNfKHZhbHVlcyk7CiAgfQoKICBSb3V0ZU1lc3NhZ2UuVHlwZSA9IHt9OwogIFJvdXRlTWVzc2FnZS5UeXBlLlRFWFQgPSAwOwogIFJvdXRlTWVzc2FnZS5UeXBlLkJJTkFSWSA9IFJvdXRlTWVzc2FnZS5UeXBlLlRFWFQgKyAxOwoKICBSb3V0ZU1lc3NhZ2UuVHlwZS5pc0tub3duRW51bVZhbHVlID0gZnVuY3Rpb24odmFsdWUpIHsKICAgIHN3aXRjaCAodmFsdWUpIHsKICAgIGNhc2UgMDoKICAgIGNhc2UgMToKICAgICAgcmV0dXJuIHRydWU7CiAgICB9CiAgICByZXR1cm4gZmFsc2U7CiAgfTsKCiAgUm91dGVNZXNzYWdlLlR5cGUudmFsaWRhdGUgPSBmdW5jdGlvbihlbnVtVmFsdWUpIHsKICAgIHZhciBpc0V4dGVuc2libGUgPSBmYWxzZTsKICAgIGlmIChpc0V4dGVuc2libGUgfHwgdGhpcy5pc0tub3duRW51bVZhbHVlKGVudW1WYWx1ZSkpCiAgICAgIHJldHVybiB2YWxpZGF0b3IudmFsaWRhdGlvbkVycm9yLk5PTkU7CgogICAgcmV0dXJuIHZhbGlkYXRvci52YWxpZGF0aW9uRXJyb3IuVU5LTk9XTl9FTlVNX1ZBTFVFOwogIH07CgogIFJvdXRlTWVzc2FnZS5wcm90b3R5cGUuaW5pdERlZmF1bHRzXyA9IGZ1bmN0aW9uKCkgewogICAgdGhpcy50eXBlID0gMDsKICAgIHRoaXMubWVzc2FnZSA9IG51bGw7CiAgICB0aGlzLmRhdGEgPSBudWxsOwogIH07CiAgUm91dGVNZXNzYWdlLnByb3RvdHlwZS5pbml0RmllbGRzXyA9IGZ1bmN0aW9uKGZpZWxkcykgewogICAgZm9yKHZhciBmaWVsZCBpbiBmaWVsZHMpIHsKICAgICAgICBpZiAodGhpcy5oYXNPd25Qcm9wZXJ0eShmaWVsZCkpCiAgICAgICAgICB0aGlzW2ZpZWxkXSA9IGZpZWxkc1tmaWVsZF07CiAgICB9CiAgfTsKCiAgUm91dGVNZXNzYWdlLnZhbGlkYXRlID0gZnVuY3Rpb24obWVzc2FnZVZhbGlkYXRvciwgb2Zmc2V0KSB7CiAgICB2YXIgZXJyOwogICAgZXJyID0gbWVzc2FnZVZhbGlkYXRvci52YWxpZGF0ZVN0cnVjdEhlYWRlcihvZmZzZXQsIGNvZGVjLmtTdHJ1Y3RIZWFkZXJTaXplKTsKICAgIGlmIChlcnIgIT09IHZhbGlkYXRvci52YWxpZGF0aW9uRXJyb3IuTk9ORSkKICAgICAgICByZXR1cm4gZXJyOwoKICAgIHZhciBrVmVyc2lvblNpemVzID0gWwogICAgICB7dmVyc2lvbjogMCwgbnVtQnl0ZXM6IDMyfQogICAgXTsKICAgIGVyciA9IG1lc3NhZ2VWYWxpZGF0b3IudmFsaWRhdGVTdHJ1Y3RWZXJzaW9uKG9mZnNldCwga1ZlcnNpb25TaXplcyk7CiAgICBpZiAoZXJyICE9PSB2YWxpZGF0b3IudmFsaWRhdGlvbkVycm9yLk5PTkUpCiAgICAgICAgcmV0dXJuIGVycjsKCgogICAgLy8gdmFsaWRhdGUgUm91dGVNZXNzYWdlLnR5cGUKICAgIGVyciA9IG1lc3NhZ2VWYWxpZGF0b3IudmFsaWRhdGVFbnVtKG9mZnNldCArIGNvZGVjLmtTdHJ1Y3RIZWFkZXJTaXplICsgMCwgUm91dGVNZXNzYWdlLlR5cGUpOwogICAgaWYgKGVyciAhPT0gdmFsaWRhdG9yLnZhbGlkYXRpb25FcnJvci5OT05FKQogICAgICAgIHJldHVybiBlcnI7CgoKICAgIC8vIHZhbGlkYXRlIFJvdXRlTWVzc2FnZS5tZXNzYWdlCiAgICBlcnIgPSBtZXNzYWdlVmFsaWRhdG9yLnZhbGlkYXRlU3RyaW5nUG9pbnRlcihvZmZzZXQgKyBjb2RlYy5rU3RydWN0SGVhZGVyU2l6ZSArIDgsIHRydWUpCiAgICBpZiAoZXJyICE9PSB2YWxpZGF0b3IudmFsaWRhdGlvbkVycm9yLk5PTkUpCiAgICAgICAgcmV0dXJuIGVycjsKCgogICAgLy8gdmFsaWRhdGUgUm91dGVNZXNzYWdlLmRhdGEKICAgIGVyciA9IG1lc3NhZ2VWYWxpZGF0b3IudmFsaWRhdGVBcnJheVBvaW50ZXIob2Zmc2V0ICsgY29kZWMua1N0cnVjdEhlYWRlclNpemUgKyAxNiwgMSwgY29kZWMuVWludDgsIHRydWUsIFswXSwgMCk7CiAgICBpZiAoZXJyICE9PSB2YWxpZGF0b3IudmFsaWRhdGlvbkVycm9yLk5PTkUpCiAgICAgICAgcmV0dXJuIGVycjsKCiAgICByZXR1cm4gdmFsaWRhdG9yLnZhbGlkYXRpb25FcnJvci5OT05FOwogIH07CgogIFJvdXRlTWVzc2FnZS5lbmNvZGVkU2l6ZSA9IGNvZGVjLmtTdHJ1Y3RIZWFkZXJTaXplICsgMjQ7CgogIFJvdXRlTWVzc2FnZS5kZWNvZGUgPSBmdW5jdGlvbihkZWNvZGVyKSB7CiAgICB2YXIgcGFja2VkOwogICAgdmFyIHZhbCA9IG5ldyBSb3V0ZU1lc3NhZ2UoKTsKICAgIHZhciBudW1iZXJPZkJ5dGVzID0gZGVjb2Rlci5yZWFkVWludDMyKCk7CiAgICB2YXIgdmVyc2lvbiA9IGRlY29kZXIucmVhZFVpbnQzMigpOwogICAgdmFsLnR5cGUgPSBkZWNvZGVyLmRlY29kZVN0cnVjdChjb2RlYy5JbnQzMik7CiAgICBkZWNvZGVyLnNraXAoMSk7CiAgICBkZWNvZGVyLnNraXAoMSk7CiAgICBkZWNvZGVyLnNraXAoMSk7CiAgICBkZWNvZGVyLnNraXAoMSk7CiAgICB2YWwubWVzc2FnZSA9IGRlY29kZXIuZGVjb2RlU3RydWN0KGNvZGVjLk51bGxhYmxlU3RyaW5nKTsKICAgIHZhbC5kYXRhID0gZGVjb2Rlci5kZWNvZGVBcnJheVBvaW50ZXIoY29kZWMuVWludDgpOwogICAgcmV0dXJuIHZhbDsKICB9OwoKICBSb3V0ZU1lc3NhZ2UuZW5jb2RlID0gZnVuY3Rpb24oZW5jb2RlciwgdmFsKSB7CiAgICB2YXIgcGFja2VkOwogICAgZW5jb2Rlci53cml0ZVVpbnQzMihSb3V0ZU1lc3NhZ2UuZW5jb2RlZFNpemUpOwogICAgZW5jb2Rlci53cml0ZVVpbnQzMigwKTsKICAgIGVuY29kZXIuZW5jb2RlU3RydWN0KGNvZGVjLkludDMyLCB2YWwudHlwZSk7CiAgICBlbmNvZGVyLnNraXAoMSk7CiAgICBlbmNvZGVyLnNraXAoMSk7CiAgICBlbmNvZGVyLnNraXAoMSk7CiAgICBlbmNvZGVyLnNraXAoMSk7CiAgICBlbmNvZGVyLmVuY29kZVN0cnVjdChjb2RlYy5OdWxsYWJsZVN0cmluZywgdmFsLm1lc3NhZ2UpOwogICAgZW5jb2Rlci5lbmNvZGVBcnJheVBvaW50ZXIoY29kZWMuVWludDgsIHZhbC5kYXRhKTsKICB9OwogIGZ1bmN0aW9uIFNpbmtTZWFyY2hDcml0ZXJpYSh2YWx1ZXMpIHsKICAgIHRoaXMuaW5pdERlZmF1bHRzXygpOwogICAgdGhpcy5pbml0RmllbGRzXyh2YWx1ZXMpOwogIH0KCgogIFNpbmtTZWFyY2hDcml0ZXJpYS5wcm90b3R5cGUuaW5pdERlZmF1bHRzXyA9IGZ1bmN0aW9uKCkgewogICAgdGhpcy5pbnB1dCA9IG51bGw7CiAgICB0aGlzLmRvbWFpbiA9IG51bGw7CiAgfTsKICBTaW5rU2VhcmNoQ3JpdGVyaWEucHJvdG90eXBlLmluaXRGaWVsZHNfID0gZnVuY3Rpb24oZmllbGRzKSB7CiAgICBmb3IodmFyIGZpZWxkIGluIGZpZWxkcykgewogICAgICAgIGlmICh0aGlzLmhhc093blByb3BlcnR5KGZpZWxkKSkKICAgICAgICAgIHRoaXNbZmllbGRdID0gZmllbGRzW2ZpZWxkXTsKICAgIH0KICB9OwoKICBTaW5rU2VhcmNoQ3JpdGVyaWEudmFsaWRhdGUgPSBmdW5jdGlvbihtZXNzYWdlVmFsaWRhdG9yLCBvZmZzZXQpIHsKICAgIHZhciBlcnI7CiAgICBlcnIgPSBtZXNzYWdlVmFsaWRhdG9yLnZhbGlkYXRlU3RydWN0SGVhZGVyKG9mZnNldCwgY29kZWMua1N0cnVjdEhlYWRlclNpemUpOwogICAgaWYgKGVyciAhPT0gdmFsaWRhdG9yLnZhbGlkYXRpb25FcnJvci5OT05FKQogICAgICAgIHJldHVybiBlcnI7CgogICAgdmFyIGtWZXJzaW9uU2l6ZXMgPSBbCiAgICAgIHt2ZXJzaW9uOiAwLCBudW1CeXRlczogMjR9CiAgICBdOwogICAgZXJyID0gbWVzc2FnZVZhbGlkYXRvci52YWxpZGF0ZVN0cnVjdFZlcnNpb24ob2Zmc2V0LCBrVmVyc2lvblNpemVzKTsKICAgIGlmIChlcnIgIT09IHZhbGlkYXRvci52YWxpZGF0aW9uRXJyb3IuTk9ORSkKICAgICAgICByZXR1cm4gZXJyOwoKCiAgICAvLyB2YWxpZGF0ZSBTaW5rU2VhcmNoQ3JpdGVyaWEuaW5wdXQKICAgIGVyciA9IG1lc3NhZ2VWYWxpZGF0b3IudmFsaWRhdGVTdHJpbmdQb2ludGVyKG9mZnNldCArIGNvZGVjLmtTdHJ1Y3RIZWFkZXJTaXplICsgMCwgZmFsc2UpCiAgICBpZiAoZXJyICE9PSB2YWxpZGF0b3IudmFsaWRhdGlvbkVycm9yLk5PTkUpCiAgICAgICAgcmV0dXJuIGVycjsKCgogICAgLy8gdmFsaWRhdGUgU2lua1NlYXJjaENyaXRlcmlhLmRvbWFpbgogICAgZXJyID0gbWVzc2FnZVZhbGlkYXRvci52YWxpZGF0ZVN0cmluZ1BvaW50ZXIob2Zmc2V0ICsgY29kZWMua1N0cnVjdEhlYWRlclNpemUgKyA4LCBmYWxzZSkKICAgIGlmIChlcnIgIT09IHZhbGlkYXRvci52YWxpZGF0aW9uRXJyb3IuTk9ORSkKICAgICAgICByZXR1cm4gZXJyOwoKICAgIHJldHVybiB2YWxpZGF0b3IudmFsaWRhdGlvbkVycm9yLk5PTkU7CiAgfTsKCiAgU2lua1NlYXJjaENyaXRlcmlhLmVuY29kZWRTaXplID0gY29kZWMua1N0cnVjdEhlYWRlclNpemUgKyAxNjsKCiAgU2lua1NlYXJjaENyaXRlcmlhLmRlY29kZSA9IGZ1bmN0aW9uKGRlY29kZXIpIHsKICAgIHZhciBwYWNrZWQ7CiAgICB2YXIgdmFsID0gbmV3IFNpbmtTZWFyY2hDcml0ZXJpYSgpOwogICAgdmFyIG51bWJlck9mQnl0ZXMgPSBkZWNvZGVyLnJlYWRVaW50MzIoKTsKICAgIHZhciB2ZXJzaW9uID0gZGVjb2Rlci5yZWFkVWludDMyKCk7CiAgICB2YWwuaW5wdXQgPSBkZWNvZGVyLmRlY29kZVN0cnVjdChjb2RlYy5TdHJpbmcpOwogICAgdmFsLmRvbWFpbiA9IGRlY29kZXIuZGVjb2RlU3RydWN0KGNvZGVjLlN0cmluZyk7CiAgICByZXR1cm4gdmFsOwogIH07CgogIFNpbmtTZWFyY2hDcml0ZXJpYS5lbmNvZGUgPSBmdW5jdGlvbihlbmNvZGVyLCB2YWwpIHsKICAgIHZhciBwYWNrZWQ7CiAgICBlbmNvZGVyLndyaXRlVWludDMyKFNpbmtTZWFyY2hDcml0ZXJpYS5lbmNvZGVkU2l6ZSk7CiAgICBlbmNvZGVyLndyaXRlVWludDMyKDApOwogICAgZW5jb2Rlci5lbmNvZGVTdHJ1Y3QoY29kZWMuU3RyaW5nLCB2YWwuaW5wdXQpOwogICAgZW5jb2Rlci5lbmNvZGVTdHJ1Y3QoY29kZWMuU3RyaW5nLCB2YWwuZG9tYWluKTsKICB9OwogIGZ1bmN0aW9uIE1lZGlhUm91dGVQcm92aWRlckNvbmZpZyh2YWx1ZXMpIHsKICAgIHRoaXMuaW5pdERlZmF1bHRzXygpOwogICAgdGhpcy5pbml0RmllbGRzXyh2YWx1ZXMpOwogIH0KCgogIE1lZGlhUm91dGVQcm92aWRlckNvbmZpZy5wcm90b3R5cGUuaW5pdERlZmF1bHRzXyA9IGZ1bmN0aW9uKCkgewogICAgdGhpcy5lbmFibGVEaWFsRGlzY292ZXJ5ID0gZmFsc2U7CiAgICB0aGlzLmVuYWJsZUNhc3REaXNjb3ZlcnkgPSBmYWxzZTsKICB9OwogIE1lZGlhUm91dGVQcm92aWRlckNvbmZpZy5wcm90b3R5cGUuaW5pdEZpZWxkc18gPSBmdW5jdGlvbihmaWVsZHMpIHsKICAgIGZvcih2YXIgZmllbGQgaW4gZmllbGRzKSB7CiAgICAgICAgaWYgKHRoaXMuaGFzT3duUHJvcGVydHkoZmllbGQpKQogICAgICAgICAgdGhpc1tmaWVsZF0gPSBmaWVsZHNbZmllbGRdOwogICAgfQogIH07CgogIE1lZGlhUm91dGVQcm92aWRlckNvbmZpZy52YWxpZGF0ZSA9IGZ1bmN0aW9uKG1lc3NhZ2VWYWxpZGF0b3IsIG9mZnNldCkgewogICAgdmFyIGVycjsKICAgIGVyciA9IG1lc3NhZ2VWYWxpZGF0b3IudmFsaWRhdGVTdHJ1Y3RIZWFkZXIob2Zmc2V0LCBjb2RlYy5rU3RydWN0SGVhZGVyU2l6ZSk7CiAgICBpZiAoZXJyICE9PSB2YWxpZGF0b3IudmFsaWRhdGlvbkVycm9yLk5PTkUpCiAgICAgICAgcmV0dXJuIGVycjsKCiAgICB2YXIga1ZlcnNpb25TaXplcyA9IFsKICAgICAge3ZlcnNpb246IDAsIG51bUJ5dGVzOiAxNn0KICAgIF07CiAgICBlcnIgPSBtZXNzYWdlVmFsaWRhdG9yLnZhbGlkYXRlU3RydWN0VmVyc2lvbihvZmZzZXQsIGtWZXJzaW9uU2l6ZXMpOwogICAgaWYgKGVyciAhPT0gdmFsaWRhdG9yLnZhbGlkYXRpb25FcnJvci5OT05FKQogICAgICAgIHJldHVybiBlcnI7CgoKCiAgICByZXR1cm4gdmFsaWRhdG9yLnZhbGlkYXRpb25FcnJvci5OT05FOwogIH07CgogIE1lZGlhUm91dGVQcm92aWRlckNvbmZpZy5lbmNvZGVkU2l6ZSA9IGNvZGVjLmtTdHJ1Y3RIZWFkZXJTaXplICsgODsKCiAgTWVkaWFSb3V0ZVByb3ZpZGVyQ29uZmlnLmRlY29kZSA9IGZ1bmN0aW9uKGRlY29kZXIpIHsKICAgIHZhciBwYWNrZWQ7CiAgICB2YXIgdmFsID0gbmV3IE1lZGlhUm91dGVQcm92aWRlckNvbmZpZygpOwogICAgdmFyIG51bWJlck9mQnl0ZXMgPSBkZWNvZGVyLnJlYWRVaW50MzIoKTsKICAgIHZhciB2ZXJzaW9uID0gZGVjb2Rlci5yZWFkVWludDMyKCk7CiAgICBwYWNrZWQgPSBkZWNvZGVyLnJlYWRVaW50OCgpOwogICAgdmFsLmVuYWJsZURpYWxEaXNjb3ZlcnkgPSAocGFja2VkID4+IDApICYgMSA/IHRydWUgOiBmYWxzZTsKICAgIHZhbC5lbmFibGVDYXN0RGlzY292ZXJ5ID0gKHBhY2tlZCA+PiAxKSAmIDEgPyB0cnVlIDogZmFsc2U7CiAgICBkZWNvZGVyLnNraXAoMSk7CiAgICBkZWNvZGVyLnNraXAoMSk7CiAgICBkZWNvZGVyLnNraXAoMSk7CiAgICBkZWNvZGVyLnNraXAoMSk7CiAgICBkZWNvZGVyLnNraXAoMSk7CiAgICBkZWNvZGVyLnNraXAoMSk7CiAgICBkZWNvZGVyLnNraXAoMSk7CiAgICByZXR1cm4gdmFsOwogIH07CgogIE1lZGlhUm91dGVQcm92aWRlckNvbmZpZy5lbmNvZGUgPSBmdW5jdGlvbihlbmNvZGVyLCB2YWwpIHsKICAgIHZhciBwYWNrZWQ7CiAgICBlbmNvZGVyLndyaXRlVWludDMyKE1lZGlhUm91dGVQcm92aWRlckNvbmZpZy5lbmNvZGVkU2l6ZSk7CiAgICBlbmNvZGVyLndyaXRlVWludDMyKDApOwogICAgcGFja2VkID0gMDsKICAgIHBhY2tlZCB8PSAodmFsLmVuYWJsZURpYWxEaXNjb3ZlcnkgJiAxKSA8PCAwCiAgICBwYWNrZWQgfD0gKHZhbC5lbmFibGVDYXN0RGlzY292ZXJ5ICYgMSkgPDwgMQogICAgZW5jb2Rlci53cml0ZVVpbnQ4KHBhY2tlZCk7CiAgICBlbmNvZGVyLnNraXAoMSk7CiAgICBlbmNvZGVyLnNraXAoMSk7CiAgICBlbmNvZGVyLnNraXAoMSk7CiAgICBlbmNvZGVyLnNraXAoMSk7CiAgICBlbmNvZGVyLnNraXAoMSk7CiAgICBlbmNvZGVyLnNraXAoMSk7CiAgICBlbmNvZGVyLnNraXAoMSk7CiAgfTsKICBmdW5jdGlvbiBNZWRpYVJvdXRlUHJvdmlkZXJfQ3JlYXRlUm91dGVfUGFyYW1zKHZhbHVlcykgewogICAgdGhpcy5pbml0RGVmYXVsdHNfKCk7CiAgICB0aGlzLmluaXRGaWVsZHNfKHZhbHVlcyk7CiAgfQoKCiAgTWVkaWFSb3V0ZVByb3ZpZGVyX0NyZWF0ZVJvdXRlX1BhcmFtcy5wcm90b3R5cGUuaW5pdERlZmF1bHRzXyA9IGZ1bmN0aW9uKCkgewogICAgdGhpcy5tZWRpYVNvdXJjZSA9IG51bGw7CiAgICB0aGlzLnNpbmtJZCA9IG51bGw7CiAgICB0aGlzLm9yaWdpbmFsUHJlc2VudGF0aW9uSWQgPSBudWxsOwogICAgdGhpcy5vcmlnaW4gPSBudWxsOwogICAgdGhpcy50YWJJZCA9IDA7CiAgICB0aGlzLmluY29nbml0byA9IGZhbHNlOwogICAgdGhpcy50aW1lb3V0ID0gbnVsbDsKICB9OwogIE1lZGlhUm91dGVQcm92aWRlcl9DcmVhdGVSb3V0ZV9QYXJhbXMucHJvdG90eXBlLmluaXRGaWVsZHNfID0gZnVuY3Rpb24oZmllbGRzKSB7CiAgICBmb3IodmFyIGZpZWxkIGluIGZpZWxkcykgewogICAgICAgIGlmICh0aGlzLmhhc093blByb3BlcnR5KGZpZWxkKSkKICAgICAgICAgIHRoaXNbZmllbGRdID0gZmllbGRzW2ZpZWxkXTsKICAgIH0KICB9OwoKICBNZWRpYVJvdXRlUHJvdmlkZXJfQ3JlYXRlUm91dGVfUGFyYW1zLnZhbGlkYXRlID0gZnVuY3Rpb24obWVzc2FnZVZhbGlkYXRvciwgb2Zmc2V0KSB7CiAgICB2YXIgZXJyOwogICAgZXJyID0gbWVzc2FnZVZhbGlkYXRvci52YWxpZGF0ZVN0cnVjdEhlYWRlcihvZmZzZXQsIGNvZGVjLmtTdHJ1Y3RIZWFkZXJTaXplKTsKICAgIGlmIChlcnIgIT09IHZhbGlkYXRvci52YWxpZGF0aW9uRXJyb3IuTk9ORSkKICAgICAgICByZXR1cm4gZXJyOwoKICAgIHZhciBrVmVyc2lvblNpemVzID0gWwogICAgICB7dmVyc2lvbjogMCwgbnVtQnl0ZXM6IDU2fQogICAgXTsKICAgIGVyciA9IG1lc3NhZ2VWYWxpZGF0b3IudmFsaWRhdGVTdHJ1Y3RWZXJzaW9uKG9mZnNldCwga1ZlcnNpb25TaXplcyk7CiAgICBpZiAoZXJyICE9PSB2YWxpZGF0b3IudmFsaWRhdGlvbkVycm9yLk5PTkUpCiAgICAgICAgcmV0dXJuIGVycjsKCgogICAgLy8gdmFsaWRhdGUgTWVkaWFSb3V0ZVByb3ZpZGVyX0NyZWF0ZVJvdXRlX1BhcmFtcy5tZWRpYVNvdXJjZQogICAgZXJyID0gbWVzc2FnZVZhbGlkYXRvci52YWxpZGF0ZVN0cmluZ1BvaW50ZXIob2Zmc2V0ICsgY29kZWMua1N0cnVjdEhlYWRlclNpemUgKyAwLCBmYWxzZSkKICAgIGlmIChlcnIgIT09IHZhbGlkYXRvci52YWxpZGF0aW9uRXJyb3IuTk9ORSkKICAgICAgICByZXR1cm4gZXJyOwoKCiAgICAvLyB2YWxpZGF0ZSBNZWRpYVJvdXRlUHJvdmlkZXJfQ3JlYXRlUm91dGVfUGFyYW1zLnNpbmtJZAogICAgZXJyID0gbWVzc2FnZVZhbGlkYXRvci52YWxpZGF0ZVN0cmluZ1BvaW50ZXIob2Zmc2V0ICsgY29kZWMua1N0cnVjdEhlYWRlclNpemUgKyA4LCBmYWxzZSkKICAgIGlmIChlcnIgIT09IHZhbGlkYXRvci52YWxpZGF0aW9uRXJyb3IuTk9ORSkKICAgICAgICByZXR1cm4gZXJyOwoKCiAgICAvLyB2YWxpZGF0ZSBNZWRpYVJvdXRlUHJvdmlkZXJfQ3JlYXRlUm91dGVfUGFyYW1zLm9yaWdpbmFsUHJlc2VudGF0aW9uSWQKICAgIGVyciA9IG1lc3NhZ2VWYWxpZGF0b3IudmFsaWRhdGVTdHJpbmdQb2ludGVyKG9mZnNldCArIGNvZGVjLmtTdHJ1Y3RIZWFkZXJTaXplICsgMTYsIGZhbHNlKQogICAgaWYgKGVyciAhPT0gdmFsaWRhdG9yLnZhbGlkYXRpb25FcnJvci5OT05FKQogICAgICAgIHJldHVybiBlcnI7CgoKICAgIC8vIHZhbGlkYXRlIE1lZGlhUm91dGVQcm92aWRlcl9DcmVhdGVSb3V0ZV9QYXJhbXMub3JpZ2luCiAgICBlcnIgPSBtZXNzYWdlVmFsaWRhdG9yLnZhbGlkYXRlU3RydWN0UG9pbnRlcihvZmZzZXQgKyBjb2RlYy5rU3RydWN0SGVhZGVyU2l6ZSArIDI0LCBvcmlnaW4kLk9yaWdpbiwgZmFsc2UpOwogICAgaWYgKGVyciAhPT0gdmFsaWRhdG9yLnZhbGlkYXRpb25FcnJvci5OT05FKQogICAgICAgIHJldHVybiBlcnI7CgoKCiAgICAvLyB2YWxpZGF0ZSBNZWRpYVJvdXRlUHJvdmlkZXJfQ3JlYXRlUm91dGVfUGFyYW1zLnRpbWVvdXQKICAgIGVyciA9IG1lc3NhZ2VWYWxpZGF0b3IudmFsaWRhdGVTdHJ1Y3RQb2ludGVyKG9mZnNldCArIGNvZGVjLmtTdHJ1Y3RIZWFkZXJTaXplICsgNDAsIHRpbWUkLlRpbWVEZWx0YSwgZmFsc2UpOwogICAgaWYgKGVyciAhPT0gdmFsaWRhdG9yLnZhbGlkYXRpb25FcnJvci5OT05FKQogICAgICAgIHJldHVybiBlcnI7CgoKICAgIHJldHVybiB2YWxpZGF0b3IudmFsaWRhdGlvbkVycm9yLk5PTkU7CiAgfTsKCiAgTWVkaWFSb3V0ZVByb3ZpZGVyX0NyZWF0ZVJvdXRlX1BhcmFtcy5lbmNvZGVkU2l6ZSA9IGNvZGVjLmtTdHJ1Y3RIZWFkZXJTaXplICsgNDg7CgogIE1lZGlhUm91dGVQcm92aWRlcl9DcmVhdGVSb3V0ZV9QYXJhbXMuZGVjb2RlID0gZnVuY3Rpb24oZGVjb2RlcikgewogICAgdmFyIHBhY2tlZDsKICAgIHZhciB2YWwgPSBuZXcgTWVkaWFSb3V0ZVByb3ZpZGVyX0NyZWF0ZVJvdXRlX1BhcmFtcygpOwogICAgdmFyIG51bWJlck9mQnl0ZXMgPSBkZWNvZGVyLnJlYWRVaW50MzIoKTsKICAgIHZhciB2ZXJzaW9uID0gZGVjb2Rlci5yZWFkVWludDMyKCk7CiAgICB2YWwubWVkaWFTb3VyY2UgPSBkZWNvZGVyLmRlY29kZVN0cnVjdChjb2RlYy5TdHJpbmcpOwogICAgdmFsLnNpbmtJZCA9IGRlY29kZXIuZGVjb2RlU3RydWN0KGNvZGVjLlN0cmluZyk7CiAgICB2YWwub3JpZ2luYWxQcmVzZW50YXRpb25JZCA9IGRlY29kZXIuZGVjb2RlU3RydWN0KGNvZGVjLlN0cmluZyk7CiAgICB2YWwub3JpZ2luID0gZGVjb2Rlci5kZWNvZGVTdHJ1Y3RQb2ludGVyKG9yaWdpbiQuT3JpZ2luKTsKICAgIHZhbC50YWJJZCA9IGRlY29kZXIuZGVjb2RlU3RydWN0KGNvZGVjLkludDMyKTsKICAgIHBhY2tlZCA9IGRlY29kZXIucmVhZFVpbnQ4KCk7CiAgICB2YWwuaW5jb2duaXRvID0gKHBhY2tlZCA+PiAwKSAmIDEgPyB0cnVlIDogZmFsc2U7CiAgICBkZWNvZGVyLnNraXAoMSk7CiAgICBkZWNvZGVyLnNraXAoMSk7CiAgICBkZWNvZGVyLnNraXAoMSk7CiAgICB2YWwudGltZW91dCA9IGRlY29kZXIuZGVjb2RlU3RydWN0UG9pbnRlcih0aW1lJC5UaW1lRGVsdGEpOwogICAgcmV0dXJuIHZhbDsKICB9OwoKICBNZWRpYVJvdXRlUHJvdmlkZXJfQ3JlYXRlUm91dGVfUGFyYW1zLmVuY29kZSA9IGZ1bmN0aW9uKGVuY29kZXIsIHZhbCkgewogICAgdmFyIHBhY2tlZDsKICAgIGVuY29kZXIud3JpdGVVaW50MzIoTWVkaWFSb3V0ZVByb3ZpZGVyX0NyZWF0ZVJvdXRlX1BhcmFtcy5lbmNvZGVkU2l6ZSk7CiAgICBlbmNvZGVyLndyaXRlVWludDMyKDApOwogICAgZW5jb2Rlci5lbmNvZGVTdHJ1Y3QoY29kZWMuU3RyaW5nLCB2YWwubWVkaWFTb3VyY2UpOwogICAgZW5jb2Rlci5lbmNvZGVTdHJ1Y3QoY29kZWMuU3RyaW5nLCB2YWwuc2lua0lkKTsKICAgIGVuY29kZXIuZW5jb2RlU3RydWN0KGNvZGVjLlN0cmluZywgdmFsLm9yaWdpbmFsUHJlc2VudGF0aW9uSWQpOwogICAgZW5jb2Rlci5lbmNvZGVTdHJ1Y3RQb2ludGVyKG9yaWdpbiQuT3JpZ2luLCB2YWwub3JpZ2luKTsKICAgIGVuY29kZXIuZW5jb2RlU3RydWN0KGNvZGVjLkludDMyLCB2YWwudGFiSWQpOwogICAgcGFja2VkID0gMDsKICAgIHBhY2tlZCB8PSAodmFsLmluY29nbml0byAmIDEpIDw8IDAKICAgIGVuY29kZXIud3JpdGVVaW50OChwYWNrZWQpOwogICAgZW5jb2Rlci5za2lwKDEpOwogICAgZW5jb2Rlci5za2lwKDEpOwogICAgZW5jb2Rlci5za2lwKDEpOwogICAgZW5jb2Rlci5lbmNvZGVTdHJ1Y3RQb2ludGVyKHRpbWUkLlRpbWVEZWx0YSwgdmFsLnRpbWVvdXQpOwogIH07CiAgZnVuY3Rpb24gTWVkaWFSb3V0ZVByb3ZpZGVyX0NyZWF0ZVJvdXRlX1Jlc3BvbnNlUGFyYW1zKHZhbHVlcykgewogICAgdGhpcy5pbml0RGVmYXVsdHNfKCk7CiAgICB0aGlzLmluaXRGaWVsZHNfKHZhbHVlcyk7CiAgfQoKCiAgTWVkaWFSb3V0ZVByb3ZpZGVyX0NyZWF0ZVJvdXRlX1Jlc3BvbnNlUGFyYW1zLnByb3RvdHlwZS5pbml0RGVmYXVsdHNfID0gZnVuY3Rpb24oKSB7CiAgICB0aGlzLnJvdXRlID0gbnVsbDsKICAgIHRoaXMuZXJyb3JUZXh0ID0gbnVsbDsKICAgIHRoaXMucmVzdWx0Q29kZSA9IDA7CiAgfTsKICBNZWRpYVJvdXRlUHJvdmlkZXJfQ3JlYXRlUm91dGVfUmVzcG9uc2VQYXJhbXMucHJvdG90eXBlLmluaXRGaWVsZHNfID0gZnVuY3Rpb24oZmllbGRzKSB7CiAgICBmb3IodmFyIGZpZWxkIGluIGZpZWxkcykgewogICAgICAgIGlmICh0aGlzLmhhc093blByb3BlcnR5KGZpZWxkKSkKICAgICAgICAgIHRoaXNbZmllbGRdID0gZmllbGRzW2ZpZWxkXTsKICAgIH0KICB9OwoKICBNZWRpYVJvdXRlUHJvdmlkZXJfQ3JlYXRlUm91dGVfUmVzcG9uc2VQYXJhbXMudmFsaWRhdGUgPSBmdW5jdGlvbihtZXNzYWdlVmFsaWRhdG9yLCBvZmZzZXQpIHsKICAgIHZhciBlcnI7CiAgICBlcnIgPSBtZXNzYWdlVmFsaWRhdG9yLnZhbGlkYXRlU3RydWN0SGVhZGVyKG9mZnNldCwgY29kZWMua1N0cnVjdEhlYWRlclNpemUpOwogICAgaWYgKGVyciAhPT0gdmFsaWRhdG9yLnZhbGlkYXRpb25FcnJvci5OT05FKQogICAgICAgIHJldHVybiBlcnI7CgogICAgdmFyIGtWZXJzaW9uU2l6ZXMgPSBbCiAgICAgIHt2ZXJzaW9uOiAwLCBudW1CeXRlczogMzJ9CiAgICBdOwogICAgZXJyID0gbWVzc2FnZVZhbGlkYXRvci52YWxpZGF0ZVN0cnVjdFZlcnNpb24ob2Zmc2V0LCBrVmVyc2lvblNpemVzKTsKICAgIGlmIChlcnIgIT09IHZhbGlkYXRvci52YWxpZGF0aW9uRXJyb3IuTk9ORSkKICAgICAgICByZXR1cm4gZXJyOwoKCiAgICAvLyB2YWxpZGF0ZSBNZWRpYVJvdXRlUHJvdmlkZXJfQ3JlYXRlUm91dGVfUmVzcG9uc2VQYXJhbXMucm91dGUKICAgIGVyciA9IG1lc3NhZ2VWYWxpZGF0b3IudmFsaWRhdGVTdHJ1Y3RQb2ludGVyKG9mZnNldCArIGNvZGVjLmtTdHJ1Y3RIZWFkZXJTaXplICsgMCwgTWVkaWFSb3V0ZSwgdHJ1ZSk7CiAgICBpZiAoZXJyICE9PSB2YWxpZGF0b3IudmFsaWRhdGlvbkVycm9yLk5PTkUpCiAgICAgICAgcmV0dXJuIGVycjsKCgogICAgLy8gdmFsaWRhdGUgTWVkaWFSb3V0ZVByb3ZpZGVyX0NyZWF0ZVJvdXRlX1Jlc3BvbnNlUGFyYW1zLmVycm9yVGV4dAogICAgZXJyID0gbWVzc2FnZVZhbGlkYXRvci52YWxpZGF0ZVN0cmluZ1BvaW50ZXIob2Zmc2V0ICsgY29kZWMua1N0cnVjdEhlYWRlclNpemUgKyA4LCB0cnVlKQogICAgaWYgKGVyciAhPT0gdmFsaWRhdG9yLnZhbGlkYXRpb25FcnJvci5OT05FKQogICAgICAgIHJldHVybiBlcnI7CgoKICAgIC8vIHZhbGlkYXRlIE1lZGlhUm91dGVQcm92aWRlcl9DcmVhdGVSb3V0ZV9SZXNwb25zZVBhcmFtcy5yZXN1bHRDb2RlCiAgICBlcnIgPSBtZXNzYWdlVmFsaWRhdG9yLnZhbGlkYXRlRW51bShvZmZzZXQgKyBjb2RlYy5rU3RydWN0SGVhZGVyU2l6ZSArIDE2LCBSb3V0ZVJlcXVlc3RSZXN1bHRDb2RlKTsKICAgIGlmIChlcnIgIT09IHZhbGlkYXRvci52YWxpZGF0aW9uRXJyb3IuTk9ORSkKICAgICAgICByZXR1cm4gZXJyOwoKICAgIHJldHVybiB2YWxpZGF0b3IudmFsaWRhdGlvbkVycm9yLk5PTkU7CiAgfTsKCiAgTWVkaWFSb3V0ZVByb3ZpZGVyX0NyZWF0ZVJvdXRlX1Jlc3BvbnNlUGFyYW1zLmVuY29kZWRTaXplID0gY29kZWMua1N0cnVjdEhlYWRlclNpemUgKyAyNDsKCiAgTWVkaWFSb3V0ZVByb3ZpZGVyX0NyZWF0ZVJvdXRlX1Jlc3BvbnNlUGFyYW1zLmRlY29kZSA9IGZ1bmN0aW9uKGRlY29kZXIpIHsKICAgIHZhciBwYWNrZWQ7CiAgICB2YXIgdmFsID0gbmV3IE1lZGlhUm91dGVQcm92aWRlcl9DcmVhdGVSb3V0ZV9SZXNwb25zZVBhcmFtcygpOwogICAgdmFyIG51bWJlck9mQnl0ZXMgPSBkZWNvZGVyLnJlYWRVaW50MzIoKTsKICAgIHZhciB2ZXJzaW9uID0gZGVjb2Rlci5yZWFkVWludDMyKCk7CiAgICB2YWwucm91dGUgPSBkZWNvZGVyLmRlY29kZVN0cnVjdFBvaW50ZXIoTWVkaWFSb3V0ZSk7CiAgICB2YWwuZXJyb3JUZXh0ID0gZGVjb2Rlci5kZWNvZGVTdHJ1Y3QoY29kZWMuTnVsbGFibGVTdHJpbmcpOwogICAgdmFsLnJlc3VsdENvZGUgPSBkZWNvZGVyLmRlY29kZVN0cnVjdChjb2RlYy5JbnQzMik7CiAgICBkZWNvZGVyLnNraXAoMSk7CiAgICBkZWNvZGVyLnNraXAoMSk7CiAgICBkZWNvZGVyLnNraXAoMSk7CiAgICBkZWNvZGVyLnNraXAoMSk7CiAgICByZXR1cm4gdmFsOwogIH07CgogIE1lZGlhUm91dGVQcm92aWRlcl9DcmVhdGVSb3V0ZV9SZXNwb25zZVBhcmFtcy5lbmNvZGUgPSBmdW5jdGlvbihlbmNvZGVyLCB2YWwpIHsKICAgIHZhciBwYWNrZWQ7CiAgICBlbmNvZGVyLndyaXRlVWludDMyKE1lZGlhUm91dGVQcm92aWRlcl9DcmVhdGVSb3V0ZV9SZXNwb25zZVBhcmFtcy5lbmNvZGVkU2l6ZSk7CiAgICBlbmNvZGVyLndyaXRlVWludDMyKDApOwogICAgZW5jb2Rlci5lbmNvZGVTdHJ1Y3RQb2ludGVyKE1lZGlhUm91dGUsIHZhbC5yb3V0ZSk7CiAgICBlbmNvZGVyLmVuY29kZVN0cnVjdChjb2RlYy5OdWxsYWJsZVN0cmluZywgdmFsLmVycm9yVGV4dCk7CiAgICBlbmNvZGVyLmVuY29kZVN0cnVjdChjb2RlYy5JbnQzMiwgdmFsLnJlc3VsdENvZGUpOwogICAgZW5jb2Rlci5za2lwKDEpOwogICAgZW5jb2Rlci5za2lwKDEpOwogICAgZW5jb2Rlci5za2lwKDEpOwogICAgZW5jb2Rlci5za2lwKDEpOwogIH07CiAgZnVuY3Rpb24gTWVkaWFSb3V0ZVByb3ZpZGVyX0pvaW5Sb3V0ZV9QYXJhbXModmFsdWVzKSB7CiAgICB0aGlzLmluaXREZWZhdWx0c18oKTsKICAgIHRoaXMuaW5pdEZpZWxkc18odmFsdWVzKTsKICB9CgoKICBNZWRpYVJvdXRlUHJvdmlkZXJfSm9pblJvdXRlX1BhcmFtcy5wcm90b3R5cGUuaW5pdERlZmF1bHRzXyA9IGZ1bmN0aW9uKCkgewogICAgdGhpcy5tZWRpYVNvdXJjZSA9IG51bGw7CiAgICB0aGlzLnByZXNlbnRhdGlvbklkID0gbnVsbDsKICAgIHRoaXMub3JpZ2luID0gbnVsbDsKICAgIHRoaXMudGFiSWQgPSAwOwogICAgdGhpcy5pbmNvZ25pdG8gPSBmYWxzZTsKICAgIHRoaXMudGltZW91dCA9IG51bGw7CiAgfTsKICBNZWRpYVJvdXRlUHJvdmlkZXJfSm9pblJvdXRlX1BhcmFtcy5wcm90b3R5cGUuaW5pdEZpZWxkc18gPSBmdW5jdGlvbihmaWVsZHMpIHsKICAgIGZvcih2YXIgZmllbGQgaW4gZmllbGRzKSB7CiAgICAgICAgaWYgKHRoaXMuaGFzT3duUHJvcGVydHkoZmllbGQpKQogICAgICAgICAgdGhpc1tmaWVsZF0gPSBmaWVsZHNbZmllbGRdOwogICAgfQogIH07CgogIE1lZGlhUm91dGVQcm92aWRlcl9Kb2luUm91dGVfUGFyYW1zLnZhbGlkYXRlID0gZnVuY3Rpb24obWVzc2FnZVZhbGlkYXRvciwgb2Zmc2V0KSB7CiAgICB2YXIgZXJyOwogICAgZXJyID0gbWVzc2FnZVZhbGlkYXRvci52YWxpZGF0ZVN0cnVjdEhlYWRlcihvZmZzZXQsIGNvZGVjLmtTdHJ1Y3RIZWFkZXJTaXplKTsKICAgIGlmIChlcnIgIT09IHZhbGlkYXRvci52YWxpZGF0aW9uRXJyb3IuTk9ORSkKICAgICAgICByZXR1cm4gZXJyOwoKICAgIHZhciBrVmVyc2lvblNpemVzID0gWwogICAgICB7dmVyc2lvbjogMCwgbnVtQnl0ZXM6IDQ4fQogICAgXTsKICAgIGVyciA9IG1lc3NhZ2VWYWxpZGF0b3IudmFsaWRhdGVTdHJ1Y3RWZXJzaW9uKG9mZnNldCwga1ZlcnNpb25TaXplcyk7CiAgICBpZiAoZXJyICE9PSB2YWxpZGF0b3IudmFsaWRhdGlvbkVycm9yLk5PTkUpCiAgICAgICAgcmV0dXJuIGVycjsKCgogICAgLy8gdmFsaWRhdGUgTWVkaWFSb3V0ZVByb3ZpZGVyX0pvaW5Sb3V0ZV9QYXJhbXMubWVkaWFTb3VyY2UKICAgIGVyciA9IG1lc3NhZ2VWYWxpZGF0b3IudmFsaWRhdGVTdHJpbmdQb2ludGVyKG9mZnNldCArIGNvZGVjLmtTdHJ1Y3RIZWFkZXJTaXplICsgMCwgZmFsc2UpCiAgICBpZiAoZXJyICE9PSB2YWxpZGF0b3IudmFsaWRhdGlvbkVycm9yLk5PTkUpCiAgICAgICAgcmV0dXJuIGVycjsKCgogICAgLy8gdmFsaWRhdGUgTWVkaWFSb3V0ZVByb3ZpZGVyX0pvaW5Sb3V0ZV9QYXJhbXMucHJlc2VudGF0aW9uSWQKICAgIGVyciA9IG1lc3NhZ2VWYWxpZGF0b3IudmFsaWRhdGVTdHJpbmdQb2ludGVyKG9mZnNldCArIGNvZGVjLmtTdHJ1Y3RIZWFkZXJTaXplICsgOCwgZmFsc2UpCiAgICBpZiAoZXJyICE9PSB2YWxpZGF0b3IudmFsaWRhdGlvbkVycm9yLk5PTkUpCiAgICAgICAgcmV0dXJuIGVycjsKCgogICAgLy8gdmFsaWRhdGUgTWVkaWFSb3V0ZVByb3ZpZGVyX0pvaW5Sb3V0ZV9QYXJhbXMub3JpZ2luCiAgICBlcnIgPSBtZXNzYWdlVmFsaWRhdG9yLnZhbGlkYXRlU3RydWN0UG9pbnRlcihvZmZzZXQgKyBjb2RlYy5rU3RydWN0SGVhZGVyU2l6ZSArIDE2LCBvcmlnaW4kLk9yaWdpbiwgZmFsc2UpOwogICAgaWYgKGVyciAhPT0gdmFsaWRhdG9yLnZhbGlkYXRpb25FcnJvci5OT05FKQogICAgICAgIHJldHVybiBlcnI7CgoKCiAgICAvLyB2YWxpZGF0ZSBNZWRpYVJvdXRlUHJvdmlkZXJfSm9pblJvdXRlX1BhcmFtcy50aW1lb3V0CiAgICBlcnIgPSBtZXNzYWdlVmFsaWRhdG9yLnZhbGlkYXRlU3RydWN0UG9pbnRlcihvZmZzZXQgKyBjb2RlYy5rU3RydWN0SGVhZGVyU2l6ZSArIDMyLCB0aW1lJC5UaW1lRGVsdGEsIGZhbHNlKTsKICAgIGlmIChlcnIgIT09IHZhbGlkYXRvci52YWxpZGF0aW9uRXJyb3IuTk9ORSkKICAgICAgICByZXR1cm4gZXJyOwoKCiAgICByZXR1cm4gdmFsaWRhdG9yLnZhbGlkYXRpb25FcnJvci5OT05FOwogIH07CgogIE1lZGlhUm91dGVQcm92aWRlcl9Kb2luUm91dGVfUGFyYW1zLmVuY29kZWRTaXplID0gY29kZWMua1N0cnVjdEhlYWRlclNpemUgKyA0MDsKCiAgTWVkaWFSb3V0ZVByb3ZpZGVyX0pvaW5Sb3V0ZV9QYXJhbXMuZGVjb2RlID0gZnVuY3Rpb24oZGVjb2RlcikgewogICAgdmFyIHBhY2tlZDsKICAgIHZhciB2YWwgPSBuZXcgTWVkaWFSb3V0ZVByb3ZpZGVyX0pvaW5Sb3V0ZV9QYXJhbXMoKTsKICAgIHZhciBudW1iZXJPZkJ5dGVzID0gZGVjb2Rlci5yZWFkVWludDMyKCk7CiAgICB2YXIgdmVyc2lvbiA9IGRlY29kZXIucmVhZFVpbnQzMigpOwogICAgdmFsLm1lZGlhU291cmNlID0gZGVjb2Rlci5kZWNvZGVTdHJ1Y3QoY29kZWMuU3RyaW5nKTsKICAgIHZhbC5wcmVzZW50YXRpb25JZCA9IGRlY29kZXIuZGVjb2RlU3RydWN0KGNvZGVjLlN0cmluZyk7CiAgICB2YWwub3JpZ2luID0gZGVjb2Rlci5kZWNvZGVTdHJ1Y3RQb2ludGVyKG9yaWdpbiQuT3JpZ2luKTsKICAgIHZhbC50YWJJZCA9IGRlY29kZXIuZGVjb2RlU3RydWN0KGNvZGVjLkludDMyKTsKICAgIHBhY2tlZCA9IGRlY29kZXIucmVhZFVpbnQ4KCk7CiAgICB2YWwuaW5jb2duaXRvID0gKHBhY2tlZCA+PiAwKSAmIDEgPyB0cnVlIDogZmFsc2U7CiAgICBkZWNvZGVyLnNraXAoMSk7CiAgICBkZWNvZGVyLnNraXAoMSk7CiAgICBkZWNvZGVyLnNraXAoMSk7CiAgICB2YWwudGltZW91dCA9IGRlY29kZXIuZGVjb2RlU3RydWN0UG9pbnRlcih0aW1lJC5UaW1lRGVsdGEpOwogICAgcmV0dXJuIHZhbDsKICB9OwoKICBNZWRpYVJvdXRlUHJvdmlkZXJfSm9pblJvdXRlX1BhcmFtcy5lbmNvZGUgPSBmdW5jdGlvbihlbmNvZGVyLCB2YWwpIHsKICAgIHZhciBwYWNrZWQ7CiAgICBlbmNvZGVyLndyaXRlVWludDMyKE1lZGlhUm91dGVQcm92aWRlcl9Kb2luUm91dGVfUGFyYW1zLmVuY29kZWRTaXplKTsKICAgIGVuY29kZXIud3JpdGVVaW50MzIoMCk7CiAgICBlbmNvZGVyLmVuY29kZVN0cnVjdChjb2RlYy5TdHJpbmcsIHZhbC5tZWRpYVNvdXJjZSk7CiAgICBlbmNvZGVyLmVuY29kZVN0cnVjdChjb2RlYy5TdHJpbmcsIHZhbC5wcmVzZW50YXRpb25JZCk7CiAgICBlbmNvZGVyLmVuY29kZVN0cnVjdFBvaW50ZXIob3JpZ2luJC5PcmlnaW4sIHZhbC5vcmlnaW4pOwogICAgZW5jb2Rlci5lbmNvZGVTdHJ1Y3QoY29kZWMuSW50MzIsIHZhbC50YWJJZCk7CiAgICBwYWNrZWQgPSAwOwogICAgcGFja2VkIHw9ICh2YWwuaW5jb2duaXRvICYgMSkgPDwgMAogICAgZW5jb2Rlci53cml0ZVVpbnQ4KHBhY2tlZCk7CiAgICBlbmNvZGVyLnNraXAoMSk7CiAgICBlbmNvZGVyLnNraXAoMSk7CiAgICBlbmNvZGVyLnNraXAoMSk7CiAgICBlbmNvZGVyLmVuY29kZVN0cnVjdFBvaW50ZXIodGltZSQuVGltZURlbHRhLCB2YWwudGltZW91dCk7CiAgfTsKICBmdW5jdGlvbiBNZWRpYVJvdXRlUHJvdmlkZXJfSm9pblJvdXRlX1Jlc3BvbnNlUGFyYW1zKHZhbHVlcykgewogICAgdGhpcy5pbml0RGVmYXVsdHNfKCk7CiAgICB0aGlzLmluaXRGaWVsZHNfKHZhbHVlcyk7CiAgfQoKCiAgTWVkaWFSb3V0ZVByb3ZpZGVyX0pvaW5Sb3V0ZV9SZXNwb25zZVBhcmFtcy5wcm90b3R5cGUuaW5pdERlZmF1bHRzXyA9IGZ1bmN0aW9uKCkgewogICAgdGhpcy5yb3V0ZSA9IG51bGw7CiAgICB0aGlzLmVycm9yVGV4dCA9IG51bGw7CiAgICB0aGlzLnJlc3VsdENvZGUgPSAwOwogIH07CiAgTWVkaWFSb3V0ZVByb3ZpZGVyX0pvaW5Sb3V0ZV9SZXNwb25zZVBhcmFtcy5wcm90b3R5cGUuaW5pdEZpZWxkc18gPSBmdW5jdGlvbihmaWVsZHMpIHsKICAgIGZvcih2YXIgZmllbGQgaW4gZmllbGRzKSB7CiAgICAgICAgaWYgKHRoaXMuaGFzT3duUHJvcGVydHkoZmllbGQpKQogICAgICAgICAgdGhpc1tmaWVsZF0gPSBmaWVsZHNbZmllbGRdOwogICAgfQogIH07CgogIE1lZGlhUm91dGVQcm92aWRlcl9Kb2luUm91dGVfUmVzcG9uc2VQYXJhbXMudmFsaWRhdGUgPSBmdW5jdGlvbihtZXNzYWdlVmFsaWRhdG9yLCBvZmZzZXQpIHsKICAgIHZhciBlcnI7CiAgICBlcnIgPSBtZXNzYWdlVmFsaWRhdG9yLnZhbGlkYXRlU3RydWN0SGVhZGVyKG9mZnNldCwgY29kZWMua1N0cnVjdEhlYWRlclNpemUpOwogICAgaWYgKGVyciAhPT0gdmFsaWRhdG9yLnZhbGlkYXRpb25FcnJvci5OT05FKQogICAgICAgIHJldHVybiBlcnI7CgogICAgdmFyIGtWZXJzaW9uU2l6ZXMgPSBbCiAgICAgIHt2ZXJzaW9uOiAwLCBudW1CeXRlczogMzJ9CiAgICBdOwogICAgZXJyID0gbWVzc2FnZVZhbGlkYXRvci52YWxpZGF0ZVN0cnVjdFZlcnNpb24ob2Zmc2V0LCBrVmVyc2lvblNpemVzKTsKICAgIGlmIChlcnIgIT09IHZhbGlkYXRvci52YWxpZGF0aW9uRXJyb3IuTk9ORSkKICAgICAgICByZXR1cm4gZXJyOwoKCiAgICAvLyB2YWxpZGF0ZSBNZWRpYVJvdXRlUHJvdmlkZXJfSm9pblJvdXRlX1Jlc3BvbnNlUGFyYW1zLnJvdXRlCiAgICBlcnIgPSBtZXNzYWdlVmFsaWRhdG9yLnZhbGlkYXRlU3RydWN0UG9pbnRlcihvZmZzZXQgKyBjb2RlYy5rU3RydWN0SGVhZGVyU2l6ZSArIDAsIE1lZGlhUm91dGUsIHRydWUpOwogICAgaWYgKGVyciAhPT0gdmFsaWRhdG9yLnZhbGlkYXRpb25FcnJvci5OT05FKQogICAgICAgIHJldHVybiBlcnI7CgoKICAgIC8vIHZhbGlkYXRlIE1lZGlhUm91dGVQcm92aWRlcl9Kb2luUm91dGVfUmVzcG9uc2VQYXJhbXMuZXJyb3JUZXh0CiAgICBlcnIgPSBtZXNzYWdlVmFsaWRhdG9yLnZhbGlkYXRlU3RyaW5nUG9pbnRlcihvZmZzZXQgKyBjb2RlYy5rU3RydWN0SGVhZGVyU2l6ZSArIDgsIHRydWUpCiAgICBpZiAoZXJyICE9PSB2YWxpZGF0b3IudmFsaWRhdGlvbkVycm9yLk5PTkUpCiAgICAgICAgcmV0dXJuIGVycjsKCgogICAgLy8gdmFsaWRhdGUgTWVkaWFSb3V0ZVByb3ZpZGVyX0pvaW5Sb3V0ZV9SZXNwb25zZVBhcmFtcy5yZXN1bHRDb2RlCiAgICBlcnIgPSBtZXNzYWdlVmFsaWRhdG9yLnZhbGlkYXRlRW51bShvZmZzZXQgKyBjb2RlYy5rU3RydWN0SGVhZGVyU2l6ZSArIDE2LCBSb3V0ZVJlcXVlc3RSZXN1bHRDb2RlKTsKICAgIGlmIChlcnIgIT09IHZhbGlkYXRvci52YWxpZGF0aW9uRXJyb3IuTk9ORSkKICAgICAgICByZXR1cm4gZXJyOwoKICAgIHJldHVybiB2YWxpZGF0b3IudmFsaWRhdGlvbkVycm9yLk5PTkU7CiAgfTsKCiAgTWVkaWFSb3V0ZVByb3ZpZGVyX0pvaW5Sb3V0ZV9SZXNwb25zZVBhcmFtcy5lbmNvZGVkU2l6ZSA9IGNvZGVjLmtTdHJ1Y3RIZWFkZXJTaXplICsgMjQ7CgogIE1lZGlhUm91dGVQcm92aWRlcl9Kb2luUm91dGVfUmVzcG9uc2VQYXJhbXMuZGVjb2RlID0gZnVuY3Rpb24oZGVjb2RlcikgewogICAgdmFyIHBhY2tlZDsKICAgIHZhciB2YWwgPSBuZXcgTWVkaWFSb3V0ZVByb3ZpZGVyX0pvaW5Sb3V0ZV9SZXNwb25zZVBhcmFtcygpOwogICAgdmFyIG51bWJlck9mQnl0ZXMgPSBkZWNvZGVyLnJlYWRVaW50MzIoKTsKICAgIHZhciB2ZXJzaW9uID0gZGVjb2Rlci5yZWFkVWludDMyKCk7CiAgICB2YWwucm91dGUgPSBkZWNvZGVyLmRlY29kZVN0cnVjdFBvaW50ZXIoTWVkaWFSb3V0ZSk7CiAgICB2YWwuZXJyb3JUZXh0ID0gZGVjb2Rlci5kZWNvZGVTdHJ1Y3QoY29kZWMuTnVsbGFibGVTdHJpbmcpOwogICAgdmFsLnJlc3VsdENvZGUgPSBkZWNvZGVyLmRlY29kZVN0cnVjdChjb2RlYy5JbnQzMik7CiAgICBkZWNvZGVyLnNraXAoMSk7CiAgICBkZWNvZGVyLnNraXAoMSk7CiAgICBkZWNvZGVyLnNraXAoMSk7CiAgICBkZWNvZGVyLnNraXAoMSk7CiAgICByZXR1cm4gdmFsOwogIH07CgogIE1lZGlhUm91dGVQcm92aWRlcl9Kb2luUm91dGVfUmVzcG9uc2VQYXJhbXMuZW5jb2RlID0gZnVuY3Rpb24oZW5jb2RlciwgdmFsKSB7CiAgICB2YXIgcGFja2VkOwogICAgZW5jb2Rlci53cml0ZVVpbnQzMihNZWRpYVJvdXRlUHJvdmlkZXJfSm9pblJvdXRlX1Jlc3BvbnNlUGFyYW1zLmVuY29kZWRTaXplKTsKICAgIGVuY29kZXIud3JpdGVVaW50MzIoMCk7CiAgICBlbmNvZGVyLmVuY29kZVN0cnVjdFBvaW50ZXIoTWVkaWFSb3V0ZSwgdmFsLnJvdXRlKTsKICAgIGVuY29kZXIuZW5jb2RlU3RydWN0KGNvZGVjLk51bGxhYmxlU3RyaW5nLCB2YWwuZXJyb3JUZXh0KTsKICAgIGVuY29kZXIuZW5jb2RlU3RydWN0KGNvZGVjLkludDMyLCB2YWwucmVzdWx0Q29kZSk7CiAgICBlbmNvZGVyLnNraXAoMSk7CiAgICBlbmNvZGVyLnNraXAoMSk7CiAgICBlbmNvZGVyLnNraXAoMSk7CiAgICBlbmNvZGVyLnNraXAoMSk7CiAgfTsKICBmdW5jdGlvbiBNZWRpYVJvdXRlUHJvdmlkZXJfQ29ubmVjdFJvdXRlQnlSb3V0ZUlkX1BhcmFtcyh2YWx1ZXMpIHsKICAgIHRoaXMuaW5pdERlZmF1bHRzXygpOwogICAgdGhpcy5pbml0RmllbGRzXyh2YWx1ZXMpOwogIH0KCgogIE1lZGlhUm91dGVQcm92aWRlcl9Db25uZWN0Um91dGVCeVJvdXRlSWRfUGFyYW1zLnByb3RvdHlwZS5pbml0RGVmYXVsdHNfID0gZnVuY3Rpb24oKSB7CiAgICB0aGlzLm1lZGlhU291cmNlID0gbnVsbDsKICAgIHRoaXMucm91dGVJZCA9IG51bGw7CiAgICB0aGlzLnByZXNlbnRhdGlvbklkID0gbnVsbDsKICAgIHRoaXMub3JpZ2luID0gbnVsbDsKICAgIHRoaXMudGFiSWQgPSAwOwogICAgdGhpcy5pbmNvZ25pdG8gPSBmYWxzZTsKICAgIHRoaXMudGltZW91dCA9IG51bGw7CiAgfTsKICBNZWRpYVJvdXRlUHJvdmlkZXJfQ29ubmVjdFJvdXRlQnlSb3V0ZUlkX1BhcmFtcy5wcm90b3R5cGUuaW5pdEZpZWxkc18gPSBmdW5jdGlvbihmaWVsZHMpIHsKICAgIGZvcih2YXIgZmllbGQgaW4gZmllbGRzKSB7CiAgICAgICAgaWYgKHRoaXMuaGFzT3duUHJvcGVydHkoZmllbGQpKQogICAgICAgICAgdGhpc1tmaWVsZF0gPSBmaWVsZHNbZmllbGRdOwogICAgfQogIH07CgogIE1lZGlhUm91dGVQcm92aWRlcl9Db25uZWN0Um91dGVCeVJvdXRlSWRfUGFyYW1zLnZhbGlkYXRlID0gZnVuY3Rpb24obWVzc2FnZVZhbGlkYXRvciwgb2Zmc2V0KSB7CiAgICB2YXIgZXJyOwogICAgZXJyID0gbWVzc2FnZVZhbGlkYXRvci52YWxpZGF0ZVN0cnVjdEhlYWRlcihvZmZzZXQsIGNvZGVjLmtTdHJ1Y3RIZWFkZXJTaXplKTsKICAgIGlmIChlcnIgIT09IHZhbGlkYXRvci52YWxpZGF0aW9uRXJyb3IuTk9ORSkKICAgICAgICByZXR1cm4gZXJyOwoKICAgIHZhciBrVmVyc2lvblNpemVzID0gWwogICAgICB7dmVyc2lvbjogMCwgbnVtQnl0ZXM6IDU2fQogICAgXTsKICAgIGVyciA9IG1lc3NhZ2VWYWxpZGF0b3IudmFsaWRhdGVTdHJ1Y3RWZXJzaW9uKG9mZnNldCwga1ZlcnNpb25TaXplcyk7CiAgICBpZiAoZXJyICE9PSB2YWxpZGF0b3IudmFsaWRhdGlvbkVycm9yLk5PTkUpCiAgICAgICAgcmV0dXJuIGVycjsKCgogICAgLy8gdmFsaWRhdGUgTWVkaWFSb3V0ZVByb3ZpZGVyX0Nvbm5lY3RSb3V0ZUJ5Um91dGVJZF9QYXJhbXMubWVkaWFTb3VyY2UKICAgIGVyciA9IG1lc3NhZ2VWYWxpZGF0b3IudmFsaWRhdGVTdHJpbmdQb2ludGVyKG9mZnNldCArIGNvZGVjLmtTdHJ1Y3RIZWFkZXJTaXplICsgMCwgZmFsc2UpCiAgICBpZiAoZXJyICE9PSB2YWxpZGF0b3IudmFsaWRhdGlvbkVycm9yLk5PTkUpCiAgICAgICAgcmV0dXJuIGVycjsKCgogICAgLy8gdmFsaWRhdGUgTWVkaWFSb3V0ZVByb3ZpZGVyX0Nvbm5lY3RSb3V0ZUJ5Um91dGVJZF9QYXJhbXMucm91dGVJZAogICAgZXJyID0gbWVzc2FnZVZhbGlkYXRvci52YWxpZGF0ZVN0cmluZ1BvaW50ZXIob2Zmc2V0ICsgY29kZWMua1N0cnVjdEhlYWRlclNpemUgKyA4LCBmYWxzZSkKICAgIGlmIChlcnIgIT09IHZhbGlkYXRvci52YWxpZGF0aW9uRXJyb3IuTk9ORSkKICAgICAgICByZXR1cm4gZXJyOwoKCiAgICAvLyB2YWxpZGF0ZSBNZWRpYVJvdXRlUHJvdmlkZXJfQ29ubmVjdFJvdXRlQnlSb3V0ZUlkX1BhcmFtcy5wcmVzZW50YXRpb25JZAogICAgZXJyID0gbWVzc2FnZVZhbGlkYXRvci52YWxpZGF0ZVN0cmluZ1BvaW50ZXIob2Zmc2V0ICsgY29kZWMua1N0cnVjdEhlYWRlclNpemUgKyAxNiwgZmFsc2UpCiAgICBpZiAoZXJyICE9PSB2YWxpZGF0b3IudmFsaWRhdGlvbkVycm9yLk5PTkUpCiAgICAgICAgcmV0dXJuIGVycjsKCgogICAgLy8gdmFsaWRhdGUgTWVkaWFSb3V0ZVByb3ZpZGVyX0Nvbm5lY3RSb3V0ZUJ5Um91dGVJZF9QYXJhbXMub3JpZ2luCiAgICBlcnIgPSBtZXNzYWdlVmFsaWRhdG9yLnZhbGlkYXRlU3RydWN0UG9pbnRlcihvZmZzZXQgKyBjb2RlYy5rU3RydWN0SGVhZGVyU2l6ZSArIDI0LCBvcmlnaW4kLk9yaWdpbiwgZmFsc2UpOwogICAgaWYgKGVyciAhPT0gdmFsaWRhdG9yLnZhbGlkYXRpb25FcnJvci5OT05FKQogICAgICAgIHJldHVybiBlcnI7CgoKCiAgICAvLyB2YWxpZGF0ZSBNZWRpYVJvdXRlUHJvdmlkZXJfQ29ubmVjdFJvdXRlQnlSb3V0ZUlkX1BhcmFtcy50aW1lb3V0CiAgICBlcnIgPSBtZXNzYWdlVmFsaWRhdG9yLnZhbGlkYXRlU3RydWN0UG9pbnRlcihvZmZzZXQgKyBjb2RlYy5rU3RydWN0SGVhZGVyU2l6ZSArIDQwLCB0aW1lJC5UaW1lRGVsdGEsIGZhbHNlKTsKICAgIGlmIChlcnIgIT09IHZhbGlkYXRvci52YWxpZGF0aW9uRXJyb3IuTk9ORSkKICAgICAgICByZXR1cm4gZXJyOwoKCiAgICByZXR1cm4gdmFsaWRhdG9yLnZhbGlkYXRpb25FcnJvci5OT05FOwogIH07CgogIE1lZGlhUm91dGVQcm92aWRlcl9Db25uZWN0Um91dGVCeVJvdXRlSWRfUGFyYW1zLmVuY29kZWRTaXplID0gY29kZWMua1N0cnVjdEhlYWRlclNpemUgKyA0ODsKCiAgTWVkaWFSb3V0ZVByb3ZpZGVyX0Nvbm5lY3RSb3V0ZUJ5Um91dGVJZF9QYXJhbXMuZGVjb2RlID0gZnVuY3Rpb24oZGVjb2RlcikgewogICAgdmFyIHBhY2tlZDsKICAgIHZhciB2YWwgPSBuZXcgTWVkaWFSb3V0ZVByb3ZpZGVyX0Nvbm5lY3RSb3V0ZUJ5Um91dGVJZF9QYXJhbXMoKTsKICAgIHZhciBudW1iZXJPZkJ5dGVzID0gZGVjb2Rlci5yZWFkVWludDMyKCk7CiAgICB2YXIgdmVyc2lvbiA9IGRlY29kZXIucmVhZFVpbnQzMigpOwogICAgdmFsLm1lZGlhU291cmNlID0gZGVjb2Rlci5kZWNvZGVTdHJ1Y3QoY29kZWMuU3RyaW5nKTsKICAgIHZhbC5yb3V0ZUlkID0gZGVjb2Rlci5kZWNvZGVTdHJ1Y3QoY29kZWMuU3RyaW5nKTsKICAgIHZhbC5wcmVzZW50YXRpb25JZCA9IGRlY29kZXIuZGVjb2RlU3RydWN0KGNvZGVjLlN0cmluZyk7CiAgICB2YWwub3JpZ2luID0gZGVjb2Rlci5kZWNvZGVTdHJ1Y3RQb2ludGVyKG9yaWdpbiQuT3JpZ2luKTsKICAgIHZhbC50YWJJZCA9IGRlY29kZXIuZGVjb2RlU3RydWN0KGNvZGVjLkludDMyKTsKICAgIHBhY2tlZCA9IGRlY29kZXIucmVhZFVpbnQ4KCk7CiAgICB2YWwuaW5jb2duaXRvID0gKHBhY2tlZCA+PiAwKSAmIDEgPyB0cnVlIDogZmFsc2U7CiAgICBkZWNvZGVyLnNraXAoMSk7CiAgICBkZWNvZGVyLnNraXAoMSk7CiAgICBkZWNvZGVyLnNraXAoMSk7CiAgICB2YWwudGltZW91dCA9IGRlY29kZXIuZGVjb2RlU3RydWN0UG9pbnRlcih0aW1lJC5UaW1lRGVsdGEpOwogICAgcmV0dXJuIHZhbDsKICB9OwoKICBNZWRpYVJvdXRlUHJvdmlkZXJfQ29ubmVjdFJvdXRlQnlSb3V0ZUlkX1BhcmFtcy5lbmNvZGUgPSBmdW5jdGlvbihlbmNvZGVyLCB2YWwpIHsKICAgIHZhciBwYWNrZWQ7CiAgICBlbmNvZGVyLndyaXRlVWludDMyKE1lZGlhUm91dGVQcm92aWRlcl9Db25uZWN0Um91dGVCeVJvdXRlSWRfUGFyYW1zLmVuY29kZWRTaXplKTsKICAgIGVuY29kZXIud3JpdGVVaW50MzIoMCk7CiAgICBlbmNvZGVyLmVuY29kZVN0cnVjdChjb2RlYy5TdHJpbmcsIHZhbC5tZWRpYVNvdXJjZSk7CiAgICBlbmNvZGVyLmVuY29kZVN0cnVjdChjb2RlYy5TdHJpbmcsIHZhbC5yb3V0ZUlkKTsKICAgIGVuY29kZXIuZW5jb2RlU3RydWN0KGNvZGVjLlN0cmluZywgdmFsLnByZXNlbnRhdGlvbklkKTsKICAgIGVuY29kZXIuZW5jb2RlU3RydWN0UG9pbnRlcihvcmlnaW4kLk9yaWdpbiwgdmFsLm9yaWdpbik7CiAgICBlbmNvZGVyLmVuY29kZVN0cnVjdChjb2RlYy5JbnQzMiwgdmFsLnRhYklkKTsKICAgIHBhY2tlZCA9IDA7CiAgICBwYWNrZWQgfD0gKHZhbC5pbmNvZ25pdG8gJiAxKSA8PCAwCiAgICBlbmNvZGVyLndyaXRlVWludDgocGFja2VkKTsKICAgIGVuY29kZXIuc2tpcCgxKTsKICAgIGVuY29kZXIuc2tpcCgxKTsKICAgIGVuY29kZXIuc2tpcCgxKTsKICAgIGVuY29kZXIuZW5jb2RlU3RydWN0UG9pbnRlcih0aW1lJC5UaW1lRGVsdGEsIHZhbC50aW1lb3V0KTsKICB9OwogIGZ1bmN0aW9uIE1lZGlhUm91dGVQcm92aWRlcl9Db25uZWN0Um91dGVCeVJvdXRlSWRfUmVzcG9uc2VQYXJhbXModmFsdWVzKSB7CiAgICB0aGlzLmluaXREZWZhdWx0c18oKTsKICAgIHRoaXMuaW5pdEZpZWxkc18odmFsdWVzKTsKICB9CgoKICBNZWRpYVJvdXRlUHJvdmlkZXJfQ29ubmVjdFJvdXRlQnlSb3V0ZUlkX1Jlc3BvbnNlUGFyYW1zLnByb3RvdHlwZS5pbml0RGVmYXVsdHNfID0gZnVuY3Rpb24oKSB7CiAgICB0aGlzLnJvdXRlID0gbnVsbDsKICAgIHRoaXMuZXJyb3JUZXh0ID0gbnVsbDsKICAgIHRoaXMucmVzdWx0Q29kZSA9IDA7CiAgfTsKICBNZWRpYVJvdXRlUHJvdmlkZXJfQ29ubmVjdFJvdXRlQnlSb3V0ZUlkX1Jlc3BvbnNlUGFyYW1zLnByb3RvdHlwZS5pbml0RmllbGRzXyA9IGZ1bmN0aW9uKGZpZWxkcykgewogICAgZm9yKHZhciBmaWVsZCBpbiBmaWVsZHMpIHsKICAgICAgICBpZiAodGhpcy5oYXNPd25Qcm9wZXJ0eShmaWVsZCkpCiAgICAgICAgICB0aGlzW2ZpZWxkXSA9IGZpZWxkc1tmaWVsZF07CiAgICB9CiAgfTsKCiAgTWVkaWFSb3V0ZVByb3ZpZGVyX0Nvbm5lY3RSb3V0ZUJ5Um91dGVJZF9SZXNwb25zZVBhcmFtcy52YWxpZGF0ZSA9IGZ1bmN0aW9uKG1lc3NhZ2VWYWxpZGF0b3IsIG9mZnNldCkgewogICAgdmFyIGVycjsKICAgIGVyciA9IG1lc3NhZ2VWYWxpZGF0b3IudmFsaWRhdGVTdHJ1Y3RIZWFkZXIob2Zmc2V0LCBjb2RlYy5rU3RydWN0SGVhZGVyU2l6ZSk7CiAgICBpZiAoZXJyICE9PSB2YWxpZGF0b3IudmFsaWRhdGlvbkVycm9yLk5PTkUpCiAgICAgICAgcmV0dXJuIGVycjsKCiAgICB2YXIga1ZlcnNpb25TaXplcyA9IFsKICAgICAge3ZlcnNpb246IDAsIG51bUJ5dGVzOiAzMn0KICAgIF07CiAgICBlcnIgPSBtZXNzYWdlVmFsaWRhdG9yLnZhbGlkYXRlU3RydWN0VmVyc2lvbihvZmZzZXQsIGtWZXJzaW9uU2l6ZXMpOwogICAgaWYgKGVyciAhPT0gdmFsaWRhdG9yLnZhbGlkYXRpb25FcnJvci5OT05FKQogICAgICAgIHJldHVybiBlcnI7CgoKICAgIC8vIHZhbGlkYXRlIE1lZGlhUm91dGVQcm92aWRlcl9Db25uZWN0Um91dGVCeVJvdXRlSWRfUmVzcG9uc2VQYXJhbXMucm91dGUKICAgIGVyciA9IG1lc3NhZ2VWYWxpZGF0b3IudmFsaWRhdGVTdHJ1Y3RQb2ludGVyKG9mZnNldCArIGNvZGVjLmtTdHJ1Y3RIZWFkZXJTaXplICsgMCwgTWVkaWFSb3V0ZSwgdHJ1ZSk7CiAgICBpZiAoZXJyICE9PSB2YWxpZGF0b3IudmFsaWRhdGlvbkVycm9yLk5PTkUpCiAgICAgICAgcmV0dXJuIGVycjsKCgogICAgLy8gdmFsaWRhdGUgTWVkaWFSb3V0ZVByb3ZpZGVyX0Nvbm5lY3RSb3V0ZUJ5Um91dGVJZF9SZXNwb25zZVBhcmFtcy5lcnJvclRleHQKICAgIGVyciA9IG1lc3NhZ2VWYWxpZGF0b3IudmFsaWRhdGVTdHJpbmdQb2ludGVyKG9mZnNldCArIGNvZGVjLmtTdHJ1Y3RIZWFkZXJTaXplICsgOCwgdHJ1ZSkKICAgIGlmIChlcnIgIT09IHZhbGlkYXRvci52YWxpZGF0aW9uRXJyb3IuTk9ORSkKICAgICAgICByZXR1cm4gZXJyOwoKCiAgICAvLyB2YWxpZGF0ZSBNZWRpYVJvdXRlUHJvdmlkZXJfQ29ubmVjdFJvdXRlQnlSb3V0ZUlkX1Jlc3BvbnNlUGFyYW1zLnJlc3VsdENvZGUKICAgIGVyciA9IG1lc3NhZ2VWYWxpZGF0b3IudmFsaWRhdGVFbnVtKG9mZnNldCArIGNvZGVjLmtTdHJ1Y3RIZWFkZXJTaXplICsgMTYsIFJvdXRlUmVxdWVzdFJlc3VsdENvZGUpOwogICAgaWYgKGVyciAhPT0gdmFsaWRhdG9yLnZhbGlkYXRpb25FcnJvci5OT05FKQogICAgICAgIHJldHVybiBlcnI7CgogICAgcmV0dXJuIHZhbGlkYXRvci52YWxpZGF0aW9uRXJyb3IuTk9ORTsKICB9OwoKICBNZWRpYVJvdXRlUHJvdmlkZXJfQ29ubmVjdFJvdXRlQnlSb3V0ZUlkX1Jlc3BvbnNlUGFyYW1zLmVuY29kZWRTaXplID0gY29kZWMua1N0cnVjdEhlYWRlclNpemUgKyAyNDsKCiAgTWVkaWFSb3V0ZVByb3ZpZGVyX0Nvbm5lY3RSb3V0ZUJ5Um91dGVJZF9SZXNwb25zZVBhcmFtcy5kZWNvZGUgPSBmdW5jdGlvbihkZWNvZGVyKSB7CiAgICB2YXIgcGFja2VkOwogICAgdmFyIHZhbCA9IG5ldyBNZWRpYVJvdXRlUHJvdmlkZXJfQ29ubmVjdFJvdXRlQnlSb3V0ZUlkX1Jlc3BvbnNlUGFyYW1zKCk7CiAgICB2YXIgbnVtYmVyT2ZCeXRlcyA9IGRlY29kZXIucmVhZFVpbnQzMigpOwogICAgdmFyIHZlcnNpb24gPSBkZWNvZGVyLnJlYWRVaW50MzIoKTsKICAgIHZhbC5yb3V0ZSA9IGRlY29kZXIuZGVjb2RlU3RydWN0UG9pbnRlcihNZWRpYVJvdXRlKTsKICAgIHZhbC5lcnJvclRleHQgPSBkZWNvZGVyLmRlY29kZVN0cnVjdChjb2RlYy5OdWxsYWJsZVN0cmluZyk7CiAgICB2YWwucmVzdWx0Q29kZSA9IGRlY29kZXIuZGVjb2RlU3RydWN0KGNvZGVjLkludDMyKTsKICAgIGRlY29kZXIuc2tpcCgxKTsKICAgIGRlY29kZXIuc2tpcCgxKTsKICAgIGRlY29kZXIuc2tpcCgxKTsKICAgIGRlY29kZXIuc2tpcCgxKTsKICAgIHJldHVybiB2YWw7CiAgfTsKCiAgTWVkaWFSb3V0ZVByb3ZpZGVyX0Nvbm5lY3RSb3V0ZUJ5Um91dGVJZF9SZXNwb25zZVBhcmFtcy5lbmNvZGUgPSBmdW5jdGlvbihlbmNvZGVyLCB2YWwpIHsKICAgIHZhciBwYWNrZWQ7CiAgICBlbmNvZGVyLndyaXRlVWludDMyKE1lZGlhUm91dGVQcm92aWRlcl9Db25uZWN0Um91dGVCeVJvdXRlSWRfUmVzcG9uc2VQYXJhbXMuZW5jb2RlZFNpemUpOwogICAgZW5jb2Rlci53cml0ZVVpbnQzMigwKTsKICAgIGVuY29kZXIuZW5jb2RlU3RydWN0UG9pbnRlcihNZWRpYVJvdXRlLCB2YWwucm91dGUpOwogICAgZW5jb2Rlci5lbmNvZGVTdHJ1Y3QoY29kZWMuTnVsbGFibGVTdHJpbmcsIHZhbC5lcnJvclRleHQpOwogICAgZW5jb2Rlci5lbmNvZGVTdHJ1Y3QoY29kZWMuSW50MzIsIHZhbC5yZXN1bHRDb2RlKTsKICAgIGVuY29kZXIuc2tpcCgxKTsKICAgIGVuY29kZXIuc2tpcCgxKTsKICAgIGVuY29kZXIuc2tpcCgxKTsKICAgIGVuY29kZXIuc2tpcCgxKTsKICB9OwogIGZ1bmN0aW9uIE1lZGlhUm91dGVQcm92aWRlcl9UZXJtaW5hdGVSb3V0ZV9QYXJhbXModmFsdWVzKSB7CiAgICB0aGlzLmluaXREZWZhdWx0c18oKTsKICAgIHRoaXMuaW5pdEZpZWxkc18odmFsdWVzKTsKICB9CgoKICBNZWRpYVJvdXRlUHJvdmlkZXJfVGVybWluYXRlUm91dGVfUGFyYW1zLnByb3RvdHlwZS5pbml0RGVmYXVsdHNfID0gZnVuY3Rpb24oKSB7CiAgICB0aGlzLnJvdXRlSWQgPSBudWxsOwogIH07CiAgTWVkaWFSb3V0ZVByb3ZpZGVyX1Rlcm1pbmF0ZVJvdXRlX1BhcmFtcy5wcm90b3R5cGUuaW5pdEZpZWxkc18gPSBmdW5jdGlvbihmaWVsZHMpIHsKICAgIGZvcih2YXIgZmllbGQgaW4gZmllbGRzKSB7CiAgICAgICAgaWYgKHRoaXMuaGFzT3duUHJvcGVydHkoZmllbGQpKQogICAgICAgICAgdGhpc1tmaWVsZF0gPSBmaWVsZHNbZmllbGRdOwogICAgfQogIH07CgogIE1lZGlhUm91dGVQcm92aWRlcl9UZXJtaW5hdGVSb3V0ZV9QYXJhbXMudmFsaWRhdGUgPSBmdW5jdGlvbihtZXNzYWdlVmFsaWRhdG9yLCBvZmZzZXQpIHsKICAgIHZhciBlcnI7CiAgICBlcnIgPSBtZXNzYWdlVmFsaWRhdG9yLnZhbGlkYXRlU3RydWN0SGVhZGVyKG9mZnNldCwgY29kZWMua1N0cnVjdEhlYWRlclNpemUpOwogICAgaWYgKGVyciAhPT0gdmFsaWRhdG9yLnZhbGlkYXRpb25FcnJvci5OT05FKQogICAgICAgIHJldHVybiBlcnI7CgogICAgdmFyIGtWZXJzaW9uU2l6ZXMgPSBbCiAgICAgIHt2ZXJzaW9uOiAwLCBudW1CeXRlczogMTZ9CiAgICBdOwogICAgZXJyID0gbWVzc2FnZVZhbGlkYXRvci52YWxpZGF0ZVN0cnVjdFZlcnNpb24ob2Zmc2V0LCBrVmVyc2lvblNpemVzKTsKICAgIGlmIChlcnIgIT09IHZhbGlkYXRvci52YWxpZGF0aW9uRXJyb3IuTk9ORSkKICAgICAgICByZXR1cm4gZXJyOwoKCiAgICAvLyB2YWxpZGF0ZSBNZWRpYVJvdXRlUHJvdmlkZXJfVGVybWluYXRlUm91dGVfUGFyYW1zLnJvdXRlSWQKICAgIGVyciA9IG1lc3NhZ2VWYWxpZGF0b3IudmFsaWRhdGVTdHJpbmdQb2ludGVyKG9mZnNldCArIGNvZGVjLmtTdHJ1Y3RIZWFkZXJTaXplICsgMCwgZmFsc2UpCiAgICBpZiAoZXJyICE9PSB2YWxpZGF0b3IudmFsaWRhdGlvbkVycm9yLk5PTkUpCiAgICAgICAgcmV0dXJuIGVycjsKCiAgICByZXR1cm4gdmFsaWRhdG9yLnZhbGlkYXRpb25FcnJvci5OT05FOwogIH07CgogIE1lZGlhUm91dGVQcm92aWRlcl9UZXJtaW5hdGVSb3V0ZV9QYXJhbXMuZW5jb2RlZFNpemUgPSBjb2RlYy5rU3RydWN0SGVhZGVyU2l6ZSArIDg7CgogIE1lZGlhUm91dGVQcm92aWRlcl9UZXJtaW5hdGVSb3V0ZV9QYXJhbXMuZGVjb2RlID0gZnVuY3Rpb24oZGVjb2RlcikgewogICAgdmFyIHBhY2tlZDsKICAgIHZhciB2YWwgPSBuZXcgTWVkaWFSb3V0ZVByb3ZpZGVyX1Rlcm1pbmF0ZVJvdXRlX1BhcmFtcygpOwogICAgdmFyIG51bWJlck9mQnl0ZXMgPSBkZWNvZGVyLnJlYWRVaW50MzIoKTsKICAgIHZhciB2ZXJzaW9uID0gZGVjb2Rlci5yZWFkVWludDMyKCk7CiAgICB2YWwucm91dGVJZCA9IGRlY29kZXIuZGVjb2RlU3RydWN0KGNvZGVjLlN0cmluZyk7CiAgICByZXR1cm4gdmFsOwogIH07CgogIE1lZGlhUm91dGVQcm92aWRlcl9UZXJtaW5hdGVSb3V0ZV9QYXJhbXMuZW5jb2RlID0gZnVuY3Rpb24oZW5jb2RlciwgdmFsKSB7CiAgICB2YXIgcGFja2VkOwogICAgZW5jb2Rlci53cml0ZVVpbnQzMihNZWRpYVJvdXRlUHJvdmlkZXJfVGVybWluYXRlUm91dGVfUGFyYW1zLmVuY29kZWRTaXplKTsKICAgIGVuY29kZXIud3JpdGVVaW50MzIoMCk7CiAgICBlbmNvZGVyLmVuY29kZVN0cnVjdChjb2RlYy5TdHJpbmcsIHZhbC5yb3V0ZUlkKTsKICB9OwogIGZ1bmN0aW9uIE1lZGlhUm91dGVQcm92aWRlcl9UZXJtaW5hdGVSb3V0ZV9SZXNwb25zZVBhcmFtcyh2YWx1ZXMpIHsKICAgIHRoaXMuaW5pdERlZmF1bHRzXygpOwogICAgdGhpcy5pbml0RmllbGRzXyh2YWx1ZXMpOwogIH0KCgogIE1lZGlhUm91dGVQcm92aWRlcl9UZXJtaW5hdGVSb3V0ZV9SZXNwb25zZVBhcmFtcy5wcm90b3R5cGUuaW5pdERlZmF1bHRzXyA9IGZ1bmN0aW9uKCkgewogICAgdGhpcy5lcnJvclRleHQgPSBudWxsOwogICAgdGhpcy5yZXN1bHRDb2RlID0gMDsKICB9OwogIE1lZGlhUm91dGVQcm92aWRlcl9UZXJtaW5hdGVSb3V0ZV9SZXNwb25zZVBhcmFtcy5wcm90b3R5cGUuaW5pdEZpZWxkc18gPSBmdW5jdGlvbihmaWVsZHMpIHsKICAgIGZvcih2YXIgZmllbGQgaW4gZmllbGRzKSB7CiAgICAgICAgaWYgKHRoaXMuaGFzT3duUHJvcGVydHkoZmllbGQpKQogICAgICAgICAgdGhpc1tmaWVsZF0gPSBmaWVsZHNbZmllbGRdOwogICAgfQogIH07CgogIE1lZGlhUm91dGVQcm92aWRlcl9UZXJtaW5hdGVSb3V0ZV9SZXNwb25zZVBhcmFtcy52YWxpZGF0ZSA9IGZ1bmN0aW9uKG1lc3NhZ2VWYWxpZGF0b3IsIG9mZnNldCkgewogICAgdmFyIGVycjsKICAgIGVyciA9IG1lc3NhZ2VWYWxpZGF0b3IudmFsaWRhdGVTdHJ1Y3RIZWFkZXIob2Zmc2V0LCBjb2RlYy5rU3RydWN0SGVhZGVyU2l6ZSk7CiAgICBpZiAoZXJyICE9PSB2YWxpZGF0b3IudmFsaWRhdGlvbkVycm9yLk5PTkUpCiAgICAgICAgcmV0dXJuIGVycjsKCiAgICB2YXIga1ZlcnNpb25TaXplcyA9IFsKICAgICAge3ZlcnNpb246IDAsIG51bUJ5dGVzOiAyNH0KICAgIF07CiAgICBlcnIgPSBtZXNzYWdlVmFsaWRhdG9yLnZhbGlkYXRlU3RydWN0VmVyc2lvbihvZmZzZXQsIGtWZXJzaW9uU2l6ZXMpOwogICAgaWYgKGVyciAhPT0gdmFsaWRhdG9yLnZhbGlkYXRpb25FcnJvci5OT05FKQogICAgICAgIHJldHVybiBlcnI7CgoKICAgIC8vIHZhbGlkYXRlIE1lZGlhUm91dGVQcm92aWRlcl9UZXJtaW5hdGVSb3V0ZV9SZXNwb25zZVBhcmFtcy5lcnJvclRleHQKICAgIGVyciA9IG1lc3NhZ2VWYWxpZGF0b3IudmFsaWRhdGVTdHJpbmdQb2ludGVyKG9mZnNldCArIGNvZGVjLmtTdHJ1Y3RIZWFkZXJTaXplICsgMCwgdHJ1ZSkKICAgIGlmIChlcnIgIT09IHZhbGlkYXRvci52YWxpZGF0aW9uRXJyb3IuTk9ORSkKICAgICAgICByZXR1cm4gZXJyOwoKCiAgICAvLyB2YWxpZGF0ZSBNZWRpYVJvdXRlUHJvdmlkZXJfVGVybWluYXRlUm91dGVfUmVzcG9uc2VQYXJhbXMucmVzdWx0Q29kZQogICAgZXJyID0gbWVzc2FnZVZhbGlkYXRvci52YWxpZGF0ZUVudW0ob2Zmc2V0ICsgY29kZWMua1N0cnVjdEhlYWRlclNpemUgKyA4LCBSb3V0ZVJlcXVlc3RSZXN1bHRDb2RlKTsKICAgIGlmIChlcnIgIT09IHZhbGlkYXRvci52YWxpZGF0aW9uRXJyb3IuTk9ORSkKICAgICAgICByZXR1cm4gZXJyOwoKICAgIHJldHVybiB2YWxpZGF0b3IudmFsaWRhdGlvbkVycm9yLk5PTkU7CiAgfTsKCiAgTWVkaWFSb3V0ZVByb3ZpZGVyX1Rlcm1pbmF0ZVJvdXRlX1Jlc3BvbnNlUGFyYW1zLmVuY29kZWRTaXplID0gY29kZWMua1N0cnVjdEhlYWRlclNpemUgKyAxNjsKCiAgTWVkaWFSb3V0ZVByb3ZpZGVyX1Rlcm1pbmF0ZVJvdXRlX1Jlc3BvbnNlUGFyYW1zLmRlY29kZSA9IGZ1bmN0aW9uKGRlY29kZXIpIHsKICAgIHZhciBwYWNrZWQ7CiAgICB2YXIgdmFsID0gbmV3IE1lZGlhUm91dGVQcm92aWRlcl9UZXJtaW5hdGVSb3V0ZV9SZXNwb25zZVBhcmFtcygpOwogICAgdmFyIG51bWJlck9mQnl0ZXMgPSBkZWNvZGVyLnJlYWRVaW50MzIoKTsKICAgIHZhciB2ZXJzaW9uID0gZGVjb2Rlci5yZWFkVWludDMyKCk7CiAgICB2YWwuZXJyb3JUZXh0ID0gZGVjb2Rlci5kZWNvZGVTdHJ1Y3QoY29kZWMuTnVsbGFibGVTdHJpbmcpOwogICAgdmFsLnJlc3VsdENvZGUgPSBkZWNvZGVyLmRlY29kZVN0cnVjdChjb2RlYy5JbnQzMik7CiAgICBkZWNvZGVyLnNraXAoMSk7CiAgICBkZWNvZGVyLnNraXAoMSk7CiAgICBkZWNvZGVyLnNraXAoMSk7CiAgICBkZWNvZGVyLnNraXAoMSk7CiAgICByZXR1cm4gdmFsOwogIH07CgogIE1lZGlhUm91dGVQcm92aWRlcl9UZXJtaW5hdGVSb3V0ZV9SZXNwb25zZVBhcmFtcy5lbmNvZGUgPSBmdW5jdGlvbihlbmNvZGVyLCB2YWwpIHsKICAgIHZhciBwYWNrZWQ7CiAgICBlbmNvZGVyLndyaXRlVWludDMyKE1lZGlhUm91dGVQcm92aWRlcl9UZXJtaW5hdGVSb3V0ZV9SZXNwb25zZVBhcmFtcy5lbmNvZGVkU2l6ZSk7CiAgICBlbmNvZGVyLndyaXRlVWludDMyKDApOwogICAgZW5jb2Rlci5lbmNvZGVTdHJ1Y3QoY29kZWMuTnVsbGFibGVTdHJpbmcsIHZhbC5lcnJvclRleHQpOwogICAgZW5jb2Rlci5lbmNvZGVTdHJ1Y3QoY29kZWMuSW50MzIsIHZhbC5yZXN1bHRDb2RlKTsKICAgIGVuY29kZXIuc2tpcCgxKTsKICAgIGVuY29kZXIuc2tpcCgxKTsKICAgIGVuY29kZXIuc2tpcCgxKTsKICAgIGVuY29kZXIuc2tpcCgxKTsKICB9OwogIGZ1bmN0aW9uIE1lZGlhUm91dGVQcm92aWRlcl9TZW5kUm91dGVNZXNzYWdlX1BhcmFtcyh2YWx1ZXMpIHsKICAgIHRoaXMuaW5pdERlZmF1bHRzXygpOwogICAgdGhpcy5pbml0RmllbGRzXyh2YWx1ZXMpOwogIH0KCgogIE1lZGlhUm91dGVQcm92aWRlcl9TZW5kUm91dGVNZXNzYWdlX1BhcmFtcy5wcm90b3R5cGUuaW5pdERlZmF1bHRzXyA9IGZ1bmN0aW9uKCkgewogICAgdGhpcy5tZWRpYVJvdXRlSWQgPSBudWxsOwogICAgdGhpcy5tZXNzYWdlID0gbnVsbDsKICB9OwogIE1lZGlhUm91dGVQcm92aWRlcl9TZW5kUm91dGVNZXNzYWdlX1BhcmFtcy5wcm90b3R5cGUuaW5pdEZpZWxkc18gPSBmdW5jdGlvbihmaWVsZHMpIHsKICAgIGZvcih2YXIgZmllbGQgaW4gZmllbGRzKSB7CiAgICAgICAgaWYgKHRoaXMuaGFzT3duUHJvcGVydHkoZmllbGQpKQogICAgICAgICAgdGhpc1tmaWVsZF0gPSBmaWVsZHNbZmllbGRdOwogICAgfQogIH07CgogIE1lZGlhUm91dGVQcm92aWRlcl9TZW5kUm91dGVNZXNzYWdlX1BhcmFtcy52YWxpZGF0ZSA9IGZ1bmN0aW9uKG1lc3NhZ2VWYWxpZGF0b3IsIG9mZnNldCkgewogICAgdmFyIGVycjsKICAgIGVyciA9IG1lc3NhZ2VWYWxpZGF0b3IudmFsaWRhdGVTdHJ1Y3RIZWFkZXIob2Zmc2V0LCBjb2RlYy5rU3RydWN0SGVhZGVyU2l6ZSk7CiAgICBpZiAoZXJyICE9PSB2YWxpZGF0b3IudmFsaWRhdGlvbkVycm9yLk5PTkUpCiAgICAgICAgcmV0dXJuIGVycjsKCiAgICB2YXIga1ZlcnNpb25TaXplcyA9IFsKICAgICAge3ZlcnNpb246IDAsIG51bUJ5dGVzOiAyNH0KICAgIF07CiAgICBlcnIgPSBtZXNzYWdlVmFsaWRhdG9yLnZhbGlkYXRlU3RydWN0VmVyc2lvbihvZmZzZXQsIGtWZXJzaW9uU2l6ZXMpOwogICAgaWYgKGVyciAhPT0gdmFsaWRhdG9yLnZhbGlkYXRpb25FcnJvci5OT05FKQogICAgICAgIHJldHVybiBlcnI7CgoKICAgIC8vIHZhbGlkYXRlIE1lZGlhUm91dGVQcm92aWRlcl9TZW5kUm91dGVNZXNzYWdlX1BhcmFtcy5tZWRpYVJvdXRlSWQKICAgIGVyciA9IG1lc3NhZ2VWYWxpZGF0b3IudmFsaWRhdGVTdHJpbmdQb2ludGVyKG9mZnNldCArIGNvZGVjLmtTdHJ1Y3RIZWFkZXJTaXplICsgMCwgZmFsc2UpCiAgICBpZiAoZXJyICE9PSB2YWxpZGF0b3IudmFsaWRhdGlvbkVycm9yLk5PTkUpCiAgICAgICAgcmV0dXJuIGVycjsKCgogICAgLy8gdmFsaWRhdGUgTWVkaWFSb3V0ZVByb3ZpZGVyX1NlbmRSb3V0ZU1lc3NhZ2VfUGFyYW1zLm1lc3NhZ2UKICAgIGVyciA9IG1lc3NhZ2VWYWxpZGF0b3IudmFsaWRhdGVTdHJpbmdQb2ludGVyKG9mZnNldCArIGNvZGVjLmtTdHJ1Y3RIZWFkZXJTaXplICsgOCwgZmFsc2UpCiAgICBpZiAoZXJyICE9PSB2YWxpZGF0b3IudmFsaWRhdGlvbkVycm9yLk5PTkUpCiAgICAgICAgcmV0dXJuIGVycjsKCiAgICByZXR1cm4gdmFsaWRhdG9yLnZhbGlkYXRpb25FcnJvci5OT05FOwogIH07CgogIE1lZGlhUm91dGVQcm92aWRlcl9TZW5kUm91dGVNZXNzYWdlX1BhcmFtcy5lbmNvZGVkU2l6ZSA9IGNvZGVjLmtTdHJ1Y3RIZWFkZXJTaXplICsgMTY7CgogIE1lZGlhUm91dGVQcm92aWRlcl9TZW5kUm91dGVNZXNzYWdlX1BhcmFtcy5kZWNvZGUgPSBmdW5jdGlvbihkZWNvZGVyKSB7CiAgICB2YXIgcGFja2VkOwogICAgdmFyIHZhbCA9IG5ldyBNZWRpYVJvdXRlUHJvdmlkZXJfU2VuZFJvdXRlTWVzc2FnZV9QYXJhbXMoKTsKICAgIHZhciBudW1iZXJPZkJ5dGVzID0gZGVjb2Rlci5yZWFkVWludDMyKCk7CiAgICB2YXIgdmVyc2lvbiA9IGRlY29kZXIucmVhZFVpbnQzMigpOwogICAgdmFsLm1lZGlhUm91dGVJZCA9IGRlY29kZXIuZGVjb2RlU3RydWN0KGNvZGVjLlN0cmluZyk7CiAgICB2YWwubWVzc2FnZSA9IGRlY29kZXIuZGVjb2RlU3RydWN0KGNvZGVjLlN0cmluZyk7CiAgICByZXR1cm4gdmFsOwogIH07CgogIE1lZGlhUm91dGVQcm92aWRlcl9TZW5kUm91dGVNZXNzYWdlX1BhcmFtcy5lbmNvZGUgPSBmdW5jdGlvbihlbmNvZGVyLCB2YWwpIHsKICAgIHZhciBwYWNrZWQ7CiAgICBlbmNvZGVyLndyaXRlVWludDMyKE1lZGlhUm91dGVQcm92aWRlcl9TZW5kUm91dGVNZXNzYWdlX1BhcmFtcy5lbmNvZGVkU2l6ZSk7CiAgICBlbmNvZGVyLndyaXRlVWludDMyKDApOwogICAgZW5jb2Rlci5lbmNvZGVTdHJ1Y3QoY29kZWMuU3RyaW5nLCB2YWwubWVkaWFSb3V0ZUlkKTsKICAgIGVuY29kZXIuZW5jb2RlU3RydWN0KGNvZGVjLlN0cmluZywgdmFsLm1lc3NhZ2UpOwogIH07CiAgZnVuY3Rpb24gTWVkaWFSb3V0ZVByb3ZpZGVyX1NlbmRSb3V0ZU1lc3NhZ2VfUmVzcG9uc2VQYXJhbXModmFsdWVzKSB7CiAgICB0aGlzLmluaXREZWZhdWx0c18oKTsKICAgIHRoaXMuaW5pdEZpZWxkc18odmFsdWVzKTsKICB9CgoKICBNZWRpYVJvdXRlUHJvdmlkZXJfU2VuZFJvdXRlTWVzc2FnZV9SZXNwb25zZVBhcmFtcy5wcm90b3R5cGUuaW5pdERlZmF1bHRzXyA9IGZ1bmN0aW9uKCkgewogICAgdGhpcy5zZW50ID0gZmFsc2U7CiAgfTsKICBNZWRpYVJvdXRlUHJvdmlkZXJfU2VuZFJvdXRlTWVzc2FnZV9SZXNwb25zZVBhcmFtcy5wcm90b3R5cGUuaW5pdEZpZWxkc18gPSBmdW5jdGlvbihmaWVsZHMpIHsKICAgIGZvcih2YXIgZmllbGQgaW4gZmllbGRzKSB7CiAgICAgICAgaWYgKHRoaXMuaGFzT3duUHJvcGVydHkoZmllbGQpKQogICAgICAgICAgdGhpc1tmaWVsZF0gPSBmaWVsZHNbZmllbGRdOwogICAgfQogIH07CgogIE1lZGlhUm91dGVQcm92aWRlcl9TZW5kUm91dGVNZXNzYWdlX1Jlc3BvbnNlUGFyYW1zLnZhbGlkYXRlID0gZnVuY3Rpb24obWVzc2FnZVZhbGlkYXRvciwgb2Zmc2V0KSB7CiAgICB2YXIgZXJyOwogICAgZXJyID0gbWVzc2FnZVZhbGlkYXRvci52YWxpZGF0ZVN0cnVjdEhlYWRlcihvZmZzZXQsIGNvZGVjLmtTdHJ1Y3RIZWFkZXJTaXplKTsKICAgIGlmIChlcnIgIT09IHZhbGlkYXRvci52YWxpZGF0aW9uRXJyb3IuTk9ORSkKICAgICAgICByZXR1cm4gZXJyOwoKICAgIHZhciBrVmVyc2lvblNpemVzID0gWwogICAgICB7dmVyc2lvbjogMCwgbnVtQnl0ZXM6IDE2fQogICAgXTsKICAgIGVyciA9IG1lc3NhZ2VWYWxpZGF0b3IudmFsaWRhdGVTdHJ1Y3RWZXJzaW9uKG9mZnNldCwga1ZlcnNpb25TaXplcyk7CiAgICBpZiAoZXJyICE9PSB2YWxpZGF0b3IudmFsaWRhdGlvbkVycm9yLk5PTkUpCiAgICAgICAgcmV0dXJuIGVycjsKCgogICAgcmV0dXJuIHZhbGlkYXRvci52YWxpZGF0aW9uRXJyb3IuTk9ORTsKICB9OwoKICBNZWRpYVJvdXRlUHJvdmlkZXJfU2VuZFJvdXRlTWVzc2FnZV9SZXNwb25zZVBhcmFtcy5lbmNvZGVkU2l6ZSA9IGNvZGVjLmtTdHJ1Y3RIZWFkZXJTaXplICsgODsKCiAgTWVkaWFSb3V0ZVByb3ZpZGVyX1NlbmRSb3V0ZU1lc3NhZ2VfUmVzcG9uc2VQYXJhbXMuZGVjb2RlID0gZnVuY3Rpb24oZGVjb2RlcikgewogICAgdmFyIHBhY2tlZDsKICAgIHZhciB2YWwgPSBuZXcgTWVkaWFSb3V0ZVByb3ZpZGVyX1NlbmRSb3V0ZU1lc3NhZ2VfUmVzcG9uc2VQYXJhbXMoKTsKICAgIHZhciBudW1iZXJPZkJ5dGVzID0gZGVjb2Rlci5yZWFkVWludDMyKCk7CiAgICB2YXIgdmVyc2lvbiA9IGRlY29kZXIucmVhZFVpbnQzMigpOwogICAgcGFja2VkID0gZGVjb2Rlci5yZWFkVWludDgoKTsKICAgIHZhbC5zZW50ID0gKHBhY2tlZCA+PiAwKSAmIDEgPyB0cnVlIDogZmFsc2U7CiAgICBkZWNvZGVyLnNraXAoMSk7CiAgICBkZWNvZGVyLnNraXAoMSk7CiAgICBkZWNvZGVyLnNraXAoMSk7CiAgICBkZWNvZGVyLnNraXAoMSk7CiAgICBkZWNvZGVyLnNraXAoMSk7CiAgICBkZWNvZGVyLnNraXAoMSk7CiAgICBkZWNvZGVyLnNraXAoMSk7CiAgICByZXR1cm4gdmFsOwogIH07CgogIE1lZGlhUm91dGVQcm92aWRlcl9TZW5kUm91dGVNZXNzYWdlX1Jlc3BvbnNlUGFyYW1zLmVuY29kZSA9IGZ1bmN0aW9uKGVuY29kZXIsIHZhbCkgewogICAgdmFyIHBhY2tlZDsKICAgIGVuY29kZXIud3JpdGVVaW50MzIoTWVkaWFSb3V0ZVByb3ZpZGVyX1NlbmRSb3V0ZU1lc3NhZ2VfUmVzcG9uc2VQYXJhbXMuZW5jb2RlZFNpemUpOwogICAgZW5jb2Rlci53cml0ZVVpbnQzMigwKTsKICAgIHBhY2tlZCA9IDA7CiAgICBwYWNrZWQgfD0gKHZhbC5zZW50ICYgMSkgPDwgMAogICAgZW5jb2Rlci53cml0ZVVpbnQ4KHBhY2tlZCk7CiAgICBlbmNvZGVyLnNraXAoMSk7CiAgICBlbmNvZGVyLnNraXAoMSk7CiAgICBlbmNvZGVyLnNraXAoMSk7CiAgICBlbmNvZGVyLnNraXAoMSk7CiAgICBlbmNvZGVyLnNraXAoMSk7CiAgICBlbmNvZGVyLnNraXAoMSk7CiAgICBlbmNvZGVyLnNraXAoMSk7CiAgfTsKICBmdW5jdGlvbiBNZWRpYVJvdXRlUHJvdmlkZXJfU2VuZFJvdXRlQmluYXJ5TWVzc2FnZV9QYXJhbXModmFsdWVzKSB7CiAgICB0aGlzLmluaXREZWZhdWx0c18oKTsKICAgIHRoaXMuaW5pdEZpZWxkc18odmFsdWVzKTsKICB9CgoKICBNZWRpYVJvdXRlUHJvdmlkZXJfU2VuZFJvdXRlQmluYXJ5TWVzc2FnZV9QYXJhbXMucHJvdG90eXBlLmluaXREZWZhdWx0c18gPSBmdW5jdGlvbigpIHsKICAgIHRoaXMubWVkaWFSb3V0ZUlkID0gbnVsbDsKICAgIHRoaXMuZGF0YSA9IG51bGw7CiAgfTsKICBNZWRpYVJvdXRlUHJvdmlkZXJfU2VuZFJvdXRlQmluYXJ5TWVzc2FnZV9QYXJhbXMucHJvdG90eXBlLmluaXRGaWVsZHNfID0gZnVuY3Rpb24oZmllbGRzKSB7CiAgICBmb3IodmFyIGZpZWxkIGluIGZpZWxkcykgewogICAgICAgIGlmICh0aGlzLmhhc093blByb3BlcnR5KGZpZWxkKSkKICAgICAgICAgIHRoaXNbZmllbGRdID0gZmllbGRzW2ZpZWxkXTsKICAgIH0KICB9OwoKICBNZWRpYVJvdXRlUHJvdmlkZXJfU2VuZFJvdXRlQmluYXJ5TWVzc2FnZV9QYXJhbXMudmFsaWRhdGUgPSBmdW5jdGlvbihtZXNzYWdlVmFsaWRhdG9yLCBvZmZzZXQpIHsKICAgIHZhciBlcnI7CiAgICBlcnIgPSBtZXNzYWdlVmFsaWRhdG9yLnZhbGlkYXRlU3RydWN0SGVhZGVyKG9mZnNldCwgY29kZWMua1N0cnVjdEhlYWRlclNpemUpOwogICAgaWYgKGVyciAhPT0gdmFsaWRhdG9yLnZhbGlkYXRpb25FcnJvci5OT05FKQogICAgICAgIHJldHVybiBlcnI7CgogICAgdmFyIGtWZXJzaW9uU2l6ZXMgPSBbCiAgICAgIHt2ZXJzaW9uOiAwLCBudW1CeXRlczogMjR9CiAgICBdOwogICAgZXJyID0gbWVzc2FnZVZhbGlkYXRvci52YWxpZGF0ZVN0cnVjdFZlcnNpb24ob2Zmc2V0LCBrVmVyc2lvblNpemVzKTsKICAgIGlmIChlcnIgIT09IHZhbGlkYXRvci52YWxpZGF0aW9uRXJyb3IuTk9ORSkKICAgICAgICByZXR1cm4gZXJyOwoKCiAgICAvLyB2YWxpZGF0ZSBNZWRpYVJvdXRlUHJvdmlkZXJfU2VuZFJvdXRlQmluYXJ5TWVzc2FnZV9QYXJhbXMubWVkaWFSb3V0ZUlkCiAgICBlcnIgPSBtZXNzYWdlVmFsaWRhdG9yLnZhbGlkYXRlU3RyaW5nUG9pbnRlcihvZmZzZXQgKyBjb2RlYy5rU3RydWN0SGVhZGVyU2l6ZSArIDAsIGZhbHNlKQogICAgaWYgKGVyciAhPT0gdmFsaWRhdG9yLnZhbGlkYXRpb25FcnJvci5OT05FKQogICAgICAgIHJldHVybiBlcnI7CgoKICAgIC8vIHZhbGlkYXRlIE1lZGlhUm91dGVQcm92aWRlcl9TZW5kUm91dGVCaW5hcnlNZXNzYWdlX1BhcmFtcy5kYXRhCiAgICBlcnIgPSBtZXNzYWdlVmFsaWRhdG9yLnZhbGlkYXRlQXJyYXlQb2ludGVyKG9mZnNldCArIGNvZGVjLmtTdHJ1Y3RIZWFkZXJTaXplICsgOCwgMSwgY29kZWMuVWludDgsIGZhbHNlLCBbMF0sIDApOwogICAgaWYgKGVyciAhPT0gdmFsaWRhdG9yLnZhbGlkYXRpb25FcnJvci5OT05FKQogICAgICAgIHJldHVybiBlcnI7CgogICAgcmV0dXJuIHZhbGlkYXRvci52YWxpZGF0aW9uRXJyb3IuTk9ORTsKICB9OwoKICBNZWRpYVJvdXRlUHJvdmlkZXJfU2VuZFJvdXRlQmluYXJ5TWVzc2FnZV9QYXJhbXMuZW5jb2RlZFNpemUgPSBjb2RlYy5rU3RydWN0SGVhZGVyU2l6ZSArIDE2OwoKICBNZWRpYVJvdXRlUHJvdmlkZXJfU2VuZFJvdXRlQmluYXJ5TWVzc2FnZV9QYXJhbXMuZGVjb2RlID0gZnVuY3Rpb24oZGVjb2RlcikgewogICAgdmFyIHBhY2tlZDsKICAgIHZhciB2YWwgPSBuZXcgTWVkaWFSb3V0ZVByb3ZpZGVyX1NlbmRSb3V0ZUJpbmFyeU1lc3NhZ2VfUGFyYW1zKCk7CiAgICB2YXIgbnVtYmVyT2ZCeXRlcyA9IGRlY29kZXIucmVhZFVpbnQzMigpOwogICAgdmFyIHZlcnNpb24gPSBkZWNvZGVyLnJlYWRVaW50MzIoKTsKICAgIHZhbC5tZWRpYVJvdXRlSWQgPSBkZWNvZGVyLmRlY29kZVN0cnVjdChjb2RlYy5TdHJpbmcpOwogICAgdmFsLmRhdGEgPSBkZWNvZGVyLmRlY29kZUFycmF5UG9pbnRlcihjb2RlYy5VaW50OCk7CiAgICByZXR1cm4gdmFsOwogIH07CgogIE1lZGlhUm91dGVQcm92aWRlcl9TZW5kUm91dGVCaW5hcnlNZXNzYWdlX1BhcmFtcy5lbmNvZGUgPSBmdW5jdGlvbihlbmNvZGVyLCB2YWwpIHsKICAgIHZhciBwYWNrZWQ7CiAgICBlbmNvZGVyLndyaXRlVWludDMyKE1lZGlhUm91dGVQcm92aWRlcl9TZW5kUm91dGVCaW5hcnlNZXNzYWdlX1BhcmFtcy5lbmNvZGVkU2l6ZSk7CiAgICBlbmNvZGVyLndyaXRlVWludDMyKDApOwogICAgZW5jb2Rlci5lbmNvZGVTdHJ1Y3QoY29kZWMuU3RyaW5nLCB2YWwubWVkaWFSb3V0ZUlkKTsKICAgIGVuY29kZXIuZW5jb2RlQXJyYXlQb2ludGVyKGNvZGVjLlVpbnQ4LCB2YWwuZGF0YSk7CiAgfTsKICBmdW5jdGlvbiBNZWRpYVJvdXRlUHJvdmlkZXJfU2VuZFJvdXRlQmluYXJ5TWVzc2FnZV9SZXNwb25zZVBhcmFtcyh2YWx1ZXMpIHsKICAgIHRoaXMuaW5pdERlZmF1bHRzXygpOwogICAgdGhpcy5pbml0RmllbGRzXyh2YWx1ZXMpOwogIH0KCgogIE1lZGlhUm91dGVQcm92aWRlcl9TZW5kUm91dGVCaW5hcnlNZXNzYWdlX1Jlc3BvbnNlUGFyYW1zLnByb3RvdHlwZS5pbml0RGVmYXVsdHNfID0gZnVuY3Rpb24oKSB7CiAgICB0aGlzLnNlbnQgPSBmYWxzZTsKICB9OwogIE1lZGlhUm91dGVQcm92aWRlcl9TZW5kUm91dGVCaW5hcnlNZXNzYWdlX1Jlc3BvbnNlUGFyYW1zLnByb3RvdHlwZS5pbml0RmllbGRzXyA9IGZ1bmN0aW9uKGZpZWxkcykgewogICAgZm9yKHZhciBmaWVsZCBpbiBmaWVsZHMpIHsKICAgICAgICBpZiAodGhpcy5oYXNPd25Qcm9wZXJ0eShmaWVsZCkpCiAgICAgICAgICB0aGlzW2ZpZWxkXSA9IGZpZWxkc1tmaWVsZF07CiAgICB9CiAgfTsKCiAgTWVkaWFSb3V0ZVByb3ZpZGVyX1NlbmRSb3V0ZUJpbmFyeU1lc3NhZ2VfUmVzcG9uc2VQYXJhbXMudmFsaWRhdGUgPSBmdW5jdGlvbihtZXNzYWdlVmFsaWRhdG9yLCBvZmZzZXQpIHsKICAgIHZhciBlcnI7CiAgICBlcnIgPSBtZXNzYWdlVmFsaWRhdG9yLnZhbGlkYXRlU3RydWN0SGVhZGVyKG9mZnNldCwgY29kZWMua1N0cnVjdEhlYWRlclNpemUpOwogICAgaWYgKGVyciAhPT0gdmFsaWRhdG9yLnZhbGlkYXRpb25FcnJvci5OT05FKQogICAgICAgIHJldHVybiBlcnI7CgogICAgdmFyIGtWZXJzaW9uU2l6ZXMgPSBbCiAgICAgIHt2ZXJzaW9uOiAwLCBudW1CeXRlczogMTZ9CiAgICBdOwogICAgZXJyID0gbWVzc2FnZVZhbGlkYXRvci52YWxpZGF0ZVN0cnVjdFZlcnNpb24ob2Zmc2V0LCBrVmVyc2lvblNpemVzKTsKICAgIGlmIChlcnIgIT09IHZhbGlkYXRvci52YWxpZGF0aW9uRXJyb3IuTk9ORSkKICAgICAgICByZXR1cm4gZXJyOwoKCiAgICByZXR1cm4gdmFsaWRhdG9yLnZhbGlkYXRpb25FcnJvci5OT05FOwogIH07CgogIE1lZGlhUm91dGVQcm92aWRlcl9TZW5kUm91dGVCaW5hcnlNZXNzYWdlX1Jlc3BvbnNlUGFyYW1zLmVuY29kZWRTaXplID0gY29kZWMua1N0cnVjdEhlYWRlclNpemUgKyA4OwoKICBNZWRpYVJvdXRlUHJvdmlkZXJfU2VuZFJvdXRlQmluYXJ5TWVzc2FnZV9SZXNwb25zZVBhcmFtcy5kZWNvZGUgPSBmdW5jdGlvbihkZWNvZGVyKSB7CiAgICB2YXIgcGFja2VkOwogICAgdmFyIHZhbCA9IG5ldyBNZWRpYVJvdXRlUHJvdmlkZXJfU2VuZFJvdXRlQmluYXJ5TWVzc2FnZV9SZXNwb25zZVBhcmFtcygpOwogICAgdmFyIG51bWJlck9mQnl0ZXMgPSBkZWNvZGVyLnJlYWRVaW50MzIoKTsKICAgIHZhciB2ZXJzaW9uID0gZGVjb2Rlci5yZWFkVWludDMyKCk7CiAgICBwYWNrZWQgPSBkZWNvZGVyLnJlYWRVaW50OCgpOwogICAgdmFsLnNlbnQgPSAocGFja2VkID4+IDApICYgMSA/IHRydWUgOiBmYWxzZTsKICAgIGRlY29kZXIuc2tpcCgxKTsKICAgIGRlY29kZXIuc2tpcCgxKTsKICAgIGRlY29kZXIuc2tpcCgxKTsKICAgIGRlY29kZXIuc2tpcCgxKTsKICAgIGRlY29kZXIuc2tpcCgxKTsKICAgIGRlY29kZXIuc2tpcCgxKTsKICAgIGRlY29kZXIuc2tpcCgxKTsKICAgIHJldHVybiB2YWw7CiAgfTsKCiAgTWVkaWFSb3V0ZVByb3ZpZGVyX1NlbmRSb3V0ZUJpbmFyeU1lc3NhZ2VfUmVzcG9uc2VQYXJhbXMuZW5jb2RlID0gZnVuY3Rpb24oZW5jb2RlciwgdmFsKSB7CiAgICB2YXIgcGFja2VkOwogICAgZW5jb2Rlci53cml0ZVVpbnQzMihNZWRpYVJvdXRlUHJvdmlkZXJfU2VuZFJvdXRlQmluYXJ5TWVzc2FnZV9SZXNwb25zZVBhcmFtcy5lbmNvZGVkU2l6ZSk7CiAgICBlbmNvZGVyLndyaXRlVWludDMyKDApOwogICAgcGFja2VkID0gMDsKICAgIHBhY2tlZCB8PSAodmFsLnNlbnQgJiAxKSA8PCAwCiAgICBlbmNvZGVyLndyaXRlVWludDgocGFja2VkKTsKICAgIGVuY29kZXIuc2tpcCgxKTsKICAgIGVuY29kZXIuc2tpcCgxKTsKICAgIGVuY29kZXIuc2tpcCgxKTsKICAgIGVuY29kZXIuc2tpcCgxKTsKICAgIGVuY29kZXIuc2tpcCgxKTsKICAgIGVuY29kZXIuc2tpcCgxKTsKICAgIGVuY29kZXIuc2tpcCgxKTsKICB9OwogIGZ1bmN0aW9uIE1lZGlhUm91dGVQcm92aWRlcl9TdGFydE9ic2VydmluZ01lZGlhU2lua3NfUGFyYW1zKHZhbHVlcykgewogICAgdGhpcy5pbml0RGVmYXVsdHNfKCk7CiAgICB0aGlzLmluaXRGaWVsZHNfKHZhbHVlcyk7CiAgfQoKCiAgTWVkaWFSb3V0ZVByb3ZpZGVyX1N0YXJ0T2JzZXJ2aW5nTWVkaWFTaW5rc19QYXJhbXMucHJvdG90eXBlLmluaXREZWZhdWx0c18gPSBmdW5jdGlvbigpIHsKICAgIHRoaXMubWVkaWFTb3VyY2UgPSBudWxsOwogIH07CiAgTWVkaWFSb3V0ZVByb3ZpZGVyX1N0YXJ0T2JzZXJ2aW5nTWVkaWFTaW5rc19QYXJhbXMucHJvdG90eXBlLmluaXRGaWVsZHNfID0gZnVuY3Rpb24oZmllbGRzKSB7CiAgICBmb3IodmFyIGZpZWxkIGluIGZpZWxkcykgewogICAgICAgIGlmICh0aGlzLmhhc093blByb3BlcnR5KGZpZWxkKSkKICAgICAgICAgIHRoaXNbZmllbGRdID0gZmllbGRzW2ZpZWxkXTsKICAgIH0KICB9OwoKICBNZWRpYVJvdXRlUHJvdmlkZXJfU3RhcnRPYnNlcnZpbmdNZWRpYVNpbmtzX1BhcmFtcy52YWxpZGF0ZSA9IGZ1bmN0aW9uKG1lc3NhZ2VWYWxpZGF0b3IsIG9mZnNldCkgewogICAgdmFyIGVycjsKICAgIGVyciA9IG1lc3NhZ2VWYWxpZGF0b3IudmFsaWRhdGVTdHJ1Y3RIZWFkZXIob2Zmc2V0LCBjb2RlYy5rU3RydWN0SGVhZGVyU2l6ZSk7CiAgICBpZiAoZXJyICE9PSB2YWxpZGF0b3IudmFsaWRhdGlvbkVycm9yLk5PTkUpCiAgICAgICAgcmV0dXJuIGVycjsKCiAgICB2YXIga1ZlcnNpb25TaXplcyA9IFsKICAgICAge3ZlcnNpb246IDAsIG51bUJ5dGVzOiAxNn0KICAgIF07CiAgICBlcnIgPSBtZXNzYWdlVmFsaWRhdG9yLnZhbGlkYXRlU3RydWN0VmVyc2lvbihvZmZzZXQsIGtWZXJzaW9uU2l6ZXMpOwogICAgaWYgKGVyciAhPT0gdmFsaWRhdG9yLnZhbGlkYXRpb25FcnJvci5OT05FKQogICAgICAgIHJldHVybiBlcnI7CgoKICAgIC8vIHZhbGlkYXRlIE1lZGlhUm91dGVQcm92aWRlcl9TdGFydE9ic2VydmluZ01lZGlhU2lua3NfUGFyYW1zLm1lZGlhU291cmNlCiAgICBlcnIgPSBtZXNzYWdlVmFsaWRhdG9yLnZhbGlkYXRlU3RyaW5nUG9pbnRlcihvZmZzZXQgKyBjb2RlYy5rU3RydWN0SGVhZGVyU2l6ZSArIDAsIGZhbHNlKQogICAgaWYgKGVyciAhPT0gdmFsaWRhdG9yLnZhbGlkYXRpb25FcnJvci5OT05FKQogICAgICAgIHJldHVybiBlcnI7CgogICAgcmV0dXJuIHZhbGlkYXRvci52YWxpZGF0aW9uRXJyb3IuTk9ORTsKICB9OwoKICBNZWRpYVJvdXRlUHJvdmlkZXJfU3RhcnRPYnNlcnZpbmdNZWRpYVNpbmtzX1BhcmFtcy5lbmNvZGVkU2l6ZSA9IGNvZGVjLmtTdHJ1Y3RIZWFkZXJTaXplICsgODsKCiAgTWVkaWFSb3V0ZVByb3ZpZGVyX1N0YXJ0T2JzZXJ2aW5nTWVkaWFTaW5rc19QYXJhbXMuZGVjb2RlID0gZnVuY3Rpb24oZGVjb2RlcikgewogICAgdmFyIHBhY2tlZDsKICAgIHZhciB2YWwgPSBuZXcgTWVkaWFSb3V0ZVByb3ZpZGVyX1N0YXJ0T2JzZXJ2aW5nTWVkaWFTaW5rc19QYXJhbXMoKTsKICAgIHZhciBudW1iZXJPZkJ5dGVzID0gZGVjb2Rlci5yZWFkVWludDMyKCk7CiAgICB2YXIgdmVyc2lvbiA9IGRlY29kZXIucmVhZFVpbnQzMigpOwogICAgdmFsLm1lZGlhU291cmNlID0gZGVjb2Rlci5kZWNvZGVTdHJ1Y3QoY29kZWMuU3RyaW5nKTsKICAgIHJldHVybiB2YWw7CiAgfTsKCiAgTWVkaWFSb3V0ZVByb3ZpZGVyX1N0YXJ0T2JzZXJ2aW5nTWVkaWFTaW5rc19QYXJhbXMuZW5jb2RlID0gZnVuY3Rpb24oZW5jb2RlciwgdmFsKSB7CiAgICB2YXIgcGFja2VkOwogICAgZW5jb2Rlci53cml0ZVVpbnQzMihNZWRpYVJvdXRlUHJvdmlkZXJfU3RhcnRPYnNlcnZpbmdNZWRpYVNpbmtzX1BhcmFtcy5lbmNvZGVkU2l6ZSk7CiAgICBlbmNvZGVyLndyaXRlVWludDMyKDApOwogICAgZW5jb2Rlci5lbmNvZGVTdHJ1Y3QoY29kZWMuU3RyaW5nLCB2YWwubWVkaWFTb3VyY2UpOwogIH07CiAgZnVuY3Rpb24gTWVkaWFSb3V0ZVByb3ZpZGVyX1N0b3BPYnNlcnZpbmdNZWRpYVNpbmtzX1BhcmFtcyh2YWx1ZXMpIHsKICAgIHRoaXMuaW5pdERlZmF1bHRzXygpOwogICAgdGhpcy5pbml0RmllbGRzXyh2YWx1ZXMpOwogIH0KCgogIE1lZGlhUm91dGVQcm92aWRlcl9TdG9wT2JzZXJ2aW5nTWVkaWFTaW5rc19QYXJhbXMucHJvdG90eXBlLmluaXREZWZhdWx0c18gPSBmdW5jdGlvbigpIHsKICAgIHRoaXMubWVkaWFTb3VyY2UgPSBudWxsOwogIH07CiAgTWVkaWFSb3V0ZVByb3ZpZGVyX1N0b3BPYnNlcnZpbmdNZWRpYVNpbmtzX1BhcmFtcy5wcm90b3R5cGUuaW5pdEZpZWxkc18gPSBmdW5jdGlvbihmaWVsZHMpIHsKICAgIGZvcih2YXIgZmllbGQgaW4gZmllbGRzKSB7CiAgICAgICAgaWYgKHRoaXMuaGFzT3duUHJvcGVydHkoZmllbGQpKQogICAgICAgICAgdGhpc1tmaWVsZF0gPSBmaWVsZHNbZmllbGRdOwogICAgfQogIH07CgogIE1lZGlhUm91dGVQcm92aWRlcl9TdG9wT2JzZXJ2aW5nTWVkaWFTaW5rc19QYXJhbXMudmFsaWRhdGUgPSBmdW5jdGlvbihtZXNzYWdlVmFsaWRhdG9yLCBvZmZzZXQpIHsKICAgIHZhciBlcnI7CiAgICBlcnIgPSBtZXNzYWdlVmFsaWRhdG9yLnZhbGlkYXRlU3RydWN0SGVhZGVyKG9mZnNldCwgY29kZWMua1N0cnVjdEhlYWRlclNpemUpOwogICAgaWYgKGVyciAhPT0gdmFsaWRhdG9yLnZhbGlkYXRpb25FcnJvci5OT05FKQogICAgICAgIHJldHVybiBlcnI7CgogICAgdmFyIGtWZXJzaW9uU2l6ZXMgPSBbCiAgICAgIHt2ZXJzaW9uOiAwLCBudW1CeXRlczogMTZ9CiAgICBdOwogICAgZXJyID0gbWVzc2FnZVZhbGlkYXRvci52YWxpZGF0ZVN0cnVjdFZlcnNpb24ob2Zmc2V0LCBrVmVyc2lvblNpemVzKTsKICAgIGlmIChlcnIgIT09IHZhbGlkYXRvci52YWxpZGF0aW9uRXJyb3IuTk9ORSkKICAgICAgICByZXR1cm4gZXJyOwoKCiAgICAvLyB2YWxpZGF0ZSBNZWRpYVJvdXRlUHJvdmlkZXJfU3RvcE9ic2VydmluZ01lZGlhU2lua3NfUGFyYW1zLm1lZGlhU291cmNlCiAgICBlcnIgPSBtZXNzYWdlVmFsaWRhdG9yLnZhbGlkYXRlU3RyaW5nUG9pbnRlcihvZmZzZXQgKyBjb2RlYy5rU3RydWN0SGVhZGVyU2l6ZSArIDAsIGZhbHNlKQogICAgaWYgKGVyciAhPT0gdmFsaWRhdG9yLnZhbGlkYXRpb25FcnJvci5OT05FKQogICAgICAgIHJldHVybiBlcnI7CgogICAgcmV0dXJuIHZhbGlkYXRvci52YWxpZGF0aW9uRXJyb3IuTk9ORTsKICB9OwoKICBNZWRpYVJvdXRlUHJvdmlkZXJfU3RvcE9ic2VydmluZ01lZGlhU2lua3NfUGFyYW1zLmVuY29kZWRTaXplID0gY29kZWMua1N0cnVjdEhlYWRlclNpemUgKyA4OwoKICBNZWRpYVJvdXRlUHJvdmlkZXJfU3RvcE9ic2VydmluZ01lZGlhU2lua3NfUGFyYW1zLmRlY29kZSA9IGZ1bmN0aW9uKGRlY29kZXIpIHsKICAgIHZhciBwYWNrZWQ7CiAgICB2YXIgdmFsID0gbmV3IE1lZGlhUm91dGVQcm92aWRlcl9TdG9wT2JzZXJ2aW5nTWVkaWFTaW5rc19QYXJhbXMoKTsKICAgIHZhciBudW1iZXJPZkJ5dGVzID0gZGVjb2Rlci5yZWFkVWludDMyKCk7CiAgICB2YXIgdmVyc2lvbiA9IGRlY29kZXIucmVhZFVpbnQzMigpOwogICAgdmFsLm1lZGlhU291cmNlID0gZGVjb2Rlci5kZWNvZGVTdHJ1Y3QoY29kZWMuU3RyaW5nKTsKICAgIHJldHVybiB2YWw7CiAgfTsKCiAgTWVkaWFSb3V0ZVByb3ZpZGVyX1N0b3BPYnNlcnZpbmdNZWRpYVNpbmtzX1BhcmFtcy5lbmNvZGUgPSBmdW5jdGlvbihlbmNvZGVyLCB2YWwpIHsKICAgIHZhciBwYWNrZWQ7CiAgICBlbmNvZGVyLndyaXRlVWludDMyKE1lZGlhUm91dGVQcm92aWRlcl9TdG9wT2JzZXJ2aW5nTWVkaWFTaW5rc19QYXJhbXMuZW5jb2RlZFNpemUpOwogICAgZW5jb2Rlci53cml0ZVVpbnQzMigwKTsKICAgIGVuY29kZXIuZW5jb2RlU3RydWN0KGNvZGVjLlN0cmluZywgdmFsLm1lZGlhU291cmNlKTsKICB9OwogIGZ1bmN0aW9uIE1lZGlhUm91dGVQcm92aWRlcl9TdGFydE9ic2VydmluZ01lZGlhUm91dGVzX1BhcmFtcyh2YWx1ZXMpIHsKICAgIHRoaXMuaW5pdERlZmF1bHRzXygpOwogICAgdGhpcy5pbml0RmllbGRzXyh2YWx1ZXMpOwogIH0KCgogIE1lZGlhUm91dGVQcm92aWRlcl9TdGFydE9ic2VydmluZ01lZGlhUm91dGVzX1BhcmFtcy5wcm90b3R5cGUuaW5pdERlZmF1bHRzXyA9IGZ1bmN0aW9uKCkgewogICAgdGhpcy5tZWRpYVNvdXJjZSA9IG51bGw7CiAgfTsKICBNZWRpYVJvdXRlUHJvdmlkZXJfU3RhcnRPYnNlcnZpbmdNZWRpYVJvdXRlc19QYXJhbXMucHJvdG90eXBlLmluaXRGaWVsZHNfID0gZnVuY3Rpb24oZmllbGRzKSB7CiAgICBmb3IodmFyIGZpZWxkIGluIGZpZWxkcykgewogICAgICAgIGlmICh0aGlzLmhhc093blByb3BlcnR5KGZpZWxkKSkKICAgICAgICAgIHRoaXNbZmllbGRdID0gZmllbGRzW2ZpZWxkXTsKICAgIH0KICB9OwoKICBNZWRpYVJvdXRlUHJvdmlkZXJfU3RhcnRPYnNlcnZpbmdNZWRpYVJvdXRlc19QYXJhbXMudmFsaWRhdGUgPSBmdW5jdGlvbihtZXNzYWdlVmFsaWRhdG9yLCBvZmZzZXQpIHsKICAgIHZhciBlcnI7CiAgICBlcnIgPSBtZXNzYWdlVmFsaWRhdG9yLnZhbGlkYXRlU3RydWN0SGVhZGVyKG9mZnNldCwgY29kZWMua1N0cnVjdEhlYWRlclNpemUpOwogICAgaWYgKGVyciAhPT0gdmFsaWRhdG9yLnZhbGlkYXRpb25FcnJvci5OT05FKQogICAgICAgIHJldHVybiBlcnI7CgogICAgdmFyIGtWZXJzaW9uU2l6ZXMgPSBbCiAgICAgIHt2ZXJzaW9uOiAwLCBudW1CeXRlczogMTZ9CiAgICBdOwogICAgZXJyID0gbWVzc2FnZVZhbGlkYXRvci52YWxpZGF0ZVN0cnVjdFZlcnNpb24ob2Zmc2V0LCBrVmVyc2lvblNpemVzKTsKICAgIGlmIChlcnIgIT09IHZhbGlkYXRvci52YWxpZGF0aW9uRXJyb3IuTk9ORSkKICAgICAgICByZXR1cm4gZXJyOwoKCiAgICAvLyB2YWxpZGF0ZSBNZWRpYVJvdXRlUHJvdmlkZXJfU3RhcnRPYnNlcnZpbmdNZWRpYVJvdXRlc19QYXJhbXMubWVkaWFTb3VyY2UKICAgIGVyciA9IG1lc3NhZ2VWYWxpZGF0b3IudmFsaWRhdGVTdHJpbmdQb2ludGVyKG9mZnNldCArIGNvZGVjLmtTdHJ1Y3RIZWFkZXJTaXplICsgMCwgZmFsc2UpCiAgICBpZiAoZXJyICE9PSB2YWxpZGF0b3IudmFsaWRhdGlvbkVycm9yLk5PTkUpCiAgICAgICAgcmV0dXJuIGVycjsKCiAgICByZXR1cm4gdmFsaWRhdG9yLnZhbGlkYXRpb25FcnJvci5OT05FOwogIH07CgogIE1lZGlhUm91dGVQcm92aWRlcl9TdGFydE9ic2VydmluZ01lZGlhUm91dGVzX1BhcmFtcy5lbmNvZGVkU2l6ZSA9IGNvZGVjLmtTdHJ1Y3RIZWFkZXJTaXplICsgODsKCiAgTWVkaWFSb3V0ZVByb3ZpZGVyX1N0YXJ0T2JzZXJ2aW5nTWVkaWFSb3V0ZXNfUGFyYW1zLmRlY29kZSA9IGZ1bmN0aW9uKGRlY29kZXIpIHsKICAgIHZhciBwYWNrZWQ7CiAgICB2YXIgdmFsID0gbmV3IE1lZGlhUm91dGVQcm92aWRlcl9TdGFydE9ic2VydmluZ01lZGlhUm91dGVzX1BhcmFtcygpOwogICAgdmFyIG51bWJlck9mQnl0ZXMgPSBkZWNvZGVyLnJlYWRVaW50MzIoKTsKICAgIHZhciB2ZXJzaW9uID0gZGVjb2Rlci5yZWFkVWludDMyKCk7CiAgICB2YWwubWVkaWFTb3VyY2UgPSBkZWNvZGVyLmRlY29kZVN0cnVjdChjb2RlYy5TdHJpbmcpOwogICAgcmV0dXJuIHZhbDsKICB9OwoKICBNZWRpYVJvdXRlUHJvdmlkZXJfU3RhcnRPYnNlcnZpbmdNZWRpYVJvdXRlc19QYXJhbXMuZW5jb2RlID0gZnVuY3Rpb24oZW5jb2RlciwgdmFsKSB7CiAgICB2YXIgcGFja2VkOwogICAgZW5jb2Rlci53cml0ZVVpbnQzMihNZWRpYVJvdXRlUHJvdmlkZXJfU3RhcnRPYnNlcnZpbmdNZWRpYVJvdXRlc19QYXJhbXMuZW5jb2RlZFNpemUpOwogICAgZW5jb2Rlci53cml0ZVVpbnQzMigwKTsKICAgIGVuY29kZXIuZW5jb2RlU3RydWN0KGNvZGVjLlN0cmluZywgdmFsLm1lZGlhU291cmNlKTsKICB9OwogIGZ1bmN0aW9uIE1lZGlhUm91dGVQcm92aWRlcl9TdG9wT2JzZXJ2aW5nTWVkaWFSb3V0ZXNfUGFyYW1zKHZhbHVlcykgewogICAgdGhpcy5pbml0RGVmYXVsdHNfKCk7CiAgICB0aGlzLmluaXRGaWVsZHNfKHZhbHVlcyk7CiAgfQoKCiAgTWVkaWFSb3V0ZVByb3ZpZGVyX1N0b3BPYnNlcnZpbmdNZWRpYVJvdXRlc19QYXJhbXMucHJvdG90eXBlLmluaXREZWZhdWx0c18gPSBmdW5jdGlvbigpIHsKICAgIHRoaXMubWVkaWFTb3VyY2UgPSBudWxsOwogIH07CiAgTWVkaWFSb3V0ZVByb3ZpZGVyX1N0b3BPYnNlcnZpbmdNZWRpYVJvdXRlc19QYXJhbXMucHJvdG90eXBlLmluaXRGaWVsZHNfID0gZnVuY3Rpb24oZmllbGRzKSB7CiAgICBmb3IodmFyIGZpZWxkIGluIGZpZWxkcykgewogICAgICAgIGlmICh0aGlzLmhhc093blByb3BlcnR5KGZpZWxkKSkKICAgICAgICAgIHRoaXNbZmllbGRdID0gZmllbGRzW2ZpZWxkXTsKICAgIH0KICB9OwoKICBNZWRpYVJvdXRlUHJvdmlkZXJfU3RvcE9ic2VydmluZ01lZGlhUm91dGVzX1BhcmFtcy52YWxpZGF0ZSA9IGZ1bmN0aW9uKG1lc3NhZ2VWYWxpZGF0b3IsIG9mZnNldCkgewogICAgdmFyIGVycjsKICAgIGVyciA9IG1lc3NhZ2VWYWxpZGF0b3IudmFsaWRhdGVTdHJ1Y3RIZWFkZXIob2Zmc2V0LCBjb2RlYy5rU3RydWN0SGVhZGVyU2l6ZSk7CiAgICBpZiAoZXJyICE9PSB2YWxpZGF0b3IudmFsaWRhdGlvbkVycm9yLk5PTkUpCiAgICAgICAgcmV0dXJuIGVycjsKCiAgICB2YXIga1ZlcnNpb25TaXplcyA9IFsKICAgICAge3ZlcnNpb246IDAsIG51bUJ5dGVzOiAxNn0KICAgIF07CiAgICBlcnIgPSBtZXNzYWdlVmFsaWRhdG9yLnZhbGlkYXRlU3RydWN0VmVyc2lvbihvZmZzZXQsIGtWZXJzaW9uU2l6ZXMpOwogICAgaWYgKGVyciAhPT0gdmFsaWRhdG9yLnZhbGlkYXRpb25FcnJvci5OT05FKQogICAgICAgIHJldHVybiBlcnI7CgoKICAgIC8vIHZhbGlkYXRlIE1lZGlhUm91dGVQcm92aWRlcl9TdG9wT2JzZXJ2aW5nTWVkaWFSb3V0ZXNfUGFyYW1zLm1lZGlhU291cmNlCiAgICBlcnIgPSBtZXNzYWdlVmFsaWRhdG9yLnZhbGlkYXRlU3RyaW5nUG9pbnRlcihvZmZzZXQgKyBjb2RlYy5rU3RydWN0SGVhZGVyU2l6ZSArIDAsIGZhbHNlKQogICAgaWYgKGVyciAhPT0gdmFsaWRhdG9yLnZhbGlkYXRpb25FcnJvci5OT05FKQogICAgICAgIHJldHVybiBlcnI7CgogICAgcmV0dXJuIHZhbGlkYXRvci52YWxpZGF0aW9uRXJyb3IuTk9ORTsKICB9OwoKICBNZWRpYVJvdXRlUHJvdmlkZXJfU3RvcE9ic2VydmluZ01lZGlhUm91dGVzX1BhcmFtcy5lbmNvZGVkU2l6ZSA9IGNvZGVjLmtTdHJ1Y3RIZWFkZXJTaXplICsgODsKCiAgTWVkaWFSb3V0ZVByb3ZpZGVyX1N0b3BPYnNlcnZpbmdNZWRpYVJvdXRlc19QYXJhbXMuZGVjb2RlID0gZnVuY3Rpb24oZGVjb2RlcikgewogICAgdmFyIHBhY2tlZDsKICAgIHZhciB2YWwgPSBuZXcgTWVkaWFSb3V0ZVByb3ZpZGVyX1N0b3BPYnNlcnZpbmdNZWRpYVJvdXRlc19QYXJhbXMoKTsKICAgIHZhciBudW1iZXJPZkJ5dGVzID0gZGVjb2Rlci5yZWFkVWludDMyKCk7CiAgICB2YXIgdmVyc2lvbiA9IGRlY29kZXIucmVhZFVpbnQzMigpOwogICAgdmFsLm1lZGlhU291cmNlID0gZGVjb2Rlci5kZWNvZGVTdHJ1Y3QoY29kZWMuU3RyaW5nKTsKICAgIHJldHVybiB2YWw7CiAgfTsKCiAgTWVkaWFSb3V0ZVByb3ZpZGVyX1N0b3BPYnNlcnZpbmdNZWRpYVJvdXRlc19QYXJhbXMuZW5jb2RlID0gZnVuY3Rpb24oZW5jb2RlciwgdmFsKSB7CiAgICB2YXIgcGFja2VkOwogICAgZW5jb2Rlci53cml0ZVVpbnQzMihNZWRpYVJvdXRlUHJvdmlkZXJfU3RvcE9ic2VydmluZ01lZGlhUm91dGVzX1BhcmFtcy5lbmNvZGVkU2l6ZSk7CiAgICBlbmNvZGVyLndyaXRlVWludDMyKDApOwogICAgZW5jb2Rlci5lbmNvZGVTdHJ1Y3QoY29kZWMuU3RyaW5nLCB2YWwubWVkaWFTb3VyY2UpOwogIH07CiAgZnVuY3Rpb24gTWVkaWFSb3V0ZVByb3ZpZGVyX1N0YXJ0TGlzdGVuaW5nRm9yUm91dGVNZXNzYWdlc19QYXJhbXModmFsdWVzKSB7CiAgICB0aGlzLmluaXREZWZhdWx0c18oKTsKICAgIHRoaXMuaW5pdEZpZWxkc18odmFsdWVzKTsKICB9CgoKICBNZWRpYVJvdXRlUHJvdmlkZXJfU3RhcnRMaXN0ZW5pbmdGb3JSb3V0ZU1lc3NhZ2VzX1BhcmFtcy5wcm90b3R5cGUuaW5pdERlZmF1bHRzXyA9IGZ1bmN0aW9uKCkgewogICAgdGhpcy5yb3V0ZUlkID0gbnVsbDsKICB9OwogIE1lZGlhUm91dGVQcm92aWRlcl9TdGFydExpc3RlbmluZ0ZvclJvdXRlTWVzc2FnZXNfUGFyYW1zLnByb3RvdHlwZS5pbml0RmllbGRzXyA9IGZ1bmN0aW9uKGZpZWxkcykgewogICAgZm9yKHZhciBmaWVsZCBpbiBmaWVsZHMpIHsKICAgICAgICBpZiAodGhpcy5oYXNPd25Qcm9wZXJ0eShmaWVsZCkpCiAgICAgICAgICB0aGlzW2ZpZWxkXSA9IGZpZWxkc1tmaWVsZF07CiAgICB9CiAgfTsKCiAgTWVkaWFSb3V0ZVByb3ZpZGVyX1N0YXJ0TGlzdGVuaW5nRm9yUm91dGVNZXNzYWdlc19QYXJhbXMudmFsaWRhdGUgPSBmdW5jdGlvbihtZXNzYWdlVmFsaWRhdG9yLCBvZmZzZXQpIHsKICAgIHZhciBlcnI7CiAgICBlcnIgPSBtZXNzYWdlVmFsaWRhdG9yLnZhbGlkYXRlU3RydWN0SGVhZGVyKG9mZnNldCwgY29kZWMua1N0cnVjdEhlYWRlclNpemUpOwogICAgaWYgKGVyciAhPT0gdmFsaWRhdG9yLnZhbGlkYXRpb25FcnJvci5OT05FKQogICAgICAgIHJldHVybiBlcnI7CgogICAgdmFyIGtWZXJzaW9uU2l6ZXMgPSBbCiAgICAgIHt2ZXJzaW9uOiAwLCBudW1CeXRlczogMTZ9CiAgICBdOwogICAgZXJyID0gbWVzc2FnZVZhbGlkYXRvci52YWxpZGF0ZVN0cnVjdFZlcnNpb24ob2Zmc2V0LCBrVmVyc2lvblNpemVzKTsKICAgIGlmIChlcnIgIT09IHZhbGlkYXRvci52YWxpZGF0aW9uRXJyb3IuTk9ORSkKICAgICAgICByZXR1cm4gZXJyOwoKCiAgICAvLyB2YWxpZGF0ZSBNZWRpYVJvdXRlUHJvdmlkZXJfU3RhcnRMaXN0ZW5pbmdGb3JSb3V0ZU1lc3NhZ2VzX1BhcmFtcy5yb3V0ZUlkCiAgICBlcnIgPSBtZXNzYWdlVmFsaWRhdG9yLnZhbGlkYXRlU3RyaW5nUG9pbnRlcihvZmZzZXQgKyBjb2RlYy5rU3RydWN0SGVhZGVyU2l6ZSArIDAsIGZhbHNlKQogICAgaWYgKGVyciAhPT0gdmFsaWRhdG9yLnZhbGlkYXRpb25FcnJvci5OT05FKQogICAgICAgIHJldHVybiBlcnI7CgogICAgcmV0dXJuIHZhbGlkYXRvci52YWxpZGF0aW9uRXJyb3IuTk9ORTsKICB9OwoKICBNZWRpYVJvdXRlUHJvdmlkZXJfU3RhcnRMaXN0ZW5pbmdGb3JSb3V0ZU1lc3NhZ2VzX1BhcmFtcy5lbmNvZGVkU2l6ZSA9IGNvZGVjLmtTdHJ1Y3RIZWFkZXJTaXplICsgODsKCiAgTWVkaWFSb3V0ZVByb3ZpZGVyX1N0YXJ0TGlzdGVuaW5nRm9yUm91dGVNZXNzYWdlc19QYXJhbXMuZGVjb2RlID0gZnVuY3Rpb24oZGVjb2RlcikgewogICAgdmFyIHBhY2tlZDsKICAgIHZhciB2YWwgPSBuZXcgTWVkaWFSb3V0ZVByb3ZpZGVyX1N0YXJ0TGlzdGVuaW5nRm9yUm91dGVNZXNzYWdlc19QYXJhbXMoKTsKICAgIHZhciBudW1iZXJPZkJ5dGVzID0gZGVjb2Rlci5yZWFkVWludDMyKCk7CiAgICB2YXIgdmVyc2lvbiA9IGRlY29kZXIucmVhZFVpbnQzMigpOwogICAgdmFsLnJvdXRlSWQgPSBkZWNvZGVyLmRlY29kZVN0cnVjdChjb2RlYy5TdHJpbmcpOwogICAgcmV0dXJuIHZhbDsKICB9OwoKICBNZWRpYVJvdXRlUHJvdmlkZXJfU3RhcnRMaXN0ZW5pbmdGb3JSb3V0ZU1lc3NhZ2VzX1BhcmFtcy5lbmNvZGUgPSBmdW5jdGlvbihlbmNvZGVyLCB2YWwpIHsKICAgIHZhciBwYWNrZWQ7CiAgICBlbmNvZGVyLndyaXRlVWludDMyKE1lZGlhUm91dGVQcm92aWRlcl9TdGFydExpc3RlbmluZ0ZvclJvdXRlTWVzc2FnZXNfUGFyYW1zLmVuY29kZWRTaXplKTsKICAgIGVuY29kZXIud3JpdGVVaW50MzIoMCk7CiAgICBlbmNvZGVyLmVuY29kZVN0cnVjdChjb2RlYy5TdHJpbmcsIHZhbC5yb3V0ZUlkKTsKICB9OwogIGZ1bmN0aW9uIE1lZGlhUm91dGVQcm92aWRlcl9TdG9wTGlzdGVuaW5nRm9yUm91dGVNZXNzYWdlc19QYXJhbXModmFsdWVzKSB7CiAgICB0aGlzLmluaXREZWZhdWx0c18oKTsKICAgIHRoaXMuaW5pdEZpZWxkc18odmFsdWVzKTsKICB9CgoKICBNZWRpYVJvdXRlUHJvdmlkZXJfU3RvcExpc3RlbmluZ0ZvclJvdXRlTWVzc2FnZXNfUGFyYW1zLnByb3RvdHlwZS5pbml0RGVmYXVsdHNfID0gZnVuY3Rpb24oKSB7CiAgICB0aGlzLnJvdXRlSWQgPSBudWxsOwogIH07CiAgTWVkaWFSb3V0ZVByb3ZpZGVyX1N0b3BMaXN0ZW5pbmdGb3JSb3V0ZU1lc3NhZ2VzX1BhcmFtcy5wcm90b3R5cGUuaW5pdEZpZWxkc18gPSBmdW5jdGlvbihmaWVsZHMpIHsKICAgIGZvcih2YXIgZmllbGQgaW4gZmllbGRzKSB7CiAgICAgICAgaWYgKHRoaXMuaGFzT3duUHJvcGVydHkoZmllbGQpKQogICAgICAgICAgdGhpc1tmaWVsZF0gPSBmaWVsZHNbZmllbGRdOwogICAgfQogIH07CgogIE1lZGlhUm91dGVQcm92aWRlcl9TdG9wTGlzdGVuaW5nRm9yUm91dGVNZXNzYWdlc19QYXJhbXMudmFsaWRhdGUgPSBmdW5jdGlvbihtZXNzYWdlVmFsaWRhdG9yLCBvZmZzZXQpIHsKICAgIHZhciBlcnI7CiAgICBlcnIgPSBtZXNzYWdlVmFsaWRhdG9yLnZhbGlkYXRlU3RydWN0SGVhZGVyKG9mZnNldCwgY29kZWMua1N0cnVjdEhlYWRlclNpemUpOwogICAgaWYgKGVyciAhPT0gdmFsaWRhdG9yLnZhbGlkYXRpb25FcnJvci5OT05FKQogICAgICAgIHJldHVybiBlcnI7CgogICAgdmFyIGtWZXJzaW9uU2l6ZXMgPSBbCiAgICAgIHt2ZXJzaW9uOiAwLCBudW1CeXRlczogMTZ9CiAgICBdOwogICAgZXJyID0gbWVzc2FnZVZhbGlkYXRvci52YWxpZGF0ZVN0cnVjdFZlcnNpb24ob2Zmc2V0LCBrVmVyc2lvblNpemVzKTsKICAgIGlmIChlcnIgIT09IHZhbGlkYXRvci52YWxpZGF0aW9uRXJyb3IuTk9ORSkKICAgICAgICByZXR1cm4gZXJyOwoKCiAgICAvLyB2YWxpZGF0ZSBNZWRpYVJvdXRlUHJvdmlkZXJfU3RvcExpc3RlbmluZ0ZvclJvdXRlTWVzc2FnZXNfUGFyYW1zLnJvdXRlSWQKICAgIGVyciA9IG1lc3NhZ2VWYWxpZGF0b3IudmFsaWRhdGVTdHJpbmdQb2ludGVyKG9mZnNldCArIGNvZGVjLmtTdHJ1Y3RIZWFkZXJTaXplICsgMCwgZmFsc2UpCiAgICBpZiAoZXJyICE9PSB2YWxpZGF0b3IudmFsaWRhdGlvbkVycm9yLk5PTkUpCiAgICAgICAgcmV0dXJuIGVycjsKCiAgICByZXR1cm4gdmFsaWRhdG9yLnZhbGlkYXRpb25FcnJvci5OT05FOwogIH07CgogIE1lZGlhUm91dGVQcm92aWRlcl9TdG9wTGlzdGVuaW5nRm9yUm91dGVNZXNzYWdlc19QYXJhbXMuZW5jb2RlZFNpemUgPSBjb2RlYy5rU3RydWN0SGVhZGVyU2l6ZSArIDg7CgogIE1lZGlhUm91dGVQcm92aWRlcl9TdG9wTGlzdGVuaW5nRm9yUm91dGVNZXNzYWdlc19QYXJhbXMuZGVjb2RlID0gZnVuY3Rpb24oZGVjb2RlcikgewogICAgdmFyIHBhY2tlZDsKICAgIHZhciB2YWwgPSBuZXcgTWVkaWFSb3V0ZVByb3ZpZGVyX1N0b3BMaXN0ZW5pbmdGb3JSb3V0ZU1lc3NhZ2VzX1BhcmFtcygpOwogICAgdmFyIG51bWJlck9mQnl0ZXMgPSBkZWNvZGVyLnJlYWRVaW50MzIoKTsKICAgIHZhciB2ZXJzaW9uID0gZGVjb2Rlci5yZWFkVWludDMyKCk7CiAgICB2YWwucm91dGVJZCA9IGRlY29kZXIuZGVjb2RlU3RydWN0KGNvZGVjLlN0cmluZyk7CiAgICByZXR1cm4gdmFsOwogIH07CgogIE1lZGlhUm91dGVQcm92aWRlcl9TdG9wTGlzdGVuaW5nRm9yUm91dGVNZXNzYWdlc19QYXJhbXMuZW5jb2RlID0gZnVuY3Rpb24oZW5jb2RlciwgdmFsKSB7CiAgICB2YXIgcGFja2VkOwogICAgZW5jb2Rlci53cml0ZVVpbnQzMihNZWRpYVJvdXRlUHJvdmlkZXJfU3RvcExpc3RlbmluZ0ZvclJvdXRlTWVzc2FnZXNfUGFyYW1zLmVuY29kZWRTaXplKTsKICAgIGVuY29kZXIud3JpdGVVaW50MzIoMCk7CiAgICBlbmNvZGVyLmVuY29kZVN0cnVjdChjb2RlYy5TdHJpbmcsIHZhbC5yb3V0ZUlkKTsKICB9OwogIGZ1bmN0aW9uIE1lZGlhUm91dGVQcm92aWRlcl9EZXRhY2hSb3V0ZV9QYXJhbXModmFsdWVzKSB7CiAgICB0aGlzLmluaXREZWZhdWx0c18oKTsKICAgIHRoaXMuaW5pdEZpZWxkc18odmFsdWVzKTsKICB9CgoKICBNZWRpYVJvdXRlUHJvdmlkZXJfRGV0YWNoUm91dGVfUGFyYW1zLnByb3RvdHlwZS5pbml0RGVmYXVsdHNfID0gZnVuY3Rpb24oKSB7CiAgICB0aGlzLnJvdXRlSWQgPSBudWxsOwogIH07CiAgTWVkaWFSb3V0ZVByb3ZpZGVyX0RldGFjaFJvdXRlX1BhcmFtcy5wcm90b3R5cGUuaW5pdEZpZWxkc18gPSBmdW5jdGlvbihmaWVsZHMpIHsKICAgIGZvcih2YXIgZmllbGQgaW4gZmllbGRzKSB7CiAgICAgICAgaWYgKHRoaXMuaGFzT3duUHJvcGVydHkoZmllbGQpKQogICAgICAgICAgdGhpc1tmaWVsZF0gPSBmaWVsZHNbZmllbGRdOwogICAgfQogIH07CgogIE1lZGlhUm91dGVQcm92aWRlcl9EZXRhY2hSb3V0ZV9QYXJhbXMudmFsaWRhdGUgPSBmdW5jdGlvbihtZXNzYWdlVmFsaWRhdG9yLCBvZmZzZXQpIHsKICAgIHZhciBlcnI7CiAgICBlcnIgPSBtZXNzYWdlVmFsaWRhdG9yLnZhbGlkYXRlU3RydWN0SGVhZGVyKG9mZnNldCwgY29kZWMua1N0cnVjdEhlYWRlclNpemUpOwogICAgaWYgKGVyciAhPT0gdmFsaWRhdG9yLnZhbGlkYXRpb25FcnJvci5OT05FKQogICAgICAgIHJldHVybiBlcnI7CgogICAgdmFyIGtWZXJzaW9uU2l6ZXMgPSBbCiAgICAgIHt2ZXJzaW9uOiAwLCBudW1CeXRlczogMTZ9CiAgICBdOwogICAgZXJyID0gbWVzc2FnZVZhbGlkYXRvci52YWxpZGF0ZVN0cnVjdFZlcnNpb24ob2Zmc2V0LCBrVmVyc2lvblNpemVzKTsKICAgIGlmIChlcnIgIT09IHZhbGlkYXRvci52YWxpZGF0aW9uRXJyb3IuTk9ORSkKICAgICAgICByZXR1cm4gZXJyOwoKCiAgICAvLyB2YWxpZGF0ZSBNZWRpYVJvdXRlUHJvdmlkZXJfRGV0YWNoUm91dGVfUGFyYW1zLnJvdXRlSWQKICAgIGVyciA9IG1lc3NhZ2VWYWxpZGF0b3IudmFsaWRhdGVTdHJpbmdQb2ludGVyKG9mZnNldCArIGNvZGVjLmtTdHJ1Y3RIZWFkZXJTaXplICsgMCwgZmFsc2UpCiAgICBpZiAoZXJyICE9PSB2YWxpZGF0b3IudmFsaWRhdGlvbkVycm9yLk5PTkUpCiAgICAgICAgcmV0dXJuIGVycjsKCiAgICByZXR1cm4gdmFsaWRhdG9yLnZhbGlkYXRpb25FcnJvci5OT05FOwogIH07CgogIE1lZGlhUm91dGVQcm92aWRlcl9EZXRhY2hSb3V0ZV9QYXJhbXMuZW5jb2RlZFNpemUgPSBjb2RlYy5rU3RydWN0SGVhZGVyU2l6ZSArIDg7CgogIE1lZGlhUm91dGVQcm92aWRlcl9EZXRhY2hSb3V0ZV9QYXJhbXMuZGVjb2RlID0gZnVuY3Rpb24oZGVjb2RlcikgewogICAgdmFyIHBhY2tlZDsKICAgIHZhciB2YWwgPSBuZXcgTWVkaWFSb3V0ZVByb3ZpZGVyX0RldGFjaFJvdXRlX1BhcmFtcygpOwogICAgdmFyIG51bWJlck9mQnl0ZXMgPSBkZWNvZGVyLnJlYWRVaW50MzIoKTsKICAgIHZhciB2ZXJzaW9uID0gZGVjb2Rlci5yZWFkVWludDMyKCk7CiAgICB2YWwucm91dGVJZCA9IGRlY29kZXIuZGVjb2RlU3RydWN0KGNvZGVjLlN0cmluZyk7CiAgICByZXR1cm4gdmFsOwogIH07CgogIE1lZGlhUm91dGVQcm92aWRlcl9EZXRhY2hSb3V0ZV9QYXJhbXMuZW5jb2RlID0gZnVuY3Rpb24oZW5jb2RlciwgdmFsKSB7CiAgICB2YXIgcGFja2VkOwogICAgZW5jb2Rlci53cml0ZVVpbnQzMihNZWRpYVJvdXRlUHJvdmlkZXJfRGV0YWNoUm91dGVfUGFyYW1zLmVuY29kZWRTaXplKTsKICAgIGVuY29kZXIud3JpdGVVaW50MzIoMCk7CiAgICBlbmNvZGVyLmVuY29kZVN0cnVjdChjb2RlYy5TdHJpbmcsIHZhbC5yb3V0ZUlkKTsKICB9OwogIGZ1bmN0aW9uIE1lZGlhUm91dGVQcm92aWRlcl9FbmFibGVNZG5zRGlzY292ZXJ5X1BhcmFtcyh2YWx1ZXMpIHsKICAgIHRoaXMuaW5pdERlZmF1bHRzXygpOwogICAgdGhpcy5pbml0RmllbGRzXyh2YWx1ZXMpOwogIH0KCgogIE1lZGlhUm91dGVQcm92aWRlcl9FbmFibGVNZG5zRGlzY292ZXJ5X1BhcmFtcy5wcm90b3R5cGUuaW5pdERlZmF1bHRzXyA9IGZ1bmN0aW9uKCkgewogIH07CiAgTWVkaWFSb3V0ZVByb3ZpZGVyX0VuYWJsZU1kbnNEaXNjb3ZlcnlfUGFyYW1zLnByb3RvdHlwZS5pbml0RmllbGRzXyA9IGZ1bmN0aW9uKGZpZWxkcykgewogICAgZm9yKHZhciBmaWVsZCBpbiBmaWVsZHMpIHsKICAgICAgICBpZiAodGhpcy5oYXNPd25Qcm9wZXJ0eShmaWVsZCkpCiAgICAgICAgICB0aGlzW2ZpZWxkXSA9IGZpZWxkc1tmaWVsZF07CiAgICB9CiAgfTsKCiAgTWVkaWFSb3V0ZVByb3ZpZGVyX0VuYWJsZU1kbnNEaXNjb3ZlcnlfUGFyYW1zLnZhbGlkYXRlID0gZnVuY3Rpb24obWVzc2FnZVZhbGlkYXRvciwgb2Zmc2V0KSB7CiAgICB2YXIgZXJyOwogICAgZXJyID0gbWVzc2FnZVZhbGlkYXRvci52YWxpZGF0ZVN0cnVjdEhlYWRlcihvZmZzZXQsIGNvZGVjLmtTdHJ1Y3RIZWFkZXJTaXplKTsKICAgIGlmIChlcnIgIT09IHZhbGlkYXRvci52YWxpZGF0aW9uRXJyb3IuTk9ORSkKICAgICAgICByZXR1cm4gZXJyOwoKICAgIHZhciBrVmVyc2lvblNpemVzID0gWwogICAgICB7dmVyc2lvbjogMCwgbnVtQnl0ZXM6IDh9CiAgICBdOwogICAgZXJyID0gbWVzc2FnZVZhbGlkYXRvci52YWxpZGF0ZVN0cnVjdFZlcnNpb24ob2Zmc2V0LCBrVmVyc2lvblNpemVzKTsKICAgIGlmIChlcnIgIT09IHZhbGlkYXRvci52YWxpZGF0aW9uRXJyb3IuTk9ORSkKICAgICAgICByZXR1cm4gZXJyOwoKICAgIHJldHVybiB2YWxpZGF0b3IudmFsaWRhdGlvbkVycm9yLk5PTkU7CiAgfTsKCiAgTWVkaWFSb3V0ZVByb3ZpZGVyX0VuYWJsZU1kbnNEaXNjb3ZlcnlfUGFyYW1zLmVuY29kZWRTaXplID0gY29kZWMua1N0cnVjdEhlYWRlclNpemUgKyAwOwoKICBNZWRpYVJvdXRlUHJvdmlkZXJfRW5hYmxlTWRuc0Rpc2NvdmVyeV9QYXJhbXMuZGVjb2RlID0gZnVuY3Rpb24oZGVjb2RlcikgewogICAgdmFyIHBhY2tlZDsKICAgIHZhciB2YWwgPSBuZXcgTWVkaWFSb3V0ZVByb3ZpZGVyX0VuYWJsZU1kbnNEaXNjb3ZlcnlfUGFyYW1zKCk7CiAgICB2YXIgbnVtYmVyT2ZCeXRlcyA9IGRlY29kZXIucmVhZFVpbnQzMigpOwogICAgdmFyIHZlcnNpb24gPSBkZWNvZGVyLnJlYWRVaW50MzIoKTsKICAgIHJldHVybiB2YWw7CiAgfTsKCiAgTWVkaWFSb3V0ZVByb3ZpZGVyX0VuYWJsZU1kbnNEaXNjb3ZlcnlfUGFyYW1zLmVuY29kZSA9IGZ1bmN0aW9uKGVuY29kZXIsIHZhbCkgewogICAgdmFyIHBhY2tlZDsKICAgIGVuY29kZXIud3JpdGVVaW50MzIoTWVkaWFSb3V0ZVByb3ZpZGVyX0VuYWJsZU1kbnNEaXNjb3ZlcnlfUGFyYW1zLmVuY29kZWRTaXplKTsKICAgIGVuY29kZXIud3JpdGVVaW50MzIoMCk7CiAgfTsKICBmdW5jdGlvbiBNZWRpYVJvdXRlUHJvdmlkZXJfVXBkYXRlTWVkaWFTaW5rc19QYXJhbXModmFsdWVzKSB7CiAgICB0aGlzLmluaXREZWZhdWx0c18oKTsKICAgIHRoaXMuaW5pdEZpZWxkc18odmFsdWVzKTsKICB9CgoKICBNZWRpYVJvdXRlUHJvdmlkZXJfVXBkYXRlTWVkaWFTaW5rc19QYXJhbXMucHJvdG90eXBlLmluaXREZWZhdWx0c18gPSBmdW5jdGlvbigpIHsKICAgIHRoaXMubWVkaWFTb3VyY2UgPSBudWxsOwogIH07CiAgTWVkaWFSb3V0ZVByb3ZpZGVyX1VwZGF0ZU1lZGlhU2lua3NfUGFyYW1zLnByb3RvdHlwZS5pbml0RmllbGRzXyA9IGZ1bmN0aW9uKGZpZWxkcykgewogICAgZm9yKHZhciBmaWVsZCBpbiBmaWVsZHMpIHsKICAgICAgICBpZiAodGhpcy5oYXNPd25Qcm9wZXJ0eShmaWVsZCkpCiAgICAgICAgICB0aGlzW2ZpZWxkXSA9IGZpZWxkc1tmaWVsZF07CiAgICB9CiAgfTsKCiAgTWVkaWFSb3V0ZVByb3ZpZGVyX1VwZGF0ZU1lZGlhU2lua3NfUGFyYW1zLnZhbGlkYXRlID0gZnVuY3Rpb24obWVzc2FnZVZhbGlkYXRvciwgb2Zmc2V0KSB7CiAgICB2YXIgZXJyOwogICAgZXJyID0gbWVzc2FnZVZhbGlkYXRvci52YWxpZGF0ZVN0cnVjdEhlYWRlcihvZmZzZXQsIGNvZGVjLmtTdHJ1Y3RIZWFkZXJTaXplKTsKICAgIGlmIChlcnIgIT09IHZhbGlkYXRvci52YWxpZGF0aW9uRXJyb3IuTk9ORSkKICAgICAgICByZXR1cm4gZXJyOwoKICAgIHZhciBrVmVyc2lvblNpemVzID0gWwogICAgICB7dmVyc2lvbjogMCwgbnVtQnl0ZXM6IDE2fQogICAgXTsKICAgIGVyciA9IG1lc3NhZ2VWYWxpZGF0b3IudmFsaWRhdGVTdHJ1Y3RWZXJzaW9uKG9mZnNldCwga1ZlcnNpb25TaXplcyk7CiAgICBpZiAoZXJyICE9PSB2YWxpZGF0b3IudmFsaWRhdGlvbkVycm9yLk5PTkUpCiAgICAgICAgcmV0dXJuIGVycjsKCgogICAgLy8gdmFsaWRhdGUgTWVkaWFSb3V0ZVByb3ZpZGVyX1VwZGF0ZU1lZGlhU2lua3NfUGFyYW1zLm1lZGlhU291cmNlCiAgICBlcnIgPSBtZXNzYWdlVmFsaWRhdG9yLnZhbGlkYXRlU3RyaW5nUG9pbnRlcihvZmZzZXQgKyBjb2RlYy5rU3RydWN0SGVhZGVyU2l6ZSArIDAsIGZhbHNlKQogICAgaWYgKGVyciAhPT0gdmFsaWRhdG9yLnZhbGlkYXRpb25FcnJvci5OT05FKQogICAgICAgIHJldHVybiBlcnI7CgogICAgcmV0dXJuIHZhbGlkYXRvci52YWxpZGF0aW9uRXJyb3IuTk9ORTsKICB9OwoKICBNZWRpYVJvdXRlUHJvdmlkZXJfVXBkYXRlTWVkaWFTaW5rc19QYXJhbXMuZW5jb2RlZFNpemUgPSBjb2RlYy5rU3RydWN0SGVhZGVyU2l6ZSArIDg7CgogIE1lZGlhUm91dGVQcm92aWRlcl9VcGRhdGVNZWRpYVNpbmtzX1BhcmFtcy5kZWNvZGUgPSBmdW5jdGlvbihkZWNvZGVyKSB7CiAgICB2YXIgcGFja2VkOwogICAgdmFyIHZhbCA9IG5ldyBNZWRpYVJvdXRlUHJvdmlkZXJfVXBkYXRlTWVkaWFTaW5rc19QYXJhbXMoKTsKICAgIHZhciBudW1iZXJPZkJ5dGVzID0gZGVjb2Rlci5yZWFkVWludDMyKCk7CiAgICB2YXIgdmVyc2lvbiA9IGRlY29kZXIucmVhZFVpbnQzMigpOwogICAgdmFsLm1lZGlhU291cmNlID0gZGVjb2Rlci5kZWNvZGVTdHJ1Y3QoY29kZWMuU3RyaW5nKTsKICAgIHJldHVybiB2YWw7CiAgfTsKCiAgTWVkaWFSb3V0ZVByb3ZpZGVyX1VwZGF0ZU1lZGlhU2lua3NfUGFyYW1zLmVuY29kZSA9IGZ1bmN0aW9uKGVuY29kZXIsIHZhbCkgewogICAgdmFyIHBhY2tlZDsKICAgIGVuY29kZXIud3JpdGVVaW50MzIoTWVkaWFSb3V0ZVByb3ZpZGVyX1VwZGF0ZU1lZGlhU2lua3NfUGFyYW1zLmVuY29kZWRTaXplKTsKICAgIGVuY29kZXIud3JpdGVVaW50MzIoMCk7CiAgICBlbmNvZGVyLmVuY29kZVN0cnVjdChjb2RlYy5TdHJpbmcsIHZhbC5tZWRpYVNvdXJjZSk7CiAgfTsKICBmdW5jdGlvbiBNZWRpYVJvdXRlUHJvdmlkZXJfU2VhcmNoU2lua3NfUGFyYW1zKHZhbHVlcykgewogICAgdGhpcy5pbml0RGVmYXVsdHNfKCk7CiAgICB0aGlzLmluaXRGaWVsZHNfKHZhbHVlcyk7CiAgfQoKCiAgTWVkaWFSb3V0ZVByb3ZpZGVyX1NlYXJjaFNpbmtzX1BhcmFtcy5wcm90b3R5cGUuaW5pdERlZmF1bHRzXyA9IGZ1bmN0aW9uKCkgewogICAgdGhpcy5zaW5rSWQgPSBudWxsOwogICAgdGhpcy5tZWRpYVNvdXJjZSA9IG51bGw7CiAgICB0aGlzLnNlYXJjaENyaXRlcmlhID0gbnVsbDsKICB9OwogIE1lZGlhUm91dGVQcm92aWRlcl9TZWFyY2hTaW5rc19QYXJhbXMucHJvdG90eXBlLmluaXRGaWVsZHNfID0gZnVuY3Rpb24oZmllbGRzKSB7CiAgICBmb3IodmFyIGZpZWxkIGluIGZpZWxkcykgewogICAgICAgIGlmICh0aGlzLmhhc093blByb3BlcnR5KGZpZWxkKSkKICAgICAgICAgIHRoaXNbZmllbGRdID0gZmllbGRzW2ZpZWxkXTsKICAgIH0KICB9OwoKICBNZWRpYVJvdXRlUHJvdmlkZXJfU2VhcmNoU2lua3NfUGFyYW1zLnZhbGlkYXRlID0gZnVuY3Rpb24obWVzc2FnZVZhbGlkYXRvciwgb2Zmc2V0KSB7CiAgICB2YXIgZXJyOwogICAgZXJyID0gbWVzc2FnZVZhbGlkYXRvci52YWxpZGF0ZVN0cnVjdEhlYWRlcihvZmZzZXQsIGNvZGVjLmtTdHJ1Y3RIZWFkZXJTaXplKTsKICAgIGlmIChlcnIgIT09IHZhbGlkYXRvci52YWxpZGF0aW9uRXJyb3IuTk9ORSkKICAgICAgICByZXR1cm4gZXJyOwoKICAgIHZhciBrVmVyc2lvblNpemVzID0gWwogICAgICB7dmVyc2lvbjogMCwgbnVtQnl0ZXM6IDMyfQogICAgXTsKICAgIGVyciA9IG1lc3NhZ2VWYWxpZGF0b3IudmFsaWRhdGVTdHJ1Y3RWZXJzaW9uKG9mZnNldCwga1ZlcnNpb25TaXplcyk7CiAgICBpZiAoZXJyICE9PSB2YWxpZGF0b3IudmFsaWRhdGlvbkVycm9yLk5PTkUpCiAgICAgICAgcmV0dXJuIGVycjsKCgogICAgLy8gdmFsaWRhdGUgTWVkaWFSb3V0ZVByb3ZpZGVyX1NlYXJjaFNpbmtzX1BhcmFtcy5zaW5rSWQKICAgIGVyciA9IG1lc3NhZ2VWYWxpZGF0b3IudmFsaWRhdGVTdHJpbmdQb2ludGVyKG9mZnNldCArIGNvZGVjLmtTdHJ1Y3RIZWFkZXJTaXplICsgMCwgZmFsc2UpCiAgICBpZiAoZXJyICE9PSB2YWxpZGF0b3IudmFsaWRhdGlvbkVycm9yLk5PTkUpCiAgICAgICAgcmV0dXJuIGVycjsKCgogICAgLy8gdmFsaWRhdGUgTWVkaWFSb3V0ZVByb3ZpZGVyX1NlYXJjaFNpbmtzX1BhcmFtcy5tZWRpYVNvdXJjZQogICAgZXJyID0gbWVzc2FnZVZhbGlkYXRvci52YWxpZGF0ZVN0cmluZ1BvaW50ZXIob2Zmc2V0ICsgY29kZWMua1N0cnVjdEhlYWRlclNpemUgKyA4LCBmYWxzZSkKICAgIGlmIChlcnIgIT09IHZhbGlkYXRvci52YWxpZGF0aW9uRXJyb3IuTk9ORSkKICAgICAgICByZXR1cm4gZXJyOwoKCiAgICAvLyB2YWxpZGF0ZSBNZWRpYVJvdXRlUHJvdmlkZXJfU2VhcmNoU2lua3NfUGFyYW1zLnNlYXJjaENyaXRlcmlhCiAgICBlcnIgPSBtZXNzYWdlVmFsaWRhdG9yLnZhbGlkYXRlU3RydWN0UG9pbnRlcihvZmZzZXQgKyBjb2RlYy5rU3RydWN0SGVhZGVyU2l6ZSArIDE2LCBTaW5rU2VhcmNoQ3JpdGVyaWEsIGZhbHNlKTsKICAgIGlmIChlcnIgIT09IHZhbGlkYXRvci52YWxpZGF0aW9uRXJyb3IuTk9ORSkKICAgICAgICByZXR1cm4gZXJyOwoKICAgIHJldHVybiB2YWxpZGF0b3IudmFsaWRhdGlvbkVycm9yLk5PTkU7CiAgfTsKCiAgTWVkaWFSb3V0ZVByb3ZpZGVyX1NlYXJjaFNpbmtzX1BhcmFtcy5lbmNvZGVkU2l6ZSA9IGNvZGVjLmtTdHJ1Y3RIZWFkZXJTaXplICsgMjQ7CgogIE1lZGlhUm91dGVQcm92aWRlcl9TZWFyY2hTaW5rc19QYXJhbXMuZGVjb2RlID0gZnVuY3Rpb24oZGVjb2RlcikgewogICAgdmFyIHBhY2tlZDsKICAgIHZhciB2YWwgPSBuZXcgTWVkaWFSb3V0ZVByb3ZpZGVyX1NlYXJjaFNpbmtzX1BhcmFtcygpOwogICAgdmFyIG51bWJlck9mQnl0ZXMgPSBkZWNvZGVyLnJlYWRVaW50MzIoKTsKICAgIHZhciB2ZXJzaW9uID0gZGVjb2Rlci5yZWFkVWludDMyKCk7CiAgICB2YWwuc2lua0lkID0gZGVjb2Rlci5kZWNvZGVTdHJ1Y3QoY29kZWMuU3RyaW5nKTsKICAgIHZhbC5tZWRpYVNvdXJjZSA9IGRlY29kZXIuZGVjb2RlU3RydWN0KGNvZGVjLlN0cmluZyk7CiAgICB2YWwuc2VhcmNoQ3JpdGVyaWEgPSBkZWNvZGVyLmRlY29kZVN0cnVjdFBvaW50ZXIoU2lua1NlYXJjaENyaXRlcmlhKTsKICAgIHJldHVybiB2YWw7CiAgfTsKCiAgTWVkaWFSb3V0ZVByb3ZpZGVyX1NlYXJjaFNpbmtzX1BhcmFtcy5lbmNvZGUgPSBmdW5jdGlvbihlbmNvZGVyLCB2YWwpIHsKICAgIHZhciBwYWNrZWQ7CiAgICBlbmNvZGVyLndyaXRlVWludDMyKE1lZGlhUm91dGVQcm92aWRlcl9TZWFyY2hTaW5rc19QYXJhbXMuZW5jb2RlZFNpemUpOwogICAgZW5jb2Rlci53cml0ZVVpbnQzMigwKTsKICAgIGVuY29kZXIuZW5jb2RlU3RydWN0KGNvZGVjLlN0cmluZywgdmFsLnNpbmtJZCk7CiAgICBlbmNvZGVyLmVuY29kZVN0cnVjdChjb2RlYy5TdHJpbmcsIHZhbC5tZWRpYVNvdXJjZSk7CiAgICBlbmNvZGVyLmVuY29kZVN0cnVjdFBvaW50ZXIoU2lua1NlYXJjaENyaXRlcmlhLCB2YWwuc2VhcmNoQ3JpdGVyaWEpOwogIH07CiAgZnVuY3Rpb24gTWVkaWFSb3V0ZVByb3ZpZGVyX1NlYXJjaFNpbmtzX1Jlc3BvbnNlUGFyYW1zKHZhbHVlcykgewogICAgdGhpcy5pbml0RGVmYXVsdHNfKCk7CiAgICB0aGlzLmluaXRGaWVsZHNfKHZhbHVlcyk7CiAgfQoKCiAgTWVkaWFSb3V0ZVByb3ZpZGVyX1NlYXJjaFNpbmtzX1Jlc3BvbnNlUGFyYW1zLnByb3RvdHlwZS5pbml0RGVmYXVsdHNfID0gZnVuY3Rpb24oKSB7CiAgICB0aGlzLnNpbmtJZCA9IG51bGw7CiAgfTsKICBNZWRpYVJvdXRlUHJvdmlkZXJfU2VhcmNoU2lua3NfUmVzcG9uc2VQYXJhbXMucHJvdG90eXBlLmluaXRGaWVsZHNfID0gZnVuY3Rpb24oZmllbGRzKSB7CiAgICBmb3IodmFyIGZpZWxkIGluIGZpZWxkcykgewogICAgICAgIGlmICh0aGlzLmhhc093blByb3BlcnR5KGZpZWxkKSkKICAgICAgICAgIHRoaXNbZmllbGRdID0gZmllbGRzW2ZpZWxkXTsKICAgIH0KICB9OwoKICBNZWRpYVJvdXRlUHJvdmlkZXJfU2VhcmNoU2lua3NfUmVzcG9uc2VQYXJhbXMudmFsaWRhdGUgPSBmdW5jdGlvbihtZXNzYWdlVmFsaWRhdG9yLCBvZmZzZXQpIHsKICAgIHZhciBlcnI7CiAgICBlcnIgPSBtZXNzYWdlVmFsaWRhdG9yLnZhbGlkYXRlU3RydWN0SGVhZGVyKG9mZnNldCwgY29kZWMua1N0cnVjdEhlYWRlclNpemUpOwogICAgaWYgKGVyciAhPT0gdmFsaWRhdG9yLnZhbGlkYXRpb25FcnJvci5OT05FKQogICAgICAgIHJldHVybiBlcnI7CgogICAgdmFyIGtWZXJzaW9uU2l6ZXMgPSBbCiAgICAgIHt2ZXJzaW9uOiAwLCBudW1CeXRlczogMTZ9CiAgICBdOwogICAgZXJyID0gbWVzc2FnZVZhbGlkYXRvci52YWxpZGF0ZVN0cnVjdFZlcnNpb24ob2Zmc2V0LCBrVmVyc2lvblNpemVzKTsKICAgIGlmIChlcnIgIT09IHZhbGlkYXRvci52YWxpZGF0aW9uRXJyb3IuTk9ORSkKICAgICAgICByZXR1cm4gZXJyOwoKCiAgICAvLyB2YWxpZGF0ZSBNZWRpYVJvdXRlUHJvdmlkZXJfU2VhcmNoU2lua3NfUmVzcG9uc2VQYXJhbXMuc2lua0lkCiAgICBlcnIgPSBtZXNzYWdlVmFsaWRhdG9yLnZhbGlkYXRlU3RyaW5nUG9pbnRlcihvZmZzZXQgKyBjb2RlYy5rU3RydWN0SGVhZGVyU2l6ZSArIDAsIGZhbHNlKQogICAgaWYgKGVyciAhPT0gdmFsaWRhdG9yLnZhbGlkYXRpb25FcnJvci5OT05FKQogICAgICAgIHJldHVybiBlcnI7CgogICAgcmV0dXJuIHZhbGlkYXRvci52YWxpZGF0aW9uRXJyb3IuTk9ORTsKICB9OwoKICBNZWRpYVJvdXRlUHJvdmlkZXJfU2VhcmNoU2lua3NfUmVzcG9uc2VQYXJhbXMuZW5jb2RlZFNpemUgPSBjb2RlYy5rU3RydWN0SGVhZGVyU2l6ZSArIDg7CgogIE1lZGlhUm91dGVQcm92aWRlcl9TZWFyY2hTaW5rc19SZXNwb25zZVBhcmFtcy5kZWNvZGUgPSBmdW5jdGlvbihkZWNvZGVyKSB7CiAgICB2YXIgcGFja2VkOwogICAgdmFyIHZhbCA9IG5ldyBNZWRpYVJvdXRlUHJvdmlkZXJfU2VhcmNoU2lua3NfUmVzcG9uc2VQYXJhbXMoKTsKICAgIHZhciBudW1iZXJPZkJ5dGVzID0gZGVjb2Rlci5yZWFkVWludDMyKCk7CiAgICB2YXIgdmVyc2lvbiA9IGRlY29kZXIucmVhZFVpbnQzMigpOwogICAgdmFsLnNpbmtJZCA9IGRlY29kZXIuZGVjb2RlU3RydWN0KGNvZGVjLlN0cmluZyk7CiAgICByZXR1cm4gdmFsOwogIH07CgogIE1lZGlhUm91dGVQcm92aWRlcl9TZWFyY2hTaW5rc19SZXNwb25zZVBhcmFtcy5lbmNvZGUgPSBmdW5jdGlvbihlbmNvZGVyLCB2YWwpIHsKICAgIHZhciBwYWNrZWQ7CiAgICBlbmNvZGVyLndyaXRlVWludDMyKE1lZGlhUm91dGVQcm92aWRlcl9TZWFyY2hTaW5rc19SZXNwb25zZVBhcmFtcy5lbmNvZGVkU2l6ZSk7CiAgICBlbmNvZGVyLndyaXRlVWludDMyKDApOwogICAgZW5jb2Rlci5lbmNvZGVTdHJ1Y3QoY29kZWMuU3RyaW5nLCB2YWwuc2lua0lkKTsKICB9OwogIGZ1bmN0aW9uIE1lZGlhUm91dGVQcm92aWRlcl9Qcm92aWRlU2lua3NfUGFyYW1zKHZhbHVlcykgewogICAgdGhpcy5pbml0RGVmYXVsdHNfKCk7CiAgICB0aGlzLmluaXRGaWVsZHNfKHZhbHVlcyk7CiAgfQoKCiAgTWVkaWFSb3V0ZVByb3ZpZGVyX1Byb3ZpZGVTaW5rc19QYXJhbXMucHJvdG90eXBlLmluaXREZWZhdWx0c18gPSBmdW5jdGlvbigpIHsKICAgIHRoaXMucHJvdmlkZXJOYW1lID0gbnVsbDsKICAgIHRoaXMuc2lua3MgPSBudWxsOwogIH07CiAgTWVkaWFSb3V0ZVByb3ZpZGVyX1Byb3ZpZGVTaW5rc19QYXJhbXMucHJvdG90eXBlLmluaXRGaWVsZHNfID0gZnVuY3Rpb24oZmllbGRzKSB7CiAgICBmb3IodmFyIGZpZWxkIGluIGZpZWxkcykgewogICAgICAgIGlmICh0aGlzLmhhc093blByb3BlcnR5KGZpZWxkKSkKICAgICAgICAgIHRoaXNbZmllbGRdID0gZmllbGRzW2ZpZWxkXTsKICAgIH0KICB9OwoKICBNZWRpYVJvdXRlUHJvdmlkZXJfUHJvdmlkZVNpbmtzX1BhcmFtcy52YWxpZGF0ZSA9IGZ1bmN0aW9uKG1lc3NhZ2VWYWxpZGF0b3IsIG9mZnNldCkgewogICAgdmFyIGVycjsKICAgIGVyciA9IG1lc3NhZ2VWYWxpZGF0b3IudmFsaWRhdGVTdHJ1Y3RIZWFkZXIob2Zmc2V0LCBjb2RlYy5rU3RydWN0SGVhZGVyU2l6ZSk7CiAgICBpZiAoZXJyICE9PSB2YWxpZGF0b3IudmFsaWRhdGlvbkVycm9yLk5PTkUpCiAgICAgICAgcmV0dXJuIGVycjsKCiAgICB2YXIga1ZlcnNpb25TaXplcyA9IFsKICAgICAge3ZlcnNpb246IDAsIG51bUJ5dGVzOiAyNH0KICAgIF07CiAgICBlcnIgPSBtZXNzYWdlVmFsaWRhdG9yLnZhbGlkYXRlU3RydWN0VmVyc2lvbihvZmZzZXQsIGtWZXJzaW9uU2l6ZXMpOwogICAgaWYgKGVyciAhPT0gdmFsaWRhdG9yLnZhbGlkYXRpb25FcnJvci5OT05FKQogICAgICAgIHJldHVybiBlcnI7CgoKICAgIC8vIHZhbGlkYXRlIE1lZGlhUm91dGVQcm92aWRlcl9Qcm92aWRlU2lua3NfUGFyYW1zLnByb3ZpZGVyTmFtZQogICAgZXJyID0gbWVzc2FnZVZhbGlkYXRvci52YWxpZGF0ZVN0cmluZ1BvaW50ZXIob2Zmc2V0ICsgY29kZWMua1N0cnVjdEhlYWRlclNpemUgKyAwLCBmYWxzZSkKICAgIGlmIChlcnIgIT09IHZhbGlkYXRvci52YWxpZGF0aW9uRXJyb3IuTk9ORSkKICAgICAgICByZXR1cm4gZXJyOwoKCiAgICAvLyB2YWxpZGF0ZSBNZWRpYVJvdXRlUHJvdmlkZXJfUHJvdmlkZVNpbmtzX1BhcmFtcy5zaW5rcwogICAgZXJyID0gbWVzc2FnZVZhbGlkYXRvci52YWxpZGF0ZUFycmF5UG9pbnRlcihvZmZzZXQgKyBjb2RlYy5rU3RydWN0SGVhZGVyU2l6ZSArIDgsIDgsIG5ldyBjb2RlYy5Qb2ludGVyVG8oTWVkaWFTaW5rKSwgZmFsc2UsIFswXSwgMCk7CiAgICBpZiAoZXJyICE9PSB2YWxpZGF0b3IudmFsaWRhdGlvbkVycm9yLk5PTkUpCiAgICAgICAgcmV0dXJuIGVycjsKCiAgICByZXR1cm4gdmFsaWRhdG9yLnZhbGlkYXRpb25FcnJvci5OT05FOwogIH07CgogIE1lZGlhUm91dGVQcm92aWRlcl9Qcm92aWRlU2lua3NfUGFyYW1zLmVuY29kZWRTaXplID0gY29kZWMua1N0cnVjdEhlYWRlclNpemUgKyAxNjsKCiAgTWVkaWFSb3V0ZVByb3ZpZGVyX1Byb3ZpZGVTaW5rc19QYXJhbXMuZGVjb2RlID0gZnVuY3Rpb24oZGVjb2RlcikgewogICAgdmFyIHBhY2tlZDsKICAgIHZhciB2YWwgPSBuZXcgTWVkaWFSb3V0ZVByb3ZpZGVyX1Byb3ZpZGVTaW5rc19QYXJhbXMoKTsKICAgIHZhciBudW1iZXJPZkJ5dGVzID0gZGVjb2Rlci5yZWFkVWludDMyKCk7CiAgICB2YXIgdmVyc2lvbiA9IGRlY29kZXIucmVhZFVpbnQzMigpOwogICAgdmFsLnByb3ZpZGVyTmFtZSA9IGRlY29kZXIuZGVjb2RlU3RydWN0KGNvZGVjLlN0cmluZyk7CiAgICB2YWwuc2lua3MgPSBkZWNvZGVyLmRlY29kZUFycmF5UG9pbnRlcihuZXcgY29kZWMuUG9pbnRlclRvKE1lZGlhU2luaykpOwogICAgcmV0dXJuIHZhbDsKICB9OwoKICBNZWRpYVJvdXRlUHJvdmlkZXJfUHJvdmlkZVNpbmtzX1BhcmFtcy5lbmNvZGUgPSBmdW5jdGlvbihlbmNvZGVyLCB2YWwpIHsKICAgIHZhciBwYWNrZWQ7CiAgICBlbmNvZGVyLndyaXRlVWludDMyKE1lZGlhUm91dGVQcm92aWRlcl9Qcm92aWRlU2lua3NfUGFyYW1zLmVuY29kZWRTaXplKTsKICAgIGVuY29kZXIud3JpdGVVaW50MzIoMCk7CiAgICBlbmNvZGVyLmVuY29kZVN0cnVjdChjb2RlYy5TdHJpbmcsIHZhbC5wcm92aWRlck5hbWUpOwogICAgZW5jb2Rlci5lbmNvZGVBcnJheVBvaW50ZXIobmV3IGNvZGVjLlBvaW50ZXJUbyhNZWRpYVNpbmspLCB2YWwuc2lua3MpOwogIH07CiAgZnVuY3Rpb24gTWVkaWFSb3V0ZVByb3ZpZGVyX0NyZWF0ZU1lZGlhUm91dGVDb250cm9sbGVyX1BhcmFtcyh2YWx1ZXMpIHsKICAgIHRoaXMuaW5pdERlZmF1bHRzXygpOwogICAgdGhpcy5pbml0RmllbGRzXyh2YWx1ZXMpOwogIH0KCgogIE1lZGlhUm91dGVQcm92aWRlcl9DcmVhdGVNZWRpYVJvdXRlQ29udHJvbGxlcl9QYXJhbXMucHJvdG90eXBlLmluaXREZWZhdWx0c18gPSBmdW5jdGlvbigpIHsKICAgIHRoaXMucm91dGVJZCA9IG51bGw7CiAgICB0aGlzLm1lZGlhQ29udHJvbGxlciA9IG5ldyBiaW5kaW5ncy5JbnRlcmZhY2VSZXF1ZXN0KCk7CiAgICB0aGlzLm9ic2VydmVyID0gbmV3IG1lZGlhX3N0YXR1cyQuTWVkaWFTdGF0dXNPYnNlcnZlclB0cigpOwogIH07CiAgTWVkaWFSb3V0ZVByb3ZpZGVyX0NyZWF0ZU1lZGlhUm91dGVDb250cm9sbGVyX1BhcmFtcy5wcm90b3R5cGUuaW5pdEZpZWxkc18gPSBmdW5jdGlvbihmaWVsZHMpIHsKICAgIGZvcih2YXIgZmllbGQgaW4gZmllbGRzKSB7CiAgICAgICAgaWYgKHRoaXMuaGFzT3duUHJvcGVydHkoZmllbGQpKQogICAgICAgICAgdGhpc1tmaWVsZF0gPSBmaWVsZHNbZmllbGRdOwogICAgfQogIH07CgogIE1lZGlhUm91dGVQcm92aWRlcl9DcmVhdGVNZWRpYVJvdXRlQ29udHJvbGxlcl9QYXJhbXMudmFsaWRhdGUgPSBmdW5jdGlvbihtZXNzYWdlVmFsaWRhdG9yLCBvZmZzZXQpIHsKICAgIHZhciBlcnI7CiAgICBlcnIgPSBtZXNzYWdlVmFsaWRhdG9yLnZhbGlkYXRlU3RydWN0SGVhZGVyKG9mZnNldCwgY29kZWMua1N0cnVjdEhlYWRlclNpemUpOwogICAgaWYgKGVyciAhPT0gdmFsaWRhdG9yLnZhbGlkYXRpb25FcnJvci5OT05FKQogICAgICAgIHJldHVybiBlcnI7CgogICAgdmFyIGtWZXJzaW9uU2l6ZXMgPSBbCiAgICAgIHt2ZXJzaW9uOiAwLCBudW1CeXRlczogMzJ9CiAgICBdOwogICAgZXJyID0gbWVzc2FnZVZhbGlkYXRvci52YWxpZGF0ZVN0cnVjdFZlcnNpb24ob2Zmc2V0LCBrVmVyc2lvblNpemVzKTsKICAgIGlmIChlcnIgIT09IHZhbGlkYXRvci52YWxpZGF0aW9uRXJyb3IuTk9ORSkKICAgICAgICByZXR1cm4gZXJyOwoKCiAgICAvLyB2YWxpZGF0ZSBNZWRpYVJvdXRlUHJvdmlkZXJfQ3JlYXRlTWVkaWFSb3V0ZUNvbnRyb2xsZXJfUGFyYW1zLnJvdXRlSWQKICAgIGVyciA9IG1lc3NhZ2VWYWxpZGF0b3IudmFsaWRhdGVTdHJpbmdQb2ludGVyKG9mZnNldCArIGNvZGVjLmtTdHJ1Y3RIZWFkZXJTaXplICsgMCwgZmFsc2UpCiAgICBpZiAoZXJyICE9PSB2YWxpZGF0b3IudmFsaWRhdGlvbkVycm9yLk5PTkUpCiAgICAgICAgcmV0dXJuIGVycjsKCgogICAgLy8gdmFsaWRhdGUgTWVkaWFSb3V0ZVByb3ZpZGVyX0NyZWF0ZU1lZGlhUm91dGVDb250cm9sbGVyX1BhcmFtcy5tZWRpYUNvbnRyb2xsZXIKICAgIGVyciA9IG1lc3NhZ2VWYWxpZGF0b3IudmFsaWRhdGVJbnRlcmZhY2VSZXF1ZXN0KG9mZnNldCArIGNvZGVjLmtTdHJ1Y3RIZWFkZXJTaXplICsgOCwgZmFsc2UpCiAgICBpZiAoZXJyICE9PSB2YWxpZGF0b3IudmFsaWRhdGlvbkVycm9yLk5PTkUpCiAgICAgICAgcmV0dXJuIGVycjsKCgogICAgLy8gdmFsaWRhdGUgTWVkaWFSb3V0ZVByb3ZpZGVyX0NyZWF0ZU1lZGlhUm91dGVDb250cm9sbGVyX1BhcmFtcy5vYnNlcnZlcgogICAgZXJyID0gbWVzc2FnZVZhbGlkYXRvci52YWxpZGF0ZUludGVyZmFjZShvZmZzZXQgKyBjb2RlYy5rU3RydWN0SGVhZGVyU2l6ZSArIDEyLCBmYWxzZSk7CiAgICBpZiAoZXJyICE9PSB2YWxpZGF0b3IudmFsaWRhdGlvbkVycm9yLk5PTkUpCiAgICAgICAgcmV0dXJuIGVycjsKCiAgICByZXR1cm4gdmFsaWRhdG9yLnZhbGlkYXRpb25FcnJvci5OT05FOwogIH07CgogIE1lZGlhUm91dGVQcm92aWRlcl9DcmVhdGVNZWRpYVJvdXRlQ29udHJvbGxlcl9QYXJhbXMuZW5jb2RlZFNpemUgPSBjb2RlYy5rU3RydWN0SGVhZGVyU2l6ZSArIDI0OwoKICBNZWRpYVJvdXRlUHJvdmlkZXJfQ3JlYXRlTWVkaWFSb3V0ZUNvbnRyb2xsZXJfUGFyYW1zLmRlY29kZSA9IGZ1bmN0aW9uKGRlY29kZXIpIHsKICAgIHZhciBwYWNrZWQ7CiAgICB2YXIgdmFsID0gbmV3IE1lZGlhUm91dGVQcm92aWRlcl9DcmVhdGVNZWRpYVJvdXRlQ29udHJvbGxlcl9QYXJhbXMoKTsKICAgIHZhciBudW1iZXJPZkJ5dGVzID0gZGVjb2Rlci5yZWFkVWludDMyKCk7CiAgICB2YXIgdmVyc2lvbiA9IGRlY29kZXIucmVhZFVpbnQzMigpOwogICAgdmFsLnJvdXRlSWQgPSBkZWNvZGVyLmRlY29kZVN0cnVjdChjb2RlYy5TdHJpbmcpOwogICAgdmFsLm1lZGlhQ29udHJvbGxlciA9IGRlY29kZXIuZGVjb2RlU3RydWN0KGNvZGVjLkludGVyZmFjZVJlcXVlc3QpOwogICAgdmFsLm9ic2VydmVyID0gZGVjb2Rlci5kZWNvZGVTdHJ1Y3QobmV3IGNvZGVjLkludGVyZmFjZShtZWRpYV9zdGF0dXMkLk1lZGlhU3RhdHVzT2JzZXJ2ZXJQdHIpKTsKICAgIGRlY29kZXIuc2tpcCgxKTsKICAgIGRlY29kZXIuc2tpcCgxKTsKICAgIGRlY29kZXIuc2tpcCgxKTsKICAgIGRlY29kZXIuc2tpcCgxKTsKICAgIHJldHVybiB2YWw7CiAgfTsKCiAgTWVkaWFSb3V0ZVByb3ZpZGVyX0NyZWF0ZU1lZGlhUm91dGVDb250cm9sbGVyX1BhcmFtcy5lbmNvZGUgPSBmdW5jdGlvbihlbmNvZGVyLCB2YWwpIHsKICAgIHZhciBwYWNrZWQ7CiAgICBlbmNvZGVyLndyaXRlVWludDMyKE1lZGlhUm91dGVQcm92aWRlcl9DcmVhdGVNZWRpYVJvdXRlQ29udHJvbGxlcl9QYXJhbXMuZW5jb2RlZFNpemUpOwogICAgZW5jb2Rlci53cml0ZVVpbnQzMigwKTsKICAgIGVuY29kZXIuZW5jb2RlU3RydWN0KGNvZGVjLlN0cmluZywgdmFsLnJvdXRlSWQpOwogICAgZW5jb2Rlci5lbmNvZGVTdHJ1Y3QoY29kZWMuSW50ZXJmYWNlUmVxdWVzdCwgdmFsLm1lZGlhQ29udHJvbGxlcik7CiAgICBlbmNvZGVyLmVuY29kZVN0cnVjdChuZXcgY29kZWMuSW50ZXJmYWNlKG1lZGlhX3N0YXR1cyQuTWVkaWFTdGF0dXNPYnNlcnZlclB0ciksIHZhbC5vYnNlcnZlcik7CiAgICBlbmNvZGVyLnNraXAoMSk7CiAgICBlbmNvZGVyLnNraXAoMSk7CiAgICBlbmNvZGVyLnNraXAoMSk7CiAgICBlbmNvZGVyLnNraXAoMSk7CiAgfTsKICBmdW5jdGlvbiBNZWRpYVJvdXRlUHJvdmlkZXJfQ3JlYXRlTWVkaWFSb3V0ZUNvbnRyb2xsZXJfUmVzcG9uc2VQYXJhbXModmFsdWVzKSB7CiAgICB0aGlzLmluaXREZWZhdWx0c18oKTsKICAgIHRoaXMuaW5pdEZpZWxkc18odmFsdWVzKTsKICB9CgoKICBNZWRpYVJvdXRlUHJvdmlkZXJfQ3JlYXRlTWVkaWFSb3V0ZUNvbnRyb2xsZXJfUmVzcG9uc2VQYXJhbXMucHJvdG90eXBlLmluaXREZWZhdWx0c18gPSBmdW5jdGlvbigpIHsKICAgIHRoaXMuc3VjY2VzcyA9IGZhbHNlOwogIH07CiAgTWVkaWFSb3V0ZVByb3ZpZGVyX0NyZWF0ZU1lZGlhUm91dGVDb250cm9sbGVyX1Jlc3BvbnNlUGFyYW1zLnByb3RvdHlwZS5pbml0RmllbGRzXyA9IGZ1bmN0aW9uKGZpZWxkcykgewogICAgZm9yKHZhciBmaWVsZCBpbiBmaWVsZHMpIHsKICAgICAgICBpZiAodGhpcy5oYXNPd25Qcm9wZXJ0eShmaWVsZCkpCiAgICAgICAgICB0aGlzW2ZpZWxkXSA9IGZpZWxkc1tmaWVsZF07CiAgICB9CiAgfTsKCiAgTWVkaWFSb3V0ZVByb3ZpZGVyX0NyZWF0ZU1lZGlhUm91dGVDb250cm9sbGVyX1Jlc3BvbnNlUGFyYW1zLnZhbGlkYXRlID0gZnVuY3Rpb24obWVzc2FnZVZhbGlkYXRvciwgb2Zmc2V0KSB7CiAgICB2YXIgZXJyOwogICAgZXJyID0gbWVzc2FnZVZhbGlkYXRvci52YWxpZGF0ZVN0cnVjdEhlYWRlcihvZmZzZXQsIGNvZGVjLmtTdHJ1Y3RIZWFkZXJTaXplKTsKICAgIGlmIChlcnIgIT09IHZhbGlkYXRvci52YWxpZGF0aW9uRXJyb3IuTk9ORSkKICAgICAgICByZXR1cm4gZXJyOwoKICAgIHZhciBrVmVyc2lvblNpemVzID0gWwogICAgICB7dmVyc2lvbjogMCwgbnVtQnl0ZXM6IDE2fQogICAgXTsKICAgIGVyciA9IG1lc3NhZ2VWYWxpZGF0b3IudmFsaWRhdGVTdHJ1Y3RWZXJzaW9uKG9mZnNldCwga1ZlcnNpb25TaXplcyk7CiAgICBpZiAoZXJyICE9PSB2YWxpZGF0b3IudmFsaWRhdGlvbkVycm9yLk5PTkUpCiAgICAgICAgcmV0dXJuIGVycjsKCgogICAgcmV0dXJuIHZhbGlkYXRvci52YWxpZGF0aW9uRXJyb3IuTk9ORTsKICB9OwoKICBNZWRpYVJvdXRlUHJvdmlkZXJfQ3JlYXRlTWVkaWFSb3V0ZUNvbnRyb2xsZXJfUmVzcG9uc2VQYXJhbXMuZW5jb2RlZFNpemUgPSBjb2RlYy5rU3RydWN0SGVhZGVyU2l6ZSArIDg7CgogIE1lZGlhUm91dGVQcm92aWRlcl9DcmVhdGVNZWRpYVJvdXRlQ29udHJvbGxlcl9SZXNwb25zZVBhcmFtcy5kZWNvZGUgPSBmdW5jdGlvbihkZWNvZGVyKSB7CiAgICB2YXIgcGFja2VkOwogICAgdmFyIHZhbCA9IG5ldyBNZWRpYVJvdXRlUHJvdmlkZXJfQ3JlYXRlTWVkaWFSb3V0ZUNvbnRyb2xsZXJfUmVzcG9uc2VQYXJhbXMoKTsKICAgIHZhciBudW1iZXJPZkJ5dGVzID0gZGVjb2Rlci5yZWFkVWludDMyKCk7CiAgICB2YXIgdmVyc2lvbiA9IGRlY29kZXIucmVhZFVpbnQzMigpOwogICAgcGFja2VkID0gZGVjb2Rlci5yZWFkVWludDgoKTsKICAgIHZhbC5zdWNjZXNzID0gKHBhY2tlZCA+PiAwKSAmIDEgPyB0cnVlIDogZmFsc2U7CiAgICBkZWNvZGVyLnNraXAoMSk7CiAgICBkZWNvZGVyLnNraXAoMSk7CiAgICBkZWNvZGVyLnNraXAoMSk7CiAgICBkZWNvZGVyLnNraXAoMSk7CiAgICBkZWNvZGVyLnNraXAoMSk7CiAgICBkZWNvZGVyLnNraXAoMSk7CiAgICBkZWNvZGVyLnNraXAoMSk7CiAgICByZXR1cm4gdmFsOwogIH07CgogIE1lZGlhUm91dGVQcm92aWRlcl9DcmVhdGVNZWRpYVJvdXRlQ29udHJvbGxlcl9SZXNwb25zZVBhcmFtcy5lbmNvZGUgPSBmdW5jdGlvbihlbmNvZGVyLCB2YWwpIHsKICAgIHZhciBwYWNrZWQ7CiAgICBlbmNvZGVyLndyaXRlVWludDMyKE1lZGlhUm91dGVQcm92aWRlcl9DcmVhdGVNZWRpYVJvdXRlQ29udHJvbGxlcl9SZXNwb25zZVBhcmFtcy5lbmNvZGVkU2l6ZSk7CiAgICBlbmNvZGVyLndyaXRlVWludDMyKDApOwogICAgcGFja2VkID0gMDsKICAgIHBhY2tlZCB8PSAodmFsLnN1Y2Nlc3MgJiAxKSA8PCAwCiAgICBlbmNvZGVyLndyaXRlVWludDgocGFja2VkKTsKICAgIGVuY29kZXIuc2tpcCgxKTsKICAgIGVuY29kZXIuc2tpcCgxKTsKICAgIGVuY29kZXIuc2tpcCgxKTsKICAgIGVuY29kZXIuc2tpcCgxKTsKICAgIGVuY29kZXIuc2tpcCgxKTsKICAgIGVuY29kZXIuc2tpcCgxKTsKICAgIGVuY29kZXIuc2tpcCgxKTsKICB9OwogIGZ1bmN0aW9uIE1lZGlhUm91dGVyX1JlZ2lzdGVyTWVkaWFSb3V0ZVByb3ZpZGVyX1BhcmFtcyh2YWx1ZXMpIHsKICAgIHRoaXMuaW5pdERlZmF1bHRzXygpOwogICAgdGhpcy5pbml0RmllbGRzXyh2YWx1ZXMpOwogIH0KCgogIE1lZGlhUm91dGVyX1JlZ2lzdGVyTWVkaWFSb3V0ZVByb3ZpZGVyX1BhcmFtcy5wcm90b3R5cGUuaW5pdERlZmF1bHRzXyA9IGZ1bmN0aW9uKCkgewogICAgdGhpcy5wcm92aWRlcklkID0gMDsKICAgIHRoaXMubWVkaWFSb3V0ZXJQcm92aWRlciA9IG5ldyBNZWRpYVJvdXRlUHJvdmlkZXJQdHIoKTsKICB9OwogIE1lZGlhUm91dGVyX1JlZ2lzdGVyTWVkaWFSb3V0ZVByb3ZpZGVyX1BhcmFtcy5wcm90b3R5cGUuaW5pdEZpZWxkc18gPSBmdW5jdGlvbihmaWVsZHMpIHsKICAgIGZvcih2YXIgZmllbGQgaW4gZmllbGRzKSB7CiAgICAgICAgaWYgKHRoaXMuaGFzT3duUHJvcGVydHkoZmllbGQpKQogICAgICAgICAgdGhpc1tmaWVsZF0gPSBmaWVsZHNbZmllbGRdOwogICAgfQogIH07CgogIE1lZGlhUm91dGVyX1JlZ2lzdGVyTWVkaWFSb3V0ZVByb3ZpZGVyX1BhcmFtcy52YWxpZGF0ZSA9IGZ1bmN0aW9uKG1lc3NhZ2VWYWxpZGF0b3IsIG9mZnNldCkgewogICAgdmFyIGVycjsKICAgIGVyciA9IG1lc3NhZ2VWYWxpZGF0b3IudmFsaWRhdGVTdHJ1Y3RIZWFkZXIob2Zmc2V0LCBjb2RlYy5rU3RydWN0SGVhZGVyU2l6ZSk7CiAgICBpZiAoZXJyICE9PSB2YWxpZGF0b3IudmFsaWRhdGlvbkVycm9yLk5PTkUpCiAgICAgICAgcmV0dXJuIGVycjsKCiAgICB2YXIga1ZlcnNpb25TaXplcyA9IFsKICAgICAge3ZlcnNpb246IDAsIG51bUJ5dGVzOiAyNH0KICAgIF07CiAgICBlcnIgPSBtZXNzYWdlVmFsaWRhdG9yLnZhbGlkYXRlU3RydWN0VmVyc2lvbihvZmZzZXQsIGtWZXJzaW9uU2l6ZXMpOwogICAgaWYgKGVyciAhPT0gdmFsaWRhdG9yLnZhbGlkYXRpb25FcnJvci5OT05FKQogICAgICAgIHJldHVybiBlcnI7CgoKICAgIC8vIHZhbGlkYXRlIE1lZGlhUm91dGVyX1JlZ2lzdGVyTWVkaWFSb3V0ZVByb3ZpZGVyX1BhcmFtcy5wcm92aWRlcklkCiAgICBlcnIgPSBtZXNzYWdlVmFsaWRhdG9yLnZhbGlkYXRlRW51bShvZmZzZXQgKyBjb2RlYy5rU3RydWN0SGVhZGVyU2l6ZSArIDAsIE1lZGlhUm91dGVQcm92aWRlci5JZCk7CiAgICBpZiAoZXJyICE9PSB2YWxpZGF0b3IudmFsaWRhdGlvbkVycm9yLk5PTkUpCiAgICAgICAgcmV0dXJuIGVycjsKCgogICAgLy8gdmFsaWRhdGUgTWVkaWFSb3V0ZXJfUmVnaXN0ZXJNZWRpYVJvdXRlUHJvdmlkZXJfUGFyYW1zLm1lZGlhUm91dGVyUHJvdmlkZXIKICAgIGVyciA9IG1lc3NhZ2VWYWxpZGF0b3IudmFsaWRhdGVJbnRlcmZhY2Uob2Zmc2V0ICsgY29kZWMua1N0cnVjdEhlYWRlclNpemUgKyA0LCBmYWxzZSk7CiAgICBpZiAoZXJyICE9PSB2YWxpZGF0b3IudmFsaWRhdGlvbkVycm9yLk5PTkUpCiAgICAgICAgcmV0dXJuIGVycjsKCiAgICByZXR1cm4gdmFsaWRhdG9yLnZhbGlkYXRpb25FcnJvci5OT05FOwogIH07CgogIE1lZGlhUm91dGVyX1JlZ2lzdGVyTWVkaWFSb3V0ZVByb3ZpZGVyX1BhcmFtcy5lbmNvZGVkU2l6ZSA9IGNvZGVjLmtTdHJ1Y3RIZWFkZXJTaXplICsgMTY7CgogIE1lZGlhUm91dGVyX1JlZ2lzdGVyTWVkaWFSb3V0ZVByb3ZpZGVyX1BhcmFtcy5kZWNvZGUgPSBmdW5jdGlvbihkZWNvZGVyKSB7CiAgICB2YXIgcGFja2VkOwogICAgdmFyIHZhbCA9IG5ldyBNZWRpYVJvdXRlcl9SZWdpc3Rlck1lZGlhUm91dGVQcm92aWRlcl9QYXJhbXMoKTsKICAgIHZhciBudW1iZXJPZkJ5dGVzID0gZGVjb2Rlci5yZWFkVWludDMyKCk7CiAgICB2YXIgdmVyc2lvbiA9IGRlY29kZXIucmVhZFVpbnQzMigpOwogICAgdmFsLnByb3ZpZGVySWQgPSBkZWNvZGVyLmRlY29kZVN0cnVjdChjb2RlYy5JbnQzMik7CiAgICB2YWwubWVkaWFSb3V0ZXJQcm92aWRlciA9IGRlY29kZXIuZGVjb2RlU3RydWN0KG5ldyBjb2RlYy5JbnRlcmZhY2UoTWVkaWFSb3V0ZVByb3ZpZGVyUHRyKSk7CiAgICBkZWNvZGVyLnNraXAoMSk7CiAgICBkZWNvZGVyLnNraXAoMSk7CiAgICBkZWNvZGVyLnNraXAoMSk7CiAgICBkZWNvZGVyLnNraXAoMSk7CiAgICByZXR1cm4gdmFsOwogIH07CgogIE1lZGlhUm91dGVyX1JlZ2lzdGVyTWVkaWFSb3V0ZVByb3ZpZGVyX1BhcmFtcy5lbmNvZGUgPSBmdW5jdGlvbihlbmNvZGVyLCB2YWwpIHsKICAgIHZhciBwYWNrZWQ7CiAgICBlbmNvZGVyLndyaXRlVWludDMyKE1lZGlhUm91dGVyX1JlZ2lzdGVyTWVkaWFSb3V0ZVByb3ZpZGVyX1BhcmFtcy5lbmNvZGVkU2l6ZSk7CiAgICBlbmNvZGVyLndyaXRlVWludDMyKDApOwogICAgZW5jb2Rlci5lbmNvZGVTdHJ1Y3QoY29kZWMuSW50MzIsIHZhbC5wcm92aWRlcklkKTsKICAgIGVuY29kZXIuZW5jb2RlU3RydWN0KG5ldyBjb2RlYy5JbnRlcmZhY2UoTWVkaWFSb3V0ZVByb3ZpZGVyUHRyKSwgdmFsLm1lZGlhUm91dGVyUHJvdmlkZXIpOwogICAgZW5jb2Rlci5za2lwKDEpOwogICAgZW5jb2Rlci5za2lwKDEpOwogICAgZW5jb2Rlci5za2lwKDEpOwogICAgZW5jb2Rlci5za2lwKDEpOwogIH07CiAgZnVuY3Rpb24gTWVkaWFSb3V0ZXJfUmVnaXN0ZXJNZWRpYVJvdXRlUHJvdmlkZXJfUmVzcG9uc2VQYXJhbXModmFsdWVzKSB7CiAgICB0aGlzLmluaXREZWZhdWx0c18oKTsKICAgIHRoaXMuaW5pdEZpZWxkc18odmFsdWVzKTsKICB9CgoKICBNZWRpYVJvdXRlcl9SZWdpc3Rlck1lZGlhUm91dGVQcm92aWRlcl9SZXNwb25zZVBhcmFtcy5wcm90b3R5cGUuaW5pdERlZmF1bHRzXyA9IGZ1bmN0aW9uKCkgewogICAgdGhpcy5pbnN0YW5jZUlkID0gbnVsbDsKICAgIHRoaXMuY29uZmlnID0gbnVsbDsKICB9OwogIE1lZGlhUm91dGVyX1JlZ2lzdGVyTWVkaWFSb3V0ZVByb3ZpZGVyX1Jlc3BvbnNlUGFyYW1zLnByb3RvdHlwZS5pbml0RmllbGRzXyA9IGZ1bmN0aW9uKGZpZWxkcykgewogICAgZm9yKHZhciBmaWVsZCBpbiBmaWVsZHMpIHsKICAgICAgICBpZiAodGhpcy5oYXNPd25Qcm9wZXJ0eShmaWVsZCkpCiAgICAgICAgICB0aGlzW2ZpZWxkXSA9IGZpZWxkc1tmaWVsZF07CiAgICB9CiAgfTsKCiAgTWVkaWFSb3V0ZXJfUmVnaXN0ZXJNZWRpYVJvdXRlUHJvdmlkZXJfUmVzcG9uc2VQYXJhbXMudmFsaWRhdGUgPSBmdW5jdGlvbihtZXNzYWdlVmFsaWRhdG9yLCBvZmZzZXQpIHsKICAgIHZhciBlcnI7CiAgICBlcnIgPSBtZXNzYWdlVmFsaWRhdG9yLnZhbGlkYXRlU3RydWN0SGVhZGVyKG9mZnNldCwgY29kZWMua1N0cnVjdEhlYWRlclNpemUpOwogICAgaWYgKGVyciAhPT0gdmFsaWRhdG9yLnZhbGlkYXRpb25FcnJvci5OT05FKQogICAgICAgIHJldHVybiBlcnI7CgogICAgdmFyIGtWZXJzaW9uU2l6ZXMgPSBbCiAgICAgIHt2ZXJzaW9uOiAwLCBudW1CeXRlczogMjR9CiAgICBdOwogICAgZXJyID0gbWVzc2FnZVZhbGlkYXRvci52YWxpZGF0ZVN0cnVjdFZlcnNpb24ob2Zmc2V0LCBrVmVyc2lvblNpemVzKTsKICAgIGlmIChlcnIgIT09IHZhbGlkYXRvci52YWxpZGF0aW9uRXJyb3IuTk9ORSkKICAgICAgICByZXR1cm4gZXJyOwoKCiAgICAvLyB2YWxpZGF0ZSBNZWRpYVJvdXRlcl9SZWdpc3Rlck1lZGlhUm91dGVQcm92aWRlcl9SZXNwb25zZVBhcmFtcy5pbnN0YW5jZUlkCiAgICBlcnIgPSBtZXNzYWdlVmFsaWRhdG9yLnZhbGlkYXRlU3RyaW5nUG9pbnRlcihvZmZzZXQgKyBjb2RlYy5rU3RydWN0SGVhZGVyU2l6ZSArIDAsIGZhbHNlKQogICAgaWYgKGVyciAhPT0gdmFsaWRhdG9yLnZhbGlkYXRpb25FcnJvci5OT05FKQogICAgICAgIHJldHVybiBlcnI7CgoKICAgIC8vIHZhbGlkYXRlIE1lZGlhUm91dGVyX1JlZ2lzdGVyTWVkaWFSb3V0ZVByb3ZpZGVyX1Jlc3BvbnNlUGFyYW1zLmNvbmZpZwogICAgZXJyID0gbWVzc2FnZVZhbGlkYXRvci52YWxpZGF0ZVN0cnVjdFBvaW50ZXIob2Zmc2V0ICsgY29kZWMua1N0cnVjdEhlYWRlclNpemUgKyA4LCBNZWRpYVJvdXRlUHJvdmlkZXJDb25maWcsIGZhbHNlKTsKICAgIGlmIChlcnIgIT09IHZhbGlkYXRvci52YWxpZGF0aW9uRXJyb3IuTk9ORSkKICAgICAgICByZXR1cm4gZXJyOwoKICAgIHJldHVybiB2YWxpZGF0b3IudmFsaWRhdGlvbkVycm9yLk5PTkU7CiAgfTsKCiAgTWVkaWFSb3V0ZXJfUmVnaXN0ZXJNZWRpYVJvdXRlUHJvdmlkZXJfUmVzcG9uc2VQYXJhbXMuZW5jb2RlZFNpemUgPSBjb2RlYy5rU3RydWN0SGVhZGVyU2l6ZSArIDE2OwoKICBNZWRpYVJvdXRlcl9SZWdpc3Rlck1lZGlhUm91dGVQcm92aWRlcl9SZXNwb25zZVBhcmFtcy5kZWNvZGUgPSBmdW5jdGlvbihkZWNvZGVyKSB7CiAgICB2YXIgcGFja2VkOwogICAgdmFyIHZhbCA9IG5ldyBNZWRpYVJvdXRlcl9SZWdpc3Rlck1lZGlhUm91dGVQcm92aWRlcl9SZXNwb25zZVBhcmFtcygpOwogICAgdmFyIG51bWJlck9mQnl0ZXMgPSBkZWNvZGVyLnJlYWRVaW50MzIoKTsKICAgIHZhciB2ZXJzaW9uID0gZGVjb2Rlci5yZWFkVWludDMyKCk7CiAgICB2YWwuaW5zdGFuY2VJZCA9IGRlY29kZXIuZGVjb2RlU3RydWN0KGNvZGVjLlN0cmluZyk7CiAgICB2YWwuY29uZmlnID0gZGVjb2Rlci5kZWNvZGVTdHJ1Y3RQb2ludGVyKE1lZGlhUm91dGVQcm92aWRlckNvbmZpZyk7CiAgICByZXR1cm4gdmFsOwogIH07CgogIE1lZGlhUm91dGVyX1JlZ2lzdGVyTWVkaWFSb3V0ZVByb3ZpZGVyX1Jlc3BvbnNlUGFyYW1zLmVuY29kZSA9IGZ1bmN0aW9uKGVuY29kZXIsIHZhbCkgewogICAgdmFyIHBhY2tlZDsKICAgIGVuY29kZXIud3JpdGVVaW50MzIoTWVkaWFSb3V0ZXJfUmVnaXN0ZXJNZWRpYVJvdXRlUHJvdmlkZXJfUmVzcG9uc2VQYXJhbXMuZW5jb2RlZFNpemUpOwogICAgZW5jb2Rlci53cml0ZVVpbnQzMigwKTsKICAgIGVuY29kZXIuZW5jb2RlU3RydWN0KGNvZGVjLlN0cmluZywgdmFsLmluc3RhbmNlSWQpOwogICAgZW5jb2Rlci5lbmNvZGVTdHJ1Y3RQb2ludGVyKE1lZGlhUm91dGVQcm92aWRlckNvbmZpZywgdmFsLmNvbmZpZyk7CiAgfTsKICBmdW5jdGlvbiBNZWRpYVJvdXRlcl9PblNpbmtzUmVjZWl2ZWRfUGFyYW1zKHZhbHVlcykgewogICAgdGhpcy5pbml0RGVmYXVsdHNfKCk7CiAgICB0aGlzLmluaXRGaWVsZHNfKHZhbHVlcyk7CiAgfQoKCiAgTWVkaWFSb3V0ZXJfT25TaW5rc1JlY2VpdmVkX1BhcmFtcy5wcm90b3R5cGUuaW5pdERlZmF1bHRzXyA9IGZ1bmN0aW9uKCkgewogICAgdGhpcy5wcm92aWRlcklkID0gMDsKICAgIHRoaXMubWVkaWFTb3VyY2UgPSBudWxsOwogICAgdGhpcy5zaW5rcyA9IG51bGw7CiAgICB0aGlzLm9yaWdpbnMgPSBudWxsOwogIH07CiAgTWVkaWFSb3V0ZXJfT25TaW5rc1JlY2VpdmVkX1BhcmFtcy5wcm90b3R5cGUuaW5pdEZpZWxkc18gPSBmdW5jdGlvbihmaWVsZHMpIHsKICAgIGZvcih2YXIgZmllbGQgaW4gZmllbGRzKSB7CiAgICAgICAgaWYgKHRoaXMuaGFzT3duUHJvcGVydHkoZmllbGQpKQogICAgICAgICAgdGhpc1tmaWVsZF0gPSBmaWVsZHNbZmllbGRdOwogICAgfQogIH07CgogIE1lZGlhUm91dGVyX09uU2lua3NSZWNlaXZlZF9QYXJhbXMudmFsaWRhdGUgPSBmdW5jdGlvbihtZXNzYWdlVmFsaWRhdG9yLCBvZmZzZXQpIHsKICAgIHZhciBlcnI7CiAgICBlcnIgPSBtZXNzYWdlVmFsaWRhdG9yLnZhbGlkYXRlU3RydWN0SGVhZGVyKG9mZnNldCwgY29kZWMua1N0cnVjdEhlYWRlclNpemUpOwogICAgaWYgKGVyciAhPT0gdmFsaWRhdG9yLnZhbGlkYXRpb25FcnJvci5OT05FKQogICAgICAgIHJldHVybiBlcnI7CgogICAgdmFyIGtWZXJzaW9uU2l6ZXMgPSBbCiAgICAgIHt2ZXJzaW9uOiAwLCBudW1CeXRlczogNDB9CiAgICBdOwogICAgZXJyID0gbWVzc2FnZVZhbGlkYXRvci52YWxpZGF0ZVN0cnVjdFZlcnNpb24ob2Zmc2V0LCBrVmVyc2lvblNpemVzKTsKICAgIGlmIChlcnIgIT09IHZhbGlkYXRvci52YWxpZGF0aW9uRXJyb3IuTk9ORSkKICAgICAgICByZXR1cm4gZXJyOwoKCiAgICAvLyB2YWxpZGF0ZSBNZWRpYVJvdXRlcl9PblNpbmtzUmVjZWl2ZWRfUGFyYW1zLnByb3ZpZGVySWQKICAgIGVyciA9IG1lc3NhZ2VWYWxpZGF0b3IudmFsaWRhdGVFbnVtKG9mZnNldCArIGNvZGVjLmtTdHJ1Y3RIZWFkZXJTaXplICsgMCwgTWVkaWFSb3V0ZVByb3ZpZGVyLklkKTsKICAgIGlmIChlcnIgIT09IHZhbGlkYXRvci52YWxpZGF0aW9uRXJyb3IuTk9ORSkKICAgICAgICByZXR1cm4gZXJyOwoKCiAgICAvLyB2YWxpZGF0ZSBNZWRpYVJvdXRlcl9PblNpbmtzUmVjZWl2ZWRfUGFyYW1zLm1lZGlhU291cmNlCiAgICBlcnIgPSBtZXNzYWdlVmFsaWRhdG9yLnZhbGlkYXRlU3RyaW5nUG9pbnRlcihvZmZzZXQgKyBjb2RlYy5rU3RydWN0SGVhZGVyU2l6ZSArIDgsIGZhbHNlKQogICAgaWYgKGVyciAhPT0gdmFsaWRhdG9yLnZhbGlkYXRpb25FcnJvci5OT05FKQogICAgICAgIHJldHVybiBlcnI7CgoKICAgIC8vIHZhbGlkYXRlIE1lZGlhUm91dGVyX09uU2lua3NSZWNlaXZlZF9QYXJhbXMuc2lua3MKICAgIGVyciA9IG1lc3NhZ2VWYWxpZGF0b3IudmFsaWRhdGVBcnJheVBvaW50ZXIob2Zmc2V0ICsgY29kZWMua1N0cnVjdEhlYWRlclNpemUgKyAxNiwgOCwgbmV3IGNvZGVjLlBvaW50ZXJUbyhNZWRpYVNpbmspLCBmYWxzZSwgWzBdLCAwKTsKICAgIGlmIChlcnIgIT09IHZhbGlkYXRvci52YWxpZGF0aW9uRXJyb3IuTk9ORSkKICAgICAgICByZXR1cm4gZXJyOwoKCiAgICAvLyB2YWxpZGF0ZSBNZWRpYVJvdXRlcl9PblNpbmtzUmVjZWl2ZWRfUGFyYW1zLm9yaWdpbnMKICAgIGVyciA9IG1lc3NhZ2VWYWxpZGF0b3IudmFsaWRhdGVBcnJheVBvaW50ZXIob2Zmc2V0ICsgY29kZWMua1N0cnVjdEhlYWRlclNpemUgKyAyNCwgOCwgbmV3IGNvZGVjLlBvaW50ZXJUbyhvcmlnaW4kLk9yaWdpbiksIGZhbHNlLCBbMF0sIDApOwogICAgaWYgKGVyciAhPT0gdmFsaWRhdG9yLnZhbGlkYXRpb25FcnJvci5OT05FKQogICAgICAgIHJldHVybiBlcnI7CgogICAgcmV0dXJuIHZhbGlkYXRvci52YWxpZGF0aW9uRXJyb3IuTk9ORTsKICB9OwoKICBNZWRpYVJvdXRlcl9PblNpbmtzUmVjZWl2ZWRfUGFyYW1zLmVuY29kZWRTaXplID0gY29kZWMua1N0cnVjdEhlYWRlclNpemUgKyAzMjsKCiAgTWVkaWFSb3V0ZXJfT25TaW5rc1JlY2VpdmVkX1BhcmFtcy5kZWNvZGUgPSBmdW5jdGlvbihkZWNvZGVyKSB7CiAgICB2YXIgcGFja2VkOwogICAgdmFyIHZhbCA9IG5ldyBNZWRpYVJvdXRlcl9PblNpbmtzUmVjZWl2ZWRfUGFyYW1zKCk7CiAgICB2YXIgbnVtYmVyT2ZCeXRlcyA9IGRlY29kZXIucmVhZFVpbnQzMigpOwogICAgdmFyIHZlcnNpb24gPSBkZWNvZGVyLnJlYWRVaW50MzIoKTsKICAgIHZhbC5wcm92aWRlcklkID0gZGVjb2Rlci5kZWNvZGVTdHJ1Y3QoY29kZWMuSW50MzIpOwogICAgZGVjb2Rlci5za2lwKDEpOwogICAgZGVjb2Rlci5za2lwKDEpOwogICAgZGVjb2Rlci5za2lwKDEpOwogICAgZGVjb2Rlci5za2lwKDEpOwogICAgdmFsLm1lZGlhU291cmNlID0gZGVjb2Rlci5kZWNvZGVTdHJ1Y3QoY29kZWMuU3RyaW5nKTsKICAgIHZhbC5zaW5rcyA9IGRlY29kZXIuZGVjb2RlQXJyYXlQb2ludGVyKG5ldyBjb2RlYy5Qb2ludGVyVG8oTWVkaWFTaW5rKSk7CiAgICB2YWwub3JpZ2lucyA9IGRlY29kZXIuZGVjb2RlQXJyYXlQb2ludGVyKG5ldyBjb2RlYy5Qb2ludGVyVG8ob3JpZ2luJC5PcmlnaW4pKTsKICAgIHJldHVybiB2YWw7CiAgfTsKCiAgTWVkaWFSb3V0ZXJfT25TaW5rc1JlY2VpdmVkX1BhcmFtcy5lbmNvZGUgPSBmdW5jdGlvbihlbmNvZGVyLCB2YWwpIHsKICAgIHZhciBwYWNrZWQ7CiAgICBlbmNvZGVyLndyaXRlVWludDMyKE1lZGlhUm91dGVyX09uU2lua3NSZWNlaXZlZF9QYXJhbXMuZW5jb2RlZFNpemUpOwogICAgZW5jb2Rlci53cml0ZVVpbnQzMigwKTsKICAgIGVuY29kZXIuZW5jb2RlU3RydWN0KGNvZGVjLkludDMyLCB2YWwucHJvdmlkZXJJZCk7CiAgICBlbmNvZGVyLnNraXAoMSk7CiAgICBlbmNvZGVyLnNraXAoMSk7CiAgICBlbmNvZGVyLnNraXAoMSk7CiAgICBlbmNvZGVyLnNraXAoMSk7CiAgICBlbmNvZGVyLmVuY29kZVN0cnVjdChjb2RlYy5TdHJpbmcsIHZhbC5tZWRpYVNvdXJjZSk7CiAgICBlbmNvZGVyLmVuY29kZUFycmF5UG9pbnRlcihuZXcgY29kZWMuUG9pbnRlclRvKE1lZGlhU2luayksIHZhbC5zaW5rcyk7CiAgICBlbmNvZGVyLmVuY29kZUFycmF5UG9pbnRlcihuZXcgY29kZWMuUG9pbnRlclRvKG9yaWdpbiQuT3JpZ2luKSwgdmFsLm9yaWdpbnMpOwogIH07CiAgZnVuY3Rpb24gTWVkaWFSb3V0ZXJfT25Jc3N1ZV9QYXJhbXModmFsdWVzKSB7CiAgICB0aGlzLmluaXREZWZhdWx0c18oKTsKICAgIHRoaXMuaW5pdEZpZWxkc18odmFsdWVzKTsKICB9CgoKICBNZWRpYVJvdXRlcl9Pbklzc3VlX1BhcmFtcy5wcm90b3R5cGUuaW5pdERlZmF1bHRzXyA9IGZ1bmN0aW9uKCkgewogICAgdGhpcy5pc3N1ZSA9IG51bGw7CiAgfTsKICBNZWRpYVJvdXRlcl9Pbklzc3VlX1BhcmFtcy5wcm90b3R5cGUuaW5pdEZpZWxkc18gPSBmdW5jdGlvbihmaWVsZHMpIHsKICAgIGZvcih2YXIgZmllbGQgaW4gZmllbGRzKSB7CiAgICAgICAgaWYgKHRoaXMuaGFzT3duUHJvcGVydHkoZmllbGQpKQogICAgICAgICAgdGhpc1tmaWVsZF0gPSBmaWVsZHNbZmllbGRdOwogICAgfQogIH07CgogIE1lZGlhUm91dGVyX09uSXNzdWVfUGFyYW1zLnZhbGlkYXRlID0gZnVuY3Rpb24obWVzc2FnZVZhbGlkYXRvciwgb2Zmc2V0KSB7CiAgICB2YXIgZXJyOwogICAgZXJyID0gbWVzc2FnZVZhbGlkYXRvci52YWxpZGF0ZVN0cnVjdEhlYWRlcihvZmZzZXQsIGNvZGVjLmtTdHJ1Y3RIZWFkZXJTaXplKTsKICAgIGlmIChlcnIgIT09IHZhbGlkYXRvci52YWxpZGF0aW9uRXJyb3IuTk9ORSkKICAgICAgICByZXR1cm4gZXJyOwoKICAgIHZhciBrVmVyc2lvblNpemVzID0gWwogICAgICB7dmVyc2lvbjogMCwgbnVtQnl0ZXM6IDE2fQogICAgXTsKICAgIGVyciA9IG1lc3NhZ2VWYWxpZGF0b3IudmFsaWRhdGVTdHJ1Y3RWZXJzaW9uKG9mZnNldCwga1ZlcnNpb25TaXplcyk7CiAgICBpZiAoZXJyICE9PSB2YWxpZGF0b3IudmFsaWRhdGlvbkVycm9yLk5PTkUpCiAgICAgICAgcmV0dXJuIGVycjsKCgogICAgLy8gdmFsaWRhdGUgTWVkaWFSb3V0ZXJfT25Jc3N1ZV9QYXJhbXMuaXNzdWUKICAgIGVyciA9IG1lc3NhZ2VWYWxpZGF0b3IudmFsaWRhdGVTdHJ1Y3RQb2ludGVyKG9mZnNldCArIGNvZGVjLmtTdHJ1Y3RIZWFkZXJTaXplICsgMCwgSXNzdWUsIGZhbHNlKTsKICAgIGlmIChlcnIgIT09IHZhbGlkYXRvci52YWxpZGF0aW9uRXJyb3IuTk9ORSkKICAgICAgICByZXR1cm4gZXJyOwoKICAgIHJldHVybiB2YWxpZGF0b3IudmFsaWRhdGlvbkVycm9yLk5PTkU7CiAgfTsKCiAgTWVkaWFSb3V0ZXJfT25Jc3N1ZV9QYXJhbXMuZW5jb2RlZFNpemUgPSBjb2RlYy5rU3RydWN0SGVhZGVyU2l6ZSArIDg7CgogIE1lZGlhUm91dGVyX09uSXNzdWVfUGFyYW1zLmRlY29kZSA9IGZ1bmN0aW9uKGRlY29kZXIpIHsKICAgIHZhciBwYWNrZWQ7CiAgICB2YXIgdmFsID0gbmV3IE1lZGlhUm91dGVyX09uSXNzdWVfUGFyYW1zKCk7CiAgICB2YXIgbnVtYmVyT2ZCeXRlcyA9IGRlY29kZXIucmVhZFVpbnQzMigpOwogICAgdmFyIHZlcnNpb24gPSBkZWNvZGVyLnJlYWRVaW50MzIoKTsKICAgIHZhbC5pc3N1ZSA9IGRlY29kZXIuZGVjb2RlU3RydWN0UG9pbnRlcihJc3N1ZSk7CiAgICByZXR1cm4gdmFsOwogIH07CgogIE1lZGlhUm91dGVyX09uSXNzdWVfUGFyYW1zLmVuY29kZSA9IGZ1bmN0aW9uKGVuY29kZXIsIHZhbCkgewogICAgdmFyIHBhY2tlZDsKICAgIGVuY29kZXIud3JpdGVVaW50MzIoTWVkaWFSb3V0ZXJfT25Jc3N1ZV9QYXJhbXMuZW5jb2RlZFNpemUpOwogICAgZW5jb2Rlci53cml0ZVVpbnQzMigwKTsKICAgIGVuY29kZXIuZW5jb2RlU3RydWN0UG9pbnRlcihJc3N1ZSwgdmFsLmlzc3VlKTsKICB9OwogIGZ1bmN0aW9uIE1lZGlhUm91dGVyX09uUm91dGVzVXBkYXRlZF9QYXJhbXModmFsdWVzKSB7CiAgICB0aGlzLmluaXREZWZhdWx0c18oKTsKICAgIHRoaXMuaW5pdEZpZWxkc18odmFsdWVzKTsKICB9CgoKICBNZWRpYVJvdXRlcl9PblJvdXRlc1VwZGF0ZWRfUGFyYW1zLnByb3RvdHlwZS5pbml0RGVmYXVsdHNfID0gZnVuY3Rpb24oKSB7CiAgICB0aGlzLnByb3ZpZGVySWQgPSAwOwogICAgdGhpcy5yb3V0ZXMgPSBudWxsOwogICAgdGhpcy5tZWRpYVNvdXJjZSA9IG51bGw7CiAgICB0aGlzLmpvaW5hYmxlUm91dGVJZHMgPSBudWxsOwogIH07CiAgTWVkaWFSb3V0ZXJfT25Sb3V0ZXNVcGRhdGVkX1BhcmFtcy5wcm90b3R5cGUuaW5pdEZpZWxkc18gPSBmdW5jdGlvbihmaWVsZHMpIHsKICAgIGZvcih2YXIgZmllbGQgaW4gZmllbGRzKSB7CiAgICAgICAgaWYgKHRoaXMuaGFzT3duUHJvcGVydHkoZmllbGQpKQogICAgICAgICAgdGhpc1tmaWVsZF0gPSBmaWVsZHNbZmllbGRdOwogICAgfQogIH07CgogIE1lZGlhUm91dGVyX09uUm91dGVzVXBkYXRlZF9QYXJhbXMudmFsaWRhdGUgPSBmdW5jdGlvbihtZXNzYWdlVmFsaWRhdG9yLCBvZmZzZXQpIHsKICAgIHZhciBlcnI7CiAgICBlcnIgPSBtZXNzYWdlVmFsaWRhdG9yLnZhbGlkYXRlU3RydWN0SGVhZGVyKG9mZnNldCwgY29kZWMua1N0cnVjdEhlYWRlclNpemUpOwogICAgaWYgKGVyciAhPT0gdmFsaWRhdG9yLnZhbGlkYXRpb25FcnJvci5OT05FKQogICAgICAgIHJldHVybiBlcnI7CgogICAgdmFyIGtWZXJzaW9uU2l6ZXMgPSBbCiAgICAgIHt2ZXJzaW9uOiAwLCBudW1CeXRlczogNDB9CiAgICBdOwogICAgZXJyID0gbWVzc2FnZVZhbGlkYXRvci52YWxpZGF0ZVN0cnVjdFZlcnNpb24ob2Zmc2V0LCBrVmVyc2lvblNpemVzKTsKICAgIGlmIChlcnIgIT09IHZhbGlkYXRvci52YWxpZGF0aW9uRXJyb3IuTk9ORSkKICAgICAgICByZXR1cm4gZXJyOwoKCiAgICAvLyB2YWxpZGF0ZSBNZWRpYVJvdXRlcl9PblJvdXRlc1VwZGF0ZWRfUGFyYW1zLnByb3ZpZGVySWQKICAgIGVyciA9IG1lc3NhZ2VWYWxpZGF0b3IudmFsaWRhdGVFbnVtKG9mZnNldCArIGNvZGVjLmtTdHJ1Y3RIZWFkZXJTaXplICsgMCwgTWVkaWFSb3V0ZVByb3ZpZGVyLklkKTsKICAgIGlmIChlcnIgIT09IHZhbGlkYXRvci52YWxpZGF0aW9uRXJyb3IuTk9ORSkKICAgICAgICByZXR1cm4gZXJyOwoKCiAgICAvLyB2YWxpZGF0ZSBNZWRpYVJvdXRlcl9PblJvdXRlc1VwZGF0ZWRfUGFyYW1zLnJvdXRlcwogICAgZXJyID0gbWVzc2FnZVZhbGlkYXRvci52YWxpZGF0ZUFycmF5UG9pbnRlcihvZmZzZXQgKyBjb2RlYy5rU3RydWN0SGVhZGVyU2l6ZSArIDgsIDgsIG5ldyBjb2RlYy5Qb2ludGVyVG8oTWVkaWFSb3V0ZSksIGZhbHNlLCBbMF0sIDApOwogICAgaWYgKGVyciAhPT0gdmFsaWRhdG9yLnZhbGlkYXRpb25FcnJvci5OT05FKQogICAgICAgIHJldHVybiBlcnI7CgoKICAgIC8vIHZhbGlkYXRlIE1lZGlhUm91dGVyX09uUm91dGVzVXBkYXRlZF9QYXJhbXMubWVkaWFTb3VyY2UKICAgIGVyciA9IG1lc3NhZ2VWYWxpZGF0b3IudmFsaWRhdGVTdHJpbmdQb2ludGVyKG9mZnNldCArIGNvZGVjLmtTdHJ1Y3RIZWFkZXJTaXplICsgMTYsIGZhbHNlKQogICAgaWYgKGVyciAhPT0gdmFsaWRhdG9yLnZhbGlkYXRpb25FcnJvci5OT05FKQogICAgICAgIHJldHVybiBlcnI7CgoKICAgIC8vIHZhbGlkYXRlIE1lZGlhUm91dGVyX09uUm91dGVzVXBkYXRlZF9QYXJhbXMuam9pbmFibGVSb3V0ZUlkcwogICAgZXJyID0gbWVzc2FnZVZhbGlkYXRvci52YWxpZGF0ZUFycmF5UG9pbnRlcihvZmZzZXQgKyBjb2RlYy5rU3RydWN0SGVhZGVyU2l6ZSArIDI0LCA4LCBjb2RlYy5TdHJpbmcsIGZhbHNlLCBbMCwgMF0sIDApOwogICAgaWYgKGVyciAhPT0gdmFsaWRhdG9yLnZhbGlkYXRpb25FcnJvci5OT05FKQogICAgICAgIHJldHVybiBlcnI7CgogICAgcmV0dXJuIHZhbGlkYXRvci52YWxpZGF0aW9uRXJyb3IuTk9ORTsKICB9OwoKICBNZWRpYVJvdXRlcl9PblJvdXRlc1VwZGF0ZWRfUGFyYW1zLmVuY29kZWRTaXplID0gY29kZWMua1N0cnVjdEhlYWRlclNpemUgKyAzMjsKCiAgTWVkaWFSb3V0ZXJfT25Sb3V0ZXNVcGRhdGVkX1BhcmFtcy5kZWNvZGUgPSBmdW5jdGlvbihkZWNvZGVyKSB7CiAgICB2YXIgcGFja2VkOwogICAgdmFyIHZhbCA9IG5ldyBNZWRpYVJvdXRlcl9PblJvdXRlc1VwZGF0ZWRfUGFyYW1zKCk7CiAgICB2YXIgbnVtYmVyT2ZCeXRlcyA9IGRlY29kZXIucmVhZFVpbnQzMigpOwogICAgdmFyIHZlcnNpb24gPSBkZWNvZGVyLnJlYWRVaW50MzIoKTsKICAgIHZhbC5wcm92aWRlcklkID0gZGVjb2Rlci5kZWNvZGVTdHJ1Y3QoY29kZWMuSW50MzIpOwogICAgZGVjb2Rlci5za2lwKDEpOwogICAgZGVjb2Rlci5za2lwKDEpOwogICAgZGVjb2Rlci5za2lwKDEpOwogICAgZGVjb2Rlci5za2lwKDEpOwogICAgdmFsLnJvdXRlcyA9IGRlY29kZXIuZGVjb2RlQXJyYXlQb2ludGVyKG5ldyBjb2RlYy5Qb2ludGVyVG8oTWVkaWFSb3V0ZSkpOwogICAgdmFsLm1lZGlhU291cmNlID0gZGVjb2Rlci5kZWNvZGVTdHJ1Y3QoY29kZWMuU3RyaW5nKTsKICAgIHZhbC5qb2luYWJsZVJvdXRlSWRzID0gZGVjb2Rlci5kZWNvZGVBcnJheVBvaW50ZXIoY29kZWMuU3RyaW5nKTsKICAgIHJldHVybiB2YWw7CiAgfTsKCiAgTWVkaWFSb3V0ZXJfT25Sb3V0ZXNVcGRhdGVkX1BhcmFtcy5lbmNvZGUgPSBmdW5jdGlvbihlbmNvZGVyLCB2YWwpIHsKICAgIHZhciBwYWNrZWQ7CiAgICBlbmNvZGVyLndyaXRlVWludDMyKE1lZGlhUm91dGVyX09uUm91dGVzVXBkYXRlZF9QYXJhbXMuZW5jb2RlZFNpemUpOwogICAgZW5jb2Rlci53cml0ZVVpbnQzMigwKTsKICAgIGVuY29kZXIuZW5jb2RlU3RydWN0KGNvZGVjLkludDMyLCB2YWwucHJvdmlkZXJJZCk7CiAgICBlbmNvZGVyLnNraXAoMSk7CiAgICBlbmNvZGVyLnNraXAoMSk7CiAgICBlbmNvZGVyLnNraXAoMSk7CiAgICBlbmNvZGVyLnNraXAoMSk7CiAgICBlbmNvZGVyLmVuY29kZUFycmF5UG9pbnRlcihuZXcgY29kZWMuUG9pbnRlclRvKE1lZGlhUm91dGUpLCB2YWwucm91dGVzKTsKICAgIGVuY29kZXIuZW5jb2RlU3RydWN0KGNvZGVjLlN0cmluZywgdmFsLm1lZGlhU291cmNlKTsKICAgIGVuY29kZXIuZW5jb2RlQXJyYXlQb2ludGVyKGNvZGVjLlN0cmluZywgdmFsLmpvaW5hYmxlUm91dGVJZHMpOwogIH07CiAgZnVuY3Rpb24gTWVkaWFSb3V0ZXJfT25TaW5rQXZhaWxhYmlsaXR5VXBkYXRlZF9QYXJhbXModmFsdWVzKSB7CiAgICB0aGlzLmluaXREZWZhdWx0c18oKTsKICAgIHRoaXMuaW5pdEZpZWxkc18odmFsdWVzKTsKICB9CgoKICBNZWRpYVJvdXRlcl9PblNpbmtBdmFpbGFiaWxpdHlVcGRhdGVkX1BhcmFtcy5wcm90b3R5cGUuaW5pdERlZmF1bHRzXyA9IGZ1bmN0aW9uKCkgewogICAgdGhpcy5wcm92aWRlcklkID0gMDsKICAgIHRoaXMuYXZhaWxhYmlsaXR5ID0gMDsKICB9OwogIE1lZGlhUm91dGVyX09uU2lua0F2YWlsYWJpbGl0eVVwZGF0ZWRfUGFyYW1zLnByb3RvdHlwZS5pbml0RmllbGRzXyA9IGZ1bmN0aW9uKGZpZWxkcykgewogICAgZm9yKHZhciBmaWVsZCBpbiBmaWVsZHMpIHsKICAgICAgICBpZiAodGhpcy5oYXNPd25Qcm9wZXJ0eShmaWVsZCkpCiAgICAgICAgICB0aGlzW2ZpZWxkXSA9IGZpZWxkc1tmaWVsZF07CiAgICB9CiAgfTsKCiAgTWVkaWFSb3V0ZXJfT25TaW5rQXZhaWxhYmlsaXR5VXBkYXRlZF9QYXJhbXMudmFsaWRhdGUgPSBmdW5jdGlvbihtZXNzYWdlVmFsaWRhdG9yLCBvZmZzZXQpIHsKICAgIHZhciBlcnI7CiAgICBlcnIgPSBtZXNzYWdlVmFsaWRhdG9yLnZhbGlkYXRlU3RydWN0SGVhZGVyKG9mZnNldCwgY29kZWMua1N0cnVjdEhlYWRlclNpemUpOwogICAgaWYgKGVyciAhPT0gdmFsaWRhdG9yLnZhbGlkYXRpb25FcnJvci5OT05FKQogICAgICAgIHJldHVybiBlcnI7CgogICAgdmFyIGtWZXJzaW9uU2l6ZXMgPSBbCiAgICAgIHt2ZXJzaW9uOiAwLCBudW1CeXRlczogMTZ9CiAgICBdOwogICAgZXJyID0gbWVzc2FnZVZhbGlkYXRvci52YWxpZGF0ZVN0cnVjdFZlcnNpb24ob2Zmc2V0LCBrVmVyc2lvblNpemVzKTsKICAgIGlmIChlcnIgIT09IHZhbGlkYXRvci52YWxpZGF0aW9uRXJyb3IuTk9ORSkKICAgICAgICByZXR1cm4gZXJyOwoKCiAgICAvLyB2YWxpZGF0ZSBNZWRpYVJvdXRlcl9PblNpbmtBdmFpbGFiaWxpdHlVcGRhdGVkX1BhcmFtcy5wcm92aWRlcklkCiAgICBlcnIgPSBtZXNzYWdlVmFsaWRhdG9yLnZhbGlkYXRlRW51bShvZmZzZXQgKyBjb2RlYy5rU3RydWN0SGVhZGVyU2l6ZSArIDAsIE1lZGlhUm91dGVQcm92aWRlci5JZCk7CiAgICBpZiAoZXJyICE9PSB2YWxpZGF0b3IudmFsaWRhdGlvbkVycm9yLk5PTkUpCiAgICAgICAgcmV0dXJuIGVycjsKCgogICAgLy8gdmFsaWRhdGUgTWVkaWFSb3V0ZXJfT25TaW5rQXZhaWxhYmlsaXR5VXBkYXRlZF9QYXJhbXMuYXZhaWxhYmlsaXR5CiAgICBlcnIgPSBtZXNzYWdlVmFsaWRhdG9yLnZhbGlkYXRlRW51bShvZmZzZXQgKyBjb2RlYy5rU3RydWN0SGVhZGVyU2l6ZSArIDQsIE1lZGlhUm91dGVyLlNpbmtBdmFpbGFiaWxpdHkpOwogICAgaWYgKGVyciAhPT0gdmFsaWRhdG9yLnZhbGlkYXRpb25FcnJvci5OT05FKQogICAgICAgIHJldHVybiBlcnI7CgogICAgcmV0dXJuIHZhbGlkYXRvci52YWxpZGF0aW9uRXJyb3IuTk9ORTsKICB9OwoKICBNZWRpYVJvdXRlcl9PblNpbmtBdmFpbGFiaWxpdHlVcGRhdGVkX1BhcmFtcy5lbmNvZGVkU2l6ZSA9IGNvZGVjLmtTdHJ1Y3RIZWFkZXJTaXplICsgODsKCiAgTWVkaWFSb3V0ZXJfT25TaW5rQXZhaWxhYmlsaXR5VXBkYXRlZF9QYXJhbXMuZGVjb2RlID0gZnVuY3Rpb24oZGVjb2RlcikgewogICAgdmFyIHBhY2tlZDsKICAgIHZhciB2YWwgPSBuZXcgTWVkaWFSb3V0ZXJfT25TaW5rQXZhaWxhYmlsaXR5VXBkYXRlZF9QYXJhbXMoKTsKICAgIHZhciBudW1iZXJPZkJ5dGVzID0gZGVjb2Rlci5yZWFkVWludDMyKCk7CiAgICB2YXIgdmVyc2lvbiA9IGRlY29kZXIucmVhZFVpbnQzMigpOwogICAgdmFsLnByb3ZpZGVySWQgPSBkZWNvZGVyLmRlY29kZVN0cnVjdChjb2RlYy5JbnQzMik7CiAgICB2YWwuYXZhaWxhYmlsaXR5ID0gZGVjb2Rlci5kZWNvZGVTdHJ1Y3QoY29kZWMuSW50MzIpOwogICAgcmV0dXJuIHZhbDsKICB9OwoKICBNZWRpYVJvdXRlcl9PblNpbmtBdmFpbGFiaWxpdHlVcGRhdGVkX1BhcmFtcy5lbmNvZGUgPSBmdW5jdGlvbihlbmNvZGVyLCB2YWwpIHsKICAgIHZhciBwYWNrZWQ7CiAgICBlbmNvZGVyLndyaXRlVWludDMyKE1lZGlhUm91dGVyX09uU2lua0F2YWlsYWJpbGl0eVVwZGF0ZWRfUGFyYW1zLmVuY29kZWRTaXplKTsKICAgIGVuY29kZXIud3JpdGVVaW50MzIoMCk7CiAgICBlbmNvZGVyLmVuY29kZVN0cnVjdChjb2RlYy5JbnQzMiwgdmFsLnByb3ZpZGVySWQpOwogICAgZW5jb2Rlci5lbmNvZGVTdHJ1Y3QoY29kZWMuSW50MzIsIHZhbC5hdmFpbGFiaWxpdHkpOwogIH07CiAgZnVuY3Rpb24gTWVkaWFSb3V0ZXJfT25QcmVzZW50YXRpb25Db25uZWN0aW9uU3RhdGVDaGFuZ2VkX1BhcmFtcyh2YWx1ZXMpIHsKICAgIHRoaXMuaW5pdERlZmF1bHRzXygpOwogICAgdGhpcy5pbml0RmllbGRzXyh2YWx1ZXMpOwogIH0KCgogIE1lZGlhUm91dGVyX09uUHJlc2VudGF0aW9uQ29ubmVjdGlvblN0YXRlQ2hhbmdlZF9QYXJhbXMucHJvdG90eXBlLmluaXREZWZhdWx0c18gPSBmdW5jdGlvbigpIHsKICAgIHRoaXMucm91dGVJZCA9IG51bGw7CiAgICB0aGlzLnN0YXRlID0gMDsKICB9OwogIE1lZGlhUm91dGVyX09uUHJlc2VudGF0aW9uQ29ubmVjdGlvblN0YXRlQ2hhbmdlZF9QYXJhbXMucHJvdG90eXBlLmluaXRGaWVsZHNfID0gZnVuY3Rpb24oZmllbGRzKSB7CiAgICBmb3IodmFyIGZpZWxkIGluIGZpZWxkcykgewogICAgICAgIGlmICh0aGlzLmhhc093blByb3BlcnR5KGZpZWxkKSkKICAgICAgICAgIHRoaXNbZmllbGRdID0gZmllbGRzW2ZpZWxkXTsKICAgIH0KICB9OwoKICBNZWRpYVJvdXRlcl9PblByZXNlbnRhdGlvbkNvbm5lY3Rpb25TdGF0ZUNoYW5nZWRfUGFyYW1zLnZhbGlkYXRlID0gZnVuY3Rpb24obWVzc2FnZVZhbGlkYXRvciwgb2Zmc2V0KSB7CiAgICB2YXIgZXJyOwogICAgZXJyID0gbWVzc2FnZVZhbGlkYXRvci52YWxpZGF0ZVN0cnVjdEhlYWRlcihvZmZzZXQsIGNvZGVjLmtTdHJ1Y3RIZWFkZXJTaXplKTsKICAgIGlmIChlcnIgIT09IHZhbGlkYXRvci52YWxpZGF0aW9uRXJyb3IuTk9ORSkKICAgICAgICByZXR1cm4gZXJyOwoKICAgIHZhciBrVmVyc2lvblNpemVzID0gWwogICAgICB7dmVyc2lvbjogMCwgbnVtQnl0ZXM6IDI0fQogICAgXTsKICAgIGVyciA9IG1lc3NhZ2VWYWxpZGF0b3IudmFsaWRhdGVTdHJ1Y3RWZXJzaW9uKG9mZnNldCwga1ZlcnNpb25TaXplcyk7CiAgICBpZiAoZXJyICE9PSB2YWxpZGF0b3IudmFsaWRhdGlvbkVycm9yLk5PTkUpCiAgICAgICAgcmV0dXJuIGVycjsKCgogICAgLy8gdmFsaWRhdGUgTWVkaWFSb3V0ZXJfT25QcmVzZW50YXRpb25Db25uZWN0aW9uU3RhdGVDaGFuZ2VkX1BhcmFtcy5yb3V0ZUlkCiAgICBlcnIgPSBtZXNzYWdlVmFsaWRhdG9yLnZhbGlkYXRlU3RyaW5nUG9pbnRlcihvZmZzZXQgKyBjb2RlYy5rU3RydWN0SGVhZGVyU2l6ZSArIDAsIGZhbHNlKQogICAgaWYgKGVyciAhPT0gdmFsaWRhdG9yLnZhbGlkYXRpb25FcnJvci5OT05FKQogICAgICAgIHJldHVybiBlcnI7CgoKICAgIC8vIHZhbGlkYXRlIE1lZGlhUm91dGVyX09uUHJlc2VudGF0aW9uQ29ubmVjdGlvblN0YXRlQ2hhbmdlZF9QYXJhbXMuc3RhdGUKICAgIGVyciA9IG1lc3NhZ2VWYWxpZGF0b3IudmFsaWRhdGVFbnVtKG9mZnNldCArIGNvZGVjLmtTdHJ1Y3RIZWFkZXJTaXplICsgOCwgTWVkaWFSb3V0ZXIuUHJlc2VudGF0aW9uQ29ubmVjdGlvblN0YXRlKTsKICAgIGlmIChlcnIgIT09IHZhbGlkYXRvci52YWxpZGF0aW9uRXJyb3IuTk9ORSkKICAgICAgICByZXR1cm4gZXJyOwoKICAgIHJldHVybiB2YWxpZGF0b3IudmFsaWRhdGlvbkVycm9yLk5PTkU7CiAgfTsKCiAgTWVkaWFSb3V0ZXJfT25QcmVzZW50YXRpb25Db25uZWN0aW9uU3RhdGVDaGFuZ2VkX1BhcmFtcy5lbmNvZGVkU2l6ZSA9IGNvZGVjLmtTdHJ1Y3RIZWFkZXJTaXplICsgMTY7CgogIE1lZGlhUm91dGVyX09uUHJlc2VudGF0aW9uQ29ubmVjdGlvblN0YXRlQ2hhbmdlZF9QYXJhbXMuZGVjb2RlID0gZnVuY3Rpb24oZGVjb2RlcikgewogICAgdmFyIHBhY2tlZDsKICAgIHZhciB2YWwgPSBuZXcgTWVkaWFSb3V0ZXJfT25QcmVzZW50YXRpb25Db25uZWN0aW9uU3RhdGVDaGFuZ2VkX1BhcmFtcygpOwogICAgdmFyIG51bWJlck9mQnl0ZXMgPSBkZWNvZGVyLnJlYWRVaW50MzIoKTsKICAgIHZhciB2ZXJzaW9uID0gZGVjb2Rlci5yZWFkVWludDMyKCk7CiAgICB2YWwucm91dGVJZCA9IGRlY29kZXIuZGVjb2RlU3RydWN0KGNvZGVjLlN0cmluZyk7CiAgICB2YWwuc3RhdGUgPSBkZWNvZGVyLmRlY29kZVN0cnVjdChjb2RlYy5JbnQzMik7CiAgICBkZWNvZGVyLnNraXAoMSk7CiAgICBkZWNvZGVyLnNraXAoMSk7CiAgICBkZWNvZGVyLnNraXAoMSk7CiAgICBkZWNvZGVyLnNraXAoMSk7CiAgICByZXR1cm4gdmFsOwogIH07CgogIE1lZGlhUm91dGVyX09uUHJlc2VudGF0aW9uQ29ubmVjdGlvblN0YXRlQ2hhbmdlZF9QYXJhbXMuZW5jb2RlID0gZnVuY3Rpb24oZW5jb2RlciwgdmFsKSB7CiAgICB2YXIgcGFja2VkOwogICAgZW5jb2Rlci53cml0ZVVpbnQzMihNZWRpYVJvdXRlcl9PblByZXNlbnRhdGlvbkNvbm5lY3Rpb25TdGF0ZUNoYW5nZWRfUGFyYW1zLmVuY29kZWRTaXplKTsKICAgIGVuY29kZXIud3JpdGVVaW50MzIoMCk7CiAgICBlbmNvZGVyLmVuY29kZVN0cnVjdChjb2RlYy5TdHJpbmcsIHZhbC5yb3V0ZUlkKTsKICAgIGVuY29kZXIuZW5jb2RlU3RydWN0KGNvZGVjLkludDMyLCB2YWwuc3RhdGUpOwogICAgZW5jb2Rlci5za2lwKDEpOwogICAgZW5jb2Rlci5za2lwKDEpOwogICAgZW5jb2Rlci5za2lwKDEpOwogICAgZW5jb2Rlci5za2lwKDEpOwogIH07CiAgZnVuY3Rpb24gTWVkaWFSb3V0ZXJfT25QcmVzZW50YXRpb25Db25uZWN0aW9uQ2xvc2VkX1BhcmFtcyh2YWx1ZXMpIHsKICAgIHRoaXMuaW5pdERlZmF1bHRzXygpOwogICAgdGhpcy5pbml0RmllbGRzXyh2YWx1ZXMpOwogIH0KCgogIE1lZGlhUm91dGVyX09uUHJlc2VudGF0aW9uQ29ubmVjdGlvbkNsb3NlZF9QYXJhbXMucHJvdG90eXBlLmluaXREZWZhdWx0c18gPSBmdW5jdGlvbigpIHsKICAgIHRoaXMucm91dGVJZCA9IG51bGw7CiAgICB0aGlzLnJlYXNvbiA9IDA7CiAgICB0aGlzLm1lc3NhZ2UgPSBudWxsOwogIH07CiAgTWVkaWFSb3V0ZXJfT25QcmVzZW50YXRpb25Db25uZWN0aW9uQ2xvc2VkX1BhcmFtcy5wcm90b3R5cGUuaW5pdEZpZWxkc18gPSBmdW5jdGlvbihmaWVsZHMpIHsKICAgIGZvcih2YXIgZmllbGQgaW4gZmllbGRzKSB7CiAgICAgICAgaWYgKHRoaXMuaGFzT3duUHJvcGVydHkoZmllbGQpKQogICAgICAgICAgdGhpc1tmaWVsZF0gPSBmaWVsZHNbZmllbGRdOwogICAgfQogIH07CgogIE1lZGlhUm91dGVyX09uUHJlc2VudGF0aW9uQ29ubmVjdGlvbkNsb3NlZF9QYXJhbXMudmFsaWRhdGUgPSBmdW5jdGlvbihtZXNzYWdlVmFsaWRhdG9yLCBvZmZzZXQpIHsKICAgIHZhciBlcnI7CiAgICBlcnIgPSBtZXNzYWdlVmFsaWRhdG9yLnZhbGlkYXRlU3RydWN0SGVhZGVyKG9mZnNldCwgY29kZWMua1N0cnVjdEhlYWRlclNpemUpOwogICAgaWYgKGVyciAhPT0gdmFsaWRhdG9yLnZhbGlkYXRpb25FcnJvci5OT05FKQogICAgICAgIHJldHVybiBlcnI7CgogICAgdmFyIGtWZXJzaW9uU2l6ZXMgPSBbCiAgICAgIHt2ZXJzaW9uOiAwLCBudW1CeXRlczogMzJ9CiAgICBdOwogICAgZXJyID0gbWVzc2FnZVZhbGlkYXRvci52YWxpZGF0ZVN0cnVjdFZlcnNpb24ob2Zmc2V0LCBrVmVyc2lvblNpemVzKTsKICAgIGlmIChlcnIgIT09IHZhbGlkYXRvci52YWxpZGF0aW9uRXJyb3IuTk9ORSkKICAgICAgICByZXR1cm4gZXJyOwoKCiAgICAvLyB2YWxpZGF0ZSBNZWRpYVJvdXRlcl9PblByZXNlbnRhdGlvbkNvbm5lY3Rpb25DbG9zZWRfUGFyYW1zLnJvdXRlSWQKICAgIGVyciA9IG1lc3NhZ2VWYWxpZGF0b3IudmFsaWRhdGVTdHJpbmdQb2ludGVyKG9mZnNldCArIGNvZGVjLmtTdHJ1Y3RIZWFkZXJTaXplICsgMCwgZmFsc2UpCiAgICBpZiAoZXJyICE9PSB2YWxpZGF0b3IudmFsaWRhdGlvbkVycm9yLk5PTkUpCiAgICAgICAgcmV0dXJuIGVycjsKCgogICAgLy8gdmFsaWRhdGUgTWVkaWFSb3V0ZXJfT25QcmVzZW50YXRpb25Db25uZWN0aW9uQ2xvc2VkX1BhcmFtcy5yZWFzb24KICAgIGVyciA9IG1lc3NhZ2VWYWxpZGF0b3IudmFsaWRhdGVFbnVtKG9mZnNldCArIGNvZGVjLmtTdHJ1Y3RIZWFkZXJTaXplICsgOCwgTWVkaWFSb3V0ZXIuUHJlc2VudGF0aW9uQ29ubmVjdGlvbkNsb3NlUmVhc29uKTsKICAgIGlmIChlcnIgIT09IHZhbGlkYXRvci52YWxpZGF0aW9uRXJyb3IuTk9ORSkKICAgICAgICByZXR1cm4gZXJyOwoKCiAgICAvLyB2YWxpZGF0ZSBNZWRpYVJvdXRlcl9PblByZXNlbnRhdGlvbkNvbm5lY3Rpb25DbG9zZWRfUGFyYW1zLm1lc3NhZ2UKICAgIGVyciA9IG1lc3NhZ2VWYWxpZGF0b3IudmFsaWRhdGVTdHJpbmdQb2ludGVyKG9mZnNldCArIGNvZGVjLmtTdHJ1Y3RIZWFkZXJTaXplICsgMTYsIGZhbHNlKQogICAgaWYgKGVyciAhPT0gdmFsaWRhdG9yLnZhbGlkYXRpb25FcnJvci5OT05FKQogICAgICAgIHJldHVybiBlcnI7CgogICAgcmV0dXJuIHZhbGlkYXRvci52YWxpZGF0aW9uRXJyb3IuTk9ORTsKICB9OwoKICBNZWRpYVJvdXRlcl9PblByZXNlbnRhdGlvbkNvbm5lY3Rpb25DbG9zZWRfUGFyYW1zLmVuY29kZWRTaXplID0gY29kZWMua1N0cnVjdEhlYWRlclNpemUgKyAyNDsKCiAgTWVkaWFSb3V0ZXJfT25QcmVzZW50YXRpb25Db25uZWN0aW9uQ2xvc2VkX1BhcmFtcy5kZWNvZGUgPSBmdW5jdGlvbihkZWNvZGVyKSB7CiAgICB2YXIgcGFja2VkOwogICAgdmFyIHZhbCA9IG5ldyBNZWRpYVJvdXRlcl9PblByZXNlbnRhdGlvbkNvbm5lY3Rpb25DbG9zZWRfUGFyYW1zKCk7CiAgICB2YXIgbnVtYmVyT2ZCeXRlcyA9IGRlY29kZXIucmVhZFVpbnQzMigpOwogICAgdmFyIHZlcnNpb24gPSBkZWNvZGVyLnJlYWRVaW50MzIoKTsKICAgIHZhbC5yb3V0ZUlkID0gZGVjb2Rlci5kZWNvZGVTdHJ1Y3QoY29kZWMuU3RyaW5nKTsKICAgIHZhbC5yZWFzb24gPSBkZWNvZGVyLmRlY29kZVN0cnVjdChjb2RlYy5JbnQzMik7CiAgICBkZWNvZGVyLnNraXAoMSk7CiAgICBkZWNvZGVyLnNraXAoMSk7CiAgICBkZWNvZGVyLnNraXAoMSk7CiAgICBkZWNvZGVyLnNraXAoMSk7CiAgICB2YWwubWVzc2FnZSA9IGRlY29kZXIuZGVjb2RlU3RydWN0KGNvZGVjLlN0cmluZyk7CiAgICByZXR1cm4gdmFsOwogIH07CgogIE1lZGlhUm91dGVyX09uUHJlc2VudGF0aW9uQ29ubmVjdGlvbkNsb3NlZF9QYXJhbXMuZW5jb2RlID0gZnVuY3Rpb24oZW5jb2RlciwgdmFsKSB7CiAgICB2YXIgcGFja2VkOwogICAgZW5jb2Rlci53cml0ZVVpbnQzMihNZWRpYVJvdXRlcl9PblByZXNlbnRhdGlvbkNvbm5lY3Rpb25DbG9zZWRfUGFyYW1zLmVuY29kZWRTaXplKTsKICAgIGVuY29kZXIud3JpdGVVaW50MzIoMCk7CiAgICBlbmNvZGVyLmVuY29kZVN0cnVjdChjb2RlYy5TdHJpbmcsIHZhbC5yb3V0ZUlkKTsKICAgIGVuY29kZXIuZW5jb2RlU3RydWN0KGNvZGVjLkludDMyLCB2YWwucmVhc29uKTsKICAgIGVuY29kZXIuc2tpcCgxKTsKICAgIGVuY29kZXIuc2tpcCgxKTsKICAgIGVuY29kZXIuc2tpcCgxKTsKICAgIGVuY29kZXIuc2tpcCgxKTsKICAgIGVuY29kZXIuZW5jb2RlU3RydWN0KGNvZGVjLlN0cmluZywgdmFsLm1lc3NhZ2UpOwogIH07CiAgZnVuY3Rpb24gTWVkaWFSb3V0ZXJfT25Sb3V0ZU1lc3NhZ2VzUmVjZWl2ZWRfUGFyYW1zKHZhbHVlcykgewogICAgdGhpcy5pbml0RGVmYXVsdHNfKCk7CiAgICB0aGlzLmluaXRGaWVsZHNfKHZhbHVlcyk7CiAgfQoKCiAgTWVkaWFSb3V0ZXJfT25Sb3V0ZU1lc3NhZ2VzUmVjZWl2ZWRfUGFyYW1zLnByb3RvdHlwZS5pbml0RGVmYXVsdHNfID0gZnVuY3Rpb24oKSB7CiAgICB0aGlzLnJvdXRlSWQgPSBudWxsOwogICAgdGhpcy5tZXNzYWdlcyA9IG51bGw7CiAgfTsKICBNZWRpYVJvdXRlcl9PblJvdXRlTWVzc2FnZXNSZWNlaXZlZF9QYXJhbXMucHJvdG90eXBlLmluaXRGaWVsZHNfID0gZnVuY3Rpb24oZmllbGRzKSB7CiAgICBmb3IodmFyIGZpZWxkIGluIGZpZWxkcykgewogICAgICAgIGlmICh0aGlzLmhhc093blByb3BlcnR5KGZpZWxkKSkKICAgICAgICAgIHRoaXNbZmllbGRdID0gZmllbGRzW2ZpZWxkXTsKICAgIH0KICB9OwoKICBNZWRpYVJvdXRlcl9PblJvdXRlTWVzc2FnZXNSZWNlaXZlZF9QYXJhbXMudmFsaWRhdGUgPSBmdW5jdGlvbihtZXNzYWdlVmFsaWRhdG9yLCBvZmZzZXQpIHsKICAgIHZhciBlcnI7CiAgICBlcnIgPSBtZXNzYWdlVmFsaWRhdG9yLnZhbGlkYXRlU3RydWN0SGVhZGVyKG9mZnNldCwgY29kZWMua1N0cnVjdEhlYWRlclNpemUpOwogICAgaWYgKGVyciAhPT0gdmFsaWRhdG9yLnZhbGlkYXRpb25FcnJvci5OT05FKQogICAgICAgIHJldHVybiBlcnI7CgogICAgdmFyIGtWZXJzaW9uU2l6ZXMgPSBbCiAgICAgIHt2ZXJzaW9uOiAwLCBudW1CeXRlczogMjR9CiAgICBdOwogICAgZXJyID0gbWVzc2FnZVZhbGlkYXRvci52YWxpZGF0ZVN0cnVjdFZlcnNpb24ob2Zmc2V0LCBrVmVyc2lvblNpemVzKTsKICAgIGlmIChlcnIgIT09IHZhbGlkYXRvci52YWxpZGF0aW9uRXJyb3IuTk9ORSkKICAgICAgICByZXR1cm4gZXJyOwoKCiAgICAvLyB2YWxpZGF0ZSBNZWRpYVJvdXRlcl9PblJvdXRlTWVzc2FnZXNSZWNlaXZlZF9QYXJhbXMucm91dGVJZAogICAgZXJyID0gbWVzc2FnZVZhbGlkYXRvci52YWxpZGF0ZVN0cmluZ1BvaW50ZXIob2Zmc2V0ICsgY29kZWMua1N0cnVjdEhlYWRlclNpemUgKyAwLCBmYWxzZSkKICAgIGlmIChlcnIgIT09IHZhbGlkYXRvci52YWxpZGF0aW9uRXJyb3IuTk9ORSkKICAgICAgICByZXR1cm4gZXJyOwoKCiAgICAvLyB2YWxpZGF0ZSBNZWRpYVJvdXRlcl9PblJvdXRlTWVzc2FnZXNSZWNlaXZlZF9QYXJhbXMubWVzc2FnZXMKICAgIGVyciA9IG1lc3NhZ2VWYWxpZGF0b3IudmFsaWRhdGVBcnJheVBvaW50ZXIob2Zmc2V0ICsgY29kZWMua1N0cnVjdEhlYWRlclNpemUgKyA4LCA4LCBuZXcgY29kZWMuUG9pbnRlclRvKFJvdXRlTWVzc2FnZSksIGZhbHNlLCBbMF0sIDApOwogICAgaWYgKGVyciAhPT0gdmFsaWRhdG9yLnZhbGlkYXRpb25FcnJvci5OT05FKQogICAgICAgIHJldHVybiBlcnI7CgogICAgcmV0dXJuIHZhbGlkYXRvci52YWxpZGF0aW9uRXJyb3IuTk9ORTsKICB9OwoKICBNZWRpYVJvdXRlcl9PblJvdXRlTWVzc2FnZXNSZWNlaXZlZF9QYXJhbXMuZW5jb2RlZFNpemUgPSBjb2RlYy5rU3RydWN0SGVhZGVyU2l6ZSArIDE2OwoKICBNZWRpYVJvdXRlcl9PblJvdXRlTWVzc2FnZXNSZWNlaXZlZF9QYXJhbXMuZGVjb2RlID0gZnVuY3Rpb24oZGVjb2RlcikgewogICAgdmFyIHBhY2tlZDsKICAgIHZhciB2YWwgPSBuZXcgTWVkaWFSb3V0ZXJfT25Sb3V0ZU1lc3NhZ2VzUmVjZWl2ZWRfUGFyYW1zKCk7CiAgICB2YXIgbnVtYmVyT2ZCeXRlcyA9IGRlY29kZXIucmVhZFVpbnQzMigpOwogICAgdmFyIHZlcnNpb24gPSBkZWNvZGVyLnJlYWRVaW50MzIoKTsKICAgIHZhbC5yb3V0ZUlkID0gZGVjb2Rlci5kZWNvZGVTdHJ1Y3QoY29kZWMuU3RyaW5nKTsKICAgIHZhbC5tZXNzYWdlcyA9IGRlY29kZXIuZGVjb2RlQXJyYXlQb2ludGVyKG5ldyBjb2RlYy5Qb2ludGVyVG8oUm91dGVNZXNzYWdlKSk7CiAgICByZXR1cm4gdmFsOwogIH07CgogIE1lZGlhUm91dGVyX09uUm91dGVNZXNzYWdlc1JlY2VpdmVkX1BhcmFtcy5lbmNvZGUgPSBmdW5jdGlvbihlbmNvZGVyLCB2YWwpIHsKICAgIHZhciBwYWNrZWQ7CiAgICBlbmNvZGVyLndyaXRlVWludDMyKE1lZGlhUm91dGVyX09uUm91dGVNZXNzYWdlc1JlY2VpdmVkX1BhcmFtcy5lbmNvZGVkU2l6ZSk7CiAgICBlbmNvZGVyLndyaXRlVWludDMyKDApOwogICAgZW5jb2Rlci5lbmNvZGVTdHJ1Y3QoY29kZWMuU3RyaW5nLCB2YWwucm91dGVJZCk7CiAgICBlbmNvZGVyLmVuY29kZUFycmF5UG9pbnRlcihuZXcgY29kZWMuUG9pbnRlclRvKFJvdXRlTWVzc2FnZSksIHZhbC5tZXNzYWdlcyk7CiAgfTsKICBmdW5jdGlvbiBNZWRpYVJvdXRlcl9Pbk1lZGlhUmVtb3RlckNyZWF0ZWRfUGFyYW1zKHZhbHVlcykgewogICAgdGhpcy5pbml0RGVmYXVsdHNfKCk7CiAgICB0aGlzLmluaXRGaWVsZHNfKHZhbHVlcyk7CiAgfQoKCiAgTWVkaWFSb3V0ZXJfT25NZWRpYVJlbW90ZXJDcmVhdGVkX1BhcmFtcy5wcm90b3R5cGUuaW5pdERlZmF1bHRzXyA9IGZ1bmN0aW9uKCkgewogICAgdGhpcy50YWJJZCA9IDA7CiAgICB0aGlzLnJlbW90ZXIgPSBuZXcgbWlycm9yX3NlcnZpY2VfcmVtb3RpbmckLk1pcnJvclNlcnZpY2VSZW1vdGVyUHRyKCk7CiAgICB0aGlzLnJlbW90aW5nU291cmNlID0gbmV3IGJpbmRpbmdzLkludGVyZmFjZVJlcXVlc3QoKTsKICB9OwogIE1lZGlhUm91dGVyX09uTWVkaWFSZW1vdGVyQ3JlYXRlZF9QYXJhbXMucHJvdG90eXBlLmluaXRGaWVsZHNfID0gZnVuY3Rpb24oZmllbGRzKSB7CiAgICBmb3IodmFyIGZpZWxkIGluIGZpZWxkcykgewogICAgICAgIGlmICh0aGlzLmhhc093blByb3BlcnR5KGZpZWxkKSkKICAgICAgICAgIHRoaXNbZmllbGRdID0gZmllbGRzW2ZpZWxkXTsKICAgIH0KICB9OwoKICBNZWRpYVJvdXRlcl9Pbk1lZGlhUmVtb3RlckNyZWF0ZWRfUGFyYW1zLnZhbGlkYXRlID0gZnVuY3Rpb24obWVzc2FnZVZhbGlkYXRvciwgb2Zmc2V0KSB7CiAgICB2YXIgZXJyOwogICAgZXJyID0gbWVzc2FnZVZhbGlkYXRvci52YWxpZGF0ZVN0cnVjdEhlYWRlcihvZmZzZXQsIGNvZGVjLmtTdHJ1Y3RIZWFkZXJTaXplKTsKICAgIGlmIChlcnIgIT09IHZhbGlkYXRvci52YWxpZGF0aW9uRXJyb3IuTk9ORSkKICAgICAgICByZXR1cm4gZXJyOwoKICAgIHZhciBrVmVyc2lvblNpemVzID0gWwogICAgICB7dmVyc2lvbjogMCwgbnVtQnl0ZXM6IDI0fQogICAgXTsKICAgIGVyciA9IG1lc3NhZ2VWYWxpZGF0b3IudmFsaWRhdGVTdHJ1Y3RWZXJzaW9uKG9mZnNldCwga1ZlcnNpb25TaXplcyk7CiAgICBpZiAoZXJyICE9PSB2YWxpZGF0b3IudmFsaWRhdGlvbkVycm9yLk5PTkUpCiAgICAgICAgcmV0dXJuIGVycjsKCgoKICAgIC8vIHZhbGlkYXRlIE1lZGlhUm91dGVyX09uTWVkaWFSZW1vdGVyQ3JlYXRlZF9QYXJhbXMucmVtb3RlcgogICAgZXJyID0gbWVzc2FnZVZhbGlkYXRvci52YWxpZGF0ZUludGVyZmFjZShvZmZzZXQgKyBjb2RlYy5rU3RydWN0SGVhZGVyU2l6ZSArIDQsIGZhbHNlKTsKICAgIGlmIChlcnIgIT09IHZhbGlkYXRvci52YWxpZGF0aW9uRXJyb3IuTk9ORSkKICAgICAgICByZXR1cm4gZXJyOwoKCiAgICAvLyB2YWxpZGF0ZSBNZWRpYVJvdXRlcl9Pbk1lZGlhUmVtb3RlckNyZWF0ZWRfUGFyYW1zLnJlbW90aW5nU291cmNlCiAgICBlcnIgPSBtZXNzYWdlVmFsaWRhdG9yLnZhbGlkYXRlSW50ZXJmYWNlUmVxdWVzdChvZmZzZXQgKyBjb2RlYy5rU3RydWN0SGVhZGVyU2l6ZSArIDEyLCBmYWxzZSkKICAgIGlmIChlcnIgIT09IHZhbGlkYXRvci52YWxpZGF0aW9uRXJyb3IuTk9ORSkKICAgICAgICByZXR1cm4gZXJyOwoKICAgIHJldHVybiB2YWxpZGF0b3IudmFsaWRhdGlvbkVycm9yLk5PTkU7CiAgfTsKCiAgTWVkaWFSb3V0ZXJfT25NZWRpYVJlbW90ZXJDcmVhdGVkX1BhcmFtcy5lbmNvZGVkU2l6ZSA9IGNvZGVjLmtTdHJ1Y3RIZWFkZXJTaXplICsgMTY7CgogIE1lZGlhUm91dGVyX09uTWVkaWFSZW1vdGVyQ3JlYXRlZF9QYXJhbXMuZGVjb2RlID0gZnVuY3Rpb24oZGVjb2RlcikgewogICAgdmFyIHBhY2tlZDsKICAgIHZhciB2YWwgPSBuZXcgTWVkaWFSb3V0ZXJfT25NZWRpYVJlbW90ZXJDcmVhdGVkX1BhcmFtcygpOwogICAgdmFyIG51bWJlck9mQnl0ZXMgPSBkZWNvZGVyLnJlYWRVaW50MzIoKTsKICAgIHZhciB2ZXJzaW9uID0gZGVjb2Rlci5yZWFkVWludDMyKCk7CiAgICB2YWwudGFiSWQgPSBkZWNvZGVyLmRlY29kZVN0cnVjdChjb2RlYy5JbnQzMik7CiAgICB2YWwucmVtb3RlciA9IGRlY29kZXIuZGVjb2RlU3RydWN0KG5ldyBjb2RlYy5JbnRlcmZhY2UobWlycm9yX3NlcnZpY2VfcmVtb3RpbmckLk1pcnJvclNlcnZpY2VSZW1vdGVyUHRyKSk7CiAgICB2YWwucmVtb3RpbmdTb3VyY2UgPSBkZWNvZGVyLmRlY29kZVN0cnVjdChjb2RlYy5JbnRlcmZhY2VSZXF1ZXN0KTsKICAgIHJldHVybiB2YWw7CiAgfTsKCiAgTWVkaWFSb3V0ZXJfT25NZWRpYVJlbW90ZXJDcmVhdGVkX1BhcmFtcy5lbmNvZGUgPSBmdW5jdGlvbihlbmNvZGVyLCB2YWwpIHsKICAgIHZhciBwYWNrZWQ7CiAgICBlbmNvZGVyLndyaXRlVWludDMyKE1lZGlhUm91dGVyX09uTWVkaWFSZW1vdGVyQ3JlYXRlZF9QYXJhbXMuZW5jb2RlZFNpemUpOwogICAgZW5jb2Rlci53cml0ZVVpbnQzMigwKTsKICAgIGVuY29kZXIuZW5jb2RlU3RydWN0KGNvZGVjLkludDMyLCB2YWwudGFiSWQpOwogICAgZW5jb2Rlci5lbmNvZGVTdHJ1Y3QobmV3IGNvZGVjLkludGVyZmFjZShtaXJyb3Jfc2VydmljZV9yZW1vdGluZyQuTWlycm9yU2VydmljZVJlbW90ZXJQdHIpLCB2YWwucmVtb3Rlcik7CiAgICBlbmNvZGVyLmVuY29kZVN0cnVjdChjb2RlYy5JbnRlcmZhY2VSZXF1ZXN0LCB2YWwucmVtb3RpbmdTb3VyY2UpOwogIH07CgogIGZ1bmN0aW9uIE1lZGlhU2lua0V4dHJhRGF0YSh2YWx1ZSkgewogICAgdGhpcy5pbml0RGVmYXVsdF8oKTsKICAgIHRoaXMuaW5pdFZhbHVlXyh2YWx1ZSk7CiAgfQogIAogIAogIE1lZGlhU2lua0V4dHJhRGF0YS5UYWdzID0gewogICAgZGlhbE1lZGlhU2luazogMCwKICAgIGNhc3RNZWRpYVNpbms6IDEsCiAgfTsKICAKICBNZWRpYVNpbmtFeHRyYURhdGEucHJvdG90eXBlLmluaXREZWZhdWx0XyA9IGZ1bmN0aW9uKCkgewogICAgdGhpcy4kZGF0YSA9IG51bGw7CiAgICB0aGlzLiR0YWcgPSB1bmRlZmluZWQ7CiAgfQogIAogIE1lZGlhU2lua0V4dHJhRGF0YS5wcm90b3R5cGUuaW5pdFZhbHVlXyA9IGZ1bmN0aW9uKHZhbHVlKSB7CiAgICBpZiAodmFsdWUgPT0gdW5kZWZpbmVkKSB7CiAgICAgIHJldHVybjsKICAgIH0KICAKICAgIHZhciBrZXlzID0gT2JqZWN0LmtleXModmFsdWUpOwogICAgaWYgKGtleXMubGVuZ3RoID09IDApIHsKICAgICAgcmV0dXJuOwogICAgfQogIAogICAgaWYgKGtleXMubGVuZ3RoID4gMSkgewogICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCJZb3UgbWF5IHNldCBvbmx5IG9uZSBtZW1iZXIgb24gYSB1bmlvbi4iKTsKICAgIH0KICAKICAgIHZhciBmaWVsZHMgPSBbCiAgICAgICAgImRpYWxNZWRpYVNpbmsiLAogICAgICAgICJjYXN0TWVkaWFTaW5rIiwKICAgIF07CiAgCiAgICBpZiAoZmllbGRzLmluZGV4T2Yoa2V5c1swXSkgPCAwKSB7CiAgICAgIHRocm93IG5ldyBSZWZlcmVuY2VFcnJvcihrZXlzWzBdICsgIiBpcyBub3QgYSBNZWRpYVNpbmtFeHRyYURhdGEgbWVtYmVyLiIpOwogIAogICAgfQogIAogICAgdGhpc1trZXlzWzBdXSA9IHZhbHVlW2tleXNbMF1dOwogIH0KICBPYmplY3QuZGVmaW5lUHJvcGVydHkoTWVkaWFTaW5rRXh0cmFEYXRhLnByb3RvdHlwZSwgImRpYWxNZWRpYVNpbmsiLCB7CiAgICBnZXQ6IGZ1bmN0aW9uKCkgewogICAgICBpZiAodGhpcy4kdGFnICE9IE1lZGlhU2lua0V4dHJhRGF0YS5UYWdzLmRpYWxNZWRpYVNpbmspIHsKICAgICAgICB0aHJvdyBuZXcgUmVmZXJlbmNlRXJyb3IoCiAgICAgICAgICAgICJNZWRpYVNpbmtFeHRyYURhdGEuZGlhbE1lZGlhU2luayBpcyBub3QgY3VycmVudGx5IHNldC4iKTsKICAgICAgfQogICAgICByZXR1cm4gdGhpcy4kZGF0YTsKICAgIH0sCiAgCiAgICBzZXQ6IGZ1bmN0aW9uKHZhbHVlKSB7CiAgICAgIHRoaXMuJHRhZyA9IE1lZGlhU2lua0V4dHJhRGF0YS5UYWdzLmRpYWxNZWRpYVNpbms7CiAgICAgIHRoaXMuJGRhdGEgPSB2YWx1ZTsKICAgIH0KICB9KTsKICBPYmplY3QuZGVmaW5lUHJvcGVydHkoTWVkaWFTaW5rRXh0cmFEYXRhLnByb3RvdHlwZSwgImNhc3RNZWRpYVNpbmsiLCB7CiAgICBnZXQ6IGZ1bmN0aW9uKCkgewogICAgICBpZiAodGhpcy4kdGFnICE9IE1lZGlhU2lua0V4dHJhRGF0YS5UYWdzLmNhc3RNZWRpYVNpbmspIHsKICAgICAgICB0aHJvdyBuZXcgUmVmZXJlbmNlRXJyb3IoCiAgICAgICAgICAgICJNZWRpYVNpbmtFeHRyYURhdGEuY2FzdE1lZGlhU2luayBpcyBub3QgY3VycmVudGx5IHNldC4iKTsKICAgICAgfQogICAgICByZXR1cm4gdGhpcy4kZGF0YTsKICAgIH0sCiAgCiAgICBzZXQ6IGZ1bmN0aW9uKHZhbHVlKSB7CiAgICAgIHRoaXMuJHRhZyA9IE1lZGlhU2lua0V4dHJhRGF0YS5UYWdzLmNhc3RNZWRpYVNpbms7CiAgICAgIHRoaXMuJGRhdGEgPSB2YWx1ZTsKICAgIH0KICB9KTsKICAKICAKICAgIE1lZGlhU2lua0V4dHJhRGF0YS5lbmNvZGUgPSBmdW5jdGlvbihlbmNvZGVyLCB2YWwpIHsKICAgICAgaWYgKHZhbCA9PSBudWxsKSB7CiAgICAgICAgZW5jb2Rlci53cml0ZVVpbnQ2NCgwKTsKICAgICAgICBlbmNvZGVyLndyaXRlVWludDY0KDApOwogICAgICAgIHJldHVybjsKICAgICAgfQogICAgICBpZiAodmFsLiR0YWcgPT0gdW5kZWZpbmVkKSB7CiAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcigiQ2Fubm90IGVuY29kZSB1bmlvbnMgd2l0aCBhbiB1bmtub3duIG1lbWJlciBzZXQuIik7CiAgICAgIH0KICAgIAogICAgICBlbmNvZGVyLndyaXRlVWludDMyKDE2KTsKICAgICAgZW5jb2Rlci53cml0ZVVpbnQzMih2YWwuJHRhZyk7CiAgICAgIHN3aXRjaCAodmFsLiR0YWcpIHsKICAgICAgICBjYXNlIE1lZGlhU2lua0V4dHJhRGF0YS5UYWdzLmRpYWxNZWRpYVNpbms6CiAgICAgICAgICBlbmNvZGVyLmVuY29kZVN0cnVjdFBvaW50ZXIoRGlhbE1lZGlhU2luaywgdmFsLmRpYWxNZWRpYVNpbmspOwogICAgICAgICAgYnJlYWs7CiAgICAgICAgY2FzZSBNZWRpYVNpbmtFeHRyYURhdGEuVGFncy5jYXN0TWVkaWFTaW5rOgogICAgICAgICAgZW5jb2Rlci5lbmNvZGVTdHJ1Y3RQb2ludGVyKENhc3RNZWRpYVNpbmssIHZhbC5jYXN0TWVkaWFTaW5rKTsKICAgICAgICAgIGJyZWFrOwogICAgICB9CiAgICAgIGVuY29kZXIuYWxpZ24oKTsKICAgIH07CiAgCiAgCiAgICBNZWRpYVNpbmtFeHRyYURhdGEuZGVjb2RlID0gZnVuY3Rpb24oZGVjb2RlcikgewogICAgICB2YXIgc2l6ZSA9IGRlY29kZXIucmVhZFVpbnQzMigpOwogICAgICBpZiAoc2l6ZSA9PSAwKSB7CiAgICAgICAgZGVjb2Rlci5yZWFkVWludDMyKCk7CiAgICAgICAgZGVjb2Rlci5yZWFkVWludDY0KCk7CiAgICAgICAgcmV0dXJuIG51bGw7CiAgICAgIH0KICAgIAogICAgICB2YXIgcmVzdWx0ID0gbmV3IE1lZGlhU2lua0V4dHJhRGF0YSgpOwogICAgICB2YXIgdGFnID0gZGVjb2Rlci5yZWFkVWludDMyKCk7CiAgICAgIHN3aXRjaCAodGFnKSB7CiAgICAgICAgY2FzZSBNZWRpYVNpbmtFeHRyYURhdGEuVGFncy5kaWFsTWVkaWFTaW5rOgogICAgICAgICAgcmVzdWx0LmRpYWxNZWRpYVNpbmsgPSBkZWNvZGVyLmRlY29kZVN0cnVjdFBvaW50ZXIoRGlhbE1lZGlhU2luayk7CiAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIE1lZGlhU2lua0V4dHJhRGF0YS5UYWdzLmNhc3RNZWRpYVNpbms6CiAgICAgICAgICByZXN1bHQuY2FzdE1lZGlhU2luayA9IGRlY29kZXIuZGVjb2RlU3RydWN0UG9pbnRlcihDYXN0TWVkaWFTaW5rKTsKICAgICAgICAgIGJyZWFrOwogICAgICB9CiAgICAgIGRlY29kZXIuYWxpZ24oKTsKICAgIAogICAgICByZXR1cm4gcmVzdWx0OwogICAgfTsKICAKICAKICAgIE1lZGlhU2lua0V4dHJhRGF0YS52YWxpZGF0ZSA9IGZ1bmN0aW9uKG1lc3NhZ2VWYWxpZGF0b3IsIG9mZnNldCkgewogICAgICB2YXIgc2l6ZSA9IG1lc3NhZ2VWYWxpZGF0b3IuZGVjb2RlVW5pb25TaXplKG9mZnNldCk7CiAgICAgIGlmIChzaXplICE9IDE2KSB7CiAgICAgICAgcmV0dXJuIHZhbGlkYXRvci52YWxpZGF0aW9uRXJyb3IuSU5WQUxJRF9VTklPTl9TSVpFOwogICAgICB9CiAgICAKICAgICAgdmFyIHRhZyA9IG1lc3NhZ2VWYWxpZGF0b3IuZGVjb2RlVW5pb25UYWcob2Zmc2V0KTsKICAgICAgdmFyIGRhdGFfb2Zmc2V0ID0gb2Zmc2V0ICsgODsKICAgICAgdmFyIGVycjsKICAgICAgc3dpdGNoICh0YWcpIHsKICAgICAgICBjYXNlIE1lZGlhU2lua0V4dHJhRGF0YS5UYWdzLmRpYWxNZWRpYVNpbms6CiAgICAgICAgICAKICAgIAogICAgLy8gdmFsaWRhdGUgTWVkaWFTaW5rRXh0cmFEYXRhLmRpYWxNZWRpYVNpbmsKICAgIGVyciA9IG1lc3NhZ2VWYWxpZGF0b3IudmFsaWRhdGVTdHJ1Y3RQb2ludGVyKGRhdGFfb2Zmc2V0LCBEaWFsTWVkaWFTaW5rLCBmYWxzZSk7CiAgICBpZiAoZXJyICE9PSB2YWxpZGF0b3IudmFsaWRhdGlvbkVycm9yLk5PTkUpCiAgICAgICAgcmV0dXJuIGVycjsKICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgTWVkaWFTaW5rRXh0cmFEYXRhLlRhZ3MuY2FzdE1lZGlhU2luazoKICAgICAgICAgIAogICAgCiAgICAvLyB2YWxpZGF0ZSBNZWRpYVNpbmtFeHRyYURhdGEuY2FzdE1lZGlhU2luawogICAgZXJyID0gbWVzc2FnZVZhbGlkYXRvci52YWxpZGF0ZVN0cnVjdFBvaW50ZXIoZGF0YV9vZmZzZXQsIENhc3RNZWRpYVNpbmssIGZhbHNlKTsKICAgIGlmIChlcnIgIT09IHZhbGlkYXRvci52YWxpZGF0aW9uRXJyb3IuTk9ORSkKICAgICAgICByZXR1cm4gZXJyOwogICAgICAgICAgYnJlYWs7CiAgICAgIH0KICAgIAogICAgICByZXR1cm4gdmFsaWRhdG9yLnZhbGlkYXRpb25FcnJvci5OT05FOwogICAgfTsKICAKICBNZWRpYVNpbmtFeHRyYURhdGEuZW5jb2RlZFNpemUgPSAxNjsKICB2YXIga01lZGlhUm91dGVQcm92aWRlcl9DcmVhdGVSb3V0ZV9OYW1lID0gODI0MTU0NDQyOwogIHZhciBrTWVkaWFSb3V0ZVByb3ZpZGVyX0pvaW5Sb3V0ZV9OYW1lID0gMzk4NjMzNzA7CiAgdmFyIGtNZWRpYVJvdXRlUHJvdmlkZXJfQ29ubmVjdFJvdXRlQnlSb3V0ZUlkX05hbWUgPSAxOTg1NDgwNDgxOwogIHZhciBrTWVkaWFSb3V0ZVByb3ZpZGVyX1Rlcm1pbmF0ZVJvdXRlX05hbWUgPSAxNzM3NjI0NDk5OwogIHZhciBrTWVkaWFSb3V0ZVByb3ZpZGVyX1NlbmRSb3V0ZU1lc3NhZ2VfTmFtZSA9IDY4NzQ4OTU2MTsKICB2YXIga01lZGlhUm91dGVQcm92aWRlcl9TZW5kUm91dGVCaW5hcnlNZXNzYWdlX05hbWUgPSAxNDAzMzM1MDE1OwogIHZhciBrTWVkaWFSb3V0ZVByb3ZpZGVyX1N0YXJ0T2JzZXJ2aW5nTWVkaWFTaW5rc19OYW1lID0gMjA1MjM3NjA3NjsKICB2YXIga01lZGlhUm91dGVQcm92aWRlcl9TdG9wT2JzZXJ2aW5nTWVkaWFTaW5rc19OYW1lID0gMzY1MTUwMjU2OwogIHZhciBrTWVkaWFSb3V0ZVByb3ZpZGVyX1N0YXJ0T2JzZXJ2aW5nTWVkaWFSb3V0ZXNfTmFtZSA9IDE5ODY3Mjg1Mjc7CiAgdmFyIGtNZWRpYVJvdXRlUHJvdmlkZXJfU3RvcE9ic2VydmluZ01lZGlhUm91dGVzX05hbWUgPSA5MzA4NzM3MDsKICB2YXIga01lZGlhUm91dGVQcm92aWRlcl9TdGFydExpc3RlbmluZ0ZvclJvdXRlTWVzc2FnZXNfTmFtZSA9IDQ2MzQxMTQ1OTsKICB2YXIga01lZGlhUm91dGVQcm92aWRlcl9TdG9wTGlzdGVuaW5nRm9yUm91dGVNZXNzYWdlc19OYW1lID0gMTY4ODA4MDE0NTsKICB2YXIga01lZGlhUm91dGVQcm92aWRlcl9EZXRhY2hSb3V0ZV9OYW1lID0gNzA4MzgwMjY3OwogIHZhciBrTWVkaWFSb3V0ZVByb3ZpZGVyX0VuYWJsZU1kbnNEaXNjb3ZlcnlfTmFtZSA9IDEwNDIxNjMzMjA7CiAgdmFyIGtNZWRpYVJvdXRlUHJvdmlkZXJfVXBkYXRlTWVkaWFTaW5rc19OYW1lID0gNjE5ODM2MjM4OwogIHZhciBrTWVkaWFSb3V0ZVByb3ZpZGVyX1NlYXJjaFNpbmtzX05hbWUgPSAyMTE5MDM2OTAyOwogIHZhciBrTWVkaWFSb3V0ZVByb3ZpZGVyX1Byb3ZpZGVTaW5rc19OYW1lID0gNjMyMTQ5Mjk1OwogIHZhciBrTWVkaWFSb3V0ZVByb3ZpZGVyX0NyZWF0ZU1lZGlhUm91dGVDb250cm9sbGVyX05hbWUgPSAxNjA1NjU2Nzk3OwoKICBmdW5jdGlvbiBNZWRpYVJvdXRlUHJvdmlkZXJQdHIoaGFuZGxlT3JQdHJJbmZvKSB7CiAgICB0aGlzLnB0ciA9IG5ldyBiaW5kaW5ncy5JbnRlcmZhY2VQdHJDb250cm9sbGVyKE1lZGlhUm91dGVQcm92aWRlciwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaGFuZGxlT3JQdHJJbmZvKTsKICB9CgogIGZ1bmN0aW9uIE1lZGlhUm91dGVQcm92aWRlckFzc29jaWF0ZWRQdHIoYXNzb2NpYXRlZEludGVyZmFjZVB0ckluZm8pIHsKICAgIHRoaXMucHRyID0gbmV3IGFzc29jaWF0ZWRCaW5kaW5ncy5Bc3NvY2lhdGVkSW50ZXJmYWNlUHRyQ29udHJvbGxlcigKICAgICAgICBNZWRpYVJvdXRlUHJvdmlkZXIsIGFzc29jaWF0ZWRJbnRlcmZhY2VQdHJJbmZvKTsKICB9CgogIE1lZGlhUm91dGVQcm92aWRlckFzc29jaWF0ZWRQdHIucHJvdG90eXBlID0KICAgICAgT2JqZWN0LmNyZWF0ZShNZWRpYVJvdXRlUHJvdmlkZXJQdHIucHJvdG90eXBlKTsKICBNZWRpYVJvdXRlUHJvdmlkZXJBc3NvY2lhdGVkUHRyLnByb3RvdHlwZS5jb25zdHJ1Y3RvciA9CiAgICAgIE1lZGlhUm91dGVQcm92aWRlckFzc29jaWF0ZWRQdHI7CgogIGZ1bmN0aW9uIE1lZGlhUm91dGVQcm92aWRlclByb3h5KHJlY2VpdmVyKSB7CiAgICB0aGlzLnJlY2VpdmVyXyA9IHJlY2VpdmVyOwogIH0KICBNZWRpYVJvdXRlUHJvdmlkZXJQdHIucHJvdG90eXBlLmNyZWF0ZVJvdXRlID0gZnVuY3Rpb24oKSB7CiAgICByZXR1cm4gTWVkaWFSb3V0ZVByb3ZpZGVyUHJveHkucHJvdG90eXBlLmNyZWF0ZVJvdXRlCiAgICAgICAgLmFwcGx5KHRoaXMucHRyLmdldFByb3h5KCksIGFyZ3VtZW50cyk7CiAgfTsKCiAgTWVkaWFSb3V0ZVByb3ZpZGVyUHJveHkucHJvdG90eXBlLmNyZWF0ZVJvdXRlID0gZnVuY3Rpb24obWVkaWFTb3VyY2UsIHNpbmtJZCwgb3JpZ2luYWxQcmVzZW50YXRpb25JZCwgb3JpZ2luLCB0YWJJZCwgdGltZW91dCwgaW5jb2duaXRvKSB7CiAgICB2YXIgcGFyYW1zID0gbmV3IE1lZGlhUm91dGVQcm92aWRlcl9DcmVhdGVSb3V0ZV9QYXJhbXMoKTsKICAgIHBhcmFtcy5tZWRpYVNvdXJjZSA9IG1lZGlhU291cmNlOwogICAgcGFyYW1zLnNpbmtJZCA9IHNpbmtJZDsKICAgIHBhcmFtcy5vcmlnaW5hbFByZXNlbnRhdGlvbklkID0gb3JpZ2luYWxQcmVzZW50YXRpb25JZDsKICAgIHBhcmFtcy5vcmlnaW4gPSBvcmlnaW47CiAgICBwYXJhbXMudGFiSWQgPSB0YWJJZDsKICAgIHBhcmFtcy50aW1lb3V0ID0gdGltZW91dDsKICAgIHBhcmFtcy5pbmNvZ25pdG8gPSBpbmNvZ25pdG87CiAgICByZXR1cm4gbmV3IFByb21pc2UoZnVuY3Rpb24ocmVzb2x2ZSwgcmVqZWN0KSB7CiAgICAgIHZhciBidWlsZGVyID0gbmV3IGNvZGVjLk1lc3NhZ2VWMUJ1aWxkZXIoCiAgICAgICAgICBrTWVkaWFSb3V0ZVByb3ZpZGVyX0NyZWF0ZVJvdXRlX05hbWUsCiAgICAgICAgICBjb2RlYy5hbGlnbihNZWRpYVJvdXRlUHJvdmlkZXJfQ3JlYXRlUm91dGVfUGFyYW1zLmVuY29kZWRTaXplKSwKICAgICAgICAgIGNvZGVjLmtNZXNzYWdlRXhwZWN0c1Jlc3BvbnNlLCAwKTsKICAgICAgYnVpbGRlci5lbmNvZGVTdHJ1Y3QoTWVkaWFSb3V0ZVByb3ZpZGVyX0NyZWF0ZVJvdXRlX1BhcmFtcywgcGFyYW1zKTsKICAgICAgdmFyIG1lc3NhZ2UgPSBidWlsZGVyLmZpbmlzaCgpOwogICAgICB0aGlzLnJlY2VpdmVyXy5hY2NlcHRBbmRFeHBlY3RSZXNwb25zZShtZXNzYWdlKS50aGVuKGZ1bmN0aW9uKG1lc3NhZ2UpIHsKICAgICAgICB2YXIgcmVhZGVyID0gbmV3IGNvZGVjLk1lc3NhZ2VSZWFkZXIobWVzc2FnZSk7CiAgICAgICAgdmFyIHJlc3BvbnNlUGFyYW1zID0KICAgICAgICAgICAgcmVhZGVyLmRlY29kZVN0cnVjdChNZWRpYVJvdXRlUHJvdmlkZXJfQ3JlYXRlUm91dGVfUmVzcG9uc2VQYXJhbXMpOwogICAgICAgIHJlc29sdmUocmVzcG9uc2VQYXJhbXMpOwogICAgICB9KS5jYXRjaChmdW5jdGlvbihyZXN1bHQpIHsKICAgICAgICByZWplY3QoRXJyb3IoIkNvbm5lY3Rpb24gZXJyb3I6ICIgKyByZXN1bHQpKTsKICAgICAgfSk7CiAgICB9LmJpbmQodGhpcykpOwogIH07CiAgTWVkaWFSb3V0ZVByb3ZpZGVyUHRyLnByb3RvdHlwZS5qb2luUm91dGUgPSBmdW5jdGlvbigpIHsKICAgIHJldHVybiBNZWRpYVJvdXRlUHJvdmlkZXJQcm94eS5wcm90b3R5cGUuam9pblJvdXRlCiAgICAgICAgLmFwcGx5KHRoaXMucHRyLmdldFByb3h5KCksIGFyZ3VtZW50cyk7CiAgfTsKCiAgTWVkaWFSb3V0ZVByb3ZpZGVyUHJveHkucHJvdG90eXBlLmpvaW5Sb3V0ZSA9IGZ1bmN0aW9uKG1lZGlhU291cmNlLCBwcmVzZW50YXRpb25JZCwgb3JpZ2luLCB0YWJJZCwgdGltZW91dCwgaW5jb2duaXRvKSB7CiAgICB2YXIgcGFyYW1zID0gbmV3IE1lZGlhUm91dGVQcm92aWRlcl9Kb2luUm91dGVfUGFyYW1zKCk7CiAgICBwYXJhbXMubWVkaWFTb3VyY2UgPSBtZWRpYVNvdXJjZTsKICAgIHBhcmFtcy5wcmVzZW50YXRpb25JZCA9IHByZXNlbnRhdGlvbklkOwogICAgcGFyYW1zLm9yaWdpbiA9IG9yaWdpbjsKICAgIHBhcmFtcy50YWJJZCA9IHRhYklkOwogICAgcGFyYW1zLnRpbWVvdXQgPSB0aW1lb3V0OwogICAgcGFyYW1zLmluY29nbml0byA9IGluY29nbml0bzsKICAgIHJldHVybiBuZXcgUHJvbWlzZShmdW5jdGlvbihyZXNvbHZlLCByZWplY3QpIHsKICAgICAgdmFyIGJ1aWxkZXIgPSBuZXcgY29kZWMuTWVzc2FnZVYxQnVpbGRlcigKICAgICAgICAgIGtNZWRpYVJvdXRlUHJvdmlkZXJfSm9pblJvdXRlX05hbWUsCiAgICAgICAgICBjb2RlYy5hbGlnbihNZWRpYVJvdXRlUHJvdmlkZXJfSm9pblJvdXRlX1BhcmFtcy5lbmNvZGVkU2l6ZSksCiAgICAgICAgICBjb2RlYy5rTWVzc2FnZUV4cGVjdHNSZXNwb25zZSwgMCk7CiAgICAgIGJ1aWxkZXIuZW5jb2RlU3RydWN0KE1lZGlhUm91dGVQcm92aWRlcl9Kb2luUm91dGVfUGFyYW1zLCBwYXJhbXMpOwogICAgICB2YXIgbWVzc2FnZSA9IGJ1aWxkZXIuZmluaXNoKCk7CiAgICAgIHRoaXMucmVjZWl2ZXJfLmFjY2VwdEFuZEV4cGVjdFJlc3BvbnNlKG1lc3NhZ2UpLnRoZW4oZnVuY3Rpb24obWVzc2FnZSkgewogICAgICAgIHZhciByZWFkZXIgPSBuZXcgY29kZWMuTWVzc2FnZVJlYWRlcihtZXNzYWdlKTsKICAgICAgICB2YXIgcmVzcG9uc2VQYXJhbXMgPQogICAgICAgICAgICByZWFkZXIuZGVjb2RlU3RydWN0KE1lZGlhUm91dGVQcm92aWRlcl9Kb2luUm91dGVfUmVzcG9uc2VQYXJhbXMpOwogICAgICAgIHJlc29sdmUocmVzcG9uc2VQYXJhbXMpOwogICAgICB9KS5jYXRjaChmdW5jdGlvbihyZXN1bHQpIHsKICAgICAgICByZWplY3QoRXJyb3IoIkNvbm5lY3Rpb24gZXJyb3I6ICIgKyByZXN1bHQpKTsKICAgICAgfSk7CiAgICB9LmJpbmQodGhpcykpOwogIH07CiAgTWVkaWFSb3V0ZVByb3ZpZGVyUHRyLnByb3RvdHlwZS5jb25uZWN0Um91dGVCeVJvdXRlSWQgPSBmdW5jdGlvbigpIHsKICAgIHJldHVybiBNZWRpYVJvdXRlUHJvdmlkZXJQcm94eS5wcm90b3R5cGUuY29ubmVjdFJvdXRlQnlSb3V0ZUlkCiAgICAgICAgLmFwcGx5KHRoaXMucHRyLmdldFByb3h5KCksIGFyZ3VtZW50cyk7CiAgfTsKCiAgTWVkaWFSb3V0ZVByb3ZpZGVyUHJveHkucHJvdG90eXBlLmNvbm5lY3RSb3V0ZUJ5Um91dGVJZCA9IGZ1bmN0aW9uKG1lZGlhU291cmNlLCByb3V0ZUlkLCBwcmVzZW50YXRpb25JZCwgb3JpZ2luLCB0YWJJZCwgdGltZW91dCwgaW5jb2duaXRvKSB7CiAgICB2YXIgcGFyYW1zID0gbmV3IE1lZGlhUm91dGVQcm92aWRlcl9Db25uZWN0Um91dGVCeVJvdXRlSWRfUGFyYW1zKCk7CiAgICBwYXJhbXMubWVkaWFTb3VyY2UgPSBtZWRpYVNvdXJjZTsKICAgIHBhcmFtcy5yb3V0ZUlkID0gcm91dGVJZDsKICAgIHBhcmFtcy5wcmVzZW50YXRpb25JZCA9IHByZXNlbnRhdGlvbklkOwogICAgcGFyYW1zLm9yaWdpbiA9IG9yaWdpbjsKICAgIHBhcmFtcy50YWJJZCA9IHRhYklkOwogICAgcGFyYW1zLnRpbWVvdXQgPSB0aW1lb3V0OwogICAgcGFyYW1zLmluY29nbml0byA9IGluY29nbml0bzsKICAgIHJldHVybiBuZXcgUHJvbWlzZShmdW5jdGlvbihyZXNvbHZlLCByZWplY3QpIHsKICAgICAgdmFyIGJ1aWxkZXIgPSBuZXcgY29kZWMuTWVzc2FnZVYxQnVpbGRlcigKICAgICAgICAgIGtNZWRpYVJvdXRlUHJvdmlkZXJfQ29ubmVjdFJvdXRlQnlSb3V0ZUlkX05hbWUsCiAgICAgICAgICBjb2RlYy5hbGlnbihNZWRpYVJvdXRlUHJvdmlkZXJfQ29ubmVjdFJvdXRlQnlSb3V0ZUlkX1BhcmFtcy5lbmNvZGVkU2l6ZSksCiAgICAgICAgICBjb2RlYy5rTWVzc2FnZUV4cGVjdHNSZXNwb25zZSwgMCk7CiAgICAgIGJ1aWxkZXIuZW5jb2RlU3RydWN0KE1lZGlhUm91dGVQcm92aWRlcl9Db25uZWN0Um91dGVCeVJvdXRlSWRfUGFyYW1zLCBwYXJhbXMpOwogICAgICB2YXIgbWVzc2FnZSA9IGJ1aWxkZXIuZmluaXNoKCk7CiAgICAgIHRoaXMucmVjZWl2ZXJfLmFjY2VwdEFuZEV4cGVjdFJlc3BvbnNlKG1lc3NhZ2UpLnRoZW4oZnVuY3Rpb24obWVzc2FnZSkgewogICAgICAgIHZhciByZWFkZXIgPSBuZXcgY29kZWMuTWVzc2FnZVJlYWRlcihtZXNzYWdlKTsKICAgICAgICB2YXIgcmVzcG9uc2VQYXJhbXMgPQogICAgICAgICAgICByZWFkZXIuZGVjb2RlU3RydWN0KE1lZGlhUm91dGVQcm92aWRlcl9Db25uZWN0Um91dGVCeVJvdXRlSWRfUmVzcG9uc2VQYXJhbXMpOwogICAgICAgIHJlc29sdmUocmVzcG9uc2VQYXJhbXMpOwogICAgICB9KS5jYXRjaChmdW5jdGlvbihyZXN1bHQpIHsKICAgICAgICByZWplY3QoRXJyb3IoIkNvbm5lY3Rpb24gZXJyb3I6ICIgKyByZXN1bHQpKTsKICAgICAgfSk7CiAgICB9LmJpbmQodGhpcykpOwogIH07CiAgTWVkaWFSb3V0ZVByb3ZpZGVyUHRyLnByb3RvdHlwZS50ZXJtaW5hdGVSb3V0ZSA9IGZ1bmN0aW9uKCkgewogICAgcmV0dXJuIE1lZGlhUm91dGVQcm92aWRlclByb3h5LnByb3RvdHlwZS50ZXJtaW5hdGVSb3V0ZQogICAgICAgIC5hcHBseSh0aGlzLnB0ci5nZXRQcm94eSgpLCBhcmd1bWVudHMpOwogIH07CgogIE1lZGlhUm91dGVQcm92aWRlclByb3h5LnByb3RvdHlwZS50ZXJtaW5hdGVSb3V0ZSA9IGZ1bmN0aW9uKHJvdXRlSWQpIHsKICAgIHZhciBwYXJhbXMgPSBuZXcgTWVkaWFSb3V0ZVByb3ZpZGVyX1Rlcm1pbmF0ZVJvdXRlX1BhcmFtcygpOwogICAgcGFyYW1zLnJvdXRlSWQgPSByb3V0ZUlkOwogICAgcmV0dXJuIG5ldyBQcm9taXNlKGZ1bmN0aW9uKHJlc29sdmUsIHJlamVjdCkgewogICAgICB2YXIgYnVpbGRlciA9IG5ldyBjb2RlYy5NZXNzYWdlVjFCdWlsZGVyKAogICAgICAgICAga01lZGlhUm91dGVQcm92aWRlcl9UZXJtaW5hdGVSb3V0ZV9OYW1lLAogICAgICAgICAgY29kZWMuYWxpZ24oTWVkaWFSb3V0ZVByb3ZpZGVyX1Rlcm1pbmF0ZVJvdXRlX1BhcmFtcy5lbmNvZGVkU2l6ZSksCiAgICAgICAgICBjb2RlYy5rTWVzc2FnZUV4cGVjdHNSZXNwb25zZSwgMCk7CiAgICAgIGJ1aWxkZXIuZW5jb2RlU3RydWN0KE1lZGlhUm91dGVQcm92aWRlcl9UZXJtaW5hdGVSb3V0ZV9QYXJhbXMsIHBhcmFtcyk7CiAgICAgIHZhciBtZXNzYWdlID0gYnVpbGRlci5maW5pc2goKTsKICAgICAgdGhpcy5yZWNlaXZlcl8uYWNjZXB0QW5kRXhwZWN0UmVzcG9uc2UobWVzc2FnZSkudGhlbihmdW5jdGlvbihtZXNzYWdlKSB7CiAgICAgICAgdmFyIHJlYWRlciA9IG5ldyBjb2RlYy5NZXNzYWdlUmVhZGVyKG1lc3NhZ2UpOwogICAgICAgIHZhciByZXNwb25zZVBhcmFtcyA9CiAgICAgICAgICAgIHJlYWRlci5kZWNvZGVTdHJ1Y3QoTWVkaWFSb3V0ZVByb3ZpZGVyX1Rlcm1pbmF0ZVJvdXRlX1Jlc3BvbnNlUGFyYW1zKTsKICAgICAgICByZXNvbHZlKHJlc3BvbnNlUGFyYW1zKTsKICAgICAgfSkuY2F0Y2goZnVuY3Rpb24ocmVzdWx0KSB7CiAgICAgICAgcmVqZWN0KEVycm9yKCJDb25uZWN0aW9uIGVycm9yOiAiICsgcmVzdWx0KSk7CiAgICAgIH0pOwogICAgfS5iaW5kKHRoaXMpKTsKICB9OwogIE1lZGlhUm91dGVQcm92aWRlclB0ci5wcm90b3R5cGUuc2VuZFJvdXRlTWVzc2FnZSA9IGZ1bmN0aW9uKCkgewogICAgcmV0dXJuIE1lZGlhUm91dGVQcm92aWRlclByb3h5LnByb3RvdHlwZS5zZW5kUm91dGVNZXNzYWdlCiAgICAgICAgLmFwcGx5KHRoaXMucHRyLmdldFByb3h5KCksIGFyZ3VtZW50cyk7CiAgfTsKCiAgTWVkaWFSb3V0ZVByb3ZpZGVyUHJveHkucHJvdG90eXBlLnNlbmRSb3V0ZU1lc3NhZ2UgPSBmdW5jdGlvbihtZWRpYVJvdXRlSWQsIG1lc3NhZ2UpIHsKICAgIHZhciBwYXJhbXMgPSBuZXcgTWVkaWFSb3V0ZVByb3ZpZGVyX1NlbmRSb3V0ZU1lc3NhZ2VfUGFyYW1zKCk7CiAgICBwYXJhbXMubWVkaWFSb3V0ZUlkID0gbWVkaWFSb3V0ZUlkOwogICAgcGFyYW1zLm1lc3NhZ2UgPSBtZXNzYWdlOwogICAgcmV0dXJuIG5ldyBQcm9taXNlKGZ1bmN0aW9uKHJlc29sdmUsIHJlamVjdCkgewogICAgICB2YXIgYnVpbGRlciA9IG5ldyBjb2RlYy5NZXNzYWdlVjFCdWlsZGVyKAogICAgICAgICAga01lZGlhUm91dGVQcm92aWRlcl9TZW5kUm91dGVNZXNzYWdlX05hbWUsCiAgICAgICAgICBjb2RlYy5hbGlnbihNZWRpYVJvdXRlUHJvdmlkZXJfU2VuZFJvdXRlTWVzc2FnZV9QYXJhbXMuZW5jb2RlZFNpemUpLAogICAgICAgICAgY29kZWMua01lc3NhZ2VFeHBlY3RzUmVzcG9uc2UsIDApOwogICAgICBidWlsZGVyLmVuY29kZVN0cnVjdChNZWRpYVJvdXRlUHJvdmlkZXJfU2VuZFJvdXRlTWVzc2FnZV9QYXJhbXMsIHBhcmFtcyk7CiAgICAgIHZhciBtZXNzYWdlID0gYnVpbGRlci5maW5pc2goKTsKICAgICAgdGhpcy5yZWNlaXZlcl8uYWNjZXB0QW5kRXhwZWN0UmVzcG9uc2UobWVzc2FnZSkudGhlbihmdW5jdGlvbihtZXNzYWdlKSB7CiAgICAgICAgdmFyIHJlYWRlciA9IG5ldyBjb2RlYy5NZXNzYWdlUmVhZGVyKG1lc3NhZ2UpOwogICAgICAgIHZhciByZXNwb25zZVBhcmFtcyA9CiAgICAgICAgICAgIHJlYWRlci5kZWNvZGVTdHJ1Y3QoTWVkaWFSb3V0ZVByb3ZpZGVyX1NlbmRSb3V0ZU1lc3NhZ2VfUmVzcG9uc2VQYXJhbXMpOwogICAgICAgIHJlc29sdmUocmVzcG9uc2VQYXJhbXMpOwogICAgICB9KS5jYXRjaChmdW5jdGlvbihyZXN1bHQpIHsKICAgICAgICByZWplY3QoRXJyb3IoIkNvbm5lY3Rpb24gZXJyb3I6ICIgKyByZXN1bHQpKTsKICAgICAgfSk7CiAgICB9LmJpbmQodGhpcykpOwogIH07CiAgTWVkaWFSb3V0ZVByb3ZpZGVyUHRyLnByb3RvdHlwZS5zZW5kUm91dGVCaW5hcnlNZXNzYWdlID0gZnVuY3Rpb24oKSB7CiAgICByZXR1cm4gTWVkaWFSb3V0ZVByb3ZpZGVyUHJveHkucHJvdG90eXBlLnNlbmRSb3V0ZUJpbmFyeU1lc3NhZ2UKICAgICAgICAuYXBwbHkodGhpcy5wdHIuZ2V0UHJveHkoKSwgYXJndW1lbnRzKTsKICB9OwoKICBNZWRpYVJvdXRlUHJvdmlkZXJQcm94eS5wcm90b3R5cGUuc2VuZFJvdXRlQmluYXJ5TWVzc2FnZSA9IGZ1bmN0aW9uKG1lZGlhUm91dGVJZCwgZGF0YSkgewogICAgdmFyIHBhcmFtcyA9IG5ldyBNZWRpYVJvdXRlUHJvdmlkZXJfU2VuZFJvdXRlQmluYXJ5TWVzc2FnZV9QYXJhbXMoKTsKICAgIHBhcmFtcy5tZWRpYVJvdXRlSWQgPSBtZWRpYVJvdXRlSWQ7CiAgICBwYXJhbXMuZGF0YSA9IGRhdGE7CiAgICByZXR1cm4gbmV3IFByb21pc2UoZnVuY3Rpb24ocmVzb2x2ZSwgcmVqZWN0KSB7CiAgICAgIHZhciBidWlsZGVyID0gbmV3IGNvZGVjLk1lc3NhZ2VWMUJ1aWxkZXIoCiAgICAgICAgICBrTWVkaWFSb3V0ZVByb3ZpZGVyX1NlbmRSb3V0ZUJpbmFyeU1lc3NhZ2VfTmFtZSwKICAgICAgICAgIGNvZGVjLmFsaWduKE1lZGlhUm91dGVQcm92aWRlcl9TZW5kUm91dGVCaW5hcnlNZXNzYWdlX1BhcmFtcy5lbmNvZGVkU2l6ZSksCiAgICAgICAgICBjb2RlYy5rTWVzc2FnZUV4cGVjdHNSZXNwb25zZSwgMCk7CiAgICAgIGJ1aWxkZXIuZW5jb2RlU3RydWN0KE1lZGlhUm91dGVQcm92aWRlcl9TZW5kUm91dGVCaW5hcnlNZXNzYWdlX1BhcmFtcywgcGFyYW1zKTsKICAgICAgdmFyIG1lc3NhZ2UgPSBidWlsZGVyLmZpbmlzaCgpOwogICAgICB0aGlzLnJlY2VpdmVyXy5hY2NlcHRBbmRFeHBlY3RSZXNwb25zZShtZXNzYWdlKS50aGVuKGZ1bmN0aW9uKG1lc3NhZ2UpIHsKICAgICAgICB2YXIgcmVhZGVyID0gbmV3IGNvZGVjLk1lc3NhZ2VSZWFkZXIobWVzc2FnZSk7CiAgICAgICAgdmFyIHJlc3BvbnNlUGFyYW1zID0KICAgICAgICAgICAgcmVhZGVyLmRlY29kZVN0cnVjdChNZWRpYVJvdXRlUHJvdmlkZXJfU2VuZFJvdXRlQmluYXJ5TWVzc2FnZV9SZXNwb25zZVBhcmFtcyk7CiAgICAgICAgcmVzb2x2ZShyZXNwb25zZVBhcmFtcyk7CiAgICAgIH0pLmNhdGNoKGZ1bmN0aW9uKHJlc3VsdCkgewogICAgICAgIHJlamVjdChFcnJvcigiQ29ubmVjdGlvbiBlcnJvcjogIiArIHJlc3VsdCkpOwogICAgICB9KTsKICAgIH0uYmluZCh0aGlzKSk7CiAgfTsKICBNZWRpYVJvdXRlUHJvdmlkZXJQdHIucHJvdG90eXBlLnN0YXJ0T2JzZXJ2aW5nTWVkaWFTaW5rcyA9IGZ1bmN0aW9uKCkgewogICAgcmV0dXJuIE1lZGlhUm91dGVQcm92aWRlclByb3h5LnByb3RvdHlwZS5zdGFydE9ic2VydmluZ01lZGlhU2lua3MKICAgICAgICAuYXBwbHkodGhpcy5wdHIuZ2V0UHJveHkoKSwgYXJndW1lbnRzKTsKICB9OwoKICBNZWRpYVJvdXRlUHJvdmlkZXJQcm94eS5wcm90b3R5cGUuc3RhcnRPYnNlcnZpbmdNZWRpYVNpbmtzID0gZnVuY3Rpb24obWVkaWFTb3VyY2UpIHsKICAgIHZhciBwYXJhbXMgPSBuZXcgTWVkaWFSb3V0ZVByb3ZpZGVyX1N0YXJ0T2JzZXJ2aW5nTWVkaWFTaW5rc19QYXJhbXMoKTsKICAgIHBhcmFtcy5tZWRpYVNvdXJjZSA9IG1lZGlhU291cmNlOwogICAgdmFyIGJ1aWxkZXIgPSBuZXcgY29kZWMuTWVzc2FnZVYwQnVpbGRlcigKICAgICAgICBrTWVkaWFSb3V0ZVByb3ZpZGVyX1N0YXJ0T2JzZXJ2aW5nTWVkaWFTaW5rc19OYW1lLAogICAgICAgIGNvZGVjLmFsaWduKE1lZGlhUm91dGVQcm92aWRlcl9TdGFydE9ic2VydmluZ01lZGlhU2lua3NfUGFyYW1zLmVuY29kZWRTaXplKSk7CiAgICBidWlsZGVyLmVuY29kZVN0cnVjdChNZWRpYVJvdXRlUHJvdmlkZXJfU3RhcnRPYnNlcnZpbmdNZWRpYVNpbmtzX1BhcmFtcywgcGFyYW1zKTsKICAgIHZhciBtZXNzYWdlID0gYnVpbGRlci5maW5pc2goKTsKICAgIHRoaXMucmVjZWl2ZXJfLmFjY2VwdChtZXNzYWdlKTsKICB9OwogIE1lZGlhUm91dGVQcm92aWRlclB0ci5wcm90b3R5cGUuc3RvcE9ic2VydmluZ01lZGlhU2lua3MgPSBmdW5jdGlvbigpIHsKICAgIHJldHVybiBNZWRpYVJvdXRlUHJvdmlkZXJQcm94eS5wcm90b3R5cGUuc3RvcE9ic2VydmluZ01lZGlhU2lua3MKICAgICAgICAuYXBwbHkodGhpcy5wdHIuZ2V0UHJveHkoKSwgYXJndW1lbnRzKTsKICB9OwoKICBNZWRpYVJvdXRlUHJvdmlkZXJQcm94eS5wcm90b3R5cGUuc3RvcE9ic2VydmluZ01lZGlhU2lua3MgPSBmdW5jdGlvbihtZWRpYVNvdXJjZSkgewogICAgdmFyIHBhcmFtcyA9IG5ldyBNZWRpYVJvdXRlUHJvdmlkZXJfU3RvcE9ic2VydmluZ01lZGlhU2lua3NfUGFyYW1zKCk7CiAgICBwYXJhbXMubWVkaWFTb3VyY2UgPSBtZWRpYVNvdXJjZTsKICAgIHZhciBidWlsZGVyID0gbmV3IGNvZGVjLk1lc3NhZ2VWMEJ1aWxkZXIoCiAgICAgICAga01lZGlhUm91dGVQcm92aWRlcl9TdG9wT2JzZXJ2aW5nTWVkaWFTaW5rc19OYW1lLAogICAgICAgIGNvZGVjLmFsaWduKE1lZGlhUm91dGVQcm92aWRlcl9TdG9wT2JzZXJ2aW5nTWVkaWFTaW5rc19QYXJhbXMuZW5jb2RlZFNpemUpKTsKICAgIGJ1aWxkZXIuZW5jb2RlU3RydWN0KE1lZGlhUm91dGVQcm92aWRlcl9TdG9wT2JzZXJ2aW5nTWVkaWFTaW5rc19QYXJhbXMsIHBhcmFtcyk7CiAgICB2YXIgbWVzc2FnZSA9IGJ1aWxkZXIuZmluaXNoKCk7CiAgICB0aGlzLnJlY2VpdmVyXy5hY2NlcHQobWVzc2FnZSk7CiAgfTsKICBNZWRpYVJvdXRlUHJvdmlkZXJQdHIucHJvdG90eXBlLnN0YXJ0T2JzZXJ2aW5nTWVkaWFSb3V0ZXMgPSBmdW5jdGlvbigpIHsKICAgIHJldHVybiBNZWRpYVJvdXRlUHJvdmlkZXJQcm94eS5wcm90b3R5cGUuc3RhcnRPYnNlcnZpbmdNZWRpYVJvdXRlcwogICAgICAgIC5hcHBseSh0aGlzLnB0ci5nZXRQcm94eSgpLCBhcmd1bWVudHMpOwogIH07CgogIE1lZGlhUm91dGVQcm92aWRlclByb3h5LnByb3RvdHlwZS5zdGFydE9ic2VydmluZ01lZGlhUm91dGVzID0gZnVuY3Rpb24obWVkaWFTb3VyY2UpIHsKICAgIHZhciBwYXJhbXMgPSBuZXcgTWVkaWFSb3V0ZVByb3ZpZGVyX1N0YXJ0T2JzZXJ2aW5nTWVkaWFSb3V0ZXNfUGFyYW1zKCk7CiAgICBwYXJhbXMubWVkaWFTb3VyY2UgPSBtZWRpYVNvdXJjZTsKICAgIHZhciBidWlsZGVyID0gbmV3IGNvZGVjLk1lc3NhZ2VWMEJ1aWxkZXIoCiAgICAgICAga01lZGlhUm91dGVQcm92aWRlcl9TdGFydE9ic2VydmluZ01lZGlhUm91dGVzX05hbWUsCiAgICAgICAgY29kZWMuYWxpZ24oTWVkaWFSb3V0ZVByb3ZpZGVyX1N0YXJ0T2JzZXJ2aW5nTWVkaWFSb3V0ZXNfUGFyYW1zLmVuY29kZWRTaXplKSk7CiAgICBidWlsZGVyLmVuY29kZVN0cnVjdChNZWRpYVJvdXRlUHJvdmlkZXJfU3RhcnRPYnNlcnZpbmdNZWRpYVJvdXRlc19QYXJhbXMsIHBhcmFtcyk7CiAgICB2YXIgbWVzc2FnZSA9IGJ1aWxkZXIuZmluaXNoKCk7CiAgICB0aGlzLnJlY2VpdmVyXy5hY2NlcHQobWVzc2FnZSk7CiAgfTsKICBNZWRpYVJvdXRlUHJvdmlkZXJQdHIucHJvdG90eXBlLnN0b3BPYnNlcnZpbmdNZWRpYVJvdXRlcyA9IGZ1bmN0aW9uKCkgewogICAgcmV0dXJuIE1lZGlhUm91dGVQcm92aWRlclByb3h5LnByb3RvdHlwZS5zdG9wT2JzZXJ2aW5nTWVkaWFSb3V0ZXMKICAgICAgICAuYXBwbHkodGhpcy5wdHIuZ2V0UHJveHkoKSwgYXJndW1lbnRzKTsKICB9OwoKICBNZWRpYVJvdXRlUHJvdmlkZXJQcm94eS5wcm90b3R5cGUuc3RvcE9ic2VydmluZ01lZGlhUm91dGVzID0gZnVuY3Rpb24obWVkaWFTb3VyY2UpIHsKICAgIHZhciBwYXJhbXMgPSBuZXcgTWVkaWFSb3V0ZVByb3ZpZGVyX1N0b3BPYnNlcnZpbmdNZWRpYVJvdXRlc19QYXJhbXMoKTsKICAgIHBhcmFtcy5tZWRpYVNvdXJjZSA9IG1lZGlhU291cmNlOwogICAgdmFyIGJ1aWxkZXIgPSBuZXcgY29kZWMuTWVzc2FnZVYwQnVpbGRlcigKICAgICAgICBrTWVkaWFSb3V0ZVByb3ZpZGVyX1N0b3BPYnNlcnZpbmdNZWRpYVJvdXRlc19OYW1lLAogICAgICAgIGNvZGVjLmFsaWduKE1lZGlhUm91dGVQcm92aWRlcl9TdG9wT2JzZXJ2aW5nTWVkaWFSb3V0ZXNfUGFyYW1zLmVuY29kZWRTaXplKSk7CiAgICBidWlsZGVyLmVuY29kZVN0cnVjdChNZWRpYVJvdXRlUHJvdmlkZXJfU3RvcE9ic2VydmluZ01lZGlhUm91dGVzX1BhcmFtcywgcGFyYW1zKTsKICAgIHZhciBtZXNzYWdlID0gYnVpbGRlci5maW5pc2goKTsKICAgIHRoaXMucmVjZWl2ZXJfLmFjY2VwdChtZXNzYWdlKTsKICB9OwogIE1lZGlhUm91dGVQcm92aWRlclB0ci5wcm90b3R5cGUuc3RhcnRMaXN0ZW5pbmdGb3JSb3V0ZU1lc3NhZ2VzID0gZnVuY3Rpb24oKSB7CiAgICByZXR1cm4gTWVkaWFSb3V0ZVByb3ZpZGVyUHJveHkucHJvdG90eXBlLnN0YXJ0TGlzdGVuaW5nRm9yUm91dGVNZXNzYWdlcwogICAgICAgIC5hcHBseSh0aGlzLnB0ci5nZXRQcm94eSgpLCBhcmd1bWVudHMpOwogIH07CgogIE1lZGlhUm91dGVQcm92aWRlclByb3h5LnByb3RvdHlwZS5zdGFydExpc3RlbmluZ0ZvclJvdXRlTWVzc2FnZXMgPSBmdW5jdGlvbihyb3V0ZUlkKSB7CiAgICB2YXIgcGFyYW1zID0gbmV3IE1lZGlhUm91dGVQcm92aWRlcl9TdGFydExpc3RlbmluZ0ZvclJvdXRlTWVzc2FnZXNfUGFyYW1zKCk7CiAgICBwYXJhbXMucm91dGVJZCA9IHJvdXRlSWQ7CiAgICB2YXIgYnVpbGRlciA9IG5ldyBjb2RlYy5NZXNzYWdlVjBCdWlsZGVyKAogICAgICAgIGtNZWRpYVJvdXRlUHJvdmlkZXJfU3RhcnRMaXN0ZW5pbmdGb3JSb3V0ZU1lc3NhZ2VzX05hbWUsCiAgICAgICAgY29kZWMuYWxpZ24oTWVkaWFSb3V0ZVByb3ZpZGVyX1N0YXJ0TGlzdGVuaW5nRm9yUm91dGVNZXNzYWdlc19QYXJhbXMuZW5jb2RlZFNpemUpKTsKICAgIGJ1aWxkZXIuZW5jb2RlU3RydWN0KE1lZGlhUm91dGVQcm92aWRlcl9TdGFydExpc3RlbmluZ0ZvclJvdXRlTWVzc2FnZXNfUGFyYW1zLCBwYXJhbXMpOwogICAgdmFyIG1lc3NhZ2UgPSBidWlsZGVyLmZpbmlzaCgpOwogICAgdGhpcy5yZWNlaXZlcl8uYWNjZXB0KG1lc3NhZ2UpOwogIH07CiAgTWVkaWFSb3V0ZVByb3ZpZGVyUHRyLnByb3RvdHlwZS5zdG9wTGlzdGVuaW5nRm9yUm91dGVNZXNzYWdlcyA9IGZ1bmN0aW9uKCkgewogICAgcmV0dXJuIE1lZGlhUm91dGVQcm92aWRlclByb3h5LnByb3RvdHlwZS5zdG9wTGlzdGVuaW5nRm9yUm91dGVNZXNzYWdlcwogICAgICAgIC5hcHBseSh0aGlzLnB0ci5nZXRQcm94eSgpLCBhcmd1bWVudHMpOwogIH07CgogIE1lZGlhUm91dGVQcm92aWRlclByb3h5LnByb3RvdHlwZS5zdG9wTGlzdGVuaW5nRm9yUm91dGVNZXNzYWdlcyA9IGZ1bmN0aW9uKHJvdXRlSWQpIHsKICAgIHZhciBwYXJhbXMgPSBuZXcgTWVkaWFSb3V0ZVByb3ZpZGVyX1N0b3BMaXN0ZW5pbmdGb3JSb3V0ZU1lc3NhZ2VzX1BhcmFtcygpOwogICAgcGFyYW1zLnJvdXRlSWQgPSByb3V0ZUlkOwogICAgdmFyIGJ1aWxkZXIgPSBuZXcgY29kZWMuTWVzc2FnZVYwQnVpbGRlcigKICAgICAgICBrTWVkaWFSb3V0ZVByb3ZpZGVyX1N0b3BMaXN0ZW5pbmdGb3JSb3V0ZU1lc3NhZ2VzX05hbWUsCiAgICAgICAgY29kZWMuYWxpZ24oTWVkaWFSb3V0ZVByb3ZpZGVyX1N0b3BMaXN0ZW5pbmdGb3JSb3V0ZU1lc3NhZ2VzX1BhcmFtcy5lbmNvZGVkU2l6ZSkpOwogICAgYnVpbGRlci5lbmNvZGVTdHJ1Y3QoTWVkaWFSb3V0ZVByb3ZpZGVyX1N0b3BMaXN0ZW5pbmdGb3JSb3V0ZU1lc3NhZ2VzX1BhcmFtcywgcGFyYW1zKTsKICAgIHZhciBtZXNzYWdlID0gYnVpbGRlci5maW5pc2goKTsKICAgIHRoaXMucmVjZWl2ZXJfLmFjY2VwdChtZXNzYWdlKTsKICB9OwogIE1lZGlhUm91dGVQcm92aWRlclB0ci5wcm90b3R5cGUuZGV0YWNoUm91dGUgPSBmdW5jdGlvbigpIHsKICAgIHJldHVybiBNZWRpYVJvdXRlUHJvdmlkZXJQcm94eS5wcm90b3R5cGUuZGV0YWNoUm91dGUKICAgICAgICAuYXBwbHkodGhpcy5wdHIuZ2V0UHJveHkoKSwgYXJndW1lbnRzKTsKICB9OwoKICBNZWRpYVJvdXRlUHJvdmlkZXJQcm94eS5wcm90b3R5cGUuZGV0YWNoUm91dGUgPSBmdW5jdGlvbihyb3V0ZUlkKSB7CiAgICB2YXIgcGFyYW1zID0gbmV3IE1lZGlhUm91dGVQcm92aWRlcl9EZXRhY2hSb3V0ZV9QYXJhbXMoKTsKICAgIHBhcmFtcy5yb3V0ZUlkID0gcm91dGVJZDsKICAgIHZhciBidWlsZGVyID0gbmV3IGNvZGVjLk1lc3NhZ2VWMEJ1aWxkZXIoCiAgICAgICAga01lZGlhUm91dGVQcm92aWRlcl9EZXRhY2hSb3V0ZV9OYW1lLAogICAgICAgIGNvZGVjLmFsaWduKE1lZGlhUm91dGVQcm92aWRlcl9EZXRhY2hSb3V0ZV9QYXJhbXMuZW5jb2RlZFNpemUpKTsKICAgIGJ1aWxkZXIuZW5jb2RlU3RydWN0KE1lZGlhUm91dGVQcm92aWRlcl9EZXRhY2hSb3V0ZV9QYXJhbXMsIHBhcmFtcyk7CiAgICB2YXIgbWVzc2FnZSA9IGJ1aWxkZXIuZmluaXNoKCk7CiAgICB0aGlzLnJlY2VpdmVyXy5hY2NlcHQobWVzc2FnZSk7CiAgfTsKICBNZWRpYVJvdXRlUHJvdmlkZXJQdHIucHJvdG90eXBlLmVuYWJsZU1kbnNEaXNjb3ZlcnkgPSBmdW5jdGlvbigpIHsKICAgIHJldHVybiBNZWRpYVJvdXRlUHJvdmlkZXJQcm94eS5wcm90b3R5cGUuZW5hYmxlTWRuc0Rpc2NvdmVyeQogICAgICAgIC5hcHBseSh0aGlzLnB0ci5nZXRQcm94eSgpLCBhcmd1bWVudHMpOwogIH07CgogIE1lZGlhUm91dGVQcm92aWRlclByb3h5LnByb3RvdHlwZS5lbmFibGVNZG5zRGlzY292ZXJ5ID0gZnVuY3Rpb24oKSB7CiAgICB2YXIgcGFyYW1zID0gbmV3IE1lZGlhUm91dGVQcm92aWRlcl9FbmFibGVNZG5zRGlzY292ZXJ5X1BhcmFtcygpOwogICAgdmFyIGJ1aWxkZXIgPSBuZXcgY29kZWMuTWVzc2FnZVYwQnVpbGRlcigKICAgICAgICBrTWVkaWFSb3V0ZVByb3ZpZGVyX0VuYWJsZU1kbnNEaXNjb3ZlcnlfTmFtZSwKICAgICAgICBjb2RlYy5hbGlnbihNZWRpYVJvdXRlUHJvdmlkZXJfRW5hYmxlTWRuc0Rpc2NvdmVyeV9QYXJhbXMuZW5jb2RlZFNpemUpKTsKICAgIGJ1aWxkZXIuZW5jb2RlU3RydWN0KE1lZGlhUm91dGVQcm92aWRlcl9FbmFibGVNZG5zRGlzY292ZXJ5X1BhcmFtcywgcGFyYW1zKTsKICAgIHZhciBtZXNzYWdlID0gYnVpbGRlci5maW5pc2goKTsKICAgIHRoaXMucmVjZWl2ZXJfLmFjY2VwdChtZXNzYWdlKTsKICB9OwogIE1lZGlhUm91dGVQcm92aWRlclB0ci5wcm90b3R5cGUudXBkYXRlTWVkaWFTaW5rcyA9IGZ1bmN0aW9uKCkgewogICAgcmV0dXJuIE1lZGlhUm91dGVQcm92aWRlclByb3h5LnByb3RvdHlwZS51cGRhdGVNZWRpYVNpbmtzCiAgICAgICAgLmFwcGx5KHRoaXMucHRyLmdldFByb3h5KCksIGFyZ3VtZW50cyk7CiAgfTsKCiAgTWVkaWFSb3V0ZVByb3ZpZGVyUHJveHkucHJvdG90eXBlLnVwZGF0ZU1lZGlhU2lua3MgPSBmdW5jdGlvbihtZWRpYVNvdXJjZSkgewogICAgdmFyIHBhcmFtcyA9IG5ldyBNZWRpYVJvdXRlUHJvdmlkZXJfVXBkYXRlTWVkaWFTaW5rc19QYXJhbXMoKTsKICAgIHBhcmFtcy5tZWRpYVNvdXJjZSA9IG1lZGlhU291cmNlOwogICAgdmFyIGJ1aWxkZXIgPSBuZXcgY29kZWMuTWVzc2FnZVYwQnVpbGRlcigKICAgICAgICBrTWVkaWFSb3V0ZVByb3ZpZGVyX1VwZGF0ZU1lZGlhU2lua3NfTmFtZSwKICAgICAgICBjb2RlYy5hbGlnbihNZWRpYVJvdXRlUHJvdmlkZXJfVXBkYXRlTWVkaWFTaW5rc19QYXJhbXMuZW5jb2RlZFNpemUpKTsKICAgIGJ1aWxkZXIuZW5jb2RlU3RydWN0KE1lZGlhUm91dGVQcm92aWRlcl9VcGRhdGVNZWRpYVNpbmtzX1BhcmFtcywgcGFyYW1zKTsKICAgIHZhciBtZXNzYWdlID0gYnVpbGRlci5maW5pc2goKTsKICAgIHRoaXMucmVjZWl2ZXJfLmFjY2VwdChtZXNzYWdlKTsKICB9OwogIE1lZGlhUm91dGVQcm92aWRlclB0ci5wcm90b3R5cGUuc2VhcmNoU2lua3MgPSBmdW5jdGlvbigpIHsKICAgIHJldHVybiBNZWRpYVJvdXRlUHJvdmlkZXJQcm94eS5wcm90b3R5cGUuc2VhcmNoU2lua3MKICAgICAgICAuYXBwbHkodGhpcy5wdHIuZ2V0UHJveHkoKSwgYXJndW1lbnRzKTsKICB9OwoKICBNZWRpYVJvdXRlUHJvdmlkZXJQcm94eS5wcm90b3R5cGUuc2VhcmNoU2lua3MgPSBmdW5jdGlvbihzaW5rSWQsIG1lZGlhU291cmNlLCBzZWFyY2hDcml0ZXJpYSkgewogICAgdmFyIHBhcmFtcyA9IG5ldyBNZWRpYVJvdXRlUHJvdmlkZXJfU2VhcmNoU2lua3NfUGFyYW1zKCk7CiAgICBwYXJhbXMuc2lua0lkID0gc2lua0lkOwogICAgcGFyYW1zLm1lZGlhU291cmNlID0gbWVkaWFTb3VyY2U7CiAgICBwYXJhbXMuc2VhcmNoQ3JpdGVyaWEgPSBzZWFyY2hDcml0ZXJpYTsKICAgIHJldHVybiBuZXcgUHJvbWlzZShmdW5jdGlvbihyZXNvbHZlLCByZWplY3QpIHsKICAgICAgdmFyIGJ1aWxkZXIgPSBuZXcgY29kZWMuTWVzc2FnZVYxQnVpbGRlcigKICAgICAgICAgIGtNZWRpYVJvdXRlUHJvdmlkZXJfU2VhcmNoU2lua3NfTmFtZSwKICAgICAgICAgIGNvZGVjLmFsaWduKE1lZGlhUm91dGVQcm92aWRlcl9TZWFyY2hTaW5rc19QYXJhbXMuZW5jb2RlZFNpemUpLAogICAgICAgICAgY29kZWMua01lc3NhZ2VFeHBlY3RzUmVzcG9uc2UsIDApOwogICAgICBidWlsZGVyLmVuY29kZVN0cnVjdChNZWRpYVJvdXRlUHJvdmlkZXJfU2VhcmNoU2lua3NfUGFyYW1zLCBwYXJhbXMpOwogICAgICB2YXIgbWVzc2FnZSA9IGJ1aWxkZXIuZmluaXNoKCk7CiAgICAgIHRoaXMucmVjZWl2ZXJfLmFjY2VwdEFuZEV4cGVjdFJlc3BvbnNlKG1lc3NhZ2UpLnRoZW4oZnVuY3Rpb24obWVzc2FnZSkgewogICAgICAgIHZhciByZWFkZXIgPSBuZXcgY29kZWMuTWVzc2FnZVJlYWRlcihtZXNzYWdlKTsKICAgICAgICB2YXIgcmVzcG9uc2VQYXJhbXMgPQogICAgICAgICAgICByZWFkZXIuZGVjb2RlU3RydWN0KE1lZGlhUm91dGVQcm92aWRlcl9TZWFyY2hTaW5rc19SZXNwb25zZVBhcmFtcyk7CiAgICAgICAgcmVzb2x2ZShyZXNwb25zZVBhcmFtcyk7CiAgICAgIH0pLmNhdGNoKGZ1bmN0aW9uKHJlc3VsdCkgewogICAgICAgIHJlamVjdChFcnJvcigiQ29ubmVjdGlvbiBlcnJvcjogIiArIHJlc3VsdCkpOwogICAgICB9KTsKICAgIH0uYmluZCh0aGlzKSk7CiAgfTsKICBNZWRpYVJvdXRlUHJvdmlkZXJQdHIucHJvdG90eXBlLnByb3ZpZGVTaW5rcyA9IGZ1bmN0aW9uKCkgewogICAgcmV0dXJuIE1lZGlhUm91dGVQcm92aWRlclByb3h5LnByb3RvdHlwZS5wcm92aWRlU2lua3MKICAgICAgICAuYXBwbHkodGhpcy5wdHIuZ2V0UHJveHkoKSwgYXJndW1lbnRzKTsKICB9OwoKICBNZWRpYVJvdXRlUHJvdmlkZXJQcm94eS5wcm90b3R5cGUucHJvdmlkZVNpbmtzID0gZnVuY3Rpb24ocHJvdmlkZXJOYW1lLCBzaW5rcykgewogICAgdmFyIHBhcmFtcyA9IG5ldyBNZWRpYVJvdXRlUHJvdmlkZXJfUHJvdmlkZVNpbmtzX1BhcmFtcygpOwogICAgcGFyYW1zLnByb3ZpZGVyTmFtZSA9IHByb3ZpZGVyTmFtZTsKICAgIHBhcmFtcy5zaW5rcyA9IHNpbmtzOwogICAgdmFyIGJ1aWxkZXIgPSBuZXcgY29kZWMuTWVzc2FnZVYwQnVpbGRlcigKICAgICAgICBrTWVkaWFSb3V0ZVByb3ZpZGVyX1Byb3ZpZGVTaW5rc19OYW1lLAogICAgICAgIGNvZGVjLmFsaWduKE1lZGlhUm91dGVQcm92aWRlcl9Qcm92aWRlU2lua3NfUGFyYW1zLmVuY29kZWRTaXplKSk7CiAgICBidWlsZGVyLmVuY29kZVN0cnVjdChNZWRpYVJvdXRlUHJvdmlkZXJfUHJvdmlkZVNpbmtzX1BhcmFtcywgcGFyYW1zKTsKICAgIHZhciBtZXNzYWdlID0gYnVpbGRlci5maW5pc2goKTsKICAgIHRoaXMucmVjZWl2ZXJfLmFjY2VwdChtZXNzYWdlKTsKICB9OwogIE1lZGlhUm91dGVQcm92aWRlclB0ci5wcm90b3R5cGUuY3JlYXRlTWVkaWFSb3V0ZUNvbnRyb2xsZXIgPSBmdW5jdGlvbigpIHsKICAgIHJldHVybiBNZWRpYVJvdXRlUHJvdmlkZXJQcm94eS5wcm90b3R5cGUuY3JlYXRlTWVkaWFSb3V0ZUNvbnRyb2xsZXIKICAgICAgICAuYXBwbHkodGhpcy5wdHIuZ2V0UHJveHkoKSwgYXJndW1lbnRzKTsKICB9OwoKICBNZWRpYVJvdXRlUHJvdmlkZXJQcm94eS5wcm90b3R5cGUuY3JlYXRlTWVkaWFSb3V0ZUNvbnRyb2xsZXIgPSBmdW5jdGlvbihyb3V0ZUlkLCBtZWRpYUNvbnRyb2xsZXIsIG9ic2VydmVyKSB7CiAgICB2YXIgcGFyYW1zID0gbmV3IE1lZGlhUm91dGVQcm92aWRlcl9DcmVhdGVNZWRpYVJvdXRlQ29udHJvbGxlcl9QYXJhbXMoKTsKICAgIHBhcmFtcy5yb3V0ZUlkID0gcm91dGVJZDsKICAgIHBhcmFtcy5tZWRpYUNvbnRyb2xsZXIgPSBtZWRpYUNvbnRyb2xsZXI7CiAgICBwYXJhbXMub2JzZXJ2ZXIgPSBvYnNlcnZlcjsKICAgIHJldHVybiBuZXcgUHJvbWlzZShmdW5jdGlvbihyZXNvbHZlLCByZWplY3QpIHsKICAgICAgdmFyIGJ1aWxkZXIgPSBuZXcgY29kZWMuTWVzc2FnZVYxQnVpbGRlcigKICAgICAgICAgIGtNZWRpYVJvdXRlUHJvdmlkZXJfQ3JlYXRlTWVkaWFSb3V0ZUNvbnRyb2xsZXJfTmFtZSwKICAgICAgICAgIGNvZGVjLmFsaWduKE1lZGlhUm91dGVQcm92aWRlcl9DcmVhdGVNZWRpYVJvdXRlQ29udHJvbGxlcl9QYXJhbXMuZW5jb2RlZFNpemUpLAogICAgICAgICAgY29kZWMua01lc3NhZ2VFeHBlY3RzUmVzcG9uc2UsIDApOwogICAgICBidWlsZGVyLmVuY29kZVN0cnVjdChNZWRpYVJvdXRlUHJvdmlkZXJfQ3JlYXRlTWVkaWFSb3V0ZUNvbnRyb2xsZXJfUGFyYW1zLCBwYXJhbXMpOwogICAgICB2YXIgbWVzc2FnZSA9IGJ1aWxkZXIuZmluaXNoKCk7CiAgICAgIHRoaXMucmVjZWl2ZXJfLmFjY2VwdEFuZEV4cGVjdFJlc3BvbnNlKG1lc3NhZ2UpLnRoZW4oZnVuY3Rpb24obWVzc2FnZSkgewogICAgICAgIHZhciByZWFkZXIgPSBuZXcgY29kZWMuTWVzc2FnZVJlYWRlcihtZXNzYWdlKTsKICAgICAgICB2YXIgcmVzcG9uc2VQYXJhbXMgPQogICAgICAgICAgICByZWFkZXIuZGVjb2RlU3RydWN0KE1lZGlhUm91dGVQcm92aWRlcl9DcmVhdGVNZWRpYVJvdXRlQ29udHJvbGxlcl9SZXNwb25zZVBhcmFtcyk7CiAgICAgICAgcmVzb2x2ZShyZXNwb25zZVBhcmFtcyk7CiAgICAgIH0pLmNhdGNoKGZ1bmN0aW9uKHJlc3VsdCkgewogICAgICAgIHJlamVjdChFcnJvcigiQ29ubmVjdGlvbiBlcnJvcjogIiArIHJlc3VsdCkpOwogICAgICB9KTsKICAgIH0uYmluZCh0aGlzKSk7CiAgfTsKCiAgZnVuY3Rpb24gTWVkaWFSb3V0ZVByb3ZpZGVyU3R1YihkZWxlZ2F0ZSkgewogICAgdGhpcy5kZWxlZ2F0ZV8gPSBkZWxlZ2F0ZTsKICB9CiAgTWVkaWFSb3V0ZVByb3ZpZGVyU3R1Yi5wcm90b3R5cGUuY3JlYXRlUm91dGUgPSBmdW5jdGlvbihtZWRpYVNvdXJjZSwgc2lua0lkLCBvcmlnaW5hbFByZXNlbnRhdGlvbklkLCBvcmlnaW4sIHRhYklkLCB0aW1lb3V0LCBpbmNvZ25pdG8pIHsKICAgIHJldHVybiB0aGlzLmRlbGVnYXRlXyAmJiB0aGlzLmRlbGVnYXRlXy5jcmVhdGVSb3V0ZSAmJiB0aGlzLmRlbGVnYXRlXy5jcmVhdGVSb3V0ZShtZWRpYVNvdXJjZSwgc2lua0lkLCBvcmlnaW5hbFByZXNlbnRhdGlvbklkLCBvcmlnaW4sIHRhYklkLCB0aW1lb3V0LCBpbmNvZ25pdG8pOwogIH0KICBNZWRpYVJvdXRlUHJvdmlkZXJTdHViLnByb3RvdHlwZS5qb2luUm91dGUgPSBmdW5jdGlvbihtZWRpYVNvdXJjZSwgcHJlc2VudGF0aW9uSWQsIG9yaWdpbiwgdGFiSWQsIHRpbWVvdXQsIGluY29nbml0bykgewogICAgcmV0dXJuIHRoaXMuZGVsZWdhdGVfICYmIHRoaXMuZGVsZWdhdGVfLmpvaW5Sb3V0ZSAmJiB0aGlzLmRlbGVnYXRlXy5qb2luUm91dGUobWVkaWFTb3VyY2UsIHByZXNlbnRhdGlvbklkLCBvcmlnaW4sIHRhYklkLCB0aW1lb3V0LCBpbmNvZ25pdG8pOwogIH0KICBNZWRpYVJvdXRlUHJvdmlkZXJTdHViLnByb3RvdHlwZS5jb25uZWN0Um91dGVCeVJvdXRlSWQgPSBmdW5jdGlvbihtZWRpYVNvdXJjZSwgcm91dGVJZCwgcHJlc2VudGF0aW9uSWQsIG9yaWdpbiwgdGFiSWQsIHRpbWVvdXQsIGluY29nbml0bykgewogICAgcmV0dXJuIHRoaXMuZGVsZWdhdGVfICYmIHRoaXMuZGVsZWdhdGVfLmNvbm5lY3RSb3V0ZUJ5Um91dGVJZCAmJiB0aGlzLmRlbGVnYXRlXy5jb25uZWN0Um91dGVCeVJvdXRlSWQobWVkaWFTb3VyY2UsIHJvdXRlSWQsIHByZXNlbnRhdGlvbklkLCBvcmlnaW4sIHRhYklkLCB0aW1lb3V0LCBpbmNvZ25pdG8pOwogIH0KICBNZWRpYVJvdXRlUHJvdmlkZXJTdHViLnByb3RvdHlwZS50ZXJtaW5hdGVSb3V0ZSA9IGZ1bmN0aW9uKHJvdXRlSWQpIHsKICAgIHJldHVybiB0aGlzLmRlbGVnYXRlXyAmJiB0aGlzLmRlbGVnYXRlXy50ZXJtaW5hdGVSb3V0ZSAmJiB0aGlzLmRlbGVnYXRlXy50ZXJtaW5hdGVSb3V0ZShyb3V0ZUlkKTsKICB9CiAgTWVkaWFSb3V0ZVByb3ZpZGVyU3R1Yi5wcm90b3R5cGUuc2VuZFJvdXRlTWVzc2FnZSA9IGZ1bmN0aW9uKG1lZGlhUm91dGVJZCwgbWVzc2FnZSkgewogICAgcmV0dXJuIHRoaXMuZGVsZWdhdGVfICYmIHRoaXMuZGVsZWdhdGVfLnNlbmRSb3V0ZU1lc3NhZ2UgJiYgdGhpcy5kZWxlZ2F0ZV8uc2VuZFJvdXRlTWVzc2FnZShtZWRpYVJvdXRlSWQsIG1lc3NhZ2UpOwogIH0KICBNZWRpYVJvdXRlUHJvdmlkZXJTdHViLnByb3RvdHlwZS5zZW5kUm91dGVCaW5hcnlNZXNzYWdlID0gZnVuY3Rpb24obWVkaWFSb3V0ZUlkLCBkYXRhKSB7CiAgICByZXR1cm4gdGhpcy5kZWxlZ2F0ZV8gJiYgdGhpcy5kZWxlZ2F0ZV8uc2VuZFJvdXRlQmluYXJ5TWVzc2FnZSAmJiB0aGlzLmRlbGVnYXRlXy5zZW5kUm91dGVCaW5hcnlNZXNzYWdlKG1lZGlhUm91dGVJZCwgZGF0YSk7CiAgfQogIE1lZGlhUm91dGVQcm92aWRlclN0dWIucHJvdG90eXBlLnN0YXJ0T2JzZXJ2aW5nTWVkaWFTaW5rcyA9IGZ1bmN0aW9uKG1lZGlhU291cmNlKSB7CiAgICByZXR1cm4gdGhpcy5kZWxlZ2F0ZV8gJiYgdGhpcy5kZWxlZ2F0ZV8uc3RhcnRPYnNlcnZpbmdNZWRpYVNpbmtzICYmIHRoaXMuZGVsZWdhdGVfLnN0YXJ0T2JzZXJ2aW5nTWVkaWFTaW5rcyhtZWRpYVNvdXJjZSk7CiAgfQogIE1lZGlhUm91dGVQcm92aWRlclN0dWIucHJvdG90eXBlLnN0b3BPYnNlcnZpbmdNZWRpYVNpbmtzID0gZnVuY3Rpb24obWVkaWFTb3VyY2UpIHsKICAgIHJldHVybiB0aGlzLmRlbGVnYXRlXyAmJiB0aGlzLmRlbGVnYXRlXy5zdG9wT2JzZXJ2aW5nTWVkaWFTaW5rcyAmJiB0aGlzLmRlbGVnYXRlXy5zdG9wT2JzZXJ2aW5nTWVkaWFTaW5rcyhtZWRpYVNvdXJjZSk7CiAgfQogIE1lZGlhUm91dGVQcm92aWRlclN0dWIucHJvdG90eXBlLnN0YXJ0T2JzZXJ2aW5nTWVkaWFSb3V0ZXMgPSBmdW5jdGlvbihtZWRpYVNvdXJjZSkgewogICAgcmV0dXJuIHRoaXMuZGVsZWdhdGVfICYmIHRoaXMuZGVsZWdhdGVfLnN0YXJ0T2JzZXJ2aW5nTWVkaWFSb3V0ZXMgJiYgdGhpcy5kZWxlZ2F0ZV8uc3RhcnRPYnNlcnZpbmdNZWRpYVJvdXRlcyhtZWRpYVNvdXJjZSk7CiAgfQogIE1lZGlhUm91dGVQcm92aWRlclN0dWIucHJvdG90eXBlLnN0b3BPYnNlcnZpbmdNZWRpYVJvdXRlcyA9IGZ1bmN0aW9uKG1lZGlhU291cmNlKSB7CiAgICByZXR1cm4gdGhpcy5kZWxlZ2F0ZV8gJiYgdGhpcy5kZWxlZ2F0ZV8uc3RvcE9ic2VydmluZ01lZGlhUm91dGVzICYmIHRoaXMuZGVsZWdhdGVfLnN0b3BPYnNlcnZpbmdNZWRpYVJvdXRlcyhtZWRpYVNvdXJjZSk7CiAgfQogIE1lZGlhUm91dGVQcm92aWRlclN0dWIucHJvdG90eXBlLnN0YXJ0TGlzdGVuaW5nRm9yUm91dGVNZXNzYWdlcyA9IGZ1bmN0aW9uKHJvdXRlSWQpIHsKICAgIHJldHVybiB0aGlzLmRlbGVnYXRlXyAmJiB0aGlzLmRlbGVnYXRlXy5zdGFydExpc3RlbmluZ0ZvclJvdXRlTWVzc2FnZXMgJiYgdGhpcy5kZWxlZ2F0ZV8uc3RhcnRMaXN0ZW5pbmdGb3JSb3V0ZU1lc3NhZ2VzKHJvdXRlSWQpOwogIH0KICBNZWRpYVJvdXRlUHJvdmlkZXJTdHViLnByb3RvdHlwZS5zdG9wTGlzdGVuaW5nRm9yUm91dGVNZXNzYWdlcyA9IGZ1bmN0aW9uKHJvdXRlSWQpIHsKICAgIHJldHVybiB0aGlzLmRlbGVnYXRlXyAmJiB0aGlzLmRlbGVnYXRlXy5zdG9wTGlzdGVuaW5nRm9yUm91dGVNZXNzYWdlcyAmJiB0aGlzLmRlbGVnYXRlXy5zdG9wTGlzdGVuaW5nRm9yUm91dGVNZXNzYWdlcyhyb3V0ZUlkKTsKICB9CiAgTWVkaWFSb3V0ZVByb3ZpZGVyU3R1Yi5wcm90b3R5cGUuZGV0YWNoUm91dGUgPSBmdW5jdGlvbihyb3V0ZUlkKSB7CiAgICByZXR1cm4gdGhpcy5kZWxlZ2F0ZV8gJiYgdGhpcy5kZWxlZ2F0ZV8uZGV0YWNoUm91dGUgJiYgdGhpcy5kZWxlZ2F0ZV8uZGV0YWNoUm91dGUocm91dGVJZCk7CiAgfQogIE1lZGlhUm91dGVQcm92aWRlclN0dWIucHJvdG90eXBlLmVuYWJsZU1kbnNEaXNjb3ZlcnkgPSBmdW5jdGlvbigpIHsKICAgIHJldHVybiB0aGlzLmRlbGVnYXRlXyAmJiB0aGlzLmRlbGVnYXRlXy5lbmFibGVNZG5zRGlzY292ZXJ5ICYmIHRoaXMuZGVsZWdhdGVfLmVuYWJsZU1kbnNEaXNjb3ZlcnkoKTsKICB9CiAgTWVkaWFSb3V0ZVByb3ZpZGVyU3R1Yi5wcm90b3R5cGUudXBkYXRlTWVkaWFTaW5rcyA9IGZ1bmN0aW9uKG1lZGlhU291cmNlKSB7CiAgICByZXR1cm4gdGhpcy5kZWxlZ2F0ZV8gJiYgdGhpcy5kZWxlZ2F0ZV8udXBkYXRlTWVkaWFTaW5rcyAmJiB0aGlzLmRlbGVnYXRlXy51cGRhdGVNZWRpYVNpbmtzKG1lZGlhU291cmNlKTsKICB9CiAgTWVkaWFSb3V0ZVByb3ZpZGVyU3R1Yi5wcm90b3R5cGUuc2VhcmNoU2lua3MgPSBmdW5jdGlvbihzaW5rSWQsIG1lZGlhU291cmNlLCBzZWFyY2hDcml0ZXJpYSkgewogICAgcmV0dXJuIHRoaXMuZGVsZWdhdGVfICYmIHRoaXMuZGVsZWdhdGVfLnNlYXJjaFNpbmtzICYmIHRoaXMuZGVsZWdhdGVfLnNlYXJjaFNpbmtzKHNpbmtJZCwgbWVkaWFTb3VyY2UsIHNlYXJjaENyaXRlcmlhKTsKICB9CiAgTWVkaWFSb3V0ZVByb3ZpZGVyU3R1Yi5wcm90b3R5cGUucHJvdmlkZVNpbmtzID0gZnVuY3Rpb24ocHJvdmlkZXJOYW1lLCBzaW5rcykgewogICAgcmV0dXJuIHRoaXMuZGVsZWdhdGVfICYmIHRoaXMuZGVsZWdhdGVfLnByb3ZpZGVTaW5rcyAmJiB0aGlzLmRlbGVnYXRlXy5wcm92aWRlU2lua3MocHJvdmlkZXJOYW1lLCBzaW5rcyk7CiAgfQogIE1lZGlhUm91dGVQcm92aWRlclN0dWIucHJvdG90eXBlLmNyZWF0ZU1lZGlhUm91dGVDb250cm9sbGVyID0gZnVuY3Rpb24ocm91dGVJZCwgbWVkaWFDb250cm9sbGVyLCBvYnNlcnZlcikgewogICAgcmV0dXJuIHRoaXMuZGVsZWdhdGVfICYmIHRoaXMuZGVsZWdhdGVfLmNyZWF0ZU1lZGlhUm91dGVDb250cm9sbGVyICYmIHRoaXMuZGVsZWdhdGVfLmNyZWF0ZU1lZGlhUm91dGVDb250cm9sbGVyKHJvdXRlSWQsIG1lZGlhQ29udHJvbGxlciwgb2JzZXJ2ZXIpOwogIH0KCiAgTWVkaWFSb3V0ZVByb3ZpZGVyU3R1Yi5wcm90b3R5cGUuYWNjZXB0ID0gZnVuY3Rpb24obWVzc2FnZSkgewogICAgdmFyIHJlYWRlciA9IG5ldyBjb2RlYy5NZXNzYWdlUmVhZGVyKG1lc3NhZ2UpOwogICAgc3dpdGNoIChyZWFkZXIubWVzc2FnZU5hbWUpIHsKICAgIGNhc2Uga01lZGlhUm91dGVQcm92aWRlcl9TdGFydE9ic2VydmluZ01lZGlhU2lua3NfTmFtZToKICAgICAgdmFyIHBhcmFtcyA9IHJlYWRlci5kZWNvZGVTdHJ1Y3QoTWVkaWFSb3V0ZVByb3ZpZGVyX1N0YXJ0T2JzZXJ2aW5nTWVkaWFTaW5rc19QYXJhbXMpOwogICAgICB0aGlzLnN0YXJ0T2JzZXJ2aW5nTWVkaWFTaW5rcyhwYXJhbXMubWVkaWFTb3VyY2UpOwogICAgICByZXR1cm4gdHJ1ZTsKICAgIGNhc2Uga01lZGlhUm91dGVQcm92aWRlcl9TdG9wT2JzZXJ2aW5nTWVkaWFTaW5rc19OYW1lOgogICAgICB2YXIgcGFyYW1zID0gcmVhZGVyLmRlY29kZVN0cnVjdChNZWRpYVJvdXRlUHJvdmlkZXJfU3RvcE9ic2VydmluZ01lZGlhU2lua3NfUGFyYW1zKTsKICAgICAgdGhpcy5zdG9wT2JzZXJ2aW5nTWVkaWFTaW5rcyhwYXJhbXMubWVkaWFTb3VyY2UpOwogICAgICByZXR1cm4gdHJ1ZTsKICAgIGNhc2Uga01lZGlhUm91dGVQcm92aWRlcl9TdGFydE9ic2VydmluZ01lZGlhUm91dGVzX05hbWU6CiAgICAgIHZhciBwYXJhbXMgPSByZWFkZXIuZGVjb2RlU3RydWN0KE1lZGlhUm91dGVQcm92aWRlcl9TdGFydE9ic2VydmluZ01lZGlhUm91dGVzX1BhcmFtcyk7CiAgICAgIHRoaXMuc3RhcnRPYnNlcnZpbmdNZWRpYVJvdXRlcyhwYXJhbXMubWVkaWFTb3VyY2UpOwogICAgICByZXR1cm4gdHJ1ZTsKICAgIGNhc2Uga01lZGlhUm91dGVQcm92aWRlcl9TdG9wT2JzZXJ2aW5nTWVkaWFSb3V0ZXNfTmFtZToKICAgICAgdmFyIHBhcmFtcyA9IHJlYWRlci5kZWNvZGVTdHJ1Y3QoTWVkaWFSb3V0ZVByb3ZpZGVyX1N0b3BPYnNlcnZpbmdNZWRpYVJvdXRlc19QYXJhbXMpOwogICAgICB0aGlzLnN0b3BPYnNlcnZpbmdNZWRpYVJvdXRlcyhwYXJhbXMubWVkaWFTb3VyY2UpOwogICAgICByZXR1cm4gdHJ1ZTsKICAgIGNhc2Uga01lZGlhUm91dGVQcm92aWRlcl9TdGFydExpc3RlbmluZ0ZvclJvdXRlTWVzc2FnZXNfTmFtZToKICAgICAgdmFyIHBhcmFtcyA9IHJlYWRlci5kZWNvZGVTdHJ1Y3QoTWVkaWFSb3V0ZVByb3ZpZGVyX1N0YXJ0TGlzdGVuaW5nRm9yUm91dGVNZXNzYWdlc19QYXJhbXMpOwogICAgICB0aGlzLnN0YXJ0TGlzdGVuaW5nRm9yUm91dGVNZXNzYWdlcyhwYXJhbXMucm91dGVJZCk7CiAgICAgIHJldHVybiB0cnVlOwogICAgY2FzZSBrTWVkaWFSb3V0ZVByb3ZpZGVyX1N0b3BMaXN0ZW5pbmdGb3JSb3V0ZU1lc3NhZ2VzX05hbWU6CiAgICAgIHZhciBwYXJhbXMgPSByZWFkZXIuZGVjb2RlU3RydWN0KE1lZGlhUm91dGVQcm92aWRlcl9TdG9wTGlzdGVuaW5nRm9yUm91dGVNZXNzYWdlc19QYXJhbXMpOwogICAgICB0aGlzLnN0b3BMaXN0ZW5pbmdGb3JSb3V0ZU1lc3NhZ2VzKHBhcmFtcy5yb3V0ZUlkKTsKICAgICAgcmV0dXJuIHRydWU7CiAgICBjYXNlIGtNZWRpYVJvdXRlUHJvdmlkZXJfRGV0YWNoUm91dGVfTmFtZToKICAgICAgdmFyIHBhcmFtcyA9IHJlYWRlci5kZWNvZGVTdHJ1Y3QoTWVkaWFSb3V0ZVByb3ZpZGVyX0RldGFjaFJvdXRlX1BhcmFtcyk7CiAgICAgIHRoaXMuZGV0YWNoUm91dGUocGFyYW1zLnJvdXRlSWQpOwogICAgICByZXR1cm4gdHJ1ZTsKICAgIGNhc2Uga01lZGlhUm91dGVQcm92aWRlcl9FbmFibGVNZG5zRGlzY292ZXJ5X05hbWU6CiAgICAgIHZhciBwYXJhbXMgPSByZWFkZXIuZGVjb2RlU3RydWN0KE1lZGlhUm91dGVQcm92aWRlcl9FbmFibGVNZG5zRGlzY292ZXJ5X1BhcmFtcyk7CiAgICAgIHRoaXMuZW5hYmxlTWRuc0Rpc2NvdmVyeSgpOwogICAgICByZXR1cm4gdHJ1ZTsKICAgIGNhc2Uga01lZGlhUm91dGVQcm92aWRlcl9VcGRhdGVNZWRpYVNpbmtzX05hbWU6CiAgICAgIHZhciBwYXJhbXMgPSByZWFkZXIuZGVjb2RlU3RydWN0KE1lZGlhUm91dGVQcm92aWRlcl9VcGRhdGVNZWRpYVNpbmtzX1BhcmFtcyk7CiAgICAgIHRoaXMudXBkYXRlTWVkaWFTaW5rcyhwYXJhbXMubWVkaWFTb3VyY2UpOwogICAgICByZXR1cm4gdHJ1ZTsKICAgIGNhc2Uga01lZGlhUm91dGVQcm92aWRlcl9Qcm92aWRlU2lua3NfTmFtZToKICAgICAgdmFyIHBhcmFtcyA9IHJlYWRlci5kZWNvZGVTdHJ1Y3QoTWVkaWFSb3V0ZVByb3ZpZGVyX1Byb3ZpZGVTaW5rc19QYXJhbXMpOwogICAgICB0aGlzLnByb3ZpZGVTaW5rcyhwYXJhbXMucHJvdmlkZXJOYW1lLCBwYXJhbXMuc2lua3MpOwogICAgICByZXR1cm4gdHJ1ZTsKICAgIGRlZmF1bHQ6CiAgICAgIHJldHVybiBmYWxzZTsKICAgIH0KICB9OwoKICBNZWRpYVJvdXRlUHJvdmlkZXJTdHViLnByb3RvdHlwZS5hY2NlcHRXaXRoUmVzcG9uZGVyID0KICAgICAgZnVuY3Rpb24obWVzc2FnZSwgcmVzcG9uZGVyKSB7CiAgICB2YXIgcmVhZGVyID0gbmV3IGNvZGVjLk1lc3NhZ2VSZWFkZXIobWVzc2FnZSk7CiAgICBzd2l0Y2ggKHJlYWRlci5tZXNzYWdlTmFtZSkgewogICAgY2FzZSBrTWVkaWFSb3V0ZVByb3ZpZGVyX0NyZWF0ZVJvdXRlX05hbWU6CiAgICAgIHZhciBwYXJhbXMgPSByZWFkZXIuZGVjb2RlU3RydWN0KE1lZGlhUm91dGVQcm92aWRlcl9DcmVhdGVSb3V0ZV9QYXJhbXMpOwogICAgICB0aGlzLmNyZWF0ZVJvdXRlKHBhcmFtcy5tZWRpYVNvdXJjZSwgcGFyYW1zLnNpbmtJZCwgcGFyYW1zLm9yaWdpbmFsUHJlc2VudGF0aW9uSWQsIHBhcmFtcy5vcmlnaW4sIHBhcmFtcy50YWJJZCwgcGFyYW1zLnRpbWVvdXQsIHBhcmFtcy5pbmNvZ25pdG8pLnRoZW4oZnVuY3Rpb24ocmVzcG9uc2UpIHsKICAgICAgICB2YXIgcmVzcG9uc2VQYXJhbXMgPQogICAgICAgICAgICBuZXcgTWVkaWFSb3V0ZVByb3ZpZGVyX0NyZWF0ZVJvdXRlX1Jlc3BvbnNlUGFyYW1zKCk7CiAgICAgICAgcmVzcG9uc2VQYXJhbXMucm91dGUgPSByZXNwb25zZS5yb3V0ZTsKICAgICAgICByZXNwb25zZVBhcmFtcy5lcnJvclRleHQgPSByZXNwb25zZS5lcnJvclRleHQ7CiAgICAgICAgcmVzcG9uc2VQYXJhbXMucmVzdWx0Q29kZSA9IHJlc3BvbnNlLnJlc3VsdENvZGU7CiAgICAgICAgdmFyIGJ1aWxkZXIgPSBuZXcgY29kZWMuTWVzc2FnZVYxQnVpbGRlcigKICAgICAgICAgICAga01lZGlhUm91dGVQcm92aWRlcl9DcmVhdGVSb3V0ZV9OYW1lLAogICAgICAgICAgICBjb2RlYy5hbGlnbihNZWRpYVJvdXRlUHJvdmlkZXJfQ3JlYXRlUm91dGVfUmVzcG9uc2VQYXJhbXMuZW5jb2RlZFNpemUpLAogICAgICAgICAgICBjb2RlYy5rTWVzc2FnZUlzUmVzcG9uc2UsIHJlYWRlci5yZXF1ZXN0SUQpOwogICAgICAgIGJ1aWxkZXIuZW5jb2RlU3RydWN0KE1lZGlhUm91dGVQcm92aWRlcl9DcmVhdGVSb3V0ZV9SZXNwb25zZVBhcmFtcywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXNwb25zZVBhcmFtcyk7CiAgICAgICAgdmFyIG1lc3NhZ2UgPSBidWlsZGVyLmZpbmlzaCgpOwogICAgICAgIHJlc3BvbmRlci5hY2NlcHQobWVzc2FnZSk7CiAgICAgIH0pOwogICAgICByZXR1cm4gdHJ1ZTsKICAgIGNhc2Uga01lZGlhUm91dGVQcm92aWRlcl9Kb2luUm91dGVfTmFtZToKICAgICAgdmFyIHBhcmFtcyA9IHJlYWRlci5kZWNvZGVTdHJ1Y3QoTWVkaWFSb3V0ZVByb3ZpZGVyX0pvaW5Sb3V0ZV9QYXJhbXMpOwogICAgICB0aGlzLmpvaW5Sb3V0ZShwYXJhbXMubWVkaWFTb3VyY2UsIHBhcmFtcy5wcmVzZW50YXRpb25JZCwgcGFyYW1zLm9yaWdpbiwgcGFyYW1zLnRhYklkLCBwYXJhbXMudGltZW91dCwgcGFyYW1zLmluY29nbml0bykudGhlbihmdW5jdGlvbihyZXNwb25zZSkgewogICAgICAgIHZhciByZXNwb25zZVBhcmFtcyA9CiAgICAgICAgICAgIG5ldyBNZWRpYVJvdXRlUHJvdmlkZXJfSm9pblJvdXRlX1Jlc3BvbnNlUGFyYW1zKCk7CiAgICAgICAgcmVzcG9uc2VQYXJhbXMucm91dGUgPSByZXNwb25zZS5yb3V0ZTsKICAgICAgICByZXNwb25zZVBhcmFtcy5lcnJvclRleHQgPSByZXNwb25zZS5lcnJvclRleHQ7CiAgICAgICAgcmVzcG9uc2VQYXJhbXMucmVzdWx0Q29kZSA9IHJlc3BvbnNlLnJlc3VsdENvZGU7CiAgICAgICAgdmFyIGJ1aWxkZXIgPSBuZXcgY29kZWMuTWVzc2FnZVYxQnVpbGRlcigKICAgICAgICAgICAga01lZGlhUm91dGVQcm92aWRlcl9Kb2luUm91dGVfTmFtZSwKICAgICAgICAgICAgY29kZWMuYWxpZ24oTWVkaWFSb3V0ZVByb3ZpZGVyX0pvaW5Sb3V0ZV9SZXNwb25zZVBhcmFtcy5lbmNvZGVkU2l6ZSksCiAgICAgICAgICAgIGNvZGVjLmtNZXNzYWdlSXNSZXNwb25zZSwgcmVhZGVyLnJlcXVlc3RJRCk7CiAgICAgICAgYnVpbGRlci5lbmNvZGVTdHJ1Y3QoTWVkaWFSb3V0ZVByb3ZpZGVyX0pvaW5Sb3V0ZV9SZXNwb25zZVBhcmFtcywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXNwb25zZVBhcmFtcyk7CiAgICAgICAgdmFyIG1lc3NhZ2UgPSBidWlsZGVyLmZpbmlzaCgpOwogICAgICAgIHJlc3BvbmRlci5hY2NlcHQobWVzc2FnZSk7CiAgICAgIH0pOwogICAgICByZXR1cm4gdHJ1ZTsKICAgIGNhc2Uga01lZGlhUm91dGVQcm92aWRlcl9Db25uZWN0Um91dGVCeVJvdXRlSWRfTmFtZToKICAgICAgdmFyIHBhcmFtcyA9IHJlYWRlci5kZWNvZGVTdHJ1Y3QoTWVkaWFSb3V0ZVByb3ZpZGVyX0Nvbm5lY3RSb3V0ZUJ5Um91dGVJZF9QYXJhbXMpOwogICAgICB0aGlzLmNvbm5lY3RSb3V0ZUJ5Um91dGVJZChwYXJhbXMubWVkaWFTb3VyY2UsIHBhcmFtcy5yb3V0ZUlkLCBwYXJhbXMucHJlc2VudGF0aW9uSWQsIHBhcmFtcy5vcmlnaW4sIHBhcmFtcy50YWJJZCwgcGFyYW1zLnRpbWVvdXQsIHBhcmFtcy5pbmNvZ25pdG8pLnRoZW4oZnVuY3Rpb24ocmVzcG9uc2UpIHsKICAgICAgICB2YXIgcmVzcG9uc2VQYXJhbXMgPQogICAgICAgICAgICBuZXcgTWVkaWFSb3V0ZVByb3ZpZGVyX0Nvbm5lY3RSb3V0ZUJ5Um91dGVJZF9SZXNwb25zZVBhcmFtcygpOwogICAgICAgIHJlc3BvbnNlUGFyYW1zLnJvdXRlID0gcmVzcG9uc2Uucm91dGU7CiAgICAgICAgcmVzcG9uc2VQYXJhbXMuZXJyb3JUZXh0ID0gcmVzcG9uc2UuZXJyb3JUZXh0OwogICAgICAgIHJlc3BvbnNlUGFyYW1zLnJlc3VsdENvZGUgPSByZXNwb25zZS5yZXN1bHRDb2RlOwogICAgICAgIHZhciBidWlsZGVyID0gbmV3IGNvZGVjLk1lc3NhZ2VWMUJ1aWxkZXIoCiAgICAgICAgICAgIGtNZWRpYVJvdXRlUHJvdmlkZXJfQ29ubmVjdFJvdXRlQnlSb3V0ZUlkX05hbWUsCiAgICAgICAgICAgIGNvZGVjLmFsaWduKE1lZGlhUm91dGVQcm92aWRlcl9Db25uZWN0Um91dGVCeVJvdXRlSWRfUmVzcG9uc2VQYXJhbXMuZW5jb2RlZFNpemUpLAogICAgICAgICAgICBjb2RlYy5rTWVzc2FnZUlzUmVzcG9uc2UsIHJlYWRlci5yZXF1ZXN0SUQpOwogICAgICAgIGJ1aWxkZXIuZW5jb2RlU3RydWN0KE1lZGlhUm91dGVQcm92aWRlcl9Db25uZWN0Um91dGVCeVJvdXRlSWRfUmVzcG9uc2VQYXJhbXMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVzcG9uc2VQYXJhbXMpOwogICAgICAgIHZhciBtZXNzYWdlID0gYnVpbGRlci5maW5pc2goKTsKICAgICAgICByZXNwb25kZXIuYWNjZXB0KG1lc3NhZ2UpOwogICAgICB9KTsKICAgICAgcmV0dXJuIHRydWU7CiAgICBjYXNlIGtNZWRpYVJvdXRlUHJvdmlkZXJfVGVybWluYXRlUm91dGVfTmFtZToKICAgICAgdmFyIHBhcmFtcyA9IHJlYWRlci5kZWNvZGVTdHJ1Y3QoTWVkaWFSb3V0ZVByb3ZpZGVyX1Rlcm1pbmF0ZVJvdXRlX1BhcmFtcyk7CiAgICAgIHRoaXMudGVybWluYXRlUm91dGUocGFyYW1zLnJvdXRlSWQpLnRoZW4oZnVuY3Rpb24ocmVzcG9uc2UpIHsKICAgICAgICB2YXIgcmVzcG9uc2VQYXJhbXMgPQogICAgICAgICAgICBuZXcgTWVkaWFSb3V0ZVByb3ZpZGVyX1Rlcm1pbmF0ZVJvdXRlX1Jlc3BvbnNlUGFyYW1zKCk7CiAgICAgICAgcmVzcG9uc2VQYXJhbXMuZXJyb3JUZXh0ID0gcmVzcG9uc2UuZXJyb3JUZXh0OwogICAgICAgIHJlc3BvbnNlUGFyYW1zLnJlc3VsdENvZGUgPSByZXNwb25zZS5yZXN1bHRDb2RlOwogICAgICAgIHZhciBidWlsZGVyID0gbmV3IGNvZGVjLk1lc3NhZ2VWMUJ1aWxkZXIoCiAgICAgICAgICAgIGtNZWRpYVJvdXRlUHJvdmlkZXJfVGVybWluYXRlUm91dGVfTmFtZSwKICAgICAgICAgICAgY29kZWMuYWxpZ24oTWVkaWFSb3V0ZVByb3ZpZGVyX1Rlcm1pbmF0ZVJvdXRlX1Jlc3BvbnNlUGFyYW1zLmVuY29kZWRTaXplKSwKICAgICAgICAgICAgY29kZWMua01lc3NhZ2VJc1Jlc3BvbnNlLCByZWFkZXIucmVxdWVzdElEKTsKICAgICAgICBidWlsZGVyLmVuY29kZVN0cnVjdChNZWRpYVJvdXRlUHJvdmlkZXJfVGVybWluYXRlUm91dGVfUmVzcG9uc2VQYXJhbXMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVzcG9uc2VQYXJhbXMpOwogICAgICAgIHZhciBtZXNzYWdlID0gYnVpbGRlci5maW5pc2goKTsKICAgICAgICByZXNwb25kZXIuYWNjZXB0KG1lc3NhZ2UpOwogICAgICB9KTsKICAgICAgcmV0dXJuIHRydWU7CiAgICBjYXNlIGtNZWRpYVJvdXRlUHJvdmlkZXJfU2VuZFJvdXRlTWVzc2FnZV9OYW1lOgogICAgICB2YXIgcGFyYW1zID0gcmVhZGVyLmRlY29kZVN0cnVjdChNZWRpYVJvdXRlUHJvdmlkZXJfU2VuZFJvdXRlTWVzc2FnZV9QYXJhbXMpOwogICAgICB0aGlzLnNlbmRSb3V0ZU1lc3NhZ2UocGFyYW1zLm1lZGlhUm91dGVJZCwgcGFyYW1zLm1lc3NhZ2UpLnRoZW4oZnVuY3Rpb24ocmVzcG9uc2UpIHsKICAgICAgICB2YXIgcmVzcG9uc2VQYXJhbXMgPQogICAgICAgICAgICBuZXcgTWVkaWFSb3V0ZVByb3ZpZGVyX1NlbmRSb3V0ZU1lc3NhZ2VfUmVzcG9uc2VQYXJhbXMoKTsKICAgICAgICByZXNwb25zZVBhcmFtcy5zZW50ID0gcmVzcG9uc2Uuc2VudDsKICAgICAgICB2YXIgYnVpbGRlciA9IG5ldyBjb2RlYy5NZXNzYWdlVjFCdWlsZGVyKAogICAgICAgICAgICBrTWVkaWFSb3V0ZVByb3ZpZGVyX1NlbmRSb3V0ZU1lc3NhZ2VfTmFtZSwKICAgICAgICAgICAgY29kZWMuYWxpZ24oTWVkaWFSb3V0ZVByb3ZpZGVyX1NlbmRSb3V0ZU1lc3NhZ2VfUmVzcG9uc2VQYXJhbXMuZW5jb2RlZFNpemUpLAogICAgICAgICAgICBjb2RlYy5rTWVzc2FnZUlzUmVzcG9uc2UsIHJlYWRlci5yZXF1ZXN0SUQpOwogICAgICAgIGJ1aWxkZXIuZW5jb2RlU3RydWN0KE1lZGlhUm91dGVQcm92aWRlcl9TZW5kUm91dGVNZXNzYWdlX1Jlc3BvbnNlUGFyYW1zLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlc3BvbnNlUGFyYW1zKTsKICAgICAgICB2YXIgbWVzc2FnZSA9IGJ1aWxkZXIuZmluaXNoKCk7CiAgICAgICAgcmVzcG9uZGVyLmFjY2VwdChtZXNzYWdlKTsKICAgICAgfSk7CiAgICAgIHJldHVybiB0cnVlOwogICAgY2FzZSBrTWVkaWFSb3V0ZVByb3ZpZGVyX1NlbmRSb3V0ZUJpbmFyeU1lc3NhZ2VfTmFtZToKICAgICAgdmFyIHBhcmFtcyA9IHJlYWRlci5kZWNvZGVTdHJ1Y3QoTWVkaWFSb3V0ZVByb3ZpZGVyX1NlbmRSb3V0ZUJpbmFyeU1lc3NhZ2VfUGFyYW1zKTsKICAgICAgdGhpcy5zZW5kUm91dGVCaW5hcnlNZXNzYWdlKHBhcmFtcy5tZWRpYVJvdXRlSWQsIHBhcmFtcy5kYXRhKS50aGVuKGZ1bmN0aW9uKHJlc3BvbnNlKSB7CiAgICAgICAgdmFyIHJlc3BvbnNlUGFyYW1zID0KICAgICAgICAgICAgbmV3IE1lZGlhUm91dGVQcm92aWRlcl9TZW5kUm91dGVCaW5hcnlNZXNzYWdlX1Jlc3BvbnNlUGFyYW1zKCk7CiAgICAgICAgcmVzcG9uc2VQYXJhbXMuc2VudCA9IHJlc3BvbnNlLnNlbnQ7CiAgICAgICAgdmFyIGJ1aWxkZXIgPSBuZXcgY29kZWMuTWVzc2FnZVYxQnVpbGRlcigKICAgICAgICAgICAga01lZGlhUm91dGVQcm92aWRlcl9TZW5kUm91dGVCaW5hcnlNZXNzYWdlX05hbWUsCiAgICAgICAgICAgIGNvZGVjLmFsaWduKE1lZGlhUm91dGVQcm92aWRlcl9TZW5kUm91dGVCaW5hcnlNZXNzYWdlX1Jlc3BvbnNlUGFyYW1zLmVuY29kZWRTaXplKSwKICAgICAgICAgICAgY29kZWMua01lc3NhZ2VJc1Jlc3BvbnNlLCByZWFkZXIucmVxdWVzdElEKTsKICAgICAgICBidWlsZGVyLmVuY29kZVN0cnVjdChNZWRpYVJvdXRlUHJvdmlkZXJfU2VuZFJvdXRlQmluYXJ5TWVzc2FnZV9SZXNwb25zZVBhcmFtcywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXNwb25zZVBhcmFtcyk7CiAgICAgICAgdmFyIG1lc3NhZ2UgPSBidWlsZGVyLmZpbmlzaCgpOwogICAgICAgIHJlc3BvbmRlci5hY2NlcHQobWVzc2FnZSk7CiAgICAgIH0pOwogICAgICByZXR1cm4gdHJ1ZTsKICAgIGNhc2Uga01lZGlhUm91dGVQcm92aWRlcl9TZWFyY2hTaW5rc19OYW1lOgogICAgICB2YXIgcGFyYW1zID0gcmVhZGVyLmRlY29kZVN0cnVjdChNZWRpYVJvdXRlUHJvdmlkZXJfU2VhcmNoU2lua3NfUGFyYW1zKTsKICAgICAgdGhpcy5zZWFyY2hTaW5rcyhwYXJhbXMuc2lua0lkLCBwYXJhbXMubWVkaWFTb3VyY2UsIHBhcmFtcy5zZWFyY2hDcml0ZXJpYSkudGhlbihmdW5jdGlvbihyZXNwb25zZSkgewogICAgICAgIHZhciByZXNwb25zZVBhcmFtcyA9CiAgICAgICAgICAgIG5ldyBNZWRpYVJvdXRlUHJvdmlkZXJfU2VhcmNoU2lua3NfUmVzcG9uc2VQYXJhbXMoKTsKICAgICAgICByZXNwb25zZVBhcmFtcy5zaW5rSWQgPSByZXNwb25zZS5zaW5rSWQ7CiAgICAgICAgdmFyIGJ1aWxkZXIgPSBuZXcgY29kZWMuTWVzc2FnZVYxQnVpbGRlcigKICAgICAgICAgICAga01lZGlhUm91dGVQcm92aWRlcl9TZWFyY2hTaW5rc19OYW1lLAogICAgICAgICAgICBjb2RlYy5hbGlnbihNZWRpYVJvdXRlUHJvdmlkZXJfU2VhcmNoU2lua3NfUmVzcG9uc2VQYXJhbXMuZW5jb2RlZFNpemUpLAogICAgICAgICAgICBjb2RlYy5rTWVzc2FnZUlzUmVzcG9uc2UsIHJlYWRlci5yZXF1ZXN0SUQpOwogICAgICAgIGJ1aWxkZXIuZW5jb2RlU3RydWN0KE1lZGlhUm91dGVQcm92aWRlcl9TZWFyY2hTaW5rc19SZXNwb25zZVBhcmFtcywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXNwb25zZVBhcmFtcyk7CiAgICAgICAgdmFyIG1lc3NhZ2UgPSBidWlsZGVyLmZpbmlzaCgpOwogICAgICAgIHJlc3BvbmRlci5hY2NlcHQobWVzc2FnZSk7CiAgICAgIH0pOwogICAgICByZXR1cm4gdHJ1ZTsKICAgIGNhc2Uga01lZGlhUm91dGVQcm92aWRlcl9DcmVhdGVNZWRpYVJvdXRlQ29udHJvbGxlcl9OYW1lOgogICAgICB2YXIgcGFyYW1zID0gcmVhZGVyLmRlY29kZVN0cnVjdChNZWRpYVJvdXRlUHJvdmlkZXJfQ3JlYXRlTWVkaWFSb3V0ZUNvbnRyb2xsZXJfUGFyYW1zKTsKICAgICAgdGhpcy5jcmVhdGVNZWRpYVJvdXRlQ29udHJvbGxlcihwYXJhbXMucm91dGVJZCwgcGFyYW1zLm1lZGlhQ29udHJvbGxlciwgcGFyYW1zLm9ic2VydmVyKS50aGVuKGZ1bmN0aW9uKHJlc3BvbnNlKSB7CiAgICAgICAgdmFyIHJlc3BvbnNlUGFyYW1zID0KICAgICAgICAgICAgbmV3IE1lZGlhUm91dGVQcm92aWRlcl9DcmVhdGVNZWRpYVJvdXRlQ29udHJvbGxlcl9SZXNwb25zZVBhcmFtcygpOwogICAgICAgIHJlc3BvbnNlUGFyYW1zLnN1Y2Nlc3MgPSByZXNwb25zZS5zdWNjZXNzOwogICAgICAgIHZhciBidWlsZGVyID0gbmV3IGNvZGVjLk1lc3NhZ2VWMUJ1aWxkZXIoCiAgICAgICAgICAgIGtNZWRpYVJvdXRlUHJvdmlkZXJfQ3JlYXRlTWVkaWFSb3V0ZUNvbnRyb2xsZXJfTmFtZSwKICAgICAgICAgICAgY29kZWMuYWxpZ24oTWVkaWFSb3V0ZVByb3ZpZGVyX0NyZWF0ZU1lZGlhUm91dGVDb250cm9sbGVyX1Jlc3BvbnNlUGFyYW1zLmVuY29kZWRTaXplKSwKICAgICAgICAgICAgY29kZWMua01lc3NhZ2VJc1Jlc3BvbnNlLCByZWFkZXIucmVxdWVzdElEKTsKICAgICAgICBidWlsZGVyLmVuY29kZVN0cnVjdChNZWRpYVJvdXRlUHJvdmlkZXJfQ3JlYXRlTWVkaWFSb3V0ZUNvbnRyb2xsZXJfUmVzcG9uc2VQYXJhbXMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVzcG9uc2VQYXJhbXMpOwogICAgICAgIHZhciBtZXNzYWdlID0gYnVpbGRlci5maW5pc2goKTsKICAgICAgICByZXNwb25kZXIuYWNjZXB0KG1lc3NhZ2UpOwogICAgICB9KTsKICAgICAgcmV0dXJuIHRydWU7CiAgICBkZWZhdWx0OgogICAgICByZXR1cm4gZmFsc2U7CiAgICB9CiAgfTsKCiAgZnVuY3Rpb24gdmFsaWRhdGVNZWRpYVJvdXRlUHJvdmlkZXJSZXF1ZXN0KG1lc3NhZ2VWYWxpZGF0b3IpIHsKICAgIHZhciBtZXNzYWdlID0gbWVzc2FnZVZhbGlkYXRvci5tZXNzYWdlOwogICAgdmFyIHBhcmFtc0NsYXNzID0gbnVsbDsKICAgIHN3aXRjaCAobWVzc2FnZS5nZXROYW1lKCkpIHsKICAgICAgY2FzZSBrTWVkaWFSb3V0ZVByb3ZpZGVyX0NyZWF0ZVJvdXRlX05hbWU6CiAgICAgICAgaWYgKG1lc3NhZ2UuZXhwZWN0c1Jlc3BvbnNlKCkpCiAgICAgICAgICBwYXJhbXNDbGFzcyA9IE1lZGlhUm91dGVQcm92aWRlcl9DcmVhdGVSb3V0ZV9QYXJhbXM7CiAgICAgIGJyZWFrOwogICAgICBjYXNlIGtNZWRpYVJvdXRlUHJvdmlkZXJfSm9pblJvdXRlX05hbWU6CiAgICAgICAgaWYgKG1lc3NhZ2UuZXhwZWN0c1Jlc3BvbnNlKCkpCiAgICAgICAgICBwYXJhbXNDbGFzcyA9IE1lZGlhUm91dGVQcm92aWRlcl9Kb2luUm91dGVfUGFyYW1zOwogICAgICBicmVhazsKICAgICAgY2FzZSBrTWVkaWFSb3V0ZVByb3ZpZGVyX0Nvbm5lY3RSb3V0ZUJ5Um91dGVJZF9OYW1lOgogICAgICAgIGlmIChtZXNzYWdlLmV4cGVjdHNSZXNwb25zZSgpKQogICAgICAgICAgcGFyYW1zQ2xhc3MgPSBNZWRpYVJvdXRlUHJvdmlkZXJfQ29ubmVjdFJvdXRlQnlSb3V0ZUlkX1BhcmFtczsKICAgICAgYnJlYWs7CiAgICAgIGNhc2Uga01lZGlhUm91dGVQcm92aWRlcl9UZXJtaW5hdGVSb3V0ZV9OYW1lOgogICAgICAgIGlmIChtZXNzYWdlLmV4cGVjdHNSZXNwb25zZSgpKQogICAgICAgICAgcGFyYW1zQ2xhc3MgPSBNZWRpYVJvdXRlUHJvdmlkZXJfVGVybWluYXRlUm91dGVfUGFyYW1zOwogICAgICBicmVhazsKICAgICAgY2FzZSBrTWVkaWFSb3V0ZVByb3ZpZGVyX1NlbmRSb3V0ZU1lc3NhZ2VfTmFtZToKICAgICAgICBpZiAobWVzc2FnZS5leHBlY3RzUmVzcG9uc2UoKSkKICAgICAgICAgIHBhcmFtc0NsYXNzID0gTWVkaWFSb3V0ZVByb3ZpZGVyX1NlbmRSb3V0ZU1lc3NhZ2VfUGFyYW1zOwogICAgICBicmVhazsKICAgICAgY2FzZSBrTWVkaWFSb3V0ZVByb3ZpZGVyX1NlbmRSb3V0ZUJpbmFyeU1lc3NhZ2VfTmFtZToKICAgICAgICBpZiAobWVzc2FnZS5leHBlY3RzUmVzcG9uc2UoKSkKICAgICAgICAgIHBhcmFtc0NsYXNzID0gTWVkaWFSb3V0ZVByb3ZpZGVyX1NlbmRSb3V0ZUJpbmFyeU1lc3NhZ2VfUGFyYW1zOwogICAgICBicmVhazsKICAgICAgY2FzZSBrTWVkaWFSb3V0ZVByb3ZpZGVyX1N0YXJ0T2JzZXJ2aW5nTWVkaWFTaW5rc19OYW1lOgogICAgICAgIGlmICghbWVzc2FnZS5leHBlY3RzUmVzcG9uc2UoKSAmJiAhbWVzc2FnZS5pc1Jlc3BvbnNlKCkpCiAgICAgICAgICBwYXJhbXNDbGFzcyA9IE1lZGlhUm91dGVQcm92aWRlcl9TdGFydE9ic2VydmluZ01lZGlhU2lua3NfUGFyYW1zOwogICAgICBicmVhazsKICAgICAgY2FzZSBrTWVkaWFSb3V0ZVByb3ZpZGVyX1N0b3BPYnNlcnZpbmdNZWRpYVNpbmtzX05hbWU6CiAgICAgICAgaWYgKCFtZXNzYWdlLmV4cGVjdHNSZXNwb25zZSgpICYmICFtZXNzYWdlLmlzUmVzcG9uc2UoKSkKICAgICAgICAgIHBhcmFtc0NsYXNzID0gTWVkaWFSb3V0ZVByb3ZpZGVyX1N0b3BPYnNlcnZpbmdNZWRpYVNpbmtzX1BhcmFtczsKICAgICAgYnJlYWs7CiAgICAgIGNhc2Uga01lZGlhUm91dGVQcm92aWRlcl9TdGFydE9ic2VydmluZ01lZGlhUm91dGVzX05hbWU6CiAgICAgICAgaWYgKCFtZXNzYWdlLmV4cGVjdHNSZXNwb25zZSgpICYmICFtZXNzYWdlLmlzUmVzcG9uc2UoKSkKICAgICAgICAgIHBhcmFtc0NsYXNzID0gTWVkaWFSb3V0ZVByb3ZpZGVyX1N0YXJ0T2JzZXJ2aW5nTWVkaWFSb3V0ZXNfUGFyYW1zOwogICAgICBicmVhazsKICAgICAgY2FzZSBrTWVkaWFSb3V0ZVByb3ZpZGVyX1N0b3BPYnNlcnZpbmdNZWRpYVJvdXRlc19OYW1lOgogICAgICAgIGlmICghbWVzc2FnZS5leHBlY3RzUmVzcG9uc2UoKSAmJiAhbWVzc2FnZS5pc1Jlc3BvbnNlKCkpCiAgICAgICAgICBwYXJhbXNDbGFzcyA9IE1lZGlhUm91dGVQcm92aWRlcl9TdG9wT2JzZXJ2aW5nTWVkaWFSb3V0ZXNfUGFyYW1zOwogICAgICBicmVhazsKICAgICAgY2FzZSBrTWVkaWFSb3V0ZVByb3ZpZGVyX1N0YXJ0TGlzdGVuaW5nRm9yUm91dGVNZXNzYWdlc19OYW1lOgogICAgICAgIGlmICghbWVzc2FnZS5leHBlY3RzUmVzcG9uc2UoKSAmJiAhbWVzc2FnZS5pc1Jlc3BvbnNlKCkpCiAgICAgICAgICBwYXJhbXNDbGFzcyA9IE1lZGlhUm91dGVQcm92aWRlcl9TdGFydExpc3RlbmluZ0ZvclJvdXRlTWVzc2FnZXNfUGFyYW1zOwogICAgICBicmVhazsKICAgICAgY2FzZSBrTWVkaWFSb3V0ZVByb3ZpZGVyX1N0b3BMaXN0ZW5pbmdGb3JSb3V0ZU1lc3NhZ2VzX05hbWU6CiAgICAgICAgaWYgKCFtZXNzYWdlLmV4cGVjdHNSZXNwb25zZSgpICYmICFtZXNzYWdlLmlzUmVzcG9uc2UoKSkKICAgICAgICAgIHBhcmFtc0NsYXNzID0gTWVkaWFSb3V0ZVByb3ZpZGVyX1N0b3BMaXN0ZW5pbmdGb3JSb3V0ZU1lc3NhZ2VzX1BhcmFtczsKICAgICAgYnJlYWs7CiAgICAgIGNhc2Uga01lZGlhUm91dGVQcm92aWRlcl9EZXRhY2hSb3V0ZV9OYW1lOgogICAgICAgIGlmICghbWVzc2FnZS5leHBlY3RzUmVzcG9uc2UoKSAmJiAhbWVzc2FnZS5pc1Jlc3BvbnNlKCkpCiAgICAgICAgICBwYXJhbXNDbGFzcyA9IE1lZGlhUm91dGVQcm92aWRlcl9EZXRhY2hSb3V0ZV9QYXJhbXM7CiAgICAgIGJyZWFrOwogICAgICBjYXNlIGtNZWRpYVJvdXRlUHJvdmlkZXJfRW5hYmxlTWRuc0Rpc2NvdmVyeV9OYW1lOgogICAgICAgIGlmICghbWVzc2FnZS5leHBlY3RzUmVzcG9uc2UoKSAmJiAhbWVzc2FnZS5pc1Jlc3BvbnNlKCkpCiAgICAgICAgICBwYXJhbXNDbGFzcyA9IE1lZGlhUm91dGVQcm92aWRlcl9FbmFibGVNZG5zRGlzY292ZXJ5X1BhcmFtczsKICAgICAgYnJlYWs7CiAgICAgIGNhc2Uga01lZGlhUm91dGVQcm92aWRlcl9VcGRhdGVNZWRpYVNpbmtzX05hbWU6CiAgICAgICAgaWYgKCFtZXNzYWdlLmV4cGVjdHNSZXNwb25zZSgpICYmICFtZXNzYWdlLmlzUmVzcG9uc2UoKSkKICAgICAgICAgIHBhcmFtc0NsYXNzID0gTWVkaWFSb3V0ZVByb3ZpZGVyX1VwZGF0ZU1lZGlhU2lua3NfUGFyYW1zOwogICAgICBicmVhazsKICAgICAgY2FzZSBrTWVkaWFSb3V0ZVByb3ZpZGVyX1NlYXJjaFNpbmtzX05hbWU6CiAgICAgICAgaWYgKG1lc3NhZ2UuZXhwZWN0c1Jlc3BvbnNlKCkpCiAgICAgICAgICBwYXJhbXNDbGFzcyA9IE1lZGlhUm91dGVQcm92aWRlcl9TZWFyY2hTaW5rc19QYXJhbXM7CiAgICAgIGJyZWFrOwogICAgICBjYXNlIGtNZWRpYVJvdXRlUHJvdmlkZXJfUHJvdmlkZVNpbmtzX05hbWU6CiAgICAgICAgaWYgKCFtZXNzYWdlLmV4cGVjdHNSZXNwb25zZSgpICYmICFtZXNzYWdlLmlzUmVzcG9uc2UoKSkKICAgICAgICAgIHBhcmFtc0NsYXNzID0gTWVkaWFSb3V0ZVByb3ZpZGVyX1Byb3ZpZGVTaW5rc19QYXJhbXM7CiAgICAgIGJyZWFrOwogICAgICBjYXNlIGtNZWRpYVJvdXRlUHJvdmlkZXJfQ3JlYXRlTWVkaWFSb3V0ZUNvbnRyb2xsZXJfTmFtZToKICAgICAgICBpZiAobWVzc2FnZS5leHBlY3RzUmVzcG9uc2UoKSkKICAgICAgICAgIHBhcmFtc0NsYXNzID0gTWVkaWFSb3V0ZVByb3ZpZGVyX0NyZWF0ZU1lZGlhUm91dGVDb250cm9sbGVyX1BhcmFtczsKICAgICAgYnJlYWs7CiAgICB9CiAgICBpZiAocGFyYW1zQ2xhc3MgPT09IG51bGwpCiAgICAgIHJldHVybiB2YWxpZGF0b3IudmFsaWRhdGlvbkVycm9yLk5PTkU7CiAgICByZXR1cm4gcGFyYW1zQ2xhc3MudmFsaWRhdGUobWVzc2FnZVZhbGlkYXRvciwgbWVzc2FnZVZhbGlkYXRvci5tZXNzYWdlLmdldEhlYWRlck51bUJ5dGVzKCkpOwogIH0KCiAgZnVuY3Rpb24gdmFsaWRhdGVNZWRpYVJvdXRlUHJvdmlkZXJSZXNwb25zZShtZXNzYWdlVmFsaWRhdG9yKSB7CiAgIHZhciBtZXNzYWdlID0gbWVzc2FnZVZhbGlkYXRvci5tZXNzYWdlOwogICB2YXIgcGFyYW1zQ2xhc3MgPSBudWxsOwogICBzd2l0Y2ggKG1lc3NhZ2UuZ2V0TmFtZSgpKSB7CiAgICAgIGNhc2Uga01lZGlhUm91dGVQcm92aWRlcl9DcmVhdGVSb3V0ZV9OYW1lOgogICAgICAgIGlmIChtZXNzYWdlLmlzUmVzcG9uc2UoKSkKICAgICAgICAgIHBhcmFtc0NsYXNzID0gTWVkaWFSb3V0ZVByb3ZpZGVyX0NyZWF0ZVJvdXRlX1Jlc3BvbnNlUGFyYW1zOwogICAgICAgIGJyZWFrOwogICAgICBjYXNlIGtNZWRpYVJvdXRlUHJvdmlkZXJfSm9pblJvdXRlX05hbWU6CiAgICAgICAgaWYgKG1lc3NhZ2UuaXNSZXNwb25zZSgpKQogICAgICAgICAgcGFyYW1zQ2xhc3MgPSBNZWRpYVJvdXRlUHJvdmlkZXJfSm9pblJvdXRlX1Jlc3BvbnNlUGFyYW1zOwogICAgICAgIGJyZWFrOwogICAgICBjYXNlIGtNZWRpYVJvdXRlUHJvdmlkZXJfQ29ubmVjdFJvdXRlQnlSb3V0ZUlkX05hbWU6CiAgICAgICAgaWYgKG1lc3NhZ2UuaXNSZXNwb25zZSgpKQogICAgICAgICAgcGFyYW1zQ2xhc3MgPSBNZWRpYVJvdXRlUHJvdmlkZXJfQ29ubmVjdFJvdXRlQnlSb3V0ZUlkX1Jlc3BvbnNlUGFyYW1zOwogICAgICAgIGJyZWFrOwogICAgICBjYXNlIGtNZWRpYVJvdXRlUHJvdmlkZXJfVGVybWluYXRlUm91dGVfTmFtZToKICAgICAgICBpZiAobWVzc2FnZS5pc1Jlc3BvbnNlKCkpCiAgICAgICAgICBwYXJhbXNDbGFzcyA9IE1lZGlhUm91dGVQcm92aWRlcl9UZXJtaW5hdGVSb3V0ZV9SZXNwb25zZVBhcmFtczsKICAgICAgICBicmVhazsKICAgICAgY2FzZSBrTWVkaWFSb3V0ZVByb3ZpZGVyX1NlbmRSb3V0ZU1lc3NhZ2VfTmFtZToKICAgICAgICBpZiAobWVzc2FnZS5pc1Jlc3BvbnNlKCkpCiAgICAgICAgICBwYXJhbXNDbGFzcyA9IE1lZGlhUm91dGVQcm92aWRlcl9TZW5kUm91dGVNZXNzYWdlX1Jlc3BvbnNlUGFyYW1zOwogICAgICAgIGJyZWFrOwogICAgICBjYXNlIGtNZWRpYVJvdXRlUHJvdmlkZXJfU2VuZFJvdXRlQmluYXJ5TWVzc2FnZV9OYW1lOgogICAgICAgIGlmIChtZXNzYWdlLmlzUmVzcG9uc2UoKSkKICAgICAgICAgIHBhcmFtc0NsYXNzID0gTWVkaWFSb3V0ZVByb3ZpZGVyX1NlbmRSb3V0ZUJpbmFyeU1lc3NhZ2VfUmVzcG9uc2VQYXJhbXM7CiAgICAgICAgYnJlYWs7CiAgICAgIGNhc2Uga01lZGlhUm91dGVQcm92aWRlcl9TZWFyY2hTaW5rc19OYW1lOgogICAgICAgIGlmIChtZXNzYWdlLmlzUmVzcG9uc2UoKSkKICAgICAgICAgIHBhcmFtc0NsYXNzID0gTWVkaWFSb3V0ZVByb3ZpZGVyX1NlYXJjaFNpbmtzX1Jlc3BvbnNlUGFyYW1zOwogICAgICAgIGJyZWFrOwogICAgICBjYXNlIGtNZWRpYVJvdXRlUHJvdmlkZXJfQ3JlYXRlTWVkaWFSb3V0ZUNvbnRyb2xsZXJfTmFtZToKICAgICAgICBpZiAobWVzc2FnZS5pc1Jlc3BvbnNlKCkpCiAgICAgICAgICBwYXJhbXNDbGFzcyA9IE1lZGlhUm91dGVQcm92aWRlcl9DcmVhdGVNZWRpYVJvdXRlQ29udHJvbGxlcl9SZXNwb25zZVBhcmFtczsKICAgICAgICBicmVhazsKICAgIH0KICAgIGlmIChwYXJhbXNDbGFzcyA9PT0gbnVsbCkKICAgICAgcmV0dXJuIHZhbGlkYXRvci52YWxpZGF0aW9uRXJyb3IuTk9ORTsKICAgIHJldHVybiBwYXJhbXNDbGFzcy52YWxpZGF0ZShtZXNzYWdlVmFsaWRhdG9yLCBtZXNzYWdlVmFsaWRhdG9yLm1lc3NhZ2UuZ2V0SGVhZGVyTnVtQnl0ZXMoKSk7CiAgfQoKICB2YXIgTWVkaWFSb3V0ZVByb3ZpZGVyID0gewogICAgbmFtZTogJ21lZGlhX3JvdXRlcjo6bW9qb206Ok1lZGlhUm91dGVQcm92aWRlcicsCiAgICBrVmVyc2lvbjogMCwKICAgIHB0ckNsYXNzOiBNZWRpYVJvdXRlUHJvdmlkZXJQdHIsCiAgICBwcm94eUNsYXNzOiBNZWRpYVJvdXRlUHJvdmlkZXJQcm94eSwKICAgIHN0dWJDbGFzczogTWVkaWFSb3V0ZVByb3ZpZGVyU3R1YiwKICAgIHZhbGlkYXRlUmVxdWVzdDogdmFsaWRhdGVNZWRpYVJvdXRlUHJvdmlkZXJSZXF1ZXN0LAogICAgdmFsaWRhdGVSZXNwb25zZTogdmFsaWRhdGVNZWRpYVJvdXRlUHJvdmlkZXJSZXNwb25zZSwKICB9OwogIE1lZGlhUm91dGVQcm92aWRlci5JZCA9IHt9OwogIE1lZGlhUm91dGVQcm92aWRlci5JZC5FWFRFTlNJT04gPSAwOwogIE1lZGlhUm91dGVQcm92aWRlci5JZC5XSVJFRF9ESVNQTEFZID0gTWVkaWFSb3V0ZVByb3ZpZGVyLklkLkVYVEVOU0lPTiArIDE7CgogIE1lZGlhUm91dGVQcm92aWRlci5JZC5pc0tub3duRW51bVZhbHVlID0gZnVuY3Rpb24odmFsdWUpIHsKICAgIHN3aXRjaCAodmFsdWUpIHsKICAgIGNhc2UgMDoKICAgIGNhc2UgMToKICAgICAgcmV0dXJuIHRydWU7CiAgICB9CiAgICByZXR1cm4gZmFsc2U7CiAgfTsKCiAgTWVkaWFSb3V0ZVByb3ZpZGVyLklkLnZhbGlkYXRlID0gZnVuY3Rpb24oZW51bVZhbHVlKSB7CiAgICB2YXIgaXNFeHRlbnNpYmxlID0gZmFsc2U7CiAgICBpZiAoaXNFeHRlbnNpYmxlIHx8IHRoaXMuaXNLbm93bkVudW1WYWx1ZShlbnVtVmFsdWUpKQogICAgICByZXR1cm4gdmFsaWRhdG9yLnZhbGlkYXRpb25FcnJvci5OT05FOwoKICAgIHJldHVybiB2YWxpZGF0b3IudmFsaWRhdGlvbkVycm9yLlVOS05PV05fRU5VTV9WQUxVRTsKICB9OwogIE1lZGlhUm91dGVQcm92aWRlclN0dWIucHJvdG90eXBlLnZhbGlkYXRvciA9IHZhbGlkYXRlTWVkaWFSb3V0ZVByb3ZpZGVyUmVxdWVzdDsKICBNZWRpYVJvdXRlUHJvdmlkZXJQcm94eS5wcm90b3R5cGUudmFsaWRhdG9yID0gdmFsaWRhdGVNZWRpYVJvdXRlUHJvdmlkZXJSZXNwb25zZTsKICB2YXIga01lZGlhUm91dGVyX1JlZ2lzdGVyTWVkaWFSb3V0ZVByb3ZpZGVyX05hbWUgPSAxMzcxMTE5MjE3OwogIHZhciBrTWVkaWFSb3V0ZXJfT25TaW5rc1JlY2VpdmVkX05hbWUgPSAxMjc3ODQwMzkxOwogIHZhciBrTWVkaWFSb3V0ZXJfT25Jc3N1ZV9OYW1lID0gMTExODIwNDA3MDsKICB2YXIga01lZGlhUm91dGVyX09uUm91dGVzVXBkYXRlZF9OYW1lID0gOTU5ODIyMzk2OwogIHZhciBrTWVkaWFSb3V0ZXJfT25TaW5rQXZhaWxhYmlsaXR5VXBkYXRlZF9OYW1lID0gMTU4MjU1MTc5ODsKICB2YXIga01lZGlhUm91dGVyX09uUHJlc2VudGF0aW9uQ29ubmVjdGlvblN0YXRlQ2hhbmdlZF9OYW1lID0gMTM2NzA0MzcwNTsKICB2YXIga01lZGlhUm91dGVyX09uUHJlc2VudGF0aW9uQ29ubmVjdGlvbkNsb3NlZF9OYW1lID0gMTcwMTA1NzQxOwogIHZhciBrTWVkaWFSb3V0ZXJfT25Sb3V0ZU1lc3NhZ2VzUmVjZWl2ZWRfTmFtZSA9IDI3NzA1NDA2MzsKICB2YXIga01lZGlhUm91dGVyX09uTWVkaWFSZW1vdGVyQ3JlYXRlZF9OYW1lID0gNjk3MTYzMTQ7CgogIGZ1bmN0aW9uIE1lZGlhUm91dGVyUHRyKGhhbmRsZU9yUHRySW5mbykgewogICAgdGhpcy5wdHIgPSBuZXcgYmluZGluZ3MuSW50ZXJmYWNlUHRyQ29udHJvbGxlcihNZWRpYVJvdXRlciwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaGFuZGxlT3JQdHJJbmZvKTsKICB9CgogIGZ1bmN0aW9uIE1lZGlhUm91dGVyQXNzb2NpYXRlZFB0cihhc3NvY2lhdGVkSW50ZXJmYWNlUHRySW5mbykgewogICAgdGhpcy5wdHIgPSBuZXcgYXNzb2NpYXRlZEJpbmRpbmdzLkFzc29jaWF0ZWRJbnRlcmZhY2VQdHJDb250cm9sbGVyKAogICAgICAgIE1lZGlhUm91dGVyLCBhc3NvY2lhdGVkSW50ZXJmYWNlUHRySW5mbyk7CiAgfQoKICBNZWRpYVJvdXRlckFzc29jaWF0ZWRQdHIucHJvdG90eXBlID0KICAgICAgT2JqZWN0LmNyZWF0ZShNZWRpYVJvdXRlclB0ci5wcm90b3R5cGUpOwogIE1lZGlhUm91dGVyQXNzb2NpYXRlZFB0ci5wcm90b3R5cGUuY29uc3RydWN0b3IgPQogICAgICBNZWRpYVJvdXRlckFzc29jaWF0ZWRQdHI7CgogIGZ1bmN0aW9uIE1lZGlhUm91dGVyUHJveHkocmVjZWl2ZXIpIHsKICAgIHRoaXMucmVjZWl2ZXJfID0gcmVjZWl2ZXI7CiAgfQogIE1lZGlhUm91dGVyUHRyLnByb3RvdHlwZS5yZWdpc3Rlck1lZGlhUm91dGVQcm92aWRlciA9IGZ1bmN0aW9uKCkgewogICAgcmV0dXJuIE1lZGlhUm91dGVyUHJveHkucHJvdG90eXBlLnJlZ2lzdGVyTWVkaWFSb3V0ZVByb3ZpZGVyCiAgICAgICAgLmFwcGx5KHRoaXMucHRyLmdldFByb3h5KCksIGFyZ3VtZW50cyk7CiAgfTsKCiAgTWVkaWFSb3V0ZXJQcm94eS5wcm90b3R5cGUucmVnaXN0ZXJNZWRpYVJvdXRlUHJvdmlkZXIgPSBmdW5jdGlvbihwcm92aWRlcklkLCBtZWRpYVJvdXRlclByb3ZpZGVyKSB7CiAgICB2YXIgcGFyYW1zID0gbmV3IE1lZGlhUm91dGVyX1JlZ2lzdGVyTWVkaWFSb3V0ZVByb3ZpZGVyX1BhcmFtcygpOwogICAgcGFyYW1zLnByb3ZpZGVySWQgPSBwcm92aWRlcklkOwogICAgcGFyYW1zLm1lZGlhUm91dGVyUHJvdmlkZXIgPSBtZWRpYVJvdXRlclByb3ZpZGVyOwogICAgcmV0dXJuIG5ldyBQcm9taXNlKGZ1bmN0aW9uKHJlc29sdmUsIHJlamVjdCkgewogICAgICB2YXIgYnVpbGRlciA9IG5ldyBjb2RlYy5NZXNzYWdlVjFCdWlsZGVyKAogICAgICAgICAga01lZGlhUm91dGVyX1JlZ2lzdGVyTWVkaWFSb3V0ZVByb3ZpZGVyX05hbWUsCiAgICAgICAgICBjb2RlYy5hbGlnbihNZWRpYVJvdXRlcl9SZWdpc3Rlck1lZGlhUm91dGVQcm92aWRlcl9QYXJhbXMuZW5jb2RlZFNpemUpLAogICAgICAgICAgY29kZWMua01lc3NhZ2VFeHBlY3RzUmVzcG9uc2UsIDApOwogICAgICBidWlsZGVyLmVuY29kZVN0cnVjdChNZWRpYVJvdXRlcl9SZWdpc3Rlck1lZGlhUm91dGVQcm92aWRlcl9QYXJhbXMsIHBhcmFtcyk7CiAgICAgIHZhciBtZXNzYWdlID0gYnVpbGRlci5maW5pc2goKTsKICAgICAgdGhpcy5yZWNlaXZlcl8uYWNjZXB0QW5kRXhwZWN0UmVzcG9uc2UobWVzc2FnZSkudGhlbihmdW5jdGlvbihtZXNzYWdlKSB7CiAgICAgICAgdmFyIHJlYWRlciA9IG5ldyBjb2RlYy5NZXNzYWdlUmVhZGVyKG1lc3NhZ2UpOwogICAgICAgIHZhciByZXNwb25zZVBhcmFtcyA9CiAgICAgICAgICAgIHJlYWRlci5kZWNvZGVTdHJ1Y3QoTWVkaWFSb3V0ZXJfUmVnaXN0ZXJNZWRpYVJvdXRlUHJvdmlkZXJfUmVzcG9uc2VQYXJhbXMpOwogICAgICAgIHJlc29sdmUocmVzcG9uc2VQYXJhbXMpOwogICAgICB9KS5jYXRjaChmdW5jdGlvbihyZXN1bHQpIHsKICAgICAgICByZWplY3QoRXJyb3IoIkNvbm5lY3Rpb24gZXJyb3I6ICIgKyByZXN1bHQpKTsKICAgICAgfSk7CiAgICB9LmJpbmQodGhpcykpOwogIH07CiAgTWVkaWFSb3V0ZXJQdHIucHJvdG90eXBlLm9uU2lua3NSZWNlaXZlZCA9IGZ1bmN0aW9uKCkgewogICAgcmV0dXJuIE1lZGlhUm91dGVyUHJveHkucHJvdG90eXBlLm9uU2lua3NSZWNlaXZlZAogICAgICAgIC5hcHBseSh0aGlzLnB0ci5nZXRQcm94eSgpLCBhcmd1bWVudHMpOwogIH07CgogIE1lZGlhUm91dGVyUHJveHkucHJvdG90eXBlLm9uU2lua3NSZWNlaXZlZCA9IGZ1bmN0aW9uKHByb3ZpZGVySWQsIG1lZGlhU291cmNlLCBzaW5rcywgb3JpZ2lucykgewogICAgdmFyIHBhcmFtcyA9IG5ldyBNZWRpYVJvdXRlcl9PblNpbmtzUmVjZWl2ZWRfUGFyYW1zKCk7CiAgICBwYXJhbXMucHJvdmlkZXJJZCA9IHByb3ZpZGVySWQ7CiAgICBwYXJhbXMubWVkaWFTb3VyY2UgPSBtZWRpYVNvdXJjZTsKICAgIHBhcmFtcy5zaW5rcyA9IHNpbmtzOwogICAgcGFyYW1zLm9yaWdpbnMgPSBvcmlnaW5zOwogICAgdmFyIGJ1aWxkZXIgPSBuZXcgY29kZWMuTWVzc2FnZVYwQnVpbGRlcigKICAgICAgICBrTWVkaWFSb3V0ZXJfT25TaW5rc1JlY2VpdmVkX05hbWUsCiAgICAgICAgY29kZWMuYWxpZ24oTWVkaWFSb3V0ZXJfT25TaW5rc1JlY2VpdmVkX1BhcmFtcy5lbmNvZGVkU2l6ZSkpOwogICAgYnVpbGRlci5lbmNvZGVTdHJ1Y3QoTWVkaWFSb3V0ZXJfT25TaW5rc1JlY2VpdmVkX1BhcmFtcywgcGFyYW1zKTsKICAgIHZhciBtZXNzYWdlID0gYnVpbGRlci5maW5pc2goKTsKICAgIHRoaXMucmVjZWl2ZXJfLmFjY2VwdChtZXNzYWdlKTsKICB9OwogIE1lZGlhUm91dGVyUHRyLnByb3RvdHlwZS5vbklzc3VlID0gZnVuY3Rpb24oKSB7CiAgICByZXR1cm4gTWVkaWFSb3V0ZXJQcm94eS5wcm90b3R5cGUub25Jc3N1ZQogICAgICAgIC5hcHBseSh0aGlzLnB0ci5nZXRQcm94eSgpLCBhcmd1bWVudHMpOwogIH07CgogIE1lZGlhUm91dGVyUHJveHkucHJvdG90eXBlLm9uSXNzdWUgPSBmdW5jdGlvbihpc3N1ZSkgewogICAgdmFyIHBhcmFtcyA9IG5ldyBNZWRpYVJvdXRlcl9Pbklzc3VlX1BhcmFtcygpOwogICAgcGFyYW1zLmlzc3VlID0gaXNzdWU7CiAgICB2YXIgYnVpbGRlciA9IG5ldyBjb2RlYy5NZXNzYWdlVjBCdWlsZGVyKAogICAgICAgIGtNZWRpYVJvdXRlcl9Pbklzc3VlX05hbWUsCiAgICAgICAgY29kZWMuYWxpZ24oTWVkaWFSb3V0ZXJfT25Jc3N1ZV9QYXJhbXMuZW5jb2RlZFNpemUpKTsKICAgIGJ1aWxkZXIuZW5jb2RlU3RydWN0KE1lZGlhUm91dGVyX09uSXNzdWVfUGFyYW1zLCBwYXJhbXMpOwogICAgdmFyIG1lc3NhZ2UgPSBidWlsZGVyLmZpbmlzaCgpOwogICAgdGhpcy5yZWNlaXZlcl8uYWNjZXB0KG1lc3NhZ2UpOwogIH07CiAgTWVkaWFSb3V0ZXJQdHIucHJvdG90eXBlLm9uUm91dGVzVXBkYXRlZCA9IGZ1bmN0aW9uKCkgewogICAgcmV0dXJuIE1lZGlhUm91dGVyUHJveHkucHJvdG90eXBlLm9uUm91dGVzVXBkYXRlZAogICAgICAgIC5hcHBseSh0aGlzLnB0ci5nZXRQcm94eSgpLCBhcmd1bWVudHMpOwogIH07CgogIE1lZGlhUm91dGVyUHJveHkucHJvdG90eXBlLm9uUm91dGVzVXBkYXRlZCA9IGZ1bmN0aW9uKHByb3ZpZGVySWQsIHJvdXRlcywgbWVkaWFTb3VyY2UsIGpvaW5hYmxlUm91dGVJZHMpIHsKICAgIHZhciBwYXJhbXMgPSBuZXcgTWVkaWFSb3V0ZXJfT25Sb3V0ZXNVcGRhdGVkX1BhcmFtcygpOwogICAgcGFyYW1zLnByb3ZpZGVySWQgPSBwcm92aWRlcklkOwogICAgcGFyYW1zLnJvdXRlcyA9IHJvdXRlczsKICAgIHBhcmFtcy5tZWRpYVNvdXJjZSA9IG1lZGlhU291cmNlOwogICAgcGFyYW1zLmpvaW5hYmxlUm91dGVJZHMgPSBqb2luYWJsZVJvdXRlSWRzOwogICAgdmFyIGJ1aWxkZXIgPSBuZXcgY29kZWMuTWVzc2FnZVYwQnVpbGRlcigKICAgICAgICBrTWVkaWFSb3V0ZXJfT25Sb3V0ZXNVcGRhdGVkX05hbWUsCiAgICAgICAgY29kZWMuYWxpZ24oTWVkaWFSb3V0ZXJfT25Sb3V0ZXNVcGRhdGVkX1BhcmFtcy5lbmNvZGVkU2l6ZSkpOwogICAgYnVpbGRlci5lbmNvZGVTdHJ1Y3QoTWVkaWFSb3V0ZXJfT25Sb3V0ZXNVcGRhdGVkX1BhcmFtcywgcGFyYW1zKTsKICAgIHZhciBtZXNzYWdlID0gYnVpbGRlci5maW5pc2goKTsKICAgIHRoaXMucmVjZWl2ZXJfLmFjY2VwdChtZXNzYWdlKTsKICB9OwogIE1lZGlhUm91dGVyUHRyLnByb3RvdHlwZS5vblNpbmtBdmFpbGFiaWxpdHlVcGRhdGVkID0gZnVuY3Rpb24oKSB7CiAgICByZXR1cm4gTWVkaWFSb3V0ZXJQcm94eS5wcm90b3R5cGUub25TaW5rQXZhaWxhYmlsaXR5VXBkYXRlZAogICAgICAgIC5hcHBseSh0aGlzLnB0ci5nZXRQcm94eSgpLCBhcmd1bWVudHMpOwogIH07CgogIE1lZGlhUm91dGVyUHJveHkucHJvdG90eXBlLm9uU2lua0F2YWlsYWJpbGl0eVVwZGF0ZWQgPSBmdW5jdGlvbihwcm92aWRlcklkLCBhdmFpbGFiaWxpdHkpIHsKICAgIHZhciBwYXJhbXMgPSBuZXcgTWVkaWFSb3V0ZXJfT25TaW5rQXZhaWxhYmlsaXR5VXBkYXRlZF9QYXJhbXMoKTsKICAgIHBhcmFtcy5wcm92aWRlcklkID0gcHJvdmlkZXJJZDsKICAgIHBhcmFtcy5hdmFpbGFiaWxpdHkgPSBhdmFpbGFiaWxpdHk7CiAgICB2YXIgYnVpbGRlciA9IG5ldyBjb2RlYy5NZXNzYWdlVjBCdWlsZGVyKAogICAgICAgIGtNZWRpYVJvdXRlcl9PblNpbmtBdmFpbGFiaWxpdHlVcGRhdGVkX05hbWUsCiAgICAgICAgY29kZWMuYWxpZ24oTWVkaWFSb3V0ZXJfT25TaW5rQXZhaWxhYmlsaXR5VXBkYXRlZF9QYXJhbXMuZW5jb2RlZFNpemUpKTsKICAgIGJ1aWxkZXIuZW5jb2RlU3RydWN0KE1lZGlhUm91dGVyX09uU2lua0F2YWlsYWJpbGl0eVVwZGF0ZWRfUGFyYW1zLCBwYXJhbXMpOwogICAgdmFyIG1lc3NhZ2UgPSBidWlsZGVyLmZpbmlzaCgpOwogICAgdGhpcy5yZWNlaXZlcl8uYWNjZXB0KG1lc3NhZ2UpOwogIH07CiAgTWVkaWFSb3V0ZXJQdHIucHJvdG90eXBlLm9uUHJlc2VudGF0aW9uQ29ubmVjdGlvblN0YXRlQ2hhbmdlZCA9IGZ1bmN0aW9uKCkgewogICAgcmV0dXJuIE1lZGlhUm91dGVyUHJveHkucHJvdG90eXBlLm9uUHJlc2VudGF0aW9uQ29ubmVjdGlvblN0YXRlQ2hhbmdlZAogICAgICAgIC5hcHBseSh0aGlzLnB0ci5nZXRQcm94eSgpLCBhcmd1bWVudHMpOwogIH07CgogIE1lZGlhUm91dGVyUHJveHkucHJvdG90eXBlLm9uUHJlc2VudGF0aW9uQ29ubmVjdGlvblN0YXRlQ2hhbmdlZCA9IGZ1bmN0aW9uKHJvdXRlSWQsIHN0YXRlKSB7CiAgICB2YXIgcGFyYW1zID0gbmV3IE1lZGlhUm91dGVyX09uUHJlc2VudGF0aW9uQ29ubmVjdGlvblN0YXRlQ2hhbmdlZF9QYXJhbXMoKTsKICAgIHBhcmFtcy5yb3V0ZUlkID0gcm91dGVJZDsKICAgIHBhcmFtcy5zdGF0ZSA9IHN0YXRlOwogICAgdmFyIGJ1aWxkZXIgPSBuZXcgY29kZWMuTWVzc2FnZVYwQnVpbGRlcigKICAgICAgICBrTWVkaWFSb3V0ZXJfT25QcmVzZW50YXRpb25Db25uZWN0aW9uU3RhdGVDaGFuZ2VkX05hbWUsCiAgICAgICAgY29kZWMuYWxpZ24oTWVkaWFSb3V0ZXJfT25QcmVzZW50YXRpb25Db25uZWN0aW9uU3RhdGVDaGFuZ2VkX1BhcmFtcy5lbmNvZGVkU2l6ZSkpOwogICAgYnVpbGRlci5lbmNvZGVTdHJ1Y3QoTWVkaWFSb3V0ZXJfT25QcmVzZW50YXRpb25Db25uZWN0aW9uU3RhdGVDaGFuZ2VkX1BhcmFtcywgcGFyYW1zKTsKICAgIHZhciBtZXNzYWdlID0gYnVpbGRlci5maW5pc2goKTsKICAgIHRoaXMucmVjZWl2ZXJfLmFjY2VwdChtZXNzYWdlKTsKICB9OwogIE1lZGlhUm91dGVyUHRyLnByb3RvdHlwZS5vblByZXNlbnRhdGlvbkNvbm5lY3Rpb25DbG9zZWQgPSBmdW5jdGlvbigpIHsKICAgIHJldHVybiBNZWRpYVJvdXRlclByb3h5LnByb3RvdHlwZS5vblByZXNlbnRhdGlvbkNvbm5lY3Rpb25DbG9zZWQKICAgICAgICAuYXBwbHkodGhpcy5wdHIuZ2V0UHJveHkoKSwgYXJndW1lbnRzKTsKICB9OwoKICBNZWRpYVJvdXRlclByb3h5LnByb3RvdHlwZS5vblByZXNlbnRhdGlvbkNvbm5lY3Rpb25DbG9zZWQgPSBmdW5jdGlvbihyb3V0ZUlkLCByZWFzb24sIG1lc3NhZ2UpIHsKICAgIHZhciBwYXJhbXMgPSBuZXcgTWVkaWFSb3V0ZXJfT25QcmVzZW50YXRpb25Db25uZWN0aW9uQ2xvc2VkX1BhcmFtcygpOwogICAgcGFyYW1zLnJvdXRlSWQgPSByb3V0ZUlkOwogICAgcGFyYW1zLnJlYXNvbiA9IHJlYXNvbjsKICAgIHBhcmFtcy5tZXNzYWdlID0gbWVzc2FnZTsKICAgIHZhciBidWlsZGVyID0gbmV3IGNvZGVjLk1lc3NhZ2VWMEJ1aWxkZXIoCiAgICAgICAga01lZGlhUm91dGVyX09uUHJlc2VudGF0aW9uQ29ubmVjdGlvbkNsb3NlZF9OYW1lLAogICAgICAgIGNvZGVjLmFsaWduKE1lZGlhUm91dGVyX09uUHJlc2VudGF0aW9uQ29ubmVjdGlvbkNsb3NlZF9QYXJhbXMuZW5jb2RlZFNpemUpKTsKICAgIGJ1aWxkZXIuZW5jb2RlU3RydWN0KE1lZGlhUm91dGVyX09uUHJlc2VudGF0aW9uQ29ubmVjdGlvbkNsb3NlZF9QYXJhbXMsIHBhcmFtcyk7CiAgICB2YXIgbWVzc2FnZSA9IGJ1aWxkZXIuZmluaXNoKCk7CiAgICB0aGlzLnJlY2VpdmVyXy5hY2NlcHQobWVzc2FnZSk7CiAgfTsKICBNZWRpYVJvdXRlclB0ci5wcm90b3R5cGUub25Sb3V0ZU1lc3NhZ2VzUmVjZWl2ZWQgPSBmdW5jdGlvbigpIHsKICAgIHJldHVybiBNZWRpYVJvdXRlclByb3h5LnByb3RvdHlwZS5vblJvdXRlTWVzc2FnZXNSZWNlaXZlZAogICAgICAgIC5hcHBseSh0aGlzLnB0ci5nZXRQcm94eSgpLCBhcmd1bWVudHMpOwogIH07CgogIE1lZGlhUm91dGVyUHJveHkucHJvdG90eXBlLm9uUm91dGVNZXNzYWdlc1JlY2VpdmVkID0gZnVuY3Rpb24ocm91dGVJZCwgbWVzc2FnZXMpIHsKICAgIHZhciBwYXJhbXMgPSBuZXcgTWVkaWFSb3V0ZXJfT25Sb3V0ZU1lc3NhZ2VzUmVjZWl2ZWRfUGFyYW1zKCk7CiAgICBwYXJhbXMucm91dGVJZCA9IHJvdXRlSWQ7CiAgICBwYXJhbXMubWVzc2FnZXMgPSBtZXNzYWdlczsKICAgIHZhciBidWlsZGVyID0gbmV3IGNvZGVjLk1lc3NhZ2VWMEJ1aWxkZXIoCiAgICAgICAga01lZGlhUm91dGVyX09uUm91dGVNZXNzYWdlc1JlY2VpdmVkX05hbWUsCiAgICAgICAgY29kZWMuYWxpZ24oTWVkaWFSb3V0ZXJfT25Sb3V0ZU1lc3NhZ2VzUmVjZWl2ZWRfUGFyYW1zLmVuY29kZWRTaXplKSk7CiAgICBidWlsZGVyLmVuY29kZVN0cnVjdChNZWRpYVJvdXRlcl9PblJvdXRlTWVzc2FnZXNSZWNlaXZlZF9QYXJhbXMsIHBhcmFtcyk7CiAgICB2YXIgbWVzc2FnZSA9IGJ1aWxkZXIuZmluaXNoKCk7CiAgICB0aGlzLnJlY2VpdmVyXy5hY2NlcHQobWVzc2FnZSk7CiAgfTsKICBNZWRpYVJvdXRlclB0ci5wcm90b3R5cGUub25NZWRpYVJlbW90ZXJDcmVhdGVkID0gZnVuY3Rpb24oKSB7CiAgICByZXR1cm4gTWVkaWFSb3V0ZXJQcm94eS5wcm90b3R5cGUub25NZWRpYVJlbW90ZXJDcmVhdGVkCiAgICAgICAgLmFwcGx5KHRoaXMucHRyLmdldFByb3h5KCksIGFyZ3VtZW50cyk7CiAgfTsKCiAgTWVkaWFSb3V0ZXJQcm94eS5wcm90b3R5cGUub25NZWRpYVJlbW90ZXJDcmVhdGVkID0gZnVuY3Rpb24odGFiSWQsIHJlbW90ZXIsIHJlbW90aW5nU291cmNlKSB7CiAgICB2YXIgcGFyYW1zID0gbmV3IE1lZGlhUm91dGVyX09uTWVkaWFSZW1vdGVyQ3JlYXRlZF9QYXJhbXMoKTsKICAgIHBhcmFtcy50YWJJZCA9IHRhYklkOwogICAgcGFyYW1zLnJlbW90ZXIgPSByZW1vdGVyOwogICAgcGFyYW1zLnJlbW90aW5nU291cmNlID0gcmVtb3RpbmdTb3VyY2U7CiAgICB2YXIgYnVpbGRlciA9IG5ldyBjb2RlYy5NZXNzYWdlVjBCdWlsZGVyKAogICAgICAgIGtNZWRpYVJvdXRlcl9Pbk1lZGlhUmVtb3RlckNyZWF0ZWRfTmFtZSwKICAgICAgICBjb2RlYy5hbGlnbihNZWRpYVJvdXRlcl9Pbk1lZGlhUmVtb3RlckNyZWF0ZWRfUGFyYW1zLmVuY29kZWRTaXplKSk7CiAgICBidWlsZGVyLmVuY29kZVN0cnVjdChNZWRpYVJvdXRlcl9Pbk1lZGlhUmVtb3RlckNyZWF0ZWRfUGFyYW1zLCBwYXJhbXMpOwogICAgdmFyIG1lc3NhZ2UgPSBidWlsZGVyLmZpbmlzaCgpOwogICAgdGhpcy5yZWNlaXZlcl8uYWNjZXB0KG1lc3NhZ2UpOwogIH07CgogIGZ1bmN0aW9uIE1lZGlhUm91dGVyU3R1YihkZWxlZ2F0ZSkgewogICAgdGhpcy5kZWxlZ2F0ZV8gPSBkZWxlZ2F0ZTsKICB9CiAgTWVkaWFSb3V0ZXJTdHViLnByb3RvdHlwZS5yZWdpc3Rlck1lZGlhUm91dGVQcm92aWRlciA9IGZ1bmN0aW9uKHByb3ZpZGVySWQsIG1lZGlhUm91dGVyUHJvdmlkZXIpIHsKICAgIHJldHVybiB0aGlzLmRlbGVnYXRlXyAmJiB0aGlzLmRlbGVnYXRlXy5yZWdpc3Rlck1lZGlhUm91dGVQcm92aWRlciAmJiB0aGlzLmRlbGVnYXRlXy5yZWdpc3Rlck1lZGlhUm91dGVQcm92aWRlcihwcm92aWRlcklkLCBtZWRpYVJvdXRlclByb3ZpZGVyKTsKICB9CiAgTWVkaWFSb3V0ZXJTdHViLnByb3RvdHlwZS5vblNpbmtzUmVjZWl2ZWQgPSBmdW5jdGlvbihwcm92aWRlcklkLCBtZWRpYVNvdXJjZSwgc2lua3MsIG9yaWdpbnMpIHsKICAgIHJldHVybiB0aGlzLmRlbGVnYXRlXyAmJiB0aGlzLmRlbGVnYXRlXy5vblNpbmtzUmVjZWl2ZWQgJiYgdGhpcy5kZWxlZ2F0ZV8ub25TaW5rc1JlY2VpdmVkKHByb3ZpZGVySWQsIG1lZGlhU291cmNlLCBzaW5rcywgb3JpZ2lucyk7CiAgfQogIE1lZGlhUm91dGVyU3R1Yi5wcm90b3R5cGUub25Jc3N1ZSA9IGZ1bmN0aW9uKGlzc3VlKSB7CiAgICByZXR1cm4gdGhpcy5kZWxlZ2F0ZV8gJiYgdGhpcy5kZWxlZ2F0ZV8ub25Jc3N1ZSAmJiB0aGlzLmRlbGVnYXRlXy5vbklzc3VlKGlzc3VlKTsKICB9CiAgTWVkaWFSb3V0ZXJTdHViLnByb3RvdHlwZS5vblJvdXRlc1VwZGF0ZWQgPSBmdW5jdGlvbihwcm92aWRlcklkLCByb3V0ZXMsIG1lZGlhU291cmNlLCBqb2luYWJsZVJvdXRlSWRzKSB7CiAgICByZXR1cm4gdGhpcy5kZWxlZ2F0ZV8gJiYgdGhpcy5kZWxlZ2F0ZV8ub25Sb3V0ZXNVcGRhdGVkICYmIHRoaXMuZGVsZWdhdGVfLm9uUm91dGVzVXBkYXRlZChwcm92aWRlcklkLCByb3V0ZXMsIG1lZGlhU291cmNlLCBqb2luYWJsZVJvdXRlSWRzKTsKICB9CiAgTWVkaWFSb3V0ZXJTdHViLnByb3RvdHlwZS5vblNpbmtBdmFpbGFiaWxpdHlVcGRhdGVkID0gZnVuY3Rpb24ocHJvdmlkZXJJZCwgYXZhaWxhYmlsaXR5KSB7CiAgICByZXR1cm4gdGhpcy5kZWxlZ2F0ZV8gJiYgdGhpcy5kZWxlZ2F0ZV8ub25TaW5rQXZhaWxhYmlsaXR5VXBkYXRlZCAmJiB0aGlzLmRlbGVnYXRlXy5vblNpbmtBdmFpbGFiaWxpdHlVcGRhdGVkKHByb3ZpZGVySWQsIGF2YWlsYWJpbGl0eSk7CiAgfQogIE1lZGlhUm91dGVyU3R1Yi5wcm90b3R5cGUub25QcmVzZW50YXRpb25Db25uZWN0aW9uU3RhdGVDaGFuZ2VkID0gZnVuY3Rpb24ocm91dGVJZCwgc3RhdGUpIHsKICAgIHJldHVybiB0aGlzLmRlbGVnYXRlXyAmJiB0aGlzLmRlbGVnYXRlXy5vblByZXNlbnRhdGlvbkNvbm5lY3Rpb25TdGF0ZUNoYW5nZWQgJiYgdGhpcy5kZWxlZ2F0ZV8ub25QcmVzZW50YXRpb25Db25uZWN0aW9uU3RhdGVDaGFuZ2VkKHJvdXRlSWQsIHN0YXRlKTsKICB9CiAgTWVkaWFSb3V0ZXJTdHViLnByb3RvdHlwZS5vblByZXNlbnRhdGlvbkNvbm5lY3Rpb25DbG9zZWQgPSBmdW5jdGlvbihyb3V0ZUlkLCByZWFzb24sIG1lc3NhZ2UpIHsKICAgIHJldHVybiB0aGlzLmRlbGVnYXRlXyAmJiB0aGlzLmRlbGVnYXRlXy5vblByZXNlbnRhdGlvbkNvbm5lY3Rpb25DbG9zZWQgJiYgdGhpcy5kZWxlZ2F0ZV8ub25QcmVzZW50YXRpb25Db25uZWN0aW9uQ2xvc2VkKHJvdXRlSWQsIHJlYXNvbiwgbWVzc2FnZSk7CiAgfQogIE1lZGlhUm91dGVyU3R1Yi5wcm90b3R5cGUub25Sb3V0ZU1lc3NhZ2VzUmVjZWl2ZWQgPSBmdW5jdGlvbihyb3V0ZUlkLCBtZXNzYWdlcykgewogICAgcmV0dXJuIHRoaXMuZGVsZWdhdGVfICYmIHRoaXMuZGVsZWdhdGVfLm9uUm91dGVNZXNzYWdlc1JlY2VpdmVkICYmIHRoaXMuZGVsZWdhdGVfLm9uUm91dGVNZXNzYWdlc1JlY2VpdmVkKHJvdXRlSWQsIG1lc3NhZ2VzKTsKICB9CiAgTWVkaWFSb3V0ZXJTdHViLnByb3RvdHlwZS5vbk1lZGlhUmVtb3RlckNyZWF0ZWQgPSBmdW5jdGlvbih0YWJJZCwgcmVtb3RlciwgcmVtb3RpbmdTb3VyY2UpIHsKICAgIHJldHVybiB0aGlzLmRlbGVnYXRlXyAmJiB0aGlzLmRlbGVnYXRlXy5vbk1lZGlhUmVtb3RlckNyZWF0ZWQgJiYgdGhpcy5kZWxlZ2F0ZV8ub25NZWRpYVJlbW90ZXJDcmVhdGVkKHRhYklkLCByZW1vdGVyLCByZW1vdGluZ1NvdXJjZSk7CiAgfQoKICBNZWRpYVJvdXRlclN0dWIucHJvdG90eXBlLmFjY2VwdCA9IGZ1bmN0aW9uKG1lc3NhZ2UpIHsKICAgIHZhciByZWFkZXIgPSBuZXcgY29kZWMuTWVzc2FnZVJlYWRlcihtZXNzYWdlKTsKICAgIHN3aXRjaCAocmVhZGVyLm1lc3NhZ2VOYW1lKSB7CiAgICBjYXNlIGtNZWRpYVJvdXRlcl9PblNpbmtzUmVjZWl2ZWRfTmFtZToKICAgICAgdmFyIHBhcmFtcyA9IHJlYWRlci5kZWNvZGVTdHJ1Y3QoTWVkaWFSb3V0ZXJfT25TaW5rc1JlY2VpdmVkX1BhcmFtcyk7CiAgICAgIHRoaXMub25TaW5rc1JlY2VpdmVkKHBhcmFtcy5wcm92aWRlcklkLCBwYXJhbXMubWVkaWFTb3VyY2UsIHBhcmFtcy5zaW5rcywgcGFyYW1zLm9yaWdpbnMpOwogICAgICByZXR1cm4gdHJ1ZTsKICAgIGNhc2Uga01lZGlhUm91dGVyX09uSXNzdWVfTmFtZToKICAgICAgdmFyIHBhcmFtcyA9IHJlYWRlci5kZWNvZGVTdHJ1Y3QoTWVkaWFSb3V0ZXJfT25Jc3N1ZV9QYXJhbXMpOwogICAgICB0aGlzLm9uSXNzdWUocGFyYW1zLmlzc3VlKTsKICAgICAgcmV0dXJuIHRydWU7CiAgICBjYXNlIGtNZWRpYVJvdXRlcl9PblJvdXRlc1VwZGF0ZWRfTmFtZToKICAgICAgdmFyIHBhcmFtcyA9IHJlYWRlci5kZWNvZGVTdHJ1Y3QoTWVkaWFSb3V0ZXJfT25Sb3V0ZXNVcGRhdGVkX1BhcmFtcyk7CiAgICAgIHRoaXMub25Sb3V0ZXNVcGRhdGVkKHBhcmFtcy5wcm92aWRlcklkLCBwYXJhbXMucm91dGVzLCBwYXJhbXMubWVkaWFTb3VyY2UsIHBhcmFtcy5qb2luYWJsZVJvdXRlSWRzKTsKICAgICAgcmV0dXJuIHRydWU7CiAgICBjYXNlIGtNZWRpYVJvdXRlcl9PblNpbmtBdmFpbGFiaWxpdHlVcGRhdGVkX05hbWU6CiAgICAgIHZhciBwYXJhbXMgPSByZWFkZXIuZGVjb2RlU3RydWN0KE1lZGlhUm91dGVyX09uU2lua0F2YWlsYWJpbGl0eVVwZGF0ZWRfUGFyYW1zKTsKICAgICAgdGhpcy5vblNpbmtBdmFpbGFiaWxpdHlVcGRhdGVkKHBhcmFtcy5wcm92aWRlcklkLCBwYXJhbXMuYXZhaWxhYmlsaXR5KTsKICAgICAgcmV0dXJuIHRydWU7CiAgICBjYXNlIGtNZWRpYVJvdXRlcl9PblByZXNlbnRhdGlvbkNvbm5lY3Rpb25TdGF0ZUNoYW5nZWRfTmFtZToKICAgICAgdmFyIHBhcmFtcyA9IHJlYWRlci5kZWNvZGVTdHJ1Y3QoTWVkaWFSb3V0ZXJfT25QcmVzZW50YXRpb25Db25uZWN0aW9uU3RhdGVDaGFuZ2VkX1BhcmFtcyk7CiAgICAgIHRoaXMub25QcmVzZW50YXRpb25Db25uZWN0aW9uU3RhdGVDaGFuZ2VkKHBhcmFtcy5yb3V0ZUlkLCBwYXJhbXMuc3RhdGUpOwogICAgICByZXR1cm4gdHJ1ZTsKICAgIGNhc2Uga01lZGlhUm91dGVyX09uUHJlc2VudGF0aW9uQ29ubmVjdGlvbkNsb3NlZF9OYW1lOgogICAgICB2YXIgcGFyYW1zID0gcmVhZGVyLmRlY29kZVN0cnVjdChNZWRpYVJvdXRlcl9PblByZXNlbnRhdGlvbkNvbm5lY3Rpb25DbG9zZWRfUGFyYW1zKTsKICAgICAgdGhpcy5vblByZXNlbnRhdGlvbkNvbm5lY3Rpb25DbG9zZWQocGFyYW1zLnJvdXRlSWQsIHBhcmFtcy5yZWFzb24sIHBhcmFtcy5tZXNzYWdlKTsKICAgICAgcmV0dXJuIHRydWU7CiAgICBjYXNlIGtNZWRpYVJvdXRlcl9PblJvdXRlTWVzc2FnZXNSZWNlaXZlZF9OYW1lOgogICAgICB2YXIgcGFyYW1zID0gcmVhZGVyLmRlY29kZVN0cnVjdChNZWRpYVJvdXRlcl9PblJvdXRlTWVzc2FnZXNSZWNlaXZlZF9QYXJhbXMpOwogICAgICB0aGlzLm9uUm91dGVNZXNzYWdlc1JlY2VpdmVkKHBhcmFtcy5yb3V0ZUlkLCBwYXJhbXMubWVzc2FnZXMpOwogICAgICByZXR1cm4gdHJ1ZTsKICAgIGNhc2Uga01lZGlhUm91dGVyX09uTWVkaWFSZW1vdGVyQ3JlYXRlZF9OYW1lOgogICAgICB2YXIgcGFyYW1zID0gcmVhZGVyLmRlY29kZVN0cnVjdChNZWRpYVJvdXRlcl9Pbk1lZGlhUmVtb3RlckNyZWF0ZWRfUGFyYW1zKTsKICAgICAgdGhpcy5vbk1lZGlhUmVtb3RlckNyZWF0ZWQocGFyYW1zLnRhYklkLCBwYXJhbXMucmVtb3RlciwgcGFyYW1zLnJlbW90aW5nU291cmNlKTsKICAgICAgcmV0dXJuIHRydWU7CiAgICBkZWZhdWx0OgogICAgICByZXR1cm4gZmFsc2U7CiAgICB9CiAgfTsKCiAgTWVkaWFSb3V0ZXJTdHViLnByb3RvdHlwZS5hY2NlcHRXaXRoUmVzcG9uZGVyID0KICAgICAgZnVuY3Rpb24obWVzc2FnZSwgcmVzcG9uZGVyKSB7CiAgICB2YXIgcmVhZGVyID0gbmV3IGNvZGVjLk1lc3NhZ2VSZWFkZXIobWVzc2FnZSk7CiAgICBzd2l0Y2ggKHJlYWRlci5tZXNzYWdlTmFtZSkgewogICAgY2FzZSBrTWVkaWFSb3V0ZXJfUmVnaXN0ZXJNZWRpYVJvdXRlUHJvdmlkZXJfTmFtZToKICAgICAgdmFyIHBhcmFtcyA9IHJlYWRlci5kZWNvZGVTdHJ1Y3QoTWVkaWFSb3V0ZXJfUmVnaXN0ZXJNZWRpYVJvdXRlUHJvdmlkZXJfUGFyYW1zKTsKICAgICAgdGhpcy5yZWdpc3Rlck1lZGlhUm91dGVQcm92aWRlcihwYXJhbXMucHJvdmlkZXJJZCwgcGFyYW1zLm1lZGlhUm91dGVyUHJvdmlkZXIpLnRoZW4oZnVuY3Rpb24ocmVzcG9uc2UpIHsKICAgICAgICB2YXIgcmVzcG9uc2VQYXJhbXMgPQogICAgICAgICAgICBuZXcgTWVkaWFSb3V0ZXJfUmVnaXN0ZXJNZWRpYVJvdXRlUHJvdmlkZXJfUmVzcG9uc2VQYXJhbXMoKTsKICAgICAgICByZXNwb25zZVBhcmFtcy5pbnN0YW5jZUlkID0gcmVzcG9uc2UuaW5zdGFuY2VJZDsKICAgICAgICByZXNwb25zZVBhcmFtcy5jb25maWcgPSByZXNwb25zZS5jb25maWc7CiAgICAgICAgdmFyIGJ1aWxkZXIgPSBuZXcgY29kZWMuTWVzc2FnZVYxQnVpbGRlcigKICAgICAgICAgICAga01lZGlhUm91dGVyX1JlZ2lzdGVyTWVkaWFSb3V0ZVByb3ZpZGVyX05hbWUsCiAgICAgICAgICAgIGNvZGVjLmFsaWduKE1lZGlhUm91dGVyX1JlZ2lzdGVyTWVkaWFSb3V0ZVByb3ZpZGVyX1Jlc3BvbnNlUGFyYW1zLmVuY29kZWRTaXplKSwKICAgICAgICAgICAgY29kZWMua01lc3NhZ2VJc1Jlc3BvbnNlLCByZWFkZXIucmVxdWVzdElEKTsKICAgICAgICBidWlsZGVyLmVuY29kZVN0cnVjdChNZWRpYVJvdXRlcl9SZWdpc3Rlck1lZGlhUm91dGVQcm92aWRlcl9SZXNwb25zZVBhcmFtcywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXNwb25zZVBhcmFtcyk7CiAgICAgICAgdmFyIG1lc3NhZ2UgPSBidWlsZGVyLmZpbmlzaCgpOwogICAgICAgIHJlc3BvbmRlci5hY2NlcHQobWVzc2FnZSk7CiAgICAgIH0pOwogICAgICByZXR1cm4gdHJ1ZTsKICAgIGRlZmF1bHQ6CiAgICAgIHJldHVybiBmYWxzZTsKICAgIH0KICB9OwoKICBmdW5jdGlvbiB2YWxpZGF0ZU1lZGlhUm91dGVyUmVxdWVzdChtZXNzYWdlVmFsaWRhdG9yKSB7CiAgICB2YXIgbWVzc2FnZSA9IG1lc3NhZ2VWYWxpZGF0b3IubWVzc2FnZTsKICAgIHZhciBwYXJhbXNDbGFzcyA9IG51bGw7CiAgICBzd2l0Y2ggKG1lc3NhZ2UuZ2V0TmFtZSgpKSB7CiAgICAgIGNhc2Uga01lZGlhUm91dGVyX1JlZ2lzdGVyTWVkaWFSb3V0ZVByb3ZpZGVyX05hbWU6CiAgICAgICAgaWYgKG1lc3NhZ2UuZXhwZWN0c1Jlc3BvbnNlKCkpCiAgICAgICAgICBwYXJhbXNDbGFzcyA9IE1lZGlhUm91dGVyX1JlZ2lzdGVyTWVkaWFSb3V0ZVByb3ZpZGVyX1BhcmFtczsKICAgICAgYnJlYWs7CiAgICAgIGNhc2Uga01lZGlhUm91dGVyX09uU2lua3NSZWNlaXZlZF9OYW1lOgogICAgICAgIGlmICghbWVzc2FnZS5leHBlY3RzUmVzcG9uc2UoKSAmJiAhbWVzc2FnZS5pc1Jlc3BvbnNlKCkpCiAgICAgICAgICBwYXJhbXNDbGFzcyA9IE1lZGlhUm91dGVyX09uU2lua3NSZWNlaXZlZF9QYXJhbXM7CiAgICAgIGJyZWFrOwogICAgICBjYXNlIGtNZWRpYVJvdXRlcl9Pbklzc3VlX05hbWU6CiAgICAgICAgaWYgKCFtZXNzYWdlLmV4cGVjdHNSZXNwb25zZSgpICYmICFtZXNzYWdlLmlzUmVzcG9uc2UoKSkKICAgICAgICAgIHBhcmFtc0NsYXNzID0gTWVkaWFSb3V0ZXJfT25Jc3N1ZV9QYXJhbXM7CiAgICAgIGJyZWFrOwogICAgICBjYXNlIGtNZWRpYVJvdXRlcl9PblJvdXRlc1VwZGF0ZWRfTmFtZToKICAgICAgICBpZiAoIW1lc3NhZ2UuZXhwZWN0c1Jlc3BvbnNlKCkgJiYgIW1lc3NhZ2UuaXNSZXNwb25zZSgpKQogICAgICAgICAgcGFyYW1zQ2xhc3MgPSBNZWRpYVJvdXRlcl9PblJvdXRlc1VwZGF0ZWRfUGFyYW1zOwogICAgICBicmVhazsKICAgICAgY2FzZSBrTWVkaWFSb3V0ZXJfT25TaW5rQXZhaWxhYmlsaXR5VXBkYXRlZF9OYW1lOgogICAgICAgIGlmICghbWVzc2FnZS5leHBlY3RzUmVzcG9uc2UoKSAmJiAhbWVzc2FnZS5pc1Jlc3BvbnNlKCkpCiAgICAgICAgICBwYXJhbXNDbGFzcyA9IE1lZGlhUm91dGVyX09uU2lua0F2YWlsYWJpbGl0eVVwZGF0ZWRfUGFyYW1zOwogICAgICBicmVhazsKICAgICAgY2FzZSBrTWVkaWFSb3V0ZXJfT25QcmVzZW50YXRpb25Db25uZWN0aW9uU3RhdGVDaGFuZ2VkX05hbWU6CiAgICAgICAgaWYgKCFtZXNzYWdlLmV4cGVjdHNSZXNwb25zZSgpICYmICFtZXNzYWdlLmlzUmVzcG9uc2UoKSkKICAgICAgICAgIHBhcmFtc0NsYXNzID0gTWVkaWFSb3V0ZXJfT25QcmVzZW50YXRpb25Db25uZWN0aW9uU3RhdGVDaGFuZ2VkX1BhcmFtczsKICAgICAgYnJlYWs7CiAgICAgIGNhc2Uga01lZGlhUm91dGVyX09uUHJlc2VudGF0aW9uQ29ubmVjdGlvbkNsb3NlZF9OYW1lOgogICAgICAgIGlmICghbWVzc2FnZS5leHBlY3RzUmVzcG9uc2UoKSAmJiAhbWVzc2FnZS5pc1Jlc3BvbnNlKCkpCiAgICAgICAgICBwYXJhbXNDbGFzcyA9IE1lZGlhUm91dGVyX09uUHJlc2VudGF0aW9uQ29ubmVjdGlvbkNsb3NlZF9QYXJhbXM7CiAgICAgIGJyZWFrOwogICAgICBjYXNlIGtNZWRpYVJvdXRlcl9PblJvdXRlTWVzc2FnZXNSZWNlaXZlZF9OYW1lOgogICAgICAgIGlmICghbWVzc2FnZS5leHBlY3RzUmVzcG9uc2UoKSAmJiAhbWVzc2FnZS5pc1Jlc3BvbnNlKCkpCiAgICAgICAgICBwYXJhbXNDbGFzcyA9IE1lZGlhUm91dGVyX09uUm91dGVNZXNzYWdlc1JlY2VpdmVkX1BhcmFtczsKICAgICAgYnJlYWs7CiAgICAgIGNhc2Uga01lZGlhUm91dGVyX09uTWVkaWFSZW1vdGVyQ3JlYXRlZF9OYW1lOgogICAgICAgIGlmICghbWVzc2FnZS5leHBlY3RzUmVzcG9uc2UoKSAmJiAhbWVzc2FnZS5pc1Jlc3BvbnNlKCkpCiAgICAgICAgICBwYXJhbXNDbGFzcyA9IE1lZGlhUm91dGVyX09uTWVkaWFSZW1vdGVyQ3JlYXRlZF9QYXJhbXM7CiAgICAgIGJyZWFrOwogICAgfQogICAgaWYgKHBhcmFtc0NsYXNzID09PSBudWxsKQogICAgICByZXR1cm4gdmFsaWRhdG9yLnZhbGlkYXRpb25FcnJvci5OT05FOwogICAgcmV0dXJuIHBhcmFtc0NsYXNzLnZhbGlkYXRlKG1lc3NhZ2VWYWxpZGF0b3IsIG1lc3NhZ2VWYWxpZGF0b3IubWVzc2FnZS5nZXRIZWFkZXJOdW1CeXRlcygpKTsKICB9CgogIGZ1bmN0aW9uIHZhbGlkYXRlTWVkaWFSb3V0ZXJSZXNwb25zZShtZXNzYWdlVmFsaWRhdG9yKSB7CiAgIHZhciBtZXNzYWdlID0gbWVzc2FnZVZhbGlkYXRvci5tZXNzYWdlOwogICB2YXIgcGFyYW1zQ2xhc3MgPSBudWxsOwogICBzd2l0Y2ggKG1lc3NhZ2UuZ2V0TmFtZSgpKSB7CiAgICAgIGNhc2Uga01lZGlhUm91dGVyX1JlZ2lzdGVyTWVkaWFSb3V0ZVByb3ZpZGVyX05hbWU6CiAgICAgICAgaWYgKG1lc3NhZ2UuaXNSZXNwb25zZSgpKQogICAgICAgICAgcGFyYW1zQ2xhc3MgPSBNZWRpYVJvdXRlcl9SZWdpc3Rlck1lZGlhUm91dGVQcm92aWRlcl9SZXNwb25zZVBhcmFtczsKICAgICAgICBicmVhazsKICAgIH0KICAgIGlmIChwYXJhbXNDbGFzcyA9PT0gbnVsbCkKICAgICAgcmV0dXJuIHZhbGlkYXRvci52YWxpZGF0aW9uRXJyb3IuTk9ORTsKICAgIHJldHVybiBwYXJhbXNDbGFzcy52YWxpZGF0ZShtZXNzYWdlVmFsaWRhdG9yLCBtZXNzYWdlVmFsaWRhdG9yLm1lc3NhZ2UuZ2V0SGVhZGVyTnVtQnl0ZXMoKSk7CiAgfQoKICB2YXIgTWVkaWFSb3V0ZXIgPSB7CiAgICBuYW1lOiAnbWVkaWFfcm91dGVyOjptb2pvbTo6TWVkaWFSb3V0ZXInLAogICAga1ZlcnNpb246IDAsCiAgICBwdHJDbGFzczogTWVkaWFSb3V0ZXJQdHIsCiAgICBwcm94eUNsYXNzOiBNZWRpYVJvdXRlclByb3h5LAogICAgc3R1YkNsYXNzOiBNZWRpYVJvdXRlclN0dWIsCiAgICB2YWxpZGF0ZVJlcXVlc3Q6IHZhbGlkYXRlTWVkaWFSb3V0ZXJSZXF1ZXN0LAogICAgdmFsaWRhdGVSZXNwb25zZTogdmFsaWRhdGVNZWRpYVJvdXRlclJlc3BvbnNlLAogIH07CiAgTWVkaWFSb3V0ZXIuU2lua0F2YWlsYWJpbGl0eSA9IHt9OwogIE1lZGlhUm91dGVyLlNpbmtBdmFpbGFiaWxpdHkuVU5BVkFJTEFCTEUgPSAwOwogIE1lZGlhUm91dGVyLlNpbmtBdmFpbGFiaWxpdHkuUEVSX1NPVVJDRSA9IE1lZGlhUm91dGVyLlNpbmtBdmFpbGFiaWxpdHkuVU5BVkFJTEFCTEUgKyAxOwogIE1lZGlhUm91dGVyLlNpbmtBdmFpbGFiaWxpdHkuQVZBSUxBQkxFID0gTWVkaWFSb3V0ZXIuU2lua0F2YWlsYWJpbGl0eS5QRVJfU09VUkNFICsgMTsKCiAgTWVkaWFSb3V0ZXIuU2lua0F2YWlsYWJpbGl0eS5pc0tub3duRW51bVZhbHVlID0gZnVuY3Rpb24odmFsdWUpIHsKICAgIHN3aXRjaCAodmFsdWUpIHsKICAgIGNhc2UgMDoKICAgIGNhc2UgMToKICAgIGNhc2UgMjoKICAgICAgcmV0dXJuIHRydWU7CiAgICB9CiAgICByZXR1cm4gZmFsc2U7CiAgfTsKCiAgTWVkaWFSb3V0ZXIuU2lua0F2YWlsYWJpbGl0eS52YWxpZGF0ZSA9IGZ1bmN0aW9uKGVudW1WYWx1ZSkgewogICAgdmFyIGlzRXh0ZW5zaWJsZSA9IGZhbHNlOwogICAgaWYgKGlzRXh0ZW5zaWJsZSB8fCB0aGlzLmlzS25vd25FbnVtVmFsdWUoZW51bVZhbHVlKSkKICAgICAgcmV0dXJuIHZhbGlkYXRvci52YWxpZGF0aW9uRXJyb3IuTk9ORTsKCiAgICByZXR1cm4gdmFsaWRhdG9yLnZhbGlkYXRpb25FcnJvci5VTktOT1dOX0VOVU1fVkFMVUU7CiAgfTsKICBNZWRpYVJvdXRlci5QcmVzZW50YXRpb25Db25uZWN0aW9uU3RhdGUgPSB7fTsKICBNZWRpYVJvdXRlci5QcmVzZW50YXRpb25Db25uZWN0aW9uU3RhdGUuQ09OTkVDVElORyA9IDA7CiAgTWVkaWFSb3V0ZXIuUHJlc2VudGF0aW9uQ29ubmVjdGlvblN0YXRlLkNPTk5FQ1RFRCA9IE1lZGlhUm91dGVyLlByZXNlbnRhdGlvbkNvbm5lY3Rpb25TdGF0ZS5DT05ORUNUSU5HICsgMTsKICBNZWRpYVJvdXRlci5QcmVzZW50YXRpb25Db25uZWN0aW9uU3RhdGUuQ0xPU0VEID0gTWVkaWFSb3V0ZXIuUHJlc2VudGF0aW9uQ29ubmVjdGlvblN0YXRlLkNPTk5FQ1RFRCArIDE7CiAgTWVkaWFSb3V0ZXIuUHJlc2VudGF0aW9uQ29ubmVjdGlvblN0YXRlLlRFUk1JTkFURUQgPSBNZWRpYVJvdXRlci5QcmVzZW50YXRpb25Db25uZWN0aW9uU3RhdGUuQ0xPU0VEICsgMTsKCiAgTWVkaWFSb3V0ZXIuUHJlc2VudGF0aW9uQ29ubmVjdGlvblN0YXRlLmlzS25vd25FbnVtVmFsdWUgPSBmdW5jdGlvbih2YWx1ZSkgewogICAgc3dpdGNoICh2YWx1ZSkgewogICAgY2FzZSAwOgogICAgY2FzZSAxOgogICAgY2FzZSAyOgogICAgY2FzZSAzOgogICAgICByZXR1cm4gdHJ1ZTsKICAgIH0KICAgIHJldHVybiBmYWxzZTsKICB9OwoKICBNZWRpYVJvdXRlci5QcmVzZW50YXRpb25Db25uZWN0aW9uU3RhdGUudmFsaWRhdGUgPSBmdW5jdGlvbihlbnVtVmFsdWUpIHsKICAgIHZhciBpc0V4dGVuc2libGUgPSBmYWxzZTsKICAgIGlmIChpc0V4dGVuc2libGUgfHwgdGhpcy5pc0tub3duRW51bVZhbHVlKGVudW1WYWx1ZSkpCiAgICAgIHJldHVybiB2YWxpZGF0b3IudmFsaWRhdGlvbkVycm9yLk5PTkU7CgogICAgcmV0dXJuIHZhbGlkYXRvci52YWxpZGF0aW9uRXJyb3IuVU5LTk9XTl9FTlVNX1ZBTFVFOwogIH07CiAgTWVkaWFSb3V0ZXIuUHJlc2VudGF0aW9uQ29ubmVjdGlvbkNsb3NlUmVhc29uID0ge307CiAgTWVkaWFSb3V0ZXIuUHJlc2VudGF0aW9uQ29ubmVjdGlvbkNsb3NlUmVhc29uLkNPTk5FQ1RJT05fRVJST1IgPSAwOwogIE1lZGlhUm91dGVyLlByZXNlbnRhdGlvbkNvbm5lY3Rpb25DbG9zZVJlYXNvbi5DTE9TRUQgPSBNZWRpYVJvdXRlci5QcmVzZW50YXRpb25Db25uZWN0aW9uQ2xvc2VSZWFzb24uQ09OTkVDVElPTl9FUlJPUiArIDE7CiAgTWVkaWFSb3V0ZXIuUHJlc2VudGF0aW9uQ29ubmVjdGlvbkNsb3NlUmVhc29uLldFTlRfQVdBWSA9IE1lZGlhUm91dGVyLlByZXNlbnRhdGlvbkNvbm5lY3Rpb25DbG9zZVJlYXNvbi5DTE9TRUQgKyAxOwoKICBNZWRpYVJvdXRlci5QcmVzZW50YXRpb25Db25uZWN0aW9uQ2xvc2VSZWFzb24uaXNLbm93bkVudW1WYWx1ZSA9IGZ1bmN0aW9uKHZhbHVlKSB7CiAgICBzd2l0Y2ggKHZhbHVlKSB7CiAgICBjYXNlIDA6CiAgICBjYXNlIDE6CiAgICBjYXNlIDI6CiAgICAgIHJldHVybiB0cnVlOwogICAgfQogICAgcmV0dXJuIGZhbHNlOwogIH07CgogIE1lZGlhUm91dGVyLlByZXNlbnRhdGlvbkNvbm5lY3Rpb25DbG9zZVJlYXNvbi52YWxpZGF0ZSA9IGZ1bmN0aW9uKGVudW1WYWx1ZSkgewogICAgdmFyIGlzRXh0ZW5zaWJsZSA9IGZhbHNlOwogICAgaWYgKGlzRXh0ZW5zaWJsZSB8fCB0aGlzLmlzS25vd25FbnVtVmFsdWUoZW51bVZhbHVlKSkKICAgICAgcmV0dXJuIHZhbGlkYXRvci52YWxpZGF0aW9uRXJyb3IuTk9ORTsKCiAgICByZXR1cm4gdmFsaWRhdG9yLnZhbGlkYXRpb25FcnJvci5VTktOT1dOX0VOVU1fVkFMVUU7CiAgfTsKICBNZWRpYVJvdXRlclN0dWIucHJvdG90eXBlLnZhbGlkYXRvciA9IHZhbGlkYXRlTWVkaWFSb3V0ZXJSZXF1ZXN0OwogIE1lZGlhUm91dGVyUHJveHkucHJvdG90eXBlLnZhbGlkYXRvciA9IHZhbGlkYXRlTWVkaWFSb3V0ZXJSZXNwb25zZTsKICBleHBvcnRzLlNpbmtJY29uVHlwZSA9IFNpbmtJY29uVHlwZTsKICBleHBvcnRzLlJvdXRlQ29udHJvbGxlclR5cGUgPSBSb3V0ZUNvbnRyb2xsZXJUeXBlOwogIGV4cG9ydHMuUm91dGVSZXF1ZXN0UmVzdWx0Q29kZSA9IFJvdXRlUmVxdWVzdFJlc3VsdENvZGU7CiAgZXhwb3J0cy5NZWRpYVNpbmsgPSBNZWRpYVNpbms7CiAgZXhwb3J0cy5EaWFsTWVkaWFTaW5rID0gRGlhbE1lZGlhU2luazsKICBleHBvcnRzLkNhc3RNZWRpYVNpbmsgPSBDYXN0TWVkaWFTaW5rOwogIGV4cG9ydHMuTWVkaWFSb3V0ZSA9IE1lZGlhUm91dGU7CiAgZXhwb3J0cy5Jc3N1ZSA9IElzc3VlOwogIGV4cG9ydHMuUm91dGVNZXNzYWdlID0gUm91dGVNZXNzYWdlOwogIGV4cG9ydHMuU2lua1NlYXJjaENyaXRlcmlhID0gU2lua1NlYXJjaENyaXRlcmlhOwogIGV4cG9ydHMuTWVkaWFSb3V0ZVByb3ZpZGVyQ29uZmlnID0gTWVkaWFSb3V0ZVByb3ZpZGVyQ29uZmlnOwogIGV4cG9ydHMuTWVkaWFTaW5rRXh0cmFEYXRhID0gTWVkaWFTaW5rRXh0cmFEYXRhOwogIGV4cG9ydHMuTWVkaWFSb3V0ZVByb3ZpZGVyID0gTWVkaWFSb3V0ZVByb3ZpZGVyOwogIGV4cG9ydHMuTWVkaWFSb3V0ZVByb3ZpZGVyUHRyID0gTWVkaWFSb3V0ZVByb3ZpZGVyUHRyOwogIGV4cG9ydHMuTWVkaWFSb3V0ZVByb3ZpZGVyQXNzb2NpYXRlZFB0ciA9IE1lZGlhUm91dGVQcm92aWRlckFzc29jaWF0ZWRQdHI7CiAgZXhwb3J0cy5NZWRpYVJvdXRlciA9IE1lZGlhUm91dGVyOwogIGV4cG9ydHMuTWVkaWFSb3V0ZXJQdHIgPSBNZWRpYVJvdXRlclB0cjsKICBleHBvcnRzLk1lZGlhUm91dGVyQXNzb2NpYXRlZFB0ciA9IE1lZGlhUm91dGVyQXNzb2NpYXRlZFB0cjsKfSkoKTsvLyBDb3B5cmlnaHQgMjAxNSBUaGUgQ2hyb21pdW0gQXV0aG9ycy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KLy8gVXNlIG9mIHRoaXMgc291cmNlIGNvZGUgaXMgZ292ZXJuZWQgYnkgYSBCU0Qtc3R5bGUgbGljZW5zZSB0aGF0IGNhbiBiZQovLyBmb3VuZCBpbiB0aGUgTElDRU5TRSBmaWxlLgoKJ3VzZSBzdHJpY3QnOwoKaWYgKCh0eXBlb2YgbW9qbyA9PT0gJ3VuZGVmaW5lZCcpIHx8ICFtb2pvLmJpbmRpbmdzTGlicmFyeUluaXRpYWxpemVkKSB7CiAgbG9hZFNjcmlwdCgnbW9qb19iaW5kaW5ncycpOwp9Cm1vam8uY29uZmlnLmF1dG9Mb2FkTW9qb21EZXBzID0gZmFsc2U7Cgpsb2FkU2NyaXB0KCdjaHJvbWUvY29tbW9uL21lZGlhX3JvdXRlci9tb2pvL21lZGlhX2NvbnRyb2xsZXIubW9qb20nKTsKbG9hZFNjcmlwdCgnY2hyb21lL2NvbW1vbi9tZWRpYV9yb3V0ZXIvbW9qby9tZWRpYV9yb3V0ZXIubW9qb20nKTsKbG9hZFNjcmlwdCgnY2hyb21lL2NvbW1vbi9tZWRpYV9yb3V0ZXIvbW9qby9tZWRpYV9zdGF0dXMubW9qb20nKTsKbG9hZFNjcmlwdCgnZXh0ZW5zaW9ucy9jb21tb24vbW9qby9rZWVwX2FsaXZlLm1vam9tJyk7CmxvYWRTY3JpcHQoJ21lZGlhL21vam8vaW50ZXJmYWNlcy9taXJyb3Jfc2VydmljZV9yZW1vdGluZy5tb2pvbScpOwpsb2FkU2NyaXB0KCdtZWRpYS9tb2pvL2ludGVyZmFjZXMvcmVtb3RpbmdfY29tbW9uLm1vam9tJyk7CmxvYWRTY3JpcHQoJ21vam8vY29tbW9uL3RpbWUubW9qb20nKTsKbG9hZFNjcmlwdCgnbmV0L2ludGVyZmFjZXMvaXBfYWRkcmVzcy5tb2pvbScpOwpsb2FkU2NyaXB0KCduZXQvaW50ZXJmYWNlcy9pcF9lbmRwb2ludC5tb2pvbScpOwpsb2FkU2NyaXB0KCd1cmwvbW9qby9vcmlnaW4ubW9qb20nKTsKbG9hZFNjcmlwdCgndXJsL21vam8vdXJsLm1vam9tJyk7CgovLyBUaGUgZm9sbG93aW5nIGFkYXB0ZXIgY2xhc3NlcyBwcmVzZXJ2ZSBiYWNrd2FyZCBjb21wYXRpYmlsaXR5IGZvciB0aGUgbWVkaWEKLy8gcm91dGVyIGNvbXBvbmVudCBleHRlbnNpb24uCi8vIFRPRE8oY3JidWcuY29tLzc4NzEyOCk6IFJlbW92ZSB0aGVzZSBhZGFwdGVycy4KCmZ1bmN0aW9uIGFzc2lnbkZpZWxkcyhvYmplY3QsIGZpZWxkcykgewogIGZvcih2YXIgZmllbGQgaW4gZmllbGRzKSB7CiAgICBpZiAob2JqZWN0Lmhhc093blByb3BlcnR5KGZpZWxkKSkKICAgICAgb2JqZWN0W2ZpZWxkXSA9IGZpZWxkc1tmaWVsZF07CiAgfQp9CgovKioKICogQWRhcHRlciBmb3IgbWVkaWFSb3V0ZXIubW9qb20uRGlhbE1lZGlhU2luay4KICogQGNvbnN0cnVjdG9yCiAqLwpmdW5jdGlvbiBEaWFsTWVkaWFTaW5rQWRhcHRlcihmaWVsZHMpIHsKICB0aGlzLmlwX2FkZHJlc3MgPSBudWxsOwogIHRoaXMubW9kZWxfbmFtZSA9IG51bGw7CiAgdGhpcy5hcHBfdXJsID0gbnVsbDsKCiAgYXNzaWduRmllbGRzKHRoaXMsIGZpZWxkcyk7Cn0KCkRpYWxNZWRpYVNpbmtBZGFwdGVyLmZyb21OZXdWZXJzaW9uID0gZnVuY3Rpb24ob3RoZXIpIHsKICByZXR1cm4gbmV3IERpYWxNZWRpYVNpbmtBZGFwdGVyKHsKICAgICdpcF9hZGRyZXNzJzogSVBBZGRyZXNzQWRhcHRlci5mcm9tTmV3VmVyc2lvbihvdGhlci5pcEFkZHJlc3MpLAogICAgJ21vZGVsX25hbWUnOiBvdGhlci5tb2RlbE5hbWUsCiAgICAnYXBwX3VybCc6IG90aGVyLmFwcFVybCwKICB9KTsKfTsKCkRpYWxNZWRpYVNpbmtBZGFwdGVyLnByb3RvdHlwZS50b05ld1ZlcnNpb24gPSBmdW5jdGlvbigpIHsKICByZXR1cm4gbmV3IG1lZGlhUm91dGVyLm1vam9tLkRpYWxNZWRpYVNpbmsoewogICAgJ2lwQWRkcmVzcycgOiB0aGlzLmlwX2FkZHJlc3MudG9OZXdWZXJzaW9uKCksCiAgICAnbW9kZWxOYW1lJyA6IHRoaXMubW9kZWxfbmFtZSwKICAgICdhcHBVcmwnIDogdGhpcy5hcHBfdXJsLAogIH0pOwp9OwoKLyoqCiAqIEFkYXB0ZXIgZm9yIG1lZGlhUm91dGVyLm1vam9tLkNhc3RNZWRpYVNpbmsuCiAqIEBjb25zdHJ1Y3RvcgogKi8KZnVuY3Rpb24gQ2FzdE1lZGlhU2lua0FkYXB0ZXIoZmllbGRzKSB7CiAgdGhpcy5pcF9lbmRwb2ludCA9IG51bGw7CiAgdGhpcy5tb2RlbF9uYW1lID0gbnVsbDsKICB0aGlzLmNhcGFiaWxpdGllcyA9IDA7CiAgdGhpcy5jYXN0X2NoYW5uZWxfaWQgPSAwOwoKICBhc3NpZ25GaWVsZHModGhpcywgZmllbGRzKTsKfQoKQ2FzdE1lZGlhU2lua0FkYXB0ZXIuZnJvbU5ld1ZlcnNpb24gPSBmdW5jdGlvbihvdGhlcikgewogIHJldHVybiBuZXcgQ2FzdE1lZGlhU2lua0FkYXB0ZXIoewogICAgJ2lwX2VuZHBvaW50JzogSVBFbmRwb2ludEFkYXB0ZXIuZnJvbU5ld1ZlcnNpb24ob3RoZXIuaXBFbmRwb2ludCksCiAgICAnbW9kZWxfbmFtZSc6IG90aGVyLm1vZGVsTmFtZSwKICAgICdjYXBhYmlsaXRpZXMnOiBvdGhlci5jYXBhYmlsaXRpZXMsCiAgICAnY2FzdF9jaGFubmVsX2lkJzogb3RoZXIuY2FzdENoYW5uZWxJZCwKICB9KTsKfTsKCkNhc3RNZWRpYVNpbmtBZGFwdGVyLnByb3RvdHlwZS50b05ld1ZlcnNpb24gPSBmdW5jdGlvbigpIHsKICByZXR1cm4gbmV3IG1lZGlhUm91dGVyLm1vam9tLkNhc3RNZWRpYVNpbmsoewogICAgJ2lwRW5kcG9pbnQnOiB0aGlzLmlwX2VuZHBvaW50LnRvTmV3VmVyc2lvbigpLAogICAgJ21vZGVsTmFtZSc6IHRoaXMubW9kZWxfbmFtZSwKICAgICdjYXBhYmlsaXRpZXMnOiB0aGlzLmNhcGFiaWxpdGllcywKICAgICdjYXN0Q2hhbm5lbElkJzogdGhpcy5jYXN0X2NoYW5uZWxfaWQsCiAgfSk7Cn07CgovKioKICogQWRhcHRlciBmb3IgbWVkaWFSb3V0ZXIubW9qb20uSGFuZ291dHNNZWRpYVN0YXR1c0V4dHJhRGF0YS4KICogQGNvbnN0cnVjdG9yCiAqLwpmdW5jdGlvbiBIYW5nb3V0c01lZGlhU3RhdHVzRXh0cmFEYXRhQWRhcHRlcihmaWVsZHMpIHsKICB0aGlzLmxvY2FsX3ByZXNlbnQgPSBmYWxzZTsKCiAgYXNzaWduRmllbGRzKHRoaXMsIGZpZWxkcyk7Cn0KCkhhbmdvdXRzTWVkaWFTdGF0dXNFeHRyYURhdGFBZGFwdGVyLnByb3RvdHlwZS50b05ld1ZlcnNpb24gPSBmdW5jdGlvbigpIHsKICByZXR1cm4gbmV3IG1lZGlhUm91dGVyLm1vam9tLkhhbmdvdXRzTWVkaWFTdGF0dXNFeHRyYURhdGEoewogICAgJ2xvY2FsUHJlc2VudCc6IHRoaXMubG9jYWxfcHJlc2VudCwKICB9KTsKfTsKCi8qKgogKiBBZGFwdGVyIGZvciBuZXQuaW50ZXJmYWNlcy5JUEFkZHJlc3MuCiAqIEBjb25zdHJ1Y3RvcgogKi8KZnVuY3Rpb24gSVBBZGRyZXNzQWRhcHRlcihmaWVsZHMpIHsKICB0aGlzLmFkZHJlc3NfYnl0ZXMgPSBudWxsOwoKICBhc3NpZ25GaWVsZHModGhpcywgZmllbGRzKTsKfQoKSVBBZGRyZXNzQWRhcHRlci5mcm9tTmV3VmVyc2lvbiA9IGZ1bmN0aW9uKG90aGVyKSB7CiAgcmV0dXJuIG5ldyBJUEFkZHJlc3NBZGFwdGVyKHsKICAgICdhZGRyZXNzX2J5dGVzJzogb3RoZXIuYWRkcmVzc0J5dGVzLAogIH0pOwp9OwoKSVBBZGRyZXNzQWRhcHRlci5wcm90b3R5cGUudG9OZXdWZXJzaW9uID0gZnVuY3Rpb24oKSB7CiAgcmV0dXJuIG5ldyBuZXQuaW50ZXJmYWNlcy5JUEFkZHJlc3MoewogICAgJ2FkZHJlc3NCeXRlcyc6IHRoaXMuYWRkcmVzc19ieXRlcywKICB9KTsKfTsKCi8qKgogKiBBZGFwdGVyIGZvciBuZXQuaW50ZXJmYWNlcy5JUEVuZHBvaW50LgogKiBAY29uc3RydWN0b3IKICovCmZ1bmN0aW9uIElQRW5kcG9pbnRBZGFwdGVyKGZpZWxkcykgewogIHRoaXMuYWRkcmVzcyA9IG51bGw7CiAgdGhpcy5wb3J0ID0gMDsKCiAgYXNzaWduRmllbGRzKHRoaXMsIGZpZWxkcyk7Cn0KCklQRW5kcG9pbnRBZGFwdGVyLmZyb21OZXdWZXJzaW9uID0gZnVuY3Rpb24ob3RoZXIpIHsKICByZXR1cm4gbmV3IElQRW5kcG9pbnRBZGFwdGVyKHsKICAgICdhZGRyZXNzJzogSVBBZGRyZXNzQWRhcHRlci5mcm9tTmV3VmVyc2lvbihvdGhlci5hZGRyZXNzKSwKICAgICdwb3J0Jzogb3RoZXIucG9ydCwKICB9KTsKfTsKCklQRW5kcG9pbnRBZGFwdGVyLnByb3RvdHlwZS50b05ld1ZlcnNpb24gPSBmdW5jdGlvbigpIHsKICByZXR1cm4gbmV3IG5ldC5pbnRlcmZhY2VzLklQRW5kcG9pbnQoewogICAgJ2FkZHJlc3MnOiB0aGlzLmFkZHJlc3MudG9OZXdWZXJzaW9uKCksCiAgICAncG9ydCc6IHRoaXMucG9ydCwKICB9KTsKfTsKCi8qKgogKiBBZGFwdGVyIGZvciBtZWRpYVJvdXRlci5tb2pvbS5NZWRpYVN0YXR1cy4KICogQGNvbnN0cnVjdG9yCiAqLwpmdW5jdGlvbiBNZWRpYVN0YXR1c0FkYXB0ZXIoZmllbGRzKSB7CiAgdGhpcy50aXRsZSA9IG51bGw7CiAgdGhpcy5kZXNjcmlwdGlvbiA9IG51bGw7CiAgdGhpcy5jYW5fcGxheV9wYXVzZSA9IGZhbHNlOwogIHRoaXMuY2FuX211dGUgPSBmYWxzZTsKICB0aGlzLmNhbl9zZXRfdm9sdW1lID0gZmFsc2U7CiAgdGhpcy5jYW5fc2VlayA9IGZhbHNlOwogIHRoaXMuaXNfbXV0ZWQgPSBmYWxzZTsKICB0aGlzLnBsYXlfc3RhdGUgPSAwOwogIHRoaXMudm9sdW1lID0gMDsKICB0aGlzLmR1cmF0aW9uID0gbnVsbDsKICB0aGlzLmN1cnJlbnRfdGltZSA9IG51bGw7CiAgdGhpcy5oYW5nb3V0c19leHRyYV9kYXRhID0gbnVsbDsKCiAgYXNzaWduRmllbGRzKHRoaXMsIGZpZWxkcyk7Cn0KCk1lZGlhU3RhdHVzQWRhcHRlci5QbGF5U3RhdGUgPSBtZWRpYVJvdXRlci5tb2pvbS5NZWRpYVN0YXR1cy5QbGF5U3RhdGU7CgpNZWRpYVN0YXR1c0FkYXB0ZXIucHJvdG90eXBlLnRvTmV3VmVyc2lvbiA9IGZ1bmN0aW9uKCkgewogIHJldHVybiBuZXcgbWVkaWFSb3V0ZXIubW9qb20uTWVkaWFTdGF0dXMoewogICAgJ3RpdGxlJzogdGhpcy50aXRsZSwKICAgICdkZXNjcmlwdGlvbic6IHRoaXMuZGVzY3JpcHRpb24sCiAgICAnY2FuUGxheVBhdXNlJzogdGhpcy5jYW5fcGxheV9wYXVzZSwKICAgICdjYW5NdXRlJzogdGhpcy5jYW5fbXV0ZSwKICAgICdjYW5TZXRWb2x1bWUnOiB0aGlzLmNhbl9zZXRfdm9sdW1lLAogICAgJ2NhblNlZWsnOiB0aGlzLmNhbl9zZWVrLAogICAgJ2lzTXV0ZWQnOiB0aGlzLmlzX211dGVkLAogICAgJ3BsYXlTdGF0ZSc6IHRoaXMucGxheV9zdGF0ZSwKICAgICd2b2x1bWUnOiB0aGlzLnZvbHVtZSwKICAgICdkdXJhdGlvbic6IHRoaXMuZHVyYXRpb24sCiAgICAnY3VycmVudFRpbWUnOiB0aGlzLmN1cnJlbnRfdGltZSwKICAgICdoYW5nb3V0c0V4dHJhRGF0YSc6CiAgICAgICAgdGhpcy5oYW5nb3V0c19leHRyYV9kYXRhICYmIHRoaXMuaGFuZ291dHNfZXh0cmFfZGF0YS50b05ld1ZlcnNpb24oKSwKICB9KTsKfTsKCi8qKgogKiBBZGFwdGVyIGZvciBtZWRpYS5tb2pvbS5SZW1vdGluZ1NpbmtNZXRhZGF0YS4KICogQGNvbnN0cnVjdG9yCiAqLwpmdW5jdGlvbiBSZW1vdGluZ1NpbmtNZXRhZGF0YUFkYXB0ZXIoZmllbGRzKSB7CiAgdGhpcy5mZWF0dXJlcyA9IG51bGw7CiAgdGhpcy5hdWRpb19jYXBhYmlsaXRpZXMgPSBudWxsOwogIHRoaXMudmlkZW9fY2FwYWJpbGl0aWVzID0gbnVsbDsKICB0aGlzLmZyaWVuZGx5X25hbWUgPSBudWxsOwoKICBhc3NpZ25GaWVsZHModGhpcywgZmllbGRzKTsKfQoKUmVtb3RpbmdTaW5rTWV0YWRhdGFBZGFwdGVyLmZyb21OZXdWZXJzaW9uID0gZnVuY3Rpb24ob3RoZXIpIHsKICByZXR1cm4gbmV3IFJlbW90aW5nU2lua01ldGFkYXRhQWRhcHRlcih7CiAgICAnZmVhdHVyZXMnOiBvdGhlci5mZWF0dXJlcywKICAgICdhdWRpb19jYXBhYmlsaXRpZXMnOiBvdGhlci5hdWRpb0NhcGFiaWxpdGllcywKICAgICd2aWRlb19jYXBhYmlsaXRpZXMnOiBvdGhlci52aWRlb0NhcGFiaWxpdGllcywKICAgICdmcmllbmRseV9uYW1lJzogb3RoZXIuZnJpZW5kbHlOYW1lLAogIH0pOwp9OwoKUmVtb3RpbmdTaW5rTWV0YWRhdGFBZGFwdGVyLnByb3RvdHlwZS50b05ld1ZlcnNpb24gPSBmdW5jdGlvbigpIHsKICByZXR1cm4gbmV3IG1lZGlhLm1vam9tLlJlbW90aW5nU2lua01ldGFkYXRhKHsKICAgICdmZWF0dXJlcyc6IHRoaXMuZmVhdHVyZXMsCiAgICAnYXVkaW9DYXBhYmlsaXRpZXMnOiB0aGlzLmF1ZGlvX2NhcGFiaWxpdGllcywKICAgICd2aWRlb0NhcGFiaWxpdGllcyc6IHRoaXMudmlkZW9fY2FwYWJpbGl0aWVzLAogICAgJ2ZyaWVuZGx5TmFtZSc6IHRoaXMuZnJpZW5kbHlfbmFtZSwKICB9KTsKfTsKCi8qKgogKiBBZGFwdGVyIGZvciBtZWRpYVJvdXRlci5tb2pvbS5NZWRpYVNpbmsuCiAqIEBjb25zdHJ1Y3RvcgogKi8KZnVuY3Rpb24gTWVkaWFTaW5rQWRhcHRlcihmaWVsZHMpIHsKICB0aGlzLnNpbmtfaWQgPSBudWxsOwogIHRoaXMubmFtZSA9IG51bGw7CiAgdGhpcy5kZXNjcmlwdGlvbiA9IG51bGw7CiAgdGhpcy5kb21haW4gPSBudWxsOwogIHRoaXMuaWNvbl90eXBlID0gMDsKICB0aGlzLmV4dHJhX2RhdGEgPSBudWxsOwoKICBhc3NpZ25GaWVsZHModGhpcywgZmllbGRzKTsKfQoKTWVkaWFTaW5rQWRhcHRlci5mcm9tTmV3VmVyc2lvbiA9IGZ1bmN0aW9uKG90aGVyKSB7CiAgcmV0dXJuIG5ldyBNZWRpYVNpbmtBZGFwdGVyKHsKICAgICdzaW5rX2lkJzogb3RoZXIuc2lua0lkLAogICAgJ25hbWUnOiBvdGhlci5uYW1lLAogICAgJ2Rlc2NyaXB0aW9uJzogb3RoZXIuZGVzY3JpcHRpb24sCiAgICAnZG9tYWluJzogb3RoZXIuZG9tYWluLAogICAgJ2ljb25fdHlwZSc6IG90aGVyLmljb25UeXBlLAogICAgJ2V4dHJhX2RhdGEnOiBvdGhlci5leHRyYURhdGEgJiYKICAgICAgICBNZWRpYVNpbmtFeHRyYURhdGFBZGFwdGVyLmZyb21OZXdWZXJzaW9uKG90aGVyLmV4dHJhRGF0YSksCiAgfSk7Cn07CgpNZWRpYVNpbmtBZGFwdGVyLnByb3RvdHlwZS50b05ld1ZlcnNpb24gPSBmdW5jdGlvbigpIHsKICByZXR1cm4gbmV3IG1lZGlhUm91dGVyLm1vam9tLk1lZGlhU2luayh7CiAgICAnc2lua0lkJzogdGhpcy5zaW5rX2lkLAogICAgJ25hbWUnOiB0aGlzLm5hbWUsCiAgICAnZGVzY3JpcHRpb24nOiB0aGlzLmRlc2NyaXB0aW9uLAogICAgJ2RvbWFpbic6IHRoaXMuZG9tYWluLAogICAgJ2ljb25UeXBlJzogdGhpcy5pY29uX3R5cGUsCiAgICAnZXh0cmFEYXRhJzogdGhpcy5leHRyYV9kYXRhICYmIHRoaXMuZXh0cmFfZGF0YS50b05ld1ZlcnNpb24oKSwKICB9KTsKfTsKCi8qKgogKiBBZGFwdGVyIGZvciBtZWRpYVJvdXRlci5tb2pvbS5NZWRpYVNpbmtFeHRyYURhdGEuCiAqIEBjb25zdHJ1Y3RvcgogKi8KZnVuY3Rpb24gTWVkaWFTaW5rRXh0cmFEYXRhQWRhcHRlcih2YWx1ZSkgewogIHRoaXMuJGRhdGEgPSBudWxsOwogIHRoaXMuJHRhZyA9IHVuZGVmaW5lZDsKCiAgaWYgKHZhbHVlID09IHVuZGVmaW5lZCkgewogICAgcmV0dXJuOwogIH0KCiAgdmFyIGtleXMgPSBPYmplY3Qua2V5cyh2YWx1ZSk7CiAgaWYgKGtleXMubGVuZ3RoID09IDApIHsKICAgIHJldHVybjsKICB9CgogIGlmIChrZXlzLmxlbmd0aCA+IDEpIHsKICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ1lvdSBtYXkgc2V0IG9ubHkgb25lIG1lbWJlciBvbiBhIHVuaW9uLicpOwogIH0KCiAgdmFyIGZpZWxkcyA9IFsKICAgICdkaWFsX21lZGlhX3NpbmsnLAogICAgJ2Nhc3RfbWVkaWFfc2luaycsCiAgXTsKCiAgaWYgKGZpZWxkcy5pbmRleE9mKGtleXNbMF0pIDwgMCkgewogICAgdGhyb3cgbmV3IFJlZmVyZW5jZUVycm9yKGtleXNbMF0gKwogICAgICAgICcgaXMgbm90IGEgTWVkaWFTaW5rRXh0cmFEYXRhQWRhcHRlciBtZW1iZXIuJyk7CiAgfQoKICB0aGlzW2tleXNbMF1dID0gdmFsdWVba2V5c1swXV07Cn0KCk1lZGlhU2lua0V4dHJhRGF0YUFkYXB0ZXIuVGFncyA9IHsKICBkaWFsX21lZGlhX3Npbms6IDAsCiAgY2FzdF9tZWRpYV9zaW5rOiAxLAp9OwoKT2JqZWN0LmRlZmluZVByb3BlcnR5KE1lZGlhU2lua0V4dHJhRGF0YUFkYXB0ZXIucHJvdG90eXBlLCAnZGlhbF9tZWRpYV9zaW5rJywgewogIGdldDogZnVuY3Rpb24oKSB7CiAgICBpZiAodGhpcy4kdGFnICE9IE1lZGlhU2lua0V4dHJhRGF0YUFkYXB0ZXIuVGFncy5kaWFsX21lZGlhX3NpbmspIHsKICAgICAgdGhyb3cgbmV3IFJlZmVyZW5jZUVycm9yKAogICAgICAgICAgJ01lZGlhU2lua0V4dHJhRGF0YUFkYXB0ZXIuZGlhbF9tZWRpYV9zaW5rIGlzIG5vdCBjdXJyZW50bHkgc2V0LicpOwogICAgfQogICAgcmV0dXJuIHRoaXMuJGRhdGE7CiAgfSwKCiAgc2V0OiBmdW5jdGlvbih2YWx1ZSkgewogICAgdGhpcy4kdGFnID0gTWVkaWFTaW5rRXh0cmFEYXRhQWRhcHRlci5UYWdzLmRpYWxfbWVkaWFfc2luazsKICAgIHRoaXMuJGRhdGEgPSB2YWx1ZTsKICB9Cn0pOwoKT2JqZWN0LmRlZmluZVByb3BlcnR5KE1lZGlhU2lua0V4dHJhRGF0YUFkYXB0ZXIucHJvdG90eXBlLCAnY2FzdF9tZWRpYV9zaW5rJywgewogIGdldDogZnVuY3Rpb24oKSB7CiAgICBpZiAodGhpcy4kdGFnICE9IE1lZGlhU2lua0V4dHJhRGF0YUFkYXB0ZXIuVGFncy5jYXN0X21lZGlhX3NpbmspIHsKICAgICAgdGhyb3cgbmV3IFJlZmVyZW5jZUVycm9yKAogICAgICAgICAgJ01lZGlhU2lua0V4dHJhRGF0YUFkYXB0ZXIuY2FzdF9tZWRpYV9zaW5rIGlzIG5vdCBjdXJyZW50bHkgc2V0LicpOwogICAgfQogICAgcmV0dXJuIHRoaXMuJGRhdGE7CiAgfSwKCiAgc2V0OiBmdW5jdGlvbih2YWx1ZSkgewogICAgdGhpcy4kdGFnID0gTWVkaWFTaW5rRXh0cmFEYXRhQWRhcHRlci5UYWdzLmNhc3RfbWVkaWFfc2luazsKICAgIHRoaXMuJGRhdGEgPSB2YWx1ZTsKICB9Cn0pOwoKTWVkaWFTaW5rRXh0cmFEYXRhQWRhcHRlci5mcm9tTmV3VmVyc2lvbiA9IGZ1bmN0aW9uKG90aGVyKSB7CiAgaWYgKG90aGVyLiR0YWcgPT0gbWVkaWFSb3V0ZXIubW9qb20uTWVkaWFTaW5rRXh0cmFEYXRhLlRhZ3MuZGlhbE1lZGlhU2luaykgewogICAgcmV0dXJuIG5ldyBNZWRpYVNpbmtFeHRyYURhdGFBZGFwdGVyKHsKICAgICAgJ2RpYWxfbWVkaWFfc2luayc6CiAgICAgICAgICBEaWFsTWVkaWFTaW5rQWRhcHRlci5mcm9tTmV3VmVyc2lvbihvdGhlci5kaWFsTWVkaWFTaW5rKSwKICAgIH0pOwogIH0gZWxzZSB7CiAgICByZXR1cm4gbmV3IE1lZGlhU2lua0V4dHJhRGF0YUFkYXB0ZXIoewogICAgICAnY2FzdF9tZWRpYV9zaW5rJzoKICAgICAgICAgIENhc3RNZWRpYVNpbmtBZGFwdGVyLmZyb21OZXdWZXJzaW9uKG90aGVyLmNhc3RNZWRpYVNpbmspLAogICAgfSk7CiAgfQp9OwoKTWVkaWFTaW5rRXh0cmFEYXRhQWRhcHRlci5wcm90b3R5cGUudG9OZXdWZXJzaW9uID0gZnVuY3Rpb24oKSB7CiAgaWYgKHRoaXMuJHRhZyA9PSBNZWRpYVNpbmtFeHRyYURhdGFBZGFwdGVyLlRhZ3MuZGlhbF9tZWRpYV9zaW5rKSB7CiAgICByZXR1cm4gbmV3IG1lZGlhUm91dGVyLm1vam9tLk1lZGlhU2lua0V4dHJhRGF0YSh7CiAgICAgICdkaWFsTWVkaWFTaW5rJzogdGhpcy5kaWFsX21lZGlhX3NpbmsudG9OZXdWZXJzaW9uKCksCiAgICB9KTsKICB9IGVsc2UgewogICAgcmV0dXJuIG5ldyBtZWRpYVJvdXRlci5tb2pvbS5NZWRpYVNpbmtFeHRyYURhdGEoewogICAgICAnY2FzdE1lZGlhU2luayc6IHRoaXMuY2FzdF9tZWRpYV9zaW5rLnRvTmV3VmVyc2lvbigpLAogICAgfSk7CiAgfQp9OwoKLyoqCiAqIEFkYXB0ZXIgZm9yIG1lZGlhLm1vam9tLk1pcnJvclNlcnZpY2VSZW1vdGVyUHRyLgogKiBAY29uc3RydWN0b3IKICovCmZ1bmN0aW9uIE1pcnJvclNlcnZpY2VSZW1vdGVyUHRyQWRhcHRlcihoYW5kbGVPclB0ckluZm8pIHsKICB0aGlzLnB0ciA9IG5ldyBtb2pvLkludGVyZmFjZVB0ckNvbnRyb2xsZXIoTWlycm9yU2VydmljZVJlbW90ZXJBZGFwdGVyLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBoYW5kbGVPclB0ckluZm8pOwp9CgpNaXJyb3JTZXJ2aWNlUmVtb3RlclB0ckFkYXB0ZXIucHJvdG90eXBlID0KICAgIE9iamVjdC5jcmVhdGUobWVkaWEubW9qb20uTWlycm9yU2VydmljZVJlbW90ZXJQdHIucHJvdG90eXBlKTsKTWlycm9yU2VydmljZVJlbW90ZXJQdHJBZGFwdGVyLnByb3RvdHlwZS5jb25zdHJ1Y3RvciA9CiAgICBNaXJyb3JTZXJ2aWNlUmVtb3RlclB0ckFkYXB0ZXI7CgpNaXJyb3JTZXJ2aWNlUmVtb3RlclB0ckFkYXB0ZXIucHJvdG90eXBlLnN0YXJ0RGF0YVN0cmVhbXMgPSBmdW5jdGlvbigpIHsKICByZXR1cm4gTWlycm9yU2VydmljZVJlbW90ZXJQcm94eS5wcm90b3R5cGUuc3RhcnREYXRhU3RyZWFtcwogICAgICAuYXBwbHkodGhpcy5wdHIuZ2V0UHJveHkoKSwgYXJndW1lbnRzKS50aGVuKGZ1bmN0aW9uKHJlc3BvbnNlKSB7CiAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKHsKICAgICAgJ2F1ZGlvX3N0cmVhbV9pZCc6IHJlc3BvbnNlLmF1ZGlvU3RyZWFtSWQsCiAgICAgICd2aWRlb19zdHJlYW1faWQnOiByZXNwb25zZS52aWRlb1N0cmVhbUlkLAogICAgfSk7CiAgfSk7Cn07CgovKioKICogQWRhcHRlciBmb3IgbWVkaWEubW9qb20uTWlycm9yU2VydmljZVJlbW90ZXIuc3R1YmNsYXNzLgogKiBAY29uc3RydWN0b3IKICovCmZ1bmN0aW9uIE1pcnJvclNlcnZpY2VSZW1vdGVyU3R1YkFkYXB0ZXIoZGVsZWdhdGUpIHsKICB0aGlzLmRlbGVnYXRlXyA9IGRlbGVnYXRlOwp9CgpNaXJyb3JTZXJ2aWNlUmVtb3RlclN0dWJBZGFwdGVyLnByb3RvdHlwZSA9IE9iamVjdC5jcmVhdGUoCiAgICBtZWRpYS5tb2pvbS5NaXJyb3JTZXJ2aWNlUmVtb3Rlci5zdHViQ2xhc3MucHJvdG90eXBlKTsKTWlycm9yU2VydmljZVJlbW90ZXJTdHViQWRhcHRlci5wcm90b3R5cGUuY29uc3RydWN0b3IgPQogICAgTWlycm9yU2VydmljZVJlbW90ZXJTdHViQWRhcHRlcjsKCk1pcnJvclNlcnZpY2VSZW1vdGVyU3R1YkFkYXB0ZXIucHJvdG90eXBlLnN0YXJ0RGF0YVN0cmVhbXMgPQogICAgZnVuY3Rpb24oaGFzQXVkaW8sIGhhc1ZpZGVvKSB7CiAgcmV0dXJuIHRoaXMuZGVsZWdhdGVfICYmIHRoaXMuZGVsZWdhdGVfLnN0YXJ0RGF0YVN0cmVhbXMgJiYKICAgICAgdGhpcy5kZWxlZ2F0ZV8uc3RhcnREYXRhU3RyZWFtcyhoYXNBdWRpbywgaGFzVmlkZW8pLnRoZW4oCiAgICAgICAgICBmdW5jdGlvbihyZXNwb25zZSkgewogICAgICAgICAgICByZXR1cm4gewogICAgICAgICAgICAgICdhdWRpb1N0cmVhbUlkJzogcmVzcG9uc2UuYXVkaW9fc3RyZWFtX2lkLAogICAgICAgICAgICAgICd2aWRlb1N0cmVhbUlkJzogcmVzcG9uc2UudmlkZW9fc3RyZWFtX2lkLAogICAgICAgICAgICB9OwogICAgICAgICAgfSk7Cn07CgovKioKICogQWRhcHRlciBmb3IgbWVkaWEubW9qb20uTWlycm9yU2VydmljZVJlbW90ZXIuCiAqLwp2YXIgTWlycm9yU2VydmljZVJlbW90ZXJBZGFwdGVyID0gewogICAgbmFtZTogJ21lZGlhOjptb2pvbTo6TWlycm9yU2VydmljZVJlbW90ZXInLAogICAga1ZlcnNpb246IDAsCiAgICBwdHJDbGFzczogTWlycm9yU2VydmljZVJlbW90ZXJQdHJBZGFwdGVyLAogICAgcHJveHlDbGFzczogbWVkaWEubW9qb20uTWlycm9yU2VydmljZVJlbW90ZXIucHJveHlDbGFzcywKICAgIHN0dWJDbGFzczogTWlycm9yU2VydmljZVJlbW90ZXJTdHViQWRhcHRlciwKICAgIHZhbGlkYXRlUmVxdWVzdDogbWVkaWEubW9qb20uTWlycm9yU2VydmljZVJlbW90ZXIudmFsaWRhdGVSZXF1ZXN0LAogICAgdmFsaWRhdGVSZXNwb25zZTogbWVkaWEubW9qb20uTWlycm9yU2VydmljZVJlbW90ZXIudmFsaWRhdGVSZXNwb25zZSwKfTsKCi8qKgogKiBBZGFwdGVyIGZvciBtZWRpYS5tb2pvbS5NaXJyb3JTZXJ2aWNlUmVtb3RpbmdTb3VyY2VQdHIuCiAqIEBjb25zdHJ1Y3RvcgogKi8KZnVuY3Rpb24gTWlycm9yU2VydmljZVJlbW90aW5nU291cmNlUHRyQWRhcHRlcihoYW5kbGVPclB0ckluZm8pIHsKICB0aGlzLnB0ciA9IG5ldyBtb2pvLkludGVyZmFjZVB0ckNvbnRyb2xsZXIoTWlycm9yU2VydmljZVJlbW90aW5nU291cmNlQWRhcHRlciwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaGFuZGxlT3JQdHJJbmZvKTsKfQoKTWlycm9yU2VydmljZVJlbW90aW5nU291cmNlUHRyQWRhcHRlci5wcm90b3R5cGUgPQogICAgT2JqZWN0LmNyZWF0ZShtZWRpYS5tb2pvbS5NaXJyb3JTZXJ2aWNlUmVtb3RpbmdTb3VyY2VQdHIucHJvdG90eXBlKTsKTWlycm9yU2VydmljZVJlbW90aW5nU291cmNlUHRyQWRhcHRlci5wcm90b3R5cGUuY29uc3RydWN0b3IgPQogICAgTWlycm9yU2VydmljZVJlbW90aW5nU291cmNlUHRyQWRhcHRlcjsKCk1pcnJvclNlcnZpY2VSZW1vdGluZ1NvdXJjZVB0ckFkYXB0ZXIucHJvdG90eXBlLm9uU2lua0F2YWlsYWJsZSA9CiAgICBmdW5jdGlvbihtZXRhZGF0YSkgewogIHJldHVybiB0aGlzLnB0ci5nZXRQcm94eSgpLm9uU2lua0F2YWlsYWJsZShtZXRhZGF0YS50b05ld1ZlcnNpb24oKSk7Cn07CgovKioKICogQWRhcHRlciBmb3IgbWVkaWEubW9qb20uTWlycm9yU2VydmljZVJlbW90aW5nU291cmNlLgogKi8KdmFyIE1pcnJvclNlcnZpY2VSZW1vdGluZ1NvdXJjZUFkYXB0ZXIgPSB7CiAgICBuYW1lOiAnbWVkaWE6Om1vam9tOjpNaXJyb3JTZXJ2aWNlUmVtb3RpbmdTb3VyY2UnLAogICAga1ZlcnNpb246IDAsCiAgICBwdHJDbGFzczogTWlycm9yU2VydmljZVJlbW90aW5nU291cmNlUHRyQWRhcHRlciwKICAgIHByb3h5Q2xhc3M6IG1lZGlhLm1vam9tLk1pcnJvclNlcnZpY2VSZW1vdGluZ1NvdXJjZS5wcm94eUNsYXNzLAogICAgc3R1YkNsYXNzOiBudWxsLAogICAgdmFsaWRhdGVSZXF1ZXN0OiBtZWRpYS5tb2pvbS5NaXJyb3JTZXJ2aWNlUmVtb3RpbmdTb3VyY2UudmFsaWRhdGVSZXF1ZXN0LAogICAgdmFsaWRhdGVSZXNwb25zZTogbnVsbCwKfTsKCi8qKgogKiBBZGFwdGVyIGZvciBtZWRpYVJvdXRlci5tb2pvbS5NZWRpYVN0YXR1c09ic2VydmVyLgogKiBAY29uc3RydWN0b3IKICovCmZ1bmN0aW9uIE1lZGlhU3RhdHVzT2JzZXJ2ZXJQdHJBZGFwdGVyKGhhbmRsZU9yUHRySW5mbykgewogIHRoaXMucHRyID0gbmV3IG1vam8uSW50ZXJmYWNlUHRyQ29udHJvbGxlcihNZWRpYVN0YXR1c09ic2VydmVyQWRhcHRlciwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaGFuZGxlT3JQdHJJbmZvKTsKfQoKTWVkaWFTdGF0dXNPYnNlcnZlclB0ckFkYXB0ZXIucHJvdG90eXBlID0KICAgIE9iamVjdC5jcmVhdGUobWVkaWFSb3V0ZXIubW9qb20uTWVkaWFTdGF0dXNPYnNlcnZlclB0ci5wcm90b3R5cGUpOwpNZWRpYVN0YXR1c09ic2VydmVyUHRyQWRhcHRlci5wcm90b3R5cGUuY29uc3RydWN0b3IgPQogICAgTWVkaWFTdGF0dXNPYnNlcnZlclB0ckFkYXB0ZXI7CgpNZWRpYVN0YXR1c09ic2VydmVyUHRyQWRhcHRlci5wcm90b3R5cGUub25NZWRpYVN0YXR1c1VwZGF0ZWQgPQogICAgZnVuY3Rpb24oc3RhdHVzKSB7CiAgcmV0dXJuIHRoaXMucHRyLmdldFByb3h5KCkub25NZWRpYVN0YXR1c1VwZGF0ZWQoc3RhdHVzLnRvTmV3VmVyc2lvbigpKTsKfTsKCi8qKgogKiBBZGFwdGVyIGZvciBtZWRpYVJvdXRlci5tb2pvbS5NZWRpYVN0YXR1c09ic2VydmVyLgogKi8KdmFyIE1lZGlhU3RhdHVzT2JzZXJ2ZXJBZGFwdGVyID0gewogIG5hbWU6ICdtZWRpYVJvdXRlcjo6bW9qb206Ok1lZGlhU3RhdHVzT2JzZXJ2ZXInLAogIGtWZXJzaW9uOiAwLAogIHB0ckNsYXNzOiBNZWRpYVN0YXR1c09ic2VydmVyUHRyQWRhcHRlciwKICBwcm94eUNsYXNzOiBtZWRpYVJvdXRlci5tb2pvbS5NZWRpYVN0YXR1c09ic2VydmVyLnByb3h5Q2xhc3MsCiAgc3R1YkNsYXNzOiBudWxsLAogIHZhbGlkYXRlUmVxdWVzdDogbWVkaWFSb3V0ZXIubW9qb20uTWVkaWFTdGF0dXNPYnNlcnZlci52YWxpZGF0ZVJlcXVlc3QsCiAgdmFsaWRhdGVSZXNwb25zZTogbnVsbCwKfTsKCi8qKgogKiBDb252ZXJ0cyBhIG1lZGlhIHNpbmsgdG8gYSBNZWRpYVNpbmsgTW9qbyBvYmplY3QuCiAqIEBwYXJhbSB7IU1lZGlhU2lua30gc2luayBBIG1lZGlhIHNpbmsuCiAqIEByZXR1cm4geyFtZWRpYVJvdXRlci5tb2pvbS5NZWRpYVNpbmt9IEEgTW9qbyBNZWRpYVNpbmsgb2JqZWN0LgogKi8KZnVuY3Rpb24gc2lua1RvTW9qb18oc2luaykgewogIHJldHVybiBuZXcgbWVkaWFSb3V0ZXIubW9qb20uTWVkaWFTaW5rKHsKICAgICduYW1lJzogc2luay5mcmllbmRseU5hbWUsCiAgICAnZGVzY3JpcHRpb24nOiBzaW5rLmRlc2NyaXB0aW9uLAogICAgJ2RvbWFpbic6IHNpbmsuZG9tYWluLAogICAgJ3NpbmtJZCc6IHNpbmsuaWQsCiAgICAnaWNvblR5cGUnOiBzaW5rSWNvblR5cGVUb01vam8oc2luay5pY29uVHlwZSksCiAgICAncHJvdmlkZXJJZCc6IG1lZGlhUm91dGVyLm1vam9tLk1lZGlhUm91dGVQcm92aWRlci5JZC5FWFRFTlNJT04sCiAgfSk7Cn0KCi8qKgogKiBDb252ZXJ0cyBhIG1lZGlhIHNpbmsncyBpY29uIHR5cGUgdG8gYSBNZWRpYVNpbmsuSWNvblR5cGUgTW9qbyBvYmplY3QuCiAqIEBwYXJhbSB7IU1lZGlhU2luay5JY29uVHlwZX0gdHlwZSBBIG1lZGlhIHNpbmsncyBpY29uIHR5cGUuCiAqIEByZXR1cm4geyFtZWRpYVJvdXRlci5tb2pvbS5NZWRpYVNpbmsuSWNvblR5cGV9IEEgTW9qbyBNZWRpYVNpbmsuSWNvblR5cGUKICogICAgIG9iamVjdC4KICovCmZ1bmN0aW9uIHNpbmtJY29uVHlwZVRvTW9qbyh0eXBlKSB7CiAgc3dpdGNoICh0eXBlKSB7CiAgICBjYXNlICdjYXN0JzoKICAgICAgcmV0dXJuIG1lZGlhUm91dGVyLm1vam9tLlNpbmtJY29uVHlwZS5DQVNUOwogICAgY2FzZSAnY2FzdF9hdWRpb19ncm91cCc6CiAgICAgIHJldHVybiBtZWRpYVJvdXRlci5tb2pvbS5TaW5rSWNvblR5cGUuQ0FTVF9BVURJT19HUk9VUDsKICAgIGNhc2UgJ2Nhc3RfYXVkaW8nOgogICAgICByZXR1cm4gbWVkaWFSb3V0ZXIubW9qb20uU2lua0ljb25UeXBlLkNBU1RfQVVESU87CiAgICBjYXNlICdtZWV0aW5nJzoKICAgICAgcmV0dXJuIG1lZGlhUm91dGVyLm1vam9tLlNpbmtJY29uVHlwZS5NRUVUSU5HOwogICAgY2FzZSAnaGFuZ291dCc6CiAgICAgIHJldHVybiBtZWRpYVJvdXRlci5tb2pvbS5TaW5rSWNvblR5cGUuSEFOR09VVDsKICAgIGNhc2UgJ2VkdWNhdGlvbic6CiAgICAgIHJldHVybiBtZWRpYVJvdXRlci5tb2pvbS5TaW5rSWNvblR5cGUuRURVQ0FUSU9OOwogICAgY2FzZSAnZ2VuZXJpYyc6CiAgICAgIHJldHVybiBtZWRpYVJvdXRlci5tb2pvbS5TaW5rSWNvblR5cGUuR0VORVJJQzsKICAgIGRlZmF1bHQ6CiAgICAgIGNvbnNvbGUuZXJyb3IoJ1Vua25vd24gc2luayBpY29uIHR5cGUgOiAnICsgdHlwZSk7CiAgICAgIHJldHVybiBtZWRpYVJvdXRlci5tb2pvbS5TaW5rSWNvblR5cGUuR0VORVJJQzsKICB9Cn0KCi8qKgogKiBSZXR1cm5zIGEgTW9qbyBNZWRpYVJvdXRlIG9iamVjdCBnaXZlbiBhIE1lZGlhUm91dGUgYW5kIGEKICogbWVkaWEgc2luayBuYW1lLgogKiBAcGFyYW0geyFNZWRpYVJvdXRlfSByb3V0ZQogKiBAcmV0dXJuIHshbWVkaWFSb3V0ZXIubW9qb20uTWVkaWFSb3V0ZX0KICovCmZ1bmN0aW9uIHJvdXRlVG9Nb2pvXyhyb3V0ZSkgewogIHJldHVybiBuZXcgbWVkaWFSb3V0ZXIubW9qb20uTWVkaWFSb3V0ZSh7CiAgICAnbWVkaWFSb3V0ZUlkJzogcm91dGUuaWQsCiAgICAnbWVkaWFTb3VyY2UnOiByb3V0ZS5tZWRpYVNvdXJjZSwKICAgICdtZWRpYVNpbmtJZCc6IHJvdXRlLnNpbmtJZCwKICAgICdkZXNjcmlwdGlvbic6IHJvdXRlLmRlc2NyaXB0aW9uLAogICAgJ2ljb25VcmwnOiByb3V0ZS5pY29uVXJsLAogICAgJ2lzTG9jYWwnOiByb3V0ZS5pc0xvY2FsLAogICAgJ2ZvckRpc3BsYXknOiByb3V0ZS5mb3JEaXNwbGF5LAogICAgJ2lzSW5jb2duaXRvJzogcm91dGUub2ZmVGhlUmVjb3JkLAogICAgJ2lzTG9jYWxQcmVzZW50YXRpb24nOiByb3V0ZS5pc09mZnNjcmVlblByZXNlbnRhdGlvbiwKICAgICdjb250cm9sbGVyVHlwZSc6IHJvdXRlLmNvbnRyb2xsZXJUeXBlLAogICAgLy8gQmVnaW4gbmV3bHkgYWRkZWQgcHJvcGVydGllcywgZm9sbG93ZWQgYnkgdGhlIG1pbGVzdG9uZSB0aGV5IHdlcmUKICAgIC8vIGFkZGVkLiAgVGhlIGd1YXJkIHNob3VsZCBiZSBzYWZlIHRvIHJlbW92ZSBOKzIgbWlsZXN0b25lcyBsYXRlci4KICAgICdwcmVzZW50YXRpb25JZCc6IHJvdXRlLnByZXNlbnRhdGlvbklkIHx8ICcnICAvLyBNNjQKICB9KTsKfQoKLyoqCiAqIENvbnZlcnRzIGEgcm91dGUgbWVzc2FnZSB0byBhIFJvdXRlTWVzc2FnZSBNb2pvIG9iamVjdC4KICogQHBhcmFtIHshUm91dGVNZXNzYWdlfSBtZXNzYWdlCiAqIEByZXR1cm4geyFtZWRpYVJvdXRlci5tb2pvbS5Sb3V0ZU1lc3NhZ2V9IEEgTW9qbyBSb3V0ZU1lc3NhZ2Ugb2JqZWN0LgogKi8KZnVuY3Rpb24gbWVzc2FnZVRvTW9qb18obWVzc2FnZSkgewogIGlmICgic3RyaW5nIiA9PSB0eXBlb2YgbWVzc2FnZS5tZXNzYWdlKSB7CiAgICByZXR1cm4gbmV3IG1lZGlhUm91dGVyLm1vam9tLlJvdXRlTWVzc2FnZSh7CiAgICAgICd0eXBlJzogbWVkaWFSb3V0ZXIubW9qb20uUm91dGVNZXNzYWdlLlR5cGUuVEVYVCwKICAgICAgJ21lc3NhZ2UnOiBtZXNzYWdlLm1lc3NhZ2UsCiAgICB9KTsKICB9IGVsc2UgewogICAgcmV0dXJuIG5ldyBtZWRpYVJvdXRlci5tb2pvbS5Sb3V0ZU1lc3NhZ2UoewogICAgICAndHlwZSc6IG1lZGlhUm91dGVyLm1vam9tLlJvdXRlTWVzc2FnZS5UeXBlLkJJTkFSWSwKICAgICAgJ2RhdGEnOiBtZXNzYWdlLm1lc3NhZ2UsCiAgICB9KTsKICB9Cn0KCi8qKgogKiBDb252ZXJ0cyBwcmVzZW50YXRpb24gY29ubmVjdGlvbiBzdGF0ZSB0byBNb2pvIGVudW0gdmFsdWUuCiAqIEBwYXJhbSB7IXN0cmluZ30gc3RhdGUKICogQHJldHVybiB7IW1lZGlhUm91dGVyLm1vam9tLk1lZGlhUm91dGVyLlByZXNlbnRhdGlvbkNvbm5lY3Rpb25TdGF0ZX0KICovCmZ1bmN0aW9uIHByZXNlbnRhdGlvbkNvbm5lY3Rpb25TdGF0ZVRvTW9qb18oc3RhdGUpIHsKICB2YXIgUHJlc2VudGF0aW9uQ29ubmVjdGlvblN0YXRlID0KICAgICAgbWVkaWFSb3V0ZXIubW9qb20uTWVkaWFSb3V0ZXIuUHJlc2VudGF0aW9uQ29ubmVjdGlvblN0YXRlOwogIHN3aXRjaCAoc3RhdGUpIHsKICAgIGNhc2UgJ2Nvbm5lY3RpbmcnOgogICAgICByZXR1cm4gUHJlc2VudGF0aW9uQ29ubmVjdGlvblN0YXRlLkNPTk5FQ1RJTkc7CiAgICBjYXNlICdjb25uZWN0ZWQnOgogICAgICByZXR1cm4gUHJlc2VudGF0aW9uQ29ubmVjdGlvblN0YXRlLkNPTk5FQ1RFRDsKICAgIGNhc2UgJ2Nsb3NlZCc6CiAgICAgIHJldHVybiBQcmVzZW50YXRpb25Db25uZWN0aW9uU3RhdGUuQ0xPU0VEOwogICAgY2FzZSAndGVybWluYXRlZCc6CiAgICAgIHJldHVybiBQcmVzZW50YXRpb25Db25uZWN0aW9uU3RhdGUuVEVSTUlOQVRFRDsKICAgIGRlZmF1bHQ6CiAgICAgIGNvbnNvbGUuZXJyb3IoJ1Vua25vd24gcHJlc2VudGF0aW9uIGNvbm5lY3Rpb24gc3RhdGU6ICcgKyBzdGF0ZSk7CiAgICAgIHJldHVybiBQcmVzZW50YXRpb25Db25uZWN0aW9uU3RhdGUuVEVSTUlOQVRFRDsKICB9Cn0KCi8qKgogKiBDb252ZXJ0cyBwcmVzZW50YXRpb24gY29ubmVjdGlvbiBjbG9zZSByZWFzb24gdG8gTW9qbyBlbnVtIHZhbHVlLgogKiBAcGFyYW0geyFzdHJpbmd9IHJlYXNvbgogKiBAcmV0dXJuIHshbWVkaWFSb3V0ZXIubW9qb20uTWVkaWFSb3V0ZXIuUHJlc2VudGF0aW9uQ29ubmVjdGlvbkNsb3NlUmVhc29ufQogKi8KZnVuY3Rpb24gcHJlc2VudGF0aW9uQ29ubmVjdGlvbkNsb3NlUmVhc29uVG9Nb2pvXyhyZWFzb24pIHsKICB2YXIgUHJlc2VudGF0aW9uQ29ubmVjdGlvbkNsb3NlUmVhc29uID0KICAgICAgbWVkaWFSb3V0ZXIubW9qb20uTWVkaWFSb3V0ZXIuUHJlc2VudGF0aW9uQ29ubmVjdGlvbkNsb3NlUmVhc29uOwogIHN3aXRjaCAocmVhc29uKSB7CiAgICBjYXNlICdlcnJvcic6CiAgICAgIHJldHVybiBQcmVzZW50YXRpb25Db25uZWN0aW9uQ2xvc2VSZWFzb24uQ09OTkVDVElPTl9FUlJPUjsKICAgIGNhc2UgJ2Nsb3NlZCc6CiAgICAgIHJldHVybiBQcmVzZW50YXRpb25Db25uZWN0aW9uQ2xvc2VSZWFzb24uQ0xPU0VEOwogICAgY2FzZSAnd2VudF9hd2F5JzoKICAgICAgcmV0dXJuIFByZXNlbnRhdGlvbkNvbm5lY3Rpb25DbG9zZVJlYXNvbi5XRU5UX0FXQVk7CiAgICBkZWZhdWx0OgogICAgICBjb25zb2xlLmVycm9yKCdVbmtub3duIHByZXNlbnRhdGlvbiBjb25uZWN0aW9uIGNsb3NlIHJlYXNvbiA6ICcgKwogICAgICAgICAgcmVhc29uKTsKICAgICAgcmV0dXJuIFByZXNlbnRhdGlvbkNvbm5lY3Rpb25DbG9zZVJlYXNvbi5DT05ORUNUSU9OX0VSUk9SOwogIH0KfQoKLyoqCiAqIENvbnZlcnRzIHN0cmluZyB0byBNb2pvIG9yaWdpbi4KICogQHBhcmFtIHtzdHJpbmd8IXVybC5tb2pvbS5PcmlnaW59IG9yaWdpbgogKiBAcmV0dXJuIHshdXJsLm1vam9tLk9yaWdpbn0KICovCmZ1bmN0aW9uIHN0cmluZ1RvTW9qb09yaWdpbl8ob3JpZ2luKSB7CiAgaWYgKG9yaWdpbiBpbnN0YW5jZW9mIHVybC5tb2pvbS5PcmlnaW4pIHsKICAgIHJldHVybiBvcmlnaW47CiAgfQogIHZhciBvcmlnaW5VcmwgPSBuZXcgVVJMKG9yaWdpbik7CiAgdmFyIG1vam9PcmlnaW4gPSB7fTsKICBtb2pvT3JpZ2luLnNjaGVtZSA9IG9yaWdpblVybC5wcm90b2NvbC5yZXBsYWNlKCc6JywgJycpOwogIG1vam9PcmlnaW4uaG9zdCA9IG9yaWdpblVybC5ob3N0bmFtZTsKICB2YXIgcG9ydCA9IG9yaWdpblVybC5wb3J0ID8gTnVtYmVyLnBhcnNlSW50KG9yaWdpblVybC5wb3J0KSA6IDA7CiAgc3dpdGNoIChtb2pvT3JpZ2luLnNjaGVtZSkgewogICAgY2FzZSAnaHR0cCc6CiAgICAgIG1vam9PcmlnaW4ucG9ydCA9IHBvcnQgfHwgODA7CiAgICAgIGJyZWFrOwogICAgY2FzZSAnaHR0cHMnOgogICAgICBtb2pvT3JpZ2luLnBvcnQgPSBwb3J0IHx8IDQ0MzsKICAgICAgYnJlYWs7CiAgICBkZWZhdWx0OgogICAgICB0aHJvdyBuZXcgRXJyb3IoJ1NjaGVtZSBtdXN0IGJlIGh0dHAgb3IgaHR0cHMnKTsKICB9CiAgbW9qb09yaWdpbi5zdWJvcmlnaW4gPSAnJzsKICByZXR1cm4gbmV3IHVybC5tb2pvbS5PcmlnaW4obW9qb09yaWdpbik7Cn0KCi8qKgogKiBQYXJzZXMgdGhlIGdpdmVuIHJvdXRlIHJlcXVlc3QgRXJyb3Igb2JqZWN0IGFuZCBjb252ZXJ0cyBpdCB0byB0aGUKICogY29ycmVzcG9uZGluZyByZXN1bHQgY29kZS4KICogQHBhcmFtIHshRXJyb3J9IGVycm9yCiAqIEByZXR1cm4geyFtZWRpYVJvdXRlci5tb2pvbS5Sb3V0ZVJlcXVlc3RSZXN1bHRDb2RlfQogKi8KZnVuY3Rpb24gZ2V0Um91dGVSZXF1ZXN0UmVzdWx0Q29kZV8oZXJyb3IpIHsKICByZXR1cm4gZXJyb3IuZXJyb3JDb2RlID8gZXJyb3IuZXJyb3JDb2RlIDoKICAgIG1lZGlhUm91dGVyLm1vam9tLlJvdXRlUmVxdWVzdFJlc3VsdENvZGUuVU5LTk9XTl9FUlJPUjsKfQoKLyoqCiAqIENyZWF0ZXMgYW5kIHJldHVybnMgYSBzdWNjZXNzZnVsIHJvdXRlIHJlc3BvbnNlIGZyb20gZ2l2ZW4gcm91dGUuCiAqIEBwYXJhbSB7IU1lZGlhUm91dGV9IHJvdXRlCiAqIEByZXR1cm4geyFPYmplY3R9CiAqLwpmdW5jdGlvbiB0b1N1Y2Nlc3NSb3V0ZVJlc3BvbnNlXyhyb3V0ZSkgewogIHJldHVybiB7CiAgICAgIHJvdXRlOiByb3V0ZVRvTW9qb18ocm91dGUpLAogICAgICByZXN1bHRDb2RlOiBtZWRpYVJvdXRlci5tb2pvbS5Sb3V0ZVJlcXVlc3RSZXN1bHRDb2RlLk9LCiAgfTsKfQoKLyoqCiAqIENyZWF0ZXMgYW5kIHJldHVybnMgYSBlcnJvciByb3V0ZSByZXNwb25zZSBmcm9tIGdpdmVuIEVycm9yIG9iamVjdC4KICogQHBhcmFtIHshRXJyb3J9IGVycm9yCiAqIEByZXR1cm4geyFPYmplY3R9CiAqLwpmdW5jdGlvbiB0b0Vycm9yUm91dGVSZXNwb25zZV8oZXJyb3IpIHsKICByZXR1cm4gewogICAgICBlcnJvclRleHQ6IGVycm9yLm1lc3NhZ2UsCiAgICAgIHJlc3VsdENvZGU6IGdldFJvdXRlUmVxdWVzdFJlc3VsdENvZGVfKGVycm9yKQogIH07Cn0KCi8qKgogKiBDcmVhdGVzIGEgbmV3IE1lZGlhUm91dGVyLgogKiBDb252ZXJ0cyBhIHJvdXRlIHN0cnVjdCB0byBpdHMgTW9qbyBmb3JtLgogKiBAcGFyYW0geyFtZWRpYVJvdXRlci5tb2pvbS5NZWRpYVJvdXRlclB0cn0gc2VydmljZQogKiBAY29uc3RydWN0b3IKICovCmZ1bmN0aW9uIE1lZGlhUm91dGVyKHNlcnZpY2UpIHsKICAvKioKICAgKiBUaGUgTW9qbyBzZXJ2aWNlIHByb3h5LiBBbGxvd3MgZXh0ZW5zaW9uIGNvZGUgdG8gY2FsbCBtZXRob2RzIHRoYXQgcmVzaWRlCiAgICogaW4gdGhlIGJyb3dzZXIuCiAgICogQHR5cGUgeyFtZWRpYVJvdXRlci5tb2pvbS5NZWRpYVJvdXRlclB0cn0KICAgKi8KICB0aGlzLnNlcnZpY2VfID0gc2VydmljZTsKCiAgLyoqCiAgICogVGhlIHByb3ZpZGVyIG1hbmFnZXIgc2VydmljZSBkZWxlZ2F0ZS4gSXRzIG1ldGhvZHMgYXJlIGNhbGxlZCBieSB0aGUKICAgKiBicm93c2VyLXJlc2lkZW50IE1vam8gc2VydmljZS4KICAgKiBAdHlwZSB7IU1lZGlhUm91dGVyfQogICAqLwogIHRoaXMubXJwbV8gPSBuZXcgTWVkaWFSb3V0ZVByb3ZpZGVyKHRoaXMpOwoKICAvKioKICAgKiBIYW5kbGUgdG8gYSBLZWVwQWxpdmUgc2VydmljZSBvYmplY3QsIHdoaWNoIHByZXZlbnRzIHRoZSBleHRlbnNpb24gZnJvbQogICAqIGJlaW5nIHN1c3BlbmRlZCBhcyBsb25nIGFzIGl0IHJlbWFpbnMgaW4gc2NvcGUuCiAgICogQHR5cGUge2Jvb2xlYW59CiAgICovCiAgdGhpcy5rZWVwQWxpdmVfID0gbnVsbDsKCiAgLyoqCiAgICogVGhlIGJpbmRpbmdzIHRvIGJpbmQgdGhlIHNlcnZpY2UgZGVsZWdhdGUgdG8gdGhlIE1vam8gaW50ZXJmYWNlLgogICAqIE9iamVjdCBtdXN0IHJlbWFpbiBpbiBzY29wZSBmb3IgdGhlIGxpZmV0aW1lIG9mIHRoZSBjb25uZWN0aW9uIHRvCiAgICogcHJldmVudCB0aGUgY29ubmVjdGlvbiBmcm9tIGNsb3NpbmcgYXV0b21hdGljYWxseS4KICAgKiBAdHlwZSB7IW1vam8uQmluZGluZ30KICAgKi8KICB0aGlzLm1lZGlhUm91dGVQcm92aWRlckJpbmRpbmdfID0gbmV3IG1vam8uQmluZGluZygKICAgICAgbWVkaWFSb3V0ZXIubW9qb20uTWVkaWFSb3V0ZVByb3ZpZGVyLCB0aGlzLm1ycG1fKTsKfQoKLyoqCiAqIFJldHVybnMgZGVmaW5pdGlvbnMgb2YgTW9qbyBjb3JlIGFuZCBnZW5lcmF0ZWQgTW9qb20gY2xhc3NlcyB0aGF0IGNhbiBiZQogKiB1c2VkIGRpcmVjdGx5IGJ5IHRoZSBjb21wb25lbnQuCiAqIEByZXR1cm4geyFPYmplY3R9CiAqIFRPRE8oaW1jaGVuZyk6IFdlIHNob3VsZCBleHBvcnQgdGhlc2UgYWxvbmcgd2l0aCBNZWRpYVJvdXRlci4gVGhpcyByZXF1aXJlcwogKiB1cyB0byBtb2RpZnkgdGhlIGNvbXBvbmVudCB0byBoYW5kbGUgbXVsdGlwbGUgZXhwb3J0cy4gV2hlbiB0aGF0IGxvZ2ljIGlzCiAqIGJha2VkIGluIGZvciBhIGNvdXBsZSBvZiBtaWxlc3RvbmVzLCB3ZSBzaG91bGQgYmUgYWJsZSB0byByZW1vdmUgdGhpcwogKiBtZXRob2QuCiAqIFRPRE8oaW1jaGVuZyk6IFdlIHNob3VsZCBzdG9wIGV4cG9ydGluZyBtb2pvIGJpbmRpbmdzIGNsYXNzZXMgdGhhdCB0aGUKICogTWVkaWEgUm91dGVyIGV4dGVuc2lvbiBkb2Vzbid0IGRpcmVjdGx5IHVzZSwgc3VjaCBhcwogKiBtb2pvLkFzc29jaWF0ZWRJbnRlcmZhY2VQdHJJbmZvLCBtb2pvLkludGVyZmFjZVB0ckNvbnRyb2xsZXIgYW5kCiAqIG1vam8uaW50ZXJmYWNlQ29udHJvbC4KICovCk1lZGlhUm91dGVyLnByb3RvdHlwZS5nZXRNb2pvRXhwb3J0cyA9IGZ1bmN0aW9uKCkgewogIHJldHVybiB7CiAgICBBc3NvY2lhdGVkSW50ZXJmYWNlUHRySW5mbzogbW9qby5Bc3NvY2lhdGVkSW50ZXJmYWNlUHRySW5mbywKICAgIEJpbmRpbmc6IG1vam8uQmluZGluZywKICAgIERpYWxNZWRpYVNpbms6IERpYWxNZWRpYVNpbmtBZGFwdGVyLAogICAgQ2FzdE1lZGlhU2luazogQ2FzdE1lZGlhU2lua0FkYXB0ZXIsCiAgICBIYW5nb3V0c01lZGlhUm91dGVDb250cm9sbGVyOgogICAgICAgIG1lZGlhUm91dGVyLm1vam9tLkhhbmdvdXRzTWVkaWFSb3V0ZUNvbnRyb2xsZXIsCiAgICBIYW5nb3V0c01lZGlhU3RhdHVzRXh0cmFEYXRhOiBIYW5nb3V0c01lZGlhU3RhdHVzRXh0cmFEYXRhQWRhcHRlciwKICAgIElQQWRkcmVzczogSVBBZGRyZXNzQWRhcHRlciwKICAgIElQRW5kcG9pbnQ6IElQRW5kcG9pbnRBZGFwdGVyLAogICAgSW50ZXJmYWNlUHRyQ29udHJvbGxlcjogbW9qby5JbnRlcmZhY2VQdHJDb250cm9sbGVyLAogICAgSW50ZXJmYWNlUHRySW5mbzogbW9qby5JbnRlcmZhY2VQdHJJbmZvLAogICAgSW50ZXJmYWNlUmVxdWVzdDogbW9qby5JbnRlcmZhY2VSZXF1ZXN0LAogICAgTWVkaWFDb250cm9sbGVyOiBtZWRpYVJvdXRlci5tb2pvbS5NZWRpYUNvbnRyb2xsZXIsCiAgICBNZWRpYVN0YXR1czogTWVkaWFTdGF0dXNBZGFwdGVyLAogICAgTWVkaWFTdGF0dXNPYnNlcnZlclB0cjogbWVkaWFSb3V0ZXIubW9qb20uTWVkaWFTdGF0dXNPYnNlcnZlclB0ciwKICAgIE1pcnJvclNlcnZpY2VSZW1vdGVyOiBNaXJyb3JTZXJ2aWNlUmVtb3RlckFkYXB0ZXIsCiAgICBNaXJyb3JTZXJ2aWNlUmVtb3RlclB0cjogTWlycm9yU2VydmljZVJlbW90ZXJQdHJBZGFwdGVyLAogICAgTWlycm9yU2VydmljZVJlbW90aW5nU291cmNlUHRyOiBNaXJyb3JTZXJ2aWNlUmVtb3RpbmdTb3VyY2VQdHJBZGFwdGVyLAogICAgUmVtb3RpbmdTdG9wUmVhc29uOiBtZWRpYS5tb2pvbS5SZW1vdGluZ1N0b3BSZWFzb24sCiAgICBSZW1vdGluZ1N0YXJ0RmFpbFJlYXNvbjogbWVkaWEubW9qb20uUmVtb3RpbmdTdGFydEZhaWxSZWFzb24sCiAgICBSZW1vdGluZ1NpbmtGZWF0dXJlOiBtZWRpYS5tb2pvbS5SZW1vdGluZ1NpbmtGZWF0dXJlLAogICAgUmVtb3RpbmdTaW5rQXVkaW9DYXBhYmlsaXR5OgogICAgICAgIG1lZGlhLm1vam9tLlJlbW90aW5nU2lua0F1ZGlvQ2FwYWJpbGl0eSwKICAgIFJlbW90aW5nU2lua1ZpZGVvQ2FwYWJpbGl0eToKICAgICAgICBtZWRpYS5tb2pvbS5SZW1vdGluZ1NpbmtWaWRlb0NhcGFiaWxpdHksCiAgICBSZW1vdGluZ1NpbmtNZXRhZGF0YTogUmVtb3RpbmdTaW5rTWV0YWRhdGFBZGFwdGVyLAogICAgUm91dGVDb250cm9sbGVyVHlwZTogbWVkaWFSb3V0ZXIubW9qb20uUm91dGVDb250cm9sbGVyVHlwZSwKICAgIE9yaWdpbjogdXJsLm1vam9tLk9yaWdpbiwKICAgIFNpbms6IE1lZGlhU2lua0FkYXB0ZXIsCiAgICBTaW5rRXh0cmFEYXRhOiBNZWRpYVNpbmtFeHRyYURhdGFBZGFwdGVyLAogICAgVGltZURlbHRhOiBtb2pvLmNvbW1vbi5tb2pvbS5UaW1lRGVsdGEsCiAgICBVcmw6IHVybC5tb2pvbS5VcmwsCiAgICBpbnRlcmZhY2VDb250cm9sOiBtb2pvLmludGVyZmFjZUNvbnRyb2wsCiAgICBtYWtlUmVxdWVzdDogbW9qby5tYWtlUmVxdWVzdCwKICB9Owp9OwoKLyoqCiAqIFJlZ2lzdGVycyB0aGUgTWVkaWEgUm91dGVyIFByb3ZpZGVyIE1hbmFnZXIgd2l0aCB0aGUgTWVkaWEgUm91dGVyLgogKiBAcmV0dXJuIHshUHJvbWlzZTxPYmplY3Q+fSBJbnN0YW5jZSBJRCBhbmQgY29uZmlnIGZvciB0aGUgTWVkaWEgUm91dGVyLgogKi8KTWVkaWFSb3V0ZXIucHJvdG90eXBlLnN0YXJ0ID0gZnVuY3Rpb24oKSB7CiAgcmV0dXJuIHRoaXMuc2VydmljZV8ucmVnaXN0ZXJNZWRpYVJvdXRlUHJvdmlkZXIoCiAgICAgIG1lZGlhUm91dGVyLm1vam9tLk1lZGlhUm91dGVQcm92aWRlci5JZC5FWFRFTlNJT04sCiAgICAgIHRoaXMubWVkaWFSb3V0ZVByb3ZpZGVyQmluZGluZ18uY3JlYXRlSW50ZXJmYWNlUHRyQW5kQmluZCgpKS50aGVuKAogICAgICAgICAgZnVuY3Rpb24ocmVzcG9uc2UpIHsKICAgICAgICAgICAgcmV0dXJuIHsKICAgICAgICAgICAgICAnaW5zdGFuY2VfaWQnOiByZXNwb25zZS5pbnN0YW5jZUlkLAogICAgICAgICAgICAgICdjb25maWcnOiB7CiAgICAgICAgICAgICAgICAnZW5hYmxlX2RpYWxfZGlzY292ZXJ5JzogcmVzcG9uc2UuY29uZmlnLmVuYWJsZURpYWxEaXNjb3ZlcnksCiAgICAgICAgICAgICAgICAnZW5hYmxlX2Nhc3RfZGlzY292ZXJ5JzogcmVzcG9uc2UuY29uZmlnLmVuYWJsZUNhc3REaXNjb3ZlcnksCiAgICAgICAgICAgICAgfQogICAgICAgICAgICB9OwogICAgICAgICAgfSk7Cn0KCi8qKgogKiBTZXRzIHRoZSBzZXJ2aWNlIGRlbGVnYXRlIG1ldGhvZHMuCiAqIEBwYXJhbSB7T2JqZWN0fSBoYW5kbGVycwogKi8KTWVkaWFSb3V0ZXIucHJvdG90eXBlLnNldEhhbmRsZXJzID0gZnVuY3Rpb24oaGFuZGxlcnMpIHsKICB0aGlzLm1ycG1fLnNldEhhbmRsZXJzKGhhbmRsZXJzKTsKfQoKLyoqCiAqIFRoZSBrZWVwIGFsaXZlIHN0YXR1cy4KICogQHJldHVybiB7Ym9vbGVhbn0KICovCk1lZGlhUm91dGVyLnByb3RvdHlwZS5nZXRLZWVwQWxpdmUgPSBmdW5jdGlvbigpIHsKICByZXR1cm4gdGhpcy5rZWVwQWxpdmVfICE9IG51bGw7Cn07CgovKioKICogQ2FsbGVkIGJ5IHRoZSBwcm92aWRlciBtYW5hZ2VyIHdoZW4gYSBzaW5rIGxpc3QgZm9yIGEgZ2l2ZW4gc291cmNlIGlzCiAqIHVwZGF0ZWQuCiAqIEBwYXJhbSB7IXN0cmluZ30gc291cmNlVXJuCiAqIEBwYXJhbSB7IUFycmF5PCFNZWRpYVNpbms+fSBzaW5rcwogKiBAcGFyYW0geyFBcnJheTxzdHJpbmd8IXVybC5tb2pvbS5PcmlnaW4+fSBvcmlnaW5zCiAqLwpNZWRpYVJvdXRlci5wcm90b3R5cGUub25TaW5rc1JlY2VpdmVkID0gZnVuY3Rpb24oc291cmNlVXJuLCBzaW5rcywgb3JpZ2lucykgewogIC8vIHxvcmlnaW5zfCBpcyBhIHN0cmluZyBhcnJheSBpZiB0aGUgTWVkaWEgUm91dGVyIGNvbXBvbmVudCBleHRlbnNpb24gdmVyc2lvbgogIC8vIGlzIDU5IG9yIG9sZGVyLiBXaXRob3V0IHRoZSBzdHJpbmdUb01vam9PcmlnaW5fKCkgY29udmVyc2lvbiwgY2xpZW50cyB1c2luZwogIC8vIHRob3NlIGV4dGVuc2lvbiB2ZXJzaW9ucyB3b3VsZCBzZWUgYSBjcmFzaCBzaG93biBpbgogIC8vIGh0dHBzOi8vY3JidWcuY29tLzc4NzQyNy4KICB0aGlzLnNlcnZpY2VfLm9uU2lua3NSZWNlaXZlZCgKICAgICAgbWVkaWFSb3V0ZXIubW9qb20uTWVkaWFSb3V0ZVByb3ZpZGVyLklkLkVYVEVOU0lPTiwgc291cmNlVXJuLAogICAgICBzaW5rcy5tYXAoc2lua1RvTW9qb18pLCBvcmlnaW5zLm1hcChzdHJpbmdUb01vam9PcmlnaW5fKSk7Cn07CgovKioKICogQ2FsbGVkIGJ5IHRoZSBwcm92aWRlciBtYW5hZ2VyIHdoZW4gYSBzaW5rIGlzIGZvdW5kIHRvIG5vdGlmeSB0aGUgTVIgb2YgdGhlCiAqIHNpbmsncyBJRC4gVGhlIGFjdHVhbCBzaW5rIHdpbGwgYmUgcmV0dXJuZWQgdGhyb3VnaCB0aGUgbm9ybWFsIHNpbmsgbGlzdAogKiB1cGRhdGUgcHJvY2Vzcywgc28gdGhpcyBoZWxwcyB0aGUgTVIgaWRlbnRpZnkgdGhlIHNlYXJjaCByZXN1bHQgaW4gdGhlCiAqIGxpc3QuCiAqIEBwYXJhbSB7c3RyaW5nfSBwc2V1ZG9TaW5rSWQgIElEIG9mIHRoZSBwc2V1ZG8gc2luayB0aGF0IHN0YXJ0ZWQgdGhlCiAqICAgICBzZWFyY2guCiAqIEBwYXJhbSB7c3RyaW5nfSBzaW5rSWQgSUQgb2YgdGhlIG5ld2x5LWZvdW5kIHNpbmsuCiAqLwpNZWRpYVJvdXRlci5wcm90b3R5cGUub25TZWFyY2hTaW5rSWRSZWNlaXZlZCA9IGZ1bmN0aW9uKAogICAgcHNldWRvU2lua0lkLCBzaW5rSWQpIHsKICB0aGlzLnNlcnZpY2VfLm9uU2VhcmNoU2lua0lkUmVjZWl2ZWQocHNldWRvU2lua0lkLCBzaW5rSWQpOwp9OwoKLyoqCiAqIENhbGxlZCBieSB0aGUgcHJvdmlkZXIgbWFuYWdlciB0byBrZWVwIHRoZSBleHRlbnNpb24gZnJvbSBzdXNwZW5kaW5nCiAqIGlmIGl0IGVudGVycyBhIHN0YXRlIHdoZXJlIHN1c3BlbnNpb24gaXMgdW5kZXNpcmFibGUgKGUuZy4gdGhlcmUgaXMgYW4KICogYWN0aXZlIE1lZGlhUm91dGUuKQogKiBJZiBrZWVwQWxpdmUgaXMgdHJ1ZSwgdGhlIGV4dGVuc2lvbiBpcyBrZXB0IGFsaXZlLgogKiBJZiBrZWVwQWxpdmUgaXMgZmFsc2UsIHRoZSBleHRlbnNpb24gaXMgYWxsb3dlZCB0byBzdXNwZW5kLgogKiBAcGFyYW0ge2Jvb2xlYW59IGtlZXBBbGl2ZQogKi8KTWVkaWFSb3V0ZXIucHJvdG90eXBlLnNldEtlZXBBbGl2ZSA9IGZ1bmN0aW9uKGtlZXBBbGl2ZSkgewogIGlmIChrZWVwQWxpdmUgPT09IGZhbHNlICYmIHRoaXMua2VlcEFsaXZlXykgewogICAgdGhpcy5rZWVwQWxpdmVfLnB0ci5yZXNldCgpOwogICAgdGhpcy5rZWVwQWxpdmVfID0gbnVsbDsKICB9IGVsc2UgaWYgKGtlZXBBbGl2ZSA9PT0gdHJ1ZSAmJiAhdGhpcy5rZWVwQWxpdmVfKSB7CiAgICB0aGlzLmtlZXBBbGl2ZV8gPSBuZXcgZXh0ZW5zaW9ucy5LZWVwQWxpdmVQdHI7CiAgICBNb2pvLmJpbmRJbnRlcmZhY2UoZXh0ZW5zaW9ucy5LZWVwQWxpdmUubmFtZSwKICAgICAgICAgICAgICAgICAgICAgICBtb2pvLm1ha2VSZXF1ZXN0KHRoaXMua2VlcEFsaXZlXykuaGFuZGxlKTsKICB9Cn07CgovKioKICogQ2FsbGVkIGJ5IHRoZSBwcm92aWRlciBtYW5hZ2VyIHRvIHNlbmQgYW4gaXNzdWUgZnJvbSBhIG1lZGlhIHJvdXRlCiAqIHByb3ZpZGVyIHRvIHRoZSBNZWRpYSBSb3V0ZXIsIHRvIHNob3cgdGhlIHVzZXIuCiAqIEBwYXJhbSB7IU9iamVjdH0gaXNzdWUgVGhlIGlzc3VlIG9iamVjdC4KICovCk1lZGlhUm91dGVyLnByb3RvdHlwZS5vbklzc3VlID0gZnVuY3Rpb24oaXNzdWUpIHsKICBmdW5jdGlvbiBpc3N1ZVNldmVyaXR5VG9Nb2pvXyhzZXZlcml0eSkgewogICAgc3dpdGNoIChzZXZlcml0eSkgewogICAgICBjYXNlICdmYXRhbCc6CiAgICAgICAgcmV0dXJuIG1lZGlhUm91dGVyLm1vam9tLklzc3VlLlNldmVyaXR5LkZBVEFMOwogICAgICBjYXNlICd3YXJuaW5nJzoKICAgICAgICByZXR1cm4gbWVkaWFSb3V0ZXIubW9qb20uSXNzdWUuU2V2ZXJpdHkuV0FSTklORzsKICAgICAgY2FzZSAnbm90aWZpY2F0aW9uJzoKICAgICAgICByZXR1cm4gbWVkaWFSb3V0ZXIubW9qb20uSXNzdWUuU2V2ZXJpdHkuTk9USUZJQ0FUSU9OOwogICAgICBkZWZhdWx0OgogICAgICAgIGNvbnNvbGUuZXJyb3IoJ1Vua25vd24gaXNzdWUgc2V2ZXJpdHk6ICcgKyBzZXZlcml0eSk7CiAgICAgICAgcmV0dXJuIG1lZGlhUm91dGVyLm1vam9tLklzc3VlLlNldmVyaXR5Lk5PVElGSUNBVElPTjsKICAgIH0KICB9CgogIGZ1bmN0aW9uIGlzc3VlQWN0aW9uVG9Nb2pvXyhhY3Rpb24pIHsKICAgIHN3aXRjaCAoYWN0aW9uKSB7CiAgICAgIGNhc2UgJ2Rpc21pc3MnOgogICAgICAgIHJldHVybiBtZWRpYVJvdXRlci5tb2pvbS5Jc3N1ZS5BY3Rpb25UeXBlLkRJU01JU1M7CiAgICAgIGNhc2UgJ2xlYXJuX21vcmUnOgogICAgICAgIHJldHVybiBtZWRpYVJvdXRlci5tb2pvbS5Jc3N1ZS5BY3Rpb25UeXBlLkxFQVJOX01PUkU7CiAgICAgIGRlZmF1bHQ6CiAgICAgICAgY29uc29sZS5lcnJvcignVW5rbm93biBpc3N1ZSBhY3Rpb24gdHlwZSA6ICcgKyBhY3Rpb24pOwogICAgICAgIHJldHVybiBtZWRpYVJvdXRlci5tb2pvbS5Jc3N1ZS5BY3Rpb25UeXBlLk9LOwogICAgfQogIH0KCiAgdmFyIHNlY29uZGFyeUFjdGlvbnMgPSAoaXNzdWUuc2Vjb25kYXJ5QWN0aW9ucyB8fCBbXSkubWFwKGlzc3VlQWN0aW9uVG9Nb2pvXyk7CiAgdGhpcy5zZXJ2aWNlXy5vbklzc3VlKG5ldyBtZWRpYVJvdXRlci5tb2pvbS5Jc3N1ZSh7CiAgICAncm91dGVJZCc6IGlzc3VlLnJvdXRlSWQgfHwgJycsCiAgICAnc2V2ZXJpdHknOiBpc3N1ZVNldmVyaXR5VG9Nb2pvXyhpc3N1ZS5zZXZlcml0eSksCiAgICAndGl0bGUnOiBpc3N1ZS50aXRsZSwKICAgICdtZXNzYWdlJzogaXNzdWUubWVzc2FnZSB8fCAnJywKICAgICdkZWZhdWx0QWN0aW9uJzogaXNzdWVBY3Rpb25Ub01vam9fKGlzc3VlLmRlZmF1bHRBY3Rpb24pLAogICAgJ3NlY29uZGFyeUFjdGlvbnMnOiBzZWNvbmRhcnlBY3Rpb25zLAogICAgJ2hlbHBQYWdlSWQnOiBpc3N1ZS5oZWxwUGFnZUlkLAogICAgJ2lzQmxvY2tpbmcnOiBpc3N1ZS5pc0Jsb2NraW5nCiAgfSkpOwp9OwoKLyoqCiAqIENhbGxlZCBieSB0aGUgcHJvdmlkZXIgbWFuYWdlciB3aGVuIHRoZSBzZXQgb2YgYWN0aXZlIHJvdXRlcwogKiBoYXMgYmVlbiB1cGRhdGVkLgogKiBAcGFyYW0geyFBcnJheTxNZWRpYVJvdXRlPn0gcm91dGVzIFRoZSBhY3RpdmUgc2V0IG9mIG1lZGlhIHJvdXRlcy4KICogQHBhcmFtIHtzdHJpbmc9fSBzb3VyY2VVcm4gVGhlIHNvdXJjZVVybiBhc3NvY2lhdGVkIHdpdGggdGhpcyByb3V0ZQogKiAgICAgcXVlcnkuCiAqIEBwYXJhbSB7QXJyYXk8c3RyaW5nPj19IGpvaW5hYmxlUm91dGVJZHMgVGhlIGFjdGl2ZSBzZXQgb2Ygam9pbmFibGUKICogICAgIG1lZGlhIHJvdXRlcy4KICovCk1lZGlhUm91dGVyLnByb3RvdHlwZS5vblJvdXRlc1VwZGF0ZWQgPSBmdW5jdGlvbigKICAgIHJvdXRlcywgc291cmNlVXJuID0gJycsIGpvaW5hYmxlUm91dGVJZHMgPSBbXSkgewogIHRoaXMuc2VydmljZV8ub25Sb3V0ZXNVcGRhdGVkKAogICAgICBtZWRpYVJvdXRlci5tb2pvbS5NZWRpYVJvdXRlUHJvdmlkZXIuSWQuRVhURU5TSU9OLAogICAgICByb3V0ZXMubWFwKHJvdXRlVG9Nb2pvXyksIHNvdXJjZVVybiwgam9pbmFibGVSb3V0ZUlkcyk7Cn07CgovKioKICogQ2FsbGVkIGJ5IHRoZSBwcm92aWRlciBtYW5hZ2VyIHdoZW4gc2luayBhdmFpbGFiaWxpdHkgaGFzIGJlZW4gdXBkYXRlZC4KICogQHBhcmFtIHshbWVkaWFSb3V0ZXIubW9qb20uTWVkaWFSb3V0ZXIuU2lua0F2YWlsYWJpbGl0eX0gYXZhaWxhYmlsaXR5CiAqICAgICBUaGUgbmV3IHNpbmsgYXZhaWxhYmlsaXR5LgogKi8KTWVkaWFSb3V0ZXIucHJvdG90eXBlLm9uU2lua0F2YWlsYWJpbGl0eVVwZGF0ZWQgPSBmdW5jdGlvbihhdmFpbGFiaWxpdHkpIHsKICB0aGlzLnNlcnZpY2VfLm9uU2lua0F2YWlsYWJpbGl0eVVwZGF0ZWQoCiAgICAgIG1lZGlhUm91dGVyLm1vam9tLk1lZGlhUm91dGVQcm92aWRlci5JZC5FWFRFTlNJT04sIGF2YWlsYWJpbGl0eSk7Cn07CgovKioKICogQ2FsbGVkIGJ5IHRoZSBwcm92aWRlciBtYW5hZ2VyIHdoZW4gdGhlIHN0YXRlIG9mIGEgcHJlc2VudGF0aW9uIGNvbm5lY3RlZAogKiB0byBhIHJvdXRlIGhhcyBjaGFuZ2VkLgogKiBAcGFyYW0ge3N0cmluZ30gcm91dGVJZAogKiBAcGFyYW0ge3N0cmluZ30gc3RhdGUKICovCk1lZGlhUm91dGVyLnByb3RvdHlwZS5vblByZXNlbnRhdGlvbkNvbm5lY3Rpb25TdGF0ZUNoYW5nZWQgPQogICAgZnVuY3Rpb24ocm91dGVJZCwgc3RhdGUpIHsKICB0aGlzLnNlcnZpY2VfLm9uUHJlc2VudGF0aW9uQ29ubmVjdGlvblN0YXRlQ2hhbmdlZCgKICAgICAgcm91dGVJZCwgcHJlc2VudGF0aW9uQ29ubmVjdGlvblN0YXRlVG9Nb2pvXyhzdGF0ZSkpOwp9OwoKLyoqCiAqIENhbGxlZCBieSB0aGUgcHJvdmlkZXIgbWFuYWdlciB3aGVuIHRoZSBzdGF0ZSBvZiBhIHByZXNlbnRhdGlvbiBjb25uZWN0ZWQKICogdG8gYSByb3V0ZSBoYXMgY2xvc2VkLgogKiBAcGFyYW0ge3N0cmluZ30gcm91dGVJZAogKiBAcGFyYW0ge3N0cmluZ30gcmVhc29uCiAqIEBwYXJhbSB7c3RyaW5nfSBtZXNzYWdlCiAqLwpNZWRpYVJvdXRlci5wcm90b3R5cGUub25QcmVzZW50YXRpb25Db25uZWN0aW9uQ2xvc2VkID0KICAgIGZ1bmN0aW9uKHJvdXRlSWQsIHJlYXNvbiwgbWVzc2FnZSkgewogIHRoaXMuc2VydmljZV8ub25QcmVzZW50YXRpb25Db25uZWN0aW9uQ2xvc2VkKAogICAgICByb3V0ZUlkLCBwcmVzZW50YXRpb25Db25uZWN0aW9uQ2xvc2VSZWFzb25Ub01vam9fKHJlYXNvbiksIG1lc3NhZ2UpOwp9OwoKLyoqCiAqIEBwYXJhbSB7c3RyaW5nfSByb3V0ZUlkCiAqIEBwYXJhbSB7IUFycmF5PCFSb3V0ZU1lc3NhZ2U+fSBtZXNhZ2VzCiAqLwpNZWRpYVJvdXRlci5wcm90b3R5cGUub25Sb3V0ZU1lc3NhZ2VzUmVjZWl2ZWQgPSBmdW5jdGlvbihyb3V0ZUlkLCBtZXNzYWdlcykgewogIHRoaXMuc2VydmljZV8ub25Sb3V0ZU1lc3NhZ2VzUmVjZWl2ZWQoCiAgICAgIHJvdXRlSWQsIG1lc3NhZ2VzLm1hcChtZXNzYWdlVG9Nb2pvXykpOwp9OwoKLyoqCiAqIEBwYXJhbSB7bnVtYmVyfSB0YWJJZAogKiBAcGFyYW0geyFtZWRpYS5tb2pvbS5NaXJyb3JTZXJ2aWNlUmVtb3RlclB0cn0gcmVtb3RlcgogKiBAcGFyYW0geyFtb2pvLkludGVyZmFjZVJlcXVlc3R9IHJlbW90aW5nU291cmNlCiAqLwpNZWRpYVJvdXRlci5wcm90b3R5cGUub25NZWRpYVJlbW90ZXJDcmVhdGVkID0gZnVuY3Rpb24odGFiSWQsIHJlbW90ZXIsCiAgICByZW1vdGluZ1NvdXJjZSkgewogIHRoaXMuc2VydmljZV8ub25NZWRpYVJlbW90ZXJDcmVhdGVkKAogICAgICB0YWJJZCwKICAgICAgbmV3IG1lZGlhLm1vam9tLk1pcnJvclNlcnZpY2VSZW1vdGVyUHRyKHJlbW90ZXIucHRyLnBhc3NJbnRlcmZhY2UoKSksCiAgICAgIHJlbW90aW5nU291cmNlKTsKfQoKLyoqCiAqIE9iamVjdCBjb250YWluaW5nIGNhbGxiYWNrcyBzZXQgYnkgdGhlIHByb3ZpZGVyIG1hbmFnZXIuCiAqCiAqIEBjb25zdHJ1Y3RvcgogKiBAc3RydWN0CiAqLwpmdW5jdGlvbiBNZWRpYVJvdXRlckhhbmRsZXJzKCkgewogIC8qKgogICAqIEB0eXBlIHtmdW5jdGlvbighc3RyaW5nLCAhc3RyaW5nLCAhc3RyaW5nLCAhc3RyaW5nLCAhbnVtYmVyKX0KICAgKi8KICB0aGlzLmNyZWF0ZVJvdXRlID0gbnVsbDsKCiAgLyoqCiAgICogQHR5cGUge2Z1bmN0aW9uKCFzdHJpbmcsICFzdHJpbmcsICFzdHJpbmcsICFudW1iZXIpfQogICAqLwogIHRoaXMuam9pblJvdXRlID0gbnVsbDsKCiAgLyoqCiAgICogQHR5cGUge2Z1bmN0aW9uKHN0cmluZyk6IFByb21pc2V9CiAgICovCiAgdGhpcy50ZXJtaW5hdGVSb3V0ZSA9IG51bGw7CgogIC8qKgogICAqIEB0eXBlIHtmdW5jdGlvbihzdHJpbmcpfQogICAqLwogIHRoaXMuc3RhcnRPYnNlcnZpbmdNZWRpYVNpbmtzID0gbnVsbDsKCiAgLyoqCiAgICogQHR5cGUge2Z1bmN0aW9uKHN0cmluZyl9CiAgICovCiAgdGhpcy5zdG9wT2JzZXJ2aW5nTWVkaWFTaW5rcyA9IG51bGw7CgogIC8qKgogICAqIEB0eXBlIHtmdW5jdGlvbihzdHJpbmcsIHN0cmluZyk6IFByb21pc2V9CiAgICovCiAgdGhpcy5zZW5kUm91dGVNZXNzYWdlID0gbnVsbDsKCiAgLyoqCiAgICogQHR5cGUge2Z1bmN0aW9uKHN0cmluZywgVWludDhBcnJheSk6IFByb21pc2V9CiAgICovCiAgdGhpcy5zZW5kUm91dGVCaW5hcnlNZXNzYWdlID0gbnVsbDsKCiAgLyoqCiAgICogQHR5cGUge2Z1bmN0aW9uKHN0cmluZyl9CiAgICovCiAgdGhpcy5zdGFydExpc3RlbmluZ0ZvclJvdXRlTWVzc2FnZXMgPSBudWxsOwoKICAvKioKICAgKiBAdHlwZSB7ZnVuY3Rpb24oc3RyaW5nKX0KICAgKi8KICB0aGlzLnN0b3BMaXN0ZW5pbmdGb3JSb3V0ZU1lc3NhZ2VzID0gbnVsbDsKCiAgLyoqCiAgICogQHR5cGUge2Z1bmN0aW9uKHN0cmluZyl9CiAgICovCiAgdGhpcy5kZXRhY2hSb3V0ZSA9IG51bGw7CgogIC8qKgogICAqIEB0eXBlIHtmdW5jdGlvbigpfQogICAqLwogIHRoaXMuc3RhcnRPYnNlcnZpbmdNZWRpYVJvdXRlcyA9IG51bGw7CgogIC8qKgogICAqIEB0eXBlIHtmdW5jdGlvbigpfQogICAqLwogIHRoaXMuc3RvcE9ic2VydmluZ01lZGlhUm91dGVzID0gbnVsbDsKCiAgLyoqCiAgICogQHR5cGUge2Z1bmN0aW9uKCl9CiAgICovCiAgdGhpcy5jb25uZWN0Um91dGVCeVJvdXRlSWQgPSBudWxsOwoKICAvKioKICAgKiBAdHlwZSB7ZnVuY3Rpb24oKX0KICAgKi8KICB0aGlzLmVuYWJsZU1kbnNEaXNjb3ZlcnkgPSBudWxsOwoKICAvKioKICAgKiBAdHlwZSB7ZnVuY3Rpb24oKX0KICAgKi8KICB0aGlzLnVwZGF0ZU1lZGlhU2lua3MgPSBudWxsOwoKICAvKioKICAgKiBAdHlwZSB7ZnVuY3Rpb24oc3RyaW5nLCBzdHJpbmcsICFTaW5rU2VhcmNoQ3JpdGVyaWEpOiBzdHJpbmd9CiAgICovCiAgdGhpcy5zZWFyY2hTaW5rcyA9IG51bGw7CgogIC8qKgogICAqIEB0eXBlIHtmdW5jdGlvbigpfQogICAqLwogIHRoaXMucHJvdmlkZVNpbmtzID0gbnVsbDsKCiAgLyoqCiAgICogQHR5cGUge2Z1bmN0aW9uKHN0cmluZywgIW1vam8uSW50ZXJmYWNlUmVxdWVzdCwKICAgKiAgICAgICAgICAgICFtZWRpYVJvdXRlci5tb2pvbS5NZWRpYVN0YXR1c09ic2VydmVyUHRyKTogIVByb21pc2U8dm9pZD59CiAgICovCiAgdGhpcy5jcmVhdGVNZWRpYVJvdXRlQ29udHJvbGxlciA9IG51bGw7Cn07CgovKioKICogUm91dGVzIGNhbGxzIGZyb20gTWVkaWEgUm91dGVyIHRvIHRoZSBwcm92aWRlciBtYW5hZ2VyIGV4dGVuc2lvbi4KICogUmVnaXN0ZXJlZCB3aXRoIHRoZSBNZWRpYVJvdXRlciBzdHViLgogKiBAcGFyYW0geyFNZWRpYVJvdXRlcn0gTWVkaWFSb3V0ZXIgcHJveHkgdG8gY2FsbCBpbnRvIHRoZQogKiBNZWRpYSBSb3V0ZXIgbW9qbyBpbnRlcmZhY2UuCiAqIEBjb25zdHJ1Y3RvcgogKi8KZnVuY3Rpb24gTWVkaWFSb3V0ZVByb3ZpZGVyKG1lZGlhUm91dGVyKSB7CiAgLyoqCiAgICogT2JqZWN0IGNvbnRhaW5pbmcgSlMgY2FsbGJhY2tzIGludG8gUHJvdmlkZXIgTWFuYWdlciBjb2RlLgogICAqIEB0eXBlIHshTWVkaWFSb3V0ZXJIYW5kbGVyc30KICAgKi8KICB0aGlzLmhhbmRsZXJzXyA9IG5ldyBNZWRpYVJvdXRlckhhbmRsZXJzKCk7CgogIC8qKgogICAqIFByb3h5IGNsYXNzIHRvIHRoZSBicm93c2VyJ3MgTWVkaWEgUm91dGVyIE1vam8gc2VydmljZS4KICAgKiBAdHlwZSB7IU1lZGlhUm91dGVyfQogICAqLwogIHRoaXMubWVkaWFSb3V0ZXJfID0gbWVkaWFSb3V0ZXI7Cn0KCi8qCiAqIFNldHMgdGhlIGNhbGxiYWNrIGhhbmRsZXIgdXNlZCB0byBpbnZva2UgbWV0aG9kcyBpbiB0aGUgcHJvdmlkZXIgbWFuYWdlci4KICoKICogQHBhcmFtIHshTWVkaWFSb3V0ZXJIYW5kbGVyc30gaGFuZGxlcnMKICovCk1lZGlhUm91dGVQcm92aWRlci5wcm90b3R5cGUuc2V0SGFuZGxlcnMgPSBmdW5jdGlvbihoYW5kbGVycykgewogIHRoaXMuaGFuZGxlcnNfID0gaGFuZGxlcnM7CiAgdmFyIHJlcXVpcmVkSGFuZGxlcnMgPSBbCiAgICAnc3RvcE9ic2VydmluZ01lZGlhUm91dGVzJywKICAgICdzdGFydE9ic2VydmluZ01lZGlhUm91dGVzJywKICAgICdzZW5kUm91dGVNZXNzYWdlJywKICAgICdzZW5kUm91dGVCaW5hcnlNZXNzYWdlJywKICAgICdzdGFydExpc3RlbmluZ0ZvclJvdXRlTWVzc2FnZXMnLAogICAgJ3N0b3BMaXN0ZW5pbmdGb3JSb3V0ZU1lc3NhZ2VzJywKICAgICdkZXRhY2hSb3V0ZScsCiAgICAndGVybWluYXRlUm91dGUnLAogICAgJ2pvaW5Sb3V0ZScsCiAgICAnY3JlYXRlUm91dGUnLAogICAgJ3N0b3BPYnNlcnZpbmdNZWRpYVNpbmtzJywKICAgICdzdGFydE9ic2VydmluZ01lZGlhUm91dGVzJywKICAgICdjb25uZWN0Um91dGVCeVJvdXRlSWQnLAogICAgJ2VuYWJsZU1kbnNEaXNjb3ZlcnknLAogICAgJ3VwZGF0ZU1lZGlhU2lua3MnLAogICAgJ3NlYXJjaFNpbmtzJywKICAgICdwcm92aWRlU2lua3MnLAogICAgJ2NyZWF0ZU1lZGlhUm91dGVDb250cm9sbGVyJywKICAgICdvbkJlZm9yZUludm9rZUhhbmRsZXInCiAgXTsKICByZXF1aXJlZEhhbmRsZXJzLmZvckVhY2goZnVuY3Rpb24obmV4dEhhbmRsZXIpIHsKICAgIGlmIChoYW5kbGVyc1tuZXh0SGFuZGxlcl0gPT09IHVuZGVmaW5lZCkgewogICAgICBjb25zb2xlLmVycm9yKG5leHRIYW5kbGVyICsgJyBoYW5kbGVyIG5vdCByZWdpc3RlcmVkLicpOwogICAgfQogIH0pOwp9CgovKioKICogU3RhcnRzIHF1ZXJ5aW5nIGZvciBzaW5rcyBjYXBhYmxlIG9mIGRpc3BsYXlpbmcgdGhlIG1lZGlhIHNvdXJjZQogKiBkZXNpZ25hdGVkIGJ5IHxzb3VyY2VVcm58LiAgUmVzdWx0cyBhcmUgcmV0dXJuZWQgYnkgY2FsbGluZwogKiBPblNpbmtzUmVjZWl2ZWQuCiAqIEBwYXJhbSB7IXN0cmluZ30gc291cmNlVXJuCiAqLwpNZWRpYVJvdXRlUHJvdmlkZXIucHJvdG90eXBlLnN0YXJ0T2JzZXJ2aW5nTWVkaWFTaW5rcyA9CiAgICBmdW5jdGlvbihzb3VyY2VVcm4pIHsKICB0aGlzLmhhbmRsZXJzXy5vbkJlZm9yZUludm9rZUhhbmRsZXIoKTsKICB0aGlzLmhhbmRsZXJzXy5zdGFydE9ic2VydmluZ01lZGlhU2lua3Moc291cmNlVXJuKTsKfTsKCi8qKgogKiBTdG9wcyBxdWVyeWluZyBmb3Igc2lua3MgY2FwYWJsZSBvZiBkaXNwbGF5aW5nIHxzb3VyY2VVcm58LgogKiBAcGFyYW0geyFzdHJpbmd9IHNvdXJjZVVybgogKi8KTWVkaWFSb3V0ZVByb3ZpZGVyLnByb3RvdHlwZS5zdG9wT2JzZXJ2aW5nTWVkaWFTaW5rcyA9CiAgICBmdW5jdGlvbihzb3VyY2VVcm4pIHsKICB0aGlzLmhhbmRsZXJzXy5vbkJlZm9yZUludm9rZUhhbmRsZXIoKTsKICB0aGlzLmhhbmRsZXJzXy5zdG9wT2JzZXJ2aW5nTWVkaWFTaW5rcyhzb3VyY2VVcm4pOwp9OwoKLyoqCiAqIFJlcXVlc3RzIHRoYXQgfHNpbmtJZHwgcmVuZGVyIHRoZSBtZWRpYSByZWZlcmVuY2VkIGJ5IHxzb3VyY2VVcm58LiBJZiB0aGUKICogcmVxdWVzdCBpcyBmcm9tIHRoZSBQcmVzZW50YXRpb24gQVBJLCB0aGVuIG9yaWdpbiBhbmQgdGFiSWQgd2lsbAogKiBiZSBwb3B1bGF0ZWQuCiAqIEBwYXJhbSB7IXN0cmluZ30gc291cmNlVXJuIE1lZGlhIHNvdXJjZSB0byByZW5kZXIuCiAqIEBwYXJhbSB7IXN0cmluZ30gc2lua0lkIE1lZGlhIHNpbmsgSUQuCiAqIEBwYXJhbSB7IXN0cmluZ30gcHJlc2VudGF0aW9uSWQgUHJlc2VudGF0aW9uIElEIGZyb20gdGhlIHNpdGUKICogICAgIHJlcXVlc3RpbmcgcHJlc2VudGF0aW9uLiBUT0RPKG1mb2x0eik6IFJlbW92ZS4KICogQHBhcmFtIHshdXJsLm1vam9tLk9yaWdpbn0gb3JpZ2luIE9yaWdpbiBvZiBzaXRlIHJlcXVlc3RpbmcgcHJlc2VudGF0aW9uLgogKiBAcGFyYW0geyFudW1iZXJ9IHRhYklkIElEIG9mIHRhYiByZXF1ZXN0aW5nIHByZXNlbnRhdGlvbi4KICogQHBhcmFtIHshbW9qby5jb21tb24ubW9qb20uVGltZURlbHRhfSB0aW1lb3V0IElmIHBvc2l0aXZlLCB0aGUgdGltZW91dAogKiAgICAgZHVyYXRpb24gZm9yIHRoZSByZXF1ZXN0LiBPdGhlcndpc2UsIHRoZSBkZWZhdWx0IGR1cmF0aW9uIHdpbGwgYmUgdXNlZC4KICogQHBhcmFtIHshYm9vbGVhbn0gaW5jb2duaXRvIElmIHRydWUsIHRoZSByb3V0ZSBpcyBiZWluZyByZXF1ZXN0ZWQgYnkKICogICAgIGFuIGluY29nbml0byBwcm9maWxlLgogKiBAcmV0dXJuIHshUHJvbWlzZS48IU9iamVjdD59IEEgUHJvbWlzZSByZXNvbHZpbmcgdG8gYW4gb2JqZWN0IGRlc2NyaWJpbmcKICogICAgIHRoZSBuZXdseSBjcmVhdGVkIG1lZGlhIHJvdXRlLCBvciByZWplY3Rpbmcgd2l0aCBhbiBlcnJvciBtZXNzYWdlIG9uCiAqICAgICBmYWlsdXJlLgogKi8KTWVkaWFSb3V0ZVByb3ZpZGVyLnByb3RvdHlwZS5jcmVhdGVSb3V0ZSA9CiAgICBmdW5jdGlvbihzb3VyY2VVcm4sIHNpbmtJZCwgcHJlc2VudGF0aW9uSWQsIG9yaWdpbiwgdGFiSWQsCiAgICAgICAgICAgICB0aW1lb3V0LCBpbmNvZ25pdG8pIHsKICB0aGlzLmhhbmRsZXJzXy5vbkJlZm9yZUludm9rZUhhbmRsZXIoKTsKICByZXR1cm4gdGhpcy5oYW5kbGVyc18uY3JlYXRlUm91dGUoCiAgICAgIHNvdXJjZVVybiwgc2lua0lkLCBwcmVzZW50YXRpb25JZCwgb3JpZ2luLCB0YWJJZCwKICAgICAgTWF0aC5mbG9vcih0aW1lb3V0Lm1pY3Jvc2Vjb25kcyAvIDEwMDApLCBpbmNvZ25pdG8pCiAgICAgIC50aGVuKGZ1bmN0aW9uKHJvdXRlKSB7CiAgICAgICAgcmV0dXJuIHRvU3VjY2Vzc1JvdXRlUmVzcG9uc2VfKHJvdXRlKTsKICAgICAgfSwKICAgICAgZnVuY3Rpb24oZXJyKSB7CiAgICAgICAgcmV0dXJuIHRvRXJyb3JSb3V0ZVJlc3BvbnNlXyhlcnIpOwogICAgICB9KTsKfTsKCi8qKgogKiBIYW5kbGVzIGEgcmVxdWVzdCB2aWEgdGhlIFByZXNlbnRhdGlvbiBBUEkgdG8gam9pbiBhbiBleGlzdGluZyByb3V0ZSBnaXZlbgogKiBieSB8c291cmNlVXJufCBhbmQgfHByZXNlbnRhdGlvbklkfC4gfG9yaWdpbnwgYW5kIHx0YWJJZHwgYXJlIHVzZWQgZm9yCiAqIHZhbGlkYXRpbmcgc2FtZS1vcmlnaW4vdGFiIHNjb3BlLgogKiBAcGFyYW0geyFzdHJpbmd9IHNvdXJjZVVybiBNZWRpYSBzb3VyY2UgdG8gcmVuZGVyLgogKiBAcGFyYW0geyFzdHJpbmd9IHByZXNlbnRhdGlvbklkIFByZXNlbnRhdGlvbiBJRCB0byBqb2luLgogKiBAcGFyYW0geyF1cmwubW9qb20uT3JpZ2lufSBvcmlnaW4gT3JpZ2luIG9mIHNpdGUgcmVxdWVzdGluZyBqb2luLgogKiBAcGFyYW0geyFudW1iZXJ9IHRhYklkIElEIG9mIHRhYiByZXF1ZXN0aW5nIGpvaW4uCiAqIEBwYXJhbSB7IW1vam8uY29tbW9uLm1vam9tLlRpbWVEZWx0YX0gdGltZW91dCBJZiBwb3NpdGl2ZSwgdGhlIHRpbWVvdXQKICogICAgIGR1cmF0aW9uIGZvciB0aGUgcmVxdWVzdC4gT3RoZXJ3aXNlLCB0aGUgZGVmYXVsdCBkdXJhdGlvbiB3aWxsIGJlIHVzZWQuCiAqIEBwYXJhbSB7IWJvb2xlYW59IGluY29nbml0byBJZiB0cnVlLCB0aGUgcm91dGUgaXMgYmVpbmcgcmVxdWVzdGVkIGJ5CiAqICAgICBhbiBpbmNvZ25pdG8gcHJvZmlsZS4KICogQHJldHVybiB7IVByb21pc2UuPCFPYmplY3Q+fSBBIFByb21pc2UgcmVzb2x2aW5nIHRvIGFuIG9iamVjdCBkZXNjcmliaW5nCiAqICAgICB0aGUgbmV3bHkgY3JlYXRlZCBtZWRpYSByb3V0ZSwgb3IgcmVqZWN0aW5nIHdpdGggYW4gZXJyb3IgbWVzc2FnZSBvbgogKiAgICAgZmFpbHVyZS4KICovCk1lZGlhUm91dGVQcm92aWRlci5wcm90b3R5cGUuam9pblJvdXRlID0KICAgIGZ1bmN0aW9uKHNvdXJjZVVybiwgcHJlc2VudGF0aW9uSWQsIG9yaWdpbiwgdGFiSWQsIHRpbWVvdXQsCiAgICAgICAgICAgICBpbmNvZ25pdG8pIHsKICB0aGlzLmhhbmRsZXJzXy5vbkJlZm9yZUludm9rZUhhbmRsZXIoKTsKICByZXR1cm4gdGhpcy5oYW5kbGVyc18uam9pblJvdXRlKAogICAgICBzb3VyY2VVcm4sIHByZXNlbnRhdGlvbklkLCBvcmlnaW4sIHRhYklkLAogICAgICBNYXRoLmZsb29yKHRpbWVvdXQubWljcm9zZWNvbmRzIC8gMTAwMCksIGluY29nbml0bykKICAgICAgLnRoZW4oZnVuY3Rpb24ocm91dGUpIHsKICAgICAgICByZXR1cm4gdG9TdWNjZXNzUm91dGVSZXNwb25zZV8ocm91dGUpOwogICAgICB9LAogICAgICBmdW5jdGlvbihlcnIpIHsKICAgICAgICByZXR1cm4gdG9FcnJvclJvdXRlUmVzcG9uc2VfKGVycik7CiAgICAgIH0pOwp9OwoKLyoqCiAqIEhhbmRsZXMgYSByZXF1ZXN0IHZpYSB0aGUgUHJlc2VudGF0aW9uIEFQSSB0byBqb2luIGFuIGV4aXN0aW5nIHJvdXRlIGdpdmVuCiAqIGJ5IHxzb3VyY2VVcm58IGFuZCB8cm91dGVJZHwuIHxvcmlnaW58IGFuZCB8dGFiSWR8IGFyZSB1c2VkIGZvcgogKiB2YWxpZGF0aW5nIHNhbWUtb3JpZ2luL3RhYiBzY29wZS4KICogQHBhcmFtIHshc3RyaW5nfSBzb3VyY2VVcm4gTWVkaWEgc291cmNlIHRvIHJlbmRlci4KICogQHBhcmFtIHshc3RyaW5nfSByb3V0ZUlkIFJvdXRlIElEIHRvIGpvaW4uCiAqIEBwYXJhbSB7IXN0cmluZ30gcHJlc2VudGF0aW9uSWQgUHJlc2VudGF0aW9uIElEIHRvIGpvaW4uCiAqIEBwYXJhbSB7IXVybC5tb2pvbS5PcmlnaW59IG9yaWdpbiBPcmlnaW4gb2Ygc2l0ZSByZXF1ZXN0aW5nIGpvaW4uCiAqIEBwYXJhbSB7IW51bWJlcn0gdGFiSWQgSUQgb2YgdGFiIHJlcXVlc3Rpbmcgam9pbi4KICogQHBhcmFtIHshbW9qby5jb21tb24ubW9qb20uVGltZURlbHRhfSB0aW1lb3V0IElmIHBvc2l0aXZlLCB0aGUgdGltZW91dAogKiAgICAgZHVyYXRpb24gZm9yIHRoZSByZXF1ZXN0LiBPdGhlcndpc2UsIHRoZSBkZWZhdWx0IGR1cmF0aW9uIHdpbGwgYmUgdXNlZC4KICogQHBhcmFtIHshYm9vbGVhbn0gaW5jb2duaXRvIElmIHRydWUsIHRoZSByb3V0ZSBpcyBiZWluZyByZXF1ZXN0ZWQgYnkKICogICAgIGFuIGluY29nbml0byBwcm9maWxlLgogKiBAcmV0dXJuIHshUHJvbWlzZS48IU9iamVjdD59IEEgUHJvbWlzZSByZXNvbHZpbmcgdG8gYW4gb2JqZWN0IGRlc2NyaWJpbmcKICogICAgIHRoZSBuZXdseSBjcmVhdGVkIG1lZGlhIHJvdXRlLCBvciByZWplY3Rpbmcgd2l0aCBhbiBlcnJvciBtZXNzYWdlIG9uCiAqICAgICBmYWlsdXJlLgogKi8KTWVkaWFSb3V0ZVByb3ZpZGVyLnByb3RvdHlwZS5jb25uZWN0Um91dGVCeVJvdXRlSWQgPQogICAgZnVuY3Rpb24oc291cmNlVXJuLCByb3V0ZUlkLCBwcmVzZW50YXRpb25JZCwgb3JpZ2luLCB0YWJJZCwKICAgICAgICAgICAgIHRpbWVvdXQsIGluY29nbml0bykgewogIHRoaXMuaGFuZGxlcnNfLm9uQmVmb3JlSW52b2tlSGFuZGxlcigpOwogIHJldHVybiB0aGlzLmhhbmRsZXJzXy5jb25uZWN0Um91dGVCeVJvdXRlSWQoCiAgICAgIHNvdXJjZVVybiwgcm91dGVJZCwgcHJlc2VudGF0aW9uSWQsIG9yaWdpbiwgdGFiSWQsCiAgICAgIE1hdGguZmxvb3IodGltZW91dC5taWNyb3NlY29uZHMgLyAxMDAwKSwgaW5jb2duaXRvKQogICAgICAudGhlbihmdW5jdGlvbihyb3V0ZSkgewogICAgICAgIHJldHVybiB0b1N1Y2Nlc3NSb3V0ZVJlc3BvbnNlXyhyb3V0ZSk7CiAgICAgIH0sCiAgICAgIGZ1bmN0aW9uKGVycikgewogICAgICAgIHJldHVybiB0b0Vycm9yUm91dGVSZXNwb25zZV8oZXJyKTsKICAgICAgfSk7Cn07CgovKioKICogVGVybWluYXRlcyB0aGUgcm91dGUgc3BlY2lmaWVkIGJ5IHxyb3V0ZUlkfC4KICogQHBhcmFtIHshc3RyaW5nfSByb3V0ZUlkCiAqIEByZXR1cm4geyFQcm9taXNlPCFPYmplY3Q+fSBBIFByb21pc2UgcmVzb2x2aW5nIHRvIGFuIG9iamVjdCBkZXNjcmliaW5nCiAqICAgIHRoZSByZXN1bHQgb2YgdGhlIHRlcm1pbmF0ZSBvcGVyYXRpb24sIG9yIHJlamVjdGluZyB3aXRoIGFuIGVycm9yCiAqICAgIG1lc3NhZ2UgYW5kIGNvZGUgaWYgdGhlIG9wZXJhdGlvbiBmYWlsZWQuCiAqLwpNZWRpYVJvdXRlUHJvdmlkZXIucHJvdG90eXBlLnRlcm1pbmF0ZVJvdXRlID0gZnVuY3Rpb24ocm91dGVJZCkgewogIHRoaXMuaGFuZGxlcnNfLm9uQmVmb3JlSW52b2tlSGFuZGxlcigpOwogIHJldHVybiB0aGlzLmhhbmRsZXJzXy50ZXJtaW5hdGVSb3V0ZShyb3V0ZUlkKS50aGVuKAogICAgICAoKSA9PiAoe3Jlc3VsdENvZGU6IG1lZGlhUm91dGVyLm1vam9tLlJvdXRlUmVxdWVzdFJlc3VsdENvZGUuT0t9KSwKICAgICAgKGVycikgPT4gdG9FcnJvclJvdXRlUmVzcG9uc2VfKGVycikpOwp9OwoKLyoqCiAqIFBvc3RzIGEgbWVzc2FnZSB0byB0aGUgcm91dGUgZGVzaWduYXRlZCBieSB8cm91dGVJZHwuCiAqIEBwYXJhbSB7IXN0cmluZ30gcm91dGVJZAogKiBAcGFyYW0geyFzdHJpbmd9IG1lc3NhZ2UKICogQHJldHVybiB7IVByb21pc2UuPGJvb2xlYW4+fSBSZXNvbHZlZCB3aXRoIHRydWUgaWYgdGhlIG1lc3NhZ2Ugd2FzIHNlbnQsCiAqICAgIG9yIGZhbHNlIG9uIGZhaWx1cmUuCiAqLwpNZWRpYVJvdXRlUHJvdmlkZXIucHJvdG90eXBlLnNlbmRSb3V0ZU1lc3NhZ2UgPSBmdW5jdGlvbigKICByb3V0ZUlkLCBtZXNzYWdlKSB7CiAgdGhpcy5oYW5kbGVyc18ub25CZWZvcmVJbnZva2VIYW5kbGVyKCk7CiAgcmV0dXJuIHRoaXMuaGFuZGxlcnNfLnNlbmRSb3V0ZU1lc3NhZ2Uocm91dGVJZCwgbWVzc2FnZSkKICAgICAgLnRoZW4oZnVuY3Rpb24oKSB7CiAgICAgICAgcmV0dXJuIHsnc2VudCc6IHRydWV9OwogICAgICB9LCBmdW5jdGlvbigpIHsKICAgICAgICByZXR1cm4geydzZW50JzogZmFsc2V9OwogICAgICB9KTsKfTsKCi8qKgogKiBTZW5kcyBhIGJpbmFyeSBtZXNzYWdlIHRvIHRoZSByb3V0ZSBkZXNpZ25hdGVkIGJ5IHxyb3V0ZUlkfC4KICogQHBhcmFtIHshc3RyaW5nfSByb3V0ZUlkCiAqIEBwYXJhbSB7IUFycmF5PG51bWJlcj59IGRhdGEKICogQHJldHVybiB7IVByb21pc2UuPGJvb2xlYW4+fSBSZXNvbHZlZCB3aXRoIHRydWUgaWYgdGhlIGRhdGEgd2FzIHNlbnQsCiAqICAgIG9yIGZhbHNlIG9uIGZhaWx1cmUuCiAqLwpNZWRpYVJvdXRlUHJvdmlkZXIucHJvdG90eXBlLnNlbmRSb3V0ZUJpbmFyeU1lc3NhZ2UgPSBmdW5jdGlvbigKICByb3V0ZUlkLCBkYXRhKSB7CiAgdGhpcy5oYW5kbGVyc18ub25CZWZvcmVJbnZva2VIYW5kbGVyKCk7CiAgcmV0dXJuIHRoaXMuaGFuZGxlcnNfLnNlbmRSb3V0ZUJpbmFyeU1lc3NhZ2Uocm91dGVJZCwgbmV3IFVpbnQ4QXJyYXkoZGF0YSkpCiAgICAgIC50aGVuKGZ1bmN0aW9uKCkgewogICAgICAgIHJldHVybiB7J3NlbnQnOiB0cnVlfTsKICAgICAgfSwgZnVuY3Rpb24oKSB7CiAgICAgICAgcmV0dXJuIHsnc2VudCc6IGZhbHNlfTsKICAgICAgfSk7Cn07CgovKioKICogTGlzdGVuIGZvciBtZXNzYWdlcyBmcm9tIGEgcm91dGUuCiAqIEBwYXJhbSB7IXN0cmluZ30gcm91dGVJZAogKi8KTWVkaWFSb3V0ZVByb3ZpZGVyLnByb3RvdHlwZS5zdGFydExpc3RlbmluZ0ZvclJvdXRlTWVzc2FnZXMgPSBmdW5jdGlvbigKICAgIHJvdXRlSWQpIHsKICB0aGlzLmhhbmRsZXJzXy5vbkJlZm9yZUludm9rZUhhbmRsZXIoKTsKICB0aGlzLmhhbmRsZXJzXy5zdGFydExpc3RlbmluZ0ZvclJvdXRlTWVzc2FnZXMocm91dGVJZCk7Cn07CgovKioKICogQHBhcmFtIHshc3RyaW5nfSByb3V0ZUlkCiAqLwpNZWRpYVJvdXRlUHJvdmlkZXIucHJvdG90eXBlLnN0b3BMaXN0ZW5pbmdGb3JSb3V0ZU1lc3NhZ2VzID0gZnVuY3Rpb24oCiAgICByb3V0ZUlkKSB7CiAgdGhpcy5oYW5kbGVyc18ub25CZWZvcmVJbnZva2VIYW5kbGVyKCk7CiAgdGhpcy5oYW5kbGVyc18uc3RvcExpc3RlbmluZ0ZvclJvdXRlTWVzc2FnZXMocm91dGVJZCk7Cn07CgovKioKICogSW5kaWNhdGVzIHRoYXQgdGhlIHByZXNlbnRhdGlvbiBjb25uZWN0aW9uIHRoYXQgd2FzIGNvbm5lY3RlZCB0byB8cm91dGVJZHwKICogaXMgbm8gbG9uZ2VyIGNvbm5lY3RlZCB0byBpdC4KICogQHBhcmFtIHshc3RyaW5nfSByb3V0ZUlkCiAqLwpNZWRpYVJvdXRlUHJvdmlkZXIucHJvdG90eXBlLmRldGFjaFJvdXRlID0gZnVuY3Rpb24oCiAgICByb3V0ZUlkKSB7CiAgdGhpcy5oYW5kbGVyc18uZGV0YWNoUm91dGUocm91dGVJZCk7Cn07CgovKioKICogUmVxdWVzdHMgdGhhdCB0aGUgcHJvdmlkZXIgbWFuYWdlciBzdGFydCBzZW5kaW5nIGluZm9ybWF0aW9uIGFib3V0IGFjdGl2ZQogKiBtZWRpYSByb3V0ZXMgdG8gdGhlIE1lZGlhIFJvdXRlci4KICogQHBhcmFtIHshc3RyaW5nfSBzb3VyY2VVcm4KICovCk1lZGlhUm91dGVQcm92aWRlci5wcm90b3R5cGUuc3RhcnRPYnNlcnZpbmdNZWRpYVJvdXRlcyA9IGZ1bmN0aW9uKHNvdXJjZVVybikgewogIHRoaXMuaGFuZGxlcnNfLm9uQmVmb3JlSW52b2tlSGFuZGxlcigpOwogIHRoaXMuaGFuZGxlcnNfLnN0YXJ0T2JzZXJ2aW5nTWVkaWFSb3V0ZXMoc291cmNlVXJuKTsKfTsKCi8qKgogKiBSZXF1ZXN0cyB0aGF0IHRoZSBwcm92aWRlciBtYW5hZ2VyIHN0b3Agc2VuZGluZyBpbmZvcm1hdGlvbiBhYm91dCBhY3RpdmUKICogbWVkaWEgcm91dGVzIHRvIHRoZSBNZWRpYSBSb3V0ZXIuCiAqIEBwYXJhbSB7IXN0cmluZ30gc291cmNlVXJuCiAqLwpNZWRpYVJvdXRlUHJvdmlkZXIucHJvdG90eXBlLnN0b3BPYnNlcnZpbmdNZWRpYVJvdXRlcyA9IGZ1bmN0aW9uKHNvdXJjZVVybikgewogIHRoaXMuaGFuZGxlcnNfLm9uQmVmb3JlSW52b2tlSGFuZGxlcigpOwogIHRoaXMuaGFuZGxlcnNfLnN0b3BPYnNlcnZpbmdNZWRpYVJvdXRlcyhzb3VyY2VVcm4pOwp9OwoKLyoqCiAqIEVuYWJsZXMgbUROUyBkZXZpY2UgZGlzY292ZXJ5LgogKi8KTWVkaWFSb3V0ZVByb3ZpZGVyLnByb3RvdHlwZS5lbmFibGVNZG5zRGlzY292ZXJ5ID0gZnVuY3Rpb24oKSB7CiAgdGhpcy5oYW5kbGVyc18ub25CZWZvcmVJbnZva2VIYW5kbGVyKCk7CiAgdGhpcy5oYW5kbGVyc18uZW5hYmxlTWRuc0Rpc2NvdmVyeSgpOwp9OwoKLyoqCiAqIFJlcXVlc3RzIHRoYXQgdGhlIHByb3ZpZGVyIG1hbmFnZXIgdXBkYXRlIG1lZGlhIHNpbmtzLgogKiBAcGFyYW0geyFzdHJpbmd9IHNvdXJjZVVybgogKi8KTWVkaWFSb3V0ZVByb3ZpZGVyLnByb3RvdHlwZS51cGRhdGVNZWRpYVNpbmtzID0gZnVuY3Rpb24oc291cmNlVXJuKSB7CiAgdGhpcy5oYW5kbGVyc18ub25CZWZvcmVJbnZva2VIYW5kbGVyKCk7CiAgdGhpcy5oYW5kbGVyc18udXBkYXRlTWVkaWFTaW5rcyhzb3VyY2VVcm4pOwp9OwoKLyoqCiAqIFJlcXVlc3RzIHRoYXQgdGhlIHByb3ZpZGVyIG1hbmFnZXIgc2VhcmNoIGl0cyBwcm92aWRlcnMgZm9yIGEgc2luayBtYXRjaGluZwogKiB8c2VhcmNoQ3JpdGVyaWF8IHRoYXQgaXMgY29tcGF0aWJsZSB3aXRoIHxzb3VyY2VVcm58LiBJZiBhIHNpbmsgaXMgZm91bmQKICogdGhhdCBjYW4gYmUgdXNlZCBpbW1lZGlhdGVseSBmb3Igcm91dGUgY3JlYXRpb24sIGl0cyBJRCBpcyByZXR1cm5lZC4KICogT3RoZXJ3aXNlIHRoZSBlbXB0eSBzdHJpbmcgaXMgcmV0dXJuZWQuCiAqCiAqIEBwYXJhbSB7c3RyaW5nfSBzaW5rSWQgU2luayBJRCBvZiB0aGUgcHNldWRvIHNpbmsgZ2VuZXJhdGluZyB0aGUgcmVxdWVzdC4KICogQHBhcmFtIHtzdHJpbmd9IHNvdXJjZVVybiBNZWRpYSBzb3VyY2UgdG8gYmUgdXNlZCB3aXRoIHRoZSBzaW5rLgogKiBAcGFyYW0geyFTaW5rU2VhcmNoQ3JpdGVyaWF9IHNlYXJjaENyaXRlcmlhIFNlYXJjaCBjcml0ZXJpYSBmb3IgdGhlIHJvdXRlCiAqICAgICBwcm92aWRlcnMuCiAqIEByZXR1cm4geyFQcm9taXNlLjwhe3NpbmtfaWQ6ICFzdHJpbmd9Pn0gQSBQcm9taXNlIHJlc29sdmluZyB0byBlaXRoZXIgdGhlCiAqICAgICBzaW5rIElEIG9mIHRoZSBzaW5rIGZvdW5kIGJ5IHRoZSBzZWFyY2ggdGhhdCBjYW4gYmUgdXNlZCBmb3Igcm91dGUKICogICAgIGNyZWF0aW9uLCBvciB0aGUgZW1wdHkgc3RyaW5nIGlmIG5vIHJvdXRlIGNhbiBiZSBpbW1lZGlhdGVseSBjcmVhdGVkLgogKi8KTWVkaWFSb3V0ZVByb3ZpZGVyLnByb3RvdHlwZS5zZWFyY2hTaW5rcyA9IGZ1bmN0aW9uKAogICAgc2lua0lkLCBzb3VyY2VVcm4sIHNlYXJjaENyaXRlcmlhKSB7CiAgdGhpcy5oYW5kbGVyc18ub25CZWZvcmVJbnZva2VIYW5kbGVyKCk7CiByZXR1cm4gdGhpcy5oYW5kbGVyc18uc2VhcmNoU2lua3Moc2lua0lkLCBzb3VyY2VVcm4sIHNlYXJjaENyaXRlcmlhKS50aGVuKAogICAgICBzaW5rSWQgPT4gewogICAgICAgIHJldHVybiB7ICdzaW5rSWQnOiBzaW5rSWQgfTsKICAgICAgfSwKICAgICAgKCkgPT4gewogICAgICAgIHJldHVybiB7ICdzaW5rSWQnOiAnJyB9OwogICAgICB9KTsKfTsKCi8qKgogKiBOb3RpZmllcyB0aGUgcHJvdmlkZXIgbWFuYWdlciB0aGF0IE1lZGlhUm91dGVyIGhhcyBkaXNjb3ZlcmVkIGEgbGlzdCBvZgogKiBzaW5rcy4KICogQHBhcmFtIHtzdHJpbmd9IHByb3ZpZGVyTmFtZQogKiBAcGFyYW0geyFBcnJheTwhbWVkaWFSb3V0ZXIubW9qb20uTWVkaWFTaW5rPn0gc2lua3MKICovCk1lZGlhUm91dGVQcm92aWRlci5wcm90b3R5cGUucHJvdmlkZVNpbmtzID0gZnVuY3Rpb24ocHJvdmlkZXJOYW1lLCBzaW5rcykgewogIHRoaXMuaGFuZGxlcnNfLm9uQmVmb3JlSW52b2tlSGFuZGxlcigpOwogIHRoaXMuaGFuZGxlcnNfLnByb3ZpZGVTaW5rcyhwcm92aWRlck5hbWUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNpbmtzLm1hcChNZWRpYVNpbmtBZGFwdGVyLmZyb21OZXdWZXJzaW9uKSk7Cn07CgovKioKICogQ3JlYXRlcyBhIGNvbnRyb2xsZXIgZm9yIHRoZSBnaXZlbiByb3V0ZSBhbmQgYmluZHMgdGhlIGdpdmVuCiAqIEludGVyZmFjZVJlcXVlc3QgdG8gaXQsIGFuZCByZWdpc3RlcnMgYW4gb2JzZXJ2ZXIgZm9yIG1lZGlhIHN0YXR1cyB1cGRhdGVzCiAqIGZvciB0aGUgcm91dGUuCiAqIEBwYXJhbSB7c3RyaW5nfSByb3V0ZUlkCiAqIEBwYXJhbSB7IW1vam8uSW50ZXJmYWNlUmVxdWVzdH0gY29udHJvbGxlclJlcXVlc3QKICogQHBhcmFtIHshbWVkaWFSb3V0ZXIubW9qb20uTWVkaWFTdGF0dXNPYnNlcnZlclB0cn0gb2JzZXJ2ZXIKICogQHJldHVybiB7IVByb21pc2U8IXtzdWNjZXNzOiBib29sZWFufT59IFJlc29sdmVzIHRvIHRydWUgaWYgYSBjb250cm9sbGVyCiAqICAgICBpcyBjcmVhdGVkLiBSZXNvbHZlcyB0byBmYWxzZSBpZiBhIGNvbnRyb2xsZXIgY2Fubm90IGJlIGNyZWF0ZWQsIG9yIGlmCiAqICAgICB0aGUgY29udHJvbGxlciBpcyBhbHJlYWR5IGJvdW5kLgogKi8KTWVkaWFSb3V0ZVByb3ZpZGVyLnByb3RvdHlwZS5jcmVhdGVNZWRpYVJvdXRlQ29udHJvbGxlciA9IGZ1bmN0aW9uKAogICAgcm91dGVJZCwgY29udHJvbGxlclJlcXVlc3QsIG9ic2VydmVyKSB7CiAgdGhpcy5oYW5kbGVyc18ub25CZWZvcmVJbnZva2VIYW5kbGVyKCk7CiAgcmV0dXJuIHRoaXMuaGFuZGxlcnNfLmNyZWF0ZU1lZGlhUm91dGVDb250cm9sbGVyKAogICAgICByb3V0ZUlkLCBjb250cm9sbGVyUmVxdWVzdCwKICAgICAgbmV3IE1lZGlhU3RhdHVzT2JzZXJ2ZXJQdHJBZGFwdGVyKG9ic2VydmVyLnB0ci5wYXNzSW50ZXJmYWNlKCkpKS50aGVuKAogICAgICAgICAgKCkgPT4gKHtzdWNjZXNzOiB0cnVlfSksIGUgPT4gKHtzdWNjZXNzOiBmYWxzZX0pKTsKfTsKCnZhciBwdHIgPSBuZXcgbWVkaWFSb3V0ZXIubW9qb20uTWVkaWFSb3V0ZXJQdHI7Ck1vam8uYmluZEludGVyZmFjZShtZWRpYVJvdXRlci5tb2pvbS5NZWRpYVJvdXRlci5uYW1lLAogICAgICAgICAgICAgICAgICAgbW9qby5tYWtlUmVxdWVzdChwdHIpLmhhbmRsZSk7CmV4cG9ydHMuJHNldCgncmV0dXJuVmFsdWUnLCBuZXcgTWVkaWFSb3V0ZXIocHRyKSk7Ci8vIENvcHlyaWdodCAyMDE0IFRoZSBDaHJvbWl1bSBBdXRob3JzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgovLyBVc2Ugb2YgdGhpcyBzb3VyY2UgY29kZSBpcyBnb3Zlcm5lZCBieSBhIEJTRC1zdHlsZSBsaWNlbnNlIHRoYXQgY2FuIGJlCi8vIGZvdW5kIGluIHRoZSBMSUNFTlNFIGZpbGUuCgondXNlIHN0cmljdCc7CgooZnVuY3Rpb24oKSB7CiAgdmFyIG1vam9tSWQgPSAnY2hyb21lL2NvbW1vbi9tZWRpYV9yb3V0ZXIvbW9qby9tZWRpYV9zdGF0dXMubW9qb20nOwogIGlmIChtb2pvLmludGVybmFsLmlzTW9qb21Mb2FkZWQobW9qb21JZCkpIHsKICAgIGNvbnNvbGUud2FybignVGhlIGZvbGxvd2luZyBtb2pvbSBpcyBsb2FkZWQgbXVsdGlwbGUgdGltZXM6ICcgKyBtb2pvbUlkKTsKICAgIHJldHVybjsKICB9CiAgbW9qby5pbnRlcm5hbC5tYXJrTW9qb21Mb2FkZWQobW9qb21JZCk7CiAgdmFyIGJpbmRpbmdzID0gbW9qbzsKICB2YXIgYXNzb2NpYXRlZEJpbmRpbmdzID0gbW9qbzsKICB2YXIgY29kZWMgPSBtb2pvLmludGVybmFsOwogIHZhciB2YWxpZGF0b3IgPSBtb2pvLmludGVybmFsOwoKICB2YXIgZXhwb3J0cyA9IG1vam8uaW50ZXJuYWwuZXhwb3NlTmFtZXNwYWNlKCdtZWRpYVJvdXRlci5tb2pvbScpOwogIHZhciB0aW1lJCA9CiAgICAgIG1vam8uaW50ZXJuYWwuZXhwb3NlTmFtZXNwYWNlKCdtb2pvLmNvbW1vbi5tb2pvbScpOwogIGlmIChtb2pvLmNvbmZpZy5hdXRvTG9hZE1vam9tRGVwcykgewogICAgbW9qby5pbnRlcm5hbC5sb2FkTW9qb21JZk5lY2Vzc2FyeSgKICAgICAgICAnbW9qby9jb21tb24vdGltZS5tb2pvbScsICcuLi8uLi8uLi8uLi9tb2pvL2NvbW1vbi90aW1lLm1vam9tLmpzJyk7CiAgfQoKCgogIGZ1bmN0aW9uIE1lZGlhU3RhdHVzKHZhbHVlcykgewogICAgdGhpcy5pbml0RGVmYXVsdHNfKCk7CiAgICB0aGlzLmluaXRGaWVsZHNfKHZhbHVlcyk7CiAgfQoKICBNZWRpYVN0YXR1cy5QbGF5U3RhdGUgPSB7fTsKICBNZWRpYVN0YXR1cy5QbGF5U3RhdGUuUExBWUlORyA9IDA7CiAgTWVkaWFTdGF0dXMuUGxheVN0YXRlLlBBVVNFRCA9IE1lZGlhU3RhdHVzLlBsYXlTdGF0ZS5QTEFZSU5HICsgMTsKICBNZWRpYVN0YXR1cy5QbGF5U3RhdGUuQlVGRkVSSU5HID0gTWVkaWFTdGF0dXMuUGxheVN0YXRlLlBBVVNFRCArIDE7CgogIE1lZGlhU3RhdHVzLlBsYXlTdGF0ZS5pc0tub3duRW51bVZhbHVlID0gZnVuY3Rpb24odmFsdWUpIHsKICAgIHN3aXRjaCAodmFsdWUpIHsKICAgIGNhc2UgMDoKICAgIGNhc2UgMToKICAgIGNhc2UgMjoKICAgICAgcmV0dXJuIHRydWU7CiAgICB9CiAgICByZXR1cm4gZmFsc2U7CiAgfTsKCiAgTWVkaWFTdGF0dXMuUGxheVN0YXRlLnZhbGlkYXRlID0gZnVuY3Rpb24oZW51bVZhbHVlKSB7CiAgICB2YXIgaXNFeHRlbnNpYmxlID0gZmFsc2U7CiAgICBpZiAoaXNFeHRlbnNpYmxlIHx8IHRoaXMuaXNLbm93bkVudW1WYWx1ZShlbnVtVmFsdWUpKQogICAgICByZXR1cm4gdmFsaWRhdG9yLnZhbGlkYXRpb25FcnJvci5OT05FOwoKICAgIHJldHVybiB2YWxpZGF0b3IudmFsaWRhdGlvbkVycm9yLlVOS05PV05fRU5VTV9WQUxVRTsKICB9OwoKICBNZWRpYVN0YXR1cy5wcm90b3R5cGUuaW5pdERlZmF1bHRzXyA9IGZ1bmN0aW9uKCkgewogICAgdGhpcy50aXRsZSA9IG51bGw7CiAgICB0aGlzLmRlc2NyaXB0aW9uID0gbnVsbDsKICAgIHRoaXMuY2FuUGxheVBhdXNlID0gZmFsc2U7CiAgICB0aGlzLmNhbk11dGUgPSBmYWxzZTsKICAgIHRoaXMuY2FuU2V0Vm9sdW1lID0gZmFsc2U7CiAgICB0aGlzLmNhblNlZWsgPSBmYWxzZTsKICAgIHRoaXMuaXNNdXRlZCA9IGZhbHNlOwogICAgdGhpcy5wbGF5U3RhdGUgPSAwOwogICAgdGhpcy52b2x1bWUgPSAwOwogICAgdGhpcy5kdXJhdGlvbiA9IG51bGw7CiAgICB0aGlzLmN1cnJlbnRUaW1lID0gbnVsbDsKICAgIHRoaXMuaGFuZ291dHNFeHRyYURhdGEgPSBudWxsOwogIH07CiAgTWVkaWFTdGF0dXMucHJvdG90eXBlLmluaXRGaWVsZHNfID0gZnVuY3Rpb24oZmllbGRzKSB7CiAgICBmb3IodmFyIGZpZWxkIGluIGZpZWxkcykgewogICAgICAgIGlmICh0aGlzLmhhc093blByb3BlcnR5KGZpZWxkKSkKICAgICAgICAgIHRoaXNbZmllbGRdID0gZmllbGRzW2ZpZWxkXTsKICAgIH0KICB9OwoKICBNZWRpYVN0YXR1cy52YWxpZGF0ZSA9IGZ1bmN0aW9uKG1lc3NhZ2VWYWxpZGF0b3IsIG9mZnNldCkgewogICAgdmFyIGVycjsKICAgIGVyciA9IG1lc3NhZ2VWYWxpZGF0b3IudmFsaWRhdGVTdHJ1Y3RIZWFkZXIob2Zmc2V0LCBjb2RlYy5rU3RydWN0SGVhZGVyU2l6ZSk7CiAgICBpZiAoZXJyICE9PSB2YWxpZGF0b3IudmFsaWRhdGlvbkVycm9yLk5PTkUpCiAgICAgICAgcmV0dXJuIGVycjsKCiAgICB2YXIga1ZlcnNpb25TaXplcyA9IFsKICAgICAge3ZlcnNpb246IDAsIG51bUJ5dGVzOiA2NH0KICAgIF07CiAgICBlcnIgPSBtZXNzYWdlVmFsaWRhdG9yLnZhbGlkYXRlU3RydWN0VmVyc2lvbihvZmZzZXQsIGtWZXJzaW9uU2l6ZXMpOwogICAgaWYgKGVyciAhPT0gdmFsaWRhdG9yLnZhbGlkYXRpb25FcnJvci5OT05FKQogICAgICAgIHJldHVybiBlcnI7CgoKICAgIC8vIHZhbGlkYXRlIE1lZGlhU3RhdHVzLnRpdGxlCiAgICBlcnIgPSBtZXNzYWdlVmFsaWRhdG9yLnZhbGlkYXRlU3RyaW5nUG9pbnRlcihvZmZzZXQgKyBjb2RlYy5rU3RydWN0SGVhZGVyU2l6ZSArIDAsIGZhbHNlKQogICAgaWYgKGVyciAhPT0gdmFsaWRhdG9yLnZhbGlkYXRpb25FcnJvci5OT05FKQogICAgICAgIHJldHVybiBlcnI7CgoKICAgIC8vIHZhbGlkYXRlIE1lZGlhU3RhdHVzLmRlc2NyaXB0aW9uCiAgICBlcnIgPSBtZXNzYWdlVmFsaWRhdG9yLnZhbGlkYXRlU3RyaW5nUG9pbnRlcihvZmZzZXQgKyBjb2RlYy5rU3RydWN0SGVhZGVyU2l6ZSArIDgsIGZhbHNlKQogICAgaWYgKGVyciAhPT0gdmFsaWRhdG9yLnZhbGlkYXRpb25FcnJvci5OT05FKQogICAgICAgIHJldHVybiBlcnI7CgoKCgoKCiAgICAvLyB2YWxpZGF0ZSBNZWRpYVN0YXR1cy5wbGF5U3RhdGUKICAgIGVyciA9IG1lc3NhZ2VWYWxpZGF0b3IudmFsaWRhdGVFbnVtKG9mZnNldCArIGNvZGVjLmtTdHJ1Y3RIZWFkZXJTaXplICsgMjAsIE1lZGlhU3RhdHVzLlBsYXlTdGF0ZSk7CiAgICBpZiAoZXJyICE9PSB2YWxpZGF0b3IudmFsaWRhdGlvbkVycm9yLk5PTkUpCiAgICAgICAgcmV0dXJuIGVycjsKCgoKCiAgICAvLyB2YWxpZGF0ZSBNZWRpYVN0YXR1cy5kdXJhdGlvbgogICAgZXJyID0gbWVzc2FnZVZhbGlkYXRvci52YWxpZGF0ZVN0cnVjdFBvaW50ZXIob2Zmc2V0ICsgY29kZWMua1N0cnVjdEhlYWRlclNpemUgKyAzMiwgdGltZSQuVGltZURlbHRhLCBmYWxzZSk7CiAgICBpZiAoZXJyICE9PSB2YWxpZGF0b3IudmFsaWRhdGlvbkVycm9yLk5PTkUpCiAgICAgICAgcmV0dXJuIGVycjsKCgogICAgLy8gdmFsaWRhdGUgTWVkaWFTdGF0dXMuY3VycmVudFRpbWUKICAgIGVyciA9IG1lc3NhZ2VWYWxpZGF0b3IudmFsaWRhdGVTdHJ1Y3RQb2ludGVyKG9mZnNldCArIGNvZGVjLmtTdHJ1Y3RIZWFkZXJTaXplICsgNDAsIHRpbWUkLlRpbWVEZWx0YSwgZmFsc2UpOwogICAgaWYgKGVyciAhPT0gdmFsaWRhdG9yLnZhbGlkYXRpb25FcnJvci5OT05FKQogICAgICAgIHJldHVybiBlcnI7CgoKICAgIC8vIHZhbGlkYXRlIE1lZGlhU3RhdHVzLmhhbmdvdXRzRXh0cmFEYXRhCiAgICBlcnIgPSBtZXNzYWdlVmFsaWRhdG9yLnZhbGlkYXRlU3RydWN0UG9pbnRlcihvZmZzZXQgKyBjb2RlYy5rU3RydWN0SGVhZGVyU2l6ZSArIDQ4LCBIYW5nb3V0c01lZGlhU3RhdHVzRXh0cmFEYXRhLCB0cnVlKTsKICAgIGlmIChlcnIgIT09IHZhbGlkYXRvci52YWxpZGF0aW9uRXJyb3IuTk9ORSkKICAgICAgICByZXR1cm4gZXJyOwoKICAgIHJldHVybiB2YWxpZGF0b3IudmFsaWRhdGlvbkVycm9yLk5PTkU7CiAgfTsKCiAgTWVkaWFTdGF0dXMuZW5jb2RlZFNpemUgPSBjb2RlYy5rU3RydWN0SGVhZGVyU2l6ZSArIDU2OwoKICBNZWRpYVN0YXR1cy5kZWNvZGUgPSBmdW5jdGlvbihkZWNvZGVyKSB7CiAgICB2YXIgcGFja2VkOwogICAgdmFyIHZhbCA9IG5ldyBNZWRpYVN0YXR1cygpOwogICAgdmFyIG51bWJlck9mQnl0ZXMgPSBkZWNvZGVyLnJlYWRVaW50MzIoKTsKICAgIHZhciB2ZXJzaW9uID0gZGVjb2Rlci5yZWFkVWludDMyKCk7CiAgICB2YWwudGl0bGUgPSBkZWNvZGVyLmRlY29kZVN0cnVjdChjb2RlYy5TdHJpbmcpOwogICAgdmFsLmRlc2NyaXB0aW9uID0gZGVjb2Rlci5kZWNvZGVTdHJ1Y3QoY29kZWMuU3RyaW5nKTsKICAgIHBhY2tlZCA9IGRlY29kZXIucmVhZFVpbnQ4KCk7CiAgICB2YWwuY2FuUGxheVBhdXNlID0gKHBhY2tlZCA+PiAwKSAmIDEgPyB0cnVlIDogZmFsc2U7CiAgICB2YWwuY2FuTXV0ZSA9IChwYWNrZWQgPj4gMSkgJiAxID8gdHJ1ZSA6IGZhbHNlOwogICAgdmFsLmNhblNldFZvbHVtZSA9IChwYWNrZWQgPj4gMikgJiAxID8gdHJ1ZSA6IGZhbHNlOwogICAgdmFsLmNhblNlZWsgPSAocGFja2VkID4+IDMpICYgMSA/IHRydWUgOiBmYWxzZTsKICAgIHZhbC5pc011dGVkID0gKHBhY2tlZCA+PiA0KSAmIDEgPyB0cnVlIDogZmFsc2U7CiAgICBkZWNvZGVyLnNraXAoMSk7CiAgICBkZWNvZGVyLnNraXAoMSk7CiAgICBkZWNvZGVyLnNraXAoMSk7CiAgICB2YWwucGxheVN0YXRlID0gZGVjb2Rlci5kZWNvZGVTdHJ1Y3QoY29kZWMuSW50MzIpOwogICAgdmFsLnZvbHVtZSA9IGRlY29kZXIuZGVjb2RlU3RydWN0KGNvZGVjLkZsb2F0KTsKICAgIGRlY29kZXIuc2tpcCgxKTsKICAgIGRlY29kZXIuc2tpcCgxKTsKICAgIGRlY29kZXIuc2tpcCgxKTsKICAgIGRlY29kZXIuc2tpcCgxKTsKICAgIHZhbC5kdXJhdGlvbiA9IGRlY29kZXIuZGVjb2RlU3RydWN0UG9pbnRlcih0aW1lJC5UaW1lRGVsdGEpOwogICAgdmFsLmN1cnJlbnRUaW1lID0gZGVjb2Rlci5kZWNvZGVTdHJ1Y3RQb2ludGVyKHRpbWUkLlRpbWVEZWx0YSk7CiAgICB2YWwuaGFuZ291dHNFeHRyYURhdGEgPSBkZWNvZGVyLmRlY29kZVN0cnVjdFBvaW50ZXIoSGFuZ291dHNNZWRpYVN0YXR1c0V4dHJhRGF0YSk7CiAgICByZXR1cm4gdmFsOwogIH07CgogIE1lZGlhU3RhdHVzLmVuY29kZSA9IGZ1bmN0aW9uKGVuY29kZXIsIHZhbCkgewogICAgdmFyIHBhY2tlZDsKICAgIGVuY29kZXIud3JpdGVVaW50MzIoTWVkaWFTdGF0dXMuZW5jb2RlZFNpemUpOwogICAgZW5jb2Rlci53cml0ZVVpbnQzMigwKTsKICAgIGVuY29kZXIuZW5jb2RlU3RydWN0KGNvZGVjLlN0cmluZywgdmFsLnRpdGxlKTsKICAgIGVuY29kZXIuZW5jb2RlU3RydWN0KGNvZGVjLlN0cmluZywgdmFsLmRlc2NyaXB0aW9uKTsKICAgIHBhY2tlZCA9IDA7CiAgICBwYWNrZWQgfD0gKHZhbC5jYW5QbGF5UGF1c2UgJiAxKSA8PCAwCiAgICBwYWNrZWQgfD0gKHZhbC5jYW5NdXRlICYgMSkgPDwgMQogICAgcGFja2VkIHw9ICh2YWwuY2FuU2V0Vm9sdW1lICYgMSkgPDwgMgogICAgcGFja2VkIHw9ICh2YWwuY2FuU2VlayAmIDEpIDw8IDMKICAgIHBhY2tlZCB8PSAodmFsLmlzTXV0ZWQgJiAxKSA8PCA0CiAgICBlbmNvZGVyLndyaXRlVWludDgocGFja2VkKTsKICAgIGVuY29kZXIuc2tpcCgxKTsKICAgIGVuY29kZXIuc2tpcCgxKTsKICAgIGVuY29kZXIuc2tpcCgxKTsKICAgIGVuY29kZXIuZW5jb2RlU3RydWN0KGNvZGVjLkludDMyLCB2YWwucGxheVN0YXRlKTsKICAgIGVuY29kZXIuZW5jb2RlU3RydWN0KGNvZGVjLkZsb2F0LCB2YWwudm9sdW1lKTsKICAgIGVuY29kZXIuc2tpcCgxKTsKICAgIGVuY29kZXIuc2tpcCgxKTsKICAgIGVuY29kZXIuc2tpcCgxKTsKICAgIGVuY29kZXIuc2tpcCgxKTsKICAgIGVuY29kZXIuZW5jb2RlU3RydWN0UG9pbnRlcih0aW1lJC5UaW1lRGVsdGEsIHZhbC5kdXJhdGlvbik7CiAgICBlbmNvZGVyLmVuY29kZVN0cnVjdFBvaW50ZXIodGltZSQuVGltZURlbHRhLCB2YWwuY3VycmVudFRpbWUpOwogICAgZW5jb2Rlci5lbmNvZGVTdHJ1Y3RQb2ludGVyKEhhbmdvdXRzTWVkaWFTdGF0dXNFeHRyYURhdGEsIHZhbC5oYW5nb3V0c0V4dHJhRGF0YSk7CiAgfTsKICBmdW5jdGlvbiBIYW5nb3V0c01lZGlhU3RhdHVzRXh0cmFEYXRhKHZhbHVlcykgewogICAgdGhpcy5pbml0RGVmYXVsdHNfKCk7CiAgICB0aGlzLmluaXRGaWVsZHNfKHZhbHVlcyk7CiAgfQoKCiAgSGFuZ291dHNNZWRpYVN0YXR1c0V4dHJhRGF0YS5wcm90b3R5cGUuaW5pdERlZmF1bHRzXyA9IGZ1bmN0aW9uKCkgewogICAgdGhpcy5sb2NhbFByZXNlbnQgPSBmYWxzZTsKICB9OwogIEhhbmdvdXRzTWVkaWFTdGF0dXNFeHRyYURhdGEucHJvdG90eXBlLmluaXRGaWVsZHNfID0gZnVuY3Rpb24oZmllbGRzKSB7CiAgICBmb3IodmFyIGZpZWxkIGluIGZpZWxkcykgewogICAgICAgIGlmICh0aGlzLmhhc093blByb3BlcnR5KGZpZWxkKSkKICAgICAgICAgIHRoaXNbZmllbGRdID0gZmllbGRzW2ZpZWxkXTsKICAgIH0KICB9OwoKICBIYW5nb3V0c01lZGlhU3RhdHVzRXh0cmFEYXRhLnZhbGlkYXRlID0gZnVuY3Rpb24obWVzc2FnZVZhbGlkYXRvciwgb2Zmc2V0KSB7CiAgICB2YXIgZXJyOwogICAgZXJyID0gbWVzc2FnZVZhbGlkYXRvci52YWxpZGF0ZVN0cnVjdEhlYWRlcihvZmZzZXQsIGNvZGVjLmtTdHJ1Y3RIZWFkZXJTaXplKTsKICAgIGlmIChlcnIgIT09IHZhbGlkYXRvci52YWxpZGF0aW9uRXJyb3IuTk9ORSkKICAgICAgICByZXR1cm4gZXJyOwoKICAgIHZhciBrVmVyc2lvblNpemVzID0gWwogICAgICB7dmVyc2lvbjogMCwgbnVtQnl0ZXM6IDE2fQogICAgXTsKICAgIGVyciA9IG1lc3NhZ2VWYWxpZGF0b3IudmFsaWRhdGVTdHJ1Y3RWZXJzaW9uKG9mZnNldCwga1ZlcnNpb25TaXplcyk7CiAgICBpZiAoZXJyICE9PSB2YWxpZGF0b3IudmFsaWRhdGlvbkVycm9yLk5PTkUpCiAgICAgICAgcmV0dXJuIGVycjsKCgogICAgcmV0dXJuIHZhbGlkYXRvci52YWxpZGF0aW9uRXJyb3IuTk9ORTsKICB9OwoKICBIYW5nb3V0c01lZGlhU3RhdHVzRXh0cmFEYXRhLmVuY29kZWRTaXplID0gY29kZWMua1N0cnVjdEhlYWRlclNpemUgKyA4OwoKICBIYW5nb3V0c01lZGlhU3RhdHVzRXh0cmFEYXRhLmRlY29kZSA9IGZ1bmN0aW9uKGRlY29kZXIpIHsKICAgIHZhciBwYWNrZWQ7CiAgICB2YXIgdmFsID0gbmV3IEhhbmdvdXRzTWVkaWFTdGF0dXNFeHRyYURhdGEoKTsKICAgIHZhciBudW1iZXJPZkJ5dGVzID0gZGVjb2Rlci5yZWFkVWludDMyKCk7CiAgICB2YXIgdmVyc2lvbiA9IGRlY29kZXIucmVhZFVpbnQzMigpOwogICAgcGFja2VkID0gZGVjb2Rlci5yZWFkVWludDgoKTsKICAgIHZhbC5sb2NhbFByZXNlbnQgPSAocGFja2VkID4+IDApICYgMSA/IHRydWUgOiBmYWxzZTsKICAgIGRlY29kZXIuc2tpcCgxKTsKICAgIGRlY29kZXIuc2tpcCgxKTsKICAgIGRlY29kZXIuc2tpcCgxKTsKICAgIGRlY29kZXIuc2tpcCgxKTsKICAgIGRlY29kZXIuc2tpcCgxKTsKICAgIGRlY29kZXIuc2tpcCgxKTsKICAgIGRlY29kZXIuc2tpcCgxKTsKICAgIHJldHVybiB2YWw7CiAgfTsKCiAgSGFuZ291dHNNZWRpYVN0YXR1c0V4dHJhRGF0YS5lbmNvZGUgPSBmdW5jdGlvbihlbmNvZGVyLCB2YWwpIHsKICAgIHZhciBwYWNrZWQ7CiAgICBlbmNvZGVyLndyaXRlVWludDMyKEhhbmdvdXRzTWVkaWFTdGF0dXNFeHRyYURhdGEuZW5jb2RlZFNpemUpOwogICAgZW5jb2Rlci53cml0ZVVpbnQzMigwKTsKICAgIHBhY2tlZCA9IDA7CiAgICBwYWNrZWQgfD0gKHZhbC5sb2NhbFByZXNlbnQgJiAxKSA8PCAwCiAgICBlbmNvZGVyLndyaXRlVWludDgocGFja2VkKTsKICAgIGVuY29kZXIuc2tpcCgxKTsKICAgIGVuY29kZXIuc2tpcCgxKTsKICAgIGVuY29kZXIuc2tpcCgxKTsKICAgIGVuY29kZXIuc2tpcCgxKTsKICAgIGVuY29kZXIuc2tpcCgxKTsKICAgIGVuY29kZXIuc2tpcCgxKTsKICAgIGVuY29kZXIuc2tpcCgxKTsKICB9OwogIGZ1bmN0aW9uIE1lZGlhU3RhdHVzT2JzZXJ2ZXJfT25NZWRpYVN0YXR1c1VwZGF0ZWRfUGFyYW1zKHZhbHVlcykgewogICAgdGhpcy5pbml0RGVmYXVsdHNfKCk7CiAgICB0aGlzLmluaXRGaWVsZHNfKHZhbHVlcyk7CiAgfQoKCiAgTWVkaWFTdGF0dXNPYnNlcnZlcl9Pbk1lZGlhU3RhdHVzVXBkYXRlZF9QYXJhbXMucHJvdG90eXBlLmluaXREZWZhdWx0c18gPSBmdW5jdGlvbigpIHsKICAgIHRoaXMuc3RhdHVzID0gbnVsbDsKICB9OwogIE1lZGlhU3RhdHVzT2JzZXJ2ZXJfT25NZWRpYVN0YXR1c1VwZGF0ZWRfUGFyYW1zLnByb3RvdHlwZS5pbml0RmllbGRzXyA9IGZ1bmN0aW9uKGZpZWxkcykgewogICAgZm9yKHZhciBmaWVsZCBpbiBmaWVsZHMpIHsKICAgICAgICBpZiAodGhpcy5oYXNPd25Qcm9wZXJ0eShmaWVsZCkpCiAgICAgICAgICB0aGlzW2ZpZWxkXSA9IGZpZWxkc1tmaWVsZF07CiAgICB9CiAgfTsKCiAgTWVkaWFTdGF0dXNPYnNlcnZlcl9Pbk1lZGlhU3RhdHVzVXBkYXRlZF9QYXJhbXMudmFsaWRhdGUgPSBmdW5jdGlvbihtZXNzYWdlVmFsaWRhdG9yLCBvZmZzZXQpIHsKICAgIHZhciBlcnI7CiAgICBlcnIgPSBtZXNzYWdlVmFsaWRhdG9yLnZhbGlkYXRlU3RydWN0SGVhZGVyKG9mZnNldCwgY29kZWMua1N0cnVjdEhlYWRlclNpemUpOwogICAgaWYgKGVyciAhPT0gdmFsaWRhdG9yLnZhbGlkYXRpb25FcnJvci5OT05FKQogICAgICAgIHJldHVybiBlcnI7CgogICAgdmFyIGtWZXJzaW9uU2l6ZXMgPSBbCiAgICAgIHt2ZXJzaW9uOiAwLCBudW1CeXRlczogMTZ9CiAgICBdOwogICAgZXJyID0gbWVzc2FnZVZhbGlkYXRvci52YWxpZGF0ZVN0cnVjdFZlcnNpb24ob2Zmc2V0LCBrVmVyc2lvblNpemVzKTsKICAgIGlmIChlcnIgIT09IHZhbGlkYXRvci52YWxpZGF0aW9uRXJyb3IuTk9ORSkKICAgICAgICByZXR1cm4gZXJyOwoKCiAgICAvLyB2YWxpZGF0ZSBNZWRpYVN0YXR1c09ic2VydmVyX09uTWVkaWFTdGF0dXNVcGRhdGVkX1BhcmFtcy5zdGF0dXMKICAgIGVyciA9IG1lc3NhZ2VWYWxpZGF0b3IudmFsaWRhdGVTdHJ1Y3RQb2ludGVyKG9mZnNldCArIGNvZGVjLmtTdHJ1Y3RIZWFkZXJTaXplICsgMCwgTWVkaWFTdGF0dXMsIGZhbHNlKTsKICAgIGlmIChlcnIgIT09IHZhbGlkYXRvci52YWxpZGF0aW9uRXJyb3IuTk9ORSkKICAgICAgICByZXR1cm4gZXJyOwoKICAgIHJldHVybiB2YWxpZGF0b3IudmFsaWRhdGlvbkVycm9yLk5PTkU7CiAgfTsKCiAgTWVkaWFTdGF0dXNPYnNlcnZlcl9Pbk1lZGlhU3RhdHVzVXBkYXRlZF9QYXJhbXMuZW5jb2RlZFNpemUgPSBjb2RlYy5rU3RydWN0SGVhZGVyU2l6ZSArIDg7CgogIE1lZGlhU3RhdHVzT2JzZXJ2ZXJfT25NZWRpYVN0YXR1c1VwZGF0ZWRfUGFyYW1zLmRlY29kZSA9IGZ1bmN0aW9uKGRlY29kZXIpIHsKICAgIHZhciBwYWNrZWQ7CiAgICB2YXIgdmFsID0gbmV3IE1lZGlhU3RhdHVzT2JzZXJ2ZXJfT25NZWRpYVN0YXR1c1VwZGF0ZWRfUGFyYW1zKCk7CiAgICB2YXIgbnVtYmVyT2ZCeXRlcyA9IGRlY29kZXIucmVhZFVpbnQzMigpOwogICAgdmFyIHZlcnNpb24gPSBkZWNvZGVyLnJlYWRVaW50MzIoKTsKICAgIHZhbC5zdGF0dXMgPSBkZWNvZGVyLmRlY29kZVN0cnVjdFBvaW50ZXIoTWVkaWFTdGF0dXMpOwogICAgcmV0dXJuIHZhbDsKICB9OwoKICBNZWRpYVN0YXR1c09ic2VydmVyX09uTWVkaWFTdGF0dXNVcGRhdGVkX1BhcmFtcy5lbmNvZGUgPSBmdW5jdGlvbihlbmNvZGVyLCB2YWwpIHsKICAgIHZhciBwYWNrZWQ7CiAgICBlbmNvZGVyLndyaXRlVWludDMyKE1lZGlhU3RhdHVzT2JzZXJ2ZXJfT25NZWRpYVN0YXR1c1VwZGF0ZWRfUGFyYW1zLmVuY29kZWRTaXplKTsKICAgIGVuY29kZXIud3JpdGVVaW50MzIoMCk7CiAgICBlbmNvZGVyLmVuY29kZVN0cnVjdFBvaW50ZXIoTWVkaWFTdGF0dXMsIHZhbC5zdGF0dXMpOwogIH07CiAgdmFyIGtNZWRpYVN0YXR1c09ic2VydmVyX09uTWVkaWFTdGF0dXNVcGRhdGVkX05hbWUgPSAxMjUzMDIwNzI5OwoKICBmdW5jdGlvbiBNZWRpYVN0YXR1c09ic2VydmVyUHRyKGhhbmRsZU9yUHRySW5mbykgewogICAgdGhpcy5wdHIgPSBuZXcgYmluZGluZ3MuSW50ZXJmYWNlUHRyQ29udHJvbGxlcihNZWRpYVN0YXR1c09ic2VydmVyLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBoYW5kbGVPclB0ckluZm8pOwogIH0KCiAgZnVuY3Rpb24gTWVkaWFTdGF0dXNPYnNlcnZlckFzc29jaWF0ZWRQdHIoYXNzb2NpYXRlZEludGVyZmFjZVB0ckluZm8pIHsKICAgIHRoaXMucHRyID0gbmV3IGFzc29jaWF0ZWRCaW5kaW5ncy5Bc3NvY2lhdGVkSW50ZXJmYWNlUHRyQ29udHJvbGxlcigKICAgICAgICBNZWRpYVN0YXR1c09ic2VydmVyLCBhc3NvY2lhdGVkSW50ZXJmYWNlUHRySW5mbyk7CiAgfQoKICBNZWRpYVN0YXR1c09ic2VydmVyQXNzb2NpYXRlZFB0ci5wcm90b3R5cGUgPQogICAgICBPYmplY3QuY3JlYXRlKE1lZGlhU3RhdHVzT2JzZXJ2ZXJQdHIucHJvdG90eXBlKTsKICBNZWRpYVN0YXR1c09ic2VydmVyQXNzb2NpYXRlZFB0ci5wcm90b3R5cGUuY29uc3RydWN0b3IgPQogICAgICBNZWRpYVN0YXR1c09ic2VydmVyQXNzb2NpYXRlZFB0cjsKCiAgZnVuY3Rpb24gTWVkaWFTdGF0dXNPYnNlcnZlclByb3h5KHJlY2VpdmVyKSB7CiAgICB0aGlzLnJlY2VpdmVyXyA9IHJlY2VpdmVyOwogIH0KICBNZWRpYVN0YXR1c09ic2VydmVyUHRyLnByb3RvdHlwZS5vbk1lZGlhU3RhdHVzVXBkYXRlZCA9IGZ1bmN0aW9uKCkgewogICAgcmV0dXJuIE1lZGlhU3RhdHVzT2JzZXJ2ZXJQcm94eS5wcm90b3R5cGUub25NZWRpYVN0YXR1c1VwZGF0ZWQKICAgICAgICAuYXBwbHkodGhpcy5wdHIuZ2V0UHJveHkoKSwgYXJndW1lbnRzKTsKICB9OwoKICBNZWRpYVN0YXR1c09ic2VydmVyUHJveHkucHJvdG90eXBlLm9uTWVkaWFTdGF0dXNVcGRhdGVkID0gZnVuY3Rpb24oc3RhdHVzKSB7CiAgICB2YXIgcGFyYW1zID0gbmV3IE1lZGlhU3RhdHVzT2JzZXJ2ZXJfT25NZWRpYVN0YXR1c1VwZGF0ZWRfUGFyYW1zKCk7CiAgICBwYXJhbXMuc3RhdHVzID0gc3RhdHVzOwogICAgdmFyIGJ1aWxkZXIgPSBuZXcgY29kZWMuTWVzc2FnZVYwQnVpbGRlcigKICAgICAgICBrTWVkaWFTdGF0dXNPYnNlcnZlcl9Pbk1lZGlhU3RhdHVzVXBkYXRlZF9OYW1lLAogICAgICAgIGNvZGVjLmFsaWduKE1lZGlhU3RhdHVzT2JzZXJ2ZXJfT25NZWRpYVN0YXR1c1VwZGF0ZWRfUGFyYW1zLmVuY29kZWRTaXplKSk7CiAgICBidWlsZGVyLmVuY29kZVN0cnVjdChNZWRpYVN0YXR1c09ic2VydmVyX09uTWVkaWFTdGF0dXNVcGRhdGVkX1BhcmFtcywgcGFyYW1zKTsKICAgIHZhciBtZXNzYWdlID0gYnVpbGRlci5maW5pc2goKTsKICAgIHRoaXMucmVjZWl2ZXJfLmFjY2VwdChtZXNzYWdlKTsKICB9OwoKICBmdW5jdGlvbiBNZWRpYVN0YXR1c09ic2VydmVyU3R1YihkZWxlZ2F0ZSkgewogICAgdGhpcy5kZWxlZ2F0ZV8gPSBkZWxlZ2F0ZTsKICB9CiAgTWVkaWFTdGF0dXNPYnNlcnZlclN0dWIucHJvdG90eXBlLm9uTWVkaWFTdGF0dXNVcGRhdGVkID0gZnVuY3Rpb24oc3RhdHVzKSB7CiAgICByZXR1cm4gdGhpcy5kZWxlZ2F0ZV8gJiYgdGhpcy5kZWxlZ2F0ZV8ub25NZWRpYVN0YXR1c1VwZGF0ZWQgJiYgdGhpcy5kZWxlZ2F0ZV8ub25NZWRpYVN0YXR1c1VwZGF0ZWQoc3RhdHVzKTsKICB9CgogIE1lZGlhU3RhdHVzT2JzZXJ2ZXJTdHViLnByb3RvdHlwZS5hY2NlcHQgPSBmdW5jdGlvbihtZXNzYWdlKSB7CiAgICB2YXIgcmVhZGVyID0gbmV3IGNvZGVjLk1lc3NhZ2VSZWFkZXIobWVzc2FnZSk7CiAgICBzd2l0Y2ggKHJlYWRlci5tZXNzYWdlTmFtZSkgewogICAgY2FzZSBrTWVkaWFTdGF0dXNPYnNlcnZlcl9Pbk1lZGlhU3RhdHVzVXBkYXRlZF9OYW1lOgogICAgICB2YXIgcGFyYW1zID0gcmVhZGVyLmRlY29kZVN0cnVjdChNZWRpYVN0YXR1c09ic2VydmVyX09uTWVkaWFTdGF0dXNVcGRhdGVkX1BhcmFtcyk7CiAgICAgIHRoaXMub25NZWRpYVN0YXR1c1VwZGF0ZWQocGFyYW1zLnN0YXR1cyk7CiAgICAgIHJldHVybiB0cnVlOwogICAgZGVmYXVsdDoKICAgICAgcmV0dXJuIGZhbHNlOwogICAgfQogIH07CgogIE1lZGlhU3RhdHVzT2JzZXJ2ZXJTdHViLnByb3RvdHlwZS5hY2NlcHRXaXRoUmVzcG9uZGVyID0KICAgICAgZnVuY3Rpb24obWVzc2FnZSwgcmVzcG9uZGVyKSB7CiAgICB2YXIgcmVhZGVyID0gbmV3IGNvZGVjLk1lc3NhZ2VSZWFkZXIobWVzc2FnZSk7CiAgICBzd2l0Y2ggKHJlYWRlci5tZXNzYWdlTmFtZSkgewogICAgZGVmYXVsdDoKICAgICAgcmV0dXJuIGZhbHNlOwogICAgfQogIH07CgogIGZ1bmN0aW9uIHZhbGlkYXRlTWVkaWFTdGF0dXNPYnNlcnZlclJlcXVlc3QobWVzc2FnZVZhbGlkYXRvcikgewogICAgdmFyIG1lc3NhZ2UgPSBtZXNzYWdlVmFsaWRhdG9yLm1lc3NhZ2U7CiAgICB2YXIgcGFyYW1zQ2xhc3MgPSBudWxsOwogICAgc3dpdGNoIChtZXNzYWdlLmdldE5hbWUoKSkgewogICAgICBjYXNlIGtNZWRpYVN0YXR1c09ic2VydmVyX09uTWVkaWFTdGF0dXNVcGRhdGVkX05hbWU6CiAgICAgICAgaWYgKCFtZXNzYWdlLmV4cGVjdHNSZXNwb25zZSgpICYmICFtZXNzYWdlLmlzUmVzcG9uc2UoKSkKICAgICAgICAgIHBhcmFtc0NsYXNzID0gTWVkaWFTdGF0dXNPYnNlcnZlcl9Pbk1lZGlhU3RhdHVzVXBkYXRlZF9QYXJhbXM7CiAgICAgIGJyZWFrOwogICAgfQogICAgaWYgKHBhcmFtc0NsYXNzID09PSBudWxsKQogICAgICByZXR1cm4gdmFsaWRhdG9yLnZhbGlkYXRpb25FcnJvci5OT05FOwogICAgcmV0dXJuIHBhcmFtc0NsYXNzLnZhbGlkYXRlKG1lc3NhZ2VWYWxpZGF0b3IsIG1lc3NhZ2VWYWxpZGF0b3IubWVzc2FnZS5nZXRIZWFkZXJOdW1CeXRlcygpKTsKICB9CgogIGZ1bmN0aW9uIHZhbGlkYXRlTWVkaWFTdGF0dXNPYnNlcnZlclJlc3BvbnNlKG1lc3NhZ2VWYWxpZGF0b3IpIHsKICAgIHJldHVybiB2YWxpZGF0b3IudmFsaWRhdGlvbkVycm9yLk5PTkU7CiAgfQoKICB2YXIgTWVkaWFTdGF0dXNPYnNlcnZlciA9IHsKICAgIG5hbWU6ICdtZWRpYV9yb3V0ZXI6Om1vam9tOjpNZWRpYVN0YXR1c09ic2VydmVyJywKICAgIGtWZXJzaW9uOiAwLAogICAgcHRyQ2xhc3M6IE1lZGlhU3RhdHVzT2JzZXJ2ZXJQdHIsCiAgICBwcm94eUNsYXNzOiBNZWRpYVN0YXR1c09ic2VydmVyUHJveHksCiAgICBzdHViQ2xhc3M6IE1lZGlhU3RhdHVzT2JzZXJ2ZXJTdHViLAogICAgdmFsaWRhdGVSZXF1ZXN0OiB2YWxpZGF0ZU1lZGlhU3RhdHVzT2JzZXJ2ZXJSZXF1ZXN0LAogICAgdmFsaWRhdGVSZXNwb25zZTogbnVsbCwKICB9OwogIE1lZGlhU3RhdHVzT2JzZXJ2ZXJTdHViLnByb3RvdHlwZS52YWxpZGF0b3IgPSB2YWxpZGF0ZU1lZGlhU3RhdHVzT2JzZXJ2ZXJSZXF1ZXN0OwogIE1lZGlhU3RhdHVzT2JzZXJ2ZXJQcm94eS5wcm90b3R5cGUudmFsaWRhdG9yID0gbnVsbDsKICBleHBvcnRzLk1lZGlhU3RhdHVzID0gTWVkaWFTdGF0dXM7CiAgZXhwb3J0cy5IYW5nb3V0c01lZGlhU3RhdHVzRXh0cmFEYXRhID0gSGFuZ291dHNNZWRpYVN0YXR1c0V4dHJhRGF0YTsKICBleHBvcnRzLk1lZGlhU3RhdHVzT2JzZXJ2ZXIgPSBNZWRpYVN0YXR1c09ic2VydmVyOwogIGV4cG9ydHMuTWVkaWFTdGF0dXNPYnNlcnZlclB0ciA9IE1lZGlhU3RhdHVzT2JzZXJ2ZXJQdHI7CiAgZXhwb3J0cy5NZWRpYVN0YXR1c09ic2VydmVyQXNzb2NpYXRlZFB0ciA9IE1lZGlhU3RhdHVzT2JzZXJ2ZXJBc3NvY2lhdGVkUHRyOwp9KSgpOy8vIENvcHlyaWdodCAyMDE0IFRoZSBDaHJvbWl1bSBBdXRob3JzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgovLyBVc2Ugb2YgdGhpcyBzb3VyY2UgY29kZSBpcyBnb3Zlcm5lZCBieSBhIEJTRC1zdHlsZSBsaWNlbnNlIHRoYXQgY2FuIGJlCi8vIGZvdW5kIGluIHRoZSBMSUNFTlNFIGZpbGUuCgondXNlIHN0cmljdCc7CgooZnVuY3Rpb24oKSB7CiAgdmFyIG1vam9tSWQgPSAnbW9qby9jb21tb24vdGltZS5tb2pvbSc7CiAgaWYgKG1vam8uaW50ZXJuYWwuaXNNb2pvbUxvYWRlZChtb2pvbUlkKSkgewogICAgY29uc29sZS53YXJuKCdUaGUgZm9sbG93aW5nIG1vam9tIGlzIGxvYWRlZCBtdWx0aXBsZSB0aW1lczogJyArIG1vam9tSWQpOwogICAgcmV0dXJuOwogIH0KICBtb2pvLmludGVybmFsLm1hcmtNb2pvbUxvYWRlZChtb2pvbUlkKTsKICB2YXIgYmluZGluZ3MgPSBtb2pvOwogIHZhciBhc3NvY2lhdGVkQmluZGluZ3MgPSBtb2pvOwogIHZhciBjb2RlYyA9IG1vam8uaW50ZXJuYWw7CiAgdmFyIHZhbGlkYXRvciA9IG1vam8uaW50ZXJuYWw7CgogIHZhciBleHBvcnRzID0gbW9qby5pbnRlcm5hbC5leHBvc2VOYW1lc3BhY2UoJ21vam8uY29tbW9uLm1vam9tJyk7CgoKCiAgZnVuY3Rpb24gVGltZSh2YWx1ZXMpIHsKICAgIHRoaXMuaW5pdERlZmF1bHRzXygpOwogICAgdGhpcy5pbml0RmllbGRzXyh2YWx1ZXMpOwogIH0KCgogIFRpbWUucHJvdG90eXBlLmluaXREZWZhdWx0c18gPSBmdW5jdGlvbigpIHsKICAgIHRoaXMuaW50ZXJuYWxWYWx1ZSA9IDA7CiAgfTsKICBUaW1lLnByb3RvdHlwZS5pbml0RmllbGRzXyA9IGZ1bmN0aW9uKGZpZWxkcykgewogICAgZm9yKHZhciBmaWVsZCBpbiBmaWVsZHMpIHsKICAgICAgICBpZiAodGhpcy5oYXNPd25Qcm9wZXJ0eShmaWVsZCkpCiAgICAgICAgICB0aGlzW2ZpZWxkXSA9IGZpZWxkc1tmaWVsZF07CiAgICB9CiAgfTsKCiAgVGltZS52YWxpZGF0ZSA9IGZ1bmN0aW9uKG1lc3NhZ2VWYWxpZGF0b3IsIG9mZnNldCkgewogICAgdmFyIGVycjsKICAgIGVyciA9IG1lc3NhZ2VWYWxpZGF0b3IudmFsaWRhdGVTdHJ1Y3RIZWFkZXIob2Zmc2V0LCBjb2RlYy5rU3RydWN0SGVhZGVyU2l6ZSk7CiAgICBpZiAoZXJyICE9PSB2YWxpZGF0b3IudmFsaWRhdGlvbkVycm9yLk5PTkUpCiAgICAgICAgcmV0dXJuIGVycjsKCiAgICB2YXIga1ZlcnNpb25TaXplcyA9IFsKICAgICAge3ZlcnNpb246IDAsIG51bUJ5dGVzOiAxNn0KICAgIF07CiAgICBlcnIgPSBtZXNzYWdlVmFsaWRhdG9yLnZhbGlkYXRlU3RydWN0VmVyc2lvbihvZmZzZXQsIGtWZXJzaW9uU2l6ZXMpOwogICAgaWYgKGVyciAhPT0gdmFsaWRhdG9yLnZhbGlkYXRpb25FcnJvci5OT05FKQogICAgICAgIHJldHVybiBlcnI7CgoKICAgIHJldHVybiB2YWxpZGF0b3IudmFsaWRhdGlvbkVycm9yLk5PTkU7CiAgfTsKCiAgVGltZS5lbmNvZGVkU2l6ZSA9IGNvZGVjLmtTdHJ1Y3RIZWFkZXJTaXplICsgODsKCiAgVGltZS5kZWNvZGUgPSBmdW5jdGlvbihkZWNvZGVyKSB7CiAgICB2YXIgcGFja2VkOwogICAgdmFyIHZhbCA9IG5ldyBUaW1lKCk7CiAgICB2YXIgbnVtYmVyT2ZCeXRlcyA9IGRlY29kZXIucmVhZFVpbnQzMigpOwogICAgdmFyIHZlcnNpb24gPSBkZWNvZGVyLnJlYWRVaW50MzIoKTsKICAgIHZhbC5pbnRlcm5hbFZhbHVlID0gZGVjb2Rlci5kZWNvZGVTdHJ1Y3QoY29kZWMuSW50NjQpOwogICAgcmV0dXJuIHZhbDsKICB9OwoKICBUaW1lLmVuY29kZSA9IGZ1bmN0aW9uKGVuY29kZXIsIHZhbCkgewogICAgdmFyIHBhY2tlZDsKICAgIGVuY29kZXIud3JpdGVVaW50MzIoVGltZS5lbmNvZGVkU2l6ZSk7CiAgICBlbmNvZGVyLndyaXRlVWludDMyKDApOwogICAgZW5jb2Rlci5lbmNvZGVTdHJ1Y3QoY29kZWMuSW50NjQsIHZhbC5pbnRlcm5hbFZhbHVlKTsKICB9OwogIGZ1bmN0aW9uIFRpbWVEZWx0YSh2YWx1ZXMpIHsKICAgIHRoaXMuaW5pdERlZmF1bHRzXygpOwogICAgdGhpcy5pbml0RmllbGRzXyh2YWx1ZXMpOwogIH0KCgogIFRpbWVEZWx0YS5wcm90b3R5cGUuaW5pdERlZmF1bHRzXyA9IGZ1bmN0aW9uKCkgewogICAgdGhpcy5taWNyb3NlY29uZHMgPSAwOwogIH07CiAgVGltZURlbHRhLnByb3RvdHlwZS5pbml0RmllbGRzXyA9IGZ1bmN0aW9uKGZpZWxkcykgewogICAgZm9yKHZhciBmaWVsZCBpbiBmaWVsZHMpIHsKICAgICAgICBpZiAodGhpcy5oYXNPd25Qcm9wZXJ0eShmaWVsZCkpCiAgICAgICAgICB0aGlzW2ZpZWxkXSA9IGZpZWxkc1tmaWVsZF07CiAgICB9CiAgfTsKCiAgVGltZURlbHRhLnZhbGlkYXRlID0gZnVuY3Rpb24obWVzc2FnZVZhbGlkYXRvciwgb2Zmc2V0KSB7CiAgICB2YXIgZXJyOwogICAgZXJyID0gbWVzc2FnZVZhbGlkYXRvci52YWxpZGF0ZVN0cnVjdEhlYWRlcihvZmZzZXQsIGNvZGVjLmtTdHJ1Y3RIZWFkZXJTaXplKTsKICAgIGlmIChlcnIgIT09IHZhbGlkYXRvci52YWxpZGF0aW9uRXJyb3IuTk9ORSkKICAgICAgICByZXR1cm4gZXJyOwoKICAgIHZhciBrVmVyc2lvblNpemVzID0gWwogICAgICB7dmVyc2lvbjogMCwgbnVtQnl0ZXM6IDE2fQogICAgXTsKICAgIGVyciA9IG1lc3NhZ2VWYWxpZGF0b3IudmFsaWRhdGVTdHJ1Y3RWZXJzaW9uKG9mZnNldCwga1ZlcnNpb25TaXplcyk7CiAgICBpZiAoZXJyICE9PSB2YWxpZGF0b3IudmFsaWRhdGlvbkVycm9yLk5PTkUpCiAgICAgICAgcmV0dXJuIGVycjsKCgogICAgcmV0dXJuIHZhbGlkYXRvci52YWxpZGF0aW9uRXJyb3IuTk9ORTsKICB9OwoKICBUaW1lRGVsdGEuZW5jb2RlZFNpemUgPSBjb2RlYy5rU3RydWN0SGVhZGVyU2l6ZSArIDg7CgogIFRpbWVEZWx0YS5kZWNvZGUgPSBmdW5jdGlvbihkZWNvZGVyKSB7CiAgICB2YXIgcGFja2VkOwogICAgdmFyIHZhbCA9IG5ldyBUaW1lRGVsdGEoKTsKICAgIHZhciBudW1iZXJPZkJ5dGVzID0gZGVjb2Rlci5yZWFkVWludDMyKCk7CiAgICB2YXIgdmVyc2lvbiA9IGRlY29kZXIucmVhZFVpbnQzMigpOwogICAgdmFsLm1pY3Jvc2Vjb25kcyA9IGRlY29kZXIuZGVjb2RlU3RydWN0KGNvZGVjLkludDY0KTsKICAgIHJldHVybiB2YWw7CiAgfTsKCiAgVGltZURlbHRhLmVuY29kZSA9IGZ1bmN0aW9uKGVuY29kZXIsIHZhbCkgewogICAgdmFyIHBhY2tlZDsKICAgIGVuY29kZXIud3JpdGVVaW50MzIoVGltZURlbHRhLmVuY29kZWRTaXplKTsKICAgIGVuY29kZXIud3JpdGVVaW50MzIoMCk7CiAgICBlbmNvZGVyLmVuY29kZVN0cnVjdChjb2RlYy5JbnQ2NCwgdmFsLm1pY3Jvc2Vjb25kcyk7CiAgfTsKICBmdW5jdGlvbiBUaW1lVGlja3ModmFsdWVzKSB7CiAgICB0aGlzLmluaXREZWZhdWx0c18oKTsKICAgIHRoaXMuaW5pdEZpZWxkc18odmFsdWVzKTsKICB9CgoKICBUaW1lVGlja3MucHJvdG90eXBlLmluaXREZWZhdWx0c18gPSBmdW5jdGlvbigpIHsKICAgIHRoaXMuaW50ZXJuYWxWYWx1ZSA9IDA7CiAgfTsKICBUaW1lVGlja3MucHJvdG90eXBlLmluaXRGaWVsZHNfID0gZnVuY3Rpb24oZmllbGRzKSB7CiAgICBmb3IodmFyIGZpZWxkIGluIGZpZWxkcykgewogICAgICAgIGlmICh0aGlzLmhhc093blByb3BlcnR5KGZpZWxkKSkKICAgICAgICAgIHRoaXNbZmllbGRdID0gZmllbGRzW2ZpZWxkXTsKICAgIH0KICB9OwoKICBUaW1lVGlja3MudmFsaWRhdGUgPSBmdW5jdGlvbihtZXNzYWdlVmFsaWRhdG9yLCBvZmZzZXQpIHsKICAgIHZhciBlcnI7CiAgICBlcnIgPSBtZXNzYWdlVmFsaWRhdG9yLnZhbGlkYXRlU3RydWN0SGVhZGVyKG9mZnNldCwgY29kZWMua1N0cnVjdEhlYWRlclNpemUpOwogICAgaWYgKGVyciAhPT0gdmFsaWRhdG9yLnZhbGlkYXRpb25FcnJvci5OT05FKQogICAgICAgIHJldHVybiBlcnI7CgogICAgdmFyIGtWZXJzaW9uU2l6ZXMgPSBbCiAgICAgIHt2ZXJzaW9uOiAwLCBudW1CeXRlczogMTZ9CiAgICBdOwogICAgZXJyID0gbWVzc2FnZVZhbGlkYXRvci52YWxpZGF0ZVN0cnVjdFZlcnNpb24ob2Zmc2V0LCBrVmVyc2lvblNpemVzKTsKICAgIGlmIChlcnIgIT09IHZhbGlkYXRvci52YWxpZGF0aW9uRXJyb3IuTk9ORSkKICAgICAgICByZXR1cm4gZXJyOwoKCiAgICByZXR1cm4gdmFsaWRhdG9yLnZhbGlkYXRpb25FcnJvci5OT05FOwogIH07CgogIFRpbWVUaWNrcy5lbmNvZGVkU2l6ZSA9IGNvZGVjLmtTdHJ1Y3RIZWFkZXJTaXplICsgODsKCiAgVGltZVRpY2tzLmRlY29kZSA9IGZ1bmN0aW9uKGRlY29kZXIpIHsKICAgIHZhciBwYWNrZWQ7CiAgICB2YXIgdmFsID0gbmV3IFRpbWVUaWNrcygpOwogICAgdmFyIG51bWJlck9mQnl0ZXMgPSBkZWNvZGVyLnJlYWRVaW50MzIoKTsKICAgIHZhciB2ZXJzaW9uID0gZGVjb2Rlci5yZWFkVWludDMyKCk7CiAgICB2YWwuaW50ZXJuYWxWYWx1ZSA9IGRlY29kZXIuZGVjb2RlU3RydWN0KGNvZGVjLkludDY0KTsKICAgIHJldHVybiB2YWw7CiAgfTsKCiAgVGltZVRpY2tzLmVuY29kZSA9IGZ1bmN0aW9uKGVuY29kZXIsIHZhbCkgewogICAgdmFyIHBhY2tlZDsKICAgIGVuY29kZXIud3JpdGVVaW50MzIoVGltZVRpY2tzLmVuY29kZWRTaXplKTsKICAgIGVuY29kZXIud3JpdGVVaW50MzIoMCk7CiAgICBlbmNvZGVyLmVuY29kZVN0cnVjdChjb2RlYy5JbnQ2NCwgdmFsLmludGVybmFsVmFsdWUpOwogIH07CiAgZXhwb3J0cy5UaW1lID0gVGltZTsKICBleHBvcnRzLlRpbWVEZWx0YSA9IFRpbWVEZWx0YTsKICBleHBvcnRzLlRpbWVUaWNrcyA9IFRpbWVUaWNrczsKfSkoKTsvLyBDb3B5cmlnaHQgMjAxNCBUaGUgQ2hyb21pdW0gQXV0aG9ycy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KLy8gVXNlIG9mIHRoaXMgc291cmNlIGNvZGUgaXMgZ292ZXJuZWQgYnkgYSBCU0Qtc3R5bGUgbGljZW5zZSB0aGF0IGNhbiBiZQovLyBmb3VuZCBpbiB0aGUgTElDRU5TRSBmaWxlLgoKJ3VzZSBzdHJpY3QnOwoKKGZ1bmN0aW9uKCkgewogIHZhciBtb2pvbUlkID0gJ25ldC9pbnRlcmZhY2VzL2lwX2FkZHJlc3MubW9qb20nOwogIGlmIChtb2pvLmludGVybmFsLmlzTW9qb21Mb2FkZWQobW9qb21JZCkpIHsKICAgIGNvbnNvbGUud2FybignVGhlIGZvbGxvd2luZyBtb2pvbSBpcyBsb2FkZWQgbXVsdGlwbGUgdGltZXM6ICcgKyBtb2pvbUlkKTsKICAgIHJldHVybjsKICB9CiAgbW9qby5pbnRlcm5hbC5tYXJrTW9qb21Mb2FkZWQobW9qb21JZCk7CiAgdmFyIGJpbmRpbmdzID0gbW9qbzsKICB2YXIgYXNzb2NpYXRlZEJpbmRpbmdzID0gbW9qbzsKICB2YXIgY29kZWMgPSBtb2pvLmludGVybmFsOwogIHZhciB2YWxpZGF0b3IgPSBtb2pvLmludGVybmFsOwoKICB2YXIgZXhwb3J0cyA9IG1vam8uaW50ZXJuYWwuZXhwb3NlTmFtZXNwYWNlKCduZXQuaW50ZXJmYWNlcycpOwoKCgogIGZ1bmN0aW9uIElQQWRkcmVzcyh2YWx1ZXMpIHsKICAgIHRoaXMuaW5pdERlZmF1bHRzXygpOwogICAgdGhpcy5pbml0RmllbGRzXyh2YWx1ZXMpOwogIH0KCgogIElQQWRkcmVzcy5wcm90b3R5cGUuaW5pdERlZmF1bHRzXyA9IGZ1bmN0aW9uKCkgewogICAgdGhpcy5hZGRyZXNzQnl0ZXMgPSBudWxsOwogIH07CiAgSVBBZGRyZXNzLnByb3RvdHlwZS5pbml0RmllbGRzXyA9IGZ1bmN0aW9uKGZpZWxkcykgewogICAgZm9yKHZhciBmaWVsZCBpbiBmaWVsZHMpIHsKICAgICAgICBpZiAodGhpcy5oYXNPd25Qcm9wZXJ0eShmaWVsZCkpCiAgICAgICAgICB0aGlzW2ZpZWxkXSA9IGZpZWxkc1tmaWVsZF07CiAgICB9CiAgfTsKCiAgSVBBZGRyZXNzLnZhbGlkYXRlID0gZnVuY3Rpb24obWVzc2FnZVZhbGlkYXRvciwgb2Zmc2V0KSB7CiAgICB2YXIgZXJyOwogICAgZXJyID0gbWVzc2FnZVZhbGlkYXRvci52YWxpZGF0ZVN0cnVjdEhlYWRlcihvZmZzZXQsIGNvZGVjLmtTdHJ1Y3RIZWFkZXJTaXplKTsKICAgIGlmIChlcnIgIT09IHZhbGlkYXRvci52YWxpZGF0aW9uRXJyb3IuTk9ORSkKICAgICAgICByZXR1cm4gZXJyOwoKICAgIHZhciBrVmVyc2lvblNpemVzID0gWwogICAgICB7dmVyc2lvbjogMCwgbnVtQnl0ZXM6IDE2fQogICAgXTsKICAgIGVyciA9IG1lc3NhZ2VWYWxpZGF0b3IudmFsaWRhdGVTdHJ1Y3RWZXJzaW9uKG9mZnNldCwga1ZlcnNpb25TaXplcyk7CiAgICBpZiAoZXJyICE9PSB2YWxpZGF0b3IudmFsaWRhdGlvbkVycm9yLk5PTkUpCiAgICAgICAgcmV0dXJuIGVycjsKCgogICAgLy8gdmFsaWRhdGUgSVBBZGRyZXNzLmFkZHJlc3NCeXRlcwogICAgZXJyID0gbWVzc2FnZVZhbGlkYXRvci52YWxpZGF0ZUFycmF5UG9pbnRlcihvZmZzZXQgKyBjb2RlYy5rU3RydWN0SGVhZGVyU2l6ZSArIDAsIDEsIGNvZGVjLlVpbnQ4LCBmYWxzZSwgWzBdLCAwKTsKICAgIGlmIChlcnIgIT09IHZhbGlkYXRvci52YWxpZGF0aW9uRXJyb3IuTk9ORSkKICAgICAgICByZXR1cm4gZXJyOwoKICAgIHJldHVybiB2YWxpZGF0b3IudmFsaWRhdGlvbkVycm9yLk5PTkU7CiAgfTsKCiAgSVBBZGRyZXNzLmVuY29kZWRTaXplID0gY29kZWMua1N0cnVjdEhlYWRlclNpemUgKyA4OwoKICBJUEFkZHJlc3MuZGVjb2RlID0gZnVuY3Rpb24oZGVjb2RlcikgewogICAgdmFyIHBhY2tlZDsKICAgIHZhciB2YWwgPSBuZXcgSVBBZGRyZXNzKCk7CiAgICB2YXIgbnVtYmVyT2ZCeXRlcyA9IGRlY29kZXIucmVhZFVpbnQzMigpOwogICAgdmFyIHZlcnNpb24gPSBkZWNvZGVyLnJlYWRVaW50MzIoKTsKICAgIHZhbC5hZGRyZXNzQnl0ZXMgPSBkZWNvZGVyLmRlY29kZUFycmF5UG9pbnRlcihjb2RlYy5VaW50OCk7CiAgICByZXR1cm4gdmFsOwogIH07CgogIElQQWRkcmVzcy5lbmNvZGUgPSBmdW5jdGlvbihlbmNvZGVyLCB2YWwpIHsKICAgIHZhciBwYWNrZWQ7CiAgICBlbmNvZGVyLndyaXRlVWludDMyKElQQWRkcmVzcy5lbmNvZGVkU2l6ZSk7CiAgICBlbmNvZGVyLndyaXRlVWludDMyKDApOwogICAgZW5jb2Rlci5lbmNvZGVBcnJheVBvaW50ZXIoY29kZWMuVWludDgsIHZhbC5hZGRyZXNzQnl0ZXMpOwogIH07CiAgZXhwb3J0cy5JUEFkZHJlc3MgPSBJUEFkZHJlc3M7Cn0pKCk7Ly8gQ29weXJpZ2h0IDIwMTQgVGhlIENocm9taXVtIEF1dGhvcnMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCi8vIFVzZSBvZiB0aGlzIHNvdXJjZSBjb2RlIGlzIGdvdmVybmVkIGJ5IGEgQlNELXN0eWxlIGxpY2Vuc2UgdGhhdCBjYW4gYmUKLy8gZm91bmQgaW4gdGhlIExJQ0VOU0UgZmlsZS4KCid1c2Ugc3RyaWN0JzsKCihmdW5jdGlvbigpIHsKICB2YXIgbW9qb21JZCA9ICduZXQvaW50ZXJmYWNlcy9pcF9lbmRwb2ludC5tb2pvbSc7CiAgaWYgKG1vam8uaW50ZXJuYWwuaXNNb2pvbUxvYWRlZChtb2pvbUlkKSkgewogICAgY29uc29sZS53YXJuKCdUaGUgZm9sbG93aW5nIG1vam9tIGlzIGxvYWRlZCBtdWx0aXBsZSB0aW1lczogJyArIG1vam9tSWQpOwogICAgcmV0dXJuOwogIH0KICBtb2pvLmludGVybmFsLm1hcmtNb2pvbUxvYWRlZChtb2pvbUlkKTsKICB2YXIgYmluZGluZ3MgPSBtb2pvOwogIHZhciBhc3NvY2lhdGVkQmluZGluZ3MgPSBtb2pvOwogIHZhciBjb2RlYyA9IG1vam8uaW50ZXJuYWw7CiAgdmFyIHZhbGlkYXRvciA9IG1vam8uaW50ZXJuYWw7CgogIHZhciBleHBvcnRzID0gbW9qby5pbnRlcm5hbC5leHBvc2VOYW1lc3BhY2UoJ25ldC5pbnRlcmZhY2VzJyk7CiAgdmFyIGlwX2FkZHJlc3MkID0KICAgICAgbW9qby5pbnRlcm5hbC5leHBvc2VOYW1lc3BhY2UoJ25ldC5pbnRlcmZhY2VzJyk7CiAgaWYgKG1vam8uY29uZmlnLmF1dG9Mb2FkTW9qb21EZXBzKSB7CiAgICBtb2pvLmludGVybmFsLmxvYWRNb2pvbUlmTmVjZXNzYXJ5KAogICAgICAgICduZXQvaW50ZXJmYWNlcy9pcF9hZGRyZXNzLm1vam9tJywgJ2lwX2FkZHJlc3MubW9qb20uanMnKTsKICB9CgoKCiAgZnVuY3Rpb24gSVBFbmRQb2ludCh2YWx1ZXMpIHsKICAgIHRoaXMuaW5pdERlZmF1bHRzXygpOwogICAgdGhpcy5pbml0RmllbGRzXyh2YWx1ZXMpOwogIH0KCgogIElQRW5kUG9pbnQucHJvdG90eXBlLmluaXREZWZhdWx0c18gPSBmdW5jdGlvbigpIHsKICAgIHRoaXMuYWRkcmVzcyA9IG51bGw7CiAgICB0aGlzLnBvcnQgPSAwOwogIH07CiAgSVBFbmRQb2ludC5wcm90b3R5cGUuaW5pdEZpZWxkc18gPSBmdW5jdGlvbihmaWVsZHMpIHsKICAgIGZvcih2YXIgZmllbGQgaW4gZmllbGRzKSB7CiAgICAgICAgaWYgKHRoaXMuaGFzT3duUHJvcGVydHkoZmllbGQpKQogICAgICAgICAgdGhpc1tmaWVsZF0gPSBmaWVsZHNbZmllbGRdOwogICAgfQogIH07CgogIElQRW5kUG9pbnQudmFsaWRhdGUgPSBmdW5jdGlvbihtZXNzYWdlVmFsaWRhdG9yLCBvZmZzZXQpIHsKICAgIHZhciBlcnI7CiAgICBlcnIgPSBtZXNzYWdlVmFsaWRhdG9yLnZhbGlkYXRlU3RydWN0SGVhZGVyKG9mZnNldCwgY29kZWMua1N0cnVjdEhlYWRlclNpemUpOwogICAgaWYgKGVyciAhPT0gdmFsaWRhdG9yLnZhbGlkYXRpb25FcnJvci5OT05FKQogICAgICAgIHJldHVybiBlcnI7CgogICAgdmFyIGtWZXJzaW9uU2l6ZXMgPSBbCiAgICAgIHt2ZXJzaW9uOiAwLCBudW1CeXRlczogMjR9CiAgICBdOwogICAgZXJyID0gbWVzc2FnZVZhbGlkYXRvci52YWxpZGF0ZVN0cnVjdFZlcnNpb24ob2Zmc2V0LCBrVmVyc2lvblNpemVzKTsKICAgIGlmIChlcnIgIT09IHZhbGlkYXRvci52YWxpZGF0aW9uRXJyb3IuTk9ORSkKICAgICAgICByZXR1cm4gZXJyOwoKCiAgICAvLyB2YWxpZGF0ZSBJUEVuZFBvaW50LmFkZHJlc3MKICAgIGVyciA9IG1lc3NhZ2VWYWxpZGF0b3IudmFsaWRhdGVTdHJ1Y3RQb2ludGVyKG9mZnNldCArIGNvZGVjLmtTdHJ1Y3RIZWFkZXJTaXplICsgMCwgaXBfYWRkcmVzcyQuSVBBZGRyZXNzLCBmYWxzZSk7CiAgICBpZiAoZXJyICE9PSB2YWxpZGF0b3IudmFsaWRhdGlvbkVycm9yLk5PTkUpCiAgICAgICAgcmV0dXJuIGVycjsKCgogICAgcmV0dXJuIHZhbGlkYXRvci52YWxpZGF0aW9uRXJyb3IuTk9ORTsKICB9OwoKICBJUEVuZFBvaW50LmVuY29kZWRTaXplID0gY29kZWMua1N0cnVjdEhlYWRlclNpemUgKyAxNjsKCiAgSVBFbmRQb2ludC5kZWNvZGUgPSBmdW5jdGlvbihkZWNvZGVyKSB7CiAgICB2YXIgcGFja2VkOwogICAgdmFyIHZhbCA9IG5ldyBJUEVuZFBvaW50KCk7CiAgICB2YXIgbnVtYmVyT2ZCeXRlcyA9IGRlY29kZXIucmVhZFVpbnQzMigpOwogICAgdmFyIHZlcnNpb24gPSBkZWNvZGVyLnJlYWRVaW50MzIoKTsKICAgIHZhbC5hZGRyZXNzID0gZGVjb2Rlci5kZWNvZGVTdHJ1Y3RQb2ludGVyKGlwX2FkZHJlc3MkLklQQWRkcmVzcyk7CiAgICB2YWwucG9ydCA9IGRlY29kZXIuZGVjb2RlU3RydWN0KGNvZGVjLlVpbnQxNik7CiAgICBkZWNvZGVyLnNraXAoMSk7CiAgICBkZWNvZGVyLnNraXAoMSk7CiAgICBkZWNvZGVyLnNraXAoMSk7CiAgICBkZWNvZGVyLnNraXAoMSk7CiAgICBkZWNvZGVyLnNraXAoMSk7CiAgICBkZWNvZGVyLnNraXAoMSk7CiAgICByZXR1cm4gdmFsOwogIH07CgogIElQRW5kUG9pbnQuZW5jb2RlID0gZnVuY3Rpb24oZW5jb2RlciwgdmFsKSB7CiAgICB2YXIgcGFja2VkOwogICAgZW5jb2Rlci53cml0ZVVpbnQzMihJUEVuZFBvaW50LmVuY29kZWRTaXplKTsKICAgIGVuY29kZXIud3JpdGVVaW50MzIoMCk7CiAgICBlbmNvZGVyLmVuY29kZVN0cnVjdFBvaW50ZXIoaXBfYWRkcmVzcyQuSVBBZGRyZXNzLCB2YWwuYWRkcmVzcyk7CiAgICBlbmNvZGVyLmVuY29kZVN0cnVjdChjb2RlYy5VaW50MTYsIHZhbC5wb3J0KTsKICAgIGVuY29kZXIuc2tpcCgxKTsKICAgIGVuY29kZXIuc2tpcCgxKTsKICAgIGVuY29kZXIuc2tpcCgxKTsKICAgIGVuY29kZXIuc2tpcCgxKTsKICAgIGVuY29kZXIuc2tpcCgxKTsKICAgIGVuY29kZXIuc2tpcCgxKTsKICB9OwogIGV4cG9ydHMuSVBFbmRQb2ludCA9IElQRW5kUG9pbnQ7Cn0pKCk7Ly8gQ29weXJpZ2h0IDIwMTQgVGhlIENocm9taXVtIEF1dGhvcnMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCi8vIFVzZSBvZiB0aGlzIHNvdXJjZSBjb2RlIGlzIGdvdmVybmVkIGJ5IGEgQlNELXN0eWxlIGxpY2Vuc2UgdGhhdCBjYW4gYmUKLy8gZm91bmQgaW4gdGhlIExJQ0VOU0UgZmlsZS4KCid1c2Ugc3RyaWN0JzsKCihmdW5jdGlvbigpIHsKICB2YXIgbW9qb21JZCA9ICd1cmwvbW9qby9vcmlnaW4ubW9qb20nOwogIGlmIChtb2pvLmludGVybmFsLmlzTW9qb21Mb2FkZWQobW9qb21JZCkpIHsKICAgIGNvbnNvbGUud2FybignVGhlIGZvbGxvd2luZyBtb2pvbSBpcyBsb2FkZWQgbXVsdGlwbGUgdGltZXM6ICcgKyBtb2pvbUlkKTsKICAgIHJldHVybjsKICB9CiAgbW9qby5pbnRlcm5hbC5tYXJrTW9qb21Mb2FkZWQobW9qb21JZCk7CiAgdmFyIGJpbmRpbmdzID0gbW9qbzsKICB2YXIgYXNzb2NpYXRlZEJpbmRpbmdzID0gbW9qbzsKICB2YXIgY29kZWMgPSBtb2pvLmludGVybmFsOwogIHZhciB2YWxpZGF0b3IgPSBtb2pvLmludGVybmFsOwoKICB2YXIgZXhwb3J0cyA9IG1vam8uaW50ZXJuYWwuZXhwb3NlTmFtZXNwYWNlKCd1cmwubW9qb20nKTsKCgoKICBmdW5jdGlvbiBPcmlnaW4odmFsdWVzKSB7CiAgICB0aGlzLmluaXREZWZhdWx0c18oKTsKICAgIHRoaXMuaW5pdEZpZWxkc18odmFsdWVzKTsKICB9CgoKICBPcmlnaW4ucHJvdG90eXBlLmluaXREZWZhdWx0c18gPSBmdW5jdGlvbigpIHsKICAgIHRoaXMuc2NoZW1lID0gbnVsbDsKICAgIHRoaXMuaG9zdCA9IG51bGw7CiAgICB0aGlzLnBvcnQgPSAwOwogICAgdGhpcy51bmlxdWUgPSBmYWxzZTsKICAgIHRoaXMuc3Vib3JpZ2luID0gbnVsbDsKICB9OwogIE9yaWdpbi5wcm90b3R5cGUuaW5pdEZpZWxkc18gPSBmdW5jdGlvbihmaWVsZHMpIHsKICAgIGZvcih2YXIgZmllbGQgaW4gZmllbGRzKSB7CiAgICAgICAgaWYgKHRoaXMuaGFzT3duUHJvcGVydHkoZmllbGQpKQogICAgICAgICAgdGhpc1tmaWVsZF0gPSBmaWVsZHNbZmllbGRdOwogICAgfQogIH07CgogIE9yaWdpbi52YWxpZGF0ZSA9IGZ1bmN0aW9uKG1lc3NhZ2VWYWxpZGF0b3IsIG9mZnNldCkgewogICAgdmFyIGVycjsKICAgIGVyciA9IG1lc3NhZ2VWYWxpZGF0b3IudmFsaWRhdGVTdHJ1Y3RIZWFkZXIob2Zmc2V0LCBjb2RlYy5rU3RydWN0SGVhZGVyU2l6ZSk7CiAgICBpZiAoZXJyICE9PSB2YWxpZGF0b3IudmFsaWRhdGlvbkVycm9yLk5PTkUpCiAgICAgICAgcmV0dXJuIGVycjsKCiAgICB2YXIga1ZlcnNpb25TaXplcyA9IFsKICAgICAge3ZlcnNpb246IDAsIG51bUJ5dGVzOiA0MH0KICAgIF07CiAgICBlcnIgPSBtZXNzYWdlVmFsaWRhdG9yLnZhbGlkYXRlU3RydWN0VmVyc2lvbihvZmZzZXQsIGtWZXJzaW9uU2l6ZXMpOwogICAgaWYgKGVyciAhPT0gdmFsaWRhdG9yLnZhbGlkYXRpb25FcnJvci5OT05FKQogICAgICAgIHJldHVybiBlcnI7CgoKICAgIC8vIHZhbGlkYXRlIE9yaWdpbi5zY2hlbWUKICAgIGVyciA9IG1lc3NhZ2VWYWxpZGF0b3IudmFsaWRhdGVTdHJpbmdQb2ludGVyKG9mZnNldCArIGNvZGVjLmtTdHJ1Y3RIZWFkZXJTaXplICsgMCwgZmFsc2UpCiAgICBpZiAoZXJyICE9PSB2YWxpZGF0b3IudmFsaWRhdGlvbkVycm9yLk5PTkUpCiAgICAgICAgcmV0dXJuIGVycjsKCgogICAgLy8gdmFsaWRhdGUgT3JpZ2luLmhvc3QKICAgIGVyciA9IG1lc3NhZ2VWYWxpZGF0b3IudmFsaWRhdGVTdHJpbmdQb2ludGVyKG9mZnNldCArIGNvZGVjLmtTdHJ1Y3RIZWFkZXJTaXplICsgOCwgZmFsc2UpCiAgICBpZiAoZXJyICE9PSB2YWxpZGF0b3IudmFsaWRhdGlvbkVycm9yLk5PTkUpCiAgICAgICAgcmV0dXJuIGVycjsKCgoKICAgIC8vIHZhbGlkYXRlIE9yaWdpbi5zdWJvcmlnaW4KICAgIGVyciA9IG1lc3NhZ2VWYWxpZGF0b3IudmFsaWRhdGVTdHJpbmdQb2ludGVyKG9mZnNldCArIGNvZGVjLmtTdHJ1Y3RIZWFkZXJTaXplICsgMjQsIGZhbHNlKQogICAgaWYgKGVyciAhPT0gdmFsaWRhdG9yLnZhbGlkYXRpb25FcnJvci5OT05FKQogICAgICAgIHJldHVybiBlcnI7CgoKICAgIHJldHVybiB2YWxpZGF0b3IudmFsaWRhdGlvbkVycm9yLk5PTkU7CiAgfTsKCiAgT3JpZ2luLmVuY29kZWRTaXplID0gY29kZWMua1N0cnVjdEhlYWRlclNpemUgKyAzMjsKCiAgT3JpZ2luLmRlY29kZSA9IGZ1bmN0aW9uKGRlY29kZXIpIHsKICAgIHZhciBwYWNrZWQ7CiAgICB2YXIgdmFsID0gbmV3IE9yaWdpbigpOwogICAgdmFyIG51bWJlck9mQnl0ZXMgPSBkZWNvZGVyLnJlYWRVaW50MzIoKTsKICAgIHZhciB2ZXJzaW9uID0gZGVjb2Rlci5yZWFkVWludDMyKCk7CiAgICB2YWwuc2NoZW1lID0gZGVjb2Rlci5kZWNvZGVTdHJ1Y3QoY29kZWMuU3RyaW5nKTsKICAgIHZhbC5ob3N0ID0gZGVjb2Rlci5kZWNvZGVTdHJ1Y3QoY29kZWMuU3RyaW5nKTsKICAgIHZhbC5wb3J0ID0gZGVjb2Rlci5kZWNvZGVTdHJ1Y3QoY29kZWMuVWludDE2KTsKICAgIHBhY2tlZCA9IGRlY29kZXIucmVhZFVpbnQ4KCk7CiAgICB2YWwudW5pcXVlID0gKHBhY2tlZCA+PiAwKSAmIDEgPyB0cnVlIDogZmFsc2U7CiAgICBkZWNvZGVyLnNraXAoMSk7CiAgICBkZWNvZGVyLnNraXAoMSk7CiAgICBkZWNvZGVyLnNraXAoMSk7CiAgICBkZWNvZGVyLnNraXAoMSk7CiAgICBkZWNvZGVyLnNraXAoMSk7CiAgICB2YWwuc3Vib3JpZ2luID0gZGVjb2Rlci5kZWNvZGVTdHJ1Y3QoY29kZWMuU3RyaW5nKTsKICAgIHJldHVybiB2YWw7CiAgfTsKCiAgT3JpZ2luLmVuY29kZSA9IGZ1bmN0aW9uKGVuY29kZXIsIHZhbCkgewogICAgdmFyIHBhY2tlZDsKICAgIGVuY29kZXIud3JpdGVVaW50MzIoT3JpZ2luLmVuY29kZWRTaXplKTsKICAgIGVuY29kZXIud3JpdGVVaW50MzIoMCk7CiAgICBlbmNvZGVyLmVuY29kZVN0cnVjdChjb2RlYy5TdHJpbmcsIHZhbC5zY2hlbWUpOwogICAgZW5jb2Rlci5lbmNvZGVTdHJ1Y3QoY29kZWMuU3RyaW5nLCB2YWwuaG9zdCk7CiAgICBlbmNvZGVyLmVuY29kZVN0cnVjdChjb2RlYy5VaW50MTYsIHZhbC5wb3J0KTsKICAgIHBhY2tlZCA9IDA7CiAgICBwYWNrZWQgfD0gKHZhbC51bmlxdWUgJiAxKSA8PCAwCiAgICBlbmNvZGVyLndyaXRlVWludDgocGFja2VkKTsKICAgIGVuY29kZXIuc2tpcCgxKTsKICAgIGVuY29kZXIuc2tpcCgxKTsKICAgIGVuY29kZXIuc2tpcCgxKTsKICAgIGVuY29kZXIuc2tpcCgxKTsKICAgIGVuY29kZXIuc2tpcCgxKTsKICAgIGVuY29kZXIuZW5jb2RlU3RydWN0KGNvZGVjLlN0cmluZywgdmFsLnN1Ym9yaWdpbik7CiAgfTsKICBleHBvcnRzLk9yaWdpbiA9IE9yaWdpbjsKfSkoKTsvLyBDb3B5cmlnaHQgMjAxNCBUaGUgQ2hyb21pdW0gQXV0aG9ycy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KLy8gVXNlIG9mIHRoaXMgc291cmNlIGNvZGUgaXMgZ292ZXJuZWQgYnkgYSBCU0Qtc3R5bGUgbGljZW5zZSB0aGF0IGNhbiBiZQovLyBmb3VuZCBpbiB0aGUgTElDRU5TRSBmaWxlLgoKJ3VzZSBzdHJpY3QnOwoKKGZ1bmN0aW9uKCkgewogIHZhciBtb2pvbUlkID0gJ3VybC9tb2pvL3VybC5tb2pvbSc7CiAgaWYgKG1vam8uaW50ZXJuYWwuaXNNb2pvbUxvYWRlZChtb2pvbUlkKSkgewogICAgY29uc29sZS53YXJuKCdUaGUgZm9sbG93aW5nIG1vam9tIGlzIGxvYWRlZCBtdWx0aXBsZSB0aW1lczogJyArIG1vam9tSWQpOwogICAgcmV0dXJuOwogIH0KICBtb2pvLmludGVybmFsLm1hcmtNb2pvbUxvYWRlZChtb2pvbUlkKTsKICB2YXIgYmluZGluZ3MgPSBtb2pvOwogIHZhciBhc3NvY2lhdGVkQmluZGluZ3MgPSBtb2pvOwogIHZhciBjb2RlYyA9IG1vam8uaW50ZXJuYWw7CiAgdmFyIHZhbGlkYXRvciA9IG1vam8uaW50ZXJuYWw7CgogIHZhciBleHBvcnRzID0gbW9qby5pbnRlcm5hbC5leHBvc2VOYW1lc3BhY2UoJ3VybC5tb2pvbScpOwoKCgogIGZ1bmN0aW9uIFVybCh2YWx1ZXMpIHsKICAgIHRoaXMuaW5pdERlZmF1bHRzXygpOwogICAgdGhpcy5pbml0RmllbGRzXyh2YWx1ZXMpOwogIH0KCgogIFVybC5wcm90b3R5cGUuaW5pdERlZmF1bHRzXyA9IGZ1bmN0aW9uKCkgewogICAgdGhpcy51cmwgPSBudWxsOwogIH07CiAgVXJsLnByb3RvdHlwZS5pbml0RmllbGRzXyA9IGZ1bmN0aW9uKGZpZWxkcykgewogICAgZm9yKHZhciBmaWVsZCBpbiBmaWVsZHMpIHsKICAgICAgICBpZiAodGhpcy5oYXNPd25Qcm9wZXJ0eShmaWVsZCkpCiAgICAgICAgICB0aGlzW2ZpZWxkXSA9IGZpZWxkc1tmaWVsZF07CiAgICB9CiAgfTsKCiAgVXJsLnZhbGlkYXRlID0gZnVuY3Rpb24obWVzc2FnZVZhbGlkYXRvciwgb2Zmc2V0KSB7CiAgICB2YXIgZXJyOwogICAgZXJyID0gbWVzc2FnZVZhbGlkYXRvci52YWxpZGF0ZVN0cnVjdEhlYWRlcihvZmZzZXQsIGNvZGVjLmtTdHJ1Y3RIZWFkZXJTaXplKTsKICAgIGlmIChlcnIgIT09IHZhbGlkYXRvci52YWxpZGF0aW9uRXJyb3IuTk9ORSkKICAgICAgICByZXR1cm4gZXJyOwoKICAgIHZhciBrVmVyc2lvblNpemVzID0gWwogICAgICB7dmVyc2lvbjogMCwgbnVtQnl0ZXM6IDE2fQogICAgXTsKICAgIGVyciA9IG1lc3NhZ2VWYWxpZGF0b3IudmFsaWRhdGVTdHJ1Y3RWZXJzaW9uKG9mZnNldCwga1ZlcnNpb25TaXplcyk7CiAgICBpZiAoZXJyICE9PSB2YWxpZGF0b3IudmFsaWRhdGlvbkVycm9yLk5PTkUpCiAgICAgICAgcmV0dXJuIGVycjsKCgogICAgLy8gdmFsaWRhdGUgVXJsLnVybAogICAgZXJyID0gbWVzc2FnZVZhbGlkYXRvci52YWxpZGF0ZVN0cmluZ1BvaW50ZXIob2Zmc2V0ICsgY29kZWMua1N0cnVjdEhlYWRlclNpemUgKyAwLCBmYWxzZSkKICAgIGlmIChlcnIgIT09IHZhbGlkYXRvci52YWxpZGF0aW9uRXJyb3IuTk9ORSkKICAgICAgICByZXR1cm4gZXJyOwoKICAgIHJldHVybiB2YWxpZGF0b3IudmFsaWRhdGlvbkVycm9yLk5PTkU7CiAgfTsKCiAgVXJsLmVuY29kZWRTaXplID0gY29kZWMua1N0cnVjdEhlYWRlclNpemUgKyA4OwoKICBVcmwuZGVjb2RlID0gZnVuY3Rpb24oZGVjb2RlcikgewogICAgdmFyIHBhY2tlZDsKICAgIHZhciB2YWwgPSBuZXcgVXJsKCk7CiAgICB2YXIgbnVtYmVyT2ZCeXRlcyA9IGRlY29kZXIucmVhZFVpbnQzMigpOwogICAgdmFyIHZlcnNpb24gPSBkZWNvZGVyLnJlYWRVaW50MzIoKTsKICAgIHZhbC51cmwgPSBkZWNvZGVyLmRlY29kZVN0cnVjdChjb2RlYy5TdHJpbmcpOwogICAgcmV0dXJuIHZhbDsKICB9OwoKICBVcmwuZW5jb2RlID0gZnVuY3Rpb24oZW5jb2RlciwgdmFsKSB7CiAgICB2YXIgcGFja2VkOwogICAgZW5jb2Rlci53cml0ZVVpbnQzMihVcmwuZW5jb2RlZFNpemUpOwogICAgZW5jb2Rlci53cml0ZVVpbnQzMigwKTsKICAgIGVuY29kZXIuZW5jb2RlU3RydWN0KGNvZGVjLlN0cmluZywgdmFsLnVybCk7CiAgfTsKICBleHBvcnRzLlVybCA9IFVybDsKfSkoKTsvLyBDb3B5cmlnaHQgMjAxNCBUaGUgQ2hyb21pdW0gQXV0aG9ycy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KLy8gVXNlIG9mIHRoaXMgc291cmNlIGNvZGUgaXMgZ292ZXJuZWQgYnkgYSBCU0Qtc3R5bGUgbGljZW5zZSB0aGF0IGNhbiBiZQovLyBmb3VuZCBpbiB0aGUgTElDRU5TRSBmaWxlLgoKJ3VzZSBzdHJpY3QnOwoKKGZ1bmN0aW9uKCkgewogIHZhciBtb2pvbUlkID0gJ21lZGlhL21vam8vaW50ZXJmYWNlcy9taXJyb3Jfc2VydmljZV9yZW1vdGluZy5tb2pvbSc7CiAgaWYgKG1vam8uaW50ZXJuYWwuaXNNb2pvbUxvYWRlZChtb2pvbUlkKSkgewogICAgY29uc29sZS53YXJuKCdUaGUgZm9sbG93aW5nIG1vam9tIGlzIGxvYWRlZCBtdWx0aXBsZSB0aW1lczogJyArIG1vam9tSWQpOwogICAgcmV0dXJuOwogIH0KICBtb2pvLmludGVybmFsLm1hcmtNb2pvbUxvYWRlZChtb2pvbUlkKTsKICB2YXIgYmluZGluZ3MgPSBtb2pvOwogIHZhciBhc3NvY2lhdGVkQmluZGluZ3MgPSBtb2pvOwogIHZhciBjb2RlYyA9IG1vam8uaW50ZXJuYWw7CiAgdmFyIHZhbGlkYXRvciA9IG1vam8uaW50ZXJuYWw7CgogIHZhciBleHBvcnRzID0gbW9qby5pbnRlcm5hbC5leHBvc2VOYW1lc3BhY2UoJ21lZGlhLm1vam9tJyk7CiAgdmFyIHJlbW90aW5nX2NvbW1vbiQgPQogICAgICBtb2pvLmludGVybmFsLmV4cG9zZU5hbWVzcGFjZSgnbWVkaWEubW9qb20nKTsKICBpZiAobW9qby5jb25maWcuYXV0b0xvYWRNb2pvbURlcHMpIHsKICAgIG1vam8uaW50ZXJuYWwubG9hZE1vam9tSWZOZWNlc3NhcnkoCiAgICAgICAgJ21lZGlhL21vam8vaW50ZXJmYWNlcy9yZW1vdGluZ19jb21tb24ubW9qb20nLCAncmVtb3RpbmdfY29tbW9uLm1vam9tLmpzJyk7CiAgfQoKCgogIGZ1bmN0aW9uIE1pcnJvclNlcnZpY2VSZW1vdGVyX1N0YXJ0X1BhcmFtcyh2YWx1ZXMpIHsKICAgIHRoaXMuaW5pdERlZmF1bHRzXygpOwogICAgdGhpcy5pbml0RmllbGRzXyh2YWx1ZXMpOwogIH0KCgogIE1pcnJvclNlcnZpY2VSZW1vdGVyX1N0YXJ0X1BhcmFtcy5wcm90b3R5cGUuaW5pdERlZmF1bHRzXyA9IGZ1bmN0aW9uKCkgewogIH07CiAgTWlycm9yU2VydmljZVJlbW90ZXJfU3RhcnRfUGFyYW1zLnByb3RvdHlwZS5pbml0RmllbGRzXyA9IGZ1bmN0aW9uKGZpZWxkcykgewogICAgZm9yKHZhciBmaWVsZCBpbiBmaWVsZHMpIHsKICAgICAgICBpZiAodGhpcy5oYXNPd25Qcm9wZXJ0eShmaWVsZCkpCiAgICAgICAgICB0aGlzW2ZpZWxkXSA9IGZpZWxkc1tmaWVsZF07CiAgICB9CiAgfTsKCiAgTWlycm9yU2VydmljZVJlbW90ZXJfU3RhcnRfUGFyYW1zLnZhbGlkYXRlID0gZnVuY3Rpb24obWVzc2FnZVZhbGlkYXRvciwgb2Zmc2V0KSB7CiAgICB2YXIgZXJyOwogICAgZXJyID0gbWVzc2FnZVZhbGlkYXRvci52YWxpZGF0ZVN0cnVjdEhlYWRlcihvZmZzZXQsIGNvZGVjLmtTdHJ1Y3RIZWFkZXJTaXplKTsKICAgIGlmIChlcnIgIT09IHZhbGlkYXRvci52YWxpZGF0aW9uRXJyb3IuTk9ORSkKICAgICAgICByZXR1cm4gZXJyOwoKICAgIHZhciBrVmVyc2lvblNpemVzID0gWwogICAgICB7dmVyc2lvbjogMCwgbnVtQnl0ZXM6IDh9CiAgICBdOwogICAgZXJyID0gbWVzc2FnZVZhbGlkYXRvci52YWxpZGF0ZVN0cnVjdFZlcnNpb24ob2Zmc2V0LCBrVmVyc2lvblNpemVzKTsKICAgIGlmIChlcnIgIT09IHZhbGlkYXRvci52YWxpZGF0aW9uRXJyb3IuTk9ORSkKICAgICAgICByZXR1cm4gZXJyOwoKICAgIHJldHVybiB2YWxpZGF0b3IudmFsaWRhdGlvbkVycm9yLk5PTkU7CiAgfTsKCiAgTWlycm9yU2VydmljZVJlbW90ZXJfU3RhcnRfUGFyYW1zLmVuY29kZWRTaXplID0gY29kZWMua1N0cnVjdEhlYWRlclNpemUgKyAwOwoKICBNaXJyb3JTZXJ2aWNlUmVtb3Rlcl9TdGFydF9QYXJhbXMuZGVjb2RlID0gZnVuY3Rpb24oZGVjb2RlcikgewogICAgdmFyIHBhY2tlZDsKICAgIHZhciB2YWwgPSBuZXcgTWlycm9yU2VydmljZVJlbW90ZXJfU3RhcnRfUGFyYW1zKCk7CiAgICB2YXIgbnVtYmVyT2ZCeXRlcyA9IGRlY29kZXIucmVhZFVpbnQzMigpOwogICAgdmFyIHZlcnNpb24gPSBkZWNvZGVyLnJlYWRVaW50MzIoKTsKICAgIHJldHVybiB2YWw7CiAgfTsKCiAgTWlycm9yU2VydmljZVJlbW90ZXJfU3RhcnRfUGFyYW1zLmVuY29kZSA9IGZ1bmN0aW9uKGVuY29kZXIsIHZhbCkgewogICAgdmFyIHBhY2tlZDsKICAgIGVuY29kZXIud3JpdGVVaW50MzIoTWlycm9yU2VydmljZVJlbW90ZXJfU3RhcnRfUGFyYW1zLmVuY29kZWRTaXplKTsKICAgIGVuY29kZXIud3JpdGVVaW50MzIoMCk7CiAgfTsKICBmdW5jdGlvbiBNaXJyb3JTZXJ2aWNlUmVtb3Rlcl9TdGFydERhdGFTdHJlYW1zX1BhcmFtcyh2YWx1ZXMpIHsKICAgIHRoaXMuaW5pdERlZmF1bHRzXygpOwogICAgdGhpcy5pbml0RmllbGRzXyh2YWx1ZXMpOwogIH0KCgogIE1pcnJvclNlcnZpY2VSZW1vdGVyX1N0YXJ0RGF0YVN0cmVhbXNfUGFyYW1zLnByb3RvdHlwZS5pbml0RGVmYXVsdHNfID0gZnVuY3Rpb24oKSB7CiAgICB0aGlzLmhhc0F1ZGlvID0gZmFsc2U7CiAgICB0aGlzLmhhc1ZpZGVvID0gZmFsc2U7CiAgfTsKICBNaXJyb3JTZXJ2aWNlUmVtb3Rlcl9TdGFydERhdGFTdHJlYW1zX1BhcmFtcy5wcm90b3R5cGUuaW5pdEZpZWxkc18gPSBmdW5jdGlvbihmaWVsZHMpIHsKICAgIGZvcih2YXIgZmllbGQgaW4gZmllbGRzKSB7CiAgICAgICAgaWYgKHRoaXMuaGFzT3duUHJvcGVydHkoZmllbGQpKQogICAgICAgICAgdGhpc1tmaWVsZF0gPSBmaWVsZHNbZmllbGRdOwogICAgfQogIH07CgogIE1pcnJvclNlcnZpY2VSZW1vdGVyX1N0YXJ0RGF0YVN0cmVhbXNfUGFyYW1zLnZhbGlkYXRlID0gZnVuY3Rpb24obWVzc2FnZVZhbGlkYXRvciwgb2Zmc2V0KSB7CiAgICB2YXIgZXJyOwogICAgZXJyID0gbWVzc2FnZVZhbGlkYXRvci52YWxpZGF0ZVN0cnVjdEhlYWRlcihvZmZzZXQsIGNvZGVjLmtTdHJ1Y3RIZWFkZXJTaXplKTsKICAgIGlmIChlcnIgIT09IHZhbGlkYXRvci52YWxpZGF0aW9uRXJyb3IuTk9ORSkKICAgICAgICByZXR1cm4gZXJyOwoKICAgIHZhciBrVmVyc2lvblNpemVzID0gWwogICAgICB7dmVyc2lvbjogMCwgbnVtQnl0ZXM6IDE2fQogICAgXTsKICAgIGVyciA9IG1lc3NhZ2VWYWxpZGF0b3IudmFsaWRhdGVTdHJ1Y3RWZXJzaW9uKG9mZnNldCwga1ZlcnNpb25TaXplcyk7CiAgICBpZiAoZXJyICE9PSB2YWxpZGF0b3IudmFsaWRhdGlvbkVycm9yLk5PTkUpCiAgICAgICAgcmV0dXJuIGVycjsKCgoKICAgIHJldHVybiB2YWxpZGF0b3IudmFsaWRhdGlvbkVycm9yLk5PTkU7CiAgfTsKCiAgTWlycm9yU2VydmljZVJlbW90ZXJfU3RhcnREYXRhU3RyZWFtc19QYXJhbXMuZW5jb2RlZFNpemUgPSBjb2RlYy5rU3RydWN0SGVhZGVyU2l6ZSArIDg7CgogIE1pcnJvclNlcnZpY2VSZW1vdGVyX1N0YXJ0RGF0YVN0cmVhbXNfUGFyYW1zLmRlY29kZSA9IGZ1bmN0aW9uKGRlY29kZXIpIHsKICAgIHZhciBwYWNrZWQ7CiAgICB2YXIgdmFsID0gbmV3IE1pcnJvclNlcnZpY2VSZW1vdGVyX1N0YXJ0RGF0YVN0cmVhbXNfUGFyYW1zKCk7CiAgICB2YXIgbnVtYmVyT2ZCeXRlcyA9IGRlY29kZXIucmVhZFVpbnQzMigpOwogICAgdmFyIHZlcnNpb24gPSBkZWNvZGVyLnJlYWRVaW50MzIoKTsKICAgIHBhY2tlZCA9IGRlY29kZXIucmVhZFVpbnQ4KCk7CiAgICB2YWwuaGFzQXVkaW8gPSAocGFja2VkID4+IDApICYgMSA/IHRydWUgOiBmYWxzZTsKICAgIHZhbC5oYXNWaWRlbyA9IChwYWNrZWQgPj4gMSkgJiAxID8gdHJ1ZSA6IGZhbHNlOwogICAgZGVjb2Rlci5za2lwKDEpOwogICAgZGVjb2Rlci5za2lwKDEpOwogICAgZGVjb2Rlci5za2lwKDEpOwogICAgZGVjb2Rlci5za2lwKDEpOwogICAgZGVjb2Rlci5za2lwKDEpOwogICAgZGVjb2Rlci5za2lwKDEpOwogICAgZGVjb2Rlci5za2lwKDEpOwogICAgcmV0dXJuIHZhbDsKICB9OwoKICBNaXJyb3JTZXJ2aWNlUmVtb3Rlcl9TdGFydERhdGFTdHJlYW1zX1BhcmFtcy5lbmNvZGUgPSBmdW5jdGlvbihlbmNvZGVyLCB2YWwpIHsKICAgIHZhciBwYWNrZWQ7CiAgICBlbmNvZGVyLndyaXRlVWludDMyKE1pcnJvclNlcnZpY2VSZW1vdGVyX1N0YXJ0RGF0YVN0cmVhbXNfUGFyYW1zLmVuY29kZWRTaXplKTsKICAgIGVuY29kZXIud3JpdGVVaW50MzIoMCk7CiAgICBwYWNrZWQgPSAwOwogICAgcGFja2VkIHw9ICh2YWwuaGFzQXVkaW8gJiAxKSA8PCAwCiAgICBwYWNrZWQgfD0gKHZhbC5oYXNWaWRlbyAmIDEpIDw8IDEKICAgIGVuY29kZXIud3JpdGVVaW50OChwYWNrZWQpOwogICAgZW5jb2Rlci5za2lwKDEpOwogICAgZW5jb2Rlci5za2lwKDEpOwogICAgZW5jb2Rlci5za2lwKDEpOwogICAgZW5jb2Rlci5za2lwKDEpOwogICAgZW5jb2Rlci5za2lwKDEpOwogICAgZW5jb2Rlci5za2lwKDEpOwogICAgZW5jb2Rlci5za2lwKDEpOwogIH07CiAgZnVuY3Rpb24gTWlycm9yU2VydmljZVJlbW90ZXJfU3RhcnREYXRhU3RyZWFtc19SZXNwb25zZVBhcmFtcyh2YWx1ZXMpIHsKICAgIHRoaXMuaW5pdERlZmF1bHRzXygpOwogICAgdGhpcy5pbml0RmllbGRzXyh2YWx1ZXMpOwogIH0KCgogIE1pcnJvclNlcnZpY2VSZW1vdGVyX1N0YXJ0RGF0YVN0cmVhbXNfUmVzcG9uc2VQYXJhbXMucHJvdG90eXBlLmluaXREZWZhdWx0c18gPSBmdW5jdGlvbigpIHsKICAgIHRoaXMuYXVkaW9TdHJlYW1JZCA9IDA7CiAgICB0aGlzLnZpZGVvU3RyZWFtSWQgPSAwOwogIH07CiAgTWlycm9yU2VydmljZVJlbW90ZXJfU3RhcnREYXRhU3RyZWFtc19SZXNwb25zZVBhcmFtcy5wcm90b3R5cGUuaW5pdEZpZWxkc18gPSBmdW5jdGlvbihmaWVsZHMpIHsKICAgIGZvcih2YXIgZmllbGQgaW4gZmllbGRzKSB7CiAgICAgICAgaWYgKHRoaXMuaGFzT3duUHJvcGVydHkoZmllbGQpKQogICAgICAgICAgdGhpc1tmaWVsZF0gPSBmaWVsZHNbZmllbGRdOwogICAgfQogIH07CgogIE1pcnJvclNlcnZpY2VSZW1vdGVyX1N0YXJ0RGF0YVN0cmVhbXNfUmVzcG9uc2VQYXJhbXMudmFsaWRhdGUgPSBmdW5jdGlvbihtZXNzYWdlVmFsaWRhdG9yLCBvZmZzZXQpIHsKICAgIHZhciBlcnI7CiAgICBlcnIgPSBtZXNzYWdlVmFsaWRhdG9yLnZhbGlkYXRlU3RydWN0SGVhZGVyKG9mZnNldCwgY29kZWMua1N0cnVjdEhlYWRlclNpemUpOwogICAgaWYgKGVyciAhPT0gdmFsaWRhdG9yLnZhbGlkYXRpb25FcnJvci5OT05FKQogICAgICAgIHJldHVybiBlcnI7CgogICAgdmFyIGtWZXJzaW9uU2l6ZXMgPSBbCiAgICAgIHt2ZXJzaW9uOiAwLCBudW1CeXRlczogMTZ9CiAgICBdOwogICAgZXJyID0gbWVzc2FnZVZhbGlkYXRvci52YWxpZGF0ZVN0cnVjdFZlcnNpb24ob2Zmc2V0LCBrVmVyc2lvblNpemVzKTsKICAgIGlmIChlcnIgIT09IHZhbGlkYXRvci52YWxpZGF0aW9uRXJyb3IuTk9ORSkKICAgICAgICByZXR1cm4gZXJyOwoKCgogICAgcmV0dXJuIHZhbGlkYXRvci52YWxpZGF0aW9uRXJyb3IuTk9ORTsKICB9OwoKICBNaXJyb3JTZXJ2aWNlUmVtb3Rlcl9TdGFydERhdGFTdHJlYW1zX1Jlc3BvbnNlUGFyYW1zLmVuY29kZWRTaXplID0gY29kZWMua1N0cnVjdEhlYWRlclNpemUgKyA4OwoKICBNaXJyb3JTZXJ2aWNlUmVtb3Rlcl9TdGFydERhdGFTdHJlYW1zX1Jlc3BvbnNlUGFyYW1zLmRlY29kZSA9IGZ1bmN0aW9uKGRlY29kZXIpIHsKICAgIHZhciBwYWNrZWQ7CiAgICB2YXIgdmFsID0gbmV3IE1pcnJvclNlcnZpY2VSZW1vdGVyX1N0YXJ0RGF0YVN0cmVhbXNfUmVzcG9uc2VQYXJhbXMoKTsKICAgIHZhciBudW1iZXJPZkJ5dGVzID0gZGVjb2Rlci5yZWFkVWludDMyKCk7CiAgICB2YXIgdmVyc2lvbiA9IGRlY29kZXIucmVhZFVpbnQzMigpOwogICAgdmFsLmF1ZGlvU3RyZWFtSWQgPSBkZWNvZGVyLmRlY29kZVN0cnVjdChjb2RlYy5JbnQzMik7CiAgICB2YWwudmlkZW9TdHJlYW1JZCA9IGRlY29kZXIuZGVjb2RlU3RydWN0KGNvZGVjLkludDMyKTsKICAgIHJldHVybiB2YWw7CiAgfTsKCiAgTWlycm9yU2VydmljZVJlbW90ZXJfU3RhcnREYXRhU3RyZWFtc19SZXNwb25zZVBhcmFtcy5lbmNvZGUgPSBmdW5jdGlvbihlbmNvZGVyLCB2YWwpIHsKICAgIHZhciBwYWNrZWQ7CiAgICBlbmNvZGVyLndyaXRlVWludDMyKE1pcnJvclNlcnZpY2VSZW1vdGVyX1N0YXJ0RGF0YVN0cmVhbXNfUmVzcG9uc2VQYXJhbXMuZW5jb2RlZFNpemUpOwogICAgZW5jb2Rlci53cml0ZVVpbnQzMigwKTsKICAgIGVuY29kZXIuZW5jb2RlU3RydWN0KGNvZGVjLkludDMyLCB2YWwuYXVkaW9TdHJlYW1JZCk7CiAgICBlbmNvZGVyLmVuY29kZVN0cnVjdChjb2RlYy5JbnQzMiwgdmFsLnZpZGVvU3RyZWFtSWQpOwogIH07CiAgZnVuY3Rpb24gTWlycm9yU2VydmljZVJlbW90ZXJfU3RvcF9QYXJhbXModmFsdWVzKSB7CiAgICB0aGlzLmluaXREZWZhdWx0c18oKTsKICAgIHRoaXMuaW5pdEZpZWxkc18odmFsdWVzKTsKICB9CgoKICBNaXJyb3JTZXJ2aWNlUmVtb3Rlcl9TdG9wX1BhcmFtcy5wcm90b3R5cGUuaW5pdERlZmF1bHRzXyA9IGZ1bmN0aW9uKCkgewogICAgdGhpcy5yZWFzb24gPSAwOwogIH07CiAgTWlycm9yU2VydmljZVJlbW90ZXJfU3RvcF9QYXJhbXMucHJvdG90eXBlLmluaXRGaWVsZHNfID0gZnVuY3Rpb24oZmllbGRzKSB7CiAgICBmb3IodmFyIGZpZWxkIGluIGZpZWxkcykgewogICAgICAgIGlmICh0aGlzLmhhc093blByb3BlcnR5KGZpZWxkKSkKICAgICAgICAgIHRoaXNbZmllbGRdID0gZmllbGRzW2ZpZWxkXTsKICAgIH0KICB9OwoKICBNaXJyb3JTZXJ2aWNlUmVtb3Rlcl9TdG9wX1BhcmFtcy52YWxpZGF0ZSA9IGZ1bmN0aW9uKG1lc3NhZ2VWYWxpZGF0b3IsIG9mZnNldCkgewogICAgdmFyIGVycjsKICAgIGVyciA9IG1lc3NhZ2VWYWxpZGF0b3IudmFsaWRhdGVTdHJ1Y3RIZWFkZXIob2Zmc2V0LCBjb2RlYy5rU3RydWN0SGVhZGVyU2l6ZSk7CiAgICBpZiAoZXJyICE9PSB2YWxpZGF0b3IudmFsaWRhdGlvbkVycm9yLk5PTkUpCiAgICAgICAgcmV0dXJuIGVycjsKCiAgICB2YXIga1ZlcnNpb25TaXplcyA9IFsKICAgICAge3ZlcnNpb246IDAsIG51bUJ5dGVzOiAxNn0KICAgIF07CiAgICBlcnIgPSBtZXNzYWdlVmFsaWRhdG9yLnZhbGlkYXRlU3RydWN0VmVyc2lvbihvZmZzZXQsIGtWZXJzaW9uU2l6ZXMpOwogICAgaWYgKGVyciAhPT0gdmFsaWRhdG9yLnZhbGlkYXRpb25FcnJvci5OT05FKQogICAgICAgIHJldHVybiBlcnI7CgoKICAgIC8vIHZhbGlkYXRlIE1pcnJvclNlcnZpY2VSZW1vdGVyX1N0b3BfUGFyYW1zLnJlYXNvbgogICAgZXJyID0gbWVzc2FnZVZhbGlkYXRvci52YWxpZGF0ZUVudW0ob2Zmc2V0ICsgY29kZWMua1N0cnVjdEhlYWRlclNpemUgKyAwLCByZW1vdGluZ19jb21tb24kLlJlbW90aW5nU3RvcFJlYXNvbik7CiAgICBpZiAoZXJyICE9PSB2YWxpZGF0b3IudmFsaWRhdGlvbkVycm9yLk5PTkUpCiAgICAgICAgcmV0dXJuIGVycjsKCiAgICByZXR1cm4gdmFsaWRhdG9yLnZhbGlkYXRpb25FcnJvci5OT05FOwogIH07CgogIE1pcnJvclNlcnZpY2VSZW1vdGVyX1N0b3BfUGFyYW1zLmVuY29kZWRTaXplID0gY29kZWMua1N0cnVjdEhlYWRlclNpemUgKyA4OwoKICBNaXJyb3JTZXJ2aWNlUmVtb3Rlcl9TdG9wX1BhcmFtcy5kZWNvZGUgPSBmdW5jdGlvbihkZWNvZGVyKSB7CiAgICB2YXIgcGFja2VkOwogICAgdmFyIHZhbCA9IG5ldyBNaXJyb3JTZXJ2aWNlUmVtb3Rlcl9TdG9wX1BhcmFtcygpOwogICAgdmFyIG51bWJlck9mQnl0ZXMgPSBkZWNvZGVyLnJlYWRVaW50MzIoKTsKICAgIHZhciB2ZXJzaW9uID0gZGVjb2Rlci5yZWFkVWludDMyKCk7CiAgICB2YWwucmVhc29uID0gZGVjb2Rlci5kZWNvZGVTdHJ1Y3QoY29kZWMuSW50MzIpOwogICAgZGVjb2Rlci5za2lwKDEpOwogICAgZGVjb2Rlci5za2lwKDEpOwogICAgZGVjb2Rlci5za2lwKDEpOwogICAgZGVjb2Rlci5za2lwKDEpOwogICAgcmV0dXJuIHZhbDsKICB9OwoKICBNaXJyb3JTZXJ2aWNlUmVtb3Rlcl9TdG9wX1BhcmFtcy5lbmNvZGUgPSBmdW5jdGlvbihlbmNvZGVyLCB2YWwpIHsKICAgIHZhciBwYWNrZWQ7CiAgICBlbmNvZGVyLndyaXRlVWludDMyKE1pcnJvclNlcnZpY2VSZW1vdGVyX1N0b3BfUGFyYW1zLmVuY29kZWRTaXplKTsKICAgIGVuY29kZXIud3JpdGVVaW50MzIoMCk7CiAgICBlbmNvZGVyLmVuY29kZVN0cnVjdChjb2RlYy5JbnQzMiwgdmFsLnJlYXNvbik7CiAgICBlbmNvZGVyLnNraXAoMSk7CiAgICBlbmNvZGVyLnNraXAoMSk7CiAgICBlbmNvZGVyLnNraXAoMSk7CiAgICBlbmNvZGVyLnNraXAoMSk7CiAgfTsKICBmdW5jdGlvbiBNaXJyb3JTZXJ2aWNlUmVtb3Rlcl9TZW5kTWVzc2FnZVRvU2lua19QYXJhbXModmFsdWVzKSB7CiAgICB0aGlzLmluaXREZWZhdWx0c18oKTsKICAgIHRoaXMuaW5pdEZpZWxkc18odmFsdWVzKTsKICB9CgoKICBNaXJyb3JTZXJ2aWNlUmVtb3Rlcl9TZW5kTWVzc2FnZVRvU2lua19QYXJhbXMucHJvdG90eXBlLmluaXREZWZhdWx0c18gPSBmdW5jdGlvbigpIHsKICAgIHRoaXMubWVzc2FnZSA9IG51bGw7CiAgfTsKICBNaXJyb3JTZXJ2aWNlUmVtb3Rlcl9TZW5kTWVzc2FnZVRvU2lua19QYXJhbXMucHJvdG90eXBlLmluaXRGaWVsZHNfID0gZnVuY3Rpb24oZmllbGRzKSB7CiAgICBmb3IodmFyIGZpZWxkIGluIGZpZWxkcykgewogICAgICAgIGlmICh0aGlzLmhhc093blByb3BlcnR5KGZpZWxkKSkKICAgICAgICAgIHRoaXNbZmllbGRdID0gZmllbGRzW2ZpZWxkXTsKICAgIH0KICB9OwoKICBNaXJyb3JTZXJ2aWNlUmVtb3Rlcl9TZW5kTWVzc2FnZVRvU2lua19QYXJhbXMudmFsaWRhdGUgPSBmdW5jdGlvbihtZXNzYWdlVmFsaWRhdG9yLCBvZmZzZXQpIHsKICAgIHZhciBlcnI7CiAgICBlcnIgPSBtZXNzYWdlVmFsaWRhdG9yLnZhbGlkYXRlU3RydWN0SGVhZGVyKG9mZnNldCwgY29kZWMua1N0cnVjdEhlYWRlclNpemUpOwogICAgaWYgKGVyciAhPT0gdmFsaWRhdG9yLnZhbGlkYXRpb25FcnJvci5OT05FKQogICAgICAgIHJldHVybiBlcnI7CgogICAgdmFyIGtWZXJzaW9uU2l6ZXMgPSBbCiAgICAgIHt2ZXJzaW9uOiAwLCBudW1CeXRlczogMTZ9CiAgICBdOwogICAgZXJyID0gbWVzc2FnZVZhbGlkYXRvci52YWxpZGF0ZVN0cnVjdFZlcnNpb24ob2Zmc2V0LCBrVmVyc2lvblNpemVzKTsKICAgIGlmIChlcnIgIT09IHZhbGlkYXRvci52YWxpZGF0aW9uRXJyb3IuTk9ORSkKICAgICAgICByZXR1cm4gZXJyOwoKCiAgICAvLyB2YWxpZGF0ZSBNaXJyb3JTZXJ2aWNlUmVtb3Rlcl9TZW5kTWVzc2FnZVRvU2lua19QYXJhbXMubWVzc2FnZQogICAgZXJyID0gbWVzc2FnZVZhbGlkYXRvci52YWxpZGF0ZUFycmF5UG9pbnRlcihvZmZzZXQgKyBjb2RlYy5rU3RydWN0SGVhZGVyU2l6ZSArIDAsIDEsIGNvZGVjLlVpbnQ4LCBmYWxzZSwgWzBdLCAwKTsKICAgIGlmIChlcnIgIT09IHZhbGlkYXRvci52YWxpZGF0aW9uRXJyb3IuTk9ORSkKICAgICAgICByZXR1cm4gZXJyOwoKICAgIHJldHVybiB2YWxpZGF0b3IudmFsaWRhdGlvbkVycm9yLk5PTkU7CiAgfTsKCiAgTWlycm9yU2VydmljZVJlbW90ZXJfU2VuZE1lc3NhZ2VUb1NpbmtfUGFyYW1zLmVuY29kZWRTaXplID0gY29kZWMua1N0cnVjdEhlYWRlclNpemUgKyA4OwoKICBNaXJyb3JTZXJ2aWNlUmVtb3Rlcl9TZW5kTWVzc2FnZVRvU2lua19QYXJhbXMuZGVjb2RlID0gZnVuY3Rpb24oZGVjb2RlcikgewogICAgdmFyIHBhY2tlZDsKICAgIHZhciB2YWwgPSBuZXcgTWlycm9yU2VydmljZVJlbW90ZXJfU2VuZE1lc3NhZ2VUb1NpbmtfUGFyYW1zKCk7CiAgICB2YXIgbnVtYmVyT2ZCeXRlcyA9IGRlY29kZXIucmVhZFVpbnQzMigpOwogICAgdmFyIHZlcnNpb24gPSBkZWNvZGVyLnJlYWRVaW50MzIoKTsKICAgIHZhbC5tZXNzYWdlID0gZGVjb2Rlci5kZWNvZGVBcnJheVBvaW50ZXIoY29kZWMuVWludDgpOwogICAgcmV0dXJuIHZhbDsKICB9OwoKICBNaXJyb3JTZXJ2aWNlUmVtb3Rlcl9TZW5kTWVzc2FnZVRvU2lua19QYXJhbXMuZW5jb2RlID0gZnVuY3Rpb24oZW5jb2RlciwgdmFsKSB7CiAgICB2YXIgcGFja2VkOwogICAgZW5jb2Rlci53cml0ZVVpbnQzMihNaXJyb3JTZXJ2aWNlUmVtb3Rlcl9TZW5kTWVzc2FnZVRvU2lua19QYXJhbXMuZW5jb2RlZFNpemUpOwogICAgZW5jb2Rlci53cml0ZVVpbnQzMigwKTsKICAgIGVuY29kZXIuZW5jb2RlQXJyYXlQb2ludGVyKGNvZGVjLlVpbnQ4LCB2YWwubWVzc2FnZSk7CiAgfTsKICBmdW5jdGlvbiBNaXJyb3JTZXJ2aWNlUmVtb3Rlcl9Fc3RpbWF0ZVRyYW5zbWlzc2lvbkNhcGFjaXR5X1BhcmFtcyh2YWx1ZXMpIHsKICAgIHRoaXMuaW5pdERlZmF1bHRzXygpOwogICAgdGhpcy5pbml0RmllbGRzXyh2YWx1ZXMpOwogIH0KCgogIE1pcnJvclNlcnZpY2VSZW1vdGVyX0VzdGltYXRlVHJhbnNtaXNzaW9uQ2FwYWNpdHlfUGFyYW1zLnByb3RvdHlwZS5pbml0RGVmYXVsdHNfID0gZnVuY3Rpb24oKSB7CiAgfTsKICBNaXJyb3JTZXJ2aWNlUmVtb3Rlcl9Fc3RpbWF0ZVRyYW5zbWlzc2lvbkNhcGFjaXR5X1BhcmFtcy5wcm90b3R5cGUuaW5pdEZpZWxkc18gPSBmdW5jdGlvbihmaWVsZHMpIHsKICAgIGZvcih2YXIgZmllbGQgaW4gZmllbGRzKSB7CiAgICAgICAgaWYgKHRoaXMuaGFzT3duUHJvcGVydHkoZmllbGQpKQogICAgICAgICAgdGhpc1tmaWVsZF0gPSBmaWVsZHNbZmllbGRdOwogICAgfQogIH07CgogIE1pcnJvclNlcnZpY2VSZW1vdGVyX0VzdGltYXRlVHJhbnNtaXNzaW9uQ2FwYWNpdHlfUGFyYW1zLnZhbGlkYXRlID0gZnVuY3Rpb24obWVzc2FnZVZhbGlkYXRvciwgb2Zmc2V0KSB7CiAgICB2YXIgZXJyOwogICAgZXJyID0gbWVzc2FnZVZhbGlkYXRvci52YWxpZGF0ZVN0cnVjdEhlYWRlcihvZmZzZXQsIGNvZGVjLmtTdHJ1Y3RIZWFkZXJTaXplKTsKICAgIGlmIChlcnIgIT09IHZhbGlkYXRvci52YWxpZGF0aW9uRXJyb3IuTk9ORSkKICAgICAgICByZXR1cm4gZXJyOwoKICAgIHZhciBrVmVyc2lvblNpemVzID0gWwogICAgICB7dmVyc2lvbjogMCwgbnVtQnl0ZXM6IDh9CiAgICBdOwogICAgZXJyID0gbWVzc2FnZVZhbGlkYXRvci52YWxpZGF0ZVN0cnVjdFZlcnNpb24ob2Zmc2V0LCBrVmVyc2lvblNpemVzKTsKICAgIGlmIChlcnIgIT09IHZhbGlkYXRvci52YWxpZGF0aW9uRXJyb3IuTk9ORSkKICAgICAgICByZXR1cm4gZXJyOwoKICAgIHJldHVybiB2YWxpZGF0b3IudmFsaWRhdGlvbkVycm9yLk5PTkU7CiAgfTsKCiAgTWlycm9yU2VydmljZVJlbW90ZXJfRXN0aW1hdGVUcmFuc21pc3Npb25DYXBhY2l0eV9QYXJhbXMuZW5jb2RlZFNpemUgPSBjb2RlYy5rU3RydWN0SGVhZGVyU2l6ZSArIDA7CgogIE1pcnJvclNlcnZpY2VSZW1vdGVyX0VzdGltYXRlVHJhbnNtaXNzaW9uQ2FwYWNpdHlfUGFyYW1zLmRlY29kZSA9IGZ1bmN0aW9uKGRlY29kZXIpIHsKICAgIHZhciBwYWNrZWQ7CiAgICB2YXIgdmFsID0gbmV3IE1pcnJvclNlcnZpY2VSZW1vdGVyX0VzdGltYXRlVHJhbnNtaXNzaW9uQ2FwYWNpdHlfUGFyYW1zKCk7CiAgICB2YXIgbnVtYmVyT2ZCeXRlcyA9IGRlY29kZXIucmVhZFVpbnQzMigpOwogICAgdmFyIHZlcnNpb24gPSBkZWNvZGVyLnJlYWRVaW50MzIoKTsKICAgIHJldHVybiB2YWw7CiAgfTsKCiAgTWlycm9yU2VydmljZVJlbW90ZXJfRXN0aW1hdGVUcmFuc21pc3Npb25DYXBhY2l0eV9QYXJhbXMuZW5jb2RlID0gZnVuY3Rpb24oZW5jb2RlciwgdmFsKSB7CiAgICB2YXIgcGFja2VkOwogICAgZW5jb2Rlci53cml0ZVVpbnQzMihNaXJyb3JTZXJ2aWNlUmVtb3Rlcl9Fc3RpbWF0ZVRyYW5zbWlzc2lvbkNhcGFjaXR5X1BhcmFtcy5lbmNvZGVkU2l6ZSk7CiAgICBlbmNvZGVyLndyaXRlVWludDMyKDApOwogIH07CiAgZnVuY3Rpb24gTWlycm9yU2VydmljZVJlbW90ZXJfRXN0aW1hdGVUcmFuc21pc3Npb25DYXBhY2l0eV9SZXNwb25zZVBhcmFtcyh2YWx1ZXMpIHsKICAgIHRoaXMuaW5pdERlZmF1bHRzXygpOwogICAgdGhpcy5pbml0RmllbGRzXyh2YWx1ZXMpOwogIH0KCgogIE1pcnJvclNlcnZpY2VSZW1vdGVyX0VzdGltYXRlVHJhbnNtaXNzaW9uQ2FwYWNpdHlfUmVzcG9uc2VQYXJhbXMucHJvdG90eXBlLmluaXREZWZhdWx0c18gPSBmdW5jdGlvbigpIHsKICAgIHRoaXMucmF0ZSA9IDA7CiAgfTsKICBNaXJyb3JTZXJ2aWNlUmVtb3Rlcl9Fc3RpbWF0ZVRyYW5zbWlzc2lvbkNhcGFjaXR5X1Jlc3BvbnNlUGFyYW1zLnByb3RvdHlwZS5pbml0RmllbGRzXyA9IGZ1bmN0aW9uKGZpZWxkcykgewogICAgZm9yKHZhciBmaWVsZCBpbiBmaWVsZHMpIHsKICAgICAgICBpZiAodGhpcy5oYXNPd25Qcm9wZXJ0eShmaWVsZCkpCiAgICAgICAgICB0aGlzW2ZpZWxkXSA9IGZpZWxkc1tmaWVsZF07CiAgICB9CiAgfTsKCiAgTWlycm9yU2VydmljZVJlbW90ZXJfRXN0aW1hdGVUcmFuc21pc3Npb25DYXBhY2l0eV9SZXNwb25zZVBhcmFtcy52YWxpZGF0ZSA9IGZ1bmN0aW9uKG1lc3NhZ2VWYWxpZGF0b3IsIG9mZnNldCkgewogICAgdmFyIGVycjsKICAgIGVyciA9IG1lc3NhZ2VWYWxpZGF0b3IudmFsaWRhdGVTdHJ1Y3RIZWFkZXIob2Zmc2V0LCBjb2RlYy5rU3RydWN0SGVhZGVyU2l6ZSk7CiAgICBpZiAoZXJyICE9PSB2YWxpZGF0b3IudmFsaWRhdGlvbkVycm9yLk5PTkUpCiAgICAgICAgcmV0dXJuIGVycjsKCiAgICB2YXIga1ZlcnNpb25TaXplcyA9IFsKICAgICAge3ZlcnNpb246IDAsIG51bUJ5dGVzOiAxNn0KICAgIF07CiAgICBlcnIgPSBtZXNzYWdlVmFsaWRhdG9yLnZhbGlkYXRlU3RydWN0VmVyc2lvbihvZmZzZXQsIGtWZXJzaW9uU2l6ZXMpOwogICAgaWYgKGVyciAhPT0gdmFsaWRhdG9yLnZhbGlkYXRpb25FcnJvci5OT05FKQogICAgICAgIHJldHVybiBlcnI7CgoKICAgIHJldHVybiB2YWxpZGF0b3IudmFsaWRhdGlvbkVycm9yLk5PTkU7CiAgfTsKCiAgTWlycm9yU2VydmljZVJlbW90ZXJfRXN0aW1hdGVUcmFuc21pc3Npb25DYXBhY2l0eV9SZXNwb25zZVBhcmFtcy5lbmNvZGVkU2l6ZSA9IGNvZGVjLmtTdHJ1Y3RIZWFkZXJTaXplICsgODsKCiAgTWlycm9yU2VydmljZVJlbW90ZXJfRXN0aW1hdGVUcmFuc21pc3Npb25DYXBhY2l0eV9SZXNwb25zZVBhcmFtcy5kZWNvZGUgPSBmdW5jdGlvbihkZWNvZGVyKSB7CiAgICB2YXIgcGFja2VkOwogICAgdmFyIHZhbCA9IG5ldyBNaXJyb3JTZXJ2aWNlUmVtb3Rlcl9Fc3RpbWF0ZVRyYW5zbWlzc2lvbkNhcGFjaXR5X1Jlc3BvbnNlUGFyYW1zKCk7CiAgICB2YXIgbnVtYmVyT2ZCeXRlcyA9IGRlY29kZXIucmVhZFVpbnQzMigpOwogICAgdmFyIHZlcnNpb24gPSBkZWNvZGVyLnJlYWRVaW50MzIoKTsKICAgIHZhbC5yYXRlID0gZGVjb2Rlci5kZWNvZGVTdHJ1Y3QoY29kZWMuRG91YmxlKTsKICAgIHJldHVybiB2YWw7CiAgfTsKCiAgTWlycm9yU2VydmljZVJlbW90ZXJfRXN0aW1hdGVUcmFuc21pc3Npb25DYXBhY2l0eV9SZXNwb25zZVBhcmFtcy5lbmNvZGUgPSBmdW5jdGlvbihlbmNvZGVyLCB2YWwpIHsKICAgIHZhciBwYWNrZWQ7CiAgICBlbmNvZGVyLndyaXRlVWludDMyKE1pcnJvclNlcnZpY2VSZW1vdGVyX0VzdGltYXRlVHJhbnNtaXNzaW9uQ2FwYWNpdHlfUmVzcG9uc2VQYXJhbXMuZW5jb2RlZFNpemUpOwogICAgZW5jb2Rlci53cml0ZVVpbnQzMigwKTsKICAgIGVuY29kZXIuZW5jb2RlU3RydWN0KGNvZGVjLkRvdWJsZSwgdmFsLnJhdGUpOwogIH07CiAgZnVuY3Rpb24gTWlycm9yU2VydmljZVJlbW90aW5nU291cmNlX09uU2lua0F2YWlsYWJsZV9QYXJhbXModmFsdWVzKSB7CiAgICB0aGlzLmluaXREZWZhdWx0c18oKTsKICAgIHRoaXMuaW5pdEZpZWxkc18odmFsdWVzKTsKICB9CgoKICBNaXJyb3JTZXJ2aWNlUmVtb3RpbmdTb3VyY2VfT25TaW5rQXZhaWxhYmxlX1BhcmFtcy5wcm90b3R5cGUuaW5pdERlZmF1bHRzXyA9IGZ1bmN0aW9uKCkgewogICAgdGhpcy5tZXRhZGF0YSA9IG51bGw7CiAgfTsKICBNaXJyb3JTZXJ2aWNlUmVtb3RpbmdTb3VyY2VfT25TaW5rQXZhaWxhYmxlX1BhcmFtcy5wcm90b3R5cGUuaW5pdEZpZWxkc18gPSBmdW5jdGlvbihmaWVsZHMpIHsKICAgIGZvcih2YXIgZmllbGQgaW4gZmllbGRzKSB7CiAgICAgICAgaWYgKHRoaXMuaGFzT3duUHJvcGVydHkoZmllbGQpKQogICAgICAgICAgdGhpc1tmaWVsZF0gPSBmaWVsZHNbZmllbGRdOwogICAgfQogIH07CgogIE1pcnJvclNlcnZpY2VSZW1vdGluZ1NvdXJjZV9PblNpbmtBdmFpbGFibGVfUGFyYW1zLnZhbGlkYXRlID0gZnVuY3Rpb24obWVzc2FnZVZhbGlkYXRvciwgb2Zmc2V0KSB7CiAgICB2YXIgZXJyOwogICAgZXJyID0gbWVzc2FnZVZhbGlkYXRvci52YWxpZGF0ZVN0cnVjdEhlYWRlcihvZmZzZXQsIGNvZGVjLmtTdHJ1Y3RIZWFkZXJTaXplKTsKICAgIGlmIChlcnIgIT09IHZhbGlkYXRvci52YWxpZGF0aW9uRXJyb3IuTk9ORSkKICAgICAgICByZXR1cm4gZXJyOwoKICAgIHZhciBrVmVyc2lvblNpemVzID0gWwogICAgICB7dmVyc2lvbjogMCwgbnVtQnl0ZXM6IDE2fQogICAgXTsKICAgIGVyciA9IG1lc3NhZ2VWYWxpZGF0b3IudmFsaWRhdGVTdHJ1Y3RWZXJzaW9uKG9mZnNldCwga1ZlcnNpb25TaXplcyk7CiAgICBpZiAoZXJyICE9PSB2YWxpZGF0b3IudmFsaWRhdGlvbkVycm9yLk5PTkUpCiAgICAgICAgcmV0dXJuIGVycjsKCgogICAgLy8gdmFsaWRhdGUgTWlycm9yU2VydmljZVJlbW90aW5nU291cmNlX09uU2lua0F2YWlsYWJsZV9QYXJhbXMubWV0YWRhdGEKICAgIGVyciA9IG1lc3NhZ2VWYWxpZGF0b3IudmFsaWRhdGVTdHJ1Y3RQb2ludGVyKG9mZnNldCArIGNvZGVjLmtTdHJ1Y3RIZWFkZXJTaXplICsgMCwgcmVtb3RpbmdfY29tbW9uJC5SZW1vdGluZ1NpbmtNZXRhZGF0YSwgZmFsc2UpOwogICAgaWYgKGVyciAhPT0gdmFsaWRhdG9yLnZhbGlkYXRpb25FcnJvci5OT05FKQogICAgICAgIHJldHVybiBlcnI7CgogICAgcmV0dXJuIHZhbGlkYXRvci52YWxpZGF0aW9uRXJyb3IuTk9ORTsKICB9OwoKICBNaXJyb3JTZXJ2aWNlUmVtb3RpbmdTb3VyY2VfT25TaW5rQXZhaWxhYmxlX1BhcmFtcy5lbmNvZGVkU2l6ZSA9IGNvZGVjLmtTdHJ1Y3RIZWFkZXJTaXplICsgODsKCiAgTWlycm9yU2VydmljZVJlbW90aW5nU291cmNlX09uU2lua0F2YWlsYWJsZV9QYXJhbXMuZGVjb2RlID0gZnVuY3Rpb24oZGVjb2RlcikgewogICAgdmFyIHBhY2tlZDsKICAgIHZhciB2YWwgPSBuZXcgTWlycm9yU2VydmljZVJlbW90aW5nU291cmNlX09uU2lua0F2YWlsYWJsZV9QYXJhbXMoKTsKICAgIHZhciBudW1iZXJPZkJ5dGVzID0gZGVjb2Rlci5yZWFkVWludDMyKCk7CiAgICB2YXIgdmVyc2lvbiA9IGRlY29kZXIucmVhZFVpbnQzMigpOwogICAgdmFsLm1ldGFkYXRhID0gZGVjb2Rlci5kZWNvZGVTdHJ1Y3RQb2ludGVyKHJlbW90aW5nX2NvbW1vbiQuUmVtb3RpbmdTaW5rTWV0YWRhdGEpOwogICAgcmV0dXJuIHZhbDsKICB9OwoKICBNaXJyb3JTZXJ2aWNlUmVtb3RpbmdTb3VyY2VfT25TaW5rQXZhaWxhYmxlX1BhcmFtcy5lbmNvZGUgPSBmdW5jdGlvbihlbmNvZGVyLCB2YWwpIHsKICAgIHZhciBwYWNrZWQ7CiAgICBlbmNvZGVyLndyaXRlVWludDMyKE1pcnJvclNlcnZpY2VSZW1vdGluZ1NvdXJjZV9PblNpbmtBdmFpbGFibGVfUGFyYW1zLmVuY29kZWRTaXplKTsKICAgIGVuY29kZXIud3JpdGVVaW50MzIoMCk7CiAgICBlbmNvZGVyLmVuY29kZVN0cnVjdFBvaW50ZXIocmVtb3RpbmdfY29tbW9uJC5SZW1vdGluZ1NpbmtNZXRhZGF0YSwgdmFsLm1ldGFkYXRhKTsKICB9OwogIGZ1bmN0aW9uIE1pcnJvclNlcnZpY2VSZW1vdGluZ1NvdXJjZV9Pbk1lc3NhZ2VGcm9tU2lua19QYXJhbXModmFsdWVzKSB7CiAgICB0aGlzLmluaXREZWZhdWx0c18oKTsKICAgIHRoaXMuaW5pdEZpZWxkc18odmFsdWVzKTsKICB9CgoKICBNaXJyb3JTZXJ2aWNlUmVtb3RpbmdTb3VyY2VfT25NZXNzYWdlRnJvbVNpbmtfUGFyYW1zLnByb3RvdHlwZS5pbml0RGVmYXVsdHNfID0gZnVuY3Rpb24oKSB7CiAgICB0aGlzLm1lc3NhZ2UgPSBudWxsOwogIH07CiAgTWlycm9yU2VydmljZVJlbW90aW5nU291cmNlX09uTWVzc2FnZUZyb21TaW5rX1BhcmFtcy5wcm90b3R5cGUuaW5pdEZpZWxkc18gPSBmdW5jdGlvbihmaWVsZHMpIHsKICAgIGZvcih2YXIgZmllbGQgaW4gZmllbGRzKSB7CiAgICAgICAgaWYgKHRoaXMuaGFzT3duUHJvcGVydHkoZmllbGQpKQogICAgICAgICAgdGhpc1tmaWVsZF0gPSBmaWVsZHNbZmllbGRdOwogICAgfQogIH07CgogIE1pcnJvclNlcnZpY2VSZW1vdGluZ1NvdXJjZV9Pbk1lc3NhZ2VGcm9tU2lua19QYXJhbXMudmFsaWRhdGUgPSBmdW5jdGlvbihtZXNzYWdlVmFsaWRhdG9yLCBvZmZzZXQpIHsKICAgIHZhciBlcnI7CiAgICBlcnIgPSBtZXNzYWdlVmFsaWRhdG9yLnZhbGlkYXRlU3RydWN0SGVhZGVyKG9mZnNldCwgY29kZWMua1N0cnVjdEhlYWRlclNpemUpOwogICAgaWYgKGVyciAhPT0gdmFsaWRhdG9yLnZhbGlkYXRpb25FcnJvci5OT05FKQogICAgICAgIHJldHVybiBlcnI7CgogICAgdmFyIGtWZXJzaW9uU2l6ZXMgPSBbCiAgICAgIHt2ZXJzaW9uOiAwLCBudW1CeXRlczogMTZ9CiAgICBdOwogICAgZXJyID0gbWVzc2FnZVZhbGlkYXRvci52YWxpZGF0ZVN0cnVjdFZlcnNpb24ob2Zmc2V0LCBrVmVyc2lvblNpemVzKTsKICAgIGlmIChlcnIgIT09IHZhbGlkYXRvci52YWxpZGF0aW9uRXJyb3IuTk9ORSkKICAgICAgICByZXR1cm4gZXJyOwoKCiAgICAvLyB2YWxpZGF0ZSBNaXJyb3JTZXJ2aWNlUmVtb3RpbmdTb3VyY2VfT25NZXNzYWdlRnJvbVNpbmtfUGFyYW1zLm1lc3NhZ2UKICAgIGVyciA9IG1lc3NhZ2VWYWxpZGF0b3IudmFsaWRhdGVBcnJheVBvaW50ZXIob2Zmc2V0ICsgY29kZWMua1N0cnVjdEhlYWRlclNpemUgKyAwLCAxLCBjb2RlYy5VaW50OCwgZmFsc2UsIFswXSwgMCk7CiAgICBpZiAoZXJyICE9PSB2YWxpZGF0b3IudmFsaWRhdGlvbkVycm9yLk5PTkUpCiAgICAgICAgcmV0dXJuIGVycjsKCiAgICByZXR1cm4gdmFsaWRhdG9yLnZhbGlkYXRpb25FcnJvci5OT05FOwogIH07CgogIE1pcnJvclNlcnZpY2VSZW1vdGluZ1NvdXJjZV9Pbk1lc3NhZ2VGcm9tU2lua19QYXJhbXMuZW5jb2RlZFNpemUgPSBjb2RlYy5rU3RydWN0SGVhZGVyU2l6ZSArIDg7CgogIE1pcnJvclNlcnZpY2VSZW1vdGluZ1NvdXJjZV9Pbk1lc3NhZ2VGcm9tU2lua19QYXJhbXMuZGVjb2RlID0gZnVuY3Rpb24oZGVjb2RlcikgewogICAgdmFyIHBhY2tlZDsKICAgIHZhciB2YWwgPSBuZXcgTWlycm9yU2VydmljZVJlbW90aW5nU291cmNlX09uTWVzc2FnZUZyb21TaW5rX1BhcmFtcygpOwogICAgdmFyIG51bWJlck9mQnl0ZXMgPSBkZWNvZGVyLnJlYWRVaW50MzIoKTsKICAgIHZhciB2ZXJzaW9uID0gZGVjb2Rlci5yZWFkVWludDMyKCk7CiAgICB2YWwubWVzc2FnZSA9IGRlY29kZXIuZGVjb2RlQXJyYXlQb2ludGVyKGNvZGVjLlVpbnQ4KTsKICAgIHJldHVybiB2YWw7CiAgfTsKCiAgTWlycm9yU2VydmljZVJlbW90aW5nU291cmNlX09uTWVzc2FnZUZyb21TaW5rX1BhcmFtcy5lbmNvZGUgPSBmdW5jdGlvbihlbmNvZGVyLCB2YWwpIHsKICAgIHZhciBwYWNrZWQ7CiAgICBlbmNvZGVyLndyaXRlVWludDMyKE1pcnJvclNlcnZpY2VSZW1vdGluZ1NvdXJjZV9Pbk1lc3NhZ2VGcm9tU2lua19QYXJhbXMuZW5jb2RlZFNpemUpOwogICAgZW5jb2Rlci53cml0ZVVpbnQzMigwKTsKICAgIGVuY29kZXIuZW5jb2RlQXJyYXlQb2ludGVyKGNvZGVjLlVpbnQ4LCB2YWwubWVzc2FnZSk7CiAgfTsKICBmdW5jdGlvbiBNaXJyb3JTZXJ2aWNlUmVtb3RpbmdTb3VyY2VfT25TdG9wcGVkX1BhcmFtcyh2YWx1ZXMpIHsKICAgIHRoaXMuaW5pdERlZmF1bHRzXygpOwogICAgdGhpcy5pbml0RmllbGRzXyh2YWx1ZXMpOwogIH0KCgogIE1pcnJvclNlcnZpY2VSZW1vdGluZ1NvdXJjZV9PblN0b3BwZWRfUGFyYW1zLnByb3RvdHlwZS5pbml0RGVmYXVsdHNfID0gZnVuY3Rpb24oKSB7CiAgICB0aGlzLnJlYXNvbiA9IDA7CiAgfTsKICBNaXJyb3JTZXJ2aWNlUmVtb3RpbmdTb3VyY2VfT25TdG9wcGVkX1BhcmFtcy5wcm90b3R5cGUuaW5pdEZpZWxkc18gPSBmdW5jdGlvbihmaWVsZHMpIHsKICAgIGZvcih2YXIgZmllbGQgaW4gZmllbGRzKSB7CiAgICAgICAgaWYgKHRoaXMuaGFzT3duUHJvcGVydHkoZmllbGQpKQogICAgICAgICAgdGhpc1tmaWVsZF0gPSBmaWVsZHNbZmllbGRdOwogICAgfQogIH07CgogIE1pcnJvclNlcnZpY2VSZW1vdGluZ1NvdXJjZV9PblN0b3BwZWRfUGFyYW1zLnZhbGlkYXRlID0gZnVuY3Rpb24obWVzc2FnZVZhbGlkYXRvciwgb2Zmc2V0KSB7CiAgICB2YXIgZXJyOwogICAgZXJyID0gbWVzc2FnZVZhbGlkYXRvci52YWxpZGF0ZVN0cnVjdEhlYWRlcihvZmZzZXQsIGNvZGVjLmtTdHJ1Y3RIZWFkZXJTaXplKTsKICAgIGlmIChlcnIgIT09IHZhbGlkYXRvci52YWxpZGF0aW9uRXJyb3IuTk9ORSkKICAgICAgICByZXR1cm4gZXJyOwoKICAgIHZhciBrVmVyc2lvblNpemVzID0gWwogICAgICB7dmVyc2lvbjogMCwgbnVtQnl0ZXM6IDE2fQogICAgXTsKICAgIGVyciA9IG1lc3NhZ2VWYWxpZGF0b3IudmFsaWRhdGVTdHJ1Y3RWZXJzaW9uKG9mZnNldCwga1ZlcnNpb25TaXplcyk7CiAgICBpZiAoZXJyICE9PSB2YWxpZGF0b3IudmFsaWRhdGlvbkVycm9yLk5PTkUpCiAgICAgICAgcmV0dXJuIGVycjsKCgogICAgLy8gdmFsaWRhdGUgTWlycm9yU2VydmljZVJlbW90aW5nU291cmNlX09uU3RvcHBlZF9QYXJhbXMucmVhc29uCiAgICBlcnIgPSBtZXNzYWdlVmFsaWRhdG9yLnZhbGlkYXRlRW51bShvZmZzZXQgKyBjb2RlYy5rU3RydWN0SGVhZGVyU2l6ZSArIDAsIHJlbW90aW5nX2NvbW1vbiQuUmVtb3RpbmdTdG9wUmVhc29uKTsKICAgIGlmIChlcnIgIT09IHZhbGlkYXRvci52YWxpZGF0aW9uRXJyb3IuTk9ORSkKICAgICAgICByZXR1cm4gZXJyOwoKICAgIHJldHVybiB2YWxpZGF0b3IudmFsaWRhdGlvbkVycm9yLk5PTkU7CiAgfTsKCiAgTWlycm9yU2VydmljZVJlbW90aW5nU291cmNlX09uU3RvcHBlZF9QYXJhbXMuZW5jb2RlZFNpemUgPSBjb2RlYy5rU3RydWN0SGVhZGVyU2l6ZSArIDg7CgogIE1pcnJvclNlcnZpY2VSZW1vdGluZ1NvdXJjZV9PblN0b3BwZWRfUGFyYW1zLmRlY29kZSA9IGZ1bmN0aW9uKGRlY29kZXIpIHsKICAgIHZhciBwYWNrZWQ7CiAgICB2YXIgdmFsID0gbmV3IE1pcnJvclNlcnZpY2VSZW1vdGluZ1NvdXJjZV9PblN0b3BwZWRfUGFyYW1zKCk7CiAgICB2YXIgbnVtYmVyT2ZCeXRlcyA9IGRlY29kZXIucmVhZFVpbnQzMigpOwogICAgdmFyIHZlcnNpb24gPSBkZWNvZGVyLnJlYWRVaW50MzIoKTsKICAgIHZhbC5yZWFzb24gPSBkZWNvZGVyLmRlY29kZVN0cnVjdChjb2RlYy5JbnQzMik7CiAgICBkZWNvZGVyLnNraXAoMSk7CiAgICBkZWNvZGVyLnNraXAoMSk7CiAgICBkZWNvZGVyLnNraXAoMSk7CiAgICBkZWNvZGVyLnNraXAoMSk7CiAgICByZXR1cm4gdmFsOwogIH07CgogIE1pcnJvclNlcnZpY2VSZW1vdGluZ1NvdXJjZV9PblN0b3BwZWRfUGFyYW1zLmVuY29kZSA9IGZ1bmN0aW9uKGVuY29kZXIsIHZhbCkgewogICAgdmFyIHBhY2tlZDsKICAgIGVuY29kZXIud3JpdGVVaW50MzIoTWlycm9yU2VydmljZVJlbW90aW5nU291cmNlX09uU3RvcHBlZF9QYXJhbXMuZW5jb2RlZFNpemUpOwogICAgZW5jb2Rlci53cml0ZVVpbnQzMigwKTsKICAgIGVuY29kZXIuZW5jb2RlU3RydWN0KGNvZGVjLkludDMyLCB2YWwucmVhc29uKTsKICAgIGVuY29kZXIuc2tpcCgxKTsKICAgIGVuY29kZXIuc2tpcCgxKTsKICAgIGVuY29kZXIuc2tpcCgxKTsKICAgIGVuY29kZXIuc2tpcCgxKTsKICB9OwogIGZ1bmN0aW9uIE1pcnJvclNlcnZpY2VSZW1vdGluZ1NvdXJjZV9PbkVycm9yX1BhcmFtcyh2YWx1ZXMpIHsKICAgIHRoaXMuaW5pdERlZmF1bHRzXygpOwogICAgdGhpcy5pbml0RmllbGRzXyh2YWx1ZXMpOwogIH0KCgogIE1pcnJvclNlcnZpY2VSZW1vdGluZ1NvdXJjZV9PbkVycm9yX1BhcmFtcy5wcm90b3R5cGUuaW5pdERlZmF1bHRzXyA9IGZ1bmN0aW9uKCkgewogIH07CiAgTWlycm9yU2VydmljZVJlbW90aW5nU291cmNlX09uRXJyb3JfUGFyYW1zLnByb3RvdHlwZS5pbml0RmllbGRzXyA9IGZ1bmN0aW9uKGZpZWxkcykgewogICAgZm9yKHZhciBmaWVsZCBpbiBmaWVsZHMpIHsKICAgICAgICBpZiAodGhpcy5oYXNPd25Qcm9wZXJ0eShmaWVsZCkpCiAgICAgICAgICB0aGlzW2ZpZWxkXSA9IGZpZWxkc1tmaWVsZF07CiAgICB9CiAgfTsKCiAgTWlycm9yU2VydmljZVJlbW90aW5nU291cmNlX09uRXJyb3JfUGFyYW1zLnZhbGlkYXRlID0gZnVuY3Rpb24obWVzc2FnZVZhbGlkYXRvciwgb2Zmc2V0KSB7CiAgICB2YXIgZXJyOwogICAgZXJyID0gbWVzc2FnZVZhbGlkYXRvci52YWxpZGF0ZVN0cnVjdEhlYWRlcihvZmZzZXQsIGNvZGVjLmtTdHJ1Y3RIZWFkZXJTaXplKTsKICAgIGlmIChlcnIgIT09IHZhbGlkYXRvci52YWxpZGF0aW9uRXJyb3IuTk9ORSkKICAgICAgICByZXR1cm4gZXJyOwoKICAgIHZhciBrVmVyc2lvblNpemVzID0gWwogICAgICB7dmVyc2lvbjogMCwgbnVtQnl0ZXM6IDh9CiAgICBdOwogICAgZXJyID0gbWVzc2FnZVZhbGlkYXRvci52YWxpZGF0ZVN0cnVjdFZlcnNpb24ob2Zmc2V0LCBrVmVyc2lvblNpemVzKTsKICAgIGlmIChlcnIgIT09IHZhbGlkYXRvci52YWxpZGF0aW9uRXJyb3IuTk9ORSkKICAgICAgICByZXR1cm4gZXJyOwoKICAgIHJldHVybiB2YWxpZGF0b3IudmFsaWRhdGlvbkVycm9yLk5PTkU7CiAgfTsKCiAgTWlycm9yU2VydmljZVJlbW90aW5nU291cmNlX09uRXJyb3JfUGFyYW1zLmVuY29kZWRTaXplID0gY29kZWMua1N0cnVjdEhlYWRlclNpemUgKyAwOwoKICBNaXJyb3JTZXJ2aWNlUmVtb3RpbmdTb3VyY2VfT25FcnJvcl9QYXJhbXMuZGVjb2RlID0gZnVuY3Rpb24oZGVjb2RlcikgewogICAgdmFyIHBhY2tlZDsKICAgIHZhciB2YWwgPSBuZXcgTWlycm9yU2VydmljZVJlbW90aW5nU291cmNlX09uRXJyb3JfUGFyYW1zKCk7CiAgICB2YXIgbnVtYmVyT2ZCeXRlcyA9IGRlY29kZXIucmVhZFVpbnQzMigpOwogICAgdmFyIHZlcnNpb24gPSBkZWNvZGVyLnJlYWRVaW50MzIoKTsKICAgIHJldHVybiB2YWw7CiAgfTsKCiAgTWlycm9yU2VydmljZVJlbW90aW5nU291cmNlX09uRXJyb3JfUGFyYW1zLmVuY29kZSA9IGZ1bmN0aW9uKGVuY29kZXIsIHZhbCkgewogICAgdmFyIHBhY2tlZDsKICAgIGVuY29kZXIud3JpdGVVaW50MzIoTWlycm9yU2VydmljZVJlbW90aW5nU291cmNlX09uRXJyb3JfUGFyYW1zLmVuY29kZWRTaXplKTsKICAgIGVuY29kZXIud3JpdGVVaW50MzIoMCk7CiAgfTsKICB2YXIga01pcnJvclNlcnZpY2VSZW1vdGVyX1N0YXJ0X05hbWUgPSAxNTk3MjQ1NDAxOwogIHZhciBrTWlycm9yU2VydmljZVJlbW90ZXJfU3RhcnREYXRhU3RyZWFtc19OYW1lID0gMTQ3NDQ5Nzc5NjsKICB2YXIga01pcnJvclNlcnZpY2VSZW1vdGVyX1N0b3BfTmFtZSA9IDI0NzUwNjU5NjsKICB2YXIga01pcnJvclNlcnZpY2VSZW1vdGVyX1NlbmRNZXNzYWdlVG9TaW5rX05hbWUgPSAxNjUxMjU2MDU1OwogIHZhciBrTWlycm9yU2VydmljZVJlbW90ZXJfRXN0aW1hdGVUcmFuc21pc3Npb25DYXBhY2l0eV9OYW1lID0gMjU1NTgyODQyOwoKICBmdW5jdGlvbiBNaXJyb3JTZXJ2aWNlUmVtb3RlclB0cihoYW5kbGVPclB0ckluZm8pIHsKICAgIHRoaXMucHRyID0gbmV3IGJpbmRpbmdzLkludGVyZmFjZVB0ckNvbnRyb2xsZXIoTWlycm9yU2VydmljZVJlbW90ZXIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGhhbmRsZU9yUHRySW5mbyk7CiAgfQoKICBmdW5jdGlvbiBNaXJyb3JTZXJ2aWNlUmVtb3RlckFzc29jaWF0ZWRQdHIoYXNzb2NpYXRlZEludGVyZmFjZVB0ckluZm8pIHsKICAgIHRoaXMucHRyID0gbmV3IGFzc29jaWF0ZWRCaW5kaW5ncy5Bc3NvY2lhdGVkSW50ZXJmYWNlUHRyQ29udHJvbGxlcigKICAgICAgICBNaXJyb3JTZXJ2aWNlUmVtb3RlciwgYXNzb2NpYXRlZEludGVyZmFjZVB0ckluZm8pOwogIH0KCiAgTWlycm9yU2VydmljZVJlbW90ZXJBc3NvY2lhdGVkUHRyLnByb3RvdHlwZSA9CiAgICAgIE9iamVjdC5jcmVhdGUoTWlycm9yU2VydmljZVJlbW90ZXJQdHIucHJvdG90eXBlKTsKICBNaXJyb3JTZXJ2aWNlUmVtb3RlckFzc29jaWF0ZWRQdHIucHJvdG90eXBlLmNvbnN0cnVjdG9yID0KICAgICAgTWlycm9yU2VydmljZVJlbW90ZXJBc3NvY2lhdGVkUHRyOwoKICBmdW5jdGlvbiBNaXJyb3JTZXJ2aWNlUmVtb3RlclByb3h5KHJlY2VpdmVyKSB7CiAgICB0aGlzLnJlY2VpdmVyXyA9IHJlY2VpdmVyOwogIH0KICBNaXJyb3JTZXJ2aWNlUmVtb3RlclB0ci5wcm90b3R5cGUuc3RhcnQgPSBmdW5jdGlvbigpIHsKICAgIHJldHVybiBNaXJyb3JTZXJ2aWNlUmVtb3RlclByb3h5LnByb3RvdHlwZS5zdGFydAogICAgICAgIC5hcHBseSh0aGlzLnB0ci5nZXRQcm94eSgpLCBhcmd1bWVudHMpOwogIH07CgogIE1pcnJvclNlcnZpY2VSZW1vdGVyUHJveHkucHJvdG90eXBlLnN0YXJ0ID0gZnVuY3Rpb24oKSB7CiAgICB2YXIgcGFyYW1zID0gbmV3IE1pcnJvclNlcnZpY2VSZW1vdGVyX1N0YXJ0X1BhcmFtcygpOwogICAgdmFyIGJ1aWxkZXIgPSBuZXcgY29kZWMuTWVzc2FnZVYwQnVpbGRlcigKICAgICAgICBrTWlycm9yU2VydmljZVJlbW90ZXJfU3RhcnRfTmFtZSwKICAgICAgICBjb2RlYy5hbGlnbihNaXJyb3JTZXJ2aWNlUmVtb3Rlcl9TdGFydF9QYXJhbXMuZW5jb2RlZFNpemUpKTsKICAgIGJ1aWxkZXIuZW5jb2RlU3RydWN0KE1pcnJvclNlcnZpY2VSZW1vdGVyX1N0YXJ0X1BhcmFtcywgcGFyYW1zKTsKICAgIHZhciBtZXNzYWdlID0gYnVpbGRlci5maW5pc2goKTsKICAgIHRoaXMucmVjZWl2ZXJfLmFjY2VwdChtZXNzYWdlKTsKICB9OwogIE1pcnJvclNlcnZpY2VSZW1vdGVyUHRyLnByb3RvdHlwZS5zdGFydERhdGFTdHJlYW1zID0gZnVuY3Rpb24oKSB7CiAgICByZXR1cm4gTWlycm9yU2VydmljZVJlbW90ZXJQcm94eS5wcm90b3R5cGUuc3RhcnREYXRhU3RyZWFtcwogICAgICAgIC5hcHBseSh0aGlzLnB0ci5nZXRQcm94eSgpLCBhcmd1bWVudHMpOwogIH07CgogIE1pcnJvclNlcnZpY2VSZW1vdGVyUHJveHkucHJvdG90eXBlLnN0YXJ0RGF0YVN0cmVhbXMgPSBmdW5jdGlvbihoYXNBdWRpbywgaGFzVmlkZW8pIHsKICAgIHZhciBwYXJhbXMgPSBuZXcgTWlycm9yU2VydmljZVJlbW90ZXJfU3RhcnREYXRhU3RyZWFtc19QYXJhbXMoKTsKICAgIHBhcmFtcy5oYXNBdWRpbyA9IGhhc0F1ZGlvOwogICAgcGFyYW1zLmhhc1ZpZGVvID0gaGFzVmlkZW87CiAgICByZXR1cm4gbmV3IFByb21pc2UoZnVuY3Rpb24ocmVzb2x2ZSwgcmVqZWN0KSB7CiAgICAgIHZhciBidWlsZGVyID0gbmV3IGNvZGVjLk1lc3NhZ2VWMUJ1aWxkZXIoCiAgICAgICAgICBrTWlycm9yU2VydmljZVJlbW90ZXJfU3RhcnREYXRhU3RyZWFtc19OYW1lLAogICAgICAgICAgY29kZWMuYWxpZ24oTWlycm9yU2VydmljZVJlbW90ZXJfU3RhcnREYXRhU3RyZWFtc19QYXJhbXMuZW5jb2RlZFNpemUpLAogICAgICAgICAgY29kZWMua01lc3NhZ2VFeHBlY3RzUmVzcG9uc2UsIDApOwogICAgICBidWlsZGVyLmVuY29kZVN0cnVjdChNaXJyb3JTZXJ2aWNlUmVtb3Rlcl9TdGFydERhdGFTdHJlYW1zX1BhcmFtcywgcGFyYW1zKTsKICAgICAgdmFyIG1lc3NhZ2UgPSBidWlsZGVyLmZpbmlzaCgpOwogICAgICB0aGlzLnJlY2VpdmVyXy5hY2NlcHRBbmRFeHBlY3RSZXNwb25zZShtZXNzYWdlKS50aGVuKGZ1bmN0aW9uKG1lc3NhZ2UpIHsKICAgICAgICB2YXIgcmVhZGVyID0gbmV3IGNvZGVjLk1lc3NhZ2VSZWFkZXIobWVzc2FnZSk7CiAgICAgICAgdmFyIHJlc3BvbnNlUGFyYW1zID0KICAgICAgICAgICAgcmVhZGVyLmRlY29kZVN0cnVjdChNaXJyb3JTZXJ2aWNlUmVtb3Rlcl9TdGFydERhdGFTdHJlYW1zX1Jlc3BvbnNlUGFyYW1zKTsKICAgICAgICByZXNvbHZlKHJlc3BvbnNlUGFyYW1zKTsKICAgICAgfSkuY2F0Y2goZnVuY3Rpb24ocmVzdWx0KSB7CiAgICAgICAgcmVqZWN0KEVycm9yKCJDb25uZWN0aW9uIGVycm9yOiAiICsgcmVzdWx0KSk7CiAgICAgIH0pOwogICAgfS5iaW5kKHRoaXMpKTsKICB9OwogIE1pcnJvclNlcnZpY2VSZW1vdGVyUHRyLnByb3RvdHlwZS5zdG9wID0gZnVuY3Rpb24oKSB7CiAgICByZXR1cm4gTWlycm9yU2VydmljZVJlbW90ZXJQcm94eS5wcm90b3R5cGUuc3RvcAogICAgICAgIC5hcHBseSh0aGlzLnB0ci5nZXRQcm94eSgpLCBhcmd1bWVudHMpOwogIH07CgogIE1pcnJvclNlcnZpY2VSZW1vdGVyUHJveHkucHJvdG90eXBlLnN0b3AgPSBmdW5jdGlvbihyZWFzb24pIHsKICAgIHZhciBwYXJhbXMgPSBuZXcgTWlycm9yU2VydmljZVJlbW90ZXJfU3RvcF9QYXJhbXMoKTsKICAgIHBhcmFtcy5yZWFzb24gPSByZWFzb247CiAgICB2YXIgYnVpbGRlciA9IG5ldyBjb2RlYy5NZXNzYWdlVjBCdWlsZGVyKAogICAgICAgIGtNaXJyb3JTZXJ2aWNlUmVtb3Rlcl9TdG9wX05hbWUsCiAgICAgICAgY29kZWMuYWxpZ24oTWlycm9yU2VydmljZVJlbW90ZXJfU3RvcF9QYXJhbXMuZW5jb2RlZFNpemUpKTsKICAgIGJ1aWxkZXIuZW5jb2RlU3RydWN0KE1pcnJvclNlcnZpY2VSZW1vdGVyX1N0b3BfUGFyYW1zLCBwYXJhbXMpOwogICAgdmFyIG1lc3NhZ2UgPSBidWlsZGVyLmZpbmlzaCgpOwogICAgdGhpcy5yZWNlaXZlcl8uYWNjZXB0KG1lc3NhZ2UpOwogIH07CiAgTWlycm9yU2VydmljZVJlbW90ZXJQdHIucHJvdG90eXBlLnNlbmRNZXNzYWdlVG9TaW5rID0gZnVuY3Rpb24oKSB7CiAgICByZXR1cm4gTWlycm9yU2VydmljZVJlbW90ZXJQcm94eS5wcm90b3R5cGUuc2VuZE1lc3NhZ2VUb1NpbmsKICAgICAgICAuYXBwbHkodGhpcy5wdHIuZ2V0UHJveHkoKSwgYXJndW1lbnRzKTsKICB9OwoKICBNaXJyb3JTZXJ2aWNlUmVtb3RlclByb3h5LnByb3RvdHlwZS5zZW5kTWVzc2FnZVRvU2luayA9IGZ1bmN0aW9uKG1lc3NhZ2UpIHsKICAgIHZhciBwYXJhbXMgPSBuZXcgTWlycm9yU2VydmljZVJlbW90ZXJfU2VuZE1lc3NhZ2VUb1NpbmtfUGFyYW1zKCk7CiAgICBwYXJhbXMubWVzc2FnZSA9IG1lc3NhZ2U7CiAgICB2YXIgYnVpbGRlciA9IG5ldyBjb2RlYy5NZXNzYWdlVjBCdWlsZGVyKAogICAgICAgIGtNaXJyb3JTZXJ2aWNlUmVtb3Rlcl9TZW5kTWVzc2FnZVRvU2lua19OYW1lLAogICAgICAgIGNvZGVjLmFsaWduKE1pcnJvclNlcnZpY2VSZW1vdGVyX1NlbmRNZXNzYWdlVG9TaW5rX1BhcmFtcy5lbmNvZGVkU2l6ZSkpOwogICAgYnVpbGRlci5lbmNvZGVTdHJ1Y3QoTWlycm9yU2VydmljZVJlbW90ZXJfU2VuZE1lc3NhZ2VUb1NpbmtfUGFyYW1zLCBwYXJhbXMpOwogICAgdmFyIG1lc3NhZ2UgPSBidWlsZGVyLmZpbmlzaCgpOwogICAgdGhpcy5yZWNlaXZlcl8uYWNjZXB0KG1lc3NhZ2UpOwogIH07CiAgTWlycm9yU2VydmljZVJlbW90ZXJQdHIucHJvdG90eXBlLmVzdGltYXRlVHJhbnNtaXNzaW9uQ2FwYWNpdHkgPSBmdW5jdGlvbigpIHsKICAgIHJldHVybiBNaXJyb3JTZXJ2aWNlUmVtb3RlclByb3h5LnByb3RvdHlwZS5lc3RpbWF0ZVRyYW5zbWlzc2lvbkNhcGFjaXR5CiAgICAgICAgLmFwcGx5KHRoaXMucHRyLmdldFByb3h5KCksIGFyZ3VtZW50cyk7CiAgfTsKCiAgTWlycm9yU2VydmljZVJlbW90ZXJQcm94eS5wcm90b3R5cGUuZXN0aW1hdGVUcmFuc21pc3Npb25DYXBhY2l0eSA9IGZ1bmN0aW9uKCkgewogICAgdmFyIHBhcmFtcyA9IG5ldyBNaXJyb3JTZXJ2aWNlUmVtb3Rlcl9Fc3RpbWF0ZVRyYW5zbWlzc2lvbkNhcGFjaXR5X1BhcmFtcygpOwogICAgcmV0dXJuIG5ldyBQcm9taXNlKGZ1bmN0aW9uKHJlc29sdmUsIHJlamVjdCkgewogICAgICB2YXIgYnVpbGRlciA9IG5ldyBjb2RlYy5NZXNzYWdlVjFCdWlsZGVyKAogICAgICAgICAga01pcnJvclNlcnZpY2VSZW1vdGVyX0VzdGltYXRlVHJhbnNtaXNzaW9uQ2FwYWNpdHlfTmFtZSwKICAgICAgICAgIGNvZGVjLmFsaWduKE1pcnJvclNlcnZpY2VSZW1vdGVyX0VzdGltYXRlVHJhbnNtaXNzaW9uQ2FwYWNpdHlfUGFyYW1zLmVuY29kZWRTaXplKSwKICAgICAgICAgIGNvZGVjLmtNZXNzYWdlRXhwZWN0c1Jlc3BvbnNlLCAwKTsKICAgICAgYnVpbGRlci5lbmNvZGVTdHJ1Y3QoTWlycm9yU2VydmljZVJlbW90ZXJfRXN0aW1hdGVUcmFuc21pc3Npb25DYXBhY2l0eV9QYXJhbXMsIHBhcmFtcyk7CiAgICAgIHZhciBtZXNzYWdlID0gYnVpbGRlci5maW5pc2goKTsKICAgICAgdGhpcy5yZWNlaXZlcl8uYWNjZXB0QW5kRXhwZWN0UmVzcG9uc2UobWVzc2FnZSkudGhlbihmdW5jdGlvbihtZXNzYWdlKSB7CiAgICAgICAgdmFyIHJlYWRlciA9IG5ldyBjb2RlYy5NZXNzYWdlUmVhZGVyKG1lc3NhZ2UpOwogICAgICAgIHZhciByZXNwb25zZVBhcmFtcyA9CiAgICAgICAgICAgIHJlYWRlci5kZWNvZGVTdHJ1Y3QoTWlycm9yU2VydmljZVJlbW90ZXJfRXN0aW1hdGVUcmFuc21pc3Npb25DYXBhY2l0eV9SZXNwb25zZVBhcmFtcyk7CiAgICAgICAgcmVzb2x2ZShyZXNwb25zZVBhcmFtcyk7CiAgICAgIH0pLmNhdGNoKGZ1bmN0aW9uKHJlc3VsdCkgewogICAgICAgIHJlamVjdChFcnJvcigiQ29ubmVjdGlvbiBlcnJvcjogIiArIHJlc3VsdCkpOwogICAgICB9KTsKICAgIH0uYmluZCh0aGlzKSk7CiAgfTsKCiAgZnVuY3Rpb24gTWlycm9yU2VydmljZVJlbW90ZXJTdHViKGRlbGVnYXRlKSB7CiAgICB0aGlzLmRlbGVnYXRlXyA9IGRlbGVnYXRlOwogIH0KICBNaXJyb3JTZXJ2aWNlUmVtb3RlclN0dWIucHJvdG90eXBlLnN0YXJ0ID0gZnVuY3Rpb24oKSB7CiAgICByZXR1cm4gdGhpcy5kZWxlZ2F0ZV8gJiYgdGhpcy5kZWxlZ2F0ZV8uc3RhcnQgJiYgdGhpcy5kZWxlZ2F0ZV8uc3RhcnQoKTsKICB9CiAgTWlycm9yU2VydmljZVJlbW90ZXJTdHViLnByb3RvdHlwZS5zdGFydERhdGFTdHJlYW1zID0gZnVuY3Rpb24oaGFzQXVkaW8sIGhhc1ZpZGVvKSB7CiAgICByZXR1cm4gdGhpcy5kZWxlZ2F0ZV8gJiYgdGhpcy5kZWxlZ2F0ZV8uc3RhcnREYXRhU3RyZWFtcyAmJiB0aGlzLmRlbGVnYXRlXy5zdGFydERhdGFTdHJlYW1zKGhhc0F1ZGlvLCBoYXNWaWRlbyk7CiAgfQogIE1pcnJvclNlcnZpY2VSZW1vdGVyU3R1Yi5wcm90b3R5cGUuc3RvcCA9IGZ1bmN0aW9uKHJlYXNvbikgewogICAgcmV0dXJuIHRoaXMuZGVsZWdhdGVfICYmIHRoaXMuZGVsZWdhdGVfLnN0b3AgJiYgdGhpcy5kZWxlZ2F0ZV8uc3RvcChyZWFzb24pOwogIH0KICBNaXJyb3JTZXJ2aWNlUmVtb3RlclN0dWIucHJvdG90eXBlLnNlbmRNZXNzYWdlVG9TaW5rID0gZnVuY3Rpb24obWVzc2FnZSkgewogICAgcmV0dXJuIHRoaXMuZGVsZWdhdGVfICYmIHRoaXMuZGVsZWdhdGVfLnNlbmRNZXNzYWdlVG9TaW5rICYmIHRoaXMuZGVsZWdhdGVfLnNlbmRNZXNzYWdlVG9TaW5rKG1lc3NhZ2UpOwogIH0KICBNaXJyb3JTZXJ2aWNlUmVtb3RlclN0dWIucHJvdG90eXBlLmVzdGltYXRlVHJhbnNtaXNzaW9uQ2FwYWNpdHkgPSBmdW5jdGlvbigpIHsKICAgIHJldHVybiB0aGlzLmRlbGVnYXRlXyAmJiB0aGlzLmRlbGVnYXRlXy5lc3RpbWF0ZVRyYW5zbWlzc2lvbkNhcGFjaXR5ICYmIHRoaXMuZGVsZWdhdGVfLmVzdGltYXRlVHJhbnNtaXNzaW9uQ2FwYWNpdHkoKTsKICB9CgogIE1pcnJvclNlcnZpY2VSZW1vdGVyU3R1Yi5wcm90b3R5cGUuYWNjZXB0ID0gZnVuY3Rpb24obWVzc2FnZSkgewogICAgdmFyIHJlYWRlciA9IG5ldyBjb2RlYy5NZXNzYWdlUmVhZGVyKG1lc3NhZ2UpOwogICAgc3dpdGNoIChyZWFkZXIubWVzc2FnZU5hbWUpIHsKICAgIGNhc2Uga01pcnJvclNlcnZpY2VSZW1vdGVyX1N0YXJ0X05hbWU6CiAgICAgIHZhciBwYXJhbXMgPSByZWFkZXIuZGVjb2RlU3RydWN0KE1pcnJvclNlcnZpY2VSZW1vdGVyX1N0YXJ0X1BhcmFtcyk7CiAgICAgIHRoaXMuc3RhcnQoKTsKICAgICAgcmV0dXJuIHRydWU7CiAgICBjYXNlIGtNaXJyb3JTZXJ2aWNlUmVtb3Rlcl9TdG9wX05hbWU6CiAgICAgIHZhciBwYXJhbXMgPSByZWFkZXIuZGVjb2RlU3RydWN0KE1pcnJvclNlcnZpY2VSZW1vdGVyX1N0b3BfUGFyYW1zKTsKICAgICAgdGhpcy5zdG9wKHBhcmFtcy5yZWFzb24pOwogICAgICByZXR1cm4gdHJ1ZTsKICAgIGNhc2Uga01pcnJvclNlcnZpY2VSZW1vdGVyX1NlbmRNZXNzYWdlVG9TaW5rX05hbWU6CiAgICAgIHZhciBwYXJhbXMgPSByZWFkZXIuZGVjb2RlU3RydWN0KE1pcnJvclNlcnZpY2VSZW1vdGVyX1NlbmRNZXNzYWdlVG9TaW5rX1BhcmFtcyk7CiAgICAgIHRoaXMuc2VuZE1lc3NhZ2VUb1NpbmsocGFyYW1zLm1lc3NhZ2UpOwogICAgICByZXR1cm4gdHJ1ZTsKICAgIGRlZmF1bHQ6CiAgICAgIHJldHVybiBmYWxzZTsKICAgIH0KICB9OwoKICBNaXJyb3JTZXJ2aWNlUmVtb3RlclN0dWIucHJvdG90eXBlLmFjY2VwdFdpdGhSZXNwb25kZXIgPQogICAgICBmdW5jdGlvbihtZXNzYWdlLCByZXNwb25kZXIpIHsKICAgIHZhciByZWFkZXIgPSBuZXcgY29kZWMuTWVzc2FnZVJlYWRlcihtZXNzYWdlKTsKICAgIHN3aXRjaCAocmVhZGVyLm1lc3NhZ2VOYW1lKSB7CiAgICBjYXNlIGtNaXJyb3JTZXJ2aWNlUmVtb3Rlcl9TdGFydERhdGFTdHJlYW1zX05hbWU6CiAgICAgIHZhciBwYXJhbXMgPSByZWFkZXIuZGVjb2RlU3RydWN0KE1pcnJvclNlcnZpY2VSZW1vdGVyX1N0YXJ0RGF0YVN0cmVhbXNfUGFyYW1zKTsKICAgICAgdGhpcy5zdGFydERhdGFTdHJlYW1zKHBhcmFtcy5oYXNBdWRpbywgcGFyYW1zLmhhc1ZpZGVvKS50aGVuKGZ1bmN0aW9uKHJlc3BvbnNlKSB7CiAgICAgICAgdmFyIHJlc3BvbnNlUGFyYW1zID0KICAgICAgICAgICAgbmV3IE1pcnJvclNlcnZpY2VSZW1vdGVyX1N0YXJ0RGF0YVN0cmVhbXNfUmVzcG9uc2VQYXJhbXMoKTsKICAgICAgICByZXNwb25zZVBhcmFtcy5hdWRpb1N0cmVhbUlkID0gcmVzcG9uc2UuYXVkaW9TdHJlYW1JZDsKICAgICAgICByZXNwb25zZVBhcmFtcy52aWRlb1N0cmVhbUlkID0gcmVzcG9uc2UudmlkZW9TdHJlYW1JZDsKICAgICAgICB2YXIgYnVpbGRlciA9IG5ldyBjb2RlYy5NZXNzYWdlVjFCdWlsZGVyKAogICAgICAgICAgICBrTWlycm9yU2VydmljZVJlbW90ZXJfU3RhcnREYXRhU3RyZWFtc19OYW1lLAogICAgICAgICAgICBjb2RlYy5hbGlnbihNaXJyb3JTZXJ2aWNlUmVtb3Rlcl9TdGFydERhdGFTdHJlYW1zX1Jlc3BvbnNlUGFyYW1zLmVuY29kZWRTaXplKSwKICAgICAgICAgICAgY29kZWMua01lc3NhZ2VJc1Jlc3BvbnNlLCByZWFkZXIucmVxdWVzdElEKTsKICAgICAgICBidWlsZGVyLmVuY29kZVN0cnVjdChNaXJyb3JTZXJ2aWNlUmVtb3Rlcl9TdGFydERhdGFTdHJlYW1zX1Jlc3BvbnNlUGFyYW1zLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlc3BvbnNlUGFyYW1zKTsKICAgICAgICB2YXIgbWVzc2FnZSA9IGJ1aWxkZXIuZmluaXNoKCk7CiAgICAgICAgcmVzcG9uZGVyLmFjY2VwdChtZXNzYWdlKTsKICAgICAgfSk7CiAgICAgIHJldHVybiB0cnVlOwogICAgY2FzZSBrTWlycm9yU2VydmljZVJlbW90ZXJfRXN0aW1hdGVUcmFuc21pc3Npb25DYXBhY2l0eV9OYW1lOgogICAgICB2YXIgcGFyYW1zID0gcmVhZGVyLmRlY29kZVN0cnVjdChNaXJyb3JTZXJ2aWNlUmVtb3Rlcl9Fc3RpbWF0ZVRyYW5zbWlzc2lvbkNhcGFjaXR5X1BhcmFtcyk7CiAgICAgIHRoaXMuZXN0aW1hdGVUcmFuc21pc3Npb25DYXBhY2l0eSgpLnRoZW4oZnVuY3Rpb24ocmVzcG9uc2UpIHsKICAgICAgICB2YXIgcmVzcG9uc2VQYXJhbXMgPQogICAgICAgICAgICBuZXcgTWlycm9yU2VydmljZVJlbW90ZXJfRXN0aW1hdGVUcmFuc21pc3Npb25DYXBhY2l0eV9SZXNwb25zZVBhcmFtcygpOwogICAgICAgIHJlc3BvbnNlUGFyYW1zLnJhdGUgPSByZXNwb25zZS5yYXRlOwogICAgICAgIHZhciBidWlsZGVyID0gbmV3IGNvZGVjLk1lc3NhZ2VWMUJ1aWxkZXIoCiAgICAgICAgICAgIGtNaXJyb3JTZXJ2aWNlUmVtb3Rlcl9Fc3RpbWF0ZVRyYW5zbWlzc2lvbkNhcGFjaXR5X05hbWUsCiAgICAgICAgICAgIGNvZGVjLmFsaWduKE1pcnJvclNlcnZpY2VSZW1vdGVyX0VzdGltYXRlVHJhbnNtaXNzaW9uQ2FwYWNpdHlfUmVzcG9uc2VQYXJhbXMuZW5jb2RlZFNpemUpLAogICAgICAgICAgICBjb2RlYy5rTWVzc2FnZUlzUmVzcG9uc2UsIHJlYWRlci5yZXF1ZXN0SUQpOwogICAgICAgIGJ1aWxkZXIuZW5jb2RlU3RydWN0KE1pcnJvclNlcnZpY2VSZW1vdGVyX0VzdGltYXRlVHJhbnNtaXNzaW9uQ2FwYWNpdHlfUmVzcG9uc2VQYXJhbXMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVzcG9uc2VQYXJhbXMpOwogICAgICAgIHZhciBtZXNzYWdlID0gYnVpbGRlci5maW5pc2goKTsKICAgICAgICByZXNwb25kZXIuYWNjZXB0KG1lc3NhZ2UpOwogICAgICB9KTsKICAgICAgcmV0dXJuIHRydWU7CiAgICBkZWZhdWx0OgogICAgICByZXR1cm4gZmFsc2U7CiAgICB9CiAgfTsKCiAgZnVuY3Rpb24gdmFsaWRhdGVNaXJyb3JTZXJ2aWNlUmVtb3RlclJlcXVlc3QobWVzc2FnZVZhbGlkYXRvcikgewogICAgdmFyIG1lc3NhZ2UgPSBtZXNzYWdlVmFsaWRhdG9yLm1lc3NhZ2U7CiAgICB2YXIgcGFyYW1zQ2xhc3MgPSBudWxsOwogICAgc3dpdGNoIChtZXNzYWdlLmdldE5hbWUoKSkgewogICAgICBjYXNlIGtNaXJyb3JTZXJ2aWNlUmVtb3Rlcl9TdGFydF9OYW1lOgogICAgICAgIGlmICghbWVzc2FnZS5leHBlY3RzUmVzcG9uc2UoKSAmJiAhbWVzc2FnZS5pc1Jlc3BvbnNlKCkpCiAgICAgICAgICBwYXJhbXNDbGFzcyA9IE1pcnJvclNlcnZpY2VSZW1vdGVyX1N0YXJ0X1BhcmFtczsKICAgICAgYnJlYWs7CiAgICAgIGNhc2Uga01pcnJvclNlcnZpY2VSZW1vdGVyX1N0YXJ0RGF0YVN0cmVhbXNfTmFtZToKICAgICAgICBpZiAobWVzc2FnZS5leHBlY3RzUmVzcG9uc2UoKSkKICAgICAgICAgIHBhcmFtc0NsYXNzID0gTWlycm9yU2VydmljZVJlbW90ZXJfU3RhcnREYXRhU3RyZWFtc19QYXJhbXM7CiAgICAgIGJyZWFrOwogICAgICBjYXNlIGtNaXJyb3JTZXJ2aWNlUmVtb3Rlcl9TdG9wX05hbWU6CiAgICAgICAgaWYgKCFtZXNzYWdlLmV4cGVjdHNSZXNwb25zZSgpICYmICFtZXNzYWdlLmlzUmVzcG9uc2UoKSkKICAgICAgICAgIHBhcmFtc0NsYXNzID0gTWlycm9yU2VydmljZVJlbW90ZXJfU3RvcF9QYXJhbXM7CiAgICAgIGJyZWFrOwogICAgICBjYXNlIGtNaXJyb3JTZXJ2aWNlUmVtb3Rlcl9TZW5kTWVzc2FnZVRvU2lua19OYW1lOgogICAgICAgIGlmICghbWVzc2FnZS5leHBlY3RzUmVzcG9uc2UoKSAmJiAhbWVzc2FnZS5pc1Jlc3BvbnNlKCkpCiAgICAgICAgICBwYXJhbXNDbGFzcyA9IE1pcnJvclNlcnZpY2VSZW1vdGVyX1NlbmRNZXNzYWdlVG9TaW5rX1BhcmFtczsKICAgICAgYnJlYWs7CiAgICAgIGNhc2Uga01pcnJvclNlcnZpY2VSZW1vdGVyX0VzdGltYXRlVHJhbnNtaXNzaW9uQ2FwYWNpdHlfTmFtZToKICAgICAgICBpZiAobWVzc2FnZS5leHBlY3RzUmVzcG9uc2UoKSkKICAgICAgICAgIHBhcmFtc0NsYXNzID0gTWlycm9yU2VydmljZVJlbW90ZXJfRXN0aW1hdGVUcmFuc21pc3Npb25DYXBhY2l0eV9QYXJhbXM7CiAgICAgIGJyZWFrOwogICAgfQogICAgaWYgKHBhcmFtc0NsYXNzID09PSBudWxsKQogICAgICByZXR1cm4gdmFsaWRhdG9yLnZhbGlkYXRpb25FcnJvci5OT05FOwogICAgcmV0dXJuIHBhcmFtc0NsYXNzLnZhbGlkYXRlKG1lc3NhZ2VWYWxpZGF0b3IsIG1lc3NhZ2VWYWxpZGF0b3IubWVzc2FnZS5nZXRIZWFkZXJOdW1CeXRlcygpKTsKICB9CgogIGZ1bmN0aW9uIHZhbGlkYXRlTWlycm9yU2VydmljZVJlbW90ZXJSZXNwb25zZShtZXNzYWdlVmFsaWRhdG9yKSB7CiAgIHZhciBtZXNzYWdlID0gbWVzc2FnZVZhbGlkYXRvci5tZXNzYWdlOwogICB2YXIgcGFyYW1zQ2xhc3MgPSBudWxsOwogICBzd2l0Y2ggKG1lc3NhZ2UuZ2V0TmFtZSgpKSB7CiAgICAgIGNhc2Uga01pcnJvclNlcnZpY2VSZW1vdGVyX1N0YXJ0RGF0YVN0cmVhbXNfTmFtZToKICAgICAgICBpZiAobWVzc2FnZS5pc1Jlc3BvbnNlKCkpCiAgICAgICAgICBwYXJhbXNDbGFzcyA9IE1pcnJvclNlcnZpY2VSZW1vdGVyX1N0YXJ0RGF0YVN0cmVhbXNfUmVzcG9uc2VQYXJhbXM7CiAgICAgICAgYnJlYWs7CiAgICAgIGNhc2Uga01pcnJvclNlcnZpY2VSZW1vdGVyX0VzdGltYXRlVHJhbnNtaXNzaW9uQ2FwYWNpdHlfTmFtZToKICAgICAgICBpZiAobWVzc2FnZS5pc1Jlc3BvbnNlKCkpCiAgICAgICAgICBwYXJhbXNDbGFzcyA9IE1pcnJvclNlcnZpY2VSZW1vdGVyX0VzdGltYXRlVHJhbnNtaXNzaW9uQ2FwYWNpdHlfUmVzcG9uc2VQYXJhbXM7CiAgICAgICAgYnJlYWs7CiAgICB9CiAgICBpZiAocGFyYW1zQ2xhc3MgPT09IG51bGwpCiAgICAgIHJldHVybiB2YWxpZGF0b3IudmFsaWRhdGlvbkVycm9yLk5PTkU7CiAgICByZXR1cm4gcGFyYW1zQ2xhc3MudmFsaWRhdGUobWVzc2FnZVZhbGlkYXRvciwgbWVzc2FnZVZhbGlkYXRvci5tZXNzYWdlLmdldEhlYWRlck51bUJ5dGVzKCkpOwogIH0KCiAgdmFyIE1pcnJvclNlcnZpY2VSZW1vdGVyID0gewogICAgbmFtZTogJ21lZGlhOjptb2pvbTo6TWlycm9yU2VydmljZVJlbW90ZXInLAogICAga1ZlcnNpb246IDAsCiAgICBwdHJDbGFzczogTWlycm9yU2VydmljZVJlbW90ZXJQdHIsCiAgICBwcm94eUNsYXNzOiBNaXJyb3JTZXJ2aWNlUmVtb3RlclByb3h5LAogICAgc3R1YkNsYXNzOiBNaXJyb3JTZXJ2aWNlUmVtb3RlclN0dWIsCiAgICB2YWxpZGF0ZVJlcXVlc3Q6IHZhbGlkYXRlTWlycm9yU2VydmljZVJlbW90ZXJSZXF1ZXN0LAogICAgdmFsaWRhdGVSZXNwb25zZTogdmFsaWRhdGVNaXJyb3JTZXJ2aWNlUmVtb3RlclJlc3BvbnNlLAogIH07CiAgTWlycm9yU2VydmljZVJlbW90ZXJTdHViLnByb3RvdHlwZS52YWxpZGF0b3IgPSB2YWxpZGF0ZU1pcnJvclNlcnZpY2VSZW1vdGVyUmVxdWVzdDsKICBNaXJyb3JTZXJ2aWNlUmVtb3RlclByb3h5LnByb3RvdHlwZS52YWxpZGF0b3IgPSB2YWxpZGF0ZU1pcnJvclNlcnZpY2VSZW1vdGVyUmVzcG9uc2U7CiAgdmFyIGtNaXJyb3JTZXJ2aWNlUmVtb3RpbmdTb3VyY2VfT25TaW5rQXZhaWxhYmxlX05hbWUgPSAxMDAwMzQ5MTE3OwogIHZhciBrTWlycm9yU2VydmljZVJlbW90aW5nU291cmNlX09uTWVzc2FnZUZyb21TaW5rX05hbWUgPSAxMTY3ODA3Mjc2OwogIHZhciBrTWlycm9yU2VydmljZVJlbW90aW5nU291cmNlX09uU3RvcHBlZF9OYW1lID0gMTUxOTEwNTYzOTsKICB2YXIga01pcnJvclNlcnZpY2VSZW1vdGluZ1NvdXJjZV9PbkVycm9yX05hbWUgPSAxMjY2NjcyMzg1OwoKICBmdW5jdGlvbiBNaXJyb3JTZXJ2aWNlUmVtb3RpbmdTb3VyY2VQdHIoaGFuZGxlT3JQdHJJbmZvKSB7CiAgICB0aGlzLnB0ciA9IG5ldyBiaW5kaW5ncy5JbnRlcmZhY2VQdHJDb250cm9sbGVyKE1pcnJvclNlcnZpY2VSZW1vdGluZ1NvdXJjZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaGFuZGxlT3JQdHJJbmZvKTsKICB9CgogIGZ1bmN0aW9uIE1pcnJvclNlcnZpY2VSZW1vdGluZ1NvdXJjZUFzc29jaWF0ZWRQdHIoYXNzb2NpYXRlZEludGVyZmFjZVB0ckluZm8pIHsKICAgIHRoaXMucHRyID0gbmV3IGFzc29jaWF0ZWRCaW5kaW5ncy5Bc3NvY2lhdGVkSW50ZXJmYWNlUHRyQ29udHJvbGxlcigKICAgICAgICBNaXJyb3JTZXJ2aWNlUmVtb3RpbmdTb3VyY2UsIGFzc29jaWF0ZWRJbnRlcmZhY2VQdHJJbmZvKTsKICB9CgogIE1pcnJvclNlcnZpY2VSZW1vdGluZ1NvdXJjZUFzc29jaWF0ZWRQdHIucHJvdG90eXBlID0KICAgICAgT2JqZWN0LmNyZWF0ZShNaXJyb3JTZXJ2aWNlUmVtb3RpbmdTb3VyY2VQdHIucHJvdG90eXBlKTsKICBNaXJyb3JTZXJ2aWNlUmVtb3RpbmdTb3VyY2VBc3NvY2lhdGVkUHRyLnByb3RvdHlwZS5jb25zdHJ1Y3RvciA9CiAgICAgIE1pcnJvclNlcnZpY2VSZW1vdGluZ1NvdXJjZUFzc29jaWF0ZWRQdHI7CgogIGZ1bmN0aW9uIE1pcnJvclNlcnZpY2VSZW1vdGluZ1NvdXJjZVByb3h5KHJlY2VpdmVyKSB7CiAgICB0aGlzLnJlY2VpdmVyXyA9IHJlY2VpdmVyOwogIH0KICBNaXJyb3JTZXJ2aWNlUmVtb3RpbmdTb3VyY2VQdHIucHJvdG90eXBlLm9uU2lua0F2YWlsYWJsZSA9IGZ1bmN0aW9uKCkgewogICAgcmV0dXJuIE1pcnJvclNlcnZpY2VSZW1vdGluZ1NvdXJjZVByb3h5LnByb3RvdHlwZS5vblNpbmtBdmFpbGFibGUKICAgICAgICAuYXBwbHkodGhpcy5wdHIuZ2V0UHJveHkoKSwgYXJndW1lbnRzKTsKICB9OwoKICBNaXJyb3JTZXJ2aWNlUmVtb3RpbmdTb3VyY2VQcm94eS5wcm90b3R5cGUub25TaW5rQXZhaWxhYmxlID0gZnVuY3Rpb24obWV0YWRhdGEpIHsKICAgIHZhciBwYXJhbXMgPSBuZXcgTWlycm9yU2VydmljZVJlbW90aW5nU291cmNlX09uU2lua0F2YWlsYWJsZV9QYXJhbXMoKTsKICAgIHBhcmFtcy5tZXRhZGF0YSA9IG1ldGFkYXRhOwogICAgdmFyIGJ1aWxkZXIgPSBuZXcgY29kZWMuTWVzc2FnZVYwQnVpbGRlcigKICAgICAgICBrTWlycm9yU2VydmljZVJlbW90aW5nU291cmNlX09uU2lua0F2YWlsYWJsZV9OYW1lLAogICAgICAgIGNvZGVjLmFsaWduKE1pcnJvclNlcnZpY2VSZW1vdGluZ1NvdXJjZV9PblNpbmtBdmFpbGFibGVfUGFyYW1zLmVuY29kZWRTaXplKSk7CiAgICBidWlsZGVyLmVuY29kZVN0cnVjdChNaXJyb3JTZXJ2aWNlUmVtb3RpbmdTb3VyY2VfT25TaW5rQXZhaWxhYmxlX1BhcmFtcywgcGFyYW1zKTsKICAgIHZhciBtZXNzYWdlID0gYnVpbGRlci5maW5pc2goKTsKICAgIHRoaXMucmVjZWl2ZXJfLmFjY2VwdChtZXNzYWdlKTsKICB9OwogIE1pcnJvclNlcnZpY2VSZW1vdGluZ1NvdXJjZVB0ci5wcm90b3R5cGUub25NZXNzYWdlRnJvbVNpbmsgPSBmdW5jdGlvbigpIHsKICAgIHJldHVybiBNaXJyb3JTZXJ2aWNlUmVtb3RpbmdTb3VyY2VQcm94eS5wcm90b3R5cGUub25NZXNzYWdlRnJvbVNpbmsKICAgICAgICAuYXBwbHkodGhpcy5wdHIuZ2V0UHJveHkoKSwgYXJndW1lbnRzKTsKICB9OwoKICBNaXJyb3JTZXJ2aWNlUmVtb3RpbmdTb3VyY2VQcm94eS5wcm90b3R5cGUub25NZXNzYWdlRnJvbVNpbmsgPSBmdW5jdGlvbihtZXNzYWdlKSB7CiAgICB2YXIgcGFyYW1zID0gbmV3IE1pcnJvclNlcnZpY2VSZW1vdGluZ1NvdXJjZV9Pbk1lc3NhZ2VGcm9tU2lua19QYXJhbXMoKTsKICAgIHBhcmFtcy5tZXNzYWdlID0gbWVzc2FnZTsKICAgIHZhciBidWlsZGVyID0gbmV3IGNvZGVjLk1lc3NhZ2VWMEJ1aWxkZXIoCiAgICAgICAga01pcnJvclNlcnZpY2VSZW1vdGluZ1NvdXJjZV9Pbk1lc3NhZ2VGcm9tU2lua19OYW1lLAogICAgICAgIGNvZGVjLmFsaWduKE1pcnJvclNlcnZpY2VSZW1vdGluZ1NvdXJjZV9Pbk1lc3NhZ2VGcm9tU2lua19QYXJhbXMuZW5jb2RlZFNpemUpKTsKICAgIGJ1aWxkZXIuZW5jb2RlU3RydWN0KE1pcnJvclNlcnZpY2VSZW1vdGluZ1NvdXJjZV9Pbk1lc3NhZ2VGcm9tU2lua19QYXJhbXMsIHBhcmFtcyk7CiAgICB2YXIgbWVzc2FnZSA9IGJ1aWxkZXIuZmluaXNoKCk7CiAgICB0aGlzLnJlY2VpdmVyXy5hY2NlcHQobWVzc2FnZSk7CiAgfTsKICBNaXJyb3JTZXJ2aWNlUmVtb3RpbmdTb3VyY2VQdHIucHJvdG90eXBlLm9uU3RvcHBlZCA9IGZ1bmN0aW9uKCkgewogICAgcmV0dXJuIE1pcnJvclNlcnZpY2VSZW1vdGluZ1NvdXJjZVByb3h5LnByb3RvdHlwZS5vblN0b3BwZWQKICAgICAgICAuYXBwbHkodGhpcy5wdHIuZ2V0UHJveHkoKSwgYXJndW1lbnRzKTsKICB9OwoKICBNaXJyb3JTZXJ2aWNlUmVtb3RpbmdTb3VyY2VQcm94eS5wcm90b3R5cGUub25TdG9wcGVkID0gZnVuY3Rpb24ocmVhc29uKSB7CiAgICB2YXIgcGFyYW1zID0gbmV3IE1pcnJvclNlcnZpY2VSZW1vdGluZ1NvdXJjZV9PblN0b3BwZWRfUGFyYW1zKCk7CiAgICBwYXJhbXMucmVhc29uID0gcmVhc29uOwogICAgdmFyIGJ1aWxkZXIgPSBuZXcgY29kZWMuTWVzc2FnZVYwQnVpbGRlcigKICAgICAgICBrTWlycm9yU2VydmljZVJlbW90aW5nU291cmNlX09uU3RvcHBlZF9OYW1lLAogICAgICAgIGNvZGVjLmFsaWduKE1pcnJvclNlcnZpY2VSZW1vdGluZ1NvdXJjZV9PblN0b3BwZWRfUGFyYW1zLmVuY29kZWRTaXplKSk7CiAgICBidWlsZGVyLmVuY29kZVN0cnVjdChNaXJyb3JTZXJ2aWNlUmVtb3RpbmdTb3VyY2VfT25TdG9wcGVkX1BhcmFtcywgcGFyYW1zKTsKICAgIHZhciBtZXNzYWdlID0gYnVpbGRlci5maW5pc2goKTsKICAgIHRoaXMucmVjZWl2ZXJfLmFjY2VwdChtZXNzYWdlKTsKICB9OwogIE1pcnJvclNlcnZpY2VSZW1vdGluZ1NvdXJjZVB0ci5wcm90b3R5cGUub25FcnJvciA9IGZ1bmN0aW9uKCkgewogICAgcmV0dXJuIE1pcnJvclNlcnZpY2VSZW1vdGluZ1NvdXJjZVByb3h5LnByb3RvdHlwZS5vbkVycm9yCiAgICAgICAgLmFwcGx5KHRoaXMucHRyLmdldFByb3h5KCksIGFyZ3VtZW50cyk7CiAgfTsKCiAgTWlycm9yU2VydmljZVJlbW90aW5nU291cmNlUHJveHkucHJvdG90eXBlLm9uRXJyb3IgPSBmdW5jdGlvbigpIHsKICAgIHZhciBwYXJhbXMgPSBuZXcgTWlycm9yU2VydmljZVJlbW90aW5nU291cmNlX09uRXJyb3JfUGFyYW1zKCk7CiAgICB2YXIgYnVpbGRlciA9IG5ldyBjb2RlYy5NZXNzYWdlVjBCdWlsZGVyKAogICAgICAgIGtNaXJyb3JTZXJ2aWNlUmVtb3RpbmdTb3VyY2VfT25FcnJvcl9OYW1lLAogICAgICAgIGNvZGVjLmFsaWduKE1pcnJvclNlcnZpY2VSZW1vdGluZ1NvdXJjZV9PbkVycm9yX1BhcmFtcy5lbmNvZGVkU2l6ZSkpOwogICAgYnVpbGRlci5lbmNvZGVTdHJ1Y3QoTWlycm9yU2VydmljZVJlbW90aW5nU291cmNlX09uRXJyb3JfUGFyYW1zLCBwYXJhbXMpOwogICAgdmFyIG1lc3NhZ2UgPSBidWlsZGVyLmZpbmlzaCgpOwogICAgdGhpcy5yZWNlaXZlcl8uYWNjZXB0KG1lc3NhZ2UpOwogIH07CgogIGZ1bmN0aW9uIE1pcnJvclNlcnZpY2VSZW1vdGluZ1NvdXJjZVN0dWIoZGVsZWdhdGUpIHsKICAgIHRoaXMuZGVsZWdhdGVfID0gZGVsZWdhdGU7CiAgfQogIE1pcnJvclNlcnZpY2VSZW1vdGluZ1NvdXJjZVN0dWIucHJvdG90eXBlLm9uU2lua0F2YWlsYWJsZSA9IGZ1bmN0aW9uKG1ldGFkYXRhKSB7CiAgICByZXR1cm4gdGhpcy5kZWxlZ2F0ZV8gJiYgdGhpcy5kZWxlZ2F0ZV8ub25TaW5rQXZhaWxhYmxlICYmIHRoaXMuZGVsZWdhdGVfLm9uU2lua0F2YWlsYWJsZShtZXRhZGF0YSk7CiAgfQogIE1pcnJvclNlcnZpY2VSZW1vdGluZ1NvdXJjZVN0dWIucHJvdG90eXBlLm9uTWVzc2FnZUZyb21TaW5rID0gZnVuY3Rpb24obWVzc2FnZSkgewogICAgcmV0dXJuIHRoaXMuZGVsZWdhdGVfICYmIHRoaXMuZGVsZWdhdGVfLm9uTWVzc2FnZUZyb21TaW5rICYmIHRoaXMuZGVsZWdhdGVfLm9uTWVzc2FnZUZyb21TaW5rKG1lc3NhZ2UpOwogIH0KICBNaXJyb3JTZXJ2aWNlUmVtb3RpbmdTb3VyY2VTdHViLnByb3RvdHlwZS5vblN0b3BwZWQgPSBmdW5jdGlvbihyZWFzb24pIHsKICAgIHJldHVybiB0aGlzLmRlbGVnYXRlXyAmJiB0aGlzLmRlbGVnYXRlXy5vblN0b3BwZWQgJiYgdGhpcy5kZWxlZ2F0ZV8ub25TdG9wcGVkKHJlYXNvbik7CiAgfQogIE1pcnJvclNlcnZpY2VSZW1vdGluZ1NvdXJjZVN0dWIucHJvdG90eXBlLm9uRXJyb3IgPSBmdW5jdGlvbigpIHsKICAgIHJldHVybiB0aGlzLmRlbGVnYXRlXyAmJiB0aGlzLmRlbGVnYXRlXy5vbkVycm9yICYmIHRoaXMuZGVsZWdhdGVfLm9uRXJyb3IoKTsKICB9CgogIE1pcnJvclNlcnZpY2VSZW1vdGluZ1NvdXJjZVN0dWIucHJvdG90eXBlLmFjY2VwdCA9IGZ1bmN0aW9uKG1lc3NhZ2UpIHsKICAgIHZhciByZWFkZXIgPSBuZXcgY29kZWMuTWVzc2FnZVJlYWRlcihtZXNzYWdlKTsKICAgIHN3aXRjaCAocmVhZGVyLm1lc3NhZ2VOYW1lKSB7CiAgICBjYXNlIGtNaXJyb3JTZXJ2aWNlUmVtb3RpbmdTb3VyY2VfT25TaW5rQXZhaWxhYmxlX05hbWU6CiAgICAgIHZhciBwYXJhbXMgPSByZWFkZXIuZGVjb2RlU3RydWN0KE1pcnJvclNlcnZpY2VSZW1vdGluZ1NvdXJjZV9PblNpbmtBdmFpbGFibGVfUGFyYW1zKTsKICAgICAgdGhpcy5vblNpbmtBdmFpbGFibGUocGFyYW1zLm1ldGFkYXRhKTsKICAgICAgcmV0dXJuIHRydWU7CiAgICBjYXNlIGtNaXJyb3JTZXJ2aWNlUmVtb3RpbmdTb3VyY2VfT25NZXNzYWdlRnJvbVNpbmtfTmFtZToKICAgICAgdmFyIHBhcmFtcyA9IHJlYWRlci5kZWNvZGVTdHJ1Y3QoTWlycm9yU2VydmljZVJlbW90aW5nU291cmNlX09uTWVzc2FnZUZyb21TaW5rX1BhcmFtcyk7CiAgICAgIHRoaXMub25NZXNzYWdlRnJvbVNpbmsocGFyYW1zLm1lc3NhZ2UpOwogICAgICByZXR1cm4gdHJ1ZTsKICAgIGNhc2Uga01pcnJvclNlcnZpY2VSZW1vdGluZ1NvdXJjZV9PblN0b3BwZWRfTmFtZToKICAgICAgdmFyIHBhcmFtcyA9IHJlYWRlci5kZWNvZGVTdHJ1Y3QoTWlycm9yU2VydmljZVJlbW90aW5nU291cmNlX09uU3RvcHBlZF9QYXJhbXMpOwogICAgICB0aGlzLm9uU3RvcHBlZChwYXJhbXMucmVhc29uKTsKICAgICAgcmV0dXJuIHRydWU7CiAgICBjYXNlIGtNaXJyb3JTZXJ2aWNlUmVtb3RpbmdTb3VyY2VfT25FcnJvcl9OYW1lOgogICAgICB2YXIgcGFyYW1zID0gcmVhZGVyLmRlY29kZVN0cnVjdChNaXJyb3JTZXJ2aWNlUmVtb3RpbmdTb3VyY2VfT25FcnJvcl9QYXJhbXMpOwogICAgICB0aGlzLm9uRXJyb3IoKTsKICAgICAgcmV0dXJuIHRydWU7CiAgICBkZWZhdWx0OgogICAgICByZXR1cm4gZmFsc2U7CiAgICB9CiAgfTsKCiAgTWlycm9yU2VydmljZVJlbW90aW5nU291cmNlU3R1Yi5wcm90b3R5cGUuYWNjZXB0V2l0aFJlc3BvbmRlciA9CiAgICAgIGZ1bmN0aW9uKG1lc3NhZ2UsIHJlc3BvbmRlcikgewogICAgdmFyIHJlYWRlciA9IG5ldyBjb2RlYy5NZXNzYWdlUmVhZGVyKG1lc3NhZ2UpOwogICAgc3dpdGNoIChyZWFkZXIubWVzc2FnZU5hbWUpIHsKICAgIGRlZmF1bHQ6CiAgICAgIHJldHVybiBmYWxzZTsKICAgIH0KICB9OwoKICBmdW5jdGlvbiB2YWxpZGF0ZU1pcnJvclNlcnZpY2VSZW1vdGluZ1NvdXJjZVJlcXVlc3QobWVzc2FnZVZhbGlkYXRvcikgewogICAgdmFyIG1lc3NhZ2UgPSBtZXNzYWdlVmFsaWRhdG9yLm1lc3NhZ2U7CiAgICB2YXIgcGFyYW1zQ2xhc3MgPSBudWxsOwogICAgc3dpdGNoIChtZXNzYWdlLmdldE5hbWUoKSkgewogICAgICBjYXNlIGtNaXJyb3JTZXJ2aWNlUmVtb3RpbmdTb3VyY2VfT25TaW5rQXZhaWxhYmxlX05hbWU6CiAgICAgICAgaWYgKCFtZXNzYWdlLmV4cGVjdHNSZXNwb25zZSgpICYmICFtZXNzYWdlLmlzUmVzcG9uc2UoKSkKICAgICAgICAgIHBhcmFtc0NsYXNzID0gTWlycm9yU2VydmljZVJlbW90aW5nU291cmNlX09uU2lua0F2YWlsYWJsZV9QYXJhbXM7CiAgICAgIGJyZWFrOwogICAgICBjYXNlIGtNaXJyb3JTZXJ2aWNlUmVtb3RpbmdTb3VyY2VfT25NZXNzYWdlRnJvbVNpbmtfTmFtZToKICAgICAgICBpZiAoIW1lc3NhZ2UuZXhwZWN0c1Jlc3BvbnNlKCkgJiYgIW1lc3NhZ2UuaXNSZXNwb25zZSgpKQogICAgICAgICAgcGFyYW1zQ2xhc3MgPSBNaXJyb3JTZXJ2aWNlUmVtb3RpbmdTb3VyY2VfT25NZXNzYWdlRnJvbVNpbmtfUGFyYW1zOwogICAgICBicmVhazsKICAgICAgY2FzZSBrTWlycm9yU2VydmljZVJlbW90aW5nU291cmNlX09uU3RvcHBlZF9OYW1lOgogICAgICAgIGlmICghbWVzc2FnZS5leHBlY3RzUmVzcG9uc2UoKSAmJiAhbWVzc2FnZS5pc1Jlc3BvbnNlKCkpCiAgICAgICAgICBwYXJhbXNDbGFzcyA9IE1pcnJvclNlcnZpY2VSZW1vdGluZ1NvdXJjZV9PblN0b3BwZWRfUGFyYW1zOwogICAgICBicmVhazsKICAgICAgY2FzZSBrTWlycm9yU2VydmljZVJlbW90aW5nU291cmNlX09uRXJyb3JfTmFtZToKICAgICAgICBpZiAoIW1lc3NhZ2UuZXhwZWN0c1Jlc3BvbnNlKCkgJiYgIW1lc3NhZ2UuaXNSZXNwb25zZSgpKQogICAgICAgICAgcGFyYW1zQ2xhc3MgPSBNaXJyb3JTZXJ2aWNlUmVtb3RpbmdTb3VyY2VfT25FcnJvcl9QYXJhbXM7CiAgICAgIGJyZWFrOwogICAgfQogICAgaWYgKHBhcmFtc0NsYXNzID09PSBudWxsKQogICAgICByZXR1cm4gdmFsaWRhdG9yLnZhbGlkYXRpb25FcnJvci5OT05FOwogICAgcmV0dXJuIHBhcmFtc0NsYXNzLnZhbGlkYXRlKG1lc3NhZ2VWYWxpZGF0b3IsIG1lc3NhZ2VWYWxpZGF0b3IubWVzc2FnZS5nZXRIZWFkZXJOdW1CeXRlcygpKTsKICB9CgogIGZ1bmN0aW9uIHZhbGlkYXRlTWlycm9yU2VydmljZVJlbW90aW5nU291cmNlUmVzcG9uc2UobWVzc2FnZVZhbGlkYXRvcikgewogICAgcmV0dXJuIHZhbGlkYXRvci52YWxpZGF0aW9uRXJyb3IuTk9ORTsKICB9CgogIHZhciBNaXJyb3JTZXJ2aWNlUmVtb3RpbmdTb3VyY2UgPSB7CiAgICBuYW1lOiAnbWVkaWE6Om1vam9tOjpNaXJyb3JTZXJ2aWNlUmVtb3RpbmdTb3VyY2UnLAogICAga1ZlcnNpb246IDAsCiAgICBwdHJDbGFzczogTWlycm9yU2VydmljZVJlbW90aW5nU291cmNlUHRyLAogICAgcHJveHlDbGFzczogTWlycm9yU2VydmljZVJlbW90aW5nU291cmNlUHJveHksCiAgICBzdHViQ2xhc3M6IE1pcnJvclNlcnZpY2VSZW1vdGluZ1NvdXJjZVN0dWIsCiAgICB2YWxpZGF0ZVJlcXVlc3Q6IHZhbGlkYXRlTWlycm9yU2VydmljZVJlbW90aW5nU291cmNlUmVxdWVzdCwKICAgIHZhbGlkYXRlUmVzcG9uc2U6IG51bGwsCiAgfTsKICBNaXJyb3JTZXJ2aWNlUmVtb3RpbmdTb3VyY2VTdHViLnByb3RvdHlwZS52YWxpZGF0b3IgPSB2YWxpZGF0ZU1pcnJvclNlcnZpY2VSZW1vdGluZ1NvdXJjZVJlcXVlc3Q7CiAgTWlycm9yU2VydmljZVJlbW90aW5nU291cmNlUHJveHkucHJvdG90eXBlLnZhbGlkYXRvciA9IG51bGw7CiAgZXhwb3J0cy5NaXJyb3JTZXJ2aWNlUmVtb3RlciA9IE1pcnJvclNlcnZpY2VSZW1vdGVyOwogIGV4cG9ydHMuTWlycm9yU2VydmljZVJlbW90ZXJQdHIgPSBNaXJyb3JTZXJ2aWNlUmVtb3RlclB0cjsKICBleHBvcnRzLk1pcnJvclNlcnZpY2VSZW1vdGVyQXNzb2NpYXRlZFB0ciA9IE1pcnJvclNlcnZpY2VSZW1vdGVyQXNzb2NpYXRlZFB0cjsKICBleHBvcnRzLk1pcnJvclNlcnZpY2VSZW1vdGluZ1NvdXJjZSA9IE1pcnJvclNlcnZpY2VSZW1vdGluZ1NvdXJjZTsKICBleHBvcnRzLk1pcnJvclNlcnZpY2VSZW1vdGluZ1NvdXJjZVB0ciA9IE1pcnJvclNlcnZpY2VSZW1vdGluZ1NvdXJjZVB0cjsKICBleHBvcnRzLk1pcnJvclNlcnZpY2VSZW1vdGluZ1NvdXJjZUFzc29jaWF0ZWRQdHIgPSBNaXJyb3JTZXJ2aWNlUmVtb3RpbmdTb3VyY2VBc3NvY2lhdGVkUHRyOwp9KSgpOy8vIENvcHlyaWdodCAyMDE0IFRoZSBDaHJvbWl1bSBBdXRob3JzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgovLyBVc2Ugb2YgdGhpcyBzb3VyY2UgY29kZSBpcyBnb3Zlcm5lZCBieSBhIEJTRC1zdHlsZSBsaWNlbnNlIHRoYXQgY2FuIGJlCi8vIGZvdW5kIGluIHRoZSBMSUNFTlNFIGZpbGUuCgondXNlIHN0cmljdCc7CgooZnVuY3Rpb24oKSB7CiAgdmFyIG1vam9tSWQgPSAnbWVkaWEvbW9qby9pbnRlcmZhY2VzL3JlbW90aW5nX2NvbW1vbi5tb2pvbSc7CiAgaWYgKG1vam8uaW50ZXJuYWwuaXNNb2pvbUxvYWRlZChtb2pvbUlkKSkgewogICAgY29uc29sZS53YXJuKCdUaGUgZm9sbG93aW5nIG1vam9tIGlzIGxvYWRlZCBtdWx0aXBsZSB0aW1lczogJyArIG1vam9tSWQpOwogICAgcmV0dXJuOwogIH0KICBtb2pvLmludGVybmFsLm1hcmtNb2pvbUxvYWRlZChtb2pvbUlkKTsKICB2YXIgYmluZGluZ3MgPSBtb2pvOwogIHZhciBhc3NvY2lhdGVkQmluZGluZ3MgPSBtb2pvOwogIHZhciBjb2RlYyA9IG1vam8uaW50ZXJuYWw7CiAgdmFyIHZhbGlkYXRvciA9IG1vam8uaW50ZXJuYWw7CgogIHZhciBleHBvcnRzID0gbW9qby5pbnRlcm5hbC5leHBvc2VOYW1lc3BhY2UoJ21lZGlhLm1vam9tJyk7CgoKICB2YXIgUmVtb3RpbmdTdG9wUmVhc29uID0ge307CiAgUmVtb3RpbmdTdG9wUmVhc29uLlJPVVRFX1RFUk1JTkFURUQgPSAwOwogIFJlbW90aW5nU3RvcFJlYXNvbi5MT0NBTF9QTEFZQkFDSyA9IFJlbW90aW5nU3RvcFJlYXNvbi5ST1VURV9URVJNSU5BVEVEICsgMTsKICBSZW1vdGluZ1N0b3BSZWFzb24uU09VUkNFX0dPTkUgPSBSZW1vdGluZ1N0b3BSZWFzb24uTE9DQUxfUExBWUJBQ0sgKyAxOwogIFJlbW90aW5nU3RvcFJlYXNvbi5NRVNTQUdFX1NFTkRfRkFJTEVEID0gUmVtb3RpbmdTdG9wUmVhc29uLlNPVVJDRV9HT05FICsgMTsKICBSZW1vdGluZ1N0b3BSZWFzb24uREFUQV9TRU5EX0ZBSUxFRCA9IFJlbW90aW5nU3RvcFJlYXNvbi5NRVNTQUdFX1NFTkRfRkFJTEVEICsgMTsKICBSZW1vdGluZ1N0b3BSZWFzb24uVU5FWFBFQ1RFRF9GQUlMVVJFID0gUmVtb3RpbmdTdG9wUmVhc29uLkRBVEFfU0VORF9GQUlMRUQgKyAxOwogIFJlbW90aW5nU3RvcFJlYXNvbi5TRVJWSUNFX0dPTkUgPSBSZW1vdGluZ1N0b3BSZWFzb24uVU5FWFBFQ1RFRF9GQUlMVVJFICsgMTsKICBSZW1vdGluZ1N0b3BSZWFzb24uVVNFUl9ESVNBQkxFRCA9IFJlbW90aW5nU3RvcFJlYXNvbi5TRVJWSUNFX0dPTkUgKyAxOwoKICBSZW1vdGluZ1N0b3BSZWFzb24uaXNLbm93bkVudW1WYWx1ZSA9IGZ1bmN0aW9uKHZhbHVlKSB7CiAgICBzd2l0Y2ggKHZhbHVlKSB7CiAgICBjYXNlIDA6CiAgICBjYXNlIDE6CiAgICBjYXNlIDI6CiAgICBjYXNlIDM6CiAgICBjYXNlIDQ6CiAgICBjYXNlIDU6CiAgICBjYXNlIDY6CiAgICBjYXNlIDc6CiAgICAgIHJldHVybiB0cnVlOwogICAgfQogICAgcmV0dXJuIGZhbHNlOwogIH07CgogIFJlbW90aW5nU3RvcFJlYXNvbi52YWxpZGF0ZSA9IGZ1bmN0aW9uKGVudW1WYWx1ZSkgewogICAgdmFyIGlzRXh0ZW5zaWJsZSA9IGZhbHNlOwogICAgaWYgKGlzRXh0ZW5zaWJsZSB8fCB0aGlzLmlzS25vd25FbnVtVmFsdWUoZW51bVZhbHVlKSkKICAgICAgcmV0dXJuIHZhbGlkYXRvci52YWxpZGF0aW9uRXJyb3IuTk9ORTsKCiAgICByZXR1cm4gdmFsaWRhdG9yLnZhbGlkYXRpb25FcnJvci5VTktOT1dOX0VOVU1fVkFMVUU7CiAgfTsKICB2YXIgUmVtb3RpbmdTdGFydEZhaWxSZWFzb24gPSB7fTsKICBSZW1vdGluZ1N0YXJ0RmFpbFJlYXNvbi5DQU5OT1RfU1RBUlRfTVVMVElQTEUgPSAwOwogIFJlbW90aW5nU3RhcnRGYWlsUmVhc29uLlJPVVRFX1RFUk1JTkFURUQgPSBSZW1vdGluZ1N0YXJ0RmFpbFJlYXNvbi5DQU5OT1RfU1RBUlRfTVVMVElQTEUgKyAxOwogIFJlbW90aW5nU3RhcnRGYWlsUmVhc29uLlNFUlZJQ0VfTk9UX0NPTk5FQ1RFRCA9IFJlbW90aW5nU3RhcnRGYWlsUmVhc29uLlJPVVRFX1RFUk1JTkFURUQgKyAxOwoKICBSZW1vdGluZ1N0YXJ0RmFpbFJlYXNvbi5pc0tub3duRW51bVZhbHVlID0gZnVuY3Rpb24odmFsdWUpIHsKICAgIHN3aXRjaCAodmFsdWUpIHsKICAgIGNhc2UgMDoKICAgIGNhc2UgMToKICAgIGNhc2UgMjoKICAgICAgcmV0dXJuIHRydWU7CiAgICB9CiAgICByZXR1cm4gZmFsc2U7CiAgfTsKCiAgUmVtb3RpbmdTdGFydEZhaWxSZWFzb24udmFsaWRhdGUgPSBmdW5jdGlvbihlbnVtVmFsdWUpIHsKICAgIHZhciBpc0V4dGVuc2libGUgPSBmYWxzZTsKICAgIGlmIChpc0V4dGVuc2libGUgfHwgdGhpcy5pc0tub3duRW51bVZhbHVlKGVudW1WYWx1ZSkpCiAgICAgIHJldHVybiB2YWxpZGF0b3IudmFsaWRhdGlvbkVycm9yLk5PTkU7CgogICAgcmV0dXJuIHZhbGlkYXRvci52YWxpZGF0aW9uRXJyb3IuVU5LTk9XTl9FTlVNX1ZBTFVFOwogIH07CiAgdmFyIFJlbW90aW5nU2lua0ZlYXR1cmUgPSB7fTsKICBSZW1vdGluZ1NpbmtGZWF0dXJlLlJFTkRFUklORyA9IDA7CiAgUmVtb3RpbmdTaW5rRmVhdHVyZS5DT05URU5UX0RFQ1JZUFRJT04gPSBSZW1vdGluZ1NpbmtGZWF0dXJlLlJFTkRFUklORyArIDE7CgogIFJlbW90aW5nU2lua0ZlYXR1cmUuaXNLbm93bkVudW1WYWx1ZSA9IGZ1bmN0aW9uKHZhbHVlKSB7CiAgICBzd2l0Y2ggKHZhbHVlKSB7CiAgICBjYXNlIDA6CiAgICBjYXNlIDE6CiAgICAgIHJldHVybiB0cnVlOwogICAgfQogICAgcmV0dXJuIGZhbHNlOwogIH07CgogIFJlbW90aW5nU2lua0ZlYXR1cmUudmFsaWRhdGUgPSBmdW5jdGlvbihlbnVtVmFsdWUpIHsKICAgIHZhciBpc0V4dGVuc2libGUgPSBmYWxzZTsKICAgIGlmIChpc0V4dGVuc2libGUgfHwgdGhpcy5pc0tub3duRW51bVZhbHVlKGVudW1WYWx1ZSkpCiAgICAgIHJldHVybiB2YWxpZGF0b3IudmFsaWRhdGlvbkVycm9yLk5PTkU7CgogICAgcmV0dXJuIHZhbGlkYXRvci52YWxpZGF0aW9uRXJyb3IuVU5LTk9XTl9FTlVNX1ZBTFVFOwogIH07CiAgdmFyIFJlbW90aW5nU2lua0F1ZGlvQ2FwYWJpbGl0eSA9IHt9OwogIFJlbW90aW5nU2lua0F1ZGlvQ2FwYWJpbGl0eS5DT0RFQ19CQVNFTElORV9TRVQgPSAwOwogIFJlbW90aW5nU2lua0F1ZGlvQ2FwYWJpbGl0eS5DT0RFQ19BQUMgPSBSZW1vdGluZ1NpbmtBdWRpb0NhcGFiaWxpdHkuQ09ERUNfQkFTRUxJTkVfU0VUICsgMTsKICBSZW1vdGluZ1NpbmtBdWRpb0NhcGFiaWxpdHkuQ09ERUNfT1BVUyA9IFJlbW90aW5nU2lua0F1ZGlvQ2FwYWJpbGl0eS5DT0RFQ19BQUMgKyAxOwoKICBSZW1vdGluZ1NpbmtBdWRpb0NhcGFiaWxpdHkuaXNLbm93bkVudW1WYWx1ZSA9IGZ1bmN0aW9uKHZhbHVlKSB7CiAgICBzd2l0Y2ggKHZhbHVlKSB7CiAgICBjYXNlIDA6CiAgICBjYXNlIDE6CiAgICBjYXNlIDI6CiAgICAgIHJldHVybiB0cnVlOwogICAgfQogICAgcmV0dXJuIGZhbHNlOwogIH07CgogIFJlbW90aW5nU2lua0F1ZGlvQ2FwYWJpbGl0eS52YWxpZGF0ZSA9IGZ1bmN0aW9uKGVudW1WYWx1ZSkgewogICAgdmFyIGlzRXh0ZW5zaWJsZSA9IGZhbHNlOwogICAgaWYgKGlzRXh0ZW5zaWJsZSB8fCB0aGlzLmlzS25vd25FbnVtVmFsdWUoZW51bVZhbHVlKSkKICAgICAgcmV0dXJuIHZhbGlkYXRvci52YWxpZGF0aW9uRXJyb3IuTk9ORTsKCiAgICByZXR1cm4gdmFsaWRhdG9yLnZhbGlkYXRpb25FcnJvci5VTktOT1dOX0VOVU1fVkFMVUU7CiAgfTsKICB2YXIgUmVtb3RpbmdTaW5rVmlkZW9DYXBhYmlsaXR5ID0ge307CiAgUmVtb3RpbmdTaW5rVmlkZW9DYXBhYmlsaXR5LlNVUFBPUlRfNEsgPSAwOwogIFJlbW90aW5nU2lua1ZpZGVvQ2FwYWJpbGl0eS5DT0RFQ19CQVNFTElORV9TRVQgPSBSZW1vdGluZ1NpbmtWaWRlb0NhcGFiaWxpdHkuU1VQUE9SVF80SyArIDE7CiAgUmVtb3RpbmdTaW5rVmlkZW9DYXBhYmlsaXR5LkNPREVDX0gyNjQgPSBSZW1vdGluZ1NpbmtWaWRlb0NhcGFiaWxpdHkuQ09ERUNfQkFTRUxJTkVfU0VUICsgMTsKICBSZW1vdGluZ1NpbmtWaWRlb0NhcGFiaWxpdHkuQ09ERUNfVlA4ID0gUmVtb3RpbmdTaW5rVmlkZW9DYXBhYmlsaXR5LkNPREVDX0gyNjQgKyAxOwogIFJlbW90aW5nU2lua1ZpZGVvQ2FwYWJpbGl0eS5DT0RFQ19WUDkgPSBSZW1vdGluZ1NpbmtWaWRlb0NhcGFiaWxpdHkuQ09ERUNfVlA4ICsgMTsKICBSZW1vdGluZ1NpbmtWaWRlb0NhcGFiaWxpdHkuQ09ERUNfSEVWQyA9IFJlbW90aW5nU2lua1ZpZGVvQ2FwYWJpbGl0eS5DT0RFQ19WUDkgKyAxOwoKICBSZW1vdGluZ1NpbmtWaWRlb0NhcGFiaWxpdHkuaXNLbm93bkVudW1WYWx1ZSA9IGZ1bmN0aW9uKHZhbHVlKSB7CiAgICBzd2l0Y2ggKHZhbHVlKSB7CiAgICBjYXNlIDA6CiAgICBjYXNlIDE6CiAgICBjYXNlIDI6CiAgICBjYXNlIDM6CiAgICBjYXNlIDQ6CiAgICBjYXNlIDU6CiAgICAgIHJldHVybiB0cnVlOwogICAgfQogICAgcmV0dXJuIGZhbHNlOwogIH07CgogIFJlbW90aW5nU2lua1ZpZGVvQ2FwYWJpbGl0eS52YWxpZGF0ZSA9IGZ1bmN0aW9uKGVudW1WYWx1ZSkgewogICAgdmFyIGlzRXh0ZW5zaWJsZSA9IGZhbHNlOwogICAgaWYgKGlzRXh0ZW5zaWJsZSB8fCB0aGlzLmlzS25vd25FbnVtVmFsdWUoZW51bVZhbHVlKSkKICAgICAgcmV0dXJuIHZhbGlkYXRvci52YWxpZGF0aW9uRXJyb3IuTk9ORTsKCiAgICByZXR1cm4gdmFsaWRhdG9yLnZhbGlkYXRpb25FcnJvci5VTktOT1dOX0VOVU1fVkFMVUU7CiAgfTsKCiAgZnVuY3Rpb24gUmVtb3RpbmdTaW5rTWV0YWRhdGEodmFsdWVzKSB7CiAgICB0aGlzLmluaXREZWZhdWx0c18oKTsKICAgIHRoaXMuaW5pdEZpZWxkc18odmFsdWVzKTsKICB9CgoKICBSZW1vdGluZ1NpbmtNZXRhZGF0YS5wcm90b3R5cGUuaW5pdERlZmF1bHRzXyA9IGZ1bmN0aW9uKCkgewogICAgdGhpcy5mZWF0dXJlcyA9IG51bGw7CiAgICB0aGlzLmF1ZGlvQ2FwYWJpbGl0aWVzID0gbnVsbDsKICAgIHRoaXMudmlkZW9DYXBhYmlsaXRpZXMgPSBudWxsOwogICAgdGhpcy5mcmllbmRseU5hbWUgPSBudWxsOwogIH07CiAgUmVtb3RpbmdTaW5rTWV0YWRhdGEucHJvdG90eXBlLmluaXRGaWVsZHNfID0gZnVuY3Rpb24oZmllbGRzKSB7CiAgICBmb3IodmFyIGZpZWxkIGluIGZpZWxkcykgewogICAgICAgIGlmICh0aGlzLmhhc093blByb3BlcnR5KGZpZWxkKSkKICAgICAgICAgIHRoaXNbZmllbGRdID0gZmllbGRzW2ZpZWxkXTsKICAgIH0KICB9OwoKICBSZW1vdGluZ1NpbmtNZXRhZGF0YS52YWxpZGF0ZSA9IGZ1bmN0aW9uKG1lc3NhZ2VWYWxpZGF0b3IsIG9mZnNldCkgewogICAgdmFyIGVycjsKICAgIGVyciA9IG1lc3NhZ2VWYWxpZGF0b3IudmFsaWRhdGVTdHJ1Y3RIZWFkZXIob2Zmc2V0LCBjb2RlYy5rU3RydWN0SGVhZGVyU2l6ZSk7CiAgICBpZiAoZXJyICE9PSB2YWxpZGF0b3IudmFsaWRhdGlvbkVycm9yLk5PTkUpCiAgICAgICAgcmV0dXJuIGVycjsKCiAgICB2YXIga1ZlcnNpb25TaXplcyA9IFsKICAgICAge3ZlcnNpb246IDAsIG51bUJ5dGVzOiA0MH0KICAgIF07CiAgICBlcnIgPSBtZXNzYWdlVmFsaWRhdG9yLnZhbGlkYXRlU3RydWN0VmVyc2lvbihvZmZzZXQsIGtWZXJzaW9uU2l6ZXMpOwogICAgaWYgKGVyciAhPT0gdmFsaWRhdG9yLnZhbGlkYXRpb25FcnJvci5OT05FKQogICAgICAgIHJldHVybiBlcnI7CgoKICAgIC8vIHZhbGlkYXRlIFJlbW90aW5nU2lua01ldGFkYXRhLmZlYXR1cmVzCiAgICBlcnIgPSBtZXNzYWdlVmFsaWRhdG9yLnZhbGlkYXRlQXJyYXlQb2ludGVyKG9mZnNldCArIGNvZGVjLmtTdHJ1Y3RIZWFkZXJTaXplICsgMCwgNCwgbmV3IGNvZGVjLkVudW0oUmVtb3RpbmdTaW5rRmVhdHVyZSksIGZhbHNlLCBbMF0sIDApOwogICAgaWYgKGVyciAhPT0gdmFsaWRhdG9yLnZhbGlkYXRpb25FcnJvci5OT05FKQogICAgICAgIHJldHVybiBlcnI7CgoKICAgIC8vIHZhbGlkYXRlIFJlbW90aW5nU2lua01ldGFkYXRhLmF1ZGlvQ2FwYWJpbGl0aWVzCiAgICBlcnIgPSBtZXNzYWdlVmFsaWRhdG9yLnZhbGlkYXRlQXJyYXlQb2ludGVyKG9mZnNldCArIGNvZGVjLmtTdHJ1Y3RIZWFkZXJTaXplICsgOCwgNCwgbmV3IGNvZGVjLkVudW0oUmVtb3RpbmdTaW5rQXVkaW9DYXBhYmlsaXR5KSwgZmFsc2UsIFswXSwgMCk7CiAgICBpZiAoZXJyICE9PSB2YWxpZGF0b3IudmFsaWRhdGlvbkVycm9yLk5PTkUpCiAgICAgICAgcmV0dXJuIGVycjsKCgogICAgLy8gdmFsaWRhdGUgUmVtb3RpbmdTaW5rTWV0YWRhdGEudmlkZW9DYXBhYmlsaXRpZXMKICAgIGVyciA9IG1lc3NhZ2VWYWxpZGF0b3IudmFsaWRhdGVBcnJheVBvaW50ZXIob2Zmc2V0ICsgY29kZWMua1N0cnVjdEhlYWRlclNpemUgKyAxNiwgNCwgbmV3IGNvZGVjLkVudW0oUmVtb3RpbmdTaW5rVmlkZW9DYXBhYmlsaXR5KSwgZmFsc2UsIFswXSwgMCk7CiAgICBpZiAoZXJyICE9PSB2YWxpZGF0b3IudmFsaWRhdGlvbkVycm9yLk5PTkUpCiAgICAgICAgcmV0dXJuIGVycjsKCgogICAgLy8gdmFsaWRhdGUgUmVtb3RpbmdTaW5rTWV0YWRhdGEuZnJpZW5kbHlOYW1lCiAgICBlcnIgPSBtZXNzYWdlVmFsaWRhdG9yLnZhbGlkYXRlU3RyaW5nUG9pbnRlcihvZmZzZXQgKyBjb2RlYy5rU3RydWN0SGVhZGVyU2l6ZSArIDI0LCBmYWxzZSkKICAgIGlmIChlcnIgIT09IHZhbGlkYXRvci52YWxpZGF0aW9uRXJyb3IuTk9ORSkKICAgICAgICByZXR1cm4gZXJyOwoKICAgIHJldHVybiB2YWxpZGF0b3IudmFsaWRhdGlvbkVycm9yLk5PTkU7CiAgfTsKCiAgUmVtb3RpbmdTaW5rTWV0YWRhdGEuZW5jb2RlZFNpemUgPSBjb2RlYy5rU3RydWN0SGVhZGVyU2l6ZSArIDMyOwoKICBSZW1vdGluZ1NpbmtNZXRhZGF0YS5kZWNvZGUgPSBmdW5jdGlvbihkZWNvZGVyKSB7CiAgICB2YXIgcGFja2VkOwogICAgdmFyIHZhbCA9IG5ldyBSZW1vdGluZ1NpbmtNZXRhZGF0YSgpOwogICAgdmFyIG51bWJlck9mQnl0ZXMgPSBkZWNvZGVyLnJlYWRVaW50MzIoKTsKICAgIHZhciB2ZXJzaW9uID0gZGVjb2Rlci5yZWFkVWludDMyKCk7CiAgICB2YWwuZmVhdHVyZXMgPSBkZWNvZGVyLmRlY29kZUFycmF5UG9pbnRlcihuZXcgY29kZWMuRW51bShSZW1vdGluZ1NpbmtGZWF0dXJlKSk7CiAgICB2YWwuYXVkaW9DYXBhYmlsaXRpZXMgPSBkZWNvZGVyLmRlY29kZUFycmF5UG9pbnRlcihuZXcgY29kZWMuRW51bShSZW1vdGluZ1NpbmtBdWRpb0NhcGFiaWxpdHkpKTsKICAgIHZhbC52aWRlb0NhcGFiaWxpdGllcyA9IGRlY29kZXIuZGVjb2RlQXJyYXlQb2ludGVyKG5ldyBjb2RlYy5FbnVtKFJlbW90aW5nU2lua1ZpZGVvQ2FwYWJpbGl0eSkpOwogICAgdmFsLmZyaWVuZGx5TmFtZSA9IGRlY29kZXIuZGVjb2RlU3RydWN0KGNvZGVjLlN0cmluZyk7CiAgICByZXR1cm4gdmFsOwogIH07CgogIFJlbW90aW5nU2lua01ldGFkYXRhLmVuY29kZSA9IGZ1bmN0aW9uKGVuY29kZXIsIHZhbCkgewogICAgdmFyIHBhY2tlZDsKICAgIGVuY29kZXIud3JpdGVVaW50MzIoUmVtb3RpbmdTaW5rTWV0YWRhdGEuZW5jb2RlZFNpemUpOwogICAgZW5jb2Rlci53cml0ZVVpbnQzMigwKTsKICAgIGVuY29kZXIuZW5jb2RlQXJyYXlQb2ludGVyKG5ldyBjb2RlYy5FbnVtKFJlbW90aW5nU2lua0ZlYXR1cmUpLCB2YWwuZmVhdHVyZXMpOwogICAgZW5jb2Rlci5lbmNvZGVBcnJheVBvaW50ZXIobmV3IGNvZGVjLkVudW0oUmVtb3RpbmdTaW5rQXVkaW9DYXBhYmlsaXR5KSwgdmFsLmF1ZGlvQ2FwYWJpbGl0aWVzKTsKICAgIGVuY29kZXIuZW5jb2RlQXJyYXlQb2ludGVyKG5ldyBjb2RlYy5FbnVtKFJlbW90aW5nU2lua1ZpZGVvQ2FwYWJpbGl0eSksIHZhbC52aWRlb0NhcGFiaWxpdGllcyk7CiAgICBlbmNvZGVyLmVuY29kZVN0cnVjdChjb2RlYy5TdHJpbmcsIHZhbC5mcmllbmRseU5hbWUpOwogIH07CiAgZXhwb3J0cy5SZW1vdGluZ1N0b3BSZWFzb24gPSBSZW1vdGluZ1N0b3BSZWFzb247CiAgZXhwb3J0cy5SZW1vdGluZ1N0YXJ0RmFpbFJlYXNvbiA9IFJlbW90aW5nU3RhcnRGYWlsUmVhc29uOwogIGV4cG9ydHMuUmVtb3RpbmdTaW5rRmVhdHVyZSA9IFJlbW90aW5nU2lua0ZlYXR1cmU7CiAgZXhwb3J0cy5SZW1vdGluZ1NpbmtBdWRp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