<html><head><base href="https://websim.ai/html-merger/"><title>HTML Merger Tool: Interactive Visual Merger</title><style>

    body {

        font-family: 'Roboto', sans-serif;

        background: #f5e6d3; /* Creme background */

        color: #ff4136; /* Red text */

        margin: 0;

        padding: 20px;

        display: flex;

        justify-content: center;

        align-items: center;

        min-height: 100vh;

    }


    .container {

        background: #ffffff; /* White container background */

        border-radius: 10px;

        padding: 30px;

        box-shadow: 0 8px 32px 0 rgba(0, 0, 0, 0.1);

        border: 1px solid #add8e6; /* Light blue border */

        width: 90%;

        max-width: 1200px;

    }


    h1, h2 {

        text-align: center;

        color: #ff4136; /* Red header */

        margin-bottom: 20px;

        text-shadow: 1px 1px 2px rgba(0, 0, 0, 0.1);

    }


    h1 {

        font-size: 2.5em;

    }


    h2 {

        font-size: 1.8em;

    }


    .code-container {

        display: flex;

        gap: 20px;

        margin-bottom: 20px;

    }


    .code-area {

        flex: 1;

    }


    textarea {

        width: 100%;

        height: 300px;

        background: #f0f8ff; /* Light blue background for textareas */

        border: 1px solid #add8e6; /* Light blue border */

        border-radius: 5px;

        padding: 10px;

        color: #333; /* Dark gray text for better readability */

        font-family: 'Fira Code', monospace;

        resize: vertical;

        font-size: 14px;

    }


    button {

        display: block;

        width: 200px;

        margin: 20px auto;

        padding: 10px;

        background: #ff4136; /* Red button */

        color: #fff;

        border: none;

        border-radius: 5px;

        font-size: 1em;

        cursor: pointer;

        transition: background 0.3s ease, transform 0.1s ease;

    }


    button:hover {

        background: #ff725c; /* Lighter red on hover */

        transform: translateY(-2px);

    }


    button:active {

        transform: translateY(1px);

    }


    #mergedHTML {

        width: 100%;

        height: 300px;

        background: #f0f8ff; /* Light blue background */

        border: 1px solid #add8e6; /* Light blue border */

        border-radius: 5px;

        padding: 10px;

        color: #333; /* Dark gray text */

        font-family: 'Fira Code', monospace;

        margin-top: 20px;

        font-size: 14px;

    }


    #visualMerger {

        display: flex;

        justify-content: space-between;

        margin-top: 20px;

    }


    .visual-area {

        width: 48%;

        border: 1px solid #add8e6;

        border-radius: 5px;

        padding: 10px;

        background: #f0f8ff;

    }


    .highlight-add {

        background-color: #ccffcc;

    }


    .highlight-remove {

        background-color: #ffcccc;

        text-decoration: line-through;

    }


    .highlight-change {

        background-color: #ffffcc;

    }

</style></head><body>

    <div class="container">

        <h1>HTML Merger Tool: Interactive Visual Merger</h1>

        <div class="code-container">

            <div class="code-area">

                <h2>Original HTML</h2>

                <textarea id="oldHTML" placeholder="Paste the original HTML here..."></textarea>

            </div>

            <div class="code-area">

                <h2>New HTML</h2>

                <textarea id="newHTML" placeholder="Paste the new HTML here..."></textarea>

            </div>

        </div>

        <button id="mergeButton">Merge HTML</button>

        <h2>Merged HTML</h2>

        <textarea id="mergedHTML" readonly></textarea>

        <div id="visualMerger">

            <div class="visual-area" id="visualOld">

                <h3>Original HTML Structure</h3>

            </div>

            <div class="visual-area" id="visualNew">

                <h3>New HTML Structure</h3>

            </div>

        </div>

    </div>


    <script>

        const oldHTMLArea = document.getElementById('oldHTML');

        const newHTMLArea = document.getElementById('newHTML');

        const mergedHTMLArea = document.getElementById('mergedHTML');

        const mergeButton = document.getElementById('mergeButton');

        const visualOld = document.getElementById('visualOld');

        const visualNew = document.getElementById('visualNew');


        mergeButton.addEventListener('click', mergeHTML);


        function mergeHTML() {

            const oldHTML = oldHTMLArea.value;

            const newHTML = newHTMLArea.value;


            // Parse HTML strings into DOM objects

            const oldDOM = new DOMParser().parseFromString(oldHTML, 'text/html');

            const newDOM = new DOMParser().parseFromString(newHTML, 'text/html');


            // Merge the DOMs

            const mergedDOM = mergeDOMs(oldDOM.body, newDOM.body);


            // Serialize the merged DOM back into a string

            const mergedHTML = new XMLSerializer().serializeToString(mergedDOM);


            // Display the merged HTML

            mergedHTMLArea.value = mergedHTML;


            // Update visual representation

            updateVisualMerger(oldDOM.body, newDOM.body);

        }


        function mergeDOMs(oldNode, newNode) {

            const mergedNode = oldNode.cloneNode(false);


            const oldChildren = Array.from(oldNode.childNodes);

            const newChildren = Array.from(newNode.childNodes);


            // Simple merge strategy: Keep all nodes from both old and new

            oldChildren.forEach(child => mergedNode.appendChild(child.cloneNode(true)));

            newChildren.forEach(child => {

                if (!oldChildren.some(oldChild => oldChild.isEqualNode(child))) {

                    mergedNode.appendChild(child.cloneNode(true));

                }

            });


            return mergedNode;

        }


        function updateVisualMerger(oldDOM, newDOM) {

            visualOld.innerHTML = '<h3>Original HTML Structure</h3>' + visualizeDOM(oldDOM);

            visualNew.innerHTML = '<h3>New HTML Structure</h3>' + visualizeDOM(newDOM, oldDOM);

        }


        function visualizeDOM(node, compareNode = null) {

            let html = '';

            if (node.nodeType === Node.ELEMENT_NODE) {

                const tagName = node.tagName.toLowerCase();

                let className = '';

                if (compareNode) {

                    if (!compareNode.querySelector(tagName)) {

                        className = 'highlight-add';

                    } else if (node.innerHTML !== compareNode.querySelector(tagName).innerHTML) {

                        className = 'highlight-change';

                    }

                }

                html += `<div class="${className}"><span>&lt;${tagName}&gt;</span>`;

                for (let child of node.childNodes) {

                    html += visualizeDOM(child, compareNode);

                }

                html += `<span>&lt;/${tagName}&gt;</span></div>`;

            } else if (node.nodeType === Node.TEXT_NODE) {

                const text = node.textContent.trim();

                if (text) {

                    html += `<span>${text}</span>`;

                }

            }

            return html;

        }

    </script>

</body></html>