{
	"address": "e467b9dd11fa00df",
	"balance": "233888682813",
	"keys": [
		{
			"index": "0",
			"public_key": "0xdfd3ae152932922137e846a8035e61a1741d3ef9e229461b1a000a1c4ca0c50d22cfcc2976e1403b9a6bbf2afb7b01ddb0a26419dd89304ff17f3736f1e8984f",
			"signing_algorithm": "ECDSA_secp256k1",
			"hashing_algorithm": "SHA2_256",
			"sequence_number": "16",
			"weight": "1000",
			"revoked": true
		},
		{
			"index": "1",
			"public_key": "0x3588eb28b60e28d24c1e8b03f9a00f73ebd3f6707ee813e27d58ecb6439b8dde1413d7a74a7cc7e8939cbef2e0aa6acc51d5c7010afdb4c6dba55d4cc2ca8bed",
			"signing_algorithm": "ECDSA_P256",
			"hashing_algorithm": "SHA2_256",
			"sequence_number": "233",
			"weight": "1000",
			"revoked": true
		},
		{
			"index": "2",
			"public_key": "0xb097cf3dcfedf7c4684cd9a536a327cfe633c98f6b6c12803b4d7f3eb05e85e943cf6623cd265b88c9526cc2f8443c9e5d78d2cc4b791b099938476a383f0757",
			"signing_algorithm": "ECDSA_P256",
			"hashing_algorithm": "SHA2_256",
			"sequence_number": "1",
			"weight": "400",
			"revoked": true
		},
		{
			"index": "3",
			"public_key": "0x460b2ec791eece9fd97abd296403c5ab5cee3877346c0876d119b7e77e9123a28424ec50bfe68d9a93ced5f610d73ac06f8cbe1742ce4207a6f325745d3d96ca",
			"signing_algorithm": "ECDSA_P256",
			"hashing_algorithm": "SHA2_256",
			"sequence_number": "0",
			"weight": "400",
			"revoked": true
		},
		{
			"index": "4",
			"public_key": "0xda2ffb11a9eda290fc182bc59528be3d6b3dfe05b4ff7f779df2dd1f491abc895236948aa7d3ac7b5f37cc007acd3aa3ae5e1b43a3207cb3cb87e5b5e16912a4",
			"signing_algorithm": "ECDSA_P256",
			"hashing_algorithm": "SHA2_256",
			"sequence_number": "0",
			"weight": "400",
			"revoked": true
		},
		{
			"index": "5",
			"public_key": "0xa67d09f8526ae8260e6589da8d58a8c544cf9048d6426804c39ddb4920a9e315a2b7dae8dbd5dbc696d5f31f5b7f72c7d2d4d3e03bcd7ac01e033de2a3492600",
			"signing_algorithm": "ECDSA_P256",
			"hashing_algorithm": "SHA2_256",
			"sequence_number": "0",
			"weight": "400",
			"revoked": true
		},
		{
			"index": "6",
			"public_key": "0x9d80d397be438bdd8f930986ed58819a6209e374926bf3d9af21dd418d0e338f0b1adba148182dde642428f3350e3a5396e0e561df81b99ac88180dade0150c6",
			"signing_algorithm": "ECDSA_P256",
			"hashing_algorithm": "SHA2_256",
			"sequence_number": "0",
			"weight": "400",
			"revoked": true
		},
		{
			"index": "7",
			"public_key": "0xb8cf3deaf03db95abc406f0eb7b35c83e6c131919ca4faf11d0aeb66b832e4ea4ae9bee1ce0f93613e6f8bcf40a18a7a90f2de622f2b9de91171d2cdeb90ae86",
			"signing_algorithm": "ECDSA_secp256k1",
			"hashing_algorithm": "SHA2_256",
			"sequence_number": "3",
			"weight": "250",
			"revoked": true
		},
		{
			"index": "8",
			"public_key": "0xf4c49ec76efeb369cedefe511ed7def63d7090d80577d238e216d8ef88682fae151b4af30be7b99ef999547ccb3c1dc6f3b94865ee2e9e4a1572960d31a73694",
			"signing_algorithm": "ECDSA_secp256k1",
			"hashing_algorithm": "SHA2_256",
			"sequence_number": "0",
			"weight": "250",
			"revoked": true
		},
		{
			"index": "9",
			"public_key": "0x5c421222950a6f41b41420f032cbb1fb9c1902ad205b76d6fbd943c92eb6459e780cffa92d137bd4a754976135774d6dac860062922aea93bc9ff834c4c95790",
			"signing_algorithm": "ECDSA_P256",
			"hashing_algorithm": "SHA2_256",
			"sequence_number": "1",
			"weight": "250",
			"revoked": true
		},
		{
			"index": "10",
			"public_key": "0xbcd1fa5093e884c028e36a47a5ba4cd4e55d08f931685c8a28e5eee9fe8573967f480df8049b1b6f03e40ab072d227592ba62927db64c9c2655fef26c65b836b",
			"signing_algorithm": "ECDSA_secp256k1",
			"hashing_algorithm": "SHA2_256",
			"sequence_number": "1",
			"weight": "250",
			"revoked": true
		},
		{
			"index": "11",
			"public_key": "0x181a71ed25fc85443aebcf6ec708241498f93a3b395e628d98685b4d78e3242c1e1b11edeb0c143d752df5b155fce47df223e7a535b18b8409b2452d4d1df5c9",
			"signing_algorithm": "ECDSA_P256",
			"hashing_algorithm": "SHA2_256",
			"sequence_number": "212",
			"weight": "250",
			"revoked": false
		},
		{
			"index": "12",
			"public_key": "0x5c999370c484e2963d4dce5b75e4c48a1e901518d34f5abfe6e13de064e71c31f1412068e9f20b4692764287fd71f7cac2924f04fec270aa8f7476eba96aa965",
			"signing_algorithm": "ECDSA_P256",
			"hashing_algorithm": "SHA2_256",
			"sequence_number": "170",
			"weight": "250",
			"revoked": false
		},
		{
			"index": "13",
			"public_key": "0xb049757d6412fdecd6b1a67f94cbf07dca5c0102831a9b3db2d17ee3a3a9fcc9081311c92b5479c9ea1cdcf49d3f4cfa81990c35849a3eb1a31dbe0c6b257f0d",
			"signing_algorithm": "ECDSA_P256",
			"hashing_algorithm": "SHA2_256",
			"sequence_number": "12",
			"weight": "250",
			"revoked": false
		},
		{
			"index": "14",
			"public_key": "0xebf2a717ffb63fd9aab2c161c5988347f98f75f7cdc853f30c85c1b697b1224aad7c3ada89e2c0f5797e549bc86834d7a4e0ce3ca4e300c780bb5d81d32953da",
			"signing_algorithm": "ECDSA_P256",
			"hashing_algorithm": "SHA3_256",
			"sequence_number": "0",
			"weight": "250",
			"revoked": true
		},
		{
			"index": "15",
			"public_key": "0xfda3f37f8289bbc26c3bd817034726fa3c23eb8d9420c4ac1eef808dd0ce9056b66d0ef022ff00501e9a78e72a6322356db494dcacfcdc3a270ee3110adf0d8b",
			"signing_algorithm": "ECDSA_P256",
			"hashing_algorithm": "SHA2_256",
			"sequence_number": "0",
			"weight": "250",
			"revoked": true
		},
		{
			"index": "16",
			"public_key": "0x708c3b36830e9d8dcfac9536fcec3df02fc24b82fbb793d5e3206c64ded49f8e11bcf2aa535b2c2f8e6ace17b6f3c8c6edd0d041222023e8e4b0729b07726b74",
			"signing_algorithm": "ECDSA_P256",
			"hashing_algorithm": "SHA2_256",
			"sequence_number": "0",
			"weight": "250",
			"revoked": false
		},
		{
			"index": "17",
			"public_key": "0xee4aec89e6d83fe563ee93de01374961fcf117b7e746c78b3097f54b630a053fd4ee70a4bde974ce12d71deb444c5c23c224ad92f05a6f72b54742fd9700a3b7",
			"signing_algorithm": "ECDSA_P256",
			"hashing_algorithm": "SHA2_256",
			"sequence_number": "0",
			"weight": "250",
			"revoked": true
		},
		{
			"index": "18",
			"public_key": "0x475aac6dc9e0a045323f8e24f0aa8ebbec9dfedc34a5cc47bbb206f8d639f03812231731a9608edab6582056ab0a3281350666330daca384c7dff777cc6823be",
			"signing_algorithm": "ECDSA_P256",
			"hashing_algorithm": "SHA2_256",
			"sequence_number": "2",
			"weight": "250",
			"revoked": false
		},
		{
			"index": "19",
			"public_key": "0x9a9b21fd1a3bba399fc88289da202d14fd3dc03498f06d77af15f2c30a30f4138118410d7ade3a21a103752b385b15abbeca50d271583de0eb5bb0465310baa3",
			"signing_algorithm": "ECDSA_P256",
			"hashing_algorithm": "SHA2_256",
			"sequence_number": "0",
			"weight": "250",
			"revoked": false
		}
	],
	"contracts": {
		"AccountV2Migration": "YWNjZXNzKGFsbCkKY29udHJhY3QgQWNjb3VudFYyTWlncmF0aW9uIHsKCiAgICBhY2Nlc3MoYWxsKQogICAgZW51bSBTdG9yYWdlRm9ybWF0OiBVSW50OCB7CiAgICAgICAgYWNjZXNzKGFsbCkKICAgICAgICBjYXNlIFVua25vd24KCiAgICAgICAgYWNjZXNzKGFsbCkKICAgICAgICBjYXNlIFYxCgogICAgICAgIGFjY2VzcyhhbGwpCiAgICAgICAgY2FzZSBWMgogICAgfQoKICAgIGFjY2VzcyhhbGwpCiAgICBldmVudCBNaWdyYXRlZCgKICAgICAgICBhZGRyZXNzU3RhcnRJbmRleDogVUludDY0LAogICAgICAgIGNvdW50OiBVSW50NjQKICAgICkKCiAgICBhY2Nlc3MoYWxsKQogICAgcmVzb3VyY2UgQWRtaW4gewogICAgICAgIGFjY2VzcyhhbGwpCiAgICAgICAgZnVuIHNldE5leHRBZGRyZXNzU3RhcnRJbmRleChfIG5leHRBZGRyZXNzU3RhcnRJbmRleDogVUludDY0KSB7CiAgICAgICAgICAgIEFjY291bnRWMk1pZ3JhdGlvbi5uZXh0QWRkcmVzc1N0YXJ0SW5kZXggPSBuZXh0QWRkcmVzc1N0YXJ0SW5kZXgKICAgICAgICB9CgogICAgICAgIGFjY2VzcyhhbGwpCiAgICAgICAgZnVuIHNldEJhdGNoU2l6ZShfIGJhdGNoU2l6ZTogVUludDY0KSB7CiAgICAgICAgICAgIEFjY291bnRWMk1pZ3JhdGlvbi5iYXRjaFNpemUgPSBiYXRjaFNpemUKICAgICAgICB9CgogICAgICAgIGFjY2VzcyhhbGwpCiAgICAgICAgZnVuIHNldE1heEFkZHJlc3NJbmRleChfIG1heEFkZHJlc3NJbmRleDogVUludDY0KSB7CiAgICAgICAgICAgIEFjY291bnRWMk1pZ3JhdGlvbi5tYXhBZGRyZXNzSW5kZXggPSBtYXhBZGRyZXNzSW5kZXgKICAgICAgICB9CgogICAgICAgIGFjY2VzcyhhbGwpCiAgICAgICAgZnVuIG1pZ3JhdGVOZXh0QmF0Y2goKSB7CiAgICAgICAgICAgIEFjY291bnRWMk1pZ3JhdGlvbi5taWdyYXRlTmV4dEJhdGNoKCkKICAgICAgICB9CiAgICB9CgogICAgYWNjZXNzKGFsbCkKICAgIGxldCBhZG1pblN0b3JhZ2VQYXRoOiBTdG9yYWdlUGF0aAoKICAgIGFjY2VzcyhhbGwpCiAgICB2YXIgbmV4dEFkZHJlc3NTdGFydEluZGV4OiBVSW50NjQKCiAgICBhY2Nlc3MoYWxsKQogICAgdmFyIG1heEFkZHJlc3NJbmRleDogVUludDY0CgogICAgYWNjZXNzKGFsbCkKICAgIHZhciBiYXRjaFNpemU6IFVJbnQ2NAoKICAgIGluaXQoKSB7CiAgICAgICAgc2VsZi5hZG1pblN0b3JhZ2VQYXRoID0gL3N0b3JhZ2UvYWNjb3VudFYyTWlncmF0aW9uQWRtaW4KICAgICAgICBzZWxmLm5leHRBZGRyZXNzU3RhcnRJbmRleCA9IDEKICAgICAgICBzZWxmLm1heEFkZHJlc3NJbmRleCA9IDAKICAgICAgICBzZWxmLmJhdGNoU2l6ZSA9IDAKCiAgICAgICAgc2VsZi5hY2NvdW50LnN0b3JhZ2Uuc2F2ZSgKICAgICAgICAgICAgPC1jcmVhdGUgQWRtaW4oKSwKICAgICAgICAgICAgdG86IHNlbGYuYWRtaW5TdG9yYWdlUGF0aAogICAgICAgICkKICAgIH0KCiAgICBhY2Nlc3MoYWNjb3VudCkKICAgIGZ1biBtaWdyYXRlTmV4dEJhdGNoKCkgewogICAgICAgIHZhciBiYXRjaFNpemUgPSBzZWxmLmJhdGNoU2l6ZQogICAgICAgIGlmIGJhdGNoU2l6ZSA8PSAwIHsKICAgICAgICAgICAgcmV0dXJuCiAgICAgICAgfQoKICAgICAgICBsZXQgc3RhcnRJbmRleCA9IHNlbGYubmV4dEFkZHJlc3NTdGFydEluZGV4CiAgICAgICAgaWYgc3RhcnRJbmRleCA+IHNlbGYubWF4QWRkcmVzc0luZGV4IHsKICAgICAgICAgICAgcmV0dXJuCiAgICAgICAgfQoKICAgICAgICBsZXQgbWF4QmF0Y2hTaXplID0gc2VsZi5tYXhBZGRyZXNzSW5kZXggLSBzdGFydEluZGV4ICsgMQogICAgICAgIGlmIGJhdGNoU2l6ZSA+IG1heEJhdGNoU2l6ZSB7CiAgICAgICAgICAgIGJhdGNoU2l6ZSA9IG1heEJhdGNoU2l6ZQogICAgICAgIH0KCiAgICAgICAgaWYgIXNjaGVkdWxlQWNjb3VudFYyTWlncmF0aW9uKAogICAgICAgICAgICBhZGRyZXNzU3RhcnRJbmRleDogc3RhcnRJbmRleCwKICAgICAgICAgICAgY291bnQ6IGJhdGNoU2l6ZQogICAgICAgICkgewogICAgICAgICAgICByZXR1cm4KICAgICAgICB9CgogICAgICAgIHNlbGYubmV4dEFkZHJlc3NTdGFydEluZGV4ID0gc3RhcnRJbmRleCArIGJhdGNoU2l6ZQoKICAgICAgICBlbWl0IE1pZ3JhdGVkKAogICAgICAgICAgICBhZGRyZXNzU3RhcnRJbmRleDogc3RhcnRJbmRleCwKICAgICAgICAgICAgY291bnQ6IGJhdGNoU2l6ZQogICAgICAgICkKICAgIH0KCiAgICBhY2Nlc3MoYWxsKQogICAgZnVuIGdldEFjY291bnRTdG9yYWdlRm9ybWF0KGFkZHJlc3M6IEFkZHJlc3MpOiBTdG9yYWdlRm9ybWF0PyB7CiAgICAgICAgbGV0IHJhd1N0b3JhZ2VGb3JtYXQgPSBnZXRBY2NvdW50U3RvcmFnZUZvcm1hdChhZGRyZXNzOiBhZGRyZXNzKQogICAgICAgIHJldHVybiBTdG9yYWdlRm9ybWF0KHJhd1ZhbHVlOiByYXdTdG9yYWdlRm9ybWF0KQogICAgfQp9Cg==",
		"Crypto": "CmFjY2VzcyhhbGwpIGNvbnRyYWN0IENyeXB0byB7CgogICAgYWNjZXNzKGFsbCkKICAgIGZ1biBoYXNoKF8gZGF0YTogW1VJbnQ4XSwgYWxnb3JpdGhtOiBIYXNoQWxnb3JpdGhtKTogW1VJbnQ4XSB7CiAgICAgICAgcmV0dXJuIGFsZ29yaXRobS5oYXNoKGRhdGEpCiAgICB9CgogICAgYWNjZXNzKGFsbCkKICAgIGZ1biBoYXNoV2l0aFRhZyhfIGRhdGE6IFtVSW50OF0sIHRhZzogU3RyaW5nLCBhbGdvcml0aG06IEhhc2hBbGdvcml0aG0pOiBbVUludDhdIHsKICAgICAgICByZXR1cm4gYWxnb3JpdGhtLmhhc2hXaXRoVGFnKGRhdGEsIHRhZzogdGFnKQogICAgfQoKICAgIGFjY2VzcyhhbGwpCiAgICBzdHJ1Y3QgS2V5TGlzdEVudHJ5IHsKCiAgICAgICAgYWNjZXNzKGFsbCkKICAgICAgICBsZXQga2V5SW5kZXg6IEludAoKICAgICAgICBhY2Nlc3MoYWxsKQogICAgICAgIGxldCBwdWJsaWNLZXk6IFB1YmxpY0tleQoKICAgICAgICBhY2Nlc3MoYWxsKQogICAgICAgIGxldCBoYXNoQWxnb3JpdGhtOiBIYXNoQWxnb3JpdGhtCgogICAgICAgIGFjY2VzcyhhbGwpCiAgICAgICAgbGV0IHdlaWdodDogVUZpeDY0CgogICAgICAgIGFjY2VzcyhhbGwpCiAgICAgICAgbGV0IGlzUmV2b2tlZDogQm9vbAoKICAgICAgICBpbml0KAogICAgICAgICAgICBrZXlJbmRleDogSW50LAogICAgICAgICAgICBwdWJsaWNLZXk6IFB1YmxpY0tleSwKICAgICAgICAgICAgaGFzaEFsZ29yaXRobTogSGFzaEFsZ29yaXRobSwKICAgICAgICAgICAgd2VpZ2h0OiBVRml4NjQsCiAgICAgICAgICAgIGlzUmV2b2tlZDogQm9vbAogICAgICAgICkgewogICAgICAgICAgICBzZWxmLmtleUluZGV4ID0ga2V5SW5kZXgKICAgICAgICAgICAgc2VsZi5wdWJsaWNLZXkgPSBwdWJsaWNLZXkKICAgICAgICAgICAgc2VsZi5oYXNoQWxnb3JpdGhtID0gaGFzaEFsZ29yaXRobQogICAgICAgICAgICBzZWxmLndlaWdodCA9IHdlaWdodAogICAgICAgICAgICBzZWxmLmlzUmV2b2tlZCA9IGlzUmV2b2tlZAogICAgICAgIH0KICAgIH0KCiAgICBhY2Nlc3MoYWxsKQogICAgc3RydWN0IEtleUxpc3QgewoKICAgICAgICBhY2Nlc3Moc2VsZikKICAgICAgICBsZXQgZW50cmllczogW0tleUxpc3RFbnRyeV0KCiAgICAgICAgaW5pdCgpIHsKICAgICAgICAgICAgc2VsZi5lbnRyaWVzID0gW10KICAgICAgICB9CgogICAgICAgIC8vLyBBZGRzIGEgbmV3IGtleSB3aXRoIHRoZSBnaXZlbiB3ZWlnaHQKICAgICAgICBhY2Nlc3MoYWxsKQogICAgICAgIGZ1biBhZGQoCiAgICAgICAgICAgIF8gcHVibGljS2V5OiBQdWJsaWNLZXksCiAgICAgICAgICAgIGhhc2hBbGdvcml0aG06IEhhc2hBbGdvcml0aG0sCiAgICAgICAgICAgIHdlaWdodDogVUZpeDY0CiAgICAgICAgKTogS2V5TGlzdEVudHJ5IHsKCiAgICAgICAgICAgIGxldCBrZXlJbmRleCA9IHNlbGYuZW50cmllcy5sZW5ndGgKICAgICAgICAgICAgbGV0IGVudHJ5ID0gS2V5TGlzdEVudHJ5KAogICAgICAgICAgICAgICAga2V5SW5kZXg6IGtleUluZGV4LAogICAgICAgICAgICAgICAgcHVibGljS2V5OiBwdWJsaWNLZXksCiAgICAgICAgICAgICAgICBoYXNoQWxnb3JpdGhtOiBoYXNoQWxnb3JpdGhtLAogICAgICAgICAgICAgICAgd2VpZ2h0OiB3ZWlnaHQsCiAgICAgICAgICAgICAgICBpc1Jldm9rZWQ6IGZhbHNlCiAgICAgICAgICAgICkKICAgICAgICAgICAgc2VsZi5lbnRyaWVzLmFwcGVuZChlbnRyeSkKICAgICAgICAgICAgcmV0dXJuIGVudHJ5CiAgICAgICAgfQoKICAgICAgICAvLy8gUmV0dXJucyB0aGUga2V5IGF0IHRoZSBnaXZlbiBpbmRleCwgaWYgaXQgZXhpc3RzLgogICAgICAgIC8vLyBSZXZva2VkIGtleXMgYXJlIGFsd2F5cyByZXR1cm5lZCwgYnV0IHRoZXkgaGF2ZSB0aGUgYGlzUmV2b2tlZGAgZmllbGQgc2V0IHRvIHRydWUKICAgICAgICBhY2Nlc3MoYWxsKQogICAgICAgIGZ1biBnZXQoa2V5SW5kZXg6IEludCk6IEtleUxpc3RFbnRyeT8gewogICAgICAgICAgICBpZiBrZXlJbmRleCA+PSBzZWxmLmVudHJpZXMubGVuZ3RoIHsKICAgICAgICAgICAgICAgIHJldHVybiBuaWwKICAgICAgICAgICAgfQoKICAgICAgICAgICAgcmV0dXJuIHNlbGYuZW50cmllc1trZXlJbmRleF0KICAgICAgICB9CgogICAgICAgIC8vLyBNYXJrcyB0aGUga2V5IGF0IHRoZSBnaXZlbiBpbmRleCByZXZva2VkLCBidXQgZG9lcyBub3QgZGVsZXRlIGl0CiAgICAgICAgYWNjZXNzKGFsbCkKICAgICAgICBmdW4gcmV2b2tlKGtleUluZGV4OiBJbnQpIHsKICAgICAgICAgICAgaWYga2V5SW5kZXggPj0gc2VsZi5lbnRyaWVzLmxlbmd0aCB7CiAgICAgICAgICAgICAgICByZXR1cm4KICAgICAgICAgICAgfQoKICAgICAgICAgICAgbGV0IGN1cnJlbnRFbnRyeSA9IHNlbGYuZW50cmllc1trZXlJbmRleF0KICAgICAgICAgICAgc2VsZi5lbnRyaWVzW2tleUluZGV4XSA9IEtleUxpc3RFbnRyeSgKICAgICAgICAgICAgICAgIGtleUluZGV4OiBjdXJyZW50RW50cnkua2V5SW5kZXgsCiAgICAgICAgICAgICAgICBwdWJsaWNLZXk6IGN1cnJlbnRFbnRyeS5wdWJsaWNLZXksCiAgICAgICAgICAgICAgICBoYXNoQWxnb3JpdGhtOiBjdXJyZW50RW50cnkuaGFzaEFsZ29yaXRobSwKICAgICAgICAgICAgICAgIHdlaWdodDogY3VycmVudEVudHJ5LndlaWdodCwKICAgICAgICAgICAgICAgIGlzUmV2b2tlZDogdHJ1ZQogICAgICAgICAgICApCiAgICAgICAgfQoKICAgICAgICAvLy8gUmV0dXJucyB0cnVlIGlmIHRoZSBnaXZlbiBzaWduYXR1cmVzIGFyZSB2YWxpZCBmb3IgdGhlIGdpdmVuIHNpZ25lZCBkYXRhCiAgICAgICAgYWNjZXNzKGFsbCkKICAgICAgICBmdW4gdmVyaWZ5KAogICAgICAgICAgICBzaWduYXR1cmVTZXQ6IFtLZXlMaXN0U2lnbmF0dXJlXSwKICAgICAgICAgICAgc2lnbmVkRGF0YTogW1VJbnQ4XSwKICAgICAgICAgICAgZG9tYWluU2VwYXJhdGlvblRhZzogU3RyaW5nCiAgICAgICAgKTogQm9vbCB7CgogICAgICAgICAgICB2YXIgdmFsaWRXZWlnaHRzOiBVRml4NjQgPSAwLjAKCiAgICAgICAgICAgIGxldCBzZWVuS2V5SW5kaWNlczoge0ludDogQm9vbH0gPSB7fQoKICAgICAgICAgICAgZm9yIHNpZ25hdHVyZSBpbiBzaWduYXR1cmVTZXQgewoKICAgICAgICAgICAgICAgIC8vIEVuc3VyZSB0aGUga2V5IGluZGV4IGlzIHZhbGlkCiAgICAgICAgICAgICAgICBpZiBzaWduYXR1cmUua2V5SW5kZXggPj0gc2VsZi5lbnRyaWVzLmxlbmd0aCB7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlCiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgLy8gRW5zdXJlIHRoaXMga2V5IGluZGV4IGhhcyBub3QgYWxyZWFkeSBiZWVuIHNlZW4KICAgICAgICAgICAgICAgIGlmIHNlZW5LZXlJbmRpY2VzW3NpZ25hdHVyZS5rZXlJbmRleF0gPz8gZmFsc2UgewogICAgICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZQogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIC8vIFJlY29yZCB0aGUga2V5IGluZGV4IHdhcyBzZWVuCiAgICAgICAgICAgICAgICBzZWVuS2V5SW5kaWNlc1tzaWduYXR1cmUua2V5SW5kZXhdID0gdHJ1ZQoKICAgICAgICAgICAgICAgIC8vIEdldCB0aGUgYWN0dWFsIGtleQogICAgICAgICAgICAgICAgbGV0IGtleSA9IHNlbGYuZW50cmllc1tzaWduYXR1cmUua2V5SW5kZXhdCgogICAgICAgICAgICAgICAgLy8gRW5zdXJlIHRoZSBrZXkgaXMgbm90IHJldm9rZWQKICAgICAgICAgICAgICAgIGlmIGtleS5pc1Jldm9rZWQgewogICAgICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZQogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIC8vIEVuc3VyZSB0aGUgc2lnbmF0dXJlIGlzIHZhbGlkCiAgICAgICAgICAgICAgICBpZiAha2V5LnB1YmxpY0tleS52ZXJpZnkoCiAgICAgICAgICAgICAgICAgICAgc2lnbmF0dXJlOiBzaWduYXR1cmUuc2lnbmF0dXJlLAogICAgICAgICAgICAgICAgICAgIHNpZ25lZERhdGE6IHNpZ25lZERhdGEsCiAgICAgICAgICAgICAgICAgICAgZG9tYWluU2VwYXJhdGlvblRhZzogZG9tYWluU2VwYXJhdGlvblRhZywKICAgICAgICAgICAgICAgICAgICBoYXNoQWxnb3JpdGhtOmtleS5oYXNoQWxnb3JpdGhtCiAgICAgICAgICAgICAgICApIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2UKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICB2YWxpZFdlaWdodHMgPSB2YWxpZFdlaWdodHMgKyBrZXkud2VpZ2h0CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHJldHVybiB2YWxpZFdlaWdodHMgPj0gMS4wCiAgICAgICAgfQogICAgfQoKICAgIGFjY2VzcyhhbGwpCiAgICBzdHJ1Y3QgS2V5TGlzdFNpZ25hdHVyZSB7CgogICAgICAgIGFjY2VzcyhhbGwpCiAgICAgICAgbGV0IGtleUluZGV4OiBJbnQKCiAgICAgICAgYWNjZXNzKGFsbCkKICAgICAgICBsZXQgc2lnbmF0dXJlOiBbVUludDhdCgogICAgICAgIGluaXQoa2V5SW5kZXg6IEludCwgc2lnbmF0dXJlOiBbVUludDhdKSB7CiAgICAgICAgICAgIHNlbGYua2V5SW5kZXggPSBrZXlJbmRleAogICAgICAgICAgICBzZWxmLnNpZ25hdHVyZSA9IHNpZ25hdHVyZQogICAgICAgIH0KICAgIH0KfQ==",
		"DependencyAudit": "aW1wb3J0IE1pZ3JhdGlvbkNvbnRyYWN0U3RhZ2luZyBmcm9tIDB4NTYxMDBkNDZhYTliMDIxMgoKLy8gVGhpcyBjb250cmFjdCBpcyBpcyB1c2VkIGJ5IHRoZSBGVk0gY2FsbGluZyB0aGUgYGNoZWNrRGVwZW5kZW5jaWVzYCBmdW5jdGlvbiBmcm9tIGEgZnVuY3Rpb24gb2YgdGhlIHNhbWUgbmFtZSBhbmQgc2luZ25hdHVyZSBpbiB0aGUgRmxvd1NlcnZpY2VBY2NvdW50IGNvbnRyYWN0LAovLyBhdCB0aGUgZW5kIG9mIGV2ZXJ5IHRyYW5zYWN0aW9uLgovLyBUaGUgYGRlcGVuZGVuY2llc0FkZHJlc3Nlc2AgYW5kIGBkZXBlbmRlbmNpZXNOYW1lc2Agd2lsbCBiZSBhbGwgdGhlIGRlcGVuZGVuY2llcyBuZWVkZGVkIHRvIHJ1biB0aGF0IHRyYW5zYWN0aW9uLgovLwovLyBUaGUgYGNoZWNrRGVwZW5kZW5jaWVzYCBmdW5jdGlvbiB3aWxsIGNoZWNrIGlmIGFueSBvZiB0aGUgZGVwZW5kZW5jaWVzIGFyZSBub3Qgc3RhZ2VkIGluIHRoZSBNaWdyYXRpb25Db250cmFjdFN0YWdpbmcgY29udHJhY3QuCi8vIElmIGFueSBvZiB0aGUgZGVwZW5kZW5jaWVzIGFyZSBub3Qgc3RhZ2VkLCB0aGUgZnVuY3Rpb24gd2lsbCBlbWl0IGFuIGV2ZW50IHdpdGggdGhlIHVuc3RhZ2VkIGRlcGVuZGVuY2llcywgb3IgcGFuaWMgaWYgYHBhbmljT25VbnN0YWdlZGAgaXMgc2V0IHRvIHRydWUuCmFjY2VzcyhhbGwpIGNvbnRyYWN0IERlcGVuZGVuY3lBdWRpdCB7CgogICAgYWNjZXNzKGFsbCkgbGV0IEFkbWluaXN0cmF0b3JTdG9yYWdlUGF0aDogU3RvcmFnZVBhdGgKCiAgICAvLyBUaGUgc3lzdGVtIGFkZHJlc3NlcyBoYXZlIGNvbnRyYWN0cyB0aGF0IHdpbGwgbm90IGJlIHN0YWdlcyB2aWEgdGhlIG1pZ3JhdGlvbiBjb250cmFjdCBzbyB3ZSBleGNsdWRlIHRoZW0gZnJvbSB0aGUgZGVwZW5kZW5jeSBjaGVrY3MKICAgIGFjY2VzcyhzZWxmKSB2YXIgZXhjbHVkZWRBZGRyZXNzZXM6IHtBZGRyZXNzOiBCb29sfQoKICAgIGFjY2VzcyhhbGwpIHZhciBwYW5pY09uVW5zdGFnZWQ6IEJvb2wKCiAgICBhY2Nlc3MoYWxsKSBldmVudCBVbnN0YWdlZERlcGVuZGVuY2llcyhkZXBlbmRlbmNpZXM6IFtEZXBlbmRlbmN5XSkKCiAgICBhY2Nlc3MoYWxsKSBldmVudCBQYW5pY09uVW5zdGFnZWREZXBlbmRlbmNpZXNDaGFuZ2VkKHNob3VsZFBhbmljOiBCb29sKQoKICAgIGFjY2VzcyhhbGwpIGV2ZW50IEJsb2NrQm91bmRhcmllc0NoYW5nZWQoc3RhcnQ6IFVJbnQ2ND8sIGVuZDogVUludDY0PykKCiAgICAvLyBjaGVja0RlcGVuZGVuY2llcyBpcyBjYWxsZWQgZnJvbSB0aGUgRmxvd1NlcnZpY2VBY2NvdW50IGNvbnRyYWN0CiAgICBhY2Nlc3MoYWNjb3VudCkgZnVuIGNoZWNrRGVwZW5kZW5jaWVzKF8gZGVwZW5kZW5jaWVzQWRkcmVzc2VzOiBbQWRkcmVzc10sIF8gZGVwZW5kZW5jaWVzTmFtZXM6IFtTdHJpbmddLCBfIGF1dGhvcml6ZXJzOiBbQWRkcmVzc10pIHsKICAgICAgICB2YXIgdW5zdGFnZWREZXBlbmRlbmNpZXM6IFtEZXBlbmRlbmN5XSA9IFtdCgogICAgICAgIHZhciBudW1EZXBlbmRlbmNpZXMgPSBkZXBlbmRlbmNpZXNBZGRyZXNzZXMubGVuZ3RoCiAgICAgICAgdmFyIGkgPSAwCiAgICAgICAgd2hpbGUgaSA8IG51bURlcGVuZGVuY2llcyB7CiAgICAgICAgICAgIGxldCBpc0V4Y2x1ZGVkID0gRGVwZW5kZW5jeUF1ZGl0LmV4Y2x1ZGVkQWRkcmVzc2VzW2RlcGVuZGVuY2llc0FkZHJlc3Nlc1tpXV0gPz8gZmFsc2UKICAgICAgICAgICAgaWYgaXNFeGNsdWRlZCB7CiAgICAgICAgICAgICAgICBpID0gaSArIDEKICAgICAgICAgICAgICAgIGNvbnRpbnVlCiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGxldCBzdGFnZWQgPSBNaWdyYXRpb25Db250cmFjdFN0YWdpbmcuaXNTdGFnZWQoYWRkcmVzczogZGVwZW5kZW5jaWVzQWRkcmVzc2VzW2ldLCBuYW1lOiBkZXBlbmRlbmNpZXNOYW1lc1tpXSkKICAgICAgICAgICAgaWYgIXN0YWdlZCB7CiAgICAgICAgICAgICAgICB1bnN0YWdlZERlcGVuZGVuY2llcy5hcHBlbmQoRGVwZW5kZW5jeShhZGRyZXNzOiBkZXBlbmRlbmNpZXNBZGRyZXNzZXNbaV0sIG5hbWU6IGRlcGVuZGVuY2llc05hbWVzW2ldKSkKICAgICAgICAgICAgfQoKICAgICAgICAgICAgaSA9IGkgKyAxCiAgICAgICAgfQoKICAgICAgICBpZiB1bnN0YWdlZERlcGVuZGVuY2llcy5sZW5ndGggPiAwIHsKICAgICAgICAgICAgc2VsZi5tYXliZVBhbmljT25VbnN0YWdlZERlcGVuZGVuY2llcyh1bnN0YWdlZERlcGVuZGVuY2llcykKCiAgICAgICAgICAgIGVtaXQgVW5zdGFnZWREZXBlbmRlbmNpZXMoZGVwZW5kZW5jaWVzOiB1bnN0YWdlZERlcGVuZGVuY2llcykKICAgICAgICB9CiAgICB9CgogICAgYWNjZXNzKHNlbGYpIGZ1biBtYXliZVBhbmljT25VbnN0YWdlZERlcGVuZGVuY2llcyhfIHVuc3RhZ2VkRGVwZW5kZW5jaWVzOiBbRGVwZW5kZW5jeV0pIHsKICAgICAgICAvLyBJZiBgcGFuaWNPblVuc3RhZ2VkYCBpcyBzZXQgdG8gZmFsc2UsIHRoZSBmdW5jdGlvbiB3aWxsIHJldHVybiB3aXRob3V0IHBhbmlja2luZwogICAgICAgIC8vIFRoZW4gY2hlY2sgaWYgd2Ugc2hvdWxkIHBhbmljIHJhbmRvbWx5CiAgICAgICAgaWYgIURlcGVuZGVuY3lBdWRpdC5wYW5pY09uVW5zdGFnZWQgfHwgIXNlbGYuc2hvdWxkUGFuaWNSYW5kb21seSgpIHsKICAgICAgICAgICAgcmV0dXJuCiAgICAgICAgfQoKICAgICAgICB2YXIgdW5zdGFnZWREZXBlbmRlbmNpZXNTdHJpbmcgPSAiIgogICAgICAgIHZhciBudW1VbnN0YWdlZERlcGVuZGVuY2llcyA9IHVuc3RhZ2VkRGVwZW5kZW5jaWVzLmxlbmd0aAogICAgICAgIHZhciBqID0gMAogICAgICAgIHdoaWxlIGogPCBudW1VbnN0YWdlZERlcGVuZGVuY2llcyB7CiAgICAgICAgICAgIGlmIGogPiAwIHsKICAgICAgICAgICAgICAgIHVuc3RhZ2VkRGVwZW5kZW5jaWVzU3RyaW5nID0gdW5zdGFnZWREZXBlbmRlbmNpZXNTdHJpbmcuY29uY2F0KCIsICIpCiAgICAgICAgICAgIH0KICAgICAgICAgICAgdW5zdGFnZWREZXBlbmRlbmNpZXNTdHJpbmcgPSB1bnN0YWdlZERlcGVuZGVuY2llc1N0cmluZy5jb25jYXQodW5zdGFnZWREZXBlbmRlbmNpZXNbal0udG9TdHJpbmcoKSkKCiAgICAgICAgICAgIGogPSBqICsgMQogICAgICAgIH0KCiAgICAgICAgLy8gdGhlIHRyYW5zYWN0aW9ucyB3aWxsIGZhaWwgd2l0aCBhIG1lc3NhZ2UgdGhhdCBsb29rcyBsaWtlIHRoaXM6IGBlcnJvcjogcGFuaWM6IEZvdW5kIHVuc3RhZ2VkIGRlcGVuZGVuY2llczogQS4yY2VhZTk1OWVkMWE3ZTdhLk1pZ3JhdGlvbkNvbnRyYWN0U3RhZ2luZywgQS4yY2VhZTk1OWVkMWE3ZTdhLkRlcGVuZGVuY3lBdWRpdGAKICAgICAgICBwYW5pYygiVGhpcyB0cmFuc2FjdGlvbiBpcyB1c2luZyBkZXBlbmRlbmNpZXMgbm90IHN0YWdlZCBmb3IgQ3Jlc2NlbmRvIHVwZ3JhZGUgY29taW5nIHNvb24hIExlYXJuIG1vcmU6IGh0dHBzOi8vYml0Lmx5L0ZMT1dDUkVTQ0VORE8uIERlcGVuZGVuY2llcyBub3Qgc3RhZ2VkOiAiLmNvbmNhdCh1bnN0YWdlZERlcGVuZGVuY2llc1N0cmluZykpCiAgICB9CgogICAgLy8gc2hvdWxkUGFuaWNSYW5kb21seSBpcyB1c2VkIHRvIHJhbmRvbWx5IHBhbmljIG9uIHVuc3RhZ2VkIGRlcGVuZGVuY2llcwogICAgLy8gVGhlIHByb2JhYmlsaXR5IG9mIHBhbmlja2luZyBpcyBiYXNlZCBvbiB0aGUgY3VycmVudCBibG9jayBoZWlnaHQgYW5kIHRoZSBzdGFydCBhbmQgZW5kIGJsb2NrIGhlaWdodHMKICAgIC8vIElmIHRoZSBzdGFydCBibG9jayBoZWlnaHQgaXMgZ3JlYXRlciB0aGFuIG9yIGVxdWFsIHRvIHRoZSBlbmQgYmxvY2sgaGVpZ2h0LCB0aGUgZnVuY3Rpb24gd2lsbCByZXR1cm4gdHJ1ZQogICAgLy8gVGhlIGZ1bmN0aW9uIHdpbGwgYWx3YXlzIHJldHVybiB0cnVlIGlmIHRoZSBjdXJyZW50IGJsb2NrIGlzIG1vcmUgdGhhbiB0aGUgZW5kIGJsb2NrIGhlaWdodAogICAgLy8gVGhlIGZ1bmN0aW9uIHdpbGwgYWx3YXlzIHJldHVybiBmYWxzZSBpZiB0aGUgY3VycmVudCBibG9jayBpcyBsZXNzIHRoYW4gdGhlIHN0YXJ0IGJsb2NrIGhlaWdodAogICAgLy8gVGhlIGZ1bmN0aW9uIHdpbGwgcmV0dXJuIHRydWUgaWYgYSByYW5kb20gbnVtYmVyIGJldHdlZW4gdGhlIHN0YXJ0IGFuZCBlbmQgYmxvY2sgaGVpZ2h0cyBpcyBsZXNzIHRoYW4gdGhlIGN1cnJlbnQgYmxvY2sgaGVpZ2h0CiAgICAvLyBUaGlzIG1lYW5zIHRoZSBwcm9iYWJpbGl0eSBvZiBwYW5pY2tpbmcgaW5jcmVhc2VzIGxpbmVhcmx5IGFzIHRoZSBjdXJyZW50IGJsb2NrIGhlaWdodCBhcHByb2FjaGVzIHRoZSBlbmQgYmxvY2sgaGVpZ2h0CiAgICBhY2Nlc3Moc2VsZikgZnVuIHNob3VsZFBhbmljUmFuZG9tbHkoKTogQm9vbCB7CiAgICAgICAgLy8gZ2V0IHN0YXJ0IGJsb2NrIGhlaWdodCBvciB0cnVlCiAgICAgICAgLy8gZ2V0IGVuZCBibG9jayBoZWlnaHQgb3IgdHJ1ZQogICAgICAgIC8vIGdldCBjdXJyZW50IGJsb2NrIGhlaWdodAogICAgICAgIC8vIGdldCByYW5kb20gbnVtYmVyIGJldHdlZW4gc3RhcnQgYW5kIGVuZAogICAgICAgIC8vIGlmIHJhbmRvbSBudW1iZXIgaXMgbGVzcyB0aGFuIGN1cnJlbnQgYmxvY2sgcmV0dXJuIHRydWUKICAgICAgICAvLyBlbHNlIHJldHVybiBmYWxzZQoKICAgICAgICBsZXQgbWF5YmVCb3VuZGFyaWVzID0gc2VsZi5nZXRCb3VuZGFyaWVzKCkKICAgICAgICBpZiBtYXliZUJvdW5kYXJpZXMgPT0gbmlsIHsKICAgICAgICAgICAgLy8gaWYgc2V0dGluZ3MgYXJlIGludmFsaWQgdXNlIGRlZmF1bHQgYmVoYXZpb3VyOiBwYW5pYyB0cnVlCiAgICAgICAgICAgIHJldHVybiB0cnVlCiAgICAgICAgfQogICAgICAgIGxldCBib3VuZGFyaWVzID0gbWF5YmVCb3VuZGFyaWVzIQoKICAgICAgICBsZXQgc3RhcnRCbG9jazogVUludDY0ID0gYm91bmRhcmllcy5zdGFydAogICAgICAgIGxldCBlbmRCbG9jazogVUludDY0ID0gYm91bmRhcmllcy5lbmQKICAgICAgICBsZXQgY3VycmVudEJsb2NrOiBVSW50NjQgPSBnZXRDdXJyZW50QmxvY2soKS5oZWlnaHQKCiAgICAgICAgaWYgc3RhcnRCbG9jayA+PSBlbmRCbG9jayB7CiAgICAgICAgICAgIC8vIHRoaXMgc2hvdWxkIG5ldmVyIGhhcHBlbiBiZWN1c2Ugd2UgdmFsaWRhdGUgdGhlIGJvdW5kYXJpZXMgd2hlbiBzZXR0aW5nIHRoZW0KICAgICAgICAgICAgLy8gaWYgc2V0dGluZ3MgYXJlIGludmFsaWQgdXNlIGRlZmF1bHQgYmVoYXZpb3VyOiBwYW5pYyB0cnVlCiAgICAgICAgICAgIHJldHVybiB0cnVlCiAgICAgICAgfQoKICAgICAgICBsZXQgZGlmID0gZW5kQmxvY2sgLSBzdGFydEJsb2NrCiAgICAgICAgdmFyIHJuZCA9IHJldmVydGlibGVSYW5kb208VUludDY0PigpICUgZGlmCiAgICAgICAgcm5kID0gcm5kICsgc3RhcnRCbG9jawoKICAgICAgICAvLyBmYWlsIGlmIHRoZSByYW5kb20gbnVtYmVyIGlzIGxlc3MgdGhhbiB0aGUgY3VycmVudCBibG9jawogICAgICAgIHJldHVybiBybmQgPCBjdXJyZW50QmxvY2sKICAgIH0KCiAgICBhY2Nlc3MoYWxsKSBzdHJ1Y3QgQm91bmRhcmllcyB7CiAgICAgICAgYWNjZXNzKGFsbCkgbGV0IHN0YXJ0OiBVSW50NjQKICAgICAgICBhY2Nlc3MoYWxsKSBsZXQgZW5kOiBVSW50NjQKCiAgICAgICAgaW5pdChzdGFydDogVUludDY0LCBlbmQ6IFVJbnQ2NCkgewogICAgICAgICAgICBzZWxmLnN0YXJ0ID0gc3RhcnQKICAgICAgICAgICAgc2VsZi5lbmQgPSBlbmQKICAgICAgICB9CiAgICB9CgogICAgYWNjZXNzKGFsbCkgZnVuIGdldEJvdW5kYXJpZXMoKTogQm91bmRhcmllcz8gewogICAgICAgIHJldHVybiBzZWxmLmFjY291bnQuc3RvcmFnZS5jb3B5PEJvdW5kYXJpZXM+KGZyb206IC9zdG9yYWdlL2Zsb3dEZXBlbmRlbmN5QXVkaXRCb3VuZGFyaWVzKQogICAgfQoKICAgIGFjY2VzcyhhbGwpIGZ1biBnZXRDdXJyZW50RmFpbHVyZVByb2JhYmlsaXR5KCk6IFVGaXg2NCB7CiAgICAgICAgaWYgIURlcGVuZGVuY3lBdWRpdC5wYW5pY09uVW5zdGFnZWQgewogICAgICAgICAgICByZXR1cm4gMC4wIGFzIFVGaXg2NAogICAgICAgIH0KCiAgICAgICAgbGV0IG1heWJlQm91bmRhcmllcyA9IHNlbGYuZ2V0Qm91bmRhcmllcygpCiAgICAgICAgaWYgbWF5YmVCb3VuZGFyaWVzID09IG5pbCB7CiAgICAgICAgICAgIHJldHVybiAxLjAgYXMgVUZpeDY0CiAgICAgICAgfQoKICAgICAgICBsZXQgYm91bmRhcmllcyA9IG1heWJlQm91bmRhcmllcyEKCiAgICAgICAgbGV0IHN0YXJ0QmxvY2s6IFVJbnQ2NCA9IGJvdW5kYXJpZXMuc3RhcnQKICAgICAgICBsZXQgZW5kQmxvY2s6IFVJbnQ2NCA9IGJvdW5kYXJpZXMuZW5kCiAgICAgICAgbGV0IGN1cnJlbnRCbG9jazogVUludDY0ID0gZ2V0Q3VycmVudEJsb2NrKCkuaGVpZ2h0CgogICAgICAgIGlmIHN0YXJ0QmxvY2sgPj0gZW5kQmxvY2sgewogICAgICAgICAgICByZXR1cm4gMS4wIGFzIFVGaXg2NAogICAgICAgIH0KICAgICAgICBpZiBjdXJyZW50QmxvY2sgPj0gZW5kQmxvY2sgewogICAgICAgICAgICByZXR1cm4gMS4wIGFzIFVGaXg2NAogICAgICAgIH0KICAgICAgICBpZiBjdXJyZW50QmxvY2sgPCBzdGFydEJsb2NrIHsKICAgICAgICAgICAgcmV0dXJuIDAuMCBhcyBVRml4NjQKICAgICAgICB9CgogICAgICAgIGxldCBkaWYgPSBlbmRCbG9jayAtIHN0YXJ0QmxvY2sKICAgICAgICBsZXQgY3VycmVudERpZiA9IGN1cnJlbnRCbG9jayAtIHN0YXJ0QmxvY2sKCiAgICAgICAgcmV0dXJuIFVGaXg2NChjdXJyZW50RGlmKSAvIFVGaXg2NChkaWYpCiAgICB9CgogICAgYWNjZXNzKHNlbGYpIGZ1biBzZXRCb3VuZGFyaWVzKGJvdW5kYXJpZXM6IEJvdW5kYXJpZXMpIHsKICAgICAgICBzZWxmLmFjY291bnQuc3RvcmFnZS5sb2FkPEJvdW5kYXJpZXM+KGZyb206IC9zdG9yYWdlL2Zsb3dEZXBlbmRlbmN5QXVkaXRCb3VuZGFyaWVzKQogICAgICAgIHNlbGYuYWNjb3VudC5zdG9yYWdlLnNhdmUoYm91bmRhcmllcywgdG86IC9zdG9yYWdlL2Zsb3dEZXBlbmRlbmN5QXVkaXRCb3VuZGFyaWVzKQogICAgfQoKICAgIGFjY2VzcyhzZWxmKSBmdW4gdW5zZXRCb3VuZGFyaWVzKCkgewogICAgICAgIHNlbGYuYWNjb3VudC5zdG9yYWdlLmxvYWQ8Qm91bmRhcmllcz4oZnJvbTogL3N0b3JhZ2UvZmxvd0RlcGVuZGVuY3lBdWRpdEJvdW5kYXJpZXMpCiAgICB9CgogICAgLy8gVGhlIEFkbWluaXN0cmF0b3IgcmVzb3JjZSBjYW4gYmUgdXNlZCB0byBhZGQgb3IgcmVtb3ZlIGFkZHJlc3NlcyBmcm9tIHRoZSBleGNsdWRlZEFkZHJlc3NlcyBkaWN0aW9uYXJ5CiAgICAvLwogICAgYWNjZXNzKGFsbCkgcmVzb3VyY2UgQWRtaW5pc3RyYXRvciB7CiAgICAgICAgLy8gYWRkRXhjbHVkZWRBZGRyZXNzZXMgYWRkIHRoZSBhZGRyZXNzZXMgdG8gdGhlIGV4Y2x1ZGVkQWRkcmVzc2VzIGRpY3Rpb25hcnkKICAgICAgICBhY2Nlc3MoYWxsKSBmdW4gYWRkRXhjbHVkZWRBZGRyZXNzZXMoYWRkcmVzc2VzOiBbQWRkcmVzc10pIHsKICAgICAgICAgICAgZm9yIGFkZHJlc3MgaW4gYWRkcmVzc2VzIHsKICAgICAgICAgICAgICAgIERlcGVuZGVuY3lBdWRpdC5leGNsdWRlZEFkZHJlc3Nlc1thZGRyZXNzXSA9IHRydWUKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgLy8gcmVtb3ZlRXhjbHVkZWRBZGRyZXNzZXMgcmVtb3ZlIHRoZSBhZGRyZXNzZXMgZnJvbSB0aGUgZXhjbHVkZWRBZGRyZXNzZXMgZGljdGlvbmFyeQogICAgICAgIGFjY2VzcyhhbGwpIGZ1biByZW1vdmVFeGNsdWRlZEFkZHJlc3NlcyhhZGRyZXNzZXM6IFtBZGRyZXNzXSkgewogICAgICAgICAgICBmb3IgYWRkcmVzcyBpbiBhZGRyZXNzZXMgewogICAgICAgICAgICAgICAgRGVwZW5kZW5jeUF1ZGl0LmV4Y2x1ZGVkQWRkcmVzc2VzLnJlbW92ZShrZXk6IGFkZHJlc3MpCiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIC8vIHNldFBhbmljT25VbnN0YWdlZERlcGVuZGVuY2llcyBzZXRzIHRoZSBgcGFuaWNPblVuc3RhZ2VkYCB2YXJpYWJsZSB0byB0aGUgdmFsdWUgb2YgYHNob3VsZFBhbmljYAogICAgICAgIGFjY2VzcyhhbGwpIGZ1biBzZXRQYW5pY09uVW5zdGFnZWREZXBlbmRlbmNpZXMoc2hvdWxkUGFuaWM6IEJvb2wpIHsKICAgICAgICAgICAgRGVwZW5kZW5jeUF1ZGl0LnBhbmljT25VbnN0YWdlZCA9IHNob3VsZFBhbmljCiAgICAgICAgICAgIGVtaXQgUGFuaWNPblVuc3RhZ2VkRGVwZW5kZW5jaWVzQ2hhbmdlZChzaG91bGRQYW5pYzogc2hvdWxkUGFuaWMpCiAgICAgICAgfQoKICAgICAgICAvLyBzZXRTdGFydEVuZEJsb2NrIHNldHMgdGhlIHN0YXJ0IGFuZCBlbmQgYmxvY2sgaGVpZ2h0cyBmb3IgdGhlIGBzaG91bGRQYW5pY1JhbmRvbWx5YCBmdW5jdGlvbgogICAgICAgIGFjY2VzcyhhbGwpIGZ1biBzZXRTdGFydEVuZEJsb2NrKHN0YXJ0OiBVSW50NjQsIGVuZDogVUludDY0KSB7CiAgICAgICAgICAgIHByZSB7CiAgICAgICAgICAgICAgICBzdGFydCA8IGVuZDogIlN0YXJ0IGJsb2NrIGhlaWdodCBtdXN0IGJlIGxlc3MgdGhhbiBlbmQgYmxvY2sgaGVpZ2h0IgogICAgICAgICAgICB9CgogICAgICAgICAgICBsZXQgYm91bmRhcmllcyA9IEJvdW5kYXJpZXMoc3RhcnQ6IHN0YXJ0LCBlbmQ6IGVuZCkKICAgICAgICAgICAgRGVwZW5kZW5jeUF1ZGl0LnNldEJvdW5kYXJpZXMoYm91bmRhcmllczogYm91bmRhcmllcykKICAgICAgICAgICAgZW1pdCBCbG9ja0JvdW5kYXJpZXNDaGFuZ2VkKHN0YXJ0OiBzdGFydCwgZW5kOiBlbmQpCiAgICAgICAgfQoKICAgICAgICAvLyB1bnNldFN0YXJ0RW5kQmxvY2sgdW5zZXRzIHRoZSBzdGFydCBhbmQgZW5kIGJsb2NrIGhlaWdodHMgZm9yIHRoZSBgc2hvdWxkUGFuaWNSYW5kb21seWAgZnVuY3Rpb24KICAgICAgICBhY2Nlc3MoYWxsKSBmdW4gdW5zZXRTdGFydEVuZEJsb2NrKCkgewogICAgICAgICAgICBEZXBlbmRlbmN5QXVkaXQudW5zZXRCb3VuZGFyaWVzKCkKICAgICAgICAgICAgZW1pdCBCbG9ja0JvdW5kYXJpZXNDaGFuZ2VkKHN0YXJ0OiBuaWwsIGVuZDogbmlsKQogICAgICAgIH0KCiAgICAgICAgLy8gdGVzdENoZWNrRGVwZW5kZW5jaWVzIGlzIHVzZWQgZm9yIHRlc3RpbmcgcHVycG9zZXMKICAgICAgICAvLyBJdCB3aWxsIGNhbGwgdGhlIGBjaGVja0RlcGVuZGVuY2llc2AgZnVuY3Rpb24gd2l0aCB0aGUgcHJvdmlkZWQgZGVwZW5kZW5jaWVzCiAgICAgICAgLy8gYGNoZWNrRGVwZW5kZW5jaWVzYCBpcyBvdGhlcndpc2Ugbm90IGNhbGxhYmxlIGZyb20gdGhlIG91dHNpZGUKICAgICAgICBhY2Nlc3MoYWxsKSBmdW4gdGVzdENoZWNrRGVwZW5kZW5jaWVzKF8gZGVwZW5kZW5jaWVzQWRkcmVzc2VzOiBbQWRkcmVzc10sIF8gZGVwZW5kZW5jaWVzTmFtZXM6IFtTdHJpbmddLCBfIGF1dGhvcml6ZXJzOiBbQWRkcmVzc10pIHsKICAgICAgICAgICAgcmV0dXJuIERlcGVuZGVuY3lBdWRpdC5jaGVja0RlcGVuZGVuY2llcyhkZXBlbmRlbmNpZXNBZGRyZXNzZXMsIGRlcGVuZGVuY2llc05hbWVzLCBhdXRob3JpemVycykKICAgICAgICB9CiAgICB9CgogICAgYWNjZXNzKGFsbCkgc3RydWN0IERlcGVuZGVuY3kgewogICAgICAgIGFjY2VzcyhhbGwpIGxldCBhZGRyZXNzOiBBZGRyZXNzCiAgICAgICAgYWNjZXNzKGFsbCkgbGV0IG5hbWU6IFN0cmluZwoKICAgICAgICBpbml0KGFkZHJlc3M6IEFkZHJlc3MsIG5hbWU6IFN0cmluZykgewogICAgICAgICAgICBzZWxmLmFkZHJlc3MgPSBhZGRyZXNzCiAgICAgICAgICAgIHNlbGYubmFtZSA9IG5hbWUKICAgICAgICB9CgogICAgICAgIGFjY2VzcyhhbGwpIGZ1biB0b1N0cmluZygpOiBTdHJpbmcgewogICAgICAgICAgICB2YXIgYWRkcmVzc1N0cmluZyA9IHNlbGYuYWRkcmVzcy50b1N0cmluZygpCiAgICAgICAgICAgIC8vIHJlbW92ZSAweCBwcmVmaXgKICAgICAgICAgICAgYWRkcmVzc1N0cmluZyA9IGFkZHJlc3NTdHJpbmcuc2xpY2UoZnJvbTogMiwgdXBUbzogYWRkcmVzc1N0cmluZy5sZW5ndGgpCiAgICAgICAgICAgIHJldHVybiAiQS4iLmNvbmNhdChhZGRyZXNzU3RyaW5nKS5jb25jYXQoIi4iKS5jb25jYXQoc2VsZi5uYW1lKQogICAgICAgIH0KICAgIH0KCiAgICAvLyBUaGUgYWRtaW4gcmVzb3VyY2UgaXMgc2F2ZWQgdG8gdGhlIHN0b3JhZ2Ugc28gdGhhdCB0aGUgYWRtaW4gY2FuIGJlIGFjY2Vzc2VkIGJ5IHRoZSBzZXJ2aWNlIGFjY291bnQKICAgIC8vIFRoZSBgZXhjbHVkZWRBZGRyZXNzZXNgIHdpbGwgYmUgdGhlIGFkZHJlc3NlcyB3aXRoIHRoZSBzeXN0ZW0gY29udHJhY3RzLgogICAgaW5pdChleGNsdWRlZEFkZHJlc3NlczogW0FkZHJlc3NdKSB7CiAgICAgICAgc2VsZi5leGNsdWRlZEFkZHJlc3NlcyA9IHt9CiAgICAgICAgc2VsZi5wYW5pY09uVW5zdGFnZWQgPSBmYWxzZQoKICAgICAgICBzZWxmLkFkbWluaXN0cmF0b3JTdG9yYWdlUGF0aCA9IC9zdG9yYWdlL2Zsb3dEZXBlbmRlbmN5QXVkaXRBZG1pbgoKICAgICAgICBmb3IgYWRkcmVzcyBpbiBleGNsdWRlZEFkZHJlc3NlcyB7CiAgICAgICAgICAgIHNlbGYuZXhjbHVkZWRBZGRyZXNzZXNbYWRkcmVzc10gPSB0cnVlCiAgICAgICAgfQoKICAgICAgICBsZXQgYWRtaW4gPC0gY3JlYXRlIEFkbWluaXN0cmF0b3IoKQogICAgICAgIHNlbGYuYWNjb3VudC5zdG9yYWdlLnNhdmUoPC1hZG1pbiwgdG86IHNlbGYuQWRtaW5pc3RyYXRvclN0b3JhZ2VQYXRoKQogICAgfQp9Cg==",
		"EVM": "aW1wb3J0IENyeXB0bwppbXBvcnQgTm9uRnVuZ2libGVUb2tlbiBmcm9tIDB4MWQ3ZTU3YWE1NTgxNzQ0OAppbXBvcnQgRnVuZ2libGVUb2tlbiBmcm9tIDB4ZjIzM2RjZWU4OGZlMGFiZQppbXBvcnQgRmxvd1Rva2VuIGZyb20gMHgxNjU0NjUzMzk5MDQwYTYxCgovKgoKICAgIFRoZSBGbG93IEVWTSBjb250cmFjdCBkZWZpbmVzIGltcG9ydGFudCB0eXBlcyBhbmQgZnVuY3Rpb25hbGl0eQogICAgdG8gYWxsb3cgQ2FkZW5jZSBjb2RlIGFuZCBGbG93IFNES3MgdG8gaW50ZXJmYWNlCiAgICB3aXRoIHRoZSBFdGhlcmV1bSBWaXJ0dWFsIE1hY2hpbmUgZW52aXJvbm1lbnQgb24gRmxvdy4KCiAgICBUaGUgRVZNIGNvbnRyYWN0IGVtaXRzIGV2ZW50cyB3aGVuIHJlbGV2YW50IGFjdGlvbnMgaGFwcGVuIGluIEZsb3cgRVZNCiAgICBzdWNoIGFzIGNyZWF0aW5nIG5ldyBibG9ja3MsIGV4ZWN1dGluZyB0cmFuc2FjdGlvbnMsIGFuZCBicmlkZ2luZyBGTE9XCgogICAgVGhpcyBjb250cmFjdCBhbHNvIGRlZmluZXMgQ2FkZW5jZS1Pd25lZCBBY2NvdW50IGZ1bmN0aW9uYWxpdHksCiAgICB3aGljaCBpcyBjdXJyZW50bHkgdGhlIG9ubHkgd2F5IGZvciBDYWRlbmNlIGNvZGUgdG8gaW50ZXJhY3Qgd2l0aCBGbG93IEVWTS4KCiAgICBBZGRpdGlvbmFsbHksIGZ1bmN0aW9uYWxpdHkgaXMgcHJvdmlkZWQgZm9yIGNvbW1vbiBFVk0gdHlwZXMKICAgIHN1Y2ggYXMgYWRkcmVzc2VzLCBiYWxhbmNlcywgQUJJcywgdHJhbnNhY3Rpb24gcmVzdWx0cywgYW5kIG1vcmUuCgogICAgVGhlIEVWTSBjb250cmFjdCBpcyBkZXBsb3llZCB0byB0aGUgRmxvdyBTZXJ2aWNlIEFjY291bnQgb24gZXZlcnkgbmV0d29yawogICAgYW5kIG1hbnkgb2YgaXRzIGZ1bmN0aW9uYWxpdHkgaXMgZGlyZWN0bHkgY29ubmVjdGVkIHRvIHRoZSBwcm90b2NvbCBzb2Z0d2FyZQogICAgdG8gYWxsb3cgaW50ZXJhY3Rpb24gd2l0aCB0aGUgRVZNLgoKICAgIFNlZSBhZGRpdGlvbmFsIEVWTSBkb2N1bWVudGF0aW9uIGhlcmU6IGh0dHBzOi8vZGV2ZWxvcGVycy5mbG93LmNvbS9idWlsZC9ldm0vaG93LWl0LXdvcmtzCgoqLwoKYWNjZXNzKGFsbCkgY29udHJhY3QgRVZNIHsKCiAgICAvLy8gQmxvY2sgZXhlY3V0ZWQgZXZlbnQgaXMgZW1pdHRlZCB3aGVuIGEgbmV3IGJsb2NrIGlzIGNyZWF0ZWQsCiAgICAvLy8gd2hpY2ggYWx3YXlzIGhhcHBlbnMgd2hlbiBhIHRyYW5zYWN0aW9uIGlzIGV4ZWN1dGVkLgogICAgYWNjZXNzKGFsbCkgZXZlbnQgQmxvY2tFeGVjdXRlZCAoCiAgICAgICAgLy8gaGVpZ2h0IG9yIG51bWJlciBvZiB0aGUgYmxvY2sKICAgICAgICBoZWlnaHQ6IFVJbnQ2NCwKICAgICAgICAvLyBoYXNoIG9mIHRoZSBibG9jawogICAgICAgIGhhc2g6IFtVSW50ODsgMzJdLAogICAgICAgIC8vIHRpbWVzdGFtcCBvZiB0aGUgYmxvY2sgY3JlYXRpb24KICAgICAgICB0aW1lc3RhbXA6IFVJbnQ2NCwKICAgICAgICAvLyB0b3RhbCBGbG93IHN1cHBseQogICAgICAgIHRvdGFsU3VwcGx5OiBJbnQsCiAgICAgICAgLy8gYWxsIGdhcyB1c2VkIGluIHRoZSBibG9jayBieSB0cmFuc2FjdGlvbnMgaW5jbHVkZWQKICAgICAgICB0b3RhbEdhc1VzZWQ6IFVJbnQ2NCwKICAgICAgICAvLyBwYXJlbnQgYmxvY2sgaGFzaAogICAgICAgIHBhcmVudEhhc2g6IFtVSW50ODsgMzJdLAogICAgICAgIC8vIHJvb3QgaGFzaCBvZiBhbGwgdGhlIHRyYW5zYWN0aW9uIHJlY2VpcHRzCiAgICAgICAgcmVjZWlwdFJvb3Q6IFtVSW50ODsgMzJdLAogICAgICAgIC8vIHJvb3QgaGFzaCBvZiBhbGwgdGhlIHRyYW5zYWN0aW9uIGhhc2hlcwogICAgICAgIHRyYW5zYWN0aW9uSGFzaFJvb3Q6IFtVSW50ODsgMzJdLAogICAgICAgIC8vLyB2YWx1ZSByZXR1cm5lZCBmb3IgUFJFVlJBTkRBTyBvcGNvZGUKICAgICAgICBwcmV2cmFuZGFvOiBbVUludDg7IDMyXSwKICAgICkKCiAgICAvLy8gVHJhbnNhY3Rpb24gZXhlY3V0ZWQgZXZlbnQgaXMgZW1pdHRlZCBldmVyeSB0aW1lIGEgdHJhbnNhY3Rpb24KICAgIC8vLyBpcyBleGVjdXRlZCBieSB0aGUgRVZNIChldmVuIGlmIGZhaWxlZCkuCiAgICBhY2Nlc3MoYWxsKSBldmVudCBUcmFuc2FjdGlvbkV4ZWN1dGVkICgKICAgICAgICAvLyBoYXNoIG9mIHRoZSB0cmFuc2FjdGlvbgogICAgICAgIGhhc2g6IFtVSW50ODsgMzJdLAogICAgICAgIC8vIGluZGV4IG9mIHRoZSB0cmFuc2FjdGlvbiBpbiBhIGJsb2NrCiAgICAgICAgaW5kZXg6IFVJbnQxNiwKICAgICAgICAvLyB0eXBlIG9mIHRoZSB0cmFuc2FjdGlvbgogICAgICAgIHR5cGU6IFVJbnQ4LAogICAgICAgIC8vIFJMUCBlbmNvZGVkIHRyYW5zYWN0aW9uIHBheWxvYWQKICAgICAgICBwYXlsb2FkOiBbVUludDhdLAogICAgICAgIC8vIGNvZGUgaW5kaWNhdGluZyBhIHNwZWNpZmljIHZhbGlkYXRpb24gKDIwMS0zMDApIG9yIGV4ZWN1dGlvbiAoMzAxLTQwMCkgZXJyb3IKICAgICAgICBlcnJvckNvZGU6IFVJbnQxNiwKICAgICAgICAvLyBhIGh1bWFuLXJlYWRhYmxlIG1lc3NhZ2UgYWJvdXQgdGhlIGVycm9yIChpZiBhbnkpCiAgICAgICAgZXJyb3JNZXNzYWdlOiBTdHJpbmcsCiAgICAgICAgLy8gdGhlIGFtb3VudCBvZiBnYXMgdHJhbnNhY3Rpb24gdXNlZAogICAgICAgIGdhc0NvbnN1bWVkOiBVSW50NjQsCiAgICAgICAgLy8gaWYgdHJhbnNhY3Rpb24gd2FzIGEgZGVwbG95bWVudCBjb250YWlucyBhIG5ld2x5IGRlcGxveWVkIGNvbnRyYWN0IGFkZHJlc3MKICAgICAgICBjb250cmFjdEFkZHJlc3M6IFN0cmluZywKICAgICAgICAvLyBSTFAgZW5jb2RlZCBsb2dzCiAgICAgICAgbG9nczogW1VJbnQ4XSwKICAgICAgICAvLyBibG9jayBoZWlnaHQgaW4gd2hpY2ggdHJhbnNhY3Rpb24gd2FzIGluY2x1ZGVkCiAgICAgICAgYmxvY2tIZWlnaHQ6IFVJbnQ2NCwKICAgICAgICAvLy8gY2FwdHVyZXMgdGhlIGhleCBlbmNvZGVkIGRhdGEgdGhhdCBpcyByZXR1cm5lZCBmcm9tCiAgICAgICAgLy8vIHRoZSBldm0uIEZvciBjb250cmFjdCBkZXBsb3ltZW50cwogICAgICAgIC8vLyBpdCByZXR1cm5zIHRoZSBjb2RlIGRlcGxveWVkIHRvCiAgICAgICAgLy8vIHRoZSBhZGRyZXNzIHByb3ZpZGVkIGluIHRoZSBjb250cmFjdEFkZHJlc3MgZmllbGQuCiAgICAgICAgLy8vIGluIGNhc2Ugb2YgcmV2ZXJ0LCB0aGUgc21hcnQgY29udHJhY3QgY3VzdG9tIGVycm9yIG1lc3NhZ2UKICAgICAgICAvLy8gaXMgYWxzbyByZXR1cm5lZCBoZXJlIChzZWUgRUlQLTE0MCBmb3IgbW9yZSBkZXRhaWxzKS4KICAgICAgICByZXR1cm5lZERhdGE6IFtVSW50OF0sCiAgICAgICAgLy8vIGNhcHR1cmVzIHRoZSBpbnB1dCBhbmQgb3V0cHV0IG9mIHRoZSBjYWxscyAocmxwIGVuY29kZWQpIHRvIHRoZSBleHRyYQogICAgICAgIC8vLyBwcmVjb21waWxlZCBjb250cmFjdHMgKGUuZy4gQ2FkZW5jZSBBcmNoKSBkdXJpbmcgdGhlIHRyYW5zYWN0aW9uIGV4ZWN1dGlvbi4KICAgICAgICAvLy8gVGhpcyBkYXRhIGhlbHBzIHRvIHJlcGxheSB0aGUgdHJhbnNhY3Rpb25zIHdpdGhvdXQgdGhlIG5lZWQgdG8KICAgICAgICAvLy8gaGF2ZSBhY2Nlc3MgdG8gdGhlIGZ1bGwgY2FkZW5jZSBzdGF0ZSBkYXRhLgogICAgICAgIHByZWNvbXBpbGVkQ2FsbHM6IFtVSW50OF0sCiAgICAgICAgLy8vIHN0YXRlVXBkYXRlQ2hlY2tzdW0gcHJvdmlkZXMgYSBtZWFuIHRvIHZhbGlkYXRlCiAgICAgICAgLy8vIHRoZSB1cGRhdGVzIHRvIHRoZSBzdG9yYWdlIHdoZW4gcmUtZXhlY3V0aW5nIGEgdHJhbnNhY3Rpb24gb2ZmLWNoYWluLgogICAgICAgIHN0YXRlVXBkYXRlQ2hlY2tzdW06IFtVSW50ODsgNF0KICAgICkKCiAgICAvLy8gRkxPV1Rva2Vuc0RlcG9zaXRlZCBpcyBlbWl0dGVkIHdoZW4gRkxPVyB0b2tlbnMgaXMgYnJpZGdlZAogICAgLy8vIGludG8gdGhlIEVWTSBlbnZpcm9ubWVudC4gTm90ZSB0aGF0IHRoaXMgZXZlbnQgaXMgbm90IGVtaXR0ZWQKICAgIC8vLyBmb3IgdHJhbnNmZXIgb2YgZmxvdyB0b2tlbnMgYmV0d2VlbiB0d28gRVZNIGFkZHJlc3Nlcy4KICAgIC8vLyBTaW1pbGFyIHRvIHRoZSBGdW5naWJsZVRva2VuLkRlcG9zaXRlZCBldmVudAogICAgLy8vIHRoaXMgZXZlbnQgaW5jbHVkZXMgYSBkZXBvc2l0ZWRVVUlEIHRoYXQgY2FwdHVyZXMgdGhlCiAgICAvLy8gdXVpZCBvZiB0aGUgc291cmNlIHZhdWx0LgogICAgYWNjZXNzKGFsbCkgZXZlbnQgRkxPV1Rva2Vuc0RlcG9zaXRlZCAoCiAgICAgICAgYWRkcmVzczogU3RyaW5nLAogICAgICAgIGFtb3VudDogVUZpeDY0LAogICAgICAgIGRlcG9zaXRlZFVVSUQ6IFVJbnQ2NCwKICAgICAgICBiYWxhbmNlQWZ0ZXJJbkF0dG9GbG93OiBVSW50CiAgICApCgogICAgLy8vIEZMT1dUb2tlbnNXaXRoZHJhd24gaXMgZW1pdHRlZCB3aGVuIEZMT1cgdG9rZW5zIGFyZSBicmlkZ2VkCiAgICAvLy8gb3V0IG9mIHRoZSBFVk0gZW52aXJvbm1lbnQuIE5vdGUgdGhhdCB0aGlzIGV2ZW50IGlzIG5vdCBlbWl0dGVkCiAgICAvLy8gZm9yIHRyYW5zZmVyIG9mIGZsb3cgdG9rZW5zIGJldHdlZW4gdHdvIEVWTSBhZGRyZXNzZXMuCiAgICAvLy8gc2ltaWxhciB0byB0aGUgRnVuZ2libGVUb2tlbi5XaXRoZHJhd24gZXZlbnRzCiAgICAvLy8gdGhpcyBldmVudCBpbmNsdWRlcyBhIHdpdGhkcmF3blVVSUQgdGhhdCBjYXB0dXJlcyB0aGUKICAgIC8vLyB1dWlkIG9mIHRoZSByZXR1cm5pbmcgdmF1bHQuCiAgICBhY2Nlc3MoYWxsKSBldmVudCBGTE9XVG9rZW5zV2l0aGRyYXduICgKICAgICAgICBhZGRyZXNzOiBTdHJpbmcsCiAgICAgICAgYW1vdW50OiBVRml4NjQsCiAgICAgICAgd2l0aGRyYXduVVVJRDogVUludDY0LAogICAgICAgIGJhbGFuY2VBZnRlckluQXR0b0Zsb3c6IFVJbnQKICAgICkKCiAgICAvLy8gQnJpZGdlQWNjZXNzb3JVcGRhdGVkIGlzIGVtaXR0ZWQgd2hlbiB0aGUgQnJpZGdlQWNjZXNzb3IgQ2FwYWJpbGl0eQogICAgLy8vIGlzIHVwZGF0ZWQgaW4gdGhlIHN0b3JlZCBCcmlkZ2VSb3V0ZXIgYWxvbmcgd2l0aCBpZGVudGlmeWluZwogICAgLy8vIGluZm9ybWF0aW9uIGFib3V0IGJvdGguCiAgICBhY2Nlc3MoYWxsKSBldmVudCBCcmlkZ2VBY2Nlc3NvclVwZGF0ZWQgKAogICAgICAgIHJvdXRlclR5cGU6IFR5cGUsCiAgICAgICAgcm91dGVyVVVJRDogVUludDY0LAogICAgICAgIHJvdXRlckFkZHJlc3M6IEFkZHJlc3MsCiAgICAgICAgYWNjZXNzb3JUeXBlOiBUeXBlLAogICAgICAgIGFjY2Vzc29yVVVJRDogVUludDY0LAogICAgICAgIGFjY2Vzc29yQWRkcmVzczogQWRkcmVzcwogICAgKQoKICAgICAvLy8gQmxvY2sgcmV0dXJucyBpbmZvcm1hdGlvbiBhYm91dCB0aGUgbGF0ZXN0IGV4ZWN1dGVkIGJsb2NrLgogICAgYWNjZXNzKGFsbCkgc3RydWN0IEVWTUJsb2NrIHsKICAgICAgICBhY2Nlc3MoYWxsKSBsZXQgaGVpZ2h0OiBVSW50NjQKCiAgICAgICAgYWNjZXNzKGFsbCkgbGV0IGhhc2g6IFN0cmluZwoKICAgICAgICBhY2Nlc3MoYWxsKSBsZXQgdG90YWxTdXBwbHk6IEludAoKICAgICAgICBhY2Nlc3MoYWxsKSBsZXQgdGltZXN0YW1wOiBVSW50NjQKCiAgICAgICAgaW5pdChoZWlnaHQ6IFVJbnQ2NCwgaGFzaDogU3RyaW5nLCB0b3RhbFN1cHBseTogSW50LCB0aW1lc3RhbXA6IFVJbnQ2NCkgewogICAgICAgICAgICBzZWxmLmhlaWdodCA9IGhlaWdodAogICAgICAgICAgICBzZWxmLmhhc2ggPSBoYXNoCiAgICAgICAgICAgIHNlbGYudG90YWxTdXBwbHkgPSB0b3RhbFN1cHBseQogICAgICAgICAgICBzZWxmLnRpbWVzdGFtcCA9IHRpbWVzdGFtcAogICAgICAgIH0KICAgIH0KCiAgICAvLy8gUmV0dXJucyB0aGUgbGF0ZXN0IGV4ZWN1dGVkIGJsb2NrLgogICAgYWNjZXNzKGFsbCkKICAgIGZ1biBnZXRMYXRlc3RCbG9jaygpOiBFVk1CbG9jayB7CiAgICAgICAgcmV0dXJuIEludGVybmFsRVZNLmdldExhdGVzdEJsb2NrKCkgYXMhIEVWTUJsb2NrCiAgICB9CgogICAgLy8vIEVWTUFkZHJlc3MgaXMgYW4gRVZNLWNvbXBhdGlibGUgYWRkcmVzcwogICAgYWNjZXNzKGFsbCkgc3RydWN0IEVWTUFkZHJlc3MgewoKICAgICAgICAvLy8gQnl0ZXMgb2YgdGhlIGFkZHJlc3MKICAgICAgICBhY2Nlc3MoYWxsKSBsZXQgYnl0ZXM6IFtVSW50ODsgMjBdCgogICAgICAgIC8vLyBDb25zdHJ1Y3RzIGEgbmV3IEVWTSBhZGRyZXNzIGZyb20gdGhlIGdpdmVuIGJ5dGUgcmVwcmVzZW50YXRpb24KICAgICAgICB2aWV3IGluaXQoYnl0ZXM6IFtVSW50ODsgMjBdKSB7CiAgICAgICAgICAgIHNlbGYuYnl0ZXMgPSBieXRlcwogICAgICAgIH0KCiAgICAgICAgLy8vIEJhbGFuY2Ugb2YgdGhlIGFkZHJlc3MKICAgICAgICBhY2Nlc3MoYWxsKQogICAgICAgIHZpZXcgZnVuIGJhbGFuY2UoKTogQmFsYW5jZSB7CiAgICAgICAgICAgIGxldCBiYWxhbmNlID0gSW50ZXJuYWxFVk0uYmFsYW5jZSgKICAgICAgICAgICAgICAgIGFkZHJlc3M6IHNlbGYuYnl0ZXMKICAgICAgICAgICAgKQogICAgICAgICAgICByZXR1cm4gQmFsYW5jZShhdHRvZmxvdzogYmFsYW5jZSkKICAgICAgICB9CgogICAgICAgIC8vLyBOb25jZSBvZiB0aGUgYWRkcmVzcwogICAgICAgIGFjY2VzcyhhbGwpCiAgICAgICAgdmlldyBmdW4gbm9uY2UoKTogVUludDY0IHsKICAgICAgICAgICAgcmV0dXJuIEludGVybmFsRVZNLm5vbmNlKAogICAgICAgICAgICAgICAgYWRkcmVzczogc2VsZi5ieXRlcwogICAgICAgICAgICApCiAgICAgICAgfQoKICAgICAgICAvLy8gQ29kZSBvZiB0aGUgYWRkcmVzcwogICAgICAgIGFjY2VzcyhhbGwpCiAgICAgICAgdmlldyBmdW4gY29kZSgpOiBbVUludDhdIHsKICAgICAgICAgICAgcmV0dXJuIEludGVybmFsRVZNLmNvZGUoCiAgICAgICAgICAgICAgICBhZGRyZXNzOiBzZWxmLmJ5dGVzCiAgICAgICAgICAgICkKICAgICAgICB9CgogICAgICAgIC8vLyBDb2RlSGFzaCBvZiB0aGUgYWRkcmVzcwogICAgICAgIGFjY2VzcyhhbGwpCiAgICAgICAgdmlldyBmdW4gY29kZUhhc2goKTogW1VJbnQ4XSB7CiAgICAgICAgICAgIHJldHVybiBJbnRlcm5hbEVWTS5jb2RlSGFzaCgKICAgICAgICAgICAgICAgIGFkZHJlc3M6IHNlbGYuYnl0ZXMKICAgICAgICAgICAgKQogICAgICAgIH0KCiAgICAgICAgLy8vIERlcG9zaXRzIHRoZSBnaXZlbiB2YXVsdCBpbnRvIHRoZSBFVk0gYWNjb3VudCB3aXRoIHRoZSBnaXZlbiBhZGRyZXNzCiAgICAgICAgYWNjZXNzKGFsbCkKICAgICAgICBmdW4gZGVwb3NpdChmcm9tOiBARmxvd1Rva2VuLlZhdWx0KSB7CiAgICAgICAgICAgIHByZSB7CiAgICAgICAgICAgICAgICAhRVZNLmlzUGF1c2VkKCk6ICJFVk0gb3BlcmF0aW9ucyBhcmUgdGVtcG9yYXJpbHkgcGF1c2VkIgogICAgICAgICAgICB9CgogICAgICAgICAgICBsZXQgYW1vdW50ID0gZnJvbS5iYWxhbmNlCiAgICAgICAgICAgIGlmIGFtb3VudCA9PSAwLjAgewogICAgICAgICAgICAgICAgZGVzdHJveSBmcm9tCiAgICAgICAgICAgICAgICByZXR1cm4KICAgICAgICAgICAgfQogICAgICAgICAgICBsZXQgZGVwb3NpdGVkVVVJRCA9IGZyb20udXVpZAogICAgICAgICAgICBJbnRlcm5hbEVWTS5kZXBvc2l0KAogICAgICAgICAgICAgICAgZnJvbTogPC1mcm9tLAogICAgICAgICAgICAgICAgdG86IHNlbGYuYnl0ZXMKICAgICAgICAgICAgKQogICAgICAgICAgICBlbWl0IEZMT1dUb2tlbnNEZXBvc2l0ZWQoCiAgICAgICAgICAgICAgICBhZGRyZXNzOiBzZWxmLnRvU3RyaW5nKCksCiAgICAgICAgICAgICAgICBhbW91bnQ6IGFtb3VudCwKICAgICAgICAgICAgICAgIGRlcG9zaXRlZFVVSUQ6IGRlcG9zaXRlZFVVSUQsCiAgICAgICAgICAgICAgICBiYWxhbmNlQWZ0ZXJJbkF0dG9GbG93OiBzZWxmLmJhbGFuY2UoKS5hdHRvZmxvdwogICAgICAgICAgICApCiAgICAgICAgfQoKICAgICAgICAvLy8gU2VyaWFsaXplcyB0aGUgYWRkcmVzcyB0byBhIGhleCBzdHJpbmcgd2l0aG91dCB0aGUgMHggcHJlZml4CiAgICAgICAgLy8vIEZ1dHVyZSBpbXBsZW1lbnRhdGlvbnMgc2hvdWxkIHBhc3MgZGF0YSB0byBJbnRlcm5hbEVWTSBmb3IgbmF0aXZlIHNlcmlhbGl6YXRpb24KICAgICAgICBhY2Nlc3MoYWxsKQogICAgICAgIHZpZXcgZnVuIHRvU3RyaW5nKCk6IFN0cmluZyB7CiAgICAgICAgICAgIHJldHVybiBTdHJpbmcuZW5jb2RlSGV4KHNlbGYuYnl0ZXMudG9WYXJpYWJsZVNpemVkKCkpCiAgICAgICAgfQoKICAgICAgICAvLy8gQ29tcGFyZXMgdGhlIGFkZHJlc3Mgd2l0aCBhbm90aGVyIGFkZHJlc3MKICAgICAgICBhY2Nlc3MoYWxsKQogICAgICAgIHZpZXcgZnVuIGVxdWFscyhfIG90aGVyOiBFVk1BZGRyZXNzKTogQm9vbCB7CiAgICAgICAgICAgIHJldHVybiBzZWxmLmJ5dGVzID09IG90aGVyLmJ5dGVzCiAgICAgICAgfQogICAgfQoKICAgIC8vLyBDb252ZXJ0cyBhIGhleCBzdHJpbmcgdG8gYW4gRVZNIGFkZHJlc3MgaWYgdGhlIHN0cmluZyBpcyBhIHZhbGlkIGhleCBzdHJpbmcKICAgIC8vLyBGdXR1cmUgaW1wbGVtZW50YXRpb25zIHNob3VsZCBwYXNzIGRhdGEgdG8gSW50ZXJuYWxFVk0gZm9yIG5hdGl2ZSBkZXNlcmlhbGl6YXRpb24KICAgIGFjY2VzcyhhbGwpCiAgICBmdW4gYWRkcmVzc0Zyb21TdHJpbmcoXyBhc0hleDogU3RyaW5nKTogRVZNQWRkcmVzcyB7CiAgICAgICAgcHJlIHsKICAgICAgICAgICAgYXNIZXgubGVuZ3RoID09IDQwIHx8IGFzSGV4Lmxlbmd0aCA9PSA0MjoKICAgICAgICAgICAgICAgICJFVk0uYWRkcmVzc0Zyb21TdHJpbmcoKTogSW52YWxpZCBoZXggc3RyaW5nIGxlbmd0aCBmb3IgYW4gRVZNIGFkZHJlc3MuIFRoZSBwcm92aWRlZCBzdHJpbmcgaXMgXChhc0hleC5sZW5ndGgpLCBidXQgdGhlIGxlbmd0aCBtdXN0IGJlIDQwIG9yIDQyLiIKICAgICAgICB9CiAgICAgICAgLy8gU3RyaXAgdGhlIDB4IHByZWZpeCBpZiBpdCBleGlzdHMKICAgICAgICB2YXIgd2l0aG91dFByZWZpeCA9IGFzSGV4CiAgICAgICAgaWYgYXNIZXgubGVuZ3RoID09IDQyIHsKICAgICAgICAgICAgYXNzZXJ0KAogICAgICAgICAgICAgICAgYXNIZXhbMF0gPT0gIjAiICYmIGFzSGV4WzFdID09ICJ4IiwKICAgICAgICAgICAgICAgIG1lc3NhZ2U6ICJFVk0uYWRkcmVzc0Zyb21TdHJpbmcoKTogVGhlIDQyLWNoYXJhY3RlciBFVk0gYWRkcmVzcyBzdHJpbmcgbXVzdCBoYXZlIGEgJzB4JyBwcmVmaXgiCiAgICAgICAgICAgICkKICAgICAgICAgICAgd2l0aG91dFByZWZpeCA9IGFzSGV4LnNsaWNlKGZyb206IDIsIHVwVG86IGFzSGV4Lmxlbmd0aCkKICAgICAgICB9CgogICAgICAgIHJldHVybiBFVk1BZGRyZXNzKAogICAgICAgICAgICBieXRlczogd2l0aG91dFByZWZpeC5kZWNvZGVIZXgoKS50b0NvbnN0YW50U2l6ZWQ8W1VJbnQ4OyAyMF0+KCkhCiAgICAgICAgKQogICAgfQoKICAgIC8vLyBFVk1CeXRlcyBpcyBhIHR5cGUgd3JhcHBlciB1c2VkIGZvciBBQkkgZW5jb2RpbmcvZGVjb2RpbmcgaW50bwogICAgLy8vIFNvbGlkaXR5IGBieXRlc2AgdHlwZQogICAgYWNjZXNzKGFsbCkgc3RydWN0IEVWTUJ5dGVzIHsKCiAgICAgICAgLy8vIEJ5dGUgYXJyYXkgcmVwcmVzZW50aW5nIHRoZSBgYnl0ZXNgIHZhbHVlCiAgICAgICAgYWNjZXNzKGFsbCkgbGV0IHZhbHVlOiBbVUludDhdCgogICAgICAgIHZpZXcgaW5pdCh2YWx1ZTogW1VJbnQ4XSkgewogICAgICAgICAgICBzZWxmLnZhbHVlID0gdmFsdWUKICAgICAgICB9CiAgICB9CgogICAgLy8vIEVWTUJ5dGVzNCBpcyBhIHR5cGUgd3JhcHBlciB1c2VkIGZvciBBQkkgZW5jb2RpbmcvZGVjb2RpbmcgaW50bwogICAgLy8vIFNvbGlkaXR5IGBieXRlczRgIHR5cGUKICAgIGFjY2VzcyhhbGwpIHN0cnVjdCBFVk1CeXRlczQgewoKICAgICAgICAvLy8gQnl0ZSBhcnJheSByZXByZXNlbnRpbmcgdGhlIGBieXRlczRgIHZhbHVlCiAgICAgICAgYWNjZXNzKGFsbCkgbGV0IHZhbHVlOiBbVUludDg7IDRdCgogICAgICAgIHZpZXcgaW5pdCh2YWx1ZTogW1VJbnQ4OyA0XSkgewogICAgICAgICAgICBzZWxmLnZhbHVlID0gdmFsdWUKICAgICAgICB9CiAgICB9CgogICAgLy8vIEVWTUJ5dGVzMzIgaXMgYSB0eXBlIHdyYXBwZXIgdXNlZCBmb3IgQUJJIGVuY29kaW5nL2RlY29kaW5nIGludG8KICAgIC8vLyBTb2xpZGl0eSBgYnl0ZXMzMmAgdHlwZQogICAgYWNjZXNzKGFsbCkgc3RydWN0IEVWTUJ5dGVzMzIgewoKICAgICAgICAvLy8gQnl0ZSBhcnJheSByZXByZXNlbnRpbmcgdGhlIGBieXRlczMyYCB2YWx1ZQogICAgICAgIGFjY2VzcyhhbGwpIGxldCB2YWx1ZTogW1VJbnQ4OyAzMl0KCiAgICAgICAgdmlldyBpbml0KHZhbHVlOiBbVUludDg7IDMyXSkgewogICAgICAgICAgICBzZWxmLnZhbHVlID0gdmFsdWUKICAgICAgICB9CiAgICB9CgogICAgYWNjZXNzKGFsbCkgc3RydWN0IEJhbGFuY2UgewoKICAgICAgICAvLy8gVGhlIGJhbGFuY2UgaW4gYXR0by1GTE9XCiAgICAgICAgLy8vIEF0dG8tRkxPVyBpcyB0aGUgc21hbGxlc3QgZGVub21pbmF0aW9uIG9mIEZMT1cgKDFlMTggRkxPVykKICAgICAgICAvLy8gdGhhdCBpcyB1c2VkIHRvIHN0b3JlIGFjY291bnQgYmFsYW5jZXMgaW5zaWRlIEVWTQogICAgICAgIC8vLyBzaW1pbGFyIHRvIHRoZSB3YXkgV0VJIGlzIHVzZWQgdG8gc3RvcmUgRVRIIGRpdmlzaWJsZSB0byAxOCBkZWNpbWFsIHBsYWNlcy4KICAgICAgICBhY2Nlc3MoYWxsKSB2YXIgYXR0b2Zsb3c6IFVJbnQKCiAgICAgICAgLy8vIENvbnN0cnVjdHMgYSBuZXcgYmFsYW5jZQogICAgICAgIGFjY2VzcyhhbGwpCiAgICAgICAgdmlldyBpbml0KGF0dG9mbG93OiBVSW50KSB7CiAgICAgICAgICAgIHNlbGYuYXR0b2Zsb3cgPSBhdHRvZmxvdwogICAgICAgIH0KCiAgICAgICAgLy8vIFNldHMgdGhlIGJhbGFuY2UgYnkgYSBVRml4NjQgKDggZGVjaW1hbCBwb2ludHMpLCB0aGUgZm9ybWF0CiAgICAgICAgLy8vIHRoYXQgaXMgdXNlZCBpbiBDYWRlbmNlIHRvIHN0b3JlIEZMT1cgdG9rZW5zLgogICAgICAgIGFjY2VzcyhhbGwpCiAgICAgICAgZnVuIHNldEZMT1coZmxvdzogVUZpeDY0KXsKICAgICAgICAgICAgc2VsZi5hdHRvZmxvdyA9IEludGVybmFsRVZNLmNhc3RUb0F0dG9GTE9XKGJhbGFuY2U6IGZsb3cpCiAgICAgICAgfQoKICAgICAgICAvLy8gQ2FzdHMgdGhlIGJhbGFuY2UgdG8gYSBVRml4NjQgKHJvdW5kaW5nIGRvd24pCiAgICAgICAgLy8vIFdhcm5pbmchIGNhc3RpbmcgYSBiYWxhbmNlIHRvIGEgVUZpeDY0IHdoaWNoIHN1cHBvcnRzIGEgbG93ZXIgbGV2ZWwgb2YgcHJlY2lzaW9uCiAgICAgICAgLy8vICg4IGRlY2ltYWwgcG9pbnRzIGluIGNvbXBhcmUgdG8gMTgpIG1pZ2h0IHJlc3VsdCBpbiByb3VuZGluZyBkb3duIGVycm9yLgogICAgICAgIC8vLyBVc2UgdGhlIGluQXR0b0ZMT1cgZnVuY3Rpb24gaWYgeW91IG5lZWQgbW9yZSBhY2N1cmFjeS4KICAgICAgICBhY2Nlc3MoYWxsKQogICAgICAgIHZpZXcgZnVuIGluRkxPVygpOiBVRml4NjQgewogICAgICAgICAgICByZXR1cm4gSW50ZXJuYWxFVk0uY2FzdFRvRkxPVyhiYWxhbmNlOiBzZWxmLmF0dG9mbG93KQogICAgICAgIH0KCiAgICAgICAgLy8vIFJldHVybnMgdGhlIGJhbGFuY2UgaW4gQXR0by1GTE9XCiAgICAgICAgYWNjZXNzKGFsbCkKICAgICAgICB2aWV3IGZ1biBpbkF0dG9GTE9XKCk6IFVJbnQgewogICAgICAgICAgICByZXR1cm4gc2VsZi5hdHRvZmxvdwogICAgICAgIH0KCiAgICAgICAgLy8vIFJldHVybnMgdHJ1ZSBpZiB0aGUgYmFsYW5jZSBpcyB6ZXJvCiAgICAgICAgYWNjZXNzKGFsbCkKICAgICAgICB2aWV3IGZ1biBpc1plcm8oKTogQm9vbCB7CiAgICAgICAgICAgIHJldHVybiBzZWxmLmF0dG9mbG93ID09IDAKICAgICAgICB9CiAgICB9CgogICAgLy8vIHJlcG9ydHMgdGhlIHN0YXR1cyBvZiBldm0gZXhlY3V0aW9uLgogICAgYWNjZXNzKGFsbCkgZW51bSBTdGF0dXM6IFVJbnQ4IHsKICAgICAgICAvLy8gUmV0dXJuZWQgKHJhcmVseSkgd2hlbiBzdGF0dXMgaXMgdW5rbm93bgogICAgICAgIC8vLyBhbmQgc29tZXRoaW5nIGhhcyBnb25lIHZlcnkgd3JvbmcuCiAgICAgICAgYWNjZXNzKGFsbCkgY2FzZSB1bmtub3duCgogICAgICAgIC8vLyBSZXR1cm5lZCB3aGVuIGV4ZWN1dGlvbiBvZiBhbiBldm0gdHJhbnNhY3Rpb24vY2FsbAogICAgICAgIC8vLyBoYXMgZmFpbGVkIGF0IHRoZSB2YWxpZGF0aW9uIHN0ZXAgKGUuZy4gbm9uY2UgbWlzbWF0Y2gpLgogICAgICAgIC8vLyBBbiBpbnZhbGlkIHRyYW5zYWN0aW9uL2NhbGwgaXMgcmVqZWN0ZWQgdG8gYmUgZXhlY3V0ZWQKICAgICAgICAvLy8gb3IgYmUgaW5jbHVkZWQgaW4gYSBibG9jay4KICAgICAgICBhY2Nlc3MoYWxsKSBjYXNlIGludmFsaWQKCiAgICAgICAgLy8vIFJldHVybmVkIHdoZW4gZXhlY3V0aW9uIG9mIGFuIGV2bSB0cmFuc2FjdGlvbi9jYWxsCiAgICAgICAgLy8vIGhhcyBiZWVuIHN1Y2Nlc3NmdWwgYnV0IHRoZSB2bSBoYXMgcmVwb3J0ZWQgYW4gZXJyb3IgaW4KICAgICAgICAvLy8gdGhlIG91dGNvbWUgb2YgZXhlY3V0aW9uIChlLmcuIHJ1bm5pbmcgb3V0IG9mIGdhcykuCiAgICAgICAgLy8vIEEgZmFpbGVkIHR4L2NhbGwgaXMgaW5jbHVkZWQgaW4gYSBibG9jay4KICAgICAgICAvLy8gTm90ZSB0aGF0IHJlc3VibWlzc2lvbiBvZiBhIGZhaWxlZCB0cmFuc2FjdGlvbiB3b3VsZAogICAgICAgIC8vLyByZXN1bHQgaW4gaW52YWxpZCBzdGF0dXMgaW4gdGhlIHNlY29uZCBhdHRlbXB0LCBnaXZlbgogICAgICAgIC8vLyB0aGUgbm9uY2Ugd291bGQgYmVjb21lIGludmFsaWQuCiAgICAgICAgYWNjZXNzKGFsbCkgY2FzZSBmYWlsZWQKCiAgICAgICAgLy8vIFJldHVybmVkIHdoZW4gZXhlY3V0aW9uIG9mIGFuIGV2bSB0cmFuc2FjdGlvbi9jYWxsCiAgICAgICAgLy8vIGhhcyBiZWVuIHN1Y2Nlc3NmdWwgYW5kIG5vIGVycm9yIGlzIHJlcG9ydGVkIGJ5IHRoZSB2bS4KICAgICAgICBhY2Nlc3MoYWxsKSBjYXNlIHN1Y2Nlc3NmdWwKICAgIH0KCiAgICAvLy8gUmVwb3J0cyB0aGUgb3V0Y29tZSBvZiBhbiBldm0gdHJhbnNhY3Rpb24vY2FsbCBleGVjdXRpb24gYXR0ZW1wdAogICAgYWNjZXNzKGFsbCkgc3RydWN0IFJlc3VsdCB7CiAgICAgICAgLy8vIHN0YXR1cyBvZiB0aGUgZXhlY3V0aW9uCiAgICAgICAgYWNjZXNzKGFsbCkgbGV0IHN0YXR1czogU3RhdHVzCgogICAgICAgIC8vLyBlcnJvciBjb2RlIChlcnJvciBjb2RlIHplcm8gbWVhbnMgbm8gZXJyb3IpCiAgICAgICAgYWNjZXNzKGFsbCkgbGV0IGVycm9yQ29kZTogVUludDY0CgogICAgICAgIC8vLyBlcnJvciBtZXNzYWdlCiAgICAgICAgYWNjZXNzKGFsbCkgbGV0IGVycm9yTWVzc2FnZTogU3RyaW5nCgogICAgICAgIC8vLyByZXR1cm5zIHRoZSBhbW91bnQgb2YgZ2FzIG1ldGVyZWQgZHVyaW5nCiAgICAgICAgLy8vIGV2bSBleGVjdXRpb24KICAgICAgICBhY2Nlc3MoYWxsKSBsZXQgZ2FzVXNlZDogVUludDY0CgogICAgICAgIC8vLyByZXR1cm5zIHRoZSBkYXRhIHRoYXQgaXMgcmV0dXJuZWQgZnJvbQogICAgICAgIC8vLyB0aGUgZXZtIGZvciB0aGUgY2FsbC4gRm9yIGNvYS5kZXBsb3kKICAgICAgICAvLy8gY2FsbHMgaXQgcmV0dXJucyB0aGUgY29kZSBkZXBsb3llZCB0bwogICAgICAgIC8vLyB0aGUgYWRkcmVzcyBwcm92aWRlZCBpbiB0aGUgY29udHJhY3RBZGRyZXNzIGZpZWxkLgogICAgICAgIC8vLyBpbiBjYXNlIG9mIHJldmVydCwgdGhlIHNtYXJ0IGNvbnRyYWN0IGN1c3RvbSBlcnJvciBtZXNzYWdlCiAgICAgICAgLy8vIGlzIGFsc28gcmV0dXJuZWQgaGVyZSAoc2VlIEVJUC0xNDAgZm9yIG1vcmUgZGV0YWlscykuCiAgICAgICAgYWNjZXNzKGFsbCkgbGV0IGRhdGE6IFtVSW50OF0KCiAgICAgICAgLy8vIHJldHVybnMgdGhlIG5ld2x5IGRlcGxveWVkIGNvbnRyYWN0IGFkZHJlc3MKICAgICAgICAvLy8gaWYgdGhlIHRyYW5zYWN0aW9uIGNhdXNlZCBzdWNoIGEgZGVwbG95bWVudAogICAgICAgIC8vLyBvdGhlcndpc2UgdGhlIHZhbHVlIGlzIG5pbC4KICAgICAgICBhY2Nlc3MoYWxsKSBsZXQgZGVwbG95ZWRDb250cmFjdDogRVZNQWRkcmVzcz8KCiAgICAgICAgaW5pdCgKICAgICAgICAgICAgc3RhdHVzOiBTdGF0dXMsCiAgICAgICAgICAgIGVycm9yQ29kZTogVUludDY0LAogICAgICAgICAgICBlcnJvck1lc3NhZ2U6IFN0cmluZywKICAgICAgICAgICAgZ2FzVXNlZDogVUludDY0LAogICAgICAgICAgICBkYXRhOiBbVUludDhdLAogICAgICAgICAgICBjb250cmFjdEFkZHJlc3M6IFtVSW50ODsgMjBdPwogICAgICAgICkgewogICAgICAgICAgICBzZWxmLnN0YXR1cyA9IHN0YXR1cwogICAgICAgICAgICBzZWxmLmVycm9yQ29kZSA9IGVycm9yQ29kZQogICAgICAgICAgICBzZWxmLmVycm9yTWVzc2FnZSA9IGVycm9yTWVzc2FnZQogICAgICAgICAgICBzZWxmLmdhc1VzZWQgPSBnYXNVc2VkCiAgICAgICAgICAgIHNlbGYuZGF0YSA9IGRhdGEKCiAgICAgICAgICAgIGlmIGxldCBhZGRyZXNzQnl0ZXMgPSBjb250cmFjdEFkZHJlc3MgewogICAgICAgICAgICAgICAgc2VsZi5kZXBsb3llZENvbnRyYWN0ID0gRVZNQWRkcmVzcyhieXRlczogYWRkcmVzc0J5dGVzKQogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgc2VsZi5kZXBsb3llZENvbnRyYWN0ID0gbmlsCiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9CgogICAgLy8vIFJlcG9ydHMgdGhlIG91dGNvbWUgb2YgYW4gZXZtIHRyYW5zYWN0aW9uL2NhbGwgZXhlY3V0aW9uIGF0dGVtcHQuCiAgICAvLy8gVGhlIHJlc3VsdHMgZmllbGQgaGFzIHRoZSBkZWNvZGVkIGV2bSB0cmFuc2FjdGlvbi9jYWxsIHJlc3VsdHMgaWYKICAgIC8vLyByZXN1bHQgdHlwZXMgYXJlIHByb3ZpZGVkOyBvdGhlcndpc2UsIHRoZSByZXN1bHRzIGZpZWxkIGlzIG5pbC4KICAgIGFjY2VzcyhhbGwpIHN0cnVjdCBSZXN1bHREZWNvZGVkIHsKICAgICAgICAvLy8gc3RhdHVzIG9mIHRoZSBleGVjdXRpb24KICAgICAgICBhY2Nlc3MoYWxsKSBsZXQgc3RhdHVzOiBTdGF0dXMKCiAgICAgICAgLy8vIGVycm9yIGNvZGUgKGVycm9yIGNvZGUgemVybyBtZWFucyBubyBlcnJvcikKICAgICAgICBhY2Nlc3MoYWxsKSBsZXQgZXJyb3JDb2RlOiBVSW50NjQKCiAgICAgICAgLy8vIGVycm9yIG1lc3NhZ2UKICAgICAgICBhY2Nlc3MoYWxsKSBsZXQgZXJyb3JNZXNzYWdlOiBTdHJpbmcKCiAgICAgICAgLy8vIHJldHVybnMgdGhlIGFtb3VudCBvZiBnYXMgbWV0ZXJlZCBkdXJpbmcKICAgICAgICAvLy8gZXZtIGV4ZWN1dGlvbgogICAgICAgIGFjY2VzcyhhbGwpIGxldCBnYXNVc2VkOiBVSW50NjQKCiAgICAgICAgLy8vIFJldHVybnMgdGhlIGRlY29kZWQgcmVzdWx0cyBmcm9tIHRoZSBldm0gY2FsbCBpZgogICAgICAgIC8vLyB0aGUgZXZtIGNhbGwgaXMgc3VjY2Vzc2Z1bCBhbmQgcmVzdWx0VHlwZXMgYXJlIHByb3ZpZGVkLgogICAgICAgIC8vLyBPdGhlcndpc2UsIHJldHVybnMgcmF3IHJlc3VsdCBkYXRhIGZyb20gdGhlIGV2bSBjYWxsLgogICAgICAgIGFjY2VzcyhhbGwpIGxldCByZXN1bHRzOiBbQW55U3RydWN0XQoKICAgICAgICAvLy8gcmV0dXJucyB0aGUgbmV3bHkgZGVwbG95ZWQgY29udHJhY3QgYWRkcmVzcwogICAgICAgIC8vLyBpZiB0aGUgdHJhbnNhY3Rpb24gY2F1c2VkIHN1Y2ggYSBkZXBsb3ltZW50CiAgICAgICAgLy8vIG90aGVyd2lzZSB0aGUgdmFsdWUgaXMgbmlsLgogICAgICAgIGFjY2VzcyhhbGwpIGxldCBkZXBsb3llZENvbnRyYWN0OiBFVk1BZGRyZXNzPwoKICAgICAgICBpbml0KAogICAgICAgICAgICBzdGF0dXM6IFN0YXR1cywKICAgICAgICAgICAgZXJyb3JDb2RlOiBVSW50NjQsCiAgICAgICAgICAgIGVycm9yTWVzc2FnZTogU3RyaW5nLAogICAgICAgICAgICBnYXNVc2VkOiBVSW50NjQsCiAgICAgICAgICAgIHJlc3VsdHM6IFtBbnlTdHJ1Y3RdLAogICAgICAgICAgICBjb250cmFjdEFkZHJlc3M6IFtVSW50ODsgMjBdPwogICAgICAgICkgewogICAgICAgICAgICBzZWxmLnN0YXR1cyA9IHN0YXR1cwogICAgICAgICAgICBzZWxmLmVycm9yQ29kZSA9IGVycm9yQ29kZQogICAgICAgICAgICBzZWxmLmVycm9yTWVzc2FnZSA9IGVycm9yTWVzc2FnZQogICAgICAgICAgICBzZWxmLmdhc1VzZWQgPSBnYXNVc2VkCiAgICAgICAgICAgIHNlbGYucmVzdWx0cyA9IHJlc3VsdHMKCiAgICAgICAgICAgIGlmIGxldCBhZGRyZXNzQnl0ZXMgPSBjb250cmFjdEFkZHJlc3MgewogICAgICAgICAgICAgICAgc2VsZi5kZXBsb3llZENvbnRyYWN0ID0gRVZNQWRkcmVzcyhieXRlczogYWRkcmVzc0J5dGVzKQogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgc2VsZi5kZXBsb3llZENvbnRyYWN0ID0gbmlsCiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9CgogICAgLyogCiAgICAgICAgQ2FkZW5jZS1Pd25lZCBBY2NvdW50cyAoQ09BKSAKICAgICAgICBBIENPQSBpcyBhIG5hdGl2ZWx5IHN1cHBvcnRlZCBFVk0gc21hcnQgY29udHJhY3Qgd2FsbGV0IHR5cGUgCiAgICAgICAgdGhhdCBhbGxvd3MgYSBDYWRlbmNlIHJlc291cmNlIHRvIG93biBhbmQgY29udHJvbCBhbiBFVk0gYWRkcmVzcy4KICAgICAgICBUaGlzIG5hdGl2ZSB3YWxsZXQgcHJvdmlkZXMgdGhlIHByaW1pdGl2ZXMgbmVlZGVkIHRvIGJyaWRnZQogICAgICAgIG9yIGNvbnRyb2wgYXNzZXRzIGFjcm9zcyBGbG93IEVWTSBhbmQgQ2FkZW5jZS4KICAgICAgICBGcm9tIHRoZSBFVk0gcGVyc3BlY3RpdmUsIENPQXMgYXJlIHNtYXJ0IGNvbnRyYWN0IHdhbGxldHMKICAgICAgICB0aGF0IGFjY2VwdCBuYXRpdmUgdG9rZW4gdHJhbnNmZXJzIGFuZCBzdXBwb3J0IHNldmVyYWwgRVJDcwogICAgICAgIGluY2x1ZGluZyBFUkMtMTY1LCBFUkMtNzIxLCBFUkMtNzc3LCBFUkMtMTE1NSwgRVJDLTEyNzEuCgogICAgICAgIENPQXMgYXJlIG5vdCBjb250cm9sbGVkIGJ5IGEga2V5LgogICAgICAgIEluc3RlYWQsIGV2ZXJ5IENPQSBhY2NvdW50IGhhcyBhIHVuaXF1ZSByZXNvdXJjZSBhY2Nlc3NpYmxlCiAgICAgICAgb24gdGhlIENhZGVuY2Ugc2lkZSwgYW5kIGFueW9uZSB3aG8gb3ducyB0aGF0IHJlc291cmNlIHN1Ym1pdHMgdHJhbnNhY3Rpb25zCiAgICAgICAgb24gYmVoYWxmIG9mIHRoaXMgYWRkcmVzcy4gVGhlc2UgZGlyZWN0IHRyYW5zYWN0aW9ucyBoYXZlIENPQeKAmXMgRVZNIGFkZHJlc3MKICAgICAgICBhcyB0aGUgdHgub3JpZ2luIGFuZCBhIG5ldyBFVk0gdHJhbnNhY3Rpb24gdHlwZSAoVHhUeXBlID0gMHhmZikKICAgICAgICBpcyB1c2VkIHRvIGRpZmZlcmVudGlhdGUgdGhlc2UgdHJhbnNhY3Rpb25zIGZyb20gb3RoZXIgdHlwZXMKICAgICAgICBvZiBFVk0gdHJhbnNhY3Rpb25zIChlLmcsIER5bmFtaWNGZWVUeFR5cGUgKDB4MDIpLgoKICAgICAgICBCZWNhdXNlIG9mIHRoaXMsIHVzZXJzIGFyZSBuZXZlciBhYmxlIHRvIGFjY2VzcyBhIGtleSBmb3IgdGhlaXIgYWNjb3VudCwKICAgICAgICBtZWFuaW5nIHRoYXQgdGhleSBjYW5ub3QgY29udHJvbCB0aGVpciBDT0EncyBhZGRyZXNzIG9uIG90aGVyIEVWTSBibG9ja2NoYWlucy4KICAgICovCgogICAgLyogRW50aXRsZW1lbnRzIGVuYWJsaW5nIGZpbmVyLWdyYWluZWQgYWNjZXNzIGNvbnRyb2wgb24gYSBDYWRlbmNlT3duZWRBY2NvdW50ICovCgogICAgLy8vIEFsbG93cyB2YWxpZGF0aW5nIG93bmVyc2hpcCBvZiBhIENPQQogICAgYWNjZXNzKGFsbCkgZW50aXRsZW1lbnQgVmFsaWRhdGUKCiAgICAvLy8gQWxsb3dzIHdpdGhkcmF3aW5nIEZMT1cgZnJvbSB0aGUgQ09BIGJhY2sgdG8gQ2FkZW5jZQogICAgYWNjZXNzKGFsbCkgZW50aXRsZW1lbnQgV2l0aGRyYXcKCiAgICAvLy8gQWxsb3dzIHNlbmRpbmcgQ2FsbCB0cmFuc2FjdGlvbnMgZnJvbSB0aGUgQ09BCiAgICBhY2Nlc3MoYWxsKSBlbnRpdGxlbWVudCBDYWxsCgogICAgLy8vIEFsbG93cyBzZW5kaW5nIGRlcGxveSBjb250cmFjdCB0cmFuc2FjdGlvbnMgZnJvbSB0aGUgQ09BCiAgICBhY2Nlc3MoYWxsKSBlbnRpdGxlbWVudCBEZXBsb3kKCiAgICAvLy8gQWxsb3dzIGFjY2VzcyB0byBhbGwgdGhlIHByaXZsaWdlZCBmdW5jdGlvbmFsaXR5IG9uIGEgQ09BCiAgICBhY2Nlc3MoYWxsKSBlbnRpdGxlbWVudCBPd25lcgoKICAgIC8vLyBBbGxvd3MgYWNjZXNzIHRvIGFsbCBicmlkZ2luZyBmdW5jdGlvbmFsaXR5IGZvciBDT0FzCiAgICBhY2Nlc3MoYWxsKSBlbnRpdGxlbWVudCBCcmlkZ2UKCiAgICAvLy8gRXZlbnQgdGhhdCBpbmRpY2F0ZXMgd2hlbiBhIG5ldyBDT0EgaXMgY3JlYXRlZAogICAgYWNjZXNzKGFsbCkgZXZlbnQgQ2FkZW5jZU93bmVkQWNjb3VudENyZWF0ZWQoYWRkcmVzczogU3RyaW5nLCB1dWlkOiBVSW50NjQpCgogICAgLy8vIEludGVyZmFjZSBmb3IgdHlwZXMgdGhhdCBoYXZlIGFuIGFzc29jaWF0ZWQgRVZNIGFkZHJlc3MKICAgIGFjY2VzcyhhbGwpIHJlc291cmNlIGludGVyZmFjZSBBZGRyZXNzYWJsZSB7CiAgICAgICAgLy8vIEdldHMgdGhlIEVWTSBhZGRyZXNzCiAgICAgICAgYWNjZXNzKGFsbCkKICAgICAgICB2aWV3IGZ1biBhZGRyZXNzKCk6IEVWTUFkZHJlc3MKICAgIH0KCiAgICBhY2Nlc3MoYWxsKSByZXNvdXJjZSBDYWRlbmNlT3duZWRBY2NvdW50OiBBZGRyZXNzYWJsZSB7CgogICAgICAgIGFjY2VzcyhzZWxmKSB2YXIgYWRkcmVzc0J5dGVzOiBbVUludDg7IDIwXQoKICAgICAgICBpbml0KCkgewogICAgICAgICAgICAvLyBhZGRyZXNzIGlzIGluaXRpYWxseSBzZXQgdG8gemVybwogICAgICAgICAgICAvLyBidXQgdXBkYXRlZCB0aHJvdWdoIGluaXRBZGRyZXNzIGxhdGVyCiAgICAgICAgICAgIC8vIHdlIGhhdmUgdG8gZG8gdGhpcyBzaW5jZSB3ZSBuZWVkIHJlc291cmNlIGlkICh1dWlkKQogICAgICAgICAgICAvLyB0byBjYWxjdWxhdGUgdGhlIEVWTSBhZGRyZXNzIGZvciB0aGlzIGNhZGVuY2Ugb3duZWQgYWNjb3VudAogICAgICAgICAgICBzZWxmLmFkZHJlc3NCeXRlcyA9IFswLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwXQogICAgICAgIH0KCiAgICAgICAgLy8vIFNldHMgdGhlIEVWTSBhZGRyZXNzIGZvciB0aGUgQ09BLiBPbmx5IGNhbGxhYmxlIG9uY2Ugb24gaW5pdGlhbCBjcmVhdGlvbi4KICAgICAgICAvLy8KICAgICAgICAvLy8gQHBhcmFtIGFkZHJlc3NCeXRlczogVGhlIDIwIGJ5dGUgRVZNIGFkZHJlc3MKICAgICAgICBhY2Nlc3MoY29udHJhY3QpCiAgICAgICAgZnVuIGluaXRBZGRyZXNzKGFkZHJlc3NCeXRlczogW1VJbnQ4OyAyMF0pIHsKICAgICAgICAgICAgLy8gb25seSBhbGxvdyBzZXQgYWRkcmVzcyBmb3IgdGhlIGZpcnN0IHRpbWUKICAgICAgICAgICAgLy8gY2hlY2sgYWRkcmVzcyBpcyBlbXB0eQogICAgICAgICAgICBwcmUgewogICAgICAgICAgICAgICAgc2VsZi5hZGRyZXNzQnl0ZXMgPT0gWzAsMCwwLDAsMCwwLDAsMCwwLDAsMCwwLDAsMCwwLDAsMCwwLDAsMF06CiAgICAgICAgICAgICAgICAgICAgIkVWTS5DYWRlbmNlT3duZWRBY2NvdW50LmluaXRBZGRyZXNzKCk6IENhbm5vdCBpbml0aWFsaXplIHRoZSBhZGRyZXNzIGJ5dGVzIGlmIGl0IGhhcyBhbHJlYWR5IGJlZW4gc2V0ISIKICAgICAgICAgICAgfQogICAgICAgICAgIHNlbGYuYWRkcmVzc0J5dGVzID0gYWRkcmVzc0J5dGVzCiAgICAgICAgfQoKICAgICAgICAvLy8gR2V0cyBUaGUgRVZNIGFkZHJlc3Mgb2YgdGhlIGNhZGVuY2Ugb3duZWQgYWNjb3VudAogICAgICAgIC8vLwogICAgICAgIGFjY2VzcyhhbGwpCiAgICAgICAgdmlldyBmdW4gYWRkcmVzcygpOiBFVk1BZGRyZXNzIHsKICAgICAgICAgICAgLy8gQWx3YXlzIGNyZWF0ZSBhIG5ldyBFVk1BZGRyZXNzIGluc3RhbmNlCiAgICAgICAgICAgIHJldHVybiBFVk1BZGRyZXNzKGJ5dGVzOiBzZWxmLmFkZHJlc3NCeXRlcykKICAgICAgICB9CgogICAgICAgIC8vLyBHZXRzIHRoZSBiYWxhbmNlIG9mIHRoZSBjYWRlbmNlIG93bmVkIGFjY291bnQKICAgICAgICAvLy8KICAgICAgICBhY2Nlc3MoYWxsKQogICAgICAgIHZpZXcgZnVuIGJhbGFuY2UoKTogQmFsYW5jZSB7CiAgICAgICAgICAgIHJldHVybiBCYWxhbmNlKGF0dG9mbG93OiBJbnRlcm5hbEVWTS5iYWxhbmNlKGFkZHJlc3M6IHNlbGYuYWRkcmVzc0J5dGVzKSkKICAgICAgICB9CgogICAgICAgIC8vLyBEZXBvc2l0cyB0aGUgZ2l2ZW4gdmF1bHQgaW50byB0aGUgY2FkZW5jZSBvd25lZCBhY2NvdW50J3MgYmFsYW5jZQogICAgICAgIC8vLwogICAgICAgIC8vLyBAcGFyYW0gZnJvbTogVGhlIEZsb3dUb2tlbiBWYXVsdCB0byBkZXBvc2l0IHRvIHRoaXMgY2FkZW5jZSBvd25lZCBhY2NvdW50CiAgICAgICAgYWNjZXNzKGFsbCkKICAgICAgICBmdW4gZGVwb3NpdChmcm9tOiBARmxvd1Rva2VuLlZhdWx0KSB7CiAgICAgICAgICAgIHNlbGYuYWRkcmVzcygpLmRlcG9zaXQoZnJvbTogPC1mcm9tKQogICAgICAgIH0KCiAgICAgICAgLy8vIEdldHMgdGhlIEVWTSBhZGRyZXNzIG9mIHRoZSBjYWRlbmNlIG93bmVkIGFjY291bnQgYmVoaW5kIGFuIGVudGl0bGVtZW50LAogICAgICAgIC8vLyBhY3RpbmcgYXMgcHJvb2Ygb2YgYWNjZXNzCiAgICAgICAgYWNjZXNzKE93bmVyIHwgVmFsaWRhdGUpCiAgICAgICAgdmlldyBmdW4gcHJvdGVjdGVkQWRkcmVzcygpOiBFVk1BZGRyZXNzIHsKICAgICAgICAgICAgcmV0dXJuIHNlbGYuYWRkcmVzcygpCiAgICAgICAgfQoKICAgICAgICAvLy8gV2l0aGRyYXdzIHRoZSBiYWxhbmNlIGZyb20gdGhlIGNhZGVuY2Ugb3duZWQgYWNjb3VudCdzIGJhbGFuY2UuCiAgICAgICAgLy8vIE5vdGUgdGhhdCBhbW91bnRzIHNtYWxsZXIgdGhhbiAxZTEwIGF0dG9GbG93IGNhbid0IGJlIHdpdGhkcmF3biwKICAgICAgICAvLy8gZ2l2ZW4gdGhhdCBGbG93IFRva2VuIFZhdWx0cyB1c2UgVUZpeDY0IHRvIHN0b3JlIGJhbGFuY2VzLgogICAgICAgIC8vLyBJbiBvdGhlciB3b3JkcywgdGhlIHNtYWxsZXN0IHdpdGhkcmF3YWJsZSBhbW91bnQgaXMgMWUxMCBhdHRvRmxvdy4KICAgICAgICAvLy8gQW1vdW50cyBzbWFsbGVyIHRoYW4gMWUxMCBhdHRvRmxvdywgd2lsbCBjYXVzZSB0aGUgZnVuY3Rpb24gdG8gcGFuaWMKICAgICAgICAvLy8gd2l0aDogIndpdGhkcmF3IGZhaWxlZCEgc21hbGxlc3QgdW5pdCBhbGxvd2VkIHRvIHRyYW5zZmVyIGlzIDFlMTAgYXR0b0Zsb3ciLgogICAgICAgIC8vLyBJZiB0aGUgZ2l2ZW4gYmFsYW5jZSBjb252ZXJzaW9uIHRvIFVGaXg2NCByZXN1bHRzIGluIHJvdW5kaW5nIGxvc3MsCiAgICAgICAgLy8vIHRoZSB3aXRoZHJhd2FsIGFtb3VudCB3aWxsIGJlIHRydW5jYXRlZCB0byB0aGUgbWF4aW11bSBwcmVjaXNpb24gZm9yIFVGaXg2NC4KICAgICAgICAvLy8KICAgICAgICAvLy8gQHBhcmFtIGJhbGFuY2U6IFRoZSBFVk0gYmFsYW5jZSB0byB3aXRoZHJhdwogICAgICAgIC8vLwogICAgICAgIC8vLyBAcmV0dXJuIEEgRmxvd1Rva2VuIFZhdWx0IHdpdGggdGhlIHJlcXVlc3RlZCBiYWxhbmNlCiAgICAgICAgYWNjZXNzKE93bmVyIHwgV2l0aGRyYXcpCiAgICAgICAgZnVuIHdpdGhkcmF3KGJhbGFuY2U6IEJhbGFuY2UpOiBARmxvd1Rva2VuLlZhdWx0IHsKICAgICAgICAgICAgcHJlIHsKICAgICAgICAgICAgICAgICFFVk0uaXNQYXVzZWQoKTogIkVWTSBvcGVyYXRpb25zIGFyZSB0ZW1wb3JhcmlseSBwYXVzZWQiCiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGlmIGJhbGFuY2UuaXNaZXJvKCkgewogICAgICAgICAgICAgICAgcmV0dXJuIDwtRmxvd1Rva2VuLmNyZWF0ZUVtcHR5VmF1bHQodmF1bHRUeXBlOiBUeXBlPEBGbG93VG9rZW4uVmF1bHQ+KCkpCiAgICAgICAgICAgIH0KICAgICAgICAgICAgbGV0IHZhdWx0IDwtIEludGVybmFsRVZNLndpdGhkcmF3KAogICAgICAgICAgICAgICAgZnJvbTogc2VsZi5hZGRyZXNzQnl0ZXMsCiAgICAgICAgICAgICAgICBhbW91bnQ6IGJhbGFuY2UuYXR0b2Zsb3cKICAgICAgICAgICAgKSBhcyEgQEZsb3dUb2tlbi5WYXVsdAogICAgICAgICAgICBlbWl0IEZMT1dUb2tlbnNXaXRoZHJhd24oCiAgICAgICAgICAgICAgICBhZGRyZXNzOiBzZWxmLmFkZHJlc3MoKS50b1N0cmluZygpLAogICAgICAgICAgICAgICAgYW1vdW50OiBiYWxhbmNlLmluRkxPVygpLAogICAgICAgICAgICAgICAgd2l0aGRyYXduVVVJRDogdmF1bHQudXVpZCwKICAgICAgICAgICAgICAgIGJhbGFuY2VBZnRlckluQXR0b0Zsb3c6IHNlbGYuYmFsYW5jZSgpLmF0dG9mbG93CiAgICAgICAgICAgICkKICAgICAgICAgICAgcmV0dXJuIDwtdmF1bHQKICAgICAgICB9CgogICAgICAgIC8vLyBEZXBsb3lzIGEgY29udHJhY3QgdG8gdGhlIEVWTSBlbnZpcm9ubWVudC4KICAgICAgICAvLy8gUmV0dXJucyB0aGUgcmVzdWx0IHdoaWNoIGNvbnRhaW5zIGFkZHJlc3Mgb2YKICAgICAgICAvLy8gdGhlIG5ld2x5IGRlcGxveWVkIGNvbnRyYWN0CiAgICAgICAgLy8vCiAgICAgICAgLy8vIEBwYXJhbSBjb2RlOiBUaGUgYnl0ZWNvZGUgb2YgdGhlIFNvbGlkaXR5IGNvbnRyYWN0CiAgICAgICAgLy8vIEBwYXJhbSBnYXNMaW1pdDogVGhlIEVWTSBHYXMgbGltaXQgZm9yIHRoZSBkZXBsb3ltZW50IHRyYW5zYWN0aW9uCiAgICAgICAgLy8vIEBwYXJhbSB2YWx1ZTogVGhlIHZhbHVlLCBhcyBhbiBFVk0uQmFsYW5jZSBvYmplY3QsIHRvIHNlbmQgd2l0aCB0aGUgZGVwbG95bWVudAogICAgICAgIC8vLwogICAgICAgIC8vLyBAcmV0dXJuIFRoZSBFVk0gdHJhbnNhY3Rpb24gcmVzdWx0CiAgICAgICAgYWNjZXNzKE93bmVyIHwgRGVwbG95KQogICAgICAgIGZ1biBkZXBsb3koCiAgICAgICAgICAgIGNvZGU6IFtVSW50OF0sCiAgICAgICAgICAgIGdhc0xpbWl0OiBVSW50NjQsCiAgICAgICAgICAgIHZhbHVlOiBCYWxhbmNlCiAgICAgICAgKTogUmVzdWx0IHsKICAgICAgICAgICAgcHJlIHsKICAgICAgICAgICAgICAgICFFVk0uaXNQYXVzZWQoKTogIkVWTSBvcGVyYXRpb25zIGFyZSB0ZW1wb3JhcmlseSBwYXVzZWQiCiAgICAgICAgICAgIH0KICAgICAgICAgICAgcmV0dXJuIEludGVybmFsRVZNLmRlcGxveSgKICAgICAgICAgICAgICAgIGZyb206IHNlbGYuYWRkcmVzc0J5dGVzLAogICAgICAgICAgICAgICAgY29kZTogY29kZSwKICAgICAgICAgICAgICAgIGdhc0xpbWl0OiBnYXNMaW1pdCwKICAgICAgICAgICAgICAgIHZhbHVlOiB2YWx1ZS5hdHRvZmxvdwogICAgICAgICAgICApIGFzISBSZXN1bHQKICAgICAgICB9CgogICAgICAgIC8vLyBDYWxscyBhIGZ1bmN0aW9uIHdpdGggdGhlIGdpdmVuIGRhdGEuCiAgICAgICAgLy8vIFRoZSBleGVjdXRpb24gaXMgbGltaXRlZCBieSB0aGUgZ2l2ZW4gYW1vdW50IG9mIGdhcwogICAgICAgIGFjY2VzcyhPd25lciB8IENhbGwpCiAgICAgICAgZnVuIGNhbGwoCiAgICAgICAgICAgIHRvOiBFVk1BZGRyZXNzLAogICAgICAgICAgICBkYXRhOiBbVUludDhdLAogICAgICAgICAgICBnYXNMaW1pdDogVUludDY0LAogICAgICAgICAgICB2YWx1ZTogQmFsYW5jZQogICAgICAgICk6IFJlc3VsdCB7CiAgICAgICAgICAgIHByZSB7CiAgICAgICAgICAgICAgICAhRVZNLmlzUGF1c2VkKCk6ICJFVk0gb3BlcmF0aW9ucyBhcmUgdGVtcG9yYXJpbHkgcGF1c2VkIgogICAgICAgICAgICB9CiAgICAgICAgICAgIHJldHVybiBJbnRlcm5hbEVWTS5jYWxsKAogICAgICAgICAgICAgICAgZnJvbTogc2VsZi5hZGRyZXNzQnl0ZXMsCiAgICAgICAgICAgICAgICB0bzogdG8uYnl0ZXMsCiAgICAgICAgICAgICAgICBkYXRhOiBkYXRhLAogICAgICAgICAgICAgICAgZ2FzTGltaXQ6IGdhc0xpbWl0LAogICAgICAgICAgICAgICAgdmFsdWU6IHZhbHVlLmF0dG9mbG93CiAgICAgICAgICAgICkgYXMhIFJlc3VsdAogICAgICAgIH0KCiAgICAgICAgLy8vIENhbGxzIGEgY29udHJhY3QgZnVuY3Rpb24gd2l0aCB0aGUgZ2l2ZW4gc2lnbmF0dXJlIGFuZCBhcmdzLgogICAgICAgIC8vLyBUaGUgZXhlY3V0aW9uIGlzIGxpbWl0ZWQgYnkgdGhlIGdpdmVuIGFtb3VudCBvZiBnYXMuCiAgICAgICAgLy8vIFRoZSB2YWx1ZSBpcyBhdHRvZmxvdy4gIElmIHRoZSByZXN1bHRUeXBlcyBpcyBwcm92aWRlZCwKICAgICAgICAvLy8gdGhlIGV2bSBjYWxsIHJlc3VsdHMgYXJlIGRlY29kZWQgYW5kIHJldHVybmVkIGluIFJlc3VsdERlY29kZWQucmVzdWx0czsKICAgICAgICAvLy8gb3RoZXJ3aXNlLCB0aGUgZXZtIGNhbGwgcmVzdWx0cyBhcmUgZGlzY2FyZGVkIGFuZCBub3QgcmV0dXJuZWQuCiAgICAgICAgYWNjZXNzKE93bmVyIHwgQ2FsbCkKICAgICAgICBmdW4gY2FsbFdpdGhTaWdBbmRBcmdzKAogICAgICAgICAgICB0bzogRVZNQWRkcmVzcywKICAgICAgICAgICAgc2lnbmF0dXJlOiBTdHJpbmcsCiAgICAgICAgICAgIGFyZ3M6IFtBbnlTdHJ1Y3RdLAogICAgICAgICAgICBnYXNMaW1pdDogVUludDY0LAogICAgICAgICAgICB2YWx1ZTogVUludCwKICAgICAgICAgICAgcmVzdWx0VHlwZXM6IFtUeXBlXT8KICAgICAgICApOiBSZXN1bHREZWNvZGVkIHsKICAgICAgICAgICAgcHJlIHsKICAgICAgICAgICAgICAgICFFVk0uaXNQYXVzZWQoKTogIkVWTSBvcGVyYXRpb25zIGFyZSB0ZW1wb3JhcmlseSBwYXVzZWQiCiAgICAgICAgICAgIH0KICAgICAgICAgICAgcmV0dXJuIEludGVybmFsRVZNLmNhbGxXaXRoU2lnQW5kQXJncygKICAgICAgICAgICAgICAgIGZyb206IHNlbGYuYWRkcmVzc0J5dGVzLAogICAgICAgICAgICAgICAgdG86IHRvLmJ5dGVzLAogICAgICAgICAgICAgICAgc2lnbmF0dXJlOiBzaWduYXR1cmUsCiAgICAgICAgICAgICAgICBhcmdzOiBhcmdzLAogICAgICAgICAgICAgICAgZ2FzTGltaXQ6IGdhc0xpbWl0LAogICAgICAgICAgICAgICAgdmFsdWU6IHZhbHVlLAogICAgICAgICAgICAgICAgcmVzdWx0VHlwZXM6IHJlc3VsdFR5cGVzCiAgICAgICAgICAgICkgYXMhIFJlc3VsdERlY29kZWQKICAgICAgICB9CgogICAgICAgIC8vLyBDYWxscyBhIGNvbnRyYWN0IGZ1bmN0aW9uIHdpdGggdGhlIGdpdmVuIGRhdGEuCiAgICAgICAgLy8vIFRoZSBleGVjdXRpb24gaXMgbGltaXRlZCBieSB0aGUgZ2l2ZW4gYW1vdW50IG9mIGdhcy4KICAgICAgICAvLy8gVGhlIHRyYW5zYWN0aW9uIHN0YXRlIGNoYW5nZXMgYXJlIG5vdCBwZXJzaXN0ZWQuCiAgICAgICAgYWNjZXNzKGFsbCkKICAgICAgICBmdW4gZHJ5Q2FsbCgKICAgICAgICAgICAgdG86IEVWTUFkZHJlc3MsCiAgICAgICAgICAgIGRhdGE6IFtVSW50OF0sCiAgICAgICAgICAgIGdhc0xpbWl0OiBVSW50NjQsCiAgICAgICAgICAgIHZhbHVlOiBCYWxhbmNlLAogICAgICAgICk6IFJlc3VsdCB7CiAgICAgICAgICAgIHJldHVybiBJbnRlcm5hbEVWTS5kcnlDYWxsKAogICAgICAgICAgICAgICAgZnJvbTogc2VsZi5hZGRyZXNzQnl0ZXMsCiAgICAgICAgICAgICAgICB0bzogdG8uYnl0ZXMsCiAgICAgICAgICAgICAgICBkYXRhOiBkYXRhLAogICAgICAgICAgICAgICAgZ2FzTGltaXQ6IGdhc0xpbWl0LAogICAgICAgICAgICAgICAgdmFsdWU6IHZhbHVlLmF0dG9mbG93CiAgICAgICAgICAgICkgYXMhIFJlc3VsdAogICAgICAgIH0KCiAgICAgICAgLy8vIENhbGxzIGEgY29udHJhY3QgZnVuY3Rpb24gd2l0aCB0aGUgZ2l2ZW4gc2lnbmF0dXJlIGFuZCBhcmdzLgogICAgICAgIC8vLyBUaGUgZXhlY3V0aW9uIGlzIGxpbWl0ZWQgYnkgdGhlIGdpdmVuIGFtb3VudCBvZiBnYXMuCiAgICAgICAgLy8vIFRoZSB2YWx1ZSBpcyBhdHRvZmxvdy4gIElmIHRoZSByZXN1bHRUeXBlcyBpcyBwcm92aWRlZCwKICAgICAgICAvLy8gdGhlIGV2bSBjYWxsIHJlc3VsdHMgYXJlIGRlY29kZWQgYW5kIHJldHVybmVkIGluIFJlc3VsdERlY29kZWQucmVzdWx0czsKICAgICAgICAvLy8gb3RoZXJ3aXNlLCB0aGUgZXZtIGNhbGwgcmVzdWx0cyBhcmUgZGlzY2FyZGVkIGFuZCBub3QgcmV0dXJuZWQuCiAgICAgICAgLy8vIFRoZSB0cmFuc2FjdGlvbiBzdGF0ZSBjaGFuZ2VzIGFyZSBub3QgcGVyc2lzdGVkLgogICAgICAgIGFjY2VzcyhhbGwpCiAgICAgICAgZnVuIGRyeUNhbGxXaXRoU2lnQW5kQXJncygKICAgICAgICAgICAgdG86IEVWTUFkZHJlc3MsCiAgICAgICAgICAgIHNpZ25hdHVyZTogU3RyaW5nLAogICAgICAgICAgICBhcmdzOiBbQW55U3RydWN0XSwKICAgICAgICAgICAgZ2FzTGltaXQ6IFVJbnQ2NCwKICAgICAgICAgICAgdmFsdWU6IFVJbnQsCiAgICAgICAgICAgIHJlc3VsdFR5cGVzOiBbVHlwZV0/CiAgICAgICAgKTogUmVzdWx0RGVjb2RlZCB7CiAgICAgICAgICAgIHJldHVybiBJbnRlcm5hbEVWTS5kcnlDYWxsV2l0aFNpZ0FuZEFyZ3MoCiAgICAgICAgICAgICAgICBmcm9tOiBzZWxmLmFkZHJlc3NCeXRlcywKICAgICAgICAgICAgICAgIHRvOiB0by5ieXRlcywKICAgICAgICAgICAgICAgIHNpZ25hdHVyZTogc2lnbmF0dXJlLAogICAgICAgICAgICAgICAgYXJnczogYXJncywKICAgICAgICAgICAgICAgIGdhc0xpbWl0OiBnYXNMaW1pdCwKICAgICAgICAgICAgICAgIHZhbHVlOiB2YWx1ZSwKICAgICAgICAgICAgICAgIHJlc3VsdFR5cGVzOiByZXN1bHRUeXBlcywKICAgICAgICAgICAgKSBhcyEgUmVzdWx0RGVjb2RlZAogICAgICAgIH0KCiAgICAgICAgLy8vIEJyaWRnZXMgdGhlIGdpdmVuIE5GVCB0byB0aGUgRVZNIGVudmlyb25tZW50LCByZXF1aXJpbmcgYSBQcm92aWRlcgogICAgICAgIC8vLyBmcm9tIHdoaWNoIHRvIHdpdGhkcmF3IGEgZmVlIHRvIGZ1bGZpbGwgdGhlIGJyaWRnZSByZXF1ZXN0CiAgICAgICAgLy8vCiAgICAgICAgLy8vIEBwYXJhbSBuZnQ6IFRoZSBORlQgdG8gYnJpZGdlIHRvIHRoZSBDT0EncyBhZGRyZXNzIGluIEZsb3cgRVZNCiAgICAgICAgLy8vIEBwYXJhbSBmZWVQcm92aWRlcjogQSBXaXRoZHJhdyBlbnRpdGxlZCBQcm92aWRlciByZWZlcmVuY2UgdG8gYSBGbG93VG9rZW4gVmF1bHQKICAgICAgICAvLy8gICAgICAgICAgICAgICAgICAgICB0aGF0IGNvbnRhaW5zIHRoZSBmZWVzIHRvIGJlIHRha2VuIHRvIHBheSBmb3IgYnJpZGdpbmcKICAgICAgICBhY2Nlc3MoYWxsKQogICAgICAgIGZ1biBkZXBvc2l0TkZUKAogICAgICAgICAgICBuZnQ6IEB7Tm9uRnVuZ2libGVUb2tlbi5ORlR9LAogICAgICAgICAgICBmZWVQcm92aWRlcjogYXV0aChGdW5naWJsZVRva2VuLldpdGhkcmF3KSAme0Z1bmdpYmxlVG9rZW4uUHJvdmlkZXJ9CiAgICAgICAgKSB7CiAgICAgICAgICAgIHByZSB7CiAgICAgICAgICAgICAgICAhRVZNLmlzUGF1c2VkKCk6ICJFVk0gb3BlcmF0aW9ucyBhcmUgdGVtcG9yYXJpbHkgcGF1c2VkIgogICAgICAgICAgICB9CiAgICAgICAgICAgIEVWTS5ib3Jyb3dCcmlkZ2VBY2Nlc3NvcigpLmRlcG9zaXRORlQobmZ0OiA8LW5mdCwgdG86IHNlbGYuYWRkcmVzcygpLCBmZWVQcm92aWRlcjogZmVlUHJvdmlkZXIpCiAgICAgICAgfQoKICAgICAgICAvLy8gQnJpZGdlcyB0aGUgZ2l2ZW4gTkZUIGZyb20gdGhlIEVWTSBlbnZpcm9ubWVudCwgcmVxdWlyaW5nIGEgUHJvdmlkZXIKICAgICAgICAvLy8gZnJvbSB3aGljaCB0byB3aXRoZHJhdyBhIGZlZSB0byBmdWxmaWxsIHRoZSBicmlkZ2UgcmVxdWVzdC4KICAgICAgICAvLy8gTm90ZTogdGhlIGNhbGxlciBoYXMgdG8gb3duIHRoZSByZXF1ZXN0ZWQgTkZUIGluIEVWTQogICAgICAgIC8vLwogICAgICAgIC8vLyBAcGFyYW0gdHlwZTogVGhlIENhZGVuY2UgdHlwZSBvZiB0aGUgTkZUIHRvIHdpdGhkcmF3CiAgICAgICAgLy8vIEBwYXJhbSBpZDogVGhlIEVWTSBFUkM3MjEgSUQgb2YgdGhlIE5GVCB0byB3aXRoZHJhdwogICAgICAgIC8vLyBAcGFyYW0gZmVlUHJvdmlkZXI6IEEgV2l0aGRyYXcgZW50aXRsZWQgUHJvdmlkZXIgcmVmZXJlbmNlIHRvIGEgRmxvd1Rva2VuIFZhdWx0CiAgICAgICAgLy8vICAgICAgICAgICAgICAgICAgICAgdGhhdCBjb250YWlucyB0aGUgZmVlcyB0byBiZSB0YWtlbiB0byBwYXkgZm9yIGJyaWRnaW5nCiAgICAgICAgLy8vCiAgICAgICAgLy8vIEByZXR1cm4gVGhlIHJlcXVlc3RlZCBORlQKICAgICAgICBhY2Nlc3MoT3duZXIgfCBCcmlkZ2UpCiAgICAgICAgZnVuIHdpdGhkcmF3TkZUKAogICAgICAgICAgICB0eXBlOiBUeXBlLAogICAgICAgICAgICBpZDogVUludDI1NiwKICAgICAgICAgICAgZmVlUHJvdmlkZXI6IGF1dGgoRnVuZ2libGVUb2tlbi5XaXRoZHJhdykgJntGdW5naWJsZVRva2VuLlByb3ZpZGVyfQogICAgICAgICk6IEB7Tm9uRnVuZ2libGVUb2tlbi5ORlR9IHsKICAgICAgICAgICAgcHJlIHsKICAgICAgICAgICAgICAgICFFVk0uaXNQYXVzZWQoKTogIkVWTSBvcGVyYXRpb25zIGFyZSB0ZW1wb3JhcmlseSBwYXVzZWQiCiAgICAgICAgICAgIH0KICAgICAgICAgICAgcmV0dXJuIDwtIEVWTS5ib3Jyb3dCcmlkZ2VBY2Nlc3NvcigpLndpdGhkcmF3TkZUKAogICAgICAgICAgICAgICAgY2FsbGVyOiAmc2VsZiBhcyBhdXRoKENhbGwpICZDYWRlbmNlT3duZWRBY2NvdW50LAogICAgICAgICAgICAgICAgdHlwZTogdHlwZSwKICAgICAgICAgICAgICAgIGlkOiBpZCwKICAgICAgICAgICAgICAgIGZlZVByb3ZpZGVyOiBmZWVQcm92aWRlcgogICAgICAgICAgICApCiAgICAgICAgfQoKICAgICAgICAvLy8gQnJpZGdlcyB0aGUgZ2l2ZW4gVmF1bHQgdG8gdGhlIEVWTSBlbnZpcm9ubWVudAogICAgICAgIGFjY2VzcyhhbGwpCiAgICAgICAgZnVuIGRlcG9zaXRUb2tlbnMoCiAgICAgICAgICAgIHZhdWx0OiBAe0Z1bmdpYmxlVG9rZW4uVmF1bHR9LAogICAgICAgICAgICBmZWVQcm92aWRlcjogYXV0aChGdW5naWJsZVRva2VuLldpdGhkcmF3KSAme0Z1bmdpYmxlVG9rZW4uUHJvdmlkZXJ9CiAgICAgICAgKSB7CiAgICAgICAgICAgIHByZSB7CiAgICAgICAgICAgICAgICAhRVZNLmlzUGF1c2VkKCk6ICJFVk0gb3BlcmF0aW9ucyBhcmUgdGVtcG9yYXJpbHkgcGF1c2VkIgogICAgICAgICAgICB9CiAgICAgICAgICAgIEVWTS5ib3Jyb3dCcmlkZ2VBY2Nlc3NvcigpLmRlcG9zaXRUb2tlbnModmF1bHQ6IDwtdmF1bHQsIHRvOiBzZWxmLmFkZHJlc3MoKSwgZmVlUHJvdmlkZXI6IGZlZVByb3ZpZGVyKQogICAgICAgIH0KCiAgICAgICAgLy8vIEJyaWRnZXMgdGhlIGdpdmVuIGZ1bmdpYmxlIHRva2VucyBmcm9tIHRoZSBFVk0gZW52aXJvbm1lbnQsIHJlcXVpcmluZyBhIFByb3ZpZGVyIGZyb20gd2hpY2ggdG8gd2l0aGRyYXcgYQogICAgICAgIC8vLyBmZWUgdG8gZnVsZmlsbCB0aGUgYnJpZGdlIHJlcXVlc3QuIE5vdGU6IHRoZSBjYWxsZXIgc2hvdWxkIG93biB0aGUgcmVxdWVzdGVkIHRva2VucyAmIHN1ZmZpY2llbnQgYmFsYW5jZSBvZgogICAgICAgIC8vLyByZXF1ZXN0ZWQgdG9rZW5zIGluIEVWTQogICAgICAgIGFjY2VzcyhPd25lciB8IEJyaWRnZSkKICAgICAgICBmdW4gd2l0aGRyYXdUb2tlbnMoCiAgICAgICAgICAgIHR5cGU6IFR5cGUsCiAgICAgICAgICAgIGFtb3VudDogVUludDI1NiwKICAgICAgICAgICAgZmVlUHJvdmlkZXI6IGF1dGgoRnVuZ2libGVUb2tlbi5XaXRoZHJhdykgJntGdW5naWJsZVRva2VuLlByb3ZpZGVyfQogICAgICAgICk6IEB7RnVuZ2libGVUb2tlbi5WYXVsdH0gewogICAgICAgICAgICBwcmUgewogICAgICAgICAgICAgICAgIUVWTS5pc1BhdXNlZCgpOiAiRVZNIG9wZXJhdGlvbnMgYXJlIHRlbXBvcmFyaWx5IHBhdXNlZCIKICAgICAgICAgICAgfQogICAgICAgICAgICByZXR1cm4gPC0gRVZNLmJvcnJvd0JyaWRnZUFjY2Vzc29yKCkud2l0aGRyYXdUb2tlbnMoCiAgICAgICAgICAgICAgICBjYWxsZXI6ICZzZWxmIGFzIGF1dGgoQ2FsbCkgJkNhZGVuY2VPd25lZEFjY291bnQsCiAgICAgICAgICAgICAgICB0eXBlOiB0eXBlLAogICAgICAgICAgICAgICAgYW1vdW50OiBhbW91bnQsCiAgICAgICAgICAgICAgICBmZWVQcm92aWRlcjogZmVlUHJvdmlkZXIKICAgICAgICAgICAgKQogICAgICAgIH0KICAgIH0KCiAgICAvLy8gQ3JlYXRlcyBhIG5ldyBjYWRlbmNlIG93bmVkIGFjY291bnQKICAgIGFjY2VzcyhhbGwpCiAgICBmdW4gY3JlYXRlQ2FkZW5jZU93bmVkQWNjb3VudCgpOiBAQ2FkZW5jZU93bmVkQWNjb3VudCB7CiAgICAgICAgcHJlIHsKICAgICAgICAgICAgIXNlbGYuaXNQYXVzZWQoKTogIkVWTSBvcGVyYXRpb25zIGFyZSB0ZW1wb3JhcmlseSBwYXVzZWQiCiAgICAgICAgfQogICAgICAgIGxldCBhY2MgPC1jcmVhdGUgQ2FkZW5jZU93bmVkQWNjb3VudCgpCiAgICAgICAgbGV0IGFkZHIgPSBJbnRlcm5hbEVWTS5jcmVhdGVDYWRlbmNlT3duZWRBY2NvdW50KHV1aWQ6IGFjYy51dWlkKQogICAgICAgIGFjYy5pbml0QWRkcmVzcyhhZGRyZXNzQnl0ZXM6IGFkZHIpCgogICAgICAgIGVtaXQgQ2FkZW5jZU93bmVkQWNjb3VudENyZWF0ZWQoYWRkcmVzczogYWNjLmFkZHJlc3MoKS50b1N0cmluZygpLCB1dWlkOiBhY2MudXVpZCkKICAgICAgICByZXR1cm4gPC1hY2MKICAgIH0KCiAgICAvLy8gUnVucyBhbiBhIFJMUC1lbmNvZGVkIEVWTSB0cmFuc2FjdGlvbiwgZGVkdWN0cyB0aGUgZ2FzIGZlZXMsCiAgICAvLy8gYW5kIGRlcG9zaXRzIHRoZSBnYXMgZmVlcyBpbnRvIHRoZSBwcm92aWRlZCBjb2luYmFzZSBhZGRyZXNzLgogICAgLy8vCiAgICAvLy8gQHBhcmFtIHR4OiBUaGUgcmxwLWVuY29kZWQgdHJhbnNhY3Rpb24gdG8gcnVuCiAgICAvLy8gQHBhcmFtIGNvaW5iYXNlOiBUaGUgYWRkcmVzcyBvZiBlbnRpdHkgdG8gcmVjZWl2ZSB0aGUgdHJhbnNhY3Rpb24gZmVlcwogICAgLy8vIGZvciByZWxheWluZyB0aGUgdHJhbnNhY3Rpb24KICAgIC8vLwogICAgLy8vIEByZXR1cm46IFRoZSB0cmFuc2FjdGlvbiByZXN1bHQKICAgIGFjY2VzcyhhbGwpCiAgICBmdW4gcnVuKHR4OiBbVUludDhdLCBjb2luYmFzZTogRVZNQWRkcmVzcyk6IFJlc3VsdCB7CiAgICAgICAgcHJlIHsKICAgICAgICAgICAgIXNlbGYuaXNQYXVzZWQoKTogIkVWTSBvcGVyYXRpb25zIGFyZSB0ZW1wb3JhcmlseSBwYXVzZWQiCiAgICAgICAgfQogICAgICAgIHJldHVybiBJbnRlcm5hbEVWTS5ydW4oCiAgICAgICAgICAgIHR4OiB0eCwKICAgICAgICAgICAgY29pbmJhc2U6IGNvaW5iYXNlLmJ5dGVzCiAgICAgICAgKSBhcyEgUmVzdWx0CiAgICB9CgogICAgLy8vIG11c3RSdW4gcnVucyB0aGUgdHJhbnNhY3Rpb24gdXNpbmcgRVZNLnJ1bgogICAgLy8vIEl0IHdpbGwgcm9sbGJhY2sgaWYgdGhlIHR4IGV4ZWN1dGlvbiBzdGF0dXMgaXMgdW5rbm93biBvciBpbnZhbGlkLgogICAgLy8vIE5vdGUgdGhhdCB0aGlzIG1ldGhvZCBkb2VzIG5vdCByb2xsYmFjayBpZiB0cmFuc2FjdGlvbgogICAgLy8vIGlzIGV4ZWN1dGVkIGJ1dCBhbiB2bSBlcnJvciBpcyByZXBvcnRlZCBhcyB0aGUgb3V0Y29tZQogICAgLy8vIG9mIHRoZSBleGVjdXRpb24gKHN0YXR1czogZmFpbGVkKS4KICAgIGFjY2VzcyhhbGwpCiAgICBmdW4gbXVzdFJ1bih0eDogW1VJbnQ4XSwgY29pbmJhc2U6IEVWTUFkZHJlc3MpOiBSZXN1bHQgewogICAgICAgIGxldCBydW5SZXN1bHQgPSBzZWxmLnJ1bih0eDogdHgsIGNvaW5iYXNlOiBjb2luYmFzZSkKICAgICAgICBhc3NlcnQoCiAgICAgICAgICAgIHJ1blJlc3VsdC5zdGF0dXMgPT0gU3RhdHVzLmZhaWxlZCB8fCBydW5SZXN1bHQuc3RhdHVzID09IFN0YXR1cy5zdWNjZXNzZnVsLAogICAgICAgICAgICBtZXNzYWdlOiAiRVZNLm11c3RSdW4oKTogVGhlIHByb3ZpZGVkIHRyYW5zYWN0aW9uIGlzIG5vdCB2YWxpZCBmb3IgZXhlY3V0aW9uIgogICAgICAgICkKICAgICAgICByZXR1cm4gcnVuUmVzdWx0CiAgICB9CgogICAgLy8vIFNpbXVsYXRlcyBydW5uaW5nIHVuc2lnbmVkIFJMUC1lbmNvZGVkIHRyYW5zYWN0aW9uIHVzaW5nCiAgICAvLy8gdGhlIGZyb20gYWRkcmVzcyBhcyB0aGUgc2lnbmVyLgogICAgLy8vIFRoZSB0cmFuc2FjdGlvbiBzdGF0ZSBjaGFuZ2VzIGFyZSBub3QgcGVyc2lzdGVkLgogICAgLy8vIFRoaXMgaXMgdXNlZnVsIGZvciBnYXMgZXN0aW1hdGlvbiBvciBjYWxsaW5nIHZpZXcgY29udHJhY3QgZnVuY3Rpb25zLgogICAgLy8vIE5vdGU6IGRyeS1ydW4gZnVuY3Rpb25zIGFyZSBpbnRlbnRpb25hbGx5IGV4ZW1wdCBmcm9tIHRoZSBpc1BhdXNlZCgpIGd1YXJkIOKAlAogICAgLy8vIHRoZXkgcGVyZm9ybSBubyBzdGF0ZSBtdXRhdGlvbnMgYW5kIHJlbWFpbiBhdmFpbGFibGUgaW4gcmVhZC1vbmx5IG1vZGUuCiAgICBhY2Nlc3MoYWxsKQogICAgZnVuIGRyeVJ1bih0eDogW1VJbnQ4XSwgZnJvbTogRVZNQWRkcmVzcyk6IFJlc3VsdCB7CiAgICAgICAgcmV0dXJuIEludGVybmFsRVZNLmRyeVJ1bigKICAgICAgICAgICAgdHg6IHR4LAogICAgICAgICAgICBmcm9tOiBmcm9tLmJ5dGVzLAogICAgICAgICkgYXMhIFJlc3VsdAogICAgfQoKICAgIC8vLyBDYWxscyBhIGNvbnRyYWN0IGZ1bmN0aW9uIHdpdGggdGhlIGdpdmVuIGRhdGEuCiAgICAvLy8gVGhlIGV4ZWN1dGlvbiBpcyBsaW1pdGVkIGJ5IHRoZSBnaXZlbiBhbW91bnQgb2YgZ2FzLgogICAgLy8vIFRoZSB0cmFuc2FjdGlvbiBzdGF0ZSBjaGFuZ2VzIGFyZSBub3QgcGVyc2lzdGVkLgogICAgYWNjZXNzKGFsbCkKICAgIGZ1biBkcnlDYWxsKAogICAgICAgIGZyb206IEVWTUFkZHJlc3MsCiAgICAgICAgdG86IEVWTUFkZHJlc3MsCiAgICAgICAgZGF0YTogW1VJbnQ4XSwKICAgICAgICBnYXNMaW1pdDogVUludDY0LAogICAgICAgIHZhbHVlOiBCYWxhbmNlLAogICAgKTogUmVzdWx0IHsKICAgICAgICByZXR1cm4gSW50ZXJuYWxFVk0uZHJ5Q2FsbCgKICAgICAgICAgICAgZnJvbTogZnJvbS5ieXRlcywKICAgICAgICAgICAgdG86IHRvLmJ5dGVzLAogICAgICAgICAgICBkYXRhOiBkYXRhLAogICAgICAgICAgICBnYXNMaW1pdDogZ2FzTGltaXQsCiAgICAgICAgICAgIHZhbHVlOiB2YWx1ZS5hdHRvZmxvdwogICAgICAgICkgYXMhIFJlc3VsdAogICAgfQoKICAgIC8vLyBDYWxscyBhIGNvbnRyYWN0IGZ1bmN0aW9uIHdpdGggdGhlIGdpdmVuIHNpZ25hdHVyZSBhbmQgYXJncy4KICAgIC8vLyBUaGUgZXhlY3V0aW9uIGlzIGxpbWl0ZWQgYnkgdGhlIGdpdmVuIGFtb3VudCBvZiBnYXMuCiAgICAvLy8gVGhlIHZhbHVlIGlzIGF0dG9mbG93LiAgSWYgdGhlIHJlc3VsdFR5cGVzIGlzIHByb3ZpZGVkLAogICAgLy8vIHRoZSBldm0gY2FsbCByZXN1bHRzIGFyZSBkZWNvZGVkIGFuZCByZXR1cm5lZCBpbiBSZXN1bHREZWNvZGVkLnJlc3VsdHM7CiAgICAvLy8gb3RoZXJ3aXNlLCB0aGUgZXZtIGNhbGwgcmVzdWx0cyBhcmUgZGlzY2FyZGVkIGFuZCBub3QgcmV0dXJuZWQuCiAgICAvLy8gVGhlIHRyYW5zYWN0aW9uIHN0YXRlIGNoYW5nZXMgYXJlIG5vdCBwZXJzaXN0ZWQuCiAgICBhY2Nlc3MoYWxsKQogICAgZnVuIGRyeUNhbGxXaXRoU2lnQW5kQXJncygKICAgICAgICBmcm9tOiBFVk1BZGRyZXNzLAogICAgICAgIHRvOiBFVk1BZGRyZXNzLAogICAgICAgIHNpZ25hdHVyZTogU3RyaW5nLAogICAgICAgIGFyZ3M6IFtBbnlTdHJ1Y3RdLAogICAgICAgIGdhc0xpbWl0OiBVSW50NjQsCiAgICAgICAgdmFsdWU6IFVJbnQsCiAgICAgICAgcmVzdWx0VHlwZXM6IFtUeXBlXT8sCiAgICApOiBSZXN1bHREZWNvZGVkIHsKICAgICAgICByZXR1cm4gSW50ZXJuYWxFVk0uZHJ5Q2FsbFdpdGhTaWdBbmRBcmdzKAogICAgICAgICAgICBmcm9tOiBmcm9tLmJ5dGVzLAogICAgICAgICAgICB0bzogdG8uYnl0ZXMsCiAgICAgICAgICAgIHNpZ25hdHVyZTogc2lnbmF0dXJlLAogICAgICAgICAgICBhcmdzOiBhcmdzLAogICAgICAgICAgICBnYXNMaW1pdDogZ2FzTGltaXQsCiAgICAgICAgICAgIHZhbHVlOiB2YWx1ZSwKICAgICAgICAgICAgcmVzdWx0VHlwZXM6IHJlc3VsdFR5cGVzCiAgICAgICAgKSBhcyEgUmVzdWx0RGVjb2RlZAogICAgfQoKICAgIC8vLyBSdW5zIGEgYmF0Y2ggb2YgUkxQLWVuY29kZWQgRVZNIHRyYW5zYWN0aW9ucywgZGVkdWN0cyB0aGUgZ2FzIGZlZXMsCiAgICAvLy8gYW5kIGRlcG9zaXRzIHRoZSBnYXMgZmVlcyBpbnRvIHRoZSBwcm92aWRlZCBjb2luYmFzZSBhZGRyZXNzLgogICAgLy8vIEFuIGludmFsaWQgdHJhbnNhY3Rpb24gaXMgbm90IGV4ZWN1dGVkIGFuZCBub3QgaW5jbHVkZWQgaW4gdGhlIGJsb2NrLgogICAgYWNjZXNzKGFsbCkKICAgIGZ1biBiYXRjaFJ1bih0eHM6IFtbVUludDhdXSwgY29pbmJhc2U6IEVWTUFkZHJlc3MpOiBbUmVzdWx0XSB7CiAgICAgICAgcHJlIHsKICAgICAgICAgICAgIXNlbGYuaXNQYXVzZWQoKTogIkVWTSBvcGVyYXRpb25zIGFyZSB0ZW1wb3JhcmlseSBwYXVzZWQiCiAgICAgICAgfQogICAgICAgIHJldHVybiBJbnRlcm5hbEVWTS5iYXRjaFJ1bigKICAgICAgICAgICAgdHhzOiB0eHMsCiAgICAgICAgICAgIGNvaW5iYXNlOiBjb2luYmFzZS5ieXRlcywKICAgICAgICApIGFzISBbUmVzdWx0XQogICAgfQoKICAgIC8vLyBFbmNvZGVzIHRoZSBnaXZlbiB2YWx1ZXMgaW50byBhbiBBQkktZW5jb2RlZCBieXRlIGFycmF5IGFjY29yZGluZyB0bwogICAgLy8vIHRoZSBTb2xpZGl0eSBBQkkgc3BlY2lmaWNhdGlvbi4gQ2FkZW5jZSB0eXBlcyBhcmUgbWFwcGVkIHRvIHRoZWlyCiAgICAvLy8gY29ycmVzcG9uZGluZyBTb2xpZGl0eSB0eXBlcyAoZS5nLiBVSW50MjU2IOKGkiB1aW50MjU2LCBbVUludDhdIOKGkiBieXRlcykuCiAgICAvLy8KICAgIC8vLyBObyBlcnJvciByZXR1cm5zIGFyZSBleHBlY3RlZCBkdXJpbmcgbm9ybWFsIG9wZXJhdGlvbi4KICAgIGFjY2VzcyhhbGwpCiAgICBmdW4gZW5jb2RlQUJJKF8gdmFsdWVzOiBbQW55U3RydWN0XSk6IFtVSW50OF0gewogICAgICAgIHJldHVybiBJbnRlcm5hbEVWTS5lbmNvZGVBQkkodmFsdWVzKQogICAgfQoKICAgIC8vLyBEZWNvZGVzIGFuIEFCSS1lbmNvZGVkIGJ5dGUgYXJyYXkgaW50byBDYWRlbmNlIHZhbHVlcyBhY2NvcmRpbmcgdG8KICAgIC8vLyB0aGUgU29saWRpdHkgQUJJIHNwZWNpZmljYXRpb24uIFRoZSBwcm92aWRlZCB0eXBlcyBtdXN0IG1hdGNoIHRoZQogICAgLy8vIGVuY29kaW5nIG9mIGRhdGEgZXhhY3RseTsgYSBtaXNtYXRjaCB3aWxsIHBhbmljLgogICAgLy8vCiAgICAvLy8gTm8gZXJyb3IgcmV0dXJucyBhcmUgZXhwZWN0ZWQgZHVyaW5nIG5vcm1hbCBvcGVyYXRpb24uCiAgICBhY2Nlc3MoYWxsKQogICAgZnVuIGRlY29kZUFCSSh0eXBlczogW1R5cGVdLCBkYXRhOiBbVUludDhdKTogW0FueVN0cnVjdF0gewogICAgICAgIHJldHVybiBJbnRlcm5hbEVWTS5kZWNvZGVBQkkodHlwZXM6IHR5cGVzLCBkYXRhOiBkYXRhKQogICAgfQoKICAgIGFjY2VzcyhhbGwpCiAgICBmdW4gZW5jb2RlQUJJV2l0aFNpZ25hdHVyZSgKICAgICAgICBfIHNpZ25hdHVyZTogU3RyaW5nLAogICAgICAgIF8gdmFsdWVzOiBbQW55U3RydWN0XQogICAgKTogW1VJbnQ4XSB7CiAgICAgICAgbGV0IG1ldGhvZElEID0gSGFzaEFsZ29yaXRobS5LRUNDQUtfMjU2Lmhhc2goCiAgICAgICAgICAgIHNpZ25hdHVyZS51dGY4CiAgICAgICAgKS5zbGljZShmcm9tOiAwLCB1cFRvOiA0KQogICAgICAgIGxldCBhcmd1bWVudHMgPSBJbnRlcm5hbEVWTS5lbmNvZGVBQkkodmFsdWVzKQoKICAgICAgICByZXR1cm4gbWV0aG9kSUQuY29uY2F0KGFyZ3VtZW50cykKICAgIH0KCiAgICBhY2Nlc3MoYWxsKQogICAgZnVuIGRlY29kZUFCSVdpdGhTaWduYXR1cmUoCiAgICAgICAgXyBzaWduYXR1cmU6IFN0cmluZywKICAgICAgICB0eXBlczogW1R5cGVdLAogICAgICAgIGRhdGE6IFtVSW50OF0KICAgICk6IFtBbnlTdHJ1Y3RdIHsKICAgICAgICBwcmUgewogICAgICAgICAgICBkYXRhLmxlbmd0aCA+PSA0OiAiRVZNLmRlY29kZUFCSVdpdGhTaWduYXR1cmUoKTogQ2Fubm90IGRlY29kZSEgVGhlIHByb3ZpZGVkIGRhdGEgZG9lcyBub3QgY29udGFpbiBhIHNpZ25hdHVyZS4iCiAgICAgICAgfQogICAgICAgIGxldCBtZXRob2RJRCA9IEhhc2hBbGdvcml0aG0uS0VDQ0FLXzI1Ni5oYXNoKAogICAgICAgICAgICBzaWduYXR1cmUudXRmOAogICAgICAgICkuc2xpY2UoZnJvbTogMCwgdXBUbzogNCkKCiAgICAgICAgLy8gQ29tcGFyZSB0aGUgNC1ieXRlIG1ldGhvZCBJRCBwcmVmaXggdXNpbmcgaW5kZXggYWNjZXNzIHJhdGhlciB0aGFuIHJlbW92ZUZpcnN0KCksCiAgICAgICAgLy8gc2luY2UgcmVtb3ZlRmlyc3QoKSBpcyBPKG4pIGFuZCB3b3VsZCBzaGlmdCB0aGUgZW50aXJlIGFycmF5IG9uIGVhY2ggY2FsbC4KICAgICAgICAvLyBkYXRhLnNsaWNlKCkgaXMgdGhlbiB1c2VkIHRvIHBhc3Mgb25seSB0aGUgQUJJLWVuY29kZWQgYXJndW1lbnRzIHRvIGRlY29kZUFCSS4KICAgICAgICBmb3IgaSwgYnl0ZSBpbiBtZXRob2RJRCB7CiAgICAgICAgICAgIGlmIGJ5dGUgIT0gZGF0YVtpXSB7CiAgICAgICAgICAgICAgICBwYW5pYygiRVZNLmRlY29kZUFCSVdpdGhTaWduYXR1cmUoKTogQ2Fubm90IGRlY29kZSEgVGhlIHNpZ25hdHVyZSBkb2VzIG5vdCBtYXRjaCB0aGUgcHJvdmlkZWQgZGF0YS4iKQogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gSW50ZXJuYWxFVk0uZGVjb2RlQUJJKHR5cGVzOiB0eXBlcywgZGF0YTogZGF0YS5zbGljZShmcm9tOiA0LCB1cFRvOiBkYXRhLmxlbmd0aCkpCiAgICB9CgogICAgLy8vIFZhbGlkYXRpb25SZXN1bHQgcmV0dXJucyB0aGUgcmVzdWx0IG9mIENPQSBvd25lcnNoaXAgcHJvb2YgdmFsaWRhdGlvbgogICAgYWNjZXNzKGFsbCkgc3RydWN0IFZhbGlkYXRpb25SZXN1bHQgewoKICAgICAgICBhY2Nlc3MoYWxsKSBsZXQgaXNWYWxpZDogQm9vbAoKICAgICAgICAvLy8gSWYgdGhlcmUgd2FzIGEgcHJvYmxlbSB3aXRoIHZhbGlkYXRpb24sIHRoaXMgZGVzY3JpYmVzCiAgICAgICAgLy8vIHdoYXQgdGhlIHByb2JsZW0gd2FzCiAgICAgICAgYWNjZXNzKGFsbCkgbGV0IHByb2JsZW06IFN0cmluZz8KCiAgICAgICAgaW5pdChpc1ZhbGlkOiBCb29sLCBwcm9ibGVtOiBTdHJpbmc/KSB7CiAgICAgICAgICAgIHNlbGYuaXNWYWxpZCA9IGlzVmFsaWQKICAgICAgICAgICAgc2VsZi5wcm9ibGVtID0gcHJvYmxlbQogICAgICAgIH0KICAgIH0KCiAgICAvLy8gdmFsaWRhdGVDT0FPd25lcnNoaXBQcm9vZiB2YWxpZGF0ZXMgYSBDT0Egb3duZXJzaGlwIHByb29mLgogICAgLy8vCiAgICAvLy8gTm90ZTogdGhpcyBmdW5jdGlvbiBkb2VzIG5vdCBlbmZvcmNlIHRoYXQgYHNpZ25lZERhdGFgIGluY2x1ZGVzIGBldm1BZGRyZXNzYC4KICAgIC8vLyBJbiBwcmluY2lwbGUsIGEgc2lnbmF0dXJlIHByb2R1Y2VkIGZvciBvbmUgcHVycG9zZSBjb3VsZCBiZSByZXBsYXllZCBoZXJlIGFnYWluc3QKICAgIC8vLyBhIGRpZmZlcmVudCBDT0Egb3duZWQgYnkgdGhlIHNhbWUgQ2FkZW5jZSBhY2NvdW50LiBJbiBwcmFjdGljZSB0aGlzIGlzIGxvdy1yaXNrOgogICAgLy8vIHRoZSBFVk0tc2lkZSBwcmVjb21waWxlICh2ZXJpZnlDT0FPd25lcnNoaXBQcm9vZikgYWx3YXlzIHBhc3NlcyB0aGUgY2FsbGluZyBDT0EncwogICAgLy8vIGFkZHJlc3MgYXMgdGhlIGV2bUFkZHJlc3MgYXJndW1lbnQsIGFuZCBGbG93IHdhbGxldHMgaGlzdG9yaWNhbGx5IGNyZWF0ZSBhdCBtb3N0IG9uZQogICAgLy8vIENPQSBwZXIgYWNjb3VudC4gQ2FsbGVycyBidWlsZGluZyBvZmYtY2hhaW4gYXV0aGVudGljYXRpb24gZmxvd3Mgb24gdG9wIG9mIHRoaXMKICAgIC8vLyBmdW5jdGlvbiBzaG91bGQgZW5zdXJlIGBzaWduZWREYXRhYCBlbmNvZGVzIGBldm1BZGRyZXNzYCB0byBwcmV2ZW50IGNyb3NzLWFkZHJlc3MgcmVwbGF5LgogICAgYWNjZXNzKGFsbCkKICAgIGZ1biB2YWxpZGF0ZUNPQU93bmVyc2hpcFByb29mKAogICAgICAgIGFkZHJlc3M6IEFkZHJlc3MsCiAgICAgICAgcGF0aDogUHVibGljUGF0aCwKICAgICAgICBzaWduZWREYXRhOiBbVUludDhdLAogICAgICAgIGtleUluZGljZXM6IFtVSW50NjRdLAogICAgICAgIHNpZ25hdHVyZXM6IFtbVUludDhdXSwKICAgICAgICBldm1BZGRyZXNzOiBbVUludDg7IDIwXQogICAgKTogVmFsaWRhdGlvblJlc3VsdCB7CiAgICAgICAgLy8gbWFrZSBzaWduYXR1cmUgc2V0IGZpcnN0CiAgICAgICAgLy8gY2hlY2sgbnVtYmVyIG9mIHNpZ25hdHVyZXMgbWF0Y2hlcyBudW1iZXIgb2Yga2V5IGluZGljZXMKICAgICAgICBpZiBrZXlJbmRpY2VzLmxlbmd0aCAhPSBzaWduYXR1cmVzLmxlbmd0aCB7CiAgICAgICAgICAgIHJldHVybiBWYWxpZGF0aW9uUmVzdWx0KAogICAgICAgICAgICAgICAgaXNWYWxpZDogZmFsc2UsCiAgICAgICAgICAgICAgICBwcm9ibGVtOiAiRVZNLnZhbGlkYXRlQ09BT3duZXJzaGlwUHJvb2YoKTogS2V5IGluZGljZXMgYXJyYXkgbGVuZ3RoIGRvZXNuJ3QgbWF0Y2ggdGhlIHNpZ25hdHVyZXMgYXJyYXkgbGVuZ3RoISIKICAgICAgICAgICAgKQogICAgICAgIH0KCiAgICAgICAgLy8gZmV0Y2ggYWNjb3VudAogICAgICAgIGxldCBhY2MgPSBnZXRBY2NvdW50KGFkZHJlc3MpCgogICAgICAgIHZhciBzaWduYXR1cmVTZXQ6IFtDcnlwdG8uS2V5TGlzdFNpZ25hdHVyZV0gPSBbXQogICAgICAgIGxldCBrZXlMaXN0ID0gQ3J5cHRvLktleUxpc3QoKQogICAgICAgIHZhciBrZXlMaXN0TGVuZ3RoID0gMAogICAgICAgIGxldCBzZWVuQWNjb3VudEtleUluZGljZXM6IHtJbnQ6IEludH0gPSB7fQogICAgICAgIGZvciBzaWduYXR1cmVJbmRleCwgc2lnbmF0dXJlIGluIHNpZ25hdHVyZXMgewogICAgICAgICAgICAvLyBpbmRleCBvZiB0aGUga2V5IG9uIHRoZSBhY2NvdW50CiAgICAgICAgICAgIGxldCBhY2NvdW50S2V5SW5kZXggPSBJbnQoa2V5SW5kaWNlc1tzaWduYXR1cmVJbmRleF0hKQogICAgICAgICAgICAvLyBpbmRleCBvZiB0aGUga2V5IGluIHRoZSBrZXkgbGlzdAogICAgICAgICAgICB2YXIga2V5TGlzdEluZGV4ID0gMAoKICAgICAgICAgICAgaWYgIXNlZW5BY2NvdW50S2V5SW5kaWNlcy5jb250YWluc0tleShhY2NvdW50S2V5SW5kZXgpIHsKICAgICAgICAgICAgICAgIC8vIGZldGNoIGFjY291bnQga2V5IHdpdGggYWNjb3VudEtleUluZGV4CiAgICAgICAgICAgICAgICBpZiBsZXQga2V5ID0gYWNjLmtleXMuZ2V0KGtleUluZGV4OiBhY2NvdW50S2V5SW5kZXgpIHsKICAgICAgICAgICAgICAgICAgICBpZiBrZXkuaXNSZXZva2VkIHsKICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFZhbGlkYXRpb25SZXN1bHQoCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpc1ZhbGlkOiBmYWxzZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHByb2JsZW06ICJFVk0udmFsaWRhdGVDT0FPd25lcnNoaXBQcm9vZigpOiBDYW5ub3QgdmFsaWRhdGUgQ09BIG93bmVyc2hpcCBmb3IgQ2FkZW5jZSBhY2NvdW50IFwoYWRkcmVzcykuIFRoZSBhY2NvdW50IGtleSBhdCBpbmRleCBcKGFjY291bnRLZXlJbmRleCkgaXMgcmV2b2tlZC4iCiAgICAgICAgICAgICAgICAgICAgICAgICkKICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgIGtleUxpc3QuYWRkKAogICAgICAgICAgICAgICAgICAgICAga2V5LnB1YmxpY0tleSwKICAgICAgICAgICAgICAgICAgICAgIGhhc2hBbGdvcml0aG06IGtleS5oYXNoQWxnb3JpdGhtLAogICAgICAgICAgICAgICAgICAgICAgLy8gbm9ybWFsaXphdGlvbiBmYWN0b3IuIFdlIG5lZWQgdG8gZGl2aWRlIGJ5IDEwMDAgYmVjYXVzZSB0aGUKICAgICAgICAgICAgICAgICAgICAgIC8vIGBDcnlwdG8uS2V5TGlzdC52ZXJpZnkoKWAgZnVuY3Rpb24gZXhwZWN0cyB0aGUgd2VpZ2h0IHRvIGJlCiAgICAgICAgICAgICAgICAgICAgICAvLyBpbiB0aGUgcmFuZ2UgWzAsIDFdLiAxMDAwIGlzIHRoZSBrZXkgd2VpZ2h0IHRocmVzaG9sZC4KICAgICAgICAgICAgICAgICAgICAgIHdlaWdodDoga2V5LndlaWdodCAvIDEwMDAuMCwKICAgICAgICAgICAgICAgICAgICkKCiAgICAgICAgICAgICAgICAgICBrZXlMaXN0SW5kZXggPSBrZXlMaXN0TGVuZ3RoCiAgICAgICAgICAgICAgICAgICBrZXlMaXN0TGVuZ3RoID0ga2V5TGlzdExlbmd0aCArIDEKICAgICAgICAgICAgICAgICAgIHNlZW5BY2NvdW50S2V5SW5kaWNlc1thY2NvdW50S2V5SW5kZXhdID0ga2V5TGlzdEluZGV4CiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgIHJldHVybiBWYWxpZGF0aW9uUmVzdWx0KAogICAgICAgICAgICAgICAgICAgICAgICBpc1ZhbGlkOiBmYWxzZSwKICAgICAgICAgICAgICAgICAgICAgICAgcHJvYmxlbTogIkVWTS52YWxpZGF0ZUNPQU93bmVyc2hpcFByb29mKCk6IENhbm5vdCB2YWxpZGF0ZSBDT0Egb3duZXJzaGlwIGZvciBDYWRlbmNlIGFjY291bnQgXChhZGRyZXNzKS4gVGhlIGtleSBpbmRleCBcKGFjY291bnRLZXlJbmRleCkgaXMgaW52YWxpZC4iCiAgICAgICAgICAgICAgICAgICAgKQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAvLyBpZiB3ZSBoYXZlIGFscmVhZHkgc2VlbiB0aGlzIGFjY291bnRLZXlJbmRleCwgdXNlIHRoZSBrZXlMaXN0SW5kZXgKICAgICAgICAgICAgICAgLy8gdGhhdCB3YXMgcHJldmlvdXNseSBhc3NpZ25lZCB0byBpdAogICAgICAgICAgICAgICAvLyBgQ3J5cHRvLktleUxpc3QudmVyaWZ5KClgIGtub3dzIGhvdyB0byBoYW5kbGUgZHVwbGljYXRlIGtleXMKICAgICAgICAgICAgICAga2V5TGlzdEluZGV4ID0gc2VlbkFjY291bnRLZXlJbmRpY2VzW2FjY291bnRLZXlJbmRleF0hCiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHNpZ25hdHVyZVNldC5hcHBlbmQoQ3J5cHRvLktleUxpc3RTaWduYXR1cmUoCiAgICAgICAgICAgICAgIGtleUluZGV4OiBrZXlMaXN0SW5kZXgsCiAgICAgICAgICAgICAgIHNpZ25hdHVyZTogc2lnbmF0dXJlCiAgICAgICAgICAgICkpCiAgICAgICAgfQoKICAgICAgICBsZXQgaXNWYWxpZCA9IGtleUxpc3QudmVyaWZ5KAogICAgICAgICAgICBzaWduYXR1cmVTZXQ6IHNpZ25hdHVyZVNldCwKICAgICAgICAgICAgc2lnbmVkRGF0YTogc2lnbmVkRGF0YSwKICAgICAgICAgICAgZG9tYWluU2VwYXJhdGlvblRhZzogIkZMT1ctVjAuMC11c2VyIgogICAgICAgICkKCiAgICAgICAgaWYgIWlzVmFsaWR7CiAgICAgICAgICAgIHJldHVybiBWYWxpZGF0aW9uUmVzdWx0KAogICAgICAgICAgICAgICAgaXNWYWxpZDogZmFsc2UsCiAgICAgICAgICAgICAgICBwcm9ibGVtOiAiRVZNLnZhbGlkYXRlQ09BT3duZXJzaGlwUHJvb2YoKTogQ2Fubm90IHZhbGlkYXRlIENPQSBvd25lcnNoaXAgZm9yIENhZGVuY2UgYWNjb3VudCBcKGFkZHJlc3MpLiBUaGUgZ2l2ZW4gc2lnbmF0dXJlcyBhcmUgbm90IHZhbGlkIG9yIHByb3ZpZGUgZW5vdWdoIHdlaWdodC4iCiAgICAgICAgICAgICkKICAgICAgICB9CgogICAgICAgIGlmIGxldCBjb2FSZWYgPSBhY2MuY2FwYWJpbGl0aWVzLmJvcnJvdzwmRVZNLkNhZGVuY2VPd25lZEFjY291bnQ+KHBhdGgpIHsKICAgICAgICAgICAgLy8gdmVyaWZ5IGV2bSBhZGRyZXNzIG1hdGNoaW5nIOKAlCBjYXB0dXJlIGJ5dGVzIG9uY2UgdG8gYXZvaWQgcmVkdW5kYW50IGJvcnJvdwogICAgICAgICAgICBsZXQgY29hQWRkcmVzc0J5dGVzID0gY29hUmVmLmFkZHJlc3MoKS5ieXRlcwogICAgICAgICAgICBmb3IgaW5kZXgsIGl0ZW0gaW4gY29hQWRkcmVzc0J5dGVzIHsKICAgICAgICAgICAgICAgIGlmIGl0ZW0gIT0gZXZtQWRkcmVzc1tpbmRleF0gewogICAgICAgICAgICAgICAgICAgIHJldHVybiBWYWxpZGF0aW9uUmVzdWx0KAogICAgICAgICAgICAgICAgICAgICAgICBpc1ZhbGlkOiBmYWxzZSwKICAgICAgICAgICAgICAgICAgICAgICAgcHJvYmxlbTogIkVWTS52YWxpZGF0ZUNPQU93bmVyc2hpcFByb29mKCk6IENhbm5vdCB2YWxpZGF0ZSBDT0Egb3duZXJzaGlwLiBUaGUgcHJvdmlkZWQgZXZtIGFkZHJlc3MgZG9lcyBub3QgbWF0Y2ggdGhlIGFjY291bnQncyBDT0EgYWRkcmVzcy4iCiAgICAgICAgICAgICAgICAgICAgKQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIHJldHVybiBWYWxpZGF0aW9uUmVzdWx0KAogICAgICAgICAgICAgICAgaXNWYWxpZDogdHJ1ZSwKICAgICAgICAgICAgICAgIHByb2JsZW06IG5pbAogICAgICAgICAgICApCiAgICAgICAgfQoKICAgICAgICByZXR1cm4gVmFsaWRhdGlvblJlc3VsdCgKICAgICAgICAgICAgaXNWYWxpZDogZmFsc2UsCiAgICAgICAgICAgIHByb2JsZW06ICJFVk0udmFsaWRhdGVDT0FPd25lcnNoaXBQcm9vZigpOiBDYW5ub3QgdmFsaWRhdGUgQ09BIG93bmVyc2hpcC4gQ291bGQgbm90IGJvcnJvdyB0aGUgQ09BIHJlc291cmNlIGZvciBhY2NvdW50IFwoYWRkcmVzcykuIgogICAgICAgICkKICAgIH0KCiAgICAvLy8gSW50ZXJmYWNlIGZvciBhIHJlc291cmNlIHdoaWNoIGFjdHMgYXMgYW4gZW50cnlwb2ludCB0byB0aGUgVk0gYnJpZGdlCiAgICBhY2Nlc3MoYWxsKSByZXNvdXJjZSBpbnRlcmZhY2UgQnJpZGdlQWNjZXNzb3IgewoKICAgICAgICAvLy8gRW5kcG9pbnQgZW5hYmxpbmcgdGhlIGJyaWRnaW5nIG9mIGFuIE5GVCB0byBFVk0KICAgICAgICBhY2Nlc3MoQnJpZGdlKQogICAgICAgIGZ1biBkZXBvc2l0TkZUKAogICAgICAgICAgICBuZnQ6IEB7Tm9uRnVuZ2libGVUb2tlbi5ORlR9LAogICAgICAgICAgICB0bzogRVZNQWRkcmVzcywKICAgICAgICAgICAgZmVlUHJvdmlkZXI6IGF1dGgoRnVuZ2libGVUb2tlbi5XaXRoZHJhdykgJntGdW5naWJsZVRva2VuLlByb3ZpZGVyfQogICAgICAgICkKCiAgICAgICAgLy8vIEVuZHBvaW50IGVuYWJsaW5nIHRoZSBicmlkZ2luZyBvZiBhbiBORlQgZnJvbSBFVk0KICAgICAgICBhY2Nlc3MoQnJpZGdlKQogICAgICAgIGZ1biB3aXRoZHJhd05GVCgKICAgICAgICAgICAgY2FsbGVyOiBhdXRoKENhbGwpICZDYWRlbmNlT3duZWRBY2NvdW50LAogICAgICAgICAgICB0eXBlOiBUeXBlLAogICAgICAgICAgICBpZDogVUludDI1NiwKICAgICAgICAgICAgZmVlUHJvdmlkZXI6IGF1dGgoRnVuZ2libGVUb2tlbi5XaXRoZHJhdykgJntGdW5naWJsZVRva2VuLlByb3ZpZGVyfQogICAgICAgICk6IEB7Tm9uRnVuZ2libGVUb2tlbi5ORlR9CgogICAgICAgIC8vLyBFbmRwb2ludCBlbmFibGluZyB0aGUgYnJpZGdpbmcgb2YgYSBmdW5naWJsZSB0b2tlbiB2YXVsdCB0byBFVk0KICAgICAgICBhY2Nlc3MoQnJpZGdlKQogICAgICAgIGZ1biBkZXBvc2l0VG9rZW5zKAogICAgICAgICAgICB2YXVsdDogQHtGdW5naWJsZVRva2VuLlZhdWx0fSwKICAgICAgICAgICAgdG86IEVWTUFkZHJlc3MsCiAgICAgICAgICAgIGZlZVByb3ZpZGVyOiBhdXRoKEZ1bmdpYmxlVG9rZW4uV2l0aGRyYXcpICZ7RnVuZ2libGVUb2tlbi5Qcm92aWRlcn0KICAgICAgICApCgogICAgICAgIC8vLyBFbmRwb2ludCBlbmFibGluZyB0aGUgYnJpZGdpbmcgb2YgZnVuZ2libGUgdG9rZW5zIGZyb20gRVZNCiAgICAgICAgYWNjZXNzKEJyaWRnZSkKICAgICAgICBmdW4gd2l0aGRyYXdUb2tlbnMoCiAgICAgICAgICAgIGNhbGxlcjogYXV0aChDYWxsKSAmQ2FkZW5jZU93bmVkQWNjb3VudCwKICAgICAgICAgICAgdHlwZTogVHlwZSwKICAgICAgICAgICAgYW1vdW50OiBVSW50MjU2LAogICAgICAgICAgICBmZWVQcm92aWRlcjogYXV0aChGdW5naWJsZVRva2VuLldpdGhkcmF3KSAme0Z1bmdpYmxlVG9rZW4uUHJvdmlkZXJ9CiAgICAgICAgKTogQHtGdW5naWJsZVRva2VuLlZhdWx0fQogICAgfQoKICAgIC8vLyBJbnRlcmZhY2Ugd2hpY2ggY2FwdHVyZXMgYSBDYXBhYmlsaXR5IHRvIHRoZSBicmlkZ2UgQWNjZXNzb3IsCiAgICAvLy8gc2F2aW5nIGl0IHdpdGhpbiB0aGUgQnJpZGdlUm91dGVyIHJlc291cmNlCiAgICBhY2Nlc3MoYWxsKSByZXNvdXJjZSBpbnRlcmZhY2UgQnJpZGdlUm91dGVyIHsKCiAgICAgICAgLy8vIFJldHVybnMgYSByZWZlcmVuY2UgdG8gdGhlIEJyaWRnZUFjY2Vzc29yIGRlc2lnbmF0ZWQKICAgICAgICAvLy8gZm9yIGludGVybmFsIGJyaWRnZSByZXF1ZXN0cwogICAgICAgIGFjY2VzcyhCcmlkZ2UpIHZpZXcgZnVuIGJvcnJvd0JyaWRnZUFjY2Vzc29yKCk6IGF1dGgoQnJpZGdlKSAme0JyaWRnZUFjY2Vzc29yfQoKICAgICAgICAvLy8gU2V0cyB0aGUgQnJpZGdlQWNjZXNzb3IgQ2FwYWJpbGl0eSBpbiB0aGUgQnJpZGdlUm91dGVyCiAgICAgICAgYWNjZXNzKEJyaWRnZSkgZnVuIHNldEJyaWRnZUFjY2Vzc29yKF8gYWNjZXNzb3I6IENhcGFiaWxpdHk8YXV0aChCcmlkZ2UpICZ7QnJpZGdlQWNjZXNzb3J9PikgewogICAgICAgICAgICBwcmUgewogICAgICAgICAgICAgICAgYWNjZXNzb3IuY2hlY2soKToKICAgICAgICAgICAgICAgICAgICAiRVZNLnNldEJyaWRnZUFjY2Vzc29yKCk6IEludmFsaWQgQnJpZGdlQWNjZXNzb3IgQ2FwYWJpbGl0eSBwcm92aWRlZCIKICAgICAgICAgICAgfQogICAgICAgICAgICBwb3N0IHsKICAgICAgICAgICAgICAgIGVtaXQgQnJpZGdlQWNjZXNzb3JVcGRhdGVkKAogICAgICAgICAgICAgICAgICAgIHJvdXRlclR5cGU6IHNlbGYuZ2V0VHlwZSgpLAogICAgICAgICAgICAgICAgICAgIHJvdXRlclVVSUQ6IHNlbGYudXVpZCwKICAgICAgICAgICAgICAgICAgICByb3V0ZXJBZGRyZXNzOiBzZWxmLm93bmVyPy5hZGRyZXNzID8/IHBhbmljKCJFVk0uc2V0QnJpZGdlQWNjZXNzb3IoKTogUm91dGVyIG11c3QgYmUgc3RvcmVkIGluIGFuIGFjY291bnQncyBzdG9yYWdlIiksCiAgICAgICAgICAgICAgICAgICAgYWNjZXNzb3JUeXBlOiBhY2Nlc3Nvci5ib3Jyb3coKSEuZ2V0VHlwZSgpLAogICAgICAgICAgICAgICAgICAgIGFjY2Vzc29yVVVJRDogYWNjZXNzb3IuYm9ycm93KCkhLnV1aWQsCiAgICAgICAgICAgICAgICAgICAgYWNjZXNzb3JBZGRyZXNzOiBhY2Nlc3Nvci5hZGRyZXNzCiAgICAgICAgICAgICAgICApCiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9CgogICAgLy8vIFJldHVybnMgYSByZWZlcmVuY2UgdG8gdGhlIEJyaWRnZUFjY2Vzc29yIGRlc2lnbmF0ZWQgZm9yIGludGVybmFsIGJyaWRnZSByZXF1ZXN0cwogICAgYWNjZXNzKHNlbGYpCiAgICB2aWV3IGZ1biBib3Jyb3dCcmlkZ2VBY2Nlc3NvcigpOiBhdXRoKEJyaWRnZSkgJntCcmlkZ2VBY2Nlc3Nvcn0gewogICAgICAgIHJldHVybiBzZWxmLmFjY291bnQuc3RvcmFnZS5ib3Jyb3c8YXV0aChCcmlkZ2UpICZ7QnJpZGdlUm91dGVyfT4oZnJvbTogL3N0b3JhZ2UvZXZtQnJpZGdlUm91dGVyKQogICAgICAgICAgICA/LmJvcnJvd0JyaWRnZUFjY2Vzc29yKCkKICAgICAgICAgICAgPz8gcGFuaWMoIkVWTS5ib3Jyb3dCcmlkZ2VBY2Nlc3NvcigpOiBDb3VsZCBub3QgYm9ycm93IGEgcmVmZXJlbmNlIHRvIHRoZSBFVk0gYnJpZGdlLiIpCiAgICB9CgogICAgLy8vIFRoZSBIZWFydGJlYXQgcmVzb3VyY2UgY29udHJvbHMgdGhlIGJsb2NrIHByb2R1Y3Rpb24uCiAgICAvLy8gSXQgaXMgc3RvcmVkIGluIHRoZSBzdG9yYWdlIGFuZCB1c2VkIGluIHRoZSBGbG93IHByb3RvY29sCiAgICAvLy8gdG8gY2FsbCB0aGUgaGVhcnRiZWF0IGZ1bmN0aW9uIG9uY2UgcGVyIGJsb2NrLgogICAgYWNjZXNzKGFsbCkgcmVzb3VyY2UgSGVhcnRiZWF0IHsKICAgICAgICAvLy8gaGVhcnRiZWF0IGNhbGxzIGNvbW1pdCBibG9jayBwcm9wb3NhbHMgYW5kIGZvcm1zIG5ldyBibG9ja3MKICAgICAgICAvLy8gaW5jbHVkaW5nIGFsbCB0aGUgcmVjZW50bHkgZXhlY3V0ZWQgdHJhbnNhY3Rpb25zLgogICAgICAgIC8vLyBUaGUgRmxvdyBwcm90b2NvbCBtYWtlcyBzdXJlIHRvIGNhbGwgdGhpcyBmdW5jdGlvbgogICAgICAgIC8vLyBvbmNlIHBlciBibG9jayBhcyBhIHN5c3RlbSBjYWxsLgogICAgICAgIGFjY2VzcyhhbGwpCiAgICAgICAgZnVuIGhlYXJ0YmVhdCgpIHsKICAgICAgICAgICAgSW50ZXJuYWxFVk0uY29tbWl0QmxvY2tQcm9wb3NhbCgpCiAgICAgICAgfQogICAgfQoKICAgIC8vLyBzZXR1cEhlYXJ0YmVhdCBjcmVhdGVzIGEgaGVhcnRiZWF0IHJlc291cmNlIGFuZCBzYXZlcyBpdCB0byBzdG9yYWdlLgogICAgLy8vIFRoZSBmdW5jdGlvbiBpcyBjYWxsZWQgb25jZSBkdXJpbmcgdGhlIGNvbnRyYWN0IGluaXRpYWxpemF0aW9uLgogICAgLy8vCiAgICAvLy8gVGhlIGhlYXJ0YmVhdCByZXNvdXJjZSBpcyB1c2VkIHRvIGNvbnRyb2wgdGhlIGJsb2NrIHByb2R1Y3Rpb24sCiAgICAvLy8gYW5kIHVzZWQgaW4gdGhlIEZsb3cgcHJvdG9jb2wgdG8gY2FsbCB0aGUgaGVhcnRiZWF0IGZ1bmN0aW9uIG9uY2UgcGVyIGJsb2NrLgogICAgLy8vCiAgICAvLy8gVGhlIGZ1bmN0aW9uIGlzIGFjY2VzcyhhbGwpIGJlY2F1c2UgaXQgaXMgY2FsbGVkIGR1cmluZyBjb250cmFjdCBpbml0aWFsaXphdGlvbgogICAgLy8vIGJlZm9yZSBhY2NvdW50LWxldmVsIGFjY2VzcyBpcyBhdmFpbGFibGUuIEl0IGlzIHNhZmUgdG8gYmUgcHVibGljIGJlY2F1c2UKICAgIC8vLyBpdCBjYW4gb25seSBzdWNjZWVkIG9uY2U6IGFueSBzdWJzZXF1ZW50IGNhbGwgd2lsbCBwYW5pYyBiZWNhdXNlIHRoZSBzdG9yYWdlCiAgICAvLy8gcGF0aCBpcyBhbHJlYWR5IG9jY3VwaWVkLgogICAgLy8vCiAgICAvLy8gVGhlIHJlc3VsdGluZyByZXNvdXJjZSBpcyBzdG9yZWQgaW4gdGhlIGFjY291bnQgc3RvcmFnZSwKICAgIC8vLyBhbmQgaXMgb25seSBhY2Nlc3NpYmxlIGJ5IHRoZSBhY2NvdW50LCBub3QgdGhlIGNhbGxlciBvZiB0aGUgZnVuY3Rpb24uCiAgICBhY2Nlc3MoYWxsKQogICAgZnVuIHNldHVwSGVhcnRiZWF0KCkgewogICAgICAgIHNlbGYuYWNjb3VudC5zdG9yYWdlLnNhdmUoPC1jcmVhdGUgSGVhcnRiZWF0KCksIHRvOiAvc3RvcmFnZS9FVk1IZWFydGJlYXQpCiAgICB9CgogICAgLy8vIFJldHVybnMgd2hldGhlciBFVk0gdHJhbnNhY3Rpb25zIGhhdmUgYmVlbiBwYXVzZWQsIGVpdGhlciBmb3IKICAgIC8vLyBtYWludGVuYW5jZSBvciBhbnkgc2l0dWF0aW9uIHRoYXQgcmVxdWlyZXMgc3BlY2lhbCBnb3Zlcm5hbmNlCiAgICAvLy8gaGFuZGxpbmcuCiAgICAvLy8KICAgIC8vLyBPbmx5IHRoZSBHb3Zlcm5hbmNlIENvbW1pdHRlZSBjYW4gcGF1c2UgdGhlIEVWTSB0cmFuc2FjdGlvbnMsIHdpdGgKICAgIC8vLyBhIG11bHRpLXNpZyBDYWRlbmNlIHRyYW5zYWN0aW9uLiBUaGUgRVZNIGVudGVycyBhIHJlYWQtb25seSBtb2RlLAogICAgLy8vIHdoZXJlIGFsbCBFVk0gc3RhdGUgaXMgYXZhaWxhYmxlIGZvciByZWFkaW5nLCBidXQgbm8gc3RhdGUgdXBkYXRlcwogICAgLy8vIGFyZSBleGVjdXRlZC4KICAgIGFjY2VzcyhhbGwpCiAgICB2aWV3IGZ1biBpc1BhdXNlZCgpOiBCb29sIHsKICAgICAgICByZXR1cm4gc2VsZi5hY2NvdW50LnN0b3JhZ2UuY29weTxCb29sPigKICAgICAgICAgICAgZnJvbTogL3N0b3JhZ2UvZXZtT3BlcmF0aW9uc1BhdXNlZAogICAgICAgICkgPz8gZmFsc2UKICAgIH0KCiAgICBpbml0KCkgewogICAgICAgIHNlbGYuc2V0dXBIZWFydGJlYXQoKQogICAgfQoKICAgIC8vIFBsYWNlaG9sZGVyIHRvIGxvYWQgdGVzdCBoZWxwZXJzIGF2YWlsYWJsZSBvbmx5IG9uIEZsb3cgRW11bGF0b3IgbmV0d29yawogICAgLy8gI2xvYWRUZXN0SGVscGVycwp9Cg==",
		"FlowContractAudits": "cHViIGNvbnRyYWN0IEZsb3dDb250cmFjdEF1ZGl0cyB7CiAgICAKICAgIC8vIEV2ZW50IHRoYXQgaXMgZW1pdHRlZCB3aGVuIGEgbmV3IEF1ZGl0b3IgcmVzb3VyY2UgaXMgY3JlYXRlZAogICAgcHViIGV2ZW50IEF1ZGl0b3JDcmVhdGVkKCkKCiAgICAvLyBFdmVudCB0aGF0IGlzIGVtaXR0ZWQgd2hlbiBhIG5ldyBjb250cmFjdCBhdWRpdCB2b3VjaGVyIGlzIGNyZWF0ZWQKICAgIHB1YiBldmVudCBWb3VjaGVyQ3JlYXRlZChhZGRyZXNzOiBBZGRyZXNzPywgcmVjdXJyZW50OiBCb29sLCBleHBpcnlCbG9ja0hlaWdodDogVUludDY0PywgY29kZUhhc2g6IFN0cmluZykKCiAgICAvLyBFdmVudCB0aGF0IGlzIGVtaXR0ZWQgd2hlbiBhIGNvbnRyYWN0IGF1ZGl0IHZvdWNoZXIgaXMgdXNlZAogICAgcHViIGV2ZW50IFZvdWNoZXJVc2VkKGFkZHJlc3M6IEFkZHJlc3MsIGtleTogU3RyaW5nLCByZWN1cnJlbnQ6IEJvb2wsIGV4cGlyeUJsb2NrSGVpZ2h0OiBVSW50NjQ/KQoKICAgIC8vIEV2ZW50IHRoYXQgaXMgZW1pdHRlZCB3aGVuIGEgY29udHJhY3QgYXVkaXQgdm91Y2hlciBpcyByZW1vdmVkCiAgICBwdWIgZXZlbnQgVm91Y2hlclJlbW92ZWQoa2V5OiBTdHJpbmcsIHJlY3VycmVudDogQm9vbCwgZXhwaXJ5QmxvY2tIZWlnaHQ6IFVJbnQ2ND8pCgogICAgLy8gRGljdGlvbmFyeSBvZiBhbGwgdm91Y2hlcnMKICAgIGFjY2Vzcyhjb250cmFjdCkgdmFyIHZvdWNoZXJzOiB7U3RyaW5nOiBBdWRpdFZvdWNoZXJ9CgogICAgLy8gVGhlIHN0b3JhZ2UgcGF0aCBmb3IgdGhlIGFkbWluIHJlc291cmNlCiAgICBwdWIgbGV0IEFkbWluU3RvcmFnZVBhdGg6IFN0b3JhZ2VQYXRoCgogICAgLy8gVGhlIHN0b3JhZ2UgUGF0aCBmb3IgYXVkaXRvcnMnIEF1ZGl0b3JQcm94eQogICAgcHViIGxldCBBdWRpdG9yUHJveHlTdG9yYWdlUGF0aDogU3RvcmFnZVBhdGgKCiAgICAvLyBUaGUgcHVibGljIHBhdGggZm9yIGF1ZGl0b3JzJyBBdWRpdG9yUHJveHkgY2FwYWJpbGl0eQogICAgcHViIGxldCBBdWRpdG9yUHJveHlQdWJsaWNQYXRoOiBQdWJsaWNQYXRoCgogICAgLy8gU2luZ2xlIGF1ZGl0IHZvdWNoZXIgdGhhdCBpcyB1c2VkIGZvciBjb250cmFjdCBkZXBsb3ltZW50CiAgICBwdWIgc3RydWN0IEF1ZGl0Vm91Y2hlciB7CiAgICAgICAgCiAgICAgICAgLy8gQWRkcmVzcyBvZiB0aGUgYWNjb3VudCB0aGUgdm91Y2hlciBpcyBpbnRlbmRlZCBmb3IKICAgICAgICAvLyBJZiBuaWwsIHRoZSBjb250cmFjdCBjYW4gYmUgZGVwbG95ZWQgdG8gYW55IGFjY291bnQKICAgICAgICBwdWIgbGV0IGFkZHJlc3M6IEFkZHJlc3M/CgogICAgICAgIC8vIElmIGZhbHNlLCB0aGUgdm91Y2hlciB3aWxsIGJlIHJlbW92ZWQgYWZ0ZXIgZmlyc3QgdXNlCiAgICAgICAgcHViIGxldCByZWN1cnJlbnQ6IEJvb2wKCiAgICAgICAgLy8gSWYgbm9uLW5pbCwgdGhlIHZvdWNoZXIgd29uJ3QgYmUgdmFsaWQgYWZ0ZXIgdGhlIGV4cGlyeSBibG9jayBoZWlnaHQKICAgICAgICBwdWIgbGV0IGV4cGlyeUJsb2NrSGVpZ2h0OiBVSW50NjQ/CiAgICAgICAgCiAgICAgICAgLy8gSGFzaCBvZiBjb250cmFjdCBjb2RlCiAgICAgICAgcHViIGxldCBjb2RlSGFzaDogU3RyaW5nCiAgICAgICAgCiAgICAgICAgaW5pdChhZGRyZXNzOiBBZGRyZXNzPywgcmVjdXJyZW50OiBCb29sLCBleHBpcnlCbG9ja0hlaWdodDogVUludDY0PywgY29kZUhhc2g6IFN0cmluZykgewogICAgICAgICAgICBzZWxmLmFkZHJlc3MgPSBhZGRyZXNzCiAgICAgICAgICAgIHNlbGYucmVjdXJyZW50ID0gcmVjdXJyZW50CiAgICAgICAgICAgIHNlbGYuZXhwaXJ5QmxvY2tIZWlnaHQgPSBleHBpcnlCbG9ja0hlaWdodAogICAgICAgICAgICBzZWxmLmNvZGVIYXNoID0gY29kZUhhc2gKICAgICAgICB9CiAgICB9CgogICAgLy8gUmV0dXJucyBhbGwgY3VycmVudCB2b3VjaGVycwogICAgcHViIGZ1biBnZXRBbGxWb3VjaGVycygpOiB7U3RyaW5nOiBBdWRpdFZvdWNoZXJ9IHsKICAgICAgICByZXR1cm4gc2VsZi52b3VjaGVycwogICAgfQoKICAgIC8vIEdldCB0aGUgYXNzb2NpYXRlZCBkaWN0aW9uYXJ5IGtleSBmb3IgZ2l2ZW4gYWRkcmVzcyBhbmQgY29kZUhhc2gKICAgIHB1YiBmdW4gZ2VuZXJhdGVWb3VjaGVyS2V5KGFkZHJlc3M6IEFkZHJlc3M/LCBjb2RlSGFzaDogU3RyaW5nKTogU3RyaW5nIHsKICAgICAgICBpZiBhZGRyZXNzICE9IG5pbCB7CiAgICAgICAgICAgIHJldHVybiBhZGRyZXNzIS50b1N0cmluZygpLmNvbmNhdCgiLSIpLmNvbmNhdChjb2RlSGFzaCkKICAgICAgICB9CiAgICAgICAgcmV0dXJuICJhbnktIi5jb25jYXQoY29kZUhhc2gpCiAgICB9CiAgICAKICAgIHB1YiBmdW4gaGFzaENvbnRyYWN0Q29kZShfIGNvZGU6IFN0cmluZyk6IFN0cmluZyB7CiAgICAgICAgcmV0dXJuIFN0cmluZy5lbmNvZGVIZXgoSGFzaEFsZ29yaXRobS5TSEEzXzI1Ni5oYXNoKGNvZGUudXRmOCkpCiAgICB9CgogICAgLy8gQXVkaXRvcnMgY2FuIGNyZWF0ZSBuZXcgdm91Y2hlcnMgYW5kIHJlbW92ZSB0aGVtCiAgICBwdWIgcmVzb3VyY2UgQXVkaXRvciB7CgogICAgICAgIC8vIENyZWF0ZSBuZXcgdm91Y2hlciB3aXRoIGNvbnRyYWN0IGNvZGUKICAgICAgICBwdWIgZnVuIGFkZFZvdWNoZXIoYWRkcmVzczogQWRkcmVzcz8sIHJlY3VycmVudDogQm9vbCwgZXhwaXJ5T2Zmc2V0OiBVSW50NjQ/LCBjb2RlOiBTdHJpbmcpIHsKICAgICAgICAgICAgbGV0IGNvZGVIYXNoID0gRmxvd0NvbnRyYWN0QXVkaXRzLmhhc2hDb250cmFjdENvZGUoY29kZSkKICAgICAgICAgICAgc2VsZi5hZGRWb3VjaGVySGFzaGVkKGFkZHJlc3M6IGFkZHJlc3MsIHJlY3VycmVudDogcmVjdXJyZW50LCBleHBpcnlPZmZzZXQ6IGV4cGlyeU9mZnNldCwgY29kZUhhc2g6IGNvZGVIYXNoKQogICAgICAgIH0KCiAgICAgICAgLy8gQ3JlYXRlIG5ldyB2b3VjaGVyIHdpdGggaGFzaGVkIGNvbnRyYWN0IGNvZGUKICAgICAgICBwdWIgZnVuIGFkZFZvdWNoZXJIYXNoZWQoYWRkcmVzczogQWRkcmVzcz8sIHJlY3VycmVudDogQm9vbCwgZXhwaXJ5T2Zmc2V0OiBVSW50NjQ/LCBjb2RlSGFzaDogU3RyaW5nKSB7CgogICAgICAgICAgICAvLyBjYWxjdWxhdGUgZXhwaXJ5IGJsb2NrIGhlaWdodCBiYXNlZCBvbiBleHBpcnlPZmZzZXQKICAgICAgICAgICAgdmFyIGV4cGlyeUJsb2NrSGVpZ2h0OiBVSW50NjQ/ID0gbmlsCiAgICAgICAgICAgIGlmIGV4cGlyeU9mZnNldCAhPSBuaWwgewogICAgICAgICAgICAgICAgZXhwaXJ5QmxvY2tIZWlnaHQgPSBnZXRDdXJyZW50QmxvY2soKS5oZWlnaHQgKyBleHBpcnlPZmZzZXQhCiAgICAgICAgICAgIH0KICAgICAgICAgICAgCiAgICAgICAgICAgIGxldCBrZXkgPSBGbG93Q29udHJhY3RBdWRpdHMuZ2VuZXJhdGVWb3VjaGVyS2V5KGFkZHJlc3M6IGFkZHJlc3MsIGNvZGVIYXNoOiBjb2RlSGFzaCkKCiAgICAgICAgICAgIC8vIGlmIGEgdm91Y2hlciB3aXRoIHRoZSBzYW1lIGtleSBleGlzdHMsIHJlbW92ZSBpdCBmaXJzdAogICAgICAgICAgICBGbG93Q29udHJhY3RBdWRpdHMuZGVsZXRlVm91Y2hlcihrZXkpCgogICAgICAgICAgICBsZXQgdm91Y2hlciA9IEF1ZGl0Vm91Y2hlcihhZGRyZXNzOiBhZGRyZXNzLCByZWN1cnJlbnQ6IHJlY3VycmVudCwgZXhwaXJ5QmxvY2tIZWlnaHQ6IGV4cGlyeUJsb2NrSGVpZ2h0LCBjb2RlSGFzaDogY29kZUhhc2gpICAgICAgICAgICAgCgogICAgICAgICAgICBGbG93Q29udHJhY3RBdWRpdHMudm91Y2hlcnMuaW5zZXJ0KGtleToga2V5LCB2b3VjaGVyKSAgICAgICAgICAgIAoKICAgICAgICAgICAgZW1pdCBWb3VjaGVyQ3JlYXRlZChhZGRyZXNzOiBhZGRyZXNzLCByZWN1cnJlbnQ6IHJlY3VycmVudCwgZXhwaXJ5QmxvY2tIZWlnaHQ6IGV4cGlyeUJsb2NrSGVpZ2h0LCBjb2RlSGFzaDogY29kZUhhc2gpCiAgICAgICAgfQoKICAgICAgICAvLyBSZW1vdmUgYSB2b3VjaGVyIHdpdGggZ2l2ZW4ga2V5CiAgICAgICAgcHViIGZ1biBkZWxldGVWb3VjaGVyKGtleTogU3RyaW5nKSB7CiAgICAgICAgICAgIEZsb3dDb250cmFjdEF1ZGl0cy5kZWxldGVWb3VjaGVyKGtleSkgICAgICAgICAgICAKICAgICAgICB9CiAgICB9CgogICAgLy8gVXNlZCBieSBhZG1pbiB0byBzZXQgdGhlIEF1ZGl0b3IgY2FwYWJpbGl0eQogICAgcHViIHJlc291cmNlIGludGVyZmFjZSBBdWRpdG9yUHJveHlQdWJsaWMgewogICAgICAgIHB1YiBmdW4gc2V0QXVkaXRvckNhcGFiaWxpdHkoXyBjYXA6IENhcGFiaWxpdHk8JkF1ZGl0b3I+KQogICAgfQoKICAgIC8vIFRoZSBhdWRpdG9yIGFjY291bnQgd2lsbCBoYXZlIGF1ZGl0IGFjY2VzcyB0aHJvdWdoIEF1ZGl0b3JQcm94eQogICAgLy8gVGhpcyBlbmFibGVzIHRoZSBhZG1pbiBhY2NvdW50IHRvIHJldm9rZSBhY2Nlc3MKICAgIC8vIFNlZSBodHRwczovL2RvY3Mub25mbG93Lm9yZy9jYWRlbmNlL2Rlc2lnbi1wYXR0ZXJucy8jY2FwYWJpbGl0eS1yZXZvY2F0aW9uCiAgICBwdWIgcmVzb3VyY2UgQXVkaXRvclByb3h5OiBBdWRpdG9yUHJveHlQdWJsaWMgewogICAgICAgIGFjY2VzcyhzZWxmKSB2YXIgYXVkaXRvckNhcGFiaWxpdHk6IENhcGFiaWxpdHk8JkF1ZGl0b3I+PwoKICAgICAgICBwdWIgZnVuIHNldEF1ZGl0b3JDYXBhYmlsaXR5KF8gY2FwOiBDYXBhYmlsaXR5PCZBdWRpdG9yPikgewogICAgICAgICAgICBzZWxmLmF1ZGl0b3JDYXBhYmlsaXR5ID0gY2FwCiAgICAgICAgfQoKICAgICAgICBwdWIgZnVuIGFkZFZvdWNoZXIoYWRkcmVzczogQWRkcmVzcz8sIHJlY3VycmVudDogQm9vbCwgZXhwaXJ5T2Zmc2V0OiBVSW50NjQ/LCBjb2RlOiBTdHJpbmcpIHsKICAgICAgICAgICAgc2VsZi5hdWRpdG9yQ2FwYWJpbGl0eSEuYm9ycm93KCkhLmFkZFZvdWNoZXIoYWRkcmVzczogYWRkcmVzcywgcmVjdXJyZW50OiByZWN1cnJlbnQsIGV4cGlyeU9mZnNldDogZXhwaXJ5T2Zmc2V0LCBjb2RlOiBjb2RlKQogICAgICAgIH0KCiAgICAgICAgcHViIGZ1biBhZGRWb3VjaGVySGFzaGVkKGFkZHJlc3M6IEFkZHJlc3M/LCByZWN1cnJlbnQ6IEJvb2wsIGV4cGlyeU9mZnNldDogVUludDY0PywgY29kZUhhc2g6IFN0cmluZykgewogICAgICAgICAgICBzZWxmLmF1ZGl0b3JDYXBhYmlsaXR5IS5ib3Jyb3coKSEuYWRkVm91Y2hlckhhc2hlZChhZGRyZXNzOiBhZGRyZXNzLCByZWN1cnJlbnQ6IHJlY3VycmVudCwgZXhwaXJ5T2Zmc2V0OiBleHBpcnlPZmZzZXQsIGNvZGVIYXNoOiBjb2RlSGFzaCkKICAgICAgICB9CgogICAgICAgIHB1YiBmdW4gZGVsZXRlVm91Y2hlcihrZXk6IFN0cmluZykgewogICAgICAgICAgICBzZWxmLmF1ZGl0b3JDYXBhYmlsaXR5IS5ib3Jyb3coKSEuZGVsZXRlVm91Y2hlcihrZXk6IGtleSkKICAgICAgICB9CgogICAgICAgIGluaXQoKSB7CiAgICAgICAgICAgIHNlbGYuYXVkaXRvckNhcGFiaWxpdHkgPSBuaWwKICAgICAgICB9CgogICAgfQoKICAgIC8vIENhbiBiZSBjYWxsZWQgYnkgYW55b25lIGJ1dCBuZWVkcyBhIGNhcGFiaWxpdHkgdG8gZnVuY3Rpb24KICAgIHB1YiBmdW4gY3JlYXRlQXVkaXRvclByb3h5KCk6IEBBdWRpdG9yUHJveHkgewogICAgICAgIHJldHVybiA8LSBjcmVhdGUgQXVkaXRvclByb3h5KCkKICAgIH0KCiAgICBwdWIgcmVzb3VyY2UgQWRtaW5pc3RyYXRvciB7CiAgICAgICAgCiAgICAgICAgLy8gQ3JlYXRlcyBuZXcgQXVkaXRvcgogICAgICAgIHB1YiBmdW4gY3JlYXRlTmV3QXVkaXRvcigpOiBAQXVkaXRvciB7CiAgICAgICAgICAgIGVtaXQgQXVkaXRvckNyZWF0ZWQoKQogICAgICAgICAgICByZXR1cm4gPC1jcmVhdGUgQXVkaXRvcigpCiAgICAgICAgfQoKICAgICAgICAvLyBDaGVja3MgYWxsIHZvdWNoZXJzIGFuZCByZW1vdmVzIGV4cGlyZWQgb25lcwogICAgICAgIHB1YiBmdW4gY2xlYW51cEV4cGlyZWRWb3VjaGVycygpIHsKICAgICAgICAgICAgZm9yIGtleSBpbiBGbG93Q29udHJhY3RBdWRpdHMudm91Y2hlcnMua2V5cyB7ICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgbGV0IHYgPSBGbG93Q29udHJhY3RBdWRpdHMudm91Y2hlcnNba2V5XSEKICAgICAgICAgICAgICAgIGlmIHYuZXhwaXJ5QmxvY2tIZWlnaHQgIT0gbmlsIHsKICAgICAgICAgICAgICAgICAgICBpZiBnZXRDdXJyZW50QmxvY2soKS5oZWlnaHQgPiB2LmV4cGlyeUJsb2NrSGVpZ2h0ISB7CiAgICAgICAgICAgICAgICAgICAgICAgIEZsb3dDb250cmFjdEF1ZGl0cy5kZWxldGVWb3VjaGVyKGtleSkgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIC8vIEZvciB0ZXN0aW5nCiAgICAgICAgcHViIGZ1biB1c2VWb3VjaGVyRm9yRGVwbG95KGFkZHJlc3M6IEFkZHJlc3MsIGNvZGU6IFN0cmluZyk6IEJvb2wgewogICAgICAgICAgICByZXR1cm4gRmxvd0NvbnRyYWN0QXVkaXRzLnVzZVZvdWNoZXJGb3JEZXBsb3koYWRkcmVzczogYWRkcmVzcywgY29kZTogY29kZSkKICAgICAgICB9CiAgICB9CgogICAgLy8gVGhpcyBmdW5jdGlvbiB3aWxsIGJlIGNhbGxlZCBieSB0aGUgRlZNIG9uIGNvbnRyYWN0IGRlcGxveS91cGRhdGUKICAgIGFjY2Vzcyhjb250cmFjdCkgZnVuIHVzZVZvdWNoZXJGb3JEZXBsb3koYWRkcmVzczogQWRkcmVzcywgY29kZTogU3RyaW5nKTogQm9vbCB7CiAgICAgICAgbGV0IGNvZGVIYXNoID0gRmxvd0NvbnRyYWN0QXVkaXRzLmhhc2hDb250cmFjdENvZGUoY29kZSkKICAgICAgICB2YXIga2V5ID0gRmxvd0NvbnRyYWN0QXVkaXRzLmdlbmVyYXRlVm91Y2hlcktleShhZGRyZXNzOiBhZGRyZXNzLCBjb2RlSGFzaDogY29kZUhhc2gpCgogICAgICAgIC8vIGZpcnN0IGNoZWNrIGZvciB2b3VjaGVyIGJhc2VkIG9uIHRhcmdldCBhY2NvdW50CiAgICAgICAgLy8gaWYgbm90IGZvdW5kIGNoZWNrIGZvciBhbnkgYWNjb3VudAogICAgICAgIGlmICFGbG93Q29udHJhY3RBdWRpdHMudm91Y2hlcnMuY29udGFpbnNLZXkoa2V5KSB7CiAgICAgICAgICAgIGtleSA9IEZsb3dDb250cmFjdEF1ZGl0cy5nZW5lcmF0ZVZvdWNoZXJLZXkoYWRkcmVzczogbmlsLCBjb2RlSGFzaDogY29kZUhhc2gpCiAgICAgICAgICAgIGlmICFGbG93Q29udHJhY3RBdWRpdHMudm91Y2hlcnMuY29udGFpbnNLZXkoa2V5KSB7CiAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2UKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgbGV0IHYgPSBGbG93Q29udHJhY3RBdWRpdHMudm91Y2hlcnNba2V5XSEKCiAgICAgICAgLy8gZW5zdXJlIGNvbnRyYWN0IGNvZGUgbWF0Y2hlcyB0aGUgdm91Y2hlcgogICAgICAgIGlmIHYuY29kZUhhc2ggIT0gY29kZUhhc2ggIHsKICAgICAgICAgICAgcmV0dXJuIGZhbHNlCiAgICAgICAgfQoKICAgICAgICAvLyBpZiBleHBpcnlCbG9ja0hlaWdodCBpcyBzZXQsIGNoZWNrIHRoZSBjdXJyZW50IGJsb2NrIGhlaWdodAogICAgICAgIC8vIGFuZCByZW1vdmUvZXhwaXJlIHRoZSB2b3VjaGVyIGlmIG5vdCB3aXRoaW4gdGhlIGFjY2VwdGFibGUgcmFuZ2UKICAgICAgICBpZiB2LmV4cGlyeUJsb2NrSGVpZ2h0ICE9IG5pbCB7CiAgICAgICAgICAgIGlmIGdldEN1cnJlbnRCbG9jaygpLmhlaWdodCA+IHYuZXhwaXJ5QmxvY2tIZWlnaHQhIHsKICAgICAgICAgICAgICAgIEZsb3dDb250cmFjdEF1ZGl0cy5kZWxldGVWb3VjaGVyKGtleSkgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2UKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgLy8gcmVtb3ZlIHRoZSB2b3VjaGVyIGlmIG5vdCByZWN1cnJlbnQKICAgICAgICBpZiAhdi5yZWN1cnJlbnQgewogICAgICAgICAgICBGbG93Q29udHJhY3RBdWRpdHMuZGVsZXRlVm91Y2hlcihrZXkpCiAgICAgICAgfQogICAgICAgICAgICAgICAgCiAgICAgICAgZW1pdCBWb3VjaGVyVXNlZChhZGRyZXNzOiBhZGRyZXNzLCBrZXk6IGtleSwgcmVjdXJyZW50OiB2LnJlY3VycmVudCwgZXhwaXJ5QmxvY2tIZWlnaHQ6IHYuZXhwaXJ5QmxvY2tIZWlnaHQpICAgICAgICAgICAgICAgIAogICAgICAgIHJldHVybiB0cnVlCiAgICB9CgogICAgLy8gSGVscGVyIGZ1bmN0aW9uIHRvIHJlbW92ZSBhIHZvdWNoZXIgd2l0aCBnaXZlbiBrZXkKICAgIGFjY2Vzcyhjb250cmFjdCkgZnVuIGRlbGV0ZVZvdWNoZXIoXyBrZXk6IFN0cmluZykgewogICAgICAgIGxldCB2ID0gRmxvd0NvbnRyYWN0QXVkaXRzLnZvdWNoZXJzLnJlbW92ZShrZXk6IGtleSkKICAgICAgICBpZiB2ICE9IG5pbCB7CiAgICAgICAgICAgIGVtaXQgVm91Y2hlclJlbW92ZWQoa2V5OiBrZXksIHJlY3VycmVudDogdiEucmVjdXJyZW50LCBleHBpcnlCbG9ja0hlaWdodDogdiEuZXhwaXJ5QmxvY2tIZWlnaHQpCiAgICAgICAgfQogICAgfQoKICAgIGluaXQoKSB7CiAgICAgICAgc2VsZi52b3VjaGVycyA9IHt9CgogICAgICAgIHNlbGYuQWRtaW5TdG9yYWdlUGF0aCA9IC9zdG9yYWdlL2Zsb3dDb250cmFjdEF1ZGl0Vm91Y2hlcnNBZG1pbgogICAgICAgIHNlbGYuQXVkaXRvclByb3h5U3RvcmFnZVBhdGggPSAvc3RvcmFnZS9mbG93Q29udHJhY3RBdWRpdFZvdWNoZXJzQXVkaXRvclByb3h5CiAgICAgICAgc2VsZi5BdWRpdG9yUHJveHlQdWJsaWNQYXRoID0gL3B1YmxpYy9mbG93Q29udHJhY3RBdWRpdFZvdWNoZXJzQXVkaXRvclByb3h5CgogICAgICAgIGxldCBhZG1pbiA8LSBjcmVhdGUgQWRtaW5pc3RyYXRvcigpCiAgICAgICAgc2VsZi5hY2NvdW50LnNhdmUoPC1hZG1pbiwgdG86IHNlbGYuQWRtaW5TdG9yYWdlUGF0aCkKICAgIH0KfQo=",
		"FlowServiceAccount": "aW1wb3J0IEZ1bmdpYmxlVG9rZW4gZnJvbSAweGYyMzNkY2VlODhmZTBhYmUKaW1wb3J0IEZsb3dUb2tlbiBmcm9tIDB4MTY1NDY1MzM5OTA0MGE2MQppbXBvcnQgRmxvd0ZlZXMgZnJvbSAweGY5MTllZTc3NDQ3Yjc0OTcKaW1wb3J0IEZsb3dTdG9yYWdlRmVlcyBmcm9tIDB4ZTQ2N2I5ZGQxMWZhMDBkZgppbXBvcnQgRmxvd0V4ZWN1dGlvblBhcmFtZXRlcnMgZnJvbSAweGY0MjZmZjU3ZWU4ZjYxMTAKCmFjY2VzcyhhbGwpIGNvbnRyYWN0IEZsb3dTZXJ2aWNlQWNjb3VudCB7CgogICAgYWNjZXNzKGFsbCkgZXZlbnQgVHJhbnNhY3Rpb25GZWVVcGRhdGVkKG5ld0ZlZTogVUZpeDY0KQoKICAgIGFjY2VzcyhhbGwpIGV2ZW50IEFjY291bnRDcmVhdGlvbkZlZVVwZGF0ZWQobmV3RmVlOiBVRml4NjQpCgogICAgYWNjZXNzKGFsbCkgZXZlbnQgQWNjb3VudENyZWF0b3JBZGRlZChhY2NvdW50Q3JlYXRvcjogQWRkcmVzcykKCiAgICBhY2Nlc3MoYWxsKSBldmVudCBBY2NvdW50Q3JlYXRvclJlbW92ZWQoYWNjb3VudENyZWF0b3I6IEFkZHJlc3MpCgogICAgYWNjZXNzKGFsbCkgZXZlbnQgSXNBY2NvdW50Q3JlYXRpb25SZXN0cmljdGVkVXBkYXRlZChpc1Jlc3RyaWN0ZWQ6IEJvb2wpCgogICAgLy8vIEEgZml4ZWQtcmF0ZSBmZWUgY2hhcmdlZCB0byBleGVjdXRlIGEgdHJhbnNhY3Rpb24KICAgIGFjY2VzcyhhbGwpIHZhciB0cmFuc2FjdGlvbkZlZTogVUZpeDY0CgogICAgLy8vIEEgZml4ZWQtcmF0ZSBmZWUgY2hhcmdlZCB0byBjcmVhdGUgYSBuZXcgYWNjb3VudAogICAgYWNjZXNzKGFsbCkgdmFyIGFjY291bnRDcmVhdGlvbkZlZTogVUZpeDY0CgogICAgLy8vIFRoZSBsaXN0IG9mIGFjY291bnQgYWRkcmVzc2VzIHRoYXQgaGF2ZSBwZXJtaXNzaW9uIHRvIGNyZWF0ZSBhY2NvdW50cwogICAgYWNjZXNzKGNvbnRyYWN0KSB2YXIgYWNjb3VudENyZWF0b3JzOiB7QWRkcmVzczogQm9vbH0KCiAgICAvLy8gSW5pdGlhbGl6ZSBhbiBhY2NvdW50IHdpdGggYSBGbG93VG9rZW4gVmF1bHQgYW5kIHB1Ymxpc2ggY2FwYWJpbGl0aWVzLgogICAgYWNjZXNzKGFsbCkgZnVuIGluaXREZWZhdWx0VG9rZW4oXyBhY2N0OiBhdXRoKFNhdmVWYWx1ZSwgQ2FwYWJpbGl0aWVzKSAmQWNjb3VudCkgewogICAgICAgIC8vIENyZWF0ZSBhIG5ldyBGbG93VG9rZW4gVmF1bHQgYW5kIHNhdmUgaXQgaW4gc3RvcmFnZQogICAgICAgIGFjY3Quc3RvcmFnZS5zYXZlKDwtRmxvd1Rva2VuLmNyZWF0ZUVtcHR5VmF1bHQodmF1bHRUeXBlOiBUeXBlPEBGbG93VG9rZW4uVmF1bHQ+KCkpLCB0bzogL3N0b3JhZ2UvZmxvd1Rva2VuVmF1bHQpCgogICAgICAgIC8vIENyZWF0ZSBhIHB1YmxpYyBjYXBhYmlsaXR5IHRvIHRoZSBWYXVsdCB0aGF0IG9ubHkgZXhwb3NlcwogICAgICAgIC8vIHRoZSBkZXBvc2l0IGZ1bmN0aW9uIHRocm91Z2ggdGhlIFJlY2VpdmVyIGludGVyZmFjZQogICAgICAgIGxldCByZWNlaXZlckNhcGFiaWxpdHkgPSBhY2N0LmNhcGFiaWxpdGllcy5zdG9yYWdlLmlzc3VlPCZGbG93VG9rZW4uVmF1bHQ+KC9zdG9yYWdlL2Zsb3dUb2tlblZhdWx0KQogICAgICAgIGFjY3QuY2FwYWJpbGl0aWVzLnB1Ymxpc2gocmVjZWl2ZXJDYXBhYmlsaXR5LCBhdDogL3B1YmxpYy9mbG93VG9rZW5SZWNlaXZlcikKCiAgICAgICAgLy8gQ3JlYXRlIGEgcHVibGljIGNhcGFiaWxpdHkgdG8gdGhlIFZhdWx0IHRoYXQgb25seSBleHBvc2VzCiAgICAgICAgLy8gdGhlIGJhbGFuY2UgZmllbGQgdGhyb3VnaCB0aGUgQmFsYW5jZSBpbnRlcmZhY2UKICAgICAgICBsZXQgYmFsYW5jZUNhcGFiaWxpdHkgPSBhY2N0LmNhcGFiaWxpdGllcy5zdG9yYWdlLmlzc3VlPCZGbG93VG9rZW4uVmF1bHQ+KC9zdG9yYWdlL2Zsb3dUb2tlblZhdWx0KQogICAgICAgIGFjY3QuY2FwYWJpbGl0aWVzLnB1Ymxpc2goYmFsYW5jZUNhcGFiaWxpdHksIGF0OiAvcHVibGljL2Zsb3dUb2tlbkJhbGFuY2UpCiAgICB9CgogICAgLy8vIEdldCB0aGUgZGVmYXVsdCB0b2tlbiBiYWxhbmNlIG9uIGFuIGFjY291bnQKICAgIC8vLwogICAgLy8vIFJldHVybnMgMCBpZiB0aGUgYWNjb3VudCBoYXMgbm8gZGVmYXVsdCBiYWxhbmNlCiAgICAvLy8KICAgIC8vLyBEZXByZWNhdGVkOiBwcmVmZXIgYGFjY3QuYmFsYW5jZWAgZGlyZWN0bHkuIFRoaXMgZnVuY3Rpb24gaXMgb25seQogICAgLy8vIGtlcHQgZm9yIGhpc3RvcmljIHJlYXNvbnMuCiAgICBhY2Nlc3MoYWxsKSB2aWV3IGZ1biBkZWZhdWx0VG9rZW5CYWxhbmNlKF8gYWNjdDogJkFjY291bnQpOiBVRml4NjQgewogICAgICAgIHJldHVybiBhY2N0LmJhbGFuY2UKICAgIH0KCiAgICAvLy8gUmV0dXJuIGEgcmVmZXJlbmNlIHRvIHRoZSBkZWZhdWx0IHRva2VuIHZhdWx0IG9uIGFuIGFjY291bnQKICAgIGFjY2VzcyhhbGwpIHZpZXcgZnVuIGRlZmF1bHRUb2tlblZhdWx0KF8gYWNjdDogYXV0aChCb3Jyb3dWYWx1ZSkgJkFjY291bnQpOiBhdXRoKEZ1bmdpYmxlVG9rZW4uV2l0aGRyYXcpICZGbG93VG9rZW4uVmF1bHQgewogICAgICAgIHJldHVybiBhY2N0LnN0b3JhZ2UuYm9ycm93PGF1dGgoRnVuZ2libGVUb2tlbi5XaXRoZHJhdykgJkZsb3dUb2tlbi5WYXVsdD4oZnJvbTogL3N0b3JhZ2UvZmxvd1Rva2VuVmF1bHQpCiAgICAgICAgICAgID8/IHBhbmljKCJGbG93U2VydmljZUFjY291bnQuZGVmYXVsdFRva2VuVmF1bHQ6IFVuYWJsZSB0byBib3Jyb3cgcmVmZXJlbmNlIHRvIHRoZSBkZWZhdWx0IHRva2VuIHZhdWx0IikKICAgIH0KCiAgICAvLy8gV2lsbCBiZSBkZXByZWNhdGVkIGFuZCBjYW4gYmUgZGVsZXRlZCBhZnRlciB0aGUgc3dpdGNob3ZlciB0byBGbG93RmVlcy5kZWR1Y3RUcmFuc2FjdGlvbkZlZQogICAgLy8vCiAgICAvLy8gQ2FsbGVkIHdoZW4gYSB0cmFuc2FjdGlvbiBpcyBzdWJtaXR0ZWQgdG8gZGVkdWN0IHRoZSBmZWUKICAgIC8vLyBmcm9tIHRoZSBBdXRoQWNjb3VudCB0aGF0IHN1Ym1pdHRlZCBpdAogICAgYWNjZXNzKGFsbCkgZnVuIGRlZHVjdFRyYW5zYWN0aW9uRmVlKF8gYWNjdDogYXV0aChCb3Jyb3dWYWx1ZSkgJkFjY291bnQpIHsKICAgICAgICBpZiBzZWxmLnRyYW5zYWN0aW9uRmVlID09IFVGaXg2NCgwKSB7CiAgICAgICAgICAgIHJldHVybgogICAgICAgIH0KCiAgICAgICAgbGV0IHRva2VuVmF1bHQgPSBzZWxmLmRlZmF1bHRUb2tlblZhdWx0KGFjY3QpCiAgICAgICAgdmFyIGZlZUFtb3VudCA9IHNlbGYudHJhbnNhY3Rpb25GZWUKICAgICAgICBpZiBzZWxmLnRyYW5zYWN0aW9uRmVlID4gdG9rZW5WYXVsdC5iYWxhbmNlIHsKICAgICAgICAgICAgZmVlQW1vdW50ID0gdG9rZW5WYXVsdC5iYWxhbmNlCiAgICAgICAgfQogICAgICAgIAogICAgICAgIGxldCBmZWVWYXVsdCA8LSB0b2tlblZhdWx0LndpdGhkcmF3KGFtb3VudDogZmVlQW1vdW50KQogICAgICAgIEZsb3dGZWVzLmRlcG9zaXQoZnJvbTogPC1mZWVWYXVsdCkKICAgIH0KCiAgICAvLy8gLSBEZWR1Y3RzIHRoZSBhY2NvdW50IGNyZWF0aW9uIGZlZSBmcm9tIGEgcGF5ZXIgYWNjb3VudC4KICAgIC8vLyAtIEluaXRzIHRoZSBkZWZhdWx0IHRva2VuLgogICAgLy8vIC0gSW5pdHMgYWNjb3VudCBzdG9yYWdlIGNhcGFjaXR5LgogICAgYWNjZXNzKGFsbCkgZnVuIHNldHVwTmV3QWNjb3VudCgKICAgICAgICBuZXdBY2NvdW50OiBhdXRoKFNhdmVWYWx1ZSwgQm9ycm93VmFsdWUsIENhcGFiaWxpdGllcykgJkFjY291bnQsCiAgICAgICAgcGF5ZXI6IGF1dGgoQm9ycm93VmFsdWUpICZBY2NvdW50CiAgICApIHsKCiAgICAgICAgaWYgIUZsb3dTZXJ2aWNlQWNjb3VudC5pc0FjY291bnRDcmVhdG9yKHBheWVyLmFkZHJlc3MpIHsKICAgICAgICAgICAgcGFuaWMoIkZsb3dTZXJ2aWNlQWNjb3VudC5zZXR1cE5ld0FjY291bnQ6IEFjY291bnQgXChwYXllci5hZGRyZXNzKSBpcyBub3QgYXV0aG9yaXplZCB0byBjcmVhdGUgYWNjb3VudHMiKQogICAgICAgIH0KCgogICAgICAgIGlmIHNlbGYuYWNjb3VudENyZWF0aW9uRmVlIDwgRmxvd1N0b3JhZ2VGZWVzLm1pbmltdW1TdG9yYWdlUmVzZXJ2YXRpb24gewogICAgICAgICAgICBwYW5pYygiRmxvd1NlcnZpY2VBY2NvdW50LnNldHVwTmV3QWNjb3VudDogQWNjb3VudCBjcmVhdGlvbiBmZWVzIHNldHVwIGluY29ycmVjdGx5IikKICAgICAgICB9CgogICAgICAgIGxldCB0b2tlblZhdWx0ID0gc2VsZi5kZWZhdWx0VG9rZW5WYXVsdChwYXllcikKICAgICAgICBsZXQgZmVlVmF1bHQgPC0gdG9rZW5WYXVsdC53aXRoZHJhdyhhbW91bnQ6IHNlbGYuYWNjb3VudENyZWF0aW9uRmVlKQogICAgICAgIGxldCBzdG9yYWdlRmVlVmF1bHQgPC0gKGZlZVZhdWx0LndpdGhkcmF3KGFtb3VudDogRmxvd1N0b3JhZ2VGZWVzLm1pbmltdW1TdG9yYWdlUmVzZXJ2YXRpb24pIGFzISBARmxvd1Rva2VuLlZhdWx0KQogICAgICAgIEZsb3dGZWVzLmRlcG9zaXQoZnJvbTogPC1mZWVWYXVsdCkKCiAgICAgICAgRmxvd1NlcnZpY2VBY2NvdW50LmluaXREZWZhdWx0VG9rZW4obmV3QWNjb3VudCkKCiAgICAgICAgbGV0IHZhdWx0UmVmID0gRmxvd1NlcnZpY2VBY2NvdW50LmRlZmF1bHRUb2tlblZhdWx0KG5ld0FjY291bnQpCgogICAgICAgIHZhdWx0UmVmLmRlcG9zaXQoZnJvbTogPC1zdG9yYWdlRmVlVmF1bHQpCiAgICB9CgogICAgLy8vIFJldHVybnMgdHJ1ZSBpZiB0aGUgZ2l2ZW4gYWRkcmVzcyBpcyBwZXJtaXR0ZWQgdG8gY3JlYXRlIGFjY291bnRzLCBmYWxzZSBvdGhlcndpc2UKICAgIGFjY2VzcyhhbGwpIHZpZXcgZnVuIGlzQWNjb3VudENyZWF0b3IoXyBhZGRyZXNzOiBBZGRyZXNzKTogQm9vbCB7CiAgICAgICAgLy8gSWYgYWNjb3VudCBjcmVhdGlvbiBpcyBub3QgcmVzdHJpY3RlZCwgdGhlbiBhbnlvbmUgY2FuIGNyZWF0ZSBhbiBhY2NvdW50CiAgICAgICAgaWYgIXNlbGYuaXNBY2NvdW50Q3JlYXRpb25SZXN0cmljdGVkKCkgewogICAgICAgICAgICByZXR1cm4gdHJ1ZQogICAgICAgIH0KICAgICAgICByZXR1cm4gc2VsZi5hY2NvdW50Q3JlYXRvcnNbYWRkcmVzc10gPz8gZmFsc2UKICAgIH0KCiAgICAvLy8gSXMgdHJ1ZSBpZiBuZXcgYWNjb250cyBjYW4gb25seSBiZSBjcmVhdGVkIGJ5IGFwcHJvdmVkIGFjY291bnRzIGBzZWxmLmFjY291bnRDcmVhdG9yc2AKICAgIGFjY2VzcyhhbGwpIHZpZXcgZnVuIGlzQWNjb3VudENyZWF0aW9uUmVzdHJpY3RlZCgpOiBCb29sIHsKICAgICAgICByZXR1cm4gc2VsZi5hY2NvdW50LnN0b3JhZ2UuY29weTxCb29sPihmcm9tOiAvc3RvcmFnZS9pc0FjY291bnRDcmVhdGlvblJlc3RyaWN0ZWQpID8/IGZhbHNlCiAgICB9CgogICAgLy8gQXV0aG9yaXphdGlvbiByZXNvdXJjZSB0byBjaGFuZ2UgdGhlIGZpZWxkcyBvZiB0aGUgY29udHJhY3QKICAgIC8vLyBSZXR1cm5zIGFsbCBhZGRyZXNzZXMgcGVybWl0dGVkIHRvIGNyZWF0ZSBhY2NvdW50cwogICAgYWNjZXNzKGFsbCkgdmlldyBmdW4gZ2V0QWNjb3VudENyZWF0b3JzKCk6IFtBZGRyZXNzXSB7CiAgICAgICAgcmV0dXJuIHNlbGYuYWNjb3VudENyZWF0b3JzLmtleXMKICAgIH0KCiAgICAvLyBHZXRzIEV4ZWN1dGlvbiBFZmZvcnQgV2VpZ2h0cyBmcm9tIHRoZSBzZXJ2aWNlIGFjY291bnQncyBzdG9yYWdlIAogICAgYWNjZXNzKGFsbCkgdmlldyBmdW4gZ2V0RXhlY3V0aW9uRWZmb3J0V2VpZ2h0cygpOiB7VUludDY0OiBVSW50NjR9IHsKICAgICAgICByZXR1cm4gRmxvd0V4ZWN1dGlvblBhcmFtZXRlcnMuZ2V0RXhlY3V0aW9uRWZmb3J0V2VpZ2h0cygpCiAgICB9CgogICAgLy8gR2V0cyBFeGVjdXRpb24gTWVtb3J5IFdlaWdodHMgZnJvbSB0aGUgc2VydmljZSBhY2NvdW50J3Mgc3RvcmFnZSAKICAgIGFjY2VzcyhhbGwpIHZpZXcgZnVuIGdldEV4ZWN1dGlvbk1lbW9yeVdlaWdodHMoKToge1VJbnQ2NDogVUludDY0fSB7CiAgICAgICAgcmV0dXJuIEZsb3dFeGVjdXRpb25QYXJhbWV0ZXJzLmdldEV4ZWN1dGlvbk1lbW9yeVdlaWdodHMoKQogICAgfQoKICAgIC8vIEdldHMgRXhlY3V0aW9uIE1lbW9yeSBMaW1pdCBmcm9tIHRoZSBzZXJ2aWNlIGFjY291bnQncyBzdG9yYWdlCiAgICBhY2Nlc3MoYWxsKSB2aWV3IGZ1biBnZXRFeGVjdXRpb25NZW1vcnlMaW1pdCgpOiBVSW50NjQgewogICAgICAgIHJldHVybiBGbG93RXhlY3V0aW9uUGFyYW1ldGVycy5nZXRFeGVjdXRpb25NZW1vcnlMaW1pdCgpCiAgICB9CgogICAgLy8vIEF1dGhvcml6YXRpb24gcmVzb3VyY2UgdG8gY2hhbmdlIHRoZSBmaWVsZHMgb2YgdGhlIGNvbnRyYWN0CiAgICBhY2Nlc3MoYWxsKSByZXNvdXJjZSBBZG1pbmlzdHJhdG9yIHsKCiAgICAgICAgLy8vIFNldHMgdGhlIHRyYW5zYWN0aW9uIGZlZQogICAgICAgIGFjY2VzcyhhbGwpIGZ1biBzZXRUcmFuc2FjdGlvbkZlZShfIG5ld0ZlZTogVUZpeDY0KSB7CiAgICAgICAgICAgIGlmIG5ld0ZlZSAhPSBGbG93U2VydmljZUFjY291bnQudHJhbnNhY3Rpb25GZWUgewogICAgICAgICAgICAgICAgZW1pdCBUcmFuc2FjdGlvbkZlZVVwZGF0ZWQobmV3RmVlOiBuZXdGZWUpCiAgICAgICAgICAgIH0KICAgICAgICAgICAgRmxvd1NlcnZpY2VBY2NvdW50LnRyYW5zYWN0aW9uRmVlID0gbmV3RmVlCiAgICAgICAgfQoKICAgICAgICAvLy8gU2V0cyB0aGUgYWNjb3VudCBjcmVhdGlvbiBmZWUKICAgICAgICBhY2Nlc3MoYWxsKSBmdW4gc2V0QWNjb3VudENyZWF0aW9uRmVlKF8gbmV3RmVlOiBVRml4NjQpIHsKICAgICAgICAgICAgaWYgbmV3RmVlICE9IEZsb3dTZXJ2aWNlQWNjb3VudC5hY2NvdW50Q3JlYXRpb25GZWUgewogICAgICAgICAgICAgICAgZW1pdCBBY2NvdW50Q3JlYXRpb25GZWVVcGRhdGVkKG5ld0ZlZTogbmV3RmVlKQogICAgICAgICAgICB9CiAgICAgICAgICAgIEZsb3dTZXJ2aWNlQWNjb3VudC5hY2NvdW50Q3JlYXRpb25GZWUgPSBuZXdGZWUKICAgICAgICB9CgogICAgICAgIC8vLyBBZGRzIGFuIGFjY291bnQgYWRkcmVzcyBhcyBhbiBhdXRob3JpemVkIGFjY291bnQgY3JlYXRvcgogICAgICAgIGFjY2VzcyhhbGwpIGZ1biBhZGRBY2NvdW50Q3JlYXRvcihfIGFjY291bnRDcmVhdG9yOiBBZGRyZXNzKSB7CiAgICAgICAgICAgIGlmIEZsb3dTZXJ2aWNlQWNjb3VudC5hY2NvdW50Q3JlYXRvcnNbYWNjb3VudENyZWF0b3JdID09IG5pbCB7CiAgICAgICAgICAgICAgICBlbWl0IEFjY291bnRDcmVhdG9yQWRkZWQoYWNjb3VudENyZWF0b3I6IGFjY291bnRDcmVhdG9yKQogICAgICAgICAgICB9CiAgICAgICAgICAgIEZsb3dTZXJ2aWNlQWNjb3VudC5hY2NvdW50Q3JlYXRvcnNbYWNjb3VudENyZWF0b3JdID0gdHJ1ZQogICAgICAgIH0KCiAgICAgICAgLy8vIFJlbW92ZXMgYW4gYWNjb3VudCBhZGRyZXNzIGFzIGFuIGF1dGhvcml6ZWQgYWNjb3VudCBjcmVhdG9yCiAgICAgICAgYWNjZXNzKGFsbCkgZnVuIHJlbW92ZUFjY291bnRDcmVhdG9yKF8gYWNjb3VudENyZWF0b3I6IEFkZHJlc3MpIHsKICAgICAgICAgICAgaWYgRmxvd1NlcnZpY2VBY2NvdW50LmFjY291bnRDcmVhdG9yc1thY2NvdW50Q3JlYXRvcl0gIT0gbmlsIHsKICAgICAgICAgICAgICAgIGVtaXQgQWNjb3VudENyZWF0b3JSZW1vdmVkKGFjY291bnRDcmVhdG9yOiBhY2NvdW50Q3JlYXRvcikKICAgICAgICAgICAgfQogICAgICAgICAgICBGbG93U2VydmljZUFjY291bnQuYWNjb3VudENyZWF0b3JzLnJlbW92ZShrZXk6IGFjY291bnRDcmVhdG9yKQogICAgICAgIH0KCiAgICAgICAgIGFjY2VzcyhhbGwpIGZ1biBzZXRJc0FjY291bnRDcmVhdGlvblJlc3RyaWN0ZWQoXyBlbmFibGVkOiBCb29sKSB7CiAgICAgICAgICAgIGxldCBwYXRoID0gL3N0b3JhZ2UvaXNBY2NvdW50Q3JlYXRpb25SZXN0cmljdGVkCiAgICAgICAgICAgIGxldCBvbGRWYWx1ZSA9IEZsb3dTZXJ2aWNlQWNjb3VudC5hY2NvdW50LnN0b3JhZ2UubG9hZDxCb29sPihmcm9tOiBwYXRoKQogICAgICAgICAgICBGbG93U2VydmljZUFjY291bnQuYWNjb3VudC5zdG9yYWdlLnNhdmU8Qm9vbD4oZW5hYmxlZCwgdG86IHBhdGgpCiAgICAgICAgICAgIGlmIGVuYWJsZWQgIT0gb2xkVmFsdWUgewogICAgICAgICAgICAgICAgZW1pdCBJc0FjY291bnRDcmVhdGlvblJlc3RyaWN0ZWRVcGRhdGVkKGlzUmVzdHJpY3RlZDogZW5hYmxlZCkKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0KCiAgICBpbml0KCkgewogICAgICAgIHNlbGYudHJhbnNhY3Rpb25GZWUgPSAwLjAKICAgICAgICBzZWxmLmFjY291bnRDcmVhdGlvbkZlZSA9IDAuMAoKICAgICAgICBzZWxmLmFjY291bnRDcmVhdG9ycyA9IHt9CgogICAgICAgIGxldCBhZG1pbiA8LSBjcmVhdGUgQWRtaW5pc3RyYXRvcigpCiAgICAgICAgYWRtaW4uYWRkQWNjb3VudENyZWF0b3Ioc2VsZi5hY2NvdW50LmFkZHJlc3MpCgogICAgICAgIHNlbGYuYWNjb3VudC5zdG9yYWdlLnNhdmUoPC1hZG1pbiwgdG86IC9zdG9yYWdlL2Zsb3dTZXJ2aWNlQWRtaW4pCiAgICB9Cn0K",
		"FlowStorageFees": "LyoKICogVGhlIEZsb3dTdG9yYWdlRmVlcyBzbWFydCBjb250cmFjdAogKgogKiBBbiBhY2NvdW50J3Mgc3RvcmFnZSBjYXBhY2l0eSBkZXRlcm1pbmVzIHVwIHRvIGhvdyBtdWNoIHN0b3JhZ2Ugb24gY2hhaW4gaXQgY2FuIHVzZS4gCiAqIEEgc3RvcmFnZSBjYXBhY2l0eSBpcyBjYWxjdWxhdGVkIGJ5IG11bHRpcGx5aW5nIHRoZSBhbW91bnQgb2YgcmVzZXJ2ZWQgZmxvdyB3aXRoIGBTdG9yYWdlRmVlLnN0b3JhZ2VNZWdhQnl0ZXNQZXJSZXNlcnZlZEZMT1dgCiAqIFRoZSBtaW5pbXVtIGFtb3VudCBvZiBmbG93IHRva2VucyByZXNlcnZlZCBmb3Igc3RvcmFnZSBjYXBhY2l0eSBpcyBgRmxvd1N0b3JhZ2VGZWVzLm1pbmltdW1TdG9yYWdlUmVzZXJ2YXRpb25gIHRoaXMgaXMgcGFpZCBkdXJpbmcgYWNjb3VudCBjcmVhdGlvbiwgYnkgdGhlIGNyZWF0b3IuCiAqIAogKiBBdCB0aGUgZW5kIG9mIGFsbCB0cmFuc2FjdGlvbnMsIGFueSBhY2NvdW50IHRoYXQgaGFkIGFueSB2YWx1ZSBjaGFuZ2VkIGluIHRoZWlyIHN0b3JhZ2UgCiAqIGhhcyB0aGVpciBzdG9yYWdlIGNhcGFjaXR5IGNoZWNrZWQgYWdhaW5zdCB0aGVpciBzdG9yYWdlIHVzZWQgYW5kIHRoZWlyIG1haW4gZmxvdyB0b2tlbiB2YXVsdCBhZ2FpbnN0IHRoZSBtaW5pbXVtIHJlc2VydmF0aW9uLgogKiBJZiBhbnkgYWNjb3VudCBmYWlscyB0aGlzIGNoZWNrIHRoZSB0cmFuc2FjdGlvbiB3aWwgZmFpbC4KICogCiAqIEFuIGFjY291bnQgbW92aW5nL2RlbGV0aW5nIGl0cyBgRmxvd1Rva2VuLlZhdWx0YCByZXNvdXJjZSB3aWxsIHJlc3VsdCAKICogaW4gdGhlIHRyYW5zYWN0aW9uIGZhaWxpbmcgYmVjYXVzZSB0aGUgYWNjb3VudCB3aWxsIGhhdmUgbm8gc3RvcmFnZSBjYXBhY2l0eS4KICogCiAqLwoKaW1wb3J0IEZ1bmdpYmxlVG9rZW4gZnJvbSAweGYyMzNkY2VlODhmZTBhYmUKaW1wb3J0IEZsb3dUb2tlbiBmcm9tIDB4MTY1NDY1MzM5OTA0MGE2MQoKYWNjZXNzKGFsbCkgY29udHJhY3QgRmxvd1N0b3JhZ2VGZWVzIHsKCiAgICAvLyBFbWl0dGVkIHdoZW4gdGhlIGFtb3VudCBvZiBzdG9yYWdlIGNhcGFjaXR5IGFuIGFjY291bnQgaGFzIHBlciByZXNlcnZlZCBGbG93IHRva2VuIGNoYW5nZXMKICAgIGFjY2VzcyhhbGwpIGV2ZW50IFN0b3JhZ2VNZWdhQnl0ZXNQZXJSZXNlcnZlZEZMT1dDaGFuZ2VkKF8gc3RvcmFnZU1lZ2FCeXRlc1BlclJlc2VydmVkRkxPVzogVUZpeDY0KQoKICAgIC8vIEVtaXR0ZWQgd2hlbiB0aGUgbWluaW11bSBhbW91bnQgb2YgRmxvdyB0b2tlbnMgdGhhdCBhbiBhY2NvdW50IG5lZWRzIHRvIGhhdmUgcmVzZXJ2ZWQgZm9yIHN0b3JhZ2UgY2FwYWNpdHkgY2hhbmdlcy4KICAgIGFjY2VzcyhhbGwpIGV2ZW50IE1pbmltdW1TdG9yYWdlUmVzZXJ2YXRpb25DaGFuZ2VkKF8gbWluaW11bVN0b3JhZ2VSZXNlcnZhdGlvbjogVUZpeDY0KQoKICAgIC8vIERlZmluZXMgaG93IG11Y2ggc3RvcmFnZSBjYXBhY2l0eSBldmVyeSBhY2NvdW50IGhhcyBwZXIgcmVzZXJ2ZWQgRmxvdyB0b2tlbi4KICAgIC8vIGRlZmluaXRpb24gaXMgd3JpdHRlbiBwZXIgdW5pdCBvZiBmbG93IGluc3RlYWQgb2YgdGhlIGludmVyc2UsIAogICAgLy8gc28gdGhlcmUgaXMgbm8gbG9zcyBvZiBwcmVjaXNpb24gY2FsY3VsYXRpbmcgc3RvcmFnZSBmcm9tIGZsb3csIAogICAgLy8gYnV0IHRoZXJlIGlzIGxvc3Mgb2YgcHJlY2lzaW9uIHdoZW4gY2FsY3VsYXRpbmcgZmxvdyBwZXIgc3RvcmFnZS4KICAgIGFjY2VzcyhhbGwpIHZhciBzdG9yYWdlTWVnYUJ5dGVzUGVyUmVzZXJ2ZWRGTE9XOiBVRml4NjQKCiAgICAvLyBEZWZpbmVzIHRoZSBtaW5pbXVtIGFtb3VudCBvZiBGbG93IHRva2VucyB0aGF0IGV2ZXJ5IGFjY291bnQgbmVlZHMgdG8gaGF2ZSByZXNlcnZlZCBmb3Igc3RvcmFnZSBjYXBhY2l0eS4KICAgIC8vIElmIGFuIGFjY291bnQgaGFzIGxlc3MgdGhlbiB0aGlzIGFtb3VudCByZXNlcnZlZCBieSB0aGUgZW5kIG9mIGFueSB0cmFuc2FjdGlvbiBpdCBwYXJ0aWNpcGF0ZWQgaW4sIHRoZSB0cmFuc2FjdGlvbiB3aWxsIGZhaWwuCiAgICBhY2Nlc3MoYWxsKSB2YXIgbWluaW11bVN0b3JhZ2VSZXNlcnZhdGlvbjogVUZpeDY0CgogICAgLy8gQW4gYWRtaW5pc3RyYXRvciByZXNvdXJjZSB0aGF0IGNhbiBjaGFuZ2UgdGhlIHBhcmFtZXRlcnMgb2YgdGhlIEZsb3dTdG9yYWdlRmVlcyBzbWFydCBjb250cmFjdC4KICAgIGFjY2VzcyhhbGwpIHJlc291cmNlIEFkbWluaXN0cmF0b3IgewoKICAgICAgICAvLyBDaGFuZ2VzIHRoZSBhbW91bnQgb2Ygc3RvcmFnZSBjYXBhY2l0eSBhbiBhY2NvdW50IGhhcyBwZXIgYWNjb3VudHMnIHJlc2VydmVkIHN0b3JhZ2UgRkxPVy4KICAgICAgICBhY2Nlc3MoYWxsKSBmdW4gc2V0U3RvcmFnZU1lZ2FCeXRlc1BlclJlc2VydmVkRkxPVyhfIHN0b3JhZ2VNZWdhQnl0ZXNQZXJSZXNlcnZlZEZMT1c6IFVGaXg2NCkgewogICAgICAgICAgICBpZiBGbG93U3RvcmFnZUZlZXMuc3RvcmFnZU1lZ2FCeXRlc1BlclJlc2VydmVkRkxPVyA9PSBzdG9yYWdlTWVnYUJ5dGVzUGVyUmVzZXJ2ZWRGTE9XIHsKICAgICAgICAgICAgICByZXR1cm4KICAgICAgICAgICAgfQogICAgICAgICAgICBGbG93U3RvcmFnZUZlZXMuc3RvcmFnZU1lZ2FCeXRlc1BlclJlc2VydmVkRkxPVyA9IHN0b3JhZ2VNZWdhQnl0ZXNQZXJSZXNlcnZlZEZMT1cKICAgICAgICAgICAgZW1pdCBTdG9yYWdlTWVnYUJ5dGVzUGVyUmVzZXJ2ZWRGTE9XQ2hhbmdlZChzdG9yYWdlTWVnYUJ5dGVzUGVyUmVzZXJ2ZWRGTE9XKQogICAgICAgIH0KCiAgICAgICAgLy8gQ2hhbmdlcyB0aGUgbWluaW11bSBhbW91bnQgb2YgRkxPVyBhbiBhY2NvdW50IGhhcyB0byBoYXZlIHJlc2VydmVkLgogICAgICAgIGFjY2VzcyhhbGwpIGZ1biBzZXRNaW5pbXVtU3RvcmFnZVJlc2VydmF0aW9uKF8gbWluaW11bVN0b3JhZ2VSZXNlcnZhdGlvbjogVUZpeDY0KSB7CiAgICAgICAgICAgIGlmIEZsb3dTdG9yYWdlRmVlcy5taW5pbXVtU3RvcmFnZVJlc2VydmF0aW9uID09IG1pbmltdW1TdG9yYWdlUmVzZXJ2YXRpb24gewogICAgICAgICAgICAgIHJldHVybgogICAgICAgICAgICB9CiAgICAgICAgICAgIEZsb3dTdG9yYWdlRmVlcy5taW5pbXVtU3RvcmFnZVJlc2VydmF0aW9uID0gbWluaW11bVN0b3JhZ2VSZXNlcnZhdGlvbgogICAgICAgICAgICBlbWl0IE1pbmltdW1TdG9yYWdlUmVzZXJ2YXRpb25DaGFuZ2VkKG1pbmltdW1TdG9yYWdlUmVzZXJ2YXRpb24pCiAgICAgICAgfQoKICAgICAgICBhY2Nlc3MoY29udHJhY3QpIGluaXQoKXt9CiAgICB9CgogICAgLy8vIGNhbGN1bGF0ZUFjY291bnRDYXBhY2l0eSByZXR1cm5zIHRoZSBzdG9yYWdlIGNhcGFjaXR5IG9mIGFuIGFjY291bnQKICAgIC8vLwogICAgLy8vIFJldHVybnMgbWVnYWJ5dGVzCiAgICAvLy8gSWYgdGhlIGFjY291bnQgaGFzIG5vIGRlZmF1bHQgYmFsYW5jZSBpdCBpcyBjb3VudGVkIGFzIGEgYmFsYW5jZSBvZiAwLjAgRkxPVwogICAgYWNjZXNzKGFsbCkgZnVuIGNhbGN1bGF0ZUFjY291bnRDYXBhY2l0eShfIGFjY291bnRBZGRyZXNzOiBBZGRyZXNzKTogVUZpeDY0IHsKICAgICAgICBsZXQgYmFsYW5jZSA9IGdldEFjY291bnQoYWNjb3VudEFkZHJlc3MpLmJhbGFuY2UKCiAgICAgICAgcmV0dXJuIHNlbGYuYWNjb3VudEJhbGFuY2VUb0FjY291bnRTdG9yYWdlQ2FwYWNpdHkoYmFsYW5jZSkKICAgIH0KCiAgICAvLy8gY2FsY3VsYXRlQWNjb3VudHNDYXBhY2l0eSByZXR1cm5zIHRoZSBzdG9yYWdlIGNhcGFjaXR5IG9mIGEgYmF0Y2ggb2YgYWNjb3VudHMKICAgIGFjY2VzcyhhbGwpIGZ1biBjYWxjdWxhdGVBY2NvdW50c0NhcGFjaXR5KF8gYWNjb3VudEFkZHJlc3NlczogW0FkZHJlc3NdKTogW1VGaXg2NF0gewogICAgICAgIGxldCBjYXBhY2l0aWVzOiBbVUZpeDY0XSA9IFtdCiAgICAgICAgZm9yIGFjY291bnRBZGRyZXNzIGluIGFjY291bnRBZGRyZXNzZXMgewogICAgICAgICAgICBsZXQgY2FwYWNpdHkgPSBzZWxmLmNhbGN1bGF0ZUFjY291bnRDYXBhY2l0eShhY2NvdW50QWRkcmVzcykKICAgICAgICAgICAgY2FwYWNpdGllcy5hcHBlbmQoY2FwYWNpdHkpCiAgICAgICAgfQogICAgICAgIHJldHVybiBjYXBhY2l0aWVzCiAgICB9CgogICAgLy8gZ2V0QWNjb3VudHNDYXBhY2l0eUZvclRyYW5zYWN0aW9uU3RvcmFnZUNoZWNrIHJldHVybnMgdGhlIHN0b3JhZ2UgY2FwYWNpdHkgb2YgYSBiYXRjaCBvZiBhY2NvdW50cwogICAgLy8gVGhpcyBpcyB1c2VkIHRvIGNoZWNrIGlmIGEgdHJhbnNhY3Rpb24gd2lsbCBmYWlsIGJlY2F1c2Ugb2YgYW55IGFjY291bnQgYmVpbmcgb3ZlciB0aGUgc3RvcmFnZSBjYXBhY2l0eQogICAgLy8gVGhlIHBheWVyIGlzIGFuIGV4Y2VwdGlvbiBhcyBpdHMgc3RvcmFnZSBjYXBhY2l0eSBpcyBkZXJpdmVkIGZyb20gaXRzIGJhbGFuY2UgbWludXMgdGhlIG1heGltdW0gcG9zc2libGUgdHJhbnNhY3Rpb24gZmVlcyAKICAgIC8vICh0cmFuc2FjdGlvbiBmZWVzIGlmIHRoZSBleGVjdXRpb24gZWZmb3J0IGlzIGF0IHRoZSBleGVjdXRpb24gZWZvcnQgbGltaXQsIGEuay5hLjogY29tcHV0YXRpb24gbGltaXQsIGEuay5hLjogZ2FzIGxpbWl0KQogICAgYWNjZXNzKGFsbCkgZnVuIGdldEFjY291bnRzQ2FwYWNpdHlGb3JUcmFuc2FjdGlvblN0b3JhZ2VDaGVjayhhY2NvdW50QWRkcmVzc2VzOiBbQWRkcmVzc10sIHBheWVyOiBBZGRyZXNzLCBtYXhUeEZlZXM6IFVGaXg2NCk6IFtVRml4NjRdIHsKICAgICAgICBsZXQgY2FwYWNpdGllczogW1VGaXg2NF0gPSBbXQogICAgICAgIGZvciBhY2NvdW50QWRkcmVzcyBpbiBhY2NvdW50QWRkcmVzc2VzIHsKICAgICAgICAgICAgdmFyIGJhbGFuY2UgPSBnZXRBY2NvdW50KGFjY291bnRBZGRyZXNzKS5iYWxhbmNlCgogICAgICAgICAgICBpZiBhY2NvdW50QWRkcmVzcyA9PSBwYXllciB7CiAgICAgICAgICAgICAgICAvLyBpZiB0aGUgYWNjb3VudCBpcyB0aGUgcGF5ZXIsIGRlZHVjdCB0aGUgbWF4aW11bSBwb3NzaWJsZSB0cmFuc2FjdGlvbiBmZWVzIGZyb20gdGhlIGJhbGFuY2UKICAgICAgICAgICAgICAgIGJhbGFuY2UgPSBiYWxhbmNlLnNhdHVyYXRpbmdTdWJ0cmFjdChtYXhUeEZlZXMpCiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGNhcGFjaXRpZXMuYXBwZW5kKHNlbGYuYWNjb3VudEJhbGFuY2VUb0FjY291bnRTdG9yYWdlQ2FwYWNpdHkoYmFsYW5jZSkpIAogICAgICAgIH0KICAgICAgICByZXR1cm4gY2FwYWNpdGllcwogICAgfQoKICAgIC8vIGFjY291bnRCYWxhbmNlVG9BY2NvdW50U3RvcmFnZUNhcGFjaXR5IHJldHVybnMgdGhlIHN0b3JhZ2UgY2FwYWNpdHkKICAgIC8vIGFuIGFjY291bnQgd291bGQgaGF2ZSB3aXRoIGdpdmVuIHRoZSBmbG93IGJhbGFuY2Ugb2YgdGhlIGFjY291bnQuCiAgICBhY2Nlc3MoYWxsKSB2aWV3IGZ1biBhY2NvdW50QmFsYW5jZVRvQWNjb3VudFN0b3JhZ2VDYXBhY2l0eShfIGJhbGFuY2U6IFVGaXg2NCk6IFVGaXg2NCB7CiAgICAgICAgLy8gZ2V0IGFkZHJlc3MgdG9rZW4gYmFsYW5jZQogICAgICAgIGlmIGJhbGFuY2UgPCBzZWxmLm1pbmltdW1TdG9yYWdlUmVzZXJ2YXRpb24gewogICAgICAgICAgICAvLyBpZiA8IHRoZW4gbWluaW11bSByZXR1cm4gMAogICAgICAgICAgICByZXR1cm4gMC4wCiAgICAgICAgfQoKICAgICAgICAvLyByZXR1cm4gYmFsYW5jZSBtdWx0aXBsaWVkIHdpdGggbWVnYWJ5dGVzIHBlciBmbG93IAogICAgICAgIHJldHVybiBzZWxmLmZsb3dUb1N0b3JhZ2VDYXBhY2l0eShiYWxhbmNlKQogICAgfQoKICAgIC8vIEFtb3VudCBpbiBGbG93IHRva2VucwogICAgLy8gUmV0dXJucyBtZWdhYnl0ZXMKICAgIGFjY2VzcyhhbGwpIHZpZXcgZnVuIGZsb3dUb1N0b3JhZ2VDYXBhY2l0eShfIGFtb3VudDogVUZpeDY0KTogVUZpeDY0IHsKICAgICAgICByZXR1cm4gYW1vdW50LnNhdHVyYXRpbmdNdWx0aXBseShGbG93U3RvcmFnZUZlZXMuc3RvcmFnZU1lZ2FCeXRlc1BlclJlc2VydmVkRkxPVykKICAgIH0KCiAgICAvLyBBbW91bnQgaW4gbWVnYWJ5dGVzCiAgICAvLyBSZXR1cm5zIEZsb3cgdG9rZW5zCiAgICBhY2Nlc3MoYWxsKSB2aWV3IGZ1biBzdG9yYWdlQ2FwYWNpdHlUb0Zsb3coXyBhbW91bnQ6IFVGaXg2NCk6IFVGaXg2NCB7CiAgICAgICAgaWYgRmxvd1N0b3JhZ2VGZWVzLnN0b3JhZ2VNZWdhQnl0ZXNQZXJSZXNlcnZlZEZMT1cgPT0gMC4wIHsKICAgICAgICAgICAgcmV0dXJuIDAuMAogICAgICAgIH0KICAgICAgICAvLyBwb3NzaWJsZSBsb3NzIG9mIHByZWNpc2lvbgogICAgICAgIC8vIHB1dHRpbmcgdGhlIHJlc3VsdCBiYWNrIGludG8gYGZsb3dUb1N0b3JhZ2VDYXBhY2l0eWAgbWlnaHQgbm90IHlpZWxkIHRoZSBzYW1lIHJlc3VsdAogICAgICAgIHJldHVybiBhbW91bnQgLyBGbG93U3RvcmFnZUZlZXMuc3RvcmFnZU1lZ2FCeXRlc1BlclJlc2VydmVkRkxPVwogICAgfQoKICAgIC8vIGNvbnZlcnRzIHN0b3JhZ2UgdXNlZCBmcm9tIFVJbnQ2NCBCeXRlcyB0byBVRml4NjQgTWVnYWJ5dGVzLgogICAgYWNjZXNzKGFsbCkgdmlldyBmdW4gY29udmVydFVJbnQ2NFN0b3JhZ2VCeXRlc1RvVUZpeDY0TWVnYWJ5dGVzKF8gc3RvcmFnZTogVUludDY0KTogVUZpeDY0IHsKICAgICAgICAvLyBzYWZlIGNvbnZlcnQgVUludDY0IHRvIFVGaXg2NCAod2l0aG91dCBvdmVyZmxvdykKICAgICAgICBsZXQgZiA9IFVGaXg2NChzdG9yYWdlICUgMTAwMDAwMDAwKSAqIDAuMDAwMDAwMDEgKyBVRml4NjQoc3RvcmFnZSAvIDEwMDAwMDAwMCkKICAgICAgICAvLyBkZWNpbWFsIHBvaW50IGNvcnJlY3Rpb24uIE1lZ2FieXRlcyB0byBieXRlcyBoYXZlIGEgY29udmVyc2lvbiBvZiAxMF4tNiB3aGlsZSBVRml4NjQgbWluaW11bSB2YWx1ZSBpcyAxMF4tOAogICAgICAgIGxldCBzdG9yYWdlTWIgPSBmLnNhdHVyYXRpbmdNdWx0aXBseSgxMDAuMCkKICAgICAgICByZXR1cm4gc3RvcmFnZU1iCiAgICB9CgogICAgLy8vIEdldHMgImF2YWlsYWJsZSIgYmFsYW5jZSBvZiBhbiBhY2NvdW50CiAgICAvLy8KICAgIC8vLyBUaGUgYXZhaWxhYmxlIGJhbGFuY2Ugb2YgYW4gYWNjb3VudCBpcyBpdHMgZGVmYXVsdCB0b2tlbiBiYWxhbmNlIG1pbnVzIHdoYXQgaXMgcmVzZXJ2ZWQgZm9yIHN0b3JhZ2UuCiAgICAvLy8gSWYgdGhlIGFjY291bnQgaGFzIG5vIGRlZmF1bHQgYmFsYW5jZSBpdCBpcyBjb3VudGVkIGFzIGEgYmFsYW5jZSBvZiAwLjAgRkxPVwogICAgYWNjZXNzKGFsbCkgZnVuIGRlZmF1bHRUb2tlbkF2YWlsYWJsZUJhbGFuY2UoXyBhY2NvdW50QWRkcmVzczogQWRkcmVzcyk6IFVGaXg2NCB7CiAgICAgICAgbGV0IGJhbGFuY2UgPSBnZXRBY2NvdW50KGFjY291bnRBZGRyZXNzKS5iYWxhbmNlCgogICAgICAgIC8vIGdldCBob3cgbXVjaCBzaG91bGQgYmUgcmVzZXJ2ZWQgZm9yIHN0b3JhZ2UKICAgICAgICBsZXQgcmVzZXJ2ZWQgPSBzZWxmLmRlZmF1bHRUb2tlblJlc2VydmVkQmFsYW5jZShhY2NvdW50QWRkcmVzcykKCiAgICAgICAgcmV0dXJuIGJhbGFuY2Uuc2F0dXJhdGluZ1N1YnRyYWN0KHJlc2VydmVkKQogICAgfQoKICAgIC8vLyBHZXRzICJyZXNlcnZlZCIgYmFsYW5jZSBvZiBhbiBhY2NvdW50CiAgICAvLy8KICAgIC8vLyBUaGUgcmVzZXJ2ZWQgYmFsYW5jZSBvZiBhbiBhY2NvdW50IGlzIGl0cyBzdG9yYWdlIHVzZWQgbXVsdGlwbGllZCBieSB0aGUgc3RvcmFnZSBjb3N0IHBlciBmbG93IHRva2VuLgogICAgLy8vIFRoZSByZXNlcnZlZCBiYWxhbmNlIGlzIGF0IGxlYXN0IHRoZSBtaW5pbXVtIHN0b3JhZ2UgcmVzZXJ2YXRpb24uCiAgICBhY2Nlc3MoYWxsKSB2aWV3IGZ1biBkZWZhdWx0VG9rZW5SZXNlcnZlZEJhbGFuY2UoXyBhY2NvdW50QWRkcmVzczogQWRkcmVzcyk6IFVGaXg2NCB7CiAgICAgICAgbGV0IGFjY3QgPSBnZXRBY2NvdW50KGFjY291bnRBZGRyZXNzKQogICAgICAgIHZhciByZXNlcnZlZCA9IHNlbGYuc3RvcmFnZUNhcGFjaXR5VG9GbG93KHNlbGYuY29udmVydFVJbnQ2NFN0b3JhZ2VCeXRlc1RvVUZpeDY0TWVnYWJ5dGVzKGFjY3Quc3RvcmFnZS51c2VkKSkKICAgICAgICAvLyBhdCBsZWFzdCBzZWxmLm1pbmltdW1TdG9yYWdlUmVzZXJ2YXRpb24gc2hvdWxkIGJlIHJlc2VydmVkCiAgICAgICAgaWYgcmVzZXJ2ZWQgPCBzZWxmLm1pbmltdW1TdG9yYWdlUmVzZXJ2YXRpb24gewogICAgICAgICAgICByZXNlcnZlZCA9IHNlbGYubWluaW11bVN0b3JhZ2VSZXNlcnZhdGlvbgogICAgICAgIH0KCiAgICAgICAgcmV0dXJuIHJlc2VydmVkCiAgICB9CgogICAgaW5pdCgpIHsKICAgICAgICBzZWxmLnN0b3JhZ2VNZWdhQnl0ZXNQZXJSZXNlcnZlZEZMT1cgPSAxLjAgLy8gMSBNYiBwZXIgMSBGbG93IHRva2VuCiAgICAgICAgc2VsZi5taW5pbXVtU3RvcmFnZVJlc2VydmF0aW9uID0gMC4wIC8vIG9yIDAga2Igb2YgbWluaW11bSBzdG9yYWdlIHJlc2VydmF0aW9uCgogICAgICAgIGxldCBhZG1pbiA8LSBjcmVhdGUgQWRtaW5pc3RyYXRvcigpCiAgICAgICAgc2VsZi5hY2NvdW50LnN0b3JhZ2Uuc2F2ZSg8LWFkbWluLCB0bzogL3N0b3JhZ2Uvc3RvcmFnZUZlZXNBZG1pbikKICAgIH0KfQog",
		"FlowTransactionScheduler": "aW1wb3J0IEZ1bmdpYmxlVG9rZW4gZnJvbSAweGYyMzNkY2VlODhmZTBhYmUKaW1wb3J0IEZsb3dUb2tlbiBmcm9tIDB4MTY1NDY1MzM5OTA0MGE2MQppbXBvcnQgRmxvd0ZlZXMgZnJvbSAweGY5MTllZTc3NDQ3Yjc0OTcKaW1wb3J0IEZsb3dTdG9yYWdlRmVlcyBmcm9tIDB4ZTQ2N2I5ZGQxMWZhMDBkZgppbXBvcnQgVmlld1Jlc29sdmVyIGZyb20gMHgxZDdlNTdhYTU1ODE3NDQ4CgovLy8gRmxvd1RyYW5zYWN0aW9uU2NoZWR1bGVyIGVuYWJsZXMgc21hcnQgY29udHJhY3RzIHRvIHNjaGVkdWxlIGF1dG9ub21vdXMgZXhlY3V0aW9uIGluIHRoZSBmdXR1cmUuCi8vLwovLy8gVGhpcyBjb250cmFjdCBpbXBsZW1lbnRzIEZMSVAgMzMwJ3Mgc2NoZWR1bGVkIHRyYW5zYWN0aW9uIHN5c3RlbSwgYWxsb3dpbmcgY29udHJhY3RzIHRvICJ3YWtlIHVwIiBhbmQgZXhlY3V0ZQovLy8gbG9naWMgYXQgcHJlZGVmaW5lZCB0aW1lcyB3aXRob3V0IGV4dGVybmFsIHRyaWdnZXJzLgovLy8KLy8vIFNjaGVkdWxlZCB0cmFuc2FjdGlvbnMgYXJlIHByaW9yaXRpemVkIChIaWdoL01lZGl1bS9Mb3cpIHdpdGggZGlmZmVyZW50IGV4ZWN1dGlvbiBndWFyYW50ZWVzIGFuZCBmZWUgbXVsdGlwbGllcnM6Ci8vLyAgIC0gSGlnaCBwcmlvcml0eSBndWFyYW50ZWVzIGZpcnN0LWJsb2NrIGV4ZWN1dGlvbiBhdCB0aGUgZXhhY3QgcmVxdWVzdGVkIHRpbWVzdGFtcCAoZmFpbHMgaWYgc2xvdCBpcyBmdWxsKS4KLy8vICAgLSBNZWRpdW0gcHJpb3JpdHkgcHJvdmlkZXMgYmVzdC1lZmZvcnQgc2NoZWR1bGluZywgc2hpZnRpbmcgdG8gdGhlIG5leHQgYXZhaWxhYmxlIHNsb3QgaWYgdGhlIHJlcXVlc3RlZCBvbmUgaXMgZnVsbC4KLy8vICAgLSBMb3cgcHJpb3JpdHkgc2hpZnRzIHRvIHRoZSBuZXh0IGF2YWlsYWJsZSBzbG90IGlmIHRoZSByZXF1ZXN0ZWQgb25lIGlzIGZ1bGwuCi8vLwovLy8gRWFjaCBwcmlvcml0eSBsZXZlbCBoYXMgaXRzIG93biBpbmRlcGVuZGVudCBlZmZvcnQgcG9vbCBwZXIgdGltZSBzbG90IHdpdGggbm8gc2hhcmVkIGNhcGFjaXR5IGJldHdlZW4gcHJpb3JpdGllcy4KLy8vIExvdyBwcmlvcml0eSB0cmFuc2FjdGlvbnMgYXJlIG5ldmVyIHJlc2NoZWR1bGVkIGJ5IGhpZ2hlciBwcmlvcml0eSB0cmFuc2FjdGlvbnMuCi8vLwovLy8gVGhlIHN5c3RlbSB1c2VzIHRpbWUgc2xvdHMgd2l0aCBleGVjdXRpb24gZWZmb3J0IGxpbWl0cyB0byBtYW5hZ2UgbmV0d29yayByZXNvdXJjZXMsCi8vLyBlbnN1cmluZyBwcmVkaWN0YWJsZSBwZXJmb3JtYW5jZSB3aGlsZSBlbmFibGluZyBub3ZlbCBhdXRvbm9tb3VzIGJsb2NrY2hhaW4gcGF0dGVybnMgbGlrZSByZWN1cnJpbmcKLy8vIHBheW1lbnRzLCBhdXRvbWF0ZWQgYXJiaXRyYWdlLCBhbmQgdGltZS1iYXNlZCBjb250cmFjdCBsb2dpYy4KYWNjZXNzKGFsbCkgY29udHJhY3QgRmxvd1RyYW5zYWN0aW9uU2NoZWR1bGVyIHsKCiAgICAvLy8gc2luZ2xldG9uIGluc3RhbmNlIHVzZWQgdG8gc3RvcmUgYWxsIHNjaGVkdWxlZCB0cmFuc2FjdGlvbiBkYXRhCiAgICAvLy8gYW5kIHJvdXRlIGFsbCBzY2hlZHVsZWQgdHJhbnNhY3Rpb24gZnVuY3Rpb25hbGl0eQogICAgYWNjZXNzKHNlbGYpIHZhciBzaGFyZWRTY2hlZHVsZXI6IENhcGFiaWxpdHk8YXV0aChDYW5jZWwpICZTaGFyZWRTY2hlZHVsZXI+CgogICAgLy8vIHN0b3JhZ2UgcGF0aCBmb3IgdGhlIHNpbmdsZXRvbiBzY2hlZHVsZXIgcmVzb3VyY2UKICAgIGFjY2VzcyhhbGwpIGxldCBzdG9yYWdlUGF0aDogU3RvcmFnZVBhdGgKCiAgICAvLy8gRW51bXMKCiAgICAvLy8gUHJpb3JpdHkKICAgIGFjY2VzcyhhbGwpIGVudW0gUHJpb3JpdHk6IFVJbnQ4IHsKICAgICAgICBhY2Nlc3MoYWxsKSBjYXNlIEhpZ2gKICAgICAgICBhY2Nlc3MoYWxsKSBjYXNlIE1lZGl1bQogICAgICAgIGFjY2VzcyhhbGwpIGNhc2UgTG93CiAgICB9CgogICAgLy8vIFN0YXR1cwogICAgYWNjZXNzKGFsbCkgZW51bSBTdGF0dXM6IFVJbnQ4IHsKICAgICAgICAvLy8gdW5rbm93biBzdGF0dXNlcyBhcmUgdXNlZCBmb3IgaGFuZGxpbmcgaGlzdG9yaWMgc2NoZWR1bGVkIHRyYW5zYWN0aW9ucyB3aXRoIG51bGwgc3RhdHVzZXMKICAgICAgICBhY2Nlc3MoYWxsKSBjYXNlIFVua25vd24KICAgICAgICAvLy8gbXV0YWJsZSBzdGF0dXMKICAgICAgICBhY2Nlc3MoYWxsKSBjYXNlIFNjaGVkdWxlZAogICAgICAgIC8vLyBmaW5hbGl6ZWQgc3RhdHVzZXMKICAgICAgICBhY2Nlc3MoYWxsKSBjYXNlIEV4ZWN1dGVkCiAgICAgICAgYWNjZXNzKGFsbCkgY2FzZSBDYW5jZWxlZAogICAgfQoKICAgIC8vLyBFdmVudHMKCiAgICAvLy8gRW1pdHRlZCB3aGVuIGEgdHJhbnNhY3Rpb24gaXMgc2NoZWR1bGVkCiAgICBhY2Nlc3MoYWxsKSBldmVudCBTY2hlZHVsZWQoCiAgICAgICAgaWQ6IFVJbnQ2NCwKICAgICAgICBwcmlvcml0eTogVUludDgsCiAgICAgICAgdGltZXN0YW1wOiBVRml4NjQsCiAgICAgICAgZXhlY3V0aW9uRWZmb3J0OiBVSW50NjQsCiAgICAgICAgZmVlczogVUZpeDY0LAogICAgICAgIHRyYW5zYWN0aW9uSGFuZGxlck93bmVyOiBBZGRyZXNzLAogICAgICAgIHRyYW5zYWN0aW9uSGFuZGxlclR5cGVJZGVudGlmaWVyOiBTdHJpbmcsCiAgICAgICAgdHJhbnNhY3Rpb25IYW5kbGVyVVVJRDogVUludDY0LAogICAgICAgIAogICAgICAgIC8vIFRoZSBwdWJsaWMgcGF0aCBvZiB0aGUgdHJhbnNhY3Rpb24gaGFuZGxlciB0aGF0IGNhbiBiZSB1c2VkIHRvIHJlc29sdmUgdmlld3MKICAgICAgICAvLyBESVNDTEFJTUVSOiBUaGVyZSBpcyBubyBndWFyYW50ZWUgdGhhdCB0aGUgcHVibGljIHBhdGggaXMgYWNjdXJhdGUKICAgICAgICB0cmFuc2FjdGlvbkhhbmRsZXJQdWJsaWNQYXRoOiBQdWJsaWNQYXRoPwogICAgKQoKICAgIC8vLyBFbWl0dGVkIHdoZW4gYSBzY2hlZHVsZWQgdHJhbnNhY3Rpb24ncyBzY2hlZHVsZWQgdGltZXN0YW1wIGlzIHJlYWNoZWQgYW5kIGl0IGlzIHJlYWR5IGZvciBleGVjdXRpb24KICAgIGFjY2VzcyhhbGwpIGV2ZW50IFBlbmRpbmdFeGVjdXRpb24oCiAgICAgICAgaWQ6IFVJbnQ2NCwKICAgICAgICBwcmlvcml0eTogVUludDgsCiAgICAgICAgZXhlY3V0aW9uRWZmb3J0OiBVSW50NjQsCiAgICAgICAgZmVlczogVUZpeDY0LAogICAgICAgIHRyYW5zYWN0aW9uSGFuZGxlck93bmVyOiBBZGRyZXNzLAogICAgICAgIHRyYW5zYWN0aW9uSGFuZGxlclR5cGVJZGVudGlmaWVyOiBTdHJpbmcKICAgICkKCiAgICAvLy8gRW1pdHRlZCB3aGVuIGEgc2NoZWR1bGVkIHRyYW5zYWN0aW9uIGlzIGV4ZWN1dGVkIGJ5IHRoZSBGVk0KICAgIGFjY2VzcyhhbGwpIGV2ZW50IEV4ZWN1dGVkKAogICAgICAgIGlkOiBVSW50NjQsCiAgICAgICAgcHJpb3JpdHk6IFVJbnQ4LAogICAgICAgIGV4ZWN1dGlvbkVmZm9ydDogVUludDY0LAogICAgICAgIHRyYW5zYWN0aW9uSGFuZGxlck93bmVyOiBBZGRyZXNzLAogICAgICAgIHRyYW5zYWN0aW9uSGFuZGxlclR5cGVJZGVudGlmaWVyOiBTdHJpbmcsCiAgICAgICAgdHJhbnNhY3Rpb25IYW5kbGVyVVVJRDogVUludDY0LAoKICAgICAgICAvLyBUaGUgcHVibGljIHBhdGggb2YgdGhlIHRyYW5zYWN0aW9uIGhhbmRsZXIgdGhhdCBjYW4gYmUgdXNlZCB0byByZXNvbHZlIHZpZXdzCiAgICAgICAgLy8gRElTQ0xBSU1FUjogVGhlcmUgaXMgbm8gZ3VhcmFudGVlIHRoYXQgdGhlIHB1YmxpYyBwYXRoIGlzIGFjY3VyYXRlCiAgICAgICAgdHJhbnNhY3Rpb25IYW5kbGVyUHVibGljUGF0aDogUHVibGljUGF0aD8KICAgICkKCiAgICAvLy8gRW1pdHRlZCB3aGVuIGEgc2NoZWR1bGVkIHRyYW5zYWN0aW9uIGlzIGNhbmNlbGVkIGJ5IHRoZSBjcmVhdG9yIG9mIHRoZSB0cmFuc2FjdGlvbgogICAgYWNjZXNzKGFsbCkgZXZlbnQgQ2FuY2VsZWQoCiAgICAgICAgaWQ6IFVJbnQ2NCwKICAgICAgICBwcmlvcml0eTogVUludDgsCiAgICAgICAgZmVlc1JldHVybmVkOiBVRml4NjQsCiAgICAgICAgZmVlc0RlZHVjdGVkOiBVRml4NjQsCiAgICAgICAgdHJhbnNhY3Rpb25IYW5kbGVyT3duZXI6IEFkZHJlc3MsCiAgICAgICAgdHJhbnNhY3Rpb25IYW5kbGVyVHlwZUlkZW50aWZpZXI6IFN0cmluZwogICAgKQoKICAgIC8vLyBFbWl0dGVkIHdoZW4gYSBjb2xsZWN0aW9uIGxpbWl0IGlzIHJlYWNoZWQKICAgIC8vLyBUaGUgbGltaXQgdGhhdCB3YXMgcmVhY2hlZCBpcyBub24tbmlsIGFuZCBpcyB0aGUgbGltaXQgdGhhdCB3YXMgcmVhY2hlZAogICAgLy8vIFRoZSBvdGhlciBsaW1pdCB0aGF0IHdhcyBub3QgcmVhY2hlZCBpcyBuaWwKICAgIGFjY2VzcyhhbGwpIGV2ZW50IENvbGxlY3Rpb25MaW1pdFJlYWNoZWQoCiAgICAgICAgY29sbGVjdGlvbkVmZm9ydExpbWl0OiBVSW50NjQ/LAogICAgICAgIGNvbGxlY3Rpb25UcmFuc2FjdGlvbnNMaW1pdDogSW50PwogICAgKQoKICAgIC8vLyBFbWl0dGVkIHdoZW4gdGhlIGxpbWl0IG9uIHRoZSBudW1iZXIgb2YgdHJhbnNhY3Rpb25zIHRoYXQgY2FuIGJlIHJlbW92ZWQgaW4gcHJvY2VzcygpIGlzIHJlYWNoZWQKICAgIGFjY2VzcyhhbGwpIGV2ZW50IFJlbW92YWxMaW1pdFJlYWNoZWQoKQoKICAgIC8vIEVtaXR0ZWQgd2hlbiBvbmUgb3IgbW9yZSBvZiB0aGUgY29uZmlndXJhdGlvbiBkZXRhaWxzIGZpZWxkcyBhcmUgdXBkYXRlZAogICAgLy8gRXZlbnQgbGlzdGVuZXJzIGNhbiBsaXN0ZW4gdG8gdGhpcyBhbmQgcXVlcnkgdGhlIG5ldyBjb25maWd1cmF0aW9uCiAgICAvLyBpZiB0aGV5IG5lZWQgdG8KICAgIGFjY2VzcyhhbGwpIGV2ZW50IENvbmZpZ1VwZGF0ZWQoKQoKICAgIC8vIEVtaXR0ZWQgd2hlbiBhIGNyaXRpY2FsIGlzc3VlIGlzIGVuY291bnRlcmVkCiAgICBhY2Nlc3MoYWxsKSBldmVudCBDcml0aWNhbElzc3VlKG1lc3NhZ2U6IFN0cmluZykKCiAgICAvLy8gRW50aXRsZW1lbnRzCiAgICBhY2Nlc3MoYWxsKSBlbnRpdGxlbWVudCBFeGVjdXRlCiAgICBhY2Nlc3MoYWxsKSBlbnRpdGxlbWVudCBQcm9jZXNzCiAgICBhY2Nlc3MoYWxsKSBlbnRpdGxlbWVudCBDYW5jZWwKICAgIGFjY2VzcyhhbGwpIGVudGl0bGVtZW50IFVwZGF0ZUNvbmZpZwoKICAgIC8vLyBJbnRlcmZhY2VzCgogICAgLy8vIFRyYW5zYWN0aW9uSGFuZGxlciBpcyBhbiBpbnRlcmZhY2UgdGhhdCBkZWZpbmVzIGEgc2luZ2xlIG1ldGhvZCBleGVjdXRlVHJhbnNhY3Rpb24gdGhhdCAKICAgIC8vLyBtdXN0IGJlIGltcGxlbWVudGVkIGJ5IHRoZSByZXNvdXJjZSB0aGF0IGNvbnRhaW5zIHRoZSBsb2dpYyB0byBiZSBleGVjdXRlZCBieSB0aGUgc2NoZWR1bGVkIHRyYW5zYWN0aW9uLgogICAgLy8vIEFuIGF1dGhvcml6ZWQgY2FwYWJpbGl0eSB0byB0aGlzIHJlc291cmNlIGlzIHByb3ZpZGVkIHdoZW4gc2NoZWR1bGluZyBhIHRyYW5zYWN0aW9uLgogICAgLy8vIFRoZSB0cmFuc2FjdGlvbiBzY2hlZHVsZXIgdXNlcyB0aGlzIGNhcGFiaWxpdHkgdG8gZXhlY3V0ZSB0aGUgdHJhbnNhY3Rpb24gd2hlbiBpdHMgc2NoZWR1bGVkIHRpbWVzdGFtcCBhcnJpdmVzLgogICAgYWNjZXNzKGFsbCkgcmVzb3VyY2UgaW50ZXJmYWNlIFRyYW5zYWN0aW9uSGFuZGxlcjogVmlld1Jlc29sdmVyLlJlc29sdmVyIHsKCiAgICAgICAgYWNjZXNzKGFsbCkgdmlldyBmdW4gZ2V0Vmlld3MoKTogW1R5cGVdIHsKICAgICAgICAgICAgcmV0dXJuIFtdCiAgICAgICAgfQoKICAgICAgICBhY2Nlc3MoYWxsKSBmdW4gcmVzb2x2ZVZpZXcoXyB2aWV3OiBUeXBlKTogQW55U3RydWN0PyB7CiAgICAgICAgICAgIHJldHVybiBuaWwKICAgICAgICB9CgogICAgICAgIC8vLyBFeGVjdXRlcyB0aGUgaW1wbGVtZW50ZWQgdHJhbnNhY3Rpb24gbG9naWMKICAgICAgICAvLy8KICAgICAgICAvLy8gQHBhcmFtIGlkOiBUaGUgaWQgb2YgdGhlIHNjaGVkdWxlZCB0cmFuc2FjdGlvbiAodGhpcyBjYW4gYmUgdXNlZnVsIGZvciBhbnkgaW50ZXJuYWwgdHJhY2tpbmcpCiAgICAgICAgLy8vIEBwYXJhbSBkYXRhOiBUaGUgZGF0YSB0aGF0IHdhcyBwYXNzZWQgd2hlbiB0aGUgdHJhbnNhY3Rpb24gd2FzIG9yaWdpbmFsbHkgc2NoZWR1bGVkCiAgICAgICAgLy8vIHRoYXQgbWF5IGJlIHVzZWZ1bCBmb3IgdGhlIGV4ZWN1dGlvbiBvZiB0aGUgdHJhbnNhY3Rpb24gbG9naWMKICAgICAgICBhY2Nlc3MoRXhlY3V0ZSkgZnVuIGV4ZWN1dGVUcmFuc2FjdGlvbihpZDogVUludDY0LCBkYXRhOiBBbnlTdHJ1Y3Q/KQogICAgfQoKICAgIC8vLyBTdHJ1Y3RzCgogICAgLy8vIFNjaGVkdWxlZFRyYW5zYWN0aW9uIGlzIHRoZSByZXNvdXJjZSB0aGF0IHRoZSB1c2VyIHJlY2VpdmVzIGFmdGVyIHNjaGVkdWxpbmcgYSB0cmFuc2FjdGlvbi4KICAgIC8vLyBJdCBhbGxvd3MgdGhlbSB0byBnZXQgdGhlIHN0YXR1cyBvZiB0aGVpciB0cmFuc2FjdGlvbiBhbmQgY2FuIGJlIHBhc3NlZCBiYWNrCiAgICAvLy8gdG8gdGhlIHNjaGVkdWxlciBjb250cmFjdCB0byBjYW5jZWwgdGhlIHRyYW5zYWN0aW9uIGlmIGl0IGhhcyBub3QgeWV0IGJlZW4gZXhlY3V0ZWQuIAogICAgYWNjZXNzKGFsbCkgcmVzb3VyY2UgU2NoZWR1bGVkVHJhbnNhY3Rpb24gewogICAgICAgIGFjY2VzcyhhbGwpIGxldCBpZDogVUludDY0CiAgICAgICAgYWNjZXNzKGFsbCkgbGV0IHRpbWVzdGFtcDogVUZpeDY0CiAgICAgICAgYWNjZXNzKGFsbCkgbGV0IGhhbmRsZXJUeXBlSWRlbnRpZmllcjogU3RyaW5nCgogICAgICAgIGFjY2VzcyhhbGwpIHZpZXcgZnVuIHN0YXR1cygpOiBTdGF0dXM/IHsKICAgICAgICAgICAgcmV0dXJuIEZsb3dUcmFuc2FjdGlvblNjaGVkdWxlci5zaGFyZWRTY2hlZHVsZXIuYm9ycm93KCkhLmdldFN0YXR1cyhpZDogc2VsZi5pZCkKICAgICAgICB9CgogICAgICAgIGluaXQoCiAgICAgICAgICAgIGlkOiBVSW50NjQsIAogICAgICAgICAgICB0aW1lc3RhbXA6IFVGaXg2NCwKICAgICAgICAgICAgaGFuZGxlclR5cGVJZGVudGlmaWVyOiBTdHJpbmcKICAgICAgICApIHsKICAgICAgICAgICAgc2VsZi5pZCA9IGlkCiAgICAgICAgICAgIHNlbGYudGltZXN0YW1wID0gdGltZXN0YW1wCiAgICAgICAgICAgIHNlbGYuaGFuZGxlclR5cGVJZGVudGlmaWVyID0gaGFuZGxlclR5cGVJZGVudGlmaWVyCiAgICAgICAgfQoKICAgICAgICAvLyBldmVudCBlbWl0dGVkIHdoZW4gdGhlIHJlc291cmNlIGlzIGRlc3Ryb3llZAogICAgICAgIGFjY2VzcyhhbGwpIGV2ZW50IFJlc291cmNlRGVzdHJveWVkKGlkOiBVSW50NjQgPSBzZWxmLmlkLCB0aW1lc3RhbXA6IFVGaXg2NCA9IHNlbGYudGltZXN0YW1wLCBoYW5kbGVyVHlwZUlkZW50aWZpZXI6IFN0cmluZyA9IHNlbGYuaGFuZGxlclR5cGVJZGVudGlmaWVyKQogICAgfQoKICAgIC8vLyBFc3RpbWF0ZWRTY2hlZHVsZWRUcmFuc2FjdGlvbiBjb250YWlucyBkYXRhIGZvciBlc3RpbWF0aW5nIHRyYW5zYWN0aW9uIHNjaGVkdWxpbmcuCiAgICBhY2Nlc3MoYWxsKSBzdHJ1Y3QgRXN0aW1hdGVkU2NoZWR1bGVkVHJhbnNhY3Rpb24gewogICAgICAgIC8vLyBmbG93RmVlIGlzIHRoZSBlc3RpbWF0ZWQgZmVlIGluIEZsb3cgZm9yIHRoZSB0cmFuc2FjdGlvbiB0byBiZSBzY2hlZHVsZWQKICAgICAgICBhY2Nlc3MoYWxsKSBsZXQgZmxvd0ZlZTogVUZpeDY0PwogICAgICAgIC8vLyB0aW1lc3RhbXAgaXMgZXN0aW1hdGVkIHRpbWVzdGFtcCB0aGF0IHRoZSB0cmFuc2FjdGlvbiB3aWxsIGJlIGV4ZWN1dGVkIGF0CiAgICAgICAgYWNjZXNzKGFsbCkgbGV0IHRpbWVzdGFtcDogVUZpeDY0PwogICAgICAgIC8vLyBlcnJvciBpcyBhbiBvcHRpb25hbCBlcnJvciBtZXNzYWdlIGlmIHRoZSB0cmFuc2FjdGlvbiBjYW5ub3QgYmUgc2NoZWR1bGVkCiAgICAgICAgYWNjZXNzKGFsbCkgbGV0IGVycm9yOiBTdHJpbmc/CgogICAgICAgIGFjY2Vzcyhjb250cmFjdCkgdmlldyBpbml0KGZsb3dGZWU6IFVGaXg2ND8sIHRpbWVzdGFtcDogVUZpeDY0PywgZXJyb3I6IFN0cmluZz8pIHsKICAgICAgICAgICAgc2VsZi5mbG93RmVlID0gZmxvd0ZlZQogICAgICAgICAgICBzZWxmLnRpbWVzdGFtcCA9IHRpbWVzdGFtcAogICAgICAgICAgICBzZWxmLmVycm9yID0gZXJyb3IKICAgICAgICB9CiAgICB9CgogICAgLy8vIFRyYW5zYWN0aW9uIGRhdGEgaXMgYSByZXByZXNlbnRhdGlvbiBvZiBhIHNjaGVkdWxlZCB0cmFuc2FjdGlvbgogICAgLy8vIEl0IGlzIHRoZSBzb3VyY2Ugb2YgdHJ1dGggZm9yIGFuIGluZGl2aWR1YWwgdHJhbnNhY3Rpb24gYW5kIHN0b3JlcyB0aGUKICAgIC8vLyBjYXBhYmlsaXR5IHRvIHRoZSBoYW5kbGVyIHRoYXQgY29udGFpbnMgdGhlIGxvZ2ljIHRoYXQgd2lsbCBiZSBleGVjdXRlZCBieSB0aGUgdHJhbnNhY3Rpb24uCiAgICBhY2Nlc3MoYWxsKSBzdHJ1Y3QgVHJhbnNhY3Rpb25EYXRhIHsKICAgICAgICBhY2Nlc3MoYWxsKSBsZXQgaWQ6IFVJbnQ2NAogICAgICAgIGFjY2VzcyhhbGwpIGxldCBwcmlvcml0eTogUHJpb3JpdHkKICAgICAgICBhY2Nlc3MoYWxsKSBsZXQgZXhlY3V0aW9uRWZmb3J0OiBVSW50NjQKICAgICAgICBhY2Nlc3MoYWxsKSB2YXIgc3RhdHVzOiBTdGF0dXMKCiAgICAgICAgLy8vIEZlZSBhbW91bnQgdG8gcGF5IGZvciB0aGUgdHJhbnNhY3Rpb24KICAgICAgICBhY2Nlc3MoYWxsKSBsZXQgZmVlczogVUZpeDY0CgogICAgICAgIC8vLyBUaGUgdGltZXN0YW1wIHRoYXQgdGhlIHRyYW5zYWN0aW9uIGlzIHNjaGVkdWxlZCBmb3IKICAgICAgICAvLy8gRm9yIG1lZGl1bSBwcmlvcml0eSB0cmFuc2FjdGlvbnMsIGl0IG1heSBiZSBkaWZmZXJlbnQgdGhhbiB0aGUgcmVxdWVzdGVkIHRpbWVzdGFtcAogICAgICAgIC8vLyBGb3IgbG93IHByaW9yaXR5IHRyYW5zYWN0aW9ucywgaXQgaXMgdGhlIHJlcXVlc3RlZCB0aW1lc3RhbXAsCiAgICAgICAgLy8vIGJ1dCB0aGUgdGltZXN0YW1wIHdoZXJlIHRoZSB0cmFuc2FjdGlvbiBpcyBhY3R1YWxseSBleGVjdXRlZCBtYXkgYmUgZGlmZmVyZW50CiAgICAgICAgYWNjZXNzKGFsbCkgdmFyIHNjaGVkdWxlZFRpbWVzdGFtcDogVUZpeDY0CgogICAgICAgIC8vLyBDYXBhYmlsaXR5IHRvIHRoZSBsb2dpYyB0aGF0IHRoZSB0cmFuc2FjdGlvbiB3aWxsIGV4ZWN1dGUKICAgICAgICBhY2Nlc3MoY29udHJhY3QpIGxldCBoYW5kbGVyOiBDYXBhYmlsaXR5PGF1dGgoRXhlY3V0ZSkgJntUcmFuc2FjdGlvbkhhbmRsZXJ9PgoKICAgICAgICAvLy8gVHlwZSBpZGVudGlmaWVyIG9mIHRoZSB0cmFuc2FjdGlvbiBoYW5kbGVyCiAgICAgICAgYWNjZXNzKGFsbCkgbGV0IGhhbmRsZXJUeXBlSWRlbnRpZmllcjogU3RyaW5nCiAgICAgICAgYWNjZXNzKGFsbCkgbGV0IGhhbmRsZXJBZGRyZXNzOiBBZGRyZXNzCgogICAgICAgIC8vLyBPcHRpb25hbCBkYXRhIHRoYXQgY2FuIGJlIHBhc3NlZCB0byB0aGUgaGFuZGxlcgogICAgICAgIC8vLyBUaGlzIGRhdGEgaXMgcHVibGljbHkgYWNjZXNzaWJsZSwgc28gbWFrZSBzdXJlIGl0IGRvZXMgbm90IGNvbnRhaW4KICAgICAgICAvLy8gYW55IHByaXZpbGVnZWQgaW5mb3JtYXRpb24gb3IgZnVuY3Rpb25hbGl0eQogICAgICAgIGFjY2Vzcyhjb250cmFjdCkgbGV0IGRhdGE6IEFueVN0cnVjdD8KCiAgICAgICAgYWNjZXNzKGNvbnRyYWN0KSBpbml0KAogICAgICAgICAgICBpZDogVUludDY0LAogICAgICAgICAgICBoYW5kbGVyOiBDYXBhYmlsaXR5PGF1dGgoRXhlY3V0ZSkgJntUcmFuc2FjdGlvbkhhbmRsZXJ9PiwKICAgICAgICAgICAgc2NoZWR1bGVkVGltZXN0YW1wOiBVRml4NjQsCiAgICAgICAgICAgIGRhdGE6IEFueVN0cnVjdD8sCiAgICAgICAgICAgIHByaW9yaXR5OiBQcmlvcml0eSwKICAgICAgICAgICAgZXhlY3V0aW9uRWZmb3J0OiBVSW50NjQsCiAgICAgICAgICAgIGZlZXM6IFVGaXg2NCwKICAgICAgICApIHsKICAgICAgICAgICAgc2VsZi5pZCA9IGlkCiAgICAgICAgICAgIHNlbGYuaGFuZGxlciA9IGhhbmRsZXIKICAgICAgICAgICAgc2VsZi5kYXRhID0gZGF0YQogICAgICAgICAgICBzZWxmLnByaW9yaXR5ID0gcHJpb3JpdHkKICAgICAgICAgICAgc2VsZi5leGVjdXRpb25FZmZvcnQgPSBleGVjdXRpb25FZmZvcnQKICAgICAgICAgICAgc2VsZi5mZWVzID0gZmVlcwogICAgICAgICAgICBzZWxmLnN0YXR1cyA9IFN0YXR1cy5TY2hlZHVsZWQKICAgICAgICAgICAgbGV0IGhhbmRsZXJSZWYgPSBoYW5kbGVyLmJvcnJvdygpCiAgICAgICAgICAgICAgICA/PyBwYW5pYygiSW52YWxpZCB0cmFuc2FjdGlvbiBoYW5kbGVyOiBDb3VsZCBub3QgYm9ycm93IGEgcmVmZXJlbmNlIHRvIHRoZSB0cmFuc2FjdGlvbiBoYW5kbGVyIikKICAgICAgICAgICAgc2VsZi5oYW5kbGVyQWRkcmVzcyA9IGhhbmRsZXIuYWRkcmVzcwogICAgICAgICAgICBzZWxmLmhhbmRsZXJUeXBlSWRlbnRpZmllciA9IGhhbmRsZXJSZWYuZ2V0VHlwZSgpLmlkZW50aWZpZXIKICAgICAgICAgICAgc2VsZi5zY2hlZHVsZWRUaW1lc3RhbXAgPSBzY2hlZHVsZWRUaW1lc3RhbXAKICAgICAgICB9CgogICAgICAgIC8vLyBzZXRTdGF0dXMgdXBkYXRlcyB0aGUgc3RhdHVzIG9mIHRoZSB0cmFuc2FjdGlvbi4KICAgICAgICAvLy8gSXQgcGFuaWNzIGlmIHRoZSB0cmFuc2FjdGlvbiBzdGF0dXMgaXMgYWxyZWFkeSBmaW5hbGl6ZWQuCiAgICAgICAgYWNjZXNzKGNvbnRyYWN0KSBmdW4gc2V0U3RhdHVzKG5ld1N0YXR1czogU3RhdHVzKSB7CiAgICAgICAgICAgIHByZSB7CiAgICAgICAgICAgICAgICBuZXdTdGF0dXMgIT0gU3RhdHVzLlVua25vd246ICJJbnZhbGlkIHN0YXR1czogTmV3IHN0YXR1cyBjYW5ub3QgYmUgVW5rbm93biIKICAgICAgICAgICAgICAgIHNlbGYuc3RhdHVzICE9IFN0YXR1cy5FeGVjdXRlZCAmJiBzZWxmLnN0YXR1cyAhPSBTdGF0dXMuQ2FuY2VsZWQ6CiAgICAgICAgICAgICAgICAgICAgIkludmFsaWQgc3RhdHVzOiBUcmFuc2FjdGlvbiB3aXRoIGlkIFwoc2VsZi5pZCkgaXMgYWxyZWFkeSBmaW5hbGl6ZWQiCiAgICAgICAgICAgICAgICBuZXdTdGF0dXMgPT0gU3RhdHVzLkV4ZWN1dGVkID8gc2VsZi5zdGF0dXMgPT0gU3RhdHVzLlNjaGVkdWxlZCA6IHRydWU6CiAgICAgICAgICAgICAgICAgICAgIkludmFsaWQgc3RhdHVzOiBUcmFuc2FjdGlvbiB3aXRoIGlkIFwoc2VsZi5pZCkgY2FuIG9ubHkgYmUgc2V0IGFzIEV4ZWN1dGVkIGlmIGl0IGlzIFNjaGVkdWxlZCIKICAgICAgICAgICAgICAgIG5ld1N0YXR1cyA9PSBTdGF0dXMuQ2FuY2VsZWQgPyBzZWxmLnN0YXR1cyA9PSBTdGF0dXMuU2NoZWR1bGVkIDogdHJ1ZToKICAgICAgICAgICAgICAgICAgICAiSW52YWxpZCBzdGF0dXM6IFRyYW5zYWN0aW9uIHdpdGggaWQgXChzZWxmLmlkKSBjYW4gb25seSBiZSBzZXQgYXMgQ2FuY2VsZWQgaWYgaXQgaXMgU2NoZWR1bGVkIgogICAgICAgICAgICB9CgogICAgICAgICAgICBzZWxmLnN0YXR1cyA9IG5ld1N0YXR1cwogICAgICAgIH0KCiAgICAgICAgLy8vIHNldFNjaGVkdWxlZFRpbWVzdGFtcCB1cGRhdGVzIHRoZSBzY2hlZHVsZWQgdGltZXN0YW1wIG9mIHRoZSB0cmFuc2FjdGlvbi4KICAgICAgICAvLy8gSXQgcGFuaWNzIGlmIHRoZSB0cmFuc2FjdGlvbiBzdGF0dXMgaXMgYWxyZWFkeSBmaW5hbGl6ZWQuCiAgICAgICAgYWNjZXNzKGNvbnRyYWN0KSBmdW4gc2V0U2NoZWR1bGVkVGltZXN0YW1wKG5ld1RpbWVzdGFtcDogVUZpeDY0KSB7CiAgICAgICAgICAgIHByZSB7CiAgICAgICAgICAgICAgICBzZWxmLnN0YXR1cyAhPSBTdGF0dXMuRXhlY3V0ZWQgJiYgc2VsZi5zdGF0dXMgIT0gU3RhdHVzLkNhbmNlbGVkOgogICAgICAgICAgICAgICAgICAgICJJbnZhbGlkIHN0YXR1czogVHJhbnNhY3Rpb24gd2l0aCBpZCBcKHNlbGYuaWQpIGlzIGFscmVhZHkgZmluYWxpemVkIgogICAgICAgICAgICB9CiAgICAgICAgICAgIHNlbGYuc2NoZWR1bGVkVGltZXN0YW1wID0gbmV3VGltZXN0YW1wCiAgICAgICAgfQoKICAgICAgICAvLy8gcGF5QW5kUmVmdW5kRmVlcyB3aXRoZHJhd3MgZmVlcyBmcm9tIHRoZSB0cmFuc2FjdGlvbiBiYXNlZCBvbiB0aGUgcmVmdW5kIG11bHRpcGxpZXIuCiAgICAgICAgLy8vIEl0IGRlcG9zaXRzIGFueSBsZWZ0b3ZlciBmZWVzIHRvIHRoZSBGbG93RmVlcyB2YXVsdCB0byBiZSB1c2VkIHRvIHBheSBub2RlIG9wZXJhdG9yIHJld2FyZHMKICAgICAgICAvLy8gbGlrZSBhbnkgb3RoZXIgdHJhbnNhY3Rpb24gb24gdGhlIEZsb3cgbmV0d29yay4KICAgICAgICBhY2Nlc3MoY29udHJhY3QpIGZ1biBwYXlBbmRSZWZ1bmRGZWVzKHJlZnVuZE11bHRpcGxpZXI6IFVGaXg2NCk6IEBGbG93VG9rZW4uVmF1bHQgewogICAgICAgICAgICBwcmUgewogICAgICAgICAgICAgICAgcmVmdW5kTXVsdGlwbGllciA+PSAwLjAgJiYgcmVmdW5kTXVsdGlwbGllciA8PSAxLjA6CiAgICAgICAgICAgICAgICAgICAgIkludmFsaWQgcmVmdW5kIG11bHRpcGxpZXI6IFRoZSBtdWx0aXBsaWVyIG11c3QgYmUgYmV0d2VlbiAwLjAgYW5kIDEuMCBidXQgZ290IFwocmVmdW5kTXVsdGlwbGllcikiCiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYgcmVmdW5kTXVsdGlwbGllciA9PSAwLjAgewogICAgICAgICAgICAgICAgRmxvd0ZlZXMuZGVwb3NpdChmcm9tOiA8LUZsb3dUcmFuc2FjdGlvblNjaGVkdWxlci53aXRoZHJhd0ZlZXMoYW1vdW50OiBzZWxmLmZlZXMpKQogICAgICAgICAgICAgICAgcmV0dXJuIDwtRmxvd1Rva2VuLmNyZWF0ZUVtcHR5VmF1bHQodmF1bHRUeXBlOiBUeXBlPEBGbG93VG9rZW4uVmF1bHQ+KCkpCiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICBsZXQgYW1vdW50VG9SZXR1cm4gPSBzZWxmLmZlZXMgKiByZWZ1bmRNdWx0aXBsaWVyCiAgICAgICAgICAgICAgICBsZXQgYW1vdW50VG9LZWVwID0gc2VsZi5mZWVzIC0gYW1vdW50VG9SZXR1cm4KICAgICAgICAgICAgICAgIGxldCBmZWVzVG9SZXR1cm4gPC0gRmxvd1RyYW5zYWN0aW9uU2NoZWR1bGVyLndpdGhkcmF3RmVlcyhhbW91bnQ6IGFtb3VudFRvUmV0dXJuKQogICAgICAgICAgICAgICAgRmxvd0ZlZXMuZGVwb3NpdChmcm9tOiA8LUZsb3dUcmFuc2FjdGlvblNjaGVkdWxlci53aXRoZHJhd0ZlZXMoYW1vdW50OiBhbW91bnRUb0tlZXApKQogICAgICAgICAgICAgICAgcmV0dXJuIDwtZmVlc1RvUmV0dXJuCiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIC8vLyBnZXREYXRhIGNvcGllcyBhbmQgcmV0dXJucyB0aGUgZGF0YSBmaWVsZAogICAgICAgIGFjY2VzcyhhbGwpIHZpZXcgZnVuIGdldERhdGEoKTogQW55U3RydWN0PyB7CiAgICAgICAgICAgIHJldHVybiBzZWxmLmRhdGEKICAgICAgICB9CgogICAgICAgIC8vLyBib3Jyb3dIYW5kbGVyIHJldHVybnMgYW4gdW4tZW50aXRsZWQgcmVmZXJlbmNlIHRvIHRoZSB0cmFuc2FjdGlvbiBoYW5kbGVyCiAgICAgICAgLy8vIFRoaXMgYWxsb3dzIHVzZXJzIHRvIHF1ZXJ5IG1ldGFkYXRhIHZpZXdzIGFib3V0IHRoZSBoYW5kbGVyCiAgICAgICAgLy8vIEByZXR1cm46IEFuIHVuLWVudGl0bGVkIHJlZmVyZW5jZSB0byB0aGUgdHJhbnNhY3Rpb24gaGFuZGxlcgogICAgICAgIGFjY2VzcyhhbGwpIHZpZXcgZnVuIGJvcnJvd0hhbmRsZXIoKTogJntUcmFuc2FjdGlvbkhhbmRsZXJ9IHsKICAgICAgICAgICAgcmV0dXJuIHNlbGYuaGFuZGxlci5ib3Jyb3coKSBhcz8gJntUcmFuc2FjdGlvbkhhbmRsZXJ9CiAgICAgICAgICAgICAgICA/PyBwYW5pYygiSW52YWxpZCB0cmFuc2FjdGlvbiBoYW5kbGVyOiBDb3VsZCBub3QgYm9ycm93IGEgcmVmZXJlbmNlIHRvIHRoZSB0cmFuc2FjdGlvbiBoYW5kbGVyIikKICAgICAgICB9CiAgICB9CgogICAgLy8vIFN0cnVjdCBpbnRlcmZhY2UgcmVwcmVzZW50aW5nIGFsbCB0aGUgYmFzZSBjb25maWd1cmF0aW9uIGRldGFpbHMgaW4gdGhlIFNjaGVkdWxlciBjb250cmFjdAogICAgLy8vIHRoYXQgaXMgdXNlZCBmb3IgZ292ZXJuaW5nIHRoZSBwcm90b2NvbAogICAgLy8vIFRoaXMgaXMgYW4gaW50ZXJmYWNlIHRvIGFsbG93IGZvciB0aGUgY29uZmlndXJhdGlvbiBkZXRhaWxzIHRvIGJlIHVwZGF0ZWQgaW4gdGhlIGZ1dHVyZQogICAgYWNjZXNzKGFsbCkgc3RydWN0IGludGVyZmFjZSBTY2hlZHVsZXJDb25maWcgewoKICAgICAgICAvLy8gbWF4aW11bSBlZmZvcnQgdGhhdCBjYW4gYmUgdXNlZCBmb3IgYW55IHRyYW5zYWN0aW9uCiAgICAgICAgYWNjZXNzKGFsbCkgdmFyIG1heGltdW1JbmRpdmlkdWFsRWZmb3J0OiBVSW50NjQKCiAgICAgICAgLy8vIG1pbmltdW0gZXhlY3V0aW9uIGVmZm9ydCBpcyB0aGUgbWluaW11bSBlZmZvcnQgdGhhdCBjYW4gYmUgCiAgICAgICAgLy8vIHVzZWQgZm9yIGFueSB0cmFuc2FjdGlvbgogICAgICAgIGFjY2VzcyhhbGwpIHZhciBtaW5pbXVtRXhlY3V0aW9uRWZmb3J0OiBVSW50NjQKCiAgICAgICAgLy8vIHNsb3QgdG90YWwgZWZmb3J0IGxpbWl0IGlzIHRoZSBtYXhpbXVtIGVmZm9ydCB0aGF0IGNhbiBiZSAKICAgICAgICAvLy8gY3VtdWxhdGl2ZWx5IGFsbG9jYXRlZCB0byBvbmUgdGltZXNsb3QgYnkgYWxsIHByaW9yaXRpZXMKICAgICAgICBhY2Nlc3MoYWxsKSB2YXIgc2xvdFRvdGFsRWZmb3J0TGltaXQ6IFVJbnQ2NAoKICAgICAgICAvLy8gc2xvdCBzaGFyZWQgZWZmb3J0IGxpbWl0IGlzIHRoZSBtYXhpbXVtIGVmZm9ydCAKICAgICAgICAvLy8gdGhhdCBjYW4gYmUgYWxsb2NhdGVkIHRvIGhpZ2ggYW5kIG1lZGl1bSBwcmlvcml0eSAKICAgICAgICAvLy8gdHJhbnNhY3Rpb25zIGNvbWJpbmVkIGFmdGVyIHRoZWlyIGV4Y2x1c2l2ZSBlZmZvcnQgcmVzZXJ2ZXMgaGF2ZSBiZWVuIGZpbGxlZAogICAgICAgIGFjY2VzcyhhbGwpIHZhciBzbG90U2hhcmVkRWZmb3J0TGltaXQ6IFVJbnQ2NAoKICAgICAgICAvLy8gcHJpb3JpdHkgZWZmb3J0IHJlc2VydmUgaXMgdGhlIGFtb3VudCBvZiBlZmZvcnQgdGhhdCBpcyAKICAgICAgICAvLy8gcmVzZXJ2ZWQgZXhjbHVzaXZlbHkgZm9yIGVhY2ggcHJpb3JpdHkKICAgICAgICBhY2Nlc3MoYWxsKSB2YXIgcHJpb3JpdHlFZmZvcnRSZXNlcnZlOiB7UHJpb3JpdHk6IFVJbnQ2NH0KCiAgICAgICAgLy8vIHByaW9yaXR5IGVmZm9ydCBsaW1pdCBpcyB0aGUgbWF4aW11bSBjdW11bGF0aXZlIGVmZm9ydCBwZXIgcHJpb3JpdHkgaW4gYSB0aW1lc2xvdAogICAgICAgIGFjY2VzcyhhbGwpIHZhciBwcmlvcml0eUVmZm9ydExpbWl0OiB7UHJpb3JpdHk6IFVJbnQ2NH0KCiAgICAgICAgLy8vIG1heCBkYXRhIHNpemUgaXMgdGhlIG1heGltdW0gZGF0YSBzaXplIHRoYXQgY2FuIGJlIHN0b3JlZCBmb3IgYSB0cmFuc2FjdGlvbgogICAgICAgIGFjY2VzcyhhbGwpIHZhciBtYXhEYXRhU2l6ZU1COiBVRml4NjQKCiAgICAgICAgLy8vIHByaW9yaXR5IGZlZSBtdWx0aXBsaWVycyBhcmUgdmFsdWVzIHdlIHVzZSB0byBjYWxjdWxhdGUgdGhlIGFkZGVkIAogICAgICAgIC8vLyBwcm9jZXNzaW5nIGZlZSBmb3IgZWFjaCBwcmlvcml0eQogICAgICAgIGFjY2VzcyhhbGwpIHZhciBwcmlvcml0eUZlZU11bHRpcGxpZXJzOiB7UHJpb3JpdHk6IFVGaXg2NH0KCiAgICAgICAgLy8vIHJlZnVuZCBtdWx0aXBsaWVyIGlzIHRoZSBwb3J0aW9uIG9mIHRoZSBmZWVzIHRoYXQgYXJlIHJlZnVuZGVkIHdoZW4gYW55IHRyYW5zYWN0aW9uIGlzIGNhbmNlbGxlZAogICAgICAgIGFjY2VzcyhhbGwpIHZhciByZWZ1bmRNdWx0aXBsaWVyOiBVRml4NjQKCiAgICAgICAgLy8vIGNhbmNlbGVkVHJhbnNhY3Rpb25zTGltaXQgaXMgdGhlIG1heGltdW0gbnVtYmVyIG9mIGNhbmNlbGVkIHRyYW5zYWN0aW9ucwogICAgICAgIC8vLyB0byBrZWVwIGluIHRoZSBjYW5jZWxlZFRyYW5zYWN0aW9ucyBhcnJheQogICAgICAgIGFjY2VzcyhhbGwpIHZhciBjYW5jZWxlZFRyYW5zYWN0aW9uc0xpbWl0OiBVSW50CgogICAgICAgIC8vLyBjb2xsZWN0aW9uRWZmb3J0TGltaXQgaXMgdGhlIG1heGltdW0gZWZmb3J0IHRoYXQgY2FuIGJlIHVzZWQgZm9yIGFsbCB0cmFuc2FjdGlvbnMgaW4gYSBjb2xsZWN0aW9uCiAgICAgICAgYWNjZXNzKGFsbCkgdmFyIGNvbGxlY3Rpb25FZmZvcnRMaW1pdDogVUludDY0CgogICAgICAgIC8vLyBjb2xsZWN0aW9uVHJhbnNhY3Rpb25zTGltaXQgaXMgdGhlIG1heGltdW0gbnVtYmVyIG9mIHRyYW5zYWN0aW9ucyB0aGF0IGNhbiBiZSBwcm9jZXNzZWQgaW4gYSBjb2xsZWN0aW9uCiAgICAgICAgYWNjZXNzKGFsbCkgdmFyIGNvbGxlY3Rpb25UcmFuc2FjdGlvbnNMaW1pdDogSW50CgogICAgICAgIGFjY2VzcyhhbGwpIGluaXQoCiAgICAgICAgICAgIG1heGltdW1JbmRpdmlkdWFsRWZmb3J0OiBVSW50NjQsCiAgICAgICAgICAgIG1pbmltdW1FeGVjdXRpb25FZmZvcnQ6IFVJbnQ2NCwKICAgICAgICAgICAgcHJpb3JpdHlFZmZvcnRMaW1pdDoge1ByaW9yaXR5OiBVSW50NjR9LAogICAgICAgICAgICBtYXhEYXRhU2l6ZU1COiBVRml4NjQsCiAgICAgICAgICAgIHByaW9yaXR5RmVlTXVsdGlwbGllcnM6IHtQcmlvcml0eTogVUZpeDY0fSwKICAgICAgICAgICAgcmVmdW5kTXVsdGlwbGllcjogVUZpeDY0LAogICAgICAgICAgICBjYW5jZWxlZFRyYW5zYWN0aW9uc0xpbWl0OiBVSW50LAogICAgICAgICAgICBjb2xsZWN0aW9uRWZmb3J0TGltaXQ6IFVJbnQ2NCwKICAgICAgICAgICAgY29sbGVjdGlvblRyYW5zYWN0aW9uc0xpbWl0OiBJbnQsCiAgICAgICAgICAgIHR4UmVtb3ZhbExpbWl0OiBVSW50CiAgICAgICAgKSB7CiAgICAgICAgICAgIHBvc3QgewogICAgICAgICAgICAgICAgc2VsZi5yZWZ1bmRNdWx0aXBsaWVyID49IDAuMCAmJiBzZWxmLnJlZnVuZE11bHRpcGxpZXIgPD0gMS4wOgogICAgICAgICAgICAgICAgICAgICJJbnZhbGlkIHJlZnVuZCBtdWx0aXBsaWVyOiBUaGUgbXVsdGlwbGllciBtdXN0IGJlIGJldHdlZW4gMC4wIGFuZCAxLjAgYnV0IGdvdCBcKHJlZnVuZE11bHRpcGxpZXIpIgogICAgICAgICAgICAgICAgc2VsZi5wcmlvcml0eUZlZU11bHRpcGxpZXJzW1ByaW9yaXR5Lkxvd10hID49IDEuMDoKICAgICAgICAgICAgICAgICAgICAiSW52YWxpZCBwcmlvcml0eSBmZWUgbXVsdGlwbGllcjogTG93IHByaW9yaXR5IG11bHRpcGxpZXIgbXVzdCBiZSBncmVhdGVyIHRoYW4gb3IgZXF1YWwgdG8gMS4wIGJ1dCBnb3QgXChzZWxmLnByaW9yaXR5RmVlTXVsdGlwbGllcnNbUHJpb3JpdHkuTG93XSEpIgogICAgICAgICAgICAgICAgc2VsZi5wcmlvcml0eUZlZU11bHRpcGxpZXJzW1ByaW9yaXR5Lk1lZGl1bV0hID4gc2VsZi5wcmlvcml0eUZlZU11bHRpcGxpZXJzW1ByaW9yaXR5Lkxvd10hOgogICAgICAgICAgICAgICAgICAgICJJbnZhbGlkIHByaW9yaXR5IGZlZSBtdWx0aXBsaWVyOiBNZWRpdW0gcHJpb3JpdHkgbXVsdGlwbGllciBtdXN0IGJlIGdyZWF0ZXIgdGhhbiBvciBlcXVhbCB0byBcKHByaW9yaXR5RmVlTXVsdGlwbGllcnNbUHJpb3JpdHkuTG93XSEpIGJ1dCBnb3QgXChwcmlvcml0eUZlZU11bHRpcGxpZXJzW1ByaW9yaXR5Lk1lZGl1bV0hKSIKICAgICAgICAgICAgICAgIHNlbGYucHJpb3JpdHlGZWVNdWx0aXBsaWVyc1tQcmlvcml0eS5IaWdoXSEgPiBzZWxmLnByaW9yaXR5RmVlTXVsdGlwbGllcnNbUHJpb3JpdHkuTWVkaXVtXSE6CiAgICAgICAgICAgICAgICAgICAgIkludmFsaWQgcHJpb3JpdHkgZmVlIG11bHRpcGxpZXI6IEhpZ2ggcHJpb3JpdHkgbXVsdGlwbGllciBtdXN0IGJlIGdyZWF0ZXIgdGhhbiBvciBlcXVhbCB0byBcKHByaW9yaXR5RmVlTXVsdGlwbGllcnNbUHJpb3JpdHkuTWVkaXVtXSEpIGJ1dCBnb3QgXChwcmlvcml0eUZlZU11bHRpcGxpZXJzW1ByaW9yaXR5LkhpZ2hdISkiCiAgICAgICAgICAgICAgICBzZWxmLnByaW9yaXR5RWZmb3J0TGltaXRbUHJpb3JpdHkuTG93XSEgPiAwOgogICAgICAgICAgICAgICAgICAgICJJbnZhbGlkIHByaW9yaXR5IGVmZm9ydCBsaW1pdDogTG93IHByaW9yaXR5IGVmZm9ydCBsaW1pdCBtdXN0IGJlIGdyZWF0ZXIgdGhhbiAwIgogICAgICAgICAgICAgICAgc2VsZi5wcmlvcml0eUVmZm9ydExpbWl0W1ByaW9yaXR5Lk1lZGl1bV0hID4gc2VsZi5wcmlvcml0eUVmZm9ydExpbWl0W1ByaW9yaXR5Lkxvd10hOgogICAgICAgICAgICAgICAgICAgICJJbnZhbGlkIHByaW9yaXR5IGVmZm9ydCBsaW1pdDogTWVkaXVtIHByaW9yaXR5IGVmZm9ydCBsaW1pdCBtdXN0IGJlIGdyZWF0ZXIgdGhhbiB0aGUgbG93IHByaW9yaXR5IGVmZm9ydCBsaW1pdCBvZiBcKHByaW9yaXR5RWZmb3J0TGltaXRbUHJpb3JpdHkuTG93XSEpIgogICAgICAgICAgICAgICAgc2VsZi5wcmlvcml0eUVmZm9ydExpbWl0W1ByaW9yaXR5LkhpZ2hdISA+IHNlbGYucHJpb3JpdHlFZmZvcnRMaW1pdFtQcmlvcml0eS5NZWRpdW1dIToKICAgICAgICAgICAgICAgICAgICAiSW52YWxpZCBwcmlvcml0eSBlZmZvcnQgbGltaXQ6IEhpZ2ggcHJpb3JpdHkgZWZmb3J0IGxpbWl0IG11c3QgYmUgZ3JlYXRlciB0aGFuIHRoZSBtZWRpdW0gcHJpb3JpdHkgZWZmb3J0IGxpbWl0IG9mIFwocHJpb3JpdHlFZmZvcnRMaW1pdFtQcmlvcml0eS5NZWRpdW1dISkiCiAgICAgICAgICAgICAgICBzZWxmLmNvbGxlY3Rpb25UcmFuc2FjdGlvbnNMaW1pdCA+PSAwOgogICAgICAgICAgICAgICAgICAgICJJbnZhbGlkIGNvbGxlY3Rpb24gdHJhbnNhY3Rpb25zIGxpbWl0OiBDb2xsZWN0aW9uIHRyYW5zYWN0aW9ucyBsaW1pdCBtdXN0IGJlIGdyZWF0ZXIgdGhhbiBvciBlcXVhbCB0byAwIGJ1dCBnb3QgXChjb2xsZWN0aW9uVHJhbnNhY3Rpb25zTGltaXQpIgogICAgICAgICAgICAgICAgc2VsZi5jYW5jZWxlZFRyYW5zYWN0aW9uc0xpbWl0ID49IDE6CiAgICAgICAgICAgICAgICAgICAgIkludmFsaWQgY2FuY2VsZWQgdHJhbnNhY3Rpb25zIGxpbWl0OiBDYW5jZWxlZCB0cmFuc2FjdGlvbnMgbGltaXQgbXVzdCBiZSBncmVhdGVyIHRoYW4gb3IgZXF1YWwgdG8gMSBidXQgZ290IFwoY2FuY2VsZWRUcmFuc2FjdGlvbnNMaW1pdCkiCiAgICAgICAgICAgICAgICBzZWxmLmNvbGxlY3Rpb25FZmZvcnRMaW1pdCA+IHNlbGYuc2xvdFRvdGFsRWZmb3J0TGltaXQ6CiAgICAgICAgICAgICAgICAgICAgIkludmFsaWQgY29sbGVjdGlvbiBlZmZvcnQgbGltaXQ6IENvbGxlY3Rpb24gZWZmb3J0IGxpbWl0IG11c3QgYmUgZ3JlYXRlciB0aGFuIFwoc2VsZi5zbG90VG90YWxFZmZvcnRMaW1pdCkgYnV0IGdvdCBcKHNlbGYuY29sbGVjdGlvbkVmZm9ydExpbWl0KSIKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgYWNjZXNzKGFsbCkgdmlldyBmdW4gZ2V0VHhSZW1vdmFsTGltaXQoKTogVUludAogICAgfQoKICAgIC8vLyBDb25jcmV0ZSBpbXBsZW1lbnRhdGlvbiBvZiB0aGUgU2NoZWR1bGVyQ29uZmlnIGludGVyZmFjZQogICAgLy8vIFRoaXMgc3RydWN0IGlzIHVzZWQgdG8gc3RvcmUgdGhlIGNvbmZpZ3VyYXRpb24gZGV0YWlscyBpbiB0aGUgU2NoZWR1bGVyIGNvbnRyYWN0CiAgICBhY2Nlc3MoYWxsKSBzdHJ1Y3QgQ29uZmlnOiBTY2hlZHVsZXJDb25maWcgewogICAgICAgIGFjY2VzcyhhbGwpIHZhciBtYXhpbXVtSW5kaXZpZHVhbEVmZm9ydDogVUludDY0CiAgICAgICAgYWNjZXNzKGFsbCkgdmFyIG1pbmltdW1FeGVjdXRpb25FZmZvcnQ6IFVJbnQ2NAogICAgICAgIGFjY2VzcyhhbGwpIHZhciBzbG90VG90YWxFZmZvcnRMaW1pdDogVUludDY0CiAgICAgICAgYWNjZXNzKGFsbCkgdmFyIHNsb3RTaGFyZWRFZmZvcnRMaW1pdDogVUludDY0CiAgICAgICAgYWNjZXNzKGFsbCkgdmFyIHByaW9yaXR5RWZmb3J0UmVzZXJ2ZToge1ByaW9yaXR5OiBVSW50NjR9CiAgICAgICAgYWNjZXNzKGFsbCkgdmFyIHByaW9yaXR5RWZmb3J0TGltaXQ6IHtQcmlvcml0eTogVUludDY0fQogICAgICAgIGFjY2VzcyhhbGwpIHZhciBtYXhEYXRhU2l6ZU1COiBVRml4NjQKICAgICAgICBhY2Nlc3MoYWxsKSB2YXIgcHJpb3JpdHlGZWVNdWx0aXBsaWVyczoge1ByaW9yaXR5OiBVRml4NjR9CiAgICAgICAgYWNjZXNzKGFsbCkgdmFyIHJlZnVuZE11bHRpcGxpZXI6IFVGaXg2NAogICAgICAgIGFjY2VzcyhhbGwpIHZhciBjYW5jZWxlZFRyYW5zYWN0aW9uc0xpbWl0OiBVSW50CiAgICAgICAgYWNjZXNzKGFsbCkgdmFyIGNvbGxlY3Rpb25FZmZvcnRMaW1pdDogVUludDY0CiAgICAgICAgYWNjZXNzKGFsbCkgdmFyIGNvbGxlY3Rpb25UcmFuc2FjdGlvbnNMaW1pdDogSW50CgogICAgICAgIGFjY2VzcyhhbGwpIGluaXQoCiAgICAgICAgICAgIG1heGltdW1JbmRpdmlkdWFsRWZmb3J0OiBVSW50NjQsCiAgICAgICAgICAgIG1pbmltdW1FeGVjdXRpb25FZmZvcnQ6IFVJbnQ2NCwKICAgICAgICAgICAgcHJpb3JpdHlFZmZvcnRMaW1pdDoge1ByaW9yaXR5OiBVSW50NjR9LAogICAgICAgICAgICBtYXhEYXRhU2l6ZU1COiBVRml4NjQsCiAgICAgICAgICAgIHByaW9yaXR5RmVlTXVsdGlwbGllcnM6IHtQcmlvcml0eTogVUZpeDY0fSwKICAgICAgICAgICAgcmVmdW5kTXVsdGlwbGllcjogVUZpeDY0LAogICAgICAgICAgICBjYW5jZWxlZFRyYW5zYWN0aW9uc0xpbWl0OiBVSW50LAogICAgICAgICAgICBjb2xsZWN0aW9uRWZmb3J0TGltaXQ6IFVJbnQ2NCwKICAgICAgICAgICAgY29sbGVjdGlvblRyYW5zYWN0aW9uc0xpbWl0OiBJbnQsCiAgICAgICAgICAgIHR4UmVtb3ZhbExpbWl0OiBVSW50CiAgICAgICAgKSB7CiAgICAgICAgICAgIHNlbGYubWF4aW11bUluZGl2aWR1YWxFZmZvcnQgPSBtYXhpbXVtSW5kaXZpZHVhbEVmZm9ydAogICAgICAgICAgICBzZWxmLm1pbmltdW1FeGVjdXRpb25FZmZvcnQgPSBtaW5pbXVtRXhlY3V0aW9uRWZmb3J0CiAgICAgICAgICAgIHNlbGYucHJpb3JpdHlFZmZvcnRMaW1pdCA9IHByaW9yaXR5RWZmb3J0TGltaXQKICAgICAgICAgICAgLy8gTGVnYWN5IGZpZWxkcyBrZXB0IGZvciBzdG9yYWdlIGNvbXBhdGliaWxpdHk7IG5vdCB1c2VkIGJ5IHNjaGVkdWxpbmcgbG9naWMKICAgICAgICAgICAgc2VsZi5zbG90VG90YWxFZmZvcnRMaW1pdCA9IHByaW9yaXR5RWZmb3J0TGltaXRbUHJpb3JpdHkuSGlnaF0hICsgcHJpb3JpdHlFZmZvcnRMaW1pdFtQcmlvcml0eS5NZWRpdW1dISArIHByaW9yaXR5RWZmb3J0TGltaXRbUHJpb3JpdHkuTG93XSEKICAgICAgICAgICAgc2VsZi5zbG90U2hhcmVkRWZmb3J0TGltaXQgPSAwCiAgICAgICAgICAgIHNlbGYucHJpb3JpdHlFZmZvcnRSZXNlcnZlID0ge1ByaW9yaXR5LkhpZ2g6IHByaW9yaXR5RWZmb3J0TGltaXRbUHJpb3JpdHkuSGlnaF0hLCBQcmlvcml0eS5NZWRpdW06IHByaW9yaXR5RWZmb3J0TGltaXRbUHJpb3JpdHkuTWVkaXVtXSEsIFByaW9yaXR5LkxvdzogcHJpb3JpdHlFZmZvcnRMaW1pdFtQcmlvcml0eS5Mb3ddIX0KICAgICAgICAgICAgc2VsZi5tYXhEYXRhU2l6ZU1CID0gbWF4RGF0YVNpemVNQgogICAgICAgICAgICBzZWxmLnByaW9yaXR5RmVlTXVsdGlwbGllcnMgPSBwcmlvcml0eUZlZU11bHRpcGxpZXJzCiAgICAgICAgICAgIHNlbGYucmVmdW5kTXVsdGlwbGllciA9IHJlZnVuZE11bHRpcGxpZXIKICAgICAgICAgICAgc2VsZi5jYW5jZWxlZFRyYW5zYWN0aW9uc0xpbWl0ID0gY2FuY2VsZWRUcmFuc2FjdGlvbnNMaW1pdAogICAgICAgICAgICBzZWxmLmNvbGxlY3Rpb25FZmZvcnRMaW1pdCA9IGNvbGxlY3Rpb25FZmZvcnRMaW1pdAogICAgICAgICAgICBzZWxmLmNvbGxlY3Rpb25UcmFuc2FjdGlvbnNMaW1pdCA9IGNvbGxlY3Rpb25UcmFuc2FjdGlvbnNMaW1pdAogICAgICAgIH0KCiAgICAgICAgYWNjZXNzKGFsbCkgdmlldyBmdW4gZ2V0VHhSZW1vdmFsTGltaXQoKTogVUludCB7CiAgICAgICAgICAgIHJldHVybiBGbG93VHJhbnNhY3Rpb25TY2hlZHVsZXIuYWNjb3VudC5zdG9yYWdlLmNvcHk8VUludD4oZnJvbTogL3N0b3JhZ2UvdHhSZW1vdmFsTGltaXQpCiAgICAgICAgICAgICAgICA/PyAyMDAKICAgICAgICB9CiAgICB9CgoKICAgIC8vLyBTb3J0ZWRUaW1lc3RhbXBzIG1haW50YWlucyB0aW1lc3RhbXBzIHNvcnRlZCBpbiBhc2NlbmRpbmcgb3JkZXIgZm9yIGVmZmljaWVudCBwcm9jZXNzaW5nCiAgICAvLy8gSXQgZW5jYXBzdWxhdGVzIGFsbCBvcGVyYXRpb25zIHJlbGF0ZWQgdG8gbWFpbnRhaW5pbmcgYW5kIHF1ZXJ5aW5nIHNvcnRlZCB0aW1lc3RhbXBzCiAgICBhY2Nlc3MoYWxsKSBzdHJ1Y3QgU29ydGVkVGltZXN0YW1wcyB7CiAgICAgICAgLy8vIEludGVybmFsIHNvcnRlZCBhcnJheSBvZiB0aW1lc3RhbXBzCiAgICAgICAgYWNjZXNzKHNlbGYpIHZhciB0aW1lc3RhbXBzOiBbVUZpeDY0XQoKICAgICAgICBhY2Nlc3MoYWxsKSBpbml0KCkgewogICAgICAgICAgICBzZWxmLnRpbWVzdGFtcHMgPSBbXQogICAgICAgIH0KCiAgICAgICAgLy8vIGJpc2VjdCBpcyBhIGZ1bmN0aW9uIHRoYXQgZmluZHMgdGhlIGluZGV4IHRvIGluc2VydCBhIG5ldyB0aW1lc3RhbXAgaW4gdGhlIHNvcnRlZCBhcnJheS4KICAgICAgICAvLy8gdGFrZW4gZnJvbSBiaXNlY3RfcmlnaHQgaW4gcHRob24gaHR0cHM6Ly9zdGFja292ZXJmbG93LmNvbS9xdWVzdGlvbnMvMjk0NTAxNy9qYXZhcy1lcXVpdmFsZW50LXRvLWJpc2VjdC1pbi1weXRob24KICAgICAgICAvLy8gQHBhcmFtIG5ldzogVGhlIG5ldyB0aW1lc3RhbXAgdG8gaW5zZXJ0CiAgICAgICAgLy8vIEByZXR1cm46IFRoZSBpbmRleCB0byBpbnNlcnQgdGhlIG5ldyB0aW1lc3RhbXAgYXQgb3IgbmlsIGlmIHRoZSB0aW1lc3RhbXAgaXMgYWxyZWFkeSBpbiB0aGUgYXJyYXkKCQlhY2Nlc3MoYWxsKSBmdW4gYmlzZWN0KG5ldzogVUZpeDY0KTogSW50PyB7CgkJCXZhciBoaWdoID0gc2VsZi50aW1lc3RhbXBzLmxlbmd0aAoJCQl2YXIgbG93ID0gMAoJCQl3aGlsZSBsb3cgPCBoaWdoIHsKCQkJCWxldCBtaWQgPSAobG93K2hpZ2gpLzIKCQkJCWxldCBtaWRUaW1lc3RhbXAgPSBzZWxmLnRpbWVzdGFtcHNbbWlkXQoKCQkJCWlmIG1pZFRpbWVzdGFtcCA9PSBuZXcgewogICAgICAgICAgICAgICAgICAgIHJldHVybiBuaWwKICAgICAgICAgICAgICAgIH0gZWxzZSBpZiBtaWRUaW1lc3RhbXAgPiBuZXcgewoJCQkJCWhpZ2ggPSBtaWQKCQkJCX0gZWxzZSB7CgkJCQkJbG93ID0gbWlkICsgMQoJCQkJfQoJCQl9CgkJCXJldHVybiBsb3cKCQl9CgogICAgICAgIC8vLyBBZGQgYSB0aW1lc3RhbXAgdG8gdGhlIHNvcnRlZCBhcnJheSBtYWludGFpbmluZyBzb3J0ZWQgb3JkZXIKICAgICAgICBhY2Nlc3MoYWxsKSBmdW4gYWRkKHRpbWVzdGFtcDogVUZpeDY0KSB7CiAgICAgICAgICAgIC8vIE9ubHkgaW5zZXJ0IGlmIHRoZSB0aW1lc3RhbXAgaXMgbm90IGFscmVhZHkgaW4gdGhlIGFycmF5CiAgICAgICAgICAgIGlmIGxldCBpbnNlcnRJbmRleCA9IHNlbGYuYmlzZWN0KG5ldzogdGltZXN0YW1wKSB7CiAgICAgICAgICAgICAgICBzZWxmLnRpbWVzdGFtcHMuaW5zZXJ0KGF0OiBpbnNlcnRJbmRleCwgdGltZXN0YW1wKQogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICAvLy8gUmVtb3ZlIGEgdGltZXN0YW1wIGZyb20gdGhlIHNvcnRlZCBhcnJheQogICAgICAgIGFjY2VzcyhhbGwpIGZ1biByZW1vdmUodGltZXN0YW1wOiBVRml4NjQpIHsKICAgICAgICAgICAgLy8gT25seSByZW1vdmUgaWYgdGhlIHRpbWVzdGFtcCBpcyBpbiB0aGUgYXJyYXkKICAgICAgICAgICAgaWYgbGV0IGluZGV4ID0gc2VsZi50aW1lc3RhbXBzLmZpcnN0SW5kZXgob2Y6IHRpbWVzdGFtcCkgewogICAgICAgICAgICAgICAgc2VsZi50aW1lc3RhbXBzLnJlbW92ZShhdDogaW5kZXgpCiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIC8vLyBHZXQgYWxsIHRpbWVzdGFtcHMgdGhhdCBhcmUgaW4gdGhlIHBhc3QgKGxlc3MgdGhhbiBvciBlcXVhbCB0byBjdXJyZW50IHRpbWVzdGFtcCkKICAgICAgICBhY2Nlc3MoYWxsKSBmdW4gZ2V0QmVmb3JlKGN1cnJlbnQ6IFVGaXg2NCk6IFtVRml4NjRdIHsKICAgICAgICAgICAgbGV0IHBhc3RUaW1lc3RhbXBzOiBbVUZpeDY0XSA9IFtdCiAgICAgICAgICAgIGZvciB0aW1lc3RhbXAgaW4gc2VsZi50aW1lc3RhbXBzIHsKICAgICAgICAgICAgICAgIGlmIHRpbWVzdGFtcCA8PSBjdXJyZW50IHsKICAgICAgICAgICAgICAgICAgICBwYXN0VGltZXN0YW1wcy5hcHBlbmQodGltZXN0YW1wKQogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICBicmVhayAgLy8gTm8gbmVlZCB0byBjaGVjayBmdXJ0aGVyIHNpbmNlIGFycmF5IGlzIHNvcnRlZAogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIHJldHVybiBwYXN0VGltZXN0YW1wcwogICAgICAgIH0KCiAgICAgICAgLy8vIENoZWNrIGlmIHRoZXJlIGFyZSBhbnkgdGltZXN0YW1wcyB0aGF0IG5lZWQgcHJvY2Vzc2luZwogICAgICAgIC8vLyBSZXR1cm5zIHRydWUgaWYgcHJvY2Vzc2luZyBpcyBuZWVkZWQsIGZhbHNlIGZvciBlYXJseSBleGl0CiAgICAgICAgYWNjZXNzKGFsbCkgZnVuIGhhc0JlZm9yZShjdXJyZW50OiBVRml4NjQpOiBCb29sIHsKICAgICAgICAgICAgcmV0dXJuIHNlbGYudGltZXN0YW1wcy5sZW5ndGggPiAwICYmIHNlbGYudGltZXN0YW1wc1swXSA8PSBjdXJyZW50CiAgICAgICAgfQoKICAgICAgICAvLy8gR2V0IHRoZSB3aG9sZSBhcnJheSBvZiB0aW1lc3RhbXBzCiAgICAgICAgYWNjZXNzKGFsbCkgZnVuIGdldEFsbCgpOiBbVUZpeDY0XSB7CiAgICAgICAgICAgIHJldHVybiBzZWxmLnRpbWVzdGFtcHMKICAgICAgICB9CiAgICB9CgogICAgLy8vIFJlc291cmNlcwoKICAgIC8vLyBTaGFyZWQgc2NoZWR1bGVyIGlzIGEgcmVzb3VyY2UgdGhhdCBpcyB1c2VkIGFzIGEgc2luZ2xldG9uIGluIHRoZSBzY2hlZHVsZXIgY29udHJhY3QgYW5kIGNvbnRhaW5zIAogICAgLy8vIGFsbCB0aGUgZnVuY3Rpb25hbGl0eSB0byBzY2hlZHVsZSwgcHJvY2VzcyBhbmQgZXhlY3V0ZSB0cmFuc2FjdGlvbnMgYXMgd2VsbCBhcyB0aGUgaW50ZXJuYWwgc3RhdGUuIAogICAgYWNjZXNzKGFsbCkgcmVzb3VyY2UgU2hhcmVkU2NoZWR1bGVyIHsKICAgICAgICAvLy8gbmV4dElEIGNvbnRhaW5zIHRoZSBuZXh0IHRyYW5zYWN0aW9uIElEIHRvIGJlIGFzc2lnbmVkCiAgICAgICAgLy8vIFRoaXMgdGhlIElEIGlzIG1vbm90b25pY2FsbHkgaW5jcmVhc2luZyBhbmQgaXMgdXNlZCB0byBpZGVudGlmeSBlYWNoIHRyYW5zYWN0aW9uCiAgICAgICAgYWNjZXNzKGNvbnRyYWN0KSB2YXIgbmV4dElEOiBVSW50NjQKCiAgICAgICAgLy8vIHRyYW5zYWN0aW9ucyBpcyBhIG1hcCBvZiB0cmFuc2FjdGlvbiBJRHMgdG8gVHJhbnNhY3Rpb25EYXRhIHN0cnVjdHMKICAgICAgICBhY2Nlc3MoY29udHJhY3QpIHZhciB0cmFuc2FjdGlvbnM6IHtVSW50NjQ6IFRyYW5zYWN0aW9uRGF0YX0KCiAgICAgICAgLy8vIHNsb3QgcXVldWUgaXMgYSBtYXAgb2YgdGltZXN0YW1wcyB0byBQcmlvcml0aWVzIHRvIHRyYW5zYWN0aW9uIElEcyBhbmQgdGhlaXIgZXhlY3V0aW9uIGVmZm9ydHMKICAgICAgICBhY2Nlc3MoY29udHJhY3QpIHZhciBzbG90UXVldWU6IHtVRml4NjQ6IHtQcmlvcml0eToge1VJbnQ2NDogVUludDY0fX19CgogICAgICAgIC8vLyBzbG90IHVzZWQgZWZmb3J0IGlzIGEgbWFwIG9mIHRpbWVzdGFtcHMgbWFwIG9mIHByaW9yaXRpZXMgYW5kIAogICAgICAgIC8vLyBlZmZvcnRzIHRoYXQgaGFzIGJlZW4gdXNlZCBmb3IgdGhlIHRpbWVzbG90CiAgICAgICAgYWNjZXNzKGNvbnRyYWN0KSB2YXIgc2xvdFVzZWRFZmZvcnQ6IHtVRml4NjQ6IHtQcmlvcml0eTogVUludDY0fX0KCiAgICAgICAgLy8vIHNvcnRlZCB0aW1lc3RhbXBzIG1hbmFnZXIgZm9yIGVmZmljaWVudCBwcm9jZXNzaW5nCiAgICAgICAgYWNjZXNzKGNvbnRyYWN0KSB2YXIgc29ydGVkVGltZXN0YW1wczogU29ydGVkVGltZXN0YW1wcwogICAgCiAgICAgICAgLy8vIGNhbmNlbGVkIHRyYW5zYWN0aW9ucyBrZWVwcyBhIHJlY29yZCBvZiBjYW5jZWxlZCB0cmFuc2FjdGlvbiBJRHMgdXAgdG8gYSBjYW5jZWxlZFRyYW5zYWN0aW9uc0xpbWl0CiAgICAgICAgYWNjZXNzKGNvbnRyYWN0KSB2YXIgY2FuY2VsZWRUcmFuc2FjdGlvbnM6IFtVSW50NjRdCgogICAgICAgIC8vLyBTdHJ1Y3QgdGhhdCBjb250YWlucyBhbGwgdGhlIGNvbmZpZ3VyYXRpb24gZGV0YWlscyBmb3IgdGhlIHRyYW5zYWN0aW9uIHNjaGVkdWxlciBwcm90b2NvbAogICAgICAgIC8vLyBDYW4gYmUgdXBkYXRlZCBieSB0aGUgb3duZXIgb2YgdGhlIGNvbnRyYWN0CiAgICAgICAgYWNjZXNzKGNvbnRyYWN0KSB2YXIgY29uZmlnOiB7U2NoZWR1bGVyQ29uZmlnfQoKICAgICAgICBhY2Nlc3MoYWxsKSBpbml0KCkgewogICAgICAgICAgICBzZWxmLm5leHRJRCA9IDEKICAgICAgICAgICAgc2VsZi5jYW5jZWxlZFRyYW5zYWN0aW9ucyA9IFswIGFzIFVJbnQ2NF0KICAgICAgICAgICAgCiAgICAgICAgICAgIHNlbGYudHJhbnNhY3Rpb25zID0ge30KICAgICAgICAgICAgc2VsZi5zbG90VXNlZEVmZm9ydCA9IHt9CiAgICAgICAgICAgIHNlbGYuc2xvdFF1ZXVlID0ge30KICAgICAgICAgICAgc2VsZi5zb3J0ZWRUaW1lc3RhbXBzID0gU29ydGVkVGltZXN0YW1wcygpCiAgICAgICAgICAgIAogICAgICAgICAgICAvKiBEZWZhdWx0IHNsb3QgZWZmb3J0cyAtIGVhY2ggcHJpb3JpdHkgaGFzIGl0cyBvd24gaW5kZXBlbmRlbnQgcG9vbDoKCiAgICAgICAgICAgICAgICBUaW1lc3RhbXAgU2xvdCAoMjVrZWUgdG90YWwpCiAgICAgICAgICAgICAgICDilIzilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilJAKICAgICAgICAgICAgICAgIOKUgiDilIzilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilJAg4pSCIEhpZ2g6IDE1a2VlIOKAlCBmYWlsIGlmIGZ1bGwKICAgICAgICAgICAgICAgIOKUgiDilIIgICBIaWdoIFBvb2wgMTVrZWUgICDilIIg4pSCCiAgICAgICAgICAgICAgICDilIIg4pSU4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSYIOKUggogICAgICAgICAgICAgICAg4pSCIOKUjOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUkCDilIIgTWVkaXVtOiA3LjVrZWUg4oCUIHNoaWZ0IHRvIG5leHQgc2xvdCBpZiBmdWxsCiAgICAgICAgICAgICAgICDilIIg4pSCICBNZWRpdW0gUG9vbCA3LjVrZWUg4pSCIOKUggogICAgICAgICAgICAgICAg4pSCIOKUlOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUmCDilIIKICAgICAgICAgICAgICAgIOKUgiDilIzilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilJAg4pSCIExvdzogMi41a2VlIOKAlCBzaGlmdCB0byBuZXh0IHNsb3QgaWYgZnVsbAogICAgICAgICAgICAgICAg4pSCIOKUgiAgIExvdyBQb29sIDIuNWtlZSAgIOKUgiDilIIKICAgICAgICAgICAgICAgIOKUgiDilJTilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilJgg4pSCCiAgICAgICAgICAgICAgICDilJTilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilJgKICAgICAgICAgICAgKi8KCiAgICAgICAgICAgIHNlbGYuY29uZmlnID0gQ29uZmlnKAogICAgICAgICAgICAgICAgbWF4aW11bUluZGl2aWR1YWxFZmZvcnQ6IDk5OTksCiAgICAgICAgICAgICAgICBtaW5pbXVtRXhlY3V0aW9uRWZmb3J0OiAxMDAsCiAgICAgICAgICAgICAgICBwcmlvcml0eUVmZm9ydExpbWl0OiB7CiAgICAgICAgICAgICAgICAgICAgUHJpb3JpdHkuSGlnaDogMTVfMDAwLAogICAgICAgICAgICAgICAgICAgIFByaW9yaXR5Lk1lZGl1bTogN181MDAsCiAgICAgICAgICAgICAgICAgICAgUHJpb3JpdHkuTG93OiAyXzUwMAogICAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICAgIG1heERhdGFTaXplTUI6IDAuMDAxLAogICAgICAgICAgICAgICAgcHJpb3JpdHlGZWVNdWx0aXBsaWVyczogewogICAgICAgICAgICAgICAgICAgIFByaW9yaXR5LkhpZ2g6IDEwLjAsCiAgICAgICAgICAgICAgICAgICAgUHJpb3JpdHkuTWVkaXVtOiA1LjAsCiAgICAgICAgICAgICAgICAgICAgUHJpb3JpdHkuTG93OiAyLjAKICAgICAgICAgICAgICAgIH0sCiAgICAgICAgICAgICAgICByZWZ1bmRNdWx0aXBsaWVyOiAwLjUsCiAgICAgICAgICAgICAgICBjYW5jZWxlZFRyYW5zYWN0aW9uc0xpbWl0OiAxMDAwLAogICAgICAgICAgICAgICAgY29sbGVjdGlvbkVmZm9ydExpbWl0OiA1MDBfMDAwLCAvLyBNYXhpbXVtIGVmZm9ydCBmb3IgYWxsIHRyYW5zYWN0aW9ucyBpbiBhIGNvbGxlY3Rpb24KICAgICAgICAgICAgICAgIGNvbGxlY3Rpb25UcmFuc2FjdGlvbnNMaW1pdDogMTUwLCAvLyBNYXhpbXVtIG51bWJlciBvZiB0cmFuc2FjdGlvbnMgaW4gYSBjb2xsZWN0aW9uCiAgICAgICAgICAgICAgICB0eFJlbW92YWxMaW1pdDogMjAwCiAgICAgICAgICAgICkKICAgICAgICB9CgogICAgICAgIC8vLyBHZXRzIGEgY29weSBvZiB0aGUgc3RydWN0IGNvbnRhaW5pbmcgYWxsIHRoZSBjb25maWd1cmF0aW9uIGRldGFpbHMKICAgICAgICAvLy8gb2YgdGhlIFNjaGVkdWxlciByZXNvdXJjZQogICAgICAgIGFjY2Vzcyhjb250cmFjdCkgdmlldyBmdW4gZ2V0Q29uZmlnKCk6IHtTY2hlZHVsZXJDb25maWd9IHsKICAgICAgICAgICAgcmV0dXJuIHNlbGYuY29uZmlnCiAgICAgICAgfQoKICAgICAgICAvLy8gc2V0cyBhbGwgdGhlIGNvbmZpZ3VyYXRpb24gZGV0YWlscyBmb3IgdGhlIFNjaGVkdWxlciByZXNvdXJjZQogICAgICAgIC8vLyBOT1RFOiBUaGlzIGZ1bmN0aW9uIGlzIGd1YXJkZWQgYnkgdGhlIFVwZGF0ZUNvbmZpZyBlbnRpdGxlbWVudCwgd2hpY2ggaXMgYW4gYWRtaW4tb25seQogICAgICAgIC8vLyBjYXBhYmlsaXR5LiBJdCBpcyBub3QgY2FsbGFibGUgYnkgcmVndWxhciB1c2Vycy4gQW55IGNvbmZpZ3VyYXRpb24gY2hhbmdlcyAoaW5jbHVkaW5nCiAgICAgICAgLy8vIHR4UmVtb3ZhbExpbWl0KSByZXF1aXJlIGV4cGxpY2l0IGF1dGhvcml6YXRpb24gZnJvbSB0aGUgY29udHJhY3QgYWRtaW5pc3RyYXRvci4KICAgICAgICBhY2Nlc3MoVXBkYXRlQ29uZmlnKSBmdW4gc2V0Q29uZmlnKG5ld0NvbmZpZzoge1NjaGVkdWxlckNvbmZpZ30sIHR4UmVtb3ZhbExpbWl0OiBVSW50KSB7CiAgICAgICAgICAgIHNlbGYuY29uZmlnID0gbmV3Q29uZmlnCiAgICAgICAgICAgIEZsb3dUcmFuc2FjdGlvblNjaGVkdWxlci5hY2NvdW50LnN0b3JhZ2UubG9hZDxVSW50Pihmcm9tOiAvc3RvcmFnZS90eFJlbW92YWxMaW1pdCkKICAgICAgICAgICAgRmxvd1RyYW5zYWN0aW9uU2NoZWR1bGVyLmFjY291bnQuc3RvcmFnZS5zYXZlKHR4UmVtb3ZhbExpbWl0LCB0bzogL3N0b3JhZ2UvdHhSZW1vdmFsTGltaXQpCiAgICAgICAgICAgIGVtaXQgQ29uZmlnVXBkYXRlZCgpCiAgICAgICAgfQoKICAgICAgICAvLy8gZ2V0VHJhbnNhY3Rpb24gcmV0dXJucyBhIGNvcHkgb2YgdGhlIHNwZWNpZmllZCB0cmFuc2FjdGlvbgogICAgICAgIGFjY2Vzcyhjb250cmFjdCkgdmlldyBmdW4gZ2V0VHJhbnNhY3Rpb24oaWQ6IFVJbnQ2NCk6IFRyYW5zYWN0aW9uRGF0YT8gewogICAgICAgICAgICByZXR1cm4gc2VsZi50cmFuc2FjdGlvbnNbaWRdCiAgICAgICAgfQoKICAgICAgICAvLy8gYm9ycm93VHJhbnNhY3Rpb24gYm9ycm93cyBhIHJlZmVyZW5jZSB0byB0aGUgc3BlY2lmaWVkIHRyYW5zYWN0aW9uCiAgICAgICAgYWNjZXNzKGNvbnRyYWN0KSB2aWV3IGZ1biBib3Jyb3dUcmFuc2FjdGlvbihpZDogVUludDY0KTogJlRyYW5zYWN0aW9uRGF0YT8gewogICAgICAgICAgICByZXR1cm4gJnNlbGYudHJhbnNhY3Rpb25zW2lkXQogICAgICAgIH0KCiAgICAgICAgLy8vIGdldENhbmNlbGVkVHJhbnNhY3Rpb25zIHJldHVybnMgYSBjb3B5IG9mIHRoZSBjYW5jZWxlZCB0cmFuc2FjdGlvbnMgYXJyYXkKICAgICAgICBhY2Nlc3MoY29udHJhY3QpIHZpZXcgZnVuIGdldENhbmNlbGVkVHJhbnNhY3Rpb25zKCk6IFtVSW50NjRdIHsKICAgICAgICAgICAgcmV0dXJuIHNlbGYuY2FuY2VsZWRUcmFuc2FjdGlvbnMKICAgICAgICB9CgogICAgICAgIC8vLyBnZXRUcmFuc2FjdGlvbnNGb3JUaW1lZnJhbWUgcmV0dXJucyBhIGRpY3Rpb25hcnkgb2YgdHJhbnNhY3Rpb25zIHNjaGVkdWxlZCB3aXRoaW4gYSBzcGVjaWZpZWQgdGltZSByYW5nZSwKICAgICAgICAvLy8gb3JnYW5pemVkIGJ5IHRpbWVzdGFtcCBhbmQgcHJpb3JpdHkgd2l0aCBhcnJheXMgb2YgdHJhbnNhY3Rpb24gSURzLgogICAgICAgIC8vLyBXQVJOSU5HOiBJZiB5b3UgcHJvdmlkZSBhIHRpbWUgcmFuZ2UgdGhhdCBpcyB0b28gbGFyZ2UsIHRoZSBmdW5jdGlvbiB3aWxsIGxpa2VseSBmYWlsIHRvIGNvbXBsZXRlCiAgICAgICAgLy8vIGJlY2F1c2UgdGhlIGZ1bmN0aW9uIHdpbGwgcnVuIG91dCBvZiBnYXMuIEtlZXAgdGhlIHRpbWUgcmFuZ2Ugc21hbGwuCiAgICAgICAgLy8vCiAgICAgICAgLy8vIEBwYXJhbSBzdGFydFRpbWVzdGFtcDogVGhlIHN0YXJ0IHRpbWVzdGFtcCAoaW5jbHVzaXZlKSBmb3IgdGhlIHRpbWUgcmFuZ2UKICAgICAgICAvLy8gQHBhcmFtIGVuZFRpbWVzdGFtcDogVGhlIGVuZCB0aW1lc3RhbXAgKGluY2x1c2l2ZSkgZm9yIHRoZSB0aW1lIHJhbmdlCiAgICAgICAgLy8vIEByZXR1cm4ge1VGaXg2NDoge1ByaW9yaXR5OiBbVUludDY0XX19OiBBIGRpY3Rpb25hcnkgbWFwcGluZyB0aW1lc3RhbXBzIHRvIHByaW9yaXRpZXMgdG8gYXJyYXlzIG9mIHRyYW5zYWN0aW9uIElEcwogICAgICAgIGFjY2Vzcyhjb250cmFjdCkgZnVuIGdldFRyYW5zYWN0aW9uc0ZvclRpbWVmcmFtZShzdGFydFRpbWVzdGFtcDogVUZpeDY0LCBlbmRUaW1lc3RhbXA6IFVGaXg2NCk6IHtVRml4NjQ6IHtVSW50ODogW1VJbnQ2NF19fSB7CiAgICAgICAgICAgIHZhciB0cmFuc2FjdGlvbnNJblRpbWVmcmFtZToge1VGaXg2NDoge1VJbnQ4OiBbVUludDY0XX19ID0ge30KICAgICAgICAgICAgCiAgICAgICAgICAgIC8vIFZhbGlkYXRlIGlucHV0IHBhcmFtZXRlcnMKICAgICAgICAgICAgaWYgc3RhcnRUaW1lc3RhbXAgPiBlbmRUaW1lc3RhbXAgewogICAgICAgICAgICAgICAgcmV0dXJuIHRyYW5zYWN0aW9uc0luVGltZWZyYW1lCiAgICAgICAgICAgIH0KICAgICAgICAgICAgCiAgICAgICAgICAgIC8vIEdldCBhbGwgdGltZXN0YW1wcyB0aGF0IGZhbGwgd2l0aGluIHRoZSBzcGVjaWZpZWQgcmFuZ2UKICAgICAgICAgICAgbGV0IGFsbFRpbWVzdGFtcHNCZWZvcmVFbmQgPSBzZWxmLnNvcnRlZFRpbWVzdGFtcHMuZ2V0QmVmb3JlKGN1cnJlbnQ6IGVuZFRpbWVzdGFtcCkKICAgICAgICAgICAgCiAgICAgICAgICAgIGZvciB0aW1lc3RhbXAgaW4gYWxsVGltZXN0YW1wc0JlZm9yZUVuZCB7CiAgICAgICAgICAgICAgICAvLyBDaGVjayBpZiB0aGlzIHRpbWVzdGFtcCBmYWxscyB3aXRoaW4gb3VyIHJhbmdlCiAgICAgICAgICAgICAgICBpZiB0aW1lc3RhbXAgPCBzdGFydFRpbWVzdGFtcCB7IGNvbnRpbnVlIH0KICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgbGV0IHRyYW5zYWN0aW9uUHJpb3JpdGllcyA9IHNlbGYuc2xvdFF1ZXVlW3RpbWVzdGFtcF0gPz8ge30KICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgdmFyIHRpbWVzdGFtcFRyYW5zYWN0aW9uczoge1VJbnQ4OiBbVUludDY0XX0gPSB7fQogICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICBmb3IgcHJpb3JpdHkgaW4gdHJhbnNhY3Rpb25Qcmlvcml0aWVzIHsKICAgICAgICAgICAgICAgICAgICBsZXQgdHJhbnNhY3Rpb25JRHMgPSB0cmFuc2FjdGlvblByaW9yaXRpZXNbcHJpb3JpdHldID8/IHt9CiAgICAgICAgICAgICAgICAgICAgdmFyIHByaW9yaXR5VHJhbnNhY3Rpb25zOiBbVUludDY0XSA9IFtdCgogICAgICAgICAgICAgICAgICAgIGZvciBpZCBpbiB0cmFuc2FjdGlvbklEcyB7CiAgICAgICAgICAgICAgICAgICAgICAgIHByaW9yaXR5VHJhbnNhY3Rpb25zLmFwcGVuZChpZCkKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgIGlmIHByaW9yaXR5VHJhbnNhY3Rpb25zLmxlbmd0aCA+IDAgewogICAgICAgICAgICAgICAgICAgICAgICB0aW1lc3RhbXBUcmFuc2FjdGlvbnNbcHJpb3JpdHkucmF3VmFsdWVdID0gcHJpb3JpdHlUcmFuc2FjdGlvbnMKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgIGlmIHRpbWVzdGFtcFRyYW5zYWN0aW9ucy5rZXlzLmxlbmd0aCA+IDAgewogICAgICAgICAgICAgICAgICAgIHRyYW5zYWN0aW9uc0luVGltZWZyYW1lW3RpbWVzdGFtcF0gPSB0aW1lc3RhbXBUcmFuc2FjdGlvbnMKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIAogICAgICAgICAgICB9CiAgICAgICAgICAgIAogICAgICAgICAgICByZXR1cm4gdHJhbnNhY3Rpb25zSW5UaW1lZnJhbWUKICAgICAgICB9CgogICAgICAgIC8vLyBjYWxjdWxhdGUgZmVlIGJ5IGNvbnZlcnRpbmcgZXhlY3V0aW9uIGVmZm9ydCB0byBhIGZlZSBpbiBGbG93IHRva2Vucy4KICAgICAgICAvLy8gQHBhcmFtIGV4ZWN1dGlvbkVmZm9ydDogVGhlIGV4ZWN1dGlvbiBlZmZvcnQgb2YgdGhlIHRyYW5zYWN0aW9uCiAgICAgICAgLy8vIEBwYXJhbSBwcmlvcml0eTogVGhlIHByaW9yaXR5IG9mIHRoZSB0cmFuc2FjdGlvbgogICAgICAgIC8vLyBAcGFyYW0gZGF0YVNpemVNQjogVGhlIHNpemUgb2YgdGhlIGRhdGEgdGhhdCB3YXMgcGFzc2VkIHdoZW4gdGhlIHRyYW5zYWN0aW9uIHdhcyBvcmlnaW5hbGx5IHNjaGVkdWxlZAogICAgICAgIC8vLyBAcmV0dXJuIFVGaXg2NDogVGhlIGZlZSBpbiBGbG93IHRva2VucyB0aGF0IGlzIHJlcXVpcmVkIHRvIHBheSBmb3IgdGhlIHRyYW5zYWN0aW9uCiAgICAgICAgYWNjZXNzKGNvbnRyYWN0KSBmdW4gY2FsY3VsYXRlRmVlKGV4ZWN1dGlvbkVmZm9ydDogVUludDY0LCBwcmlvcml0eTogUHJpb3JpdHksIGRhdGFTaXplTUI6IFVGaXg2NCk6IFVGaXg2NCB7CiAgICAgICAgICAgIC8vIFVzZSB0aGUgb2ZmaWNpYWwgRmxvd0ZlZXMgY2FsY3VsYXRpb24KICAgICAgICAgICAgbGV0IGJhc2VGZWUgPSBGbG93RmVlcy5jb21wdXRlRmVlcyhpbmNsdXNpb25FZmZvcnQ6IDEuMCwgZXhlY3V0aW9uRWZmb3J0OiBVRml4NjQoZXhlY3V0aW9uRWZmb3J0KS8xMDAwMDAwMDAuMCkKICAgICAgICAgICAgCiAgICAgICAgICAgIC8vIFNjYWxlIHRoZSBleGVjdXRpb24gZmVlIGJ5IHRoZSBtdWx0aXBsaWVyIGZvciB0aGUgcHJpb3JpdHkKICAgICAgICAgICAgbGV0IHNjYWxlZEV4ZWN1dGlvbkZlZSA9IGJhc2VGZWUgKiBzZWxmLmNvbmZpZy5wcmlvcml0eUZlZU11bHRpcGxpZXJzW3ByaW9yaXR5XSEKCiAgICAgICAgICAgIC8vIENhbGN1bGF0ZSB0aGUgRkxPVyByZXF1aXJlZCB0byBwYXkgZm9yIHN0b3JhZ2Ugb2YgdGhlIHRyYW5zYWN0aW9uIGRhdGEKICAgICAgICAgICAgbGV0IHN0b3JhZ2VGZWUgPSBGbG93U3RvcmFnZUZlZXMuc3RvcmFnZUNhcGFjaXR5VG9GbG93KGRhdGFTaXplTUIpCgogICAgICAgICAgICAvLyBBZGQgaW5jbHVzaW9uIEZsb3cgZmVlIGZvciBzY2hlZHVsZWQgdHJhbnNhY3Rpb25zCiAgICAgICAgICAgIGxldCBpbmNsdXNpb25GZWUgPSAwLjAwMDAxCgogICAgICAgICAgICByZXR1cm4gc2NhbGVkRXhlY3V0aW9uRmVlICsgc3RvcmFnZUZlZSArIGluY2x1c2lvbkZlZQogICAgICAgIH0KCiAgICAgICAgLy8vIGdldE5leHRJREFuZEluY3JlbWVudCByZXR1cm5zIHRoZSBuZXh0IElEIGFuZCBpbmNyZW1lbnRzIHRoZSBJRCBjb3VudGVyCiAgICAgICAgYWNjZXNzKHNlbGYpIGZ1biBnZXROZXh0SURBbmRJbmNyZW1lbnQoKTogVUludDY0IHsKICAgICAgICAgICAgbGV0IG5leHRJRCA9IHNlbGYubmV4dElECiAgICAgICAgICAgIHNlbGYubmV4dElEID0gc2VsZi5uZXh0SUQgKyAxCiAgICAgICAgICAgIHJldHVybiBuZXh0SUQKICAgICAgICB9CgogICAgICAgIC8vLyBnZXQgc3RhdHVzIG9mIHRoZSBzY2hlZHVsZWQgdHJhbnNhY3Rpb24KICAgICAgICAvLy8gQHBhcmFtIGlkOiBUaGUgSUQgb2YgdGhlIHRyYW5zYWN0aW9uIHRvIGdldCB0aGUgc3RhdHVzIG9mCiAgICAgICAgLy8vIEByZXR1cm4gU3RhdHVzOiBUaGUgc3RhdHVzIG9mIHRoZSB0cmFuc2FjdGlvbiwgaWYgdGhlIHRyYW5zYWN0aW9uIGlzIG5vdCBmb3VuZCBVbmtub3duIGlzIHJldHVybmVkLgogICAgICAgIGFjY2Vzcyhjb250cmFjdCkgdmlldyBmdW4gZ2V0U3RhdHVzKGlkOiBVSW50NjQpOiBTdGF0dXM/IHsKICAgICAgICAgICAgLy8gaWYgdGhlIHRyYW5zYWN0aW9uIElEIGlzIGdyZWF0ZXIgdGhhbiB0aGUgbmV4dCBJRCwgaXQgaXMgbm90IHNjaGVkdWxlZCB5ZXQgYW5kIGhhcyBuZXZlciBleGlzdGVkCiAgICAgICAgICAgIGlmIGlkID09IDAgYXMgVUludDY0IHx8IGlkID49IHNlbGYubmV4dElEIHsKICAgICAgICAgICAgICAgIHJldHVybiBuaWwKICAgICAgICAgICAgfQoKICAgICAgICAgICAgLy8gVGhpcyBzaG91bGQgYWx3YXlzIHJldHVybiBTY2hlZHVsZWQgb3IgRXhlY3V0ZWQKICAgICAgICAgICAgaWYgbGV0IHR4ID0gc2VsZi5ib3Jyb3dUcmFuc2FjdGlvbihpZDogaWQpIHsKICAgICAgICAgICAgICAgIHJldHVybiB0eC5zdGF0dXMKICAgICAgICAgICAgfQoKICAgICAgICAgICAgLy8gaWYgdGhlIHRyYW5zYWN0aW9uIHdhcyBjYW5jZWxlZCBhbmQgaXQgaXMgc3RpbGwgbm90IHBydW5lZCBmcm9tIAogICAgICAgICAgICAvLyBsaXN0IHJldHVybiBjYW5jZWxlZCBzdGF0dXMKICAgICAgICAgICAgaWYgc2VsZi5jYW5jZWxlZFRyYW5zYWN0aW9ucy5jb250YWlucyhpZCkgewogICAgICAgICAgICAgICAgcmV0dXJuIFN0YXR1cy5DYW5jZWxlZAogICAgICAgICAgICB9CgogICAgICAgICAgICAvLyBJZiB3ZSByZWFjaCB0aGlzIHBvaW50LCB0aGUgdHJhbnNhY3Rpb24gaXMgbm90IGluIHRoZSBhY3RpdmUgdHJhbnNhY3Rpb25zIG1hcAogICAgICAgICAgICAvLyBhbmQgbm90IGluIGNhbmNlbGVkVHJhbnNhY3Rpb25zLiBTaW5jZSBTY2hlZHVsZWQgdHJhbnNhY3Rpb25zIGFsd2F5cyByZW1haW4gaW4KICAgICAgICAgICAgLy8gdGhlIHRyYW5zYWN0aW9ucyBtYXAgdW50aWwgZXhlY3V0aW9uLCBhIHRyYW5zYWN0aW9uIGNhbiBvbmx5IHJlYWNoIHRoaXMgY29kZSBwYXRoCiAgICAgICAgICAgIC8vIGFmdGVyIGl0IGhhcyBiZWVuIGV4ZWN1dGVkIGFuZCBhZ2VkIG91dC4gVGhlIGluZmVyZW5jZSBiZWxvdyB1c2VzIHRoZSBzb3J0ZWQKICAgICAgICAgICAgLy8gY2FuY2VsZWRUcmFuc2FjdGlvbnMgYXJyYXkgYXMgYSBsb3dlci1ib3VuZCBhbmNob3I6IGlmIHRoZSByZXF1ZXN0ZWQgSUQgaXMgZ3JlYXRlcgogICAgICAgICAgICAvLyB0aGFuIHRoZSBvbGRlc3Qga25vd24gY2FuY2VsZWQgSUQsIGl0IG11c3QgaGF2ZSBiZWVuIGV4ZWN1dGVkIChub3QgY2FuY2VsZWQpLAogICAgICAgICAgICAvLyBiZWNhdXNlIGFueSBjYW5jZWxsYXRpb24gd291bGQgaGF2ZSBhZGRlZCBpdCB0byB0aGUgY2FuY2VsZWRUcmFuc2FjdGlvbnMgYXJyYXkuCiAgICAgICAgICAgIC8vIE5PVEU6IFNjaGVkdWxlZCAoZnV0dXJlKSB0cmFuc2FjdGlvbnMgY2Fubm90IGJlIGluY29ycmVjdGx5IHJlcG9ydGVkIGFzIEV4ZWN1dGVkCiAgICAgICAgICAgIC8vIGhlcmUg4oCUIHRoZXkgYXJlIHN0aWxsIGluIHRoZSB0cmFuc2FjdGlvbnMgbWFwIGFuZCBhcmUgcmV0dXJuZWQgYXMgU2NoZWR1bGVkIGFib3ZlLgogICAgICAgICAgICBsZXQgZmlyc3RDYW5jZWxlZElEID0gc2VsZi5jYW5jZWxlZFRyYW5zYWN0aW9uc1swXQogICAgICAgICAgICBpZiBpZCA+IGZpcnN0Q2FuY2VsZWRJRCB7CiAgICAgICAgICAgICAgICByZXR1cm4gU3RhdHVzLkV4ZWN1dGVkCiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIC8vIHRoZSB0cmFuc2FjdGlvbiBsaXN0IHdhcyBwcnVuZWQgYW5kIHRoZSB0cmFuc2FjdGlvbiBzdGF0dXMgbWlnaHQgYmUgCiAgICAgICAgICAgIC8vIGVpdGhlciBjYW5jZWxlZCBvciBleGVjdXRlIHNvIHdlIHJldHVybiB1bmtub3duCiAgICAgICAgICAgIHJldHVybiBTdGF0dXMuVW5rbm93bgogICAgICAgIH0KCiAgICAgICAgLy8vIHNjaGVkdWxlIGlzIHRoZSBwcmltYXJ5IGVudHJ5IHBvaW50IGZvciBzY2hlZHVsaW5nIGEgbmV3IHRyYW5zYWN0aW9uIHdpdGhpbiB0aGUgc2NoZWR1bGVyIGNvbnRyYWN0LiAKICAgICAgICAvLy8gSWYgc2NoZWR1bGluZyB0aGUgdHJhbnNhY3Rpb24gaXMgbm90IHBvc3NpYmxlIGVpdGhlciBkdWUgdG8gaW52YWxpZCBhcmd1bWVudHMgb3IgZHVlIHRvIAogICAgICAgIC8vLyB1bmF2YWlsYWJsZSBzbG90cywgdGhlIGZ1bmN0aW9uIHBhbmljcy4gCiAgICAgICAgLy8KICAgICAgICAvLy8gVGhlIHNjaGVkdWxlIGZ1bmN0aW9uIGFjY2VwdHMgdGhlIGZvbGxvd2luZyBhcmd1bWVudHM6CiAgICAgICAgLy8vIEBwYXJhbTogdHJhbnNhY3Rpb246IEEgY2FwYWJpbGl0eSB0byBhIHJlc291cmNlIGluIHN0b3JhZ2UgdGhhdCBpbXBsZW1lbnRzIHRoZSB0cmFuc2FjdGlvbiBoYW5kbGVyIAogICAgICAgIC8vLyAgICBpbnRlcmZhY2UuIFRoaXMgaGFuZGxlciB3aWxsIGJlIGludm9rZWQgYXQgZXhlY3V0aW9uIHRpbWUgYW5kIHdpbGwgcmVjZWl2ZSB0aGUgc3BlY2lmaWVkIGRhdGEgcGF5bG9hZC4KICAgICAgICAvLy8gQHBhcmFtOiB0aW1lc3RhbXA6IFNwZWNpZmllcyB0aGUgZWFybGllc3QgYmxvY2sgdGltZXN0YW1wIGF0IHdoaWNoIHRoZSB0cmFuc2FjdGlvbiBpcyBlbGlnaWJsZSBmb3IgZXhlY3V0aW9uIAogICAgICAgIC8vLyAgICAoVW5peCB0aW1lc3RhbXAgc28gZnJhY3Rpb25hbCBzZWNvbmRzIHZhbHVlcyBhcmUgaWdub3JlZCkuIEl0IG11c3QgYmUgc2V0IGluIHRoZSBmdXR1cmUuCiAgICAgICAgLy8vIEBwYXJhbTogcHJpb3JpdHk6IEFuIGVudW0gdmFsdWUgKGBIaWdoYCwgYE1lZGl1bWAsIG9yIGBMb3dgKSB0aGF0IGluZmx1ZW5jZXMgdGhlIHNjaGVkdWxpbmcgYmVoYXZpb3IgYW5kIGRldGVybWluZXMgCiAgICAgICAgLy8vICAgIGhvdyBzb29uIGFmdGVyIHRoZSB0aW1lc3RhbXAgdGhlIHRyYW5zYWN0aW9uIHdpbGwgYmUgZXhlY3V0ZWQuCiAgICAgICAgLy8vIEBwYXJhbTogZXhlY3V0aW9uRWZmb3J0OiBEZWZpbmVzIHRoZSBtYXhpbXVtIGNvbXB1dGF0aW9uYWwgcmVzb3VyY2VzIGFsbG9jYXRlZCB0byB0aGUgdHJhbnNhY3Rpb24uIFRoaXMgYWxzbyBkZXRlcm1pbmVzIAogICAgICAgIC8vLyAgICB0aGUgZmVlIGNoYXJnZWQuIFVudXNlZCBleGVjdXRpb24gZWZmb3J0IGlzIG5vdCByZWZ1bmRlZC4KICAgICAgICAvLy8gQHBhcmFtOiBmZWVzOiBBIFZhdWx0IHJlc291cmNlIGNvbnRhaW5pbmcgc3VmZmljaWVudCBmdW5kcyB0byBjb3ZlciB0aGUgcmVxdWlyZWQgZXhlY3V0aW9uIGVmZm9ydC4KICAgICAgICBhY2Nlc3MoY29udHJhY3QpIGZ1biBzY2hlZHVsZSgKICAgICAgICAgICAgaGFuZGxlckNhcDogQ2FwYWJpbGl0eTxhdXRoKEV4ZWN1dGUpICZ7VHJhbnNhY3Rpb25IYW5kbGVyfT4sCiAgICAgICAgICAgIGRhdGE6IEFueVN0cnVjdD8sCiAgICAgICAgICAgIHRpbWVzdGFtcDogVUZpeDY0LAogICAgICAgICAgICBwcmlvcml0eTogUHJpb3JpdHksCiAgICAgICAgICAgIGV4ZWN1dGlvbkVmZm9ydDogVUludDY0LAogICAgICAgICAgICBmZWVzOiBARmxvd1Rva2VuLlZhdWx0CiAgICAgICAgKTogQFNjaGVkdWxlZFRyYW5zYWN0aW9uIHsKCiAgICAgICAgICAgIC8vIFVzZSB0aGUgZXN0aW1hdGUgZnVuY3Rpb24gdG8gdmFsaWRhdGUgaW5wdXRzCiAgICAgICAgICAgIGxldCBlc3RpbWF0ZSA9IHNlbGYuZXN0aW1hdGUoCiAgICAgICAgICAgICAgICBkYXRhOiBkYXRhLAogICAgICAgICAgICAgICAgdGltZXN0YW1wOiB0aW1lc3RhbXAsCiAgICAgICAgICAgICAgICBwcmlvcml0eTogcHJpb3JpdHksCiAgICAgICAgICAgICAgICBleGVjdXRpb25FZmZvcnQ6IGV4ZWN1dGlvbkVmZm9ydAogICAgICAgICAgICApCgogICAgICAgICAgICBpZiBlc3RpbWF0ZS5lcnJvciAhPSBuaWwgewogICAgICAgICAgICAgICAgcGFuaWMoZXN0aW1hdGUuZXJyb3IhKQogICAgICAgICAgICB9CgogICAgICAgICAgICBhc3NlcnQgKAogICAgICAgICAgICAgICAgZmVlcy5iYWxhbmNlID49IGVzdGltYXRlLmZsb3dGZWUhLAogICAgICAgICAgICAgICAgbWVzc2FnZTogIkluc3VmZmljaWVudCBmZWVzOiBUaGUgRmVlIGJhbGFuY2Ugb2YgXChmZWVzLmJhbGFuY2UpIGlzIG5vdCBzdWZmaWNpZW50IHRvIHBheSB0aGUgcmVxdWlyZWQgYW1vdW50IG9mIFwoZXN0aW1hdGUuZmxvd0ZlZSEpIGZvciBleGVjdXRpb24gb2YgdGhlIHRyYW5zYWN0aW9uLiIKICAgICAgICAgICAgKQoKICAgICAgICAgICAgbGV0IHRyYW5zYWN0aW9uSUQgPSBzZWxmLmdldE5leHRJREFuZEluY3JlbWVudCgpCiAgICAgICAgICAgIGxldCB0cmFuc2FjdGlvbkRhdGEgPSBUcmFuc2FjdGlvbkRhdGEoCiAgICAgICAgICAgICAgICBpZDogdHJhbnNhY3Rpb25JRCwKICAgICAgICAgICAgICAgIGhhbmRsZXI6IGhhbmRsZXJDYXAsCiAgICAgICAgICAgICAgICBzY2hlZHVsZWRUaW1lc3RhbXA6IGVzdGltYXRlLnRpbWVzdGFtcCEsCiAgICAgICAgICAgICAgICBkYXRhOiBkYXRhLAogICAgICAgICAgICAgICAgcHJpb3JpdHk6IHByaW9yaXR5LAogICAgICAgICAgICAgICAgZXhlY3V0aW9uRWZmb3J0OiBleGVjdXRpb25FZmZvcnQsCiAgICAgICAgICAgICAgICBmZWVzOiBmZWVzLmJhbGFuY2UsCiAgICAgICAgICAgICkKCiAgICAgICAgICAgIC8vIERlcG9zaXQgdGhlIGZlZXMgdG8gdGhlIHNlcnZpY2UgYWNjb3VudCdzIHZhdWx0CiAgICAgICAgICAgIEZsb3dUcmFuc2FjdGlvblNjaGVkdWxlci5kZXBvc2l0RmVlcyhmcm9tOiA8LWZlZXMpCgogICAgICAgICAgICAvLyBSZXNlcnZlIHRoZSBzbG90IGNhcGFjaXR5IGJlZm9yZSBpbnZva2luZyBoYW5kbGVyIGNhbGxiYWNrLgogICAgICAgICAgICBzZWxmLmFkZFRyYW5zYWN0aW9uKHNsb3Q6IGVzdGltYXRlLnRpbWVzdGFtcCEsIHR4RGF0YTogdHJhbnNhY3Rpb25EYXRhKQoKICAgICAgICAgICAgbGV0IGhhbmRsZXJSZWYgPSBoYW5kbGVyQ2FwLmJvcnJvdygpCiAgICAgICAgICAgICAgICA/PyBwYW5pYygiSW52YWxpZCB0cmFuc2FjdGlvbiBoYW5kbGVyOiBDb3VsZCBub3QgYm9ycm93IGEgcmVmZXJlbmNlIHRvIHRoZSB0cmFuc2FjdGlvbiBoYW5kbGVyIikKCiAgICAgICAgICAgIGxldCBoYW5kbGVyUHVibGljUGF0aCA9IGhhbmRsZXJSZWYucmVzb2x2ZVZpZXcoVHlwZTxQdWJsaWNQYXRoPigpKSBhcz8gUHVibGljUGF0aAoKICAgICAgICAgICAgZW1pdCBTY2hlZHVsZWQoCiAgICAgICAgICAgICAgICBpZDogdHJhbnNhY3Rpb25EYXRhLmlkLAogICAgICAgICAgICAgICAgcHJpb3JpdHk6IHRyYW5zYWN0aW9uRGF0YS5wcmlvcml0eS5yYXdWYWx1ZSwKICAgICAgICAgICAgICAgIHRpbWVzdGFtcDogdHJhbnNhY3Rpb25EYXRhLnNjaGVkdWxlZFRpbWVzdGFtcCwKICAgICAgICAgICAgICAgIGV4ZWN1dGlvbkVmZm9ydDogdHJhbnNhY3Rpb25EYXRhLmV4ZWN1dGlvbkVmZm9ydCwKICAgICAgICAgICAgICAgIGZlZXM6IHRyYW5zYWN0aW9uRGF0YS5mZWVzLAogICAgICAgICAgICAgICAgdHJhbnNhY3Rpb25IYW5kbGVyT3duZXI6IHRyYW5zYWN0aW9uRGF0YS5oYW5kbGVyLmFkZHJlc3MsCiAgICAgICAgICAgICAgICB0cmFuc2FjdGlvbkhhbmRsZXJUeXBlSWRlbnRpZmllcjogdHJhbnNhY3Rpb25EYXRhLmhhbmRsZXJUeXBlSWRlbnRpZmllciwKICAgICAgICAgICAgICAgIHRyYW5zYWN0aW9uSGFuZGxlclVVSUQ6IGhhbmRsZXJSZWYudXVpZCwKICAgICAgICAgICAgICAgIHRyYW5zYWN0aW9uSGFuZGxlclB1YmxpY1BhdGg6IGhhbmRsZXJQdWJsaWNQYXRoCiAgICAgICAgICAgICkKCiAgICAgICAgICAgIHJldHVybiA8LWNyZWF0ZSBTY2hlZHVsZWRUcmFuc2FjdGlvbigKICAgICAgICAgICAgICAgIGlkOiB0cmFuc2FjdGlvbklELCAKICAgICAgICAgICAgICAgIHRpbWVzdGFtcDogZXN0aW1hdGUudGltZXN0YW1wISwKICAgICAgICAgICAgICAgIGhhbmRsZXJUeXBlSWRlbnRpZmllcjogdHJhbnNhY3Rpb25EYXRhLmhhbmRsZXJUeXBlSWRlbnRpZmllcgogICAgICAgICAgICApCiAgICAgICAgfQoKICAgICAgICAvLy8gVGhlIGVzdGltYXRlIGZ1bmN0aW9uIGNhbGN1bGF0ZXMgdGhlIHJlcXVpcmVkIGZlZSBpbiBGbG93IGFuZCBleHBlY3RlZCBleGVjdXRpb24gdGltZXN0YW1wIGZvcgogICAgICAgIC8vLyBhIHRyYW5zYWN0aW9uIGJhc2VkIG9uIHRoZSByZXF1ZXN0ZWQgdGltZXN0YW1wLCBwcmlvcml0eSwgYW5kIGV4ZWN1dGlvbiBlZmZvcnQuCiAgICAgICAgLy8vCiAgICAgICAgLy8vIElmIHRoZSBwcm92aWRlZCBhcmd1bWVudHMgYXJlIGludmFsaWQgb3IgdGhlIHRyYW5zYWN0aW9uIGNhbm5vdCBiZSBzY2hlZHVsZWQgKGUuZy4sIGR1ZSB0bwogICAgICAgIC8vLyBpbnN1ZmZpY2llbnQgY29tcHV0YXRpb24gZWZmb3J0IG9yIHVuYXZhaWxhYmxlIHRpbWUgc2xvdHMpIHRoZSBlc3RpbWF0ZSBmdW5jdGlvbgogICAgICAgIC8vLyByZXR1cm5zIGFuIEVzdGltYXRlZFNjaGVkdWxlZFRyYW5zYWN0aW9uIHN0cnVjdCB3aXRoIGEgbm9uLW5pbCBlcnJvciBtZXNzYWdlLgogICAgICAgIC8vLwogICAgICAgIC8vLyBUaGlzIGhlbHBzIGRldmVsb3BlcnMgZW5zdXJlIHN1ZmZpY2llbnQgZnVuZGluZyBhbmQgcHJldmlldyB0aGUgZXhwZWN0ZWQgc2NoZWR1bGluZyB3aW5kb3csCiAgICAgICAgLy8vIHJlZHVjaW5nIHRoZSByaXNrIG9mIHVubmVjZXNzYXJ5IGNhbmNlbGxhdGlvbnMuCiAgICAgICAgLy8vCiAgICAgICAgLy8vIFYyOiBFYWNoIHByaW9yaXR5IGhhcyBpdHMgb3duIGluZGVwZW5kZW50IHBvb2wuIExvdyBwcmlvcml0eSB0cmFuc2FjdGlvbnMgcmVjZWl2ZSBhIHZhbGlkCiAgICAgICAgLy8vIHRpbWVzdGFtcCBlc3RpbWF0ZSBqdXN0IGxpa2UgSGlnaCBhbmQgTWVkaXVtIHByaW9yaXR5IHRyYW5zYWN0aW9ucy4KICAgICAgICAvLy8KICAgICAgICAvLy8gQHBhcmFtIGRhdGE6IFRoZSBkYXRhIHRoYXQgd2FzIHBhc3NlZCB3aGVuIHRoZSB0cmFuc2FjdGlvbiB3YXMgb3JpZ2luYWxseSBzY2hlZHVsZWQKICAgICAgICAvLy8gQHBhcmFtIHRpbWVzdGFtcDogVGhlIHJlcXVlc3RlZCB0aW1lc3RhbXAgZm9yIHRoZSB0cmFuc2FjdGlvbgogICAgICAgIC8vLyBAcGFyYW0gcHJpb3JpdHk6IFRoZSBwcmlvcml0eSBvZiB0aGUgdHJhbnNhY3Rpb24KICAgICAgICAvLy8gQHBhcmFtIGV4ZWN1dGlvbkVmZm9ydDogVGhlIGV4ZWN1dGlvbiBlZmZvcnQgb2YgdGhlIHRyYW5zYWN0aW9uCiAgICAgICAgLy8vIEByZXR1cm4gRXN0aW1hdGVkU2NoZWR1bGVkVHJhbnNhY3Rpb246IEEgc3RydWN0IGNvbnRhaW5pbmcgdGhlIGVzdGltYXRlZCBmZWUsIHRpbWVzdGFtcCwgYW5kIGVycm9yIG1lc3NhZ2UKICAgICAgICBhY2Nlc3MoY29udHJhY3QpIGZ1biBlc3RpbWF0ZSgKICAgICAgICAgICAgZGF0YTogQW55U3RydWN0PywKICAgICAgICAgICAgdGltZXN0YW1wOiBVRml4NjQsCiAgICAgICAgICAgIHByaW9yaXR5OiBQcmlvcml0eSwKICAgICAgICAgICAgZXhlY3V0aW9uRWZmb3J0OiBVSW50NjQKICAgICAgICApOiBFc3RpbWF0ZWRTY2hlZHVsZWRUcmFuc2FjdGlvbiB7CiAgICAgICAgICAgIC8vIFJlbW92ZSBmcmFjdGlvbmFsIHZhbHVlcyBmcm9tIHRoZSB0aW1lc3RhbXAKICAgICAgICAgICAgbGV0IHNhbml0aXplZFRpbWVzdGFtcCA9IFVGaXg2NChVSW50NjQodGltZXN0YW1wKSkKCiAgICAgICAgICAgIGlmIHNhbml0aXplZFRpbWVzdGFtcCA8PSBnZXRDdXJyZW50QmxvY2soKS50aW1lc3RhbXAgewogICAgICAgICAgICAgICAgcmV0dXJuIEVzdGltYXRlZFNjaGVkdWxlZFRyYW5zYWN0aW9uKAogICAgICAgICAgICAgICAgICAgICAgICAgICAgZmxvd0ZlZTogbmlsLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgdGltZXN0YW1wOiBuaWwsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBlcnJvcjogIkludmFsaWQgdGltZXN0YW1wOiBcKHNhbml0aXplZFRpbWVzdGFtcCkgaXMgaW4gdGhlIHBhc3QsIGN1cnJlbnQgdGltZXN0YW1wOiBcKGdldEN1cnJlbnRCbG9jaygpLnRpbWVzdGFtcCkiCiAgICAgICAgICAgICAgICAgICAgICAgICkKICAgICAgICAgICAgfQoKICAgICAgICAgICAgaWYgZXhlY3V0aW9uRWZmb3J0ID4gc2VsZi5jb25maWcubWF4aW11bUluZGl2aWR1YWxFZmZvcnQgewogICAgICAgICAgICAgICAgcmV0dXJuIEVzdGltYXRlZFNjaGVkdWxlZFRyYW5zYWN0aW9uKAogICAgICAgICAgICAgICAgICAgIGZsb3dGZWU6IG5pbCwKICAgICAgICAgICAgICAgICAgICB0aW1lc3RhbXA6IG5pbCwKICAgICAgICAgICAgICAgICAgICBlcnJvcjogIkludmFsaWQgZXhlY3V0aW9uIGVmZm9ydDogXChleGVjdXRpb25FZmZvcnQpIGlzIGdyZWF0ZXIgdGhhbiB0aGUgbWF4aW11bSB0cmFuc2FjdGlvbiBlZmZvcnQgb2YgXChzZWxmLmNvbmZpZy5tYXhpbXVtSW5kaXZpZHVhbEVmZm9ydCkiCiAgICAgICAgICAgICAgICApCiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGlmIGV4ZWN1dGlvbkVmZm9ydCA+IHNlbGYuY29uZmlnLnByaW9yaXR5RWZmb3J0TGltaXRbcHJpb3JpdHldISB7CiAgICAgICAgICAgICAgICByZXR1cm4gRXN0aW1hdGVkU2NoZWR1bGVkVHJhbnNhY3Rpb24oCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBmbG93RmVlOiBuaWwsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aW1lc3RhbXA6IG5pbCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVycm9yOiAiSW52YWxpZCBleGVjdXRpb24gZWZmb3J0OiBcKGV4ZWN1dGlvbkVmZm9ydCkgaXMgZ3JlYXRlciB0aGFuIHRoZSBwcmlvcml0eSdzIG1heCBlZmZvcnQgb2YgXChzZWxmLmNvbmZpZy5wcmlvcml0eUVmZm9ydExpbWl0W3ByaW9yaXR5XSEpIgogICAgICAgICAgICAgICAgICAgICAgICApCiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGlmIGV4ZWN1dGlvbkVmZm9ydCA8IHNlbGYuY29uZmlnLm1pbmltdW1FeGVjdXRpb25FZmZvcnQgewogICAgICAgICAgICAgICAgcmV0dXJuIEVzdGltYXRlZFNjaGVkdWxlZFRyYW5zYWN0aW9uKAogICAgICAgICAgICAgICAgICAgICAgICAgICAgZmxvd0ZlZTogbmlsLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgdGltZXN0YW1wOiBuaWwsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBlcnJvcjogIkludmFsaWQgZXhlY3V0aW9uIGVmZm9ydDogXChleGVjdXRpb25FZmZvcnQpIGlzIGxlc3MgdGhhbiB0aGUgbWluaW11bSBleGVjdXRpb24gZWZmb3J0IG9mIFwoc2VsZi5jb25maWcubWluaW11bUV4ZWN1dGlvbkVmZm9ydCkiCiAgICAgICAgICAgICAgICAgICAgICAgICkKICAgICAgICAgICAgfQoKICAgICAgICAgICAgbGV0IGRhdGFTaXplTUIgPSBGbG93VHJhbnNhY3Rpb25TY2hlZHVsZXIuZ2V0U2l6ZU9mRGF0YShkYXRhKQogICAgICAgICAgICBpZiBkYXRhU2l6ZU1CID4gc2VsZi5jb25maWcubWF4RGF0YVNpemVNQiB7CiAgICAgICAgICAgICAgICByZXR1cm4gRXN0aW1hdGVkU2NoZWR1bGVkVHJhbnNhY3Rpb24oCiAgICAgICAgICAgICAgICAgICAgZmxvd0ZlZTogbmlsLAogICAgICAgICAgICAgICAgICAgIHRpbWVzdGFtcDogbmlsLAogICAgICAgICAgICAgICAgICAgIGVycm9yOiAiSW52YWxpZCBkYXRhIHNpemU6IFwoZGF0YVNpemVNQikgaXMgZ3JlYXRlciB0aGFuIHRoZSBtYXhpbXVtIGRhdGEgc2l6ZSBvZiBcKHNlbGYuY29uZmlnLm1heERhdGFTaXplTUIpTUIiCiAgICAgICAgICAgICAgICApCiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGxldCBmZWUgPSBzZWxmLmNhbGN1bGF0ZUZlZShleGVjdXRpb25FZmZvcnQ6IGV4ZWN1dGlvbkVmZm9ydCwgcHJpb3JpdHk6IHByaW9yaXR5LCBkYXRhU2l6ZU1COiBkYXRhU2l6ZU1CKQoKICAgICAgICAgICAgbGV0IHNjaGVkdWxlZFRpbWVzdGFtcCA9IHNlbGYuY2FsY3VsYXRlU2NoZWR1bGVkVGltZXN0YW1wKAogICAgICAgICAgICAgICAgdGltZXN0YW1wOiBzYW5pdGl6ZWRUaW1lc3RhbXAsIAogICAgICAgICAgICAgICAgcHJpb3JpdHk6IHByaW9yaXR5LCAKICAgICAgICAgICAgICAgIGV4ZWN1dGlvbkVmZm9ydDogZXhlY3V0aW9uRWZmb3J0CiAgICAgICAgICAgICkKCiAgICAgICAgICAgIGlmIHNjaGVkdWxlZFRpbWVzdGFtcCA9PSBuaWwgewogICAgICAgICAgICAgICAgcmV0dXJuIEVzdGltYXRlZFNjaGVkdWxlZFRyYW5zYWN0aW9uKAogICAgICAgICAgICAgICAgICAgICAgICAgICAgZmxvd0ZlZTogbmlsLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgdGltZXN0YW1wOiBuaWwsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBlcnJvcjogIkludmFsaWQgZXhlY3V0aW9uIGVmZm9ydDogXChleGVjdXRpb25FZmZvcnQpIGlzIGdyZWF0ZXIgdGhhbiB0aGUgcHJpb3JpdHkncyBhdmFpbGFibGUgZWZmb3J0IGZvciB0aGUgcmVxdWVzdGVkIHRpbWVzdGFtcC4iCiAgICAgICAgICAgICAgICAgICAgICAgICkKICAgICAgICAgICAgfQoKICAgICAgICAgICAgcmV0dXJuIEVzdGltYXRlZFNjaGVkdWxlZFRyYW5zYWN0aW9uKGZsb3dGZWU6IGZlZSwgdGltZXN0YW1wOiBzY2hlZHVsZWRUaW1lc3RhbXAsIGVycm9yOiBuaWwpCiAgICAgICAgfQoKICAgICAgICAvLy8gY2FsY3VsYXRlU2NoZWR1bGVkVGltZXN0YW1wIGNhbGN1bGF0ZXMgdGhlIHRpbWVzdGFtcCBhdCB3aGljaCBhIHRyYW5zYWN0aW9uIAogICAgICAgIC8vLyBjYW4gYmUgc2NoZWR1bGVkLiBJdCB0YWtlcyBpbnRvIGFjY291bnQgdGhlIHByaW9yaXR5IG9mIHRoZSB0cmFuc2FjdGlvbiBhbmQgCiAgICAgICAgLy8vIHRoZSBleGVjdXRpb24gZWZmb3J0LgogICAgICAgIC8vLyAtIElmIHRoZSB0cmFuc2FjdGlvbiBpcyBoaWdoIHByaW9yaXR5LCBpdCByZXR1cm5zIHRoZSB0aW1lc3RhbXAgaWYgdGhlcmUgaXMgZW5vdWdoIAogICAgICAgIC8vLyAgICBzcGFjZSBvciBuaWwgaWYgdGhlcmUgaXMgbm8gc3BhY2UgbGVmdC4KICAgICAgICAvLy8gLSBJZiB0aGUgdHJhbnNhY3Rpb24gaXMgbWVkaXVtIG9yIGxvdyBwcmlvcml0eSBhbmQgdGhlcmUgaXMgc3BhY2UgbGVmdCBpbiB0aGUgcmVxdWVzdGVkIHRpbWVzdGFtcCwKICAgICAgICAvLy8gICBpdCByZXR1cm5zIHRoZSByZXF1ZXN0ZWQgdGltZXN0YW1wLiBJZiB0aGVyZSBpcyBub3QgZW5vdWdoIHNwYWNlLCBpdCBmaW5kcyB0aGUgbmV4dCB0aW1lc3RhbXAgd2l0aCBzcGFjZS4KICAgICAgICAvLy8KICAgICAgICAvLy8gQHBhcmFtIHRpbWVzdGFtcDogVGhlIHJlcXVlc3RlZCB0aW1lc3RhbXAgZm9yIHRoZSB0cmFuc2FjdGlvbgogICAgICAgIC8vLyBAcGFyYW0gcHJpb3JpdHk6IFRoZSBwcmlvcml0eSBvZiB0aGUgdHJhbnNhY3Rpb24KICAgICAgICAvLy8gQHBhcmFtIGV4ZWN1dGlvbkVmZm9ydDogVGhlIGV4ZWN1dGlvbiBlZmZvcnQgb2YgdGhlIHRyYW5zYWN0aW9uCiAgICAgICAgLy8vIEByZXR1cm4gVUZpeDY0PzogVGhlIHRpbWVzdGFtcCBhdCB3aGljaCB0aGUgdHJhbnNhY3Rpb24gY2FuIGJlIHNjaGVkdWxlZCwgb3IgbmlsIGlmIHRoZXJlIGlzIG5vIHNwYWNlIGxlZnQgZm9yIGEgaGlnaCBwcmlvcml0eSB0cmFuc2FjdGlvbgogICAgICAgIGFjY2Vzcyhjb250cmFjdCkgdmlldyBmdW4gY2FsY3VsYXRlU2NoZWR1bGVkVGltZXN0YW1wKAogICAgICAgICAgICB0aW1lc3RhbXA6IFVGaXg2NCwgCiAgICAgICAgICAgIHByaW9yaXR5OiBQcmlvcml0eSwgCiAgICAgICAgICAgIGV4ZWN1dGlvbkVmZm9ydDogVUludDY0CiAgICAgICAgKTogVUZpeDY0PyB7CgogICAgICAgICAgICB2YXIgdGltZXN0YW1wVG9TZWFyY2ggPSB0aW1lc3RhbXAKCiAgICAgICAgICAgIC8vIElmIG5vIGF2YWlsYWJsZSB0aW1lc3RhbXBzIGFyZSBmb3VuZCwgdGhpcyB3aWxsIGV2ZW50dWFsbHkgcmVhY2ggdGhlIGdhcyBsaW1pdCBhbmQgZmFpbAogICAgICAgICAgICAvLyBUaGlzIGlzIGV4dHJlbWVseSB1bmxpa2VseQogICAgICAgICAgICB3aGlsZSB0cnVlIHsKCiAgICAgICAgICAgICAgICBsZXQgdXNlZCA9IHNlbGYuc2xvdFVzZWRFZmZvcnRbdGltZXN0YW1wVG9TZWFyY2hdCiAgICAgICAgICAgICAgICAvLyBpZiBub3RoaW5nIGlzIHNjaGVkdWxlZCBhdCB0aGlzIHRpbWVzdGFtcCwgd2UgY2FuIHNjaGVkdWxlIGF0IHByb3ZpZGVkIHRpbWVzdGFtcAogICAgICAgICAgICAgICAgaWYgdXNlZCA9PSBuaWwgeyAKICAgICAgICAgICAgICAgICAgICByZXR1cm4gdGltZXN0YW1wVG9TZWFyY2gKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgbGV0IGF2YWlsYWJsZSA9IHNlbGYuZ2V0U2xvdEF2YWlsYWJsZUVmZm9ydChzYW5pdGl6ZWRUaW1lc3RhbXA6IHRpbWVzdGFtcFRvU2VhcmNoLCBwcmlvcml0eTogcHJpb3JpdHkpCiAgICAgICAgICAgICAgICAvLyBpZiB0aGVyZXMgZW5vdWdoIHNwYWNlLCB3ZSBjYW4gdGVudGF0aXZlbHkgc2NoZWR1bGUgYXQgcHJvdmlkZWQgdGltZXN0YW1wCiAgICAgICAgICAgICAgICBpZiBleGVjdXRpb25FZmZvcnQgPD0gYXZhaWxhYmxlIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gdGltZXN0YW1wVG9TZWFyY2gKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgaWYgcHJpb3JpdHkgPT0gUHJpb3JpdHkuSGlnaCB7CiAgICAgICAgICAgICAgICAgICAgLy8gaGlnaCBwcmlvcml0eSBkZW1hbmRzIHNjaGVkdWxpbmcgYXQgZXhhY3QgdGltZXN0YW1wIG9yIGZhaWxpbmcKICAgICAgICAgICAgICAgICAgICByZXR1cm4gbmlsCiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgdGltZXN0YW1wVG9TZWFyY2ggPSB0aW1lc3RhbXBUb1NlYXJjaCArIDEuMAogICAgICAgICAgICB9CgogICAgICAgICAgICAvLyBzaG91bGQgbmV2ZXIgaGFwcGVuCiAgICAgICAgICAgIHJldHVybiBuaWwKICAgICAgICB9CgogICAgICAgIC8vLyBzbG90IGF2YWlsYWJsZSBlZmZvcnQgcmV0dXJucyB0aGUgYW1vdW50IG9mIGVmZm9ydCB0aGF0IGlzIGF2YWlsYWJsZSBmb3IgYSBnaXZlbiB0aW1lc3RhbXAgYW5kIHByaW9yaXR5LgogICAgICAgIC8vLyBFYWNoIHByaW9yaXR5IGhhcyBpdHMgb3duIGluZGVwZW5kZW50IHBvb2wgd2l0aCBubyBzaGFyZWQgY2FwYWNpdHkgYmV0d2VlbiBwcmlvcml0aWVzLgogICAgICAgIC8vLyBAcGFyYW0gc2FuaXRpemVkVGltZXN0YW1wOiBUaGUgdGltZXN0YW1wIHRvIGdldCB0aGUgYXZhaWxhYmxlIGVmZm9ydCBmb3IuIEl0IHNob3VsZCBhbHJlYWR5IGhhdmUgYmVlbiBzYW5pdGl6ZWQKICAgICAgICAvLy8gICAgICAgICAgICAgICAgICAgICAgICAgICAgaW4gdGhlIGNhbGxpbmcgZnVuY3Rpb24KICAgICAgICAvLy8gQHBhcmFtIHByaW9yaXR5OiBUaGUgcHJpb3JpdHkgdG8gZ2V0IHRoZSBhdmFpbGFibGUgZWZmb3J0IGZvcgogICAgICAgIC8vLyBAcmV0dXJuIFVJbnQ2NDogVGhlIGFtb3VudCBvZiBlZmZvcnQgdGhhdCBpcyBhdmFpbGFibGUgZm9yIHRoZSBnaXZlbiB0aW1lc3RhbXAgYW5kIHByaW9yaXR5CiAgICAgICAgYWNjZXNzKGNvbnRyYWN0KSB2aWV3IGZ1biBnZXRTbG90QXZhaWxhYmxlRWZmb3J0KHNhbml0aXplZFRpbWVzdGFtcDogVUZpeDY0LCBwcmlvcml0eTogUHJpb3JpdHkpOiBVSW50NjQgewogICAgICAgICAgICBsZXQgbGltaXQgPSBzZWxmLmNvbmZpZy5wcmlvcml0eUVmZm9ydExpbWl0W3ByaW9yaXR5XSEKCiAgICAgICAgICAgIGlmICFzZWxmLnNsb3RVc2VkRWZmb3J0LmNvbnRhaW5zS2V5KHNhbml0aXplZFRpbWVzdGFtcCkgewogICAgICAgICAgICAgICAgcmV0dXJuIGxpbWl0CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGxldCBzbG90UHJpb3JpdHlFZmZvcnRzVXNlZCA9ICZzZWxmLnNsb3RVc2VkRWZmb3J0W3Nhbml0aXplZFRpbWVzdGFtcF0hIGFzICZ7UHJpb3JpdHk6IFVJbnQ2NH0KICAgICAgICAgICAgbGV0IHVzZWQgPSBzbG90UHJpb3JpdHlFZmZvcnRzVXNlZFtwcmlvcml0eV0gPz8gMAogICAgICAgICAgICByZXR1cm4gbGltaXQuc2F0dXJhdGluZ1N1YnRyYWN0KHVzZWQpCiAgICAgICAgfQoKICAgICAgICAvLy8gYWRkIHRyYW5zYWN0aW9uIHRvIHRoZSBxdWV1ZSBhbmQgdXBkYXRlcyBhbGwgdGhlIGludGVybmFsIHN0YXRlCiAgICAgICAgYWNjZXNzKHNlbGYpIGZ1biBhZGRUcmFuc2FjdGlvbihzbG90OiBVRml4NjQsIHR4RGF0YTogVHJhbnNhY3Rpb25EYXRhKSB7CgogICAgICAgICAgICAvLyBJZiBub3RoaW5nIGlzIGluIHRoZSBxdWV1ZSBmb3IgdGhpcyBzbG90LCBpbml0aWFsaXplIHRoZSBzbG90CiAgICAgICAgICAgIGlmIHNlbGYuc2xvdFF1ZXVlW3Nsb3RdID09IG5pbCB7CiAgICAgICAgICAgICAgICBzZWxmLnNsb3RRdWV1ZVtzbG90XSA9IHt9CgogICAgICAgICAgICAgICAgLy8gVGhpcyBhbHNvIG1lYW5zIHRoYXQgdGhlIHVzZWQgZWZmb3J0IHJlY29yZCBmb3IgdGhpcyBzbG90IGhhcyBub3QgYmVlbiBpbml0aWFsaXplZAogICAgICAgICAgICAgICAgc2VsZi5zbG90VXNlZEVmZm9ydFtzbG90XSA9IHsKICAgICAgICAgICAgICAgICAgICBQcmlvcml0eS5IaWdoOiAwLAogICAgICAgICAgICAgICAgICAgIFByaW9yaXR5Lk1lZGl1bTogMCwKICAgICAgICAgICAgICAgICAgICBQcmlvcml0eS5Mb3c6IDAKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICBzZWxmLnNvcnRlZFRpbWVzdGFtcHMuYWRkKHRpbWVzdGFtcDogc2xvdCkKICAgICAgICAgICAgfQoKICAgICAgICAgICAgLy8gQWRkIHRoaXMgdHJhbnNhY3Rpb24gaWQgdG8gdGhlIHNsb3QKICAgICAgICAgICAgbGV0IHRyYW5zYWN0aW9uc0ZvclNsb3QgPSBzZWxmLnNsb3RRdWV1ZVtzbG90XSEKICAgICAgICAgICAgaWYgbGV0IHByaW9yaXR5UXVldWUgPSB0cmFuc2FjdGlvbnNGb3JTbG90W3R4RGF0YS5wcmlvcml0eV0gewogICAgICAgICAgICAgICAgcHJpb3JpdHlRdWV1ZVt0eERhdGEuaWRdID0gdHhEYXRhLmV4ZWN1dGlvbkVmZm9ydAogICAgICAgICAgICAgICAgdHJhbnNhY3Rpb25zRm9yU2xvdFt0eERhdGEucHJpb3JpdHldID0gcHJpb3JpdHlRdWV1ZQogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgdHJhbnNhY3Rpb25zRm9yU2xvdFt0eERhdGEucHJpb3JpdHldID0gewogICAgICAgICAgICAgICAgICAgIHR4RGF0YS5pZDogdHhEYXRhLmV4ZWN1dGlvbkVmZm9ydAogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIHNlbGYuc2xvdFF1ZXVlW3Nsb3RdID0gdHJhbnNhY3Rpb25zRm9yU2xvdAoKICAgICAgICAgICAgLy8gQWRkIHRoZSBleGVjdXRpb24gZWZmb3J0IGZvciB0aGlzIHRyYW5zYWN0aW9uIHRvIHRoZSBwZXItcHJpb3JpdHkgdG90YWwgZm9yIHRoZSBzbG90LgogICAgICAgICAgICAvLyBOT1RFOiBUaGlzIGFkZGl0aW9uIGNhbm5vdCBvdmVyZmxvdyBpbiBwcmFjdGljZS4gZXhlY3V0aW9uRWZmb3J0IGlzIHZhbGlkYXRlZCBhZ2FpbnN0CiAgICAgICAgICAgIC8vIG1heGltdW1JbmRpdmlkdWFsRWZmb3J0IGFuZCBwcmlvcml0eUVmZm9ydExpbWl0IGJlZm9yZSByZWFjaGluZyB0aGlzIHBvaW50IChpbiBlc3RpbWF0ZSgpKSwKICAgICAgICAgICAgLy8gYW5kIHRoZSBjdW11bGF0aXZlIHNsb3QgdG90YWwgaXMgYm91bmRlZCBieSBwcmlvcml0eUVmZm9ydExpbWl0W3ByaW9yaXR5XSB3aGljaCBpcwogICAgICAgICAgICAvLyBjaGVja2VkIG9uIGV2ZXJ5IHNjaGVkdWxlKCkgY2FsbC4gVUludDY0IG1heCAofjEuOGUxOSkgZmFyIGV4Y2VlZHMgYW55IHJlYWNoYWJsZSBzdW0uCiAgICAgICAgICAgIGxldCBzbG90RWZmb3J0cyA9ICZzZWxmLnNsb3RVc2VkRWZmb3J0W3Nsb3RdISBhcyBhdXRoKE11dGF0ZSkgJntQcmlvcml0eTogVUludDY0fQogICAgICAgICAgICBsZXQgbmV3U2xvdEVmZm9ydCA9IHNsb3RFZmZvcnRzW3R4RGF0YS5wcmlvcml0eV0hICsgdHhEYXRhLmV4ZWN1dGlvbkVmZm9ydAoKICAgICAgICAgICAgLy8gVGhlIHBlci1wcmlvcml0eSBzbG90IHRvdGFsIG11c3QgbmV2ZXIgZXhjZWVkIHRoZSBjb25maWd1cmVkIGxpbWl0LgogICAgICAgICAgICAvLyBlc3RpbWF0ZSgpIGFscmVhZHkgZW5mb3JjZXMgdGhpcyBiZWZvcmUgc2NoZWR1bGUoKSByZXNlcnZlcyBjYXBhY2l0eSwgc28KICAgICAgICAgICAgLy8gdGhpcyBhc3NlcnRpb24gc2hvdWxkIGJlIHVucmVhY2hhYmxlOyBpdCBndWFyZHMgYWdhaW5zdCBhbnkgcmVlbnRyYW5jeSB2ZWN0b3IKICAgICAgICAgICAgLy8gdGhhdCByZWFjaGVzIGFkZFRyYW5zYWN0aW9uKCkgd2l0aG91dCBhIGZyZXNoIGNhcGFjaXR5IGNoZWNrLgogICAgICAgICAgICBsZXQgbGltaXQgPSBzZWxmLmNvbmZpZy5wcmlvcml0eUVmZm9ydExpbWl0W3R4RGF0YS5wcmlvcml0eV0hCiAgICAgICAgICAgIGFzc2VydCgKICAgICAgICAgICAgICAgIG5ld1Nsb3RFZmZvcnQgPD0gbGltaXQsCiAgICAgICAgICAgICAgICBtZXNzYWdlOiAiSW52YWxpZCBleGVjdXRpb24gZWZmb3J0OiBzY2hlZHVsaW5nIFwodHhEYXRhLmV4ZWN1dGlvbkVmZm9ydCkgd291bGQgcmFpc2UgdGhlIFwodHhEYXRhLnByaW9yaXR5LnJhd1ZhbHVlKSBwcmlvcml0eSBzbG90IHRvdGFsIHRvIFwobmV3U2xvdEVmZm9ydCksIGV4Y2VlZGluZyB0aGUgbGltaXQgb2YgXChsaW1pdCkuIgogICAgICAgICAgICApCgogICAgICAgICAgICBzbG90RWZmb3J0c1t0eERhdGEucHJpb3JpdHldID0gbmV3U2xvdEVmZm9ydAoKICAgICAgICAgICAgLy8gU3RvcmUgdGhlIHRyYW5zYWN0aW9uIGluIHRoZSB0cmFuc2FjdGlvbnMgbWFwCiAgICAgICAgICAgIHNlbGYudHJhbnNhY3Rpb25zW3R4RGF0YS5pZF0gPSB0eERhdGEKICAgICAgICB9CgogICAgICAgIC8vLyByZW1vdmUgdGhlIHRyYW5zYWN0aW9uIGZyb20gdGhlIHNsb3QgcXVldWUuCiAgICAgICAgYWNjZXNzKHNlbGYpIGZ1biByZW1vdmVUcmFuc2FjdGlvbih0eERhdGE6ICZUcmFuc2FjdGlvbkRhdGEpOiBUcmFuc2FjdGlvbkRhdGEgewoKICAgICAgICAgICAgbGV0IHRyYW5zYWN0aW9uSUQgPSB0eERhdGEuaWQKICAgICAgICAgICAgbGV0IHNsb3QgPSB0eERhdGEuc2NoZWR1bGVkVGltZXN0YW1wCiAgICAgICAgICAgIGxldCB0cmFuc2FjdGlvblByaW9yaXR5ID0gdHhEYXRhLnByaW9yaXR5CgogICAgICAgICAgICAvLyByZW1vdmUgdHJhbnNhY3Rpb24gb2JqZWN0CiAgICAgICAgICAgIGxldCB0cmFuc2FjdGlvbk9iamVjdCA9IHNlbGYudHJhbnNhY3Rpb25zLnJlbW92ZShrZXk6IHRyYW5zYWN0aW9uSUQpIQogICAgICAgICAgICAKICAgICAgICAgICAgLy8gZ2FyYmFnZSBjb2xsZWN0IHNsb3RzIAogICAgICAgICAgICBsZXQgdHJhbnNhY3Rpb25RdWV1ZSA9IHNlbGYuc2xvdFF1ZXVlW3Nsb3RdIQoKICAgICAgICAgICAgaWYgbGV0IHByaW9yaXR5UXVldWUgPSB0cmFuc2FjdGlvblF1ZXVlW3RyYW5zYWN0aW9uUHJpb3JpdHldIHsKICAgICAgICAgICAgICAgIHByaW9yaXR5UXVldWVbdHJhbnNhY3Rpb25JRF0gPSBuaWwKICAgICAgICAgICAgICAgIGlmIHByaW9yaXR5UXVldWUua2V5cy5sZW5ndGggPT0gMCB7CiAgICAgICAgICAgICAgICAgICAgdHJhbnNhY3Rpb25RdWV1ZS5yZW1vdmUoa2V5OiB0cmFuc2FjdGlvblByaW9yaXR5KQogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICB0cmFuc2FjdGlvblF1ZXVlW3RyYW5zYWN0aW9uUHJpb3JpdHldID0gcHJpb3JpdHlRdWV1ZQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIHNlbGYuc2xvdFF1ZXVlW3Nsb3RdID0gdHJhbnNhY3Rpb25RdWV1ZQoKICAgICAgICAgICAgLy8gaWYgdGhlIHNsb3QgaXMgbm93IGVtcHR5IHJlbW92ZSBpdCBmcm9tIHRoZSBtYXBzCiAgICAgICAgICAgIGlmIHRyYW5zYWN0aW9uUXVldWUua2V5cy5sZW5ndGggPT0gMCB7CiAgICAgICAgICAgICAgICBzZWxmLnNsb3RRdWV1ZS5yZW1vdmUoa2V5OiBzbG90KQogICAgICAgICAgICAgICAgc2VsZi5zbG90VXNlZEVmZm9ydC5yZW1vdmUoa2V5OiBzbG90KQoKICAgICAgICAgICAgICAgIHNlbGYuc29ydGVkVGltZXN0YW1wcy5yZW1vdmUodGltZXN0YW1wOiBzbG90KQogICAgICAgICAgICB9CgogICAgICAgICAgICByZXR1cm4gdHJhbnNhY3Rpb25PYmplY3QKICAgICAgICB9CgogICAgICAgIC8vLyBwZW5kaW5nUXVldWUgY3JlYXRlcyBhIGxpc3Qgb2YgdHJhbnNhY3Rpb25zIHRoYXQgYXJlIHJlYWR5IGZvciBleGVjdXRpb24uCiAgICAgICAgLy8vIEZvciB0cmFuc2FjdGlvbiB0byBiZSByZWFkeSBmb3IgZXhlY3V0aW9uIGl0IG11c3QgYmUgc2NoZWR1bGVkLgogICAgICAgIC8vLwogICAgICAgIC8vLyBUaGUgcXVldWUgaXMgc29ydGVkIGJ5IHRpbWVzdGFtcCBhbmQgdGhlbiBieSBwcmlvcml0eSAoaGlnaCwgbWVkaXVtLCBsb3cpLgogICAgICAgIC8vLyBUaGUgcXVldWUgd2lsbCBjb250YWluIHRyYW5zYWN0aW9ucyBmcm9tIGFsbCB0aW1lc3RhbXBzIHRoYXQgYXJlIGluIHRoZSBwYXN0LgogICAgICAgIC8vLyBMb3cgcHJpb3JpdHkgdHJhbnNhY3Rpb25zIHdpbGwgb25seSBiZSBhZGRlZCBpZiB0aGVyZSBpcyBlZmZvcnQgYXZhaWxhYmxlIGluIHRoZSBzbG90LiAgCiAgICAgICAgLy8vIFRoZSByZXR1cm4gdmFsdWUgY2FuIGJlIGVtcHR5IGlmIHRoZXJlIGFyZSBubyB0cmFuc2FjdGlvbnMgcmVhZHkgZm9yIGV4ZWN1dGlvbi4KICAgICAgICBhY2Nlc3MoUHJvY2VzcykgZnVuIHBlbmRpbmdRdWV1ZSgpOiBbJlRyYW5zYWN0aW9uRGF0YV0gewogICAgICAgICAgICBsZXQgY3VycmVudFRpbWVzdGFtcCA9IGdldEN1cnJlbnRCbG9jaygpLnRpbWVzdGFtcAogICAgICAgICAgICB2YXIgcGVuZGluZ1RyYW5zYWN0aW9uczogWyZUcmFuc2FjdGlvbkRhdGFdID0gW10KCiAgICAgICAgICAgIC8vIHRvdGFsIGVmZm9ydCBhY3Jvc3MgZGlmZmVyZW50IHRpbWVzdGFtcHMgZ3VhcmRzIGNvbGxlY3Rpb24gYmVpbmcgb3ZlciB0aGUgZWZmb3J0IGxpbWl0CiAgICAgICAgICAgIHZhciBjb2xsZWN0aW9uQXZhaWxhYmxlRWZmb3J0ID0gc2VsZi5jb25maWcuY29sbGVjdGlvbkVmZm9ydExpbWl0CiAgICAgICAgICAgIHZhciB0cmFuc2FjdGlvbnNBdmFpbGFibGVDb3VudCA9IHNlbGYuY29uZmlnLmNvbGxlY3Rpb25UcmFuc2FjdGlvbnNMaW1pdAoKICAgICAgICAgICAgLy8gQ29sbGVjdCBwYXN0IHRpbWVzdGFtcHMgZWZmaWNpZW50bHkgZnJvbSBzb3J0ZWQgYXJyYXkKICAgICAgICAgICAgbGV0IHBhc3RUaW1lc3RhbXBzID0gc2VsZi5zb3J0ZWRUaW1lc3RhbXBzLmdldEJlZm9yZShjdXJyZW50OiBjdXJyZW50VGltZXN0YW1wKQoKICAgICAgICAgICAgZm9yIHRpbWVzdGFtcCBpbiBwYXN0VGltZXN0YW1wcyB7CiAgICAgICAgICAgICAgICBsZXQgdHJhbnNhY3Rpb25Qcmlvcml0aWVzID0gc2VsZi5zbG90UXVldWVbdGltZXN0YW1wXSA/PyB7fQogICAgICAgICAgICAgICAgdmFyIGhpZ2g6IFsmVHJhbnNhY3Rpb25EYXRhXSA9IFtdCiAgICAgICAgICAgICAgICB2YXIgbWVkaXVtOiBbJlRyYW5zYWN0aW9uRGF0YV0gPSBbXQogICAgICAgICAgICAgICAgdmFyIGxvdzogWyZUcmFuc2FjdGlvbkRhdGFdID0gW10KCiAgICAgICAgICAgICAgICBmb3IgcHJpb3JpdHkgaW4gdHJhbnNhY3Rpb25Qcmlvcml0aWVzIHsKICAgICAgICAgICAgICAgICAgICBsZXQgdHJhbnNhY3Rpb25JRHMgPSB0cmFuc2FjdGlvblByaW9yaXRpZXNbcHJpb3JpdHldID8/IHt9CiAgICAgICAgICAgICAgICAgICAgZm9yIGlkIGluIHRyYW5zYWN0aW9uSURzIHsKICAgICAgICAgICAgICAgICAgICAgICAgbGV0IHR4ID0gc2VsZi5ib3Jyb3dUcmFuc2FjdGlvbihpZDogaWQpCiAgICAgICAgICAgICAgICAgICAgICAgIGlmIHR4ID09IG5pbCB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbWl0IENyaXRpY2FsSXNzdWUobWVzc2FnZTogIkludmFsaWQgSUQ6IFwoaWQpIHRyYW5zYWN0aW9uIG5vdCBmb3VuZCB3aGlsZSBwcmVwYXJpbmcgcGVuZGluZyBxdWV1ZSIpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb250aW51ZQogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAvLyBPbmx5IGFkZCBzY2hlZHVsZWQgdHJhbnNhY3Rpb25zIHRvIHRoZSBxdWV1ZQogICAgICAgICAgICAgICAgICAgICAgICBpZiB0eCEuc3RhdHVzICE9IFN0YXR1cy5TY2hlZHVsZWQgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgY29udGludWUKICAgICAgICAgICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICAgICAgICAgLy8gdGhpcyBpcyBzYWZlZ3VhcmQgdG8gcHJldmVudCBjb2xsZWN0aW9uIGdyb3dpbmcgdG9vIGxhcmdlIGluIGNhc2Ugb2YgYmxvY2sgcHJvZHVjdGlvbiBzbG93ZG93bgogICAgICAgICAgICAgICAgICAgICAgICBpZiB0eCEuZXhlY3V0aW9uRWZmb3J0ID49IGNvbGxlY3Rpb25BdmFpbGFibGVFZmZvcnQgfHwgdHJhbnNhY3Rpb25zQXZhaWxhYmxlQ291bnQgPT0gMCB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbWl0IENvbGxlY3Rpb25MaW1pdFJlYWNoZWQoCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29sbGVjdGlvbkVmZm9ydExpbWl0OiB0cmFuc2FjdGlvbnNBdmFpbGFibGVDb3VudCA9PSAwID8gbmlsIDogc2VsZi5jb25maWcuY29sbGVjdGlvbkVmZm9ydExpbWl0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbGxlY3Rpb25UcmFuc2FjdGlvbnNMaW1pdDogdHJhbnNhY3Rpb25zQXZhaWxhYmxlQ291bnQgPT0gMCA/IHNlbGYuY29uZmlnLmNvbGxlY3Rpb25UcmFuc2FjdGlvbnNMaW1pdCA6IG5pbAogICAgICAgICAgICAgICAgICAgICAgICAgICAgKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWsKICAgICAgICAgICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICAgICAgICAgY29sbGVjdGlvbkF2YWlsYWJsZUVmZm9ydCA9IGNvbGxlY3Rpb25BdmFpbGFibGVFZmZvcnQuc2F0dXJhdGluZ1N1YnRyYWN0KHR4IS5leGVjdXRpb25FZmZvcnQpCiAgICAgICAgICAgICAgICAgICAgICAgIHRyYW5zYWN0aW9uc0F2YWlsYWJsZUNvdW50ID0gdHJhbnNhY3Rpb25zQXZhaWxhYmxlQ291bnQgLSAxCiAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgIHN3aXRjaCB0eCEucHJpb3JpdHkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSBQcmlvcml0eS5IaWdoOgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGhpZ2guYXBwZW5kKHR4ISkKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgUHJpb3JpdHkuTWVkaXVtOgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1lZGl1bS5hcHBlbmQodHghKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSBQcmlvcml0eS5Mb3c6CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbG93LmFwcGVuZCh0eCEpCiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgcGVuZGluZ1RyYW5zYWN0aW9ucyA9IHBlbmRpbmdUcmFuc2FjdGlvbnMKICAgICAgICAgICAgICAgICAgICAuY29uY2F0KGhpZ2gpCiAgICAgICAgICAgICAgICAgICAgLmNvbmNhdChtZWRpdW0pCiAgICAgICAgICAgICAgICAgICAgLmNvbmNhdChsb3cpCiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHJldHVybiBwZW5kaW5nVHJhbnNhY3Rpb25zCiAgICAgICAgfQoKICAgICAgICAvLy8gcmVtb3ZlRXhlY3V0ZWRUcmFuc2FjdGlvbnMgcmVtb3ZlcyBhbGwgdHJhbnNhY3Rpb25zIHRoYXQgYXJlIG1hcmtlZCBhcyBleGVjdXRlZC4KICAgICAgICBhY2Nlc3Moc2VsZikgZnVuIHJlbW92ZUV4ZWN1dGVkVHJhbnNhY3Rpb25zKF8gY3VycmVudFRpbWVzdGFtcDogVUZpeDY0KSB7CiAgICAgICAgICAgIGxldCBwYXN0VGltZXN0YW1wcyA9IHNlbGYuc29ydGVkVGltZXN0YW1wcy5nZXRCZWZvcmUoY3VycmVudDogY3VycmVudFRpbWVzdGFtcCkKICAgICAgICAgICAgdmFyIG51bVJlbW92ZWQgPSAwCiAgICAgICAgICAgIGxldCByZW1vdmFsTGltaXQgPSBzZWxmLmNvbmZpZy5nZXRUeFJlbW92YWxMaW1pdCgpCgogICAgICAgICAgICBmb3IgdGltZXN0YW1wIGluIHBhc3RUaW1lc3RhbXBzIHsKICAgICAgICAgICAgICAgIGxldCB0cmFuc2FjdGlvblByaW9yaXRpZXMgPSBzZWxmLnNsb3RRdWV1ZVt0aW1lc3RhbXBdID8/IHt9CiAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgIGZvciBwcmlvcml0eSBpbiB0cmFuc2FjdGlvblByaW9yaXRpZXMgewogICAgICAgICAgICAgICAgICAgIGxldCB0cmFuc2FjdGlvbklEcyA9IHRyYW5zYWN0aW9uUHJpb3JpdGllc1twcmlvcml0eV0gPz8ge30KICAgICAgICAgICAgICAgICAgICBmb3IgaWQgaW4gdHJhbnNhY3Rpb25JRHMgewoKICAgICAgICAgICAgICAgICAgICAgICAgbnVtUmVtb3ZlZCA9IG51bVJlbW92ZWQgKyAxCgogICAgICAgICAgICAgICAgICAgICAgICBpZiBVSW50KG51bVJlbW92ZWQpID49IHJlbW92YWxMaW1pdCB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbWl0IFJlbW92YWxMaW1pdFJlYWNoZWQoKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuCiAgICAgICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgICAgIGxldCB0eCA9IHNlbGYuYm9ycm93VHJhbnNhY3Rpb24oaWQ6IGlkKQogICAgICAgICAgICAgICAgICAgICAgICBpZiB0eCA9PSBuaWwgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgZW1pdCBDcml0aWNhbElzc3VlKG1lc3NhZ2U6ICJJbnZhbGlkIElEOiBcKGlkKSB0cmFuc2FjdGlvbiBub3QgZm91bmQgd2hpbGUgcmVtb3ZpbmcgZXhlY3V0ZWQgdHJhbnNhY3Rpb25zIikKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlCiAgICAgICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgICAgIC8vIE9ubHkgcmVtb3ZlIGV4ZWN1dGVkIHRyYW5zYWN0aW9ucwogICAgICAgICAgICAgICAgICAgICAgICBpZiB0eCEuc3RhdHVzICE9IFN0YXR1cy5FeGVjdXRlZCB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb250aW51ZQogICAgICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgICAgICAvLyBjaGFyZ2UgdGhlIGZ1bGwgZmVlIGZvciB0cmFuc2FjdGlvbiBleGVjdXRpb24KICAgICAgICAgICAgICAgICAgICAgICAgZGVzdHJveSB0eCEucGF5QW5kUmVmdW5kRmVlcyhyZWZ1bmRNdWx0aXBsaWVyOiAwLjApCgogICAgICAgICAgICAgICAgICAgICAgICBzZWxmLnJlbW92ZVRyYW5zYWN0aW9uKHR4RGF0YTogdHghKQogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgLy8vIHByb2Nlc3Mgc2NoZWR1bGVkIHRyYW5zYWN0aW9ucyBhbmQgcHJlcGFyZSB0aGVtIGZvciBleGVjdXRpb24uIAogICAgICAgIC8vLwogICAgICAgIC8vLyBGaXJzdCwgaXQgcmVtb3ZlcyB0cmFuc2FjdGlvbnMgdGhhdCBoYXZlIGFscmVhZHkgYmVlbiBleGVjdXRlZC4gCiAgICAgICAgLy8vIFRoZW4sIGl0IGl0ZXJhdGVzIG92ZXIgcGFzdCB0aW1lc3RhbXBzIGluIHRoZSBxdWV1ZSBhbmQgcHJvY2Vzc2VzIHRoZSB0cmFuc2FjdGlvbnMgdGhhdCBhcmUgCiAgICAgICAgLy8vIGVsaWdpYmxlIGZvciBleGVjdXRpb24uIEl0IGFsc28gZW1pdHMgYW4gZXZlbnQgZm9yIGVhY2ggdHJhbnNhY3Rpb24gdGhhdCBpcyBwcm9jZXNzZWQuCiAgICAgICAgLy8vCiAgICAgICAgLy8vIFRoaXMgZnVuY3Rpb24gaXMgb25seSBjYWxsZWQgYnkgdGhlIEZWTSB0byBwcm9jZXNzIHRyYW5zYWN0aW9ucy4KICAgICAgICBhY2Nlc3MoUHJvY2VzcykgZnVuIHByb2Nlc3MoKSB7CiAgICAgICAgICAgIGxldCBjdXJyZW50VGltZXN0YW1wID0gZ2V0Q3VycmVudEJsb2NrKCkudGltZXN0YW1wCiAgICAgICAgICAgIC8vIEVhcmx5IGV4aXQgaWYgbm8gdGltZXN0YW1wcyBuZWVkIHByb2Nlc3NpbmcKICAgICAgICAgICAgaWYgIXNlbGYuc29ydGVkVGltZXN0YW1wcy5oYXNCZWZvcmUoY3VycmVudDogY3VycmVudFRpbWVzdGFtcCkgewogICAgICAgICAgICAgICAgcmV0dXJuCiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHNlbGYucmVtb3ZlRXhlY3V0ZWRUcmFuc2FjdGlvbnMoY3VycmVudFRpbWVzdGFtcCkKCiAgICAgICAgICAgIGxldCBwZW5kaW5nVHJhbnNhY3Rpb25zID0gc2VsZi5wZW5kaW5nUXVldWUoKQoKICAgICAgICAgICAgZm9yIHR4IGluIHBlbmRpbmdUcmFuc2FjdGlvbnMgewoKICAgICAgICAgICAgICAgIGVtaXQgUGVuZGluZ0V4ZWN1dGlvbigKICAgICAgICAgICAgICAgICAgICBpZDogdHguaWQsCiAgICAgICAgICAgICAgICAgICAgcHJpb3JpdHk6IHR4LnByaW9yaXR5LnJhd1ZhbHVlLAogICAgICAgICAgICAgICAgICAgIGV4ZWN1dGlvbkVmZm9ydDogdHguZXhlY3V0aW9uRWZmb3J0LAogICAgICAgICAgICAgICAgICAgIGZlZXM6IHR4LmZlZXMsCiAgICAgICAgICAgICAgICAgICAgdHJhbnNhY3Rpb25IYW5kbGVyT3duZXI6IHR4LmhhbmRsZXIuYWRkcmVzcywKICAgICAgICAgICAgICAgICAgICAvLyBDYW5ub3QgdXNlIHRoZSByZWFsIHR5cGUgaWRlbnRpZmllciBoZXJlIGJlY2F1c2UgaWYKICAgICAgICAgICAgICAgICAgICAvLyB0aGUgaGFuZGxlciBjb250cmFjdCBpcyBicm9rZW4sIGl0IGNvdWxkIGNhdXNlIHRoZSBwcm9jZXNzIGZ1bmN0aW9uIHRvIGZhaWwKICAgICAgICAgICAgICAgICAgICB0cmFuc2FjdGlvbkhhbmRsZXJUeXBlSWRlbnRpZmllcjogIiIKICAgICAgICAgICAgICAgICkKCiAgICAgICAgICAgICAgICAvLyBhZnRlciBwZW5kaW5nIGV4ZWN1dGlvbiBldmVudCBpcyBlbWl0dGVkIHdlIHNldCB0aGUgdHJhbnNhY3Rpb24gYXMgZXhlY3V0ZWQgYmVjYXVzZSB3ZSAKICAgICAgICAgICAgICAgIC8vIG11c3QgcmVseSBvbiBleGVjdXRpb24gbm9kZSB0byBhY3R1YWxseSBleGVjdXRlIGl0LiBFeGVjdXRpb24gb2YgdGhlIHRyYW5zYWN0aW9uIGlzIAogICAgICAgICAgICAgICAgLy8gZG9uZSBpbiBhIHNlcGFyYXRlIHRyYW5zYWN0aW9uIHRoYXQgY2FsbHMgZXhlY3V0ZVRyYW5zYWN0aW9uKGlkKSBmdW5jdGlvbi4KICAgICAgICAgICAgICAgIC8vIEV4ZWN1dGluZyB0aGUgdHJhbnNhY3Rpb24gY2FuIG5vdCB1cGRhdGUgdGhlIHN0YXR1cyBvZiB0cmFuc2FjdGlvbiBvciBhbnkgb3RoZXIgc2hhcmVkIHN0YXRlLAogICAgICAgICAgICAgICAgLy8gc2luY2UgdGhhdCBibG9ja3MgY29uY3VycmVudCB0cmFuc2FjdGlvbiBleGVjdXRpb24uCiAgICAgICAgICAgICAgICAvLyBUaGVyZWZvcmUgYW4gb3B0aW1pc3RpYyB1cGRhdGUgdG8gZXhlY3V0ZWQgaXMgbWFkZSBoZXJlIHRvIGF2b2lkIHJhY2UgY29uZGl0aW9uLgogICAgICAgICAgICAgICAgdHguc2V0U3RhdHVzKG5ld1N0YXR1czogU3RhdHVzLkV4ZWN1dGVkKQogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICAvLy8gY2FuY2VsIGEgc2NoZWR1bGVkIHRyYW5zYWN0aW9uIGFuZCByZXR1cm4gYSBwb3J0aW9uIG9mIHRoZSBmZWVzIHRoYXQgd2VyZSBwYWlkLgogICAgICAgIC8vLwogICAgICAgIC8vLyBAcGFyYW0gaWQ6IFRoZSBJRCBvZiB0aGUgdHJhbnNhY3Rpb24gdG8gY2FuY2VsCiAgICAgICAgLy8vIEByZXR1cm46IFRoZSBmZWVzIHRvIGJlIHJldHVybmVkIHRvIHRoZSBjYWxsZXIKICAgICAgICBhY2Nlc3MoQ2FuY2VsKSBmdW4gY2FuY2VsKGlkOiBVSW50NjQpOiBARmxvd1Rva2VuLlZhdWx0IHsKICAgICAgICAgICAgbGV0IHR4ID0gc2VsZi5ib3Jyb3dUcmFuc2FjdGlvbihpZDogaWQpID8/IAogICAgICAgICAgICAgICAgcGFuaWMoIkludmFsaWQgSUQ6IFwoaWQpIHRyYW5zYWN0aW9uIG5vdCBmb3VuZCIpCgogICAgICAgICAgICBhc3NlcnQoCiAgICAgICAgICAgICAgICB0eC5zdGF0dXMgPT0gU3RhdHVzLlNjaGVkdWxlZCwKICAgICAgICAgICAgICAgIG1lc3NhZ2U6ICJUcmFuc2FjdGlvbiBtdXN0IGJlIGluIGEgc2NoZWR1bGVkIHN0YXRlIGluIG9yZGVyIHRvIGJlIGNhbmNlbGVkIgogICAgICAgICAgICApCiAgICAgICAgICAgIAogICAgICAgICAgICAvLyBTdWJ0cmFjdCB0aGUgZXhlY3V0aW9uIGVmZm9ydCBmb3IgdGhpcyB0cmFuc2FjdGlvbiBmcm9tIHRoZSBzbG90J3MgcHJpb3JpdHkKICAgICAgICAgICAgbGV0IHNsb3RFZmZvcnRzID0gc2VsZi5zbG90VXNlZEVmZm9ydFt0eC5zY2hlZHVsZWRUaW1lc3RhbXBdIQogICAgICAgICAgICBzbG90RWZmb3J0c1t0eC5wcmlvcml0eV0gPSBzbG90RWZmb3J0c1t0eC5wcmlvcml0eV0hLnNhdHVyYXRpbmdTdWJ0cmFjdCh0eC5leGVjdXRpb25FZmZvcnQpCiAgICAgICAgICAgIHNlbGYuc2xvdFVzZWRFZmZvcnRbdHguc2NoZWR1bGVkVGltZXN0YW1wXSA9IHNsb3RFZmZvcnRzCgogICAgICAgICAgICBsZXQgdG90YWxGZWVzID0gdHguZmVlcwogICAgICAgICAgICBsZXQgcmVmdW5kZWRGZWVzIDwtIHR4LnBheUFuZFJlZnVuZEZlZXMocmVmdW5kTXVsdGlwbGllcjogc2VsZi5jb25maWcucmVmdW5kTXVsdGlwbGllcikKCiAgICAgICAgICAgIC8vIGlmIHRoZSB0cmFuc2FjdGlvbiB3YXMgY2FuY2VsZWQsIGFkZCBpdCB0byB0aGUgY2FuY2VsZWQgdHJhbnNhY3Rpb25zIGFycmF5CiAgICAgICAgICAgIC8vIG1haW50YWluIHNvcnRlZCBvcmRlciBieSBpbnNlcnRpbmcgYXQgdGhlIGNvcnJlY3QgcG9zaXRpb24KCQkJdmFyIGhpZ2ggPSBzZWxmLmNhbmNlbGVkVHJhbnNhY3Rpb25zLmxlbmd0aAoJCQl2YXIgbG93ID0gMAoJCQl3aGlsZSBsb3cgPCBoaWdoIHsKCQkJCWxldCBtaWQgPSAobG93K2hpZ2gpLzIKCQkJCWxldCBtaWRDYW5jZWxlZElEID0gc2VsZi5jYW5jZWxlZFRyYW5zYWN0aW9uc1ttaWRdCgoJCQkJaWYgbWlkQ2FuY2VsZWRJRCA9PSBpZCB7CiAgICAgICAgICAgICAgICAgICAgZW1pdCBDcml0aWNhbElzc3VlKG1lc3NhZ2U6ICJJbnZhbGlkIElEOiBcKGlkKSB0cmFuc2FjdGlvbiBhbHJlYWR5IGluIGNhbmNlbGVkIHRyYW5zYWN0aW9ucyBhcnJheSIpCiAgICAgICAgICAgICAgICAgICAgYnJlYWsKICAgICAgICAgICAgICAgIH0gZWxzZSBpZiBtaWRDYW5jZWxlZElEID4gaWQgewoJCQkJCWhpZ2ggPSBtaWQKCQkJCX0gZWxzZSB7CgkJCQkJbG93ID0gbWlkICsgMQoJCQkJfQoJCQl9CiAgICAgICAgICAgIHNlbGYuY2FuY2VsZWRUcmFuc2FjdGlvbnMuaW5zZXJ0KGF0OiBsb3csIGlkKQogICAgICAgICAgICAKICAgICAgICAgICAgLy8ga2VlcCB0aGUgYXJyYXkgdW5kZXIgdGhlIGxpbWl0CiAgICAgICAgICAgIGlmIFVJbnQoc2VsZi5jYW5jZWxlZFRyYW5zYWN0aW9ucy5sZW5ndGgpID4gc2VsZi5jb25maWcuY2FuY2VsZWRUcmFuc2FjdGlvbnNMaW1pdCB7CiAgICAgICAgICAgICAgICBzZWxmLmNhbmNlbGVkVHJhbnNhY3Rpb25zLnJlbW92ZShhdDogMCkKICAgICAgICAgICAgfQoKICAgICAgICAgICAgZW1pdCBDYW5jZWxlZCgKICAgICAgICAgICAgICAgIGlkOiB0eC5pZCwKICAgICAgICAgICAgICAgIHByaW9yaXR5OiB0eC5wcmlvcml0eS5yYXdWYWx1ZSwKICAgICAgICAgICAgICAgIGZlZXNSZXR1cm5lZDogcmVmdW5kZWRGZWVzLmJhbGFuY2UsCiAgICAgICAgICAgICAgICBmZWVzRGVkdWN0ZWQ6IHRvdGFsRmVlcyAtIHJlZnVuZGVkRmVlcy5iYWxhbmNlLAogICAgICAgICAgICAgICAgdHJhbnNhY3Rpb25IYW5kbGVyT3duZXI6IHR4LmhhbmRsZXIuYWRkcmVzcywKICAgICAgICAgICAgICAgIHRyYW5zYWN0aW9uSGFuZGxlclR5cGVJZGVudGlmaWVyOiB0eC5oYW5kbGVyVHlwZUlkZW50aWZpZXIKICAgICAgICAgICAgKQoKICAgICAgICAgICAgc2VsZi5yZW1vdmVUcmFuc2FjdGlvbih0eERhdGE6IHR4KQogICAgICAgICAgICAKICAgICAgICAgICAgcmV0dXJuIDwtcmVmdW5kZWRGZWVzCiAgICAgICAgfQoKICAgICAgICAvLy8gZXhlY3V0ZSB0cmFuc2FjdGlvbiBpcyBhIHN5c3RlbSBmdW5jdGlvbiB0aGF0IGlzIGNhbGxlZCBieSBGVk0gdG8gZXhlY3V0ZSBhIHRyYW5zYWN0aW9uIGJ5IElELgogICAgICAgIC8vLyBUaGUgdHJhbnNhY3Rpb24gbXVzdCBiZSBmb3VuZCBhbmQgaW4gY29ycmVjdCBzdGF0ZSBvciB0aGUgZnVuY3Rpb24gcGFuaWNzIGFuZCB0aGlzIGlzIGEgZmF0YWwgZXJyb3IKICAgICAgICAvLy8KICAgICAgICAvLy8gVGhpcyBmdW5jdGlvbiBpcyBvbmx5IGNhbGxlZCBieSB0aGUgRlZNIHRvIGV4ZWN1dGUgdHJhbnNhY3Rpb25zLgogICAgICAgIC8vLyBXQVJOSU5HOiB0aGlzIGZ1bmN0aW9uIHNob3VsZCBub3QgY2hhbmdlIGFueSBzaGFyZWQgc3RhdGUsIGl0IHdpbGwgYmUgcnVuIGNvbmN1cnJlbnRseSBhbmQgaXQgbXVzdCBub3QgYmUgYmxvY2tpbmcuCiAgICAgICAgYWNjZXNzKEV4ZWN1dGUpIGZ1biBleGVjdXRlVHJhbnNhY3Rpb24oaWQ6IFVJbnQ2NCkgewogICAgICAgICAgICBsZXQgdHggPSBzZWxmLmJvcnJvd1RyYW5zYWN0aW9uKGlkOiBpZCkgPz8gCiAgICAgICAgICAgICAgICBwYW5pYygiSW52YWxpZCBJRDogVHJhbnNhY3Rpb24gd2l0aCBpZCBcKGlkKSBub3QgZm91bmQiKQoKICAgICAgICAgICAgYXNzZXJ0ICgKICAgICAgICAgICAgICAgIHR4LnN0YXR1cyA9PSBTdGF0dXMuRXhlY3V0ZWQsCiAgICAgICAgICAgICAgICBtZXNzYWdlOiAiSW52YWxpZCBJRDogQ2Fubm90IGV4ZWN1dGUgdHJhbnNhY3Rpb24gd2l0aCBpZCBcKGlkKSBiZWNhdXNlIGl0IGhhcyBpbmNvcnJlY3Qgc3RhdHVzIFwodHguc3RhdHVzLnJhd1ZhbHVlKSIKICAgICAgICAgICAgKQoKICAgICAgICAgICAgbGV0IHRyYW5zYWN0aW9uSGFuZGxlciA9IHR4LmhhbmRsZXIuYm9ycm93KCkKICAgICAgICAgICAgICAgID8/IHBhbmljKCJJbnZhbGlkIHRyYW5zYWN0aW9uIGhhbmRsZXI6IENvdWxkIG5vdCBib3Jyb3cgYSByZWZlcmVuY2UgdG8gdGhlIHRyYW5zYWN0aW9uIGhhbmRsZXIiKQoKICAgICAgICAgICAgbGV0IGhhbmRsZXJQdWJsaWNQYXRoID0gdHJhbnNhY3Rpb25IYW5kbGVyLnJlc29sdmVWaWV3KFR5cGU8UHVibGljUGF0aD4oKSkgYXM/IFB1YmxpY1BhdGgKCiAgICAgICAgICAgIGVtaXQgRXhlY3V0ZWQoCiAgICAgICAgICAgICAgICBpZDogdHguaWQsCiAgICAgICAgICAgICAgICBwcmlvcml0eTogdHgucHJpb3JpdHkucmF3VmFsdWUsCiAgICAgICAgICAgICAgICBleGVjdXRpb25FZmZvcnQ6IHR4LmV4ZWN1dGlvbkVmZm9ydCwKICAgICAgICAgICAgICAgIHRyYW5zYWN0aW9uSGFuZGxlck93bmVyOiB0eC5oYW5kbGVyLmFkZHJlc3MsCiAgICAgICAgICAgICAgICB0cmFuc2FjdGlvbkhhbmRsZXJUeXBlSWRlbnRpZmllcjogdHJhbnNhY3Rpb25IYW5kbGVyLmdldFR5cGUoKS5pZGVudGlmaWVyLAogICAgICAgICAgICAgICAgdHJhbnNhY3Rpb25IYW5kbGVyVVVJRDogdHJhbnNhY3Rpb25IYW5kbGVyLnV1aWQsCiAgICAgICAgICAgICAgICB0cmFuc2FjdGlvbkhhbmRsZXJQdWJsaWNQYXRoOiBoYW5kbGVyUHVibGljUGF0aAoKICAgICAgICAgICAgKQogICAgICAgICAgICAKICAgICAgICAgICAgdHJhbnNhY3Rpb25IYW5kbGVyLmV4ZWN1dGVUcmFuc2FjdGlvbihpZDogaWQsIGRhdGE6IHR4LmdldERhdGEoKSkKICAgICAgICB9CiAgICB9CiAgICAKICAgIC8vLyBEZXBvc2l0IGZlZXMgdG8gdGhpcyBjb250cmFjdCdzIGFjY291bnQncyB2YXVsdAogICAgYWNjZXNzKGNvbnRyYWN0KSBmdW4gZGVwb3NpdEZlZXMoZnJvbTogQEZsb3dUb2tlbi5WYXVsdCkgewogICAgICAgIGxldCB2YXVsdFJlZiA9IHNlbGYuYWNjb3VudC5zdG9yYWdlLmJvcnJvdzwmRmxvd1Rva2VuLlZhdWx0Pihmcm9tOiAvc3RvcmFnZS9mbG93VG9rZW5WYXVsdCkKICAgICAgICAgICAgPz8gcGFuaWMoIlVuYWJsZSB0byBib3Jyb3cgcmVmZXJlbmNlIHRvIHRoZSBkZWZhdWx0IHRva2VuIHZhdWx0IikKICAgICAgICB2YXVsdFJlZi5kZXBvc2l0KGZyb206IDwtZnJvbSkKICAgIH0KCiAgICAvLy8gV2l0aGRyYXcgZmVlcyBmcm9tIHRoaXMgY29udHJhY3QncyBhY2NvdW50J3MgdmF1bHQKICAgIGFjY2Vzcyhjb250cmFjdCkgZnVuIHdpdGhkcmF3RmVlcyhhbW91bnQ6IFVGaXg2NCk6IEBGbG93VG9rZW4uVmF1bHQgewogICAgICAgIGxldCB2YXVsdFJlZiA9IHNlbGYuYWNjb3VudC5zdG9yYWdlLmJvcnJvdzxhdXRoKEZ1bmdpYmxlVG9rZW4uV2l0aGRyYXcpICZGbG93VG9rZW4uVmF1bHQ+KGZyb206IC9zdG9yYWdlL2Zsb3dUb2tlblZhdWx0KQogICAgICAgICAgICA/PyBwYW5pYygiVW5hYmxlIHRvIGJvcnJvdyByZWZlcmVuY2UgdG8gdGhlIGRlZmF1bHQgdG9rZW4gdmF1bHQiKQogICAgICAgICAgICAKICAgICAgICByZXR1cm4gPC12YXVsdFJlZi53aXRoZHJhdyhhbW91bnQ6IGFtb3VudCkgYXMhIEBGbG93VG9rZW4uVmF1bHQKICAgIH0KCiAgICBhY2Nlc3MoYWxsKSBmdW4gc2NoZWR1bGUoCiAgICAgICAgaGFuZGxlckNhcDogQ2FwYWJpbGl0eTxhdXRoKEV4ZWN1dGUpICZ7VHJhbnNhY3Rpb25IYW5kbGVyfT4sCiAgICAgICAgZGF0YTogQW55U3RydWN0PywKICAgICAgICB0aW1lc3RhbXA6IFVGaXg2NCwKICAgICAgICBwcmlvcml0eTogUHJpb3JpdHksCiAgICAgICAgZXhlY3V0aW9uRWZmb3J0OiBVSW50NjQsCiAgICAgICAgZmVlczogQEZsb3dUb2tlbi5WYXVsdAogICAgKTogQFNjaGVkdWxlZFRyYW5zYWN0aW9uIHsKICAgICAgICByZXR1cm4gPC1zZWxmLnNoYXJlZFNjaGVkdWxlci5ib3Jyb3coKSEuc2NoZWR1bGUoCiAgICAgICAgICAgIGhhbmRsZXJDYXA6IGhhbmRsZXJDYXAsIAogICAgICAgICAgICBkYXRhOiBkYXRhLCAKICAgICAgICAgICAgdGltZXN0YW1wOiB0aW1lc3RhbXAsIAogICAgICAgICAgICBwcmlvcml0eTogcHJpb3JpdHksIAogICAgICAgICAgICBleGVjdXRpb25FZmZvcnQ6IGV4ZWN1dGlvbkVmZm9ydCwgCiAgICAgICAgICAgIGZlZXM6IDwtZmVlcwogICAgICAgICkKICAgIH0KCiAgICBhY2Nlc3MoYWxsKSBmdW4gZXN0aW1hdGUoCiAgICAgICAgZGF0YTogQW55U3RydWN0PywKICAgICAgICB0aW1lc3RhbXA6IFVGaXg2NCwKICAgICAgICBwcmlvcml0eTogUHJpb3JpdHksCiAgICAgICAgZXhlY3V0aW9uRWZmb3J0OiBVSW50NjQKICAgICk6IEVzdGltYXRlZFNjaGVkdWxlZFRyYW5zYWN0aW9uIHsKICAgICAgICByZXR1cm4gc2VsZi5zaGFyZWRTY2hlZHVsZXIuYm9ycm93KCkhCiAgICAgICAgICAgIC5lc3RpbWF0ZSgKICAgICAgICAgICAgICAgIGRhdGE6IGRhdGEsIAogICAgICAgICAgICAgICAgdGltZXN0YW1wOiB0aW1lc3RhbXAsIAogICAgICAgICAgICAgICAgcHJpb3JpdHk6IHByaW9yaXR5LCAKICAgICAgICAgICAgICAgIGV4ZWN1dGlvbkVmZm9ydDogZXhlY3V0aW9uRWZmb3J0LAogICAgICAgICAgICApCiAgICB9CgogICAgLy8vIEFsbG93cyB1c2VycyB0byBjYWxjdWxhdGUgdGhlIGZlZSBmb3IgYSBzY2hlZHVsZWQgdHJhbnNhY3Rpb24gd2l0aG91dCBoYXZpbmcgdG8gY2FsbCB0aGUgZXhwZW5zaXZlIGVzdGltYXRlIGZ1bmN0aW9uCiAgICAvLy8gQHBhcmFtIGV4ZWN1dGlvbkVmZm9ydDogVGhlIGV4ZWN1dGlvbiBlZmZvcnQgb2YgdGhlIHRyYW5zYWN0aW9uCiAgICAvLy8gQHBhcmFtIHByaW9yaXR5OiBUaGUgcHJpb3JpdHkgb2YgdGhlIHRyYW5zYWN0aW9uCiAgICAvLy8gQHBhcmFtIGRhdGFTaXplTUI6IFRoZSBzaXplIG9mIHRoZSBkYXRhIHRvIGJlIHN0b3JlZCB3aXRoIHRoZSBzY2hlZHVsZWQgdHJhbnNhY3Rpb24KICAgIC8vLyAgICAgICAgICAgICAgICAgICAgVGhlIHVzZXIgbXVzdCBjYWxjdWxhdGUgdGhpcyBkYXRhIHNpemUgdGhlbXNlbHZlcyBiZWZvcmUgY2FsbGluZyB0aGlzIGZ1bmN0aW9uCiAgICAvLy8gICAgICAgICAgICAgICAgICAgIEJ1dCBzaG91bGQgYmUgZG9uZSBpbiBhIHNlcGFyYXRlIHNjcmlwdCBvciB0cmFuc2FjdGlvbiB0byBhdm9pZCB0aGUgZXhwZW5zaXZlIGdldFNpemVPZkRhdGEgZnVuY3Rpb24KICAgIC8vLyBAcmV0dXJuIFVGaXg2NDogVGhlIGZlZSBpbiBGbG93IHRva2VucyB0aGF0IGlzIHJlcXVpcmVkIHRvIHBheSBmb3IgdGhlIHRyYW5zYWN0aW9uCiAgICBhY2Nlc3MoYWxsKSBmdW4gY2FsY3VsYXRlRmVlKGV4ZWN1dGlvbkVmZm9ydDogVUludDY0LCBwcmlvcml0eTogUHJpb3JpdHksIGRhdGFTaXplTUI6IFVGaXg2NCk6IFVGaXg2NCB7CiAgICAgICAgcmV0dXJuIHNlbGYuc2hhcmVkU2NoZWR1bGVyLmJvcnJvdygpIS5jYWxjdWxhdGVGZWUoZXhlY3V0aW9uRWZmb3J0OiBleGVjdXRpb25FZmZvcnQsIHByaW9yaXR5OiBwcmlvcml0eSwgZGF0YVNpemVNQjogZGF0YVNpemVNQikKICAgIH0KCiAgICBhY2Nlc3MoYWxsKSBmdW4gY2FuY2VsKHNjaGVkdWxlZFR4OiBAU2NoZWR1bGVkVHJhbnNhY3Rpb24pOiBARmxvd1Rva2VuLlZhdWx0IHsKICAgICAgICBsZXQgaWQgPSBzY2hlZHVsZWRUeC5pZAogICAgICAgIGRlc3Ryb3kgc2NoZWR1bGVkVHgKICAgICAgICByZXR1cm4gPC1zZWxmLnNoYXJlZFNjaGVkdWxlci5ib3Jyb3coKSEuY2FuY2VsKGlkOiBpZCkKICAgIH0KCiAgICAvLy8gZ2V0VHJhbnNhY3Rpb25EYXRhIHJldHVybnMgdGhlIHRyYW5zYWN0aW9uIGRhdGEgZm9yIGEgZ2l2ZW4gSUQKICAgIC8vLyBUaGlzIGZ1bmN0aW9uIGNhbiBvbmx5IGdldCB0aGUgZGF0YSBmb3IgYSB0cmFuc2FjdGlvbiB0aGF0IGlzIGN1cnJlbnRseSBzY2hlZHVsZWQgb3IgcGVuZGluZyBleGVjdXRpb24KICAgIC8vLyBiZWNhdXNlIGZpbmFsaXplZCB0cmFuc2FjdGlvbiBtZXRhZGF0YSBpcyBub3Qgc3RvcmVkIGluIHRoZSBjb250cmFjdAogICAgLy8vIEBwYXJhbSBpZDogVGhlIElEIG9mIHRoZSB0cmFuc2FjdGlvbiB0byBnZXQgdGhlIGRhdGEgZm9yCiAgICAvLy8gQHJldHVybjogVGhlIHRyYW5zYWN0aW9uIGRhdGEgZm9yIHRoZSBnaXZlbiBJRAogICAgYWNjZXNzKGFsbCkgdmlldyBmdW4gZ2V0VHJhbnNhY3Rpb25EYXRhKGlkOiBVSW50NjQpOiBUcmFuc2FjdGlvbkRhdGE/IHsKICAgICAgICByZXR1cm4gc2VsZi5zaGFyZWRTY2hlZHVsZXIuYm9ycm93KCkhLmdldFRyYW5zYWN0aW9uKGlkOiBpZCkKICAgIH0KCiAgICAvLy8gYm9ycm93SGFuZGxlckZvcklEIHJldHVybnMgYW4gdW4tZW50aXRsZWQgcmVmZXJlbmNlIHRvIHRoZSB0cmFuc2FjdGlvbiBoYW5kbGVyIGZvciBhIGdpdmVuIElECiAgICAvLy8gVGhlIGhhbmRsZXIgcmVmZXJlbmNlIGNhbiBiZSB1c2VkIHRvIHJlc29sdmUgdmlld3MgdG8gZ2V0IGluZm8gYWJvdXQgdGhlIGhhbmRsZXIgYW5kIHNlZSB3aGVyZSBpdCBpcyBzdG9yZWQKICAgIC8vLyBAcGFyYW0gaWQ6IFRoZSBJRCBvZiB0aGUgdHJhbnNhY3Rpb24gdG8gZ2V0IHRoZSBoYW5kbGVyIGZvcgogICAgLy8vIEByZXR1cm46IEFuIHVuLWVudGl0bGVkIHJlZmVyZW5jZSB0byB0aGUgdHJhbnNhY3Rpb24gaGFuZGxlciBmb3IgdGhlIGdpdmVuIElECiAgICBhY2Nlc3MoYWxsKSB2aWV3IGZ1biBib3Jyb3dIYW5kbGVyRm9ySUQoXyBpZDogVUludDY0KTogJntUcmFuc2FjdGlvbkhhbmRsZXJ9PyB7CiAgICAgICAgcmV0dXJuIHNlbGYuZ2V0VHJhbnNhY3Rpb25EYXRhKGlkOiBpZCk/LmJvcnJvd0hhbmRsZXIoKQogICAgfQoKICAgIC8vLyBnZXRDYW5jZWxlZFRyYW5zYWN0aW9ucyByZXR1cm5zIHRoZSBJRHMgb2YgdGhlIHRyYW5zYWN0aW9ucyB0aGF0IGhhdmUgYmVlbiBjYW5jZWxlZAogICAgLy8vIEByZXR1cm46IFRoZSBJRHMgb2YgdGhlIHRyYW5zYWN0aW9ucyB0aGF0IGhhdmUgYmVlbiBjYW5jZWxlZAogICAgYWNjZXNzKGFsbCkgdmlldyBmdW4gZ2V0Q2FuY2VsZWRUcmFuc2FjdGlvbnMoKTogW1VJbnQ2NF0gewogICAgICAgIHJldHVybiBzZWxmLnNoYXJlZFNjaGVkdWxlci5ib3Jyb3coKSEuZ2V0Q2FuY2VsZWRUcmFuc2FjdGlvbnMoKQogICAgfQoKCiAgICBhY2Nlc3MoYWxsKSB2aWV3IGZ1biBnZXRTdGF0dXMoaWQ6IFVJbnQ2NCk6IFN0YXR1cz8gewogICAgICAgIHJldHVybiBzZWxmLnNoYXJlZFNjaGVkdWxlci5ib3Jyb3coKSEuZ2V0U3RhdHVzKGlkOiBpZCkKICAgIH0KCiAgICAvLy8gZ2V0VHJhbnNhY3Rpb25zRm9yVGltZWZyYW1lIHJldHVybnMgdGhlIElEcyBvZiB0aGUgdHJhbnNhY3Rpb25zIHRoYXQgYXJlIHNjaGVkdWxlZCBmb3IgYSBnaXZlbiB0aW1lZnJhbWUKICAgIC8vLyBAcGFyYW0gc3RhcnRUaW1lc3RhbXA6IFRoZSBzdGFydCB0aW1lc3RhbXAgdG8gZ2V0IHRoZSBJRHMgZm9yCiAgICAvLy8gQHBhcmFtIGVuZFRpbWVzdGFtcDogVGhlIGVuZCB0aW1lc3RhbXAgdG8gZ2V0IHRoZSBJRHMgZm9yCiAgICAvLy8gQHJldHVybjogVGhlIElEcyBvZiB0aGUgdHJhbnNhY3Rpb25zIHRoYXQgYXJlIHNjaGVkdWxlZCBmb3IgdGhlIGdpdmVuIHRpbWVmcmFtZQogICAgYWNjZXNzKGFsbCkgZnVuIGdldFRyYW5zYWN0aW9uc0ZvclRpbWVmcmFtZShzdGFydFRpbWVzdGFtcDogVUZpeDY0LCBlbmRUaW1lc3RhbXA6IFVGaXg2NCk6IHtVRml4NjQ6IHtVSW50ODogW1VJbnQ2NF19fSB7CiAgICAgICAgcmV0dXJuIHNlbGYuc2hhcmVkU2NoZWR1bGVyLmJvcnJvdygpIS5nZXRUcmFuc2FjdGlvbnNGb3JUaW1lZnJhbWUoc3RhcnRUaW1lc3RhbXA6IHN0YXJ0VGltZXN0YW1wLCBlbmRUaW1lc3RhbXA6IGVuZFRpbWVzdGFtcCkKICAgIH0KCiAgICBhY2Nlc3MoYWxsKSB2aWV3IGZ1biBnZXRTbG90QXZhaWxhYmxlRWZmb3J0KHRpbWVzdGFtcDogVUZpeDY0LCBwcmlvcml0eTogUHJpb3JpdHkpOiBVSW50NjQgewogICAgICAgIC8vIFJlbW92ZSBmcmFjdGlvbmFsIHZhbHVlcyBmcm9tIHRoZSB0aW1lc3RhbXAKICAgICAgICBsZXQgc2FuaXRpemVkVGltZXN0YW1wID0gVUZpeDY0KFVJbnQ2NCh0aW1lc3RhbXApKQogICAgICAgIHJldHVybiBzZWxmLnNoYXJlZFNjaGVkdWxlci5ib3Jyb3coKSEuZ2V0U2xvdEF2YWlsYWJsZUVmZm9ydChzYW5pdGl6ZWRUaW1lc3RhbXA6IHNhbml0aXplZFRpbWVzdGFtcCwgcHJpb3JpdHk6IHByaW9yaXR5KQogICAgfQoKICAgIGFjY2VzcyhhbGwpIGZ1biBnZXRDb25maWcoKToge1NjaGVkdWxlckNvbmZpZ30gewogICAgICAgIHJldHVybiBzZWxmLnNoYXJlZFNjaGVkdWxlci5ib3Jyb3coKSEuZ2V0Q29uZmlnKCkKICAgIH0KICAgIAogICAgLy8vIGdldFNpemVPZkRhdGEgdGFrZXMgYSB0cmFuc2FjdGlvbidzIGRhdGEKICAgIC8vLyBhcmd1bWVudCBhbmQgc3RvcmVzIGl0IGluIHRoZSBjb250cmFjdCBhY2NvdW50J3Mgc3RvcmFnZSwgCiAgICAvLy8gY2hlY2tpbmcgc3RvcmFnZSB1c2VkIGJlZm9yZSBhbmQgYWZ0ZXIgdG8gc2VlIGhvdyBsYXJnZSB0aGUgZGF0YSBpcyBpbiBNQgogICAgLy8vIElmIGRhdGEgaXMgbmlsLCB0aGUgZnVuY3Rpb24gcmV0dXJucyAwLjAKICAgIGFjY2VzcyhhbGwpIGZ1biBnZXRTaXplT2ZEYXRhKF8gZGF0YTogQW55U3RydWN0Pyk6IFVGaXg2NCB7CiAgICAgICAgaWYgc2VsZi5pc1NpemVUcml2aWFsKGRhdGEpIHsKICAgICAgICAgICAgcmV0dXJuIDAuMAogICAgICAgIH0KCiAgICAgICAgbGV0IHN0b3JhZ2VQYXRoID0gL3N0b3JhZ2UvZGF0YVRlbXAKICAgICAgICBsZXQgc3RvcmFnZVVzZWRCZWZvcmUgPSBzZWxmLmFjY291bnQuc3RvcmFnZS51c2VkCiAgICAgICAgc2VsZi5hY2NvdW50LnN0b3JhZ2Uuc2F2ZShkYXRhISwgdG86IHN0b3JhZ2VQYXRoKQogICAgICAgIGxldCBzdG9yYWdlVXNlZEFmdGVyID0gc2VsZi5hY2NvdW50LnN0b3JhZ2UudXNlZAogICAgICAgIHNlbGYuYWNjb3VudC5zdG9yYWdlLmxvYWQ8QW55U3RydWN0Pihmcm9tOiBzdG9yYWdlUGF0aCkKCiAgICAgICAgcmV0dXJuIEZsb3dTdG9yYWdlRmVlcy5jb252ZXJ0VUludDY0U3RvcmFnZUJ5dGVzVG9VRml4NjRNZWdhYnl0ZXMoc3RvcmFnZVVzZWRBZnRlci5zYXR1cmF0aW5nU3VidHJhY3Qoc3RvcmFnZVVzZWRCZWZvcmUpKQogICAgfQoKCiAgICBhY2Nlc3MoYWxsKSBmdW4gaXNTaXplVHJpdmlhbChfIG9wdGlvbmFsRGF0YTogQW55U3RydWN0Pyk6IEJvb2wgewogICAgICAgIC8vIElmIGRhdGEgaXMgbm9uLW5pbCwgc2tpcCB0aGUga25vd24gc21hbGwtc2l6ZWQgcHJpbWl0aXZlIHR5cGVzLgogICAgICAgIGlmIGxldCBkYXRhID0gb3B0aW9uYWxEYXRhIHsKICAgICAgICAgICAgbGV0IHR5cGUgPSBkYXRhLmdldFR5cGUoKQoKICAgICAgICAgICAgLy8gQXJiaXRyYXJ5LXNpemVkIG51bWJlcnMgY2FuIGJlIGxhcmdlLgogICAgICAgICAgICAvLyBTbyB0aGV5IG11c3QgYmUgbWVhc3VyZWQuCiAgICAgICAgICAgIGlmIHR5cGUuaXNTdWJ0eXBlKG9mOiBUeXBlPEludD4oKSkKICAgICAgICAgICAgICAgIHx8IHR5cGUuaXNTdWJ0eXBlKG9mOiBUeXBlPFVJbnQ+KCkpIHsKICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZQogICAgICAgICAgICB9CgogICAgICAgICAgICAvLyBTb21lIHByaW1pdGl2ZSB0eXBlcyBhcmUgdHJpdmlhbCBpbiBzaXplLgogICAgICAgICAgICBpZiB0eXBlLmlzU3VidHlwZShvZjogVHlwZTxOdW1iZXI+KCkpCiAgICAgICAgICAgICAgICB8fCB0eXBlLmlzU3VidHlwZShvZjogVHlwZTxCb29sPigpKQogICAgICAgICAgICAgICAgfHwgdHlwZS5pc1N1YnR5cGUob2Y6IFR5cGU8QWRkcmVzcz4oKSkKICAgICAgICAgICAgICAgIHx8IHR5cGUuaXNTdWJ0eXBlKG9mOiBUeXBlPENoYXJhY3Rlcj4oKSkKICAgICAgICAgICAgICAgIHx8IHR5cGUuaXNTdWJ0eXBlKG9mOiBUeXBlPENhcGFiaWxpdHk+KCkpIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZQogICAgICAgICAgICB9CgogICAgICAgICAgICAvLyBFdmVyeXRoaW5nIGVsc2UgbmVlZHMgdG8gYmUgbWVhc3VyZWQuCiAgICAgICAgICAgIHJldHVybiBmYWxzZQogICAgICAgIH0KCiAgICAgICAgLy8gRGF0YSBpcyBuaWw6IG5vIG5lZWQgdG8gbWVhc3N1cmUuCiAgICAgICAgcmV0dXJuIHRydWUKICAgIH0KCgogICAgYWNjZXNzKGFsbCkgaW5pdCgpIHsKICAgICAgICBzZWxmLnN0b3JhZ2VQYXRoID0gL3N0b3JhZ2Uvc2hhcmVkU2NoZWR1bGVyCiAgICAgICAgbGV0IHNjaGVkdWxlciA8LSBjcmVhdGUgU2hhcmVkU2NoZWR1bGVyKCkKICAgICAgICBsZXQgb2xkU2NoZWR1bGVyIDwtIHNlbGYuYWNjb3VudC5zdG9yYWdlLmxvYWQ8QEFueVJlc291cmNlPihmcm9tOiBzZWxmLnN0b3JhZ2VQYXRoKQogICAgICAgIGRlc3Ryb3kgb2xkU2NoZWR1bGVyCiAgICAgICAgc2VsZi5hY2NvdW50LnN0b3JhZ2Uuc2F2ZSg8LXNjaGVkdWxlciwgdG86IHNlbGYuc3RvcmFnZVBhdGgpCiAgICAgICAgCiAgICAgICAgc2VsZi5zaGFyZWRTY2hlZHVsZXIgPSBzZWxmLmFjY291bnQuY2FwYWJpbGl0aWVzLnN0b3JhZ2UKICAgICAgICAgICAgLmlzc3VlPGF1dGgoQ2FuY2VsKSAmU2hhcmVkU2NoZWR1bGVyPihzZWxmLnN0b3JhZ2VQYXRoKQogICAgfQp9",
		"FlowTransactionSchedulerUtils": "aW1wb3J0IEZsb3dUcmFuc2FjdGlvblNjaGVkdWxlciBmcm9tIDB4ZTQ2N2I5ZGQxMWZhMDBkZgppbXBvcnQgRnVuZ2libGVUb2tlbiBmcm9tIDB4ZjIzM2RjZWU4OGZlMGFiZQppbXBvcnQgRmxvd1Rva2VuIGZyb20gMHgxNjU0NjUzMzk5MDQwYTYxCmltcG9ydCBFVk0gZnJvbSAweGU0NjdiOWRkMTFmYTAwZGYKaW1wb3J0IE1ldGFkYXRhVmlld3MgZnJvbSAweDFkN2U1N2FhNTU4MTc0NDgKCi8vLyBGbG93VHJhbnNhY3Rpb25TY2hlZHVsZXJVdGlscyBwcm92aWRlcyB1dGlsaXR5IGZ1bmN0aW9uYWxpdHkgZm9yIHdvcmtpbmcgd2l0aCBzY2hlZHVsZWQgdHJhbnNhY3Rpb25zCi8vLyBvbiB0aGUgRmxvdyBibG9ja2NoYWluLgovLy8KLy8vIEluIHRoZSBmdXR1cmUsIHRoaXMgY29udHJhY3Qgd2lsbCBiZSB1cGRhdGVkIHRvIGluY2x1ZGUgbW9yZSBmdW5jdGlvbmFsaXR5IAovLy8gdG8gbWFrZSBpdCBtb3JlIGNvbnZlbmllbnQgZm9yIHdvcmtpbmcgd2l0aCBzY2hlZHVsZWQgdHJhbnNhY3Rpb25zIGZvciB2YXJpb3VzIHVzZSBjYXNlcy4KLy8vCmFjY2VzcyhhbGwpIGNvbnRyYWN0IEZsb3dUcmFuc2FjdGlvblNjaGVkdWxlclV0aWxzIHsKCiAgICAvLy8gU3RvcmFnZSBwYXRoIGZvciBNYW5hZ2VyIHJlc291cmNlcwogICAgYWNjZXNzKGFsbCkgbGV0IG1hbmFnZXJTdG9yYWdlUGF0aDogU3RvcmFnZVBhdGgKCiAgICAvLy8gUHVibGljIHBhdGggZm9yIE1hbmFnZXIgcmVzb3VyY2VzCiAgICBhY2Nlc3MoYWxsKSBsZXQgbWFuYWdlclB1YmxpY1BhdGg6IFB1YmxpY1BhdGgKCiAgICAvLy8gRW50aXRsZW1lbnRzCiAgICBhY2Nlc3MoYWxsKSBlbnRpdGxlbWVudCBPd25lcgoKICAgIC8vLyBIYW5kbGVySW5mbyBpcyBhIHN0cnVjdCB0aGF0IHN0b3JlcyBpbmZvcm1hdGlvbiBhYm91dCBhIHNpbmdsZSB0cmFuc2FjdGlvbiBoYW5kbGVyCiAgICAvLy8gdGhhdCBoYXMgYmVlbiB1c2VkIHRvIHNjaGVkdWxlIHRyYW5zYWN0aW9ucy4KICAgIC8vLyBJdCBpcyBzdG9yZWQgaW4gdGhlIG1hbmFnZXIncyBoYW5kbGVySW5mb3MgZGljdGlvbmFyeS4KICAgIC8vLyBJdCBzdG9yZXMgdGhlIHR5cGUgaWRlbnRpZmllciBvZiB0aGUgaGFuZGxlciwgdGhlIHRyYW5zYWN0aW9uIElEcyB0aGF0IGhhdmUgYmVlbiBzY2hlZHVsZWQgZm9yIGl0LAogICAgLy8vIGFuZCBhIGNhcGFiaWxpdHkgdG8gdGhlIGhhbmRsZXIuCiAgICAvLy8gVGhlIGNhcGFiaWxpdHkgaXMgdXNlZCB0byBib3Jyb3cgYSByZWZlcmVuY2UgdG8gdGhlIGhhbmRsZXIgd2hlbiBuZWVkZWQuCiAgICAvLy8gVGhlIHRyYW5zYWN0aW9uIElEcyBhcmUgdXNlZCB0byB0cmFjayB0aGUgdHJhbnNhY3Rpb25zIHRoYXQgaGF2ZSBiZWVuIHNjaGVkdWxlZCBmb3IgdGhlIGhhbmRsZXIuCiAgICAvLy8gVGhlIHR5cGUgaWRlbnRpZmllciBpcyB1c2VkIHRvIGRpZmZlcmVudGlhdGUgYmV0d2VlbiBoYW5kbGVycyBvZiB0aGUgc2FtZSB0eXBlLgogICAgYWNjZXNzKGFsbCkgc3RydWN0IEhhbmRsZXJJbmZvIHsKICAgICAgICAvLy8gVGhlIHR5cGUgaWRlbnRpZmllciBvZiB0aGUgaGFuZGxlcgogICAgICAgIGFjY2VzcyhhbGwpIGxldCB0eXBlSWRlbnRpZmllcjogU3RyaW5nCgogICAgICAgIC8vLyBUaGUgdHJhbnNhY3Rpb24gSURzIHRoYXQgaGF2ZSBiZWVuIHNjaGVkdWxlZCBmb3IgdGhlIGhhbmRsZXIKICAgICAgICBhY2Nlc3MoYWxsKSBsZXQgdHJhbnNhY3Rpb25JRHM6IFtVSW50NjRdCgogICAgICAgIC8vLyBUaGUgY2FwYWJpbGl0eSB0byB0aGUgaGFuZGxlcgogICAgICAgIGFjY2Vzcyhjb250cmFjdCkgbGV0IGNhcGFiaWxpdHk6IENhcGFiaWxpdHk8YXV0aChGbG93VHJhbnNhY3Rpb25TY2hlZHVsZXIuRXhlY3V0ZSkgJntGbG93VHJhbnNhY3Rpb25TY2hlZHVsZXIuVHJhbnNhY3Rpb25IYW5kbGVyfT4KCiAgICAgICAgaW5pdCh0eXBlSWRlbnRpZmllcjogU3RyaW5nLCBjYXBhYmlsaXR5OiBDYXBhYmlsaXR5PGF1dGgoRmxvd1RyYW5zYWN0aW9uU2NoZWR1bGVyLkV4ZWN1dGUpICZ7Rmxvd1RyYW5zYWN0aW9uU2NoZWR1bGVyLlRyYW5zYWN0aW9uSGFuZGxlcn0+KSB7CiAgICAgICAgICAgIHNlbGYudHlwZUlkZW50aWZpZXIgPSB0eXBlSWRlbnRpZmllcgogICAgICAgICAgICBzZWxmLmNhcGFiaWxpdHkgPSBjYXBhYmlsaXR5CiAgICAgICAgICAgIHNlbGYudHJhbnNhY3Rpb25JRHMgPSBbXQogICAgICAgIH0KCiAgICAgICAgLy8vIEFkZCBhIHRyYW5zYWN0aW9uIElEIHRvIHRoZSBoYW5kbGVyJ3MgdHJhbnNhY3Rpb24gSURzCiAgICAgICAgLy8vIEBwYXJhbSBpZDogVGhlIElEIG9mIHRoZSB0cmFuc2FjdGlvbiB0byBhZGQKICAgICAgICBhY2Nlc3MoY29udHJhY3QpIGZ1biBhZGRUcmFuc2FjdGlvbklEKGlkOiBVSW50NjQpIHsKICAgICAgICAgICAgc2VsZi50cmFuc2FjdGlvbklEcy5hcHBlbmQoaWQpCiAgICAgICAgfQoKICAgICAgICAvLy8gUmVtb3ZlIGEgdHJhbnNhY3Rpb24gSUQgZnJvbSB0aGUgaGFuZGxlcidzIHRyYW5zYWN0aW9uIElEcwogICAgICAgIC8vLyBAcGFyYW0gaWQ6IFRoZSBJRCBvZiB0aGUgdHJhbnNhY3Rpb24gdG8gcmVtb3ZlCiAgICAgICAgYWNjZXNzKGNvbnRyYWN0KSBmdW4gcmVtb3ZlVHJhbnNhY3Rpb25JRChpZDogVUludDY0KSB7CiAgICAgICAgICAgIGxldCBpbmRleCA9IHNlbGYudHJhbnNhY3Rpb25JRHMuZmlyc3RJbmRleChvZjogaWQpCiAgICAgICAgICAgIGlmIGluZGV4ICE9IG5pbCB7CiAgICAgICAgICAgICAgICBzZWxmLnRyYW5zYWN0aW9uSURzLnJlbW92ZShhdDogaW5kZXghKQogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICAvLy8gQm9ycm93IGFuIHVuLWVudGl0bGVkIHJlZmVyZW5jZSB0byB0aGUgaGFuZGxlcgogICAgICAgIC8vLyBAcmV0dXJuOiBBIHJlZmVyZW5jZSB0byB0aGUgaGFuZGxlciwgb3IgbmlsIGlmIG5vdCBmb3VuZAogICAgICAgIGFjY2Vzcyhjb250cmFjdCkgdmlldyBmdW4gYm9ycm93KCk6ICZ7Rmxvd1RyYW5zYWN0aW9uU2NoZWR1bGVyLlRyYW5zYWN0aW9uSGFuZGxlcn0/IHsKICAgICAgICAgICAgcmV0dXJuIHNlbGYuY2FwYWJpbGl0eS5ib3Jyb3coKSBhcz8gJntGbG93VHJhbnNhY3Rpb25TY2hlZHVsZXIuVHJhbnNhY3Rpb25IYW5kbGVyfQogICAgICAgIH0KICAgIH0KCiAgICAvLy8gVGhlIE1hbmFnZXIgcmVzb3VyY2Ugb2ZmZXJzIGEgY29udmVuaWVudCB3YXkgZm9yIHVzZXJzIGFuZCBkZXZlbG9wZXJzIHRvCiAgICAvLy8gZ3JvdXAsIHNjaGVkdWxlLCBjYW5jZWwsIGFuZCBxdWVyeSBzY2hlZHVsZWQgdHJhbnNhY3Rpb25zIHRocm91Z2ggYSBzaW5nbGUgcmVzb3VyY2UuCiAgICAvLy8gVGhlIE1hbmFnZXIgaXMgZGVmaW5lZCBhcyBhbiBpbnRlcmZhY2UgdG8gYWxsb3cgZm9yIG11bHRpcGxlIGltcGxlbWVudGF0aW9ucyBvZiB0aGUgbWFuYWdlcgogICAgLy8vIGFuZCB0byBzdXBwb3J0IHVwZ3JhZGVzIHRoYXQgbWF5IGJlIG5lZWRlZCBpbiB0aGUgZnV0dXJlIHRvIGFkZCBhZGRpdGlvbmFsIHN0b3JhZ2UgZmllbGRzIGFuZCBmdW5jdGlvbmFsaXR5LgogICAgLy8vIAogICAgLy8vIEtleSBmZWF0dXJlczoKICAgIC8vLyAtIE9yZ2FuaXplcyBzY2hlZHVsZWQgYW5kIGV4ZWN1dGVkIHRyYW5zYWN0aW9ucyBieSBoYW5kbGVyIHR5cGUgYW5kIHRpbWVzdGFtcAogICAgLy8vIC0gU2ltcGxpZmllZCBzY2hlZHVsaW5nIGludGVyZmFjZSB0aGF0IHdvcmtzIHdpdGggcHJldmlvdXNseSB1c2VkIHRyYW5zYWN0aW9uIGhhbmRsZXJzCiAgICAvLy8gLSBUcmFuc2FjdGlvbiB0cmFja2luZyBhbmQgcXVlcnlpbmcgY2FwYWJpbGl0aWVzIGJ5IGhhbmRsZXIsIHRpbWVzdGFtcCwgYW5kIElECiAgICAvLy8gLSBIYW5kbGVyIG1ldGFkYXRhIGFuZCB2aWV3IHJlc29sdXRpb24gc3VwcG9ydAogICAgYWNjZXNzKGFsbCkgcmVzb3VyY2UgaW50ZXJmYWNlIE1hbmFnZXIgewoKICAgICAgICAvLy8gU2NoZWR1bGVzIGEgdHJhbnNhY3Rpb24gYnkgcGFzc2luZyB0aGUgYXJndW1lbnRzIGRpcmVjdGx5CiAgICAgICAgLy8vIHRvIHRoZSBGbG93VHJhbnNhY3Rpb25TY2hlZHVsZXIgc2NoZWR1bGUgZnVuY3Rpb24KICAgICAgICAvLy8gVGhpcyBhbHNvIHNob3VsZCBzdG9yZSB0aGUgaW5mb3JtYXRpb24gYWJvdXQgdGhlIHRyYW5zYWN0aW9uCiAgICAgICAgLy8vIGFuZCBoYW5kbGVyIGluIHRoZSBtYW5hZ2VyJ3MgZmllbGRzCiAgICAgICAgYWNjZXNzKE93bmVyKSBmdW4gc2NoZWR1bGUoCiAgICAgICAgICAgIGhhbmRsZXJDYXA6IENhcGFiaWxpdHk8YXV0aChGbG93VHJhbnNhY3Rpb25TY2hlZHVsZXIuRXhlY3V0ZSkgJntGbG93VHJhbnNhY3Rpb25TY2hlZHVsZXIuVHJhbnNhY3Rpb25IYW5kbGVyfT4sCiAgICAgICAgICAgIGRhdGE6IEFueVN0cnVjdD8sCiAgICAgICAgICAgIHRpbWVzdGFtcDogVUZpeDY0LAogICAgICAgICAgICBwcmlvcml0eTogRmxvd1RyYW5zYWN0aW9uU2NoZWR1bGVyLlByaW9yaXR5LAogICAgICAgICAgICBleGVjdXRpb25FZmZvcnQ6IFVJbnQ2NCwKICAgICAgICAgICAgZmVlczogQEZsb3dUb2tlbi5WYXVsdAogICAgICAgICk6IFVJbnQ2NAoKICAgICAgICAvLy8gU2NoZWR1bGVzIGEgdHJhbnNhY3Rpb24gdGhhdCB1c2VzIGEgcHJldmlvdXNseSB1c2VkIGhhbmRsZXIKICAgICAgICAvLy8gVGhpcyBzaG91bGQgYWxzbyBzdG9yZSB0aGUgaW5mb3JtYXRpb24gYWJvdXQgdGhlIHRyYW5zYWN0aW9uCiAgICAgICAgLy8vIGFuZCBoYW5kbGVyIGluIHRoZSBtYW5hZ2VyJ3MgZmllbGRzCiAgICAgICAgYWNjZXNzKE93bmVyKSBmdW4gc2NoZWR1bGVCeUhhbmRsZXIoCiAgICAgICAgICAgIGhhbmRsZXJUeXBlSWRlbnRpZmllcjogU3RyaW5nLAogICAgICAgICAgICBoYW5kbGVyVVVJRDogVUludDY0PywKICAgICAgICAgICAgZGF0YTogQW55U3RydWN0PywKICAgICAgICAgICAgdGltZXN0YW1wOiBVRml4NjQsCiAgICAgICAgICAgIHByaW9yaXR5OiBGbG93VHJhbnNhY3Rpb25TY2hlZHVsZXIuUHJpb3JpdHksCiAgICAgICAgICAgIGV4ZWN1dGlvbkVmZm9ydDogVUludDY0LAogICAgICAgICAgICBmZWVzOiBARmxvd1Rva2VuLlZhdWx0CiAgICAgICAgKTogVUludDY0CgogICAgICAgIC8vLyBDYW5jZWxzIGEgc2NoZWR1bGVkIHRyYW5zYWN0aW9uIGJ5IGl0cyBJRAogICAgICAgIC8vLyBUaGlzIHNob3VsZCBhbHNvIHJlbW92ZSB0aGUgaW5mb3JtYXRpb24gYWJvdXQgdGhlIHRyYW5zYWN0aW9uIGZyb20gdGhlIG1hbmFnZXIncyBmaWVsZHMKICAgICAgICBhY2Nlc3MoT3duZXIpIGZ1biBjYW5jZWwoaWQ6IFVJbnQ2NCk6IEBGbG93VG9rZW4uVmF1bHQKICAgICAgICAKICAgICAgICBhY2Nlc3MoYWxsKSB2aWV3IGZ1biBnZXRUcmFuc2FjdGlvbkRhdGEoXyBpZDogVUludDY0KTogRmxvd1RyYW5zYWN0aW9uU2NoZWR1bGVyLlRyYW5zYWN0aW9uRGF0YT8KICAgICAgICBhY2Nlc3MoYWxsKSB2aWV3IGZ1biBib3Jyb3dUcmFuc2FjdGlvbkhhbmRsZXJGb3JJRChfIGlkOiBVSW50NjQpOiAme0Zsb3dUcmFuc2FjdGlvblNjaGVkdWxlci5UcmFuc2FjdGlvbkhhbmRsZXJ9PwogICAgICAgIGFjY2VzcyhhbGwpIGZ1biBnZXRIYW5kbGVyVHlwZUlkZW50aWZpZXJzKCk6IHtTdHJpbmc6IFtVSW50NjRdfQogICAgICAgIGFjY2VzcyhhbGwpIHZpZXcgZnVuIGJvcnJvd0hhbmRsZXIoaGFuZGxlclR5cGVJZGVudGlmaWVyOiBTdHJpbmcsIGhhbmRsZXJVVUlEOiBVSW50NjQ/KTogJntGbG93VHJhbnNhY3Rpb25TY2hlZHVsZXIuVHJhbnNhY3Rpb25IYW5kbGVyfT8KICAgICAgICBhY2Nlc3MoYWxsKSBmdW4gZ2V0SGFuZGxlclZpZXdzKGhhbmRsZXJUeXBlSWRlbnRpZmllcjogU3RyaW5nLCBoYW5kbGVyVVVJRDogVUludDY0Pyk6IFtUeXBlXSAKICAgICAgICBhY2Nlc3MoYWxsKSBmdW4gcmVzb2x2ZUhhbmRsZXJWaWV3KGhhbmRsZXJUeXBlSWRlbnRpZmllcjogU3RyaW5nLCBoYW5kbGVyVVVJRDogVUludDY0Pywgdmlld1R5cGU6IFR5cGUpOiBBbnlTdHJ1Y3Q/ICAgICAgCiAgICAgICAgYWNjZXNzKGFsbCkgZnVuIGdldEhhbmRsZXJWaWV3c0Zyb21UcmFuc2FjdGlvbklEKF8gaWQ6IFVJbnQ2NCk6IFtUeXBlXQogICAgICAgIGFjY2VzcyhhbGwpIGZ1biByZXNvbHZlSGFuZGxlclZpZXdGcm9tVHJhbnNhY3Rpb25JRChfIGlkOiBVSW50NjQsIHZpZXdUeXBlOiBUeXBlKTogQW55U3RydWN0PyAKICAgICAgICBhY2Nlc3MoYWxsKSB2aWV3IGZ1biBnZXRUcmFuc2FjdGlvbklEcygpOiBbVUludDY0XQogICAgICAgIGFjY2VzcyhhbGwpIHZpZXcgZnVuIGdldFRyYW5zYWN0aW9uSURzQnlIYW5kbGVyKGhhbmRsZXJUeXBlSWRlbnRpZmllcjogU3RyaW5nLCBoYW5kbGVyVVVJRDogVUludDY0Pyk6IFtVSW50NjRdCiAgICAgICAgYWNjZXNzKGFsbCkgdmlldyBmdW4gZ2V0VHJhbnNhY3Rpb25JRHNCeVRpbWVzdGFtcChfIHRpbWVzdGFtcDogVUZpeDY0KTogW1VJbnQ2NF0KICAgICAgICBhY2Nlc3MoYWxsKSBmdW4gZ2V0VHJhbnNhY3Rpb25JRHNCeVRpbWVzdGFtcFJhbmdlKHN0YXJ0VGltZXN0YW1wOiBVRml4NjQsIGVuZFRpbWVzdGFtcDogVUZpeDY0KToge1VGaXg2NDogW1VJbnQ2NF19CiAgICAgICAgYWNjZXNzKGFsbCkgdmlldyBmdW4gZ2V0VHJhbnNhY3Rpb25TdGF0dXMoaWQ6IFVJbnQ2NCk6IEZsb3dUcmFuc2FjdGlvblNjaGVkdWxlci5TdGF0dXM/CiAgICAgICAgYWNjZXNzKGFsbCkgdmlldyBmdW4gZ2V0U29ydGVkVGltZXN0YW1wcygpOiBGbG93VHJhbnNhY3Rpb25TY2hlZHVsZXIuU29ydGVkVGltZXN0YW1wcwogICAgfQoKICAgIC8vLyBNYW5hZ2VyIHJlc291cmNlIGlzIG1lYW50IHRvIHByb3ZpZGUgdXNlcnMgYW5kIGRldmVsb3BlcnMgd2l0aCBhIHNpbXBsZSB3YXkKICAgIC8vLyB0byBncm91cCB0aGUgc2NoZWR1bGVkIHRyYW5zYWN0aW9ucyB0aGF0IHRoZXkgb3duIGludG8gb25lIHBsYWNlIHRvIG1ha2UgaXQgbW9yZQogICAgLy8vIGNvbnZlbmllbnQgdG8gc2NoZWR1bGUvY2FuY2VsIHRyYW5zYWN0aW9ucyBhbmQgZ2V0IGluZm9ybWF0aW9uIGFib3V0IHRoZSB0cmFuc2FjdGlvbnMKICAgIC8vLyB0aGF0IGFyZSBtYW5hZ2VkLgogICAgLy8vIEl0IHN0b3JlcyBTY2hlZHVsZWRUcmFuc2FjdGlvbiByZXNvdXJjZXMgaW4gYSBkaWN0aW9uYXJ5IGFuZCBoYXMgb3RoZXIgZmllbGRzCiAgICAvLy8gdG8gdHJhY2sgdGhlIHNjaGVkdWxlZCB0cmFuc2FjdGlvbnMgYnkgdGltZXN0YW1wIGFuZCBoYW5kbGVyCiAgICAvLy8KICAgIGFjY2VzcyhhbGwpIHJlc291cmNlIE1hbmFnZXJWMTogTWFuYWdlciB7CiAgICAgICAgLy8vIERpY3Rpb25hcnkgc3RvcmluZyBzY2hlZHVsZWQgdHJhbnNhY3Rpb25zIGJ5IHRoZWlyIElECiAgICAgICAgYWNjZXNzKHNlbGYpIHZhciBzY2hlZHVsZWRUcmFuc2FjdGlvbnM6IEB7VUludDY0OiBGbG93VHJhbnNhY3Rpb25TY2hlZHVsZXIuU2NoZWR1bGVkVHJhbnNhY3Rpb259CgogICAgICAgIC8vLyBTb3J0ZWQgYXJyYXkgb2YgdGltZXN0YW1wcyB0aGF0IHRoaXMgbWFuYWdlciBoYXMgdHJhbnNhY3Rpb25zIHNjaGVkdWxlZCBhdAogICAgICAgIGFjY2VzcyhzZWxmKSB2YXIgc29ydGVkVGltZXN0YW1wczogRmxvd1RyYW5zYWN0aW9uU2NoZWR1bGVyLlNvcnRlZFRpbWVzdGFtcHMKCiAgICAgICAgLy8vIERpY3Rpb25hcnkgc3RvcmluZyB0aGUgSURzIG9mIHRoZSB0cmFuc2FjdGlvbnMgc2NoZWR1bGVkIGF0IGEgZ2l2ZW4gdGltZXN0YW1wCiAgICAgICAgYWNjZXNzKHNlbGYpIGxldCBpZHNCeVRpbWVzdGFtcDoge1VGaXg2NDogW1VJbnQ2NF19CgogICAgICAgIC8vLyBEaWN0aW9uYXJ5IHN0b3JpbmcgdGhlIGhhbmRsZXIgVVVJRHMgZm9yIHRyYW5zYWN0aW9uIElEcwogICAgICAgIGFjY2VzcyhzZWxmKSBsZXQgaGFuZGxlclVVSURzQnlUcmFuc2FjdGlvbklEOiB7VUludDY0OiBVSW50NjR9CgogICAgICAgIC8vLyBEaWN0aW9uYXJ5IHN0b3JpbmcgdGhlIGhhbmRsZXJzIHRoYXQgdGhpcyBtYW5hZ2VyIGhhcyBzY2hlZHVsZWQgdHJhbnNhY3Rpb25zIGZvciBhdCBvbmUgcG9pbnQKICAgICAgICAvLy8gVGhlIGZpZWxkIGRpZmZlcmVudGlhdGVzIGJldHdlZW4gaGFuZGxlcnMgb2YgdGhlIHNhbWUgdHlwZSBieSB0aGVpciBVVUlEIGJlY2F1c2UgdGhlcmUgY2FuIGJlIG11bHRpcGxlIGhhbmRsZXJzIG9mIHRoZSBzYW1lIHR5cGUKICAgICAgICAvLy8gdGhhdCBwZXJmb3JtIHRoZSBzYW1lIGZ1bmN0aW9uYWxpdHkgYnV0IG1heWJlIGRvIGl0IGZvciBkaWZmZXJlbnQgcHVycG9zZXMKICAgICAgICAvLy8gc28gaXQgaXMgaW1wb3J0YW50IHRvIGRpZmZlcmVudGlhdGUgYmV0d2VlbiB0aGVtIGluIGNhc2UgdGhlIHVzZXIgbmVlZHMgdG8gcmV0cmlldmUgYSBzcGVjaWZpYyBoYW5kbGVyCiAgICAgICAgLy8vIFRoZSBtZXRhZGF0YSBmb3IgZWFjaCBoYW5kbGVyIHRoYXQgcG90ZW50aWFsbHkgaW5jbHVkZXMgaW5mb3JtYXRpb24gYWJvdXQgdGhlIGhhbmRsZXIncyBwdXJwb3NlCiAgICAgICAgLy8vIGNhbiBiZSByZXRyaWV2ZWQgZnJvbSB0aGUgaGFuZGxlcidzIHJlZmVyZW5jZSB2aWEgdGhlIGdldFZpZXdzKCkgYW5kIHJlc29sdmVWaWV3KCkgZnVuY3Rpb25zCiAgICAgICAgYWNjZXNzKHNlbGYpIGxldCBoYW5kbGVySW5mb3M6IHtTdHJpbmc6IHtVSW50NjQ6IEhhbmRsZXJJbmZvfX0KCiAgICAgICAgaW5pdCgpIHsKICAgICAgICAgICAgc2VsZi5zY2hlZHVsZWRUcmFuc2FjdGlvbnMgPC0ge30KICAgICAgICAgICAgc2VsZi5zb3J0ZWRUaW1lc3RhbXBzID0gRmxvd1RyYW5zYWN0aW9uU2NoZWR1bGVyLlNvcnRlZFRpbWVzdGFtcHMoKQogICAgICAgICAgICBzZWxmLmlkc0J5VGltZXN0YW1wID0ge30KICAgICAgICAgICAgc2VsZi5oYW5kbGVyVVVJRHNCeVRyYW5zYWN0aW9uSUQgPSB7fQogICAgICAgICAgICBzZWxmLmhhbmRsZXJJbmZvcyA9IHt9CiAgICAgICAgfQoKICAgICAgICAvLy8gc2NoZWR1bGVCeUhhbmRsZXIgc2NoZWR1bGVzIGEgdHJhbnNhY3Rpb24gYnkgYSBnaXZlbiBoYW5kbGVyIHRoYXQgaGFzIGJlZW4gdXNlZCBiZWZvcmUKICAgICAgICAvLy8gQHBhcmFtIGhhbmRsZXJUeXBlSWRlbnRpZmllcjogVGhlIHR5cGUgaWRlbnRpZmllciBvZiB0aGUgaGFuZGxlcgogICAgICAgIC8vLyBAcGFyYW0gZGF0YTogT3B0aW9uYWwgZGF0YSB0byBwYXNzIHRvIHRoZSB0cmFuc2FjdGlvbiB3aGVuIGV4ZWN1dGVkCiAgICAgICAgLy8vIEBwYXJhbSB0aW1lc3RhbXA6IFRoZSB0aW1lc3RhbXAgd2hlbiB0aGUgdHJhbnNhY3Rpb24gc2hvdWxkIGJlIGV4ZWN1dGVkCiAgICAgICAgLy8vIEBwYXJhbSBwcmlvcml0eTogVGhlIHByaW9yaXR5IG9mIHRoZSB0cmFuc2FjdGlvbiAoSGlnaCwgTWVkaXVtLCBvciBMb3cpCiAgICAgICAgLy8vIEBwYXJhbSBleGVjdXRpb25FZmZvcnQ6IFRoZSBleGVjdXRpb24gZWZmb3J0IGZvciB0aGUgdHJhbnNhY3Rpb24KICAgICAgICAvLy8gQHBhcmFtIGZlZXM6IEEgRmxvd1Rva2VuIHZhdWx0IGNvbnRhaW5pbmcgc3VmZmljaWVudCBmZWVzCiAgICAgICAgLy8vIEByZXR1cm46IFRoZSBJRCBvZiB0aGUgc2NoZWR1bGVkIHRyYW5zYWN0aW9uCiAgICAgICAgYWNjZXNzKE93bmVyKSBmdW4gc2NoZWR1bGVCeUhhbmRsZXIoCiAgICAgICAgICAgIGhhbmRsZXJUeXBlSWRlbnRpZmllcjogU3RyaW5nLAogICAgICAgICAgICBoYW5kbGVyVVVJRDogVUludDY0PywKICAgICAgICAgICAgZGF0YTogQW55U3RydWN0PywKICAgICAgICAgICAgdGltZXN0YW1wOiBVRml4NjQsCiAgICAgICAgICAgIHByaW9yaXR5OiBGbG93VHJhbnNhY3Rpb25TY2hlZHVsZXIuUHJpb3JpdHksCiAgICAgICAgICAgIGV4ZWN1dGlvbkVmZm9ydDogVUludDY0LAogICAgICAgICAgICBmZWVzOiBARmxvd1Rva2VuLlZhdWx0CiAgICAgICAgKTogVUludDY0IHsKICAgICAgICAgICAgcHJlIHsKICAgICAgICAgICAgICAgIHNlbGYuaGFuZGxlckluZm9zLmNvbnRhaW5zS2V5KGhhbmRsZXJUeXBlSWRlbnRpZmllcik6ICJJbnZhbGlkIGhhbmRsZXIgdHlwZSBpZGVudGlmaWVyOiBIYW5kbGVyIHdpdGggdHlwZSBpZGVudGlmaWVyIFwoaGFuZGxlclR5cGVJZGVudGlmaWVyKSBub3QgZm91bmQgaW4gbWFuYWdlciIKICAgICAgICAgICAgICAgIGhhbmRsZXJVVUlEID09IG5pbCB8fCBzZWxmLmhhbmRsZXJJbmZvc1toYW5kbGVyVHlwZUlkZW50aWZpZXJdIS5jb250YWluc0tleShoYW5kbGVyVVVJRCEpOiAiSW52YWxpZCBoYW5kbGVyIFVVSUQ6IEhhbmRsZXIgd2l0aCB0eXBlIGlkZW50aWZpZXIgXChoYW5kbGVyVHlwZUlkZW50aWZpZXIpIGFuZCBVVUlEIFwoaGFuZGxlclVVSUQhKSBub3QgZm91bmQgaW4gbWFuYWdlciIKICAgICAgICAgICAgfQogICAgICAgICAgICBsZXQgaGFuZGxlcnMgPSBzZWxmLmhhbmRsZXJJbmZvc1toYW5kbGVyVHlwZUlkZW50aWZpZXJdIQogICAgICAgICAgICB2YXIgaWQgPSBoYW5kbGVyVVVJRAogICAgICAgICAgICBpZiBoYW5kbGVyVVVJRCA9PSBuaWwgewogICAgICAgICAgICAgICAgYXNzZXJ0ICgKICAgICAgICAgICAgICAgICAgICBoYW5kbGVycy5rZXlzLmxlbmd0aCA9PSAxLAogICAgICAgICAgICAgICAgICAgIG1lc3NhZ2U6ICJJbnZhbGlkIGhhbmRsZXIgVVVJRDogSGFuZGxlciB3aXRoIHR5cGUgaWRlbnRpZmllciBcKGhhbmRsZXJUeXBlSWRlbnRpZmllcikgaGFzIG1vcmUgdGhhbiBvbmUgVVVJRCwgYnV0IG5vIFVVSUQgd2FzIHByb3ZpZGVkIgogICAgICAgICAgICAgICAgKQogICAgICAgICAgICAgICAgaWQgPSBoYW5kbGVycy5rZXlzWzBdCiAgICAgICAgICAgIH0KICAgICAgICAgICAgcmV0dXJuIHNlbGYuc2NoZWR1bGUoaGFuZGxlckNhcDogaGFuZGxlcnNbaWQhXSEuY2FwYWJpbGl0eSwgZGF0YTogZGF0YSwgdGltZXN0YW1wOiB0aW1lc3RhbXAsIHByaW9yaXR5OiBwcmlvcml0eSwgZXhlY3V0aW9uRWZmb3J0OiBleGVjdXRpb25FZmZvcnQsIGZlZXM6IDwtZmVlcykKICAgICAgICB9CgogICAgICAgIC8vLyBTY2hlZHVsZSBhIHRyYW5zYWN0aW9uIGFuZCBzdG9yZSBpdCBpbiB0aGUgbWFuYWdlcidzIGRpY3Rpb25hcnkKICAgICAgICAvLy8gQHBhcmFtIGhhbmRsZXJDYXA6IEEgY2FwYWJpbGl0eSB0byBhIHJlc291cmNlIHRoYXQgaW1wbGVtZW50cyB0aGUgVHJhbnNhY3Rpb25IYW5kbGVyIGludGVyZmFjZQogICAgICAgIC8vLyBAcGFyYW0gZGF0YTogT3B0aW9uYWwgZGF0YSB0byBwYXNzIHRvIHRoZSB0cmFuc2FjdGlvbiB3aGVuIGV4ZWN1dGVkCiAgICAgICAgLy8vIEBwYXJhbSB0aW1lc3RhbXA6IFRoZSB0aW1lc3RhbXAgd2hlbiB0aGUgdHJhbnNhY3Rpb24gc2hvdWxkIGJlIGV4ZWN1dGVkCiAgICAgICAgLy8vIEBwYXJhbSBwcmlvcml0eTogVGhlIHByaW9yaXR5IG9mIHRoZSB0cmFuc2FjdGlvbiAoSGlnaCwgTWVkaXVtLCBvciBMb3cpCiAgICAgICAgLy8vIEBwYXJhbSBleGVjdXRpb25FZmZvcnQ6IFRoZSBleGVjdXRpb24gZWZmb3J0IGZvciB0aGUgdHJhbnNhY3Rpb24KICAgICAgICAvLy8gQHBhcmFtIGZlZXM6IEEgRmxvd1Rva2VuIHZhdWx0IGNvbnRhaW5pbmcgc3VmZmljaWVudCBmZWVzCiAgICAgICAgLy8vIEByZXR1cm46IFRoZSBJRCBvZiB0aGUgc2NoZWR1bGVkIHRyYW5zYWN0aW9uCiAgICAgICAgYWNjZXNzKE93bmVyKSBmdW4gc2NoZWR1bGUoCiAgICAgICAgICAgIGhhbmRsZXJDYXA6IENhcGFiaWxpdHk8YXV0aChGbG93VHJhbnNhY3Rpb25TY2hlZHVsZXIuRXhlY3V0ZSkgJntGbG93VHJhbnNhY3Rpb25TY2hlZHVsZXIuVHJhbnNhY3Rpb25IYW5kbGVyfT4sCiAgICAgICAgICAgIGRhdGE6IEFueVN0cnVjdD8sCiAgICAgICAgICAgIHRpbWVzdGFtcDogVUZpeDY0LAogICAgICAgICAgICBwcmlvcml0eTogRmxvd1RyYW5zYWN0aW9uU2NoZWR1bGVyLlByaW9yaXR5LAogICAgICAgICAgICBleGVjdXRpb25FZmZvcnQ6IFVJbnQ2NCwKICAgICAgICAgICAgZmVlczogQEZsb3dUb2tlbi5WYXVsdAogICAgICAgICk6IFVJbnQ2NCB7CiAgICAgICAgICAgIC8vIENsZWFuIHVwIGFueSBzdGFsZSB0cmFuc2FjdGlvbnMgYmVmb3JlIHNjaGVkdWxpbmcgYSBuZXcgb25lCiAgICAgICAgICAgIHNlbGYuY2xlYW51cCgpCgogICAgICAgICAgICAvLyBSb3V0ZSB0byB0aGUgbWFpbiBGbG93VHJhbnNhY3Rpb25TY2hlZHVsZXIKICAgICAgICAgICAgbGV0IHNjaGVkdWxlZFRyYW5zYWN0aW9uIDwtIEZsb3dUcmFuc2FjdGlvblNjaGVkdWxlci5zY2hlZHVsZSgKICAgICAgICAgICAgICAgIGhhbmRsZXJDYXA6IGhhbmRsZXJDYXAsCiAgICAgICAgICAgICAgICBkYXRhOiBkYXRhLAogICAgICAgICAgICAgICAgdGltZXN0YW1wOiB0aW1lc3RhbXAsCiAgICAgICAgICAgICAgICBwcmlvcml0eTogcHJpb3JpdHksCiAgICAgICAgICAgICAgICBleGVjdXRpb25FZmZvcnQ6IGV4ZWN1dGlvbkVmZm9ydCwKICAgICAgICAgICAgICAgIGZlZXM6IDwtZmVlcwogICAgICAgICAgICApCgogICAgICAgICAgICAvLyBTdG9yZSB0aGUgaGFuZGxlciBjYXBhYmlsaXR5IGluIG91ciBkaWN0aW9uYXJ5IGZvciBsYXRlciByZXRyaWV2YWwKICAgICAgICAgICAgbGV0IGlkID0gc2NoZWR1bGVkVHJhbnNhY3Rpb24uaWQKICAgICAgICAgICAgbGV0IGFjdHVhbFRpbWVzdGFtcCA9IHNjaGVkdWxlZFRyYW5zYWN0aW9uLnRpbWVzdGFtcAogICAgICAgICAgICBsZXQgaGFuZGxlclJlZiA9IGhhbmRsZXJDYXAuYm9ycm93KCkKICAgICAgICAgICAgICAgID8/IHBhbmljKCJJbnZhbGlkIHRyYW5zYWN0aW9uIGhhbmRsZXI6IENvdWxkIG5vdCBib3Jyb3cgYSByZWZlcmVuY2UgdG8gdGhlIHRyYW5zYWN0aW9uIGhhbmRsZXIiKQogICAgICAgICAgICBsZXQgaGFuZGxlclR5cGVJZGVudGlmaWVyID0gaGFuZGxlclJlZi5nZXRUeXBlKCkuaWRlbnRpZmllcgogICAgICAgICAgICBsZXQgaGFuZGxlclVVSUQgPSBoYW5kbGVyUmVmLnV1aWQKCiAgICAgICAgICAgIHNlbGYuaGFuZGxlclVVSURzQnlUcmFuc2FjdGlvbklEW2lkXSA9IGhhbmRsZXJVVUlECgogICAgICAgICAgICAvLyBTdG9yZSB0aGUgaGFuZGxlciBjYXBhYmlsaXR5IGluIHRoZSBoYW5kbGVycyBkaWN0aW9uYXJ5IGZvciBsYXRlciByZXRyaWV2YWwKICAgICAgICAgICAgaWYgc2VsZi5oYW5kbGVySW5mb3NbaGFuZGxlclR5cGVJZGVudGlmaWVyXSAhPSBuaWwgewogICAgICAgICAgICAgICAgbGV0IGhhbmRsZXJzID0gJnNlbGYuaGFuZGxlckluZm9zW2hhbmRsZXJUeXBlSWRlbnRpZmllcl0hIGFzIGF1dGgoTXV0YXRlKSAme1VJbnQ2NDogSGFuZGxlckluZm99CiAgICAgICAgICAgICAgICBpZiBsZXQgaGFuZGxlckluZm8gPSBoYW5kbGVyc1toYW5kbGVyVVVJRF0gewogICAgICAgICAgICAgICAgICAgIGhhbmRsZXJJbmZvLmFkZFRyYW5zYWN0aW9uSUQoaWQ6IGlkKQogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICBsZXQgaGFuZGxlckluZm8gPSBIYW5kbGVySW5mbyh0eXBlSWRlbnRpZmllcjogaGFuZGxlclR5cGVJZGVudGlmaWVyLCBjYXBhYmlsaXR5OiBoYW5kbGVyQ2FwKQogICAgICAgICAgICAgICAgICAgIGhhbmRsZXJJbmZvLmFkZFRyYW5zYWN0aW9uSUQoaWQ6IGlkKQogICAgICAgICAgICAgICAgICAgIGhhbmRsZXJzW2hhbmRsZXJVVUlEXSA9IGhhbmRsZXJJbmZvCiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICBsZXQgaGFuZGxlckluZm8gPSBIYW5kbGVySW5mbyh0eXBlSWRlbnRpZmllcjogaGFuZGxlclR5cGVJZGVudGlmaWVyLCBjYXBhYmlsaXR5OiBoYW5kbGVyQ2FwKQogICAgICAgICAgICAgICAgaGFuZGxlckluZm8uYWRkVHJhbnNhY3Rpb25JRChpZDogaWQpCiAgICAgICAgICAgICAgICBsZXQgdXVpZERpY3Rpb25hcnk6IHtVSW50NjQ6IEhhbmRsZXJJbmZvfSA9IHtoYW5kbGVyVVVJRDogaGFuZGxlckluZm99CiAgICAgICAgICAgICAgICBzZWxmLmhhbmRsZXJJbmZvc1toYW5kbGVyVHlwZUlkZW50aWZpZXJdID0gdXVpZERpY3Rpb25hcnkKICAgICAgICAgICAgfQoKICAgICAgICAgICAgLy8gU3RvcmUgdGhlIHRyYW5zYWN0aW9uIGluIHRoZSB0cmFuc2FjdGlvbnMgZGljdGlvbmFyeQogICAgICAgICAgICBzZWxmLnNjaGVkdWxlZFRyYW5zYWN0aW9uc1tzY2hlZHVsZWRUcmFuc2FjdGlvbi5pZF0gPC0hIHNjaGVkdWxlZFRyYW5zYWN0aW9uCgogICAgICAgICAgICAvLyBBZGQgdGhlIHRyYW5zYWN0aW9uIHRvIHRoZSBzb3J0ZWQgdGltZXN0YW1wcyBhcnJheQogICAgICAgICAgICBzZWxmLnNvcnRlZFRpbWVzdGFtcHMuYWRkKHRpbWVzdGFtcDogYWN0dWFsVGltZXN0YW1wKQoKICAgICAgICAgICAgLy8gU3RvcmUgdGhlIHRyYW5zYWN0aW9uIGluIHRoZSBpZHMgYnkgdGltZXN0YW1wIGRpY3Rpb25hcnkKICAgICAgICAgICAgaWYgc2VsZi5pZHNCeVRpbWVzdGFtcFthY3R1YWxUaW1lc3RhbXBdICE9IG5pbCB7CiAgICAgICAgICAgICAgICBsZXQgaWRzID0gJnNlbGYuaWRzQnlUaW1lc3RhbXBbYWN0dWFsVGltZXN0YW1wXSEgYXMgYXV0aChNdXRhdGUpICZbVUludDY0XQogICAgICAgICAgICAgICAgaWRzLmFwcGVuZChpZCkKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIHNlbGYuaWRzQnlUaW1lc3RhbXBbYWN0dWFsVGltZXN0YW1wXSA9IFtpZF0KICAgICAgICAgICAgfQoKICAgICAgICAgICAgcmV0dXJuIGlkCiAgICAgICAgfQoKICAgICAgICAvLy8gQ2FuY2VsIGEgc2NoZWR1bGVkIHRyYW5zYWN0aW9uIGJ5IGl0cyBJRAogICAgICAgIC8vLyBAcGFyYW0gaWQ6IFRoZSBJRCBvZiB0aGUgdHJhbnNhY3Rpb24gdG8gY2FuY2VsCiAgICAgICAgLy8vIEByZXR1cm46IEEgRmxvd1Rva2VuIHZhdWx0IGNvbnRhaW5pbmcgdGhlIHJlZnVuZGVkIGZlZXMKICAgICAgICBhY2Nlc3MoT3duZXIpIGZ1biBjYW5jZWwoaWQ6IFVJbnQ2NCk6IEBGbG93VG9rZW4uVmF1bHQgewogICAgICAgICAgICAvLyBSZW1vdmUgdGhlIHRyYW5zYWN0aW9uIGZyb20gdGhlIHRyYW5zYWN0aW9ucyBkaWN0aW9uYXJ5CiAgICAgICAgICAgIGxldCB0eCA8LSBzZWxmLnNjaGVkdWxlZFRyYW5zYWN0aW9ucy5yZW1vdmUoa2V5OiBpZCkKICAgICAgICAgICAgICAgID8/IHBhbmljKCJJbnZhbGlkIElEOiBUcmFuc2FjdGlvbiB3aXRoIElEIFwoaWQpIG5vdCBmb3VuZCBpbiBtYW5hZ2VyIikKCiAgICAgICAgICAgIHNlbGYucmVtb3ZlSUQoaWQ6IGlkLCB0aW1lc3RhbXA6IHR4LnRpbWVzdGFtcCwgaGFuZGxlclR5cGVJZGVudGlmaWVyOiB0eC5oYW5kbGVyVHlwZUlkZW50aWZpZXIpCgogICAgICAgICAgICAvLyBDYW5jZWwgdGhlIHRyYW5zYWN0aW9uIHRocm91Z2ggdGhlIG1haW4gc2NoZWR1bGVyCiAgICAgICAgICAgIGxldCByZWZ1bmRlZEZlZXMgPC0gRmxvd1RyYW5zYWN0aW9uU2NoZWR1bGVyLmNhbmNlbChzY2hlZHVsZWRUeDogPC10eCEpCgogICAgICAgICAgICByZXR1cm4gPC1yZWZ1bmRlZEZlZXMKICAgICAgICB9CgogICAgICAgIC8vLyBSZW1vdmUgYW4gSUQgZnJvbSB0aGUgbWFuYWdlcidzIGZpZWxkcwogICAgICAgIC8vLyBAcGFyYW0gaWQ6IFRoZSBJRCBvZiB0aGUgdHJhbnNhY3Rpb24gdG8gcmVtb3ZlCiAgICAgICAgLy8vIEBwYXJhbSB0aW1lc3RhbXA6IFRoZSB0aW1lc3RhbXAgb2YgdGhlIHRyYW5zYWN0aW9uIHRvIHJlbW92ZQogICAgICAgIC8vLyBAcGFyYW0gaGFuZGxlclR5cGVJZGVudGlmaWVyOiBUaGUgdHlwZSBpZGVudGlmaWVyIG9mIHRoZSBoYW5kbGVyIG9mIHRoZSB0cmFuc2FjdGlvbiB0byByZW1vdmUKICAgICAgICBhY2Nlc3Moc2VsZikgZnVuIHJlbW92ZUlEKGlkOiBVSW50NjQsIHRpbWVzdGFtcDogVUZpeDY0LCBoYW5kbGVyVHlwZUlkZW50aWZpZXI6IFN0cmluZykgewogICAgICAgICAgICBwcmUgewogICAgICAgICAgICAgICAgc2VsZi5oYW5kbGVySW5mb3MuY29udGFpbnNLZXkoaGFuZGxlclR5cGVJZGVudGlmaWVyKTogIkludmFsaWQgaGFuZGxlciB0eXBlIGlkZW50aWZpZXI6IEhhbmRsZXIgd2l0aCB0eXBlIGlkZW50aWZpZXIgXChoYW5kbGVyVHlwZUlkZW50aWZpZXIpIG5vdCBmb3VuZCBpbiBtYW5hZ2VyIgogICAgICAgICAgICB9CgogICAgICAgICAgICBpZiBzZWxmLmlkc0J5VGltZXN0YW1wLmNvbnRhaW5zS2V5KHRpbWVzdGFtcCkgewogICAgICAgICAgICAgICAgbGV0IGlkcyA9ICZzZWxmLmlkc0J5VGltZXN0YW1wW3RpbWVzdGFtcF0hIGFzIGF1dGgoTXV0YXRlKSAmW1VJbnQ2NF0KICAgICAgICAgICAgICAgIGlmIGxldCBpbmRleCA9IGlkcy5maXJzdEluZGV4KG9mOiBpZCkgewogICAgICAgICAgICAgICAgICAgIGlkcy5yZW1vdmUoYXQ6IGluZGV4KQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgaWYgaWRzLmxlbmd0aCA9PSAwIHsKICAgICAgICAgICAgICAgICAgICBzZWxmLmlkc0J5VGltZXN0YW1wLnJlbW92ZShrZXk6IHRpbWVzdGFtcCkKICAgICAgICAgICAgICAgICAgICBzZWxmLnNvcnRlZFRpbWVzdGFtcHMucmVtb3ZlKHRpbWVzdGFtcDogdGltZXN0YW1wKQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CgogICAgICAgICAgICBpZiBsZXQgaGFuZGxlclVVSUQgPSBzZWxmLmhhbmRsZXJVVUlEc0J5VHJhbnNhY3Rpb25JRC5yZW1vdmUoa2V5OiBpZCkgewogICAgICAgICAgICAgICAgLy8gUmVtb3ZlIHRoZSB0cmFuc2FjdGlvbiBJRCBmcm9tIHRoZSBoYW5kbGVyIGluZm8gYXJyYXkKICAgICAgICAgICAgICAgIGxldCBoYW5kbGVycyA9ICZzZWxmLmhhbmRsZXJJbmZvc1toYW5kbGVyVHlwZUlkZW50aWZpZXJdISBhcyBhdXRoKE11dGF0ZSkgJntVSW50NjQ6IEhhbmRsZXJJbmZvfQogICAgICAgICAgICAgICAgaWYgbGV0IGhhbmRsZXJJbmZvID0gaGFuZGxlcnNbaGFuZGxlclVVSURdIHsKICAgICAgICAgICAgICAgICAgICBoYW5kbGVySW5mby5yZW1vdmVUcmFuc2FjdGlvbklEKGlkOiBpZCkKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgLy8vIENsZWFuIHVwIHRyYW5zYWN0aW9ucyB0aGF0IGFyZSBubyBsb25nZXIgdmFsaWQgKHJldHVybiBuaWwgb3IgVW5rbm93biBzdGF0dXMpCiAgICAgICAgLy8vIFRoaXMgcmVtb3ZlcyBhbmQgZGVzdHJveXMgdHJhbnNhY3Rpb25zIHRoYXQgaGF2ZSBiZWVuIGV4ZWN1dGVkLCBjYW5jZWxlZCwgb3IgYXJlIG90aGVyd2lzZSBpbnZhbGlkCiAgICAgICAgLy8vIEByZXR1cm46IFRoZSB0cmFuc2FjdGlvbnMgdGhhdCB3ZXJlIGNsZWFuZWQgdXAgKHJlbW92ZWQgZnJvbSB0aGUgbWFuYWdlcikKICAgICAgICBhY2Nlc3MoT3duZXIpIGZ1biBjbGVhbnVwKCk6IFtVSW50NjRdIHsKICAgICAgICAgICAgbGV0IGN1cnJlbnRUaW1lc3RhbXAgPSBnZXRDdXJyZW50QmxvY2soKS50aW1lc3RhbXAKICAgICAgICAgICAgdmFyIHRyYW5zYWN0aW9uc1RvUmVtb3ZlOiB7VUludDY0OiBVRml4NjR9ID0ge30KCiAgICAgICAgICAgIGxldCBwYXN0VGltZXN0YW1wcyA9IHNlbGYuc29ydGVkVGltZXN0YW1wcy5nZXRCZWZvcmUoY3VycmVudDogY3VycmVudFRpbWVzdGFtcCkKICAgICAgICAgICAgZm9yIHRpbWVzdGFtcCBpbiBwYXN0VGltZXN0YW1wcyB7CiAgICAgICAgICAgICAgICBsZXQgaWRzID0gc2VsZi5pZHNCeVRpbWVzdGFtcFt0aW1lc3RhbXBdID8/IFtdCiAgICAgICAgICAgICAgICBpZiBpZHMubGVuZ3RoID09IDAgewogICAgICAgICAgICAgICAgICAgIHNlbGYuc29ydGVkVGltZXN0YW1wcy5yZW1vdmUodGltZXN0YW1wOiB0aW1lc3RhbXApCiAgICAgICAgICAgICAgICAgICAgY29udGludWUKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGZvciBpZCBpbiBpZHMgewogICAgICAgICAgICAgICAgICAgIGxldCBzdGF0dXMgPSBGbG93VHJhbnNhY3Rpb25TY2hlZHVsZXIuZ2V0U3RhdHVzKGlkOiBpZCkKICAgICAgICAgICAgICAgICAgICBpZiBzdGF0dXMgPT0gbmlsIHx8IHN0YXR1cyEgIT0gRmxvd1RyYW5zYWN0aW9uU2NoZWR1bGVyLlN0YXR1cy5TY2hlZHVsZWQgewogICAgICAgICAgICAgICAgICAgICAgICB0cmFuc2FjdGlvbnNUb1JlbW92ZVtpZF0gPSB0aW1lc3RhbXAKICAgICAgICAgICAgICAgICAgICAgICAgLy8gTmVlZCB0byB0ZW1wb3JhcmlseSBsaW1pdCB0aGUgbnVtYmVyIG9mIHRyYW5zYWN0aW9ucyB0byByZW1vdmUKICAgICAgICAgICAgICAgICAgICAgICAgLy8gYmVjYXVzZSBzb21lIG1hbmFnZXJzIG9uIG1haW5uZXQgaGF2ZSBhbHJlYWR5IGhpdCB0aGUgbGltaXQgYW5kIHdlIG5lZWQgdG8gYmF0Y2ggdGhlbQogICAgICAgICAgICAgICAgICAgICAgICAvLyB0byBtYWtlIHN1cmUgdGhleSBnZXQgY2xlYW5lZCB1cCBwcm9wZXJseQogICAgICAgICAgICAgICAgICAgICAgICAvLyBUaGlzIHdpbGwgYmUgcmVtb3ZlZCBldmVudHVhbGx5CiAgICAgICAgICAgICAgICAgICAgICAgIGlmIHRyYW5zYWN0aW9uc1RvUmVtb3ZlLmxlbmd0aCA+IDUwIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrCiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIC8vIFRoZW4gcmVtb3ZlIGFuZCBkZXN0cm95IHRoZSBpZGVudGlmaWVkIHRyYW5zYWN0aW9ucwogICAgICAgICAgICBmb3IgaWQgaW4gdHJhbnNhY3Rpb25zVG9SZW1vdmUgewogICAgICAgICAgICAgICAgaWYgbGV0IHR4IDwtIHNlbGYuc2NoZWR1bGVkVHJhbnNhY3Rpb25zLnJlbW92ZShrZXk6IGlkKSB7CiAgICAgICAgICAgICAgICAgICAgc2VsZi5yZW1vdmVJRChpZDogaWQsIHRpbWVzdGFtcDogdHJhbnNhY3Rpb25zVG9SZW1vdmVbaWRdISwgaGFuZGxlclR5cGVJZGVudGlmaWVyOiB0eC5oYW5kbGVyVHlwZUlkZW50aWZpZXIpCiAgICAgICAgICAgICAgICAgICAgZGVzdHJveSB0eAogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CgogICAgICAgICAgICByZXR1cm4gdHJhbnNhY3Rpb25zVG9SZW1vdmUua2V5cwogICAgICAgIH0KCiAgICAgICAgLy8vIFJlbW92ZSBhIGhhbmRsZXIgY2FwYWJpbGl0eSBmcm9tIHRoZSBtYW5hZ2VyCiAgICAgICAgLy8vIFRoZSBzcGVjaWZpZWQgaGFuZGxlciBtdXN0IG5vdCBoYXZlIGFueSB0cmFuc2FjdGlvbnMgc2NoZWR1bGVkIGZvciBpdAogICAgICAgIC8vLyBAcGFyYW0gaGFuZGxlclR5cGVJZGVudGlmaWVyOiBUaGUgdHlwZSBpZGVudGlmaWVyIG9mIHRoZSBoYW5kbGVyCiAgICAgICAgLy8vIEBwYXJhbSBoYW5kbGVyVVVJRDogVGhlIFVVSUQgb2YgdGhlIGhhbmRsZXIKICAgICAgICBhY2Nlc3MoT3duZXIpIGZ1biByZW1vdmVIYW5kbGVyKGhhbmRsZXJUeXBlSWRlbnRpZmllcjogU3RyaW5nLCBoYW5kbGVyVVVJRDogVUludDY0PykgewogICAgICAgICAgICAvLyBNYWtlIHN1cmUgdGhlIGhhbmRsZXIgZXhpc3RzCiAgICAgICAgICAgIGlmIGxldCBoYW5kbGVycyA9IHNlbGYuaGFuZGxlckluZm9zW2hhbmRsZXJUeXBlSWRlbnRpZmllcl0gewogICAgICAgICAgICAgICAgdmFyIGlkID0gaGFuZGxlclVVSUQKICAgICAgICAgICAgICAgIC8vIElmIG5vIFVVSUQgaXMgcHJvdmlkZWQsIHRoZXJlIG11c3QgYmUgb25seSBvbmUgaGFuZGxlciBvZiB0aGUgdHlwZQogICAgICAgICAgICAgICAgaWYgaGFuZGxlclVVSUQgPT0gbmlsIHsKICAgICAgICAgICAgICAgICAgICBpZiBoYW5kbGVycy5rZXlzLmxlbmd0aCA+IDEgewogICAgICAgICAgICAgICAgICAgICAgICAvLyBOby1vcCBpZiB3ZSBkb24ndCBrbm93IHdoaWNoIFVVSUQgdG8gcmVtb3ZlCiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybgogICAgICAgICAgICAgICAgICAgIH0gZWxzZSBpZiBoYW5kbGVycy5rZXlzLmxlbmd0aCA9PSAwIHsKICAgICAgICAgICAgICAgICAgICAgICAgc2VsZi5oYW5kbGVySW5mb3MucmVtb3ZlKGtleTogaGFuZGxlclR5cGVJZGVudGlmaWVyKQogICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4KICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgaWQgPSBoYW5kbGVycy5rZXlzWzBdCiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAvLyBNYWtlIHN1cmUgdGhlIGhhbmRsZXIgaGFzIG5vIHRyYW5zYWN0aW9ucyBzY2hlZHVsZWQgZm9yIGl0CiAgICAgICAgICAgICAgICBpZiBsZXQgaGFuZGxlckluZm8gPSBoYW5kbGVyc1tpZCFdIHsKICAgICAgICAgICAgICAgICAgICBpZiBoYW5kbGVySW5mby50cmFuc2FjdGlvbklEcy5sZW5ndGggPiAwIHsKICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuCiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgLy8gUmVtb3ZlIHRoZSBoYW5kbGVyIHV1aWQgZnJvbSB0aGUgaGFuZGxlcnMgZGljdGlvbmFyeQogICAgICAgICAgICAgICAgaGFuZGxlcnMucmVtb3ZlKGtleTogaWQhKQoKICAgICAgICAgICAgICAgIC8vIElmIHRoZXJlIGFyZSBubyBtb3JlIGhhbmRsZXJzIG9mIHRoZSB0eXBlLCByZW1vdmUgdGhlIHR5cGUgZnJvbSB0aGUgaGFuZGxlcnMgZGljdGlvbmFyeQogICAgICAgICAgICAgICAgaWYgaGFuZGxlcnMua2V5cy5sZW5ndGggPT0gMCB7CiAgICAgICAgICAgICAgICAgICAgc2VsZi5oYW5kbGVySW5mb3MucmVtb3ZlKGtleTogaGFuZGxlclR5cGVJZGVudGlmaWVyKQogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICBzZWxmLmhhbmRsZXJJbmZvc1toYW5kbGVyVHlwZUlkZW50aWZpZXJdID0gaGFuZGxlcnMKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgLy8vIEdldCB0cmFuc2FjdGlvbiBkYXRhIGJ5IGl0cyBJRAogICAgICAgIC8vLyBAcGFyYW0gaWQ6IFRoZSBJRCBvZiB0aGUgdHJhbnNhY3Rpb24gdG8gcmV0cmlldmUKICAgICAgICAvLy8gQHJldHVybjogVGhlIHRyYW5zYWN0aW9uIGRhdGEgZnJvbSBGbG93VHJhbnNhY3Rpb25TY2hlZHVsZXIsIG9yIG5pbCBpZiBub3QgZm91bmQKICAgICAgICBhY2Nlc3MoYWxsKSB2aWV3IGZ1biBnZXRUcmFuc2FjdGlvbkRhdGEoXyBpZDogVUludDY0KTogRmxvd1RyYW5zYWN0aW9uU2NoZWR1bGVyLlRyYW5zYWN0aW9uRGF0YT8gewogICAgICAgICAgICBpZiBzZWxmLnNjaGVkdWxlZFRyYW5zYWN0aW9ucy5jb250YWluc0tleShpZCkgewogICAgICAgICAgICAgICAgcmV0dXJuIEZsb3dUcmFuc2FjdGlvblNjaGVkdWxlci5nZXRUcmFuc2FjdGlvbkRhdGEoaWQ6IGlkKQogICAgICAgICAgICB9CiAgICAgICAgICAgIHJldHVybiBuaWwKICAgICAgICB9CgogICAgICAgIC8vLyBHZXQgYW4gdW4tZW50aXRsZWQgcmVmZXJlbmNlIHRvIGEgdHJhbnNhY3Rpb24gaGFuZGxlciBvZiBhIGdpdmVuIElECiAgICAgICAgLy8vIEBwYXJhbSBpZDogVGhlIElEIG9mIHRoZSB0cmFuc2FjdGlvbiB0byByZXRyaWV2ZQogICAgICAgIC8vLyBAcmV0dXJuOiBBIHJlZmVyZW5jZSB0byB0aGUgdHJhbnNhY3Rpb24gaGFuZGxlciwgb3IgbmlsIGlmIG5vdCBmb3VuZAogICAgICAgIGFjY2VzcyhhbGwpIHZpZXcgZnVuIGJvcnJvd1RyYW5zYWN0aW9uSGFuZGxlckZvcklEKF8gaWQ6IFVJbnQ2NCk6ICZ7Rmxvd1RyYW5zYWN0aW9uU2NoZWR1bGVyLlRyYW5zYWN0aW9uSGFuZGxlcn0/IHsKICAgICAgICAgICAgbGV0IHR4RGF0YSA9IHNlbGYuZ2V0VHJhbnNhY3Rpb25EYXRhKGlkKQogICAgICAgICAgICByZXR1cm4gdHhEYXRhPy5ib3Jyb3dIYW5kbGVyKCkKICAgICAgICB9CgogICAgICAgIC8vLyBHZXQgYWxsIHRoZSBoYW5kbGVyIHR5cGUgaWRlbnRpZmllcnMgdGhhdCB0aGUgbWFuYWdlciBoYXMgc2NoZWR1bGVkIHRyYW5zYWN0aW9ucyBmb3IKICAgICAgICAvLy8gQHJldHVybjogQSBkaWN0aW9uYXJ5IG9mIGFsbCBoYW5kbGVyIHR5cGUgaWRlbnRpZmllcnMgYW5kIHRoZWlyIFVVSURzCiAgICAgICAgYWNjZXNzKGFsbCkgZnVuIGdldEhhbmRsZXJUeXBlSWRlbnRpZmllcnMoKToge1N0cmluZzogW1VJbnQ2NF19IHsKICAgICAgICAgICAgdmFyIGhhbmRsZXJUeXBlSWRlbnRpZmllcnM6IHtTdHJpbmc6IFtVSW50NjRdfSA9IHt9CiAgICAgICAgICAgIGZvciBoYW5kbGVyVHlwZUlkZW50aWZpZXIgaW4gc2VsZi5oYW5kbGVySW5mb3Mua2V5cyB7CiAgICAgICAgICAgICAgICBsZXQgaGFuZGxlclVVSURzOiBbVUludDY0XSA9IFtdCiAgICAgICAgICAgICAgICBsZXQgaGFuZGxlclR5cGVzID0gc2VsZi5oYW5kbGVySW5mb3NbaGFuZGxlclR5cGVJZGVudGlmaWVyXSEKICAgICAgICAgICAgICAgIGZvciB1dWlkIGluIGhhbmRsZXJUeXBlcyB7CiAgICAgICAgICAgICAgICAgICAgbGV0IGhhbmRsZXJJbmZvID0gaGFuZGxlclR5cGVzW3V1aWRdIQogICAgICAgICAgICAgICAgICAgIGlmICFoYW5kbGVySW5mby5jYXBhYmlsaXR5LmNoZWNrKCkgewogICAgICAgICAgICAgICAgICAgICAgICBjb250aW51ZQogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBoYW5kbGVyVVVJRHMuYXBwZW5kKHV1aWQpCiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBoYW5kbGVyVHlwZUlkZW50aWZpZXJzW2hhbmRsZXJUeXBlSWRlbnRpZmllcl0gPSBoYW5kbGVyVVVJRHMKICAgICAgICAgICAgfQogICAgICAgICAgICByZXR1cm4gaGFuZGxlclR5cGVJZGVudGlmaWVycwogICAgICAgIH0KCiAgICAgICAgLy8vIEdldCBhbiB1bi1lbnRpdGxlZCByZWZlcmVuY2UgdG8gYSBoYW5kbGVyIGJ5IGEgZ2l2ZW4gdHlwZSBpZGVudGlmaWVyCiAgICAgICAgLy8vIEBwYXJhbSBoYW5kbGVyVHlwZUlkZW50aWZpZXI6IFRoZSB0eXBlIGlkZW50aWZpZXIgb2YgdGhlIGhhbmRsZXIKICAgICAgICAvLy8gQHBhcmFtIGhhbmRsZXJVVUlEOiBUaGUgVVVJRCBvZiB0aGUgaGFuZGxlciwgaWYgbmlsLCB0aGVyZSBtdXN0IGJlIG9ubHkgb25lIGhhbmRsZXIgb2YgdGhlIHR5cGUsIG90aGVyd2lzZSBuaWwgd2lsbCBiZSByZXR1cm5lZAogICAgICAgIC8vLyBAcmV0dXJuOiBBbiB1bi1lbnRpdGxlZCByZWZlcmVuY2UgdG8gdGhlIGhhbmRsZXIsIG9yIG5pbCBpZiBub3QgZm91bmQKICAgICAgICBhY2Nlc3MoYWxsKSB2aWV3IGZ1biBib3Jyb3dIYW5kbGVyKGhhbmRsZXJUeXBlSWRlbnRpZmllcjogU3RyaW5nLCBoYW5kbGVyVVVJRDogVUludDY0Pyk6ICZ7Rmxvd1RyYW5zYWN0aW9uU2NoZWR1bGVyLlRyYW5zYWN0aW9uSGFuZGxlcn0/IHsKICAgICAgICAgICAgaWYgbGV0IGhhbmRsZXJzID0gc2VsZi5oYW5kbGVySW5mb3NbaGFuZGxlclR5cGVJZGVudGlmaWVyXSB7CiAgICAgICAgICAgICAgICBpZiBoYW5kbGVyVVVJRCAhPSBuaWwgewogICAgICAgICAgICAgICAgICAgIGlmIGxldCBoYW5kbGVySW5mbyA9IGhhbmRsZXJzW2hhbmRsZXJVVUlEIV0gewogICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gaGFuZGxlckluZm8uYm9ycm93KCkKICAgICAgICAgICAgICAgICAgICB9IAogICAgICAgICAgICAgICAgfSBlbHNlIGlmIGhhbmRsZXJzLmtleXMubGVuZ3RoID09IDEgewogICAgICAgICAgICAgICAgICAgIC8vIElmIG5vIHV1aWQgaXMgcHJvdmlkZWQsIHdlIGNhbiBqdXN0IGRlZmF1bHQgdG8gdGhlIG9ubHkgaGFuZGxlciB1dWlkCiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGhhbmRsZXJzW2hhbmRsZXJzLmtleXNbMF1dIS5ib3Jyb3coKQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIHJldHVybiBuaWwKICAgICAgICB9CgogICAgICAgIC8vLyBHZXQgYWxsIHRoZSB2aWV3cyB0aGF0IGEgaGFuZGxlciBpbXBsZW1lbnRzCiAgICAgICAgLy8vIEBwYXJhbSBoYW5kbGVyVHlwZUlkZW50aWZpZXI6IFRoZSB0eXBlIGlkZW50aWZpZXIgb2YgdGhlIGhhbmRsZXIKICAgICAgICAvLy8gQHBhcmFtIGhhbmRsZXJVVUlEOiBUaGUgVVVJRCBvZiB0aGUgaGFuZGxlciwgaWYgbmlsLCB0aGVyZSBtdXN0IGJlIG9ubHkgb25lIGhhbmRsZXIgb2YgdGhlIHR5cGUsIG90aGVyd2lzZSBuaWwgd2lsbCBiZSByZXR1cm5lZAogICAgICAgIC8vLyBAcmV0dXJuOiBBbiBhcnJheSBvZiBhbGwgdmlld3MKICAgICAgICBhY2Nlc3MoYWxsKSBmdW4gZ2V0SGFuZGxlclZpZXdzKGhhbmRsZXJUeXBlSWRlbnRpZmllcjogU3RyaW5nLCBoYW5kbGVyVVVJRDogVUludDY0Pyk6IFtUeXBlXSB7CiAgICAgICAgICAgIGlmIGxldCBoYW5kbGVyID0gc2VsZi5ib3Jyb3dIYW5kbGVyKGhhbmRsZXJUeXBlSWRlbnRpZmllcjogaGFuZGxlclR5cGVJZGVudGlmaWVyLCBoYW5kbGVyVVVJRDogaGFuZGxlclVVSUQpIHsKICAgICAgICAgICAgICAgIHJldHVybiBoYW5kbGVyLmdldFZpZXdzKCkKICAgICAgICAgICAgfQogICAgICAgICAgICByZXR1cm4gW10KICAgICAgICB9CgogICAgICAgIC8vLyBSZXNvbHZlIGEgdmlldyBmb3IgYSBoYW5kbGVyIGJ5IGEgZ2l2ZW4gdHlwZSBpZGVudGlmaWVyCiAgICAgICAgLy8vIEBwYXJhbSBoYW5kbGVyVHlwZUlkZW50aWZpZXI6IFRoZSB0eXBlIGlkZW50aWZpZXIgb2YgdGhlIGhhbmRsZXIKICAgICAgICAvLy8gQHBhcmFtIGhhbmRsZXJVVUlEOiBUaGUgVVVJRCBvZiB0aGUgaGFuZGxlciwgaWYgbmlsLCB0aGVyZSBtdXN0IGJlIG9ubHkgb25lIGhhbmRsZXIgb2YgdGhlIHR5cGUsIG90aGVyd2lzZSBuaWwgd2lsbCBiZSByZXR1cm5lZAogICAgICAgIC8vLyBAcGFyYW0gdmlld1R5cGU6IFRoZSB0eXBlIG9mIHRoZSB2aWV3IHRvIHJlc29sdmUKICAgICAgICAvLy8gQHJldHVybjogVGhlIHJlc29sdmVkIHZpZXcsIG9yIG5pbCBpZiBub3QgZm91bmQKICAgICAgICBhY2Nlc3MoYWxsKSBmdW4gcmVzb2x2ZUhhbmRsZXJWaWV3KGhhbmRsZXJUeXBlSWRlbnRpZmllcjogU3RyaW5nLCBoYW5kbGVyVVVJRDogVUludDY0Pywgdmlld1R5cGU6IFR5cGUpOiBBbnlTdHJ1Y3Q/IHsKICAgICAgICAgICAgaWYgbGV0IGhhbmRsZXIgPSBzZWxmLmJvcnJvd0hhbmRsZXIoaGFuZGxlclR5cGVJZGVudGlmaWVyOiBoYW5kbGVyVHlwZUlkZW50aWZpZXIsIGhhbmRsZXJVVUlEOiBoYW5kbGVyVVVJRCkgewogICAgICAgICAgICAgICAgcmV0dXJuIGhhbmRsZXIucmVzb2x2ZVZpZXcodmlld1R5cGUpCiAgICAgICAgICAgIH0KICAgICAgICAgICAgcmV0dXJuIG5pbAogICAgICAgIH0KCiAgICAgICAgLy8vIEdldCBhbGwgdGhlIHZpZXdzIHRoYXQgYSBoYW5kbGVyIGltcGxlbWVudHMgZnJvbSBhIGdpdmVuIHRyYW5zYWN0aW9uIElECiAgICAgICAgLy8vIEBwYXJhbSB0cmFuc2FjdGlvbklkOiBUaGUgSUQgb2YgdGhlIHRyYW5zYWN0aW9uCiAgICAgICAgLy8vIEByZXR1cm46IEFuIGFycmF5IG9mIGFsbCB2aWV3cwogICAgICAgIGFjY2VzcyhhbGwpIGZ1biBnZXRIYW5kbGVyVmlld3NGcm9tVHJhbnNhY3Rpb25JRChfIGlkOiBVSW50NjQpOiBbVHlwZV0gewogICAgICAgICAgICBpZiBsZXQgaGFuZGxlciA9IHNlbGYuYm9ycm93VHJhbnNhY3Rpb25IYW5kbGVyRm9ySUQoaWQpIHsKICAgICAgICAgICAgICAgIHJldHVybiBoYW5kbGVyLmdldFZpZXdzKCkKICAgICAgICAgICAgfQogICAgICAgICAgICByZXR1cm4gW10KICAgICAgICB9CgogICAgICAgIC8vLyBSZXNvbHZlIGEgdmlldyBmb3IgYSBoYW5kbGVyIGZyb20gYSBnaXZlbiB0cmFuc2FjdGlvbiBJRAogICAgICAgIC8vLyBAcGFyYW0gdHJhbnNhY3Rpb25JZDogVGhlIElEIG9mIHRoZSB0cmFuc2FjdGlvbgogICAgICAgIC8vLyBAcGFyYW0gdmlld1R5cGU6IFRoZSB0eXBlIG9mIHRoZSB2aWV3IHRvIHJlc29sdmUKICAgICAgICAvLy8gQHJldHVybjogVGhlIHJlc29sdmVkIHZpZXcsIG9yIG5pbCBpZiBub3QgZm91bmQKICAgICAgICBhY2Nlc3MoYWxsKSBmdW4gcmVzb2x2ZUhhbmRsZXJWaWV3RnJvbVRyYW5zYWN0aW9uSUQoXyBpZDogVUludDY0LCB2aWV3VHlwZTogVHlwZSk6IEFueVN0cnVjdD8gewogICAgICAgICAgICBpZiBsZXQgaGFuZGxlciA9IHNlbGYuYm9ycm93VHJhbnNhY3Rpb25IYW5kbGVyRm9ySUQoaWQpIHsKICAgICAgICAgICAgICAgIHJldHVybiBoYW5kbGVyLnJlc29sdmVWaWV3KHZpZXdUeXBlKQogICAgICAgICAgICB9CiAgICAgICAgICAgIHJldHVybiBuaWwKICAgICAgICB9CgogICAgICAgIC8vLyBHZXQgYWxsIHRyYW5zYWN0aW9uIElEcyBzdG9yZWQgaW4gdGhlIG1hbmFnZXIKICAgICAgICAvLy8gQHJldHVybjogQW4gYXJyYXkgb2YgYWxsIHRyYW5zYWN0aW9uIElEcwogICAgICAgIGFjY2VzcyhhbGwpIHZpZXcgZnVuIGdldFRyYW5zYWN0aW9uSURzKCk6IFtVSW50NjRdIHsKICAgICAgICAgICAgcmV0dXJuIHNlbGYuc2NoZWR1bGVkVHJhbnNhY3Rpb25zLmtleXMKICAgICAgICB9CgogICAgICAgIC8vLyBHZXQgYWxsIHRyYW5zYWN0aW9uIElEcyBzdG9yZWQgaW4gdGhlIG1hbmFnZXIgYnkgYSBnaXZlbiBoYW5kbGVyCiAgICAgICAgLy8vIEBwYXJhbSBoYW5kbGVyVHlwZUlkZW50aWZpZXI6IFRoZSB0eXBlIGlkZW50aWZpZXIgb2YgdGhlIGhhbmRsZXIKICAgICAgICAvLy8gQHJldHVybjogQW4gYXJyYXkgb2YgYWxsIHRyYW5zYWN0aW9uIElEcwogICAgICAgIGFjY2VzcyhhbGwpIHZpZXcgZnVuIGdldFRyYW5zYWN0aW9uSURzQnlIYW5kbGVyKGhhbmRsZXJUeXBlSWRlbnRpZmllcjogU3RyaW5nLCBoYW5kbGVyVVVJRDogVUludDY0Pyk6IFtVSW50NjRdIHsKICAgICAgICAgICAgaWYgbGV0IGhhbmRsZXJzID0gc2VsZi5oYW5kbGVySW5mb3NbaGFuZGxlclR5cGVJZGVudGlmaWVyXSB7CiAgICAgICAgICAgICAgICBpZiBoYW5kbGVyVVVJRCAhPSBuaWwgewogICAgICAgICAgICAgICAgICAgIGlmIGxldCBoYW5kbGVySW5mbyA9IGhhbmRsZXJzW2hhbmRsZXJVVUlEIV0gewogICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gaGFuZGxlckluZm8udHJhbnNhY3Rpb25JRHMKICAgICAgICAgICAgICAgICAgICB9IAogICAgICAgICAgICAgICAgfSBlbHNlIGlmIGhhbmRsZXJzLmtleXMubGVuZ3RoID09IDEgewogICAgICAgICAgICAgICAgICAgIC8vIElmIG5vIHV1aWQgaXMgcHJvdmlkZWQsIHdlIGNhbiBqdXN0IGRlZmF1bHQgdG8gdGhlIG9ubHkgaGFuZGxlciB1dWlkCiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGhhbmRsZXJzW2hhbmRsZXJzLmtleXNbMF1dIS50cmFuc2FjdGlvbklEcwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIHJldHVybiBbXQogICAgICAgIH0KCiAgICAgICAgLy8vIEdldCBhbGwgdHJhbnNhY3Rpb24gSURzIHN0b3JlZCBpbiB0aGUgbWFuYWdlciBieSBhIGdpdmVuIHRpbWVzdGFtcAogICAgICAgIC8vLyBAcGFyYW0gdGltZXN0YW1wOiBUaGUgdGltZXN0YW1wCiAgICAgICAgLy8vIEByZXR1cm46IEFuIGFycmF5IG9mIGFsbCB0cmFuc2FjdGlvbiBJRHMKICAgICAgICBhY2Nlc3MoYWxsKSB2aWV3IGZ1biBnZXRUcmFuc2FjdGlvbklEc0J5VGltZXN0YW1wKF8gdGltZXN0YW1wOiBVRml4NjQpOiBbVUludDY0XSB7CiAgICAgICAgICAgIHJldHVybiBzZWxmLmlkc0J5VGltZXN0YW1wW3RpbWVzdGFtcF0gPz8gW10KICAgICAgICB9CgogICAgICAgIC8vLyBHZXQgYWxsIHRoZSB0aW1lc3RhbXBzIGFuZCBJRHMgZnJvbSBhIGdpdmVuIHJhbmdlIG9mIHRpbWVzdGFtcHMKICAgICAgICAvLy8gQHBhcmFtIHN0YXJ0VGltZXN0YW1wOiBUaGUgc3RhcnQgdGltZXN0YW1wCiAgICAgICAgLy8vIEBwYXJhbSBlbmRUaW1lc3RhbXA6IFRoZSBlbmQgdGltZXN0YW1wCiAgICAgICAgLy8vIEByZXR1cm46IEEgZGljdGlvbmFyeSBvZiB0aW1lc3RhbXBzIGFuZCBJRHMKICAgICAgICBhY2Nlc3MoYWxsKSBmdW4gZ2V0VHJhbnNhY3Rpb25JRHNCeVRpbWVzdGFtcFJhbmdlKHN0YXJ0VGltZXN0YW1wOiBVRml4NjQsIGVuZFRpbWVzdGFtcDogVUZpeDY0KToge1VGaXg2NDogW1VJbnQ2NF19IHsKICAgICAgICAgICAgdmFyIHRyYW5zYWN0aW9uc0luVGltZWZyYW1lOiB7VUZpeDY0OiBbVUludDY0XX0gPSB7fQogICAgICAgICAgICAKICAgICAgICAgICAgLy8gVmFsaWRhdGUgaW5wdXQgcGFyYW1ldGVycwogICAgICAgICAgICBpZiBzdGFydFRpbWVzdGFtcCA+IGVuZFRpbWVzdGFtcCB7CiAgICAgICAgICAgICAgICByZXR1cm4gdHJhbnNhY3Rpb25zSW5UaW1lZnJhbWUKICAgICAgICAgICAgfQogICAgICAgICAgICAKICAgICAgICAgICAgLy8gR2V0IGFsbCB0aW1lc3RhbXBzIHRoYXQgZmFsbCB3aXRoaW4gdGhlIHNwZWNpZmllZCByYW5nZQogICAgICAgICAgICBsZXQgYWxsVGltZXN0YW1wc0JlZm9yZUVuZCA9IHNlbGYuc29ydGVkVGltZXN0YW1wcy5nZXRCZWZvcmUoY3VycmVudDogZW5kVGltZXN0YW1wKQogICAgICAgICAgICAKICAgICAgICAgICAgZm9yIHRpbWVzdGFtcCBpbiBhbGxUaW1lc3RhbXBzQmVmb3JlRW5kIHsKICAgICAgICAgICAgICAgIC8vIENoZWNrIGlmIHRoaXMgdGltZXN0YW1wIGZhbGxzIHdpdGhpbiBvdXIgcmFuZ2UKICAgICAgICAgICAgICAgIGlmIHRpbWVzdGFtcCA8IHN0YXJ0VGltZXN0YW1wIHsgY29udGludWUgfQogICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICB2YXIgdGltZXN0YW1wVHJhbnNhY3Rpb25zOiBbVUludDY0XSA9IHNlbGYuaWRzQnlUaW1lc3RhbXBbdGltZXN0YW1wXSA/PyBbXQogICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICBpZiB0aW1lc3RhbXBUcmFuc2FjdGlvbnMubGVuZ3RoID4gMCB7CiAgICAgICAgICAgICAgICAgICAgdHJhbnNhY3Rpb25zSW5UaW1lZnJhbWVbdGltZXN0YW1wXSA9IHRpbWVzdGFtcFRyYW5zYWN0aW9ucwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIAogICAgICAgICAgICByZXR1cm4gdHJhbnNhY3Rpb25zSW5UaW1lZnJhbWUKICAgICAgICB9CgogICAgICAgIC8vLyBHZXQgdGhlIHN0YXR1cyBvZiBhIHRyYW5zYWN0aW9uIGJ5IGl0cyBJRAogICAgICAgIC8vLyBAcGFyYW0gaWQ6IFRoZSBJRCBvZiB0aGUgdHJhbnNhY3Rpb24KICAgICAgICAvLy8gQHJldHVybjogVGhlIHN0YXR1cyBvZiB0aGUgdHJhbnNhY3Rpb24sIG9yIFN0YXR1cy5Vbmtub3duIGlmIG5vdCBmb3VuZCBpbiBtYW5hZ2VyCiAgICAgICAgYWNjZXNzKGFsbCkgdmlldyBmdW4gZ2V0VHJhbnNhY3Rpb25TdGF0dXMoaWQ6IFVJbnQ2NCk6IEZsb3dUcmFuc2FjdGlvblNjaGVkdWxlci5TdGF0dXM/IHsKICAgICAgICAgICAgaWYgc2VsZi5zY2hlZHVsZWRUcmFuc2FjdGlvbnMuY29udGFpbnNLZXkoaWQpIHsKICAgICAgICAgICAgICAgIHJldHVybiBGbG93VHJhbnNhY3Rpb25TY2hlZHVsZXIuZ2V0U3RhdHVzKGlkOiBpZCkKICAgICAgICAgICAgfQogICAgICAgICAgICByZXR1cm4gRmxvd1RyYW5zYWN0aW9uU2NoZWR1bGVyLlN0YXR1cy5Vbmtub3duCiAgICAgICAgfQoKICAgICAgICAvLy8gR2V0cyB0aGUgc29ydGVkIHRpbWVzdGFtcHMgc3RydWN0CiAgICAgICAgLy8vIEByZXR1cm46IFRoZSBzb3J0ZWQgdGltZXN0YW1wcyBzdHJ1Y3QKICAgICAgICBhY2Nlc3MoYWxsKSB2aWV3IGZ1biBnZXRTb3J0ZWRUaW1lc3RhbXBzKCk6IEZsb3dUcmFuc2FjdGlvblNjaGVkdWxlci5Tb3J0ZWRUaW1lc3RhbXBzIHsKICAgICAgICAgICAgcmV0dXJuIHNlbGYuc29ydGVkVGltZXN0YW1wcwogICAgICAgIH0KICAgIH0KCiAgICAvLy8gQ3JlYXRlIGEgbmV3IE1hbmFnZXIgaW5zdGFuY2UKICAgIC8vLyBAcmV0dXJuOiBBIG5ldyBNYW5hZ2VyIHJlc291cmNlCiAgICBhY2Nlc3MoYWxsKSBmdW4gY3JlYXRlTWFuYWdlcigpOiBAe01hbmFnZXJ9IHsKICAgICAgICByZXR1cm4gPC1jcmVhdGUgTWFuYWdlclYxKCkKICAgIH0KCiAgICBhY2Nlc3MoYWxsKSBpbml0KCkgewogICAgICAgIHNlbGYubWFuYWdlclN0b3JhZ2VQYXRoID0gL3N0b3JhZ2UvZmxvd1RyYW5zYWN0aW9uU2NoZWR1bGVyTWFuYWdlcgogICAgICAgIHNlbGYubWFuYWdlclB1YmxpY1BhdGggPSAvcHVibGljL2Zsb3dUcmFuc2FjdGlvblNjaGVkdWxlck1hbmFnZXIKICAgIH0KCiAgICAvLy8gR2V0IGEgcHVibGljIHJlZmVyZW5jZSB0byBhIG1hbmFnZXIgYXQgdGhlIGdpdmVuIGFkZHJlc3MKICAgIC8vLyBAcGFyYW0gYWRkcmVzczogVGhlIGFkZHJlc3Mgb2YgdGhlIG1hbmFnZXIKICAgIC8vLyBAcmV0dXJuOiBBIHB1YmxpYyByZWZlcmVuY2UgdG8gdGhlIG1hbmFnZXIKICAgIGFjY2VzcyhhbGwpIHZpZXcgZnVuIGJvcnJvd01hbmFnZXIoYXQ6IEFkZHJlc3MpOiAme01hbmFnZXJ9PyB7CiAgICAgICAgcmV0dXJuIGdldEFjY291bnQoYXQpLmNhcGFiaWxpdGllcy5ib3Jyb3c8JntNYW5hZ2VyfT4oc2VsZi5tYW5hZ2VyUHVibGljUGF0aCkKICAgIH0KCiAgICAvKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAgICAKICAgIENPQSBIYW5kbGVyIFV0aWxzCgogICAgKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KCiAgICBhY2Nlc3MoYWxsKSBldmVudCBDT0FIYW5kbGVyRXhlY3V0aW9uRXJyb3IoaWQ6IFVJbnQ2NCwgb3duZXI6IEFkZHJlc3M/LCBjb2FBZGRyZXNzOiBTdHJpbmc/LCBlcnJvck1lc3NhZ2U6IFN0cmluZykKCiAgICBhY2Nlc3MoYWxsKSB2aWV3IGZ1biBjb2FIYW5kbGVyU3RvcmFnZVBhdGgoKTogU3RvcmFnZVBhdGggewogICAgICAgIHJldHVybiAvc3RvcmFnZS9jb2FTY2hlZHVsZWRUcmFuc2FjdGlvbkhhbmRsZXIKICAgIH0KCiAgICBhY2Nlc3MoYWxsKSB2aWV3IGZ1biBjb2FIYW5kbGVyUHVibGljUGF0aCgpOiBQdWJsaWNQYXRoIHsKICAgICAgICByZXR1cm4gL3B1YmxpYy9jb2FTY2hlZHVsZWRUcmFuc2FjdGlvbkhhbmRsZXIKICAgIH0KCiAgICAvLy8gQ09BVHJhbnNhY3Rpb25IYW5kbGVyIGlzIGEgcmVzb3VyY2UgdGhhdCB3cmFwcyBhIGNhcGFiaWxpdHkgdG8gYSBDT0EgKENhZGVuY2UgT3duZWQgQWNjb3VudCkKICAgIC8vLyBhbmQgaW1wbGVtZW50cyB0aGUgVHJhbnNhY3Rpb25IYW5kbGVyIGludGVyZmFjZSB0byBhbGxvdyBzY2hlZHVsaW5nIHRyYW5zYWN0aW9ucyBmb3IgQ09Bcy4KICAgIC8vLyBUaGlzIGhhbmRsZXIgZW5hYmxlcyB1c2VycyB0byBzY2hlZHVsZSB0cmFuc2FjdGlvbnMgdGhhdCB3aWxsIGJlIGV4ZWN1dGVkIG9uIGJlaGFsZiBvZiB0aGVpciBDT0EuCiAgICBhY2Nlc3MoYWxsKSByZXNvdXJjZSBDT0FUcmFuc2FjdGlvbkhhbmRsZXI6IEZsb3dUcmFuc2FjdGlvblNjaGVkdWxlci5UcmFuc2FjdGlvbkhhbmRsZXIgewogICAgICAgIC8vLyBUaGUgY2FwYWJpbGl0eSB0byB0aGUgQ09BIHJlc291cmNlCiAgICAgICAgYWNjZXNzKHNlbGYpIGxldCBjb2FDYXBhYmlsaXR5OiBDYXBhYmlsaXR5PGF1dGgoRVZNLk93bmVyKSAmRVZNLkNhZGVuY2VPd25lZEFjY291bnQ+CgogICAgICAgIC8vLyBUaGUgY2FwYWJpbGl0eSB0byB0aGUgRmxvd1Rva2VuIHZhdWx0CiAgICAgICAgYWNjZXNzKHNlbGYpIGxldCBmbG93VG9rZW5WYXVsdENhcGFiaWxpdHk6IENhcGFiaWxpdHk8YXV0aChGdW5naWJsZVRva2VuLldpdGhkcmF3KSAmRmxvd1Rva2VuLlZhdWx0PgoKICAgICAgICBpbml0KGNvYUNhcGFiaWxpdHk6IENhcGFiaWxpdHk8YXV0aChFVk0uT3duZXIpICZFVk0uQ2FkZW5jZU93bmVkQWNjb3VudD4sCiAgICAgICAgICAgICBmbG93VG9rZW5WYXVsdENhcGFiaWxpdHk6IENhcGFiaWxpdHk8YXV0aChGdW5naWJsZVRva2VuLldpdGhkcmF3KSAmRmxvd1Rva2VuLlZhdWx0PiwKICAgICAgICApCiAgICAgICAgewogICAgICAgICAgICBwcmUgewogICAgICAgICAgICAgICAgY29hQ2FwYWJpbGl0eS5jaGVjaygpOiAiQ09BIGNhcGFiaWxpdHkgaXMgaW52YWxpZCBvciBleHBpcmVkIgogICAgICAgICAgICAgICAgZmxvd1Rva2VuVmF1bHRDYXBhYmlsaXR5LmNoZWNrKCk6ICJGbG93VG9rZW4gdmF1bHQgY2FwYWJpbGl0eSBpcyBpbnZhbGlkIG9yIGV4cGlyZWQiCiAgICAgICAgICAgIH0KICAgICAgICAgICAgc2VsZi5jb2FDYXBhYmlsaXR5ID0gY29hQ2FwYWJpbGl0eQogICAgICAgICAgICBzZWxmLmZsb3dUb2tlblZhdWx0Q2FwYWJpbGl0eSA9IGZsb3dUb2tlblZhdWx0Q2FwYWJpbGl0eQogICAgICAgIH0KCiAgICAgICAgYWNjZXNzKHNlbGYpIGZ1biBlbWl0RXJyb3IoaWQ6IFVJbnQ2NCwgZXJyb3JNZXNzYWdlOiBTdHJpbmcpIHsKICAgICAgICAgICAgbGV0IGNvYSA9IHNlbGYuY29hQ2FwYWJpbGl0eS5ib3Jyb3coKSEKICAgICAgICAgICAgZW1pdCBDT0FIYW5kbGVyRXhlY3V0aW9uRXJyb3IoaWQ6IGlkLCBvd25lcjogc2VsZi5vd25lcj8uYWRkcmVzcywgY29hQWRkcmVzczogY29hLmFkZHJlc3MoKS50b1N0cmluZygpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlcnJvck1lc3NhZ2U6IGVycm9yTWVzc2FnZSkKICAgICAgICB9CgogICAgICAgIC8vLyBFeGVjdXRlIHRoZSBzY2hlZHVsZWQgdHJhbnNhY3Rpb24gdXNpbmcgdGhlIENPQQogICAgICAgIC8vLyBAcGFyYW0gaWQ6IFRoZSBJRCBvZiB0aGUgc2NoZWR1bGVkIHRyYW5zYWN0aW9uCiAgICAgICAgLy8vIEBwYXJhbSBkYXRhOiBPcHRpb25hbCBkYXRhIHBhc3NlZCB0byB0aGUgdHJhbnNhY3Rpb24gZXhlY3V0aW9uLiBJbiB0aGlzIGNhc2UsIHRoZSBkYXRhIG11c3QgYmUgYSBDT0FIYW5kbGVyUGFyYW1zIHN0cnVjdCB3aXRoIHZhbGlkIHZhbHVlcy4KICAgICAgICBhY2Nlc3MoRmxvd1RyYW5zYWN0aW9uU2NoZWR1bGVyLkV4ZWN1dGUpIGZ1biBleGVjdXRlVHJhbnNhY3Rpb24oaWQ6IFVJbnQ2NCwgZGF0YTogQW55U3RydWN0PykgewoKICAgICAgICAgICAgLy8gQm9ycm93IHRoZSBDT0EgY2FwYWJpbGl0eQogICAgICAgICAgICBsZXQgY29hID0gc2VsZi5jb2FDYXBhYmlsaXR5LmJvcnJvdygpCiAgICAgICAgICAgIGlmIGNvYSA9PSBuaWwgewogICAgICAgICAgICAgICAgZW1pdCBDT0FIYW5kbGVyRXhlY3V0aW9uRXJyb3IoaWQ6IGlkLCBvd25lcjogc2VsZi5vd25lcj8uYWRkcmVzcyA/PyBBZGRyZXNzKDB4MCksIGNvYUFkZHJlc3M6IG5pbCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVycm9yTWVzc2FnZTogIkNPQSBjYXBhYmlsaXR5IGlzIGludmFsaWQgb3IgZXhwaXJlZCBmb3Igc2NoZWR1bGVkIHRyYW5zYWN0aW9uIHdpdGggSUQgXChpZCkiKQogICAgICAgICAgICAgICAgcmV0dXJuCiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIC8vIFBhcnNlIHRoZSBkYXRhIGludG8gYSBsaXN0IG9mIENPQUhhbmRsZXJQYXJhbXMKICAgICAgICAgICAgLy8gSWYgdGhlIGRhdGEgaXMgYSBzaW5nbGUgQ09BSGFuZGxlclBhcmFtcyBzdHJ1Y3QsIHdyYXAgaXQgaW4gYSBsaXN0CiAgICAgICAgICAgIHZhciBwYXJhbXM6IFtDT0FIYW5kbGVyUGFyYW1zXT8gPSBkYXRhIGFzPyBbQ09BSGFuZGxlclBhcmFtc10KICAgICAgICAgICAgaWYgcGFyYW1zID09IG5pbCB7CiAgICAgICAgICAgICAgICBpZiBsZXQgcGFyYW0gPSBkYXRhIGFzPyBDT0FIYW5kbGVyUGFyYW1zIHsKICAgICAgICAgICAgICAgICAgICBwYXJhbXMgPSBbcGFyYW1dCiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIC8vIEl0ZXJhdGUgdGhyb3VnaCBhbGwgdGhlIENPQSB0cmFuc2FjdGlvbnMgYW5kIGV4ZWN1dGUgdGhlbSBhbGwKICAgICAgICAgICAgLy8gSWYgcmV2ZXJ0T25GYWlsdXJlIGlzIHRydWUgZm9yIGEgdHJhbnNhY3Rpb24gYW5kIGFueSBwYXJ0IG9mIGl0IGZhaWxzLCB0aGUgZW50aXJlIHNjaGVkdWxlZCB0cmFuc2FjdGlvbiB3aWxsIGJlIHJldmVydGVkCiAgICAgICAgICAgIC8vIElmIG5vdCBidXQgYSBwYXJ0IG9mIHRoZSB0cmFuc2FjdGlvbiBmYWlscywgYW4gZXJyb3IgZXZlbnQgd2lsbCBiZSBlbWl0dGVkIGJ1dCB0aGUgc2NoZWR1bGVkIHRyYW5zYWN0aW9uIHdpbGwgY29udGludWUgdG8gZXhlY3V0ZSB0aGUgbmV4dCB0cmFuc2FjdGlvbgogICAgICAgICAgICAvLwogICAgICAgICAgICBpZiBsZXQgdHJhbnNhY3Rpb25zID0gcGFyYW1zIHsKICAgICAgICAgICAgICAgIGZvciBpbmRleCwgdHhQYXJhbXMgaW4gdHJhbnNhY3Rpb25zIHsKICAgICAgICAgICAgICAgICAgICBzd2l0Y2ggdHhQYXJhbXMudHhUeXBlIHsKICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSBDT0FIYW5kbGVyVHhUeXBlLkRlcG9zaXRGTE9XOgogICAgICAgICAgICAgICAgICAgICAgICAgICAgbGV0IHZhdWx0ID0gc2VsZi5mbG93VG9rZW5WYXVsdENhcGFiaWxpdHkuYm9ycm93KCkKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIHZhdWx0ID09IG5pbCB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgIXR4UGFyYW1zLnJldmVydE9uRmFpbHVyZSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNlbGYuZW1pdEVycm9yKGlkOiBpZCwgZXJyb3JNZXNzYWdlOiAiRmxvd1Rva2VuIHZhdWx0IGNhcGFiaWxpdHkgaXMgaW52YWxpZCBvciBleHBpcmVkIGZvciBzY2hlZHVsZWQgdHJhbnNhY3Rpb24gd2l0aCBJRCBcKGlkKSBhbmQgaW5kZXggXChpbmRleCkiKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb250aW51ZQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBhbmljKCJGbG93VG9rZW4gdmF1bHQgY2FwYWJpbGl0eSBpcyBpbnZhbGlkIG9yIGV4cGlyZWQgZm9yIHNjaGVkdWxlZCB0cmFuc2FjdGlvbiB3aXRoIElEIFwoaWQpIGFuZCBpbmRleCBcKGluZGV4KSIpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIHR4UGFyYW1zLmFtb3VudCEgPiB2YXVsdCEuYmFsYW5jZSAmJiAhdHhQYXJhbXMucmV2ZXJ0T25GYWlsdXJlIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZWxmLmVtaXRFcnJvcihpZDogaWQsIGVycm9yTWVzc2FnZTogIkluc3VmZmljaWVudCBGTE9XIGluIEZsb3dUb2tlbiB2YXVsdCBmb3IgZGVwb3NpdCBpbnRvIENPQSBmb3Igc2NoZWR1bGVkIHRyYW5zYWN0aW9uIHdpdGggSUQgXChpZCkgYW5kIGluZGV4IFwoaW5kZXgpIikKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb250aW51ZQogICAgICAgICAgICAgICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIERlcG9zaXQgdGhlIEZMT1cgaW50byB0aGUgQ09BIHZhdWx0LiBJZiB0aGVyZSBpc24ndCBlbm91Z2ggRkxPVyBpbiB0aGUgdmF1bHQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvL3RoZSB0cmFuc2FjdGlvbiB3aWxsIGJlIHJldmVydGVkIGJlY2F1c2Ugd2Uga25vdyByZXZlcnRPbkZhaWx1cmUgaXMgdHJ1ZQogICAgICAgICAgICAgICAgICAgICAgICAgICAgY29hIS5kZXBvc2l0KGZyb206IDwtdmF1bHQhLndpdGhkcmF3KGFtb3VudDogdHhQYXJhbXMuYW1vdW50ISkgYXMhIEBGbG93VG9rZW4uVmF1bHQpCiAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgQ09BSGFuZGxlclR4VHlwZS5XaXRoZHJhd0ZMT1c6CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBsZXQgdmF1bHQgPSBzZWxmLmZsb3dUb2tlblZhdWx0Q2FwYWJpbGl0eS5ib3Jyb3coKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgdmF1bHQgPT0gbmlsIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAhdHhQYXJhbXMucmV2ZXJ0T25GYWlsdXJlIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2VsZi5lbWl0RXJyb3IoaWQ6IGlkLCBlcnJvck1lc3NhZ2U6ICJGbG93VG9rZW4gdmF1bHQgY2FwYWJpbGl0eSBpcyBpbnZhbGlkIG9yIGV4cGlyZWQgZm9yIHNjaGVkdWxlZCB0cmFuc2FjdGlvbiB3aXRoIElEIFwoaWQpIGFuZCBpbmRleCBcKGluZGV4KSIpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcGFuaWMoIkZsb3dUb2tlbiB2YXVsdCBjYXBhYmlsaXR5IGlzIGludmFsaWQgb3IgZXhwaXJlZCBmb3Igc2NoZWR1bGVkIHRyYW5zYWN0aW9uIHdpdGggSUQgXChpZCkgYW5kIGluZGV4IFwoaW5kZXgpIikKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgICAgICAgICAgbGV0IGFtb3VudCA9IEVWTS5CYWxhbmNlKGF0dG9mbG93OiAwKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgYW1vdW50LnNldEZMT1coZmxvdzogdHhQYXJhbXMuYW1vdW50ISkKCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiBhbW91bnQuYXR0b2Zsb3cgPiBjb2EhLmJhbGFuY2UoKS5hdHRvZmxvdyAmJiAhdHhQYXJhbXMucmV2ZXJ0T25GYWlsdXJlIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZWxmLmVtaXRFcnJvcihpZDogaWQsIGVycm9yTWVzc2FnZTogIkluc3VmZmljaWVudCBGTE9XIGluIENPQSB2YXVsdCBmb3Igd2l0aGRyYXdhbCBmcm9tIENPQSBmb3Igc2NoZWR1bGVkIHRyYW5zYWN0aW9uIHdpdGggSUQgXChpZCkgYW5kIGluZGV4IFwoaW5kZXgpIikKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb250aW51ZQogICAgICAgICAgICAgICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIFdpdGhkcmF3IHRoZSBGTE9XIGZyb20gdGhlIENPQSB2YXVsdC4gSWYgdGhlcmUgaXNuJ3QgZW5vdWdoIEZMT1cgaW4gdGhlIENPQSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIHRoZSB0cmFuc2FjdGlvbiB3aWxsIGJlIHJldmVydGVkIGJlY2F1c2Ugd2Uga25vdyByZXZlcnRPbkZhaWx1cmUgaXMgdHJ1ZQogICAgICAgICAgICAgICAgICAgICAgICAgICAgdmF1bHQhLmRlcG9zaXQoZnJvbTogPC1jb2EhLndpdGhkcmF3KGJhbGFuY2U6IGFtb3VudCkpCiAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgQ09BSGFuZGxlclR4VHlwZS5DYWxsOgogICAgICAgICAgICAgICAgICAgICAgICAgICAgbGV0IHJlc3VsdCA9IGNvYSEuY2FsbCh0bzogdHhQYXJhbXMuY2FsbFRvRVZNQWRkcmVzcyEsIGRhdGE6IHR4UGFyYW1zLmRhdGEhLCBnYXNMaW1pdDogdHhQYXJhbXMuZ2FzTGltaXQhLCB2YWx1ZTogdHhQYXJhbXMudmFsdWUhKQoKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIHJlc3VsdC5zdGF0dXMgIT0gRVZNLlN0YXR1cy5zdWNjZXNzZnVsIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAhdHhQYXJhbXMucmV2ZXJ0T25GYWlsdXJlIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2VsZi5lbWl0RXJyb3IoaWQ6IGlkLCBlcnJvck1lc3NhZ2U6ICJFVk0gY2FsbCBmYWlsZWQgZm9yIHNjaGVkdWxlZCB0cmFuc2FjdGlvbiB3aXRoIElEIFwoaWQpIGFuZCBpbmRleCBcKGluZGV4KSB3aXRoIGVycm9yOiBcKHJlc3VsdC5lcnJvckNvZGUpOlwocmVzdWx0LmVycm9yTWVzc2FnZSkiKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb250aW51ZQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBhbmljKCJFVk0gY2FsbCBmYWlsZWQgZm9yIHNjaGVkdWxlZCB0cmFuc2FjdGlvbiB3aXRoIElEIFwoaWQpIGFuZCBpbmRleCBcKGluZGV4KSB3aXRoIGVycm9yOiBcKHJlc3VsdC5lcnJvckNvZGUpOlwocmVzdWx0LmVycm9yTWVzc2FnZSkiKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICBzZWxmLmVtaXRFcnJvcihpZDogaWQsIGVycm9yTWVzc2FnZTogIkludmFsaWQgc2NoZWR1bGVkIHRyYW5zYWN0aW9uIGRhdGEgdHlwZSBmb3IgQ09BIGhhbmRsZXIgZXhlY3V0aW9uIGZvciB0eCB3aXRoIElEIFwoaWQpISBFeHBlY3RlZCBbRmxvd1RyYW5zYWN0aW9uU2NoZWR1bGVyVXRpbHMuQ09BSGFuZGxlclBhcmFtc10gYnV0IGdvdCBcKGRhdGEuZ2V0VHlwZSgpLmlkZW50aWZpZXIpIikKICAgICAgICAgICAgICAgIHJldHVybgogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICAvLy8gR2V0IHRoZSB2aWV3cyBzdXBwb3J0ZWQgYnkgdGhpcyBoYW5kbGVyCiAgICAgICAgLy8vIEByZXR1cm46IEFycmF5IG9mIHZpZXcgdHlwZXMKICAgICAgICBhY2Nlc3MoYWxsKSB2aWV3IGZ1biBnZXRWaWV3cygpOiBbVHlwZV0gewogICAgICAgICAgICByZXR1cm4gWwogICAgICAgICAgICAgICAgVHlwZTxDT0FIYW5kbGVyVmlldz4oKSwKICAgICAgICAgICAgICAgIFR5cGU8U3RvcmFnZVBhdGg+KCksCiAgICAgICAgICAgICAgICBUeXBlPFB1YmxpY1BhdGg+KCksCiAgICAgICAgICAgICAgICBUeXBlPE1ldGFkYXRhVmlld3MuRGlzcGxheT4oKQogICAgICAgICAgICBdCiAgICAgICAgfQoKICAgICAgICAvLy8gUmVzb2x2ZSBhIHZpZXcgZm9yIHRoaXMgaGFuZGxlcgogICAgICAgIC8vLyBAcGFyYW0gdmlld1R5cGU6IFRoZSB0eXBlIG9mIHZpZXcgdG8gcmVzb2x2ZQogICAgICAgIC8vLyBAcmV0dXJuOiBUaGUgcmVzb2x2ZWQgdmlldyBkYXRhLCBvciBuaWwgaWYgbm90IHN1cHBvcnRlZAogICAgICAgIGFjY2VzcyhhbGwpIGZ1biByZXNvbHZlVmlldyhfIHZpZXdUeXBlOiBUeXBlKTogQW55U3RydWN0PyB7CiAgICAgICAgICAgIGlmIHZpZXdUeXBlID09IFR5cGU8Q09BSGFuZGxlclZpZXc+KCkgewogICAgICAgICAgICAgICAgcmV0dXJuIENPQUhhbmRsZXJWaWV3KAogICAgICAgICAgICAgICAgICAgIGNvYU93bmVyOiBzZWxmLmNvYUNhcGFiaWxpdHkuYm9ycm93KCk/Lm93bmVyPy5hZGRyZXNzLAogICAgICAgICAgICAgICAgICAgIGNvYUVWTUFkZHJlc3M6IHNlbGYuY29hQ2FwYWJpbGl0eS5ib3Jyb3coKT8uYWRkcmVzcygpLAogICAgICAgICAgICAgICAgICAgIGNvYUJhbGFuY2U6IHNlbGYuY29hQ2FwYWJpbGl0eS5ib3Jyb3coKT8uYmFsYW5jZSgpLAogICAgICAgICAgICAgICAgKQogICAgICAgICAgICB9CiAgICAgICAgICAgIGlmIHZpZXdUeXBlID09IFR5cGU8U3RvcmFnZVBhdGg+KCkgewogICAgICAgICAgICAgICAgcmV0dXJuIEZsb3dUcmFuc2FjdGlvblNjaGVkdWxlclV0aWxzLmNvYUhhbmRsZXJTdG9yYWdlUGF0aCgpCiAgICAgICAgICAgIH0gZWxzZSBpZiB2aWV3VHlwZSA9PSBUeXBlPFB1YmxpY1BhdGg+KCkgewogICAgICAgICAgICAgICAgcmV0dXJuIEZsb3dUcmFuc2FjdGlvblNjaGVkdWxlclV0aWxzLmNvYUhhbmRsZXJQdWJsaWNQYXRoKCkKICAgICAgICAgICAgfSBlbHNlIGlmIHZpZXdUeXBlID09IFR5cGU8TWV0YWRhdGFWaWV3cy5EaXNwbGF5PigpIHsKICAgICAgICAgICAgICAgIHJldHVybiBNZXRhZGF0YVZpZXdzLkRpc3BsYXkoCiAgICAgICAgICAgICAgICAgICAgbmFtZTogIkNPQSBTY2hlZHVsZWQgVHJhbnNhY3Rpb24gSGFuZGxlciIsCiAgICAgICAgICAgICAgICAgICAgZGVzY3JpcHRpb246ICJTY2hlZHVsZWQgVHJhbnNhY3Rpb24gSGFuZGxlciB0aGF0IGNhbiBleGVjdXRlIHRyYW5zYWN0aW9ucyBvbiBiZWhhbGYgb2YgYSBDT0EiLAogICAgICAgICAgICAgICAgICAgIHRodW1ibmFpbDogTWV0YWRhdGFWaWV3cy5IVFRQRmlsZSgKICAgICAgICAgICAgICAgICAgICAgICAgdXJsOiAiIgogICAgICAgICAgICAgICAgICAgICkKICAgICAgICAgICAgICAgICkKICAgICAgICAgICAgfQogICAgICAgICAgICByZXR1cm4gbmlsCiAgICAgICAgfQogICAgfQoKICAgIC8vLyBFbnVtIGZvciBDT0EgaGFuZGxlciBleGVjdXRpb24gdHlwZQogICAgYWNjZXNzKGFsbCkgZW51bSBDT0FIYW5kbGVyVHhUeXBlOiBVSW50OCB7CiAgICAgICAgYWNjZXNzKGFsbCkgY2FzZSBEZXBvc2l0RkxPVwogICAgICAgIGFjY2VzcyhhbGwpIGNhc2UgV2l0aGRyYXdGTE9XCiAgICAgICAgYWNjZXNzKGFsbCkgY2FzZSBDYWxsCgogICAgICAgIC8vIFRPRE86IFNob3VsZCB3ZSBoYXZlIG90aGVyIHRyYW5zYWN0aW9uIHR5cGVzPz8KICAgIH0KCiAgICBhY2Nlc3MoYWxsKSBzdHJ1Y3QgQ09BSGFuZGxlclBhcmFtcyB7CgogICAgICAgIC8vLyBUaGUgdHlwZSBvZiB0cmFuc2FjdGlvbiB0byBleGVjdXRlCiAgICAgICAgYWNjZXNzKGFsbCkgbGV0IHR4VHlwZTogQ09BSGFuZGxlclR4VHlwZQoKICAgICAgICAvLy8gSW5kaWNhdGVzIGlmIHRoZSB3aG9sZSBzZXQgb2Ygc2NoZWR1bGVkIHRyYW5zYWN0aW9ucyBzaG91bGQgYmUgcmV2ZXJ0ZWQKICAgICAgICAvLy8gaWYgdGhpcyBvbmUgdHJhbnNhY3Rpb24gZmFpbHMgdG8gZXhlY3V0ZSBpbiBFVk0KICAgICAgICBhY2Nlc3MoYWxsKSBsZXQgcmV2ZXJ0T25GYWlsdXJlOiBCb29sCgogICAgICAgIC8vLyBUaGUgYW1vdW50IG9mIEZMT1cgdG8gZGVwb3NpdCBvciB3aXRoZHJhdwogICAgICAgIC8vLyBOb3QgcmVxdWlyZWQgZm9yIHRoZSBDYWxsIHRyYW5zYWN0aW9uIHR5cGUKICAgICAgICBhY2Nlc3MoYWxsKSBsZXQgYW1vdW50OiBVRml4NjQ/CgogICAgICAgIC8vLyBUaGUgZm9sbG93aW5nIGZpZWxkcyBhcmUgb25seSByZXF1aXJlZCBmb3IgdGhlIENhbGwgdHJhbnNhY3Rpb24gdHlwZQogICAgICAgIGFjY2VzcyhhbGwpIGxldCBjYWxsVG9FVk1BZGRyZXNzOiBFVk0uRVZNQWRkcmVzcz8KICAgICAgICBhY2Nlc3MoYWxsKSBsZXQgZGF0YTogW1VJbnQ4XT8KICAgICAgICBhY2Nlc3MoYWxsKSBsZXQgZ2FzTGltaXQ6IFVJbnQ2ND8KICAgICAgICBhY2Nlc3MoYWxsKSBsZXQgdmFsdWU6IEVWTS5CYWxhbmNlPwoKICAgICAgICBpbml0KHR4VHlwZTogVUludDgsIHJldmVydE9uRmFpbHVyZTogQm9vbCwgYW1vdW50OiBVRml4NjQ/LCBjYWxsVG9FVk1BZGRyZXNzOiBTdHJpbmc/LCBkYXRhOiBbVUludDhdPywgZ2FzTGltaXQ6IFVJbnQ2ND8sIHZhbHVlOiBVSW50PykgewogICAgICAgICAgICBzZWxmLnR4VHlwZSA9IENPQUhhbmRsZXJUeFR5cGUocmF3VmFsdWU6IHR4VHlwZSkKICAgICAgICAgICAgICAgID8/IHBhbmljKCJJbnZhbGlkIENPQSB0cmFuc2FjdGlvbiB0eXBlIGVudW0iKQogICAgICAgICAgICBzZWxmLnJldmVydE9uRmFpbHVyZSA9IHJldmVydE9uRmFpbHVyZQogICAgICAgICAgICBpZiBzZWxmLnR4VHlwZSA9PSBDT0FIYW5kbGVyVHhUeXBlLkRlcG9zaXRGTE9XIHsKICAgICAgICAgICAgICAgIGFzc2VydChhbW91bnQgIT0gbmlsLCBtZXNzYWdlOiAiQW1vdW50IGlzIHJlcXVpcmVkIGZvciBkZXBvc2l0IGJ1dCB3YXMgbm90IHByb3ZpZGVkIikKICAgICAgICAgICAgfQogICAgICAgICAgICBpZiBzZWxmLnR4VHlwZSA9PSBDT0FIYW5kbGVyVHhUeXBlLldpdGhkcmF3RkxPVyB7CiAgICAgICAgICAgICAgICBhc3NlcnQoYW1vdW50ICE9IG5pbCwgbWVzc2FnZTogIkFtb3VudCBpcyByZXF1aXJlZCBmb3Igd2l0aGRyYXdhbCBidXQgd2FzIG5vdCBwcm92aWRlZCIpCiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYgc2VsZi50eFR5cGUgPT0gQ09BSGFuZGxlclR4VHlwZS5DYWxsIHsKICAgICAgICAgICAgICAgIGFzc2VydChjYWxsVG9FVk1BZGRyZXNzICE9IG5pbCwgbWVzc2FnZTogIkNhbGwgdG8gRVZNIGFkZHJlc3MgaXMgcmVxdWlyZWQgZm9yIEVWTSBjYWxsIGJ1dCB3YXMgbm90IHByb3ZpZGVkIikKICAgICAgICAgICAgICAgIGFzc2VydCgoZGF0YSAhPSBuaWwgJiYgdmFsdWUgIT0gbmlsKSB8fCAoZGF0YSA9PSBuaWwgPyB2YWx1ZSAhPSBuaWwgOiB0cnVlKSwgbWVzc2FnZTogIkRhdGEgYW5kL29yIHZhbHVlIGFyZSByZXF1aXJlZCBmb3IgRVZNIGNhbGwgYnV0IG5laXRoZXIgd2VyZSBwcm92aWRlZCIpCiAgICAgICAgICAgICAgICBhc3NlcnQoZ2FzTGltaXQgIT0gbmlsLCBtZXNzYWdlOiAiR2FzIGxpbWl0IGlzIHJlcXVpcmVkIGZvciBFVk0gY2FsbCBidXQgd2FzIG5vdCBwcm92aWRlZCIpCiAgICAgICAgICAgIH0KICAgICAgICAgICAgc2VsZi5hbW91bnQgPSBhbW91bnQKICAgICAgICAgICAgaWYgY2FsbFRvRVZNQWRkcmVzcyAhPSBuaWwgewogICAgICAgICAgICAgICAgc2VsZi5jYWxsVG9FVk1BZGRyZXNzID0gRVZNLmFkZHJlc3NGcm9tU3RyaW5nKGNhbGxUb0VWTUFkZHJlc3MhKQogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgc2VsZi5jYWxsVG9FVk1BZGRyZXNzID0gbmlsCiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYgZGF0YSAhPSBuaWwgewogICAgICAgICAgICAgICAgc2VsZi5kYXRhID0gZGF0YQogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgc2VsZi5kYXRhID0gW10KICAgICAgICAgICAgfQogICAgICAgICAgICBzZWxmLmdhc0xpbWl0ID0gZ2FzTGltaXQKICAgICAgICAgICAgaWYgbGV0IHVud3JhcHBlZFZhbHVlID0gdmFsdWUgewogICAgICAgICAgICAgICAgc2VsZi52YWx1ZSA9IEVWTS5CYWxhbmNlKGF0dG9mbG93OiB1bndyYXBwZWRWYWx1ZSkKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIHNlbGYudmFsdWUgPSBuaWwKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0KCiAgICAvLy8gVmlldyBzdHJ1Y3QgZm9yIENPQSBoYW5kbGVyIG1ldGFkYXRhCiAgICBhY2Nlc3MoYWxsKSBzdHJ1Y3QgQ09BSGFuZGxlclZpZXcgewogICAgICAgIGFjY2VzcyhhbGwpIGxldCBjb2FPd25lcjogQWRkcmVzcz8KICAgICAgICBhY2Nlc3MoYWxsKSBsZXQgY29hRVZNQWRkcmVzczogRVZNLkVWTUFkZHJlc3M/CgogICAgICAgIGFjY2VzcyhhbGwpIGxldCBjb2FCYWxhbmNlOiBFVk0uQmFsYW5jZT8KCiAgICAgICAgaW5pdChjb2FPd25lcjogQWRkcmVzcz8sIGNvYUVWTUFkZHJlc3M6IEVWTS5FVk1BZGRyZXNzPywgY29hQmFsYW5jZTogRVZNLkJhbGFuY2U/KSB7CiAgICAgICAgICAgIHNlbGYuY29hT3duZXIgPSBjb2FPd25lcgogICAgICAgICAgICBzZWxmLmNvYUVWTUFkZHJlc3MgPSBjb2FFVk1BZGRyZXNzCiAgICAgICAgICAgIHNlbGYuY29hQmFsYW5jZSA9IGNvYUJhbGFuY2UKICAgICAgICB9CiAgICB9CgogICAgLy8vIENyZWF0ZSBhIENPQSB0cmFuc2FjdGlvbiBoYW5kbGVyCiAgICAvLy8gQHBhcmFtIGNvYUNhcGFiaWxpdHk6IENhcGFiaWxpdHkgdG8gdGhlIENPQSByZXNvdXJjZQogICAgLy8vIEBwYXJhbSBmbG93VG9rZW5WYXVsdENhcGFiaWxpdHk6IENhcGFiaWxpdHkgdG8gdGhlIEZsb3dUb2tlbiB2YXVsdAogICAgLy8vIEByZXR1cm46IEEgbmV3IENPQVRyYW5zYWN0aW9uSGFuZGxlciByZXNvdXJjZQogICAgYWNjZXNzKGFsbCkgZnVuIGNyZWF0ZUNPQVRyYW5zYWN0aW9uSGFuZGxlcigKICAgICAgICBjb2FDYXBhYmlsaXR5OiBDYXBhYmlsaXR5PGF1dGgoRVZNLk93bmVyKSAmRVZNLkNhZGVuY2VPd25lZEFjY291bnQ+LAogICAgICAgIGZsb3dUb2tlblZhdWx0Q2FwYWJpbGl0eTogQ2FwYWJpbGl0eTxhdXRoKEZ1bmdpYmxlVG9rZW4uV2l0aGRyYXcpICZGbG93VG9rZW4uVmF1bHQ+LAogICAgKTogQENPQVRyYW5zYWN0aW9uSGFuZGxlciB7CiAgICAgICAgcmV0dXJuIDwtY3JlYXRlIENPQVRyYW5zYWN0aW9uSGFuZGxlcigKICAgICAgICAgICAgY29hQ2FwYWJpbGl0eTogY29hQ2FwYWJpbGl0eSwKICAgICAgICAgICAgZmxvd1Rva2VuVmF1bHRDYXBhYmlsaXR5OiBmbG93VG9rZW5WYXVsdENhcGFiaWxpdHksCiAgICAgICAgKQogICAgfQoKICAgIC8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogICAgCiAgICBTY2hlZHVsZWQgVHJhbnNhY3Rpb25zIE1ldGFkYXRhIFZpZXdzCiAgICAKICAgICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwoKfQ==",
		"Migration": "YWNjZXNzKGFsbCkKY29udHJhY3QgTWlncmF0aW9uIHsKCiAgICBhY2Nlc3MoYWxsKQogICAgcmVzb3VyY2UgQWRtaW4gewoKICAgICAgICBhY2Nlc3MoYWxsKQogICAgICAgIGZ1biBtaWdyYXRlKCkgewogICAgICAgICAgICBNaWdyYXRpb24ubWlncmF0ZSgpCiAgICAgICAgfQogICAgfQoKICAgIGFjY2VzcyhhbGwpCiAgICBsZXQgYWRtaW5TdG9yYWdlUGF0aDogU3RvcmFnZVBhdGgKCiAgICBpbml0KCkgewogICAgICAgIHNlbGYuYWRtaW5TdG9yYWdlUGF0aCA9IC9zdG9yYWdlL21pZ3JhdGlvbkFkbWluCgogICAgICAgIHNlbGYuYWNjb3VudC5zdG9yYWdlLnNhdmUoCiAgICAgICAgICAgIDwtY3JlYXRlIEFkbWluKCksCiAgICAgICAgICAgIHRvOiBzZWxmLmFkbWluU3RvcmFnZVBhdGgKICAgICAgICApCiAgICB9CgogICAgYWNjZXNzKGNvbnRyYWN0KQogICAgZnVuIG1pZ3JhdGUoKSB7CiAgICAgICAgLy8gTk8tT1AKICAgIH0KfQo=",
		"NodeVersionBeacon": "Ly8vIFRoZSBOb2RlVmVyc2lvbkJlYWNvbiBjb250cmFjdCBob2xkcyB0aGUgcGFzdCBhbmQgZnV0dXJlIHByb3RvY29sIHZlcnNpb25zLgovLy8gdGhhdCBzaG91bGQgYmUgdXNlZCB0byBleGVjdXRlL2hhbmRsZSBibG9ja3MgYXQgYWEgZ2l2ZW4gYmxvY2sgaGVpZ2h0LgovLy8KLy8vIFRoZSBzZXJ2aWNlIGFjY291bnQgaG9sZHMgdGhlIE5vZGVWZXJzaW9uQmVhY29uLkhlYXJ0YmVhdCByZXNvdXJjZQovLy8gd2hpY2ggaXMgcmVzcG9uc2libGUgZm9yIGVtaXR0aW5nIHRoZSBWZXJzaW9uQmVhY29uIGV2ZW50LgovLy8gVGhlIGV2ZW50IGNvbnRhaW5zIHRoZSBjdXJyZW50IHZlcnNpb24gYW5kIGFsbCB0aGUgdXBjb21pbmcgdmVyc2lvbnMuCi8vLyBUaGUgZXZlbnQgaXMgZW1pdHRlZCBldmVyeSB0aW1lIHRoZSB2ZXJzaW9uIHRhYmxlIGlzIHVwZGF0ZWQKLy8vIG9yIGEgdmVyc2lvbiBib3VuZGFyeSBpcyByZWFjaGVkLgovLy8KLy8vIFRoZSBOb2RlVmVyc2lvbkJlYWNvbi5BZG1pbiByZXNvdXJjZSBpcyB1c2VkIHRvIGFkZCBuZXcgdmVyc2lvbiBib3VuZGFyaWVzCi8vLyBvciBjaGFuZ2UgZXhpc3RpbmcgZnV0dXJlIHZlcnNpb24gYm91bmRhcmllcy4gRnV0dXJlIHZlcnNpb24gYm91bmRhcmllcyBjYW4gb25seSBiZQovLy8gY2hhbmdlZCBpZiB0aGV5IG9jY3VyIGFmdGVyIHRoZSBjdXJyZW50IGJsb2NrIGhlaWdodCArIHZlcnNpb25VcGRhdGVGcmVlemVQZXJpb2QuCi8vLyBUaGlzIGlzIHRvIGVuc3VyZSB0aGF0IG5vZGVzIGhhdmUgZW5vdWdoIHRpbWUgdG8gcmVhY3QgdG8gdmVyc2lvbiB0YWJsZSBjaGFuZ2VzLgovLy8gVGhlIHZlcnNpb25VcGRhdGVGcmVlemVQZXJpb2QgY2FuIGFsc28gYmUgY2hhbmdlZCBieSB0aGUgYWRtaW4gcmVzb3VyY2UsIGJ1dCBvbmx5IGlmCi8vLyB0aGVyZSBhcmUgbm8gdXBjb21pbmcgdmVyc2lvbiBib3VuZGFyaWVzIHdpdGhpbiB0aGUgY3VycmVudCB2ZXJzaW9uVXBkYXRlRnJlZXplUGVyaW9kIG9yCi8vLyB0aGUgbmV3IHZlcnNpb25VcGRhdGVGcmVlemVQZXJpb2QuCi8vLwovLy8gVGhlIGNvbnRyYWN0IGl0c2VsZiBjYW4gYmUgdXNlZCB0byBxdWVyeSB0aGUgY3VycmVudCB2ZXJzaW9uIGFuZCB0aGUgbmV4dCB1cGNvbWluZyB2ZXJzaW9uLgphY2Nlc3MoYWxsKSBjb250cmFjdCBOb2RlVmVyc2lvbkJlYWNvbiB7CgogICAgLy8vID09PT09PT09PT09PT09PT09PT09PT09PT0KICAgIC8vLyBFeGVjdXRpb24gU3RhdGUgVmVyc2lvbmluZwogICAgLy8vID09PT09PT09PT09PT09PT09PT09PT09PT0KCiAgICAvLy8gU3RydWN0IHJlcHJlc2VudGluZyBzb2Z0d2FyZSB2ZXJzaW9uIGFzIFNlbWFudGljIFZlcnNpb24KICAgIC8vLyBhbG9uZyB3aXRoIGhlbHBlciBmdW5jdGlvbnMKICAgIC8vLyBGb3IgcmVmZXJlbmNlLCBzZWUgaHR0cHM6Ly9zZW12ZXIub3JnLwogICAgYWNjZXNzKGFsbCkgc3RydWN0IFNlbXZlciB7CiAgICAgICAgLy8vIENvbXBvbmVudHMgZGVmaW5pbmcgYSBzZW1hbnRpYyB2ZXJzaW9uCiAgICAgICAgYWNjZXNzKGFsbCkgbGV0IG1ham9yOiBVSW50OAogICAgICAgIGFjY2VzcyhhbGwpIGxldCBtaW5vcjogVUludDgKICAgICAgICBhY2Nlc3MoYWxsKSBsZXQgcGF0Y2g6IFVJbnQ4CiAgICAgICAgYWNjZXNzKGFsbCkgbGV0IHByZVJlbGVhc2U6IFN0cmluZz8KCiAgICAgICAgaW5pdChtYWpvcjogVUludDgsIG1pbm9yOiBVSW50OCwgcGF0Y2g6IFVJbnQ4LCBwcmVSZWxlYXNlOiBTdHJpbmc/KSB7CiAgICAgICAgICAgIHNlbGYubWFqb3IgPSBtYWpvcgogICAgICAgICAgICBzZWxmLm1pbm9yID0gbWlub3IKICAgICAgICAgICAgc2VsZi5wYXRjaCA9IHBhdGNoCiAgICAgICAgICAgIHNlbGYucHJlUmVsZWFzZSA9IHByZVJlbGVhc2UKICAgICAgICB9CgogICAgICAgIC8vLyBSZXR1cm5zIHZlcnNpb24gaW4gU2VtdmVyIGZvcm1hdCAoZS5nLiB2PG1ham9yPi48bWlub3I+LjxwYXRjaD4tPHByZVJlbGVhc2U+KQogICAgICAgIC8vLyBhcyBhIFN0cmluZwogICAgICAgIGFjY2VzcyhhbGwpIHZpZXcgZnVuIHRvU3RyaW5nKCk6IFN0cmluZyB7CiAgICAgICAgICAgIGxldCBzZW12ZXJDb3JlU3RyaW5nID0gc2VsZi5tYWpvci50b1N0cmluZygpCiAgICAgICAgICAgICAgICAgLmNvbmNhdCgiLiIpCiAgICAgICAgICAgICAgICAgLmNvbmNhdCgKICAgICAgICAgICAgICAgICAgICAgc2VsZi5taW5vci50b1N0cmluZygpCiAgICAgICAgICAgICAgICAgKS5jb25jYXQoIi4iKQogICAgICAgICAgICAgICAgIC5jb25jYXQoCiAgICAgICAgICAgICAgICAgICAgIHNlbGYucGF0Y2gudG9TdHJpbmcoKQogICAgICAgICAgICAgICAgICkKICAgICAgICAgICAgLy8gQ29uY2F0IHByZS1yZWxlYXNlIGlmIGl0IGV4aXN0cyAmIHJldHVybgogICAgICAgICAgICBpZiBzZWxmLnByZVJlbGVhc2UgIT0gbmlsIHsKICAgICAgICAgICAgICAgIHJldHVybiBzZW12ZXJDb3JlU3RyaW5nLmNvbmNhdCgiLSIpLmNvbmNhdChzZWxmLnByZVJlbGVhc2UhKQogICAgICAgICAgICB9CgogICAgICAgICAgICByZXR1cm4gc2VtdmVyQ29yZVN0cmluZwogICAgICAgIH0KCiAgICAgICAgLyogQ3VzdG9tIENvbXBhcmF0b3JzICovCgogICAgICAgIC8vLyBSZXR1cm5zIHRydWUgaWYgU2VtdmVyIGNvcmUgaXMgZ3JlYXRlciB0aGFuCiAgICAgICAgLy8vIHBhc3NlZCBTZW12ZXIgY29yZSBhbmQgZmFsc2Ugb3RoZXJ3aXNlCiAgICAgICAgYWNjZXNzKGFsbCkgdmlldyBmdW4gY29yZUdyZWF0ZXJUaGFuKF8gb3RoZXI6IFNlbXZlcik6IEJvb2wgewogICAgICAgICAgICBpZiAoc2VsZi5tYWpvciAhPSBvdGhlci5tYWpvcikgewogICAgICAgICAgICAgICAgcmV0dXJuIHNlbGYubWFqb3IgPiBvdGhlci5tYWpvcgogICAgICAgICAgICB9CgogICAgICAgICAgICBpZiAoc2VsZi5taW5vciAhPSBvdGhlci5taW5vcikgewogICAgICAgICAgICAgICAgcmV0dXJuIHNlbGYubWlub3IgPiBvdGhlci5taW5vcgogICAgICAgICAgICB9CgogICAgICAgICAgICBpZiAoc2VsZi5wYXRjaCAhPSBvdGhlci5wYXRjaCkgewogICAgICAgICAgICAgICAgcmV0dXJuIHNlbGYucGF0Y2ggPiBvdGhlci5wYXRjaAogICAgICAgICAgICB9CgogICAgICAgICAgICByZXR1cm4gZmFsc2UKICAgICAgICB9CgogICAgICAgIC8vLyBSZXR1cm5zIHRydWUgaWYgU2VtdmVyIGNvcmUgaXMgZ3JlYXRlciB0aGFuIG9yCiAgICAgICAgLy8vIGVxdWFsIHRvIHBhc3NlZCBTZW12ZXIgY29yZSBhbmQgZmFsc2Ugb3RoZXJ3aXNlCiAgICAgICAgYWNjZXNzKGFsbCkgdmlldyBmdW4gY29yZUdyZWF0ZXJUaGFuT3JFcXVhbFRvKF8gb3RoZXI6IFNlbXZlcik6IEJvb2wgewogICAgICAgICAgICByZXR1cm4gc2VsZi5jb3JlR3JlYXRlclRoYW4ob3RoZXIpIHx8IHNlbGYuY29yZUVxdWFsVG8ob3RoZXIpCiAgICAgICAgfQoKICAgICAgICAvLy8gUmV0dXJucyB0cnVlIGlmIFNlbXZlciBjb3JlIGlzIGxlc3MgdGhhbgogICAgICAgIC8vLyBwYXNzZWQgU2VtdmVyIGNvcmUgYW5kIGZhbHNlIG90aGVyd2lzZQogICAgICAgIGFjY2VzcyhhbGwpIHZpZXcgZnVuIGNvcmVMZXNzVGhhbihfIG90aGVyOiBTZW12ZXIpOiBCb29sIHsKICAgICAgICAgICAgcmV0dXJuICFzZWxmLmNvcmVHcmVhdGVyVGhhbk9yRXF1YWxUbyhvdGhlcikKICAgICAgICB9CgogICAgICAgIC8vLyBSZXR1cm5zIHRydWUgaWYgU2VtdmVyIGNvcmUgaXMgbGVzcyB0aGFuIG9yCiAgICAgICAgLy8vIGVxdWFsIHRvIHBhc3NlZCBTZW12ZXIgY29yZSBhbmQgZmFsc2Ugb3RoZXJ3aXNlCiAgICAgICAgYWNjZXNzKGFsbCkgdmlldyBmdW4gY29yZUxlc3NUaGFuT3JFcXVhbFRvKF8gb3RoZXI6IFNlbXZlcik6IEJvb2wgewogICAgICAgICAgICByZXR1cm4gIXNlbGYuY29yZUdyZWF0ZXJUaGFuKG90aGVyKQogICAgICAgIH0KCiAgICAgICAgLy8vIFJldHVybnMgdHJ1ZSBpZiBTZW12ZXIgaXMgZXF1YWwgdG8gcGFzc2VkCiAgICAgICAgLy8vIFNlbXZlciBjb3JlIGFuZCBmYWxzZSBvdGhlcndpc2UKICAgICAgICBhY2Nlc3MoYWxsKSB2aWV3IGZ1biBjb3JlRXF1YWxUbyhfIG90aGVyOiBTZW12ZXIpOiBCb29sIHsKICAgICAgICAgICAgcmV0dXJuIHNlbGYubWFqb3IgPT0gb3RoZXIubWFqb3IgJiYgc2VsZi5taW5vciA9PSBvdGhlci5taW5vciAmJiBzZWxmLnBhdGNoID09IG90aGVyLnBhdGNoCiAgICAgICAgfQoKICAgICAgICAvLy8gUmV0dXJucyB0cnVlIGlmIFNlbXZlciBpcyAqZXhhY3RseSogZXF1YWwgdG8gcGFzc2VkCiAgICAgICAgLy8vIFNlbXZlciBhbmQgZmFsc2Ugb3RoZXJ3aXNlCiAgICAgICAgYWNjZXNzKGFsbCkgdmlldyBmdW4gc3RyaWN0RXF1YWxUbyhfIG90aGVyOiBTZW12ZXIpOiBCb29sIHsKICAgICAgICAgICAgcmV0dXJuIHNlbGYuY29yZUVxdWFsVG8ob3RoZXIpICYmIHNlbGYucHJlUmVsZWFzZSA9PSBvdGhlci5wcmVSZWxlYXNlCiAgICAgICAgfQogICAgfQoKICAgIC8vLyBSZXR1cm5zIHRoZSB2MC4wLjAgdmVyc2lvbi4KICAgIGFjY2VzcyhhbGwpIGZ1biB6ZXJvU2VtdmVyKCk6IFNlbXZlciB7CiAgICAgICAgcmV0dXJuIFNlbXZlcihtYWpvcjogMCwgbWlub3I6IDAsIHBhdGNoOiAwLCBwcmVSZWxlYXNlOiBuaWwpCiAgICB9CgogICAgLy8vIFN0cnVjdCBmb3IgZW1pdHRpbmcgdGhlIGN1cnJlbnQgYW5kIGluY29taW5nIHZlcnNpb25zIGFsb25nIHdpdGggdGhlaXIgYmxvY2sKICAgIGFjY2VzcyhhbGwpIHN0cnVjdCBWZXJzaW9uQm91bmRhcnkgewogICAgICAgIGFjY2VzcyhhbGwpIGxldCBibG9ja0hlaWdodDogVUludDY0CiAgICAgICAgYWNjZXNzKGFsbCkgbGV0IHZlcnNpb246IFNlbXZlcgoKICAgICAgICBpbml0KGJsb2NrSGVpZ2h0OiBVSW50NjQsIHZlcnNpb246IFNlbXZlcil7CiAgICAgICAgICAgIHNlbGYuYmxvY2tIZWlnaHQgPSBibG9ja0hlaWdodAogICAgICAgICAgICBzZWxmLnZlcnNpb24gPSB2ZXJzaW9uCiAgICAgICAgfQogICAgfQoKICAgIC8vLyBSZXR1cm5zIHRoZSB6ZXJvIGJvdW5kYXJ5LiBVc2VkIGFzIGEgc2VudGluZWwgdmFsdWUKICAgIC8vLyBmb3IgdmVyc2lvbnMgYmVmb3JlIHRoZSB2ZXJzaW9uIGJlYWNvbiBjb250cmFjdC4KICAgIC8vLyBTaW1wbGlmaWVzIGVkZ2UgY2FzZSBjb2RlLgogICAgLy8vIFRoZSB6ZXJvIGJvdW5kYXJ5IGlzIGF0IGJsb2NrIGhlaWdodCAwIGFuZCBoYXMgdmVyc2lvbiB2MC4wLjAuCiAgICAvLy8gSXQgaXMgYWx3YXlzIHRoZSBmaXJzdCBlbGVtZW50IGluIHRoZSB2ZXJzaW9uQm91bmRhcnlCbG9ja0xpc3QuCiAgICBhY2Nlc3MoYWxsKSBmdW4gemVyb1ZlcnNpb25Cb3VuZGFyeSgpOiBWZXJzaW9uQm91bmRhcnkgewogICAgICAgIGxldCB6ZXJvVmVyc2lvbiA9IHNlbGYuemVyb1NlbXZlcigpCiAgICAgICAgcmV0dXJuIFZlcnNpb25Cb3VuZGFyeSgKICAgICAgICAgICAgYmxvY2tIZWlnaHQ6IDAsCiAgICAgICAgICAgIHZlcnNpb246IHplcm9WZXJzaW9uCiAgICAgICAgKQogICAgfQoKICAgIC8vLyBBIHNlcnZpY2UgZXZlbnQgZW1pdHRlZCB3aGVuIHRoZSB2ZXJzaW9uIHRhYmxlIGlzIHVwZGF0ZWQuCiAgICAvLy8gVGhlIHZlcnNpb24gaXMgdGhlIHNvZnR3YXJlIHZlcnNpb24gd2hpY2ggbXVzdCBiZSB1c2VkIGZvciBleGVjdXRpbmcgYSBoZWlnaHQgcmFuZ2Ugb2YgYmxvY2tzLgogICAgLy8vIFRoZSB2ZXJzaW9uIHBlcnRhaW5zIHRvIEV4ZWN1dGlvbiBhbmQgVmVyaWZpY2F0aW9uIE5vZGVzLgogICAgLy8vIFRoZSB0YWJsZSBjb250YWlucyB0aGUgY3VycmVudCB2ZXJzaW9uIGFuZCBhbGwgdGhlIHVwY29taW5nIHZlcnNpb25zIHNvcnRlZCBieSBibG9jayBoZWlnaHQuCiAgICAvLy8gVGhlIHNlcXVlbmNlIGluY3JlYXNlcyBieSBvbmUgZWFjaCB0aW1lIGFuIGV2ZW50IGlzIGVtaXR0ZWQuIAogICAgLy8vIEl0IGNhbiBiZSB1c2VkIHRvIHZlcmlmeSBubyBldmVudHMgd2VyZSBtaXNzZWQuCiAgICBhY2Nlc3MoYWxsKSBldmVudCBWZXJzaW9uQmVhY29uKAogICAgICAgIHZlcnNpb25Cb3VuZGFyaWVzOiBbVmVyc2lvbkJvdW5kYXJ5XSwKICAgICAgICBzZXF1ZW5jZTogVUludDY0CiAgICApCgogICAgLy8vIEV2ZW50IGVtaXR0ZWQgYW55IHRpbWUgdGhlIHZlcnNpb24gYm91bmRhcnkgZnJlZXplIHBlcmlvZCBpcyB1cGRhdGVkLgogICAgLy8vIGZyZWV6ZSBwZXJpb2QgaXMgbWVhc3VyZWQgaW4gYmxvY2tzIChmcm9tIHRoZSBjdXJyZW50IGJsb2NrKS4KICAgIGFjY2VzcyhhbGwpIGV2ZW50IE5vZGVWZXJzaW9uQm91bmRhcnlGcmVlemVQZXJpb2RDaGFuZ2VkKGZyZWV6ZVBlcmlvZDogVUludDY0KQoKICAgIC8vLyBDYW5vbmljYWwgc3RvcmFnZSBwYXRoIGZvciB0aGUgTm9kZVZlcnNpb25CZWFjb24uQWRtaW4gcmVzb3VyY2UuCiAgICBhY2Nlc3MoYWxsKSBsZXQgQWRtaW5TdG9yYWdlUGF0aDogU3RvcmFnZVBhdGgKCiAgICAvLy8gQ2Fub25pY2FsIHN0b3JhZ2UgcGF0aCBmb3IgdGhlIE5vZGVWZXJzaW9uQmVhY29uLkhlYXJ0YmVhdCByZXNvdXJjZS4KICAgIGFjY2VzcyhhbGwpIGxldCBIZWFydGJlYXRTdG9yYWdlUGF0aDogU3RvcmFnZVBhdGgKCiAgICAvLy8gQmxvY2sgaGVpZ2h0IGluZGV4ZWQgdmVyc2lvbiBib3VuZGFyaWVzLgogICAgYWNjZXNzKGNvbnRyYWN0KSBsZXQgdmVyc2lvbkJvdW5kYXJ5OiB7VUludDY0OiBWZXJzaW9uQm91bmRhcnl9CgogICAgLy8vIFNvcnRlZCBBcnJheSBjb250YWluaW5nIHZlcnNpb24gYm91bmRhcnkgYmxvY2sgaGVpZ2h0cy4KICAgIGFjY2Vzcyhjb250cmFjdCkgdmFyIHZlcnNpb25Cb3VuZGFyeUJsb2NrTGlzdDogW1VJbnQ2NF0KCiAgICAvLy8gSW5kZXggaW4gdGhlIHZlcnNpb25Cb3VuZGFyeUJsb2NrTGlzdCBvZiB0aGUgbmV4dCB1cGNvbWluZyB2ZXJzaW9uIGJvdW5kYXJ5LAogICAgLy8vIG9yIG5pbCBpZiBubyB1cGNvbWluZyB2ZXJzaW9uIGJvdW5kYXJ5LgogICAgYWNjZXNzKGNvbnRyYWN0KSB2YXIgZmlyc3RVcGNvbWluZ0JvdW5kYXJ5OiBVSW50NjQ/CgogICAgLy8vIHZlcnNpb25VcGRhdGVGcmVlemVQZXJpb2QgaXMgdGhlIG51bWJlciBvZiBibG9ja3MgKHBhc3QgdGhlIGN1cnJlbnQgb25lKSBmb3Igd2hpY2ggdmVyc2lvbiBib3VuZGFyeQogICAgLy8vIGNoYW5nZXMgYXJlIG5vdCBhbGxvd2VkLiBUaGlzIGlzIHRvIGVuc3VyZSB0aGF0IG5vZGVzIGhhdmUgZW5vdWdoIHRpbWUgdG8gcmVhY3QgdG8KICAgIC8vLyB2ZXJzaW9uIHRhYmxlIGNoYW5nZXMuCiAgICBhY2Nlc3MoY29udHJhY3QpIHZhciB2ZXJzaW9uQm91bmRhcnlGcmVlemVQZXJpb2Q6IFVJbnQ2NAoKICAgIC8vLyBCb29sZWFuIGZsYWcgZm9yIGtlZXBpbmcgdHJhY2sgaWYgYSBWZXJzaW9uQmVhY29uIGV2ZW50IG5lZWRzIHRvIGJlIGVtaXR0ZWQgb24gbmV4dCBoZWFydGJlYXQuCiAgICBhY2Nlc3MoY29udHJhY3QpIHZhciBlbWl0RXZlbnRPbk5leHRIZWFydGJlYXQ6IEJvb2wKCiAgICAvLy8gQSBjb3VudGVyIHRoYXQgaW5jcmVhc2VzIGV2ZXJ5IHRpbWUgdGhlIFZlcnNpb24gYmVhY29uIGV2ZW50IGlzIGVtaXR0ZWQuCiAgICBhY2Nlc3MoY29udHJhY3QpIHZhciBuZXh0VmVyc2lvbkJlYWNvbkV2ZW50U2VxdWVuY2U6IFVJbnQ2NAoKICAgIC8vLyBBZG1pbiByZXNvdXJjZSB0aGF0IG1hbmFnZXMgdmVyc2lvbiBib3VuZGFyaWVzCiAgICAvLy8gbWFpbnRhaW5lZCBpbiB0aGlzIGNvbnRyYWN0LgogICAgYWNjZXNzKGFsbCkgcmVzb3VyY2UgQWRtaW4gewogICAgICAgIC8vLyBBZGRzIG9yIHVwZGF0ZXMgYSB2ZXJzaW9uIGJvdW5kYXJ5LgogICAgICAgIGFjY2VzcyhhbGwpIGZ1biBzZXRWZXJzaW9uQm91bmRhcnkodmVyc2lvbkJvdW5kYXJ5OiBWZXJzaW9uQm91bmRhcnkpIHsKICAgICAgICAgICAgcHJlIHsKICAgICAgICAgICAgICAgIHZlcnNpb25Cb3VuZGFyeS5ibG9ja0hlaWdodCA+IGdldEN1cnJlbnRCbG9jaygpLmhlaWdodCArIE5vZGVWZXJzaW9uQmVhY29uLnZlcnNpb25Cb3VuZGFyeUZyZWV6ZVBlcmlvZAogICAgICAgICAgICAgICAgICAgIDogIk5vZGVWZXJzaW9uQmVhY29uLkFkbWluLnNldFZlcnNpb25Cb3VuZGFyeTogQ2Fubm90IHNldC91cGRhdGUgYSB2ZXJzaW9uIGJvdW5kYXJ5IGZvciBwYXN0IGJsb2NrcyBvciBibG9ja3MgaW4gdGhlIG5lYXIgZnV0dXJlLiBNdXN0IGJlIGdyZWF0ZXIgdGhhbiBcKGdldEN1cnJlbnRCbG9jaygpLmhlaWdodCArIE5vZGVWZXJzaW9uQmVhY29uLnZlcnNpb25Cb3VuZGFyeUZyZWV6ZVBlcmlvZCkgYnV0IGdvdCBcKHZlcnNpb25Cb3VuZGFyeS5ibG9ja0hlaWdodCkiCiAgICAgICAgICAgIH0KICAgICAgICAgICAgLy8gU2V0IHRoZSBmbGFnIHRvIHRydWUgc28gdGhlIGV2ZW50IHdpbGwgYmUgZW1pdHRlZCBuZXh0IHRpbWUgZW1pdENoYW5nZXMgaXMgY2FsbGVkCiAgICAgICAgICAgIE5vZGVWZXJzaW9uQmVhY29uLmVtaXRFdmVudE9uTmV4dEhlYXJ0YmVhdCA9IHRydWUKCiAgICAgICAgICAgIGxldCBleGlzdHMgPSBOb2RlVmVyc2lvbkJlYWNvbi52ZXJzaW9uQm91bmRhcnlbdmVyc2lvbkJvdW5kYXJ5LmJsb2NrSGVpZ2h0XSAhPSBuaWwKICAgICAgICAgICAgTm9kZVZlcnNpb25CZWFjb24udmVyc2lvbkJvdW5kYXJ5W3ZlcnNpb25Cb3VuZGFyeS5ibG9ja0hlaWdodF0gPSB2ZXJzaW9uQm91bmRhcnkKCiAgICAgICAgICAgIGlmIGV4aXN0cyB7CiAgICAgICAgICAgICAgICAvLyB0aGlzIHdhcyBhbiB1cGRhdGUgc28gbm90aGluZyBlbHNlIG5lZWRzIHRvIGJlIGRvbmUKICAgICAgICAgICAgICAgIHJldHVybgogICAgICAgICAgICB9CgogICAgICAgICAgICAvLyBXZSBoYXZlIHRvIGluc2VydCB0aGUgYmxvY2sgaGVpZ2h0IGludG8gdGhlIG9yZGVyZWQgbGlzdC4KICAgICAgICAgICAgLy8gVGhpcyBpcyBhbiBpbmVmZmljaWVudCBhbGdvcml0aG0sIGJ1dCBpdCBpcyBub3QgZXhwZWN0ZWQgdGhhdCB0aGUgbGlzdCBvZgogICAgICAgICAgICAvLyB1cGNvbWluZyB2ZXJzaW9ucyB3aWxsIGJlIGxvbmcuCiAgICAgICAgICAgIHZhciBpID0gTm9kZVZlcnNpb25CZWFjb24udmVyc2lvbkJvdW5kYXJ5QmxvY2tMaXN0Lmxlbmd0aAogICAgICAgICAgICB3aGlsZSBpID4gMSAmJiBOb2RlVmVyc2lvbkJlYWNvbi52ZXJzaW9uQm91bmRhcnlCbG9ja0xpc3RbaS0xXSA+IHZlcnNpb25Cb3VuZGFyeS5ibG9ja0hlaWdodCAgewogICAgICAgICAgICAgICAgaSA9IGkgLSAxCiAgICAgICAgICAgIH0KICAgICAgICAgICAgTm9kZVZlcnNpb25CZWFjb24udmVyc2lvbkJvdW5kYXJ5QmxvY2tMaXN0Lmluc2VydChhdDogaSwgdmVyc2lvbkJvdW5kYXJ5LmJsb2NrSGVpZ2h0KQoKICAgICAgICAgICAgLy8gbm8gbmVlZCB0byBjaGFuZ2UgdGhlIGZpcnN0VXBjb21pbmdCb3VuZGFyeSB1bmxlc3MgaXQgd2FzIG5pbAogICAgICAgICAgICAvLyBjYXNlIDE6IGluZGV4IHBvaW50cyB0byBhIGxvd2VyIGJsb2NrIGhlaWdodCB0aGVuIHRoZSBvbmUgaW5zZXJ0ZWQKICAgICAgICAgICAgLy8gPT4gaXQgc2hvdWxkIHJlbWFpbiBwb2ludGluZyBhdCB0aGF0IGluZGV4CiAgICAgICAgICAgIC8vIGNhc2UgMjogaW5kZXggcG9pbnRzIHRvIHRoZSBlbnRyeSB0aGF0IHdhcyByZXBsYWNlZCBieSB0aGlzIGluc2VydAogICAgICAgICAgICAvLyA9PiBpdCBzaG91bGQgcmVtYWluIHBvaW50aW5nIGF0IHRoaXMgbmV3IGVudHJ5LCBzaW5jZSBpdCBpcyBiZWZvcmUgdGhlIG9sZCBvbmUKICAgICAgICAgICAgLy8gY2FzZSAzOiBpbmRleCB3YXMgcG9pbnRpbmcgdG8gYW4gZW50cnkgbGF0ZXIgdGhhbiB0aGUgaW5zZXJ0IEZpeGVkUG9pbnQKICAgICAgICAgICAgLy8gPT4gdGhpcyBpcyBpbGxlZ2FsIGFuZCBjYW5ub3QgaGFwcGVuIHNpbmNlIHRoZXJlIGFyZSBlbnRyaWVzIHdpdGggbG93ZXIgYmxvY2sgaGVpZ2h0cy4KICAgICAgICAgICAgaWYgTm9kZVZlcnNpb25CZWFjb24uZmlyc3RVcGNvbWluZ0JvdW5kYXJ5ID09IG5pbCB7CiAgICAgICAgICAgICAgICBOb2RlVmVyc2lvbkJlYWNvbi5maXJzdFVwY29taW5nQm91bmRhcnkgPSBVSW50NjQoTm9kZVZlcnNpb25CZWFjb24udmVyc2lvbkJvdW5kYXJ5QmxvY2tMaXN0Lmxlbmd0aCAtIDEpCiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIC8vLyBEZWxldGVzIGFuIHVwY29taW5nIHZlcnNpb24gYm91bmRhcnkuCiAgICAgICAgYWNjZXNzKGFsbCkgZnVuIGRlbGV0ZVZlcnNpb25Cb3VuZGFyeShibG9ja0hlaWdodDogVUludDY0KSB7CiAgICAgICAgICAgIHByZSB7CiAgICAgICAgICAgICAgICBibG9ja0hlaWdodCA+IGdldEN1cnJlbnRCbG9jaygpLmhlaWdodCArIE5vZGVWZXJzaW9uQmVhY29uLnZlcnNpb25Cb3VuZGFyeUZyZWV6ZVBlcmlvZAogICAgICAgICAgICAgICAgICAgIDogIk5vZGVWZXJzaW9uQmVhY29uLkFkbWluLmRlbGV0ZVZlcnNpb25Cb3VuZGFyeTogQ2Fubm90IGRlbGV0ZSBhIHZlcnNpb24gYm91bmRhcnkgZm9yIHBhc3QgYmxvY2tzIG9yIGJsb2NrcyBpbiB0aGUgbmVhciBmdXR1cmUuIE11c3QgYmUgZ3JlYXRlciB0aGFuIFwoZ2V0Q3VycmVudEJsb2NrKCkuaGVpZ2h0ICsgTm9kZVZlcnNpb25CZWFjb24udmVyc2lvbkJvdW5kYXJ5RnJlZXplUGVyaW9kKSBidXQgZ290IFwoYmxvY2tIZWlnaHQpIgogICAgICAgICAgICAgICAgTm9kZVZlcnNpb25CZWFjb24udmVyc2lvbkJvdW5kYXJ5LmNvbnRhaW5zS2V5KGJsb2NrSGVpZ2h0KTogIk5vZGVWZXJzaW9uQmVhY29uLkFkbWluLmRlbGV0ZVZlcnNpb25Cb3VuZGFyeTogTm8gYm91bmRhcnkgZGVmaW5lZCBhdCBibG9jayBoZWlnaHQgXChibG9ja0hlaWdodCkiCiAgICAgICAgICAgIH0KICAgICAgICAgICAgLy8gU2V0IHRoZSBmbGFnIHRvIHRydWUgc28gdGhlIGV2ZW50IHdpbGwgYmUgZW1pdHRlZCBuZXh0IHRpbWUgZW1pdENoYW5nZXMgaXMgY2FsbGVkCiAgICAgICAgICAgIE5vZGVWZXJzaW9uQmVhY29uLmVtaXRFdmVudE9uTmV4dEhlYXJ0YmVhdCA9IHRydWUKCiAgICAgICAgICAgIC8vIFJlbW92ZSB0aGUgdmVyc2lvbiBtYXBwaW5nIGFuZCB1cGNvbWluZ0Jsb2NrQm91bmRhcmllcwogICAgICAgICAgICBOb2RlVmVyc2lvbkJlYWNvbi52ZXJzaW9uQm91bmRhcnkucmVtb3ZlKGtleTogYmxvY2tIZWlnaHQpCgogICAgICAgICAgICAvLyBXZSBoYXZlIHRvIHJlbW92ZSB0aGUgYmxvY2sgaGVpZ2h0IGZyb20gdGhlIG9yZGVyZWQgbGlzdC4KICAgICAgICAgICAgLy8gVGhpcyBpcyBhbiBpbmVmZmljaWVudCBhbGdvcml0aG0sIGJ1dCBpdCBpcyBub3QgZXhwZWN0ZWQgdGhhdCB0aGUgbGlzdCBvZgogICAgICAgICAgICAvLyB1cGNvbWluZyB2ZXJzaW9ucyB3aWxsIGJlIGxvbmcuCiAgICAgICAgICAgIHZhciBpID0gTm9kZVZlcnNpb25CZWFjb24udmVyc2lvbkJvdW5kYXJ5QmxvY2tMaXN0Lmxlbmd0aCAtIDEKICAgICAgICAgICAgd2hpbGUgaSA+IDAgJiYgTm9kZVZlcnNpb25CZWFjb24udmVyc2lvbkJvdW5kYXJ5QmxvY2tMaXN0W2ldID4gYmxvY2tIZWlnaHQgIHsKICAgICAgICAgICAgICAgIGkgPSBpIC0gMQogICAgICAgICAgICB9CiAgICAgICAgICAgIGFzc2VydChOb2RlVmVyc2lvbkJlYWNvbi52ZXJzaW9uQm91bmRhcnlCbG9ja0xpc3RbaV0gPT0gYmxvY2tIZWlnaHQsCiAgICAgICAgICAgICBtZXNzYWdlOiAiTm9kZVZlcnNpb25CZWFjb24uQWRtaW4uZGVsZXRlVmVyc2lvbkJvdW5kYXJ5OiB2ZXJzaW9uIGJvdW5kYXJ5IGV4aXN0cyBpbiBtYXAsIHNvIGl0IHNob3VsZCBhbHNvIGV4aXN0IGluIHRoZSBvcmRlcmVkIGxpc3QiKQoKICAgICAgICAgICAgTm9kZVZlcnNpb25CZWFjb24udmVyc2lvbkJvdW5kYXJ5QmxvY2tMaXN0LnJlbW92ZShhdDogaSkKCiAgICAgICAgICAgIC8vIHRoZSBpbmRleCBoYXMgdG8gYmUgZml4ZWQsIGJ1dCB5b3UgY2Fubm90IGNoYW5nZSByZWNvcmRzIGJlZm9yZSB0aGUgaW5kZXgKICAgICAgICAgICAgLy8gc28gdGhlIG9ubHkgY2FzZSB0byBiZSBhZGRyZXNzZWQgaXMgdGhhdCB0aGUgaW5kZXggaXMgcG9pbnRpbmcgb2ZmIHRoZSBsaXN0LAogICAgICAgICAgICAvLyBiZWNhdXNlIHRoZSBsaXN0IGlzIG5vdyBzaG9ydGVyLgogICAgICAgICAgICBpZiBOb2RlVmVyc2lvbkJlYWNvbi5maXJzdFVwY29taW5nQm91bmRhcnkgIT0gbmlsICYmCiAgICAgICAgICAgICAgICBOb2RlVmVyc2lvbkJlYWNvbi5maXJzdFVwY29taW5nQm91bmRhcnkhID49IFVJbnQ2NChOb2RlVmVyc2lvbkJlYWNvbi52ZXJzaW9uQm91bmRhcnlCbG9ja0xpc3QubGVuZ3RoKSB7CiAgICAgICAgICAgICAgICBOb2RlVmVyc2lvbkJlYWNvbi5maXJzdFVwY29taW5nQm91bmRhcnkgPSBuaWwKICAgICAgICAgICAgfQoKICAgICAgICB9CgogICAgICAgIC8vLyBVcGRhdGVzIHRoZSBudW1iZXIgb2YgYmxvY2tzIGluIHdoaWNoIHZlcnNpb24gYm91bmRhcmllcyBhcmUgZnJvemVuLgogICAgICAgIGFjY2VzcyhhbGwpIGZ1biBzZXRWZXJzaW9uQm91bmRhcnlGcmVlemVQZXJpb2QobmV3RnJlZXplUGVyaW9kOiBVSW50NjQpIHsKICAgICAgICAgICAgcG9zdCB7CiAgICAgICAgICAgICAgICBOb2RlVmVyc2lvbkJlYWNvbi52ZXJzaW9uQm91bmRhcnlGcmVlemVQZXJpb2QgPT0gbmV3RnJlZXplUGVyaW9kOiAiTm9kZVZlcnNpb25CZWFjb24uQWRtaW4uc2V0VmVyc2lvbkJvdW5kYXJ5RnJlZXplUGVyaW9kOiBVcGRhdGUgYnVmZmVyIHdhcyBub3QgcHJvcGVybHkgc2V0ISIKICAgICAgICAgICAgfQoKICAgICAgICAgICAgLy8gR2V0IGN1cnJlbnQgYmxvY2sgaGVpZ2h0LgogICAgICAgICAgICBsZXQgY3VycmVudEJsb2NrSGVpZ2h0ID0gZ2V0Q3VycmVudEJsb2NrKCkuaGVpZ2h0CgogICAgICAgICAgICAvLyBObyBib3VuZGFyaWVzIGRlZmluZWQgYmV5b25kIGN1cnJlbnQgYmxvY2ssIHNhZmUgdG8gbWFrZSBjaGFuZ2VzCiAgICAgICAgICAgIGlmIE5vZGVWZXJzaW9uQmVhY29uLmZpcnN0VXBjb21pbmdCb3VuZGFyeSA9PSBuaWwgewogICAgICAgICAgICAgICAgTm9kZVZlcnNpb25CZWFjb24udmVyc2lvbkJvdW5kYXJ5RnJlZXplUGVyaW9kID0gbmV3RnJlZXplUGVyaW9kCiAgICAgICAgICAgICAgICByZXR1cm4KICAgICAgICAgICAgfQoKICAgICAgICAgICAgbGV0IG5leHRCbG9ja0JvdW5kYXJ5ID0gTm9kZVZlcnNpb25CZWFjb24udmVyc2lvbkJvdW5kYXJ5QmxvY2tMaXN0W05vZGVWZXJzaW9uQmVhY29uLmZpcnN0VXBjb21pbmdCb3VuZGFyeSFdCgogICAgICAgICAgICAvLyBFbnN1cmUgdGhhdCB0aGUgd2UncmUgbm90IGN1cnJlbnRseSB3aXRoaW4gdGhlIG9sZCBvciBuZXcgZnJlZXplIHBlcmlvZAogICAgICAgICAgICAvLyBvZiB0aGUgbmV4dCBibG9jayBoZWlnaHQgYm91bmRhcnkKICAgICAgICAgICAgYXNzZXJ0KAogICAgICAgICAgICAgICAgY3VycmVudEJsb2NrSGVpZ2h0ICsgTm9kZVZlcnNpb25CZWFjb24udmVyc2lvbkJvdW5kYXJ5RnJlZXplUGVyaW9kIDwgbmV4dEJsb2NrQm91bmRhcnkgJiYKICAgICAgICAgICAgICAgIGN1cnJlbnRCbG9ja0hlaWdodCArIG5ld0ZyZWV6ZVBlcmlvZCA8IG5leHRCbG9ja0JvdW5kYXJ5LAogICAgICAgICAgICAgICAgbWVzc2FnZTogIk5vZGVWZXJzaW9uQmVhY29uLkFkbWluLnNldFZlcnNpb25Cb3VuZGFyeUZyZWV6ZVBlcmlvZDogVXBkYXRpbmcgYnVmZmVyIG5vdyBicmVha3MgdmVyc2lvbiBib3VuZGFyeSB1cGRhdGUgZXhwZWN0YXRpb25zLiBUcnkgdXBkYXRpbmcgYnVmZmVyIGFmdGVyIG5leHQgdmVyc2lvbiBib3VuZGFyeS4iCiAgICAgICAgICAgICkKCiAgICAgICAgICAgIE5vZGVWZXJzaW9uQmVhY29uLnZlcnNpb25Cb3VuZGFyeUZyZWV6ZVBlcmlvZCA9IG5ld0ZyZWV6ZVBlcmlvZAoKICAgICAgICAgICAgZW1pdCBOb2RlVmVyc2lvbkJvdW5kYXJ5RnJlZXplUGVyaW9kQ2hhbmdlZChmcmVlemVQZXJpb2Q6IG5ld0ZyZWV6ZVBlcmlvZCkKICAgICAgICB9CgogICAgICAgIC8vLyBFbWl0cyB0aGUgZ2l2ZW4gcHJvdG9jb2wgc3RhdGUgdmVyc2lvbiB1cGdyYWRlIGV2ZW50LgogICAgICAgIC8vLyBJZiB0aGUgdmVyc2lvbiBhbmQgYWN0aXZlIHZpZXcgYXJlIHZhbGlkLCB0aGlzIHdpbGwgY2F1c2UgdGhlIFByb3RvY29sIFN0YXRlCiAgICAgICAgLy8vIHRvIHVwZ3JhZGUgaXRzIG1vZGVsIHZlcnNpb24gd2hlbiB0aGUgZXZlbnQgaXMgaW5jb3Jwb3JhdGVkLgogICAgICAgIC8vLyBJZiBlaXRoZXIgdGhlIHZlcnNpb24gb3IgYWN0aXZlIHZpZXcgYXJlIGludmFsaWQsIHRoZSBzZXJ2aWNlIGV2ZW50IHdpbGwgYmUKICAgICAgICAvLy8gaWdub3JlZCBhbmQgd2lsbCBoYXZlIG5vIGVmZmVjdC4gQWxsIHZhbGlkYXRpb24gaXMgcGVyZm9ybWVkIHdoZW4gdGhlIHNlcnZpY2UKICAgICAgICAvLy8gZXZlbnQgaXMgaW5jb3Jwb3JhdGVkIGJ5IHRoZSBQcm90b2NvbCBTdGF0ZS4KICAgICAgICAvLy8gSXQgaXMgc2FmZSB0byBlbWl0IHRoZSBzYW1lIFByb3RvY29sU3RhdGVWZXJzaW9uVXBncmFkZSBldmVudCBtdWx0aXBsZSB0aW1lcywKICAgICAgICAvLy8gYXMgb25seSB2ZXJzaW9uIHVwZ3JhZGUgd2lsbCBvY2N1ci4KICAgICAgICBhY2Nlc3MoYWxsKSBmdW4gZW1pdFByb3RvY29sU3RhdGVWZXJzaW9uVXBncmFkZShuZXdQcm90b2NvbFZlcnNpb246IFVJbnQ2NCwgYWN0aXZlVmlldzogVUludDY0KSB7CiAgICAgICAgICAgIGVtaXQgUHJvdG9jb2xTdGF0ZVZlcnNpb25VcGdyYWRlKG5ld1Byb3RvY29sVmVyc2lvbjogbmV3UHJvdG9jb2xWZXJzaW9uLCBhY3RpdmVWaWV3OiBhY3RpdmVWaWV3KQogICAgICAgIH0KICAgIH0KCiAgICAvLy8gSGVhcnRiZWF0IHJlc291cmNlIHRoYXQgZW1pdHMgdGhlIHZlcnNpb24gYmVhY29uIGV2ZW50IGFuZCBrZWVwcyB0cmFjayBvZiB1cGNvbWluZyB2ZXJzaW9ucy4KICAgIC8vLyBUaGlzIHJlc291cmNlIHNob3VsZCBhbHdheXMgYmUgaGVsZCBvbmx5IGJ5IHRoZSBzZXJ2aWNlIGFjY291bnQsCiAgICAvLy8gYmVjYXVzZSB0aGUgc2VydmljZSBhY2NvdW50IHNob3VsZCBiZSB0aGUgb25seSBvbmUgZW1pdHRpbmcgdGhlIGV2ZW50LAogICAgLy8vIGFuZCBvbmx5IGR1cmluZyB0aGUgc3lzdGVtIHRyYW5zYWN0aW9uCiAgICBhY2Nlc3MoYWxsKSByZXNvdXJjZSBIZWFydGJlYXQgewogICAgICAgIC8vIGhlYXJ0YmVhdCBpcyBjYWxsZWQgZHVyaW5nIHRoZSBzeXN0ZW0gdHJhbnNhY3Rpb24gZXZlcnkgYmxvY2suCiAgICAgICAgYWNjZXNzKGFsbCkgZnVuIGhlYXJ0YmVhdCgpIHsKICAgICAgICAgICAgc2VsZi5jaGVja0ZpcnN0VXBjb21pbmdCb3VuZGFyeSgpCgogICAgICAgICAgICBpZiAoIU5vZGVWZXJzaW9uQmVhY29uLmVtaXRFdmVudE9uTmV4dEhlYXJ0YmVhdCkgewogICAgICAgICAgICAgICAgcmV0dXJuCiAgICAgICAgICAgIH0KICAgICAgICAgICAgTm9kZVZlcnNpb25CZWFjb24uZW1pdEV2ZW50T25OZXh0SGVhcnRiZWF0ID0gZmFsc2UKCiAgICAgICAgICAgIHNlbGYuZW1pdFZlcnNpb25CZWFjb25FdmVudCh2ZXJzaW9uQm91bmRhcmllczogTm9kZVZlcnNpb25CZWFjb24uZ2V0Q3VycmVudFZlcnNpb25Cb3VuZGFyaWVzKCkpCiAgICAgICAgfQoKICAgICAgICBhY2Nlc3Moc2VsZikgZnVuIGVtaXRWZXJzaW9uQmVhY29uRXZlbnQodmVyc2lvbkJvdW5kYXJpZXMgOiBbVmVyc2lvbkJvdW5kYXJ5XSkgewoKICAgICAgICAgICAgZW1pdCBWZXJzaW9uQmVhY29uKHZlcnNpb25Cb3VuZGFyaWVzOiB2ZXJzaW9uQm91bmRhcmllcywKICAgICAgICAgICAgICAgIHNlcXVlbmNlOiBOb2RlVmVyc2lvbkJlYWNvbi5uZXh0VmVyc2lvbkJlYWNvbkV2ZW50U2VxdWVuY2UpCiAgICAgICAgICAgIC8vIEFmdGVyIGVtaXR0aW5nIHRoZSBldmVudCBpbmNyZWFzZSB0aGUgZXZlbnQgc2VxdWVuY2UgbnVtYmVyIGFuZCBzZXQgdGhlIGZsYWcgdG8gZmFsc2UKICAgICAgICAgICAgLy8gc28gdGhlIGV2ZW50IHdvbid0IGJlIGVtaXR0ZWQgb24gdGhlIG5leHQgYmxvY2sgaWYgdGhlcmUgaXNuJ3QgYW55IGNoYW5nZXMgdG8gdGhlIHRhYmxlCiAgICAgICAgICAgIE5vZGVWZXJzaW9uQmVhY29uLm5leHRWZXJzaW9uQmVhY29uRXZlbnRTZXF1ZW5jZSA9IE5vZGVWZXJzaW9uQmVhY29uLm5leHRWZXJzaW9uQmVhY29uRXZlbnRTZXF1ZW5jZSArIDEKCiAgICAgICAgfQoKICAgICAgICAvLy8gQ2hlY2sgaWYgdGhlIGluZGV4IHBvaW50aW5nIHRvIHRoZSBuZXh0IHZlcnNpb24gYm91bmRhcnkgbmVlZHMgdG8gYmUgbW92ZWQuCiAgICAgICAgYWNjZXNzKHNlbGYpIGZ1biBjaGVja0ZpcnN0VXBjb21pbmdCb3VuZGFyeSgpIHsKICAgICAgICAgICAgaWYgTm9kZVZlcnNpb25CZWFjb24uZmlyc3RVcGNvbWluZ0JvdW5kYXJ5ID09IG5pbCB7CiAgICAgICAgICAgICAgICByZXR1cm4KICAgICAgICAgICAgfQoKICAgICAgICAgICAgbGV0IGN1cnJlbnRCbG9ja0hlaWdodCA9IGdldEN1cnJlbnRCbG9jaygpLmhlaWdodAogICAgICAgICAgICB2YXIgYm91bmRhcnlJbmRleCA9ICBOb2RlVmVyc2lvbkJlYWNvbi5maXJzdFVwY29taW5nQm91bmRhcnkhCiAgICAgICAgICAgIHdoaWxlIGJvdW5kYXJ5SW5kZXggPCBVSW50NjQoTm9kZVZlcnNpb25CZWFjb24udmVyc2lvbkJvdW5kYXJ5QmxvY2tMaXN0Lmxlbmd0aCkKICAgICAgICAgICAgICAmJiBOb2RlVmVyc2lvbkJlYWNvbi52ZXJzaW9uQm91bmRhcnlCbG9ja0xpc3RbYm91bmRhcnlJbmRleF0gPD0gY3VycmVudEJsb2NrSGVpZ2h0IHsKICAgICAgICAgICAgICAgIGJvdW5kYXJ5SW5kZXggPSBib3VuZGFyeUluZGV4ICsgMQogICAgICAgICAgICB9CgogICAgICAgICAgICBpZiBib3VuZGFyeUluZGV4ID09IE5vZGVWZXJzaW9uQmVhY29uLmZpcnN0VXBjb21pbmdCb3VuZGFyeSEgewogICAgICAgICAgICAgICAgLy8gbm8gY2hhbmdlCiAgICAgICAgICAgICAgICByZXR1cm4KICAgICAgICAgICAgfQoKICAgICAgICAgICAgaWYgYm91bmRhcnlJbmRleCA+PSBVSW50NjQoTm9kZVZlcnNpb25CZWFjb24udmVyc2lvbkJvdW5kYXJ5QmxvY2tMaXN0Lmxlbmd0aCkgewogICAgICAgICAgICAgICAgTm9kZVZlcnNpb25CZWFjb24uZmlyc3RVcGNvbWluZ0JvdW5kYXJ5ID0gbmlsCiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICBOb2RlVmVyc2lvbkJlYWNvbi5maXJzdFVwY29taW5nQm91bmRhcnkgPSBib3VuZGFyeUluZGV4CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIC8vIElmIHdlIHBhc3NlZCBhIGJvdW5kYXJ5IHJlLWVtaXQgdGhlIFZlcnNpb25CZWFjb24gZXZlbnQKICAgICAgICAgICAgTm9kZVZlcnNpb25CZWFjb24uZW1pdEV2ZW50T25OZXh0SGVhcnRiZWF0ID0gdHJ1ZQogICAgICAgIH0KICAgIH0KCiAgICAvLy8gZ2V0Q3VycmVudFZlcnNpb25Cb3VuZGFyaWVzIHJldHVybnMgdGhlIGN1cnJlbnQgdmVyc2lvbiBib3VuZGFyaWVzLgogICAgLy8vIHRoaXMgaXMgdGhlIHNhbWUgbGlzdCBhcyB0aGUgb25lIGVtaXR0ZWQgYnkgdGhlIFZlcnNpb25CZWFjb24gZXZlbnQuCiAgICBhY2Nlc3MoYWxsKSBmdW4gZ2V0Q3VycmVudFZlcnNpb25Cb3VuZGFyaWVzKCk6IFtWZXJzaW9uQm91bmRhcnldIHsKICAgICAgICAgICAgbGV0IHRhYmxlVXBkYXRlczogW1ZlcnNpb25Cb3VuZGFyeV0gPSBbXQoKICAgICAgICAgICAgaWYgTm9kZVZlcnNpb25CZWFjb24uZmlyc3RVcGNvbWluZ0JvdW5kYXJ5ID09IG5pbCB7CiAgICAgICAgICAgICAgICAvLyBubyBmdXR1cmUgYm91bmRhcmllcy4gSnVzdCByZXR1cm4gdGhlIGxhc3Qgb25lLgogICAgICAgICAgICAgICAgLy8gdGhpcyBpcyBzYWZlLCB0aGVyZSBpcyBhdCBsZWFzdCBvbmUgcmVjb3JkIGluIHRoZSB2ZXJzaW9uQm91bmRhcnlCbG9ja0xpc3QKICAgICAgICAgICAgICAgIHRhYmxlVXBkYXRlcy5hcHBlbmQoTm9kZVZlcnNpb25CZWFjb24udmVyc2lvbkJvdW5kYXJ5WwogICAgICAgICAgICAgICAgICAgIE5vZGVWZXJzaW9uQmVhY29uLnZlcnNpb25Cb3VuZGFyeUJsb2NrTGlzdFtOb2RlVmVyc2lvbkJlYWNvbi52ZXJzaW9uQm91bmRhcnlCbG9ja0xpc3QubGVuZ3RoIC0gMV0KICAgICAgICAgICAgICAgIF0hKQogICAgICAgICAgICAgICAgcmV0dXJuIHRhYmxlVXBkYXRlcwogICAgICAgICAgICB9CgogICAgICAgICAgICAvLyAtMSB0byBpbmNsdWRlIHRoZSB2ZXJzaW9uIHRoZSBub2RlIHNob3VsZCBjdXJyZW50bHkgYmUgb24KICAgICAgICAgICAgdmFyIHN0YXJ0ID0gKE5vZGVWZXJzaW9uQmVhY29uLmZpcnN0VXBjb21pbmdCb3VuZGFyeSA/PyBVSW50NjQoTm9kZVZlcnNpb25CZWFjb24udmVyc2lvbkJvdW5kYXJ5QmxvY2tMaXN0Lmxlbmd0aCkpIC0gMQogICAgICAgICAgICBsZXQgZW5kID0gVUludDY0KE5vZGVWZXJzaW9uQmVhY29uLnZlcnNpb25Cb3VuZGFyeUJsb2NrTGlzdC5sZW5ndGgpCgogICAgICAgICAgICBpZiBzdGFydCA8IDAgewogICAgICAgICAgICAgICAgLy8gdGhpcyBpcyB0aGUgY2FzZSB3aGVuIHRoZSBjdXJyZW50IGluZGV4IGlzIGF0IDAKICAgICAgICAgICAgICAgIHN0YXJ0ID0gMAogICAgICAgICAgICB9CgogICAgICAgICAgICB2YXIgaSA9IHN0YXJ0CgogICAgICAgICAgICB3aGlsZSBpIDwgZW5kIHsKICAgICAgICAgICAgICAgIGxldCBibG9jayA9IE5vZGVWZXJzaW9uQmVhY29uLnZlcnNpb25Cb3VuZGFyeUJsb2NrTGlzdFtpXQogICAgICAgICAgICAgICAgdGFibGVVcGRhdGVzLmFwcGVuZChOb2RlVmVyc2lvbkJlYWNvbi52ZXJzaW9uQm91bmRhcnlbYmxvY2tdISkKICAgICAgICAgICAgICAgIGkgPSBpICsgMQogICAgICAgICAgICB9CgogICAgICAgICAgICByZXR1cm4gdGFibGVVcGRhdGVzCiAgICB9CgogICAgLy8vIFJldHVybnMgdGhlIHZlcnNpb25Cb3VuZGFyeUZyZWV6ZVBlcmlvZAogICAgYWNjZXNzKGFsbCkgdmlldyBmdW4gZ2V0VmVyc2lvbkJvdW5kYXJ5RnJlZXplUGVyaW9kKCk6IFVJbnQ2NCB7CiAgICAgICAgcmV0dXJuIE5vZGVWZXJzaW9uQmVhY29uLnZlcnNpb25Cb3VuZGFyeUZyZWV6ZVBlcmlvZAogICAgfQoKICAgIC8vLyBSZXR1cm5zIHRoZSBzZXF1ZW5jZSBudW1iZXIgb2YgdGhlIG5leHQgdmVyc2lvbiBiZWFjb24gZXZlbnQKICAgIC8vLyBUaGlzIGNhbiBiZSB1c2VkIHRvIHZlcmlmeSB0aGF0IG5vIHZlcnNpb24gYmVhY29uIGV2ZW50cyB3ZXJlIG1pc3NlZC4KICAgIGFjY2VzcyhhbGwpIHZpZXcgZnVuIGdldE5leHRWZXJzaW9uQmVhY29uU2VxdWVuY2UoKTogVUludDY0IHsKICAgICAgICByZXR1cm4gc2VsZi5uZXh0VmVyc2lvbkJlYWNvbkV2ZW50U2VxdWVuY2UKICAgIH0KCiAgICAvLy8gRnVuY3Rpb24gdGhhdCByZXR1cm5zIHRoZSB2ZXJzaW9uIHRoYXQgd2FzIGRlZmluZWQgYXQgdGhlIG1vc3QKICAgIC8vLyByZWNlbnQgYmxvY2sgaGVpZ2h0IGJvdW5kYXJ5LiBNYXkgcmV0dXJuIHplcm8gYm91bmRhcnkuCiAgICBhY2Nlc3MoYWxsKSBmdW4gZ2V0Q3VycmVudFZlcnNpb25Cb3VuZGFyeSgpOiBWZXJzaW9uQm91bmRhcnkgewogICAgICAgIHZhciBjdXJyZW50OiBVSW50NjQgPSAwCgogICAgICAgIC8vIGluZGV4IGlzIG5ldmVyIDAgc2luY2UgdmVyc2lvbiAwIGlzIGFsd2F5cyBpbiB0aGUgcGFzdAogICAgICAgIGlmIGxldCBpbmRleCA9IE5vZGVWZXJzaW9uQmVhY29uLmZpcnN0VXBjb21pbmdCb3VuZGFyeSB7CiAgICAgICAgICAgIGFzc2VydChpbmRleCA+IDAsIG1lc3NhZ2U6ICJOb2RlVmVyc2lvbkJlYWNvbi5nZXRDdXJyZW50VmVyc2lvbkJvdW5kYXJ5OiBpbmRleCBzaG91bGQgbmV2ZXIgYmUgMCBzaW5jZSB2ZXJzaW9uIDAgaXMgYWx3YXlzIGluIHRoZSBwYXN0IikKICAgICAgICAgICAgY3VycmVudCA9IHNlbGYudmVyc2lvbkJvdW5kYXJ5QmxvY2tMaXN0W2luZGV4LTFdCiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgY3VycmVudCA9IFVJbnQ2NChOb2RlVmVyc2lvbkJlYWNvbi52ZXJzaW9uQm91bmRhcnlCbG9ja0xpc3QubGVuZ3RoIC0gMSkKICAgICAgICB9CgogICAgICAgIGxldCBibG9jayA9IHNlbGYudmVyc2lvbkJvdW5kYXJ5QmxvY2tMaXN0W2N1cnJlbnRdCgogICAgICAgIC8vIFJldHVybiB0aGUgdmVyc2lvbiBtYXBwZWQgdG8gdGhlIGxhc3QgaGlzdG9yaWNhbCBibG9jayBoZWlnaHQgYm91bmRhcnkKICAgICAgICByZXR1cm4gc2VsZi52ZXJzaW9uQm91bmRhcnlbYmxvY2tdIQogICAgfQoKICAgIGFjY2VzcyhhbGwpIGZ1biBnZXROZXh0VmVyc2lvbkJvdW5kYXJ5KCkgOiBWZXJzaW9uQm91bmRhcnk/IHsKICAgICAgICBpZiBsZXQgaW5kZXggPSBOb2RlVmVyc2lvbkJlYWNvbi5maXJzdFVwY29taW5nQm91bmRhcnkgewogICAgICAgICAgICBsZXQgYmxvY2sgPSBzZWxmLnZlcnNpb25Cb3VuZGFyeUJsb2NrTGlzdFtpbmRleF0KICAgICAgICAgICAgcmV0dXJuIHNlbGYudmVyc2lvbkJvdW5kYXJ5W2Jsb2NrXQogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIHJldHVybiBuaWwKICAgICAgICB9CiAgICB9CgogICAgLy8vIENoZWNrcyB3aGV0aGVyIGdpdmVuIHZlcnNpb24gd2FzIGNvbXBhdGlibGUgYXQgdGhlIGdpdmVuIGhpc3RvcmljYWwgYmxvY2sgaGVpZ2h0CiAgICBhY2Nlc3MoYWxsKSB2aWV3IGZ1biBnZXRWZXJzaW9uQm91bmRhcnkoZWZmZWN0aXZlQXRCbG9ja0hlaWdodDogVUludDY0KTogVmVyc2lvbkJvdW5kYXJ5IHsKICAgICAgICBsZXQgYmxvY2sgPSBzZWxmLnNlYXJjaEZvckNsb3Nlc3RIaXN0b3JpY2FsQmxvY2tCb3VuZGFyeShibG9ja0hlaWdodDogZWZmZWN0aXZlQXRCbG9ja0hlaWdodCkKCiAgICAgICAgcmV0dXJuIHNlbGYudmVyc2lvbkJvdW5kYXJ5W2Jsb2NrXSEKICAgIH0KCiAgICBhY2Nlc3MoYWxsKSBzdHJ1Y3QgVmVyc2lvbkJvdW5kYXJ5UGFnZSB7CiAgICAgICAgYWNjZXNzKGFsbCkgbGV0IHBhZ2U6IEludAogICAgICAgIGFjY2VzcyhhbGwpIGxldCBwZXJQYWdlOiBJbnQKICAgICAgICBhY2Nlc3MoYWxsKSBsZXQgdG90YWxMZW5ndGg6IEludAogICAgICAgIGFjY2VzcyhhbGwpIGxldCB2YWx1ZXMgOiBbVmVyc2lvbkJvdW5kYXJ5XQoKICAgICAgICB2aWV3IGluaXQocGFnZTogSW50LCBwZXJQYWdlOiBJbnQsIHRvdGFsTGVuZ3RoOiBJbnQsIHZhbHVlczogW1ZlcnNpb25Cb3VuZGFyeV0pIHsKICAgICAgICAgICAgc2VsZi5wYWdlID0gcGFnZQogICAgICAgICAgICBzZWxmLnBlclBhZ2UgPSBwZXJQYWdlCiAgICAgICAgICAgIHNlbGYudG90YWxMZW5ndGggPSB0b3RhbExlbmd0aAogICAgICAgICAgICBzZWxmLnZhbHVlcyA9IHZhbHVlcwogICAgICAgIH0KCiAgICB9CgogICAgLy8vIFJldHVybnMgYSBwYWdlIG9mIHZlcnNpb24gYm91bmRhcmllcwogICAgLy8vIHBhZ2UgaXMgemVybyBiYXNlZAogICAgLy8vIHJlc3VsdHMgYXJlIHNvcnRlZCBieSBibG9jayBoZWlnaHQKICAgIGFjY2VzcyhhbGwpIGZ1biBnZXRWZXJzaW9uQm91bmRhcmllc1BhZ2UocGFnZTogSW50LCBwZXJQYWdlOiBJbnQpIDogVmVyc2lvbkJvdW5kYXJ5UGFnZSB7CiAgICAgICAgcHJlIHsKICAgICAgICAgICAgcGFnZSA+PSAwOiAiTm9kZVZlcnNpb25CZWFjb24uZ2V0VmVyc2lvbkJvdW5kYXJpZXNQYWdlOiBwYWdlIG11c3QgYmUgZ3JlYXRlciB0aGFuIG9yIGVxdWFsIHRvIDAgYnV0IGdvdCBcKHBhZ2UpIgogICAgICAgICAgICBwZXJQYWdlID4gMDogIk5vZGVWZXJzaW9uQmVhY29uLmdldFZlcnNpb25Cb3VuZGFyaWVzUGFnZTogcGVyUGFnZSBtdXN0IGJlIGdyZWF0ZXIgdGhhbiAwIGJ1dCBnb3QgXChwZXJQYWdlKSIKICAgICAgICB9CgogICAgICAgIGxldCB0b3RhbExlbmd0aCA9IE5vZGVWZXJzaW9uQmVhY29uLnZlcnNpb25Cb3VuZGFyeUJsb2NrTGlzdC5sZW5ndGgKICAgICAgICB2YXIgc3RhcnRJbmRleCA9IHBhZ2UgKiBwZXJQYWdlCiAgICAgICAgaWYgc3RhcnRJbmRleCA+IHRvdGFsTGVuZ3RoIHsKICAgICAgICAgICAgc3RhcnRJbmRleCA9IHRvdGFsTGVuZ3RoCiAgICAgICAgfQogICAgICAgIHZhciBlbmRJbmRleCA9IHN0YXJ0SW5kZXggKyBwZXJQYWdlCiAgICAgICAgaWYgZW5kSW5kZXggPiB0b3RhbExlbmd0aCB7CiAgICAgICAgICAgIGVuZEluZGV4ID0gdG90YWxMZW5ndGgKICAgICAgICB9CiAgICAgICAgbGV0IHZhbHVlczogW1ZlcnNpb25Cb3VuZGFyeV0gPSBbXQogICAgICAgIGlmIHN0YXJ0SW5kZXggPT0gZW5kSW5kZXggewogICAgICAgICAgICByZXR1cm4gVmVyc2lvbkJvdW5kYXJ5UGFnZShwYWdlOiBwYWdlLCBwZXJQYWdlOiBwZXJQYWdlLCB0b3RhbExlbmd0aDogdG90YWxMZW5ndGgsIHZhbHVlczogdmFsdWVzKQogICAgICAgIH0KICAgICAgICBmb3IgYmxvY2sgaW4gc2VsZi52ZXJzaW9uQm91bmRhcnlCbG9ja0xpc3Quc2xpY2UoZnJvbTogc3RhcnRJbmRleCwgdXBUbzogZW5kSW5kZXgpIHsKICAgICAgICAgICAgdmFsdWVzLmFwcGVuZChOb2RlVmVyc2lvbkJlYWNvbi52ZXJzaW9uQm91bmRhcnlbYmxvY2tdISkKICAgICAgICB9CiAgICAgICAgcmV0dXJuIFZlcnNpb25Cb3VuZGFyeVBhZ2UocGFnZTogcGFnZSwgcGVyUGFnZTogcGVyUGFnZSwgdG90YWxMZW5ndGg6IHRvdGFsTGVuZ3RoLCB2YWx1ZXM6IHZhbHVlcykKICAgIH0KCgogICAgLy8vIEJpbmFyeSBzZWFyY2ggYWxnb3JpdGhtIHRvIGZpbmQgY2xvc2VzdCB2YWx1ZSBrZXkgaW4gdmVyc2lvblRhYmxlIHRoYXQgaXMgPD0gdGFyZ2V0IHZhbHVlCiAgICBhY2Nlc3MoY29udHJhY3QpIHZpZXcgZnVuIHNlYXJjaEZvckNsb3Nlc3RIaXN0b3JpY2FsQmxvY2tCb3VuZGFyeShibG9ja0hlaWdodDogVUludDY0KTogVUludDY0IHsKICAgICAgICAvLyBSZXR1cm4gbGFzdCBibG9jayBib3VuZGFyeSBpZiB0YXJnZXQgaXMgYmV5b25kCiAgICAgICAgbGV0IGxlbmd0aCA9IHNlbGYudmVyc2lvbkJvdW5kYXJ5QmxvY2tMaXN0Lmxlbmd0aAogICAgICAgIGlmIGJsb2NrSGVpZ2h0ID49IHNlbGYudmVyc2lvbkJvdW5kYXJ5QmxvY2tMaXN0W2xlbmd0aCAtIDFdIHsKICAgICAgICAgICAgcmV0dXJuIHNlbGYudmVyc2lvbkJvdW5kYXJ5QmxvY2tMaXN0W2xlbmd0aCAtIDFdCiAgICAgICAgfQoKICAgICAgICAvLyBEZWZpbmUgc2VhcmNoIGJvdW5kcwogICAgICAgIHZhciBsZWZ0ID0gMAogICAgICAgIHZhciByaWdodCA9IGxlbmd0aAogICAgICAgIC8vIExvb3AgdW50aWwgc2VhcmNoIHBvaW50ZXJzIGNyb3NzCiAgICAgICAgd2hpbGUgbGVmdCA8IHJpZ2h0IHsKICAgICAgICAgICAgdmFyIG1pZCA9IChsZWZ0ICsgcmlnaHQpIC8gMgogICAgICAgICAgICBpZiBzZWxmLnZlcnNpb25Cb3VuZGFyeUJsb2NrTGlzdFttaWRdID09IGJsb2NrSGVpZ2h0IHsKICAgICAgICAgICAgICAgIHJldHVybiBzZWxmLnZlcnNpb25Cb3VuZGFyeUJsb2NrTGlzdFttaWRdCiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYgYmxvY2tIZWlnaHQgPCBzZWxmLnZlcnNpb25Cb3VuZGFyeUJsb2NrTGlzdFttaWRdIHsKICAgICAgICAgICAgICAgIGlmIG1pZCA+IDAgJiYgYmxvY2tIZWlnaHQgPiBzZWxmLnZlcnNpb25Cb3VuZGFyeUJsb2NrTGlzdFttaWQgLTFdIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gc2VsZi52ZXJzaW9uQm91bmRhcnlCbG9ja0xpc3RbbWlkIC0gMV0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIHJpZ2h0ID0gbWlkCiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICBpZiBtaWQgPCAobGVuZ3RoIC0gMSkgJiYgYmxvY2tIZWlnaHQgPCBzZWxmLnZlcnNpb25Cb3VuZGFyeUJsb2NrTGlzdFttaWQgKyAxXSB7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHNlbGYudmVyc2lvbkJvdW5kYXJ5QmxvY2tMaXN0W21pZF0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGxlZnQgPSBtaWQgKyAxCiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgLy8gUmV0dXJuIHplcm8gdmVyc2lvbiBpZiBub3RoaW5nIGZvdW5kCiAgICAgICAgcmV0dXJuIHNlbGYudmVyc2lvbkJvdW5kYXJ5QmxvY2tMaXN0WzBdCiAgICB9CgogICAgLy8vID09PT09PT09PT09PT09PT09PT09PT09PT0KICAgIC8vLyBQcm90b2NvbCBTdGF0ZSBWZXJzaW9uaW5nCiAgICAvLy8gPT09PT09PT09PT09PT09PT09PT09PT09PQoKICAgIC8vLyBBIHNlcnZpY2UgZXZlbnQgd2hpY2ggaXMgZW1pdHRlZCB0byBpbmRpY2F0ZSB0aGF0IHRoZSBQcm90b2NvbCBTdGF0ZSB2ZXJzaW9uIGlzIGJlaW5nIHVwZ3JhZGVkLgogICAgLy8vIFRoaXMgYWN0cyBhcyBhIHNpZ25hbCB0byBiZWdpbiB1c2luZyB0aGUgdXBncmFkZWQgUHJvdG9jb2wgU3RhdGUgdmVyc2lvbiAKICAgIC8vLyBhZnRlciB0aGlzIHNlcnZpY2UgZXZlbnQgaXMgc2VhbGVkLCBhbmQgYWZ0ZXIgdmlldyBgYWN0aXZlVmlld2AgaXMgZW50ZXJlZC4KICAgIC8vLyBOb2RlcyBydW5uaW5nIGEgc29mdHdhcmUgdmVyc2lvbiB3aGljaCBkb2VzIG5vdCBzdXBwb3J0IGBuZXdQcm90b2NvbFZlcnNpb25gCiAgICAvLy8gd2lsbCBzdG9wIHByb2Nlc3NpbmcgbmV3IGJsb2NrcyB3aGVuIHRoZXkgcmVhY2ggdmlldyBgYWN0aXZlQXRWaWV3YC4KICAgIGFjY2VzcyhhbGwpIGV2ZW50IFByb3RvY29sU3RhdGVWZXJzaW9uVXBncmFkZShuZXdQcm90b2NvbFZlcnNpb246IFVJbnQ2NCwgYWN0aXZlVmlldzogVUludDY0KQoKICAgIGluaXQodmVyc2lvblVwZGF0ZUZyZWV6ZVBlcmlvZDogVUludDY0KSB7CiAgICAgICAgc2VsZi5BZG1pblN0b3JhZ2VQYXRoID0gL3N0b3JhZ2UvTm9kZVZlcnNpb25CZWFjb25BZG1pbgogICAgICAgIHNlbGYuSGVhcnRiZWF0U3RvcmFnZVBhdGggPSAvc3RvcmFnZS9Ob2RlVmVyc2lvbkJlYWNvbkhlYXJ0YmVhdAoKICAgICAgICAvLyBpbnNlcnQgYSB6ZXJvLXRoIHZlcnNpb24gdG8gbWFrZSB0aGUgQVBJIHNpbXBsZXIgYW5kIG1vcmUgcm9idXN0CiAgICAgICAgbGV0IHplcm8gPSBOb2RlVmVyc2lvbkJlYWNvbi56ZXJvVmVyc2lvbkJvdW5kYXJ5KCkKCiAgICAgICAgc2VsZi52ZXJzaW9uQm91bmRhcnkgPSB7emVyby5ibG9ja0hlaWdodDp6ZXJvfQogICAgICAgIHNlbGYudmVyc2lvbkJvdW5kYXJ5QmxvY2tMaXN0ID0gW3plcm8uYmxvY2tIZWlnaHRdCiAgICAgICAgc2VsZi52ZXJzaW9uQm91bmRhcnlGcmVlemVQZXJpb2QgPSB2ZXJzaW9uVXBkYXRlRnJlZXplUGVyaW9kCiAgICAgICAgc2VsZi5maXJzdFVwY29taW5nQm91bmRhcnkgPSBuaWwKICAgICAgICBzZWxmLm5leHRWZXJzaW9uQmVhY29uRXZlbnRTZXF1ZW5jZSA9IDAKCiAgICAgICAgLy8gZW1pdCB0aGUgZXZlbnQgb24gdGhlIGZpcnN0IGhlYXJ0YmVhdCB0byBzZW5kIHRoZSB6ZXJvIHZlcnNpb24KICAgICAgICBzZWxmLmVtaXRFdmVudE9uTmV4dEhlYXJ0YmVhdCA9IHRydWUKCiAgICAgICAgc2VsZi5hY2NvdW50LnN0b3JhZ2Uuc2F2ZSg8LWNyZWF0ZSBBZG1pbigpLCB0bzogc2VsZi5BZG1pblN0b3JhZ2VQYXRoKQogICAgICAgIHNlbGYuYWNjb3VudC5zdG9yYWdlLnNhdmUoPC1jcmVhdGUgSGVhcnRiZWF0KCksIHRvOiBzZWxmLkhlYXJ0YmVhdFN0b3JhZ2VQYXRoKQogICAgfQp9Cg==",
		"RandomBeaconHistory": "Ly8vIFJhbmRvbUJlYWNvbkhpc3RvcnkgKEZMSVAgMTIzKQovLy8KLy8vIFRoaXMgY29udHJhY3Qgc3RvcmVzIHRoZSBoaXN0b3J5IG9mIHJhbmRvbSBzb3VyY2VzIGdlbmVyYXRlZCBieSB0aGUgRmxvdyBuZXR3b3JrLiBUaGUgZGVmaW5lZCBIZWFydGJlYXQgcmVzb3VyY2UgaXMKLy8vIHVwZGF0ZWQgYnkgdGhlIEZsb3cgU2VydmljZSBBY2NvdW50IGF0IHRoZSBlbmQgb2YgZXZlcnkgYmxvY2sgd2l0aCB0aGF0IGJsb2NrJ3Mgc291cmNlIG9mIHJhbmRvbW5lc3MuCi8vLwovLy8gV2hpbGUgdGhlIHNvdXJjZSB2YWx1ZXMgYXJlIHNhZmVseSBnZW5lcmF0ZWQgYnkgdGhlIFJhbmRvbSBCZWFjb24gKG5vbi1wcmVkaWN0YWJsZSwgdW5iaWFzYWJsZSwgdmVyaWZpYWJsZSkgYW5kCi8vLyB0cmFuc21pdHRlZCBpbnRvIHRoZSBleGVjdXRpb24gZW52aXJvbm1lbnQgdmlhIHRoZSBjb21taXR0aW5nIHRyYW5zYWN0aW9uLCB1c2luZyB0aGUgcmF3IHZhbHVlcyBmcm9tIHRoaXMgY29udHJhY3QKLy8vIGRvZXMgbm90IGd1YXJhbnRlZSBub24tcmV2ZXJ0aWJsZSByYW5kb21uZXNzLiBUaGUgSGVhcmJlYXQgaXMgaW50ZW5kZWQgdG8gYmUgdXNlZCBpbiBjb25qdW5jdGlvbiB3aXRoIGEgY29tbWl0LXJldmVhbAovLy8gbWVjaGFuaXNtIHRvIHByb3ZpZGUgYW4gb25jaGFpbiBzb3VyY2Ugb2Ygbm9uLXJldmVydGlibGUgcmFuZG9tbmVzcy4KLy8vIEl0IGlzIGFsc28gcmVjb21tZW5kZWQgdG8gdXNlIHRoZSBzb3VyY2UgdmFsdWVzIHdpdGggYSBwc2V1ZG8tcmFuZG9tIG51bWJlcgovLy8gZ2VuZXJhdG9yIChQUk5HKSB0byBnZW5lcmF0ZSBhbiBhcmJpdHJhcnktbG9uZyBzZXF1ZW5jZSBvZiByYW5kb20gdmFsdWVzLgovLy8KLy8vIEZvciB1c2FnZSBvZiByYW5kb21uZXNzIHdoZXJlIHJlc3VsdCBhYm9ydGlvbiBpcyBub3QgYW4gaXNzdWUsIGl0IGlzIHJlY29tbWVuZGVkCi8vLyB0byB1c2UgdGhlIENhZGVuY2UgYnVpbHQtaW4gZnVuY3Rpb24gYHJldmVydGlibGVSYW5kb21gLCB3aGljaCBpcyBhbHNvIGJhc2VkIG9uCi8vLyB0aGUgc2FmZSBSYW5kb20gQmVhY29uLgovLy8KLy8vIFJlYWQgdGhlIGZ1bGwgRkxJUCBoZXJlOiBodHRwczovL2dpdGh1Yi5jb20vb25mbG93L2ZsaXBzL3B1bGwvMTIzCi8vLwphY2Nlc3MoYWxsKSBjb250cmFjdCBSYW5kb21CZWFjb25IaXN0b3J5IHsKCiAgICAvLy8gVGhlIGhlaWdodCBhdCB3aGljaCB0aGUgZmlyc3Qgc291cmNlIG9mIHJhbmRvbW5lc3Mgd2FzIHJlY29yZGVkCiAgICBhY2Nlc3MoY29udHJhY3QpIHZhciBsb3dlc3RIZWlnaHQ6IFVJbnQ2ND8KICAgIC8vLyBTZXF1ZW5jZSBvZiByYW5kb20gc291cmNlcyByZWNvcmRlZCBieSB0aGUgSGVhcnRiZWF0LCBzdG9yZWQgYXMgYW4gYXJyYXkgb3ZlciBhIG1hcHBpbmcgdG8gcmVkdWNlIHN0b3JhZ2UKICAgIGFjY2Vzcyhjb250cmFjdCkgbGV0IHJhbmRvbVNvdXJjZUhpc3Rvcnk6IFtbVUludDhdXQoKICAgIC8vLyBUaGUgcGF0aCBvZiB0aGUgSGVhcnRiZWF0IHJlc291cmNlIGluIHRoZSBkZXBsb3ltZW50IGFjY291bnQKICAgIGFjY2VzcyhhbGwpIGxldCBIZWFydGJlYXRTdG9yYWdlUGF0aDogU3RvcmFnZVBhdGgKCiAgICAvLyBFdmVudCBlbWl0dGVkIHdoZW4gbWlzc2luZyBTb1JzIGZyb20gcGFzdCBoZWFydGJlYXRzIGFyZSBkZXRlY3RlZCBhbmQgd2lsbCBiZSBiYWNrZmlsbGVkOgogICAgLy8gIC0gYGJsb2NrSGVpZ2h0YCBpcyB0aGUgaGVpZ2h0IHdoZXJlIHRoZSBnYXAgaXMgZGV0ZWN0ZWQKICAgIC8vICAtIGBnYXBTdGFydEhlaWdodGAgaXMgdGhlIGhlaWdodCBvZiB0aGUgZmlyc3QgbWlzc2luZyBlbnRyeSBkZXRlY3RlZAogICAgYWNjZXNzKGFsbCkgZXZlbnQgUmFuZG9tSGlzdG9yeU1pc3NpbmcoYmxvY2tIZWlnaHQ6IFVJbnQ2NCwgZ2FwU3RhcnRIZWlnaHQ6IFVJbnQ2NCkKCiAgICAvLyBFdmVudCBlbWl0dGVkIHdoZW4gbWlzc2luZyBTb1JzIGFyZSBiYWNrZmlsbGVkIG9uIHRoZSBjdXJyZW50IGhlYXJ0YmVhdDoKICAgIC8vICAtIGBibG9ja0hlaWdodGAgaXMgdGhlIGhlaWdodCB3aGVyZSB0aGUgYmFja2ZpbGwgaGFwcGVuZWQsIGl0IGFsc28gZGVmaW5lcyB0aGUgU29SIHVzZWQgdG8gYmFja2ZpbGwKICAgIC8vICAtIGBnYXBTdGFydEhlaWdodGAgaXMgdGhlIGhlaWdodCBvZiB0aGUgZmlyc3QgYmFja2ZpbGxlZCBlbnRyeQogICAgLy8gIC0gYGNvdW50YCBpcyB0aGUgbnVtYmVyIG9mIGJhY2tmaWxsZWQgZW50cmllcwogICAgLy8gTm90ZSB0aGF0IGluIHZlcnkgcmFyZSBjYXNlcywgdGhlIGJhY2tmaWxsZWQgZ2FwIG1heSBub3QgYmUgY29udGlndW91cy4gVGhpcyBldmVudCBkb2VzIG5vdAogICAgLy8gZnVsbHkgZGVmaW5lIHRoZSBiYWNrZmlsbGVkIGVudHJpZXMgaW4gdGhpcyBjYXNlLgogICAgYWNjZXNzKGFsbCkgZXZlbnQgUmFuZG9tSGlzdG9yeUJhY2tmaWxsZWQoYmxvY2tIZWlnaHQ6IFVJbnQ2NCwgZ2FwU3RhcnRIZWlnaHQ6IFVJbnQ2NCwgY291bnQ6IFVJbnQ2NCkKCiAgICAvKiAtLS0gSGVhcmJlYXQgLS0tICovCiAgICAvLwogICAgLy8vIFRoZSBIZWFydGJlYXQgcmVzb3VyY2UgY29udGFpbmluZyBlYWNoIGJsb2NrJ3Mgc291cmNlIG9mIHJhbmRvbW5lc3MgaW4gc2VxdWVuY2UKICAgIC8vLwogICAgYWNjZXNzKGFsbCkgcmVzb3VyY2UgSGVhcnRiZWF0IHsKCiAgICAgICAgLy8vIENhbGxhYmxlIGJ5IG93bmVyIG9mIHRoZSBIZWFydGJlYXQgcmVzb3VyY2UsIEZsb3cgU2VydmljZSBBY2NvdW50LCByZWNvcmRzIHRoZSBwcm92aWRlZCByYW5kb20gc291cmNlCiAgICAgICAgLy8vCiAgICAgICAgLy8vIEBwYXJhbSByYW5kb21Tb3VyY2VIaXN0b3J5IFRoZSByYW5kb20gc291cmNlIHRvIHJlY29yZAogICAgICAgIC8vLwogICAgICAgIC8vLyBUaGUgRmxvdyBwcm90b2NvbCBtYWtlcyBzdXJlIHRvIGNhbGwgdGhpcyBmdW5jdGlvbiBvbmNlIHBlciBibG9jayBhcyBhIHN5c3RlbSBjYWxsLiBUaGUgdHJhbnNhY3Rpb24KICAgICAgICAvLy8gY29tZXMgYXQgdGhlIGVuZCBvZiBlYWNoIGJsb2NrIHNvIHRoYXQgdGhlIGN1cnJlbnQgYmxvY2sncyBlbnRyeSBiZWNvbWVzIGF2YWlsYWJsZSBvbmx5IGluIHRoZSBjaGlsZAogICAgICAgIC8vLyBibG9jay4KICAgICAgICAvLy8KICAgICAgICBhY2Nlc3MoYWxsKSBmdW4gaGVhcnRiZWF0KHJhbmRvbVNvdXJjZUhpc3Rvcnk6IFtVSW50OF0pIHsKCiAgICAgICAgICAgIGFzc2VydCgKICAgICAgICAgICAgICAgIC8vIHJhbmRvbSBzb3VyY2UgbXVzdCBiZSBhdCBsZWFzdCAxMjggYml0cwogICAgICAgICAgICAgICAgcmFuZG9tU291cmNlSGlzdG9yeS5sZW5ndGggPj0gMTI4IC8gOCwKICAgICAgICAgICAgICAgIG1lc3NhZ2U6ICJSYW5kb21CZWFjb25IaXN0b3J5LkhlYXJ0YmVhdC5oZWFydGJlYXQ6IFJhbmRvbSBzb3VyY2UgbXVzdCBiZSBhdCBsZWFzdCAxMjggYml0cyBidXQgZ290IFwocmFuZG9tU291cmNlSGlzdG9yeS5sZW5ndGggKiA4KSBiaXRzIgogICAgICAgICAgICApCgogICAgICAgICAgICBsZXQgY3VycmVudEJsb2NrSGVpZ2h0ID0gZ2V0Q3VycmVudEJsb2NrKCkuaGVpZ2h0CiAgICAgICAgICAgIC8vIGluaXQgbG93ZXN0QmxvY2tIZWlnaHQgaWYgaXQgaXMgbm90IHNldCB5ZXQKICAgICAgICAgICAgaWYgUmFuZG9tQmVhY29uSGlzdG9yeS5sb3dlc3RIZWlnaHQgPT0gbmlsIHsKICAgICAgICAgICAgICAgIFJhbmRvbUJlYWNvbkhpc3RvcnkubG93ZXN0SGVpZ2h0ID0gY3VycmVudEJsb2NrSGVpZ2h0CiAgICAgICAgICAgIH0KICAgICAgICAgICAgdmFyIG1heWJlQmFja2ZpbGxlciA9IFJhbmRvbUJlYWNvbkhpc3RvcnkuYm9ycm93QmFja2ZpbGxlcigpCiAgICAgICAgICAgIC8vIENyZWF0ZSAmIHNhdmUgQmFja2ZpbGxlciBpZiBpdCBpcyBub3Qgc2F2ZWQgeWV0CiAgICAgICAgICAgIGlmIG1heWJlQmFja2ZpbGxlciA9PSBuaWwgewogICAgICAgICAgICAgICAgUmFuZG9tQmVhY29uSGlzdG9yeS5hY2NvdW50LnN0b3JhZ2Uuc2F2ZSg8LWNyZWF0ZSBCYWNrZmlsbGVyKCksIHRvOiAvc3RvcmFnZS9yYW5kb21CZWFjb25IaXN0b3J5QmFja2ZpbGxlcikKICAgICAgICAgICAgICAgIG1heWJlQmFja2ZpbGxlciA9IFJhbmRvbUJlYWNvbkhpc3RvcnkuYm9ycm93QmFja2ZpbGxlcigpCiAgICAgICAgICAgIH0KICAgICAgICAgICAgbGV0IGJhY2tmaWxsZXIgPSBtYXliZUJhY2tmaWxsZXIgPz8gcGFuaWMoIlByb2JsZW0gYm9ycm93aW5nIGJhY2tmaWxsZXIiKQoKICAgICAgICAgICAgLy8gY2hlY2sgZm9yIGFueSBleGlzdGluZyBnYXAgYW5kIGJhY2tmaWxsIHVzaW5nIHRoZSBpbnB1dCByYW5kb20gc291cmNlIGlmIG5lZWRlZC4KICAgICAgICAgICAgYmFja2ZpbGxlci5iYWNrZmlsbChyYW5kb21Tb3VyY2U6IHJhbmRvbVNvdXJjZUhpc3RvcnkpCgogICAgICAgICAgICAvLyB3ZSBhcmUgbm93IGF0IHRoZSBjb3JyZWN0IGluZGV4IHRvIHJlY29yZCB0aGUgc291cmNlIG9mIHJhbmRvbW5lc3MKICAgICAgICAgICAgLy8gY3JlYXRlZCBieSB0aGUgcHJvdG9jb2wgZm9yIHRoZSBjdXJyZW50IGJsb2NrCiAgICAgICAgICAgIFJhbmRvbUJlYWNvbkhpc3RvcnkucmFuZG9tU291cmNlSGlzdG9yeS5hcHBlbmQocmFuZG9tU291cmNlSGlzdG9yeSkKICAgICAgICB9CiAgICB9CgogICAgLyogLS0tIEJhY2tmaWxsZXIgLS0tICovCiAgICAvLwogICAgLy8vIEEgcmVjb3ZlcnkgbWVjaGFuaXNtIGRlc2lnbmVkIHRvIGJhY2tmaWxsIG1pc3NlZCBzb3VyY2VzIG9mIHJhbmRvbW5lc3MgaW4gdGhlIGV2ZW50IG9mIGEgbWlzc2VkIGNvbW1pdG1lbnQgZHVlCiAgICAvLy8gdG8gYSBzeXN0ZW0gdHJhbnNhY3Rpb24gZmFpbHVyZS4KICAgIC8vLwogICAgYWNjZXNzKGFsbCkgcmVzb3VyY2UgQmFja2ZpbGxlciB7CiAgICAgICAgLy8vIFN0YXJ0IGluZGV4IG9mIHRoZSBmaXJzdCBnYXAgaW4gdGhlIGByYW5kb21Tb3VyY2VIaXN0b3J5YCBhcnJheSB3aGVyZSByYW5kb20gc291cmNlcyB3ZXJlIG5vdCByZWNvcmRlZCwKICAgICAgICAvLy8gYmVjYXVzZSBvZiBhIGhlYXJ0YmVhdCBmYWlsdXJlLgogICAgICAgIC8vLyBUaGVyZSBtYXkgYmUgbm9uIGNvbnRpZ3VvdXMgZ2FwcyBpbiB0aGUgaGlzdG9yeSwgYGdhcFN0YXJ0SW5kZXhgIGlzIHRoZSBzdGFydCBpbmRleCBvZiB0aGUgbG93ZXN0LWhlaWdodAogICAgICAgIC8vLyBnYXAuCiAgICAgICAgLy8vIElmIG5vIGdhcHMgZXhpc3QsIGBnYXBTdGFydEluZGV4YCBpcyBlcXVhbCB0byB0aGUgYHJhbmRvbVNvdXJjZUhpc3RvcnlgIGFycmF5IGxlbmd0aC4KICAgICAgICBhY2Nlc3MoY29udHJhY3QpIHZhciBnYXBTdGFydEluZGV4OiBVSW50NjQKICAgICAgICAvLy8gQmFja0ZpbGxpbmcgaXMgbGltaXRlZCB0byBhIG1heGltdW0gbnVtYmVyIG9mIGVudHJpZXMgcGVyIGNhbGwgdG8gbGltaXQgdGhlIGNvbXB1dGF0aW9uIGNvc3QuCiAgICAgICAgLy8vIFRoaXMgbWVhbnMgYSBsYXJnZSBnYXAgbWF5IG5lZWQgYSBmZXcgY2FsbHMgdG8gZ2V0IGZ1bGx5IGJhY2tmaWxsZWQuCiAgICAgICAgYWNjZXNzKGNvbnRyYWN0KSB2YXIgbWF4RW50cmllc1BlckNhbGw6IFVJbnQ2NAoKICAgICAgICBpbml0KCkgewogICAgICAgICAgICBzZWxmLmdhcFN0YXJ0SW5kZXggPSBVSW50NjQoUmFuZG9tQmVhY29uSGlzdG9yeS5yYW5kb21Tb3VyY2VIaXN0b3J5Lmxlbmd0aCkKICAgICAgICAgICAgc2VsZi5tYXhFbnRyaWVzUGVyQ2FsbCA9IDEwMAogICAgICAgIH0KCiAgICAgICAgYWNjZXNzKGFsbCkgdmlldyBmdW4gZ2V0TWF4RW50cmllc1BlckNhbGwoKSA6IFVJbnQ2NCB7CiAgICAgICAgICAgIHJldHVybiBzZWxmLm1heEVudHJpZXNQZXJDYWxsCiAgICAgICAgfQoKICAgICAgICBhY2Nlc3MoYWxsKSBmdW4gc2V0TWF4RW50cmllc1BlckNhbGwobWF4OiBVSW50NjQpIHsKICAgICAgICAgICAgYXNzZXJ0KAogICAgICAgICAgICAgICAgbWF4ID4gMCwKICAgICAgICAgICAgICAgIG1lc3NhZ2U6ICJSYW5kb21CZWFjb25IaXN0b3J5LkJhY2tmaWxsZXIuc2V0TWF4RW50cmllc1BlckNhbGw6IHRoZSBtYXhpbXVtIGVudHJ5IHBlciBjYWxsIG11c3QgYmUgc3RyaWN0bHkgcG9zaXRpdmUgYnV0IGdvdCBcKG1heCkiCiAgICAgICAgICAgICkKICAgICAgICAgICAgc2VsZi5tYXhFbnRyaWVzUGVyQ2FsbCA9IG1heAogICAgICAgIH0KCiAgICAgICAgLy8vIEZpbmRzIHRoZSBjb3JyZWN0IGluZGV4IHRvIGZpbGwgd2l0aCB0aGUgbmV3IHJhbmRvbSBzb3VyY2UuIElmIGEgZ2FwIGlzIGRldGVjdGVkLCBlbWl0cyB0aGUKICAgICAgICAvLy8gUmFuZG9tSGlzdG9yeU1pc3NpbmcgZXZlbnQuCiAgICAgICAgLy8vCiAgICAgICAgYWNjZXNzKGNvbnRyYWN0KSB2aWV3IGZ1biBmaW5kR2FwQW5kUmV0dXJuQ29ycmVjdEluZGV4KCk6IFVJbnQ2NCB7CgogICAgICAgICAgICBsZXQgY3VycmVudEJsb2NrSGVpZ2h0ID0gZ2V0Q3VycmVudEJsb2NrKCkuaGVpZ2h0CiAgICAgICAgICAgIC8vIGNvcnJlY3QgaW5kZXggdG8gZmlsbCB3aXRoIHRoZSBuZXcgcmFuZG9tIHNvdXJjZQogICAgICAgICAgICAvLyBzbyB0aGF0IGV2ZW50dWFsbHkgcmFuZG9tU291cmNlSGlzdG9yeVtjb3JyZWN0SW5kZXhdID0gaW5wdXRSYW5kb20KICAgICAgICAgICAgbGV0IGxvd2VzdEhlaWdodCA9IFJhbmRvbUJlYWNvbkhpc3RvcnkubG93ZXN0SGVpZ2h0IQogICAgICAgICAgICBsZXQgY29ycmVjdEluZGV4ID0gY3VycmVudEJsb2NrSGVpZ2h0IC0gbG93ZXN0SGVpZ2h0CgogICAgICAgICAgICAvLyBpZiBhIG5ldyBnYXAgaXMgZGV0ZWN0ZWQsIGVtaXQgYW4gZXZlbnQKICAgICAgICAgICAgdmFyIGFycmF5TGVuZ3RoID0gVUludDY0KFJhbmRvbUJlYWNvbkhpc3RvcnkucmFuZG9tU291cmNlSGlzdG9yeS5sZW5ndGgpCiAgICAgICAgICAgIGlmIGNvcnJlY3RJbmRleCA+IGFycmF5TGVuZ3RoIHsKICAgICAgICAgICAgICAgIGxldCBnYXBTdGFydEhlaWdodCA9IGxvd2VzdEhlaWdodCArIGFycmF5TGVuZ3RoCiAgICAgICAgICAgICAgICBlbWl0IFJhbmRvbUhpc3RvcnlNaXNzaW5nKGJsb2NrSGVpZ2h0OiBjdXJyZW50QmxvY2tIZWlnaHQsIGdhcFN0YXJ0SGVpZ2h0OiBnYXBTdGFydEhlaWdodCkKICAgICAgICAgICAgfQogICAgICAgICAgICByZXR1cm4gY29ycmVjdEluZGV4CiAgICAgICAgfQoKICAgICAgICAvLy8gQmFja2ZpbGxzIHBvc3NpYmxlIGVtcHR5IGVudHJpZXMgKGdhcHMpIGluIHRoZSBoaXN0b3J5IGFycmF5IHN0YXJ0aW5nIGZyb20gdGhlIHN0b3JlZCBgZ2FwU3RhcnRJbmRleGAsCiAgICAgICAgLy8vIHVzaW5nIGByYW5kb21Tb3VyY2VgIGFzIGEgc2VlZCBmb3IgYWxsIGVudHJpZXMuCiAgICAgICAgLy8vIElmIHRoZXJlIGFyZSBubyBnYXBzLCBgZ2FwU3RhcnRJbmRleGAgaXMganVzdCB1cGRhdGVkIHRvIGBSYW5kb21CZWFjb25IaXN0b3J5YCdzIGxlbmd0aC4KICAgICAgICAvLwogICAgICAgIC8vLyBXaGVuIGJhY2tmaWxsaW5nLCBhbGwgZW50cmllcyB1c2UgdGhlIHNhbWUgZW50cm9weS4gRWFjaCBlbnRyeSBpcyBleHRyYWN0ZWQgZnJvbSBgcmFuZG9tU291cmNlYCB1c2luZwogICAgICAgIC8vLyBzdWNjZXNzaXZlIGhhc2hpbmcuIFRoaXMgbWFrZXMgc3VyZSB0aGUgZW50cmllcyBhcmUgYWxsIGRpc3RpbmN0IGFsdGhvdWdoIHRoZXkgcHJvdmlkZQogICAgICAgIC8vLyB0aGUgc2FtZSBlbnRyb3B5LgogICAgICAgIC8vCiAgICAgICAgLy8vIGdhcHMgb25seSBvY2N1ciBpbiB0aGUgcmFyZSBldmVudCBvZiBhIHN5c3RlbSB0cmFuc2FjdGlvbiBmYWlsdXJlLiBJbiB0aGlzIGNhc2UsIGVudHJpZXMgYXJlIHN0aWxsCiAgICAgICAgLy8vIGZpbGxlZCB1c2luZyBhIHNvdXJjZSBub3Qga25vd24gYXQgdGhlIHRpbWUgb2YgYmxvY2sgZXhlY3V0aW9uLCB3aGljaCBndWFyYW50ZWVzIHVucHJlZGljYXRhYmlsaXR5LgogICAgICAgIGFjY2Vzcyhjb250cmFjdCkgZnVuIGJhY2tmaWxsKHJhbmRvbVNvdXJjZTogW1VJbnQ4XSkgewoKICAgICAgICAgICAgbGV0IGNvcnJlY3RJbmRleCA9IHNlbGYuZmluZEdhcEFuZFJldHVybkNvcnJlY3RJbmRleCgpCiAgICAgICAgICAgIHZhciBhcnJheUxlbmd0aCA9IFVJbnQ2NChSYW5kb21CZWFjb25IaXN0b3J5LnJhbmRvbVNvdXJjZUhpc3RvcnkubGVuZ3RoKQogICAgICAgICAgICAvLyBvcHRpb25hbCBvcHRpbWl6YXRpb24gZm9yIHRoZSBoYXBweSBjb21tb24gcGF0aDogaWYgbm8gZ2FwcyBhcmUgZGV0ZWN0ZWQsCiAgICAgICAgICAgIC8vIGJhY2tmaWxsaW5nIGlzbid0IG5lZWRlZCwgcmV0dXJuIGVhcmx5CiAgICAgICAgICAgIGlmIGNvcnJlY3RJbmRleCA9PSBzZWxmLmdhcFN0YXJ0SW5kZXggIHsKICAgICAgICAgICAgICAgIHNlbGYuZ2FwU3RhcnRJbmRleCA9IGFycmF5TGVuZ3RoICsgMQogICAgICAgICAgICAgICAgcmV0dXJuCiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIC8vIElmIGEgbmV3IGdhcCBpcyBkZXRlY3RlZCBpbiB0aGUgY3VycmVudCB0cmFuc2FjdGlvbiwgZmlsbCB0aGUgZ2FwIHdpdGggZW1wdHkgZW50cmllcy4KICAgICAgICAgICAgLy8gVGhpcyBoYXBwZW5zIGluIHRoZSByYXJlIGNhc2Ugd2hlcmUgYSBuZXcgZ2FwIG9jY3VycyBiZWNhdXNlIG9mIGEgc3lzdGVtIHRyYW5zYWN0aW9uIGZhaWx1cmUuCiAgICAgICAgICAgIHdoaWxlIGNvcnJlY3RJbmRleCA+IFVJbnQ2NChSYW5kb21CZWFjb25IaXN0b3J5LnJhbmRvbVNvdXJjZUhpc3RvcnkubGVuZ3RoKSB7CiAgICAgICAgICAgICAgICBSYW5kb21CZWFjb25IaXN0b3J5LnJhbmRvbVNvdXJjZUhpc3RvcnkuYXBwZW5kKFtdKQogICAgICAgICAgICB9CgogICAgICAgICAgICBhcnJheUxlbmd0aCA9IFVJbnQ2NChSYW5kb21CZWFjb25IaXN0b3J5LnJhbmRvbVNvdXJjZUhpc3RvcnkubGVuZ3RoKQogICAgICAgICAgICB2YXIgbmV3RW50cnkgPSByYW5kb21Tb3VyY2UKICAgICAgICAgICAgdmFyIGluZGV4ID0gc2VsZi5nYXBTdGFydEluZGV4CiAgICAgICAgICAgIHZhciBjb3VudCA9IDAgYXMgVUludDY0CiAgICAgICAgICAgIHdoaWxlIGNvdW50IDwgc2VsZi5tYXhFbnRyaWVzUGVyQ2FsbCB7CiAgICAgICAgICAgICAgICAvLyBtb3ZlIHRvIHRoZSBuZXh0IGVtcHR5IGVudHJ5CiAgICAgICAgICAgICAgICB3aGlsZSBpbmRleCA8IGFycmF5TGVuZ3RoICYmIFJhbmRvbUJlYWNvbkhpc3RvcnkucmFuZG9tU291cmNlSGlzdG9yeVtpbmRleF0ubGVuZ3RoID4gMCB7CiAgICAgICAgICAgICAgICAgICAgaW5kZXggPSBpbmRleCArIDEKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIC8vIGlmIHdlIHJlYWNoIHRoZSBlbmQgb2YgdGhlIGFycmF5IHRoZW4gYWxsIGV4aXN0aW5nIGdhcHMgZ290IGZpbGxlZAogICAgICAgICAgICAgICAgaWYgaW5kZXggPT0gYXJyYXlMZW5ndGggewogICAgICAgICAgICAgICAgICAgIGJyZWFrCiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAvLyBiYWNrIGZpbGwgdGhlIGVtcHR5IGVudHJ5CiAgICAgICAgICAgICAgICAvLyBJdCBpcyBndWFyYW50ZWVkIHRoYXQgc2hhMyBvdXRwdXQgKDI1NiBiaXRzKSBpcyBsYXJnZXIgdGhhbiB0aGUgbWluaW11bQogICAgICAgICAgICAgICAgLy8gcmVxdWlyZWQgc2l6ZSBvZiBhbiBTb1IgKDEyOCBiaXRzKQogICAgICAgICAgICAgICAgbmV3RW50cnkgPSBIYXNoQWxnb3JpdGhtLlNIQTNfMjU2Lmhhc2gobmV3RW50cnkpCiAgICAgICAgICAgICAgICBSYW5kb21CZWFjb25IaXN0b3J5LnJhbmRvbVNvdXJjZUhpc3RvcnlbaW5kZXhdID0gbmV3RW50cnkKICAgICAgICAgICAgICAgIGluZGV4ID0gaW5kZXggKyAxCiAgICAgICAgICAgICAgICBjb3VudCA9IGNvdW50ICsgMQogICAgICAgICAgICB9CgogICAgICAgICAgICAvLyBlbWl0IGFuIGV2ZW50IGFib3V0IGJhY2tmaWxsZWQgZW50cmllcwogICAgICAgICAgICBpZiBjb3VudCA+IDAgewogICAgICAgICAgICAgICAgbGV0IGdhcFN0YXJ0SGVpZ2h0ID0gUmFuZG9tQmVhY29uSGlzdG9yeS5sb3dlc3RIZWlnaHQhICsgc2VsZi5nYXBTdGFydEluZGV4CiAgICAgICAgICAgICAgICBlbWl0IFJhbmRvbUhpc3RvcnlCYWNrZmlsbGVkKAogICAgICAgICAgICAgICAgICAgIGJsb2NrSGVpZ2h0OiBnZXRDdXJyZW50QmxvY2soKS5oZWlnaHQsCiAgICAgICAgICAgICAgICAgICAgZ2FwU3RhcnRIZWlnaHQ6IGdhcFN0YXJ0SGVpZ2h0LAogICAgICAgICAgICAgICAgICAgIGNvdW50OiBjb3VudAogICAgICAgICAgICAgICAgKQogICAgICAgICAgICB9CgogICAgICAgICAgICAvLyBubyBtb3JlIGJhY2tmaWxsaW5nIGlzIHBvc3NpYmxlIGJ1dCB3ZSBuZWVkIHRvIHVwZGF0ZSBgZ2FwU3RhcnRJbmRleGAKICAgICAgICAgICAgLy8gdG86CiAgICAgICAgICAgIC8vICAtIHRoZSBuZXh0IGVtcHR5IGluZGV4IGlmIGdhcHMgc3RpbGwgZXhpc3QKICAgICAgICAgICAgLy8gIC0gdGhlIGxlbmd0aCBvZiB0aGUgYXJyYXkgYXQgdGhlIGVuZCBvZiB0aGUgdHJhbnNhY3Rpb24gaWYgdGhlcmUgYXJlIG5vIGdhcHMKICAgICAgICAgICAgd2hpbGUgaW5kZXggPCBhcnJheUxlbmd0aCAmJiBSYW5kb21CZWFjb25IaXN0b3J5LnJhbmRvbVNvdXJjZUhpc3RvcnlbaW5kZXhdLmxlbmd0aCA+IDAgewogICAgICAgICAgICAgICAgaW5kZXggPSBpbmRleCArIDEKICAgICAgICAgICAgfQogICAgICAgICAgICBpZiBpbmRleCA9PSBhcnJheUxlbmd0aCB7CiAgICAgICAgICAgICAgICBpbmRleCA9IGluZGV4ICsgMSAgIC8vIHRha2UgaW50byBhY2NvdW50IHRoZSB1cGNvbWluZyBhcHBlbmQgb2YgdGhlIFNvUiBhdCB0aGUgY29ycmVjdCBpbmRleAogICAgICAgICAgICB9CiAgICAgICAgICAgIHNlbGYuZ2FwU3RhcnRJbmRleCA9IGluZGV4CiAgICAgICAgfQogICAgfQoKICAgIC8qIC0tLSBSYW5kb21Tb3VyY2VIaXN0b3J5IC0tLSAqLwogICAgLy8KICAgIC8vLyBSZXByZXNlbnRzIGEgcmFuZG9tIHNvdXJjZSB2YWx1ZSBmb3IgYSBnaXZlbiBibG9jayBoZWlnaHQKICAgIC8vLwogICAgYWNjZXNzKGFsbCkgc3RydWN0IFJhbmRvbVNvdXJjZSB7CiAgICAgICAgYWNjZXNzKGFsbCkgbGV0IGJsb2NrSGVpZ2h0OiBVSW50NjQKICAgICAgICBhY2Nlc3MoYWxsKSBsZXQgdmFsdWU6IFtVSW50OF0KCiAgICAgICAgaW5pdChibG9ja0hlaWdodDogVUludDY0LCB2YWx1ZTogW1VJbnQ4XSkgewogICAgICAgICAgICBzZWxmLmJsb2NrSGVpZ2h0ID0gYmxvY2tIZWlnaHQKICAgICAgICAgICAgc2VsZi52YWx1ZSA9IHZhbHVlCiAgICAgICAgfQogICAgfQoKICAgIC8qIC0tLSBSYW5kb21Tb3VyY2VIaXN0b3J5UGFnZSAtLS0gKi8KICAgIC8vCiAgICAvLy8gQ29udGFpbnMgUmFuZG9tU291cmNlIHZhbHVlcyBvcmRlcmVkIGNocm9ub2xvZ2ljYWxseSBhY2NvcmRpbmcgdG8gYXNzb2NpYXRlZCBibG9jayBoZWlnaHQKICAgIC8vLwogICAgYWNjZXNzKGFsbCkgc3RydWN0IFJhbmRvbVNvdXJjZUhpc3RvcnlQYWdlIHsKICAgICAgICBhY2Nlc3MoYWxsKSBsZXQgcGFnZTogVUludDY0CiAgICAgICAgYWNjZXNzKGFsbCkgbGV0IHBlclBhZ2U6IFVJbnQ2NAogICAgICAgIGFjY2VzcyhhbGwpIGxldCB0b3RhbExlbmd0aDogVUludDY0CiAgICAgICAgYWNjZXNzKGFsbCkgbGV0IHZhbHVlczogW1JhbmRvbVNvdXJjZV0KICAgIAogICAgICAgIHZpZXcgaW5pdChwYWdlOiBVSW50NjQsIHBlclBhZ2U6IFVJbnQ2NCwgdG90YWxMZW5ndGg6IFVJbnQ2NCwgdmFsdWVzOiBbUmFuZG9tU291cmNlXSkgewogICAgICAgICAgICBzZWxmLnBhZ2UgPSBwYWdlCiAgICAgICAgICAgIHNlbGYucGVyUGFnZSA9IHBlclBhZ2UKICAgICAgICAgICAgc2VsZi50b3RhbExlbmd0aCA9IHRvdGFsTGVuZ3RoCiAgICAgICAgICAgIHNlbGYudmFsdWVzID0gdmFsdWVzCiAgICAgICAgfQogICAgfQoKICAgIC8qIC0tLSBDb250cmFjdCBNZXRob2RzIC0tLSAqLwogICAgLy8KICAgIC8vLyBHZXR0ZXIgZm9yIHRoZSBzb3VyY2Ugb2YgcmFuZG9tbmVzcyBhdCBhIGdpdmVuIGJsb2NrIGhlaWdodC4gUGFuaWNzIGlmIHRoZSByZXF1ZXN0ZWQgYmxvY2sgaGVpZ2h0IGVpdGhlcgogICAgLy8vIHByZWNlZGVzIG9yIGV4Y2VlZHMgdGhlIHJlY29yZGVkIGhpc3RvcnkuIE5vdGUgdGhhdCBhIHNvdXJjZSBvZiByYW5kb21uZXNzIGZvciBibG9jayBuIHdpbGwgbm90IGJlIGFjY2Vzc2libGUKICAgIC8vLyB1bnRpbCBibG9jayBuKzEuCiAgICAvLy8KICAgIC8vLyBAcGFyYW0gYXRCbG9ja0hlaWdodCBUaGUgYmxvY2sgaGVpZ2h0IGF0IHdoaWNoIHRvIHJldHJpZXZlIHRoZSBzb3VyY2Ugb2YgcmFuZG9tbmVzcwogICAgLy8vCiAgICAvLy8gQHJldHVybiBUaGUgc291cmNlIG9mIHJhbmRvbW5lc3MgYXQgdGhlIGdpdmVuIGJsb2NrIGhlaWdodCBhcyBSYW5kb21Tb3VyY2Ugc3RydWN0CiAgICAvLy8KICAgIGFjY2VzcyhhbGwpIGZ1biBzb3VyY2VPZlJhbmRvbW5lc3MoYXRCbG9ja0hlaWdodCBibG9ja0hlaWdodDogVUludDY0KTogUmFuZG9tU291cmNlIHsKICAgICAgICBwcmUgewogICAgICAgICAgICBzZWxmLmxvd2VzdEhlaWdodCAhPSBuaWw6ICJSYW5kb21CZWFjb25IaXN0b3J5LnNvdXJjZU9mUmFuZG9tbmVzczogSGlzdG9yeSBoYXMgbm90IHlldCBiZWVuIGluaXRpYWxpemVkIgogICAgICAgICAgICBibG9ja0hlaWdodCA+PSBzZWxmLmxvd2VzdEhlaWdodCE6ICJSYW5kb21CZWFjb25IaXN0b3J5LnNvdXJjZU9mUmFuZG9tbmVzczogUmVxdWVzdGVkIGJsb2NrIGhlaWdodCBcKGJsb2NrSGVpZ2h0KSBwcmVjZWRlcyByZWNvcmRlZCBoaXN0b3J5LCB3aGljaCBzdGFydHMgYXQgXChzZWxmLmxvd2VzdEhlaWdodCEpIgogICAgICAgICAgICBibG9ja0hlaWdodCA8IGdldEN1cnJlbnRCbG9jaygpLmhlaWdodDogIlJhbmRvbUJlYWNvbkhpc3Rvcnkuc291cmNlT2ZSYW5kb21uZXNzOiBTb3VyY2Ugb2YgcmFuZG9tbmVzcyBub3QgeWV0IHJlY29yZGVkIGZvciBibG9jayBoZWlnaHQgXChibG9ja0hlaWdodCkiCiAgICAgICAgfQogICAgICAgIGxldCBpbmRleCA9IGJsb2NrSGVpZ2h0IC0gc2VsZi5sb3dlc3RIZWlnaHQhCiAgICAgICAgYXNzZXJ0KAogICAgICAgICAgICBpbmRleCA+PSAwLAogICAgICAgICAgICBtZXNzYWdlOiAiUmFuZG9tQmVhY29uSGlzdG9yeS5zb3VyY2VPZlJhbmRvbW5lc3M6IFByb2JsZW0gZmluZGluZyByYW5kb20gc291cmNlIGhpc3RvcnkgaW5kZXgiCiAgICAgICAgKQogICAgICAgIGFzc2VydCgKICAgICAgICAgICAgaW5kZXggPCBVSW50NjQoc2VsZi5yYW5kb21Tb3VyY2VIaXN0b3J5Lmxlbmd0aCkgJiYgc2VsZi5yYW5kb21Tb3VyY2VIaXN0b3J5W2luZGV4XS5sZW5ndGggPiAwLAogICAgICAgICAgICBtZXNzYWdlOiAiUmFuZG9tQmVhY29uSGlzdG9yeS5zb3VyY2VPZlJhbmRvbW5lc3M6IFNvdXJjZSBvZiByYW5kb21uZXNzIGlzIGN1cnJlbnRseSBub3QgYXZhaWxhYmxlIGJ1dCB3aWxsIGJlIGF2YWlsYWJsZSBzb29uIgogICAgICAgICkKICAgICAgICByZXR1cm4gUmFuZG9tU291cmNlKGJsb2NrSGVpZ2h0OiBibG9ja0hlaWdodCwgdmFsdWU6IHNlbGYucmFuZG9tU291cmNlSGlzdG9yeVtpbmRleF0pCiAgICB9CgogICAgLy8vIFJldHJpZXZlcyBhIHBhZ2UgZnJvbSB0aGUgaGlzdG9yeSBvZiByYW5kb20gc291cmNlcyByZWNvcmRlZCBzbyBmYXIsIG9yZGVyZWQgY2hyb25vbG9naWNhbGx5CiAgICAvLy8KICAgIC8vLyBAcGFyYW0gcGFnZTogVGhlIHBhZ2UgbnVtYmVyIHRvIHJldHJpZXZlLCAwLWluZGV4ZWQKICAgIC8vLyBAcGFyYW0gcGVyUGFnZTogVGhlIG51bWJlciBvZiByYW5kb20gc291cmNlcyB0byBpbmNsdWRlIHBlciBwYWdlCiAgICAvLy8KICAgIC8vLyBAcmV0dXJuIEEgUmFuZG9tU291cmNlSGlzdG9yeVBhZ2UgY29udGFpbmluZyBSYW5kb21Tb3VyY2UgdmFsdWVzIGluIGNob3Jvbm9sb2dpY2FsIG9yZGVyIGFjY29yZGluZyB0bwogICAgLy8vIGFzc29jaWF0ZWQgYmxvY2sgaGVpZ2h0CiAgICAvLy8KICAgIGFjY2VzcyhhbGwpIGZ1biBnZXRSYW5kb21Tb3VyY2VIaXN0b3J5UGFnZShfIHBhZ2U6IFVJbnQ2NCwgcGVyUGFnZTogVUludDY0KTogUmFuZG9tU291cmNlSGlzdG9yeVBhZ2UgewogICAgICAgIHByZSB7CiAgICAgICAgICAgIHNlbGYubG93ZXN0SGVpZ2h0ICE9IG5pbDogIlJhbmRvbUJlYWNvbkhpc3RvcnkuZ2V0UmFuZG9tU291cmNlSGlzdG9yeVBhZ2U6IEhpc3RvcnkgaGFzIG5vdCB5ZXQgYmVlbiBpbml0aWFsaXplZCIKICAgICAgICB9CiAgICAgICAgbGV0IHZhbHVlczogW1JhbmRvbVNvdXJjZV0gPSBbXQogICAgICAgIGxldCB0b3RhbExlbmd0aCA9IFVJbnQ2NChzZWxmLnJhbmRvbVNvdXJjZUhpc3RvcnkubGVuZ3RoKQoKICAgICAgICB2YXIgc3RhcnRJbmRleCA9IHBhZ2UgKiBwZXJQYWdlCiAgICAgICAgaWYgc3RhcnRJbmRleCA+IHRvdGFsTGVuZ3RoIHsKICAgICAgICAgICAgc3RhcnRJbmRleCA9IHRvdGFsTGVuZ3RoCiAgICAgICAgfQogICAgICAgIHZhciBlbmRJbmRleCA9IHN0YXJ0SW5kZXggKyBwZXJQYWdlCiAgICAgICAgaWYgZW5kSW5kZXggPiB0b3RhbExlbmd0aCB7CiAgICAgICAgICAgIGVuZEluZGV4ID0gdG90YWxMZW5ndGgKICAgICAgICB9CgogICAgICAgIC8vIFJldHVybiBlbXB0eSBwYWdlIGlmIHJlcXVlc3QgZXhjZWVkcyBsYXN0IHBhZ2UKICAgICAgICBpZiBzdGFydEluZGV4ID09IGVuZEluZGV4IHsKICAgICAgICAgICAgcmV0dXJuIFJhbmRvbVNvdXJjZUhpc3RvcnlQYWdlKHBhZ2U6IHBhZ2UsIHBlclBhZ2U6IHBlclBhZ2UsIHRvdGFsTGVuZ3RoOiB0b3RhbExlbmd0aCwgdmFsdWVzOiB2YWx1ZXMpCiAgICAgICAgfQoKICAgICAgICAvLyBJdGVyYXRlIG92ZXIgaGlzdG9yeSBhbmQgY29uc3RydWN0IHBhZ2UgUmFuZG9tU291cmNlIHZhbHVlcwogICAgICAgIGxldCBsb3dlc3RIZWlnaHQgPSBzZWxmLmxvd2VzdEhlaWdodCEKICAgICAgICBmb3IgaSwgdmFsdWUgaW4gc2VsZi5yYW5kb21Tb3VyY2VIaXN0b3J5LnNsaWNlKGZyb206IEludChzdGFydEluZGV4KSwgdXBUbzogSW50KGVuZEluZGV4KSkgewogICAgICAgICAgICBhc3NlcnQoCiAgICAgICAgICAgICAgICB2YWx1ZS5sZW5ndGggPiAwLAogICAgICAgICAgICAgICAgbWVzc2FnZTogIlJhbmRvbUJlYWNvbkhpc3RvcnkuZ2V0UmFuZG9tU291cmNlSGlzdG9yeVBhZ2U6IFNvdXJjZSBvZiByYW5kb21uZXNzIGlzIGN1cnJlbnRseSBub3QgYXZhaWxhYmxlIGJ1dCB3aWxsIGJlIGF2YWlsYWJsZSBzb29uIgogICAgICAgICAgICApCiAgICAgICAgICAgIHZhbHVlcy5hcHBlbmQoCiAgICAgICAgICAgICAgICBSYW5kb21Tb3VyY2UoCiAgICAgICAgICAgICAgICAgICAgYmxvY2tIZWlnaHQ6IGxvd2VzdEhlaWdodCArIHN0YXJ0SW5kZXggKyBVSW50NjQoaSksCiAgICAgICAgICAgICAgICAgICAgdmFsdWU6IHZhbHVlCiAgICAgICAgICAgICAgICApCiAgICAgICAgICAgICkKICAgICAgICB9CgogICAgICAgIHJldHVybiBSYW5kb21Tb3VyY2VIaXN0b3J5UGFnZSgKICAgICAgICAgICAgcGFnZTogcGFnZSwKICAgICAgICAgICAgcGVyUGFnZTogcGVyUGFnZSwKICAgICAgICAgICAgdG90YWxMZW5ndGg6IHRvdGFsTGVuZ3RoLAogICAgICAgICAgICB2YWx1ZXM6IHZhbHVlcwogICAgICAgICkKICAgIH0KCiAgICAvLy8gR2V0dGVyIGZvciB0aGUgYmxvY2sgaGVpZ2h0IGF0IHdoaWNoIHRoZSBmaXJzdCBzb3VyY2Ugb2YgcmFuZG9tbmVzcyB3YXMgcmVjb3JkZWQKICAgIC8vLwogICAgLy8vIEByZXR1cm4gVGhlIGJsb2NrIGhlaWdodCBhdCB3aGljaCB0aGUgZmlyc3Qgc291cmNlIG9mIHJhbmRvbW5lc3Mgd2FzIHJlY29yZGVkCiAgICAvLy8KICAgIGFjY2VzcyhhbGwpIHZpZXcgZnVuIGdldExvd2VzdEhlaWdodCgpOiBVSW50NjQgewogICAgICAgIHJldHVybiBzZWxmLmxvd2VzdEhlaWdodCA/PyBwYW5pYygiUmFuZG9tQmVhY29uSGlzdG9yeS5nZXRMb3dlc3RIZWlnaHQ6IEhpc3RvcnkgaGFzIG5vdCB5ZXQgYmVlbiBpbml0aWFsaXplZCIpCiAgICB9CgogICAgLy8vIEdldHRlciBmb3IgdGhlIGNvbnRyYWN0J3MgQmFja2ZpbGxlciByZXNvdXJjZQogICAgYWNjZXNzKGNvbnRyYWN0KSBmdW4gYm9ycm93QmFja2ZpbGxlcigpOiAmQmFja2ZpbGxlcj8gewogICAgICAgIHJldHVybiBzZWxmLmFjY291bnQuc3RvcmFnZS5ib3Jyb3c8JkJhY2tmaWxsZXI+KGZyb206IC9zdG9yYWdlL3JhbmRvbUJlYWNvbkhpc3RvcnlCYWNrZmlsbGVyKQogICAgfQoKICAgIGluaXQoKSB7CiAgICAgICAgc2VsZi5sb3dlc3RIZWlnaHQgPSBuaWwKICAgICAgICBzZWxmLnJhbmRvbVNvdXJjZUhpc3RvcnkgPSBbXQogICAgICAgIHNlbGYuSGVhcnRiZWF0U3RvcmFnZVBhdGggPSAvc3RvcmFnZS9GbG93UmFuZG9tQmVhY29uSGlzdG9yeUhlYXJ0YmVhdAoKICAgICAgICBzZWxmLmFjY291bnQuc3RvcmFnZS5zYXZlKDwtY3JlYXRlIEhlYXJ0YmVhdCgpLCB0bzogc2VsZi5IZWFydGJlYXRTdG9yYWdlUGF0aCkKICAgIH0KfQo=",
		"RetrieveFraudulentTokensEvents": "aW1wb3J0IEZ1bmdpYmxlVG9rZW4gZnJvbSAweGYyMzNkY2VlODhmZTBhYmUKaW1wb3J0IEZsb3dUb2tlbiBmcm9tIDB4MTY1NDY1MzM5OTA0MGE2MQppbXBvcnQgRVZNIGZyb20gMHhlNDY3YjlkZDExZmEwMGRmCgovLy8gQ29udHJhY3QgZGVwbG95ZWQgdG8gdGhlIHNlcnZpY2UgYWNjb3VudCB0byBlbWl0IGV2ZW50cyB3aGVuIGZyYXVkdWxlbnQgdG9rZW5zCi8vLyBmcm9tIHRoZSBEZWMgMjd0aCwgMjAyNSBhdHRhY2sgYXJlIHJldHJpZXZlZCBvciBkZXN0cm95ZWQKLy8vIFRoaXMgaXMgdG8gaGF2ZSB0cmFuc3BhcmVuY3kgd2l0aCB0aGUgYWN0aW9ucyB0aGUgc2VydmljZSBhY2NvdW50IGNvbW1pdHRlZSB0YWtlcwovLy8gdG8gcmVjb25jaWxlIHRoZSBmcmF1ZHVsZW50IHRva2VucwoKYWNjZXNzKGFsbCkgY29udHJhY3QgUmV0cmlldmVGcmF1ZHVsZW50VG9rZW5zRXZlbnRzIHsKCiAgICBhY2Nlc3MoYWxsKSBsZXQgYWRtaW5TdG9yYWdlUGF0aDogU3RvcmFnZVBhdGgKCiAgICAvLy8gRXZlbnQgZW1pdHRlZCB3aGVuIGZyYXVkdWxlbnQgdG9rZW5zIGFyZSByZXRyaWV2ZWQgZnJvbSBhbnkgYWRkcmVzcyBhbmQgc3RvcmVkIGluIHRoZSBzZXJ2aWNlIGFjY291bnQncyB2YXVsdAogICAgLy8vIGZvciBsYXRlciBkZXN0cnVjdGlvbgogICAgLy8vIEBwYXJhbSB0eXBlSWRlbnRpZmllciAtIFRoZSB0eXBlIGlkZW50aWZpZXIgb2YgdGhlIGZyYXVkdWxlbnQgdG9rZW5zCiAgICAvLy8gQHBhcmFtIGFtb3VudCAtIFRoZSBhbW91bnQgb2YgZnJhdWR1bGVudCB0b2tlbnMgcmV0cmlldmVkCiAgICAvLy8gQHBhcmFtIGZyb21BZGRyZXNzIC0gVGhlIGFkZHJlc3MgZnJvbSB3aGljaCB0aGUgZnJhdWR1bGVudCB0b2tlbnMgd2VyZSByZXRyaWV2ZWQuCiAgICAvLy8gICAgICAgICAgICAgICAgICAgICAgVGhpcyBjYW4gYmUgYSBDYWRlbmNlIEFkZHJlc3MsIGEgQ09BIEFkZHJlc3MsIG9yIGFuIEVPQSBBZGRyZXNzLgogICAgYWNjZXNzKGFsbCkgZXZlbnQgRnJhdWR1bGVudFRva2Vuc1JldHJpZXZlZCh0eXBlSWRlbnRpZmllcjogU3RyaW5nLCBhbW91bnQ6IFVGaXg2NCwgZnJvbUFkZHJlc3M6IFN0cmluZykKCiAgICAvLy8gRXZlbnQgZW1pdHRlZCB3aGVuIGZyYXVkdWxlbnQgdG9rZW5zIGFyZSBkZXN0cm95ZWQgZnJvbSB0aGUgc2VydmljZSBhY2NvdW50J3MgdmF1bHQKICAgIC8vLyBAcGFyYW0gdHlwZUlkZW50aWZpZXIgLSBUaGUgdHlwZSBpZGVudGlmaWVyIG9mIHRoZSBmcmF1ZHVsZW50IHRva2VucyB0byBiZSBkZXN0cm95ZWQKICAgIC8vLyBAcGFyYW0gYW1vdW50IC0gVGhlIGFtb3VudCBvZiBmcmF1ZHVsZW50IHRva2VucyBkZXN0cm95ZWQKICAgIGFjY2VzcyhhbGwpIGV2ZW50IEZyYXVkdWxlbnRUb2tlbnNEZXN0cm95ZWQodHlwZUlkZW50aWZpZXI6IFN0cmluZywgYW1vdW50OiBVRml4NjQpCgogICAgLy8vIFJlc291cmNlIHRoYXQgYWxsb3dzIG9ubHkgdGhlIHNlcnZpY2UgYWNjb3VudCBhZG1pbiB0byBlbWl0IHRoZSBldmVudHMKICAgIGFjY2VzcyhhbGwpIHJlc291cmNlIEFkbWluIHsKCiAgICAgICAgLy8vIEVtaXRzIHRoZSBGcmF1ZHVsZW50VG9rZW5zUmV0cmlldmVkIGV2ZW50CiAgICAgICAgYWNjZXNzKGFsbCkgZnVuIGVtaXRSZXRyaWV2ZVRva2Vuc0V2ZW50KHR5cGVJZGVudGlmaWVyOiBTdHJpbmcsIGFtb3VudDogVUZpeDY0LCBmcm9tQWRkcmVzczogU3RyaW5nKSB7CiAgICAgICAgICAgIGVtaXQgRnJhdWR1bGVudFRva2Vuc1JldHJpZXZlZCh0eXBlSWRlbnRpZmllcjogdHlwZUlkZW50aWZpZXIsIGFtb3VudDogYW1vdW50LCBmcm9tQWRkcmVzczogZnJvbUFkZHJlc3MpCiAgICAgICAgfQogICAgICAgIAogICAgICAgIC8vLyBFbWl0cyB0aGUgRnJhdWR1bGVudFRva2Vuc0Rlc3Ryb3llZCBldmVudAogICAgICAgIGFjY2VzcyhhbGwpIGZ1biBlbWl0RGVzdHJveVRva2Vuc0V2ZW50KHR5cGVJZGVudGlmaWVyOiBTdHJpbmcsIGFtb3VudDogVUZpeDY0KSB7CiAgICAgICAgICAgIGVtaXQgRnJhdWR1bGVudFRva2Vuc0Rlc3Ryb3llZCh0eXBlSWRlbnRpZmllcjogdHlwZUlkZW50aWZpZXIsIGFtb3VudDogYW1vdW50KQogICAgICAgIH0KICAgIH0KCiAgICBpbml0KCkgewoKICAgICAgICBzZWxmLmFkbWluU3RvcmFnZVBhdGggPSAvc3RvcmFnZS9zZXJ2aWNlQWNjb3VudEFkbWluCgogICAgICAgIC8vIENyZWF0ZSBhIG5ldyBTZXJ2aWNlQWNjb3VudEFkbWluIHJlc291cmNlCiAgICAgICAgc2VsZi5hY2NvdW50LnN0b3JhZ2Uuc2F2ZSg8LWNyZWF0ZSBBZG1pbigpLCB0bzogc2VsZi5hZG1pblN0b3JhZ2VQYXRoKQoKICAgICAgICAvLyBTdG9yZSBhIG5ldyBGbG93VG9rZW4gVmF1bHQgYXQgYSBub24tc3RhbmRhcmQgc3RvcmFnZSBwYXRoIHRvIGhvbGQgZnJhdWR1bGVudCB0b2tlbnMKICAgICAgICBsZXQgZW1wdHlWYXVsdCA8LSBGbG93VG9rZW4uY3JlYXRlRW1wdHlWYXVsdCh2YXVsdFR5cGU6IFR5cGU8QEZsb3dUb2tlbi5WYXVsdD4oKSkKICAgICAgICBzZWxmLmFjY291bnQuc3RvcmFnZS5zYXZlKDwtZW1wdHlWYXVsdCwgdG86IC9zdG9yYWdlL2ZyYXVkdWxlbnRGbG93VG9rZW5WYXVsdCkKCiAgICAgICAgLy8gQ3JlYXRlIGEgcHVibGljIGNhcGFiaWxpdHkgdG8gdGhlIFZhdWx0IHRoYXQgb25seSBleHBvc2VzCiAgICAgICAgLy8gdGhlIGRlcG9zaXQgZnVuY3Rpb24gdGhyb3VnaCB0aGUgUmVjZWl2ZXIgaW50ZXJmYWNlCiAgICAgICAgbGV0IHJlY2VpdmVyQ2FwYWJpbGl0eSA9IHNlbGYuYWNjb3VudC5jYXBhYmlsaXRpZXMuc3RvcmFnZS5pc3N1ZTwmRmxvd1Rva2VuLlZhdWx0Pigvc3RvcmFnZS9mcmF1ZHVsZW50Rmxvd1Rva2VuVmF1bHQpCiAgICAgICAgc2VsZi5hY2NvdW50LmNhcGFiaWxpdGllcy5wdWJsaXNoKHJlY2VpdmVyQ2FwYWJpbGl0eSwgYXQ6IC9wdWJsaWMvZnJhdWR1bGVudEZsb3dUb2tlblJlY2VpdmVyKQoKICAgICAgICAvLyBDcmVhdGUgYSBwdWJsaWMgY2FwYWJpbGl0eSB0byB0aGUgVmF1bHQgdGhhdCBvbmx5IGV4cG9zZXMKICAgICAgICAvLyB0aGUgYmFsYW5jZSBmaWVsZCB0aHJvdWdoIHRoZSBCYWxhbmNlIGludGVyZmFjZQogICAgICAgIGxldCBiYWxhbmNlQ2FwYWJpbGl0eSA9IHNlbGYuYWNjb3VudC5jYXBhYmlsaXRpZXMuc3RvcmFnZS5pc3N1ZTwmRmxvd1Rva2VuLlZhdWx0Pigvc3RvcmFnZS9mcmF1ZHVsZW50Rmxvd1Rva2VuVmF1bHQpCiAgICAgICAgc2VsZi5hY2NvdW50LmNhcGFiaWxpdGllcy5wdWJsaXNoKGJhbGFuY2VDYXBhYmlsaXR5LCBhdDogL3B1YmxpYy9mcmF1ZHVsZW50Rmxvd1Rva2VuQmFsYW5jZSkKCiAgICAgICAgLy8gQ3JlYXRlIGEgbmV3IGFycmF5IHRvIHN0b3JlIHRoZSBDT0FzIHRvIGJlIGRlc3Ryb3llZAogICAgICAgIGxldCBuZXdDb2FBcnJheTogQFtFVk0uQ2FkZW5jZU93bmVkQWNjb3VudF0gPC0gW10KICAgICAgICBzZWxmLmFjY291bnQuc3RvcmFnZS5zYXZlKDwtbmV3Q29hQXJyYXksIHRvOiAvc3RvcmFnZS9jb2FBcnJheVRvRGVzdHJveSkKCiAgICAgICAgLyogLS0tIENvbmZpZ3VyZSBDT0EgLS0tICovCiAgICAgICAgLy8KICAgICAgICAvLyBFbnN1cmUgdGhlcmUgaXMgbm90IHlldCBhIENhZGVuY2VPd25lZEFjY291bnQgaW4gdGhlIHN0YW5kYXJkIHBhdGgKICAgICAgICBsZXQgY29hUGF0aCA9IC9zdG9yYWdlL2V2bQogICAgICAgIGlmIHNlbGYuYWNjb3VudC5zdG9yYWdlLnR5cGUoYXQ6IGNvYVBhdGgpICE9IG5pbCB7CiAgICAgICAgICAgIHBhbmljKAogICAgICAgICAgICAgICAgIkNPQSBhbHJlYWR5IGV4aXN0cyBpbiB0aGUgc2VydmljZSBhY2NvdW50IGF0IHBhdGg9XChjb2FQYXRoKSIKICAgICAgICAgICAgICAgIC5jb25jYXQoIi4gTWFrZSBzdXJlIHRoZSBzaWduaW5nIGFjY291bnQgZG9lcyBub3QgYWxyZWFkeSBoYXZlIGEgQ2FkZW5jZU93bmVkQWNjb3VudC4iKQogICAgICAgICAgICApCiAgICAgICAgfQogICAgICAgIC8vIENPQSBub3QgZm91bmQgaW4gc3RhbmRhcmQgcGF0aCwgY3JlYXRlIGFuZCBwdWJsaXNoIGEgcHVibGljICoqdW5lbnRpdGxlZCoqIGNhcGFiaWxpdHkKICAgICAgICBzZWxmLmFjY291bnQuc3RvcmFnZS5zYXZlKDwtRVZNLmNyZWF0ZUNhZGVuY2VPd25lZEFjY291bnQoKSwgdG86IGNvYVBhdGgpCiAgICAgICAgbGV0IGNvYUNhcGFiaWxpdHkgPSBzZWxmLmFjY291bnQuY2FwYWJpbGl0aWVzLnN0b3JhZ2UuaXNzdWU8JkVWTS5DYWRlbmNlT3duZWRBY2NvdW50Pihjb2FQYXRoKQogICAgICAgIHNlbGYuYWNjb3VudC5jYXBhYmlsaXRpZXMucHVibGlzaChjb2FDYXBhYmlsaXR5LCBhdDogL3B1YmxpYy9ldm0pCiAgICB9Cn0="
	},
	"_expandable": {},
	"_links": {
		"_self": "/v1/accounts/e467b9dd11fa00df"
	}
}