<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Osinting MAP</title>
    <script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/vis/4.21.0/vis.min.js"></script>
    <link href="https://cdnjs.cloudflare.com/ajax/libs/vis/4.21.0/vis.min.css" rel="stylesheet" type="text/css" />
    <style>
        #toggle-btn {
            position: absolute;
            top: 20px;
            right: -30px; 
            background-color: transparent;
            border: none;
            padding: 0;
            cursor: pointer;
            box-shadow: none; 
            border-radius: 50%; 
            overflow: hidden;
        }

        #toggle-btn img {
            width: 30px;
            height: 30px;
            display: block; 
        }

        body {
            font-family: Arial, sans-serif;
            margin: 0;
            padding: 0;
            height: 100vh;
            background-color: #1a1a1a;
            display: flex;
            overflow: hidden;
        }

        #sidebar {
            width: 250px;
            background-color: #2d2d2d;
            color: #fff;
            padding: 15px;
            box-shadow: 2px 0 5px rgba(0, 0, 0, 0.2);
            display: flex;
            flex-direction: column;
            transition: transform 0.3s ease;
            z-index: 2;
            position: absolute;
            left: 0;
            top: 2cm;
        }

        #sidebar.collapsed {
            transform: translateX(-250px);
        }

        #sidebar-content {
            display: block;
        }

        #sidebar.collapsed #sidebar-content {
            display: none;
        }

        #toggle-btn {
            position: absolute;
            top: 20px;
            right: -25px;
            font-size: 24px;
            cursor: pointer;
            background-color: #2d2d2d;
            color: white;
            border: none;
            padding: 10px;
            border-radius: 50%;
            box-shadow: 2px 0 5px rgba(0, 0, 0, 0.2);
        }

        #network-container {
            flex: 1;
            height: 100%;
            display: flex;
            transition: margin-left 0.3s ease;
        }

        #network-container.fullscreen {
            margin-left: 0;
        }

        #network {
            flex: 1;
            height: 100%;
            background-color: #1a1a1a;
            background-image: radial-gradient(#6f05d3 1px, transparent 1px);
            background-size: 15px 15px;
        }

        button {
            background-color: #4a4a4a;
            color: #fff;
            border: none;
            padding: 10px;
            margin: 5px 0;
            cursor: pointer;
            font-size: 14px;
            border-radius: 4px;
            transition: background-color 0.3s ease;
        }

        button:hover {
            background-color: #666;
        }

        input, select {
            padding: 10px;
            margin: 5px 0;
            font-size: 14px;
            background-color: #333;
            border: 1px solid #4a4a4a;
            color: #fff;
            border-radius: 4px;
        }

        label {
            margin-top: 10px;
            font-size: 14px;
        }

        #saved-maps {
            margin-top: 20px;
            max-height: 200px;
            overflow-y: auto;
        }

        #saved-maps div {
            display: flex;
            justify-content: space-between;
            align-items: center;
            margin-bottom: 5px;
        }

        #saved-maps button {
            padding: 5px;
            font-size: 12px;
        }
    </style>
</head>
<body>
    <div id="sidebar">
        <div id="sidebar-content">
            <label for="node-label">Node Name:</label>
            <input type="text" id="node-label" placeholder="Enter node name">
            
            <label for="node-image">Node Image URL:</label>
            <input type="text" id="node-image" placeholder="Enter image URL">

            <label for="node-link">Node Link:</label>
            <input type="text" id="node-link" placeholder="Enter link URL">

            <button onclick="addNode()">Add Node</button>
            
            <label for="social-icon">Social Icon:</label>
            <select id="social-icon">
                <option value="facebook">Facebook</option>
                <option value="twitter">Twitter</option>
                <option value="instagram">Instagram</option>
                <option value="linkedin">Linkedin</option>
                <option value="medium">Medium</option>
                <option value="telegram">Telegram</option>
            </select>
            <button onclick="addSocialIcon()">Add Social Icon</button>
            
            <label for="save-name">Save Name:</label>
            <input type="text" id="save-name" placeholder="Enter save name">
            <button onclick="saveMap()">Save Map</button>
            
            <div id="saved-maps"></div>
        </div>
        <button id="toggle-btn" onclick="toggleSidebar()">
            <img src="https://i.ibb.co/PMvDL8f/jT0P50p.png" alt="Toggle Sidebar" style="width: 30px; height: 30px;">
        </button>
    </div>
    <div id="network-container">
        <div id="network"></div>
    </div>
    <script>
        document.addEventListener('DOMContentLoaded', function() {
            window.nodes = new vis.DataSet([]);
            window.edges = new vis.DataSet([]);
            window.dragging = false;
            window.startNode = null;
            window.tempEdge = null;

            const container = document.getElementById('network');
            const data = { 
                nodes: window.nodes, 
                edges: window.edges 
            };
            
            const options = {
                nodes: {
                    shape: 'box',
                    font: { 
                        size: 16, 
                        color: '#ffffff',
                        face: 'Arial'
                    },
                    borderWidth: 1,
                    color: { 
                        border: '#666666',
                        background: '#333333',
                        highlight: {
                            border: '#888888',
                            background: '#444444'
                        }
                    },
                    margin: 10
                },
                edges: { 
                    width: 2,
                    color: { 
                        color: '#6e6e6e',
                        highlight: '#8a2be2',
                        hover: '#8a2be2'
                    },
                    arrows: {
                        to: { enabled: true, scaleFactor: 0.5 }
                    },
                    smooth: {
                        enabled: true,
                        type: 'continuous',
                        roundness: 0.5
                    }
                },
                physics: {
                    enabled: false
                },
                interaction: {
                    hover: true,
                    dragNodes: true,
                    dragView: true,
                    zoomView: true,
                    navigationButtons: true,
                    keyboard: true
                },
                manipulation: {
                    enabled: true
                }
            };

            window.network = new vis.Network(container, data, options);

            const connectionPoint = document.createElement('div');
            connectionPoint.className = 'connection-point';
            connectionPoint.style.display = 'none';
            document.body.appendChild(connectionPoint);

            network.on("dragStart", function(params) {
                if (params.nodes.length === 1) {
                    window.dragging = true;
                    window.startNode = params.nodes[0];
                    connectionPoint.style.display = 'block';
                    
                    const position = network.getPositions([window.startNode])[window.startNode];
                    const canvasPosition = network.canvasToDOM(position);
                    connectionPoint.style.left = canvasPosition.x + 'px';
                    connectionPoint.style.top = canvasPosition.y + 'px';
                }
            });

            network.on("dragging", function(params) {
                if (window.dragging && window.startNode) {
                    connectionPoint.style.left = params.pointer.DOM.x + 'px';
                    connectionPoint.style.top = params.pointer.DOM.y + 'px';
                    
                    const endPoint = network.getNodeAt(params.pointer.DOM);
                    if (endPoint && endPoint !== window.startNode) {
                        connectionPoint.style.transform = 'scale(1.5)';
                    } else {
                        connectionPoint.style.transform = 'scale(1)';
                    }
                }
            });

            network.on("dragEnd", function(params) {
                if (window.dragging && window.startNode) {
                    const endNode = network.getNodeAt(params.pointer.DOM);
                    if (endNode && endNode !== window.startNode) {
                        edges.add({
                            from: window.startNode,
                            to: endNode,
                            smooth: {
                                enabled: true,
                                type: 'continuous'
                            }
                        });
                    }
                }
                
                window.dragging = false;
                window.startNode = null;
                connectionPoint.style.display = 'none';
                connectionPoint.style.transform = 'scale(1)';
            });

            network.on("doubleClick", function(params) {
                if (params.nodes.length === 1) {
                    const nodeId = params.nodes[0];
                    const newLabel = prompt("Enter new name for the node:");
                    if (newLabel) {
                        window.nodes.update({ id: nodeId, label: newLabel });
                    }
                }
            });

            network.on("click", function(params) {
                const nodeId = params.nodes[0];
                const node = window.nodes.get(nodeId);
                if (node && node.url) {
                    window.open(node.url, '_blank');
                }
            });

            nodes.add([
                { id: 1, label: 'Node 1' },
                { id: 2, label: 'Node 2' },
                { id: 3, label: 'Node 3' }
            ]);

            updateSavedMapsList();
        });

        function addNode() {
            const label = document.getElementById('node-label').value;
            const imageUrl = document.getElementById('node-image').value;
            const linkUrl = document.getElementById('node-link').value;
            const newNodeId = Date.now();
            
            if (label) {
                const newNode = { 
                    id: newNodeId, 
                    label: label 
                };
                
                if (imageUrl) {
                    newNode.shape = 'image';
                    newNode.image = imageUrl;
                }

                if (linkUrl) {
                    newNode.url = linkUrl;
                    newNode.title = linkUrl;
                }

                window.nodes.add(newNode);
                document.getElementById('node-label').value = '';
                document.getElementById('node-image').value = '';
                document.getElementById('node-link').value = '';
            }
        }

        function addSocialIcon() {
            const icon = document.getElementById('social-icon').value;
            const iconMap = {
                'facebook': 'https://upload.wikimedia.org/wikipedia/commons/5/51/Facebook_f_logo_%282019%29.svg',
                'twitter': 'https://osintservice.com/indexassets/img/x.webp',
                'instagram': 'https://upload.wikimedia.org/wikipedia/commons/a/a5/Instagram_icon.png',
                'linkedin': 'https://upload.wikimedia.org/wikipedia/commons/c/ca/LinkedIn_logo_initials.png',
                'medium': 'https://cdn-icons-png.flaticon.com/512/5968/5968906.png',
                'telegram': 'https://osintservice.com/indexassets/img/telegram.png',
            };
            const newNodeId = Date.now();
            window.nodes.add({ 
                id: newNodeId, 
                label: icon.charAt(0).toUpperCase() + icon.slice(1),
                shape: 'image',
                image: iconMap[icon]
            });
        }

        function toggleSidebar() {
            const sidebar = document.getElementById('sidebar');
            sidebar.classList.toggle('collapsed');
        }

        function saveMap() {
    const saveName = document.getElementById('save-name').value || 'Unnamed Map';
    const nodes = window.nodes.get();
    const nodePositions = window.network.getPositions();
    
    const nodesWithPositions = nodes.map(node => {
        const position = nodePositions[node.id];
        return { ...node, x: position.x, y: position.y };
    });

    const data = {
        nodes: nodesWithPositions,
        edges: window.edges.get()
    };

    let savedMaps = JSON.parse(localStorage.getItem('savedMaps')) || {};
    savedMaps[saveName] = data;
    localStorage.setItem('savedMaps', JSON.stringify(savedMaps));
    alert('Map saved successfully!');
    updateSavedMapsList();
}


        function loadMap(saveName) {
            const savedMaps = JSON.parse(localStorage.getItem('savedMaps')) || {};
            const data = savedMaps[saveName];
            if (data) {
                window.nodes.clear();
                window.edges.clear();
                window.nodes.add(data.nodes);
                window.edges.add(data.edges);
                window.network.fit(); // Adjust the view to fit all nodes
                alert('Map loaded successfully!');
            } else {
                alert('No saved map found with this name!');
            }
        }

        function deleteMap(saveName) {
            if (confirm('Are you sure you want to delete this saved map?')) {
                let savedMaps = JSON.parse(localStorage.getItem('savedMaps')) || {};
                delete savedMaps[saveName];
                localStorage.setItem('savedMaps', JSON.stringify(savedMaps));
                updateSavedMapsList();
                alert('Map deleted successfully!');
            }
        }

        function resetMap() {
            if (confirm('Are you sure you want to reset the current map? This will clear all nodes and edges.')) {
                window.nodes.clear();
                window.edges.clear();
                alert('Map reset successfully!');
            }
        }

        function updateSavedMapsList() {
            const savedMapsContainer = document.getElementById('saved-maps');
            savedMapsContainer.innerHTML = '<h3>Saved Maps:</h3>';
            const savedMaps = JSON.parse(localStorage.getItem('savedMaps')) || {};
            for (const [name, data] of Object.entries(savedMaps)) {
                const mapDiv = document.createElement('div');
                mapDiv.innerHTML = `
                    <span>${name}</span>
                    <button onclick="loadMap('${name}')">Load</button>
                    <button onclick="deleteMap('${name}')">Delete</button>
                `;
                savedMapsContainer.appendChild(mapDiv);
            }
        }

        // Load saved map on page load
        document.addEventListener('DOMContentLoaded', function() {
            updateSavedMapsList();
        });
    </script>
</body>
</html>