Spaces:
Running
Running
<html lang="en"> | |
<head> | |
<meta charset="UTF-8"> | |
<title>Enhanced ID Generator Tool v6</title> | |
<meta name="viewport" content="width=device-width, initial-scale=1.0"> | |
<!-- Tailwind CSS --> | |
<link href="https://cdn.jsdelivr.net/npm/tailwindcss@2.2.19/dist/tailwind.min.css" rel="stylesheet"> | |
<!-- Font Awesome --> | |
<link href="https://cdn.jsdelivr.net/npm/@fortawesome/fontawesome-free@6.5.2/css/all.min.css" rel="stylesheet"> | |
<!-- Google Fonts --> | |
<link href="https://fonts.googleapis.com/css2?family=Roboto:wght@400;700&display=swap" rel="stylesheet"> | |
<!-- Chart.js --> | |
<script src="https://cdn.jsdelivr.net/npm/chart.js@4.4.3/dist/chart.umd.min.js"></script> | |
<style> | |
html, body { font-family: 'Roboto', sans-serif; background: #f3f4f6; color: #222; scroll-behavior: smooth;} | |
.shadow-card { box-shadow: 0 6px 24px rgb(0 0 0 / 7%),0 1.5px 5px rgb(0 0 0 / 4%);} | |
.admin-divider {border-bottom: 1.5px solid #e5e7eb;} | |
.fa {vertical-align: middle;} | |
/* Hide scrollbars for PDF export */ | |
::-webkit-scrollbar {display: none;} | |
* { scrollbar-width: none; -ms-overflow-style: none;} | |
/* Remove number input arrows for consistency in PDF export*/ | |
input[type=number]::-webkit-inner-spin-button, | |
input[type=number]::-webkit-outer-spin-button { -webkit-appearance: none; margin: 0; } | |
input[type=number] { -moz-appearance: textfield;} | |
/* Card table styles */ | |
#generatedCardsTable th, #generatedCardsTable td, | |
#marketplaceTable th, #marketplaceTable td, | |
#ssnMarketplaceTable th, #ssnMarketplaceTable td, | |
#paymentTestTable th, #paymentTestTable td { | |
padding: 0.25rem 0.5rem; | |
border-right: 1px solid #eee; | |
border-top: 1px solid #eee; | |
} | |
#generatedCardsTable th:last-child, #generatedCardsTable td:last-child, | |
#marketplaceTable th:last-child, #marketplaceTable td:last-child, | |
#ssnMarketplaceTable th:last-child, #ssnMarketplaceTable td:last-child, | |
#paymentTestTable th:last-child, #paymentTestTable td:last-child { | |
border-right: none; | |
} | |
/* Hide file input for a better button */ | |
#importFile {display:none;} | |
.table-wrap {overflow-x: auto;} | |
/* Right sidebar navigation */ | |
.right-sidebar { | |
position: fixed; | |
right: 0; | |
top: 50%; | |
transform: translateY(-50%); | |
z-index: 100; | |
} | |
.right-sidebar-item { | |
padding: 10px; | |
background: rgba(16, 185, 129, 0.9); | |
margin: 5px 0; | |
border-radius: 8px 0 0 8px; | |
transition: all 0.3s; | |
} | |
.right-sidebar-item:hover { | |
padding-right: 15px; | |
background: rgba(5, 150, 105, 1); | |
} | |
/* Bottom navigation */ | |
.bottom-navbar { | |
position: fixed; | |
bottom: 0; | |
left: 0; | |
right: 0; | |
background: rgba(16, 185, 129, 0.9); | |
display: flex; | |
justify-content: center; | |
padding: 10px; | |
z-index: 100; | |
} | |
.bottom-navbar-item { | |
margin: 0 15px; | |
color: white; | |
transition: all 0.3s; | |
} | |
.bottom-navbar-item:hover { | |
transform: scale(1.2); | |
} | |
/* Horizontal sidebar under history section */ | |
.horizontal-sidebar { | |
display: flex; | |
justify-content: center; | |
background: rgba(59, 130, 246, 0.1); | |
border-radius: 8px; | |
padding: 8px; | |
margin: 10px 0; | |
border: 1px solid rgba(59, 130, 246, 0.2); | |
} | |
.horizontal-sidebar-item { | |
margin: 0 15px; | |
color: #3b82f6; | |
transition: all 0.3s; | |
display: flex; | |
align-items: center; | |
font-size: 0.9rem; | |
} | |
.horizontal-sidebar-item:hover { | |
transform: scale(1.1); | |
color: #1d4ed8; | |
} | |
/* Stats dashboard */ | |
.stats-card { | |
background: white; | |
border-radius: 8px; | |
padding: 15px; | |
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1); | |
transition: all 0.3s; | |
} | |
.stats-card:hover { | |
transform: translateY(-5px); | |
box-shadow: 0 6px 12px rgba(0, 0, 0, 0.15); | |
} | |
/* Marketplace section */ | |
.marketplace-toggle { | |
position: relative; | |
display: inline-block; | |
width: 50px; | |
height: 24px; | |
} | |
.marketplace-toggle input { | |
opacity: 0; | |
width: 0; | |
height: 0; | |
} | |
.marketplace-slider { | |
position: absolute; | |
cursor: pointer; | |
top: 0; | |
left: 0; | |
right: 0; | |
bottom: 0; | |
background-color: #ccc; | |
transition: .4s; | |
border-radius: 24px; | |
} | |
.marketplace-slider:before { | |
position: absolute; | |
content: ""; | |
height: 16px; | |
width: 16px; | |
left: 4px; | |
bottom: 4px; | |
background-color: white; | |
transition: .4s; | |
border-radius: 50%; | |
} | |
input:checked + .marketplace-slider { | |
background-color: #10b981; | |
} | |
input:checked + .marketplace-slider:before { | |
transform: translateX(26px); | |
} | |
/* Filter tags */ | |
.filter-tag { | |
display: inline-block; | |
background: #e5e7eb; | |
border-radius: 16px; | |
padding: 4px 12px; | |
margin: 4px; | |
font-size: 0.75rem; | |
cursor: pointer; | |
transition: all 0.2s; | |
} | |
.filter-tag:hover, .filter-tag.active { | |
background: #3b82f6; | |
color: white; | |
} | |
/* Analysis results */ | |
.analysis-badge { | |
display: inline-block; | |
padding: 2px 6px; | |
border-radius: 4px; | |
font-size: 0.7rem; | |
font-weight: bold; | |
margin-right: 4px; | |
} | |
.analysis-badge.low { | |
background-color: #10b981; | |
color: white; | |
} | |
.analysis-badge.high { | |
background-color: #ef4444; | |
color: white; | |
} | |
.analysis-badge.medium { | |
background-color: #f59e0b; | |
color: white; | |
} | |
/* Accordion/Collapse styles */ | |
.accordion-header { | |
cursor: pointer; | |
transition: all 0.3s ease; | |
display: flex; | |
align-items: center; | |
justify-content: space-between; | |
padding: 10px; | |
border-radius: 8px; | |
} | |
.accordion-header:hover { | |
background-color: rgba(59, 130, 246, 0.1); | |
} | |
.accordion-content { | |
max-height: 0; | |
overflow: hidden; | |
transition: max-height 0.3s ease; | |
} | |
.accordion-content.open { | |
max-height: 2000px; | |
} | |
.accordion-icon { | |
transition: transform 0.3s ease; | |
} | |
.accordion-icon.open { | |
transform: rotate(180deg); | |
} | |
/* Slider bar styles */ | |
.slider-container { | |
width: 100%; | |
padding: 10px 0; | |
} | |
.slider { | |
-webkit-appearance: none; | |
width: 100%; | |
height: 8px; | |
border-radius: 5px; | |
background: #d3d3d3; | |
outline: none; | |
opacity: 0.7; | |
-webkit-transition: .2s; | |
transition: opacity .2s; | |
} | |
.slider:hover { | |
opacity: 1; | |
} | |
.slider::-webkit-slider-thumb { | |
-webkit-appearance: none; | |
appearance: none; | |
width: 20px; | |
height: 20px; | |
border-radius: 50%; | |
background: #3b82f6; | |
cursor: pointer; | |
} | |
.slider::-moz-range-thumb { | |
width: 20px; | |
height: 20px; | |
border-radius: 50%; | |
background: #3b82f6; | |
cursor: pointer; | |
} | |
/* Analysis results in marketplace */ | |
.analysis-results { | |
display: flex; | |
flex-wrap: wrap; | |
gap: 4px; | |
margin-top: 4px; | |
} | |
.analysis-result-item { | |
font-size: 0.7rem; | |
padding: 2px 6px; | |
border-radius: 4px; | |
background-color: #f3f4f6; | |
border: 1px solid #e5e7eb; | |
} | |
.validator-result { | |
display: inline-block; | |
padding: 2px 6px; | |
border-radius: 4px; | |
font-size: 0.7rem; | |
font-weight: bold; | |
} | |
.validator-result.live { | |
background-color: #10b981; | |
color: white; | |
} | |
.validator-result.dead { | |
background-color: #ef4444; | |
color: white; | |
} | |
@media print { | |
html, body {background: white;} | |
.print-hide {display: none ;} | |
.right-sidebar, .bottom-navbar, .horizontal-sidebar {display: none ;} | |
} | |
</style> | |
</head> | |
<body> | |
<!-- HEADER --> | |
<header class="flex items-center bg-gradient-to-r from-green-400 to-green-200 p-4 shadow-lg"> | |
<div class="flex items-center space-x-3"> | |
<i class="fa fa-id-card text-2xl text-white"></i> | |
<span class="text-2xl font-bold text-white tracking-wide">Fake ID Data Tools+ v6</span> | |
</div> | |
<button onclick="showAdmin(true)" class="ml-auto px-6 py-2 rounded bg-black text-white font-semibold shadow-card print-hide transition hover:bg-green-800 text-sm"><i class="fas fa-user-cog mr-2"></i>Admin Panel</button> | |
</header> | |
<!-- RIGHT SIDEBAR NAVIGATION --> | |
<div class="right-sidebar print-hide"> | |
<a href="#stats-dashboard" class="right-sidebar-item text-white block"><i class="fas fa-chart-line"></i></a> | |
<a href="#card-generation" class="right-sidebar-item text-white block"><i class="fas fa-credit-card"></i></a> | |
<a href="#cards-history" class="right-sidebar-item text-white block"><i class="fas fa-history"></i></a> | |
<a href="#marketplace-section" class="right-sidebar-item text-white block"><i class="fas fa-shopping-cart"></i></a> | |
<a href="#validator-section" class="right-sidebar-item text-white block"><i class="fas fa-check-circle"></i></a> | |
<a href="#payment-test-section" class="right-sidebar-item text-white block"><i class="fa fa-credit-card-alt"></i></a> | |
<a href="#analyzers-section" class="right-sidebar-item text-white block"><i class="fas fa-flask"></i></a> | |
<a href="#ssn-tools" class="right-sidebar-item text-white block"><i class="fas fa-address-card"></i></a> | |
</div> | |
<!-- BOTTOM NAVIGATION --> | |
<div class="bottom-navbar print-hide"> | |
<a href="#" class="bottom-navbar-item" onclick="window.scrollBy(-300, 0)"><i class="fas fa-arrow-left"></i></a> | |
<a href="#stats-dashboard" class="bottom-navbar-item"><i class="fas fa-chart-line"></i></a> | |
<a href="#card-generation" class="bottom-navbar-item"><i class="fas fa-credit-card"></i></a> | |
<a href="#cards-history" class="bottom-navbar-item"><i class="fas fa-history"></i></a> | |
<a href="#marketplace-section" class="bottom-navbar-item"><i class="fas fa-shopping-cart"></i></a> | |
<a href="#validator-section" class="bottom-navbar-item"><i class="fas fa-check-circle"></i></a> | |
<a href="#payment-test-section" class="bottom-navbar-item"><i class="fa fa-credit-card-alt"></i></a> | |
<a href="#analyzers-section" class="bottom-navbar-item"><i class="fas fa-flask"></i></a> | |
<a href="#ssn-tools" class="bottom-navbar-item"><i class="fas fa-address-card"></i></a> | |
<a href="#" class="bottom-navbar-item" onclick="window.scrollBy(300, 0)"><i class="fas fa-arrow-right"></i></a> | |
</div> | |
<main class="max-w-5xl mx-auto p-4 space-y-6 bg-white mt-6 rounded-lg shadow-card mb-20"> | |
<!-- STATS DASHBOARD --> | |
<section id="stats-dashboard" class="mb-8"> | |
<div class="flex items-center mb-4"> | |
<i class="fa fa-chart-line text-purple-600 mr-2"></i> | |
<h2 class="text-xl font-bold text-purple-800">Dashboard</h2> | |
</div> | |
<div class="grid grid-cols-1 md:grid-cols-4 gap-4"> | |
<div class="stats-card bg-gradient-to-br from-green-50 to-green-100 border border-green-200"> | |
<div class="text-green-800 font-bold mb-1">Total Cards Generated</div> | |
<div class="flex items-center"> | |
<i class="fas fa-credit-card text-green-600 text-3xl mr-3"></i> | |
<span class="text-2xl font-bold" id="statsTotalCards">0</span> | |
</div> | |
</div> | |
<div class="stats-card bg-gradient-to-br from-blue-50 to-blue-100 border border-blue-200"> | |
<div class="text-blue-800 font-bold mb-1">Live/Valid Cards</div> | |
<div class="flex items-center"> | |
<i class="fas fa-check-circle text-blue-600 text-3xl mr-3"></i> | |
<span class="text-2xl font-bold" id="statsLiveCards">0</span> | |
</div> | |
</div> | |
<div class="stats-card bg-gradient-to-br from-yellow-50 to-yellow-100 border border-yellow-200"> | |
<div class="text-yellow-800 font-bold mb-1">Low Fraud Score (<50)</div> | |
<div class="flex items-center"> | |
<i class="fas fa-shield-alt text-yellow-600 text-3xl mr-3"></i> | |
<span class="text-2xl font-bold" id="statsLowFraudCards">0</span> | |
</div> | |
</div> | |
<div class="stats-card bg-gradient-to-br from-purple-50 to-purple-100 border border-purple-200"> | |
<div class="text-purple-800 font-bold mb-1">Total SSNs Generated</div> | |
<div class="flex items-center"> | |
<i class="fas fa-id-card text-purple-600 text-3xl mr-3"></i> | |
<span class="text-2xl font-bold" id="statsTotalSSNs">0</span> | |
</div> | |
</div> | |
</div> | |
</section> | |
<!-- CARD GENERATION --> | |
<section id="card-generation"> | |
<div class="flex items-center mb-2"> | |
<i class="fa fa-credit-card text-green-600 mr-2"></i> | |
<h2 class="text-xl font-bold text-green-800">Card Generation</h2> | |
</div> | |
<div class="rounded bg-green-50 p-4 shadow-card border border-green-200"> | |
<div class="grid md:grid-cols-6 sm:grid-cols-2 grid-cols-1 gap-3 mb-4"> | |
<div><label class="block text-xs mb-1 font-semibold">Card Holder Name</label><input id="holderInput" type="text" class="w-full rounded border px-2 py-1" placeholder="Auto-generated if blank"></div> | |
<div><label class="block text-xs mb-1 font-semibold">Phone Number</label><input id="phoneInput" type="text" class="w-full rounded border px-2 py-1" placeholder="Auto-generated if blank"></div> | |
<div><label class="block text-xs mb-1 font-semibold">Date of Birth</label><input id="dobInput" type="date" class="w-full rounded border px-2 py-1" placeholder="Auto-generated if blank"></div> | |
<div><label class="block text-xs mb-1 font-semibold">Number to Generate <span class="text-gray-400">(max 5000)</span></label><input id="qtyInput" min="1" max="5000" type="number" value="1" class="w-full rounded border px-2 py-1"></div> | |
<div><label class="block text-xs mb-1 font-semibold">BIN Source <span class="text-xs text-blue-500">(6 digits)</span></label><input id="binInput" type="text" class="w-full rounded border px-2 py-1" placeholder="Auto-generated if blank"></div> | |
<div><label class="block text-xs mb-1 font-semibold">Bank Name</label><input id="bankInput" type="text" class="w-full rounded border px-2 py-1" placeholder="Auto-generated if blank"></div> | |
</div> | |
<div class="grid md:grid-cols-3 sm:grid-cols-2 grid-cols-1 gap-3 mb-3"> | |
<div><label class="block text-xs mb-1 font-semibold">Email</label><input id="emailInput" type="text" class="w-full rounded border px-2 py-1" placeholder="Auto-generated if blank"></div> | |
<div><label class="block text-xs mb-1 font-semibold">Address</label><input id="addressInput" type="text" class="w-full rounded border px-2 py-1" placeholder="Auto-generated if blank"></div> | |
<div class="flex items-center mt-7"> | |
<input id="randBinCheck" type="checkbox" class="mr-2"><label for="randBinCheck" class="text-xs font-semibold">System Random BIN</label> | |
</div> | |
</div> | |
<div class="flex flex-wrap space-x-2 mt-2 mb-2 items-center"> | |
<button id="generateBtn" class="bg-green-600 hover:bg-green-700 text-white font-bold rounded-md px-4 py-2 shadow-card flex items-center mb-2"><i class="fa-solid fa-circle-plus mr-2"></i>Generate Cards</button> | |
<label for="importFile" class="bg-blue-400 hover:bg-blue-600 text-white font-bold rounded-md px-4 py-2 shadow-card flex items-center cursor-pointer mb-2"><i class="fa fa-file-upload mr-2"></i>Import Data</label> | |
<input type="file" id="importFile" accept=".txt,.csv,.json,.pdf"> | |
<button onclick="clearHistory()" class="bg-red-400 hover:bg-red-600 text-white font-bold rounded-md px-4 py-2 shadow-card flex items-center mb-2"><i class="fa fa-trash mr-2"></i>Clear History</button> | |
<button onclick="exportHistory('csv')" class="bg-gray-800 hover:bg-gray-900 text-white font-bold rounded-md px-3 py-2 shadow-card flex items-center text-xs mb-2"><i class="fa fa-file-csv mr-2"></i>Export CSV</button> | |
<button onclick="exportHistory('json')" class="bg-gray-800 hover:bg-gray-900 text-white font-bold rounded-md px-3 py-2 shadow-card flex items-center text-xs mb-2"><i class="fa fa-file-code mr-2"></i>Export JSON</button> | |
<button onclick="exportHistory('txt')" class="bg-gray-800 hover:bg-gray-900 text-white font-bold rounded-md px-3 py-2 shadow-card flex items-center text-xs mb-2"><i class="fa fa-file-lines mr-2"></i>Export TXT</button> | |
<button onclick="copyAllCards()" class="bg-purple-400 hover:bg-purple-600 text-white font-bold rounded-md px-3 py-2 shadow-card flex items-center text-xs mb-2"><i class="fa fa-copy mr-2"></i>Copy All Cards</button> | |
</div> | |
</div> | |
</section> | |
<!-- CARDS HISTORY --> | |
<section id="cards-history"> | |
<div class="flex items-center mb-2"> | |
<i class="fa fa-history text-blue-600 mr-2"></i> | |
<h2 class="text-xl font-bold text-blue-800">Generated Cards History</h2> | |
</div> | |
<div class="rounded bg-blue-50 p-4 shadow-card border border-blue-200"> | |
<div class="table-wrap" id="historyTableWrap"> | |
<table class="w-full text-xs" id="generatedCardsTable"> | |
<thead class="bg-blue-100"> | |
<tr> | |
<th class="text-left">Name</th> | |
<th class="text-left">Card Number</th> | |
<th class="text-left">Expiry</th> | |
<th class="text-left">CVV</th> | |
<th class="text-left">Status</th> | |
<th class="text-left">Actions</th> | |
</tr> | |
</thead> | |
<tbody id="historyTableBody"> | |
<!-- History will be displayed here --> | |
</tbody> | |
</table> | |
</div> | |
</div> | |
</section> | |
<!-- HORIZONTAL SIDEBAR --> | |
<div class="horizontal-sidebar print-hide"> | |
<a href="#marketplace-section" class="horizontal-sidebar-item"><i class="fas fa-shopping-cart mr-1"></i>Marketplace</a> | |
<a href="#validator-section" class="horizontal-sidebar-item"><i class="fas fa-check-circle mr-1"></i>Validator</a> | |
<a href="#payment-test-section" class="horizontal-sidebar-item"><i class="fa fa-credit-card-alt mr-1"></i>Payment Test</a> | |
<a href="#analyzers-section" class="horizontal-sidebar-item"><i class="fas fa-flask mr-1"></i>Analyzers</a> | |
<a href="#ssn-tools" class="horizontal-sidebar-item"><i class="fas fa-address-card mr-1"></i>SSN Tools</a> | |
</div> | |
<!-- MARKETPLACE SECTION --> | |
<section id="marketplace-section" class="mb-8"> | |
<div class="flex items-center mb-4"> | |
<i class="fa fa-shopping-cart text-blue-600 mr-2"></i> | |
<h2 class="text-xl font-bold text-blue-800">Card Marketplace</h2> | |
</div> | |
<div class="rounded bg-blue-50 p-4 shadow-card border border-blue-200"> | |
<div class="flex justify-between items-center mb-4"> | |
<div class="flex items-center"> | |
<label class="marketplace-toggle mr-2"> | |
<input type="checkbox" id="marketplaceToggle" onchange="toggleMarketplace(this.checked)"> | |
<span class="marketplace-slider"></span> | |
</label> | |
<span class="text-sm font-semibold">Enable Marketplace</span> | |
</div> | |
<div> | |
<button onclick="clearMarketplace()" class="bg-red-400 hover:bg-red-600 text-white font-bold rounded-md px-3 py-1 shadow-card flex items-center text-xs"> | |
<i class="fa fa-trash mr-1"></i>Clear Marketplace | |
</button> | |
</div> | |
</div> | |
<!-- FRAUD SCORE FILTER FOR MARKETPLACE --> | |
<div class="mb-4 bg-white p-3 rounded-lg shadow-sm"> | |
<h3 class="text-lg font-semibold mb-3 text-blue-700">Fraud Score Filter</h3> | |
<div class="grid grid-cols-1 md:grid-cols-2 gap-4"> | |
<div> | |
<label class="block text-xs mb-1 font-semibold">Minimum Fraud Score</label> | |
<input id="minFraudScore" type="range" min="0" max="100" value="0" class="slider w-full" oninput="document.getElementById('minFraudScoreValue').textContent = this.value"> | |
<div class="text-xs text-gray-600 mt-1">Min: <span id="minFraudScoreValue">0</span></div> | |
</div> | |
<div> | |
<label class="block text-xs mb-1 font-semibold">Maximum Fraud Score</label> | |
<input id="maxFraudScore" type="range" min="0" max="100" value="100" class="slider w-full" oninput="document.getElementById('maxFraudScoreValue').textContent = this.value"> | |
<div class="text-xs text-gray-600 mt-1">Max: <span id="maxFraudScoreValue">100</span></div> | |
</div> | |
</div> | |
<div class="mt-3 flex space-x-2"> | |
<button onclick="filterByFraudScore()" class="bg-blue-600 hover:bg-blue-700 text-white font-bold rounded-md px-3 py-1 shadow-card flex items-center text-xs"> | |
<i class="fa fa-filter mr-1"></i>Apply Filter | |
</button> | |
<button onclick="resetFraudScoreFilter()" class="bg-gray-500 hover:bg-gray-600 text-white font-bold rounded-md px-3 py-1 shadow-card flex items-center text-xs"> | |
<i class="fa fa-undo mr-1"></i>Reset | |
</button> | |
<div class="flex items-center ml-2"> | |
<button id="lowFraudScoreBtn" onclick="setLowFraudScore()" class="bg-green-500 hover:bg-green-600 text-white font-bold rounded-md px-2 py-1 shadow-card flex items-center text-xs mr-1"> | |
<i class="fa fa-shield-alt mr-1"></i>Low Risk | |
</button> | |
<button id="highFraudScoreBtn" onclick="setHighFraudScore()" class="bg-red-500 hover:bg-red-600 text-white font-bold rounded-md px-2 py-1 shadow-card flex items-center text-xs"> | |
<i class="fa fa-exclamation-triangle mr-1"></i>High Risk | |
</button> | |
</div> | |
</div> | |
</div> | |
<div class="mb-4"> | |
<label class="block text-xs mb-1 font-semibold">Filter by Card Type:</label> | |
<div id="marketplaceFilterTags" class="flex flex-wrap"> | |
<!-- Filter tags will be added here --> | |
</div> | |
</div> | |
<div class="table-wrap" id="marketplaceTableWrap"> | |
<table class="w-full text-xs" id="marketplaceTable"> | |
<thead class="bg-blue-100"> | |
<tr> | |
<th class="text-left">Card Number</th> | |
<th class="text-left">Holder</th> | |
<th class="text-left">Expiry</th> | |
<th class="text-left">CVV</th> | |
<th class="text-left">Type</th> | |
<th class="text-left">Bank</th> | |
<th class="text-left">Status</th> | |
<th class="text-left">Fraud Score</th> | |
<th class="text-left">Actions</th> | |
</tr> | |
</thead> | |
<tbody id="marketplaceTableBody"> | |
<!-- Marketplace items will be displayed here --> | |
</tbody> | |
</table> | |
</div> | |
</div> | |
</section> | |
<!-- VALIDATOR SECTION --> | |
<section id="validator-section" class="mb-8"> | |
<div class="flex items-center mb-2"> | |
<i class="fa fa-check-circle text-teal-600 mr-2"></i> | |
<h2 class="text-xl font-bold text-teal-800">Card Validator</h2> | |
</div> | |
<div class="rounded bg-teal-50 p-4 shadow-card border border-teal-200"> | |
<div class="mb-3"> | |
<label class="block text-xs mb-1 font-semibold">Enter Card Number(s)</label> | |
<textarea id="validateInput" class="w-full rounded border px-2 py-1" rows="4" placeholder="Enter card numbers, one per line or separated by space/comma/pipe"></textarea> | |
</div> | |
<button onclick="validateCards()" class="bg-teal-600 hover:bg-teal-700 text-white font-bold rounded-md px-4 py-2 shadow-card flex items-center"> | |
<i class="fa fa-check mr-2"></i>Validate Cards | |
</button> | |
<div id="validateResults" class="mt-4 space-y-2"> | |
<!-- Validation results will be displayed here --> | |
</div> | |
</div> | |
</section> | |
<!-- PAYMENT PROCESSING TEST SECTION --> | |
<section id="payment-test-section" class="mb-8"> | |
<div class="flex items-center mb-4"> | |
<i class="fa fa-credit-card-alt text-indigo-600 mr-2"></i> | |
<h2 class="text-xl font-bold text-indigo-800">Payment Processing Test</h2> | |
</div> | |
<div class="rounded bg-indigo-50 p-4 shadow-card border border-indigo-200"> | |
<div class="grid md:grid-cols-2 grid-cols-1 gap-4 mb-4"> | |
<div> | |
<div class="bg-white p-4 rounded-lg shadow-sm"> | |
<h3 class="text-lg font-semibold mb-3 text-indigo-700">Card Information</h3> | |
<div class="grid grid-cols-1 gap-3"> | |
<div> | |
<label class="block text-xs mb-1 font-semibold">Card Number</label> | |
<input id="paymentCardNumber" type="text" class="w-full rounded border px-2 py-1" placeholder="Card number"> | |
</div> | |
<div class="grid grid-cols-3 gap-2"> | |
<div> | |
<label class="block text-xs mb-1 font-semibold">Month</label> | |
<input id="paymentCardMonth" type="text" class="w-full rounded border px-2 py-1" placeholder="MM"> | |
</div> | |
<div> | |
<label class="block text-xs mb-1 font-semibold">Year</label> | |
<input id="paymentCardYear" type="text" class="w-full rounded border px-2 py-1" placeholder="YY"> | |
</div> | |
<div> | |
<label class="block text-xs mb-1 font-semibold">CVV</label> | |
<input id="paymentCardCVV" type="text" class="w-full rounded border px-2 py-1" placeholder="CVV"> | |
</div> | |
</div> | |
<div> | |
<label class="block text-xs mb-1 font-semibold">Card Holder Name</label> | |
<input id="paymentCardHolder" type="text" class="w-full rounded border px-2 py-1" placeholder="Card holder name"> | |
</div> | |
</div> | |
</div> | |
</div> | |
<div> | |
<div class="bg-white p-4 rounded-lg shadow-sm"> | |
<h3 class="text-lg font-semibold mb-3 text-indigo-700">Payment Details</h3> | |
<div class="grid grid-cols-1 gap-3"> | |
<div> | |
<label class="block text-xs mb-1 font-semibold">Amount</label> | |
<input id="paymentAmount" type="text" class="w-full rounded border px-2 py-1" value="1.00" placeholder="Amount"> | |
</div> | |
<div> | |
<label class="block text-xs mb-1 font-semibold">Currency</label> | |
<select id="paymentCurrency" class="w-full rounded border px-2 py-1"> | |
<option value="USD">USD</option> | |
<option value="EUR">EUR</option> | |
<option value="GBP">GBP</option> | |
<option value="CAD">CAD</option> | |
<option value="AUD">AUD</option> | |
</select> | |
</div> | |
<div> | |
<label class="block text-xs mb-1 font-semibold">Description</label> | |
<input id="paymentDescription" type="text" class="w-full rounded border px-2 py-1" value="Test Payment" placeholder="Description"> | |
</div> | |
</div> | |
</div> | |
</div> | |
</div> | |
<div class="flex flex-wrap space-x-2 mt-4 mb-2 items-center"> | |
<button id="processPaymentBtn" class="bg-indigo-600 hover:bg-indigo-700 text-white font-bold rounded-md px-4 py-2 shadow-card flex items-center mb-2"> | |
<i class="fa fa-credit-card mr-2"></i>Process Payment | |
</button> | |
<button id="testSelectedCardBtn" class="bg-blue-600 hover:bg-blue-700 text-white font-bold rounded-md px-4 py-2 shadow-card flex items-center mb-2"> | |
<i class="fa fa-check-circle mr-2"></i>Test Selected Card | |
</button> | |
<button id="testAllCardsBtn" class="bg-purple-600 hover:bg-purple-700 text-white font-bold rounded-md px-4 py-2 shadow-card flex items-center mb-2"> | |
<i class="fa fa-list-check mr-2"></i>Test All Generated Cards | |
</button> | |
<div class="flex items-center ml-2"> | |
<input id="autoTestCheck" type="checkbox" class="mr-2"> | |
<label for="autoTestCheck" class="text-xs font-semibold">Auto-test cards after generation</label> | |
</div> | |
</div> | |
<div id="paymentResult" class="mt-4 p-4 rounded-lg hidden"> | |
<!-- Payment result will be displayed here --> | |
</div> | |
<div class="mt-6"> | |
<h3 class="text-lg font-semibold mb-3 text-indigo-700">Payment Test Results</h3> | |
<div class="table-wrap" id="paymentTestTableWrap"> | |
<table class="w-full text-xs" id="paymentTestTable"> | |
<thead class="bg-indigo-100"> | |
<tr> | |
<th class="text-left">Card Number</th> | |
<th class="text-left">Holder</th> | |
<th class="text-left">Expiry</th> | |
<th class="text-left">Amount</th> | |
<th class="text-left">Status</th> | |
<th class="text-left">Message</th> | |
<th class="text-left">Timestamp</th> | |
</tr> | |
</thead> | |
<tbody id="paymentTestTableBody"> | |
<!-- Payment test results will be displayed here --> | |
</tbody> | |
</table> | |
</div> | |
</div> | |
</div> | |
</section> | |
<!-- ANALYZERS SECTION --> | |
<section id="analyzers-section" class="mb-8"> | |
<div class="flex items-center mb-2"> | |
<i class="fa fa-flask text-orange-600 mr-2"></i> | |
<h2 class="text-xl font-bold text-orange-800">Card Analyzers</h2> | |
</div> | |
<div class="rounded bg-orange-50 p-4 shadow-card border border-orange-200"> | |
<div class="grid grid-cols-1 md:grid-cols-2 gap-4"> | |
<!-- BIN Analyzer --> | |
<div> | |
<h3 class="text-lg font-semibold mb-3 text-orange-700">BIN Analyzer</h3> | |
<div class="mb-3"> | |
<label class="block text-xs mb-1 font-semibold">Enter BIN (6 digits)</label> | |
<input id="binAnalyzeInput" type="text" class="w-full rounded border px-2 py-1" placeholder="e.g., 453910"> | |
</div> | |
<button onclick="analyzeBin()" class="bg-orange-600 hover:bg-orange-700 text-white font-bold rounded-md px-4 py-2 shadow-card flex items-center"> | |
<i class="fa fa-search mr-2"></i>Analyze BIN | |
</button> | |
<div id="binAnalyzeResult" class="mt-4 text-sm"> | |
<!-- BIN analysis result will be displayed here --> | |
</div> | |
</div> | |
<!-- Fraud Score Analyzer --> | |
<div> | |
<h3 class="text-lg font-semibold mb-3 text-orange-700">Fraud Score Analyzer</h3> | |
<div class="mb-3"> | |
<label class="block text-xs mb-1 font-semibold">Enter Card Number</label> | |
<input id="fraudScoreInput" type="text" class="w-full rounded border px-2 py-1" placeholder="Enter full card number"> | |
</div> | |
<button onclick="analyzeFraudScore()" class="bg-orange-600 hover:bg-orange-700 text-white font-bold rounded-md px-4 py-2 shadow-card flex items-center"> | |
<i class="fa fa-shield-alt mr-2"></i>Analyze Score | |
</button> | |
<div id="fraudScoreResult" class="mt-4 text-sm"> | |
<!-- Fraud score analysis result will be displayed here --> | |
</div> | |
</div> | |
</div> | |
</div> | |
</section> | |
<!-- SSN TOOLS SECTION --> | |
<section id="ssn-tools" class="mb-8"> | |
<div class="flex items-center mb-4"> | |
<i class="fa fa-address-card text-purple-600 mr-2"></i> | |
<h2 class="text-xl font-bold text-purple-800">SSN Tools</h2> | |
</div> | |
<div class="rounded bg-purple-50 p-4 shadow-card border border-purple-200 space-y-6"> | |
<!-- SSN Validator --> | |
<div class="bg-white p-3 rounded-lg shadow-sm"> | |
<h3 class="text-lg font-semibold mb-3 text-purple-700">SSN Validator</h3> | |
<div class="mb-3"> | |
<label class="block text-xs mb-1 font-semibold">Enter SSN(s)</label> | |
<textarea id="ssnValidateInput" class="w-full rounded border px-2 py-1" rows="3" placeholder="Enter SSNs, one per line or separated by space/comma/pipe"></textarea> | |
</div> | |
<button onclick="validateSSNs()" class="bg-purple-600 hover:bg-purple-700 text-white font-bold rounded-md px-4 py-1 shadow-card flex items-center"> | |
<i class="fa fa-check mr-2"></i>Validate SSNs | |
</button> | |
<div id="ssnValidateResults" class="mt-3 space-y-1 text-sm"> | |
<!-- SSN Validation results will be displayed here --> | |
</div> | |
</div> | |
<!-- STATE SSN GENERATION SECTION --> | |
<div class="bg-white p-3 rounded-lg shadow-sm"> | |
<h3 class="text-lg font-semibold mb-3 text-purple-700">State-Specific SSN Generation</h3> | |
<div class="grid grid-cols-1 md:grid-cols-3 gap-4"> | |
<div> | |
<label class="block text-xs mb-1 font-semibold">State</label> | |
<select id="ssnStateSelect" class="w-full rounded border px-2 py-1"> | |
<option value="Alabama">Alabama</option> | |
<option value="Alaska">Alaska</option> | |
<option value="Arizona">Arizona</option> | |
<option value="Arkansas">Arkansas</option> | |
<option value="California">California</option> | |
<option value="Colorado">Colorado</option> | |
<option value="Connecticut">Connecticut</option> | |
<option value="Delaware">Delaware</option> | |
<option value="Random">Random (Other States)</option> | |
</select> | |
<p class="text-xs text-gray-600 mt-1"> | |
<span id="alabamaSSNInfo">Alabama (2011): 416-65-0001 to 424-67-9999</span> | |
<span id="alaskaSSNInfo" class="hidden">Alaska (2011): 574-61-0001 to 574-61-9999</span> | |
<span id="arizonaSSNInfo" class="hidden">Arizona (2011): 764-23-0001 to 765-29-9999</span> | |
<span id="arkansasSSNInfo" class="hidden">Arkansas (2011): 676-20-0001 to 679-22-9999</span> | |
<span id="californiaSSNInfo" class="hidden">California (2011): 602-83-0001 to 626-87-9999</span> | |
<span id="coloradoSSNInfo" class="hidden">Colorado (2011): 650-58-0001 to 653-62-9999</span> | |
<span id="connecticutSSNInfo" class="hidden">Connecticut (2011): 040-13-0001 to 049-15-9999</span> | |
<span id="delawareSSNInfo" class="hidden">Delaware (2011): 221-11-0001 to 222-13-9999</span> | |
</p> | |
</div> | |
<div> | |
<label class="block text-xs mb-1 font-semibold">Number of SSNs to Generate</label> | |
<input id="stateSSNCount" type="number" min="1" max="100" value="1" class="w-full rounded border px-2 py-1"> | |
</div> | |
<div class="flex items-end"> | |
<button onclick="generateStateSSNs()" class="bg-purple-600 hover:bg-purple-700 text-white font-bold rounded-md px-4 py-1 shadow-card flex items-center"> | |
<i class="fa fa-id-card mr-2"></i>Generate State SSNs | |
</button> | |
</div> | |
</div> | |
</div> | |
<!-- SSN AUTO-GENERATION SECTION --> | |
<div class="bg-white p-3 rounded-lg shadow-sm"> | |
<h3 class="text-lg font-semibold mb-3 text-purple-700">SSN Auto-Generation</h3> | |
<div class="grid grid-cols-1 md:grid-cols-3 gap-4"> | |
<div> | |
<label class="block text-xs mb-1 font-semibold">State for Auto-Generation</label> | |
<select id="autoGenStateSelect" class="w-full rounded border px-2 py-1"> | |
<option value="Alabama">Alabama</option> | |
<option value="Alaska">Alaska</option> | |
<option value="Arizona">Arizona</option> | |
<option value="Arkansas">Arkansas</option> | |
<option value="California">California</option> | |
<option value="Colorado">Colorado</option> | |
<option value="Connecticut">Connecticut</option> | |
<option value="Delaware">Delaware</option> | |
<option value="Random">Random (Other States)</option> | |
</select> | |
</div> | |
<div> | |
<label class="block text-xs mb-1 font-semibold">Generation Interval (ms)</label> | |
<input id="autoGenInterval" type="number" min="500" max="10000" value="1000" class="w-full rounded border px-2 py-1"> | |
<p class="text-xs text-gray-600 mt-1">Minimum: 500ms, Maximum: 10000ms</p> | |
</div> | |
<div class="flex items-end"> | |
<button id="startAutoGenBtn" class="bg-green-600 hover:bg-green-700 text-white font-bold rounded-md px-4 py-1 shadow-card flex items-center"> | |
<i class="fa fa-play mr-2"></i>Start Auto-Generation | |
</button> | |
<button id="stopAutoGenBtn" class="bg-red-600 hover:bg-red-700 text-white font-bold rounded-md px-4 py-1 shadow-card flex items-center ml-2 hidden"> | |
<i class="fa fa-stop mr-2"></i>Stop | |
</button> | |
</div> | |
</div> | |
<div class="mt-3"> | |
<div id="autoGenStatus" class="text-sm text-gray-600">Ready to start auto-generation</div> | |
<div class="mt-2"> | |
<button id="removeDuplicatesBtn" class="bg-purple-600 hover:bg-purple-700 text-white font-bold rounded-md px-3 py-1 shadow-card flex items-center text-sm"> | |
<i class="fa fa-broom mr-1"></i>Remove Duplicate SSNs | |
</button> | |
</div> | |
</div> | |
</div> | |
<!-- SSN MARKETPLACE SECTION --> | |
<div class="bg-white p-3 rounded-lg shadow-sm"> | |
<h3 class="text-lg font-semibold mb-3 text-purple-700">SSN Marketplace</h3> | |
<div class="grid grid-cols-1 md:grid-cols-3 gap-4 mb-4"> | |
<div> | |
<label class="block text-xs mb-1 font-semibold">Search SSN</label> | |
<input id="ssnSearchInput" type="text" class="w-full rounded border px-2 py-1" placeholder="Search by SSN or state"> | |
</div> | |
<div> | |
<label class="block text-xs mb-1 font-semibold">Filter by State</label> | |
<select id="ssnStateFilter" class="w-full rounded border px-2 py-1"> | |
<option value="">All States</option> | |
<option value="Alabama">Alabama</option> | |
<option value="Alaska">Alaska</option> | |
<option value="Arizona">Arizona</option> | |
<option value="Arkansas">Arkansas</option> | |
<option value="California">California</option> | |
<option value="Colorado">Colorado</option> | |
<option value="Connecticut">Connecticut</option> | |
<option value="Delaware">Delaware</option> | |
<option value="Random">Random (Other States)</option> | |
</select> | |
</div> | |
<div class="flex items-end"> | |
<button onclick="filterSSNMarketplace()" class="bg-purple-600 hover:bg-purple-700 text-white font-bold rounded-md px-3 py-1 shadow-card flex items-center text-sm"> | |
<i class="fa fa-filter mr-1"></i>Apply Filter | |
</button> | |
<button onclick="resetSSNFilters()" class="bg-gray-500 hover:bg-gray-600 text-white font-bold rounded-md px-3 py-1 shadow-card flex items-center text-sm ml-2"> | |
<i class="fa fa-undo mr-1"></i>Reset | |
</button> | |
</div> | |
</div> | |
<div class="table-wrap" id="ssnMarketplaceTableWrap"> | |
<table class="w-full text-xs" id="ssnMarketplaceTable"> | |
<thead class="bg-purple-100"> | |
<tr> | |
<th class="text-left">SSN</th> | |
<th class="text-left">State</th> | |
<th class="text-left">Issue Date</th> | |
<th class="text-left">Validation</th> | |
<th class="text-left">Actions</th> | |
</tr> | |
</thead> | |
<tbody id="ssnMarketplaceTableBody"> | |
<!-- SSN marketplace items will be displayed here --> | |
</tbody> | |
</table> | |
</div> | |
<div class="mt-4 flex justify-between items-center"> | |
<div> | |
<span class="text-sm text-gray-600">Total SSNs: <span id="totalSSNsInMarketplace">0</span></span> | |
</div> | |
<div> | |
<button onclick="exportSSNs('csv')" class="bg-gray-800 hover:bg-gray-900 text-white font-bold rounded-md px-3 py-1 shadow-card flex items-center text-xs"> | |
<i class="fa fa-file-csv mr-1"></i>Export CSV | |
</button> | |
</div> | |
</div> | |
</div> | |
</div> | |
</section> | |
<!-- ADMIN PANEL (Initially Hidden) --> | |
<div id="adminPanel" class="fixed inset-0 bg-gray-800 bg-opacity-75 flex justify-center items-center z-50 hidden print-hide"> | |
<div class="bg-white rounded-lg shadow-xl p-6 w-full max-w-2xl relative max-h-screen overflow-y-auto"> | |
<button onclick="showAdmin(false)" class="absolute top-3 right-3 text-gray-500 hover:text-gray-700"><i class="fas fa-times fa-lg"></i></button> | |
<h2 class="text-2xl font-bold mb-4 text-gray-800">Admin Panel</h2> | |
<!-- Settings Section --> | |
<div class="mb-6"> | |
<h3 class="text-xl font-semibold mb-3 text-gray-700">Settings</h3> | |
<div class="grid grid-cols-1 md:grid-cols-2 gap-4"> | |
<div> | |
<label class="block text-sm font-medium text-gray-600 mb-1">Theme</label> | |
<select id="themeSelect" class="w-full rounded border px-2 py-1"> | |
<option value="default">Default</option> | |
<option value="hacker">Hacker</option> | |
<option value="matrix">Matrix</option> | |
<option value="dark">Dark</option> | |
</select> | |
</div> | |
<div> | |
<label class="block text-sm font-medium text-gray-600 mb-1">Font Color</label> | |
<input id="fontColorInput" type="color" value="#222222" class="w-full rounded border p-1 h-8"> | |
</div> | |
</div> | |
<button onclick="applyAdminSettings()" class="mt-3 bg-blue-600 hover:bg-blue-700 text-white font-bold rounded-md px-4 py-1 shadow-card flex items-center text-sm"> | |
<i class="fas fa-save mr-1"></i>Apply Settings | |
</button> | |
</div> | |
<div class="admin-divider my-6"></div> | |
<!-- User Metrics Section --> | |
<div class="mb-6"> | |
<h3 class="text-xl font-semibold mb-3 text-gray-700">User Metrics</h3> | |
<div class="grid grid-cols-1 md:grid-cols-3 gap-4 text-center"> | |
<div class="bg-gray-100 p-3 rounded"> | |
<div class="text-gray-600 text-sm">Total Cards Generated</div> | |
<div class="text-xl font-bold" id="adminTotalCards">0</div> | |
</div> | |
<div class="bg-gray-100 p-3 rounded"> | |
<div class="text-gray-600 text-sm">Live Cards</div> | |
<div class="text-xl font-bold" id="adminLiveCards">0</div> | |
</div> | |
<div class="bg-gray-100 p-3 rounded"> | |
<div class="text-gray-600 text-sm">Total SSNs Generated</div> | |
<div class="text-xl font-bold" id="adminTotalSSNs">0</div> | |
</div> | |
</div> | |
</div> | |
<div class="admin-divider my-6"></div> | |
<!-- Crypto Rates Section --> | |
<div> | |
<h3 class="text-xl font-semibold mb-3 text-gray-700">Crypto Rates</h3> | |
<div id="cryptoRates" class="grid grid-cols-2 md:grid-cols-4 gap-2 text-xs"> | |
<!-- Crypto rates will be loaded here --> | |
Loading rates... | |
</div> | |
</div> | |
</div> | |
</div> | |
</main> | |
<script> | |
// Helper function to get element by ID | |
const el = (id) => document.getElementById(id); | |
// Global variables | |
let cards = []; | |
let marketplaceCards = []; | |
let isMarketplaceEnabled = false; | |
let activeMarketplaceFilter = 'all'; | |
let totalCardsGenerated = 0; | |
let totalSSNsGenerated = 0; | |
let ssnMarketplace = []; | |
let paymentTestResults = []; | |
let autoGenInterval = null; | |
let autoGenCount = 0; | |
// --- Core Card Generation Logic --- | |
const genRandom = (len) => { | |
let ret = ''; | |
for (let i = 0; i < len; i++) { | |
ret += Math.floor(Math.random() * 10); | |
} | |
return ret; | |
}; | |
const luhnChk = (cardNo) => { | |
let nDigits = cardNo.length; | |
let nSum = 0; | |
let isSecond = false; | |
for (let i = nDigits - 1; i >= 0; i--) { | |
let d = cardNo[i].charCodeAt() - '0'.charCodeAt(); | |
if (isSecond == true) d = d * 2; | |
nSum += parseInt(d / 10, 10); | |
nSum += d % 10; | |
isSecond = !isSecond; | |
} | |
return (nSum % 10 == 0); | |
}; | |
const genCC = (bin) => { | |
let card = bin + genRandom(16 - bin.length - 1); | |
for (let i = 0; i < 10; i++) { | |
if (luhnChk(card + i)) { | |
return card + i; | |
} | |
} | |
return card + '0'; // Fallback, should rarely happen | |
}; | |
const genExp = () => { | |
let month = Math.floor(Math.random() * 12) + 1; | |
let year = new Date().getFullYear() + Math.floor(Math.random() * 5) + 2; // Expire in 2-6 years | |
return { mm: String(month).padStart(2, '0'), yy: String(year).slice(-2) }; | |
}; | |
const genCVV = () => genRandom(3); | |
// --- Data Generation (Names, Addresses, etc.) --- | |
const firstNames = ["James", "Mary", "John", "Patricia", "Robert", "Jennifer", "Michael", "Linda", "William", "Elizabeth", "David", "Barbara", "Richard", "Susan", "Joseph", "Jessica", "Thomas", "Sarah", "Charles", "Karen"]; | |
const lastNames = ["Smith", "Johnson", "Williams", "Brown", "Jones", "Garcia", "Miller", "Davis", "Rodriguez", "Martinez", "Hernandez", "Lopez", "Gonzalez", "Wilson", "Anderson", "Thomas", "Taylor", "Moore", "Martin", "Jackson"]; | |
const streets = ["Main St", "Oak St", "Pine St", "Maple Ave", "Cedar Ln", "Elm St", "Washington Ave", "Lake St", "Hill St", "Park Ave"]; | |
const cities = ["New York", "Los Angeles", "Chicago", "Houston", "Phoenix", "Philadelphia", "San Antonio", "San Diego", "Dallas", "San Jose"]; | |
const states = ["NY", "CA", "IL", "TX", "AZ", "PA", "TX", "CA", "TX", "CA"]; | |
const genName = () => `${firstNames[Math.floor(Math.random() * firstNames.length)]} ${lastNames[Math.floor(Math.random() * lastNames.length)]}`; | |
const genPhone = () => `${genRandom(3)}-${genRandom(3)}-${genRandom(4)}`; | |
const genDOB = () => { | |
const year = new Date().getFullYear() - (Math.floor(Math.random() * 50) + 18); // Age 18-67 | |
const month = Math.floor(Math.random() * 12) + 1; | |
const day = Math.floor(Math.random() * 28) + 1; // Simple day generation | |
return `${year}-${String(month).padStart(2, '0')}-${String(day).padStart(2, '0')}`; | |
}; | |
const genEmail = (name) => `${name.toLowerCase().replace(' ', '.')}@${['gmail.com', 'yahoo.com', 'outlook.com'][Math.floor(Math.random() * 3)]}`; | |
const genAddress = () => `${Math.floor(Math.random() * 1000) + 1} ${streets[Math.floor(Math.random() * streets.length)]}, ${cities[Math.floor(Math.random() * cities.length)]}, ${states[Math.floor(Math.random() * states.length)]} ${genRandom(5)}`; | |
const genSSN = () => `${genRandom(3)}-${genRandom(2)}-${genRandom(4)}`; | |
// --- BIN Data and Card Type Detection --- | |
const binData = { | |
'4': { type: 'Visa', bank: 'Various Banks' }, '453910': { type: 'Visa', bank: 'Bank of America' }, '455608': { type: 'Visa', bank: 'Chase' }, '491642': { type: 'Visa', bank: 'Wells Fargo' }, | |
'5': { type: 'Mastercard', bank: 'Various Banks' }, '510000': { type: 'Mastercard', bank: 'Capital One' }, '549833': { type: 'Mastercard', bank: 'Citi' }, '557919': { type: 'Mastercard', bank: 'Bank of America' }, | |
'34': { type: 'American Express', bank: 'American Express' }, '37': { type: 'American Express', bank: 'American Express' }, '371445': { type: 'American Express', bank: 'American Express' }, | |
'6011': { type: 'Discover', bank: 'Discover' }, '65': { type: 'Discover', bank: 'Discover' }, '601100': { type: 'Discover', bank: 'Discover' }, | |
'35': { type: 'JCB', bank: 'JCB' }, '352800': { type: 'JCB', bank: 'JCB' }, | |
'30': { type: 'Diners Club', bank: 'Diners Club' }, '36': { type: 'Diners Club', bank: 'Diners Club' }, '38': { type: 'Diners Club', bank: 'Diners Club' }, '300000': { type: 'Diners Club', bank: 'Diners Club' }, | |
}; | |
const famousBins = ['453910', '455608', '491642', '510000', '549833', '557919', '371445', '601100', '352800', '300000']; | |
const getCardInfo = (bin) => { | |
for (let len = 6; len >= 1; len--) { | |
let prefix = bin.substring(0, len); | |
if (binData[prefix]) { | |
return binData[prefix]; | |
} | |
} | |
return { type: 'Unknown', bank: 'Unknown Bank' }; | |
}; | |
// --- History Management --- | |
const loadHistory = () => { | |
const savedCards = localStorage.getItem("cards"); | |
if (savedCards) cards = JSON.parse(savedCards); | |
const savedTotal = localStorage.getItem("totalCardsGenerated"); | |
if (savedTotal) totalCardsGenerated = parseInt(savedTotal); | |
const savedSSNTotal = localStorage.getItem("totalSSNsGenerated"); | |
if (savedSSNTotal) totalSSNsGenerated = parseInt(savedSSNTotal); | |
}; | |
const saveHistory = () => { | |
localStorage.setItem("cards", JSON.stringify(cards)); | |
localStorage.setItem("totalCardsGenerated", totalCardsGenerated); | |
localStorage.setItem("totalSSNsGenerated", totalSSNsGenerated); | |
}; | |
const renderHistory = () => { | |
const tbody = el('historyTableBody'); | |
tbody.innerHTML = ''; | |
if (cards.length === 0) { | |
tbody.innerHTML = '<tr><td colspan="6" class="text-center py-4 text-gray-500">No cards generated yet.</td></tr>'; | |
return; | |
} | |
cards.forEach((card, index) => { | |
const row = document.createElement('tr'); | |
row.className = index % 2 === 0 ? 'bg-white' : 'bg-blue-50'; | |
row.setAttribute('data-card-number', card.number); | |
const statusClass = card.status === 'LIVE' ? 'bg-green-100 text-green-800' : (card.status === 'DEAD' ? 'bg-red-100 text-red-800' : 'bg-gray-100 text-gray-800'); | |
const statusText = card.status || 'UNKNOWN'; | |
row.innerHTML = ` | |
<td>${card.name || '-'}</td> | |
<td>${card.number}</td> | |
<td>${card.mm}/${card.yy}</td> | |
<td>${card.cvv}</td> | |
<td><span class="px-2 py-1 rounded ${statusClass}">${statusText}</span></td> | |
<td> | |
<button onclick="copyCardDetails(${index})" class="bg-blue-500 hover:bg-blue-600 text-white rounded px-2 py-1 text-xs"><i class="fas fa-copy mr-1"></i>Copy</button> | |
<button onclick="deleteCard(${index})" class="bg-red-500 hover:bg-red-600 text-white rounded px-2 py-1 text-xs ml-1"><i class="fas fa-trash mr-1"></i>Delete</button> | |
</td> | |
`; | |
tbody.appendChild(row); | |
}); | |
updateStatsDisplay(); | |
}; | |
const clearHistory = () => { | |
if (confirm('Are you sure you want to clear all generated card history?')) { | |
cards = []; | |
totalCardsGenerated = 0; | |
saveHistory(); | |
renderHistory(); | |
renderMarketplace(); | |
updateStatsDisplay(); | |
} | |
}; | |
const deleteCard = (index) => { | |
cards.splice(index, 1); | |
saveHistory(); | |
renderHistory(); | |
renderMarketplace(); // Update marketplace if card is removed | |
}; | |
const copyCardDetails = (index) => { | |
const card = cards[index]; | |
const details = `Name: ${card.name}\nNumber: ${card.number}\nExpiry: ${card.mm}/${card.yy}\nCVV: ${card.cvv}\nAddress: ${card.address}\nPhone: ${card.phone}\nEmail: ${card.email}\nDOB: ${card.dob}\nSSN: ${card.ssn}\nBank: ${card.bank}`; | |
navigator.clipboard.writeText(details).then(() => { | |
alert('Card details copied to clipboard.'); | |
}); | |
}; | |
const copyAllCards = () => { | |
if (cards.length === 0) { | |
alert('No cards to copy.'); | |
return; | |
} | |
const allDetails = cards.map(card => `${card.number}|${card.mm}|${card.yy}|${card.cvv}`).join('\n'); | |
navigator.clipboard.writeText(allDetails).then(() => { | |
alert(`Copied ${cards.length} cards (number|mm|yy|cvv) to clipboard.`); | |
}); | |
}; | |
// --- Marketplace Logic --- | |
const loadMarketplace = () => { | |
const savedMarketplace = localStorage.getItem("marketplaceCards"); | |
if (savedMarketplace) marketplaceCards = JSON.parse(savedMarketplace); | |
const savedEnabled = localStorage.getItem("isMarketplaceEnabled"); | |
isMarketplaceEnabled = savedEnabled === "true"; | |
el('marketplaceToggle').checked = isMarketplaceEnabled; | |
}; | |
const saveMarketplace = () => { | |
localStorage.setItem("marketplaceCards", JSON.stringify(marketplaceCards)); | |
localStorage.setItem("isMarketplaceEnabled", isMarketplaceEnabled); | |
}; | |
const toggleMarketplace = (enabled) => { | |
isMarketplaceEnabled = enabled; | |
saveMarketplace(); | |
if (enabled && marketplaceCards.length === 0 && cards.length > 0) { | |
// Auto-populate marketplace if enabled and empty, but history exists | |
marketplaceCards = [...cards]; | |
saveMarketplace(); | |
} | |
renderMarketplace(); | |
}; | |
const renderMarketplace = () => { | |
const tbody = el('marketplaceTableBody'); | |
const filterTagsContainer = el('marketplaceFilterTags'); | |
tbody.innerHTML = ''; | |
filterTagsContainer.innerHTML = ''; | |
if (!isMarketplaceEnabled) { | |
tbody.innerHTML = '<tr><td colspan="9" class="text-center py-4 text-gray-500">Marketplace is disabled. Enable it to see cards.</td></tr>'; | |
return; | |
} | |
// Get fraud score filters | |
const minFraudScore = localStorage.getItem("minFraudScore") ? parseInt(localStorage.getItem("minFraudScore")) : 0; | |
const maxFraudScore = localStorage.getItem("maxFraudScore") ? parseInt(localStorage.getItem("maxFraudScore")) : 100; | |
// Filter cards based on active type filter and fraud score | |
const filteredCards = marketplaceCards.filter(card => | |
(activeMarketplaceFilter === 'all' || card.type === activeMarketplaceFilter) && | |
(card.fraudScore === undefined || (card.fraudScore >= minFraudScore && card.fraudScore <= maxFraudScore)) | |
); | |
// Populate filter tags | |
const types = ['all', ...new Set(marketplaceCards.map(c => c.type))]; | |
types.forEach(type => { | |
const tag = document.createElement('span'); | |
tag.className = `filter-tag ${type === activeMarketplaceFilter ? 'active' : ''}`; | |
tag.textContent = type === 'all' ? 'All Types' : type; | |
tag.onclick = () => { | |
activeMarketplaceFilter = type; | |
renderMarketplace(); | |
}; | |
filterTagsContainer.appendChild(tag); | |
}); | |
if (filteredCards.length === 0) { | |
tbody.innerHTML = `<tr><td colspan="9" class="text-center py-4 text-gray-500">No cards found matching filter '${activeMarketplaceFilter}' and fraud score range [${minFraudScore}-${maxFraudScore}].</td></tr>`; | |
return; | |
} | |
filteredCards.forEach((card, index) => { | |
const row = document.createElement('tr'); | |
row.className = index % 2 === 0 ? 'bg-white' : 'bg-blue-50'; | |
const statusClass = card.status === 'LIVE' ? 'bg-green-100 text-green-800' : (card.status === 'DEAD' ? 'bg-red-100 text-red-800' : 'bg-gray-100 text-gray-800'); | |
const statusText = card.status || 'UNKNOWN'; | |
const fraudScore = card.fraudScore !== undefined ? card.fraudScore : 'N/A'; | |
const fraudScoreClass = fraudScore < 50 ? 'text-green-600' : (fraudScore > 75 ? 'text-red-600' : 'text-yellow-600'); | |
row.innerHTML = ` | |
<td>${card.number}</td> | |
<td>${card.name || '-'}</td> | |
<td>${card.mm}/${card.yy}</td> | |
<td>${card.cvv}</td> | |
<td>${card.type || 'Unknown'}</td> | |
<td>${card.bank || 'Unknown'}</td> | |
<td><span class="px-2 py-1 rounded ${statusClass}">${statusText}</span></td> | |
<td><span class="font-semibold ${fraudScoreClass}">${fraudScore}</span></td> | |
<td> | |
<button onclick="copyMarketplaceCard(${index})" class="bg-blue-500 hover:bg-blue-600 text-white rounded px-2 py-1 text-xs"><i class="fas fa-copy mr-1"></i>Copy</button> | |
<button onclick="deleteMarketplaceCard(${index})" class="bg-red-500 hover:bg-red-600 text-white rounded px-2 py-1 text-xs ml-1"><i class="fas fa-trash mr-1"></i>Delete</button> | |
</td> | |
`; | |
tbody.appendChild(row); | |
}); | |
}; | |
const clearMarketplace = () => { | |
if (confirm('Are you sure you want to clear the marketplace?')) { | |
marketplaceCards = []; | |
saveMarketplace(); | |
renderMarketplace(); | |
} | |
}; | |
const copyMarketplaceCard = (index) => { | |
// Find the actual card in the full marketplace list based on filtered index | |
const minFraudScore = localStorage.getItem("minFraudScore") ? parseInt(localStorage.getItem("minFraudScore")) : 0; | |
const maxFraudScore = localStorage.getItem("maxFraudScore") ? parseInt(localStorage.getItem("maxFraudScore")) : 100; | |
const filteredCards = marketplaceCards.filter(card => | |
(activeMarketplaceFilter === 'all' || card.type === activeMarketplaceFilter) && | |
(card.fraudScore === undefined || (card.fraudScore >= minFraudScore && card.fraudScore <= maxFraudScore)) | |
); | |
const card = filteredCards[index]; | |
if (!card) return; | |
const details = `${card.number}|${card.mm}|${card.yy}|${card.cvv}`; | |
navigator.clipboard.writeText(details).then(() => { | |
alert('Card details (number|mm|yy|cvv) copied to clipboard.'); | |
}); | |
}; | |
const deleteMarketplaceCard = (index) => { | |
// Find the actual card in the full marketplace list based on filtered index | |
const minFraudScore = localStorage.getItem("minFraudScore") ? parseInt(localStorage.getItem("minFraudScore")) : 0; | |
const maxFraudScore = localStorage.getItem("maxFraudScore") ? parseInt(localStorage.getItem("maxFraudScore")) : 100; | |
const filteredCards = marketplaceCards.filter(card => | |
(activeMarketplaceFilter === 'all' || card.type === activeMarketplaceFilter) && | |
(card.fraudScore === undefined || (card.fraudScore >= minFraudScore && card.fraudScore <= maxFraudScore)) | |
); | |
const cardToDelete = filteredCards[index]; | |
if (!cardToDelete) return; | |
// Find the index in the original marketplaceCards array | |
const originalIndex = marketplaceCards.findIndex(c => c.number === cardToDelete.number && c.name === cardToDelete.name); // Use more fields if needed for uniqueness | |
if (originalIndex !== -1) { | |
marketplaceCards.splice(originalIndex, 1); | |
saveMarketplace(); | |
renderMarketplace(); | |
} | |
}; | |
// --- Card Validator --- | |
const validateCards = () => { | |
const input = el('validateInput').value; | |
const resultsDiv = el('validateResults'); | |
resultsDiv.innerHTML = ''; | |
const cardNumbers = input.match(/\d{13,16}/g) || []; | |
if (cardNumbers.length === 0) { | |
resultsDiv.innerHTML = '<p class="text-red-600">No valid card numbers found.</p>'; | |
return; | |
} | |
cardNumbers.forEach(cn => { | |
const isValid = luhnChk(cn); | |
const cardInfo = getCardInfo(cn.substring(0, 6)); | |
const resultP = document.createElement('p'); | |
resultP.className = `text-sm p-1 rounded ${isValid ? 'bg-green-100 text-green-800' : 'bg-red-100 text-red-800'}`; | |
resultP.innerHTML = `Card: ${cn} - ${isValid ? 'Valid (Luhn)' : 'Invalid (Luhn)'} - Type: ${cardInfo.type}`; | |
resultsDiv.appendChild(resultP); | |
}); | |
}; | |
// --- SSN Validator --- | |
const validateSSNFormat = (ssn) => { | |
// Basic format check: XXX-XX-XXXX | |
return /^\d{3}-\d{2}-\d{4}$/.test(ssn); | |
}; | |
const validateSSNs = () => { | |
const input = el('ssnValidateInput').value; | |
const resultsDiv = el('ssnValidateResults'); | |
resultsDiv.innerHTML = ''; | |
const ssns = input.match(/\d{3}-\d{2}-\d{4}/g) || []; | |
if (ssns.length === 0) { | |
resultsDiv.innerHTML = '<p class="text-red-600">No valid SSN formats found.</p>'; | |
return; | |
} | |
ssns.forEach(ssn => { | |
const isValid = validateSSNFormat(ssn); | |
const resultP = document.createElement('p'); | |
resultP.className = `text-sm p-1 rounded ${isValid ? 'bg-green-100 text-green-800' : 'bg-red-100 text-red-800'}`; | |
resultP.innerHTML = `SSN: ${ssn} - ${isValid ? 'Valid Format' : 'Invalid Format'}`; | |
resultsDiv.appendChild(resultP); | |
}); | |
}; | |
// --- Analyzers --- | |
const analyzeBin = () => { | |
const bin = el('binAnalyzeInput').value.substring(0, 6); | |
const resultDiv = el('binAnalyzeResult'); | |
if (bin.length < 6) { | |
resultDiv.innerHTML = '<p class="text-red-600">Please enter at least 6 digits.</p>'; | |
return; | |
} | |
const info = getCardInfo(bin); | |
resultDiv.innerHTML = ` | |
<p><strong>BIN:</strong> ${bin}</p> | |
<p><strong>Card Type:</strong> ${info.type}</p> | |
<p><strong>Issuing Bank:</strong> ${info.bank}</p> | |
`; | |
}; | |
const analyzeFraudScore = () => { | |
const cardNumber = el('fraudScoreInput').value.replace(/\s/g, ''); | |
const resultDiv = el('fraudScoreResult'); | |
if (!luhnChk(cardNumber)) { | |
resultDiv.innerHTML = '<p class="text-red-600">Invalid card number.</p>'; | |
return; | |
} | |
// Simulate fraud score analysis | |
const score = Math.floor(Math.random() * 101); | |
const riskLevel = score < 50 ? 'Low' : (score > 75 ? 'High' : 'Medium'); | |
const riskClass = score < 50 ? 'text-green-600' : (score > 75 ? 'text-red-600' : 'text-yellow-600'); | |
resultDiv.innerHTML = ` | |
<p><strong>Card Number:</strong> ${maskCardNumber(cardNumber)}</p> | |
<p><strong>Estimated Fraud Score:</strong> <span class="font-bold ${riskClass}">${score}</span></p> | |
<p><strong>Estimated Risk Level:</strong> <span class="font-bold ${riskClass}">${riskLevel}</span></p> | |
<p class="text-xs text-gray-500 mt-1">(Note: This is a simulated score for demonstration purposes.)</p> | |
`; | |
// Update score in history/marketplace if card exists | |
const cardIndex = cards.findIndex(c => c.number === cardNumber); | |
if (cardIndex !== -1) { | |
cards[cardIndex].fraudScore = score; | |
saveHistory(); | |
renderHistory(); | |
} | |
const marketplaceIndex = marketplaceCards.findIndex(c => c.number === cardNumber); | |
if (marketplaceIndex !== -1) { | |
marketplaceCards[marketplaceIndex].fraudScore = score; | |
saveMarketplace(); | |
renderMarketplace(); | |
} | |
}; | |
// --- Stats Display --- | |
const updateStatsDisplay = () => { | |
const liveCards = cards.filter(c => c.status === 'LIVE').length; | |
const lowFraudCards = cards.filter(c => c.fraudScore !== undefined && c.fraudScore < 50).length; | |
el('statsTotalCards').textContent = totalCardsGenerated; | |
el('statsLiveCards').textContent = liveCards; | |
el('statsLowFraudCards').textContent = lowFraudCards; | |
el('statsTotalSSNs').textContent = totalSSNsGenerated; | |
// Update admin panel stats if visible | |
if (el('adminPanel') && !el('adminPanel').classList.contains('hidden')) { | |
el('adminTotalCards').textContent = totalCardsGenerated; | |
el('adminLiveCards').textContent = liveCards; | |
el('adminTotalSSNs').textContent = totalSSNsGenerated; | |
} | |
}; | |
// --- Admin Panel Logic --- | |
const showAdmin = (show) => { | |
const panel = el('adminPanel'); | |
if (show) { | |
panel.classList.remove('hidden'); | |
updateStatsDisplay(); // Update stats when opening | |
fetchCryptoRates(); // Fetch rates when opening | |
} else { | |
panel.classList.add('hidden'); | |
} | |
}; | |
const applyAdminSettings = () => { | |
const theme = el('themeSelect').value; | |
const fontColor = el('fontColorInput').value; | |
// Apply theme (basic example, more complex themes need more CSS) | |
document.body.classList.remove('theme-hacker', 'theme-matrix', 'theme-dark'); | |
if (theme === 'hacker') { | |
document.body.classList.add('theme-hacker'); | |
document.body.style.backgroundColor = '#000'; | |
document.body.style.color = '#0f0'; | |
} else if (theme === 'matrix') { | |
document.body.classList.add('theme-matrix'); | |
document.body.style.backgroundColor = '#000'; | |
document.body.style.color = '#0f0'; // Similar to hacker for simplicity | |
} else if (theme === 'dark') { | |
document.body.classList.add('theme-dark'); | |
document.body.style.backgroundColor = '#1a202c'; | |
document.body.style.color = '#e2e8f0'; | |
} else { | |
document.body.style.backgroundColor = '#f3f4f6'; // Default bg | |
document.body.style.color = fontColor; // Apply selected font color for default | |
} | |
// Apply font color (only for default theme in this example) | |
if (theme === 'default') { | |
document.body.style.color = fontColor; | |
} | |
// Save settings | |
localStorage.setItem('adminTheme', theme); | |
localStorage.setItem('adminFontColor', fontColor); | |
alert('Settings applied!'); | |
}; | |
const loadAdminSettings = () => { | |
const theme = localStorage.getItem('adminTheme') || 'default'; | |
const fontColor = localStorage.getItem('adminFontColor') || '#222222'; | |
el('themeSelect').value = theme; | |
el('fontColorInput').value = fontColor; | |
// Re-apply settings on load | |
applyAdminSettings(); | |
}; | |
// --- Crypto Rates --- | |
const fetchCryptoRates = async () => { | |
const ratesDiv = el('cryptoRates'); | |
ratesDiv.innerHTML = 'Loading rates...'; | |
try { | |
// Using CoinGecko API (free, no key needed for simple price) | |
const response = await fetch('https://api.coingecko.com/api/v3/simple/price?ids=bitcoin,ethereum,litecoin,ripple&vs_currencies=usd'); | |
if (!response.ok) throw new Error('Network response was not ok'); | |
const data = await response.json(); | |
ratesDiv.innerHTML = ''; | |
for (const [coin, priceData] of Object.entries(data)) { | |
const price = priceData.usd; | |
const coinDiv = document.createElement('div'); | |
coinDiv.className = 'bg-gray-200 p-2 rounded text-center'; | |
coinDiv.innerHTML = `<div class="font-bold capitalize">${coin}</div><div>$${price.toFixed(2)}</div>`; | |
ratesDiv.appendChild(coinDiv); | |
} | |
} catch (error) { | |
console.error('Error fetching crypto rates:', error); | |
ratesDiv.innerHTML = '<p class="text-red-500 col-span-full">Failed to load crypto rates.</p>'; | |
} | |
}; | |
// --- File Handling --- | |
const downloadText = (content, filename) => { | |
const blob = new Blob([content], { type: 'text/plain' }); | |
const link = document.createElement('a'); | |
link.href = URL.createObjectURL(blob); | |
link.download = filename; | |
link.click(); | |
URL.revokeObjectURL(link.href); | |
}; | |
const exportHistory = (format) => { | |
if (cards.length === 0) { | |
alert('No history to export.'); | |
return; | |
} | |
let content = ''; | |
const filename = `card_history.${format}`; | |
if (format === 'csv') { | |
content = 'Name,Number,ExpiryMonth,ExpiryYear,CVV,Status,FraudScore,Address,Phone,Email,DOB,SSN,Bank,Type\n'; | |
cards.forEach(c => { | |
content += `"${c.name || ''}",${c.number},${c.mm},${c.yy},${c.cvv},${c.status || 'UNKNOWN'},${c.fraudScore !== undefined ? c.fraudScore : ''},"${c.address || ''}","${c.phone || ''}","${c.email || ''}","${c.dob || ''}","${c.ssn || ''}","${c.bank || ''}","${c.type || ''}"\n`; | |
}); | |
} else if (format === 'json') { | |
content = JSON.stringify(cards, null, 2); | |
} else { // txt format (number|mm|yy|cvv) | |
content = cards.map(c => `${c.number}|${c.mm}|${c.yy}|${c.cvv}`).join('\n'); | |
} | |
downloadText(content, filename); | |
}; | |
const handleImport = (event) => { | |
const file = event.target.files[0]; | |
if (!file) return; | |
const reader = new FileReader(); | |
reader.onload = (e) => { | |
const content = e.target.result; | |
try { | |
let importedCount = 0; | |
// Try parsing as JSON first | |
try { | |
const importedCards = JSON.parse(content); | |
if (Array.isArray(importedCards)) { | |
importedCards.forEach(card => { | |
if (card.number && card.mm && card.yy && card.cvv) { | |
// Basic validation | |
cards.push({ | |
name: card.name || '', | |
number: card.number, | |
mm: card.mm, | |
yy: card.yy, | |
cvv: card.cvv, | |
status: card.status || 'UNKNOWN', | |
fraudScore: card.fraudScore, | |
address: card.address || '', | |
phone: card.phone || '', | |
email: card.email || '', | |
dob: card.dob || '', | |
ssn: card.ssn || '', | |
bank: card.bank || getCardInfo(card.number.substring(0,6)).bank, | |
type: card.type || getCardInfo(card.number.substring(0,6)).type | |
}); | |
importedCount++; | |
} | |
}); | |
} | |
} catch (jsonError) { | |
// If JSON fails, try parsing as text (CSV/TXT) | |
const lines = content.split('\n'); | |
lines.forEach(line => { | |
const parts = line.split(/[|,;\s]+/); // Split by common delimiters | |
if (parts.length >= 4 && luhnChk(parts[0])) { // Assuming number|mm|yy|cvv format | |
const number = parts[0]; | |
const mm = parts[1]; | |
const yy = parts[2]; | |
const cvv = parts[3]; | |
const info = getCardInfo(number.substring(0,6)); | |
cards.push({ | |
name: '', // Cannot reliably import name from this format | |
number: number, | |
mm: mm, | |
yy: yy, | |
cvv: cvv, | |
status: 'UNKNOWN', | |
bank: info.bank, | |
type: info.type | |
}); | |
importedCount++; | |
} | |
}); | |
} | |
if (importedCount > 0) { | |
totalCardsGenerated += importedCount; // Increment total count | |
saveHistory(); | |
renderHistory(); | |
renderMarketplace(); | |
alert(`Successfully imported ${importedCount} cards.`); | |
} else { | |
alert('Could not parse file or find valid card data.'); | |
} | |
} catch (error) { | |
alert('Error processing file: ' + error.message); | |
} | |
}; | |
reader.readAsText(file); | |
// Reset file input to allow importing the same file again | |
event.target.value = null; | |
}; | |
// --- Initialization --- | |
document.addEventListener('DOMContentLoaded', () => { | |
loadHistory(); | |
loadMarketplace(); | |
loadAdminSettings(); | |
renderHistory(); | |
renderMarketplace(); | |
updateStatsDisplay(); | |
el('generateBtn').onclick = () => { | |
const qty = parseInt(el('qtyInput').value) || 1; | |
const binPrefix = el('binInput').value.trim(); | |
const useRandomBin = el('randBinCheck').checked; | |
const holderName = el('holderInput').value.trim(); | |
const phoneNumber = el('phoneInput').value.trim(); | |
const dob = el('dobInput').value.trim(); | |
const email = el('emailInput').value.trim(); | |
const address = el('addressInput').value.trim(); | |
const bankName = el('bankInput').value.trim(); | |
if (qty > 5000) { | |
alert('Maximum generation limit is 5000 cards at a time.'); | |
return; | |
} | |
let generatedCount = 0; | |
for (let i = 0; i < qty; i++) { | |
let currentBin = binPrefix; | |
if (useRandomBin || !currentBin) { | |
currentBin = famousBins[Math.floor(Math.random() * famousBins.length)]; | |
} | |
if (currentBin.length < 2 || currentBin.length > 6) { | |
alert('BIN must be between 2 and 6 digits.'); | |
return; // Stop generation if BIN is invalid | |
} | |
const number = genCC(currentBin); | |
const expiry = genExp(); | |
const cvv = genCVV(); | |
const name = holderName || genName(); | |
const cardInfo = getCardInfo(number.substring(0, 6)); | |
const newCard = { | |
name: name, | |
number: number, | |
mm: expiry.mm, | |
yy: expiry.yy, | |
cvv: cvv, | |
status: 'UNKNOWN', // Initial status | |
fraudScore: undefined, | |
address: address || genAddress(), | |
phone: phoneNumber || genPhone(), | |
email: email || genEmail(name), | |
dob: dob || genDOB(), | |
ssn: genSSN(), // Generate a random SSN by default | |
bank: bankName || cardInfo.bank, | |
type: cardInfo.type | |
}; | |
cards.push(newCard); | |
if (isMarketplaceEnabled) { | |
marketplaceCards.push(newCard); | |
} | |
generatedCount++; | |
} | |
totalCardsGenerated += generatedCount; | |
saveHistory(); | |
saveMarketplace(); | |
renderHistory(); | |
renderMarketplace(); | |
alert(`Generated ${generatedCount} cards.`); | |
// Auto-test if enabled | |
if (el('autoTestCheck') && el('autoTestCheck').checked) { | |
setTimeout(() => { | |
testAllCards(); | |
}, 500); | |
} | |
}; | |
el('importFile').addEventListener('change', handleImport); | |
// Initialize SSN marketplace functionality | |
loadSSNMarketplace(); | |
renderSSNMarketplace(); | |
// Initialize payment test functionality | |
if (document.getElementById('payment-test-section')) { | |
initPaymentTest(); | |
} | |
// Initialize fraud score filter | |
const minFraudScore = localStorage.getItem("minFraudScore"); | |
const maxFraudScore = localStorage.getItem("maxFraudScore"); | |
if (minFraudScore !== null && el('minFraudScore')) { | |
el('minFraudScore').value = minFraudScore; | |
el('minFraudScoreValue').textContent = minFraudScore; | |
} | |
if (maxFraudScore !== null && el('maxFraudScore')) { | |
el('maxFraudScore').value = maxFraudScore; | |
el('maxFraudScoreValue').textContent = maxFraudScore; | |
} | |
// Initialize SSN auto-gen and duplicate removal listeners | |
if (el('startAutoGenBtn')) el('startAutoGenBtn').addEventListener('click', startAutoGeneration); | |
if (el('stopAutoGenBtn')) el('stopAutoGenBtn').addEventListener('click', stopAutoGeneration); | |
if (el('removeDuplicatesBtn')) el('removeDuplicatesBtn').addEventListener('click', removeDuplicateSSNs); | |
// Initialize state selection dropdowns and info spans | |
initStateSelection(); | |
}); | |
// --- PAYMENT PROCESSING TEST FUNCTIONALITY --- | |
function loadPaymentTestResults() { | |
const savedResults = localStorage.getItem("paymentTestResults"); | |
if (savedResults) { | |
paymentTestResults = JSON.parse(savedResults); | |
} | |
} | |
function savePaymentTestResults() { | |
localStorage.setItem("paymentTestResults", JSON.stringify(paymentTestResults)); | |
} | |
function renderPaymentTestResults() { | |
const tableBody = el('paymentTestTableBody'); | |
if (!tableBody) return; | |
tableBody.innerHTML = ''; | |
if (paymentTestResults.length === 0) { | |
tableBody.innerHTML = '<tr><td colspan="7" class="text-center py-4 text-gray-500">No payment tests performed yet.</td></tr>'; | |
return; | |
} | |
paymentTestResults.forEach((result, index) => { | |
const row = document.createElement('tr'); | |
row.className = index % 2 === 0 ? 'bg-white' : 'bg-indigo-50'; | |
const statusClass = result.status === 'Success' ? 'bg-green-100 text-green-800' : 'bg-red-100 text-red-800'; | |
row.innerHTML = ` | |
<td>${maskCardNumber(result.cardNumber)}</td> | |
<td>${result.cardHolder}</td> | |
<td>${result.expiry}</td> | |
<td>${result.amount} ${result.currency}</td> | |
<td><span class="px-2 py-1 rounded ${statusClass}">${result.status}</span></td> | |
<td>${result.message}</td> | |
<td>${new Date(result.timestamp).toLocaleString()}</td> | |
`; | |
tableBody.appendChild(row); | |
}); | |
} | |
function maskCardNumber(cardNumber) { | |
if (!cardNumber) return ''; | |
return cardNumber.replace(/\s/g, '').replace(/^.+(.{4})$/, '****-****-****-$1'); | |
} | |
function processPayment() { | |
const cardNumber = el('paymentCardNumber').value.replace(/\s/g, ''); | |
const cardMonth = el('paymentCardMonth').value; | |
const cardYear = el('paymentCardYear').value; | |
const cardCVV = el('paymentCardCVV').value; | |
const cardHolder = el('paymentCardHolder').value; | |
const amount = el('paymentAmount').value; | |
const currency = el('paymentCurrency').value; | |
const description = el('paymentDescription').value; | |
if (!cardNumber || !cardMonth || !cardYear || !cardCVV || !cardHolder || !amount) { | |
showPaymentResult('Please fill in all required fields.', false); | |
return; | |
} | |
showPaymentResult('Processing payment...', null); | |
setTimeout(() => { | |
const cardInHistory = cards.find(c => c.number === cardNumber); | |
const cardInMarketplace = marketplaceCards.find(c => c.number === cardNumber); | |
let card = cardInHistory || cardInMarketplace; | |
let success = false; | |
let message = ''; | |
if (card && card.status !== 'UNKNOWN') { | |
// If card exists and has a known status, use it | |
success = card.status === 'LIVE'; | |
message = success ? 'Payment processed successfully.' : 'Payment failed. Card declined (known status).'; | |
} else { | |
// If card doesn't exist or status is unknown, simulate based on Luhn and random chance | |
const isLuhn = luhnChk(cardNumber); | |
success = isLuhn && Math.random() > 0.3; // 70% chance of success for valid Luhn | |
message = !isLuhn ? 'Payment failed. Invalid card number.' : (success ? 'Payment processed successfully (simulated).' : 'Payment failed. Card declined (simulated).'); | |
} | |
const result = { | |
cardNumber, | |
cardHolder, | |
expiry: `${cardMonth}/${cardYear}`, | |
amount, | |
currency, | |
status: success ? 'Success' : 'Failed', | |
message, | |
timestamp: new Date().getTime() | |
}; | |
paymentTestResults.unshift(result); | |
savePaymentTestResults(); | |
renderPaymentTestResults(); | |
showPaymentResult(message, success); | |
// Update card status in history and marketplace if it exists | |
const newStatus = success ? 'LIVE' : 'DEAD'; | |
let statusUpdated = false; | |
if (cardInHistory) { | |
cardInHistory.status = newStatus; | |
statusUpdated = true; | |
} | |
if (cardInMarketplace) { | |
cardInMarketplace.status = newStatus; | |
statusUpdated = true; | |
} | |
if (statusUpdated) { | |
saveHistory(); | |
saveMarketplace(); | |
renderHistory(); | |
renderMarketplace(); | |
updateStatsDisplay(); | |
} | |
}, 1500); | |
} | |
function showPaymentResult(message, success) { | |
const resultDiv = el('paymentResult'); | |
resultDiv.classList.remove('hidden', 'bg-green-100', 'bg-red-100', 'bg-blue-100'); | |
if (success === null) { | |
resultDiv.classList.add('bg-blue-100'); | |
resultDiv.innerHTML = `<div class="flex items-center"><i class="fas fa-spinner fa-spin text-blue-600 mr-2"></i><span class="text-blue-800">${message}</span></div>`; | |
} else if (success) { | |
resultDiv.classList.add('bg-green-100'); | |
resultDiv.innerHTML = `<div class="flex items-center"><i class="fas fa-check-circle text-green-600 mr-2"></i><span class="text-green-800">${message}</span></div>`; | |
} else { | |
resultDiv.classList.add('bg-red-100'); | |
resultDiv.innerHTML = `<div class="flex items-center"><i class="fas fa-times-circle text-red-600 mr-2"></i><span class="text-red-800">${message}</span></div>`; | |
} | |
resultDiv.classList.remove('hidden'); | |
} | |
function testSelectedCard(cardNumber) { | |
const card = cards.find(c => c.number === cardNumber) || marketplaceCards.find(c => c.number === cardNumber); | |
if (!card) { | |
alert('Card not found.'); | |
return; | |
} | |
el('paymentCardNumber').value = card.number; | |
el('paymentCardMonth').value = card.mm; | |
el('paymentCardYear').value = card.yy; | |
el('paymentCardCVV').value = card.cvv; | |
el('paymentCardHolder').value = card.name; | |
document.getElementById('payment-test-section').scrollIntoView({ behavior: 'smooth' }); | |
setTimeout(processPayment, 500); | |
} | |
function testAllCards() { | |
const cardsToTest = cards; // Test cards from history | |
if (cardsToTest.length === 0) { | |
alert('No cards available in history to test.'); | |
return; | |
} | |
if (!confirm(`This will test all ${cardsToTest.length} cards from the history. Continue?`)) { | |
return; | |
} | |
showPaymentResult(`Testing ${cardsToTest.length} cards...`, null); | |
let index = 0; | |
let processedCount = 0; | |
const intervalId = setInterval(() => { | |
if (index >= cardsToTest.length) { | |
clearInterval(intervalId); | |
showPaymentResult(`Completed testing ${processedCount} cards.`, true); | |
saveHistory(); | |
saveMarketplace(); | |
savePaymentTestResults(); | |
renderHistory(); | |
renderMarketplace(); | |
renderPaymentTestResults(); | |
updateStatsDisplay(); | |
return; | |
} | |
const card = cardsToTest[index]; | |
const isLuhn = luhnChk(card.number); | |
const success = card.status === 'LIVE' || (isLuhn && Math.random() > 0.3); | |
const message = !isLuhn ? 'Invalid card number.' : (success ? 'Payment processed successfully (simulated).' : 'Card declined (simulated).'); | |
const result = { | |
cardNumber: card.number, | |
cardHolder: card.name, | |
expiry: `${card.mm}/${card.yy}`, | |
amount: el('paymentAmount').value, | |
currency: el('paymentCurrency').value, | |
status: success ? 'Success' : 'Failed', | |
message, | |
timestamp: new Date().getTime() | |
}; | |
paymentTestResults.unshift(result); | |
card.status = success ? 'LIVE' : 'DEAD'; | |
// Update marketplace card status if it exists there too | |
const mpCard = marketplaceCards.find(mpc => mpc.number === card.number); | |
if (mpCard) mpCard.status = card.status; | |
processedCount++; | |
showPaymentResult(`Testing card ${index + 1} of ${cardsToTest.length}... Status: ${card.status}`, null); | |
index++; | |
}, 150); // Shorter delay for batch testing | |
} | |
function addTestButtonsToHistoryTable() { | |
const originalRenderHistory = window.renderHistory; | |
window.renderHistory = function() { | |
originalRenderHistory(); | |
const rows = document.querySelectorAll('#generatedCardsTable tbody tr'); | |
rows.forEach(row => { | |
const cardNumber = row.getAttribute('data-card-number'); | |
if (!cardNumber) return; | |
if (row.querySelector('.test-card-btn')) return; | |
const actionsCell = row.querySelector('td:last-child'); | |
if (actionsCell) { | |
const testBtn = document.createElement('button'); | |
testBtn.className = 'test-card-btn bg-indigo-500 hover:bg-indigo-600 text-white rounded px-2 py-1 text-xs ml-1'; | |
testBtn.innerHTML = '<i class="fas fa-credit-card mr-1"></i>Test'; | |
testBtn.onclick = function(e) { e.stopPropagation(); testSelectedCard(cardNumber); }; | |
actionsCell.appendChild(testBtn); | |
} | |
}); | |
}; | |
} | |
function initPaymentTest() { | |
loadPaymentTestResults(); | |
renderPaymentTestResults(); | |
el('processPaymentBtn').addEventListener('click', processPayment); | |
el('testSelectedCardBtn').addEventListener('click', () => { | |
const cardNumber = el('paymentCardNumber').value.replace(/\s/g, ''); | |
if (!cardNumber) { alert('Please enter a card number.'); return; } | |
processPayment(); | |
}); | |
el('testAllCardsBtn').addEventListener('click', testAllCards); | |
addTestButtonsToHistoryTable(); | |
const autoTestCheck = el('autoTestCheck'); | |
const savedAutoTest = localStorage.getItem("autoTestEnabled"); | |
if (savedAutoTest === "true") autoTestCheck.checked = true; | |
autoTestCheck.addEventListener('change', function() { localStorage.setItem("autoTestEnabled", this.checked); }); | |
} | |
// --- FRAUD SCORE FILTER JAVASCRIPT --- | |
function filterByFraudScore() { | |
const minScore = parseInt(el('minFraudScore').value); | |
const maxScore = parseInt(el('maxFraudScore').value); | |
localStorage.setItem("minFraudScore", minScore); | |
localStorage.setItem("maxFraudScore", maxScore); | |
renderMarketplace(); | |
} | |
function resetFraudScoreFilter() { | |
el('minFraudScore').value = 0; | |
el('maxFraudScore').value = 100; | |
el('minFraudScoreValue').textContent = '0'; | |
el('maxFraudScoreValue').textContent = '100'; | |
localStorage.removeItem("minFraudScore"); | |
localStorage.removeItem("maxFraudScore"); | |
renderMarketplace(); | |
} | |
function setLowFraudScore() { | |
el('minFraudScore').value = 0; | |
el('maxFraudScore').value = 50; | |
el('minFraudScoreValue').textContent = '0'; | |
el('maxFraudScoreValue').textContent = '50'; | |
filterByFraudScore(); | |
} | |
function setHighFraudScore() { | |
el('minFraudScore').value = 51; | |
el('maxFraudScore').value = 100; | |
el('minFraudScoreValue').textContent = '51'; | |
el('maxFraudScoreValue').textContent = '100'; | |
filterByFraudScore(); | |
} | |
// --- STATE SSN GENERATION AND MARKETPLACE JAVASCRIPT --- | |
function loadSSNMarketplace() { | |
const savedSSNs = localStorage.getItem("ssnMarketplace"); | |
if (savedSSNs) ssnMarketplace = JSON.parse(savedSSNs); | |
} | |
function saveSSNMarketplace() { | |
localStorage.setItem("ssnMarketplace", JSON.stringify(ssnMarketplace)); | |
} | |
function generateAlabamaSSN() { | |
const area = Math.floor(Math.random() * (424 - 416 + 1)) + 416; | |
const group = Math.floor(Math.random() * (67 - 65 + 1)) + 65; | |
const serial = Math.floor(Math.random() * 9999) + 1; | |
return { ssn: `${area}-${String(group).padStart(2,'0')}-${String(serial).padStart(4,'0')}`, state: 'Alabama', issueDate: '2011', isValid: true }; | |
} | |
function generateAlaskaSSN() { | |
const area = 574; const group = 61; | |
const serial = Math.floor(Math.random() * 9999) + 1; | |
return { ssn: `${area}-${String(group).padStart(2,'0')}-${String(serial).padStart(4,'0')}`, state: 'Alaska', issueDate: '2011', isValid: true }; | |
} | |
function generateArizonaSSN() { | |
const area = Math.floor(Math.random() * (765 - 764 + 1)) + 764; | |
let group; | |
if (area === 764) group = Math.floor(Math.random() * (99 - 23 + 1)) + 23; | |
else group = Math.floor(Math.random() * 29) + 1; | |
const serial = Math.floor(Math.random() * 9999) + 1; | |
return { ssn: `${area}-${String(group).padStart(2,'0')}-${String(serial).padStart(4,'0')}`, state: 'Arizona', issueDate: '2011', isValid: true }; | |
} | |
function generateArkansasSSN() { | |
const area = Math.floor(Math.random() * (679 - 676 + 1)) + 676; | |
let group; | |
if (area === 676) group = Math.floor(Math.random() * (99 - 20 + 1)) + 20; | |
else if (area === 679) group = Math.floor(Math.random() * 22) + 1; | |
else group = Math.floor(Math.random() * 99) + 1; | |
const serial = Math.floor(Math.random() * 9999) + 1; | |
return { ssn: `${area}-${String(group).padStart(2,'0')}-${String(serial).padStart(4,'0')}`, state: 'Arkansas', issueDate: '2011', isValid: true }; | |
} | |
function generateCaliforniaSSN() { | |
const area = Math.floor(Math.random() * (626 - 602 + 1)) + 602; | |
let group; | |
if (area === 602) group = Math.floor(Math.random() * (99 - 83 + 1)) + 83; | |
else if (area === 626) group = Math.floor(Math.random() * 87) + 1; | |
else group = Math.floor(Math.random() * 99) + 1; | |
const serial = Math.floor(Math.random() * 9999) + 1; | |
return { ssn: `${area}-${String(group).padStart(2,'0')}-${String(serial).padStart(4,'0')}`, state: 'California', issueDate: '2011', isValid: true }; | |
} | |
function generateColoradoSSN() { | |
const area = Math.floor(Math.random() * (653 - 650 + 1)) + 650; | |
let group; | |
if (area === 650) group = Math.floor(Math.random() * (99 - 58 + 1)) + 58; | |
else if (area === 653) group = Math.floor(Math.random() * 62) + 1; | |
else group = Math.floor(Math.random() * 99) + 1; | |
const serial = Math.floor(Math.random() * 9999) + 1; | |
return { ssn: `${area}-${String(group).padStart(2,'0')}-${String(serial).padStart(4,'0')}`, state: 'Colorado', issueDate: '2011', isValid: true }; | |
} | |
function generateConnecticutSSN() { | |
const area = Math.floor(Math.random() * (49 - 40 + 1)) + 40; | |
let group; | |
if (area === 40) group = Math.floor(Math.random() * (99 - 13 + 1)) + 13; | |
else if (area === 49) group = Math.floor(Math.random() * 15) + 1; | |
else group = Math.floor(Math.random() * 99) + 1; | |
const serial = Math.floor(Math.random() * 9999) + 1; | |
return { ssn: `${String(area).padStart(3,'0')}-${String(group).padStart(2,'0')}-${String(serial).padStart(4,'0')}`, state: 'Connecticut', issueDate: '2011', isValid: true }; | |
} | |
function generateDelawareSSN() { | |
const area = Math.floor(Math.random() * (222 - 221 + 1)) + 221; | |
let group; | |
if (area === 221) group = Math.floor(Math.random() * (99 - 11 + 1)) + 11; | |
else group = Math.floor(Math.random() * 13) + 1; | |
const serial = Math.floor(Math.random() * 9999) + 1; | |
return { ssn: `${area}-${String(group).padStart(2,'0')}-${String(serial).padStart(4,'0')}`, state: 'Delaware', issueDate: '2011', isValid: true }; | |
} | |
function generateRandomStateSSN() { | |
const ssn = genSSN(); // Use the original basic generator | |
const otherStates = ["New York", "Texas", "Florida", "Illinois", "Pennsylvania", "Ohio", "Georgia", "North Carolina", "Michigan", "New Jersey"]; | |
const randomState = otherStates[Math.floor(Math.random() * otherStates.length)]; | |
const currentYear = new Date().getFullYear(); | |
const randomYear = Math.floor(Math.random() * 20) + (currentYear - 20); | |
return { ssn: ssn, state: randomState, issueDate: String(randomYear), isValid: validateSSNFormat(ssn) }; | |
} | |
function generateStateSSNs() { | |
const state = el('ssnStateSelect').value; | |
const count = parseInt(el('stateSSNCount').value) || 1; | |
if (count < 1 || count > 100) { alert('Please enter a number between 1 and 100.'); return; } | |
let generatedCount = 0; | |
let attempts = 0; | |
const maxAttempts = count * 3; | |
while (generatedCount < count && attempts < maxAttempts) { | |
let ssnData; | |
if (state === 'Alabama') ssnData = generateAlabamaSSN(); | |
else if (state === 'Alaska') ssnData = generateAlaskaSSN(); | |
else if (state === 'Arizona') ssnData = generateArizonaSSN(); | |
else if (state === 'Arkansas') ssnData = generateArkansasSSN(); | |
else if (state === 'California') ssnData = generateCaliforniaSSN(); | |
else if (state === 'Colorado') ssnData = generateColoradoSSN(); | |
else if (state === 'Connecticut') ssnData = generateConnecticutSSN(); | |
else if (state === 'Delaware') ssnData = generateDelawareSSN(); | |
else ssnData = generateRandomStateSSN(); | |
if (!isSSNDuplicate(ssnData.ssn)) { | |
ssnMarketplace.push(ssnData); | |
generatedCount++; | |
} | |
attempts++; | |
} | |
totalSSNsGenerated += generatedCount; | |
saveSSNMarketplace(); | |
renderSSNMarketplace(); | |
updateStatsDisplay(); | |
alert(generatedCount < count ? `Generated ${generatedCount} unique ${state} SSNs. Some duplicates skipped.` : `Generated ${generatedCount} unique ${state} SSNs.`); | |
} | |
function initStateSelection() { | |
const ssnStateSelect = el('ssnStateSelect'); | |
if (!ssnStateSelect) return; | |
ssnStateSelect.addEventListener('change', function() { | |
const state = this.value; | |
['alabama', 'alaska', 'arizona', 'arkansas', 'california', 'colorado', 'connecticut', 'delaware'].forEach(s => { | |
const infoEl = el(`${s}SSNInfo`); | |
if (infoEl) infoEl.classList.add('hidden'); | |
}); | |
const selectedInfoEl = el(`${state.toLowerCase()}SSNInfo`); | |
if (selectedInfoEl) selectedInfoEl.classList.remove('hidden'); | |
}); | |
// Trigger change once on load to show default info | |
ssnStateSelect.dispatchEvent(new Event('change')); | |
} | |
function renderSSNMarketplace() { | |
const tableBody = el('ssnMarketplaceTableBody'); | |
if (!tableBody) return; | |
tableBody.innerHTML = ''; | |
const searchTerm = (el('ssnSearchInput')?.value || '').toLowerCase(); | |
const stateFilter = el('ssnStateFilter')?.value || ''; | |
const filteredSSNs = ssnMarketplace.filter(ssnData => { | |
const matchesSearch = !searchTerm || ssnData.ssn.toLowerCase().includes(searchTerm) || ssnData.state.toLowerCase().includes(searchTerm); | |
const matchesState = !stateFilter || ssnData.state === stateFilter; | |
return matchesSearch && matchesState; | |
}); | |
if (el('totalSSNsInMarketplace')) el('totalSSNsInMarketplace').textContent = filteredSSNs.length; | |
if (filteredSSNs.length === 0) { | |
tableBody.innerHTML = '<tr><td colspan="5" class="text-center py-4 text-gray-500">No SSNs found.</td></tr>'; | |
return; | |
} | |
filteredSSNs.forEach((ssnData, index) => { | |
const row = document.createElement('tr'); | |
row.className = index % 2 === 0 ? 'bg-white' : 'bg-purple-50'; | |
const validationClass = ssnData.isValid ? 'bg-green-100 text-green-800' : 'bg-red-100 text-red-800'; | |
const validationText = ssnData.isValid ? 'Valid' : 'Invalid'; | |
// Use original index from ssnMarketplace for deletion | |
const originalIndex = ssnMarketplace.findIndex(item => item.ssn === ssnData.ssn); | |
row.innerHTML = ` | |
<td>${ssnData.ssn}</td> | |
<td>${ssnData.state}</td> | |
<td>${ssnData.issueDate}</td> | |
<td><span class="px-2 py-1 rounded ${validationClass}">${validationText}</span></td> | |
<td> | |
<button onclick="copySSN('${ssnData.ssn}')" class="bg-blue-500 hover:bg-blue-600 text-white rounded px-2 py-1 text-xs"><i class="fas fa-copy mr-1"></i>Copy</button> | |
<button onclick="deleteSSN(${originalIndex})" class="bg-red-500 hover:bg-red-600 text-white rounded px-2 py-1 text-xs ml-1"><i class="fas fa-trash mr-1"></i>Delete</button> | |
</td> | |
`; | |
tableBody.appendChild(row); | |
}); | |
} | |
function copySSN(ssn) { | |
navigator.clipboard.writeText(ssn).then(() => alert(`SSN ${ssn} copied.`)); | |
} | |
function deleteSSN(index) { | |
if (index < 0 || index >= ssnMarketplace.length) return; // Safety check | |
if (confirm(`Delete SSN ${ssnMarketplace[index].ssn}?`)) { | |
ssnMarketplace.splice(index, 1); | |
saveSSNMarketplace(); | |
renderSSNMarketplace(); | |
} | |
} | |
function filterSSNMarketplace() { renderSSNMarketplace(); } | |
function resetSSNFilters() { | |
if (el('ssnSearchInput')) el('ssnSearchInput').value = ''; | |
if (el('ssnStateFilter')) el('ssnStateFilter').value = ''; | |
renderSSNMarketplace(); | |
} | |
function exportSSNs(format) { | |
if (ssnMarketplace.length === 0) { alert('No SSNs to export.'); return; } | |
if (format === 'csv') { | |
let content = 'SSN,State,Issue Date,Validation\n'; | |
ssnMarketplace.forEach(d => content += `${d.ssn},${d.state},${d.issueDate},${d.isValid ? 'Valid' : 'Invalid'}\n`); | |
downloadText(content, 'ssn_marketplace.csv'); | |
} | |
} | |
// --- SSN AUTO-GENERATION AND DUPLICATE REMOVAL JAVASCRIPT --- | |
function startAutoGeneration() { | |
const interval = parseInt(el('autoGenInterval').value); | |
if (interval < 500 || interval > 10000) { alert('Interval must be between 500ms and 10000ms.'); return; } | |
const state = el('autoGenStateSelect').value; | |
el('startAutoGenBtn').classList.add('hidden'); | |
el('stopAutoGenBtn').classList.remove('hidden'); | |
el('autoGenStatus').textContent = `Auto-generating ${state} SSNs...`; | |
autoGenCount = 0; | |
autoGenInterval = setInterval(() => { | |
let ssnData; | |
if (state === 'Alabama') ssnData = generateAlabamaSSN(); | |
else if (state === 'Alaska') ssnData = generateAlaskaSSN(); | |
else if (state === 'Arizona') ssnData = generateArizonaSSN(); | |
else if (state === 'Arkansas') ssnData = generateArkansasSSN(); | |
else if (state === 'California') ssnData = generateCaliforniaSSN(); | |
else if (state === 'Colorado') ssnData = generateColoradoSSN(); | |
else if (state === 'Connecticut') ssnData = generateConnecticutSSN(); | |
else if (state === 'Delaware') ssnData = generateDelawareSSN(); | |
else ssnData = generateRandomStateSSN(); | |
if (!isSSNDuplicate(ssnData.ssn)) { | |
ssnMarketplace.push(ssnData); | |
totalSSNsGenerated++; | |
saveSSNMarketplace(); | |
renderSSNMarketplace(); | |
updateStatsDisplay(); | |
autoGenCount++; | |
el('autoGenStatus').textContent = `Auto-generating ${state} SSNs... (${autoGenCount} generated)`; | |
} | |
}, interval); | |
} | |
function stopAutoGeneration() { | |
if (autoGenInterval) { | |
clearInterval(autoGenInterval); | |
autoGenInterval = null; | |
el('startAutoGenBtn').classList.remove('hidden'); | |
el('stopAutoGenBtn').classList.add('hidden'); | |
el('autoGenStatus').textContent = `Auto-generation stopped. Generated ${autoGenCount} unique SSNs.`; | |
} | |
} | |
function isSSNDuplicate(ssn) { | |
return ssnMarketplace.some(item => item.ssn === ssn); | |
} | |
function removeDuplicateSSNs() { | |
const initialCount = ssnMarketplace.length; | |
const uniqueSSNs = new Map(); | |
ssnMarketplace.forEach(ssnData => uniqueSSNs.set(ssnData.ssn, ssnData)); | |
ssnMarketplace = Array.from(uniqueSSNs.values()); | |
saveSSNMarketplace(); | |
renderSSNMarketplace(); | |
const removedCount = initialCount - ssnMarketplace.length; | |
alert(`Removed ${removedCount} duplicate SSNs. ${ssnMarketplace.length} unique SSNs remain.`); | |
} | |
</script> | |
</body> | |
</html> | |