tmux-team 2.2.0 → 3.0.0-alpha.1

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.
@@ -64,7 +64,6 @@ function createDefaultConfig(): ResolvedConfig {
64
64
  pollInterval: 0.1, // Fast polling for tests
65
65
  captureLines: 100,
66
66
  preambleEvery: 3,
67
- hideOrphanTasks: false,
68
67
  },
69
68
  agents: {},
70
69
  paneRegistry: {
@@ -222,7 +221,6 @@ describe('buildMessage (via cmdTalk)', () => {
222
221
  pollInterval: 0.1,
223
222
  captureLines: 100,
224
223
  preambleEvery: 3,
225
- hideOrphanTasks: false,
226
224
  },
227
225
  };
228
226
 
@@ -259,7 +257,6 @@ describe('buildMessage (via cmdTalk)', () => {
259
257
  pollInterval: 0.1,
260
258
  captureLines: 100,
261
259
  preambleEvery: 1,
262
- hideOrphanTasks: false,
263
260
  },
264
261
  };
265
262
 
@@ -283,7 +280,6 @@ describe('buildMessage (via cmdTalk)', () => {
283
280
  pollInterval: 0.1,
284
281
  captureLines: 100,
285
282
  preambleEvery: 0,
286
- hideOrphanTasks: false,
287
283
  },
288
284
  };
289
285
 
@@ -470,7 +466,6 @@ describe('cmdTalk - --wait mode', () => {
470
466
  pollInterval: 0.01,
471
467
  captureLines: 100,
472
468
  preambleEvery: 3,
473
- hideOrphanTasks: false,
474
469
  },
475
470
  },
476
471
  });
@@ -513,7 +508,6 @@ describe('cmdTalk - --wait mode', () => {
513
508
  pollInterval: 0.01,
514
509
  captureLines: 100,
515
510
  preambleEvery: 3,
516
- hideOrphanTasks: false,
517
511
  },
518
512
  },
519
513
  });
@@ -544,7 +538,6 @@ describe('cmdTalk - --wait mode', () => {
544
538
  pollInterval: 0.02,
545
539
  captureLines: 100,
546
540
  preambleEvery: 3,
547
- hideOrphanTasks: false,
548
541
  },
549
542
  },
550
543
  });
@@ -563,23 +556,23 @@ describe('cmdTalk - --wait mode', () => {
563
556
  expect(output.error).toContain('Timed out');
564
557
  });
565
558
 
566
- it('isolates response from baseline using scrollback', async () => {
559
+ it('isolates response using start/end markers in scrollback', async () => {
567
560
  const tmux = createMockTmux();
568
561
  const ui = createMockUI();
569
562
 
570
- let captureCount = 0;
571
- const baseline = 'Previous conversation\nOld content here';
563
+ const oldContent = 'Previous conversation\nOld content here';
572
564
 
573
565
  tmux.capture = () => {
574
- captureCount++;
575
- if (captureCount === 1) return baseline;
576
- // Second capture includes baseline + new content + marker
566
+ // Simulate scrollback with old content, start marker, response, and end marker
577
567
  const sent = tmux.sends[0]?.message || '';
578
- const match = sent.match(/\{tmux-team-end:([a-f0-9]+)\}/);
579
- if (match) {
580
- return `${baseline}\n\nNew response content\n\n{tmux-team-end:${match[1]}}`;
568
+ const startMatch = sent.match(/\{tmux-team-start:([a-f0-9]+)\}/);
569
+ const endMatch = sent.match(/\{tmux-team-end:([a-f0-9]+)\}/);
570
+ if (startMatch && endMatch) {
571
+ // Start and end markers should have the same nonce
572
+ expect(startMatch[1]).toBe(endMatch[1]);
573
+ return `${oldContent}\n\n{tmux-team-start:${startMatch[1]}}\nMessage content here\n\nNew response content\n\n{tmux-team-end:${endMatch[1]}}`;
581
574
  }
582
- return baseline;
575
+ return oldContent;
583
576
  };
584
577
 
585
578
  const ctx = createContext({
@@ -593,7 +586,6 @@ describe('cmdTalk - --wait mode', () => {
593
586
  pollInterval: 0.01,
594
587
  captureLines: 100,
595
588
  preambleEvery: 3,
596
- hideOrphanTasks: false,
597
589
  },
598
590
  },
599
591
  });
@@ -602,8 +594,11 @@ describe('cmdTalk - --wait mode', () => {
602
594
 
603
595
  const output = ui.jsonOutput[0] as Record<string, unknown>;
604
596
  expect(output.status).toBe('completed');
605
- // Response should NOT include baseline content
606
- expect(output.response).toBe('New response content');
597
+ // Response should NOT include old content before start marker
598
+ expect(output.response).not.toContain('Previous conversation');
599
+ expect(output.response).not.toContain('Old content here');
600
+ // Response should contain the actual response content
601
+ expect(output.response).toContain('New response content');
607
602
  });
608
603
 
609
604
  it('clears active request on completion', async () => {
@@ -629,7 +624,6 @@ describe('cmdTalk - --wait mode', () => {
629
624
  pollInterval: 0.01,
630
625
  captureLines: 100,
631
626
  preambleEvery: 3,
632
- hideOrphanTasks: false,
633
627
  },
634
628
  },
635
629
  });
@@ -658,7 +652,6 @@ describe('cmdTalk - --wait mode', () => {
658
652
  pollInterval: 0.01,
659
653
  captureLines: 100,
660
654
  preambleEvery: 3,
661
- hideOrphanTasks: false,
662
655
  },
663
656
  },
664
657
  });
@@ -713,7 +706,6 @@ describe('cmdTalk - --wait mode', () => {
713
706
  pollInterval: 0.05,
714
707
  captureLines: 100,
715
708
  preambleEvery: 3,
716
- hideOrphanTasks: false,
717
709
  },
718
710
  paneRegistry: {
719
711
  codex: { pane: '10.1' },
@@ -760,7 +752,6 @@ describe('cmdTalk - --wait mode', () => {
760
752
  pollInterval: 0.02,
761
753
  captureLines: 100,
762
754
  preambleEvery: 3,
763
- hideOrphanTasks: false,
764
755
  },
765
756
  paneRegistry: {
766
757
  codex: { pane: '10.1' },
@@ -818,7 +809,6 @@ describe('cmdTalk - --wait mode', () => {
818
809
  pollInterval: 0.02,
819
810
  captureLines: 100,
820
811
  preambleEvery: 3,
821
- hideOrphanTasks: false,
822
812
  },
823
813
  paneRegistry: {
824
814
  codex: { pane: '10.1' },
@@ -853,25 +843,32 @@ describe('cmdTalk - nonce collision handling', () => {
853
843
  const ui = createMockUI();
854
844
 
855
845
  let captureCount = 0;
856
- const oldMarker = '{tmux-team-end:0000}'; // Old marker from previous request
846
+ const oldStartMarker = '{tmux-team-start:0000}';
847
+ const oldEndMarker = '{tmux-team-end:0000}'; // Old marker from previous request
857
848
 
858
849
  tmux.capture = () => {
859
850
  captureCount++;
851
+ // Scrollback includes OLD markers from a previous request
860
852
  if (captureCount === 1) {
861
- // Baseline includes an OLD marker
862
- return `Old response ${oldMarker}`;
853
+ return `${oldStartMarker}\nOld question\nOld response\n${oldEndMarker}`;
863
854
  }
864
- // New capture still has old marker but not new one yet
855
+ // New capture still has old markers but new request markers not complete yet
865
856
  if (captureCount === 2) {
866
- return `Old response ${oldMarker}\nNew question asked`;
857
+ const sent = tmux.sends[0]?.message || '';
858
+ const startMatch = sent.match(/\{tmux-team-start:([a-f0-9]+)\}/);
859
+ if (startMatch) {
860
+ return `${oldStartMarker}\nOld question\nOld response\n${oldEndMarker}\n\n{tmux-team-start:${startMatch[1]}}\nNew question asked`;
861
+ }
862
+ return `${oldStartMarker}\nOld question\nOld response\n${oldEndMarker}`;
867
863
  }
868
- // Finally, new marker appears
864
+ // Finally, new end marker appears
869
865
  const sent = tmux.sends[0]?.message || '';
870
- const match = sent.match(/\{tmux-team-end:([a-f0-9]+)\}/);
871
- if (match) {
872
- return `Old response ${oldMarker}\nNew question asked\nNew response {tmux-team-end:${match[1]}}`;
866
+ const startMatch = sent.match(/\{tmux-team-start:([a-f0-9]+)\}/);
867
+ const endMatch = sent.match(/\{tmux-team-end:([a-f0-9]+)\}/);
868
+ if (startMatch && endMatch) {
869
+ return `${oldStartMarker}\nOld question\nOld response\n${oldEndMarker}\n\n{tmux-team-start:${startMatch[1]}}\nNew question asked\n\nNew response\n\n{tmux-team-end:${endMatch[1]}}`;
873
870
  }
874
- return `Old response ${oldMarker}`;
871
+ return `${oldStartMarker}\nOld question\nOld response\n${oldEndMarker}`;
875
872
  };
876
873
 
877
874
  const ctx = createContext({
@@ -885,7 +882,6 @@ describe('cmdTalk - nonce collision handling', () => {
885
882
  pollInterval: 0.01,
886
883
  captureLines: 100,
887
884
  preambleEvery: 3,
888
- hideOrphanTasks: false,
889
885
  },
890
886
  },
891
887
  });
@@ -894,8 +890,10 @@ describe('cmdTalk - nonce collision handling', () => {
894
890
 
895
891
  const output = ui.jsonOutput[0] as Record<string, unknown>;
896
892
  expect(output.status).toBe('completed');
897
- // Response should be from after the new question, not triggered by old marker
893
+ // Response should be from after the new start marker, not triggered by old markers
898
894
  expect(output.response as string).not.toContain('Old response');
895
+ expect(output.response as string).not.toContain('Old question');
896
+ expect(output.response as string).toContain('New response');
899
897
  });
900
898
  });
901
899
 
@@ -916,13 +914,14 @@ describe('cmdTalk - JSON output contract', () => {
916
914
  const tmux = createMockTmux();
917
915
  const ui = createMockUI();
918
916
 
919
- let captureCount = 0;
920
917
  tmux.capture = () => {
921
- captureCount++;
922
- if (captureCount === 1) return '';
923
918
  const sent = tmux.sends[0]?.message || '';
924
- const match = sent.match(/\{tmux-team-end:([a-f0-9]+)\}/);
925
- return match ? `Response {tmux-team-end:${match[1]}}` : '';
919
+ const startMatch = sent.match(/\{tmux-team-start:([a-f0-9]+)\}/);
920
+ const endMatch = sent.match(/\{tmux-team-end:([a-f0-9]+)\}/);
921
+ if (startMatch && endMatch) {
922
+ return `{tmux-team-start:${startMatch[1]}}\nMessage\n\nResponse\n\n{tmux-team-end:${endMatch[1]}}`;
923
+ }
924
+ return '';
926
925
  };
927
926
 
928
927
  const ctx = createContext({
@@ -936,7 +935,6 @@ describe('cmdTalk - JSON output contract', () => {
936
935
  pollInterval: 0.01,
937
936
  captureLines: 100,
938
937
  preambleEvery: 3,
939
- hideOrphanTasks: false,
940
938
  },
941
939
  },
942
940
  });
@@ -949,7 +947,8 @@ describe('cmdTalk - JSON output contract', () => {
949
947
  expect(output).toHaveProperty('status', 'completed');
950
948
  expect(output).toHaveProperty('requestId');
951
949
  expect(output).toHaveProperty('nonce');
952
- expect(output).toHaveProperty('marker');
950
+ expect(output).toHaveProperty('startMarker');
951
+ expect(output).toHaveProperty('endMarker');
953
952
  expect(output).toHaveProperty('response');
954
953
  });
955
954
 
@@ -969,7 +968,6 @@ describe('cmdTalk - JSON output contract', () => {
969
968
  pollInterval: 0.01,
970
969
  captureLines: 100,
971
970
  preambleEvery: 3,
972
- hideOrphanTasks: false,
973
971
  },
974
972
  },
975
973
  });
@@ -987,6 +985,258 @@ describe('cmdTalk - JSON output contract', () => {
987
985
  expect(output).toHaveProperty('error');
988
986
  expect(output).toHaveProperty('requestId');
989
987
  expect(output).toHaveProperty('nonce');
990
- expect(output).toHaveProperty('marker');
988
+ expect(output).toHaveProperty('startMarker');
989
+ expect(output).toHaveProperty('endMarker');
990
+ });
991
+ });
992
+
993
+ // ─────────────────────────────────────────────────────────────
994
+ // Start/End Marker Tests - comprehensive coverage for the new marker system
995
+ // ─────────────────────────────────────────────────────────────
996
+
997
+ describe('cmdTalk - start/end marker extraction', () => {
998
+ let testDir: string;
999
+
1000
+ beforeEach(() => {
1001
+ testDir = fs.mkdtempSync(path.join(os.tmpdir(), 'talk-test-'));
1002
+ });
1003
+
1004
+ afterEach(() => {
1005
+ if (fs.existsSync(testDir)) {
1006
+ fs.rmSync(testDir, { recursive: true, force: true });
1007
+ }
1008
+ });
1009
+
1010
+ it('includes both start and end markers in sent message', async () => {
1011
+ const tmux = createMockTmux();
1012
+ const ui = createMockUI();
1013
+
1014
+ // Return markers immediately to complete
1015
+ tmux.capture = () => {
1016
+ const sent = tmux.sends[0]?.message || '';
1017
+ const startMatch = sent.match(/\{tmux-team-start:([a-f0-9]+)\}/);
1018
+ const endMatch = sent.match(/\{tmux-team-end:([a-f0-9]+)\}/);
1019
+ if (startMatch && endMatch) {
1020
+ return `${startMatch[0]}\nContent\nResponse\n${endMatch[0]}`;
1021
+ }
1022
+ return '';
1023
+ };
1024
+
1025
+ const ctx = createContext({
1026
+ tmux,
1027
+ ui,
1028
+ paths: createTestPaths(testDir),
1029
+ flags: { wait: true, json: true, timeout: 5 },
1030
+ config: { defaults: { timeout: 5, pollInterval: 0.01, captureLines: 100, preambleEvery: 3 } },
1031
+ });
1032
+
1033
+ await cmdTalk(ctx, 'claude', 'Test message');
1034
+
1035
+ const sent = tmux.sends[0].message;
1036
+ expect(sent).toMatch(/\{tmux-team-start:[a-f0-9]+\}/);
1037
+ expect(sent).toMatch(/\{tmux-team-end:[a-f0-9]+\}/);
1038
+
1039
+ // Both markers should have same nonce
1040
+ const startMatch = sent.match(/\{tmux-team-start:([a-f0-9]+)\}/);
1041
+ const endMatch = sent.match(/\{tmux-team-end:([a-f0-9]+)\}/);
1042
+ expect(startMatch?.[1]).toBe(endMatch?.[1]);
1043
+ });
1044
+
1045
+ it('extracts only content between start and end markers', async () => {
1046
+ const tmux = createMockTmux();
1047
+ const ui = createMockUI();
1048
+
1049
+ tmux.capture = () => {
1050
+ const sent = tmux.sends[0]?.message || '';
1051
+ const startMatch = sent.match(/\{tmux-team-start:([a-f0-9]+)\}/);
1052
+ const endMatch = sent.match(/\{tmux-team-end:([a-f0-9]+)\}/);
1053
+ if (startMatch && endMatch) {
1054
+ // Simulate scrollback with content before start marker, message, and response
1055
+ return `Old garbage\nMore old stuff\n{tmux-team-start:${startMatch[1]}}\nThe original message\n\nThis is the actual response\n\n{tmux-team-end:${endMatch[1]}}\nContent after marker`;
1056
+ }
1057
+ return 'Old garbage\nMore old stuff';
1058
+ };
1059
+
1060
+ const ctx = createContext({
1061
+ tmux,
1062
+ ui,
1063
+ paths: createTestPaths(testDir),
1064
+ flags: { wait: true, json: true, timeout: 5 },
1065
+ config: { defaults: { timeout: 5, pollInterval: 0.01, captureLines: 100, preambleEvery: 3 } },
1066
+ });
1067
+
1068
+ await cmdTalk(ctx, 'claude', 'Test');
1069
+
1070
+ const output = ui.jsonOutput[0] as Record<string, unknown>;
1071
+ expect(output.status).toBe('completed');
1072
+ expect(output.response).toContain('actual response');
1073
+ expect(output.response).not.toContain('Old garbage');
1074
+ expect(output.response).not.toContain('Content after marker');
1075
+ });
1076
+
1077
+ it('handles multiline responses correctly', async () => {
1078
+ const tmux = createMockTmux();
1079
+ const ui = createMockUI();
1080
+
1081
+ const multilineResponse = `Line 1 of response
1082
+ Line 2 of response
1083
+ Line 3 with special chars: <>&"'
1084
+ Line 4 final`;
1085
+
1086
+ tmux.capture = () => {
1087
+ const sent = tmux.sends[0]?.message || '';
1088
+ const startMatch = sent.match(/\{tmux-team-start:([a-f0-9]+)\}/);
1089
+ const endMatch = sent.match(/\{tmux-team-end:([a-f0-9]+)\}/);
1090
+ if (startMatch && endMatch) {
1091
+ return `{tmux-team-start:${startMatch[1]}}\nMessage\n\n${multilineResponse}\n\n{tmux-team-end:${endMatch[1]}}`;
1092
+ }
1093
+ return '';
1094
+ };
1095
+
1096
+ const ctx = createContext({
1097
+ tmux,
1098
+ ui,
1099
+ paths: createTestPaths(testDir),
1100
+ flags: { wait: true, json: true, timeout: 5 },
1101
+ config: { defaults: { timeout: 5, pollInterval: 0.01, captureLines: 100, preambleEvery: 3 } },
1102
+ });
1103
+
1104
+ await cmdTalk(ctx, 'claude', 'Test');
1105
+
1106
+ const output = ui.jsonOutput[0] as Record<string, unknown>;
1107
+ expect(output.response).toContain('Line 1 of response');
1108
+ expect(output.response).toContain('Line 4 final');
1109
+ });
1110
+
1111
+ it('handles empty response between markers', async () => {
1112
+ const tmux = createMockTmux();
1113
+ const ui = createMockUI();
1114
+
1115
+ tmux.capture = () => {
1116
+ const sent = tmux.sends[0]?.message || '';
1117
+ const startMatch = sent.match(/\{tmux-team-start:([a-f0-9]+)\}/);
1118
+ const endMatch = sent.match(/\{tmux-team-end:([a-f0-9]+)\}/);
1119
+ if (startMatch && endMatch) {
1120
+ // Just markers with message, agent printed end marker immediately
1121
+ return `{tmux-team-start:${startMatch[1]}}\nMessage here\n{tmux-team-end:${endMatch[1]}}`;
1122
+ }
1123
+ return '';
1124
+ };
1125
+
1126
+ const ctx = createContext({
1127
+ tmux,
1128
+ ui,
1129
+ paths: createTestPaths(testDir),
1130
+ flags: { wait: true, json: true, timeout: 5 },
1131
+ config: { defaults: { timeout: 5, pollInterval: 0.01, captureLines: 100, preambleEvery: 3 } },
1132
+ });
1133
+
1134
+ await cmdTalk(ctx, 'claude', 'Test');
1135
+
1136
+ const output = ui.jsonOutput[0] as Record<string, unknown>;
1137
+ expect(output.status).toBe('completed');
1138
+ // Response should be the message content (trimmed)
1139
+ expect(typeof output.response).toBe('string');
1140
+ });
1141
+
1142
+ it('correctly handles start marker on same line as content', async () => {
1143
+ const tmux = createMockTmux();
1144
+ const ui = createMockUI();
1145
+
1146
+ tmux.capture = () => {
1147
+ const sent = tmux.sends[0]?.message || '';
1148
+ const startMatch = sent.match(/\{tmux-team-start:([a-f0-9]+)\}/);
1149
+ const endMatch = sent.match(/\{tmux-team-end:([a-f0-9]+)\}/);
1150
+ if (startMatch && endMatch) {
1151
+ // Start marker followed by newline, then content
1152
+ return `Old stuff\n{tmux-team-start:${startMatch[1]}}\nActual response content\n{tmux-team-end:${endMatch[1]}}`;
1153
+ }
1154
+ return 'Old stuff';
1155
+ };
1156
+
1157
+ const ctx = createContext({
1158
+ tmux,
1159
+ ui,
1160
+ paths: createTestPaths(testDir),
1161
+ flags: { wait: true, json: true, timeout: 5 },
1162
+ config: { defaults: { timeout: 5, pollInterval: 0.01, captureLines: 100, preambleEvery: 3 } },
1163
+ });
1164
+
1165
+ await cmdTalk(ctx, 'claude', 'Test');
1166
+
1167
+ const output = ui.jsonOutput[0] as Record<string, unknown>;
1168
+ expect(output.response).not.toContain('Old stuff');
1169
+ expect(output.response).toContain('Actual response content');
1170
+ });
1171
+
1172
+ it('uses lastIndexOf for start marker to handle multiple occurrences', async () => {
1173
+ const tmux = createMockTmux();
1174
+ const ui = createMockUI();
1175
+
1176
+ let captureCount = 0;
1177
+ tmux.capture = () => {
1178
+ captureCount++;
1179
+ const sent = tmux.sends[0]?.message || '';
1180
+ const startMatch = sent.match(/\{tmux-team-start:([a-f0-9]+)\}/);
1181
+ const endMatch = sent.match(/\{tmux-team-end:([a-f0-9]+)\}/);
1182
+ if (startMatch && endMatch) {
1183
+ if (captureCount < 3) {
1184
+ // First few captures: old markers in history, new start marker sent but not end yet
1185
+ return `{tmux-team-start:old1}\nOld message\nOld response\n{tmux-team-end:old1}\n\n{tmux-team-start:${startMatch[1]}}\nNew message pending`;
1186
+ }
1187
+ // Finally, new end marker appears
1188
+ return `{tmux-team-start:old1}\nOld message\nOld response\n{tmux-team-end:old1}\n\n{tmux-team-start:${startMatch[1]}}\nNew message\n\nNew actual response\n\n{tmux-team-end:${endMatch[1]}}`;
1189
+ }
1190
+ return '';
1191
+ };
1192
+
1193
+ const ctx = createContext({
1194
+ tmux,
1195
+ ui,
1196
+ paths: createTestPaths(testDir),
1197
+ flags: { wait: true, json: true, timeout: 5 },
1198
+ config: { defaults: { timeout: 5, pollInterval: 0.01, captureLines: 100, preambleEvery: 3 } },
1199
+ });
1200
+
1201
+ await cmdTalk(ctx, 'claude', 'Test');
1202
+
1203
+ const output = ui.jsonOutput[0] as Record<string, unknown>;
1204
+ expect(output.status).toBe('completed');
1205
+ // Should get response from the NEW start marker, not the old one
1206
+ expect(output.response).toContain('New actual response');
1207
+ expect(output.response).not.toContain('Old response');
1208
+ });
1209
+
1210
+ it('handles large scrollback with markers at edges', async () => {
1211
+ const tmux = createMockTmux();
1212
+ const ui = createMockUI();
1213
+
1214
+ // Simulate 100+ lines of scrollback
1215
+ const lotsOfContent = Array.from({ length: 150 }, (_, i) => `Line ${i}`).join('\n');
1216
+
1217
+ tmux.capture = () => {
1218
+ const sent = tmux.sends[0]?.message || '';
1219
+ const startMatch = sent.match(/\{tmux-team-start:([a-f0-9]+)\}/);
1220
+ const endMatch = sent.match(/\{tmux-team-end:([a-f0-9]+)\}/);
1221
+ if (startMatch && endMatch) {
1222
+ return `${lotsOfContent}\n{tmux-team-start:${startMatch[1]}}\nMessage\n\nThe actual response\n\n{tmux-team-end:${endMatch[1]}}`;
1223
+ }
1224
+ return lotsOfContent;
1225
+ };
1226
+
1227
+ const ctx = createContext({
1228
+ tmux,
1229
+ ui,
1230
+ paths: createTestPaths(testDir),
1231
+ flags: { wait: true, json: true, timeout: 5 },
1232
+ config: { defaults: { timeout: 5, pollInterval: 0.01, captureLines: 200, preambleEvery: 3 } },
1233
+ });
1234
+
1235
+ await cmdTalk(ctx, 'claude', 'Test');
1236
+
1237
+ const output = ui.jsonOutput[0] as Record<string, unknown>;
1238
+ expect(output.status).toBe('completed');
1239
+ expect(output.response).toContain('actual response');
1240
+ expect(output.response).not.toContain('Line 0');
991
1241
  });
992
1242
  });