@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.
@@ -5792,7 +5792,7 @@
5792
5792
  }
5793
5793
  };
5794
5794
  }
5795
- const file_src_api_yorkie_v1_resources = /* @__PURE__ */ fileDesc("CiFzcmMvYXBpL3lvcmtpZS92MS9yZXNvdXJjZXMucHJvdG8SCXlvcmtpZS52MSKuAQoIU25hcHNob3QSJAoEcm9vdBgBIAEoCzIWLnlvcmtpZS52MS5KU09ORWxlbWVudBI1CglwcmVzZW5jZXMYAiADKAsyIi55b3JraWUudjEuU25hcHNob3QuUHJlc2VuY2VzRW50cnkaRQoOUHJlc2VuY2VzRW50cnkSCwoDa2V5GAEgASgJEiIKBXZhbHVlGAIgASgLMhMueW9ya2llLnYxLlByZXNlbmNlOgI4ASL7AQoKQ2hhbmdlUGFjaxIUCgxkb2N1bWVudF9rZXkYASABKAkSKQoKY2hlY2twb2ludBgCIAEoCzIVLnlvcmtpZS52MS5DaGVja3BvaW50EhAKCHNuYXBzaG90GAMgASgMEiIKB2NoYW5nZXMYBCADKAsyES55b3JraWUudjEuQ2hhbmdlEjAKEW1pbl9zeW5jZWRfdGlja2V0GAUgASgLMhUueW9ya2llLnYxLlRpbWVUaWNrZXQSEgoKaXNfcmVtb3ZlZBgGIAEoCBIwCg52ZXJzaW9uX3ZlY3RvchgHIAEoCzIYLnlvcmtpZS52MS5WZXJzaW9uVmVjdG9yIpgBCgZDaGFuZ2USHwoCaWQYASABKAsyEy55b3JraWUudjEuQ2hhbmdlSUQSDwoHbWVzc2FnZRgCIAEoCRIoCgpvcGVyYXRpb25zGAMgAygLMhQueW9ya2llLnYxLk9wZXJhdGlvbhIyCg9wcmVzZW5jZV9jaGFuZ2UYBCABKAsyGS55b3JraWUudjEuUHJlc2VuY2VDaGFuZ2UihwEKCENoYW5nZUlEEhIKCmNsaWVudF9zZXEYASABKA0SEgoKc2VydmVyX3NlcRgCIAEoAxIPCgdsYW1wb3J0GAMgASgDEhAKCGFjdG9yX2lkGAQgASgMEjAKDnZlcnNpb25fdmVjdG9yGAUgASgLMhgueW9ya2llLnYxLlZlcnNpb25WZWN0b3IidAoNVmVyc2lvblZlY3RvchI0CgZ2ZWN0b3IYASADKAsyJC55b3JraWUudjEuVmVyc2lvblZlY3Rvci5WZWN0b3JFbnRyeRotCgtWZWN0b3JFbnRyeRILCgNrZXkYASABKAkSDQoFdmFsdWUYAiABKAM6AjgBItkaCglPcGVyYXRpb24SJwoDc2V0GAEgASgLMhgueW9ya2llLnYxLk9wZXJhdGlvbi5TZXRIABInCgNhZGQYAiABKAsyGC55b3JraWUudjEuT3BlcmF0aW9uLkFkZEgAEikKBG1vdmUYAyABKAsyGS55b3JraWUudjEuT3BlcmF0aW9uLk1vdmVIABItCgZyZW1vdmUYBCABKAsyGy55b3JraWUudjEuT3BlcmF0aW9uLlJlbW92ZUgAEikKBGVkaXQYBSABKAsyGS55b3JraWUudjEuT3BlcmF0aW9uLkVkaXRIABIrCgVzdHlsZRgHIAEoCzIaLnlvcmtpZS52MS5PcGVyYXRpb24uU3R5bGVIABIxCghpbmNyZWFzZRgIIAEoCzIdLnlvcmtpZS52MS5PcGVyYXRpb24uSW5jcmVhc2VIABIyCgl0cmVlX2VkaXQYCSABKAsyHS55b3JraWUudjEuT3BlcmF0aW9uLlRyZWVFZGl0SAASNAoKdHJlZV9zdHlsZRgKIAEoCzIeLnlvcmtpZS52MS5PcGVyYXRpb24uVHJlZVN0eWxlSAASMgoJYXJyYXlfc2V0GAsgASgLMh0ueW9ya2llLnYxLk9wZXJhdGlvbi5BcnJheVNldEgAGp0BCgNTZXQSMAoRcGFyZW50X2NyZWF0ZWRfYXQYASABKAsyFS55b3JraWUudjEuVGltZVRpY2tldBILCgNrZXkYAiABKAkSKwoFdmFsdWUYAyABKAsyHC55b3JraWUudjEuSlNPTkVsZW1lbnRTaW1wbGUSKgoLZXhlY3V0ZWRfYXQYBCABKAsyFS55b3JraWUudjEuVGltZVRpY2tldBrAAQoDQWRkEjAKEXBhcmVudF9jcmVhdGVkX2F0GAEgASgLMhUueW9ya2llLnYxLlRpbWVUaWNrZXQSLgoPcHJldl9jcmVhdGVkX2F0GAIgASgLMhUueW9ya2llLnYxLlRpbWVUaWNrZXQSKwoFdmFsdWUYAyABKAsyHC55b3JraWUudjEuSlNPTkVsZW1lbnRTaW1wbGUSKgoLZXhlY3V0ZWRfYXQYBCABKAsyFS55b3JraWUudjEuVGltZVRpY2tldBq/AQoETW92ZRIwChFwYXJlbnRfY3JlYXRlZF9hdBgBIAEoCzIVLnlvcmtpZS52MS5UaW1lVGlja2V0Ei4KD3ByZXZfY3JlYXRlZF9hdBgCIAEoCzIVLnlvcmtpZS52MS5UaW1lVGlja2V0EikKCmNyZWF0ZWRfYXQYAyABKAsyFS55b3JraWUudjEuVGltZVRpY2tldBIqCgtleGVjdXRlZF9hdBgEIAEoCzIVLnlvcmtpZS52MS5UaW1lVGlja2V0GpEBCgZSZW1vdmUSMAoRcGFyZW50X2NyZWF0ZWRfYXQYASABKAsyFS55b3JraWUudjEuVGltZVRpY2tldBIpCgpjcmVhdGVkX2F0GAIgASgLMhUueW9ya2llLnYxLlRpbWVUaWNrZXQSKgoLZXhlY3V0ZWRfYXQYAyABKAsyFS55b3JraWUudjEuVGltZVRpY2tldBrZAwoERWRpdBIwChFwYXJlbnRfY3JlYXRlZF9hdBgBIAEoCzIVLnlvcmtpZS52MS5UaW1lVGlja2V0EiQKBGZyb20YAiABKAsyFi55b3JraWUudjEuVGV4dE5vZGVQb3MSIgoCdG8YAyABKAsyFi55b3JraWUudjEuVGV4dE5vZGVQb3MSUwoXY3JlYXRlZF9hdF9tYXBfYnlfYWN0b3IYBCADKAsyMi55b3JraWUudjEuT3BlcmF0aW9uLkVkaXQuQ3JlYXRlZEF0TWFwQnlBY3RvckVudHJ5Eg8KB2NvbnRlbnQYBSABKAkSKgoLZXhlY3V0ZWRfYXQYBiABKAsyFS55b3JraWUudjEuVGltZVRpY2tldBI9CgphdHRyaWJ1dGVzGAcgAygLMikueW9ya2llLnYxLk9wZXJhdGlvbi5FZGl0LkF0dHJpYnV0ZXNFbnRyeRpRChhDcmVhdGVkQXRNYXBCeUFjdG9yRW50cnkSCwoDa2V5GAEgASgJEiQKBXZhbHVlGAIgASgLMhUueW9ya2llLnYxLlRpbWVUaWNrZXQ6AjgBGjEKD0F0dHJpYnV0ZXNFbnRyeRILCgNrZXkYASABKAkSDQoFdmFsdWUYAiABKAk6AjgBGukDCgVTdHlsZRIwChFwYXJlbnRfY3JlYXRlZF9hdBgBIAEoCzIVLnlvcmtpZS52MS5UaW1lVGlja2V0EiQKBGZyb20YAiABKAsyFi55b3JraWUudjEuVGV4dE5vZGVQb3MSIgoCdG8YAyABKAsyFi55b3JraWUudjEuVGV4dE5vZGVQb3MSPgoKYXR0cmlidXRlcxgEIAMoCzIqLnlvcmtpZS52MS5PcGVyYXRpb24uU3R5bGUuQXR0cmlidXRlc0VudHJ5EioKC2V4ZWN1dGVkX2F0GAUgASgLMhUueW9ya2llLnYxLlRpbWVUaWNrZXQSVAoXY3JlYXRlZF9hdF9tYXBfYnlfYWN0b3IYBiADKAsyMy55b3JraWUudjEuT3BlcmF0aW9uLlN0eWxlLkNyZWF0ZWRBdE1hcEJ5QWN0b3JFbnRyeRIcChRhdHRyaWJ1dGVzX3RvX3JlbW92ZRgHIAMoCRoxCg9BdHRyaWJ1dGVzRW50cnkSCwoDa2V5GAEgASgJEg0KBXZhbHVlGAIgASgJOgI4ARpRChhDcmVhdGVkQXRNYXBCeUFjdG9yRW50cnkSCwoDa2V5GAEgASgJEiQKBXZhbHVlGAIgASgLMhUueW9ya2llLnYxLlRpbWVUaWNrZXQ6AjgBGqQBCghJbmNyZWFzZRIwChFwYXJlbnRfY3JlYXRlZF9hdBgBIAEoCzIVLnlvcmtpZS52MS5UaW1lVGlja2V0EisKBXZhbHVlGAIgASgLMhwueW9ya2llLnYxLkpTT05FbGVtZW50U2ltcGxlEioKC2V4ZWN1dGVkX2F0GAMgASgLMhUueW9ya2llLnYxLlRpbWVUaWNrZXQSDQoFYWN0b3IYBCABKAkakwMKCFRyZWVFZGl0EjAKEXBhcmVudF9jcmVhdGVkX2F0GAEgASgLMhUueW9ya2llLnYxLlRpbWVUaWNrZXQSIAoEZnJvbRgCIAEoCzISLnlvcmtpZS52MS5UcmVlUG9zEh4KAnRvGAMgASgLMhIueW9ya2llLnYxLlRyZWVQb3MSVwoXY3JlYXRlZF9hdF9tYXBfYnlfYWN0b3IYBCADKAsyNi55b3JraWUudjEuT3BlcmF0aW9uLlRyZWVFZGl0LkNyZWF0ZWRBdE1hcEJ5QWN0b3JFbnRyeRImCghjb250ZW50cxgFIAMoCzIULnlvcmtpZS52MS5UcmVlTm9kZXMSEwoLc3BsaXRfbGV2ZWwYByABKAUSKgoLZXhlY3V0ZWRfYXQYBiABKAsyFS55b3JraWUudjEuVGltZVRpY2tldBpRChhDcmVhdGVkQXRNYXBCeUFjdG9yRW50cnkSCwoDa2V5GAEgASgJEiQKBXZhbHVlGAIgASgLMhUueW9ya2llLnYxLlRpbWVUaWNrZXQ6AjgBGu0DCglUcmVlU3R5bGUSMAoRcGFyZW50X2NyZWF0ZWRfYXQYASABKAsyFS55b3JraWUudjEuVGltZVRpY2tldBIgCgRmcm9tGAIgASgLMhIueW9ya2llLnYxLlRyZWVQb3MSHgoCdG8YAyABKAsyEi55b3JraWUudjEuVHJlZVBvcxJCCgphdHRyaWJ1dGVzGAQgAygLMi4ueW9ya2llLnYxLk9wZXJhdGlvbi5UcmVlU3R5bGUuQXR0cmlidXRlc0VudHJ5EioKC2V4ZWN1dGVkX2F0GAUgASgLMhUueW9ya2llLnYxLlRpbWVUaWNrZXQSHAoUYXR0cmlidXRlc190b19yZW1vdmUYBiADKAkSWAoXY3JlYXRlZF9hdF9tYXBfYnlfYWN0b3IYByADKAsyNy55b3JraWUudjEuT3BlcmF0aW9uLlRyZWVTdHlsZS5DcmVhdGVkQXRNYXBCeUFjdG9yRW50cnkaMQoPQXR0cmlidXRlc0VudHJ5EgsKA2tleRgBIAEoCRINCgV2YWx1ZRgCIAEoCToCOAEaUQoYQ3JlYXRlZEF0TWFwQnlBY3RvckVudHJ5EgsKA2tleRgBIAEoCRIkCgV2YWx1ZRgCIAEoCzIVLnlvcmtpZS52MS5UaW1lVGlja2V0OgI4ARrAAQoIQXJyYXlTZXQSMAoRcGFyZW50X2NyZWF0ZWRfYXQYASABKAsyFS55b3JraWUudjEuVGltZVRpY2tldBIpCgpjcmVhdGVkX2F0GAIgASgLMhUueW9ya2llLnYxLlRpbWVUaWNrZXQSKwoFdmFsdWUYAyABKAsyHC55b3JraWUudjEuSlNPTkVsZW1lbnRTaW1wbGUSKgoLZXhlY3V0ZWRfYXQYBCABKAsyFS55b3JraWUudjEuVGltZVRpY2tldEIGCgRib2R5IsUBChFKU09ORWxlbWVudFNpbXBsZRIpCgpjcmVhdGVkX2F0GAEgASgLMhUueW9ya2llLnYxLlRpbWVUaWNrZXQSJwoIbW92ZWRfYXQYAiABKAsyFS55b3JraWUudjEuVGltZVRpY2tldBIpCgpyZW1vdmVkX2F0GAMgASgLMhUueW9ya2llLnYxLlRpbWVUaWNrZXQSIgoEdHlwZRgEIAEoDjIULnlvcmtpZS52MS5WYWx1ZVR5cGUSDQoFdmFsdWUYBSABKAwinwsKC0pTT05FbGVtZW50EjgKC2pzb25fb2JqZWN0GAEgASgLMiEueW9ya2llLnYxLkpTT05FbGVtZW50LkpTT05PYmplY3RIABI2Cgpqc29uX2FycmF5GAIgASgLMiAueW9ya2llLnYxLkpTT05FbGVtZW50LkpTT05BcnJheUgAEjUKCXByaW1pdGl2ZRgDIAEoCzIgLnlvcmtpZS52MS5KU09ORWxlbWVudC5QcmltaXRpdmVIABIrCgR0ZXh0GAUgASgLMhsueW9ya2llLnYxLkpTT05FbGVtZW50LlRleHRIABIxCgdjb3VudGVyGAYgASgLMh4ueW9ya2llLnYxLkpTT05FbGVtZW50LkNvdW50ZXJIABIrCgR0cmVlGAcgASgLMhsueW9ya2llLnYxLkpTT05FbGVtZW50LlRyZWVIABquAQoKSlNPTk9iamVjdBIhCgVub2RlcxgBIAMoCzISLnlvcmtpZS52MS5SSFROb2RlEikKCmNyZWF0ZWRfYXQYAiABKAsyFS55b3JraWUudjEuVGltZVRpY2tldBInCghtb3ZlZF9hdBgDIAEoCzIVLnlvcmtpZS52MS5UaW1lVGlja2V0EikKCnJlbW92ZWRfYXQYBCABKAsyFS55b3JraWUudjEuVGltZVRpY2tldBqtAQoJSlNPTkFycmF5EiEKBW5vZGVzGAEgAygLMhIueW9ya2llLnYxLlJHQU5vZGUSKQoKY3JlYXRlZF9hdBgCIAEoCzIVLnlvcmtpZS52MS5UaW1lVGlja2V0EicKCG1vdmVkX2F0GAMgASgLMhUueW9ya2llLnYxLlRpbWVUaWNrZXQSKQoKcmVtb3ZlZF9hdBgEIAEoCzIVLnlvcmtpZS52MS5UaW1lVGlja2V0Gr0BCglQcmltaXRpdmUSIgoEdHlwZRgBIAEoDjIULnlvcmtpZS52MS5WYWx1ZVR5cGUSDQoFdmFsdWUYAiABKAwSKQoKY3JlYXRlZF9hdBgDIAEoCzIVLnlvcmtpZS52MS5UaW1lVGlja2V0EicKCG1vdmVkX2F0GAQgASgLMhUueW9ya2llLnYxLlRpbWVUaWNrZXQSKQoKcmVtb3ZlZF9hdBgFIAEoCzIVLnlvcmtpZS52MS5UaW1lVGlja2V0GqkBCgRUZXh0EiIKBW5vZGVzGAEgAygLMhMueW9ya2llLnYxLlRleHROb2RlEikKCmNyZWF0ZWRfYXQYAiABKAsyFS55b3JraWUudjEuVGltZVRpY2tldBInCghtb3ZlZF9hdBgDIAEoCzIVLnlvcmtpZS52MS5UaW1lVGlja2V0EikKCnJlbW92ZWRfYXQYBCABKAsyFS55b3JraWUudjEuVGltZVRpY2tldBrYAQoHQ291bnRlchIiCgR0eXBlGAEgASgOMhQueW9ya2llLnYxLlZhbHVlVHlwZRINCgV2YWx1ZRgCIAEoDBIpCgpjcmVhdGVkX2F0GAMgASgLMhUueW9ya2llLnYxLlRpbWVUaWNrZXQSJwoIbW92ZWRfYXQYBCABKAsyFS55b3JraWUudjEuVGltZVRpY2tldBIpCgpyZW1vdmVkX2F0GAUgASgLMhUueW9ya2llLnYxLlRpbWVUaWNrZXQSFQoNaGxsX3JlZ2lzdGVycxgHIAEoDEoECAYQBxqpAQoEVHJlZRIiCgVub2RlcxgBIAMoCzITLnlvcmtpZS52MS5UcmVlTm9kZRIpCgpjcmVhdGVkX2F0GAIgASgLMhUueW9ya2llLnYxLlRpbWVUaWNrZXQSJwoIbW92ZWRfYXQYAyABKAsyFS55b3JraWUudjEuVGltZVRpY2tldBIpCgpyZW1vdmVkX2F0GAQgASgLMhUueW9ya2llLnYxLlRpbWVUaWNrZXRCBgoEYm9keSI/CgdSSFROb2RlEgsKA2tleRgBIAEoCRInCgdlbGVtZW50GAIgASgLMhYueW9ya2llLnYxLkpTT05FbGVtZW50IlQKB1JHQU5vZGUSIAoEbmV4dBgBIAEoCzISLnlvcmtpZS52MS5SR0FOb2RlEicKB2VsZW1lbnQYAiABKAsyFi55b3JraWUudjEuSlNPTkVsZW1lbnQiWAoITm9kZUF0dHISDQoFdmFsdWUYASABKAkSKQoKdXBkYXRlZF9hdBgCIAEoCzIVLnlvcmtpZS52MS5UaW1lVGlja2V0EhIKCmlzX3JlbW92ZWQYAyABKAgilAIKCFRleHROb2RlEiEKAmlkGAEgASgLMhUueW9ya2llLnYxLlRleHROb2RlSUQSDQoFdmFsdWUYAiABKAkSKQoKcmVtb3ZlZF9hdBgDIAEoCzIVLnlvcmtpZS52MS5UaW1lVGlja2V0EioKC2luc19wcmV2X2lkGAQgASgLMhUueW9ya2llLnYxLlRleHROb2RlSUQSNwoKYXR0cmlidXRlcxgFIAMoCzIjLnlvcmtpZS52MS5UZXh0Tm9kZS5BdHRyaWJ1dGVzRW50cnkaRgoPQXR0cmlidXRlc0VudHJ5EgsKA2tleRgBIAEoCRIiCgV2YWx1ZRgCIAEoCzITLnlvcmtpZS52MS5Ob2RlQXR0cjoCOAEiRwoKVGV4dE5vZGVJRBIpCgpjcmVhdGVkX2F0GAEgASgLMhUueW9ya2llLnYxLlRpbWVUaWNrZXQSDgoGb2Zmc2V0GAIgASgFIrMDCghUcmVlTm9kZRIhCgJpZBgBIAEoCzIVLnlvcmtpZS52MS5UcmVlTm9kZUlEEgwKBHR5cGUYAiABKAkSDQoFdmFsdWUYAyABKAkSKQoKcmVtb3ZlZF9hdBgEIAEoCzIVLnlvcmtpZS52MS5UaW1lVGlja2V0EioKC2luc19wcmV2X2lkGAUgASgLMhUueW9ya2llLnYxLlRyZWVOb2RlSUQSKgoLaW5zX25leHRfaWQYBiABKAsyFS55b3JraWUudjEuVHJlZU5vZGVJRBINCgVkZXB0aBgHIAEoBRI3CgphdHRyaWJ1dGVzGAggAygLMiMueW9ya2llLnYxLlRyZWVOb2RlLkF0dHJpYnV0ZXNFbnRyeRIqCgttZXJnZWRfZnJvbRgJIAEoCzIVLnlvcmtpZS52MS5UcmVlTm9kZUlEEigKCW1lcmdlZF9hdBgKIAEoCzIVLnlvcmtpZS52MS5UaW1lVGlja2V0GkYKD0F0dHJpYnV0ZXNFbnRyeRILCgNrZXkYASABKAkSIgoFdmFsdWUYAiABKAsyEy55b3JraWUudjEuTm9kZUF0dHI6AjgBIjEKCVRyZWVOb2RlcxIkCgdjb250ZW50GAEgAygLMhMueW9ya2llLnYxLlRyZWVOb2RlIkcKClRyZWVOb2RlSUQSKQoKY3JlYXRlZF9hdBgBIAEoCzIVLnlvcmtpZS52MS5UaW1lVGlja2V0Eg4KBm9mZnNldBgCIAEoBSJjCgdUcmVlUG9zEigKCXBhcmVudF9pZBgBIAEoCzIVLnlvcmtpZS52MS5UcmVlTm9kZUlEEi4KD2xlZnRfc2libGluZ19pZBgCIAEoCzIVLnlvcmtpZS52MS5UcmVlTm9kZUlEImsKBFVzZXISCgoCaWQYASABKAkSFQoNYXV0aF9wcm92aWRlchgCIAEoCRIQCgh1c2VybmFtZRgDIAEoCRIuCgpjcmVhdGVkX2F0GAQgASgLMhouZ29vZ2xlLnByb3RvYnVmLlRpbWVzdGFtcCKJAQoGTWVtYmVyEgoKAmlkGAEgASgJEhIKCnByb2plY3RfaWQYAiABKAkSDwoHdXNlcl9pZBgDIAEoCRIQCgh1c2VybmFtZRgEIAEoCRIMCgRyb2xlGAUgASgJEi4KCmludml0ZWRfYXQYBiABKAsyGi5nb29nbGUucHJvdG9idWYuVGltZXN0YW1wIukGCgdQcm9qZWN0EgoKAmlkGAEgASgJEgwKBG5hbWUYAiABKAkSEgoKcHVibGljX2tleRgDIAEoCRISCgpzZWNyZXRfa2V5GAQgASgJEhgKEGF1dGhfd2ViaG9va191cmwYBSABKAkSHAoUYXV0aF93ZWJob29rX21ldGhvZHMYBiADKAkSIAoYYXV0aF93ZWJob29rX21heF9yZXRyaWVzGBEgASgEEiYKHmF1dGhfd2ViaG9va19taW5fd2FpdF9pbnRlcnZhbBgSIAEoCRImCh5hdXRoX3dlYmhvb2tfbWF4X3dhaXRfaW50ZXJ2YWwYEyABKAkSJAocYXV0aF93ZWJob29rX3JlcXVlc3RfdGltZW91dBgUIAEoCRIZChFldmVudF93ZWJob29rX3VybBgHIAEoCRIcChRldmVudF93ZWJob29rX2V2ZW50cxgIIAMoCRIhChlldmVudF93ZWJob29rX21heF9yZXRyaWVzGBUgASgEEicKH2V2ZW50X3dlYmhvb2tfbWluX3dhaXRfaW50ZXJ2YWwYFiABKAkSJwofZXZlbnRfd2ViaG9va19tYXhfd2FpdF9pbnRlcnZhbBgXIAEoCRIlCh1ldmVudF93ZWJob29rX3JlcXVlc3RfdGltZW91dBgYIAEoCRIjChtjbGllbnRfZGVhY3RpdmF0ZV90aHJlc2hvbGQYCSABKAkSGgoSc25hcHNob3RfdGhyZXNob2xkGBkgASgDEhkKEXNuYXBzaG90X2ludGVydmFsGBogASgDEiQKHG1heF9zdWJzY3JpYmVyc19wZXJfZG9jdW1lbnQYCiABKAUSJAocbWF4X2F0dGFjaG1lbnRzX3Blcl9kb2N1bWVudBgLIAEoBRIdChVtYXhfc2l6ZV9wZXJfZG9jdW1lbnQYDyABKAUSGAoQcmVtb3ZlX29uX2RldGFjaBgQIAEoCBIdChVhdXRvX3JldmlzaW9uX2VuYWJsZWQYGyABKAgSFwoPYWxsb3dlZF9vcmlnaW5zGA4gAygJEi4KCmNyZWF0ZWRfYXQYDCABKAsyGi5nb29nbGUucHJvdG9idWYuVGltZXN0YW1wEi4KCnVwZGF0ZWRfYXQYDSABKAsyGi5nb29nbGUucHJvdG9idWYuVGltZXN0YW1wIi8KC01ldHJpY1BvaW50EhEKCXRpbWVzdGFtcBgBIAEoAxINCgV2YWx1ZRgCIAEoBSKjDAoWVXBkYXRhYmxlUHJvamVjdEZpZWxkcxIqCgRuYW1lGAEgASgLMhwuZ29vZ2xlLnByb3RvYnVmLlN0cmluZ1ZhbHVlEjYKEGF1dGhfd2ViaG9va191cmwYAiABKAsyHC5nb29nbGUucHJvdG9idWYuU3RyaW5nVmFsdWUSUgoUYXV0aF93ZWJob29rX21ldGhvZHMYAyABKAsyNC55b3JraWUudjEuVXBkYXRhYmxlUHJvamVjdEZpZWxkcy5BdXRoV2ViaG9va01ldGhvZHMSPgoYYXV0aF93ZWJob29rX21heF9yZXRyaWVzGAwgASgLMhwuZ29vZ2xlLnByb3RvYnVmLlVJbnQ2NFZhbHVlEkQKHmF1dGhfd2ViaG9va19taW5fd2FpdF9pbnRlcnZhbBgNIAEoCzIcLmdvb2dsZS5wcm90b2J1Zi5TdHJpbmdWYWx1ZRJECh5hdXRoX3dlYmhvb2tfbWF4X3dhaXRfaW50ZXJ2YWwYDiABKAsyHC5nb29nbGUucHJvdG9idWYuU3RyaW5nVmFsdWUSQgocYXV0aF93ZWJob29rX3JlcXVlc3RfdGltZW91dBgPIAEoCzIcLmdvb2dsZS5wcm90b2J1Zi5TdHJpbmdWYWx1ZRI3ChFldmVudF93ZWJob29rX3VybBgEIAEoCzIcLmdvb2dsZS5wcm90b2J1Zi5TdHJpbmdWYWx1ZRJSChRldmVudF93ZWJob29rX2V2ZW50cxgFIAEoCzI0LnlvcmtpZS52MS5VcGRhdGFibGVQcm9qZWN0RmllbGRzLkV2ZW50V2ViaG9va0V2ZW50cxI/ChlldmVudF93ZWJob29rX21heF9yZXRyaWVzGBAgASgLMhwuZ29vZ2xlLnByb3RvYnVmLlVJbnQ2NFZhbHVlEkUKH2V2ZW50X3dlYmhvb2tfbWluX3dhaXRfaW50ZXJ2YWwYESABKAsyHC5nb29nbGUucHJvdG9idWYuU3RyaW5nVmFsdWUSRQofZXZlbnRfd2ViaG9va19tYXhfd2FpdF9pbnRlcnZhbBgSIAEoCzIcLmdvb2dsZS5wcm90b2J1Zi5TdHJpbmdWYWx1ZRJDCh1ldmVudF93ZWJob29rX3JlcXVlc3RfdGltZW91dBgTIAEoCzIcLmdvb2dsZS5wcm90b2J1Zi5TdHJpbmdWYWx1ZRI3ChJzbmFwc2hvdF90aHJlc2hvbGQYFCABKAsyGy5nb29nbGUucHJvdG9idWYuSW50NjRWYWx1ZRI2ChFzbmFwc2hvdF9pbnRlcnZhbBgVIAEoCzIbLmdvb2dsZS5wcm90b2J1Zi5JbnQ2NFZhbHVlEkEKG2NsaWVudF9kZWFjdGl2YXRlX3RocmVzaG9sZBgGIAEoCzIcLmdvb2dsZS5wcm90b2J1Zi5TdHJpbmdWYWx1ZRJBChxtYXhfc3Vic2NyaWJlcnNfcGVyX2RvY3VtZW50GAcgASgLMhsuZ29vZ2xlLnByb3RvYnVmLkludDMyVmFsdWUSQQocbWF4X2F0dGFjaG1lbnRzX3Blcl9kb2N1bWVudBgIIAEoCzIbLmdvb2dsZS5wcm90b2J1Zi5JbnQzMlZhbHVlEjoKFW1heF9zaXplX3Blcl9kb2N1bWVudBgKIAEoCzIbLmdvb2dsZS5wcm90b2J1Zi5JbnQzMlZhbHVlEjQKEHJlbW92ZV9vbl9kZXRhY2gYCyABKAsyGi5nb29nbGUucHJvdG9idWYuQm9vbFZhbHVlEjkKFWF1dG9fcmV2aXNpb25fZW5hYmxlZBgWIAEoCzIaLmdvb2dsZS5wcm90b2J1Zi5Cb29sVmFsdWUSSQoPYWxsb3dlZF9vcmlnaW5zGAkgASgLMjAueW9ya2llLnYxLlVwZGF0YWJsZVByb2plY3RGaWVsZHMuQWxsb3dlZE9yaWdpbnMaJQoSQXV0aFdlYmhvb2tNZXRob2RzEg8KB21ldGhvZHMYASADKAkaJAoSRXZlbnRXZWJob29rRXZlbnRzEg4KBmV2ZW50cxgBIAMoCRohCg5BbGxvd2VkT3JpZ2lucxIPCgdvcmlnaW5zGAEgAygJIqcDCg9Eb2N1bWVudFN1bW1hcnkSCgoCaWQYASABKAkSCwoDa2V5GAIgASgJEgwKBHJvb3QYAyABKAkSGAoQYXR0YWNoZWRfY2xpZW50cxgHIAEoBRIpCg1kb2N1bWVudF9zaXplGAggASgLMhIueW9ya2llLnYxLkRvY1NpemUSEgoKc2NoZW1hX2tleRgJIAEoCRI8CglwcmVzZW5jZXMYCiADKAsyKS55b3JraWUudjEuRG9jdW1lbnRTdW1tYXJ5LlByZXNlbmNlc0VudHJ5Ei4KCmNyZWF0ZWRfYXQYBCABKAsyGi5nb29nbGUucHJvdG9idWYuVGltZXN0YW1wEi8KC2FjY2Vzc2VkX2F0GAUgASgLMhouZ29vZ2xlLnByb3RvYnVmLlRpbWVzdGFtcBIuCgp1cGRhdGVkX2F0GAYgASgLMhouZ29vZ2xlLnByb3RvYnVmLlRpbWVzdGFtcBpFCg5QcmVzZW5jZXNFbnRyeRILCgNrZXkYASABKAkSIgoFdmFsdWUYAiABKAsyEy55b3JraWUudjEuUHJlc2VuY2U6AjgBItoBCg5QcmVzZW5jZUNoYW5nZRIyCgR0eXBlGAEgASgOMiQueW9ya2llLnYxLlByZXNlbmNlQ2hhbmdlLkNoYW5nZVR5cGUSJQoIcHJlc2VuY2UYAiABKAsyEy55b3JraWUudjEuUHJlc2VuY2UibQoKQ2hhbmdlVHlwZRIbChdDSEFOR0VfVFlQRV9VTlNQRUNJRklFRBAAEhMKD0NIQU5HRV9UWVBFX1BVVBABEhYKEkNIQU5HRV9UWVBFX0RFTEVURRACEhUKEUNIQU5HRV9UWVBFX0NMRUFSEAMiZAoIUHJlc2VuY2USKwoEZGF0YRgBIAMoCzIdLnlvcmtpZS52MS5QcmVzZW5jZS5EYXRhRW50cnkaKwoJRGF0YUVudHJ5EgsKA2tleRgBIAEoCRINCgV2YWx1ZRgCIAEoCToCOAEiNAoOQ2hhbm5lbFN1bW1hcnkSCwoDa2V5GAEgASgJEhUKDXNlc3Npb25fY291bnQYAiABKAUiNAoKQ2hlY2twb2ludBISCgpzZXJ2ZXJfc2VxGAEgASgDEhIKCmNsaWVudF9zZXEYAiABKA0iYQoLVGV4dE5vZGVQb3MSKQoKY3JlYXRlZF9hdBgBIAEoCzIVLnlvcmtpZS52MS5UaW1lVGlja2V0Eg4KBm9mZnNldBgCIAEoBRIXCg9yZWxhdGl2ZV9vZmZzZXQYAyABKAUiQgoKVGltZVRpY2tldBIPCgdsYW1wb3J0GAEgASgDEhEKCWRlbGltaXRlchgCIAEoDRIQCghhY3Rvcl9pZBgDIAEoDCIuCgxEb2NFdmVudEJvZHkSDQoFdG9waWMYASABKAkSDwoHcGF5bG9hZBgCIAEoDCJrCghEb2NFdmVudBIlCgR0eXBlGAEgASgOMhcueW9ya2llLnYxLkRvY0V2ZW50VHlwZRIRCglwdWJsaXNoZXIYAiABKAkSJQoEYm9keRgDIAEoCzIXLnlvcmtpZS52MS5Eb2NFdmVudEJvZHki1gEKDENoYW5uZWxFdmVudBIqCgR0eXBlGAEgASgOMhwueW9ya2llLnYxLkNoYW5uZWxFdmVudC5UeXBlEhEKCXB1Ymxpc2hlchgCIAEoCRIVCg1zZXNzaW9uX2NvdW50GAMgASgDEgsKA3NlcRgEIAEoAxINCgV0b3BpYxgFIAEoCRIPCgdwYXlsb2FkGAYgASgMIkMKBFR5cGUSFAoQVFlQRV9VTlNQRUNJRklFRBAAEhEKDVRZUEVfUFJFU0VOQ0UQARISCg5UWVBFX0JST0FEQ0FTVBACIiYKCERhdGFTaXplEgwKBGRhdGEYASABKAUSDAoEbWV0YRgCIAEoBSJNCgdEb2NTaXplEiEKBGxpdmUYASABKAsyEy55b3JraWUudjEuRGF0YVNpemUSHwoCZ2MYAiABKAsyEy55b3JraWUudjEuRGF0YVNpemUikQEKBlNjaGVtYRIKCgJpZBgBIAEoCRIMCgRuYW1lGAIgASgJEg8KB3ZlcnNpb24YAyABKAUSDAoEYm9keRgEIAEoCRIeCgVydWxlcxgFIAMoCzIPLnlvcmtpZS52MS5SdWxlEi4KCmNyZWF0ZWRfYXQYBiABKAsyGi5nb29nbGUucHJvdG9idWYuVGltZXN0YW1wIlAKDFRyZWVOb2RlUnVsZRIRCglub2RlX3R5cGUYASABKAkSDwoHY29udGVudBgCIAEoCRINCgVtYXJrcxgDIAEoCRINCgVncm91cBgEIAEoCSJPCgRSdWxlEgwKBHBhdGgYASABKAkSDAoEdHlwZRgCIAEoCRIrCgp0cmVlX25vZGVzGAMgAygLMhcueW9ya2llLnYxLlRyZWVOb2RlUnVsZSKDAQoPUmV2aXNpb25TdW1tYXJ5EgoKAmlkGAEgASgJEg0KBWxhYmVsGAIgASgJEhMKC2Rlc2NyaXB0aW9uGAMgASgJEhAKCHNuYXBzaG90GAQgASgJEi4KCmNyZWF0ZWRfYXQYBSABKAsyGi5nb29nbGUucHJvdG9idWYuVGltZXN0YW1wKvwCCglWYWx1ZVR5cGUSEwoPVkFMVUVfVFlQRV9OVUxMEAASFgoSVkFMVUVfVFlQRV9CT09MRUFOEAESFgoSVkFMVUVfVFlQRV9JTlRFR0VSEAISEwoPVkFMVUVfVFlQRV9MT05HEAMSFQoRVkFMVUVfVFlQRV9ET1VCTEUQBBIVChFWQUxVRV9UWVBFX1NUUklORxAFEhQKEFZBTFVFX1RZUEVfQllURVMQBhITCg9WQUxVRV9UWVBFX0RBVEUQBxIaChZWQUxVRV9UWVBFX0pTT05fT0JKRUNUEAgSGQoVVkFMVUVfVFlQRV9KU09OX0FSUkFZEAkSEwoPVkFMVUVfVFlQRV9URVhUEAoSGgoWVkFMVUVfVFlQRV9JTlRFR0VSX0NOVBALEhcKE1ZBTFVFX1RZUEVfTE9OR19DTlQQDBITCg9WQUxVRV9UWVBFX1RSRUUQDRIgChxWQUxVRV9UWVBFX0lOVEVHRVJfREVEVVBfQ05UEA4iBAgPEA8qpgEKDERvY0V2ZW50VHlwZRIjCh9ET0NfRVZFTlRfVFlQRV9ET0NVTUVOVF9DSEFOR0VEEAASIwofRE9DX0VWRU5UX1RZUEVfRE9DVU1FTlRfV0FUQ0hFRBABEiUKIURPQ19FVkVOVF9UWVBFX0RPQ1VNRU5UX1VOV0FUQ0hFRBACEiUKIURPQ19FVkVOVF9UWVBFX0RPQ1VNRU5UX0JST0FEQ0FTVBADQkUKEWRldi55b3JraWUuYXBpLnYxUAFaLmdpdGh1Yi5jb20veW9ya2llLXRlYW0veW9ya2llL2FwaS95b3JraWUvdjE7djFiBnByb3RvMw", [file_google_protobuf_timestamp, file_google_protobuf_wrappers]);
5795
+ const file_src_api_yorkie_v1_resources = /* @__PURE__ */ fileDesc("CiFzcmMvYXBpL3lvcmtpZS92MS9yZXNvdXJjZXMucHJvdG8SCXlvcmtpZS52MSKuAQoIU25hcHNob3QSJAoEcm9vdBgBIAEoCzIWLnlvcmtpZS52MS5KU09ORWxlbWVudBI1CglwcmVzZW5jZXMYAiADKAsyIi55b3JraWUudjEuU25hcHNob3QuUHJlc2VuY2VzRW50cnkaRQoOUHJlc2VuY2VzRW50cnkSCwoDa2V5GAEgASgJEiIKBXZhbHVlGAIgASgLMhMueW9ya2llLnYxLlByZXNlbmNlOgI4ASL7AQoKQ2hhbmdlUGFjaxIUCgxkb2N1bWVudF9rZXkYASABKAkSKQoKY2hlY2twb2ludBgCIAEoCzIVLnlvcmtpZS52MS5DaGVja3BvaW50EhAKCHNuYXBzaG90GAMgASgMEiIKB2NoYW5nZXMYBCADKAsyES55b3JraWUudjEuQ2hhbmdlEjAKEW1pbl9zeW5jZWRfdGlja2V0GAUgASgLMhUueW9ya2llLnYxLlRpbWVUaWNrZXQSEgoKaXNfcmVtb3ZlZBgGIAEoCBIwCg52ZXJzaW9uX3ZlY3RvchgHIAEoCzIYLnlvcmtpZS52MS5WZXJzaW9uVmVjdG9yIpgBCgZDaGFuZ2USHwoCaWQYASABKAsyEy55b3JraWUudjEuQ2hhbmdlSUQSDwoHbWVzc2FnZRgCIAEoCRIoCgpvcGVyYXRpb25zGAMgAygLMhQueW9ya2llLnYxLk9wZXJhdGlvbhIyCg9wcmVzZW5jZV9jaGFuZ2UYBCABKAsyGS55b3JraWUudjEuUHJlc2VuY2VDaGFuZ2UihwEKCENoYW5nZUlEEhIKCmNsaWVudF9zZXEYASABKA0SEgoKc2VydmVyX3NlcRgCIAEoAxIPCgdsYW1wb3J0GAMgASgDEhAKCGFjdG9yX2lkGAQgASgMEjAKDnZlcnNpb25fdmVjdG9yGAUgASgLMhgueW9ya2llLnYxLlZlcnNpb25WZWN0b3IidAoNVmVyc2lvblZlY3RvchI0CgZ2ZWN0b3IYASADKAsyJC55b3JraWUudjEuVmVyc2lvblZlY3Rvci5WZWN0b3JFbnRyeRotCgtWZWN0b3JFbnRyeRILCgNrZXkYASABKAkSDQoFdmFsdWUYAiABKAM6AjgBItkaCglPcGVyYXRpb24SJwoDc2V0GAEgASgLMhgueW9ya2llLnYxLk9wZXJhdGlvbi5TZXRIABInCgNhZGQYAiABKAsyGC55b3JraWUudjEuT3BlcmF0aW9uLkFkZEgAEikKBG1vdmUYAyABKAsyGS55b3JraWUudjEuT3BlcmF0aW9uLk1vdmVIABItCgZyZW1vdmUYBCABKAsyGy55b3JraWUudjEuT3BlcmF0aW9uLlJlbW92ZUgAEikKBGVkaXQYBSABKAsyGS55b3JraWUudjEuT3BlcmF0aW9uLkVkaXRIABIrCgVzdHlsZRgHIAEoCzIaLnlvcmtpZS52MS5PcGVyYXRpb24uU3R5bGVIABIxCghpbmNyZWFzZRgIIAEoCzIdLnlvcmtpZS52MS5PcGVyYXRpb24uSW5jcmVhc2VIABIyCgl0cmVlX2VkaXQYCSABKAsyHS55b3JraWUudjEuT3BlcmF0aW9uLlRyZWVFZGl0SAASNAoKdHJlZV9zdHlsZRgKIAEoCzIeLnlvcmtpZS52MS5PcGVyYXRpb24uVHJlZVN0eWxlSAASMgoJYXJyYXlfc2V0GAsgASgLMh0ueW9ya2llLnYxLk9wZXJhdGlvbi5BcnJheVNldEgAGp0BCgNTZXQSMAoRcGFyZW50X2NyZWF0ZWRfYXQYASABKAsyFS55b3JraWUudjEuVGltZVRpY2tldBILCgNrZXkYAiABKAkSKwoFdmFsdWUYAyABKAsyHC55b3JraWUudjEuSlNPTkVsZW1lbnRTaW1wbGUSKgoLZXhlY3V0ZWRfYXQYBCABKAsyFS55b3JraWUudjEuVGltZVRpY2tldBrAAQoDQWRkEjAKEXBhcmVudF9jcmVhdGVkX2F0GAEgASgLMhUueW9ya2llLnYxLlRpbWVUaWNrZXQSLgoPcHJldl9jcmVhdGVkX2F0GAIgASgLMhUueW9ya2llLnYxLlRpbWVUaWNrZXQSKwoFdmFsdWUYAyABKAsyHC55b3JraWUudjEuSlNPTkVsZW1lbnRTaW1wbGUSKgoLZXhlY3V0ZWRfYXQYBCABKAsyFS55b3JraWUudjEuVGltZVRpY2tldBq/AQoETW92ZRIwChFwYXJlbnRfY3JlYXRlZF9hdBgBIAEoCzIVLnlvcmtpZS52MS5UaW1lVGlja2V0Ei4KD3ByZXZfY3JlYXRlZF9hdBgCIAEoCzIVLnlvcmtpZS52MS5UaW1lVGlja2V0EikKCmNyZWF0ZWRfYXQYAyABKAsyFS55b3JraWUudjEuVGltZVRpY2tldBIqCgtleGVjdXRlZF9hdBgEIAEoCzIVLnlvcmtpZS52MS5UaW1lVGlja2V0GpEBCgZSZW1vdmUSMAoRcGFyZW50X2NyZWF0ZWRfYXQYASABKAsyFS55b3JraWUudjEuVGltZVRpY2tldBIpCgpjcmVhdGVkX2F0GAIgASgLMhUueW9ya2llLnYxLlRpbWVUaWNrZXQSKgoLZXhlY3V0ZWRfYXQYAyABKAsyFS55b3JraWUudjEuVGltZVRpY2tldBrZAwoERWRpdBIwChFwYXJlbnRfY3JlYXRlZF9hdBgBIAEoCzIVLnlvcmtpZS52MS5UaW1lVGlja2V0EiQKBGZyb20YAiABKAsyFi55b3JraWUudjEuVGV4dE5vZGVQb3MSIgoCdG8YAyABKAsyFi55b3JraWUudjEuVGV4dE5vZGVQb3MSUwoXY3JlYXRlZF9hdF9tYXBfYnlfYWN0b3IYBCADKAsyMi55b3JraWUudjEuT3BlcmF0aW9uLkVkaXQuQ3JlYXRlZEF0TWFwQnlBY3RvckVudHJ5Eg8KB2NvbnRlbnQYBSABKAkSKgoLZXhlY3V0ZWRfYXQYBiABKAsyFS55b3JraWUudjEuVGltZVRpY2tldBI9CgphdHRyaWJ1dGVzGAcgAygLMikueW9ya2llLnYxLk9wZXJhdGlvbi5FZGl0LkF0dHJpYnV0ZXNFbnRyeRpRChhDcmVhdGVkQXRNYXBCeUFjdG9yRW50cnkSCwoDa2V5GAEgASgJEiQKBXZhbHVlGAIgASgLMhUueW9ya2llLnYxLlRpbWVUaWNrZXQ6AjgBGjEKD0F0dHJpYnV0ZXNFbnRyeRILCgNrZXkYASABKAkSDQoFdmFsdWUYAiABKAk6AjgBGukDCgVTdHlsZRIwChFwYXJlbnRfY3JlYXRlZF9hdBgBIAEoCzIVLnlvcmtpZS52MS5UaW1lVGlja2V0EiQKBGZyb20YAiABKAsyFi55b3JraWUudjEuVGV4dE5vZGVQb3MSIgoCdG8YAyABKAsyFi55b3JraWUudjEuVGV4dE5vZGVQb3MSPgoKYXR0cmlidXRlcxgEIAMoCzIqLnlvcmtpZS52MS5PcGVyYXRpb24uU3R5bGUuQXR0cmlidXRlc0VudHJ5EioKC2V4ZWN1dGVkX2F0GAUgASgLMhUueW9ya2llLnYxLlRpbWVUaWNrZXQSVAoXY3JlYXRlZF9hdF9tYXBfYnlfYWN0b3IYBiADKAsyMy55b3JraWUudjEuT3BlcmF0aW9uLlN0eWxlLkNyZWF0ZWRBdE1hcEJ5QWN0b3JFbnRyeRIcChRhdHRyaWJ1dGVzX3RvX3JlbW92ZRgHIAMoCRoxCg9BdHRyaWJ1dGVzRW50cnkSCwoDa2V5GAEgASgJEg0KBXZhbHVlGAIgASgJOgI4ARpRChhDcmVhdGVkQXRNYXBCeUFjdG9yRW50cnkSCwoDa2V5GAEgASgJEiQKBXZhbHVlGAIgASgLMhUueW9ya2llLnYxLlRpbWVUaWNrZXQ6AjgBGqQBCghJbmNyZWFzZRIwChFwYXJlbnRfY3JlYXRlZF9hdBgBIAEoCzIVLnlvcmtpZS52MS5UaW1lVGlja2V0EisKBXZhbHVlGAIgASgLMhwueW9ya2llLnYxLkpTT05FbGVtZW50U2ltcGxlEioKC2V4ZWN1dGVkX2F0GAMgASgLMhUueW9ya2llLnYxLlRpbWVUaWNrZXQSDQoFYWN0b3IYBCABKAkakwMKCFRyZWVFZGl0EjAKEXBhcmVudF9jcmVhdGVkX2F0GAEgASgLMhUueW9ya2llLnYxLlRpbWVUaWNrZXQSIAoEZnJvbRgCIAEoCzISLnlvcmtpZS52MS5UcmVlUG9zEh4KAnRvGAMgASgLMhIueW9ya2llLnYxLlRyZWVQb3MSVwoXY3JlYXRlZF9hdF9tYXBfYnlfYWN0b3IYBCADKAsyNi55b3JraWUudjEuT3BlcmF0aW9uLlRyZWVFZGl0LkNyZWF0ZWRBdE1hcEJ5QWN0b3JFbnRyeRImCghjb250ZW50cxgFIAMoCzIULnlvcmtpZS52MS5UcmVlTm9kZXMSEwoLc3BsaXRfbGV2ZWwYByABKAUSKgoLZXhlY3V0ZWRfYXQYBiABKAsyFS55b3JraWUudjEuVGltZVRpY2tldBpRChhDcmVhdGVkQXRNYXBCeUFjdG9yRW50cnkSCwoDa2V5GAEgASgJEiQKBXZhbHVlGAIgASgLMhUueW9ya2llLnYxLlRpbWVUaWNrZXQ6AjgBGu0DCglUcmVlU3R5bGUSMAoRcGFyZW50X2NyZWF0ZWRfYXQYASABKAsyFS55b3JraWUudjEuVGltZVRpY2tldBIgCgRmcm9tGAIgASgLMhIueW9ya2llLnYxLlRyZWVQb3MSHgoCdG8YAyABKAsyEi55b3JraWUudjEuVHJlZVBvcxJCCgphdHRyaWJ1dGVzGAQgAygLMi4ueW9ya2llLnYxLk9wZXJhdGlvbi5UcmVlU3R5bGUuQXR0cmlidXRlc0VudHJ5EioKC2V4ZWN1dGVkX2F0GAUgASgLMhUueW9ya2llLnYxLlRpbWVUaWNrZXQSHAoUYXR0cmlidXRlc190b19yZW1vdmUYBiADKAkSWAoXY3JlYXRlZF9hdF9tYXBfYnlfYWN0b3IYByADKAsyNy55b3JraWUudjEuT3BlcmF0aW9uLlRyZWVTdHlsZS5DcmVhdGVkQXRNYXBCeUFjdG9yRW50cnkaMQoPQXR0cmlidXRlc0VudHJ5EgsKA2tleRgBIAEoCRINCgV2YWx1ZRgCIAEoCToCOAEaUQoYQ3JlYXRlZEF0TWFwQnlBY3RvckVudHJ5EgsKA2tleRgBIAEoCRIkCgV2YWx1ZRgCIAEoCzIVLnlvcmtpZS52MS5UaW1lVGlja2V0OgI4ARrAAQoIQXJyYXlTZXQSMAoRcGFyZW50X2NyZWF0ZWRfYXQYASABKAsyFS55b3JraWUudjEuVGltZVRpY2tldBIpCgpjcmVhdGVkX2F0GAIgASgLMhUueW9ya2llLnYxLlRpbWVUaWNrZXQSKwoFdmFsdWUYAyABKAsyHC55b3JraWUudjEuSlNPTkVsZW1lbnRTaW1wbGUSKgoLZXhlY3V0ZWRfYXQYBCABKAsyFS55b3JraWUudjEuVGltZVRpY2tldEIGCgRib2R5IsUBChFKU09ORWxlbWVudFNpbXBsZRIpCgpjcmVhdGVkX2F0GAEgASgLMhUueW9ya2llLnYxLlRpbWVUaWNrZXQSJwoIbW92ZWRfYXQYAiABKAsyFS55b3JraWUudjEuVGltZVRpY2tldBIpCgpyZW1vdmVkX2F0GAMgASgLMhUueW9ya2llLnYxLlRpbWVUaWNrZXQSIgoEdHlwZRgEIAEoDjIULnlvcmtpZS52MS5WYWx1ZVR5cGUSDQoFdmFsdWUYBSABKAwinwsKC0pTT05FbGVtZW50EjgKC2pzb25fb2JqZWN0GAEgASgLMiEueW9ya2llLnYxLkpTT05FbGVtZW50LkpTT05PYmplY3RIABI2Cgpqc29uX2FycmF5GAIgASgLMiAueW9ya2llLnYxLkpTT05FbGVtZW50LkpTT05BcnJheUgAEjUKCXByaW1pdGl2ZRgDIAEoCzIgLnlvcmtpZS52MS5KU09ORWxlbWVudC5QcmltaXRpdmVIABIrCgR0ZXh0GAUgASgLMhsueW9ya2llLnYxLkpTT05FbGVtZW50LlRleHRIABIxCgdjb3VudGVyGAYgASgLMh4ueW9ya2llLnYxLkpTT05FbGVtZW50LkNvdW50ZXJIABIrCgR0cmVlGAcgASgLMhsueW9ya2llLnYxLkpTT05FbGVtZW50LlRyZWVIABquAQoKSlNPTk9iamVjdBIhCgVub2RlcxgBIAMoCzISLnlvcmtpZS52MS5SSFROb2RlEikKCmNyZWF0ZWRfYXQYAiABKAsyFS55b3JraWUudjEuVGltZVRpY2tldBInCghtb3ZlZF9hdBgDIAEoCzIVLnlvcmtpZS52MS5UaW1lVGlja2V0EikKCnJlbW92ZWRfYXQYBCABKAsyFS55b3JraWUudjEuVGltZVRpY2tldBqtAQoJSlNPTkFycmF5EiEKBW5vZGVzGAEgAygLMhIueW9ya2llLnYxLlJHQU5vZGUSKQoKY3JlYXRlZF9hdBgCIAEoCzIVLnlvcmtpZS52MS5UaW1lVGlja2V0EicKCG1vdmVkX2F0GAMgASgLMhUueW9ya2llLnYxLlRpbWVUaWNrZXQSKQoKcmVtb3ZlZF9hdBgEIAEoCzIVLnlvcmtpZS52MS5UaW1lVGlja2V0Gr0BCglQcmltaXRpdmUSIgoEdHlwZRgBIAEoDjIULnlvcmtpZS52MS5WYWx1ZVR5cGUSDQoFdmFsdWUYAiABKAwSKQoKY3JlYXRlZF9hdBgDIAEoCzIVLnlvcmtpZS52MS5UaW1lVGlja2V0EicKCG1vdmVkX2F0GAQgASgLMhUueW9ya2llLnYxLlRpbWVUaWNrZXQSKQoKcmVtb3ZlZF9hdBgFIAEoCzIVLnlvcmtpZS52MS5UaW1lVGlja2V0GqkBCgRUZXh0EiIKBW5vZGVzGAEgAygLMhMueW9ya2llLnYxLlRleHROb2RlEikKCmNyZWF0ZWRfYXQYAiABKAsyFS55b3JraWUudjEuVGltZVRpY2tldBInCghtb3ZlZF9hdBgDIAEoCzIVLnlvcmtpZS52MS5UaW1lVGlja2V0EikKCnJlbW92ZWRfYXQYBCABKAsyFS55b3JraWUudjEuVGltZVRpY2tldBrYAQoHQ291bnRlchIiCgR0eXBlGAEgASgOMhQueW9ya2llLnYxLlZhbHVlVHlwZRINCgV2YWx1ZRgCIAEoDBIpCgpjcmVhdGVkX2F0GAMgASgLMhUueW9ya2llLnYxLlRpbWVUaWNrZXQSJwoIbW92ZWRfYXQYBCABKAsyFS55b3JraWUudjEuVGltZVRpY2tldBIpCgpyZW1vdmVkX2F0GAUgASgLMhUueW9ya2llLnYxLlRpbWVUaWNrZXQSFQoNaGxsX3JlZ2lzdGVycxgHIAEoDEoECAYQBxqpAQoEVHJlZRIiCgVub2RlcxgBIAMoCzITLnlvcmtpZS52MS5UcmVlTm9kZRIpCgpjcmVhdGVkX2F0GAIgASgLMhUueW9ya2llLnYxLlRpbWVUaWNrZXQSJwoIbW92ZWRfYXQYAyABKAsyFS55b3JraWUudjEuVGltZVRpY2tldBIpCgpyZW1vdmVkX2F0GAQgASgLMhUueW9ya2llLnYxLlRpbWVUaWNrZXRCBgoEYm9keSI/CgdSSFROb2RlEgsKA2tleRgBIAEoCRInCgdlbGVtZW50GAIgASgLMhYueW9ya2llLnYxLkpTT05FbGVtZW50Iu4BCgdSR0FOb2RlEiAKBG5leHQYASABKAsyEi55b3JraWUudjEuUkdBTm9kZRInCgdlbGVtZW50GAIgASgLMhYueW9ya2llLnYxLkpTT05FbGVtZW50EjIKE3Bvc2l0aW9uX2NyZWF0ZWRfYXQYAyABKAsyFS55b3JraWUudjEuVGltZVRpY2tldBIwChFwb3NpdGlvbl9tb3ZlZF9hdBgEIAEoCzIVLnlvcmtpZS52MS5UaW1lVGlja2V0EjIKE3Bvc2l0aW9uX3JlbW92ZWRfYXQYBSABKAsyFS55b3JraWUudjEuVGltZVRpY2tldCJYCghOb2RlQXR0chINCgV2YWx1ZRgBIAEoCRIpCgp1cGRhdGVkX2F0GAIgASgLMhUueW9ya2llLnYxLlRpbWVUaWNrZXQSEgoKaXNfcmVtb3ZlZBgDIAEoCCKUAgoIVGV4dE5vZGUSIQoCaWQYASABKAsyFS55b3JraWUudjEuVGV4dE5vZGVJRBINCgV2YWx1ZRgCIAEoCRIpCgpyZW1vdmVkX2F0GAMgASgLMhUueW9ya2llLnYxLlRpbWVUaWNrZXQSKgoLaW5zX3ByZXZfaWQYBCABKAsyFS55b3JraWUudjEuVGV4dE5vZGVJRBI3CgphdHRyaWJ1dGVzGAUgAygLMiMueW9ya2llLnYxLlRleHROb2RlLkF0dHJpYnV0ZXNFbnRyeRpGCg9BdHRyaWJ1dGVzRW50cnkSCwoDa2V5GAEgASgJEiIKBXZhbHVlGAIgASgLMhMueW9ya2llLnYxLk5vZGVBdHRyOgI4ASJHCgpUZXh0Tm9kZUlEEikKCmNyZWF0ZWRfYXQYASABKAsyFS55b3JraWUudjEuVGltZVRpY2tldBIOCgZvZmZzZXQYAiABKAUiswMKCFRyZWVOb2RlEiEKAmlkGAEgASgLMhUueW9ya2llLnYxLlRyZWVOb2RlSUQSDAoEdHlwZRgCIAEoCRINCgV2YWx1ZRgDIAEoCRIpCgpyZW1vdmVkX2F0GAQgASgLMhUueW9ya2llLnYxLlRpbWVUaWNrZXQSKgoLaW5zX3ByZXZfaWQYBSABKAsyFS55b3JraWUudjEuVHJlZU5vZGVJRBIqCgtpbnNfbmV4dF9pZBgGIAEoCzIVLnlvcmtpZS52MS5UcmVlTm9kZUlEEg0KBWRlcHRoGAcgASgFEjcKCmF0dHJpYnV0ZXMYCCADKAsyIy55b3JraWUudjEuVHJlZU5vZGUuQXR0cmlidXRlc0VudHJ5EioKC21lcmdlZF9mcm9tGAkgASgLMhUueW9ya2llLnYxLlRyZWVOb2RlSUQSKAoJbWVyZ2VkX2F0GAogASgLMhUueW9ya2llLnYxLlRpbWVUaWNrZXQaRgoPQXR0cmlidXRlc0VudHJ5EgsKA2tleRgBIAEoCRIiCgV2YWx1ZRgCIAEoCzITLnlvcmtpZS52MS5Ob2RlQXR0cjoCOAEiMQoJVHJlZU5vZGVzEiQKB2NvbnRlbnQYASADKAsyEy55b3JraWUudjEuVHJlZU5vZGUiRwoKVHJlZU5vZGVJRBIpCgpjcmVhdGVkX2F0GAEgASgLMhUueW9ya2llLnYxLlRpbWVUaWNrZXQSDgoGb2Zmc2V0GAIgASgFImMKB1RyZWVQb3MSKAoJcGFyZW50X2lkGAEgASgLMhUueW9ya2llLnYxLlRyZWVOb2RlSUQSLgoPbGVmdF9zaWJsaW5nX2lkGAIgASgLMhUueW9ya2llLnYxLlRyZWVOb2RlSUQiawoEVXNlchIKCgJpZBgBIAEoCRIVCg1hdXRoX3Byb3ZpZGVyGAIgASgJEhAKCHVzZXJuYW1lGAMgASgJEi4KCmNyZWF0ZWRfYXQYBCABKAsyGi5nb29nbGUucHJvdG9idWYuVGltZXN0YW1wIokBCgZNZW1iZXISCgoCaWQYASABKAkSEgoKcHJvamVjdF9pZBgCIAEoCRIPCgd1c2VyX2lkGAMgASgJEhAKCHVzZXJuYW1lGAQgASgJEgwKBHJvbGUYBSABKAkSLgoKaW52aXRlZF9hdBgGIAEoCzIaLmdvb2dsZS5wcm90b2J1Zi5UaW1lc3RhbXAi6QYKB1Byb2plY3QSCgoCaWQYASABKAkSDAoEbmFtZRgCIAEoCRISCgpwdWJsaWNfa2V5GAMgASgJEhIKCnNlY3JldF9rZXkYBCABKAkSGAoQYXV0aF93ZWJob29rX3VybBgFIAEoCRIcChRhdXRoX3dlYmhvb2tfbWV0aG9kcxgGIAMoCRIgChhhdXRoX3dlYmhvb2tfbWF4X3JldHJpZXMYESABKAQSJgoeYXV0aF93ZWJob29rX21pbl93YWl0X2ludGVydmFsGBIgASgJEiYKHmF1dGhfd2ViaG9va19tYXhfd2FpdF9pbnRlcnZhbBgTIAEoCRIkChxhdXRoX3dlYmhvb2tfcmVxdWVzdF90aW1lb3V0GBQgASgJEhkKEWV2ZW50X3dlYmhvb2tfdXJsGAcgASgJEhwKFGV2ZW50X3dlYmhvb2tfZXZlbnRzGAggAygJEiEKGWV2ZW50X3dlYmhvb2tfbWF4X3JldHJpZXMYFSABKAQSJwofZXZlbnRfd2ViaG9va19taW5fd2FpdF9pbnRlcnZhbBgWIAEoCRInCh9ldmVudF93ZWJob29rX21heF93YWl0X2ludGVydmFsGBcgASgJEiUKHWV2ZW50X3dlYmhvb2tfcmVxdWVzdF90aW1lb3V0GBggASgJEiMKG2NsaWVudF9kZWFjdGl2YXRlX3RocmVzaG9sZBgJIAEoCRIaChJzbmFwc2hvdF90aHJlc2hvbGQYGSABKAMSGQoRc25hcHNob3RfaW50ZXJ2YWwYGiABKAMSJAocbWF4X3N1YnNjcmliZXJzX3Blcl9kb2N1bWVudBgKIAEoBRIkChxtYXhfYXR0YWNobWVudHNfcGVyX2RvY3VtZW50GAsgASgFEh0KFW1heF9zaXplX3Blcl9kb2N1bWVudBgPIAEoBRIYChByZW1vdmVfb25fZGV0YWNoGBAgASgIEh0KFWF1dG9fcmV2aXNpb25fZW5hYmxlZBgbIAEoCBIXCg9hbGxvd2VkX29yaWdpbnMYDiADKAkSLgoKY3JlYXRlZF9hdBgMIAEoCzIaLmdvb2dsZS5wcm90b2J1Zi5UaW1lc3RhbXASLgoKdXBkYXRlZF9hdBgNIAEoCzIaLmdvb2dsZS5wcm90b2J1Zi5UaW1lc3RhbXAiLwoLTWV0cmljUG9pbnQSEQoJdGltZXN0YW1wGAEgASgDEg0KBXZhbHVlGAIgASgFIqMMChZVcGRhdGFibGVQcm9qZWN0RmllbGRzEioKBG5hbWUYASABKAsyHC5nb29nbGUucHJvdG9idWYuU3RyaW5nVmFsdWUSNgoQYXV0aF93ZWJob29rX3VybBgCIAEoCzIcLmdvb2dsZS5wcm90b2J1Zi5TdHJpbmdWYWx1ZRJSChRhdXRoX3dlYmhvb2tfbWV0aG9kcxgDIAEoCzI0LnlvcmtpZS52MS5VcGRhdGFibGVQcm9qZWN0RmllbGRzLkF1dGhXZWJob29rTWV0aG9kcxI+ChhhdXRoX3dlYmhvb2tfbWF4X3JldHJpZXMYDCABKAsyHC5nb29nbGUucHJvdG9idWYuVUludDY0VmFsdWUSRAoeYXV0aF93ZWJob29rX21pbl93YWl0X2ludGVydmFsGA0gASgLMhwuZ29vZ2xlLnByb3RvYnVmLlN0cmluZ1ZhbHVlEkQKHmF1dGhfd2ViaG9va19tYXhfd2FpdF9pbnRlcnZhbBgOIAEoCzIcLmdvb2dsZS5wcm90b2J1Zi5TdHJpbmdWYWx1ZRJCChxhdXRoX3dlYmhvb2tfcmVxdWVzdF90aW1lb3V0GA8gASgLMhwuZ29vZ2xlLnByb3RvYnVmLlN0cmluZ1ZhbHVlEjcKEWV2ZW50X3dlYmhvb2tfdXJsGAQgASgLMhwuZ29vZ2xlLnByb3RvYnVmLlN0cmluZ1ZhbHVlElIKFGV2ZW50X3dlYmhvb2tfZXZlbnRzGAUgASgLMjQueW9ya2llLnYxLlVwZGF0YWJsZVByb2plY3RGaWVsZHMuRXZlbnRXZWJob29rRXZlbnRzEj8KGWV2ZW50X3dlYmhvb2tfbWF4X3JldHJpZXMYECABKAsyHC5nb29nbGUucHJvdG9idWYuVUludDY0VmFsdWUSRQofZXZlbnRfd2ViaG9va19taW5fd2FpdF9pbnRlcnZhbBgRIAEoCzIcLmdvb2dsZS5wcm90b2J1Zi5TdHJpbmdWYWx1ZRJFCh9ldmVudF93ZWJob29rX21heF93YWl0X2ludGVydmFsGBIgASgLMhwuZ29vZ2xlLnByb3RvYnVmLlN0cmluZ1ZhbHVlEkMKHWV2ZW50X3dlYmhvb2tfcmVxdWVzdF90aW1lb3V0GBMgASgLMhwuZ29vZ2xlLnByb3RvYnVmLlN0cmluZ1ZhbHVlEjcKEnNuYXBzaG90X3RocmVzaG9sZBgUIAEoCzIbLmdvb2dsZS5wcm90b2J1Zi5JbnQ2NFZhbHVlEjYKEXNuYXBzaG90X2ludGVydmFsGBUgASgLMhsuZ29vZ2xlLnByb3RvYnVmLkludDY0VmFsdWUSQQobY2xpZW50X2RlYWN0aXZhdGVfdGhyZXNob2xkGAYgASgLMhwuZ29vZ2xlLnByb3RvYnVmLlN0cmluZ1ZhbHVlEkEKHG1heF9zdWJzY3JpYmVyc19wZXJfZG9jdW1lbnQYByABKAsyGy5nb29nbGUucHJvdG9idWYuSW50MzJWYWx1ZRJBChxtYXhfYXR0YWNobWVudHNfcGVyX2RvY3VtZW50GAggASgLMhsuZ29vZ2xlLnByb3RvYnVmLkludDMyVmFsdWUSOgoVbWF4X3NpemVfcGVyX2RvY3VtZW50GAogASgLMhsuZ29vZ2xlLnByb3RvYnVmLkludDMyVmFsdWUSNAoQcmVtb3ZlX29uX2RldGFjaBgLIAEoCzIaLmdvb2dsZS5wcm90b2J1Zi5Cb29sVmFsdWUSOQoVYXV0b19yZXZpc2lvbl9lbmFibGVkGBYgASgLMhouZ29vZ2xlLnByb3RvYnVmLkJvb2xWYWx1ZRJJCg9hbGxvd2VkX29yaWdpbnMYCSABKAsyMC55b3JraWUudjEuVXBkYXRhYmxlUHJvamVjdEZpZWxkcy5BbGxvd2VkT3JpZ2lucxolChJBdXRoV2ViaG9va01ldGhvZHMSDwoHbWV0aG9kcxgBIAMoCRokChJFdmVudFdlYmhvb2tFdmVudHMSDgoGZXZlbnRzGAEgAygJGiEKDkFsbG93ZWRPcmlnaW5zEg8KB29yaWdpbnMYASADKAkipwMKD0RvY3VtZW50U3VtbWFyeRIKCgJpZBgBIAEoCRILCgNrZXkYAiABKAkSDAoEcm9vdBgDIAEoCRIYChBhdHRhY2hlZF9jbGllbnRzGAcgASgFEikKDWRvY3VtZW50X3NpemUYCCABKAsyEi55b3JraWUudjEuRG9jU2l6ZRISCgpzY2hlbWFfa2V5GAkgASgJEjwKCXByZXNlbmNlcxgKIAMoCzIpLnlvcmtpZS52MS5Eb2N1bWVudFN1bW1hcnkuUHJlc2VuY2VzRW50cnkSLgoKY3JlYXRlZF9hdBgEIAEoCzIaLmdvb2dsZS5wcm90b2J1Zi5UaW1lc3RhbXASLwoLYWNjZXNzZWRfYXQYBSABKAsyGi5nb29nbGUucHJvdG9idWYuVGltZXN0YW1wEi4KCnVwZGF0ZWRfYXQYBiABKAsyGi5nb29nbGUucHJvdG9idWYuVGltZXN0YW1wGkUKDlByZXNlbmNlc0VudHJ5EgsKA2tleRgBIAEoCRIiCgV2YWx1ZRgCIAEoCzITLnlvcmtpZS52MS5QcmVzZW5jZToCOAEi2gEKDlByZXNlbmNlQ2hhbmdlEjIKBHR5cGUYASABKA4yJC55b3JraWUudjEuUHJlc2VuY2VDaGFuZ2UuQ2hhbmdlVHlwZRIlCghwcmVzZW5jZRgCIAEoCzITLnlvcmtpZS52MS5QcmVzZW5jZSJtCgpDaGFuZ2VUeXBlEhsKF0NIQU5HRV9UWVBFX1VOU1BFQ0lGSUVEEAASEwoPQ0hBTkdFX1RZUEVfUFVUEAESFgoSQ0hBTkdFX1RZUEVfREVMRVRFEAISFQoRQ0hBTkdFX1RZUEVfQ0xFQVIQAyJkCghQcmVzZW5jZRIrCgRkYXRhGAEgAygLMh0ueW9ya2llLnYxLlByZXNlbmNlLkRhdGFFbnRyeRorCglEYXRhRW50cnkSCwoDa2V5GAEgASgJEg0KBXZhbHVlGAIgASgJOgI4ASI0Cg5DaGFubmVsU3VtbWFyeRILCgNrZXkYASABKAkSFQoNc2Vzc2lvbl9jb3VudBgCIAEoBSI0CgpDaGVja3BvaW50EhIKCnNlcnZlcl9zZXEYASABKAMSEgoKY2xpZW50X3NlcRgCIAEoDSJhCgtUZXh0Tm9kZVBvcxIpCgpjcmVhdGVkX2F0GAEgASgLMhUueW9ya2llLnYxLlRpbWVUaWNrZXQSDgoGb2Zmc2V0GAIgASgFEhcKD3JlbGF0aXZlX29mZnNldBgDIAEoBSJCCgpUaW1lVGlja2V0Eg8KB2xhbXBvcnQYASABKAMSEQoJZGVsaW1pdGVyGAIgASgNEhAKCGFjdG9yX2lkGAMgASgMIi4KDERvY0V2ZW50Qm9keRINCgV0b3BpYxgBIAEoCRIPCgdwYXlsb2FkGAIgASgMImsKCERvY0V2ZW50EiUKBHR5cGUYASABKA4yFy55b3JraWUudjEuRG9jRXZlbnRUeXBlEhEKCXB1Ymxpc2hlchgCIAEoCRIlCgRib2R5GAMgASgLMhcueW9ya2llLnYxLkRvY0V2ZW50Qm9keSLWAQoMQ2hhbm5lbEV2ZW50EioKBHR5cGUYASABKA4yHC55b3JraWUudjEuQ2hhbm5lbEV2ZW50LlR5cGUSEQoJcHVibGlzaGVyGAIgASgJEhUKDXNlc3Npb25fY291bnQYAyABKAMSCwoDc2VxGAQgASgDEg0KBXRvcGljGAUgASgJEg8KB3BheWxvYWQYBiABKAwiQwoEVHlwZRIUChBUWVBFX1VOU1BFQ0lGSUVEEAASEQoNVFlQRV9QUkVTRU5DRRABEhIKDlRZUEVfQlJPQURDQVNUEAIiJgoIRGF0YVNpemUSDAoEZGF0YRgBIAEoBRIMCgRtZXRhGAIgASgFIk0KB0RvY1NpemUSIQoEbGl2ZRgBIAEoCzITLnlvcmtpZS52MS5EYXRhU2l6ZRIfCgJnYxgCIAEoCzITLnlvcmtpZS52MS5EYXRhU2l6ZSKRAQoGU2NoZW1hEgoKAmlkGAEgASgJEgwKBG5hbWUYAiABKAkSDwoHdmVyc2lvbhgDIAEoBRIMCgRib2R5GAQgASgJEh4KBXJ1bGVzGAUgAygLMg8ueW9ya2llLnYxLlJ1bGUSLgoKY3JlYXRlZF9hdBgGIAEoCzIaLmdvb2dsZS5wcm90b2J1Zi5UaW1lc3RhbXAiUAoMVHJlZU5vZGVSdWxlEhEKCW5vZGVfdHlwZRgBIAEoCRIPCgdjb250ZW50GAIgASgJEg0KBW1hcmtzGAMgASgJEg0KBWdyb3VwGAQgASgJIk8KBFJ1bGUSDAoEcGF0aBgBIAEoCRIMCgR0eXBlGAIgASgJEisKCnRyZWVfbm9kZXMYAyADKAsyFy55b3JraWUudjEuVHJlZU5vZGVSdWxlIoMBCg9SZXZpc2lvblN1bW1hcnkSCgoCaWQYASABKAkSDQoFbGFiZWwYAiABKAkSEwoLZGVzY3JpcHRpb24YAyABKAkSEAoIc25hcHNob3QYBCABKAkSLgoKY3JlYXRlZF9hdBgFIAEoCzIaLmdvb2dsZS5wcm90b2J1Zi5UaW1lc3RhbXAq/AIKCVZhbHVlVHlwZRITCg9WQUxVRV9UWVBFX05VTEwQABIWChJWQUxVRV9UWVBFX0JPT0xFQU4QARIWChJWQUxVRV9UWVBFX0lOVEVHRVIQAhITCg9WQUxVRV9UWVBFX0xPTkcQAxIVChFWQUxVRV9UWVBFX0RPVUJMRRAEEhUKEVZBTFVFX1RZUEVfU1RSSU5HEAUSFAoQVkFMVUVfVFlQRV9CWVRFUxAGEhMKD1ZBTFVFX1RZUEVfREFURRAHEhoKFlZBTFVFX1RZUEVfSlNPTl9PQkpFQ1QQCBIZChVWQUxVRV9UWVBFX0pTT05fQVJSQVkQCRITCg9WQUxVRV9UWVBFX1RFWFQQChIaChZWQUxVRV9UWVBFX0lOVEVHRVJfQ05UEAsSFwoTVkFMVUVfVFlQRV9MT05HX0NOVBAMEhMKD1ZBTFVFX1RZUEVfVFJFRRANEiAKHFZBTFVFX1RZUEVfSU5URUdFUl9ERURVUF9DTlQQDiIECA8QDyqmAQoMRG9jRXZlbnRUeXBlEiMKH0RPQ19FVkVOVF9UWVBFX0RPQ1VNRU5UX0NIQU5HRUQQABIjCh9ET0NfRVZFTlRfVFlQRV9ET0NVTUVOVF9XQVRDSEVEEAESJQohRE9DX0VWRU5UX1RZUEVfRE9DVU1FTlRfVU5XQVRDSEVEEAISJQohRE9DX0VWRU5UX1RZUEVfRE9DVU1FTlRfQlJPQURDQVNUEANCRQoRZGV2LnlvcmtpZS5hcGkudjFQAVouZ2l0aHViLmNvbS95b3JraWUtdGVhbS95b3JraWUvYXBpL3lvcmtpZS92MTt2MWIGcHJvdG8z", [file_google_protobuf_timestamp, file_google_protobuf_wrappers]);
5796
5796
  const SnapshotSchema = /* @__PURE__ */ messageDesc(file_src_api_yorkie_v1_resources, 0);
5797
5797
  const ChangePackSchema = /* @__PURE__ */ messageDesc(file_src_api_yorkie_v1_resources, 1);
5798
5798
  const ChangeSchema = /* @__PURE__ */ messageDesc(file_src_api_yorkie_v1_resources, 2);
@@ -7141,6 +7141,13 @@
7141
7141
  if (this.valueType === 5) {
7142
7142
  return `"${escapeString(this.value)}"`;
7143
7143
  }
7144
+ if (this.valueType === 6) {
7145
+ const bytes = this.value;
7146
+ return `"${btoa(String.fromCharCode(...bytes))}"`;
7147
+ }
7148
+ if (this.valueType === 7) {
7149
+ return `"${this.value.toISOString()}"`;
7150
+ }
7144
7151
  return `${this.value}`;
7145
7152
  }
7146
7153
  /**
@@ -7283,19 +7290,54 @@
7283
7290
  }
7284
7291
  }
7285
7292
  }
7293
+ class ElementEntry {
7294
+ elem;
7295
+ positionNode;
7296
+ posMovedAt;
7297
+ constructor(elem) {
7298
+ this.elem = elem;
7299
+ }
7300
+ }
7286
7301
  class RGATreeListNode extends SplayNode {
7302
+ _elementEntry;
7303
+ _createdAt;
7304
+ _removedAt;
7287
7305
  prev;
7288
7306
  next;
7289
- movedFrom;
7290
- constructor(value) {
7291
- super(value);
7292
- this.value = value;
7307
+ constructor(elem, createdAt) {
7308
+ super(elem);
7309
+ this._createdAt = createdAt;
7310
+ }
7311
+ /**
7312
+ * `createWithElement` creates a new node that owns an element.
7313
+ */
7314
+ static createWithElement(elem) {
7315
+ const entry = new ElementEntry(elem);
7316
+ const node = new RGATreeListNode(elem, elem.getCreatedAt());
7317
+ entry.positionNode = node;
7318
+ node._elementEntry = entry;
7319
+ return node;
7320
+ }
7321
+ /**
7322
+ * `createBarePosition` creates a position node without an element
7323
+ * (used for move).
7324
+ */
7325
+ static createBarePosition(createdAt) {
7326
+ return new RGATreeListNode(void 0, createdAt);
7293
7327
  }
7294
7328
  /**
7295
- * `createAfter` creates a new node after the given node.
7329
+ * `createAfter` creates a new node with the given element after
7330
+ * the given prev node.
7296
7331
  */
7297
- static createAfter(prev, value) {
7298
- const newNode = new RGATreeListNode(value);
7332
+ static createAfter(prev, elem) {
7333
+ const newNode = RGATreeListNode.createWithElement(elem);
7334
+ RGATreeListNode.insertNodeAfter(prev, newNode);
7335
+ return newNode;
7336
+ }
7337
+ /**
7338
+ * `insertNodeAfter` inserts a node after the given prev node.
7339
+ */
7340
+ static insertNodeAfter(prev, newNode) {
7299
7341
  const prevNext = prev.next;
7300
7342
  prev.next = newNode;
7301
7343
  newNode.prev = prev;
@@ -7303,26 +7345,41 @@
7303
7345
  if (prevNext) {
7304
7346
  prevNext.prev = newNode;
7305
7347
  }
7306
- return newNode;
7307
7348
  }
7308
7349
  /**
7309
- * `remove` removes value based on removing time.
7350
+ * `remove` removes the element based on removing time.
7310
7351
  */
7311
7352
  remove(removedAt) {
7312
- return this.value.remove(removedAt);
7353
+ if (!this._elementEntry) {
7354
+ return false;
7355
+ }
7356
+ return this._elementEntry.elem.remove(removedAt);
7313
7357
  }
7314
7358
  /**
7315
- * `getCreatedAt` returns creation time of this value
7359
+ * `getCreatedAt` returns the creation time. For live nodes with
7360
+ * elements, returns the element's createdAt for backward
7361
+ * compatibility.
7316
7362
  */
7317
7363
  getCreatedAt() {
7318
- return this.value.getCreatedAt();
7364
+ if (this._elementEntry) {
7365
+ return this._elementEntry.elem.getCreatedAt();
7366
+ }
7367
+ return this._createdAt;
7319
7368
  }
7320
7369
  /**
7321
- * `getPositionedAt` returns the time of this element when it was positioned
7322
- * in the array.
7370
+ * `getPositionedAt` returns the time this element was positioned.
7371
+ * For live nodes, the position register (posMovedAt) is the source
7372
+ * of truth. For dead nodes (no element), the position node's own
7373
+ * createdAt is used.
7323
7374
  */
7324
7375
  getPositionedAt() {
7325
- return this.value.getPositionedAt();
7376
+ if (this._elementEntry) {
7377
+ if (this._elementEntry.posMovedAt) {
7378
+ return this._elementEntry.posMovedAt;
7379
+ }
7380
+ return this._elementEntry.elem.getCreatedAt();
7381
+ }
7382
+ return this._createdAt;
7326
7383
  }
7327
7384
  /**
7328
7385
  * `release` releases prev and next node.
@@ -7339,9 +7396,13 @@
7339
7396
  }
7340
7397
  /**
7341
7398
  * `getLength` returns the length of this node.
7399
+ * Dead nodes (no element) return 0, removed elements return 0.
7342
7400
  */
7343
7401
  getLength() {
7344
- return this.value.isRemoved() ? 0 : 1;
7402
+ if (!this._elementEntry || this.isRemoved()) {
7403
+ return 0;
7404
+ }
7405
+ return 1;
7345
7406
  }
7346
7407
  /**
7347
7408
  * `getPrev` returns a previous node.
@@ -7356,28 +7417,87 @@
7356
7417
  return this.next;
7357
7418
  }
7358
7419
  /**
7359
- * `getMovedFrom` returns the previous element before the element moved.
7420
+ * `getValue` returns the element value.
7360
7421
  */
7361
- getMovedFrom() {
7362
- return this.movedFrom;
7422
+ getValue() {
7423
+ if (!this._elementEntry) {
7424
+ return this.value;
7425
+ }
7426
+ return this._elementEntry.elem;
7363
7427
  }
7364
7428
  /**
7365
- * `setMovedFrom` sets the previous element before the element moved.
7429
+ * `getElement` returns the element or undefined if dead position.
7366
7430
  */
7367
- setMovedFrom(movedFrom) {
7368
- this.movedFrom = movedFrom;
7431
+ getElement() {
7432
+ return this._elementEntry?.elem;
7369
7433
  }
7370
7434
  /**
7371
- * `getValue` returns a element value.
7435
+ * `isRemoved` checks if the value was removed.
7372
7436
  */
7373
- getValue() {
7374
- return this.value;
7437
+ isRemoved() {
7438
+ if (!this._elementEntry) {
7439
+ return true;
7440
+ }
7441
+ return this._elementEntry.elem.isRemoved();
7375
7442
  }
7376
7443
  /**
7377
- * `isRemoved` checks if the value was removed.
7444
+ * `getElementEntry` returns the element entry.
7378
7445
  */
7379
- isRemoved() {
7380
- return this.value.isRemoved();
7446
+ getElementEntry() {
7447
+ return this._elementEntry;
7448
+ }
7449
+ /**
7450
+ * `setElementEntry` sets the element entry.
7451
+ */
7452
+ setElementEntry(entry) {
7453
+ this._elementEntry = entry;
7454
+ }
7455
+ /**
7456
+ * `getPositionCreatedAt` returns the position node's own createdAt.
7457
+ */
7458
+ getPositionCreatedAt() {
7459
+ return this._createdAt;
7460
+ }
7461
+ /**
7462
+ * `getPositionMovedAt` returns the LWW timestamp of the element's
7463
+ * move into this position. Undefined for insert-created positions.
7464
+ */
7465
+ getPositionMovedAt() {
7466
+ if (!this._elementEntry) {
7467
+ return void 0;
7468
+ }
7469
+ return this._elementEntry.posMovedAt;
7470
+ }
7471
+ /**
7472
+ * `getRemovedAt` returns the time this dead position node was
7473
+ * removed (for GC).
7474
+ */
7475
+ getRemovedAt() {
7476
+ return this._removedAt;
7477
+ }
7478
+ /**
7479
+ * `setRemovedAt` sets the removal time of this position node.
7480
+ */
7481
+ setRemovedAt(removedAt) {
7482
+ this._removedAt = removedAt;
7483
+ }
7484
+ /**
7485
+ * `toIDString` returns a unique identifier for this position node
7486
+ * (for GC).
7487
+ */
7488
+ toIDString() {
7489
+ return this._createdAt.toIDString();
7490
+ }
7491
+ /**
7492
+ * `getDataSize` returns the data size of this position node
7493
+ * (for GC).
7494
+ */
7495
+ getDataSize() {
7496
+ let meta = TimeTicketSize;
7497
+ if (this._removedAt) {
7498
+ meta += TimeTicketSize;
7499
+ }
7500
+ return { data: 0, meta };
7381
7501
  }
7382
7502
  }
7383
7503
  class RGATreeList {
@@ -7385,13 +7505,15 @@
7385
7505
  last;
7386
7506
  nodeMapByIndex;
7387
7507
  nodeMapByCreatedAt;
7508
+ elementMapByCreatedAt;
7388
7509
  constructor() {
7389
7510
  const dummyValue = Primitive.of(0, InitialTimeTicket);
7390
7511
  dummyValue.setRemovedAt(InitialTimeTicket);
7391
- this.dummyHead = new RGATreeListNode(dummyValue);
7512
+ this.dummyHead = RGATreeListNode.createWithElement(dummyValue);
7392
7513
  this.last = this.dummyHead;
7393
7514
  this.nodeMapByIndex = new SplayTree();
7394
7515
  this.nodeMapByCreatedAt = /* @__PURE__ */ new Map();
7516
+ this.elementMapByCreatedAt = /* @__PURE__ */ new Map();
7395
7517
  this.nodeMapByIndex.insert(this.dummyHead);
7396
7518
  this.nodeMapByCreatedAt.set(
7397
7519
  this.dummyHead.getCreatedAt().toIDString(),
@@ -7411,22 +7533,10 @@
7411
7533
  return this.nodeMapByIndex.length;
7412
7534
  }
7413
7535
  /**
7414
- * `findNextBeforeExecutedAt` returns the node by the given createdAt and
7415
- * executedAt. It passes through nodes created after executedAt from the
7416
- * given node and returns the next node.
7417
- * @returns the next node of the given createdAt and executedAt
7536
+ * `findNextBeforeExecutedAt` walks forward from the given node,
7537
+ * skipping nodes positioned after executedAt (RGA insertion rule).
7418
7538
  */
7419
- findNextBeforeExecutedAt(createdAt, executedAt) {
7420
- let node = this.nodeMapByCreatedAt.get(createdAt.toIDString());
7421
- if (!node) {
7422
- throw new YorkieError(
7423
- Code.ErrInvalidArgument,
7424
- `cant find the given node: ${createdAt.toIDString()}`
7425
- );
7426
- }
7427
- while (node.getValue().getMovedAt() && node.getValue().getMovedAt().after(executedAt) && node.getMovedFrom()) {
7428
- node = node.getMovedFrom();
7429
- }
7539
+ findNextBeforeExecutedAt(node, executedAt) {
7430
7540
  while (node.getNext() && node.getNext().getPositionedAt().after(executedAt)) {
7431
7541
  node = node.getNext();
7432
7542
  }
@@ -7438,65 +7548,103 @@
7438
7548
  }
7439
7549
  node.release();
7440
7550
  this.nodeMapByIndex.delete(node);
7441
- this.nodeMapByCreatedAt.delete(node.getValue().getCreatedAt().toIDString());
7551
+ this.nodeMapByCreatedAt.delete(node.getPositionCreatedAt().toIDString());
7442
7552
  }
7443
7553
  /**
7444
- * `insertAfter` adds a new node with the value after the given node.
7554
+ * `insertAfter` adds a new node with the value after the given
7555
+ * position. prevCreatedAt is a position node identity. Looks up
7556
+ * nodeMapByCreatedAt first, then elementMapByCreatedAt for backward
7557
+ * compatibility.
7445
7558
  */
7446
7559
  insertAfter(prevCreatedAt, value, executedAt = value.getCreatedAt()) {
7447
- const prevNode = this.findNextBeforeExecutedAt(prevCreatedAt, executedAt);
7560
+ let startNode = this.nodeMapByCreatedAt.get(prevCreatedAt.toIDString());
7561
+ if (!startNode) {
7562
+ const entry = this.elementMapByCreatedAt.get(prevCreatedAt.toIDString());
7563
+ if (entry) {
7564
+ startNode = entry.positionNode;
7565
+ }
7566
+ }
7567
+ if (!startNode) {
7568
+ throw new YorkieError(
7569
+ Code.ErrInvalidArgument,
7570
+ `cant find the given node: ${prevCreatedAt.toIDString()}`
7571
+ );
7572
+ }
7573
+ const prevNode = this.findNextBeforeExecutedAt(startNode, executedAt);
7448
7574
  const newNode = RGATreeListNode.createAfter(prevNode, value);
7449
7575
  if (prevNode === this.last) {
7450
7576
  this.last = newNode;
7451
7577
  }
7452
7578
  this.nodeMapByIndex.insertAfter(prevNode, newNode);
7453
- this.nodeMapByCreatedAt.set(newNode.getCreatedAt().toIDString(), newNode);
7579
+ this.nodeMapByCreatedAt.set(value.getCreatedAt().toIDString(), newNode);
7580
+ this.elementMapByCreatedAt.set(
7581
+ value.getCreatedAt().toIDString(),
7582
+ newNode.getElementEntry()
7583
+ );
7454
7584
  return newNode;
7455
7585
  }
7456
7586
  /**
7457
- * `moveAfter` moves the given `createdAt` element
7458
- * after the `prevCreatedAt` element.
7587
+ * `insertPositionAfter` creates a bare position node after
7588
+ * resolving position via forward skip (RGA insertion rule).
7589
+ * Used by moveAfter. prevCreatedAt is a POSITION node identity.
7590
+ */
7591
+ insertPositionAfter(prevCreatedAt, executedAt) {
7592
+ const startNode = this.nodeMapByCreatedAt.get(prevCreatedAt.toIDString());
7593
+ if (!startNode) {
7594
+ throw new YorkieError(
7595
+ Code.ErrInvalidArgument,
7596
+ `cant find the given node: ${prevCreatedAt.toIDString()}`
7597
+ );
7598
+ }
7599
+ const prevNode = this.findNextBeforeExecutedAt(startNode, executedAt);
7600
+ const newNode = RGATreeListNode.createBarePosition(executedAt);
7601
+ RGATreeListNode.insertNodeAfter(prevNode, newNode);
7602
+ if (prevNode === this.last) {
7603
+ this.last = newNode;
7604
+ }
7605
+ this.nodeMapByIndex.insertAfter(prevNode, newNode);
7606
+ this.nodeMapByCreatedAt.set(executedAt.toIDString(), newNode);
7607
+ return newNode;
7608
+ }
7609
+ /**
7610
+ * `moveAfter` moves the given `createdAt` element after the
7611
+ * `prevCreatedAt` element using LWW position register semantics.
7612
+ * Returns the dead position node (if any) for GC registration.
7459
7613
  */
7460
7614
  moveAfter(prevCreatedAt, createdAt, executedAt) {
7461
- let prevNode = this.nodeMapByCreatedAt.get(prevCreatedAt.toIDString());
7462
- if (!prevNode) {
7615
+ if (!this.nodeMapByCreatedAt.has(prevCreatedAt.toIDString())) {
7463
7616
  throw new YorkieError(
7464
7617
  Code.ErrInvalidArgument,
7465
7618
  `cant find the given node: ${prevCreatedAt.toIDString()}`
7466
7619
  );
7467
7620
  }
7468
- let node = this.nodeMapByCreatedAt.get(createdAt.toIDString());
7469
- if (!node) {
7621
+ const entry = this.elementMapByCreatedAt.get(createdAt.toIDString());
7622
+ if (!entry) {
7470
7623
  throw new YorkieError(
7471
7624
  Code.ErrInvalidArgument,
7472
7625
  `cant find the given node: ${createdAt.toIDString()}`
7473
7626
  );
7474
7627
  }
7475
- if (prevNode !== node && executedAt.after(node.getPositionedAt())) {
7476
- const movedFrom = node.getPrev();
7477
- let nextNode = node.getNext();
7478
- this.release(node);
7479
- node = this.insertAfter(
7480
- prevNode.getCreatedAt(),
7481
- node.getValue(),
7482
- executedAt
7483
- );
7484
- node.getValue().setMovedAt(executedAt);
7485
- node.setMovedFrom(movedFrom);
7486
- while (nextNode && nextNode.getPositionedAt().after(executedAt)) {
7487
- prevNode = node;
7488
- node = nextNode;
7489
- nextNode = node.getNext();
7490
- this.release(node);
7491
- node = this.insertAfter(
7492
- prevNode.getCreatedAt(),
7493
- node.getValue(),
7494
- executedAt
7495
- );
7496
- node.getValue().setMovedAt(executedAt);
7497
- node.setMovedFrom(movedFrom);
7628
+ if (entry.posMovedAt && !executedAt.after(entry.posMovedAt)) {
7629
+ if (this.nodeMapByCreatedAt.has(executedAt.toIDString())) {
7630
+ return void 0;
7498
7631
  }
7632
+ const deadPosNode = this.insertPositionAfter(prevCreatedAt, executedAt);
7633
+ deadPosNode.setRemovedAt(executedAt);
7634
+ this.nodeMapByIndex.splayNode(deadPosNode);
7635
+ return deadPosNode;
7499
7636
  }
7637
+ const newPosNode = this.insertPositionAfter(prevCreatedAt, executedAt);
7638
+ const oldPosNode = entry.positionNode;
7639
+ oldPosNode.setElementEntry(void 0);
7640
+ oldPosNode.setRemovedAt(executedAt);
7641
+ this.nodeMapByIndex.splayNode(oldPosNode);
7642
+ newPosNode.setElementEntry(entry);
7643
+ entry.positionNode = newPosNode;
7644
+ entry.posMovedAt = executedAt;
7645
+ entry.elem.setMovedAt(executedAt);
7646
+ this.nodeMapByIndex.splayNode(newPosNode);
7647
+ return oldPosNode;
7500
7648
  }
7501
7649
  /**
7502
7650
  * `insert` adds the given element after the last node.
@@ -7505,34 +7653,53 @@
7505
7653
  this.insertAfter(this.last.getCreatedAt(), value);
7506
7654
  }
7507
7655
  /**
7508
- * `getByID` returns the element of the given creation time.
7656
+ * `getByID` returns the node of the given creation time.
7657
+ * Checks elementMapByCreatedAt first (for moved elements whose
7658
+ * position node createdAt differs), then nodeMapByCreatedAt.
7509
7659
  */
7510
7660
  getByID(createdAt) {
7661
+ const entry = this.elementMapByCreatedAt.get(createdAt.toIDString());
7662
+ if (entry) {
7663
+ return entry.positionNode;
7664
+ }
7511
7665
  return this.nodeMapByCreatedAt.get(createdAt.toIDString());
7512
7666
  }
7513
7667
  /**
7514
7668
  * `subPathOf` returns the sub path of the given element.
7515
7669
  */
7516
7670
  subPathOf(createdAt) {
7517
- const node = this.nodeMapByCreatedAt.get(createdAt.toIDString());
7518
- if (!node) {
7519
- return;
7671
+ const entry = this.elementMapByCreatedAt.get(createdAt.toIDString());
7672
+ if (!entry) {
7673
+ const node = this.nodeMapByCreatedAt.get(createdAt.toIDString());
7674
+ if (!node) {
7675
+ return;
7676
+ }
7677
+ return String(this.nodeMapByIndex.indexOf(node));
7520
7678
  }
7521
- return String(this.nodeMapByIndex.indexOf(node));
7679
+ return String(this.nodeMapByIndex.indexOf(entry.positionNode));
7522
7680
  }
7523
7681
  /**
7524
- * `purge` physically purges element.
7682
+ * `purge` physically purges the given child. Handles both dead
7683
+ * position nodes (GCChild from GCParent path) and CRDTElements
7684
+ * (from CRDTContainer path).
7525
7685
  */
7526
- purge(element) {
7527
- const node = this.nodeMapByCreatedAt.get(
7686
+ purge(child) {
7687
+ if (child instanceof RGATreeListNode) {
7688
+ this.release(child);
7689
+ return;
7690
+ }
7691
+ const element = child;
7692
+ const entry = this.elementMapByCreatedAt.get(
7528
7693
  element.getCreatedAt().toIDString()
7529
7694
  );
7530
- if (!node) {
7695
+ if (!entry) {
7531
7696
  throw new YorkieError(
7532
7697
  Code.ErrInvalidArgument,
7533
7698
  `fail to find the given createdAt: ${element.getCreatedAt().toIDString()}`
7534
7699
  );
7535
7700
  }
7701
+ const node = entry.positionNode;
7702
+ this.elementMapByCreatedAt.delete(element.getCreatedAt().toIDString());
7536
7703
  this.release(node);
7537
7704
  }
7538
7705
  /**
@@ -7543,42 +7710,69 @@
7543
7710
  return;
7544
7711
  }
7545
7712
  const node = this.nodeMapByIndex.findForArray(idx);
7546
- const rgaNode = node;
7547
- return rgaNode;
7713
+ return node;
7548
7714
  }
7549
7715
  /**
7550
- * `getPrevCreatedAt` returns a creation time of the previous node.
7716
+ * `findPrevCreatedAt` returns the position node's createdAt of the
7717
+ * previous element. This returns a position identity suitable for
7718
+ * use as prevCreatedAt in moveAfter.
7551
7719
  */
7552
- getPrevCreatedAt(createdAt) {
7553
- let node = this.nodeMapByCreatedAt.get(createdAt.toIDString());
7720
+ findPrevCreatedAt(createdAt) {
7721
+ const entry = this.elementMapByCreatedAt.get(createdAt.toIDString());
7722
+ if (!entry) {
7723
+ throw new YorkieError(
7724
+ Code.ErrInvalidArgument,
7725
+ `cant find the given node: ${createdAt.toIDString()}`
7726
+ );
7727
+ }
7728
+ let node = entry.positionNode;
7554
7729
  do {
7555
7730
  node = node.getPrev();
7556
- } while (this.dummyHead !== node && node.isRemoved());
7557
- return node.getValue().getCreatedAt();
7731
+ if (!node.getElementEntry()) {
7732
+ continue;
7733
+ }
7734
+ if (this.dummyHead === node || !node.isRemoved()) {
7735
+ break;
7736
+ }
7737
+ } while (node);
7738
+ return node.getPositionCreatedAt();
7739
+ }
7740
+ /**
7741
+ * `getPrevCreatedAt` returns the position node's createdAt of the
7742
+ * previous element. Delegates to findPrevCreatedAt.
7743
+ */
7744
+ getPrevCreatedAt(createdAt) {
7745
+ return this.findPrevCreatedAt(createdAt);
7558
7746
  }
7559
7747
  /**
7560
7748
  * `delete` deletes the node of the given creation time.
7561
7749
  */
7562
7750
  delete(createdAt, editedAt) {
7563
- const node = this.nodeMapByCreatedAt.get(createdAt.toIDString());
7751
+ const entry = this.elementMapByCreatedAt.get(createdAt.toIDString());
7752
+ if (!entry) {
7753
+ throw new YorkieError(
7754
+ Code.ErrInvalidArgument,
7755
+ `cant find the given node: ${createdAt.toIDString()}`
7756
+ );
7757
+ }
7758
+ const node = entry.positionNode;
7564
7759
  const alreadyRemoved = node.isRemoved();
7565
- if (node.remove(editedAt) && !alreadyRemoved) {
7760
+ if (entry.elem.remove(editedAt) && !alreadyRemoved) {
7566
7761
  this.nodeMapByIndex.splayNode(node);
7567
7762
  }
7568
- return node.getValue();
7763
+ return entry.elem;
7569
7764
  }
7570
7765
  /**
7571
7766
  * `set` sets the given element at the given creation time.
7572
7767
  */
7573
7768
  set(createdAt, element, executedAt) {
7574
- const node = this.nodeMapByCreatedAt.get(createdAt.toIDString());
7575
- if (!node) {
7769
+ if (!this.elementMapByCreatedAt.has(createdAt.toIDString())) {
7576
7770
  throw new YorkieError(
7577
7771
  Code.ErrInvalidArgument,
7578
7772
  `cant find the given node: ${createdAt.toIDString()}`
7579
7773
  );
7580
7774
  }
7581
- this.insertAfter(node.getCreatedAt(), element, executedAt);
7775
+ this.insertAfter(createdAt, element, executedAt);
7582
7776
  return this.delete(createdAt, executedAt);
7583
7777
  }
7584
7778
  /**
@@ -7607,18 +7801,80 @@
7607
7801
  return this.last.getValue();
7608
7802
  }
7609
7803
  /**
7610
- * `getLastCreatedAt` returns the creation time of last element.
7804
+ * `getLastCreatedAt` returns the position node's createdAt of the
7805
+ * last node in the linked list. This is a position identity
7806
+ * suitable for use as prevCreatedAt.
7611
7807
  */
7612
7808
  getLastCreatedAt() {
7613
- return this.last.getCreatedAt();
7809
+ return this.last.getPositionCreatedAt();
7614
7810
  }
7615
7811
  /**
7616
- * `toTestString` returns a String containing the meta data of the node id
7617
- * for debugging purpose.
7812
+ * `posCreatedAt` returns the createdAt of the position node
7813
+ * currently holding the element. Used to convert element identity
7814
+ * to position identity.
7815
+ */
7816
+ posCreatedAt(elemCreatedAt) {
7817
+ const entry = this.elementMapByCreatedAt.get(elemCreatedAt.toIDString());
7818
+ if (!entry) {
7819
+ throw new YorkieError(
7820
+ Code.ErrInvalidArgument,
7821
+ `cant find the given node: ${elemCreatedAt.toIDString()}`
7822
+ );
7823
+ }
7824
+ return entry.positionNode.getPositionCreatedAt();
7825
+ }
7826
+ /**
7827
+ * `addDeadPosition` appends a dead position node during snapshot
7828
+ * restoration.
7829
+ */
7830
+ addDeadPosition(posCreatedAt, removedAt) {
7831
+ const node = RGATreeListNode.createBarePosition(posCreatedAt);
7832
+ node.setRemovedAt(removedAt);
7833
+ const prevNode = this.last;
7834
+ RGATreeListNode.insertNodeAfter(prevNode, node);
7835
+ this.last = node;
7836
+ this.nodeMapByIndex.insertAfter(prevNode, node);
7837
+ this.nodeMapByCreatedAt.set(posCreatedAt.toIDString(), node);
7838
+ }
7839
+ /**
7840
+ * `addMovedElement` appends an element with explicit position
7841
+ * identity during snapshot restoration.
7842
+ */
7843
+ addMovedElement(elem, posCreatedAt, posMovedAt) {
7844
+ const entry = new ElementEntry(elem);
7845
+ entry.posMovedAt = posMovedAt;
7846
+ const node = RGATreeListNode.createBarePosition(posCreatedAt);
7847
+ node.setElementEntry(entry);
7848
+ entry.positionNode = node;
7849
+ const prevNode = this.last;
7850
+ RGATreeListNode.insertNodeAfter(prevNode, node);
7851
+ this.last = node;
7852
+ this.nodeMapByIndex.insertAfter(prevNode, node);
7853
+ this.nodeMapByCreatedAt.set(posCreatedAt.toIDString(), node);
7854
+ this.elementMapByCreatedAt.set(elem.getCreatedAt().toIDString(), entry);
7855
+ }
7856
+ /**
7857
+ * `allNodes` returns all nodes including dead position nodes.
7858
+ */
7859
+ allNodes() {
7860
+ const nodes = [];
7861
+ let current = this.dummyHead.getNext();
7862
+ while (current) {
7863
+ nodes.push(current);
7864
+ current = current.getNext();
7865
+ }
7866
+ return nodes;
7867
+ }
7868
+ /**
7869
+ * `toTestString` returns a String containing the meta data of the
7870
+ * node id for debugging purpose.
7618
7871
  */
7619
7872
  toTestString() {
7620
7873
  const json = [];
7621
7874
  for (const node of this) {
7875
+ if (!node.getElementEntry()) {
7876
+ continue;
7877
+ }
7622
7878
  const elem = `${node.getCreatedAt().toIDString()}:${node.getValue().toJSON()}`;
7623
7879
  if (node.isRemoved()) {
7624
7880
  json.push(`{${elem}}`);
@@ -7675,10 +7931,11 @@
7675
7931
  this.elements.insertAfter(prevCreatedAt, value, executedAt);
7676
7932
  }
7677
7933
  /**
7678
- * `moveAfter` moves the given `createdAt` element after the `prevCreatedAt`.
7934
+ * `moveAfter` moves the given `createdAt` element after the
7935
+ * `prevCreatedAt`. Returns the dead position node for GC.
7679
7936
  */
7680
7937
  moveAfter(prevCreatedAt, createdAt, executedAt) {
7681
- this.elements.moveAfter(prevCreatedAt, createdAt, executedAt);
7938
+ return this.elements.moveAfter(prevCreatedAt, createdAt, executedAt);
7682
7939
  }
7683
7940
  /**
7684
7941
  * `get` returns the element of the given index.
@@ -7707,11 +7964,20 @@
7707
7964
  return this.elements.getLast();
7708
7965
  }
7709
7966
  /**
7710
- * `getPrevCreatedAt` returns the creation time of the previous node.
7967
+ * `getPrevCreatedAt` returns the creation time of the previous
7968
+ * node.
7711
7969
  */
7712
7970
  getPrevCreatedAt(createdAt) {
7713
7971
  return this.elements.getPrevCreatedAt(createdAt);
7714
7972
  }
7973
+ /**
7974
+ * `posCreatedAt` returns the createdAt of the position node
7975
+ * currently holding the element. Used to convert element identity
7976
+ * to position identity for moves.
7977
+ */
7978
+ posCreatedAt(elemCreatedAt) {
7979
+ return this.elements.posCreatedAt(elemCreatedAt);
7980
+ }
7715
7981
  /**
7716
7982
  * `delete` deletes the element of the given creation time.
7717
7983
  */
@@ -7725,7 +7991,8 @@
7725
7991
  return this.elements.deleteByIndex(index, editedAt);
7726
7992
  }
7727
7993
  /**
7728
- * `set` sets the given element at the given position of the creation time.
7994
+ * `set` sets the given element at the given position of the
7995
+ * creation time.
7729
7996
  */
7730
7997
  set(createdAt, value, executedAt) {
7731
7998
  return this.elements.set(createdAt, value, executedAt);
@@ -7743,18 +8010,19 @@
7743
8010
  return this.elements.length;
7744
8011
  }
7745
8012
  /**
7746
- * `[Symbol.iterator]` returns an iterator for the elements in this array.
8013
+ * `[Symbol.iterator]` returns an iterator for the elements in
8014
+ * this array.
7747
8015
  */
7748
8016
  *[Symbol.iterator]() {
7749
8017
  for (const node of this.elements) {
7750
- if (!node.isRemoved()) {
8018
+ if (node.getElementEntry() && !node.isRemoved()) {
7751
8019
  yield node.getValue();
7752
8020
  }
7753
8021
  }
7754
8022
  }
7755
8023
  /**
7756
- * `toTestString` returns a String containing the meta data of this value
7757
- * for debugging purpose.
8024
+ * `toTestString` returns a String containing the meta data of
8025
+ * this value for debugging purpose.
7758
8026
  */
7759
8027
  toTestString() {
7760
8028
  return this.elements.toTestString();
@@ -7764,6 +8032,9 @@
7764
8032
  */
7765
8033
  getDescendants(callback) {
7766
8034
  for (const node of this.elements) {
8035
+ if (!node.getElementEntry()) {
8036
+ continue;
8037
+ }
7767
8038
  const element = node.getValue();
7768
8039
  if (callback(element, this)) {
7769
8040
  return;
@@ -7825,21 +8096,52 @@
7825
8096
  return this.toJSON();
7826
8097
  }
7827
8098
  /**
7828
- * `getElements` returns an array of elements contained in this RGATreeList.
8099
+ * `getElements` returns the underlying RGATreeList.
7829
8100
  */
7830
8101
  getElements() {
7831
8102
  return this.elements;
7832
8103
  }
8104
+ /**
8105
+ * `getRGATreeList` returns the underlying RGATreeList (GCParent
8106
+ * for dead positions).
8107
+ */
8108
+ getRGATreeList() {
8109
+ return this.elements;
8110
+ }
8111
+ /**
8112
+ * `getAllRGANodes` returns all RGA nodes including dead position
8113
+ * nodes.
8114
+ */
8115
+ getAllRGANodes() {
8116
+ return this.elements.allNodes();
8117
+ }
7833
8118
  /**
7834
8119
  * `deepcopy` copies itself deeply.
7835
8120
  */
7836
8121
  deepcopy() {
7837
8122
  const clone = CRDTArray.create(this.getCreatedAt());
7838
8123
  for (const node of this.elements) {
7839
- clone.elements.insertAfter(
7840
- clone.getLastCreatedAt(),
7841
- node.getValue().deepcopy()
7842
- );
8124
+ if (!node.getElementEntry()) {
8125
+ const removedAt = node.getRemovedAt();
8126
+ if (removedAt) {
8127
+ clone.elements.addDeadPosition(
8128
+ node.getPositionCreatedAt(),
8129
+ removedAt
8130
+ );
8131
+ }
8132
+ continue;
8133
+ }
8134
+ const value = node.getValue().deepcopy();
8135
+ const posMovedAt = node.getPositionMovedAt();
8136
+ if (posMovedAt) {
8137
+ clone.elements.addMovedElement(
8138
+ value,
8139
+ node.getPositionCreatedAt(),
8140
+ posMovedAt
8141
+ );
8142
+ } else {
8143
+ clone.elements.insertAfter(clone.getLastCreatedAt(), value);
8144
+ }
7843
8145
  }
7844
8146
  clone.setRemovedAt(this.getRemovedAt());
7845
8147
  clone.setMovedAt(this.getMovedAt());
@@ -8096,6 +8398,9 @@
8096
8398
  if (removed) {
8097
8399
  root.registerRemovedElement(removed);
8098
8400
  }
8401
+ if (value.getRemovedAt()) {
8402
+ root.registerRemovedElement(value);
8403
+ }
8099
8404
  return {
8100
8405
  opInfos: [
8101
8406
  {
@@ -8188,7 +8493,17 @@
8188
8493
  const array = parentObject;
8189
8494
  const reverseOp = this.toReverseOperation(array);
8190
8495
  const previousIndex = Number(array.subPathOf(this.createdAt));
8191
- array.moveAfter(this.prevCreatedAt, this.createdAt, this.getExecutedAt());
8496
+ const deadNode = array.moveAfter(
8497
+ this.prevCreatedAt,
8498
+ this.createdAt,
8499
+ this.getExecutedAt()
8500
+ );
8501
+ if (deadNode) {
8502
+ root.registerGCPair({
8503
+ parent: array.getRGATreeList(),
8504
+ child: deadNode
8505
+ });
8506
+ }
8192
8507
  const index = Number(array.subPathOf(this.createdAt));
8193
8508
  return {
8194
8509
  opInfos: [
@@ -8211,7 +8526,8 @@
8211
8526
  );
8212
8527
  }
8213
8528
  /**
8214
- * `getEffectedCreatedAt` returns the creation time of the effected element.
8529
+ * `getEffectedCreatedAt` returns the creation time of the
8530
+ * effected element.
8215
8531
  */
8216
8532
  getEffectedCreatedAt() {
8217
8533
  return this.createdAt;
@@ -8223,7 +8539,8 @@
8223
8539
  return `${this.getParentCreatedAt().toTestString()}.MOVE`;
8224
8540
  }
8225
8541
  /**
8226
- * `getPrevCreatedAt` returns the creation time of previous element.
8542
+ * `getPrevCreatedAt` returns the creation time of previous
8543
+ * element.
8227
8544
  */
8228
8545
  getPrevCreatedAt() {
8229
8546
  return this.prevCreatedAt;
@@ -8235,7 +8552,8 @@
8235
8552
  return this.createdAt;
8236
8553
  }
8237
8554
  /**
8238
- * `setPrevCreatedAt` sets the creation time of the previous element.
8555
+ * `setPrevCreatedAt` sets the creation time of the previous
8556
+ * element.
8239
8557
  */
8240
8558
  setPrevCreatedAt(createdAt) {
8241
8559
  this.prevCreatedAt = createdAt;
@@ -10816,6 +11134,32 @@
10816
11134
  }
10817
11135
  actualRight.push(child);
10818
11136
  }
11137
+ if (versionVector) {
11138
+ const movedToLeft = [];
11139
+ const remaining = [];
11140
+ let boundaryReached = false;
11141
+ for (const child of actualRight) {
11142
+ if (!boundaryReached) {
11143
+ if (child.insPrevID !== void 0 && !child.isText) {
11144
+ remaining.push(child);
11145
+ continue;
11146
+ }
11147
+ const actorID = child.id.getCreatedAt().getActorID();
11148
+ const knownLamport = versionVector.get(actorID);
11149
+ if (knownLamport === void 0 || knownLamport < child.id.getCreatedAt().getLamport()) {
11150
+ movedToLeft.push(child);
11151
+ continue;
11152
+ }
11153
+ }
11154
+ boundaryReached = true;
11155
+ remaining.push(child);
11156
+ }
11157
+ if (movedToLeft.length > 0) {
11158
+ left.push(...movedToLeft);
11159
+ actualRight.length = 0;
11160
+ actualRight.push(...remaining);
11161
+ }
11162
+ }
10819
11163
  this._children = left;
10820
11164
  clone._children = actualRight;
10821
11165
  this.visibleSize = this._children.reduce(
@@ -11579,7 +11923,7 @@
11579
11923
  CRDTTreeNodeID.of(issueTimeTicket(), 0),
11580
11924
  this.type,
11581
11925
  void 0,
11582
- void 0,
11926
+ this.attrs?.deepcopy(),
11583
11927
  this.removedAt
11584
11928
  );
11585
11929
  }
@@ -11592,8 +11936,14 @@
11592
11936
  split.insPrevID = this.id;
11593
11937
  if (this.insNextID) {
11594
11938
  const insNext = tree.findFloorNode(this.insNextID);
11595
- insNext.insPrevID = split.id;
11596
11939
  split.insNextID = this.insNextID;
11940
+ if (insNext) {
11941
+ insNext.insPrevID = split.id;
11942
+ if (!this.isText && insNext.parent && !insNext.isRemoved && insNext.parent !== split.parent && split.allChildren.length === 0) {
11943
+ split.parent.detachChild(split);
11944
+ insNext.parent.insertBefore(split, insNext);
11945
+ }
11946
+ }
11597
11947
  }
11598
11948
  this.insNextID = split.id;
11599
11949
  tree.registerNode(split);
@@ -11817,7 +12167,7 @@
11817
12167
  * given node, advancing past element-type split siblings that the editing
11818
12168
  * client did not know about (not in versionVector).
11819
12169
  */
11820
- advancePastUnknownSplitSiblings(node, versionVector) {
12170
+ advancePastUnknownSplitSiblings(node, versionVector, relaxParentCheck = false, skipActorID) {
11821
12171
  if (!versionVector || !node) {
11822
12172
  return node;
11823
12173
  }
@@ -11827,10 +12177,13 @@
11827
12177
  if (!next || next.isText) {
11828
12178
  break;
11829
12179
  }
11830
- if (next.parent !== current.parent) {
12180
+ if (!relaxParentCheck && next.parent !== current.parent) {
11831
12181
  break;
11832
12182
  }
11833
12183
  const actorID = next.id.getCreatedAt().getActorID();
12184
+ if (skipActorID !== void 0 && actorID === skipActorID) {
12185
+ break;
12186
+ }
11834
12187
  const knownLamport = versionVector.get(actorID);
11835
12188
  if (knownLamport !== void 0 && knownLamport >= next.id.getCreatedAt().getLamport()) {
11836
12189
  break;
@@ -11999,6 +12352,53 @@
11999
12352
  addDataSizes(diff, curr.getDataSize());
12000
12353
  }
12001
12354
  }
12355
+ if (tokenType === TokenType.Start && versionVector !== void 0) {
12356
+ let current = node;
12357
+ while (current.insNextID) {
12358
+ const next = this.findFloorNode(current.insNextID);
12359
+ if (!next || next.isText) {
12360
+ break;
12361
+ }
12362
+ if (ticketKnown(versionVector, next.id.getCreatedAt())) {
12363
+ break;
12364
+ }
12365
+ const siblingPairs = next.setAttrs(attributes, editedAt);
12366
+ const siblingAffectedAttrs = siblingPairs.reduce(
12367
+ (acc, [, curr]) => {
12368
+ if (curr) {
12369
+ acc[curr.getKey()] = attrs[curr.getKey()];
12370
+ }
12371
+ return acc;
12372
+ },
12373
+ {}
12374
+ );
12375
+ if (Object.keys(siblingAffectedAttrs).length > 0) {
12376
+ const parentOfNext = next.parent;
12377
+ const previousNext = next.prevSibling || parentOfNext;
12378
+ changes.push({
12379
+ type: "style",
12380
+ from: this.toIndex(parentOfNext, previousNext),
12381
+ to: this.toIndex(next, next),
12382
+ fromPath: this.toPath(parentOfNext, previousNext),
12383
+ toPath: this.toPath(next, next),
12384
+ actor: editedAt.getActorID(),
12385
+ value: siblingAffectedAttrs
12386
+ });
12387
+ }
12388
+ for (const [prev] of siblingPairs) {
12389
+ if (prev) {
12390
+ pairs.push({ parent: next, child: prev });
12391
+ }
12392
+ }
12393
+ for (const [key] of Object.entries(attrs)) {
12394
+ const curr = next.attrs?.getNodeMapByKey().get(key);
12395
+ if (curr !== void 0) {
12396
+ addDataSizes(diff, curr.getDataSize());
12397
+ }
12398
+ }
12399
+ current = next;
12400
+ }
12401
+ }
12002
12402
  }
12003
12403
  }
12004
12404
  );
@@ -12065,6 +12465,43 @@
12065
12465
  toPath: this.toPath(node, node),
12066
12466
  value: attributesToRemove
12067
12467
  });
12468
+ if (tokenType === TokenType.Start && versionVector !== void 0) {
12469
+ let current = node;
12470
+ while (current.insNextID) {
12471
+ const next = this.findFloorNode(current.insNextID);
12472
+ if (!next || next.isText) {
12473
+ break;
12474
+ }
12475
+ if (ticketKnown(versionVector, next.id.getCreatedAt())) {
12476
+ break;
12477
+ }
12478
+ if (!next.attrs) {
12479
+ next.attrs = new RHT();
12480
+ }
12481
+ let removedAny = false;
12482
+ for (const value of attributesToRemove) {
12483
+ const nodesTobeRemoved = next.attrs.remove(value, editedAt);
12484
+ removedAny = removedAny || nodesTobeRemoved.length > 0;
12485
+ for (const rhtNode of nodesTobeRemoved) {
12486
+ pairs.push({ parent: next, child: rhtNode });
12487
+ }
12488
+ }
12489
+ if (removedAny) {
12490
+ const parentOfNext = next.parent;
12491
+ const previousNext = next.prevSibling || parentOfNext;
12492
+ changes.push({
12493
+ actor: editedAt.getActorID(),
12494
+ type: "removeStyle",
12495
+ from: this.toIndex(parentOfNext, previousNext),
12496
+ to: this.toIndex(next, next),
12497
+ fromPath: this.toPath(parentOfNext, previousNext),
12498
+ toPath: this.toPath(next, next),
12499
+ value: attributesToRemove
12500
+ });
12501
+ }
12502
+ current = next;
12503
+ }
12504
+ }
12068
12505
  }
12069
12506
  }
12070
12507
  );
@@ -12087,6 +12524,23 @@
12087
12524
  addDataSizes(diff, diffTo, diffFrom);
12088
12525
  const fromLeft = fromLeftRaw !== fromParent ? this.advancePastUnknownSplitSiblings(fromLeftRaw, versionVector) : fromLeftRaw;
12089
12526
  const toLeft = toLeftRaw !== toParent ? this.advancePastUnknownSplitSiblings(toLeftRaw, versionVector) : toLeftRaw;
12527
+ let collectFromParent = fromParent;
12528
+ let collectFromLeft = fromLeft;
12529
+ if (fromLeft !== fromParent && fromParent !== toParent) {
12530
+ let current = fromLeft;
12531
+ while (current.insNextID) {
12532
+ const next = this.findFloorNode(current.insNextID);
12533
+ if (!next || next.isText) {
12534
+ break;
12535
+ }
12536
+ if (next.parent && next.parent === toParent) {
12537
+ collectFromLeft = next;
12538
+ collectFromParent = toParent;
12539
+ break;
12540
+ }
12541
+ current = next;
12542
+ }
12543
+ }
12090
12544
  const fromIdx = this.toIndex(fromParent, fromLeft);
12091
12545
  const fromPath = this.toPath(fromParent, fromLeft);
12092
12546
  const nodesToBeRemoved = [];
@@ -12095,8 +12549,8 @@
12095
12549
  const toBeMergedNodes = [];
12096
12550
  const preTombstoned = /* @__PURE__ */ new Set();
12097
12551
  this.traverseInPosRange(
12098
- fromParent,
12099
- fromLeft,
12552
+ collectFromParent,
12553
+ collectFromLeft,
12100
12554
  toParent,
12101
12555
  toLeft,
12102
12556
  ([node, tokenType], ended) => {
@@ -12200,9 +12654,20 @@
12200
12654
  let parent = fromParent;
12201
12655
  let left = fromLeft;
12202
12656
  while (splitCount < splitLevel) {
12657
+ if (left !== parent) {
12658
+ left = this.advancePastUnknownSplitSiblings(
12659
+ left,
12660
+ versionVector,
12661
+ true,
12662
+ editedAt.getActorID()
12663
+ );
12664
+ if (left.parent && left.parent !== parent) {
12665
+ parent = left.parent;
12666
+ }
12667
+ }
12203
12668
  parent.split(
12204
12669
  this,
12205
- parent.findOffset(left, true) + 1,
12670
+ left !== parent ? parent.findOffset(left, true) + 1 : 0,
12206
12671
  issueTimeTicket,
12207
12672
  versionVector
12208
12673
  );
@@ -12809,10 +13274,10 @@
12809
13274
  );
12810
13275
  this.lastToIdx = preEditFromIdx + removedSize;
12811
13276
  let reverseOp;
12812
- const isPureL1Split = this.splitLevel === 1 && !this.contents?.length && removedNodes.length === 0;
13277
+ const isPureSplit = this.splitLevel > 0 && !this.contents?.length && removedNodes.length === 0;
12813
13278
  if (this.splitLevel === 0) {
12814
13279
  reverseOp = this.toReverseOperation(tree, removedNodes, preEditFromIdx);
12815
- } else if (isPureL1Split) {
13280
+ } else if (isPureSplit) {
12816
13281
  reverseOp = this.toSplitReverseOperation(tree, preEditFromIdx);
12817
13282
  }
12818
13283
  root.acc(diff);
@@ -14823,14 +15288,26 @@
14823
15288
  }
14824
15289
  return pbRHTNodes;
14825
15290
  }
14826
- function toRGANodes(rgaTreeList) {
15291
+ function toRGANodes(arr) {
14827
15292
  const pbRGANodes = [];
14828
- for (const rgaTreeListNode of rgaTreeList) {
14829
- pbRGANodes.push(
14830
- create(RGANodeSchema, {
14831
- element: toElement(rgaTreeListNode.getValue())
14832
- })
14833
- );
15293
+ for (const rgaNode of arr.getAllRGANodes()) {
15294
+ if (!rgaNode.getElementEntry()) {
15295
+ pbRGANodes.push(
15296
+ create(RGANodeSchema, {
15297
+ positionCreatedAt: toTimeTicket(rgaNode.getPositionCreatedAt()),
15298
+ positionRemovedAt: toTimeTicket(rgaNode.getRemovedAt())
15299
+ })
15300
+ );
15301
+ continue;
15302
+ }
15303
+ const pbNode = create(RGANodeSchema, {
15304
+ element: toElement(rgaNode.getValue())
15305
+ });
15306
+ if (rgaNode.getPositionMovedAt()) {
15307
+ pbNode.positionMovedAt = toTimeTicket(rgaNode.getPositionMovedAt());
15308
+ pbNode.positionCreatedAt = toTimeTicket(rgaNode.getPositionCreatedAt());
15309
+ }
15310
+ pbRGANodes.push(pbNode);
14834
15311
  }
14835
15312
  return pbRGANodes;
14836
15313
  }
@@ -14930,7 +15407,7 @@
14930
15407
  body: {
14931
15408
  case: "jsonArray",
14932
15409
  value: create(JSONElement_JSONArraySchema, {
14933
- nodes: toRGANodes(arr.getElements()),
15410
+ nodes: toRGANodes(arr),
14934
15411
  createdAt: toTimeTicket(arr.getCreatedAt()),
14935
15412
  movedAt: toTimeTicket(arr.getMovedAt()),
14936
15413
  removedAt: toTimeTicket(arr.getRemovedAt())
@@ -15468,7 +15945,32 @@
15468
15945
  function fromArray(pbArray) {
15469
15946
  const rgaTreeList = new RGATreeList();
15470
15947
  for (const pbRGANode of pbArray.nodes) {
15471
- rgaTreeList.insert(fromElement(pbRGANode.element));
15948
+ if (!pbRGANode.element) {
15949
+ if (!pbRGANode.positionCreatedAt || !pbRGANode.positionRemovedAt) {
15950
+ throw new YorkieError(
15951
+ Code.ErrInvalidArgument,
15952
+ "dead RGA position node missing position timestamps"
15953
+ );
15954
+ }
15955
+ const posCreatedAt = fromTimeTicket(pbRGANode.positionCreatedAt);
15956
+ const posRemovedAt = fromTimeTicket(pbRGANode.positionRemovedAt);
15957
+ rgaTreeList.addDeadPosition(posCreatedAt, posRemovedAt);
15958
+ continue;
15959
+ }
15960
+ const elem = fromElement(pbRGANode.element);
15961
+ const posMovedAt = fromTimeTicket(pbRGANode.positionMovedAt);
15962
+ if (posMovedAt) {
15963
+ if (!pbRGANode.positionCreatedAt) {
15964
+ throw new YorkieError(
15965
+ Code.ErrInvalidArgument,
15966
+ "moved RGA node missing position_created_at"
15967
+ );
15968
+ }
15969
+ const posCreatedAt = fromTimeTicket(pbRGANode.positionCreatedAt);
15970
+ rgaTreeList.addMovedElement(elem, posCreatedAt, posMovedAt);
15971
+ } else {
15972
+ rgaTreeList.insert(elem);
15973
+ }
15472
15974
  }
15473
15975
  const arr = new CRDTArray(fromTimeTicket(pbArray.createdAt), rgaTreeList);
15474
15976
  arr.setMovedAt(fromTimeTicket(pbArray.movedAt));
@@ -16256,10 +16758,16 @@
16256
16758
  };
16257
16759
  } else if (method === "insertAfter") {
16258
16760
  return (prevID, value) => {
16761
+ let posCreatedAt;
16762
+ try {
16763
+ posCreatedAt = target.posCreatedAt(prevID);
16764
+ } catch {
16765
+ posCreatedAt = prevID;
16766
+ }
16259
16767
  const inserted = ArrayProxy.insertAfterInternal(
16260
16768
  context,
16261
16769
  target,
16262
- prevID,
16770
+ posCreatedAt,
16263
16771
  value
16264
16772
  );
16265
16773
  return toWrappedElement(context, inserted);
@@ -16444,7 +16952,7 @@
16444
16952
  static moveBeforeInternal(context, target, nextCreatedAt, createdAt) {
16445
16953
  const ticket = context.issueTimeTicket();
16446
16954
  const prevCreatedAt = target.getPrevCreatedAt(nextCreatedAt);
16447
- target.moveAfter(prevCreatedAt, createdAt, ticket);
16955
+ const deadNode = target.moveAfter(prevCreatedAt, createdAt, ticket);
16448
16956
  context.push(
16449
16957
  MoveOperation.create(
16450
16958
  target.getCreatedAt(),
@@ -16453,26 +16961,45 @@
16453
16961
  ticket
16454
16962
  )
16455
16963
  );
16964
+ if (deadNode) {
16965
+ context.registerGCPair({
16966
+ parent: target.getRGATreeList(),
16967
+ child: deadNode
16968
+ });
16969
+ }
16456
16970
  }
16457
16971
  /**
16458
16972
  * `moveAfterInternal` moves the given `createdAt` element
16459
- * after the specific element.
16973
+ * after the specific element. Converts element identity to
16974
+ * position identity for the prevCreatedAt.
16460
16975
  */
16461
16976
  static moveAfterInternal(context, target, prevCreatedAt, createdAt) {
16462
16977
  const ticket = context.issueTimeTicket();
16978
+ let posCreatedAt;
16979
+ try {
16980
+ posCreatedAt = target.posCreatedAt(prevCreatedAt);
16981
+ } catch {
16982
+ posCreatedAt = prevCreatedAt;
16983
+ }
16984
+ const deadNode = target.moveAfter(posCreatedAt, createdAt, ticket);
16463
16985
  context.push(
16464
16986
  MoveOperation.create(
16465
16987
  target.getCreatedAt(),
16466
- prevCreatedAt,
16988
+ posCreatedAt,
16467
16989
  createdAt,
16468
16990
  ticket
16469
16991
  )
16470
16992
  );
16471
- target.moveAfter(prevCreatedAt, createdAt, ticket);
16993
+ if (deadNode) {
16994
+ context.registerGCPair({
16995
+ parent: target.getRGATreeList(),
16996
+ child: deadNode
16997
+ });
16998
+ }
16472
16999
  }
16473
17000
  /**
16474
- * `moveAfterByIndexInternal` moves the given element to its new position
16475
- * after the given previous element.
17001
+ * `moveAfterByIndexInternal` moves the given element to its new
17002
+ * position after the given previous element.
16476
17003
  */
16477
17004
  static moveAfterByIndexInternal(context, target, prevIndex, targetIndex) {
16478
17005
  const prevElem = target.get(prevIndex);
@@ -16503,7 +17030,7 @@
16503
17030
  static moveFrontInternal(context, target, createdAt) {
16504
17031
  const ticket = context.issueTimeTicket();
16505
17032
  const head = target.getHead();
16506
- target.moveAfter(head.getCreatedAt(), createdAt, ticket);
17033
+ const deadNode = target.moveAfter(head.getCreatedAt(), createdAt, ticket);
16507
17034
  context.push(
16508
17035
  MoveOperation.create(
16509
17036
  target.getCreatedAt(),
@@ -16512,6 +17039,12 @@
16512
17039
  ticket
16513
17040
  )
16514
17041
  );
17042
+ if (deadNode) {
17043
+ context.registerGCPair({
17044
+ parent: target.getRGATreeList(),
17045
+ child: deadNode
17046
+ });
17047
+ }
16515
17048
  }
16516
17049
  /**
16517
17050
  * `moveLastInternal` moves the given `createdAt` element
@@ -16520,13 +17053,20 @@
16520
17053
  static moveLastInternal(context, target, createdAt) {
16521
17054
  const ticket = context.issueTimeTicket();
16522
17055
  const last = target.getLastCreatedAt();
16523
- target.moveAfter(last, createdAt, ticket);
17056
+ const deadNode = target.moveAfter(last, createdAt, ticket);
16524
17057
  context.push(
16525
17058
  MoveOperation.create(target.getCreatedAt(), last, createdAt, ticket)
16526
17059
  );
17060
+ if (deadNode) {
17061
+ context.registerGCPair({
17062
+ parent: target.getRGATreeList(),
17063
+ child: deadNode
17064
+ });
17065
+ }
16527
17066
  }
16528
17067
  /**
16529
- * `insertAfterInternal` inserts the value after the previously created element.
17068
+ * `insertAfterInternal` inserts the value after the previously
17069
+ * created element.
16530
17070
  */
16531
17071
  static insertAfterInternal(context, target, prevCreatedAt, value) {
16532
17072
  const createdAt = context.issueTimeTicket();
@@ -16554,12 +17094,13 @@
16554
17094
  `index out of bounds: ${index}`
16555
17095
  );
16556
17096
  }
16557
- ArrayProxy.insertAfterInternal(
16558
- context,
16559
- target,
16560
- prevElem.getCreatedAt(),
16561
- value
16562
- );
17097
+ let posCreatedAt;
17098
+ try {
17099
+ posCreatedAt = target.posCreatedAt(prevElem.getCreatedAt());
17100
+ } catch {
17101
+ posCreatedAt = prevElem.getCreatedAt();
17102
+ }
17103
+ ArrayProxy.insertAfterInternal(context, target, posCreatedAt, value);
16563
17104
  return target;
16564
17105
  }
16565
17106
  /**
@@ -16658,7 +17199,17 @@
16658
17199
  }
16659
17200
  }
16660
17201
  if (items) {
16661
- let previousID = from === 0 ? target.getHead().getID() : target.get(from - 1).getID();
17202
+ let previousID;
17203
+ if (from === 0) {
17204
+ previousID = target.getHead().getID();
17205
+ } else {
17206
+ const elemID = target.get(from - 1).getID();
17207
+ try {
17208
+ previousID = target.posCreatedAt(elemID);
17209
+ } catch {
17210
+ previousID = elemID;
17211
+ }
17212
+ }
16662
17213
  for (const item of items) {
16663
17214
  const newElem = ArrayProxy.insertAfterInternal(
16664
17215
  context,
@@ -18008,6 +18559,16 @@
18008
18559
  this.registerGCPair(pair);
18009
18560
  }
18010
18561
  }
18562
+ if (elem instanceof CRDTArray) {
18563
+ for (const node of elem.getAllRGANodes()) {
18564
+ if (!node.getElementEntry() && node.getRemovedAt()) {
18565
+ this.registerGCPair({
18566
+ parent: elem.getRGATreeList(),
18567
+ child: node
18568
+ });
18569
+ }
18570
+ }
18571
+ }
18011
18572
  return false;
18012
18573
  });
18013
18574
  }
@@ -19099,6 +19660,11 @@
19099
19660
  if (logger.isEnabled(LogLevel.Trivial)) {
19100
19661
  logger.trivial(`trying to update a local change: ${this.toJSON()}`);
19101
19662
  }
19663
+ const prev = {
19664
+ hadPresence: this.presences.has(actorID),
19665
+ wasOnline: this.status === "attached",
19666
+ presence: this.presences.has(actorID) ? deepcopy(this.presences.get(actorID)) : void 0
19667
+ };
19102
19668
  const change = ctx.toChange();
19103
19669
  const { opInfos, reverseOps } = change.execute(
19104
19670
  this.root,
@@ -19144,14 +19710,14 @@
19144
19710
  });
19145
19711
  }
19146
19712
  if (change.hasPresenceChange()) {
19147
- event.push({
19148
- type: "presence-changed",
19149
- source: OpSource.Local,
19150
- value: {
19151
- clientID: actorID,
19152
- presence: this.getPresence(actorID)
19153
- }
19154
- });
19713
+ const presenceEvent = this.reconcilePresence(
19714
+ actorID,
19715
+ prev,
19716
+ OpSource.Local
19717
+ );
19718
+ if (presenceEvent) {
19719
+ event.push(presenceEvent);
19720
+ }
19155
19721
  }
19156
19722
  this.publish(event);
19157
19723
  if (logger.isEnabled(LogLevel.Trivial)) {
@@ -19635,41 +20201,11 @@
19635
20201
  change.execute(this.clone.root, this.clone.presences, source);
19636
20202
  const events = [];
19637
20203
  const actorID = change.getID().getActorID();
19638
- if (change.hasPresenceChange() && this.onlineClients.has(actorID)) {
19639
- const presenceChange = change.getPresenceChange();
19640
- switch (presenceChange.type) {
19641
- case PresenceChangeType.Put:
19642
- events.push(
19643
- this.presences.has(actorID) ? {
19644
- type: "presence-changed",
19645
- source,
19646
- value: {
19647
- clientID: actorID,
19648
- presence: presenceChange.presence
19649
- }
19650
- } : {
19651
- type: "watched",
19652
- source: OpSource.Remote,
19653
- value: {
19654
- clientID: actorID,
19655
- presence: presenceChange.presence
19656
- }
19657
- }
19658
- );
19659
- break;
19660
- case PresenceChangeType.Clear:
19661
- events.push({
19662
- type: "unwatched",
19663
- source: OpSource.Remote,
19664
- value: {
19665
- clientID: actorID,
19666
- presence: this.getPresence(actorID)
19667
- }
19668
- });
19669
- this.removeOnlineClient(actorID);
19670
- break;
19671
- }
19672
- }
20204
+ const prev = change.hasPresenceChange() ? {
20205
+ hadPresence: this.presences.has(actorID),
20206
+ wasOnline: this.onlineClients.has(actorID),
20207
+ presence: this.presences.has(actorID) ? deepcopy(this.presences.get(actorID)) : void 0
20208
+ } : void 0;
19673
20209
  const { opInfos, operations } = change.execute(
19674
20210
  this.root,
19675
20211
  this.presences,
@@ -19724,6 +20260,16 @@
19724
20260
  }
19725
20261
  );
19726
20262
  }
20263
+ if (prev && change.hasPresenceChange()) {
20264
+ const presenceChange = change.getPresenceChange();
20265
+ if (presenceChange.type === PresenceChangeType.Clear) {
20266
+ this.removeOnlineClient(actorID);
20267
+ }
20268
+ const presenceEvent = this.reconcilePresence(actorID, prev, source);
20269
+ if (presenceEvent) {
20270
+ events.push(presenceEvent);
20271
+ }
20272
+ }
19727
20273
  if (events.length) {
19728
20274
  this.publish(events);
19729
20275
  }
@@ -19752,46 +20298,43 @@
19752
20298
  * `applyDocEvent` applies the given doc event into this document.
19753
20299
  */
19754
20300
  applyDocEvent(type, publisher) {
19755
- const events = [];
20301
+ const prev = {
20302
+ hadPresence: this.presences.has(publisher),
20303
+ wasOnline: this.onlineClients.has(publisher),
20304
+ presence: this.presences.has(publisher) ? deepcopy(this.presences.get(publisher)) : void 0
20305
+ };
19756
20306
  if (type === DocEventType$1.DOCUMENT_WATCHED) {
19757
20307
  if (this.onlineClients.has(publisher) && this.hasPresence(publisher)) {
19758
20308
  return;
19759
20309
  }
19760
20310
  this.addOnlineClient(publisher);
19761
- if (this.hasPresence(publisher)) {
19762
- events.push({
19763
- type: "watched",
19764
- source: OpSource.Remote,
19765
- value: {
19766
- clientID: publisher,
19767
- presence: this.getPresence(publisher)
19768
- }
19769
- });
19770
- }
19771
20311
  } else if (type === DocEventType$1.DOCUMENT_UNWATCHED) {
19772
- const presence = this.getPresence(publisher);
19773
20312
  this.removeOnlineClient(publisher);
19774
20313
  this.presences.delete(publisher);
19775
- if (presence) {
19776
- events.push({
19777
- type: "unwatched",
19778
- source: OpSource.Remote,
19779
- value: { clientID: publisher, presence }
19780
- });
19781
- }
19782
20314
  }
19783
- if (events.length) {
19784
- this.publish(events);
20315
+ const event = this.reconcilePresence(publisher, prev, OpSource.Remote);
20316
+ if (event) {
20317
+ this.publish([event]);
19785
20318
  }
19786
20319
  }
19787
20320
  /**
19788
20321
  * `applyStatus` applies the document status into this document.
19789
20322
  */
19790
20323
  applyStatus(status) {
20324
+ const actorID = this.changeID.getActorID();
20325
+ const prev = {
20326
+ hadPresence: this.presences.has(actorID),
20327
+ wasOnline: this.status === "attached",
20328
+ presence: this.presences.has(actorID) ? deepcopy(this.presences.get(actorID)) : void 0
20329
+ };
19791
20330
  this.status = status;
19792
20331
  if (status === "detached") {
19793
20332
  this.setActor(InitialActorID);
19794
20333
  }
20334
+ const event = this.reconcilePresence(actorID, prev, OpSource.Local);
20335
+ if (event) {
20336
+ this.publish([event]);
20337
+ }
19795
20338
  this.publish([
19796
20339
  {
19797
20340
  source: status === "removed" ? OpSource.Remote : OpSource.Local,
@@ -19891,6 +20434,57 @@
19891
20434
  removeOnlineClient(clientID) {
19892
20435
  this.onlineClients.delete(clientID);
19893
20436
  }
20437
+ /**
20438
+ * `reconcilePresence` compares the previous and current state of a client's
20439
+ * presence/online status and returns the appropriate event to emit.
20440
+ *
20441
+ * For remote clients, "online" means the client is in onlineClients.
20442
+ * For self, "online" means the document status is Attached.
20443
+ *
20444
+ * State transition table:
20445
+ * (!hadP || !wasOn) → (hasP && isOn) : watched (remote) or presence-changed (self)
20446
+ * (hadP && wasOn) → (hasP && isOn) : presence-changed
20447
+ * (hadP && wasOn) → (!hasP || !isOn): unwatched (remote only)
20448
+ * otherwise : no event (waiting)
20449
+ */
20450
+ reconcilePresence(actorID, prev, source) {
20451
+ const isSelf = actorID === this.changeID.getActorID();
20452
+ const hasPresence = this.presences.has(actorID);
20453
+ const isOnline = isSelf ? this.status === "attached" : this.onlineClients.has(actorID);
20454
+ if (!hasPresence || !isOnline) {
20455
+ if (prev.hadPresence && prev.wasOnline && !isSelf) {
20456
+ return {
20457
+ type: "unwatched",
20458
+ source: OpSource.Remote,
20459
+ value: {
20460
+ clientID: actorID,
20461
+ presence: prev.presence
20462
+ }
20463
+ };
20464
+ }
20465
+ return void 0;
20466
+ }
20467
+ const presence = deepcopy(this.presences.get(actorID));
20468
+ if (!prev.hadPresence || !prev.wasOnline) {
20469
+ if (isSelf) {
20470
+ return {
20471
+ type: "presence-changed",
20472
+ source,
20473
+ value: { clientID: actorID, presence }
20474
+ };
20475
+ }
20476
+ return {
20477
+ type: "watched",
20478
+ source: OpSource.Remote,
20479
+ value: { clientID: actorID, presence }
20480
+ };
20481
+ }
20482
+ return {
20483
+ type: "presence-changed",
20484
+ source,
20485
+ value: { clientID: actorID, presence }
20486
+ };
20487
+ }
19894
20488
  /**
19895
20489
  * `hasPresence` returns whether the given clientID has a presence or not.
19896
20490
  */
@@ -20052,18 +20646,24 @@
20052
20646
  const ticket = ctx.issueTimeTicket();
20053
20647
  op.setExecutedAt(ticket);
20054
20648
  if (op instanceof ArraySetOperation) {
20055
- const prev = op.getCreatedAt();
20649
+ const prev2 = op.getCreatedAt();
20056
20650
  op.getValue().setCreatedAt(ticket);
20057
- this.internalHistory.reconcileCreatedAt(prev, ticket);
20651
+ this.internalHistory.reconcileCreatedAt(prev2, ticket);
20058
20652
  } else if (op instanceof AddOperation) {
20059
- const prev = op.getValue().getCreatedAt();
20653
+ const prev2 = op.getValue().getCreatedAt();
20060
20654
  op.getValue().setCreatedAt(ticket);
20061
- this.internalHistory.reconcileCreatedAt(prev, ticket);
20655
+ this.internalHistory.reconcileCreatedAt(prev2, ticket);
20062
20656
  }
20063
20657
  ctx.push(op);
20064
20658
  }
20065
20659
  const change = ctx.toChange();
20066
20660
  change.execute(this.clone.root, this.clone.presences, OpSource.UndoRedo);
20661
+ const actorID = this.changeID.getActorID();
20662
+ const prev = {
20663
+ hadPresence: this.presences.has(actorID),
20664
+ wasOnline: this.status === "attached",
20665
+ presence: this.presences.has(actorID) ? deepcopy(this.presences.get(actorID)) : void 0
20666
+ };
20067
20667
  const { opInfos, reverseOps } = change.execute(
20068
20668
  this.root,
20069
20669
  this.presences,
@@ -20085,7 +20685,6 @@
20085
20685
  }
20086
20686
  this.localChanges.push(change);
20087
20687
  this.changeID = ctx.getNextID();
20088
- const actorID = this.changeID.getActorID();
20089
20688
  const events = [];
20090
20689
  if (opInfos.length) {
20091
20690
  events.push({
@@ -20102,14 +20701,14 @@
20102
20701
  });
20103
20702
  }
20104
20703
  if (change.hasPresenceChange()) {
20105
- events.push({
20106
- type: "presence-changed",
20107
- source: OpSource.UndoRedo,
20108
- value: {
20109
- clientID: actorID,
20110
- presence: this.getPresence(actorID)
20111
- }
20112
- });
20704
+ const presenceEvent = this.reconcilePresence(
20705
+ actorID,
20706
+ prev,
20707
+ OpSource.UndoRedo
20708
+ );
20709
+ if (presenceEvent) {
20710
+ events.push(presenceEvent);
20711
+ }
20113
20712
  }
20114
20713
  this.publish(events);
20115
20714
  }
@@ -20125,6 +20724,8 @@
20125
20724
  watchStream;
20126
20725
  watchLoopTimerID;
20127
20726
  watchAbortController;
20727
+ syncPromise;
20728
+ _detaching = false;
20128
20729
  constructor(reconnectStreamDelay, resource, resourceID, syncMode) {
20129
20730
  this.reconnectStreamDelay = reconnectStreamDelay;
20130
20731
  this.resource = resource;
@@ -20200,6 +20801,49 @@
20200
20801
  };
20201
20802
  await doLoop();
20202
20803
  }
20804
+ /**
20805
+ * `markDetaching` marks this attachment as being in the process of detaching.
20806
+ * Once marked, the sync loop will skip this attachment.
20807
+ */
20808
+ markDetaching() {
20809
+ this._detaching = true;
20810
+ }
20811
+ /**
20812
+ * `isDetaching` returns whether this attachment is being detached.
20813
+ */
20814
+ isDetaching() {
20815
+ return this._detaching;
20816
+ }
20817
+ /**
20818
+ * `resetDetaching` resets the detaching flag so the attachment can resume
20819
+ * syncing. Used when a detach RPC fails and the document remains attached.
20820
+ */
20821
+ resetDetaching() {
20822
+ this._detaching = false;
20823
+ }
20824
+ /**
20825
+ * `setSyncPromise` sets the in-progress sync promise for this attachment.
20826
+ */
20827
+ setSyncPromise(promise) {
20828
+ this.syncPromise = promise;
20829
+ }
20830
+ /**
20831
+ * `clearSyncPromise` clears the in-progress sync promise.
20832
+ */
20833
+ clearSyncPromise() {
20834
+ this.syncPromise = void 0;
20835
+ }
20836
+ /**
20837
+ * `waitForSyncComplete` waits for any in-progress sync to complete.
20838
+ */
20839
+ async waitForSyncComplete() {
20840
+ if (this.syncPromise) {
20841
+ try {
20842
+ await this.syncPromise;
20843
+ } catch {
20844
+ }
20845
+ }
20846
+ }
20203
20847
  /**
20204
20848
  * `cancelWatchStream` cancels the watch stream.
20205
20849
  */
@@ -20234,7 +20878,7 @@
20234
20878
  };
20235
20879
  }
20236
20880
  const name = "@yorkie-js/sdk";
20237
- const version = "0.7.5";
20881
+ const version = "0.7.7";
20238
20882
  const pkg = {
20239
20883
  name,
20240
20884
  version
@@ -20559,6 +21203,7 @@
20559
21203
  taskQueue;
20560
21204
  processing = false;
20561
21205
  keepalive = false;
21206
+ deactivating = false;
20562
21207
  /**
20563
21208
  * @param rpcAddr - the address of the RPC server.
20564
21209
  * @param opts - the options of the client.
@@ -20628,6 +21273,7 @@
20628
21273
  );
20629
21274
  this.id = res.clientId;
20630
21275
  this.status = "activated";
21276
+ this.deactivating = false;
20631
21277
  this.runSyncLoop();
20632
21278
  logger.info(`[AC] c:"${this.getKey()}" activated, id:"${this.id}"`);
20633
21279
  if (typeof window !== "undefined") {
@@ -20656,6 +21302,7 @@
20656
21302
  if (this.status === "deactivated") {
20657
21303
  return Promise.resolve();
20658
21304
  }
21305
+ this.deactivating = true;
20659
21306
  const task = async () => {
20660
21307
  try {
20661
21308
  await this.rpcClient.deactivateClient(
@@ -20669,6 +21316,7 @@
20669
21316
  logger.info(`[DC] c"${this.getKey()}" deactivated`);
20670
21317
  } catch (err) {
20671
21318
  logger.error(`[DC] c:"${this.getKey()}" err :`, err);
21319
+ this.deactivating = false;
20672
21320
  await this.handleConnectError(err);
20673
21321
  throw err;
20674
21322
  }
@@ -20809,8 +21457,10 @@
20809
21457
  );
20810
21458
  }
20811
21459
  doc.update((_, p) => p.clear());
21460
+ attachment.markDetaching();
20812
21461
  const task = async () => {
20813
21462
  try {
21463
+ await attachment.waitForSyncComplete();
20814
21464
  const res = await this.rpcClient.detachDocument(
20815
21465
  {
20816
21466
  clientId: this.id,
@@ -20829,6 +21479,7 @@
20829
21479
  return doc;
20830
21480
  } catch (err) {
20831
21481
  logger.error(`[DD] c:"${this.getKey()}" err :`, err);
21482
+ attachment.resetDetaching();
20832
21483
  await this.handleConnectError(err);
20833
21484
  throw err;
20834
21485
  }
@@ -21395,7 +22046,7 @@
21395
22046
  */
21396
22047
  runSyncLoop() {
21397
22048
  const doLoop = async () => {
21398
- if (!this.isActive()) {
22049
+ if (!this.isActive() || this.deactivating) {
21399
22050
  logger.debug(`[SL] c:"${this.getKey()}" exit sync loop`);
21400
22051
  this.conditions[
21401
22052
  "SyncLoop"
@@ -21407,43 +22058,62 @@
21407
22058
  await this.enqueueTask(async () => {
21408
22059
  const syncs = [];
21409
22060
  for (const [, attachment] of this.attachmentMap) {
22061
+ if (this.deactivating) {
22062
+ break;
22063
+ }
21410
22064
  if (!attachment.needSync(this.channelHeartbeatInterval)) {
21411
22065
  continue;
21412
22066
  }
22067
+ if (attachment.isDetaching()) {
22068
+ continue;
22069
+ }
21413
22070
  if (attachment.changeEventReceived !== void 0) {
21414
22071
  attachment.changeEventReceived = false;
21415
22072
  }
21416
- syncs.push(
21417
- this.syncInternal(attachment, attachment.syncMode).catch((e) => {
21418
- if (isErrorCode(e, Code.ErrUnauthenticated)) {
21419
- attachment.resource.publish([
21420
- {
21421
- type: DocEventType.AuthError,
21422
- value: {
21423
- reason: errorMetadataOf(e).reason,
21424
- method: "PushPull"
21425
- }
22073
+ const syncPromise = this.syncInternal(
22074
+ attachment,
22075
+ attachment.syncMode
22076
+ ).then(() => {
22077
+ }).catch((e) => {
22078
+ if (isErrorCode(e, Code.ErrUnauthenticated)) {
22079
+ attachment.resource.publish([
22080
+ {
22081
+ type: DocEventType.AuthError,
22082
+ value: {
22083
+ reason: errorMetadataOf(e).reason,
22084
+ method: "PushPull"
21426
22085
  }
21427
- ]);
21428
- }
21429
- if (isErrorCode(e, Code.ErrEpochMismatch)) {
21430
- attachment.resource.publish([
21431
- {
21432
- type: DocEventType.EpochMismatch,
21433
- value: {
21434
- method: "PushPull"
21435
- }
22086
+ }
22087
+ ]);
22088
+ }
22089
+ if (isErrorCode(e, Code.ErrEpochMismatch)) {
22090
+ attachment.resource.publish([
22091
+ {
22092
+ type: DocEventType.EpochMismatch,
22093
+ value: {
22094
+ method: "PushPull"
21436
22095
  }
21437
- ]);
21438
- }
21439
- throw e;
21440
- })
21441
- );
22096
+ }
22097
+ ]);
22098
+ }
22099
+ throw e;
22100
+ }).finally(() => {
22101
+ attachment.clearSyncPromise();
22102
+ });
22103
+ attachment.setSyncPromise(syncPromise);
22104
+ syncs.push(syncPromise);
21442
22105
  }
21443
22106
  await Promise.all(syncs);
21444
22107
  setTimeout(doLoop, this.syncLoopDuration);
21445
22108
  });
21446
22109
  } catch (err) {
22110
+ if (this.deactivating) {
22111
+ this.conditions[
22112
+ "SyncLoop"
22113
+ /* SyncLoop */
22114
+ ] = false;
22115
+ return;
22116
+ }
21447
22117
  logger.error(`[SL] c:"${this.getKey()}" sync failed:`, err);
21448
22118
  if (await this.handleConnectError(err)) {
21449
22119
  setTimeout(doLoop, this.retrySyncLoopDelay);
@@ -21924,8 +22594,11 @@
21924
22594
  function isCounter(value) {
21925
22595
  return typeof value === "object" && value !== null && value.type === "Counter" && typeof value.value === "object";
21926
22596
  }
22597
+ function isDedupCounter(value) {
22598
+ return typeof value === "object" && value !== null && value.type === "DedupCounter" && typeof value.value === "object" && typeof value.registers === "string";
22599
+ }
21927
22600
  function isObject(value) {
21928
- return typeof value === "object" && value !== null && !Array.isArray(value) && !isText(value) && !isTree(value) && !isInt(value) && !isLong(value) && !isDate(value) && !isBinData(value) && !isCounter(value);
22601
+ 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);
21929
22602
  }
21930
22603
  function parse(yson) {
21931
22604
  try {
@@ -21941,6 +22614,12 @@
21941
22614
  }
21942
22615
  function preprocessYSON(yson) {
21943
22616
  let result = yson;
22617
+ result = result.replace(
22618
+ /DedupCounter\(Int\((-?\d+)\),"([^"]+)"\)/g,
22619
+ (_, value, registers) => {
22620
+ return `{"__yson_type":"DedupCounter","__yson_data":{"__yson_type":"Int","__yson_data":${value}},"__yson_registers":"${registers}"}`;
22621
+ }
22622
+ );
21944
22623
  result = result.replace(
21945
22624
  /Counter\((Int|Long)\((-?\d+)\)\)/g,
21946
22625
  (_, type, value) => {
@@ -22001,6 +22680,20 @@
22001
22680
  value: value.__yson_data
22002
22681
  };
22003
22682
  }
22683
+ if (value.__yson_type === "DedupCounter" && typeof value.__yson_data === "object" && typeof value.__yson_registers === "string") {
22684
+ const counterValue = postprocessValue(value.__yson_data);
22685
+ if (typeof counterValue === "object" && counterValue !== null && "type" in counterValue && counterValue.type === "Int") {
22686
+ return {
22687
+ type: "DedupCounter",
22688
+ value: counterValue,
22689
+ registers: value.__yson_registers
22690
+ };
22691
+ }
22692
+ throw new YorkieError(
22693
+ Code.ErrInvalidArgument,
22694
+ "DedupCounter must contain Int"
22695
+ );
22696
+ }
22004
22697
  if (value.__yson_type === "Counter" && typeof value.__yson_data === "object") {
22005
22698
  const counterValue = postprocessValue(value.__yson_data);
22006
22699
  if (typeof counterValue === "object" && counterValue !== null && "type" in counterValue && (counterValue.type === "Int" || counterValue.type === "Long")) {
@@ -22089,6 +22782,7 @@
22089
22782
  isBinData,
22090
22783
  isCounter,
22091
22784
  isDate,
22785
+ isDedupCounter,
22092
22786
  isInt,
22093
22787
  isLong,
22094
22788
  isObject,