1848 lines
		
	
	
		
			72 KiB
		
	
	
	
		
			HTML
		
	
	
	
	
	
			
		
		
	
	
			1848 lines
		
	
	
		
			72 KiB
		
	
	
	
		
			HTML
		
	
	
	
	
	
<!DOCTYPE html>
 | 
						||
<html lang="en">
 | 
						||
<head>
 | 
						||
    <meta charset="UTF-8">
 | 
						||
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
 | 
						||
    <title>DFIR Tools YAML Editor</title>
 | 
						||
    <script src="https://cdnjs.cloudflare.com/ajax/libs/js-yaml/4.1.0/js-yaml.min.js"></script>
 | 
						||
    <style>
 | 
						||
        * {
 | 
						||
            margin: 0;
 | 
						||
            padding: 0;
 | 
						||
            box-sizing: border-box;
 | 
						||
        }
 | 
						||
 | 
						||
        body {
 | 
						||
            font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
 | 
						||
            background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
 | 
						||
            min-height: 100vh;
 | 
						||
            padding: 20px;
 | 
						||
        }
 | 
						||
 | 
						||
        .container {
 | 
						||
            max-width: 1400px;
 | 
						||
            margin: 0 auto;
 | 
						||
            background: white;
 | 
						||
            border-radius: 15px;
 | 
						||
            box-shadow: 0 20px 40px rgba(0,0,0,0.1);
 | 
						||
            overflow: hidden;
 | 
						||
        }
 | 
						||
 | 
						||
        .header {
 | 
						||
            background: linear-gradient(135deg, #2c3e50 0%, #3498db 100%);
 | 
						||
            color: white;
 | 
						||
            padding: 25px;
 | 
						||
            text-align: center;
 | 
						||
        }
 | 
						||
 | 
						||
        .header h1 {
 | 
						||
            font-size: 2.2em;
 | 
						||
            margin-bottom: 10px;
 | 
						||
        }
 | 
						||
 | 
						||
        .header p {
 | 
						||
            opacity: 0.9;
 | 
						||
            font-size: 1.1em;
 | 
						||
        }
 | 
						||
 | 
						||
        .tabs {
 | 
						||
            background: #f8f9fa;
 | 
						||
            display: flex;
 | 
						||
            border-bottom: 2px solid #e9ecef;
 | 
						||
        }
 | 
						||
 | 
						||
        .tab {
 | 
						||
            padding: 15px 25px;
 | 
						||
            cursor: pointer;
 | 
						||
            border-bottom: 3px solid transparent;
 | 
						||
            transition: all 0.3s ease;
 | 
						||
            font-weight: 500;
 | 
						||
        }
 | 
						||
 | 
						||
        .tab:hover {
 | 
						||
            background: #e9ecef;
 | 
						||
        }
 | 
						||
 | 
						||
        .tab.active {
 | 
						||
            background: white;
 | 
						||
            border-bottom-color: #3498db;
 | 
						||
            color: #3498db;
 | 
						||
        }
 | 
						||
 | 
						||
        .tab-content {
 | 
						||
            display: none;
 | 
						||
            padding: 30px;
 | 
						||
            min-height: 600px;
 | 
						||
        }
 | 
						||
 | 
						||
        .tab-content.active {
 | 
						||
            display: block;
 | 
						||
        }
 | 
						||
 | 
						||
        .file-input-section {
 | 
						||
            background: #f8f9fa;
 | 
						||
            padding: 20px;
 | 
						||
            border-radius: 10px;
 | 
						||
            margin-bottom: 20px;
 | 
						||
            border: 2px dashed #dee2e6;
 | 
						||
            text-align: center;
 | 
						||
        }
 | 
						||
 | 
						||
        .file-input-section input {
 | 
						||
            margin: 10px;
 | 
						||
            padding: 10px;
 | 
						||
            border: 1px solid #ddd;
 | 
						||
            border-radius: 5px;
 | 
						||
        }
 | 
						||
 | 
						||
        .btn {
 | 
						||
            background: linear-gradient(135deg, #3498db, #2980b9);
 | 
						||
            color: white;
 | 
						||
            border: none;
 | 
						||
            padding: 12px 24px;
 | 
						||
            border-radius: 8px;
 | 
						||
            cursor: pointer;
 | 
						||
            font-size: 14px;
 | 
						||
            font-weight: 500;
 | 
						||
            transition: all 0.3s ease;
 | 
						||
            margin: 5px;
 | 
						||
        }
 | 
						||
 | 
						||
        .btn:hover {
 | 
						||
            transform: translateY(-2px);
 | 
						||
            box-shadow: 0 8px 15px rgba(52, 152, 219, 0.3);
 | 
						||
        }
 | 
						||
 | 
						||
        .btn-danger {
 | 
						||
            background: linear-gradient(135deg, #e74c3c, #c0392b);
 | 
						||
        }
 | 
						||
 | 
						||
        .btn-success {
 | 
						||
            background: linear-gradient(135deg, #27ae60, #229954);
 | 
						||
        }
 | 
						||
 | 
						||
        .btn-warning {
 | 
						||
            background: linear-gradient(135deg, #f39c12, #e67e22);
 | 
						||
        }
 | 
						||
 | 
						||
        .tools-grid {
 | 
						||
            display: grid;
 | 
						||
            grid-template-columns: repeat(auto-fill, minmax(350px, 1fr));
 | 
						||
            gap: 20px;
 | 
						||
            margin-top: 20px;
 | 
						||
        }
 | 
						||
 | 
						||
        .tool-card {
 | 
						||
            background: white;
 | 
						||
            border: 1px solid #e9ecef;
 | 
						||
            border-radius: 10px;
 | 
						||
            padding: 20px;
 | 
						||
            box-shadow: 0 4px 6px rgba(0,0,0,0.1);
 | 
						||
            transition: all 0.3s ease;
 | 
						||
        }
 | 
						||
 | 
						||
        .tool-card:hover {
 | 
						||
            transform: translateY(-5px);
 | 
						||
            box-shadow: 0 8px 15px rgba(0,0,0,0.15);
 | 
						||
        }
 | 
						||
 | 
						||
        .tool-card.method {
 | 
						||
            border-left: 4px solid #9b59b6;
 | 
						||
            background: linear-gradient(135deg, #f8f9fa 0%, #f4f1ff 100%);
 | 
						||
        }
 | 
						||
 | 
						||
        .tool-card.software {
 | 
						||
            border-left: 4px solid #3498db;
 | 
						||
        }
 | 
						||
 | 
						||
        .tool-card h3 {
 | 
						||
            color: #2c3e50;
 | 
						||
            margin-bottom: 10px;
 | 
						||
            font-size: 1.3em;
 | 
						||
            display: flex;
 | 
						||
            align-items: center;
 | 
						||
            gap: 8px;
 | 
						||
        }
 | 
						||
 | 
						||
        .tool-icon {
 | 
						||
            font-size: 1.4em;
 | 
						||
        }
 | 
						||
 | 
						||
        .tool-card p {
 | 
						||
            color: #7f8c8d;
 | 
						||
            margin-bottom: 15px;
 | 
						||
            font-size: 0.9em;
 | 
						||
            line-height: 1.4;
 | 
						||
        }
 | 
						||
 | 
						||
        .tag {
 | 
						||
            display: inline-block;
 | 
						||
            background: #ecf0f1;
 | 
						||
            color: #34495e;
 | 
						||
            padding: 4px 8px;
 | 
						||
            border-radius: 15px;
 | 
						||
            font-size: 0.8em;
 | 
						||
            margin: 2px;
 | 
						||
        }
 | 
						||
 | 
						||
        .tag.method-tag {
 | 
						||
            background: #e8e4ff;
 | 
						||
            color: #9b59b6;
 | 
						||
            font-weight: bold;
 | 
						||
        }
 | 
						||
 | 
						||
        .tag.domain-agnostic {
 | 
						||
            background: #e8f5e8;
 | 
						||
            color: #27ae60;
 | 
						||
            font-weight: bold;
 | 
						||
        }
 | 
						||
 | 
						||
        .skill-badge {
 | 
						||
            display: inline-block;
 | 
						||
            padding: 4px 12px;
 | 
						||
            border-radius: 20px;
 | 
						||
            font-size: 0.8em;
 | 
						||
            font-weight: bold;
 | 
						||
            margin: 5px 0;
 | 
						||
        }
 | 
						||
 | 
						||
        .skill-novice { background: #d5f4e6; color: #158bc2; }
 | 
						||
        .skill-beginner { background: #d5f4e6; color: #27ae60; }
 | 
						||
        .skill-intermediate { background: #ffeaa7; color: #e17055; }
 | 
						||
        .skill-advanced { background: #fab1a0; color: #d63031; }
 | 
						||
        .skill-expert { background: #2c3e50; color: #ffffff; }
 | 
						||
 | 
						||
        .form-section {
 | 
						||
            background: #f8f9fa;
 | 
						||
            padding: 25px;
 | 
						||
            border-radius: 10px;
 | 
						||
            margin-bottom: 20px;
 | 
						||
        }
 | 
						||
 | 
						||
        .form-group {
 | 
						||
            margin-bottom: 20px;
 | 
						||
        }
 | 
						||
 | 
						||
        .form-group label {
 | 
						||
            display: block;
 | 
						||
            margin-bottom: 8px;
 | 
						||
            font-weight: 600;
 | 
						||
            color: #2c3e50;
 | 
						||
        }
 | 
						||
 | 
						||
        .form-group input,
 | 
						||
        .form-group textarea,
 | 
						||
        .form-group select {
 | 
						||
            width: 100%;
 | 
						||
            padding: 12px;
 | 
						||
            border: 2px solid #e9ecef;
 | 
						||
            border-radius: 8px;
 | 
						||
            font-size: 14px;
 | 
						||
            transition: border-color 0.3s ease;
 | 
						||
        }
 | 
						||
 | 
						||
        .form-group input:focus,
 | 
						||
        .form-group textarea:focus,
 | 
						||
        .form-group select:focus {
 | 
						||
            outline: none;
 | 
						||
            border-color: #3498db;
 | 
						||
            box-shadow: 0 0 0 3px rgba(52, 152, 219, 0.1);
 | 
						||
        }
 | 
						||
 | 
						||
        .checkbox-group {
 | 
						||
            display: grid;
 | 
						||
            grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
 | 
						||
            gap: 10px;
 | 
						||
            margin-top: 10px;
 | 
						||
        }
 | 
						||
 | 
						||
        .checkbox-item {
 | 
						||
            display: flex;
 | 
						||
            align-items: center;
 | 
						||
            gap: 8px;
 | 
						||
        }
 | 
						||
 | 
						||
        .search-bar {
 | 
						||
            width: 100%;
 | 
						||
            padding: 15px;
 | 
						||
            border: 2px solid #e9ecef;
 | 
						||
            border-radius: 10px;
 | 
						||
            font-size: 16px;
 | 
						||
            margin-bottom: 20px;
 | 
						||
        }
 | 
						||
 | 
						||
        .bulk-operations {
 | 
						||
            background: #fff3cd;
 | 
						||
            border: 1px solid #ffeaa7;
 | 
						||
            border-radius: 10px;
 | 
						||
            padding: 20px;
 | 
						||
            margin-bottom: 20px;
 | 
						||
        }
 | 
						||
 | 
						||
        .stats {
 | 
						||
            display: grid;
 | 
						||
            grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
 | 
						||
            gap: 20px;
 | 
						||
            margin-bottom: 30px;
 | 
						||
        }
 | 
						||
 | 
						||
        .stat-card {
 | 
						||
            background: white;
 | 
						||
            padding: 20px;
 | 
						||
            border-radius: 10px;
 | 
						||
            text-align: center;
 | 
						||
            box-shadow: 0 4px 6px rgba(0,0,0,0.1);
 | 
						||
        }
 | 
						||
 | 
						||
        .stat-number {
 | 
						||
            font-size: 2em;
 | 
						||
            font-weight: bold;
 | 
						||
            color: #3498db;
 | 
						||
        }
 | 
						||
 | 
						||
        .stat-label {
 | 
						||
            color: #7f8c8d;
 | 
						||
            margin-top: 5px;
 | 
						||
        }
 | 
						||
 | 
						||
        .hidden {
 | 
						||
            display: none !important;
 | 
						||
        }
 | 
						||
 | 
						||
        .tag-input-container {
 | 
						||
            display: flex;
 | 
						||
            flex-wrap: wrap;
 | 
						||
            gap: 5px;
 | 
						||
            margin-bottom: 10px;
 | 
						||
            padding: 10px;
 | 
						||
            border: 2px solid #e9ecef;
 | 
						||
            border-radius: 8px;
 | 
						||
            min-height: 50px;
 | 
						||
            align-items: center;
 | 
						||
        }
 | 
						||
 | 
						||
        .tag-input {
 | 
						||
            border: none;
 | 
						||
            outline: none;
 | 
						||
            padding: 5px;
 | 
						||
            flex: 1;
 | 
						||
            min-width: 100px;
 | 
						||
        }
 | 
						||
 | 
						||
        .removable-tag {
 | 
						||
            background: #3498db;
 | 
						||
            color: white;
 | 
						||
            padding: 4px 8px;
 | 
						||
            border-radius: 15px;
 | 
						||
            font-size: 0.8em;
 | 
						||
            display: flex;
 | 
						||
            align-items: center;
 | 
						||
            gap: 5px;
 | 
						||
        }
 | 
						||
 | 
						||
        .remove-tag {
 | 
						||
            cursor: pointer;
 | 
						||
            background: rgba(255,255,255,0.3);
 | 
						||
            border-radius: 50%;
 | 
						||
            width: 16px;
 | 
						||
            height: 16px;
 | 
						||
            display: flex;
 | 
						||
            align-items: center;
 | 
						||
            justify-content: center;
 | 
						||
            font-size: 12px;
 | 
						||
        }
 | 
						||
 | 
						||
        .export-section {
 | 
						||
            background: #e8f5e8;
 | 
						||
            border: 1px solid #c3e6c3;
 | 
						||
            border-radius: 10px;
 | 
						||
            padding: 20px;
 | 
						||
            margin-top: 20px;
 | 
						||
        }
 | 
						||
 | 
						||
        .tag-stat {
 | 
						||
            display: flex;
 | 
						||
            justify-content: space-between;
 | 
						||
            align-items: center;
 | 
						||
            padding: 8px 12px;
 | 
						||
            margin: 5px 0;
 | 
						||
            background: #f8f9fa;
 | 
						||
            border-radius: 8px;
 | 
						||
            border-left: 4px solid #3498db;
 | 
						||
        }
 | 
						||
 | 
						||
        .tag-stat:hover {
 | 
						||
            background: #e9ecef;
 | 
						||
            cursor: pointer;
 | 
						||
        }
 | 
						||
 | 
						||
        .tag-name {
 | 
						||
            font-weight: 500;
 | 
						||
            color: #2c3e50;
 | 
						||
        }
 | 
						||
 | 
						||
        .tag-count {
 | 
						||
            background: #3498db;
 | 
						||
            color: white;
 | 
						||
            padding: 4px 8px;
 | 
						||
            border-radius: 12px;
 | 
						||
            font-size: 0.85em;
 | 
						||
            font-weight: bold;
 | 
						||
        }
 | 
						||
 | 
						||
        .skill-bar {
 | 
						||
            display: flex;
 | 
						||
            align-items: center;
 | 
						||
            margin: 10px 0;
 | 
						||
            gap: 15px;
 | 
						||
        }
 | 
						||
 | 
						||
        .skill-label {
 | 
						||
            width: 100px;
 | 
						||
            font-weight: 500;
 | 
						||
            text-transform: capitalize;
 | 
						||
        }
 | 
						||
 | 
						||
        .skill-progress {
 | 
						||
            flex: 1;
 | 
						||
            height: 20px;
 | 
						||
            background: #e9ecef;
 | 
						||
            border-radius: 10px;
 | 
						||
            overflow: hidden;
 | 
						||
            position: relative;
 | 
						||
        }
 | 
						||
 | 
						||
        .skill-fill {
 | 
						||
            height: 100%;
 | 
						||
            border-radius: 10px;
 | 
						||
            transition: width 0.3s ease;
 | 
						||
        }
 | 
						||
 | 
						||
        .skill-fill.novice { background: linear-gradient(90deg, #77b7d3, #2e92cc); }
 | 
						||
        .skill-fill.beginner { background: linear-gradient(90deg, #27ae60, #2ecc71); }
 | 
						||
        .skill-fill.intermediate { background: linear-gradient(90deg, #f39c12, #e67e22); }
 | 
						||
        .skill-fill.advanced { background: linear-gradient(90deg, #e74c3c, #c0392b); }
 | 
						||
        .skill-fill.expert { background: linear-gradient(90deg, #2c3e50, #34495e); }
 | 
						||
 | 
						||
        .skill-count {
 | 
						||
            min-width: 30px;
 | 
						||
            text-align: right;
 | 
						||
            font-weight: bold;
 | 
						||
            color: #2c3e50;
 | 
						||
        }
 | 
						||
 | 
						||
        .error-message {
 | 
						||
            background: #f8d7da;
 | 
						||
            color: #721c24;
 | 
						||
            padding: 12px;
 | 
						||
            border-radius: 8px;
 | 
						||
            margin: 10px 0;
 | 
						||
            border: 1px solid #f5c6cb;
 | 
						||
        }
 | 
						||
 | 
						||
        .success-message {
 | 
						||
            background: #d4edda;
 | 
						||
            color: #155724;
 | 
						||
            padding: 12px;
 | 
						||
            border-radius: 8px;
 | 
						||
            margin: 10px 0;
 | 
						||
            border: 1px solid #c3e6cb;
 | 
						||
        }
 | 
						||
 | 
						||
        .type-badge {
 | 
						||
            display: inline-block;
 | 
						||
            padding: 4px 8px;
 | 
						||
            border-radius: 12px;
 | 
						||
            font-size: 0.75em;
 | 
						||
            font-weight: bold;
 | 
						||
            text-transform: uppercase;
 | 
						||
            margin-left: 10px;
 | 
						||
        }
 | 
						||
 | 
						||
        .type-software {
 | 
						||
            background: #3498db;
 | 
						||
            color: white;
 | 
						||
        }
 | 
						||
 | 
						||
        .type-method {
 | 
						||
            background: #9b59b6;
 | 
						||
            color: white;
 | 
						||
        }
 | 
						||
 | 
						||
        .conditional-fields {
 | 
						||
            transition: opacity 0.3s ease;
 | 
						||
        }
 | 
						||
 | 
						||
        .conditional-fields.disabled {
 | 
						||
            opacity: 0.5;
 | 
						||
            pointer-events: none;
 | 
						||
        }
 | 
						||
 | 
						||
        .icon-input {
 | 
						||
            font-size: 1.5em;
 | 
						||
            text-align: center;
 | 
						||
            padding: 10px;
 | 
						||
            width: 80px;
 | 
						||
        }
 | 
						||
    </style>
 | 
						||
</head>
 | 
						||
<body>
 | 
						||
    <div class="container">
 | 
						||
        <div class="header">
 | 
						||
            <h1>🔧 DFIR Tools YAML Editor</h1>
 | 
						||
            <p>Comprehensive editor for Digital Forensics and Incident Response tools database</p>
 | 
						||
        </div>
 | 
						||
 | 
						||
        <div class="tabs">
 | 
						||
            <div class="tab active" onclick="showTab('overview')">📊 Overview</div>
 | 
						||
            <div class="tab" onclick="showTab('tools')">🛠️ Tools</div>
 | 
						||
            <div class="tab" onclick="showTab('editor')">✏️ Editor</div>
 | 
						||
            <div class="tab" onclick="showTab('bulk')">📋 Bulk Edit</div>
 | 
						||
            <div class="tab" onclick="showTab('export')">💾 Export</div>
 | 
						||
        </div>
 | 
						||
 | 
						||
        <!-- Overview Tab -->
 | 
						||
        <div id="overview" class="tab-content active">
 | 
						||
            <div class="file-input-section">
 | 
						||
                <h3>📁 Load YAML File</h3>
 | 
						||
                <input type="file" id="fileInput" accept=".yaml,.yml" />
 | 
						||
                <button class="btn" onclick="loadFile()">Load File</button>
 | 
						||
                <button class="btn btn-success" onclick="loadSampleData()">Load Sample Data</button>
 | 
						||
            </div>
 | 
						||
 | 
						||
            <div id="statsSection" class="hidden">
 | 
						||
                <div class="stats">
 | 
						||
                    <div class="stat-card">
 | 
						||
                        <div class="stat-number" id="totalTools">0</div>
 | 
						||
                        <div class="stat-label">Total Tools</div>
 | 
						||
                    </div>
 | 
						||
                    <div class="stat-card">
 | 
						||
                        <div class="stat-number" id="softwareCount">0</div>
 | 
						||
                        <div class="stat-label">Software</div>
 | 
						||
                    </div>
 | 
						||
                    <div class="stat-card">
 | 
						||
                        <div class="stat-number" id="methodCount">0</div>
 | 
						||
                        <div class="stat-label">Methods</div>
 | 
						||
                    </div>
 | 
						||
                    <div class="stat-card">
 | 
						||
                        <div class="stat-number" id="totalDomains">0</div>
 | 
						||
                        <div class="stat-label">Domains</div>
 | 
						||
                    </div>
 | 
						||
                    <div class="stat-card">
 | 
						||
                        <div class="stat-number" id="totalPhases">0</div>
 | 
						||
                        <div class="stat-label">Phases</div>
 | 
						||
                    </div>
 | 
						||
                    <div class="stat-card">
 | 
						||
                        <div class="stat-number" id="totalDomainAgnostic">0</div>
 | 
						||
                        <div class="stat-label">Domain-Agnostic</div>
 | 
						||
                    </div>
 | 
						||
                    <div class="stat-card">
 | 
						||
                        <div class="stat-number" id="selfHostedCount">0</div>
 | 
						||
                        <div class="stat-label">CC24-Server</div>
 | 
						||
                    </div>
 | 
						||
                    <div class="stat-card">
 | 
						||
                        <div class="stat-number" id="knowledgebaseCount">0</div>
 | 
						||
                        <div class="stat-label">Knowledgebase</div>
 | 
						||
                    </div>
 | 
						||
                </div>
 | 
						||
 | 
						||
                <div class="form-section">
 | 
						||
                    <h3>🏷️ Tag Analytics</h3>
 | 
						||
                    <div id="tagAnalytics" style="max-height: 400px; overflow-y: auto;">
 | 
						||
                        <p>Loading tag statistics...</p>
 | 
						||
                    </div>
 | 
						||
                </div>
 | 
						||
 | 
						||
                <div class="form-section">
 | 
						||
                    <h3>📊 Skill Level Distribution</h3>
 | 
						||
                    <div id="skillDistribution"></div>
 | 
						||
                </div>
 | 
						||
            </div>
 | 
						||
        </div>
 | 
						||
 | 
						||
        <!-- Tools Tab -->
 | 
						||
        <div id="tools" class="tab-content">
 | 
						||
            <input type="text" class="search-bar" id="searchBar" placeholder="🔍 Search tools by name, description, tags, domains, phases, or type..." onkeyup="filterTools()" />
 | 
						||
            <div class="tools-grid" id="toolsGrid"></div>
 | 
						||
        </div>
 | 
						||
 | 
						||
        <!-- Editor Tab -->
 | 
						||
        <div id="editor" class="tab-content">
 | 
						||
            <div class="form-section">
 | 
						||
                <h3 id="editorTitle">Add New Tool</h3>
 | 
						||
                <div id="messageArea"></div>
 | 
						||
                <form id="toolForm">
 | 
						||
                    <div style="display: grid; grid-template-columns: 1fr 1fr 100px; gap: 20px;">
 | 
						||
                        <div class="form-group">
 | 
						||
                            <label for="toolName">Tool Name *</label>
 | 
						||
                            <input type="text" id="toolName" required />
 | 
						||
                        </div>
 | 
						||
                        <div class="form-group">
 | 
						||
                            <label for="toolType">Type *</label>
 | 
						||
                            <select id="toolType" required onchange="handleTypeChange()">
 | 
						||
                                <option value="">Select Type</option>
 | 
						||
                                <option value="software">Software</option>
 | 
						||
                                <option value="method">Method</option>
 | 
						||
                            </select>
 | 
						||
                        </div>
 | 
						||
                        <div class="form-group">
 | 
						||
                            <label for="toolIcon">Icon <small style="color: #7f8c8d; cursor: pointer;" onclick="showIconSuggestions()" title="Click for suggestions">💡 suggestions</small></label>
 | 
						||
                            <input type="text" id="toolIcon" class="icon-input" placeholder="🔧" maxlength="2" />
 | 
						||
                        </div>
 | 
						||
                    </div>
 | 
						||
 | 
						||
                    <div class="form-group">
 | 
						||
                        <label for="description">Description *</label>
 | 
						||
                        <textarea id="description" rows="3" required></textarea>
 | 
						||
                    </div>
 | 
						||
 | 
						||
                    <div style="display: grid; grid-template-columns: 1fr 1fr; gap: 20px;">
 | 
						||
                        <div class="form-group">
 | 
						||
                            <label for="skillLevel">Skill Level *</label>
 | 
						||
                            <select id="skillLevel" required>
 | 
						||
                                <option value="">Select Level</option>
 | 
						||
                                <option value="novice">Novice</option>
 | 
						||
                                <option value="beginner">Beginner</option>
 | 
						||
                                <option value="intermediate">Intermediate</option>
 | 
						||
                                <option value="advanced">Advanced</option>
 | 
						||
                                <option value="expert">Expert</option>
 | 
						||
                            </select>
 | 
						||
                        </div>
 | 
						||
                        <div class="form-group">
 | 
						||
                            <label for="url">URL</label>
 | 
						||
                            <input type="url" id="url" />
 | 
						||
                        </div>
 | 
						||
                    </div>
 | 
						||
 | 
						||
                    <!-- Software-specific fields -->
 | 
						||
                    <div id="softwareFields" class="conditional-fields">
 | 
						||
                        <div style="display: grid; grid-template-columns: 1fr 1fr 1fr; gap: 20px;">
 | 
						||
                            <div class="form-group">
 | 
						||
                                <label for="projectUrl">Project URL</label>
 | 
						||
                                <input type="url" id="projectUrl" />
 | 
						||
                            </div>
 | 
						||
                            <div class="form-group">
 | 
						||
                                <label for="license">License</label>
 | 
						||
                                <input type="text" id="license" />
 | 
						||
                            </div>
 | 
						||
                            <div class="form-group">
 | 
						||
                                <label for="accessType">Access Type</label>
 | 
						||
                                <select id="accessType">
 | 
						||
                                    <option value="">Select Type</option>
 | 
						||
                                    <option value="download">Download</option>
 | 
						||
                                    <option value="server-based">CC24-Server</option>
 | 
						||
                                    <option value="commercial">Commercial</option>
 | 
						||
                                    <option value="built-in">Built-in</option>
 | 
						||
                                </select>
 | 
						||
                            </div>
 | 
						||
                        </div>
 | 
						||
 | 
						||
                        <div style="display: grid; grid-template-columns: 1fr 1fr; gap: 20px;">
 | 
						||
                            <div class="form-group">
 | 
						||
                                <label for="statusUrl">Status URL</label>
 | 
						||
                                <input type="url" id="statusUrl" />
 | 
						||
                            </div>
 | 
						||
                            <div class="form-group">
 | 
						||
                                <div class="checkbox-item">
 | 
						||
                                    <input type="checkbox" id="knowledgebase" />
 | 
						||
                                    <label for="knowledgebase">📚 Knowledgebase Tool</label>
 | 
						||
                                </div>
 | 
						||
                            </div>
 | 
						||
                        </div>
 | 
						||
 | 
						||
                        <div class="form-group">
 | 
						||
                            <label>Platforms</label>
 | 
						||
                            <div class="checkbox-group" id="platformsCheckbox">
 | 
						||
                                <div class="checkbox-item">
 | 
						||
                                    <input type="checkbox" id="platform-windows" value="Windows">
 | 
						||
                                    <label for="platform-windows">Windows</label>
 | 
						||
                                </div>
 | 
						||
                                <div class="checkbox-item">
 | 
						||
                                    <input type="checkbox" id="platform-linux" value="Linux">
 | 
						||
                                    <label for="platform-linux">Linux</label>
 | 
						||
                                </div>
 | 
						||
                                <div class="checkbox-item">
 | 
						||
                                    <input type="checkbox" id="platform-macos" value="macOS">
 | 
						||
                                    <label for="platform-macos">macOS</label>
 | 
						||
                                </div>
 | 
						||
                                <div class="checkbox-item">
 | 
						||
                                    <input type="checkbox" id="platform-web" value="Web">
 | 
						||
                                    <label for="platform-web">Web</label>
 | 
						||
                                </div>
 | 
						||
                                <div class="checkbox-item">
 | 
						||
                                    <input type="checkbox" id="platform-os" value="OS">
 | 
						||
                                    <label for="platform-os">Operating System</label>
 | 
						||
                                </div>
 | 
						||
                                <div class="checkbox-item">
 | 
						||
                                    <input type="checkbox" id="platform-hardware" value="Hardware">
 | 
						||
                                    <label for="platform-hardware">Hardware</label>
 | 
						||
                                </div>
 | 
						||
                            </div>
 | 
						||
                        </div>
 | 
						||
                    </div>
 | 
						||
 | 
						||
                    <div class="form-group">
 | 
						||
                        <label>Domains</label>
 | 
						||
                        <div class="checkbox-group" id="domainsCheckbox"></div>
 | 
						||
                    </div>
 | 
						||
 | 
						||
                    <div class="form-group">
 | 
						||
                        <label>Phases</label>
 | 
						||
                        <div class="checkbox-group" id="phasesCheckbox"></div>
 | 
						||
                    </div>
 | 
						||
 | 
						||
                    <div class="form-group">
 | 
						||
                        <label>Domain-Agnostic Software Categories</label>
 | 
						||
                        <div class="checkbox-group" id="domainAgnosticCheckbox"></div>
 | 
						||
                    </div>
 | 
						||
 | 
						||
                    <div class="form-group">
 | 
						||
                        <label for="tagsInput">Tags</label>
 | 
						||
                        <div class="tag-input-container" id="tagContainer">
 | 
						||
                            <input type="text" class="tag-input" id="tagsInput" placeholder="Type and press Enter to add tags..." onkeypress="addTagOnEnter(event)" />
 | 
						||
                        </div>
 | 
						||
                    </div>
 | 
						||
 | 
						||
                    <div style="text-align: center; margin-top: 30px;">
 | 
						||
                        <button type="button" class="btn btn-success" onclick="saveTool()">💾 Save Tool</button>
 | 
						||
                        <button type="button" class="btn btn-warning" onclick="clearForm()">🗑️ Clear Form</button>
 | 
						||
                        <button type="button" class="btn btn-danger" id="deleteBtn" onclick="deleteTool()" style="display: none;">🗑️ Delete Tool</button>
 | 
						||
                    </div>
 | 
						||
                </form>
 | 
						||
            </div>
 | 
						||
        </div>
 | 
						||
 | 
						||
        <!-- Bulk Edit Tab -->
 | 
						||
        <div id="bulk" class="tab-content">
 | 
						||
            <div class="bulk-operations">
 | 
						||
                <h3>🔄 Bulk Operations</h3>
 | 
						||
                <p>Select multiple tools to perform bulk operations</p>
 | 
						||
                
 | 
						||
                <div style="margin: 20px 0;">
 | 
						||
                    <button class="btn" onclick="selectAllTools()">Select All</button>
 | 
						||
                    <button class="btn" onclick="selectByType('software')">Select Software</button>
 | 
						||
                    <button class="btn" onclick="selectByType('method')">Select Methods</button>
 | 
						||
                    <button class="btn" onclick="clearSelection()">Clear Selection</button>
 | 
						||
                    <span id="selectionCount" style="margin-left: 20px; font-weight: bold;">0 selected</span>
 | 
						||
                </div>
 | 
						||
 | 
						||
                <div style="display: grid; grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); gap: 15px; margin-top: 20px;">
 | 
						||
                    <button class="btn btn-warning" onclick="bulkUpdateSkillLevel()">Update Skill Level</button>
 | 
						||
                    <button class="btn btn-warning" onclick="bulkUpdateDomains()">Update Domains</button>
 | 
						||
                    <button class="btn btn-warning" onclick="bulkUpdatePhases()">Update Phases</button>
 | 
						||
                    <button class="btn btn-warning" onclick="bulkUpdateDomainAgnostic()">Update Domain-Agnostic</button>
 | 
						||
                    <button class="btn btn-warning" onclick="bulkUpdateTags()">Update Tags</button>
 | 
						||
                    <button class="btn btn-warning" onclick="bulkUpdateType()">Update Type</button>
 | 
						||
                    <button class="btn btn-warning" onclick="bulkUpdateIcons()">🎨 Update Icons</button>
 | 
						||
                </div>
 | 
						||
 | 
						||
                <div style="display: grid; grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); gap: 15px; margin-top: 15px;">
 | 
						||
                    <button class="btn" onclick="bulkSetKnowledgebase(true)">📚 Set as Knowledgebase</button>
 | 
						||
                    <button class="btn" onclick="bulkSetKnowledgebase(false)">📖 Remove Knowledgebase</button>
 | 
						||
                    <button class="btn" onclick="bulkClearField('icon')">🗑️ Clear Icons</button>
 | 
						||
                    <button class="btn" onclick="bulkClearField('tags')">🗑️ Clear All Tags</button>
 | 
						||
                    <button class="btn" onclick="bulkClearField('domains')">🗑️ Clear All Domains</button>
 | 
						||
                </div>
 | 
						||
 | 
						||
                <div style="display: grid; grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); gap: 15px; margin-top: 15px;">
 | 
						||
                    <button class="btn" onclick="bulkClearField('phases')">🗑️ Clear All Phases</button>
 | 
						||
                    <button class="btn" onclick="bulkClearField('domain-agnostic-software')">🗑️ Clear Domain-Agnostic</button>
 | 
						||
                    <button class="btn" onclick="bulkClearField('platforms')">🗑️ Clear All Platforms</button>
 | 
						||
                    <button class="btn" onclick="bulkClearField('url')">🗑️ Clear All URLs</button>
 | 
						||
                </div>
 | 
						||
 | 
						||
                <div style="display: grid; grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); gap: 15px; margin-top: 15px;">
 | 
						||
                    <button class="btn" onclick="bulkClearField('projectUrl')">🗑️ Clear Project URLs</button>
 | 
						||
                    <button class="btn" onclick="bulkClearField('statusUrl')">🗑️ Clear Status URLs</button>
 | 
						||
                    <button class="btn btn-danger" onclick="bulkDelete()">🗑️ Delete Selected</button>
 | 
						||
                </div>
 | 
						||
            </div>
 | 
						||
 | 
						||
            <div class="tools-grid" id="bulkToolsGrid"></div>
 | 
						||
        </div>
 | 
						||
 | 
						||
        <!-- Export Tab -->
 | 
						||
        <div id="export" class="tab-content">
 | 
						||
            <div class="export-section">
 | 
						||
                <h3>💾 Export Options</h3>
 | 
						||
                <p>Download your edited YAML file</p>
 | 
						||
                
 | 
						||
                <div style="margin: 20px 0;">
 | 
						||
                    <button class="btn btn-success" onclick="exportYAML()">📥 Download YAML</button>
 | 
						||
                    <button class="btn" onclick="previewYAML()">👁️ Preview YAML</button>
 | 
						||
                    <button class="btn btn-warning" onclick="validateYAML()">✅ Validate Structure</button>
 | 
						||
                </div>
 | 
						||
            </div>
 | 
						||
 | 
						||
            <div id="yamlPreview" class="form-section hidden">
 | 
						||
                <h3>YAML Preview</h3>
 | 
						||
                <textarea readonly style="width: 100%; height: 400px; font-family: monospace; font-size: 12px;" id="yamlPreviewText"></textarea>
 | 
						||
            </div>
 | 
						||
 | 
						||
            <div id="validationResults" class="form-section hidden">
 | 
						||
                <h3>Validation Results</h3>
 | 
						||
                <div id="validationContent"></div>
 | 
						||
            </div>
 | 
						||
        </div>
 | 
						||
    </div>
 | 
						||
 | 
						||
    <script>
 | 
						||
        let yamlData = null;
 | 
						||
        let currentEditingIndex = -1;
 | 
						||
        let selectedTools = new Set();
 | 
						||
 | 
						||
        function showTab(tabName) {
 | 
						||
            // Hide all tab contents
 | 
						||
            document.querySelectorAll('.tab-content').forEach(content => {
 | 
						||
                content.classList.remove('active');
 | 
						||
            });
 | 
						||
            
 | 
						||
            // Remove active class from all tabs
 | 
						||
            document.querySelectorAll('.tab').forEach(tab => {
 | 
						||
                tab.classList.remove('active');
 | 
						||
            });
 | 
						||
            
 | 
						||
            // Show selected tab content
 | 
						||
            document.getElementById(tabName).classList.add('active');
 | 
						||
            
 | 
						||
            // Add active class to clicked tab
 | 
						||
            event.target.classList.add('active');
 | 
						||
 | 
						||
            // Refresh content based on tab
 | 
						||
            if (tabName === 'tools') {
 | 
						||
                renderToolsGrid();
 | 
						||
            } else if (tabName === 'bulk') {
 | 
						||
                renderBulkGrid();
 | 
						||
            }
 | 
						||
        }
 | 
						||
 | 
						||
        function handleTypeChange() {
 | 
						||
            const type = document.getElementById('toolType').value;
 | 
						||
            const softwareFields = document.getElementById('softwareFields');
 | 
						||
            
 | 
						||
            if (type === 'method') {
 | 
						||
                softwareFields.classList.add('disabled');
 | 
						||
                // Clear software-specific fields for methods
 | 
						||
                document.getElementById('projectUrl').value = '';
 | 
						||
                document.getElementById('license').value = '';
 | 
						||
                document.getElementById('accessType').value = '';
 | 
						||
                document.getElementById('statusUrl').value = '';
 | 
						||
                document.getElementById('knowledgebase').checked = false;
 | 
						||
                // Clear platform checkboxes
 | 
						||
                document.querySelectorAll('#platformsCheckbox input').forEach(cb => cb.checked = false);
 | 
						||
            } else {
 | 
						||
                softwareFields.classList.remove('disabled');
 | 
						||
            }
 | 
						||
        }
 | 
						||
 | 
						||
        function showMessage(message, type = 'success') {
 | 
						||
            const messageArea = document.getElementById('messageArea');
 | 
						||
            const className = type === 'error' ? 'error-message' : 'success-message';
 | 
						||
            messageArea.innerHTML = `<div class="${className}">${message}</div>`;
 | 
						||
            setTimeout(() => {
 | 
						||
                messageArea.innerHTML = '';
 | 
						||
            }, 5000);
 | 
						||
        }
 | 
						||
 | 
						||
        function loadFile() {
 | 
						||
            const fileInput = document.getElementById('fileInput');
 | 
						||
            const file = fileInput.files[0];
 | 
						||
            
 | 
						||
            if (!file) {
 | 
						||
                showMessage('Please select a file', 'error');
 | 
						||
                return;
 | 
						||
            }
 | 
						||
 | 
						||
            const reader = new FileReader();
 | 
						||
            reader.onload = function(e) {
 | 
						||
                try {
 | 
						||
                    yamlData = jsyaml.load(e.target.result);
 | 
						||
                    console.log('Loaded YAML data:', yamlData);
 | 
						||
                    updateUI();
 | 
						||
                    showMessage('File loaded successfully!');
 | 
						||
                } catch (error) {
 | 
						||
                    showMessage('Error parsing YAML: ' + error.message, 'error');
 | 
						||
                }
 | 
						||
            };
 | 
						||
            reader.readAsText(file);
 | 
						||
        }
 | 
						||
 | 
						||
        function loadSampleData() {
 | 
						||
            try {
 | 
						||
                const sampleData = {
 | 
						||
                    tools: [
 | 
						||
                        {
 | 
						||
                            name: "Autopsy",
 | 
						||
                            icon: "📱",
 | 
						||
                            type: "software",
 | 
						||
                            description: "The leading open-source digital forensics platform.",
 | 
						||
                            domains: ["incident-response", "law-enforcement"],
 | 
						||
                            phases: ["examination", "analysis"],
 | 
						||
                            platforms: ["Windows", "Linux"],
 | 
						||
                            skillLevel: "intermediate",
 | 
						||
                            accessType: "download",
 | 
						||
                            url: "https://www.autopsy.com/",
 | 
						||
                            projectUrl: "",
 | 
						||
                            license: "Apache 2.0",
 | 
						||
                            knowledgebase: false,
 | 
						||
                            tags: ["gui", "filesystem", "timeline-analysis", "carving"]
 | 
						||
                        },
 | 
						||
                        {
 | 
						||
                            name: "Live Memory Acquisition Procedure",
 | 
						||
                            icon: "🧠",
 | 
						||
                            type: "method",
 | 
						||
                            description: "Standardized procedure for forensically sound memory acquisition.",
 | 
						||
                            domains: ["incident-response", "law-enforcement"],
 | 
						||
                            phases: ["data-collection"],
 | 
						||
                            platforms: [],
 | 
						||
                            skillLevel: "advanced",
 | 
						||
                            accessType: null,
 | 
						||
                            url: "https://www.nist.gov/publications/guide-integrating-forensic-techniques-incident-response",
 | 
						||
                            projectUrl: null,
 | 
						||
                            license: null,
 | 
						||
                            knowledgebase: false,
 | 
						||
                            tags: ["memory-acquisition", "volatile-evidence", "procedure"]
 | 
						||
                        }
 | 
						||
                    ],
 | 
						||
                    domains: [
 | 
						||
                        { id: "incident-response", name: "Incident Response & Breach Investigation" },
 | 
						||
                        { id: "law-enforcement", name: "Law Enforcement & Criminal Investigation" },
 | 
						||
                        { id: "malware-analysis", name: "Malware Analysis & Reverse Engineering" }
 | 
						||
                    ],
 | 
						||
                    phases: [
 | 
						||
                        { id: "data-collection", name: "Data Collection", description: "Imaging, Acquisition, Remote Collection Tools" },
 | 
						||
                        { id: "examination", name: "Examination", description: "Parsing, Extraction, Initial Analysis Tools" },
 | 
						||
                        { id: "analysis", name: "Analysis", description: "Deep Analysis, Correlation, Visualization Tools" },
 | 
						||
                        { id: "reporting", name: "Reporting", description: "Documentation, Visualization, Presentation Tools" }
 | 
						||
                    ],
 | 
						||
                    "domain-agnostic-software": [
 | 
						||
                        { id: "collaboration-general", name: "Collaboration & General", description: "Cross-cutting tools and collaboration platforms" },
 | 
						||
                        { id: "specific-os", name: "Operating Systems", description: "Operating Systems which focus on forensics" }
 | 
						||
                    ]
 | 
						||
                };
 | 
						||
                yamlData = sampleData;
 | 
						||
                updateUI();
 | 
						||
                showMessage('Sample data loaded successfully!');
 | 
						||
            } catch (error) {
 | 
						||
                showMessage('Error loading sample data: ' + error.message, 'error');
 | 
						||
            }
 | 
						||
        }
 | 
						||
 | 
						||
        function updateUI() {
 | 
						||
            if (!yamlData) return;
 | 
						||
 | 
						||
            // Show stats section
 | 
						||
            document.getElementById('statsSection').classList.remove('hidden');
 | 
						||
 | 
						||
            // Update statistics
 | 
						||
            updateStats();
 | 
						||
            
 | 
						||
            // Update checkboxes
 | 
						||
            updateDomainCheckboxes();
 | 
						||
            updatePhaseCheckboxes();
 | 
						||
            updateDomainAgnosticCheckboxes();
 | 
						||
            
 | 
						||
            // Render tools grid
 | 
						||
            renderToolsGrid();
 | 
						||
        }
 | 
						||
 | 
						||
        function updateStats() {
 | 
						||
            if (!yamlData || !yamlData.tools) return;
 | 
						||
 | 
						||
            const tools = yamlData.tools;
 | 
						||
            document.getElementById('totalTools').textContent = tools.length;
 | 
						||
            
 | 
						||
            const softwareCount = tools.filter(tool => tool.type === 'software').length;
 | 
						||
            const methodCount = tools.filter(tool => tool.type === 'method').length;
 | 
						||
            document.getElementById('softwareCount').textContent = softwareCount;
 | 
						||
            document.getElementById('methodCount').textContent = methodCount;
 | 
						||
            
 | 
						||
            document.getElementById('totalDomains').textContent = yamlData.domains ? yamlData.domains.length : 0;
 | 
						||
            document.getElementById('totalPhases').textContent = yamlData.phases ? yamlData.phases.length : 0;
 | 
						||
            document.getElementById('totalDomainAgnostic').textContent = yamlData['domain-agnostic-software'] ? yamlData['domain-agnostic-software'].length : 0;
 | 
						||
            
 | 
						||
            const selfHosted = tools.filter(tool => tool.accessType === 'server-based').length;
 | 
						||
            document.getElementById('selfHostedCount').textContent = selfHosted;
 | 
						||
 | 
						||
            const knowledgebaseTools = tools.filter(tool => tool.knowledgebase === true).length;
 | 
						||
            document.getElementById('knowledgebaseCount').textContent = knowledgebaseTools;
 | 
						||
 | 
						||
            // Update analytics
 | 
						||
            updateTagAnalytics();
 | 
						||
            updateSkillDistribution();
 | 
						||
        }
 | 
						||
 | 
						||
        function updateTagAnalytics() {
 | 
						||
            const tagCounts = {};
 | 
						||
            
 | 
						||
            if (yamlData && yamlData.tools) {
 | 
						||
                yamlData.tools.forEach(tool => {
 | 
						||
                    if (tool.tags && Array.isArray(tool.tags)) {
 | 
						||
                        tool.tags.forEach(tag => {
 | 
						||
                            tagCounts[tag] = (tagCounts[tag] || 0) + 1;
 | 
						||
                        });
 | 
						||
                    }
 | 
						||
                });
 | 
						||
            }
 | 
						||
 | 
						||
            const container = document.getElementById('tagAnalytics');
 | 
						||
            
 | 
						||
            if (Object.keys(tagCounts).length === 0) {
 | 
						||
                container.innerHTML = '<p style="color: #7f8c8d; font-style: italic;">No tags found</p>';
 | 
						||
                return;
 | 
						||
            }
 | 
						||
 | 
						||
            const sortedTags = Object.entries(tagCounts).sort((a, b) => b[1] - a[1]);
 | 
						||
            
 | 
						||
            container.innerHTML = sortedTags.map(([tag, count]) => `
 | 
						||
                <div class="tag-stat" onclick="searchForTag('${tag}')">
 | 
						||
                    <span class="tag-name">${tag}</span>
 | 
						||
                    <span class="tag-count">${count}</span>
 | 
						||
                </div>
 | 
						||
            `).join('');
 | 
						||
        }
 | 
						||
 | 
						||
        function updateSkillDistribution() {
 | 
						||
            const skillCounts = { novice: 0, beginner: 0, intermediate: 0, advanced: 0, expert: 0 };
 | 
						||
            
 | 
						||
            if (yamlData && yamlData.tools) {
 | 
						||
                yamlData.tools.forEach(tool => {
 | 
						||
                    const skill = tool.skillLevel || 'intermediate';
 | 
						||
                    if (skillCounts.hasOwnProperty(skill)) {
 | 
						||
                        skillCounts[skill]++;
 | 
						||
                    }
 | 
						||
                });
 | 
						||
            }
 | 
						||
 | 
						||
            const total = Object.values(skillCounts).reduce((sum, count) => sum + count, 0);
 | 
						||
            const container = document.getElementById('skillDistribution');
 | 
						||
            
 | 
						||
            if (total === 0) {
 | 
						||
                container.innerHTML = '<p style="color: #7f8c8d; font-style: italic;">No skill data available</p>';
 | 
						||
                return;
 | 
						||
            }
 | 
						||
 | 
						||
            container.innerHTML = Object.entries(skillCounts).map(([skill, count]) => {
 | 
						||
                const percentage = total > 0 ? (count / total) * 100 : 0;
 | 
						||
                return `
 | 
						||
                    <div class="skill-bar">
 | 
						||
                        <div class="skill-label">${skill}</div>
 | 
						||
                        <div class="skill-progress">
 | 
						||
                            <div class="skill-fill ${skill}" style="width: ${percentage}%"></div>
 | 
						||
                        </div>
 | 
						||
                        <div class="skill-count">${count}</div>
 | 
						||
                    </div>
 | 
						||
                `;
 | 
						||
            }).join('');
 | 
						||
        }
 | 
						||
 | 
						||
        function searchForTag(tag) {
 | 
						||
            showTab('tools');
 | 
						||
            document.querySelector('[onclick="showTab(\'tools\')"]').classList.add('active');
 | 
						||
            document.getElementById('searchBar').value = tag;
 | 
						||
            filterTools();
 | 
						||
        }
 | 
						||
 | 
						||
        function updateDomainCheckboxes() {
 | 
						||
            const container = document.getElementById('domainsCheckbox');
 | 
						||
            container.innerHTML = '';
 | 
						||
            
 | 
						||
            if (yamlData.domains) {
 | 
						||
                yamlData.domains.forEach(domain => {
 | 
						||
                    const div = document.createElement('div');
 | 
						||
                    div.className = 'checkbox-item';
 | 
						||
                    div.innerHTML = `
 | 
						||
                        <input type="checkbox" id="domain-${domain.id}" value="${domain.id}">
 | 
						||
                        <label for="domain-${domain.id}">${domain.name}</label>
 | 
						||
                    `;
 | 
						||
                    container.appendChild(div);
 | 
						||
                });
 | 
						||
            }
 | 
						||
        }
 | 
						||
 | 
						||
        function updatePhaseCheckboxes() {
 | 
						||
            const container = document.getElementById('phasesCheckbox');
 | 
						||
            container.innerHTML = '';
 | 
						||
            
 | 
						||
            if (yamlData.phases) {
 | 
						||
                yamlData.phases.forEach(phase => {
 | 
						||
                    const div = document.createElement('div');
 | 
						||
                    div.className = 'checkbox-item';
 | 
						||
                    div.innerHTML = `
 | 
						||
                        <input type="checkbox" id="phase-${phase.id}" value="${phase.id}">
 | 
						||
                        <label for="phase-${phase.id}">${phase.name}</label>
 | 
						||
                    `;
 | 
						||
                    container.appendChild(div);
 | 
						||
                });
 | 
						||
            }
 | 
						||
        }
 | 
						||
 | 
						||
        function updateDomainAgnosticCheckboxes() {
 | 
						||
            const container = document.getElementById('domainAgnosticCheckbox');
 | 
						||
            container.innerHTML = '';
 | 
						||
            
 | 
						||
            if (yamlData['domain-agnostic-software']) {
 | 
						||
                yamlData['domain-agnostic-software'].forEach(category => {
 | 
						||
                    const div = document.createElement('div');
 | 
						||
                    div.className = 'checkbox-item';
 | 
						||
                    div.innerHTML = `
 | 
						||
                        <input type="checkbox" id="domain-agnostic-${category.id}" value="${category.id}">
 | 
						||
                        <label for="domain-agnostic-${category.id}">${category.name}</label>
 | 
						||
                    `;
 | 
						||
                    container.appendChild(div);
 | 
						||
                });
 | 
						||
            }
 | 
						||
        }
 | 
						||
 | 
						||
        function renderToolsGrid() {
 | 
						||
            const container = document.getElementById('toolsGrid');
 | 
						||
            container.innerHTML = '';
 | 
						||
            
 | 
						||
            if (!yamlData || !yamlData.tools) return;
 | 
						||
 | 
						||
            yamlData.tools.forEach((tool, index) => {
 | 
						||
                const card = createToolCard(tool, index);
 | 
						||
                container.appendChild(card);
 | 
						||
            });
 | 
						||
        }
 | 
						||
 | 
						||
        function renderBulkGrid() {
 | 
						||
            const container = document.getElementById('bulkToolsGrid');
 | 
						||
            container.innerHTML = '';
 | 
						||
            
 | 
						||
            if (!yamlData || !yamlData.tools) return;
 | 
						||
 | 
						||
            yamlData.tools.forEach((tool, index) => {
 | 
						||
                const card = createBulkToolCard(tool, index);
 | 
						||
                container.appendChild(card);
 | 
						||
            });
 | 
						||
 | 
						||
            updateSelectionCount();
 | 
						||
        }
 | 
						||
 | 
						||
        function createToolCard(tool, index) {
 | 
						||
            const card = document.createElement('div');
 | 
						||
            card.className = `tool-card ${tool.type || 'software'}`;
 | 
						||
            
 | 
						||
            const skillClass = `skill-${tool.skillLevel || 'intermediate'}`;
 | 
						||
            const tags = (tool.tags || []).map(tag => `<span class="tag">${tag}</span>`).join('');
 | 
						||
            const knowledgebaseIndicator = tool.knowledgebase ? '<span class="tag" style="background: #e8f5e8; color: #27ae60; font-weight: bold;">📚 Knowledgebase</span>' : '';
 | 
						||
            const typeIndicator = `<span class="type-badge type-${tool.type || 'software'}">${tool.type || 'software'}</span>`;
 | 
						||
            
 | 
						||
            // Add domain-agnostic indicators
 | 
						||
            const domainAgnosticTags = (tool['domain-agnostic-software'] || []).map(cat => {
 | 
						||
                const categoryName = getDomainAgnosticName(cat);
 | 
						||
                return `<span class="tag domain-agnostic">🔧 ${categoryName}</span>`;
 | 
						||
            }).join('');
 | 
						||
            
 | 
						||
            card.innerHTML = `
 | 
						||
                <h3>
 | 
						||
                    ${tool.icon ? `<span class="tool-icon">${tool.icon}</span>` : ''}
 | 
						||
                    ${tool.name}
 | 
						||
                    ${typeIndicator}
 | 
						||
                </h3>
 | 
						||
                <div style="margin: 5px 0;">
 | 
						||
                    <div class="skill-badge ${skillClass}">${tool.skillLevel || 'intermediate'}</div>
 | 
						||
                    ${knowledgebaseIndicator}
 | 
						||
                </div>
 | 
						||
                <p>${tool.description}</p>
 | 
						||
                <div style="margin: 10px 0;">${tags}${domainAgnosticTags}</div>
 | 
						||
                <div style="margin-top: 15px;">
 | 
						||
                    <button class="btn" onclick="editTool(${index})">✏️ Edit</button>
 | 
						||
                    <button class="btn btn-danger" onclick="confirmDelete(${index})">🗑️ Delete</button>
 | 
						||
                </div>
 | 
						||
            `;
 | 
						||
            
 | 
						||
            return card;
 | 
						||
        }
 | 
						||
 | 
						||
        function createBulkToolCard(tool, index) {
 | 
						||
            const card = document.createElement('div');
 | 
						||
            card.className = `tool-card ${tool.type || 'software'}`;
 | 
						||
            
 | 
						||
            const skillClass = `skill-${tool.skillLevel || 'intermediate'}`;
 | 
						||
            const isSelected = selectedTools.has(index);
 | 
						||
            const knowledgebaseIndicator = tool.knowledgebase ? '<span class="tag" style="background: #e8f5e8; color: #27ae60; font-weight: bold; margin-left: 10px;">📚 KB</span>' : '';
 | 
						||
            const typeIndicator = `<span class="type-badge type-${tool.type || 'software'}" style="margin-left: 10px;">${tool.type || 'software'}</span>`;
 | 
						||
            
 | 
						||
            card.innerHTML = `
 | 
						||
                <div style="display: flex; align-items: center; gap: 10px; margin-bottom: 10px;">
 | 
						||
                    <input type="checkbox" ${isSelected ? 'checked' : ''} onchange="toggleToolSelection(${index})" />
 | 
						||
                    <h3 style="margin: 0; display: flex; align-items: center; gap: 8px;">
 | 
						||
                        ${tool.icon ? `<span class="tool-icon">${tool.icon}</span>` : ''}
 | 
						||
                        ${tool.name}
 | 
						||
                    </h3>
 | 
						||
                    ${typeIndicator}
 | 
						||
                    ${knowledgebaseIndicator}
 | 
						||
                </div>
 | 
						||
                <div class="skill-badge ${skillClass}">${tool.skillLevel || 'intermediate'}</div>
 | 
						||
                <p>${tool.description}</p>
 | 
						||
            `;
 | 
						||
            
 | 
						||
            if (isSelected) {
 | 
						||
                card.style.border = '2px solid #3498db';
 | 
						||
                card.style.backgroundColor = '#f8f9ff';
 | 
						||
            }
 | 
						||
            
 | 
						||
            return card;
 | 
						||
        }
 | 
						||
 | 
						||
        function getDomainAgnosticName(id) {
 | 
						||
            if (!yamlData['domain-agnostic-software']) return id;
 | 
						||
            const category = yamlData['domain-agnostic-software'].find(cat => cat.id === id);
 | 
						||
            return category ? category.name : id;
 | 
						||
        }
 | 
						||
 | 
						||
        function filterTools() {
 | 
						||
            const searchTerm = document.getElementById('searchBar').value.toLowerCase();
 | 
						||
            const cards = document.querySelectorAll('#toolsGrid .tool-card');
 | 
						||
            
 | 
						||
            if (!yamlData || !yamlData.tools) return;
 | 
						||
            
 | 
						||
            cards.forEach((card, index) => {
 | 
						||
                const tool = yamlData.tools[index];
 | 
						||
                
 | 
						||
                const searchableText = [
 | 
						||
                    tool.name || '',
 | 
						||
                    tool.description || '',
 | 
						||
                    tool.type || '',
 | 
						||
                    ...(tool.tags || []),
 | 
						||
                    ...(tool.domains || []),
 | 
						||
                    ...(tool.phases || []),
 | 
						||
                    ...(tool.platforms || []),
 | 
						||
                    ...(tool['domain-agnostic-software'] || []),
 | 
						||
                    tool.skillLevel || '',
 | 
						||
                    tool.license || '',
 | 
						||
                    tool.accessType || '',
 | 
						||
                    tool.knowledgebase ? 'knowledgebase' : ''
 | 
						||
                ].join(' ').toLowerCase();
 | 
						||
                
 | 
						||
                if (searchableText.includes(searchTerm)) {
 | 
						||
                    card.style.display = '';
 | 
						||
                } else {
 | 
						||
                    card.style.display = 'none';
 | 
						||
                }
 | 
						||
            });
 | 
						||
        }
 | 
						||
 | 
						||
        function editTool(index) {
 | 
						||
            currentEditingIndex = index;
 | 
						||
            const tool = yamlData.tools[index];
 | 
						||
            
 | 
						||
            showTab('editor');
 | 
						||
            document.querySelector('[onclick="showTab(\'editor\')"]').classList.add('active');
 | 
						||
            
 | 
						||
            document.getElementById('editorTitle').textContent = `Edit Tool: ${tool.name}`;
 | 
						||
            document.getElementById('deleteBtn').style.display = 'inline-block';
 | 
						||
            
 | 
						||
            // Populate form fields
 | 
						||
            document.getElementById('toolName').value = tool.name || '';
 | 
						||
            document.getElementById('toolType').value = tool.type || 'software';
 | 
						||
            document.getElementById('toolIcon').value = tool.icon || '';
 | 
						||
            document.getElementById('description').value = tool.description || '';
 | 
						||
            document.getElementById('skillLevel').value = tool.skillLevel || '';
 | 
						||
            document.getElementById('url').value = tool.url || '';
 | 
						||
            document.getElementById('projectUrl').value = tool.projectUrl || '';
 | 
						||
            document.getElementById('license').value = tool.license || '';
 | 
						||
            document.getElementById('accessType').value = tool.accessType || '';
 | 
						||
            document.getElementById('statusUrl').value = tool.statusUrl || '';
 | 
						||
            document.getElementById('knowledgebase').checked = tool.knowledgebase || false;
 | 
						||
            
 | 
						||
            // Handle conditional fields
 | 
						||
            handleTypeChange();
 | 
						||
            
 | 
						||
            // Set checkboxes
 | 
						||
            setCheckboxValues('#platformsCheckbox input', tool.platforms || []);
 | 
						||
            setCheckboxValues('#domainsCheckbox input', tool.domains || []);
 | 
						||
            setCheckboxValues('#phasesCheckbox input', tool.phases || []);
 | 
						||
            setCheckboxValues('#domainAgnosticCheckbox input', tool['domain-agnostic-software'] || []);
 | 
						||
            
 | 
						||
            populateTags(tool.tags || []);
 | 
						||
        }
 | 
						||
 | 
						||
        function setCheckboxValues(selector, values) {
 | 
						||
            document.querySelectorAll(selector).forEach(checkbox => {
 | 
						||
                checkbox.checked = values.includes(checkbox.value);
 | 
						||
            });
 | 
						||
        }
 | 
						||
 | 
						||
        function populateTags(tags) {
 | 
						||
            const container = document.getElementById('tagContainer');
 | 
						||
            container.querySelectorAll('.removable-tag').forEach(tag => tag.remove());
 | 
						||
            
 | 
						||
            tags.forEach(tag => {
 | 
						||
                addTag(tag);
 | 
						||
            });
 | 
						||
        }
 | 
						||
 | 
						||
        function addTagOnEnter(event) {
 | 
						||
            if (event.key === 'Enter') {
 | 
						||
                event.preventDefault();
 | 
						||
                const input = event.target;
 | 
						||
                const tag = input.value.trim();
 | 
						||
                if (tag) {
 | 
						||
                    addTag(tag);
 | 
						||
                    input.value = '';
 | 
						||
                }
 | 
						||
            }
 | 
						||
        }
 | 
						||
 | 
						||
        function addTag(tagText) {
 | 
						||
            const container = document.getElementById('tagContainer');
 | 
						||
            const input = container.querySelector('.tag-input');
 | 
						||
            
 | 
						||
            const tagElement = document.createElement('span');
 | 
						||
            tagElement.className = 'removable-tag';
 | 
						||
            tagElement.innerHTML = `
 | 
						||
                ${tagText}
 | 
						||
                <span class="remove-tag" onclick="removeTag(this)">×</span>
 | 
						||
            `;
 | 
						||
            
 | 
						||
            container.insertBefore(tagElement, input);
 | 
						||
        }
 | 
						||
 | 
						||
        function removeTag(element) {
 | 
						||
            element.parentElement.remove();
 | 
						||
        }
 | 
						||
 | 
						||
        function saveTool() {
 | 
						||
            try {
 | 
						||
                if (!yamlData) {
 | 
						||
                    yamlData = { tools: [], domains: [], phases: [], 'domain-agnostic-software': [] };
 | 
						||
                }
 | 
						||
                if (!yamlData.tools) {
 | 
						||
                    yamlData.tools = [];
 | 
						||
                }
 | 
						||
 | 
						||
                const toolType = document.getElementById('toolType').value;
 | 
						||
                const tool = {
 | 
						||
                    name: document.getElementById('toolName').value,
 | 
						||
                    type: toolType,
 | 
						||
                    description: document.getElementById('description').value,
 | 
						||
                    domains: getCheckedValues('#domainsCheckbox input:checked'),
 | 
						||
                    phases: getCheckedValues('#phasesCheckbox input:checked'),
 | 
						||
                    skillLevel: document.getElementById('skillLevel').value,
 | 
						||
                    url: document.getElementById('url').value,
 | 
						||
                    tags: getTags()
 | 
						||
                };
 | 
						||
 | 
						||
                // Add icon if provided
 | 
						||
                const icon = document.getElementById('toolIcon').value.trim();
 | 
						||
                if (icon) {
 | 
						||
                    tool.icon = icon;
 | 
						||
                }
 | 
						||
 | 
						||
                // Add software-specific fields
 | 
						||
                if (toolType === 'software') {
 | 
						||
                    tool.platforms = getCheckedValues('#platformsCheckbox input:checked');
 | 
						||
                    tool.accessType = document.getElementById('accessType').value;
 | 
						||
                    tool.projectUrl = document.getElementById('projectUrl').value;
 | 
						||
                    tool.license = document.getElementById('license').value;
 | 
						||
                    tool.knowledgebase = document.getElementById('knowledgebase').checked;
 | 
						||
                    
 | 
						||
                    const statusUrl = document.getElementById('statusUrl').value;
 | 
						||
                    if (statusUrl) {
 | 
						||
                        tool.statusUrl = statusUrl;
 | 
						||
                    }
 | 
						||
                } else {
 | 
						||
                    // For methods, set appropriate defaults
 | 
						||
                    tool.platforms = [];
 | 
						||
                    tool.accessType = null;
 | 
						||
                    tool.projectUrl = null;
 | 
						||
                    tool.license = null;
 | 
						||
                    tool.knowledgebase = false;
 | 
						||
                }
 | 
						||
 | 
						||
                // Add domain-agnostic software if selected
 | 
						||
                const domainAgnostic = getCheckedValues('#domainAgnosticCheckbox input:checked');
 | 
						||
                if (domainAgnostic.length > 0) {
 | 
						||
                    tool['domain-agnostic-software'] = domainAgnostic;
 | 
						||
                } else {
 | 
						||
                    tool['domain-agnostic-software'] = null;
 | 
						||
                }
 | 
						||
 | 
						||
                // Clean up empty arrays and null values
 | 
						||
                Object.keys(tool).forEach(key => {
 | 
						||
                    if (Array.isArray(tool[key]) && tool[key].length === 0) {
 | 
						||
                        if (key === 'platforms' && toolType === 'method') {
 | 
						||
                            tool[key] = []; // Keep empty array for methods
 | 
						||
                        } else {
 | 
						||
                            delete tool[key];
 | 
						||
                        }
 | 
						||
                    } else if (tool[key] === '' || tool[key] === null) {
 | 
						||
                        if ((key === 'accessType' || key === 'projectUrl' || key === 'license') && toolType === 'method') {
 | 
						||
                            tool[key] = null; // Keep null for methods
 | 
						||
                        } else {
 | 
						||
                            delete tool[key];
 | 
						||
                        }
 | 
						||
                    }
 | 
						||
                });
 | 
						||
 | 
						||
                if (currentEditingIndex >= 0) {
 | 
						||
                    yamlData.tools[currentEditingIndex] = tool;
 | 
						||
                    showMessage('Tool updated successfully!');
 | 
						||
                } else {
 | 
						||
                    yamlData.tools.push(tool);
 | 
						||
                    showMessage('Tool added successfully!');
 | 
						||
                }
 | 
						||
 | 
						||
                clearForm();
 | 
						||
                updateStats();
 | 
						||
                renderToolsGrid();
 | 
						||
            } catch (error) {
 | 
						||
                showMessage('Error saving tool: ' + error.message, 'error');
 | 
						||
            }
 | 
						||
        }
 | 
						||
 | 
						||
        function getCheckedValues(selector) {
 | 
						||
            return Array.from(document.querySelectorAll(selector)).map(checkbox => checkbox.value);
 | 
						||
        }
 | 
						||
 | 
						||
        function getTags() {
 | 
						||
            const tags = [];
 | 
						||
            document.querySelectorAll('#tagContainer .removable-tag').forEach(tagElement => {
 | 
						||
                const text = tagElement.textContent.replace('×', '').trim();
 | 
						||
                if (text) tags.push(text);
 | 
						||
            });
 | 
						||
            return tags;
 | 
						||
        }
 | 
						||
 | 
						||
        function clearForm() {
 | 
						||
            document.getElementById('toolForm').reset();
 | 
						||
            document.getElementById('tagContainer').querySelectorAll('.removable-tag').forEach(tag => tag.remove());
 | 
						||
            document.getElementById('editorTitle').textContent = 'Add New Tool';
 | 
						||
            document.getElementById('deleteBtn').style.display = 'none';
 | 
						||
            document.getElementById('softwareFields').classList.remove('disabled');
 | 
						||
            currentEditingIndex = -1;
 | 
						||
        }
 | 
						||
 | 
						||
        function confirmDelete(index) {
 | 
						||
            if (confirm(`Are you sure you want to delete "${yamlData.tools[index].name}"?`)) {
 | 
						||
                deleteTool(index);
 | 
						||
            }
 | 
						||
        }
 | 
						||
 | 
						||
        function deleteTool(index = currentEditingIndex) {
 | 
						||
            if (index >= 0 && yamlData && yamlData.tools) {
 | 
						||
                yamlData.tools.splice(index, 1);
 | 
						||
                clearForm();
 | 
						||
                updateStats();
 | 
						||
                renderToolsGrid();
 | 
						||
                showMessage('Tool deleted successfully!');
 | 
						||
            }
 | 
						||
        }
 | 
						||
 | 
						||
        // Bulk operations
 | 
						||
        function toggleToolSelection(index) {
 | 
						||
            if (selectedTools.has(index)) {
 | 
						||
                selectedTools.delete(index);
 | 
						||
            } else {
 | 
						||
                selectedTools.add(index);
 | 
						||
            }
 | 
						||
            updateSelectionCount();
 | 
						||
            renderBulkGrid();
 | 
						||
        }
 | 
						||
 | 
						||
        function selectAllTools() {
 | 
						||
            if (yamlData && yamlData.tools) {
 | 
						||
                yamlData.tools.forEach((_, index) => selectedTools.add(index));
 | 
						||
                updateSelectionCount();
 | 
						||
                renderBulkGrid();
 | 
						||
            }
 | 
						||
        }
 | 
						||
 | 
						||
        function selectByType(type) {
 | 
						||
            if (yamlData && yamlData.tools) {
 | 
						||
                yamlData.tools.forEach((tool, index) => {
 | 
						||
                    if (tool.type === type) {
 | 
						||
                        selectedTools.add(index);
 | 
						||
                    }
 | 
						||
                });
 | 
						||
                updateSelectionCount();
 | 
						||
                renderBulkGrid();
 | 
						||
            }
 | 
						||
        }
 | 
						||
 | 
						||
        function clearSelection() {
 | 
						||
            selectedTools.clear();
 | 
						||
            updateSelectionCount();
 | 
						||
            renderBulkGrid();
 | 
						||
        }
 | 
						||
 | 
						||
        function updateSelectionCount() {
 | 
						||
            document.getElementById('selectionCount').textContent = `${selectedTools.size} selected`;
 | 
						||
        }
 | 
						||
 | 
						||
        function showIconSuggestions() {
 | 
						||
            const suggestions = `DFIR Tool Icons by Operational Mode:
 | 
						||
 | 
						||
📦 Downloaded/Installed    🌐 Web Application    ☁️ Cloud Service
 | 
						||
🖥️ Operating System       ⌨️ Command Line      📡 Server/Self-hosted
 | 
						||
🔧 Hardware Tool          💰 Commercial        ⚙️ Built-in/System  
 | 
						||
📱 Mobile Application     🔗 API/Library       📋 Method/Procedure
 | 
						||
 | 
						||
🖲️ Remote Access         💻 Desktop GUI       🛠️ Utility/Helper
 | 
						||
🏢 Enterprise Platform   🔓 Open Source       🎯 Specialized Tool
 | 
						||
📊 Analysis Platform     🗄️ Database/Storage  🔄 Processing Engine
 | 
						||
 | 
						||
Most common combinations:
 | 
						||
📦 + 🔓 = Open Source Desktop Software
 | 
						||
🌐 + ☁️ = Cloud Web Application  
 | 
						||
🖥️ + 🔓 = Forensic Live OS
 | 
						||
⌨️ + 🔧 = Command Line Utility
 | 
						||
📋 + 🎯 = Specialized Method
 | 
						||
 | 
						||
Click any emoji to copy it, then paste into the icon field.`;
 | 
						||
            
 | 
						||
            alert(suggestions);
 | 
						||
        }
 | 
						||
 | 
						||
        function bulkUpdateIcons() {
 | 
						||
            if (selectedTools.size === 0) {
 | 
						||
                showMessage('No tools selected', 'error');
 | 
						||
                return;
 | 
						||
            }
 | 
						||
 | 
						||
            // Show operational mode-focused icon suggestions
 | 
						||
            const suggestedIcons = `
 | 
						||
DFIR Tool Icons by Operational Mode:
 | 
						||
 | 
						||
📦 Downloaded/Installed    🌐 Web Application    ☁️ Cloud Service
 | 
						||
🖥️ Operating System       ⌨️ Command Line      📡 Server/Self-hosted
 | 
						||
🔧 Hardware Tool          💰 Commercial        ⚙️ Built-in/System  
 | 
						||
📱 Mobile Application     🔗 API/Library       📋 Method/Procedure
 | 
						||
 | 
						||
🖲️ Remote Access         💻 Desktop GUI       🛠️ Utility/Helper
 | 
						||
🏢 Enterprise Platform   🔓 Open Source       🎯 Specialized Tool
 | 
						||
📊 Analysis Platform     🗄️ Database/Storage  🔄 Processing Engine
 | 
						||
 | 
						||
Quick suggestions by access type:
 | 
						||
• Downloaded Software: 📦
 | 
						||
• Web Applications: 🌐  
 | 
						||
• Cloud Services: ☁️
 | 
						||
• Operating Systems: 🖥️
 | 
						||
• Command Line: ⌨️
 | 
						||
• Hardware: 🔧
 | 
						||
• Methods/Procedures: 📋`;
 | 
						||
 | 
						||
            const icon = prompt(`Enter emoji icon (single character) or leave empty to remove:\n\n${suggestedIcons}`);
 | 
						||
            
 | 
						||
            if (icon !== null) { // Allow empty string to remove icons
 | 
						||
                const trimmedIcon = icon.trim();
 | 
						||
                if (trimmedIcon.length > 2) {
 | 
						||
                    showMessage('Icon should be a single emoji character', 'error');
 | 
						||
                    return;
 | 
						||
                }
 | 
						||
                
 | 
						||
                selectedTools.forEach(index => {
 | 
						||
                    if (trimmedIcon === '') {
 | 
						||
                        delete yamlData.tools[index].icon; // Remove icon field entirely
 | 
						||
                    } else {
 | 
						||
                        yamlData.tools[index].icon = trimmedIcon;
 | 
						||
                    }
 | 
						||
                });
 | 
						||
                
 | 
						||
                const action = trimmedIcon === '' ? 'removed icons from' : 'updated icons for';
 | 
						||
                showMessage(`Successfully ${action} ${selectedTools.size} tools`);
 | 
						||
                renderBulkGrid();
 | 
						||
                renderToolsGrid(); // Update tools view if visible
 | 
						||
            }
 | 
						||
        }
 | 
						||
 | 
						||
        function bulkUpdateType() {
 | 
						||
            if (selectedTools.size === 0) {
 | 
						||
                showMessage('No tools selected', 'error');
 | 
						||
                return;
 | 
						||
            }
 | 
						||
 | 
						||
            const type = prompt('Enter type (software/method):');
 | 
						||
            if (type && ['software', 'method'].includes(type)) {
 | 
						||
                selectedTools.forEach(index => {
 | 
						||
                    yamlData.tools[index].type = type;
 | 
						||
                    
 | 
						||
                    // Handle method-specific cleanup
 | 
						||
                    if (type === 'method') {
 | 
						||
                        yamlData.tools[index].platforms = [];
 | 
						||
                        yamlData.tools[index].accessType = null;
 | 
						||
                        yamlData.tools[index].projectUrl = null;
 | 
						||
                        yamlData.tools[index].license = null;
 | 
						||
                        yamlData.tools[index].knowledgebase = false;
 | 
						||
                        if (yamlData.tools[index].statusUrl) {
 | 
						||
                            delete yamlData.tools[index].statusUrl;
 | 
						||
                        }
 | 
						||
                    }
 | 
						||
                });
 | 
						||
                showMessage(`Updated type for ${selectedTools.size} tools`);
 | 
						||
                updateStats();
 | 
						||
                renderBulkGrid();
 | 
						||
            }
 | 
						||
        }
 | 
						||
 | 
						||
        function bulkUpdateSkillLevel() {
 | 
						||
            if (selectedTools.size === 0) {
 | 
						||
                showMessage('No tools selected', 'error');
 | 
						||
                return;
 | 
						||
            }
 | 
						||
 | 
						||
            const skillLevel = prompt('Enter skill level (novice/beginner/intermediate/advanced/expert):');
 | 
						||
            if (skillLevel && ['novice','beginner', 'intermediate', 'advanced', 'expert'].includes(skillLevel)) {
 | 
						||
                selectedTools.forEach(index => {
 | 
						||
                    yamlData.tools[index].skillLevel = skillLevel;
 | 
						||
                });
 | 
						||
                showMessage(`Updated skill level for ${selectedTools.size} tools`);
 | 
						||
                renderBulkGrid();
 | 
						||
            }
 | 
						||
        }
 | 
						||
 | 
						||
        function bulkUpdateDomains() {
 | 
						||
            if (selectedTools.size === 0) {
 | 
						||
                showMessage('No tools selected', 'error');
 | 
						||
                return;
 | 
						||
            }
 | 
						||
 | 
						||
            const domains = prompt('Enter domains (comma-separated):');
 | 
						||
            if (domains) {
 | 
						||
                const domainList = domains.split(',').map(d => d.trim()).filter(d => d);
 | 
						||
                selectedTools.forEach(index => {
 | 
						||
                    yamlData.tools[index].domains = domainList;
 | 
						||
                });
 | 
						||
                showMessage(`Updated domains for ${selectedTools.size} tools`);
 | 
						||
                renderBulkGrid();
 | 
						||
            }
 | 
						||
        }
 | 
						||
 | 
						||
        function bulkUpdatePhases() {
 | 
						||
            if (selectedTools.size === 0) {
 | 
						||
                showMessage('No tools selected', 'error');
 | 
						||
                return;
 | 
						||
            }
 | 
						||
 | 
						||
            const phases = prompt('Enter phases (comma-separated):');
 | 
						||
            if (phases) {
 | 
						||
                const phaseList = phases.split(',').map(p => p.trim()).filter(p => p);
 | 
						||
                selectedTools.forEach(index => {
 | 
						||
                    yamlData.tools[index].phases = phaseList;
 | 
						||
                });
 | 
						||
                showMessage(`Updated phases for ${selectedTools.size} tools`);
 | 
						||
                renderBulkGrid();
 | 
						||
            }
 | 
						||
        }
 | 
						||
 | 
						||
        function bulkUpdateDomainAgnostic() {
 | 
						||
            if (selectedTools.size === 0) {
 | 
						||
                showMessage('No tools selected', 'error');
 | 
						||
                return;
 | 
						||
            }
 | 
						||
 | 
						||
            const categories = prompt('Enter domain-agnostic categories (comma-separated):');
 | 
						||
            if (categories) {
 | 
						||
                const categoryList = categories.split(',').map(c => c.trim()).filter(c => c);
 | 
						||
                selectedTools.forEach(index => {
 | 
						||
                    yamlData.tools[index]['domain-agnostic-software'] = categoryList;
 | 
						||
                });
 | 
						||
                showMessage(`Updated domain-agnostic categories for ${selectedTools.size} tools`);
 | 
						||
                renderBulkGrid();
 | 
						||
            }
 | 
						||
        }
 | 
						||
 | 
						||
        function bulkUpdateTags() {
 | 
						||
            if (selectedTools.size === 0) {
 | 
						||
                showMessage('No tools selected', 'error');
 | 
						||
                return;
 | 
						||
            }
 | 
						||
 | 
						||
            const tags = prompt('Enter tags (comma-separated):');
 | 
						||
            if (tags) {
 | 
						||
                const tagList = tags.split(',').map(t => t.trim()).filter(t => t);
 | 
						||
                selectedTools.forEach(index => {
 | 
						||
                    yamlData.tools[index].tags = tagList;
 | 
						||
                });
 | 
						||
                showMessage(`Updated tags for ${selectedTools.size} tools`);
 | 
						||
                updateStats();
 | 
						||
                renderBulkGrid();
 | 
						||
            }
 | 
						||
        }
 | 
						||
 | 
						||
        function bulkSetKnowledgebase(value) {
 | 
						||
            if (selectedTools.size === 0) {
 | 
						||
                showMessage('No tools selected', 'error');
 | 
						||
                return;
 | 
						||
            }
 | 
						||
 | 
						||
            // Only apply to software tools
 | 
						||
            const softwareTools = Array.from(selectedTools).filter(index => 
 | 
						||
                yamlData.tools[index].type === 'software'
 | 
						||
            );
 | 
						||
 | 
						||
            if (softwareTools.length === 0) {
 | 
						||
                showMessage('No software tools selected (knowledgebase only applies to software)', 'error');
 | 
						||
                return;
 | 
						||
            }
 | 
						||
 | 
						||
            const action = value ? 'set as knowledgebase' : 'remove knowledgebase flag from';
 | 
						||
            if (!confirm(`Are you sure you want to ${action} ${softwareTools.length} selected software tools?`)) {
 | 
						||
                return;
 | 
						||
            }
 | 
						||
 | 
						||
            softwareTools.forEach(index => {
 | 
						||
                if (yamlData.tools[index]) {
 | 
						||
                    yamlData.tools[index].knowledgebase = value;
 | 
						||
                }
 | 
						||
            });
 | 
						||
 | 
						||
            const actionCompleted = value ? 'marked as knowledgebase' : 'removed knowledgebase flag from';
 | 
						||
            showMessage(`Successfully ${actionCompleted} ${softwareTools.length} software tools`);
 | 
						||
            
 | 
						||
            updateStats();
 | 
						||
            renderBulkGrid();
 | 
						||
        }
 | 
						||
 | 
						||
        function bulkClearField(fieldName) {
 | 
						||
            if (selectedTools.size === 0) {
 | 
						||
                showMessage('No tools selected', 'error');
 | 
						||
                return;
 | 
						||
            }
 | 
						||
 | 
						||
            const fieldDisplayName = fieldName.charAt(0).toUpperCase() + fieldName.slice(1).replace('-', ' ');
 | 
						||
            if (!confirm(`Are you sure you want to clear ${fieldDisplayName} for ${selectedTools.size} selected tools?`)) {
 | 
						||
                return;
 | 
						||
            }
 | 
						||
 | 
						||
            selectedTools.forEach(index => {
 | 
						||
                if (yamlData.tools[index]) {
 | 
						||
                    const tool = yamlData.tools[index];
 | 
						||
                    const arrayFields = ['tags', 'domains', 'phases', 'platforms', 'domain-agnostic-software'];
 | 
						||
                    
 | 
						||
                    if (arrayFields.includes(fieldName)) {
 | 
						||
                        if (fieldName === 'platforms' && tool.type === 'method') {
 | 
						||
                            tool[fieldName] = []; // Keep empty array for methods
 | 
						||
                        } else {
 | 
						||
                            tool[fieldName] = [];
 | 
						||
                        }
 | 
						||
                    } else if (fieldName === 'icon') {
 | 
						||
                        delete tool.icon; // Remove icon field entirely
 | 
						||
                    } else {
 | 
						||
                        if ((fieldName === 'projectUrl' || fieldName === 'accessType' || fieldName === 'license') && tool.type === 'method') {
 | 
						||
                            tool[fieldName] = null; // Keep null for methods
 | 
						||
                        } else {
 | 
						||
                            tool[fieldName] = '';
 | 
						||
                        }
 | 
						||
                    }
 | 
						||
                }
 | 
						||
            });
 | 
						||
 | 
						||
            showMessage(`Cleared ${fieldDisplayName} for ${selectedTools.size} tools`);
 | 
						||
            
 | 
						||
            if (fieldName === 'tags') {
 | 
						||
                updateStats();
 | 
						||
            }
 | 
						||
            
 | 
						||
            renderBulkGrid();
 | 
						||
            if (fieldName === 'icon') {
 | 
						||
                renderToolsGrid(); // Update tools view to reflect icon changes
 | 
						||
            }
 | 
						||
        }
 | 
						||
 | 
						||
        function bulkDelete() {
 | 
						||
            if (selectedTools.size === 0) {
 | 
						||
                showMessage('No tools selected', 'error');
 | 
						||
                return;
 | 
						||
            }
 | 
						||
 | 
						||
            if (confirm(`Are you sure you want to delete ${selectedTools.size} tools?`)) {
 | 
						||
                const indices = Array.from(selectedTools).sort((a, b) => b - a);
 | 
						||
                indices.forEach(index => {
 | 
						||
                    yamlData.tools.splice(index, 1);
 | 
						||
                });
 | 
						||
                selectedTools.clear();
 | 
						||
                updateStats();
 | 
						||
                renderBulkGrid();
 | 
						||
                showMessage('Tools deleted successfully!');
 | 
						||
            }
 | 
						||
        }
 | 
						||
 | 
						||
        function validateYAML() {
 | 
						||
            if (!yamlData) {
 | 
						||
                showMessage('No data to validate', 'error');
 | 
						||
                return;
 | 
						||
            }
 | 
						||
 | 
						||
            const validationResults = [];
 | 
						||
            
 | 
						||
            // Check required sections
 | 
						||
            if (!yamlData.tools) validationResults.push('❌ Missing tools section');
 | 
						||
            if (!yamlData.domains) validationResults.push('❌ Missing domains section');
 | 
						||
            if (!yamlData.phases) validationResults.push('❌ Missing phases section');
 | 
						||
            
 | 
						||
            // Validate tools
 | 
						||
            if (yamlData.tools) {
 | 
						||
                yamlData.tools.forEach((tool, index) => {
 | 
						||
                    if (!tool.name) validationResults.push(`❌ Tool ${index + 1}: Missing name`);
 | 
						||
                    if (!tool.description) validationResults.push(`❌ Tool ${index + 1}: Missing description`);
 | 
						||
                    if (!tool.skillLevel) validationResults.push(`❌ Tool ${index + 1}: Missing skillLevel`);
 | 
						||
                    if (!tool.type) validationResults.push(`❌ Tool ${index + 1}: Missing type`);
 | 
						||
                    if (tool.type && !['software', 'method'].includes(tool.type)) {
 | 
						||
                        validationResults.push(`❌ Tool ${index + 1}: Invalid type (must be 'software' or 'method')`);
 | 
						||
                    }
 | 
						||
                    
 | 
						||
                    // Software-specific validation
 | 
						||
                    if (tool.type === 'software') {
 | 
						||
                        if (!tool.platforms || tool.platforms.length === 0) {
 | 
						||
                            validationResults.push(`❌ Tool ${index + 1}: Software must have platforms`);
 | 
						||
                        }
 | 
						||
                        if (!tool.license) validationResults.push(`❌ Tool ${index + 1}: Software should have license`);
 | 
						||
                    }
 | 
						||
                    
 | 
						||
                    // Method-specific validation
 | 
						||
                    if (tool.type === 'method') {
 | 
						||
                        if (tool.platforms && tool.platforms.length > 0) {
 | 
						||
                            validationResults.push(`⚠️ Tool ${index + 1}: Methods should not have platforms`);
 | 
						||
                        }
 | 
						||
                    }
 | 
						||
                });
 | 
						||
            }
 | 
						||
 | 
						||
            const container = document.getElementById('validationContent');
 | 
						||
            if (validationResults.length === 0) {
 | 
						||
                container.innerHTML = '<div class="success-message">✅ YAML structure is valid!</div>';
 | 
						||
            } else {
 | 
						||
                container.innerHTML = '<div class="error-message">' + validationResults.join('<br>') + '</div>';
 | 
						||
            }
 | 
						||
            
 | 
						||
            document.getElementById('validationResults').classList.remove('hidden');
 | 
						||
        }
 | 
						||
 | 
						||
        function previewYAML() {
 | 
						||
            if (!yamlData) {
 | 
						||
                showMessage('No data to preview', 'error');
 | 
						||
                return;
 | 
						||
            }
 | 
						||
 | 
						||
            const yamlString = jsyaml.dump(yamlData, { indent: 2 });
 | 
						||
            document.getElementById('yamlPreviewText').value = yamlString;
 | 
						||
            document.getElementById('yamlPreview').classList.remove('hidden');
 | 
						||
        }
 | 
						||
 | 
						||
        function exportYAML() {
 | 
						||
            if (!yamlData) {
 | 
						||
                showMessage('No data to export', 'error');
 | 
						||
                return;
 | 
						||
            }
 | 
						||
 | 
						||
            const yamlString = jsyaml.dump(yamlData, { indent: 2 });
 | 
						||
            const blob = new Blob([yamlString], { type: 'text/yaml' });
 | 
						||
            const url = URL.createObjectURL(blob);
 | 
						||
            
 | 
						||
            const a = document.createElement('a');
 | 
						||
            a.href = url;
 | 
						||
            a.download = 'dfir-tools.yaml';
 | 
						||
            document.body.appendChild(a);
 | 
						||
            a.click();
 | 
						||
            document.body.removeChild(a);
 | 
						||
            URL.revokeObjectURL(url);
 | 
						||
            
 | 
						||
            showMessage('YAML file exported successfully!');
 | 
						||
        }
 | 
						||
    </script>
 | 
						||
</body>
 | 
						||
</html> |