@yorkie-js/sdk 0.7.5 → 0.7.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -5788,7 +5788,7 @@ function createGrpcWebTransport(options) {
5788
5788
  }
5789
5789
  };
5790
5790
  }
5791
- const file_src_api_yorkie_v1_resources = /* @__PURE__ */ fileDesc("CiFzcmMvYXBpL3lvcmtpZS92MS9yZXNvdXJjZXMucHJvdG8SCXlvcmtpZS52MSKuAQoIU25hcHNob3QSJAoEcm9vdBgBIAEoCzIWLnlvcmtpZS52MS5KU09ORWxlbWVudBI1CglwcmVzZW5jZXMYAiADKAsyIi55b3JraWUudjEuU25hcHNob3QuUHJlc2VuY2VzRW50cnkaRQoOUHJlc2VuY2VzRW50cnkSCwoDa2V5GAEgASgJEiIKBXZhbHVlGAIgASgLMhMueW9ya2llLnYxLlByZXNlbmNlOgI4ASL7AQoKQ2hhbmdlUGFjaxIUCgxkb2N1bWVudF9rZXkYASABKAkSKQoKY2hlY2twb2ludBgCIAEoCzIVLnlvcmtpZS52MS5DaGVja3BvaW50EhAKCHNuYXBzaG90GAMgASgMEiIKB2NoYW5nZXMYBCADKAsyES55b3JraWUudjEuQ2hhbmdlEjAKEW1pbl9zeW5jZWRfdGlja2V0GAUgASgLMhUueW9ya2llLnYxLlRpbWVUaWNrZXQSEgoKaXNfcmVtb3ZlZBgGIAEoCBIwCg52ZXJzaW9uX3ZlY3RvchgHIAEoCzIYLnlvcmtpZS52MS5WZXJzaW9uVmVjdG9yIpgBCgZDaGFuZ2USHwoCaWQYASABKAsyEy55b3JraWUudjEuQ2hhbmdlSUQSDwoHbWVzc2FnZRgCIAEoCRIoCgpvcGVyYXRpb25zGAMgAygLMhQueW9ya2llLnYxLk9wZXJhdGlvbhIyCg9wcmVzZW5jZV9jaGFuZ2UYBCABKAsyGS55b3JraWUudjEuUHJlc2VuY2VDaGFuZ2UihwEKCENoYW5nZUlEEhIKCmNsaWVudF9zZXEYASABKA0SEgoKc2VydmVyX3NlcRgCIAEoAxIPCgdsYW1wb3J0GAMgASgDEhAKCGFjdG9yX2lkGAQgASgMEjAKDnZlcnNpb25fdmVjdG9yGAUgASgLMhgueW9ya2llLnYxLlZlcnNpb25WZWN0b3IidAoNVmVyc2lvblZlY3RvchI0CgZ2ZWN0b3IYASADKAsyJC55b3JraWUudjEuVmVyc2lvblZlY3Rvci5WZWN0b3JFbnRyeRotCgtWZWN0b3JFbnRyeRILCgNrZXkYASABKAkSDQoFdmFsdWUYAiABKAM6AjgBItkaCglPcGVyYXRpb24SJwoDc2V0GAEgASgLMhgueW9ya2llLnYxLk9wZXJhdGlvbi5TZXRIABInCgNhZGQYAiABKAsyGC55b3JraWUudjEuT3BlcmF0aW9uLkFkZEgAEikKBG1vdmUYAyABKAsyGS55b3JraWUudjEuT3BlcmF0aW9uLk1vdmVIABItCgZyZW1vdmUYBCABKAsyGy55b3JraWUudjEuT3BlcmF0aW9uLlJlbW92ZUgAEikKBGVkaXQYBSABKAsyGS55b3JraWUudjEuT3BlcmF0aW9uLkVkaXRIABIrCgVzdHlsZRgHIAEoCzIaLnlvcmtpZS52MS5PcGVyYXRpb24uU3R5bGVIABIxCghpbmNyZWFzZRgIIAEoCzIdLnlvcmtpZS52MS5PcGVyYXRpb24uSW5jcmVhc2VIABIyCgl0cmVlX2VkaXQYCSABKAsyHS55b3JraWUudjEuT3BlcmF0aW9uLlRyZWVFZGl0SAASNAoKdHJlZV9zdHlsZRgKIAEoCzIeLnlvcmtpZS52MS5PcGVyYXRpb24uVHJlZVN0eWxlSAASMgoJYXJyYXlfc2V0GAsgASgLMh0ueW9ya2llLnYxLk9wZXJhdGlvbi5BcnJheVNldEgAGp0BCgNTZXQSMAoRcGFyZW50X2NyZWF0ZWRfYXQYASABKAsyFS55b3JraWUudjEuVGltZVRpY2tldBILCgNrZXkYAiABKAkSKwoFdmFsdWUYAyABKAsyHC55b3JraWUudjEuSlNPTkVsZW1lbnRTaW1wbGUSKgoLZXhlY3V0ZWRfYXQYBCABKAsyFS55b3JraWUudjEuVGltZVRpY2tldBrAAQoDQWRkEjAKEXBhcmVudF9jcmVhdGVkX2F0GAEgASgLMhUueW9ya2llLnYxLlRpbWVUaWNrZXQSLgoPcHJldl9jcmVhdGVkX2F0GAIgASgLMhUueW9ya2llLnYxLlRpbWVUaWNrZXQSKwoFdmFsdWUYAyABKAsyHC55b3JraWUudjEuSlNPTkVsZW1lbnRTaW1wbGUSKgoLZXhlY3V0ZWRfYXQYBCABKAsyFS55b3JraWUudjEuVGltZVRpY2tldBq/AQoETW92ZRIwChFwYXJlbnRfY3JlYXRlZF9hdBgBIAEoCzIVLnlvcmtpZS52MS5UaW1lVGlja2V0Ei4KD3ByZXZfY3JlYXRlZF9hdBgCIAEoCzIVLnlvcmtpZS52MS5UaW1lVGlja2V0EikKCmNyZWF0ZWRfYXQYAyABKAsyFS55b3JraWUudjEuVGltZVRpY2tldBIqCgtleGVjdXRlZF9hdBgEIAEoCzIVLnlvcmtpZS52MS5UaW1lVGlja2V0GpEBCgZSZW1vdmUSMAoRcGFyZW50X2NyZWF0ZWRfYXQYASABKAsyFS55b3JraWUudjEuVGltZVRpY2tldBIpCgpjcmVhdGVkX2F0GAIgASgLMhUueW9ya2llLnYxLlRpbWVUaWNrZXQSKgoLZXhlY3V0ZWRfYXQYAyABKAsyFS55b3JraWUudjEuVGltZVRpY2tldBrZAwoERWRpdBIwChFwYXJlbnRfY3JlYXRlZF9hdBgBIAEoCzIVLnlvcmtpZS52MS5UaW1lVGlja2V0EiQKBGZyb20YAiABKAsyFi55b3JraWUudjEuVGV4dE5vZGVQb3MSIgoCdG8YAyABKAsyFi55b3JraWUudjEuVGV4dE5vZGVQb3MSUwoXY3JlYXRlZF9hdF9tYXBfYnlfYWN0b3IYBCADKAsyMi55b3JraWUudjEuT3BlcmF0aW9uLkVkaXQuQ3JlYXRlZEF0TWFwQnlBY3RvckVudHJ5Eg8KB2NvbnRlbnQYBSABKAkSKgoLZXhlY3V0ZWRfYXQYBiABKAsyFS55b3JraWUudjEuVGltZVRpY2tldBI9CgphdHRyaWJ1dGVzGAcgAygLMikueW9ya2llLnYxLk9wZXJhdGlvbi5FZGl0LkF0dHJpYnV0ZXNFbnRyeRpRChhDcmVhdGVkQXRNYXBCeUFjdG9yRW50cnkSCwoDa2V5GAEgASgJEiQKBXZhbHVlGAIgASgLMhUueW9ya2llLnYxLlRpbWVUaWNrZXQ6AjgBGjEKD0F0dHJpYnV0ZXNFbnRyeRILCgNrZXkYASABKAkSDQoFdmFsdWUYAiABKAk6AjgBGukDCgVTdHlsZRIwChFwYXJlbnRfY3JlYXRlZF9hdBgBIAEoCzIVLnlvcmtpZS52MS5UaW1lVGlja2V0EiQKBGZyb20YAiABKAsyFi55b3JraWUudjEuVGV4dE5vZGVQb3MSIgoCdG8YAyABKAsyFi55b3JraWUudjEuVGV4dE5vZGVQb3MSPgoKYXR0cmlidXRlcxgEIAMoCzIqLnlvcmtpZS52MS5PcGVyYXRpb24uU3R5bGUuQXR0cmlidXRlc0VudHJ5EioKC2V4ZWN1dGVkX2F0GAUgASgLMhUueW9ya2llLnYxLlRpbWVUaWNrZXQSVAoXY3JlYXRlZF9hdF9tYXBfYnlfYWN0b3IYBiADKAsyMy55b3JraWUudjEuT3BlcmF0aW9uLlN0eWxlLkNyZWF0ZWRBdE1hcEJ5QWN0b3JFbnRyeRIcChRhdHRyaWJ1dGVzX3RvX3JlbW92ZRgHIAMoCRoxCg9BdHRyaWJ1dGVzRW50cnkSCwoDa2V5GAEgASgJEg0KBXZhbHVlGAIgASgJOgI4ARpRChhDcmVhdGVkQXRNYXBCeUFjdG9yRW50cnkSCwoDa2V5GAEgASgJEiQKBXZhbHVlGAIgASgLMhUueW9ya2llLnYxLlRpbWVUaWNrZXQ6AjgBGqQBCghJbmNyZWFzZRIwChFwYXJlbnRfY3JlYXRlZF9hdBgBIAEoCzIVLnlvcmtpZS52MS5UaW1lVGlja2V0EisKBXZhbHVlGAIgASgLMhwueW9ya2llLnYxLkpTT05FbGVtZW50U2ltcGxlEioKC2V4ZWN1dGVkX2F0GAMgASgLMhUueW9ya2llLnYxLlRpbWVUaWNrZXQSDQoFYWN0b3IYBCABKAkakwMKCFRyZWVFZGl0EjAKEXBhcmVudF9jcmVhdGVkX2F0GAEgASgLMhUueW9ya2llLnYxLlRpbWVUaWNrZXQSIAoEZnJvbRgCIAEoCzISLnlvcmtpZS52MS5UcmVlUG9zEh4KAnRvGAMgASgLMhIueW9ya2llLnYxLlRyZWVQb3MSVwoXY3JlYXRlZF9hdF9tYXBfYnlfYWN0b3IYBCADKAsyNi55b3JraWUudjEuT3BlcmF0aW9uLlRyZWVFZGl0LkNyZWF0ZWRBdE1hcEJ5QWN0b3JFbnRyeRImCghjb250ZW50cxgFIAMoCzIULnlvcmtpZS52MS5UcmVlTm9kZXMSEwoLc3BsaXRfbGV2ZWwYByABKAUSKgoLZXhlY3V0ZWRfYXQYBiABKAsyFS55b3JraWUudjEuVGltZVRpY2tldBpRChhDcmVhdGVkQXRNYXBCeUFjdG9yRW50cnkSCwoDa2V5GAEgASgJEiQKBXZhbHVlGAIgASgLMhUueW9ya2llLnYxLlRpbWVUaWNrZXQ6AjgBGu0DCglUcmVlU3R5bGUSMAoRcGFyZW50X2NyZWF0ZWRfYXQYASABKAsyFS55b3JraWUudjEuVGltZVRpY2tldBIgCgRmcm9tGAIgASgLMhIueW9ya2llLnYxLlRyZWVQb3MSHgoCdG8YAyABKAsyEi55b3JraWUudjEuVHJlZVBvcxJCCgphdHRyaWJ1dGVzGAQgAygLMi4ueW9ya2llLnYxLk9wZXJhdGlvbi5UcmVlU3R5bGUuQXR0cmlidXRlc0VudHJ5EioKC2V4ZWN1dGVkX2F0GAUgASgLMhUueW9ya2llLnYxLlRpbWVUaWNrZXQSHAoUYXR0cmlidXRlc190b19yZW1vdmUYBiADKAkSWAoXY3JlYXRlZF9hdF9tYXBfYnlfYWN0b3IYByADKAsyNy55b3JraWUudjEuT3BlcmF0aW9uLlRyZWVTdHlsZS5DcmVhdGVkQXRNYXBCeUFjdG9yRW50cnkaMQoPQXR0cmlidXRlc0VudHJ5EgsKA2tleRgBIAEoCRINCgV2YWx1ZRgCIAEoCToCOAEaUQoYQ3JlYXRlZEF0TWFwQnlBY3RvckVudHJ5EgsKA2tleRgBIAEoCRIkCgV2YWx1ZRgCIAEoCzIVLnlvcmtpZS52MS5UaW1lVGlja2V0OgI4ARrAAQoIQXJyYXlTZXQSMAoRcGFyZW50X2NyZWF0ZWRfYXQYASABKAsyFS55b3JraWUudjEuVGltZVRpY2tldBIpCgpjcmVhdGVkX2F0GAIgASgLMhUueW9ya2llLnYxLlRpbWVUaWNrZXQSKwoFdmFsdWUYAyABKAsyHC55b3JraWUudjEuSlNPTkVsZW1lbnRTaW1wbGUSKgoLZXhlY3V0ZWRfYXQYBCABKAsyFS55b3JraWUudjEuVGltZVRpY2tldEIGCgRib2R5IsUBChFKU09ORWxlbWVudFNpbXBsZRIpCgpjcmVhdGVkX2F0GAEgASgLMhUueW9ya2llLnYxLlRpbWVUaWNrZXQSJwoIbW92ZWRfYXQYAiABKAsyFS55b3JraWUudjEuVGltZVRpY2tldBIpCgpyZW1vdmVkX2F0GAMgASgLMhUueW9ya2llLnYxLlRpbWVUaWNrZXQSIgoEdHlwZRgEIAEoDjIULnlvcmtpZS52MS5WYWx1ZVR5cGUSDQoFdmFsdWUYBSABKAwinwsKC0pTT05FbGVtZW50EjgKC2pzb25fb2JqZWN0GAEgASgLMiEueW9ya2llLnYxLkpTT05FbGVtZW50LkpTT05PYmplY3RIABI2Cgpqc29uX2FycmF5GAIgASgLMiAueW9ya2llLnYxLkpTT05FbGVtZW50LkpTT05BcnJheUgAEjUKCXByaW1pdGl2ZRgDIAEoCzIgLnlvcmtpZS52MS5KU09ORWxlbWVudC5QcmltaXRpdmVIABIrCgR0ZXh0GAUgASgLMhsueW9ya2llLnYxLkpTT05FbGVtZW50LlRleHRIABIxCgdjb3VudGVyGAYgASgLMh4ueW9ya2llLnYxLkpTT05FbGVtZW50LkNvdW50ZXJIABIrCgR0cmVlGAcgASgLMhsueW9ya2llLnYxLkpTT05FbGVtZW50LlRyZWVIABquAQoKSlNPTk9iamVjdBIhCgVub2RlcxgBIAMoCzISLnlvcmtpZS52MS5SSFROb2RlEikKCmNyZWF0ZWRfYXQYAiABKAsyFS55b3JraWUudjEuVGltZVRpY2tldBInCghtb3ZlZF9hdBgDIAEoCzIVLnlvcmtpZS52MS5UaW1lVGlja2V0EikKCnJlbW92ZWRfYXQYBCABKAsyFS55b3JraWUudjEuVGltZVRpY2tldBqtAQoJSlNPTkFycmF5EiEKBW5vZGVzGAEgAygLMhIueW9ya2llLnYxLlJHQU5vZGUSKQoKY3JlYXRlZF9hdBgCIAEoCzIVLnlvcmtpZS52MS5UaW1lVGlja2V0EicKCG1vdmVkX2F0GAMgASgLMhUueW9ya2llLnYxLlRpbWVUaWNrZXQSKQoKcmVtb3ZlZF9hdBgEIAEoCzIVLnlvcmtpZS52MS5UaW1lVGlja2V0Gr0BCglQcmltaXRpdmUSIgoEdHlwZRgBIAEoDjIULnlvcmtpZS52MS5WYWx1ZVR5cGUSDQoFdmFsdWUYAiABKAwSKQoKY3JlYXRlZF9hdBgDIAEoCzIVLnlvcmtpZS52MS5UaW1lVGlja2V0EicKCG1vdmVkX2F0GAQgASgLMhUueW9ya2llLnYxLlRpbWVUaWNrZXQSKQoKcmVtb3ZlZF9hdBgFIAEoCzIVLnlvcmtpZS52MS5UaW1lVGlja2V0GqkBCgRUZXh0EiIKBW5vZGVzGAEgAygLMhMueW9ya2llLnYxLlRleHROb2RlEikKCmNyZWF0ZWRfYXQYAiABKAsyFS55b3JraWUudjEuVGltZVRpY2tldBInCghtb3ZlZF9hdBgDIAEoCzIVLnlvcmtpZS52MS5UaW1lVGlja2V0EikKCnJlbW92ZWRfYXQYBCABKAsyFS55b3JraWUudjEuVGltZVRpY2tldBrYAQoHQ291bnRlchIiCgR0eXBlGAEgASgOMhQueW9ya2llLnYxLlZhbHVlVHlwZRINCgV2YWx1ZRgCIAEoDBIpCgpjcmVhdGVkX2F0GAMgASgLMhUueW9ya2llLnYxLlRpbWVUaWNrZXQSJwoIbW92ZWRfYXQYBCABKAsyFS55b3JraWUudjEuVGltZVRpY2tldBIpCgpyZW1vdmVkX2F0GAUgASgLMhUueW9ya2llLnYxLlRpbWVUaWNrZXQSFQoNaGxsX3JlZ2lzdGVycxgHIAEoDEoECAYQBxqpAQoEVHJlZRIiCgVub2RlcxgBIAMoCzITLnlvcmtpZS52MS5UcmVlTm9kZRIpCgpjcmVhdGVkX2F0GAIgASgLMhUueW9ya2llLnYxLlRpbWVUaWNrZXQSJwoIbW92ZWRfYXQYAyABKAsyFS55b3JraWUudjEuVGltZVRpY2tldBIpCgpyZW1vdmVkX2F0GAQgASgLMhUueW9ya2llLnYxLlRpbWVUaWNrZXRCBgoEYm9keSI/CgdSSFROb2RlEgsKA2tleRgBIAEoCRInCgdlbGVtZW50GAIgASgLMhYueW9ya2llLnYxLkpTT05FbGVtZW50IlQKB1JHQU5vZGUSIAoEbmV4dBgBIAEoCzISLnlvcmtpZS52MS5SR0FOb2RlEicKB2VsZW1lbnQYAiABKAsyFi55b3JraWUudjEuSlNPTkVsZW1lbnQiWAoITm9kZUF0dHISDQoFdmFsdWUYASABKAkSKQoKdXBkYXRlZF9hdBgCIAEoCzIVLnlvcmtpZS52MS5UaW1lVGlja2V0EhIKCmlzX3JlbW92ZWQYAyABKAgilAIKCFRleHROb2RlEiEKAmlkGAEgASgLMhUueW9ya2llLnYxLlRleHROb2RlSUQSDQoFdmFsdWUYAiABKAkSKQoKcmVtb3ZlZF9hdBgDIAEoCzIVLnlvcmtpZS52MS5UaW1lVGlja2V0EioKC2luc19wcmV2X2lkGAQgASgLMhUueW9ya2llLnYxLlRleHROb2RlSUQSNwoKYXR0cmlidXRlcxgFIAMoCzIjLnlvcmtpZS52MS5UZXh0Tm9kZS5BdHRyaWJ1dGVzRW50cnkaRgoPQXR0cmlidXRlc0VudHJ5EgsKA2tleRgBIAEoCRIiCgV2YWx1ZRgCIAEoCzITLnlvcmtpZS52MS5Ob2RlQXR0cjoCOAEiRwoKVGV4dE5vZGVJRBIpCgpjcmVhdGVkX2F0GAEgASgLMhUueW9ya2llLnYxLlRpbWVUaWNrZXQSDgoGb2Zmc2V0GAIgASgFIrMDCghUcmVlTm9kZRIhCgJpZBgBIAEoCzIVLnlvcmtpZS52MS5UcmVlTm9kZUlEEgwKBHR5cGUYAiABKAkSDQoFdmFsdWUYAyABKAkSKQoKcmVtb3ZlZF9hdBgEIAEoCzIVLnlvcmtpZS52MS5UaW1lVGlja2V0EioKC2luc19wcmV2X2lkGAUgASgLMhUueW9ya2llLnYxLlRyZWVOb2RlSUQSKgoLaW5zX25leHRfaWQYBiABKAsyFS55b3JraWUudjEuVHJlZU5vZGVJRBINCgVkZXB0aBgHIAEoBRI3CgphdHRyaWJ1dGVzGAggAygLMiMueW9ya2llLnYxLlRyZWVOb2RlLkF0dHJpYnV0ZXNFbnRyeRIqCgttZXJnZWRfZnJvbRgJIAEoCzIVLnlvcmtpZS52MS5UcmVlTm9kZUlEEigKCW1lcmdlZF9hdBgKIAEoCzIVLnlvcmtpZS52MS5UaW1lVGlja2V0GkYKD0F0dHJpYnV0ZXNFbnRyeRILCgNrZXkYASABKAkSIgoFdmFsdWUYAiABKAsyEy55b3JraWUudjEuTm9kZUF0dHI6AjgBIjEKCVRyZWVOb2RlcxIkCgdjb250ZW50GAEgAygLMhMueW9ya2llLnYxLlRyZWVOb2RlIkcKClRyZWVOb2RlSUQSKQoKY3JlYXRlZF9hdBgBIAEoCzIVLnlvcmtpZS52MS5UaW1lVGlja2V0Eg4KBm9mZnNldBgCIAEoBSJjCgdUcmVlUG9zEigKCXBhcmVudF9pZBgBIAEoCzIVLnlvcmtpZS52MS5UcmVlTm9kZUlEEi4KD2xlZnRfc2libGluZ19pZBgCIAEoCzIVLnlvcmtpZS52MS5UcmVlTm9kZUlEImsKBFVzZXISCgoCaWQYASABKAkSFQoNYXV0aF9wcm92aWRlchgCIAEoCRIQCgh1c2VybmFtZRgDIAEoCRIuCgpjcmVhdGVkX2F0GAQgASgLMhouZ29vZ2xlLnByb3RvYnVmLlRpbWVzdGFtcCKJAQoGTWVtYmVyEgoKAmlkGAEgASgJEhIKCnByb2plY3RfaWQYAiABKAkSDwoHdXNlcl9pZBgDIAEoCRIQCgh1c2VybmFtZRgEIAEoCRIMCgRyb2xlGAUgASgJEi4KCmludml0ZWRfYXQYBiABKAsyGi5nb29nbGUucHJvdG9idWYuVGltZXN0YW1wIukGCgdQcm9qZWN0EgoKAmlkGAEgASgJEgwKBG5hbWUYAiABKAkSEgoKcHVibGljX2tleRgDIAEoCRISCgpzZWNyZXRfa2V5GAQgASgJEhgKEGF1dGhfd2ViaG9va191cmwYBSABKAkSHAoUYXV0aF93ZWJob29rX21ldGhvZHMYBiADKAkSIAoYYXV0aF93ZWJob29rX21heF9yZXRyaWVzGBEgASgEEiYKHmF1dGhfd2ViaG9va19taW5fd2FpdF9pbnRlcnZhbBgSIAEoCRImCh5hdXRoX3dlYmhvb2tfbWF4X3dhaXRfaW50ZXJ2YWwYEyABKAkSJAocYXV0aF93ZWJob29rX3JlcXVlc3RfdGltZW91dBgUIAEoCRIZChFldmVudF93ZWJob29rX3VybBgHIAEoCRIcChRldmVudF93ZWJob29rX2V2ZW50cxgIIAMoCRIhChlldmVudF93ZWJob29rX21heF9yZXRyaWVzGBUgASgEEicKH2V2ZW50X3dlYmhvb2tfbWluX3dhaXRfaW50ZXJ2YWwYFiABKAkSJwofZXZlbnRfd2ViaG9va19tYXhfd2FpdF9pbnRlcnZhbBgXIAEoCRIlCh1ldmVudF93ZWJob29rX3JlcXVlc3RfdGltZW91dBgYIAEoCRIjChtjbGllbnRfZGVhY3RpdmF0ZV90aHJlc2hvbGQYCSABKAkSGgoSc25hcHNob3RfdGhyZXNob2xkGBkgASgDEhkKEXNuYXBzaG90X2ludGVydmFsGBogASgDEiQKHG1heF9zdWJzY3JpYmVyc19wZXJfZG9jdW1lbnQYCiABKAUSJAocbWF4X2F0dGFjaG1lbnRzX3Blcl9kb2N1bWVudBgLIAEoBRIdChVtYXhfc2l6ZV9wZXJfZG9jdW1lbnQYDyABKAUSGAoQcmVtb3ZlX29uX2RldGFjaBgQIAEoCBIdChVhdXRvX3JldmlzaW9uX2VuYWJsZWQYGyABKAgSFwoPYWxsb3dlZF9vcmlnaW5zGA4gAygJEi4KCmNyZWF0ZWRfYXQYDCABKAsyGi5nb29nbGUucHJvdG9idWYuVGltZXN0YW1wEi4KCnVwZGF0ZWRfYXQYDSABKAsyGi5nb29nbGUucHJvdG9idWYuVGltZXN0YW1wIi8KC01ldHJpY1BvaW50EhEKCXRpbWVzdGFtcBgBIAEoAxINCgV2YWx1ZRgCIAEoBSKjDAoWVXBkYXRhYmxlUHJvamVjdEZpZWxkcxIqCgRuYW1lGAEgASgLMhwuZ29vZ2xlLnByb3RvYnVmLlN0cmluZ1ZhbHVlEjYKEGF1dGhfd2ViaG9va191cmwYAiABKAsyHC5nb29nbGUucHJvdG9idWYuU3RyaW5nVmFsdWUSUgoUYXV0aF93ZWJob29rX21ldGhvZHMYAyABKAsyNC55b3JraWUudjEuVXBkYXRhYmxlUHJvamVjdEZpZWxkcy5BdXRoV2ViaG9va01ldGhvZHMSPgoYYXV0aF93ZWJob29rX21heF9yZXRyaWVzGAwgASgLMhwuZ29vZ2xlLnByb3RvYnVmLlVJbnQ2NFZhbHVlEkQKHmF1dGhfd2ViaG9va19taW5fd2FpdF9pbnRlcnZhbBgNIAEoCzIcLmdvb2dsZS5wcm90b2J1Zi5TdHJpbmdWYWx1ZRJECh5hdXRoX3dlYmhvb2tfbWF4X3dhaXRfaW50ZXJ2YWwYDiABKAsyHC5nb29nbGUucHJvdG9idWYuU3RyaW5nVmFsdWUSQgocYXV0aF93ZWJob29rX3JlcXVlc3RfdGltZW91dBgPIAEoCzIcLmdvb2dsZS5wcm90b2J1Zi5TdHJpbmdWYWx1ZRI3ChFldmVudF93ZWJob29rX3VybBgEIAEoCzIcLmdvb2dsZS5wcm90b2J1Zi5TdHJpbmdWYWx1ZRJSChRldmVudF93ZWJob29rX2V2ZW50cxgFIAEoCzI0LnlvcmtpZS52MS5VcGRhdGFibGVQcm9qZWN0RmllbGRzLkV2ZW50V2ViaG9va0V2ZW50cxI/ChlldmVudF93ZWJob29rX21heF9yZXRyaWVzGBAgASgLMhwuZ29vZ2xlLnByb3RvYnVmLlVJbnQ2NFZhbHVlEkUKH2V2ZW50X3dlYmhvb2tfbWluX3dhaXRfaW50ZXJ2YWwYESABKAsyHC5nb29nbGUucHJvdG9idWYuU3RyaW5nVmFsdWUSRQofZXZlbnRfd2ViaG9va19tYXhfd2FpdF9pbnRlcnZhbBgSIAEoCzIcLmdvb2dsZS5wcm90b2J1Zi5TdHJpbmdWYWx1ZRJDCh1ldmVudF93ZWJob29rX3JlcXVlc3RfdGltZW91dBgTIAEoCzIcLmdvb2dsZS5wcm90b2J1Zi5TdHJpbmdWYWx1ZRI3ChJzbmFwc2hvdF90aHJlc2hvbGQYFCABKAsyGy5nb29nbGUucHJvdG9idWYuSW50NjRWYWx1ZRI2ChFzbmFwc2hvdF9pbnRlcnZhbBgVIAEoCzIbLmdvb2dsZS5wcm90b2J1Zi5JbnQ2NFZhbHVlEkEKG2NsaWVudF9kZWFjdGl2YXRlX3RocmVzaG9sZBgGIAEoCzIcLmdvb2dsZS5wcm90b2J1Zi5TdHJpbmdWYWx1ZRJBChxtYXhfc3Vic2NyaWJlcnNfcGVyX2RvY3VtZW50GAcgASgLMhsuZ29vZ2xlLnByb3RvYnVmLkludDMyVmFsdWUSQQocbWF4X2F0dGFjaG1lbnRzX3Blcl9kb2N1bWVudBgIIAEoCzIbLmdvb2dsZS5wcm90b2J1Zi5JbnQzMlZhbHVlEjoKFW1heF9zaXplX3Blcl9kb2N1bWVudBgKIAEoCzIbLmdvb2dsZS5wcm90b2J1Zi5JbnQzMlZhbHVlEjQKEHJlbW92ZV9vbl9kZXRhY2gYCyABKAsyGi5nb29nbGUucHJvdG9idWYuQm9vbFZhbHVlEjkKFWF1dG9fcmV2aXNpb25fZW5hYmxlZBgWIAEoCzIaLmdvb2dsZS5wcm90b2J1Zi5Cb29sVmFsdWUSSQoPYWxsb3dlZF9vcmlnaW5zGAkgASgLMjAueW9ya2llLnYxLlVwZGF0YWJsZVByb2plY3RGaWVsZHMuQWxsb3dlZE9yaWdpbnMaJQoSQXV0aFdlYmhvb2tNZXRob2RzEg8KB21ldGhvZHMYASADKAkaJAoSRXZlbnRXZWJob29rRXZlbnRzEg4KBmV2ZW50cxgBIAMoCRohCg5BbGxvd2VkT3JpZ2lucxIPCgdvcmlnaW5zGAEgAygJIqcDCg9Eb2N1bWVudFN1bW1hcnkSCgoCaWQYASABKAkSCwoDa2V5GAIgASgJEgwKBHJvb3QYAyABKAkSGAoQYXR0YWNoZWRfY2xpZW50cxgHIAEoBRIpCg1kb2N1bWVudF9zaXplGAggASgLMhIueW9ya2llLnYxLkRvY1NpemUSEgoKc2NoZW1hX2tleRgJIAEoCRI8CglwcmVzZW5jZXMYCiADKAsyKS55b3JraWUudjEuRG9jdW1lbnRTdW1tYXJ5LlByZXNlbmNlc0VudHJ5Ei4KCmNyZWF0ZWRfYXQYBCABKAsyGi5nb29nbGUucHJvdG9idWYuVGltZXN0YW1wEi8KC2FjY2Vzc2VkX2F0GAUgASgLMhouZ29vZ2xlLnByb3RvYnVmLlRpbWVzdGFtcBIuCgp1cGRhdGVkX2F0GAYgASgLMhouZ29vZ2xlLnByb3RvYnVmLlRpbWVzdGFtcBpFCg5QcmVzZW5jZXNFbnRyeRILCgNrZXkYASABKAkSIgoFdmFsdWUYAiABKAsyEy55b3JraWUudjEuUHJlc2VuY2U6AjgBItoBCg5QcmVzZW5jZUNoYW5nZRIyCgR0eXBlGAEgASgOMiQueW9ya2llLnYxLlByZXNlbmNlQ2hhbmdlLkNoYW5nZVR5cGUSJQoIcHJlc2VuY2UYAiABKAsyEy55b3JraWUudjEuUHJlc2VuY2UibQoKQ2hhbmdlVHlwZRIbChdDSEFOR0VfVFlQRV9VTlNQRUNJRklFRBAAEhMKD0NIQU5HRV9UWVBFX1BVVBABEhYKEkNIQU5HRV9UWVBFX0RFTEVURRACEhUKEUNIQU5HRV9UWVBFX0NMRUFSEAMiZAoIUHJlc2VuY2USKwoEZGF0YRgBIAMoCzIdLnlvcmtpZS52MS5QcmVzZW5jZS5EYXRhRW50cnkaKwoJRGF0YUVudHJ5EgsKA2tleRgBIAEoCRINCgV2YWx1ZRgCIAEoCToCOAEiNAoOQ2hhbm5lbFN1bW1hcnkSCwoDa2V5GAEgASgJEhUKDXNlc3Npb25fY291bnQYAiABKAUiNAoKQ2hlY2twb2ludBISCgpzZXJ2ZXJfc2VxGAEgASgDEhIKCmNsaWVudF9zZXEYAiABKA0iYQoLVGV4dE5vZGVQb3MSKQoKY3JlYXRlZF9hdBgBIAEoCzIVLnlvcmtpZS52MS5UaW1lVGlja2V0Eg4KBm9mZnNldBgCIAEoBRIXCg9yZWxhdGl2ZV9vZmZzZXQYAyABKAUiQgoKVGltZVRpY2tldBIPCgdsYW1wb3J0GAEgASgDEhEKCWRlbGltaXRlchgCIAEoDRIQCghhY3Rvcl9pZBgDIAEoDCIuCgxEb2NFdmVudEJvZHkSDQoFdG9waWMYASABKAkSDwoHcGF5bG9hZBgCIAEoDCJrCghEb2NFdmVudBIlCgR0eXBlGAEgASgOMhcueW9ya2llLnYxLkRvY0V2ZW50VHlwZRIRCglwdWJsaXNoZXIYAiABKAkSJQoEYm9keRgDIAEoCzIXLnlvcmtpZS52MS5Eb2NFdmVudEJvZHki1gEKDENoYW5uZWxFdmVudBIqCgR0eXBlGAEgASgOMhwueW9ya2llLnYxLkNoYW5uZWxFdmVudC5UeXBlEhEKCXB1Ymxpc2hlchgCIAEoCRIVCg1zZXNzaW9uX2NvdW50GAMgASgDEgsKA3NlcRgEIAEoAxINCgV0b3BpYxgFIAEoCRIPCgdwYXlsb2FkGAYgASgMIkMKBFR5cGUSFAoQVFlQRV9VTlNQRUNJRklFRBAAEhEKDVRZUEVfUFJFU0VOQ0UQARISCg5UWVBFX0JST0FEQ0FTVBACIiYKCERhdGFTaXplEgwKBGRhdGEYASABKAUSDAoEbWV0YRgCIAEoBSJNCgdEb2NTaXplEiEKBGxpdmUYASABKAsyEy55b3JraWUudjEuRGF0YVNpemUSHwoCZ2MYAiABKAsyEy55b3JraWUudjEuRGF0YVNpemUikQEKBlNjaGVtYRIKCgJpZBgBIAEoCRIMCgRuYW1lGAIgASgJEg8KB3ZlcnNpb24YAyABKAUSDAoEYm9keRgEIAEoCRIeCgVydWxlcxgFIAMoCzIPLnlvcmtpZS52MS5SdWxlEi4KCmNyZWF0ZWRfYXQYBiABKAsyGi5nb29nbGUucHJvdG9idWYuVGltZXN0YW1wIlAKDFRyZWVOb2RlUnVsZRIRCglub2RlX3R5cGUYASABKAkSDwoHY29udGVudBgCIAEoCRINCgVtYXJrcxgDIAEoCRINCgVncm91cBgEIAEoCSJPCgRSdWxlEgwKBHBhdGgYASABKAkSDAoEdHlwZRgCIAEoCRIrCgp0cmVlX25vZGVzGAMgAygLMhcueW9ya2llLnYxLlRyZWVOb2RlUnVsZSKDAQoPUmV2aXNpb25TdW1tYXJ5EgoKAmlkGAEgASgJEg0KBWxhYmVsGAIgASgJEhMKC2Rlc2NyaXB0aW9uGAMgASgJEhAKCHNuYXBzaG90GAQgASgJEi4KCmNyZWF0ZWRfYXQYBSABKAsyGi5nb29nbGUucHJvdG9idWYuVGltZXN0YW1wKvwCCglWYWx1ZVR5cGUSEwoPVkFMVUVfVFlQRV9OVUxMEAASFgoSVkFMVUVfVFlQRV9CT09MRUFOEAESFgoSVkFMVUVfVFlQRV9JTlRFR0VSEAISEwoPVkFMVUVfVFlQRV9MT05HEAMSFQoRVkFMVUVfVFlQRV9ET1VCTEUQBBIVChFWQUxVRV9UWVBFX1NUUklORxAFEhQKEFZBTFVFX1RZUEVfQllURVMQBhITCg9WQUxVRV9UWVBFX0RBVEUQBxIaChZWQUxVRV9UWVBFX0pTT05fT0JKRUNUEAgSGQoVVkFMVUVfVFlQRV9KU09OX0FSUkFZEAkSEwoPVkFMVUVfVFlQRV9URVhUEAoSGgoWVkFMVUVfVFlQRV9JTlRFR0VSX0NOVBALEhcKE1ZBTFVFX1RZUEVfTE9OR19DTlQQDBITCg9WQUxVRV9UWVBFX1RSRUUQDRIgChxWQUxVRV9UWVBFX0lOVEVHRVJfREVEVVBfQ05UEA4iBAgPEA8qpgEKDERvY0V2ZW50VHlwZRIjCh9ET0NfRVZFTlRfVFlQRV9ET0NVTUVOVF9DSEFOR0VEEAASIwofRE9DX0VWRU5UX1RZUEVfRE9DVU1FTlRfV0FUQ0hFRBABEiUKIURPQ19FVkVOVF9UWVBFX0RPQ1VNRU5UX1VOV0FUQ0hFRBACEiUKIURPQ19FVkVOVF9UWVBFX0RPQ1VNRU5UX0JST0FEQ0FTVBADQkUKEWRldi55b3JraWUuYXBpLnYxUAFaLmdpdGh1Yi5jb20veW9ya2llLXRlYW0veW9ya2llL2FwaS95b3JraWUvdjE7djFiBnByb3RvMw", [file_google_protobuf_timestamp, file_google_protobuf_wrappers]);
5791
+ const file_src_api_yorkie_v1_resources = /* @__PURE__ */ fileDesc("CiFzcmMvYXBpL3lvcmtpZS92MS9yZXNvdXJjZXMucHJvdG8SCXlvcmtpZS52MSKuAQoIU25hcHNob3QSJAoEcm9vdBgBIAEoCzIWLnlvcmtpZS52MS5KU09ORWxlbWVudBI1CglwcmVzZW5jZXMYAiADKAsyIi55b3JraWUudjEuU25hcHNob3QuUHJlc2VuY2VzRW50cnkaRQoOUHJlc2VuY2VzRW50cnkSCwoDa2V5GAEgASgJEiIKBXZhbHVlGAIgASgLMhMueW9ya2llLnYxLlByZXNlbmNlOgI4ASL7AQoKQ2hhbmdlUGFjaxIUCgxkb2N1bWVudF9rZXkYASABKAkSKQoKY2hlY2twb2ludBgCIAEoCzIVLnlvcmtpZS52MS5DaGVja3BvaW50EhAKCHNuYXBzaG90GAMgASgMEiIKB2NoYW5nZXMYBCADKAsyES55b3JraWUudjEuQ2hhbmdlEjAKEW1pbl9zeW5jZWRfdGlja2V0GAUgASgLMhUueW9ya2llLnYxLlRpbWVUaWNrZXQSEgoKaXNfcmVtb3ZlZBgGIAEoCBIwCg52ZXJzaW9uX3ZlY3RvchgHIAEoCzIYLnlvcmtpZS52MS5WZXJzaW9uVmVjdG9yIpgBCgZDaGFuZ2USHwoCaWQYASABKAsyEy55b3JraWUudjEuQ2hhbmdlSUQSDwoHbWVzc2FnZRgCIAEoCRIoCgpvcGVyYXRpb25zGAMgAygLMhQueW9ya2llLnYxLk9wZXJhdGlvbhIyCg9wcmVzZW5jZV9jaGFuZ2UYBCABKAsyGS55b3JraWUudjEuUHJlc2VuY2VDaGFuZ2UihwEKCENoYW5nZUlEEhIKCmNsaWVudF9zZXEYASABKA0SEgoKc2VydmVyX3NlcRgCIAEoAxIPCgdsYW1wb3J0GAMgASgDEhAKCGFjdG9yX2lkGAQgASgMEjAKDnZlcnNpb25fdmVjdG9yGAUgASgLMhgueW9ya2llLnYxLlZlcnNpb25WZWN0b3IidAoNVmVyc2lvblZlY3RvchI0CgZ2ZWN0b3IYASADKAsyJC55b3JraWUudjEuVmVyc2lvblZlY3Rvci5WZWN0b3JFbnRyeRotCgtWZWN0b3JFbnRyeRILCgNrZXkYASABKAkSDQoFdmFsdWUYAiABKAM6AjgBItkaCglPcGVyYXRpb24SJwoDc2V0GAEgASgLMhgueW9ya2llLnYxLk9wZXJhdGlvbi5TZXRIABInCgNhZGQYAiABKAsyGC55b3JraWUudjEuT3BlcmF0aW9uLkFkZEgAEikKBG1vdmUYAyABKAsyGS55b3JraWUudjEuT3BlcmF0aW9uLk1vdmVIABItCgZyZW1vdmUYBCABKAsyGy55b3JraWUudjEuT3BlcmF0aW9uLlJlbW92ZUgAEikKBGVkaXQYBSABKAsyGS55b3JraWUudjEuT3BlcmF0aW9uLkVkaXRIABIrCgVzdHlsZRgHIAEoCzIaLnlvcmtpZS52MS5PcGVyYXRpb24uU3R5bGVIABIxCghpbmNyZWFzZRgIIAEoCzIdLnlvcmtpZS52MS5PcGVyYXRpb24uSW5jcmVhc2VIABIyCgl0cmVlX2VkaXQYCSABKAsyHS55b3JraWUudjEuT3BlcmF0aW9uLlRyZWVFZGl0SAASNAoKdHJlZV9zdHlsZRgKIAEoCzIeLnlvcmtpZS52MS5PcGVyYXRpb24uVHJlZVN0eWxlSAASMgoJYXJyYXlfc2V0GAsgASgLMh0ueW9ya2llLnYxLk9wZXJhdGlvbi5BcnJheVNldEgAGp0BCgNTZXQSMAoRcGFyZW50X2NyZWF0ZWRfYXQYASABKAsyFS55b3JraWUudjEuVGltZVRpY2tldBILCgNrZXkYAiABKAkSKwoFdmFsdWUYAyABKAsyHC55b3JraWUudjEuSlNPTkVsZW1lbnRTaW1wbGUSKgoLZXhlY3V0ZWRfYXQYBCABKAsyFS55b3JraWUudjEuVGltZVRpY2tldBrAAQoDQWRkEjAKEXBhcmVudF9jcmVhdGVkX2F0GAEgASgLMhUueW9ya2llLnYxLlRpbWVUaWNrZXQSLgoPcHJldl9jcmVhdGVkX2F0GAIgASgLMhUueW9ya2llLnYxLlRpbWVUaWNrZXQSKwoFdmFsdWUYAyABKAsyHC55b3JraWUudjEuSlNPTkVsZW1lbnRTaW1wbGUSKgoLZXhlY3V0ZWRfYXQYBCABKAsyFS55b3JraWUudjEuVGltZVRpY2tldBq/AQoETW92ZRIwChFwYXJlbnRfY3JlYXRlZF9hdBgBIAEoCzIVLnlvcmtpZS52MS5UaW1lVGlja2V0Ei4KD3ByZXZfY3JlYXRlZF9hdBgCIAEoCzIVLnlvcmtpZS52MS5UaW1lVGlja2V0EikKCmNyZWF0ZWRfYXQYAyABKAsyFS55b3JraWUudjEuVGltZVRpY2tldBIqCgtleGVjdXRlZF9hdBgEIAEoCzIVLnlvcmtpZS52MS5UaW1lVGlja2V0GpEBCgZSZW1vdmUSMAoRcGFyZW50X2NyZWF0ZWRfYXQYASABKAsyFS55b3JraWUudjEuVGltZVRpY2tldBIpCgpjcmVhdGVkX2F0GAIgASgLMhUueW9ya2llLnYxLlRpbWVUaWNrZXQSKgoLZXhlY3V0ZWRfYXQYAyABKAsyFS55b3JraWUudjEuVGltZVRpY2tldBrZAwoERWRpdBIwChFwYXJlbnRfY3JlYXRlZF9hdBgBIAEoCzIVLnlvcmtpZS52MS5UaW1lVGlja2V0EiQKBGZyb20YAiABKAsyFi55b3JraWUudjEuVGV4dE5vZGVQb3MSIgoCdG8YAyABKAsyFi55b3JraWUudjEuVGV4dE5vZGVQb3MSUwoXY3JlYXRlZF9hdF9tYXBfYnlfYWN0b3IYBCADKAsyMi55b3JraWUudjEuT3BlcmF0aW9uLkVkaXQuQ3JlYXRlZEF0TWFwQnlBY3RvckVudHJ5Eg8KB2NvbnRlbnQYBSABKAkSKgoLZXhlY3V0ZWRfYXQYBiABKAsyFS55b3JraWUudjEuVGltZVRpY2tldBI9CgphdHRyaWJ1dGVzGAcgAygLMikueW9ya2llLnYxLk9wZXJhdGlvbi5FZGl0LkF0dHJpYnV0ZXNFbnRyeRpRChhDcmVhdGVkQXRNYXBCeUFjdG9yRW50cnkSCwoDa2V5GAEgASgJEiQKBXZhbHVlGAIgASgLMhUueW9ya2llLnYxLlRpbWVUaWNrZXQ6AjgBGjEKD0F0dHJpYnV0ZXNFbnRyeRILCgNrZXkYASABKAkSDQoFdmFsdWUYAiABKAk6AjgBGukDCgVTdHlsZRIwChFwYXJlbnRfY3JlYXRlZF9hdBgBIAEoCzIVLnlvcmtpZS52MS5UaW1lVGlja2V0EiQKBGZyb20YAiABKAsyFi55b3JraWUudjEuVGV4dE5vZGVQb3MSIgoCdG8YAyABKAsyFi55b3JraWUudjEuVGV4dE5vZGVQb3MSPgoKYXR0cmlidXRlcxgEIAMoCzIqLnlvcmtpZS52MS5PcGVyYXRpb24uU3R5bGUuQXR0cmlidXRlc0VudHJ5EioKC2V4ZWN1dGVkX2F0GAUgASgLMhUueW9ya2llLnYxLlRpbWVUaWNrZXQSVAoXY3JlYXRlZF9hdF9tYXBfYnlfYWN0b3IYBiADKAsyMy55b3JraWUudjEuT3BlcmF0aW9uLlN0eWxlLkNyZWF0ZWRBdE1hcEJ5QWN0b3JFbnRyeRIcChRhdHRyaWJ1dGVzX3RvX3JlbW92ZRgHIAMoCRoxCg9BdHRyaWJ1dGVzRW50cnkSCwoDa2V5GAEgASgJEg0KBXZhbHVlGAIgASgJOgI4ARpRChhDcmVhdGVkQXRNYXBCeUFjdG9yRW50cnkSCwoDa2V5GAEgASgJEiQKBXZhbHVlGAIgASgLMhUueW9ya2llLnYxLlRpbWVUaWNrZXQ6AjgBGqQBCghJbmNyZWFzZRIwChFwYXJlbnRfY3JlYXRlZF9hdBgBIAEoCzIVLnlvcmtpZS52MS5UaW1lVGlja2V0EisKBXZhbHVlGAIgASgLMhwueW9ya2llLnYxLkpTT05FbGVtZW50U2ltcGxlEioKC2V4ZWN1dGVkX2F0GAMgASgLMhUueW9ya2llLnYxLlRpbWVUaWNrZXQSDQoFYWN0b3IYBCABKAkakwMKCFRyZWVFZGl0EjAKEXBhcmVudF9jcmVhdGVkX2F0GAEgASgLMhUueW9ya2llLnYxLlRpbWVUaWNrZXQSIAoEZnJvbRgCIAEoCzISLnlvcmtpZS52MS5UcmVlUG9zEh4KAnRvGAMgASgLMhIueW9ya2llLnYxLlRyZWVQb3MSVwoXY3JlYXRlZF9hdF9tYXBfYnlfYWN0b3IYBCADKAsyNi55b3JraWUudjEuT3BlcmF0aW9uLlRyZWVFZGl0LkNyZWF0ZWRBdE1hcEJ5QWN0b3JFbnRyeRImCghjb250ZW50cxgFIAMoCzIULnlvcmtpZS52MS5UcmVlTm9kZXMSEwoLc3BsaXRfbGV2ZWwYByABKAUSKgoLZXhlY3V0ZWRfYXQYBiABKAsyFS55b3JraWUudjEuVGltZVRpY2tldBpRChhDcmVhdGVkQXRNYXBCeUFjdG9yRW50cnkSCwoDa2V5GAEgASgJEiQKBXZhbHVlGAIgASgLMhUueW9ya2llLnYxLlRpbWVUaWNrZXQ6AjgBGu0DCglUcmVlU3R5bGUSMAoRcGFyZW50X2NyZWF0ZWRfYXQYASABKAsyFS55b3JraWUudjEuVGltZVRpY2tldBIgCgRmcm9tGAIgASgLMhIueW9ya2llLnYxLlRyZWVQb3MSHgoCdG8YAyABKAsyEi55b3JraWUudjEuVHJlZVBvcxJCCgphdHRyaWJ1dGVzGAQgAygLMi4ueW9ya2llLnYxLk9wZXJhdGlvbi5UcmVlU3R5bGUuQXR0cmlidXRlc0VudHJ5EioKC2V4ZWN1dGVkX2F0GAUgASgLMhUueW9ya2llLnYxLlRpbWVUaWNrZXQSHAoUYXR0cmlidXRlc190b19yZW1vdmUYBiADKAkSWAoXY3JlYXRlZF9hdF9tYXBfYnlfYWN0b3IYByADKAsyNy55b3JraWUudjEuT3BlcmF0aW9uLlRyZWVTdHlsZS5DcmVhdGVkQXRNYXBCeUFjdG9yRW50cnkaMQoPQXR0cmlidXRlc0VudHJ5EgsKA2tleRgBIAEoCRINCgV2YWx1ZRgCIAEoCToCOAEaUQoYQ3JlYXRlZEF0TWFwQnlBY3RvckVudHJ5EgsKA2tleRgBIAEoCRIkCgV2YWx1ZRgCIAEoCzIVLnlvcmtpZS52MS5UaW1lVGlja2V0OgI4ARrAAQoIQXJyYXlTZXQSMAoRcGFyZW50X2NyZWF0ZWRfYXQYASABKAsyFS55b3JraWUudjEuVGltZVRpY2tldBIpCgpjcmVhdGVkX2F0GAIgASgLMhUueW9ya2llLnYxLlRpbWVUaWNrZXQSKwoFdmFsdWUYAyABKAsyHC55b3JraWUudjEuSlNPTkVsZW1lbnRTaW1wbGUSKgoLZXhlY3V0ZWRfYXQYBCABKAsyFS55b3JraWUudjEuVGltZVRpY2tldEIGCgRib2R5IsUBChFKU09ORWxlbWVudFNpbXBsZRIpCgpjcmVhdGVkX2F0GAEgASgLMhUueW9ya2llLnYxLlRpbWVUaWNrZXQSJwoIbW92ZWRfYXQYAiABKAsyFS55b3JraWUudjEuVGltZVRpY2tldBIpCgpyZW1vdmVkX2F0GAMgASgLMhUueW9ya2llLnYxLlRpbWVUaWNrZXQSIgoEdHlwZRgEIAEoDjIULnlvcmtpZS52MS5WYWx1ZVR5cGUSDQoFdmFsdWUYBSABKAwinwsKC0pTT05FbGVtZW50EjgKC2pzb25fb2JqZWN0GAEgASgLMiEueW9ya2llLnYxLkpTT05FbGVtZW50LkpTT05PYmplY3RIABI2Cgpqc29uX2FycmF5GAIgASgLMiAueW9ya2llLnYxLkpTT05FbGVtZW50LkpTT05BcnJheUgAEjUKCXByaW1pdGl2ZRgDIAEoCzIgLnlvcmtpZS52MS5KU09ORWxlbWVudC5QcmltaXRpdmVIABIrCgR0ZXh0GAUgASgLMhsueW9ya2llLnYxLkpTT05FbGVtZW50LlRleHRIABIxCgdjb3VudGVyGAYgASgLMh4ueW9ya2llLnYxLkpTT05FbGVtZW50LkNvdW50ZXJIABIrCgR0cmVlGAcgASgLMhsueW9ya2llLnYxLkpTT05FbGVtZW50LlRyZWVIABquAQoKSlNPTk9iamVjdBIhCgVub2RlcxgBIAMoCzISLnlvcmtpZS52MS5SSFROb2RlEikKCmNyZWF0ZWRfYXQYAiABKAsyFS55b3JraWUudjEuVGltZVRpY2tldBInCghtb3ZlZF9hdBgDIAEoCzIVLnlvcmtpZS52MS5UaW1lVGlja2V0EikKCnJlbW92ZWRfYXQYBCABKAsyFS55b3JraWUudjEuVGltZVRpY2tldBqtAQoJSlNPTkFycmF5EiEKBW5vZGVzGAEgAygLMhIueW9ya2llLnYxLlJHQU5vZGUSKQoKY3JlYXRlZF9hdBgCIAEoCzIVLnlvcmtpZS52MS5UaW1lVGlja2V0EicKCG1vdmVkX2F0GAMgASgLMhUueW9ya2llLnYxLlRpbWVUaWNrZXQSKQoKcmVtb3ZlZF9hdBgEIAEoCzIVLnlvcmtpZS52MS5UaW1lVGlja2V0Gr0BCglQcmltaXRpdmUSIgoEdHlwZRgBIAEoDjIULnlvcmtpZS52MS5WYWx1ZVR5cGUSDQoFdmFsdWUYAiABKAwSKQoKY3JlYXRlZF9hdBgDIAEoCzIVLnlvcmtpZS52MS5UaW1lVGlja2V0EicKCG1vdmVkX2F0GAQgASgLMhUueW9ya2llLnYxLlRpbWVUaWNrZXQSKQoKcmVtb3ZlZF9hdBgFIAEoCzIVLnlvcmtpZS52MS5UaW1lVGlja2V0GqkBCgRUZXh0EiIKBW5vZGVzGAEgAygLMhMueW9ya2llLnYxLlRleHROb2RlEikKCmNyZWF0ZWRfYXQYAiABKAsyFS55b3JraWUudjEuVGltZVRpY2tldBInCghtb3ZlZF9hdBgDIAEoCzIVLnlvcmtpZS52MS5UaW1lVGlja2V0EikKCnJlbW92ZWRfYXQYBCABKAsyFS55b3JraWUudjEuVGltZVRpY2tldBrYAQoHQ291bnRlchIiCgR0eXBlGAEgASgOMhQueW9ya2llLnYxLlZhbHVlVHlwZRINCgV2YWx1ZRgCIAEoDBIpCgpjcmVhdGVkX2F0GAMgASgLMhUueW9ya2llLnYxLlRpbWVUaWNrZXQSJwoIbW92ZWRfYXQYBCABKAsyFS55b3JraWUudjEuVGltZVRpY2tldBIpCgpyZW1vdmVkX2F0GAUgASgLMhUueW9ya2llLnYxLlRpbWVUaWNrZXQSFQoNaGxsX3JlZ2lzdGVycxgHIAEoDEoECAYQBxqpAQoEVHJlZRIiCgVub2RlcxgBIAMoCzITLnlvcmtpZS52MS5UcmVlTm9kZRIpCgpjcmVhdGVkX2F0GAIgASgLMhUueW9ya2llLnYxLlRpbWVUaWNrZXQSJwoIbW92ZWRfYXQYAyABKAsyFS55b3JraWUudjEuVGltZVRpY2tldBIpCgpyZW1vdmVkX2F0GAQgASgLMhUueW9ya2llLnYxLlRpbWVUaWNrZXRCBgoEYm9keSI/CgdSSFROb2RlEgsKA2tleRgBIAEoCRInCgdlbGVtZW50GAIgASgLMhYueW9ya2llLnYxLkpTT05FbGVtZW50Iu4BCgdSR0FOb2RlEiAKBG5leHQYASABKAsyEi55b3JraWUudjEuUkdBTm9kZRInCgdlbGVtZW50GAIgASgLMhYueW9ya2llLnYxLkpTT05FbGVtZW50EjIKE3Bvc2l0aW9uX2NyZWF0ZWRfYXQYAyABKAsyFS55b3JraWUudjEuVGltZVRpY2tldBIwChFwb3NpdGlvbl9tb3ZlZF9hdBgEIAEoCzIVLnlvcmtpZS52MS5UaW1lVGlja2V0EjIKE3Bvc2l0aW9uX3JlbW92ZWRfYXQYBSABKAsyFS55b3JraWUudjEuVGltZVRpY2tldCJYCghOb2RlQXR0chINCgV2YWx1ZRgBIAEoCRIpCgp1cGRhdGVkX2F0GAIgASgLMhUueW9ya2llLnYxLlRpbWVUaWNrZXQSEgoKaXNfcmVtb3ZlZBgDIAEoCCKUAgoIVGV4dE5vZGUSIQoCaWQYASABKAsyFS55b3JraWUudjEuVGV4dE5vZGVJRBINCgV2YWx1ZRgCIAEoCRIpCgpyZW1vdmVkX2F0GAMgASgLMhUueW9ya2llLnYxLlRpbWVUaWNrZXQSKgoLaW5zX3ByZXZfaWQYBCABKAsyFS55b3JraWUudjEuVGV4dE5vZGVJRBI3CgphdHRyaWJ1dGVzGAUgAygLMiMueW9ya2llLnYxLlRleHROb2RlLkF0dHJpYnV0ZXNFbnRyeRpGCg9BdHRyaWJ1dGVzRW50cnkSCwoDa2V5GAEgASgJEiIKBXZhbHVlGAIgASgLMhMueW9ya2llLnYxLk5vZGVBdHRyOgI4ASJHCgpUZXh0Tm9kZUlEEikKCmNyZWF0ZWRfYXQYASABKAsyFS55b3JraWUudjEuVGltZVRpY2tldBIOCgZvZmZzZXQYAiABKAUiswMKCFRyZWVOb2RlEiEKAmlkGAEgASgLMhUueW9ya2llLnYxLlRyZWVOb2RlSUQSDAoEdHlwZRgCIAEoCRINCgV2YWx1ZRgDIAEoCRIpCgpyZW1vdmVkX2F0GAQgASgLMhUueW9ya2llLnYxLlRpbWVUaWNrZXQSKgoLaW5zX3ByZXZfaWQYBSABKAsyFS55b3JraWUudjEuVHJlZU5vZGVJRBIqCgtpbnNfbmV4dF9pZBgGIAEoCzIVLnlvcmtpZS52MS5UcmVlTm9kZUlEEg0KBWRlcHRoGAcgASgFEjcKCmF0dHJpYnV0ZXMYCCADKAsyIy55b3JraWUudjEuVHJlZU5vZGUuQXR0cmlidXRlc0VudHJ5EioKC21lcmdlZF9mcm9tGAkgASgLMhUueW9ya2llLnYxLlRyZWVOb2RlSUQSKAoJbWVyZ2VkX2F0GAogASgLMhUueW9ya2llLnYxLlRpbWVUaWNrZXQaRgoPQXR0cmlidXRlc0VudHJ5EgsKA2tleRgBIAEoCRIiCgV2YWx1ZRgCIAEoCzITLnlvcmtpZS52MS5Ob2RlQXR0cjoCOAEiMQoJVHJlZU5vZGVzEiQKB2NvbnRlbnQYASADKAsyEy55b3JraWUudjEuVHJlZU5vZGUiRwoKVHJlZU5vZGVJRBIpCgpjcmVhdGVkX2F0GAEgASgLMhUueW9ya2llLnYxLlRpbWVUaWNrZXQSDgoGb2Zmc2V0GAIgASgFImMKB1RyZWVQb3MSKAoJcGFyZW50X2lkGAEgASgLMhUueW9ya2llLnYxLlRyZWVOb2RlSUQSLgoPbGVmdF9zaWJsaW5nX2lkGAIgASgLMhUueW9ya2llLnYxLlRyZWVOb2RlSUQiawoEVXNlchIKCgJpZBgBIAEoCRIVCg1hdXRoX3Byb3ZpZGVyGAIgASgJEhAKCHVzZXJuYW1lGAMgASgJEi4KCmNyZWF0ZWRfYXQYBCABKAsyGi5nb29nbGUucHJvdG9idWYuVGltZXN0YW1wIokBCgZNZW1iZXISCgoCaWQYASABKAkSEgoKcHJvamVjdF9pZBgCIAEoCRIPCgd1c2VyX2lkGAMgASgJEhAKCHVzZXJuYW1lGAQgASgJEgwKBHJvbGUYBSABKAkSLgoKaW52aXRlZF9hdBgGIAEoCzIaLmdvb2dsZS5wcm90b2J1Zi5UaW1lc3RhbXAi6QYKB1Byb2plY3QSCgoCaWQYASABKAkSDAoEbmFtZRgCIAEoCRISCgpwdWJsaWNfa2V5GAMgASgJEhIKCnNlY3JldF9rZXkYBCABKAkSGAoQYXV0aF93ZWJob29rX3VybBgFIAEoCRIcChRhdXRoX3dlYmhvb2tfbWV0aG9kcxgGIAMoCRIgChhhdXRoX3dlYmhvb2tfbWF4X3JldHJpZXMYESABKAQSJgoeYXV0aF93ZWJob29rX21pbl93YWl0X2ludGVydmFsGBIgASgJEiYKHmF1dGhfd2ViaG9va19tYXhfd2FpdF9pbnRlcnZhbBgTIAEoCRIkChxhdXRoX3dlYmhvb2tfcmVxdWVzdF90aW1lb3V0GBQgASgJEhkKEWV2ZW50X3dlYmhvb2tfdXJsGAcgASgJEhwKFGV2ZW50X3dlYmhvb2tfZXZlbnRzGAggAygJEiEKGWV2ZW50X3dlYmhvb2tfbWF4X3JldHJpZXMYFSABKAQSJwofZXZlbnRfd2ViaG9va19taW5fd2FpdF9pbnRlcnZhbBgWIAEoCRInCh9ldmVudF93ZWJob29rX21heF93YWl0X2ludGVydmFsGBcgASgJEiUKHWV2ZW50X3dlYmhvb2tfcmVxdWVzdF90aW1lb3V0GBggASgJEiMKG2NsaWVudF9kZWFjdGl2YXRlX3RocmVzaG9sZBgJIAEoCRIaChJzbmFwc2hvdF90aHJlc2hvbGQYGSABKAMSGQoRc25hcHNob3RfaW50ZXJ2YWwYGiABKAMSJAocbWF4X3N1YnNjcmliZXJzX3Blcl9kb2N1bWVudBgKIAEoBRIkChxtYXhfYXR0YWNobWVudHNfcGVyX2RvY3VtZW50GAsgASgFEh0KFW1heF9zaXplX3Blcl9kb2N1bWVudBgPIAEoBRIYChByZW1vdmVfb25fZGV0YWNoGBAgASgIEh0KFWF1dG9fcmV2aXNpb25fZW5hYmxlZBgbIAEoCBIXCg9hbGxvd2VkX29yaWdpbnMYDiADKAkSLgoKY3JlYXRlZF9hdBgMIAEoCzIaLmdvb2dsZS5wcm90b2J1Zi5UaW1lc3RhbXASLgoKdXBkYXRlZF9hdBgNIAEoCzIaLmdvb2dsZS5wcm90b2J1Zi5UaW1lc3RhbXAiLwoLTWV0cmljUG9pbnQSEQoJdGltZXN0YW1wGAEgASgDEg0KBXZhbHVlGAIgASgFIqMMChZVcGRhdGFibGVQcm9qZWN0RmllbGRzEioKBG5hbWUYASABKAsyHC5nb29nbGUucHJvdG9idWYuU3RyaW5nVmFsdWUSNgoQYXV0aF93ZWJob29rX3VybBgCIAEoCzIcLmdvb2dsZS5wcm90b2J1Zi5TdHJpbmdWYWx1ZRJSChRhdXRoX3dlYmhvb2tfbWV0aG9kcxgDIAEoCzI0LnlvcmtpZS52MS5VcGRhdGFibGVQcm9qZWN0RmllbGRzLkF1dGhXZWJob29rTWV0aG9kcxI+ChhhdXRoX3dlYmhvb2tfbWF4X3JldHJpZXMYDCABKAsyHC5nb29nbGUucHJvdG9idWYuVUludDY0VmFsdWUSRAoeYXV0aF93ZWJob29rX21pbl93YWl0X2ludGVydmFsGA0gASgLMhwuZ29vZ2xlLnByb3RvYnVmLlN0cmluZ1ZhbHVlEkQKHmF1dGhfd2ViaG9va19tYXhfd2FpdF9pbnRlcnZhbBgOIAEoCzIcLmdvb2dsZS5wcm90b2J1Zi5TdHJpbmdWYWx1ZRJCChxhdXRoX3dlYmhvb2tfcmVxdWVzdF90aW1lb3V0GA8gASgLMhwuZ29vZ2xlLnByb3RvYnVmLlN0cmluZ1ZhbHVlEjcKEWV2ZW50X3dlYmhvb2tfdXJsGAQgASgLMhwuZ29vZ2xlLnByb3RvYnVmLlN0cmluZ1ZhbHVlElIKFGV2ZW50X3dlYmhvb2tfZXZlbnRzGAUgASgLMjQueW9ya2llLnYxLlVwZGF0YWJsZVByb2plY3RGaWVsZHMuRXZlbnRXZWJob29rRXZlbnRzEj8KGWV2ZW50X3dlYmhvb2tfbWF4X3JldHJpZXMYECABKAsyHC5nb29nbGUucHJvdG9idWYuVUludDY0VmFsdWUSRQofZXZlbnRfd2ViaG9va19taW5fd2FpdF9pbnRlcnZhbBgRIAEoCzIcLmdvb2dsZS5wcm90b2J1Zi5TdHJpbmdWYWx1ZRJFCh9ldmVudF93ZWJob29rX21heF93YWl0X2ludGVydmFsGBIgASgLMhwuZ29vZ2xlLnByb3RvYnVmLlN0cmluZ1ZhbHVlEkMKHWV2ZW50X3dlYmhvb2tfcmVxdWVzdF90aW1lb3V0GBMgASgLMhwuZ29vZ2xlLnByb3RvYnVmLlN0cmluZ1ZhbHVlEjcKEnNuYXBzaG90X3RocmVzaG9sZBgUIAEoCzIbLmdvb2dsZS5wcm90b2J1Zi5JbnQ2NFZhbHVlEjYKEXNuYXBzaG90X2ludGVydmFsGBUgASgLMhsuZ29vZ2xlLnByb3RvYnVmLkludDY0VmFsdWUSQQobY2xpZW50X2RlYWN0aXZhdGVfdGhyZXNob2xkGAYgASgLMhwuZ29vZ2xlLnByb3RvYnVmLlN0cmluZ1ZhbHVlEkEKHG1heF9zdWJzY3JpYmVyc19wZXJfZG9jdW1lbnQYByABKAsyGy5nb29nbGUucHJvdG9idWYuSW50MzJWYWx1ZRJBChxtYXhfYXR0YWNobWVudHNfcGVyX2RvY3VtZW50GAggASgLMhsuZ29vZ2xlLnByb3RvYnVmLkludDMyVmFsdWUSOgoVbWF4X3NpemVfcGVyX2RvY3VtZW50GAogASgLMhsuZ29vZ2xlLnByb3RvYnVmLkludDMyVmFsdWUSNAoQcmVtb3ZlX29uX2RldGFjaBgLIAEoCzIaLmdvb2dsZS5wcm90b2J1Zi5Cb29sVmFsdWUSOQoVYXV0b19yZXZpc2lvbl9lbmFibGVkGBYgASgLMhouZ29vZ2xlLnByb3RvYnVmLkJvb2xWYWx1ZRJJCg9hbGxvd2VkX29yaWdpbnMYCSABKAsyMC55b3JraWUudjEuVXBkYXRhYmxlUHJvamVjdEZpZWxkcy5BbGxvd2VkT3JpZ2lucxolChJBdXRoV2ViaG9va01ldGhvZHMSDwoHbWV0aG9kcxgBIAMoCRokChJFdmVudFdlYmhvb2tFdmVudHMSDgoGZXZlbnRzGAEgAygJGiEKDkFsbG93ZWRPcmlnaW5zEg8KB29yaWdpbnMYASADKAkipwMKD0RvY3VtZW50U3VtbWFyeRIKCgJpZBgBIAEoCRILCgNrZXkYAiABKAkSDAoEcm9vdBgDIAEoCRIYChBhdHRhY2hlZF9jbGllbnRzGAcgASgFEikKDWRvY3VtZW50X3NpemUYCCABKAsyEi55b3JraWUudjEuRG9jU2l6ZRISCgpzY2hlbWFfa2V5GAkgASgJEjwKCXByZXNlbmNlcxgKIAMoCzIpLnlvcmtpZS52MS5Eb2N1bWVudFN1bW1hcnkuUHJlc2VuY2VzRW50cnkSLgoKY3JlYXRlZF9hdBgEIAEoCzIaLmdvb2dsZS5wcm90b2J1Zi5UaW1lc3RhbXASLwoLYWNjZXNzZWRfYXQYBSABKAsyGi5nb29nbGUucHJvdG9idWYuVGltZXN0YW1wEi4KCnVwZGF0ZWRfYXQYBiABKAsyGi5nb29nbGUucHJvdG9idWYuVGltZXN0YW1wGkUKDlByZXNlbmNlc0VudHJ5EgsKA2tleRgBIAEoCRIiCgV2YWx1ZRgCIAEoCzITLnlvcmtpZS52MS5QcmVzZW5jZToCOAEi2gEKDlByZXNlbmNlQ2hhbmdlEjIKBHR5cGUYASABKA4yJC55b3JraWUudjEuUHJlc2VuY2VDaGFuZ2UuQ2hhbmdlVHlwZRIlCghwcmVzZW5jZRgCIAEoCzITLnlvcmtpZS52MS5QcmVzZW5jZSJtCgpDaGFuZ2VUeXBlEhsKF0NIQU5HRV9UWVBFX1VOU1BFQ0lGSUVEEAASEwoPQ0hBTkdFX1RZUEVfUFVUEAESFgoSQ0hBTkdFX1RZUEVfREVMRVRFEAISFQoRQ0hBTkdFX1RZUEVfQ0xFQVIQAyJkCghQcmVzZW5jZRIrCgRkYXRhGAEgAygLMh0ueW9ya2llLnYxLlByZXNlbmNlLkRhdGFFbnRyeRorCglEYXRhRW50cnkSCwoDa2V5GAEgASgJEg0KBXZhbHVlGAIgASgJOgI4ASI0Cg5DaGFubmVsU3VtbWFyeRILCgNrZXkYASABKAkSFQoNc2Vzc2lvbl9jb3VudBgCIAEoBSI0CgpDaGVja3BvaW50EhIKCnNlcnZlcl9zZXEYASABKAMSEgoKY2xpZW50X3NlcRgCIAEoDSJhCgtUZXh0Tm9kZVBvcxIpCgpjcmVhdGVkX2F0GAEgASgLMhUueW9ya2llLnYxLlRpbWVUaWNrZXQSDgoGb2Zmc2V0GAIgASgFEhcKD3JlbGF0aXZlX29mZnNldBgDIAEoBSJCCgpUaW1lVGlja2V0Eg8KB2xhbXBvcnQYASABKAMSEQoJZGVsaW1pdGVyGAIgASgNEhAKCGFjdG9yX2lkGAMgASgMIi4KDERvY0V2ZW50Qm9keRINCgV0b3BpYxgBIAEoCRIPCgdwYXlsb2FkGAIgASgMImsKCERvY0V2ZW50EiUKBHR5cGUYASABKA4yFy55b3JraWUudjEuRG9jRXZlbnRUeXBlEhEKCXB1Ymxpc2hlchgCIAEoCRIlCgRib2R5GAMgASgLMhcueW9ya2llLnYxLkRvY0V2ZW50Qm9keSLWAQoMQ2hhbm5lbEV2ZW50EioKBHR5cGUYASABKA4yHC55b3JraWUudjEuQ2hhbm5lbEV2ZW50LlR5cGUSEQoJcHVibGlzaGVyGAIgASgJEhUKDXNlc3Npb25fY291bnQYAyABKAMSCwoDc2VxGAQgASgDEg0KBXRvcGljGAUgASgJEg8KB3BheWxvYWQYBiABKAwiQwoEVHlwZRIUChBUWVBFX1VOU1BFQ0lGSUVEEAASEQoNVFlQRV9QUkVTRU5DRRABEhIKDlRZUEVfQlJPQURDQVNUEAIiJgoIRGF0YVNpemUSDAoEZGF0YRgBIAEoBRIMCgRtZXRhGAIgASgFIk0KB0RvY1NpemUSIQoEbGl2ZRgBIAEoCzITLnlvcmtpZS52MS5EYXRhU2l6ZRIfCgJnYxgCIAEoCzITLnlvcmtpZS52MS5EYXRhU2l6ZSKRAQoGU2NoZW1hEgoKAmlkGAEgASgJEgwKBG5hbWUYAiABKAkSDwoHdmVyc2lvbhgDIAEoBRIMCgRib2R5GAQgASgJEh4KBXJ1bGVzGAUgAygLMg8ueW9ya2llLnYxLlJ1bGUSLgoKY3JlYXRlZF9hdBgGIAEoCzIaLmdvb2dsZS5wcm90b2J1Zi5UaW1lc3RhbXAiUAoMVHJlZU5vZGVSdWxlEhEKCW5vZGVfdHlwZRgBIAEoCRIPCgdjb250ZW50GAIgASgJEg0KBW1hcmtzGAMgASgJEg0KBWdyb3VwGAQgASgJIk8KBFJ1bGUSDAoEcGF0aBgBIAEoCRIMCgR0eXBlGAIgASgJEisKCnRyZWVfbm9kZXMYAyADKAsyFy55b3JraWUudjEuVHJlZU5vZGVSdWxlIoMBCg9SZXZpc2lvblN1bW1hcnkSCgoCaWQYASABKAkSDQoFbGFiZWwYAiABKAkSEwoLZGVzY3JpcHRpb24YAyABKAkSEAoIc25hcHNob3QYBCABKAkSLgoKY3JlYXRlZF9hdBgFIAEoCzIaLmdvb2dsZS5wcm90b2J1Zi5UaW1lc3RhbXAq/AIKCVZhbHVlVHlwZRITCg9WQUxVRV9UWVBFX05VTEwQABIWChJWQUxVRV9UWVBFX0JPT0xFQU4QARIWChJWQUxVRV9UWVBFX0lOVEVHRVIQAhITCg9WQUxVRV9UWVBFX0xPTkcQAxIVChFWQUxVRV9UWVBFX0RPVUJMRRAEEhUKEVZBTFVFX1RZUEVfU1RSSU5HEAUSFAoQVkFMVUVfVFlQRV9CWVRFUxAGEhMKD1ZBTFVFX1RZUEVfREFURRAHEhoKFlZBTFVFX1RZUEVfSlNPTl9PQkpFQ1QQCBIZChVWQUxVRV9UWVBFX0pTT05fQVJSQVkQCRITCg9WQUxVRV9UWVBFX1RFWFQQChIaChZWQUxVRV9UWVBFX0lOVEVHRVJfQ05UEAsSFwoTVkFMVUVfVFlQRV9MT05HX0NOVBAMEhMKD1ZBTFVFX1RZUEVfVFJFRRANEiAKHFZBTFVFX1RZUEVfSU5URUdFUl9ERURVUF9DTlQQDiIECA8QDyqmAQoMRG9jRXZlbnRUeXBlEiMKH0RPQ19FVkVOVF9UWVBFX0RPQ1VNRU5UX0NIQU5HRUQQABIjCh9ET0NfRVZFTlRfVFlQRV9ET0NVTUVOVF9XQVRDSEVEEAESJQohRE9DX0VWRU5UX1RZUEVfRE9DVU1FTlRfVU5XQVRDSEVEEAISJQohRE9DX0VWRU5UX1RZUEVfRE9DVU1FTlRfQlJPQURDQVNUEANCRQoRZGV2LnlvcmtpZS5hcGkudjFQAVouZ2l0aHViLmNvbS95b3JraWUtdGVhbS95b3JraWUvYXBpL3lvcmtpZS92MTt2MWIGcHJvdG8z", [file_google_protobuf_timestamp, file_google_protobuf_wrappers]);
5792
5792
  const SnapshotSchema = /* @__PURE__ */ messageDesc(file_src_api_yorkie_v1_resources, 0);
5793
5793
  const ChangePackSchema = /* @__PURE__ */ messageDesc(file_src_api_yorkie_v1_resources, 1);
5794
5794
  const ChangeSchema = /* @__PURE__ */ messageDesc(file_src_api_yorkie_v1_resources, 2);
@@ -7137,6 +7137,13 @@ class Primitive extends CRDTElement {
7137
7137
  if (this.valueType === 5) {
7138
7138
  return `"${escapeString(this.value)}"`;
7139
7139
  }
7140
+ if (this.valueType === 6) {
7141
+ const bytes = this.value;
7142
+ return `"${btoa(String.fromCharCode(...bytes))}"`;
7143
+ }
7144
+ if (this.valueType === 7) {
7145
+ return `"${this.value.toISOString()}"`;
7146
+ }
7140
7147
  return `${this.value}`;
7141
7148
  }
7142
7149
  /**
@@ -7279,19 +7286,54 @@ class Primitive extends CRDTElement {
7279
7286
  }
7280
7287
  }
7281
7288
  }
7289
+ class ElementEntry {
7290
+ elem;
7291
+ positionNode;
7292
+ posMovedAt;
7293
+ constructor(elem) {
7294
+ this.elem = elem;
7295
+ }
7296
+ }
7282
7297
  class RGATreeListNode extends SplayNode {
7298
+ _elementEntry;
7299
+ _createdAt;
7300
+ _removedAt;
7283
7301
  prev;
7284
7302
  next;
7285
- movedFrom;
7286
- constructor(value) {
7287
- super(value);
7288
- this.value = value;
7303
+ constructor(elem, createdAt) {
7304
+ super(elem);
7305
+ this._createdAt = createdAt;
7289
7306
  }
7290
7307
  /**
7291
- * `createAfter` creates a new node after the given node.
7308
+ * `createWithElement` creates a new node that owns an element.
7292
7309
  */
7293
- static createAfter(prev, value) {
7294
- const newNode = new RGATreeListNode(value);
7310
+ static createWithElement(elem) {
7311
+ const entry = new ElementEntry(elem);
7312
+ const node = new RGATreeListNode(elem, elem.getCreatedAt());
7313
+ entry.positionNode = node;
7314
+ node._elementEntry = entry;
7315
+ return node;
7316
+ }
7317
+ /**
7318
+ * `createBarePosition` creates a position node without an element
7319
+ * (used for move).
7320
+ */
7321
+ static createBarePosition(createdAt) {
7322
+ return new RGATreeListNode(void 0, createdAt);
7323
+ }
7324
+ /**
7325
+ * `createAfter` creates a new node with the given element after
7326
+ * the given prev node.
7327
+ */
7328
+ static createAfter(prev, elem) {
7329
+ const newNode = RGATreeListNode.createWithElement(elem);
7330
+ RGATreeListNode.insertNodeAfter(prev, newNode);
7331
+ return newNode;
7332
+ }
7333
+ /**
7334
+ * `insertNodeAfter` inserts a node after the given prev node.
7335
+ */
7336
+ static insertNodeAfter(prev, newNode) {
7295
7337
  const prevNext = prev.next;
7296
7338
  prev.next = newNode;
7297
7339
  newNode.prev = prev;
@@ -7299,26 +7341,41 @@ class RGATreeListNode extends SplayNode {
7299
7341
  if (prevNext) {
7300
7342
  prevNext.prev = newNode;
7301
7343
  }
7302
- return newNode;
7303
7344
  }
7304
7345
  /**
7305
- * `remove` removes value based on removing time.
7346
+ * `remove` removes the element based on removing time.
7306
7347
  */
7307
7348
  remove(removedAt) {
7308
- return this.value.remove(removedAt);
7349
+ if (!this._elementEntry) {
7350
+ return false;
7351
+ }
7352
+ return this._elementEntry.elem.remove(removedAt);
7309
7353
  }
7310
7354
  /**
7311
- * `getCreatedAt` returns creation time of this value
7355
+ * `getCreatedAt` returns the creation time. For live nodes with
7356
+ * elements, returns the element's createdAt for backward
7357
+ * compatibility.
7312
7358
  */
7313
7359
  getCreatedAt() {
7314
- return this.value.getCreatedAt();
7360
+ if (this._elementEntry) {
7361
+ return this._elementEntry.elem.getCreatedAt();
7362
+ }
7363
+ return this._createdAt;
7315
7364
  }
7316
7365
  /**
7317
- * `getPositionedAt` returns the time of this element when it was positioned
7318
- * in the array.
7366
+ * `getPositionedAt` returns the time this element was positioned.
7367
+ * For live nodes, the position register (posMovedAt) is the source
7368
+ * of truth. For dead nodes (no element), the position node's own
7369
+ * createdAt is used.
7319
7370
  */
7320
7371
  getPositionedAt() {
7321
- return this.value.getPositionedAt();
7372
+ if (this._elementEntry) {
7373
+ if (this._elementEntry.posMovedAt) {
7374
+ return this._elementEntry.posMovedAt;
7375
+ }
7376
+ return this._elementEntry.elem.getCreatedAt();
7377
+ }
7378
+ return this._createdAt;
7322
7379
  }
7323
7380
  /**
7324
7381
  * `release` releases prev and next node.
@@ -7335,9 +7392,13 @@ class RGATreeListNode extends SplayNode {
7335
7392
  }
7336
7393
  /**
7337
7394
  * `getLength` returns the length of this node.
7395
+ * Dead nodes (no element) return 0, removed elements return 0.
7338
7396
  */
7339
7397
  getLength() {
7340
- return this.value.isRemoved() ? 0 : 1;
7398
+ if (!this._elementEntry || this.isRemoved()) {
7399
+ return 0;
7400
+ }
7401
+ return 1;
7341
7402
  }
7342
7403
  /**
7343
7404
  * `getPrev` returns a previous node.
@@ -7352,28 +7413,87 @@ class RGATreeListNode extends SplayNode {
7352
7413
  return this.next;
7353
7414
  }
7354
7415
  /**
7355
- * `getMovedFrom` returns the previous element before the element moved.
7416
+ * `getValue` returns the element value.
7356
7417
  */
7357
- getMovedFrom() {
7358
- return this.movedFrom;
7418
+ getValue() {
7419
+ if (!this._elementEntry) {
7420
+ return this.value;
7421
+ }
7422
+ return this._elementEntry.elem;
7359
7423
  }
7360
7424
  /**
7361
- * `setMovedFrom` sets the previous element before the element moved.
7425
+ * `getElement` returns the element or undefined if dead position.
7362
7426
  */
7363
- setMovedFrom(movedFrom) {
7364
- this.movedFrom = movedFrom;
7427
+ getElement() {
7428
+ return this._elementEntry?.elem;
7365
7429
  }
7366
7430
  /**
7367
- * `getValue` returns a element value.
7431
+ * `isRemoved` checks if the value was removed.
7368
7432
  */
7369
- getValue() {
7370
- return this.value;
7433
+ isRemoved() {
7434
+ if (!this._elementEntry) {
7435
+ return true;
7436
+ }
7437
+ return this._elementEntry.elem.isRemoved();
7371
7438
  }
7372
7439
  /**
7373
- * `isRemoved` checks if the value was removed.
7440
+ * `getElementEntry` returns the element entry.
7374
7441
  */
7375
- isRemoved() {
7376
- return this.value.isRemoved();
7442
+ getElementEntry() {
7443
+ return this._elementEntry;
7444
+ }
7445
+ /**
7446
+ * `setElementEntry` sets the element entry.
7447
+ */
7448
+ setElementEntry(entry) {
7449
+ this._elementEntry = entry;
7450
+ }
7451
+ /**
7452
+ * `getPositionCreatedAt` returns the position node's own createdAt.
7453
+ */
7454
+ getPositionCreatedAt() {
7455
+ return this._createdAt;
7456
+ }
7457
+ /**
7458
+ * `getPositionMovedAt` returns the LWW timestamp of the element's
7459
+ * move into this position. Undefined for insert-created positions.
7460
+ */
7461
+ getPositionMovedAt() {
7462
+ if (!this._elementEntry) {
7463
+ return void 0;
7464
+ }
7465
+ return this._elementEntry.posMovedAt;
7466
+ }
7467
+ /**
7468
+ * `getRemovedAt` returns the time this dead position node was
7469
+ * removed (for GC).
7470
+ */
7471
+ getRemovedAt() {
7472
+ return this._removedAt;
7473
+ }
7474
+ /**
7475
+ * `setRemovedAt` sets the removal time of this position node.
7476
+ */
7477
+ setRemovedAt(removedAt) {
7478
+ this._removedAt = removedAt;
7479
+ }
7480
+ /**
7481
+ * `toIDString` returns a unique identifier for this position node
7482
+ * (for GC).
7483
+ */
7484
+ toIDString() {
7485
+ return this._createdAt.toIDString();
7486
+ }
7487
+ /**
7488
+ * `getDataSize` returns the data size of this position node
7489
+ * (for GC).
7490
+ */
7491
+ getDataSize() {
7492
+ let meta = TimeTicketSize;
7493
+ if (this._removedAt) {
7494
+ meta += TimeTicketSize;
7495
+ }
7496
+ return { data: 0, meta };
7377
7497
  }
7378
7498
  }
7379
7499
  class RGATreeList {
@@ -7381,13 +7501,15 @@ class RGATreeList {
7381
7501
  last;
7382
7502
  nodeMapByIndex;
7383
7503
  nodeMapByCreatedAt;
7504
+ elementMapByCreatedAt;
7384
7505
  constructor() {
7385
7506
  const dummyValue = Primitive.of(0, InitialTimeTicket);
7386
7507
  dummyValue.setRemovedAt(InitialTimeTicket);
7387
- this.dummyHead = new RGATreeListNode(dummyValue);
7508
+ this.dummyHead = RGATreeListNode.createWithElement(dummyValue);
7388
7509
  this.last = this.dummyHead;
7389
7510
  this.nodeMapByIndex = new SplayTree();
7390
7511
  this.nodeMapByCreatedAt = /* @__PURE__ */ new Map();
7512
+ this.elementMapByCreatedAt = /* @__PURE__ */ new Map();
7391
7513
  this.nodeMapByIndex.insert(this.dummyHead);
7392
7514
  this.nodeMapByCreatedAt.set(
7393
7515
  this.dummyHead.getCreatedAt().toIDString(),
@@ -7407,22 +7529,10 @@ class RGATreeList {
7407
7529
  return this.nodeMapByIndex.length;
7408
7530
  }
7409
7531
  /**
7410
- * `findNextBeforeExecutedAt` returns the node by the given createdAt and
7411
- * executedAt. It passes through nodes created after executedAt from the
7412
- * given node and returns the next node.
7413
- * @returns the next node of the given createdAt and executedAt
7532
+ * `findNextBeforeExecutedAt` walks forward from the given node,
7533
+ * skipping nodes positioned after executedAt (RGA insertion rule).
7414
7534
  */
7415
- findNextBeforeExecutedAt(createdAt, executedAt) {
7416
- let node = this.nodeMapByCreatedAt.get(createdAt.toIDString());
7417
- if (!node) {
7418
- throw new YorkieError(
7419
- Code.ErrInvalidArgument,
7420
- `cant find the given node: ${createdAt.toIDString()}`
7421
- );
7422
- }
7423
- while (node.getValue().getMovedAt() && node.getValue().getMovedAt().after(executedAt) && node.getMovedFrom()) {
7424
- node = node.getMovedFrom();
7425
- }
7535
+ findNextBeforeExecutedAt(node, executedAt) {
7426
7536
  while (node.getNext() && node.getNext().getPositionedAt().after(executedAt)) {
7427
7537
  node = node.getNext();
7428
7538
  }
@@ -7434,65 +7544,103 @@ class RGATreeList {
7434
7544
  }
7435
7545
  node.release();
7436
7546
  this.nodeMapByIndex.delete(node);
7437
- this.nodeMapByCreatedAt.delete(node.getValue().getCreatedAt().toIDString());
7547
+ this.nodeMapByCreatedAt.delete(node.getPositionCreatedAt().toIDString());
7438
7548
  }
7439
7549
  /**
7440
- * `insertAfter` adds a new node with the value after the given node.
7550
+ * `insertAfter` adds a new node with the value after the given
7551
+ * position. prevCreatedAt is a position node identity. Looks up
7552
+ * nodeMapByCreatedAt first, then elementMapByCreatedAt for backward
7553
+ * compatibility.
7441
7554
  */
7442
7555
  insertAfter(prevCreatedAt, value, executedAt = value.getCreatedAt()) {
7443
- const prevNode = this.findNextBeforeExecutedAt(prevCreatedAt, executedAt);
7556
+ let startNode = this.nodeMapByCreatedAt.get(prevCreatedAt.toIDString());
7557
+ if (!startNode) {
7558
+ const entry = this.elementMapByCreatedAt.get(prevCreatedAt.toIDString());
7559
+ if (entry) {
7560
+ startNode = entry.positionNode;
7561
+ }
7562
+ }
7563
+ if (!startNode) {
7564
+ throw new YorkieError(
7565
+ Code.ErrInvalidArgument,
7566
+ `cant find the given node: ${prevCreatedAt.toIDString()}`
7567
+ );
7568
+ }
7569
+ const prevNode = this.findNextBeforeExecutedAt(startNode, executedAt);
7444
7570
  const newNode = RGATreeListNode.createAfter(prevNode, value);
7445
7571
  if (prevNode === this.last) {
7446
7572
  this.last = newNode;
7447
7573
  }
7448
7574
  this.nodeMapByIndex.insertAfter(prevNode, newNode);
7449
- this.nodeMapByCreatedAt.set(newNode.getCreatedAt().toIDString(), newNode);
7575
+ this.nodeMapByCreatedAt.set(value.getCreatedAt().toIDString(), newNode);
7576
+ this.elementMapByCreatedAt.set(
7577
+ value.getCreatedAt().toIDString(),
7578
+ newNode.getElementEntry()
7579
+ );
7450
7580
  return newNode;
7451
7581
  }
7452
7582
  /**
7453
- * `moveAfter` moves the given `createdAt` element
7454
- * after the `prevCreatedAt` element.
7583
+ * `insertPositionAfter` creates a bare position node after
7584
+ * resolving position via forward skip (RGA insertion rule).
7585
+ * Used by moveAfter. prevCreatedAt is a POSITION node identity.
7586
+ */
7587
+ insertPositionAfter(prevCreatedAt, executedAt) {
7588
+ const startNode = this.nodeMapByCreatedAt.get(prevCreatedAt.toIDString());
7589
+ if (!startNode) {
7590
+ throw new YorkieError(
7591
+ Code.ErrInvalidArgument,
7592
+ `cant find the given node: ${prevCreatedAt.toIDString()}`
7593
+ );
7594
+ }
7595
+ const prevNode = this.findNextBeforeExecutedAt(startNode, executedAt);
7596
+ const newNode = RGATreeListNode.createBarePosition(executedAt);
7597
+ RGATreeListNode.insertNodeAfter(prevNode, newNode);
7598
+ if (prevNode === this.last) {
7599
+ this.last = newNode;
7600
+ }
7601
+ this.nodeMapByIndex.insertAfter(prevNode, newNode);
7602
+ this.nodeMapByCreatedAt.set(executedAt.toIDString(), newNode);
7603
+ return newNode;
7604
+ }
7605
+ /**
7606
+ * `moveAfter` moves the given `createdAt` element after the
7607
+ * `prevCreatedAt` element using LWW position register semantics.
7608
+ * Returns the dead position node (if any) for GC registration.
7455
7609
  */
7456
7610
  moveAfter(prevCreatedAt, createdAt, executedAt) {
7457
- let prevNode = this.nodeMapByCreatedAt.get(prevCreatedAt.toIDString());
7458
- if (!prevNode) {
7611
+ if (!this.nodeMapByCreatedAt.has(prevCreatedAt.toIDString())) {
7459
7612
  throw new YorkieError(
7460
7613
  Code.ErrInvalidArgument,
7461
7614
  `cant find the given node: ${prevCreatedAt.toIDString()}`
7462
7615
  );
7463
7616
  }
7464
- let node = this.nodeMapByCreatedAt.get(createdAt.toIDString());
7465
- if (!node) {
7617
+ const entry = this.elementMapByCreatedAt.get(createdAt.toIDString());
7618
+ if (!entry) {
7466
7619
  throw new YorkieError(
7467
7620
  Code.ErrInvalidArgument,
7468
7621
  `cant find the given node: ${createdAt.toIDString()}`
7469
7622
  );
7470
7623
  }
7471
- if (prevNode !== node && executedAt.after(node.getPositionedAt())) {
7472
- const movedFrom = node.getPrev();
7473
- let nextNode = node.getNext();
7474
- this.release(node);
7475
- node = this.insertAfter(
7476
- prevNode.getCreatedAt(),
7477
- node.getValue(),
7478
- executedAt
7479
- );
7480
- node.getValue().setMovedAt(executedAt);
7481
- node.setMovedFrom(movedFrom);
7482
- while (nextNode && nextNode.getPositionedAt().after(executedAt)) {
7483
- prevNode = node;
7484
- node = nextNode;
7485
- nextNode = node.getNext();
7486
- this.release(node);
7487
- node = this.insertAfter(
7488
- prevNode.getCreatedAt(),
7489
- node.getValue(),
7490
- executedAt
7491
- );
7492
- node.getValue().setMovedAt(executedAt);
7493
- node.setMovedFrom(movedFrom);
7624
+ if (entry.posMovedAt && !executedAt.after(entry.posMovedAt)) {
7625
+ if (this.nodeMapByCreatedAt.has(executedAt.toIDString())) {
7626
+ return void 0;
7494
7627
  }
7628
+ const deadPosNode = this.insertPositionAfter(prevCreatedAt, executedAt);
7629
+ deadPosNode.setRemovedAt(executedAt);
7630
+ this.nodeMapByIndex.splayNode(deadPosNode);
7631
+ return deadPosNode;
7495
7632
  }
7633
+ const newPosNode = this.insertPositionAfter(prevCreatedAt, executedAt);
7634
+ const oldPosNode = entry.positionNode;
7635
+ oldPosNode.setElementEntry(void 0);
7636
+ oldPosNode.setRemovedAt(executedAt);
7637
+ this.nodeMapByIndex.splayNode(oldPosNode);
7638
+ newPosNode.setElementEntry(entry);
7639
+ entry.positionNode = newPosNode;
7640
+ entry.posMovedAt = executedAt;
7641
+ entry.elem.setMovedAt(executedAt);
7642
+ this.nodeMapByIndex.splayNode(newPosNode);
7643
+ return oldPosNode;
7496
7644
  }
7497
7645
  /**
7498
7646
  * `insert` adds the given element after the last node.
@@ -7501,34 +7649,53 @@ class RGATreeList {
7501
7649
  this.insertAfter(this.last.getCreatedAt(), value);
7502
7650
  }
7503
7651
  /**
7504
- * `getByID` returns the element of the given creation time.
7652
+ * `getByID` returns the node of the given creation time.
7653
+ * Checks elementMapByCreatedAt first (for moved elements whose
7654
+ * position node createdAt differs), then nodeMapByCreatedAt.
7505
7655
  */
7506
7656
  getByID(createdAt) {
7657
+ const entry = this.elementMapByCreatedAt.get(createdAt.toIDString());
7658
+ if (entry) {
7659
+ return entry.positionNode;
7660
+ }
7507
7661
  return this.nodeMapByCreatedAt.get(createdAt.toIDString());
7508
7662
  }
7509
7663
  /**
7510
7664
  * `subPathOf` returns the sub path of the given element.
7511
7665
  */
7512
7666
  subPathOf(createdAt) {
7513
- const node = this.nodeMapByCreatedAt.get(createdAt.toIDString());
7514
- if (!node) {
7515
- return;
7667
+ const entry = this.elementMapByCreatedAt.get(createdAt.toIDString());
7668
+ if (!entry) {
7669
+ const node = this.nodeMapByCreatedAt.get(createdAt.toIDString());
7670
+ if (!node) {
7671
+ return;
7672
+ }
7673
+ return String(this.nodeMapByIndex.indexOf(node));
7516
7674
  }
7517
- return String(this.nodeMapByIndex.indexOf(node));
7675
+ return String(this.nodeMapByIndex.indexOf(entry.positionNode));
7518
7676
  }
7519
7677
  /**
7520
- * `purge` physically purges element.
7678
+ * `purge` physically purges the given child. Handles both dead
7679
+ * position nodes (GCChild from GCParent path) and CRDTElements
7680
+ * (from CRDTContainer path).
7521
7681
  */
7522
- purge(element) {
7523
- const node = this.nodeMapByCreatedAt.get(
7682
+ purge(child) {
7683
+ if (child instanceof RGATreeListNode) {
7684
+ this.release(child);
7685
+ return;
7686
+ }
7687
+ const element = child;
7688
+ const entry = this.elementMapByCreatedAt.get(
7524
7689
  element.getCreatedAt().toIDString()
7525
7690
  );
7526
- if (!node) {
7691
+ if (!entry) {
7527
7692
  throw new YorkieError(
7528
7693
  Code.ErrInvalidArgument,
7529
7694
  `fail to find the given createdAt: ${element.getCreatedAt().toIDString()}`
7530
7695
  );
7531
7696
  }
7697
+ const node = entry.positionNode;
7698
+ this.elementMapByCreatedAt.delete(element.getCreatedAt().toIDString());
7532
7699
  this.release(node);
7533
7700
  }
7534
7701
  /**
@@ -7539,42 +7706,69 @@ class RGATreeList {
7539
7706
  return;
7540
7707
  }
7541
7708
  const node = this.nodeMapByIndex.findForArray(idx);
7542
- const rgaNode = node;
7543
- return rgaNode;
7709
+ return node;
7544
7710
  }
7545
7711
  /**
7546
- * `getPrevCreatedAt` returns a creation time of the previous node.
7712
+ * `findPrevCreatedAt` returns the position node's createdAt of the
7713
+ * previous element. This returns a position identity suitable for
7714
+ * use as prevCreatedAt in moveAfter.
7547
7715
  */
7548
- getPrevCreatedAt(createdAt) {
7549
- let node = this.nodeMapByCreatedAt.get(createdAt.toIDString());
7716
+ findPrevCreatedAt(createdAt) {
7717
+ const entry = this.elementMapByCreatedAt.get(createdAt.toIDString());
7718
+ if (!entry) {
7719
+ throw new YorkieError(
7720
+ Code.ErrInvalidArgument,
7721
+ `cant find the given node: ${createdAt.toIDString()}`
7722
+ );
7723
+ }
7724
+ let node = entry.positionNode;
7550
7725
  do {
7551
7726
  node = node.getPrev();
7552
- } while (this.dummyHead !== node && node.isRemoved());
7553
- return node.getValue().getCreatedAt();
7727
+ if (!node.getElementEntry()) {
7728
+ continue;
7729
+ }
7730
+ if (this.dummyHead === node || !node.isRemoved()) {
7731
+ break;
7732
+ }
7733
+ } while (node);
7734
+ return node.getPositionCreatedAt();
7735
+ }
7736
+ /**
7737
+ * `getPrevCreatedAt` returns the position node's createdAt of the
7738
+ * previous element. Delegates to findPrevCreatedAt.
7739
+ */
7740
+ getPrevCreatedAt(createdAt) {
7741
+ return this.findPrevCreatedAt(createdAt);
7554
7742
  }
7555
7743
  /**
7556
7744
  * `delete` deletes the node of the given creation time.
7557
7745
  */
7558
7746
  delete(createdAt, editedAt) {
7559
- const node = this.nodeMapByCreatedAt.get(createdAt.toIDString());
7747
+ const entry = this.elementMapByCreatedAt.get(createdAt.toIDString());
7748
+ if (!entry) {
7749
+ throw new YorkieError(
7750
+ Code.ErrInvalidArgument,
7751
+ `cant find the given node: ${createdAt.toIDString()}`
7752
+ );
7753
+ }
7754
+ const node = entry.positionNode;
7560
7755
  const alreadyRemoved = node.isRemoved();
7561
- if (node.remove(editedAt) && !alreadyRemoved) {
7756
+ if (entry.elem.remove(editedAt) && !alreadyRemoved) {
7562
7757
  this.nodeMapByIndex.splayNode(node);
7563
7758
  }
7564
- return node.getValue();
7759
+ return entry.elem;
7565
7760
  }
7566
7761
  /**
7567
7762
  * `set` sets the given element at the given creation time.
7568
7763
  */
7569
7764
  set(createdAt, element, executedAt) {
7570
- const node = this.nodeMapByCreatedAt.get(createdAt.toIDString());
7571
- if (!node) {
7765
+ if (!this.elementMapByCreatedAt.has(createdAt.toIDString())) {
7572
7766
  throw new YorkieError(
7573
7767
  Code.ErrInvalidArgument,
7574
7768
  `cant find the given node: ${createdAt.toIDString()}`
7575
7769
  );
7576
7770
  }
7577
- this.insertAfter(node.getCreatedAt(), element, executedAt);
7771
+ this.insertAfter(createdAt, element, executedAt);
7578
7772
  return this.delete(createdAt, executedAt);
7579
7773
  }
7580
7774
  /**
@@ -7603,18 +7797,80 @@ class RGATreeList {
7603
7797
  return this.last.getValue();
7604
7798
  }
7605
7799
  /**
7606
- * `getLastCreatedAt` returns the creation time of last element.
7800
+ * `getLastCreatedAt` returns the position node's createdAt of the
7801
+ * last node in the linked list. This is a position identity
7802
+ * suitable for use as prevCreatedAt.
7607
7803
  */
7608
7804
  getLastCreatedAt() {
7609
- return this.last.getCreatedAt();
7805
+ return this.last.getPositionCreatedAt();
7610
7806
  }
7611
7807
  /**
7612
- * `toTestString` returns a String containing the meta data of the node id
7613
- * for debugging purpose.
7808
+ * `posCreatedAt` returns the createdAt of the position node
7809
+ * currently holding the element. Used to convert element identity
7810
+ * to position identity.
7811
+ */
7812
+ posCreatedAt(elemCreatedAt) {
7813
+ const entry = this.elementMapByCreatedAt.get(elemCreatedAt.toIDString());
7814
+ if (!entry) {
7815
+ throw new YorkieError(
7816
+ Code.ErrInvalidArgument,
7817
+ `cant find the given node: ${elemCreatedAt.toIDString()}`
7818
+ );
7819
+ }
7820
+ return entry.positionNode.getPositionCreatedAt();
7821
+ }
7822
+ /**
7823
+ * `addDeadPosition` appends a dead position node during snapshot
7824
+ * restoration.
7825
+ */
7826
+ addDeadPosition(posCreatedAt, removedAt) {
7827
+ const node = RGATreeListNode.createBarePosition(posCreatedAt);
7828
+ node.setRemovedAt(removedAt);
7829
+ const prevNode = this.last;
7830
+ RGATreeListNode.insertNodeAfter(prevNode, node);
7831
+ this.last = node;
7832
+ this.nodeMapByIndex.insertAfter(prevNode, node);
7833
+ this.nodeMapByCreatedAt.set(posCreatedAt.toIDString(), node);
7834
+ }
7835
+ /**
7836
+ * `addMovedElement` appends an element with explicit position
7837
+ * identity during snapshot restoration.
7838
+ */
7839
+ addMovedElement(elem, posCreatedAt, posMovedAt) {
7840
+ const entry = new ElementEntry(elem);
7841
+ entry.posMovedAt = posMovedAt;
7842
+ const node = RGATreeListNode.createBarePosition(posCreatedAt);
7843
+ node.setElementEntry(entry);
7844
+ entry.positionNode = node;
7845
+ const prevNode = this.last;
7846
+ RGATreeListNode.insertNodeAfter(prevNode, node);
7847
+ this.last = node;
7848
+ this.nodeMapByIndex.insertAfter(prevNode, node);
7849
+ this.nodeMapByCreatedAt.set(posCreatedAt.toIDString(), node);
7850
+ this.elementMapByCreatedAt.set(elem.getCreatedAt().toIDString(), entry);
7851
+ }
7852
+ /**
7853
+ * `allNodes` returns all nodes including dead position nodes.
7854
+ */
7855
+ allNodes() {
7856
+ const nodes = [];
7857
+ let current = this.dummyHead.getNext();
7858
+ while (current) {
7859
+ nodes.push(current);
7860
+ current = current.getNext();
7861
+ }
7862
+ return nodes;
7863
+ }
7864
+ /**
7865
+ * `toTestString` returns a String containing the meta data of the
7866
+ * node id for debugging purpose.
7614
7867
  */
7615
7868
  toTestString() {
7616
7869
  const json = [];
7617
7870
  for (const node of this) {
7871
+ if (!node.getElementEntry()) {
7872
+ continue;
7873
+ }
7618
7874
  const elem = `${node.getCreatedAt().toIDString()}:${node.getValue().toJSON()}`;
7619
7875
  if (node.isRemoved()) {
7620
7876
  json.push(`{${elem}}`);
@@ -7671,10 +7927,11 @@ class CRDTArray extends CRDTContainer {
7671
7927
  this.elements.insertAfter(prevCreatedAt, value, executedAt);
7672
7928
  }
7673
7929
  /**
7674
- * `moveAfter` moves the given `createdAt` element after the `prevCreatedAt`.
7930
+ * `moveAfter` moves the given `createdAt` element after the
7931
+ * `prevCreatedAt`. Returns the dead position node for GC.
7675
7932
  */
7676
7933
  moveAfter(prevCreatedAt, createdAt, executedAt) {
7677
- this.elements.moveAfter(prevCreatedAt, createdAt, executedAt);
7934
+ return this.elements.moveAfter(prevCreatedAt, createdAt, executedAt);
7678
7935
  }
7679
7936
  /**
7680
7937
  * `get` returns the element of the given index.
@@ -7703,11 +7960,20 @@ class CRDTArray extends CRDTContainer {
7703
7960
  return this.elements.getLast();
7704
7961
  }
7705
7962
  /**
7706
- * `getPrevCreatedAt` returns the creation time of the previous node.
7963
+ * `getPrevCreatedAt` returns the creation time of the previous
7964
+ * node.
7707
7965
  */
7708
7966
  getPrevCreatedAt(createdAt) {
7709
7967
  return this.elements.getPrevCreatedAt(createdAt);
7710
7968
  }
7969
+ /**
7970
+ * `posCreatedAt` returns the createdAt of the position node
7971
+ * currently holding the element. Used to convert element identity
7972
+ * to position identity for moves.
7973
+ */
7974
+ posCreatedAt(elemCreatedAt) {
7975
+ return this.elements.posCreatedAt(elemCreatedAt);
7976
+ }
7711
7977
  /**
7712
7978
  * `delete` deletes the element of the given creation time.
7713
7979
  */
@@ -7721,7 +7987,8 @@ class CRDTArray extends CRDTContainer {
7721
7987
  return this.elements.deleteByIndex(index, editedAt);
7722
7988
  }
7723
7989
  /**
7724
- * `set` sets the given element at the given position of the creation time.
7990
+ * `set` sets the given element at the given position of the
7991
+ * creation time.
7725
7992
  */
7726
7993
  set(createdAt, value, executedAt) {
7727
7994
  return this.elements.set(createdAt, value, executedAt);
@@ -7739,18 +8006,19 @@ class CRDTArray extends CRDTContainer {
7739
8006
  return this.elements.length;
7740
8007
  }
7741
8008
  /**
7742
- * `[Symbol.iterator]` returns an iterator for the elements in this array.
8009
+ * `[Symbol.iterator]` returns an iterator for the elements in
8010
+ * this array.
7743
8011
  */
7744
8012
  *[Symbol.iterator]() {
7745
8013
  for (const node of this.elements) {
7746
- if (!node.isRemoved()) {
8014
+ if (node.getElementEntry() && !node.isRemoved()) {
7747
8015
  yield node.getValue();
7748
8016
  }
7749
8017
  }
7750
8018
  }
7751
8019
  /**
7752
- * `toTestString` returns a String containing the meta data of this value
7753
- * for debugging purpose.
8020
+ * `toTestString` returns a String containing the meta data of
8021
+ * this value for debugging purpose.
7754
8022
  */
7755
8023
  toTestString() {
7756
8024
  return this.elements.toTestString();
@@ -7760,6 +8028,9 @@ class CRDTArray extends CRDTContainer {
7760
8028
  */
7761
8029
  getDescendants(callback) {
7762
8030
  for (const node of this.elements) {
8031
+ if (!node.getElementEntry()) {
8032
+ continue;
8033
+ }
7763
8034
  const element = node.getValue();
7764
8035
  if (callback(element, this)) {
7765
8036
  return;
@@ -7821,21 +8092,52 @@ class CRDTArray extends CRDTContainer {
7821
8092
  return this.toJSON();
7822
8093
  }
7823
8094
  /**
7824
- * `getElements` returns an array of elements contained in this RGATreeList.
8095
+ * `getElements` returns the underlying RGATreeList.
7825
8096
  */
7826
8097
  getElements() {
7827
8098
  return this.elements;
7828
8099
  }
8100
+ /**
8101
+ * `getRGATreeList` returns the underlying RGATreeList (GCParent
8102
+ * for dead positions).
8103
+ */
8104
+ getRGATreeList() {
8105
+ return this.elements;
8106
+ }
8107
+ /**
8108
+ * `getAllRGANodes` returns all RGA nodes including dead position
8109
+ * nodes.
8110
+ */
8111
+ getAllRGANodes() {
8112
+ return this.elements.allNodes();
8113
+ }
7829
8114
  /**
7830
8115
  * `deepcopy` copies itself deeply.
7831
8116
  */
7832
8117
  deepcopy() {
7833
8118
  const clone = CRDTArray.create(this.getCreatedAt());
7834
8119
  for (const node of this.elements) {
7835
- clone.elements.insertAfter(
7836
- clone.getLastCreatedAt(),
7837
- node.getValue().deepcopy()
7838
- );
8120
+ if (!node.getElementEntry()) {
8121
+ const removedAt = node.getRemovedAt();
8122
+ if (removedAt) {
8123
+ clone.elements.addDeadPosition(
8124
+ node.getPositionCreatedAt(),
8125
+ removedAt
8126
+ );
8127
+ }
8128
+ continue;
8129
+ }
8130
+ const value = node.getValue().deepcopy();
8131
+ const posMovedAt = node.getPositionMovedAt();
8132
+ if (posMovedAt) {
8133
+ clone.elements.addMovedElement(
8134
+ value,
8135
+ node.getPositionCreatedAt(),
8136
+ posMovedAt
8137
+ );
8138
+ } else {
8139
+ clone.elements.insertAfter(clone.getLastCreatedAt(), value);
8140
+ }
7839
8141
  }
7840
8142
  clone.setRemovedAt(this.getRemovedAt());
7841
8143
  clone.setMovedAt(this.getMovedAt());
@@ -8092,6 +8394,9 @@ class SetOperation extends Operation {
8092
8394
  if (removed) {
8093
8395
  root.registerRemovedElement(removed);
8094
8396
  }
8397
+ if (value.getRemovedAt()) {
8398
+ root.registerRemovedElement(value);
8399
+ }
8095
8400
  return {
8096
8401
  opInfos: [
8097
8402
  {
@@ -8184,7 +8489,17 @@ class MoveOperation extends Operation {
8184
8489
  const array = parentObject;
8185
8490
  const reverseOp = this.toReverseOperation(array);
8186
8491
  const previousIndex = Number(array.subPathOf(this.createdAt));
8187
- array.moveAfter(this.prevCreatedAt, this.createdAt, this.getExecutedAt());
8492
+ const deadNode = array.moveAfter(
8493
+ this.prevCreatedAt,
8494
+ this.createdAt,
8495
+ this.getExecutedAt()
8496
+ );
8497
+ if (deadNode) {
8498
+ root.registerGCPair({
8499
+ parent: array.getRGATreeList(),
8500
+ child: deadNode
8501
+ });
8502
+ }
8188
8503
  const index = Number(array.subPathOf(this.createdAt));
8189
8504
  return {
8190
8505
  opInfos: [
@@ -8207,7 +8522,8 @@ class MoveOperation extends Operation {
8207
8522
  );
8208
8523
  }
8209
8524
  /**
8210
- * `getEffectedCreatedAt` returns the creation time of the effected element.
8525
+ * `getEffectedCreatedAt` returns the creation time of the
8526
+ * effected element.
8211
8527
  */
8212
8528
  getEffectedCreatedAt() {
8213
8529
  return this.createdAt;
@@ -8219,7 +8535,8 @@ class MoveOperation extends Operation {
8219
8535
  return `${this.getParentCreatedAt().toTestString()}.MOVE`;
8220
8536
  }
8221
8537
  /**
8222
- * `getPrevCreatedAt` returns the creation time of previous element.
8538
+ * `getPrevCreatedAt` returns the creation time of previous
8539
+ * element.
8223
8540
  */
8224
8541
  getPrevCreatedAt() {
8225
8542
  return this.prevCreatedAt;
@@ -8231,7 +8548,8 @@ class MoveOperation extends Operation {
8231
8548
  return this.createdAt;
8232
8549
  }
8233
8550
  /**
8234
- * `setPrevCreatedAt` sets the creation time of the previous element.
8551
+ * `setPrevCreatedAt` sets the creation time of the previous
8552
+ * element.
8235
8553
  */
8236
8554
  setPrevCreatedAt(createdAt) {
8237
8555
  this.prevCreatedAt = createdAt;
@@ -11575,7 +11893,7 @@ class CRDTTreeNode extends IndexTreeNode {
11575
11893
  CRDTTreeNodeID.of(issueTimeTicket(), 0),
11576
11894
  this.type,
11577
11895
  void 0,
11578
- void 0,
11896
+ this.attrs?.deepcopy(),
11579
11897
  this.removedAt
11580
11898
  );
11581
11899
  }
@@ -11995,6 +12313,53 @@ class CRDTTree extends CRDTElement {
11995
12313
  addDataSizes(diff, curr.getDataSize());
11996
12314
  }
11997
12315
  }
12316
+ if (tokenType === TokenType.Start && versionVector !== void 0) {
12317
+ let current = node;
12318
+ while (current.insNextID) {
12319
+ const next = this.findFloorNode(current.insNextID);
12320
+ if (!next || next.isText) {
12321
+ break;
12322
+ }
12323
+ if (ticketKnown(versionVector, next.id.getCreatedAt())) {
12324
+ break;
12325
+ }
12326
+ const siblingPairs = next.setAttrs(attributes, editedAt);
12327
+ const siblingAffectedAttrs = siblingPairs.reduce(
12328
+ (acc, [, curr]) => {
12329
+ if (curr) {
12330
+ acc[curr.getKey()] = attrs[curr.getKey()];
12331
+ }
12332
+ return acc;
12333
+ },
12334
+ {}
12335
+ );
12336
+ if (Object.keys(siblingAffectedAttrs).length > 0) {
12337
+ const parentOfNext = next.parent;
12338
+ const previousNext = next.prevSibling || parentOfNext;
12339
+ changes.push({
12340
+ type: "style",
12341
+ from: this.toIndex(parentOfNext, previousNext),
12342
+ to: this.toIndex(next, next),
12343
+ fromPath: this.toPath(parentOfNext, previousNext),
12344
+ toPath: this.toPath(next, next),
12345
+ actor: editedAt.getActorID(),
12346
+ value: siblingAffectedAttrs
12347
+ });
12348
+ }
12349
+ for (const [prev] of siblingPairs) {
12350
+ if (prev) {
12351
+ pairs.push({ parent: next, child: prev });
12352
+ }
12353
+ }
12354
+ for (const [key] of Object.entries(attrs)) {
12355
+ const curr = next.attrs?.getNodeMapByKey().get(key);
12356
+ if (curr !== void 0) {
12357
+ addDataSizes(diff, curr.getDataSize());
12358
+ }
12359
+ }
12360
+ current = next;
12361
+ }
12362
+ }
11998
12363
  }
11999
12364
  }
12000
12365
  );
@@ -12061,6 +12426,43 @@ class CRDTTree extends CRDTElement {
12061
12426
  toPath: this.toPath(node, node),
12062
12427
  value: attributesToRemove
12063
12428
  });
12429
+ if (tokenType === TokenType.Start && versionVector !== void 0) {
12430
+ let current = node;
12431
+ while (current.insNextID) {
12432
+ const next = this.findFloorNode(current.insNextID);
12433
+ if (!next || next.isText) {
12434
+ break;
12435
+ }
12436
+ if (ticketKnown(versionVector, next.id.getCreatedAt())) {
12437
+ break;
12438
+ }
12439
+ if (!next.attrs) {
12440
+ next.attrs = new RHT();
12441
+ }
12442
+ let removedAny = false;
12443
+ for (const value of attributesToRemove) {
12444
+ const nodesTobeRemoved = next.attrs.remove(value, editedAt);
12445
+ removedAny = removedAny || nodesTobeRemoved.length > 0;
12446
+ for (const rhtNode of nodesTobeRemoved) {
12447
+ pairs.push({ parent: next, child: rhtNode });
12448
+ }
12449
+ }
12450
+ if (removedAny) {
12451
+ const parentOfNext = next.parent;
12452
+ const previousNext = next.prevSibling || parentOfNext;
12453
+ changes.push({
12454
+ actor: editedAt.getActorID(),
12455
+ type: "removeStyle",
12456
+ from: this.toIndex(parentOfNext, previousNext),
12457
+ to: this.toIndex(next, next),
12458
+ fromPath: this.toPath(parentOfNext, previousNext),
12459
+ toPath: this.toPath(next, next),
12460
+ value: attributesToRemove
12461
+ });
12462
+ }
12463
+ current = next;
12464
+ }
12465
+ }
12064
12466
  }
12065
12467
  }
12066
12468
  );
@@ -14819,14 +15221,26 @@ function toRHTNodes(rht) {
14819
15221
  }
14820
15222
  return pbRHTNodes;
14821
15223
  }
14822
- function toRGANodes(rgaTreeList) {
15224
+ function toRGANodes(arr) {
14823
15225
  const pbRGANodes = [];
14824
- for (const rgaTreeListNode of rgaTreeList) {
14825
- pbRGANodes.push(
14826
- create(RGANodeSchema, {
14827
- element: toElement(rgaTreeListNode.getValue())
14828
- })
14829
- );
15226
+ for (const rgaNode of arr.getAllRGANodes()) {
15227
+ if (!rgaNode.getElementEntry()) {
15228
+ pbRGANodes.push(
15229
+ create(RGANodeSchema, {
15230
+ positionCreatedAt: toTimeTicket(rgaNode.getPositionCreatedAt()),
15231
+ positionRemovedAt: toTimeTicket(rgaNode.getRemovedAt())
15232
+ })
15233
+ );
15234
+ continue;
15235
+ }
15236
+ const pbNode = create(RGANodeSchema, {
15237
+ element: toElement(rgaNode.getValue())
15238
+ });
15239
+ if (rgaNode.getPositionMovedAt()) {
15240
+ pbNode.positionMovedAt = toTimeTicket(rgaNode.getPositionMovedAt());
15241
+ pbNode.positionCreatedAt = toTimeTicket(rgaNode.getPositionCreatedAt());
15242
+ }
15243
+ pbRGANodes.push(pbNode);
14830
15244
  }
14831
15245
  return pbRGANodes;
14832
15246
  }
@@ -14926,7 +15340,7 @@ function toArray(arr) {
14926
15340
  body: {
14927
15341
  case: "jsonArray",
14928
15342
  value: create(JSONElement_JSONArraySchema, {
14929
- nodes: toRGANodes(arr.getElements()),
15343
+ nodes: toRGANodes(arr),
14930
15344
  createdAt: toTimeTicket(arr.getCreatedAt()),
14931
15345
  movedAt: toTimeTicket(arr.getMovedAt()),
14932
15346
  removedAt: toTimeTicket(arr.getRemovedAt())
@@ -15464,7 +15878,32 @@ function fromObject(pbObject) {
15464
15878
  function fromArray(pbArray) {
15465
15879
  const rgaTreeList = new RGATreeList();
15466
15880
  for (const pbRGANode of pbArray.nodes) {
15467
- rgaTreeList.insert(fromElement(pbRGANode.element));
15881
+ if (!pbRGANode.element) {
15882
+ if (!pbRGANode.positionCreatedAt || !pbRGANode.positionRemovedAt) {
15883
+ throw new YorkieError(
15884
+ Code.ErrInvalidArgument,
15885
+ "dead RGA position node missing position timestamps"
15886
+ );
15887
+ }
15888
+ const posCreatedAt = fromTimeTicket(pbRGANode.positionCreatedAt);
15889
+ const posRemovedAt = fromTimeTicket(pbRGANode.positionRemovedAt);
15890
+ rgaTreeList.addDeadPosition(posCreatedAt, posRemovedAt);
15891
+ continue;
15892
+ }
15893
+ const elem = fromElement(pbRGANode.element);
15894
+ const posMovedAt = fromTimeTicket(pbRGANode.positionMovedAt);
15895
+ if (posMovedAt) {
15896
+ if (!pbRGANode.positionCreatedAt) {
15897
+ throw new YorkieError(
15898
+ Code.ErrInvalidArgument,
15899
+ "moved RGA node missing position_created_at"
15900
+ );
15901
+ }
15902
+ const posCreatedAt = fromTimeTicket(pbRGANode.positionCreatedAt);
15903
+ rgaTreeList.addMovedElement(elem, posCreatedAt, posMovedAt);
15904
+ } else {
15905
+ rgaTreeList.insert(elem);
15906
+ }
15468
15907
  }
15469
15908
  const arr = new CRDTArray(fromTimeTicket(pbArray.createdAt), rgaTreeList);
15470
15909
  arr.setMovedAt(fromTimeTicket(pbArray.movedAt));
@@ -16252,10 +16691,16 @@ class ArrayProxy {
16252
16691
  };
16253
16692
  } else if (method === "insertAfter") {
16254
16693
  return (prevID, value) => {
16694
+ let posCreatedAt;
16695
+ try {
16696
+ posCreatedAt = target.posCreatedAt(prevID);
16697
+ } catch {
16698
+ posCreatedAt = prevID;
16699
+ }
16255
16700
  const inserted = ArrayProxy.insertAfterInternal(
16256
16701
  context,
16257
16702
  target,
16258
- prevID,
16703
+ posCreatedAt,
16259
16704
  value
16260
16705
  );
16261
16706
  return toWrappedElement(context, inserted);
@@ -16440,7 +16885,7 @@ class ArrayProxy {
16440
16885
  static moveBeforeInternal(context, target, nextCreatedAt, createdAt) {
16441
16886
  const ticket = context.issueTimeTicket();
16442
16887
  const prevCreatedAt = target.getPrevCreatedAt(nextCreatedAt);
16443
- target.moveAfter(prevCreatedAt, createdAt, ticket);
16888
+ const deadNode = target.moveAfter(prevCreatedAt, createdAt, ticket);
16444
16889
  context.push(
16445
16890
  MoveOperation.create(
16446
16891
  target.getCreatedAt(),
@@ -16449,26 +16894,45 @@ class ArrayProxy {
16449
16894
  ticket
16450
16895
  )
16451
16896
  );
16897
+ if (deadNode) {
16898
+ context.registerGCPair({
16899
+ parent: target.getRGATreeList(),
16900
+ child: deadNode
16901
+ });
16902
+ }
16452
16903
  }
16453
16904
  /**
16454
16905
  * `moveAfterInternal` moves the given `createdAt` element
16455
- * after the specific element.
16906
+ * after the specific element. Converts element identity to
16907
+ * position identity for the prevCreatedAt.
16456
16908
  */
16457
16909
  static moveAfterInternal(context, target, prevCreatedAt, createdAt) {
16458
16910
  const ticket = context.issueTimeTicket();
16911
+ let posCreatedAt;
16912
+ try {
16913
+ posCreatedAt = target.posCreatedAt(prevCreatedAt);
16914
+ } catch {
16915
+ posCreatedAt = prevCreatedAt;
16916
+ }
16917
+ const deadNode = target.moveAfter(posCreatedAt, createdAt, ticket);
16459
16918
  context.push(
16460
16919
  MoveOperation.create(
16461
16920
  target.getCreatedAt(),
16462
- prevCreatedAt,
16921
+ posCreatedAt,
16463
16922
  createdAt,
16464
16923
  ticket
16465
16924
  )
16466
16925
  );
16467
- target.moveAfter(prevCreatedAt, createdAt, ticket);
16926
+ if (deadNode) {
16927
+ context.registerGCPair({
16928
+ parent: target.getRGATreeList(),
16929
+ child: deadNode
16930
+ });
16931
+ }
16468
16932
  }
16469
16933
  /**
16470
- * `moveAfterByIndexInternal` moves the given element to its new position
16471
- * after the given previous element.
16934
+ * `moveAfterByIndexInternal` moves the given element to its new
16935
+ * position after the given previous element.
16472
16936
  */
16473
16937
  static moveAfterByIndexInternal(context, target, prevIndex, targetIndex) {
16474
16938
  const prevElem = target.get(prevIndex);
@@ -16499,7 +16963,7 @@ class ArrayProxy {
16499
16963
  static moveFrontInternal(context, target, createdAt) {
16500
16964
  const ticket = context.issueTimeTicket();
16501
16965
  const head = target.getHead();
16502
- target.moveAfter(head.getCreatedAt(), createdAt, ticket);
16966
+ const deadNode = target.moveAfter(head.getCreatedAt(), createdAt, ticket);
16503
16967
  context.push(
16504
16968
  MoveOperation.create(
16505
16969
  target.getCreatedAt(),
@@ -16508,6 +16972,12 @@ class ArrayProxy {
16508
16972
  ticket
16509
16973
  )
16510
16974
  );
16975
+ if (deadNode) {
16976
+ context.registerGCPair({
16977
+ parent: target.getRGATreeList(),
16978
+ child: deadNode
16979
+ });
16980
+ }
16511
16981
  }
16512
16982
  /**
16513
16983
  * `moveLastInternal` moves the given `createdAt` element
@@ -16516,13 +16986,20 @@ class ArrayProxy {
16516
16986
  static moveLastInternal(context, target, createdAt) {
16517
16987
  const ticket = context.issueTimeTicket();
16518
16988
  const last = target.getLastCreatedAt();
16519
- target.moveAfter(last, createdAt, ticket);
16989
+ const deadNode = target.moveAfter(last, createdAt, ticket);
16520
16990
  context.push(
16521
16991
  MoveOperation.create(target.getCreatedAt(), last, createdAt, ticket)
16522
16992
  );
16993
+ if (deadNode) {
16994
+ context.registerGCPair({
16995
+ parent: target.getRGATreeList(),
16996
+ child: deadNode
16997
+ });
16998
+ }
16523
16999
  }
16524
17000
  /**
16525
- * `insertAfterInternal` inserts the value after the previously created element.
17001
+ * `insertAfterInternal` inserts the value after the previously
17002
+ * created element.
16526
17003
  */
16527
17004
  static insertAfterInternal(context, target, prevCreatedAt, value) {
16528
17005
  const createdAt = context.issueTimeTicket();
@@ -16550,12 +17027,13 @@ class ArrayProxy {
16550
17027
  `index out of bounds: ${index}`
16551
17028
  );
16552
17029
  }
16553
- ArrayProxy.insertAfterInternal(
16554
- context,
16555
- target,
16556
- prevElem.getCreatedAt(),
16557
- value
16558
- );
17030
+ let posCreatedAt;
17031
+ try {
17032
+ posCreatedAt = target.posCreatedAt(prevElem.getCreatedAt());
17033
+ } catch {
17034
+ posCreatedAt = prevElem.getCreatedAt();
17035
+ }
17036
+ ArrayProxy.insertAfterInternal(context, target, posCreatedAt, value);
16559
17037
  return target;
16560
17038
  }
16561
17039
  /**
@@ -16654,7 +17132,17 @@ class ArrayProxy {
16654
17132
  }
16655
17133
  }
16656
17134
  if (items) {
16657
- let previousID = from === 0 ? target.getHead().getID() : target.get(from - 1).getID();
17135
+ let previousID;
17136
+ if (from === 0) {
17137
+ previousID = target.getHead().getID();
17138
+ } else {
17139
+ const elemID = target.get(from - 1).getID();
17140
+ try {
17141
+ previousID = target.posCreatedAt(elemID);
17142
+ } catch {
17143
+ previousID = elemID;
17144
+ }
17145
+ }
16658
17146
  for (const item of items) {
16659
17147
  const newElem = ArrayProxy.insertAfterInternal(
16660
17148
  context,
@@ -18004,6 +18492,16 @@ class CRDTRoot {
18004
18492
  this.registerGCPair(pair);
18005
18493
  }
18006
18494
  }
18495
+ if (elem instanceof CRDTArray) {
18496
+ for (const node of elem.getAllRGANodes()) {
18497
+ if (!node.getElementEntry() && node.getRemovedAt()) {
18498
+ this.registerGCPair({
18499
+ parent: elem.getRGATreeList(),
18500
+ child: node
18501
+ });
18502
+ }
18503
+ }
18504
+ }
18007
18505
  return false;
18008
18506
  });
18009
18507
  }
@@ -19095,6 +19593,11 @@ class Document {
19095
19593
  if (logger.isEnabled(LogLevel.Trivial)) {
19096
19594
  logger.trivial(`trying to update a local change: ${this.toJSON()}`);
19097
19595
  }
19596
+ const prev = {
19597
+ hadPresence: this.presences.has(actorID),
19598
+ wasOnline: this.status === "attached",
19599
+ presence: this.presences.has(actorID) ? deepcopy(this.presences.get(actorID)) : void 0
19600
+ };
19098
19601
  const change = ctx.toChange();
19099
19602
  const { opInfos, reverseOps } = change.execute(
19100
19603
  this.root,
@@ -19140,14 +19643,14 @@ class Document {
19140
19643
  });
19141
19644
  }
19142
19645
  if (change.hasPresenceChange()) {
19143
- event.push({
19144
- type: "presence-changed",
19145
- source: OpSource.Local,
19146
- value: {
19147
- clientID: actorID,
19148
- presence: this.getPresence(actorID)
19149
- }
19150
- });
19646
+ const presenceEvent = this.reconcilePresence(
19647
+ actorID,
19648
+ prev,
19649
+ OpSource.Local
19650
+ );
19651
+ if (presenceEvent) {
19652
+ event.push(presenceEvent);
19653
+ }
19151
19654
  }
19152
19655
  this.publish(event);
19153
19656
  if (logger.isEnabled(LogLevel.Trivial)) {
@@ -19631,41 +20134,11 @@ class Document {
19631
20134
  change.execute(this.clone.root, this.clone.presences, source);
19632
20135
  const events = [];
19633
20136
  const actorID = change.getID().getActorID();
19634
- if (change.hasPresenceChange() && this.onlineClients.has(actorID)) {
19635
- const presenceChange = change.getPresenceChange();
19636
- switch (presenceChange.type) {
19637
- case PresenceChangeType.Put:
19638
- events.push(
19639
- this.presences.has(actorID) ? {
19640
- type: "presence-changed",
19641
- source,
19642
- value: {
19643
- clientID: actorID,
19644
- presence: presenceChange.presence
19645
- }
19646
- } : {
19647
- type: "watched",
19648
- source: OpSource.Remote,
19649
- value: {
19650
- clientID: actorID,
19651
- presence: presenceChange.presence
19652
- }
19653
- }
19654
- );
19655
- break;
19656
- case PresenceChangeType.Clear:
19657
- events.push({
19658
- type: "unwatched",
19659
- source: OpSource.Remote,
19660
- value: {
19661
- clientID: actorID,
19662
- presence: this.getPresence(actorID)
19663
- }
19664
- });
19665
- this.removeOnlineClient(actorID);
19666
- break;
19667
- }
19668
- }
20137
+ const prev = change.hasPresenceChange() ? {
20138
+ hadPresence: this.presences.has(actorID),
20139
+ wasOnline: this.onlineClients.has(actorID),
20140
+ presence: this.presences.has(actorID) ? deepcopy(this.presences.get(actorID)) : void 0
20141
+ } : void 0;
19669
20142
  const { opInfos, operations } = change.execute(
19670
20143
  this.root,
19671
20144
  this.presences,
@@ -19720,6 +20193,16 @@ class Document {
19720
20193
  }
19721
20194
  );
19722
20195
  }
20196
+ if (prev && change.hasPresenceChange()) {
20197
+ const presenceChange = change.getPresenceChange();
20198
+ if (presenceChange.type === PresenceChangeType.Clear) {
20199
+ this.removeOnlineClient(actorID);
20200
+ }
20201
+ const presenceEvent = this.reconcilePresence(actorID, prev, source);
20202
+ if (presenceEvent) {
20203
+ events.push(presenceEvent);
20204
+ }
20205
+ }
19723
20206
  if (events.length) {
19724
20207
  this.publish(events);
19725
20208
  }
@@ -19748,46 +20231,43 @@ class Document {
19748
20231
  * `applyDocEvent` applies the given doc event into this document.
19749
20232
  */
19750
20233
  applyDocEvent(type, publisher) {
19751
- const events = [];
20234
+ const prev = {
20235
+ hadPresence: this.presences.has(publisher),
20236
+ wasOnline: this.onlineClients.has(publisher),
20237
+ presence: this.presences.has(publisher) ? deepcopy(this.presences.get(publisher)) : void 0
20238
+ };
19752
20239
  if (type === DocEventType$1.DOCUMENT_WATCHED) {
19753
20240
  if (this.onlineClients.has(publisher) && this.hasPresence(publisher)) {
19754
20241
  return;
19755
20242
  }
19756
20243
  this.addOnlineClient(publisher);
19757
- if (this.hasPresence(publisher)) {
19758
- events.push({
19759
- type: "watched",
19760
- source: OpSource.Remote,
19761
- value: {
19762
- clientID: publisher,
19763
- presence: this.getPresence(publisher)
19764
- }
19765
- });
19766
- }
19767
20244
  } else if (type === DocEventType$1.DOCUMENT_UNWATCHED) {
19768
- const presence = this.getPresence(publisher);
19769
20245
  this.removeOnlineClient(publisher);
19770
20246
  this.presences.delete(publisher);
19771
- if (presence) {
19772
- events.push({
19773
- type: "unwatched",
19774
- source: OpSource.Remote,
19775
- value: { clientID: publisher, presence }
19776
- });
19777
- }
19778
20247
  }
19779
- if (events.length) {
19780
- this.publish(events);
20248
+ const event = this.reconcilePresence(publisher, prev, OpSource.Remote);
20249
+ if (event) {
20250
+ this.publish([event]);
19781
20251
  }
19782
20252
  }
19783
20253
  /**
19784
20254
  * `applyStatus` applies the document status into this document.
19785
20255
  */
19786
20256
  applyStatus(status) {
20257
+ const actorID = this.changeID.getActorID();
20258
+ const prev = {
20259
+ hadPresence: this.presences.has(actorID),
20260
+ wasOnline: this.status === "attached",
20261
+ presence: this.presences.has(actorID) ? deepcopy(this.presences.get(actorID)) : void 0
20262
+ };
19787
20263
  this.status = status;
19788
20264
  if (status === "detached") {
19789
20265
  this.setActor(InitialActorID);
19790
20266
  }
20267
+ const event = this.reconcilePresence(actorID, prev, OpSource.Local);
20268
+ if (event) {
20269
+ this.publish([event]);
20270
+ }
19791
20271
  this.publish([
19792
20272
  {
19793
20273
  source: status === "removed" ? OpSource.Remote : OpSource.Local,
@@ -19887,6 +20367,57 @@ class Document {
19887
20367
  removeOnlineClient(clientID) {
19888
20368
  this.onlineClients.delete(clientID);
19889
20369
  }
20370
+ /**
20371
+ * `reconcilePresence` compares the previous and current state of a client's
20372
+ * presence/online status and returns the appropriate event to emit.
20373
+ *
20374
+ * For remote clients, "online" means the client is in onlineClients.
20375
+ * For self, "online" means the document status is Attached.
20376
+ *
20377
+ * State transition table:
20378
+ * (!hadP || !wasOn) → (hasP && isOn) : watched (remote) or presence-changed (self)
20379
+ * (hadP && wasOn) → (hasP && isOn) : presence-changed
20380
+ * (hadP && wasOn) → (!hasP || !isOn): unwatched (remote only)
20381
+ * otherwise : no event (waiting)
20382
+ */
20383
+ reconcilePresence(actorID, prev, source) {
20384
+ const isSelf = actorID === this.changeID.getActorID();
20385
+ const hasPresence = this.presences.has(actorID);
20386
+ const isOnline = isSelf ? this.status === "attached" : this.onlineClients.has(actorID);
20387
+ if (!hasPresence || !isOnline) {
20388
+ if (prev.hadPresence && prev.wasOnline && !isSelf) {
20389
+ return {
20390
+ type: "unwatched",
20391
+ source: OpSource.Remote,
20392
+ value: {
20393
+ clientID: actorID,
20394
+ presence: prev.presence
20395
+ }
20396
+ };
20397
+ }
20398
+ return void 0;
20399
+ }
20400
+ const presence = deepcopy(this.presences.get(actorID));
20401
+ if (!prev.hadPresence || !prev.wasOnline) {
20402
+ if (isSelf) {
20403
+ return {
20404
+ type: "presence-changed",
20405
+ source,
20406
+ value: { clientID: actorID, presence }
20407
+ };
20408
+ }
20409
+ return {
20410
+ type: "watched",
20411
+ source: OpSource.Remote,
20412
+ value: { clientID: actorID, presence }
20413
+ };
20414
+ }
20415
+ return {
20416
+ type: "presence-changed",
20417
+ source,
20418
+ value: { clientID: actorID, presence }
20419
+ };
20420
+ }
19890
20421
  /**
19891
20422
  * `hasPresence` returns whether the given clientID has a presence or not.
19892
20423
  */
@@ -20048,18 +20579,24 @@ class Document {
20048
20579
  const ticket = ctx.issueTimeTicket();
20049
20580
  op.setExecutedAt(ticket);
20050
20581
  if (op instanceof ArraySetOperation) {
20051
- const prev = op.getCreatedAt();
20582
+ const prev2 = op.getCreatedAt();
20052
20583
  op.getValue().setCreatedAt(ticket);
20053
- this.internalHistory.reconcileCreatedAt(prev, ticket);
20584
+ this.internalHistory.reconcileCreatedAt(prev2, ticket);
20054
20585
  } else if (op instanceof AddOperation) {
20055
- const prev = op.getValue().getCreatedAt();
20586
+ const prev2 = op.getValue().getCreatedAt();
20056
20587
  op.getValue().setCreatedAt(ticket);
20057
- this.internalHistory.reconcileCreatedAt(prev, ticket);
20588
+ this.internalHistory.reconcileCreatedAt(prev2, ticket);
20058
20589
  }
20059
20590
  ctx.push(op);
20060
20591
  }
20061
20592
  const change = ctx.toChange();
20062
20593
  change.execute(this.clone.root, this.clone.presences, OpSource.UndoRedo);
20594
+ const actorID = this.changeID.getActorID();
20595
+ const prev = {
20596
+ hadPresence: this.presences.has(actorID),
20597
+ wasOnline: this.status === "attached",
20598
+ presence: this.presences.has(actorID) ? deepcopy(this.presences.get(actorID)) : void 0
20599
+ };
20063
20600
  const { opInfos, reverseOps } = change.execute(
20064
20601
  this.root,
20065
20602
  this.presences,
@@ -20081,7 +20618,6 @@ class Document {
20081
20618
  }
20082
20619
  this.localChanges.push(change);
20083
20620
  this.changeID = ctx.getNextID();
20084
- const actorID = this.changeID.getActorID();
20085
20621
  const events = [];
20086
20622
  if (opInfos.length) {
20087
20623
  events.push({
@@ -20098,14 +20634,14 @@ class Document {
20098
20634
  });
20099
20635
  }
20100
20636
  if (change.hasPresenceChange()) {
20101
- events.push({
20102
- type: "presence-changed",
20103
- source: OpSource.UndoRedo,
20104
- value: {
20105
- clientID: actorID,
20106
- presence: this.getPresence(actorID)
20107
- }
20108
- });
20637
+ const presenceEvent = this.reconcilePresence(
20638
+ actorID,
20639
+ prev,
20640
+ OpSource.UndoRedo
20641
+ );
20642
+ if (presenceEvent) {
20643
+ events.push(presenceEvent);
20644
+ }
20109
20645
  }
20110
20646
  this.publish(events);
20111
20647
  }
@@ -20121,6 +20657,8 @@ class Attachment {
20121
20657
  watchStream;
20122
20658
  watchLoopTimerID;
20123
20659
  watchAbortController;
20660
+ syncPromise;
20661
+ _detaching = false;
20124
20662
  constructor(reconnectStreamDelay, resource, resourceID, syncMode) {
20125
20663
  this.reconnectStreamDelay = reconnectStreamDelay;
20126
20664
  this.resource = resource;
@@ -20196,6 +20734,49 @@ class Attachment {
20196
20734
  };
20197
20735
  await doLoop();
20198
20736
  }
20737
+ /**
20738
+ * `markDetaching` marks this attachment as being in the process of detaching.
20739
+ * Once marked, the sync loop will skip this attachment.
20740
+ */
20741
+ markDetaching() {
20742
+ this._detaching = true;
20743
+ }
20744
+ /**
20745
+ * `isDetaching` returns whether this attachment is being detached.
20746
+ */
20747
+ isDetaching() {
20748
+ return this._detaching;
20749
+ }
20750
+ /**
20751
+ * `resetDetaching` resets the detaching flag so the attachment can resume
20752
+ * syncing. Used when a detach RPC fails and the document remains attached.
20753
+ */
20754
+ resetDetaching() {
20755
+ this._detaching = false;
20756
+ }
20757
+ /**
20758
+ * `setSyncPromise` sets the in-progress sync promise for this attachment.
20759
+ */
20760
+ setSyncPromise(promise) {
20761
+ this.syncPromise = promise;
20762
+ }
20763
+ /**
20764
+ * `clearSyncPromise` clears the in-progress sync promise.
20765
+ */
20766
+ clearSyncPromise() {
20767
+ this.syncPromise = void 0;
20768
+ }
20769
+ /**
20770
+ * `waitForSyncComplete` waits for any in-progress sync to complete.
20771
+ */
20772
+ async waitForSyncComplete() {
20773
+ if (this.syncPromise) {
20774
+ try {
20775
+ await this.syncPromise;
20776
+ } catch {
20777
+ }
20778
+ }
20779
+ }
20199
20780
  /**
20200
20781
  * `cancelWatchStream` cancels the watch stream.
20201
20782
  */
@@ -20230,7 +20811,7 @@ function createAuthInterceptor(apiKey, token) {
20230
20811
  };
20231
20812
  }
20232
20813
  const name = "@yorkie-js/sdk";
20233
- const version = "0.7.5";
20814
+ const version = "0.7.6";
20234
20815
  const pkg = {
20235
20816
  name,
20236
20817
  version
@@ -20555,6 +21136,7 @@ class Client {
20555
21136
  taskQueue;
20556
21137
  processing = false;
20557
21138
  keepalive = false;
21139
+ deactivating = false;
20558
21140
  /**
20559
21141
  * @param rpcAddr - the address of the RPC server.
20560
21142
  * @param opts - the options of the client.
@@ -20624,6 +21206,7 @@ class Client {
20624
21206
  );
20625
21207
  this.id = res.clientId;
20626
21208
  this.status = "activated";
21209
+ this.deactivating = false;
20627
21210
  this.runSyncLoop();
20628
21211
  logger.info(`[AC] c:"${this.getKey()}" activated, id:"${this.id}"`);
20629
21212
  if (typeof window !== "undefined") {
@@ -20652,6 +21235,7 @@ class Client {
20652
21235
  if (this.status === "deactivated") {
20653
21236
  return Promise.resolve();
20654
21237
  }
21238
+ this.deactivating = true;
20655
21239
  const task = async () => {
20656
21240
  try {
20657
21241
  await this.rpcClient.deactivateClient(
@@ -20665,6 +21249,7 @@ class Client {
20665
21249
  logger.info(`[DC] c"${this.getKey()}" deactivated`);
20666
21250
  } catch (err) {
20667
21251
  logger.error(`[DC] c:"${this.getKey()}" err :`, err);
21252
+ this.deactivating = false;
20668
21253
  await this.handleConnectError(err);
20669
21254
  throw err;
20670
21255
  }
@@ -20805,8 +21390,10 @@ class Client {
20805
21390
  );
20806
21391
  }
20807
21392
  doc.update((_, p) => p.clear());
21393
+ attachment.markDetaching();
20808
21394
  const task = async () => {
20809
21395
  try {
21396
+ await attachment.waitForSyncComplete();
20810
21397
  const res = await this.rpcClient.detachDocument(
20811
21398
  {
20812
21399
  clientId: this.id,
@@ -20825,6 +21412,7 @@ class Client {
20825
21412
  return doc;
20826
21413
  } catch (err) {
20827
21414
  logger.error(`[DD] c:"${this.getKey()}" err :`, err);
21415
+ attachment.resetDetaching();
20828
21416
  await this.handleConnectError(err);
20829
21417
  throw err;
20830
21418
  }
@@ -21391,7 +21979,7 @@ class Client {
21391
21979
  */
21392
21980
  runSyncLoop() {
21393
21981
  const doLoop = async () => {
21394
- if (!this.isActive()) {
21982
+ if (!this.isActive() || this.deactivating) {
21395
21983
  logger.debug(`[SL] c:"${this.getKey()}" exit sync loop`);
21396
21984
  this.conditions[
21397
21985
  "SyncLoop"
@@ -21403,43 +21991,62 @@ class Client {
21403
21991
  await this.enqueueTask(async () => {
21404
21992
  const syncs = [];
21405
21993
  for (const [, attachment] of this.attachmentMap) {
21994
+ if (this.deactivating) {
21995
+ break;
21996
+ }
21406
21997
  if (!attachment.needSync(this.channelHeartbeatInterval)) {
21407
21998
  continue;
21408
21999
  }
22000
+ if (attachment.isDetaching()) {
22001
+ continue;
22002
+ }
21409
22003
  if (attachment.changeEventReceived !== void 0) {
21410
22004
  attachment.changeEventReceived = false;
21411
22005
  }
21412
- syncs.push(
21413
- this.syncInternal(attachment, attachment.syncMode).catch((e) => {
21414
- if (isErrorCode(e, Code.ErrUnauthenticated)) {
21415
- attachment.resource.publish([
21416
- {
21417
- type: DocEventType.AuthError,
21418
- value: {
21419
- reason: errorMetadataOf(e).reason,
21420
- method: "PushPull"
21421
- }
22006
+ const syncPromise = this.syncInternal(
22007
+ attachment,
22008
+ attachment.syncMode
22009
+ ).then(() => {
22010
+ }).catch((e) => {
22011
+ if (isErrorCode(e, Code.ErrUnauthenticated)) {
22012
+ attachment.resource.publish([
22013
+ {
22014
+ type: DocEventType.AuthError,
22015
+ value: {
22016
+ reason: errorMetadataOf(e).reason,
22017
+ method: "PushPull"
21422
22018
  }
21423
- ]);
21424
- }
21425
- if (isErrorCode(e, Code.ErrEpochMismatch)) {
21426
- attachment.resource.publish([
21427
- {
21428
- type: DocEventType.EpochMismatch,
21429
- value: {
21430
- method: "PushPull"
21431
- }
22019
+ }
22020
+ ]);
22021
+ }
22022
+ if (isErrorCode(e, Code.ErrEpochMismatch)) {
22023
+ attachment.resource.publish([
22024
+ {
22025
+ type: DocEventType.EpochMismatch,
22026
+ value: {
22027
+ method: "PushPull"
21432
22028
  }
21433
- ]);
21434
- }
21435
- throw e;
21436
- })
21437
- );
22029
+ }
22030
+ ]);
22031
+ }
22032
+ throw e;
22033
+ }).finally(() => {
22034
+ attachment.clearSyncPromise();
22035
+ });
22036
+ attachment.setSyncPromise(syncPromise);
22037
+ syncs.push(syncPromise);
21438
22038
  }
21439
22039
  await Promise.all(syncs);
21440
22040
  setTimeout(doLoop, this.syncLoopDuration);
21441
22041
  });
21442
22042
  } catch (err) {
22043
+ if (this.deactivating) {
22044
+ this.conditions[
22045
+ "SyncLoop"
22046
+ /* SyncLoop */
22047
+ ] = false;
22048
+ return;
22049
+ }
21443
22050
  logger.error(`[SL] c:"${this.getKey()}" sync failed:`, err);
21444
22051
  if (await this.handleConnectError(err)) {
21445
22052
  setTimeout(doLoop, this.retrySyncLoopDelay);