diff --git a/client/src/protoFleet/api/generated/fleetnodegateway/v1/fleetnodegateway_pb.ts b/client/src/protoFleet/api/generated/fleetnodegateway/v1/fleetnodegateway_pb.ts index 63e6198f0..71daffc46 100644 --- a/client/src/protoFleet/api/generated/fleetnodegateway/v1/fleetnodegateway_pb.ts +++ b/client/src/protoFleet/api/generated/fleetnodegateway/v1/fleetnodegateway_pb.ts @@ -33,7 +33,7 @@ import type { Message } from "@bufbuild/protobuf"; export const file_fleetnodegateway_v1_fleetnodegateway: GenFile = /*@__PURE__*/ fileDesc( - "CipmbGVldG5vZGVnYXRld2F5L3YxL2ZsZWV0bm9kZWdhdGV3YXkucHJvdG8SE2ZsZWV0bm9kZWdhdGV3YXkudjEilwEKD1JlZ2lzdGVyUmVxdWVzdBIkChBlbnJvbGxtZW50X3Rva2VuGAEgASgJQgq6SAdyBRAUGIAEEhgKBG5hbWUYAiABKAlCCrpIB3IFEAEY/wESIAoPaWRlbnRpdHlfcHVia2V5GAMgASgMQge6SAR6AmggEiIKEWVuY3J5cHRpb25fcHVia2V5GAQgASgMQge6SAR6AmggIokBChBSZWdpc3RlclJlc3BvbnNlEhUKDWZsZWV0X25vZGVfaWQYASABKAMSQAoRZW5yb2xsbWVudF9zdGF0dXMYAiABKA4yJS5mbGVldG5vZGVnYXRld2F5LnYxLkVucm9sbG1lbnRTdGF0dXMSHAoUaWRlbnRpdHlfZmluZ2VycHJpbnQYAyABKAkiWgoZQmVnaW5BdXRoSGFuZHNoYWtlUmVxdWVzdBIbCgdhcGlfa2V5GAEgASgJQgq6SAdyBRAUGIAEEiAKD2lkZW50aXR5X3B1YmtleRgCIAEoDEIHukgEegJoICJfChpCZWdpbkF1dGhIYW5kc2hha2VSZXNwb25zZRIRCgljaGFsbGVuZ2UYASABKAwSLgoKZXhwaXJlc19hdBgCIAEoCzIaLmdvb2dsZS5wcm90b2J1Zi5UaW1lc3RhbXAiWAocQ29tcGxldGVBdXRoSGFuZHNoYWtlUmVxdWVzdBIcCgljaGFsbGVuZ2UYASABKAxCCbpIBnoEEBAYQBIaCglzaWduYXR1cmUYAiABKAxCB7pIBHoCaEAiZgodQ29tcGxldGVBdXRoSGFuZHNoYWtlUmVzcG9uc2USFQoNc2Vzc2lvbl90b2tlbhgBIAEoCRIuCgpleHBpcmVzX2F0GAIgASgLMhouZ29vZ2xlLnByb3RvYnVmLlRpbWVzdGFtcCJtChZVcGxvYWRUZWxlbWV0cnlSZXF1ZXN0EhoKB3BheWxvYWQYASABKAxCCbpIBnoEGICAQBI3CgtjYXB0dXJlZF9hdBgCIAEoCzIaLmdvb2dsZS5wcm90b2J1Zi5UaW1lc3RhbXBCBrpIA8gBASIxChdVcGxvYWRUZWxlbWV0cnlSZXNwb25zZRIWCg5hY2NlcHRlZF9jb3VudBgBIAEoAyJqChNVcGxvYWRFdmVudHNSZXF1ZXN0EhoKB3BheWxvYWQYASABKAxCCbpIBnoEGICAQBI3CgtjYXB0dXJlZF9hdBgCIAEoCzIaLmdvb2dsZS5wcm90b2J1Zi5UaW1lc3RhbXBCBrpIA8gBASIuChRVcGxvYWRFdmVudHNSZXNwb25zZRIWCg5hY2NlcHRlZF9jb3VudBgBIAEoAyJNChZVcGxvYWRIZWFydGJlYXRSZXF1ZXN0EjMKB3NlbnRfYXQYASABKAsyGi5nb29nbGUucHJvdG9idWYuVGltZXN0YW1wQga6SAPIAQEiSgoXVXBsb2FkSGVhcnRiZWF0UmVzcG9uc2USLwoLcmVjZWl2ZWRfYXQYASABKAsyGi5nb29nbGUucHJvdG9idWYuVGltZXN0YW1wIuQBChJDb21tYW5kQXJ0aWZhY3RSZWYSHwoLYXJ0aWZhY3RfaWQYASABKAlCCrpIB3IFEAEYgAESSAoHcHVycG9zZRgCIAEoDjIrLmZsZWV0bm9kZWdhdGV3YXkudjEuQ29tbWFuZEFydGlmYWN0UHVycG9zZUIKukgHggEEEAEgABIcCghmaWxlbmFtZRgDIAEoCUIKukgHcgUQARj/ARIbCgpzaXplX2J5dGVzGAQgASgDQge6SAQiAiAAEigKBnNoYTI1NhgFIAEoCUIYukgVchMyDl5bYS1mMC05XXs2NH0kmAFAIpECChtDb21tYW5kQXJ0aWZhY3RVcGxvYWRIZWFkZXISHgoKY29tbWFuZF9pZBgBIAEoCUIKukgHcgUQARiAARJICgdwdXJwb3NlGAIgASgOMisuZmxlZXRub2RlZ2F0ZXdheS52MS5Db21tYW5kQXJ0aWZhY3RQdXJwb3NlQgq6SAeCAQQQASAAEhwKCGZpbGVuYW1lGAMgASgJQgq6SAdyBRABGP8BEhsKCnNpemVfYnl0ZXMYBCABKANCB7pIBCICIAASKAoGc2hhMjU2GAUgASgJQhi6SBVyEzIOXlthLWYwLTldezY0fSSYAUASIwoRZGV2aWNlX2lkZW50aWZpZXIYBiABKAlCCLpIBXIDGP8BIjEKFENvbW1hbmRBcnRpZmFjdENodW5rEhkKBGRhdGEYASABKAxCC7pICHoGEAEYgIBAIq0BChxVcGxvYWRDb21tYW5kQXJ0aWZhY3RSZXF1ZXN0EkIKBmhlYWRlchgBIAEoCzIwLmZsZWV0bm9kZWdhdGV3YXkudjEuQ29tbWFuZEFydGlmYWN0VXBsb2FkSGVhZGVySAASOgoFY2h1bmsYAiABKAsyKS5mbGVldG5vZGVnYXRld2F5LnYxLkNvbW1hbmRBcnRpZmFjdENodW5rSABCDQoEcGFydBIFukgCCAEiYgodVXBsb2FkQ29tbWFuZEFydGlmYWN0UmVzcG9uc2USQQoIYXJ0aWZhY3QYASABKAsyJy5mbGVldG5vZGVnYXRld2F5LnYxLkNvbW1hbmRBcnRpZmFjdFJlZkIGukgDyAEBIqgBCh5Eb3dubG9hZENvbW1hbmRBcnRpZmFjdFJlcXVlc3QSHgoKY29tbWFuZF9pZBgBIAEoCUIKukgHcgUQARiAARJBCghhcnRpZmFjdBgCIAEoCzInLmZsZWV0bm9kZWdhdGV3YXkudjEuQ29tbWFuZEFydGlmYWN0UmVmQga6SAPIAQESIwoRZGV2aWNlX2lkZW50aWZpZXIYAyABKAlCCLpIBXIDGP8BImIKHUNvbW1hbmRBcnRpZmFjdERvd25sb2FkSGVhZGVyEkEKCGFydGlmYWN0GAEgASgLMicuZmxlZXRub2RlZ2F0ZXdheS52MS5Db21tYW5kQXJ0aWZhY3RSZWZCBrpIA8gBASKyAQofRG93bmxvYWRDb21tYW5kQXJ0aWZhY3RSZXNwb25zZRJECgZoZWFkZXIYASABKAsyMi5mbGVldG5vZGVnYXRld2F5LnYxLkNvbW1hbmRBcnRpZmFjdERvd25sb2FkSGVhZGVySAASOgoFY2h1bmsYAiABKAsyKS5mbGVldG5vZGVnYXRld2F5LnYxLkNvbW1hbmRBcnRpZmFjdENodW5rSABCDQoEcGFydBIFukgCCAEiiQEKHlJlcG9ydERpc2NvdmVyZWREZXZpY2VzUmVxdWVzdBJHCgdkZXZpY2VzGAEgAygLMisuZmxlZXRub2RlZ2F0ZXdheS52MS5EaXNjb3ZlcmVkRGV2aWNlUmVwb3J0Qgm6SAaSAQMQgAgSHgoKY29tbWFuZF9pZBgCIAEoCUIKukgHcgUQARiAASKDAwoWRGlzY292ZXJlZERldmljZVJlcG9ydBIlChFkZXZpY2VfaWRlbnRpZmllchgBIAEoCUIKukgHcgUQARj/ARIfCgppcF9hZGRyZXNzGAIgASgJQgu6SAhyBhABGC1wARKGAQoEcG9ydBgDIAEoCUJ4ukh1ugFsCgpwb3J0LnJhbmdlEilwb3J0IG11c3QgYmUgYSBkZWNpbWFsIG51bWJlciBpbiAxLi42NTUzNRozdGhpcy5tYXRjaGVzKCdeWzEtOV1bMC05XSokJykgJiYgaW50KHRoaXMpIDw9IDY1NTM1cgQQARgFEhsKCnVybF9zY2hlbWUYBCABKAlCB7pIBHICGCASHgoLZHJpdmVyX25hbWUYBSABKAlCCbpIBnIEEAEYMhIXCgVtb2RlbBgGIAEoCUIIukgFcgMY/wESHgoMbWFudWZhY3R1cmVyGAcgASgJQgi6SAVyAxj/ARIiChBmaXJtd2FyZV92ZXJzaW9uGAggASgJQgi6SAVyAxj/ASJRCh9SZXBvcnREaXNjb3ZlcmVkRGV2aWNlc1Jlc3BvbnNlEhYKDmFjY2VwdGVkX2NvdW50GAEgASgDEhYKDnJlamVjdGVkX2NvdW50GAIgASgDIvoDChNGbGVldE5vZGVQYWlyUmVzdWx0EiUKEWRldmljZV9pZGVudGlmaWVyGAEgASgJQgq6SAdyBRABGP8BEjEKB291dGNvbWUYAiABKA4yIC5mbGVldG5vZGVnYXRld2F5LnYxLlBhaXJPdXRjb21lEh8KDXNlcmlhbF9udW1iZXIYAyABKAlCCLpIBXIDGP8BEhwKC21hY19hZGRyZXNzGAQgASgJQge6SARyAhhAEhcKBW1vZGVsGAUgASgJQgi6SAVyAxj/ARIeCgxtYW51ZmFjdHVyZXIYBiABKAlCCLpIBXIDGP8BEiIKEGZpcm13YXJlX3ZlcnNpb24YByABKAlCCLpIBXIDGP8BEh8KDWVycm9yX21lc3NhZ2UYCCABKAlCCLpIBXIDGIAgEiQKF2RlZmF1bHRfcGFzc3dvcmRfYWN0aXZlGAwgASgISACIAQESSAoVZW5jcnlwdGVkX2NyZWRlbnRpYWxzGA0gASgLMikuZmxlZXRub2RlZ2F0ZXdheS52MS5FbmNyeXB0ZWRDcmVkZW50aWFsc0IaChhfZGVmYXVsdF9wYXNzd29yZF9hY3RpdmVKBAgJEApKBAgKEAtKBAgLEAxSDXVzZWRfdXNlcm5hbWVSDXVzZWRfcGFzc3dvcmRSEHVzZWRfY3JlZGVudGlhbHMiTgoURW5jcnlwdGVkQ3JlZGVudGlhbHMSGgoIdXNlcm5hbWUYASABKAxCCLpIBXoDGIAgEhoKCHBhc3N3b3JkGAIgASgMQgi6SAV6AxiAICKCAQoaUmVwb3J0UGFpcmVkRGV2aWNlc1JlcXVlc3QSHgoKY29tbWFuZF9pZBgBIAEoCUIKukgHcgUQARiAARJECgdyZXN1bHRzGAIgAygLMiguZmxlZXRub2RlZ2F0ZXdheS52MS5GbGVldE5vZGVQYWlyUmVzdWx0Qgm6SAaSAQMQgAgiTQobUmVwb3J0UGFpcmVkRGV2aWNlc1Jlc3BvbnNlEhYKDmFjY2VwdGVkX2NvdW50GAEgASgDEhYKDnJlamVjdGVkX2NvdW50GAIgASgDIokBChRDb250cm9sU3RyZWFtUmVxdWVzdBIyCgVoZWxsbxgBIAEoCzIhLmZsZWV0bm9kZWdhdGV3YXkudjEuQ29udHJvbEhlbGxvSAASLgoDYWNrGAIgASgLMh8uZmxlZXRub2RlZ2F0ZXdheS52MS5Db250cm9sQWNrSABCDQoEa2luZBIFukgCCAEimAEKFUNvbnRyb2xTdHJlYW1SZXNwb25zZRI4CghhY2NlcHRlZBgBIAEoCzIkLmZsZWV0bm9kZWdhdGV3YXkudjEuQ29udHJvbEFjY2VwdGVkSAASNgoHY29tbWFuZBgCIAEoCzIjLmZsZWV0bm9kZWdhdGV3YXkudjEuQ29udHJvbENvbW1hbmRIAEINCgRraW5kEgW6SAIIASIOCgxDb250cm9sSGVsbG8iQgoPQ29udHJvbEFjY2VwdGVkEi8KC3NlcnZlcl90aW1lGAEgASgLMhouZ29vZ2xlLnByb3RvYnVmLlRpbWVzdGFtcCJMCg5Db250cm9sQ29tbWFuZBIeCgpjb21tYW5kX2lkGAEgASgJQgq6SAdyBRABGIABEhoKB3BheWxvYWQYAiABKAxCCbpIBnoEGICAQCK3AwoZTWluZXJDb25uZWN0aW9uRGVzY3JpcHRvchIlChFkZXZpY2VfaWRlbnRpZmllchgBIAEoCUIKukgHcgUQARj/ARIeCgtkcml2ZXJfbmFtZRgCIAEoCUIJukgGcgQQARgyEh8KCmlwX2FkZHJlc3MYAyABKAlCC7pICHIGEAEYLXABEoYBCgRwb3J0GAQgASgJQni6SHW6AWwKCnBvcnQucmFuZ2USKXBvcnQgbXVzdCBiZSBhIGRlY2ltYWwgbnVtYmVyIGluIDEuLjY1NTM1GjN0aGlzLm1hdGNoZXMoJ15bMS05XVswLTldKiQnKSAmJiBpbnQodGhpcykgPD0gNjU1MzVyBBABGAUSGwoKdXJsX3NjaGVtZRgFIAEoCUIHukgEcgIYIBIfCg1zZXJpYWxfbnVtYmVyGAYgASgJQgi6SAVyAxj/ARIdCgttYWNfYWRkcmVzcxgHIAEoCUIIukgFcgMY/wESJQoTY3JlZGVudGlhbF91c2VybmFtZRgIIAEoDEIIukgFegMYgCASJQoTY3JlZGVudGlhbF9wYXNzd29yZBgJIAEoDEIIukgFegMYgCAitwcKDE1pbmVyQ29tbWFuZBJGCgZ0YXJnZXQYASABKAsyLi5mbGVldG5vZGVnYXRld2F5LnYxLk1pbmVyQ29ubmVjdGlvbkRlc2NyaXB0b3JCBrpIA8gBARIzCgZyZWJvb3QYAiABKAsyIS5mbGVldG5vZGVnYXRld2F5LnYxLlJlYm9vdEFjdGlvbkgAEj4KDHN0YXJ0X21pbmluZxgDIAEoCzImLmZsZWV0bm9kZWdhdGV3YXkudjEuU3RhcnRNaW5pbmdBY3Rpb25IABI8CgtzdG9wX21pbmluZxgEIAEoCzIlLmZsZWV0bm9kZWdhdGV3YXkudjEuU3RvcE1pbmluZ0FjdGlvbkgAEjgKCWJsaW5rX2xlZBgFIAEoCzIjLmZsZWV0bm9kZWdhdGV3YXkudjEuQmxpbmtMZWRBY3Rpb25IABI1CgdjdXJ0YWlsGAYgASgLMiIuZmxlZXRub2RlZ2F0ZXdheS52MS5DdXJ0YWlsQWN0aW9uSAASOQoJdW5jdXJ0YWlsGAcgASgLMiQuZmxlZXRub2RlZ2F0ZXdheS52MS5VbmN1cnRhaWxBY3Rpb25IABJFChBzZXRfY29vbGluZ19tb2RlGAggASgLMikuZmxlZXRub2RlZ2F0ZXdheS52MS5TZXRDb29saW5nTW9kZUFjdGlvbkgAEkUKEHNldF9wb3dlcl90YXJnZXQYCSABKAsyKS5mbGVldG5vZGVnYXRld2F5LnYxLlNldFBvd2VyVGFyZ2V0QWN0aW9uSAASSwoTdXBkYXRlX21pbmluZ19wb29scxgKIAEoCzIsLmZsZWV0bm9kZWdhdGV3YXkudjEuVXBkYXRlTWluaW5nUG9vbHNBY3Rpb25IABJFChBnZXRfbWluaW5nX3Bvb2xzGAsgASgLMikuZmxlZXRub2RlZ2F0ZXdheS52MS5HZXRNaW5pbmdQb29sc0FjdGlvbkgAEjoKCmdldF9lcnJvcnMYDCABKAsyJC5mbGVldG5vZGVnYXRld2F5LnYxLkdldEVycm9yc0FjdGlvbkgAEk8KFXVwZGF0ZV9taW5lcl9wYXNzd29yZBgNIAEoCzIuLmZsZWV0bm9kZWdhdGV3YXkudjEuVXBkYXRlTWluZXJQYXNzd29yZEFjdGlvbkgAEkAKDWRvd25sb2FkX2xvZ3MYDiABKAsyJy5mbGVldG5vZGVnYXRld2F5LnYxLkRvd25sb2FkTG9nc0FjdGlvbkgAQg8KBmFjdGlvbhIFukgCCAEiDgoMUmVib290QWN0aW9uIhMKEVN0YXJ0TWluaW5nQWN0aW9uIhIKEFN0b3BNaW5pbmdBY3Rpb24iEAoOQmxpbmtMZWRBY3Rpb24iEQoPVW5jdXJ0YWlsQWN0aW9uIhYKFEdldE1pbmluZ1Bvb2xzQWN0aW9uIhEKD0dldEVycm9yc0FjdGlvbiI4ChJEb3dubG9hZExvZ3NBY3Rpb24SIgoOYmF0Y2hfbG9nX3V1aWQYASABKAlCCrpIB3IFEAEYgAEimgIKFE5vZGVFbmNyeXB0ZWRQYXlsb2FkEqYBCglhbGdvcml0aG0YASABKAlCkgG6SI4BugGEAQogbm9kZV9lbmNyeXB0ZWRfcGF5bG9hZC5hbGdvcml0aG0SM2FsZ29yaXRobSBtdXN0IGJlIHgyNTUxOS1oa2RmLXNoYTI1Ni1hZXMtMjU2LWdjbS12MRordGhpcyA9PSAneDI1NTE5LWhrZGYtc2hhMjU2LWFlcy0yNTYtZ2NtLXYxJ3IEEAEYQBIhChBlcGhlbWVyYWxfcHVia2V5GAIgASgMQge6SAR6AmggEhYKBW5vbmNlGAMgASgMQge6SAR6AmgMEh4KCmNpcGhlcnRleHQYBCABKAxCCrpIB3oFEBEYgEAicQoZVXBkYXRlTWluZXJQYXNzd29yZEFjdGlvbhJUChllbmNyeXB0ZWRfcGFzc3dvcmRfdXBkYXRlGAEgASgLMikuZmxlZXRub2RlZ2F0ZXdheS52MS5Ob2RlRW5jcnlwdGVkUGF5bG9hZEIGukgDyAEBIm0KGVVwZGF0ZU1pbmVyUGFzc3dvcmRSZXN1bHQSUAoVZW5jcnlwdGVkX2NyZWRlbnRpYWxzGAEgASgLMikuZmxlZXRub2RlZ2F0ZXdheS52MS5FbmNyeXB0ZWRDcmVkZW50aWFsc0IGukgDyAEBIkAKDUN1cnRhaWxBY3Rpb24SLwoFbGV2ZWwYASABKA4yIC5jdXJ0YWlsbWVudC52MS5DdXJ0YWlsbWVudExldmVsIjwKFFNldENvb2xpbmdNb2RlQWN0aW9uEiQKBG1vZGUYASABKA4yFi5jb21tb24udjEuQ29vbGluZ01vZGUiUgoUU2V0UG93ZXJUYXJnZXRBY3Rpb24SOgoQcGVyZm9ybWFuY2VfbW9kZRgBIAEoDjIgLm1pbmVyY29tbWFuZC52MS5QZXJmb3JtYW5jZU1vZGUihQMKEE1pbmluZ1Bvb2xDb25maWcSGwoIcHJpb3JpdHkYASABKAVCCbpIBhoEGAIoABK3AgoDdXJsGAIgASgJQqkCukilAnKiAhAMGIACMpoCXihzdHJhdHVtXCsodGNwfHNzbHx3cyk6XC9cLygoW2EtekEtWjAtOV1bYS16QS1aMC05Li1dKlthLXpBLVowLTldXC5bYS16QS1aXXsyLH0pfChcZHsxLDN9XC4pezN9XGR7MSwzfXxcWyhbMC05YS1mQS1GOl0rKVxdKSg6XGR7MSw1fSk/fHN0cmF0dW0yXCt0Y3A6XC9cLygoW2EtekEtWjAtOV1bYS16QS1aMC05Li1dKlthLXpBLVowLTldXC5bYS16QS1aXXsyLH0pfChcZHsxLDN9XC4pezN9XGR7MSwzfXxcWyhbMC05YS1mQS1GOl0rKVxdKTpcZHsxLDV9XC9bQS1aYS16MC05XytcLz06Li1dKykkEhoKCHVzZXJuYW1lGAMgASgJQgi6SAVyAxiABCJbChdVcGRhdGVNaW5pbmdQb29sc0FjdGlvbhJACgVwb29scxgBIAMoCzIlLmZsZWV0bm9kZWdhdGV3YXkudjEuTWluaW5nUG9vbENvbmZpZ0IKukgHkgEECAEQAyJWChRHZXRNaW5pbmdQb29sc1Jlc3VsdBI+CgVwb29scxgBIAMoCzIlLmZsZWV0bm9kZWdhdGV3YXkudjEuTWluaW5nUG9vbENvbmZpZ0IIukgFkgECEAMixQUKEE1pbmVyRXJyb3JSZXBvcnQSNAoLbWluZXJfZXJyb3IYASABKA4yFS5lcnJvcnMudjEuTWluZXJFcnJvckIIukgFggECEAESHwoNY2F1c2Vfc3VtbWFyeRgCIAEoCUIIukgFcgMYgCASJAoScmVjb21tZW5kZWRfYWN0aW9uGAMgASgJQgi6SAVyAxiAIBIvCghzZXZlcml0eRgEIAEoDjITLmVycm9ycy52MS5TZXZlcml0eUIIukgFggECEAESMQoNZmlyc3Rfc2Vlbl9hdBgFIAEoCzIaLmdvb2dsZS5wcm90b2J1Zi5UaW1lc3RhbXASMAoMbGFzdF9zZWVuX2F0GAYgASgLMhouZ29vZ2xlLnByb3RvYnVmLlRpbWVzdGFtcBItCgljbG9zZWRfYXQYByABKAsyGi5nb29nbGUucHJvdG9idWYuVGltZXN0YW1wEnAKEXZlbmRvcl9hdHRyaWJ1dGVzGAggAygLMjsuZmxlZXRub2RlZ2F0ZXdheS52MS5NaW5lckVycm9yUmVwb3J0LlZlbmRvckF0dHJpYnV0ZXNFbnRyeUIYukgVmgESECAiB3IFEAEYgAEqBXIDGIAIEh0KCWRldmljZV9pZBgJIAEoCUIKukgHcgUQARj/ARIjCgxjb21wb25lbnRfaWQYCiABKAlCCLpIBXIDGP8BSACIAQESGAoGaW1wYWN0GAsgASgJQgi6SAVyAxiAIBIZCgdzdW1tYXJ5GAwgASgJQgi6SAVyAxiAIBI6Cg5jb21wb25lbnRfdHlwZRgNIAEoDjIYLmVycm9ycy52MS5Db21wb25lbnRUeXBlQgi6SAWCAQIQARo3ChVWZW5kb3JBdHRyaWJ1dGVzRW50cnkSCwoDa2V5GAEgASgJEg0KBXZhbHVlGAIgASgJOgI4AUIPCg1fY29tcG9uZW50X2lkIqMBCg9HZXRFcnJvcnNSZXN1bHQSHQoJZGV2aWNlX2lkGAEgASgJQgq6SAdyBRABGP8BEkAKBmVycm9ycxgCIAMoCzIlLmZsZWV0bm9kZWdhdGV3YXkudjEuTWluZXJFcnJvclJlcG9ydEIJukgGkgEDEIAEEhEKCXRydW5jYXRlZBgDIAEoCBIcChRvbWl0dGVkX3JlcG9ydF9jb3VudBgEIAEoDSL9AQoMQWdlbnRDb21tYW5kEi8KCGRpc2NvdmVyGAEgASgLMhsucGFpcmluZy52MS5EaXNjb3ZlclJlcXVlc3RIABIwCgRwYWlyGAIgASgLMiAucGFpcmluZy52MS5GbGVldE5vZGVQYWlyUmVxdWVzdEgAEjoKDW1pbmVyX2NvbW1hbmQYAyABKAsyIS5mbGVldG5vZGVnYXRld2F5LnYxLk1pbmVyQ29tbWFuZEgAEjwKCXRlbGVtZXRyeRgEIAEoCzInLnRlbGVtZXRyeS52MS5GbGVldE5vZGVUZWxlbWV0cnlSZXF1ZXN0SABCEAoHY29tbWFuZBIFukgCCAEiqAEKCkNvbnRyb2xBY2sSHgoKY29tbWFuZF9pZBgBIAEoCUIKukgHcgUQARiAARIRCglzdWNjZWVkZWQYAiABKAgSHwoNZXJyb3JfbWVzc2FnZRgDIAEoCUIIukgFcgMYgCASKgoEY29kZRgEIAEoDjIcLmZsZWV0bm9kZWdhdGV3YXkudjEuQWNrQ29kZRIaCgdwYXlsb2FkGAUgASgMQgm6SAZ6BBiAgEAqlAEKEEVucm9sbG1lbnRTdGF0dXMSIQodRU5ST0xMTUVOVF9TVEFUVVNfVU5TUEVDSUZJRUQQABIdChlFTlJPTExNRU5UX1NUQVRVU19QRU5ESU5HEAESHwobRU5ST0xMTUVOVF9TVEFUVVNfQ09ORklSTUVEEAISHQoZRU5ST0xMTUVOVF9TVEFUVVNfUkVWT0tFRBADKpoBChZDb21tYW5kQXJ0aWZhY3RQdXJwb3NlEigKJENPTU1BTkRfQVJUSUZBQ1RfUFVSUE9TRV9VTlNQRUNJRklFRBAAEicKI0NPTU1BTkRfQVJUSUZBQ1RfUFVSUE9TRV9NSU5FUl9MT0dTEAESLQopQ09NTUFORF9BUlRJRkFDVF9QVVJQT1NFX0ZJUk1XQVJFX1BBWUxPQUQQAiqYAQoLUGFpck91dGNvbWUSHAoYUEFJUl9PVVRDT01FX1VOU1BFQ0lGSUVEEAASFwoTUEFJUl9PVVRDT01FX1BBSVJFRBABEhwKGFBBSVJfT1VUQ09NRV9BVVRIX05FRURFRBACEhwKGFBBSVJfT1VUQ09NRV9BVVRIX0ZBSUxFRBADEhYKElBBSVJfT1VUQ09NRV9FUlJPUhAEKrQCCgdBY2tDb2RlEhgKFEFDS19DT0RFX1VOU1BFQ0lGSUVEEAASDwoLQUNLX0NPREVfT0sQARIUChBBQ0tfQ09ERV9QQVJUSUFMEAISGAoUQUNLX0NPREVfQkFEX1JFUVVFU1QQAxIcChhBQ0tfQ09ERV9BR0VOVF9JTkNBUEFCTEUQBBIYChRBQ0tfQ09ERV9TQ0FOX0ZBSUxFRBAFEhoKFkFDS19DT0RFX1JFUE9SVF9GQUlMRUQQBhIVChFBQ0tfQ09ERV9JTlRFUk5BTBAHEhEKDUFDS19DT0RFX0JVU1kQCBIcChhBQ0tfQ09ERV9VTkFVVEhFTlRJQ0FURUQQCRIaChZBQ0tfQ09ERV9VTklNUExFTUVOVEVEEAoSFgoSQUNLX0NPREVfRk9SQklEREVOEAsypwoKF0ZsZWV0Tm9kZUdhdGV3YXlTZXJ2aWNlElcKCFJlZ2lzdGVyEiQuZmxlZXRub2RlZ2F0ZXdheS52MS5SZWdpc3RlclJlcXVlc3QaJS5mbGVldG5vZGVnYXRld2F5LnYxLlJlZ2lzdGVyUmVzcG9uc2USdQoSQmVnaW5BdXRoSGFuZHNoYWtlEi4uZmxlZXRub2RlZ2F0ZXdheS52MS5CZWdpbkF1dGhIYW5kc2hha2VSZXF1ZXN0Gi8uZmxlZXRub2RlZ2F0ZXdheS52MS5CZWdpbkF1dGhIYW5kc2hha2VSZXNwb25zZRJ+ChVDb21wbGV0ZUF1dGhIYW5kc2hha2USMS5mbGVldG5vZGVnYXRld2F5LnYxLkNvbXBsZXRlQXV0aEhhbmRzaGFrZVJlcXVlc3QaMi5mbGVldG5vZGVnYXRld2F5LnYxLkNvbXBsZXRlQXV0aEhhbmRzaGFrZVJlc3BvbnNlEm4KD1VwbG9hZFRlbGVtZXRyeRIrLmZsZWV0bm9kZWdhdGV3YXkudjEuVXBsb2FkVGVsZW1ldHJ5UmVxdWVzdBosLmZsZWV0bm9kZWdhdGV3YXkudjEuVXBsb2FkVGVsZW1ldHJ5UmVzcG9uc2UoARJlCgxVcGxvYWRFdmVudHMSKC5mbGVldG5vZGVnYXRld2F5LnYxLlVwbG9hZEV2ZW50c1JlcXVlc3QaKS5mbGVldG5vZGVnYXRld2F5LnYxLlVwbG9hZEV2ZW50c1Jlc3BvbnNlKAESbAoPVXBsb2FkSGVhcnRiZWF0EisuZmxlZXRub2RlZ2F0ZXdheS52MS5VcGxvYWRIZWFydGJlYXRSZXF1ZXN0GiwuZmxlZXRub2RlZ2F0ZXdheS52MS5VcGxvYWRIZWFydGJlYXRSZXNwb25zZRKAAQoVVXBsb2FkQ29tbWFuZEFydGlmYWN0EjEuZmxlZXRub2RlZ2F0ZXdheS52MS5VcGxvYWRDb21tYW5kQXJ0aWZhY3RSZXF1ZXN0GjIuZmxlZXRub2RlZ2F0ZXdheS52MS5VcGxvYWRDb21tYW5kQXJ0aWZhY3RSZXNwb25zZSgBEoYBChdEb3dubG9hZENvbW1hbmRBcnRpZmFjdBIzLmZsZWV0bm9kZWdhdGV3YXkudjEuRG93bmxvYWRDb21tYW5kQXJ0aWZhY3RSZXF1ZXN0GjQuZmxlZXRub2RlZ2F0ZXdheS52MS5Eb3dubG9hZENvbW1hbmRBcnRpZmFjdFJlc3BvbnNlMAEShAEKF1JlcG9ydERpc2NvdmVyZWREZXZpY2VzEjMuZmxlZXRub2RlZ2F0ZXdheS52MS5SZXBvcnREaXNjb3ZlcmVkRGV2aWNlc1JlcXVlc3QaNC5mbGVldG5vZGVnYXRld2F5LnYxLlJlcG9ydERpc2NvdmVyZWREZXZpY2VzUmVzcG9uc2USeAoTUmVwb3J0UGFpcmVkRGV2aWNlcxIvLmZsZWV0bm9kZWdhdGV3YXkudjEuUmVwb3J0UGFpcmVkRGV2aWNlc1JlcXVlc3QaMC5mbGVldG5vZGVnYXRld2F5LnYxLlJlcG9ydFBhaXJlZERldmljZXNSZXNwb25zZRJqCg1Db250cm9sU3RyZWFtEikuZmxlZXRub2RlZ2F0ZXdheS52MS5Db250cm9sU3RyZWFtUmVxdWVzdBoqLmZsZWV0bm9kZWdhdGV3YXkudjEuQ29udHJvbFN0cmVhbVJlc3BvbnNlKAEwAUL4AQoXY29tLmZsZWV0bm9kZWdhdGV3YXkudjFCFUZsZWV0bm9kZWdhdGV3YXlQcm90b1ABWllnaXRodWIuY29tL2Jsb2NrL3Byb3RvLWZsZWV0L3NlcnZlci9nZW5lcmF0ZWQvZ3JwYy9mbGVldG5vZGVnYXRld2F5L3YxO2ZsZWV0bm9kZWdhdGV3YXl2MaICA0ZYWKoCE0ZsZWV0bm9kZWdhdGV3YXkuVjHKAhNGbGVldG5vZGVnYXRld2F5XFYx4gIfRmxlZXRub2RlZ2F0ZXdheVxWMVxHUEJNZXRhZGF0YeoCFEZsZWV0bm9kZWdhdGV3YXk6OlYxYgZwcm90bzM", + "CipmbGVldG5vZGVnYXRld2F5L3YxL2ZsZWV0bm9kZWdhdGV3YXkucHJvdG8SE2ZsZWV0bm9kZWdhdGV3YXkudjEilwEKD1JlZ2lzdGVyUmVxdWVzdBIkChBlbnJvbGxtZW50X3Rva2VuGAEgASgJQgq6SAdyBRAUGIAEEhgKBG5hbWUYAiABKAlCCrpIB3IFEAEY/wESIAoPaWRlbnRpdHlfcHVia2V5GAMgASgMQge6SAR6AmggEiIKEWVuY3J5cHRpb25fcHVia2V5GAQgASgMQge6SAR6AmggIokBChBSZWdpc3RlclJlc3BvbnNlEhUKDWZsZWV0X25vZGVfaWQYASABKAMSQAoRZW5yb2xsbWVudF9zdGF0dXMYAiABKA4yJS5mbGVldG5vZGVnYXRld2F5LnYxLkVucm9sbG1lbnRTdGF0dXMSHAoUaWRlbnRpdHlfZmluZ2VycHJpbnQYAyABKAkiWgoZQmVnaW5BdXRoSGFuZHNoYWtlUmVxdWVzdBIbCgdhcGlfa2V5GAEgASgJQgq6SAdyBRAUGIAEEiAKD2lkZW50aXR5X3B1YmtleRgCIAEoDEIHukgEegJoICJfChpCZWdpbkF1dGhIYW5kc2hha2VSZXNwb25zZRIRCgljaGFsbGVuZ2UYASABKAwSLgoKZXhwaXJlc19hdBgCIAEoCzIaLmdvb2dsZS5wcm90b2J1Zi5UaW1lc3RhbXAiWAocQ29tcGxldGVBdXRoSGFuZHNoYWtlUmVxdWVzdBIcCgljaGFsbGVuZ2UYASABKAxCCbpIBnoEEBAYQBIaCglzaWduYXR1cmUYAiABKAxCB7pIBHoCaEAiZgodQ29tcGxldGVBdXRoSGFuZHNoYWtlUmVzcG9uc2USFQoNc2Vzc2lvbl90b2tlbhgBIAEoCRIuCgpleHBpcmVzX2F0GAIgASgLMhouZ29vZ2xlLnByb3RvYnVmLlRpbWVzdGFtcCJtChZVcGxvYWRUZWxlbWV0cnlSZXF1ZXN0EhoKB3BheWxvYWQYASABKAxCCbpIBnoEGICAQBI3CgtjYXB0dXJlZF9hdBgCIAEoCzIaLmdvb2dsZS5wcm90b2J1Zi5UaW1lc3RhbXBCBrpIA8gBASIxChdVcGxvYWRUZWxlbWV0cnlSZXNwb25zZRIWCg5hY2NlcHRlZF9jb3VudBgBIAEoAyJqChNVcGxvYWRFdmVudHNSZXF1ZXN0EhoKB3BheWxvYWQYASABKAxCCbpIBnoEGICAQBI3CgtjYXB0dXJlZF9hdBgCIAEoCzIaLmdvb2dsZS5wcm90b2J1Zi5UaW1lc3RhbXBCBrpIA8gBASIuChRVcGxvYWRFdmVudHNSZXNwb25zZRIWCg5hY2NlcHRlZF9jb3VudBgBIAEoAyJNChZVcGxvYWRIZWFydGJlYXRSZXF1ZXN0EjMKB3NlbnRfYXQYASABKAsyGi5nb29nbGUucHJvdG9idWYuVGltZXN0YW1wQga6SAPIAQEiSgoXVXBsb2FkSGVhcnRiZWF0UmVzcG9uc2USLwoLcmVjZWl2ZWRfYXQYASABKAsyGi5nb29nbGUucHJvdG9idWYuVGltZXN0YW1wIuQBChJDb21tYW5kQXJ0aWZhY3RSZWYSHwoLYXJ0aWZhY3RfaWQYASABKAlCCrpIB3IFEAEYgAESSAoHcHVycG9zZRgCIAEoDjIrLmZsZWV0bm9kZWdhdGV3YXkudjEuQ29tbWFuZEFydGlmYWN0UHVycG9zZUIKukgHggEEEAEgABIcCghmaWxlbmFtZRgDIAEoCUIKukgHcgUQARj/ARIbCgpzaXplX2J5dGVzGAQgASgDQge6SAQiAiAAEigKBnNoYTI1NhgFIAEoCUIYukgVchMyDl5bYS1mMC05XXs2NH0kmAFAIpECChtDb21tYW5kQXJ0aWZhY3RVcGxvYWRIZWFkZXISHgoKY29tbWFuZF9pZBgBIAEoCUIKukgHcgUQARiAARJICgdwdXJwb3NlGAIgASgOMisuZmxlZXRub2RlZ2F0ZXdheS52MS5Db21tYW5kQXJ0aWZhY3RQdXJwb3NlQgq6SAeCAQQQASAAEhwKCGZpbGVuYW1lGAMgASgJQgq6SAdyBRABGP8BEhsKCnNpemVfYnl0ZXMYBCABKANCB7pIBCICIAASKAoGc2hhMjU2GAUgASgJQhi6SBVyEzIOXlthLWYwLTldezY0fSSYAUASIwoRZGV2aWNlX2lkZW50aWZpZXIYBiABKAlCCLpIBXIDGP8BIjEKFENvbW1hbmRBcnRpZmFjdENodW5rEhkKBGRhdGEYASABKAxCC7pICHoGEAEYgIBAIq0BChxVcGxvYWRDb21tYW5kQXJ0aWZhY3RSZXF1ZXN0EkIKBmhlYWRlchgBIAEoCzIwLmZsZWV0bm9kZWdhdGV3YXkudjEuQ29tbWFuZEFydGlmYWN0VXBsb2FkSGVhZGVySAASOgoFY2h1bmsYAiABKAsyKS5mbGVldG5vZGVnYXRld2F5LnYxLkNvbW1hbmRBcnRpZmFjdENodW5rSABCDQoEcGFydBIFukgCCAEiYgodVXBsb2FkQ29tbWFuZEFydGlmYWN0UmVzcG9uc2USQQoIYXJ0aWZhY3QYASABKAsyJy5mbGVldG5vZGVnYXRld2F5LnYxLkNvbW1hbmRBcnRpZmFjdFJlZkIGukgDyAEBIqgBCh5Eb3dubG9hZENvbW1hbmRBcnRpZmFjdFJlcXVlc3QSHgoKY29tbWFuZF9pZBgBIAEoCUIKukgHcgUQARiAARJBCghhcnRpZmFjdBgCIAEoCzInLmZsZWV0bm9kZWdhdGV3YXkudjEuQ29tbWFuZEFydGlmYWN0UmVmQga6SAPIAQESIwoRZGV2aWNlX2lkZW50aWZpZXIYAyABKAlCCLpIBXIDGP8BImIKHUNvbW1hbmRBcnRpZmFjdERvd25sb2FkSGVhZGVyEkEKCGFydGlmYWN0GAEgASgLMicuZmxlZXRub2RlZ2F0ZXdheS52MS5Db21tYW5kQXJ0aWZhY3RSZWZCBrpIA8gBASKyAQofRG93bmxvYWRDb21tYW5kQXJ0aWZhY3RSZXNwb25zZRJECgZoZWFkZXIYASABKAsyMi5mbGVldG5vZGVnYXRld2F5LnYxLkNvbW1hbmRBcnRpZmFjdERvd25sb2FkSGVhZGVySAASOgoFY2h1bmsYAiABKAsyKS5mbGVldG5vZGVnYXRld2F5LnYxLkNvbW1hbmRBcnRpZmFjdENodW5rSABCDQoEcGFydBIFukgCCAEiiQEKHlJlcG9ydERpc2NvdmVyZWREZXZpY2VzUmVxdWVzdBJHCgdkZXZpY2VzGAEgAygLMisuZmxlZXRub2RlZ2F0ZXdheS52MS5EaXNjb3ZlcmVkRGV2aWNlUmVwb3J0Qgm6SAaSAQMQgAgSHgoKY29tbWFuZF9pZBgCIAEoCUIKukgHcgUQARiAASKDAwoWRGlzY292ZXJlZERldmljZVJlcG9ydBIlChFkZXZpY2VfaWRlbnRpZmllchgBIAEoCUIKukgHcgUQARj/ARIfCgppcF9hZGRyZXNzGAIgASgJQgu6SAhyBhABGC1wARKGAQoEcG9ydBgDIAEoCUJ4ukh1ugFsCgpwb3J0LnJhbmdlEilwb3J0IG11c3QgYmUgYSBkZWNpbWFsIG51bWJlciBpbiAxLi42NTUzNRozdGhpcy5tYXRjaGVzKCdeWzEtOV1bMC05XSokJykgJiYgaW50KHRoaXMpIDw9IDY1NTM1cgQQARgFEhsKCnVybF9zY2hlbWUYBCABKAlCB7pIBHICGCASHgoLZHJpdmVyX25hbWUYBSABKAlCCbpIBnIEEAEYMhIXCgVtb2RlbBgGIAEoCUIIukgFcgMY/wESHgoMbWFudWZhY3R1cmVyGAcgASgJQgi6SAVyAxj/ARIiChBmaXJtd2FyZV92ZXJzaW9uGAggASgJQgi6SAVyAxj/ASJRCh9SZXBvcnREaXNjb3ZlcmVkRGV2aWNlc1Jlc3BvbnNlEhYKDmFjY2VwdGVkX2NvdW50GAEgASgDEhYKDnJlamVjdGVkX2NvdW50GAIgASgDIvoDChNGbGVldE5vZGVQYWlyUmVzdWx0EiUKEWRldmljZV9pZGVudGlmaWVyGAEgASgJQgq6SAdyBRABGP8BEjEKB291dGNvbWUYAiABKA4yIC5mbGVldG5vZGVnYXRld2F5LnYxLlBhaXJPdXRjb21lEh8KDXNlcmlhbF9udW1iZXIYAyABKAlCCLpIBXIDGP8BEhwKC21hY19hZGRyZXNzGAQgASgJQge6SARyAhhAEhcKBW1vZGVsGAUgASgJQgi6SAVyAxj/ARIeCgxtYW51ZmFjdHVyZXIYBiABKAlCCLpIBXIDGP8BEiIKEGZpcm13YXJlX3ZlcnNpb24YByABKAlCCLpIBXIDGP8BEh8KDWVycm9yX21lc3NhZ2UYCCABKAlCCLpIBXIDGIAgEiQKF2RlZmF1bHRfcGFzc3dvcmRfYWN0aXZlGAwgASgISACIAQESSAoVZW5jcnlwdGVkX2NyZWRlbnRpYWxzGA0gASgLMikuZmxlZXRub2RlZ2F0ZXdheS52MS5FbmNyeXB0ZWRDcmVkZW50aWFsc0IaChhfZGVmYXVsdF9wYXNzd29yZF9hY3RpdmVKBAgJEApKBAgKEAtKBAgLEAxSDXVzZWRfdXNlcm5hbWVSDXVzZWRfcGFzc3dvcmRSEHVzZWRfY3JlZGVudGlhbHMiTgoURW5jcnlwdGVkQ3JlZGVudGlhbHMSGgoIdXNlcm5hbWUYASABKAxCCLpIBXoDGIAgEhoKCHBhc3N3b3JkGAIgASgMQgi6SAV6AxiAICKCAQoaUmVwb3J0UGFpcmVkRGV2aWNlc1JlcXVlc3QSHgoKY29tbWFuZF9pZBgBIAEoCUIKukgHcgUQARiAARJECgdyZXN1bHRzGAIgAygLMiguZmxlZXRub2RlZ2F0ZXdheS52MS5GbGVldE5vZGVQYWlyUmVzdWx0Qgm6SAaSAQMQgAgiTQobUmVwb3J0UGFpcmVkRGV2aWNlc1Jlc3BvbnNlEhYKDmFjY2VwdGVkX2NvdW50GAEgASgDEhYKDnJlamVjdGVkX2NvdW50GAIgASgDIokBChRDb250cm9sU3RyZWFtUmVxdWVzdBIyCgVoZWxsbxgBIAEoCzIhLmZsZWV0bm9kZWdhdGV3YXkudjEuQ29udHJvbEhlbGxvSAASLgoDYWNrGAIgASgLMh8uZmxlZXRub2RlZ2F0ZXdheS52MS5Db250cm9sQWNrSABCDQoEa2luZBIFukgCCAEimAEKFUNvbnRyb2xTdHJlYW1SZXNwb25zZRI4CghhY2NlcHRlZBgBIAEoCzIkLmZsZWV0bm9kZWdhdGV3YXkudjEuQ29udHJvbEFjY2VwdGVkSAASNgoHY29tbWFuZBgCIAEoCzIjLmZsZWV0bm9kZWdhdGV3YXkudjEuQ29udHJvbENvbW1hbmRIAEINCgRraW5kEgW6SAIIASIOCgxDb250cm9sSGVsbG8iQgoPQ29udHJvbEFjY2VwdGVkEi8KC3NlcnZlcl90aW1lGAEgASgLMhouZ29vZ2xlLnByb3RvYnVmLlRpbWVzdGFtcCJMCg5Db250cm9sQ29tbWFuZBIeCgpjb21tYW5kX2lkGAEgASgJQgq6SAdyBRABGIABEhoKB3BheWxvYWQYAiABKAxCCbpIBnoEGICAQCK3AwoZTWluZXJDb25uZWN0aW9uRGVzY3JpcHRvchIlChFkZXZpY2VfaWRlbnRpZmllchgBIAEoCUIKukgHcgUQARj/ARIeCgtkcml2ZXJfbmFtZRgCIAEoCUIJukgGcgQQARgyEh8KCmlwX2FkZHJlc3MYAyABKAlCC7pICHIGEAEYLXABEoYBCgRwb3J0GAQgASgJQni6SHW6AWwKCnBvcnQucmFuZ2USKXBvcnQgbXVzdCBiZSBhIGRlY2ltYWwgbnVtYmVyIGluIDEuLjY1NTM1GjN0aGlzLm1hdGNoZXMoJ15bMS05XVswLTldKiQnKSAmJiBpbnQodGhpcykgPD0gNjU1MzVyBBABGAUSGwoKdXJsX3NjaGVtZRgFIAEoCUIHukgEcgIYIBIfCg1zZXJpYWxfbnVtYmVyGAYgASgJQgi6SAVyAxj/ARIdCgttYWNfYWRkcmVzcxgHIAEoCUIIukgFcgMY/wESJQoTY3JlZGVudGlhbF91c2VybmFtZRgIIAEoDEIIukgFegMYgCASJQoTY3JlZGVudGlhbF9wYXNzd29yZBgJIAEoDEIIukgFegMYgCAi1wgKDE1pbmVyQ29tbWFuZBJGCgZ0YXJnZXQYASABKAsyLi5mbGVldG5vZGVnYXRld2F5LnYxLk1pbmVyQ29ubmVjdGlvbkRlc2NyaXB0b3JCBrpIA8gBARIzCgZyZWJvb3QYAiABKAsyIS5mbGVldG5vZGVnYXRld2F5LnYxLlJlYm9vdEFjdGlvbkgAEj4KDHN0YXJ0X21pbmluZxgDIAEoCzImLmZsZWV0bm9kZWdhdGV3YXkudjEuU3RhcnRNaW5pbmdBY3Rpb25IABI8CgtzdG9wX21pbmluZxgEIAEoCzIlLmZsZWV0bm9kZWdhdGV3YXkudjEuU3RvcE1pbmluZ0FjdGlvbkgAEjgKCWJsaW5rX2xlZBgFIAEoCzIjLmZsZWV0bm9kZWdhdGV3YXkudjEuQmxpbmtMZWRBY3Rpb25IABI1CgdjdXJ0YWlsGAYgASgLMiIuZmxlZXRub2RlZ2F0ZXdheS52MS5DdXJ0YWlsQWN0aW9uSAASOQoJdW5jdXJ0YWlsGAcgASgLMiQuZmxlZXRub2RlZ2F0ZXdheS52MS5VbmN1cnRhaWxBY3Rpb25IABJFChBzZXRfY29vbGluZ19tb2RlGAggASgLMikuZmxlZXRub2RlZ2F0ZXdheS52MS5TZXRDb29saW5nTW9kZUFjdGlvbkgAEkUKEHNldF9wb3dlcl90YXJnZXQYCSABKAsyKS5mbGVldG5vZGVnYXRld2F5LnYxLlNldFBvd2VyVGFyZ2V0QWN0aW9uSAASSwoTdXBkYXRlX21pbmluZ19wb29scxgKIAEoCzIsLmZsZWV0bm9kZWdhdGV3YXkudjEuVXBkYXRlTWluaW5nUG9vbHNBY3Rpb25IABJFChBnZXRfbWluaW5nX3Bvb2xzGAsgASgLMikuZmxlZXRub2RlZ2F0ZXdheS52MS5HZXRNaW5pbmdQb29sc0FjdGlvbkgAEjoKCmdldF9lcnJvcnMYDCABKAsyJC5mbGVldG5vZGVnYXRld2F5LnYxLkdldEVycm9yc0FjdGlvbkgAEk8KFXVwZGF0ZV9taW5lcl9wYXNzd29yZBgNIAEoCzIuLmZsZWV0bm9kZWdhdGV3YXkudjEuVXBkYXRlTWluZXJQYXNzd29yZEFjdGlvbkgAEkAKDWRvd25sb2FkX2xvZ3MYDiABKAsyJy5mbGVldG5vZGVnYXRld2F5LnYxLkRvd25sb2FkTG9nc0FjdGlvbkgAEkQKD2Zpcm13YXJlX3VwZGF0ZRgPIAEoCzIpLmZsZWV0bm9kZWdhdGV3YXkudjEuRmlybXdhcmVVcGRhdGVBY3Rpb25IABJYChpnZXRfZmlybXdhcmVfdXBkYXRlX3N0YXR1cxgQIAEoCzIyLmZsZWV0bm9kZWdhdGV3YXkudjEuR2V0RmlybXdhcmVVcGRhdGVTdGF0dXNBY3Rpb25IAEIPCgZhY3Rpb24SBbpIAggBIg4KDFJlYm9vdEFjdGlvbiITChFTdGFydE1pbmluZ0FjdGlvbiISChBTdG9wTWluaW5nQWN0aW9uIhAKDkJsaW5rTGVkQWN0aW9uIhEKD1VuY3VydGFpbEFjdGlvbiIWChRHZXRNaW5pbmdQb29sc0FjdGlvbiIRCg9HZXRFcnJvcnNBY3Rpb24iHwodR2V0RmlybXdhcmVVcGRhdGVTdGF0dXNBY3Rpb24iOAoSRG93bmxvYWRMb2dzQWN0aW9uEiIKDmJhdGNoX2xvZ191dWlkGAEgASgJQgq6SAdyBRABGIABIpoCChROb2RlRW5jcnlwdGVkUGF5bG9hZBKmAQoJYWxnb3JpdGhtGAEgASgJQpIBukiOAboBhAEKIG5vZGVfZW5jcnlwdGVkX3BheWxvYWQuYWxnb3JpdGhtEjNhbGdvcml0aG0gbXVzdCBiZSB4MjU1MTktaGtkZi1zaGEyNTYtYWVzLTI1Ni1nY20tdjEaK3RoaXMgPT0gJ3gyNTUxOS1oa2RmLXNoYTI1Ni1hZXMtMjU2LWdjbS12MSdyBBABGEASIQoQZXBoZW1lcmFsX3B1YmtleRgCIAEoDEIHukgEegJoIBIWCgVub25jZRgDIAEoDEIHukgEegJoDBIeCgpjaXBoZXJ0ZXh0GAQgASgMQgq6SAd6BRARGIBAInEKGVVwZGF0ZU1pbmVyUGFzc3dvcmRBY3Rpb24SVAoZZW5jcnlwdGVkX3Bhc3N3b3JkX3VwZGF0ZRgBIAEoCzIpLmZsZWV0bm9kZWdhdGV3YXkudjEuTm9kZUVuY3J5cHRlZFBheWxvYWRCBrpIA8gBASJtChlVcGRhdGVNaW5lclBhc3N3b3JkUmVzdWx0ElAKFWVuY3J5cHRlZF9jcmVkZW50aWFscxgBIAEoCzIpLmZsZWV0bm9kZWdhdGV3YXkudjEuRW5jcnlwdGVkQ3JlZGVudGlhbHNCBrpIA8gBASJZChRGaXJtd2FyZVVwZGF0ZUFjdGlvbhJBCghhcnRpZmFjdBgBIAEoCzInLmZsZWV0bm9kZWdhdGV3YXkudjEuQ29tbWFuZEFydGlmYWN0UmVmQga6SAPIAQEiQAoNQ3VydGFpbEFjdGlvbhIvCgVsZXZlbBgBIAEoDjIgLmN1cnRhaWxtZW50LnYxLkN1cnRhaWxtZW50TGV2ZWwiPAoUU2V0Q29vbGluZ01vZGVBY3Rpb24SJAoEbW9kZRgBIAEoDjIWLmNvbW1vbi52MS5Db29saW5nTW9kZSJSChRTZXRQb3dlclRhcmdldEFjdGlvbhI6ChBwZXJmb3JtYW5jZV9tb2RlGAEgASgOMiAubWluZXJjb21tYW5kLnYxLlBlcmZvcm1hbmNlTW9kZSKFAwoQTWluaW5nUG9vbENvbmZpZxIbCghwcmlvcml0eRgBIAEoBUIJukgGGgQYAigAErcCCgN1cmwYAiABKAlCqQK6SKUCcqICEAwYgAIymgJeKHN0cmF0dW1cKyh0Y3B8c3NsfHdzKTpcL1wvKChbYS16QS1aMC05XVthLXpBLVowLTkuLV0qW2EtekEtWjAtOV1cLlthLXpBLVpdezIsfSl8KFxkezEsM31cLil7M31cZHsxLDN9fFxbKFswLTlhLWZBLUY6XSspXF0pKDpcZHsxLDV9KT98c3RyYXR1bTJcK3RjcDpcL1wvKChbYS16QS1aMC05XVthLXpBLVowLTkuLV0qW2EtekEtWjAtOV1cLlthLXpBLVpdezIsfSl8KFxkezEsM31cLil7M31cZHsxLDN9fFxbKFswLTlhLWZBLUY6XSspXF0pOlxkezEsNX1cL1tBLVphLXowLTlfK1wvPTouLV0rKSQSGgoIdXNlcm5hbWUYAyABKAlCCLpIBXIDGIAEIlsKF1VwZGF0ZU1pbmluZ1Bvb2xzQWN0aW9uEkAKBXBvb2xzGAEgAygLMiUuZmxlZXRub2RlZ2F0ZXdheS52MS5NaW5pbmdQb29sQ29uZmlnQgq6SAeSAQQIARADIlYKFEdldE1pbmluZ1Bvb2xzUmVzdWx0Ej4KBXBvb2xzGAEgAygLMiUuZmxlZXRub2RlZ2F0ZXdheS52MS5NaW5pbmdQb29sQ29uZmlnQgi6SAWSAQIQAyKAAQoaRmlybXdhcmVVcGRhdGVTdGF0dXNSZXN1bHQSFgoFc3RhdGUYASABKAlCB7pIBHICGEASFQoIcHJvZ3Jlc3MYAiABKAVIAIgBARIcCgVlcnJvchgDIAEoCUIIukgFcgMYgCBIAYgBAUILCglfcHJvZ3Jlc3NCCAoGX2Vycm9yIsUFChBNaW5lckVycm9yUmVwb3J0EjQKC21pbmVyX2Vycm9yGAEgASgOMhUuZXJyb3JzLnYxLk1pbmVyRXJyb3JCCLpIBYIBAhABEh8KDWNhdXNlX3N1bW1hcnkYAiABKAlCCLpIBXIDGIAgEiQKEnJlY29tbWVuZGVkX2FjdGlvbhgDIAEoCUIIukgFcgMYgCASLwoIc2V2ZXJpdHkYBCABKA4yEy5lcnJvcnMudjEuU2V2ZXJpdHlCCLpIBYIBAhABEjEKDWZpcnN0X3NlZW5fYXQYBSABKAsyGi5nb29nbGUucHJvdG9idWYuVGltZXN0YW1wEjAKDGxhc3Rfc2Vlbl9hdBgGIAEoCzIaLmdvb2dsZS5wcm90b2J1Zi5UaW1lc3RhbXASLQoJY2xvc2VkX2F0GAcgASgLMhouZ29vZ2xlLnByb3RvYnVmLlRpbWVzdGFtcBJwChF2ZW5kb3JfYXR0cmlidXRlcxgIIAMoCzI7LmZsZWV0bm9kZWdhdGV3YXkudjEuTWluZXJFcnJvclJlcG9ydC5WZW5kb3JBdHRyaWJ1dGVzRW50cnlCGLpIFZoBEhAgIgdyBRABGIABKgVyAxiACBIdCglkZXZpY2VfaWQYCSABKAlCCrpIB3IFEAEY/wESIwoMY29tcG9uZW50X2lkGAogASgJQgi6SAVyAxj/AUgAiAEBEhgKBmltcGFjdBgLIAEoCUIIukgFcgMYgCASGQoHc3VtbWFyeRgMIAEoCUIIukgFcgMYgCASOgoOY29tcG9uZW50X3R5cGUYDSABKA4yGC5lcnJvcnMudjEuQ29tcG9uZW50VHlwZUIIukgFggECEAEaNwoVVmVuZG9yQXR0cmlidXRlc0VudHJ5EgsKA2tleRgBIAEoCRINCgV2YWx1ZRgCIAEoCToCOAFCDwoNX2NvbXBvbmVudF9pZCKjAQoPR2V0RXJyb3JzUmVzdWx0Eh0KCWRldmljZV9pZBgBIAEoCUIKukgHcgUQARj/ARJACgZlcnJvcnMYAiADKAsyJS5mbGVldG5vZGVnYXRld2F5LnYxLk1pbmVyRXJyb3JSZXBvcnRCCbpIBpIBAxCABBIRCgl0cnVuY2F0ZWQYAyABKAgSHAoUb21pdHRlZF9yZXBvcnRfY291bnQYBCABKA0i/QEKDEFnZW50Q29tbWFuZBIvCghkaXNjb3ZlchgBIAEoCzIbLnBhaXJpbmcudjEuRGlzY292ZXJSZXF1ZXN0SAASMAoEcGFpchgCIAEoCzIgLnBhaXJpbmcudjEuRmxlZXROb2RlUGFpclJlcXVlc3RIABI6Cg1taW5lcl9jb21tYW5kGAMgASgLMiEuZmxlZXRub2RlZ2F0ZXdheS52MS5NaW5lckNvbW1hbmRIABI8Cgl0ZWxlbWV0cnkYBCABKAsyJy50ZWxlbWV0cnkudjEuRmxlZXROb2RlVGVsZW1ldHJ5UmVxdWVzdEgAQhAKB2NvbW1hbmQSBbpIAggBIqgBCgpDb250cm9sQWNrEh4KCmNvbW1hbmRfaWQYASABKAlCCrpIB3IFEAEYgAESEQoJc3VjY2VlZGVkGAIgASgIEh8KDWVycm9yX21lc3NhZ2UYAyABKAlCCLpIBXIDGIAgEioKBGNvZGUYBCABKA4yHC5mbGVldG5vZGVnYXRld2F5LnYxLkFja0NvZGUSGgoHcGF5bG9hZBgFIAEoDEIJukgGegQYgIBAKpQBChBFbnJvbGxtZW50U3RhdHVzEiEKHUVOUk9MTE1FTlRfU1RBVFVTX1VOU1BFQ0lGSUVEEAASHQoZRU5ST0xMTUVOVF9TVEFUVVNfUEVORElORxABEh8KG0VOUk9MTE1FTlRfU1RBVFVTX0NPTkZJUk1FRBACEh0KGUVOUk9MTE1FTlRfU1RBVFVTX1JFVk9LRUQQAyqaAQoWQ29tbWFuZEFydGlmYWN0UHVycG9zZRIoCiRDT01NQU5EX0FSVElGQUNUX1BVUlBPU0VfVU5TUEVDSUZJRUQQABInCiNDT01NQU5EX0FSVElGQUNUX1BVUlBPU0VfTUlORVJfTE9HUxABEi0KKUNPTU1BTkRfQVJUSUZBQ1RfUFVSUE9TRV9GSVJNV0FSRV9QQVlMT0FEEAIqmAEKC1BhaXJPdXRjb21lEhwKGFBBSVJfT1VUQ09NRV9VTlNQRUNJRklFRBAAEhcKE1BBSVJfT1VUQ09NRV9QQUlSRUQQARIcChhQQUlSX09VVENPTUVfQVVUSF9ORUVERUQQAhIcChhQQUlSX09VVENPTUVfQVVUSF9GQUlMRUQQAxIWChJQQUlSX09VVENPTUVfRVJST1IQBCq0AgoHQWNrQ29kZRIYChRBQ0tfQ09ERV9VTlNQRUNJRklFRBAAEg8KC0FDS19DT0RFX09LEAESFAoQQUNLX0NPREVfUEFSVElBTBACEhgKFEFDS19DT0RFX0JBRF9SRVFVRVNUEAMSHAoYQUNLX0NPREVfQUdFTlRfSU5DQVBBQkxFEAQSGAoUQUNLX0NPREVfU0NBTl9GQUlMRUQQBRIaChZBQ0tfQ09ERV9SRVBPUlRfRkFJTEVEEAYSFQoRQUNLX0NPREVfSU5URVJOQUwQBxIRCg1BQ0tfQ09ERV9CVVNZEAgSHAoYQUNLX0NPREVfVU5BVVRIRU5USUNBVEVEEAkSGgoWQUNLX0NPREVfVU5JTVBMRU1FTlRFRBAKEhYKEkFDS19DT0RFX0ZPUkJJRERFThALMqcKChdGbGVldE5vZGVHYXRld2F5U2VydmljZRJXCghSZWdpc3RlchIkLmZsZWV0bm9kZWdhdGV3YXkudjEuUmVnaXN0ZXJSZXF1ZXN0GiUuZmxlZXRub2RlZ2F0ZXdheS52MS5SZWdpc3RlclJlc3BvbnNlEnUKEkJlZ2luQXV0aEhhbmRzaGFrZRIuLmZsZWV0bm9kZWdhdGV3YXkudjEuQmVnaW5BdXRoSGFuZHNoYWtlUmVxdWVzdBovLmZsZWV0bm9kZWdhdGV3YXkudjEuQmVnaW5BdXRoSGFuZHNoYWtlUmVzcG9uc2USfgoVQ29tcGxldGVBdXRoSGFuZHNoYWtlEjEuZmxlZXRub2RlZ2F0ZXdheS52MS5Db21wbGV0ZUF1dGhIYW5kc2hha2VSZXF1ZXN0GjIuZmxlZXRub2RlZ2F0ZXdheS52MS5Db21wbGV0ZUF1dGhIYW5kc2hha2VSZXNwb25zZRJuCg9VcGxvYWRUZWxlbWV0cnkSKy5mbGVldG5vZGVnYXRld2F5LnYxLlVwbG9hZFRlbGVtZXRyeVJlcXVlc3QaLC5mbGVldG5vZGVnYXRld2F5LnYxLlVwbG9hZFRlbGVtZXRyeVJlc3BvbnNlKAESZQoMVXBsb2FkRXZlbnRzEiguZmxlZXRub2RlZ2F0ZXdheS52MS5VcGxvYWRFdmVudHNSZXF1ZXN0GikuZmxlZXRub2RlZ2F0ZXdheS52MS5VcGxvYWRFdmVudHNSZXNwb25zZSgBEmwKD1VwbG9hZEhlYXJ0YmVhdBIrLmZsZWV0bm9kZWdhdGV3YXkudjEuVXBsb2FkSGVhcnRiZWF0UmVxdWVzdBosLmZsZWV0bm9kZWdhdGV3YXkudjEuVXBsb2FkSGVhcnRiZWF0UmVzcG9uc2USgAEKFVVwbG9hZENvbW1hbmRBcnRpZmFjdBIxLmZsZWV0bm9kZWdhdGV3YXkudjEuVXBsb2FkQ29tbWFuZEFydGlmYWN0UmVxdWVzdBoyLmZsZWV0bm9kZWdhdGV3YXkudjEuVXBsb2FkQ29tbWFuZEFydGlmYWN0UmVzcG9uc2UoARKGAQoXRG93bmxvYWRDb21tYW5kQXJ0aWZhY3QSMy5mbGVldG5vZGVnYXRld2F5LnYxLkRvd25sb2FkQ29tbWFuZEFydGlmYWN0UmVxdWVzdBo0LmZsZWV0bm9kZWdhdGV3YXkudjEuRG93bmxvYWRDb21tYW5kQXJ0aWZhY3RSZXNwb25zZTABEoQBChdSZXBvcnREaXNjb3ZlcmVkRGV2aWNlcxIzLmZsZWV0bm9kZWdhdGV3YXkudjEuUmVwb3J0RGlzY292ZXJlZERldmljZXNSZXF1ZXN0GjQuZmxlZXRub2RlZ2F0ZXdheS52MS5SZXBvcnREaXNjb3ZlcmVkRGV2aWNlc1Jlc3BvbnNlEngKE1JlcG9ydFBhaXJlZERldmljZXMSLy5mbGVldG5vZGVnYXRld2F5LnYxLlJlcG9ydFBhaXJlZERldmljZXNSZXF1ZXN0GjAuZmxlZXRub2RlZ2F0ZXdheS52MS5SZXBvcnRQYWlyZWREZXZpY2VzUmVzcG9uc2USagoNQ29udHJvbFN0cmVhbRIpLmZsZWV0bm9kZWdhdGV3YXkudjEuQ29udHJvbFN0cmVhbVJlcXVlc3QaKi5mbGVldG5vZGVnYXRld2F5LnYxLkNvbnRyb2xTdHJlYW1SZXNwb25zZSgBMAFC+AEKF2NvbS5mbGVldG5vZGVnYXRld2F5LnYxQhVGbGVldG5vZGVnYXRld2F5UHJvdG9QAVpZZ2l0aHViLmNvbS9ibG9jay9wcm90by1mbGVldC9zZXJ2ZXIvZ2VuZXJhdGVkL2dycGMvZmxlZXRub2RlZ2F0ZXdheS92MTtmbGVldG5vZGVnYXRld2F5djGiAgNGWFiqAhNGbGVldG5vZGVnYXRld2F5LlYxygITRmxlZXRub2RlZ2F0ZXdheVxWMeICH0ZsZWV0bm9kZWdhdGV3YXlcVjFcR1BCTWV0YWRhdGHqAhRGbGVldG5vZGVnYXRld2F5OjpWMWIGcHJvdG8z", [ file_buf_validate_validate, file_common_v1_cooling, @@ -1104,6 +1104,20 @@ export type MinerCommand = Message<"fleetnodegateway.v1.MinerCommand"> & { value: DownloadLogsAction; case: "downloadLogs"; } + | { + /** + * @generated from field: fleetnodegateway.v1.FirmwareUpdateAction firmware_update = 15; + */ + value: FirmwareUpdateAction; + case: "firmwareUpdate"; + } + | { + /** + * @generated from field: fleetnodegateway.v1.GetFirmwareUpdateStatusAction get_firmware_update_status = 16; + */ + value: GetFirmwareUpdateStatusAction; + case: "getFirmwareUpdateStatus"; + } | { case: undefined; value?: undefined }; }; @@ -1206,6 +1220,19 @@ export const GetErrorsActionSchema: GenMessage = /*@__PURE__*/ messageDesc(file_fleetnodegateway_v1_fleetnodegateway, 40); +/** + * @generated from message fleetnodegateway.v1.GetFirmwareUpdateStatusAction + */ +export type GetFirmwareUpdateStatusAction = Message<"fleetnodegateway.v1.GetFirmwareUpdateStatusAction"> & {}; + +/** + * Describes the message fleetnodegateway.v1.GetFirmwareUpdateStatusAction. + * Use `create(GetFirmwareUpdateStatusActionSchema)` to create a new message. + */ +export const GetFirmwareUpdateStatusActionSchema: GenMessage = + /*@__PURE__*/ + messageDesc(file_fleetnodegateway_v1_fleetnodegateway, 41); + /** * @generated from message fleetnodegateway.v1.DownloadLogsAction */ @@ -1222,7 +1249,7 @@ export type DownloadLogsAction = Message<"fleetnodegateway.v1.DownloadLogsAction */ export const DownloadLogsActionSchema: GenMessage = /*@__PURE__*/ - messageDesc(file_fleetnodegateway_v1_fleetnodegateway, 41); + messageDesc(file_fleetnodegateway_v1_fleetnodegateway, 42); /** * @generated from message fleetnodegateway.v1.NodeEncryptedPayload @@ -1255,7 +1282,7 @@ export type NodeEncryptedPayload = Message<"fleetnodegateway.v1.NodeEncryptedPay */ export const NodeEncryptedPayloadSchema: GenMessage = /*@__PURE__*/ - messageDesc(file_fleetnodegateway_v1_fleetnodegateway, 42); + messageDesc(file_fleetnodegateway_v1_fleetnodegateway, 43); /** * @generated from message fleetnodegateway.v1.UpdateMinerPasswordAction @@ -1273,7 +1300,7 @@ export type UpdateMinerPasswordAction = Message<"fleetnodegateway.v1.UpdateMiner */ export const UpdateMinerPasswordActionSchema: GenMessage = /*@__PURE__*/ - messageDesc(file_fleetnodegateway_v1_fleetnodegateway, 43); + messageDesc(file_fleetnodegateway_v1_fleetnodegateway, 44); /** * @generated from message fleetnodegateway.v1.UpdateMinerPasswordResult @@ -1291,7 +1318,25 @@ export type UpdateMinerPasswordResult = Message<"fleetnodegateway.v1.UpdateMiner */ export const UpdateMinerPasswordResultSchema: GenMessage = /*@__PURE__*/ - messageDesc(file_fleetnodegateway_v1_fleetnodegateway, 44); + messageDesc(file_fleetnodegateway_v1_fleetnodegateway, 45); + +/** + * @generated from message fleetnodegateway.v1.FirmwareUpdateAction + */ +export type FirmwareUpdateAction = Message<"fleetnodegateway.v1.FirmwareUpdateAction"> & { + /** + * @generated from field: fleetnodegateway.v1.CommandArtifactRef artifact = 1; + */ + artifact?: CommandArtifactRef | undefined; +}; + +/** + * Describes the message fleetnodegateway.v1.FirmwareUpdateAction. + * Use `create(FirmwareUpdateActionSchema)` to create a new message. + */ +export const FirmwareUpdateActionSchema: GenMessage = + /*@__PURE__*/ + messageDesc(file_fleetnodegateway_v1_fleetnodegateway, 46); /** * @generated from message fleetnodegateway.v1.CurtailAction @@ -1309,7 +1354,7 @@ export type CurtailAction = Message<"fleetnodegateway.v1.CurtailAction"> & { */ export const CurtailActionSchema: GenMessage = /*@__PURE__*/ - messageDesc(file_fleetnodegateway_v1_fleetnodegateway, 45); + messageDesc(file_fleetnodegateway_v1_fleetnodegateway, 47); /** * @generated from message fleetnodegateway.v1.SetCoolingModeAction @@ -1327,7 +1372,7 @@ export type SetCoolingModeAction = Message<"fleetnodegateway.v1.SetCoolingModeAc */ export const SetCoolingModeActionSchema: GenMessage = /*@__PURE__*/ - messageDesc(file_fleetnodegateway_v1_fleetnodegateway, 46); + messageDesc(file_fleetnodegateway_v1_fleetnodegateway, 48); /** * @generated from message fleetnodegateway.v1.SetPowerTargetAction @@ -1345,7 +1390,7 @@ export type SetPowerTargetAction = Message<"fleetnodegateway.v1.SetPowerTargetAc */ export const SetPowerTargetActionSchema: GenMessage = /*@__PURE__*/ - messageDesc(file_fleetnodegateway_v1_fleetnodegateway, 47); + messageDesc(file_fleetnodegateway_v1_fleetnodegateway, 49); /** * @generated from message fleetnodegateway.v1.MiningPoolConfig @@ -1373,7 +1418,7 @@ export type MiningPoolConfig = Message<"fleetnodegateway.v1.MiningPoolConfig"> & */ export const MiningPoolConfigSchema: GenMessage = /*@__PURE__*/ - messageDesc(file_fleetnodegateway_v1_fleetnodegateway, 48); + messageDesc(file_fleetnodegateway_v1_fleetnodegateway, 50); /** * @generated from message fleetnodegateway.v1.UpdateMiningPoolsAction @@ -1391,7 +1436,7 @@ export type UpdateMiningPoolsAction = Message<"fleetnodegateway.v1.UpdateMiningP */ export const UpdateMiningPoolsActionSchema: GenMessage = /*@__PURE__*/ - messageDesc(file_fleetnodegateway_v1_fleetnodegateway, 49); + messageDesc(file_fleetnodegateway_v1_fleetnodegateway, 51); /** * @generated from message fleetnodegateway.v1.GetMiningPoolsResult @@ -1409,7 +1454,35 @@ export type GetMiningPoolsResult = Message<"fleetnodegateway.v1.GetMiningPoolsRe */ export const GetMiningPoolsResultSchema: GenMessage = /*@__PURE__*/ - messageDesc(file_fleetnodegateway_v1_fleetnodegateway, 50); + messageDesc(file_fleetnodegateway_v1_fleetnodegateway, 52); + +/** + * @generated from message fleetnodegateway.v1.FirmwareUpdateStatusResult + */ +export type FirmwareUpdateStatusResult = Message<"fleetnodegateway.v1.FirmwareUpdateStatusResult"> & { + /** + * @generated from field: string state = 1; + */ + state: string; + + /** + * @generated from field: optional int32 progress = 2; + */ + progress?: number | undefined; + + /** + * @generated from field: optional string error = 3; + */ + error?: string | undefined; +}; + +/** + * Describes the message fleetnodegateway.v1.FirmwareUpdateStatusResult. + * Use `create(FirmwareUpdateStatusResultSchema)` to create a new message. + */ +export const FirmwareUpdateStatusResultSchema: GenMessage = + /*@__PURE__*/ + messageDesc(file_fleetnodegateway_v1_fleetnodegateway, 53); /** * @generated from message fleetnodegateway.v1.MinerErrorReport @@ -1487,7 +1560,7 @@ export type MinerErrorReport = Message<"fleetnodegateway.v1.MinerErrorReport"> & */ export const MinerErrorReportSchema: GenMessage = /*@__PURE__*/ - messageDesc(file_fleetnodegateway_v1_fleetnodegateway, 51); + messageDesc(file_fleetnodegateway_v1_fleetnodegateway, 54); /** * @generated from message fleetnodegateway.v1.GetErrorsResult @@ -1520,7 +1593,7 @@ export type GetErrorsResult = Message<"fleetnodegateway.v1.GetErrorsResult"> & { */ export const GetErrorsResultSchema: GenMessage = /*@__PURE__*/ - messageDesc(file_fleetnodegateway_v1_fleetnodegateway, 52); + messageDesc(file_fleetnodegateway_v1_fleetnodegateway, 55); /** * AgentCommand is the typed envelope marshaled into ControlCommand.payload so a @@ -1578,7 +1651,7 @@ export type AgentCommand = Message<"fleetnodegateway.v1.AgentCommand"> & { */ export const AgentCommandSchema: GenMessage = /*@__PURE__*/ - messageDesc(file_fleetnodegateway_v1_fleetnodegateway, 53); + messageDesc(file_fleetnodegateway_v1_fleetnodegateway, 56); /** * @generated from message fleetnodegateway.v1.ControlAck @@ -1618,7 +1691,7 @@ export type ControlAck = Message<"fleetnodegateway.v1.ControlAck"> & { */ export const ControlAckSchema: GenMessage = /*@__PURE__*/ - messageDesc(file_fleetnodegateway_v1_fleetnodegateway, 54); + messageDesc(file_fleetnodegateway_v1_fleetnodegateway, 57); /** * @generated from enum fleetnodegateway.v1.EnrollmentStatus diff --git a/proto/fleetnodegateway/v1/fleetnodegateway.proto b/proto/fleetnodegateway/v1/fleetnodegateway.proto index 4e2ac372a..0250d3586 100644 --- a/proto/fleetnodegateway/v1/fleetnodegateway.proto +++ b/proto/fleetnodegateway/v1/fleetnodegateway.proto @@ -330,6 +330,8 @@ message MinerCommand { GetErrorsAction get_errors = 12; UpdateMinerPasswordAction update_miner_password = 13; DownloadLogsAction download_logs = 14; + FirmwareUpdateAction firmware_update = 15; + GetFirmwareUpdateStatusAction get_firmware_update_status = 16; } } @@ -340,6 +342,7 @@ message BlinkLedAction {} message UncurtailAction {} message GetMiningPoolsAction {} message GetErrorsAction {} +message GetFirmwareUpdateStatusAction {} message DownloadLogsAction { string batch_log_uuid = 1 [(buf.validate.field).string = {min_len: 1, max_len: 128}]; @@ -367,6 +370,10 @@ message UpdateMinerPasswordResult { EncryptedCredentials encrypted_credentials = 1 [(buf.validate.field).required = true]; } +message FirmwareUpdateAction { + CommandArtifactRef artifact = 1 [(buf.validate.field).required = true]; +} + message CurtailAction { curtailment.v1.CurtailmentLevel level = 1; } @@ -399,6 +406,12 @@ message GetMiningPoolsResult { repeated MiningPoolConfig pools = 1 [(buf.validate.field).repeated.max_items = 3]; } +message FirmwareUpdateStatusResult { + string state = 1 [(buf.validate.field).string.max_len = 64]; + optional int32 progress = 2; + optional string error = 3 [(buf.validate.field).string.max_len = 4096]; +} + message MinerErrorReport { errors.v1.MinerError miner_error = 1 [(buf.validate.field).enum.defined_only = true]; string cause_summary = 2 [(buf.validate.field).string.max_len = 4096]; diff --git a/server/cmd/fleetnode/minercommand.go b/server/cmd/fleetnode/minercommand.go index 378f1634a..7095b333a 100644 --- a/server/cmd/fleetnode/minercommand.go +++ b/server/cmd/fleetnode/minercommand.go @@ -7,11 +7,17 @@ import ( "encoding/hex" "errors" "fmt" + "io" "log/slog" "net/netip" + "os" + "path/filepath" + "sync" + "syscall" "time" "buf.build/go/protovalidate" + "connectrpc.com/connect" "google.golang.org/grpc/codes" grpcstatus "google.golang.org/grpc/status" "google.golang.org/protobuf/proto" @@ -32,10 +38,16 @@ import ( sdk "github.com/block/proto-fleet/server/sdk/v1" ) -// minerCommandTimeout bounds a single miner command. It must stay below the server's -// WorkerExecutionTimeout (default 30s) minus ack slack, or a slow command can be -// retried while the node still runs it (duplicate reboot/curtail). var so tests shrink it. -var minerCommandTimeout = 25 * time.Second +var ( + // minerCommandTimeout bounds a short miner command. It must stay below the server's + // WorkerExecutionTimeout (default 30s) minus ack slack, or a slow command can be + // retried while the node still runs it (duplicate reboot/curtail). var so tests shrink it. + minerCommandTimeout = 25 * time.Second + // firmwareMinerCommandTimeout stays below the server-side firmware execution + // budget (default 15m) so fleetd has time to poll install status and reboot + // after the node finishes the artifact download and device upload. + firmwareMinerCommandTimeout = 10 * time.Minute +) const ( supportedMiningPoolSlots = 3 @@ -43,8 +55,17 @@ const ( maxGetErrorsReports = 512 minerLogsArtifactFilename = "miner-logs.csv" commandArtifactChunkSize = 1 << 20 + + firmwareArtifactTempDirName = "firmware-artifacts" + firmwareArtifactTempDirPrefix = "download-" + maxFleetNodeFirmwareArtifactSizeBytes = 500 * 1024 * 1024 + maxConcurrentFirmwareDownloads = 1 + maxActiveFirmwareArtifactBytes = maxFleetNodeFirmwareArtifactSizeBytes + minFirmwareTempFreeBytes = 64 * 1024 * 1024 ) +var firmwareDownloadCapacity = newFirmwareDownloadLimiter(maxConcurrentFirmwareDownloads, maxActiveFirmwareArtifactBytes) + // driverGetter is the plugin-manager seam the executor needs; *plugins.Manager satisfies it. type driverGetter interface { GetDriverByDriverName(driverName string) (sdk.Driver, error) @@ -108,7 +129,7 @@ func (r *RunCmd) handleMinerCommand(ctx context.Context, client gatewayClient, s } bundle = passwordUpdate.secretBundle(target, bundle) - cmdCtx, cancel := context.WithTimeout(ctx, minerCommandTimeout) + cmdCtx, cancel := context.WithTimeout(ctx, minerCommandActionTimeout(mc)) defer cancel() result, err := driver.NewDevice(cmdCtx, target.GetDeviceIdentifier(), sdk.DeviceInfo{ @@ -144,7 +165,7 @@ func (r *RunCmd) handleMinerCommand(ctx context.Context, client gatewayClient, s if passwordUpdate != nil { payload, err = passwordUpdate.run(cmdCtx, dev, bundle, r.minerSecrets) } else { - payload, err = runMinerAction(cmdCtx, client, commandID, caps, dev, mc) + payload, err = runMinerAction(cmdCtx, client, commandID, r.firmwareTempRootForDownloads(), caps, dev, mc) } if err != nil { code, msg := classifyMinerActionError("execute command", mc, err) @@ -212,6 +233,13 @@ func (u *passwordUpdateCommand) run(ctx context.Context, dev sdk.Device, bundle return payload, nil } +func minerCommandActionTimeout(mc *pb.MinerCommand) time.Duration { + if mc.GetFirmwareUpdate() != nil { + return firmwareMinerCommandTimeout + } + return minerCommandTimeout +} + // validateDialTarget rejects descriptors the node should never dial: a non-IP, public, // or link-local address, or a scheme the drivers can't dial. Loopback is allowed for the // dev virtual driver; mirrors the discovery path's private-address policy. @@ -238,7 +266,14 @@ func commandCapabilities(ctx context.Context, driver sdk.Driver, mc *pb.MinerCom return caps, err } -func runMinerAction(ctx context.Context, client gatewayClient, commandID string, caps sdk.Capabilities, dev sdk.Device, mc *pb.MinerCommand) ([]byte, error) { +func (r *RunCmd) firmwareTempRootForDownloads() string { + if r.firmwareTempRoot != "" { + return r.firmwareTempRoot + } + return filepath.Join(os.TempDir(), "proto-fleet-firmware") +} + +func runMinerAction(ctx context.Context, client gatewayClient, commandID, firmwareTempRoot string, caps sdk.Capabilities, dev sdk.Device, mc *pb.MinerCommand) ([]byte, error) { switch a := mc.GetAction().(type) { case *pb.MinerCommand_Reboot: return nil, dev.Reboot(ctx) @@ -310,6 +345,10 @@ func runMinerAction(ctx context.Context, client gatewayClient, commandID string, return nil, cmdErr(pb.AckCode_ACK_CODE_PARTIAL, "uploaded partial miner log data; retry after partial log pagination is supported") } return nil, nil + case *pb.MinerCommand_FirmwareUpdate: + return nil, runFirmwareUpdateAction(ctx, client, commandID, mc.GetTarget().GetDeviceIdentifier(), firmwareTempRoot, dev, a.FirmwareUpdate.GetArtifact()) + case *pb.MinerCommand_GetFirmwareUpdateStatus: + return getFirmwareUpdateStatusResultPayload(ctx, dev) default: return nil, cmdErr(pb.AckCode_ACK_CODE_BAD_REQUEST, "unrecognized miner command action") } @@ -444,6 +483,241 @@ func updateMinerPasswordResultPayload(bundle sdk.SecretBundle, newPassword strin return payload, nil } +func runFirmwareUpdateAction(ctx context.Context, client gatewayClient, commandID, deviceIdentifier, firmwareTempRoot string, dev sdk.Device, ref *pb.CommandArtifactRef) error { + if ref == nil { + return cmdErr(pb.AckCode_ACK_CODE_BAD_REQUEST, "firmware artifact is required") + } + if ref.GetPurpose() != pb.CommandArtifactPurpose_COMMAND_ARTIFACT_PURPOSE_FIRMWARE_PAYLOAD { + return cmdErr(pb.AckCode_ACK_CODE_BAD_REQUEST, "firmware artifact has wrong purpose: %s", ref.GetPurpose()) + } + if ref.GetSizeBytes() <= 0 { + return cmdErr(pb.AckCode_ACK_CODE_BAD_REQUEST, "firmware artifact size is required") + } + if ref.GetSizeBytes() > maxFleetNodeFirmwareArtifactSizeBytes { + return cmdErr(pb.AckCode_ACK_CODE_BAD_REQUEST, "firmware artifact size %d exceeds fleet node limit %d", ref.GetSizeBytes(), maxFleetNodeFirmwareArtifactSizeBytes) + } + if client == nil { + return cmdErr(pb.AckCode_ACK_CODE_AGENT_INCAPABLE, "fleet node gateway client is unavailable") + } + releaseDownload, ok := firmwareDownloadCapacity.acquire(ref.GetSizeBytes()) + if !ok { + return cmdErr(pb.AckCode_ACK_CODE_BUSY, "firmware download capacity exhausted; retry shortly") + } + defer releaseDownload() + + tmpPath, cleanup, err := downloadFirmwareArtifact(ctx, client, commandID, deviceIdentifier, firmwareTempRoot, ref) + if err != nil { + return err + } + defer cleanup() + + file, err := os.Open(tmpPath) + if err != nil { + return fmt.Errorf("open downloaded firmware: %w", err) + } + defer file.Close() + + return dev.FirmwareUpdate(ctx, sdk.FirmwareFile{ + Reader: file, + ID: ref.GetArtifactId(), + Filename: ref.GetFilename(), + Size: ref.GetSizeBytes(), + SHA256: ref.GetSha256(), + FilePath: tmpPath, + }) +} + +type firmwareDownloadLimiter struct { + slots chan struct{} + maxBytes int64 + mu sync.Mutex + activeBytes int64 +} + +func newFirmwareDownloadLimiter(maxConcurrent int, maxBytes int64) *firmwareDownloadLimiter { + return &firmwareDownloadLimiter{ + slots: make(chan struct{}, maxConcurrent), + maxBytes: maxBytes, + } +} + +func (l *firmwareDownloadLimiter) acquire(size int64) (func(), bool) { + select { + case l.slots <- struct{}{}: + default: + return nil, false + } + + l.mu.Lock() + if l.activeBytes+size > l.maxBytes { + l.mu.Unlock() + <-l.slots + return nil, false + } + l.activeBytes += size + l.mu.Unlock() + + var once sync.Once + return func() { + once.Do(func() { + l.mu.Lock() + l.activeBytes -= size + l.mu.Unlock() + <-l.slots + }) + }, true +} + +func prepareFirmwareArtifactTempRoot(root string) error { + if err := os.RemoveAll(root); err != nil { + return fmt.Errorf("remove firmware temp dir: %w", err) + } + if err := os.MkdirAll(root, 0700); err != nil { + return fmt.Errorf("create firmware temp dir: %w", err) + } + return nil +} + +func ensureFirmwareTempSpace(root string, artifactSize int64) error { + freeBytes, err := firmwareTempFreeBytes(root) + if err != nil { + return fmt.Errorf("check firmware temp space: %w", err) + } + needed := artifactSize + minFirmwareTempFreeBytes + if freeBytes < needed { + return cmdErr(pb.AckCode_ACK_CODE_BUSY, "insufficient firmware temp space: need %d bytes, have %d bytes", needed, freeBytes) + } + return nil +} + +func firmwareTempFreeBytes(root string) (int64, error) { + var stat syscall.Statfs_t + if err := syscall.Statfs(root, &stat); err != nil { + return 0, fmt.Errorf("statfs firmware temp dir: %w", err) + } + if stat.Bsize <= 0 { + return 0, nil + } + blockSize := uint64(stat.Bsize) //nolint:gosec // Bsize is guarded above; Statfs reports a non-negative block size in practice. + availableBlocks := stat.Bavail + const maxInt64 = ^uint64(0) >> 1 + if availableBlocks > ^uint64(0)/blockSize { + return int64(maxInt64), nil + } + free := availableBlocks * blockSize + if free > maxInt64 { + return int64(maxInt64), nil + } + return int64(free), nil +} + +func downloadFirmwareArtifact(ctx context.Context, client gatewayClient, commandID, deviceIdentifier, firmwareTempRoot string, ref *pb.CommandArtifactRef) (string, func(), error) { + if firmwareTempRoot == "" { + firmwareTempRoot = filepath.Join(os.TempDir(), "proto-fleet-firmware") + } + if err := os.MkdirAll(firmwareTempRoot, 0700); err != nil { + return "", nil, fmt.Errorf("prepare firmware temp dir: %w", err) + } + if err := ensureFirmwareTempSpace(firmwareTempRoot, ref.GetSizeBytes()); err != nil { + return "", nil, err + } + + stream, err := client.DownloadCommandArtifact(ctx, connect.NewRequest(&pb.DownloadCommandArtifactRequest{ + CommandId: commandID, + Artifact: ref, + DeviceIdentifier: deviceIdentifier, + })) + if err != nil { + return "", nil, fmt.Errorf("download firmware artifact: %w", err) + } + defer stream.Close() + if !stream.Receive() { + return "", nil, commandArtifactStreamErr(stream, "receive firmware artifact header") + } + if got := stream.Msg().GetHeader(); got == nil || !commandArtifactRefsEqual(got.GetArtifact(), ref) { + return "", nil, cmdErr(pb.AckCode_ACK_CODE_BAD_REQUEST, "firmware artifact header does not match command") + } + + tmpDir, err := os.MkdirTemp(firmwareTempRoot, firmwareArtifactTempDirPrefix) + if err != nil { + return "", nil, fmt.Errorf("create firmware temp dir: %w", err) + } + cleanup := func() { _ = os.RemoveAll(tmpDir) } + filename := filepath.Base(ref.GetFilename()) + if filename == "" || filename == "." || filename == string(filepath.Separator) { + filename = "firmware.bin" + } + tmpPath := filepath.Join(tmpDir, filename) + file, err := os.OpenFile(tmpPath, os.O_CREATE|os.O_EXCL|os.O_WRONLY, 0600) + if err != nil { + cleanup() + return "", nil, fmt.Errorf("create firmware temp file: %w", err) + } + fail := func(err error) (string, func(), error) { + _ = file.Close() + cleanup() + return "", nil, err + } + + hasher := sha256.New() + var written int64 + for stream.Receive() { + chunk := stream.Msg().GetChunk() + if chunk == nil { + return fail(cmdErr(pb.AckCode_ACK_CODE_BAD_REQUEST, "firmware artifact stream contained non-chunk message after header")) + } + data := chunk.GetData() + if len(data) == 0 { + return fail(cmdErr(pb.AckCode_ACK_CODE_BAD_REQUEST, "firmware artifact chunk is empty")) + } + n, err := file.Write(data) + if err != nil { + return fail(fmt.Errorf("write firmware temp file: %w", err)) + } + if n != len(data) { + return fail(io.ErrShortWrite) + } + if _, err := hasher.Write(data); err != nil { + return fail(fmt.Errorf("hash firmware chunk: %w", err)) + } + written += int64(len(data)) + if written > ref.GetSizeBytes() { + return fail(cmdErr(pb.AckCode_ACK_CODE_BAD_REQUEST, "firmware artifact is larger than declared")) + } + } + if err := commandArtifactStreamErr(stream, "receive firmware artifact chunk"); err != nil && !errors.Is(err, io.EOF) { + return fail(err) + } + if err := file.Close(); err != nil { + cleanup() + return "", nil, fmt.Errorf("close firmware temp file: %w", err) + } + if written != ref.GetSizeBytes() { + cleanup() + return "", nil, cmdErr(pb.AckCode_ACK_CODE_BAD_REQUEST, "firmware artifact size mismatch: declared %d bytes, received %d bytes", ref.GetSizeBytes(), written) + } + if actual := hex.EncodeToString(hasher.Sum(nil)); actual != ref.GetSha256() { + cleanup() + return "", nil, cmdErr(pb.AckCode_ACK_CODE_BAD_REQUEST, "firmware artifact sha256 mismatch") + } + return tmpPath, cleanup, nil +} + +func commandArtifactStreamErr(stream *connect.ServerStreamForClient[pb.DownloadCommandArtifactResponse], stage string) error { + if err := stream.Err(); err != nil { + return fmt.Errorf("%s: %w", stage, err) + } + return io.EOF +} + +func commandArtifactRefsEqual(a, b *pb.CommandArtifactRef) bool { + return a.GetArtifactId() == b.GetArtifactId() && + a.GetPurpose() == b.GetPurpose() && + a.GetFilename() == b.GetFilename() && + a.GetSizeBytes() == b.GetSizeBytes() && + a.GetSha256() == b.GetSha256() +} + func toSDKMiningPoolConfigs(pools []*pb.MiningPoolConfig) []sdk.MiningPoolConfig { sdkPools := make([]sdk.MiningPoolConfig, 0, len(pools)) for _, pool := range pools { @@ -480,6 +754,51 @@ func validateGetMiningPoolsResult(result *pb.GetMiningPoolsResult) error { return nil } +func getFirmwareUpdateStatusResultPayload(ctx context.Context, dev sdk.Device) ([]byte, error) { + provider, ok := dev.(sdk.FirmwareUpdateStatusProvider) + if !ok { + return nil, nil + } + status, err := provider.GetFirmwareUpdateStatus(ctx) + if err != nil { + return nil, err + } + if status == nil { + return nil, nil + } + result, err := firmwareUpdateStatusResultFromSDK(status) + if err != nil { + return nil, err + } + if err := protovalidate.Validate(result); err != nil { + return nil, fmt.Errorf("invalid firmware update status result: %w", err) + } + payload, err := proto.Marshal(result) + if err != nil { + return nil, fmt.Errorf("marshal firmware update status result: %w", err) + } + return payload, nil +} + +func firmwareUpdateStatusResultFromSDK(status *sdk.FirmwareUpdateStatus) (*pb.FirmwareUpdateStatusResult, error) { + result := &pb.FirmwareUpdateStatusResult{ + State: status.State, + Error: status.Error, + } + if status.Progress != nil { + const ( + minInt32 = -1 << 31 + maxInt32 = 1<<31 - 1 + ) + if *status.Progress < minInt32 || *status.Progress > maxInt32 { + return nil, fmt.Errorf("firmware update progress %d is outside int32 range", *status.Progress) + } + progress := int32(*status.Progress) + result.Progress = &progress + } + return result, nil +} + func miningPoolConfigsFromSDK(pools []sdk.ConfiguredPool) []*pb.MiningPoolConfig { var defaultPool, backup1Pool, backup2Pool *pb.MiningPoolConfig for _, pool := range pools { diff --git a/server/cmd/fleetnode/minercommand_test.go b/server/cmd/fleetnode/minercommand_test.go index 5c02058dc..dc3a4f138 100644 --- a/server/cmd/fleetnode/minercommand_test.go +++ b/server/cmd/fleetnode/minercommand_test.go @@ -7,6 +7,11 @@ import ( "encoding/hex" "errors" "fmt" + "io" + "net/http" + "net/http/httptest" + "os" + "path/filepath" "strings" "sync" "testing" @@ -76,6 +81,16 @@ func (f failingSealProvider) Seal(sdk.SecretBundle) (*pb.EncryptedCredentials, e return nil, errors.New("seal failed") } +type firmwareStatusDevice struct { + sdk.Device + status *sdk.FirmwareUpdateStatus + err error +} + +func (d firmwareStatusDevice) GetFirmwareUpdateStatus(context.Context) (*sdk.FirmwareUpdateStatus, error) { + return d.status, d.err +} + // withTarget stamps a standard descriptor onto a command built with just an action. func withTarget(mc *pb.MinerCommand) *pb.MinerCommand { mc.Target = &pb.MinerConnectionDescriptor{ @@ -85,6 +100,64 @@ func withTarget(mc *pb.MinerCommand) *pb.MinerCommand { return mc } +func firmwareRef(id, filename string, payload []byte) *pb.CommandArtifactRef { + sum := sha256.Sum256(payload) + return &pb.CommandArtifactRef{ + ArtifactId: id, + Purpose: pb.CommandArtifactPurpose_COMMAND_ARTIFACT_PURPOSE_FIRMWARE_PAYLOAD, + Filename: filename, + SizeBytes: int64(len(payload)), + Sha256: hex.EncodeToString(sum[:]), + } +} + +type firmwareDownloadGateway struct { + fleetnodegatewayv1connect.UnimplementedFleetNodeGatewayServiceHandler + ref *pb.CommandArtifactRef + payload []byte + request *pb.DownloadCommandArtifactRequest + sendData []byte +} + +func (g *firmwareDownloadGateway) DownloadCommandArtifact(_ context.Context, req *connect.Request[pb.DownloadCommandArtifactRequest], stream *connect.ServerStream[pb.DownloadCommandArtifactResponse]) error { + g.request = req.Msg + if err := stream.Send(&pb.DownloadCommandArtifactResponse{Part: &pb.DownloadCommandArtifactResponse_Header{ + Header: &pb.CommandArtifactDownloadHeader{Artifact: g.ref}, + }}); err != nil { + return fmt.Errorf("send firmware artifact header: %w", err) + } + data := g.payload + if g.sendData != nil { + data = g.sendData + } + if err := stream.Send(&pb.DownloadCommandArtifactResponse{Part: &pb.DownloadCommandArtifactResponse_Chunk{ + Chunk: &pb.CommandArtifactChunk{Data: data}, + }}); err != nil { + return fmt.Errorf("send firmware artifact chunk: %w", err) + } + return nil +} + +func newFirmwareDownloadClient(t *testing.T, h *firmwareDownloadGateway) gatewayClient { + t.Helper() + path, handler := fleetnodegatewayv1connect.NewFleetNodeGatewayServiceHandler(h) + mux := http.NewServeMux() + mux.Handle(path, handler) + srv := httptest.NewServer(mux) + t.Cleanup(srv.Close) + return fleetnodegatewayv1connect.NewFleetNodeGatewayServiceClient(srv.Client(), srv.URL) +} + +func TestMinerCommandActionTimeoutUsesFirmwareBudget(t *testing.T) { + assert.Equal(t, minerCommandTimeout, minerCommandActionTimeout(withTarget(&pb.MinerCommand{ + Action: &pb.MinerCommand_Reboot{Reboot: &pb.RebootAction{}}, + }))) + assert.Equal(t, firmwareMinerCommandTimeout, minerCommandActionTimeout(withTarget(&pb.MinerCommand{ + Action: &pb.MinerCommand_FirmwareUpdate{FirmwareUpdate: &pb.FirmwareUpdateAction{Artifact: firmwareRef("firmware-1", "update.swu", []byte("firmware"))}}, + }))) + assert.LessOrEqual(t, firmwareMinerCommandTimeout+5*time.Minute, 15*time.Minute) +} + func TestHandleMinerCommand_ExecutesAndAcksOK(t *testing.T) { // Arrange ctrl := gomock.NewController(t) @@ -401,6 +474,7 @@ func TestHandleMinerCommand_UpdateMinerPasswordUsesCurrentPasswordWhenProtoCrede func TestHandleMinerCommand_UpdateMinerPasswordSealsBeforeUpdatingDevice(t *testing.T) { // Arrange ctrl := gomock.NewController(t) + dev := mocks.NewMockDevice(ctrl) dev.EXPECT().Close(gomock.Any()).Return(nil) drv := mocks.NewMockDriver(ctrl) @@ -475,6 +549,176 @@ func encryptedPasswordUpdateAction(t *testing.T, currentPassword, newPassword st return &pb.UpdateMinerPasswordAction{EncryptedPasswordUpdate: encrypted}, privateKey } +func TestHandleMinerCommand_FirmwareUpdateDownloadsArtifactAndCallsDevice(t *testing.T) { + ctrl := gomock.NewController(t) + payload := []byte("firmware image") + ref := firmwareRef("firmware-1", "update.swu", payload) + gateway := &firmwareDownloadGateway{ref: ref, payload: payload} + client := newFirmwareDownloadClient(t, gateway) + firmwareTempRoot := t.TempDir() + dev := mocks.NewMockDevice(ctrl) + dev.EXPECT().FirmwareUpdate(gomock.Any(), gomock.Any()). + DoAndReturn(func(_ context.Context, firmware sdk.FirmwareFile) error { + assert.Equal(t, ref.GetArtifactId(), firmware.ID) + assert.Equal(t, ref.GetFilename(), firmware.Filename) + assert.Equal(t, ref.GetSizeBytes(), firmware.Size) + assert.Equal(t, ref.GetSha256(), firmware.SHA256) + assert.NotEmpty(t, firmware.FilePath) + assert.True(t, strings.HasPrefix(firmware.FilePath, firmwareTempRoot+string(os.PathSeparator))) + data, err := os.ReadFile(firmware.FilePath) + require.NoError(t, err) + assert.Equal(t, payload, data) + readerData, err := io.ReadAll(firmware.Reader) + require.NoError(t, err) + assert.Equal(t, payload, readerData) + return nil + }) + dev.EXPECT().Close(gomock.Any()).Return(nil) + drv := mocks.NewMockDriver(ctrl) + drv.EXPECT().NewDevice(gomock.Any(), "dev-1", gomock.Any(), gomock.Any()).Return(sdk.NewDeviceResult{Device: dev}, nil) + r := &RunCmd{driverGetter: fakeDriverGetter{d: drv}, minerSecrets: nodeSecretProvider{}, firmwareTempRoot: firmwareTempRoot} + ack := &captureAcker{} + + r.handleMinerCommand(context.Background(), client, ack, "cmd-1", + withTarget(&pb.MinerCommand{Action: &pb.MinerCommand_FirmwareUpdate{FirmwareUpdate: &pb.FirmwareUpdateAction{Artifact: ref}}}), discardLogger(t)) + + got := ack.only(t) + assert.Equal(t, pb.AckCode_ACK_CODE_OK, got.GetCode()) + assert.True(t, got.GetSucceeded()) + require.NotNil(t, gateway.request) + assert.Equal(t, "cmd-1", gateway.request.GetCommandId()) + assert.Equal(t, "dev-1", gateway.request.GetDeviceIdentifier()) + assert.Equal(t, ref.GetArtifactId(), gateway.request.GetArtifact().GetArtifactId()) + entries, err := os.ReadDir(firmwareTempRoot) + require.NoError(t, err) + assert.Empty(t, entries) +} + +func TestHandleMinerCommand_FirmwareUpdateRejectsChecksumMismatch(t *testing.T) { + ctrl := gomock.NewController(t) + payload := []byte("firmware image") + ref := firmwareRef("firmware-1", "update.swu", payload) + gateway := &firmwareDownloadGateway{ref: ref, payload: payload, sendData: []byte("corrupt image")} + client := newFirmwareDownloadClient(t, gateway) + dev := mocks.NewMockDevice(ctrl) + dev.EXPECT().Close(gomock.Any()).Return(nil) + drv := mocks.NewMockDriver(ctrl) + drv.EXPECT().NewDevice(gomock.Any(), "dev-1", gomock.Any(), gomock.Any()).Return(sdk.NewDeviceResult{Device: dev}, nil) + r := &RunCmd{driverGetter: fakeDriverGetter{d: drv}, minerSecrets: nodeSecretProvider{}} + ack := &captureAcker{} + + r.handleMinerCommand(context.Background(), client, ack, "cmd-1", + withTarget(&pb.MinerCommand{Action: &pb.MinerCommand_FirmwareUpdate{FirmwareUpdate: &pb.FirmwareUpdateAction{Artifact: ref}}}), discardLogger(t)) + + got := ack.only(t) + assert.Equal(t, pb.AckCode_ACK_CODE_BAD_REQUEST, got.GetCode()) + assert.False(t, got.GetSucceeded()) + assert.Contains(t, got.GetErrorMessage(), "firmware artifact") +} + +func TestHandleMinerCommand_FirmwareUpdateRejectsOversizedArtifact(t *testing.T) { + ctrl := gomock.NewController(t) + ref := firmwareRef("firmware-1", "update.swu", []byte("firmware image")) + ref.SizeBytes = maxFleetNodeFirmwareArtifactSizeBytes + 1 + dev := mocks.NewMockDevice(ctrl) + dev.EXPECT().Close(gomock.Any()).Return(nil) + drv := mocks.NewMockDriver(ctrl) + drv.EXPECT().NewDevice(gomock.Any(), "dev-1", gomock.Any(), gomock.Any()).Return(sdk.NewDeviceResult{Device: dev}, nil) + r := &RunCmd{driverGetter: fakeDriverGetter{d: drv}, minerSecrets: nodeSecretProvider{}, firmwareTempRoot: t.TempDir()} + ack := &captureAcker{} + + r.handleMinerCommand(context.Background(), nil, ack, "cmd-1", + withTarget(&pb.MinerCommand{Action: &pb.MinerCommand_FirmwareUpdate{FirmwareUpdate: &pb.FirmwareUpdateAction{Artifact: ref}}}), discardLogger(t)) + + got := ack.only(t) + assert.Equal(t, pb.AckCode_ACK_CODE_BAD_REQUEST, got.GetCode()) + assert.False(t, got.GetSucceeded()) + assert.Contains(t, got.GetErrorMessage(), "exceeds fleet node limit") +} + +func TestHandleMinerCommand_GetFirmwareUpdateStatusReturnsPayload(t *testing.T) { + ctrl := gomock.NewController(t) + progress := 42 + errMsg := "still installing" + dev := mocks.NewMockDevice(ctrl) + dev.EXPECT().Close(gomock.Any()).Return(nil) + drv := mocks.NewMockDriver(ctrl) + drv.EXPECT().NewDevice(gomock.Any(), "dev-1", gomock.Any(), gomock.Any()).Return(sdk.NewDeviceResult{ + Device: firmwareStatusDevice{ + Device: dev, + status: &sdk.FirmwareUpdateStatus{ + State: "installing", + Progress: &progress, + Error: &errMsg, + }, + }, + }, nil) + r := &RunCmd{driverGetter: fakeDriverGetter{d: drv}, minerSecrets: nodeSecretProvider{}} + ack := &captureAcker{} + + r.handleMinerCommand(context.Background(), nil, ack, "cmd-1", + withTarget(&pb.MinerCommand{Action: &pb.MinerCommand_GetFirmwareUpdateStatus{GetFirmwareUpdateStatus: &pb.GetFirmwareUpdateStatusAction{}}}), discardLogger(t)) + + got := ack.only(t) + assert.Equal(t, pb.AckCode_ACK_CODE_OK, got.GetCode()) + assert.True(t, got.GetSucceeded()) + var result pb.FirmwareUpdateStatusResult + require.NoError(t, proto.Unmarshal(got.GetPayload(), &result)) + assert.Equal(t, "installing", result.GetState()) + require.NotNil(t, result.Progress) + assert.Equal(t, int32(42), result.GetProgress()) + require.NotNil(t, result.Error) + assert.Equal(t, errMsg, result.GetError()) +} + +func TestHandleMinerCommand_GetFirmwareUpdateStatusWithoutProviderReturnsEmptyPayload(t *testing.T) { + ctrl := gomock.NewController(t) + dev := mocks.NewMockDevice(ctrl) + dev.EXPECT().Close(gomock.Any()).Return(nil) + drv := mocks.NewMockDriver(ctrl) + drv.EXPECT().NewDevice(gomock.Any(), "dev-1", gomock.Any(), gomock.Any()).Return(sdk.NewDeviceResult{Device: dev}, nil) + r := &RunCmd{driverGetter: fakeDriverGetter{d: drv}, minerSecrets: nodeSecretProvider{}} + ack := &captureAcker{} + + r.handleMinerCommand(context.Background(), nil, ack, "cmd-1", + withTarget(&pb.MinerCommand{Action: &pb.MinerCommand_GetFirmwareUpdateStatus{GetFirmwareUpdateStatus: &pb.GetFirmwareUpdateStatusAction{}}}), discardLogger(t)) + + got := ack.only(t) + assert.Equal(t, pb.AckCode_ACK_CODE_OK, got.GetCode()) + assert.True(t, got.GetSucceeded()) + assert.Empty(t, got.GetPayload()) +} + +func TestFirmwareDownloadLimiterRejectsConcurrentAndOverQuota(t *testing.T) { + limiter := newFirmwareDownloadLimiter(1, 100) + release, ok := limiter.acquire(60) + require.True(t, ok) + + _, ok = limiter.acquire(1) + assert.False(t, ok) + + release() + releaseAgain, ok := limiter.acquire(100) + require.True(t, ok) + releaseAgain() + + _, ok = limiter.acquire(101) + assert.False(t, ok) +} + +func TestPrepareFirmwareArtifactTempRootRemovesOrphans(t *testing.T) { + root := t.TempDir() + orphan := filepath.Join(root, firmwareArtifactTempDirPrefix+"old") + require.NoError(t, os.MkdirAll(orphan, 0700)) + require.NoError(t, os.WriteFile(filepath.Join(orphan, "firmware.bin"), []byte("left behind"), 0600)) + + require.NoError(t, prepareFirmwareArtifactTempRoot(root)) + + entries, err := os.ReadDir(root) + require.NoError(t, err) + assert.Empty(t, entries) +} + func TestHandleMinerCommand_GetMiningPoolsReturnsPayload(t *testing.T) { // Arrange ctrl := gomock.NewController(t) diff --git a/server/cmd/fleetnode/run.go b/server/cmd/fleetnode/run.go index 8efe9c4fc..55835f7a6 100644 --- a/server/cmd/fleetnode/run.go +++ b/server/cmd/fleetnode/run.go @@ -8,6 +8,7 @@ import ( "log/slog" "os" "os/signal" + "path/filepath" "sync" "time" @@ -41,6 +42,7 @@ type RunCmd struct { nmapPath string `kong:"-"` resolver ipResolver `kong:"-"` localSubnets func() ([]string, error) `kong:"-"` // test seam for local-subnet detection + firmwareTempRoot string `kong:"-"` stateMu sync.Mutex `kong:"-"` // guards st.SessionToken across refreshAndSave + tokenSource. pairMu sync.Mutex `kong:"-"` // serializes pair commands; held until every pair worker exits (see handlePairCommand). @@ -141,6 +143,10 @@ func (r *RunCmd) runLocked(ctx context.Context, c *Context, resolvedPluginsDir s if err := bootstrap.ValidateServerURL(st.ServerURL, st.AllowInsecureTransport); err != nil { return err } + r.firmwareTempRoot = filepath.Join(c.StateDir, firmwareArtifactTempDirName) + if err := prepareFirmwareArtifactTempRoot(r.firmwareTempRoot); err != nil { + return fmt.Errorf("prepare firmware temp dir: %w", err) + } // Reap + spawn inside the lock, from the state loaded under it, so the // synthesized auto: identifiers hash with the fleet_node_id the gateway diff --git a/server/generated/grpc/fleetnodegateway/v1/fleetnodegateway.pb.go b/server/generated/grpc/fleetnodegateway/v1/fleetnodegateway.pb.go index c83fdf552..065d3dcde 100644 --- a/server/generated/grpc/fleetnodegateway/v1/fleetnodegateway.pb.go +++ b/server/generated/grpc/fleetnodegateway/v1/fleetnodegateway.pb.go @@ -2354,6 +2354,8 @@ type MinerCommand struct { // *MinerCommand_GetErrors // *MinerCommand_UpdateMinerPassword // *MinerCommand_DownloadLogs + // *MinerCommand_FirmwareUpdate + // *MinerCommand_GetFirmwareUpdateStatus Action isMinerCommand_Action `protobuf_oneof:"action"` unknownFields protoimpl.UnknownFields sizeCache protoimpl.SizeCache @@ -2520,6 +2522,24 @@ func (x *MinerCommand) GetDownloadLogs() *DownloadLogsAction { return nil } +func (x *MinerCommand) GetFirmwareUpdate() *FirmwareUpdateAction { + if x != nil { + if x, ok := x.Action.(*MinerCommand_FirmwareUpdate); ok { + return x.FirmwareUpdate + } + } + return nil +} + +func (x *MinerCommand) GetGetFirmwareUpdateStatus() *GetFirmwareUpdateStatusAction { + if x != nil { + if x, ok := x.Action.(*MinerCommand_GetFirmwareUpdateStatus); ok { + return x.GetFirmwareUpdateStatus + } + } + return nil +} + type isMinerCommand_Action interface { isMinerCommand_Action() } @@ -2576,6 +2596,14 @@ type MinerCommand_DownloadLogs struct { DownloadLogs *DownloadLogsAction `protobuf:"bytes,14,opt,name=download_logs,json=downloadLogs,proto3,oneof"` } +type MinerCommand_FirmwareUpdate struct { + FirmwareUpdate *FirmwareUpdateAction `protobuf:"bytes,15,opt,name=firmware_update,json=firmwareUpdate,proto3,oneof"` +} + +type MinerCommand_GetFirmwareUpdateStatus struct { + GetFirmwareUpdateStatus *GetFirmwareUpdateStatusAction `protobuf:"bytes,16,opt,name=get_firmware_update_status,json=getFirmwareUpdateStatus,proto3,oneof"` +} + func (*MinerCommand_Reboot) isMinerCommand_Action() {} func (*MinerCommand_StartMining) isMinerCommand_Action() {} @@ -2602,6 +2630,10 @@ func (*MinerCommand_UpdateMinerPassword) isMinerCommand_Action() {} func (*MinerCommand_DownloadLogs) isMinerCommand_Action() {} +func (*MinerCommand_FirmwareUpdate) isMinerCommand_Action() {} + +func (*MinerCommand_GetFirmwareUpdateStatus) isMinerCommand_Action() {} + type RebootAction struct { state protoimpl.MessageState `protogen:"open.v1"` unknownFields protoimpl.UnknownFields @@ -2854,6 +2886,42 @@ func (*GetErrorsAction) Descriptor() ([]byte, []int) { return file_fleetnodegateway_v1_fleetnodegateway_proto_rawDescGZIP(), []int{40} } +type GetFirmwareUpdateStatusAction struct { + state protoimpl.MessageState `protogen:"open.v1"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *GetFirmwareUpdateStatusAction) Reset() { + *x = GetFirmwareUpdateStatusAction{} + mi := &file_fleetnodegateway_v1_fleetnodegateway_proto_msgTypes[41] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *GetFirmwareUpdateStatusAction) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetFirmwareUpdateStatusAction) ProtoMessage() {} + +func (x *GetFirmwareUpdateStatusAction) ProtoReflect() protoreflect.Message { + mi := &file_fleetnodegateway_v1_fleetnodegateway_proto_msgTypes[41] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetFirmwareUpdateStatusAction.ProtoReflect.Descriptor instead. +func (*GetFirmwareUpdateStatusAction) Descriptor() ([]byte, []int) { + return file_fleetnodegateway_v1_fleetnodegateway_proto_rawDescGZIP(), []int{41} +} + type DownloadLogsAction struct { state protoimpl.MessageState `protogen:"open.v1"` BatchLogUuid string `protobuf:"bytes,1,opt,name=batch_log_uuid,json=batchLogUuid,proto3" json:"batch_log_uuid,omitempty"` @@ -2863,7 +2931,7 @@ type DownloadLogsAction struct { func (x *DownloadLogsAction) Reset() { *x = DownloadLogsAction{} - mi := &file_fleetnodegateway_v1_fleetnodegateway_proto_msgTypes[41] + mi := &file_fleetnodegateway_v1_fleetnodegateway_proto_msgTypes[42] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2875,7 +2943,7 @@ func (x *DownloadLogsAction) String() string { func (*DownloadLogsAction) ProtoMessage() {} func (x *DownloadLogsAction) ProtoReflect() protoreflect.Message { - mi := &file_fleetnodegateway_v1_fleetnodegateway_proto_msgTypes[41] + mi := &file_fleetnodegateway_v1_fleetnodegateway_proto_msgTypes[42] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2888,7 +2956,7 @@ func (x *DownloadLogsAction) ProtoReflect() protoreflect.Message { // Deprecated: Use DownloadLogsAction.ProtoReflect.Descriptor instead. func (*DownloadLogsAction) Descriptor() ([]byte, []int) { - return file_fleetnodegateway_v1_fleetnodegateway_proto_rawDescGZIP(), []int{41} + return file_fleetnodegateway_v1_fleetnodegateway_proto_rawDescGZIP(), []int{42} } func (x *DownloadLogsAction) GetBatchLogUuid() string { @@ -2910,7 +2978,7 @@ type NodeEncryptedPayload struct { func (x *NodeEncryptedPayload) Reset() { *x = NodeEncryptedPayload{} - mi := &file_fleetnodegateway_v1_fleetnodegateway_proto_msgTypes[42] + mi := &file_fleetnodegateway_v1_fleetnodegateway_proto_msgTypes[43] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2922,7 +2990,7 @@ func (x *NodeEncryptedPayload) String() string { func (*NodeEncryptedPayload) ProtoMessage() {} func (x *NodeEncryptedPayload) ProtoReflect() protoreflect.Message { - mi := &file_fleetnodegateway_v1_fleetnodegateway_proto_msgTypes[42] + mi := &file_fleetnodegateway_v1_fleetnodegateway_proto_msgTypes[43] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2935,7 +3003,7 @@ func (x *NodeEncryptedPayload) ProtoReflect() protoreflect.Message { // Deprecated: Use NodeEncryptedPayload.ProtoReflect.Descriptor instead. func (*NodeEncryptedPayload) Descriptor() ([]byte, []int) { - return file_fleetnodegateway_v1_fleetnodegateway_proto_rawDescGZIP(), []int{42} + return file_fleetnodegateway_v1_fleetnodegateway_proto_rawDescGZIP(), []int{43} } func (x *NodeEncryptedPayload) GetAlgorithm() string { @@ -2975,7 +3043,7 @@ type UpdateMinerPasswordAction struct { func (x *UpdateMinerPasswordAction) Reset() { *x = UpdateMinerPasswordAction{} - mi := &file_fleetnodegateway_v1_fleetnodegateway_proto_msgTypes[43] + mi := &file_fleetnodegateway_v1_fleetnodegateway_proto_msgTypes[44] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2987,7 +3055,7 @@ func (x *UpdateMinerPasswordAction) String() string { func (*UpdateMinerPasswordAction) ProtoMessage() {} func (x *UpdateMinerPasswordAction) ProtoReflect() protoreflect.Message { - mi := &file_fleetnodegateway_v1_fleetnodegateway_proto_msgTypes[43] + mi := &file_fleetnodegateway_v1_fleetnodegateway_proto_msgTypes[44] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3000,7 +3068,7 @@ func (x *UpdateMinerPasswordAction) ProtoReflect() protoreflect.Message { // Deprecated: Use UpdateMinerPasswordAction.ProtoReflect.Descriptor instead. func (*UpdateMinerPasswordAction) Descriptor() ([]byte, []int) { - return file_fleetnodegateway_v1_fleetnodegateway_proto_rawDescGZIP(), []int{43} + return file_fleetnodegateway_v1_fleetnodegateway_proto_rawDescGZIP(), []int{44} } func (x *UpdateMinerPasswordAction) GetEncryptedPasswordUpdate() *NodeEncryptedPayload { @@ -3019,7 +3087,7 @@ type UpdateMinerPasswordResult struct { func (x *UpdateMinerPasswordResult) Reset() { *x = UpdateMinerPasswordResult{} - mi := &file_fleetnodegateway_v1_fleetnodegateway_proto_msgTypes[44] + mi := &file_fleetnodegateway_v1_fleetnodegateway_proto_msgTypes[45] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3031,7 +3099,7 @@ func (x *UpdateMinerPasswordResult) String() string { func (*UpdateMinerPasswordResult) ProtoMessage() {} func (x *UpdateMinerPasswordResult) ProtoReflect() protoreflect.Message { - mi := &file_fleetnodegateway_v1_fleetnodegateway_proto_msgTypes[44] + mi := &file_fleetnodegateway_v1_fleetnodegateway_proto_msgTypes[45] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3044,7 +3112,7 @@ func (x *UpdateMinerPasswordResult) ProtoReflect() protoreflect.Message { // Deprecated: Use UpdateMinerPasswordResult.ProtoReflect.Descriptor instead. func (*UpdateMinerPasswordResult) Descriptor() ([]byte, []int) { - return file_fleetnodegateway_v1_fleetnodegateway_proto_rawDescGZIP(), []int{44} + return file_fleetnodegateway_v1_fleetnodegateway_proto_rawDescGZIP(), []int{45} } func (x *UpdateMinerPasswordResult) GetEncryptedCredentials() *EncryptedCredentials { @@ -3054,6 +3122,50 @@ func (x *UpdateMinerPasswordResult) GetEncryptedCredentials() *EncryptedCredenti return nil } +type FirmwareUpdateAction struct { + state protoimpl.MessageState `protogen:"open.v1"` + Artifact *CommandArtifactRef `protobuf:"bytes,1,opt,name=artifact,proto3" json:"artifact,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *FirmwareUpdateAction) Reset() { + *x = FirmwareUpdateAction{} + mi := &file_fleetnodegateway_v1_fleetnodegateway_proto_msgTypes[46] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *FirmwareUpdateAction) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*FirmwareUpdateAction) ProtoMessage() {} + +func (x *FirmwareUpdateAction) ProtoReflect() protoreflect.Message { + mi := &file_fleetnodegateway_v1_fleetnodegateway_proto_msgTypes[46] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use FirmwareUpdateAction.ProtoReflect.Descriptor instead. +func (*FirmwareUpdateAction) Descriptor() ([]byte, []int) { + return file_fleetnodegateway_v1_fleetnodegateway_proto_rawDescGZIP(), []int{46} +} + +func (x *FirmwareUpdateAction) GetArtifact() *CommandArtifactRef { + if x != nil { + return x.Artifact + } + return nil +} + type CurtailAction struct { state protoimpl.MessageState `protogen:"open.v1"` Level v1.CurtailmentLevel `protobuf:"varint,1,opt,name=level,proto3,enum=curtailment.v1.CurtailmentLevel" json:"level,omitempty"` @@ -3063,7 +3175,7 @@ type CurtailAction struct { func (x *CurtailAction) Reset() { *x = CurtailAction{} - mi := &file_fleetnodegateway_v1_fleetnodegateway_proto_msgTypes[45] + mi := &file_fleetnodegateway_v1_fleetnodegateway_proto_msgTypes[47] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3075,7 +3187,7 @@ func (x *CurtailAction) String() string { func (*CurtailAction) ProtoMessage() {} func (x *CurtailAction) ProtoReflect() protoreflect.Message { - mi := &file_fleetnodegateway_v1_fleetnodegateway_proto_msgTypes[45] + mi := &file_fleetnodegateway_v1_fleetnodegateway_proto_msgTypes[47] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3088,7 +3200,7 @@ func (x *CurtailAction) ProtoReflect() protoreflect.Message { // Deprecated: Use CurtailAction.ProtoReflect.Descriptor instead. func (*CurtailAction) Descriptor() ([]byte, []int) { - return file_fleetnodegateway_v1_fleetnodegateway_proto_rawDescGZIP(), []int{45} + return file_fleetnodegateway_v1_fleetnodegateway_proto_rawDescGZIP(), []int{47} } func (x *CurtailAction) GetLevel() v1.CurtailmentLevel { @@ -3107,7 +3219,7 @@ type SetCoolingModeAction struct { func (x *SetCoolingModeAction) Reset() { *x = SetCoolingModeAction{} - mi := &file_fleetnodegateway_v1_fleetnodegateway_proto_msgTypes[46] + mi := &file_fleetnodegateway_v1_fleetnodegateway_proto_msgTypes[48] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3119,7 +3231,7 @@ func (x *SetCoolingModeAction) String() string { func (*SetCoolingModeAction) ProtoMessage() {} func (x *SetCoolingModeAction) ProtoReflect() protoreflect.Message { - mi := &file_fleetnodegateway_v1_fleetnodegateway_proto_msgTypes[46] + mi := &file_fleetnodegateway_v1_fleetnodegateway_proto_msgTypes[48] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3132,7 +3244,7 @@ func (x *SetCoolingModeAction) ProtoReflect() protoreflect.Message { // Deprecated: Use SetCoolingModeAction.ProtoReflect.Descriptor instead. func (*SetCoolingModeAction) Descriptor() ([]byte, []int) { - return file_fleetnodegateway_v1_fleetnodegateway_proto_rawDescGZIP(), []int{46} + return file_fleetnodegateway_v1_fleetnodegateway_proto_rawDescGZIP(), []int{48} } func (x *SetCoolingModeAction) GetMode() v11.CoolingMode { @@ -3151,7 +3263,7 @@ type SetPowerTargetAction struct { func (x *SetPowerTargetAction) Reset() { *x = SetPowerTargetAction{} - mi := &file_fleetnodegateway_v1_fleetnodegateway_proto_msgTypes[47] + mi := &file_fleetnodegateway_v1_fleetnodegateway_proto_msgTypes[49] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3163,7 +3275,7 @@ func (x *SetPowerTargetAction) String() string { func (*SetPowerTargetAction) ProtoMessage() {} func (x *SetPowerTargetAction) ProtoReflect() protoreflect.Message { - mi := &file_fleetnodegateway_v1_fleetnodegateway_proto_msgTypes[47] + mi := &file_fleetnodegateway_v1_fleetnodegateway_proto_msgTypes[49] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3176,7 +3288,7 @@ func (x *SetPowerTargetAction) ProtoReflect() protoreflect.Message { // Deprecated: Use SetPowerTargetAction.ProtoReflect.Descriptor instead. func (*SetPowerTargetAction) Descriptor() ([]byte, []int) { - return file_fleetnodegateway_v1_fleetnodegateway_proto_rawDescGZIP(), []int{47} + return file_fleetnodegateway_v1_fleetnodegateway_proto_rawDescGZIP(), []int{49} } func (x *SetPowerTargetAction) GetPerformanceMode() v12.PerformanceMode { @@ -3197,7 +3309,7 @@ type MiningPoolConfig struct { func (x *MiningPoolConfig) Reset() { *x = MiningPoolConfig{} - mi := &file_fleetnodegateway_v1_fleetnodegateway_proto_msgTypes[48] + mi := &file_fleetnodegateway_v1_fleetnodegateway_proto_msgTypes[50] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3209,7 +3321,7 @@ func (x *MiningPoolConfig) String() string { func (*MiningPoolConfig) ProtoMessage() {} func (x *MiningPoolConfig) ProtoReflect() protoreflect.Message { - mi := &file_fleetnodegateway_v1_fleetnodegateway_proto_msgTypes[48] + mi := &file_fleetnodegateway_v1_fleetnodegateway_proto_msgTypes[50] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3222,7 +3334,7 @@ func (x *MiningPoolConfig) ProtoReflect() protoreflect.Message { // Deprecated: Use MiningPoolConfig.ProtoReflect.Descriptor instead. func (*MiningPoolConfig) Descriptor() ([]byte, []int) { - return file_fleetnodegateway_v1_fleetnodegateway_proto_rawDescGZIP(), []int{48} + return file_fleetnodegateway_v1_fleetnodegateway_proto_rawDescGZIP(), []int{50} } func (x *MiningPoolConfig) GetPriority() int32 { @@ -3255,7 +3367,7 @@ type UpdateMiningPoolsAction struct { func (x *UpdateMiningPoolsAction) Reset() { *x = UpdateMiningPoolsAction{} - mi := &file_fleetnodegateway_v1_fleetnodegateway_proto_msgTypes[49] + mi := &file_fleetnodegateway_v1_fleetnodegateway_proto_msgTypes[51] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3267,7 +3379,7 @@ func (x *UpdateMiningPoolsAction) String() string { func (*UpdateMiningPoolsAction) ProtoMessage() {} func (x *UpdateMiningPoolsAction) ProtoReflect() protoreflect.Message { - mi := &file_fleetnodegateway_v1_fleetnodegateway_proto_msgTypes[49] + mi := &file_fleetnodegateway_v1_fleetnodegateway_proto_msgTypes[51] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3280,7 +3392,7 @@ func (x *UpdateMiningPoolsAction) ProtoReflect() protoreflect.Message { // Deprecated: Use UpdateMiningPoolsAction.ProtoReflect.Descriptor instead. func (*UpdateMiningPoolsAction) Descriptor() ([]byte, []int) { - return file_fleetnodegateway_v1_fleetnodegateway_proto_rawDescGZIP(), []int{49} + return file_fleetnodegateway_v1_fleetnodegateway_proto_rawDescGZIP(), []int{51} } func (x *UpdateMiningPoolsAction) GetPools() []*MiningPoolConfig { @@ -3299,7 +3411,7 @@ type GetMiningPoolsResult struct { func (x *GetMiningPoolsResult) Reset() { *x = GetMiningPoolsResult{} - mi := &file_fleetnodegateway_v1_fleetnodegateway_proto_msgTypes[50] + mi := &file_fleetnodegateway_v1_fleetnodegateway_proto_msgTypes[52] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3311,7 +3423,7 @@ func (x *GetMiningPoolsResult) String() string { func (*GetMiningPoolsResult) ProtoMessage() {} func (x *GetMiningPoolsResult) ProtoReflect() protoreflect.Message { - mi := &file_fleetnodegateway_v1_fleetnodegateway_proto_msgTypes[50] + mi := &file_fleetnodegateway_v1_fleetnodegateway_proto_msgTypes[52] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3324,7 +3436,7 @@ func (x *GetMiningPoolsResult) ProtoReflect() protoreflect.Message { // Deprecated: Use GetMiningPoolsResult.ProtoReflect.Descriptor instead. func (*GetMiningPoolsResult) Descriptor() ([]byte, []int) { - return file_fleetnodegateway_v1_fleetnodegateway_proto_rawDescGZIP(), []int{50} + return file_fleetnodegateway_v1_fleetnodegateway_proto_rawDescGZIP(), []int{52} } func (x *GetMiningPoolsResult) GetPools() []*MiningPoolConfig { @@ -3334,6 +3446,66 @@ func (x *GetMiningPoolsResult) GetPools() []*MiningPoolConfig { return nil } +type FirmwareUpdateStatusResult struct { + state protoimpl.MessageState `protogen:"open.v1"` + State string `protobuf:"bytes,1,opt,name=state,proto3" json:"state,omitempty"` + Progress *int32 `protobuf:"varint,2,opt,name=progress,proto3,oneof" json:"progress,omitempty"` + Error *string `protobuf:"bytes,3,opt,name=error,proto3,oneof" json:"error,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *FirmwareUpdateStatusResult) Reset() { + *x = FirmwareUpdateStatusResult{} + mi := &file_fleetnodegateway_v1_fleetnodegateway_proto_msgTypes[53] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *FirmwareUpdateStatusResult) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*FirmwareUpdateStatusResult) ProtoMessage() {} + +func (x *FirmwareUpdateStatusResult) ProtoReflect() protoreflect.Message { + mi := &file_fleetnodegateway_v1_fleetnodegateway_proto_msgTypes[53] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use FirmwareUpdateStatusResult.ProtoReflect.Descriptor instead. +func (*FirmwareUpdateStatusResult) Descriptor() ([]byte, []int) { + return file_fleetnodegateway_v1_fleetnodegateway_proto_rawDescGZIP(), []int{53} +} + +func (x *FirmwareUpdateStatusResult) GetState() string { + if x != nil { + return x.State + } + return "" +} + +func (x *FirmwareUpdateStatusResult) GetProgress() int32 { + if x != nil && x.Progress != nil { + return *x.Progress + } + return 0 +} + +func (x *FirmwareUpdateStatusResult) GetError() string { + if x != nil && x.Error != nil { + return *x.Error + } + return "" +} + type MinerErrorReport struct { state protoimpl.MessageState `protogen:"open.v1"` MinerError v13.MinerError `protobuf:"varint,1,opt,name=miner_error,json=minerError,proto3,enum=errors.v1.MinerError" json:"miner_error,omitempty"` @@ -3355,7 +3527,7 @@ type MinerErrorReport struct { func (x *MinerErrorReport) Reset() { *x = MinerErrorReport{} - mi := &file_fleetnodegateway_v1_fleetnodegateway_proto_msgTypes[51] + mi := &file_fleetnodegateway_v1_fleetnodegateway_proto_msgTypes[54] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3367,7 +3539,7 @@ func (x *MinerErrorReport) String() string { func (*MinerErrorReport) ProtoMessage() {} func (x *MinerErrorReport) ProtoReflect() protoreflect.Message { - mi := &file_fleetnodegateway_v1_fleetnodegateway_proto_msgTypes[51] + mi := &file_fleetnodegateway_v1_fleetnodegateway_proto_msgTypes[54] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3380,7 +3552,7 @@ func (x *MinerErrorReport) ProtoReflect() protoreflect.Message { // Deprecated: Use MinerErrorReport.ProtoReflect.Descriptor instead. func (*MinerErrorReport) Descriptor() ([]byte, []int) { - return file_fleetnodegateway_v1_fleetnodegateway_proto_rawDescGZIP(), []int{51} + return file_fleetnodegateway_v1_fleetnodegateway_proto_rawDescGZIP(), []int{54} } func (x *MinerErrorReport) GetMinerError() v13.MinerError { @@ -3486,7 +3658,7 @@ type GetErrorsResult struct { func (x *GetErrorsResult) Reset() { *x = GetErrorsResult{} - mi := &file_fleetnodegateway_v1_fleetnodegateway_proto_msgTypes[52] + mi := &file_fleetnodegateway_v1_fleetnodegateway_proto_msgTypes[55] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3498,7 +3670,7 @@ func (x *GetErrorsResult) String() string { func (*GetErrorsResult) ProtoMessage() {} func (x *GetErrorsResult) ProtoReflect() protoreflect.Message { - mi := &file_fleetnodegateway_v1_fleetnodegateway_proto_msgTypes[52] + mi := &file_fleetnodegateway_v1_fleetnodegateway_proto_msgTypes[55] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3511,7 +3683,7 @@ func (x *GetErrorsResult) ProtoReflect() protoreflect.Message { // Deprecated: Use GetErrorsResult.ProtoReflect.Descriptor instead. func (*GetErrorsResult) Descriptor() ([]byte, []int) { - return file_fleetnodegateway_v1_fleetnodegateway_proto_rawDescGZIP(), []int{52} + return file_fleetnodegateway_v1_fleetnodegateway_proto_rawDescGZIP(), []int{55} } func (x *GetErrorsResult) GetDeviceId() string { @@ -3568,7 +3740,7 @@ type AgentCommand struct { func (x *AgentCommand) Reset() { *x = AgentCommand{} - mi := &file_fleetnodegateway_v1_fleetnodegateway_proto_msgTypes[53] + mi := &file_fleetnodegateway_v1_fleetnodegateway_proto_msgTypes[56] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3580,7 +3752,7 @@ func (x *AgentCommand) String() string { func (*AgentCommand) ProtoMessage() {} func (x *AgentCommand) ProtoReflect() protoreflect.Message { - mi := &file_fleetnodegateway_v1_fleetnodegateway_proto_msgTypes[53] + mi := &file_fleetnodegateway_v1_fleetnodegateway_proto_msgTypes[56] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3593,7 +3765,7 @@ func (x *AgentCommand) ProtoReflect() protoreflect.Message { // Deprecated: Use AgentCommand.ProtoReflect.Descriptor instead. func (*AgentCommand) Descriptor() ([]byte, []int) { - return file_fleetnodegateway_v1_fleetnodegateway_proto_rawDescGZIP(), []int{53} + return file_fleetnodegateway_v1_fleetnodegateway_proto_rawDescGZIP(), []int{56} } func (x *AgentCommand) GetCommand() isAgentCommand_Command { @@ -3681,7 +3853,7 @@ type ControlAck struct { func (x *ControlAck) Reset() { *x = ControlAck{} - mi := &file_fleetnodegateway_v1_fleetnodegateway_proto_msgTypes[54] + mi := &file_fleetnodegateway_v1_fleetnodegateway_proto_msgTypes[57] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3693,7 +3865,7 @@ func (x *ControlAck) String() string { func (*ControlAck) ProtoMessage() {} func (x *ControlAck) ProtoReflect() protoreflect.Message { - mi := &file_fleetnodegateway_v1_fleetnodegateway_proto_msgTypes[54] + mi := &file_fleetnodegateway_v1_fleetnodegateway_proto_msgTypes[57] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3706,7 +3878,7 @@ func (x *ControlAck) ProtoReflect() protoreflect.Message { // Deprecated: Use ControlAck.ProtoReflect.Descriptor instead. func (*ControlAck) Descriptor() ([]byte, []int) { - return file_fleetnodegateway_v1_fleetnodegateway_proto_rawDescGZIP(), []int{54} + return file_fleetnodegateway_v1_fleetnodegateway_proto_rawDescGZIP(), []int{57} } func (x *ControlAck) GetCommandId() string { @@ -4128,7 +4300,7 @@ var file_fleetnodegateway_v1_fleetnodegateway_proto_rawDesc = string([]byte{ 0x39, 0x0a, 0x13, 0x63, 0x72, 0x65, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x61, 0x6c, 0x5f, 0x70, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0c, 0x42, 0x08, 0xba, 0x48, 0x05, 0x7a, 0x03, 0x18, 0x80, 0x20, 0x52, 0x12, 0x63, 0x72, 0x65, 0x64, 0x65, 0x6e, 0x74, 0x69, - 0x61, 0x6c, 0x50, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x22, 0xef, 0x08, 0x0a, 0x0c, 0x4d, + 0x61, 0x6c, 0x50, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x22, 0xb8, 0x0a, 0x0a, 0x0c, 0x4d, 0x69, 0x6e, 0x65, 0x72, 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x12, 0x4e, 0x0a, 0x06, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2e, 0x2e, 0x66, 0x6c, 0x65, 0x65, 0x74, 0x6e, 0x6f, 0x64, 0x65, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x2e, 0x76, @@ -4198,361 +4370,392 @@ var file_fleetnodegateway_v1_fleetnodegateway_proto_rawDesc = string([]byte{ 0x28, 0x0b, 0x32, 0x27, 0x2e, 0x66, 0x6c, 0x65, 0x65, 0x74, 0x6e, 0x6f, 0x64, 0x65, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x2e, 0x76, 0x31, 0x2e, 0x44, 0x6f, 0x77, 0x6e, 0x6c, 0x6f, 0x61, 0x64, 0x4c, 0x6f, 0x67, 0x73, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x48, 0x00, 0x52, 0x0c, 0x64, - 0x6f, 0x77, 0x6e, 0x6c, 0x6f, 0x61, 0x64, 0x4c, 0x6f, 0x67, 0x73, 0x42, 0x0f, 0x0a, 0x06, 0x61, - 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x05, 0xba, 0x48, 0x02, 0x08, 0x01, 0x22, 0x0e, 0x0a, 0x0c, - 0x52, 0x65, 0x62, 0x6f, 0x6f, 0x74, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0x13, 0x0a, 0x11, - 0x53, 0x74, 0x61, 0x72, 0x74, 0x4d, 0x69, 0x6e, 0x69, 0x6e, 0x67, 0x41, 0x63, 0x74, 0x69, 0x6f, - 0x6e, 0x22, 0x12, 0x0a, 0x10, 0x53, 0x74, 0x6f, 0x70, 0x4d, 0x69, 0x6e, 0x69, 0x6e, 0x67, 0x41, - 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0x10, 0x0a, 0x0e, 0x42, 0x6c, 0x69, 0x6e, 0x6b, 0x4c, 0x65, - 0x64, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0x11, 0x0a, 0x0f, 0x55, 0x6e, 0x63, 0x75, 0x72, - 0x74, 0x61, 0x69, 0x6c, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0x16, 0x0a, 0x14, 0x47, 0x65, - 0x74, 0x4d, 0x69, 0x6e, 0x69, 0x6e, 0x67, 0x50, 0x6f, 0x6f, 0x6c, 0x73, 0x41, 0x63, 0x74, 0x69, - 0x6f, 0x6e, 0x22, 0x11, 0x0a, 0x0f, 0x47, 0x65, 0x74, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x73, 0x41, - 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0x46, 0x0a, 0x12, 0x44, 0x6f, 0x77, 0x6e, 0x6c, 0x6f, 0x61, - 0x64, 0x4c, 0x6f, 0x67, 0x73, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x30, 0x0a, 0x0e, 0x62, - 0x61, 0x74, 0x63, 0x68, 0x5f, 0x6c, 0x6f, 0x67, 0x5f, 0x75, 0x75, 0x69, 0x64, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x09, 0x42, 0x0a, 0xba, 0x48, 0x07, 0x72, 0x05, 0x10, 0x01, 0x18, 0x80, 0x01, 0x52, - 0x0c, 0x62, 0x61, 0x74, 0x63, 0x68, 0x4c, 0x6f, 0x67, 0x55, 0x75, 0x69, 0x64, 0x22, 0xc9, 0x02, - 0x0a, 0x14, 0x4e, 0x6f, 0x64, 0x65, 0x45, 0x6e, 0x63, 0x72, 0x79, 0x70, 0x74, 0x65, 0x64, 0x50, - 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x12, 0xb1, 0x01, 0x0a, 0x09, 0x61, 0x6c, 0x67, 0x6f, 0x72, - 0x69, 0x74, 0x68, 0x6d, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x92, 0x01, 0xba, 0x48, 0x8e, - 0x01, 0xba, 0x01, 0x84, 0x01, 0x0a, 0x20, 0x6e, 0x6f, 0x64, 0x65, 0x5f, 0x65, 0x6e, 0x63, 0x72, - 0x79, 0x70, 0x74, 0x65, 0x64, 0x5f, 0x70, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x2e, 0x61, 0x6c, - 0x67, 0x6f, 0x72, 0x69, 0x74, 0x68, 0x6d, 0x12, 0x33, 0x61, 0x6c, 0x67, 0x6f, 0x72, 0x69, 0x74, - 0x68, 0x6d, 0x20, 0x6d, 0x75, 0x73, 0x74, 0x20, 0x62, 0x65, 0x20, 0x78, 0x32, 0x35, 0x35, 0x31, - 0x39, 0x2d, 0x68, 0x6b, 0x64, 0x66, 0x2d, 0x73, 0x68, 0x61, 0x32, 0x35, 0x36, 0x2d, 0x61, 0x65, - 0x73, 0x2d, 0x32, 0x35, 0x36, 0x2d, 0x67, 0x63, 0x6d, 0x2d, 0x76, 0x31, 0x1a, 0x2b, 0x74, 0x68, - 0x69, 0x73, 0x20, 0x3d, 0x3d, 0x20, 0x27, 0x78, 0x32, 0x35, 0x35, 0x31, 0x39, 0x2d, 0x68, 0x6b, - 0x64, 0x66, 0x2d, 0x73, 0x68, 0x61, 0x32, 0x35, 0x36, 0x2d, 0x61, 0x65, 0x73, 0x2d, 0x32, 0x35, - 0x36, 0x2d, 0x67, 0x63, 0x6d, 0x2d, 0x76, 0x31, 0x27, 0x72, 0x04, 0x10, 0x01, 0x18, 0x40, 0x52, - 0x09, 0x61, 0x6c, 0x67, 0x6f, 0x72, 0x69, 0x74, 0x68, 0x6d, 0x12, 0x32, 0x0a, 0x10, 0x65, 0x70, - 0x68, 0x65, 0x6d, 0x65, 0x72, 0x61, 0x6c, 0x5f, 0x70, 0x75, 0x62, 0x6b, 0x65, 0x79, 0x18, 0x02, - 0x20, 0x01, 0x28, 0x0c, 0x42, 0x07, 0xba, 0x48, 0x04, 0x7a, 0x02, 0x68, 0x20, 0x52, 0x0f, 0x65, - 0x70, 0x68, 0x65, 0x6d, 0x65, 0x72, 0x61, 0x6c, 0x50, 0x75, 0x62, 0x6b, 0x65, 0x79, 0x12, 0x1d, - 0x0a, 0x05, 0x6e, 0x6f, 0x6e, 0x63, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x42, 0x07, 0xba, - 0x48, 0x04, 0x7a, 0x02, 0x68, 0x0c, 0x52, 0x05, 0x6e, 0x6f, 0x6e, 0x63, 0x65, 0x12, 0x2a, 0x0a, - 0x0a, 0x63, 0x69, 0x70, 0x68, 0x65, 0x72, 0x74, 0x65, 0x78, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, - 0x0c, 0x42, 0x0a, 0xba, 0x48, 0x07, 0x7a, 0x05, 0x10, 0x11, 0x18, 0x80, 0x40, 0x52, 0x0a, 0x63, - 0x69, 0x70, 0x68, 0x65, 0x72, 0x74, 0x65, 0x78, 0x74, 0x22, 0x8a, 0x01, 0x0a, 0x19, 0x55, 0x70, - 0x64, 0x61, 0x74, 0x65, 0x4d, 0x69, 0x6e, 0x65, 0x72, 0x50, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, - 0x64, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x6d, 0x0a, 0x19, 0x65, 0x6e, 0x63, 0x72, 0x79, - 0x70, 0x74, 0x65, 0x64, 0x5f, 0x70, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x5f, 0x75, 0x70, - 0x64, 0x61, 0x74, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x29, 0x2e, 0x66, 0x6c, 0x65, - 0x65, 0x74, 0x6e, 0x6f, 0x64, 0x65, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x2e, 0x76, 0x31, - 0x2e, 0x4e, 0x6f, 0x64, 0x65, 0x45, 0x6e, 0x63, 0x72, 0x79, 0x70, 0x74, 0x65, 0x64, 0x50, 0x61, - 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x42, 0x06, 0xba, 0x48, 0x03, 0xc8, 0x01, 0x01, 0x52, 0x17, 0x65, - 0x6e, 0x63, 0x72, 0x79, 0x70, 0x74, 0x65, 0x64, 0x50, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, - 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x22, 0x83, 0x01, 0x0a, 0x19, 0x55, 0x70, 0x64, 0x61, 0x74, - 0x65, 0x4d, 0x69, 0x6e, 0x65, 0x72, 0x50, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x52, 0x65, - 0x73, 0x75, 0x6c, 0x74, 0x12, 0x66, 0x0a, 0x15, 0x65, 0x6e, 0x63, 0x72, 0x79, 0x70, 0x74, 0x65, - 0x64, 0x5f, 0x63, 0x72, 0x65, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x61, 0x6c, 0x73, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x0b, 0x32, 0x29, 0x2e, 0x66, 0x6c, 0x65, 0x65, 0x74, 0x6e, 0x6f, 0x64, 0x65, 0x67, - 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x2e, 0x76, 0x31, 0x2e, 0x45, 0x6e, 0x63, 0x72, 0x79, 0x70, - 0x74, 0x65, 0x64, 0x43, 0x72, 0x65, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x61, 0x6c, 0x73, 0x42, 0x06, - 0xba, 0x48, 0x03, 0xc8, 0x01, 0x01, 0x52, 0x14, 0x65, 0x6e, 0x63, 0x72, 0x79, 0x70, 0x74, 0x65, - 0x64, 0x43, 0x72, 0x65, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x61, 0x6c, 0x73, 0x22, 0x47, 0x0a, 0x0d, - 0x43, 0x75, 0x72, 0x74, 0x61, 0x69, 0x6c, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x36, 0x0a, - 0x05, 0x6c, 0x65, 0x76, 0x65, 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x20, 0x2e, 0x63, - 0x75, 0x72, 0x74, 0x61, 0x69, 0x6c, 0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x75, - 0x72, 0x74, 0x61, 0x69, 0x6c, 0x6d, 0x65, 0x6e, 0x74, 0x4c, 0x65, 0x76, 0x65, 0x6c, 0x52, 0x05, - 0x6c, 0x65, 0x76, 0x65, 0x6c, 0x22, 0x42, 0x0a, 0x14, 0x53, 0x65, 0x74, 0x43, 0x6f, 0x6f, 0x6c, - 0x69, 0x6e, 0x67, 0x4d, 0x6f, 0x64, 0x65, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x2a, 0x0a, - 0x04, 0x6d, 0x6f, 0x64, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x16, 0x2e, 0x63, 0x6f, - 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x6f, 0x6f, 0x6c, 0x69, 0x6e, 0x67, 0x4d, - 0x6f, 0x64, 0x65, 0x52, 0x04, 0x6d, 0x6f, 0x64, 0x65, 0x22, 0x63, 0x0a, 0x14, 0x53, 0x65, 0x74, - 0x50, 0x6f, 0x77, 0x65, 0x72, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x41, 0x63, 0x74, 0x69, 0x6f, - 0x6e, 0x12, 0x4b, 0x0a, 0x10, 0x70, 0x65, 0x72, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x6e, 0x63, 0x65, - 0x5f, 0x6d, 0x6f, 0x64, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x20, 0x2e, 0x6d, 0x69, - 0x6e, 0x65, 0x72, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x65, - 0x72, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x6e, 0x63, 0x65, 0x4d, 0x6f, 0x64, 0x65, 0x52, 0x0f, 0x70, - 0x65, 0x72, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x6e, 0x63, 0x65, 0x4d, 0x6f, 0x64, 0x65, 0x22, 0x9e, - 0x03, 0x0a, 0x10, 0x4d, 0x69, 0x6e, 0x69, 0x6e, 0x67, 0x50, 0x6f, 0x6f, 0x6c, 0x43, 0x6f, 0x6e, - 0x66, 0x69, 0x67, 0x12, 0x25, 0x0a, 0x08, 0x70, 0x72, 0x69, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x05, 0x42, 0x09, 0xba, 0x48, 0x06, 0x1a, 0x04, 0x18, 0x02, 0x28, 0x00, - 0x52, 0x08, 0x70, 0x72, 0x69, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x12, 0xbc, 0x02, 0x0a, 0x03, 0x75, - 0x72, 0x6c, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x42, 0xa9, 0x02, 0xba, 0x48, 0xa5, 0x02, 0x72, - 0xa2, 0x02, 0x10, 0x0c, 0x18, 0x80, 0x02, 0x32, 0x9a, 0x02, 0x5e, 0x28, 0x73, 0x74, 0x72, 0x61, - 0x74, 0x75, 0x6d, 0x5c, 0x2b, 0x28, 0x74, 0x63, 0x70, 0x7c, 0x73, 0x73, 0x6c, 0x7c, 0x77, 0x73, - 0x29, 0x3a, 0x5c, 0x2f, 0x5c, 0x2f, 0x28, 0x28, 0x5b, 0x61, 0x2d, 0x7a, 0x41, 0x2d, 0x5a, 0x30, - 0x2d, 0x39, 0x5d, 0x5b, 0x61, 0x2d, 0x7a, 0x41, 0x2d, 0x5a, 0x30, 0x2d, 0x39, 0x2e, 0x2d, 0x5d, - 0x2a, 0x5b, 0x61, 0x2d, 0x7a, 0x41, 0x2d, 0x5a, 0x30, 0x2d, 0x39, 0x5d, 0x5c, 0x2e, 0x5b, 0x61, - 0x2d, 0x7a, 0x41, 0x2d, 0x5a, 0x5d, 0x7b, 0x32, 0x2c, 0x7d, 0x29, 0x7c, 0x28, 0x5c, 0x64, 0x7b, - 0x31, 0x2c, 0x33, 0x7d, 0x5c, 0x2e, 0x29, 0x7b, 0x33, 0x7d, 0x5c, 0x64, 0x7b, 0x31, 0x2c, 0x33, - 0x7d, 0x7c, 0x5c, 0x5b, 0x28, 0x5b, 0x30, 0x2d, 0x39, 0x61, 0x2d, 0x66, 0x41, 0x2d, 0x46, 0x3a, - 0x5d, 0x2b, 0x29, 0x5c, 0x5d, 0x29, 0x28, 0x3a, 0x5c, 0x64, 0x7b, 0x31, 0x2c, 0x35, 0x7d, 0x29, - 0x3f, 0x7c, 0x73, 0x74, 0x72, 0x61, 0x74, 0x75, 0x6d, 0x32, 0x5c, 0x2b, 0x74, 0x63, 0x70, 0x3a, - 0x5c, 0x2f, 0x5c, 0x2f, 0x28, 0x28, 0x5b, 0x61, 0x2d, 0x7a, 0x41, 0x2d, 0x5a, 0x30, 0x2d, 0x39, - 0x5d, 0x5b, 0x61, 0x2d, 0x7a, 0x41, 0x2d, 0x5a, 0x30, 0x2d, 0x39, 0x2e, 0x2d, 0x5d, 0x2a, 0x5b, - 0x61, 0x2d, 0x7a, 0x41, 0x2d, 0x5a, 0x30, 0x2d, 0x39, 0x5d, 0x5c, 0x2e, 0x5b, 0x61, 0x2d, 0x7a, - 0x41, 0x2d, 0x5a, 0x5d, 0x7b, 0x32, 0x2c, 0x7d, 0x29, 0x7c, 0x28, 0x5c, 0x64, 0x7b, 0x31, 0x2c, - 0x33, 0x7d, 0x5c, 0x2e, 0x29, 0x7b, 0x33, 0x7d, 0x5c, 0x64, 0x7b, 0x31, 0x2c, 0x33, 0x7d, 0x7c, - 0x5c, 0x5b, 0x28, 0x5b, 0x30, 0x2d, 0x39, 0x61, 0x2d, 0x66, 0x41, 0x2d, 0x46, 0x3a, 0x5d, 0x2b, - 0x29, 0x5c, 0x5d, 0x29, 0x3a, 0x5c, 0x64, 0x7b, 0x31, 0x2c, 0x35, 0x7d, 0x5c, 0x2f, 0x5b, 0x41, - 0x2d, 0x5a, 0x61, 0x2d, 0x7a, 0x30, 0x2d, 0x39, 0x5f, 0x2b, 0x5c, 0x2f, 0x3d, 0x3a, 0x2e, 0x2d, - 0x5d, 0x2b, 0x29, 0x24, 0x52, 0x03, 0x75, 0x72, 0x6c, 0x12, 0x24, 0x0a, 0x08, 0x75, 0x73, 0x65, - 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x42, 0x08, 0xba, 0x48, 0x05, - 0x72, 0x03, 0x18, 0x80, 0x04, 0x52, 0x08, 0x75, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x22, - 0x62, 0x0a, 0x17, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x4d, 0x69, 0x6e, 0x69, 0x6e, 0x67, 0x50, - 0x6f, 0x6f, 0x6c, 0x73, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x47, 0x0a, 0x05, 0x70, 0x6f, + 0x6f, 0x77, 0x6e, 0x6c, 0x6f, 0x61, 0x64, 0x4c, 0x6f, 0x67, 0x73, 0x12, 0x54, 0x0a, 0x0f, 0x66, + 0x69, 0x72, 0x6d, 0x77, 0x61, 0x72, 0x65, 0x5f, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x18, 0x0f, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x29, 0x2e, 0x66, 0x6c, 0x65, 0x65, 0x74, 0x6e, 0x6f, 0x64, 0x65, + 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x2e, 0x76, 0x31, 0x2e, 0x46, 0x69, 0x72, 0x6d, 0x77, + 0x61, 0x72, 0x65, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x48, + 0x00, 0x52, 0x0e, 0x66, 0x69, 0x72, 0x6d, 0x77, 0x61, 0x72, 0x65, 0x55, 0x70, 0x64, 0x61, 0x74, + 0x65, 0x12, 0x71, 0x0a, 0x1a, 0x67, 0x65, 0x74, 0x5f, 0x66, 0x69, 0x72, 0x6d, 0x77, 0x61, 0x72, + 0x65, 0x5f, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, + 0x10, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x32, 0x2e, 0x66, 0x6c, 0x65, 0x65, 0x74, 0x6e, 0x6f, 0x64, + 0x65, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x46, + 0x69, 0x72, 0x6d, 0x77, 0x61, 0x72, 0x65, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x53, 0x74, 0x61, + 0x74, 0x75, 0x73, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x48, 0x00, 0x52, 0x17, 0x67, 0x65, 0x74, + 0x46, 0x69, 0x72, 0x6d, 0x77, 0x61, 0x72, 0x65, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x53, 0x74, + 0x61, 0x74, 0x75, 0x73, 0x42, 0x0f, 0x0a, 0x06, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x05, + 0xba, 0x48, 0x02, 0x08, 0x01, 0x22, 0x0e, 0x0a, 0x0c, 0x52, 0x65, 0x62, 0x6f, 0x6f, 0x74, 0x41, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0x13, 0x0a, 0x11, 0x53, 0x74, 0x61, 0x72, 0x74, 0x4d, 0x69, + 0x6e, 0x69, 0x6e, 0x67, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0x12, 0x0a, 0x10, 0x53, 0x74, + 0x6f, 0x70, 0x4d, 0x69, 0x6e, 0x69, 0x6e, 0x67, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0x10, + 0x0a, 0x0e, 0x42, 0x6c, 0x69, 0x6e, 0x6b, 0x4c, 0x65, 0x64, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x22, 0x11, 0x0a, 0x0f, 0x55, 0x6e, 0x63, 0x75, 0x72, 0x74, 0x61, 0x69, 0x6c, 0x41, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x22, 0x16, 0x0a, 0x14, 0x47, 0x65, 0x74, 0x4d, 0x69, 0x6e, 0x69, 0x6e, 0x67, + 0x50, 0x6f, 0x6f, 0x6c, 0x73, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0x11, 0x0a, 0x0f, 0x47, + 0x65, 0x74, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x73, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0x1f, + 0x0a, 0x1d, 0x47, 0x65, 0x74, 0x46, 0x69, 0x72, 0x6d, 0x77, 0x61, 0x72, 0x65, 0x55, 0x70, 0x64, + 0x61, 0x74, 0x65, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x22, + 0x46, 0x0a, 0x12, 0x44, 0x6f, 0x77, 0x6e, 0x6c, 0x6f, 0x61, 0x64, 0x4c, 0x6f, 0x67, 0x73, 0x41, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x30, 0x0a, 0x0e, 0x62, 0x61, 0x74, 0x63, 0x68, 0x5f, 0x6c, + 0x6f, 0x67, 0x5f, 0x75, 0x75, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x0a, 0xba, + 0x48, 0x07, 0x72, 0x05, 0x10, 0x01, 0x18, 0x80, 0x01, 0x52, 0x0c, 0x62, 0x61, 0x74, 0x63, 0x68, + 0x4c, 0x6f, 0x67, 0x55, 0x75, 0x69, 0x64, 0x22, 0xc9, 0x02, 0x0a, 0x14, 0x4e, 0x6f, 0x64, 0x65, + 0x45, 0x6e, 0x63, 0x72, 0x79, 0x70, 0x74, 0x65, 0x64, 0x50, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, + 0x12, 0xb1, 0x01, 0x0a, 0x09, 0x61, 0x6c, 0x67, 0x6f, 0x72, 0x69, 0x74, 0x68, 0x6d, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x09, 0x42, 0x92, 0x01, 0xba, 0x48, 0x8e, 0x01, 0xba, 0x01, 0x84, 0x01, 0x0a, + 0x20, 0x6e, 0x6f, 0x64, 0x65, 0x5f, 0x65, 0x6e, 0x63, 0x72, 0x79, 0x70, 0x74, 0x65, 0x64, 0x5f, + 0x70, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x2e, 0x61, 0x6c, 0x67, 0x6f, 0x72, 0x69, 0x74, 0x68, + 0x6d, 0x12, 0x33, 0x61, 0x6c, 0x67, 0x6f, 0x72, 0x69, 0x74, 0x68, 0x6d, 0x20, 0x6d, 0x75, 0x73, + 0x74, 0x20, 0x62, 0x65, 0x20, 0x78, 0x32, 0x35, 0x35, 0x31, 0x39, 0x2d, 0x68, 0x6b, 0x64, 0x66, + 0x2d, 0x73, 0x68, 0x61, 0x32, 0x35, 0x36, 0x2d, 0x61, 0x65, 0x73, 0x2d, 0x32, 0x35, 0x36, 0x2d, + 0x67, 0x63, 0x6d, 0x2d, 0x76, 0x31, 0x1a, 0x2b, 0x74, 0x68, 0x69, 0x73, 0x20, 0x3d, 0x3d, 0x20, + 0x27, 0x78, 0x32, 0x35, 0x35, 0x31, 0x39, 0x2d, 0x68, 0x6b, 0x64, 0x66, 0x2d, 0x73, 0x68, 0x61, + 0x32, 0x35, 0x36, 0x2d, 0x61, 0x65, 0x73, 0x2d, 0x32, 0x35, 0x36, 0x2d, 0x67, 0x63, 0x6d, 0x2d, + 0x76, 0x31, 0x27, 0x72, 0x04, 0x10, 0x01, 0x18, 0x40, 0x52, 0x09, 0x61, 0x6c, 0x67, 0x6f, 0x72, + 0x69, 0x74, 0x68, 0x6d, 0x12, 0x32, 0x0a, 0x10, 0x65, 0x70, 0x68, 0x65, 0x6d, 0x65, 0x72, 0x61, + 0x6c, 0x5f, 0x70, 0x75, 0x62, 0x6b, 0x65, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x42, 0x07, + 0xba, 0x48, 0x04, 0x7a, 0x02, 0x68, 0x20, 0x52, 0x0f, 0x65, 0x70, 0x68, 0x65, 0x6d, 0x65, 0x72, + 0x61, 0x6c, 0x50, 0x75, 0x62, 0x6b, 0x65, 0x79, 0x12, 0x1d, 0x0a, 0x05, 0x6e, 0x6f, 0x6e, 0x63, + 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x42, 0x07, 0xba, 0x48, 0x04, 0x7a, 0x02, 0x68, 0x0c, + 0x52, 0x05, 0x6e, 0x6f, 0x6e, 0x63, 0x65, 0x12, 0x2a, 0x0a, 0x0a, 0x63, 0x69, 0x70, 0x68, 0x65, + 0x72, 0x74, 0x65, 0x78, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0c, 0x42, 0x0a, 0xba, 0x48, 0x07, + 0x7a, 0x05, 0x10, 0x11, 0x18, 0x80, 0x40, 0x52, 0x0a, 0x63, 0x69, 0x70, 0x68, 0x65, 0x72, 0x74, + 0x65, 0x78, 0x74, 0x22, 0x8a, 0x01, 0x0a, 0x19, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x4d, 0x69, + 0x6e, 0x65, 0x72, 0x50, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x41, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x12, 0x6d, 0x0a, 0x19, 0x65, 0x6e, 0x63, 0x72, 0x79, 0x70, 0x74, 0x65, 0x64, 0x5f, 0x70, + 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x5f, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x29, 0x2e, 0x66, 0x6c, 0x65, 0x65, 0x74, 0x6e, 0x6f, 0x64, 0x65, + 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x2e, 0x76, 0x31, 0x2e, 0x4e, 0x6f, 0x64, 0x65, 0x45, + 0x6e, 0x63, 0x72, 0x79, 0x70, 0x74, 0x65, 0x64, 0x50, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x42, + 0x06, 0xba, 0x48, 0x03, 0xc8, 0x01, 0x01, 0x52, 0x17, 0x65, 0x6e, 0x63, 0x72, 0x79, 0x70, 0x74, + 0x65, 0x64, 0x50, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, + 0x22, 0x83, 0x01, 0x0a, 0x19, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x4d, 0x69, 0x6e, 0x65, 0x72, + 0x50, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x12, 0x66, + 0x0a, 0x15, 0x65, 0x6e, 0x63, 0x72, 0x79, 0x70, 0x74, 0x65, 0x64, 0x5f, 0x63, 0x72, 0x65, 0x64, + 0x65, 0x6e, 0x74, 0x69, 0x61, 0x6c, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x29, 0x2e, + 0x66, 0x6c, 0x65, 0x65, 0x74, 0x6e, 0x6f, 0x64, 0x65, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, + 0x2e, 0x76, 0x31, 0x2e, 0x45, 0x6e, 0x63, 0x72, 0x79, 0x70, 0x74, 0x65, 0x64, 0x43, 0x72, 0x65, + 0x64, 0x65, 0x6e, 0x74, 0x69, 0x61, 0x6c, 0x73, 0x42, 0x06, 0xba, 0x48, 0x03, 0xc8, 0x01, 0x01, + 0x52, 0x14, 0x65, 0x6e, 0x63, 0x72, 0x79, 0x70, 0x74, 0x65, 0x64, 0x43, 0x72, 0x65, 0x64, 0x65, + 0x6e, 0x74, 0x69, 0x61, 0x6c, 0x73, 0x22, 0x63, 0x0a, 0x14, 0x46, 0x69, 0x72, 0x6d, 0x77, 0x61, + 0x72, 0x65, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x4b, + 0x0a, 0x08, 0x61, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x27, 0x2e, 0x66, 0x6c, 0x65, 0x65, 0x74, 0x6e, 0x6f, 0x64, 0x65, 0x67, 0x61, 0x74, 0x65, + 0x77, 0x61, 0x79, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x41, 0x72, + 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x52, 0x65, 0x66, 0x42, 0x06, 0xba, 0x48, 0x03, 0xc8, 0x01, + 0x01, 0x52, 0x08, 0x61, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x22, 0x47, 0x0a, 0x0d, 0x43, + 0x75, 0x72, 0x74, 0x61, 0x69, 0x6c, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x36, 0x0a, 0x05, + 0x6c, 0x65, 0x76, 0x65, 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x20, 0x2e, 0x63, 0x75, + 0x72, 0x74, 0x61, 0x69, 0x6c, 0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x75, 0x72, + 0x74, 0x61, 0x69, 0x6c, 0x6d, 0x65, 0x6e, 0x74, 0x4c, 0x65, 0x76, 0x65, 0x6c, 0x52, 0x05, 0x6c, + 0x65, 0x76, 0x65, 0x6c, 0x22, 0x42, 0x0a, 0x14, 0x53, 0x65, 0x74, 0x43, 0x6f, 0x6f, 0x6c, 0x69, + 0x6e, 0x67, 0x4d, 0x6f, 0x64, 0x65, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x2a, 0x0a, 0x04, + 0x6d, 0x6f, 0x64, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x16, 0x2e, 0x63, 0x6f, 0x6d, + 0x6d, 0x6f, 0x6e, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x6f, 0x6f, 0x6c, 0x69, 0x6e, 0x67, 0x4d, 0x6f, + 0x64, 0x65, 0x52, 0x04, 0x6d, 0x6f, 0x64, 0x65, 0x22, 0x63, 0x0a, 0x14, 0x53, 0x65, 0x74, 0x50, + 0x6f, 0x77, 0x65, 0x72, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x12, 0x4b, 0x0a, 0x10, 0x70, 0x65, 0x72, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x6e, 0x63, 0x65, 0x5f, + 0x6d, 0x6f, 0x64, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x20, 0x2e, 0x6d, 0x69, 0x6e, + 0x65, 0x72, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x65, 0x72, + 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x6e, 0x63, 0x65, 0x4d, 0x6f, 0x64, 0x65, 0x52, 0x0f, 0x70, 0x65, + 0x72, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x6e, 0x63, 0x65, 0x4d, 0x6f, 0x64, 0x65, 0x22, 0x9e, 0x03, + 0x0a, 0x10, 0x4d, 0x69, 0x6e, 0x69, 0x6e, 0x67, 0x50, 0x6f, 0x6f, 0x6c, 0x43, 0x6f, 0x6e, 0x66, + 0x69, 0x67, 0x12, 0x25, 0x0a, 0x08, 0x70, 0x72, 0x69, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x05, 0x42, 0x09, 0xba, 0x48, 0x06, 0x1a, 0x04, 0x18, 0x02, 0x28, 0x00, 0x52, + 0x08, 0x70, 0x72, 0x69, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x12, 0xbc, 0x02, 0x0a, 0x03, 0x75, 0x72, + 0x6c, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x42, 0xa9, 0x02, 0xba, 0x48, 0xa5, 0x02, 0x72, 0xa2, + 0x02, 0x10, 0x0c, 0x18, 0x80, 0x02, 0x32, 0x9a, 0x02, 0x5e, 0x28, 0x73, 0x74, 0x72, 0x61, 0x74, + 0x75, 0x6d, 0x5c, 0x2b, 0x28, 0x74, 0x63, 0x70, 0x7c, 0x73, 0x73, 0x6c, 0x7c, 0x77, 0x73, 0x29, + 0x3a, 0x5c, 0x2f, 0x5c, 0x2f, 0x28, 0x28, 0x5b, 0x61, 0x2d, 0x7a, 0x41, 0x2d, 0x5a, 0x30, 0x2d, + 0x39, 0x5d, 0x5b, 0x61, 0x2d, 0x7a, 0x41, 0x2d, 0x5a, 0x30, 0x2d, 0x39, 0x2e, 0x2d, 0x5d, 0x2a, + 0x5b, 0x61, 0x2d, 0x7a, 0x41, 0x2d, 0x5a, 0x30, 0x2d, 0x39, 0x5d, 0x5c, 0x2e, 0x5b, 0x61, 0x2d, + 0x7a, 0x41, 0x2d, 0x5a, 0x5d, 0x7b, 0x32, 0x2c, 0x7d, 0x29, 0x7c, 0x28, 0x5c, 0x64, 0x7b, 0x31, + 0x2c, 0x33, 0x7d, 0x5c, 0x2e, 0x29, 0x7b, 0x33, 0x7d, 0x5c, 0x64, 0x7b, 0x31, 0x2c, 0x33, 0x7d, + 0x7c, 0x5c, 0x5b, 0x28, 0x5b, 0x30, 0x2d, 0x39, 0x61, 0x2d, 0x66, 0x41, 0x2d, 0x46, 0x3a, 0x5d, + 0x2b, 0x29, 0x5c, 0x5d, 0x29, 0x28, 0x3a, 0x5c, 0x64, 0x7b, 0x31, 0x2c, 0x35, 0x7d, 0x29, 0x3f, + 0x7c, 0x73, 0x74, 0x72, 0x61, 0x74, 0x75, 0x6d, 0x32, 0x5c, 0x2b, 0x74, 0x63, 0x70, 0x3a, 0x5c, + 0x2f, 0x5c, 0x2f, 0x28, 0x28, 0x5b, 0x61, 0x2d, 0x7a, 0x41, 0x2d, 0x5a, 0x30, 0x2d, 0x39, 0x5d, + 0x5b, 0x61, 0x2d, 0x7a, 0x41, 0x2d, 0x5a, 0x30, 0x2d, 0x39, 0x2e, 0x2d, 0x5d, 0x2a, 0x5b, 0x61, + 0x2d, 0x7a, 0x41, 0x2d, 0x5a, 0x30, 0x2d, 0x39, 0x5d, 0x5c, 0x2e, 0x5b, 0x61, 0x2d, 0x7a, 0x41, + 0x2d, 0x5a, 0x5d, 0x7b, 0x32, 0x2c, 0x7d, 0x29, 0x7c, 0x28, 0x5c, 0x64, 0x7b, 0x31, 0x2c, 0x33, + 0x7d, 0x5c, 0x2e, 0x29, 0x7b, 0x33, 0x7d, 0x5c, 0x64, 0x7b, 0x31, 0x2c, 0x33, 0x7d, 0x7c, 0x5c, + 0x5b, 0x28, 0x5b, 0x30, 0x2d, 0x39, 0x61, 0x2d, 0x66, 0x41, 0x2d, 0x46, 0x3a, 0x5d, 0x2b, 0x29, + 0x5c, 0x5d, 0x29, 0x3a, 0x5c, 0x64, 0x7b, 0x31, 0x2c, 0x35, 0x7d, 0x5c, 0x2f, 0x5b, 0x41, 0x2d, + 0x5a, 0x61, 0x2d, 0x7a, 0x30, 0x2d, 0x39, 0x5f, 0x2b, 0x5c, 0x2f, 0x3d, 0x3a, 0x2e, 0x2d, 0x5d, + 0x2b, 0x29, 0x24, 0x52, 0x03, 0x75, 0x72, 0x6c, 0x12, 0x24, 0x0a, 0x08, 0x75, 0x73, 0x65, 0x72, + 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x42, 0x08, 0xba, 0x48, 0x05, 0x72, + 0x03, 0x18, 0x80, 0x04, 0x52, 0x08, 0x75, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x22, 0x62, + 0x0a, 0x17, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x4d, 0x69, 0x6e, 0x69, 0x6e, 0x67, 0x50, 0x6f, + 0x6f, 0x6c, 0x73, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x47, 0x0a, 0x05, 0x70, 0x6f, 0x6f, + 0x6c, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x25, 0x2e, 0x66, 0x6c, 0x65, 0x65, 0x74, + 0x6e, 0x6f, 0x64, 0x65, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x2e, 0x76, 0x31, 0x2e, 0x4d, + 0x69, 0x6e, 0x69, 0x6e, 0x67, 0x50, 0x6f, 0x6f, 0x6c, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x42, + 0x0a, 0xba, 0x48, 0x07, 0x92, 0x01, 0x04, 0x08, 0x01, 0x10, 0x03, 0x52, 0x05, 0x70, 0x6f, 0x6f, + 0x6c, 0x73, 0x22, 0x5d, 0x0a, 0x14, 0x47, 0x65, 0x74, 0x4d, 0x69, 0x6e, 0x69, 0x6e, 0x67, 0x50, + 0x6f, 0x6f, 0x6c, 0x73, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x12, 0x45, 0x0a, 0x05, 0x70, 0x6f, 0x6f, 0x6c, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x25, 0x2e, 0x66, 0x6c, 0x65, 0x65, 0x74, 0x6e, 0x6f, 0x64, 0x65, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x2e, 0x76, 0x31, 0x2e, 0x4d, 0x69, 0x6e, 0x69, 0x6e, 0x67, 0x50, 0x6f, 0x6f, 0x6c, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, - 0x42, 0x0a, 0xba, 0x48, 0x07, 0x92, 0x01, 0x04, 0x08, 0x01, 0x10, 0x03, 0x52, 0x05, 0x70, 0x6f, - 0x6f, 0x6c, 0x73, 0x22, 0x5d, 0x0a, 0x14, 0x47, 0x65, 0x74, 0x4d, 0x69, 0x6e, 0x69, 0x6e, 0x67, - 0x50, 0x6f, 0x6f, 0x6c, 0x73, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x12, 0x45, 0x0a, 0x05, 0x70, - 0x6f, 0x6f, 0x6c, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x25, 0x2e, 0x66, 0x6c, 0x65, - 0x65, 0x74, 0x6e, 0x6f, 0x64, 0x65, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x2e, 0x76, 0x31, - 0x2e, 0x4d, 0x69, 0x6e, 0x69, 0x6e, 0x67, 0x50, 0x6f, 0x6f, 0x6c, 0x43, 0x6f, 0x6e, 0x66, 0x69, - 0x67, 0x42, 0x08, 0xba, 0x48, 0x05, 0x92, 0x01, 0x02, 0x10, 0x03, 0x52, 0x05, 0x70, 0x6f, 0x6f, - 0x6c, 0x73, 0x22, 0xf5, 0x06, 0x0a, 0x10, 0x4d, 0x69, 0x6e, 0x65, 0x72, 0x45, 0x72, 0x72, 0x6f, - 0x72, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x12, 0x40, 0x0a, 0x0b, 0x6d, 0x69, 0x6e, 0x65, 0x72, - 0x5f, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x15, 0x2e, 0x65, - 0x72, 0x72, 0x6f, 0x72, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x4d, 0x69, 0x6e, 0x65, 0x72, 0x45, 0x72, - 0x72, 0x6f, 0x72, 0x42, 0x08, 0xba, 0x48, 0x05, 0x82, 0x01, 0x02, 0x10, 0x01, 0x52, 0x0a, 0x6d, - 0x69, 0x6e, 0x65, 0x72, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x12, 0x2d, 0x0a, 0x0d, 0x63, 0x61, 0x75, - 0x73, 0x65, 0x5f, 0x73, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, - 0x42, 0x08, 0xba, 0x48, 0x05, 0x72, 0x03, 0x18, 0x80, 0x20, 0x52, 0x0c, 0x63, 0x61, 0x75, 0x73, - 0x65, 0x53, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x12, 0x37, 0x0a, 0x12, 0x72, 0x65, 0x63, 0x6f, - 0x6d, 0x6d, 0x65, 0x6e, 0x64, 0x65, 0x64, 0x5f, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x03, - 0x20, 0x01, 0x28, 0x09, 0x42, 0x08, 0xba, 0x48, 0x05, 0x72, 0x03, 0x18, 0x80, 0x20, 0x52, 0x11, - 0x72, 0x65, 0x63, 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x64, 0x65, 0x64, 0x41, 0x63, 0x74, 0x69, 0x6f, - 0x6e, 0x12, 0x39, 0x0a, 0x08, 0x73, 0x65, 0x76, 0x65, 0x72, 0x69, 0x74, 0x79, 0x18, 0x04, 0x20, - 0x01, 0x28, 0x0e, 0x32, 0x13, 0x2e, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x73, 0x2e, 0x76, 0x31, 0x2e, - 0x53, 0x65, 0x76, 0x65, 0x72, 0x69, 0x74, 0x79, 0x42, 0x08, 0xba, 0x48, 0x05, 0x82, 0x01, 0x02, - 0x10, 0x01, 0x52, 0x08, 0x73, 0x65, 0x76, 0x65, 0x72, 0x69, 0x74, 0x79, 0x12, 0x3e, 0x0a, 0x0d, - 0x66, 0x69, 0x72, 0x73, 0x74, 0x5f, 0x73, 0x65, 0x65, 0x6e, 0x5f, 0x61, 0x74, 0x18, 0x05, 0x20, - 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, - 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, - 0x0b, 0x66, 0x69, 0x72, 0x73, 0x74, 0x53, 0x65, 0x65, 0x6e, 0x41, 0x74, 0x12, 0x3c, 0x0a, 0x0c, - 0x6c, 0x61, 0x73, 0x74, 0x5f, 0x73, 0x65, 0x65, 0x6e, 0x5f, 0x61, 0x74, 0x18, 0x06, 0x20, 0x01, - 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, - 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x0a, - 0x6c, 0x61, 0x73, 0x74, 0x53, 0x65, 0x65, 0x6e, 0x41, 0x74, 0x12, 0x37, 0x0a, 0x09, 0x63, 0x6c, - 0x6f, 0x73, 0x65, 0x64, 0x5f, 0x61, 0x74, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, + 0x42, 0x08, 0xba, 0x48, 0x05, 0x92, 0x01, 0x02, 0x10, 0x03, 0x52, 0x05, 0x70, 0x6f, 0x6f, 0x6c, + 0x73, 0x22, 0x98, 0x01, 0x0a, 0x1a, 0x46, 0x69, 0x72, 0x6d, 0x77, 0x61, 0x72, 0x65, 0x55, 0x70, + 0x64, 0x61, 0x74, 0x65, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, + 0x12, 0x1d, 0x0a, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, + 0x07, 0xba, 0x48, 0x04, 0x72, 0x02, 0x18, 0x40, 0x52, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x12, + 0x1f, 0x0a, 0x08, 0x70, 0x72, 0x6f, 0x67, 0x72, 0x65, 0x73, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, + 0x05, 0x48, 0x00, 0x52, 0x08, 0x70, 0x72, 0x6f, 0x67, 0x72, 0x65, 0x73, 0x73, 0x88, 0x01, 0x01, + 0x12, 0x23, 0x0a, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x42, + 0x08, 0xba, 0x48, 0x05, 0x72, 0x03, 0x18, 0x80, 0x20, 0x48, 0x01, 0x52, 0x05, 0x65, 0x72, 0x72, + 0x6f, 0x72, 0x88, 0x01, 0x01, 0x42, 0x0b, 0x0a, 0x09, 0x5f, 0x70, 0x72, 0x6f, 0x67, 0x72, 0x65, + 0x73, 0x73, 0x42, 0x08, 0x0a, 0x06, 0x5f, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x22, 0xf5, 0x06, 0x0a, + 0x10, 0x4d, 0x69, 0x6e, 0x65, 0x72, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x52, 0x65, 0x70, 0x6f, 0x72, + 0x74, 0x12, 0x40, 0x0a, 0x0b, 0x6d, 0x69, 0x6e, 0x65, 0x72, 0x5f, 0x65, 0x72, 0x72, 0x6f, 0x72, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x15, 0x2e, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x73, 0x2e, + 0x76, 0x31, 0x2e, 0x4d, 0x69, 0x6e, 0x65, 0x72, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x42, 0x08, 0xba, + 0x48, 0x05, 0x82, 0x01, 0x02, 0x10, 0x01, 0x52, 0x0a, 0x6d, 0x69, 0x6e, 0x65, 0x72, 0x45, 0x72, + 0x72, 0x6f, 0x72, 0x12, 0x2d, 0x0a, 0x0d, 0x63, 0x61, 0x75, 0x73, 0x65, 0x5f, 0x73, 0x75, 0x6d, + 0x6d, 0x61, 0x72, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x42, 0x08, 0xba, 0x48, 0x05, 0x72, + 0x03, 0x18, 0x80, 0x20, 0x52, 0x0c, 0x63, 0x61, 0x75, 0x73, 0x65, 0x53, 0x75, 0x6d, 0x6d, 0x61, + 0x72, 0x79, 0x12, 0x37, 0x0a, 0x12, 0x72, 0x65, 0x63, 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x64, 0x65, + 0x64, 0x5f, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x42, 0x08, + 0xba, 0x48, 0x05, 0x72, 0x03, 0x18, 0x80, 0x20, 0x52, 0x11, 0x72, 0x65, 0x63, 0x6f, 0x6d, 0x6d, + 0x65, 0x6e, 0x64, 0x65, 0x64, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x39, 0x0a, 0x08, 0x73, + 0x65, 0x76, 0x65, 0x72, 0x69, 0x74, 0x79, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x13, 0x2e, + 0x65, 0x72, 0x72, 0x6f, 0x72, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x65, 0x76, 0x65, 0x72, 0x69, + 0x74, 0x79, 0x42, 0x08, 0xba, 0x48, 0x05, 0x82, 0x01, 0x02, 0x10, 0x01, 0x52, 0x08, 0x73, 0x65, + 0x76, 0x65, 0x72, 0x69, 0x74, 0x79, 0x12, 0x3e, 0x0a, 0x0d, 0x66, 0x69, 0x72, 0x73, 0x74, 0x5f, + 0x73, 0x65, 0x65, 0x6e, 0x5f, 0x61, 0x74, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, - 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x08, 0x63, 0x6c, 0x6f, 0x73, 0x65, - 0x64, 0x41, 0x74, 0x12, 0x82, 0x01, 0x0a, 0x11, 0x76, 0x65, 0x6e, 0x64, 0x6f, 0x72, 0x5f, 0x61, - 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x18, 0x08, 0x20, 0x03, 0x28, 0x0b, 0x32, - 0x3b, 0x2e, 0x66, 0x6c, 0x65, 0x65, 0x74, 0x6e, 0x6f, 0x64, 0x65, 0x67, 0x61, 0x74, 0x65, 0x77, - 0x61, 0x79, 0x2e, 0x76, 0x31, 0x2e, 0x4d, 0x69, 0x6e, 0x65, 0x72, 0x45, 0x72, 0x72, 0x6f, 0x72, - 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x56, 0x65, 0x6e, 0x64, 0x6f, 0x72, 0x41, 0x74, 0x74, - 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x42, 0x18, 0xba, 0x48, - 0x15, 0x9a, 0x01, 0x12, 0x10, 0x20, 0x22, 0x07, 0x72, 0x05, 0x10, 0x01, 0x18, 0x80, 0x01, 0x2a, - 0x05, 0x72, 0x03, 0x18, 0x80, 0x08, 0x52, 0x10, 0x76, 0x65, 0x6e, 0x64, 0x6f, 0x72, 0x41, 0x74, - 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x12, 0x27, 0x0a, 0x09, 0x64, 0x65, 0x76, 0x69, - 0x63, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x09, 0x20, 0x01, 0x28, 0x09, 0x42, 0x0a, 0xba, 0x48, 0x07, + 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x0b, 0x66, 0x69, 0x72, 0x73, 0x74, + 0x53, 0x65, 0x65, 0x6e, 0x41, 0x74, 0x12, 0x3c, 0x0a, 0x0c, 0x6c, 0x61, 0x73, 0x74, 0x5f, 0x73, + 0x65, 0x65, 0x6e, 0x5f, 0x61, 0x74, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, + 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, + 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x0a, 0x6c, 0x61, 0x73, 0x74, 0x53, 0x65, + 0x65, 0x6e, 0x41, 0x74, 0x12, 0x37, 0x0a, 0x09, 0x63, 0x6c, 0x6f, 0x73, 0x65, 0x64, 0x5f, 0x61, + 0x74, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, + 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, + 0x61, 0x6d, 0x70, 0x52, 0x08, 0x63, 0x6c, 0x6f, 0x73, 0x65, 0x64, 0x41, 0x74, 0x12, 0x82, 0x01, + 0x0a, 0x11, 0x76, 0x65, 0x6e, 0x64, 0x6f, 0x72, 0x5f, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, + 0x74, 0x65, 0x73, 0x18, 0x08, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x3b, 0x2e, 0x66, 0x6c, 0x65, 0x65, + 0x74, 0x6e, 0x6f, 0x64, 0x65, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x2e, 0x76, 0x31, 0x2e, + 0x4d, 0x69, 0x6e, 0x65, 0x72, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, + 0x2e, 0x56, 0x65, 0x6e, 0x64, 0x6f, 0x72, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, + 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x42, 0x18, 0xba, 0x48, 0x15, 0x9a, 0x01, 0x12, 0x10, 0x20, + 0x22, 0x07, 0x72, 0x05, 0x10, 0x01, 0x18, 0x80, 0x01, 0x2a, 0x05, 0x72, 0x03, 0x18, 0x80, 0x08, + 0x52, 0x10, 0x76, 0x65, 0x6e, 0x64, 0x6f, 0x72, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, + 0x65, 0x73, 0x12, 0x27, 0x0a, 0x09, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x18, + 0x09, 0x20, 0x01, 0x28, 0x09, 0x42, 0x0a, 0xba, 0x48, 0x07, 0x72, 0x05, 0x10, 0x01, 0x18, 0xff, + 0x01, 0x52, 0x08, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x49, 0x64, 0x12, 0x30, 0x0a, 0x0c, 0x63, + 0x6f, 0x6d, 0x70, 0x6f, 0x6e, 0x65, 0x6e, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x0a, 0x20, 0x01, 0x28, + 0x09, 0x42, 0x08, 0xba, 0x48, 0x05, 0x72, 0x03, 0x18, 0xff, 0x01, 0x48, 0x00, 0x52, 0x0b, 0x63, + 0x6f, 0x6d, 0x70, 0x6f, 0x6e, 0x65, 0x6e, 0x74, 0x49, 0x64, 0x88, 0x01, 0x01, 0x12, 0x20, 0x0a, + 0x06, 0x69, 0x6d, 0x70, 0x61, 0x63, 0x74, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x09, 0x42, 0x08, 0xba, + 0x48, 0x05, 0x72, 0x03, 0x18, 0x80, 0x20, 0x52, 0x06, 0x69, 0x6d, 0x70, 0x61, 0x63, 0x74, 0x12, + 0x22, 0x0a, 0x07, 0x73, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x09, + 0x42, 0x08, 0xba, 0x48, 0x05, 0x72, 0x03, 0x18, 0x80, 0x20, 0x52, 0x07, 0x73, 0x75, 0x6d, 0x6d, + 0x61, 0x72, 0x79, 0x12, 0x49, 0x0a, 0x0e, 0x63, 0x6f, 0x6d, 0x70, 0x6f, 0x6e, 0x65, 0x6e, 0x74, + 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x0d, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x18, 0x2e, 0x65, 0x72, + 0x72, 0x6f, 0x72, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x6f, 0x6d, 0x70, 0x6f, 0x6e, 0x65, 0x6e, + 0x74, 0x54, 0x79, 0x70, 0x65, 0x42, 0x08, 0xba, 0x48, 0x05, 0x82, 0x01, 0x02, 0x10, 0x01, 0x52, + 0x0d, 0x63, 0x6f, 0x6d, 0x70, 0x6f, 0x6e, 0x65, 0x6e, 0x74, 0x54, 0x79, 0x70, 0x65, 0x1a, 0x43, + 0x0a, 0x15, 0x56, 0x65, 0x6e, 0x64, 0x6f, 0x72, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, + 0x65, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, + 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, + 0x02, 0x38, 0x01, 0x42, 0x0f, 0x0a, 0x0d, 0x5f, 0x63, 0x6f, 0x6d, 0x70, 0x6f, 0x6e, 0x65, 0x6e, + 0x74, 0x5f, 0x69, 0x64, 0x22, 0xd4, 0x01, 0x0a, 0x0f, 0x47, 0x65, 0x74, 0x45, 0x72, 0x72, 0x6f, + 0x72, 0x73, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x12, 0x27, 0x0a, 0x09, 0x64, 0x65, 0x76, 0x69, + 0x63, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x0a, 0xba, 0x48, 0x07, 0x72, 0x05, 0x10, 0x01, 0x18, 0xff, 0x01, 0x52, 0x08, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x49, - 0x64, 0x12, 0x30, 0x0a, 0x0c, 0x63, 0x6f, 0x6d, 0x70, 0x6f, 0x6e, 0x65, 0x6e, 0x74, 0x5f, 0x69, - 0x64, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x09, 0x42, 0x08, 0xba, 0x48, 0x05, 0x72, 0x03, 0x18, 0xff, - 0x01, 0x48, 0x00, 0x52, 0x0b, 0x63, 0x6f, 0x6d, 0x70, 0x6f, 0x6e, 0x65, 0x6e, 0x74, 0x49, 0x64, - 0x88, 0x01, 0x01, 0x12, 0x20, 0x0a, 0x06, 0x69, 0x6d, 0x70, 0x61, 0x63, 0x74, 0x18, 0x0b, 0x20, - 0x01, 0x28, 0x09, 0x42, 0x08, 0xba, 0x48, 0x05, 0x72, 0x03, 0x18, 0x80, 0x20, 0x52, 0x06, 0x69, - 0x6d, 0x70, 0x61, 0x63, 0x74, 0x12, 0x22, 0x0a, 0x07, 0x73, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, - 0x18, 0x0c, 0x20, 0x01, 0x28, 0x09, 0x42, 0x08, 0xba, 0x48, 0x05, 0x72, 0x03, 0x18, 0x80, 0x20, - 0x52, 0x07, 0x73, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x12, 0x49, 0x0a, 0x0e, 0x63, 0x6f, 0x6d, - 0x70, 0x6f, 0x6e, 0x65, 0x6e, 0x74, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x0d, 0x20, 0x01, 0x28, - 0x0e, 0x32, 0x18, 0x2e, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x6f, - 0x6d, 0x70, 0x6f, 0x6e, 0x65, 0x6e, 0x74, 0x54, 0x79, 0x70, 0x65, 0x42, 0x08, 0xba, 0x48, 0x05, - 0x82, 0x01, 0x02, 0x10, 0x01, 0x52, 0x0d, 0x63, 0x6f, 0x6d, 0x70, 0x6f, 0x6e, 0x65, 0x6e, 0x74, - 0x54, 0x79, 0x70, 0x65, 0x1a, 0x43, 0x0a, 0x15, 0x56, 0x65, 0x6e, 0x64, 0x6f, 0x72, 0x41, 0x74, - 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, - 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, - 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, - 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x42, 0x0f, 0x0a, 0x0d, 0x5f, 0x63, 0x6f, - 0x6d, 0x70, 0x6f, 0x6e, 0x65, 0x6e, 0x74, 0x5f, 0x69, 0x64, 0x22, 0xd4, 0x01, 0x0a, 0x0f, 0x47, - 0x65, 0x74, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x73, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x12, 0x27, - 0x0a, 0x09, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x09, 0x42, 0x0a, 0xba, 0x48, 0x07, 0x72, 0x05, 0x10, 0x01, 0x18, 0xff, 0x01, 0x52, 0x08, 0x64, - 0x65, 0x76, 0x69, 0x63, 0x65, 0x49, 0x64, 0x12, 0x48, 0x0a, 0x06, 0x65, 0x72, 0x72, 0x6f, 0x72, - 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x25, 0x2e, 0x66, 0x6c, 0x65, 0x65, 0x74, 0x6e, - 0x6f, 0x64, 0x65, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x2e, 0x76, 0x31, 0x2e, 0x4d, 0x69, - 0x6e, 0x65, 0x72, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x42, 0x09, - 0xba, 0x48, 0x06, 0x92, 0x01, 0x03, 0x10, 0x80, 0x04, 0x52, 0x06, 0x65, 0x72, 0x72, 0x6f, 0x72, - 0x73, 0x12, 0x1c, 0x0a, 0x09, 0x74, 0x72, 0x75, 0x6e, 0x63, 0x61, 0x74, 0x65, 0x64, 0x18, 0x03, - 0x20, 0x01, 0x28, 0x08, 0x52, 0x09, 0x74, 0x72, 0x75, 0x6e, 0x63, 0x61, 0x74, 0x65, 0x64, 0x12, - 0x30, 0x0a, 0x14, 0x6f, 0x6d, 0x69, 0x74, 0x74, 0x65, 0x64, 0x5f, 0x72, 0x65, 0x70, 0x6f, 0x72, - 0x74, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x12, 0x6f, - 0x6d, 0x69, 0x74, 0x74, 0x65, 0x64, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x43, 0x6f, 0x75, 0x6e, - 0x74, 0x22, 0xa6, 0x02, 0x0a, 0x0c, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x43, 0x6f, 0x6d, 0x6d, 0x61, - 0x6e, 0x64, 0x12, 0x39, 0x0a, 0x08, 0x64, 0x69, 0x73, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x70, 0x61, 0x69, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x76, - 0x31, 0x2e, 0x44, 0x69, 0x73, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, - 0x74, 0x48, 0x00, 0x52, 0x08, 0x64, 0x69, 0x73, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x12, 0x36, 0x0a, - 0x04, 0x70, 0x61, 0x69, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x20, 0x2e, 0x70, 0x61, - 0x69, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x76, 0x31, 0x2e, 0x46, 0x6c, 0x65, 0x65, 0x74, 0x4e, 0x6f, - 0x64, 0x65, 0x50, 0x61, 0x69, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x48, 0x00, 0x52, - 0x04, 0x70, 0x61, 0x69, 0x72, 0x12, 0x48, 0x0a, 0x0d, 0x6d, 0x69, 0x6e, 0x65, 0x72, 0x5f, 0x63, - 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x21, 0x2e, 0x66, - 0x6c, 0x65, 0x65, 0x74, 0x6e, 0x6f, 0x64, 0x65, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x2e, - 0x76, 0x31, 0x2e, 0x4d, 0x69, 0x6e, 0x65, 0x72, 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x48, - 0x00, 0x52, 0x0c, 0x6d, 0x69, 0x6e, 0x65, 0x72, 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x12, - 0x47, 0x0a, 0x09, 0x74, 0x65, 0x6c, 0x65, 0x6d, 0x65, 0x74, 0x72, 0x79, 0x18, 0x04, 0x20, 0x01, - 0x28, 0x0b, 0x32, 0x27, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x6d, 0x65, 0x74, 0x72, 0x79, 0x2e, 0x76, - 0x31, 0x2e, 0x46, 0x6c, 0x65, 0x65, 0x74, 0x4e, 0x6f, 0x64, 0x65, 0x54, 0x65, 0x6c, 0x65, 0x6d, - 0x65, 0x74, 0x72, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x48, 0x00, 0x52, 0x09, 0x74, - 0x65, 0x6c, 0x65, 0x6d, 0x65, 0x74, 0x72, 0x79, 0x42, 0x10, 0x0a, 0x07, 0x63, 0x6f, 0x6d, 0x6d, - 0x61, 0x6e, 0x64, 0x12, 0x05, 0xba, 0x48, 0x02, 0x08, 0x01, 0x22, 0xdb, 0x01, 0x0a, 0x0a, 0x43, - 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x41, 0x63, 0x6b, 0x12, 0x29, 0x0a, 0x0a, 0x63, 0x6f, 0x6d, - 0x6d, 0x61, 0x6e, 0x64, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x0a, 0xba, - 0x48, 0x07, 0x72, 0x05, 0x10, 0x01, 0x18, 0x80, 0x01, 0x52, 0x09, 0x63, 0x6f, 0x6d, 0x6d, 0x61, - 0x6e, 0x64, 0x49, 0x64, 0x12, 0x1c, 0x0a, 0x09, 0x73, 0x75, 0x63, 0x63, 0x65, 0x65, 0x64, 0x65, - 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x09, 0x73, 0x75, 0x63, 0x63, 0x65, 0x65, 0x64, - 0x65, 0x64, 0x12, 0x2d, 0x0a, 0x0d, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x5f, 0x6d, 0x65, 0x73, 0x73, - 0x61, 0x67, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x42, 0x08, 0xba, 0x48, 0x05, 0x72, 0x03, - 0x18, 0x80, 0x20, 0x52, 0x0c, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, - 0x65, 0x12, 0x30, 0x0a, 0x04, 0x63, 0x6f, 0x64, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0e, 0x32, - 0x1c, 0x2e, 0x66, 0x6c, 0x65, 0x65, 0x74, 0x6e, 0x6f, 0x64, 0x65, 0x67, 0x61, 0x74, 0x65, 0x77, - 0x61, 0x79, 0x2e, 0x76, 0x31, 0x2e, 0x41, 0x63, 0x6b, 0x43, 0x6f, 0x64, 0x65, 0x52, 0x04, 0x63, - 0x6f, 0x64, 0x65, 0x12, 0x23, 0x0a, 0x07, 0x70, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x18, 0x05, - 0x20, 0x01, 0x28, 0x0c, 0x42, 0x09, 0xba, 0x48, 0x06, 0x7a, 0x04, 0x18, 0x80, 0x80, 0x40, 0x52, - 0x07, 0x70, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x2a, 0x94, 0x01, 0x0a, 0x10, 0x45, 0x6e, 0x72, - 0x6f, 0x6c, 0x6c, 0x6d, 0x65, 0x6e, 0x74, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x21, 0x0a, - 0x1d, 0x45, 0x4e, 0x52, 0x4f, 0x4c, 0x4c, 0x4d, 0x45, 0x4e, 0x54, 0x5f, 0x53, 0x54, 0x41, 0x54, - 0x55, 0x53, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, - 0x12, 0x1d, 0x0a, 0x19, 0x45, 0x4e, 0x52, 0x4f, 0x4c, 0x4c, 0x4d, 0x45, 0x4e, 0x54, 0x5f, 0x53, - 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x50, 0x45, 0x4e, 0x44, 0x49, 0x4e, 0x47, 0x10, 0x01, 0x12, - 0x1f, 0x0a, 0x1b, 0x45, 0x4e, 0x52, 0x4f, 0x4c, 0x4c, 0x4d, 0x45, 0x4e, 0x54, 0x5f, 0x53, 0x54, - 0x41, 0x54, 0x55, 0x53, 0x5f, 0x43, 0x4f, 0x4e, 0x46, 0x49, 0x52, 0x4d, 0x45, 0x44, 0x10, 0x02, - 0x12, 0x1d, 0x0a, 0x19, 0x45, 0x4e, 0x52, 0x4f, 0x4c, 0x4c, 0x4d, 0x45, 0x4e, 0x54, 0x5f, 0x53, - 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x52, 0x45, 0x56, 0x4f, 0x4b, 0x45, 0x44, 0x10, 0x03, 0x2a, - 0x9a, 0x01, 0x0a, 0x16, 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x41, 0x72, 0x74, 0x69, 0x66, - 0x61, 0x63, 0x74, 0x50, 0x75, 0x72, 0x70, 0x6f, 0x73, 0x65, 0x12, 0x28, 0x0a, 0x24, 0x43, 0x4f, - 0x4d, 0x4d, 0x41, 0x4e, 0x44, 0x5f, 0x41, 0x52, 0x54, 0x49, 0x46, 0x41, 0x43, 0x54, 0x5f, 0x50, - 0x55, 0x52, 0x50, 0x4f, 0x53, 0x45, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, - 0x45, 0x44, 0x10, 0x00, 0x12, 0x27, 0x0a, 0x23, 0x43, 0x4f, 0x4d, 0x4d, 0x41, 0x4e, 0x44, 0x5f, + 0x64, 0x12, 0x48, 0x0a, 0x06, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, + 0x0b, 0x32, 0x25, 0x2e, 0x66, 0x6c, 0x65, 0x65, 0x74, 0x6e, 0x6f, 0x64, 0x65, 0x67, 0x61, 0x74, + 0x65, 0x77, 0x61, 0x79, 0x2e, 0x76, 0x31, 0x2e, 0x4d, 0x69, 0x6e, 0x65, 0x72, 0x45, 0x72, 0x72, + 0x6f, 0x72, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x42, 0x09, 0xba, 0x48, 0x06, 0x92, 0x01, 0x03, + 0x10, 0x80, 0x04, 0x52, 0x06, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x73, 0x12, 0x1c, 0x0a, 0x09, 0x74, + 0x72, 0x75, 0x6e, 0x63, 0x61, 0x74, 0x65, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x09, + 0x74, 0x72, 0x75, 0x6e, 0x63, 0x61, 0x74, 0x65, 0x64, 0x12, 0x30, 0x0a, 0x14, 0x6f, 0x6d, 0x69, + 0x74, 0x74, 0x65, 0x64, 0x5f, 0x72, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x5f, 0x63, 0x6f, 0x75, 0x6e, + 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x12, 0x6f, 0x6d, 0x69, 0x74, 0x74, 0x65, 0x64, + 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x22, 0xa6, 0x02, 0x0a, 0x0c, + 0x41, 0x67, 0x65, 0x6e, 0x74, 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x12, 0x39, 0x0a, 0x08, + 0x64, 0x69, 0x73, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1b, + 0x2e, 0x70, 0x61, 0x69, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x76, 0x31, 0x2e, 0x44, 0x69, 0x73, 0x63, + 0x6f, 0x76, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x48, 0x00, 0x52, 0x08, 0x64, + 0x69, 0x73, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x12, 0x36, 0x0a, 0x04, 0x70, 0x61, 0x69, 0x72, 0x18, + 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x20, 0x2e, 0x70, 0x61, 0x69, 0x72, 0x69, 0x6e, 0x67, 0x2e, + 0x76, 0x31, 0x2e, 0x46, 0x6c, 0x65, 0x65, 0x74, 0x4e, 0x6f, 0x64, 0x65, 0x50, 0x61, 0x69, 0x72, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x48, 0x00, 0x52, 0x04, 0x70, 0x61, 0x69, 0x72, 0x12, + 0x48, 0x0a, 0x0d, 0x6d, 0x69, 0x6e, 0x65, 0x72, 0x5f, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, + 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x21, 0x2e, 0x66, 0x6c, 0x65, 0x65, 0x74, 0x6e, 0x6f, + 0x64, 0x65, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x2e, 0x76, 0x31, 0x2e, 0x4d, 0x69, 0x6e, + 0x65, 0x72, 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x48, 0x00, 0x52, 0x0c, 0x6d, 0x69, 0x6e, + 0x65, 0x72, 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x12, 0x47, 0x0a, 0x09, 0x74, 0x65, 0x6c, + 0x65, 0x6d, 0x65, 0x74, 0x72, 0x79, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x27, 0x2e, 0x74, + 0x65, 0x6c, 0x65, 0x6d, 0x65, 0x74, 0x72, 0x79, 0x2e, 0x76, 0x31, 0x2e, 0x46, 0x6c, 0x65, 0x65, + 0x74, 0x4e, 0x6f, 0x64, 0x65, 0x54, 0x65, 0x6c, 0x65, 0x6d, 0x65, 0x74, 0x72, 0x79, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x48, 0x00, 0x52, 0x09, 0x74, 0x65, 0x6c, 0x65, 0x6d, 0x65, 0x74, + 0x72, 0x79, 0x42, 0x10, 0x0a, 0x07, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x12, 0x05, 0xba, + 0x48, 0x02, 0x08, 0x01, 0x22, 0xdb, 0x01, 0x0a, 0x0a, 0x43, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, + 0x41, 0x63, 0x6b, 0x12, 0x29, 0x0a, 0x0a, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x5f, 0x69, + 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x0a, 0xba, 0x48, 0x07, 0x72, 0x05, 0x10, 0x01, + 0x18, 0x80, 0x01, 0x52, 0x09, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x49, 0x64, 0x12, 0x1c, + 0x0a, 0x09, 0x73, 0x75, 0x63, 0x63, 0x65, 0x65, 0x64, 0x65, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, + 0x08, 0x52, 0x09, 0x73, 0x75, 0x63, 0x63, 0x65, 0x65, 0x64, 0x65, 0x64, 0x12, 0x2d, 0x0a, 0x0d, + 0x65, 0x72, 0x72, 0x6f, 0x72, 0x5f, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x03, 0x20, + 0x01, 0x28, 0x09, 0x42, 0x08, 0xba, 0x48, 0x05, 0x72, 0x03, 0x18, 0x80, 0x20, 0x52, 0x0c, 0x65, + 0x72, 0x72, 0x6f, 0x72, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x30, 0x0a, 0x04, 0x63, + 0x6f, 0x64, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1c, 0x2e, 0x66, 0x6c, 0x65, 0x65, + 0x74, 0x6e, 0x6f, 0x64, 0x65, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x2e, 0x76, 0x31, 0x2e, + 0x41, 0x63, 0x6b, 0x43, 0x6f, 0x64, 0x65, 0x52, 0x04, 0x63, 0x6f, 0x64, 0x65, 0x12, 0x23, 0x0a, + 0x07, 0x70, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0c, 0x42, 0x09, + 0xba, 0x48, 0x06, 0x7a, 0x04, 0x18, 0x80, 0x80, 0x40, 0x52, 0x07, 0x70, 0x61, 0x79, 0x6c, 0x6f, + 0x61, 0x64, 0x2a, 0x94, 0x01, 0x0a, 0x10, 0x45, 0x6e, 0x72, 0x6f, 0x6c, 0x6c, 0x6d, 0x65, 0x6e, + 0x74, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x21, 0x0a, 0x1d, 0x45, 0x4e, 0x52, 0x4f, 0x4c, + 0x4c, 0x4d, 0x45, 0x4e, 0x54, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x55, 0x4e, 0x53, + 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x1d, 0x0a, 0x19, 0x45, 0x4e, + 0x52, 0x4f, 0x4c, 0x4c, 0x4d, 0x45, 0x4e, 0x54, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, + 0x50, 0x45, 0x4e, 0x44, 0x49, 0x4e, 0x47, 0x10, 0x01, 0x12, 0x1f, 0x0a, 0x1b, 0x45, 0x4e, 0x52, + 0x4f, 0x4c, 0x4c, 0x4d, 0x45, 0x4e, 0x54, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x43, + 0x4f, 0x4e, 0x46, 0x49, 0x52, 0x4d, 0x45, 0x44, 0x10, 0x02, 0x12, 0x1d, 0x0a, 0x19, 0x45, 0x4e, + 0x52, 0x4f, 0x4c, 0x4c, 0x4d, 0x45, 0x4e, 0x54, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, + 0x52, 0x45, 0x56, 0x4f, 0x4b, 0x45, 0x44, 0x10, 0x03, 0x2a, 0x9a, 0x01, 0x0a, 0x16, 0x43, 0x6f, + 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x41, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x50, 0x75, 0x72, + 0x70, 0x6f, 0x73, 0x65, 0x12, 0x28, 0x0a, 0x24, 0x43, 0x4f, 0x4d, 0x4d, 0x41, 0x4e, 0x44, 0x5f, 0x41, 0x52, 0x54, 0x49, 0x46, 0x41, 0x43, 0x54, 0x5f, 0x50, 0x55, 0x52, 0x50, 0x4f, 0x53, 0x45, - 0x5f, 0x4d, 0x49, 0x4e, 0x45, 0x52, 0x5f, 0x4c, 0x4f, 0x47, 0x53, 0x10, 0x01, 0x12, 0x2d, 0x0a, - 0x29, 0x43, 0x4f, 0x4d, 0x4d, 0x41, 0x4e, 0x44, 0x5f, 0x41, 0x52, 0x54, 0x49, 0x46, 0x41, 0x43, - 0x54, 0x5f, 0x50, 0x55, 0x52, 0x50, 0x4f, 0x53, 0x45, 0x5f, 0x46, 0x49, 0x52, 0x4d, 0x57, 0x41, - 0x52, 0x45, 0x5f, 0x50, 0x41, 0x59, 0x4c, 0x4f, 0x41, 0x44, 0x10, 0x02, 0x2a, 0x98, 0x01, 0x0a, - 0x0b, 0x50, 0x61, 0x69, 0x72, 0x4f, 0x75, 0x74, 0x63, 0x6f, 0x6d, 0x65, 0x12, 0x1c, 0x0a, 0x18, - 0x50, 0x41, 0x49, 0x52, 0x5f, 0x4f, 0x55, 0x54, 0x43, 0x4f, 0x4d, 0x45, 0x5f, 0x55, 0x4e, 0x53, - 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x17, 0x0a, 0x13, 0x50, 0x41, - 0x49, 0x52, 0x5f, 0x4f, 0x55, 0x54, 0x43, 0x4f, 0x4d, 0x45, 0x5f, 0x50, 0x41, 0x49, 0x52, 0x45, - 0x44, 0x10, 0x01, 0x12, 0x1c, 0x0a, 0x18, 0x50, 0x41, 0x49, 0x52, 0x5f, 0x4f, 0x55, 0x54, 0x43, - 0x4f, 0x4d, 0x45, 0x5f, 0x41, 0x55, 0x54, 0x48, 0x5f, 0x4e, 0x45, 0x45, 0x44, 0x45, 0x44, 0x10, - 0x02, 0x12, 0x1c, 0x0a, 0x18, 0x50, 0x41, 0x49, 0x52, 0x5f, 0x4f, 0x55, 0x54, 0x43, 0x4f, 0x4d, - 0x45, 0x5f, 0x41, 0x55, 0x54, 0x48, 0x5f, 0x46, 0x41, 0x49, 0x4c, 0x45, 0x44, 0x10, 0x03, 0x12, - 0x16, 0x0a, 0x12, 0x50, 0x41, 0x49, 0x52, 0x5f, 0x4f, 0x55, 0x54, 0x43, 0x4f, 0x4d, 0x45, 0x5f, - 0x45, 0x52, 0x52, 0x4f, 0x52, 0x10, 0x04, 0x2a, 0xb4, 0x02, 0x0a, 0x07, 0x41, 0x63, 0x6b, 0x43, - 0x6f, 0x64, 0x65, 0x12, 0x18, 0x0a, 0x14, 0x41, 0x43, 0x4b, 0x5f, 0x43, 0x4f, 0x44, 0x45, 0x5f, - 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x0f, 0x0a, - 0x0b, 0x41, 0x43, 0x4b, 0x5f, 0x43, 0x4f, 0x44, 0x45, 0x5f, 0x4f, 0x4b, 0x10, 0x01, 0x12, 0x14, - 0x0a, 0x10, 0x41, 0x43, 0x4b, 0x5f, 0x43, 0x4f, 0x44, 0x45, 0x5f, 0x50, 0x41, 0x52, 0x54, 0x49, - 0x41, 0x4c, 0x10, 0x02, 0x12, 0x18, 0x0a, 0x14, 0x41, 0x43, 0x4b, 0x5f, 0x43, 0x4f, 0x44, 0x45, - 0x5f, 0x42, 0x41, 0x44, 0x5f, 0x52, 0x45, 0x51, 0x55, 0x45, 0x53, 0x54, 0x10, 0x03, 0x12, 0x1c, - 0x0a, 0x18, 0x41, 0x43, 0x4b, 0x5f, 0x43, 0x4f, 0x44, 0x45, 0x5f, 0x41, 0x47, 0x45, 0x4e, 0x54, - 0x5f, 0x49, 0x4e, 0x43, 0x41, 0x50, 0x41, 0x42, 0x4c, 0x45, 0x10, 0x04, 0x12, 0x18, 0x0a, 0x14, - 0x41, 0x43, 0x4b, 0x5f, 0x43, 0x4f, 0x44, 0x45, 0x5f, 0x53, 0x43, 0x41, 0x4e, 0x5f, 0x46, 0x41, - 0x49, 0x4c, 0x45, 0x44, 0x10, 0x05, 0x12, 0x1a, 0x0a, 0x16, 0x41, 0x43, 0x4b, 0x5f, 0x43, 0x4f, - 0x44, 0x45, 0x5f, 0x52, 0x45, 0x50, 0x4f, 0x52, 0x54, 0x5f, 0x46, 0x41, 0x49, 0x4c, 0x45, 0x44, - 0x10, 0x06, 0x12, 0x15, 0x0a, 0x11, 0x41, 0x43, 0x4b, 0x5f, 0x43, 0x4f, 0x44, 0x45, 0x5f, 0x49, - 0x4e, 0x54, 0x45, 0x52, 0x4e, 0x41, 0x4c, 0x10, 0x07, 0x12, 0x11, 0x0a, 0x0d, 0x41, 0x43, 0x4b, - 0x5f, 0x43, 0x4f, 0x44, 0x45, 0x5f, 0x42, 0x55, 0x53, 0x59, 0x10, 0x08, 0x12, 0x1c, 0x0a, 0x18, - 0x41, 0x43, 0x4b, 0x5f, 0x43, 0x4f, 0x44, 0x45, 0x5f, 0x55, 0x4e, 0x41, 0x55, 0x54, 0x48, 0x45, - 0x4e, 0x54, 0x49, 0x43, 0x41, 0x54, 0x45, 0x44, 0x10, 0x09, 0x12, 0x1a, 0x0a, 0x16, 0x41, 0x43, - 0x4b, 0x5f, 0x43, 0x4f, 0x44, 0x45, 0x5f, 0x55, 0x4e, 0x49, 0x4d, 0x50, 0x4c, 0x45, 0x4d, 0x45, - 0x4e, 0x54, 0x45, 0x44, 0x10, 0x0a, 0x12, 0x16, 0x0a, 0x12, 0x41, 0x43, 0x4b, 0x5f, 0x43, 0x4f, - 0x44, 0x45, 0x5f, 0x46, 0x4f, 0x52, 0x42, 0x49, 0x44, 0x44, 0x45, 0x4e, 0x10, 0x0b, 0x32, 0xa7, - 0x0a, 0x0a, 0x17, 0x46, 0x6c, 0x65, 0x65, 0x74, 0x4e, 0x6f, 0x64, 0x65, 0x47, 0x61, 0x74, 0x65, - 0x77, 0x61, 0x79, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x57, 0x0a, 0x08, 0x52, 0x65, - 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x12, 0x24, 0x2e, 0x66, 0x6c, 0x65, 0x65, 0x74, 0x6e, 0x6f, + 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x27, + 0x0a, 0x23, 0x43, 0x4f, 0x4d, 0x4d, 0x41, 0x4e, 0x44, 0x5f, 0x41, 0x52, 0x54, 0x49, 0x46, 0x41, + 0x43, 0x54, 0x5f, 0x50, 0x55, 0x52, 0x50, 0x4f, 0x53, 0x45, 0x5f, 0x4d, 0x49, 0x4e, 0x45, 0x52, + 0x5f, 0x4c, 0x4f, 0x47, 0x53, 0x10, 0x01, 0x12, 0x2d, 0x0a, 0x29, 0x43, 0x4f, 0x4d, 0x4d, 0x41, + 0x4e, 0x44, 0x5f, 0x41, 0x52, 0x54, 0x49, 0x46, 0x41, 0x43, 0x54, 0x5f, 0x50, 0x55, 0x52, 0x50, + 0x4f, 0x53, 0x45, 0x5f, 0x46, 0x49, 0x52, 0x4d, 0x57, 0x41, 0x52, 0x45, 0x5f, 0x50, 0x41, 0x59, + 0x4c, 0x4f, 0x41, 0x44, 0x10, 0x02, 0x2a, 0x98, 0x01, 0x0a, 0x0b, 0x50, 0x61, 0x69, 0x72, 0x4f, + 0x75, 0x74, 0x63, 0x6f, 0x6d, 0x65, 0x12, 0x1c, 0x0a, 0x18, 0x50, 0x41, 0x49, 0x52, 0x5f, 0x4f, + 0x55, 0x54, 0x43, 0x4f, 0x4d, 0x45, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, + 0x45, 0x44, 0x10, 0x00, 0x12, 0x17, 0x0a, 0x13, 0x50, 0x41, 0x49, 0x52, 0x5f, 0x4f, 0x55, 0x54, + 0x43, 0x4f, 0x4d, 0x45, 0x5f, 0x50, 0x41, 0x49, 0x52, 0x45, 0x44, 0x10, 0x01, 0x12, 0x1c, 0x0a, + 0x18, 0x50, 0x41, 0x49, 0x52, 0x5f, 0x4f, 0x55, 0x54, 0x43, 0x4f, 0x4d, 0x45, 0x5f, 0x41, 0x55, + 0x54, 0x48, 0x5f, 0x4e, 0x45, 0x45, 0x44, 0x45, 0x44, 0x10, 0x02, 0x12, 0x1c, 0x0a, 0x18, 0x50, + 0x41, 0x49, 0x52, 0x5f, 0x4f, 0x55, 0x54, 0x43, 0x4f, 0x4d, 0x45, 0x5f, 0x41, 0x55, 0x54, 0x48, + 0x5f, 0x46, 0x41, 0x49, 0x4c, 0x45, 0x44, 0x10, 0x03, 0x12, 0x16, 0x0a, 0x12, 0x50, 0x41, 0x49, + 0x52, 0x5f, 0x4f, 0x55, 0x54, 0x43, 0x4f, 0x4d, 0x45, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x10, + 0x04, 0x2a, 0xb4, 0x02, 0x0a, 0x07, 0x41, 0x63, 0x6b, 0x43, 0x6f, 0x64, 0x65, 0x12, 0x18, 0x0a, + 0x14, 0x41, 0x43, 0x4b, 0x5f, 0x43, 0x4f, 0x44, 0x45, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, + 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x0f, 0x0a, 0x0b, 0x41, 0x43, 0x4b, 0x5f, 0x43, + 0x4f, 0x44, 0x45, 0x5f, 0x4f, 0x4b, 0x10, 0x01, 0x12, 0x14, 0x0a, 0x10, 0x41, 0x43, 0x4b, 0x5f, + 0x43, 0x4f, 0x44, 0x45, 0x5f, 0x50, 0x41, 0x52, 0x54, 0x49, 0x41, 0x4c, 0x10, 0x02, 0x12, 0x18, + 0x0a, 0x14, 0x41, 0x43, 0x4b, 0x5f, 0x43, 0x4f, 0x44, 0x45, 0x5f, 0x42, 0x41, 0x44, 0x5f, 0x52, + 0x45, 0x51, 0x55, 0x45, 0x53, 0x54, 0x10, 0x03, 0x12, 0x1c, 0x0a, 0x18, 0x41, 0x43, 0x4b, 0x5f, + 0x43, 0x4f, 0x44, 0x45, 0x5f, 0x41, 0x47, 0x45, 0x4e, 0x54, 0x5f, 0x49, 0x4e, 0x43, 0x41, 0x50, + 0x41, 0x42, 0x4c, 0x45, 0x10, 0x04, 0x12, 0x18, 0x0a, 0x14, 0x41, 0x43, 0x4b, 0x5f, 0x43, 0x4f, + 0x44, 0x45, 0x5f, 0x53, 0x43, 0x41, 0x4e, 0x5f, 0x46, 0x41, 0x49, 0x4c, 0x45, 0x44, 0x10, 0x05, + 0x12, 0x1a, 0x0a, 0x16, 0x41, 0x43, 0x4b, 0x5f, 0x43, 0x4f, 0x44, 0x45, 0x5f, 0x52, 0x45, 0x50, + 0x4f, 0x52, 0x54, 0x5f, 0x46, 0x41, 0x49, 0x4c, 0x45, 0x44, 0x10, 0x06, 0x12, 0x15, 0x0a, 0x11, + 0x41, 0x43, 0x4b, 0x5f, 0x43, 0x4f, 0x44, 0x45, 0x5f, 0x49, 0x4e, 0x54, 0x45, 0x52, 0x4e, 0x41, + 0x4c, 0x10, 0x07, 0x12, 0x11, 0x0a, 0x0d, 0x41, 0x43, 0x4b, 0x5f, 0x43, 0x4f, 0x44, 0x45, 0x5f, + 0x42, 0x55, 0x53, 0x59, 0x10, 0x08, 0x12, 0x1c, 0x0a, 0x18, 0x41, 0x43, 0x4b, 0x5f, 0x43, 0x4f, + 0x44, 0x45, 0x5f, 0x55, 0x4e, 0x41, 0x55, 0x54, 0x48, 0x45, 0x4e, 0x54, 0x49, 0x43, 0x41, 0x54, + 0x45, 0x44, 0x10, 0x09, 0x12, 0x1a, 0x0a, 0x16, 0x41, 0x43, 0x4b, 0x5f, 0x43, 0x4f, 0x44, 0x45, + 0x5f, 0x55, 0x4e, 0x49, 0x4d, 0x50, 0x4c, 0x45, 0x4d, 0x45, 0x4e, 0x54, 0x45, 0x44, 0x10, 0x0a, + 0x12, 0x16, 0x0a, 0x12, 0x41, 0x43, 0x4b, 0x5f, 0x43, 0x4f, 0x44, 0x45, 0x5f, 0x46, 0x4f, 0x52, + 0x42, 0x49, 0x44, 0x44, 0x45, 0x4e, 0x10, 0x0b, 0x32, 0xa7, 0x0a, 0x0a, 0x17, 0x46, 0x6c, 0x65, + 0x65, 0x74, 0x4e, 0x6f, 0x64, 0x65, 0x47, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x53, 0x65, 0x72, + 0x76, 0x69, 0x63, 0x65, 0x12, 0x57, 0x0a, 0x08, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, + 0x12, 0x24, 0x2e, 0x66, 0x6c, 0x65, 0x65, 0x74, 0x6e, 0x6f, 0x64, 0x65, 0x67, 0x61, 0x74, 0x65, + 0x77, 0x61, 0x79, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x25, 0x2e, 0x66, 0x6c, 0x65, 0x65, 0x74, 0x6e, 0x6f, 0x64, 0x65, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x67, - 0x69, 0x73, 0x74, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x25, 0x2e, 0x66, - 0x6c, 0x65, 0x65, 0x74, 0x6e, 0x6f, 0x64, 0x65, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x2e, - 0x76, 0x31, 0x2e, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, - 0x6e, 0x73, 0x65, 0x12, 0x75, 0x0a, 0x12, 0x42, 0x65, 0x67, 0x69, 0x6e, 0x41, 0x75, 0x74, 0x68, - 0x48, 0x61, 0x6e, 0x64, 0x73, 0x68, 0x61, 0x6b, 0x65, 0x12, 0x2e, 0x2e, 0x66, 0x6c, 0x65, 0x65, - 0x74, 0x6e, 0x6f, 0x64, 0x65, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x2e, 0x76, 0x31, 0x2e, - 0x42, 0x65, 0x67, 0x69, 0x6e, 0x41, 0x75, 0x74, 0x68, 0x48, 0x61, 0x6e, 0x64, 0x73, 0x68, 0x61, - 0x6b, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2f, 0x2e, 0x66, 0x6c, 0x65, 0x65, - 0x74, 0x6e, 0x6f, 0x64, 0x65, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x2e, 0x76, 0x31, 0x2e, - 0x42, 0x65, 0x67, 0x69, 0x6e, 0x41, 0x75, 0x74, 0x68, 0x48, 0x61, 0x6e, 0x64, 0x73, 0x68, 0x61, - 0x6b, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x7e, 0x0a, 0x15, 0x43, 0x6f, - 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x65, 0x41, 0x75, 0x74, 0x68, 0x48, 0x61, 0x6e, 0x64, 0x73, 0x68, - 0x61, 0x6b, 0x65, 0x12, 0x31, 0x2e, 0x66, 0x6c, 0x65, 0x65, 0x74, 0x6e, 0x6f, 0x64, 0x65, 0x67, - 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x6f, 0x6d, 0x70, 0x6c, 0x65, - 0x74, 0x65, 0x41, 0x75, 0x74, 0x68, 0x48, 0x61, 0x6e, 0x64, 0x73, 0x68, 0x61, 0x6b, 0x65, 0x52, - 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x32, 0x2e, 0x66, 0x6c, 0x65, 0x65, 0x74, 0x6e, 0x6f, - 0x64, 0x65, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x6f, 0x6d, - 0x70, 0x6c, 0x65, 0x74, 0x65, 0x41, 0x75, 0x74, 0x68, 0x48, 0x61, 0x6e, 0x64, 0x73, 0x68, 0x61, - 0x6b, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x6e, 0x0a, 0x0f, 0x55, 0x70, - 0x6c, 0x6f, 0x61, 0x64, 0x54, 0x65, 0x6c, 0x65, 0x6d, 0x65, 0x74, 0x72, 0x79, 0x12, 0x2b, 0x2e, + 0x69, 0x73, 0x74, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x75, 0x0a, + 0x12, 0x42, 0x65, 0x67, 0x69, 0x6e, 0x41, 0x75, 0x74, 0x68, 0x48, 0x61, 0x6e, 0x64, 0x73, 0x68, + 0x61, 0x6b, 0x65, 0x12, 0x2e, 0x2e, 0x66, 0x6c, 0x65, 0x65, 0x74, 0x6e, 0x6f, 0x64, 0x65, 0x67, + 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x2e, 0x76, 0x31, 0x2e, 0x42, 0x65, 0x67, 0x69, 0x6e, 0x41, + 0x75, 0x74, 0x68, 0x48, 0x61, 0x6e, 0x64, 0x73, 0x68, 0x61, 0x6b, 0x65, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x1a, 0x2f, 0x2e, 0x66, 0x6c, 0x65, 0x65, 0x74, 0x6e, 0x6f, 0x64, 0x65, 0x67, + 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x2e, 0x76, 0x31, 0x2e, 0x42, 0x65, 0x67, 0x69, 0x6e, 0x41, + 0x75, 0x74, 0x68, 0x48, 0x61, 0x6e, 0x64, 0x73, 0x68, 0x61, 0x6b, 0x65, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x7e, 0x0a, 0x15, 0x43, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x65, + 0x41, 0x75, 0x74, 0x68, 0x48, 0x61, 0x6e, 0x64, 0x73, 0x68, 0x61, 0x6b, 0x65, 0x12, 0x31, 0x2e, 0x66, 0x6c, 0x65, 0x65, 0x74, 0x6e, 0x6f, 0x64, 0x65, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, - 0x2e, 0x76, 0x31, 0x2e, 0x55, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x54, 0x65, 0x6c, 0x65, 0x6d, 0x65, - 0x74, 0x72, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2c, 0x2e, 0x66, 0x6c, 0x65, - 0x65, 0x74, 0x6e, 0x6f, 0x64, 0x65, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x2e, 0x76, 0x31, - 0x2e, 0x55, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x54, 0x65, 0x6c, 0x65, 0x6d, 0x65, 0x74, 0x72, 0x79, - 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x28, 0x01, 0x12, 0x65, 0x0a, 0x0c, 0x55, 0x70, - 0x6c, 0x6f, 0x61, 0x64, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x12, 0x28, 0x2e, 0x66, 0x6c, 0x65, - 0x65, 0x74, 0x6e, 0x6f, 0x64, 0x65, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x2e, 0x76, 0x31, - 0x2e, 0x55, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x52, 0x65, 0x71, - 0x75, 0x65, 0x73, 0x74, 0x1a, 0x29, 0x2e, 0x66, 0x6c, 0x65, 0x65, 0x74, 0x6e, 0x6f, 0x64, 0x65, + 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x65, 0x41, 0x75, 0x74, 0x68, + 0x48, 0x61, 0x6e, 0x64, 0x73, 0x68, 0x61, 0x6b, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x1a, 0x32, 0x2e, 0x66, 0x6c, 0x65, 0x65, 0x74, 0x6e, 0x6f, 0x64, 0x65, 0x67, 0x61, 0x74, 0x65, + 0x77, 0x61, 0x79, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x65, 0x41, + 0x75, 0x74, 0x68, 0x48, 0x61, 0x6e, 0x64, 0x73, 0x68, 0x61, 0x6b, 0x65, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x6e, 0x0a, 0x0f, 0x55, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x54, 0x65, + 0x6c, 0x65, 0x6d, 0x65, 0x74, 0x72, 0x79, 0x12, 0x2b, 0x2e, 0x66, 0x6c, 0x65, 0x65, 0x74, 0x6e, + 0x6f, 0x64, 0x65, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x2e, 0x76, 0x31, 0x2e, 0x55, 0x70, + 0x6c, 0x6f, 0x61, 0x64, 0x54, 0x65, 0x6c, 0x65, 0x6d, 0x65, 0x74, 0x72, 0x79, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2c, 0x2e, 0x66, 0x6c, 0x65, 0x65, 0x74, 0x6e, 0x6f, 0x64, 0x65, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x2e, 0x76, 0x31, 0x2e, 0x55, 0x70, 0x6c, 0x6f, 0x61, - 0x64, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x28, - 0x01, 0x12, 0x6c, 0x0a, 0x0f, 0x55, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x48, 0x65, 0x61, 0x72, 0x74, - 0x62, 0x65, 0x61, 0x74, 0x12, 0x2b, 0x2e, 0x66, 0x6c, 0x65, 0x65, 0x74, 0x6e, 0x6f, 0x64, 0x65, + 0x64, 0x54, 0x65, 0x6c, 0x65, 0x6d, 0x65, 0x74, 0x72, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x28, 0x01, 0x12, 0x65, 0x0a, 0x0c, 0x55, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x45, 0x76, + 0x65, 0x6e, 0x74, 0x73, 0x12, 0x28, 0x2e, 0x66, 0x6c, 0x65, 0x65, 0x74, 0x6e, 0x6f, 0x64, 0x65, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x2e, 0x76, 0x31, 0x2e, 0x55, 0x70, 0x6c, 0x6f, 0x61, - 0x64, 0x48, 0x65, 0x61, 0x72, 0x74, 0x62, 0x65, 0x61, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, - 0x74, 0x1a, 0x2c, 0x2e, 0x66, 0x6c, 0x65, 0x65, 0x74, 0x6e, 0x6f, 0x64, 0x65, 0x67, 0x61, 0x74, - 0x65, 0x77, 0x61, 0x79, 0x2e, 0x76, 0x31, 0x2e, 0x55, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x48, 0x65, - 0x61, 0x72, 0x74, 0x62, 0x65, 0x61, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, - 0x80, 0x01, 0x0a, 0x15, 0x55, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, - 0x64, 0x41, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x12, 0x31, 0x2e, 0x66, 0x6c, 0x65, 0x65, - 0x74, 0x6e, 0x6f, 0x64, 0x65, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x2e, 0x76, 0x31, 0x2e, - 0x55, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x41, 0x72, 0x74, - 0x69, 0x66, 0x61, 0x63, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x32, 0x2e, 0x66, - 0x6c, 0x65, 0x65, 0x74, 0x6e, 0x6f, 0x64, 0x65, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x2e, - 0x76, 0x31, 0x2e, 0x55, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, - 0x41, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, - 0x28, 0x01, 0x12, 0x86, 0x01, 0x0a, 0x17, 0x44, 0x6f, 0x77, 0x6e, 0x6c, 0x6f, 0x61, 0x64, 0x43, - 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x41, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x12, 0x33, + 0x64, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x29, 0x2e, 0x66, 0x6c, 0x65, 0x65, 0x74, 0x6e, 0x6f, 0x64, 0x65, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, - 0x79, 0x2e, 0x76, 0x31, 0x2e, 0x44, 0x6f, 0x77, 0x6e, 0x6c, 0x6f, 0x61, 0x64, 0x43, 0x6f, 0x6d, - 0x6d, 0x61, 0x6e, 0x64, 0x41, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x52, 0x65, 0x71, 0x75, - 0x65, 0x73, 0x74, 0x1a, 0x34, 0x2e, 0x66, 0x6c, 0x65, 0x65, 0x74, 0x6e, 0x6f, 0x64, 0x65, 0x67, - 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x2e, 0x76, 0x31, 0x2e, 0x44, 0x6f, 0x77, 0x6e, 0x6c, 0x6f, - 0x61, 0x64, 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x41, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, - 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x30, 0x01, 0x12, 0x84, 0x01, 0x0a, 0x17, - 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x44, 0x69, 0x73, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x65, 0x64, - 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x73, 0x12, 0x33, 0x2e, 0x66, 0x6c, 0x65, 0x65, 0x74, 0x6e, - 0x6f, 0x64, 0x65, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, - 0x70, 0x6f, 0x72, 0x74, 0x44, 0x69, 0x73, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x65, 0x64, 0x44, 0x65, - 0x76, 0x69, 0x63, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x34, 0x2e, 0x66, - 0x6c, 0x65, 0x65, 0x74, 0x6e, 0x6f, 0x64, 0x65, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x2e, - 0x76, 0x31, 0x2e, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x44, 0x69, 0x73, 0x63, 0x6f, 0x76, 0x65, - 0x72, 0x65, 0x64, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, - 0x73, 0x65, 0x12, 0x78, 0x0a, 0x13, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x50, 0x61, 0x69, 0x72, - 0x65, 0x64, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x73, 0x12, 0x2f, 0x2e, 0x66, 0x6c, 0x65, 0x65, - 0x74, 0x6e, 0x6f, 0x64, 0x65, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x2e, 0x76, 0x31, 0x2e, + 0x79, 0x2e, 0x76, 0x31, 0x2e, 0x55, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x45, 0x76, 0x65, 0x6e, 0x74, + 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x28, 0x01, 0x12, 0x6c, 0x0a, 0x0f, 0x55, + 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x48, 0x65, 0x61, 0x72, 0x74, 0x62, 0x65, 0x61, 0x74, 0x12, 0x2b, + 0x2e, 0x66, 0x6c, 0x65, 0x65, 0x74, 0x6e, 0x6f, 0x64, 0x65, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, + 0x79, 0x2e, 0x76, 0x31, 0x2e, 0x55, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x48, 0x65, 0x61, 0x72, 0x74, + 0x62, 0x65, 0x61, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2c, 0x2e, 0x66, 0x6c, + 0x65, 0x65, 0x74, 0x6e, 0x6f, 0x64, 0x65, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x2e, 0x76, + 0x31, 0x2e, 0x55, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x48, 0x65, 0x61, 0x72, 0x74, 0x62, 0x65, 0x61, + 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x80, 0x01, 0x0a, 0x15, 0x55, 0x70, + 0x6c, 0x6f, 0x61, 0x64, 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x41, 0x72, 0x74, 0x69, 0x66, + 0x61, 0x63, 0x74, 0x12, 0x31, 0x2e, 0x66, 0x6c, 0x65, 0x65, 0x74, 0x6e, 0x6f, 0x64, 0x65, 0x67, + 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x2e, 0x76, 0x31, 0x2e, 0x55, 0x70, 0x6c, 0x6f, 0x61, 0x64, + 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x41, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x32, 0x2e, 0x66, 0x6c, 0x65, 0x65, 0x74, 0x6e, 0x6f, + 0x64, 0x65, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x2e, 0x76, 0x31, 0x2e, 0x55, 0x70, 0x6c, + 0x6f, 0x61, 0x64, 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x41, 0x72, 0x74, 0x69, 0x66, 0x61, + 0x63, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x28, 0x01, 0x12, 0x86, 0x01, 0x0a, + 0x17, 0x44, 0x6f, 0x77, 0x6e, 0x6c, 0x6f, 0x61, 0x64, 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, + 0x41, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x12, 0x33, 0x2e, 0x66, 0x6c, 0x65, 0x65, 0x74, + 0x6e, 0x6f, 0x64, 0x65, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x2e, 0x76, 0x31, 0x2e, 0x44, + 0x6f, 0x77, 0x6e, 0x6c, 0x6f, 0x61, 0x64, 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x41, 0x72, + 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x34, 0x2e, + 0x66, 0x6c, 0x65, 0x65, 0x74, 0x6e, 0x6f, 0x64, 0x65, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, + 0x2e, 0x76, 0x31, 0x2e, 0x44, 0x6f, 0x77, 0x6e, 0x6c, 0x6f, 0x61, 0x64, 0x43, 0x6f, 0x6d, 0x6d, + 0x61, 0x6e, 0x64, 0x41, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x30, 0x01, 0x12, 0x84, 0x01, 0x0a, 0x17, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, + 0x44, 0x69, 0x73, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x65, 0x64, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, + 0x73, 0x12, 0x33, 0x2e, 0x66, 0x6c, 0x65, 0x65, 0x74, 0x6e, 0x6f, 0x64, 0x65, 0x67, 0x61, 0x74, + 0x65, 0x77, 0x61, 0x79, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x44, 0x69, + 0x73, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x65, 0x64, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x73, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x34, 0x2e, 0x66, 0x6c, 0x65, 0x65, 0x74, 0x6e, 0x6f, + 0x64, 0x65, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x70, + 0x6f, 0x72, 0x74, 0x44, 0x69, 0x73, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x65, 0x64, 0x44, 0x65, 0x76, + 0x69, 0x63, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x78, 0x0a, 0x13, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x50, 0x61, 0x69, 0x72, 0x65, 0x64, 0x44, 0x65, 0x76, 0x69, - 0x63, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x30, 0x2e, 0x66, 0x6c, 0x65, - 0x65, 0x74, 0x6e, 0x6f, 0x64, 0x65, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x2e, 0x76, 0x31, - 0x2e, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x50, 0x61, 0x69, 0x72, 0x65, 0x64, 0x44, 0x65, 0x76, - 0x69, 0x63, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x6a, 0x0a, 0x0d, - 0x43, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x12, 0x29, 0x2e, + 0x63, 0x65, 0x73, 0x12, 0x2f, 0x2e, 0x66, 0x6c, 0x65, 0x65, 0x74, 0x6e, 0x6f, 0x64, 0x65, 0x67, + 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, + 0x50, 0x61, 0x69, 0x72, 0x65, 0x64, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x73, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x1a, 0x30, 0x2e, 0x66, 0x6c, 0x65, 0x65, 0x74, 0x6e, 0x6f, 0x64, 0x65, + 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x70, 0x6f, 0x72, + 0x74, 0x50, 0x61, 0x69, 0x72, 0x65, 0x64, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x73, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x6a, 0x0a, 0x0d, 0x43, 0x6f, 0x6e, 0x74, 0x72, 0x6f, + 0x6c, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x12, 0x29, 0x2e, 0x66, 0x6c, 0x65, 0x65, 0x74, 0x6e, + 0x6f, 0x64, 0x65, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x6f, + 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x1a, 0x2a, 0x2e, 0x66, 0x6c, 0x65, 0x65, 0x74, 0x6e, 0x6f, 0x64, 0x65, 0x67, 0x61, + 0x74, 0x65, 0x77, 0x61, 0x79, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, + 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x28, 0x01, + 0x30, 0x01, 0x42, 0xf8, 0x01, 0x0a, 0x17, 0x63, 0x6f, 0x6d, 0x2e, 0x66, 0x6c, 0x65, 0x65, 0x74, + 0x6e, 0x6f, 0x64, 0x65, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x2e, 0x76, 0x31, 0x42, 0x15, + 0x46, 0x6c, 0x65, 0x65, 0x74, 0x6e, 0x6f, 0x64, 0x65, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, + 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x59, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, + 0x63, 0x6f, 0x6d, 0x2f, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2d, + 0x66, 0x6c, 0x65, 0x65, 0x74, 0x2f, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2f, 0x67, 0x65, 0x6e, + 0x65, 0x72, 0x61, 0x74, 0x65, 0x64, 0x2f, 0x67, 0x72, 0x70, 0x63, 0x2f, 0x66, 0x6c, 0x65, 0x65, + 0x74, 0x6e, 0x6f, 0x64, 0x65, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x2f, 0x76, 0x31, 0x3b, 0x66, 0x6c, 0x65, 0x65, 0x74, 0x6e, 0x6f, 0x64, 0x65, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, - 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x53, 0x74, 0x72, 0x65, 0x61, - 0x6d, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2a, 0x2e, 0x66, 0x6c, 0x65, 0x65, 0x74, - 0x6e, 0x6f, 0x64, 0x65, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x2e, 0x76, 0x31, 0x2e, 0x43, - 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x52, 0x65, 0x73, 0x70, - 0x6f, 0x6e, 0x73, 0x65, 0x28, 0x01, 0x30, 0x01, 0x42, 0xf8, 0x01, 0x0a, 0x17, 0x63, 0x6f, 0x6d, - 0x2e, 0x66, 0x6c, 0x65, 0x65, 0x74, 0x6e, 0x6f, 0x64, 0x65, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, - 0x79, 0x2e, 0x76, 0x31, 0x42, 0x15, 0x46, 0x6c, 0x65, 0x65, 0x74, 0x6e, 0x6f, 0x64, 0x65, 0x67, - 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x59, 0x67, - 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x2f, - 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2d, 0x66, 0x6c, 0x65, 0x65, 0x74, 0x2f, 0x73, 0x65, 0x72, 0x76, - 0x65, 0x72, 0x2f, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x64, 0x2f, 0x67, 0x72, 0x70, - 0x63, 0x2f, 0x66, 0x6c, 0x65, 0x65, 0x74, 0x6e, 0x6f, 0x64, 0x65, 0x67, 0x61, 0x74, 0x65, 0x77, - 0x61, 0x79, 0x2f, 0x76, 0x31, 0x3b, 0x66, 0x6c, 0x65, 0x65, 0x74, 0x6e, 0x6f, 0x64, 0x65, 0x67, - 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x76, 0x31, 0xa2, 0x02, 0x03, 0x46, 0x58, 0x58, 0xaa, 0x02, + 0x76, 0x31, 0xa2, 0x02, 0x03, 0x46, 0x58, 0x58, 0xaa, 0x02, 0x13, 0x46, 0x6c, 0x65, 0x65, 0x74, + 0x6e, 0x6f, 0x64, 0x65, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x2e, 0x56, 0x31, 0xca, 0x02, 0x13, 0x46, 0x6c, 0x65, 0x65, 0x74, 0x6e, 0x6f, 0x64, 0x65, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, - 0x79, 0x2e, 0x56, 0x31, 0xca, 0x02, 0x13, 0x46, 0x6c, 0x65, 0x65, 0x74, 0x6e, 0x6f, 0x64, 0x65, - 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x5c, 0x56, 0x31, 0xe2, 0x02, 0x1f, 0x46, 0x6c, 0x65, - 0x65, 0x74, 0x6e, 0x6f, 0x64, 0x65, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x5c, 0x56, 0x31, - 0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x14, 0x46, - 0x6c, 0x65, 0x65, 0x74, 0x6e, 0x6f, 0x64, 0x65, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x3a, - 0x3a, 0x56, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x79, 0x5c, 0x56, 0x31, 0xe2, 0x02, 0x1f, 0x46, 0x6c, 0x65, 0x65, 0x74, 0x6e, 0x6f, 0x64, 0x65, + 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x5c, 0x56, 0x31, 0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65, + 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x14, 0x46, 0x6c, 0x65, 0x65, 0x74, 0x6e, 0x6f, + 0x64, 0x65, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x3a, 0x3a, 0x56, 0x31, 0x62, 0x06, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x33, }) var ( @@ -4568,7 +4771,7 @@ func file_fleetnodegateway_v1_fleetnodegateway_proto_rawDescGZIP() []byte { } var file_fleetnodegateway_v1_fleetnodegateway_proto_enumTypes = make([]protoimpl.EnumInfo, 4) -var file_fleetnodegateway_v1_fleetnodegateway_proto_msgTypes = make([]protoimpl.MessageInfo, 56) +var file_fleetnodegateway_v1_fleetnodegateway_proto_msgTypes = make([]protoimpl.MessageInfo, 59) var file_fleetnodegateway_v1_fleetnodegateway_proto_goTypes = []any{ (EnrollmentStatus)(0), // 0: fleetnodegateway.v1.EnrollmentStatus (CommandArtifactPurpose)(0), // 1: fleetnodegateway.v1.CommandArtifactPurpose @@ -4615,40 +4818,43 @@ var file_fleetnodegateway_v1_fleetnodegateway_proto_goTypes = []any{ (*UncurtailAction)(nil), // 42: fleetnodegateway.v1.UncurtailAction (*GetMiningPoolsAction)(nil), // 43: fleetnodegateway.v1.GetMiningPoolsAction (*GetErrorsAction)(nil), // 44: fleetnodegateway.v1.GetErrorsAction - (*DownloadLogsAction)(nil), // 45: fleetnodegateway.v1.DownloadLogsAction - (*NodeEncryptedPayload)(nil), // 46: fleetnodegateway.v1.NodeEncryptedPayload - (*UpdateMinerPasswordAction)(nil), // 47: fleetnodegateway.v1.UpdateMinerPasswordAction - (*UpdateMinerPasswordResult)(nil), // 48: fleetnodegateway.v1.UpdateMinerPasswordResult - (*CurtailAction)(nil), // 49: fleetnodegateway.v1.CurtailAction - (*SetCoolingModeAction)(nil), // 50: fleetnodegateway.v1.SetCoolingModeAction - (*SetPowerTargetAction)(nil), // 51: fleetnodegateway.v1.SetPowerTargetAction - (*MiningPoolConfig)(nil), // 52: fleetnodegateway.v1.MiningPoolConfig - (*UpdateMiningPoolsAction)(nil), // 53: fleetnodegateway.v1.UpdateMiningPoolsAction - (*GetMiningPoolsResult)(nil), // 54: fleetnodegateway.v1.GetMiningPoolsResult - (*MinerErrorReport)(nil), // 55: fleetnodegateway.v1.MinerErrorReport - (*GetErrorsResult)(nil), // 56: fleetnodegateway.v1.GetErrorsResult - (*AgentCommand)(nil), // 57: fleetnodegateway.v1.AgentCommand - (*ControlAck)(nil), // 58: fleetnodegateway.v1.ControlAck - nil, // 59: fleetnodegateway.v1.MinerErrorReport.VendorAttributesEntry - (*timestamppb.Timestamp)(nil), // 60: google.protobuf.Timestamp - (v1.CurtailmentLevel)(0), // 61: curtailment.v1.CurtailmentLevel - (v11.CoolingMode)(0), // 62: common.v1.CoolingMode - (v12.PerformanceMode)(0), // 63: minercommand.v1.PerformanceMode - (v13.MinerError)(0), // 64: errors.v1.MinerError - (v13.Severity)(0), // 65: errors.v1.Severity - (v13.ComponentType)(0), // 66: errors.v1.ComponentType - (*v14.DiscoverRequest)(nil), // 67: pairing.v1.DiscoverRequest - (*v14.FleetNodePairRequest)(nil), // 68: pairing.v1.FleetNodePairRequest - (*v15.FleetNodeTelemetryRequest)(nil), // 69: telemetry.v1.FleetNodeTelemetryRequest + (*GetFirmwareUpdateStatusAction)(nil), // 45: fleetnodegateway.v1.GetFirmwareUpdateStatusAction + (*DownloadLogsAction)(nil), // 46: fleetnodegateway.v1.DownloadLogsAction + (*NodeEncryptedPayload)(nil), // 47: fleetnodegateway.v1.NodeEncryptedPayload + (*UpdateMinerPasswordAction)(nil), // 48: fleetnodegateway.v1.UpdateMinerPasswordAction + (*UpdateMinerPasswordResult)(nil), // 49: fleetnodegateway.v1.UpdateMinerPasswordResult + (*FirmwareUpdateAction)(nil), // 50: fleetnodegateway.v1.FirmwareUpdateAction + (*CurtailAction)(nil), // 51: fleetnodegateway.v1.CurtailAction + (*SetCoolingModeAction)(nil), // 52: fleetnodegateway.v1.SetCoolingModeAction + (*SetPowerTargetAction)(nil), // 53: fleetnodegateway.v1.SetPowerTargetAction + (*MiningPoolConfig)(nil), // 54: fleetnodegateway.v1.MiningPoolConfig + (*UpdateMiningPoolsAction)(nil), // 55: fleetnodegateway.v1.UpdateMiningPoolsAction + (*GetMiningPoolsResult)(nil), // 56: fleetnodegateway.v1.GetMiningPoolsResult + (*FirmwareUpdateStatusResult)(nil), // 57: fleetnodegateway.v1.FirmwareUpdateStatusResult + (*MinerErrorReport)(nil), // 58: fleetnodegateway.v1.MinerErrorReport + (*GetErrorsResult)(nil), // 59: fleetnodegateway.v1.GetErrorsResult + (*AgentCommand)(nil), // 60: fleetnodegateway.v1.AgentCommand + (*ControlAck)(nil), // 61: fleetnodegateway.v1.ControlAck + nil, // 62: fleetnodegateway.v1.MinerErrorReport.VendorAttributesEntry + (*timestamppb.Timestamp)(nil), // 63: google.protobuf.Timestamp + (v1.CurtailmentLevel)(0), // 64: curtailment.v1.CurtailmentLevel + (v11.CoolingMode)(0), // 65: common.v1.CoolingMode + (v12.PerformanceMode)(0), // 66: minercommand.v1.PerformanceMode + (v13.MinerError)(0), // 67: errors.v1.MinerError + (v13.Severity)(0), // 68: errors.v1.Severity + (v13.ComponentType)(0), // 69: errors.v1.ComponentType + (*v14.DiscoverRequest)(nil), // 70: pairing.v1.DiscoverRequest + (*v14.FleetNodePairRequest)(nil), // 71: pairing.v1.FleetNodePairRequest + (*v15.FleetNodeTelemetryRequest)(nil), // 72: telemetry.v1.FleetNodeTelemetryRequest } var file_fleetnodegateway_v1_fleetnodegateway_proto_depIdxs = []int32{ 0, // 0: fleetnodegateway.v1.RegisterResponse.enrollment_status:type_name -> fleetnodegateway.v1.EnrollmentStatus - 60, // 1: fleetnodegateway.v1.BeginAuthHandshakeResponse.expires_at:type_name -> google.protobuf.Timestamp - 60, // 2: fleetnodegateway.v1.CompleteAuthHandshakeResponse.expires_at:type_name -> google.protobuf.Timestamp - 60, // 3: fleetnodegateway.v1.UploadTelemetryRequest.captured_at:type_name -> google.protobuf.Timestamp - 60, // 4: fleetnodegateway.v1.UploadEventsRequest.captured_at:type_name -> google.protobuf.Timestamp - 60, // 5: fleetnodegateway.v1.UploadHeartbeatRequest.sent_at:type_name -> google.protobuf.Timestamp - 60, // 6: fleetnodegateway.v1.UploadHeartbeatResponse.received_at:type_name -> google.protobuf.Timestamp + 63, // 1: fleetnodegateway.v1.BeginAuthHandshakeResponse.expires_at:type_name -> google.protobuf.Timestamp + 63, // 2: fleetnodegateway.v1.CompleteAuthHandshakeResponse.expires_at:type_name -> google.protobuf.Timestamp + 63, // 3: fleetnodegateway.v1.UploadTelemetryRequest.captured_at:type_name -> google.protobuf.Timestamp + 63, // 4: fleetnodegateway.v1.UploadEventsRequest.captured_at:type_name -> google.protobuf.Timestamp + 63, // 5: fleetnodegateway.v1.UploadHeartbeatRequest.sent_at:type_name -> google.protobuf.Timestamp + 63, // 6: fleetnodegateway.v1.UploadHeartbeatResponse.received_at:type_name -> google.protobuf.Timestamp 1, // 7: fleetnodegateway.v1.CommandArtifactRef.purpose:type_name -> fleetnodegateway.v1.CommandArtifactPurpose 1, // 8: fleetnodegateway.v1.CommandArtifactUploadHeader.purpose:type_name -> fleetnodegateway.v1.CommandArtifactPurpose 17, // 9: fleetnodegateway.v1.UploadCommandArtifactRequest.header:type_name -> fleetnodegateway.v1.CommandArtifactUploadHeader @@ -4663,71 +4869,74 @@ var file_fleetnodegateway_v1_fleetnodegateway_proto_depIdxs = []int32{ 28, // 18: fleetnodegateway.v1.FleetNodePairResult.encrypted_credentials:type_name -> fleetnodegateway.v1.EncryptedCredentials 27, // 19: fleetnodegateway.v1.ReportPairedDevicesRequest.results:type_name -> fleetnodegateway.v1.FleetNodePairResult 33, // 20: fleetnodegateway.v1.ControlStreamRequest.hello:type_name -> fleetnodegateway.v1.ControlHello - 58, // 21: fleetnodegateway.v1.ControlStreamRequest.ack:type_name -> fleetnodegateway.v1.ControlAck + 61, // 21: fleetnodegateway.v1.ControlStreamRequest.ack:type_name -> fleetnodegateway.v1.ControlAck 34, // 22: fleetnodegateway.v1.ControlStreamResponse.accepted:type_name -> fleetnodegateway.v1.ControlAccepted 35, // 23: fleetnodegateway.v1.ControlStreamResponse.command:type_name -> fleetnodegateway.v1.ControlCommand - 60, // 24: fleetnodegateway.v1.ControlAccepted.server_time:type_name -> google.protobuf.Timestamp + 63, // 24: fleetnodegateway.v1.ControlAccepted.server_time:type_name -> google.protobuf.Timestamp 36, // 25: fleetnodegateway.v1.MinerCommand.target:type_name -> fleetnodegateway.v1.MinerConnectionDescriptor 38, // 26: fleetnodegateway.v1.MinerCommand.reboot:type_name -> fleetnodegateway.v1.RebootAction 39, // 27: fleetnodegateway.v1.MinerCommand.start_mining:type_name -> fleetnodegateway.v1.StartMiningAction 40, // 28: fleetnodegateway.v1.MinerCommand.stop_mining:type_name -> fleetnodegateway.v1.StopMiningAction 41, // 29: fleetnodegateway.v1.MinerCommand.blink_led:type_name -> fleetnodegateway.v1.BlinkLedAction - 49, // 30: fleetnodegateway.v1.MinerCommand.curtail:type_name -> fleetnodegateway.v1.CurtailAction + 51, // 30: fleetnodegateway.v1.MinerCommand.curtail:type_name -> fleetnodegateway.v1.CurtailAction 42, // 31: fleetnodegateway.v1.MinerCommand.uncurtail:type_name -> fleetnodegateway.v1.UncurtailAction - 50, // 32: fleetnodegateway.v1.MinerCommand.set_cooling_mode:type_name -> fleetnodegateway.v1.SetCoolingModeAction - 51, // 33: fleetnodegateway.v1.MinerCommand.set_power_target:type_name -> fleetnodegateway.v1.SetPowerTargetAction - 53, // 34: fleetnodegateway.v1.MinerCommand.update_mining_pools:type_name -> fleetnodegateway.v1.UpdateMiningPoolsAction + 52, // 32: fleetnodegateway.v1.MinerCommand.set_cooling_mode:type_name -> fleetnodegateway.v1.SetCoolingModeAction + 53, // 33: fleetnodegateway.v1.MinerCommand.set_power_target:type_name -> fleetnodegateway.v1.SetPowerTargetAction + 55, // 34: fleetnodegateway.v1.MinerCommand.update_mining_pools:type_name -> fleetnodegateway.v1.UpdateMiningPoolsAction 43, // 35: fleetnodegateway.v1.MinerCommand.get_mining_pools:type_name -> fleetnodegateway.v1.GetMiningPoolsAction 44, // 36: fleetnodegateway.v1.MinerCommand.get_errors:type_name -> fleetnodegateway.v1.GetErrorsAction - 47, // 37: fleetnodegateway.v1.MinerCommand.update_miner_password:type_name -> fleetnodegateway.v1.UpdateMinerPasswordAction - 45, // 38: fleetnodegateway.v1.MinerCommand.download_logs:type_name -> fleetnodegateway.v1.DownloadLogsAction - 46, // 39: fleetnodegateway.v1.UpdateMinerPasswordAction.encrypted_password_update:type_name -> fleetnodegateway.v1.NodeEncryptedPayload - 28, // 40: fleetnodegateway.v1.UpdateMinerPasswordResult.encrypted_credentials:type_name -> fleetnodegateway.v1.EncryptedCredentials - 61, // 41: fleetnodegateway.v1.CurtailAction.level:type_name -> curtailment.v1.CurtailmentLevel - 62, // 42: fleetnodegateway.v1.SetCoolingModeAction.mode:type_name -> common.v1.CoolingMode - 63, // 43: fleetnodegateway.v1.SetPowerTargetAction.performance_mode:type_name -> minercommand.v1.PerformanceMode - 52, // 44: fleetnodegateway.v1.UpdateMiningPoolsAction.pools:type_name -> fleetnodegateway.v1.MiningPoolConfig - 52, // 45: fleetnodegateway.v1.GetMiningPoolsResult.pools:type_name -> fleetnodegateway.v1.MiningPoolConfig - 64, // 46: fleetnodegateway.v1.MinerErrorReport.miner_error:type_name -> errors.v1.MinerError - 65, // 47: fleetnodegateway.v1.MinerErrorReport.severity:type_name -> errors.v1.Severity - 60, // 48: fleetnodegateway.v1.MinerErrorReport.first_seen_at:type_name -> google.protobuf.Timestamp - 60, // 49: fleetnodegateway.v1.MinerErrorReport.last_seen_at:type_name -> google.protobuf.Timestamp - 60, // 50: fleetnodegateway.v1.MinerErrorReport.closed_at:type_name -> google.protobuf.Timestamp - 59, // 51: fleetnodegateway.v1.MinerErrorReport.vendor_attributes:type_name -> fleetnodegateway.v1.MinerErrorReport.VendorAttributesEntry - 66, // 52: fleetnodegateway.v1.MinerErrorReport.component_type:type_name -> errors.v1.ComponentType - 55, // 53: fleetnodegateway.v1.GetErrorsResult.errors:type_name -> fleetnodegateway.v1.MinerErrorReport - 67, // 54: fleetnodegateway.v1.AgentCommand.discover:type_name -> pairing.v1.DiscoverRequest - 68, // 55: fleetnodegateway.v1.AgentCommand.pair:type_name -> pairing.v1.FleetNodePairRequest - 37, // 56: fleetnodegateway.v1.AgentCommand.miner_command:type_name -> fleetnodegateway.v1.MinerCommand - 69, // 57: fleetnodegateway.v1.AgentCommand.telemetry:type_name -> telemetry.v1.FleetNodeTelemetryRequest - 3, // 58: fleetnodegateway.v1.ControlAck.code:type_name -> fleetnodegateway.v1.AckCode - 4, // 59: fleetnodegateway.v1.FleetNodeGatewayService.Register:input_type -> fleetnodegateway.v1.RegisterRequest - 6, // 60: fleetnodegateway.v1.FleetNodeGatewayService.BeginAuthHandshake:input_type -> fleetnodegateway.v1.BeginAuthHandshakeRequest - 8, // 61: fleetnodegateway.v1.FleetNodeGatewayService.CompleteAuthHandshake:input_type -> fleetnodegateway.v1.CompleteAuthHandshakeRequest - 10, // 62: fleetnodegateway.v1.FleetNodeGatewayService.UploadTelemetry:input_type -> fleetnodegateway.v1.UploadTelemetryRequest - 12, // 63: fleetnodegateway.v1.FleetNodeGatewayService.UploadEvents:input_type -> fleetnodegateway.v1.UploadEventsRequest - 14, // 64: fleetnodegateway.v1.FleetNodeGatewayService.UploadHeartbeat:input_type -> fleetnodegateway.v1.UploadHeartbeatRequest - 19, // 65: fleetnodegateway.v1.FleetNodeGatewayService.UploadCommandArtifact:input_type -> fleetnodegateway.v1.UploadCommandArtifactRequest - 21, // 66: fleetnodegateway.v1.FleetNodeGatewayService.DownloadCommandArtifact:input_type -> fleetnodegateway.v1.DownloadCommandArtifactRequest - 24, // 67: fleetnodegateway.v1.FleetNodeGatewayService.ReportDiscoveredDevices:input_type -> fleetnodegateway.v1.ReportDiscoveredDevicesRequest - 29, // 68: fleetnodegateway.v1.FleetNodeGatewayService.ReportPairedDevices:input_type -> fleetnodegateway.v1.ReportPairedDevicesRequest - 31, // 69: fleetnodegateway.v1.FleetNodeGatewayService.ControlStream:input_type -> fleetnodegateway.v1.ControlStreamRequest - 5, // 70: fleetnodegateway.v1.FleetNodeGatewayService.Register:output_type -> fleetnodegateway.v1.RegisterResponse - 7, // 71: fleetnodegateway.v1.FleetNodeGatewayService.BeginAuthHandshake:output_type -> fleetnodegateway.v1.BeginAuthHandshakeResponse - 9, // 72: fleetnodegateway.v1.FleetNodeGatewayService.CompleteAuthHandshake:output_type -> fleetnodegateway.v1.CompleteAuthHandshakeResponse - 11, // 73: fleetnodegateway.v1.FleetNodeGatewayService.UploadTelemetry:output_type -> fleetnodegateway.v1.UploadTelemetryResponse - 13, // 74: fleetnodegateway.v1.FleetNodeGatewayService.UploadEvents:output_type -> fleetnodegateway.v1.UploadEventsResponse - 15, // 75: fleetnodegateway.v1.FleetNodeGatewayService.UploadHeartbeat:output_type -> fleetnodegateway.v1.UploadHeartbeatResponse - 20, // 76: fleetnodegateway.v1.FleetNodeGatewayService.UploadCommandArtifact:output_type -> fleetnodegateway.v1.UploadCommandArtifactResponse - 23, // 77: fleetnodegateway.v1.FleetNodeGatewayService.DownloadCommandArtifact:output_type -> fleetnodegateway.v1.DownloadCommandArtifactResponse - 26, // 78: fleetnodegateway.v1.FleetNodeGatewayService.ReportDiscoveredDevices:output_type -> fleetnodegateway.v1.ReportDiscoveredDevicesResponse - 30, // 79: fleetnodegateway.v1.FleetNodeGatewayService.ReportPairedDevices:output_type -> fleetnodegateway.v1.ReportPairedDevicesResponse - 32, // 80: fleetnodegateway.v1.FleetNodeGatewayService.ControlStream:output_type -> fleetnodegateway.v1.ControlStreamResponse - 70, // [70:81] is the sub-list for method output_type - 59, // [59:70] is the sub-list for method input_type - 59, // [59:59] is the sub-list for extension type_name - 59, // [59:59] is the sub-list for extension extendee - 0, // [0:59] is the sub-list for field type_name + 48, // 37: fleetnodegateway.v1.MinerCommand.update_miner_password:type_name -> fleetnodegateway.v1.UpdateMinerPasswordAction + 46, // 38: fleetnodegateway.v1.MinerCommand.download_logs:type_name -> fleetnodegateway.v1.DownloadLogsAction + 50, // 39: fleetnodegateway.v1.MinerCommand.firmware_update:type_name -> fleetnodegateway.v1.FirmwareUpdateAction + 45, // 40: fleetnodegateway.v1.MinerCommand.get_firmware_update_status:type_name -> fleetnodegateway.v1.GetFirmwareUpdateStatusAction + 47, // 41: fleetnodegateway.v1.UpdateMinerPasswordAction.encrypted_password_update:type_name -> fleetnodegateway.v1.NodeEncryptedPayload + 28, // 42: fleetnodegateway.v1.UpdateMinerPasswordResult.encrypted_credentials:type_name -> fleetnodegateway.v1.EncryptedCredentials + 16, // 43: fleetnodegateway.v1.FirmwareUpdateAction.artifact:type_name -> fleetnodegateway.v1.CommandArtifactRef + 64, // 44: fleetnodegateway.v1.CurtailAction.level:type_name -> curtailment.v1.CurtailmentLevel + 65, // 45: fleetnodegateway.v1.SetCoolingModeAction.mode:type_name -> common.v1.CoolingMode + 66, // 46: fleetnodegateway.v1.SetPowerTargetAction.performance_mode:type_name -> minercommand.v1.PerformanceMode + 54, // 47: fleetnodegateway.v1.UpdateMiningPoolsAction.pools:type_name -> fleetnodegateway.v1.MiningPoolConfig + 54, // 48: fleetnodegateway.v1.GetMiningPoolsResult.pools:type_name -> fleetnodegateway.v1.MiningPoolConfig + 67, // 49: fleetnodegateway.v1.MinerErrorReport.miner_error:type_name -> errors.v1.MinerError + 68, // 50: fleetnodegateway.v1.MinerErrorReport.severity:type_name -> errors.v1.Severity + 63, // 51: fleetnodegateway.v1.MinerErrorReport.first_seen_at:type_name -> google.protobuf.Timestamp + 63, // 52: fleetnodegateway.v1.MinerErrorReport.last_seen_at:type_name -> google.protobuf.Timestamp + 63, // 53: fleetnodegateway.v1.MinerErrorReport.closed_at:type_name -> google.protobuf.Timestamp + 62, // 54: fleetnodegateway.v1.MinerErrorReport.vendor_attributes:type_name -> fleetnodegateway.v1.MinerErrorReport.VendorAttributesEntry + 69, // 55: fleetnodegateway.v1.MinerErrorReport.component_type:type_name -> errors.v1.ComponentType + 58, // 56: fleetnodegateway.v1.GetErrorsResult.errors:type_name -> fleetnodegateway.v1.MinerErrorReport + 70, // 57: fleetnodegateway.v1.AgentCommand.discover:type_name -> pairing.v1.DiscoverRequest + 71, // 58: fleetnodegateway.v1.AgentCommand.pair:type_name -> pairing.v1.FleetNodePairRequest + 37, // 59: fleetnodegateway.v1.AgentCommand.miner_command:type_name -> fleetnodegateway.v1.MinerCommand + 72, // 60: fleetnodegateway.v1.AgentCommand.telemetry:type_name -> telemetry.v1.FleetNodeTelemetryRequest + 3, // 61: fleetnodegateway.v1.ControlAck.code:type_name -> fleetnodegateway.v1.AckCode + 4, // 62: fleetnodegateway.v1.FleetNodeGatewayService.Register:input_type -> fleetnodegateway.v1.RegisterRequest + 6, // 63: fleetnodegateway.v1.FleetNodeGatewayService.BeginAuthHandshake:input_type -> fleetnodegateway.v1.BeginAuthHandshakeRequest + 8, // 64: fleetnodegateway.v1.FleetNodeGatewayService.CompleteAuthHandshake:input_type -> fleetnodegateway.v1.CompleteAuthHandshakeRequest + 10, // 65: fleetnodegateway.v1.FleetNodeGatewayService.UploadTelemetry:input_type -> fleetnodegateway.v1.UploadTelemetryRequest + 12, // 66: fleetnodegateway.v1.FleetNodeGatewayService.UploadEvents:input_type -> fleetnodegateway.v1.UploadEventsRequest + 14, // 67: fleetnodegateway.v1.FleetNodeGatewayService.UploadHeartbeat:input_type -> fleetnodegateway.v1.UploadHeartbeatRequest + 19, // 68: fleetnodegateway.v1.FleetNodeGatewayService.UploadCommandArtifact:input_type -> fleetnodegateway.v1.UploadCommandArtifactRequest + 21, // 69: fleetnodegateway.v1.FleetNodeGatewayService.DownloadCommandArtifact:input_type -> fleetnodegateway.v1.DownloadCommandArtifactRequest + 24, // 70: fleetnodegateway.v1.FleetNodeGatewayService.ReportDiscoveredDevices:input_type -> fleetnodegateway.v1.ReportDiscoveredDevicesRequest + 29, // 71: fleetnodegateway.v1.FleetNodeGatewayService.ReportPairedDevices:input_type -> fleetnodegateway.v1.ReportPairedDevicesRequest + 31, // 72: fleetnodegateway.v1.FleetNodeGatewayService.ControlStream:input_type -> fleetnodegateway.v1.ControlStreamRequest + 5, // 73: fleetnodegateway.v1.FleetNodeGatewayService.Register:output_type -> fleetnodegateway.v1.RegisterResponse + 7, // 74: fleetnodegateway.v1.FleetNodeGatewayService.BeginAuthHandshake:output_type -> fleetnodegateway.v1.BeginAuthHandshakeResponse + 9, // 75: fleetnodegateway.v1.FleetNodeGatewayService.CompleteAuthHandshake:output_type -> fleetnodegateway.v1.CompleteAuthHandshakeResponse + 11, // 76: fleetnodegateway.v1.FleetNodeGatewayService.UploadTelemetry:output_type -> fleetnodegateway.v1.UploadTelemetryResponse + 13, // 77: fleetnodegateway.v1.FleetNodeGatewayService.UploadEvents:output_type -> fleetnodegateway.v1.UploadEventsResponse + 15, // 78: fleetnodegateway.v1.FleetNodeGatewayService.UploadHeartbeat:output_type -> fleetnodegateway.v1.UploadHeartbeatResponse + 20, // 79: fleetnodegateway.v1.FleetNodeGatewayService.UploadCommandArtifact:output_type -> fleetnodegateway.v1.UploadCommandArtifactResponse + 23, // 80: fleetnodegateway.v1.FleetNodeGatewayService.DownloadCommandArtifact:output_type -> fleetnodegateway.v1.DownloadCommandArtifactResponse + 26, // 81: fleetnodegateway.v1.FleetNodeGatewayService.ReportDiscoveredDevices:output_type -> fleetnodegateway.v1.ReportDiscoveredDevicesResponse + 30, // 82: fleetnodegateway.v1.FleetNodeGatewayService.ReportPairedDevices:output_type -> fleetnodegateway.v1.ReportPairedDevicesResponse + 32, // 83: fleetnodegateway.v1.FleetNodeGatewayService.ControlStream:output_type -> fleetnodegateway.v1.ControlStreamResponse + 73, // [73:84] is the sub-list for method output_type + 62, // [62:73] is the sub-list for method input_type + 62, // [62:62] is the sub-list for extension type_name + 62, // [62:62] is the sub-list for extension extendee + 0, // [0:62] is the sub-list for field type_name } func init() { file_fleetnodegateway_v1_fleetnodegateway_proto_init() } @@ -4766,9 +4975,12 @@ func file_fleetnodegateway_v1_fleetnodegateway_proto_init() { (*MinerCommand_GetErrors)(nil), (*MinerCommand_UpdateMinerPassword)(nil), (*MinerCommand_DownloadLogs)(nil), + (*MinerCommand_FirmwareUpdate)(nil), + (*MinerCommand_GetFirmwareUpdateStatus)(nil), } - file_fleetnodegateway_v1_fleetnodegateway_proto_msgTypes[51].OneofWrappers = []any{} - file_fleetnodegateway_v1_fleetnodegateway_proto_msgTypes[53].OneofWrappers = []any{ + file_fleetnodegateway_v1_fleetnodegateway_proto_msgTypes[53].OneofWrappers = []any{} + file_fleetnodegateway_v1_fleetnodegateway_proto_msgTypes[54].OneofWrappers = []any{} + file_fleetnodegateway_v1_fleetnodegateway_proto_msgTypes[56].OneofWrappers = []any{ (*AgentCommand_Discover)(nil), (*AgentCommand_Pair)(nil), (*AgentCommand_MinerCommand)(nil), @@ -4780,7 +4992,7 @@ func file_fleetnodegateway_v1_fleetnodegateway_proto_init() { GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: unsafe.Slice(unsafe.StringData(file_fleetnodegateway_v1_fleetnodegateway_proto_rawDesc), len(file_fleetnodegateway_v1_fleetnodegateway_proto_rawDesc)), NumEnums: 4, - NumMessages: 56, + NumMessages: 59, NumExtensions: 0, NumServices: 1, }, diff --git a/server/internal/domain/command/execution_service.go b/server/internal/domain/command/execution_service.go index ce05df4ec..91bd031e4 100644 --- a/server/internal/domain/command/execution_service.go +++ b/server/internal/domain/command/execution_service.go @@ -544,22 +544,19 @@ func (es *ExecutionService) executeCommandOnDevice(ctx context.Context, commandT err = fleeterror.NewInternalErrorf("error unmarshalling firmware update payload: %v", fwErr) break } - reader, filename, size, openErr := es.filesService.OpenFirmwareFile(p.FirmwareFileID) + reader, info, openErr := es.filesService.OpenFirmwareFileWithInfo(p.FirmwareFileID) if openErr != nil { err = fleeterror.NewInternalErrorf("error opening firmware file: %v", openErr) break } defer reader.Close() - filePath, pathErr := es.filesService.GetFirmwareFilePath(p.FirmwareFileID) - if pathErr != nil { - err = fleeterror.NewInternalErrorf("error resolving firmware file path: %v", pathErr) - break - } err = minerInfo.FirmwareUpdate(ctx, sdk.FirmwareFile{ Reader: reader, - Filename: filename, - Size: size, - FilePath: filePath, + ID: info.ID, + Filename: info.Filename, + Size: info.Size, + SHA256: info.SHA256, + FilePath: info.FilePath, }) if err != nil { break diff --git a/server/internal/domain/command/execution_service_test.go b/server/internal/domain/command/execution_service_test.go index 2c31c0fc8..a4cbd89f0 100644 --- a/server/internal/domain/command/execution_service_test.go +++ b/server/internal/domain/command/execution_service_test.go @@ -6,6 +6,8 @@ import ( "encoding/json" "errors" "fmt" + "io" + "strings" "testing" "time" @@ -22,6 +24,7 @@ import ( storeMocks "github.com/block/proto-fleet/server/internal/domain/stores/interfaces/mocks" tmodels "github.com/block/proto-fleet/server/internal/domain/telemetry/models" "github.com/block/proto-fleet/server/internal/infrastructure/encrypt" + "github.com/block/proto-fleet/server/internal/infrastructure/files" "github.com/block/proto-fleet/server/internal/infrastructure/queue" "github.com/block/proto-fleet/server/internal/infrastructure/queue/mocks" sdk "github.com/block/proto-fleet/server/sdk/v1" @@ -666,6 +669,62 @@ func TestFirmwareUpdateAutoReboot(t *testing.T) { }) } +func TestExecuteCommandOnDevice_FirmwareUpdatePassesFileMetadata(t *testing.T) { + t.Chdir(t.TempDir()) + ctrl := gomock.NewController(t) + defer ctrl.Finish() + + filesService, err := files.NewService(files.Config{}) + require.NoError(t, err) + content := "firmware image" + fileID, err := filesService.SaveFirmwareFile("update.swu", strings.NewReader(content)) + require.NoError(t, err) + + mockQueue := mocks.NewMockMessageQueue(ctrl) + mockMinerGetter := minerMocks.NewMockCachedMinerGetter(ctrl) + mockMiner := minerIfaceMocks.NewMockMiner(ctrl) + mockDeviceStore := storeMocks.NewMockDeviceStore(ctrl) + + payloadBytes, err := json.Marshal(dto.FirmwareUpdatePayload{FirmwareFileID: fileID}) + require.NoError(t, err) + message := queue.Message{ + ID: 9, + CommandType: commandtype.FirmwareUpdate, + DeviceID: 42, + Payload: payloadBytes, + } + + mockMiner.EXPECT().GetOrgID().Return(int64(0)).AnyTimes() + mockMiner.EXPECT().GetSiteID().Return(int64(0)).AnyTimes() + mockMinerGetter.EXPECT().GetMiner(gomock.Any(), int64(42)).Return(mockMiner, nil) + mockMiner.EXPECT().FirmwareUpdate(gomock.Any(), gomock.Any()). + DoAndReturn(func(_ context.Context, firmware sdk.FirmwareFile) error { + assert.Equal(t, fileID, firmware.ID) + assert.Equal(t, "update.swu", firmware.Filename) + assert.Equal(t, int64(len(content)), firmware.Size) + assert.NotEmpty(t, firmware.SHA256) + assert.NotEmpty(t, firmware.FilePath) + data, err := io.ReadAll(firmware.Reader) + require.NoError(t, err) + assert.Equal(t, content, string(data)) + return nil + }) + mockMiner.EXPECT().Reboot(gomock.Any()).Return(nil) + mockMiner.EXPECT().GetID().Return(models.DeviceIdentifier("device-123")) + mockDeviceStore.EXPECT(). + GetDeviceStatusForDeviceIdentifiers(gomock.Any(), []tmodels.DeviceIdentifier{"device-123"}). + Return(map[tmodels.DeviceIdentifier]models.MinerStatus{}, nil) + + svc := NewExecutionService(t.Context(), &Config{ + MaxWorkers: 5, + MasterPollingInterval: 10 * time.Millisecond, + WorkerExecutionTimeout: 5 * time.Second, + }, nil, mockQueue, nil, nil, mockMinerGetter, mockDeviceStore, nil, filesService) + + _, _, err = svc.executeCommandOnDevice(t.Context(), commandtype.FirmwareUpdate, message) + require.NoError(t, err) +} + func TestExecuteCommandOnDevice_UpdateMiningPools_UsesStoredWorkerName(t *testing.T) { ctrl := gomock.NewController(t) defer ctrl.Finish() diff --git a/server/internal/domain/miner/remote_fleetnode_miner.go b/server/internal/domain/miner/remote_fleetnode_miner.go index e43cd8cb3..8eb0b14de 100644 --- a/server/internal/domain/miner/remote_fleetnode_miner.go +++ b/server/internal/domain/miner/remote_fleetnode_miner.go @@ -40,6 +40,7 @@ const ( var remoteTelemetryDefaultCommandTimeout = 5 * time.Second var _ interfaces.Miner = (*RemoteFleetNodeMiner)(nil) +var _ interfaces.FirmwareUpdateStatusProvider = (*RemoteFleetNodeMiner)(nil) type remoteTelemetryRoute struct { fleetNodeID int64 @@ -591,6 +592,14 @@ func (m *RemoteFleetNodeMiner) FirmwareUpdate(ctx context.Context, firmware sdk. return m.unsupported("firmware update") } +func (m *RemoteFleetNodeMiner) GetFirmwareUpdateStatus(ctx context.Context) (*sdk.FirmwareUpdateStatus, error) { + provider, ok := m.delegate.(interfaces.FirmwareUpdateStatusProvider) + if ok { + return provider.GetFirmwareUpdateStatus(ctx) + } + return nil, m.unsupported("get firmware update status") +} + func (m *RemoteFleetNodeMiner) Unpair(ctx context.Context) error { if m.delegate != nil { return m.delegate.Unpair(ctx) diff --git a/server/internal/domain/miner/remotenode/miner.go b/server/internal/domain/miner/remotenode/miner.go index ceea812eb..ad392e799 100644 --- a/server/internal/domain/miner/remotenode/miner.go +++ b/server/internal/domain/miner/remotenode/miner.go @@ -96,12 +96,17 @@ type Miner struct { } var _ interfaces.Miner = (*Miner)(nil) +var _ interfaces.FirmwareUpdateStatusProvider = (*Miner)(nil) // Keep the remote diagnostics wait aligned with the cloud command worker budget // and above the fleet node's minerCommandTimeout, while still bounding callers // such as telemetry error polling that use a long-lived worker context. var remoteGetErrorsCommandTimeout = 30 * time.Second +// Keep each firmware install-status poll short so a hung node/plugin can't hold +// the per-node command gate for the full firmware update worker budget. +var remoteFirmwareStatusCommandTimeout = 30 * time.Second + const maxErrorColumnStringLen = 255 // New builds a remote-node miner. It returns an error only if the connection @@ -197,6 +202,19 @@ func (m *Miner) dispatch(ctx context.Context, mc *gatewaypb.MinerCommand) error return ackToError(ack) } +func (m *Miner) dispatchWithArtifacts(ctx context.Context, mc *gatewaypb.MinerCommand, artifacts []control.ArtifactExpectation) error { + release, err := m.acquireGate(ctx) + if err != nil { + return err + } + defer release() + ack, _, err := m.sendWithoutGateWithArtifactResults(ctx, mc, artifacts) + if err != nil { + return err + } + return ackToError(ack) +} + func (m *Miner) send(ctx context.Context, mc *gatewaypb.MinerCommand) (*gatewaypb.ControlAck, error) { release, err := m.acquireGate(ctx) if err != nil { @@ -206,6 +224,23 @@ func (m *Miner) send(ctx context.Context, mc *gatewaypb.MinerCommand) (*gatewayp return m.sendWithoutGate(ctx, mc) } +func (m *Miner) sendWithCommandTimeout(ctx context.Context, timeout time.Duration, mc *gatewaypb.MinerCommand) (*gatewaypb.ControlAck, error) { + release, err := m.acquireGate(ctx) + if err != nil { + return nil, err + } + defer release() + + commandCtx, cancel := context.WithTimeout(ctx, timeout) + defer cancel() + + ack, err := m.sendWithoutGate(commandCtx, mc) + if err != nil && errors.Is(err, context.DeadlineExceeded) { + return nil, fleeterror.NewConnectionError(m.desc.GetDeviceIdentifier(), err) + } + return ack, err +} + func (m *Miner) acquireGate(ctx context.Context) (func(), error) { return acquireFleetNodeGate(ctx, m.gate, m.fleetNodeID, "fleet node command") } @@ -470,8 +505,70 @@ func logDownloadRejectedError(ack *gatewaypb.ControlAck) error { return fleeterror.NewFailedPreconditionErrorf("fleet node rejected miner log download: %s", reason) } -func (m *Miner) FirmwareUpdate(_ context.Context, _ sdk.FirmwareFile) error { - return errUnsupported("FirmwareUpdate") +func (m *Miner) FirmwareUpdate(ctx context.Context, firmware sdk.FirmwareFile) error { + if firmware.ID == "" { + return fleeterror.NewInternalError("firmware file ID is required for fleet-node firmware update") + } + if firmware.Filename == "" { + return fleeterror.NewInternalError("firmware filename is required for fleet-node firmware update") + } + if firmware.Size <= 0 { + return fleeterror.NewInternalError("firmware size is required for fleet-node firmware update") + } + if firmware.SHA256 == "" { + return fleeterror.NewInternalError("firmware sha256 is required for fleet-node firmware update") + } + ref := &gatewaypb.CommandArtifactRef{ + ArtifactId: firmware.ID, + Purpose: gatewaypb.CommandArtifactPurpose_COMMAND_ARTIFACT_PURPOSE_FIRMWARE_PAYLOAD, + Filename: firmware.Filename, + SizeBytes: firmware.Size, + Sha256: firmware.SHA256, + } + expectation := control.ArtifactExpectation{ + Direction: control.ArtifactDirectionDownload, + Purpose: ref.GetPurpose(), + ArtifactID: ref.GetArtifactId(), + DeviceIdentifier: m.desc.GetDeviceIdentifier(), + } + return m.dispatchWithArtifacts(ctx, &gatewaypb.MinerCommand{Action: &gatewaypb.MinerCommand_FirmwareUpdate{ + FirmwareUpdate: &gatewaypb.FirmwareUpdateAction{Artifact: ref}, + }}, []control.ArtifactExpectation{expectation}) +} + +func (m *Miner) GetFirmwareUpdateStatus(ctx context.Context) (*sdk.FirmwareUpdateStatus, error) { + ack, err := m.sendWithCommandTimeout(ctx, remoteFirmwareStatusCommandTimeout, &gatewaypb.MinerCommand{Action: &gatewaypb.MinerCommand_GetFirmwareUpdateStatus{ + GetFirmwareUpdateStatus: &gatewaypb.GetFirmwareUpdateStatusAction{}, + }}) + if err != nil { + return nil, err + } + if err := ackToError(ack); err != nil { + return nil, err + } + if len(ack.GetPayload()) == 0 { + return nil, nil + } + + var result gatewaypb.FirmwareUpdateStatusResult + if err := proto.Unmarshal(ack.GetPayload(), &result); err != nil { + return nil, fleeterror.NewInternalErrorf("unmarshal firmware update status result: %v", err) + } + if err := protovalidate.Validate(&result); err != nil { + return nil, fleeterror.NewInternalErrorf("invalid firmware update status result: %v", err) + } + if result.GetState() == "" { + return nil, nil + } + status := &sdk.FirmwareUpdateStatus{ + State: result.GetState(), + Error: result.Error, + } + if result.Progress != nil { + progress := int(result.GetProgress()) + status.Progress = &progress + } + return status, nil } func (m *Miner) Unpair(_ context.Context) error { @@ -487,22 +584,10 @@ func (m *Miner) GetDeviceStatus(_ context.Context) (minermodels.MinerStatus, err } func (m *Miner) GetErrors(ctx context.Context) (models.DeviceErrors, error) { - release, err := m.acquireGate(ctx) - if err != nil { - return models.DeviceErrors{}, err - } - defer release() - - commandCtx, cancel := context.WithTimeout(ctx, remoteGetErrorsCommandTimeout) - defer cancel() - - ack, err := m.sendWithoutGate(commandCtx, &gatewaypb.MinerCommand{Action: &gatewaypb.MinerCommand_GetErrors{ + ack, err := m.sendWithCommandTimeout(ctx, remoteGetErrorsCommandTimeout, &gatewaypb.MinerCommand{Action: &gatewaypb.MinerCommand_GetErrors{ GetErrors: &gatewaypb.GetErrorsAction{}, }}) if err != nil { - if errors.Is(err, context.DeadlineExceeded) { - return models.DeviceErrors{}, fleeterror.NewConnectionError(m.desc.GetDeviceIdentifier(), err) - } return models.DeviceErrors{}, err } if err := ackToError(ack); err != nil { diff --git a/server/internal/domain/miner/remotenode/miner_test.go b/server/internal/domain/miner/remotenode/miner_test.go index 4c819d16a..afe97ce41 100644 --- a/server/internal/domain/miner/remotenode/miner_test.go +++ b/server/internal/domain/miner/remotenode/miner_test.go @@ -392,6 +392,93 @@ func TestMiner_GetMiningPools_DecodesPayload(t *testing.T) { assert.NotNil(t, decodeSent(t, s).GetGetMiningPools()) } +func TestMiner_FirmwareUpdate_SendsArtifactCommand(t *testing.T) { + s := &fakeSender{ack: &gatewaypb.ControlAck{Succeeded: true, Code: gatewaypb.AckCode_ACK_CODE_OK}} + m := newTestMiner(t, s) + + err := m.FirmwareUpdate(context.Background(), sdk.FirmwareFile{ + ID: "11111111-1111-1111-1111-111111111111", + Filename: "update.swu", + Size: 42, + SHA256: strings.Repeat("a", 64), + }) + + require.NoError(t, err) + mc := decodeSent(t, s) + ref := mc.GetFirmwareUpdate().GetArtifact() + require.NotNil(t, ref) + assert.Equal(t, "11111111-1111-1111-1111-111111111111", ref.GetArtifactId()) + assert.Equal(t, gatewaypb.CommandArtifactPurpose_COMMAND_ARTIFACT_PURPOSE_FIRMWARE_PAYLOAD, ref.GetPurpose()) + assert.Equal(t, "update.swu", ref.GetFilename()) + assert.Equal(t, int64(42), ref.GetSizeBytes()) + assert.Equal(t, strings.Repeat("a", 64), ref.GetSha256()) + require.Len(t, s.artifacts, 1) + assert.Equal(t, control.ArtifactDirectionDownload, s.artifacts[0].Direction) + assert.Equal(t, ref.GetPurpose(), s.artifacts[0].Purpose) + assert.Equal(t, ref.GetArtifactId(), s.artifacts[0].ArtifactID) + assert.Equal(t, "dev-1", s.artifacts[0].DeviceIdentifier) +} + +func TestMiner_GetFirmwareUpdateStatus_DecodesPayload(t *testing.T) { + progress := int32(72) + errMsg := "installing" + payload, err := proto.Marshal(&gatewaypb.FirmwareUpdateStatusResult{ + State: "installing", + Progress: &progress, + Error: &errMsg, + }) + require.NoError(t, err) + s := &fakeSender{ack: &gatewaypb.ControlAck{ + Succeeded: true, + Code: gatewaypb.AckCode_ACK_CODE_OK, + Payload: payload, + }} + m := newTestMiner(t, s) + + status, err := m.GetFirmwareUpdateStatus(context.Background()) + + require.NoError(t, err) + require.NotNil(t, status) + assert.Equal(t, "installing", status.State) + require.NotNil(t, status.Progress) + assert.Equal(t, 72, *status.Progress) + require.NotNil(t, status.Error) + assert.Equal(t, errMsg, *status.Error) + assert.NotNil(t, decodeSent(t, s).GetGetFirmwareUpdateStatus()) +} + +func TestMiner_GetFirmwareUpdateStatus_EmptyPayloadReturnsNilStatus(t *testing.T) { + s := okSender() + m := newTestMiner(t, s) + + status, err := m.GetFirmwareUpdateStatus(context.Background()) + + require.NoError(t, err) + assert.Nil(t, status) + assert.NotNil(t, decodeSent(t, s).GetGetFirmwareUpdateStatus()) +} + +func TestMiner_GetFirmwareUpdateStatus_UsesBoundedCommandContext(t *testing.T) { + oldTimeout := remoteFirmwareStatusCommandTimeout + remoteFirmwareStatusCommandTimeout = 25 * time.Millisecond + t.Cleanup(func() { remoteFirmwareStatusCommandTimeout = oldTimeout }) + s := &blockingSender{started: make(chan struct{})} + m := newTestMiner(t, s) + + startedAt := time.Now() + _, err := m.GetFirmwareUpdateStatus(context.Background()) + + require.Error(t, err) + assert.ErrorIs(t, err, context.DeadlineExceeded) + assert.True(t, fleeterror.IsConnectionError(err), "expected connection error, got %v", err) + assert.Less(t, time.Since(startedAt), time.Second) + select { + case <-s.started: + default: + t.Fatal("SendCommand was not called") + } +} + func TestMiner_GetErrors_DecodesPayload(t *testing.T) { // Arrange now := time.Now().UTC().Truncate(time.Millisecond) diff --git a/server/internal/handlers/fleetnode/gateway/handler.go b/server/internal/handlers/fleetnode/gateway/handler.go index babc2987e..a594787da 100644 --- a/server/internal/handlers/fleetnode/gateway/handler.go +++ b/server/internal/handlers/fleetnode/gateway/handler.go @@ -228,7 +228,7 @@ func (h *Handler) DownloadCommandArtifact(ctx context.Context, req *connect.Requ } defer h.registry.ReinstateCommandArtifactTransfer(subject.FleetNodeID, req.Msg.GetCommandId(), expectation) - reader, info, err := h.files.OpenCommandArtifact(ref.GetArtifactId()) + reader, info, err := h.openCommandArtifactPayload(ref) if err != nil { return err } @@ -267,6 +267,22 @@ func (h *Handler) DownloadCommandArtifact(ctx context.Context, req *connect.Requ } } +func (h *Handler) openCommandArtifactPayload(ref *pb.CommandArtifactRef) (io.ReadCloser, files.CommandArtifactInfo, error) { + if ref.GetPurpose() != pb.CommandArtifactPurpose_COMMAND_ARTIFACT_PURPOSE_FIRMWARE_PAYLOAD { + return h.files.OpenCommandArtifact(ref.GetArtifactId()) + } + reader, info, err := h.files.OpenFirmwareFileWithInfo(ref.GetArtifactId()) + if err != nil { + return nil, files.CommandArtifactInfo{}, err + } + return reader, files.CommandArtifactInfo{ + ID: info.ID, + Filename: info.Filename, + Size: info.Size, + SHA256: info.SHA256, + }, nil +} + func sendCommandArtifactDownloadResponse(ctx context.Context, stream *connect.ServerStream[pb.DownloadCommandArtifactResponse], msg *pb.DownloadCommandArtifactResponse) error { if err := ctx.Err(); err != nil { return contextConnectError(ctx.Err(), "command artifact download deadline exceeded") diff --git a/server/internal/handlers/fleetnode/gateway/handler_artifact_test.go b/server/internal/handlers/fleetnode/gateway/handler_artifact_test.go index 478a77b4a..7997dac9d 100644 --- a/server/internal/handlers/fleetnode/gateway/handler_artifact_test.go +++ b/server/internal/handlers/fleetnode/gateway/handler_artifact_test.go @@ -34,6 +34,7 @@ func newArtifactTestClient(t *testing.T, opts ...connect.HandlerOption) (*contro h := &controlHarness{ handler: gateway.NewHandler(nil, nil, nil, registry, filesService), registry: registry, + files: filesService, fleetNodeID: 44, } return h, startControlServer(t, h, opts...) @@ -57,6 +58,15 @@ func downloadExpectation(artifact *pb.CommandArtifactRef) control.ArtifactExpect } } +func firmwareDownloadExpectation(artifact *pb.CommandArtifactRef) control.ArtifactExpectation { + return control.ArtifactExpectation{ + Direction: control.ArtifactDirectionDownload, + Purpose: pb.CommandArtifactPurpose_COMMAND_ARTIFACT_PURPOSE_FIRMWARE_PAYLOAD, + ArtifactID: artifact.GetArtifactId(), + DeviceIdentifier: "miner-a", + } +} + func uploadHeaderRequest(commandID string, payload []byte) *pb.UploadCommandArtifactRequest { return &pb.UploadCommandArtifactRequest{Part: &pb.UploadCommandArtifactRequest_Header{ Header: &pb.CommandArtifactUploadHeader{ @@ -227,6 +237,53 @@ func TestCommandArtifactUploadAndDownloadRequireInFlightExpectation(t *testing.T assert.Equal(t, connect.CodeFailedPrecondition, connect.CodeOf(badDownload.Err())) } +func TestDownloadCommandArtifactServesFirmwarePayload(t *testing.T) { + h, client := newArtifactTestClient(t) + payload := []byte("firmware image bytes") + fileID, err := h.files.SaveFirmwareFile("update.swu", bytes.NewReader(payload)) + require.NoError(t, err) + _, info, err := h.files.OpenFirmwareFileWithInfo(fileID) + require.NoError(t, err) + ref := &pb.CommandArtifactRef{ + ArtifactId: info.ID, + Purpose: pb.CommandArtifactPurpose_COMMAND_ARTIFACT_PURPOSE_FIRMWARE_PAYLOAD, + Filename: info.Filename, + SizeBytes: info.Size, + Sha256: info.SHA256, + } + + commandID := "download-firmware-command" + stream, done := startAckOnlyCommandWithArtifacts(t, h, commandID, []control.ArtifactExpectation{firmwareDownloadExpectation(ref)}) + download, err := client.DownloadCommandArtifact(context.Background(), connect.NewRequest(&pb.DownloadCommandArtifactRequest{ + CommandId: commandID, + Artifact: ref, + DeviceIdentifier: "miner-a", + })) + require.NoError(t, err) + defer download.Close() + + var got bytes.Buffer + var header *pb.CommandArtifactRef + for download.Receive() { + msg := download.Msg() + if h := msg.GetHeader(); h != nil { + header = h.GetArtifact() + continue + } + _, err := got.Write(msg.GetChunk().GetData()) + require.NoError(t, err) + } + require.NoError(t, download.Err()) + require.NotNil(t, header) + assert.Equal(t, ref.GetArtifactId(), header.GetArtifactId()) + assert.Equal(t, ref.GetPurpose(), header.GetPurpose()) + assert.Equal(t, ref.GetFilename(), header.GetFilename()) + assert.Equal(t, ref.GetSizeBytes(), header.GetSizeBytes()) + assert.Equal(t, ref.GetSha256(), header.GetSha256()) + assert.Equal(t, payload, got.Bytes()) + finishAckOnlyCommand(t, stream, commandID, done) +} + func TestCommandArtifactUploadTimeoutReleasesSlotAndAllowsRetry(t *testing.T) { oldHeaderTimeout := gateway.CommandArtifactUploadHeaderTimeout oldChunkTimeout := gateway.CommandArtifactUploadChunkTimeout diff --git a/server/internal/handlers/fleetnode/gateway/handler_controlstream_test.go b/server/internal/handlers/fleetnode/gateway/handler_controlstream_test.go index 5f0d60199..2c000557e 100644 --- a/server/internal/handlers/fleetnode/gateway/handler_controlstream_test.go +++ b/server/internal/handlers/fleetnode/gateway/handler_controlstream_test.go @@ -37,6 +37,7 @@ import ( type controlHarness struct { handler *gateway.Handler registry *control.Registry + files *files.Service fleetNodeID int64 db *sql.DB } @@ -81,6 +82,7 @@ func newControlHarness(t *testing.T) *controlHarness { return &controlHarness{ handler: gateway.NewHandler(enrollmentSvc, authSvc, pairingSvc, registry, filesService), registry: registry, + files: filesService, fleetNodeID: agent.ID, db: db, } diff --git a/server/internal/infrastructure/files/firmware.go b/server/internal/infrastructure/files/firmware.go index 7cdcbc777..1d01caa1a 100644 --- a/server/internal/infrastructure/files/firmware.go +++ b/server/internal/infrastructure/files/firmware.go @@ -21,6 +21,8 @@ type FirmwareFileInfo struct { ID string `json:"id"` Filename string `json:"filename"` Size int64 `json:"size"` + SHA256 string `json:"sha256,omitempty"` + FilePath string `json:"-"` UploadedAt time.Time `json:"uploaded_at"` } @@ -182,9 +184,7 @@ func (s *Service) SaveFirmwareFile(filename string, reader io.Reader) (string, e checksum := hex.EncodeToString(hasher.Sum(nil)) - s.mu.Lock() - s.checksumIndex[checksum] = append(s.checksumIndex[checksum], fileID) - s.mu.Unlock() + s.rememberFirmwareChecksum(checksum, fileID) slog.Info("firmware file saved", "file_id", fileID, "filename", sanitized, "checksum", checksum) return fileID, nil @@ -226,9 +226,7 @@ func (s *Service) SaveFirmwareFileFromPath(filename string, srcPath string) (str return "", fleeterror.NewInvalidArgumentError("firmware file is empty") } - s.mu.Lock() - s.checksumIndex[checksum] = append(s.checksumIndex[checksum], fileID) - s.mu.Unlock() + s.rememberFirmwareChecksum(checksum, fileID) slog.Info("firmware file saved from path", "file_id", fileID, "filename", sanitized, "checksum", checksum) return fileID, nil @@ -241,7 +239,10 @@ func (s *Service) GetFirmwareFilePath(fileID string) (string, error) { if err != nil { return "", err } + return getFirmwareFilePathForCanonicalID(canonical) +} +func getFirmwareFilePathForCanonicalID(canonical string) (string, error) { dir := getFirmwareDirPath(canonical) path, err := findSingleFileInDir(dir) if err != nil { @@ -253,23 +254,79 @@ func (s *Service) GetFirmwareFilePath(fileID string) (string, error) { // OpenFirmwareFile opens the firmware file for reading and returns the reader, // original filename, and file size. The caller is responsible for closing the reader. func (s *Service) OpenFirmwareFile(fileID string) (io.ReadCloser, string, int64, error) { - filePath, err := s.GetFirmwareFilePath(fileID) + reader, info, err := s.OpenFirmwareFileWithInfo(fileID) if err != nil { return nil, "", 0, err } + return reader, info.Filename, info.Size, nil +} +// OpenFirmwareFileWithInfo opens the firmware file for reading and returns +// metadata required to address it as a command artifact payload. +func (s *Service) OpenFirmwareFileWithInfo(fileID string) (io.ReadCloser, FirmwareFileInfo, error) { + canonical, err := canonicalizeFirmwareFileID(fileID) + if err != nil { + return nil, FirmwareFileInfo{}, err + } + filePath, err := getFirmwareFilePathForCanonicalID(canonical) + if err != nil { + return nil, FirmwareFileInfo{}, err + } file, err := os.Open(filePath) if err != nil { - return nil, "", 0, fleeterror.NewInternalErrorf("failed to open firmware file: %v", err) + return nil, FirmwareFileInfo{}, fleeterror.NewInternalErrorf("failed to open firmware file: %v", err) } info, err := file.Stat() if err != nil { file.Close() - return nil, "", 0, fleeterror.NewInternalErrorf("failed to stat firmware file: %v", err) + return nil, FirmwareFileInfo{}, fleeterror.NewInternalErrorf("failed to stat firmware file: %v", err) + } + + checksum, err := s.firmwareChecksum(canonical, filePath) + if err != nil { + file.Close() + return nil, FirmwareFileInfo{}, err + } + + return file, FirmwareFileInfo{ + ID: canonical, + Filename: filepath.Base(filePath), + Size: info.Size(), + SHA256: checksum, + FilePath: filePath, + }, nil +} + +func (s *Service) firmwareChecksum(canonicalID, filePath string) (string, error) { + if checksum, ok := s.lookupFirmwareChecksum(canonicalID); ok { + return checksum, nil } + checksum, err := computeFileChecksum(filePath) + if err != nil { + return "", fleeterror.NewInternalErrorf("failed to compute firmware checksum: %v", err) + } + s.rememberFirmwareChecksum(checksum, canonicalID) + return checksum, nil +} + +func (s *Service) lookupFirmwareChecksum(canonicalID string) (string, bool) { + s.mu.Lock() + defer s.mu.Unlock() + checksum, ok := s.firmwareChecksumByID[canonicalID] + return checksum, ok +} - return file, filepath.Base(filePath), info.Size(), nil +func (s *Service) rememberFirmwareChecksum(checksum, canonicalID string) { + s.mu.Lock() + defer s.mu.Unlock() + s.firmwareChecksumByID[canonicalID] = checksum + for _, id := range s.checksumIndex[checksum] { + if id == canonicalID { + return + } + } + s.checksumIndex[checksum] = append(s.checksumIndex[checksum], canonicalID) } // FindFirmwareFileByChecksum looks up a firmware file by its SHA-256 hex digest. @@ -307,25 +364,51 @@ func (s *Service) DeleteFirmwareFile(fileID string) error { s.mu.Lock() defer s.mu.Unlock() - for checksum, ids := range s.checksumIndex { - for i, fid := range ids { - if fid == canonical { - ids = append(ids[:i], ids[i+1:]...) - if len(ids) == 0 { - delete(s.checksumIndex, checksum) - } else { - s.checksumIndex[checksum] = ids - } - goto indexDone - } - } + checksum, ok := s.firmwareChecksumByID[canonical] + if ok { + s.removeFirmwareChecksumLocked(checksum, canonical) + } else { + s.removeFirmwareChecksumByScanLocked(canonical) } -indexDone: slog.Info("firmware file deleted", "file_id", canonical) return nil } +func (s *Service) removeFirmwareChecksumLocked(checksum, canonicalID string) { + delete(s.firmwareChecksumByID, canonicalID) + ids := s.checksumIndex[checksum] + for i, id := range ids { + if id != canonicalID { + continue + } + ids = append(ids[:i], ids[i+1:]...) + if len(ids) == 0 { + delete(s.checksumIndex, checksum) + } else { + s.checksumIndex[checksum] = ids + } + return + } +} + +func (s *Service) removeFirmwareChecksumByScanLocked(canonicalID string) { + for checksum, ids := range s.checksumIndex { + for i, id := range ids { + if id != canonicalID { + continue + } + ids = append(ids[:i], ids[i+1:]...) + if len(ids) == 0 { + delete(s.checksumIndex, checksum) + } else { + s.checksumIndex[checksum] = ids + } + return + } + } +} + // ListFirmwareFiles returns metadata for all stored firmware files, sorted by // upload time (newest first). Returns an empty slice when no files exist. func (s *Service) ListFirmwareFiles() ([]FirmwareFileInfo, error) { @@ -441,7 +524,7 @@ func (s *Service) initChecksumIndex() error { continue } - s.checksumIndex[checksum] = append(s.checksumIndex[checksum], fileID) + s.rememberFirmwareChecksum(checksum, fileID) } count := 0 diff --git a/server/internal/infrastructure/files/firmware_test.go b/server/internal/infrastructure/files/firmware_test.go index 540bc9291..48945bfa2 100644 --- a/server/internal/infrastructure/files/firmware_test.go +++ b/server/internal/infrastructure/files/firmware_test.go @@ -231,6 +231,46 @@ func TestOpenFirmwareFile_ReturnsReaderAndMetadata(t *testing.T) { assert.Equal(t, content, string(data)) } +func TestOpenFirmwareFileWithInfo_ReturnsReaderAndChecksum(t *testing.T) { + svc := setupService(t) + + content := "firmware binary data here" + fileID, err := svc.SaveFirmwareFile("update.swu", strings.NewReader(content)) + require.NoError(t, err) + + reader, info, err := svc.OpenFirmwareFileWithInfo(fileID) + require.NoError(t, err) + defer reader.Close() + + assert.Equal(t, fileID, info.ID) + assert.Equal(t, "update.swu", info.Filename) + assert.Equal(t, int64(len(content)), info.Size) + assert.Equal(t, checksumOf(content), info.SHA256) + assert.Equal(t, filepath.Join(firmwareDir, fileID, "update.swu"), info.FilePath) + + data, err := io.ReadAll(reader) + require.NoError(t, err) + assert.Equal(t, content, string(data)) +} + +func TestOpenFirmwareFileWithInfo_RebuildsMissingChecksumIndexEntry(t *testing.T) { + svc := setupService(t) + + content := "firmware binary data here" + fileID, err := svc.SaveFirmwareFile("update.swu", strings.NewReader(content)) + require.NoError(t, err) + svc.checksumIndex = make(map[string][]string) + svc.firmwareChecksumByID = make(map[string]string) + + reader, info, err := svc.OpenFirmwareFileWithInfo(fileID) + require.NoError(t, err) + defer reader.Close() + + assert.Equal(t, checksumOf(content), info.SHA256) + assert.Equal(t, []string{fileID}, svc.checksumIndex[checksumOf(content)]) + assert.Equal(t, checksumOf(content), svc.firmwareChecksumByID[fileID]) +} + func TestOpenFirmwareFile_ReturnsErrorForMissing(t *testing.T) { svc := setupService(t) @@ -248,6 +288,18 @@ func TestOpenFirmwareFile_RejectsPathTraversal(t *testing.T) { assert.Contains(t, err.Error(), "invalid firmware file ID") } +func TestOpenFirmwareFileWithInfo_RejectsInvalidOrMissingID(t *testing.T) { + svc := setupService(t) + + _, _, err := svc.OpenFirmwareFileWithInfo("../logs/tmp") + require.Error(t, err) + assert.Contains(t, err.Error(), "invalid firmware file ID") + + _, _, err = svc.OpenFirmwareFileWithInfo("00000000-0000-0000-0000-000000000000") + require.Error(t, err) + assert.Contains(t, err.Error(), "firmware file not found") +} + func TestFindFirmwareFileByChecksum_ReturnsTrueForExistingFile(t *testing.T) { svc := setupService(t) @@ -308,6 +360,7 @@ func TestDeleteFirmwareFile_RemovesFromChecksumIndex(t *testing.T) { require.NoError(t, err) assert.Empty(t, svc.checksumIndex, "checksumIndex should be empty after delete") + assert.Empty(t, svc.firmwareChecksumByID, "firmwareChecksumByID should be empty after delete") newID, err := svc.SaveFirmwareFile("firmware.swu", strings.NewReader(content)) require.NoError(t, err) diff --git a/server/internal/infrastructure/files/service.go b/server/internal/infrastructure/files/service.go index bdc27fdfd..fad39180f 100644 --- a/server/internal/infrastructure/files/service.go +++ b/server/internal/infrastructure/files/service.go @@ -82,8 +82,9 @@ type Service struct { commandArtifactRetentionTTL time.Duration commandArtifactCleanupInterval time.Duration - mu sync.Mutex - checksumIndex map[string][]string // SHA-256 hex -> fileIDs + mu sync.Mutex + checksumIndex map[string][]string // SHA-256 hex -> fileIDs + firmwareChecksumByID map[string]string // fileID -> SHA-256 hex } // MaxFirmwareFileSize returns the configured maximum firmware file size in bytes. @@ -155,6 +156,7 @@ func NewService(cfg Config) (*Service, error) { commandArtifactRetentionTTL: retentionTTL, commandArtifactCleanupInterval: cleanupInterval, checksumIndex: make(map[string][]string), + firmwareChecksumByID: make(map[string]string), } if err := svc.initChecksumIndex(); err != nil { diff --git a/server/sdk/v1/interface.go b/server/sdk/v1/interface.go index 495fe5f98..019344457 100644 --- a/server/sdk/v1/interface.go +++ b/server/sdk/v1/interface.go @@ -407,8 +407,10 @@ type DeviceConfiguration interface { // FirmwareFile represents a firmware file to be uploaded to a device. type FirmwareFile struct { Reader io.Reader + ID string Filename string Size int64 + SHA256 string FilePath string // On-disk path for gRPC bridge passthrough (plugins share the server's filesystem) } diff --git a/server/sdk/v1/pb/driver.proto b/server/sdk/v1/pb/driver.proto index 976d413e1..44efe7b09 100644 --- a/server/sdk/v1/pb/driver.proto +++ b/server/sdk/v1/pb/driver.proto @@ -507,6 +507,8 @@ message FirmwareFileInfo { string file_path = 1; string original_filename = 2; int64 file_size = 3; + string id = 4; + string sha256 = 5; } // Uploads firmware to a device. The server resolves the firmware file on disk diff --git a/server/sdk/v1/pb/generated/driver.pb.go b/server/sdk/v1/pb/generated/driver.pb.go index f4287af5b..0dc1c4de6 100644 --- a/server/sdk/v1/pb/generated/driver.pb.go +++ b/server/sdk/v1/pb/generated/driver.pb.go @@ -3940,6 +3940,8 @@ type FirmwareFileInfo struct { FilePath string `protobuf:"bytes,1,opt,name=file_path,json=filePath,proto3" json:"file_path,omitempty"` OriginalFilename string `protobuf:"bytes,2,opt,name=original_filename,json=originalFilename,proto3" json:"original_filename,omitempty"` FileSize int64 `protobuf:"varint,3,opt,name=file_size,json=fileSize,proto3" json:"file_size,omitempty"` + Id string `protobuf:"bytes,4,opt,name=id,proto3" json:"id,omitempty"` + Sha256 string `protobuf:"bytes,5,opt,name=sha256,proto3" json:"sha256,omitempty"` unknownFields protoimpl.UnknownFields sizeCache protoimpl.SizeCache } @@ -3995,6 +3997,20 @@ func (x *FirmwareFileInfo) GetFileSize() int64 { return 0 } +func (x *FirmwareFileInfo) GetId() string { + if x != nil { + return x.Id + } + return "" +} + +func (x *FirmwareFileInfo) GetSha256() string { + if x != nil { + return x.Sha256 + } + return "" +} + // Uploads firmware to a device. The server resolves the firmware file on disk // and passes its location to the plugin process. type UpdateFirmwareRequest struct { @@ -4868,402 +4884,405 @@ var file_pb_driver_proto_rawDesc = string([]byte{ 0x28, 0x09, 0x52, 0x0f, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x74, 0x50, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x12, 0x21, 0x0a, 0x0c, 0x6e, 0x65, 0x77, 0x5f, 0x70, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x6e, 0x65, 0x77, 0x50, 0x61, - 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x22, 0x79, 0x0a, 0x10, 0x46, 0x69, 0x72, 0x6d, 0x77, 0x61, - 0x72, 0x65, 0x46, 0x69, 0x6c, 0x65, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x1b, 0x0a, 0x09, 0x66, 0x69, - 0x6c, 0x65, 0x5f, 0x70, 0x61, 0x74, 0x68, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x66, - 0x69, 0x6c, 0x65, 0x50, 0x61, 0x74, 0x68, 0x12, 0x2b, 0x0a, 0x11, 0x6f, 0x72, 0x69, 0x67, 0x69, - 0x6e, 0x61, 0x6c, 0x5f, 0x66, 0x69, 0x6c, 0x65, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x10, 0x6f, 0x72, 0x69, 0x67, 0x69, 0x6e, 0x61, 0x6c, 0x46, 0x69, 0x6c, 0x65, - 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x1b, 0x0a, 0x09, 0x66, 0x69, 0x6c, 0x65, 0x5f, 0x73, 0x69, 0x7a, - 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x03, 0x52, 0x08, 0x66, 0x69, 0x6c, 0x65, 0x53, 0x69, 0x7a, - 0x65, 0x22, 0x72, 0x0a, 0x15, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x46, 0x69, 0x72, 0x6d, 0x77, - 0x61, 0x72, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x23, 0x0a, 0x03, 0x72, 0x65, - 0x66, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x73, 0x64, 0x6b, 0x2e, 0x76, 0x31, - 0x2e, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x52, 0x65, 0x66, 0x52, 0x03, 0x72, 0x65, 0x66, 0x12, - 0x34, 0x0a, 0x08, 0x66, 0x69, 0x72, 0x6d, 0x77, 0x61, 0x72, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, - 0x0b, 0x32, 0x18, 0x2e, 0x73, 0x64, 0x6b, 0x2e, 0x76, 0x31, 0x2e, 0x46, 0x69, 0x72, 0x6d, 0x77, - 0x61, 0x72, 0x65, 0x46, 0x69, 0x6c, 0x65, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x08, 0x66, 0x69, 0x72, - 0x6d, 0x77, 0x61, 0x72, 0x65, 0x22, 0x8a, 0x01, 0x0a, 0x1f, 0x47, 0x65, 0x74, 0x46, 0x69, 0x72, - 0x6d, 0x77, 0x61, 0x72, 0x65, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x53, 0x74, 0x61, 0x74, 0x75, - 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x73, 0x74, 0x61, - 0x74, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x12, - 0x1f, 0x0a, 0x08, 0x70, 0x72, 0x6f, 0x67, 0x72, 0x65, 0x73, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, - 0x05, 0x48, 0x00, 0x52, 0x08, 0x70, 0x72, 0x6f, 0x67, 0x72, 0x65, 0x73, 0x73, 0x88, 0x01, 0x01, - 0x12, 0x19, 0x0a, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x48, - 0x01, 0x52, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x88, 0x01, 0x01, 0x42, 0x0b, 0x0a, 0x09, 0x5f, - 0x70, 0x72, 0x6f, 0x67, 0x72, 0x65, 0x73, 0x73, 0x42, 0x08, 0x0a, 0x06, 0x5f, 0x65, 0x72, 0x72, - 0x6f, 0x72, 0x22, 0xde, 0x05, 0x0a, 0x0b, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x45, 0x72, 0x72, - 0x6f, 0x72, 0x12, 0x33, 0x0a, 0x0b, 0x6d, 0x69, 0x6e, 0x65, 0x72, 0x5f, 0x65, 0x72, 0x72, 0x6f, - 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x12, 0x2e, 0x73, 0x64, 0x6b, 0x2e, 0x76, 0x31, - 0x2e, 0x4d, 0x69, 0x6e, 0x65, 0x72, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x52, 0x0a, 0x6d, 0x69, 0x6e, - 0x65, 0x72, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x12, 0x23, 0x0a, 0x0d, 0x63, 0x61, 0x75, 0x73, 0x65, - 0x5f, 0x73, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, - 0x63, 0x61, 0x75, 0x73, 0x65, 0x53, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x12, 0x2d, 0x0a, 0x12, - 0x72, 0x65, 0x63, 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x64, 0x65, 0x64, 0x5f, 0x61, 0x63, 0x74, 0x69, - 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x11, 0x72, 0x65, 0x63, 0x6f, 0x6d, 0x6d, - 0x65, 0x6e, 0x64, 0x65, 0x64, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x2c, 0x0a, 0x08, 0x73, - 0x65, 0x76, 0x65, 0x72, 0x69, 0x74, 0x79, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x10, 0x2e, - 0x73, 0x64, 0x6b, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x65, 0x76, 0x65, 0x72, 0x69, 0x74, 0x79, 0x52, - 0x08, 0x73, 0x65, 0x76, 0x65, 0x72, 0x69, 0x74, 0x79, 0x12, 0x3e, 0x0a, 0x0d, 0x66, 0x69, 0x72, - 0x73, 0x74, 0x5f, 0x73, 0x65, 0x65, 0x6e, 0x5f, 0x61, 0x74, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, - 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, - 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x0b, 0x66, 0x69, - 0x72, 0x73, 0x74, 0x53, 0x65, 0x65, 0x6e, 0x41, 0x74, 0x12, 0x3c, 0x0a, 0x0c, 0x6c, 0x61, 0x73, - 0x74, 0x5f, 0x73, 0x65, 0x65, 0x6e, 0x5f, 0x61, 0x74, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, - 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, - 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x0a, 0x6c, 0x61, 0x73, - 0x74, 0x53, 0x65, 0x65, 0x6e, 0x41, 0x74, 0x12, 0x37, 0x0a, 0x09, 0x63, 0x6c, 0x6f, 0x73, 0x65, - 0x64, 0x5f, 0x61, 0x74, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, - 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, - 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x08, 0x63, 0x6c, 0x6f, 0x73, 0x65, 0x64, 0x41, 0x74, - 0x12, 0x56, 0x0a, 0x11, 0x76, 0x65, 0x6e, 0x64, 0x6f, 0x72, 0x5f, 0x61, 0x74, 0x74, 0x72, 0x69, - 0x62, 0x75, 0x74, 0x65, 0x73, 0x18, 0x08, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x29, 0x2e, 0x73, 0x64, - 0x6b, 0x2e, 0x76, 0x31, 0x2e, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x45, 0x72, 0x72, 0x6f, 0x72, - 0x2e, 0x56, 0x65, 0x6e, 0x64, 0x6f, 0x72, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, - 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x10, 0x76, 0x65, 0x6e, 0x64, 0x6f, 0x72, 0x41, 0x74, - 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x12, 0x1b, 0x0a, 0x09, 0x64, 0x65, 0x76, 0x69, - 0x63, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x09, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x64, 0x65, 0x76, - 0x69, 0x63, 0x65, 0x49, 0x64, 0x12, 0x26, 0x0a, 0x0c, 0x63, 0x6f, 0x6d, 0x70, 0x6f, 0x6e, 0x65, - 0x6e, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x0b, 0x63, - 0x6f, 0x6d, 0x70, 0x6f, 0x6e, 0x65, 0x6e, 0x74, 0x49, 0x64, 0x88, 0x01, 0x01, 0x12, 0x16, 0x0a, - 0x06, 0x69, 0x6d, 0x70, 0x61, 0x63, 0x74, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x69, - 0x6d, 0x70, 0x61, 0x63, 0x74, 0x12, 0x18, 0x0a, 0x07, 0x73, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, - 0x18, 0x0c, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x73, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x12, - 0x3c, 0x0a, 0x0e, 0x63, 0x6f, 0x6d, 0x70, 0x6f, 0x6e, 0x65, 0x6e, 0x74, 0x5f, 0x74, 0x79, 0x70, - 0x65, 0x18, 0x0d, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x15, 0x2e, 0x73, 0x64, 0x6b, 0x2e, 0x76, 0x31, - 0x2e, 0x43, 0x6f, 0x6d, 0x70, 0x6f, 0x6e, 0x65, 0x6e, 0x74, 0x54, 0x79, 0x70, 0x65, 0x52, 0x0d, - 0x63, 0x6f, 0x6d, 0x70, 0x6f, 0x6e, 0x65, 0x6e, 0x74, 0x54, 0x79, 0x70, 0x65, 0x1a, 0x43, 0x0a, - 0x15, 0x56, 0x65, 0x6e, 0x64, 0x6f, 0x72, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, - 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, - 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, - 0x38, 0x01, 0x42, 0x0f, 0x0a, 0x0d, 0x5f, 0x63, 0x6f, 0x6d, 0x70, 0x6f, 0x6e, 0x65, 0x6e, 0x74, - 0x5f, 0x69, 0x64, 0x22, 0x58, 0x0a, 0x0c, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x45, 0x72, 0x72, - 0x6f, 0x72, 0x73, 0x12, 0x1b, 0x0a, 0x09, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x5f, 0x69, 0x64, - 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x49, 0x64, - 0x12, 0x2b, 0x0a, 0x06, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, - 0x32, 0x13, 0x2e, 0x73, 0x64, 0x6b, 0x2e, 0x76, 0x31, 0x2e, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, - 0x45, 0x72, 0x72, 0x6f, 0x72, 0x52, 0x06, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x73, 0x2a, 0xa2, 0x01, - 0x0a, 0x0c, 0x48, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x1d, - 0x0a, 0x19, 0x48, 0x45, 0x41, 0x4c, 0x54, 0x48, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, - 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x12, 0x0a, - 0x0e, 0x48, 0x45, 0x41, 0x4c, 0x54, 0x48, 0x5f, 0x55, 0x4e, 0x4b, 0x4e, 0x4f, 0x57, 0x4e, 0x10, - 0x01, 0x12, 0x19, 0x0a, 0x15, 0x48, 0x45, 0x41, 0x4c, 0x54, 0x48, 0x5f, 0x48, 0x45, 0x41, 0x4c, - 0x54, 0x48, 0x59, 0x5f, 0x41, 0x43, 0x54, 0x49, 0x56, 0x45, 0x10, 0x02, 0x12, 0x1b, 0x0a, 0x17, - 0x48, 0x45, 0x41, 0x4c, 0x54, 0x48, 0x5f, 0x48, 0x45, 0x41, 0x4c, 0x54, 0x48, 0x59, 0x5f, 0x49, - 0x4e, 0x41, 0x43, 0x54, 0x49, 0x56, 0x45, 0x10, 0x03, 0x12, 0x12, 0x0a, 0x0e, 0x48, 0x45, 0x41, - 0x4c, 0x54, 0x48, 0x5f, 0x57, 0x41, 0x52, 0x4e, 0x49, 0x4e, 0x47, 0x10, 0x04, 0x12, 0x13, 0x0a, - 0x0f, 0x48, 0x45, 0x41, 0x4c, 0x54, 0x48, 0x5f, 0x43, 0x52, 0x49, 0x54, 0x49, 0x43, 0x41, 0x4c, - 0x10, 0x05, 0x2a, 0xe9, 0x01, 0x0a, 0x0f, 0x43, 0x6f, 0x6d, 0x70, 0x6f, 0x6e, 0x65, 0x6e, 0x74, - 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x20, 0x0a, 0x1c, 0x43, 0x4f, 0x4d, 0x50, 0x4f, 0x4e, - 0x45, 0x4e, 0x54, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, - 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x1c, 0x0a, 0x18, 0x43, 0x4f, 0x4d, 0x50, - 0x4f, 0x4e, 0x45, 0x4e, 0x54, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x55, 0x4e, 0x4b, - 0x4e, 0x4f, 0x57, 0x4e, 0x10, 0x01, 0x12, 0x1c, 0x0a, 0x18, 0x43, 0x4f, 0x4d, 0x50, 0x4f, 0x4e, - 0x45, 0x4e, 0x54, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x48, 0x45, 0x41, 0x4c, 0x54, - 0x48, 0x59, 0x10, 0x02, 0x12, 0x1c, 0x0a, 0x18, 0x43, 0x4f, 0x4d, 0x50, 0x4f, 0x4e, 0x45, 0x4e, - 0x54, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x57, 0x41, 0x52, 0x4e, 0x49, 0x4e, 0x47, - 0x10, 0x03, 0x12, 0x1d, 0x0a, 0x19, 0x43, 0x4f, 0x4d, 0x50, 0x4f, 0x4e, 0x45, 0x4e, 0x54, 0x5f, - 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x43, 0x52, 0x49, 0x54, 0x49, 0x43, 0x41, 0x4c, 0x10, - 0x04, 0x12, 0x1c, 0x0a, 0x18, 0x43, 0x4f, 0x4d, 0x50, 0x4f, 0x4e, 0x45, 0x4e, 0x54, 0x5f, 0x53, - 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x4f, 0x46, 0x46, 0x4c, 0x49, 0x4e, 0x45, 0x10, 0x05, 0x12, - 0x1d, 0x0a, 0x19, 0x43, 0x4f, 0x4d, 0x50, 0x4f, 0x4e, 0x45, 0x4e, 0x54, 0x5f, 0x53, 0x54, 0x41, - 0x54, 0x55, 0x53, 0x5f, 0x44, 0x49, 0x53, 0x41, 0x42, 0x4c, 0x45, 0x44, 0x10, 0x06, 0x2a, 0x6f, - 0x0a, 0x0a, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x4b, 0x69, 0x6e, 0x64, 0x12, 0x1b, 0x0a, 0x17, - 0x4d, 0x45, 0x54, 0x52, 0x49, 0x43, 0x5f, 0x4b, 0x49, 0x4e, 0x44, 0x5f, 0x55, 0x4e, 0x53, 0x50, - 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x15, 0x0a, 0x11, 0x4d, 0x45, 0x54, - 0x52, 0x49, 0x43, 0x5f, 0x4b, 0x49, 0x4e, 0x44, 0x5f, 0x47, 0x41, 0x55, 0x47, 0x45, 0x10, 0x01, - 0x12, 0x14, 0x0a, 0x10, 0x4d, 0x45, 0x54, 0x52, 0x49, 0x43, 0x5f, 0x4b, 0x49, 0x4e, 0x44, 0x5f, - 0x52, 0x41, 0x54, 0x45, 0x10, 0x02, 0x12, 0x17, 0x0a, 0x13, 0x4d, 0x45, 0x54, 0x52, 0x49, 0x43, - 0x5f, 0x4b, 0x49, 0x4e, 0x44, 0x5f, 0x43, 0x4f, 0x55, 0x4e, 0x54, 0x45, 0x52, 0x10, 0x03, 0x2a, - 0x84, 0x01, 0x0a, 0x0b, 0x43, 0x6f, 0x6f, 0x6c, 0x69, 0x6e, 0x67, 0x4d, 0x6f, 0x64, 0x65, 0x12, - 0x1c, 0x0a, 0x18, 0x43, 0x4f, 0x4f, 0x4c, 0x49, 0x4e, 0x47, 0x5f, 0x4d, 0x4f, 0x44, 0x45, 0x5f, - 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x1b, 0x0a, - 0x17, 0x43, 0x4f, 0x4f, 0x4c, 0x49, 0x4e, 0x47, 0x5f, 0x4d, 0x4f, 0x44, 0x45, 0x5f, 0x41, 0x49, - 0x52, 0x5f, 0x43, 0x4f, 0x4f, 0x4c, 0x45, 0x44, 0x10, 0x01, 0x12, 0x21, 0x0a, 0x1d, 0x43, 0x4f, - 0x4f, 0x4c, 0x49, 0x4e, 0x47, 0x5f, 0x4d, 0x4f, 0x44, 0x45, 0x5f, 0x49, 0x4d, 0x4d, 0x45, 0x52, - 0x53, 0x49, 0x4f, 0x4e, 0x5f, 0x43, 0x4f, 0x4f, 0x4c, 0x45, 0x44, 0x10, 0x02, 0x12, 0x17, 0x0a, - 0x13, 0x43, 0x4f, 0x4f, 0x4c, 0x49, 0x4e, 0x47, 0x5f, 0x4d, 0x4f, 0x44, 0x45, 0x5f, 0x4d, 0x41, - 0x4e, 0x55, 0x41, 0x4c, 0x10, 0x03, 0x2a, 0x7b, 0x0a, 0x0f, 0x50, 0x65, 0x72, 0x66, 0x6f, 0x72, - 0x6d, 0x61, 0x6e, 0x63, 0x65, 0x4d, 0x6f, 0x64, 0x65, 0x12, 0x20, 0x0a, 0x1c, 0x50, 0x45, 0x52, - 0x46, 0x4f, 0x52, 0x4d, 0x41, 0x4e, 0x43, 0x45, 0x5f, 0x4d, 0x4f, 0x44, 0x45, 0x5f, 0x55, 0x4e, - 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x25, 0x0a, 0x21, 0x50, + 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x22, 0xa1, 0x01, 0x0a, 0x10, 0x46, 0x69, 0x72, 0x6d, 0x77, + 0x61, 0x72, 0x65, 0x46, 0x69, 0x6c, 0x65, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x1b, 0x0a, 0x09, 0x66, + 0x69, 0x6c, 0x65, 0x5f, 0x70, 0x61, 0x74, 0x68, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, + 0x66, 0x69, 0x6c, 0x65, 0x50, 0x61, 0x74, 0x68, 0x12, 0x2b, 0x0a, 0x11, 0x6f, 0x72, 0x69, 0x67, + 0x69, 0x6e, 0x61, 0x6c, 0x5f, 0x66, 0x69, 0x6c, 0x65, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x10, 0x6f, 0x72, 0x69, 0x67, 0x69, 0x6e, 0x61, 0x6c, 0x46, 0x69, 0x6c, + 0x65, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x1b, 0x0a, 0x09, 0x66, 0x69, 0x6c, 0x65, 0x5f, 0x73, 0x69, + 0x7a, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x03, 0x52, 0x08, 0x66, 0x69, 0x6c, 0x65, 0x53, 0x69, + 0x7a, 0x65, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, + 0x69, 0x64, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x68, 0x61, 0x32, 0x35, 0x36, 0x18, 0x05, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x06, 0x73, 0x68, 0x61, 0x32, 0x35, 0x36, 0x22, 0x72, 0x0a, 0x15, 0x55, 0x70, + 0x64, 0x61, 0x74, 0x65, 0x46, 0x69, 0x72, 0x6d, 0x77, 0x61, 0x72, 0x65, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x12, 0x23, 0x0a, 0x03, 0x72, 0x65, 0x66, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x11, 0x2e, 0x73, 0x64, 0x6b, 0x2e, 0x76, 0x31, 0x2e, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, + 0x52, 0x65, 0x66, 0x52, 0x03, 0x72, 0x65, 0x66, 0x12, 0x34, 0x0a, 0x08, 0x66, 0x69, 0x72, 0x6d, + 0x77, 0x61, 0x72, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x73, 0x64, 0x6b, + 0x2e, 0x76, 0x31, 0x2e, 0x46, 0x69, 0x72, 0x6d, 0x77, 0x61, 0x72, 0x65, 0x46, 0x69, 0x6c, 0x65, + 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x08, 0x66, 0x69, 0x72, 0x6d, 0x77, 0x61, 0x72, 0x65, 0x22, 0x8a, + 0x01, 0x0a, 0x1f, 0x47, 0x65, 0x74, 0x46, 0x69, 0x72, 0x6d, 0x77, 0x61, 0x72, 0x65, 0x55, 0x70, + 0x64, 0x61, 0x74, 0x65, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x12, 0x1f, 0x0a, 0x08, 0x70, 0x72, 0x6f, 0x67, + 0x72, 0x65, 0x73, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x48, 0x00, 0x52, 0x08, 0x70, 0x72, + 0x6f, 0x67, 0x72, 0x65, 0x73, 0x73, 0x88, 0x01, 0x01, 0x12, 0x19, 0x0a, 0x05, 0x65, 0x72, 0x72, + 0x6f, 0x72, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x48, 0x01, 0x52, 0x05, 0x65, 0x72, 0x72, 0x6f, + 0x72, 0x88, 0x01, 0x01, 0x42, 0x0b, 0x0a, 0x09, 0x5f, 0x70, 0x72, 0x6f, 0x67, 0x72, 0x65, 0x73, + 0x73, 0x42, 0x08, 0x0a, 0x06, 0x5f, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x22, 0xde, 0x05, 0x0a, 0x0b, + 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x12, 0x33, 0x0a, 0x0b, 0x6d, + 0x69, 0x6e, 0x65, 0x72, 0x5f, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, + 0x32, 0x12, 0x2e, 0x73, 0x64, 0x6b, 0x2e, 0x76, 0x31, 0x2e, 0x4d, 0x69, 0x6e, 0x65, 0x72, 0x45, + 0x72, 0x72, 0x6f, 0x72, 0x52, 0x0a, 0x6d, 0x69, 0x6e, 0x65, 0x72, 0x45, 0x72, 0x72, 0x6f, 0x72, + 0x12, 0x23, 0x0a, 0x0d, 0x63, 0x61, 0x75, 0x73, 0x65, 0x5f, 0x73, 0x75, 0x6d, 0x6d, 0x61, 0x72, + 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x63, 0x61, 0x75, 0x73, 0x65, 0x53, 0x75, + 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x12, 0x2d, 0x0a, 0x12, 0x72, 0x65, 0x63, 0x6f, 0x6d, 0x6d, 0x65, + 0x6e, 0x64, 0x65, 0x64, 0x5f, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x11, 0x72, 0x65, 0x63, 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x64, 0x65, 0x64, 0x41, 0x63, + 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x2c, 0x0a, 0x08, 0x73, 0x65, 0x76, 0x65, 0x72, 0x69, 0x74, 0x79, + 0x18, 0x04, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x10, 0x2e, 0x73, 0x64, 0x6b, 0x2e, 0x76, 0x31, 0x2e, + 0x53, 0x65, 0x76, 0x65, 0x72, 0x69, 0x74, 0x79, 0x52, 0x08, 0x73, 0x65, 0x76, 0x65, 0x72, 0x69, + 0x74, 0x79, 0x12, 0x3e, 0x0a, 0x0d, 0x66, 0x69, 0x72, 0x73, 0x74, 0x5f, 0x73, 0x65, 0x65, 0x6e, + 0x5f, 0x61, 0x74, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, + 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, + 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x0b, 0x66, 0x69, 0x72, 0x73, 0x74, 0x53, 0x65, 0x65, 0x6e, + 0x41, 0x74, 0x12, 0x3c, 0x0a, 0x0c, 0x6c, 0x61, 0x73, 0x74, 0x5f, 0x73, 0x65, 0x65, 0x6e, 0x5f, + 0x61, 0x74, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, + 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, + 0x74, 0x61, 0x6d, 0x70, 0x52, 0x0a, 0x6c, 0x61, 0x73, 0x74, 0x53, 0x65, 0x65, 0x6e, 0x41, 0x74, + 0x12, 0x37, 0x0a, 0x09, 0x63, 0x6c, 0x6f, 0x73, 0x65, 0x64, 0x5f, 0x61, 0x74, 0x18, 0x07, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, + 0x08, 0x63, 0x6c, 0x6f, 0x73, 0x65, 0x64, 0x41, 0x74, 0x12, 0x56, 0x0a, 0x11, 0x76, 0x65, 0x6e, + 0x64, 0x6f, 0x72, 0x5f, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x18, 0x08, + 0x20, 0x03, 0x28, 0x0b, 0x32, 0x29, 0x2e, 0x73, 0x64, 0x6b, 0x2e, 0x76, 0x31, 0x2e, 0x44, 0x65, + 0x76, 0x69, 0x63, 0x65, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x2e, 0x56, 0x65, 0x6e, 0x64, 0x6f, 0x72, + 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, + 0x10, 0x76, 0x65, 0x6e, 0x64, 0x6f, 0x72, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, + 0x73, 0x12, 0x1b, 0x0a, 0x09, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x09, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x49, 0x64, 0x12, 0x26, + 0x0a, 0x0c, 0x63, 0x6f, 0x6d, 0x70, 0x6f, 0x6e, 0x65, 0x6e, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x0a, + 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x0b, 0x63, 0x6f, 0x6d, 0x70, 0x6f, 0x6e, 0x65, 0x6e, + 0x74, 0x49, 0x64, 0x88, 0x01, 0x01, 0x12, 0x16, 0x0a, 0x06, 0x69, 0x6d, 0x70, 0x61, 0x63, 0x74, + 0x18, 0x0b, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x69, 0x6d, 0x70, 0x61, 0x63, 0x74, 0x12, 0x18, + 0x0a, 0x07, 0x73, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x07, 0x73, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x12, 0x3c, 0x0a, 0x0e, 0x63, 0x6f, 0x6d, 0x70, + 0x6f, 0x6e, 0x65, 0x6e, 0x74, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x0d, 0x20, 0x01, 0x28, 0x0e, + 0x32, 0x15, 0x2e, 0x73, 0x64, 0x6b, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x6f, 0x6d, 0x70, 0x6f, 0x6e, + 0x65, 0x6e, 0x74, 0x54, 0x79, 0x70, 0x65, 0x52, 0x0d, 0x63, 0x6f, 0x6d, 0x70, 0x6f, 0x6e, 0x65, + 0x6e, 0x74, 0x54, 0x79, 0x70, 0x65, 0x1a, 0x43, 0x0a, 0x15, 0x56, 0x65, 0x6e, 0x64, 0x6f, 0x72, + 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, + 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, + 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x42, 0x0f, 0x0a, 0x0d, 0x5f, + 0x63, 0x6f, 0x6d, 0x70, 0x6f, 0x6e, 0x65, 0x6e, 0x74, 0x5f, 0x69, 0x64, 0x22, 0x58, 0x0a, 0x0c, + 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x73, 0x12, 0x1b, 0x0a, 0x09, + 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x08, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x49, 0x64, 0x12, 0x2b, 0x0a, 0x06, 0x65, 0x72, 0x72, + 0x6f, 0x72, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x73, 0x64, 0x6b, 0x2e, + 0x76, 0x31, 0x2e, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x52, 0x06, + 0x65, 0x72, 0x72, 0x6f, 0x72, 0x73, 0x2a, 0xa2, 0x01, 0x0a, 0x0c, 0x48, 0x65, 0x61, 0x6c, 0x74, + 0x68, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x1d, 0x0a, 0x19, 0x48, 0x45, 0x41, 0x4c, 0x54, + 0x48, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, + 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x12, 0x0a, 0x0e, 0x48, 0x45, 0x41, 0x4c, 0x54, 0x48, + 0x5f, 0x55, 0x4e, 0x4b, 0x4e, 0x4f, 0x57, 0x4e, 0x10, 0x01, 0x12, 0x19, 0x0a, 0x15, 0x48, 0x45, + 0x41, 0x4c, 0x54, 0x48, 0x5f, 0x48, 0x45, 0x41, 0x4c, 0x54, 0x48, 0x59, 0x5f, 0x41, 0x43, 0x54, + 0x49, 0x56, 0x45, 0x10, 0x02, 0x12, 0x1b, 0x0a, 0x17, 0x48, 0x45, 0x41, 0x4c, 0x54, 0x48, 0x5f, + 0x48, 0x45, 0x41, 0x4c, 0x54, 0x48, 0x59, 0x5f, 0x49, 0x4e, 0x41, 0x43, 0x54, 0x49, 0x56, 0x45, + 0x10, 0x03, 0x12, 0x12, 0x0a, 0x0e, 0x48, 0x45, 0x41, 0x4c, 0x54, 0x48, 0x5f, 0x57, 0x41, 0x52, + 0x4e, 0x49, 0x4e, 0x47, 0x10, 0x04, 0x12, 0x13, 0x0a, 0x0f, 0x48, 0x45, 0x41, 0x4c, 0x54, 0x48, + 0x5f, 0x43, 0x52, 0x49, 0x54, 0x49, 0x43, 0x41, 0x4c, 0x10, 0x05, 0x2a, 0xe9, 0x01, 0x0a, 0x0f, + 0x43, 0x6f, 0x6d, 0x70, 0x6f, 0x6e, 0x65, 0x6e, 0x74, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, + 0x20, 0x0a, 0x1c, 0x43, 0x4f, 0x4d, 0x50, 0x4f, 0x4e, 0x45, 0x4e, 0x54, 0x5f, 0x53, 0x54, 0x41, + 0x54, 0x55, 0x53, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, + 0x00, 0x12, 0x1c, 0x0a, 0x18, 0x43, 0x4f, 0x4d, 0x50, 0x4f, 0x4e, 0x45, 0x4e, 0x54, 0x5f, 0x53, + 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x55, 0x4e, 0x4b, 0x4e, 0x4f, 0x57, 0x4e, 0x10, 0x01, 0x12, + 0x1c, 0x0a, 0x18, 0x43, 0x4f, 0x4d, 0x50, 0x4f, 0x4e, 0x45, 0x4e, 0x54, 0x5f, 0x53, 0x54, 0x41, + 0x54, 0x55, 0x53, 0x5f, 0x48, 0x45, 0x41, 0x4c, 0x54, 0x48, 0x59, 0x10, 0x02, 0x12, 0x1c, 0x0a, + 0x18, 0x43, 0x4f, 0x4d, 0x50, 0x4f, 0x4e, 0x45, 0x4e, 0x54, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x55, + 0x53, 0x5f, 0x57, 0x41, 0x52, 0x4e, 0x49, 0x4e, 0x47, 0x10, 0x03, 0x12, 0x1d, 0x0a, 0x19, 0x43, + 0x4f, 0x4d, 0x50, 0x4f, 0x4e, 0x45, 0x4e, 0x54, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, + 0x43, 0x52, 0x49, 0x54, 0x49, 0x43, 0x41, 0x4c, 0x10, 0x04, 0x12, 0x1c, 0x0a, 0x18, 0x43, 0x4f, + 0x4d, 0x50, 0x4f, 0x4e, 0x45, 0x4e, 0x54, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x4f, + 0x46, 0x46, 0x4c, 0x49, 0x4e, 0x45, 0x10, 0x05, 0x12, 0x1d, 0x0a, 0x19, 0x43, 0x4f, 0x4d, 0x50, + 0x4f, 0x4e, 0x45, 0x4e, 0x54, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x44, 0x49, 0x53, + 0x41, 0x42, 0x4c, 0x45, 0x44, 0x10, 0x06, 0x2a, 0x6f, 0x0a, 0x0a, 0x4d, 0x65, 0x74, 0x72, 0x69, + 0x63, 0x4b, 0x69, 0x6e, 0x64, 0x12, 0x1b, 0x0a, 0x17, 0x4d, 0x45, 0x54, 0x52, 0x49, 0x43, 0x5f, + 0x4b, 0x49, 0x4e, 0x44, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, + 0x10, 0x00, 0x12, 0x15, 0x0a, 0x11, 0x4d, 0x45, 0x54, 0x52, 0x49, 0x43, 0x5f, 0x4b, 0x49, 0x4e, + 0x44, 0x5f, 0x47, 0x41, 0x55, 0x47, 0x45, 0x10, 0x01, 0x12, 0x14, 0x0a, 0x10, 0x4d, 0x45, 0x54, + 0x52, 0x49, 0x43, 0x5f, 0x4b, 0x49, 0x4e, 0x44, 0x5f, 0x52, 0x41, 0x54, 0x45, 0x10, 0x02, 0x12, + 0x17, 0x0a, 0x13, 0x4d, 0x45, 0x54, 0x52, 0x49, 0x43, 0x5f, 0x4b, 0x49, 0x4e, 0x44, 0x5f, 0x43, + 0x4f, 0x55, 0x4e, 0x54, 0x45, 0x52, 0x10, 0x03, 0x2a, 0x84, 0x01, 0x0a, 0x0b, 0x43, 0x6f, 0x6f, + 0x6c, 0x69, 0x6e, 0x67, 0x4d, 0x6f, 0x64, 0x65, 0x12, 0x1c, 0x0a, 0x18, 0x43, 0x4f, 0x4f, 0x4c, + 0x49, 0x4e, 0x47, 0x5f, 0x4d, 0x4f, 0x44, 0x45, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, + 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x1b, 0x0a, 0x17, 0x43, 0x4f, 0x4f, 0x4c, 0x49, 0x4e, + 0x47, 0x5f, 0x4d, 0x4f, 0x44, 0x45, 0x5f, 0x41, 0x49, 0x52, 0x5f, 0x43, 0x4f, 0x4f, 0x4c, 0x45, + 0x44, 0x10, 0x01, 0x12, 0x21, 0x0a, 0x1d, 0x43, 0x4f, 0x4f, 0x4c, 0x49, 0x4e, 0x47, 0x5f, 0x4d, + 0x4f, 0x44, 0x45, 0x5f, 0x49, 0x4d, 0x4d, 0x45, 0x52, 0x53, 0x49, 0x4f, 0x4e, 0x5f, 0x43, 0x4f, + 0x4f, 0x4c, 0x45, 0x44, 0x10, 0x02, 0x12, 0x17, 0x0a, 0x13, 0x43, 0x4f, 0x4f, 0x4c, 0x49, 0x4e, + 0x47, 0x5f, 0x4d, 0x4f, 0x44, 0x45, 0x5f, 0x4d, 0x41, 0x4e, 0x55, 0x41, 0x4c, 0x10, 0x03, 0x2a, + 0x7b, 0x0a, 0x0f, 0x50, 0x65, 0x72, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x6e, 0x63, 0x65, 0x4d, 0x6f, + 0x64, 0x65, 0x12, 0x20, 0x0a, 0x1c, 0x50, 0x45, 0x52, 0x46, 0x4f, 0x52, 0x4d, 0x41, 0x4e, 0x43, + 0x45, 0x5f, 0x4d, 0x4f, 0x44, 0x45, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, + 0x45, 0x44, 0x10, 0x00, 0x12, 0x25, 0x0a, 0x21, 0x50, 0x45, 0x52, 0x46, 0x4f, 0x52, 0x4d, 0x41, + 0x4e, 0x43, 0x45, 0x5f, 0x4d, 0x4f, 0x44, 0x45, 0x5f, 0x4d, 0x41, 0x58, 0x49, 0x4d, 0x55, 0x4d, + 0x5f, 0x48, 0x41, 0x53, 0x48, 0x52, 0x41, 0x54, 0x45, 0x10, 0x01, 0x12, 0x1f, 0x0a, 0x1b, 0x50, 0x45, 0x52, 0x46, 0x4f, 0x52, 0x4d, 0x41, 0x4e, 0x43, 0x45, 0x5f, 0x4d, 0x4f, 0x44, 0x45, 0x5f, - 0x4d, 0x41, 0x58, 0x49, 0x4d, 0x55, 0x4d, 0x5f, 0x48, 0x41, 0x53, 0x48, 0x52, 0x41, 0x54, 0x45, - 0x10, 0x01, 0x12, 0x1f, 0x0a, 0x1b, 0x50, 0x45, 0x52, 0x46, 0x4f, 0x52, 0x4d, 0x41, 0x4e, 0x43, - 0x45, 0x5f, 0x4d, 0x4f, 0x44, 0x45, 0x5f, 0x45, 0x46, 0x46, 0x49, 0x43, 0x49, 0x45, 0x4e, 0x43, - 0x59, 0x10, 0x02, 0x2a, 0x63, 0x0a, 0x0c, 0x43, 0x75, 0x72, 0x74, 0x61, 0x69, 0x6c, 0x4c, 0x65, - 0x76, 0x65, 0x6c, 0x12, 0x1d, 0x0a, 0x19, 0x43, 0x55, 0x52, 0x54, 0x41, 0x49, 0x4c, 0x5f, 0x4c, - 0x45, 0x56, 0x45, 0x4c, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, - 0x10, 0x00, 0x12, 0x1c, 0x0a, 0x18, 0x43, 0x55, 0x52, 0x54, 0x41, 0x49, 0x4c, 0x5f, 0x4c, 0x45, - 0x56, 0x45, 0x4c, 0x5f, 0x45, 0x46, 0x46, 0x49, 0x43, 0x49, 0x45, 0x4e, 0x43, 0x59, 0x10, 0x01, - 0x12, 0x16, 0x0a, 0x12, 0x43, 0x55, 0x52, 0x54, 0x41, 0x49, 0x4c, 0x5f, 0x4c, 0x45, 0x56, 0x45, - 0x4c, 0x5f, 0x46, 0x55, 0x4c, 0x4c, 0x10, 0x02, 0x2a, 0x9d, 0x0b, 0x0a, 0x0a, 0x4d, 0x69, 0x6e, - 0x65, 0x72, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x12, 0x1b, 0x0a, 0x17, 0x4d, 0x49, 0x4e, 0x45, 0x52, - 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, - 0x45, 0x44, 0x10, 0x00, 0x12, 0x14, 0x0a, 0x0f, 0x50, 0x53, 0x55, 0x5f, 0x4e, 0x4f, 0x54, 0x5f, - 0x50, 0x52, 0x45, 0x53, 0x45, 0x4e, 0x54, 0x10, 0xe8, 0x07, 0x12, 0x17, 0x0a, 0x12, 0x50, 0x53, - 0x55, 0x5f, 0x4d, 0x4f, 0x44, 0x45, 0x4c, 0x5f, 0x4d, 0x49, 0x53, 0x4d, 0x41, 0x54, 0x43, 0x48, - 0x10, 0xe9, 0x07, 0x12, 0x1b, 0x0a, 0x16, 0x50, 0x53, 0x55, 0x5f, 0x43, 0x4f, 0x4d, 0x4d, 0x55, - 0x4e, 0x49, 0x43, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x4c, 0x4f, 0x53, 0x54, 0x10, 0xea, 0x07, - 0x12, 0x16, 0x0a, 0x11, 0x50, 0x53, 0x55, 0x5f, 0x46, 0x41, 0x55, 0x4c, 0x54, 0x5f, 0x47, 0x45, - 0x4e, 0x45, 0x52, 0x49, 0x43, 0x10, 0xeb, 0x07, 0x12, 0x1a, 0x0a, 0x15, 0x50, 0x53, 0x55, 0x5f, - 0x49, 0x4e, 0x50, 0x55, 0x54, 0x5f, 0x56, 0x4f, 0x4c, 0x54, 0x41, 0x47, 0x45, 0x5f, 0x4c, 0x4f, - 0x57, 0x10, 0xec, 0x07, 0x12, 0x1b, 0x0a, 0x16, 0x50, 0x53, 0x55, 0x5f, 0x49, 0x4e, 0x50, 0x55, - 0x54, 0x5f, 0x56, 0x4f, 0x4c, 0x54, 0x41, 0x47, 0x45, 0x5f, 0x48, 0x49, 0x47, 0x48, 0x10, 0xed, - 0x07, 0x12, 0x1d, 0x0a, 0x18, 0x50, 0x53, 0x55, 0x5f, 0x4f, 0x55, 0x54, 0x50, 0x55, 0x54, 0x5f, - 0x56, 0x4f, 0x4c, 0x54, 0x41, 0x47, 0x45, 0x5f, 0x46, 0x41, 0x55, 0x4c, 0x54, 0x10, 0xee, 0x07, - 0x12, 0x1b, 0x0a, 0x16, 0x50, 0x53, 0x55, 0x5f, 0x4f, 0x55, 0x54, 0x50, 0x55, 0x54, 0x5f, 0x4f, - 0x56, 0x45, 0x52, 0x43, 0x55, 0x52, 0x52, 0x45, 0x4e, 0x54, 0x10, 0xef, 0x07, 0x12, 0x12, 0x0a, - 0x0d, 0x50, 0x53, 0x55, 0x5f, 0x46, 0x41, 0x4e, 0x5f, 0x46, 0x41, 0x55, 0x4c, 0x54, 0x10, 0xf0, - 0x07, 0x12, 0x19, 0x0a, 0x14, 0x50, 0x53, 0x55, 0x5f, 0x4f, 0x56, 0x45, 0x52, 0x5f, 0x54, 0x45, - 0x4d, 0x50, 0x45, 0x52, 0x41, 0x54, 0x55, 0x52, 0x45, 0x10, 0xf1, 0x07, 0x12, 0x1e, 0x0a, 0x19, - 0x50, 0x53, 0x55, 0x5f, 0x49, 0x4e, 0x50, 0x55, 0x54, 0x5f, 0x50, 0x48, 0x41, 0x53, 0x45, 0x5f, - 0x49, 0x4d, 0x42, 0x41, 0x4c, 0x41, 0x4e, 0x43, 0x45, 0x10, 0xf2, 0x07, 0x12, 0x1a, 0x0a, 0x15, - 0x50, 0x53, 0x55, 0x5f, 0x55, 0x4e, 0x44, 0x45, 0x52, 0x5f, 0x54, 0x45, 0x4d, 0x50, 0x45, 0x52, - 0x41, 0x54, 0x55, 0x52, 0x45, 0x10, 0xf3, 0x07, 0x12, 0x0f, 0x0a, 0x0a, 0x46, 0x41, 0x4e, 0x5f, - 0x46, 0x41, 0x49, 0x4c, 0x45, 0x44, 0x10, 0xd0, 0x0f, 0x12, 0x19, 0x0a, 0x14, 0x46, 0x41, 0x4e, - 0x5f, 0x54, 0x41, 0x43, 0x48, 0x5f, 0x53, 0x49, 0x47, 0x4e, 0x41, 0x4c, 0x5f, 0x4c, 0x4f, 0x53, - 0x54, 0x10, 0xd1, 0x0f, 0x12, 0x18, 0x0a, 0x13, 0x46, 0x41, 0x4e, 0x5f, 0x53, 0x50, 0x45, 0x45, - 0x44, 0x5f, 0x44, 0x45, 0x56, 0x49, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x10, 0xd2, 0x0f, 0x12, 0x1b, - 0x0a, 0x16, 0x49, 0x4e, 0x4c, 0x45, 0x54, 0x5f, 0x4f, 0x56, 0x45, 0x52, 0x5f, 0x54, 0x45, 0x4d, - 0x50, 0x45, 0x52, 0x41, 0x54, 0x55, 0x52, 0x45, 0x10, 0xda, 0x0f, 0x12, 0x1c, 0x0a, 0x17, 0x44, - 0x45, 0x56, 0x49, 0x43, 0x45, 0x5f, 0x4f, 0x56, 0x45, 0x52, 0x5f, 0x54, 0x45, 0x4d, 0x50, 0x45, - 0x52, 0x41, 0x54, 0x55, 0x52, 0x45, 0x10, 0xdb, 0x0f, 0x12, 0x1d, 0x0a, 0x18, 0x44, 0x45, 0x56, - 0x49, 0x43, 0x45, 0x5f, 0x55, 0x4e, 0x44, 0x45, 0x52, 0x5f, 0x54, 0x45, 0x4d, 0x50, 0x45, 0x52, - 0x41, 0x54, 0x55, 0x52, 0x45, 0x10, 0xdc, 0x0f, 0x12, 0x1a, 0x0a, 0x15, 0x48, 0x41, 0x53, 0x48, - 0x42, 0x4f, 0x41, 0x52, 0x44, 0x5f, 0x4e, 0x4f, 0x54, 0x5f, 0x50, 0x52, 0x45, 0x53, 0x45, 0x4e, - 0x54, 0x10, 0xb8, 0x17, 0x12, 0x1f, 0x0a, 0x1a, 0x48, 0x41, 0x53, 0x48, 0x42, 0x4f, 0x41, 0x52, - 0x44, 0x5f, 0x4f, 0x56, 0x45, 0x52, 0x5f, 0x54, 0x45, 0x4d, 0x50, 0x45, 0x52, 0x41, 0x54, 0x55, - 0x52, 0x45, 0x10, 0xb9, 0x17, 0x12, 0x1c, 0x0a, 0x17, 0x48, 0x41, 0x53, 0x48, 0x42, 0x4f, 0x41, - 0x52, 0x44, 0x5f, 0x4d, 0x49, 0x53, 0x53, 0x49, 0x4e, 0x47, 0x5f, 0x43, 0x48, 0x49, 0x50, 0x53, - 0x10, 0xba, 0x17, 0x12, 0x22, 0x0a, 0x1d, 0x41, 0x53, 0x49, 0x43, 0x5f, 0x43, 0x48, 0x41, 0x49, - 0x4e, 0x5f, 0x43, 0x4f, 0x4d, 0x4d, 0x55, 0x4e, 0x49, 0x43, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x5f, - 0x4c, 0x4f, 0x53, 0x54, 0x10, 0xbb, 0x17, 0x12, 0x1c, 0x0a, 0x17, 0x41, 0x53, 0x49, 0x43, 0x5f, - 0x43, 0x4c, 0x4f, 0x43, 0x4b, 0x5f, 0x50, 0x4c, 0x4c, 0x5f, 0x55, 0x4e, 0x4c, 0x4f, 0x43, 0x4b, - 0x45, 0x44, 0x10, 0xbc, 0x17, 0x12, 0x1d, 0x0a, 0x18, 0x41, 0x53, 0x49, 0x43, 0x5f, 0x43, 0x52, - 0x43, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x45, 0x58, 0x43, 0x45, 0x53, 0x53, 0x49, 0x56, - 0x45, 0x10, 0xbd, 0x17, 0x12, 0x24, 0x0a, 0x1f, 0x48, 0x41, 0x53, 0x48, 0x42, 0x4f, 0x41, 0x52, - 0x44, 0x5f, 0x41, 0x53, 0x49, 0x43, 0x5f, 0x4f, 0x56, 0x45, 0x52, 0x5f, 0x54, 0x45, 0x4d, 0x50, - 0x45, 0x52, 0x41, 0x54, 0x55, 0x52, 0x45, 0x10, 0xbe, 0x17, 0x12, 0x25, 0x0a, 0x20, 0x48, 0x41, - 0x53, 0x48, 0x42, 0x4f, 0x41, 0x52, 0x44, 0x5f, 0x41, 0x53, 0x49, 0x43, 0x5f, 0x55, 0x4e, 0x44, - 0x45, 0x52, 0x5f, 0x54, 0x45, 0x4d, 0x50, 0x45, 0x52, 0x41, 0x54, 0x55, 0x52, 0x45, 0x10, 0xbf, - 0x17, 0x12, 0x1e, 0x0a, 0x19, 0x42, 0x4f, 0x41, 0x52, 0x44, 0x5f, 0x50, 0x4f, 0x57, 0x45, 0x52, - 0x5f, 0x50, 0x47, 0x4f, 0x4f, 0x44, 0x5f, 0x4d, 0x49, 0x53, 0x53, 0x49, 0x4e, 0x47, 0x10, 0xac, - 0x1b, 0x12, 0x1c, 0x0a, 0x17, 0x42, 0x4f, 0x41, 0x52, 0x44, 0x5f, 0x50, 0x4f, 0x57, 0x45, 0x52, - 0x5f, 0x4f, 0x56, 0x45, 0x52, 0x43, 0x55, 0x52, 0x52, 0x45, 0x4e, 0x54, 0x10, 0xad, 0x1b, 0x12, - 0x1f, 0x0a, 0x1a, 0x42, 0x4f, 0x41, 0x52, 0x44, 0x5f, 0x50, 0x4f, 0x57, 0x45, 0x52, 0x5f, 0x52, - 0x41, 0x49, 0x4c, 0x5f, 0x55, 0x4e, 0x44, 0x45, 0x52, 0x56, 0x4f, 0x4c, 0x54, 0x10, 0xae, 0x1b, - 0x12, 0x1e, 0x0a, 0x19, 0x42, 0x4f, 0x41, 0x52, 0x44, 0x5f, 0x50, 0x4f, 0x57, 0x45, 0x52, 0x5f, - 0x52, 0x41, 0x49, 0x4c, 0x5f, 0x4f, 0x56, 0x45, 0x52, 0x56, 0x4f, 0x4c, 0x54, 0x10, 0xaf, 0x1b, - 0x12, 0x1f, 0x0a, 0x1a, 0x42, 0x4f, 0x41, 0x52, 0x44, 0x5f, 0x50, 0x4f, 0x57, 0x45, 0x52, 0x5f, - 0x53, 0x48, 0x4f, 0x52, 0x54, 0x5f, 0x44, 0x45, 0x54, 0x45, 0x43, 0x54, 0x45, 0x44, 0x10, 0xb0, - 0x1b, 0x12, 0x1e, 0x0a, 0x19, 0x54, 0x45, 0x4d, 0x50, 0x5f, 0x53, 0x45, 0x4e, 0x53, 0x4f, 0x52, - 0x5f, 0x4f, 0x50, 0x45, 0x4e, 0x5f, 0x4f, 0x52, 0x5f, 0x53, 0x48, 0x4f, 0x52, 0x54, 0x10, 0xa0, - 0x1f, 0x12, 0x16, 0x0a, 0x11, 0x54, 0x45, 0x4d, 0x50, 0x5f, 0x53, 0x45, 0x4e, 0x53, 0x4f, 0x52, - 0x5f, 0x46, 0x41, 0x55, 0x4c, 0x54, 0x10, 0xa1, 0x1f, 0x12, 0x19, 0x0a, 0x14, 0x56, 0x4f, 0x4c, - 0x54, 0x41, 0x47, 0x45, 0x5f, 0x53, 0x45, 0x4e, 0x53, 0x4f, 0x52, 0x5f, 0x46, 0x41, 0x55, 0x4c, - 0x54, 0x10, 0xa2, 0x1f, 0x12, 0x19, 0x0a, 0x14, 0x43, 0x55, 0x52, 0x52, 0x45, 0x4e, 0x54, 0x5f, - 0x53, 0x45, 0x4e, 0x53, 0x4f, 0x52, 0x5f, 0x46, 0x41, 0x55, 0x4c, 0x54, 0x10, 0xa3, 0x1f, 0x12, - 0x18, 0x0a, 0x13, 0x45, 0x45, 0x50, 0x52, 0x4f, 0x4d, 0x5f, 0x43, 0x52, 0x43, 0x5f, 0x4d, 0x49, - 0x53, 0x4d, 0x41, 0x54, 0x43, 0x48, 0x10, 0x88, 0x27, 0x12, 0x18, 0x0a, 0x13, 0x45, 0x45, 0x50, - 0x52, 0x4f, 0x4d, 0x5f, 0x52, 0x45, 0x41, 0x44, 0x5f, 0x46, 0x41, 0x49, 0x4c, 0x55, 0x52, 0x45, - 0x10, 0x89, 0x27, 0x12, 0x1b, 0x0a, 0x16, 0x46, 0x49, 0x52, 0x4d, 0x57, 0x41, 0x52, 0x45, 0x5f, - 0x49, 0x4d, 0x41, 0x47, 0x45, 0x5f, 0x49, 0x4e, 0x56, 0x41, 0x4c, 0x49, 0x44, 0x10, 0x8a, 0x27, - 0x12, 0x1c, 0x0a, 0x17, 0x46, 0x49, 0x52, 0x4d, 0x57, 0x41, 0x52, 0x45, 0x5f, 0x43, 0x4f, 0x4e, - 0x46, 0x49, 0x47, 0x5f, 0x49, 0x4e, 0x56, 0x41, 0x4c, 0x49, 0x44, 0x10, 0x8b, 0x27, 0x12, 0x25, - 0x0a, 0x20, 0x43, 0x4f, 0x4e, 0x54, 0x52, 0x4f, 0x4c, 0x5f, 0x42, 0x4f, 0x41, 0x52, 0x44, 0x5f, - 0x43, 0x4f, 0x4d, 0x4d, 0x55, 0x4e, 0x49, 0x43, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x4c, 0x4f, - 0x53, 0x54, 0x10, 0xf0, 0x2e, 0x12, 0x1a, 0x0a, 0x15, 0x43, 0x4f, 0x4e, 0x54, 0x52, 0x4f, 0x4c, - 0x5f, 0x42, 0x4f, 0x41, 0x52, 0x44, 0x5f, 0x46, 0x41, 0x49, 0x4c, 0x55, 0x52, 0x45, 0x10, 0xf1, - 0x2e, 0x12, 0x1e, 0x0a, 0x19, 0x44, 0x45, 0x56, 0x49, 0x43, 0x45, 0x5f, 0x49, 0x4e, 0x54, 0x45, - 0x52, 0x4e, 0x41, 0x4c, 0x5f, 0x42, 0x55, 0x53, 0x5f, 0x46, 0x41, 0x55, 0x4c, 0x54, 0x10, 0xf2, - 0x2e, 0x12, 0x1e, 0x0a, 0x19, 0x44, 0x45, 0x56, 0x49, 0x43, 0x45, 0x5f, 0x43, 0x4f, 0x4d, 0x4d, - 0x55, 0x4e, 0x49, 0x43, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x4c, 0x4f, 0x53, 0x54, 0x10, 0xf3, - 0x2e, 0x12, 0x16, 0x0a, 0x11, 0x49, 0x4f, 0x5f, 0x4d, 0x4f, 0x44, 0x55, 0x4c, 0x45, 0x5f, 0x46, - 0x41, 0x49, 0x4c, 0x55, 0x52, 0x45, 0x10, 0xfa, 0x2e, 0x12, 0x1a, 0x0a, 0x15, 0x48, 0x41, 0x53, - 0x48, 0x52, 0x41, 0x54, 0x45, 0x5f, 0x42, 0x45, 0x4c, 0x4f, 0x57, 0x5f, 0x54, 0x41, 0x52, 0x47, - 0x45, 0x54, 0x10, 0xc0, 0x3e, 0x12, 0x1c, 0x0a, 0x17, 0x48, 0x41, 0x53, 0x48, 0x42, 0x4f, 0x41, - 0x52, 0x44, 0x5f, 0x57, 0x41, 0x52, 0x4e, 0x5f, 0x43, 0x52, 0x43, 0x5f, 0x48, 0x49, 0x47, 0x48, - 0x10, 0xc1, 0x3e, 0x12, 0x17, 0x0a, 0x12, 0x54, 0x48, 0x45, 0x52, 0x4d, 0x41, 0x4c, 0x5f, 0x4d, - 0x41, 0x52, 0x47, 0x49, 0x4e, 0x5f, 0x4c, 0x4f, 0x57, 0x10, 0xc2, 0x3e, 0x12, 0x1a, 0x0a, 0x15, - 0x56, 0x45, 0x4e, 0x44, 0x4f, 0x52, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x55, 0x4e, 0x4d, - 0x41, 0x50, 0x50, 0x45, 0x44, 0x10, 0xa8, 0x46, 0x2a, 0x76, 0x0a, 0x08, 0x53, 0x65, 0x76, 0x65, - 0x72, 0x69, 0x74, 0x79, 0x12, 0x18, 0x0a, 0x14, 0x53, 0x45, 0x56, 0x45, 0x52, 0x49, 0x54, 0x59, - 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x15, - 0x0a, 0x11, 0x53, 0x45, 0x56, 0x45, 0x52, 0x49, 0x54, 0x59, 0x5f, 0x43, 0x52, 0x49, 0x54, 0x49, - 0x43, 0x41, 0x4c, 0x10, 0x01, 0x12, 0x12, 0x0a, 0x0e, 0x53, 0x45, 0x56, 0x45, 0x52, 0x49, 0x54, - 0x59, 0x5f, 0x4d, 0x41, 0x4a, 0x4f, 0x52, 0x10, 0x02, 0x12, 0x12, 0x0a, 0x0e, 0x53, 0x45, 0x56, - 0x45, 0x52, 0x49, 0x54, 0x59, 0x5f, 0x4d, 0x49, 0x4e, 0x4f, 0x52, 0x10, 0x03, 0x12, 0x11, 0x0a, - 0x0d, 0x53, 0x45, 0x56, 0x45, 0x52, 0x49, 0x54, 0x59, 0x5f, 0x49, 0x4e, 0x46, 0x4f, 0x10, 0x04, - 0x2a, 0xd9, 0x01, 0x0a, 0x0d, 0x43, 0x6f, 0x6d, 0x70, 0x6f, 0x6e, 0x65, 0x6e, 0x74, 0x54, 0x79, - 0x70, 0x65, 0x12, 0x1e, 0x0a, 0x1a, 0x43, 0x4f, 0x4d, 0x50, 0x4f, 0x4e, 0x45, 0x4e, 0x54, 0x5f, - 0x54, 0x59, 0x50, 0x45, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, - 0x10, 0x00, 0x12, 0x16, 0x0a, 0x12, 0x43, 0x4f, 0x4d, 0x50, 0x4f, 0x4e, 0x45, 0x4e, 0x54, 0x5f, - 0x54, 0x59, 0x50, 0x45, 0x5f, 0x50, 0x53, 0x55, 0x10, 0x01, 0x12, 0x1d, 0x0a, 0x19, 0x43, 0x4f, - 0x4d, 0x50, 0x4f, 0x4e, 0x45, 0x4e, 0x54, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x48, 0x41, 0x53, - 0x48, 0x5f, 0x42, 0x4f, 0x41, 0x52, 0x44, 0x10, 0x02, 0x12, 0x16, 0x0a, 0x12, 0x43, 0x4f, 0x4d, - 0x50, 0x4f, 0x4e, 0x45, 0x4e, 0x54, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x46, 0x41, 0x4e, 0x10, - 0x03, 0x12, 0x20, 0x0a, 0x1c, 0x43, 0x4f, 0x4d, 0x50, 0x4f, 0x4e, 0x45, 0x4e, 0x54, 0x5f, 0x54, - 0x59, 0x50, 0x45, 0x5f, 0x43, 0x4f, 0x4e, 0x54, 0x52, 0x4f, 0x4c, 0x5f, 0x42, 0x4f, 0x41, 0x52, - 0x44, 0x10, 0x04, 0x12, 0x19, 0x0a, 0x15, 0x43, 0x4f, 0x4d, 0x50, 0x4f, 0x4e, 0x45, 0x4e, 0x54, - 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x45, 0x45, 0x50, 0x52, 0x4f, 0x4d, 0x10, 0x05, 0x12, 0x1c, - 0x0a, 0x18, 0x43, 0x4f, 0x4d, 0x50, 0x4f, 0x4e, 0x45, 0x4e, 0x54, 0x5f, 0x54, 0x59, 0x50, 0x45, - 0x5f, 0x49, 0x4f, 0x5f, 0x4d, 0x4f, 0x44, 0x55, 0x4c, 0x45, 0x10, 0x06, 0x32, 0x8c, 0x12, 0x0a, - 0x06, 0x44, 0x72, 0x69, 0x76, 0x65, 0x72, 0x12, 0x3e, 0x0a, 0x09, 0x48, 0x61, 0x6e, 0x64, 0x73, - 0x68, 0x61, 0x6b, 0x65, 0x12, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, - 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x19, 0x2e, 0x73, - 0x64, 0x6b, 0x2e, 0x76, 0x31, 0x2e, 0x48, 0x61, 0x6e, 0x64, 0x73, 0x68, 0x61, 0x6b, 0x65, 0x52, - 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x48, 0x0a, 0x0e, 0x44, 0x65, 0x73, 0x63, 0x72, - 0x69, 0x62, 0x65, 0x44, 0x72, 0x69, 0x76, 0x65, 0x72, 0x12, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, - 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, - 0x79, 0x1a, 0x1e, 0x2e, 0x73, 0x64, 0x6b, 0x2e, 0x76, 0x31, 0x2e, 0x44, 0x65, 0x73, 0x63, 0x72, - 0x69, 0x62, 0x65, 0x44, 0x72, 0x69, 0x76, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, - 0x65, 0x12, 0x4f, 0x0a, 0x0e, 0x44, 0x69, 0x73, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x44, 0x65, 0x76, - 0x69, 0x63, 0x65, 0x12, 0x1d, 0x2e, 0x73, 0x64, 0x6b, 0x2e, 0x76, 0x31, 0x2e, 0x44, 0x69, 0x73, - 0x63, 0x6f, 0x76, 0x65, 0x72, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, - 0x73, 0x74, 0x1a, 0x1e, 0x2e, 0x73, 0x64, 0x6b, 0x2e, 0x76, 0x31, 0x2e, 0x44, 0x69, 0x73, 0x63, - 0x6f, 0x76, 0x65, 0x72, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, - 0x73, 0x65, 0x12, 0x43, 0x0a, 0x0a, 0x50, 0x61, 0x69, 0x72, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, - 0x12, 0x19, 0x2e, 0x73, 0x64, 0x6b, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x61, 0x69, 0x72, 0x44, 0x65, - 0x76, 0x69, 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1a, 0x2e, 0x73, 0x64, - 0x6b, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x61, 0x69, 0x72, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x52, - 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x64, 0x0a, 0x15, 0x47, 0x65, 0x74, 0x44, 0x65, - 0x66, 0x61, 0x75, 0x6c, 0x74, 0x43, 0x72, 0x65, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x61, 0x6c, 0x73, - 0x12, 0x24, 0x2e, 0x73, 0x64, 0x6b, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x44, 0x65, 0x66, - 0x61, 0x75, 0x6c, 0x74, 0x43, 0x72, 0x65, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x61, 0x6c, 0x73, 0x52, - 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x25, 0x2e, 0x73, 0x64, 0x6b, 0x2e, 0x76, 0x31, 0x2e, - 0x47, 0x65, 0x74, 0x44, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x43, 0x72, 0x65, 0x64, 0x65, 0x6e, - 0x74, 0x69, 0x61, 0x6c, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x6a, 0x0a, - 0x17, 0x47, 0x65, 0x74, 0x43, 0x61, 0x70, 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x69, 0x65, 0x73, - 0x46, 0x6f, 0x72, 0x4d, 0x6f, 0x64, 0x65, 0x6c, 0x12, 0x26, 0x2e, 0x73, 0x64, 0x6b, 0x2e, 0x76, - 0x31, 0x2e, 0x47, 0x65, 0x74, 0x43, 0x61, 0x70, 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x69, 0x65, - 0x73, 0x46, 0x6f, 0x72, 0x4d, 0x6f, 0x64, 0x65, 0x6c, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, - 0x1a, 0x27, 0x2e, 0x73, 0x64, 0x6b, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x43, 0x61, 0x70, + 0x45, 0x46, 0x46, 0x49, 0x43, 0x49, 0x45, 0x4e, 0x43, 0x59, 0x10, 0x02, 0x2a, 0x63, 0x0a, 0x0c, + 0x43, 0x75, 0x72, 0x74, 0x61, 0x69, 0x6c, 0x4c, 0x65, 0x76, 0x65, 0x6c, 0x12, 0x1d, 0x0a, 0x19, + 0x43, 0x55, 0x52, 0x54, 0x41, 0x49, 0x4c, 0x5f, 0x4c, 0x45, 0x56, 0x45, 0x4c, 0x5f, 0x55, 0x4e, + 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x1c, 0x0a, 0x18, 0x43, + 0x55, 0x52, 0x54, 0x41, 0x49, 0x4c, 0x5f, 0x4c, 0x45, 0x56, 0x45, 0x4c, 0x5f, 0x45, 0x46, 0x46, + 0x49, 0x43, 0x49, 0x45, 0x4e, 0x43, 0x59, 0x10, 0x01, 0x12, 0x16, 0x0a, 0x12, 0x43, 0x55, 0x52, + 0x54, 0x41, 0x49, 0x4c, 0x5f, 0x4c, 0x45, 0x56, 0x45, 0x4c, 0x5f, 0x46, 0x55, 0x4c, 0x4c, 0x10, + 0x02, 0x2a, 0x9d, 0x0b, 0x0a, 0x0a, 0x4d, 0x69, 0x6e, 0x65, 0x72, 0x45, 0x72, 0x72, 0x6f, 0x72, + 0x12, 0x1b, 0x0a, 0x17, 0x4d, 0x49, 0x4e, 0x45, 0x52, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, + 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x14, 0x0a, + 0x0f, 0x50, 0x53, 0x55, 0x5f, 0x4e, 0x4f, 0x54, 0x5f, 0x50, 0x52, 0x45, 0x53, 0x45, 0x4e, 0x54, + 0x10, 0xe8, 0x07, 0x12, 0x17, 0x0a, 0x12, 0x50, 0x53, 0x55, 0x5f, 0x4d, 0x4f, 0x44, 0x45, 0x4c, + 0x5f, 0x4d, 0x49, 0x53, 0x4d, 0x41, 0x54, 0x43, 0x48, 0x10, 0xe9, 0x07, 0x12, 0x1b, 0x0a, 0x16, + 0x50, 0x53, 0x55, 0x5f, 0x43, 0x4f, 0x4d, 0x4d, 0x55, 0x4e, 0x49, 0x43, 0x41, 0x54, 0x49, 0x4f, + 0x4e, 0x5f, 0x4c, 0x4f, 0x53, 0x54, 0x10, 0xea, 0x07, 0x12, 0x16, 0x0a, 0x11, 0x50, 0x53, 0x55, + 0x5f, 0x46, 0x41, 0x55, 0x4c, 0x54, 0x5f, 0x47, 0x45, 0x4e, 0x45, 0x52, 0x49, 0x43, 0x10, 0xeb, + 0x07, 0x12, 0x1a, 0x0a, 0x15, 0x50, 0x53, 0x55, 0x5f, 0x49, 0x4e, 0x50, 0x55, 0x54, 0x5f, 0x56, + 0x4f, 0x4c, 0x54, 0x41, 0x47, 0x45, 0x5f, 0x4c, 0x4f, 0x57, 0x10, 0xec, 0x07, 0x12, 0x1b, 0x0a, + 0x16, 0x50, 0x53, 0x55, 0x5f, 0x49, 0x4e, 0x50, 0x55, 0x54, 0x5f, 0x56, 0x4f, 0x4c, 0x54, 0x41, + 0x47, 0x45, 0x5f, 0x48, 0x49, 0x47, 0x48, 0x10, 0xed, 0x07, 0x12, 0x1d, 0x0a, 0x18, 0x50, 0x53, + 0x55, 0x5f, 0x4f, 0x55, 0x54, 0x50, 0x55, 0x54, 0x5f, 0x56, 0x4f, 0x4c, 0x54, 0x41, 0x47, 0x45, + 0x5f, 0x46, 0x41, 0x55, 0x4c, 0x54, 0x10, 0xee, 0x07, 0x12, 0x1b, 0x0a, 0x16, 0x50, 0x53, 0x55, + 0x5f, 0x4f, 0x55, 0x54, 0x50, 0x55, 0x54, 0x5f, 0x4f, 0x56, 0x45, 0x52, 0x43, 0x55, 0x52, 0x52, + 0x45, 0x4e, 0x54, 0x10, 0xef, 0x07, 0x12, 0x12, 0x0a, 0x0d, 0x50, 0x53, 0x55, 0x5f, 0x46, 0x41, + 0x4e, 0x5f, 0x46, 0x41, 0x55, 0x4c, 0x54, 0x10, 0xf0, 0x07, 0x12, 0x19, 0x0a, 0x14, 0x50, 0x53, + 0x55, 0x5f, 0x4f, 0x56, 0x45, 0x52, 0x5f, 0x54, 0x45, 0x4d, 0x50, 0x45, 0x52, 0x41, 0x54, 0x55, + 0x52, 0x45, 0x10, 0xf1, 0x07, 0x12, 0x1e, 0x0a, 0x19, 0x50, 0x53, 0x55, 0x5f, 0x49, 0x4e, 0x50, + 0x55, 0x54, 0x5f, 0x50, 0x48, 0x41, 0x53, 0x45, 0x5f, 0x49, 0x4d, 0x42, 0x41, 0x4c, 0x41, 0x4e, + 0x43, 0x45, 0x10, 0xf2, 0x07, 0x12, 0x1a, 0x0a, 0x15, 0x50, 0x53, 0x55, 0x5f, 0x55, 0x4e, 0x44, + 0x45, 0x52, 0x5f, 0x54, 0x45, 0x4d, 0x50, 0x45, 0x52, 0x41, 0x54, 0x55, 0x52, 0x45, 0x10, 0xf3, + 0x07, 0x12, 0x0f, 0x0a, 0x0a, 0x46, 0x41, 0x4e, 0x5f, 0x46, 0x41, 0x49, 0x4c, 0x45, 0x44, 0x10, + 0xd0, 0x0f, 0x12, 0x19, 0x0a, 0x14, 0x46, 0x41, 0x4e, 0x5f, 0x54, 0x41, 0x43, 0x48, 0x5f, 0x53, + 0x49, 0x47, 0x4e, 0x41, 0x4c, 0x5f, 0x4c, 0x4f, 0x53, 0x54, 0x10, 0xd1, 0x0f, 0x12, 0x18, 0x0a, + 0x13, 0x46, 0x41, 0x4e, 0x5f, 0x53, 0x50, 0x45, 0x45, 0x44, 0x5f, 0x44, 0x45, 0x56, 0x49, 0x41, + 0x54, 0x49, 0x4f, 0x4e, 0x10, 0xd2, 0x0f, 0x12, 0x1b, 0x0a, 0x16, 0x49, 0x4e, 0x4c, 0x45, 0x54, + 0x5f, 0x4f, 0x56, 0x45, 0x52, 0x5f, 0x54, 0x45, 0x4d, 0x50, 0x45, 0x52, 0x41, 0x54, 0x55, 0x52, + 0x45, 0x10, 0xda, 0x0f, 0x12, 0x1c, 0x0a, 0x17, 0x44, 0x45, 0x56, 0x49, 0x43, 0x45, 0x5f, 0x4f, + 0x56, 0x45, 0x52, 0x5f, 0x54, 0x45, 0x4d, 0x50, 0x45, 0x52, 0x41, 0x54, 0x55, 0x52, 0x45, 0x10, + 0xdb, 0x0f, 0x12, 0x1d, 0x0a, 0x18, 0x44, 0x45, 0x56, 0x49, 0x43, 0x45, 0x5f, 0x55, 0x4e, 0x44, + 0x45, 0x52, 0x5f, 0x54, 0x45, 0x4d, 0x50, 0x45, 0x52, 0x41, 0x54, 0x55, 0x52, 0x45, 0x10, 0xdc, + 0x0f, 0x12, 0x1a, 0x0a, 0x15, 0x48, 0x41, 0x53, 0x48, 0x42, 0x4f, 0x41, 0x52, 0x44, 0x5f, 0x4e, + 0x4f, 0x54, 0x5f, 0x50, 0x52, 0x45, 0x53, 0x45, 0x4e, 0x54, 0x10, 0xb8, 0x17, 0x12, 0x1f, 0x0a, + 0x1a, 0x48, 0x41, 0x53, 0x48, 0x42, 0x4f, 0x41, 0x52, 0x44, 0x5f, 0x4f, 0x56, 0x45, 0x52, 0x5f, + 0x54, 0x45, 0x4d, 0x50, 0x45, 0x52, 0x41, 0x54, 0x55, 0x52, 0x45, 0x10, 0xb9, 0x17, 0x12, 0x1c, + 0x0a, 0x17, 0x48, 0x41, 0x53, 0x48, 0x42, 0x4f, 0x41, 0x52, 0x44, 0x5f, 0x4d, 0x49, 0x53, 0x53, + 0x49, 0x4e, 0x47, 0x5f, 0x43, 0x48, 0x49, 0x50, 0x53, 0x10, 0xba, 0x17, 0x12, 0x22, 0x0a, 0x1d, + 0x41, 0x53, 0x49, 0x43, 0x5f, 0x43, 0x48, 0x41, 0x49, 0x4e, 0x5f, 0x43, 0x4f, 0x4d, 0x4d, 0x55, + 0x4e, 0x49, 0x43, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x4c, 0x4f, 0x53, 0x54, 0x10, 0xbb, 0x17, + 0x12, 0x1c, 0x0a, 0x17, 0x41, 0x53, 0x49, 0x43, 0x5f, 0x43, 0x4c, 0x4f, 0x43, 0x4b, 0x5f, 0x50, + 0x4c, 0x4c, 0x5f, 0x55, 0x4e, 0x4c, 0x4f, 0x43, 0x4b, 0x45, 0x44, 0x10, 0xbc, 0x17, 0x12, 0x1d, + 0x0a, 0x18, 0x41, 0x53, 0x49, 0x43, 0x5f, 0x43, 0x52, 0x43, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, + 0x5f, 0x45, 0x58, 0x43, 0x45, 0x53, 0x53, 0x49, 0x56, 0x45, 0x10, 0xbd, 0x17, 0x12, 0x24, 0x0a, + 0x1f, 0x48, 0x41, 0x53, 0x48, 0x42, 0x4f, 0x41, 0x52, 0x44, 0x5f, 0x41, 0x53, 0x49, 0x43, 0x5f, + 0x4f, 0x56, 0x45, 0x52, 0x5f, 0x54, 0x45, 0x4d, 0x50, 0x45, 0x52, 0x41, 0x54, 0x55, 0x52, 0x45, + 0x10, 0xbe, 0x17, 0x12, 0x25, 0x0a, 0x20, 0x48, 0x41, 0x53, 0x48, 0x42, 0x4f, 0x41, 0x52, 0x44, + 0x5f, 0x41, 0x53, 0x49, 0x43, 0x5f, 0x55, 0x4e, 0x44, 0x45, 0x52, 0x5f, 0x54, 0x45, 0x4d, 0x50, + 0x45, 0x52, 0x41, 0x54, 0x55, 0x52, 0x45, 0x10, 0xbf, 0x17, 0x12, 0x1e, 0x0a, 0x19, 0x42, 0x4f, + 0x41, 0x52, 0x44, 0x5f, 0x50, 0x4f, 0x57, 0x45, 0x52, 0x5f, 0x50, 0x47, 0x4f, 0x4f, 0x44, 0x5f, + 0x4d, 0x49, 0x53, 0x53, 0x49, 0x4e, 0x47, 0x10, 0xac, 0x1b, 0x12, 0x1c, 0x0a, 0x17, 0x42, 0x4f, + 0x41, 0x52, 0x44, 0x5f, 0x50, 0x4f, 0x57, 0x45, 0x52, 0x5f, 0x4f, 0x56, 0x45, 0x52, 0x43, 0x55, + 0x52, 0x52, 0x45, 0x4e, 0x54, 0x10, 0xad, 0x1b, 0x12, 0x1f, 0x0a, 0x1a, 0x42, 0x4f, 0x41, 0x52, + 0x44, 0x5f, 0x50, 0x4f, 0x57, 0x45, 0x52, 0x5f, 0x52, 0x41, 0x49, 0x4c, 0x5f, 0x55, 0x4e, 0x44, + 0x45, 0x52, 0x56, 0x4f, 0x4c, 0x54, 0x10, 0xae, 0x1b, 0x12, 0x1e, 0x0a, 0x19, 0x42, 0x4f, 0x41, + 0x52, 0x44, 0x5f, 0x50, 0x4f, 0x57, 0x45, 0x52, 0x5f, 0x52, 0x41, 0x49, 0x4c, 0x5f, 0x4f, 0x56, + 0x45, 0x52, 0x56, 0x4f, 0x4c, 0x54, 0x10, 0xaf, 0x1b, 0x12, 0x1f, 0x0a, 0x1a, 0x42, 0x4f, 0x41, + 0x52, 0x44, 0x5f, 0x50, 0x4f, 0x57, 0x45, 0x52, 0x5f, 0x53, 0x48, 0x4f, 0x52, 0x54, 0x5f, 0x44, + 0x45, 0x54, 0x45, 0x43, 0x54, 0x45, 0x44, 0x10, 0xb0, 0x1b, 0x12, 0x1e, 0x0a, 0x19, 0x54, 0x45, + 0x4d, 0x50, 0x5f, 0x53, 0x45, 0x4e, 0x53, 0x4f, 0x52, 0x5f, 0x4f, 0x50, 0x45, 0x4e, 0x5f, 0x4f, + 0x52, 0x5f, 0x53, 0x48, 0x4f, 0x52, 0x54, 0x10, 0xa0, 0x1f, 0x12, 0x16, 0x0a, 0x11, 0x54, 0x45, + 0x4d, 0x50, 0x5f, 0x53, 0x45, 0x4e, 0x53, 0x4f, 0x52, 0x5f, 0x46, 0x41, 0x55, 0x4c, 0x54, 0x10, + 0xa1, 0x1f, 0x12, 0x19, 0x0a, 0x14, 0x56, 0x4f, 0x4c, 0x54, 0x41, 0x47, 0x45, 0x5f, 0x53, 0x45, + 0x4e, 0x53, 0x4f, 0x52, 0x5f, 0x46, 0x41, 0x55, 0x4c, 0x54, 0x10, 0xa2, 0x1f, 0x12, 0x19, 0x0a, + 0x14, 0x43, 0x55, 0x52, 0x52, 0x45, 0x4e, 0x54, 0x5f, 0x53, 0x45, 0x4e, 0x53, 0x4f, 0x52, 0x5f, + 0x46, 0x41, 0x55, 0x4c, 0x54, 0x10, 0xa3, 0x1f, 0x12, 0x18, 0x0a, 0x13, 0x45, 0x45, 0x50, 0x52, + 0x4f, 0x4d, 0x5f, 0x43, 0x52, 0x43, 0x5f, 0x4d, 0x49, 0x53, 0x4d, 0x41, 0x54, 0x43, 0x48, 0x10, + 0x88, 0x27, 0x12, 0x18, 0x0a, 0x13, 0x45, 0x45, 0x50, 0x52, 0x4f, 0x4d, 0x5f, 0x52, 0x45, 0x41, + 0x44, 0x5f, 0x46, 0x41, 0x49, 0x4c, 0x55, 0x52, 0x45, 0x10, 0x89, 0x27, 0x12, 0x1b, 0x0a, 0x16, + 0x46, 0x49, 0x52, 0x4d, 0x57, 0x41, 0x52, 0x45, 0x5f, 0x49, 0x4d, 0x41, 0x47, 0x45, 0x5f, 0x49, + 0x4e, 0x56, 0x41, 0x4c, 0x49, 0x44, 0x10, 0x8a, 0x27, 0x12, 0x1c, 0x0a, 0x17, 0x46, 0x49, 0x52, + 0x4d, 0x57, 0x41, 0x52, 0x45, 0x5f, 0x43, 0x4f, 0x4e, 0x46, 0x49, 0x47, 0x5f, 0x49, 0x4e, 0x56, + 0x41, 0x4c, 0x49, 0x44, 0x10, 0x8b, 0x27, 0x12, 0x25, 0x0a, 0x20, 0x43, 0x4f, 0x4e, 0x54, 0x52, + 0x4f, 0x4c, 0x5f, 0x42, 0x4f, 0x41, 0x52, 0x44, 0x5f, 0x43, 0x4f, 0x4d, 0x4d, 0x55, 0x4e, 0x49, + 0x43, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x4c, 0x4f, 0x53, 0x54, 0x10, 0xf0, 0x2e, 0x12, 0x1a, + 0x0a, 0x15, 0x43, 0x4f, 0x4e, 0x54, 0x52, 0x4f, 0x4c, 0x5f, 0x42, 0x4f, 0x41, 0x52, 0x44, 0x5f, + 0x46, 0x41, 0x49, 0x4c, 0x55, 0x52, 0x45, 0x10, 0xf1, 0x2e, 0x12, 0x1e, 0x0a, 0x19, 0x44, 0x45, + 0x56, 0x49, 0x43, 0x45, 0x5f, 0x49, 0x4e, 0x54, 0x45, 0x52, 0x4e, 0x41, 0x4c, 0x5f, 0x42, 0x55, + 0x53, 0x5f, 0x46, 0x41, 0x55, 0x4c, 0x54, 0x10, 0xf2, 0x2e, 0x12, 0x1e, 0x0a, 0x19, 0x44, 0x45, + 0x56, 0x49, 0x43, 0x45, 0x5f, 0x43, 0x4f, 0x4d, 0x4d, 0x55, 0x4e, 0x49, 0x43, 0x41, 0x54, 0x49, + 0x4f, 0x4e, 0x5f, 0x4c, 0x4f, 0x53, 0x54, 0x10, 0xf3, 0x2e, 0x12, 0x16, 0x0a, 0x11, 0x49, 0x4f, + 0x5f, 0x4d, 0x4f, 0x44, 0x55, 0x4c, 0x45, 0x5f, 0x46, 0x41, 0x49, 0x4c, 0x55, 0x52, 0x45, 0x10, + 0xfa, 0x2e, 0x12, 0x1a, 0x0a, 0x15, 0x48, 0x41, 0x53, 0x48, 0x52, 0x41, 0x54, 0x45, 0x5f, 0x42, + 0x45, 0x4c, 0x4f, 0x57, 0x5f, 0x54, 0x41, 0x52, 0x47, 0x45, 0x54, 0x10, 0xc0, 0x3e, 0x12, 0x1c, + 0x0a, 0x17, 0x48, 0x41, 0x53, 0x48, 0x42, 0x4f, 0x41, 0x52, 0x44, 0x5f, 0x57, 0x41, 0x52, 0x4e, + 0x5f, 0x43, 0x52, 0x43, 0x5f, 0x48, 0x49, 0x47, 0x48, 0x10, 0xc1, 0x3e, 0x12, 0x17, 0x0a, 0x12, + 0x54, 0x48, 0x45, 0x52, 0x4d, 0x41, 0x4c, 0x5f, 0x4d, 0x41, 0x52, 0x47, 0x49, 0x4e, 0x5f, 0x4c, + 0x4f, 0x57, 0x10, 0xc2, 0x3e, 0x12, 0x1a, 0x0a, 0x15, 0x56, 0x45, 0x4e, 0x44, 0x4f, 0x52, 0x5f, + 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x55, 0x4e, 0x4d, 0x41, 0x50, 0x50, 0x45, 0x44, 0x10, 0xa8, + 0x46, 0x2a, 0x76, 0x0a, 0x08, 0x53, 0x65, 0x76, 0x65, 0x72, 0x69, 0x74, 0x79, 0x12, 0x18, 0x0a, + 0x14, 0x53, 0x45, 0x56, 0x45, 0x52, 0x49, 0x54, 0x59, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, + 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x15, 0x0a, 0x11, 0x53, 0x45, 0x56, 0x45, 0x52, + 0x49, 0x54, 0x59, 0x5f, 0x43, 0x52, 0x49, 0x54, 0x49, 0x43, 0x41, 0x4c, 0x10, 0x01, 0x12, 0x12, + 0x0a, 0x0e, 0x53, 0x45, 0x56, 0x45, 0x52, 0x49, 0x54, 0x59, 0x5f, 0x4d, 0x41, 0x4a, 0x4f, 0x52, + 0x10, 0x02, 0x12, 0x12, 0x0a, 0x0e, 0x53, 0x45, 0x56, 0x45, 0x52, 0x49, 0x54, 0x59, 0x5f, 0x4d, + 0x49, 0x4e, 0x4f, 0x52, 0x10, 0x03, 0x12, 0x11, 0x0a, 0x0d, 0x53, 0x45, 0x56, 0x45, 0x52, 0x49, + 0x54, 0x59, 0x5f, 0x49, 0x4e, 0x46, 0x4f, 0x10, 0x04, 0x2a, 0xd9, 0x01, 0x0a, 0x0d, 0x43, 0x6f, + 0x6d, 0x70, 0x6f, 0x6e, 0x65, 0x6e, 0x74, 0x54, 0x79, 0x70, 0x65, 0x12, 0x1e, 0x0a, 0x1a, 0x43, + 0x4f, 0x4d, 0x50, 0x4f, 0x4e, 0x45, 0x4e, 0x54, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x55, 0x4e, + 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x16, 0x0a, 0x12, 0x43, + 0x4f, 0x4d, 0x50, 0x4f, 0x4e, 0x45, 0x4e, 0x54, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x50, 0x53, + 0x55, 0x10, 0x01, 0x12, 0x1d, 0x0a, 0x19, 0x43, 0x4f, 0x4d, 0x50, 0x4f, 0x4e, 0x45, 0x4e, 0x54, + 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x48, 0x41, 0x53, 0x48, 0x5f, 0x42, 0x4f, 0x41, 0x52, 0x44, + 0x10, 0x02, 0x12, 0x16, 0x0a, 0x12, 0x43, 0x4f, 0x4d, 0x50, 0x4f, 0x4e, 0x45, 0x4e, 0x54, 0x5f, + 0x54, 0x59, 0x50, 0x45, 0x5f, 0x46, 0x41, 0x4e, 0x10, 0x03, 0x12, 0x20, 0x0a, 0x1c, 0x43, 0x4f, + 0x4d, 0x50, 0x4f, 0x4e, 0x45, 0x4e, 0x54, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x43, 0x4f, 0x4e, + 0x54, 0x52, 0x4f, 0x4c, 0x5f, 0x42, 0x4f, 0x41, 0x52, 0x44, 0x10, 0x04, 0x12, 0x19, 0x0a, 0x15, + 0x43, 0x4f, 0x4d, 0x50, 0x4f, 0x4e, 0x45, 0x4e, 0x54, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x45, + 0x45, 0x50, 0x52, 0x4f, 0x4d, 0x10, 0x05, 0x12, 0x1c, 0x0a, 0x18, 0x43, 0x4f, 0x4d, 0x50, 0x4f, + 0x4e, 0x45, 0x4e, 0x54, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x49, 0x4f, 0x5f, 0x4d, 0x4f, 0x44, + 0x55, 0x4c, 0x45, 0x10, 0x06, 0x32, 0x8c, 0x12, 0x0a, 0x06, 0x44, 0x72, 0x69, 0x76, 0x65, 0x72, + 0x12, 0x3e, 0x0a, 0x09, 0x48, 0x61, 0x6e, 0x64, 0x73, 0x68, 0x61, 0x6b, 0x65, 0x12, 0x16, 0x2e, + 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, + 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x19, 0x2e, 0x73, 0x64, 0x6b, 0x2e, 0x76, 0x31, 0x2e, 0x48, + 0x61, 0x6e, 0x64, 0x73, 0x68, 0x61, 0x6b, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x12, 0x48, 0x0a, 0x0e, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x62, 0x65, 0x44, 0x72, 0x69, 0x76, + 0x65, 0x72, 0x12, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x1e, 0x2e, 0x73, 0x64, 0x6b, + 0x2e, 0x76, 0x31, 0x2e, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x62, 0x65, 0x44, 0x72, 0x69, 0x76, + 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x4f, 0x0a, 0x0e, 0x44, 0x69, + 0x73, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x12, 0x1d, 0x2e, 0x73, + 0x64, 0x6b, 0x2e, 0x76, 0x31, 0x2e, 0x44, 0x69, 0x73, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x44, 0x65, + 0x76, 0x69, 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1e, 0x2e, 0x73, 0x64, + 0x6b, 0x2e, 0x76, 0x31, 0x2e, 0x44, 0x69, 0x73, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x44, 0x65, 0x76, + 0x69, 0x63, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x43, 0x0a, 0x0a, 0x50, + 0x61, 0x69, 0x72, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x12, 0x19, 0x2e, 0x73, 0x64, 0x6b, 0x2e, + 0x76, 0x31, 0x2e, 0x50, 0x61, 0x69, 0x72, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1a, 0x2e, 0x73, 0x64, 0x6b, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x61, + 0x69, 0x72, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x12, 0x64, 0x0a, 0x15, 0x47, 0x65, 0x74, 0x44, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x43, 0x72, + 0x65, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x61, 0x6c, 0x73, 0x12, 0x24, 0x2e, 0x73, 0x64, 0x6b, 0x2e, + 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x44, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x43, 0x72, 0x65, + 0x64, 0x65, 0x6e, 0x74, 0x69, 0x61, 0x6c, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, + 0x25, 0x2e, 0x73, 0x64, 0x6b, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x44, 0x65, 0x66, 0x61, + 0x75, 0x6c, 0x74, 0x43, 0x72, 0x65, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x61, 0x6c, 0x73, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x6a, 0x0a, 0x17, 0x47, 0x65, 0x74, 0x43, 0x61, 0x70, 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x69, 0x65, 0x73, 0x46, 0x6f, 0x72, 0x4d, 0x6f, 0x64, 0x65, - 0x6c, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x4e, 0x0a, 0x11, 0x47, 0x65, 0x74, - 0x44, 0x69, 0x73, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x79, 0x50, 0x6f, 0x72, 0x74, 0x73, 0x12, 0x16, - 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, - 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x21, 0x2e, 0x73, 0x64, 0x6b, 0x2e, 0x76, 0x31, 0x2e, - 0x47, 0x65, 0x74, 0x44, 0x69, 0x73, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x79, 0x50, 0x6f, 0x72, 0x74, - 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x40, 0x0a, 0x09, 0x4e, 0x65, 0x77, - 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x12, 0x18, 0x2e, 0x73, 0x64, 0x6b, 0x2e, 0x76, 0x31, 0x2e, - 0x4e, 0x65, 0x77, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, - 0x1a, 0x19, 0x2e, 0x73, 0x64, 0x6b, 0x2e, 0x76, 0x31, 0x2e, 0x4e, 0x65, 0x77, 0x44, 0x65, 0x76, - 0x69, 0x63, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x4f, 0x0a, 0x0e, 0x44, - 0x65, 0x73, 0x63, 0x72, 0x69, 0x62, 0x65, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x12, 0x1d, 0x2e, - 0x73, 0x64, 0x6b, 0x2e, 0x76, 0x31, 0x2e, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x62, 0x65, 0x44, - 0x65, 0x76, 0x69, 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1e, 0x2e, 0x73, - 0x64, 0x6b, 0x2e, 0x76, 0x31, 0x2e, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x62, 0x65, 0x44, 0x65, - 0x76, 0x69, 0x63, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x38, 0x0a, 0x0b, - 0x43, 0x6c, 0x6f, 0x73, 0x65, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x12, 0x11, 0x2e, 0x73, 0x64, - 0x6b, 0x2e, 0x76, 0x31, 0x2e, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x52, 0x65, 0x66, 0x1a, 0x16, - 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, - 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, 0x38, 0x0a, 0x0b, 0x53, 0x74, 0x61, 0x72, 0x74, 0x4d, - 0x69, 0x6e, 0x69, 0x6e, 0x67, 0x12, 0x11, 0x2e, 0x73, 0x64, 0x6b, 0x2e, 0x76, 0x31, 0x2e, 0x44, - 0x65, 0x76, 0x69, 0x63, 0x65, 0x52, 0x65, 0x66, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, - 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, - 0x12, 0x37, 0x0a, 0x0a, 0x53, 0x74, 0x6f, 0x70, 0x4d, 0x69, 0x6e, 0x69, 0x6e, 0x67, 0x12, 0x11, + 0x6c, 0x12, 0x26, 0x2e, 0x73, 0x64, 0x6b, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x43, 0x61, + 0x70, 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x69, 0x65, 0x73, 0x46, 0x6f, 0x72, 0x4d, 0x6f, 0x64, + 0x65, 0x6c, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x27, 0x2e, 0x73, 0x64, 0x6b, 0x2e, + 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x43, 0x61, 0x70, 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x69, + 0x65, 0x73, 0x46, 0x6f, 0x72, 0x4d, 0x6f, 0x64, 0x65, 0x6c, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x12, 0x4e, 0x0a, 0x11, 0x47, 0x65, 0x74, 0x44, 0x69, 0x73, 0x63, 0x6f, 0x76, 0x65, + 0x72, 0x79, 0x50, 0x6f, 0x72, 0x74, 0x73, 0x12, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, + 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, + 0x21, 0x2e, 0x73, 0x64, 0x6b, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x44, 0x69, 0x73, 0x63, + 0x6f, 0x76, 0x65, 0x72, 0x79, 0x50, 0x6f, 0x72, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x12, 0x40, 0x0a, 0x09, 0x4e, 0x65, 0x77, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x12, + 0x18, 0x2e, 0x73, 0x64, 0x6b, 0x2e, 0x76, 0x31, 0x2e, 0x4e, 0x65, 0x77, 0x44, 0x65, 0x76, 0x69, + 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x19, 0x2e, 0x73, 0x64, 0x6b, 0x2e, + 0x76, 0x31, 0x2e, 0x4e, 0x65, 0x77, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x4f, 0x0a, 0x0e, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x62, 0x65, + 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x12, 0x1d, 0x2e, 0x73, 0x64, 0x6b, 0x2e, 0x76, 0x31, 0x2e, + 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x62, 0x65, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1e, 0x2e, 0x73, 0x64, 0x6b, 0x2e, 0x76, 0x31, 0x2e, 0x44, + 0x65, 0x73, 0x63, 0x72, 0x69, 0x62, 0x65, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x38, 0x0a, 0x0b, 0x43, 0x6c, 0x6f, 0x73, 0x65, 0x44, 0x65, + 0x76, 0x69, 0x63, 0x65, 0x12, 0x11, 0x2e, 0x73, 0x64, 0x6b, 0x2e, 0x76, 0x31, 0x2e, 0x44, 0x65, + 0x76, 0x69, 0x63, 0x65, 0x52, 0x65, 0x66, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, + 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, + 0x38, 0x0a, 0x0b, 0x53, 0x74, 0x61, 0x72, 0x74, 0x4d, 0x69, 0x6e, 0x69, 0x6e, 0x67, 0x12, 0x11, 0x2e, 0x73, 0x64, 0x6b, 0x2e, 0x76, 0x31, 0x2e, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x52, 0x65, 0x66, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, - 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, 0x35, 0x0a, 0x08, 0x42, 0x6c, 0x69, - 0x6e, 0x6b, 0x4c, 0x45, 0x44, 0x12, 0x11, 0x2e, 0x73, 0x64, 0x6b, 0x2e, 0x76, 0x31, 0x2e, 0x44, - 0x65, 0x76, 0x69, 0x63, 0x65, 0x52, 0x65, 0x66, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, - 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, - 0x12, 0x33, 0x0a, 0x06, 0x52, 0x65, 0x62, 0x6f, 0x6f, 0x74, 0x12, 0x11, 0x2e, 0x73, 0x64, 0x6b, - 0x2e, 0x76, 0x31, 0x2e, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x52, 0x65, 0x66, 0x1a, 0x16, 0x2e, + 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, 0x37, 0x0a, 0x0a, 0x53, 0x74, 0x6f, + 0x70, 0x4d, 0x69, 0x6e, 0x69, 0x6e, 0x67, 0x12, 0x11, 0x2e, 0x73, 0x64, 0x6b, 0x2e, 0x76, 0x31, + 0x2e, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x52, 0x65, 0x66, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, + 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, + 0x74, 0x79, 0x12, 0x35, 0x0a, 0x08, 0x42, 0x6c, 0x69, 0x6e, 0x6b, 0x4c, 0x45, 0x44, 0x12, 0x11, + 0x2e, 0x73, 0x64, 0x6b, 0x2e, 0x76, 0x31, 0x2e, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x52, 0x65, + 0x66, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, 0x33, 0x0a, 0x06, 0x52, 0x65, 0x62, + 0x6f, 0x6f, 0x74, 0x12, 0x11, 0x2e, 0x73, 0x64, 0x6b, 0x2e, 0x76, 0x31, 0x2e, 0x44, 0x65, 0x76, + 0x69, 0x63, 0x65, 0x52, 0x65, 0x66, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, 0x47, + 0x0a, 0x0e, 0x53, 0x65, 0x74, 0x43, 0x6f, 0x6f, 0x6c, 0x69, 0x6e, 0x67, 0x4d, 0x6f, 0x64, 0x65, + 0x12, 0x1d, 0x2e, 0x73, 0x64, 0x6b, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x65, 0x74, 0x43, 0x6f, 0x6f, + 0x6c, 0x69, 0x6e, 0x67, 0x4d, 0x6f, 0x64, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, + 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, + 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, 0x43, 0x0a, 0x0e, 0x47, 0x65, 0x74, 0x43, 0x6f, + 0x6f, 0x6c, 0x69, 0x6e, 0x67, 0x4d, 0x6f, 0x64, 0x65, 0x12, 0x11, 0x2e, 0x73, 0x64, 0x6b, 0x2e, + 0x76, 0x31, 0x2e, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x52, 0x65, 0x66, 0x1a, 0x1e, 0x2e, 0x73, + 0x64, 0x6b, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x43, 0x6f, 0x6f, 0x6c, 0x69, 0x6e, 0x67, + 0x4d, 0x6f, 0x64, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x47, 0x0a, 0x0e, + 0x53, 0x65, 0x74, 0x50, 0x6f, 0x77, 0x65, 0x72, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x12, 0x1d, + 0x2e, 0x73, 0x64, 0x6b, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x65, 0x74, 0x50, 0x6f, 0x77, 0x65, 0x72, + 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, - 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, 0x47, 0x0a, 0x0e, 0x53, 0x65, 0x74, 0x43, 0x6f, 0x6f, 0x6c, - 0x69, 0x6e, 0x67, 0x4d, 0x6f, 0x64, 0x65, 0x12, 0x1d, 0x2e, 0x73, 0x64, 0x6b, 0x2e, 0x76, 0x31, - 0x2e, 0x53, 0x65, 0x74, 0x43, 0x6f, 0x6f, 0x6c, 0x69, 0x6e, 0x67, 0x4d, 0x6f, 0x64, 0x65, 0x52, - 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, - 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, 0x43, - 0x0a, 0x0e, 0x47, 0x65, 0x74, 0x43, 0x6f, 0x6f, 0x6c, 0x69, 0x6e, 0x67, 0x4d, 0x6f, 0x64, 0x65, - 0x12, 0x11, 0x2e, 0x73, 0x64, 0x6b, 0x2e, 0x76, 0x31, 0x2e, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, - 0x52, 0x65, 0x66, 0x1a, 0x1e, 0x2e, 0x73, 0x64, 0x6b, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, - 0x43, 0x6f, 0x6f, 0x6c, 0x69, 0x6e, 0x67, 0x4d, 0x6f, 0x64, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, - 0x6e, 0x73, 0x65, 0x12, 0x47, 0x0a, 0x0e, 0x53, 0x65, 0x74, 0x50, 0x6f, 0x77, 0x65, 0x72, 0x54, - 0x61, 0x72, 0x67, 0x65, 0x74, 0x12, 0x1d, 0x2e, 0x73, 0x64, 0x6b, 0x2e, 0x76, 0x31, 0x2e, 0x53, - 0x65, 0x74, 0x50, 0x6f, 0x77, 0x65, 0x72, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x52, 0x65, 0x71, - 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, - 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, 0x4d, 0x0a, 0x11, - 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x4d, 0x69, 0x6e, 0x69, 0x6e, 0x67, 0x50, 0x6f, 0x6f, 0x6c, - 0x73, 0x12, 0x20, 0x2e, 0x73, 0x64, 0x6b, 0x2e, 0x76, 0x31, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, - 0x65, 0x4d, 0x69, 0x6e, 0x69, 0x6e, 0x67, 0x50, 0x6f, 0x6f, 0x6c, 0x73, 0x52, 0x65, 0x71, 0x75, - 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, - 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, 0x4f, 0x0a, 0x0e, 0x47, - 0x65, 0x74, 0x4d, 0x69, 0x6e, 0x69, 0x6e, 0x67, 0x50, 0x6f, 0x6f, 0x6c, 0x73, 0x12, 0x1d, 0x2e, - 0x73, 0x64, 0x6b, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x4d, 0x69, 0x6e, 0x69, 0x6e, 0x67, - 0x50, 0x6f, 0x6f, 0x6c, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1e, 0x2e, 0x73, - 0x64, 0x6b, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x4d, 0x69, 0x6e, 0x69, 0x6e, 0x67, 0x50, - 0x6f, 0x6f, 0x6c, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x49, 0x0a, 0x0c, - 0x44, 0x6f, 0x77, 0x6e, 0x6c, 0x6f, 0x61, 0x64, 0x4c, 0x6f, 0x67, 0x73, 0x12, 0x1b, 0x2e, 0x73, - 0x64, 0x6b, 0x2e, 0x76, 0x31, 0x2e, 0x44, 0x6f, 0x77, 0x6e, 0x6c, 0x6f, 0x61, 0x64, 0x4c, 0x6f, - 0x67, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1c, 0x2e, 0x73, 0x64, 0x6b, 0x2e, - 0x76, 0x31, 0x2e, 0x44, 0x6f, 0x77, 0x6e, 0x6c, 0x6f, 0x61, 0x64, 0x4c, 0x6f, 0x67, 0x73, 0x52, - 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x47, 0x0a, 0x0e, 0x55, 0x70, 0x64, 0x61, 0x74, - 0x65, 0x46, 0x69, 0x72, 0x6d, 0x77, 0x61, 0x72, 0x65, 0x12, 0x1d, 0x2e, 0x73, 0x64, 0x6b, 0x2e, - 0x76, 0x31, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x46, 0x69, 0x72, 0x6d, 0x77, 0x61, 0x72, - 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, - 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, - 0x12, 0x55, 0x0a, 0x17, 0x47, 0x65, 0x74, 0x46, 0x69, 0x72, 0x6d, 0x77, 0x61, 0x72, 0x65, 0x55, - 0x70, 0x64, 0x61, 0x74, 0x65, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x11, 0x2e, 0x73, 0x64, - 0x6b, 0x2e, 0x76, 0x31, 0x2e, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x52, 0x65, 0x66, 0x1a, 0x27, - 0x2e, 0x73, 0x64, 0x6b, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x46, 0x69, 0x72, 0x6d, 0x77, - 0x61, 0x72, 0x65, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, - 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x33, 0x0a, 0x06, 0x55, 0x6e, 0x70, 0x61, 0x69, - 0x72, 0x12, 0x11, 0x2e, 0x73, 0x64, 0x6b, 0x2e, 0x76, 0x31, 0x2e, 0x44, 0x65, 0x76, 0x69, 0x63, - 0x65, 0x52, 0x65, 0x66, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, - 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, 0x51, 0x0a, 0x13, - 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x4d, 0x69, 0x6e, 0x65, 0x72, 0x50, 0x61, 0x73, 0x73, 0x77, - 0x6f, 0x72, 0x64, 0x12, 0x22, 0x2e, 0x73, 0x64, 0x6b, 0x2e, 0x76, 0x31, 0x2e, 0x55, 0x70, 0x64, - 0x61, 0x74, 0x65, 0x4d, 0x69, 0x6e, 0x65, 0x72, 0x50, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, - 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, - 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, - 0x39, 0x0a, 0x07, 0x43, 0x75, 0x72, 0x74, 0x61, 0x69, 0x6c, 0x12, 0x16, 0x2e, 0x73, 0x64, 0x6b, - 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x75, 0x72, 0x74, 0x61, 0x69, 0x6c, 0x52, 0x65, 0x71, 0x75, 0x65, - 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, - 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, 0x3d, 0x0a, 0x09, 0x55, 0x6e, - 0x63, 0x75, 0x72, 0x74, 0x61, 0x69, 0x6c, 0x12, 0x18, 0x2e, 0x73, 0x64, 0x6b, 0x2e, 0x76, 0x31, - 0x2e, 0x55, 0x6e, 0x63, 0x75, 0x72, 0x74, 0x61, 0x69, 0x6c, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, 0x4d, 0x0a, 0x11, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x4d, + 0x69, 0x6e, 0x69, 0x6e, 0x67, 0x50, 0x6f, 0x6f, 0x6c, 0x73, 0x12, 0x20, 0x2e, 0x73, 0x64, 0x6b, + 0x2e, 0x76, 0x31, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x4d, 0x69, 0x6e, 0x69, 0x6e, 0x67, + 0x50, 0x6f, 0x6f, 0x6c, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x67, + 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, + 0x6d, 0x70, 0x74, 0x79, 0x12, 0x4f, 0x0a, 0x0e, 0x47, 0x65, 0x74, 0x4d, 0x69, 0x6e, 0x69, 0x6e, + 0x67, 0x50, 0x6f, 0x6f, 0x6c, 0x73, 0x12, 0x1d, 0x2e, 0x73, 0x64, 0x6b, 0x2e, 0x76, 0x31, 0x2e, + 0x47, 0x65, 0x74, 0x4d, 0x69, 0x6e, 0x69, 0x6e, 0x67, 0x50, 0x6f, 0x6f, 0x6c, 0x73, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1e, 0x2e, 0x73, 0x64, 0x6b, 0x2e, 0x76, 0x31, 0x2e, 0x47, + 0x65, 0x74, 0x4d, 0x69, 0x6e, 0x69, 0x6e, 0x67, 0x50, 0x6f, 0x6f, 0x6c, 0x73, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x49, 0x0a, 0x0c, 0x44, 0x6f, 0x77, 0x6e, 0x6c, 0x6f, 0x61, + 0x64, 0x4c, 0x6f, 0x67, 0x73, 0x12, 0x1b, 0x2e, 0x73, 0x64, 0x6b, 0x2e, 0x76, 0x31, 0x2e, 0x44, + 0x6f, 0x77, 0x6e, 0x6c, 0x6f, 0x61, 0x64, 0x4c, 0x6f, 0x67, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x1a, 0x1c, 0x2e, 0x73, 0x64, 0x6b, 0x2e, 0x76, 0x31, 0x2e, 0x44, 0x6f, 0x77, 0x6e, + 0x6c, 0x6f, 0x61, 0x64, 0x4c, 0x6f, 0x67, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x12, 0x47, 0x0a, 0x0e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x46, 0x69, 0x72, 0x6d, 0x77, 0x61, + 0x72, 0x65, 0x12, 0x1d, 0x2e, 0x73, 0x64, 0x6b, 0x2e, 0x76, 0x31, 0x2e, 0x55, 0x70, 0x64, 0x61, + 0x74, 0x65, 0x46, 0x69, 0x72, 0x6d, 0x77, 0x61, 0x72, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, - 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, 0x38, 0x0a, 0x0c, 0x44, 0x65, 0x76, - 0x69, 0x63, 0x65, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x11, 0x2e, 0x73, 0x64, 0x6b, 0x2e, - 0x76, 0x31, 0x2e, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x52, 0x65, 0x66, 0x1a, 0x15, 0x2e, 0x73, - 0x64, 0x6b, 0x2e, 0x76, 0x31, 0x2e, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x4d, 0x65, 0x74, 0x72, - 0x69, 0x63, 0x73, 0x12, 0x58, 0x0a, 0x11, 0x47, 0x65, 0x74, 0x54, 0x69, 0x6d, 0x65, 0x53, 0x65, - 0x72, 0x69, 0x65, 0x73, 0x44, 0x61, 0x74, 0x61, 0x12, 0x20, 0x2e, 0x73, 0x64, 0x6b, 0x2e, 0x76, - 0x31, 0x2e, 0x47, 0x65, 0x74, 0x54, 0x69, 0x6d, 0x65, 0x53, 0x65, 0x72, 0x69, 0x65, 0x73, 0x44, - 0x61, 0x74, 0x61, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x21, 0x2e, 0x73, 0x64, 0x6b, - 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x54, 0x69, 0x6d, 0x65, 0x53, 0x65, 0x72, 0x69, 0x65, - 0x73, 0x44, 0x61, 0x74, 0x61, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x5e, 0x0a, - 0x13, 0x47, 0x65, 0x74, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x57, 0x65, 0x62, 0x56, 0x69, 0x65, - 0x77, 0x55, 0x52, 0x4c, 0x12, 0x22, 0x2e, 0x73, 0x64, 0x6b, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, - 0x74, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x57, 0x65, 0x62, 0x56, 0x69, 0x65, 0x77, 0x55, 0x52, - 0x4c, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x23, 0x2e, 0x73, 0x64, 0x6b, 0x2e, 0x76, - 0x31, 0x2e, 0x47, 0x65, 0x74, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x57, 0x65, 0x62, 0x56, 0x69, - 0x65, 0x77, 0x55, 0x52, 0x4c, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x46, 0x0a, - 0x0b, 0x42, 0x61, 0x74, 0x63, 0x68, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x1a, 0x2e, 0x73, - 0x64, 0x6b, 0x2e, 0x76, 0x31, 0x2e, 0x42, 0x61, 0x74, 0x63, 0x68, 0x53, 0x74, 0x61, 0x74, 0x75, - 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1b, 0x2e, 0x73, 0x64, 0x6b, 0x2e, 0x76, - 0x31, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x42, 0x61, 0x74, 0x63, 0x68, 0x52, 0x65, 0x73, - 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x3e, 0x0a, 0x09, 0x53, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, - 0x62, 0x65, 0x12, 0x18, 0x2e, 0x73, 0x64, 0x6b, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x75, 0x62, 0x73, - 0x63, 0x72, 0x69, 0x62, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x15, 0x2e, 0x73, - 0x64, 0x6b, 0x2e, 0x76, 0x31, 0x2e, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x4d, 0x65, 0x74, 0x72, - 0x69, 0x63, 0x73, 0x30, 0x01, 0x12, 0x34, 0x0a, 0x09, 0x47, 0x65, 0x74, 0x45, 0x72, 0x72, 0x6f, - 0x72, 0x73, 0x12, 0x11, 0x2e, 0x73, 0x64, 0x6b, 0x2e, 0x76, 0x31, 0x2e, 0x44, 0x65, 0x76, 0x69, - 0x63, 0x65, 0x52, 0x65, 0x66, 0x1a, 0x14, 0x2e, 0x73, 0x64, 0x6b, 0x2e, 0x76, 0x31, 0x2e, 0x44, - 0x65, 0x76, 0x69, 0x63, 0x65, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x73, 0x42, 0x84, 0x01, 0x0a, 0x0a, - 0x63, 0x6f, 0x6d, 0x2e, 0x73, 0x64, 0x6b, 0x2e, 0x76, 0x31, 0x42, 0x0b, 0x44, 0x72, 0x69, 0x76, - 0x65, 0x72, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x30, 0x67, 0x69, 0x74, 0x68, 0x75, - 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x2f, 0x70, 0x72, 0x6f, 0x74, - 0x6f, 0x2d, 0x66, 0x6c, 0x65, 0x65, 0x74, 0x2f, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2f, 0x73, - 0x64, 0x6b, 0x2f, 0x76, 0x31, 0x2f, 0x70, 0x62, 0x3b, 0x70, 0x62, 0xa2, 0x02, 0x03, 0x53, 0x58, - 0x58, 0xaa, 0x02, 0x06, 0x53, 0x64, 0x6b, 0x2e, 0x56, 0x31, 0xca, 0x02, 0x06, 0x53, 0x64, 0x6b, - 0x5c, 0x56, 0x31, 0xe2, 0x02, 0x12, 0x53, 0x64, 0x6b, 0x5c, 0x56, 0x31, 0x5c, 0x47, 0x50, 0x42, - 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x07, 0x53, 0x64, 0x6b, 0x3a, 0x3a, - 0x56, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, 0x55, 0x0a, 0x17, 0x47, 0x65, 0x74, + 0x46, 0x69, 0x72, 0x6d, 0x77, 0x61, 0x72, 0x65, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x53, 0x74, + 0x61, 0x74, 0x75, 0x73, 0x12, 0x11, 0x2e, 0x73, 0x64, 0x6b, 0x2e, 0x76, 0x31, 0x2e, 0x44, 0x65, + 0x76, 0x69, 0x63, 0x65, 0x52, 0x65, 0x66, 0x1a, 0x27, 0x2e, 0x73, 0x64, 0x6b, 0x2e, 0x76, 0x31, + 0x2e, 0x47, 0x65, 0x74, 0x46, 0x69, 0x72, 0x6d, 0x77, 0x61, 0x72, 0x65, 0x55, 0x70, 0x64, 0x61, + 0x74, 0x65, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x12, 0x33, 0x0a, 0x06, 0x55, 0x6e, 0x70, 0x61, 0x69, 0x72, 0x12, 0x11, 0x2e, 0x73, 0x64, 0x6b, + 0x2e, 0x76, 0x31, 0x2e, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x52, 0x65, 0x66, 0x1a, 0x16, 0x2e, + 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, + 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, 0x51, 0x0a, 0x13, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x4d, + 0x69, 0x6e, 0x65, 0x72, 0x50, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x12, 0x22, 0x2e, 0x73, + 0x64, 0x6b, 0x2e, 0x76, 0x31, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x4d, 0x69, 0x6e, 0x65, + 0x72, 0x50, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, + 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, 0x39, 0x0a, 0x07, 0x43, 0x75, 0x72, 0x74, + 0x61, 0x69, 0x6c, 0x12, 0x16, 0x2e, 0x73, 0x64, 0x6b, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x75, 0x72, + 0x74, 0x61, 0x69, 0x6c, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x67, 0x6f, + 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, + 0x70, 0x74, 0x79, 0x12, 0x3d, 0x0a, 0x09, 0x55, 0x6e, 0x63, 0x75, 0x72, 0x74, 0x61, 0x69, 0x6c, + 0x12, 0x18, 0x2e, 0x73, 0x64, 0x6b, 0x2e, 0x76, 0x31, 0x2e, 0x55, 0x6e, 0x63, 0x75, 0x72, 0x74, + 0x61, 0x69, 0x6c, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, + 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, + 0x74, 0x79, 0x12, 0x38, 0x0a, 0x0c, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x53, 0x74, 0x61, 0x74, + 0x75, 0x73, 0x12, 0x11, 0x2e, 0x73, 0x64, 0x6b, 0x2e, 0x76, 0x31, 0x2e, 0x44, 0x65, 0x76, 0x69, + 0x63, 0x65, 0x52, 0x65, 0x66, 0x1a, 0x15, 0x2e, 0x73, 0x64, 0x6b, 0x2e, 0x76, 0x31, 0x2e, 0x44, + 0x65, 0x76, 0x69, 0x63, 0x65, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x12, 0x58, 0x0a, 0x11, + 0x47, 0x65, 0x74, 0x54, 0x69, 0x6d, 0x65, 0x53, 0x65, 0x72, 0x69, 0x65, 0x73, 0x44, 0x61, 0x74, + 0x61, 0x12, 0x20, 0x2e, 0x73, 0x64, 0x6b, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x54, 0x69, + 0x6d, 0x65, 0x53, 0x65, 0x72, 0x69, 0x65, 0x73, 0x44, 0x61, 0x74, 0x61, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x1a, 0x21, 0x2e, 0x73, 0x64, 0x6b, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, + 0x54, 0x69, 0x6d, 0x65, 0x53, 0x65, 0x72, 0x69, 0x65, 0x73, 0x44, 0x61, 0x74, 0x61, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x5e, 0x0a, 0x13, 0x47, 0x65, 0x74, 0x44, 0x65, 0x76, + 0x69, 0x63, 0x65, 0x57, 0x65, 0x62, 0x56, 0x69, 0x65, 0x77, 0x55, 0x52, 0x4c, 0x12, 0x22, 0x2e, + 0x73, 0x64, 0x6b, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, + 0x57, 0x65, 0x62, 0x56, 0x69, 0x65, 0x77, 0x55, 0x52, 0x4c, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x1a, 0x23, 0x2e, 0x73, 0x64, 0x6b, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x44, 0x65, + 0x76, 0x69, 0x63, 0x65, 0x57, 0x65, 0x62, 0x56, 0x69, 0x65, 0x77, 0x55, 0x52, 0x4c, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x46, 0x0a, 0x0b, 0x42, 0x61, 0x74, 0x63, 0x68, 0x53, + 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x1a, 0x2e, 0x73, 0x64, 0x6b, 0x2e, 0x76, 0x31, 0x2e, 0x42, + 0x61, 0x74, 0x63, 0x68, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x1a, 0x1b, 0x2e, 0x73, 0x64, 0x6b, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x75, + 0x73, 0x42, 0x61, 0x74, 0x63, 0x68, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x3e, + 0x0a, 0x09, 0x53, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x62, 0x65, 0x12, 0x18, 0x2e, 0x73, 0x64, + 0x6b, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x62, 0x65, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x15, 0x2e, 0x73, 0x64, 0x6b, 0x2e, 0x76, 0x31, 0x2e, 0x44, + 0x65, 0x76, 0x69, 0x63, 0x65, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x30, 0x01, 0x12, 0x34, + 0x0a, 0x09, 0x47, 0x65, 0x74, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x73, 0x12, 0x11, 0x2e, 0x73, 0x64, + 0x6b, 0x2e, 0x76, 0x31, 0x2e, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x52, 0x65, 0x66, 0x1a, 0x14, + 0x2e, 0x73, 0x64, 0x6b, 0x2e, 0x76, 0x31, 0x2e, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x45, 0x72, + 0x72, 0x6f, 0x72, 0x73, 0x42, 0x84, 0x01, 0x0a, 0x0a, 0x63, 0x6f, 0x6d, 0x2e, 0x73, 0x64, 0x6b, + 0x2e, 0x76, 0x31, 0x42, 0x0b, 0x44, 0x72, 0x69, 0x76, 0x65, 0x72, 0x50, 0x72, 0x6f, 0x74, 0x6f, + 0x50, 0x01, 0x5a, 0x30, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x62, + 0x6c, 0x6f, 0x63, 0x6b, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2d, 0x66, 0x6c, 0x65, 0x65, 0x74, + 0x2f, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2f, 0x73, 0x64, 0x6b, 0x2f, 0x76, 0x31, 0x2f, 0x70, + 0x62, 0x3b, 0x70, 0x62, 0xa2, 0x02, 0x03, 0x53, 0x58, 0x58, 0xaa, 0x02, 0x06, 0x53, 0x64, 0x6b, + 0x2e, 0x56, 0x31, 0xca, 0x02, 0x06, 0x53, 0x64, 0x6b, 0x5c, 0x56, 0x31, 0xe2, 0x02, 0x12, 0x53, + 0x64, 0x6b, 0x5c, 0x56, 0x31, 0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, + 0x61, 0xea, 0x02, 0x07, 0x53, 0x64, 0x6b, 0x3a, 0x3a, 0x56, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x33, }) var ( diff --git a/server/sdk/v1/plugin.go b/server/sdk/v1/plugin.go index c2363abf0..aece64af0 100644 --- a/server/sdk/v1/plugin.go +++ b/server/sdk/v1/plugin.go @@ -569,8 +569,10 @@ func (s *DriverGRPCServer) UpdateFirmware(ctx context.Context, req *pb.UpdateFir firmware := FirmwareFile{ Reader: file, + ID: fw.Id, Filename: fw.OriginalFilename, Size: fw.FileSize, + SHA256: fw.Sha256, FilePath: fw.FilePath, } @@ -1164,6 +1166,8 @@ func (d *DeviceGRPCClient) FirmwareUpdate(ctx context.Context, firmware Firmware FilePath: firmware.FilePath, OriginalFilename: firmware.Filename, FileSize: firmware.Size, + Id: firmware.ID, + Sha256: firmware.SHA256, }, }) return err diff --git a/server/sdk/v1/plugin_test.go b/server/sdk/v1/plugin_test.go index 7558813e7..0c7cad276 100644 --- a/server/sdk/v1/plugin_test.go +++ b/server/sdk/v1/plugin_test.go @@ -3,6 +3,8 @@ package sdk import ( "context" "errors" + "os" + "path/filepath" "testing" "time" @@ -211,6 +213,7 @@ type fakeDevice struct { startMiningFunc func(ctx context.Context) error setCoolingModeFunc func(ctx context.Context, mode CoolingMode) error updateMinerPasswordFunc func(ctx context.Context, currentPassword, newPassword string) error + firmwareUpdateFunc func(ctx context.Context, firmware FirmwareFile) error } func (f fakeDevice) ID() string { return "device-123" } @@ -279,9 +282,14 @@ func (f fakeDevice) GetMiningPools(ctx context.Context) ([]ConfiguredPool, error func (f fakeDevice) DownloadLogs(ctx context.Context, since *time.Time, batchLogUUID string) (string, bool, error) { return "", false, nil } -func (f fakeDevice) FirmwareUpdate(ctx context.Context, firmware FirmwareFile) error { return nil } -func (f fakeDevice) Unpair(ctx context.Context) error { return nil } -func (f fakeDevice) GetErrors(ctx context.Context) (DeviceErrors, error) { return DeviceErrors{}, nil } +func (f fakeDevice) FirmwareUpdate(ctx context.Context, firmware FirmwareFile) error { + if f.firmwareUpdateFunc != nil { + return f.firmwareUpdateFunc(ctx, firmware) + } + return nil +} +func (f fakeDevice) Unpair(ctx context.Context) error { return nil } +func (f fakeDevice) GetErrors(ctx context.Context) (DeviceErrors, error) { return DeviceErrors{}, nil } func (f fakeDevice) TryBatchStatus(ctx context.Context, ids []string) (map[string]DeviceMetrics, bool, error) { return nil, false, nil } @@ -1182,6 +1190,38 @@ func TestDriverGRPCServer_UncurtailReturnsUnimplementedWhenDeviceLacksCurtailmen assert.Contains(t, st.Message(), "device does not support curtailment") } +func TestDriverGRPCServer_UpdateFirmwarePreservesMetadata(t *testing.T) { + firmwarePath := filepath.Join(t.TempDir(), "update.swu") + require.NoError(t, os.WriteFile(firmwarePath, []byte("firmware"), 0600)) + + device := fakeDevice{ + firmwareUpdateFunc: func(_ context.Context, firmware FirmwareFile) error { + assert.Equal(t, "firmware-1", firmware.ID) + assert.Equal(t, "update.swu", firmware.Filename) + assert.Equal(t, int64(8), firmware.Size) + assert.Equal(t, "64ec88ca00b268e5ba1a35678a1b5316d212f4f366b2477232534a8aeca37f3c", firmware.SHA256) + assert.Equal(t, firmwarePath, firmware.FilePath) + return nil + }, + } + server := &DriverGRPCServer{ + devices: map[string]Device{"device-123": device}, + } + + _, err := server.UpdateFirmware(context.Background(), &pb.UpdateFirmwareRequest{ + Ref: &pb.DeviceRef{DeviceId: "device-123"}, + Firmware: &pb.FirmwareFileInfo{ + FilePath: firmwarePath, + OriginalFilename: "update.swu", + FileSize: 8, + Id: "firmware-1", + Sha256: "64ec88ca00b268e5ba1a35678a1b5316d212f4f366b2477232534a8aeca37f3c", + }, + }) + + require.NoError(t, err) +} + // Control RPCs should preserve SDKError status codes across gRPC. func TestDriverGRPCServer_ControlRPCsMapSDKErrorStatus(t *testing.T) { tests := []struct { diff --git a/server/sdk/v1/python/proto_fleet_sdk/generated/pb/driver_pb2.py b/server/sdk/v1/python/proto_fleet_sdk/generated/pb/driver_pb2.py index 54b128a4a..190b14735 100644 --- a/server/sdk/v1/python/proto_fleet_sdk/generated/pb/driver_pb2.py +++ b/server/sdk/v1/python/proto_fleet_sdk/generated/pb/driver_pb2.py @@ -27,7 +27,7 @@ from google.protobuf import empty_pb2 as google_dot_protobuf_dot_empty__pb2 -DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x0fpb/driver.proto\x12\x06sdk.v1\x1a\x1fgoogle/protobuf/timestamp.proto\x1a\x1egoogle/protobuf/duration.proto\x1a\x1bgoogle/protobuf/empty.proto\"\x7f\n\x0c\x43\x61pabilities\x12\x35\n\x05\x66lags\x18\x01 \x03(\x0b\x32\x1f.sdk.v1.Capabilities.FlagsEntryR\x05\x66lags\x1a\x38\n\nFlagsEntry\x12\x10\n\x03key\x18\x01 \x01(\tR\x03key\x12\x14\n\x05value\x18\x02 \x01(\x08R\x05value:\x02\x38\x01\"U\n\x11HandshakeResponse\x12\x1f\n\x0b\x64river_name\x18\x01 \x01(\tR\ndriverName\x12\x1f\n\x0b\x61pi_version\x18\x02 \x01(\tR\napiVersion\"\x84\x01\n\x16\x44\x65scribeDriverResponse\x12\x1f\n\x0b\x64river_name\x18\x01 \x01(\tR\ndriverName\x12\x1f\n\x0b\x61pi_version\x18\x02 \x01(\tR\napiVersion\x12(\n\x04\x63\x61ps\x18\x03 \x01(\x0b\x32\x14.sdk.v1.CapabilitiesR\x04\x63\x61ps\"\x85\x01\n\x10NewDeviceRequest\x12\x1b\n\tdevice_id\x18\x01 \x01(\tR\x08\x64\x65viceId\x12&\n\x04info\x18\x02 \x01(\x0b\x32\x12.sdk.v1.DeviceInfoR\x04info\x12,\n\x06secret\x18\x03 \x01(\x0b\x32\x14.sdk.v1.SecretBundleR\x06secret\"0\n\x11NewDeviceResponse\x12\x1b\n\tdevice_id\x18\x01 \x01(\tR\x08\x64\x65viceId\"(\n\tDeviceRef\x12\x1b\n\tdevice_id\x18\x01 \x01(\tR\x08\x64\x65viceId\"\x96\x01\n\x0bMetricValue\x12\x14\n\x05value\x18\x01 \x01(\x01R\x05value\x12&\n\x04kind\x18\x02 \x01(\x0e\x32\x12.sdk.v1.MetricKindR\x04kind\x12<\n\x08metadata\x18\x03 \x01(\x0b\x32\x1b.sdk.v1.MetricValueMetaDataH\x00R\x08metadata\x88\x01\x01\x42\x0b\n\t_metadata\"\xac\x02\n\x13MetricValueMetaData\x12\x36\n\x06window\x18\x01 \x01(\x0b\x32\x19.google.protobuf.DurationH\x00R\x06window\x88\x01\x01\x12\x15\n\x03min\x18\x02 \x01(\x01H\x01R\x03min\x88\x01\x01\x12\x15\n\x03max\x18\x03 \x01(\x01H\x02R\x03max\x88\x01\x01\x12\x15\n\x03\x61vg\x18\x04 \x01(\x01H\x03R\x03\x61vg\x88\x01\x01\x12\x1c\n\x07std_dev\x18\x05 \x01(\x01H\x04R\x06stdDev\x88\x01\x01\x12=\n\ttimestamp\x18\x06 \x01(\x0b\x32\x1a.google.protobuf.TimestampH\x05R\ttimestamp\x88\x01\x01\x42\t\n\x07_windowB\x06\n\x04_minB\x06\n\x04_maxB\x06\n\x04_avgB\n\n\x08_std_devB\x0c\n\n_timestamp\"\xf3\x01\n\rComponentInfo\x12\x14\n\x05index\x18\x01 \x01(\x05R\x05index\x12\x12\n\x04name\x18\x02 \x01(\tR\x04name\x12/\n\x06status\x18\x03 \x01(\x0e\x32\x17.sdk.v1.ComponentStatusR\x06status\x12(\n\rstatus_reason\x18\x04 \x01(\tH\x00R\x0cstatusReason\x88\x01\x01\x12=\n\ttimestamp\x18\x05 \x01(\x0b\x32\x1a.google.protobuf.TimestampH\x01R\ttimestamp\x88\x01\x01\x42\x10\n\x0e_status_reasonB\x0c\n\n_timestamp\"\x81\x07\n\x10HashBoardMetrics\x12<\n\x0e\x63omponent_info\x18\x01 \x01(\x0b\x32\x15.sdk.v1.ComponentInfoR\rcomponentInfo\x12(\n\rserial_number\x18\x02 \x01(\tH\x00R\x0cserialNumber\x88\x01\x01\x12:\n\x0chash_rate_hs\x18\x03 \x01(\x0b\x32\x13.sdk.v1.MetricValueH\x01R\nhashRateHs\x88\x01\x01\x12/\n\x06temp_c\x18\x04 \x01(\x0b\x32\x13.sdk.v1.MetricValueH\x02R\x05tempC\x88\x01\x01\x12\x35\n\tvoltage_v\x18\x05 \x01(\x0b\x32\x13.sdk.v1.MetricValueH\x03R\x08voltageV\x88\x01\x01\x12\x35\n\tcurrent_a\x18\x06 \x01(\x0b\x32\x13.sdk.v1.MetricValueH\x04R\x08\x63urrentA\x88\x01\x01\x12:\n\x0cinlet_temp_c\x18\x07 \x01(\x0b\x32\x13.sdk.v1.MetricValueH\x05R\ninletTempC\x88\x01\x01\x12<\n\routlet_temp_c\x18\x08 \x01(\x0b\x32\x13.sdk.v1.MetricValueH\x06R\x0boutletTempC\x88\x01\x01\x12>\n\x0e\x61mbient_temp_c\x18\t \x01(\x0b\x32\x13.sdk.v1.MetricValueH\x07R\x0c\x61mbientTempC\x88\x01\x01\x12\"\n\nchip_count\x18\n \x01(\x05H\x08R\tchipCount\x88\x01\x01\x12\x46\n\x12\x63hip_frequency_mhz\x18\x0b \x01(\x0b\x32\x13.sdk.v1.MetricValueH\tR\x10\x63hipFrequencyMhz\x88\x01\x01\x12)\n\x05\x61sics\x18\x0c \x03(\x0b\x32\x13.sdk.v1.ASICMetricsR\x05\x61sics\x12\x33\n\x0b\x66\x61n_metrics\x18\r \x03(\x0b\x32\x12.sdk.v1.FanMetricsR\nfanMetricsB\x10\n\x0e_serial_numberB\x0f\n\r_hash_rate_hsB\t\n\x07_temp_cB\x0c\n\n_voltage_vB\x0c\n\n_current_aB\x0f\n\r_inlet_temp_cB\x10\n\x0e_outlet_temp_cB\x11\n\x0f_ambient_temp_cB\r\n\x0b_chip_countB\x15\n\x13_chip_frequency_mhz\"\xe8\x02\n\x0b\x41SICMetrics\x12<\n\x0e\x63omponent_info\x18\x01 \x01(\x0b\x32\x15.sdk.v1.ComponentInfoR\rcomponentInfo\x12/\n\x06temp_c\x18\x02 \x01(\x0b\x32\x13.sdk.v1.MetricValueH\x00R\x05tempC\x88\x01\x01\x12=\n\rfrequency_mhz\x18\x03 \x01(\x0b\x32\x13.sdk.v1.MetricValueH\x01R\x0c\x66requencyMhz\x88\x01\x01\x12\x35\n\tvoltage_v\x18\x04 \x01(\x0b\x32\x13.sdk.v1.MetricValueH\x02R\x08voltageV\x88\x01\x01\x12\x39\n\x0bhashrate_hs\x18\x05 \x01(\x0b\x32\x13.sdk.v1.MetricValueH\x03R\nhashrateHs\x88\x01\x01\x42\t\n\x07_temp_cB\x10\n\x0e_frequency_mhzB\x0c\n\n_voltage_vB\x0e\n\x0c_hashrate_hs\"\xb3\x06\n\nPSUMetrics\x12<\n\x0e\x63omponent_info\x18\x01 \x01(\x0b\x32\x15.sdk.v1.ComponentInfoR\rcomponentInfo\x12>\n\x0eoutput_power_w\x18\x02 \x01(\x0b\x32\x13.sdk.v1.MetricValueH\x00R\x0coutputPowerW\x88\x01\x01\x12\x42\n\x10output_voltage_v\x18\x03 \x01(\x0b\x32\x13.sdk.v1.MetricValueH\x01R\x0eoutputVoltageV\x88\x01\x01\x12\x42\n\x10output_current_a\x18\x04 \x01(\x0b\x32\x13.sdk.v1.MetricValueH\x02R\x0eoutputCurrentA\x88\x01\x01\x12<\n\rinput_power_w\x18\x05 \x01(\x0b\x32\x13.sdk.v1.MetricValueH\x03R\x0binputPowerW\x88\x01\x01\x12@\n\x0finput_voltage_v\x18\x06 \x01(\x0b\x32\x13.sdk.v1.MetricValueH\x04R\rinputVoltageV\x88\x01\x01\x12@\n\x0finput_current_a\x18\x07 \x01(\x0b\x32\x13.sdk.v1.MetricValueH\x05R\rinputCurrentA\x88\x01\x01\x12>\n\x0ehotspot_temp_c\x18\x08 \x01(\x0b\x32\x13.sdk.v1.MetricValueH\x06R\x0chotspotTempC\x88\x01\x01\x12G\n\x12\x65\x66\x66iciency_percent\x18\t \x01(\x0b\x32\x13.sdk.v1.MetricValueH\x07R\x11\x65\x66\x66iciencyPercent\x88\x01\x01\x12\x33\n\x0b\x66\x61n_metrics\x18\n \x03(\x0b\x32\x12.sdk.v1.FanMetricsR\nfanMetricsB\x11\n\x0f_output_power_wB\x13\n\x11_output_voltage_vB\x13\n\x11_output_current_aB\x10\n\x0e_input_power_wB\x12\n\x10_input_voltage_vB\x12\n\x10_input_current_aB\x11\n\x0f_hotspot_temp_cB\x15\n\x13_efficiency_percent\"\xfa\x01\n\nFanMetrics\x12<\n\x0e\x63omponent_info\x18\x01 \x01(\x0b\x32\x15.sdk.v1.ComponentInfoR\rcomponentInfo\x12*\n\x03rpm\x18\x02 \x01(\x0b\x32\x13.sdk.v1.MetricValueH\x00R\x03rpm\x88\x01\x01\x12/\n\x06temp_c\x18\x03 \x01(\x0b\x32\x13.sdk.v1.MetricValueH\x01R\x05tempC\x88\x01\x01\x12\x32\n\x07percent\x18\x04 \x01(\x0b\x32\x13.sdk.v1.MetricValueH\x02R\x07percent\x88\x01\x01\x42\x06\n\x04_rpmB\t\n\x07_temp_cB\n\n\x08_percent\"S\n\x13\x43ontrolBoardMetrics\x12<\n\x0e\x63omponent_info\x18\x01 \x01(\x0b\x32\x15.sdk.v1.ComponentInfoR\rcomponentInfo\"\xcb\x01\n\rSensorMetrics\x12<\n\x0e\x63omponent_info\x18\x01 \x01(\x0b\x32\x15.sdk.v1.ComponentInfoR\rcomponentInfo\x12\x17\n\x04type\x18\x02 \x01(\tH\x00R\x04type\x88\x01\x01\x12\x17\n\x04unit\x18\x03 \x01(\tH\x01R\x04unit\x88\x01\x01\x12.\n\x05value\x18\x04 \x01(\x0b\x32\x13.sdk.v1.MetricValueH\x02R\x05value\x88\x01\x01\x42\x07\n\x05_typeB\x07\n\x05_unitB\x08\n\x06_value\"\xf8\x07\n\rDeviceMetrics\x12\x1b\n\tdevice_id\x18\x01 \x01(\tR\x08\x64\x65viceId\x12\x38\n\ttimestamp\x18\x02 \x01(\x0b\x32\x1a.google.protobuf.TimestampR\ttimestamp\x12,\n\x06health\x18\x03 \x01(\x0e\x32\x14.sdk.v1.HealthStatusR\x06health\x12(\n\rhealth_reason\x18\x04 \x01(\tH\x00R\x0chealthReason\x88\x01\x01\x12\x39\n\x0bhashrate_hs\x18\x05 \x01(\x0b\x32\x13.sdk.v1.MetricValueH\x01R\nhashrateHs\x88\x01\x01\x12/\n\x06temp_c\x18\x06 \x01(\x0b\x32\x13.sdk.v1.MetricValueH\x02R\x05tempC\x88\x01\x01\x12\x31\n\x07\x66\x61n_rpm\x18\x07 \x01(\x0b\x32\x13.sdk.v1.MetricValueH\x03R\x06\x66\x61nRpm\x88\x01\x01\x12\x31\n\x07power_w\x18\x08 \x01(\x0b\x32\x13.sdk.v1.MetricValueH\x04R\x06powerW\x88\x01\x01\x12=\n\refficiency_jh\x18\t \x01(\x0b\x32\x13.sdk.v1.MetricValueH\x05R\x0c\x65\x66\x66iciencyJh\x88\x01\x01\x12\x39\n\x0bhash_boards\x18\n \x03(\x0b\x32\x18.sdk.v1.HashBoardMetricsR\nhashBoards\x12\x33\n\x0bpsu_metrics\x18\x0b \x03(\x0b\x32\x12.sdk.v1.PSUMetricsR\npsuMetrics\x12O\n\x15\x63ontrol_board_metrics\x18\x0c \x03(\x0b\x32\x1b.sdk.v1.ControlBoardMetricsR\x13\x63ontrolBoardMetrics\x12\x33\n\x0b\x66\x61n_metrics\x18\r \x03(\x0b\x32\x12.sdk.v1.FanMetricsR\nfanMetrics\x12<\n\x0esensor_metrics\x18\x0e \x03(\x0b\x32\x15.sdk.v1.SensorMetricsR\rsensorMetrics\x12)\n\x10\x66irmware_version\x18\x0f \x01(\tR\x0f\x66irmwareVersion\x12;\n\x17\x64\x65\x66\x61ult_password_active\x18\x11 \x01(\x08H\x06R\x15\x64\x65\x66\x61ultPasswordActive\x88\x01\x01\x42\x10\n\x0e_health_reasonB\x0e\n\x0c_hashrate_hsB\t\n\x07_temp_cB\n\n\x08_fan_rpmB\n\n\x08_power_wB\x10\n\x0e_efficiency_jhB\x1a\n\x18_default_password_activeJ\x04\x08\x10\x10\x11R\x12stratum_v2_support\"4\n\x15\x44\x65scribeDeviceRequest\x12\x1b\n\tdevice_id\x18\x01 \x01(\tR\x08\x64\x65viceId\"n\n\x16\x44\x65scribeDeviceResponse\x12*\n\x06\x64\x65vice\x18\x01 \x01(\x0b\x32\x12.sdk.v1.DeviceInfoR\x06\x64\x65vice\x12(\n\x04\x63\x61ps\x18\x02 \x01(\x0b\x32\x14.sdk.v1.CapabilitiesR\x04\x63\x61ps\"B\n\x13StatusBatchResponse\x12+\n\x05items\x18\x01 \x03(\x0b\x32\x15.sdk.v1.DeviceMetricsR\x05items\";\n\x12\x42\x61tchStatusRequest\x12%\n\x04refs\x18\x01 \x03(\x0b\x32\x11.sdk.v1.DeviceRefR\x04refs\"\xa9\x01\n\x10SubscribeRequest\x12\x1d\n\ndevice_ids\x18\x01 \x03(\tR\tdeviceIds\x12\"\n\nbatch_size\x18\x02 \x01(\x05H\x00R\tbatchSize\x88\x01\x01\x12.\n\x10interval_seconds\x18\x03 \x01(\x05H\x01R\x0fintervalSeconds\x88\x01\x01\x42\r\n\x0b_batch_sizeB\x13\n\x11_interval_seconds\"J\n\x10UsernamePassword\x12\x1a\n\x08username\x18\x01 \x01(\tR\x08username\x12\x1a\n\x08password\x18\x02 \x01(\tR\x08password\"#\n\x0b\x42\x65\x61rerToken\x12\x14\n\x05token\x18\x01 \x01(\tR\x05token\"p\n\rTlsClientCert\x12&\n\x0f\x63lient_cert_pem\x18\x01 \x01(\x0cR\rclientCertPem\x12\x17\n\x07key_pem\x18\x02 \x01(\x0cR\x06keyPem\x12\x1e\n\x0b\x63\x61_cert_pem\x18\x03 \x01(\x0cR\tcaCertPem\"\xa0\x02\n\x0cSecretBundle\x12\x18\n\x07version\x18\x01 \x01(\tR\x07version\x12\x37\n\tuser_pass\x18\x03 \x01(\x0b\x32\x18.sdk.v1.UsernamePasswordH\x00R\x08userPass\x12\x38\n\x0c\x62\x65\x61rer_token\x18\x04 \x01(\x0b\x32\x13.sdk.v1.BearerTokenH\x00R\x0b\x62\x65\x61rerToken\x12?\n\x0ftls_client_cert\x18\x05 \x01(\x0b\x32\x15.sdk.v1.TlsClientCertH\x00R\rtlsClientCert\x12+\n\x03ttl\x18\x06 \x01(\x0b\x32\x19.google.protobuf.DurationR\x03ttlB\x06\n\x04kindJ\x04\x08\x02\x10\x03R\x07\x61pi_key\"e\n\x15SetCoolingModeRequest\x12#\n\x03ref\x18\x01 \x01(\x0b\x32\x11.sdk.v1.DeviceRefR\x03ref\x12\'\n\x04mode\x18\x02 \x01(\x0e\x32\x13.sdk.v1.CoolingModeR\x04mode\"A\n\x16GetCoolingModeResponse\x12\'\n\x04mode\x18\x01 \x01(\x0e\x32\x13.sdk.v1.CoolingModeR\x04mode\"a\n\x0e\x43urtailRequest\x12#\n\x03ref\x18\x01 \x01(\x0b\x32\x11.sdk.v1.DeviceRefR\x03ref\x12*\n\x05level\x18\x02 \x01(\x0e\x32\x14.sdk.v1.CurtailLevelR\x05level\"7\n\x10UncurtailRequest\x12#\n\x03ref\x18\x01 \x01(\x0b\x32\x11.sdk.v1.DeviceRefR\x03ref\"\x80\x01\n\x15SetPowerTargetRequest\x12#\n\x03ref\x18\x01 \x01(\x0b\x32\x11.sdk.v1.DeviceRefR\x03ref\x12\x42\n\x10performance_mode\x18\x02 \x01(\x0e\x32\x17.sdk.v1.PerformanceModeR\x0fperformanceMode\"[\n\nMiningPool\x12\x1a\n\x08priority\x18\x01 \x01(\x05R\x08priority\x12\x10\n\x03url\x18\x02 \x01(\tR\x03url\x12\x1f\n\x0bworker_name\x18\x03 \x01(\tR\nworkerName\"i\n\x18UpdateMiningPoolsRequest\x12#\n\x03ref\x18\x01 \x01(\x0b\x32\x11.sdk.v1.DeviceRefR\x03ref\x12(\n\x05pools\x18\x02 \x03(\x0b\x32\x12.sdk.v1.MiningPoolR\x05pools\"Z\n\x0e\x43onfiguredPool\x12\x1a\n\x08priority\x18\x01 \x01(\x05R\x08priority\x12\x10\n\x03url\x18\x02 \x01(\tR\x03url\x12\x1a\n\x08username\x18\x03 \x01(\tR\x08username\"<\n\x15GetMiningPoolsRequest\x12#\n\x03ref\x18\x01 \x01(\x0b\x32\x11.sdk.v1.DeviceRefR\x03ref\"F\n\x16GetMiningPoolsResponse\x12,\n\x05pools\x18\x01 \x03(\x0b\x32\x16.sdk.v1.ConfiguredPoolR\x05pools\"\x92\x01\n\x13\x44ownloadLogsRequest\x12#\n\x03ref\x18\x01 \x01(\x0b\x32\x11.sdk.v1.DeviceRefR\x03ref\x12\x30\n\x05since\x18\x02 \x01(\x0b\x32\x1a.google.protobuf.TimestampR\x05since\x12$\n\x0e\x62\x61tch_log_uuid\x18\x03 \x01(\tR\x0c\x62\x61tchLogUuid\"N\n\x14\x44ownloadLogsResponse\x12\x19\n\x08log_data\x18\x01 \x01(\tR\x07logData\x12\x1b\n\tmore_data\x18\x02 \x01(\x08R\x08moreData\"\xe3\x02\n\nDeviceInfo\x12\x12\n\x04host\x18\x01 \x01(\tR\x04host\x12\x12\n\x04port\x18\x02 \x01(\x05R\x04port\x12\x1d\n\nurl_scheme\x18\x03 \x01(\tR\turlScheme\x12#\n\rserial_number\x18\x04 \x01(\tR\x0cserialNumber\x12\x14\n\x05model\x18\x05 \x01(\tR\x05model\x12\"\n\x0cmanufacturer\x18\x06 \x01(\tR\x0cmanufacturer\x12\x1f\n\x0bmac_address\x18\x08 \x01(\tR\nmacAddress\x12)\n\x10\x66irmware_version\x18\t \x01(\tR\x0f\x66irmwareVersion\x12;\n\x17\x64\x65\x66\x61ult_password_active\x18\n \x01(\x08H\x00R\x15\x64\x65\x66\x61ultPasswordActive\x88\x01\x01\x42\x1a\n\x18_default_password_activeJ\x04\x08\x07\x10\x08R\x04type\"J\n\x15\x44iscoverDeviceRequest\x12\x1d\n\nip_address\x18\x01 \x01(\tR\tipAddress\x12\x12\n\x04port\x18\x02 \x01(\tR\x04port\"D\n\x16\x44iscoverDeviceResponse\x12*\n\x06\x64\x65vice\x18\x01 \x01(\x0b\x32\x12.sdk.v1.DeviceInfoR\x06\x64\x65vice\"m\n\x11PairDeviceRequest\x12*\n\x06\x64\x65vice\x18\x01 \x01(\x0b\x32\x12.sdk.v1.DeviceInfoR\x06\x64\x65vice\x12,\n\x06\x61\x63\x63\x65ss\x18\x02 \x01(\x0b\x32\x14.sdk.v1.SecretBundleR\x06\x61\x63\x63\x65ss\"@\n\x12PairDeviceResponse\x12*\n\x06\x64\x65vice\x18\x01 \x01(\x0b\x32\x12.sdk.v1.DeviceInfoR\x06\x64\x65vice\"m\n\x1cGetDefaultCredentialsRequest\x12\"\n\x0cmanufacturer\x18\x01 \x01(\tR\x0cmanufacturer\x12)\n\x10\x66irmware_version\x18\x02 \x01(\tR\x0f\x66irmwareVersion\"[\n\x1dGetDefaultCredentialsResponse\x12:\n\x0b\x63redentials\x18\x01 \x03(\x0b\x32\x18.sdk.v1.UsernamePasswordR\x0b\x63redentials\"Z\n\x1eGetCapabilitiesForModelRequest\x12\x14\n\x05model\x18\x01 \x01(\tR\x05model\x12\"\n\x0cmanufacturer\x18\x02 \x01(\tR\x0cmanufacturer\"K\n\x1fGetCapabilitiesForModelResponse\x12(\n\x04\x63\x61ps\x18\x01 \x01(\x0b\x32\x14.sdk.v1.CapabilitiesR\x04\x63\x61ps\"1\n\x19GetDiscoveryPortsResponse\x12\x14\n\x05ports\x18\x01 \x03(\tR\x05ports\"/\n\x1bGetDeviceWebViewURLResponse\x12\x10\n\x03url\x18\x01 \x01(\tR\x03url\"A\n\x1aGetDeviceWebViewURLRequest\x12#\n\x03ref\x18\x01 \x01(\x0b\x32\x11.sdk.v1.DeviceRefR\x03ref\"\xcf\x02\n\x18GetTimeSeriesDataRequest\x12#\n\x03ref\x18\x01 \x01(\x0b\x32\x11.sdk.v1.DeviceRefR\x03ref\x12!\n\x0cmetric_names\x18\x02 \x03(\tR\x0bmetricNames\x12\x39\n\nstart_time\x18\x03 \x01(\x0b\x32\x1a.google.protobuf.TimestampR\tstartTime\x12\x35\n\x08\x65nd_time\x18\x04 \x01(\x0b\x32\x1a.google.protobuf.TimestampR\x07\x65ndTime\x12;\n\x0bgranularity\x18\x05 \x01(\x0b\x32\x19.google.protobuf.DurationR\x0bgranularity\x12\x1d\n\nmax_points\x18\x06 \x01(\x05R\tmaxPoints\x12\x1d\n\npage_token\x18\x07 \x01(\tR\tpageToken\"r\n\x19GetTimeSeriesDataResponse\x12-\n\x06series\x18\x01 \x03(\x0b\x32\x15.sdk.v1.DeviceMetricsR\x06series\x12&\n\x0fnext_page_token\x18\x02 \x01(\tR\rnextPageToken\"\x8f\x01\n\x1aUpdateMinerPasswordRequest\x12#\n\x03ref\x18\x01 \x01(\x0b\x32\x11.sdk.v1.DeviceRefR\x03ref\x12)\n\x10\x63urrent_password\x18\x02 \x01(\tR\x0f\x63urrentPassword\x12!\n\x0cnew_password\x18\x03 \x01(\tR\x0bnewPassword\"y\n\x10\x46irmwareFileInfo\x12\x1b\n\tfile_path\x18\x01 \x01(\tR\x08\x66ilePath\x12+\n\x11original_filename\x18\x02 \x01(\tR\x10originalFilename\x12\x1b\n\tfile_size\x18\x03 \x01(\x03R\x08\x66ileSize\"r\n\x15UpdateFirmwareRequest\x12#\n\x03ref\x18\x01 \x01(\x0b\x32\x11.sdk.v1.DeviceRefR\x03ref\x12\x34\n\x08\x66irmware\x18\x02 \x01(\x0b\x32\x18.sdk.v1.FirmwareFileInfoR\x08\x66irmware\"\x8a\x01\n\x1fGetFirmwareUpdateStatusResponse\x12\x14\n\x05state\x18\x01 \x01(\tR\x05state\x12\x1f\n\x08progress\x18\x02 \x01(\x05H\x00R\x08progress\x88\x01\x01\x12\x19\n\x05\x65rror\x18\x03 \x01(\tH\x01R\x05\x65rror\x88\x01\x01\x42\x0b\n\t_progressB\x08\n\x06_error\"\xde\x05\n\x0b\x44\x65viceError\x12\x33\n\x0bminer_error\x18\x01 \x01(\x0e\x32\x12.sdk.v1.MinerErrorR\nminerError\x12#\n\rcause_summary\x18\x02 \x01(\tR\x0c\x63\x61useSummary\x12-\n\x12recommended_action\x18\x03 \x01(\tR\x11recommendedAction\x12,\n\x08severity\x18\x04 \x01(\x0e\x32\x10.sdk.v1.SeverityR\x08severity\x12>\n\rfirst_seen_at\x18\x05 \x01(\x0b\x32\x1a.google.protobuf.TimestampR\x0b\x66irstSeenAt\x12<\n\x0clast_seen_at\x18\x06 \x01(\x0b\x32\x1a.google.protobuf.TimestampR\nlastSeenAt\x12\x37\n\tclosed_at\x18\x07 \x01(\x0b\x32\x1a.google.protobuf.TimestampR\x08\x63losedAt\x12V\n\x11vendor_attributes\x18\x08 \x03(\x0b\x32).sdk.v1.DeviceError.VendorAttributesEntryR\x10vendorAttributes\x12\x1b\n\tdevice_id\x18\t \x01(\tR\x08\x64\x65viceId\x12&\n\x0c\x63omponent_id\x18\n \x01(\tH\x00R\x0b\x63omponentId\x88\x01\x01\x12\x16\n\x06impact\x18\x0b \x01(\tR\x06impact\x12\x18\n\x07summary\x18\x0c \x01(\tR\x07summary\x12<\n\x0e\x63omponent_type\x18\r \x01(\x0e\x32\x15.sdk.v1.ComponentTypeR\rcomponentType\x1a\x43\n\x15VendorAttributesEntry\x12\x10\n\x03key\x18\x01 \x01(\tR\x03key\x12\x14\n\x05value\x18\x02 \x01(\tR\x05value:\x02\x38\x01\x42\x0f\n\r_component_id\"X\n\x0c\x44\x65viceErrors\x12\x1b\n\tdevice_id\x18\x01 \x01(\tR\x08\x64\x65viceId\x12+\n\x06\x65rrors\x18\x02 \x03(\x0b\x32\x13.sdk.v1.DeviceErrorR\x06\x65rrors*\xa2\x01\n\x0cHealthStatus\x12\x1d\n\x19HEALTH_STATUS_UNSPECIFIED\x10\x00\x12\x12\n\x0eHEALTH_UNKNOWN\x10\x01\x12\x19\n\x15HEALTH_HEALTHY_ACTIVE\x10\x02\x12\x1b\n\x17HEALTH_HEALTHY_INACTIVE\x10\x03\x12\x12\n\x0eHEALTH_WARNING\x10\x04\x12\x13\n\x0fHEALTH_CRITICAL\x10\x05*\xe9\x01\n\x0f\x43omponentStatus\x12 \n\x1c\x43OMPONENT_STATUS_UNSPECIFIED\x10\x00\x12\x1c\n\x18\x43OMPONENT_STATUS_UNKNOWN\x10\x01\x12\x1c\n\x18\x43OMPONENT_STATUS_HEALTHY\x10\x02\x12\x1c\n\x18\x43OMPONENT_STATUS_WARNING\x10\x03\x12\x1d\n\x19\x43OMPONENT_STATUS_CRITICAL\x10\x04\x12\x1c\n\x18\x43OMPONENT_STATUS_OFFLINE\x10\x05\x12\x1d\n\x19\x43OMPONENT_STATUS_DISABLED\x10\x06*o\n\nMetricKind\x12\x1b\n\x17METRIC_KIND_UNSPECIFIED\x10\x00\x12\x15\n\x11METRIC_KIND_GAUGE\x10\x01\x12\x14\n\x10METRIC_KIND_RATE\x10\x02\x12\x17\n\x13METRIC_KIND_COUNTER\x10\x03*\x84\x01\n\x0b\x43oolingMode\x12\x1c\n\x18\x43OOLING_MODE_UNSPECIFIED\x10\x00\x12\x1b\n\x17\x43OOLING_MODE_AIR_COOLED\x10\x01\x12!\n\x1d\x43OOLING_MODE_IMMERSION_COOLED\x10\x02\x12\x17\n\x13\x43OOLING_MODE_MANUAL\x10\x03*{\n\x0fPerformanceMode\x12 \n\x1cPERFORMANCE_MODE_UNSPECIFIED\x10\x00\x12%\n!PERFORMANCE_MODE_MAXIMUM_HASHRATE\x10\x01\x12\x1f\n\x1bPERFORMANCE_MODE_EFFICIENCY\x10\x02*c\n\x0c\x43urtailLevel\x12\x1d\n\x19\x43URTAIL_LEVEL_UNSPECIFIED\x10\x00\x12\x1c\n\x18\x43URTAIL_LEVEL_EFFICIENCY\x10\x01\x12\x16\n\x12\x43URTAIL_LEVEL_FULL\x10\x02*\x9d\x0b\n\nMinerError\x12\x1b\n\x17MINER_ERROR_UNSPECIFIED\x10\x00\x12\x14\n\x0fPSU_NOT_PRESENT\x10\xe8\x07\x12\x17\n\x12PSU_MODEL_MISMATCH\x10\xe9\x07\x12\x1b\n\x16PSU_COMMUNICATION_LOST\x10\xea\x07\x12\x16\n\x11PSU_FAULT_GENERIC\x10\xeb\x07\x12\x1a\n\x15PSU_INPUT_VOLTAGE_LOW\x10\xec\x07\x12\x1b\n\x16PSU_INPUT_VOLTAGE_HIGH\x10\xed\x07\x12\x1d\n\x18PSU_OUTPUT_VOLTAGE_FAULT\x10\xee\x07\x12\x1b\n\x16PSU_OUTPUT_OVERCURRENT\x10\xef\x07\x12\x12\n\rPSU_FAN_FAULT\x10\xf0\x07\x12\x19\n\x14PSU_OVER_TEMPERATURE\x10\xf1\x07\x12\x1e\n\x19PSU_INPUT_PHASE_IMBALANCE\x10\xf2\x07\x12\x1a\n\x15PSU_UNDER_TEMPERATURE\x10\xf3\x07\x12\x0f\n\nFAN_FAILED\x10\xd0\x0f\x12\x19\n\x14\x46\x41N_TACH_SIGNAL_LOST\x10\xd1\x0f\x12\x18\n\x13\x46\x41N_SPEED_DEVIATION\x10\xd2\x0f\x12\x1b\n\x16INLET_OVER_TEMPERATURE\x10\xda\x0f\x12\x1c\n\x17\x44\x45VICE_OVER_TEMPERATURE\x10\xdb\x0f\x12\x1d\n\x18\x44\x45VICE_UNDER_TEMPERATURE\x10\xdc\x0f\x12\x1a\n\x15HASHBOARD_NOT_PRESENT\x10\xb8\x17\x12\x1f\n\x1aHASHBOARD_OVER_TEMPERATURE\x10\xb9\x17\x12\x1c\n\x17HASHBOARD_MISSING_CHIPS\x10\xba\x17\x12\"\n\x1d\x41SIC_CHAIN_COMMUNICATION_LOST\x10\xbb\x17\x12\x1c\n\x17\x41SIC_CLOCK_PLL_UNLOCKED\x10\xbc\x17\x12\x1d\n\x18\x41SIC_CRC_ERROR_EXCESSIVE\x10\xbd\x17\x12$\n\x1fHASHBOARD_ASIC_OVER_TEMPERATURE\x10\xbe\x17\x12%\n HASHBOARD_ASIC_UNDER_TEMPERATURE\x10\xbf\x17\x12\x1e\n\x19\x42OARD_POWER_PGOOD_MISSING\x10\xac\x1b\x12\x1c\n\x17\x42OARD_POWER_OVERCURRENT\x10\xad\x1b\x12\x1f\n\x1a\x42OARD_POWER_RAIL_UNDERVOLT\x10\xae\x1b\x12\x1e\n\x19\x42OARD_POWER_RAIL_OVERVOLT\x10\xaf\x1b\x12\x1f\n\x1a\x42OARD_POWER_SHORT_DETECTED\x10\xb0\x1b\x12\x1e\n\x19TEMP_SENSOR_OPEN_OR_SHORT\x10\xa0\x1f\x12\x16\n\x11TEMP_SENSOR_FAULT\x10\xa1\x1f\x12\x19\n\x14VOLTAGE_SENSOR_FAULT\x10\xa2\x1f\x12\x19\n\x14\x43URRENT_SENSOR_FAULT\x10\xa3\x1f\x12\x18\n\x13\x45\x45PROM_CRC_MISMATCH\x10\x88\'\x12\x18\n\x13\x45\x45PROM_READ_FAILURE\x10\x89\'\x12\x1b\n\x16\x46IRMWARE_IMAGE_INVALID\x10\x8a\'\x12\x1c\n\x17\x46IRMWARE_CONFIG_INVALID\x10\x8b\'\x12%\n CONTROL_BOARD_COMMUNICATION_LOST\x10\xf0.\x12\x1a\n\x15\x43ONTROL_BOARD_FAILURE\x10\xf1.\x12\x1e\n\x19\x44\x45VICE_INTERNAL_BUS_FAULT\x10\xf2.\x12\x1e\n\x19\x44\x45VICE_COMMUNICATION_LOST\x10\xf3.\x12\x16\n\x11IO_MODULE_FAILURE\x10\xfa.\x12\x1a\n\x15HASHRATE_BELOW_TARGET\x10\xc0>\x12\x1c\n\x17HASHBOARD_WARN_CRC_HIGH\x10\xc1>\x12\x17\n\x12THERMAL_MARGIN_LOW\x10\xc2>\x12\x1a\n\x15VENDOR_ERROR_UNMAPPED\x10\xa8\x46*v\n\x08Severity\x12\x18\n\x14SEVERITY_UNSPECIFIED\x10\x00\x12\x15\n\x11SEVERITY_CRITICAL\x10\x01\x12\x12\n\x0eSEVERITY_MAJOR\x10\x02\x12\x12\n\x0eSEVERITY_MINOR\x10\x03\x12\x11\n\rSEVERITY_INFO\x10\x04*\xd9\x01\n\rComponentType\x12\x1e\n\x1a\x43OMPONENT_TYPE_UNSPECIFIED\x10\x00\x12\x16\n\x12\x43OMPONENT_TYPE_PSU\x10\x01\x12\x1d\n\x19\x43OMPONENT_TYPE_HASH_BOARD\x10\x02\x12\x16\n\x12\x43OMPONENT_TYPE_FAN\x10\x03\x12 \n\x1c\x43OMPONENT_TYPE_CONTROL_BOARD\x10\x04\x12\x19\n\x15\x43OMPONENT_TYPE_EEPROM\x10\x05\x12\x1c\n\x18\x43OMPONENT_TYPE_IO_MODULE\x10\x06\x32\x8c\x12\n\x06\x44river\x12>\n\tHandshake\x12\x16.google.protobuf.Empty\x1a\x19.sdk.v1.HandshakeResponse\x12H\n\x0e\x44\x65scribeDriver\x12\x16.google.protobuf.Empty\x1a\x1e.sdk.v1.DescribeDriverResponse\x12O\n\x0e\x44iscoverDevice\x12\x1d.sdk.v1.DiscoverDeviceRequest\x1a\x1e.sdk.v1.DiscoverDeviceResponse\x12\x43\n\nPairDevice\x12\x19.sdk.v1.PairDeviceRequest\x1a\x1a.sdk.v1.PairDeviceResponse\x12\x64\n\x15GetDefaultCredentials\x12$.sdk.v1.GetDefaultCredentialsRequest\x1a%.sdk.v1.GetDefaultCredentialsResponse\x12j\n\x17GetCapabilitiesForModel\x12&.sdk.v1.GetCapabilitiesForModelRequest\x1a\'.sdk.v1.GetCapabilitiesForModelResponse\x12N\n\x11GetDiscoveryPorts\x12\x16.google.protobuf.Empty\x1a!.sdk.v1.GetDiscoveryPortsResponse\x12@\n\tNewDevice\x12\x18.sdk.v1.NewDeviceRequest\x1a\x19.sdk.v1.NewDeviceResponse\x12O\n\x0e\x44\x65scribeDevice\x12\x1d.sdk.v1.DescribeDeviceRequest\x1a\x1e.sdk.v1.DescribeDeviceResponse\x12\x38\n\x0b\x43loseDevice\x12\x11.sdk.v1.DeviceRef\x1a\x16.google.protobuf.Empty\x12\x38\n\x0bStartMining\x12\x11.sdk.v1.DeviceRef\x1a\x16.google.protobuf.Empty\x12\x37\n\nStopMining\x12\x11.sdk.v1.DeviceRef\x1a\x16.google.protobuf.Empty\x12\x35\n\x08\x42linkLED\x12\x11.sdk.v1.DeviceRef\x1a\x16.google.protobuf.Empty\x12\x33\n\x06Reboot\x12\x11.sdk.v1.DeviceRef\x1a\x16.google.protobuf.Empty\x12G\n\x0eSetCoolingMode\x12\x1d.sdk.v1.SetCoolingModeRequest\x1a\x16.google.protobuf.Empty\x12\x43\n\x0eGetCoolingMode\x12\x11.sdk.v1.DeviceRef\x1a\x1e.sdk.v1.GetCoolingModeResponse\x12G\n\x0eSetPowerTarget\x12\x1d.sdk.v1.SetPowerTargetRequest\x1a\x16.google.protobuf.Empty\x12M\n\x11UpdateMiningPools\x12 .sdk.v1.UpdateMiningPoolsRequest\x1a\x16.google.protobuf.Empty\x12O\n\x0eGetMiningPools\x12\x1d.sdk.v1.GetMiningPoolsRequest\x1a\x1e.sdk.v1.GetMiningPoolsResponse\x12I\n\x0c\x44ownloadLogs\x12\x1b.sdk.v1.DownloadLogsRequest\x1a\x1c.sdk.v1.DownloadLogsResponse\x12G\n\x0eUpdateFirmware\x12\x1d.sdk.v1.UpdateFirmwareRequest\x1a\x16.google.protobuf.Empty\x12U\n\x17GetFirmwareUpdateStatus\x12\x11.sdk.v1.DeviceRef\x1a\'.sdk.v1.GetFirmwareUpdateStatusResponse\x12\x33\n\x06Unpair\x12\x11.sdk.v1.DeviceRef\x1a\x16.google.protobuf.Empty\x12Q\n\x13UpdateMinerPassword\x12\".sdk.v1.UpdateMinerPasswordRequest\x1a\x16.google.protobuf.Empty\x12\x39\n\x07\x43urtail\x12\x16.sdk.v1.CurtailRequest\x1a\x16.google.protobuf.Empty\x12=\n\tUncurtail\x12\x18.sdk.v1.UncurtailRequest\x1a\x16.google.protobuf.Empty\x12\x38\n\x0c\x44\x65viceStatus\x12\x11.sdk.v1.DeviceRef\x1a\x15.sdk.v1.DeviceMetrics\x12X\n\x11GetTimeSeriesData\x12 .sdk.v1.GetTimeSeriesDataRequest\x1a!.sdk.v1.GetTimeSeriesDataResponse\x12^\n\x13GetDeviceWebViewURL\x12\".sdk.v1.GetDeviceWebViewURLRequest\x1a#.sdk.v1.GetDeviceWebViewURLResponse\x12\x46\n\x0b\x42\x61tchStatus\x12\x1a.sdk.v1.BatchStatusRequest\x1a\x1b.sdk.v1.StatusBatchResponse\x12>\n\tSubscribe\x12\x18.sdk.v1.SubscribeRequest\x1a\x15.sdk.v1.DeviceMetrics0\x01\x12\x34\n\tGetErrors\x12\x11.sdk.v1.DeviceRef\x1a\x14.sdk.v1.DeviceErrorsB\x84\x01\n\ncom.sdk.v1B\x0b\x44riverProtoP\x01Z0github.com/block/proto-fleet/server/sdk/v1/pb;pb\xa2\x02\x03SXX\xaa\x02\x06Sdk.V1\xca\x02\x06Sdk\\V1\xe2\x02\x12Sdk\\V1\\GPBMetadata\xea\x02\x07Sdk::V1b\x06proto3') +DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x0fpb/driver.proto\x12\x06sdk.v1\x1a\x1fgoogle/protobuf/timestamp.proto\x1a\x1egoogle/protobuf/duration.proto\x1a\x1bgoogle/protobuf/empty.proto\"\x7f\n\x0c\x43\x61pabilities\x12\x35\n\x05\x66lags\x18\x01 \x03(\x0b\x32\x1f.sdk.v1.Capabilities.FlagsEntryR\x05\x66lags\x1a\x38\n\nFlagsEntry\x12\x10\n\x03key\x18\x01 \x01(\tR\x03key\x12\x14\n\x05value\x18\x02 \x01(\x08R\x05value:\x02\x38\x01\"U\n\x11HandshakeResponse\x12\x1f\n\x0b\x64river_name\x18\x01 \x01(\tR\ndriverName\x12\x1f\n\x0b\x61pi_version\x18\x02 \x01(\tR\napiVersion\"\x84\x01\n\x16\x44\x65scribeDriverResponse\x12\x1f\n\x0b\x64river_name\x18\x01 \x01(\tR\ndriverName\x12\x1f\n\x0b\x61pi_version\x18\x02 \x01(\tR\napiVersion\x12(\n\x04\x63\x61ps\x18\x03 \x01(\x0b\x32\x14.sdk.v1.CapabilitiesR\x04\x63\x61ps\"\x85\x01\n\x10NewDeviceRequest\x12\x1b\n\tdevice_id\x18\x01 \x01(\tR\x08\x64\x65viceId\x12&\n\x04info\x18\x02 \x01(\x0b\x32\x12.sdk.v1.DeviceInfoR\x04info\x12,\n\x06secret\x18\x03 \x01(\x0b\x32\x14.sdk.v1.SecretBundleR\x06secret\"0\n\x11NewDeviceResponse\x12\x1b\n\tdevice_id\x18\x01 \x01(\tR\x08\x64\x65viceId\"(\n\tDeviceRef\x12\x1b\n\tdevice_id\x18\x01 \x01(\tR\x08\x64\x65viceId\"\x96\x01\n\x0bMetricValue\x12\x14\n\x05value\x18\x01 \x01(\x01R\x05value\x12&\n\x04kind\x18\x02 \x01(\x0e\x32\x12.sdk.v1.MetricKindR\x04kind\x12<\n\x08metadata\x18\x03 \x01(\x0b\x32\x1b.sdk.v1.MetricValueMetaDataH\x00R\x08metadata\x88\x01\x01\x42\x0b\n\t_metadata\"\xac\x02\n\x13MetricValueMetaData\x12\x36\n\x06window\x18\x01 \x01(\x0b\x32\x19.google.protobuf.DurationH\x00R\x06window\x88\x01\x01\x12\x15\n\x03min\x18\x02 \x01(\x01H\x01R\x03min\x88\x01\x01\x12\x15\n\x03max\x18\x03 \x01(\x01H\x02R\x03max\x88\x01\x01\x12\x15\n\x03\x61vg\x18\x04 \x01(\x01H\x03R\x03\x61vg\x88\x01\x01\x12\x1c\n\x07std_dev\x18\x05 \x01(\x01H\x04R\x06stdDev\x88\x01\x01\x12=\n\ttimestamp\x18\x06 \x01(\x0b\x32\x1a.google.protobuf.TimestampH\x05R\ttimestamp\x88\x01\x01\x42\t\n\x07_windowB\x06\n\x04_minB\x06\n\x04_maxB\x06\n\x04_avgB\n\n\x08_std_devB\x0c\n\n_timestamp\"\xf3\x01\n\rComponentInfo\x12\x14\n\x05index\x18\x01 \x01(\x05R\x05index\x12\x12\n\x04name\x18\x02 \x01(\tR\x04name\x12/\n\x06status\x18\x03 \x01(\x0e\x32\x17.sdk.v1.ComponentStatusR\x06status\x12(\n\rstatus_reason\x18\x04 \x01(\tH\x00R\x0cstatusReason\x88\x01\x01\x12=\n\ttimestamp\x18\x05 \x01(\x0b\x32\x1a.google.protobuf.TimestampH\x01R\ttimestamp\x88\x01\x01\x42\x10\n\x0e_status_reasonB\x0c\n\n_timestamp\"\x81\x07\n\x10HashBoardMetrics\x12<\n\x0e\x63omponent_info\x18\x01 \x01(\x0b\x32\x15.sdk.v1.ComponentInfoR\rcomponentInfo\x12(\n\rserial_number\x18\x02 \x01(\tH\x00R\x0cserialNumber\x88\x01\x01\x12:\n\x0chash_rate_hs\x18\x03 \x01(\x0b\x32\x13.sdk.v1.MetricValueH\x01R\nhashRateHs\x88\x01\x01\x12/\n\x06temp_c\x18\x04 \x01(\x0b\x32\x13.sdk.v1.MetricValueH\x02R\x05tempC\x88\x01\x01\x12\x35\n\tvoltage_v\x18\x05 \x01(\x0b\x32\x13.sdk.v1.MetricValueH\x03R\x08voltageV\x88\x01\x01\x12\x35\n\tcurrent_a\x18\x06 \x01(\x0b\x32\x13.sdk.v1.MetricValueH\x04R\x08\x63urrentA\x88\x01\x01\x12:\n\x0cinlet_temp_c\x18\x07 \x01(\x0b\x32\x13.sdk.v1.MetricValueH\x05R\ninletTempC\x88\x01\x01\x12<\n\routlet_temp_c\x18\x08 \x01(\x0b\x32\x13.sdk.v1.MetricValueH\x06R\x0boutletTempC\x88\x01\x01\x12>\n\x0e\x61mbient_temp_c\x18\t \x01(\x0b\x32\x13.sdk.v1.MetricValueH\x07R\x0c\x61mbientTempC\x88\x01\x01\x12\"\n\nchip_count\x18\n \x01(\x05H\x08R\tchipCount\x88\x01\x01\x12\x46\n\x12\x63hip_frequency_mhz\x18\x0b \x01(\x0b\x32\x13.sdk.v1.MetricValueH\tR\x10\x63hipFrequencyMhz\x88\x01\x01\x12)\n\x05\x61sics\x18\x0c \x03(\x0b\x32\x13.sdk.v1.ASICMetricsR\x05\x61sics\x12\x33\n\x0b\x66\x61n_metrics\x18\r \x03(\x0b\x32\x12.sdk.v1.FanMetricsR\nfanMetricsB\x10\n\x0e_serial_numberB\x0f\n\r_hash_rate_hsB\t\n\x07_temp_cB\x0c\n\n_voltage_vB\x0c\n\n_current_aB\x0f\n\r_inlet_temp_cB\x10\n\x0e_outlet_temp_cB\x11\n\x0f_ambient_temp_cB\r\n\x0b_chip_countB\x15\n\x13_chip_frequency_mhz\"\xe8\x02\n\x0b\x41SICMetrics\x12<\n\x0e\x63omponent_info\x18\x01 \x01(\x0b\x32\x15.sdk.v1.ComponentInfoR\rcomponentInfo\x12/\n\x06temp_c\x18\x02 \x01(\x0b\x32\x13.sdk.v1.MetricValueH\x00R\x05tempC\x88\x01\x01\x12=\n\rfrequency_mhz\x18\x03 \x01(\x0b\x32\x13.sdk.v1.MetricValueH\x01R\x0c\x66requencyMhz\x88\x01\x01\x12\x35\n\tvoltage_v\x18\x04 \x01(\x0b\x32\x13.sdk.v1.MetricValueH\x02R\x08voltageV\x88\x01\x01\x12\x39\n\x0bhashrate_hs\x18\x05 \x01(\x0b\x32\x13.sdk.v1.MetricValueH\x03R\nhashrateHs\x88\x01\x01\x42\t\n\x07_temp_cB\x10\n\x0e_frequency_mhzB\x0c\n\n_voltage_vB\x0e\n\x0c_hashrate_hs\"\xb3\x06\n\nPSUMetrics\x12<\n\x0e\x63omponent_info\x18\x01 \x01(\x0b\x32\x15.sdk.v1.ComponentInfoR\rcomponentInfo\x12>\n\x0eoutput_power_w\x18\x02 \x01(\x0b\x32\x13.sdk.v1.MetricValueH\x00R\x0coutputPowerW\x88\x01\x01\x12\x42\n\x10output_voltage_v\x18\x03 \x01(\x0b\x32\x13.sdk.v1.MetricValueH\x01R\x0eoutputVoltageV\x88\x01\x01\x12\x42\n\x10output_current_a\x18\x04 \x01(\x0b\x32\x13.sdk.v1.MetricValueH\x02R\x0eoutputCurrentA\x88\x01\x01\x12<\n\rinput_power_w\x18\x05 \x01(\x0b\x32\x13.sdk.v1.MetricValueH\x03R\x0binputPowerW\x88\x01\x01\x12@\n\x0finput_voltage_v\x18\x06 \x01(\x0b\x32\x13.sdk.v1.MetricValueH\x04R\rinputVoltageV\x88\x01\x01\x12@\n\x0finput_current_a\x18\x07 \x01(\x0b\x32\x13.sdk.v1.MetricValueH\x05R\rinputCurrentA\x88\x01\x01\x12>\n\x0ehotspot_temp_c\x18\x08 \x01(\x0b\x32\x13.sdk.v1.MetricValueH\x06R\x0chotspotTempC\x88\x01\x01\x12G\n\x12\x65\x66\x66iciency_percent\x18\t \x01(\x0b\x32\x13.sdk.v1.MetricValueH\x07R\x11\x65\x66\x66iciencyPercent\x88\x01\x01\x12\x33\n\x0b\x66\x61n_metrics\x18\n \x03(\x0b\x32\x12.sdk.v1.FanMetricsR\nfanMetricsB\x11\n\x0f_output_power_wB\x13\n\x11_output_voltage_vB\x13\n\x11_output_current_aB\x10\n\x0e_input_power_wB\x12\n\x10_input_voltage_vB\x12\n\x10_input_current_aB\x11\n\x0f_hotspot_temp_cB\x15\n\x13_efficiency_percent\"\xfa\x01\n\nFanMetrics\x12<\n\x0e\x63omponent_info\x18\x01 \x01(\x0b\x32\x15.sdk.v1.ComponentInfoR\rcomponentInfo\x12*\n\x03rpm\x18\x02 \x01(\x0b\x32\x13.sdk.v1.MetricValueH\x00R\x03rpm\x88\x01\x01\x12/\n\x06temp_c\x18\x03 \x01(\x0b\x32\x13.sdk.v1.MetricValueH\x01R\x05tempC\x88\x01\x01\x12\x32\n\x07percent\x18\x04 \x01(\x0b\x32\x13.sdk.v1.MetricValueH\x02R\x07percent\x88\x01\x01\x42\x06\n\x04_rpmB\t\n\x07_temp_cB\n\n\x08_percent\"S\n\x13\x43ontrolBoardMetrics\x12<\n\x0e\x63omponent_info\x18\x01 \x01(\x0b\x32\x15.sdk.v1.ComponentInfoR\rcomponentInfo\"\xcb\x01\n\rSensorMetrics\x12<\n\x0e\x63omponent_info\x18\x01 \x01(\x0b\x32\x15.sdk.v1.ComponentInfoR\rcomponentInfo\x12\x17\n\x04type\x18\x02 \x01(\tH\x00R\x04type\x88\x01\x01\x12\x17\n\x04unit\x18\x03 \x01(\tH\x01R\x04unit\x88\x01\x01\x12.\n\x05value\x18\x04 \x01(\x0b\x32\x13.sdk.v1.MetricValueH\x02R\x05value\x88\x01\x01\x42\x07\n\x05_typeB\x07\n\x05_unitB\x08\n\x06_value\"\xf8\x07\n\rDeviceMetrics\x12\x1b\n\tdevice_id\x18\x01 \x01(\tR\x08\x64\x65viceId\x12\x38\n\ttimestamp\x18\x02 \x01(\x0b\x32\x1a.google.protobuf.TimestampR\ttimestamp\x12,\n\x06health\x18\x03 \x01(\x0e\x32\x14.sdk.v1.HealthStatusR\x06health\x12(\n\rhealth_reason\x18\x04 \x01(\tH\x00R\x0chealthReason\x88\x01\x01\x12\x39\n\x0bhashrate_hs\x18\x05 \x01(\x0b\x32\x13.sdk.v1.MetricValueH\x01R\nhashrateHs\x88\x01\x01\x12/\n\x06temp_c\x18\x06 \x01(\x0b\x32\x13.sdk.v1.MetricValueH\x02R\x05tempC\x88\x01\x01\x12\x31\n\x07\x66\x61n_rpm\x18\x07 \x01(\x0b\x32\x13.sdk.v1.MetricValueH\x03R\x06\x66\x61nRpm\x88\x01\x01\x12\x31\n\x07power_w\x18\x08 \x01(\x0b\x32\x13.sdk.v1.MetricValueH\x04R\x06powerW\x88\x01\x01\x12=\n\refficiency_jh\x18\t \x01(\x0b\x32\x13.sdk.v1.MetricValueH\x05R\x0c\x65\x66\x66iciencyJh\x88\x01\x01\x12\x39\n\x0bhash_boards\x18\n \x03(\x0b\x32\x18.sdk.v1.HashBoardMetricsR\nhashBoards\x12\x33\n\x0bpsu_metrics\x18\x0b \x03(\x0b\x32\x12.sdk.v1.PSUMetricsR\npsuMetrics\x12O\n\x15\x63ontrol_board_metrics\x18\x0c \x03(\x0b\x32\x1b.sdk.v1.ControlBoardMetricsR\x13\x63ontrolBoardMetrics\x12\x33\n\x0b\x66\x61n_metrics\x18\r \x03(\x0b\x32\x12.sdk.v1.FanMetricsR\nfanMetrics\x12<\n\x0esensor_metrics\x18\x0e \x03(\x0b\x32\x15.sdk.v1.SensorMetricsR\rsensorMetrics\x12)\n\x10\x66irmware_version\x18\x0f \x01(\tR\x0f\x66irmwareVersion\x12;\n\x17\x64\x65\x66\x61ult_password_active\x18\x11 \x01(\x08H\x06R\x15\x64\x65\x66\x61ultPasswordActive\x88\x01\x01\x42\x10\n\x0e_health_reasonB\x0e\n\x0c_hashrate_hsB\t\n\x07_temp_cB\n\n\x08_fan_rpmB\n\n\x08_power_wB\x10\n\x0e_efficiency_jhB\x1a\n\x18_default_password_activeJ\x04\x08\x10\x10\x11R\x12stratum_v2_support\"4\n\x15\x44\x65scribeDeviceRequest\x12\x1b\n\tdevice_id\x18\x01 \x01(\tR\x08\x64\x65viceId\"n\n\x16\x44\x65scribeDeviceResponse\x12*\n\x06\x64\x65vice\x18\x01 \x01(\x0b\x32\x12.sdk.v1.DeviceInfoR\x06\x64\x65vice\x12(\n\x04\x63\x61ps\x18\x02 \x01(\x0b\x32\x14.sdk.v1.CapabilitiesR\x04\x63\x61ps\"B\n\x13StatusBatchResponse\x12+\n\x05items\x18\x01 \x03(\x0b\x32\x15.sdk.v1.DeviceMetricsR\x05items\";\n\x12\x42\x61tchStatusRequest\x12%\n\x04refs\x18\x01 \x03(\x0b\x32\x11.sdk.v1.DeviceRefR\x04refs\"\xa9\x01\n\x10SubscribeRequest\x12\x1d\n\ndevice_ids\x18\x01 \x03(\tR\tdeviceIds\x12\"\n\nbatch_size\x18\x02 \x01(\x05H\x00R\tbatchSize\x88\x01\x01\x12.\n\x10interval_seconds\x18\x03 \x01(\x05H\x01R\x0fintervalSeconds\x88\x01\x01\x42\r\n\x0b_batch_sizeB\x13\n\x11_interval_seconds\"J\n\x10UsernamePassword\x12\x1a\n\x08username\x18\x01 \x01(\tR\x08username\x12\x1a\n\x08password\x18\x02 \x01(\tR\x08password\"#\n\x0b\x42\x65\x61rerToken\x12\x14\n\x05token\x18\x01 \x01(\tR\x05token\"p\n\rTlsClientCert\x12&\n\x0f\x63lient_cert_pem\x18\x01 \x01(\x0cR\rclientCertPem\x12\x17\n\x07key_pem\x18\x02 \x01(\x0cR\x06keyPem\x12\x1e\n\x0b\x63\x61_cert_pem\x18\x03 \x01(\x0cR\tcaCertPem\"\xa0\x02\n\x0cSecretBundle\x12\x18\n\x07version\x18\x01 \x01(\tR\x07version\x12\x37\n\tuser_pass\x18\x03 \x01(\x0b\x32\x18.sdk.v1.UsernamePasswordH\x00R\x08userPass\x12\x38\n\x0c\x62\x65\x61rer_token\x18\x04 \x01(\x0b\x32\x13.sdk.v1.BearerTokenH\x00R\x0b\x62\x65\x61rerToken\x12?\n\x0ftls_client_cert\x18\x05 \x01(\x0b\x32\x15.sdk.v1.TlsClientCertH\x00R\rtlsClientCert\x12+\n\x03ttl\x18\x06 \x01(\x0b\x32\x19.google.protobuf.DurationR\x03ttlB\x06\n\x04kindJ\x04\x08\x02\x10\x03R\x07\x61pi_key\"e\n\x15SetCoolingModeRequest\x12#\n\x03ref\x18\x01 \x01(\x0b\x32\x11.sdk.v1.DeviceRefR\x03ref\x12\'\n\x04mode\x18\x02 \x01(\x0e\x32\x13.sdk.v1.CoolingModeR\x04mode\"A\n\x16GetCoolingModeResponse\x12\'\n\x04mode\x18\x01 \x01(\x0e\x32\x13.sdk.v1.CoolingModeR\x04mode\"a\n\x0e\x43urtailRequest\x12#\n\x03ref\x18\x01 \x01(\x0b\x32\x11.sdk.v1.DeviceRefR\x03ref\x12*\n\x05level\x18\x02 \x01(\x0e\x32\x14.sdk.v1.CurtailLevelR\x05level\"7\n\x10UncurtailRequest\x12#\n\x03ref\x18\x01 \x01(\x0b\x32\x11.sdk.v1.DeviceRefR\x03ref\"\x80\x01\n\x15SetPowerTargetRequest\x12#\n\x03ref\x18\x01 \x01(\x0b\x32\x11.sdk.v1.DeviceRefR\x03ref\x12\x42\n\x10performance_mode\x18\x02 \x01(\x0e\x32\x17.sdk.v1.PerformanceModeR\x0fperformanceMode\"[\n\nMiningPool\x12\x1a\n\x08priority\x18\x01 \x01(\x05R\x08priority\x12\x10\n\x03url\x18\x02 \x01(\tR\x03url\x12\x1f\n\x0bworker_name\x18\x03 \x01(\tR\nworkerName\"i\n\x18UpdateMiningPoolsRequest\x12#\n\x03ref\x18\x01 \x01(\x0b\x32\x11.sdk.v1.DeviceRefR\x03ref\x12(\n\x05pools\x18\x02 \x03(\x0b\x32\x12.sdk.v1.MiningPoolR\x05pools\"Z\n\x0e\x43onfiguredPool\x12\x1a\n\x08priority\x18\x01 \x01(\x05R\x08priority\x12\x10\n\x03url\x18\x02 \x01(\tR\x03url\x12\x1a\n\x08username\x18\x03 \x01(\tR\x08username\"<\n\x15GetMiningPoolsRequest\x12#\n\x03ref\x18\x01 \x01(\x0b\x32\x11.sdk.v1.DeviceRefR\x03ref\"F\n\x16GetMiningPoolsResponse\x12,\n\x05pools\x18\x01 \x03(\x0b\x32\x16.sdk.v1.ConfiguredPoolR\x05pools\"\x92\x01\n\x13\x44ownloadLogsRequest\x12#\n\x03ref\x18\x01 \x01(\x0b\x32\x11.sdk.v1.DeviceRefR\x03ref\x12\x30\n\x05since\x18\x02 \x01(\x0b\x32\x1a.google.protobuf.TimestampR\x05since\x12$\n\x0e\x62\x61tch_log_uuid\x18\x03 \x01(\tR\x0c\x62\x61tchLogUuid\"N\n\x14\x44ownloadLogsResponse\x12\x19\n\x08log_data\x18\x01 \x01(\tR\x07logData\x12\x1b\n\tmore_data\x18\x02 \x01(\x08R\x08moreData\"\xe3\x02\n\nDeviceInfo\x12\x12\n\x04host\x18\x01 \x01(\tR\x04host\x12\x12\n\x04port\x18\x02 \x01(\x05R\x04port\x12\x1d\n\nurl_scheme\x18\x03 \x01(\tR\turlScheme\x12#\n\rserial_number\x18\x04 \x01(\tR\x0cserialNumber\x12\x14\n\x05model\x18\x05 \x01(\tR\x05model\x12\"\n\x0cmanufacturer\x18\x06 \x01(\tR\x0cmanufacturer\x12\x1f\n\x0bmac_address\x18\x08 \x01(\tR\nmacAddress\x12)\n\x10\x66irmware_version\x18\t \x01(\tR\x0f\x66irmwareVersion\x12;\n\x17\x64\x65\x66\x61ult_password_active\x18\n \x01(\x08H\x00R\x15\x64\x65\x66\x61ultPasswordActive\x88\x01\x01\x42\x1a\n\x18_default_password_activeJ\x04\x08\x07\x10\x08R\x04type\"J\n\x15\x44iscoverDeviceRequest\x12\x1d\n\nip_address\x18\x01 \x01(\tR\tipAddress\x12\x12\n\x04port\x18\x02 \x01(\tR\x04port\"D\n\x16\x44iscoverDeviceResponse\x12*\n\x06\x64\x65vice\x18\x01 \x01(\x0b\x32\x12.sdk.v1.DeviceInfoR\x06\x64\x65vice\"m\n\x11PairDeviceRequest\x12*\n\x06\x64\x65vice\x18\x01 \x01(\x0b\x32\x12.sdk.v1.DeviceInfoR\x06\x64\x65vice\x12,\n\x06\x61\x63\x63\x65ss\x18\x02 \x01(\x0b\x32\x14.sdk.v1.SecretBundleR\x06\x61\x63\x63\x65ss\"@\n\x12PairDeviceResponse\x12*\n\x06\x64\x65vice\x18\x01 \x01(\x0b\x32\x12.sdk.v1.DeviceInfoR\x06\x64\x65vice\"m\n\x1cGetDefaultCredentialsRequest\x12\"\n\x0cmanufacturer\x18\x01 \x01(\tR\x0cmanufacturer\x12)\n\x10\x66irmware_version\x18\x02 \x01(\tR\x0f\x66irmwareVersion\"[\n\x1dGetDefaultCredentialsResponse\x12:\n\x0b\x63redentials\x18\x01 \x03(\x0b\x32\x18.sdk.v1.UsernamePasswordR\x0b\x63redentials\"Z\n\x1eGetCapabilitiesForModelRequest\x12\x14\n\x05model\x18\x01 \x01(\tR\x05model\x12\"\n\x0cmanufacturer\x18\x02 \x01(\tR\x0cmanufacturer\"K\n\x1fGetCapabilitiesForModelResponse\x12(\n\x04\x63\x61ps\x18\x01 \x01(\x0b\x32\x14.sdk.v1.CapabilitiesR\x04\x63\x61ps\"1\n\x19GetDiscoveryPortsResponse\x12\x14\n\x05ports\x18\x01 \x03(\tR\x05ports\"/\n\x1bGetDeviceWebViewURLResponse\x12\x10\n\x03url\x18\x01 \x01(\tR\x03url\"A\n\x1aGetDeviceWebViewURLRequest\x12#\n\x03ref\x18\x01 \x01(\x0b\x32\x11.sdk.v1.DeviceRefR\x03ref\"\xcf\x02\n\x18GetTimeSeriesDataRequest\x12#\n\x03ref\x18\x01 \x01(\x0b\x32\x11.sdk.v1.DeviceRefR\x03ref\x12!\n\x0cmetric_names\x18\x02 \x03(\tR\x0bmetricNames\x12\x39\n\nstart_time\x18\x03 \x01(\x0b\x32\x1a.google.protobuf.TimestampR\tstartTime\x12\x35\n\x08\x65nd_time\x18\x04 \x01(\x0b\x32\x1a.google.protobuf.TimestampR\x07\x65ndTime\x12;\n\x0bgranularity\x18\x05 \x01(\x0b\x32\x19.google.protobuf.DurationR\x0bgranularity\x12\x1d\n\nmax_points\x18\x06 \x01(\x05R\tmaxPoints\x12\x1d\n\npage_token\x18\x07 \x01(\tR\tpageToken\"r\n\x19GetTimeSeriesDataResponse\x12-\n\x06series\x18\x01 \x03(\x0b\x32\x15.sdk.v1.DeviceMetricsR\x06series\x12&\n\x0fnext_page_token\x18\x02 \x01(\tR\rnextPageToken\"\x8f\x01\n\x1aUpdateMinerPasswordRequest\x12#\n\x03ref\x18\x01 \x01(\x0b\x32\x11.sdk.v1.DeviceRefR\x03ref\x12)\n\x10\x63urrent_password\x18\x02 \x01(\tR\x0f\x63urrentPassword\x12!\n\x0cnew_password\x18\x03 \x01(\tR\x0bnewPassword\"\xa1\x01\n\x10\x46irmwareFileInfo\x12\x1b\n\tfile_path\x18\x01 \x01(\tR\x08\x66ilePath\x12+\n\x11original_filename\x18\x02 \x01(\tR\x10originalFilename\x12\x1b\n\tfile_size\x18\x03 \x01(\x03R\x08\x66ileSize\x12\x0e\n\x02id\x18\x04 \x01(\tR\x02id\x12\x16\n\x06sha256\x18\x05 \x01(\tR\x06sha256\"r\n\x15UpdateFirmwareRequest\x12#\n\x03ref\x18\x01 \x01(\x0b\x32\x11.sdk.v1.DeviceRefR\x03ref\x12\x34\n\x08\x66irmware\x18\x02 \x01(\x0b\x32\x18.sdk.v1.FirmwareFileInfoR\x08\x66irmware\"\x8a\x01\n\x1fGetFirmwareUpdateStatusResponse\x12\x14\n\x05state\x18\x01 \x01(\tR\x05state\x12\x1f\n\x08progress\x18\x02 \x01(\x05H\x00R\x08progress\x88\x01\x01\x12\x19\n\x05\x65rror\x18\x03 \x01(\tH\x01R\x05\x65rror\x88\x01\x01\x42\x0b\n\t_progressB\x08\n\x06_error\"\xde\x05\n\x0b\x44\x65viceError\x12\x33\n\x0bminer_error\x18\x01 \x01(\x0e\x32\x12.sdk.v1.MinerErrorR\nminerError\x12#\n\rcause_summary\x18\x02 \x01(\tR\x0c\x63\x61useSummary\x12-\n\x12recommended_action\x18\x03 \x01(\tR\x11recommendedAction\x12,\n\x08severity\x18\x04 \x01(\x0e\x32\x10.sdk.v1.SeverityR\x08severity\x12>\n\rfirst_seen_at\x18\x05 \x01(\x0b\x32\x1a.google.protobuf.TimestampR\x0b\x66irstSeenAt\x12<\n\x0clast_seen_at\x18\x06 \x01(\x0b\x32\x1a.google.protobuf.TimestampR\nlastSeenAt\x12\x37\n\tclosed_at\x18\x07 \x01(\x0b\x32\x1a.google.protobuf.TimestampR\x08\x63losedAt\x12V\n\x11vendor_attributes\x18\x08 \x03(\x0b\x32).sdk.v1.DeviceError.VendorAttributesEntryR\x10vendorAttributes\x12\x1b\n\tdevice_id\x18\t \x01(\tR\x08\x64\x65viceId\x12&\n\x0c\x63omponent_id\x18\n \x01(\tH\x00R\x0b\x63omponentId\x88\x01\x01\x12\x16\n\x06impact\x18\x0b \x01(\tR\x06impact\x12\x18\n\x07summary\x18\x0c \x01(\tR\x07summary\x12<\n\x0e\x63omponent_type\x18\r \x01(\x0e\x32\x15.sdk.v1.ComponentTypeR\rcomponentType\x1a\x43\n\x15VendorAttributesEntry\x12\x10\n\x03key\x18\x01 \x01(\tR\x03key\x12\x14\n\x05value\x18\x02 \x01(\tR\x05value:\x02\x38\x01\x42\x0f\n\r_component_id\"X\n\x0c\x44\x65viceErrors\x12\x1b\n\tdevice_id\x18\x01 \x01(\tR\x08\x64\x65viceId\x12+\n\x06\x65rrors\x18\x02 \x03(\x0b\x32\x13.sdk.v1.DeviceErrorR\x06\x65rrors*\xa2\x01\n\x0cHealthStatus\x12\x1d\n\x19HEALTH_STATUS_UNSPECIFIED\x10\x00\x12\x12\n\x0eHEALTH_UNKNOWN\x10\x01\x12\x19\n\x15HEALTH_HEALTHY_ACTIVE\x10\x02\x12\x1b\n\x17HEALTH_HEALTHY_INACTIVE\x10\x03\x12\x12\n\x0eHEALTH_WARNING\x10\x04\x12\x13\n\x0fHEALTH_CRITICAL\x10\x05*\xe9\x01\n\x0f\x43omponentStatus\x12 \n\x1c\x43OMPONENT_STATUS_UNSPECIFIED\x10\x00\x12\x1c\n\x18\x43OMPONENT_STATUS_UNKNOWN\x10\x01\x12\x1c\n\x18\x43OMPONENT_STATUS_HEALTHY\x10\x02\x12\x1c\n\x18\x43OMPONENT_STATUS_WARNING\x10\x03\x12\x1d\n\x19\x43OMPONENT_STATUS_CRITICAL\x10\x04\x12\x1c\n\x18\x43OMPONENT_STATUS_OFFLINE\x10\x05\x12\x1d\n\x19\x43OMPONENT_STATUS_DISABLED\x10\x06*o\n\nMetricKind\x12\x1b\n\x17METRIC_KIND_UNSPECIFIED\x10\x00\x12\x15\n\x11METRIC_KIND_GAUGE\x10\x01\x12\x14\n\x10METRIC_KIND_RATE\x10\x02\x12\x17\n\x13METRIC_KIND_COUNTER\x10\x03*\x84\x01\n\x0b\x43oolingMode\x12\x1c\n\x18\x43OOLING_MODE_UNSPECIFIED\x10\x00\x12\x1b\n\x17\x43OOLING_MODE_AIR_COOLED\x10\x01\x12!\n\x1d\x43OOLING_MODE_IMMERSION_COOLED\x10\x02\x12\x17\n\x13\x43OOLING_MODE_MANUAL\x10\x03*{\n\x0fPerformanceMode\x12 \n\x1cPERFORMANCE_MODE_UNSPECIFIED\x10\x00\x12%\n!PERFORMANCE_MODE_MAXIMUM_HASHRATE\x10\x01\x12\x1f\n\x1bPERFORMANCE_MODE_EFFICIENCY\x10\x02*c\n\x0c\x43urtailLevel\x12\x1d\n\x19\x43URTAIL_LEVEL_UNSPECIFIED\x10\x00\x12\x1c\n\x18\x43URTAIL_LEVEL_EFFICIENCY\x10\x01\x12\x16\n\x12\x43URTAIL_LEVEL_FULL\x10\x02*\x9d\x0b\n\nMinerError\x12\x1b\n\x17MINER_ERROR_UNSPECIFIED\x10\x00\x12\x14\n\x0fPSU_NOT_PRESENT\x10\xe8\x07\x12\x17\n\x12PSU_MODEL_MISMATCH\x10\xe9\x07\x12\x1b\n\x16PSU_COMMUNICATION_LOST\x10\xea\x07\x12\x16\n\x11PSU_FAULT_GENERIC\x10\xeb\x07\x12\x1a\n\x15PSU_INPUT_VOLTAGE_LOW\x10\xec\x07\x12\x1b\n\x16PSU_INPUT_VOLTAGE_HIGH\x10\xed\x07\x12\x1d\n\x18PSU_OUTPUT_VOLTAGE_FAULT\x10\xee\x07\x12\x1b\n\x16PSU_OUTPUT_OVERCURRENT\x10\xef\x07\x12\x12\n\rPSU_FAN_FAULT\x10\xf0\x07\x12\x19\n\x14PSU_OVER_TEMPERATURE\x10\xf1\x07\x12\x1e\n\x19PSU_INPUT_PHASE_IMBALANCE\x10\xf2\x07\x12\x1a\n\x15PSU_UNDER_TEMPERATURE\x10\xf3\x07\x12\x0f\n\nFAN_FAILED\x10\xd0\x0f\x12\x19\n\x14\x46\x41N_TACH_SIGNAL_LOST\x10\xd1\x0f\x12\x18\n\x13\x46\x41N_SPEED_DEVIATION\x10\xd2\x0f\x12\x1b\n\x16INLET_OVER_TEMPERATURE\x10\xda\x0f\x12\x1c\n\x17\x44\x45VICE_OVER_TEMPERATURE\x10\xdb\x0f\x12\x1d\n\x18\x44\x45VICE_UNDER_TEMPERATURE\x10\xdc\x0f\x12\x1a\n\x15HASHBOARD_NOT_PRESENT\x10\xb8\x17\x12\x1f\n\x1aHASHBOARD_OVER_TEMPERATURE\x10\xb9\x17\x12\x1c\n\x17HASHBOARD_MISSING_CHIPS\x10\xba\x17\x12\"\n\x1d\x41SIC_CHAIN_COMMUNICATION_LOST\x10\xbb\x17\x12\x1c\n\x17\x41SIC_CLOCK_PLL_UNLOCKED\x10\xbc\x17\x12\x1d\n\x18\x41SIC_CRC_ERROR_EXCESSIVE\x10\xbd\x17\x12$\n\x1fHASHBOARD_ASIC_OVER_TEMPERATURE\x10\xbe\x17\x12%\n HASHBOARD_ASIC_UNDER_TEMPERATURE\x10\xbf\x17\x12\x1e\n\x19\x42OARD_POWER_PGOOD_MISSING\x10\xac\x1b\x12\x1c\n\x17\x42OARD_POWER_OVERCURRENT\x10\xad\x1b\x12\x1f\n\x1a\x42OARD_POWER_RAIL_UNDERVOLT\x10\xae\x1b\x12\x1e\n\x19\x42OARD_POWER_RAIL_OVERVOLT\x10\xaf\x1b\x12\x1f\n\x1a\x42OARD_POWER_SHORT_DETECTED\x10\xb0\x1b\x12\x1e\n\x19TEMP_SENSOR_OPEN_OR_SHORT\x10\xa0\x1f\x12\x16\n\x11TEMP_SENSOR_FAULT\x10\xa1\x1f\x12\x19\n\x14VOLTAGE_SENSOR_FAULT\x10\xa2\x1f\x12\x19\n\x14\x43URRENT_SENSOR_FAULT\x10\xa3\x1f\x12\x18\n\x13\x45\x45PROM_CRC_MISMATCH\x10\x88\'\x12\x18\n\x13\x45\x45PROM_READ_FAILURE\x10\x89\'\x12\x1b\n\x16\x46IRMWARE_IMAGE_INVALID\x10\x8a\'\x12\x1c\n\x17\x46IRMWARE_CONFIG_INVALID\x10\x8b\'\x12%\n CONTROL_BOARD_COMMUNICATION_LOST\x10\xf0.\x12\x1a\n\x15\x43ONTROL_BOARD_FAILURE\x10\xf1.\x12\x1e\n\x19\x44\x45VICE_INTERNAL_BUS_FAULT\x10\xf2.\x12\x1e\n\x19\x44\x45VICE_COMMUNICATION_LOST\x10\xf3.\x12\x16\n\x11IO_MODULE_FAILURE\x10\xfa.\x12\x1a\n\x15HASHRATE_BELOW_TARGET\x10\xc0>\x12\x1c\n\x17HASHBOARD_WARN_CRC_HIGH\x10\xc1>\x12\x17\n\x12THERMAL_MARGIN_LOW\x10\xc2>\x12\x1a\n\x15VENDOR_ERROR_UNMAPPED\x10\xa8\x46*v\n\x08Severity\x12\x18\n\x14SEVERITY_UNSPECIFIED\x10\x00\x12\x15\n\x11SEVERITY_CRITICAL\x10\x01\x12\x12\n\x0eSEVERITY_MAJOR\x10\x02\x12\x12\n\x0eSEVERITY_MINOR\x10\x03\x12\x11\n\rSEVERITY_INFO\x10\x04*\xd9\x01\n\rComponentType\x12\x1e\n\x1a\x43OMPONENT_TYPE_UNSPECIFIED\x10\x00\x12\x16\n\x12\x43OMPONENT_TYPE_PSU\x10\x01\x12\x1d\n\x19\x43OMPONENT_TYPE_HASH_BOARD\x10\x02\x12\x16\n\x12\x43OMPONENT_TYPE_FAN\x10\x03\x12 \n\x1c\x43OMPONENT_TYPE_CONTROL_BOARD\x10\x04\x12\x19\n\x15\x43OMPONENT_TYPE_EEPROM\x10\x05\x12\x1c\n\x18\x43OMPONENT_TYPE_IO_MODULE\x10\x06\x32\x8c\x12\n\x06\x44river\x12>\n\tHandshake\x12\x16.google.protobuf.Empty\x1a\x19.sdk.v1.HandshakeResponse\x12H\n\x0e\x44\x65scribeDriver\x12\x16.google.protobuf.Empty\x1a\x1e.sdk.v1.DescribeDriverResponse\x12O\n\x0e\x44iscoverDevice\x12\x1d.sdk.v1.DiscoverDeviceRequest\x1a\x1e.sdk.v1.DiscoverDeviceResponse\x12\x43\n\nPairDevice\x12\x19.sdk.v1.PairDeviceRequest\x1a\x1a.sdk.v1.PairDeviceResponse\x12\x64\n\x15GetDefaultCredentials\x12$.sdk.v1.GetDefaultCredentialsRequest\x1a%.sdk.v1.GetDefaultCredentialsResponse\x12j\n\x17GetCapabilitiesForModel\x12&.sdk.v1.GetCapabilitiesForModelRequest\x1a\'.sdk.v1.GetCapabilitiesForModelResponse\x12N\n\x11GetDiscoveryPorts\x12\x16.google.protobuf.Empty\x1a!.sdk.v1.GetDiscoveryPortsResponse\x12@\n\tNewDevice\x12\x18.sdk.v1.NewDeviceRequest\x1a\x19.sdk.v1.NewDeviceResponse\x12O\n\x0e\x44\x65scribeDevice\x12\x1d.sdk.v1.DescribeDeviceRequest\x1a\x1e.sdk.v1.DescribeDeviceResponse\x12\x38\n\x0b\x43loseDevice\x12\x11.sdk.v1.DeviceRef\x1a\x16.google.protobuf.Empty\x12\x38\n\x0bStartMining\x12\x11.sdk.v1.DeviceRef\x1a\x16.google.protobuf.Empty\x12\x37\n\nStopMining\x12\x11.sdk.v1.DeviceRef\x1a\x16.google.protobuf.Empty\x12\x35\n\x08\x42linkLED\x12\x11.sdk.v1.DeviceRef\x1a\x16.google.protobuf.Empty\x12\x33\n\x06Reboot\x12\x11.sdk.v1.DeviceRef\x1a\x16.google.protobuf.Empty\x12G\n\x0eSetCoolingMode\x12\x1d.sdk.v1.SetCoolingModeRequest\x1a\x16.google.protobuf.Empty\x12\x43\n\x0eGetCoolingMode\x12\x11.sdk.v1.DeviceRef\x1a\x1e.sdk.v1.GetCoolingModeResponse\x12G\n\x0eSetPowerTarget\x12\x1d.sdk.v1.SetPowerTargetRequest\x1a\x16.google.protobuf.Empty\x12M\n\x11UpdateMiningPools\x12 .sdk.v1.UpdateMiningPoolsRequest\x1a\x16.google.protobuf.Empty\x12O\n\x0eGetMiningPools\x12\x1d.sdk.v1.GetMiningPoolsRequest\x1a\x1e.sdk.v1.GetMiningPoolsResponse\x12I\n\x0c\x44ownloadLogs\x12\x1b.sdk.v1.DownloadLogsRequest\x1a\x1c.sdk.v1.DownloadLogsResponse\x12G\n\x0eUpdateFirmware\x12\x1d.sdk.v1.UpdateFirmwareRequest\x1a\x16.google.protobuf.Empty\x12U\n\x17GetFirmwareUpdateStatus\x12\x11.sdk.v1.DeviceRef\x1a\'.sdk.v1.GetFirmwareUpdateStatusResponse\x12\x33\n\x06Unpair\x12\x11.sdk.v1.DeviceRef\x1a\x16.google.protobuf.Empty\x12Q\n\x13UpdateMinerPassword\x12\".sdk.v1.UpdateMinerPasswordRequest\x1a\x16.google.protobuf.Empty\x12\x39\n\x07\x43urtail\x12\x16.sdk.v1.CurtailRequest\x1a\x16.google.protobuf.Empty\x12=\n\tUncurtail\x12\x18.sdk.v1.UncurtailRequest\x1a\x16.google.protobuf.Empty\x12\x38\n\x0c\x44\x65viceStatus\x12\x11.sdk.v1.DeviceRef\x1a\x15.sdk.v1.DeviceMetrics\x12X\n\x11GetTimeSeriesData\x12 .sdk.v1.GetTimeSeriesDataRequest\x1a!.sdk.v1.GetTimeSeriesDataResponse\x12^\n\x13GetDeviceWebViewURL\x12\".sdk.v1.GetDeviceWebViewURLRequest\x1a#.sdk.v1.GetDeviceWebViewURLResponse\x12\x46\n\x0b\x42\x61tchStatus\x12\x1a.sdk.v1.BatchStatusRequest\x1a\x1b.sdk.v1.StatusBatchResponse\x12>\n\tSubscribe\x12\x18.sdk.v1.SubscribeRequest\x1a\x15.sdk.v1.DeviceMetrics0\x01\x12\x34\n\tGetErrors\x12\x11.sdk.v1.DeviceRef\x1a\x14.sdk.v1.DeviceErrorsB\x84\x01\n\ncom.sdk.v1B\x0b\x44riverProtoP\x01Z0github.com/block/proto-fleet/server/sdk/v1/pb;pb\xa2\x02\x03SXX\xaa\x02\x06Sdk.V1\xca\x02\x06Sdk\\V1\xe2\x02\x12Sdk\\V1\\GPBMetadata\xea\x02\x07Sdk::V1b\x06proto3') _globals = globals() _builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) @@ -39,24 +39,24 @@ _globals['_CAPABILITIES_FLAGSENTRY']._serialized_options = b'8\001' _globals['_DEVICEERROR_VENDORATTRIBUTESENTRY']._loaded_options = None _globals['_DEVICEERROR_VENDORATTRIBUTESENTRY']._serialized_options = b'8\001' - _globals['_HEALTHSTATUS']._serialized_start=10176 - _globals['_HEALTHSTATUS']._serialized_end=10338 - _globals['_COMPONENTSTATUS']._serialized_start=10341 - _globals['_COMPONENTSTATUS']._serialized_end=10574 - _globals['_METRICKIND']._serialized_start=10576 - _globals['_METRICKIND']._serialized_end=10687 - _globals['_COOLINGMODE']._serialized_start=10690 - _globals['_COOLINGMODE']._serialized_end=10822 - _globals['_PERFORMANCEMODE']._serialized_start=10824 - _globals['_PERFORMANCEMODE']._serialized_end=10947 - _globals['_CURTAILLEVEL']._serialized_start=10949 - _globals['_CURTAILLEVEL']._serialized_end=11048 - _globals['_MINERERROR']._serialized_start=11051 - _globals['_MINERERROR']._serialized_end=12488 - _globals['_SEVERITY']._serialized_start=12490 - _globals['_SEVERITY']._serialized_end=12608 - _globals['_COMPONENTTYPE']._serialized_start=12611 - _globals['_COMPONENTTYPE']._serialized_end=12828 + _globals['_HEALTHSTATUS']._serialized_start=10217 + _globals['_HEALTHSTATUS']._serialized_end=10379 + _globals['_COMPONENTSTATUS']._serialized_start=10382 + _globals['_COMPONENTSTATUS']._serialized_end=10615 + _globals['_METRICKIND']._serialized_start=10617 + _globals['_METRICKIND']._serialized_end=10728 + _globals['_COOLINGMODE']._serialized_start=10731 + _globals['_COOLINGMODE']._serialized_end=10863 + _globals['_PERFORMANCEMODE']._serialized_start=10865 + _globals['_PERFORMANCEMODE']._serialized_end=10988 + _globals['_CURTAILLEVEL']._serialized_start=10990 + _globals['_CURTAILLEVEL']._serialized_end=11089 + _globals['_MINERERROR']._serialized_start=11092 + _globals['_MINERERROR']._serialized_end=12529 + _globals['_SEVERITY']._serialized_start=12531 + _globals['_SEVERITY']._serialized_end=12649 + _globals['_COMPONENTTYPE']._serialized_start=12652 + _globals['_COMPONENTTYPE']._serialized_end=12869 _globals['_CAPABILITIES']._serialized_start=121 _globals['_CAPABILITIES']._serialized_end=248 _globals['_CAPABILITIES_FLAGSENTRY']._serialized_start=192 @@ -163,18 +163,18 @@ _globals['_GETTIMESERIESDATARESPONSE']._serialized_end=8820 _globals['_UPDATEMINERPASSWORDREQUEST']._serialized_start=8823 _globals['_UPDATEMINERPASSWORDREQUEST']._serialized_end=8966 - _globals['_FIRMWAREFILEINFO']._serialized_start=8968 - _globals['_FIRMWAREFILEINFO']._serialized_end=9089 - _globals['_UPDATEFIRMWAREREQUEST']._serialized_start=9091 - _globals['_UPDATEFIRMWAREREQUEST']._serialized_end=9205 - _globals['_GETFIRMWAREUPDATESTATUSRESPONSE']._serialized_start=9208 - _globals['_GETFIRMWAREUPDATESTATUSRESPONSE']._serialized_end=9346 - _globals['_DEVICEERROR']._serialized_start=9349 - _globals['_DEVICEERROR']._serialized_end=10083 - _globals['_DEVICEERROR_VENDORATTRIBUTESENTRY']._serialized_start=9999 - _globals['_DEVICEERROR_VENDORATTRIBUTESENTRY']._serialized_end=10066 - _globals['_DEVICEERRORS']._serialized_start=10085 - _globals['_DEVICEERRORS']._serialized_end=10173 - _globals['_DRIVER']._serialized_start=12831 - _globals['_DRIVER']._serialized_end=15147 + _globals['_FIRMWAREFILEINFO']._serialized_start=8969 + _globals['_FIRMWAREFILEINFO']._serialized_end=9130 + _globals['_UPDATEFIRMWAREREQUEST']._serialized_start=9132 + _globals['_UPDATEFIRMWAREREQUEST']._serialized_end=9246 + _globals['_GETFIRMWAREUPDATESTATUSRESPONSE']._serialized_start=9249 + _globals['_GETFIRMWAREUPDATESTATUSRESPONSE']._serialized_end=9387 + _globals['_DEVICEERROR']._serialized_start=9390 + _globals['_DEVICEERROR']._serialized_end=10124 + _globals['_DEVICEERROR_VENDORATTRIBUTESENTRY']._serialized_start=10040 + _globals['_DEVICEERROR_VENDORATTRIBUTESENTRY']._serialized_end=10107 + _globals['_DEVICEERRORS']._serialized_start=10126 + _globals['_DEVICEERRORS']._serialized_end=10214 + _globals['_DRIVER']._serialized_start=12872 + _globals['_DRIVER']._serialized_end=15188 # @@protoc_insertion_point(module_scope) diff --git a/server/sdk/v1/python/proto_fleet_sdk/generated/pb/driver_pb2.pyi b/server/sdk/v1/python/proto_fleet_sdk/generated/pb/driver_pb2.pyi index a6f2bb75e..4e35effbb 100644 --- a/server/sdk/v1/python/proto_fleet_sdk/generated/pb/driver_pb2.pyi +++ b/server/sdk/v1/python/proto_fleet_sdk/generated/pb/driver_pb2.pyi @@ -741,14 +741,18 @@ class UpdateMinerPasswordRequest(_message.Message): def __init__(self, ref: _Optional[_Union[DeviceRef, _Mapping]] = ..., current_password: _Optional[str] = ..., new_password: _Optional[str] = ...) -> None: ... class FirmwareFileInfo(_message.Message): - __slots__ = ("file_path", "original_filename", "file_size") + __slots__ = ("file_path", "original_filename", "file_size", "id", "sha256") FILE_PATH_FIELD_NUMBER: _ClassVar[int] ORIGINAL_FILENAME_FIELD_NUMBER: _ClassVar[int] FILE_SIZE_FIELD_NUMBER: _ClassVar[int] + ID_FIELD_NUMBER: _ClassVar[int] + SHA256_FIELD_NUMBER: _ClassVar[int] file_path: str original_filename: str file_size: int - def __init__(self, file_path: _Optional[str] = ..., original_filename: _Optional[str] = ..., file_size: _Optional[int] = ...) -> None: ... + id: str + sha256: str + def __init__(self, file_path: _Optional[str] = ..., original_filename: _Optional[str] = ..., file_size: _Optional[int] = ..., id: _Optional[str] = ..., sha256: _Optional[str] = ...) -> None: ... class UpdateFirmwareRequest(_message.Message): __slots__ = ("ref", "firmware")