<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Complete ASCII Art Generator</title>
<style>
* {
box-sizing: border-box;
margin: 0;
padding: 0;
font-family: 'Consolas', 'Monaco', 'Courier New', monospace;
}
body {
background-color: #0a0a0a;
color: #d0d0d0;
min-height: 100vh;
padding: 10px;
font-size: 13px;
}
.container {
max-width: 1400px;
margin: 0 auto;
padding: 10px;
}
.header {
background-color: #111;
border: 1px solid #333;
padding: 10px;
margin-bottom: 10px;
}
h1 {
color: #a66;
font-size: 18px;
margin-bottom: 5px;
}
.subtitle {
color: #888;
font-size: 11px;
}
.warning {
background-color: #331100;
border: 1px solid #663300;
padding: 8px;
margin: 10px 0;
font-size: 11px;
color: #ff9966;
}
.content {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 10px;
}
@media (max-width: 900px) {
.content {
grid-template-columns: 1fr;
}
}
.panel {
background-color: #111;
border: 1px solid #333;
padding: 10px;
}
.panel-title {
color: #a66;
font-weight: bold;
margin-bottom: 10px;
padding-bottom: 5px;
border-bottom: 1px solid #333;
font-size: 14px;
}
.stealth-controls {
background-color: #1a1a1a;
border: 1px solid #444;
padding: 10px;
margin: 10px 0;
}
.stealth-option {
margin-bottom: 10px;
padding: 5px;
border-bottom: 1px dotted #333;
}
.stealth-label {
display: block;
margin-bottom: 5px;
color: #6a9;
font-size: 12px;
}
.stealth-desc {
font-size: 10px;
color: #777;
margin-top: 3px;
}
.detection-simulator {
background-color: #1a1a1a;
border: 1px solid #444;
padding: 10px;
margin-top: 10px;
}
.detection-result {
padding: 8px;
margin-top: 8px;
font-size: 11px;
border: 1px solid #333;
background-color: #0a0a0a;
}
.safe {
color: #6c6;
border-color: #363;
}
.warning-detection {
color: #fc6;
border-color: #663;
}
.danger {
color: #f66;
border-color: #633;
}
.upload-area {
border: 2px dashed #444;
padding: 20px;
text-align: center;
cursor: pointer;
background-color: #0a0a0a;
margin-bottom: 10px;
}
.upload-area:hover {
border-color: #a66;
}
#imageInput {
display: none;
}
.image-preview {
margin-top: 10px;
text-align: center;
}
#previewImage {
max-width: 100%;
max-height: 200px;
border: 1px solid #333;
}
.control-group {
margin-bottom: 15px;
}
.control-label {
display: block;
margin-bottom: 5px;
color: #a66;
font-size: 12px;
}
.slider-container {
display: flex;
align-items: center;
gap: 10px;
}
input[type="range"] {
flex: 1;
height: 6px;
background: #222;
border: 1px solid #333;
}
input[type="checkbox"] {
margin-right: 5px;
}
input[type="text"], textarea {
background-color: #0a0a0a;
color: #d0d0d0;
border: 1px solid #333;
padding: 8px;
width: 100%;
font-family: monospace;
font-size: 12px;
}
textarea {
resize: vertical;
min-height: 80px;
}
.slider-value {
min-width: 30px;
text-align: right;
color: #a66;
font-size: 11px;
}
.btn {
background-color: #222;
color: #d0d0d0;
border: 1px solid #333;
padding: 8px 15px;
cursor: pointer;
font-size: 12px;
margin-right: 5px;
margin-bottom: 5px;
}
.btn:hover {
background-color: #333;
border-color: #a66;
}
.btn-primary {
background-color: #6a9;
color: #000;
font-weight: bold;
}
.btn-primary:hover {
background-color: #7ba;
}
.btn-stealth {
background-color: #663;
color: #fff;
}
.btn-stealth:hover {
background-color: #774;
}
.btn-text {
background-color: #369;
color: #fff;
}
.btn-text:hover {
background-color: #47a;
}
.char-options {
display: flex;
flex-wrap: wrap;
gap: 5px;
margin-top: 10px;
}
.char-option {
padding: 5px 10px;
border: 1px solid #333;
cursor: pointer;
background-color: #0a0a0a;
font-family: monospace;
}
.char-option:hover {
border-color: #a66;
}
.char-option.active {
border-color: #a66;
background-color: #222;
}
.output-container {
position: relative;
}
#asciiOutput {
width: 100%;
height: 400px;
background-color: #0a0a0a;
color: #d0d0d0;
border: 1px solid #333;
padding: 10px;
font-family: monospace;
font-size: 11px;
line-height: 1;
resize: vertical;
white-space: pre;
overflow: auto;
tab-size: 4;
}
.output-tools {
display: flex;
flex-wrap: wrap;
gap: 5px;
margin-top: 10px;
}
.format-block {
margin-top: 10px;
padding: 10px;
background-color: #0a0a0a;
border: 1px solid #333;
font-family: monospace;
font-size: 11px;
white-space: pre-wrap;
word-break: break-all;
max-height: 200px;
overflow-y: auto;
}
.preview-output {
background-color: #0a0a0a;
border: 1px solid #333;
padding: 10px;
font-family: monospace;
font-size: 11px;
line-height: 1;
white-space: pre;
max-height: 300px;
overflow: auto;
margin-top: 10px;
}
.footer {
margin-top: 20px;
padding-top: 10px;
border-top: 1px solid #333;
color: #666;
font-size: 11px;
text-align: center;
}
.toggle-btn {
background-color: #222;
color: #6a9;
border: 1px solid #333;
padding: 5px 10px;
font-size: 11px;
cursor: pointer;
margin-top: 5px;
}
.hidden {
display: none;
}
.tab-container {
display: flex;
border-bottom: 1px solid #333;
margin-bottom: 10px;
flex-wrap: wrap;
}
.tab {
padding: 8px 15px;
cursor: pointer;
border: 1px solid transparent;
border-bottom: none;
margin-right: 5px;
background-color: #222;
margin-bottom: 5px;
}
.tab.active {
background-color: #111;
border-color: #333;
border-bottom: 1px solid #111;
color: #6a9;
}
.tab-content {
display: none;
}
.tab-content.active {
display: block;
}
.status-indicator {
display: inline-block;
width: 10px;
height: 10px;
border-radius: 50%;
margin-right: 5px;
}
.status-safe {
background-color: #6c6;
}
.status-warning {
background-color: #fc6;
}
.status-danger {
background-color: #f66;
}
.font-options {
display: grid;
grid-template-columns: repeat(2, 1fr);
gap: 5px;
margin-top: 10px;
}
.font-option {
padding: 5px;
border: 1px solid #333;
cursor: pointer;
background-color: #0a0a0a;
font-family: monospace;
text-align: center;
font-size: 11px;
}
.font-option:hover {
border-color: #a66;
}
.font-option.active {
border-color: #a66;
background-color: #222;
}
.text-examples {
display: flex;
flex-wrap: wrap;
gap: 5px;
margin-top: 10px;
}
.example-btn {
padding: 5px 10px;
background-color: #222;
border: 1px solid #333;
color: #d0d0d0;
cursor: pointer;
font-size: 11px;
}
.example-btn:hover {
background-color: #333;
border-color: #a66;
}
.banner-style {
background-color: #1a1a1a;
border-left: 3px solid #a66;
padding: 10px;
margin: 10px 0;
}
</style>
</head>
<body>
<div class="container">
<div class="header">
<h1>Complete ASCII Art Generator</h1>
<div class="subtitle">Convert images to ASCII OR create ASCII art from text directly</div>
<div class="warning">
โ ๏ธ <strong>FOR EDUCATIONAL PURPOSES ONLY</strong> โ ๏ธ<br>
This tool demonstrates how automated content detection systems work and methods that might evade them.<br>
Always respect community guidelines and terms of service.
</div>
</div>
<div class="content">
<div class="panel">
<div class="tab-container">
<div class="tab active" data-tab="image">Image to ASCII</div>
<div class="tab" data-tab="text">Text to ASCII</div>
<div class="tab" data-tab="stealth">Stealth Methods</div>
<div class="tab" data-tab="detection">Detection Simulator</div>
</div>
<div id="image-tab" class="tab-content active">
<div class="panel-title">Image Upload</div>
<div class="upload-area" id="uploadArea">
<div>๐ Click or drop image here</div>
<div style="font-size: 10px; color: #666; margin-top: 5px;">JPG, PNG, GIF supported</div>
<input type="file" id="imageInput" accept="image/*">
</div>
<div class="image-preview">
<img id="previewImage" alt="Preview">
</div>
<div class="control-group">
<div class="control-label">Output Width: <span id="widthValue">60</span> chars</div>
<div class="slider-container">
<input type="range" id="outputWidth" min="20" max="100" value="60">
</div>
</div>
<div class="control-group">
<div class="control-label">ASCII Character Set:</div>
<div class="char-options">
<div class="char-option active" data-charset="@">@ Only</div>
<div class="char-option" data-charset="@#%">Mixed @#%</div>
<div class="char-option" data-charset="โโโโ">Blocks โโโโ</div>
<div class="char-option" data-charset="ยทโขโฆโ">Dots ยทโขโฆโ</div>
<div class="char-option" data-charset="random">Random</div>
</div>
</div>
<button class="btn btn-primary" id="convertImageBtn">Generate from Image</button>
<button class="btn" id="sampleBtn">Load Sample Image</button>
</div>
<div id="text-tab" class="tab-content">
<div class="panel-title">Text to ASCII Art</div>
<div class="control-group">
<div class="control-label">Enter Text:</div>
<textarea id="inputText" placeholder="Type your text here...">ASCII ART</textarea>
</div>
<div class="control-group">
<div class="control-label">ASCII Font Style:</div>
<div class="font-options" id="fontOptions">
<div class="font-option active" data-font="block">Block</div>
<div class="font-option" data-font="banner">Banner</div>
<div class="font-option" data-font="simple">Simple</div>
<div class="font-option" data-font="outline">Outline</div>
</div>
</div>
<div class="control-group">
<div class="control-label">Character Style:</div>
<div class="char-options">
<div class="char-option active" data-textchar="@">@</div>
<div class="char-option" data-textchar="#">#</div>
<div class="char-option" data-textchar="โ">โ</div>
<div class="char-option" data-textchar="*">*</div>
<div class="char-option" data-textchar="โ">โ</div>
</div>
</div>
<div class="control-group">
<div class="control-label">Quick Examples:</div>
<div class="text-examples">
<button class="example-btn" data-example="hello">Hello</button>
<button class="example-btn" data-example="jschan">JSChan</button>
<button class="example-btn" data-example="anon">Anon</button>
<button class="example-btn" data-example="test">Test</button>
<button class="example-btn" data-example="ascii">ASCII</button>
<button class="example-btn" data-example="cool">Cool</button>
</div>
</div>
<button class="btn btn-text" id="convertTextBtn">Generate from Text</button>
<button class="btn" id="clearTextBtn">Clear Text</button>
</div>
<div id="stealth-tab" class="tab-content">
<div class="panel-title">Stealth Methods</div>
<div class="stealth-controls">
<div class="stealth-option">
<label class="stealth-label">
<input type="checkbox" id="stealthNoise" checked> Add Random Noise
</label>
<div class="stealth-desc">Randomly replaces 5% of characters with different ones</div>
</div>
<div class="stealth-option">
<label class="stealth-label">
<input type="checkbox" id="stealthLines" checked> Varied Line Endings
</label>
<div class="stealth-desc">Adds random characters at line ends to break patterns</div>
</div>
<div class="stealth-option">
<label class="stealth-label">
<input type="checkbox" id="stealthEmbed" checked> Embed in Text
</label>
<div class="stealth-desc">Wraps ASCII in natural-looking conversation</div>
</div>
<div class="stealth-option">
<label class="stealth-label">
<input type="checkbox" id="stealthSpoiler"> Use Spoiler Tags
</label>
<div class="stealth-desc">Wraps output in spoiler tags (reduces visibility)</div>
</div>
<div class="stealth-option">
<label class="stealth-label">
<input type="checkbox" id="stealthTimeSplit"> Suggest Time Splitting
</label>
<div class="stealth-desc">Adds instructions to post in parts over time</div>
</div>
<button class="btn btn-stealth" id="applyStealth">Apply Stealth Methods</button>
</div>
<div class="control-group">
<div class="control-label">Stealth Level: <span id="stealthValue">5</span>/10</div>
<div class="slider-container">
<input type="range" id="stealthLevel" min="1" max="10" value="5">
</div>
<div class="stealth-desc">Higher = more stealth but less accurate ASCII art</div>
</div>
</div>
<div id="detection-tab" class="tab-content">
<div class="panel-title">Detection Simulator</div>
<div class="detection-simulator">
<div class="control-label">Simulated Moderation System</div>
<div class="stealth-option">
<label class="stealth-label">
<input type="checkbox" id="detectRepeat" checked> Detect Repeated Characters
</label>
</div>
<div class="stealth-option">
<label class="stealth-label">
<input type="checkbox" id="detectPattern" checked> Detect Visual Patterns
</label>
</div>
<div class="stealth-option">
<label class="stealth-label">
<input type="checkbox" id="detectDensity" checked> Character Density Analysis
</label>
</div>
<button class="btn" id="runDetection">Run Detection Analysis</button>
<div id="detectionResult" class="detection-result">
Run analysis to see detection results...
</div>
<div class="stealth-desc">
This simulates basic automated detection. Real systems use more advanced methods.
</div>
</div>
</div>
</div>
<div class="panel">
<div class="panel-title">Output & Post Preparation</div>
<div class="output-container">
<textarea id="asciiOutput" placeholder="ASCII art will appear here..."></textarea>
</div>
<div class="output-tools">
<button class="btn" id="copyBtn">Copy to Clipboard</button>
<button class="btn" id="clearBtn">Clear</button>
<button class="btn" id="stealthifyBtn">Auto-Stealthify</button>
<button class="btn" id="previewBtn">Preview Post</button>
</div>
<div class="panel-title" style="margin-top: 15px;">Formatted Outputs</div>
<div class="tab-container" style="margin-top: 10px;">
<div class="tab active" data-format="jschan">JSChan Format</div>
<div class="tab" data-format="textboard">Textboard Format</div>
<div class="tab" data-format="stealth">Stealth Format</div>
</div>
<div id="jschan-format" class="tab-content active">
<div class="format-block" id="jschanCode">
[code]
[ascii]
Your ASCII art will appear here
[/ascii]
[/code]
</div>
<button class="btn" id="copyJschanBtn">Copy JSChan Format</button>
</div>
<div id="textboard-format" class="tab-content">
<div class="format-block" id="textboardCode">
[pre]
Your ASCII art will appear here
[/pre]
</div>
<button class="btn" id="copyTextboardBtn">Copy Textboard Format</button>
</div>
<div id="stealth-format" class="tab-content">
<div class="format-block" id="stealthCode">
Hey check out this cool pattern I noticed:
[spoiler]
[code]
Your ASCII art will appear here
[/code]
[/spoiler]
What do you think? Looks like a random glitch in my terminal lol
</div>
<button class="btn" id="copyStealthBtn">Copy Stealth Format</button>
</div>
<div id="previewSection" class="hidden">
<div class="panel-title" style="margin-top: 15px;">Post Preview</div>
<div class="preview-output" id="previewOutput"></div>
</div>
</div>
</div>
<div class="footer">
<div>Complete ASCII Tool โข Image-to-ASCII & Text-to-ASCII โข Educational purposes only</div>
</div>
</div>
<script>
// DOM Elements
const imageInput = document.getElementById('imageInput');
const uploadArea = document.getElementById('uploadArea');
const previewImage = document.getElementById('previewImage');
const widthSlider = document.getElementById('outputWidth');
const widthValue = document.getElementById('widthValue');
const convertImageBtn = document.getElementById('convertImageBtn');
const sampleBtn = document.getElementById('sampleBtn');
const asciiOutput = document.getElementById('asciiOutput');
const copyBtn = document.getElementById('copyBtn');
const clearBtn = document.getElementById('clearBtn');
const stealthifyBtn = document.getElementById('stealthifyBtn');
const previewBtn = document.getElementById('previewBtn');
const jschanCode = document.getElementById('jschanCode');
const copyJschanBtn = document.getElementById('copyJschanBtn');
const textboardCode = document.getElementById('textboardCode');
const copyTextboardBtn = document.getElementById('copyTextboardBtn');
const stealthCode = document.getElementById('stealthCode');
const copyStealthBtn = document.getElementById('copyStealthBtn');
const previewSection = document.getElementById('previewSection');
const previewOutput = document.getElementById('previewOutput');
const charOptions = document.querySelectorAll('.char-option');
const tabs = document.querySelectorAll('.tab');
const formatTabs = document.querySelectorAll('[data-format]');
// Text-to-ASCII elements
const inputText = document.getElementById('inputText');
const convertTextBtn = document.getElementById('convertTextBtn');
const clearTextBtn = document.getElementById('clearTextBtn');
const fontOptions = document.querySelectorAll('.font-option');
const textCharOptions = document.querySelectorAll('[data-textchar]');
const exampleBtns = document.querySelectorAll('.example-btn');
// Stealth controls
const stealthNoise = document.getElementById('stealthNoise');
const stealthLines = document.getElementById('stealthLines');
const stealthEmbed = document.getElementById('stealthEmbed');
const stealthSpoiler = document.getElementById('stealthSpoiler');
const stealthTimeSplit = document.getElementById('stealthTimeSplit');
const stealthLevel = document.getElementById('stealthLevel');
const stealthValue = document.getElementById('stealthValue');
const applyStealth = document.getElementById('applyStealth');
// Detection controls
const detectRepeat = document.getElementById('detectRepeat');
const detectPattern = document.getElementById('detectPattern');
const detectDensity = document.getElementById('detectDensity');
const runDetection = document.getElementById('runDetection');
const detectionResult = document.getElementById('detectionResult');
// Variables
let currentImage = null;
let selectedCharset = '@';
let currentAsciiText = '';
let stealthMode = false;
let selectedFont = 'block';
let selectedTextChar = '@';
// ASCII font data
const asciiFonts = {
block: {
'A': [" โโโโโโ ", "โโโโโโโโ", "โโโโโโโโ", "โโโโโโโโ", "โโโ โโโ", "โโโ โโโ"],
'B': ["โโโโโโโ ", "โโโโโโโโ", "โโโโโโโโ", "โโโโโโโโ", "โโโโโโโโ", "โโโโโโโ "],
'C': [" โโโโโโโ", "โโโโโโโโ", "โโโ ", "โโโ ", "โโโโโโโโ", " โโโโโโโ"],
'D': ["โโโโโโโ ", "โโโโโโโโ", "โโโ โโโ", "โโโ โโโ", "โโโโโโโโ", "โโโโโโโ "],
'E': ["โโโโโโโโ", "โโโโโโโโ", "โโโโโโ ", "โโโโโโ ", "โโโโโโโโ", "โโโโโโโโ"],
'F': ["โโโโโโโโ", "โโโโโโโโ", "โโโโโโ ", "โโโโโโ ", "โโโ ", "โโโ "],
'G': [" โโโโโโโ ", "โโโโโโโโ ", "โโโ โโโโ", "โโโ โโโ", "โโโโโโโโโ", " โโโโโโโ "],
'H': ["โโโ โโโ", "โโโ โโโ", "โโโโโโโโ", "โโโโโโโโ", "โโโ โโโ", "โโโ โโโ"],
'I': ["โโโ", "โโโ", "โโโ", "โโโ", "โโโ", "โโโ"],
'J': [" โโโ", " โโโ", " โโโ", "โโ โโโ", "โโโโโโโโ", " โโโโโโ "],
'K': ["โโโ โโโ", "โโโ โโโโ", "โโโโโโโ ", "โโโโโโโ ", "โโโ โโโ", "โโโ โโโ"],
'L': ["โโโ ", "โโโ ", "โโโ ", "โโโ ", "โโโโโโโโ", "โโโโโโโโ"],
'M': ["โโโโ โโโโ", "โโโโโ โโโโโ", "โโโโโโโโโโโ", "โโโโโโโโโโโ", "โโโ โโโ โโโ", "โโโ โโโ"],
'N': ["โโโโ โโโ", "โโโโโ โโโ", "โโโโโโ โโโ", "โโโโโโโโโโ", "โโโ โโโโโโ", "โโโ โโโโโ"],
'O': [" โโโโโโโ ", "โโโโโโโโโ", "โโโ โโโ", "โโโ โโโ", "โโโโโโโโโ", " โโโโโโโ "],
'P': ["โโโโโโโ ", "โโโโโโโโ", "โโโโโโโโ", "โโโโโโโ ", "โโโ ", "โโโ "],
'Q': [" โโโโโโโ ", "โโโโโโโโโ", "โโโ โโโ", "โโโโโ โโโ", "โโโโโโโโโ", " โโโโโโโ "],
'R': ["โโโโโโโ ", "โโโโโโโโ", "โโโโโโโโ", "โโโโโโโโ", "โโโ โโโ", "โโโ โโโ"],
'S': [" โโโโโโโโ", "โโโโโโโโ", "โโโโโโโโ", "โโโโโโโโ", "โโโโโโโโ", "โโโโโโโโ"],
'T': ["โโโโโโโโโ", "โโโโโโโโโ", " โโโ ", " โโโ ", " โโโ ", " โโโ "],
'U': ["โโโ โโโ", "โโโ โโโ", "โโโ โโโ", "โโโ โโโ", "โโโโโโโโโ", " โโโโโโโ "],
'V': ["โโโ โโโ", "โโโ โโโ", "โโโ โโโ", "โโโโ โโโโ", " โโโโโโโ ", " โโโโโ "],
'W': ["โโโ โโโ", "โโโ โโโ", "โโโ โโ โโโ", "โโโโโโโโโโ", "โโโโโโโโโโ", " โโโโโโโโ "],
'X': ["โโโ โโโ", "โโโโโโโโ", " โโโโโโ ", " โโโโโโ ", "โโโโ โโโ", "โโโ โโโ"],
'Y': ["โโโ โโโ", "โโโโ โโโโ", " โโโโโโโ ", " โโโโโ ", " โโโ ", " โโโ "],
'Z': ["โโโโโโโโ", "โโโโโโโโ", " โโโโโ ", " โโโโโ ", "โโโโโโโโ", "โโโโโโโโ"],
' ': [" ", " ", " ", " ", " ", " "],
'!': ["โโโ", "โโโ", "โโโ", "โโโ", "โโโ", "โโโ"],
'?': [" โโโโโโ ", "โโโโโโโโ", " โโโโ ", " โโโโ ", " โโโ ", " โโโ "]
},
banner: {
'A': [" ___ ", " / _ \\ ", "/ /_\\ \\ ", "| _ | ", "| | | | ", "\\_| |_/ "],
'B': [" ____ ", "| _ \\ ", "| |_) |", "| _ < ", "| |_) |", "|____/ "],
'C': [" ____ ", " / ___|", "| | ", "| |___ ", " \\____|", " "],
'D': [" ____ ", "| _ \\ ", "| | | |", "| |_| |", "|____/ ", " "],
'E': [" _____ ", "| ____|", "| _| ", "| |___ ", "|_____|", " "],
'F': [" _____ ", "| ___|", "| |_ ", "| _| ", "|_| ", " "],
'G': [" ____ ", " / ___|", "| | _ ", "| |_| |", " \\____|", " "],
'H': [" _ _ ", "| | | |", "| |_| |", "| _ |", "| | | |", "|_| |_|"],
'I': [" ___ ", "|_ _|", " | | ", " | | ", "|___|", " "],
'J': [" _ ", " | |", " | |", "_ | |", "| |__| |", " \\____/ "],
'K': [" _ __", "| |/ /", "| ' / ", "| . \\ ", "|_|\\_\\", " "],
'L': [" _ ", "| | ", "| | ", "| |___ ", "|_____|", " "],
'M': [" __ __ ", "| \\/ |", "| |\\/| |", "| | | |", "|_| |_|", " "],
'N': [" _ _ ", "| \\ | |", "| \\| |", "| |\\ |", "|_| \\_|", " "],
'O': [" ___ ", " / _ \\ ", "| | | |", "| |_| |", " \\___/ ", " "],
'P': [" ____ ", "| _ \\ ", "| |_) |", "| __/ ", "|_| ", " "],
'Q': [" ___ ", " / _ \\ ", "| | | |", "| |_| |", " \\__\\_\\", " "],
'R': [" ____ ", "| _ \\ ", "| |_) |", "| _ < ", "|_| \\_\\", " "],
'S': [" ____ ", "/ ___| ", "\\___ \\ ", " ___) |", "|____/ ", " "],
'T': [" _____ ", "|_ _|", " | | ", " | | ", " |_| ", " "],
'U': [" _ _ ", "| | | |", "| | | |", "| |_| |", " \\___/ ", " "],
'V': ["__ __", "\\ \\ / /", " \\ \\ / / ", " \\ V / ", " \\_/ ", " "],
'W': ["__ __", "\\ \\ / /", " \\ \\ /\\ / / ", " \\ V V / ", " \\_/\\_/ ", " "],
'X': ["__ __", "\\ \\/ /", " \\ / ", " / \\ ", "/_/\\_\\", " "],
'Y': ["__ __", "\\ \\ / /", " \\ V / ", " | | ", " |_| ", " "],
'Z': [" _____", "|__ /", " / / ", " / /_ ", "/____|", " "],
' ': [" ", " ", " ", " ", " ", " "],
'!': [" _ ", "| |", "| |", "|_|", "(_)", " "],
'?': [" ___ ", "|__ \\", " / /", " |_| ", " (_) ", " "]
},
simple: {
'A': [" ## ", "# #", "####", "# #", "# #", " "],
'B': ["### ", "# #", "### ", "# #", "### ", " "],
'C': [" ## ", "# #", "# ", "# #", " ## ", " "],
'D': ["### ", "# #", "# #", "# #", "### ", " "],
'E': ["####", "# ", "### ", "# ", "####", " "],
'F': ["####", "# ", "### ", "# ", "# ", " "],
'G': [" ## ", "# ", "# ##", "# #", " ## ", " "],
'H': ["# #", "# #", "####", "# #", "# #", " "],
'I': ["###", " # ", " # ", " # ", "###", " "],
'J': [" ##", " #", " #", "# #", " ## ", " "],
'K': ["# #", "# # ", "## ", "# # ", "# #", " "],
'L': ["# ", "# ", "# ", "# ", "####", " "],
'M': ["# #", "## ##", "# # #", "# #", "# #", " "],
'N': ["# #", "## #", "# # #", "# ##", "# #", " "],
'O': [" ## ", "# #", "# #", "# #", " ## ", " "],
'P': ["### ", "# #", "### ", "# ", "# ", " "],
'Q': [" ## ", "# #", "# #", " ## ", " #", " "],
'R': ["### ", "# #", "### ", "# # ", "# #", " "],
'S': [" ###", "# ", " ## ", " #", "### ", " "],
'T': ["#####", " # ", " # ", " # ", " # ", " "],
'U': ["# #", "# #", "# #", "# #", " ## ", " "],
'V': ["# #", "# #", " # # ", " # # ", " # ", " "],
'W': ["# #", "# #", "# # #", "## ##", "# #", " "],
'X': ["# #", " # # ", " # ", " # # ", "# #", " "],
'Y': ["# #", " # # ", " # ", " # ", " # ", " "],
'Z': ["#####", " # ", " # ", " # ", "#####", " "],
' ': [" ", " ", " ", " ", " ", " "],
'!': ["#", "#", "#", " ", "#", " "],
'?': [" ## ", "# #", " # ", " # ", " # ", " "]
},
outline: {
'A': [" .d8888b. ", "d88P Y88b", "888 888", "888 888", "Y88b d88P", " \"Y8888P\" "],
'B': ["888888b. ", "888 \"88b ", "888 .88P ", "8888888K. ", "888 \"Y88b", "888 Y88P"],
'C': [" .d8888b. ", "d88P Y88b", "888 ", "888 ", "Y88b d88P", " \"Y8888P\" "],
'D': ["8888888b. ", "888 Y88b", "888 888", "888 888", "888 d88P", "8888888P\" "],
'E': ["8888888888", "888 ", "8888888 ", "888 ", "888 ", "8888888888"],
'F': ["8888888888", "888 ", "8888888 ", "888 ", "888 ", "888 "],
'G': [" .d8888b. ", "d88P Y88b", "888 ", "888 88888", "Y88b d88P", " \"Y8888P8 "],
'H': ["888 888", "888 888", "8888888888", "888 888", "888 888", "888 888"],
'I': ["888", "888", "888", "888", "888", "888"],
'J': [" 888", " 888", " 888", "888 888", "\"Y88888P'", " "],
'K': ["888 888", "888 888 ", "8888888 ", "888 888 ", "888 888", "888 888"],
'L': ["888 ", "888 ", "888 ", "888 ", "888 ", "888888888"],
'M': ["888b d888", "8888b d8888", "88888b.d88888", "888Y88888P888", "888 Y888P 888", "888 Y8P 888"],
'N': ["888b 888", "8888b 888", "88888b 888", "888Y88b 888", "888 Y88b888", "888 Y88888"],
'O': [" .d8888b. ", "d88P Y88b", "888 888", "888 888", "Y88b d88P", " \"Y8888P\" "],
'P': ["8888888b. ", "888 \"Y88b", "888 888", "888 888", "888 d88P ", "8888888P\" "],
'Q': [" .d8888b. ", "d88P Y88b", "888 888", "888 888", "Y88b d88P", " \"Y8888P\" "],
'R': ["8888888b. ", "888 \"Y88b", "888 888", "888 d8P", "888 d8P ", "888 d8P "],
'S': [".d8888b. ", "d88P \"88b", "\"Y8888b. ", " \"Y88b", "888 888", "Y888888P'"],
'T': ["8888888888", " 888 ", " 888 ", " 888 ", " 888 ", " 888 "],
'U': ["888 888", "888 888", "888 888", "888 888", "\"Y88888P'", " "],
'V': ["888 888", "888 888", "Y88b d88P", " Y88b d88P ", " Y88o88P ", " Y888P "],
'W': ["888 888", "888 888", "888 888", "888 888", "Y88b. .d88P", " \"Y88888P\" "],
'X': ["888 888", "\"Y88b d88P", " Y88bd88P ", " Y8888P ", " d88PY88b ", " d88P Y88b"],
'Y': ["888 888", "\"Y88b d88P", " Y88bd88P ", " Y8888P ", " Y88P ", " Y8P "],
'Z': ["8888888888", " d88P", " d88P ", " d88P ", " d88P ", "d88P "],
' ': [" ", " ", " ", " ", " ", " "],
'!': ["888", "888", "888", " ", "888", " "],
'?': [" .d8888b. ", "d88P Y88b", " .d88P", " .d88P ", " 888 ", " 888 "]
}
};
// Event Listeners
uploadArea.addEventListener('click', () => imageInput.click());
uploadArea.addEventListener('dragover', (e) => {
e.preventDefault();
uploadArea.style.borderColor = '#a66';
});
uploadArea.addEventListener('dragleave', () => {
uploadArea.style.borderColor = '#444';
});
uploadArea.addEventListener('drop', (e) => {
e.preventDefault();
uploadArea.style.borderColor = '#444';
if (e.dataTransfer.files.length) {
imageInput.files = e.dataTransfer.files;
handleImageUpload(e.dataTransfer.files[0]);
}
});
imageInput.addEventListener('change', (e) => {
if (e.target.files.length) {
handleImageUpload(e.target.files[0]);
}
});
widthSlider.addEventListener('input', () => {
widthValue.textContent = widthSlider.value;
});
stealthLevel.addEventListener('input', () => {
stealthValue.textContent = stealthLevel.value;
});
convertImageBtn.addEventListener('click', generateAsciiFromImage);
sampleBtn.addEventListener('click', loadSampleImage);
convertTextBtn.addEventListener('click', generateAsciiFromText);
clearTextBtn.addEventListener('click', () => {
inputText.value = '';
});
copyBtn.addEventListener('click', () => {
copyToClipboard(currentAsciiText, 'ASCII art copied to clipboard!');
});
clearBtn.addEventListener('click', () => {
asciiOutput.value = '';
currentAsciiText = '';
updateAllFormats();
});
stealthifyBtn.addEventListener('click', applyStealthMethods);
applyStealth.addEventListener('click', applyStealthMethods);
previewBtn.addEventListener('click', () => {
previewSection.classList.toggle('hidden');
if (!previewSection.classList.contains('hidden')) {
previewOutput.textContent = currentAsciiText || 'Generate ASCII art first';
}
});
copyJschanBtn.addEventListener('click', () => {
copyToClipboard(jschanCode.textContent, 'JSChan format copied!');
});
copyTextboardBtn.addEventListener('click', () => {
copyToClipboard(textboardCode.textContent, 'Textboard format copied!');
});
copyStealthBtn.addEventListener('click', () => {
copyToClipboard(stealthCode.textContent, 'Stealth format copied!');
});
runDetection.addEventListener('click', runDetectionAnalysis);
// Image char options
charOptions.forEach(option => {
option.addEventListener('click', () => {
charOptions.forEach(opt => opt.classList.remove('active'));
option.classList.add('active');
selectedCharset = option.getAttribute('data-charset');
if (currentImage) {
generateAsciiFromImage();
}
});
});
// Text char options
textCharOptions.forEach(option => {
option.addEventListener('click', () => {
textCharOptions.forEach(opt => opt.classList.remove('active'));
option.classList.add('active');
selectedTextChar = option.getAttribute('data-textchar');
});
});
// Font options
fontOptions.forEach(option => {
option.addEventListener('click', () => {
fontOptions.forEach(opt => opt.classList.remove('active'));
option.classList.add('active');
selectedFont = option.getAttribute('data-font');
});
});
// Example buttons
exampleBtns.forEach(btn => {
btn.addEventListener('click', () => {
const example = btn.getAttribute('data-example');
inputText.value = example.toUpperCase();
generateAsciiFromText();
});
});
tabs.forEach(tab => {
tab.addEventListener('click', () => {
const tabId = tab.getAttribute('data-tab');
tabs.forEach(t => t.classList.remove('active'));
tab.classList.add('active');
document.querySelectorAll('.tab-content').forEach(content => {
content.classList.remove('active');
});
document.getElementById(`${tabId}-tab`).classList.add('active');
});
});
formatTabs.forEach(tab => {
tab.addEventListener('click', () => {
const format = tab.getAttribute('data-format');
formatTabs.forEach(t => t.classList.remove('active'));
tab.classList.add('active');
document.querySelectorAll('[id$="-format"]').forEach(content => {
content.classList.remove('active');
});
document.getElementById(`${format}-format`).classList.add('active');
});
});
// Functions
function handleImageUpload(file) {
const reader = new FileReader();
reader.onload = function(e) {
previewImage.src = e.target.result;
previewImage.style.display = 'block';
currentImage = new Image();
currentImage.src = e.target.result;
currentImage.onload = function() {
setTimeout(generateAsciiFromImage, 100);
};
};
reader.readAsDataURL(file);
}
function loadSampleImage() {
const canvas = document.createElement('canvas');
canvas.width = 100;
canvas.height = 100;
const ctx = canvas.getContext('2d');
// Draw a smiley face
ctx.fillStyle = '#000';
ctx.fillRect(0, 0, 100, 100);
ctx.fillStyle = '#fff';
// Eyes
ctx.fillRect(25, 30, 10, 10);
ctx.fillRect(65, 30, 10, 10);
// Smile
for (let i = 0; i < 40; i++) {
ctx.fillRect(30 + i, 60 + Math.sin(i * 0.2) * 5, 1, 3);
}
// Nose
ctx.fillRect(48, 45, 4, 15);
previewImage.src = canvas.toDataURL();
previewImage.style.display = 'block';
currentImage = new Image();
currentImage.src = canvas.toDataURL();
currentImage.onload = function() {
setTimeout(generateAsciiFromImage, 100);
};
}
function generateAsciiFromImage() {
if (!currentImage) {
asciiOutput.value = "Please upload an image first or use the sample button.";
return;
}
asciiOutput.value = "Processing image...";
setTimeout(() => {
const width = parseInt(widthSlider.value);
currentAsciiText = imageToAscii(currentImage, width);
// Apply stealth if enabled
if (stealthMode) {
currentAsciiText = applyStealthToText(currentAsciiText);
}
asciiOutput.value = currentAsciiText;
updateAllFormats();
runDetectionAnalysis();
}, 50);
}
function generateAsciiFromText() {
const text = inputText.value.toUpperCase().trim();
if (!text) {
asciiOutput.value = "Please enter some text first!";
return;
}
asciiOutput.value = "Generating ASCII text...";
setTimeout(() => {
currentAsciiText = textToAscii(text);
// Apply stealth if enabled
if (stealthMode) {
currentAsciiText = applyStealthToText(currentAsciiText);
}
asciiOutput.value = currentAsciiText;
updateAllFormats();
runDetectionAnalysis();
}, 50);
}
function imageToAscii(image, width) {
const canvas = document.createElement('canvas');
const ctx = canvas.getContext('2d');
// Calculate dimensions
const aspectRatio = image.height / image.width;
const outputWidth = Math.min(width, 100);
const outputHeight = Math.floor(outputWidth * aspectRatio * 0.5);
canvas.width = outputWidth;
canvas.height = outputHeight;
// Draw image to canvas
ctx.drawImage(image, 0, 0, outputWidth, outputHeight);
// Get image data
const imageData = ctx.getImageData(0, 0, outputWidth, outputHeight);
const data = imageData.data;
// Get character set
let charset;
if (selectedCharset === 'random') {
charset = '@#%&*+-=โโโโยทโขโฆโ';
} else {
charset = selectedCharset;
}
// Convert to ASCII
let asciiResult = '';
for (let y = 0; y < outputHeight; y++) {
for (let x = 0; x < outputWidth; x++) {
const index = (y * outputWidth + x) * 4;
const r = data[index];
const g = data[index + 1];
const b = data[index + 2];
// Calculate brightness
const brightness = (r + g + b) / 3;
// Determine character based on brightness
const charIndex = Math.floor((brightness / 255) * (charset.length - 1));
let char = charset[charset.length - 1 - charIndex]; // Invert: dark = high index
// If using single character set, just use that character for dark areas
if (charset.length === 1 && brightness < 128) {
char = charset[0];
} else if (charset.length === 1) {
char = ' ';
}
asciiResult += char;
}
asciiResult += '\n';
}
return asciiResult;
}
function textToAscii(text) {
const font = asciiFonts[selectedFont];
let result = '';
// For each character in the text, get its ASCII representation
const lines = Array(6).fill(''); // Most fonts are 6 lines tall
for (let i = 0; i < text.length; i++) {
const char = text[i];
const charLines = font[char] || font[' '];
for (let j = 0; j < 6; j++) {
// Replace the default characters with selected character
let line = charLines[j];
if (selectedTextChar !== '#') {
// Replace # with selected character, keep spaces
line = line.replace(/#/g, selectedTextChar);
line = line.replace(/8/g, selectedTextChar);
line = line.replace(/d/g, selectedTextChar);
line = line.replace(/Y/g, selectedTextChar);
line = line.replace(/P/g, selectedTextChar);
line = line.replace(/b/g, selectedTextChar);
line = line.replace(/"/g, selectedTextChar);
line = line.replace(/\./g, ' ');
line = line.replace(/\|/g, selectedTextChar);
line = line.replace(/_/g, selectedTextChar);
line = line.replace(/-/g, selectedTextChar);
line = line.replace(/\\/g, selectedTextChar);
line = line.replace(/\//g, selectedTextChar);
line = line.replace(/=/g, selectedTextChar);
line = line.replace(/</g, selectedTextChar);
line = line.replace(/>/g, selectedTextChar);
}
lines[j] += line + ' ';
}
}
// Combine lines
result = lines.join('\n');
// Add a border if it's a banner style
if (selectedFont === 'banner') {
const borderLength = Math.max(...lines.map(l => l.length));
const border = selectedTextChar.repeat(borderLength);
result = border + '\n' + result + '\n' + border;
}
return result;
}
function applyStealthMethods() {
stealthMode = true;
if (!currentAsciiText) {
alert("Generate ASCII art first!");
return;
}
let stealthText = currentAsciiText;
// Apply noise if enabled
if (stealthNoise.checked) {
stealthText = addRandomNoise(stealthText);
}
// Apply varied line endings if enabled
if (stealthLines.checked) {
stealthText = addVariedLineEndings(stealthText);
}
currentAsciiText = stealthText;
asciiOutput.value = currentAsciiText;
updateAllFormats();
runDetectionAnalysis();
alert("Stealth methods applied! Detection resistance increased.");
}
function applyStealthToText(text) {
let result = text;
const level = parseInt(stealthLevel.value);
// Apply noise based on level
if (stealthNoise.checked) {
result = addRandomNoise(result, level * 0.5);
}
// Apply line variations
if (stealthLines.checked) {
result = addVariedLineEndings(result, level);
}
return result;
}
function addRandomNoise(text, intensity = 5) {
const lines = text.split('\n');
const noiseChars = ' .:,;+-*|/\\';
return lines.map(line => {
let newLine = '';
for (let i = 0; i < line.length; i++) {
// Chance to replace character with noise
if (Math.random() < (intensity / 100) && line[i] !== ' ') {
newLine += noiseChars[Math.floor(Math.random() * noiseChars.length)];
} else {
newLine += line[i];
}
}
return newLine;
}).join('\n');
}
function addVariedLineEndings(text, intensity = 5) {
const lines = text.split('\n');
const endChars = ' .,:;|';
return lines.map(line => {
// Add random characters to the end of some lines
if (Math.random() < (intensity / 20) && line.trim().length > 10) {
const extraChars = Math.floor(Math.random() * 3) + 1;
for (let i = 0; i < extraChars; i++) {
line += endChars[Math.floor(Math.random() * endChars.length)];
}
}
return line;
}).join('\n');
}
function updateAllFormats() {
// JSChan format
let jschanText = `[code]\n[ascii]\n${currentAsciiText}[/ascii]\n[/code]`;
// Textboard format
let textboardText = `[pre]\n${currentAsciiText}[/pre]`;
// Stealth format
let stealthText = `Hey check out this cool pattern I noticed:\n`;
if (stealthSpoiler.checked) {
stealthText += `[spoiler]\n`;
}
stealthText += `[code]\n${currentAsciiText}[/code]\n`;
if (stealthSpoiler.checked) {
stealthText += `[/spoiler]\n`;
}
stealthText += `What do you think? Looks like a random glitch in my terminal lol`;
if (stealthTimeSplit.checked) {
stealthText += `\n\n(Posting in parts to avoid filter...)`;
}
jschanCode.textContent = jschanText;
textboardCode.textContent = textboardText;
stealthCode.textContent = stealthText;
if (!previewSection.classList.contains('hidden')) {
previewOutput.textContent = currentAsciiText;
}
}
function runDetectionAnalysis() {
if (!currentAsciiText) {
detectionResult.innerHTML = '<span class="status-indicator status-safe"></span> No text to analyze';
detectionResult.className = 'detection-result safe';
return;
}
let score = 0;
let warnings = [];
// Check for repeated characters
if (detectRepeat.checked) {
const repeated = currentAsciiText.match(/(.)\1{8,}/g);
if (repeated) {
score += 30;
warnings.push(`Found ${repeated.length} sequences of 8+ identical characters`);
}
}
// Check character density
if (detectDensity.checked) {
const nonSpace = currentAsciiText.replace(/[\s\n]/g, '');
const uniqueChars = new Set(nonSpace).size;
const totalChars = nonSpace.length;
if (totalChars > 100) {
const diversityRatio = uniqueChars / totalChars;
if (diversityRatio < 0.2) {
score += 25;
warnings.push(`Low character diversity: ${uniqueChars} unique chars out of ${totalChars}`);
}
}
}
// Check for patterns (simple version)
if (detectPattern.checked) {
const lines = currentAsciiText.split('\n');
let patternCount = 0;
// Check for lines with similar character patterns
for (let i = 0; i < lines.length - 3; i++) {
if (lines[i].length > 10 &&
lines[i+1].length > 10 &&
Math.abs(lines[i].length - lines[i+1].length) < 3) {
patternCount++;
}
}
if (patternCount > lines.length * 0.3) {
score += 20;
warnings.push(`Detected ${patternCount} lines with similar patterns`);
}
}
// Check overall size
if (currentAsciiText.length > 1000) {
score += 15;
warnings.push(`Large text block: ${currentAsciiText.length} characters`);
}
// Determine risk level
let resultHtml = '';
if (score === 0) {
resultHtml = '<span class="status-indicator status-safe"></span> <strong>SAFE</strong>: Unlikely to trigger detection';
detectionResult.className = 'detection-result safe';
} else if (score < 40) {
resultHtml = '<span class="status-indicator status-warning"></span> <strong>LOW RISK</strong>: Might trigger basic filters';
detectionResult.className = 'detection-result warning-detection';
} else if (score < 70) {
resultHtml = '<span class="status-indicator status-warning"></span> <strong>MODERATE RISK</strong>: Could be detected by automated systems';
detectionResult.className = 'detection-result warning-detection';
} else {
resultHtml = '<span class="status-indicator status-danger"></span> <strong>HIGH RISK</strong>: Likely to be detected';
detectionResult.className = 'detection-result danger';
}
resultHtml += `<br><small>Detection score: ${score}/100</small>`;
if (warnings.length > 0) {
resultHtml += '<br><br><strong>Issues detected:</strong><ul style="margin-left: 15px;">';
warnings.forEach(warning => {
resultHtml += `<li>${warning}</li>`;
});
resultHtml += '</ul>';
}
if (stealthMode) {
resultHtml += '<br><small>Stealth mode is active (reduces detection risk)</small>';
}
detectionResult.innerHTML = resultHtml;
}
function copyToClipboard(text, successMessage) {
if (!text || text.includes('Your ASCII art will appear here')) {
alert("No content to copy! Generate some art first.");
return;
}
navigator.clipboard.writeText(text).then(() => {
alert(successMessage || "Copied to clipboard!");
}).catch(err => {
// Fallback
const textArea = document.createElement('textarea');
textArea.value = text;
document.body.appendChild(textArea);
textArea.select();
document.execCommand('copy');
document.body.removeChild(textArea);
alert(successMessage || "Copied to clipboard!");
});
}
// Initialize
asciiOutput.value = "Use the tabs above to:\n1. Convert images to ASCII\n2. Create ASCII text art\n3. Apply stealth methods\n4. Test detection systems";
updateAllFormats();
// Load sample image on start and generate sample text
setTimeout(() => {
loadSampleImage();
setTimeout(() => {
inputText.value = "JSCHAN";
generateAsciiFromText();
}, 600);
}, 500);
</script>
</body>
</html>