JsExe 1.1.2 - JavaScript demo packer
by Charles Boccato (cb / adinpsz), 2012-2014

For any feedback: cb@adinpsz.org

=== Presentation ===

* JsExe is a demo-oriented JavaScript compressor. It takes as an input a standalone JavaScript source file and produces an HTML source file which executes a JavaScript with the same behaviour as the input one. JsExe aims to produce the smallest HTML file, using the best combination of compression tricks, starting with embedding JavaScript code in a PNG image. It is getting really useful for 1k demos (i.e. 1024 bytes) or larger.

In the default mode, here what JsExe does:

- It takes an JavaScript file as an input parameter.
- If it helps, the JavaScript file is optimized using an improved version of Google Closure Compiler (with no line break, better float formatting, etc).
- File byte order is reversed or not (depending on whether it improves final compression rate or not).
- It embeds the resulting file in a PNG image (8-bit grayscale format, one or more rows).
- Then it uses the most efficient combination of PNG optimizer tools, among PNGOUT, OptiPNG, AdvanceCOMP and DeflOpt.
- The output PNG is tripped of its last bytes.
- Finally the loader in charge of file decompression is appended to the output file.

For each step of the compression chain, you can force a choice by using the corresponding command line parameter. Please execute JsExe.exe for more details.

* Optionally, JsExe may parse your source file and apply a name mangling operation on 2D/3D canvases. Name mangling aims to redefine native browser functions with shorter names, reducing the cost of calling these functions. That way, a few additional bytes could be saved. For example, if there is an existing 3D context named "ctx", the name mangling operation could save a few bytes:

  for (x in ctx)
    ctx[x[0]+x[6]] = ctx[x];

  ctx.aS(...); // call ctx.attachShader(), saving 10 bytes
  ctx.bf(...); // call ctx.bindBuffer(), saving 8 bytes

In the example, the "x[0]+x[6]" expression is called the "hash function". JsExe is able to parse your source file, find the optimal hash function for 2D and/or 3D context, and then patch your file. Please execute JsExe.exe for more details.

=== Recommendations ===

* The JavaScript loader use a 2D canvas element for its own purpose. V is the name of this canvas element, and C is the name of the 2D context. If your demo is based on a 2D canvas and if you want to save a few bytes, you can reuse V and C variables. If so, your code may start with:

  // no need to create C and V variables, they have already been created by the bootstrapper
  V.style.position = 'fixed';
  V.style.top = 0;
  V.style.left = 0;
  V.width = 640;
  V.height = 480;
  C.fillRect(0, 0, 640, 480);
  // etc.

If your demo uses a WebGL canvas, you have to create a new one because an initialized 2D context cannot be converted to a 3D context.

* Do not compress your demo before packing it with JsExe. JavaSript-based compressions -- such as regexp packers -- are counterproductive if you apply PNG embedding next.

=== Changes from v1.1.1 to v1.1.2 ===

* Fix bug in JavaScript bootstrap on input files bigger than 8kb with --order=reverse enabled.
* New intermediate file when --debug enabled:
   5.image.raw: raw image file that contains copy of data bytes stored in output PNG

=== Changes from v1.1.2 to v1.1.1 ===

* Add Chrome up to v33 and Firefox up to v24 name mangling support.

=== Changes from v1.1.0 to v1.1.1 ===

* Fix mix-up between debug intermediate files when JsExe is comparing several compression methods.
* Fix Firefox v22 support of some random generated PNG.

=== Changes from v1.0.2 to v1.1.0 ===

* Add function name mangling.
* Do not remove IDAT checksum anymore (due to Firefox v22 support, 4 bytes lost)
* Set PNG maximum width to 8192 bytes (due to Firefox v22 support)
* Option for outputting all intermediate files:
   1.mapping.txt: name mangling table
   2.mangled.js: input file after name mangling
   3.externs.js: externs file sent to Closure Compiler
   4.compiled.js: optimized JavaScript file
   5.unoptimized.png: unoptimized output PNG
* Option for making String.fromCharCode reusable in your code (since this method is already used in the JavaScript loader).
* New long option names.

=== Changes from v1.0.1 to v1.0.2 ===

* Because of multirow PNG support there is no limit on input file size anymore.
* PNG color format choice has been removed. It is no more needed since the improved chain of PNG tools ("PNG script") produces the same results regardless of the color format. Thanks to AdvanceCOMP, DeflOpt and a better use of PNGOUT and OptiPNG, results are no longer dependent on the slight randomness of zlib compressor.
* For the same reason, selection of PNG optimizer has been removed, except for PNGOUT. The latter may still be used for test purposes, because it is much faster than new "PNG script" option.
* UI has been improved.

=== Greetings ===

* Gasman, Daeken, p01 for their bright ideas,
* Wullon as usual,
* Google, Ken Silverman, Cosmin Truta, Ben Jos Walbeehm, Andrea Mazzoleni for their tools.
