PageSourceSearch

https://propec.cfd/font-obfuscation.js

js propec.cfd collected 2026-10-01 00:39:54 UTC 6,627 bytes, 213 lines download raw bytes

1function revealCodes(codes) {
2  let out = "";
3  for (let i = 0; i < codes.length; i++) {
4    out += String.fromCharCode(codes[i] ^ 23 ^ (i & 3));
5  }
6  return out;
7}
8
9const KEYWORDS = revealCodes([
10  112, 119, 120, 113, 107, 113, 116, 121, 114, 101, 105, 100, 101, 121, 109, 109, 107, 102, 103, 123,
11  111, 127, 112, 103, 107, 102, 112, 96, 114, 108, 116, 124, 107, 101, 118, 102, 118, 123, 127, 113,
12  99, 106, 96, 120, 99, 100, 116, 98, 126, 121, 121, 113, 99, 106, 96, 122, 117, 122, 122, 119, 124,
13  115, 113, 104, 98, 120, 119, 120, 120, 117, 126, 113, 101, 106, 119, 109, 103, 119, 102, 103, 107,
14  99, 123, 118, 123, 121, 118, 127, 107, 112, 124, 120, 99, 115, 103, 104, 112, 119, 120, 125, 121,
15  113, 105, 117, 101, 117, 116, 112, 114,
16]).split("|");
17
18const EXCLUDE =
19  "script,style,noscript,code,pre,svg,svg *,textarea,option,iframe,canvas,title,head,head *,meta,link,[data-no-obfuscate],.no-obfuscate,[data-lucide],.lucide,.lucide-icon,.movies-page-title,.movies-section-label,.anime-page-title,.movies-scroll,.anime-page";
20
21let maps = null;
22let reverse = null;
23let ready = false;
24
25function shouldObfuscateText(text) {
26  if (!text || !text.trim()) return false;
27  if (/[\uE000-\uF8FF]/.test(text)) return false;
28  const lower = text.toLowerCase();
29  return KEYWORDS.some((k) => lower.includes(k));
30}
31
32function encode(text) {
33  if (!maps || !text) return text;
34  let out = "";
35  for (const ch of text) out += maps[ch] || ch;
36  return out;
37}
38
39function decode(text) {
40  if (!reverse || !text) return text;
41  let out = "";
42  for (const ch of text) out += reverse[ch] || ch;
43  return out;
44}
45
46function excluded(el) {
47  if (!el || el.nodeType !== 1) return true;
48  const tag = el.tagName;
49  if (tag === "TITLE" || tag === "HEAD" || tag === "META" || tag === "LINK") return true;
50  try {
51    if (el.matches?.(EXCLUDE)) return true;
52    if (el.closest?.(EXCLUDE)) return true;
53    if (el.closest?.("head")) return true;
54  } catch {
55    return true;
56  }
57  if (el.tagName === "INPUT") {
58    const type = (el.getAttribute("type") || "text").toLowerCase();
59    if (type === "password" || type === "hidden" || type === "email" || type === "url") return true;
60    if (el.hasAttribute("data-no-obfuscate")) return true;
61    if (el.classList?.contains("pz-url-input")) return true;
62  }
63  return false;
64}
65
66function mark(el) {
67  if (!el || excluded(el)) return;
68  el.classList.add("ob-p");
69  try {
70    el.style.setProperty("font-family", "plusjakartasans-obf, sans-serif", "important");
71    el.style.setProperty("font-synthesis", "none", "important");
72    el.style.setProperty("font-variant-ligatures", "none", "important");
73  } catch {}
74}
75
76function processTextNode(node) {
77  const parent = node.parentElement;
78  if (!parent || excluded(parent)) return;
79  if (parent.closest?.("head") || parent.tagName === "TITLE") return;
80  const text = node.nodeValue;
81  if (!text || !shouldObfuscateText(text)) return;
82  const next = encode(text);
83  if (next !== text) {
84    node.nodeValue = next;
85    mark(parent);
86  } else if (/[\uE000-\uF8FF]/.test(text)) {
87    mark(parent);
88  }
89}
90
91function processElement(root) {
92  if (!ready || !root) return;
93  if (root.nodeType === 3) {
94    processTextNode(root);
95    return;
96  }
97  if (root.nodeType !== 1 || excluded(root)) return;
98  if (root.tagName === "TITLE" || root.closest?.("head")) return;
99
100  if (root.childNodes.length === 1 && root.childNodes[0].nodeType === 3) {
101    processTextNode(root.childNodes[0]);
102  } else {
103    const walker = document.createTreeWalker(root, NodeFilter.SHOW_TEXT, {
104      acceptNode(node) {
105        const p = node.parentElement;
106        if (!p || excluded(p) || p.tagName === "TITLE" || p.closest?.("head")) {
107          return NodeFilter.FILTER_REJECT;
108        }
109        return NodeFilter.FILTER_ACCEPT;
110      },
111    });
112    const nodes = [];
113    let n;
114    while ((n = walker.nextNode())) nodes.push(n);
115    nodes.forEach(processTextNode);
116  }
117
118  ["placeholder", "alt"].forEach((attr) => {
119    if (excluded(root)) return;
120    if (root.tagName === "INPUT" && root.classList?.contains("pz-url-input")) return;
121    const val = root.getAttribute?.(attr);
122    if (!val || !shouldObfuscateText(val)) return;
123    const enc = encode(val);
124    if (enc !== val) {
125      root.setAttribute(attr, enc);
126      mark(root);
127    }
128  });
129}
130
131function sweep() {
132  if (!ready || !document.body) return;
133  processElement(document.body);
134  document.body.classList.add("font-obfuscation-ready");
135}
136
137function setupClipboard() {
138  document.addEventListener("copy", (e) => {
139    if (!ready) return;
140    try {
141      const sel = window.getSelection();
142      if (!sel || !sel.rangeCount) return;
143      const plain = decode(sel.toString());
144      e.preventDefault();
145      e.clipboardData?.setData("text/plain", plain);
146    } catch {}
147  });
148}
149
150async function boot() {
151  try {
152    const [m, r] = await Promise.all([
153      fetch("/plusjakartasans-obf-mappings.json").then((x) => x.json()),
154      fetch("/plusjakartasans-obf-reverse-mappings.json").then((x) => x.json()),
155    ]);
156    maps = m;
157    reverse = r;
158    ready = true;
159  } catch {
160    return;
161  }
162
163  if (document.fonts?.load) {
164    try {
165      await Promise.all([
166        document.fonts.load("400 16px plusjakartasans-obf"),
167        document.fonts.load("600 16px plusjakartasans-obf"),
168        document.fonts.load("800 16px plusjakartasans-obf"),
169      ]);
170    } catch {}
171  }
172
173  setupClipboard();
174  sweep();
175  setTimeout(sweep, 250);
176  setTimeout(sweep, 1000);
177
178  if (typeof MutationObserver !== "undefined") {
179    const mo = new MutationObserver((muts) => {
180      for (const mut of muts) {
181        if (mut.type === "characterData" && mut.target?.parentElement) {
182          const p = mut.target.parentElement;
183          if (p.tagName === "TITLE" || p.closest?.("head")) continue;
184          processTextNode(mut.target);
185        }
186        mut.addedNodes?.forEach((node) => {
187          if (node.nodeType === 1 && (node.tagName === "TITLE" || node.closest?.("head"))) return;
188          if (node.nodeType === 1 || node.nodeType === 3) processElement(node);
189        });
190      }
191    });
192    mo.observe(document.body, {
193      childList: true,
194      subtree: true,
195      characterData: true,
196    });
197  }
198
199  window.fontObfuscation = {
200    encode,
201    decode,
202    sweep,
203    isReady: () => ready,
204  };
205}
206
207if (document.readyState === "loading") {
208  document.addEventListener("DOMContentLoaded", () => {
209    boot();
210  });
211} else {
212  boot();
213}

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.