René's URL Explorer Experiment


Title: Non-deterministic `?.()` miscompile drops short-circuit on captured variable in nested closure · Issue #1408 · javascript-obfuscator/javascript-obfuscator · GitHub

Open Graph Title: Non-deterministic `?.()` miscompile drops short-circuit on captured variable in nested closure · Issue #1408 · javascript-obfuscator/javascript-obfuscator

X Title: Non-deterministic `?.()` miscompile drops short-circuit on captured variable in nested closure · Issue #1408 · javascript-obfuscator/javascript-obfuscator

Description: With controlFlowFlattening: true, the obfuscator non-deterministically miscompiles optional-call expressions of the shape captured?.(arg) — where captured is an outer-scope variable referenced inside a nested closure. On some random seed...

Open Graph Description: With controlFlowFlattening: true, the obfuscator non-deterministically miscompiles optional-call expressions of the shape captured?.(arg) — where captured is an outer-scope variable referenced insi...

X Description: With controlFlowFlattening: true, the obfuscator non-deterministically miscompiles optional-call expressions of the shape captured?.(arg) — where captured is an outer-scope variable referenced insi...

Opengraph URL: https://github.com/javascript-obfuscator/javascript-obfuscator/issues/1408

X: @github

direct link

Domain: github.com


Hey, it has json ld scripts:
{"@context":"https://schema.org","@type":"DiscussionForumPosting","headline":"Non-deterministic `?.()` miscompile drops short-circuit on captured variable in nested closure","articleBody":"With `controlFlowFlattening: true`, the obfuscator non-deterministically miscompiles optional-call expressions of the shape `captured?.(arg)` — where `captured` is an outer-scope variable referenced inside a nested closure. On some random seeds the `?.` short-circuit is dropped, and the obfuscated code calls `undefined` as a function, throwing `TypeError: \u003cX\u003e is not a function`. The bug reproduces on roughly 5% of obfuscation runs with identical input and identical options, on both `5.4.1` and `5.4.2`. Four other shapes of optional call exercised in the attached reproducer (object property, awaited, `this.member`, chained `?.`) never reproduce — only the captured-variable-in-nested-closure shape is affected.\n\n## Expected Behavior\nThe obfuscated output should preserve the runtime semantics of the input. For `fn?.(arg)`, that means evaluating to `undefined` when `fn` is `undefined` (the `?.` short-circuit), with no call performed.\n\n## Current Behavior\nOn some random seeds, the obfuscator rewrites `captured?.(arg)` — where `captured` is an outer-scope variable referenced inside a nested closure — in a way that drops the `?.` short-circuit and invokes the undefined value as a function. The obfuscated code throws `TypeError: \u003cobfuscated-name\u003e is not a function` at runtime instead of short-circuiting to `undefined`.\n\nThe miscompile is non-deterministic across runs with identical input and identical options because the obfuscator picks a fresh random seed per invocation. Only some seeds trigger it. Across 200 iterations on the attached reproducer, the failure rate is **10/200 (5.0%)** on both `5.4.1` and `5.4.2`.\n\nThe bug is narrowly shape-specific: across the same 200 iterations, four other optional-call shapes (`obj.handler?.()`, `await cb?.()`, `this.cb?.()`, chained `obj.inner?.handler?.()`) **never** reproduce. Only the captured-variable-in-nested-closure shape is affected.\n\n\n## Steps to Reproduce\n1. Save the file in [Minimal working example](#minimal-working-example-that-will-help-to-reproduce-issue) below as `standalone.mjs`.\n2. `npm install javascript-obfuscator`\n3. `node standalone.mjs 200`\n\nExpected output: all 200 iterations pass.\nActual output:\n\n```\n=== Summary over 200 iterations ===\nruns with any failure: 10/200 (5.0%)\n  shape1: 10/200 fail (5.0%) — example: THROW: _0x40002d is not a function\n  shape2: 0/200 fail (0.0%)\n  shape3: 0/200 fail (0.0%)\n  shape4: 0/200 fail (0.0%)\n  shape5: 0/200 fail (0.0%)\n```\n\nThe script prints the path to a tmp directory at the end; failing iterations' obfuscated bytes are kept there for inspection.\n\n## JavaScript Obfuscator Edition\n- [x] JavaScript Obfuscator Open Source\n- [ ] JavaScript Obfuscator Pro via API or [http://obfuscator.io](http://obfuscator.io)\n\n## Your Environment\n* Obfuscator version used: **5.4.2** (also reproduces identically on `5.4.1`)\n* Node version used: **23.x**\n* OS: macOS (darwin ARM64), but the bug is not platform-specific — the obfuscator is fed deterministic input bytes and produces non-deterministic output regardless of host.\n\n# Stack trace\nThe throw site as it appears in the obfuscated output of a failing iteration (function names are seed-dependent, but the shape is consistent):\n```\nTypeError: _0x40002d is not a function\n    at \u003canonymous\u003e (source.17.mjs:1:NNNN)    // inner closure body, where `captured?.(msg)` should have short-circuited\n    at main (harness.17.mjs:1:NNN)\n```\nNote: with `controlFlowFlattening: true` the surrounding call stack is flattened through dispatch-table dispatchers, so additional frames may appear depending on the seed. The throw itself is always at the optional-call site.\n\n## Minimal working example that will help to reproduce issue\nAlso available as a gist: \u003chttps://gist.github.com/Thorsten-Kd/5b2a0b33932dc7534f827bd6dd5b41c5\u003e\n`standalone.mjs` — self-contained, only depends on `javascript-obfuscator`:\n\n```js\nimport { spawnSync } from 'node:child_process';\nimport * as fs from 'node:fs';\nimport * as os from 'node:os';\nimport * as path from 'node:path';\n\nimport JavaScriptObfuscator from 'javascript-obfuscator';\n\nconst ITERATIONS = parseInt(process.argv[2] ?? '200', 10);\n\nconst OBFUSCATION_OPTIONS = {\n  compact: true,\n  controlFlowFlattening: true,\n  controlFlowFlatteningThreshold: 1.0,\n  deadCodeInjection: true,\n  deadCodeInjectionThreshold: 1.0,\n  identifierNamesGenerator: 'hexadecimal',\n  log: false,\n  numbersToExpressions: true,\n  selfDefending: false,\n  simplify: false,\n  splitStrings: true,\n  splitStringsChunkLength: 5,\n  stringArray: true,\n  stringArrayCallsTransformThreshold: 1.0,\n  stringArrayEncoding: ['base64'],\n  stringArrayIndexShift: true,\n  stringArrayRotate: true,\n  stringArrayShuffle: true,\n  stringArrayThreshold: 1,\n  stringArrayWrappersChainedCalls: true,\n  stringArrayWrappersCount: 5,\n  target: 'node',\n  unicodeEscapeSequence: true,\n};\n\nconst SOURCE = `\n// Shape 1: captured outer-scope variable called via \\`?.()\\` inside a\n// nested closure. This is the shape that reliably reproduces the bug.\nexport function shape1() {\n  const captured = undefined;\n  const wrap = (msg) =\u003e {\n    captured?.(msg);\n    return 'ok';\n  };\n  return wrap('payload');\n}\n\nexport function shape2() {\n  const obj = {};\n  obj.handler?.('arg');\n  return 'ok';\n}\n\nexport async function shape3() {\n  const cb = undefined;\n  await cb?.();\n  return 'ok';\n}\n\nexport class Foo { run() { this.cb?.('arg'); return 'ok'; } }\nexport function shape4Run() { return new Foo().run(); }\n\nexport function shape5() {\n  const obj = { inner: undefined };\n  obj.inner?.handler?.();\n  return 'ok';\n}\n\n// Padding so controlFlowFlattening has enough basic blocks to do\n// non-trivial rewiring. Tiny inputs sometimes don't trigger the\n// miscompile because the dispatch table CFF builds is too small.\nfunction noise(n) {\n  let acc = 0;\n  for (let i = 0; i \u003c n; i++) {\n    if (i % 2 === 0) acc += i;\n    else if (i % 3 === 0) acc -= i;\n    else acc ^= i;\n    if (acc \u003e 1000000) acc = 0;\n  }\n  return acc;\n}\nfunction processItems(items) {\n  const out = [];\n  for (const item of items) {\n    const tag = item.tag ?? 'untagged';\n    const value = item.value ?? 0;\n    if (tag === 'a') out.push(value * 2);\n    else if (tag === 'b') out.push(value + 10);\n    else out.push(value);\n  }\n  return out;\n}\nclass Store {\n  constructor() { this.data = new Map(); }\n  set(k, v) { this.data.set(k, v); }\n  get(k) { return this.data.get(k); }\n  has(k) { return this.data.has(k); }\n  *values() { for (const v of this.data.values()) yield v; }\n}\nexport function exercisePadding() {\n  noise(100);\n  processItems([{ tag: 'a', value: 1 }, { tag: 'b', value: 2 }, { value: 3 }]);\n  const s = new Store();\n  s.set('x', 1);\n  return s.has('x');\n}\n`;\n\nconst HARNESS_TEMPLATE = `\nimport { shape1, shape2, shape3, shape4Run, shape5, exercisePadding } from './SOURCE_PLACEHOLDER';\nasync function main() {\n  exercisePadding();\n  const results = { shape1: 'unset', shape2: 'unset', shape3: 'unset', shape4: 'unset', shape5: 'unset' };\n  try { results.shape1 = shape1(); } catch (e) { results.shape1 = 'THROW: ' + e.message; }\n  try { results.shape2 = shape2(); } catch (e) { results.shape2 = 'THROW: ' + e.message; }\n  try { results.shape3 = await shape3(); } catch (e) { results.shape3 = 'THROW: ' + e.message; }\n  try { results.shape4 = shape4Run(); } catch (e) { results.shape4 = 'THROW: ' + e.message; }\n  try { results.shape5 = shape5(); } catch (e) { results.shape5 = 'THROW: ' + e.message; }\n  console.log(JSON.stringify(results));\n}\nmain();\n`;\n\nconst tmpDir = await fs.promises.mkdtemp(path.join(os.tmpdir(), 'obf-repro-'));\nconsole.log(`workdir: ${tmpDir}`);\nconsole.log(`node: ${process.version}`);\n\nconst SHAPES = ['shape1', 'shape2', 'shape3', 'shape4', 'shape5'];\nconst failsByShape = Object.fromEntries(SHAPES.map((s) =\u003e [s, 0]));\nlet runsWithAnyFail = 0;\nconst examples = {};\n\nfor (let i = 1; i \u003c= ITERATIONS; i++) {\n  const obfPath = path.join(tmpDir, `source.${i}.mjs`);\n  const harnessPath = path.join(tmpDir, `harness.${i}.mjs`);\n  const obfuscated = JavaScriptObfuscator.obfuscate(SOURCE, OBFUSCATION_OPTIONS).getObfuscatedCode();\n  await fs.promises.writeFile(obfPath, obfuscated);\n  const harness = HARNESS_TEMPLATE.replace('SOURCE_PLACEHOLDER', `./source.${i}.mjs`);\n  await fs.promises.writeFile(harnessPath, harness);\n\n  const proc = spawnSync(process.execPath, [harnessPath], { encoding: 'utf-8', timeout: 10_000 });\n  let results;\n  try { results = JSON.parse(proc.stdout?.trim() ?? ''); }\n  catch {\n    runsWithAnyFail++;\n    console.log(`[${i}/${ITERATIONS}] FAIL (no JSON) stderr=${(proc.stderr ?? '').slice(0, 200)}`);\n    continue;\n  }\n  const failed = SHAPES.filter((s) =\u003e results[s] !== 'ok');\n  if (failed.length \u003e 0) {\n    runsWithAnyFail++;\n    for (const s of failed) {\n      failsByShape[s]++;\n      examples[s] ??= results[s];\n    }\n    console.log(`[${i}/${ITERATIONS}] FAIL ${failed.join(',')}`);\n  } else {\n    console.log(`[${i}/${ITERATIONS}] PASS`);\n    await fs.promises.unlink(obfPath);\n    await fs.promises.unlink(harnessPath);\n  }\n}\n\nconsole.log(`\\n=== Summary over ${ITERATIONS} iterations ===`);\nconsole.log(`runs with any failure: ${runsWithAnyFail}/${ITERATIONS} (${((runsWithAnyFail / ITERATIONS) * 100).toFixed(1)}%)`);\nfor (const s of SHAPES) {\n  const n = failsByShape[s];\n  console.log(`  ${s}: ${n}/${ITERATIONS} fail (${((n / ITERATIONS) * 100).toFixed(1)}%)${n \u003e 0 ? ` — example: ${examples[s].slice(0, 120)}` : ''}`);\n}\nconsole.log(`\\nbroken artifacts (if any) kept in: ${tmpDir}`);\n```\n\n## Suspected cause (speculation)\n\nTypeScript and modern JS engines lower `f?.(arg)` to a guarded call shape roughly equivalent to:\n\n```js\n(f === null || f === void 0) ? void 0 : f.call(undefined, arg)\n```\n\n`controlFlowFlattening` rewrites the ternary into a dispatch-table-keyed control flow graph. Under some random keyings, the dispatch branch corresponding to the `=== void 0` guard appears to collapse into the unguarded call — possibly during a dead-branch elimination pass that proves one arm \"unreachable\" using the wrong invariant. The fact that `simplify: false` does *not* prevent the miscompile rules out the simplify pass as the cause; the problem is in (or interacts with) `controlFlowFlattening` itself.\n","author":{"url":"https://github.com/Thorsten-Kd","@type":"Person","name":"Thorsten-Kd"},"datePublished":"2026-05-19T18:00:54.000Z","interactionStatistic":{"@type":"InteractionCounter","interactionType":"https://schema.org/CommentAction","userInteractionCount":3},"url":"https://github.com/1408/javascript-obfuscator/issues/1408"}

route-pattern/_view_fragments/issues/show/:user_id/:repository/:id/issue_layout(.:format)
route-controllervoltron_issues_fragments
route-actionissue_layout
fetch-noncev2:f4314c7a-40d5-bec6-49f7-4a3a818aaee8
current-catalog-service-hash81bb79d38c15960b92d99bca9288a9108c7a47b18f2423d0f6438c5b7bcd2114
request-id8D82:19CEC6:882978:C2A61D:6A633730
html-safe-nonce0ee86aca5227b38fd411c339bf85a59085b53a3a666d346fc200e22982e65a78
visitor-payloadeyJyZWZlcnJlciI6IiIsInJlcXVlc3RfaWQiOiI4RDgyOjE5Q0VDNjo4ODI5Nzg6QzJBNjFEOjZBNjMzNzMwIiwidmlzaXRvcl9pZCI6IjE3OTU4ODExOTMyNzM1NjcyMSIsInJlZ2lvbl9lZGdlIjoiaWFkIiwicmVnaW9uX3JlbmRlciI6ImlhZCJ9
visitor-hmacec2f999c95977638f0f4f1ec09bb24dbda68bb5946cf32e373ea4e5b4fd102dd
hovercard-subject-tagissue:4479782460
github-keyboard-shortcutsrepository,issues,copilot
google-site-verificationApib7-x98H0j5cPqHWwSMm6dNU4GmODRoqxLiDzdx9I
octolytics-urlhttps://collector.github.com/github/collect
analytics-location///voltron/issues_fragments/issue_layout
fb:app_id1401488693436528
apple-itunes-appapp-id=1477376905, app-argument=https://github.com/_view_fragments/issues/show/javascript-obfuscator/javascript-obfuscator/1408/issue_layout
twitter:imagehttps://opengraph.githubassets.com/8cc8ed12989737e08ec377e87c74a1ea2fc720c364158e105c10ff8e4f206476/javascript-obfuscator/javascript-obfuscator/issues/1408
twitter:cardsummary_large_image
og:imagehttps://opengraph.githubassets.com/8cc8ed12989737e08ec377e87c74a1ea2fc720c364158e105c10ff8e4f206476/javascript-obfuscator/javascript-obfuscator/issues/1408
og:image:altWith controlFlowFlattening: true, the obfuscator non-deterministically miscompiles optional-call expressions of the shape captured?.(arg) — where captured is an outer-scope variable referenced insi...
og:image:width1200
og:image:height600
og:site_nameGitHub
og:typeobject
og:author:usernameThorsten-Kd
hostnamegithub.com
expected-hostnamegithub.com
None59e55daad7174ca59d63c6974d58276ccb5477442e550bebb3c035e1bef11c94
turbo-cache-controlno-preview
go-importgithub.com/javascript-obfuscator/javascript-obfuscator git https://github.com/javascript-obfuscator/javascript-obfuscator.git
octolytics-dimension-user_id23015672
octolytics-dimension-user_loginjavascript-obfuscator
octolytics-dimension-repository_id58360147
octolytics-dimension-repository_nwojavascript-obfuscator/javascript-obfuscator
octolytics-dimension-repository_publictrue
octolytics-dimension-repository_is_forkfalse
octolytics-dimension-repository_network_root_id58360147
octolytics-dimension-repository_network_root_nwojavascript-obfuscator/javascript-obfuscator
turbo-body-classeslogged-out env-production page-responsive
disable-turbofalse
browser-stats-urlhttps://api.github.com/_private/browser/stats
browser-errors-urlhttps://api.github.com/_private/browser/errors
release990295d92a4cc7b63fbbd83a046217cd7d77d49c
ui-targetfull
theme-color#1e2327
color-schemelight dark

Links:

Skip to contenthttps://github.com/javascript-obfuscator/javascript-obfuscator/issues/1408#start-of-content
https://github.com/
Sign in https://github.com/login?return_to=https%3A%2F%2Fgithub.com%2Fjavascript-obfuscator%2Fjavascript-obfuscator%2Fissues%2F1408
GitHub CopilotWrite better code with AIhttps://github.com/features/copilot
GitHub Copilot appDirect agents from issue to mergehttps://github.com/features/ai/github-app
MCP RegistryNewIntegrate external toolshttps://github.com/mcp
ActionsAutomate any workflowhttps://github.com/features/actions
CodespacesInstant dev environmentshttps://github.com/features/codespaces
IssuesPlan and track workhttps://github.com/features/issues
Code ReviewManage code changeshttps://github.com/features/code-review
Code QualityEnforce quality at mergehttps://github.com/features/code-quality
GitHub Advanced SecurityFind and fix vulnerabilitieshttps://github.com/security/advanced-security
Code securitySecure your code as you buildhttps://github.com/security/advanced-security/code-security
Secret protectionStop leaks before they starthttps://github.com/security/advanced-security/secret-protection
Why GitHubhttps://github.com/why-github
Documentationhttps://docs.github.com
Bloghttps://github.blog
Changeloghttps://github.blog/changelog
Marketplacehttps://github.com/marketplace
View all featureshttps://github.com/features
Enterpriseshttps://github.com/enterprise
Small and medium teamshttps://github.com/team
Startupshttps://github.com/enterprise/startups
Nonprofitshttps://github.com/solutions/industry/nonprofits
App Modernizationhttps://github.com/solutions/use-case/app-modernization
DevSecOpshttps://github.com/solutions/use-case/devsecops
DevOpshttps://github.com/solutions/use-case/devops
CI/CDhttps://github.com/solutions/use-case/ci-cd
View all use caseshttps://github.com/solutions/use-case
Healthcarehttps://github.com/solutions/industry/healthcare
Financial serviceshttps://github.com/solutions/industry/financial-services
Manufacturinghttps://github.com/solutions/industry/manufacturing
Governmenthttps://github.com/solutions/industry/government
View all industrieshttps://github.com/solutions/industry
View all solutionshttps://github.com/solutions
AIhttps://github.com/resources/articles?topic=ai
Software Developmenthttps://github.com/resources/articles?topic=software-development
DevOpshttps://github.com/resources/articles?topic=devops
Securityhttps://github.com/resources/articles?topic=security
View all topicshttps://github.com/resources/articles
Customer storieshttps://github.com/customer-stories
Events & webinarshttps://github.com/resources/events
Ebooks & reportshttps://github.com/resources/whitepapers
Business insightshttps://github.com/solutions/executive-insights
GitHub Skillshttps://skills.github.com
Documentationhttps://docs.github.com
Customer supporthttps://support.github.com
Community forumhttps://github.com/orgs/community/discussions
Trust centerhttps://github.com/trust-center
Partnershttps://github.com/partners
View all resourceshttps://github.com/resources
GitHub SponsorsFund open source developershttps://github.com/open-source/sponsors
Security Labhttps://securitylab.github.com
Maintainer Communityhttps://maintainers.github.com
Acceleratorhttps://github.com/open-source/accelerator
GitHub Starshttps://stars.github.com
Archive Programhttps://archiveprogram.github.com
Topicshttps://github.com/topics
Trendinghttps://github.com/trending
Collectionshttps://github.com/collections
Enterprise platformAI-powered developer platformhttps://github.com/enterprise
GitHub Advanced SecurityEnterprise-grade security featureshttps://github.com/security/advanced-security
Copilot for BusinessEnterprise-grade AI featureshttps://github.com/features/copilot/copilot-business
Premium SupportEnterprise-grade 24/7 supporthttps://github.com/enterprise/premium-support
Pricinghttps://github.com/pricing
Search syntax tipshttps://docs.github.com/search-github/github-code-search/understanding-github-code-search-syntax
documentationhttps://docs.github.com/search-github/github-code-search/understanding-github-code-search-syntax
Sign in https://github.com/login?return_to=https%3A%2F%2Fgithub.com%2Fjavascript-obfuscator%2Fjavascript-obfuscator%2Fissues%2F1408
Sign up https://github.com/signup?ref_cta=Sign+up&ref_loc=header+logged+out&ref_page=%2F%3Cuser-name%3E%2F%3Crepo-name%3E%2Fvoltron%2Fissues_fragments%2Fissue_layout&source=header-repo&source_repo=javascript-obfuscator%2Fjavascript-obfuscator
Reloadhttps://github.com/javascript-obfuscator/javascript-obfuscator/issues/1408
Reloadhttps://github.com/javascript-obfuscator/javascript-obfuscator/issues/1408
Reloadhttps://github.com/javascript-obfuscator/javascript-obfuscator/issues/1408
Please reload this pagehttps://github.com/javascript-obfuscator/javascript-obfuscator/issues/1408
javascript-obfuscator https://github.com/javascript-obfuscator
javascript-obfuscatorhttps://github.com/javascript-obfuscator/javascript-obfuscator
Please reload this pagehttps://github.com/javascript-obfuscator/javascript-obfuscator/issues/1408
Notifications https://github.com/login?return_to=%2Fjavascript-obfuscator%2Fjavascript-obfuscator
Fork 1.7k https://github.com/login?return_to=%2Fjavascript-obfuscator%2Fjavascript-obfuscator
Star 16.2k https://github.com/login?return_to=%2Fjavascript-obfuscator%2Fjavascript-obfuscator
Code https://github.com/javascript-obfuscator/javascript-obfuscator
Issues 15 https://github.com/javascript-obfuscator/javascript-obfuscator/issues
Pull requests 5 https://github.com/javascript-obfuscator/javascript-obfuscator/pulls
Discussions https://github.com/javascript-obfuscator/javascript-obfuscator/discussions
Actions https://github.com/javascript-obfuscator/javascript-obfuscator/actions
Projects https://github.com/javascript-obfuscator/javascript-obfuscator/projects
Security and quality 0 https://github.com/javascript-obfuscator/javascript-obfuscator/security
Insights https://github.com/javascript-obfuscator/javascript-obfuscator/pulse
Code https://github.com/javascript-obfuscator/javascript-obfuscator
Issues https://github.com/javascript-obfuscator/javascript-obfuscator/issues
Pull requests https://github.com/javascript-obfuscator/javascript-obfuscator/pulls
Discussions https://github.com/javascript-obfuscator/javascript-obfuscator/discussions
Actions https://github.com/javascript-obfuscator/javascript-obfuscator/actions
Projects https://github.com/javascript-obfuscator/javascript-obfuscator/projects
Security and quality https://github.com/javascript-obfuscator/javascript-obfuscator/security
Insights https://github.com/javascript-obfuscator/javascript-obfuscator/pulse
#1409https://github.com/javascript-obfuscator/javascript-obfuscator/pull/1409
Non-deterministic ?.() miscompile drops short-circuit on captured variable in nested closurehttps://github.com/javascript-obfuscator/javascript-obfuscator/issues/1408#top
#1409https://github.com/javascript-obfuscator/javascript-obfuscator/pull/1409
bughttps://github.com/javascript-obfuscator/javascript-obfuscator/issues?q=state%3Aopen%20label%3A%22bug%22
https://github.com/Thorsten-Kd
Thorsten-Kdhttps://github.com/Thorsten-Kd
on May 19, 2026https://github.com/javascript-obfuscator/javascript-obfuscator/issues/1408#issue-4479782460
Minimal working examplehttps://github.com/javascript-obfuscator/javascript-obfuscator/issues/1408#minimal-working-example-that-will-help-to-reproduce-issue
http://obfuscator.iohttp://obfuscator.io
https://gist.github.com/Thorsten-Kd/5b2a0b33932dc7534f827bd6dd5b41c5https://gist.github.com/Thorsten-Kd/5b2a0b33932dc7534f827bd6dd5b41c5
bughttps://github.com/javascript-obfuscator/javascript-obfuscator/issues?q=state%3Aopen%20label%3A%22bug%22
https://github.com
Termshttps://docs.github.com/site-policy/github-terms/github-terms-of-service
Privacyhttps://docs.github.com/site-policy/privacy-policies/github-privacy-statement
Securityhttps://github.com/security
Statushttps://www.githubstatus.com/
Communityhttps://github.community/
Docshttps://docs.github.com/
Contacthttps://support.github.com?tags=dotcom-footer

Viewport: width=device-width


URLs of crawlers that visited me.