web素材を超圧縮

html、js、css、svg等を圧縮して自己展開するprogramを紹介します。minifyではなく汎用的な可逆圧縮となります(minify後に使うと更に効果的)。展開には外部js不要。
圧縮された文字列は基本的にhtmlかjs fileで扱う事になります。css fileやsvg fileに埋め込んで使う事はできません。しかし展開した文字列をcssやsvg等としてDOMに追加する処理をすれば疑似的にcssやsvgとして使えます。
[先日投稿した記事](https://qiita.com/mashuel/items/9b76e0c9585dd46a834e)が原作となっています。最新版は[github](https://github.com/da0ka/ppminy)にて公開中。試し切りは以下のcodepenよりどうぞ。
<p class=codepen data-height="450" data-default-tab="result" data-slug-hash="BaEBoVj" data-user="xezz" style="height:450px;box-sizing:border-box;display:flex;align-items:center;justify-content:center;border:2px solid;margin:1em 0;padding:1em;"> <span>See the Pen <a href="https://codepen.io/xezz/pen/BaEBoVj">web contents compressor</a> by xezz (<a href="https://codepen.io/xezz">@xezz</a>) on <a href="https://codepen.io">CodePen</a>.</span></p><script async src="https://cpwebassets.codepen.io/assets/embed/ei.js"></script>
(?)を押下すると大まかな使い方は表示されますが英語もどきです。github版よりcodepen版の方が使いやすいかも。

## benchmark
II+SEEまたはII+SEE2、multi-pass 22による圧縮結果。
<table>
<tr><td>file<td>元size<td>base253<td>base122
<tr><td>angular-1.8.2.min.js<td>177366<td>51826<td>58503
<tr><td>bootstrap-3.3.6.min.js<td>36868<td>8901<td>10000
<tr><td>jquery-3.7.1.min.js<td>878526<td>26691<td>30108
<tr><td>jquery-ui-1.11.4.min.js<td>240427<td>49793<td>56239
<tr><td>react-0.13.3.js<td>600572<td>92455<td>104454
<tr><td>vue-2.7.16.js<td>434871<td>75488<td>85246
</table>

## 使い方
* 手法
    1.  tiny

        復号器は最軽量、小さい素材に対して効果的

    2.  II

        遺伝法実装により圧縮率向上

    3.  II2

        上記の改良型. 最も微妙な性能

    4.  II+SEE

        Secondary Escape Estimation(SEE)実装. 大き目の素材が好物

    5.  II+SEE2

        SEEを追加実装. 復号器は最大. 超巨大っポイ素材の圧縮に向いている

* order

    予測に用いる文脈の長さ指定. 限度は15(tiny), 31(II,II2), 63(II+SEE,II+SEE2)となる. 長い方が高圧縮率になる事もあるが,速度が犠牲になり空間消費量も増大,最悪の場合死に至るわけがない

* encode

    textareaに入力した文字列を圧縮. 圧縮前にUnicodeからoptionで指定したcharsetに変換され. **全ての`\r, \r\n`を`\n`とみなす**

* do
    * eval

        復号後の文字列をJavaScriptとみなして実行

    * write

        復号後の文字列を書き出す. 通常htmlと御一緒に用いる

    * stored

        復号後の文字列を変数に格納. 変数名は[variable name]の項目で設定

* textarea(上段)

    ここに投下したfileは圧縮される. その場合[encode]を押下した場合と異なり,改行類は原型のまま扱う. ついでにUnicodeから変換する手順も省略

* textarea(下段)

    圧縮結果が出力される. 編集するなり焼くなりご自由に

* multi-pass #

    複数回圧縮を試みて最適なorderを選択. 0=無効, 1以上で #+2 回試行. 最大63. orderの設定は自動更新されるので注意

* variable name

    復号後の文字列を格納する変数の名前を設定. [do - stored] を選択していた場合に意味をなす.

    変数名だけでなく `document.body.innerHTML`, `element.textContent`, `class.prototype.text` などといったobjectも対象できる.

    `[^\w$.]+` のみからなる文字列を入力すると, 自動的に復号器の名前を採用します(bやf). 例えば, `#%&` -> `b` 等となる

* format
    * js

        純粋js fileと同等. 出力fileの拡張子はjsが既定値

    * html

        圧縮結果をhtmlで囲む. そのhtmlをformat欄の上段textareaと下段textareで指定する. 出力fileの拡張子はhtmが既定値

        presetでhtmlの雛型を召喚する(meta要素のcharset属性はbase253ならl1, それ以外はutf8が既定値)

* charset
    * inText
        * utf-8, Latin1

            textareaの文字列(Unicode)を選択した方式に変換

        * 10d

            10進数列(`0,10,99,255...`)で入力. 区切り文字は`[^0-9]`

        * 16h

            16進数列(`00,0A,99,FF...`)で入力. 区切り文字は`[^0-9A-Fa-f]`

    * inFile

        file投下して圧縮した場合に復号器に書き込む文字符号を指定. また,上段textaraにfileを投下した時に埋め込む文字列の符号化方式もこれが反映する

    * output
        * base64

            圧縮文は`[0-9A-Za-z+/]`のみからなる文字列となる. 膨張率約33%. 復号回路は最小. gzipで再圧縮しやすい

        * base122

            圧縮文は`[\1-\t\x0B\x0C\x0E-!#-%'-[]-\xff\u0180-\u01ff\u0280-\u02ff\u0380-\u03ff\u0480-\u04ff\u0580-\u05ff]`のみからなる文字列となる. 膨張率約14%. **文字符号はutf8として保存すべし**. 復号回路は最大

        * base253

            圧縮文は`[\0-\x0C\x0D-\xFF]`のみからなる文字列となる. 膨張率約1.2%. **NUL文字(\0)は複写や貼り付け不能. 文字符号はlatin1(iso-8859-1)として保存すべし**

* RawDecoder

    無圧縮の復号器を生成. gzipで再圧縮しやすくなる

* drop & embed text

    textareaにfileを投下すると同時に文字列を埋め込む. 無効にしておくと描画処理を省く分高速. ついでに空間消費量も節約

* links gain only

    圧縮結果が元fileより小さければdownload用URLを生成

* files
    * kill

        圧縮結果を全て破棄

    * LOAD

        fileを開いて圧縮開始

    * Save

        圧縮結果を全て保存

* Download

    下段textareaの内容保存

* Test

    別窓を開いてその中身に下段textareaの内容を埋め込む

* Reset

    初期化
* exit

    全てが崩壊し終焉を迎える

## 蛇足
やれやれ何が超圧縮だ…などとがっかりされた方、失望地獄のどん底に叩き込まれた方、申し訳ありません。ただの未熟者が作り上げてしまった単なる出来損ない未満のprogram故に、その程度の悲劇は大目に見て下さい…