/**
 * @module sync-conflict-text-merge.respec
 *
 * Verifies text merge (LCS algorithm) in SyncSagaCoordinator.
 *
 * Tests ibgib.data.text conflicts with various text patterns, which with
 * optimistic merging. This should trigger the automatic text merging which is
 * different than the replay of dna for other types of conflict grafts.
 */
import { respecfully, ifWe, iReckon } from '@ibgib/helper-gib/dist/respec-gib/respec-gib.mjs';
const maam = `[${import.meta.url}]`, sir = maam;
import { clone, delay, extractErrorMsg } from '@ibgib/helper-gib/dist/helpers/utils-helper.mjs';
import { GLOBAL_LOG_A_LOT } from '../core-constants.mjs';
import { TestTransformer, } from '../test-helpers.mjs';
import { SyncSagaCoordinator } from './sync-saga-coordinator.mjs';
import { getFromSpace } from '../witness/space/space-helper.mjs';
import { Metaspace_Innerspace } from '../witness/space/metaspace/metaspace-innerspace/metaspace-innerspace.mjs';
import { InnerSpace_V1 } from '../witness/space/inner-space/inner-space-v1.mjs';
import { SyncPeerInnerspace_V1 } from './sync-peer/sync-peer-innerspace/sync-peer-innerspace-v1.mjs';
import { DEFAULT_INNER_SPACE_DATA_V1 } from '../witness/space/inner-space/inner-space-types.mjs';
import { getIbGibsFromCache_fallbackToSpaces, getTjpAddr, } from '../common/other/ibgib-helper.mjs';
import { getDependencyGraph, graphsAreEquivalent } from '../common/other/graph-helper.mjs';
import { SYNC_PEER_INNERSPACE_DEFAULT_DATA_V1 } from './sync-peer/sync-peer-innerspace/sync-peer-innerspace-constants.mjs';
import { SyncConflictStrategy } from './sync-constants.mjs';
const logalot = GLOBAL_LOG_A_LOT;
const lc = sir;
await respecfully(sir, `Text merge (LCS) conflict resolution`, async () => {
    // #region Init/Setup
    const metaspace = new Metaspace_Innerspace(undefined);
    await metaspace.initialize({
        getFnAlert: () => async ({ title, msg }) => { console.log(`[Alert] ${title}: ${msg}`); },
        getFnPrompt: () => async ({ title, msg }) => { console.log(`[Prompt] ${title}: ${msg}`); return ''; },
        getFnPromptPassword: () => async (title, msg) => { console.log(`[PromptPwd] ${title}: ${msg}`); return null; },
    });
    while (!metaspace.initialized) {
        await delay(10);
    }
    const defaultLocalUserSpace = await metaspace.getLocalUserSpace({ lock: false });
    await defaultLocalUserSpace.initialized;
    const sourceSpace = new InnerSpace_V1({
        ...DEFAULT_INNER_SPACE_DATA_V1,
        name: 'source',
        uuid: 'source_uuid',
        description: 'source test space',
    });
    await sourceSpace.initialized;
    const destSpace = new InnerSpace_V1({
        ...DEFAULT_INNER_SPACE_DATA_V1,
        name: 'dest',
        uuid: 'dest_uuid',
        description: 'dest test space',
    });
    await destSpace.initialized;
    const testTransformer = new TestTransformer(metaspace, sourceSpace, destSpace);
    if (logalot) {
        console.log(`${lc} Setting up Coordinators...`);
    }
    const senderCoordinator = new SyncSagaCoordinator();
    const receiverCoordinator = new SyncSagaCoordinator();
    async function newTestPeer() {
        const peer = new SyncPeerInnerspace_V1(clone(SYNC_PEER_INNERSPACE_DEFAULT_DATA_V1));
        await peer.initialized;
        await peer.initializeOpts({
            localMetaspace: metaspace,
            localSpace: sourceSpace,
            receiverSpace: destSpace,
            receiverCoordinator: receiverCoordinator,
            receiverMetaspace: metaspace,
        });
        return peer;
    }
    // #endregion Init/Setup
    // #region Round 1: Seed common history & initial text
    const _r1 = testTransformer.newRound({
        name: 'r1_seed_common_text',
        description: 'Create timeline with initial text, sync to establish common history'
    });
    if (logalot) {
        console.log(`${lc} R1: Creating initial alpha with text...`);
    }
    // Create alpha with initial text on source
    const INITIAL_TEXT = "This is the initial quiz question.\nIt has multiple lines.\nStudents will answer this.";
    const r1_alpha_v0_source = await testTransformer.create({
        atom: 'alpha',
        in: 'source',
        data: { text: INITIAL_TEXT },
        name: 'r1_alpha_v0_source'
    });
    const alpha_tjpAddr = getTjpAddr({ ibGib: r1_alpha_v0_source.ibGib, defaultIfNone: 'incomingAddr' });
    if (logalot) {
        console.log(`${lc} R1: Syncing initial alpha to dest...`);
    }
    let r1_syncSaga;
    try {
        r1_syncSaga = await senderCoordinator.sync({
            peer: await newTestPeer(),
            localSpace: sourceSpace,
            metaspace,
            domainIbGibs: [r1_alpha_v0_source.ibGib],
            conflictStrategy: SyncConflictStrategy.optimisticWithLCS,
        });
        await r1_syncSaga.done;
        if (logalot) {
            console.log(`${lc} R1 Sync Complete.`);
        }
    }
    catch (e) {
        console.error(`${lc} R1 Sync Failed:`, e);
        iReckon(sir, false).asTo(`R1 Sync failed: ${e}`).isGonnaBeTruthy();
        return;
    }
    // Verify both sides have same text
    await respecfully(sir, `r1 verify post`, async () => {
        try {
            const r1_alpha_sourceKV = await senderCoordinator.getKnowledgeMap({
                space: sourceSpace,
                metaspace,
                domainIbGibs: [r1_alpha_v0_source.ibGib]
            });
            const r1_alpha_source_tipAddr = r1_alpha_sourceKV[alpha_tjpAddr];
            if (!r1_alpha_source_tipAddr) {
                await ifWe(sir, 'r1_alpha_source_tipAddr is falsy?', async () => {
                    iReckon(sir, true).asTo('fail').isGonnaBeFalse();
                });
                return; /* <<<< returns early */
            }
            const r1_alpha_destKV = await senderCoordinator.getKnowledgeMap({
                space: destSpace,
                metaspace,
                domainIbGibs: [r1_alpha_v0_source.ibGib]
            });
            const r1_alpha_dest_tipAddr = r1_alpha_destKV[alpha_tjpAddr];
            if (!r1_alpha_dest_tipAddr) {
                await ifWe(sir, 'r1_alpha_dest_tipAddr is falsy?', async () => {
                    iReckon(sir, true).asTo('fail').isGonnaBeFalse();
                });
                return; /* <<<< returns early */
            }
            await ifWe(sir, 'r1 tip addrs match', async () => {
                iReckon(sir, r1_alpha_source_tipAddr).asTo('R1 source/dest have same tip').isGonnaBe(r1_alpha_dest_tipAddr);
            });
            await ifWe(sir, 'r1 text synced correctly', async () => {
                if (!r1_alpha_dest_tipAddr) {
                    throw new Error(`r1_dest_tipAddr is null/undefined (E: 1a2b3c4d5e6f7a8b9c0d1e2f3a4b5c6d)`);
                }
                const resGet_destTip = await getFromSpace({ space: destSpace, addr: r1_alpha_dest_tipAddr });
                const destTipIbGib = resGet_destTip.ibGibs[0];
                iReckon(sir, destTipIbGib.data.text).asTo('Dest has initial text').isGonnaBe(INITIAL_TEXT);
            });
            await ifWe(sir, 'r1 dep graphs synced', async () => {
                const [r1_alpha_source_tip] = await getIbGibsFromCache_fallbackToSpaces({
                    addrs: [r1_alpha_source_tipAddr],
                    space: sourceSpace,
                });
                const [r1_alpha_dest_tip] = await getIbGibsFromCache_fallbackToSpaces({
                    addrs: [r1_alpha_dest_tipAddr],
                    space: destSpace,
                });
                iReckon(sir, r1_alpha_dest_tip).asTo('alpha tip exists in dest').isGonnaBeTruthy();
                if (r1_alpha_dest_tip) {
                    const r1_alpha_source_depGraph = await getDependencyGraph({
                        ibGib: r1_alpha_source_tip,
                        live: true,
                        space: sourceSpace
                    });
                    const r1_alpha_dest_depGraph = await getDependencyGraph({
                        ibGib: r1_alpha_dest_tip,
                        live: true,
                        space: destSpace
                    });
                    const graphsEqual = graphsAreEquivalent({
                        graphA: r1_alpha_source_depGraph,
                        graphB: r1_alpha_dest_depGraph,
                        slowButThorough: true,
                    });
                    iReckon(sir, graphsEqual).asTo('R1 dep graphs equal').isGonnaBeTrue();
                }
            });
        }
        catch (error) {
            console.error(`${lc} ${extractErrorMsg(error)}`);
            iReckon(sir, true).asTo('R1 verify errored').isGonnaBeFalse();
        }
    });
    // #endregion Round 1: Seed common history & initial text
    // #region Round 2: Simple append - different parts of text
    const _r2 = testTransformer.newRound({
        name: 'r2_simple_append',
        description: 'Source appends to end, dest appends to beginning - should merge both'
    });
    // #region r2 source edits
    if (logalot) {
        console.log(`${lc} R2: Source appending to end of text...`);
    }
    // const resGet_r2_source = await getFromSpace({ space: sourceSpace, addr: alpha_tjpAddr });
    // const r2_v0_graft = resGet_r2_source.ibGibs![0] as IbGib_V1<TestData>;
    const SOURCE_APPEND = "\nInstructor added hint.";
    const r2_alpha_v1_source_appendedText = await testTransformer.mut8({
        ibGib: r1_alpha_v0_source.ibGib,
        in: 'source',
        strField: { name: 'text', value: INITIAL_TEXT + SOURCE_APPEND },
        name: 'r2_alpha_v1_source_appendedText',
    });
    // #endregion r2 source edits
    // #region r2 dest edits
    if (logalot) {
        console.log(`${lc} R2: Dest prepending to beginning of text...`);
    }
    const resGet_r2_dest = await getFromSpace({ space: destSpace, addr: r1_alpha_v0_source.addr });
    const r2_v0_alpha_dest = resGet_r2_dest.ibGibs[0];
    const DEST_PREPEND = "Student note: Confusing!\n";
    const r2_alpha_v1_dest_prependedText = await testTransformer.mut8({
        ibGib: r2_v0_alpha_dest,
        in: 'dest',
        strField: { name: 'text', value: DEST_PREPEND + INITIAL_TEXT },
        name: 'r2_alpha_v1_dest_prependedText',
    });
    // #endregion r2 dest edits
    await respecfully(sir, `r2 verify pre`, async () => {
        await ifWe(sir, 'texts as expected', async () => {
            // before the sync, each side only has their edit. after the sync,
            // both sides should have both prepended and appended text
            iReckon(sir, r2_alpha_v1_source_appendedText.ibGib.data?.text.includes(INITIAL_TEXT)).asTo('alpha source has initial text').isGonnaBeTrue();
            iReckon(sir, r2_alpha_v1_source_appendedText.ibGib.data?.text.includes(SOURCE_APPEND)).asTo('alpha source has appended text').isGonnaBeTrue();
            iReckon(sir, r2_alpha_v1_source_appendedText.ibGib.data?.text.includes(DEST_PREPEND)).asTo('alpha source does NOT have prepended text').isGonnaBeFalse();
            iReckon(sir, r2_alpha_v1_dest_prependedText.ibGib.data?.text.includes(INITIAL_TEXT)).asTo('alpha dest has initial text').isGonnaBeTrue();
            iReckon(sir, r2_alpha_v1_dest_prependedText.ibGib.data?.text.includes(SOURCE_APPEND)).asTo('alpha dest does NOT have appended text').isGonnaBeFalse();
            iReckon(sir, r2_alpha_v1_dest_prependedText.ibGib.data?.text.includes(DEST_PREPEND)).asTo('alpha dest has prepended text').isGonnaBeTrue();
        });
    });
    if (logalot) {
        console.log(`${lc} Running r2 Sync (simple data.text conflict)...`);
    }
    let r2_syncSaga;
    try {
        r2_syncSaga = await senderCoordinator.sync({
            peer: await newTestPeer(),
            localSpace: sourceSpace,
            metaspace,
            domainIbGibs: [r2_alpha_v1_source_appendedText.ibGib],
            conflictStrategy: SyncConflictStrategy.optimisticWithLCS,
        });
        await r2_syncSaga.done;
    }
    catch (e) {
        console.error(`${lc} R2 Sync Failed:`, e);
        iReckon(sir, false).asTo(`R2 failed: ${e}`).isGonnaBeTruthy();
        return;
    }
    await respecfully(sir, `r2 verify post`, async () => {
        const kv_source = await senderCoordinator.getKnowledgeMap({ space: sourceSpace, metaspace, domainIbGibs: [r1_alpha_v0_source.ibGib] });
        const kv_dest = await senderCoordinator.getKnowledgeMap({ space: destSpace, metaspace, domainIbGibs: [r1_alpha_v0_source.ibGib] });
        const r2_alpha_source_tipAddr = kv_source[alpha_tjpAddr];
        if (!r2_alpha_source_tipAddr) {
            await ifWe(sir, 'r2_alpha_source_tipAddr falsy?', async () => {
                iReckon(sir, true).asTo('fails').isGonnaBe(false);
            });
            return; /* <<<< returns early */
        }
        const r2_alpha_dest_tipAddr = kv_dest[alpha_tjpAddr];
        if (!r2_alpha_dest_tipAddr) {
            await ifWe(sir, 'r2_alpha_dest_tipAddr falsy?', async () => {
                iReckon(sir, true).asTo('fails').isGonnaBe(false);
            });
            return; /* <<<< returns early */
        }
        const [r2_alpha_source_tip] = await getIbGibsFromCache_fallbackToSpaces({
            addrs: [r2_alpha_source_tipAddr],
            space: sourceSpace,
        });
        const [r2_alpha_dest_tip] = await getIbGibsFromCache_fallbackToSpaces({
            addrs: [r2_alpha_dest_tipAddr],
            space: sourceSpace,
        });
        await ifWe(sir, 'r2 tip addrs match', async () => {
            iReckon(sir, r2_alpha_source_tipAddr).asTo('alpha').isGonnaBe(r2_alpha_dest_tipAddr);
        });
        await ifWe(sir, 'r2 text merged correctly', async () => {
            // before the sync, each side only has their edit. after the sync,
            // both sides should have both prepended and appended text
            iReckon(sir, r2_alpha_v1_source_appendedText.ibGib.data?.text.includes(INITIAL_TEXT)).asTo('alpha source has initial text').isGonnaBeTrue();
            iReckon(sir, r2_alpha_v1_source_appendedText.ibGib.data?.text.includes(SOURCE_APPEND)).asTo('alpha source has appended text').isGonnaBeTrue();
            iReckon(sir, r2_alpha_v1_source_appendedText.ibGib.data?.text.includes(DEST_PREPEND)).asTo('alpha source has prepended text').isGonnaBeFalse();
            iReckon(sir, r2_alpha_v1_dest_prependedText.ibGib.data?.text.includes(INITIAL_TEXT)).asTo('alpha dest has initial text').isGonnaBeTrue();
            iReckon(sir, r2_alpha_v1_dest_prependedText.ibGib.data?.text.includes(SOURCE_APPEND)).asTo('alpha dest has appended text').isGonnaBeFalse();
            iReckon(sir, r2_alpha_v1_dest_prependedText.ibGib.data?.text.includes(DEST_PREPEND)).asTo('alpha dest has prepended text').isGonnaBeTrue();
            // actually both should be the same text now of course
            iReckon(sir, r2_alpha_source_tip.data?.text).asTo('source/dest same text').isGonnaBe(r2_alpha_dest_tip.data?.text);
            const text = r2_alpha_source_tip.data?.text;
            // we'll go one step further and assume the final output is exactly this
            iReckon(sir, text).asTo('R2 has both prepend and append').isGonnaBe(DEST_PREPEND + INITIAL_TEXT + SOURCE_APPEND);
        });
        await ifWe(sir, 'r2 dep graphs synced', async () => {
            // alpha's full dep graph should exist on dest
            const depGraph_alpha_source = await getDependencyGraph({
                ibGib: r2_alpha_source_tip,
                live: true,
                space: sourceSpace
            });
            const depGraph_alpha_dest = await getDependencyGraph({
                ibGib: r2_alpha_dest_tip,
                live: true,
                space: destSpace
            });
            const alphaDepsAreEqual = graphsAreEquivalent({
                graphA: depGraph_alpha_source,
                graphB: depGraph_alpha_dest,
                slowButThorough: true,
            });
            iReckon(sir, alphaDepsAreEqual).asTo('alpha got synced and graphs are equal').isGonnaBeTrue();
        });
    });
    // #endregion Round 2: Simple append - different parts of text
    // #region Round 3: Interleaved edits - different paragraphs
    // const _r3 = testTransformer.newRound({
    //     name: 'r3_interleaved_paragraphs',
    //     description: 'Source edits paragraph 1, dest edits paragraph 2 - should merge both changes'
    // });
    // // #region r3 source edits
    // if (logalot) { console.log(`${lc} R3: Source editing first paragraph...`); }
    // const resGet_r3_source = await getFromSpace({ space: sourceSpace, addr: alpha_tjpAddr });
    // const r3_v0_graft = resGet_r3_source.ibGibs![0] as IbGib_V1<TestData>;
    // const r3_currentText = r3_v0_graft.data!.text!;
    // // Split into lines, modify first paragraph (line 1)
    // const lines = r3_currentText.split('\n');
    // lines[0] = "This is the UPDATED quiz question."; // Source edits line 1
    // const r3_sourceModifiedText = lines.join('\n');
    // const r3_v1_source = await testTransformer.mut8({
    //     ibGib: r3_v0_graft,
    //     in: 'source',
    //     strField: { name: 'text', value: r3_sourceModifiedText },
    //     name: 'r3_v1_source',
    // });
    // // #endregion r3 source edits
    // // #region r3 dest edits
    // if (logalot) { console.log(`${lc} R3: Dest editing second paragraph...`); }
    // const resGet_r3_dest = await getFromSpace({ space: destSpace, addr: alpha_tjpAddr });
    // const r3_v0_graft_fromDest = resGet_r3_dest.ibGibs![0] as IbGib_V1<TestData>;
    // // Split and modify third line
    // const destLines = r3_v0_graft_fromDest.data!.text!.split('\n');
    // destLines[2] = "Students will DEFINITELY answer this."; // Dest edits line 3
    // const r3_destModifiedText = destLines.join('\n');
    // const r3_v1_dest = await testTransformer.mut8({
    //     ibGib: r3_v0_graft_fromDest,
    //     in: 'dest',
    //     strField: { name: 'text', value: r3_destModifiedText },
    //     name: 'r3_v1_dest',
    // });
    // // #endregion r3 dest edits
    // await respecfully(sir, `r3 verify pre`, async () => {
    //     await ifWe(sir, 'dest has alpha after R2 graft', async () => {
    //         const kv = await receiverCoordinator.getKnowledgeMap({ space: destSpace, metaspace, domainIbGibs: [r3_v0_graft_fromDest] });
    //         iReckon(sir, !!kv[alpha_tjpAddr]).asTo('dest has tip').isGonnaBeTrue();
    //     });
    // });
    // if (logalot) { console.log(`${lc} Running r3 Sync (interleaved paragraphs)...`); }
    // let r3_syncSaga: SyncSagaInfo | undefined;
    // try {
    //     r3_syncSaga = await senderCoordinator.sync({
    //         peer: await newTestPeer(),
    //         localSpace: sourceSpace,
    //         metaspace,
    //         domainIbGibs: [r3_v1_source.ibGib],
    //         conflictStrategy: SyncConflictStrategy.optimisticWithLCS,
    //     });
    //     await r3_syncSaga.done;
    // } catch (e) {
    //     console.error(`${lc} R3 Sync Failed:`, e);
    //     iReckon(sir, false).asTo(`R3 failed: ${e}`).isGonnaBeTruthy();
    //     return;
    // }
    // await respecfully(sir, `r3 verify post`, async () => {
    //     const kv_s = await senderCoordinator.getKnowledgeMap({ space: sourceSpace, metaspace, domainIbGibs: [r1_alpha_v0_source.ibGib] });
    //     const kv_d = await senderCoordinator.getKnowledgeMap({ space: destSpace, metaspace, domainIbGibs: [r1_alpha_v0_source.ibGib] });
    //     const r3_tip_s = kv_s[alpha_tjpAddr];
    //     const r3_tip_d = kv_d[alpha_tjpAddr];
    //     await ifWe(sir, 'r3 tip addrs match', async () => {
    //         iReckon(sir, r3_tip_s).asTo('R3 tips match').isGonnaBe(r3_tip_d);
    //     });
    //     await ifWe(sir, 'r3 both paragraph edits merged', async () => {
    //         const res = await getFromSpace({ space: sourceSpace, addr: r3_tip_s! });
    //         const tip = res.ibGibs![0] as IbGib_V1<TestData>;
    //         const mergedText = tip.data!.text!;
    //         // Should have BOTH source's line 1 change AND dest's line 3 change
    //         iReckon(sir, mergedText.includes("UPDATED quiz question"))
    //             .asTo('has source paragraph 1 edit')
    //             .isGonnaBeTrue();
    //         iReckon(sir, mergedText.includes("DEFINITELY answer this"))
    //             .asTo('has dest paragraph 2 edit')
    //             .isGonnaBeTrue();
    //         // Verify middle line unchanged
    //         iReckon(sir, mergedText.includes("It has multiple lines"))
    //             .asTo('middle line preserved')
    //             .isGonnaBeTrue();
    //     });
    //     await ifWe(sir, 'r3 dep graphs synced', async () => {
    //         const [d] = await getIbGibsFromCache_fallbackToSpaces({ addrs: [r3_tip_s!], space: destSpace });
    //         iReckon(sir, d).asTo('exists dest').isGonnaBeTruthy();
    //     });
    // });
    // #endregion Round 3: Interleaved edits - different paragraphs
    // #region Round 4: Same paragraph conflict
    // const _r4 = testTransformer.newRound({
    //     name: 'r4_same_paragraph_conflict',
    //     description: 'Both edit same paragraph - LCS should merge at word/character level'
    // });
    // // #region r4 source edits
    // if (logalot) { console.log(`${lc} R4: Source editing same paragraph...`); }
    // // TODO: Retrieve from source
    // // TODO: Mutate - edit specific words in paragraph
    // // #endregion r4 source edits
    // // #region r4 dest edits
    // if (logalot) { console.log(`${lc} R4: Dest editing same paragraph (different words)...`); }
    // // TODO: Retrieve from dest
    // // TODO: Mutate - edit different words in same paragraph
    // // #endregion r4 dest edits
    // await respecfully(sir, `r4 verify pre`, async () => {
    //     await ifWe(sir, 'dest has alpha after R3 graft', async () => {
    //         // TODO: Verify pre-sync state
    //     });
    // });
    // if (logalot) { console.log(`${lc} Running r4 Sync (same paragraph conflict)...`); }
    // // TODO: Add sync operation
    // await respecfully(sir, `r4 verify post`, async () => {
    //     await ifWe(sir, 'r4 tip addrs match', async () => {
    //         // TODO: Verify tips match
    //     });
    //     await ifWe(sir, 'r4 LCS merged both word changes', async () => {
    //         // TODO: Verify text has both source and dest word changes
    //         // TODO: Verify LCS algorithm preserved both edits correctly
    //     });
    //     await ifWe(sir, 'r4 dep graphs synced', async () => {
    //         // TODO: Verify dep graphs
    //     });
    // });
    // #endregion Round 4: Same paragraph conflict
    // #region Round 5: Multi-field text merge
    // const _r5 = testTransformer.newRound({
    //     name: 'r5_multi_field_text',
    //     description: 'Conflicting text edits in BOTH text and description fields simultaneously'
    // });
    // // #region r5 source edits
    // if (logalot) { console.log(`${lc} R5: Source editing both text and description...`); }
    // // TODO: Retrieve from source
    // // TODO: Mutate text field
    // // TODO: Mutate description field (in same mut8 or separate)
    // // #endregion r5 source edits
    // // #region r5 dest edits
    // if (logalot) { console.log(`${lc} R5: Dest editing both text and description differently...`); }
    // // TODO: Retrieve from dest
    // // TODO: Mutate text field (different changes)
    // // TODO: Mutate description field (different changes)
    // // #endregion r5 dest edits
    // await respecfully(sir, `r5 verify pre`, async () => {
    //     await ifWe(sir, 'dest has alpha after R4 graft', async () => {
    //         // TODO: Verify pre-sync state
    //     });
    // });
    // if (logalot) { console.log(`${lc} Running r5 Sync (multi-field text merge)...`); }
    // // TODO: Add sync operation
    // await respecfully(sir, `r5 verify post`, async () => {
    //     await ifWe(sir, 'r5 tip addrs match', async () => {
    //         // TODO: Verify tips match
    //     });
    //     await ifWe(sir, 'r5 text field merged', async () => {
    //         // TODO: Verify text field has both source and dest changes
    //     });
    //     await ifWe(sir, 'r5 description field merged', async () => {
    //         // TODO: Verify description field has both source and dest changes
    //     });
    //     await ifWe(sir, 'r5 both fields independently LCS-merged', async () => {
    //         // TODO: Verify each field was merged independently
    //         // TODO: Ensure one field's merge didn't affect the other
    //     });
    //     await ifWe(sir, 'r5 dep graphs synced', async () => {
    //         // TODO: Verify dep graphs
    //     });
    // });
    // #endregion Round 5: Multi-field text merge
});
//# sourceMappingURL=sync-conflict-text-merge.respec.mjs.map