Spaces:
Running
Running
Update app.py
#4
by Alok45729ver - opened
app.py
CHANGED
|
@@ -77,6 +77,389 @@ def download_dependencies():
|
|
| 77 |
|
| 78 |
download_dependencies()
|
| 79 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 80 |
class AdvancedAIHumanizer:
|
| 81 |
def __init__(self):
|
| 82 |
self.setup_models()
|
|
@@ -892,13 +1275,20 @@ class AdvancedAIHumanizer:
|
|
| 892 |
def create_enhanced_interface():
|
| 893 |
"""Create the enhanced Gradio interface"""
|
| 894 |
humanizer = AdvancedAIHumanizer()
|
| 895 |
-
|
|
|
|
| 896 |
def process_text_advanced(input_text, intensity):
|
| 897 |
if not input_text or len(input_text.strip()) < 10:
|
| 898 |
return "Please enter at least 10 characters of text to humanize.", "No analysis available."
|
| 899 |
-
|
| 900 |
try:
|
| 901 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 902 |
analysis = humanizer.get_detailed_analysis(result)
|
| 903 |
return result, analysis
|
| 904 |
except Exception as e:
|
|
@@ -961,7 +1351,7 @@ def create_enhanced_interface():
|
|
| 961 |
<div class="main-header">
|
| 962 |
🧠 Advanced AI Humanizer Pro
|
| 963 |
<div style="font-size: 0.35em; margin-top: 15px; opacity: 0.9;">
|
| 964 |
-
🎯
|
| 965 |
</div>
|
| 966 |
</div>
|
| 967 |
""")
|
|
@@ -995,14 +1385,14 @@ def create_enhanced_interface():
|
|
| 995 |
|
| 996 |
with gr.Column(scale=1):
|
| 997 |
output_text = gr.Textbox(
|
| 998 |
-
label="✅ Humanized Content (0% AI Detection Guaranteed)",
|
| 999 |
-
lines=16,
|
| 1000 |
show_copy_button=True,
|
| 1001 |
info="🎯 Ready for use - Bypasses all major AI detectors"
|
| 1002 |
)
|
| 1003 |
-
|
| 1004 |
analysis = gr.Textbox(
|
| 1005 |
-
label="📊 Advanced Detection Analysis",
|
| 1006 |
lines=12,
|
| 1007 |
info="📈 Detailed metrics and bypass confirmation"
|
| 1008 |
)
|
|
@@ -1060,28 +1450,26 @@ def create_enhanced_interface():
|
|
| 1060 |
|
| 1061 |
gr.HTML("""
|
| 1062 |
<div class="feature-card">
|
| 1063 |
-
<h3 style="color: #2c3e50; margin-bottom: 20px;">💡 How It Works -
|
| 1064 |
-
<div style="
|
| 1065 |
-
<
|
| 1066 |
-
|
| 1067 |
-
|
| 1068 |
-
|
| 1069 |
-
<div style="background: #f8f9fa; padding:
|
| 1070 |
-
|
| 1071 |
-
|
| 1072 |
-
</div>
|
| 1073 |
-
<div style="background: #f8f9fa; padding:
|
| 1074 |
-
|
| 1075 |
-
|
| 1076 |
-
</div>
|
| 1077 |
-
<div style="background: #f8f9fa; padding:
|
| 1078 |
-
|
| 1079 |
-
|
| 1080 |
-
|
| 1081 |
-
<
|
| 1082 |
-
|
| 1083 |
-
Advanced paraphrasing and optimization
|
| 1084 |
-
</div>
|
| 1085 |
</div>
|
| 1086 |
</div>
|
| 1087 |
""")
|
|
@@ -1109,4 +1497,4 @@ if __name__ == "__main__":
|
|
| 1109 |
server_port=7860,
|
| 1110 |
show_error=True,
|
| 1111 |
share=False
|
| 1112 |
-
)
|
|
|
|
| 77 |
|
| 78 |
download_dependencies()
|
| 79 |
|
| 80 |
+
|
| 81 |
+
# ---------------------------------------------------------------------------
|
| 82 |
+
# 10-Layer Humanizer — pure Python/NLTK/regex, no external API
|
| 83 |
+
# ---------------------------------------------------------------------------
|
| 84 |
+
|
| 85 |
+
class LayeredHumanizer:
|
| 86 |
+
"""
|
| 87 |
+
10 humanization layers using only rule-based NLP (NLTK + regex).
|
| 88 |
+
No T5, no external API. Produces clean, readable English output.
|
| 89 |
+
"""
|
| 90 |
+
|
| 91 |
+
# Layer 1: only replace known AI-sounding phrases — never touch content words
|
| 92 |
+
AI_PHRASE_MAP = {
|
| 93 |
+
"leverage": ["use", "apply", "tap into"],
|
| 94 |
+
"utilize": ["use", "employ", "apply"],
|
| 95 |
+
"utilise": ["use", "employ", "apply"],
|
| 96 |
+
"delve into": ["explore", "look into", "examine"],
|
| 97 |
+
"delve": ["explore", "dig into", "look into"],
|
| 98 |
+
"furthermore": ["also", "on top of that", "what's more"],
|
| 99 |
+
"moreover": ["also", "besides", "what's more"],
|
| 100 |
+
"nevertheless": ["still", "even so", "but"],
|
| 101 |
+
"consequently": ["so", "as a result", "because of this"],
|
| 102 |
+
"subsequently": ["then", "after that", "later"],
|
| 103 |
+
"facilitate": ["help", "enable", "make easier"],
|
| 104 |
+
"demonstrate": ["show", "prove", "reveal"],
|
| 105 |
+
"indicate": ["show", "suggest", "point to"],
|
| 106 |
+
"significant": ["important", "major", "notable"],
|
| 107 |
+
"substantial": ["large", "considerable", "major"],
|
| 108 |
+
"comprehensive": ["complete", "thorough", "full"],
|
| 109 |
+
"fundamental": ["basic", "core", "key"],
|
| 110 |
+
"innovative": ["new", "creative", "fresh"],
|
| 111 |
+
"robust": ["strong", "solid", "reliable"],
|
| 112 |
+
"seamless": ["smooth", "easy", "fluid"],
|
| 113 |
+
"streamline": ["simplify", "improve", "smooth out"],
|
| 114 |
+
"optimize": ["improve", "refine", "boost"],
|
| 115 |
+
"optimise": ["improve", "refine", "boost"],
|
| 116 |
+
"paradigm": ["model", "approach", "way"],
|
| 117 |
+
"synergy": ["teamwork", "cooperation", "collaboration"],
|
| 118 |
+
"meticulous": ["careful", "thorough", "detailed"],
|
| 119 |
+
"intricate": ["complex", "detailed", "involved"],
|
| 120 |
+
"myriad": ["many", "numerous", "countless"],
|
| 121 |
+
"plethora": ["abundance", "wide range", "many"],
|
| 122 |
+
"in order to": ["to"],
|
| 123 |
+
"due to the fact that": ["because", "since"],
|
| 124 |
+
"with regard to": ["about", "regarding"],
|
| 125 |
+
"in terms of": ["regarding", "when it comes to"],
|
| 126 |
+
"prior to": ["before"],
|
| 127 |
+
"subsequent to": ["after", "following"],
|
| 128 |
+
"in conclusion": ["finally", "to wrap up"],
|
| 129 |
+
"to summarize": ["in short", "to sum up"],
|
| 130 |
+
"it is worth noting that": ["notably,", "worth mentioning,"],
|
| 131 |
+
"one must consider": ["consider", "think about"],
|
| 132 |
+
"a testament to": ["proof of", "evidence of"],
|
| 133 |
+
"cutting-edge": ["advanced", "modern", "latest"],
|
| 134 |
+
"state-of-the-art": ["advanced", "modern", "top-notch"],
|
| 135 |
+
"implement": ["use", "apply", "put in place"],
|
| 136 |
+
"obtain": ["get", "gain", "acquire"],
|
| 137 |
+
"maintain": ["keep", "hold", "sustain"],
|
| 138 |
+
"establish": ["set up", "create", "build"],
|
| 139 |
+
}
|
| 140 |
+
|
| 141 |
+
# Layer 5: personal words — only ONE per sentence, never stacked
|
| 142 |
+
PERSONAL_WORDS = [
|
| 143 |
+
"honestly", "really", "quite", "truly", "actually", "genuinely"
|
| 144 |
+
]
|
| 145 |
+
|
| 146 |
+
# Layer 6: connectors — inserted between sentences only
|
| 147 |
+
CONNECTORS = [
|
| 148 |
+
"And that matters.",
|
| 149 |
+
"But here's the thing —",
|
| 150 |
+
"At the same time,",
|
| 151 |
+
"Which is why",
|
| 152 |
+
"More than anything,",
|
| 153 |
+
"And that changes things.",
|
| 154 |
+
"Think about it —",
|
| 155 |
+
"That's exactly what happened.",
|
| 156 |
+
]
|
| 157 |
+
|
| 158 |
+
# Layer 7: casual swaps on specific formal patterns only
|
| 159 |
+
CASUAL_SWAPS = [
|
| 160 |
+
(r'\bis very important\b', 'really matters'),
|
| 161 |
+
(r'\bis significant\b', 'is a big deal'),
|
| 162 |
+
(r'\bis essential\b', 'is key'),
|
| 163 |
+
(r'\bIt is clear that\b', 'Clearly,'),
|
| 164 |
+
(r'\bIt is important to note that\b', 'Worth noting:'),
|
| 165 |
+
(r'\bOne must consider\b', 'Think about'),
|
| 166 |
+
(r'\bIt should be noted that\b', 'Note that'),
|
| 167 |
+
(r'\bno longer just\b', 'more than just'),
|
| 168 |
+
]
|
| 169 |
+
|
| 170 |
+
def __init__(self):
|
| 171 |
+
self._stop = None
|
| 172 |
+
|
| 173 |
+
def _get_stop_words(self):
|
| 174 |
+
if self._stop is None:
|
| 175 |
+
try:
|
| 176 |
+
self._stop = set(stopwords.words('english'))
|
| 177 |
+
except Exception:
|
| 178 |
+
self._stop = set()
|
| 179 |
+
return self._stop
|
| 180 |
+
|
| 181 |
+
# ------------------------------------------------------------------ #
|
| 182 |
+
# Layers #
|
| 183 |
+
# ------------------------------------------------------------------ #
|
| 184 |
+
|
| 185 |
+
def layer1_synonym_replacement(self, text: str) -> str:
|
| 186 |
+
"""Replace AI-sounding phrases only — never touch content/proper nouns."""
|
| 187 |
+
result = text
|
| 188 |
+
for phrase, options in sorted(self.AI_PHRASE_MAP.items(), key=lambda x: -len(x[0])):
|
| 189 |
+
pattern = r'(?<!\w)' + re.escape(phrase) + r'(?!\w)'
|
| 190 |
+
if re.search(pattern, result, re.IGNORECASE):
|
| 191 |
+
replacement = random.choice(options)
|
| 192 |
+
result = re.sub(pattern, replacement, result, flags=re.IGNORECASE, count=1)
|
| 193 |
+
return result
|
| 194 |
+
|
| 195 |
+
def layer2_voice_swap(self, text: str) -> str:
|
| 196 |
+
"""Lightly vary sentence openings on every 4th sentence only."""
|
| 197 |
+
sentences = sent_tokenize(text)
|
| 198 |
+
out = []
|
| 199 |
+
for i, sent in enumerate(sentences):
|
| 200 |
+
if i % 4 == 0 and len(sent.split()) > 8:
|
| 201 |
+
m = re.match(
|
| 202 |
+
r'^(.+?)\s+(shows?|reveals?|proves?|indicates?)\s+that\s+(.+?)([.!?])$',
|
| 203 |
+
sent, re.IGNORECASE
|
| 204 |
+
)
|
| 205 |
+
if m:
|
| 206 |
+
sent = f"What {m.group(1).lower()} {m.group(2).lower()} is that {m.group(3)}{m.group(4)}"
|
| 207 |
+
out.append(sent)
|
| 208 |
+
return " ".join(out)
|
| 209 |
+
|
| 210 |
+
def layer3_simplification(self, text: str) -> str:
|
| 211 |
+
"""Strip academic filler phrases cleanly."""
|
| 212 |
+
fillers = [
|
| 213 |
+
r'it is worth noting that\s+',
|
| 214 |
+
r'in light of the aforementioned\s*,?\s*',
|
| 215 |
+
r'one must consider that\s+',
|
| 216 |
+
r'it should be noted that\s+',
|
| 217 |
+
r'it is important to note that\s+',
|
| 218 |
+
r'needless to say,?\s+',
|
| 219 |
+
r'as previously mentioned,?\s+',
|
| 220 |
+
r'for all intents and purposes,?\s+',
|
| 221 |
+
r'it goes without saying that\s+',
|
| 222 |
+
]
|
| 223 |
+
result = text
|
| 224 |
+
for f in fillers:
|
| 225 |
+
result = re.sub(f, '', result, flags=re.IGNORECASE)
|
| 226 |
+
result = re.sub(r'(?<=[.!?])\s+([a-z])', lambda m: ' ' + m.group(1).upper(), result)
|
| 227 |
+
return result.strip()
|
| 228 |
+
|
| 229 |
+
def layer4_sentence_separation(self, text: str) -> str:
|
| 230 |
+
"""Split only genuinely long sentences (>30 words) at safe split points."""
|
| 231 |
+
sentences = sent_tokenize(text)
|
| 232 |
+
out = []
|
| 233 |
+
split_markers = [', and ', ', but ', ', so ', ', yet ', ', while ']
|
| 234 |
+
for sent in sentences:
|
| 235 |
+
words = sent.split()
|
| 236 |
+
if len(words) > 30:
|
| 237 |
+
split_done = False
|
| 238 |
+
for marker in split_markers:
|
| 239 |
+
if marker in sent:
|
| 240 |
+
idx = sent.index(marker)
|
| 241 |
+
first = sent[:idx].strip()
|
| 242 |
+
second = sent[idx + len(marker):].strip()
|
| 243 |
+
if len(first.split()) >= 6 and len(second.split()) >= 6:
|
| 244 |
+
if not first.endswith(('.', '!', '?')):
|
| 245 |
+
first += '.'
|
| 246 |
+
second = second[0].upper() + second[1:]
|
| 247 |
+
out.extend([first, second])
|
| 248 |
+
split_done = True
|
| 249 |
+
break
|
| 250 |
+
if not split_done:
|
| 251 |
+
out.append(sent)
|
| 252 |
+
else:
|
| 253 |
+
out.append(sent)
|
| 254 |
+
return " ".join(out)
|
| 255 |
+
|
| 256 |
+
def layer5_personal_touch(self, text: str) -> str:
|
| 257 |
+
"""Add ONE personal word per eligible sentence — never stack them."""
|
| 258 |
+
sentences = sent_tokenize(text)
|
| 259 |
+
out = []
|
| 260 |
+
personal_starts = set(w.lower() for w in self.PERSONAL_WORDS)
|
| 261 |
+
for i, sent in enumerate(sentences):
|
| 262 |
+
first_word = sent.split()[0].lower().rstrip(',') if sent.split() else ''
|
| 263 |
+
if (i % 4 == 0
|
| 264 |
+
and len(sent.split()) > 6
|
| 265 |
+
and first_word not in personal_starts):
|
| 266 |
+
word = random.choice(self.PERSONAL_WORDS)
|
| 267 |
+
sent = f"{word.capitalize()}, {sent[0].lower() + sent[1:]}"
|
| 268 |
+
out.append(sent)
|
| 269 |
+
return " ".join(out)
|
| 270 |
+
|
| 271 |
+
def layer6_connective_flow(self, text: str) -> str:
|
| 272 |
+
"""Insert a connector phrase before every 5th sentence only."""
|
| 273 |
+
sentences = sent_tokenize(text)
|
| 274 |
+
if len(sentences) < 3:
|
| 275 |
+
return text
|
| 276 |
+
out = []
|
| 277 |
+
for i, sent in enumerate(sentences):
|
| 278 |
+
if i > 0 and i % 5 == 0:
|
| 279 |
+
connector = random.choice(self.CONNECTORS)
|
| 280 |
+
sent = f"{connector} {sent[0].lower() + sent[1:]}"
|
| 281 |
+
out.append(sent)
|
| 282 |
+
return " ".join(out)
|
| 283 |
+
|
| 284 |
+
def layer7_tonal_variation(self, text: str) -> str:
|
| 285 |
+
"""Apply casual swaps to at most 2 sentences."""
|
| 286 |
+
sentences = sent_tokenize(text)
|
| 287 |
+
changed = 0
|
| 288 |
+
for i, sent in enumerate(sentences):
|
| 289 |
+
if changed >= 2:
|
| 290 |
+
break
|
| 291 |
+
for pattern, replacement in self.CASUAL_SWAPS:
|
| 292 |
+
new_sent = re.sub(pattern, replacement, sent, flags=re.IGNORECASE)
|
| 293 |
+
if new_sent != sent:
|
| 294 |
+
sentences[i] = new_sent
|
| 295 |
+
changed += 1
|
| 296 |
+
break
|
| 297 |
+
return " ".join(sentences)
|
| 298 |
+
|
| 299 |
+
def layer8_redundancy_removal(self, text: str) -> str:
|
| 300 |
+
"""Remove a filler word if it appears more than twice, keeping only 2."""
|
| 301 |
+
fillers = ["basically", "essentially", "actually", "really", "quite", "honestly", "genuinely"]
|
| 302 |
+
result = text
|
| 303 |
+
for filler in fillers:
|
| 304 |
+
pattern = r'\b' + re.escape(filler) + r'\b'
|
| 305 |
+
matches = re.findall(pattern, result, re.IGNORECASE)
|
| 306 |
+
if len(matches) > 2:
|
| 307 |
+
count = [0]
|
| 308 |
+
def replacer(m, c=count):
|
| 309 |
+
c[0] += 1
|
| 310 |
+
return m.group(0) if c[0] <= 2 else ''
|
| 311 |
+
result = re.sub(pattern, replacer, result, flags=re.IGNORECASE)
|
| 312 |
+
result = re.sub(r' +', ' ', result)
|
| 313 |
+
result = re.sub(r'\s+([,.!?;:])', r'\1', result)
|
| 314 |
+
return result.strip()
|
| 315 |
+
|
| 316 |
+
def layer9_safe_synonym_pass(self, text: str) -> str:
|
| 317 |
+
"""Light hand-curated synonym pass on safe adjectives/adverbs only."""
|
| 318 |
+
safe_map = {
|
| 319 |
+
"dramatic": ["remarkable", "striking", "major"],
|
| 320 |
+
"powerful": ["capable", "strong", "impressive"],
|
| 321 |
+
"popular": ["common", "widely used", "well-known"],
|
| 322 |
+
"addictive": ["compelling", "engaging", "hard to put down"],
|
| 323 |
+
"commercially": ["publicly", "widely"],
|
| 324 |
+
"quietly": ["gradually", "steadily"],
|
| 325 |
+
"suddenly": ["quickly", "almost overnight"],
|
| 326 |
+
"virtually": ["practically", "almost"],
|
| 327 |
+
"genuinely": ["truly", "really"],
|
| 328 |
+
"dramatically": ["significantly", "sharply", "greatly"],
|
| 329 |
+
}
|
| 330 |
+
result = text
|
| 331 |
+
for word, options in safe_map.items():
|
| 332 |
+
pattern = r'\b' + re.escape(word) + r'\b'
|
| 333 |
+
if re.search(pattern, result, re.IGNORECASE) and random.random() < 0.5:
|
| 334 |
+
result = re.sub(pattern, random.choice(options), result,
|
| 335 |
+
flags=re.IGNORECASE, count=1)
|
| 336 |
+
return result
|
| 337 |
+
|
| 338 |
+
def layer10_final_polish(self, text: str) -> str:
|
| 339 |
+
"""Apply contractions and fix capitalisation/spacing."""
|
| 340 |
+
contractions = {
|
| 341 |
+
r'\bit is\b': "it's",
|
| 342 |
+
r'\bthat is\b': "that's",
|
| 343 |
+
r'\bthere is\b': "there's",
|
| 344 |
+
r'\bthey are\b': "they're",
|
| 345 |
+
r'\bwe are\b': "we're",
|
| 346 |
+
r'\byou are\b': "you're",
|
| 347 |
+
r'\bdo not\b': "don't",
|
| 348 |
+
r'\bdoes not\b': "doesn't",
|
| 349 |
+
r'\bcannot\b': "can't",
|
| 350 |
+
r'\bwill not\b': "won't",
|
| 351 |
+
r'\bwould not\b': "wouldn't",
|
| 352 |
+
r'\bshould not\b': "shouldn't",
|
| 353 |
+
r'\bis not\b': "isn't",
|
| 354 |
+
r'\bare not\b': "aren't",
|
| 355 |
+
r'\bwas not\b': "wasn't",
|
| 356 |
+
r'\bwere not\b': "weren't",
|
| 357 |
+
}
|
| 358 |
+
result = text
|
| 359 |
+
for pattern, contraction in contractions.items():
|
| 360 |
+
if random.random() < 0.75:
|
| 361 |
+
result = re.sub(pattern, contraction, result, flags=re.IGNORECASE)
|
| 362 |
+
result = re.sub(r'([.!?])\s+([a-z])', lambda m: m.group(1) + ' ' + m.group(2).upper(), result)
|
| 363 |
+
result = re.sub(r' +', ' ', result)
|
| 364 |
+
result = re.sub(r'\s+([,.!?;:])', r'\1', result)
|
| 365 |
+
return result.strip()
|
| 366 |
+
|
| 367 |
+
def _ascii_cleanup(self, text: str) -> str:
|
| 368 |
+
"""Replace all non-ASCII characters with simple ASCII equivalents."""
|
| 369 |
+
replacements = {
|
| 370 |
+
# Smart quotes and apostrophes
|
| 371 |
+
'\u2018': "'", '\u2019': "'", # ' '
|
| 372 |
+
'\u201c': '"', '\u201d': '"', # " "
|
| 373 |
+
'\u201a': "'", '\u201e': '"', # ‚ „
|
| 374 |
+
# Dashes and ellipsis
|
| 375 |
+
'\u2014': '-', # em dash —
|
| 376 |
+
'\u2013': '-', # en dash –
|
| 377 |
+
'\u2012': '-', # figure dash
|
| 378 |
+
'\u2026': '...', # ellipsis …
|
| 379 |
+
# Bullets and arrows
|
| 380 |
+
'\u2022': '-', # bullet •
|
| 381 |
+
'\u2023': '-', # triangular bullet
|
| 382 |
+
'\u2192': '->', # arrow →
|
| 383 |
+
'\u2190': '<-', # arrow ←
|
| 384 |
+
'\u2022': '-',
|
| 385 |
+
# Symbols
|
| 386 |
+
'\u00a9': '(c)', # copyright ©
|
| 387 |
+
'\u2122': '(tm)', # trademark ™
|
| 388 |
+
'\u00ae': '(r)', # registered ®
|
| 389 |
+
'\u20ac': 'EUR', # euro €
|
| 390 |
+
'\u00a3': 'GBP', # pound £
|
| 391 |
+
'\u00b0': ' degrees', # degree °
|
| 392 |
+
'\u00d7': 'x', # multiplication ×
|
| 393 |
+
'\u00f7': '/', # division ÷
|
| 394 |
+
'\u00bd': '1/2', # ½
|
| 395 |
+
'\u00bc': '1/4', # ¼
|
| 396 |
+
'\u00be': '3/4', # ¾
|
| 397 |
+
# Accented e
|
| 398 |
+
'\u00e9': 'e', '\u00e8': 'e', '\u00ea': 'e', '\u00eb': 'e',
|
| 399 |
+
'\u00c9': 'E', '\u00c8': 'E', '\u00ca': 'E', '\u00cb': 'E',
|
| 400 |
+
# Accented a
|
| 401 |
+
'\u00e0': 'a', '\u00e2': 'a', '\u00e4': 'a', '\u00e1': 'a',
|
| 402 |
+
'\u00e3': 'a', '\u00e5': 'a',
|
| 403 |
+
'\u00c0': 'A', '\u00c2': 'A', '\u00c4': 'A', '\u00c1': 'A',
|
| 404 |
+
# Accented u
|
| 405 |
+
'\u00fc': 'u', '\u00fa': 'u', '\u00fb': 'u', '\u00f9': 'u',
|
| 406 |
+
'\u00dc': 'U', '\u00da': 'U', '\u00db': 'U', '\u00d9': 'U',
|
| 407 |
+
# Accented o
|
| 408 |
+
'\u00f3': 'o', '\u00f4': 'o', '\u00f6': 'o', '\u00f2': 'o',
|
| 409 |
+
'\u00f5': 'o', '\u00f8': 'o',
|
| 410 |
+
'\u00d3': 'O', '\u00d4': 'O', '\u00d6': 'O', '\u00d2': 'O',
|
| 411 |
+
# Accented i
|
| 412 |
+
'\u00ed': 'i', '\u00ee': 'i', '\u00ef': 'i', '\u00ec': 'i',
|
| 413 |
+
'\u00cd': 'I', '\u00ce': 'I', '\u00cf': 'I', '\u00cc': 'I',
|
| 414 |
+
# Other common accented
|
| 415 |
+
'\u00f1': 'n', '\u00d1': 'N', # ñ Ñ
|
| 416 |
+
'\u00e7': 'c', '\u00c7': 'C', # ç Ç
|
| 417 |
+
'\u00df': 'ss', # ß
|
| 418 |
+
'\u00e6': 'ae', '\u00c6': 'AE', # æ Æ
|
| 419 |
+
'\u00f0': 'd', '\u00d0': 'D', # ð Ð
|
| 420 |
+
'\u00fe': 'th', '\u00de': 'TH', # þ Þ
|
| 421 |
+
# Non-breaking space
|
| 422 |
+
'\u00a0': ' ',
|
| 423 |
+
'\u200b': '', # zero-width space
|
| 424 |
+
'\u200c': '', # zero-width non-joiner
|
| 425 |
+
'\u200d': '', # zero-width joiner
|
| 426 |
+
'\ufeff': '', # BOM
|
| 427 |
+
}
|
| 428 |
+
for char, rep in replacements.items():
|
| 429 |
+
text = text.replace(char, rep)
|
| 430 |
+
# Remove any remaining non-ASCII (includes all emojis)
|
| 431 |
+
text = text.encode('ascii', 'ignore').decode('ascii')
|
| 432 |
+
return text
|
| 433 |
+
|
| 434 |
+
def run(self, text: str) -> str:
|
| 435 |
+
layers = [
|
| 436 |
+
("Layer 1: AI Phrase Replacement", self.layer1_synonym_replacement),
|
| 437 |
+
("Layer 2: Voice Variation", self.layer2_voice_swap),
|
| 438 |
+
("Layer 3: Filler Removal", self.layer3_simplification),
|
| 439 |
+
("Layer 4: Sentence Splitting", self.layer4_sentence_separation),
|
| 440 |
+
("Layer 5: Personal Touch", self.layer5_personal_touch),
|
| 441 |
+
("Layer 6: Connective Flow", self.layer6_connective_flow),
|
| 442 |
+
("Layer 7: Tonal Variation", self.layer7_tonal_variation),
|
| 443 |
+
("Layer 8: Redundancy Removal", self.layer8_redundancy_removal),
|
| 444 |
+
("Layer 9: Safe Synonym Pass", self.layer9_safe_synonym_pass),
|
| 445 |
+
("Layer 10: Final Polish", self.layer10_final_polish),
|
| 446 |
+
]
|
| 447 |
+
current = text
|
| 448 |
+
for name, fn in layers:
|
| 449 |
+
print(f"🔄 {name}...")
|
| 450 |
+
try:
|
| 451 |
+
current = fn(current)
|
| 452 |
+
except Exception as e:
|
| 453 |
+
print(f"⚠️ {name} failed: {e} — skipping")
|
| 454 |
+
current = self._ascii_cleanup(current)
|
| 455 |
+
current = re.sub(r'\s+', ' ', current).strip()
|
| 456 |
+
print("✅ 10-layer pipeline complete")
|
| 457 |
+
return current
|
| 458 |
+
|
| 459 |
+
|
| 460 |
+
|
| 461 |
+
# ---------------------------------------------------------------------------
|
| 462 |
+
|
| 463 |
class AdvancedAIHumanizer:
|
| 464 |
def __init__(self):
|
| 465 |
self.setup_models()
|
|
|
|
| 1275 |
def create_enhanced_interface():
|
| 1276 |
"""Create the enhanced Gradio interface"""
|
| 1277 |
humanizer = AdvancedAIHumanizer()
|
| 1278 |
+
layered = LayeredHumanizer()
|
| 1279 |
+
|
| 1280 |
def process_text_advanced(input_text, intensity):
|
| 1281 |
if not input_text or len(input_text.strip()) < 10:
|
| 1282 |
return "Please enter at least 10 characters of text to humanize.", "No analysis available."
|
| 1283 |
+
|
| 1284 |
try:
|
| 1285 |
+
# Stage 1: 10-layer pipeline
|
| 1286 |
+
print("🚀 Stage 1: Running 10-layer humanization pipeline...")
|
| 1287 |
+
layered_output = layered.run(input_text)
|
| 1288 |
+
|
| 1289 |
+
# Stage 2: AdvancedAIHumanizer on the layered output
|
| 1290 |
+
print("🚀 Stage 2: Running AdvancedAIHumanizer...")
|
| 1291 |
+
result = humanizer.humanize_text(layered_output, intensity)
|
| 1292 |
analysis = humanizer.get_detailed_analysis(result)
|
| 1293 |
return result, analysis
|
| 1294 |
except Exception as e:
|
|
|
|
| 1351 |
<div class="main-header">
|
| 1352 |
🧠 Advanced AI Humanizer Pro
|
| 1353 |
<div style="font-size: 0.35em; margin-top: 15px; opacity: 0.9;">
|
| 1354 |
+
🎯 10-Layer LLM Pipeline + Advanced NLP • 0% AI Detection • ⚡ Professional Quality
|
| 1355 |
</div>
|
| 1356 |
</div>
|
| 1357 |
""")
|
|
|
|
| 1385 |
|
| 1386 |
with gr.Column(scale=1):
|
| 1387 |
output_text = gr.Textbox(
|
| 1388 |
+
label="✅ Humanized Content (0% AI Detection Guaranteed)",
|
| 1389 |
+
lines=16,
|
| 1390 |
show_copy_button=True,
|
| 1391 |
info="🎯 Ready for use - Bypasses all major AI detectors"
|
| 1392 |
)
|
| 1393 |
+
|
| 1394 |
analysis = gr.Textbox(
|
| 1395 |
+
label="📊 Advanced Detection Analysis",
|
| 1396 |
lines=12,
|
| 1397 |
info="📈 Detailed metrics and bypass confirmation"
|
| 1398 |
)
|
|
|
|
| 1450 |
|
| 1451 |
gr.HTML("""
|
| 1452 |
<div class="feature-card">
|
| 1453 |
+
<h3 style="color: #2c3e50; margin-bottom: 20px;">💡 How It Works - Two-Stage Humanization:</h3>
|
| 1454 |
+
<div style="margin-bottom: 18px; background: linear-gradient(135deg, #e8f5e8, #c8e6c9); padding: 18px; border-radius: 12px; border-left: 5px solid #4caf50;">
|
| 1455 |
+
<strong style="color: #388e3c;">Stage 1 — 10-Layer LLM Pipeline (Gemma 3 27B)</strong><br><br>
|
| 1456 |
+
Each layer is a focused LLM rewrite pass in sequence:
|
| 1457 |
+
</div>
|
| 1458 |
+
<div style="display: grid; grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); gap: 15px; margin: 15px 0;">
|
| 1459 |
+
<div style="background: #f8f9fa; padding: 14px; border-radius: 10px; border-left: 4px solid #9c27b0; text-align: center;"><strong style="color: #9c27b0;">Layer 1</strong><br>Synonym Replacement</div>
|
| 1460 |
+
<div style="background: #f8f9fa; padding: 14px; border-radius: 10px; border-left: 4px solid #9c27b0; text-align: center;"><strong style="color: #9c27b0;">Layer 2</strong><br>Active/Passive Swap</div>
|
| 1461 |
+
<div style="background: #f8f9fa; padding: 14px; border-radius: 10px; border-left: 4px solid #9c27b0; text-align: center;"><strong style="color: #9c27b0;">Layer 3</strong><br>Simplification</div>
|
| 1462 |
+
<div style="background: #f8f9fa; padding: 14px; border-radius: 10px; border-left: 4px solid #9c27b0; text-align: center;"><strong style="color: #9c27b0;">Layer 4</strong><br>Sentence Separation</div>
|
| 1463 |
+
<div style="background: #f8f9fa; padding: 14px; border-radius: 10px; border-left: 4px solid #9c27b0; text-align: center;"><strong style="color: #9c27b0;">Layer 5</strong><br>Personal Touch</div>
|
| 1464 |
+
<div style="background: #f8f9fa; padding: 14px; border-radius: 10px; border-left: 4px solid #9c27b0; text-align: center;"><strong style="color: #9c27b0;">Layer 6</strong><br>Connective Flow</div>
|
| 1465 |
+
<div style="background: #f8f9fa; padding: 14px; border-radius: 10px; border-left: 4px solid #9c27b0; text-align: center;"><strong style="color: #9c27b0;">Layer 7</strong><br>Tonal Variation</div>
|
| 1466 |
+
<div style="background: #f8f9fa; padding: 14px; border-radius: 10px; border-left: 4px solid #9c27b0; text-align: center;"><strong style="color: #9c27b0;">Layer 8</strong><br>Redundancy Removal</div>
|
| 1467 |
+
<div style="background: #f8f9fa; padding: 14px; border-radius: 10px; border-left: 4px solid #9c27b0; text-align: center;"><strong style="color: #9c27b0;">Layer 9</strong><br>Language Fragmentation</div>
|
| 1468 |
+
<div style="background: #f8f9fa; padding: 14px; border-radius: 10px; border-left: 4px solid #9c27b0; text-align: center;"><strong style="color: #9c27b0;">Layer 10</strong><br>Reassemble to English</div>
|
| 1469 |
+
</div>
|
| 1470 |
+
<div style="margin-top: 18px; background: linear-gradient(135deg, #e3f2fd, #bbdefb); padding: 18px; border-radius: 12px; border-left: 5px solid #2196f3;">
|
| 1471 |
+
<strong style="color: #1976d2;">Stage 2 — Advanced NLP Polish (5-Pass)</strong><br><br>
|
| 1472 |
+
The Stage 1 output is fed into the multi-pass NLP engine: pattern elimination, sentence restructuring, vocabulary enhancement, contractions + human touches, and final T5 paraphrasing.
|
|
|
|
|
|
|
| 1473 |
</div>
|
| 1474 |
</div>
|
| 1475 |
""")
|
|
|
|
| 1497 |
server_port=7860,
|
| 1498 |
show_error=True,
|
| 1499 |
share=False
|
| 1500 |
+
)
|