@fluidframework/merge-tree 2.30.0 → 2.31.0

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.
Files changed (308) hide show
  1. package/CHANGELOG.md +403 -399
  2. package/api-report/merge-tree.legacy.alpha.api.md +1 -0
  3. package/dist/MergeTreeTextHelper.d.ts +9 -3
  4. package/dist/MergeTreeTextHelper.d.ts.map +1 -1
  5. package/dist/MergeTreeTextHelper.js +5 -5
  6. package/dist/MergeTreeTextHelper.js.map +1 -1
  7. package/dist/client.d.ts +7 -13
  8. package/dist/client.d.ts.map +1 -1
  9. package/dist/client.js +136 -110
  10. package/dist/client.js.map +1 -1
  11. package/dist/endOfTreeSegment.d.ts +12 -8
  12. package/dist/endOfTreeSegment.d.ts.map +1 -1
  13. package/dist/endOfTreeSegment.js +2 -4
  14. package/dist/endOfTreeSegment.js.map +1 -1
  15. package/dist/index.d.ts +6 -3
  16. package/dist/index.d.ts.map +1 -1
  17. package/dist/index.js +2 -3
  18. package/dist/index.js.map +1 -1
  19. package/dist/mergeTree.d.ts +37 -23
  20. package/dist/mergeTree.d.ts.map +1 -1
  21. package/dist/mergeTree.js +400 -483
  22. package/dist/mergeTree.js.map +1 -1
  23. package/dist/mergeTreeDeltaCallback.d.ts +4 -8
  24. package/dist/mergeTreeDeltaCallback.d.ts.map +1 -1
  25. package/dist/mergeTreeDeltaCallback.js.map +1 -1
  26. package/dist/mergeTreeNodes.d.ts +32 -10
  27. package/dist/mergeTreeNodes.d.ts.map +1 -1
  28. package/dist/mergeTreeNodes.js +43 -28
  29. package/dist/mergeTreeNodes.js.map +1 -1
  30. package/dist/partialLengths.d.ts +2 -2
  31. package/dist/partialLengths.d.ts.map +1 -1
  32. package/dist/partialLengths.js +181 -109
  33. package/dist/partialLengths.js.map +1 -1
  34. package/dist/perspective.d.ts +8 -27
  35. package/dist/perspective.d.ts.map +1 -1
  36. package/dist/perspective.js +7 -67
  37. package/dist/perspective.js.map +1 -1
  38. package/dist/revertibles.d.ts.map +1 -1
  39. package/dist/revertibles.js +2 -2
  40. package/dist/revertibles.js.map +1 -1
  41. package/dist/segmentInfos.d.ts +20 -106
  42. package/dist/segmentInfos.d.ts.map +1 -1
  43. package/dist/segmentInfos.js +28 -42
  44. package/dist/segmentInfos.js.map +1 -1
  45. package/dist/segmentPropertiesManager.d.ts +1 -14
  46. package/dist/segmentPropertiesManager.d.ts.map +1 -1
  47. package/dist/segmentPropertiesManager.js +3 -17
  48. package/dist/segmentPropertiesManager.js.map +1 -1
  49. package/dist/snapshotLoader.d.ts.map +1 -1
  50. package/dist/snapshotLoader.js +62 -19
  51. package/dist/snapshotLoader.js.map +1 -1
  52. package/dist/snapshotV1.d.ts.map +1 -1
  53. package/dist/snapshotV1.js +55 -24
  54. package/dist/snapshotV1.js.map +1 -1
  55. package/dist/snapshotlegacy.d.ts.map +1 -1
  56. package/dist/snapshotlegacy.js +6 -9
  57. package/dist/snapshotlegacy.js.map +1 -1
  58. package/dist/stamps.d.ts +1 -1
  59. package/dist/stamps.js +1 -1
  60. package/dist/stamps.js.map +1 -1
  61. package/dist/test/Insertion.perf.spec.js +6 -51
  62. package/dist/test/Insertion.perf.spec.js.map +1 -1
  63. package/dist/test/PartialLengths.perf.spec.js +18 -25
  64. package/dist/test/PartialLengths.perf.spec.js.map +1 -1
  65. package/dist/test/Removal.perf.spec.js +13 -41
  66. package/dist/test/Removal.perf.spec.js.map +1 -1
  67. package/dist/test/beastTest.spec.d.ts.map +1 -1
  68. package/dist/test/beastTest.spec.js +41 -66
  69. package/dist/test/beastTest.spec.js.map +1 -1
  70. package/dist/test/client.annotateMarker.spec.js +1 -11
  71. package/dist/test/client.annotateMarker.spec.js.map +1 -1
  72. package/dist/test/client.applyMsg.spec.js +14 -14
  73. package/dist/test/client.applyMsg.spec.js.map +1 -1
  74. package/dist/test/client.getPosition.spec.js +1 -1
  75. package/dist/test/client.getPosition.spec.js.map +1 -1
  76. package/dist/test/client.localReference.spec.js +1 -1
  77. package/dist/test/client.localReference.spec.js.map +1 -1
  78. package/dist/test/client.rollback.spec.js +49 -58
  79. package/dist/test/client.rollback.spec.js.map +1 -1
  80. package/dist/test/client.rollbackFarm.spec.js +1 -1
  81. package/dist/test/client.rollbackFarm.spec.js.map +1 -1
  82. package/dist/test/client.searchForMarker.spec.js +4 -21
  83. package/dist/test/client.searchForMarker.spec.js.map +1 -1
  84. package/dist/test/index.d.ts +2 -2
  85. package/dist/test/index.d.ts.map +1 -1
  86. package/dist/test/index.js +2 -6
  87. package/dist/test/index.js.map +1 -1
  88. package/dist/test/mergeTree.annotate.deltaCallback.spec.js +14 -59
  89. package/dist/test/mergeTree.annotate.deltaCallback.spec.js.map +1 -1
  90. package/dist/test/mergeTree.annotate.spec.js +47 -63
  91. package/dist/test/mergeTree.annotate.spec.js.map +1 -1
  92. package/dist/test/mergeTree.insert.deltaCallback.spec.js +9 -62
  93. package/dist/test/mergeTree.insert.deltaCallback.spec.js.map +1 -1
  94. package/dist/test/mergeTree.insertingWalk.spec.js +59 -125
  95. package/dist/test/mergeTree.insertingWalk.spec.js.map +1 -1
  96. package/dist/test/mergeTree.markRangeRemoved.deltaCallback.spec.js +12 -93
  97. package/dist/test/mergeTree.markRangeRemoved.deltaCallback.spec.js.map +1 -1
  98. package/dist/test/mergeTree.markRangeRemoved.spec.js +10 -7
  99. package/dist/test/mergeTree.markRangeRemoved.spec.js.map +1 -1
  100. package/dist/test/mergeTree.walk.spec.js +2 -14
  101. package/dist/test/mergeTree.walk.spec.js.map +1 -1
  102. package/dist/test/mergeTreeOperationRunner.js +2 -2
  103. package/dist/test/mergeTreeOperationRunner.js.map +1 -1
  104. package/dist/test/obliterate.concurrent.spec.js +18 -23
  105. package/dist/test/obliterate.concurrent.spec.js.map +1 -1
  106. package/dist/test/obliterate.partialLength.spec.js +166 -136
  107. package/dist/test/obliterate.partialLength.spec.js.map +1 -1
  108. package/dist/test/obliterate.spec.js +16 -126
  109. package/dist/test/obliterate.spec.js.map +1 -1
  110. package/dist/test/partialLength.spec.js +28 -196
  111. package/dist/test/partialLength.spec.js.map +1 -1
  112. package/dist/test/perspective.spec.js +34 -0
  113. package/dist/test/perspective.spec.js.map +1 -1
  114. package/dist/test/propertyManager.spec.js +1 -1
  115. package/dist/test/propertyManager.spec.js.map +1 -1
  116. package/dist/test/resetPendingSegmentsToOp.spec.js +0 -2
  117. package/dist/test/resetPendingSegmentsToOp.spec.js.map +1 -1
  118. package/dist/test/segmentGroupCollection.spec.js +10 -4
  119. package/dist/test/segmentGroupCollection.spec.js.map +1 -1
  120. package/dist/test/testClient.d.ts +1 -0
  121. package/dist/test/testClient.d.ts.map +1 -1
  122. package/dist/test/testClient.js +16 -26
  123. package/dist/test/testClient.js.map +1 -1
  124. package/dist/test/testClientLogger.d.ts.map +1 -1
  125. package/dist/test/testClientLogger.js +3 -10
  126. package/dist/test/testClientLogger.js.map +1 -1
  127. package/dist/test/testServer.d.ts +2 -1
  128. package/dist/test/testServer.d.ts.map +1 -1
  129. package/dist/test/testServer.js +7 -5
  130. package/dist/test/testServer.js.map +1 -1
  131. package/dist/test/testUtils.d.ts +36 -56
  132. package/dist/test/testUtils.d.ts.map +1 -1
  133. package/dist/test/testUtils.js +68 -77
  134. package/dist/test/testUtils.js.map +1 -1
  135. package/dist/test/text.d.ts +2 -2
  136. package/dist/test/text.d.ts.map +1 -1
  137. package/dist/test/text.js +5 -2
  138. package/dist/test/text.js.map +1 -1
  139. package/dist/textSegment.d.ts +0 -6
  140. package/dist/textSegment.d.ts.map +1 -1
  141. package/dist/textSegment.js.map +1 -1
  142. package/dist/zamboni.d.ts.map +1 -1
  143. package/dist/zamboni.js +53 -26
  144. package/dist/zamboni.js.map +1 -1
  145. package/lib/MergeTreeTextHelper.d.ts +9 -3
  146. package/lib/MergeTreeTextHelper.d.ts.map +1 -1
  147. package/lib/MergeTreeTextHelper.js +5 -5
  148. package/lib/MergeTreeTextHelper.js.map +1 -1
  149. package/lib/client.d.ts +7 -13
  150. package/lib/client.d.ts.map +1 -1
  151. package/lib/client.js +117 -116
  152. package/lib/client.js.map +1 -1
  153. package/lib/endOfTreeSegment.d.ts +12 -8
  154. package/lib/endOfTreeSegment.d.ts.map +1 -1
  155. package/lib/endOfTreeSegment.js +2 -4
  156. package/lib/endOfTreeSegment.js.map +1 -1
  157. package/lib/index.d.ts +6 -3
  158. package/lib/index.d.ts.map +1 -1
  159. package/lib/index.js +1 -1
  160. package/lib/index.js.map +1 -1
  161. package/lib/mergeTree.d.ts +37 -23
  162. package/lib/mergeTree.d.ts.map +1 -1
  163. package/lib/mergeTree.js +381 -488
  164. package/lib/mergeTree.js.map +1 -1
  165. package/lib/mergeTreeDeltaCallback.d.ts +4 -8
  166. package/lib/mergeTreeDeltaCallback.d.ts.map +1 -1
  167. package/lib/mergeTreeDeltaCallback.js.map +1 -1
  168. package/lib/mergeTreeNodes.d.ts +32 -10
  169. package/lib/mergeTreeNodes.d.ts.map +1 -1
  170. package/lib/mergeTreeNodes.js +42 -29
  171. package/lib/mergeTreeNodes.js.map +1 -1
  172. package/lib/partialLengths.d.ts +2 -2
  173. package/lib/partialLengths.d.ts.map +1 -1
  174. package/lib/partialLengths.js +160 -111
  175. package/lib/partialLengths.js.map +1 -1
  176. package/lib/perspective.d.ts +8 -27
  177. package/lib/perspective.d.ts.map +1 -1
  178. package/lib/perspective.js +8 -68
  179. package/lib/perspective.js.map +1 -1
  180. package/lib/revertibles.d.ts.map +1 -1
  181. package/lib/revertibles.js +2 -2
  182. package/lib/revertibles.js.map +1 -1
  183. package/lib/segmentInfos.d.ts +20 -106
  184. package/lib/segmentInfos.d.ts.map +1 -1
  185. package/lib/segmentInfos.js +26 -37
  186. package/lib/segmentInfos.js.map +1 -1
  187. package/lib/segmentPropertiesManager.d.ts +1 -14
  188. package/lib/segmentPropertiesManager.d.ts.map +1 -1
  189. package/lib/segmentPropertiesManager.js +2 -16
  190. package/lib/segmentPropertiesManager.js.map +1 -1
  191. package/lib/snapshotLoader.d.ts.map +1 -1
  192. package/lib/snapshotLoader.js +39 -19
  193. package/lib/snapshotLoader.js.map +1 -1
  194. package/lib/snapshotV1.d.ts.map +1 -1
  195. package/lib/snapshotV1.js +34 -26
  196. package/lib/snapshotV1.js.map +1 -1
  197. package/lib/snapshotlegacy.d.ts.map +1 -1
  198. package/lib/snapshotlegacy.js +7 -10
  199. package/lib/snapshotlegacy.js.map +1 -1
  200. package/lib/stamps.d.ts +1 -1
  201. package/lib/stamps.js +1 -1
  202. package/lib/stamps.js.map +1 -1
  203. package/lib/test/Insertion.perf.spec.js +6 -51
  204. package/lib/test/Insertion.perf.spec.js.map +1 -1
  205. package/lib/test/PartialLengths.perf.spec.js +18 -25
  206. package/lib/test/PartialLengths.perf.spec.js.map +1 -1
  207. package/lib/test/Removal.perf.spec.js +13 -41
  208. package/lib/test/Removal.perf.spec.js.map +1 -1
  209. package/lib/test/beastTest.spec.d.ts.map +1 -1
  210. package/lib/test/beastTest.spec.js +42 -67
  211. package/lib/test/beastTest.spec.js.map +1 -1
  212. package/lib/test/client.annotateMarker.spec.js +1 -11
  213. package/lib/test/client.annotateMarker.spec.js.map +1 -1
  214. package/lib/test/client.applyMsg.spec.js +14 -14
  215. package/lib/test/client.applyMsg.spec.js.map +1 -1
  216. package/lib/test/client.getPosition.spec.js +1 -1
  217. package/lib/test/client.getPosition.spec.js.map +1 -1
  218. package/lib/test/client.localReference.spec.js +1 -1
  219. package/lib/test/client.localReference.spec.js.map +1 -1
  220. package/lib/test/client.rollback.spec.js +50 -59
  221. package/lib/test/client.rollback.spec.js.map +1 -1
  222. package/lib/test/client.rollbackFarm.spec.js +1 -1
  223. package/lib/test/client.rollbackFarm.spec.js.map +1 -1
  224. package/lib/test/client.searchForMarker.spec.js +4 -21
  225. package/lib/test/client.searchForMarker.spec.js.map +1 -1
  226. package/lib/test/index.d.ts +2 -2
  227. package/lib/test/index.d.ts.map +1 -1
  228. package/lib/test/index.js +1 -1
  229. package/lib/test/index.js.map +1 -1
  230. package/lib/test/mergeTree.annotate.deltaCallback.spec.js +15 -60
  231. package/lib/test/mergeTree.annotate.deltaCallback.spec.js.map +1 -1
  232. package/lib/test/mergeTree.annotate.spec.js +48 -64
  233. package/lib/test/mergeTree.annotate.spec.js.map +1 -1
  234. package/lib/test/mergeTree.insert.deltaCallback.spec.js +10 -63
  235. package/lib/test/mergeTree.insert.deltaCallback.spec.js.map +1 -1
  236. package/lib/test/mergeTree.insertingWalk.spec.js +61 -127
  237. package/lib/test/mergeTree.insertingWalk.spec.js.map +1 -1
  238. package/lib/test/mergeTree.markRangeRemoved.deltaCallback.spec.js +13 -94
  239. package/lib/test/mergeTree.markRangeRemoved.deltaCallback.spec.js.map +1 -1
  240. package/lib/test/mergeTree.markRangeRemoved.spec.js +10 -7
  241. package/lib/test/mergeTree.markRangeRemoved.spec.js.map +1 -1
  242. package/lib/test/mergeTree.walk.spec.js +2 -14
  243. package/lib/test/mergeTree.walk.spec.js.map +1 -1
  244. package/lib/test/mergeTreeOperationRunner.js +3 -3
  245. package/lib/test/mergeTreeOperationRunner.js.map +1 -1
  246. package/lib/test/obliterate.concurrent.spec.js +18 -23
  247. package/lib/test/obliterate.concurrent.spec.js.map +1 -1
  248. package/lib/test/obliterate.partialLength.spec.js +167 -137
  249. package/lib/test/obliterate.partialLength.spec.js.map +1 -1
  250. package/lib/test/obliterate.spec.js +17 -127
  251. package/lib/test/obliterate.spec.js.map +1 -1
  252. package/lib/test/partialLength.spec.js +29 -197
  253. package/lib/test/partialLength.spec.js.map +1 -1
  254. package/lib/test/perspective.spec.js +34 -0
  255. package/lib/test/perspective.spec.js.map +1 -1
  256. package/lib/test/propertyManager.spec.js +2 -2
  257. package/lib/test/propertyManager.spec.js.map +1 -1
  258. package/lib/test/resetPendingSegmentsToOp.spec.js +0 -2
  259. package/lib/test/resetPendingSegmentsToOp.spec.js.map +1 -1
  260. package/lib/test/segmentGroupCollection.spec.js +10 -4
  261. package/lib/test/segmentGroupCollection.spec.js.map +1 -1
  262. package/lib/test/testClient.d.ts +1 -0
  263. package/lib/test/testClient.d.ts.map +1 -1
  264. package/lib/test/testClient.js +18 -28
  265. package/lib/test/testClient.js.map +1 -1
  266. package/lib/test/testClientLogger.d.ts.map +1 -1
  267. package/lib/test/testClientLogger.js +3 -10
  268. package/lib/test/testClientLogger.js.map +1 -1
  269. package/lib/test/testServer.d.ts +2 -1
  270. package/lib/test/testServer.d.ts.map +1 -1
  271. package/lib/test/testServer.js +7 -5
  272. package/lib/test/testServer.js.map +1 -1
  273. package/lib/test/testUtils.d.ts +36 -56
  274. package/lib/test/testUtils.d.ts.map +1 -1
  275. package/lib/test/testUtils.js +66 -48
  276. package/lib/test/testUtils.js.map +1 -1
  277. package/lib/test/text.d.ts +2 -2
  278. package/lib/test/text.d.ts.map +1 -1
  279. package/lib/test/text.js +6 -3
  280. package/lib/test/text.js.map +1 -1
  281. package/lib/textSegment.d.ts +0 -6
  282. package/lib/textSegment.d.ts.map +1 -1
  283. package/lib/textSegment.js.map +1 -1
  284. package/lib/tsdoc-metadata.json +1 -1
  285. package/lib/zamboni.d.ts.map +1 -1
  286. package/lib/zamboni.js +32 -28
  287. package/lib/zamboni.js.map +1 -1
  288. package/package.json +17 -20
  289. package/src/MergeTreeTextHelper.ts +17 -12
  290. package/src/client.ts +141 -197
  291. package/src/endOfTreeSegment.ts +11 -8
  292. package/src/index.ts +4 -3
  293. package/src/mergeTree.ts +482 -633
  294. package/src/mergeTreeDeltaCallback.ts +4 -8
  295. package/src/mergeTreeNodes.ts +66 -45
  296. package/src/partialLengths.ts +181 -137
  297. package/src/perspective.ts +17 -95
  298. package/src/revertibles.ts +2 -7
  299. package/src/segmentInfos.ts +48 -141
  300. package/src/segmentPropertiesManager.ts +2 -16
  301. package/src/snapshotLoader.ts +62 -30
  302. package/src/snapshotV1.ts +36 -28
  303. package/src/snapshotlegacy.ts +7 -16
  304. package/src/stamps.ts +1 -1
  305. package/src/textSegment.ts +0 -13
  306. package/src/zamboni.ts +38 -32
  307. package/tsconfig.json +1 -0
  308. package/prettier.config.cjs +0 -8
@@ -5,34 +5,46 @@
5
5
  */
6
6
  Object.defineProperty(exports, "__esModule", { value: true });
7
7
  const node_assert_1 = require("node:assert");
8
+ const constants_js_1 = require("../constants.js");
8
9
  const ops_js_1 = require("../ops.js");
10
+ const textSegment_js_1 = require("../textSegment.js");
9
11
  const testClient_js_1 = require("./testClient.js");
10
12
  const testUtils_js_1 = require("./testUtils.js");
11
13
  describe("obliterate partial lengths", () => {
12
14
  let client;
13
15
  let refSeq;
14
- const localClientId = 17;
15
- const remoteClientId = 18;
16
+ let initialLocalSeq;
17
+ let localClientId = Number.NaN;
18
+ let remoteClientId = Number.NaN;
19
+ let remoteClientId2 = Number.NaN;
16
20
  (0, testUtils_js_1.useStrictPartialLengthChecks)();
17
21
  beforeEach(() => {
18
22
  client = new testClient_js_1.TestClient({
19
23
  mergeTreeEnableObliterate: true,
20
24
  });
21
25
  client.startOrUpdateCollaboration("local");
26
+ localClientId = client.getClientId();
27
+ remoteClientId = client.getOrAddShortClientId("remote 1");
28
+ remoteClientId2 = client.getOrAddShortClientId("remote 2");
22
29
  for (const char of "hello world") {
23
30
  client.applyMsg(client.makeOpMessage(client.insertTextLocal(client.getLength(), char), client.getCurrentSeq() + 1));
24
31
  }
25
32
  node_assert_1.strict.equal(client.getText(), "hello world");
26
33
  refSeq = client.getCurrentSeq();
34
+ initialLocalSeq = client.getCollabWindow().localSeq;
27
35
  });
28
36
  it("removes text", () => {
29
37
  node_assert_1.strict.equal(client.getText(), "hello world");
30
38
  const localObliterateOp = client.obliterateRangeLocal(0, "hello world".length);
31
39
  node_assert_1.strict.equal(client.getText(), "");
32
- (0, testUtils_js_1.validatePartialLengths)(localClientId, client.mergeTree, [
33
- { seq: refSeq, len: "hello world".length, localSeq: refSeq },
34
- { seq: refSeq + 1, len: "".length, localSeq: refSeq + 1 },
40
+ const minRefSeqForLocalSeq = new Map([
41
+ [initialLocalSeq, refSeq],
42
+ [initialLocalSeq + 1, refSeq + 1],
35
43
  ]);
44
+ (0, testUtils_js_1.validatePartialLengths)(localClientId, client.mergeTree, [
45
+ { seq: refSeq, len: "hello world".length, localSeq: initialLocalSeq },
46
+ { seq: refSeq + 1, len: "".length, localSeq: initialLocalSeq + 1 },
47
+ ], minRefSeqForLocalSeq);
36
48
  client.applyMsg(client.makeOpMessage(localObliterateOp, refSeq + 1));
37
49
  (0, testUtils_js_1.validatePartialLengths)(remoteClientId, client.mergeTree, [
38
50
  { seq: refSeq, len: "hello world".length },
@@ -42,11 +54,16 @@ describe("obliterate partial lengths", () => {
42
54
  it("correctly applies local remove after local obliterate", () => {
43
55
  const localObliterateOp = client.obliterateRangeLocal(0, "hello ".length);
44
56
  const localRemoveOp = client.removeRangeLocal(0, "world".length);
45
- (0, testUtils_js_1.validatePartialLengths)(localClientId, client.mergeTree, [
46
- { seq: refSeq, len: "hello world".length },
47
- { seq: refSeq + 1, len: "world".length, localSeq: refSeq + 1 },
48
- { seq: refSeq + 2, len: "".length, localSeq: refSeq + 2 },
57
+ const minRefSeqForLocalSeq = new Map([
58
+ [initialLocalSeq, refSeq],
59
+ [initialLocalSeq + 1, refSeq],
60
+ [initialLocalSeq + 2, refSeq],
49
61
  ]);
62
+ (0, testUtils_js_1.validatePartialLengths)(localClientId, client.mergeTree, [
63
+ { seq: refSeq, len: "hello world".length, localSeq: initialLocalSeq },
64
+ { seq: refSeq, len: "world".length, localSeq: initialLocalSeq + 1 },
65
+ { seq: refSeq, len: "".length, localSeq: initialLocalSeq + 2 },
66
+ ], minRefSeqForLocalSeq);
50
67
  client.applyMsg(client.makeOpMessage(localObliterateOp, refSeq + 1));
51
68
  client.applyMsg(client.makeOpMessage(localRemoveOp, refSeq + 2));
52
69
  (0, testUtils_js_1.validatePartialLengths)(remoteClientId, client.mergeTree, [
@@ -61,16 +78,7 @@ describe("obliterate partial lengths", () => {
61
78
  });
62
79
  client.startOrUpdateCollaboration("local");
63
80
  for (let i = 0; i < 100; i++) {
64
- (0, testUtils_js_1.insertText)({
65
- mergeTree: client.mergeTree,
66
- pos: 0,
67
- refSeq: i,
68
- clientId: localClientId,
69
- seq: i + 1,
70
- text: "a",
71
- props: undefined,
72
- opArgs: { op: { type: ops_js_1.MergeTreeDeltaType.INSERT } },
73
- });
81
+ client.mergeTree.insertSegments(0, [textSegment_js_1.TextSegment.make("a")], client.mergeTree.localPerspective, { seq: i + 1, clientId: localClientId }, { op: { type: ops_js_1.MergeTreeDeltaType.INSERT } });
74
82
  (0, testUtils_js_1.validatePartialLengths)(localClientId, client.mergeTree, [{ seq: i + 1, len: i + 1 }]);
75
83
  (0, testUtils_js_1.validatePartialLengths)(remoteClientId, client.mergeTree, [{ seq: i + 1, len: i + 1 }]);
76
84
  refSeq += 1;
@@ -83,191 +91,213 @@ describe("obliterate partial lengths", () => {
83
91
  describe("overlapping remove+obliterate", () => {
84
92
  it("passes for local remove and remote obliterate", () => {
85
93
  const localRemoveOp = client.removeRangeLocal(0, "hello ".length);
86
- (0, testUtils_js_1.obliterateRange)({
87
- mergeTree: client.mergeTree,
88
- start: 0,
89
- end: "hello ".length,
90
- refSeq,
91
- clientId: remoteClientId,
92
- seq: refSeq + 1,
93
- opArgs: undefined,
94
- });
94
+ client.removeRangeRemote(0, "hello ".length, refSeq + 1, refSeq, client.getLongClientId(remoteClientId));
95
+ const minRefSeqForLocalSeq = new Map([
96
+ [initialLocalSeq, refSeq],
97
+ [initialLocalSeq + 1, refSeq],
98
+ ]);
95
99
  (0, testUtils_js_1.validatePartialLengths)(localClientId, client.mergeTree, [
96
- { seq: refSeq, len: "hello world".length, localSeq: refSeq },
97
- { seq: refSeq + 1, len: "world".length, localSeq: refSeq + 1 },
100
+ { seq: refSeq, len: "hello world".length, localSeq: initialLocalSeq },
101
+ { seq: refSeq, len: "world".length, localSeq: initialLocalSeq + 1 },
102
+ { seq: refSeq + 1, len: "world".length, localSeq: initialLocalSeq },
103
+ { seq: refSeq + 1, len: "world".length, localSeq: initialLocalSeq + 1 },
104
+ ], minRefSeqForLocalSeq);
105
+ client.applyMsg(client.makeOpMessage(localRemoveOp, refSeq + 2));
106
+ (0, testUtils_js_1.validatePartialLengths)(constants_js_1.NonCollabClient, client.mergeTree, [
107
+ { seq: refSeq, len: "hello world".length },
108
+ { seq: refSeq + 1, len: "world".length },
109
+ { seq: refSeq + 2, len: "world".length },
98
110
  ]);
99
- client.applyMsg(client.makeOpMessage(localRemoveOp, refSeq + 1));
100
111
  (0, testUtils_js_1.validatePartialLengths)(remoteClientId, client.mergeTree, [
101
- { seq: refSeq, len: "hello world".length },
102
- { seq: refSeq + 1, len: "world".length, localSeq: refSeq + 1 },
103
- ], refSeq);
112
+ { seq: refSeq, len: "world".length },
113
+ { seq: refSeq + 1, len: "world".length },
114
+ { seq: refSeq + 2, len: "world".length },
115
+ ]);
104
116
  });
105
117
  it("passes for remote remove and local obliterate", () => {
106
- client.removeRangeRemote(0, "hello ".length, refSeq + 1, refSeq, client.getLongClientId(remoteClientId));
107
118
  const localObliterateOp = client.obliterateRangeLocal(0, "hello ".length);
108
- (0, testUtils_js_1.validatePartialLengths)(localClientId, client.mergeTree, [
109
- { seq: refSeq, len: "hello world".length, localSeq: refSeq },
110
- { seq: refSeq + 1, len: "world".length, localSeq: refSeq + 1 },
111
- { seq: refSeq + 2, len: "world".length, localSeq: refSeq + 2 },
119
+ client.removeRangeRemote(0, "hello ".length, refSeq + 1, refSeq, client.getLongClientId(remoteClientId));
120
+ const minRefSeqForLocalSeq = new Map([
121
+ [initialLocalSeq, refSeq],
122
+ [initialLocalSeq + 1, refSeq],
112
123
  ]);
124
+ (0, testUtils_js_1.validatePartialLengths)(localClientId, client.mergeTree, [
125
+ { seq: refSeq, len: "hello world".length, localSeq: initialLocalSeq },
126
+ { seq: refSeq, len: "world".length, localSeq: initialLocalSeq + 1 },
127
+ { seq: refSeq + 1, len: "world".length, localSeq: initialLocalSeq },
128
+ { seq: refSeq + 1, len: "world".length, localSeq: initialLocalSeq + 1 },
129
+ ], minRefSeqForLocalSeq);
113
130
  client.applyMsg(client.makeOpMessage(localObliterateOp, refSeq + 2));
114
- (0, testUtils_js_1.validatePartialLengths)(remoteClientId, client.mergeTree, [
131
+ (0, testUtils_js_1.validatePartialLengths)(constants_js_1.NonCollabClient, client.mergeTree, [
115
132
  { seq: refSeq, len: "hello world".length },
116
- { seq: refSeq + 1, len: "hello world".length },
133
+ { seq: refSeq + 1, len: "world".length },
134
+ { seq: refSeq + 2, len: "world".length },
135
+ ]);
136
+ (0, testUtils_js_1.validatePartialLengths)(remoteClientId, client.mergeTree, [
137
+ { seq: refSeq, len: "world".length },
138
+ { seq: refSeq + 1, len: "world".length },
117
139
  { seq: refSeq + 2, len: "world".length },
118
140
  ]);
119
141
  });
120
142
  it("passes for remote remove and remote obliterate", () => {
121
143
  client.removeRangeRemote(0, "hello ".length, refSeq + 1, refSeq, client.getLongClientId(remoteClientId));
122
- (0, testUtils_js_1.obliterateRange)({
123
- mergeTree: client.mergeTree,
124
- start: 0,
125
- end: "hello ".length,
126
- refSeq,
127
- clientId: remoteClientId + 1,
128
- seq: refSeq + 2,
129
- opArgs: undefined,
130
- });
131
- (0, testUtils_js_1.validatePartialLengths)(localClientId, client.mergeTree, [
144
+ client.removeRangeRemote(0, "hello ".length, refSeq + 2, refSeq, client.getLongClientId(remoteClientId2));
145
+ (0, testUtils_js_1.validatePartialLengths)(constants_js_1.NonCollabClient, client.mergeTree, [
132
146
  { seq: refSeq, len: "hello world".length },
133
- { seq: refSeq + 1, len: "hello world".length },
147
+ { seq: refSeq + 1, len: "world".length },
134
148
  { seq: refSeq + 2, len: "world".length },
135
149
  ]);
136
150
  (0, testUtils_js_1.validatePartialLengths)(remoteClientId, client.mergeTree, [
137
- { seq: refSeq, len: "hello world".length },
138
- { seq: refSeq + 1, len: "hello world".length },
151
+ { seq: refSeq, len: "world".length },
152
+ { seq: refSeq + 1, len: "world".length },
139
153
  { seq: refSeq + 2, len: "world".length },
140
- ], 0);
141
- (0, testUtils_js_1.validatePartialLengths)(remoteClientId + 1, client.mergeTree, [
142
- { seq: refSeq, len: "hello world".length },
143
- { seq: refSeq + 1, len: "hello world".length },
154
+ ]);
155
+ (0, testUtils_js_1.validatePartialLengths)(remoteClientId2, client.mergeTree, [
156
+ { seq: refSeq, len: "world".length },
157
+ { seq: refSeq + 1, len: "world".length },
144
158
  { seq: refSeq + 2, len: "world".length },
145
- ], 0);
159
+ ]);
146
160
  });
147
161
  });
148
162
  describe("overlapping obliterate+obliterate", () => {
149
163
  it("passes for local obliterate and remote obliterate", () => {
150
164
  const localObliterateOp = client.obliterateRangeLocal(0, "hello ".length);
151
- (0, testUtils_js_1.obliterateRange)({
152
- mergeTree: client.mergeTree,
153
- start: 0,
154
- end: "hello ".length,
155
- refSeq,
156
- clientId: remoteClientId,
157
- seq: refSeq + 1,
158
- opArgs: undefined,
159
- });
165
+ client.obliterateRangeRemote(0, "hello ".length, refSeq + 1, refSeq, client.getLongClientId(remoteClientId));
166
+ const minRefSeqForLocalSeq = new Map([
167
+ [initialLocalSeq, refSeq],
168
+ [initialLocalSeq + 1, refSeq],
169
+ ]);
160
170
  (0, testUtils_js_1.validatePartialLengths)(localClientId, client.mergeTree, [
171
+ { seq: refSeq, len: "hello world".length, localSeq: initialLocalSeq },
172
+ { seq: refSeq, len: "world".length, localSeq: initialLocalSeq + 1 },
173
+ { seq: refSeq + 1, len: "world".length, localSeq: initialLocalSeq },
174
+ { seq: refSeq + 1, len: "world".length, localSeq: initialLocalSeq + 1 },
175
+ ], minRefSeqForLocalSeq);
176
+ client.applyMsg(client.makeOpMessage(localObliterateOp, refSeq + 2));
177
+ (0, testUtils_js_1.validatePartialLengths)(constants_js_1.NonCollabClient, client.mergeTree, [
161
178
  { seq: refSeq, len: "hello world".length },
162
179
  { seq: refSeq + 1, len: "world".length },
163
180
  { seq: refSeq + 2, len: "world".length },
164
181
  ]);
165
- client.applyMsg(client.makeOpMessage(localObliterateOp, refSeq + 2));
166
182
  (0, testUtils_js_1.validatePartialLengths)(remoteClientId, client.mergeTree, [
167
- { seq: refSeq, len: "hello world".length },
168
- { seq: refSeq + 1, len: "world".length, localSeq: refSeq + 1 },
169
- { seq: refSeq + 2, len: "world".length, localSeq: refSeq + 2 },
170
- ], refSeq);
171
- });
172
- it("passes for remote obliterate and local obliterate", () => {
173
- (0, testUtils_js_1.obliterateRange)({
174
- mergeTree: client.mergeTree,
175
- start: 0,
176
- end: "hello ".length,
177
- refSeq,
178
- clientId: remoteClientId,
179
- seq: refSeq + 1,
180
- opArgs: undefined,
181
- });
182
- const localObliterateOp = client.obliterateRangeLocal(0, "hello".length);
183
- (0, testUtils_js_1.validatePartialLengths)(localClientId, client.mergeTree, [
184
- { seq: refSeq, len: "hello world".length },
183
+ { seq: refSeq, len: "world".length },
185
184
  { seq: refSeq + 1, len: "world".length },
186
185
  { seq: refSeq + 2, len: "world".length },
187
186
  ]);
188
- client.applyMsg(client.makeOpMessage(localObliterateOp, refSeq + 2));
189
- (0, testUtils_js_1.validatePartialLengths)(remoteClientId, client.mergeTree, [
190
- { seq: refSeq, len: "hello world".length, localSeq: refSeq },
191
- { seq: refSeq + 1, len: "world".length, localSeq: refSeq + 1 },
192
- { seq: refSeq + 2, len: "".length, localSeq: refSeq + 2 },
193
- ], refSeq);
194
187
  });
195
188
  });
196
189
  describe("obliterate with concurrent inserts", () => {
197
190
  it("obliterates when concurrent insert in middle of string", () => {
198
191
  const localObliterateOp = client.obliterateRangeLocal(0, client.getLength());
199
- (0, testUtils_js_1.insertText)({
200
- mergeTree: client.mergeTree,
201
- pos: "hello".length,
202
- refSeq,
203
- clientId: remoteClientId,
204
- seq: refSeq + 1,
205
- text: "more ",
206
- props: undefined,
207
- opArgs: { op: { type: ops_js_1.MergeTreeDeltaType.INSERT } },
208
- });
192
+ client.insertTextRemote("hello".length, "more ", undefined, refSeq + 1, refSeq, client.getLongClientId(remoteClientId));
209
193
  node_assert_1.strict.equal(client.getText(), "");
194
+ const minRefSeqForLocalSeq = new Map([
195
+ [initialLocalSeq, refSeq],
196
+ [initialLocalSeq + 1, refSeq],
197
+ ]);
210
198
  (0, testUtils_js_1.validatePartialLengths)(localClientId, client.mergeTree, [
199
+ { seq: refSeq, len: "hello world".length, localSeq: initialLocalSeq },
200
+ { seq: refSeq, len: "".length, localSeq: initialLocalSeq + 1 },
201
+ { seq: refSeq + 1, len: "hellomore world".length, localSeq: initialLocalSeq },
202
+ { seq: refSeq + 1, len: "".length, localSeq: initialLocalSeq + 1 },
203
+ ], minRefSeqForLocalSeq);
204
+ client.applyMsg(client.makeOpMessage(localObliterateOp, refSeq + 2));
205
+ (0, testUtils_js_1.validatePartialLengths)(constants_js_1.NonCollabClient, client.mergeTree, [
211
206
  { seq: refSeq, len: "hello world".length },
212
207
  { seq: refSeq + 1, len: "hellomore world".length },
213
- { seq: refSeq + 1, len: "".length, localSeq: refSeq + 1 },
208
+ { seq: refSeq + 2, len: "".length },
214
209
  ]);
215
- client.applyMsg(client.makeOpMessage(localObliterateOp, refSeq + 2));
216
210
  (0, testUtils_js_1.validatePartialLengths)(remoteClientId, client.mergeTree, [
217
- { seq: refSeq, len: "hello world".length },
211
+ { seq: refSeq, len: "hellomore world".length },
218
212
  { seq: refSeq + 1, len: "hellomore world".length },
219
- { seq: refSeq + 2, len: "".length, localSeq: refSeq + 2 },
220
- ], refSeq);
213
+ { seq: refSeq + 2, len: "".length },
214
+ ]);
221
215
  });
222
216
  it("obliterate does not affect concurrent insert at start of string", () => {
223
217
  const localObliterateOp = client.obliterateRangeLocal(0, client.getLength());
224
- (0, testUtils_js_1.insertText)({
225
- mergeTree: client.mergeTree,
226
- pos: 0,
227
- refSeq,
228
- clientId: remoteClientId,
229
- seq: refSeq + 1,
230
- text: "more ",
231
- props: undefined,
232
- opArgs: { op: { type: ops_js_1.MergeTreeDeltaType.INSERT } },
233
- });
218
+ client.insertTextRemote(0, "more ", undefined, refSeq + 1, refSeq, client.getLongClientId(remoteClientId));
234
219
  node_assert_1.strict.equal(client.getText(), "more ");
220
+ const minRefSeqForLocalSeq = new Map([
221
+ [initialLocalSeq, refSeq],
222
+ [initialLocalSeq + 1, refSeq],
223
+ ]);
235
224
  (0, testUtils_js_1.validatePartialLengths)(localClientId, client.mergeTree, [
225
+ { seq: refSeq, len: "hello world".length, localSeq: initialLocalSeq },
226
+ { seq: refSeq, len: "".length, localSeq: initialLocalSeq + 1 },
227
+ { seq: refSeq + 1, len: "more hello world".length, localSeq: initialLocalSeq },
228
+ { seq: refSeq + 1, len: "more ".length, localSeq: initialLocalSeq + 1 },
229
+ ], minRefSeqForLocalSeq);
230
+ client.applyMsg(client.makeOpMessage(localObliterateOp, refSeq + 2));
231
+ (0, testUtils_js_1.validatePartialLengths)(constants_js_1.NonCollabClient, client.mergeTree, [
236
232
  { seq: refSeq, len: "hello world".length },
237
233
  { seq: refSeq + 1, len: "more hello world".length },
238
- { seq: refSeq + 1, len: "more ".length, localSeq: refSeq + 1 },
234
+ { seq: refSeq + 2, len: "more ".length },
239
235
  ]);
240
- client.applyMsg(client.makeOpMessage(localObliterateOp, refSeq + 2));
241
236
  (0, testUtils_js_1.validatePartialLengths)(remoteClientId, client.mergeTree, [
242
- { seq: refSeq, len: "hello world".length },
237
+ { seq: refSeq, len: "more hello world".length },
243
238
  { seq: refSeq + 1, len: "more hello world".length },
244
239
  { seq: refSeq + 2, len: "more ".length },
245
- ], refSeq);
240
+ ]);
246
241
  });
247
242
  it("obliterate does not affect concurrent insert at end of string", () => {
248
243
  const localObliterateOp = client.obliterateRangeLocal(0, client.getLength());
249
- (0, testUtils_js_1.insertText)({
250
- mergeTree: client.mergeTree,
251
- pos: "hello world".length,
252
- refSeq,
253
- clientId: remoteClientId,
254
- seq: refSeq + 1,
255
- text: "more ",
256
- props: undefined,
257
- opArgs: { op: { type: ops_js_1.MergeTreeDeltaType.INSERT } },
258
- });
244
+ client.insertTextRemote("hello world".length, "more ", undefined, refSeq + 1, refSeq, client.getLongClientId(remoteClientId));
259
245
  node_assert_1.strict.equal(client.getText(), "more ");
260
246
  (0, testUtils_js_1.validatePartialLengths)(localClientId, client.mergeTree, [
247
+ { seq: refSeq, len: "hello world".length, localSeq: initialLocalSeq },
248
+ { seq: refSeq, len: "".length, localSeq: initialLocalSeq + 1 },
249
+ { seq: refSeq + 1, len: "hello worldmore ".length, localSeq: initialLocalSeq },
250
+ { seq: refSeq + 1, len: "more ".length, localSeq: initialLocalSeq + 1 },
251
+ ]);
252
+ client.applyMsg(client.makeOpMessage(localObliterateOp, refSeq + 2));
253
+ (0, testUtils_js_1.validatePartialLengths)(constants_js_1.NonCollabClient, client.mergeTree, [
261
254
  { seq: refSeq, len: "hello world".length },
262
255
  { seq: refSeq + 1, len: "hello worldmore ".length },
263
- { seq: refSeq + 1, len: "more ".length, localSeq: refSeq + 1 },
256
+ { seq: refSeq + 2, len: "more ".length },
264
257
  ]);
265
- client.applyMsg(client.makeOpMessage(localObliterateOp, refSeq + 2));
266
258
  (0, testUtils_js_1.validatePartialLengths)(remoteClientId, client.mergeTree, [
267
- { seq: refSeq, len: "hello world".length },
259
+ { seq: refSeq, len: "hello worldmore ".length },
268
260
  { seq: refSeq + 1, len: "hello worldmore ".length },
269
261
  { seq: refSeq + 2, len: "more ".length },
270
- ], refSeq);
262
+ ]);
263
+ });
264
+ });
265
+ describe("Overlapping remote/local obliterate with insertion within the collab window", () => {
266
+ it("acked insertion", () => {
267
+ let seq = client.getCurrentSeq();
268
+ const initialSeq = seq;
269
+ client.insertTextRemote(0, "more ", undefined, ++seq, refSeq, client.getLongClientId(remoteClientId));
270
+ const insertSeq = seq;
271
+ client.obliterateRangeLocal(0, 5);
272
+ const localRemoveLocalSeq = client.getCollabWindow().localSeq;
273
+ client.obliterateRangeRemote(0, 5, ++seq, insertSeq, client.getLongClientId(remoteClientId));
274
+ const obliterateSeq = seq;
275
+ (0, testUtils_js_1.validatePartialLengths)(localClientId, client.mergeTree, [
276
+ { seq: initialSeq, localSeq: initialLocalSeq, len: "hello world".length },
277
+ { seq: insertSeq, localSeq: initialLocalSeq, len: "more hello world".length },
278
+ { seq: obliterateSeq, localSeq: initialLocalSeq, len: "hello world".length },
279
+ { seq: initialSeq, localSeq: localRemoveLocalSeq, len: "hello world".length },
280
+ { seq: insertSeq, localSeq: localRemoveLocalSeq, len: "hello world".length },
281
+ { seq: obliterateSeq, localSeq: localRemoveLocalSeq, len: "hello world".length },
282
+ ]);
283
+ });
284
+ it("local insertion", () => {
285
+ let seq = client.getCurrentSeq();
286
+ const initialSeq = seq;
287
+ client.insertTextLocal(6, "more ");
288
+ const insertLocalSeq = client.getCollabWindow().localSeq;
289
+ client.obliterateRangeLocal(6, 11); // Remove the added "more "
290
+ const localRemoveLocalSeq = client.getCollabWindow().localSeq;
291
+ client.obliterateRangeRemote(0, "hello world".length, ++seq, initialSeq, client.getLongClientId(remoteClientId));
292
+ const obliterateSeq = seq;
293
+ (0, testUtils_js_1.validatePartialLengths)(localClientId, client.mergeTree, [
294
+ { seq: initialSeq, localSeq: initialLocalSeq, len: "hello world".length },
295
+ { seq: initialSeq, localSeq: insertLocalSeq, len: "hello more world".length },
296
+ { seq: initialSeq, localSeq: localRemoveLocalSeq, len: "hello world".length },
297
+ { seq: obliterateSeq, localSeq: initialLocalSeq, len: "".length },
298
+ { seq: obliterateSeq, localSeq: insertLocalSeq, len: "".length },
299
+ { seq: obliterateSeq, localSeq: localRemoveLocalSeq, len: "".length },
300
+ ]);
271
301
  });
272
302
  });
273
303
  });
@@ -1 +1 @@
1
- {"version":3,"file":"obliterate.partialLength.spec.js","sourceRoot":"","sources":["../../src/test/obliterate.partialLength.spec.ts"],"names":[],"mappings":";AAAA;;;GAGG;;AAEH,6CAA+C;AAE/C,sCAA+C;AAE/C,mDAA6C;AAC7C,iDAKwB;AAExB,QAAQ,CAAC,4BAA4B,EAAE,GAAG,EAAE;IAC3C,IAAI,MAAkB,CAAC;IACvB,IAAI,MAAc,CAAC;IACnB,MAAM,aAAa,GAAG,EAAE,CAAC;IACzB,MAAM,cAAc,GAAG,EAAE,CAAC;IAE1B,IAAA,2CAA4B,GAAE,CAAC;IAE/B,UAAU,CAAC,GAAG,EAAE;QACf,MAAM,GAAG,IAAI,0BAAU,CAAC;YACvB,yBAAyB,EAAE,IAAI;SAC/B,CAAC,CAAC;QACH,MAAM,CAAC,0BAA0B,CAAC,OAAO,CAAC,CAAC;QAC3C,KAAK,MAAM,IAAI,IAAI,aAAa,EAAE,CAAC;YAClC,MAAM,CAAC,QAAQ,CACd,MAAM,CAAC,aAAa,CACnB,MAAM,CAAC,eAAe,CAAC,MAAM,CAAC,SAAS,EAAE,EAAE,IAAI,CAAC,EAChD,MAAM,CAAC,aAAa,EAAE,GAAG,CAAC,CAC1B,CACD,CAAC;QACH,CAAC;QACD,oBAAM,CAAC,KAAK,CAAC,MAAM,CAAC,OAAO,EAAE,EAAE,aAAa,CAAC,CAAC;QAC9C,MAAM,GAAG,MAAM,CAAC,aAAa,EAAE,CAAC;IACjC,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,cAAc,EAAE,GAAG,EAAE;QACvB,oBAAM,CAAC,KAAK,CAAC,MAAM,CAAC,OAAO,EAAE,EAAE,aAAa,CAAC,CAAC;QAC9C,MAAM,iBAAiB,GAAG,MAAM,CAAC,oBAAoB,CAAC,CAAC,EAAE,aAAa,CAAC,MAAM,CAAC,CAAC;QAC/E,oBAAM,CAAC,KAAK,CAAC,MAAM,CAAC,OAAO,EAAE,EAAE,EAAE,CAAC,CAAC;QAEnC,IAAA,qCAAsB,EAAC,aAAa,EAAE,MAAM,CAAC,SAAS,EAAE;YACvD,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,aAAa,CAAC,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE;YAC5D,EAAE,GAAG,EAAE,MAAM,GAAG,CAAC,EAAE,GAAG,EAAE,EAAE,CAAC,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,CAAC,EAAE;SACzD,CAAC,CAAC;QAEH,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,aAAa,CAAC,iBAAiB,EAAE,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC;QAErE,IAAA,qCAAsB,EAAC,cAAc,EAAE,MAAM,CAAC,SAAS,EAAE;YACxD,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,aAAa,CAAC,MAAM,EAAE;YAC1C,EAAE,GAAG,EAAE,MAAM,GAAG,CAAC,EAAE,GAAG,EAAE,EAAE,CAAC,MAAM,EAAE;SACnC,CAAC,CAAC;IACJ,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,uDAAuD,EAAE,GAAG,EAAE;QAChE,MAAM,iBAAiB,GAAG,MAAM,CAAC,oBAAoB,CAAC,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,CAAC;QAC1E,MAAM,aAAa,GAAG,MAAM,CAAC,gBAAgB,CAAC,CAAC,EAAE,OAAO,CAAC,MAAM,CAAC,CAAC;QAEjE,IAAA,qCAAsB,EAAC,aAAa,EAAE,MAAM,CAAC,SAAS,EAAE;YACvD,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,aAAa,CAAC,MAAM,EAAE;YAC1C,EAAE,GAAG,EAAE,MAAM,GAAG,CAAC,EAAE,GAAG,EAAE,OAAO,CAAC,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,CAAC,EAAE;YAC9D,EAAE,GAAG,EAAE,MAAM,GAAG,CAAC,EAAE,GAAG,EAAE,EAAE,CAAC,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,CAAC,EAAE;SACzD,CAAC,CAAC;QAEH,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,aAAa,CAAC,iBAAiB,EAAE,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC;QACrE,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,aAAa,CAAC,aAAa,EAAE,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC;QAEjE,IAAA,qCAAsB,EAAC,cAAc,EAAE,MAAM,CAAC,SAAS,EAAE;YACxD,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,aAAa,CAAC,MAAM,EAAE;YAC1C,EAAE,GAAG,EAAE,MAAM,GAAG,CAAC,EAAE,GAAG,EAAE,OAAO,CAAC,MAAM,EAAE;YACxC,EAAE,GAAG,EAAE,MAAM,GAAG,CAAC,EAAE,GAAG,EAAE,EAAE,CAAC,MAAM,EAAE;SACnC,CAAC,CAAC;IACJ,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,kCAAkC,EAAE,GAAG,EAAE;QAC3C,MAAM,GAAG,IAAI,0BAAU,CAAC;YACvB,yBAAyB,EAAE,IAAI;SAC/B,CAAC,CAAC;QACH,MAAM,CAAC,0BAA0B,CAAC,OAAO,CAAC,CAAC;QAE3C,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC;YAC9B,IAAA,yBAAU,EAAC;gBACV,SAAS,EAAE,MAAM,CAAC,SAAS;gBAC3B,GAAG,EAAE,CAAC;gBACN,MAAM,EAAE,CAAC;gBACT,QAAQ,EAAE,aAAa;gBACvB,GAAG,EAAE,CAAC,GAAG,CAAC;gBACV,IAAI,EAAE,GAAG;gBACT,KAAK,EAAE,SAAS;gBAChB,MAAM,EAAE,EAAE,EAAE,EAAE,EAAE,IAAI,EAAE,2BAAkB,CAAC,MAAM,EAAE,EAAE;aACnD,CAAC,CAAC;YAEH,IAAA,qCAAsB,EAAC,aAAa,EAAE,MAAM,CAAC,SAAS,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,GAAG,CAAC,EAAE,GAAG,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC;YACtF,IAAA,qCAAsB,EAAC,cAAc,EAAE,MAAM,CAAC,SAAS,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,GAAG,CAAC,EAAE,GAAG,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC;YAEvF,MAAM,IAAI,CAAC,CAAC;QACb,CAAC;QAED,MAAM,iBAAiB,GAAG,MAAM,CAAC,oBAAoB,CAAC,EAAE,EAAE,GAAG,CAAC,CAAC;QAE/D,IAAA,qCAAsB,EAAC,aAAa,EAAE,MAAM,CAAC,SAAS,CAAC,CAAC;QAExD,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,aAAa,CAAC,iBAAiB,EAAE,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC;QAErE,IAAA,qCAAsB,EAAC,cAAc,EAAE,MAAM,CAAC,SAAS,CAAC,CAAC;IAC1D,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,+BAA+B,EAAE,GAAG,EAAE;QAC9C,EAAE,CAAC,+CAA+C,EAAE,GAAG,EAAE;YACxD,MAAM,aAAa,GAAG,MAAM,CAAC,gBAAgB,CAAC,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,CAAC;YAClE,IAAA,8BAAe,EAAC;gBACf,SAAS,EAAE,MAAM,CAAC,SAAS;gBAC3B,KAAK,EAAE,CAAC;gBACR,GAAG,EAAE,QAAQ,CAAC,MAAM;gBACpB,MAAM;gBACN,QAAQ,EAAE,cAAc;gBACxB,GAAG,EAAE,MAAM,GAAG,CAAC;gBACf,MAAM,EAAE,SAAkB;aAC1B,CAAC,CAAC;YAEH,IAAA,qCAAsB,EAAC,aAAa,EAAE,MAAM,CAAC,SAAS,EAAE;gBACvD,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,aAAa,CAAC,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE;gBAC5D,EAAE,GAAG,EAAE,MAAM,GAAG,CAAC,EAAE,GAAG,EAAE,OAAO,CAAC,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,CAAC,EAAE;aAC9D,CAAC,CAAC;YAEH,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,aAAa,CAAC,aAAa,EAAE,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC;YAEjE,IAAA,qCAAsB,EACrB,cAAc,EACd,MAAM,CAAC,SAAS,EAChB;gBACC,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,aAAa,CAAC,MAAM,EAAE;gBAC1C,EAAE,GAAG,EAAE,MAAM,GAAG,CAAC,EAAE,GAAG,EAAE,OAAO,CAAC,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,CAAC,EAAE;aAC9D,EACD,MAAM,CACN,CAAC;QACH,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,+CAA+C,EAAE,GAAG,EAAE;YACxD,MAAM,CAAC,iBAAiB,CACvB,CAAC,EACD,QAAQ,CAAC,MAAM,EACf,MAAM,GAAG,CAAC,EACV,MAAM,EACN,MAAM,CAAC,eAAe,CAAC,cAAc,CAAC,CACtC,CAAC;YACF,MAAM,iBAAiB,GAAG,MAAM,CAAC,oBAAoB,CAAC,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,CAAC;YAE1E,IAAA,qCAAsB,EAAC,aAAa,EAAE,MAAM,CAAC,SAAS,EAAE;gBACvD,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,aAAa,CAAC,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE;gBAC5D,EAAE,GAAG,EAAE,MAAM,GAAG,CAAC,EAAE,GAAG,EAAE,OAAO,CAAC,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,CAAC,EAAE;gBAC9D,EAAE,GAAG,EAAE,MAAM,GAAG,CAAC,EAAE,GAAG,EAAE,OAAO,CAAC,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,CAAC,EAAE;aAC9D,CAAC,CAAC;YAEH,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,aAAa,CAAC,iBAAiB,EAAE,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC;YAErE,IAAA,qCAAsB,EAAC,cAAc,EAAE,MAAM,CAAC,SAAS,EAAE;gBACxD,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,aAAa,CAAC,MAAM,EAAE;gBAC1C,EAAE,GAAG,EAAE,MAAM,GAAG,CAAC,EAAE,GAAG,EAAE,aAAa,CAAC,MAAM,EAAE;gBAC9C,EAAE,GAAG,EAAE,MAAM,GAAG,CAAC,EAAE,GAAG,EAAE,OAAO,CAAC,MAAM,EAAE;aACxC,CAAC,CAAC;QACJ,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,gDAAgD,EAAE,GAAG,EAAE;YACzD,MAAM,CAAC,iBAAiB,CACvB,CAAC,EACD,QAAQ,CAAC,MAAM,EACf,MAAM,GAAG,CAAC,EACV,MAAM,EACN,MAAM,CAAC,eAAe,CAAC,cAAc,CAAC,CACtC,CAAC;YACF,IAAA,8BAAe,EAAC;gBACf,SAAS,EAAE,MAAM,CAAC,SAAS;gBAC3B,KAAK,EAAE,CAAC;gBACR,GAAG,EAAE,QAAQ,CAAC,MAAM;gBACpB,MAAM;gBACN,QAAQ,EAAE,cAAc,GAAG,CAAC;gBAC5B,GAAG,EAAE,MAAM,GAAG,CAAC;gBACf,MAAM,EAAE,SAAkB;aAC1B,CAAC,CAAC;YAEH,IAAA,qCAAsB,EAAC,aAAa,EAAE,MAAM,CAAC,SAAS,EAAE;gBACvD,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,aAAa,CAAC,MAAM,EAAE;gBAC1C,EAAE,GAAG,EAAE,MAAM,GAAG,CAAC,EAAE,GAAG,EAAE,aAAa,CAAC,MAAM,EAAE;gBAC9C,EAAE,GAAG,EAAE,MAAM,GAAG,CAAC,EAAE,GAAG,EAAE,OAAO,CAAC,MAAM,EAAE;aACxC,CAAC,CAAC;YACH,IAAA,qCAAsB,EACrB,cAAc,EACd,MAAM,CAAC,SAAS,EAChB;gBACC,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,aAAa,CAAC,MAAM,EAAE;gBAC1C,EAAE,GAAG,EAAE,MAAM,GAAG,CAAC,EAAE,GAAG,EAAE,aAAa,CAAC,MAAM,EAAE;gBAC9C,EAAE,GAAG,EAAE,MAAM,GAAG,CAAC,EAAE,GAAG,EAAE,OAAO,CAAC,MAAM,EAAE;aACxC,EACD,CAAC,CACD,CAAC;YACF,IAAA,qCAAsB,EACrB,cAAc,GAAG,CAAC,EAClB,MAAM,CAAC,SAAS,EAChB;gBACC,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,aAAa,CAAC,MAAM,EAAE;gBAC1C,EAAE,GAAG,EAAE,MAAM,GAAG,CAAC,EAAE,GAAG,EAAE,aAAa,CAAC,MAAM,EAAE;gBAC9C,EAAE,GAAG,EAAE,MAAM,GAAG,CAAC,EAAE,GAAG,EAAE,OAAO,CAAC,MAAM,EAAE;aACxC,EACD,CAAC,CACD,CAAC;QACH,CAAC,CAAC,CAAC;IACJ,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,mCAAmC,EAAE,GAAG,EAAE;QAClD,EAAE,CAAC,mDAAmD,EAAE,GAAG,EAAE;YAC5D,MAAM,iBAAiB,GAAG,MAAM,CAAC,oBAAoB,CAAC,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,CAAC;YAC1E,IAAA,8BAAe,EAAC;gBACf,SAAS,EAAE,MAAM,CAAC,SAAS;gBAC3B,KAAK,EAAE,CAAC;gBACR,GAAG,EAAE,QAAQ,CAAC,MAAM;gBACpB,MAAM;gBACN,QAAQ,EAAE,cAAc;gBACxB,GAAG,EAAE,MAAM,GAAG,CAAC;gBACf,MAAM,EAAE,SAAkB;aAC1B,CAAC,CAAC;YAEH,IAAA,qCAAsB,EAAC,aAAa,EAAE,MAAM,CAAC,SAAS,EAAE;gBACvD,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,aAAa,CAAC,MAAM,EAAE;gBAC1C,EAAE,GAAG,EAAE,MAAM,GAAG,CAAC,EAAE,GAAG,EAAE,OAAO,CAAC,MAAM,EAAE;gBACxC,EAAE,GAAG,EAAE,MAAM,GAAG,CAAC,EAAE,GAAG,EAAE,OAAO,CAAC,MAAM,EAAE;aACxC,CAAC,CAAC;YAEH,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,aAAa,CAAC,iBAAiB,EAAE,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC;YAErE,IAAA,qCAAsB,EACrB,cAAc,EACd,MAAM,CAAC,SAAS,EAChB;gBACC,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,aAAa,CAAC,MAAM,EAAE;gBAC1C,EAAE,GAAG,EAAE,MAAM,GAAG,CAAC,EAAE,GAAG,EAAE,OAAO,CAAC,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,CAAC,EAAE;gBAC9D,EAAE,GAAG,EAAE,MAAM,GAAG,CAAC,EAAE,GAAG,EAAE,OAAO,CAAC,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,CAAC,EAAE;aAC9D,EACD,MAAM,CACN,CAAC;QACH,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,mDAAmD,EAAE,GAAG,EAAE;YAC5D,IAAA,8BAAe,EAAC;gBACf,SAAS,EAAE,MAAM,CAAC,SAAS;gBAC3B,KAAK,EAAE,CAAC;gBACR,GAAG,EAAE,QAAQ,CAAC,MAAM;gBACpB,MAAM;gBACN,QAAQ,EAAE,cAAc;gBACxB,GAAG,EAAE,MAAM,GAAG,CAAC;gBACf,MAAM,EAAE,SAAkB;aAC1B,CAAC,CAAC;YACH,MAAM,iBAAiB,GAAG,MAAM,CAAC,oBAAoB,CAAC,CAAC,EAAE,OAAO,CAAC,MAAM,CAAC,CAAC;YAEzE,IAAA,qCAAsB,EAAC,aAAa,EAAE,MAAM,CAAC,SAAS,EAAE;gBACvD,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,aAAa,CAAC,MAAM,EAAE;gBAC1C,EAAE,GAAG,EAAE,MAAM,GAAG,CAAC,EAAE,GAAG,EAAE,OAAO,CAAC,MAAM,EAAE;gBACxC,EAAE,GAAG,EAAE,MAAM,GAAG,CAAC,EAAE,GAAG,EAAE,OAAO,CAAC,MAAM,EAAE;aACxC,CAAC,CAAC;YAEH,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,aAAa,CAAC,iBAAiB,EAAE,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC;YAErE,IAAA,qCAAsB,EACrB,cAAc,EACd,MAAM,CAAC,SAAS,EAChB;gBACC,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,aAAa,CAAC,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE;gBAC5D,EAAE,GAAG,EAAE,MAAM,GAAG,CAAC,EAAE,GAAG,EAAE,OAAO,CAAC,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,CAAC,EAAE;gBAC9D,EAAE,GAAG,EAAE,MAAM,GAAG,CAAC,EAAE,GAAG,EAAE,EAAE,CAAC,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,CAAC,EAAE;aACzD,EACD,MAAM,CACN,CAAC;QACH,CAAC,CAAC,CAAC;IACJ,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,oCAAoC,EAAE,GAAG,EAAE;QACnD,EAAE,CAAC,wDAAwD,EAAE,GAAG,EAAE;YACjE,MAAM,iBAAiB,GAAG,MAAM,CAAC,oBAAoB,CAAC,CAAC,EAAE,MAAM,CAAC,SAAS,EAAE,CAAC,CAAC;YAC7E,IAAA,yBAAU,EAAC;gBACV,SAAS,EAAE,MAAM,CAAC,SAAS;gBAC3B,GAAG,EAAE,OAAO,CAAC,MAAM;gBACnB,MAAM;gBACN,QAAQ,EAAE,cAAc;gBACxB,GAAG,EAAE,MAAM,GAAG,CAAC;gBACf,IAAI,EAAE,OAAO;gBACb,KAAK,EAAE,SAAS;gBAChB,MAAM,EAAE,EAAE,EAAE,EAAE,EAAE,IAAI,EAAE,2BAAkB,CAAC,MAAM,EAAE,EAAE;aACnD,CAAC,CAAC;YACH,oBAAM,CAAC,KAAK,CAAC,MAAM,CAAC,OAAO,EAAE,EAAE,EAAE,CAAC,CAAC;YAEnC,IAAA,qCAAsB,EAAC,aAAa,EAAE,MAAM,CAAC,SAAS,EAAE;gBACvD,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,aAAa,CAAC,MAAM,EAAE;gBAC1C,EAAE,GAAG,EAAE,MAAM,GAAG,CAAC,EAAE,GAAG,EAAE,kBAAkB,CAAC,MAAM,EAAE;gBACnD,EAAE,GAAG,EAAE,MAAM,GAAG,CAAC,EAAE,GAAG,EAAE,EAAE,CAAC,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,CAAC,EAAE;aACzD,CAAC,CAAC;YAEH,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,aAAa,CAAC,iBAAiB,EAAE,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC;YAErE,IAAA,qCAAsB,EACrB,cAAc,EACd,MAAM,CAAC,SAAS,EAChB;gBACC,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,aAAa,CAAC,MAAM,EAAE;gBAC1C,EAAE,GAAG,EAAE,MAAM,GAAG,CAAC,EAAE,GAAG,EAAE,kBAAkB,CAAC,MAAM,EAAE;gBACnD,EAAE,GAAG,EAAE,MAAM,GAAG,CAAC,EAAE,GAAG,EAAE,EAAE,CAAC,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,CAAC,EAAE;aACzD,EACD,MAAM,CACN,CAAC;QACH,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,iEAAiE,EAAE,GAAG,EAAE;YAC1E,MAAM,iBAAiB,GAAG,MAAM,CAAC,oBAAoB,CAAC,CAAC,EAAE,MAAM,CAAC,SAAS,EAAE,CAAC,CAAC;YAC7E,IAAA,yBAAU,EAAC;gBACV,SAAS,EAAE,MAAM,CAAC,SAAS;gBAC3B,GAAG,EAAE,CAAC;gBACN,MAAM;gBACN,QAAQ,EAAE,cAAc;gBACxB,GAAG,EAAE,MAAM,GAAG,CAAC;gBACf,IAAI,EAAE,OAAO;gBACb,KAAK,EAAE,SAAS;gBAChB,MAAM,EAAE,EAAE,EAAE,EAAE,EAAE,IAAI,EAAE,2BAAkB,CAAC,MAAM,EAAE,EAAE;aACnD,CAAC,CAAC;YACH,oBAAM,CAAC,KAAK,CAAC,MAAM,CAAC,OAAO,EAAE,EAAE,OAAO,CAAC,CAAC;YAExC,IAAA,qCAAsB,EAAC,aAAa,EAAE,MAAM,CAAC,SAAS,EAAE;gBACvD,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,aAAa,CAAC,MAAM,EAAE;gBAC1C,EAAE,GAAG,EAAE,MAAM,GAAG,CAAC,EAAE,GAAG,EAAE,kBAAkB,CAAC,MAAM,EAAE;gBACnD,EAAE,GAAG,EAAE,MAAM,GAAG,CAAC,EAAE,GAAG,EAAE,OAAO,CAAC,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,CAAC,EAAE;aAC9D,CAAC,CAAC;YAEH,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,aAAa,CAAC,iBAAiB,EAAE,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC;YAErE,IAAA,qCAAsB,EACrB,cAAc,EACd,MAAM,CAAC,SAAS,EAChB;gBACC,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,aAAa,CAAC,MAAM,EAAE;gBAC1C,EAAE,GAAG,EAAE,MAAM,GAAG,CAAC,EAAE,GAAG,EAAE,kBAAkB,CAAC,MAAM,EAAE;gBACnD,EAAE,GAAG,EAAE,MAAM,GAAG,CAAC,EAAE,GAAG,EAAE,OAAO,CAAC,MAAM,EAAE;aACxC,EACD,MAAM,CACN,CAAC;QACH,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,+DAA+D,EAAE,GAAG,EAAE;YACxE,MAAM,iBAAiB,GAAG,MAAM,CAAC,oBAAoB,CAAC,CAAC,EAAE,MAAM,CAAC,SAAS,EAAE,CAAC,CAAC;YAC7E,IAAA,yBAAU,EAAC;gBACV,SAAS,EAAE,MAAM,CAAC,SAAS;gBAC3B,GAAG,EAAE,aAAa,CAAC,MAAM;gBACzB,MAAM;gBACN,QAAQ,EAAE,cAAc;gBACxB,GAAG,EAAE,MAAM,GAAG,CAAC;gBACf,IAAI,EAAE,OAAO;gBACb,KAAK,EAAE,SAAS;gBAChB,MAAM,EAAE,EAAE,EAAE,EAAE,EAAE,IAAI,EAAE,2BAAkB,CAAC,MAAM,EAAE,EAAE;aACnD,CAAC,CAAC;YACH,oBAAM,CAAC,KAAK,CAAC,MAAM,CAAC,OAAO,EAAE,EAAE,OAAO,CAAC,CAAC;YAExC,IAAA,qCAAsB,EAAC,aAAa,EAAE,MAAM,CAAC,SAAS,EAAE;gBACvD,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,aAAa,CAAC,MAAM,EAAE;gBAC1C,EAAE,GAAG,EAAE,MAAM,GAAG,CAAC,EAAE,GAAG,EAAE,kBAAkB,CAAC,MAAM,EAAE;gBACnD,EAAE,GAAG,EAAE,MAAM,GAAG,CAAC,EAAE,GAAG,EAAE,OAAO,CAAC,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,CAAC,EAAE;aAC9D,CAAC,CAAC;YAEH,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,aAAa,CAAC,iBAAiB,EAAE,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC;YAErE,IAAA,qCAAsB,EACrB,cAAc,EACd,MAAM,CAAC,SAAS,EAChB;gBACC,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,aAAa,CAAC,MAAM,EAAE;gBAC1C,EAAE,GAAG,EAAE,MAAM,GAAG,CAAC,EAAE,GAAG,EAAE,kBAAkB,CAAC,MAAM,EAAE;gBACnD,EAAE,GAAG,EAAE,MAAM,GAAG,CAAC,EAAE,GAAG,EAAE,OAAO,CAAC,MAAM,EAAE;aACxC,EACD,MAAM,CACN,CAAC;QACH,CAAC,CAAC,CAAC;IACJ,CAAC,CAAC,CAAC;AACJ,CAAC,CAAC,CAAC","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { strict as assert } from \"node:assert\";\n\nimport { MergeTreeDeltaType } from \"../ops.js\";\n\nimport { TestClient } from \"./testClient.js\";\nimport {\n\tinsertText,\n\tobliterateRange,\n\tuseStrictPartialLengthChecks,\n\tvalidatePartialLengths,\n} from \"./testUtils.js\";\n\ndescribe(\"obliterate partial lengths\", () => {\n\tlet client: TestClient;\n\tlet refSeq: number;\n\tconst localClientId = 17;\n\tconst remoteClientId = 18;\n\n\tuseStrictPartialLengthChecks();\n\n\tbeforeEach(() => {\n\t\tclient = new TestClient({\n\t\t\tmergeTreeEnableObliterate: true,\n\t\t});\n\t\tclient.startOrUpdateCollaboration(\"local\");\n\t\tfor (const char of \"hello world\") {\n\t\t\tclient.applyMsg(\n\t\t\t\tclient.makeOpMessage(\n\t\t\t\t\tclient.insertTextLocal(client.getLength(), char),\n\t\t\t\t\tclient.getCurrentSeq() + 1,\n\t\t\t\t),\n\t\t\t);\n\t\t}\n\t\tassert.equal(client.getText(), \"hello world\");\n\t\trefSeq = client.getCurrentSeq();\n\t});\n\n\tit(\"removes text\", () => {\n\t\tassert.equal(client.getText(), \"hello world\");\n\t\tconst localObliterateOp = client.obliterateRangeLocal(0, \"hello world\".length);\n\t\tassert.equal(client.getText(), \"\");\n\n\t\tvalidatePartialLengths(localClientId, client.mergeTree, [\n\t\t\t{ seq: refSeq, len: \"hello world\".length, localSeq: refSeq },\n\t\t\t{ seq: refSeq + 1, len: \"\".length, localSeq: refSeq + 1 },\n\t\t]);\n\n\t\tclient.applyMsg(client.makeOpMessage(localObliterateOp, refSeq + 1));\n\n\t\tvalidatePartialLengths(remoteClientId, client.mergeTree, [\n\t\t\t{ seq: refSeq, len: \"hello world\".length },\n\t\t\t{ seq: refSeq + 1, len: \"\".length },\n\t\t]);\n\t});\n\n\tit(\"correctly applies local remove after local obliterate\", () => {\n\t\tconst localObliterateOp = client.obliterateRangeLocal(0, \"hello \".length);\n\t\tconst localRemoveOp = client.removeRangeLocal(0, \"world\".length);\n\n\t\tvalidatePartialLengths(localClientId, client.mergeTree, [\n\t\t\t{ seq: refSeq, len: \"hello world\".length },\n\t\t\t{ seq: refSeq + 1, len: \"world\".length, localSeq: refSeq + 1 },\n\t\t\t{ seq: refSeq + 2, len: \"\".length, localSeq: refSeq + 2 },\n\t\t]);\n\n\t\tclient.applyMsg(client.makeOpMessage(localObliterateOp, refSeq + 1));\n\t\tclient.applyMsg(client.makeOpMessage(localRemoveOp, refSeq + 2));\n\n\t\tvalidatePartialLengths(remoteClientId, client.mergeTree, [\n\t\t\t{ seq: refSeq, len: \"hello world\".length },\n\t\t\t{ seq: refSeq + 1, len: \"world\".length },\n\t\t\t{ seq: refSeq + 2, len: \"\".length },\n\t\t]);\n\t});\n\n\tit(\"is correct for different heights\", () => {\n\t\tclient = new TestClient({\n\t\t\tmergeTreeEnableObliterate: true,\n\t\t});\n\t\tclient.startOrUpdateCollaboration(\"local\");\n\n\t\tfor (let i = 0; i < 100; i++) {\n\t\t\tinsertText({\n\t\t\t\tmergeTree: client.mergeTree,\n\t\t\t\tpos: 0,\n\t\t\t\trefSeq: i,\n\t\t\t\tclientId: localClientId,\n\t\t\t\tseq: i + 1,\n\t\t\t\ttext: \"a\",\n\t\t\t\tprops: undefined,\n\t\t\t\topArgs: { op: { type: MergeTreeDeltaType.INSERT } },\n\t\t\t});\n\n\t\t\tvalidatePartialLengths(localClientId, client.mergeTree, [{ seq: i + 1, len: i + 1 }]);\n\t\t\tvalidatePartialLengths(remoteClientId, client.mergeTree, [{ seq: i + 1, len: i + 1 }]);\n\n\t\t\trefSeq += 1;\n\t\t}\n\n\t\tconst localObliterateOp = client.obliterateRangeLocal(50, 100);\n\n\t\tvalidatePartialLengths(localClientId, client.mergeTree);\n\n\t\tclient.applyMsg(client.makeOpMessage(localObliterateOp, refSeq + 1));\n\n\t\tvalidatePartialLengths(remoteClientId, client.mergeTree);\n\t});\n\n\tdescribe(\"overlapping remove+obliterate\", () => {\n\t\tit(\"passes for local remove and remote obliterate\", () => {\n\t\t\tconst localRemoveOp = client.removeRangeLocal(0, \"hello \".length);\n\t\t\tobliterateRange({\n\t\t\t\tmergeTree: client.mergeTree,\n\t\t\t\tstart: 0,\n\t\t\t\tend: \"hello \".length,\n\t\t\t\trefSeq,\n\t\t\t\tclientId: remoteClientId,\n\t\t\t\tseq: refSeq + 1,\n\t\t\t\topArgs: undefined as never,\n\t\t\t});\n\n\t\t\tvalidatePartialLengths(localClientId, client.mergeTree, [\n\t\t\t\t{ seq: refSeq, len: \"hello world\".length, localSeq: refSeq },\n\t\t\t\t{ seq: refSeq + 1, len: \"world\".length, localSeq: refSeq + 1 },\n\t\t\t]);\n\n\t\t\tclient.applyMsg(client.makeOpMessage(localRemoveOp, refSeq + 1));\n\n\t\t\tvalidatePartialLengths(\n\t\t\t\tremoteClientId,\n\t\t\t\tclient.mergeTree,\n\t\t\t\t[\n\t\t\t\t\t{ seq: refSeq, len: \"hello world\".length },\n\t\t\t\t\t{ seq: refSeq + 1, len: \"world\".length, localSeq: refSeq + 1 },\n\t\t\t\t],\n\t\t\t\trefSeq,\n\t\t\t);\n\t\t});\n\n\t\tit(\"passes for remote remove and local obliterate\", () => {\n\t\t\tclient.removeRangeRemote(\n\t\t\t\t0,\n\t\t\t\t\"hello \".length,\n\t\t\t\trefSeq + 1,\n\t\t\t\trefSeq,\n\t\t\t\tclient.getLongClientId(remoteClientId),\n\t\t\t);\n\t\t\tconst localObliterateOp = client.obliterateRangeLocal(0, \"hello \".length);\n\n\t\t\tvalidatePartialLengths(localClientId, client.mergeTree, [\n\t\t\t\t{ seq: refSeq, len: \"hello world\".length, localSeq: refSeq },\n\t\t\t\t{ seq: refSeq + 1, len: \"world\".length, localSeq: refSeq + 1 },\n\t\t\t\t{ seq: refSeq + 2, len: \"world\".length, localSeq: refSeq + 2 },\n\t\t\t]);\n\n\t\t\tclient.applyMsg(client.makeOpMessage(localObliterateOp, refSeq + 2));\n\n\t\t\tvalidatePartialLengths(remoteClientId, client.mergeTree, [\n\t\t\t\t{ seq: refSeq, len: \"hello world\".length },\n\t\t\t\t{ seq: refSeq + 1, len: \"hello world\".length },\n\t\t\t\t{ seq: refSeq + 2, len: \"world\".length },\n\t\t\t]);\n\t\t});\n\n\t\tit(\"passes for remote remove and remote obliterate\", () => {\n\t\t\tclient.removeRangeRemote(\n\t\t\t\t0,\n\t\t\t\t\"hello \".length,\n\t\t\t\trefSeq + 1,\n\t\t\t\trefSeq,\n\t\t\t\tclient.getLongClientId(remoteClientId),\n\t\t\t);\n\t\t\tobliterateRange({\n\t\t\t\tmergeTree: client.mergeTree,\n\t\t\t\tstart: 0,\n\t\t\t\tend: \"hello \".length,\n\t\t\t\trefSeq,\n\t\t\t\tclientId: remoteClientId + 1,\n\t\t\t\tseq: refSeq + 2,\n\t\t\t\topArgs: undefined as never,\n\t\t\t});\n\n\t\t\tvalidatePartialLengths(localClientId, client.mergeTree, [\n\t\t\t\t{ seq: refSeq, len: \"hello world\".length },\n\t\t\t\t{ seq: refSeq + 1, len: \"hello world\".length },\n\t\t\t\t{ seq: refSeq + 2, len: \"world\".length },\n\t\t\t]);\n\t\t\tvalidatePartialLengths(\n\t\t\t\tremoteClientId,\n\t\t\t\tclient.mergeTree,\n\t\t\t\t[\n\t\t\t\t\t{ seq: refSeq, len: \"hello world\".length },\n\t\t\t\t\t{ seq: refSeq + 1, len: \"hello world\".length },\n\t\t\t\t\t{ seq: refSeq + 2, len: \"world\".length },\n\t\t\t\t],\n\t\t\t\t0,\n\t\t\t);\n\t\t\tvalidatePartialLengths(\n\t\t\t\tremoteClientId + 1,\n\t\t\t\tclient.mergeTree,\n\t\t\t\t[\n\t\t\t\t\t{ seq: refSeq, len: \"hello world\".length },\n\t\t\t\t\t{ seq: refSeq + 1, len: \"hello world\".length },\n\t\t\t\t\t{ seq: refSeq + 2, len: \"world\".length },\n\t\t\t\t],\n\t\t\t\t0,\n\t\t\t);\n\t\t});\n\t});\n\n\tdescribe(\"overlapping obliterate+obliterate\", () => {\n\t\tit(\"passes for local obliterate and remote obliterate\", () => {\n\t\t\tconst localObliterateOp = client.obliterateRangeLocal(0, \"hello \".length);\n\t\t\tobliterateRange({\n\t\t\t\tmergeTree: client.mergeTree,\n\t\t\t\tstart: 0,\n\t\t\t\tend: \"hello \".length,\n\t\t\t\trefSeq,\n\t\t\t\tclientId: remoteClientId,\n\t\t\t\tseq: refSeq + 1,\n\t\t\t\topArgs: undefined as never,\n\t\t\t});\n\n\t\t\tvalidatePartialLengths(localClientId, client.mergeTree, [\n\t\t\t\t{ seq: refSeq, len: \"hello world\".length },\n\t\t\t\t{ seq: refSeq + 1, len: \"world\".length },\n\t\t\t\t{ seq: refSeq + 2, len: \"world\".length },\n\t\t\t]);\n\n\t\t\tclient.applyMsg(client.makeOpMessage(localObliterateOp, refSeq + 2));\n\n\t\t\tvalidatePartialLengths(\n\t\t\t\tremoteClientId,\n\t\t\t\tclient.mergeTree,\n\t\t\t\t[\n\t\t\t\t\t{ seq: refSeq, len: \"hello world\".length },\n\t\t\t\t\t{ seq: refSeq + 1, len: \"world\".length, localSeq: refSeq + 1 },\n\t\t\t\t\t{ seq: refSeq + 2, len: \"world\".length, localSeq: refSeq + 2 },\n\t\t\t\t],\n\t\t\t\trefSeq,\n\t\t\t);\n\t\t});\n\n\t\tit(\"passes for remote obliterate and local obliterate\", () => {\n\t\t\tobliterateRange({\n\t\t\t\tmergeTree: client.mergeTree,\n\t\t\t\tstart: 0,\n\t\t\t\tend: \"hello \".length,\n\t\t\t\trefSeq,\n\t\t\t\tclientId: remoteClientId,\n\t\t\t\tseq: refSeq + 1,\n\t\t\t\topArgs: undefined as never,\n\t\t\t});\n\t\t\tconst localObliterateOp = client.obliterateRangeLocal(0, \"hello\".length);\n\n\t\t\tvalidatePartialLengths(localClientId, client.mergeTree, [\n\t\t\t\t{ seq: refSeq, len: \"hello world\".length },\n\t\t\t\t{ seq: refSeq + 1, len: \"world\".length },\n\t\t\t\t{ seq: refSeq + 2, len: \"world\".length },\n\t\t\t]);\n\n\t\t\tclient.applyMsg(client.makeOpMessage(localObliterateOp, refSeq + 2));\n\n\t\t\tvalidatePartialLengths(\n\t\t\t\tremoteClientId,\n\t\t\t\tclient.mergeTree,\n\t\t\t\t[\n\t\t\t\t\t{ seq: refSeq, len: \"hello world\".length, localSeq: refSeq },\n\t\t\t\t\t{ seq: refSeq + 1, len: \"world\".length, localSeq: refSeq + 1 },\n\t\t\t\t\t{ seq: refSeq + 2, len: \"\".length, localSeq: refSeq + 2 },\n\t\t\t\t],\n\t\t\t\trefSeq,\n\t\t\t);\n\t\t});\n\t});\n\n\tdescribe(\"obliterate with concurrent inserts\", () => {\n\t\tit(\"obliterates when concurrent insert in middle of string\", () => {\n\t\t\tconst localObliterateOp = client.obliterateRangeLocal(0, client.getLength());\n\t\t\tinsertText({\n\t\t\t\tmergeTree: client.mergeTree,\n\t\t\t\tpos: \"hello\".length,\n\t\t\t\trefSeq,\n\t\t\t\tclientId: remoteClientId,\n\t\t\t\tseq: refSeq + 1,\n\t\t\t\ttext: \"more \",\n\t\t\t\tprops: undefined,\n\t\t\t\topArgs: { op: { type: MergeTreeDeltaType.INSERT } },\n\t\t\t});\n\t\t\tassert.equal(client.getText(), \"\");\n\n\t\t\tvalidatePartialLengths(localClientId, client.mergeTree, [\n\t\t\t\t{ seq: refSeq, len: \"hello world\".length },\n\t\t\t\t{ seq: refSeq + 1, len: \"hellomore world\".length },\n\t\t\t\t{ seq: refSeq + 1, len: \"\".length, localSeq: refSeq + 1 },\n\t\t\t]);\n\n\t\t\tclient.applyMsg(client.makeOpMessage(localObliterateOp, refSeq + 2));\n\n\t\t\tvalidatePartialLengths(\n\t\t\t\tremoteClientId,\n\t\t\t\tclient.mergeTree,\n\t\t\t\t[\n\t\t\t\t\t{ seq: refSeq, len: \"hello world\".length },\n\t\t\t\t\t{ seq: refSeq + 1, len: \"hellomore world\".length },\n\t\t\t\t\t{ seq: refSeq + 2, len: \"\".length, localSeq: refSeq + 2 },\n\t\t\t\t],\n\t\t\t\trefSeq,\n\t\t\t);\n\t\t});\n\n\t\tit(\"obliterate does not affect concurrent insert at start of string\", () => {\n\t\t\tconst localObliterateOp = client.obliterateRangeLocal(0, client.getLength());\n\t\t\tinsertText({\n\t\t\t\tmergeTree: client.mergeTree,\n\t\t\t\tpos: 0,\n\t\t\t\trefSeq,\n\t\t\t\tclientId: remoteClientId,\n\t\t\t\tseq: refSeq + 1,\n\t\t\t\ttext: \"more \",\n\t\t\t\tprops: undefined,\n\t\t\t\topArgs: { op: { type: MergeTreeDeltaType.INSERT } },\n\t\t\t});\n\t\t\tassert.equal(client.getText(), \"more \");\n\n\t\t\tvalidatePartialLengths(localClientId, client.mergeTree, [\n\t\t\t\t{ seq: refSeq, len: \"hello world\".length },\n\t\t\t\t{ seq: refSeq + 1, len: \"more hello world\".length },\n\t\t\t\t{ seq: refSeq + 1, len: \"more \".length, localSeq: refSeq + 1 },\n\t\t\t]);\n\n\t\t\tclient.applyMsg(client.makeOpMessage(localObliterateOp, refSeq + 2));\n\n\t\t\tvalidatePartialLengths(\n\t\t\t\tremoteClientId,\n\t\t\t\tclient.mergeTree,\n\t\t\t\t[\n\t\t\t\t\t{ seq: refSeq, len: \"hello world\".length },\n\t\t\t\t\t{ seq: refSeq + 1, len: \"more hello world\".length },\n\t\t\t\t\t{ seq: refSeq + 2, len: \"more \".length },\n\t\t\t\t],\n\t\t\t\trefSeq,\n\t\t\t);\n\t\t});\n\n\t\tit(\"obliterate does not affect concurrent insert at end of string\", () => {\n\t\t\tconst localObliterateOp = client.obliterateRangeLocal(0, client.getLength());\n\t\t\tinsertText({\n\t\t\t\tmergeTree: client.mergeTree,\n\t\t\t\tpos: \"hello world\".length,\n\t\t\t\trefSeq,\n\t\t\t\tclientId: remoteClientId,\n\t\t\t\tseq: refSeq + 1,\n\t\t\t\ttext: \"more \",\n\t\t\t\tprops: undefined,\n\t\t\t\topArgs: { op: { type: MergeTreeDeltaType.INSERT } },\n\t\t\t});\n\t\t\tassert.equal(client.getText(), \"more \");\n\n\t\t\tvalidatePartialLengths(localClientId, client.mergeTree, [\n\t\t\t\t{ seq: refSeq, len: \"hello world\".length },\n\t\t\t\t{ seq: refSeq + 1, len: \"hello worldmore \".length },\n\t\t\t\t{ seq: refSeq + 1, len: \"more \".length, localSeq: refSeq + 1 },\n\t\t\t]);\n\n\t\t\tclient.applyMsg(client.makeOpMessage(localObliterateOp, refSeq + 2));\n\n\t\t\tvalidatePartialLengths(\n\t\t\t\tremoteClientId,\n\t\t\t\tclient.mergeTree,\n\t\t\t\t[\n\t\t\t\t\t{ seq: refSeq, len: \"hello world\".length },\n\t\t\t\t\t{ seq: refSeq + 1, len: \"hello worldmore \".length },\n\t\t\t\t\t{ seq: refSeq + 2, len: \"more \".length },\n\t\t\t\t],\n\t\t\t\trefSeq,\n\t\t\t);\n\t\t});\n\t});\n});\n"]}
1
+ {"version":3,"file":"obliterate.partialLength.spec.js","sourceRoot":"","sources":["../../src/test/obliterate.partialLength.spec.ts"],"names":[],"mappings":"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","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { strict as assert } from \"node:assert\";\n\nimport { NonCollabClient } from \"../constants.js\";\nimport { MergeTreeDeltaType } from \"../ops.js\";\nimport { TextSegment } from \"../textSegment.js\";\n\nimport { TestClient } from \"./testClient.js\";\nimport { useStrictPartialLengthChecks, validatePartialLengths } from \"./testUtils.js\";\n\ndescribe(\"obliterate partial lengths\", () => {\n\tlet client: TestClient;\n\tlet refSeq: number;\n\tlet initialLocalSeq: number;\n\tlet localClientId: number = Number.NaN;\n\tlet remoteClientId: number = Number.NaN;\n\tlet remoteClientId2: number = Number.NaN;\n\n\tuseStrictPartialLengthChecks();\n\n\tbeforeEach(() => {\n\t\tclient = new TestClient({\n\t\t\tmergeTreeEnableObliterate: true,\n\t\t});\n\t\tclient.startOrUpdateCollaboration(\"local\");\n\t\tlocalClientId = client.getClientId();\n\t\tremoteClientId = client.getOrAddShortClientId(\"remote 1\");\n\t\tremoteClientId2 = client.getOrAddShortClientId(\"remote 2\");\n\t\tfor (const char of \"hello world\") {\n\t\t\tclient.applyMsg(\n\t\t\t\tclient.makeOpMessage(\n\t\t\t\t\tclient.insertTextLocal(client.getLength(), char),\n\t\t\t\t\tclient.getCurrentSeq() + 1,\n\t\t\t\t),\n\t\t\t);\n\t\t}\n\t\tassert.equal(client.getText(), \"hello world\");\n\t\trefSeq = client.getCurrentSeq();\n\t\tinitialLocalSeq = client.getCollabWindow().localSeq;\n\t});\n\n\tit(\"removes text\", () => {\n\t\tassert.equal(client.getText(), \"hello world\");\n\t\tconst localObliterateOp = client.obliterateRangeLocal(0, \"hello world\".length);\n\t\tassert.equal(client.getText(), \"\");\n\t\tconst minRefSeqForLocalSeq = new Map<number, number>([\n\t\t\t[initialLocalSeq, refSeq],\n\t\t\t[initialLocalSeq + 1, refSeq + 1],\n\t\t]);\n\t\tvalidatePartialLengths(\n\t\t\tlocalClientId,\n\t\t\tclient.mergeTree,\n\t\t\t[\n\t\t\t\t{ seq: refSeq, len: \"hello world\".length, localSeq: initialLocalSeq },\n\t\t\t\t{ seq: refSeq + 1, len: \"\".length, localSeq: initialLocalSeq + 1 },\n\t\t\t],\n\t\t\tminRefSeqForLocalSeq,\n\t\t);\n\n\t\tclient.applyMsg(client.makeOpMessage(localObliterateOp, refSeq + 1));\n\n\t\tvalidatePartialLengths(remoteClientId, client.mergeTree, [\n\t\t\t{ seq: refSeq, len: \"hello world\".length },\n\t\t\t{ seq: refSeq + 1, len: \"\".length },\n\t\t]);\n\t});\n\n\tit(\"correctly applies local remove after local obliterate\", () => {\n\t\tconst localObliterateOp = client.obliterateRangeLocal(0, \"hello \".length);\n\t\tconst localRemoveOp = client.removeRangeLocal(0, \"world\".length);\n\n\t\tconst minRefSeqForLocalSeq = new Map<number, number>([\n\t\t\t[initialLocalSeq, refSeq],\n\t\t\t[initialLocalSeq + 1, refSeq],\n\t\t\t[initialLocalSeq + 2, refSeq],\n\t\t]);\n\t\tvalidatePartialLengths(\n\t\t\tlocalClientId,\n\t\t\tclient.mergeTree,\n\t\t\t[\n\t\t\t\t{ seq: refSeq, len: \"hello world\".length, localSeq: initialLocalSeq },\n\t\t\t\t{ seq: refSeq, len: \"world\".length, localSeq: initialLocalSeq + 1 },\n\t\t\t\t{ seq: refSeq, len: \"\".length, localSeq: initialLocalSeq + 2 },\n\t\t\t],\n\t\t\tminRefSeqForLocalSeq,\n\t\t);\n\n\t\tclient.applyMsg(client.makeOpMessage(localObliterateOp, refSeq + 1));\n\t\tclient.applyMsg(client.makeOpMessage(localRemoveOp, refSeq + 2));\n\n\t\tvalidatePartialLengths(remoteClientId, client.mergeTree, [\n\t\t\t{ seq: refSeq, len: \"hello world\".length },\n\t\t\t{ seq: refSeq + 1, len: \"world\".length },\n\t\t\t{ seq: refSeq + 2, len: \"\".length },\n\t\t]);\n\t});\n\n\tit(\"is correct for different heights\", () => {\n\t\tclient = new TestClient({\n\t\t\tmergeTreeEnableObliterate: true,\n\t\t});\n\t\tclient.startOrUpdateCollaboration(\"local\");\n\n\t\tfor (let i = 0; i < 100; i++) {\n\t\t\tclient.mergeTree.insertSegments(\n\t\t\t\t0,\n\t\t\t\t[TextSegment.make(\"a\")],\n\t\t\t\tclient.mergeTree.localPerspective,\n\t\t\t\t{ seq: i + 1, clientId: localClientId },\n\t\t\t\t{ op: { type: MergeTreeDeltaType.INSERT } },\n\t\t\t);\n\n\t\t\tvalidatePartialLengths(localClientId, client.mergeTree, [{ seq: i + 1, len: i + 1 }]);\n\t\t\tvalidatePartialLengths(remoteClientId, client.mergeTree, [{ seq: i + 1, len: i + 1 }]);\n\n\t\t\trefSeq += 1;\n\t\t}\n\n\t\tconst localObliterateOp = client.obliterateRangeLocal(50, 100);\n\n\t\tvalidatePartialLengths(localClientId, client.mergeTree);\n\n\t\tclient.applyMsg(client.makeOpMessage(localObliterateOp, refSeq + 1));\n\n\t\tvalidatePartialLengths(remoteClientId, client.mergeTree);\n\t});\n\n\tdescribe(\"overlapping remove+obliterate\", () => {\n\t\tit(\"passes for local remove and remote obliterate\", () => {\n\t\t\tconst localRemoveOp = client.removeRangeLocal(0, \"hello \".length);\n\t\t\tclient.removeRangeRemote(\n\t\t\t\t0,\n\t\t\t\t\"hello \".length,\n\t\t\t\trefSeq + 1,\n\t\t\t\trefSeq,\n\t\t\t\tclient.getLongClientId(remoteClientId),\n\t\t\t);\n\n\t\t\tconst minRefSeqForLocalSeq = new Map<number, number>([\n\t\t\t\t[initialLocalSeq, refSeq],\n\t\t\t\t[initialLocalSeq + 1, refSeq],\n\t\t\t]);\n\t\t\tvalidatePartialLengths(\n\t\t\t\tlocalClientId,\n\t\t\t\tclient.mergeTree,\n\t\t\t\t[\n\t\t\t\t\t{ seq: refSeq, len: \"hello world\".length, localSeq: initialLocalSeq },\n\t\t\t\t\t{ seq: refSeq, len: \"world\".length, localSeq: initialLocalSeq + 1 },\n\t\t\t\t\t{ seq: refSeq + 1, len: \"world\".length, localSeq: initialLocalSeq },\n\t\t\t\t\t{ seq: refSeq + 1, len: \"world\".length, localSeq: initialLocalSeq + 1 },\n\t\t\t\t],\n\t\t\t\tminRefSeqForLocalSeq,\n\t\t\t);\n\n\t\t\tclient.applyMsg(client.makeOpMessage(localRemoveOp, refSeq + 2));\n\n\t\t\tvalidatePartialLengths(NonCollabClient, client.mergeTree, [\n\t\t\t\t{ seq: refSeq, len: \"hello world\".length },\n\t\t\t\t{ seq: refSeq + 1, len: \"world\".length },\n\t\t\t\t{ seq: refSeq + 2, len: \"world\".length },\n\t\t\t]);\n\t\t\tvalidatePartialLengths(remoteClientId, client.mergeTree, [\n\t\t\t\t{ seq: refSeq, len: \"world\".length },\n\t\t\t\t{ seq: refSeq + 1, len: \"world\".length },\n\t\t\t\t{ seq: refSeq + 2, len: \"world\".length },\n\t\t\t]);\n\t\t});\n\n\t\tit(\"passes for remote remove and local obliterate\", () => {\n\t\t\tconst localObliterateOp = client.obliterateRangeLocal(0, \"hello \".length);\n\t\t\tclient.removeRangeRemote(\n\t\t\t\t0,\n\t\t\t\t\"hello \".length,\n\t\t\t\trefSeq + 1,\n\t\t\t\trefSeq,\n\t\t\t\tclient.getLongClientId(remoteClientId),\n\t\t\t);\n\n\t\t\tconst minRefSeqForLocalSeq = new Map<number, number>([\n\t\t\t\t[initialLocalSeq, refSeq],\n\t\t\t\t[initialLocalSeq + 1, refSeq],\n\t\t\t]);\n\n\t\t\tvalidatePartialLengths(\n\t\t\t\tlocalClientId,\n\t\t\t\tclient.mergeTree,\n\t\t\t\t[\n\t\t\t\t\t{ seq: refSeq, len: \"hello world\".length, localSeq: initialLocalSeq },\n\t\t\t\t\t{ seq: refSeq, len: \"world\".length, localSeq: initialLocalSeq + 1 },\n\t\t\t\t\t{ seq: refSeq + 1, len: \"world\".length, localSeq: initialLocalSeq },\n\t\t\t\t\t{ seq: refSeq + 1, len: \"world\".length, localSeq: initialLocalSeq + 1 },\n\t\t\t\t],\n\t\t\t\tminRefSeqForLocalSeq,\n\t\t\t);\n\n\t\t\tclient.applyMsg(client.makeOpMessage(localObliterateOp, refSeq + 2));\n\n\t\t\tvalidatePartialLengths(NonCollabClient, client.mergeTree, [\n\t\t\t\t{ seq: refSeq, len: \"hello world\".length },\n\t\t\t\t{ seq: refSeq + 1, len: \"world\".length },\n\t\t\t\t{ seq: refSeq + 2, len: \"world\".length },\n\t\t\t]);\n\t\t\tvalidatePartialLengths(remoteClientId, client.mergeTree, [\n\t\t\t\t{ seq: refSeq, len: \"world\".length },\n\t\t\t\t{ seq: refSeq + 1, len: \"world\".length },\n\t\t\t\t{ seq: refSeq + 2, len: \"world\".length },\n\t\t\t]);\n\t\t});\n\n\t\tit(\"passes for remote remove and remote obliterate\", () => {\n\t\t\tclient.removeRangeRemote(\n\t\t\t\t0,\n\t\t\t\t\"hello \".length,\n\t\t\t\trefSeq + 1,\n\t\t\t\trefSeq,\n\t\t\t\tclient.getLongClientId(remoteClientId),\n\t\t\t);\n\t\t\tclient.removeRangeRemote(\n\t\t\t\t0,\n\t\t\t\t\"hello \".length,\n\t\t\t\trefSeq + 2,\n\t\t\t\trefSeq,\n\t\t\t\tclient.getLongClientId(remoteClientId2),\n\t\t\t);\n\n\t\t\tvalidatePartialLengths(NonCollabClient, client.mergeTree, [\n\t\t\t\t{ seq: refSeq, len: \"hello world\".length },\n\t\t\t\t{ seq: refSeq + 1, len: \"world\".length },\n\t\t\t\t{ seq: refSeq + 2, len: \"world\".length },\n\t\t\t]);\n\t\t\tvalidatePartialLengths(remoteClientId, client.mergeTree, [\n\t\t\t\t{ seq: refSeq, len: \"world\".length },\n\t\t\t\t{ seq: refSeq + 1, len: \"world\".length },\n\t\t\t\t{ seq: refSeq + 2, len: \"world\".length },\n\t\t\t]);\n\t\t\tvalidatePartialLengths(remoteClientId2, client.mergeTree, [\n\t\t\t\t{ seq: refSeq, len: \"world\".length },\n\t\t\t\t{ seq: refSeq + 1, len: \"world\".length },\n\t\t\t\t{ seq: refSeq + 2, len: \"world\".length },\n\t\t\t]);\n\t\t});\n\t});\n\n\tdescribe(\"overlapping obliterate+obliterate\", () => {\n\t\tit(\"passes for local obliterate and remote obliterate\", () => {\n\t\t\tconst localObliterateOp = client.obliterateRangeLocal(0, \"hello \".length);\n\t\t\tclient.obliterateRangeRemote(\n\t\t\t\t0,\n\t\t\t\t\"hello \".length,\n\t\t\t\trefSeq + 1,\n\t\t\t\trefSeq,\n\t\t\t\tclient.getLongClientId(remoteClientId),\n\t\t\t);\n\n\t\t\tconst minRefSeqForLocalSeq = new Map<number, number>([\n\t\t\t\t[initialLocalSeq, refSeq],\n\t\t\t\t[initialLocalSeq + 1, refSeq],\n\t\t\t]);\n\t\t\tvalidatePartialLengths(\n\t\t\t\tlocalClientId,\n\t\t\t\tclient.mergeTree,\n\t\t\t\t[\n\t\t\t\t\t{ seq: refSeq, len: \"hello world\".length, localSeq: initialLocalSeq },\n\t\t\t\t\t{ seq: refSeq, len: \"world\".length, localSeq: initialLocalSeq + 1 },\n\t\t\t\t\t{ seq: refSeq + 1, len: \"world\".length, localSeq: initialLocalSeq },\n\t\t\t\t\t{ seq: refSeq + 1, len: \"world\".length, localSeq: initialLocalSeq + 1 },\n\t\t\t\t],\n\t\t\t\tminRefSeqForLocalSeq,\n\t\t\t);\n\n\t\t\tclient.applyMsg(client.makeOpMessage(localObliterateOp, refSeq + 2));\n\n\t\t\tvalidatePartialLengths(NonCollabClient, client.mergeTree, [\n\t\t\t\t{ seq: refSeq, len: \"hello world\".length },\n\t\t\t\t{ seq: refSeq + 1, len: \"world\".length },\n\t\t\t\t{ seq: refSeq + 2, len: \"world\".length },\n\t\t\t]);\n\t\t\tvalidatePartialLengths(remoteClientId, client.mergeTree, [\n\t\t\t\t{ seq: refSeq, len: \"world\".length },\n\t\t\t\t{ seq: refSeq + 1, len: \"world\".length },\n\t\t\t\t{ seq: refSeq + 2, len: \"world\".length },\n\t\t\t]);\n\t\t});\n\t});\n\n\tdescribe(\"obliterate with concurrent inserts\", () => {\n\t\tit(\"obliterates when concurrent insert in middle of string\", () => {\n\t\t\tconst localObliterateOp = client.obliterateRangeLocal(0, client.getLength());\n\n\t\t\tclient.insertTextRemote(\n\t\t\t\t\"hello\".length,\n\t\t\t\t\"more \",\n\t\t\t\tundefined,\n\t\t\t\trefSeq + 1,\n\t\t\t\trefSeq,\n\t\t\t\tclient.getLongClientId(remoteClientId),\n\t\t\t);\n\t\t\tassert.equal(client.getText(), \"\");\n\n\t\t\tconst minRefSeqForLocalSeq = new Map<number, number>([\n\t\t\t\t[initialLocalSeq, refSeq],\n\t\t\t\t[initialLocalSeq + 1, refSeq],\n\t\t\t]);\n\t\t\tvalidatePartialLengths(\n\t\t\t\tlocalClientId,\n\t\t\t\tclient.mergeTree,\n\t\t\t\t[\n\t\t\t\t\t{ seq: refSeq, len: \"hello world\".length, localSeq: initialLocalSeq },\n\t\t\t\t\t{ seq: refSeq, len: \"\".length, localSeq: initialLocalSeq + 1 },\n\t\t\t\t\t{ seq: refSeq + 1, len: \"hellomore world\".length, localSeq: initialLocalSeq },\n\t\t\t\t\t{ seq: refSeq + 1, len: \"\".length, localSeq: initialLocalSeq + 1 },\n\t\t\t\t],\n\t\t\t\tminRefSeqForLocalSeq,\n\t\t\t);\n\n\t\t\tclient.applyMsg(client.makeOpMessage(localObliterateOp, refSeq + 2));\n\n\t\t\tvalidatePartialLengths(NonCollabClient, client.mergeTree, [\n\t\t\t\t{ seq: refSeq, len: \"hello world\".length },\n\t\t\t\t{ seq: refSeq + 1, len: \"hellomore world\".length },\n\t\t\t\t{ seq: refSeq + 2, len: \"\".length },\n\t\t\t]);\n\t\t\tvalidatePartialLengths(remoteClientId, client.mergeTree, [\n\t\t\t\t{ seq: refSeq, len: \"hellomore world\".length },\n\t\t\t\t{ seq: refSeq + 1, len: \"hellomore world\".length },\n\t\t\t\t{ seq: refSeq + 2, len: \"\".length },\n\t\t\t]);\n\t\t});\n\n\t\tit(\"obliterate does not affect concurrent insert at start of string\", () => {\n\t\t\tconst localObliterateOp = client.obliterateRangeLocal(0, client.getLength());\n\t\t\tclient.insertTextRemote(\n\t\t\t\t0,\n\t\t\t\t\"more \",\n\t\t\t\tundefined,\n\t\t\t\trefSeq + 1,\n\t\t\t\trefSeq,\n\t\t\t\tclient.getLongClientId(remoteClientId),\n\t\t\t);\n\t\t\tassert.equal(client.getText(), \"more \");\n\n\t\t\tconst minRefSeqForLocalSeq = new Map<number, number>([\n\t\t\t\t[initialLocalSeq, refSeq],\n\t\t\t\t[initialLocalSeq + 1, refSeq],\n\t\t\t]);\n\t\t\tvalidatePartialLengths(\n\t\t\t\tlocalClientId,\n\t\t\t\tclient.mergeTree,\n\t\t\t\t[\n\t\t\t\t\t{ seq: refSeq, len: \"hello world\".length, localSeq: initialLocalSeq },\n\t\t\t\t\t{ seq: refSeq, len: \"\".length, localSeq: initialLocalSeq + 1 },\n\t\t\t\t\t{ seq: refSeq + 1, len: \"more hello world\".length, localSeq: initialLocalSeq },\n\t\t\t\t\t{ seq: refSeq + 1, len: \"more \".length, localSeq: initialLocalSeq + 1 },\n\t\t\t\t],\n\t\t\t\tminRefSeqForLocalSeq,\n\t\t\t);\n\n\t\t\tclient.applyMsg(client.makeOpMessage(localObliterateOp, refSeq + 2));\n\n\t\t\tvalidatePartialLengths(NonCollabClient, client.mergeTree, [\n\t\t\t\t{ seq: refSeq, len: \"hello world\".length },\n\t\t\t\t{ seq: refSeq + 1, len: \"more hello world\".length },\n\t\t\t\t{ seq: refSeq + 2, len: \"more \".length },\n\t\t\t]);\n\t\t\tvalidatePartialLengths(remoteClientId, client.mergeTree, [\n\t\t\t\t{ seq: refSeq, len: \"more hello world\".length },\n\t\t\t\t{ seq: refSeq + 1, len: \"more hello world\".length },\n\t\t\t\t{ seq: refSeq + 2, len: \"more \".length },\n\t\t\t]);\n\t\t});\n\n\t\tit(\"obliterate does not affect concurrent insert at end of string\", () => {\n\t\t\tconst localObliterateOp = client.obliterateRangeLocal(0, client.getLength());\n\t\t\tclient.insertTextRemote(\n\t\t\t\t\"hello world\".length,\n\t\t\t\t\"more \",\n\t\t\t\tundefined,\n\t\t\t\trefSeq + 1,\n\t\t\t\trefSeq,\n\t\t\t\tclient.getLongClientId(remoteClientId),\n\t\t\t);\n\t\t\tassert.equal(client.getText(), \"more \");\n\n\t\t\tvalidatePartialLengths(localClientId, client.mergeTree, [\n\t\t\t\t{ seq: refSeq, len: \"hello world\".length, localSeq: initialLocalSeq },\n\t\t\t\t{ seq: refSeq, len: \"\".length, localSeq: initialLocalSeq + 1 },\n\t\t\t\t{ seq: refSeq + 1, len: \"hello worldmore \".length, localSeq: initialLocalSeq },\n\t\t\t\t{ seq: refSeq + 1, len: \"more \".length, localSeq: initialLocalSeq + 1 },\n\t\t\t]);\n\n\t\t\tclient.applyMsg(client.makeOpMessage(localObliterateOp, refSeq + 2));\n\n\t\t\tvalidatePartialLengths(NonCollabClient, client.mergeTree, [\n\t\t\t\t{ seq: refSeq, len: \"hello world\".length },\n\t\t\t\t{ seq: refSeq + 1, len: \"hello worldmore \".length },\n\t\t\t\t{ seq: refSeq + 2, len: \"more \".length },\n\t\t\t]);\n\t\t\tvalidatePartialLengths(remoteClientId, client.mergeTree, [\n\t\t\t\t{ seq: refSeq, len: \"hello worldmore \".length },\n\t\t\t\t{ seq: refSeq + 1, len: \"hello worldmore \".length },\n\t\t\t\t{ seq: refSeq + 2, len: \"more \".length },\n\t\t\t]);\n\t\t});\n\t});\n\n\tdescribe(\"Overlapping remote/local obliterate with insertion within the collab window\", () => {\n\t\tit(\"acked insertion\", () => {\n\t\t\tlet seq = client.getCurrentSeq();\n\t\t\tconst initialSeq = seq;\n\t\t\tclient.insertTextRemote(\n\t\t\t\t0,\n\t\t\t\t\"more \",\n\t\t\t\tundefined,\n\t\t\t\t++seq,\n\t\t\t\trefSeq,\n\t\t\t\tclient.getLongClientId(remoteClientId),\n\t\t\t);\n\t\t\tconst insertSeq = seq;\n\n\t\t\tclient.obliterateRangeLocal(0, 5);\n\t\t\tconst localRemoveLocalSeq = client.getCollabWindow().localSeq;\n\t\t\tclient.obliterateRangeRemote(\n\t\t\t\t0,\n\t\t\t\t5,\n\t\t\t\t++seq,\n\t\t\t\tinsertSeq,\n\t\t\t\tclient.getLongClientId(remoteClientId),\n\t\t\t);\n\t\t\tconst obliterateSeq = seq;\n\t\t\tvalidatePartialLengths(localClientId, client.mergeTree, [\n\t\t\t\t{ seq: initialSeq, localSeq: initialLocalSeq, len: \"hello world\".length },\n\t\t\t\t{ seq: insertSeq, localSeq: initialLocalSeq, len: \"more hello world\".length },\n\t\t\t\t{ seq: obliterateSeq, localSeq: initialLocalSeq, len: \"hello world\".length },\n\t\t\t\t{ seq: initialSeq, localSeq: localRemoveLocalSeq, len: \"hello world\".length },\n\t\t\t\t{ seq: insertSeq, localSeq: localRemoveLocalSeq, len: \"hello world\".length },\n\t\t\t\t{ seq: obliterateSeq, localSeq: localRemoveLocalSeq, len: \"hello world\".length },\n\t\t\t]);\n\t\t});\n\n\t\tit(\"local insertion\", () => {\n\t\t\tlet seq = client.getCurrentSeq();\n\t\t\tconst initialSeq = seq;\n\t\t\tclient.insertTextLocal(6, \"more \");\n\t\t\tconst insertLocalSeq = client.getCollabWindow().localSeq;\n\n\t\t\tclient.obliterateRangeLocal(6, 11); // Remove the added \"more \"\n\t\t\tconst localRemoveLocalSeq = client.getCollabWindow().localSeq;\n\t\t\tclient.obliterateRangeRemote(\n\t\t\t\t0,\n\t\t\t\t\"hello world\".length,\n\t\t\t\t++seq,\n\t\t\t\tinitialSeq,\n\t\t\t\tclient.getLongClientId(remoteClientId),\n\t\t\t);\n\t\t\tconst obliterateSeq = seq;\n\t\t\tvalidatePartialLengths(localClientId, client.mergeTree, [\n\t\t\t\t{ seq: initialSeq, localSeq: initialLocalSeq, len: \"hello world\".length },\n\t\t\t\t{ seq: initialSeq, localSeq: insertLocalSeq, len: \"hello more world\".length },\n\t\t\t\t{ seq: initialSeq, localSeq: localRemoveLocalSeq, len: \"hello world\".length },\n\t\t\t\t{ seq: obliterateSeq, localSeq: initialLocalSeq, len: \"\".length },\n\t\t\t\t{ seq: obliterateSeq, localSeq: insertLocalSeq, len: \"\".length },\n\t\t\t\t{ seq: obliterateSeq, localSeq: localRemoveLocalSeq, len: \"\".length },\n\t\t\t]);\n\t\t});\n\t});\n});\n"]}