@yorkie-js/sdk 0.7.5 → 0.7.7

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;
7306
+ }
7307
+ /**
7308
+ * `createWithElement` creates a new node that owns an element.
7309
+ */
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);
7289
7323
  }
7290
7324
  /**
7291
- * `createAfter` creates a new node after the given node.
7325
+ * `createAfter` creates a new node with the given element after
7326
+ * the given prev node.
7292
7327
  */
7293
- static createAfter(prev, value) {
7294
- const newNode = new RGATreeListNode(value);
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;
@@ -10812,6 +11130,32 @@ class IndexTreeNode {
10812
11130
  }
10813
11131
  actualRight.push(child);
10814
11132
  }
11133
+ if (versionVector) {
11134
+ const movedToLeft = [];
11135
+ const remaining = [];
11136
+ let boundaryReached = false;
11137
+ for (const child of actualRight) {
11138
+ if (!boundaryReached) {
11139
+ if (child.insPrevID !== void 0 && !child.isText) {
11140
+ remaining.push(child);
11141
+ continue;
11142
+ }
11143
+ const actorID = child.id.getCreatedAt().getActorID();
11144
+ const knownLamport = versionVector.get(actorID);
11145
+ if (knownLamport === void 0 || knownLamport < child.id.getCreatedAt().getLamport()) {
11146
+ movedToLeft.push(child);
11147
+ continue;
11148
+ }
11149
+ }
11150
+ boundaryReached = true;
11151
+ remaining.push(child);
11152
+ }
11153
+ if (movedToLeft.length > 0) {
11154
+ left.push(...movedToLeft);
11155
+ actualRight.length = 0;
11156
+ actualRight.push(...remaining);
11157
+ }
11158
+ }
10815
11159
  this._children = left;
10816
11160
  clone._children = actualRight;
10817
11161
  this.visibleSize = this._children.reduce(
@@ -11575,7 +11919,7 @@ class CRDTTreeNode extends IndexTreeNode {
11575
11919
  CRDTTreeNodeID.of(issueTimeTicket(), 0),
11576
11920
  this.type,
11577
11921
  void 0,
11578
- void 0,
11922
+ this.attrs?.deepcopy(),
11579
11923
  this.removedAt
11580
11924
  );
11581
11925
  }
@@ -11588,8 +11932,14 @@ class CRDTTreeNode extends IndexTreeNode {
11588
11932
  split.insPrevID = this.id;
11589
11933
  if (this.insNextID) {
11590
11934
  const insNext = tree.findFloorNode(this.insNextID);
11591
- insNext.insPrevID = split.id;
11592
11935
  split.insNextID = this.insNextID;
11936
+ if (insNext) {
11937
+ insNext.insPrevID = split.id;
11938
+ if (!this.isText && insNext.parent && !insNext.isRemoved && insNext.parent !== split.parent && split.allChildren.length === 0) {
11939
+ split.parent.detachChild(split);
11940
+ insNext.parent.insertBefore(split, insNext);
11941
+ }
11942
+ }
11593
11943
  }
11594
11944
  this.insNextID = split.id;
11595
11945
  tree.registerNode(split);
@@ -11813,7 +12163,7 @@ class CRDTTree extends CRDTElement {
11813
12163
  * given node, advancing past element-type split siblings that the editing
11814
12164
  * client did not know about (not in versionVector).
11815
12165
  */
11816
- advancePastUnknownSplitSiblings(node, versionVector) {
12166
+ advancePastUnknownSplitSiblings(node, versionVector, relaxParentCheck = false, skipActorID) {
11817
12167
  if (!versionVector || !node) {
11818
12168
  return node;
11819
12169
  }
@@ -11823,10 +12173,13 @@ class CRDTTree extends CRDTElement {
11823
12173
  if (!next || next.isText) {
11824
12174
  break;
11825
12175
  }
11826
- if (next.parent !== current.parent) {
12176
+ if (!relaxParentCheck && next.parent !== current.parent) {
11827
12177
  break;
11828
12178
  }
11829
12179
  const actorID = next.id.getCreatedAt().getActorID();
12180
+ if (skipActorID !== void 0 && actorID === skipActorID) {
12181
+ break;
12182
+ }
11830
12183
  const knownLamport = versionVector.get(actorID);
11831
12184
  if (knownLamport !== void 0 && knownLamport >= next.id.getCreatedAt().getLamport()) {
11832
12185
  break;
@@ -11995,6 +12348,53 @@ class CRDTTree extends CRDTElement {
11995
12348
  addDataSizes(diff, curr.getDataSize());
11996
12349
  }
11997
12350
  }
12351
+ if (tokenType === TokenType.Start && versionVector !== void 0) {
12352
+ let current = node;
12353
+ while (current.insNextID) {
12354
+ const next = this.findFloorNode(current.insNextID);
12355
+ if (!next || next.isText) {
12356
+ break;
12357
+ }
12358
+ if (ticketKnown(versionVector, next.id.getCreatedAt())) {
12359
+ break;
12360
+ }
12361
+ const siblingPairs = next.setAttrs(attributes, editedAt);
12362
+ const siblingAffectedAttrs = siblingPairs.reduce(
12363
+ (acc, [, curr]) => {
12364
+ if (curr) {
12365
+ acc[curr.getKey()] = attrs[curr.getKey()];
12366
+ }
12367
+ return acc;
12368
+ },
12369
+ {}
12370
+ );
12371
+ if (Object.keys(siblingAffectedAttrs).length > 0) {
12372
+ const parentOfNext = next.parent;
12373
+ const previousNext = next.prevSibling || parentOfNext;
12374
+ changes.push({
12375
+ type: "style",
12376
+ from: this.toIndex(parentOfNext, previousNext),
12377
+ to: this.toIndex(next, next),
12378
+ fromPath: this.toPath(parentOfNext, previousNext),
12379
+ toPath: this.toPath(next, next),
12380
+ actor: editedAt.getActorID(),
12381
+ value: siblingAffectedAttrs
12382
+ });
12383
+ }
12384
+ for (const [prev] of siblingPairs) {
12385
+ if (prev) {
12386
+ pairs.push({ parent: next, child: prev });
12387
+ }
12388
+ }
12389
+ for (const [key] of Object.entries(attrs)) {
12390
+ const curr = next.attrs?.getNodeMapByKey().get(key);
12391
+ if (curr !== void 0) {
12392
+ addDataSizes(diff, curr.getDataSize());
12393
+ }
12394
+ }
12395
+ current = next;
12396
+ }
12397
+ }
11998
12398
  }
11999
12399
  }
12000
12400
  );
@@ -12061,6 +12461,43 @@ class CRDTTree extends CRDTElement {
12061
12461
  toPath: this.toPath(node, node),
12062
12462
  value: attributesToRemove
12063
12463
  });
12464
+ if (tokenType === TokenType.Start && versionVector !== void 0) {
12465
+ let current = node;
12466
+ while (current.insNextID) {
12467
+ const next = this.findFloorNode(current.insNextID);
12468
+ if (!next || next.isText) {
12469
+ break;
12470
+ }
12471
+ if (ticketKnown(versionVector, next.id.getCreatedAt())) {
12472
+ break;
12473
+ }
12474
+ if (!next.attrs) {
12475
+ next.attrs = new RHT();
12476
+ }
12477
+ let removedAny = false;
12478
+ for (const value of attributesToRemove) {
12479
+ const nodesTobeRemoved = next.attrs.remove(value, editedAt);
12480
+ removedAny = removedAny || nodesTobeRemoved.length > 0;
12481
+ for (const rhtNode of nodesTobeRemoved) {
12482
+ pairs.push({ parent: next, child: rhtNode });
12483
+ }
12484
+ }
12485
+ if (removedAny) {
12486
+ const parentOfNext = next.parent;
12487
+ const previousNext = next.prevSibling || parentOfNext;
12488
+ changes.push({
12489
+ actor: editedAt.getActorID(),
12490
+ type: "removeStyle",
12491
+ from: this.toIndex(parentOfNext, previousNext),
12492
+ to: this.toIndex(next, next),
12493
+ fromPath: this.toPath(parentOfNext, previousNext),
12494
+ toPath: this.toPath(next, next),
12495
+ value: attributesToRemove
12496
+ });
12497
+ }
12498
+ current = next;
12499
+ }
12500
+ }
12064
12501
  }
12065
12502
  }
12066
12503
  );
@@ -12083,6 +12520,23 @@ class CRDTTree extends CRDTElement {
12083
12520
  addDataSizes(diff, diffTo, diffFrom);
12084
12521
  const fromLeft = fromLeftRaw !== fromParent ? this.advancePastUnknownSplitSiblings(fromLeftRaw, versionVector) : fromLeftRaw;
12085
12522
  const toLeft = toLeftRaw !== toParent ? this.advancePastUnknownSplitSiblings(toLeftRaw, versionVector) : toLeftRaw;
12523
+ let collectFromParent = fromParent;
12524
+ let collectFromLeft = fromLeft;
12525
+ if (fromLeft !== fromParent && fromParent !== toParent) {
12526
+ let current = fromLeft;
12527
+ while (current.insNextID) {
12528
+ const next = this.findFloorNode(current.insNextID);
12529
+ if (!next || next.isText) {
12530
+ break;
12531
+ }
12532
+ if (next.parent && next.parent === toParent) {
12533
+ collectFromLeft = next;
12534
+ collectFromParent = toParent;
12535
+ break;
12536
+ }
12537
+ current = next;
12538
+ }
12539
+ }
12086
12540
  const fromIdx = this.toIndex(fromParent, fromLeft);
12087
12541
  const fromPath = this.toPath(fromParent, fromLeft);
12088
12542
  const nodesToBeRemoved = [];
@@ -12091,8 +12545,8 @@ class CRDTTree extends CRDTElement {
12091
12545
  const toBeMergedNodes = [];
12092
12546
  const preTombstoned = /* @__PURE__ */ new Set();
12093
12547
  this.traverseInPosRange(
12094
- fromParent,
12095
- fromLeft,
12548
+ collectFromParent,
12549
+ collectFromLeft,
12096
12550
  toParent,
12097
12551
  toLeft,
12098
12552
  ([node, tokenType], ended) => {
@@ -12196,9 +12650,20 @@ class CRDTTree extends CRDTElement {
12196
12650
  let parent = fromParent;
12197
12651
  let left = fromLeft;
12198
12652
  while (splitCount < splitLevel) {
12653
+ if (left !== parent) {
12654
+ left = this.advancePastUnknownSplitSiblings(
12655
+ left,
12656
+ versionVector,
12657
+ true,
12658
+ editedAt.getActorID()
12659
+ );
12660
+ if (left.parent && left.parent !== parent) {
12661
+ parent = left.parent;
12662
+ }
12663
+ }
12199
12664
  parent.split(
12200
12665
  this,
12201
- parent.findOffset(left, true) + 1,
12666
+ left !== parent ? parent.findOffset(left, true) + 1 : 0,
12202
12667
  issueTimeTicket,
12203
12668
  versionVector
12204
12669
  );
@@ -12805,10 +13270,10 @@ class TreeEditOperation extends Operation {
12805
13270
  );
12806
13271
  this.lastToIdx = preEditFromIdx + removedSize;
12807
13272
  let reverseOp;
12808
- const isPureL1Split = this.splitLevel === 1 && !this.contents?.length && removedNodes.length === 0;
13273
+ const isPureSplit = this.splitLevel > 0 && !this.contents?.length && removedNodes.length === 0;
12809
13274
  if (this.splitLevel === 0) {
12810
13275
  reverseOp = this.toReverseOperation(tree, removedNodes, preEditFromIdx);
12811
- } else if (isPureL1Split) {
13276
+ } else if (isPureSplit) {
12812
13277
  reverseOp = this.toSplitReverseOperation(tree, preEditFromIdx);
12813
13278
  }
12814
13279
  root.acc(diff);
@@ -14819,14 +15284,26 @@ function toRHTNodes(rht) {
14819
15284
  }
14820
15285
  return pbRHTNodes;
14821
15286
  }
14822
- function toRGANodes(rgaTreeList) {
15287
+ function toRGANodes(arr) {
14823
15288
  const pbRGANodes = [];
14824
- for (const rgaTreeListNode of rgaTreeList) {
14825
- pbRGANodes.push(
14826
- create(RGANodeSchema, {
14827
- element: toElement(rgaTreeListNode.getValue())
14828
- })
14829
- );
15289
+ for (const rgaNode of arr.getAllRGANodes()) {
15290
+ if (!rgaNode.getElementEntry()) {
15291
+ pbRGANodes.push(
15292
+ create(RGANodeSchema, {
15293
+ positionCreatedAt: toTimeTicket(rgaNode.getPositionCreatedAt()),
15294
+ positionRemovedAt: toTimeTicket(rgaNode.getRemovedAt())
15295
+ })
15296
+ );
15297
+ continue;
15298
+ }
15299
+ const pbNode = create(RGANodeSchema, {
15300
+ element: toElement(rgaNode.getValue())
15301
+ });
15302
+ if (rgaNode.getPositionMovedAt()) {
15303
+ pbNode.positionMovedAt = toTimeTicket(rgaNode.getPositionMovedAt());
15304
+ pbNode.positionCreatedAt = toTimeTicket(rgaNode.getPositionCreatedAt());
15305
+ }
15306
+ pbRGANodes.push(pbNode);
14830
15307
  }
14831
15308
  return pbRGANodes;
14832
15309
  }
@@ -14926,7 +15403,7 @@ function toArray(arr) {
14926
15403
  body: {
14927
15404
  case: "jsonArray",
14928
15405
  value: create(JSONElement_JSONArraySchema, {
14929
- nodes: toRGANodes(arr.getElements()),
15406
+ nodes: toRGANodes(arr),
14930
15407
  createdAt: toTimeTicket(arr.getCreatedAt()),
14931
15408
  movedAt: toTimeTicket(arr.getMovedAt()),
14932
15409
  removedAt: toTimeTicket(arr.getRemovedAt())
@@ -15464,7 +15941,32 @@ function fromObject(pbObject) {
15464
15941
  function fromArray(pbArray) {
15465
15942
  const rgaTreeList = new RGATreeList();
15466
15943
  for (const pbRGANode of pbArray.nodes) {
15467
- rgaTreeList.insert(fromElement(pbRGANode.element));
15944
+ if (!pbRGANode.element) {
15945
+ if (!pbRGANode.positionCreatedAt || !pbRGANode.positionRemovedAt) {
15946
+ throw new YorkieError(
15947
+ Code.ErrInvalidArgument,
15948
+ "dead RGA position node missing position timestamps"
15949
+ );
15950
+ }
15951
+ const posCreatedAt = fromTimeTicket(pbRGANode.positionCreatedAt);
15952
+ const posRemovedAt = fromTimeTicket(pbRGANode.positionRemovedAt);
15953
+ rgaTreeList.addDeadPosition(posCreatedAt, posRemovedAt);
15954
+ continue;
15955
+ }
15956
+ const elem = fromElement(pbRGANode.element);
15957
+ const posMovedAt = fromTimeTicket(pbRGANode.positionMovedAt);
15958
+ if (posMovedAt) {
15959
+ if (!pbRGANode.positionCreatedAt) {
15960
+ throw new YorkieError(
15961
+ Code.ErrInvalidArgument,
15962
+ "moved RGA node missing position_created_at"
15963
+ );
15964
+ }
15965
+ const posCreatedAt = fromTimeTicket(pbRGANode.positionCreatedAt);
15966
+ rgaTreeList.addMovedElement(elem, posCreatedAt, posMovedAt);
15967
+ } else {
15968
+ rgaTreeList.insert(elem);
15969
+ }
15468
15970
  }
15469
15971
  const arr = new CRDTArray(fromTimeTicket(pbArray.createdAt), rgaTreeList);
15470
15972
  arr.setMovedAt(fromTimeTicket(pbArray.movedAt));
@@ -16252,10 +16754,16 @@ class ArrayProxy {
16252
16754
  };
16253
16755
  } else if (method === "insertAfter") {
16254
16756
  return (prevID, value) => {
16757
+ let posCreatedAt;
16758
+ try {
16759
+ posCreatedAt = target.posCreatedAt(prevID);
16760
+ } catch {
16761
+ posCreatedAt = prevID;
16762
+ }
16255
16763
  const inserted = ArrayProxy.insertAfterInternal(
16256
16764
  context,
16257
16765
  target,
16258
- prevID,
16766
+ posCreatedAt,
16259
16767
  value
16260
16768
  );
16261
16769
  return toWrappedElement(context, inserted);
@@ -16440,7 +16948,7 @@ class ArrayProxy {
16440
16948
  static moveBeforeInternal(context, target, nextCreatedAt, createdAt) {
16441
16949
  const ticket = context.issueTimeTicket();
16442
16950
  const prevCreatedAt = target.getPrevCreatedAt(nextCreatedAt);
16443
- target.moveAfter(prevCreatedAt, createdAt, ticket);
16951
+ const deadNode = target.moveAfter(prevCreatedAt, createdAt, ticket);
16444
16952
  context.push(
16445
16953
  MoveOperation.create(
16446
16954
  target.getCreatedAt(),
@@ -16449,26 +16957,45 @@ class ArrayProxy {
16449
16957
  ticket
16450
16958
  )
16451
16959
  );
16960
+ if (deadNode) {
16961
+ context.registerGCPair({
16962
+ parent: target.getRGATreeList(),
16963
+ child: deadNode
16964
+ });
16965
+ }
16452
16966
  }
16453
16967
  /**
16454
16968
  * `moveAfterInternal` moves the given `createdAt` element
16455
- * after the specific element.
16969
+ * after the specific element. Converts element identity to
16970
+ * position identity for the prevCreatedAt.
16456
16971
  */
16457
16972
  static moveAfterInternal(context, target, prevCreatedAt, createdAt) {
16458
16973
  const ticket = context.issueTimeTicket();
16974
+ let posCreatedAt;
16975
+ try {
16976
+ posCreatedAt = target.posCreatedAt(prevCreatedAt);
16977
+ } catch {
16978
+ posCreatedAt = prevCreatedAt;
16979
+ }
16980
+ const deadNode = target.moveAfter(posCreatedAt, createdAt, ticket);
16459
16981
  context.push(
16460
16982
  MoveOperation.create(
16461
16983
  target.getCreatedAt(),
16462
- prevCreatedAt,
16984
+ posCreatedAt,
16463
16985
  createdAt,
16464
16986
  ticket
16465
16987
  )
16466
16988
  );
16467
- target.moveAfter(prevCreatedAt, createdAt, ticket);
16989
+ if (deadNode) {
16990
+ context.registerGCPair({
16991
+ parent: target.getRGATreeList(),
16992
+ child: deadNode
16993
+ });
16994
+ }
16468
16995
  }
16469
16996
  /**
16470
- * `moveAfterByIndexInternal` moves the given element to its new position
16471
- * after the given previous element.
16997
+ * `moveAfterByIndexInternal` moves the given element to its new
16998
+ * position after the given previous element.
16472
16999
  */
16473
17000
  static moveAfterByIndexInternal(context, target, prevIndex, targetIndex) {
16474
17001
  const prevElem = target.get(prevIndex);
@@ -16499,7 +17026,7 @@ class ArrayProxy {
16499
17026
  static moveFrontInternal(context, target, createdAt) {
16500
17027
  const ticket = context.issueTimeTicket();
16501
17028
  const head = target.getHead();
16502
- target.moveAfter(head.getCreatedAt(), createdAt, ticket);
17029
+ const deadNode = target.moveAfter(head.getCreatedAt(), createdAt, ticket);
16503
17030
  context.push(
16504
17031
  MoveOperation.create(
16505
17032
  target.getCreatedAt(),
@@ -16508,6 +17035,12 @@ class ArrayProxy {
16508
17035
  ticket
16509
17036
  )
16510
17037
  );
17038
+ if (deadNode) {
17039
+ context.registerGCPair({
17040
+ parent: target.getRGATreeList(),
17041
+ child: deadNode
17042
+ });
17043
+ }
16511
17044
  }
16512
17045
  /**
16513
17046
  * `moveLastInternal` moves the given `createdAt` element
@@ -16516,13 +17049,20 @@ class ArrayProxy {
16516
17049
  static moveLastInternal(context, target, createdAt) {
16517
17050
  const ticket = context.issueTimeTicket();
16518
17051
  const last = target.getLastCreatedAt();
16519
- target.moveAfter(last, createdAt, ticket);
17052
+ const deadNode = target.moveAfter(last, createdAt, ticket);
16520
17053
  context.push(
16521
17054
  MoveOperation.create(target.getCreatedAt(), last, createdAt, ticket)
16522
17055
  );
17056
+ if (deadNode) {
17057
+ context.registerGCPair({
17058
+ parent: target.getRGATreeList(),
17059
+ child: deadNode
17060
+ });
17061
+ }
16523
17062
  }
16524
17063
  /**
16525
- * `insertAfterInternal` inserts the value after the previously created element.
17064
+ * `insertAfterInternal` inserts the value after the previously
17065
+ * created element.
16526
17066
  */
16527
17067
  static insertAfterInternal(context, target, prevCreatedAt, value) {
16528
17068
  const createdAt = context.issueTimeTicket();
@@ -16550,12 +17090,13 @@ class ArrayProxy {
16550
17090
  `index out of bounds: ${index}`
16551
17091
  );
16552
17092
  }
16553
- ArrayProxy.insertAfterInternal(
16554
- context,
16555
- target,
16556
- prevElem.getCreatedAt(),
16557
- value
16558
- );
17093
+ let posCreatedAt;
17094
+ try {
17095
+ posCreatedAt = target.posCreatedAt(prevElem.getCreatedAt());
17096
+ } catch {
17097
+ posCreatedAt = prevElem.getCreatedAt();
17098
+ }
17099
+ ArrayProxy.insertAfterInternal(context, target, posCreatedAt, value);
16559
17100
  return target;
16560
17101
  }
16561
17102
  /**
@@ -16654,7 +17195,17 @@ class ArrayProxy {
16654
17195
  }
16655
17196
  }
16656
17197
  if (items) {
16657
- let previousID = from === 0 ? target.getHead().getID() : target.get(from - 1).getID();
17198
+ let previousID;
17199
+ if (from === 0) {
17200
+ previousID = target.getHead().getID();
17201
+ } else {
17202
+ const elemID = target.get(from - 1).getID();
17203
+ try {
17204
+ previousID = target.posCreatedAt(elemID);
17205
+ } catch {
17206
+ previousID = elemID;
17207
+ }
17208
+ }
16658
17209
  for (const item of items) {
16659
17210
  const newElem = ArrayProxy.insertAfterInternal(
16660
17211
  context,
@@ -18004,6 +18555,16 @@ class CRDTRoot {
18004
18555
  this.registerGCPair(pair);
18005
18556
  }
18006
18557
  }
18558
+ if (elem instanceof CRDTArray) {
18559
+ for (const node of elem.getAllRGANodes()) {
18560
+ if (!node.getElementEntry() && node.getRemovedAt()) {
18561
+ this.registerGCPair({
18562
+ parent: elem.getRGATreeList(),
18563
+ child: node
18564
+ });
18565
+ }
18566
+ }
18567
+ }
18007
18568
  return false;
18008
18569
  });
18009
18570
  }
@@ -19095,6 +19656,11 @@ class Document {
19095
19656
  if (logger.isEnabled(LogLevel.Trivial)) {
19096
19657
  logger.trivial(`trying to update a local change: ${this.toJSON()}`);
19097
19658
  }
19659
+ const prev = {
19660
+ hadPresence: this.presences.has(actorID),
19661
+ wasOnline: this.status === "attached",
19662
+ presence: this.presences.has(actorID) ? deepcopy(this.presences.get(actorID)) : void 0
19663
+ };
19098
19664
  const change = ctx.toChange();
19099
19665
  const { opInfos, reverseOps } = change.execute(
19100
19666
  this.root,
@@ -19140,14 +19706,14 @@ class Document {
19140
19706
  });
19141
19707
  }
19142
19708
  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
- });
19709
+ const presenceEvent = this.reconcilePresence(
19710
+ actorID,
19711
+ prev,
19712
+ OpSource.Local
19713
+ );
19714
+ if (presenceEvent) {
19715
+ event.push(presenceEvent);
19716
+ }
19151
19717
  }
19152
19718
  this.publish(event);
19153
19719
  if (logger.isEnabled(LogLevel.Trivial)) {
@@ -19631,41 +20197,11 @@ class Document {
19631
20197
  change.execute(this.clone.root, this.clone.presences, source);
19632
20198
  const events = [];
19633
20199
  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
- }
20200
+ const prev = change.hasPresenceChange() ? {
20201
+ hadPresence: this.presences.has(actorID),
20202
+ wasOnline: this.onlineClients.has(actorID),
20203
+ presence: this.presences.has(actorID) ? deepcopy(this.presences.get(actorID)) : void 0
20204
+ } : void 0;
19669
20205
  const { opInfos, operations } = change.execute(
19670
20206
  this.root,
19671
20207
  this.presences,
@@ -19720,6 +20256,16 @@ class Document {
19720
20256
  }
19721
20257
  );
19722
20258
  }
20259
+ if (prev && change.hasPresenceChange()) {
20260
+ const presenceChange = change.getPresenceChange();
20261
+ if (presenceChange.type === PresenceChangeType.Clear) {
20262
+ this.removeOnlineClient(actorID);
20263
+ }
20264
+ const presenceEvent = this.reconcilePresence(actorID, prev, source);
20265
+ if (presenceEvent) {
20266
+ events.push(presenceEvent);
20267
+ }
20268
+ }
19723
20269
  if (events.length) {
19724
20270
  this.publish(events);
19725
20271
  }
@@ -19748,46 +20294,43 @@ class Document {
19748
20294
  * `applyDocEvent` applies the given doc event into this document.
19749
20295
  */
19750
20296
  applyDocEvent(type, publisher) {
19751
- const events = [];
20297
+ const prev = {
20298
+ hadPresence: this.presences.has(publisher),
20299
+ wasOnline: this.onlineClients.has(publisher),
20300
+ presence: this.presences.has(publisher) ? deepcopy(this.presences.get(publisher)) : void 0
20301
+ };
19752
20302
  if (type === DocEventType$1.DOCUMENT_WATCHED) {
19753
20303
  if (this.onlineClients.has(publisher) && this.hasPresence(publisher)) {
19754
20304
  return;
19755
20305
  }
19756
20306
  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
20307
  } else if (type === DocEventType$1.DOCUMENT_UNWATCHED) {
19768
- const presence = this.getPresence(publisher);
19769
20308
  this.removeOnlineClient(publisher);
19770
20309
  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
20310
  }
19779
- if (events.length) {
19780
- this.publish(events);
20311
+ const event = this.reconcilePresence(publisher, prev, OpSource.Remote);
20312
+ if (event) {
20313
+ this.publish([event]);
19781
20314
  }
19782
20315
  }
19783
20316
  /**
19784
20317
  * `applyStatus` applies the document status into this document.
19785
20318
  */
19786
20319
  applyStatus(status) {
20320
+ const actorID = this.changeID.getActorID();
20321
+ const prev = {
20322
+ hadPresence: this.presences.has(actorID),
20323
+ wasOnline: this.status === "attached",
20324
+ presence: this.presences.has(actorID) ? deepcopy(this.presences.get(actorID)) : void 0
20325
+ };
19787
20326
  this.status = status;
19788
20327
  if (status === "detached") {
19789
20328
  this.setActor(InitialActorID);
19790
20329
  }
20330
+ const event = this.reconcilePresence(actorID, prev, OpSource.Local);
20331
+ if (event) {
20332
+ this.publish([event]);
20333
+ }
19791
20334
  this.publish([
19792
20335
  {
19793
20336
  source: status === "removed" ? OpSource.Remote : OpSource.Local,
@@ -19887,6 +20430,57 @@ class Document {
19887
20430
  removeOnlineClient(clientID) {
19888
20431
  this.onlineClients.delete(clientID);
19889
20432
  }
20433
+ /**
20434
+ * `reconcilePresence` compares the previous and current state of a client's
20435
+ * presence/online status and returns the appropriate event to emit.
20436
+ *
20437
+ * For remote clients, "online" means the client is in onlineClients.
20438
+ * For self, "online" means the document status is Attached.
20439
+ *
20440
+ * State transition table:
20441
+ * (!hadP || !wasOn) → (hasP && isOn) : watched (remote) or presence-changed (self)
20442
+ * (hadP && wasOn) → (hasP && isOn) : presence-changed
20443
+ * (hadP && wasOn) → (!hasP || !isOn): unwatched (remote only)
20444
+ * otherwise : no event (waiting)
20445
+ */
20446
+ reconcilePresence(actorID, prev, source) {
20447
+ const isSelf = actorID === this.changeID.getActorID();
20448
+ const hasPresence = this.presences.has(actorID);
20449
+ const isOnline = isSelf ? this.status === "attached" : this.onlineClients.has(actorID);
20450
+ if (!hasPresence || !isOnline) {
20451
+ if (prev.hadPresence && prev.wasOnline && !isSelf) {
20452
+ return {
20453
+ type: "unwatched",
20454
+ source: OpSource.Remote,
20455
+ value: {
20456
+ clientID: actorID,
20457
+ presence: prev.presence
20458
+ }
20459
+ };
20460
+ }
20461
+ return void 0;
20462
+ }
20463
+ const presence = deepcopy(this.presences.get(actorID));
20464
+ if (!prev.hadPresence || !prev.wasOnline) {
20465
+ if (isSelf) {
20466
+ return {
20467
+ type: "presence-changed",
20468
+ source,
20469
+ value: { clientID: actorID, presence }
20470
+ };
20471
+ }
20472
+ return {
20473
+ type: "watched",
20474
+ source: OpSource.Remote,
20475
+ value: { clientID: actorID, presence }
20476
+ };
20477
+ }
20478
+ return {
20479
+ type: "presence-changed",
20480
+ source,
20481
+ value: { clientID: actorID, presence }
20482
+ };
20483
+ }
19890
20484
  /**
19891
20485
  * `hasPresence` returns whether the given clientID has a presence or not.
19892
20486
  */
@@ -20048,18 +20642,24 @@ class Document {
20048
20642
  const ticket = ctx.issueTimeTicket();
20049
20643
  op.setExecutedAt(ticket);
20050
20644
  if (op instanceof ArraySetOperation) {
20051
- const prev = op.getCreatedAt();
20645
+ const prev2 = op.getCreatedAt();
20052
20646
  op.getValue().setCreatedAt(ticket);
20053
- this.internalHistory.reconcileCreatedAt(prev, ticket);
20647
+ this.internalHistory.reconcileCreatedAt(prev2, ticket);
20054
20648
  } else if (op instanceof AddOperation) {
20055
- const prev = op.getValue().getCreatedAt();
20649
+ const prev2 = op.getValue().getCreatedAt();
20056
20650
  op.getValue().setCreatedAt(ticket);
20057
- this.internalHistory.reconcileCreatedAt(prev, ticket);
20651
+ this.internalHistory.reconcileCreatedAt(prev2, ticket);
20058
20652
  }
20059
20653
  ctx.push(op);
20060
20654
  }
20061
20655
  const change = ctx.toChange();
20062
20656
  change.execute(this.clone.root, this.clone.presences, OpSource.UndoRedo);
20657
+ const actorID = this.changeID.getActorID();
20658
+ const prev = {
20659
+ hadPresence: this.presences.has(actorID),
20660
+ wasOnline: this.status === "attached",
20661
+ presence: this.presences.has(actorID) ? deepcopy(this.presences.get(actorID)) : void 0
20662
+ };
20063
20663
  const { opInfos, reverseOps } = change.execute(
20064
20664
  this.root,
20065
20665
  this.presences,
@@ -20081,7 +20681,6 @@ class Document {
20081
20681
  }
20082
20682
  this.localChanges.push(change);
20083
20683
  this.changeID = ctx.getNextID();
20084
- const actorID = this.changeID.getActorID();
20085
20684
  const events = [];
20086
20685
  if (opInfos.length) {
20087
20686
  events.push({
@@ -20098,14 +20697,14 @@ class Document {
20098
20697
  });
20099
20698
  }
20100
20699
  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
- });
20700
+ const presenceEvent = this.reconcilePresence(
20701
+ actorID,
20702
+ prev,
20703
+ OpSource.UndoRedo
20704
+ );
20705
+ if (presenceEvent) {
20706
+ events.push(presenceEvent);
20707
+ }
20109
20708
  }
20110
20709
  this.publish(events);
20111
20710
  }
@@ -20121,6 +20720,8 @@ class Attachment {
20121
20720
  watchStream;
20122
20721
  watchLoopTimerID;
20123
20722
  watchAbortController;
20723
+ syncPromise;
20724
+ _detaching = false;
20124
20725
  constructor(reconnectStreamDelay, resource, resourceID, syncMode) {
20125
20726
  this.reconnectStreamDelay = reconnectStreamDelay;
20126
20727
  this.resource = resource;
@@ -20196,6 +20797,49 @@ class Attachment {
20196
20797
  };
20197
20798
  await doLoop();
20198
20799
  }
20800
+ /**
20801
+ * `markDetaching` marks this attachment as being in the process of detaching.
20802
+ * Once marked, the sync loop will skip this attachment.
20803
+ */
20804
+ markDetaching() {
20805
+ this._detaching = true;
20806
+ }
20807
+ /**
20808
+ * `isDetaching` returns whether this attachment is being detached.
20809
+ */
20810
+ isDetaching() {
20811
+ return this._detaching;
20812
+ }
20813
+ /**
20814
+ * `resetDetaching` resets the detaching flag so the attachment can resume
20815
+ * syncing. Used when a detach RPC fails and the document remains attached.
20816
+ */
20817
+ resetDetaching() {
20818
+ this._detaching = false;
20819
+ }
20820
+ /**
20821
+ * `setSyncPromise` sets the in-progress sync promise for this attachment.
20822
+ */
20823
+ setSyncPromise(promise) {
20824
+ this.syncPromise = promise;
20825
+ }
20826
+ /**
20827
+ * `clearSyncPromise` clears the in-progress sync promise.
20828
+ */
20829
+ clearSyncPromise() {
20830
+ this.syncPromise = void 0;
20831
+ }
20832
+ /**
20833
+ * `waitForSyncComplete` waits for any in-progress sync to complete.
20834
+ */
20835
+ async waitForSyncComplete() {
20836
+ if (this.syncPromise) {
20837
+ try {
20838
+ await this.syncPromise;
20839
+ } catch {
20840
+ }
20841
+ }
20842
+ }
20199
20843
  /**
20200
20844
  * `cancelWatchStream` cancels the watch stream.
20201
20845
  */
@@ -20230,7 +20874,7 @@ function createAuthInterceptor(apiKey, token) {
20230
20874
  };
20231
20875
  }
20232
20876
  const name = "@yorkie-js/sdk";
20233
- const version = "0.7.5";
20877
+ const version = "0.7.7";
20234
20878
  const pkg = {
20235
20879
  name,
20236
20880
  version
@@ -20555,6 +21199,7 @@ class Client {
20555
21199
  taskQueue;
20556
21200
  processing = false;
20557
21201
  keepalive = false;
21202
+ deactivating = false;
20558
21203
  /**
20559
21204
  * @param rpcAddr - the address of the RPC server.
20560
21205
  * @param opts - the options of the client.
@@ -20624,6 +21269,7 @@ class Client {
20624
21269
  );
20625
21270
  this.id = res.clientId;
20626
21271
  this.status = "activated";
21272
+ this.deactivating = false;
20627
21273
  this.runSyncLoop();
20628
21274
  logger.info(`[AC] c:"${this.getKey()}" activated, id:"${this.id}"`);
20629
21275
  if (typeof window !== "undefined") {
@@ -20652,6 +21298,7 @@ class Client {
20652
21298
  if (this.status === "deactivated") {
20653
21299
  return Promise.resolve();
20654
21300
  }
21301
+ this.deactivating = true;
20655
21302
  const task = async () => {
20656
21303
  try {
20657
21304
  await this.rpcClient.deactivateClient(
@@ -20665,6 +21312,7 @@ class Client {
20665
21312
  logger.info(`[DC] c"${this.getKey()}" deactivated`);
20666
21313
  } catch (err) {
20667
21314
  logger.error(`[DC] c:"${this.getKey()}" err :`, err);
21315
+ this.deactivating = false;
20668
21316
  await this.handleConnectError(err);
20669
21317
  throw err;
20670
21318
  }
@@ -20805,8 +21453,10 @@ class Client {
20805
21453
  );
20806
21454
  }
20807
21455
  doc.update((_, p) => p.clear());
21456
+ attachment.markDetaching();
20808
21457
  const task = async () => {
20809
21458
  try {
21459
+ await attachment.waitForSyncComplete();
20810
21460
  const res = await this.rpcClient.detachDocument(
20811
21461
  {
20812
21462
  clientId: this.id,
@@ -20825,6 +21475,7 @@ class Client {
20825
21475
  return doc;
20826
21476
  } catch (err) {
20827
21477
  logger.error(`[DD] c:"${this.getKey()}" err :`, err);
21478
+ attachment.resetDetaching();
20828
21479
  await this.handleConnectError(err);
20829
21480
  throw err;
20830
21481
  }
@@ -21391,7 +22042,7 @@ class Client {
21391
22042
  */
21392
22043
  runSyncLoop() {
21393
22044
  const doLoop = async () => {
21394
- if (!this.isActive()) {
22045
+ if (!this.isActive() || this.deactivating) {
21395
22046
  logger.debug(`[SL] c:"${this.getKey()}" exit sync loop`);
21396
22047
  this.conditions[
21397
22048
  "SyncLoop"
@@ -21403,43 +22054,62 @@ class Client {
21403
22054
  await this.enqueueTask(async () => {
21404
22055
  const syncs = [];
21405
22056
  for (const [, attachment] of this.attachmentMap) {
22057
+ if (this.deactivating) {
22058
+ break;
22059
+ }
21406
22060
  if (!attachment.needSync(this.channelHeartbeatInterval)) {
21407
22061
  continue;
21408
22062
  }
22063
+ if (attachment.isDetaching()) {
22064
+ continue;
22065
+ }
21409
22066
  if (attachment.changeEventReceived !== void 0) {
21410
22067
  attachment.changeEventReceived = false;
21411
22068
  }
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
- }
22069
+ const syncPromise = this.syncInternal(
22070
+ attachment,
22071
+ attachment.syncMode
22072
+ ).then(() => {
22073
+ }).catch((e) => {
22074
+ if (isErrorCode(e, Code.ErrUnauthenticated)) {
22075
+ attachment.resource.publish([
22076
+ {
22077
+ type: DocEventType.AuthError,
22078
+ value: {
22079
+ reason: errorMetadataOf(e).reason,
22080
+ method: "PushPull"
21422
22081
  }
21423
- ]);
21424
- }
21425
- if (isErrorCode(e, Code.ErrEpochMismatch)) {
21426
- attachment.resource.publish([
21427
- {
21428
- type: DocEventType.EpochMismatch,
21429
- value: {
21430
- method: "PushPull"
21431
- }
22082
+ }
22083
+ ]);
22084
+ }
22085
+ if (isErrorCode(e, Code.ErrEpochMismatch)) {
22086
+ attachment.resource.publish([
22087
+ {
22088
+ type: DocEventType.EpochMismatch,
22089
+ value: {
22090
+ method: "PushPull"
21432
22091
  }
21433
- ]);
21434
- }
21435
- throw e;
21436
- })
21437
- );
22092
+ }
22093
+ ]);
22094
+ }
22095
+ throw e;
22096
+ }).finally(() => {
22097
+ attachment.clearSyncPromise();
22098
+ });
22099
+ attachment.setSyncPromise(syncPromise);
22100
+ syncs.push(syncPromise);
21438
22101
  }
21439
22102
  await Promise.all(syncs);
21440
22103
  setTimeout(doLoop, this.syncLoopDuration);
21441
22104
  });
21442
22105
  } catch (err) {
22106
+ if (this.deactivating) {
22107
+ this.conditions[
22108
+ "SyncLoop"
22109
+ /* SyncLoop */
22110
+ ] = false;
22111
+ return;
22112
+ }
21443
22113
  logger.error(`[SL] c:"${this.getKey()}" sync failed:`, err);
21444
22114
  if (await this.handleConnectError(err)) {
21445
22115
  setTimeout(doLoop, this.retrySyncLoopDelay);
@@ -21920,8 +22590,11 @@ function isBinData(value) {
21920
22590
  function isCounter(value) {
21921
22591
  return typeof value === "object" && value !== null && value.type === "Counter" && typeof value.value === "object";
21922
22592
  }
22593
+ function isDedupCounter(value) {
22594
+ return typeof value === "object" && value !== null && value.type === "DedupCounter" && typeof value.value === "object" && typeof value.registers === "string";
22595
+ }
21923
22596
  function isObject(value) {
21924
- return typeof value === "object" && value !== null && !Array.isArray(value) && !isText(value) && !isTree(value) && !isInt(value) && !isLong(value) && !isDate(value) && !isBinData(value) && !isCounter(value);
22597
+ return typeof value === "object" && value !== null && !Array.isArray(value) && !isText(value) && !isTree(value) && !isInt(value) && !isLong(value) && !isDate(value) && !isBinData(value) && !isCounter(value) && !isDedupCounter(value);
21925
22598
  }
21926
22599
  function parse(yson) {
21927
22600
  try {
@@ -21937,6 +22610,12 @@ function parse(yson) {
21937
22610
  }
21938
22611
  function preprocessYSON(yson) {
21939
22612
  let result = yson;
22613
+ result = result.replace(
22614
+ /DedupCounter\(Int\((-?\d+)\),"([^"]+)"\)/g,
22615
+ (_, value, registers) => {
22616
+ return `{"__yson_type":"DedupCounter","__yson_data":{"__yson_type":"Int","__yson_data":${value}},"__yson_registers":"${registers}"}`;
22617
+ }
22618
+ );
21940
22619
  result = result.replace(
21941
22620
  /Counter\((Int|Long)\((-?\d+)\)\)/g,
21942
22621
  (_, type, value) => {
@@ -21997,6 +22676,20 @@ function postprocessValue(value) {
21997
22676
  value: value.__yson_data
21998
22677
  };
21999
22678
  }
22679
+ if (value.__yson_type === "DedupCounter" && typeof value.__yson_data === "object" && typeof value.__yson_registers === "string") {
22680
+ const counterValue = postprocessValue(value.__yson_data);
22681
+ if (typeof counterValue === "object" && counterValue !== null && "type" in counterValue && counterValue.type === "Int") {
22682
+ return {
22683
+ type: "DedupCounter",
22684
+ value: counterValue,
22685
+ registers: value.__yson_registers
22686
+ };
22687
+ }
22688
+ throw new YorkieError(
22689
+ Code.ErrInvalidArgument,
22690
+ "DedupCounter must contain Int"
22691
+ );
22692
+ }
22000
22693
  if (value.__yson_type === "Counter" && typeof value.__yson_data === "object") {
22001
22694
  const counterValue = postprocessValue(value.__yson_data);
22002
22695
  if (typeof counterValue === "object" && counterValue !== null && "type" in counterValue && (counterValue.type === "Int" || counterValue.type === "Long")) {
@@ -22085,6 +22778,7 @@ const YSON = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty
22085
22778
  isBinData,
22086
22779
  isCounter,
22087
22780
  isDate,
22781
+ isDedupCounter,
22088
22782
  isInt,
22089
22783
  isLong,
22090
22784
  isObject,