[
  {
    "path": ".eslintrc.json",
    "content": "{\n\t\"rules\": {\n\t\t\"no-use-before-define\": 2,\n\t\t\"no-caller\": 2,\n\t\t\"no-eq-null\": 2\n\t},\n\t\"parserOptions\": { \"ecmaVersion\": 6 },\n\t\"env\": {\n\t\t\"browser\": true,\n\t\t\"node\": true\n\t}\n}\n"
  },
  {
    "path": ".gitignore",
    "content": "node_modules\n.DS_Store"
  },
  {
    "path": ".npmignore",
    "content": "docs\r\ntest\r\n.DS_Store\r\n.editorconfig\r\n.gitattributes\r\n.jshintrc\r\n.travis.yml\r\nGruntfile.js"
  },
  {
    "path": "CNAME",
    "content": "jsfuck.com"
  },
  {
    "path": "Gruntfile.js",
    "content": "/*global module:false*/\nmodule.exports = function(grunt) {\n\n  // Project configuration.\n  grunt.initConfig({\n    // Task configuration.\n    eslint: {\n      gruntfile: {\n        src: 'Gruntfile.js'\n      },\n      lib_test: {\n        src: ['jsfuck.js', 'lib/**/*.js', 'test/**/*.js']\n      }\n    },\n    nodeunit: {\n      files: ['test/**/*_test.js']\n    },\n    watch: {\n      gruntfile: {\n        files: '<%= eslint.gruntfile.src %>',\n        tasks: ['eslint:gruntfile']\n      },\n      lib_test: {\n        files: '<%= eslint.lib_test.src %>',\n        tasks: ['eslint:lib_test', 'nodeunit']\n      }\n    }\n  });\n\n  // These plugins provide necessary tasks.\n  grunt.loadNpmTasks('grunt-contrib-nodeunit');\n\tgrunt.loadNpmTasks(\"gruntify-eslint\");\n  grunt.loadNpmTasks('grunt-contrib-watch');\n\n  // Default task.\n  grunt.registerTask('default', ['eslint', 'nodeunit']);\n\n};\n"
  },
  {
    "path": "LICENSE.txt",
    "content": "           DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE\n                   Version 2, December 2004\n\nCopyright (C) 2012 Martin Kleppe <http://jsfuck.com>\n\nEveryone is permitted to copy and distribute verbatim or modified\ncopies of this license document, and changing it is allowed as long\nas the name is changed.\n\n           DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE\n  TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION\n\n 0. You just DO WHAT THE FUCK YOU WANT TO."
  },
  {
    "path": "README.md",
    "content": "# JSFuck `[]()!+`\n\nJSFuck is an esoteric and educational programming style based on the atomic parts of JavaScript. It uses only six different characters to write and execute code.\n\nIt does not depend on a browser, so you can even run it on Node.js.\n\nDemo: [jsfuck.com](http://www.jsfuck.com)\n\nBy [@aemkei](https://twitter.com/aemkei) and [friends](https://github.com/aemkei/jsfuck/graphs/contributors).\n\n### Example\n\nThe following source will do an `alert(1)`:\n\n```js\n[][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[])[+[\n]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]][([][(![]+[])[+[]]+([![]]+[][[]\n])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[!+[]+!+[]+!+[]]+\n(!![]+[])[+!+[]]]+[])[!+[]+!+[]+!+[]]+(!![]+[][(![]+[])[+[]]+([![]]+[][[]])[+\n!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![\n]+[])[+!+[]]])[+!+[]+[+[]]]+([][[]]+[])[+!+[]]+(![]+[])[!+[]+!+[]+!+[]]+(!![]\n+[])[+[]]+(!![]+[])[+!+[]]+([][[]]+[])[+[]]+([][(![]+[])[+[]]+([![]]+[][[]])[\n+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!!\n[]+[])[+!+[]]]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[][(![]+[])[+[]]+([![\n]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[!+[]+!+[\n]+!+[]]+(!![]+[])[+!+[]]])[+!+[]+[+[]]]+(!![]+[])[+!+[]]]((![]+[])[+!+[]]+(![\n]+[])[!+[]+!+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]+(!![]+[])[+[]]+(!\n[]+[][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[])\n[+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]])[!+[]+!+[]+[+[]]]+[+!+[]]+(\n!![]+[][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[\n])[+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]])[!+[]+!+[]+[+[]]])()\n```\n\n### Basics\n\n    false       =>  ![]\n    true        =>  !![]\n    undefined   =>  [][[]]\n    NaN         =>  +[![]]\n    0           =>  +[]\n    1           =>  +!+[]\n    2           =>  !+[]+!+[]\n    10          =>  +[[+!+[]]+[+[]]]\n    Array       =>  []\n    Number      =>  +[]\n    String      =>  []+[]\n    Boolean     =>  ![]\n    Function    =>  [][\"filter\"]\n    run         =>  [][\"filter\"][\"constructor\"]( CODE )()\n    eval        =>  [][\"filter\"][\"constructor\"](\"return eval\")()( CODE )\n    window      =>  [][\"filter\"][\"constructor\"](\"return this\")()\n\nSee the full list [here](https://github.com/aemkei/jsfuck/blob/master/jsfuck.js).  \n\n# How it Works\n\n**Note:** Feel free to join the discussion here: https://gitter.im/aemkei/jsfuck\n\n## `[]` – Brackets\n\nLet's start with the opening and closing brackets and see what is possible here. They are super useful for this project and are considered as a core element because they provide a way to:\n\n1. deal with arrays\n2. access properties and methods.\n\n\n### `[]` – Array Literals\n\nCreate new arrays:\n\n```js\n[]   // an empty array\n[[]] // an array with one element (another array)\n```\n\n### `[X][i]` – Array / Object Access\n\n```js\n[][[]] // undefined, same as [][\"\"]\n```\n\nLater we will be able to do this:\n\n```js\n\"abc\"[0]     // get single letter\n[][\"length\"] // get property\n[][\"fill\"]   // get methods\n```\n\n### `[X][0]` - Array wrapping trick\n\nBy wrapping an expression in an array and then getting the element at index zero, we can apply several operators on one expression. This means brackets `[]` can replace parenthesis `()` to isolate expressions:\n\n```js\n          [X][0]           // X\n++[ ++[ ++[X][0] ][0] ][0] // X + 3\n```\n\n## `+` – Plus Sign\n\nThis symbol is useful, because it allows us to:\n\n1. create numbers\n2. add two values\n3. concatenating strings\n4. create strings\n\nThe current version of JSFuck uses it a lot but we not sure if they are fundamental.\n\n### Cast to Number\n\n```js\n+[] // 0 - the number 0\n```\n\n### Increment Numbers\n\nUsing the array wrapping trick mentioned above:\n\n```js\n++[ 0  ][  0  ] // 1\n++[ [] ][ +[] ] // 1\n```\n\n### Getting `undefined`\n\nGetting an element by index in an empty array will return `undefined`:\n\n```js\n[][   0 ] // undefined\n[][ +[] ] // get first element (undefined)\n[][  [] ] // look for property \"\"\n```\n\n### Getting `NaN`\n\nCasting `undefined` to Number will result in not-a-number:\n\n```js\n+[][[]]    // +undefined = NaN\n```\n\n### Add Numbers\n\n```js\n          1 +           1 // 2\n++[[]][+[]] + ++[[]][+[]] // 2\n```\n\nA shorter way using ++:\n\n```js\n++[          1][  0] // 2\n++[++[[]][  0]][  0] // 2\n++[++[[]][+[]]][+[]] // 2\n```\n\nUsing this technique, we are able to access all digits:\n\n`0`, `1`, `2`, `3`, `4`, `5`, `6`, `7`, `8`, `9`\n\n### `+[]` – Casting to String\n\nCombining the plus sign and brackets will turn other values into strings:\n\n```js\n  []        +[] // \"\" - empty string\n +[]        +[] // \"0\"\n  [][[]]    +[] // \"undefined\"\n++[][[]]    +[] // \"NaN\"\n++[[]][+[]] +[] // \"1\"\n```\n\n### `\"word\"[i]` – Get Single Characters\n\nAs we have strings, we can also get single characters:\n\n```js\n  \"undefined\"          [  0] // \"u\"\n[ \"undefined\"    ][  0][  0] // \"u\"\n[  undefined +[] ][+[]][+[]] // \"u\"\n[  [][[]]    +[] ][+[]][+[]] // \"u\"\n```\n\n```js\n  \"undefined\"   [           1 ] // \"n\"\n[[][[]]+[]][+[]][ ++[[]][+[]] ] // \"n\"\n```\n\nSince we have \"NaN\" and \"undefined\", we got the following characters:\n\n`N`,`a`,`d`,`e`,`f`,`i`,`n`,`u`.\n\n## `+` – Combine Characters\n\nNow we can concat characters to new words.\n\n```js\n// can be written using []+ only:\n\"undefined\"[4] // \"f\"\n\"undefined\"[5] // \"i\"\n\"undefined\"[6] // \"n\"\n\"undefined\"[3] // \"d\"\n\n// combine using +\n\"f\"+\"i\"+\"n\"+\"d\" // \"find\"\n```\n\n## `\"e\"` – Numbers in exponential notation\n\nAs we have the character \"e\" from \"undefined\", we can use exponential notation to construct very big numbers and get a reference to `Infinity`:\n\n```js\n+(\"1e309\")         //  Infinity\n+(\"1e309\")     +[] // \"Infinity\"\n+(\"11e100\")        //  1.1e+101\n+(\"11e100\")    +[] // \"1.1e+101\"   (gives us `.` and `+`)\n+(\"0.0000001\")     //  1e-7\n+(\"0.0000001\") +[] // \"1e-7\"       (gives us `-`)\n```\n\nResulting chars:\n\n`I`,`f`,`i`,`n`,`t`,`y`,`.`,`+`,`-`.\n\n\n## `[][\"method\"]` – Access Methods\n\nNewly combinded characters can form method names. These can be accessed using the square brackets notation:\n\n```js\n[][\"f\"+\"i\"+\"n\"+\"d\"] // where \"f\" is the first char of \"false\" and so on\n[][\"find\"]          // same as the dot syntax:\n[] .find\n```\n\n*Note*: With the characters from \"undefined\", \"NaN\" and \"Infinity\", the only method we are able to find in the objects we have is `Array.prototype.find`.\n\n## `method+[]` – Get Method Definitions\n\nWe can cast a method to a String and get its definition as a String:\n\n```js\n[][\"find\"] +[]\n```\n\nThis will return the following String:\n\n```js\n\"function find() { [native code] }\"\n```\n\n*Note*: String representations of native functions are not part of the ECMAScript standard and differ between browsers. For example, Firefox will output a slightly different string with additional line breaks using `\\n`.\n\nResulting characters:\n\n* `a`,`c`,`d`,`e`,`f`,`i`,`n`,`o`,`t`,`u`,`v`\n* ` `, `{`, `}`, `(`, `)`, `[`,`]`\n\nResulting methods:\n\n* `.concat`\n* `.find`.\n\n## `!` – Logical NOT operator\n\nThis is the fourth character in the original JSFuck set and used to create booleans.\n\nNote: This symbol could also be replaced by others, like `<` or `=`. See the section \"Alternatives\" below.\n\n### `!X` – Cast to Boolean\n\nThe logical \"Not\" operator can be used to create booleans `false` and `true`:\n\n```js\n ![] // false\n!![] // true\n```\n\n### `!X+[]` – Get \"true\" and \"false\"\n\nBooleans can be casted to string:\n\n```js\n ![] +[] // \"false\"\n!![] +[] // \"true\"\n```\n\nThis will give us access to more characters:\n\n`a`, `e`, `f`, `l`, `r`, `s`, `t`, `u`.\n\nTogether with the set above, we will have `{}()[]+. INacdefilnorstuvy` with access to these methods:\n\n* `call`\n* `concat`\n* `constructor`\n* `entries`\n* `every`\n* `fill`\n* `filter`\n* `find`\n* `fontcolor`\n* `includes`\n* `italics`\n* `reduce`\n* `reverse`\n* `slice`\n* `sort`\n\n*Important:* We might use another symbols like `=` to create booleans, because they are more powerful (see section \"Alternatives\" below).\n\n## `X[\"constructor\"]` – Primitive wrappers names\n\nWith `.constructor` we have a reference to the function that created the instance. For primitives values, it returns the corresponding built-in wrappers:\n\n```js\n0       [\"constructor\"] // Number\n\"\"      [\"constructor\"] // String\n[]      [\"constructor\"] // Array\nfalse   [\"constructor\"] // Boolean\n[].find [\"constructor\"] // Function\n```\n\nUse `+[]` to convert them to strings and retrieve their function name in order to get more chars:\n\n```js\n0[\"constructor\"]+[] // \"function Number() { ... }\"\n```\n\nNew chars available :\n`m`, `b`, `S`, `g`, `B`, `A`, `F`.\n\n… and more methods and properties:\n\n* `arguments`\n* `big`\n* `bind`\n* `bold`\n* `name`\n* `small`\n* `some`\n* `sub`\n* `substr`\n* `substring`\n* `toString`\n* `trim`\n\n\n## `()` – Parenthesis\n\n### Calling Methods\n\nSince we have access to methods, we can call them to get more power. To do this we need to introduce two more symbols `(` and `)` here.\n\nExample without arguments:\n\n```js\n\"\"[\"fontcolor\"]()   // \"<font color=\"undefined\"></font>\"\n[][\"entries\"]() +[] // \"[object Array Iterator]\"\n```\n\nNew characters:\n\n`j`, `<`, `>`, `=`, `\"`, `/`\n\n### Calling method with more than one argument\n\nCalling a method with more than one argument is non trivial - to do it you can use the following [technique](https://stackoverflow.com/q/63601330/860099) (discovered by trincot) - for example: \n\ncalling string method `\"truefalse\".replace(\"true\",\"1\")` can be written as `[\"true\", \"1\"].reduce(\"\".replace.bind(\"truefalse\"))` and finally:\n\n```js\n[\"true\"][\"concat\"](\"1\")[\"reduce\"](\"\"[\"replace\"][\"bind\"](\"truefalse\"))\n```\n\ncalling array method `[1,2,3].slice(1,2)` can be written as `[1,2].reduce([].slice.bind([1,2,3]))` and finally:\n\n```js\n[1][\"concat\"](2)[\"reduce\"]([][\"slice\"][\"bind\"]([1,2,3]))\n```\n\n\n### Calling string method with more than one argument in \"flow way\"\n\nTo be able to call a method (with multiple arguments) in right side on results of previous method you can use this [technique](https://stackoverflow.com/q/63604058/860099) (discovered by trincot) - for example: `\"truefalse\".replace(\"true\",\"1\").replace(\"false\",\"0\")` can be written as \n\n```js\n\"truefalse\"\n    .split().concat([[\"true\", \"1\"]]).reduce(\"\".replace.apply.bind(\"\".replace))\n    .split().concat([[\"false\", \"0\"]]).reduce(\"\".replace.apply.bind(\"\".replace))\n``` \n\nand finally:\n\n```js\n\"truefalse\"\n  [\"split\"]()[\"concat\"]([[\"true\"][\"concat\"](\"1\")])[\"reduce\"](\"\"[\"replace\"][\"apply\"][\"bind\"](\"\"[\"replace\"]))\n  [\"split\"]()[\"concat\"]([[\"false\"][\"concat\"](\"0\")])[\"reduce\"](\"\"[\"replace\"][\"apply\"][\"bind\"](\"\"[\"replace\"]))\n\n```\n\n### Calling array method with more than one argument in \"flow way\"\n\nTo call array methods in righthand side (flow) way\" we use similar technique like for strings but with additional tricks (details [here](https://stackoverflow.com/q/63631908/860099)) presented in following example: `[3,4,5].slice(1,2).concat(6)` can be written as `[[3,4,5]].concat([[1,2]]).reduce([].slice.apply.bind([].slice)).concat(6)` (similar like for strings) but now we need to find right-hand side way to wrap array `[3,4,5]` and get `[[3,4,5]]` which can be done as follows `[3,4,5].map([].constructor).concat([[[]]])[0].slice(-1)` so we get\n\n```js\n[3,4,5]\n    // call: slice(1,2) \n    .map([].constructor).concat([[[]]])[0].slice(-1)\n    .concat([[1,2]]).reduce([].slice.apply.bind([].slice))\n    // call next method (in flow)\n    .concat(6) \n```\nand finally (after remove dots and commas)\n\n```js\n[3][\"concat\"](4)[\"concat\"](5)\n    [\"map\"]([][\"constructor\"])[\"concat\"]([[[]]])[0][\"slice\"](-1)\n    [\"concat\"]([[1][\"concat\"](2)])[\"reduce\"]([][\"slice\"][\"apply\"][\"bind\"]([][\"slice\"]))\n    [\"concat\"](6) \n```\n\n\n\n### `number.toString(x)` – Getting any lowercase letter\n\nNumber's `toString` method has an optional argument specifying the base to use (between 2 and 36). With base 36 we can retrieve any *lowercase* letter:\n\n```js\n10[\"toString\"](36) // \"a\"\n11[\"toString\"](36) // \"b\"\n...\n34[\"toString\"](36) // \"y\"\n35[\"toString\"](36) // \"z\"\n```\nExposed characters: `abcdefghijklmnopqrstuvwxyz`\n\n### `Function(\"code\")()` – Evaluate Code\n\nThe Function constructor is the master key in JSFuck: It takes a String as an argument and returns a new anonymous function with this string as the function body. So it basically lets you evaluate any code as a String. This is like `eval`, without the need for a reference to the global scope (a.k.a. `window`). We can get the Function constructor e.g. with `[][\"find\"][\"constructor\"]`.\n\nThis is the first major step and an essential part of a JS-to-JSFuck compiler.\n...\n\n### `Function(\"return this\")()` – window\n\nWhen evaluating `function anonymous() { return this }`, we get the invocation context which is a reference to the global scope here: `window`!\n\nGetting a reference to `window` is another huge step forward for JSFuck. With the brackets characters, we could only dig in the available objects: numbers, arrays, some functions... With a reference to the global scope, we now have access to any global variable and the inner properties of these globals.\n\n### Create regular expression object\n\nYou can create regular expression e.g. `/pattern/g` as follows\n\n```js\n[][\"fill\"][\"constructor\"](\"return RegExp\")()(\"pattern\",\"g\")\n```\n\nwhich after removing the comma (by using [multi-arguments technique](#calling-method-with-more-than-one-argument) without `bind`ing) looks as follows\n\n```js\n[\"pattern\"][\"concat\"](\"g\")[\"reduce\"]([][\"fill\"][\"constructor\"](\"return RegExp\")())\n```\n\n---\n\n# Alternatives\n\n\n## Combine Characters\n\nInstead of `+` we could use `.concat` to combine strings:\n\n```js\n\"f\"[\"concat\"](\"i\")[\"concat\"](\"l\")[\"concat\"](\"l\") // fill\n```\n\nProblem: We need to combine \"c\", \"o\", \"n\", \"c\", \"a\" and \"t\" to get \"concat\".\n\n## Booleans\n\nThe `!` might be replaced with more \"powerful\" characters that have more than one use.\n\n### `=` – Boolean + Assign Values\n\n```js\nX == X // true\nX == Y // false\nX = Y  // assign a new value\n```\n\n### `>` – Boolean + Create Numbers\n\n```js\nX > Y  // true\nX > X  // false\nX >> Y // number\n```\n\nA more complex example is to get character \"f\" with `[]>+` only:\n\n```js\n[[ []>[] ] + [] ] [[]>>[]] [[]>>[]]\n[[ false ] + [] ] [     0] [     0]\n[ \"false\"       ] [     0] [     0]\n  \"false\"                  [     0]\n```\n\n## Numbers\n\nInstead of `+` we could use booleans and bitshift operators to create numbers:\n\n```js\ntrue >> false         // 1\ntrue << true          // 2\ntrue << true << true  // 4\n```\n\nProblem: Some number (like `5`) are harder to get. But it is possible when using strings, eg `\"11\" >> true`.\n\n## Execute Functions\n\nWays of executing functions other than using `()`:\n\n1. using backticks: `` ` ``\n2. handle events: `on...`\n3. constructor: `new ...`\n4. type conversion: `toString|valueOf`\n5. symbol datatype: `[Symbol...]`\n\n### Using Backticks\n\nInstead of using opening and closing parentheses, we could use backticks ` to execute functions. In ES6 they can be used to interpolate strings and serve an expression for tagged template literals.\n\n```js\n([][\"entries\"]``).constructor // Object\n```\n\nThis would give us characters from \"Object\" and access to its methods.\n\nUnfortunately, we can only pass a single string (from our basic alphabet eg. `[]!+`) as the parameter. It is not possible to call methods with multiple arguments or a precompiled string. To do that, we have to use expression interpolation using `${}` which would introduce new characters.\n\nThe possibilities of backticks were discussed in detail [in the Gitter chat room](https://gitter.im/aemkei/jsfuck).\n\n### Mapping Type Conversion\n\nAnother approach to execute functions without parentheses would be to map the `.toString` or `.valueOf` method and call them implicitly.\n\n```js\nA = []\nA[\"toString\"] = A[\"pop\"]\nA+\"\" // will execute A.pop\n```\n\nNote: There is no way to pass arguments and it requires to `=` be present in our basic alphabet. And it only works for methods that return basic types.\n\nSo far the only use-case is to wire `.toSource` in Firefox to get special characters like the backslash `\\`.\n\n### Trigger Event Handler\n\nFunction or methods could also be executed by assinging them to an event hander. There are several ways to do that, e.g:\n\n```js\n// override onload event on start\nonload = f\n\n// write image tags\ndocument.body.innerHTML = '<img onerror=f src=X />'\n\n// throw and handle error\nonerror=f; throw 'x'\n\n// trigger event\nonhashchange = f; location.hash = 1;\n```\n\nNote: We need `=` to assign the handler.\n\nProblem: We do not have access to `window` or DOM elements to attatch the event handlers.\n\n### Constructor\n\nWe could also use the `new` operator to call the function as a pseudo object type:\n\n```js\nnew f\n```\n\nProblem: The `new` operator is not (yet) available with our basic set of symbols.\n\n### Symbol\n\nA symbol is a unique and immutable data type and may be used as an identifier for object properties. This can be used to implicitly call a function.\n\n```js\nf[Symbol.toPrimitive] = f;  f++;\nf[Symbol.iterator]    = f; [...f];\n```\n\nNote: We need `=` to assign the function.\n\nProblem: We do not have access to `Symbol` using our reduced character set.\n\n# Further Readings\n\nJSFuck was not the first approach! Many people around the world are trying to break the so-called \"Wall\". Read more here:\n\n* [Esolang Wiki: JSFuck](https://esolangs.org/wiki/JSFuck)\n* [sla.ckers.org](http://sla.ckers.org/forum/read.php?24,32930) – Original Discussion\n* [Xchars.js](http://slides.com/sylvainpv/xchars-js/) – Sylvain Pollet-Villard\n* [Non Alphanumeric JavaScript](http://patriciopalladino.com/blog/2012/08/09/non-alphanumeric-javascript.html) – Patricio Palladino\n* [Non-alphanumeric code](http://www.businessinfo.co.uk/labs/talk/Nonalpha.pdf) – Gareth Heyes\n* [Executing non-alphanumeric JavaScript without parenthesis](http://blog.portswigger.net/2016/07/executing-non-alphanumeric-javascript.html) – Portswigger\n"
  },
  {
    "path": "fuck.js",
    "content": "#!/usr/bin/env node\n\nvar stream = require('stream');\nvar util = require('util');\nvar lib = require(\"./jsfuck.js\");\nvar repl = require('repl');\n\nif(process.argv.length !== 3) {\n\n  function Stream() {\n    stream.Transform.call(this);\n  }\n  util.inherits(Stream, stream.Transform);\n\n  Stream.prototype._transform = function (chunk, encoding, callback) {\n    var script = lib.JSFuck.encode(chunk.toString());\n    var lines = script.split(/\\n+/);\n    for (var i = 0; i < lines.length; i++) {\n      // ignore empty lines\n      if (lines[i] !== '') this.push(lines[i] + '\\n');\n    }\n    callback();\n  };\n\n  var fuckScript = new Stream();\n  repl.start({\n    prompt: \"FUCK> \",\n    input: fuckScript,\n    useColors: true,\n    output: process.stdout\n  });\n\n  process.stdin.pipe(fuckScript);\n} else {\n  var data = require(\"fs\").readFileSync(process.argv[2], \"utf8\");\n  var output = lib.JSFuck.encode(data, false);\n  console.log(output);\n}\n"
  },
  {
    "path": "index.html",
    "content": "<html>\n<head>\n  <title>JSFuck - Write any JavaScript with 6 Characters: []()!+</title>\n  <meta name=\"description\" content=\"JSFuck is an esoteric and educational programming style based on the atomic parts of JavaScript. It uses only six different characters to execute code.\">\n  <meta charset=\"utf-8\" />\n  <meta property=\"og:image\" content=\"http://www.jsfuck.com/preview.png\" />\n  <meta name=\"viewport\" content=\"width=device-width\" />\n  <style>\n    \n    body {\n      padding: 20px;\n    }\n    \n    body, * {\n      font-family: monospace;\n      font-size: 14px;\n      line-height: 1.4em;\n    }\n    \n    h1 {\n      font-size: 2em;\n      position: absolute;\n      top: 70px;\n      font-weight: normal;\n      left: 140px;\n    }\n    \n    h2 {\n      width: 90px;\n      text-align: right;\n      padding: 50px 5px 5px;\n      background: #F0DB4E;\n      color: #323230;\n      font-weight: bold;\n      font-size: 20px;\n      line-height: 1em;\n    }\n    \n    h3 {\n      font-weight: bold;\n    }\n        \n    p, li, textarea, .actions {\n      width: 100%;\n      max-width: 600px;\n    }\n    \n    textarea {\n      display: block;\n      height: 200px;\n      margin: 1em 0;\n    }\n    \n    ul.pre li{\n      white-space: pre;\n    }\n    \n    .checkbox {\n      display: inline-block;\n    }\n    \n    .actions a {\n      float: right;\n    }\n    \n    .actions {\n      clear: both;\n    }\n    \n  </style>\n</head>\n<body>\n  <h1>JSFuck</h1>\n  \n  <h2>()+<br>[]!</h2>\n  \n  <p>JSFuck is an esoteric and educational programming style based on the\n  atomic parts of JavaScript. It uses only six different characters to\n  write and execute code.</p>\n  \n  <p>It does not depend on a browser, so you can even run it on Node.js.</p>\n  \n  <p>Use the form below to convert your own script. Uncheck \"eval source\" to\n  get back a plain string.</p>\n\n  <input id=\"input\" type=\"text\" value=\"alert(1)\"/> \n  <button id=\"encode\" type=\"text\">Encode</button>\n  \n  <div class=\"checkbox\">\n    <input id=\"eval\" type=\"checkbox\" checked />\n    <label for=\"eval\">Eval Source</label>\n  </div>\n    <div class=\"checkbox\">\n    <input id=\"scope\" type=\"checkbox\" checked />\n    <label for=\"scope\">Run In Parent Scope</label>\n  </div>\n  \n  <textarea id=\"output\"></textarea>\n  <div class=\"actions\">\n    <span id=\"stats\">…</span>\n    <a id=\"run\" href=\"#\">Run This</a>\n  </div>\n  \n  <h3>Links</h3>\n  \n  <ul>\n    <li>\n      Share on\n      <a href=\"https://twitter.com/intent/tweet?text=This%20project%20is%20crazy:%20http://jsfuck.com%20%E2%80%93%20Write%20any%20JavaScript%20with%206%20characters%20[]()!%2B%20//%20via%20@aemkei\" target=\"_blank\">Twitter</a>\n    </li>\n    <li>View source on <a href=\"http://github.com/aemkei/jsfuck\">GitHub</a></li>\n    <li>Follow <a href=\"http://twitter.com/aemkei\">@aemkei</a> (Martin Kleppe)</li>\n    <li>Original discussion at <a href=\"http://sla.ckers.org/forum/read.php?24,32930\">Sla.ckers.org</a></li>\n  </ul>\n  \n  <h3>Alternatives</h3>\n  <ul>\n    <li><a href=\"https://github.com/alcuadrado/hieroglyphy\">Hieroglyphy</a> (8 chars, browser only)</li>\n    <li><a href=\"http://utf-8.jp/public/jsfuck.html\">utf-8.jp</a> (broken)</li>\n    <li><a href=\"http://discogscounter.getfreehosting.co.uk/js-noalnum.php\">JS-NoAlnum</a> (broken)</li>\n  </ul>\n  \n  <h3>Basics</h3>\n  \n  <ul class=\"pre\">\n    <li>false       =>  ![]</li>\n    <li>true        =>  !![]</li>\n    <li>undefined   =>  [][[]]</li>\n    <li>NaN         =>  +[![]]</li>\n    <li>0           =>  +[]</li>\n    <li>1           =>  +!+[]</li>\n    <li>2           =>  !+[]+!+[]</li>\n    <li>10          =>  [+!+[]]+[+[]]</li>\n    <li>Array       =>  []</li>\n    <li>Number      =>  +[]</li>\n    <li>String      =>  []+[]</li>\n    <li>Boolean     =>  ![]</li>\n    <li>Function    =>  [][\"filter\"]</li>\n\n    <li>eval        =>  [][\"filter\"][\"constructor\"]( CODE )()</li>\n    <li>window      =>  [][\"filter\"][\"constructor\"](\"return this\")()</li>\n  </ul>\n\n  <p>See the full list <a href=\"https://github.com/aemkei/jsfuck/blob/master/jsfuck.js\">here</a>.</p>\n\n  <script src=\"jsfuck.js\"></script>\n  <script>\n\n    function $(id){\n      return document.getElementById(id);\n    }\n    \n    function encode(){\n      var output = JSFuck.encode($(\"input\").value, $(\"eval\").checked, $(\"scope\").checked);\n      $(\"output\").value = output;\n      $(\"stats\").innerHTML = output.length + \" chars\";\n    }\n  \n    $(\"encode\").onclick = encode;\n    $(\"eval\").onchange = encode;\n    $(\"scope\").onchange = encode;\n    \n    encode();\n    \n    $(\"run\").onclick = function(){\n      value = eval($(\"output\").value);\n\n      if (!$(\"eval\").checked){\n        alert('\"' + value + '\"');\n      }\n      return false;\n    };\n  </script>\n  \n  <script type=\"text/javascript\">\n\n    var _gaq = _gaq || [];\n    _gaq.push(['_setAccount', 'UA-57649-11']);\n    _gaq.push(['_trackPageview']);\n\n    (function() {\n      var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;\n      ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';\n      var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);\n    })();\n\n  </script>\n</body>\n</html>"
  },
  {
    "path": "jsfuck.js",
    "content": "/*! JSFuck 0.5.0 - http://jsfuck.com */\n\n(function(self){\n  const MIN = 32, MAX = 126;\n\n  const SIMPLE = {\n    'false':      '![]',\n    'true':       '!![]',\n    'undefined':  '[][[]]',\n    'NaN':        '+[![]]',\n    'Infinity':   '+(+!+[]+(!+[]+[])[!+[]+!+[]+!+[]]+[+!+[]]+[+[]]+[+[]]+[+[]])' // +\"1e1000\"\n  };\n\n  const CONSTRUCTORS = {\n    'Array':    '[]',\n    'Number':   '(+[])',\n    'String':   '([]+[])',\n    'Boolean':  '(![])',\n    'Function': '[][\"at\"]',\n    'RegExp':   'Function(\"return/\"+false+\"/\")()'\n  };\n\n  const MAPPING = {\n    'a':   '(false+\"\")[1]',\n    'b':   '([][\"entries\"]()+\"\")[2]',\n    'c':   '([][\"at\"]+\"\")[3]',\n    'd':   '(undefined+\"\")[2]',\n    'e':   '(true+\"\")[3]',\n    'f':   '(false+\"\")[0]',\n    'g':   '(false+[0]+String)[20]',\n    'h':   '(+(101))[\"to\"+String[\"name\"]](21)[1]',\n    'i':   '([false]+undefined)[10]',\n    'j':   '([][\"entries\"]()+\"\")[3]',\n    'k':   '(+(20))[\"to\"+String[\"name\"]](21)',\n    'l':   '(false+\"\")[2]',\n    'm':   '(Number+\"\")[11]',\n    'n':   '(undefined+\"\")[1]',\n    'o':   '(true+[][\"at\"])[10]',\n    'p':   '(+(211))[\"to\"+String[\"name\"]](31)[1]',\n    'q':   '(\"\")[\"fontcolor\"]([0]+false+\")[20]',\n    'r':   '(true+\"\")[1]',\n    's':   '(false+\"\")[3]',\n    't':   '(true+\"\")[0]',\n    'u':   '(undefined+\"\")[0]',\n    'v':   '(+(31))[\"to\"+String[\"name\"]](32)',\n    'w':   '(+(32))[\"to\"+String[\"name\"]](33)',\n    'x':   '(+(101))[\"to\"+String[\"name\"]](34)[1]',\n    'y':   '(NaN+[Infinity])[10]',\n    'z':   '(+(35))[\"to\"+String[\"name\"]](36)',\n\n    'A':   '(NaN+[][\"entries\"]())[11]',\n    'B':   '(+[]+Boolean)[10]',\n    'C':   'Function(\"return escape\")()((\"\")[\"italics\"]())[2]',\n    'D':   'Function(\"return escape\")()([][\"at\"])[\"at\"](\"-1\")',\n    'E':   '(RegExp+\"\")[12]',\n    'F':   '(+[]+Function)[10]',\n    'G':   '(false+Function(\"return Date\")()())[30]',\n    'H':   null,\n    'I':   '(Infinity+\"\")[0]',\n    'J':   null,\n    'K':   null,\n    'L':   null,\n    'M':   '(true+Function(\"return Date\")()())[30]',\n    'N':   '(NaN+\"\")[0]',\n    'O':   null,\n    'P':   null,\n    'Q':   null,\n    'R':   '(+[]+RegExp)[10]',\n    'S':   '(+[]+String)[10]',\n    'T':   '(NaN+Function(\"return Date\")()())[30]',\n    'U':   null,\n    'V':   null,\n    'W':   null,\n    'X':   null,\n    'Y':   null,\n    'Z':   null,\n\n    ' ':   '(NaN+[][\"at\"])[11]',\n    '!':   null,\n    '\"':   '(\"\")[\"fontcolor\"]()[12]',\n    '#':   null,\n    '$':   null,\n    '%':   'Function(\"return escape\")()([][\"at\"])[22]',\n    '&':   '(\"\")[\"fontcolor\"](\")[13]',\n    '\\'':  null,\n    '(':   '([][\"at\"]+\"\")[11]',\n    ')':   '(\"\"+[][\"at\"])[12]',\n    '*':   null,\n    '+':   '(+(+!+[]+(!+[]+[])[!+[]+!+[]+!+[]]+[+!+[]]+[+[]]+[+[]])+[])[2]',\n    ',':   '[[]][\"concat\"]([[]])+\"\"',\n    '-':   '(+(.+[0000001])+\"\")[2]',\n    '.':   '(+(+!+[]+[+!+[]]+(!![]+[])[!+[]+!+[]+!+[]]+[!+[]+!+[]]+[+[]])+[])[+!+[]]',\n    '/':   '(false+[0])[\"italics\"]()[10]',\n    ':':   '(RegExp()+\"\")[3]',\n    ';':   '(\"\")[\"fontcolor\"](NaN+\")[21]',\n    '<':   '(\"\")[\"italics\"]()[0]',\n    '=':   '(\"\")[\"fontcolor\"]()[11]',\n    '>':   '(\"\")[\"italics\"]()[2]',\n    '?':   '(RegExp()+\"\")[2]',\n    '@':   null,\n    '[':   '([][\"entries\"]()+\"\")[0]',\n    '\\\\':  '(RegExp(\"/\")+\"\")[1]',\n    ']':   '([][\"entries\"]()+\"\")[22]',\n    '^':   null,\n    '_':   null,\n    '`':   null,\n    '{':   '([0]+false+[][\"at\"])[20]',\n    '|':   null,\n    '}':   '([][\"at\"]+\"\")[\"at\"](\"-1\")',\n    '~':   null\n  };\n\n  const GLOBAL = 'Function(\"return this\")()';\n\n  function fillMissingDigits(){\n    var output, number, i;\n\n    for (number = 0; number < 10; number++){\n\n      output = \"+[]\";\n\n      if (number > 0){ output = \"+!\" + output; }\n      for (i = 1; i < number; i++){ output = \"+!+[]\" + output; }\n      if (number > 1){ output = output.substr(1); }\n\n      MAPPING[number] = \"[\" + output + \"]\";\n    }\n  }\n\n  function replaceMap(){\n    var character = \"\", value, i, key;\n\n    function replace(pattern, replacement){\n      value = value.replace(\n        new RegExp(pattern, \"gi\"),\n        replacement\n      );\n    }\n\n    function digitReplacer(_,x) { return MAPPING[x]; }\n\n    function numberReplacer(_,y) {\n      var values = y.split(\"\");\n      var head = +(values.shift());\n      var output = \"+[]\";\n\n      if (head > 0){ output = \"+!\" + output; }\n      for (i = 1; i < head; i++){ output = \"+!+[]\" + output; }\n      if (head > 1){ output = output.substr(1); }\n\n      return [output].concat(values).join(\"+\").replace(/(\\d)/g, digitReplacer);\n    }\n\n    for (i = MIN; i <= MAX; i++){\n      character = String.fromCharCode(i);\n      value = MAPPING[character];\n      if(!value) {continue;}\n\n      for (key in CONSTRUCTORS){\n        replace(\"\\\\b\" + key, CONSTRUCTORS[key] + '[\"constructor\"]');\n      }\n\n      for (key in SIMPLE){\n        replace(key, SIMPLE[key]);\n      }\n\n      replace('(\\\\d\\\\d+)', numberReplacer);\n      replace('\\\\((\\\\d)\\\\)', digitReplacer);\n      replace('\\\\[(\\\\d)\\\\]', digitReplacer);\n\n      replace(\"GLOBAL\", GLOBAL);\n      replace('\\\\+\"\"', \"+[]\");\n      replace('\"\"', \"[]+[]\");\n\n      MAPPING[character] = value;\n    }\n  }\n\n  function replaceStrings(){\n    var regEx = /[^\\[\\]\\(\\)\\!\\+]{1}/g,\n      all, value, missing,\n      count = MAX - MIN;\n\n    function findMissing(){\n      var all, value, done = false;\n\n      missing = {};\n\n      for (all in MAPPING){\n\n        value = MAPPING[all];\n\n        if (value && value.match(regEx)){\n          missing[all] = value;\n          done = true;\n        }\n      }\n\n      return done;\n    }\n\n    function mappingReplacer(a, b) {\n      return b.split(\"\").join(\"+\");\n    }\n\n    function valueReplacer(c) {\n      return missing[c] ? c : MAPPING[c];\n    }\n\n    for (all in MAPPING){\n      if (MAPPING[all]){\n        MAPPING[all] = MAPPING[all].replace(/\\\"([^\\\"]+)\\\"/gi, mappingReplacer);\n      }\n    }\n\n    while (findMissing()){\n      for (all in missing){\n        value = MAPPING[all];\n        value = value.replace(regEx, valueReplacer);\n\n        MAPPING[all] = value;\n        missing[all] = value;\n      }\n\n      if (count-- === 0){\n        console.error(\"Could not compile the following chars:\", missing);\n      }\n    }\n  }\n\n  function escapeSequence(c) {\n    var cc = c.charCodeAt(0);\n    if (cc < 256) {\n      return '\\\\' + cc.toString(8);\n    } else {\n      var cc16 = cc.toString(16);\n      return '\\\\u' + ('0000' + cc16).substring(cc16.length);  \n    }\n  }\n\n  function escapeSequenceForReplace(c) {\n    return escapeSequence(c).replace('\\\\', 't');\n  }\n\n  function encode(input, wrapWithEval, runInParentScope){\n    var output = [];\n\n    if (!input){\n      return \"\";\n    }\n\n    var unmappped = ''\n    for(var k in MAPPING) {\n      if (MAPPING[k]){\n        unmappped += k;\n      }\n    }\n    unmappped = unmappped.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&');\n    unmappped = new RegExp('[^' + unmappped + ']','g');\n    var unmappedCharactersCount = (input.match(unmappped) || []).length;\n    if (unmappedCharactersCount > 1) {\n      // Without this optimization one unmapped character has encoded length\n      // of about 3600 characters. Every additional unmapped character adds \n      // 2000 to the total length. For example, the length of `~` is 3605,\n      // `~~` is 5600, and `~~~` is 7595.\n      // \n      // The loader with replace has encoded length of about 5300 characters\n      // and every additional character adds 100 to the total length. \n      // In the same example the length of `~~` becomes 5371 and `~~~` -- 5463.\n      // \n      // So, when we have more than one unmapped character we want to encode whole input\n      // except select characters (that have encoded length less than about 70)\n      // into an escape sequence.\n      //\n      // NOTE: `t` should be escaped!\n      input = input.replace(/[^0123456789.adefilnrsuN]/g, escapeSequenceForReplace);\n    } else if (unmappedCharactersCount > 0) {\n      //Because we will wrap the input into a string we need to escape Backslash \n      // and Double quote characters (we do not need to worry about other characters \n      // because they are not mapped explicitly).\n      // The JSFuck-encoded representation of `\\` is 2121 symbols,\n      // so escaped `\\` is 4243 symbols and escaped `\"` is 2261 symbols\n      // however the escape sequence of that characters are \n      // 2168 and 2155 symbols respectively, so it's more practical to \n      // rewrite them as escape sequences.\n      input = input.replace(/[\"\\\\]/g, escapeSequence);\n      //Convert all unmapped characters to escape sequence\n      input = input.replace(unmappped, escapeSequence);\n    }\n\n    var r = \"\";\n    for (var i in SIMPLE) {\n      r += i + \"|\";\n    }\n    r+= \".\";\n\n    input.replace(new RegExp(r, 'g'), function(c) {\n      var replacement = SIMPLE[c];\n      if (replacement) {\n        output.push(\"(\" + replacement + \"+[])\");\n      } else {\n        replacement = MAPPING[c];\n        if (replacement){\n          output.push(replacement);\n        } else {\n          throw new Error('Found unmapped character: ' + c);\n        }\n      }\n    });\n\n    output = output.join(\"+\");\n\n    if (/^\\d$/.test(input)){\n      output += \"+[]\";\n    }\n\n    if (unmappedCharactersCount > 1) {\n      // replace `t` with `\\\\`\n      output = \"(\" + output + \")[\" + encode(\"split\") + \"](\" + encode (\"t\") + \")[\" + encode(\"join\") +\"](\" + encode(\"\\\\\") + \")\";\n    }\n\n    if (unmappedCharactersCount > 0) {\n      output = \"[][\" + encode(\"at\") + \"]\"+\n      \"[\" + encode(\"constructor\") + \"]\" +\n      \"(\" + encode(\"return\\\"\") + \"+\" + output + \"+\" + encode(\"\\\"\") + \")()\";\n    }\n\n    if (wrapWithEval){\n      if (runInParentScope){\n        output = \"[][\" + encode(\"at\") + \"]\" +\n          \"[\" + encode(\"constructor\") + \"]\" +\n          \"(\" + encode(\"return eval\") + \")()\" +\n          \"(\" + output + \")\";\n      } else {\n        output = \"[][\" + encode(\"at\") + \"]\" +\n          \"[\" + encode(\"constructor\") + \"]\" +\n          \"(\" + output + \")()\";\n      }\n    }\n\n    return output;\n  }\n\n  fillMissingDigits();\n  replaceMap();\n  replaceStrings();\n\n  self.JSFuck = {\n    encode: encode\n  };\n})(typeof(exports) === \"undefined\" ? window : exports);\n"
  },
  {
    "path": "output.txt",
    "content": "` ` 58\n`!` 2708\n`\"` 335\n`#` 2717\n`$` 2722\n`%` 1688\n`&` 675\n`'` 2737\n`(` 54\n`)` 61\n`*` 2717\n`+` 70\n`,` 231\n`-` 135\n`.` 72\n`/` 215\n`0` 8\n`1` 10\n`2` 14\n`3` 19\n`4` 24\n`5` 29\n`6` 34\n`7` 39\n`8` 44\n`9` 49\n`:` 1303\n`;` 677\n`<` 203\n`=` 331\n`>` 209\n`?` 1298\n`@` 2698\n`A` 185\n`B` 372\n`C` 1840\n`D` 1842\n`E` 1304\n`F` 401\n`G` 2485\n`H` 2700\n`I` 70\n`J` 2706\n`K` 2711\n`L` 2716\n`M` 2486\n`N` 16\n`O` 528\n`P` 2704\n`Q` 2706\n`R` 1299\n`S` 374\n`T` 2488\n`U` 1513\n`V` 2730\n`W` 2735\n`X` 2709\n`Y` 2711\n`Z` 2715\n`[` 171\n`\\` 1509\n`]` 189\n`^` 2735\n`_` 2740\n``` 2714\n`a` 15\n`b` 177\n`c` 55\n`d` 22\n`e` 25\n`f` 13\n`g` 384\n`h` 913\n`i` 27\n`j` 182\n`k` 902\n`l` 19\n`m` 373\n`n` 18\n`o` 54\n`p` 924\n`q` 678\n`r` 16\n`s` 24\n`t` 14\n`u` 16\n`v` 918\n`w` 927\n`x` 932\n`y` 84\n`z` 957\n`{` 63\n`|` 2745\n`}` 216\n`~` 2755\n"
  },
  {
    "path": "package.json",
    "content": "{\n  \"name\": \"jsfuck\",\n  \"version\": \"0.5.0\",\n  \"description\": \"Write any JavaScript with just 6 characters: []()!+\",\n  \"main\": \"jsfuck.js\",\n  \"bin\": \"fuck.js\",\n  \"repository\": {\n    \"type\": \"git\",\n    \"url\": \"git://github.com/aemkei/jsfuck.git\"\n  },\n  \"keywords\": [\n    \"esoteric\",\n    \"obfuscation\"\n  ],\n  \"author\": {\n    \"name\": \"Martin Kleppe\",\n    \"url\": \"https://github.com/aemkei\"\n  },\n  \"licenses\": [\n    {\n      \"type\": \"WTFPL\",\n      \"url\": \"https://raw.github.com/aemkei/jsfuck/master/LICENSE.txt\"\n    }\n  ],\n  \"bugs\": {\n    \"url\": \"https://github.com/aemkei/jsfuck/issues\"\n  },\n  \"scripts\": {\n    \"start\": \"grunt default watch\"\n  },\n  \"devDependencies\": {\n    \"grunt\": \"^0.4.5\",\n    \"grunt-cli\": \"~1.2.0\",\n    \"grunt-contrib-nodeunit\": \"~0.2.0\",\n    \"grunt-contrib-watch\": \"~0.5.3\",\n    \"gruntify-eslint\": \"^5.0.0\"\n  }\n}\n"
  },
  {
    "path": "test/jsfuck_test.js",
    "content": "/*jshint -W061 */\n'use strict';\n\nvar JSFuck = require('../jsfuck.js').JSFuck,\n\ttest_encode = function (test, value) {\n\t\tvar encoded = JSFuck.encode(value),\n\t\t\tunencoded = eval(encoded);\n\n\t\ttest.strictEqual(value, unencoded, 'encoding \"' + value + '\" failed');\n\t};\nvar MIN = 32, MAX = 127;\nvar fs = require('fs');\n\nexports['integration'] = {\n\t'test': function(test) {\n\t\tvar file = fs.openSync('output.txt', 'w+');\n\n\t\tfor (var i = MIN; i < MAX; i++) {\n\t\t\tvar c = String.fromCharCode(i),\n\t\t\t\tencoded = JSFuck.encode(c);\n\t\t\tfs.writeSync(file, '`' + c + '` ' + encoded.length + '\\n');\n\t\t}\n\n\t\tfs.closeSync(file);\n\t\ttest.done();\n\t}\n};\n\nvar test = function (c, test) {\n\ttest_encode(test, c);\n\ttest.done();\n};\n\nvar createTest = function (input) {\n\texports['encode_tests']['encode \"'+input+'\"'] = test.bind(undefined, input);\n};\n\nexports['encode_tests'] = {};\n\ncreateTest('false');\ncreateTest('falsefalsetrue');\ncreateTest('ABCDEFGHIJKLMNOPQRSTUVWXYZ');\ncreateTest('abcdefghijklmnopqrstuvwxyz');\ncreateTest(';&');\ncreateTest('\\n');\ncreateTest('\\r');\ncreateTest('\\r\\n');\ncreateTest('\\u2028\\u2029');\ncreateTest('false');\ncreateTest('true');\ncreateTest('undefined');\ncreateTest('NaN');\ncreateTest('Infinity');\ncreateTest('undefinedundefined');\ncreateTest('0undefined0');\ncreateTest('undefinedArray');\ncreateTest('ArrayundefinedBoolean');\ncreateTest('undefinedBooleanArray');\ncreateTest('NaNNaN');\ncreateTest('InfinityInfinity');\ncreateTest('InfinityInfinity');\ncreateTest('NaNtrue');\ncreateTest('trueNaN');\ncreateTest('undefinedNaN');\ncreateTest('~\\\\\"');\ncreateTest('t~');\ncreateTest('~t');\ncreateTest('[(~t~)]');\ncreateTest('~0123456789 abcdefghijklmnopqrstuvwxyz()+.~');\ncreateTest('~0123456789 ABCDEFGHIJKLMNOPQRSTUVWXYZ()+.~');\n\nfor(var i=MIN; i<MAX ;i++) {\n\tcreateTest(String.fromCharCode(i));\n}\n"
  }
]