From 3d7837202cf1b0ea81155ce3a9d33a2e834c7d5b Mon Sep 17 00:00:00 2001 From: Bugs5382 <12115015+Bugs5382@users.noreply.github.com> Date: Thu, 15 Oct 2026 12:28:37 -0400 Subject: [PATCH 1/3] chore(api-client): regenerate from cryptos-manager at a1372b7 Picks up MintNodeScepChallenge, ListNodeScepChallenges and RevokeNodeScepChallenge on FleetService. Signed-off-by: Bugs5382 <12115015+Bugs5382@users.noreply.github.com> --- packages/api-client/proto-refs.env | 2 +- .../src/gen/cryptos/fleet/v1/fleet_pb.ts | 253 +++++++++++++++++- 2 files changed, 253 insertions(+), 2 deletions(-) diff --git a/packages/api-client/proto-refs.env b/packages/api-client/proto-refs.env index 6643441..d91cd04 100644 --- a/packages/api-client/proto-refs.env +++ b/packages/api-client/proto-refs.env @@ -2,4 +2,4 @@ # `npm run generate -w @cryptos-pki/api-client`, and commit src/gen in the # same change. CRYPTOS_NODE_REF=8d8b52d5bafd4247db69c003a588ccf394d03f79 -CRYPTOS_MANAGER_REF=9e8e3a9979281c5fd916ae255e78d2bdb3485fd8 +CRYPTOS_MANAGER_REF=a1372b7a2c9345fa7d73c5fd243fab767d0f8b0a diff --git a/packages/api-client/src/gen/cryptos/fleet/v1/fleet_pb.ts b/packages/api-client/src/gen/cryptos/fleet/v1/fleet_pb.ts index 11de0d4..2cafd7d 100644 --- a/packages/api-client/src/gen/cryptos/fleet/v1/fleet_pb.ts +++ b/packages/api-client/src/gen/cryptos/fleet/v1/fleet_pb.ts @@ -18,7 +18,7 @@ import type { Message } from "@bufbuild/protobuf"; * Describes the file cryptos/fleet/v1/fleet.proto. */ export const file_cryptos_fleet_v1_fleet: GenFile = /*@__PURE__*/ - fileDesc("ChxjcnlwdG9zL2ZsZWV0L3YxL2ZsZWV0LnByb3RvEhBjcnlwdG9zLmZsZWV0LnYxIhIKEExpc3ROb2Rlc1JlcXVlc3QiQQoRTGlzdE5vZGVzUmVzcG9uc2USLAoFbm9kZXMYASADKAsyHS5jcnlwdG9zLmZsZWV0LnYxLk5vZGVTdW1tYXJ5Ii8KDkdldE5vZGVSZXF1ZXN0EgwKBG5hbWUYASABKAkSDwoHbm9kZV9pZBgCIAEoCSI9Cg9HZXROb2RlUmVzcG9uc2USKgoEbm9kZRgBIAEoCzIcLmNyeXB0b3MuZmxlZXQudjEuTm9kZURldGFpbCI4ChdMaXN0Q2VydGlmaWNhdGVzUmVxdWVzdBIMCgRub2RlGAEgASgJEg8KB25vZGVfaWQYAiABKAkiTwoYTGlzdENlcnRpZmljYXRlc1Jlc3BvbnNlEjMKDGNlcnRpZmljYXRlcxgBIAMoCzIdLmNyeXB0b3MuZmxlZXQudjEuQ2VydGlmaWNhdGUiFQoTTGlzdFByb2ZpbGVzUmVxdWVzdCJKChRMaXN0UHJvZmlsZXNSZXNwb25zZRIyCgVpdGVtcxgBIAMoCzIjLmNyeXB0b3Mubm9kZS52MS5DZXJ0aWZpY2F0ZVByb2ZpbGUiTAoUQ3JlYXRlUHJvZmlsZVJlcXVlc3QSNAoHcHJvZmlsZRgBIAEoCzIjLmNyeXB0b3Mubm9kZS52MS5DZXJ0aWZpY2F0ZVByb2ZpbGUiFwoVQ3JlYXRlUHJvZmlsZVJlc3BvbnNlIkwKFFVwZGF0ZVByb2ZpbGVSZXF1ZXN0EjQKB3Byb2ZpbGUYASABKAsyIy5jcnlwdG9zLm5vZGUudjEuQ2VydGlmaWNhdGVQcm9maWxlIhcKFVVwZGF0ZVByb2ZpbGVSZXNwb25zZSIkChREZWxldGVQcm9maWxlUmVxdWVzdBIMCgRuYW1lGAEgASgJIhcKFURlbGV0ZVByb2ZpbGVSZXNwb25zZSJVChlBcHBseVByb2ZpbGVUb05vZGVSZXF1ZXN0EhEKCW5vZGVfbmFtZRgBIAEoCRIUCgxwcm9maWxlX25hbWUYAiABKAkSDwoHbm9kZV9pZBgDIAEoCSJJChpBcHBseVByb2ZpbGVUb05vZGVSZXNwb25zZRISCgpnZW5lcmF0aW9uGAEgASgEEhcKD3JlcXVpcmVzX3JlYm9vdBgCIAEoCCJBChxTZXRQcm9maWxlUmVxdWVzdGFibGVSZXF1ZXN0EgwKBG5hbWUYASABKAkSEwoLcmVxdWVzdGFibGUYAiABKAgiHwodU2V0UHJvZmlsZVJlcXVlc3RhYmxlUmVzcG9uc2UiIAoeTGlzdFJlcXVlc3RhYmxlUHJvZmlsZXNSZXF1ZXN0IlUKH0xpc3RSZXF1ZXN0YWJsZVByb2ZpbGVzUmVzcG9uc2USMgoFaXRlbXMYASADKAsyIy5jcnlwdG9zLm5vZGUudjEuQ2VydGlmaWNhdGVQcm9maWxlIhUKE0xpc3RBZGFwdGVyc1JlcXVlc3QiSgoUTGlzdEFkYXB0ZXJzUmVzcG9uc2USMgoFaXRlbXMYASADKAsyIy5jcnlwdG9zLmZsZWV0LnYxLkVucm9sbG1lbnRBZGFwdGVyIjkKGFNldEFkYXB0ZXJFbmFibGVkUmVxdWVzdBIMCgRuYW1lGAEgASgJEg8KB2VuYWJsZWQYAiABKAgiUQoZU2V0QWRhcHRlckVuYWJsZWRSZXNwb25zZRI0CgdhZGFwdGVyGAEgASgLMiMuY3J5cHRvcy5mbGVldC52MS5FbnJvbGxtZW50QWRhcHRlciISChBMaXN0QXVkaXRSZXF1ZXN0IkAKEUxpc3RBdWRpdFJlc3BvbnNlEisKBWl0ZW1zGAEgAygLMhwuY3J5cHRvcy5mbGVldC52MS5BdWRpdEV2ZW50IhgKFkxpc3RFbnJvbGxtZW50c1JlcXVlc3QiTQoXTGlzdEVucm9sbG1lbnRzUmVzcG9uc2USMgoFaXRlbXMYASADKAsyIy5jcnlwdG9zLmZsZWV0LnYxLkVucm9sbG1lbnRSZXF1ZXN0IogCCgtOb2RlU3VtbWFyeRIMCgRuYW1lGAEgASgJEg8KB2FkZHJlc3MYAiABKAkSDAoEcm9sZRgDIAEoCRIWCg5pZGVudGl0eV9zdGF0ZRgEIAEoCRIKCgJjbhgFIAEoCRIOCgZpc3N1ZXIYBiABKAkSKAoGaGVhbHRoGAcgASgOMhguY3J5cHRvcy5mbGVldC52MS5IZWFsdGgSFQoNaGVhbHRoX2RldGFpbBgIIAEoCRIKCgJpZBgJIAEoCRIyCglwcm90b2NvbHMYCiADKAsyHy5jcnlwdG9zLm5vZGUudjEuUHJvdG9jb2xTdGF0dXMSFwoPcmVib290X3JlcXVpcmVkGAsgASgIIkkKDE5vZGVJZGVudGl0eRIRCgljaGFpbl9wZW0YASABKAkSEQoJY2hhaW5fZGVyGAIgAygMEhMKC2xlYWZfc2hhMjU2GAMgASgJIqkBCgpOb2RlRGV0YWlsEi4KB3N1bW1hcnkYASABKAsyHS5jcnlwdG9zLmZsZWV0LnYxLk5vZGVTdW1tYXJ5EjAKCGlkZW50aXR5GAIgASgLMh4uY3J5cHRvcy5mbGVldC52MS5Ob2RlSWRlbnRpdHkSFQoNdHBtX2F2YWlsYWJsZRgDIAEoCBISCgpib290X2NvdW50GAQgASgEEg4KBnVwdGltZRgFIAEoCSLYAQoLQ2VydGlmaWNhdGUSDgoGc2VyaWFsGAEgASgJEhIKCnN1YmplY3RfY24YAiABKAkSEwoLaXNzdWVyX25vZGUYAyABKAkSDAoEa2luZBgEIAEoCRIOCgZzdGF0dXMYBSABKAkSEgoKbm90X2JlZm9yZRgGIAEoCRIRCglub3RfYWZ0ZXIYByABKAkSDwoHcHJvZmlsZRgIIAEoCRISCgpyZXZva2VkX2F0GAkgASgJEg4KBnJlYXNvbhgKIAEoCRIWCg5pc3N1ZXJfbm9kZV9pZBgLIAEoCSKNAQoRRW5yb2xsbWVudEFkYXB0ZXISDAoEa2luZBgBIAEoCRIMCgRuYW1lGAIgASgJEhAKCGVuZHBvaW50GAMgASgJEg8KB3Byb2ZpbGUYBCABKAkSDwoHZW5hYmxlZBgFIAEoCBISCgpjaGFsbGVuZ2VzGAYgAygJEhQKDGdwb190ZW1wbGF0ZRgHIAEoCSK8AgoKQXVkaXRFdmVudBIKCgJpZBgBIAEoCRIKCgJhdBgCIAEoCRIMCgRraW5kGAMgASgJEg8KB3N1bW1hcnkYBCABKAkSEwoLdGFyZ2V0X2tpbmQYBSABKAkSEwoLdGFyZ2V0X3BhdGgYBiABKAkSEgoKYWN0b3Jfa2luZBgHIAEoCRIQCghhY3Rvcl9jbhgIIAEoCRIUCgxhY3Rvcl9zZXJpYWwYCSABKAkSDgoGa2V5X2lkGAogASgJEgsKA3ZpYRgLIAEoCRIMCgR0b29sGAwgASgJEhYKDnJlcXVlc3RfZGlnZXN0GA0gASgJEg8KB291dGNvbWUYDiABKAkSEwoLYXBwcm92YWxfaWQYDyABKAkSFwoPYXBwcm92ZXJfc2VyaWFsGBAgASgJEg8KB25vZGVfaWQYESABKAki7wIKEUVucm9sbG1lbnRSZXF1ZXN0EgoKAmlkGAEgASgJEhUKDXByb3Bvc2VkX25hbWUYAiABKAkSDAoEcm9sZRgDIAEoCRIRCglwYXJlbnRfY24YBCABKAkSDwoHYWRkcmVzcxgFIAEoCRIOCgZzdGF0dXMYBiABKAkSGwoTYXR0ZXN0YXRpb25fc3VtbWFyeRgHIAEoCRIbChNhdHRlc3RhdGlvbl9ub2RlX2lkGAggASgJEhQKDGNzcl9rZXlfdHlwZRgJIAEoCRIWCg5jc3Jfc3ViamVjdF9jbhgKIAEoCRIUCgxyZXF1ZXN0ZWRfYXQYCyABKAkSGAoQcmVqZWN0aW9uX3JlYXNvbhgMIAEoCRIaChJhZG1pdHRlZF9ub2RlX25hbWUYDSABKAkSDAoEa2luZBgOIAEoCRIZChFwaW5uZWRfa2V5X3NoYTI1NhgPIAEoCRIYChBhZG1pdHRlZF9ub2RlX2lkGBAgASgJIswBChdDcmVhdGVFbnJvbGxtZW50UmVxdWVzdBIMCgRraW5kGAEgASgJEhUKDW5vZGVfZW5kcG9pbnQYAiABKAkSFgoOYWRtaW5fY2VydF9wZW0YAyABKAkSFQoNYWRtaW5fa2V5X3BlbRgEIAEoCRIOCgZjYV9wZW0YBSABKAkSEgoKY2hpbGRfbm9kZRgGIAEoCRIRCglwYXJlbnRfY24YByABKAkSDwoHcHJvZmlsZRgIIAEoCRIVCg1jaGlsZF9ub2RlX2lkGAkgASgJIlMKGENyZWF0ZUVucm9sbG1lbnRSZXNwb25zZRI3CgplbnJvbGxtZW50GAEgASgLMiMuY3J5cHRvcy5mbGVldC52MS5FbnJvbGxtZW50UmVxdWVzdCJ8ChhBcHByb3ZlRW5yb2xsbWVudFJlcXVlc3QSCgoCaWQYASABKAkSFQoNbm9kZV9lbmRwb2ludBgCIAEoCRIWCg5hZG1pbl9jZXJ0X3BlbRgDIAEoCRIVCg1hZG1pbl9rZXlfcGVtGAQgASgJEg4KBmNhX3BlbRgFIAEoCSJUChlBcHByb3ZlRW5yb2xsbWVudFJlc3BvbnNlEjcKCmVucm9sbG1lbnQYASABKAsyIy5jcnlwdG9zLmZsZWV0LnYxLkVucm9sbG1lbnRSZXF1ZXN0IjUKF1JlamVjdEVucm9sbG1lbnRSZXF1ZXN0EgoKAmlkGAEgASgJEg4KBnJlYXNvbhgCIAEoCSJTChhSZWplY3RFbnJvbGxtZW50UmVzcG9uc2USNwoKZW5yb2xsbWVudBgBIAEoCzIjLmNyeXB0b3MuZmxlZXQudjEuRW5yb2xsbWVudFJlcXVlc3QiDwoNV2hvQW1JUmVxdWVzdCI9ChBPcGVyYXRvcklkZW50aXR5EgoKAmNuGAEgASgJEg4KBnNlcmlhbBgCIAEoCRINCgVsZXZlbBgDIAEoCSJGCg5XaG9BbUlSZXNwb25zZRI0CghvcGVyYXRvchgBIAEoCzIiLmNyeXB0b3MuZmxlZXQudjEuT3BlcmF0b3JJZGVudGl0eSJnChhSZXZva2VDZXJ0aWZpY2F0ZVJlcXVlc3QSEQoJbm9kZV9uYW1lGAEgASgJEhIKCnNlcmlhbF9oZXgYAiABKAkSEwoLcmVhc29uX2NvZGUYAyABKAUSDwoHbm9kZV9pZBgEIAEoCSJYChlSZXZva2VDZXJ0aWZpY2F0ZVJlc3BvbnNlEhIKCnNlcmlhbF9oZXgYASABKAkSEgoKcmV2b2tlZF9hdBgCIAEoCRITCgtyZWFzb25fY29kZRgDIAEoBSI+ChVHZXRDZXJ0aWZpY2F0ZVJlcXVlc3QSEQoJbm9kZV9uYW1lGAEgASgJEhIKCnNlcmlhbF9oZXgYAiABKAkiaAoWR2V0Q2VydGlmaWNhdGVSZXNwb25zZRIXCg9jZXJ0aWZpY2F0ZV9wZW0YASABKAkSEQoJY2hhaW5fcGVtGAIgASgJEg4KBnN0YXR1cxgDIAEoCRISCgpyZXZva2VkX2F0GAQgASgJIl0KEElzc3VlTGVhZlJlcXVlc3QSEQoJbm9kZV9uYW1lGAEgASgJEg8KB2Nzcl9kZXIYAiABKAwSFAoMcHJvZmlsZV9uYW1lGAMgASgJEg8KB25vZGVfaWQYBCABKAkiJQoRSXNzdWVMZWFmUmVzcG9uc2USEAoIY2VydF9kZXIYASABKAwiTAoQUmVrZXlOb2RlUmVxdWVzdBIRCglub2RlX25hbWUYASABKAkSFAoMcHJvZmlsZV9uYW1lGAIgASgJEg8KB25vZGVfaWQYAyABKAkiTQoRUmVrZXlOb2RlUmVzcG9uc2USEgoKc3ViamVjdF9jbhgBIAEoCRIRCglpc3N1ZXJfY24YAiABKAkSEQoJY2hhaW5fbGVuGAMgASgFIjoKFEdldE5vZGVDb25maWdSZXF1ZXN0EhEKCW5vZGVfbmFtZRgBIAEoCRIPCgdub2RlX2lkGAIgASgJIkcKFUdldE5vZGVDb25maWdSZXNwb25zZRIuCgZjb25maWcYASABKAsyHi5jcnlwdG9zLm5vZGUudjEuTWFjaGluZUNvbmZpZyJsChZBcHBseU5vZGVDb25maWdSZXF1ZXN0EhEKCW5vZGVfbmFtZRgBIAEoCRIuCgZjb25maWcYAiABKAsyHi5jcnlwdG9zLm5vZGUudjEuTWFjaGluZUNvbmZpZxIPCgdub2RlX2lkGAMgASgJIkYKF0FwcGx5Tm9kZUNvbmZpZ1Jlc3BvbnNlEhIKCmdlbmVyYXRpb24YASABKAQSFwoPcmVxdWlyZXNfcmVib290GAIgASgIInAKFlNldE5vZGVQcm90b2NvbFJlcXVlc3QSEQoJbm9kZV9uYW1lGAEgASgJEjIKCHByb3RvY29sGAIgASgOMiAuY3J5cHRvcy5ub2RlLnYxLlNlcnZpY2VQcm90b2NvbBIPCgdlbmFibGVkGAMgASgIIkYKF1NldE5vZGVQcm90b2NvbFJlc3BvbnNlEhIKCmdlbmVyYXRpb24YASABKAQSFwoPcmVxdWlyZXNfcmVib290GAIgASgIIkwKEkV4cG9ydENBS2V5UmVxdWVzdBIRCglub2RlX25hbWUYASABKAkSEgoKcGFzc3BocmFzZRgCIAEoDBIPCgdub2RlX2lkGAMgASgJIicKE0V4cG9ydENBS2V5UmVzcG9uc2USEAoIZW52ZWxvcGUYASABKAwiXgoSSW1wb3J0Q0FLZXlSZXF1ZXN0EhEKCW5vZGVfbmFtZRgBIAEoCRIQCghlbnZlbG9wZRgCIAEoDBISCgpwYXNzcGhyYXNlGAMgASgMEg8KB25vZGVfaWQYBCABKAkiPAoTSW1wb3J0Q0FLZXlSZXNwb25zZRISCgpzdWJqZWN0X2NuGAEgASgJEhEKCWlzc3Vlcl9jbhgCIAEoCSJvCh9SZXZva2VPcGVyYXRvckNyZWRlbnRpYWxSZXF1ZXN0EhIKCnNlcmlhbF9oZXgYASABKAkSEwoLcmVhc29uX2NvZGUYAiABKAUSFQoNaXNzdWVyX3NoYTI1NhgDIAEoCRIMCgRub3RlGAQgASgJInMKIFJldm9rZU9wZXJhdG9yQ3JlZGVudGlhbFJlc3BvbnNlEhIKCnNlcmlhbF9oZXgYASABKAkSEgoKcmV2b2tlZF9hdBgCIAEoCRIVCg1pc3N1ZXJfc2hhMjU2GAMgASgJEhAKCHdhcm5pbmdzGAQgAygJIiAKHkxpc3RPcGVyYXRvckNyZWRlbnRpYWxzUmVxdWVzdCKNAgoST3BlcmF0b3JDcmVkZW50aWFsEhMKC2NvbW1vbl9uYW1lGAEgASgJEhIKCnNlcmlhbF9oZXgYAiABKAkSDQoFbGV2ZWwYAyABKAkSEQoJbm90X2FmdGVyGAQgASgJEg8KB3Jldm9rZWQYBSABKAgSDAoEa2luZBgGIAEoCRIVCg1pc3N1ZXJfc2hhMjU2GAcgASgJEg0KBWVtYWlsGAggASgJEhEKCWZ1bGxfbmFtZRgJIAEoCRISCgpkZW55bGlzdGVkGAogASgIEhMKC2NybF9yZXZva2VkGAsgASgIEhUKDWZpcnN0X3NlZW5fYXQYDCABKAkSFAoMbGFzdF9zZWVuX2F0GA0gASgJIlYKH0xpc3RPcGVyYXRvckNyZWRlbnRpYWxzUmVzcG9uc2USMwoFaXRlbXMYASADKAsyJC5jcnlwdG9zLmZsZWV0LnYxLk9wZXJhdG9yQ3JlZGVudGlhbCJqCiZDcmVhdGVPcGVyYXRvckNyZWRlbnRpYWxSZXF1ZXN0UmVxdWVzdBINCgVsZXZlbBgBIAEoCRINCgVlbWFpbBgCIAEoCRIRCglmdWxsX25hbWUYAyABKAkSDwoHY3NyX2RlchgEIAEoDCKUAQonQ3JlYXRlT3BlcmF0b3JDcmVkZW50aWFsUmVxdWVzdFJlc3BvbnNlEhIKCnJlcXVlc3RfaWQYASABKAkSDwoHY3NyX3BlbRgCIAEoCRIXCg9leHRmaWxlX3NlY3Rpb24YAyABKAkSFwoPb3BlbnNzbF9jb21tYW5kGAQgASgJEhIKCmV4cGlyZXNfYXQYBSABKAkiNgolTGlzdE9wZXJhdG9yQ3JlZGVudGlhbFJlcXVlc3RzUmVxdWVzdBINCgVzdGF0ZRgBIAEoCSJkCiZMaXN0T3BlcmF0b3JDcmVkZW50aWFsUmVxdWVzdHNSZXNwb25zZRI6CgVpdGVtcxgBIAMoCzIrLmNyeXB0b3MuZmxlZXQudjEuT3BlcmF0b3JDcmVkZW50aWFsUmVxdWVzdCI8CiZDYW5jZWxPcGVyYXRvckNyZWRlbnRpYWxSZXF1ZXN0UmVxdWVzdBISCgpyZXF1ZXN0X2lkGAEgASgJImcKJ0NhbmNlbE9wZXJhdG9yQ3JlZGVudGlhbFJlcXVlc3RSZXNwb25zZRI8CgdyZXF1ZXN0GAEgASgLMisuY3J5cHRvcy5mbGVldC52MS5PcGVyYXRvckNyZWRlbnRpYWxSZXF1ZXN0ItEBChlPcGVyYXRvckNyZWRlbnRpYWxSZXF1ZXN0EgoKAmlkGAEgASgJEg0KBWxldmVsGAIgASgJEg0KBWVtYWlsGAMgASgJEhEKCWZ1bGxfbmFtZRgEIAEoCRIPCgdjc3JfcGVtGAUgASgJEg0KBXN0YXRlGAYgASgJEhUKDWNyZWF0ZWRfYnlfY24YByABKAkSEgoKY3JlYXRlZF9hdBgIIAEoCRISCgpleHBpcmVzX2F0GAkgASgJEhgKEGNvbXBsZXRlZF9zZXJpYWwYCiABKAkiWgofUmVjb3JkT3BlcmF0b3JDcmVkZW50aWFsUmVxdWVzdBIQCghjZXJ0X2RlchgBIAEoDBISCgpyZXF1ZXN0X2lkGAIgASgJEhEKCWZ1bGxfbmFtZRgDIAEoCSJuCiBSZWNvcmRPcGVyYXRvckNyZWRlbnRpYWxSZXNwb25zZRI4CgpjcmVkZW50aWFsGAEgASgLMiQuY3J5cHRvcy5mbGVldC52MS5PcGVyYXRvckNyZWRlbnRpYWwSEAoId2FybmluZ3MYAiADKAkiGAoWTGlzdE9wZXJhdG9yQ0FzUmVxdWVzdCJGChdMaXN0T3BlcmF0b3JDQXNSZXNwb25zZRIrCgVpdGVtcxgBIAMoCzIcLmNyeXB0b3MuZmxlZXQudjEuT3BlcmF0b3JDQSKQAgoZUmVnaXN0ZXJPcGVyYXRvckNBUmVxdWVzdBITCgtjYV9jZXJ0X2RlchgBIAEoDBINCgN1cmwYAiABKAlIABIRCgdjcmxfZGVyGAMgASgMSAASDgoEbm9uZRgEIAEoCEgAEi0KCW9jc3BfbW9kZRgFIAEoDjIaLmNyeXB0b3MuZmxlZXQudjEuT2NzcE1vZGUSEAoIb2NzcF91cmwYBiABKAkSRQoQYWNrbm93bGVkZ2VtZW50cxgHIAMoDjIrLmNyeXB0b3MuZmxlZXQudjEuT3BlcmF0b3JDQUFja25vd2xlZGdlbWVudBIWCg5jb25maXJtX3NoYTI1NhgIIAEoCUIMCgpjcmxfc291cmNlIrABChpSZWdpc3Rlck9wZXJhdG9yQ0FSZXNwb25zZRIxCgtvcGVyYXRvcl9jYRgBIAEoCzIcLmNyeXB0b3MuZmxlZXQudjEuT3BlcmF0b3JDQRIRCgljb25maXJtZWQYAiABKAgSFQoNYWRtaW5fZXh0ZmlsZRgDIAEoCRI1CgpvY3NwX3Byb2JlGAQgASgLMiEuY3J5cHRvcy5mbGVldC52MS5PY3NwUHJvYmVSZXN1bHQiTAoXUmV0aXJlT3BlcmF0b3JDQVJlcXVlc3QSDgoGc2hhMjU2GAEgASgJEiEKGWlfdW5kZXJzdGFuZF9zZWxmX2xvY2tvdXQYAiABKAgiTQoYUmV0aXJlT3BlcmF0b3JDQVJlc3BvbnNlEjEKC29wZXJhdG9yX2NhGAEgASgLMhwuY3J5cHRvcy5mbGVldC52MS5PcGVyYXRvckNBIrYBCh1TZXRPcGVyYXRvckNBQ1JMU291cmNlUmVxdWVzdBIOCgZzaGEyNTYYASABKAkSDQoDdXJsGAIgASgJSAASDgoEbm9uZRgDIAEoCEgAEhEKB2NybF9kZXIYBSABKAxIABJFChBhY2tub3dsZWRnZW1lbnRzGAQgAygOMisuY3J5cHRvcy5mbGVldC52MS5PcGVyYXRvckNBQWNrbm93bGVkZ2VtZW50QgwKCmNybF9zb3VyY2UiUwoeU2V0T3BlcmF0b3JDQUNSTFNvdXJjZVJlc3BvbnNlEjEKC29wZXJhdG9yX2NhGAEgASgLMhwuY3J5cHRvcy5mbGVldC52MS5PcGVyYXRvckNBIjsKGFVwbG9hZE9wZXJhdG9yQ1JMUmVxdWVzdBIOCgZzaGEyNTYYASABKAkSDwoHY3JsX2RlchgCIAEoDCJOChlVcGxvYWRPcGVyYXRvckNSTFJlc3BvbnNlEjEKC29wZXJhdG9yX2NhGAEgASgLMhwuY3J5cHRvcy5mbGVldC52MS5PcGVyYXRvckNBImsKGFNldE9wZXJhdG9yQ0FPQ1NQUmVxdWVzdBIOCgZzaGEyNTYYASABKAkSLQoJb2NzcF9tb2RlGAIgASgOMhouY3J5cHRvcy5mbGVldC52MS5PY3NwTW9kZRIQCghvY3NwX3VybBgDIAEoCSKFAQoZU2V0T3BlcmF0b3JDQU9DU1BSZXNwb25zZRIxCgtvcGVyYXRvcl9jYRgBIAEoCzIcLmNyeXB0b3MuZmxlZXQudjEuT3BlcmF0b3JDQRI1CgpvY3NwX3Byb2JlGAIgASgLMiEuY3J5cHRvcy5mbGVldC52MS5PY3NwUHJvYmVSZXN1bHQiKgoWUHJldmlld0Fkb3B0aW9uUmVxdWVzdBIQCghlbmRwb2ludBgBIAEoCSI/ChdQcmV2aWV3QWRvcHRpb25SZXNwb25zZRITCgtjZXJ0X3NoYTI1NhgBIAEoCRIPCgdzdWJqZWN0GAIgASgJIkcKF0xpc3RJbnN0YWxsRGlza3NSZXF1ZXN0EhAKCGVuZHBvaW50GAEgASgJEhoKEnBpbm5lZF9jZXJ0X3NoYTI1NhgCIAEoCSJHChhMaXN0SW5zdGFsbERpc2tzUmVzcG9uc2USKwoFZGlza3MYASADKAsyHC5jcnlwdG9zLm5vZGUudjEuSW5zdGFsbERpc2sicAoQQWRvcHROb2RlUmVxdWVzdBIQCghlbmRwb2ludBgBIAEoCRIaChJwaW5uZWRfY2VydF9zaGEyNTYYAiABKAkSLgoGY29uZmlnGAMgASgLMh4uY3J5cHRvcy5ub2RlLnYxLk1hY2hpbmVDb25maWcihQEKEUFkb3B0Tm9kZVJlc3BvbnNlEg0KBXBoYXNlGAEgASgJEg4KBmRldGFpbBgCIAEoCRIMCgRkb25lGAMgASgIEg8KB25vZGVfaWQYBCABKAkSEwoLYWRvcHRpb25faWQYBSABKAkSHQoVcHJlc2VudGVkX2NlcnRfc2hhMjU2GAYgASgJIk0KIUNvbmZpcm1BZG9wdGlvbkZpbmdlcnByaW50UmVxdWVzdBITCgthZG9wdGlvbl9pZBgBIAEoCRITCgtjZXJ0X3NoYTI1NhgCIAEoCSIkCiJDb25maXJtQWRvcHRpb25GaW5nZXJwcmludFJlc3BvbnNlIloKF0RlY29tbWlzc2lvbk5vZGVSZXF1ZXN0EhEKCW5vZGVfbmFtZRgBIAEoCRIbChNjb25maXJtX2NvbW1vbl9uYW1lGAIgASgJEg8KB25vZGVfaWQYAyABKAkiLQoYRGVjb21taXNzaW9uTm9kZVJlc3BvbnNlEhEKCXJlYm9vdGluZxgBIAEoCCJhChFSZWJvb3ROb2RlUmVxdWVzdBIRCglub2RlX25hbWUYASABKAkSFQoNY29uZmlybV9jYV9jbhgCIAEoCRIRCglwb3dlcl9vZmYYAyABKAgSDwoHbm9kZV9pZBgEIAEoCSInChJSZWJvb3ROb2RlUmVzcG9uc2USEQoJcmVib290aW5nGAEgASgIIjYKEVJlbmFtZU5vZGVSZXF1ZXN0Eg8KB25vZGVfaWQYASABKAkSEAoIbmV3X25hbWUYAiABKAkiQQoSUmVuYW1lTm9kZVJlc3BvbnNlEisKBG5vZGUYASABKAsyHS5jcnlwdG9zLmZsZWV0LnYxLk5vZGVTdW1tYXJ5IjoKEVJlbW92ZU5vZGVSZXF1ZXN0Eg8KB25vZGVfaWQYASABKAkSFAoMY29uZmlybV9uYW1lGAIgASgJIkEKElJlbW92ZU5vZGVSZXNwb25zZRIrCgRub2RlGAEgASgLMh0uY3J5cHRvcy5mbGVldC52MS5Ob2RlU3VtbWFyeSIhChJMaXN0TWNwS2V5c1JlcXVlc3QSCwoDYWxsGAEgASgIIj4KE0xpc3RNY3BLZXlzUmVzcG9uc2USJwoFaXRlbXMYASADKAsyGC5jcnlwdG9zLmZsZWV0LnYxLk1jcEtleSIhChNSZXZva2VNY3BLZXlSZXF1ZXN0EgoKAmlkGAEgASgJIkEKFFJldm9rZU1jcEtleVJlc3BvbnNlEikKB21jcF9rZXkYASABKAsyGC5jcnlwdG9zLmZsZWV0LnYxLk1jcEtleSI7ChNDcmVhdGVNY3BLZXlSZXF1ZXN0Eg0KBWxhYmVsGAEgASgJEhUKDWxldmVsX2NlaWxpbmcYAiABKAkiWAoUQ3JlYXRlTWNwS2V5UmVzcG9uc2USFQoNcGxhaW50ZXh0X2tleRgBIAEoCRIpCgdtY3Bfa2V5GAIgASgLMhguY3J5cHRvcy5mbGVldC52MS5NY3BLZXkiuwEKBk1jcEtleRIKCgJpZBgBIAEoCRINCgVsYWJlbBgCIAEoCRITCgtjbGllbnRfbmFtZRgDIAEoCRITCgtvcGVyYXRvcl9jbhgEIAEoCRIXCg9vcGVyYXRvcl9zZXJpYWwYBSABKAkSFQoNbGV2ZWxfY2VpbGluZxgGIAEoCRISCgpjcmVhdGVkX2F0GAcgASgJEhQKDGxhc3RfdXNlZF9hdBgIIAEoCRISCgpyZXZva2VkX2F0GAkgASgJIiYKFExpc3RBcHByb3ZhbHNSZXF1ZXN0Eg4KBnN0YXR1cxgBIAEoCSJCChVMaXN0QXBwcm92YWxzUmVzcG9uc2USKQoFaXRlbXMYASADKAsyGi5jcnlwdG9zLmZsZWV0LnYxLkFwcHJvdmFsIjQKFURlY2lkZUFwcHJvdmFsUmVxdWVzdBIKCgJpZBgBIAEoCRIPCgdhcHByb3ZlGAIgASgIIkYKFkRlY2lkZUFwcHJvdmFsUmVzcG9uc2USLAoIYXBwcm92YWwYASABKAsyGi5jcnlwdG9zLmZsZWV0LnYxLkFwcHJvdmFsIrcCCghBcHByb3ZhbBIKCgJpZBgBIAEoCRIMCgR0b29sGAIgASgJEg8KB3N1bW1hcnkYAyABKAkSFgoOcmVxdWVzdF9kaWdlc3QYBCABKAkSFwoPcmVxdWVzdGVkX2J5X2NuGAUgASgJEhsKE3JlcXVlc3RlZF9ieV9zZXJpYWwYBiABKAkSDgoGa2V5X2lkGAcgASgJEhYKDnJlcXVpcmVkX2xldmVsGAggASgJEhIKCmNyZWF0ZWRfYXQYCSABKAkSEgoKZXhwaXJlc19hdBgKIAEoCRIOCgZzdGF0dXMYCyABKAkSFQoNZGVjaWRlZF9ieV9jbhgMIAEoCRIZChFkZWNpZGVkX2J5X3NlcmlhbBgNIAEoCRISCgpkZWNpZGVkX2F0GA4gASgJEgwKBGtpbmQYDyABKAkirwIKEkNlcnRpZmljYXRlUmVxdWVzdBIKCgJpZBgBIAEoCRIUCgxwcm9maWxlX25hbWUYAiABKAkSDwoHY3NyX3BlbRgDIAEoCRIMCgRub3RlGAQgASgJEhcKD3JlcXVlc3RlZF9ieV9jbhgFIAEoCRIbChNyZXF1ZXN0ZWRfYnlfc2VyaWFsGAYgASgJEg0KBXN0YXRlGAcgASgJEhMKC2FwcHJvdmFsX2lkGAggASgJEhcKD2NlcnRpZmljYXRlX3BlbRgJIAEoCRIWCg5mYWlsdXJlX3JlYXNvbhgKIAEoCRISCgpjcmVhdGVkX2F0GAsgASgJEhIKCmV4cGlyZXNfYXQYDCABKAkSEgoKZGVjaWRlZF9hdBgNIAEoCRIRCglpc3N1ZWRfYXQYDiABKAkiVgofQ3JlYXRlQ2VydGlmaWNhdGVSZXF1ZXN0UmVxdWVzdBIUCgxwcm9maWxlX25hbWUYASABKAkSDwoHY3NyX2RlchgCIAEoDBIMCgRub3RlGAMgASgJIlkKIENyZWF0ZUNlcnRpZmljYXRlUmVxdWVzdFJlc3BvbnNlEjUKB3JlcXVlc3QYASABKAsyJC5jcnlwdG9zLmZsZWV0LnYxLkNlcnRpZmljYXRlUmVxdWVzdCJCCh5MaXN0Q2VydGlmaWNhdGVSZXF1ZXN0c1JlcXVlc3QSDQoFc3RhdGUYASABKAkSEQoJbWluZV9vbmx5GAIgASgIIlYKH0xpc3RDZXJ0aWZpY2F0ZVJlcXVlc3RzUmVzcG9uc2USMwoFaXRlbXMYASADKAsyJC5jcnlwdG9zLmZsZWV0LnYxLkNlcnRpZmljYXRlUmVxdWVzdCIuCiBHZXRDZXJ0aWZpY2F0ZVJlcXVlc3RCeUlEUmVxdWVzdBIKCgJpZBgBIAEoCSJaCiFHZXRDZXJ0aWZpY2F0ZVJlcXVlc3RCeUlEUmVzcG9uc2USNQoHcmVxdWVzdBgBIAEoCzIkLmNyeXB0b3MuZmxlZXQudjEuQ2VydGlmaWNhdGVSZXF1ZXN0Ii0KH0NhbmNlbENlcnRpZmljYXRlUmVxdWVzdFJlcXVlc3QSCgoCaWQYASABKAkiWQogQ2FuY2VsQ2VydGlmaWNhdGVSZXF1ZXN0UmVzcG9uc2USNQoHcmVxdWVzdBgBIAEoCzIkLmNyeXB0b3MuZmxlZXQudjEuQ2VydGlmaWNhdGVSZXF1ZXN0IkQKHkxpc3ROb2RlVHNhQ2VydGlmaWNhdGVzUmVxdWVzdBIRCglub2RlX25hbWUYASABKAkSDwoHbm9kZV9pZBgCIAEoCSKGAQoSTm9kZVRzYUNlcnRpZmljYXRlEhAKCGNlcnRfcGVtGAEgASgJEhIKCnNlcmlhbF9oZXgYAiABKAkSEgoKc2hhMjU2X2hleBgDIAEoCRISCgpub3RfYmVmb3JlGAQgASgJEhEKCW5vdF9hZnRlchgFIAEoCRIPCgdjdXJyZW50GAYgASgIIl0KH0xpc3ROb2RlVHNhQ2VydGlmaWNhdGVzUmVzcG9uc2USOgoMY2VydGlmaWNhdGVzGAEgAygLMiQuY3J5cHRvcy5mbGVldC52MS5Ob2RlVHNhQ2VydGlmaWNhdGUiXgofVmFsaWRhdGVDZXJ0aWZpY2F0ZUNoYWluUmVxdWVzdBIRCglub2RlX25hbWUYASABKAkSDwoHbm9kZV9pZBgCIAEoCRIXCg9jZXJ0aWZpY2F0ZV9wZW0YAyABKAkiewogVmFsaWRhdGVDZXJ0aWZpY2F0ZUNoYWluUmVzcG9uc2USDQoFdmFsaWQYASABKAgSDgoGcmVhc29uGAIgASgJEg8KB3N1YmplY3QYAyABKAkSDgoGaXNzdWVyGAQgASgJEhcKD25vZGVfY2Ffc3ViamVjdBgFIAEoCSKuAQoaTGlzdE5vZGVBdWRpdEV2ZW50c1JlcXVlc3QSEQoJbm9kZV9uYW1lGAEgASgJEg8KB25vZGVfaWQYAiABKAkSEQoJcGFnZV9zaXplGAMgASgFEhIKCnBhZ2VfdG9rZW4YBCABKAkSEQoJZnJvbV90aW1lGAUgASgJEg8KB3RvX3RpbWUYBiABKAkSEgoKZXZlbnRfdHlwZRgHIAEoCRINCgVhY3RvchgIIAEoCSKQAgoOTm9kZUF1ZGl0RXZlbnQSCwoDc2VxGAEgASgEEgoKAnRzGAIgASgJEhUKDWFjdG9yX3N1YmplY3QYAyABKAkSEgoKcnBjX21ldGhvZBgEIAEoCRIPCgdvdXRjb21lGAUgASgJEj4KB2RldGFpbHMYBiADKAsyLS5jcnlwdG9zLmZsZWV0LnYxLk5vZGVBdWRpdEV2ZW50LkRldGFpbHNFbnRyeRIYChBlbnRyeV9zaGEyNTZfaGV4GAcgASgJEg4KBnRhcmdldBgIIAEoCRIPCgdzdW1tYXJ5GAkgASgJGi4KDERldGFpbHNFbnRyeRILCgNrZXkYASABKAkSDQoFdmFsdWUYAiABKAk6AjgBImkKG0xpc3ROb2RlQXVkaXRFdmVudHNSZXNwb25zZRIxCgdlbnRyaWVzGAEgAygLMiAuY3J5cHRvcy5mbGVldC52MS5Ob2RlQXVkaXRFdmVudBIXCg9uZXh0X3BhZ2VfdG9rZW4YAiABKAkiQQobVmVyaWZ5Tm9kZUF1ZGl0Q2hhaW5SZXF1ZXN0EhEKCW5vZGVfbmFtZRgBIAEoCRIPCgdub2RlX2lkGAIgASgJInIKHFZlcmlmeU5vZGVBdWRpdENoYWluUmVzcG9uc2USEwoLZW50cnlfY291bnQYASABKAQSDgoGaW50YWN0GAIgASgIEh0KFWZpcnN0X2Jyb2tlbl9zZXF1ZW5jZRgDIAEoBBIOCgZyZWFzb24YBCABKAkqUgoGSGVhbHRoEhYKEkhFQUxUSF9VTlNQRUNJRklFRBAAEg0KCUhFQUxUSF9VUBABEg8KC0hFQUxUSF9ET1dOEAISEAoMSEVBTFRIX0VSUk9SEAMyizMKDEZsZWV0U2VydmljZRJUCglMaXN0Tm9kZXMSIi5jcnlwdG9zLmZsZWV0LnYxLkxpc3ROb2Rlc1JlcXVlc3QaIy5jcnlwdG9zLmZsZWV0LnYxLkxpc3ROb2Rlc1Jlc3BvbnNlEk4KB0dldE5vZGUSIC5jcnlwdG9zLmZsZWV0LnYxLkdldE5vZGVSZXF1ZXN0GiEuY3J5cHRvcy5mbGVldC52MS5HZXROb2RlUmVzcG9uc2USaQoQTGlzdENlcnRpZmljYXRlcxIpLmNyeXB0b3MuZmxlZXQudjEuTGlzdENlcnRpZmljYXRlc1JlcXVlc3QaKi5jcnlwdG9zLmZsZWV0LnYxLkxpc3RDZXJ0aWZpY2F0ZXNSZXNwb25zZRJdCgxMaXN0UHJvZmlsZXMSJS5jcnlwdG9zLmZsZWV0LnYxLkxpc3RQcm9maWxlc1JlcXVlc3QaJi5jcnlwdG9zLmZsZWV0LnYxLkxpc3RQcm9maWxlc1Jlc3BvbnNlEmAKDUNyZWF0ZVByb2ZpbGUSJi5jcnlwdG9zLmZsZWV0LnYxLkNyZWF0ZVByb2ZpbGVSZXF1ZXN0GicuY3J5cHRvcy5mbGVldC52MS5DcmVhdGVQcm9maWxlUmVzcG9uc2USYAoNVXBkYXRlUHJvZmlsZRImLmNyeXB0b3MuZmxlZXQudjEuVXBkYXRlUHJvZmlsZVJlcXVlc3QaJy5jcnlwdG9zLmZsZWV0LnYxLlVwZGF0ZVByb2ZpbGVSZXNwb25zZRJgCg1EZWxldGVQcm9maWxlEiYuY3J5cHRvcy5mbGVldC52MS5EZWxldGVQcm9maWxlUmVxdWVzdBonLmNyeXB0b3MuZmxlZXQudjEuRGVsZXRlUHJvZmlsZVJlc3BvbnNlEm8KEkFwcGx5UHJvZmlsZVRvTm9kZRIrLmNyeXB0b3MuZmxlZXQudjEuQXBwbHlQcm9maWxlVG9Ob2RlUmVxdWVzdBosLmNyeXB0b3MuZmxlZXQudjEuQXBwbHlQcm9maWxlVG9Ob2RlUmVzcG9uc2USeAoVU2V0UHJvZmlsZVJlcXVlc3RhYmxlEi4uY3J5cHRvcy5mbGVldC52MS5TZXRQcm9maWxlUmVxdWVzdGFibGVSZXF1ZXN0Gi8uY3J5cHRvcy5mbGVldC52MS5TZXRQcm9maWxlUmVxdWVzdGFibGVSZXNwb25zZRJ+ChdMaXN0UmVxdWVzdGFibGVQcm9maWxlcxIwLmNyeXB0b3MuZmxlZXQudjEuTGlzdFJlcXVlc3RhYmxlUHJvZmlsZXNSZXF1ZXN0GjEuY3J5cHRvcy5mbGVldC52MS5MaXN0UmVxdWVzdGFibGVQcm9maWxlc1Jlc3BvbnNlEl0KDExpc3RBZGFwdGVycxIlLmNyeXB0b3MuZmxlZXQudjEuTGlzdEFkYXB0ZXJzUmVxdWVzdBomLmNyeXB0b3MuZmxlZXQudjEuTGlzdEFkYXB0ZXJzUmVzcG9uc2USbAoRU2V0QWRhcHRlckVuYWJsZWQSKi5jcnlwdG9zLmZsZWV0LnYxLlNldEFkYXB0ZXJFbmFibGVkUmVxdWVzdBorLmNyeXB0b3MuZmxlZXQudjEuU2V0QWRhcHRlckVuYWJsZWRSZXNwb25zZRJmCg9TZXROb2RlUHJvdG9jb2wSKC5jcnlwdG9zLmZsZWV0LnYxLlNldE5vZGVQcm90b2NvbFJlcXVlc3QaKS5jcnlwdG9zLmZsZWV0LnYxLlNldE5vZGVQcm90b2NvbFJlc3BvbnNlElQKCUxpc3RBdWRpdBIiLmNyeXB0b3MuZmxlZXQudjEuTGlzdEF1ZGl0UmVxdWVzdBojLmNyeXB0b3MuZmxlZXQudjEuTGlzdEF1ZGl0UmVzcG9uc2USZgoPTGlzdEVucm9sbG1lbnRzEiguY3J5cHRvcy5mbGVldC52MS5MaXN0RW5yb2xsbWVudHNSZXF1ZXN0GikuY3J5cHRvcy5mbGVldC52MS5MaXN0RW5yb2xsbWVudHNSZXNwb25zZRJpChBDcmVhdGVFbnJvbGxtZW50EikuY3J5cHRvcy5mbGVldC52MS5DcmVhdGVFbnJvbGxtZW50UmVxdWVzdBoqLmNyeXB0b3MuZmxlZXQudjEuQ3JlYXRlRW5yb2xsbWVudFJlc3BvbnNlEmwKEUFwcHJvdmVFbnJvbGxtZW50EiouY3J5cHRvcy5mbGVldC52MS5BcHByb3ZlRW5yb2xsbWVudFJlcXVlc3QaKy5jcnlwdG9zLmZsZWV0LnYxLkFwcHJvdmVFbnJvbGxtZW50UmVzcG9uc2USaQoQUmVqZWN0RW5yb2xsbWVudBIpLmNyeXB0b3MuZmxlZXQudjEuUmVqZWN0RW5yb2xsbWVudFJlcXVlc3QaKi5jcnlwdG9zLmZsZWV0LnYxLlJlamVjdEVucm9sbG1lbnRSZXNwb25zZRJLCgZXaG9BbUkSHy5jcnlwdG9zLmZsZWV0LnYxLldob0FtSVJlcXVlc3QaIC5jcnlwdG9zLmZsZWV0LnYxLldob0FtSVJlc3BvbnNlEmwKEVJldm9rZUNlcnRpZmljYXRlEiouY3J5cHRvcy5mbGVldC52MS5SZXZva2VDZXJ0aWZpY2F0ZVJlcXVlc3QaKy5jcnlwdG9zLmZsZWV0LnYxLlJldm9rZUNlcnRpZmljYXRlUmVzcG9uc2USYwoOR2V0Q2VydGlmaWNhdGUSJy5jcnlwdG9zLmZsZWV0LnYxLkdldENlcnRpZmljYXRlUmVxdWVzdBooLmNyeXB0b3MuZmxlZXQudjEuR2V0Q2VydGlmaWNhdGVSZXNwb25zZRJyChNMaXN0Tm9kZUF1ZGl0RXZlbnRzEiwuY3J5cHRvcy5mbGVldC52MS5MaXN0Tm9kZUF1ZGl0RXZlbnRzUmVxdWVzdBotLmNyeXB0b3MuZmxlZXQudjEuTGlzdE5vZGVBdWRpdEV2ZW50c1Jlc3BvbnNlEnUKFFZlcmlmeU5vZGVBdWRpdENoYWluEi0uY3J5cHRvcy5mbGVldC52MS5WZXJpZnlOb2RlQXVkaXRDaGFpblJlcXVlc3QaLi5jcnlwdG9zLmZsZWV0LnYxLlZlcmlmeU5vZGVBdWRpdENoYWluUmVzcG9uc2USgQEKGFZhbGlkYXRlQ2VydGlmaWNhdGVDaGFpbhIxLmNyeXB0b3MuZmxlZXQudjEuVmFsaWRhdGVDZXJ0aWZpY2F0ZUNoYWluUmVxdWVzdBoyLmNyeXB0b3MuZmxlZXQudjEuVmFsaWRhdGVDZXJ0aWZpY2F0ZUNoYWluUmVzcG9uc2USfgoXTGlzdE5vZGVUc2FDZXJ0aWZpY2F0ZXMSMC5jcnlwdG9zLmZsZWV0LnYxLkxpc3ROb2RlVHNhQ2VydGlmaWNhdGVzUmVxdWVzdBoxLmNyeXB0b3MuZmxlZXQudjEuTGlzdE5vZGVUc2FDZXJ0aWZpY2F0ZXNSZXNwb25zZRJUCglJc3N1ZUxlYWYSIi5jcnlwdG9zLmZsZWV0LnYxLklzc3VlTGVhZlJlcXVlc3QaIy5jcnlwdG9zLmZsZWV0LnYxLklzc3VlTGVhZlJlc3BvbnNlElQKCVJla2V5Tm9kZRIiLmNyeXB0b3MuZmxlZXQudjEuUmVrZXlOb2RlUmVxdWVzdBojLmNyeXB0b3MuZmxlZXQudjEuUmVrZXlOb2RlUmVzcG9uc2USYAoNR2V0Tm9kZUNvbmZpZxImLmNyeXB0b3MuZmxlZXQudjEuR2V0Tm9kZUNvbmZpZ1JlcXVlc3QaJy5jcnlwdG9zLmZsZWV0LnYxLkdldE5vZGVDb25maWdSZXNwb25zZRJmCg9BcHBseU5vZGVDb25maWcSKC5jcnlwdG9zLmZsZWV0LnYxLkFwcGx5Tm9kZUNvbmZpZ1JlcXVlc3QaKS5jcnlwdG9zLmZsZWV0LnYxLkFwcGx5Tm9kZUNvbmZpZ1Jlc3BvbnNlEloKC0V4cG9ydENBS2V5EiQuY3J5cHRvcy5mbGVldC52MS5FeHBvcnRDQUtleVJlcXVlc3QaJS5jcnlwdG9zLmZsZWV0LnYxLkV4cG9ydENBS2V5UmVzcG9uc2USWgoLSW1wb3J0Q0FLZXkSJC5jcnlwdG9zLmZsZWV0LnYxLkltcG9ydENBS2V5UmVxdWVzdBolLmNyeXB0b3MuZmxlZXQudjEuSW1wb3J0Q0FLZXlSZXNwb25zZRKWAQofQ3JlYXRlT3BlcmF0b3JDcmVkZW50aWFsUmVxdWVzdBI4LmNyeXB0b3MuZmxlZXQudjEuQ3JlYXRlT3BlcmF0b3JDcmVkZW50aWFsUmVxdWVzdFJlcXVlc3QaOS5jcnlwdG9zLmZsZWV0LnYxLkNyZWF0ZU9wZXJhdG9yQ3JlZGVudGlhbFJlcXVlc3RSZXNwb25zZRKTAQoeTGlzdE9wZXJhdG9yQ3JlZGVudGlhbFJlcXVlc3RzEjcuY3J5cHRvcy5mbGVldC52MS5MaXN0T3BlcmF0b3JDcmVkZW50aWFsUmVxdWVzdHNSZXF1ZXN0GjguY3J5cHRvcy5mbGVldC52MS5MaXN0T3BlcmF0b3JDcmVkZW50aWFsUmVxdWVzdHNSZXNwb25zZRKWAQofQ2FuY2VsT3BlcmF0b3JDcmVkZW50aWFsUmVxdWVzdBI4LmNyeXB0b3MuZmxlZXQudjEuQ2FuY2VsT3BlcmF0b3JDcmVkZW50aWFsUmVxdWVzdFJlcXVlc3QaOS5jcnlwdG9zLmZsZWV0LnYxLkNhbmNlbE9wZXJhdG9yQ3JlZGVudGlhbFJlcXVlc3RSZXNwb25zZRKBAQoYUmVjb3JkT3BlcmF0b3JDcmVkZW50aWFsEjEuY3J5cHRvcy5mbGVldC52MS5SZWNvcmRPcGVyYXRvckNyZWRlbnRpYWxSZXF1ZXN0GjIuY3J5cHRvcy5mbGVldC52MS5SZWNvcmRPcGVyYXRvckNyZWRlbnRpYWxSZXNwb25zZRKBAQoYUmV2b2tlT3BlcmF0b3JDcmVkZW50aWFsEjEuY3J5cHRvcy5mbGVldC52MS5SZXZva2VPcGVyYXRvckNyZWRlbnRpYWxSZXF1ZXN0GjIuY3J5cHRvcy5mbGVldC52MS5SZXZva2VPcGVyYXRvckNyZWRlbnRpYWxSZXNwb25zZRJ+ChdMaXN0T3BlcmF0b3JDcmVkZW50aWFscxIwLmNyeXB0b3MuZmxlZXQudjEuTGlzdE9wZXJhdG9yQ3JlZGVudGlhbHNSZXF1ZXN0GjEuY3J5cHRvcy5mbGVldC52MS5MaXN0T3BlcmF0b3JDcmVkZW50aWFsc1Jlc3BvbnNlEmYKD0xpc3RPcGVyYXRvckNBcxIoLmNyeXB0b3MuZmxlZXQudjEuTGlzdE9wZXJhdG9yQ0FzUmVxdWVzdBopLmNyeXB0b3MuZmxlZXQudjEuTGlzdE9wZXJhdG9yQ0FzUmVzcG9uc2USbwoSUmVnaXN0ZXJPcGVyYXRvckNBEisuY3J5cHRvcy5mbGVldC52MS5SZWdpc3Rlck9wZXJhdG9yQ0FSZXF1ZXN0GiwuY3J5cHRvcy5mbGVldC52MS5SZWdpc3Rlck9wZXJhdG9yQ0FSZXNwb25zZRJpChBSZXRpcmVPcGVyYXRvckNBEikuY3J5cHRvcy5mbGVldC52MS5SZXRpcmVPcGVyYXRvckNBUmVxdWVzdBoqLmNyeXB0b3MuZmxlZXQudjEuUmV0aXJlT3BlcmF0b3JDQVJlc3BvbnNlEnsKFlNldE9wZXJhdG9yQ0FDUkxTb3VyY2USLy5jcnlwdG9zLmZsZWV0LnYxLlNldE9wZXJhdG9yQ0FDUkxTb3VyY2VSZXF1ZXN0GjAuY3J5cHRvcy5mbGVldC52MS5TZXRPcGVyYXRvckNBQ1JMU291cmNlUmVzcG9uc2USbAoRVXBsb2FkT3BlcmF0b3JDUkwSKi5jcnlwdG9zLmZsZWV0LnYxLlVwbG9hZE9wZXJhdG9yQ1JMUmVxdWVzdBorLmNyeXB0b3MuZmxlZXQudjEuVXBsb2FkT3BlcmF0b3JDUkxSZXNwb25zZRJsChFTZXRPcGVyYXRvckNBT0NTUBIqLmNyeXB0b3MuZmxlZXQudjEuU2V0T3BlcmF0b3JDQU9DU1BSZXF1ZXN0GisuY3J5cHRvcy5mbGVldC52MS5TZXRPcGVyYXRvckNBT0NTUFJlc3BvbnNlEmYKD1ByZXZpZXdBZG9wdGlvbhIoLmNyeXB0b3MuZmxlZXQudjEuUHJldmlld0Fkb3B0aW9uUmVxdWVzdBopLmNyeXB0b3MuZmxlZXQudjEuUHJldmlld0Fkb3B0aW9uUmVzcG9uc2USaQoQTGlzdEluc3RhbGxEaXNrcxIpLmNyeXB0b3MuZmxlZXQudjEuTGlzdEluc3RhbGxEaXNrc1JlcXVlc3QaKi5jcnlwdG9zLmZsZWV0LnYxLkxpc3RJbnN0YWxsRGlza3NSZXNwb25zZRJWCglBZG9wdE5vZGUSIi5jcnlwdG9zLmZsZWV0LnYxLkFkb3B0Tm9kZVJlcXVlc3QaIy5jcnlwdG9zLmZsZWV0LnYxLkFkb3B0Tm9kZVJlc3BvbnNlMAEShwEKGkNvbmZpcm1BZG9wdGlvbkZpbmdlcnByaW50EjMuY3J5cHRvcy5mbGVldC52MS5Db25maXJtQWRvcHRpb25GaW5nZXJwcmludFJlcXVlc3QaNC5jcnlwdG9zLmZsZWV0LnYxLkNvbmZpcm1BZG9wdGlvbkZpbmdlcnByaW50UmVzcG9uc2USaQoQRGVjb21taXNzaW9uTm9kZRIpLmNyeXB0b3MuZmxlZXQudjEuRGVjb21taXNzaW9uTm9kZVJlcXVlc3QaKi5jcnlwdG9zLmZsZWV0LnYxLkRlY29tbWlzc2lvbk5vZGVSZXNwb25zZRJXCgpSZWJvb3ROb2RlEiMuY3J5cHRvcy5mbGVldC52MS5SZWJvb3ROb2RlUmVxdWVzdBokLmNyeXB0b3MuZmxlZXQudjEuUmVib290Tm9kZVJlc3BvbnNlElcKClJlbmFtZU5vZGUSIy5jcnlwdG9zLmZsZWV0LnYxLlJlbmFtZU5vZGVSZXF1ZXN0GiQuY3J5cHRvcy5mbGVldC52MS5SZW5hbWVOb2RlUmVzcG9uc2USVwoKUmVtb3ZlTm9kZRIjLmNyeXB0b3MuZmxlZXQudjEuUmVtb3ZlTm9kZVJlcXVlc3QaJC5jcnlwdG9zLmZsZWV0LnYxLlJlbW92ZU5vZGVSZXNwb25zZRJaCgtMaXN0TWNwS2V5cxIkLmNyeXB0b3MuZmxlZXQudjEuTGlzdE1jcEtleXNSZXF1ZXN0GiUuY3J5cHRvcy5mbGVldC52MS5MaXN0TWNwS2V5c1Jlc3BvbnNlEl0KDFJldm9rZU1jcEtleRIlLmNyeXB0b3MuZmxlZXQudjEuUmV2b2tlTWNwS2V5UmVxdWVzdBomLmNyeXB0b3MuZmxlZXQudjEuUmV2b2tlTWNwS2V5UmVzcG9uc2USXQoMQ3JlYXRlTWNwS2V5EiUuY3J5cHRvcy5mbGVldC52MS5DcmVhdGVNY3BLZXlSZXF1ZXN0GiYuY3J5cHRvcy5mbGVldC52MS5DcmVhdGVNY3BLZXlSZXNwb25zZRJgCg1MaXN0QXBwcm92YWxzEiYuY3J5cHRvcy5mbGVldC52MS5MaXN0QXBwcm92YWxzUmVxdWVzdBonLmNyeXB0b3MuZmxlZXQudjEuTGlzdEFwcHJvdmFsc1Jlc3BvbnNlEmMKDkRlY2lkZUFwcHJvdmFsEicuY3J5cHRvcy5mbGVldC52MS5EZWNpZGVBcHByb3ZhbFJlcXVlc3QaKC5jcnlwdG9zLmZsZWV0LnYxLkRlY2lkZUFwcHJvdmFsUmVzcG9uc2USgQEKGENyZWF0ZUNlcnRpZmljYXRlUmVxdWVzdBIxLmNyeXB0b3MuZmxlZXQudjEuQ3JlYXRlQ2VydGlmaWNhdGVSZXF1ZXN0UmVxdWVzdBoyLmNyeXB0b3MuZmxlZXQudjEuQ3JlYXRlQ2VydGlmaWNhdGVSZXF1ZXN0UmVzcG9uc2USfgoXTGlzdENlcnRpZmljYXRlUmVxdWVzdHMSMC5jcnlwdG9zLmZsZWV0LnYxLkxpc3RDZXJ0aWZpY2F0ZVJlcXVlc3RzUmVxdWVzdBoxLmNyeXB0b3MuZmxlZXQudjEuTGlzdENlcnRpZmljYXRlUmVxdWVzdHNSZXNwb25zZRKEAQoZR2V0Q2VydGlmaWNhdGVSZXF1ZXN0QnlJRBIyLmNyeXB0b3MuZmxlZXQudjEuR2V0Q2VydGlmaWNhdGVSZXF1ZXN0QnlJRFJlcXVlc3QaMy5jcnlwdG9zLmZsZWV0LnYxLkdldENlcnRpZmljYXRlUmVxdWVzdEJ5SURSZXNwb25zZRKBAQoYQ2FuY2VsQ2VydGlmaWNhdGVSZXF1ZXN0EjEuY3J5cHRvcy5mbGVldC52MS5DYW5jZWxDZXJ0aWZpY2F0ZVJlcXVlc3RSZXF1ZXN0GjIuY3J5cHRvcy5mbGVldC52MS5DYW5jZWxDZXJ0aWZpY2F0ZVJlcXVlc3RSZXNwb25zZUJIWkZnaXRodWIuY29tL0NyeXB0T1MtUEtJL2NyeXB0b3MtbWFuYWdlci9nZW4vZ28vY3J5cHRvcy9mbGVldC92MTtmbGVldHYxYgZwcm90bzM", [file_cryptos_fleet_v1_operator_ca, file_cryptos_node_v1_config, file_cryptos_node_v1_node, file_cryptos_node_v1_status]); + fileDesc("ChxjcnlwdG9zL2ZsZWV0L3YxL2ZsZWV0LnByb3RvEhBjcnlwdG9zLmZsZWV0LnYxIhIKEExpc3ROb2Rlc1JlcXVlc3QiQQoRTGlzdE5vZGVzUmVzcG9uc2USLAoFbm9kZXMYASADKAsyHS5jcnlwdG9zLmZsZWV0LnYxLk5vZGVTdW1tYXJ5Ii8KDkdldE5vZGVSZXF1ZXN0EgwKBG5hbWUYASABKAkSDwoHbm9kZV9pZBgCIAEoCSI9Cg9HZXROb2RlUmVzcG9uc2USKgoEbm9kZRgBIAEoCzIcLmNyeXB0b3MuZmxlZXQudjEuTm9kZURldGFpbCI4ChdMaXN0Q2VydGlmaWNhdGVzUmVxdWVzdBIMCgRub2RlGAEgASgJEg8KB25vZGVfaWQYAiABKAkiTwoYTGlzdENlcnRpZmljYXRlc1Jlc3BvbnNlEjMKDGNlcnRpZmljYXRlcxgBIAMoCzIdLmNyeXB0b3MuZmxlZXQudjEuQ2VydGlmaWNhdGUiFQoTTGlzdFByb2ZpbGVzUmVxdWVzdCJKChRMaXN0UHJvZmlsZXNSZXNwb25zZRIyCgVpdGVtcxgBIAMoCzIjLmNyeXB0b3Mubm9kZS52MS5DZXJ0aWZpY2F0ZVByb2ZpbGUiTAoUQ3JlYXRlUHJvZmlsZVJlcXVlc3QSNAoHcHJvZmlsZRgBIAEoCzIjLmNyeXB0b3Mubm9kZS52MS5DZXJ0aWZpY2F0ZVByb2ZpbGUiFwoVQ3JlYXRlUHJvZmlsZVJlc3BvbnNlIkwKFFVwZGF0ZVByb2ZpbGVSZXF1ZXN0EjQKB3Byb2ZpbGUYASABKAsyIy5jcnlwdG9zLm5vZGUudjEuQ2VydGlmaWNhdGVQcm9maWxlIhcKFVVwZGF0ZVByb2ZpbGVSZXNwb25zZSIkChREZWxldGVQcm9maWxlUmVxdWVzdBIMCgRuYW1lGAEgASgJIhcKFURlbGV0ZVByb2ZpbGVSZXNwb25zZSJVChlBcHBseVByb2ZpbGVUb05vZGVSZXF1ZXN0EhEKCW5vZGVfbmFtZRgBIAEoCRIUCgxwcm9maWxlX25hbWUYAiABKAkSDwoHbm9kZV9pZBgDIAEoCSJJChpBcHBseVByb2ZpbGVUb05vZGVSZXNwb25zZRISCgpnZW5lcmF0aW9uGAEgASgEEhcKD3JlcXVpcmVzX3JlYm9vdBgCIAEoCCJBChxTZXRQcm9maWxlUmVxdWVzdGFibGVSZXF1ZXN0EgwKBG5hbWUYASABKAkSEwoLcmVxdWVzdGFibGUYAiABKAgiHwodU2V0UHJvZmlsZVJlcXVlc3RhYmxlUmVzcG9uc2UiIAoeTGlzdFJlcXVlc3RhYmxlUHJvZmlsZXNSZXF1ZXN0IlUKH0xpc3RSZXF1ZXN0YWJsZVByb2ZpbGVzUmVzcG9uc2USMgoFaXRlbXMYASADKAsyIy5jcnlwdG9zLm5vZGUudjEuQ2VydGlmaWNhdGVQcm9maWxlIhUKE0xpc3RBZGFwdGVyc1JlcXVlc3QiSgoUTGlzdEFkYXB0ZXJzUmVzcG9uc2USMgoFaXRlbXMYASADKAsyIy5jcnlwdG9zLmZsZWV0LnYxLkVucm9sbG1lbnRBZGFwdGVyIjkKGFNldEFkYXB0ZXJFbmFibGVkUmVxdWVzdBIMCgRuYW1lGAEgASgJEg8KB2VuYWJsZWQYAiABKAgiUQoZU2V0QWRhcHRlckVuYWJsZWRSZXNwb25zZRI0CgdhZGFwdGVyGAEgASgLMiMuY3J5cHRvcy5mbGVldC52MS5FbnJvbGxtZW50QWRhcHRlciISChBMaXN0QXVkaXRSZXF1ZXN0IkAKEUxpc3RBdWRpdFJlc3BvbnNlEisKBWl0ZW1zGAEgAygLMhwuY3J5cHRvcy5mbGVldC52MS5BdWRpdEV2ZW50IhgKFkxpc3RFbnJvbGxtZW50c1JlcXVlc3QiTQoXTGlzdEVucm9sbG1lbnRzUmVzcG9uc2USMgoFaXRlbXMYASADKAsyIy5jcnlwdG9zLmZsZWV0LnYxLkVucm9sbG1lbnRSZXF1ZXN0IogCCgtOb2RlU3VtbWFyeRIMCgRuYW1lGAEgASgJEg8KB2FkZHJlc3MYAiABKAkSDAoEcm9sZRgDIAEoCRIWCg5pZGVudGl0eV9zdGF0ZRgEIAEoCRIKCgJjbhgFIAEoCRIOCgZpc3N1ZXIYBiABKAkSKAoGaGVhbHRoGAcgASgOMhguY3J5cHRvcy5mbGVldC52MS5IZWFsdGgSFQoNaGVhbHRoX2RldGFpbBgIIAEoCRIKCgJpZBgJIAEoCRIyCglwcm90b2NvbHMYCiADKAsyHy5jcnlwdG9zLm5vZGUudjEuUHJvdG9jb2xTdGF0dXMSFwoPcmVib290X3JlcXVpcmVkGAsgASgIIkkKDE5vZGVJZGVudGl0eRIRCgljaGFpbl9wZW0YASABKAkSEQoJY2hhaW5fZGVyGAIgAygMEhMKC2xlYWZfc2hhMjU2GAMgASgJIqkBCgpOb2RlRGV0YWlsEi4KB3N1bW1hcnkYASABKAsyHS5jcnlwdG9zLmZsZWV0LnYxLk5vZGVTdW1tYXJ5EjAKCGlkZW50aXR5GAIgASgLMh4uY3J5cHRvcy5mbGVldC52MS5Ob2RlSWRlbnRpdHkSFQoNdHBtX2F2YWlsYWJsZRgDIAEoCBISCgpib290X2NvdW50GAQgASgEEg4KBnVwdGltZRgFIAEoCSLYAQoLQ2VydGlmaWNhdGUSDgoGc2VyaWFsGAEgASgJEhIKCnN1YmplY3RfY24YAiABKAkSEwoLaXNzdWVyX25vZGUYAyABKAkSDAoEa2luZBgEIAEoCRIOCgZzdGF0dXMYBSABKAkSEgoKbm90X2JlZm9yZRgGIAEoCRIRCglub3RfYWZ0ZXIYByABKAkSDwoHcHJvZmlsZRgIIAEoCRISCgpyZXZva2VkX2F0GAkgASgJEg4KBnJlYXNvbhgKIAEoCRIWCg5pc3N1ZXJfbm9kZV9pZBgLIAEoCSKNAQoRRW5yb2xsbWVudEFkYXB0ZXISDAoEa2luZBgBIAEoCRIMCgRuYW1lGAIgASgJEhAKCGVuZHBvaW50GAMgASgJEg8KB3Byb2ZpbGUYBCABKAkSDwoHZW5hYmxlZBgFIAEoCBISCgpjaGFsbGVuZ2VzGAYgAygJEhQKDGdwb190ZW1wbGF0ZRgHIAEoCSK8AgoKQXVkaXRFdmVudBIKCgJpZBgBIAEoCRIKCgJhdBgCIAEoCRIMCgRraW5kGAMgASgJEg8KB3N1bW1hcnkYBCABKAkSEwoLdGFyZ2V0X2tpbmQYBSABKAkSEwoLdGFyZ2V0X3BhdGgYBiABKAkSEgoKYWN0b3Jfa2luZBgHIAEoCRIQCghhY3Rvcl9jbhgIIAEoCRIUCgxhY3Rvcl9zZXJpYWwYCSABKAkSDgoGa2V5X2lkGAogASgJEgsKA3ZpYRgLIAEoCRIMCgR0b29sGAwgASgJEhYKDnJlcXVlc3RfZGlnZXN0GA0gASgJEg8KB291dGNvbWUYDiABKAkSEwoLYXBwcm92YWxfaWQYDyABKAkSFwoPYXBwcm92ZXJfc2VyaWFsGBAgASgJEg8KB25vZGVfaWQYESABKAki7wIKEUVucm9sbG1lbnRSZXF1ZXN0EgoKAmlkGAEgASgJEhUKDXByb3Bvc2VkX25hbWUYAiABKAkSDAoEcm9sZRgDIAEoCRIRCglwYXJlbnRfY24YBCABKAkSDwoHYWRkcmVzcxgFIAEoCRIOCgZzdGF0dXMYBiABKAkSGwoTYXR0ZXN0YXRpb25fc3VtbWFyeRgHIAEoCRIbChNhdHRlc3RhdGlvbl9ub2RlX2lkGAggASgJEhQKDGNzcl9rZXlfdHlwZRgJIAEoCRIWCg5jc3Jfc3ViamVjdF9jbhgKIAEoCRIUCgxyZXF1ZXN0ZWRfYXQYCyABKAkSGAoQcmVqZWN0aW9uX3JlYXNvbhgMIAEoCRIaChJhZG1pdHRlZF9ub2RlX25hbWUYDSABKAkSDAoEa2luZBgOIAEoCRIZChFwaW5uZWRfa2V5X3NoYTI1NhgPIAEoCRIYChBhZG1pdHRlZF9ub2RlX2lkGBAgASgJIswBChdDcmVhdGVFbnJvbGxtZW50UmVxdWVzdBIMCgRraW5kGAEgASgJEhUKDW5vZGVfZW5kcG9pbnQYAiABKAkSFgoOYWRtaW5fY2VydF9wZW0YAyABKAkSFQoNYWRtaW5fa2V5X3BlbRgEIAEoCRIOCgZjYV9wZW0YBSABKAkSEgoKY2hpbGRfbm9kZRgGIAEoCRIRCglwYXJlbnRfY24YByABKAkSDwoHcHJvZmlsZRgIIAEoCRIVCg1jaGlsZF9ub2RlX2lkGAkgASgJIlMKGENyZWF0ZUVucm9sbG1lbnRSZXNwb25zZRI3CgplbnJvbGxtZW50GAEgASgLMiMuY3J5cHRvcy5mbGVldC52MS5FbnJvbGxtZW50UmVxdWVzdCJ8ChhBcHByb3ZlRW5yb2xsbWVudFJlcXVlc3QSCgoCaWQYASABKAkSFQoNbm9kZV9lbmRwb2ludBgCIAEoCRIWCg5hZG1pbl9jZXJ0X3BlbRgDIAEoCRIVCg1hZG1pbl9rZXlfcGVtGAQgASgJEg4KBmNhX3BlbRgFIAEoCSJUChlBcHByb3ZlRW5yb2xsbWVudFJlc3BvbnNlEjcKCmVucm9sbG1lbnQYASABKAsyIy5jcnlwdG9zLmZsZWV0LnYxLkVucm9sbG1lbnRSZXF1ZXN0IjUKF1JlamVjdEVucm9sbG1lbnRSZXF1ZXN0EgoKAmlkGAEgASgJEg4KBnJlYXNvbhgCIAEoCSJTChhSZWplY3RFbnJvbGxtZW50UmVzcG9uc2USNwoKZW5yb2xsbWVudBgBIAEoCzIjLmNyeXB0b3MuZmxlZXQudjEuRW5yb2xsbWVudFJlcXVlc3QiDwoNV2hvQW1JUmVxdWVzdCI9ChBPcGVyYXRvcklkZW50aXR5EgoKAmNuGAEgASgJEg4KBnNlcmlhbBgCIAEoCRINCgVsZXZlbBgDIAEoCSJGCg5XaG9BbUlSZXNwb25zZRI0CghvcGVyYXRvchgBIAEoCzIiLmNyeXB0b3MuZmxlZXQudjEuT3BlcmF0b3JJZGVudGl0eSJnChhSZXZva2VDZXJ0aWZpY2F0ZVJlcXVlc3QSEQoJbm9kZV9uYW1lGAEgASgJEhIKCnNlcmlhbF9oZXgYAiABKAkSEwoLcmVhc29uX2NvZGUYAyABKAUSDwoHbm9kZV9pZBgEIAEoCSJYChlSZXZva2VDZXJ0aWZpY2F0ZVJlc3BvbnNlEhIKCnNlcmlhbF9oZXgYASABKAkSEgoKcmV2b2tlZF9hdBgCIAEoCRITCgtyZWFzb25fY29kZRgDIAEoBSI+ChVHZXRDZXJ0aWZpY2F0ZVJlcXVlc3QSEQoJbm9kZV9uYW1lGAEgASgJEhIKCnNlcmlhbF9oZXgYAiABKAkiaAoWR2V0Q2VydGlmaWNhdGVSZXNwb25zZRIXCg9jZXJ0aWZpY2F0ZV9wZW0YASABKAkSEQoJY2hhaW5fcGVtGAIgASgJEg4KBnN0YXR1cxgDIAEoCRISCgpyZXZva2VkX2F0GAQgASgJIl0KEElzc3VlTGVhZlJlcXVlc3QSEQoJbm9kZV9uYW1lGAEgASgJEg8KB2Nzcl9kZXIYAiABKAwSFAoMcHJvZmlsZV9uYW1lGAMgASgJEg8KB25vZGVfaWQYBCABKAkiJQoRSXNzdWVMZWFmUmVzcG9uc2USEAoIY2VydF9kZXIYASABKAwiTAoQUmVrZXlOb2RlUmVxdWVzdBIRCglub2RlX25hbWUYASABKAkSFAoMcHJvZmlsZV9uYW1lGAIgASgJEg8KB25vZGVfaWQYAyABKAkiTQoRUmVrZXlOb2RlUmVzcG9uc2USEgoKc3ViamVjdF9jbhgBIAEoCRIRCglpc3N1ZXJfY24YAiABKAkSEQoJY2hhaW5fbGVuGAMgASgFIjoKFEdldE5vZGVDb25maWdSZXF1ZXN0EhEKCW5vZGVfbmFtZRgBIAEoCRIPCgdub2RlX2lkGAIgASgJIkcKFUdldE5vZGVDb25maWdSZXNwb25zZRIuCgZjb25maWcYASABKAsyHi5jcnlwdG9zLm5vZGUudjEuTWFjaGluZUNvbmZpZyJsChZBcHBseU5vZGVDb25maWdSZXF1ZXN0EhEKCW5vZGVfbmFtZRgBIAEoCRIuCgZjb25maWcYAiABKAsyHi5jcnlwdG9zLm5vZGUudjEuTWFjaGluZUNvbmZpZxIPCgdub2RlX2lkGAMgASgJIkYKF0FwcGx5Tm9kZUNvbmZpZ1Jlc3BvbnNlEhIKCmdlbmVyYXRpb24YASABKAQSFwoPcmVxdWlyZXNfcmVib290GAIgASgIInAKFlNldE5vZGVQcm90b2NvbFJlcXVlc3QSEQoJbm9kZV9uYW1lGAEgASgJEjIKCHByb3RvY29sGAIgASgOMiAuY3J5cHRvcy5ub2RlLnYxLlNlcnZpY2VQcm90b2NvbBIPCgdlbmFibGVkGAMgASgIIkYKF1NldE5vZGVQcm90b2NvbFJlc3BvbnNlEhIKCmdlbmVyYXRpb24YASABKAQSFwoPcmVxdWlyZXNfcmVib290GAIgASgIIkwKEkV4cG9ydENBS2V5UmVxdWVzdBIRCglub2RlX25hbWUYASABKAkSEgoKcGFzc3BocmFzZRgCIAEoDBIPCgdub2RlX2lkGAMgASgJIicKE0V4cG9ydENBS2V5UmVzcG9uc2USEAoIZW52ZWxvcGUYASABKAwiXgoSSW1wb3J0Q0FLZXlSZXF1ZXN0EhEKCW5vZGVfbmFtZRgBIAEoCRIQCghlbnZlbG9wZRgCIAEoDBISCgpwYXNzcGhyYXNlGAMgASgMEg8KB25vZGVfaWQYBCABKAkiPAoTSW1wb3J0Q0FLZXlSZXNwb25zZRISCgpzdWJqZWN0X2NuGAEgASgJEhEKCWlzc3Vlcl9jbhgCIAEoCSJvCh9SZXZva2VPcGVyYXRvckNyZWRlbnRpYWxSZXF1ZXN0EhIKCnNlcmlhbF9oZXgYASABKAkSEwoLcmVhc29uX2NvZGUYAiABKAUSFQoNaXNzdWVyX3NoYTI1NhgDIAEoCRIMCgRub3RlGAQgASgJInMKIFJldm9rZU9wZXJhdG9yQ3JlZGVudGlhbFJlc3BvbnNlEhIKCnNlcmlhbF9oZXgYASABKAkSEgoKcmV2b2tlZF9hdBgCIAEoCRIVCg1pc3N1ZXJfc2hhMjU2GAMgASgJEhAKCHdhcm5pbmdzGAQgAygJIiAKHkxpc3RPcGVyYXRvckNyZWRlbnRpYWxzUmVxdWVzdCKNAgoST3BlcmF0b3JDcmVkZW50aWFsEhMKC2NvbW1vbl9uYW1lGAEgASgJEhIKCnNlcmlhbF9oZXgYAiABKAkSDQoFbGV2ZWwYAyABKAkSEQoJbm90X2FmdGVyGAQgASgJEg8KB3Jldm9rZWQYBSABKAgSDAoEa2luZBgGIAEoCRIVCg1pc3N1ZXJfc2hhMjU2GAcgASgJEg0KBWVtYWlsGAggASgJEhEKCWZ1bGxfbmFtZRgJIAEoCRISCgpkZW55bGlzdGVkGAogASgIEhMKC2NybF9yZXZva2VkGAsgASgIEhUKDWZpcnN0X3NlZW5fYXQYDCABKAkSFAoMbGFzdF9zZWVuX2F0GA0gASgJIlYKH0xpc3RPcGVyYXRvckNyZWRlbnRpYWxzUmVzcG9uc2USMwoFaXRlbXMYASADKAsyJC5jcnlwdG9zLmZsZWV0LnYxLk9wZXJhdG9yQ3JlZGVudGlhbCJqCiZDcmVhdGVPcGVyYXRvckNyZWRlbnRpYWxSZXF1ZXN0UmVxdWVzdBINCgVsZXZlbBgBIAEoCRINCgVlbWFpbBgCIAEoCRIRCglmdWxsX25hbWUYAyABKAkSDwoHY3NyX2RlchgEIAEoDCKUAQonQ3JlYXRlT3BlcmF0b3JDcmVkZW50aWFsUmVxdWVzdFJlc3BvbnNlEhIKCnJlcXVlc3RfaWQYASABKAkSDwoHY3NyX3BlbRgCIAEoCRIXCg9leHRmaWxlX3NlY3Rpb24YAyABKAkSFwoPb3BlbnNzbF9jb21tYW5kGAQgASgJEhIKCmV4cGlyZXNfYXQYBSABKAkiNgolTGlzdE9wZXJhdG9yQ3JlZGVudGlhbFJlcXVlc3RzUmVxdWVzdBINCgVzdGF0ZRgBIAEoCSJkCiZMaXN0T3BlcmF0b3JDcmVkZW50aWFsUmVxdWVzdHNSZXNwb25zZRI6CgVpdGVtcxgBIAMoCzIrLmNyeXB0b3MuZmxlZXQudjEuT3BlcmF0b3JDcmVkZW50aWFsUmVxdWVzdCI8CiZDYW5jZWxPcGVyYXRvckNyZWRlbnRpYWxSZXF1ZXN0UmVxdWVzdBISCgpyZXF1ZXN0X2lkGAEgASgJImcKJ0NhbmNlbE9wZXJhdG9yQ3JlZGVudGlhbFJlcXVlc3RSZXNwb25zZRI8CgdyZXF1ZXN0GAEgASgLMisuY3J5cHRvcy5mbGVldC52MS5PcGVyYXRvckNyZWRlbnRpYWxSZXF1ZXN0ItEBChlPcGVyYXRvckNyZWRlbnRpYWxSZXF1ZXN0EgoKAmlkGAEgASgJEg0KBWxldmVsGAIgASgJEg0KBWVtYWlsGAMgASgJEhEKCWZ1bGxfbmFtZRgEIAEoCRIPCgdjc3JfcGVtGAUgASgJEg0KBXN0YXRlGAYgASgJEhUKDWNyZWF0ZWRfYnlfY24YByABKAkSEgoKY3JlYXRlZF9hdBgIIAEoCRISCgpleHBpcmVzX2F0GAkgASgJEhgKEGNvbXBsZXRlZF9zZXJpYWwYCiABKAkiWgofUmVjb3JkT3BlcmF0b3JDcmVkZW50aWFsUmVxdWVzdBIQCghjZXJ0X2RlchgBIAEoDBISCgpyZXF1ZXN0X2lkGAIgASgJEhEKCWZ1bGxfbmFtZRgDIAEoCSJuCiBSZWNvcmRPcGVyYXRvckNyZWRlbnRpYWxSZXNwb25zZRI4CgpjcmVkZW50aWFsGAEgASgLMiQuY3J5cHRvcy5mbGVldC52MS5PcGVyYXRvckNyZWRlbnRpYWwSEAoId2FybmluZ3MYAiADKAkiGAoWTGlzdE9wZXJhdG9yQ0FzUmVxdWVzdCJGChdMaXN0T3BlcmF0b3JDQXNSZXNwb25zZRIrCgVpdGVtcxgBIAMoCzIcLmNyeXB0b3MuZmxlZXQudjEuT3BlcmF0b3JDQSKQAgoZUmVnaXN0ZXJPcGVyYXRvckNBUmVxdWVzdBITCgtjYV9jZXJ0X2RlchgBIAEoDBINCgN1cmwYAiABKAlIABIRCgdjcmxfZGVyGAMgASgMSAASDgoEbm9uZRgEIAEoCEgAEi0KCW9jc3BfbW9kZRgFIAEoDjIaLmNyeXB0b3MuZmxlZXQudjEuT2NzcE1vZGUSEAoIb2NzcF91cmwYBiABKAkSRQoQYWNrbm93bGVkZ2VtZW50cxgHIAMoDjIrLmNyeXB0b3MuZmxlZXQudjEuT3BlcmF0b3JDQUFja25vd2xlZGdlbWVudBIWCg5jb25maXJtX3NoYTI1NhgIIAEoCUIMCgpjcmxfc291cmNlIrABChpSZWdpc3Rlck9wZXJhdG9yQ0FSZXNwb25zZRIxCgtvcGVyYXRvcl9jYRgBIAEoCzIcLmNyeXB0b3MuZmxlZXQudjEuT3BlcmF0b3JDQRIRCgljb25maXJtZWQYAiABKAgSFQoNYWRtaW5fZXh0ZmlsZRgDIAEoCRI1CgpvY3NwX3Byb2JlGAQgASgLMiEuY3J5cHRvcy5mbGVldC52MS5PY3NwUHJvYmVSZXN1bHQiTAoXUmV0aXJlT3BlcmF0b3JDQVJlcXVlc3QSDgoGc2hhMjU2GAEgASgJEiEKGWlfdW5kZXJzdGFuZF9zZWxmX2xvY2tvdXQYAiABKAgiTQoYUmV0aXJlT3BlcmF0b3JDQVJlc3BvbnNlEjEKC29wZXJhdG9yX2NhGAEgASgLMhwuY3J5cHRvcy5mbGVldC52MS5PcGVyYXRvckNBIrYBCh1TZXRPcGVyYXRvckNBQ1JMU291cmNlUmVxdWVzdBIOCgZzaGEyNTYYASABKAkSDQoDdXJsGAIgASgJSAASDgoEbm9uZRgDIAEoCEgAEhEKB2NybF9kZXIYBSABKAxIABJFChBhY2tub3dsZWRnZW1lbnRzGAQgAygOMisuY3J5cHRvcy5mbGVldC52MS5PcGVyYXRvckNBQWNrbm93bGVkZ2VtZW50QgwKCmNybF9zb3VyY2UiUwoeU2V0T3BlcmF0b3JDQUNSTFNvdXJjZVJlc3BvbnNlEjEKC29wZXJhdG9yX2NhGAEgASgLMhwuY3J5cHRvcy5mbGVldC52MS5PcGVyYXRvckNBIjsKGFVwbG9hZE9wZXJhdG9yQ1JMUmVxdWVzdBIOCgZzaGEyNTYYASABKAkSDwoHY3JsX2RlchgCIAEoDCJOChlVcGxvYWRPcGVyYXRvckNSTFJlc3BvbnNlEjEKC29wZXJhdG9yX2NhGAEgASgLMhwuY3J5cHRvcy5mbGVldC52MS5PcGVyYXRvckNBImsKGFNldE9wZXJhdG9yQ0FPQ1NQUmVxdWVzdBIOCgZzaGEyNTYYASABKAkSLQoJb2NzcF9tb2RlGAIgASgOMhouY3J5cHRvcy5mbGVldC52MS5PY3NwTW9kZRIQCghvY3NwX3VybBgDIAEoCSKFAQoZU2V0T3BlcmF0b3JDQU9DU1BSZXNwb25zZRIxCgtvcGVyYXRvcl9jYRgBIAEoCzIcLmNyeXB0b3MuZmxlZXQudjEuT3BlcmF0b3JDQRI1CgpvY3NwX3Byb2JlGAIgASgLMiEuY3J5cHRvcy5mbGVldC52MS5PY3NwUHJvYmVSZXN1bHQiKgoWUHJldmlld0Fkb3B0aW9uUmVxdWVzdBIQCghlbmRwb2ludBgBIAEoCSI/ChdQcmV2aWV3QWRvcHRpb25SZXNwb25zZRITCgtjZXJ0X3NoYTI1NhgBIAEoCRIPCgdzdWJqZWN0GAIgASgJIkcKF0xpc3RJbnN0YWxsRGlza3NSZXF1ZXN0EhAKCGVuZHBvaW50GAEgASgJEhoKEnBpbm5lZF9jZXJ0X3NoYTI1NhgCIAEoCSJHChhMaXN0SW5zdGFsbERpc2tzUmVzcG9uc2USKwoFZGlza3MYASADKAsyHC5jcnlwdG9zLm5vZGUudjEuSW5zdGFsbERpc2sicAoQQWRvcHROb2RlUmVxdWVzdBIQCghlbmRwb2ludBgBIAEoCRIaChJwaW5uZWRfY2VydF9zaGEyNTYYAiABKAkSLgoGY29uZmlnGAMgASgLMh4uY3J5cHRvcy5ub2RlLnYxLk1hY2hpbmVDb25maWcihQEKEUFkb3B0Tm9kZVJlc3BvbnNlEg0KBXBoYXNlGAEgASgJEg4KBmRldGFpbBgCIAEoCRIMCgRkb25lGAMgASgIEg8KB25vZGVfaWQYBCABKAkSEwoLYWRvcHRpb25faWQYBSABKAkSHQoVcHJlc2VudGVkX2NlcnRfc2hhMjU2GAYgASgJIk0KIUNvbmZpcm1BZG9wdGlvbkZpbmdlcnByaW50UmVxdWVzdBITCgthZG9wdGlvbl9pZBgBIAEoCRITCgtjZXJ0X3NoYTI1NhgCIAEoCSIkCiJDb25maXJtQWRvcHRpb25GaW5nZXJwcmludFJlc3BvbnNlIloKF0RlY29tbWlzc2lvbk5vZGVSZXF1ZXN0EhEKCW5vZGVfbmFtZRgBIAEoCRIbChNjb25maXJtX2NvbW1vbl9uYW1lGAIgASgJEg8KB25vZGVfaWQYAyABKAkiLQoYRGVjb21taXNzaW9uTm9kZVJlc3BvbnNlEhEKCXJlYm9vdGluZxgBIAEoCCJhChFSZWJvb3ROb2RlUmVxdWVzdBIRCglub2RlX25hbWUYASABKAkSFQoNY29uZmlybV9jYV9jbhgCIAEoCRIRCglwb3dlcl9vZmYYAyABKAgSDwoHbm9kZV9pZBgEIAEoCSInChJSZWJvb3ROb2RlUmVzcG9uc2USEQoJcmVib290aW5nGAEgASgIIjYKEVJlbmFtZU5vZGVSZXF1ZXN0Eg8KB25vZGVfaWQYASABKAkSEAoIbmV3X25hbWUYAiABKAkiQQoSUmVuYW1lTm9kZVJlc3BvbnNlEisKBG5vZGUYASABKAsyHS5jcnlwdG9zLmZsZWV0LnYxLk5vZGVTdW1tYXJ5IjoKEVJlbW92ZU5vZGVSZXF1ZXN0Eg8KB25vZGVfaWQYASABKAkSFAoMY29uZmlybV9uYW1lGAIgASgJIkEKElJlbW92ZU5vZGVSZXNwb25zZRIrCgRub2RlGAEgASgLMh0uY3J5cHRvcy5mbGVldC52MS5Ob2RlU3VtbWFyeSIhChJMaXN0TWNwS2V5c1JlcXVlc3QSCwoDYWxsGAEgASgIIj4KE0xpc3RNY3BLZXlzUmVzcG9uc2USJwoFaXRlbXMYASADKAsyGC5jcnlwdG9zLmZsZWV0LnYxLk1jcEtleSIhChNSZXZva2VNY3BLZXlSZXF1ZXN0EgoKAmlkGAEgASgJIkEKFFJldm9rZU1jcEtleVJlc3BvbnNlEikKB21jcF9rZXkYASABKAsyGC5jcnlwdG9zLmZsZWV0LnYxLk1jcEtleSI7ChNDcmVhdGVNY3BLZXlSZXF1ZXN0Eg0KBWxhYmVsGAEgASgJEhUKDWxldmVsX2NlaWxpbmcYAiABKAkiWAoUQ3JlYXRlTWNwS2V5UmVzcG9uc2USFQoNcGxhaW50ZXh0X2tleRgBIAEoCRIpCgdtY3Bfa2V5GAIgASgLMhguY3J5cHRvcy5mbGVldC52MS5NY3BLZXkiuwEKBk1jcEtleRIKCgJpZBgBIAEoCRINCgVsYWJlbBgCIAEoCRITCgtjbGllbnRfbmFtZRgDIAEoCRITCgtvcGVyYXRvcl9jbhgEIAEoCRIXCg9vcGVyYXRvcl9zZXJpYWwYBSABKAkSFQoNbGV2ZWxfY2VpbGluZxgGIAEoCRISCgpjcmVhdGVkX2F0GAcgASgJEhQKDGxhc3RfdXNlZF9hdBgIIAEoCRISCgpyZXZva2VkX2F0GAkgASgJIiYKFExpc3RBcHByb3ZhbHNSZXF1ZXN0Eg4KBnN0YXR1cxgBIAEoCSJCChVMaXN0QXBwcm92YWxzUmVzcG9uc2USKQoFaXRlbXMYASADKAsyGi5jcnlwdG9zLmZsZWV0LnYxLkFwcHJvdmFsIjQKFURlY2lkZUFwcHJvdmFsUmVxdWVzdBIKCgJpZBgBIAEoCRIPCgdhcHByb3ZlGAIgASgIIkYKFkRlY2lkZUFwcHJvdmFsUmVzcG9uc2USLAoIYXBwcm92YWwYASABKAsyGi5jcnlwdG9zLmZsZWV0LnYxLkFwcHJvdmFsIrcCCghBcHByb3ZhbBIKCgJpZBgBIAEoCRIMCgR0b29sGAIgASgJEg8KB3N1bW1hcnkYAyABKAkSFgoOcmVxdWVzdF9kaWdlc3QYBCABKAkSFwoPcmVxdWVzdGVkX2J5X2NuGAUgASgJEhsKE3JlcXVlc3RlZF9ieV9zZXJpYWwYBiABKAkSDgoGa2V5X2lkGAcgASgJEhYKDnJlcXVpcmVkX2xldmVsGAggASgJEhIKCmNyZWF0ZWRfYXQYCSABKAkSEgoKZXhwaXJlc19hdBgKIAEoCRIOCgZzdGF0dXMYCyABKAkSFQoNZGVjaWRlZF9ieV9jbhgMIAEoCRIZChFkZWNpZGVkX2J5X3NlcmlhbBgNIAEoCRISCgpkZWNpZGVkX2F0GA4gASgJEgwKBGtpbmQYDyABKAkirwIKEkNlcnRpZmljYXRlUmVxdWVzdBIKCgJpZBgBIAEoCRIUCgxwcm9maWxlX25hbWUYAiABKAkSDwoHY3NyX3BlbRgDIAEoCRIMCgRub3RlGAQgASgJEhcKD3JlcXVlc3RlZF9ieV9jbhgFIAEoCRIbChNyZXF1ZXN0ZWRfYnlfc2VyaWFsGAYgASgJEg0KBXN0YXRlGAcgASgJEhMKC2FwcHJvdmFsX2lkGAggASgJEhcKD2NlcnRpZmljYXRlX3BlbRgJIAEoCRIWCg5mYWlsdXJlX3JlYXNvbhgKIAEoCRISCgpjcmVhdGVkX2F0GAsgASgJEhIKCmV4cGlyZXNfYXQYDCABKAkSEgoKZGVjaWRlZF9hdBgNIAEoCRIRCglpc3N1ZWRfYXQYDiABKAkiVgofQ3JlYXRlQ2VydGlmaWNhdGVSZXF1ZXN0UmVxdWVzdBIUCgxwcm9maWxlX25hbWUYASABKAkSDwoHY3NyX2RlchgCIAEoDBIMCgRub3RlGAMgASgJIlkKIENyZWF0ZUNlcnRpZmljYXRlUmVxdWVzdFJlc3BvbnNlEjUKB3JlcXVlc3QYASABKAsyJC5jcnlwdG9zLmZsZWV0LnYxLkNlcnRpZmljYXRlUmVxdWVzdCJCCh5MaXN0Q2VydGlmaWNhdGVSZXF1ZXN0c1JlcXVlc3QSDQoFc3RhdGUYASABKAkSEQoJbWluZV9vbmx5GAIgASgIIlYKH0xpc3RDZXJ0aWZpY2F0ZVJlcXVlc3RzUmVzcG9uc2USMwoFaXRlbXMYASADKAsyJC5jcnlwdG9zLmZsZWV0LnYxLkNlcnRpZmljYXRlUmVxdWVzdCIuCiBHZXRDZXJ0aWZpY2F0ZVJlcXVlc3RCeUlEUmVxdWVzdBIKCgJpZBgBIAEoCSJaCiFHZXRDZXJ0aWZpY2F0ZVJlcXVlc3RCeUlEUmVzcG9uc2USNQoHcmVxdWVzdBgBIAEoCzIkLmNyeXB0b3MuZmxlZXQudjEuQ2VydGlmaWNhdGVSZXF1ZXN0Ii0KH0NhbmNlbENlcnRpZmljYXRlUmVxdWVzdFJlcXVlc3QSCgoCaWQYASABKAkiWQogQ2FuY2VsQ2VydGlmaWNhdGVSZXF1ZXN0UmVzcG9uc2USNQoHcmVxdWVzdBgBIAEoCzIkLmNyeXB0b3MuZmxlZXQudjEuQ2VydGlmaWNhdGVSZXF1ZXN0IkQKHkxpc3ROb2RlVHNhQ2VydGlmaWNhdGVzUmVxdWVzdBIRCglub2RlX25hbWUYASABKAkSDwoHbm9kZV9pZBgCIAEoCSKGAQoSTm9kZVRzYUNlcnRpZmljYXRlEhAKCGNlcnRfcGVtGAEgASgJEhIKCnNlcmlhbF9oZXgYAiABKAkSEgoKc2hhMjU2X2hleBgDIAEoCRISCgpub3RfYmVmb3JlGAQgASgJEhEKCW5vdF9hZnRlchgFIAEoCRIPCgdjdXJyZW50GAYgASgIIl0KH0xpc3ROb2RlVHNhQ2VydGlmaWNhdGVzUmVzcG9uc2USOgoMY2VydGlmaWNhdGVzGAEgAygLMiQuY3J5cHRvcy5mbGVldC52MS5Ob2RlVHNhQ2VydGlmaWNhdGUiXgofVmFsaWRhdGVDZXJ0aWZpY2F0ZUNoYWluUmVxdWVzdBIRCglub2RlX25hbWUYASABKAkSDwoHbm9kZV9pZBgCIAEoCRIXCg9jZXJ0aWZpY2F0ZV9wZW0YAyABKAkiewogVmFsaWRhdGVDZXJ0aWZpY2F0ZUNoYWluUmVzcG9uc2USDQoFdmFsaWQYASABKAgSDgoGcmVhc29uGAIgASgJEg8KB3N1YmplY3QYAyABKAkSDgoGaXNzdWVyGAQgASgJEhcKD25vZGVfY2Ffc3ViamVjdBgFIAEoCSKuAQoaTGlzdE5vZGVBdWRpdEV2ZW50c1JlcXVlc3QSEQoJbm9kZV9uYW1lGAEgASgJEg8KB25vZGVfaWQYAiABKAkSEQoJcGFnZV9zaXplGAMgASgFEhIKCnBhZ2VfdG9rZW4YBCABKAkSEQoJZnJvbV90aW1lGAUgASgJEg8KB3RvX3RpbWUYBiABKAkSEgoKZXZlbnRfdHlwZRgHIAEoCRINCgVhY3RvchgIIAEoCSKQAgoOTm9kZUF1ZGl0RXZlbnQSCwoDc2VxGAEgASgEEgoKAnRzGAIgASgJEhUKDWFjdG9yX3N1YmplY3QYAyABKAkSEgoKcnBjX21ldGhvZBgEIAEoCRIPCgdvdXRjb21lGAUgASgJEj4KB2RldGFpbHMYBiADKAsyLS5jcnlwdG9zLmZsZWV0LnYxLk5vZGVBdWRpdEV2ZW50LkRldGFpbHNFbnRyeRIYChBlbnRyeV9zaGEyNTZfaGV4GAcgASgJEg4KBnRhcmdldBgIIAEoCRIPCgdzdW1tYXJ5GAkgASgJGi4KDERldGFpbHNFbnRyeRILCgNrZXkYASABKAkSDQoFdmFsdWUYAiABKAk6AjgBImkKG0xpc3ROb2RlQXVkaXRFdmVudHNSZXNwb25zZRIxCgdlbnRyaWVzGAEgAygLMiAuY3J5cHRvcy5mbGVldC52MS5Ob2RlQXVkaXRFdmVudBIXCg9uZXh0X3BhZ2VfdG9rZW4YAiABKAkiQQobVmVyaWZ5Tm9kZUF1ZGl0Q2hhaW5SZXF1ZXN0EhEKCW5vZGVfbmFtZRgBIAEoCRIPCgdub2RlX2lkGAIgASgJInIKHFZlcmlmeU5vZGVBdWRpdENoYWluUmVzcG9uc2USEwoLZW50cnlfY291bnQYASABKAQSDgoGaW50YWN0GAIgASgIEh0KFWZpcnN0X2Jyb2tlbl9zZXF1ZW5jZRgDIAEoBBIOCgZyZWFzb24YBCABKAkihAEKEU5vZGVTY2VwQ2hhbGxlbmdlEgoKAmlkGAEgASgJEg8KB3Byb2ZpbGUYAiABKAkSEwoLYm91bmRfbmFtZXMYAyADKAkSEgoKY3JlYXRlZF9hdBgEIAEoCRISCgpleHBpcmVzX2F0GAUgASgJEhUKDWNyZWF0ZWRfYnlfY24YBiABKAkifQocTWludE5vZGVTY2VwQ2hhbGxlbmdlUmVxdWVzdBIRCglub2RlX25hbWUYASABKAkSDwoHbm9kZV9pZBgCIAEoCRIPCgdwcm9maWxlGAMgASgJEhMKC3R0bF9zZWNvbmRzGAQgASgNEhMKC2JvdW5kX25hbWVzGAUgAygJInMKHU1pbnROb2RlU2NlcENoYWxsZW5nZVJlc3BvbnNlEhoKEmNoYWxsZW5nZV9wYXNzd29yZBgBIAEoCRI2CgljaGFsbGVuZ2UYAiABKAsyIy5jcnlwdG9zLmZsZWV0LnYxLk5vZGVTY2VwQ2hhbGxlbmdlIkMKHUxpc3ROb2RlU2NlcENoYWxsZW5nZXNSZXF1ZXN0EhEKCW5vZGVfbmFtZRgBIAEoCRIPCgdub2RlX2lkGAIgASgJIlkKHkxpc3ROb2RlU2NlcENoYWxsZW5nZXNSZXNwb25zZRI3CgpjaGFsbGVuZ2VzGAEgAygLMiMuY3J5cHRvcy5mbGVldC52MS5Ob2RlU2NlcENoYWxsZW5nZSJQCh5SZXZva2VOb2RlU2NlcENoYWxsZW5nZVJlcXVlc3QSEQoJbm9kZV9uYW1lGAEgASgJEg8KB25vZGVfaWQYAiABKAkSCgoCaWQYAyABKAkiWQofUmV2b2tlTm9kZVNjZXBDaGFsbGVuZ2VSZXNwb25zZRI2CgljaGFsbGVuZ2UYASABKAsyIy5jcnlwdG9zLmZsZWV0LnYxLk5vZGVTY2VwQ2hhbGxlbmdlKlIKBkhlYWx0aBIWChJIRUFMVEhfVU5TUEVDSUZJRUQQABINCglIRUFMVEhfVVAQARIPCgtIRUFMVEhfRE9XThACEhAKDEhFQUxUSF9FUlJPUhADMoI2CgxGbGVldFNlcnZpY2USVAoJTGlzdE5vZGVzEiIuY3J5cHRvcy5mbGVldC52MS5MaXN0Tm9kZXNSZXF1ZXN0GiMuY3J5cHRvcy5mbGVldC52MS5MaXN0Tm9kZXNSZXNwb25zZRJOCgdHZXROb2RlEiAuY3J5cHRvcy5mbGVldC52MS5HZXROb2RlUmVxdWVzdBohLmNyeXB0b3MuZmxlZXQudjEuR2V0Tm9kZVJlc3BvbnNlEmkKEExpc3RDZXJ0aWZpY2F0ZXMSKS5jcnlwdG9zLmZsZWV0LnYxLkxpc3RDZXJ0aWZpY2F0ZXNSZXF1ZXN0GiouY3J5cHRvcy5mbGVldC52MS5MaXN0Q2VydGlmaWNhdGVzUmVzcG9uc2USXQoMTGlzdFByb2ZpbGVzEiUuY3J5cHRvcy5mbGVldC52MS5MaXN0UHJvZmlsZXNSZXF1ZXN0GiYuY3J5cHRvcy5mbGVldC52MS5MaXN0UHJvZmlsZXNSZXNwb25zZRJgCg1DcmVhdGVQcm9maWxlEiYuY3J5cHRvcy5mbGVldC52MS5DcmVhdGVQcm9maWxlUmVxdWVzdBonLmNyeXB0b3MuZmxlZXQudjEuQ3JlYXRlUHJvZmlsZVJlc3BvbnNlEmAKDVVwZGF0ZVByb2ZpbGUSJi5jcnlwdG9zLmZsZWV0LnYxLlVwZGF0ZVByb2ZpbGVSZXF1ZXN0GicuY3J5cHRvcy5mbGVldC52MS5VcGRhdGVQcm9maWxlUmVzcG9uc2USYAoNRGVsZXRlUHJvZmlsZRImLmNyeXB0b3MuZmxlZXQudjEuRGVsZXRlUHJvZmlsZVJlcXVlc3QaJy5jcnlwdG9zLmZsZWV0LnYxLkRlbGV0ZVByb2ZpbGVSZXNwb25zZRJvChJBcHBseVByb2ZpbGVUb05vZGUSKy5jcnlwdG9zLmZsZWV0LnYxLkFwcGx5UHJvZmlsZVRvTm9kZVJlcXVlc3QaLC5jcnlwdG9zLmZsZWV0LnYxLkFwcGx5UHJvZmlsZVRvTm9kZVJlc3BvbnNlEngKFVNldFByb2ZpbGVSZXF1ZXN0YWJsZRIuLmNyeXB0b3MuZmxlZXQudjEuU2V0UHJvZmlsZVJlcXVlc3RhYmxlUmVxdWVzdBovLmNyeXB0b3MuZmxlZXQudjEuU2V0UHJvZmlsZVJlcXVlc3RhYmxlUmVzcG9uc2USfgoXTGlzdFJlcXVlc3RhYmxlUHJvZmlsZXMSMC5jcnlwdG9zLmZsZWV0LnYxLkxpc3RSZXF1ZXN0YWJsZVByb2ZpbGVzUmVxdWVzdBoxLmNyeXB0b3MuZmxlZXQudjEuTGlzdFJlcXVlc3RhYmxlUHJvZmlsZXNSZXNwb25zZRJdCgxMaXN0QWRhcHRlcnMSJS5jcnlwdG9zLmZsZWV0LnYxLkxpc3RBZGFwdGVyc1JlcXVlc3QaJi5jcnlwdG9zLmZsZWV0LnYxLkxpc3RBZGFwdGVyc1Jlc3BvbnNlEmwKEVNldEFkYXB0ZXJFbmFibGVkEiouY3J5cHRvcy5mbGVldC52MS5TZXRBZGFwdGVyRW5hYmxlZFJlcXVlc3QaKy5jcnlwdG9zLmZsZWV0LnYxLlNldEFkYXB0ZXJFbmFibGVkUmVzcG9uc2USZgoPU2V0Tm9kZVByb3RvY29sEiguY3J5cHRvcy5mbGVldC52MS5TZXROb2RlUHJvdG9jb2xSZXF1ZXN0GikuY3J5cHRvcy5mbGVldC52MS5TZXROb2RlUHJvdG9jb2xSZXNwb25zZRJUCglMaXN0QXVkaXQSIi5jcnlwdG9zLmZsZWV0LnYxLkxpc3RBdWRpdFJlcXVlc3QaIy5jcnlwdG9zLmZsZWV0LnYxLkxpc3RBdWRpdFJlc3BvbnNlEmYKD0xpc3RFbnJvbGxtZW50cxIoLmNyeXB0b3MuZmxlZXQudjEuTGlzdEVucm9sbG1lbnRzUmVxdWVzdBopLmNyeXB0b3MuZmxlZXQudjEuTGlzdEVucm9sbG1lbnRzUmVzcG9uc2USaQoQQ3JlYXRlRW5yb2xsbWVudBIpLmNyeXB0b3MuZmxlZXQudjEuQ3JlYXRlRW5yb2xsbWVudFJlcXVlc3QaKi5jcnlwdG9zLmZsZWV0LnYxLkNyZWF0ZUVucm9sbG1lbnRSZXNwb25zZRJsChFBcHByb3ZlRW5yb2xsbWVudBIqLmNyeXB0b3MuZmxlZXQudjEuQXBwcm92ZUVucm9sbG1lbnRSZXF1ZXN0GisuY3J5cHRvcy5mbGVldC52MS5BcHByb3ZlRW5yb2xsbWVudFJlc3BvbnNlEmkKEFJlamVjdEVucm9sbG1lbnQSKS5jcnlwdG9zLmZsZWV0LnYxLlJlamVjdEVucm9sbG1lbnRSZXF1ZXN0GiouY3J5cHRvcy5mbGVldC52MS5SZWplY3RFbnJvbGxtZW50UmVzcG9uc2USSwoGV2hvQW1JEh8uY3J5cHRvcy5mbGVldC52MS5XaG9BbUlSZXF1ZXN0GiAuY3J5cHRvcy5mbGVldC52MS5XaG9BbUlSZXNwb25zZRJsChFSZXZva2VDZXJ0aWZpY2F0ZRIqLmNyeXB0b3MuZmxlZXQudjEuUmV2b2tlQ2VydGlmaWNhdGVSZXF1ZXN0GisuY3J5cHRvcy5mbGVldC52MS5SZXZva2VDZXJ0aWZpY2F0ZVJlc3BvbnNlEmMKDkdldENlcnRpZmljYXRlEicuY3J5cHRvcy5mbGVldC52MS5HZXRDZXJ0aWZpY2F0ZVJlcXVlc3QaKC5jcnlwdG9zLmZsZWV0LnYxLkdldENlcnRpZmljYXRlUmVzcG9uc2UScgoTTGlzdE5vZGVBdWRpdEV2ZW50cxIsLmNyeXB0b3MuZmxlZXQudjEuTGlzdE5vZGVBdWRpdEV2ZW50c1JlcXVlc3QaLS5jcnlwdG9zLmZsZWV0LnYxLkxpc3ROb2RlQXVkaXRFdmVudHNSZXNwb25zZRJ1ChRWZXJpZnlOb2RlQXVkaXRDaGFpbhItLmNyeXB0b3MuZmxlZXQudjEuVmVyaWZ5Tm9kZUF1ZGl0Q2hhaW5SZXF1ZXN0Gi4uY3J5cHRvcy5mbGVldC52MS5WZXJpZnlOb2RlQXVkaXRDaGFpblJlc3BvbnNlEoEBChhWYWxpZGF0ZUNlcnRpZmljYXRlQ2hhaW4SMS5jcnlwdG9zLmZsZWV0LnYxLlZhbGlkYXRlQ2VydGlmaWNhdGVDaGFpblJlcXVlc3QaMi5jcnlwdG9zLmZsZWV0LnYxLlZhbGlkYXRlQ2VydGlmaWNhdGVDaGFpblJlc3BvbnNlEn4KF0xpc3ROb2RlVHNhQ2VydGlmaWNhdGVzEjAuY3J5cHRvcy5mbGVldC52MS5MaXN0Tm9kZVRzYUNlcnRpZmljYXRlc1JlcXVlc3QaMS5jcnlwdG9zLmZsZWV0LnYxLkxpc3ROb2RlVHNhQ2VydGlmaWNhdGVzUmVzcG9uc2USeAoVTWludE5vZGVTY2VwQ2hhbGxlbmdlEi4uY3J5cHRvcy5mbGVldC52MS5NaW50Tm9kZVNjZXBDaGFsbGVuZ2VSZXF1ZXN0Gi8uY3J5cHRvcy5mbGVldC52MS5NaW50Tm9kZVNjZXBDaGFsbGVuZ2VSZXNwb25zZRJ7ChZMaXN0Tm9kZVNjZXBDaGFsbGVuZ2VzEi8uY3J5cHRvcy5mbGVldC52MS5MaXN0Tm9kZVNjZXBDaGFsbGVuZ2VzUmVxdWVzdBowLmNyeXB0b3MuZmxlZXQudjEuTGlzdE5vZGVTY2VwQ2hhbGxlbmdlc1Jlc3BvbnNlEn4KF1Jldm9rZU5vZGVTY2VwQ2hhbGxlbmdlEjAuY3J5cHRvcy5mbGVldC52MS5SZXZva2VOb2RlU2NlcENoYWxsZW5nZVJlcXVlc3QaMS5jcnlwdG9zLmZsZWV0LnYxLlJldm9rZU5vZGVTY2VwQ2hhbGxlbmdlUmVzcG9uc2USVAoJSXNzdWVMZWFmEiIuY3J5cHRvcy5mbGVldC52MS5Jc3N1ZUxlYWZSZXF1ZXN0GiMuY3J5cHRvcy5mbGVldC52MS5Jc3N1ZUxlYWZSZXNwb25zZRJUCglSZWtleU5vZGUSIi5jcnlwdG9zLmZsZWV0LnYxLlJla2V5Tm9kZVJlcXVlc3QaIy5jcnlwdG9zLmZsZWV0LnYxLlJla2V5Tm9kZVJlc3BvbnNlEmAKDUdldE5vZGVDb25maWcSJi5jcnlwdG9zLmZsZWV0LnYxLkdldE5vZGVDb25maWdSZXF1ZXN0GicuY3J5cHRvcy5mbGVldC52MS5HZXROb2RlQ29uZmlnUmVzcG9uc2USZgoPQXBwbHlOb2RlQ29uZmlnEiguY3J5cHRvcy5mbGVldC52MS5BcHBseU5vZGVDb25maWdSZXF1ZXN0GikuY3J5cHRvcy5mbGVldC52MS5BcHBseU5vZGVDb25maWdSZXNwb25zZRJaCgtFeHBvcnRDQUtleRIkLmNyeXB0b3MuZmxlZXQudjEuRXhwb3J0Q0FLZXlSZXF1ZXN0GiUuY3J5cHRvcy5mbGVldC52MS5FeHBvcnRDQUtleVJlc3BvbnNlEloKC0ltcG9ydENBS2V5EiQuY3J5cHRvcy5mbGVldC52MS5JbXBvcnRDQUtleVJlcXVlc3QaJS5jcnlwdG9zLmZsZWV0LnYxLkltcG9ydENBS2V5UmVzcG9uc2USlgEKH0NyZWF0ZU9wZXJhdG9yQ3JlZGVudGlhbFJlcXVlc3QSOC5jcnlwdG9zLmZsZWV0LnYxLkNyZWF0ZU9wZXJhdG9yQ3JlZGVudGlhbFJlcXVlc3RSZXF1ZXN0GjkuY3J5cHRvcy5mbGVldC52MS5DcmVhdGVPcGVyYXRvckNyZWRlbnRpYWxSZXF1ZXN0UmVzcG9uc2USkwEKHkxpc3RPcGVyYXRvckNyZWRlbnRpYWxSZXF1ZXN0cxI3LmNyeXB0b3MuZmxlZXQudjEuTGlzdE9wZXJhdG9yQ3JlZGVudGlhbFJlcXVlc3RzUmVxdWVzdBo4LmNyeXB0b3MuZmxlZXQudjEuTGlzdE9wZXJhdG9yQ3JlZGVudGlhbFJlcXVlc3RzUmVzcG9uc2USlgEKH0NhbmNlbE9wZXJhdG9yQ3JlZGVudGlhbFJlcXVlc3QSOC5jcnlwdG9zLmZsZWV0LnYxLkNhbmNlbE9wZXJhdG9yQ3JlZGVudGlhbFJlcXVlc3RSZXF1ZXN0GjkuY3J5cHRvcy5mbGVldC52MS5DYW5jZWxPcGVyYXRvckNyZWRlbnRpYWxSZXF1ZXN0UmVzcG9uc2USgQEKGFJlY29yZE9wZXJhdG9yQ3JlZGVudGlhbBIxLmNyeXB0b3MuZmxlZXQudjEuUmVjb3JkT3BlcmF0b3JDcmVkZW50aWFsUmVxdWVzdBoyLmNyeXB0b3MuZmxlZXQudjEuUmVjb3JkT3BlcmF0b3JDcmVkZW50aWFsUmVzcG9uc2USgQEKGFJldm9rZU9wZXJhdG9yQ3JlZGVudGlhbBIxLmNyeXB0b3MuZmxlZXQudjEuUmV2b2tlT3BlcmF0b3JDcmVkZW50aWFsUmVxdWVzdBoyLmNyeXB0b3MuZmxlZXQudjEuUmV2b2tlT3BlcmF0b3JDcmVkZW50aWFsUmVzcG9uc2USfgoXTGlzdE9wZXJhdG9yQ3JlZGVudGlhbHMSMC5jcnlwdG9zLmZsZWV0LnYxLkxpc3RPcGVyYXRvckNyZWRlbnRpYWxzUmVxdWVzdBoxLmNyeXB0b3MuZmxlZXQudjEuTGlzdE9wZXJhdG9yQ3JlZGVudGlhbHNSZXNwb25zZRJmCg9MaXN0T3BlcmF0b3JDQXMSKC5jcnlwdG9zLmZsZWV0LnYxLkxpc3RPcGVyYXRvckNBc1JlcXVlc3QaKS5jcnlwdG9zLmZsZWV0LnYxLkxpc3RPcGVyYXRvckNBc1Jlc3BvbnNlEm8KElJlZ2lzdGVyT3BlcmF0b3JDQRIrLmNyeXB0b3MuZmxlZXQudjEuUmVnaXN0ZXJPcGVyYXRvckNBUmVxdWVzdBosLmNyeXB0b3MuZmxlZXQudjEuUmVnaXN0ZXJPcGVyYXRvckNBUmVzcG9uc2USaQoQUmV0aXJlT3BlcmF0b3JDQRIpLmNyeXB0b3MuZmxlZXQudjEuUmV0aXJlT3BlcmF0b3JDQVJlcXVlc3QaKi5jcnlwdG9zLmZsZWV0LnYxLlJldGlyZU9wZXJhdG9yQ0FSZXNwb25zZRJ7ChZTZXRPcGVyYXRvckNBQ1JMU291cmNlEi8uY3J5cHRvcy5mbGVldC52MS5TZXRPcGVyYXRvckNBQ1JMU291cmNlUmVxdWVzdBowLmNyeXB0b3MuZmxlZXQudjEuU2V0T3BlcmF0b3JDQUNSTFNvdXJjZVJlc3BvbnNlEmwKEVVwbG9hZE9wZXJhdG9yQ1JMEiouY3J5cHRvcy5mbGVldC52MS5VcGxvYWRPcGVyYXRvckNSTFJlcXVlc3QaKy5jcnlwdG9zLmZsZWV0LnYxLlVwbG9hZE9wZXJhdG9yQ1JMUmVzcG9uc2USbAoRU2V0T3BlcmF0b3JDQU9DU1ASKi5jcnlwdG9zLmZsZWV0LnYxLlNldE9wZXJhdG9yQ0FPQ1NQUmVxdWVzdBorLmNyeXB0b3MuZmxlZXQudjEuU2V0T3BlcmF0b3JDQU9DU1BSZXNwb25zZRJmCg9QcmV2aWV3QWRvcHRpb24SKC5jcnlwdG9zLmZsZWV0LnYxLlByZXZpZXdBZG9wdGlvblJlcXVlc3QaKS5jcnlwdG9zLmZsZWV0LnYxLlByZXZpZXdBZG9wdGlvblJlc3BvbnNlEmkKEExpc3RJbnN0YWxsRGlza3MSKS5jcnlwdG9zLmZsZWV0LnYxLkxpc3RJbnN0YWxsRGlza3NSZXF1ZXN0GiouY3J5cHRvcy5mbGVldC52MS5MaXN0SW5zdGFsbERpc2tzUmVzcG9uc2USVgoJQWRvcHROb2RlEiIuY3J5cHRvcy5mbGVldC52MS5BZG9wdE5vZGVSZXF1ZXN0GiMuY3J5cHRvcy5mbGVldC52MS5BZG9wdE5vZGVSZXNwb25zZTABEocBChpDb25maXJtQWRvcHRpb25GaW5nZXJwcmludBIzLmNyeXB0b3MuZmxlZXQudjEuQ29uZmlybUFkb3B0aW9uRmluZ2VycHJpbnRSZXF1ZXN0GjQuY3J5cHRvcy5mbGVldC52MS5Db25maXJtQWRvcHRpb25GaW5nZXJwcmludFJlc3BvbnNlEmkKEERlY29tbWlzc2lvbk5vZGUSKS5jcnlwdG9zLmZsZWV0LnYxLkRlY29tbWlzc2lvbk5vZGVSZXF1ZXN0GiouY3J5cHRvcy5mbGVldC52MS5EZWNvbW1pc3Npb25Ob2RlUmVzcG9uc2USVwoKUmVib290Tm9kZRIjLmNyeXB0b3MuZmxlZXQudjEuUmVib290Tm9kZVJlcXVlc3QaJC5jcnlwdG9zLmZsZWV0LnYxLlJlYm9vdE5vZGVSZXNwb25zZRJXCgpSZW5hbWVOb2RlEiMuY3J5cHRvcy5mbGVldC52MS5SZW5hbWVOb2RlUmVxdWVzdBokLmNyeXB0b3MuZmxlZXQudjEuUmVuYW1lTm9kZVJlc3BvbnNlElcKClJlbW92ZU5vZGUSIy5jcnlwdG9zLmZsZWV0LnYxLlJlbW92ZU5vZGVSZXF1ZXN0GiQuY3J5cHRvcy5mbGVldC52MS5SZW1vdmVOb2RlUmVzcG9uc2USWgoLTGlzdE1jcEtleXMSJC5jcnlwdG9zLmZsZWV0LnYxLkxpc3RNY3BLZXlzUmVxdWVzdBolLmNyeXB0b3MuZmxlZXQudjEuTGlzdE1jcEtleXNSZXNwb25zZRJdCgxSZXZva2VNY3BLZXkSJS5jcnlwdG9zLmZsZWV0LnYxLlJldm9rZU1jcEtleVJlcXVlc3QaJi5jcnlwdG9zLmZsZWV0LnYxLlJldm9rZU1jcEtleVJlc3BvbnNlEl0KDENyZWF0ZU1jcEtleRIlLmNyeXB0b3MuZmxlZXQudjEuQ3JlYXRlTWNwS2V5UmVxdWVzdBomLmNyeXB0b3MuZmxlZXQudjEuQ3JlYXRlTWNwS2V5UmVzcG9uc2USYAoNTGlzdEFwcHJvdmFscxImLmNyeXB0b3MuZmxlZXQudjEuTGlzdEFwcHJvdmFsc1JlcXVlc3QaJy5jcnlwdG9zLmZsZWV0LnYxLkxpc3RBcHByb3ZhbHNSZXNwb25zZRJjCg5EZWNpZGVBcHByb3ZhbBInLmNyeXB0b3MuZmxlZXQudjEuRGVjaWRlQXBwcm92YWxSZXF1ZXN0GiguY3J5cHRvcy5mbGVldC52MS5EZWNpZGVBcHByb3ZhbFJlc3BvbnNlEoEBChhDcmVhdGVDZXJ0aWZpY2F0ZVJlcXVlc3QSMS5jcnlwdG9zLmZsZWV0LnYxLkNyZWF0ZUNlcnRpZmljYXRlUmVxdWVzdFJlcXVlc3QaMi5jcnlwdG9zLmZsZWV0LnYxLkNyZWF0ZUNlcnRpZmljYXRlUmVxdWVzdFJlc3BvbnNlEn4KF0xpc3RDZXJ0aWZpY2F0ZVJlcXVlc3RzEjAuY3J5cHRvcy5mbGVldC52MS5MaXN0Q2VydGlmaWNhdGVSZXF1ZXN0c1JlcXVlc3QaMS5jcnlwdG9zLmZsZWV0LnYxLkxpc3RDZXJ0aWZpY2F0ZVJlcXVlc3RzUmVzcG9uc2UShAEKGUdldENlcnRpZmljYXRlUmVxdWVzdEJ5SUQSMi5jcnlwdG9zLmZsZWV0LnYxLkdldENlcnRpZmljYXRlUmVxdWVzdEJ5SURSZXF1ZXN0GjMuY3J5cHRvcy5mbGVldC52MS5HZXRDZXJ0aWZpY2F0ZVJlcXVlc3RCeUlEUmVzcG9uc2USgQEKGENhbmNlbENlcnRpZmljYXRlUmVxdWVzdBIxLmNyeXB0b3MuZmxlZXQudjEuQ2FuY2VsQ2VydGlmaWNhdGVSZXF1ZXN0UmVxdWVzdBoyLmNyeXB0b3MuZmxlZXQudjEuQ2FuY2VsQ2VydGlmaWNhdGVSZXF1ZXN0UmVzcG9uc2VCSFpGZ2l0aHViLmNvbS9DcnlwdE9TLVBLSS9jcnlwdG9zLW1hbmFnZXIvZ2VuL2dvL2NyeXB0b3MvZmxlZXQvdjE7ZmxlZXR2MWIGcHJvdG8z", [file_cryptos_fleet_v1_operator_ca, file_cryptos_node_v1_config, file_cryptos_node_v1_node, file_cryptos_node_v1_status]); /** * @generated from message cryptos.fleet.v1.ListNodesRequest @@ -4399,6 +4399,222 @@ export type VerifyNodeAuditChainResponse = Message<"cryptos.fleet.v1.VerifyNodeA export const VerifyNodeAuditChainResponseSchema: GenMessage = /*@__PURE__*/ messageDesc(file_cryptos_fleet_v1_fleet, 134); +/** + * NodeScepChallenge describes a one-time SCEP challenge on a managed node, + * without the challenge itself, which only MintNodeScepChallengeResponse + * carries. + * + * @generated from message cryptos.fleet.v1.NodeScepChallenge + */ +export type NodeScepChallenge = Message<"cryptos.fleet.v1.NodeScepChallenge"> & { + /** + * id identifies the challenge for listing and revocation. + * + * @generated from field: string id = 1; + */ + id: string; + + /** + * profile is the node's Scep.profiles entry the enrolment it authorizes + * issues from. + * + * @generated from field: string profile = 2; + */ + profile: string; + + /** + * bound_names, when non-empty, are the only names the enrolment may + * request. + * + * @generated from field: repeated string bound_names = 3; + */ + boundNames: string[]; + + /** + * @generated from field: string created_at = 4; + */ + createdAt: string; + + /** + * expires_at is when the challenge stops being accepted if still unused. + * + * @generated from field: string expires_at = 5; + */ + expiresAt: string; + + /** + * created_by_cn is the common name of the admin certificate that minted + * it. + * + * @generated from field: string created_by_cn = 6; + */ + createdByCn: string; +}; + +/** + * Describes the message cryptos.fleet.v1.NodeScepChallenge. + * Use `create(NodeScepChallengeSchema)` to create a new message. + */ +export const NodeScepChallengeSchema: GenMessage = /*@__PURE__*/ + messageDesc(file_cryptos_fleet_v1_fleet, 135); + +/** + * @generated from message cryptos.fleet.v1.MintNodeScepChallengeRequest + */ +export type MintNodeScepChallengeRequest = Message<"cryptos.fleet.v1.MintNodeScepChallengeRequest"> & { + /** + * @generated from field: string node_name = 1; + */ + nodeName: string; + + /** + * @generated from field: string node_id = 2; + */ + nodeId: string; + + /** + * profile names the node's Scep.profiles entry to issue from. May be empty + * only when the node has exactly one profile configured. + * + * @generated from field: string profile = 3; + */ + profile: string; + + /** + * ttl_seconds is how long the challenge stays usable. Zero means the + * node's default of one hour. + * + * @generated from field: uint32 ttl_seconds = 4; + */ + ttlSeconds: number; + + /** + * bound_names optionally pins the names the enrolment may request. + * + * @generated from field: repeated string bound_names = 5; + */ + boundNames: string[]; +}; + +/** + * Describes the message cryptos.fleet.v1.MintNodeScepChallengeRequest. + * Use `create(MintNodeScepChallengeRequestSchema)` to create a new message. + */ +export const MintNodeScepChallengeRequestSchema: GenMessage = /*@__PURE__*/ + messageDesc(file_cryptos_fleet_v1_fleet, 136); + +/** + * @generated from message cryptos.fleet.v1.MintNodeScepChallengeResponse + */ +export type MintNodeScepChallengeResponse = Message<"cryptos.fleet.v1.MintNodeScepChallengeResponse"> & { + /** + * challenge_password is the challenge to give the device. Returned once + * and never again, and never written to the audit log. + * + * @generated from field: string challenge_password = 1; + */ + challengePassword: string; + + /** + * @generated from field: cryptos.fleet.v1.NodeScepChallenge challenge = 2; + */ + challenge?: NodeScepChallenge | undefined; +}; + +/** + * Describes the message cryptos.fleet.v1.MintNodeScepChallengeResponse. + * Use `create(MintNodeScepChallengeResponseSchema)` to create a new message. + */ +export const MintNodeScepChallengeResponseSchema: GenMessage = /*@__PURE__*/ + messageDesc(file_cryptos_fleet_v1_fleet, 137); + +/** + * @generated from message cryptos.fleet.v1.ListNodeScepChallengesRequest + */ +export type ListNodeScepChallengesRequest = Message<"cryptos.fleet.v1.ListNodeScepChallengesRequest"> & { + /** + * @generated from field: string node_name = 1; + */ + nodeName: string; + + /** + * @generated from field: string node_id = 2; + */ + nodeId: string; +}; + +/** + * Describes the message cryptos.fleet.v1.ListNodeScepChallengesRequest. + * Use `create(ListNodeScepChallengesRequestSchema)` to create a new message. + */ +export const ListNodeScepChallengesRequestSchema: GenMessage = /*@__PURE__*/ + messageDesc(file_cryptos_fleet_v1_fleet, 138); + +/** + * @generated from message cryptos.fleet.v1.ListNodeScepChallengesResponse + */ +export type ListNodeScepChallengesResponse = Message<"cryptos.fleet.v1.ListNodeScepChallengesResponse"> & { + /** + * challenges are the usable challenges, soonest to expire first. + * + * @generated from field: repeated cryptos.fleet.v1.NodeScepChallenge challenges = 1; + */ + challenges: NodeScepChallenge[]; +}; + +/** + * Describes the message cryptos.fleet.v1.ListNodeScepChallengesResponse. + * Use `create(ListNodeScepChallengesResponseSchema)` to create a new message. + */ +export const ListNodeScepChallengesResponseSchema: GenMessage = /*@__PURE__*/ + messageDesc(file_cryptos_fleet_v1_fleet, 139); + +/** + * @generated from message cryptos.fleet.v1.RevokeNodeScepChallengeRequest + */ +export type RevokeNodeScepChallengeRequest = Message<"cryptos.fleet.v1.RevokeNodeScepChallengeRequest"> & { + /** + * @generated from field: string node_name = 1; + */ + nodeName: string; + + /** + * @generated from field: string node_id = 2; + */ + nodeId: string; + + /** + * @generated from field: string id = 3; + */ + id: string; +}; + +/** + * Describes the message cryptos.fleet.v1.RevokeNodeScepChallengeRequest. + * Use `create(RevokeNodeScepChallengeRequestSchema)` to create a new message. + */ +export const RevokeNodeScepChallengeRequestSchema: GenMessage = /*@__PURE__*/ + messageDesc(file_cryptos_fleet_v1_fleet, 140); + +/** + * @generated from message cryptos.fleet.v1.RevokeNodeScepChallengeResponse + */ +export type RevokeNodeScepChallengeResponse = Message<"cryptos.fleet.v1.RevokeNodeScepChallengeResponse"> & { + /** + * challenge is the withdrawn challenge as it was before revocation. + * + * @generated from field: cryptos.fleet.v1.NodeScepChallenge challenge = 1; + */ + challenge?: NodeScepChallenge | undefined; +}; + +/** + * Describes the message cryptos.fleet.v1.RevokeNodeScepChallengeResponse. + * Use `create(RevokeNodeScepChallengeResponseSchema)` to create a new message. + */ +export const RevokeNodeScepChallengeResponseSchema: GenMessage = /*@__PURE__*/ + messageDesc(file_cryptos_fleet_v1_fleet, 141); + /** * Health reports the manager's view of node reachability, independent of * the node's own reported identity state. @@ -4743,6 +4959,41 @@ export const FleetService: GenService<{ input: typeof ListNodeTsaCertificatesRequestSchema; output: typeof ListNodeTsaCertificatesResponseSchema; }, + /** + * MintNodeScepChallenge mints a one-time SCEP challenge password on a + * managed node, for example to enroll a network device via its SCEP + * trustpoint. The password is returned once and is never written to the + * audit log. Operator-gated and audited (without the password). + * + * @generated from rpc cryptos.fleet.v1.FleetService.MintNodeScepChallenge + */ + mintNodeScepChallenge: { + methodKind: "unary"; + input: typeof MintNodeScepChallengeRequestSchema; + output: typeof MintNodeScepChallengeResponseSchema; + }, + /** + * ListNodeScepChallenges lists a managed node's usable SCEP challenges, + * soonest to expire first. Operator-gated; a read, so it is not audited. + * + * @generated from rpc cryptos.fleet.v1.FleetService.ListNodeScepChallenges + */ + listNodeScepChallenges: { + methodKind: "unary"; + input: typeof ListNodeScepChallengesRequestSchema; + output: typeof ListNodeScepChallengesResponseSchema; + }, + /** + * RevokeNodeScepChallenge withdraws a managed node's SCEP challenge before + * it is used or expires. Operator-gated and audited. + * + * @generated from rpc cryptos.fleet.v1.FleetService.RevokeNodeScepChallenge + */ + revokeNodeScepChallenge: { + methodKind: "unary"; + input: typeof RevokeNodeScepChallengeRequestSchema; + output: typeof RevokeNodeScepChallengeResponseSchema; + }, /** * IssueLeaf signs a leaf certificate on the named issuing node from a * browser-generated PKCS#10 CSR under a named issuance profile. Only the From 5cb20a0018a88328425f86ce32e165f0dfb85f1a Mon Sep 17 00:00:00 2001 From: Bugs5382 <12115015+Bugs5382@users.noreply.github.com> Date: Thu, 15 Oct 2026 12:35:41 -0400 Subject: [PATCH 2/3] feat(console): SCEP challenge passwords on node detail Node detail now lists a managed node's usable SCEP challenges through the manager's ListNodeScepChallenges. An operator can mint a one-time challenge password (shown once, through the same ShownOnceSecret pattern an agent key uses) and revoke an unused challenge. Minting and revoking need operator level or above, the same gate NodeChainValidate uses; a viewer sees the list only. Refs CryptOS-PKI/cryptos-manager#190 Signed-off-by: Bugs5382 <12115015+Bugs5382@users.noreply.github.com> --- .../mint-node-scep-challenge-dialog.test.tsx | 93 +++++++++++ .../mint-node-scep-challenge-dialog.tsx | 139 +++++++++++++++++ .../components/node-scep-challenges.test.tsx | 61 ++++++++ .../src/components/node-scep-challenges.tsx | 145 ++++++++++++++++++ ...revoke-node-scep-challenge-dialog.test.tsx | 77 ++++++++++ .../revoke-node-scep-challenge-dialog.tsx | 82 ++++++++++ .../src/lib/node-scep-challenges.live.test.ts | 108 +++++++++++++ .../src/lib/node-scep-challenges.test.ts | 49 ++++++ apps/console/src/lib/node-scep-challenges.ts | 122 +++++++++++++++ .../src/pages/node-detail.live.test.tsx | 3 + apps/console/src/pages/node-detail.test.tsx | 6 +- apps/console/src/pages/node-detail.tsx | 9 ++ 12 files changed, 892 insertions(+), 2 deletions(-) create mode 100644 apps/console/src/components/mint-node-scep-challenge-dialog.test.tsx create mode 100644 apps/console/src/components/mint-node-scep-challenge-dialog.tsx create mode 100644 apps/console/src/components/node-scep-challenges.test.tsx create mode 100644 apps/console/src/components/node-scep-challenges.tsx create mode 100644 apps/console/src/components/revoke-node-scep-challenge-dialog.test.tsx create mode 100644 apps/console/src/components/revoke-node-scep-challenge-dialog.tsx create mode 100644 apps/console/src/lib/node-scep-challenges.live.test.ts create mode 100644 apps/console/src/lib/node-scep-challenges.test.ts create mode 100644 apps/console/src/lib/node-scep-challenges.ts diff --git a/apps/console/src/components/mint-node-scep-challenge-dialog.test.tsx b/apps/console/src/components/mint-node-scep-challenge-dialog.test.tsx new file mode 100644 index 0000000..c244781 --- /dev/null +++ b/apps/console/src/components/mint-node-scep-challenge-dialog.test.tsx @@ -0,0 +1,93 @@ +/* +Copyright The CryptOS Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +import { fireEvent, render, screen, waitFor } from "@testing-library/react"; +import { beforeEach, describe, expect, it, vi } from "vitest"; + +import { MintNodeScepChallengeDialog } from "@/components/mint-node-scep-challenge-dialog"; +import { expectNoA11yViolations } from "@/test/axe"; + +const mintNodeScepChallenge = vi.fn(); +vi.mock("@/lib/node-scep-challenges", () => ({ + mintNodeScepChallenge: (...a: unknown[]) => mintNodeScepChallenge(...a), +})); + +const mintButton = () => screen.getByRole("button", { name: /^mint challenge$/i }); + +const renderDialog = () => + render( + , + ); + +describe("MintNodeScepChallengeDialog", () => { + beforeEach(() => { + mintNodeScepChallenge.mockReset(); + mintNodeScepChallenge.mockResolvedValue({ + challenge: { + boundNames: [], + createdAt: "", + createdByCn: "", + expiresAt: "", + id: "ch-1", + profile: "network-device", + }, + challengePassword: "one-time-password-123", + }); + }); + + it("has no axe violations before minting", async () => { + renderDialog(); + await expectNoA11yViolations(document.body); + }); + + it("mints with the entered profile, ttl and bound names, then shows the password once", async () => { + const onMinted = vi.fn(); + render( + , + ); + + fireEvent.change(screen.getByLabelText(/^profile$/i), { target: { value: "network-device" } }); + fireEvent.change(screen.getByLabelText(/ttl/i), { target: { value: "7200" } }); + fireEvent.change(screen.getByLabelText(/bound names/i), { + target: { value: "switch-1.example.org, 10.0.0.5" }, + }); + fireEvent.click(mintButton()); + + await waitFor(() => + expect(mintNodeScepChallenge).toHaveBeenCalledWith("acme-edge-07", { + boundNames: ["switch-1.example.org", "10.0.0.5"], + profile: "network-device", + ttlSeconds: 7200, + }), + ); + expect(await screen.findByText("one-time-password-123")).toBeInTheDocument(); + expect(onMinted).toHaveBeenCalled(); + }); + + it("has no axe violations after minting (shown-once secret)", async () => { + renderDialog(); + fireEvent.click(mintButton()); + await screen.findByText("one-time-password-123"); + await expectNoA11yViolations(document.body); + }); + + it("surfaces a server-side refusal inline", async () => { + mintNodeScepChallenge.mockRejectedValue(new Error('node has no profile named "bogus"')); + renderDialog(); + fireEvent.click(mintButton()); + await waitFor(() => expect(screen.getByText(/no profile named/i)).toBeInTheDocument()); + }); +}); diff --git a/apps/console/src/components/mint-node-scep-challenge-dialog.tsx b/apps/console/src/components/mint-node-scep-challenge-dialog.tsx new file mode 100644 index 0000000..6d22548 --- /dev/null +++ b/apps/console/src/components/mint-node-scep-challenge-dialog.tsx @@ -0,0 +1,139 @@ +/* +Copyright The CryptOS Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +import { Button, Dialog, Field, Input, Notice, ShownOnceSecret } from "@cryptos-pki/ui"; +import { useState } from "react"; + +import { mintNodeScepChallenge } from "@/lib/node-scep-challenges"; + +const parseBoundNames = (raw: string): string[] => + raw + .split(",") + .map((n) => n.trim()) + .filter((n) => n !== ""); + +// MintNodeScepChallengeDialog mints a one-time SCEP challenge password on a +// managed node, for example to enroll a network device via its SCEP +// trustpoint. The plaintext lives only in this dialog's state: the page is +// told a challenge was made, never what the password is, and closing the +// dialog discards it. +export const MintNodeScepChallengeDialog = ({ + nodeName, + onClose, + onMinted, +}: { + nodeName: string; + onClose: () => void; + onMinted: () => void; +}) => { + const [profile, setProfile] = useState(""); + const [ttlSeconds, setTtlSeconds] = useState("3600"); + const [boundNames, setBoundNames] = useState(""); + const [pending, setPending] = useState(false); + const [error, setError] = useState(null); + const [challengePassword, setChallengePassword] = useState(""); + + const close = () => { + setChallengePassword(""); + onClose(); + }; + + const mint = () => { + setPending(true); + setError(null); + mintNodeScepChallenge(nodeName, { + boundNames: parseBoundNames(boundNames), + profile: profile.trim(), + ttlSeconds: Number(ttlSeconds) || 0, + }) + .then((result) => { + setChallengePassword(result.challengePassword); + setPending(false); + onMinted(); + }) + .catch((error_: unknown) => { + setError(error_ instanceof Error ? error_.message : "Mint failed"); + setPending(false); + }); + }; + + return ( + + + + + ) + } + onClose={close} + open + title="Mint a SCEP challenge" + > + {challengePassword ? ( + + ) : ( + <> + + setProfile(e.target.value)} + value={profile} + /> + + + setTtlSeconds(e.target.value)} + type="number" + value={ttlSeconds} + /> + + + setBoundNames(e.target.value)} + placeholder="switch-1.example.org, 10.0.0.5" + value={boundNames} + /> + + {error ? ( + + {error} + + ) : null} + + )} + + ); +}; diff --git a/apps/console/src/components/node-scep-challenges.test.tsx b/apps/console/src/components/node-scep-challenges.test.tsx new file mode 100644 index 0000000..634102b --- /dev/null +++ b/apps/console/src/components/node-scep-challenges.test.tsx @@ -0,0 +1,61 @@ +/* +Copyright The CryptOS Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +import { render, screen } from "@testing-library/react"; +import { beforeEach, describe, expect, it, vi } from "vitest"; + +import { NodeScepChallenges } from "@/components/node-scep-challenges"; +import { expectNoA11yViolations } from "@/test/axe"; + +let level: "admin" | "operator" | "viewer" = "operator"; +vi.mock("@/context/auth", () => ({ + useOptionalAuth: () => ({ + operator: { commonName: "op@acme.example", level, serial: "AA" }, + status: "authenticated", + }), +})); + +describe("NodeScepChallenges", () => { + beforeEach(() => { + level = "operator"; + }); + + it("has no axe violations", async () => { + const { container } = render(); + await screen.findByText("ch-mock-1"); + await expectNoA11yViolations(container); + }); + + it("lists the node's SCEP challenges", async () => { + render(); + expect(await screen.findByText("ch-mock-1")).toBeInTheDocument(); + }); + + it("shows Mint and Revoke to an operator", async () => { + render(); + await screen.findByText("ch-mock-1"); + expect(screen.getByRole("button", { name: /mint challenge/i })).toBeInTheDocument(); + expect(screen.getByRole("button", { name: /^revoke$/i })).toBeInTheDocument(); + }); + + it("hides Mint and Revoke from a viewer", async () => { + level = "viewer"; + render(); + await screen.findByText("ch-mock-1"); + expect(screen.queryByRole("button", { name: /mint challenge/i })).not.toBeInTheDocument(); + expect(screen.queryByRole("button", { name: /^revoke$/i })).not.toBeInTheDocument(); + }); +}); diff --git a/apps/console/src/components/node-scep-challenges.tsx b/apps/console/src/components/node-scep-challenges.tsx new file mode 100644 index 0000000..1717032 --- /dev/null +++ b/apps/console/src/components/node-scep-challenges.tsx @@ -0,0 +1,145 @@ +/* +Copyright The CryptOS Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +import { + Button, + DataTable, + type DataTableColumn, + EmptyState, + IconCertificates, +} from "@cryptos-pki/ui"; +import { useEffect, useState } from "react"; + +import { MintNodeScepChallengeDialog } from "@/components/mint-node-scep-challenge-dialog"; +import { RevokeNodeScepChallengeDialog } from "@/components/revoke-node-scep-challenge-dialog"; +import { useOptionalAuth } from "@/context/auth"; +import { fleetErrorMessage } from "@/lib/fleet/error-copy"; +import { listNodeScepChallenges, type NodeScepChallenge } from "@/lib/node-scep-challenges"; + +// NodeScepChallenges lists a managed node's usable SCEP challenges and lets +// an operator mint a new one-time challenge password or revoke an unused +// one. Minting and revoking need operator level or above, the node's own +// write paths; viewers see the list only. +export const NodeScepChallenges = ({ nodeName }: { nodeName: string }) => { + const isOperator = useOptionalAuth()?.operator?.level !== "viewer"; + const [challenges, setChallenges] = useState([]); + const [status, setStatus] = useState<"error" | "loading" | "ready">("loading"); + const [loadError, setLoadError] = useState(""); + const [showMint, setShowMint] = useState(false); + const [revokeTarget, setRevokeTarget] = useState(null); + const [refreshKey, setRefreshKey] = useState(0); + + useEffect(() => { + let cancelled = false; + setStatus("loading"); + listNodeScepChallenges(nodeName) + .then((result) => { + if (cancelled) return; + setChallenges(result); + setStatus("ready"); + }) + .catch((error: unknown) => { + if (cancelled) return; + setLoadError(fleetErrorMessage(error, "Failed to load the node's SCEP challenges")); + setStatus("error"); + }); + return () => { + cancelled = true; + }; + }, [nodeName, refreshKey]); + + const refresh = () => setRefreshKey((k) => k + 1); + + const columns: DataTableColumn[] = [ + { cell: (c) => c.id, header: "ID", id: "id" }, + { cell: (c) => c.profile, header: "Profile", id: "profile" }, + { + cell: (c) => (c.boundNames.length > 0 ? c.boundNames.join(", ") : "—"), + header: "Bound names", + id: "boundNames", + }, + { cell: (c) => c.expiresAt.slice(0, 16).replace("T", " "), header: "Expires", id: "expiresAt" }, + { cell: (c) => c.createdByCn, header: "Minted by", id: "createdByCn" }, + { + cell: (c) => + isOperator ? ( + + ) : null, + header: Actions, + id: "actions", + mobile: "action", + }, + ]; + + return ( +
+ {isOperator ? ( +
+ +
+ ) : null} + + + } + error={ + + } + label="SCEP challenges" + rowKey={(c) => c.id} + rows={challenges} + status={status} + /> + + {showMint ? ( + setShowMint(false)} + onMinted={() => { + refresh(); + }} + /> + ) : null} + {revokeTarget ? ( + setRevokeTarget(null)} + onDone={() => { + setRevokeTarget(null); + refresh(); + }} + profile={revokeTarget.profile} + /> + ) : null} +
+ ); +}; diff --git a/apps/console/src/components/revoke-node-scep-challenge-dialog.test.tsx b/apps/console/src/components/revoke-node-scep-challenge-dialog.test.tsx new file mode 100644 index 0000000..7a962a1 --- /dev/null +++ b/apps/console/src/components/revoke-node-scep-challenge-dialog.test.tsx @@ -0,0 +1,77 @@ +/* +Copyright The CryptOS Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +import { fireEvent, render, screen, waitFor } from "@testing-library/react"; +import { beforeEach, describe, expect, it, vi } from "vitest"; + +import { RevokeNodeScepChallengeDialog } from "@/components/revoke-node-scep-challenge-dialog"; +import { expectNoA11yViolations } from "@/test/axe"; + +const revokeNodeScepChallenge = vi.fn(); +vi.mock("@/lib/node-scep-challenges", () => ({ + revokeNodeScepChallenge: (...a: unknown[]) => revokeNodeScepChallenge(...a), +})); + +const revokeButton = () => screen.getByRole("button", { name: /^revoke$/i }); + +const renderDialog = () => + render( + , + ); + +describe("RevokeNodeScepChallengeDialog", () => { + beforeEach(() => { + revokeNodeScepChallenge.mockReset(); + revokeNodeScepChallenge.mockImplementation(() => Promise.resolve()); + }); + + it("has no axe violations", async () => { + renderDialog(); + await expectNoA11yViolations(document.body); + }); + + it("confirms the revoke with the challenge id and calls onDone", async () => { + const onDone = vi.fn(); + render( + , + ); + fireEvent.click(revokeButton()); + + await waitFor(() => + expect(revokeNodeScepChallenge).toHaveBeenCalledWith("acme-edge-07", "ch-1"), + ); + await waitFor(() => expect(onDone).toHaveBeenCalled()); + }); + + it("surfaces a server-side refusal inline", async () => { + revokeNodeScepChallenge.mockRejectedValue(new Error("no challenge with that id")); + renderDialog(); + fireEvent.click(revokeButton()); + await waitFor(() => expect(screen.getByText(/no challenge with that id/i)).toBeInTheDocument()); + }); +}); diff --git a/apps/console/src/components/revoke-node-scep-challenge-dialog.tsx b/apps/console/src/components/revoke-node-scep-challenge-dialog.tsx new file mode 100644 index 0000000..5aebf68 --- /dev/null +++ b/apps/console/src/components/revoke-node-scep-challenge-dialog.tsx @@ -0,0 +1,82 @@ +/* +Copyright The CryptOS Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +import { Button, Dialog, Notice } from "@cryptos-pki/ui"; +import { useState } from "react"; + +import { revokeNodeScepChallenge } from "@/lib/node-scep-challenges"; + +// RevokeNodeScepChallengeDialog withdraws a managed node's SCEP challenge +// before it is used or expires. A device that already has the challenge +// password cannot enroll with it once revoked. +export const RevokeNodeScepChallengeDialog = ({ + challengeId, + nodeName, + onClose, + onDone, + profile, +}: { + challengeId: string; + nodeName: string; + onClose: () => void; + onDone: () => void; + profile: string; +}) => { + const [pending, setPending] = useState(false); + const [error, setError] = useState(null); + + const confirm = () => { + setPending(true); + setError(null); + revokeNodeScepChallenge(nodeName, challengeId) + .then(() => { + onDone(); + }) + .catch((error_: unknown) => { + setError(error_ instanceof Error ? error_.message : "Revoke failed"); + setPending(false); + }); + }; + + return ( + + + + + } + onClose={onClose} + open + title="Revoke SCEP challenge" + variant="destructive" + > + +

A device that already has this challenge password can no longer enroll with it.

+
+ {error ? ( + + {error} + + ) : null} +
+ ); +}; diff --git a/apps/console/src/lib/node-scep-challenges.live.test.ts b/apps/console/src/lib/node-scep-challenges.live.test.ts new file mode 100644 index 0000000..bf75849 --- /dev/null +++ b/apps/console/src/lib/node-scep-challenges.live.test.ts @@ -0,0 +1,108 @@ +/* +Copyright The CryptOS Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +import { afterEach, beforeEach, describe, expect, it, vi } from "vitest"; + +const listNodeScepChallenges = vi.fn(() => + Promise.resolve({ + challenges: [ + { + boundNames: ["switch-1.example.org"], + createdAt: "2026-01-01T00:00:00Z", + createdByCn: "admin@acme.example", + expiresAt: "2026-01-02T00:00:00Z", + id: "ch-live-1", + profile: "network-device", + }, + ], + }), +); +const mintNodeScepChallenge = vi.fn(() => + Promise.resolve({ + challenge: { + boundNames: [], + createdAt: "2026-01-01T00:00:00Z", + createdByCn: "admin@acme.example", + expiresAt: "2026-01-02T00:00:00Z", + id: "ch-live-new", + profile: "network-device", + }, + challengePassword: "live-one-time-password", + }), +); +const revokeNodeScepChallenge = vi.fn(() => Promise.resolve({ challenge: { id: "ch-live-1" } })); +vi.mock("@/lib/fleet/client", () => ({ + fleetClient: () => ({ listNodeScepChallenges, mintNodeScepChallenge, revokeNodeScepChallenge }), +})); + +import { + listNodeScepChallenges as listNodeScepChallengesLib, + mintNodeScepChallenge as mintNodeScepChallengeLib, + revokeNodeScepChallenge as revokeNodeScepChallengeLib, +} from "@/lib/node-scep-challenges"; + +describe("node-scep-challenges live path", () => { + beforeEach(() => { + listNodeScepChallenges.mockClear(); + mintNodeScepChallenge.mockClear(); + revokeNodeScepChallenge.mockClear(); + vi.stubEnv("VITE_FLEET_MODE", "live"); + }); + + afterEach(() => { + vi.unstubAllEnvs(); + }); + + it("listNodeScepChallenges forwards the node name and flattens the response", async () => { + const challenges = await listNodeScepChallengesLib("acme-issuing-01"); + expect(listNodeScepChallenges).toHaveBeenCalledWith( + expect.objectContaining({ nodeName: "acme-issuing-01" }), + ); + expect(challenges).toEqual([ + { + boundNames: ["switch-1.example.org"], + createdAt: "2026-01-01T00:00:00Z", + createdByCn: "admin@acme.example", + expiresAt: "2026-01-02T00:00:00Z", + id: "ch-live-1", + profile: "network-device", + }, + ]); + }); + + it("mintNodeScepChallenge forwards profile, ttl_seconds and bound_names", async () => { + const result = await mintNodeScepChallengeLib("acme-issuing-01", { + boundNames: ["switch-1.example.org"], + profile: "network-device", + ttlSeconds: 3600, + }); + expect(mintNodeScepChallenge).toHaveBeenCalledWith({ + boundNames: ["switch-1.example.org"], + nodeName: "acme-issuing-01", + profile: "network-device", + ttlSeconds: 3600, + }); + expect(result.challengePassword).toBe("live-one-time-password"); + }); + + it("revokeNodeScepChallenge forwards the id", async () => { + await revokeNodeScepChallengeLib("acme-issuing-01", "ch-live-1"); + expect(revokeNodeScepChallenge).toHaveBeenCalledWith({ + id: "ch-live-1", + nodeName: "acme-issuing-01", + }); + }); +}); diff --git a/apps/console/src/lib/node-scep-challenges.test.ts b/apps/console/src/lib/node-scep-challenges.test.ts new file mode 100644 index 0000000..add5060 --- /dev/null +++ b/apps/console/src/lib/node-scep-challenges.test.ts @@ -0,0 +1,49 @@ +/* +Copyright The CryptOS Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +import { describe, expect, it } from "vitest"; + +import { + listNodeScepChallenges, + mintNodeScepChallenge, + revokeNodeScepChallenge, +} from "@/lib/node-scep-challenges"; + +describe("listNodeScepChallenges (mock mode)", () => { + it("returns a deterministic demo challenge", async () => { + const challenges = await listNodeScepChallenges("acme-issuing-01"); + expect(challenges.length).toBeGreaterThan(0); + }); +}); + +describe("mintNodeScepChallenge (mock mode)", () => { + it("returns a non-empty one-time password and a matching challenge", async () => { + const result = await mintNodeScepChallenge("acme-issuing-01", { + boundNames: ["switch-1.example.org"], + profile: "network-device", + ttlSeconds: 3600, + }); + expect(result.challengePassword.length).toBeGreaterThan(0); + expect(result.challenge.profile).toBe("network-device"); + expect(result.challenge.boundNames).toEqual(["switch-1.example.org"]); + }); +}); + +describe("revokeNodeScepChallenge", () => { + it("is a no-op that resolves in mock mode", async () => { + await expect(revokeNodeScepChallenge("acme-issuing-01", "ch-mock-1")).resolves.toBeUndefined(); + }); +}); diff --git a/apps/console/src/lib/node-scep-challenges.ts b/apps/console/src/lib/node-scep-challenges.ts new file mode 100644 index 0000000..65ff3b4 --- /dev/null +++ b/apps/console/src/lib/node-scep-challenges.ts @@ -0,0 +1,122 @@ +/* +Copyright The CryptOS Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +import { fleetClient } from "@/lib/fleet/client"; +import { fleetMode } from "@/lib/fleet/mode"; + +// NodeScepChallenge is a one-time SCEP challenge on a managed node, without +// the challenge itself, which only mintNodeScepChallenge's result carries. +export interface NodeScepChallenge { + boundNames: string[]; + createdAt: string; + createdByCn: string; + expiresAt: string; + id: string; + profile: string; +} + +const mockChallenges = (): NodeScepChallenge[] => [ + { + boundNames: [], + createdAt: "2026-10-14T00:00:00Z", + createdByCn: "admin@acme.example", + expiresAt: "2026-10-15T00:00:00Z", + id: "ch-mock-1", + profile: "network-device", + }, +]; + +// listNodeScepChallenges lists a managed node's usable SCEP challenges, +// soonest to expire first. Operator level or above; mock mode returns a +// small canned set. +export const listNodeScepChallenges = async (nodeName: string): Promise => { + if (fleetMode() === "mock") { + return mockChallenges(); + } + + const response = await fleetClient().listNodeScepChallenges({ nodeName }); + return response.challenges.map((c) => ({ + boundNames: c.boundNames, + createdAt: c.createdAt, + createdByCn: c.createdByCn, + expiresAt: c.expiresAt, + id: c.id, + profile: c.profile, + })); +}; + +export interface MintNodeScepChallengeInput { + boundNames: string[]; + profile: string; + ttlSeconds: number; +} + +export interface MintNodeScepChallengeResult { + challenge: NodeScepChallenge; + challengePassword: string; +} + +// mintNodeScepChallenge mints a one-time SCEP challenge password on a +// managed node, for example to enroll a network device via its SCEP +// trustpoint. The password is returned once; the caller must not persist it +// anywhere but the operator's own clipboard. +export const mintNodeScepChallenge = async ( + nodeName: string, + { boundNames, profile, ttlSeconds }: MintNodeScepChallengeInput, +): Promise => { + if (fleetMode() === "mock") { + return { + challenge: { + boundNames, + createdAt: new Date().toISOString(), + createdByCn: "you@acme.example", + expiresAt: new Date(Date.now() + ttlSeconds * 1000).toISOString(), + id: "ch-mock-new", + profile, + }, + challengePassword: "mock-challenge-password-00000000", + }; + } + + const response = await fleetClient().mintNodeScepChallenge({ + boundNames, + nodeName, + profile, + ttlSeconds, + }); + const challenge = response.challenge; + return { + challenge: { + boundNames: challenge?.boundNames ?? [], + createdAt: challenge?.createdAt ?? "", + createdByCn: challenge?.createdByCn ?? "", + expiresAt: challenge?.expiresAt ?? "", + id: challenge?.id ?? "", + profile: challenge?.profile ?? "", + }, + challengePassword: response.challengePassword, + }; +}; + +// revokeNodeScepChallenge withdraws a managed node's SCEP challenge before it +// is used or expires. +export const revokeNodeScepChallenge = async (nodeName: string, id: string): Promise => { + if (fleetMode() === "mock") { + return; + } + + await fleetClient().revokeNodeScepChallenge({ id, nodeName }); +}; diff --git a/apps/console/src/pages/node-detail.live.test.tsx b/apps/console/src/pages/node-detail.live.test.tsx index 9af6c3c..fb4cfc6 100644 --- a/apps/console/src/pages/node-detail.live.test.tsx +++ b/apps/console/src/pages/node-detail.live.test.tsx @@ -82,6 +82,7 @@ vi.mock("@/lib/fleet/client", () => ({ listCertificates: () => Promise.resolve(listCertificatesResult), listNodeAuditEvents: () => Promise.resolve({ entries: [], nextPageToken: "" }), listNodes: () => Promise.resolve(listNodesResult), + listNodeScepChallenges: () => Promise.resolve({ challenges: [] }), listNodeTsaCertificates: () => Promise.resolve({ certificates: [] }), verifyNodeAuditChain: () => Promise.resolve({ entryCount: 0n, firstBrokenSequence: 0n, intact: true, reason: "" }), @@ -113,6 +114,7 @@ describe("NodeDetailPage live", () => { expect(screen.getByText("Certificates")).toBeInTheDocument(); await screen.findByRole("button", { name: "Verify chain" }); await screen.findByText(/not running/i); + await screen.findByText(/no usable scep challenges/i); }); it("renders an established node", async () => { @@ -121,5 +123,6 @@ describe("NodeDetailPage live", () => { expect(await screen.findByRole("link", { name: "AA11" })).toBeInTheDocument(); await screen.findByRole("button", { name: "Verify chain" }); await screen.findByText(/not running/i); + await screen.findByText(/no usable scep challenges/i); }); }); diff --git a/apps/console/src/pages/node-detail.test.tsx b/apps/console/src/pages/node-detail.test.tsx index 1d81a55..262d1bf 100644 --- a/apps/console/src/pages/node-detail.test.tsx +++ b/apps/console/src/pages/node-detail.test.tsx @@ -40,9 +40,10 @@ describe("NodeDetailPage trust chain", () => { it("has no axe violations", async () => { const { container } = renderAt("/nodes/acme-issuing-01"); - // Lets the TSA certificates panel's async fetch settle under act() instead - // of resolving after the test returns. + // Lets the TSA certificates and SCEP challenges panels' async fetches + // settle under act() instead of resolving after the test returns. await screen.findByText("0a1b2c3d"); + await screen.findByText("ch-mock-1"); await expectNoA11yViolations(container); }); @@ -52,6 +53,7 @@ describe("NodeDetailPage trust chain", () => { // of resolving after the test returns. await screen.findByRole("button", { name: "Verify chain" }); await screen.findByText("0a1b2c3d"); + await screen.findByText("ch-mock-1"); const chain = screen.getByText(/trust chain/i).closest("div")?.parentElement as HTMLElement; expect(within(chain).getByRole("link", { name: "acme-root-01" })).toHaveAttribute( "href", diff --git a/apps/console/src/pages/node-detail.tsx b/apps/console/src/pages/node-detail.tsx index 7de355d..71a09c1 100644 --- a/apps/console/src/pages/node-detail.tsx +++ b/apps/console/src/pages/node-detail.tsx @@ -30,6 +30,7 @@ import { CertInventory } from "@/components/cert-inventory"; import { NodeAuditLog } from "@/components/node-audit-log"; import { NodeChainValidate } from "@/components/node-chain-validate"; import { NodeDetailPanel } from "@/components/node-detail-panel"; +import { NodeScepChallenges } from "@/components/node-scep-challenges"; import { NodeTsaCertificates } from "@/components/node-tsa-certificates"; import { roleLabels } from "@/lib/fleet/labels"; import { chainToRoot, useNode } from "@/lib/nodes"; @@ -161,6 +162,14 @@ export const NodeDetailPage = () => { + +
+ SCEP challenges +
+
+ +
+
From 7543abc740875565d5297a78a2e940862ea38300 Mon Sep 17 00:00:00 2001 From: Bugs5382 <12115015+Bugs5382@users.noreply.github.com> Date: Thu, 15 Oct 2026 15:23:45 -0400 Subject: [PATCH 3/3] chore(api-client): regenerate from cryptos-manager main Signed-off-by: Bugs5382 <12115015+Bugs5382@users.noreply.github.com> --- packages/api-client/proto-refs.env | 2 +- .../src/gen/cryptos/fleet/v1/fleet_pb.ts | 645 +++++++++++++++++- 2 files changed, 618 insertions(+), 29 deletions(-) diff --git a/packages/api-client/proto-refs.env b/packages/api-client/proto-refs.env index d91cd04..f294798 100644 --- a/packages/api-client/proto-refs.env +++ b/packages/api-client/proto-refs.env @@ -2,4 +2,4 @@ # `npm run generate -w @cryptos-pki/api-client`, and commit src/gen in the # same change. CRYPTOS_NODE_REF=8d8b52d5bafd4247db69c003a588ccf394d03f79 -CRYPTOS_MANAGER_REF=a1372b7a2c9345fa7d73c5fd243fab767d0f8b0a +CRYPTOS_MANAGER_REF=9a707eed187fc0335b09ad8f1b49465bb9290ac1 diff --git a/packages/api-client/src/gen/cryptos/fleet/v1/fleet_pb.ts b/packages/api-client/src/gen/cryptos/fleet/v1/fleet_pb.ts index 2cafd7d..967784c 100644 --- a/packages/api-client/src/gen/cryptos/fleet/v1/fleet_pb.ts +++ b/packages/api-client/src/gen/cryptos/fleet/v1/fleet_pb.ts @@ -18,7 +18,7 @@ import type { Message } from "@bufbuild/protobuf"; * Describes the file cryptos/fleet/v1/fleet.proto. */ export const file_cryptos_fleet_v1_fleet: GenFile = /*@__PURE__*/ - fileDesc("ChxjcnlwdG9zL2ZsZWV0L3YxL2ZsZWV0LnByb3RvEhBjcnlwdG9zLmZsZWV0LnYxIhIKEExpc3ROb2Rlc1JlcXVlc3QiQQoRTGlzdE5vZGVzUmVzcG9uc2USLAoFbm9kZXMYASADKAsyHS5jcnlwdG9zLmZsZWV0LnYxLk5vZGVTdW1tYXJ5Ii8KDkdldE5vZGVSZXF1ZXN0EgwKBG5hbWUYASABKAkSDwoHbm9kZV9pZBgCIAEoCSI9Cg9HZXROb2RlUmVzcG9uc2USKgoEbm9kZRgBIAEoCzIcLmNyeXB0b3MuZmxlZXQudjEuTm9kZURldGFpbCI4ChdMaXN0Q2VydGlmaWNhdGVzUmVxdWVzdBIMCgRub2RlGAEgASgJEg8KB25vZGVfaWQYAiABKAkiTwoYTGlzdENlcnRpZmljYXRlc1Jlc3BvbnNlEjMKDGNlcnRpZmljYXRlcxgBIAMoCzIdLmNyeXB0b3MuZmxlZXQudjEuQ2VydGlmaWNhdGUiFQoTTGlzdFByb2ZpbGVzUmVxdWVzdCJKChRMaXN0UHJvZmlsZXNSZXNwb25zZRIyCgVpdGVtcxgBIAMoCzIjLmNyeXB0b3Mubm9kZS52MS5DZXJ0aWZpY2F0ZVByb2ZpbGUiTAoUQ3JlYXRlUHJvZmlsZVJlcXVlc3QSNAoHcHJvZmlsZRgBIAEoCzIjLmNyeXB0b3Mubm9kZS52MS5DZXJ0aWZpY2F0ZVByb2ZpbGUiFwoVQ3JlYXRlUHJvZmlsZVJlc3BvbnNlIkwKFFVwZGF0ZVByb2ZpbGVSZXF1ZXN0EjQKB3Byb2ZpbGUYASABKAsyIy5jcnlwdG9zLm5vZGUudjEuQ2VydGlmaWNhdGVQcm9maWxlIhcKFVVwZGF0ZVByb2ZpbGVSZXNwb25zZSIkChREZWxldGVQcm9maWxlUmVxdWVzdBIMCgRuYW1lGAEgASgJIhcKFURlbGV0ZVByb2ZpbGVSZXNwb25zZSJVChlBcHBseVByb2ZpbGVUb05vZGVSZXF1ZXN0EhEKCW5vZGVfbmFtZRgBIAEoCRIUCgxwcm9maWxlX25hbWUYAiABKAkSDwoHbm9kZV9pZBgDIAEoCSJJChpBcHBseVByb2ZpbGVUb05vZGVSZXNwb25zZRISCgpnZW5lcmF0aW9uGAEgASgEEhcKD3JlcXVpcmVzX3JlYm9vdBgCIAEoCCJBChxTZXRQcm9maWxlUmVxdWVzdGFibGVSZXF1ZXN0EgwKBG5hbWUYASABKAkSEwoLcmVxdWVzdGFibGUYAiABKAgiHwodU2V0UHJvZmlsZVJlcXVlc3RhYmxlUmVzcG9uc2UiIAoeTGlzdFJlcXVlc3RhYmxlUHJvZmlsZXNSZXF1ZXN0IlUKH0xpc3RSZXF1ZXN0YWJsZVByb2ZpbGVzUmVzcG9uc2USMgoFaXRlbXMYASADKAsyIy5jcnlwdG9zLm5vZGUudjEuQ2VydGlmaWNhdGVQcm9maWxlIhUKE0xpc3RBZGFwdGVyc1JlcXVlc3QiSgoUTGlzdEFkYXB0ZXJzUmVzcG9uc2USMgoFaXRlbXMYASADKAsyIy5jcnlwdG9zLmZsZWV0LnYxLkVucm9sbG1lbnRBZGFwdGVyIjkKGFNldEFkYXB0ZXJFbmFibGVkUmVxdWVzdBIMCgRuYW1lGAEgASgJEg8KB2VuYWJsZWQYAiABKAgiUQoZU2V0QWRhcHRlckVuYWJsZWRSZXNwb25zZRI0CgdhZGFwdGVyGAEgASgLMiMuY3J5cHRvcy5mbGVldC52MS5FbnJvbGxtZW50QWRhcHRlciISChBMaXN0QXVkaXRSZXF1ZXN0IkAKEUxpc3RBdWRpdFJlc3BvbnNlEisKBWl0ZW1zGAEgAygLMhwuY3J5cHRvcy5mbGVldC52MS5BdWRpdEV2ZW50IhgKFkxpc3RFbnJvbGxtZW50c1JlcXVlc3QiTQoXTGlzdEVucm9sbG1lbnRzUmVzcG9uc2USMgoFaXRlbXMYASADKAsyIy5jcnlwdG9zLmZsZWV0LnYxLkVucm9sbG1lbnRSZXF1ZXN0IogCCgtOb2RlU3VtbWFyeRIMCgRuYW1lGAEgASgJEg8KB2FkZHJlc3MYAiABKAkSDAoEcm9sZRgDIAEoCRIWCg5pZGVudGl0eV9zdGF0ZRgEIAEoCRIKCgJjbhgFIAEoCRIOCgZpc3N1ZXIYBiABKAkSKAoGaGVhbHRoGAcgASgOMhguY3J5cHRvcy5mbGVldC52MS5IZWFsdGgSFQoNaGVhbHRoX2RldGFpbBgIIAEoCRIKCgJpZBgJIAEoCRIyCglwcm90b2NvbHMYCiADKAsyHy5jcnlwdG9zLm5vZGUudjEuUHJvdG9jb2xTdGF0dXMSFwoPcmVib290X3JlcXVpcmVkGAsgASgIIkkKDE5vZGVJZGVudGl0eRIRCgljaGFpbl9wZW0YASABKAkSEQoJY2hhaW5fZGVyGAIgAygMEhMKC2xlYWZfc2hhMjU2GAMgASgJIqkBCgpOb2RlRGV0YWlsEi4KB3N1bW1hcnkYASABKAsyHS5jcnlwdG9zLmZsZWV0LnYxLk5vZGVTdW1tYXJ5EjAKCGlkZW50aXR5GAIgASgLMh4uY3J5cHRvcy5mbGVldC52MS5Ob2RlSWRlbnRpdHkSFQoNdHBtX2F2YWlsYWJsZRgDIAEoCBISCgpib290X2NvdW50GAQgASgEEg4KBnVwdGltZRgFIAEoCSLYAQoLQ2VydGlmaWNhdGUSDgoGc2VyaWFsGAEgASgJEhIKCnN1YmplY3RfY24YAiABKAkSEwoLaXNzdWVyX25vZGUYAyABKAkSDAoEa2luZBgEIAEoCRIOCgZzdGF0dXMYBSABKAkSEgoKbm90X2JlZm9yZRgGIAEoCRIRCglub3RfYWZ0ZXIYByABKAkSDwoHcHJvZmlsZRgIIAEoCRISCgpyZXZva2VkX2F0GAkgASgJEg4KBnJlYXNvbhgKIAEoCRIWCg5pc3N1ZXJfbm9kZV9pZBgLIAEoCSKNAQoRRW5yb2xsbWVudEFkYXB0ZXISDAoEa2luZBgBIAEoCRIMCgRuYW1lGAIgASgJEhAKCGVuZHBvaW50GAMgASgJEg8KB3Byb2ZpbGUYBCABKAkSDwoHZW5hYmxlZBgFIAEoCBISCgpjaGFsbGVuZ2VzGAYgAygJEhQKDGdwb190ZW1wbGF0ZRgHIAEoCSK8AgoKQXVkaXRFdmVudBIKCgJpZBgBIAEoCRIKCgJhdBgCIAEoCRIMCgRraW5kGAMgASgJEg8KB3N1bW1hcnkYBCABKAkSEwoLdGFyZ2V0X2tpbmQYBSABKAkSEwoLdGFyZ2V0X3BhdGgYBiABKAkSEgoKYWN0b3Jfa2luZBgHIAEoCRIQCghhY3Rvcl9jbhgIIAEoCRIUCgxhY3Rvcl9zZXJpYWwYCSABKAkSDgoGa2V5X2lkGAogASgJEgsKA3ZpYRgLIAEoCRIMCgR0b29sGAwgASgJEhYKDnJlcXVlc3RfZGlnZXN0GA0gASgJEg8KB291dGNvbWUYDiABKAkSEwoLYXBwcm92YWxfaWQYDyABKAkSFwoPYXBwcm92ZXJfc2VyaWFsGBAgASgJEg8KB25vZGVfaWQYESABKAki7wIKEUVucm9sbG1lbnRSZXF1ZXN0EgoKAmlkGAEgASgJEhUKDXByb3Bvc2VkX25hbWUYAiABKAkSDAoEcm9sZRgDIAEoCRIRCglwYXJlbnRfY24YBCABKAkSDwoHYWRkcmVzcxgFIAEoCRIOCgZzdGF0dXMYBiABKAkSGwoTYXR0ZXN0YXRpb25fc3VtbWFyeRgHIAEoCRIbChNhdHRlc3RhdGlvbl9ub2RlX2lkGAggASgJEhQKDGNzcl9rZXlfdHlwZRgJIAEoCRIWCg5jc3Jfc3ViamVjdF9jbhgKIAEoCRIUCgxyZXF1ZXN0ZWRfYXQYCyABKAkSGAoQcmVqZWN0aW9uX3JlYXNvbhgMIAEoCRIaChJhZG1pdHRlZF9ub2RlX25hbWUYDSABKAkSDAoEa2luZBgOIAEoCRIZChFwaW5uZWRfa2V5X3NoYTI1NhgPIAEoCRIYChBhZG1pdHRlZF9ub2RlX2lkGBAgASgJIswBChdDcmVhdGVFbnJvbGxtZW50UmVxdWVzdBIMCgRraW5kGAEgASgJEhUKDW5vZGVfZW5kcG9pbnQYAiABKAkSFgoOYWRtaW5fY2VydF9wZW0YAyABKAkSFQoNYWRtaW5fa2V5X3BlbRgEIAEoCRIOCgZjYV9wZW0YBSABKAkSEgoKY2hpbGRfbm9kZRgGIAEoCRIRCglwYXJlbnRfY24YByABKAkSDwoHcHJvZmlsZRgIIAEoCRIVCg1jaGlsZF9ub2RlX2lkGAkgASgJIlMKGENyZWF0ZUVucm9sbG1lbnRSZXNwb25zZRI3CgplbnJvbGxtZW50GAEgASgLMiMuY3J5cHRvcy5mbGVldC52MS5FbnJvbGxtZW50UmVxdWVzdCJ8ChhBcHByb3ZlRW5yb2xsbWVudFJlcXVlc3QSCgoCaWQYASABKAkSFQoNbm9kZV9lbmRwb2ludBgCIAEoCRIWCg5hZG1pbl9jZXJ0X3BlbRgDIAEoCRIVCg1hZG1pbl9rZXlfcGVtGAQgASgJEg4KBmNhX3BlbRgFIAEoCSJUChlBcHByb3ZlRW5yb2xsbWVudFJlc3BvbnNlEjcKCmVucm9sbG1lbnQYASABKAsyIy5jcnlwdG9zLmZsZWV0LnYxLkVucm9sbG1lbnRSZXF1ZXN0IjUKF1JlamVjdEVucm9sbG1lbnRSZXF1ZXN0EgoKAmlkGAEgASgJEg4KBnJlYXNvbhgCIAEoCSJTChhSZWplY3RFbnJvbGxtZW50UmVzcG9uc2USNwoKZW5yb2xsbWVudBgBIAEoCzIjLmNyeXB0b3MuZmxlZXQudjEuRW5yb2xsbWVudFJlcXVlc3QiDwoNV2hvQW1JUmVxdWVzdCI9ChBPcGVyYXRvcklkZW50aXR5EgoKAmNuGAEgASgJEg4KBnNlcmlhbBgCIAEoCRINCgVsZXZlbBgDIAEoCSJGCg5XaG9BbUlSZXNwb25zZRI0CghvcGVyYXRvchgBIAEoCzIiLmNyeXB0b3MuZmxlZXQudjEuT3BlcmF0b3JJZGVudGl0eSJnChhSZXZva2VDZXJ0aWZpY2F0ZVJlcXVlc3QSEQoJbm9kZV9uYW1lGAEgASgJEhIKCnNlcmlhbF9oZXgYAiABKAkSEwoLcmVhc29uX2NvZGUYAyABKAUSDwoHbm9kZV9pZBgEIAEoCSJYChlSZXZva2VDZXJ0aWZpY2F0ZVJlc3BvbnNlEhIKCnNlcmlhbF9oZXgYASABKAkSEgoKcmV2b2tlZF9hdBgCIAEoCRITCgtyZWFzb25fY29kZRgDIAEoBSI+ChVHZXRDZXJ0aWZpY2F0ZVJlcXVlc3QSEQoJbm9kZV9uYW1lGAEgASgJEhIKCnNlcmlhbF9oZXgYAiABKAkiaAoWR2V0Q2VydGlmaWNhdGVSZXNwb25zZRIXCg9jZXJ0aWZpY2F0ZV9wZW0YASABKAkSEQoJY2hhaW5fcGVtGAIgASgJEg4KBnN0YXR1cxgDIAEoCRISCgpyZXZva2VkX2F0GAQgASgJIl0KEElzc3VlTGVhZlJlcXVlc3QSEQoJbm9kZV9uYW1lGAEgASgJEg8KB2Nzcl9kZXIYAiABKAwSFAoMcHJvZmlsZV9uYW1lGAMgASgJEg8KB25vZGVfaWQYBCABKAkiJQoRSXNzdWVMZWFmUmVzcG9uc2USEAoIY2VydF9kZXIYASABKAwiTAoQUmVrZXlOb2RlUmVxdWVzdBIRCglub2RlX25hbWUYASABKAkSFAoMcHJvZmlsZV9uYW1lGAIgASgJEg8KB25vZGVfaWQYAyABKAkiTQoRUmVrZXlOb2RlUmVzcG9uc2USEgoKc3ViamVjdF9jbhgBIAEoCRIRCglpc3N1ZXJfY24YAiABKAkSEQoJY2hhaW5fbGVuGAMgASgFIjoKFEdldE5vZGVDb25maWdSZXF1ZXN0EhEKCW5vZGVfbmFtZRgBIAEoCRIPCgdub2RlX2lkGAIgASgJIkcKFUdldE5vZGVDb25maWdSZXNwb25zZRIuCgZjb25maWcYASABKAsyHi5jcnlwdG9zLm5vZGUudjEuTWFjaGluZUNvbmZpZyJsChZBcHBseU5vZGVDb25maWdSZXF1ZXN0EhEKCW5vZGVfbmFtZRgBIAEoCRIuCgZjb25maWcYAiABKAsyHi5jcnlwdG9zLm5vZGUudjEuTWFjaGluZUNvbmZpZxIPCgdub2RlX2lkGAMgASgJIkYKF0FwcGx5Tm9kZUNvbmZpZ1Jlc3BvbnNlEhIKCmdlbmVyYXRpb24YASABKAQSFwoPcmVxdWlyZXNfcmVib290GAIgASgIInAKFlNldE5vZGVQcm90b2NvbFJlcXVlc3QSEQoJbm9kZV9uYW1lGAEgASgJEjIKCHByb3RvY29sGAIgASgOMiAuY3J5cHRvcy5ub2RlLnYxLlNlcnZpY2VQcm90b2NvbBIPCgdlbmFibGVkGAMgASgIIkYKF1NldE5vZGVQcm90b2NvbFJlc3BvbnNlEhIKCmdlbmVyYXRpb24YASABKAQSFwoPcmVxdWlyZXNfcmVib290GAIgASgIIkwKEkV4cG9ydENBS2V5UmVxdWVzdBIRCglub2RlX25hbWUYASABKAkSEgoKcGFzc3BocmFzZRgCIAEoDBIPCgdub2RlX2lkGAMgASgJIicKE0V4cG9ydENBS2V5UmVzcG9uc2USEAoIZW52ZWxvcGUYASABKAwiXgoSSW1wb3J0Q0FLZXlSZXF1ZXN0EhEKCW5vZGVfbmFtZRgBIAEoCRIQCghlbnZlbG9wZRgCIAEoDBISCgpwYXNzcGhyYXNlGAMgASgMEg8KB25vZGVfaWQYBCABKAkiPAoTSW1wb3J0Q0FLZXlSZXNwb25zZRISCgpzdWJqZWN0X2NuGAEgASgJEhEKCWlzc3Vlcl9jbhgCIAEoCSJvCh9SZXZva2VPcGVyYXRvckNyZWRlbnRpYWxSZXF1ZXN0EhIKCnNlcmlhbF9oZXgYASABKAkSEwoLcmVhc29uX2NvZGUYAiABKAUSFQoNaXNzdWVyX3NoYTI1NhgDIAEoCRIMCgRub3RlGAQgASgJInMKIFJldm9rZU9wZXJhdG9yQ3JlZGVudGlhbFJlc3BvbnNlEhIKCnNlcmlhbF9oZXgYASABKAkSEgoKcmV2b2tlZF9hdBgCIAEoCRIVCg1pc3N1ZXJfc2hhMjU2GAMgASgJEhAKCHdhcm5pbmdzGAQgAygJIiAKHkxpc3RPcGVyYXRvckNyZWRlbnRpYWxzUmVxdWVzdCKNAgoST3BlcmF0b3JDcmVkZW50aWFsEhMKC2NvbW1vbl9uYW1lGAEgASgJEhIKCnNlcmlhbF9oZXgYAiABKAkSDQoFbGV2ZWwYAyABKAkSEQoJbm90X2FmdGVyGAQgASgJEg8KB3Jldm9rZWQYBSABKAgSDAoEa2luZBgGIAEoCRIVCg1pc3N1ZXJfc2hhMjU2GAcgASgJEg0KBWVtYWlsGAggASgJEhEKCWZ1bGxfbmFtZRgJIAEoCRISCgpkZW55bGlzdGVkGAogASgIEhMKC2NybF9yZXZva2VkGAsgASgIEhUKDWZpcnN0X3NlZW5fYXQYDCABKAkSFAoMbGFzdF9zZWVuX2F0GA0gASgJIlYKH0xpc3RPcGVyYXRvckNyZWRlbnRpYWxzUmVzcG9uc2USMwoFaXRlbXMYASADKAsyJC5jcnlwdG9zLmZsZWV0LnYxLk9wZXJhdG9yQ3JlZGVudGlhbCJqCiZDcmVhdGVPcGVyYXRvckNyZWRlbnRpYWxSZXF1ZXN0UmVxdWVzdBINCgVsZXZlbBgBIAEoCRINCgVlbWFpbBgCIAEoCRIRCglmdWxsX25hbWUYAyABKAkSDwoHY3NyX2RlchgEIAEoDCKUAQonQ3JlYXRlT3BlcmF0b3JDcmVkZW50aWFsUmVxdWVzdFJlc3BvbnNlEhIKCnJlcXVlc3RfaWQYASABKAkSDwoHY3NyX3BlbRgCIAEoCRIXCg9leHRmaWxlX3NlY3Rpb24YAyABKAkSFwoPb3BlbnNzbF9jb21tYW5kGAQgASgJEhIKCmV4cGlyZXNfYXQYBSABKAkiNgolTGlzdE9wZXJhdG9yQ3JlZGVudGlhbFJlcXVlc3RzUmVxdWVzdBINCgVzdGF0ZRgBIAEoCSJkCiZMaXN0T3BlcmF0b3JDcmVkZW50aWFsUmVxdWVzdHNSZXNwb25zZRI6CgVpdGVtcxgBIAMoCzIrLmNyeXB0b3MuZmxlZXQudjEuT3BlcmF0b3JDcmVkZW50aWFsUmVxdWVzdCI8CiZDYW5jZWxPcGVyYXRvckNyZWRlbnRpYWxSZXF1ZXN0UmVxdWVzdBISCgpyZXF1ZXN0X2lkGAEgASgJImcKJ0NhbmNlbE9wZXJhdG9yQ3JlZGVudGlhbFJlcXVlc3RSZXNwb25zZRI8CgdyZXF1ZXN0GAEgASgLMisuY3J5cHRvcy5mbGVldC52MS5PcGVyYXRvckNyZWRlbnRpYWxSZXF1ZXN0ItEBChlPcGVyYXRvckNyZWRlbnRpYWxSZXF1ZXN0EgoKAmlkGAEgASgJEg0KBWxldmVsGAIgASgJEg0KBWVtYWlsGAMgASgJEhEKCWZ1bGxfbmFtZRgEIAEoCRIPCgdjc3JfcGVtGAUgASgJEg0KBXN0YXRlGAYgASgJEhUKDWNyZWF0ZWRfYnlfY24YByABKAkSEgoKY3JlYXRlZF9hdBgIIAEoCRISCgpleHBpcmVzX2F0GAkgASgJEhgKEGNvbXBsZXRlZF9zZXJpYWwYCiABKAkiWgofUmVjb3JkT3BlcmF0b3JDcmVkZW50aWFsUmVxdWVzdBIQCghjZXJ0X2RlchgBIAEoDBISCgpyZXF1ZXN0X2lkGAIgASgJEhEKCWZ1bGxfbmFtZRgDIAEoCSJuCiBSZWNvcmRPcGVyYXRvckNyZWRlbnRpYWxSZXNwb25zZRI4CgpjcmVkZW50aWFsGAEgASgLMiQuY3J5cHRvcy5mbGVldC52MS5PcGVyYXRvckNyZWRlbnRpYWwSEAoId2FybmluZ3MYAiADKAkiGAoWTGlzdE9wZXJhdG9yQ0FzUmVxdWVzdCJGChdMaXN0T3BlcmF0b3JDQXNSZXNwb25zZRIrCgVpdGVtcxgBIAMoCzIcLmNyeXB0b3MuZmxlZXQudjEuT3BlcmF0b3JDQSKQAgoZUmVnaXN0ZXJPcGVyYXRvckNBUmVxdWVzdBITCgtjYV9jZXJ0X2RlchgBIAEoDBINCgN1cmwYAiABKAlIABIRCgdjcmxfZGVyGAMgASgMSAASDgoEbm9uZRgEIAEoCEgAEi0KCW9jc3BfbW9kZRgFIAEoDjIaLmNyeXB0b3MuZmxlZXQudjEuT2NzcE1vZGUSEAoIb2NzcF91cmwYBiABKAkSRQoQYWNrbm93bGVkZ2VtZW50cxgHIAMoDjIrLmNyeXB0b3MuZmxlZXQudjEuT3BlcmF0b3JDQUFja25vd2xlZGdlbWVudBIWCg5jb25maXJtX3NoYTI1NhgIIAEoCUIMCgpjcmxfc291cmNlIrABChpSZWdpc3Rlck9wZXJhdG9yQ0FSZXNwb25zZRIxCgtvcGVyYXRvcl9jYRgBIAEoCzIcLmNyeXB0b3MuZmxlZXQudjEuT3BlcmF0b3JDQRIRCgljb25maXJtZWQYAiABKAgSFQoNYWRtaW5fZXh0ZmlsZRgDIAEoCRI1CgpvY3NwX3Byb2JlGAQgASgLMiEuY3J5cHRvcy5mbGVldC52MS5PY3NwUHJvYmVSZXN1bHQiTAoXUmV0aXJlT3BlcmF0b3JDQVJlcXVlc3QSDgoGc2hhMjU2GAEgASgJEiEKGWlfdW5kZXJzdGFuZF9zZWxmX2xvY2tvdXQYAiABKAgiTQoYUmV0aXJlT3BlcmF0b3JDQVJlc3BvbnNlEjEKC29wZXJhdG9yX2NhGAEgASgLMhwuY3J5cHRvcy5mbGVldC52MS5PcGVyYXRvckNBIrYBCh1TZXRPcGVyYXRvckNBQ1JMU291cmNlUmVxdWVzdBIOCgZzaGEyNTYYASABKAkSDQoDdXJsGAIgASgJSAASDgoEbm9uZRgDIAEoCEgAEhEKB2NybF9kZXIYBSABKAxIABJFChBhY2tub3dsZWRnZW1lbnRzGAQgAygOMisuY3J5cHRvcy5mbGVldC52MS5PcGVyYXRvckNBQWNrbm93bGVkZ2VtZW50QgwKCmNybF9zb3VyY2UiUwoeU2V0T3BlcmF0b3JDQUNSTFNvdXJjZVJlc3BvbnNlEjEKC29wZXJhdG9yX2NhGAEgASgLMhwuY3J5cHRvcy5mbGVldC52MS5PcGVyYXRvckNBIjsKGFVwbG9hZE9wZXJhdG9yQ1JMUmVxdWVzdBIOCgZzaGEyNTYYASABKAkSDwoHY3JsX2RlchgCIAEoDCJOChlVcGxvYWRPcGVyYXRvckNSTFJlc3BvbnNlEjEKC29wZXJhdG9yX2NhGAEgASgLMhwuY3J5cHRvcy5mbGVldC52MS5PcGVyYXRvckNBImsKGFNldE9wZXJhdG9yQ0FPQ1NQUmVxdWVzdBIOCgZzaGEyNTYYASABKAkSLQoJb2NzcF9tb2RlGAIgASgOMhouY3J5cHRvcy5mbGVldC52MS5PY3NwTW9kZRIQCghvY3NwX3VybBgDIAEoCSKFAQoZU2V0T3BlcmF0b3JDQU9DU1BSZXNwb25zZRIxCgtvcGVyYXRvcl9jYRgBIAEoCzIcLmNyeXB0b3MuZmxlZXQudjEuT3BlcmF0b3JDQRI1CgpvY3NwX3Byb2JlGAIgASgLMiEuY3J5cHRvcy5mbGVldC52MS5PY3NwUHJvYmVSZXN1bHQiKgoWUHJldmlld0Fkb3B0aW9uUmVxdWVzdBIQCghlbmRwb2ludBgBIAEoCSI/ChdQcmV2aWV3QWRvcHRpb25SZXNwb25zZRITCgtjZXJ0X3NoYTI1NhgBIAEoCRIPCgdzdWJqZWN0GAIgASgJIkcKF0xpc3RJbnN0YWxsRGlza3NSZXF1ZXN0EhAKCGVuZHBvaW50GAEgASgJEhoKEnBpbm5lZF9jZXJ0X3NoYTI1NhgCIAEoCSJHChhMaXN0SW5zdGFsbERpc2tzUmVzcG9uc2USKwoFZGlza3MYASADKAsyHC5jcnlwdG9zLm5vZGUudjEuSW5zdGFsbERpc2sicAoQQWRvcHROb2RlUmVxdWVzdBIQCghlbmRwb2ludBgBIAEoCRIaChJwaW5uZWRfY2VydF9zaGEyNTYYAiABKAkSLgoGY29uZmlnGAMgASgLMh4uY3J5cHRvcy5ub2RlLnYxLk1hY2hpbmVDb25maWcihQEKEUFkb3B0Tm9kZVJlc3BvbnNlEg0KBXBoYXNlGAEgASgJEg4KBmRldGFpbBgCIAEoCRIMCgRkb25lGAMgASgIEg8KB25vZGVfaWQYBCABKAkSEwoLYWRvcHRpb25faWQYBSABKAkSHQoVcHJlc2VudGVkX2NlcnRfc2hhMjU2GAYgASgJIk0KIUNvbmZpcm1BZG9wdGlvbkZpbmdlcnByaW50UmVxdWVzdBITCgthZG9wdGlvbl9pZBgBIAEoCRITCgtjZXJ0X3NoYTI1NhgCIAEoCSIkCiJDb25maXJtQWRvcHRpb25GaW5nZXJwcmludFJlc3BvbnNlIloKF0RlY29tbWlzc2lvbk5vZGVSZXF1ZXN0EhEKCW5vZGVfbmFtZRgBIAEoCRIbChNjb25maXJtX2NvbW1vbl9uYW1lGAIgASgJEg8KB25vZGVfaWQYAyABKAkiLQoYRGVjb21taXNzaW9uTm9kZVJlc3BvbnNlEhEKCXJlYm9vdGluZxgBIAEoCCJhChFSZWJvb3ROb2RlUmVxdWVzdBIRCglub2RlX25hbWUYASABKAkSFQoNY29uZmlybV9jYV9jbhgCIAEoCRIRCglwb3dlcl9vZmYYAyABKAgSDwoHbm9kZV9pZBgEIAEoCSInChJSZWJvb3ROb2RlUmVzcG9uc2USEQoJcmVib290aW5nGAEgASgIIjYKEVJlbmFtZU5vZGVSZXF1ZXN0Eg8KB25vZGVfaWQYASABKAkSEAoIbmV3X25hbWUYAiABKAkiQQoSUmVuYW1lTm9kZVJlc3BvbnNlEisKBG5vZGUYASABKAsyHS5jcnlwdG9zLmZsZWV0LnYxLk5vZGVTdW1tYXJ5IjoKEVJlbW92ZU5vZGVSZXF1ZXN0Eg8KB25vZGVfaWQYASABKAkSFAoMY29uZmlybV9uYW1lGAIgASgJIkEKElJlbW92ZU5vZGVSZXNwb25zZRIrCgRub2RlGAEgASgLMh0uY3J5cHRvcy5mbGVldC52MS5Ob2RlU3VtbWFyeSIhChJMaXN0TWNwS2V5c1JlcXVlc3QSCwoDYWxsGAEgASgIIj4KE0xpc3RNY3BLZXlzUmVzcG9uc2USJwoFaXRlbXMYASADKAsyGC5jcnlwdG9zLmZsZWV0LnYxLk1jcEtleSIhChNSZXZva2VNY3BLZXlSZXF1ZXN0EgoKAmlkGAEgASgJIkEKFFJldm9rZU1jcEtleVJlc3BvbnNlEikKB21jcF9rZXkYASABKAsyGC5jcnlwdG9zLmZsZWV0LnYxLk1jcEtleSI7ChNDcmVhdGVNY3BLZXlSZXF1ZXN0Eg0KBWxhYmVsGAEgASgJEhUKDWxldmVsX2NlaWxpbmcYAiABKAkiWAoUQ3JlYXRlTWNwS2V5UmVzcG9uc2USFQoNcGxhaW50ZXh0X2tleRgBIAEoCRIpCgdtY3Bfa2V5GAIgASgLMhguY3J5cHRvcy5mbGVldC52MS5NY3BLZXkiuwEKBk1jcEtleRIKCgJpZBgBIAEoCRINCgVsYWJlbBgCIAEoCRITCgtjbGllbnRfbmFtZRgDIAEoCRITCgtvcGVyYXRvcl9jbhgEIAEoCRIXCg9vcGVyYXRvcl9zZXJpYWwYBSABKAkSFQoNbGV2ZWxfY2VpbGluZxgGIAEoCRISCgpjcmVhdGVkX2F0GAcgASgJEhQKDGxhc3RfdXNlZF9hdBgIIAEoCRISCgpyZXZva2VkX2F0GAkgASgJIiYKFExpc3RBcHByb3ZhbHNSZXF1ZXN0Eg4KBnN0YXR1cxgBIAEoCSJCChVMaXN0QXBwcm92YWxzUmVzcG9uc2USKQoFaXRlbXMYASADKAsyGi5jcnlwdG9zLmZsZWV0LnYxLkFwcHJvdmFsIjQKFURlY2lkZUFwcHJvdmFsUmVxdWVzdBIKCgJpZBgBIAEoCRIPCgdhcHByb3ZlGAIgASgIIkYKFkRlY2lkZUFwcHJvdmFsUmVzcG9uc2USLAoIYXBwcm92YWwYASABKAsyGi5jcnlwdG9zLmZsZWV0LnYxLkFwcHJvdmFsIrcCCghBcHByb3ZhbBIKCgJpZBgBIAEoCRIMCgR0b29sGAIgASgJEg8KB3N1bW1hcnkYAyABKAkSFgoOcmVxdWVzdF9kaWdlc3QYBCABKAkSFwoPcmVxdWVzdGVkX2J5X2NuGAUgASgJEhsKE3JlcXVlc3RlZF9ieV9zZXJpYWwYBiABKAkSDgoGa2V5X2lkGAcgASgJEhYKDnJlcXVpcmVkX2xldmVsGAggASgJEhIKCmNyZWF0ZWRfYXQYCSABKAkSEgoKZXhwaXJlc19hdBgKIAEoCRIOCgZzdGF0dXMYCyABKAkSFQoNZGVjaWRlZF9ieV9jbhgMIAEoCRIZChFkZWNpZGVkX2J5X3NlcmlhbBgNIAEoCRISCgpkZWNpZGVkX2F0GA4gASgJEgwKBGtpbmQYDyABKAkirwIKEkNlcnRpZmljYXRlUmVxdWVzdBIKCgJpZBgBIAEoCRIUCgxwcm9maWxlX25hbWUYAiABKAkSDwoHY3NyX3BlbRgDIAEoCRIMCgRub3RlGAQgASgJEhcKD3JlcXVlc3RlZF9ieV9jbhgFIAEoCRIbChNyZXF1ZXN0ZWRfYnlfc2VyaWFsGAYgASgJEg0KBXN0YXRlGAcgASgJEhMKC2FwcHJvdmFsX2lkGAggASgJEhcKD2NlcnRpZmljYXRlX3BlbRgJIAEoCRIWCg5mYWlsdXJlX3JlYXNvbhgKIAEoCRISCgpjcmVhdGVkX2F0GAsgASgJEhIKCmV4cGlyZXNfYXQYDCABKAkSEgoKZGVjaWRlZF9hdBgNIAEoCRIRCglpc3N1ZWRfYXQYDiABKAkiVgofQ3JlYXRlQ2VydGlmaWNhdGVSZXF1ZXN0UmVxdWVzdBIUCgxwcm9maWxlX25hbWUYASABKAkSDwoHY3NyX2RlchgCIAEoDBIMCgRub3RlGAMgASgJIlkKIENyZWF0ZUNlcnRpZmljYXRlUmVxdWVzdFJlc3BvbnNlEjUKB3JlcXVlc3QYASABKAsyJC5jcnlwdG9zLmZsZWV0LnYxLkNlcnRpZmljYXRlUmVxdWVzdCJCCh5MaXN0Q2VydGlmaWNhdGVSZXF1ZXN0c1JlcXVlc3QSDQoFc3RhdGUYASABKAkSEQoJbWluZV9vbmx5GAIgASgIIlYKH0xpc3RDZXJ0aWZpY2F0ZVJlcXVlc3RzUmVzcG9uc2USMwoFaXRlbXMYASADKAsyJC5jcnlwdG9zLmZsZWV0LnYxLkNlcnRpZmljYXRlUmVxdWVzdCIuCiBHZXRDZXJ0aWZpY2F0ZVJlcXVlc3RCeUlEUmVxdWVzdBIKCgJpZBgBIAEoCSJaCiFHZXRDZXJ0aWZpY2F0ZVJlcXVlc3RCeUlEUmVzcG9uc2USNQoHcmVxdWVzdBgBIAEoCzIkLmNyeXB0b3MuZmxlZXQudjEuQ2VydGlmaWNhdGVSZXF1ZXN0Ii0KH0NhbmNlbENlcnRpZmljYXRlUmVxdWVzdFJlcXVlc3QSCgoCaWQYASABKAkiWQogQ2FuY2VsQ2VydGlmaWNhdGVSZXF1ZXN0UmVzcG9uc2USNQoHcmVxdWVzdBgBIAEoCzIkLmNyeXB0b3MuZmxlZXQudjEuQ2VydGlmaWNhdGVSZXF1ZXN0IkQKHkxpc3ROb2RlVHNhQ2VydGlmaWNhdGVzUmVxdWVzdBIRCglub2RlX25hbWUYASABKAkSDwoHbm9kZV9pZBgCIAEoCSKGAQoSTm9kZVRzYUNlcnRpZmljYXRlEhAKCGNlcnRfcGVtGAEgASgJEhIKCnNlcmlhbF9oZXgYAiABKAkSEgoKc2hhMjU2X2hleBgDIAEoCRISCgpub3RfYmVmb3JlGAQgASgJEhEKCW5vdF9hZnRlchgFIAEoCRIPCgdjdXJyZW50GAYgASgIIl0KH0xpc3ROb2RlVHNhQ2VydGlmaWNhdGVzUmVzcG9uc2USOgoMY2VydGlmaWNhdGVzGAEgAygLMiQuY3J5cHRvcy5mbGVldC52MS5Ob2RlVHNhQ2VydGlmaWNhdGUiXgofVmFsaWRhdGVDZXJ0aWZpY2F0ZUNoYWluUmVxdWVzdBIRCglub2RlX25hbWUYASABKAkSDwoHbm9kZV9pZBgCIAEoCRIXCg9jZXJ0aWZpY2F0ZV9wZW0YAyABKAkiewogVmFsaWRhdGVDZXJ0aWZpY2F0ZUNoYWluUmVzcG9uc2USDQoFdmFsaWQYASABKAgSDgoGcmVhc29uGAIgASgJEg8KB3N1YmplY3QYAyABKAkSDgoGaXNzdWVyGAQgASgJEhcKD25vZGVfY2Ffc3ViamVjdBgFIAEoCSKuAQoaTGlzdE5vZGVBdWRpdEV2ZW50c1JlcXVlc3QSEQoJbm9kZV9uYW1lGAEgASgJEg8KB25vZGVfaWQYAiABKAkSEQoJcGFnZV9zaXplGAMgASgFEhIKCnBhZ2VfdG9rZW4YBCABKAkSEQoJZnJvbV90aW1lGAUgASgJEg8KB3RvX3RpbWUYBiABKAkSEgoKZXZlbnRfdHlwZRgHIAEoCRINCgVhY3RvchgIIAEoCSKQAgoOTm9kZUF1ZGl0RXZlbnQSCwoDc2VxGAEgASgEEgoKAnRzGAIgASgJEhUKDWFjdG9yX3N1YmplY3QYAyABKAkSEgoKcnBjX21ldGhvZBgEIAEoCRIPCgdvdXRjb21lGAUgASgJEj4KB2RldGFpbHMYBiADKAsyLS5jcnlwdG9zLmZsZWV0LnYxLk5vZGVBdWRpdEV2ZW50LkRldGFpbHNFbnRyeRIYChBlbnRyeV9zaGEyNTZfaGV4GAcgASgJEg4KBnRhcmdldBgIIAEoCRIPCgdzdW1tYXJ5GAkgASgJGi4KDERldGFpbHNFbnRyeRILCgNrZXkYASABKAkSDQoFdmFsdWUYAiABKAk6AjgBImkKG0xpc3ROb2RlQXVkaXRFdmVudHNSZXNwb25zZRIxCgdlbnRyaWVzGAEgAygLMiAuY3J5cHRvcy5mbGVldC52MS5Ob2RlQXVkaXRFdmVudBIXCg9uZXh0X3BhZ2VfdG9rZW4YAiABKAkiQQobVmVyaWZ5Tm9kZUF1ZGl0Q2hhaW5SZXF1ZXN0EhEKCW5vZGVfbmFtZRgBIAEoCRIPCgdub2RlX2lkGAIgASgJInIKHFZlcmlmeU5vZGVBdWRpdENoYWluUmVzcG9uc2USEwoLZW50cnlfY291bnQYASABKAQSDgoGaW50YWN0GAIgASgIEh0KFWZpcnN0X2Jyb2tlbl9zZXF1ZW5jZRgDIAEoBBIOCgZyZWFzb24YBCABKAkihAEKEU5vZGVTY2VwQ2hhbGxlbmdlEgoKAmlkGAEgASgJEg8KB3Byb2ZpbGUYAiABKAkSEwoLYm91bmRfbmFtZXMYAyADKAkSEgoKY3JlYXRlZF9hdBgEIAEoCRISCgpleHBpcmVzX2F0GAUgASgJEhUKDWNyZWF0ZWRfYnlfY24YBiABKAkifQocTWludE5vZGVTY2VwQ2hhbGxlbmdlUmVxdWVzdBIRCglub2RlX25hbWUYASABKAkSDwoHbm9kZV9pZBgCIAEoCRIPCgdwcm9maWxlGAMgASgJEhMKC3R0bF9zZWNvbmRzGAQgASgNEhMKC2JvdW5kX25hbWVzGAUgAygJInMKHU1pbnROb2RlU2NlcENoYWxsZW5nZVJlc3BvbnNlEhoKEmNoYWxsZW5nZV9wYXNzd29yZBgBIAEoCRI2CgljaGFsbGVuZ2UYAiABKAsyIy5jcnlwdG9zLmZsZWV0LnYxLk5vZGVTY2VwQ2hhbGxlbmdlIkMKHUxpc3ROb2RlU2NlcENoYWxsZW5nZXNSZXF1ZXN0EhEKCW5vZGVfbmFtZRgBIAEoCRIPCgdub2RlX2lkGAIgASgJIlkKHkxpc3ROb2RlU2NlcENoYWxsZW5nZXNSZXNwb25zZRI3CgpjaGFsbGVuZ2VzGAEgAygLMiMuY3J5cHRvcy5mbGVldC52MS5Ob2RlU2NlcENoYWxsZW5nZSJQCh5SZXZva2VOb2RlU2NlcENoYWxsZW5nZVJlcXVlc3QSEQoJbm9kZV9uYW1lGAEgASgJEg8KB25vZGVfaWQYAiABKAkSCgoCaWQYAyABKAkiWQofUmV2b2tlTm9kZVNjZXBDaGFsbGVuZ2VSZXNwb25zZRI2CgljaGFsbGVuZ2UYASABKAsyIy5jcnlwdG9zLmZsZWV0LnYxLk5vZGVTY2VwQ2hhbGxlbmdlKlIKBkhlYWx0aBIWChJIRUFMVEhfVU5TUEVDSUZJRUQQABINCglIRUFMVEhfVVAQARIPCgtIRUFMVEhfRE9XThACEhAKDEhFQUxUSF9FUlJPUhADMoI2CgxGbGVldFNlcnZpY2USVAoJTGlzdE5vZGVzEiIuY3J5cHRvcy5mbGVldC52MS5MaXN0Tm9kZXNSZXF1ZXN0GiMuY3J5cHRvcy5mbGVldC52MS5MaXN0Tm9kZXNSZXNwb25zZRJOCgdHZXROb2RlEiAuY3J5cHRvcy5mbGVldC52MS5HZXROb2RlUmVxdWVzdBohLmNyeXB0b3MuZmxlZXQudjEuR2V0Tm9kZVJlc3BvbnNlEmkKEExpc3RDZXJ0aWZpY2F0ZXMSKS5jcnlwdG9zLmZsZWV0LnYxLkxpc3RDZXJ0aWZpY2F0ZXNSZXF1ZXN0GiouY3J5cHRvcy5mbGVldC52MS5MaXN0Q2VydGlmaWNhdGVzUmVzcG9uc2USXQoMTGlzdFByb2ZpbGVzEiUuY3J5cHRvcy5mbGVldC52MS5MaXN0UHJvZmlsZXNSZXF1ZXN0GiYuY3J5cHRvcy5mbGVldC52MS5MaXN0UHJvZmlsZXNSZXNwb25zZRJgCg1DcmVhdGVQcm9maWxlEiYuY3J5cHRvcy5mbGVldC52MS5DcmVhdGVQcm9maWxlUmVxdWVzdBonLmNyeXB0b3MuZmxlZXQudjEuQ3JlYXRlUHJvZmlsZVJlc3BvbnNlEmAKDVVwZGF0ZVByb2ZpbGUSJi5jcnlwdG9zLmZsZWV0LnYxLlVwZGF0ZVByb2ZpbGVSZXF1ZXN0GicuY3J5cHRvcy5mbGVldC52MS5VcGRhdGVQcm9maWxlUmVzcG9uc2USYAoNRGVsZXRlUHJvZmlsZRImLmNyeXB0b3MuZmxlZXQudjEuRGVsZXRlUHJvZmlsZVJlcXVlc3QaJy5jcnlwdG9zLmZsZWV0LnYxLkRlbGV0ZVByb2ZpbGVSZXNwb25zZRJvChJBcHBseVByb2ZpbGVUb05vZGUSKy5jcnlwdG9zLmZsZWV0LnYxLkFwcGx5UHJvZmlsZVRvTm9kZVJlcXVlc3QaLC5jcnlwdG9zLmZsZWV0LnYxLkFwcGx5UHJvZmlsZVRvTm9kZVJlc3BvbnNlEngKFVNldFByb2ZpbGVSZXF1ZXN0YWJsZRIuLmNyeXB0b3MuZmxlZXQudjEuU2V0UHJvZmlsZVJlcXVlc3RhYmxlUmVxdWVzdBovLmNyeXB0b3MuZmxlZXQudjEuU2V0UHJvZmlsZVJlcXVlc3RhYmxlUmVzcG9uc2USfgoXTGlzdFJlcXVlc3RhYmxlUHJvZmlsZXMSMC5jcnlwdG9zLmZsZWV0LnYxLkxpc3RSZXF1ZXN0YWJsZVByb2ZpbGVzUmVxdWVzdBoxLmNyeXB0b3MuZmxlZXQudjEuTGlzdFJlcXVlc3RhYmxlUHJvZmlsZXNSZXNwb25zZRJdCgxMaXN0QWRhcHRlcnMSJS5jcnlwdG9zLmZsZWV0LnYxLkxpc3RBZGFwdGVyc1JlcXVlc3QaJi5jcnlwdG9zLmZsZWV0LnYxLkxpc3RBZGFwdGVyc1Jlc3BvbnNlEmwKEVNldEFkYXB0ZXJFbmFibGVkEiouY3J5cHRvcy5mbGVldC52MS5TZXRBZGFwdGVyRW5hYmxlZFJlcXVlc3QaKy5jcnlwdG9zLmZsZWV0LnYxLlNldEFkYXB0ZXJFbmFibGVkUmVzcG9uc2USZgoPU2V0Tm9kZVByb3RvY29sEiguY3J5cHRvcy5mbGVldC52MS5TZXROb2RlUHJvdG9jb2xSZXF1ZXN0GikuY3J5cHRvcy5mbGVldC52MS5TZXROb2RlUHJvdG9jb2xSZXNwb25zZRJUCglMaXN0QXVkaXQSIi5jcnlwdG9zLmZsZWV0LnYxLkxpc3RBdWRpdFJlcXVlc3QaIy5jcnlwdG9zLmZsZWV0LnYxLkxpc3RBdWRpdFJlc3BvbnNlEmYKD0xpc3RFbnJvbGxtZW50cxIoLmNyeXB0b3MuZmxlZXQudjEuTGlzdEVucm9sbG1lbnRzUmVxdWVzdBopLmNyeXB0b3MuZmxlZXQudjEuTGlzdEVucm9sbG1lbnRzUmVzcG9uc2USaQoQQ3JlYXRlRW5yb2xsbWVudBIpLmNyeXB0b3MuZmxlZXQudjEuQ3JlYXRlRW5yb2xsbWVudFJlcXVlc3QaKi5jcnlwdG9zLmZsZWV0LnYxLkNyZWF0ZUVucm9sbG1lbnRSZXNwb25zZRJsChFBcHByb3ZlRW5yb2xsbWVudBIqLmNyeXB0b3MuZmxlZXQudjEuQXBwcm92ZUVucm9sbG1lbnRSZXF1ZXN0GisuY3J5cHRvcy5mbGVldC52MS5BcHByb3ZlRW5yb2xsbWVudFJlc3BvbnNlEmkKEFJlamVjdEVucm9sbG1lbnQSKS5jcnlwdG9zLmZsZWV0LnYxLlJlamVjdEVucm9sbG1lbnRSZXF1ZXN0GiouY3J5cHRvcy5mbGVldC52MS5SZWplY3RFbnJvbGxtZW50UmVzcG9uc2USSwoGV2hvQW1JEh8uY3J5cHRvcy5mbGVldC52MS5XaG9BbUlSZXF1ZXN0GiAuY3J5cHRvcy5mbGVldC52MS5XaG9BbUlSZXNwb25zZRJsChFSZXZva2VDZXJ0aWZpY2F0ZRIqLmNyeXB0b3MuZmxlZXQudjEuUmV2b2tlQ2VydGlmaWNhdGVSZXF1ZXN0GisuY3J5cHRvcy5mbGVldC52MS5SZXZva2VDZXJ0aWZpY2F0ZVJlc3BvbnNlEmMKDkdldENlcnRpZmljYXRlEicuY3J5cHRvcy5mbGVldC52MS5HZXRDZXJ0aWZpY2F0ZVJlcXVlc3QaKC5jcnlwdG9zLmZsZWV0LnYxLkdldENlcnRpZmljYXRlUmVzcG9uc2UScgoTTGlzdE5vZGVBdWRpdEV2ZW50cxIsLmNyeXB0b3MuZmxlZXQudjEuTGlzdE5vZGVBdWRpdEV2ZW50c1JlcXVlc3QaLS5jcnlwdG9zLmZsZWV0LnYxLkxpc3ROb2RlQXVkaXRFdmVudHNSZXNwb25zZRJ1ChRWZXJpZnlOb2RlQXVkaXRDaGFpbhItLmNyeXB0b3MuZmxlZXQudjEuVmVyaWZ5Tm9kZUF1ZGl0Q2hhaW5SZXF1ZXN0Gi4uY3J5cHRvcy5mbGVldC52MS5WZXJpZnlOb2RlQXVkaXRDaGFpblJlc3BvbnNlEoEBChhWYWxpZGF0ZUNlcnRpZmljYXRlQ2hhaW4SMS5jcnlwdG9zLmZsZWV0LnYxLlZhbGlkYXRlQ2VydGlmaWNhdGVDaGFpblJlcXVlc3QaMi5jcnlwdG9zLmZsZWV0LnYxLlZhbGlkYXRlQ2VydGlmaWNhdGVDaGFpblJlc3BvbnNlEn4KF0xpc3ROb2RlVHNhQ2VydGlmaWNhdGVzEjAuY3J5cHRvcy5mbGVldC52MS5MaXN0Tm9kZVRzYUNlcnRpZmljYXRlc1JlcXVlc3QaMS5jcnlwdG9zLmZsZWV0LnYxLkxpc3ROb2RlVHNhQ2VydGlmaWNhdGVzUmVzcG9uc2USeAoVTWludE5vZGVTY2VwQ2hhbGxlbmdlEi4uY3J5cHRvcy5mbGVldC52MS5NaW50Tm9kZVNjZXBDaGFsbGVuZ2VSZXF1ZXN0Gi8uY3J5cHRvcy5mbGVldC52MS5NaW50Tm9kZVNjZXBDaGFsbGVuZ2VSZXNwb25zZRJ7ChZMaXN0Tm9kZVNjZXBDaGFsbGVuZ2VzEi8uY3J5cHRvcy5mbGVldC52MS5MaXN0Tm9kZVNjZXBDaGFsbGVuZ2VzUmVxdWVzdBowLmNyeXB0b3MuZmxlZXQudjEuTGlzdE5vZGVTY2VwQ2hhbGxlbmdlc1Jlc3BvbnNlEn4KF1Jldm9rZU5vZGVTY2VwQ2hhbGxlbmdlEjAuY3J5cHRvcy5mbGVldC52MS5SZXZva2VOb2RlU2NlcENoYWxsZW5nZVJlcXVlc3QaMS5jcnlwdG9zLmZsZWV0LnYxLlJldm9rZU5vZGVTY2VwQ2hhbGxlbmdlUmVzcG9uc2USVAoJSXNzdWVMZWFmEiIuY3J5cHRvcy5mbGVldC52MS5Jc3N1ZUxlYWZSZXF1ZXN0GiMuY3J5cHRvcy5mbGVldC52MS5Jc3N1ZUxlYWZSZXNwb25zZRJUCglSZWtleU5vZGUSIi5jcnlwdG9zLmZsZWV0LnYxLlJla2V5Tm9kZVJlcXVlc3QaIy5jcnlwdG9zLmZsZWV0LnYxLlJla2V5Tm9kZVJlc3BvbnNlEmAKDUdldE5vZGVDb25maWcSJi5jcnlwdG9zLmZsZWV0LnYxLkdldE5vZGVDb25maWdSZXF1ZXN0GicuY3J5cHRvcy5mbGVldC52MS5HZXROb2RlQ29uZmlnUmVzcG9uc2USZgoPQXBwbHlOb2RlQ29uZmlnEiguY3J5cHRvcy5mbGVldC52MS5BcHBseU5vZGVDb25maWdSZXF1ZXN0GikuY3J5cHRvcy5mbGVldC52MS5BcHBseU5vZGVDb25maWdSZXNwb25zZRJaCgtFeHBvcnRDQUtleRIkLmNyeXB0b3MuZmxlZXQudjEuRXhwb3J0Q0FLZXlSZXF1ZXN0GiUuY3J5cHRvcy5mbGVldC52MS5FeHBvcnRDQUtleVJlc3BvbnNlEloKC0ltcG9ydENBS2V5EiQuY3J5cHRvcy5mbGVldC52MS5JbXBvcnRDQUtleVJlcXVlc3QaJS5jcnlwdG9zLmZsZWV0LnYxLkltcG9ydENBS2V5UmVzcG9uc2USlgEKH0NyZWF0ZU9wZXJhdG9yQ3JlZGVudGlhbFJlcXVlc3QSOC5jcnlwdG9zLmZsZWV0LnYxLkNyZWF0ZU9wZXJhdG9yQ3JlZGVudGlhbFJlcXVlc3RSZXF1ZXN0GjkuY3J5cHRvcy5mbGVldC52MS5DcmVhdGVPcGVyYXRvckNyZWRlbnRpYWxSZXF1ZXN0UmVzcG9uc2USkwEKHkxpc3RPcGVyYXRvckNyZWRlbnRpYWxSZXF1ZXN0cxI3LmNyeXB0b3MuZmxlZXQudjEuTGlzdE9wZXJhdG9yQ3JlZGVudGlhbFJlcXVlc3RzUmVxdWVzdBo4LmNyeXB0b3MuZmxlZXQudjEuTGlzdE9wZXJhdG9yQ3JlZGVudGlhbFJlcXVlc3RzUmVzcG9uc2USlgEKH0NhbmNlbE9wZXJhdG9yQ3JlZGVudGlhbFJlcXVlc3QSOC5jcnlwdG9zLmZsZWV0LnYxLkNhbmNlbE9wZXJhdG9yQ3JlZGVudGlhbFJlcXVlc3RSZXF1ZXN0GjkuY3J5cHRvcy5mbGVldC52MS5DYW5jZWxPcGVyYXRvckNyZWRlbnRpYWxSZXF1ZXN0UmVzcG9uc2USgQEKGFJlY29yZE9wZXJhdG9yQ3JlZGVudGlhbBIxLmNyeXB0b3MuZmxlZXQudjEuUmVjb3JkT3BlcmF0b3JDcmVkZW50aWFsUmVxdWVzdBoyLmNyeXB0b3MuZmxlZXQudjEuUmVjb3JkT3BlcmF0b3JDcmVkZW50aWFsUmVzcG9uc2USgQEKGFJldm9rZU9wZXJhdG9yQ3JlZGVudGlhbBIxLmNyeXB0b3MuZmxlZXQudjEuUmV2b2tlT3BlcmF0b3JDcmVkZW50aWFsUmVxdWVzdBoyLmNyeXB0b3MuZmxlZXQudjEuUmV2b2tlT3BlcmF0b3JDcmVkZW50aWFsUmVzcG9uc2USfgoXTGlzdE9wZXJhdG9yQ3JlZGVudGlhbHMSMC5jcnlwdG9zLmZsZWV0LnYxLkxpc3RPcGVyYXRvckNyZWRlbnRpYWxzUmVxdWVzdBoxLmNyeXB0b3MuZmxlZXQudjEuTGlzdE9wZXJhdG9yQ3JlZGVudGlhbHNSZXNwb25zZRJmCg9MaXN0T3BlcmF0b3JDQXMSKC5jcnlwdG9zLmZsZWV0LnYxLkxpc3RPcGVyYXRvckNBc1JlcXVlc3QaKS5jcnlwdG9zLmZsZWV0LnYxLkxpc3RPcGVyYXRvckNBc1Jlc3BvbnNlEm8KElJlZ2lzdGVyT3BlcmF0b3JDQRIrLmNyeXB0b3MuZmxlZXQudjEuUmVnaXN0ZXJPcGVyYXRvckNBUmVxdWVzdBosLmNyeXB0b3MuZmxlZXQudjEuUmVnaXN0ZXJPcGVyYXRvckNBUmVzcG9uc2USaQoQUmV0aXJlT3BlcmF0b3JDQRIpLmNyeXB0b3MuZmxlZXQudjEuUmV0aXJlT3BlcmF0b3JDQVJlcXVlc3QaKi5jcnlwdG9zLmZsZWV0LnYxLlJldGlyZU9wZXJhdG9yQ0FSZXNwb25zZRJ7ChZTZXRPcGVyYXRvckNBQ1JMU291cmNlEi8uY3J5cHRvcy5mbGVldC52MS5TZXRPcGVyYXRvckNBQ1JMU291cmNlUmVxdWVzdBowLmNyeXB0b3MuZmxlZXQudjEuU2V0T3BlcmF0b3JDQUNSTFNvdXJjZVJlc3BvbnNlEmwKEVVwbG9hZE9wZXJhdG9yQ1JMEiouY3J5cHRvcy5mbGVldC52MS5VcGxvYWRPcGVyYXRvckNSTFJlcXVlc3QaKy5jcnlwdG9zLmZsZWV0LnYxLlVwbG9hZE9wZXJhdG9yQ1JMUmVzcG9uc2USbAoRU2V0T3BlcmF0b3JDQU9DU1ASKi5jcnlwdG9zLmZsZWV0LnYxLlNldE9wZXJhdG9yQ0FPQ1NQUmVxdWVzdBorLmNyeXB0b3MuZmxlZXQudjEuU2V0T3BlcmF0b3JDQU9DU1BSZXNwb25zZRJmCg9QcmV2aWV3QWRvcHRpb24SKC5jcnlwdG9zLmZsZWV0LnYxLlByZXZpZXdBZG9wdGlvblJlcXVlc3QaKS5jcnlwdG9zLmZsZWV0LnYxLlByZXZpZXdBZG9wdGlvblJlc3BvbnNlEmkKEExpc3RJbnN0YWxsRGlza3MSKS5jcnlwdG9zLmZsZWV0LnYxLkxpc3RJbnN0YWxsRGlza3NSZXF1ZXN0GiouY3J5cHRvcy5mbGVldC52MS5MaXN0SW5zdGFsbERpc2tzUmVzcG9uc2USVgoJQWRvcHROb2RlEiIuY3J5cHRvcy5mbGVldC52MS5BZG9wdE5vZGVSZXF1ZXN0GiMuY3J5cHRvcy5mbGVldC52MS5BZG9wdE5vZGVSZXNwb25zZTABEocBChpDb25maXJtQWRvcHRpb25GaW5nZXJwcmludBIzLmNyeXB0b3MuZmxlZXQudjEuQ29uZmlybUFkb3B0aW9uRmluZ2VycHJpbnRSZXF1ZXN0GjQuY3J5cHRvcy5mbGVldC52MS5Db25maXJtQWRvcHRpb25GaW5nZXJwcmludFJlc3BvbnNlEmkKEERlY29tbWlzc2lvbk5vZGUSKS5jcnlwdG9zLmZsZWV0LnYxLkRlY29tbWlzc2lvbk5vZGVSZXF1ZXN0GiouY3J5cHRvcy5mbGVldC52MS5EZWNvbW1pc3Npb25Ob2RlUmVzcG9uc2USVwoKUmVib290Tm9kZRIjLmNyeXB0b3MuZmxlZXQudjEuUmVib290Tm9kZVJlcXVlc3QaJC5jcnlwdG9zLmZsZWV0LnYxLlJlYm9vdE5vZGVSZXNwb25zZRJXCgpSZW5hbWVOb2RlEiMuY3J5cHRvcy5mbGVldC52MS5SZW5hbWVOb2RlUmVxdWVzdBokLmNyeXB0b3MuZmxlZXQudjEuUmVuYW1lTm9kZVJlc3BvbnNlElcKClJlbW92ZU5vZGUSIy5jcnlwdG9zLmZsZWV0LnYxLlJlbW92ZU5vZGVSZXF1ZXN0GiQuY3J5cHRvcy5mbGVldC52MS5SZW1vdmVOb2RlUmVzcG9uc2USWgoLTGlzdE1jcEtleXMSJC5jcnlwdG9zLmZsZWV0LnYxLkxpc3RNY3BLZXlzUmVxdWVzdBolLmNyeXB0b3MuZmxlZXQudjEuTGlzdE1jcEtleXNSZXNwb25zZRJdCgxSZXZva2VNY3BLZXkSJS5jcnlwdG9zLmZsZWV0LnYxLlJldm9rZU1jcEtleVJlcXVlc3QaJi5jcnlwdG9zLmZsZWV0LnYxLlJldm9rZU1jcEtleVJlc3BvbnNlEl0KDENyZWF0ZU1jcEtleRIlLmNyeXB0b3MuZmxlZXQudjEuQ3JlYXRlTWNwS2V5UmVxdWVzdBomLmNyeXB0b3MuZmxlZXQudjEuQ3JlYXRlTWNwS2V5UmVzcG9uc2USYAoNTGlzdEFwcHJvdmFscxImLmNyeXB0b3MuZmxlZXQudjEuTGlzdEFwcHJvdmFsc1JlcXVlc3QaJy5jcnlwdG9zLmZsZWV0LnYxLkxpc3RBcHByb3ZhbHNSZXNwb25zZRJjCg5EZWNpZGVBcHByb3ZhbBInLmNyeXB0b3MuZmxlZXQudjEuRGVjaWRlQXBwcm92YWxSZXF1ZXN0GiguY3J5cHRvcy5mbGVldC52MS5EZWNpZGVBcHByb3ZhbFJlc3BvbnNlEoEBChhDcmVhdGVDZXJ0aWZpY2F0ZVJlcXVlc3QSMS5jcnlwdG9zLmZsZWV0LnYxLkNyZWF0ZUNlcnRpZmljYXRlUmVxdWVzdFJlcXVlc3QaMi5jcnlwdG9zLmZsZWV0LnYxLkNyZWF0ZUNlcnRpZmljYXRlUmVxdWVzdFJlc3BvbnNlEn4KF0xpc3RDZXJ0aWZpY2F0ZVJlcXVlc3RzEjAuY3J5cHRvcy5mbGVldC52MS5MaXN0Q2VydGlmaWNhdGVSZXF1ZXN0c1JlcXVlc3QaMS5jcnlwdG9zLmZsZWV0LnYxLkxpc3RDZXJ0aWZpY2F0ZVJlcXVlc3RzUmVzcG9uc2UShAEKGUdldENlcnRpZmljYXRlUmVxdWVzdEJ5SUQSMi5jcnlwdG9zLmZsZWV0LnYxLkdldENlcnRpZmljYXRlUmVxdWVzdEJ5SURSZXF1ZXN0GjMuY3J5cHRvcy5mbGVldC52MS5HZXRDZXJ0aWZpY2F0ZVJlcXVlc3RCeUlEUmVzcG9uc2USgQEKGENhbmNlbENlcnRpZmljYXRlUmVxdWVzdBIxLmNyeXB0b3MuZmxlZXQudjEuQ2FuY2VsQ2VydGlmaWNhdGVSZXF1ZXN0UmVxdWVzdBoyLmNyeXB0b3MuZmxlZXQudjEuQ2FuY2VsQ2VydGlmaWNhdGVSZXF1ZXN0UmVzcG9uc2VCSFpGZ2l0aHViLmNvbS9DcnlwdE9TLVBLSS9jcnlwdG9zLW1hbmFnZXIvZ2VuL2dvL2NyeXB0b3MvZmxlZXQvdjE7ZmxlZXR2MWIGcHJvdG8z", [file_cryptos_fleet_v1_operator_ca, file_cryptos_node_v1_config, file_cryptos_node_v1_node, file_cryptos_node_v1_status]); + fileDesc("ChxjcnlwdG9zL2ZsZWV0L3YxL2ZsZWV0LnByb3RvEhBjcnlwdG9zLmZsZWV0LnYxIhIKEExpc3ROb2Rlc1JlcXVlc3QiQQoRTGlzdE5vZGVzUmVzcG9uc2USLAoFbm9kZXMYASADKAsyHS5jcnlwdG9zLmZsZWV0LnYxLk5vZGVTdW1tYXJ5Ii8KDkdldE5vZGVSZXF1ZXN0EgwKBG5hbWUYASABKAkSDwoHbm9kZV9pZBgCIAEoCSI9Cg9HZXROb2RlUmVzcG9uc2USKgoEbm9kZRgBIAEoCzIcLmNyeXB0b3MuZmxlZXQudjEuTm9kZURldGFpbCI4ChdMaXN0Q2VydGlmaWNhdGVzUmVxdWVzdBIMCgRub2RlGAEgASgJEg8KB25vZGVfaWQYAiABKAkiTwoYTGlzdENlcnRpZmljYXRlc1Jlc3BvbnNlEjMKDGNlcnRpZmljYXRlcxgBIAMoCzIdLmNyeXB0b3MuZmxlZXQudjEuQ2VydGlmaWNhdGUiFQoTTGlzdFByb2ZpbGVzUmVxdWVzdCJKChRMaXN0UHJvZmlsZXNSZXNwb25zZRIyCgVpdGVtcxgBIAMoCzIjLmNyeXB0b3Mubm9kZS52MS5DZXJ0aWZpY2F0ZVByb2ZpbGUiTAoUQ3JlYXRlUHJvZmlsZVJlcXVlc3QSNAoHcHJvZmlsZRgBIAEoCzIjLmNyeXB0b3Mubm9kZS52MS5DZXJ0aWZpY2F0ZVByb2ZpbGUiFwoVQ3JlYXRlUHJvZmlsZVJlc3BvbnNlIkwKFFVwZGF0ZVByb2ZpbGVSZXF1ZXN0EjQKB3Byb2ZpbGUYASABKAsyIy5jcnlwdG9zLm5vZGUudjEuQ2VydGlmaWNhdGVQcm9maWxlIhcKFVVwZGF0ZVByb2ZpbGVSZXNwb25zZSIkChREZWxldGVQcm9maWxlUmVxdWVzdBIMCgRuYW1lGAEgASgJIhcKFURlbGV0ZVByb2ZpbGVSZXNwb25zZSJVChlBcHBseVByb2ZpbGVUb05vZGVSZXF1ZXN0EhEKCW5vZGVfbmFtZRgBIAEoCRIUCgxwcm9maWxlX25hbWUYAiABKAkSDwoHbm9kZV9pZBgDIAEoCSJJChpBcHBseVByb2ZpbGVUb05vZGVSZXNwb25zZRISCgpnZW5lcmF0aW9uGAEgASgEEhcKD3JlcXVpcmVzX3JlYm9vdBgCIAEoCCJBChxTZXRQcm9maWxlUmVxdWVzdGFibGVSZXF1ZXN0EgwKBG5hbWUYASABKAkSEwoLcmVxdWVzdGFibGUYAiABKAgiHwodU2V0UHJvZmlsZVJlcXVlc3RhYmxlUmVzcG9uc2UiIAoeTGlzdFJlcXVlc3RhYmxlUHJvZmlsZXNSZXF1ZXN0IlUKH0xpc3RSZXF1ZXN0YWJsZVByb2ZpbGVzUmVzcG9uc2USMgoFaXRlbXMYASADKAsyIy5jcnlwdG9zLm5vZGUudjEuQ2VydGlmaWNhdGVQcm9maWxlIhUKE0xpc3RBZGFwdGVyc1JlcXVlc3QiSgoUTGlzdEFkYXB0ZXJzUmVzcG9uc2USMgoFaXRlbXMYASADKAsyIy5jcnlwdG9zLmZsZWV0LnYxLkVucm9sbG1lbnRBZGFwdGVyIjkKGFNldEFkYXB0ZXJFbmFibGVkUmVxdWVzdBIMCgRuYW1lGAEgASgJEg8KB2VuYWJsZWQYAiABKAgiUQoZU2V0QWRhcHRlckVuYWJsZWRSZXNwb25zZRI0CgdhZGFwdGVyGAEgASgLMiMuY3J5cHRvcy5mbGVldC52MS5FbnJvbGxtZW50QWRhcHRlciISChBMaXN0QXVkaXRSZXF1ZXN0IkAKEUxpc3RBdWRpdFJlc3BvbnNlEisKBWl0ZW1zGAEgAygLMhwuY3J5cHRvcy5mbGVldC52MS5BdWRpdEV2ZW50IhgKFkxpc3RFbnJvbGxtZW50c1JlcXVlc3QiTQoXTGlzdEVucm9sbG1lbnRzUmVzcG9uc2USMgoFaXRlbXMYASADKAsyIy5jcnlwdG9zLmZsZWV0LnYxLkVucm9sbG1lbnRSZXF1ZXN0IogCCgtOb2RlU3VtbWFyeRIMCgRuYW1lGAEgASgJEg8KB2FkZHJlc3MYAiABKAkSDAoEcm9sZRgDIAEoCRIWCg5pZGVudGl0eV9zdGF0ZRgEIAEoCRIKCgJjbhgFIAEoCRIOCgZpc3N1ZXIYBiABKAkSKAoGaGVhbHRoGAcgASgOMhguY3J5cHRvcy5mbGVldC52MS5IZWFsdGgSFQoNaGVhbHRoX2RldGFpbBgIIAEoCRIKCgJpZBgJIAEoCRIyCglwcm90b2NvbHMYCiADKAsyHy5jcnlwdG9zLm5vZGUudjEuUHJvdG9jb2xTdGF0dXMSFwoPcmVib290X3JlcXVpcmVkGAsgASgIIkkKDE5vZGVJZGVudGl0eRIRCgljaGFpbl9wZW0YASABKAkSEQoJY2hhaW5fZGVyGAIgAygMEhMKC2xlYWZfc2hhMjU2GAMgASgJIqkBCgpOb2RlRGV0YWlsEi4KB3N1bW1hcnkYASABKAsyHS5jcnlwdG9zLmZsZWV0LnYxLk5vZGVTdW1tYXJ5EjAKCGlkZW50aXR5GAIgASgLMh4uY3J5cHRvcy5mbGVldC52MS5Ob2RlSWRlbnRpdHkSFQoNdHBtX2F2YWlsYWJsZRgDIAEoCBISCgpib290X2NvdW50GAQgASgEEg4KBnVwdGltZRgFIAEoCSLYAQoLQ2VydGlmaWNhdGUSDgoGc2VyaWFsGAEgASgJEhIKCnN1YmplY3RfY24YAiABKAkSEwoLaXNzdWVyX25vZGUYAyABKAkSDAoEa2luZBgEIAEoCRIOCgZzdGF0dXMYBSABKAkSEgoKbm90X2JlZm9yZRgGIAEoCRIRCglub3RfYWZ0ZXIYByABKAkSDwoHcHJvZmlsZRgIIAEoCRISCgpyZXZva2VkX2F0GAkgASgJEg4KBnJlYXNvbhgKIAEoCRIWCg5pc3N1ZXJfbm9kZV9pZBgLIAEoCSKNAQoRRW5yb2xsbWVudEFkYXB0ZXISDAoEa2luZBgBIAEoCRIMCgRuYW1lGAIgASgJEhAKCGVuZHBvaW50GAMgASgJEg8KB3Byb2ZpbGUYBCABKAkSDwoHZW5hYmxlZBgFIAEoCBISCgpjaGFsbGVuZ2VzGAYgAygJEhQKDGdwb190ZW1wbGF0ZRgHIAEoCSK8AgoKQXVkaXRFdmVudBIKCgJpZBgBIAEoCRIKCgJhdBgCIAEoCRIMCgRraW5kGAMgASgJEg8KB3N1bW1hcnkYBCABKAkSEwoLdGFyZ2V0X2tpbmQYBSABKAkSEwoLdGFyZ2V0X3BhdGgYBiABKAkSEgoKYWN0b3Jfa2luZBgHIAEoCRIQCghhY3Rvcl9jbhgIIAEoCRIUCgxhY3Rvcl9zZXJpYWwYCSABKAkSDgoGa2V5X2lkGAogASgJEgsKA3ZpYRgLIAEoCRIMCgR0b29sGAwgASgJEhYKDnJlcXVlc3RfZGlnZXN0GA0gASgJEg8KB291dGNvbWUYDiABKAkSEwoLYXBwcm92YWxfaWQYDyABKAkSFwoPYXBwcm92ZXJfc2VyaWFsGBAgASgJEg8KB25vZGVfaWQYESABKAki7wIKEUVucm9sbG1lbnRSZXF1ZXN0EgoKAmlkGAEgASgJEhUKDXByb3Bvc2VkX25hbWUYAiABKAkSDAoEcm9sZRgDIAEoCRIRCglwYXJlbnRfY24YBCABKAkSDwoHYWRkcmVzcxgFIAEoCRIOCgZzdGF0dXMYBiABKAkSGwoTYXR0ZXN0YXRpb25fc3VtbWFyeRgHIAEoCRIbChNhdHRlc3RhdGlvbl9ub2RlX2lkGAggASgJEhQKDGNzcl9rZXlfdHlwZRgJIAEoCRIWCg5jc3Jfc3ViamVjdF9jbhgKIAEoCRIUCgxyZXF1ZXN0ZWRfYXQYCyABKAkSGAoQcmVqZWN0aW9uX3JlYXNvbhgMIAEoCRIaChJhZG1pdHRlZF9ub2RlX25hbWUYDSABKAkSDAoEa2luZBgOIAEoCRIZChFwaW5uZWRfa2V5X3NoYTI1NhgPIAEoCRIYChBhZG1pdHRlZF9ub2RlX2lkGBAgASgJIswBChdDcmVhdGVFbnJvbGxtZW50UmVxdWVzdBIMCgRraW5kGAEgASgJEhUKDW5vZGVfZW5kcG9pbnQYAiABKAkSFgoOYWRtaW5fY2VydF9wZW0YAyABKAkSFQoNYWRtaW5fa2V5X3BlbRgEIAEoCRIOCgZjYV9wZW0YBSABKAkSEgoKY2hpbGRfbm9kZRgGIAEoCRIRCglwYXJlbnRfY24YByABKAkSDwoHcHJvZmlsZRgIIAEoCRIVCg1jaGlsZF9ub2RlX2lkGAkgASgJIlMKGENyZWF0ZUVucm9sbG1lbnRSZXNwb25zZRI3CgplbnJvbGxtZW50GAEgASgLMiMuY3J5cHRvcy5mbGVldC52MS5FbnJvbGxtZW50UmVxdWVzdCJ8ChhBcHByb3ZlRW5yb2xsbWVudFJlcXVlc3QSCgoCaWQYASABKAkSFQoNbm9kZV9lbmRwb2ludBgCIAEoCRIWCg5hZG1pbl9jZXJ0X3BlbRgDIAEoCRIVCg1hZG1pbl9rZXlfcGVtGAQgASgJEg4KBmNhX3BlbRgFIAEoCSJUChlBcHByb3ZlRW5yb2xsbWVudFJlc3BvbnNlEjcKCmVucm9sbG1lbnQYASABKAsyIy5jcnlwdG9zLmZsZWV0LnYxLkVucm9sbG1lbnRSZXF1ZXN0IjUKF1JlamVjdEVucm9sbG1lbnRSZXF1ZXN0EgoKAmlkGAEgASgJEg4KBnJlYXNvbhgCIAEoCSJTChhSZWplY3RFbnJvbGxtZW50UmVzcG9uc2USNwoKZW5yb2xsbWVudBgBIAEoCzIjLmNyeXB0b3MuZmxlZXQudjEuRW5yb2xsbWVudFJlcXVlc3QiDwoNV2hvQW1JUmVxdWVzdCI9ChBPcGVyYXRvcklkZW50aXR5EgoKAmNuGAEgASgJEg4KBnNlcmlhbBgCIAEoCRINCgVsZXZlbBgDIAEoCSJGCg5XaG9BbUlSZXNwb25zZRI0CghvcGVyYXRvchgBIAEoCzIiLmNyeXB0b3MuZmxlZXQudjEuT3BlcmF0b3JJZGVudGl0eSJnChhSZXZva2VDZXJ0aWZpY2F0ZVJlcXVlc3QSEQoJbm9kZV9uYW1lGAEgASgJEhIKCnNlcmlhbF9oZXgYAiABKAkSEwoLcmVhc29uX2NvZGUYAyABKAUSDwoHbm9kZV9pZBgEIAEoCSJYChlSZXZva2VDZXJ0aWZpY2F0ZVJlc3BvbnNlEhIKCnNlcmlhbF9oZXgYASABKAkSEgoKcmV2b2tlZF9hdBgCIAEoCRITCgtyZWFzb25fY29kZRgDIAEoBSI+ChVHZXRDZXJ0aWZpY2F0ZVJlcXVlc3QSEQoJbm9kZV9uYW1lGAEgASgJEhIKCnNlcmlhbF9oZXgYAiABKAkiaAoWR2V0Q2VydGlmaWNhdGVSZXNwb25zZRIXCg9jZXJ0aWZpY2F0ZV9wZW0YASABKAkSEQoJY2hhaW5fcGVtGAIgASgJEg4KBnN0YXR1cxgDIAEoCRISCgpyZXZva2VkX2F0GAQgASgJIl0KEElzc3VlTGVhZlJlcXVlc3QSEQoJbm9kZV9uYW1lGAEgASgJEg8KB2Nzcl9kZXIYAiABKAwSFAoMcHJvZmlsZV9uYW1lGAMgASgJEg8KB25vZGVfaWQYBCABKAkiJQoRSXNzdWVMZWFmUmVzcG9uc2USEAoIY2VydF9kZXIYASABKAwiTAoQUmVrZXlOb2RlUmVxdWVzdBIRCglub2RlX25hbWUYASABKAkSFAoMcHJvZmlsZV9uYW1lGAIgASgJEg8KB25vZGVfaWQYAyABKAkiTQoRUmVrZXlOb2RlUmVzcG9uc2USEgoKc3ViamVjdF9jbhgBIAEoCRIRCglpc3N1ZXJfY24YAiABKAkSEQoJY2hhaW5fbGVuGAMgASgFIjoKFEdldE5vZGVDb25maWdSZXF1ZXN0EhEKCW5vZGVfbmFtZRgBIAEoCRIPCgdub2RlX2lkGAIgASgJIkcKFUdldE5vZGVDb25maWdSZXNwb25zZRIuCgZjb25maWcYASABKAsyHi5jcnlwdG9zLm5vZGUudjEuTWFjaGluZUNvbmZpZyJsChZBcHBseU5vZGVDb25maWdSZXF1ZXN0EhEKCW5vZGVfbmFtZRgBIAEoCRIuCgZjb25maWcYAiABKAsyHi5jcnlwdG9zLm5vZGUudjEuTWFjaGluZUNvbmZpZxIPCgdub2RlX2lkGAMgASgJIkYKF0FwcGx5Tm9kZUNvbmZpZ1Jlc3BvbnNlEhIKCmdlbmVyYXRpb24YASABKAQSFwoPcmVxdWlyZXNfcmVib290GAIgASgIInAKFlNldE5vZGVQcm90b2NvbFJlcXVlc3QSEQoJbm9kZV9uYW1lGAEgASgJEjIKCHByb3RvY29sGAIgASgOMiAuY3J5cHRvcy5ub2RlLnYxLlNlcnZpY2VQcm90b2NvbBIPCgdlbmFibGVkGAMgASgIIkYKF1NldE5vZGVQcm90b2NvbFJlc3BvbnNlEhIKCmdlbmVyYXRpb24YASABKAQSFwoPcmVxdWlyZXNfcmVib290GAIgASgIIkwKEkV4cG9ydENBS2V5UmVxdWVzdBIRCglub2RlX25hbWUYASABKAkSEgoKcGFzc3BocmFzZRgCIAEoDBIPCgdub2RlX2lkGAMgASgJIicKE0V4cG9ydENBS2V5UmVzcG9uc2USEAoIZW52ZWxvcGUYASABKAwiXgoSSW1wb3J0Q0FLZXlSZXF1ZXN0EhEKCW5vZGVfbmFtZRgBIAEoCRIQCghlbnZlbG9wZRgCIAEoDBISCgpwYXNzcGhyYXNlGAMgASgMEg8KB25vZGVfaWQYBCABKAkiPAoTSW1wb3J0Q0FLZXlSZXNwb25zZRISCgpzdWJqZWN0X2NuGAEgASgJEhEKCWlzc3Vlcl9jbhgCIAEoCSJvCh9SZXZva2VPcGVyYXRvckNyZWRlbnRpYWxSZXF1ZXN0EhIKCnNlcmlhbF9oZXgYASABKAkSEwoLcmVhc29uX2NvZGUYAiABKAUSFQoNaXNzdWVyX3NoYTI1NhgDIAEoCRIMCgRub3RlGAQgASgJInMKIFJldm9rZU9wZXJhdG9yQ3JlZGVudGlhbFJlc3BvbnNlEhIKCnNlcmlhbF9oZXgYASABKAkSEgoKcmV2b2tlZF9hdBgCIAEoCRIVCg1pc3N1ZXJfc2hhMjU2GAMgASgJEhAKCHdhcm5pbmdzGAQgAygJIiAKHkxpc3RPcGVyYXRvckNyZWRlbnRpYWxzUmVxdWVzdCKNAgoST3BlcmF0b3JDcmVkZW50aWFsEhMKC2NvbW1vbl9uYW1lGAEgASgJEhIKCnNlcmlhbF9oZXgYAiABKAkSDQoFbGV2ZWwYAyABKAkSEQoJbm90X2FmdGVyGAQgASgJEg8KB3Jldm9rZWQYBSABKAgSDAoEa2luZBgGIAEoCRIVCg1pc3N1ZXJfc2hhMjU2GAcgASgJEg0KBWVtYWlsGAggASgJEhEKCWZ1bGxfbmFtZRgJIAEoCRISCgpkZW55bGlzdGVkGAogASgIEhMKC2NybF9yZXZva2VkGAsgASgIEhUKDWZpcnN0X3NlZW5fYXQYDCABKAkSFAoMbGFzdF9zZWVuX2F0GA0gASgJIlYKH0xpc3RPcGVyYXRvckNyZWRlbnRpYWxzUmVzcG9uc2USMwoFaXRlbXMYASADKAsyJC5jcnlwdG9zLmZsZWV0LnYxLk9wZXJhdG9yQ3JlZGVudGlhbCJqCiZDcmVhdGVPcGVyYXRvckNyZWRlbnRpYWxSZXF1ZXN0UmVxdWVzdBINCgVsZXZlbBgBIAEoCRINCgVlbWFpbBgCIAEoCRIRCglmdWxsX25hbWUYAyABKAkSDwoHY3NyX2RlchgEIAEoDCKUAQonQ3JlYXRlT3BlcmF0b3JDcmVkZW50aWFsUmVxdWVzdFJlc3BvbnNlEhIKCnJlcXVlc3RfaWQYASABKAkSDwoHY3NyX3BlbRgCIAEoCRIXCg9leHRmaWxlX3NlY3Rpb24YAyABKAkSFwoPb3BlbnNzbF9jb21tYW5kGAQgASgJEhIKCmV4cGlyZXNfYXQYBSABKAkiNgolTGlzdE9wZXJhdG9yQ3JlZGVudGlhbFJlcXVlc3RzUmVxdWVzdBINCgVzdGF0ZRgBIAEoCSJkCiZMaXN0T3BlcmF0b3JDcmVkZW50aWFsUmVxdWVzdHNSZXNwb25zZRI6CgVpdGVtcxgBIAMoCzIrLmNyeXB0b3MuZmxlZXQudjEuT3BlcmF0b3JDcmVkZW50aWFsUmVxdWVzdCI8CiZDYW5jZWxPcGVyYXRvckNyZWRlbnRpYWxSZXF1ZXN0UmVxdWVzdBISCgpyZXF1ZXN0X2lkGAEgASgJImcKJ0NhbmNlbE9wZXJhdG9yQ3JlZGVudGlhbFJlcXVlc3RSZXNwb25zZRI8CgdyZXF1ZXN0GAEgASgLMisuY3J5cHRvcy5mbGVldC52MS5PcGVyYXRvckNyZWRlbnRpYWxSZXF1ZXN0ItEBChlPcGVyYXRvckNyZWRlbnRpYWxSZXF1ZXN0EgoKAmlkGAEgASgJEg0KBWxldmVsGAIgASgJEg0KBWVtYWlsGAMgASgJEhEKCWZ1bGxfbmFtZRgEIAEoCRIPCgdjc3JfcGVtGAUgASgJEg0KBXN0YXRlGAYgASgJEhUKDWNyZWF0ZWRfYnlfY24YByABKAkSEgoKY3JlYXRlZF9hdBgIIAEoCRISCgpleHBpcmVzX2F0GAkgASgJEhgKEGNvbXBsZXRlZF9zZXJpYWwYCiABKAkiWgofUmVjb3JkT3BlcmF0b3JDcmVkZW50aWFsUmVxdWVzdBIQCghjZXJ0X2RlchgBIAEoDBISCgpyZXF1ZXN0X2lkGAIgASgJEhEKCWZ1bGxfbmFtZRgDIAEoCSJuCiBSZWNvcmRPcGVyYXRvckNyZWRlbnRpYWxSZXNwb25zZRI4CgpjcmVkZW50aWFsGAEgASgLMiQuY3J5cHRvcy5mbGVldC52MS5PcGVyYXRvckNyZWRlbnRpYWwSEAoId2FybmluZ3MYAiADKAkiGAoWTGlzdE9wZXJhdG9yQ0FzUmVxdWVzdCJGChdMaXN0T3BlcmF0b3JDQXNSZXNwb25zZRIrCgVpdGVtcxgBIAMoCzIcLmNyeXB0b3MuZmxlZXQudjEuT3BlcmF0b3JDQSKQAgoZUmVnaXN0ZXJPcGVyYXRvckNBUmVxdWVzdBITCgtjYV9jZXJ0X2RlchgBIAEoDBINCgN1cmwYAiABKAlIABIRCgdjcmxfZGVyGAMgASgMSAASDgoEbm9uZRgEIAEoCEgAEi0KCW9jc3BfbW9kZRgFIAEoDjIaLmNyeXB0b3MuZmxlZXQudjEuT2NzcE1vZGUSEAoIb2NzcF91cmwYBiABKAkSRQoQYWNrbm93bGVkZ2VtZW50cxgHIAMoDjIrLmNyeXB0b3MuZmxlZXQudjEuT3BlcmF0b3JDQUFja25vd2xlZGdlbWVudBIWCg5jb25maXJtX3NoYTI1NhgIIAEoCUIMCgpjcmxfc291cmNlIrABChpSZWdpc3Rlck9wZXJhdG9yQ0FSZXNwb25zZRIxCgtvcGVyYXRvcl9jYRgBIAEoCzIcLmNyeXB0b3MuZmxlZXQudjEuT3BlcmF0b3JDQRIRCgljb25maXJtZWQYAiABKAgSFQoNYWRtaW5fZXh0ZmlsZRgDIAEoCRI1CgpvY3NwX3Byb2JlGAQgASgLMiEuY3J5cHRvcy5mbGVldC52MS5PY3NwUHJvYmVSZXN1bHQiTAoXUmV0aXJlT3BlcmF0b3JDQVJlcXVlc3QSDgoGc2hhMjU2GAEgASgJEiEKGWlfdW5kZXJzdGFuZF9zZWxmX2xvY2tvdXQYAiABKAgiTQoYUmV0aXJlT3BlcmF0b3JDQVJlc3BvbnNlEjEKC29wZXJhdG9yX2NhGAEgASgLMhwuY3J5cHRvcy5mbGVldC52MS5PcGVyYXRvckNBIrYBCh1TZXRPcGVyYXRvckNBQ1JMU291cmNlUmVxdWVzdBIOCgZzaGEyNTYYASABKAkSDQoDdXJsGAIgASgJSAASDgoEbm9uZRgDIAEoCEgAEhEKB2NybF9kZXIYBSABKAxIABJFChBhY2tub3dsZWRnZW1lbnRzGAQgAygOMisuY3J5cHRvcy5mbGVldC52MS5PcGVyYXRvckNBQWNrbm93bGVkZ2VtZW50QgwKCmNybF9zb3VyY2UiUwoeU2V0T3BlcmF0b3JDQUNSTFNvdXJjZVJlc3BvbnNlEjEKC29wZXJhdG9yX2NhGAEgASgLMhwuY3J5cHRvcy5mbGVldC52MS5PcGVyYXRvckNBIjsKGFVwbG9hZE9wZXJhdG9yQ1JMUmVxdWVzdBIOCgZzaGEyNTYYASABKAkSDwoHY3JsX2RlchgCIAEoDCJOChlVcGxvYWRPcGVyYXRvckNSTFJlc3BvbnNlEjEKC29wZXJhdG9yX2NhGAEgASgLMhwuY3J5cHRvcy5mbGVldC52MS5PcGVyYXRvckNBImsKGFNldE9wZXJhdG9yQ0FPQ1NQUmVxdWVzdBIOCgZzaGEyNTYYASABKAkSLQoJb2NzcF9tb2RlGAIgASgOMhouY3J5cHRvcy5mbGVldC52MS5PY3NwTW9kZRIQCghvY3NwX3VybBgDIAEoCSKFAQoZU2V0T3BlcmF0b3JDQU9DU1BSZXNwb25zZRIxCgtvcGVyYXRvcl9jYRgBIAEoCzIcLmNyeXB0b3MuZmxlZXQudjEuT3BlcmF0b3JDQRI1CgpvY3NwX3Byb2JlGAIgASgLMiEuY3J5cHRvcy5mbGVldC52MS5PY3NwUHJvYmVSZXN1bHQiKgoWUHJldmlld0Fkb3B0aW9uUmVxdWVzdBIQCghlbmRwb2ludBgBIAEoCSI/ChdQcmV2aWV3QWRvcHRpb25SZXNwb25zZRITCgtjZXJ0X3NoYTI1NhgBIAEoCRIPCgdzdWJqZWN0GAIgASgJIkcKF0xpc3RJbnN0YWxsRGlza3NSZXF1ZXN0EhAKCGVuZHBvaW50GAEgASgJEhoKEnBpbm5lZF9jZXJ0X3NoYTI1NhgCIAEoCSJHChhMaXN0SW5zdGFsbERpc2tzUmVzcG9uc2USKwoFZGlza3MYASADKAsyHC5jcnlwdG9zLm5vZGUudjEuSW5zdGFsbERpc2sicAoQQWRvcHROb2RlUmVxdWVzdBIQCghlbmRwb2ludBgBIAEoCRIaChJwaW5uZWRfY2VydF9zaGEyNTYYAiABKAkSLgoGY29uZmlnGAMgASgLMh4uY3J5cHRvcy5ub2RlLnYxLk1hY2hpbmVDb25maWcihQEKEUFkb3B0Tm9kZVJlc3BvbnNlEg0KBXBoYXNlGAEgASgJEg4KBmRldGFpbBgCIAEoCRIMCgRkb25lGAMgASgIEg8KB25vZGVfaWQYBCABKAkSEwoLYWRvcHRpb25faWQYBSABKAkSHQoVcHJlc2VudGVkX2NlcnRfc2hhMjU2GAYgASgJIk0KIUNvbmZpcm1BZG9wdGlvbkZpbmdlcnByaW50UmVxdWVzdBITCgthZG9wdGlvbl9pZBgBIAEoCRITCgtjZXJ0X3NoYTI1NhgCIAEoCSIkCiJDb25maXJtQWRvcHRpb25GaW5nZXJwcmludFJlc3BvbnNlIloKF0RlY29tbWlzc2lvbk5vZGVSZXF1ZXN0EhEKCW5vZGVfbmFtZRgBIAEoCRIbChNjb25maXJtX2NvbW1vbl9uYW1lGAIgASgJEg8KB25vZGVfaWQYAyABKAkiLQoYRGVjb21taXNzaW9uTm9kZVJlc3BvbnNlEhEKCXJlYm9vdGluZxgBIAEoCCJhChFSZWJvb3ROb2RlUmVxdWVzdBIRCglub2RlX25hbWUYASABKAkSFQoNY29uZmlybV9jYV9jbhgCIAEoCRIRCglwb3dlcl9vZmYYAyABKAgSDwoHbm9kZV9pZBgEIAEoCSInChJSZWJvb3ROb2RlUmVzcG9uc2USEQoJcmVib290aW5nGAEgASgIIjYKEVJlbmFtZU5vZGVSZXF1ZXN0Eg8KB25vZGVfaWQYASABKAkSEAoIbmV3X25hbWUYAiABKAkiQQoSUmVuYW1lTm9kZVJlc3BvbnNlEisKBG5vZGUYASABKAsyHS5jcnlwdG9zLmZsZWV0LnYxLk5vZGVTdW1tYXJ5IjoKEVJlbW92ZU5vZGVSZXF1ZXN0Eg8KB25vZGVfaWQYASABKAkSFAoMY29uZmlybV9uYW1lGAIgASgJIkEKElJlbW92ZU5vZGVSZXNwb25zZRIrCgRub2RlGAEgASgLMh0uY3J5cHRvcy5mbGVldC52MS5Ob2RlU3VtbWFyeSIhChJMaXN0TWNwS2V5c1JlcXVlc3QSCwoDYWxsGAEgASgIIj4KE0xpc3RNY3BLZXlzUmVzcG9uc2USJwoFaXRlbXMYASADKAsyGC5jcnlwdG9zLmZsZWV0LnYxLk1jcEtleSIhChNSZXZva2VNY3BLZXlSZXF1ZXN0EgoKAmlkGAEgASgJIkEKFFJldm9rZU1jcEtleVJlc3BvbnNlEikKB21jcF9rZXkYASABKAsyGC5jcnlwdG9zLmZsZWV0LnYxLk1jcEtleSI7ChNDcmVhdGVNY3BLZXlSZXF1ZXN0Eg0KBWxhYmVsGAEgASgJEhUKDWxldmVsX2NlaWxpbmcYAiABKAkiWAoUQ3JlYXRlTWNwS2V5UmVzcG9uc2USFQoNcGxhaW50ZXh0X2tleRgBIAEoCRIpCgdtY3Bfa2V5GAIgASgLMhguY3J5cHRvcy5mbGVldC52MS5NY3BLZXkiuwEKBk1jcEtleRIKCgJpZBgBIAEoCRINCgVsYWJlbBgCIAEoCRITCgtjbGllbnRfbmFtZRgDIAEoCRITCgtvcGVyYXRvcl9jbhgEIAEoCRIXCg9vcGVyYXRvcl9zZXJpYWwYBSABKAkSFQoNbGV2ZWxfY2VpbGluZxgGIAEoCRISCgpjcmVhdGVkX2F0GAcgASgJEhQKDGxhc3RfdXNlZF9hdBgIIAEoCRISCgpyZXZva2VkX2F0GAkgASgJIiYKFExpc3RBcHByb3ZhbHNSZXF1ZXN0Eg4KBnN0YXR1cxgBIAEoCSJCChVMaXN0QXBwcm92YWxzUmVzcG9uc2USKQoFaXRlbXMYASADKAsyGi5jcnlwdG9zLmZsZWV0LnYxLkFwcHJvdmFsIjQKFURlY2lkZUFwcHJvdmFsUmVxdWVzdBIKCgJpZBgBIAEoCRIPCgdhcHByb3ZlGAIgASgIIkYKFkRlY2lkZUFwcHJvdmFsUmVzcG9uc2USLAoIYXBwcm92YWwYASABKAsyGi5jcnlwdG9zLmZsZWV0LnYxLkFwcHJvdmFsIrcCCghBcHByb3ZhbBIKCgJpZBgBIAEoCRIMCgR0b29sGAIgASgJEg8KB3N1bW1hcnkYAyABKAkSFgoOcmVxdWVzdF9kaWdlc3QYBCABKAkSFwoPcmVxdWVzdGVkX2J5X2NuGAUgASgJEhsKE3JlcXVlc3RlZF9ieV9zZXJpYWwYBiABKAkSDgoGa2V5X2lkGAcgASgJEhYKDnJlcXVpcmVkX2xldmVsGAggASgJEhIKCmNyZWF0ZWRfYXQYCSABKAkSEgoKZXhwaXJlc19hdBgKIAEoCRIOCgZzdGF0dXMYCyABKAkSFQoNZGVjaWRlZF9ieV9jbhgMIAEoCRIZChFkZWNpZGVkX2J5X3NlcmlhbBgNIAEoCRISCgpkZWNpZGVkX2F0GA4gASgJEgwKBGtpbmQYDyABKAkirwIKEkNlcnRpZmljYXRlUmVxdWVzdBIKCgJpZBgBIAEoCRIUCgxwcm9maWxlX25hbWUYAiABKAkSDwoHY3NyX3BlbRgDIAEoCRIMCgRub3RlGAQgASgJEhcKD3JlcXVlc3RlZF9ieV9jbhgFIAEoCRIbChNyZXF1ZXN0ZWRfYnlfc2VyaWFsGAYgASgJEg0KBXN0YXRlGAcgASgJEhMKC2FwcHJvdmFsX2lkGAggASgJEhcKD2NlcnRpZmljYXRlX3BlbRgJIAEoCRIWCg5mYWlsdXJlX3JlYXNvbhgKIAEoCRISCgpjcmVhdGVkX2F0GAsgASgJEhIKCmV4cGlyZXNfYXQYDCABKAkSEgoKZGVjaWRlZF9hdBgNIAEoCRIRCglpc3N1ZWRfYXQYDiABKAkiVgofQ3JlYXRlQ2VydGlmaWNhdGVSZXF1ZXN0UmVxdWVzdBIUCgxwcm9maWxlX25hbWUYASABKAkSDwoHY3NyX2RlchgCIAEoDBIMCgRub3RlGAMgASgJIlkKIENyZWF0ZUNlcnRpZmljYXRlUmVxdWVzdFJlc3BvbnNlEjUKB3JlcXVlc3QYASABKAsyJC5jcnlwdG9zLmZsZWV0LnYxLkNlcnRpZmljYXRlUmVxdWVzdCJCCh5MaXN0Q2VydGlmaWNhdGVSZXF1ZXN0c1JlcXVlc3QSDQoFc3RhdGUYASABKAkSEQoJbWluZV9vbmx5GAIgASgIIlYKH0xpc3RDZXJ0aWZpY2F0ZVJlcXVlc3RzUmVzcG9uc2USMwoFaXRlbXMYASADKAsyJC5jcnlwdG9zLmZsZWV0LnYxLkNlcnRpZmljYXRlUmVxdWVzdCIuCiBHZXRDZXJ0aWZpY2F0ZVJlcXVlc3RCeUlEUmVxdWVzdBIKCgJpZBgBIAEoCSJaCiFHZXRDZXJ0aWZpY2F0ZVJlcXVlc3RCeUlEUmVzcG9uc2USNQoHcmVxdWVzdBgBIAEoCzIkLmNyeXB0b3MuZmxlZXQudjEuQ2VydGlmaWNhdGVSZXF1ZXN0Ii0KH0NhbmNlbENlcnRpZmljYXRlUmVxdWVzdFJlcXVlc3QSCgoCaWQYASABKAkiWQogQ2FuY2VsQ2VydGlmaWNhdGVSZXF1ZXN0UmVzcG9uc2USNQoHcmVxdWVzdBgBIAEoCzIkLmNyeXB0b3MuZmxlZXQudjEuQ2VydGlmaWNhdGVSZXF1ZXN0IkQKHkxpc3ROb2RlVHNhQ2VydGlmaWNhdGVzUmVxdWVzdBIRCglub2RlX25hbWUYASABKAkSDwoHbm9kZV9pZBgCIAEoCSKGAQoSTm9kZVRzYUNlcnRpZmljYXRlEhAKCGNlcnRfcGVtGAEgASgJEhIKCnNlcmlhbF9oZXgYAiABKAkSEgoKc2hhMjU2X2hleBgDIAEoCRISCgpub3RfYmVmb3JlGAQgASgJEhEKCW5vdF9hZnRlchgFIAEoCRIPCgdjdXJyZW50GAYgASgIIl0KH0xpc3ROb2RlVHNhQ2VydGlmaWNhdGVzUmVzcG9uc2USOgoMY2VydGlmaWNhdGVzGAEgAygLMiQuY3J5cHRvcy5mbGVldC52MS5Ob2RlVHNhQ2VydGlmaWNhdGUiXgofVmFsaWRhdGVDZXJ0aWZpY2F0ZUNoYWluUmVxdWVzdBIRCglub2RlX25hbWUYASABKAkSDwoHbm9kZV9pZBgCIAEoCRIXCg9jZXJ0aWZpY2F0ZV9wZW0YAyABKAkiewogVmFsaWRhdGVDZXJ0aWZpY2F0ZUNoYWluUmVzcG9uc2USDQoFdmFsaWQYASABKAgSDgoGcmVhc29uGAIgASgJEg8KB3N1YmplY3QYAyABKAkSDgoGaXNzdWVyGAQgASgJEhcKD25vZGVfY2Ffc3ViamVjdBgFIAEoCSKuAQoaTGlzdE5vZGVBdWRpdEV2ZW50c1JlcXVlc3QSEQoJbm9kZV9uYW1lGAEgASgJEg8KB25vZGVfaWQYAiABKAkSEQoJcGFnZV9zaXplGAMgASgFEhIKCnBhZ2VfdG9rZW4YBCABKAkSEQoJZnJvbV90aW1lGAUgASgJEg8KB3RvX3RpbWUYBiABKAkSEgoKZXZlbnRfdHlwZRgHIAEoCRINCgVhY3RvchgIIAEoCSKQAgoOTm9kZUF1ZGl0RXZlbnQSCwoDc2VxGAEgASgEEgoKAnRzGAIgASgJEhUKDWFjdG9yX3N1YmplY3QYAyABKAkSEgoKcnBjX21ldGhvZBgEIAEoCRIPCgdvdXRjb21lGAUgASgJEj4KB2RldGFpbHMYBiADKAsyLS5jcnlwdG9zLmZsZWV0LnYxLk5vZGVBdWRpdEV2ZW50LkRldGFpbHNFbnRyeRIYChBlbnRyeV9zaGEyNTZfaGV4GAcgASgJEg4KBnRhcmdldBgIIAEoCRIPCgdzdW1tYXJ5GAkgASgJGi4KDERldGFpbHNFbnRyeRILCgNrZXkYASABKAkSDQoFdmFsdWUYAiABKAk6AjgBImkKG0xpc3ROb2RlQXVkaXRFdmVudHNSZXNwb25zZRIxCgdlbnRyaWVzGAEgAygLMiAuY3J5cHRvcy5mbGVldC52MS5Ob2RlQXVkaXRFdmVudBIXCg9uZXh0X3BhZ2VfdG9rZW4YAiABKAkiQQobVmVyaWZ5Tm9kZUF1ZGl0Q2hhaW5SZXF1ZXN0EhEKCW5vZGVfbmFtZRgBIAEoCRIPCgdub2RlX2lkGAIgASgJInIKHFZlcmlmeU5vZGVBdWRpdENoYWluUmVzcG9uc2USEwoLZW50cnlfY291bnQYASABKAQSDgoGaW50YWN0GAIgASgIEh0KFWZpcnN0X2Jyb2tlbl9zZXF1ZW5jZRgDIAEoBBIOCgZyZWFzb24YBCABKAkiPwoZR2V0Tm9kZUltYWdlU3RhdHVzUmVxdWVzdBIRCglub2RlX25hbWUYASABKAkSDwoHbm9kZV9pZBgCIAEoCSKKAQoPTm9kZUltYWdlU3RhdHVzEhYKDnJ1bm5pbmdfc2hhMjU2GAEgASgJEhUKDWFjdGl2ZV9zaGEyNTYYAiABKAkSFwoPcHJldmlvdXNfc2hhMjU2GAMgASgJEhYKDnJlYm9vdF9wZW5kaW5nGAQgASgIEhcKD3J1bm5pbmdfdmVyc2lvbhgFIAEoCSJPChpHZXROb2RlSW1hZ2VTdGF0dXNSZXNwb25zZRIxCgZzdGF0dXMYASABKAsyIS5jcnlwdG9zLmZsZWV0LnYxLk5vZGVJbWFnZVN0YXR1cyJxChVTdGFnZU5vZGVJbWFnZVJlcXVlc3QSEQoJbm9kZV9uYW1lGAEgASgJEg8KB25vZGVfaWQYAiABKAkSEQoJaW1hZ2VfdXJsGAMgASgJEhEKCXNpZ25hdHVyZRgEIAEoDBIOCgZzaGEyNTYYBSABKAkiZAoWU3RhZ2VOb2RlSW1hZ2VSZXNwb25zZRIxCgZzdGF0dXMYASABKAsyIS5jcnlwdG9zLmZsZWV0LnYxLk5vZGVJbWFnZVN0YXR1cxIXCg9yZXF1aXJlc19yZWJvb3QYAiABKAgiVQoYQWN0aXZhdGVOb2RlSW1hZ2VSZXF1ZXN0EhEKCW5vZGVfbmFtZRgBIAEoCRIPCgdub2RlX2lkGAIgASgJEhUKDWNvbmZpcm1fY2FfY24YAyABKAkiLgoZQWN0aXZhdGVOb2RlSW1hZ2VSZXNwb25zZRIRCglyZWJvb3RpbmcYASABKAgiPgoYUm9sbGJhY2tOb2RlSW1hZ2VSZXF1ZXN0EhEKCW5vZGVfbmFtZRgBIAEoCRIPCgdub2RlX2lkGAIgASgJImcKGVJvbGxiYWNrTm9kZUltYWdlUmVzcG9uc2USMQoGc3RhdHVzGAEgASgLMiEuY3J5cHRvcy5mbGVldC52MS5Ob2RlSW1hZ2VTdGF0dXMSFwoPcmVxdWlyZXNfcmVib290GAIgASgIIoQBChFOb2RlU2NlcENoYWxsZW5nZRIKCgJpZBgBIAEoCRIPCgdwcm9maWxlGAIgASgJEhMKC2JvdW5kX25hbWVzGAMgAygJEhIKCmNyZWF0ZWRfYXQYBCABKAkSEgoKZXhwaXJlc19hdBgFIAEoCRIVCg1jcmVhdGVkX2J5X2NuGAYgASgJIn0KHE1pbnROb2RlU2NlcENoYWxsZW5nZVJlcXVlc3QSEQoJbm9kZV9uYW1lGAEgASgJEg8KB25vZGVfaWQYAiABKAkSDwoHcHJvZmlsZRgDIAEoCRITCgt0dGxfc2Vjb25kcxgEIAEoDRITCgtib3VuZF9uYW1lcxgFIAMoCSJzCh1NaW50Tm9kZVNjZXBDaGFsbGVuZ2VSZXNwb25zZRIaChJjaGFsbGVuZ2VfcGFzc3dvcmQYASABKAkSNgoJY2hhbGxlbmdlGAIgASgLMiMuY3J5cHRvcy5mbGVldC52MS5Ob2RlU2NlcENoYWxsZW5nZSJDCh1MaXN0Tm9kZVNjZXBDaGFsbGVuZ2VzUmVxdWVzdBIRCglub2RlX25hbWUYASABKAkSDwoHbm9kZV9pZBgCIAEoCSJZCh5MaXN0Tm9kZVNjZXBDaGFsbGVuZ2VzUmVzcG9uc2USNwoKY2hhbGxlbmdlcxgBIAMoCzIjLmNyeXB0b3MuZmxlZXQudjEuTm9kZVNjZXBDaGFsbGVuZ2UiUAoeUmV2b2tlTm9kZVNjZXBDaGFsbGVuZ2VSZXF1ZXN0EhEKCW5vZGVfbmFtZRgBIAEoCRIPCgdub2RlX2lkGAIgASgJEgoKAmlkGAMgASgJIlkKH1Jldm9rZU5vZGVTY2VwQ2hhbGxlbmdlUmVzcG9uc2USNgoJY2hhbGxlbmdlGAEgASgLMiMuY3J5cHRvcy5mbGVldC52MS5Ob2RlU2NlcENoYWxsZW5nZSLTAQoSTm9kZVNjZXBFbnJvbGxtZW50EgoKAmlkGAEgASgJEhYKDnRyYW5zYWN0aW9uX2lkGAIgASgJEg8KB3Byb2ZpbGUYAyABKAkSEgoKc3ViamVjdF9kbhgEIAEoCRIRCglkbnNfbmFtZXMYBSADKAkSFAoMaXBfYWRkcmVzc2VzGAYgAygJEg8KB2tleV9hbGcYByABKAkSDwoHY3NyX3BlbRgIIAEoCRIUCgxjaGFsbGVuZ2VfaWQYCSABKAkSEwoLcmVjZWl2ZWRfYXQYCiABKAkiVQoeTGlzdE5vZGVTY2VwRW5yb2xsbWVudHNSZXF1ZXN0EhEKCW5vZGVfbmFtZRgBIAEoCRIPCgdub2RlX2lkGAIgASgJEg8KB3Byb2ZpbGUYAyABKAkiXAofTGlzdE5vZGVTY2VwRW5yb2xsbWVudHNSZXNwb25zZRI5CgtlbnJvbGxtZW50cxgBIAMoCzIkLmNyeXB0b3MuZmxlZXQudjEuTm9kZVNjZXBFbnJvbGxtZW50IlIKIEFwcHJvdmVOb2RlU2NlcEVucm9sbG1lbnRSZXF1ZXN0EhEKCW5vZGVfbmFtZRgBIAEoCRIPCgdub2RlX2lkGAIgASgJEgoKAmlkGAMgASgJInEKIUFwcHJvdmVOb2RlU2NlcEVucm9sbG1lbnRSZXNwb25zZRI4CgplbnJvbGxtZW50GAEgASgLMiQuY3J5cHRvcy5mbGVldC52MS5Ob2RlU2NlcEVucm9sbG1lbnQSEgoKc2VyaWFsX2hleBgCIAEoCSJhCh9SZWplY3ROb2RlU2NlcEVucm9sbG1lbnRSZXF1ZXN0EhEKCW5vZGVfbmFtZRgBIAEoCRIPCgdub2RlX2lkGAIgASgJEgoKAmlkGAMgASgJEg4KBnJlYXNvbhgEIAEoCSJcCiBSZWplY3ROb2RlU2NlcEVucm9sbG1lbnRSZXNwb25zZRI4CgplbnJvbGxtZW50GAEgASgLMiQuY3J5cHRvcy5mbGVldC52MS5Ob2RlU2NlcEVucm9sbG1lbnQqUgoGSGVhbHRoEhYKEkhFQUxUSF9VTlNQRUNJRklFRBAAEg0KCUhFQUxUSF9VUBABEg8KC0hFQUxUSF9ET1dOEAISEAoMSEVBTFRIX0VSUk9SEAMyvzwKDEZsZWV0U2VydmljZRJUCglMaXN0Tm9kZXMSIi5jcnlwdG9zLmZsZWV0LnYxLkxpc3ROb2Rlc1JlcXVlc3QaIy5jcnlwdG9zLmZsZWV0LnYxLkxpc3ROb2Rlc1Jlc3BvbnNlEk4KB0dldE5vZGUSIC5jcnlwdG9zLmZsZWV0LnYxLkdldE5vZGVSZXF1ZXN0GiEuY3J5cHRvcy5mbGVldC52MS5HZXROb2RlUmVzcG9uc2USaQoQTGlzdENlcnRpZmljYXRlcxIpLmNyeXB0b3MuZmxlZXQudjEuTGlzdENlcnRpZmljYXRlc1JlcXVlc3QaKi5jcnlwdG9zLmZsZWV0LnYxLkxpc3RDZXJ0aWZpY2F0ZXNSZXNwb25zZRJdCgxMaXN0UHJvZmlsZXMSJS5jcnlwdG9zLmZsZWV0LnYxLkxpc3RQcm9maWxlc1JlcXVlc3QaJi5jcnlwdG9zLmZsZWV0LnYxLkxpc3RQcm9maWxlc1Jlc3BvbnNlEmAKDUNyZWF0ZVByb2ZpbGUSJi5jcnlwdG9zLmZsZWV0LnYxLkNyZWF0ZVByb2ZpbGVSZXF1ZXN0GicuY3J5cHRvcy5mbGVldC52MS5DcmVhdGVQcm9maWxlUmVzcG9uc2USYAoNVXBkYXRlUHJvZmlsZRImLmNyeXB0b3MuZmxlZXQudjEuVXBkYXRlUHJvZmlsZVJlcXVlc3QaJy5jcnlwdG9zLmZsZWV0LnYxLlVwZGF0ZVByb2ZpbGVSZXNwb25zZRJgCg1EZWxldGVQcm9maWxlEiYuY3J5cHRvcy5mbGVldC52MS5EZWxldGVQcm9maWxlUmVxdWVzdBonLmNyeXB0b3MuZmxlZXQudjEuRGVsZXRlUHJvZmlsZVJlc3BvbnNlEm8KEkFwcGx5UHJvZmlsZVRvTm9kZRIrLmNyeXB0b3MuZmxlZXQudjEuQXBwbHlQcm9maWxlVG9Ob2RlUmVxdWVzdBosLmNyeXB0b3MuZmxlZXQudjEuQXBwbHlQcm9maWxlVG9Ob2RlUmVzcG9uc2USeAoVU2V0UHJvZmlsZVJlcXVlc3RhYmxlEi4uY3J5cHRvcy5mbGVldC52MS5TZXRQcm9maWxlUmVxdWVzdGFibGVSZXF1ZXN0Gi8uY3J5cHRvcy5mbGVldC52MS5TZXRQcm9maWxlUmVxdWVzdGFibGVSZXNwb25zZRJ+ChdMaXN0UmVxdWVzdGFibGVQcm9maWxlcxIwLmNyeXB0b3MuZmxlZXQudjEuTGlzdFJlcXVlc3RhYmxlUHJvZmlsZXNSZXF1ZXN0GjEuY3J5cHRvcy5mbGVldC52MS5MaXN0UmVxdWVzdGFibGVQcm9maWxlc1Jlc3BvbnNlEl0KDExpc3RBZGFwdGVycxIlLmNyeXB0b3MuZmxlZXQudjEuTGlzdEFkYXB0ZXJzUmVxdWVzdBomLmNyeXB0b3MuZmxlZXQudjEuTGlzdEFkYXB0ZXJzUmVzcG9uc2USbAoRU2V0QWRhcHRlckVuYWJsZWQSKi5jcnlwdG9zLmZsZWV0LnYxLlNldEFkYXB0ZXJFbmFibGVkUmVxdWVzdBorLmNyeXB0b3MuZmxlZXQudjEuU2V0QWRhcHRlckVuYWJsZWRSZXNwb25zZRJmCg9TZXROb2RlUHJvdG9jb2wSKC5jcnlwdG9zLmZsZWV0LnYxLlNldE5vZGVQcm90b2NvbFJlcXVlc3QaKS5jcnlwdG9zLmZsZWV0LnYxLlNldE5vZGVQcm90b2NvbFJlc3BvbnNlElQKCUxpc3RBdWRpdBIiLmNyeXB0b3MuZmxlZXQudjEuTGlzdEF1ZGl0UmVxdWVzdBojLmNyeXB0b3MuZmxlZXQudjEuTGlzdEF1ZGl0UmVzcG9uc2USZgoPTGlzdEVucm9sbG1lbnRzEiguY3J5cHRvcy5mbGVldC52MS5MaXN0RW5yb2xsbWVudHNSZXF1ZXN0GikuY3J5cHRvcy5mbGVldC52MS5MaXN0RW5yb2xsbWVudHNSZXNwb25zZRJpChBDcmVhdGVFbnJvbGxtZW50EikuY3J5cHRvcy5mbGVldC52MS5DcmVhdGVFbnJvbGxtZW50UmVxdWVzdBoqLmNyeXB0b3MuZmxlZXQudjEuQ3JlYXRlRW5yb2xsbWVudFJlc3BvbnNlEmwKEUFwcHJvdmVFbnJvbGxtZW50EiouY3J5cHRvcy5mbGVldC52MS5BcHByb3ZlRW5yb2xsbWVudFJlcXVlc3QaKy5jcnlwdG9zLmZsZWV0LnYxLkFwcHJvdmVFbnJvbGxtZW50UmVzcG9uc2USaQoQUmVqZWN0RW5yb2xsbWVudBIpLmNyeXB0b3MuZmxlZXQudjEuUmVqZWN0RW5yb2xsbWVudFJlcXVlc3QaKi5jcnlwdG9zLmZsZWV0LnYxLlJlamVjdEVucm9sbG1lbnRSZXNwb25zZRJLCgZXaG9BbUkSHy5jcnlwdG9zLmZsZWV0LnYxLldob0FtSVJlcXVlc3QaIC5jcnlwdG9zLmZsZWV0LnYxLldob0FtSVJlc3BvbnNlEmwKEVJldm9rZUNlcnRpZmljYXRlEiouY3J5cHRvcy5mbGVldC52MS5SZXZva2VDZXJ0aWZpY2F0ZVJlcXVlc3QaKy5jcnlwdG9zLmZsZWV0LnYxLlJldm9rZUNlcnRpZmljYXRlUmVzcG9uc2USYwoOR2V0Q2VydGlmaWNhdGUSJy5jcnlwdG9zLmZsZWV0LnYxLkdldENlcnRpZmljYXRlUmVxdWVzdBooLmNyeXB0b3MuZmxlZXQudjEuR2V0Q2VydGlmaWNhdGVSZXNwb25zZRJyChNMaXN0Tm9kZUF1ZGl0RXZlbnRzEiwuY3J5cHRvcy5mbGVldC52MS5MaXN0Tm9kZUF1ZGl0RXZlbnRzUmVxdWVzdBotLmNyeXB0b3MuZmxlZXQudjEuTGlzdE5vZGVBdWRpdEV2ZW50c1Jlc3BvbnNlEnUKFFZlcmlmeU5vZGVBdWRpdENoYWluEi0uY3J5cHRvcy5mbGVldC52MS5WZXJpZnlOb2RlQXVkaXRDaGFpblJlcXVlc3QaLi5jcnlwdG9zLmZsZWV0LnYxLlZlcmlmeU5vZGVBdWRpdENoYWluUmVzcG9uc2USgQEKGFZhbGlkYXRlQ2VydGlmaWNhdGVDaGFpbhIxLmNyeXB0b3MuZmxlZXQudjEuVmFsaWRhdGVDZXJ0aWZpY2F0ZUNoYWluUmVxdWVzdBoyLmNyeXB0b3MuZmxlZXQudjEuVmFsaWRhdGVDZXJ0aWZpY2F0ZUNoYWluUmVzcG9uc2USfgoXTGlzdE5vZGVUc2FDZXJ0aWZpY2F0ZXMSMC5jcnlwdG9zLmZsZWV0LnYxLkxpc3ROb2RlVHNhQ2VydGlmaWNhdGVzUmVxdWVzdBoxLmNyeXB0b3MuZmxlZXQudjEuTGlzdE5vZGVUc2FDZXJ0aWZpY2F0ZXNSZXNwb25zZRJvChJHZXROb2RlSW1hZ2VTdGF0dXMSKy5jcnlwdG9zLmZsZWV0LnYxLkdldE5vZGVJbWFnZVN0YXR1c1JlcXVlc3QaLC5jcnlwdG9zLmZsZWV0LnYxLkdldE5vZGVJbWFnZVN0YXR1c1Jlc3BvbnNlEmMKDlN0YWdlTm9kZUltYWdlEicuY3J5cHRvcy5mbGVldC52MS5TdGFnZU5vZGVJbWFnZVJlcXVlc3QaKC5jcnlwdG9zLmZsZWV0LnYxLlN0YWdlTm9kZUltYWdlUmVzcG9uc2USbAoRQWN0aXZhdGVOb2RlSW1hZ2USKi5jcnlwdG9zLmZsZWV0LnYxLkFjdGl2YXRlTm9kZUltYWdlUmVxdWVzdBorLmNyeXB0b3MuZmxlZXQudjEuQWN0aXZhdGVOb2RlSW1hZ2VSZXNwb25zZRJsChFSb2xsYmFja05vZGVJbWFnZRIqLmNyeXB0b3MuZmxlZXQudjEuUm9sbGJhY2tOb2RlSW1hZ2VSZXF1ZXN0GisuY3J5cHRvcy5mbGVldC52MS5Sb2xsYmFja05vZGVJbWFnZVJlc3BvbnNlElQKCUlzc3VlTGVhZhIiLmNyeXB0b3MuZmxlZXQudjEuSXNzdWVMZWFmUmVxdWVzdBojLmNyeXB0b3MuZmxlZXQudjEuSXNzdWVMZWFmUmVzcG9uc2USVAoJUmVrZXlOb2RlEiIuY3J5cHRvcy5mbGVldC52MS5SZWtleU5vZGVSZXF1ZXN0GiMuY3J5cHRvcy5mbGVldC52MS5SZWtleU5vZGVSZXNwb25zZRJgCg1HZXROb2RlQ29uZmlnEiYuY3J5cHRvcy5mbGVldC52MS5HZXROb2RlQ29uZmlnUmVxdWVzdBonLmNyeXB0b3MuZmxlZXQudjEuR2V0Tm9kZUNvbmZpZ1Jlc3BvbnNlEmYKD0FwcGx5Tm9kZUNvbmZpZxIoLmNyeXB0b3MuZmxlZXQudjEuQXBwbHlOb2RlQ29uZmlnUmVxdWVzdBopLmNyeXB0b3MuZmxlZXQudjEuQXBwbHlOb2RlQ29uZmlnUmVzcG9uc2USWgoLRXhwb3J0Q0FLZXkSJC5jcnlwdG9zLmZsZWV0LnYxLkV4cG9ydENBS2V5UmVxdWVzdBolLmNyeXB0b3MuZmxlZXQudjEuRXhwb3J0Q0FLZXlSZXNwb25zZRJaCgtJbXBvcnRDQUtleRIkLmNyeXB0b3MuZmxlZXQudjEuSW1wb3J0Q0FLZXlSZXF1ZXN0GiUuY3J5cHRvcy5mbGVldC52MS5JbXBvcnRDQUtleVJlc3BvbnNlEpYBCh9DcmVhdGVPcGVyYXRvckNyZWRlbnRpYWxSZXF1ZXN0EjguY3J5cHRvcy5mbGVldC52MS5DcmVhdGVPcGVyYXRvckNyZWRlbnRpYWxSZXF1ZXN0UmVxdWVzdBo5LmNyeXB0b3MuZmxlZXQudjEuQ3JlYXRlT3BlcmF0b3JDcmVkZW50aWFsUmVxdWVzdFJlc3BvbnNlEpMBCh5MaXN0T3BlcmF0b3JDcmVkZW50aWFsUmVxdWVzdHMSNy5jcnlwdG9zLmZsZWV0LnYxLkxpc3RPcGVyYXRvckNyZWRlbnRpYWxSZXF1ZXN0c1JlcXVlc3QaOC5jcnlwdG9zLmZsZWV0LnYxLkxpc3RPcGVyYXRvckNyZWRlbnRpYWxSZXF1ZXN0c1Jlc3BvbnNlEpYBCh9DYW5jZWxPcGVyYXRvckNyZWRlbnRpYWxSZXF1ZXN0EjguY3J5cHRvcy5mbGVldC52MS5DYW5jZWxPcGVyYXRvckNyZWRlbnRpYWxSZXF1ZXN0UmVxdWVzdBo5LmNyeXB0b3MuZmxlZXQudjEuQ2FuY2VsT3BlcmF0b3JDcmVkZW50aWFsUmVxdWVzdFJlc3BvbnNlEoEBChhSZWNvcmRPcGVyYXRvckNyZWRlbnRpYWwSMS5jcnlwdG9zLmZsZWV0LnYxLlJlY29yZE9wZXJhdG9yQ3JlZGVudGlhbFJlcXVlc3QaMi5jcnlwdG9zLmZsZWV0LnYxLlJlY29yZE9wZXJhdG9yQ3JlZGVudGlhbFJlc3BvbnNlEoEBChhSZXZva2VPcGVyYXRvckNyZWRlbnRpYWwSMS5jcnlwdG9zLmZsZWV0LnYxLlJldm9rZU9wZXJhdG9yQ3JlZGVudGlhbFJlcXVlc3QaMi5jcnlwdG9zLmZsZWV0LnYxLlJldm9rZU9wZXJhdG9yQ3JlZGVudGlhbFJlc3BvbnNlEn4KF0xpc3RPcGVyYXRvckNyZWRlbnRpYWxzEjAuY3J5cHRvcy5mbGVldC52MS5MaXN0T3BlcmF0b3JDcmVkZW50aWFsc1JlcXVlc3QaMS5jcnlwdG9zLmZsZWV0LnYxLkxpc3RPcGVyYXRvckNyZWRlbnRpYWxzUmVzcG9uc2USZgoPTGlzdE9wZXJhdG9yQ0FzEiguY3J5cHRvcy5mbGVldC52MS5MaXN0T3BlcmF0b3JDQXNSZXF1ZXN0GikuY3J5cHRvcy5mbGVldC52MS5MaXN0T3BlcmF0b3JDQXNSZXNwb25zZRJvChJSZWdpc3Rlck9wZXJhdG9yQ0ESKy5jcnlwdG9zLmZsZWV0LnYxLlJlZ2lzdGVyT3BlcmF0b3JDQVJlcXVlc3QaLC5jcnlwdG9zLmZsZWV0LnYxLlJlZ2lzdGVyT3BlcmF0b3JDQVJlc3BvbnNlEmkKEFJldGlyZU9wZXJhdG9yQ0ESKS5jcnlwdG9zLmZsZWV0LnYxLlJldGlyZU9wZXJhdG9yQ0FSZXF1ZXN0GiouY3J5cHRvcy5mbGVldC52MS5SZXRpcmVPcGVyYXRvckNBUmVzcG9uc2USewoWU2V0T3BlcmF0b3JDQUNSTFNvdXJjZRIvLmNyeXB0b3MuZmxlZXQudjEuU2V0T3BlcmF0b3JDQUNSTFNvdXJjZVJlcXVlc3QaMC5jcnlwdG9zLmZsZWV0LnYxLlNldE9wZXJhdG9yQ0FDUkxTb3VyY2VSZXNwb25zZRJsChFVcGxvYWRPcGVyYXRvckNSTBIqLmNyeXB0b3MuZmxlZXQudjEuVXBsb2FkT3BlcmF0b3JDUkxSZXF1ZXN0GisuY3J5cHRvcy5mbGVldC52MS5VcGxvYWRPcGVyYXRvckNSTFJlc3BvbnNlEmwKEVNldE9wZXJhdG9yQ0FPQ1NQEiouY3J5cHRvcy5mbGVldC52MS5TZXRPcGVyYXRvckNBT0NTUFJlcXVlc3QaKy5jcnlwdG9zLmZsZWV0LnYxLlNldE9wZXJhdG9yQ0FPQ1NQUmVzcG9uc2USZgoPUHJldmlld0Fkb3B0aW9uEiguY3J5cHRvcy5mbGVldC52MS5QcmV2aWV3QWRvcHRpb25SZXF1ZXN0GikuY3J5cHRvcy5mbGVldC52MS5QcmV2aWV3QWRvcHRpb25SZXNwb25zZRJpChBMaXN0SW5zdGFsbERpc2tzEikuY3J5cHRvcy5mbGVldC52MS5MaXN0SW5zdGFsbERpc2tzUmVxdWVzdBoqLmNyeXB0b3MuZmxlZXQudjEuTGlzdEluc3RhbGxEaXNrc1Jlc3BvbnNlElYKCUFkb3B0Tm9kZRIiLmNyeXB0b3MuZmxlZXQudjEuQWRvcHROb2RlUmVxdWVzdBojLmNyeXB0b3MuZmxlZXQudjEuQWRvcHROb2RlUmVzcG9uc2UwARKHAQoaQ29uZmlybUFkb3B0aW9uRmluZ2VycHJpbnQSMy5jcnlwdG9zLmZsZWV0LnYxLkNvbmZpcm1BZG9wdGlvbkZpbmdlcnByaW50UmVxdWVzdBo0LmNyeXB0b3MuZmxlZXQudjEuQ29uZmlybUFkb3B0aW9uRmluZ2VycHJpbnRSZXNwb25zZRJpChBEZWNvbW1pc3Npb25Ob2RlEikuY3J5cHRvcy5mbGVldC52MS5EZWNvbW1pc3Npb25Ob2RlUmVxdWVzdBoqLmNyeXB0b3MuZmxlZXQudjEuRGVjb21taXNzaW9uTm9kZVJlc3BvbnNlElcKClJlYm9vdE5vZGUSIy5jcnlwdG9zLmZsZWV0LnYxLlJlYm9vdE5vZGVSZXF1ZXN0GiQuY3J5cHRvcy5mbGVldC52MS5SZWJvb3ROb2RlUmVzcG9uc2USVwoKUmVuYW1lTm9kZRIjLmNyeXB0b3MuZmxlZXQudjEuUmVuYW1lTm9kZVJlcXVlc3QaJC5jcnlwdG9zLmZsZWV0LnYxLlJlbmFtZU5vZGVSZXNwb25zZRJXCgpSZW1vdmVOb2RlEiMuY3J5cHRvcy5mbGVldC52MS5SZW1vdmVOb2RlUmVxdWVzdBokLmNyeXB0b3MuZmxlZXQudjEuUmVtb3ZlTm9kZVJlc3BvbnNlEloKC0xpc3RNY3BLZXlzEiQuY3J5cHRvcy5mbGVldC52MS5MaXN0TWNwS2V5c1JlcXVlc3QaJS5jcnlwdG9zLmZsZWV0LnYxLkxpc3RNY3BLZXlzUmVzcG9uc2USXQoMUmV2b2tlTWNwS2V5EiUuY3J5cHRvcy5mbGVldC52MS5SZXZva2VNY3BLZXlSZXF1ZXN0GiYuY3J5cHRvcy5mbGVldC52MS5SZXZva2VNY3BLZXlSZXNwb25zZRJdCgxDcmVhdGVNY3BLZXkSJS5jcnlwdG9zLmZsZWV0LnYxLkNyZWF0ZU1jcEtleVJlcXVlc3QaJi5jcnlwdG9zLmZsZWV0LnYxLkNyZWF0ZU1jcEtleVJlc3BvbnNlEmAKDUxpc3RBcHByb3ZhbHMSJi5jcnlwdG9zLmZsZWV0LnYxLkxpc3RBcHByb3ZhbHNSZXF1ZXN0GicuY3J5cHRvcy5mbGVldC52MS5MaXN0QXBwcm92YWxzUmVzcG9uc2USYwoORGVjaWRlQXBwcm92YWwSJy5jcnlwdG9zLmZsZWV0LnYxLkRlY2lkZUFwcHJvdmFsUmVxdWVzdBooLmNyeXB0b3MuZmxlZXQudjEuRGVjaWRlQXBwcm92YWxSZXNwb25zZRKBAQoYQ3JlYXRlQ2VydGlmaWNhdGVSZXF1ZXN0EjEuY3J5cHRvcy5mbGVldC52MS5DcmVhdGVDZXJ0aWZpY2F0ZVJlcXVlc3RSZXF1ZXN0GjIuY3J5cHRvcy5mbGVldC52MS5DcmVhdGVDZXJ0aWZpY2F0ZVJlcXVlc3RSZXNwb25zZRJ+ChdMaXN0Q2VydGlmaWNhdGVSZXF1ZXN0cxIwLmNyeXB0b3MuZmxlZXQudjEuTGlzdENlcnRpZmljYXRlUmVxdWVzdHNSZXF1ZXN0GjEuY3J5cHRvcy5mbGVldC52MS5MaXN0Q2VydGlmaWNhdGVSZXF1ZXN0c1Jlc3BvbnNlEoQBChlHZXRDZXJ0aWZpY2F0ZVJlcXVlc3RCeUlEEjIuY3J5cHRvcy5mbGVldC52MS5HZXRDZXJ0aWZpY2F0ZVJlcXVlc3RCeUlEUmVxdWVzdBozLmNyeXB0b3MuZmxlZXQudjEuR2V0Q2VydGlmaWNhdGVSZXF1ZXN0QnlJRFJlc3BvbnNlEoEBChhDYW5jZWxDZXJ0aWZpY2F0ZVJlcXVlc3QSMS5jcnlwdG9zLmZsZWV0LnYxLkNhbmNlbENlcnRpZmljYXRlUmVxdWVzdFJlcXVlc3QaMi5jcnlwdG9zLmZsZWV0LnYxLkNhbmNlbENlcnRpZmljYXRlUmVxdWVzdFJlc3BvbnNlEngKFU1pbnROb2RlU2NlcENoYWxsZW5nZRIuLmNyeXB0b3MuZmxlZXQudjEuTWludE5vZGVTY2VwQ2hhbGxlbmdlUmVxdWVzdBovLmNyeXB0b3MuZmxlZXQudjEuTWludE5vZGVTY2VwQ2hhbGxlbmdlUmVzcG9uc2USewoWTGlzdE5vZGVTY2VwQ2hhbGxlbmdlcxIvLmNyeXB0b3MuZmxlZXQudjEuTGlzdE5vZGVTY2VwQ2hhbGxlbmdlc1JlcXVlc3QaMC5jcnlwdG9zLmZsZWV0LnYxLkxpc3ROb2RlU2NlcENoYWxsZW5nZXNSZXNwb25zZRJ+ChdSZXZva2VOb2RlU2NlcENoYWxsZW5nZRIwLmNyeXB0b3MuZmxlZXQudjEuUmV2b2tlTm9kZVNjZXBDaGFsbGVuZ2VSZXF1ZXN0GjEuY3J5cHRvcy5mbGVldC52MS5SZXZva2VOb2RlU2NlcENoYWxsZW5nZVJlc3BvbnNlEn4KF0xpc3ROb2RlU2NlcEVucm9sbG1lbnRzEjAuY3J5cHRvcy5mbGVldC52MS5MaXN0Tm9kZVNjZXBFbnJvbGxtZW50c1JlcXVlc3QaMS5jcnlwdG9zLmZsZWV0LnYxLkxpc3ROb2RlU2NlcEVucm9sbG1lbnRzUmVzcG9uc2UShAEKGUFwcHJvdmVOb2RlU2NlcEVucm9sbG1lbnQSMi5jcnlwdG9zLmZsZWV0LnYxLkFwcHJvdmVOb2RlU2NlcEVucm9sbG1lbnRSZXF1ZXN0GjMuY3J5cHRvcy5mbGVldC52MS5BcHByb3ZlTm9kZVNjZXBFbnJvbGxtZW50UmVzcG9uc2USgQEKGFJlamVjdE5vZGVTY2VwRW5yb2xsbWVudBIxLmNyeXB0b3MuZmxlZXQudjEuUmVqZWN0Tm9kZVNjZXBFbnJvbGxtZW50UmVxdWVzdBoyLmNyeXB0b3MuZmxlZXQudjEuUmVqZWN0Tm9kZVNjZXBFbnJvbGxtZW50UmVzcG9uc2VCSFpGZ2l0aHViLmNvbS9DcnlwdE9TLVBLSS9jcnlwdG9zLW1hbmFnZXIvZ2VuL2dvL2NyeXB0b3MvZmxlZXQvdjE7ZmxlZXR2MWIGcHJvdG8z", [file_cryptos_fleet_v1_operator_ca, file_cryptos_node_v1_config, file_cryptos_node_v1_node, file_cryptos_node_v1_status]); /** * @generated from message cryptos.fleet.v1.ListNodesRequest @@ -4399,6 +4399,289 @@ export type VerifyNodeAuditChainResponse = Message<"cryptos.fleet.v1.VerifyNodeA export const VerifyNodeAuditChainResponseSchema: GenMessage = /*@__PURE__*/ messageDesc(file_cryptos_fleet_v1_fleet, 134); +/** + * GetNodeImageStatusRequest names the node whose CryptOS image status to + * read. + * + * @generated from message cryptos.fleet.v1.GetNodeImageStatusRequest + */ +export type GetNodeImageStatusRequest = Message<"cryptos.fleet.v1.GetNodeImageStatusRequest"> & { + /** + * node_name is the managed node to read. + * Deprecated: use node_id. Still resolves the node's current name for one + * release. + * + * @generated from field: string node_name = 1; + */ + nodeName: string; + + /** + * node_id is the stable ID (NodeSummary.id) of the node. Preferred over + * node_name; when both are set they must name the same node, or the + * manager returns InvalidArgument. + * + * @generated from field: string node_id = 2; + */ + nodeId: string; +}; + +/** + * Describes the message cryptos.fleet.v1.GetNodeImageStatusRequest. + * Use `create(GetNodeImageStatusRequestSchema)` to create a new message. + */ +export const GetNodeImageStatusRequestSchema: GenMessage = /*@__PURE__*/ + messageDesc(file_cryptos_fleet_v1_fleet, 135); + +/** + * NodeImageStatus describes the images on a managed node's ESP and the one + * currently running. + * + * @generated from message cryptos.fleet.v1.NodeImageStatus + */ +export type NodeImageStatus = Message<"cryptos.fleet.v1.NodeImageStatus"> & { + /** + * running_sha256 is the digest of the image the node booted, hex encoded. + * + * @generated from field: string running_sha256 = 1; + */ + runningSha256: string; + + /** + * active_sha256 is the digest of the image the firmware will boot next. It + * differs from running_sha256 exactly when a staged image is waiting for a + * reboot. + * + * @generated from field: string active_sha256 = 2; + */ + activeSha256: string; + + /** + * previous_sha256 is the retained image RollbackNodeImage would restore, + * hex encoded, empty on a node that has never been upgraded. + * + * @generated from field: string previous_sha256 = 3; + */ + previousSha256: string; + + /** + * reboot_pending is true when active_sha256 differs from running_sha256. + * + * @generated from field: bool reboot_pending = 4; + */ + rebootPending: boolean; + + /** + * running_version is the CryptOS version string baked into the running + * image. + * + * @generated from field: string running_version = 5; + */ + runningVersion: string; +}; + +/** + * Describes the message cryptos.fleet.v1.NodeImageStatus. + * Use `create(NodeImageStatusSchema)` to create a new message. + */ +export const NodeImageStatusSchema: GenMessage = /*@__PURE__*/ + messageDesc(file_cryptos_fleet_v1_fleet, 136); + +/** + * @generated from message cryptos.fleet.v1.GetNodeImageStatusResponse + */ +export type GetNodeImageStatusResponse = Message<"cryptos.fleet.v1.GetNodeImageStatusResponse"> & { + /** + * @generated from field: cryptos.fleet.v1.NodeImageStatus status = 1; + */ + status?: NodeImageStatus | undefined; +}; + +/** + * Describes the message cryptos.fleet.v1.GetNodeImageStatusResponse. + * Use `create(GetNodeImageStatusResponseSchema)` to create a new message. + */ +export const GetNodeImageStatusResponseSchema: GenMessage = /*@__PURE__*/ + messageDesc(file_cryptos_fleet_v1_fleet, 137); + +/** + * StageNodeImageRequest carries where to fetch the image from and the + * detached release signature over it; the manager fetches image_url itself. + * + * @generated from message cryptos.fleet.v1.StageNodeImageRequest + */ +export type StageNodeImageRequest = Message<"cryptos.fleet.v1.StageNodeImageRequest"> & { + /** + * node_name is the managed node to stage onto. + * Deprecated: use node_id. Still resolves the node's current name for one + * release. + * + * @generated from field: string node_name = 1; + */ + nodeName: string; + + /** + * node_id is the stable ID (NodeSummary.id) of the node. Preferred over + * node_name; when both are set they must name the same node, or the + * manager returns InvalidArgument. + * + * @generated from field: string node_id = 2; + */ + nodeId: string; + + /** + * image_url is an http or https URL the manager fetches the image from. + * Required. + * + * @generated from field: string image_url = 3; + */ + imageUrl: string; + + /** + * signature is the detached release signature over the whole image: PKCS#1 + * v1.5 over a SHA-256 digest, made by the CryptOS release key. Required; + * the node refuses a transfer it cannot verify. + * + * @generated from field: bytes signature = 4; + */ + signature: Uint8Array; + + /** + * sha256 is the expected digest of the image, hex encoded. Optional; when + * set the node checks it against what it received. + * + * @generated from field: string sha256 = 5; + */ + sha256: string; +}; + +/** + * Describes the message cryptos.fleet.v1.StageNodeImageRequest. + * Use `create(StageNodeImageRequestSchema)` to create a new message. + */ +export const StageNodeImageRequestSchema: GenMessage = /*@__PURE__*/ + messageDesc(file_cryptos_fleet_v1_fleet, 138); + +/** + * @generated from message cryptos.fleet.v1.StageNodeImageResponse + */ +export type StageNodeImageResponse = Message<"cryptos.fleet.v1.StageNodeImageResponse"> & { + /** + * @generated from field: cryptos.fleet.v1.NodeImageStatus status = 1; + */ + status?: NodeImageStatus | undefined; + + /** + * requires_reboot is always true on success: the staged image is what the + * firmware will boot, but the node is still running the old one. + * + * @generated from field: bool requires_reboot = 2; + */ + requiresReboot: boolean; +}; + +/** + * Describes the message cryptos.fleet.v1.StageNodeImageResponse. + * Use `create(StageNodeImageResponseSchema)` to create a new message. + */ +export const StageNodeImageResponseSchema: GenMessage = /*@__PURE__*/ + messageDesc(file_cryptos_fleet_v1_fleet, 139); + +/** + * ActivateNodeImageRequest confirms an operator-initiated reboot onto a + * staged image. + * + * @generated from message cryptos.fleet.v1.ActivateNodeImageRequest + */ +export type ActivateNodeImageRequest = Message<"cryptos.fleet.v1.ActivateNodeImageRequest"> & { + /** + * @generated from field: string node_name = 1; + */ + nodeName: string; + + /** + * @generated from field: string node_id = 2; + */ + nodeId: string; + + /** + * confirm_ca_cn must equal the node's current CA common name. + * + * @generated from field: string confirm_ca_cn = 3; + */ + confirmCaCn: string; +}; + +/** + * Describes the message cryptos.fleet.v1.ActivateNodeImageRequest. + * Use `create(ActivateNodeImageRequestSchema)` to create a new message. + */ +export const ActivateNodeImageRequestSchema: GenMessage = /*@__PURE__*/ + messageDesc(file_cryptos_fleet_v1_fleet, 140); + +/** + * @generated from message cryptos.fleet.v1.ActivateNodeImageResponse + */ +export type ActivateNodeImageResponse = Message<"cryptos.fleet.v1.ActivateNodeImageResponse"> & { + /** + * The node reboots shortly after replying; the reply exists so the caller + * learns the reboot was accepted before the connection drops. + * + * @generated from field: bool rebooting = 1; + */ + rebooting: boolean; +}; + +/** + * Describes the message cryptos.fleet.v1.ActivateNodeImageResponse. + * Use `create(ActivateNodeImageResponseSchema)` to create a new message. + */ +export const ActivateNodeImageResponseSchema: GenMessage = /*@__PURE__*/ + messageDesc(file_cryptos_fleet_v1_fleet, 141); + +/** + * @generated from message cryptos.fleet.v1.RollbackNodeImageRequest + */ +export type RollbackNodeImageRequest = Message<"cryptos.fleet.v1.RollbackNodeImageRequest"> & { + /** + * @generated from field: string node_name = 1; + */ + nodeName: string; + + /** + * @generated from field: string node_id = 2; + */ + nodeId: string; +}; + +/** + * Describes the message cryptos.fleet.v1.RollbackNodeImageRequest. + * Use `create(RollbackNodeImageRequestSchema)` to create a new message. + */ +export const RollbackNodeImageRequestSchema: GenMessage = /*@__PURE__*/ + messageDesc(file_cryptos_fleet_v1_fleet, 142); + +/** + * @generated from message cryptos.fleet.v1.RollbackNodeImageResponse + */ +export type RollbackNodeImageResponse = Message<"cryptos.fleet.v1.RollbackNodeImageResponse"> & { + /** + * @generated from field: cryptos.fleet.v1.NodeImageStatus status = 1; + */ + status?: NodeImageStatus | undefined; + + /** + * @generated from field: bool requires_reboot = 2; + */ + requiresReboot: boolean; +}; + +/** + * Describes the message cryptos.fleet.v1.RollbackNodeImageResponse. + * Use `create(RollbackNodeImageResponseSchema)` to create a new message. + */ +export const RollbackNodeImageResponseSchema: GenMessage = /*@__PURE__*/ + messageDesc(file_cryptos_fleet_v1_fleet, 143); + /** * NodeScepChallenge describes a one-time SCEP challenge on a managed node, * without the challenge itself, which only MintNodeScepChallengeResponse @@ -4456,7 +4739,7 @@ export type NodeScepChallenge = Message<"cryptos.fleet.v1.NodeScepChallenge"> & * Use `create(NodeScepChallengeSchema)` to create a new message. */ export const NodeScepChallengeSchema: GenMessage = /*@__PURE__*/ - messageDesc(file_cryptos_fleet_v1_fleet, 135); + messageDesc(file_cryptos_fleet_v1_fleet, 144); /** * @generated from message cryptos.fleet.v1.MintNodeScepChallengeRequest @@ -4501,7 +4784,7 @@ export type MintNodeScepChallengeRequest = Message<"cryptos.fleet.v1.MintNodeSce * Use `create(MintNodeScepChallengeRequestSchema)` to create a new message. */ export const MintNodeScepChallengeRequestSchema: GenMessage = /*@__PURE__*/ - messageDesc(file_cryptos_fleet_v1_fleet, 136); + messageDesc(file_cryptos_fleet_v1_fleet, 145); /** * @generated from message cryptos.fleet.v1.MintNodeScepChallengeResponse @@ -4526,7 +4809,7 @@ export type MintNodeScepChallengeResponse = Message<"cryptos.fleet.v1.MintNodeSc * Use `create(MintNodeScepChallengeResponseSchema)` to create a new message. */ export const MintNodeScepChallengeResponseSchema: GenMessage = /*@__PURE__*/ - messageDesc(file_cryptos_fleet_v1_fleet, 137); + messageDesc(file_cryptos_fleet_v1_fleet, 146); /** * @generated from message cryptos.fleet.v1.ListNodeScepChallengesRequest @@ -4548,7 +4831,7 @@ export type ListNodeScepChallengesRequest = Message<"cryptos.fleet.v1.ListNodeSc * Use `create(ListNodeScepChallengesRequestSchema)` to create a new message. */ export const ListNodeScepChallengesRequestSchema: GenMessage = /*@__PURE__*/ - messageDesc(file_cryptos_fleet_v1_fleet, 138); + messageDesc(file_cryptos_fleet_v1_fleet, 147); /** * @generated from message cryptos.fleet.v1.ListNodeScepChallengesResponse @@ -4567,7 +4850,7 @@ export type ListNodeScepChallengesResponse = Message<"cryptos.fleet.v1.ListNodeS * Use `create(ListNodeScepChallengesResponseSchema)` to create a new message. */ export const ListNodeScepChallengesResponseSchema: GenMessage = /*@__PURE__*/ - messageDesc(file_cryptos_fleet_v1_fleet, 139); + messageDesc(file_cryptos_fleet_v1_fleet, 148); /** * @generated from message cryptos.fleet.v1.RevokeNodeScepChallengeRequest @@ -4594,7 +4877,7 @@ export type RevokeNodeScepChallengeRequest = Message<"cryptos.fleet.v1.RevokeNod * Use `create(RevokeNodeScepChallengeRequestSchema)` to create a new message. */ export const RevokeNodeScepChallengeRequestSchema: GenMessage = /*@__PURE__*/ - messageDesc(file_cryptos_fleet_v1_fleet, 140); + messageDesc(file_cryptos_fleet_v1_fleet, 149); /** * @generated from message cryptos.fleet.v1.RevokeNodeScepChallengeResponse @@ -4613,7 +4896,244 @@ export type RevokeNodeScepChallengeResponse = Message<"cryptos.fleet.v1.RevokeNo * Use `create(RevokeNodeScepChallengeResponseSchema)` to create a new message. */ export const RevokeNodeScepChallengeResponseSchema: GenMessage = /*@__PURE__*/ - messageDesc(file_cryptos_fleet_v1_fleet, 141); + messageDesc(file_cryptos_fleet_v1_fleet, 150); + +/** + * NodeScepEnrollment is an initial SCEP enrolment on a managed node, held for + * an operator decision. The challenge that authorized it was consumed on + * arrival and is not carried. + * + * @generated from message cryptos.fleet.v1.NodeScepEnrollment + */ +export type NodeScepEnrollment = Message<"cryptos.fleet.v1.NodeScepEnrollment"> & { + /** + * id identifies the enrolment for approval or rejection. + * + * @generated from field: string id = 1; + */ + id: string; + + /** + * transaction_id is the client's SCEP transactionID (RFC 8894 section + * 3.2.1.1). + * + * @generated from field: string transaction_id = 2; + */ + transactionId: string; + + /** + * profile is the node's Scep.profiles entry it will issue from. + * + * @generated from field: string profile = 3; + */ + profile: string; + + /** + * subject_dn is the subject the request asks for, as an RFC 4514 string. + * + * @generated from field: string subject_dn = 4; + */ + subjectDn: string; + + /** + * @generated from field: repeated string dns_names = 5; + */ + dnsNames: string[]; + + /** + * @generated from field: repeated string ip_addresses = 6; + */ + ipAddresses: string[]; + + /** + * key_alg is the requested subject key, for example "RSA-2048" or + * "ECDSA-P384". + * + * @generated from field: string key_alg = 7; + */ + keyAlg: string; + + /** + * csr_pem is the PKCS#10 request the client signed, PEM-encoded, for an + * operator who wants to inspect it before deciding. + * + * @generated from field: string csr_pem = 8; + */ + csrPem: string; + + /** + * challenge_id is the id of the challenge that authorized the request. + * + * @generated from field: string challenge_id = 9; + */ + challengeId: string; + + /** + * @generated from field: string received_at = 10; + */ + receivedAt: string; +}; + +/** + * Describes the message cryptos.fleet.v1.NodeScepEnrollment. + * Use `create(NodeScepEnrollmentSchema)` to create a new message. + */ +export const NodeScepEnrollmentSchema: GenMessage = /*@__PURE__*/ + messageDesc(file_cryptos_fleet_v1_fleet, 151); + +/** + * @generated from message cryptos.fleet.v1.ListNodeScepEnrollmentsRequest + */ +export type ListNodeScepEnrollmentsRequest = Message<"cryptos.fleet.v1.ListNodeScepEnrollmentsRequest"> & { + /** + * @generated from field: string node_name = 1; + */ + nodeName: string; + + /** + * @generated from field: string node_id = 2; + */ + nodeId: string; + + /** + * profile, when set, keeps only enrolments for that profile. + * + * @generated from field: string profile = 3; + */ + profile: string; +}; + +/** + * Describes the message cryptos.fleet.v1.ListNodeScepEnrollmentsRequest. + * Use `create(ListNodeScepEnrollmentsRequestSchema)` to create a new message. + */ +export const ListNodeScepEnrollmentsRequestSchema: GenMessage = /*@__PURE__*/ + messageDesc(file_cryptos_fleet_v1_fleet, 152); + +/** + * @generated from message cryptos.fleet.v1.ListNodeScepEnrollmentsResponse + */ +export type ListNodeScepEnrollmentsResponse = Message<"cryptos.fleet.v1.ListNodeScepEnrollmentsResponse"> & { + /** + * @generated from field: repeated cryptos.fleet.v1.NodeScepEnrollment enrollments = 1; + */ + enrollments: NodeScepEnrollment[]; +}; + +/** + * Describes the message cryptos.fleet.v1.ListNodeScepEnrollmentsResponse. + * Use `create(ListNodeScepEnrollmentsResponseSchema)` to create a new message. + */ +export const ListNodeScepEnrollmentsResponseSchema: GenMessage = /*@__PURE__*/ + messageDesc(file_cryptos_fleet_v1_fleet, 153); + +/** + * @generated from message cryptos.fleet.v1.ApproveNodeScepEnrollmentRequest + */ +export type ApproveNodeScepEnrollmentRequest = Message<"cryptos.fleet.v1.ApproveNodeScepEnrollmentRequest"> & { + /** + * @generated from field: string node_name = 1; + */ + nodeName: string; + + /** + * @generated from field: string node_id = 2; + */ + nodeId: string; + + /** + * @generated from field: string id = 3; + */ + id: string; +}; + +/** + * Describes the message cryptos.fleet.v1.ApproveNodeScepEnrollmentRequest. + * Use `create(ApproveNodeScepEnrollmentRequestSchema)` to create a new message. + */ +export const ApproveNodeScepEnrollmentRequestSchema: GenMessage = /*@__PURE__*/ + messageDesc(file_cryptos_fleet_v1_fleet, 154); + +/** + * @generated from message cryptos.fleet.v1.ApproveNodeScepEnrollmentResponse + */ +export type ApproveNodeScepEnrollmentResponse = Message<"cryptos.fleet.v1.ApproveNodeScepEnrollmentResponse"> & { + /** + * enrollment is the approved enrolment, now out of the queue. + * + * @generated from field: cryptos.fleet.v1.NodeScepEnrollment enrollment = 1; + */ + enrollment?: NodeScepEnrollment | undefined; + + /** + * serial_hex is the serial of the issued certificate, which + * ListCertificates and RevokeCertificate know it by. + * + * @generated from field: string serial_hex = 2; + */ + serialHex: string; +}; + +/** + * Describes the message cryptos.fleet.v1.ApproveNodeScepEnrollmentResponse. + * Use `create(ApproveNodeScepEnrollmentResponseSchema)` to create a new message. + */ +export const ApproveNodeScepEnrollmentResponseSchema: GenMessage = /*@__PURE__*/ + messageDesc(file_cryptos_fleet_v1_fleet, 155); + +/** + * @generated from message cryptos.fleet.v1.RejectNodeScepEnrollmentRequest + */ +export type RejectNodeScepEnrollmentRequest = Message<"cryptos.fleet.v1.RejectNodeScepEnrollmentRequest"> & { + /** + * @generated from field: string node_name = 1; + */ + nodeName: string; + + /** + * @generated from field: string node_id = 2; + */ + nodeId: string; + + /** + * @generated from field: string id = 3; + */ + id: string; + + /** + * reason is recorded in the node's own audit log. It is not sent to the + * device, which RFC 8894 answers only with a failInfo code. + * + * @generated from field: string reason = 4; + */ + reason: string; +}; + +/** + * Describes the message cryptos.fleet.v1.RejectNodeScepEnrollmentRequest. + * Use `create(RejectNodeScepEnrollmentRequestSchema)` to create a new message. + */ +export const RejectNodeScepEnrollmentRequestSchema: GenMessage = /*@__PURE__*/ + messageDesc(file_cryptos_fleet_v1_fleet, 156); + +/** + * @generated from message cryptos.fleet.v1.RejectNodeScepEnrollmentResponse + */ +export type RejectNodeScepEnrollmentResponse = Message<"cryptos.fleet.v1.RejectNodeScepEnrollmentResponse"> & { + /** + * enrollment is the rejected enrolment, now out of the queue. + * + * @generated from field: cryptos.fleet.v1.NodeScepEnrollment enrollment = 1; + */ + enrollment?: NodeScepEnrollment | undefined; +}; + +/** + * Describes the message cryptos.fleet.v1.RejectNodeScepEnrollmentResponse. + * Use `create(RejectNodeScepEnrollmentResponseSchema)` to create a new message. + */ +export const RejectNodeScepEnrollmentResponseSchema: GenMessage = /*@__PURE__*/ + messageDesc(file_cryptos_fleet_v1_fleet, 157); /** * Health reports the manager's view of node reachability, independent of @@ -4960,39 +5480,60 @@ export const FleetService: GenService<{ output: typeof ListNodeTsaCertificatesResponseSchema; }, /** - * MintNodeScepChallenge mints a one-time SCEP challenge password on a - * managed node, for example to enroll a network device via its SCEP - * trustpoint. The password is returned once and is never written to the - * audit log. Operator-gated and audited (without the password). + * GetNodeImageStatus reports what CryptOS image a managed node is running, + * what it will boot next, and what it could roll back to. Readable at + * viewer level and above; a read, so it is not audited. * - * @generated from rpc cryptos.fleet.v1.FleetService.MintNodeScepChallenge + * @generated from rpc cryptos.fleet.v1.FleetService.GetNodeImageStatus */ - mintNodeScepChallenge: { + getNodeImageStatus: { methodKind: "unary"; - input: typeof MintNodeScepChallengeRequestSchema; - output: typeof MintNodeScepChallengeResponseSchema; + input: typeof GetNodeImageStatusRequestSchema; + output: typeof GetNodeImageStatusResponseSchema; }, /** - * ListNodeScepChallenges lists a managed node's usable SCEP challenges, - * soonest to expire first. Operator-gated; a read, so it is not audited. + * StageNodeImage installs a new CryptOS image on a managed node's spare ESP + * slot without touching the one it is running from. The manager fetches + * image_url itself (the browser never carries the image), checks the + * detached release signature, and streams it to the node the same way + * `cryptosctl image stage` does. The node will not boot it until + * ActivateNodeImage runs. Admin-gated (an unreviewed image on a trust + * anchor) and audited; the node's own refusals (a bad signature, or + * FailedPrecondition when another upgrade is already running) are + * surfaced unchanged. * - * @generated from rpc cryptos.fleet.v1.FleetService.ListNodeScepChallenges + * @generated from rpc cryptos.fleet.v1.FleetService.StageNodeImage */ - listNodeScepChallenges: { + stageNodeImage: { methodKind: "unary"; - input: typeof ListNodeScepChallengesRequestSchema; - output: typeof ListNodeScepChallengesResponseSchema; + input: typeof StageNodeImageRequestSchema; + output: typeof StageNodeImageResponseSchema; }, /** - * RevokeNodeScepChallenge withdraws a managed node's SCEP challenge before - * it is used or expires. Operator-gated and audited. + * ActivateNodeImage reboots a managed node so a staged image starts + * running. confirm_ca_cn must equal the node's current CA common name, the + * same confirmation RebootNode requires, because activating is itself a + * reboot. Admin-gated and audited. * - * @generated from rpc cryptos.fleet.v1.FleetService.RevokeNodeScepChallenge + * @generated from rpc cryptos.fleet.v1.FleetService.ActivateNodeImage */ - revokeNodeScepChallenge: { + activateNodeImage: { methodKind: "unary"; - input: typeof RevokeNodeScepChallengeRequestSchema; - output: typeof RevokeNodeScepChallengeResponseSchema; + input: typeof ActivateNodeImageRequestSchema; + output: typeof ActivateNodeImageResponseSchema; + }, + /** + * RollbackNodeImage puts a managed node's previously running image back on + * the boot path, for a node that was already activated onto a bad image. + * ActivateNodeImage (or a reboot) is still needed to actually boot it. + * Admin-gated and audited. + * + * @generated from rpc cryptos.fleet.v1.FleetService.RollbackNodeImage + */ + rollbackNodeImage: { + methodKind: "unary"; + input: typeof RollbackNodeImageRequestSchema; + output: typeof RollbackNodeImageResponseSchema; }, /** * IssueLeaf signs a leaf certificate on the named issuing node from a @@ -5479,6 +6020,54 @@ export const FleetService: GenService<{ input: typeof CancelCertificateRequestRequestSchema; output: typeof CancelCertificateRequestResponseSchema; }, + /** + * @generated from rpc cryptos.fleet.v1.FleetService.MintNodeScepChallenge + */ + mintNodeScepChallenge: { + methodKind: "unary"; + input: typeof MintNodeScepChallengeRequestSchema; + output: typeof MintNodeScepChallengeResponseSchema; + }, + /** + * @generated from rpc cryptos.fleet.v1.FleetService.ListNodeScepChallenges + */ + listNodeScepChallenges: { + methodKind: "unary"; + input: typeof ListNodeScepChallengesRequestSchema; + output: typeof ListNodeScepChallengesResponseSchema; + }, + /** + * @generated from rpc cryptos.fleet.v1.FleetService.RevokeNodeScepChallenge + */ + revokeNodeScepChallenge: { + methodKind: "unary"; + input: typeof RevokeNodeScepChallengeRequestSchema; + output: typeof RevokeNodeScepChallengeResponseSchema; + }, + /** + * @generated from rpc cryptos.fleet.v1.FleetService.ListNodeScepEnrollments + */ + listNodeScepEnrollments: { + methodKind: "unary"; + input: typeof ListNodeScepEnrollmentsRequestSchema; + output: typeof ListNodeScepEnrollmentsResponseSchema; + }, + /** + * @generated from rpc cryptos.fleet.v1.FleetService.ApproveNodeScepEnrollment + */ + approveNodeScepEnrollment: { + methodKind: "unary"; + input: typeof ApproveNodeScepEnrollmentRequestSchema; + output: typeof ApproveNodeScepEnrollmentResponseSchema; + }, + /** + * @generated from rpc cryptos.fleet.v1.FleetService.RejectNodeScepEnrollment + */ + rejectNodeScepEnrollment: { + methodKind: "unary"; + input: typeof RejectNodeScepEnrollmentRequestSchema; + output: typeof RejectNodeScepEnrollmentResponseSchema; + }, }> = /*@__PURE__*/ serviceDesc(file_cryptos_fleet_v1_fleet, 0);