Showing preview only (459K chars total). Download the full file or copy to clipboard to get everything.
Repository: Siorki/RegPack
Branch: master
Commit: a710c19a4ebe
Files: 133
Total size: 423.1 KB
Directory structure:
gitextract_zqrzria2/
├── .gitattributes
├── .gitignore
├── .gitignore.default
├── .npmignore
├── LICENSE
├── README.md
├── TestCases/
│ ├── audioContext_create1.js
│ ├── audioContext_create2.js
│ ├── audioContext_create3.js
│ ├── audioContext_create4.js
│ ├── double_renaming.js
│ ├── gitHub#17-multipleContexts.js
│ ├── gitHub#19-setInterval_declarationAlone.js
│ ├── gitHub#19-setInterval_declarationAtBegin1.js
│ ├── gitHub#19-setInterval_declarationAtBegin2.js
│ ├── gitHub#19-setInterval_declarationAtEnd1.js
│ ├── gitHub#19-setInterval_declarationAtEnd2.js
│ ├── gitHub#19-setInterval_declarationChained1.js
│ ├── gitHub#19-setInterval_declarationChained2.js
│ ├── gitHub#19-setInterval_declarationInArray1.js
│ ├── gitHub#19-setInterval_declarationInArray2.js
│ ├── gitHub#19-setInterval_declarationInFunction1.js
│ ├── gitHub#19-setInterval_declarationInFunction2.js
│ ├── gitHub#19-setInterval_declarationInFunction3.js
│ ├── gitHub#2-unicode.js
│ ├── gitHub#30-webglContext_create_charset.js
│ ├── gitHub#31-direct-hyphenBeginsBlock.js
│ ├── gitHub#31-direct-hyphenEndsBlock.js
│ ├── gitHub#31-direct-singleHyphen.js
│ ├── gitHub#31-negated-hyphenBeginsBlock.js
│ ├── gitHub#31-negated-hyphenEndsBlock.js
│ ├── gitHub#31-negated-singleHyphen.js
│ ├── gitHub#44-setInterval_arrowFunctionMultiParam.js
│ ├── gitHub#44-setInterval_arrowFunctionNoParam.js
│ ├── gitHub#44-setInterval_arrowFunctionSingleParam.js
│ ├── gitHub#47-packer_from92AndReplace.js
│ ├── gitHub#47-packer_from92NoReplace.js
│ ├── gitHub#47-packer_from92ReplaceFails.js
│ ├── gitHub#47-packer_from93AndReplace.js
│ ├── gitHub#47-packer_from93NoReplace.js
│ ├── gitHub#47-packer_rangesBeyond.js
│ ├── gitHub#47-packer_to92AndReplace.js
│ ├── gitHub#47-packer_to92NoReplace.js
│ ├── gitHub#47-packer_to93AndReplace.js
│ ├── gitHub#47-packer_to93NoReplace.js
│ ├── gitHub#47-packer_to93ReplaceFails.js
│ ├── gitHub#55-bothQuotesInUse.js
│ ├── gitHub#55-quotesAsOnlyTokens.js
│ ├── gitHub#55-sameStringInAllQuotes.js
│ ├── gitHub#56-setInterval_arrowComplexValues.js
│ ├── gitHub#56-setInterval_arrowMultipleValues.js
│ ├── gitHub#56-setInterval_arrowNoValue.js
│ ├── gitHub#56-setInterval_arrowOneValue.js
│ ├── gitHub#56-setInterval_arrowSingleValue.js
│ ├── gitHub#56-setInterval_standardComplexValues.js
│ ├── gitHub#56-setInterval_standardMultipleValues.js
│ ├── gitHub#56-setInterval_standardNoValue.js
│ ├── gitHub#56-setInterval_standardOneValue.js
│ ├── gitHub#56-setInterval_standardSingleValue.js
│ ├── gitHub#57-templateLiteralOneVariable.js
│ ├── gitHub#58-lettersOnly.js
│ ├── gitHub#58-numberAsMostFrequent.js
│ ├── gitHub#59-negatedRangeMerge-1vs3.js
│ ├── gitHub#63-backtick2DContext.js
│ ├── gitHub#63-backtickWebGLContext.js
│ ├── gitHub#64-URIError.js
│ ├── gitHub#65-backslash_invalidEscapeSequence.js
│ ├── gitHub#73-backslash_unexpandedToken.js
│ ├── gitHub#83-backslash_largerOutput.js
│ ├── gitHub#83-packer_9Alone.js
│ ├── gitHub#85-backslashSequence.js
│ ├── gitHub#85-flappyDragon.js
│ ├── gitHub#9-hashloop.js
│ ├── hash_using_length.js
│ ├── webglContext_create1.js
│ ├── webglContext_create2.js
│ ├── webglContext_create3.js
│ ├── webglContext_create4.js
│ ├── webglContext_create5.js
│ ├── webglContext_create6.js
│ └── webglContext_substringHash.js
├── bin/
│ └── regpack
├── changelog.txt
├── contextDescriptor_browser.js
├── contextDescriptor_node.js
├── package.json
├── packerData.js
├── patternViewer.js
├── regPack.html
├── regPack.js
├── shapeShifter.js
├── stringHelper.js
├── tests/
│ ├── allTests.js
│ ├── documentMock.js
│ ├── runBenchmark.js
│ ├── testAudioContextCreate.js
│ ├── testIssue0002_UnicodeSupport.js
│ ├── testIssue0009_HashLoopVariable.js
│ ├── testIssue0017_MultipleContexts.js
│ ├── testIssue0019_setInterval.js
│ ├── testIssue0030_webGLContextCreate.js
│ ├── testIssue0031_hyphenInRegex.js
│ ├── testIssue0042_patternViewer.js
│ ├── testIssue0044_setIntervalArrowFunction.js
│ ├── testIssue0045_closingBracket.js
│ ├── testIssue0047_EscapeInCharClass.js
│ ├── testIssue0050_unicodeSurrogate.js
│ ├── testIssue0055_stringDelimiters.js
│ ├── testIssue0056_setIntervalDefaultParams.js
│ ├── testIssue0057_replacementInString.js
│ ├── testIssue0058_numberAsLoopVariable.js
│ ├── testIssue0059_negatedRangeMerge.js
│ ├── testIssue0063_backtickFunctionParam.js
│ ├── testIssue0064_utf8EncodeURI.js
│ ├── testIssue0065_invalidEscapeSequence.js
│ ├── testIssue0072_setIntervalNoInitCode.js
│ ├── testIssue0074_keepWhiteSpaceSeparator.js
│ ├── testIssue0076_listVariablesInString.js
│ ├── testIssue0079_CandXMLComments.js
│ ├── testIssue0082_backticksInTemplateLiterals.js
│ ├── testIssue0083_backslashToken.js
│ ├── testIssue0085_backslashSequenceLength.js
│ ├── testIssue0087_firstCharacterInPattern.js
│ ├── testIssue0088_setIntervalAllocateVariable.js
│ ├── testIssue0089_emptyThermalMapping.js
│ ├── testIssue0094_missingVariableBlock.js
│ ├── testIssue0096_multiLineMinification.js
│ ├── testPackingConsistency.js
│ ├── testStringHelper.js
│ └── testWebGLContextCreate.js
├── thermalViewer.js
└── wiki_images/
├── thermal_view2.xcf
└── thermal_view4.xcf
================================================
FILE CONTENTS
================================================
================================================
FILE: .gitattributes
================================================
# Auto detect text files and perform LF normalization
* text=auto
# Custom for Visual Studio
*.cs diff=csharp
*.sln merge=union
*.csproj merge=union
*.vbproj merge=union
*.fsproj merge=union
*.dbproj merge=union
# Standard to msysgit
*.doc diff=astextplain
*.DOC diff=astextplain
*.docx diff=astextplain
*.DOCX diff=astextplain
*.dot diff=astextplain
*.DOT diff=astextplain
*.pdf diff=astextplain
*.PDF diff=astextplain
*.rtf diff=astextplain
*.RTF diff=astextplain
bin/regpack -crlf
================================================
FILE: .gitignore
================================================
node_modules
================================================
FILE: .gitignore.default
================================================
#################
## Eclipse
#################
*.pydevproject
.project
.metadata
bin/
tmp/
*.tmp
*.bak
*.swp
*~.nib
local.properties
.classpath
.settings/
.loadpath
# External tool builders
.externalToolBuilders/
# Locally stored "Eclipse launch configurations"
*.launch
# CDT-specific
.cproject
# PDT-specific
.buildpath
#################
## Visual Studio
#################
## Ignore Visual Studio temporary files, build results, and
## files generated by popular Visual Studio add-ons.
# User-specific files
*.suo
*.user
*.sln.docstates
# Build results
[Dd]ebug/
[Rr]elease/
*_i.c
*_p.c
*.ilk
*.meta
*.obj
*.pch
*.pdb
*.pgc
*.pgd
*.rsp
*.sbr
*.tlb
*.tli
*.tlh
*.tmp
*.vspscc
.builds
*.dotCover
## TODO: If you have NuGet Package Restore enabled, uncomment this
#packages/
# Visual C++ cache files
ipch/
*.aps
*.ncb
*.opensdf
*.sdf
# Visual Studio profiler
*.psess
*.vsp
# ReSharper is a .NET coding add-in
_ReSharper*
# Installshield output folder
[Ee]xpress
# DocProject is a documentation generator add-in
DocProject/buildhelp/
DocProject/Help/*.HxT
DocProject/Help/*.HxC
DocProject/Help/*.hhc
DocProject/Help/*.hhk
DocProject/Help/*.hhp
DocProject/Help/Html2
DocProject/Help/html
# Click-Once directory
publish
# Others
[Bb]in
[Oo]bj
sql
TestResults
*.Cache
ClientBin
stylecop.*
~$*
*.dbmdl
Generated_Code #added for RIA/Silverlight projects
# Backup & report files from converting an old project file to a newer
# Visual Studio version. Backup files are not needed, because we have git ;-)
_UpgradeReport_Files/
Backup*/
UpgradeLog*.XML
############
## Windows
############
# Windows image file caches
Thumbs.db
# Folder config file
Desktop.ini
#############
## Python
#############
*.py[co]
# Packages
*.egg
*.egg-info
dist
build
eggs
parts
bin
var
sdist
develop-eggs
.installed.cfg
# Installer logs
pip-log.txt
# Unit test / coverage reports
.coverage
.tox
#Translations
*.mo
#Mr Developer
.mr.developer.cfg
# Mac crap
.DS_Store
================================================
FILE: .npmignore
================================================
TestCases
tests
================================================
FILE: LICENSE
================================================
The MIT License (MIT)
Copyright (c) 2012-2016 Siorki
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
------------------------------------------------------------------------------
Code produced by RegPack, including the hashing (if included) and unpacking
routines, is not affected by this license. No restriction to its usage or
redistribution arise from its compression by RegPack.
================================================
FILE: README.md
================================================
**RegPack** is a packer intended for use on minified Javascript code. Current revision is 5.0.4
It is mostly suited to small size constraints (1kb, up to 4kb).
The current version works in seven stages :
- *(if enabled)* 2D, WebGL and Audio contexts method shortcuts are defined and used instead of the long, original names.
- *(if enabled)* variables are renamed in order to reduce character footprint and free tokens for compression.
- *(if enabled)* Initialization code is pushed inside the main loop, with conditional execution on the time variable, so that the unpacker can execute everything through ``setInterval()``
- string quotes are altered in order to minimize escaping inside the strings
- redundancies are eliminated and replaced by tokens, as done by JS Crush (by Aivo Paas) and First Crush (by Tim Down).
- the token list is turned into a regular expression consisting in a character class.
- the tokens are rearranged to create a negated character class (starting with a hyphen ^ then listing nontoken characters)
The text boxes show intermediate stage results. Best one gets a green highlight :
- Preprocessed : after the first four stages. Hidden if no change was brought to the initial code.
- Crushed : after the fifth stage
- RegPack'ed : best between last two stages. Depends on how the characters present in the string are spread in the ASCII table.
--
## Usage tips
- Toggle method hashing for any type of context you use. If the method renaming yields a longer code, RegPack will revert to the original one.
- "Assume global .. is a context" is for environments where the canvas is declared before your code. If entering [js1k](http://www.js1k.com), keep this on, variable is c for classic and g for webgl.
- Variable renaming is also performed inside strings, RegPack does not infer whether they are eval()ed or not. Disable if facing issues with this. Only one-letter variables are considered, others are ignored.
- Crusher settings alter the choice of strings to compress. 1/0/0 is a good allrounder, although more exotic values can yield better results depending on your code.
- Some preprocessing options negatively affect the performance and should be used with caution. Always test your packed code for speed after using these.
- "Encapsulate with(Math)" get rid of all "Math." references in the code and enclose the evaluation with(Math).
- "run with setInterval()" executes the unpacked code with ``setInterval()`` instead of ``eval()`` (meaning the evaluation is performed every frame).
[Use it online](http://siorki.github.io/regPack.html) or integrate it into your Node workflow (thanks to kanaka)
## CLI usage
```
regpack input.js > output.js
regpack input.js --crushGainFactor 1 --crushLengthFactor 0 --crushCopiesFactor 0 > output.js
```
From STDIN
```
cat input.js | regpack - > output.js
```
--
## Running unit tests with Node
```
cd tests
node AllTests
```
--
## License
Licensed under [MIT license](http://opensource.org/licenses/mit-license.html).
Code produced by RegPack, including the hashing (if included) and unpacking routines, is not affected by the license. No restriction to its usage or redistribution arise from its compression by RegPack.
--
Any feedback or improvement suggestions appreciated. Contributions welcome.
@Siorki on Twitter
================================================
FILE: TestCases/audioContext_create1.js
================================================
try {
this.webAudioSupport = true;
if (typeof AudioContext !== "undefined") {
this.audioContext = new AudioContext()
} else if (typeof webkitAudioContext !== "undefined") {
this.audioContext = new webkitAudioContext()
} else {
this.webAudioSupport = false
}
} catch (e) {
this.webAudioSupport = false
}
}
this.audioContext.createBuffer(2,22050,22050);
================================================
FILE: TestCases/audioContext_create2.js
================================================
var stdContext=null, webkitContext=null;
if (typeof AudioContext !== "undefined") {
stdContext = new AudioContext()
}
if (typeof webkitAudioContext !== "undefined") {
webkitContext = new webkitAudioContext()
}
stdContext.createBuffer(1, 22050, 22050);
stdContext.createGain();
webkitContext.createChannelMerger(2);
var c=15;
var d=7;
================================================
FILE: TestCases/audioContext_create3.js
================================================
var stdContext=null, webkitContext=null;
if (typeof webkitAudioContext !== "undefined") {
webkitContext = new webkitAudioContext()
}
if (typeof AudioContext !== "undefined") {
stdContext = new AudioContext()
}
stdContext.createBuffer(1, 22050, 22050);
stdContext.createGain();
webkitContext.createChannelMerger(2);
var c=15;
var d=7;
================================================
FILE: TestCases/audioContext_create4.js
================================================
m=[];s=[0,3,5,7,10];pl=0;for(i=0;16>i;i++)m[i]=0;ac=new webkitAudioContext()||new AudioContext();var nb=ac.createBuffer(1,16384,ac.sampleRate);d=nb.getChannelData(0);for(i=0;16384>i;i++)d[i]=2*Math.random()-1;d=ac.createDelay();d.delayTime.value=60/138;g=ac.createGain();g.gain.value=0.5;c=ac.createDynamicsCompressor();d.connect(g);g.connect(d);g.connect(c);c.connect(ac.destination);setInterval(function(){t=ac.currentTime;n=m[pl];0!=n&&(o=ac.createOscillator(),o.frequency.value=440*Math.pow(2,(n-69)/12),o.type="sawtooth",a=ac.createGain(),g=a.gain,g.setValueAtTime(1,t),g.linearRampToValueAtTime(0,t+1),f=ac.createBiquadFilter(),p=f.frequency,p.setValueAtTime(3E3+2E3*Math.random(),t),p.exponentialRampToValueAtTime(20,t+0.6),f.Q.value=5,o.connect(a),a.connect(f),f.connect(d),o.start(t),o.stop(t+0.5));0==pl%4?(o=ac.createOscillator(),f=o.frequency,f.setValueAtTime(200,t),f.exponentialRampToValueAtTime(10,t+0.25),a=ac.createGain(),g=a.gain,g.setValueAtTime(1.25,t),g.linearRampToValueAtTime(0,t+0.5),o.connect(a),a.connect(c),o.start(t),o.stop(t+0.5)):0==(pl+2)%4?(n=ac.createBufferSource(),n.buffer=nb,n.loop=!0,a=ac.createGain(),g=a.gain,g.setValueAtTime(1.25,t),g.linearRampToValueAtTime(0,t+0.2),f=ac.createBiquadFilter(),p=f.frequency,p.setValueAtTime(2500,t),p.exponentialRampToValueAtTime(500,t+0.1),n.connect(a),a.connect(f),f.connect(c),n.start(t),n.stop(t+1)):(o=ac.createBufferSource(),o.buffer=nb,o.loop=!0,f=ac.createBiquadFilter(),f.type="highpass",f.frequency.value=8E3+2E3*Math.random(),f.Q.value=5,o.connect(f),f.connect(c),o.start(t),o.stop(t+0.02));0==pl&&(i=Math.floor(16*Math.random()),0.1>Math.random()?m[i]=0:(j=Math.floor(Math.random()*s.length),o=Math.floor(Math.random()*Math.random()*3),m[i]=40+s[j]+12*o));pl=(pl+1)%16},60/138*1E3/2);
================================================
FILE: TestCases/double_renaming.js
================================================
a.fillRect(0,0,91,91);
setInterval( function () {
k = 2+2*Math.cos(3.1416*t/64);
i=0;
while(i<300) {
a.strokeStyle = "hsl(20,0%,"+(k*x.charCodeAt(i+300)+(4-k)*x.charCodeAt(i++)-140)/4+"%)";
a.lineWidth=0|(k*x.charCodeAt(i+300)+(4-k)*x.charCodeAt(i++)-140);
a.beginPath();
a.moveTo(k*x.charCodeAt(i+300)+(4-k)*x.charCodeAt(i++)-140,
k*x.charCodeAt(i+300)+(4-k)*x.charCodeAt(i++)-140);
a.lineTo(k*x.charCodeAt(i+300)+(4-k)*x.charCodeAt(i++)-140,
k*x.charCodeAt(i+300)+(4-k)*x.charCodeAt(i++)-140);
a.stroke();
}
w=w?--w:(++t&63)?w:64;
}, 40);
================================================
FILE: TestCases/gitHub#17-multipleContexts.js
================================================
a=a.cloneNode(p=[]);cc=a.getContext("2d");cc.fillStyle=n=cc.createRadialGradient(225,75,40,225,75,60);n.addColorStop(t=0,"#332");n.addColorStop(1,"#000");cc.fillRect(150,0,150,150);e=cc.getImageData(0,0,150,150);d=e.data;setInterval(function(){if(t%1200<1){for(x=y=f=s=0;f<256*256;++f)p[f]=Math.min(0,3*Math.cos((f&255)/40)-4*Math.sin(f/12800)-3);for(n=5e5;--n;s=13*s+2+9*Math.cos(s)|0)for(x+=[0,1,0,-1][s&3],y+=[0,1,0,-1][3-s&3],t=-6;++t;)for(i=-6;++i;)p[256*(y+t&255)+(x+i&255)]+=.01}f=Math.cos(t/200);for(y=-75;++y<75;)for(u=Math.sqrt(75*75-y*y)|0,q=4*((y+75)*150+75-u),x=-u;++x<u;){w=Math.sqrt(75*75-y*y-x*x);i=p[((128*Math.atan2(n=y*Math.sin(f)+Math.cos(f)*w,x)+t)/Math.PI&255)+256*(Math.acos((-w*Math.sin(f)+Math.cos(f)*y)/75)*256/Math.PI|0)];n=.1+.008*Math.max(0,n-x);d[q++]=n*(i<0?0:128+10*i);d[q++]=n*(i<0?0:64+25*i);d[q++]=n*(i<0?128:10*i);d[q++]=255}cc.putImageData(e,0,0);c.fillStyle="hsl(0,0%,"+Math.max(0,100-t)+"%)";c.fillRect(0,0,a.width,a.height);c.save();c.translate(.5*a.width,a.height/2);c.rotate(-.2-.2*Math.cos(Math.max(0,Math.min(t-100,300))*Math.PI/300));c.translate(u=-400+800*Math.cos(Math.max(0,Math.min(t-90,300))*Math.PI/300),500-500*Math.cos(Math.max(0,Math.min(t-1000,300))*Math.PI/300));c.fillStyle="#FFF";for(i=0;++i-3000;)c.fillRect(i*i%4400-1200,i%1700-1200,2,1);n=250-75*Math.cos(Math.max(0,Math.min(t-350,300))*Math.PI/300)-150*Math.cos(Math.max(0,Math.min(t-1000,300))*Math.PI/300);c.drawImage(a,0,0,150,150,1200-n,-n,2*n,2*n);n=150;c.globalCompositeOperation="lighter";for(i=0;++i-7;)c.drawImage(a,150,0,150,150,-n,-n,2*n,2*n);for(i=0;++i-7;)n=50*i,c.drawImage(a,150,0,150,150,-2*u*i-n,-n,2*n,2*n);c.restore();++t},40);
================================================
FILE: TestCases/gitHub#19-setInterval_declarationAlone.js
================================================
a=a.cloneNode(p=[s=5]);t=0;cc=a.getContext("2d");e=cc.getImageData(0,0,150,150);d=e.data;setInterval(function(){if(t%1275<1){cc.fillStyle=n=cc.createRadialGradient(225,75,25,225,75,60);n.addColorStop(x=y=f=0,"rgb("+[50,31+s%15&255,15+s%32&255]);n.addColorStop(1,"#000");cc.fillRect(150,0,150,150);for(;f<256*256;)p[f++]=Math.min(0,3*Math.cos((f&255)/20)-3*Math.cos(f/12800)-s%7+2);for(n=3e5;--n;s*=(256-s)/65)for(x+=[0,1,0,-1][s&3],y+=[0,1,0,-1][3-s&3],t=-6;++t;)for(i=0;++i-6;)p[256*(y+t&255)+(x+i&255)]+=.01}f=Math.cos(++t/200);for(y=-75;++y<75;)for(x=-(u=Math.sqrt(75*75-y*y)&255),q=4*((y+75)*150+75-u);++x<u;){w=Math.sqrt(75*75-y*y-x*x);i=p[((128*Math.atan2(n=y*Math.sin(f)+Math.cos(f)*w,x)+t)/Math.PI&255)+256*(Math.acos((-w*Math.sin(f)+Math.cos(f)*y)/75)*256/Math.PI&255)];n=.1+.008*Math.max(0,n-x);d[q++]=n*(i<0?128-s%128:s%128+s%25*i)&255;d[q++]=n*(i<0?-7*i:75+s%50*i)&255;d[q++]=n*(i<0?s%128:s%75*i)&255;d[q++]=255}cc.putImageData(e,0,0);c.fillStyle="hsl(256,25%,"+Math.max(0,100-t)+"%";c.fillRect(0,0,a.width,a.height);c.save(c.fillStyle="#fff");c.translate(.5*a.width,a.height/2);c.rotate(-.2-.2*Math.cos(Math.max(0,Math.min(t-100,300))*Math.PI/300));c.translate(u=800*Math.cos(Math.max(0,Math.min(t-90,300))*Math.PI/300)-400,500-500*Math.cos(Math.max(0,Math.min(t-1000,300))*Math.PI/300));for(i=0;++i-7500;)c.fillRect(i*i%7525-1500,i%2525-1500,Math.max(i%15/7,t-1200),Math.max(1,t-1100));n=250-75*Math.cos(Math.max(0,Math.min(t-350,300))*Math.PI/300)-150*Math.cos(Math.max(0,Math.min(t-1000,300))*Math.PI/300);c.drawImage(a,0,0,150,150,1200-n,-n,2*n,2*n);n=s|40;c.globalCompositeOperation="lighter";for(i=0;++i-12;)c.drawImage(a,150,0,150,150,-n,-25-n,2*n,2*n);for(i=0;++i-75;)n=25*(i&6),c.drawImage(a,150,0,150,150,-u*i-n,25*i-n,2*n,2*n);c.restore()},33)
================================================
FILE: TestCases/gitHub#19-setInterval_declarationAtBegin1.js
================================================
t=0;a=a.cloneNode(p=[s=5]);cc=a.getContext("2d");e=cc.getImageData(0,0,150,150);d=e.data;setInterval(function(){if(t%1275<1){cc.fillStyle=n=cc.createRadialGradient(225,75,25,225,75,60);n.addColorStop(x=y=f=0,"rgb("+[50,31+s%15&255,15+s%32&255]);n.addColorStop(1,"#000");cc.fillRect(150,0,150,150);for(;f<256*256;)p[f++]=Math.min(0,3*Math.cos((f&255)/20)-3*Math.cos(f/12800)-s%7+2);for(n=3e5;--n;s*=(256-s)/65)for(x+=[0,1,0,-1][s&3],y+=[0,1,0,-1][3-s&3],t=-6;++t;)for(i=0;++i-6;)p[256*(y+t&255)+(x+i&255)]+=.01}f=Math.cos(++t/200);for(y=-75;++y<75;)for(x=-(u=Math.sqrt(75*75-y*y)&255),q=4*((y+75)*150+75-u);++x<u;){w=Math.sqrt(75*75-y*y-x*x);i=p[((128*Math.atan2(n=y*Math.sin(f)+Math.cos(f)*w,x)+t)/Math.PI&255)+256*(Math.acos((-w*Math.sin(f)+Math.cos(f)*y)/75)*256/Math.PI&255)];n=.1+.008*Math.max(0,n-x);d[q++]=n*(i<0?128-s%128:s%128+s%25*i)&255;d[q++]=n*(i<0?-7*i:75+s%50*i)&255;d[q++]=n*(i<0?s%128:s%75*i)&255;d[q++]=255}cc.putImageData(e,0,0);c.fillStyle="hsl(256,25%,"+Math.max(0,100-t)+"%";c.fillRect(0,0,a.width,a.height);c.save(c.fillStyle="#fff");c.translate(.5*a.width,a.height/2);c.rotate(-.2-.2*Math.cos(Math.max(0,Math.min(t-100,300))*Math.PI/300));c.translate(u=800*Math.cos(Math.max(0,Math.min(t-90,300))*Math.PI/300)-400,500-500*Math.cos(Math.max(0,Math.min(t-1000,300))*Math.PI/300));for(i=0;++i-7500;)c.fillRect(i*i%7525-1500,i%2525-1500,Math.max(i%15/7,t-1200),Math.max(1,t-1100));n=250-75*Math.cos(Math.max(0,Math.min(t-350,300))*Math.PI/300)-150*Math.cos(Math.max(0,Math.min(t-1000,300))*Math.PI/300);c.drawImage(a,0,0,150,150,1200-n,-n,2*n,2*n);n=s|40;c.globalCompositeOperation="lighter";for(i=0;++i-12;)c.drawImage(a,150,0,150,150,-n,-25-n,2*n,2*n);for(i=0;++i-75;)n=25*(i&6),c.drawImage(a,150,0,150,150,-u*i-n,25*i-n,2*n,2*n);c.restore()},33)
================================================
FILE: TestCases/gitHub#19-setInterval_declarationAtBegin2.js
================================================
t=0,a=a.cloneNode(p=[s=5]);cc=a.getContext("2d");e=cc.getImageData(0,0,150,150);d=e.data;setInterval(function(){if(t%1275<1){cc.fillStyle=n=cc.createRadialGradient(225,75,25,225,75,60);n.addColorStop(x=y=f=0,"rgb("+[50,31+s%15&255,15+s%32&255]);n.addColorStop(1,"#000");cc.fillRect(150,0,150,150);for(;f<256*256;)p[f++]=Math.min(0,3*Math.cos((f&255)/20)-3*Math.cos(f/12800)-s%7+2);for(n=3e5;--n;s*=(256-s)/65)for(x+=[0,1,0,-1][s&3],y+=[0,1,0,-1][3-s&3],t=-6;++t;)for(i=0;++i-6;)p[256*(y+t&255)+(x+i&255)]+=.01}f=Math.cos(++t/200);for(y=-75;++y<75;)for(x=-(u=Math.sqrt(75*75-y*y)&255),q=4*((y+75)*150+75-u);++x<u;){w=Math.sqrt(75*75-y*y-x*x);i=p[((128*Math.atan2(n=y*Math.sin(f)+Math.cos(f)*w,x)+t)/Math.PI&255)+256*(Math.acos((-w*Math.sin(f)+Math.cos(f)*y)/75)*256/Math.PI&255)];n=.1+.008*Math.max(0,n-x);d[q++]=n*(i<0?128-s%128:s%128+s%25*i)&255;d[q++]=n*(i<0?-7*i:75+s%50*i)&255;d[q++]=n*(i<0?s%128:s%75*i)&255;d[q++]=255}cc.putImageData(e,0,0);c.fillStyle="hsl(256,25%,"+Math.max(0,100-t)+"%";c.fillRect(0,0,a.width,a.height);c.save(c.fillStyle="#fff");c.translate(.5*a.width,a.height/2);c.rotate(-.2-.2*Math.cos(Math.max(0,Math.min(t-100,300))*Math.PI/300));c.translate(u=800*Math.cos(Math.max(0,Math.min(t-90,300))*Math.PI/300)-400,500-500*Math.cos(Math.max(0,Math.min(t-1000,300))*Math.PI/300));for(i=0;++i-7500;)c.fillRect(i*i%7525-1500,i%2525-1500,Math.max(i%15/7,t-1200),Math.max(1,t-1100));n=250-75*Math.cos(Math.max(0,Math.min(t-350,300))*Math.PI/300)-150*Math.cos(Math.max(0,Math.min(t-1000,300))*Math.PI/300);c.drawImage(a,0,0,150,150,1200-n,-n,2*n,2*n);n=s|40;c.globalCompositeOperation="lighter";for(i=0;++i-12;)c.drawImage(a,150,0,150,150,-n,-25-n,2*n,2*n);for(i=0;++i-75;)n=25*(i&6),c.drawImage(a,150,0,150,150,-u*i-n,25*i-n,2*n,2*n);c.restore()},33)
================================================
FILE: TestCases/gitHub#19-setInterval_declarationAtEnd1.js
================================================
a=a.cloneNode(p=[s=5]);cc=a.getContext("2d");e=cc.getImageData(0,0,150,150);d=e.data;t=0;setInterval(function(){if(t%1275<1){cc.fillStyle=n=cc.createRadialGradient(225,75,25,225,75,60);n.addColorStop(x=y=f=0,"rgb("+[50,31+s%15&255,15+s%32&255]);n.addColorStop(1,"#000");cc.fillRect(150,0,150,150);for(;f<256*256;)p[f++]=Math.min(0,3*Math.cos((f&255)/20)-3*Math.cos(f/12800)-s%7+2);for(n=3e5;--n;s*=(256-s)/65)for(x+=[0,1,0,-1][s&3],y+=[0,1,0,-1][3-s&3],t=-6;++t;)for(i=0;++i-6;)p[256*(y+t&255)+(x+i&255)]+=.01}f=Math.cos(++t/200);for(y=-75;++y<75;)for(x=-(u=Math.sqrt(75*75-y*y)&255),q=4*((y+75)*150+75-u);++x<u;){w=Math.sqrt(75*75-y*y-x*x);i=p[((128*Math.atan2(n=y*Math.sin(f)+Math.cos(f)*w,x)+t)/Math.PI&255)+256*(Math.acos((-w*Math.sin(f)+Math.cos(f)*y)/75)*256/Math.PI&255)];n=.1+.008*Math.max(0,n-x);d[q++]=n*(i<0?128-s%128:s%128+s%25*i)&255;d[q++]=n*(i<0?-7*i:75+s%50*i)&255;d[q++]=n*(i<0?s%128:s%75*i)&255;d[q++]=255}cc.putImageData(e,0,0);c.fillStyle="hsl(256,25%,"+Math.max(0,100-t)+"%";c.fillRect(0,0,a.width,a.height);c.save(c.fillStyle="#fff");c.translate(.5*a.width,a.height/2);c.rotate(-.2-.2*Math.cos(Math.max(0,Math.min(t-100,300))*Math.PI/300));c.translate(u=800*Math.cos(Math.max(0,Math.min(t-90,300))*Math.PI/300)-400,500-500*Math.cos(Math.max(0,Math.min(t-1000,300))*Math.PI/300));for(i=0;++i-7500;)c.fillRect(i*i%7525-1500,i%2525-1500,Math.max(i%15/7,t-1200),Math.max(1,t-1100));n=250-75*Math.cos(Math.max(0,Math.min(t-350,300))*Math.PI/300)-150*Math.cos(Math.max(0,Math.min(t-1000,300))*Math.PI/300);c.drawImage(a,0,0,150,150,1200-n,-n,2*n,2*n);n=s|40;c.globalCompositeOperation="lighter";for(i=0;++i-12;)c.drawImage(a,150,0,150,150,-n,-25-n,2*n,2*n);for(i=0;++i-75;)n=25*(i&6),c.drawImage(a,150,0,150,150,-u*i-n,25*i-n,2*n,2*n);c.restore()},33)
================================================
FILE: TestCases/gitHub#19-setInterval_declarationAtEnd2.js
================================================
a=a.cloneNode(p=[s=5]);cc=a.getContext("2d");e=cc.getImageData(0,0,150,150);d=e.data,t=0;setInterval(function(){if(t%1275<1){cc.fillStyle=n=cc.createRadialGradient(225,75,25,225,75,60);n.addColorStop(x=y=f=0,"rgb("+[50,31+s%15&255,15+s%32&255]);n.addColorStop(1,"#000");cc.fillRect(150,0,150,150);for(;f<256*256;)p[f++]=Math.min(0,3*Math.cos((f&255)/20)-3*Math.cos(f/12800)-s%7+2);for(n=3e5;--n;s*=(256-s)/65)for(x+=[0,1,0,-1][s&3],y+=[0,1,0,-1][3-s&3],t=-6;++t;)for(i=0;++i-6;)p[256*(y+t&255)+(x+i&255)]+=.01}f=Math.cos(++t/200);for(y=-75;++y<75;)for(x=-(u=Math.sqrt(75*75-y*y)&255),q=4*((y+75)*150+75-u);++x<u;){w=Math.sqrt(75*75-y*y-x*x);i=p[((128*Math.atan2(n=y*Math.sin(f)+Math.cos(f)*w,x)+t)/Math.PI&255)+256*(Math.acos((-w*Math.sin(f)+Math.cos(f)*y)/75)*256/Math.PI&255)];n=.1+.008*Math.max(0,n-x);d[q++]=n*(i<0?128-s%128:s%128+s%25*i)&255;d[q++]=n*(i<0?-7*i:75+s%50*i)&255;d[q++]=n*(i<0?s%128:s%75*i)&255;d[q++]=255}cc.putImageData(e,0,0);c.fillStyle="hsl(256,25%,"+Math.max(0,100-t)+"%";c.fillRect(0,0,a.width,a.height);c.save(c.fillStyle="#fff");c.translate(.5*a.width,a.height/2);c.rotate(-.2-.2*Math.cos(Math.max(0,Math.min(t-100,300))*Math.PI/300));c.translate(u=800*Math.cos(Math.max(0,Math.min(t-90,300))*Math.PI/300)-400,500-500*Math.cos(Math.max(0,Math.min(t-1000,300))*Math.PI/300));for(i=0;++i-7500;)c.fillRect(i*i%7525-1500,i%2525-1500,Math.max(i%15/7,t-1200),Math.max(1,t-1100));n=250-75*Math.cos(Math.max(0,Math.min(t-350,300))*Math.PI/300)-150*Math.cos(Math.max(0,Math.min(t-1000,300))*Math.PI/300);c.drawImage(a,0,0,150,150,1200-n,-n,2*n,2*n);n=s|40;c.globalCompositeOperation="lighter";for(i=0;++i-12;)c.drawImage(a,150,0,150,150,-n,-25-n,2*n,2*n);for(i=0;++i-75;)n=25*(i&6),c.drawImage(a,150,0,150,150,-u*i-n,25*i-n,2*n,2*n);c.restore()},33)
================================================
FILE: TestCases/gitHub#19-setInterval_declarationChained1.js
================================================
a=a.cloneNode(p=[s=5]);t=u=0;cc=a.getContext("2d");e=cc.getImageData(0,0,150,150);d=e.data;setInterval(function(){if(t%1275<1){cc.fillStyle=n=cc.createRadialGradient(225,75,25,225,75,60);n.addColorStop(x=y=f=0,"rgb("+[50,31+s%15&255,15+s%32&255]);n.addColorStop(1,"#000");cc.fillRect(150,0,150,150);for(;f<256*256;)p[f++]=Math.min(0,3*Math.cos((f&255)/20)-3*Math.cos(f/12800)-s%7+2);for(n=3e5;--n;s*=(256-s)/65)for(x+=[0,1,0,-1][s&3],y+=[0,1,0,-1][3-s&3],t=-6;++t;)for(i=0;++i-6;)p[256*(y+t&255)+(x+i&255)]+=.01}f=Math.cos(++t/200);for(y=-75;++y<75;)for(x=-(u=Math.sqrt(75*75-y*y)&255),q=4*((y+75)*150+75-u);++x<u;){w=Math.sqrt(75*75-y*y-x*x);i=p[((128*Math.atan2(n=y*Math.sin(f)+Math.cos(f)*w,x)+t)/Math.PI&255)+256*(Math.acos((-w*Math.sin(f)+Math.cos(f)*y)/75)*256/Math.PI&255)];n=.1+.008*Math.max(0,n-x);d[q++]=n*(i<0?128-s%128:s%128+s%25*i)&255;d[q++]=n*(i<0?-7*i:75+s%50*i)&255;d[q++]=n*(i<0?s%128:s%75*i)&255;d[q++]=255}cc.putImageData(e,0,0);c.fillStyle="hsl(256,25%,"+Math.max(0,100-t)+"%";c.fillRect(0,0,a.width,a.height);c.save(c.fillStyle="#fff");c.translate(.5*a.width,a.height/2);c.rotate(-.2-.2*Math.cos(Math.max(0,Math.min(t-100,300))*Math.PI/300));c.translate(u=800*Math.cos(Math.max(0,Math.min(t-90,300))*Math.PI/300)-400,500-500*Math.cos(Math.max(0,Math.min(t-1000,300))*Math.PI/300));for(i=0;++i-7500;)c.fillRect(i*i%7525-1500,i%2525-1500,Math.max(i%15/7,t-1200),Math.max(1,t-1100));n=250-75*Math.cos(Math.max(0,Math.min(t-350,300))*Math.PI/300)-150*Math.cos(Math.max(0,Math.min(t-1000,300))*Math.PI/300);c.drawImage(a,0,0,150,150,1200-n,-n,2*n,2*n);n=s|40;c.globalCompositeOperation="lighter";for(i=0;++i-12;)c.drawImage(a,150,0,150,150,-n,-25-n,2*n,2*n);for(i=0;++i-75;)n=25*(i&6),c.drawImage(a,150,0,150,150,-u*i-n,25*i-n,2*n,2*n);c.restore()},33)
================================================
FILE: TestCases/gitHub#19-setInterval_declarationChained2.js
================================================
a=a.cloneNode(p=[s=5]);u=t=0;cc=a.getContext("2d");e=cc.getImageData(0,0,150,150);d=e.data;setInterval(function(){if(t%1275<1){cc.fillStyle=n=cc.createRadialGradient(225,75,25,225,75,60);n.addColorStop(x=y=f=0,"rgb("+[50,31+s%15&255,15+s%32&255]);n.addColorStop(1,"#000");cc.fillRect(150,0,150,150);for(;f<256*256;)p[f++]=Math.min(0,3*Math.cos((f&255)/20)-3*Math.cos(f/12800)-s%7+2);for(n=3e5;--n;s*=(256-s)/65)for(x+=[0,1,0,-1][s&3],y+=[0,1,0,-1][3-s&3],t=-6;++t;)for(i=0;++i-6;)p[256*(y+t&255)+(x+i&255)]+=.01}f=Math.cos(++t/200);for(y=-75;++y<75;)for(x=-(u=Math.sqrt(75*75-y*y)&255),q=4*((y+75)*150+75-u);++x<u;){w=Math.sqrt(75*75-y*y-x*x);i=p[((128*Math.atan2(n=y*Math.sin(f)+Math.cos(f)*w,x)+t)/Math.PI&255)+256*(Math.acos((-w*Math.sin(f)+Math.cos(f)*y)/75)*256/Math.PI&255)];n=.1+.008*Math.max(0,n-x);d[q++]=n*(i<0?128-s%128:s%128+s%25*i)&255;d[q++]=n*(i<0?-7*i:75+s%50*i)&255;d[q++]=n*(i<0?s%128:s%75*i)&255;d[q++]=255}cc.putImageData(e,0,0);c.fillStyle="hsl(256,25%,"+Math.max(0,100-t)+"%";c.fillRect(0,0,a.width,a.height);c.save(c.fillStyle="#fff");c.translate(.5*a.width,a.height/2);c.rotate(-.2-.2*Math.cos(Math.max(0,Math.min(t-100,300))*Math.PI/300));c.translate(u=800*Math.cos(Math.max(0,Math.min(t-90,300))*Math.PI/300)-400,500-500*Math.cos(Math.max(0,Math.min(t-1000,300))*Math.PI/300));for(i=0;++i-7500;)c.fillRect(i*i%7525-1500,i%2525-1500,Math.max(i%15/7,t-1200),Math.max(1,t-1100));n=250-75*Math.cos(Math.max(0,Math.min(t-350,300))*Math.PI/300)-150*Math.cos(Math.max(0,Math.min(t-1000,300))*Math.PI/300);c.drawImage(a,0,0,150,150,1200-n,-n,2*n,2*n);n=s|40;c.globalCompositeOperation="lighter";for(i=0;++i-12;)c.drawImage(a,150,0,150,150,-n,-25-n,2*n,2*n);for(i=0;++i-75;)n=25*(i&6),c.drawImage(a,150,0,150,150,-u*i-n,25*i-n,2*n,2*n);c.restore()},33)
================================================
FILE: TestCases/gitHub#19-setInterval_declarationInArray1.js
================================================
a=a.cloneNode(p=[t=0,s=5]);cc=a.getContext("2d");e=cc.getImageData(0,0,150,150);d=e.data;setInterval(function(){if(t%1275<1){cc.fillStyle=n=cc.createRadialGradient(225,75,25,225,75,60);n.addColorStop(x=y=f=0,"rgb("+[50,31+s%15&255,15+s%32&255]);n.addColorStop(1,"#000");cc.fillRect(150,0,150,150);for(;f<256*256;)p[f++]=Math.min(0,3*Math.cos((f&255)/20)-3*Math.cos(f/12800)-s%7+2);for(n=3e5;--n;s*=(256-s)/65)for(x+=[0,1,0,-1][s&3],y+=[0,1,0,-1][3-s&3],t=-6;++t;)for(i=0;++i-6;)p[256*(y+t&255)+(x+i&255)]+=.01}f=Math.cos(++t/200);for(y=-75;++y<75;)for(x=-(u=Math.sqrt(75*75-y*y)&255),q=4*((y+75)*150+75-u);++x<u;){w=Math.sqrt(75*75-y*y-x*x);i=p[((128*Math.atan2(n=y*Math.sin(f)+Math.cos(f)*w,x)+t)/Math.PI&255)+256*(Math.acos((-w*Math.sin(f)+Math.cos(f)*y)/75)*256/Math.PI&255)];n=.1+.008*Math.max(0,n-x);d[q++]=n*(i<0?128-s%128:s%128+s%25*i)&255;d[q++]=n*(i<0?-7*i:75+s%50*i)&255;d[q++]=n*(i<0?s%128:s%75*i)&255;d[q++]=255}cc.putImageData(e,0,0);c.fillStyle="hsl(256,25%,"+Math.max(0,100-t)+"%";c.fillRect(0,0,a.width,a.height);c.save(c.fillStyle="#fff");c.translate(.5*a.width,a.height/2);c.rotate(-.2-.2*Math.cos(Math.max(0,Math.min(t-100,300))*Math.PI/300));c.translate(u=800*Math.cos(Math.max(0,Math.min(t-90,300))*Math.PI/300)-400,500-500*Math.cos(Math.max(0,Math.min(t-1000,300))*Math.PI/300));for(i=0;++i-7500;)c.fillRect(i*i%7525-1500,i%2525-1500,Math.max(i%15/7,t-1200),Math.max(1,t-1100));n=250-75*Math.cos(Math.max(0,Math.min(t-350,300))*Math.PI/300)-150*Math.cos(Math.max(0,Math.min(t-1000,300))*Math.PI/300);c.drawImage(a,0,0,150,150,1200-n,-n,2*n,2*n);n=s|40;c.globalCompositeOperation="lighter";for(i=0;++i-12;)c.drawImage(a,150,0,150,150,-n,-25-n,2*n,2*n);for(i=0;++i-75;)n=25*(i&6),c.drawImage(a,150,0,150,150,-u*i-n,25*i-n,2*n,2*n);c.restore()},33)
================================================
FILE: TestCases/gitHub#19-setInterval_declarationInArray2.js
================================================
a=a.cloneNode(p=[s=5,t=0]);cc=a.getContext("2d");e=cc.getImageData(0,0,150,150);d=e.data;setInterval(function(){if(t%1275<1){cc.fillStyle=n=cc.createRadialGradient(225,75,25,225,75,60);n.addColorStop(x=y=f=0,"rgb("+[50,31+s%15&255,15+s%32&255]);n.addColorStop(1,"#000");cc.fillRect(150,0,150,150);for(;f<256*256;)p[f++]=Math.min(0,3*Math.cos((f&255)/20)-3*Math.cos(f/12800)-s%7+2);for(n=3e5;--n;s*=(256-s)/65)for(x+=[0,1,0,-1][s&3],y+=[0,1,0,-1][3-s&3],t=-6;++t;)for(i=0;++i-6;)p[256*(y+t&255)+(x+i&255)]+=.01}f=Math.cos(++t/200);for(y=-75;++y<75;)for(x=-(u=Math.sqrt(75*75-y*y)&255),q=4*((y+75)*150+75-u);++x<u;){w=Math.sqrt(75*75-y*y-x*x);i=p[((128*Math.atan2(n=y*Math.sin(f)+Math.cos(f)*w,x)+t)/Math.PI&255)+256*(Math.acos((-w*Math.sin(f)+Math.cos(f)*y)/75)*256/Math.PI&255)];n=.1+.008*Math.max(0,n-x);d[q++]=n*(i<0?128-s%128:s%128+s%25*i)&255;d[q++]=n*(i<0?-7*i:75+s%50*i)&255;d[q++]=n*(i<0?s%128:s%75*i)&255;d[q++]=255}cc.putImageData(e,0,0);c.fillStyle="hsl(256,25%,"+Math.max(0,100-t)+"%";c.fillRect(0,0,a.width,a.height);c.save(c.fillStyle="#fff");c.translate(.5*a.width,a.height/2);c.rotate(-.2-.2*Math.cos(Math.max(0,Math.min(t-100,300))*Math.PI/300));c.translate(u=800*Math.cos(Math.max(0,Math.min(t-90,300))*Math.PI/300)-400,500-500*Math.cos(Math.max(0,Math.min(t-1000,300))*Math.PI/300));for(i=0;++i-7500;)c.fillRect(i*i%7525-1500,i%2525-1500,Math.max(i%15/7,t-1200),Math.max(1,t-1100));n=250-75*Math.cos(Math.max(0,Math.min(t-350,300))*Math.PI/300)-150*Math.cos(Math.max(0,Math.min(t-1000,300))*Math.PI/300);c.drawImage(a,0,0,150,150,1200-n,-n,2*n,2*n);n=s|40;c.globalCompositeOperation="lighter";for(i=0;++i-12;)c.drawImage(a,150,0,150,150,-n,-25-n,2*n,2*n);for(i=0;++i-75;)n=25*(i&6),c.drawImage(a,150,0,150,150,-u*i-n,25*i-n,2*n,2*n);c.restore()},33)
================================================
FILE: TestCases/gitHub#19-setInterval_declarationInFunction1.js
================================================
a=a.cloneNode(p=[s=5]);cc=a.getContext("2d");e=cc.getImageData(t=0,0,150,150);d=e.data;setInterval(function(){if(t%1275<1){cc.fillStyle=n=cc.createRadialGradient(225,75,25,225,75,60);n.addColorStop(x=y=f=0,"rgb("+[50,31+s%15&255,15+s%32&255]);n.addColorStop(1,"#000");cc.fillRect(150,0,150,150);for(;f<256*256;)p[f++]=Math.min(0,3*Math.cos((f&255)/20)-3*Math.cos(f/12800)-s%7+2);for(n=3e5;--n;s*=(256-s)/65)for(x+=[0,1,0,-1][s&3],y+=[0,1,0,-1][3-s&3],t=-6;++t;)for(i=0;++i-6;)p[256*(y+t&255)+(x+i&255)]+=.01}f=Math.cos(++t/200);for(y=-75;++y<75;)for(x=-(u=Math.sqrt(75*75-y*y)&255),q=4*((y+75)*150+75-u);++x<u;){w=Math.sqrt(75*75-y*y-x*x);i=p[((128*Math.atan2(n=y*Math.sin(f)+Math.cos(f)*w,x)+t)/Math.PI&255)+256*(Math.acos((-w*Math.sin(f)+Math.cos(f)*y)/75)*256/Math.PI&255)];n=.1+.008*Math.max(0,n-x);d[q++]=n*(i<0?128-s%128:s%128+s%25*i)&255;d[q++]=n*(i<0?-7*i:75+s%50*i)&255;d[q++]=n*(i<0?s%128:s%75*i)&255;d[q++]=255}cc.putImageData(e,0,0);c.fillStyle="hsl(256,25%,"+Math.max(0,100-t)+"%";c.fillRect(0,0,a.width,a.height);c.save(c.fillStyle="#fff");c.translate(.5*a.width,a.height/2);c.rotate(-.2-.2*Math.cos(Math.max(0,Math.min(t-100,300))*Math.PI/300));c.translate(u=800*Math.cos(Math.max(0,Math.min(t-90,300))*Math.PI/300)-400,500-500*Math.cos(Math.max(0,Math.min(t-1000,300))*Math.PI/300));for(i=0;++i-7500;)c.fillRect(i*i%7525-1500,i%2525-1500,Math.max(i%15/7,t-1200),Math.max(1,t-1100));n=250-75*Math.cos(Math.max(0,Math.min(t-350,300))*Math.PI/300)-150*Math.cos(Math.max(0,Math.min(t-1000,300))*Math.PI/300);c.drawImage(a,0,0,150,150,1200-n,-n,2*n,2*n);n=s|40;c.globalCompositeOperation="lighter";for(i=0;++i-12;)c.drawImage(a,150,0,150,150,-n,-25-n,2*n,2*n);for(i=0;++i-75;)n=25*(i&6),c.drawImage(a,150,0,150,150,-u*i-n,25*i-n,2*n,2*n);c.restore()},33)
================================================
FILE: TestCases/gitHub#19-setInterval_declarationInFunction2.js
================================================
a=a.cloneNode(p=[s=5]);cc=a.getContext("2d");e=cc.getImageData(0,t=0,150,150);d=e.data;setInterval(function(){if(t%1275<1){cc.fillStyle=n=cc.createRadialGradient(225,75,25,225,75,60);n.addColorStop(x=y=f=0,"rgb("+[50,31+s%15&255,15+s%32&255]);n.addColorStop(1,"#000");cc.fillRect(150,0,150,150);for(;f<256*256;)p[f++]=Math.min(0,3*Math.cos((f&255)/20)-3*Math.cos(f/12800)-s%7+2);for(n=3e5;--n;s*=(256-s)/65)for(x+=[0,1,0,-1][s&3],y+=[0,1,0,-1][3-s&3],t=-6;++t;)for(i=0;++i-6;)p[256*(y+t&255)+(x+i&255)]+=.01}f=Math.cos(++t/200);for(y=-75;++y<75;)for(x=-(u=Math.sqrt(75*75-y*y)&255),q=4*((y+75)*150+75-u);++x<u;){w=Math.sqrt(75*75-y*y-x*x);i=p[((128*Math.atan2(n=y*Math.sin(f)+Math.cos(f)*w,x)+t)/Math.PI&255)+256*(Math.acos((-w*Math.sin(f)+Math.cos(f)*y)/75)*256/Math.PI&255)];n=.1+.008*Math.max(0,n-x);d[q++]=n*(i<0?128-s%128:s%128+s%25*i)&255;d[q++]=n*(i<0?-7*i:75+s%50*i)&255;d[q++]=n*(i<0?s%128:s%75*i)&255;d[q++]=255}cc.putImageData(e,0,0);c.fillStyle="hsl(256,25%,"+Math.max(0,100-t)+"%";c.fillRect(0,0,a.width,a.height);c.save(c.fillStyle="#fff");c.translate(.5*a.width,a.height/2);c.rotate(-.2-.2*Math.cos(Math.max(0,Math.min(t-100,300))*Math.PI/300));c.translate(u=800*Math.cos(Math.max(0,Math.min(t-90,300))*Math.PI/300)-400,500-500*Math.cos(Math.max(0,Math.min(t-1000,300))*Math.PI/300));for(i=0;++i-7500;)c.fillRect(i*i%7525-1500,i%2525-1500,Math.max(i%15/7,t-1200),Math.max(1,t-1100));n=250-75*Math.cos(Math.max(0,Math.min(t-350,300))*Math.PI/300)-150*Math.cos(Math.max(0,Math.min(t-1000,300))*Math.PI/300);c.drawImage(a,0,0,150,150,1200-n,-n,2*n,2*n);n=s|40;c.globalCompositeOperation="lighter";for(i=0;++i-12;)c.drawImage(a,150,0,150,150,-n,-25-n,2*n,2*n);for(i=0;++i-75;)n=25*(i&6),c.drawImage(a,150,0,150,150,-u*i-n,25*i-n,2*n,2*n);c.restore()},33)
================================================
FILE: TestCases/gitHub#19-setInterval_declarationInFunction3.js
================================================
a=a.cloneNode(p=[s=5]);cc=a.getContext("2d");e=cc.getImageData(0,0,150,t=0);d=e.data;setInterval(function(){if(t%1275<1){cc.fillStyle=n=cc.createRadialGradient(225,75,25,225,75,60);n.addColorStop(x=y=f=0,"rgb("+[50,31+s%15&255,15+s%32&255]);n.addColorStop(1,"#000");cc.fillRect(150,0,150,150);for(;f<256*256;)p[f++]=Math.min(0,3*Math.cos((f&255)/20)-3*Math.cos(f/12800)-s%7+2);for(n=3e5;--n;s*=(256-s)/65)for(x+=[0,1,0,-1][s&3],y+=[0,1,0,-1][3-s&3],t=-6;++t;)for(i=0;++i-6;)p[256*(y+t&255)+(x+i&255)]+=.01}f=Math.cos(++t/200);for(y=-75;++y<75;)for(x=-(u=Math.sqrt(75*75-y*y)&255),q=4*((y+75)*150+75-u);++x<u;){w=Math.sqrt(75*75-y*y-x*x);i=p[((128*Math.atan2(n=y*Math.sin(f)+Math.cos(f)*w,x)+t)/Math.PI&255)+256*(Math.acos((-w*Math.sin(f)+Math.cos(f)*y)/75)*256/Math.PI&255)];n=.1+.008*Math.max(0,n-x);d[q++]=n*(i<0?128-s%128:s%128+s%25*i)&255;d[q++]=n*(i<0?-7*i:75+s%50*i)&255;d[q++]=n*(i<0?s%128:s%75*i)&255;d[q++]=255}cc.putImageData(e,0,0);c.fillStyle="hsl(256,25%,"+Math.max(0,100-t)+"%";c.fillRect(0,0,a.width,a.height);c.save(c.fillStyle="#fff");c.translate(.5*a.width,a.height/2);c.rotate(-.2-.2*Math.cos(Math.max(0,Math.min(t-100,300))*Math.PI/300));c.translate(u=800*Math.cos(Math.max(0,Math.min(t-90,300))*Math.PI/300)-400,500-500*Math.cos(Math.max(0,Math.min(t-1000,300))*Math.PI/300));for(i=0;++i-7500;)c.fillRect(i*i%7525-1500,i%2525-1500,Math.max(i%15/7,t-1200),Math.max(1,t-1100));n=250-75*Math.cos(Math.max(0,Math.min(t-350,300))*Math.PI/300)-150*Math.cos(Math.max(0,Math.min(t-1000,300))*Math.PI/300);c.drawImage(a,0,0,150,150,1200-n,-n,2*n,2*n);n=s|40;c.globalCompositeOperation="lighter";for(i=0;++i-12;)c.drawImage(a,150,0,150,150,-n,-25-n,2*n,2*n);for(i=0;++i-75;)n=25*(i&6),c.drawImage(a,150,0,150,150,-u*i-n,25*i-n,2*n,2*n);c.restore()},33)
================================================
FILE: TestCases/gitHub#2-unicode.js
================================================
b.innerHTML="<center><p onclick=g(1,3,3,f=1)>XnO<p onclick=g(3,3,3,f=1)>XnO3D<p onclick=g(1,6,7,f=2)>Find4<p onclick=g(1,8,8,f=0)>Reversi<p id=B><p id=C>";g=function(l,h,n){c=e=1;i=0;d=[];f||(d[27]=d[36]=-1,d[28]=d[35]=1);for(B.innerHTML="";l--;){a="<p><table border>";for(j=h;j--;)for(a+="<tr>",k=n;k--;)d[i]=d[i]||0,a+="<th width=20 onclick=m(this,"+i+") id=t"+i+">"+"X\xa0O"[d[i++]+1];B.innerHTML+=a}C.innerHTML="O"}; m=function(l,h){if(e&&!d[h]){if(1==f)for(l.innerHTML="XnO"[c+1],a=3*(d[h]=c),i=3;i--;)for(j=3;j--;){if(d[9*i+j]+d[9*i+j+3]+d[9*i+j+6]==a||d[9*i+3*j]+d[9*i+3*j+1]+d[9*i+3*j+2]==a||d[9*i+0]+d[9*i+4]+d[9*i+8]==a||d[9*i+2]+d[9*i+4]+d[9*i+6]==a||d[3*i]+d[3*i+10]+d[3*i+20]==a||d[3*i+2]+d[3*i+10]+d[18+3*i]==a||d[i]+d[9+i+3]+d[18+i+6]==a||d[i+6]+d[9+i+3]+d[18+i]==a||d[0]+d[13]+d[26]==a||d[2]+d[13]+d[24]==a||d[8]+d[13]+d[18]==a||d[6]+d[13]+d[20]==a||d[3*i+j]+d[9+3*i+j]+d[18+3*i+j]==a){C.innerHTML="XnO"[c+ 1]+"✌";e=0;return}}else if(2==f&&34<h||d[h+7])for(l.innerHTML="XnO"[c+1],a=4*(d[h]=c),i=6;i--;)for(j=7;j--;)if(4>j&&d[7*i+j]+d[7*i+j+1]+d[7*i+j+2]+d[7*i+j+3]==a||3>i&&d[7*i+j]+d[7*i+j+7]+d[7*i+j+14]+d[7*i+j+21]==a||3>i&&4>j&&d[7*i+j]+d[7*i+j+8]+d[7*i+j+16]+d[7*i+j+24]==a||3>i&&2<j&&d[7*i+j]+d[7*i+j+6]+d[7*i+j+12]+d[7*i+j+18]==a){C.innerHTML="XnO"[c+1]+"✌";e=0;return}c=-c;C.innerHTML="XnO"[c+1];-1==d.indexOf(0)&&(C.innerHTML="=",e=0)}};
================================================
FILE: TestCases/gitHub#30-webglContext_create_charset.js
================================================
gl=canvas.getContext("webgl", { antialias: !0, stencil: !0 })||canvas.getContext("experimental-webgl", { antialias: !0, stencil: !0 });
gl.clearColor(0.0, 0.0, 0.0, 1.0);
gl.clearDepth(1.0);
gl.enable(gl.DEPTH_TEST);
gl.depthFunc(gl.LEQUAL);
gl.bindBuffer(gl.ARRAY_BUFFER, b = gl.createBuffer());
================================================
FILE: TestCases/gitHub#31-direct-hyphenBeginsBlock.js
================================================
! !'#$%&'()*+,
123456789:;<=>?@
ABCDEFGHIJKLMNOPQRSTUVWXYZ
[\]^_`abcdefghijklmnopqrstuvwxyz
{|}~
abcdabcdabcd
efghefghefgh
ijklijklijkl
mnopmnopmnop
qrstqrstqrst
================================================
FILE: TestCases/gitHub#31-direct-hyphenEndsBlock.js
================================================
!'#$%&'()
./0123456789:;<=>?@
ABCDEFGHIJKLMNOPQRSTUVWXYZ
[\]^_`abcdefghijklmnopqrstuvwxyz
{|}~
abcdabcdabcd
efghefghefgh
ijklijklijkl
mnopmnopmnop
qrstqrstqrst
================================================
FILE: TestCases/gitHub#31-direct-singleHyphen.js
================================================
!'#$%&'()*+,
./012345678:;<=>?@
ABCDEFGHIJKLMNOPQRSTUVWXYZ
[\]^_`abcdefghijklmnopqrstuvwx
{|}~
abcdabcdabcd
efghefghefgh
ijklijklijkl
mnopmnopmnop
qrstqrstqrst
================================================
FILE: TestCases/gitHub#31-negated-hyphenBeginsBlock.js
================================================
-
abcdabcdabcd
efghefghefgh
ijklijklijkl
mnopmnopmnop
qrstqrstqrst
uvwxyz
================================================
FILE: TestCases/gitHub#31-negated-hyphenEndsBlock.js
================================================
-
!"#$%&'()*+,!"#$%&'()*+,!"#$%&'()*+,!"#$%&'()*+,
================================================
FILE: TestCases/gitHub#31-negated-singleHyphen.js
================================================
-
$%&'$%&'$%&'$%&'$%&'$%&'$%&'$%&'
#()+#()+#()+#()+#()+#()+#()+#()+
012345678901234567890123456789
:!<=>?@
ABCDEFGHIJKLMNOPQRSTUVXWYZABCDEFGHIJKLMNOPQRSTUVXWYZ
[\]^_`
abcdefghijklmnopqrstuvwxyz
{|}~
================================================
FILE: TestCases/gitHub#44-setInterval_arrowFunctionMultiParam.js
================================================
t=0;a=a.cloneNode(p=[s=5]);cc=a.getContext("2d");e=cc.getImageData(0,0,150,150);d=e.data;setInterval((x,y,z)=>{if(t%1275<1){cc.fillStyle=n=cc.createRadialGradient(225,75,25,225,75,60);n.addColorStop(x=y=f=0,"rgb("+[50,31+s%15&255,15+s%32&255]);n.addColorStop(1,"#000");cc.fillRect(150,0,150,150);for(;f<256*256;)p[f++]=Math.min(0,3*Math.cos((f&255)/20)-3*Math.cos(f/12800)-s%7+2);for(n=3e5;--n;s*=(256-s)/65)for(x+=[0,1,0,-1][s&3],y+=[0,1,0,-1][3-s&3],t=-6;++t;)for(i=0;++i-6;)p[256*(y+t&255)+(x+i&255)]+=.01}f=Math.cos(++t/200);for(y=-75;++y<75;)for(x=-(u=Math.sqrt(75*75-y*y)&255),q=4*((y+75)*150+75-u);++x<u;){w=Math.sqrt(75*75-y*y-x*x);i=p[((128*Math.atan2(n=y*Math.sin(f)+Math.cos(f)*w,x)+t)/Math.PI&255)+256*(Math.acos((-w*Math.sin(f)+Math.cos(f)*y)/75)*256/Math.PI&255)];n=.1+.008*Math.max(0,n-x);d[q++]=n*(i<0?128-s%128:s%128+s%25*i)&255;d[q++]=n*(i<0?-7*i:75+s%50*i)&255;d[q++]=n*(i<0?s%128:s%75*i)&255;d[q++]=255}cc.putImageData(e,0,0);c.fillStyle="hsl(256,25%,"+Math.max(0,100-t)+"%";c.fillRect(0,0,a.width,a.height);c.save(c.fillStyle="#fff");c.translate(.5*a.width,a.height/2);c.rotate(-.2-.2*Math.cos(Math.max(0,Math.min(t-100,300))*Math.PI/300));c.translate(u=800*Math.cos(Math.max(0,Math.min(t-90,300))*Math.PI/300)-400,500-500*Math.cos(Math.max(0,Math.min(t-1000,300))*Math.PI/300));for(i=0;++i-7500;)c.fillRect(i*i%7525-1500,i%2525-1500,Math.max(i%15/7,t-1200),Math.max(1,t-1100));n=250-75*Math.cos(Math.max(0,Math.min(t-350,300))*Math.PI/300)-150*Math.cos(Math.max(0,Math.min(t-1000,300))*Math.PI/300);c.drawImage(a,0,0,150,150,1200-n,-n,2*n,2*n);n=s|40;c.globalCompositeOperation="lighter";for(i=0;++i-12;)c.drawImage(a,150,0,150,150,-n,-25-n,2*n,2*n);for(i=0;++i-75;)n=25*(i&6),c.drawImage(a,150,0,150,150,-u*i-n,25*i-n,2*n,2*n);c.restore()},33)
================================================
FILE: TestCases/gitHub#44-setInterval_arrowFunctionNoParam.js
================================================
t=0;a=a.cloneNode(p=[s=5]);cc=a.getContext("2d");e=cc.getImageData(0,0,150,150);d=e.data;setInterval(()=>{if(t%1275<1){cc.fillStyle=n=cc.createRadialGradient(225,75,25,225,75,60);n.addColorStop(x=y=f=0,"rgb("+[50,31+s%15&255,15+s%32&255]);n.addColorStop(1,"#000");cc.fillRect(150,0,150,150);for(;f<256*256;)p[f++]=Math.min(0,3*Math.cos((f&255)/20)-3*Math.cos(f/12800)-s%7+2);for(n=3e5;--n;s*=(256-s)/65)for(x+=[0,1,0,-1][s&3],y+=[0,1,0,-1][3-s&3],t=-6;++t;)for(i=0;++i-6;)p[256*(y+t&255)+(x+i&255)]+=.01}f=Math.cos(++t/200);for(y=-75;++y<75;)for(x=-(u=Math.sqrt(75*75-y*y)&255),q=4*((y+75)*150+75-u);++x<u;){w=Math.sqrt(75*75-y*y-x*x);i=p[((128*Math.atan2(n=y*Math.sin(f)+Math.cos(f)*w,x)+t)/Math.PI&255)+256*(Math.acos((-w*Math.sin(f)+Math.cos(f)*y)/75)*256/Math.PI&255)];n=.1+.008*Math.max(0,n-x);d[q++]=n*(i<0?128-s%128:s%128+s%25*i)&255;d[q++]=n*(i<0?-7*i:75+s%50*i)&255;d[q++]=n*(i<0?s%128:s%75*i)&255;d[q++]=255}cc.putImageData(e,0,0);c.fillStyle="hsl(256,25%,"+Math.max(0,100-t)+"%";c.fillRect(0,0,a.width,a.height);c.save(c.fillStyle="#fff");c.translate(.5*a.width,a.height/2);c.rotate(-.2-.2*Math.cos(Math.max(0,Math.min(t-100,300))*Math.PI/300));c.translate(u=800*Math.cos(Math.max(0,Math.min(t-90,300))*Math.PI/300)-400,500-500*Math.cos(Math.max(0,Math.min(t-1000,300))*Math.PI/300));for(i=0;++i-7500;)c.fillRect(i*i%7525-1500,i%2525-1500,Math.max(i%15/7,t-1200),Math.max(1,t-1100));n=250-75*Math.cos(Math.max(0,Math.min(t-350,300))*Math.PI/300)-150*Math.cos(Math.max(0,Math.min(t-1000,300))*Math.PI/300);c.drawImage(a,0,0,150,150,1200-n,-n,2*n,2*n);n=s|40;c.globalCompositeOperation="lighter";for(i=0;++i-12;)c.drawImage(a,150,0,150,150,-n,-25-n,2*n,2*n);for(i=0;++i-75;)n=25*(i&6),c.drawImage(a,150,0,150,150,-u*i-n,25*i-n,2*n,2*n);c.restore()},33)
================================================
FILE: TestCases/gitHub#44-setInterval_arrowFunctionSingleParam.js
================================================
t=0;a=a.cloneNode(p=[s=5]);cc=a.getContext("2d");e=cc.getImageData(0,0,150,150);d=e.data;setInterval(x=>{if(t%1275<1){cc.fillStyle=n=cc.createRadialGradient(225,75,25,225,75,60);n.addColorStop(x=y=f=0,"rgb("+[50,31+s%15&255,15+s%32&255]);n.addColorStop(1,"#000");cc.fillRect(150,0,150,150);for(;f<256*256;)p[f++]=Math.min(0,3*Math.cos((f&255)/20)-3*Math.cos(f/12800)-s%7+2);for(n=3e5;--n;s*=(256-s)/65)for(x+=[0,1,0,-1][s&3],y+=[0,1,0,-1][3-s&3],t=-6;++t;)for(i=0;++i-6;)p[256*(y+t&255)+(x+i&255)]+=.01}f=Math.cos(++t/200);for(y=-75;++y<75;)for(x=-(u=Math.sqrt(75*75-y*y)&255),q=4*((y+75)*150+75-u);++x<u;){w=Math.sqrt(75*75-y*y-x*x);i=p[((128*Math.atan2(n=y*Math.sin(f)+Math.cos(f)*w,x)+t)/Math.PI&255)+256*(Math.acos((-w*Math.sin(f)+Math.cos(f)*y)/75)*256/Math.PI&255)];n=.1+.008*Math.max(0,n-x);d[q++]=n*(i<0?128-s%128:s%128+s%25*i)&255;d[q++]=n*(i<0?-7*i:75+s%50*i)&255;d[q++]=n*(i<0?s%128:s%75*i)&255;d[q++]=255}cc.putImageData(e,0,0);c.fillStyle="hsl(256,25%,"+Math.max(0,100-t)+"%";c.fillRect(0,0,a.width,a.height);c.save(c.fillStyle="#fff");c.translate(.5*a.width,a.height/2);c.rotate(-.2-.2*Math.cos(Math.max(0,Math.min(t-100,300))*Math.PI/300));c.translate(u=800*Math.cos(Math.max(0,Math.min(t-90,300))*Math.PI/300)-400,500-500*Math.cos(Math.max(0,Math.min(t-1000,300))*Math.PI/300));for(i=0;++i-7500;)c.fillRect(i*i%7525-1500,i%2525-1500,Math.max(i%15/7,t-1200),Math.max(1,t-1100));n=250-75*Math.cos(Math.max(0,Math.min(t-350,300))*Math.PI/300)-150*Math.cos(Math.max(0,Math.min(t-1000,300))*Math.PI/300);c.drawImage(a,0,0,150,150,1200-n,-n,2*n,2*n);n=s|40;c.globalCompositeOperation="lighter";for(i=0;++i-12;)c.drawImage(a,150,0,150,150,-n,-25-n,2*n,2*n);for(i=0;++i-75;)n=25*(i&6),c.drawImage(a,150,0,150,150,-u*i-n,25*i-n,2*n,2*n);c.restore()},33)
================================================
FILE: TestCases/gitHub#47-packer_from92AndReplace.js
================================================
! !'#$%&'()*+,-./
456789:;<=>?@
ABCDEFGHIJKLMNOPQRSTUVWXYZ
[abcdefghijklmnopqrstuvwxyz
{|}~
abcdabcdabcd
efghefghefgh
ijklijklijkl
mnopmnopmnop
qrstqrstqrst
cdlzcdlzcdlz
k,grk,grk,gr
================================================
FILE: TestCases/gitHub#47-packer_from92NoReplace.js
================================================
' '
'! !#$%&'()*+,-./
0123456789:;<=>?@
ABCDEFGHIJKLMNOPQRSTUVWXYZ
[abcdefghijklmnopqrstuvwxyz
{|}~
abcdabcdabcd
efghefghefgh
ijklijklijkl
mnopmnopmnop
qrstqrstqrst
cdlzcdlzcdlz
k,grk,grk,gr
================================================
FILE: TestCases/gitHub#47-packer_from92ReplaceFails.js
================================================
! !'#$%&'()*+,-./
3456789:;<=>?@
ABCDEFGHIJKLMNOPQRSTUVWXYZ
[abcdefghijklmnopqrstuvwxyz
{|}~
abcdabcdabcd
efghefghefgh
ijklijklijkl
mnopmnopmnop
qrstqrstqrst
cdlzcdlzcdlz
k,grk,grk,gr
================================================
FILE: TestCases/gitHub#47-packer_from93AndReplace.js
================================================
! !'#$%&'()*+,-./
3456789:;<=>?@
ABCDEFGHIJKLMNOPQRSTUVWXYZ
[\bcdefghijklmnopqrstuvwxyz
{|}~
uvwxuvwxuvwx
efghefghefgh
ijklijklijkl
mnopmnopmnop
qrstqrstqrst
cdlzcdlzcdlz
k,grk,grk,gr
================================================
FILE: TestCases/gitHub#47-packer_from93NoReplace.js
================================================
' '
'! !#$%&'()*+,-./
0123456789:;<=>?@
ABCDEFGHIJKLMNOPQRSTUVWXYZ
[\abcdefghijklmnopqrstuvwxyz
{|}~
abcdabcdabcd
efghefghefgh
ijklijklijkl
mnopmnopmnop
qrstqrstqrst
cdlzcdlzcdlz
k,grk,grk,gr
================================================
FILE: TestCases/gitHub#47-packer_rangesBeyond.js
================================================
! !'#$%&'()*+,-./
0123456789:;<=>?
AFGHIJKQRSTUVWXYZ
[\]^_`abcdefghijklmnopqrstuvwxyz`
{|}
abcdabcdabcd
efghefghefgh
ijklijklijkl
mnopmnopmnop
qrstqrstqrst
cdlzcdlzcdlz
k,grk,grk,gr
================================================
FILE: TestCases/gitHub#47-packer_to92AndReplace.js
================================================
' '
'! !#$%&'()*+,-./
3456789:;<=>?@
ABCDEFGHIJKLMNOPQRSTUVW
]^_`abcdefghijklmnopqrstuvwxyz
{|}~
abcdabcdabcd
efghefghefgh
ijklijklijkl
mnopmnopmnop
qrstqrstqrst
cdlzcdlzcdlz
k,grk,grk,gr
================================================
FILE: TestCases/gitHub#47-packer_to92NoReplace.js
================================================
' '
'! !#$%&'()*+,-./
0123456789:;<=>?@
ABCDEFGHIJKLMNOPQRSTUVWX
]^_`abcdefghijklmnopqrstuvwxyz`
{|}~
abcdabcdabcd
efghefghefgh
ijklijklijkl
mnopmnopmnop
qrstqrstqrst
cdlzcdlzcdlz
k,grk,grk,gr
================================================
FILE: TestCases/gitHub#47-packer_to93AndReplace.js
================================================
' '
'! !#$%&'()*+,-./
3456789:;<=>?@
ABCDEFGHIJKLMNOPQRSTUVW
^_`abcdefghijklmnopqrstuvwxyz`
{|}~
abcdabcdabcd
efghefghefgh
ijklijklijkl
mnopmnopmnop
qrstqrstqrst
cdlzcdlzcdlz
k,grk,grk,gr
================================================
FILE: TestCases/gitHub#47-packer_to93NoReplace.js
================================================
' '
'! !#$%&'()*+,-./
0123456789:;<=>?@
ABCDEFGHIJKLMNOPQRSTUVWX
^_`abcdefghijklmnopqrstuvwxyz
{|}~
abcdabcdabcd
efghefghefgh
ijklijklijkl
mnopmnopmnop
qrstqrstqrst
cdlzcdlzcdlz
k,grk,grk,gr
================================================
FILE: TestCases/gitHub#47-packer_to93ReplaceFails.js
================================================
' '
'! !#$%&'()*+,-./
23456789:;<=>?@
ABCDEFGHIJKLMNOPQRSTUVW
^_`abcdefghijklmnopqrstuvwxyz`
{|}~
abcdabcdabcd
efghefghefgh
ijklijklijkl
mnopmnopmnop
qrstqrstqrst
cdlzcdlzcdlz
k,grk,grk,gr
================================================
FILE: TestCases/gitHub#55-bothQuotesInUse.js
================================================
v=0;setInterval(()=>{s="'";t='"';s='"'+s;t='"'+t;u=(v&1?s:t);u+=t+s+t;z='"'+"'"+t+s+t;console.log(u)}, 40);
================================================
FILE: TestCases/gitHub#55-quotesAsOnlyTokens.js
================================================
` `
`! !#$%&()*+,-./`
0123456789:;<=>?@
ABCDEFGHIJKLMNOPQRSTUVWXYZ
[\]^_abcdefghijklmnopqrstuvwxyz
`{|}~`
abcdabcdabcd
efghefghefgh
ijklijklijkl
mnopmnopmnop
qrstqrstqrst
================================================
FILE: TestCases/gitHub#55-sameStringInAllQuotes.js
================================================
v=0;setInterval(()=>{s="message";t='message';s=`message`+s;t='message'+t;u=(v&1?s:t);u+=t+s+t;z='message'+"message"+`message`+t+s+t;console.log(u)}, 40);
================================================
FILE: TestCases/gitHub#56-setInterval_arrowComplexValues.js
================================================
t=0;a=a.cloneNode(p=[s=5]);cc=a.getContext("2d");e=cc.getImageData(0,0,150,150);d=e.data;setInterval((w=t,x=y=z=0,aa)=>{if(t%1275<1){cc.fillStyle=n=cc.createRadialGradient(225,75,25,225,75,60);n.addColorStop(x=y=f=0,"rgb("+[50,31+s%15&255,15+s%32&255]);n.addColorStop(1,"#000");cc.fillRect(150,0,150,150);for(;f<256*256;)p[f++]=Math.min(0,3*Math.cos((f&255)/20)-3*Math.cos(f/12800)-s%7+2);for(n=3e5;--n;s*=(256-s)/65)for(x+=[0,1,0,-1][s&3],y+=[0,1,0,-1][3-s&3],t=-6;++t;)for(i=0;++i-6;)p[256*(y+t&255)+(x+i&255)]+=.01}f=Math.cos(++t/200);for(y=-75;++y<75;)for(x=-(u=Math.sqrt(75*75-y*y)&255),q=4*((y+75)*150+75-u);++x<u;){w=Math.sqrt(75*75-y*y-x*x);i=p[((128*Math.atan2(n=y*Math.sin(f)+Math.cos(f)*w,x)+t)/Math.PI&255)+256*(Math.acos((-w*Math.sin(f)+Math.cos(f)*y)/75)*256/Math.PI&255)];n=.1+.008*Math.max(0,n-x);d[q++]=n*(i<0?128-s%128:s%128+s%25*i)&255;d[q++]=n*(i<0?-7*i:75+s%50*i)&255;d[q++]=n*(i<0?s%128:s%75*i)&255;d[q++]=255}cc.putImageData(e,0,0);c.fillStyle="hsl(256,25%,"+Math.max(0,100-t)+"%";c.fillRect(0,0,a.width,a.height);c.save(c.fillStyle="#fff");c.translate(.5*a.width,a.height/2);c.rotate(-.2-.2*Math.cos(Math.max(0,Math.min(t-100,300))*Math.PI/300));c.translate(u=800*Math.cos(Math.max(0,Math.min(t-90,300))*Math.PI/300)-400,500-500*Math.cos(Math.max(0,Math.min(t-1000,300))*Math.PI/300));for(i=0;++i-7500;)c.fillRect(i*i%7525-1500,i%2525-1500,Math.max(i%15/7,t-1200),Math.max(1,t-1100));n=250-75*Math.cos(Math.max(0,Math.min(t-350,300))*Math.PI/300)-150*Math.cos(Math.max(0,Math.min(t-1000,300))*Math.PI/300);c.drawImage(a,0,0,150,150,1200-n,-n,2*n,2*n);n=s|40;c.globalCompositeOperation="lighter";for(i=0;++i-12;)c.drawImage(a,150,0,150,150,-n,-25-n,2*n,2*n);for(i=0;++i-75;)n=25*(i&6),c.drawImage(a,150,0,150,150,-u*i-n,25*i-n,2*n,2*n);c.restore()},33)
================================================
FILE: TestCases/gitHub#56-setInterval_arrowMultipleValues.js
================================================
t=0;a=a.cloneNode(p=[s=5]);cc=a.getContext("2d");e=cc.getImageData(0,0,150,150);d=e.data;setInterval((x=2,y=1,z=0)=>{if(t%1275<1){cc.fillStyle=n=cc.createRadialGradient(225,75,25,225,75,60);n.addColorStop(x=y=f=0,"rgb("+[50,31+s%15&255,15+s%32&255]);n.addColorStop(1,"#000");cc.fillRect(150,0,150,150);for(;f<256*256;)p[f++]=Math.min(0,3*Math.cos((f&255)/20)-3*Math.cos(f/12800)-s%7+2);for(n=3e5;--n;s*=(256-s)/65)for(x+=[0,1,0,-1][s&3],y+=[0,1,0,-1][3-s&3],t=-6;++t;)for(i=0;++i-6;)p[256*(y+t&255)+(x+i&255)]+=.01}f=Math.cos(++t/200);for(y=-75;++y<75;)for(x=-(u=Math.sqrt(75*75-y*y)&255),q=4*((y+75)*150+75-u);++x<u;){w=Math.sqrt(75*75-y*y-x*x);i=p[((128*Math.atan2(n=y*Math.sin(f)+Math.cos(f)*w,x)+t)/Math.PI&255)+256*(Math.acos((-w*Math.sin(f)+Math.cos(f)*y)/75)*256/Math.PI&255)];n=.1+.008*Math.max(0,n-x);d[q++]=n*(i<0?128-s%128:s%128+s%25*i)&255;d[q++]=n*(i<0?-7*i:75+s%50*i)&255;d[q++]=n*(i<0?s%128:s%75*i)&255;d[q++]=255}cc.putImageData(e,0,0);c.fillStyle="hsl(256,25%,"+Math.max(0,100-t)+"%";c.fillRect(0,0,a.width,a.height);c.save(c.fillStyle="#fff");c.translate(.5*a.width,a.height/2);c.rotate(-.2-.2*Math.cos(Math.max(0,Math.min(t-100,300))*Math.PI/300));c.translate(u=800*Math.cos(Math.max(0,Math.min(t-90,300))*Math.PI/300)-400,500-500*Math.cos(Math.max(0,Math.min(t-1000,300))*Math.PI/300));for(i=0;++i-7500;)c.fillRect(i*i%7525-1500,i%2525-1500,Math.max(i%15/7,t-1200),Math.max(1,t-1100));n=250-75*Math.cos(Math.max(0,Math.min(t-350,300))*Math.PI/300)-150*Math.cos(Math.max(0,Math.min(t-1000,300))*Math.PI/300);c.drawImage(a,0,0,150,150,1200-n,-n,2*n,2*n);n=s|40;c.globalCompositeOperation="lighter";for(i=0;++i-12;)c.drawImage(a,150,0,150,150,-n,-25-n,2*n,2*n);for(i=0;++i-75;)n=25*(i&6),c.drawImage(a,150,0,150,150,-u*i-n,25*i-n,2*n,2*n);c.restore()},33)
================================================
FILE: TestCases/gitHub#56-setInterval_arrowNoValue.js
================================================
t=0;a=a.cloneNode(p=[s=5]);cc=a.getContext("2d");e=cc.getImageData(0,0,150,150);d=e.data;setInterval((x,y,z)=>{if(t%1275<1){cc.fillStyle=n=cc.createRadialGradient(225,75,25,225,75,60);n.addColorStop(x=y=f=0,"rgb("+[50,31+s%15&255,15+s%32&255]);n.addColorStop(1,"#000");cc.fillRect(150,0,150,150);for(;f<256*256;)p[f++]=Math.min(0,3*Math.cos((f&255)/20)-3*Math.cos(f/12800)-s%7+2);for(n=3e5;--n;s*=(256-s)/65)for(x+=[0,1,0,-1][s&3],y+=[0,1,0,-1][3-s&3],t=-6;++t;)for(i=0;++i-6;)p[256*(y+t&255)+(x+i&255)]+=.01}f=Math.cos(++t/200);for(y=-75;++y<75;)for(x=-(u=Math.sqrt(75*75-y*y)&255),q=4*((y+75)*150+75-u);++x<u;){w=Math.sqrt(75*75-y*y-x*x);i=p[((128*Math.atan2(n=y*Math.sin(f)+Math.cos(f)*w,x)+t)/Math.PI&255)+256*(Math.acos((-w*Math.sin(f)+Math.cos(f)*y)/75)*256/Math.PI&255)];n=.1+.008*Math.max(0,n-x);d[q++]=n*(i<0?128-s%128:s%128+s%25*i)&255;d[q++]=n*(i<0?-7*i:75+s%50*i)&255;d[q++]=n*(i<0?s%128:s%75*i)&255;d[q++]=255}cc.putImageData(e,0,0);c.fillStyle="hsl(256,25%,"+Math.max(0,100-t)+"%";c.fillRect(0,0,a.width,a.height);c.save(c.fillStyle="#fff");c.translate(.5*a.width,a.height/2);c.rotate(-.2-.2*Math.cos(Math.max(0,Math.min(t-100,300))*Math.PI/300));c.translate(u=800*Math.cos(Math.max(0,Math.min(t-90,300))*Math.PI/300)-400,500-500*Math.cos(Math.max(0,Math.min(t-1000,300))*Math.PI/300));for(i=0;++i-7500;)c.fillRect(i*i%7525-1500,i%2525-1500,Math.max(i%15/7,t-1200),Math.max(1,t-1100));n=250-75*Math.cos(Math.max(0,Math.min(t-350,300))*Math.PI/300)-150*Math.cos(Math.max(0,Math.min(t-1000,300))*Math.PI/300);c.drawImage(a,0,0,150,150,1200-n,-n,2*n,2*n);n=s|40;c.globalCompositeOperation="lighter";for(i=0;++i-12;)c.drawImage(a,150,0,150,150,-n,-25-n,2*n,2*n);for(i=0;++i-75;)n=25*(i&6),c.drawImage(a,150,0,150,150,-u*i-n,25*i-n,2*n,2*n);c.restore()},33)
================================================
FILE: TestCases/gitHub#56-setInterval_arrowOneValue.js
================================================
t=0;a=a.cloneNode(p=[s=5]);cc=a.getContext("2d");e=cc.getImageData(0,0,150,150);d=e.data;setInterval((x,y,z=0)=>{if(t%1275<1){cc.fillStyle=n=cc.createRadialGradient(225,75,25,225,75,60);n.addColorStop(x=y=f=0,"rgb("+[50,31+s%15&255,15+s%32&255]);n.addColorStop(1,"#000");cc.fillRect(150,0,150,150);for(;f<256*256;)p[f++]=Math.min(0,3*Math.cos((f&255)/20)-3*Math.cos(f/12800)-s%7+2);for(n=3e5;--n;s*=(256-s)/65)for(x+=[0,1,0,-1][s&3],y+=[0,1,0,-1][3-s&3],t=-6;++t;)for(i=0;++i-6;)p[256*(y+t&255)+(x+i&255)]+=.01}f=Math.cos(++t/200);for(y=-75;++y<75;)for(x=-(u=Math.sqrt(75*75-y*y)&255),q=4*((y+75)*150+75-u);++x<u;){w=Math.sqrt(75*75-y*y-x*x);i=p[((128*Math.atan2(n=y*Math.sin(f)+Math.cos(f)*w,x)+t)/Math.PI&255)+256*(Math.acos((-w*Math.sin(f)+Math.cos(f)*y)/75)*256/Math.PI&255)];n=.1+.008*Math.max(0,n-x);d[q++]=n*(i<0?128-s%128:s%128+s%25*i)&255;d[q++]=n*(i<0?-7*i:75+s%50*i)&255;d[q++]=n*(i<0?s%128:s%75*i)&255;d[q++]=255}cc.putImageData(e,0,0);c.fillStyle="hsl(256,25%,"+Math.max(0,100-t)+"%";c.fillRect(0,0,a.width,a.height);c.save(c.fillStyle="#fff");c.translate(.5*a.width,a.height/2);c.rotate(-.2-.2*Math.cos(Math.max(0,Math.min(t-100,300))*Math.PI/300));c.translate(u=800*Math.cos(Math.max(0,Math.min(t-90,300))*Math.PI/300)-400,500-500*Math.cos(Math.max(0,Math.min(t-1000,300))*Math.PI/300));for(i=0;++i-7500;)c.fillRect(i*i%7525-1500,i%2525-1500,Math.max(i%15/7,t-1200),Math.max(1,t-1100));n=250-75*Math.cos(Math.max(0,Math.min(t-350,300))*Math.PI/300)-150*Math.cos(Math.max(0,Math.min(t-1000,300))*Math.PI/300);c.drawImage(a,0,0,150,150,1200-n,-n,2*n,2*n);n=s|40;c.globalCompositeOperation="lighter";for(i=0;++i-12;)c.drawImage(a,150,0,150,150,-n,-25-n,2*n,2*n);for(i=0;++i-75;)n=25*(i&6),c.drawImage(a,150,0,150,150,-u*i-n,25*i-n,2*n,2*n);c.restore()},33)
================================================
FILE: TestCases/gitHub#56-setInterval_arrowSingleValue.js
================================================
t=0;a=a.cloneNode(p=[s=5]);cc=a.getContext("2d");e=cc.getImageData(0,0,150,150);d=e.data;setInterval((x=0)=>{if(t%1275<1){cc.fillStyle=n=cc.createRadialGradient(225,75,25,225,75,60);n.addColorStop(x=y=f=0,"rgb("+[50,31+s%15&255,15+s%32&255]);n.addColorStop(1,"#000");cc.fillRect(150,0,150,150);for(;f<256*256;)p[f++]=Math.min(0,3*Math.cos((f&255)/20)-3*Math.cos(f/12800)-s%7+2);for(n=3e5;--n;s*=(256-s)/65)for(x+=[0,1,0,-1][s&3],y+=[0,1,0,-1][3-s&3],t=-6;++t;)for(i=0;++i-6;)p[256*(y+t&255)+(x+i&255)]+=.01}f=Math.cos(++t/200);for(y=-75;++y<75;)for(x=-(u=Math.sqrt(75*75-y*y)&255),q=4*((y+75)*150+75-u);++x<u;){w=Math.sqrt(75*75-y*y-x*x);i=p[((128*Math.atan2(n=y*Math.sin(f)+Math.cos(f)*w,x)+t)/Math.PI&255)+256*(Math.acos((-w*Math.sin(f)+Math.cos(f)*y)/75)*256/Math.PI&255)];n=.1+.008*Math.max(0,n-x);d[q++]=n*(i<0?128-s%128:s%128+s%25*i)&255;d[q++]=n*(i<0?-7*i:75+s%50*i)&255;d[q++]=n*(i<0?s%128:s%75*i)&255;d[q++]=255}cc.putImageData(e,0,0);c.fillStyle="hsl(256,25%,"+Math.max(0,100-t)+"%";c.fillRect(0,0,a.width,a.height);c.save(c.fillStyle="#fff");c.translate(.5*a.width,a.height/2);c.rotate(-.2-.2*Math.cos(Math.max(0,Math.min(t-100,300))*Math.PI/300));c.translate(u=800*Math.cos(Math.max(0,Math.min(t-90,300))*Math.PI/300)-400,500-500*Math.cos(Math.max(0,Math.min(t-1000,300))*Math.PI/300));for(i=0;++i-7500;)c.fillRect(i*i%7525-1500,i%2525-1500,Math.max(i%15/7,t-1200),Math.max(1,t-1100));n=250-75*Math.cos(Math.max(0,Math.min(t-350,300))*Math.PI/300)-150*Math.cos(Math.max(0,Math.min(t-1000,300))*Math.PI/300);c.drawImage(a,0,0,150,150,1200-n,-n,2*n,2*n);n=s|40;c.globalCompositeOperation="lighter";for(i=0;++i-12;)c.drawImage(a,150,0,150,150,-n,-25-n,2*n,2*n);for(i=0;++i-75;)n=25*(i&6),c.drawImage(a,150,0,150,150,-u*i-n,25*i-n,2*n,2*n);c.restore()},33)
================================================
FILE: TestCases/gitHub#56-setInterval_standardComplexValues.js
================================================
t=0;a=a.cloneNode(p=[s=5]);cc=a.getContext("2d");e=cc.getImageData(0,0,150,150);d=e.data;setInterval(function(w=t,x=y=z=0,aa){if(t%1275<1){cc.fillStyle=n=cc.createRadialGradient(225,75,25,225,75,60);n.addColorStop(x=y=f=0,"rgb("+[50,31+s%15&255,15+s%32&255]);n.addColorStop(1,"#000");cc.fillRect(150,0,150,150);for(;f<256*256;)p[f++]=Math.min(0,3*Math.cos((f&255)/20)-3*Math.cos(f/12800)-s%7+2);for(n=3e5;--n;s*=(256-s)/65)for(x+=[0,1,0,-1][s&3],y+=[0,1,0,-1][3-s&3],t=-6;++t;)for(i=0;++i-6;)p[256*(y+t&255)+(x+i&255)]+=.01}f=Math.cos(++t/200);for(y=-75;++y<75;)for(x=-(u=Math.sqrt(75*75-y*y)&255),q=4*((y+75)*150+75-u);++x<u;){w=Math.sqrt(75*75-y*y-x*x);i=p[((128*Math.atan2(n=y*Math.sin(f)+Math.cos(f)*w,x)+t)/Math.PI&255)+256*(Math.acos((-w*Math.sin(f)+Math.cos(f)*y)/75)*256/Math.PI&255)];n=.1+.008*Math.max(0,n-x);d[q++]=n*(i<0?128-s%128:s%128+s%25*i)&255;d[q++]=n*(i<0?-7*i:75+s%50*i)&255;d[q++]=n*(i<0?s%128:s%75*i)&255;d[q++]=255}cc.putImageData(e,0,0);c.fillStyle="hsl(256,25%,"+Math.max(0,100-t)+"%";c.fillRect(0,0,a.width,a.height);c.save(c.fillStyle="#fff");c.translate(.5*a.width,a.height/2);c.rotate(-.2-.2*Math.cos(Math.max(0,Math.min(t-100,300))*Math.PI/300));c.translate(u=800*Math.cos(Math.max(0,Math.min(t-90,300))*Math.PI/300)-400,500-500*Math.cos(Math.max(0,Math.min(t-1000,300))*Math.PI/300));for(i=0;++i-7500;)c.fillRect(i*i%7525-1500,i%2525-1500,Math.max(i%15/7,t-1200),Math.max(1,t-1100));n=250-75*Math.cos(Math.max(0,Math.min(t-350,300))*Math.PI/300)-150*Math.cos(Math.max(0,Math.min(t-1000,300))*Math.PI/300);c.drawImage(a,0,0,150,150,1200-n,-n,2*n,2*n);n=s|40;c.globalCompositeOperation="lighter";for(i=0;++i-12;)c.drawImage(a,150,0,150,150,-n,-25-n,2*n,2*n);for(i=0;++i-75;)n=25*(i&6),c.drawImage(a,150,0,150,150,-u*i-n,25*i-n,2*n,2*n);c.restore()},33)
================================================
FILE: TestCases/gitHub#56-setInterval_standardMultipleValues.js
================================================
t=0;a=a.cloneNode(p=[s=5]);cc=a.getContext("2d");e=cc.getImageData(0,0,150,150);d=e.data;setInterval(function(x=2,y=1,z=0){if(t%1275<1){cc.fillStyle=n=cc.createRadialGradient(225,75,25,225,75,60);n.addColorStop(x=y=f=0,"rgb("+[50,31+s%15&255,15+s%32&255]);n.addColorStop(1,"#000");cc.fillRect(150,0,150,150);for(;f<256*256;)p[f++]=Math.min(0,3*Math.cos((f&255)/20)-3*Math.cos(f/12800)-s%7+2);for(n=3e5;--n;s*=(256-s)/65)for(x+=[0,1,0,-1][s&3],y+=[0,1,0,-1][3-s&3],t=-6;++t;)for(i=0;++i-6;)p[256*(y+t&255)+(x+i&255)]+=.01}f=Math.cos(++t/200);for(y=-75;++y<75;)for(x=-(u=Math.sqrt(75*75-y*y)&255),q=4*((y+75)*150+75-u);++x<u;){w=Math.sqrt(75*75-y*y-x*x);i=p[((128*Math.atan2(n=y*Math.sin(f)+Math.cos(f)*w,x)+t)/Math.PI&255)+256*(Math.acos((-w*Math.sin(f)+Math.cos(f)*y)/75)*256/Math.PI&255)];n=.1+.008*Math.max(0,n-x);d[q++]=n*(i<0?128-s%128:s%128+s%25*i)&255;d[q++]=n*(i<0?-7*i:75+s%50*i)&255;d[q++]=n*(i<0?s%128:s%75*i)&255;d[q++]=255}cc.putImageData(e,0,0);c.fillStyle="hsl(256,25%,"+Math.max(0,100-t)+"%";c.fillRect(0,0,a.width,a.height);c.save(c.fillStyle="#fff");c.translate(.5*a.width,a.height/2);c.rotate(-.2-.2*Math.cos(Math.max(0,Math.min(t-100,300))*Math.PI/300));c.translate(u=800*Math.cos(Math.max(0,Math.min(t-90,300))*Math.PI/300)-400,500-500*Math.cos(Math.max(0,Math.min(t-1000,300))*Math.PI/300));for(i=0;++i-7500;)c.fillRect(i*i%7525-1500,i%2525-1500,Math.max(i%15/7,t-1200),Math.max(1,t-1100));n=250-75*Math.cos(Math.max(0,Math.min(t-350,300))*Math.PI/300)-150*Math.cos(Math.max(0,Math.min(t-1000,300))*Math.PI/300);c.drawImage(a,0,0,150,150,1200-n,-n,2*n,2*n);n=s|40;c.globalCompositeOperation="lighter";for(i=0;++i-12;)c.drawImage(a,150,0,150,150,-n,-25-n,2*n,2*n);for(i=0;++i-75;)n=25*(i&6),c.drawImage(a,150,0,150,150,-u*i-n,25*i-n,2*n,2*n);c.restore()},33)
================================================
FILE: TestCases/gitHub#56-setInterval_standardNoValue.js
================================================
t=0;a=a.cloneNode(p=[s=5]);cc=a.getContext("2d");e=cc.getImageData(0,0,150,150);d=e.data;setInterval(function(x,y,z){if(t%1275<1){cc.fillStyle=n=cc.createRadialGradient(225,75,25,225,75,60);n.addColorStop(x=y=f=0,"rgb("+[50,31+s%15&255,15+s%32&255]);n.addColorStop(1,"#000");cc.fillRect(150,0,150,150);for(;f<256*256;)p[f++]=Math.min(0,3*Math.cos((f&255)/20)-3*Math.cos(f/12800)-s%7+2);for(n=3e5;--n;s*=(256-s)/65)for(x+=[0,1,0,-1][s&3],y+=[0,1,0,-1][3-s&3],t=-6;++t;)for(i=0;++i-6;)p[256*(y+t&255)+(x+i&255)]+=.01}f=Math.cos(++t/200);for(y=-75;++y<75;)for(x=-(u=Math.sqrt(75*75-y*y)&255),q=4*((y+75)*150+75-u);++x<u;){w=Math.sqrt(75*75-y*y-x*x);i=p[((128*Math.atan2(n=y*Math.sin(f)+Math.cos(f)*w,x)+t)/Math.PI&255)+256*(Math.acos((-w*Math.sin(f)+Math.cos(f)*y)/75)*256/Math.PI&255)];n=.1+.008*Math.max(0,n-x);d[q++]=n*(i<0?128-s%128:s%128+s%25*i)&255;d[q++]=n*(i<0?-7*i:75+s%50*i)&255;d[q++]=n*(i<0?s%128:s%75*i)&255;d[q++]=255}cc.putImageData(e,0,0);c.fillStyle="hsl(256,25%,"+Math.max(0,100-t)+"%";c.fillRect(0,0,a.width,a.height);c.save(c.fillStyle="#fff");c.translate(.5*a.width,a.height/2);c.rotate(-.2-.2*Math.cos(Math.max(0,Math.min(t-100,300))*Math.PI/300));c.translate(u=800*Math.cos(Math.max(0,Math.min(t-90,300))*Math.PI/300)-400,500-500*Math.cos(Math.max(0,Math.min(t-1000,300))*Math.PI/300));for(i=0;++i-7500;)c.fillRect(i*i%7525-1500,i%2525-1500,Math.max(i%15/7,t-1200),Math.max(1,t-1100));n=250-75*Math.cos(Math.max(0,Math.min(t-350,300))*Math.PI/300)-150*Math.cos(Math.max(0,Math.min(t-1000,300))*Math.PI/300);c.drawImage(a,0,0,150,150,1200-n,-n,2*n,2*n);n=s|40;c.globalCompositeOperation="lighter";for(i=0;++i-12;)c.drawImage(a,150,0,150,150,-n,-25-n,2*n,2*n);for(i=0;++i-75;)n=25*(i&6),c.drawImage(a,150,0,150,150,-u*i-n,25*i-n,2*n,2*n);c.restore()},33)
================================================
FILE: TestCases/gitHub#56-setInterval_standardOneValue.js
================================================
t=0;a=a.cloneNode(p=[s=5]);cc=a.getContext("2d");e=cc.getImageData(0,0,150,150);d=e.data;setInterval(function(x,y,z=0){if(t%1275<1){cc.fillStyle=n=cc.createRadialGradient(225,75,25,225,75,60);n.addColorStop(x=y=f=0,"rgb("+[50,31+s%15&255,15+s%32&255]);n.addColorStop(1,"#000");cc.fillRect(150,0,150,150);for(;f<256*256;)p[f++]=Math.min(0,3*Math.cos((f&255)/20)-3*Math.cos(f/12800)-s%7+2);for(n=3e5;--n;s*=(256-s)/65)for(x+=[0,1,0,-1][s&3],y+=[0,1,0,-1][3-s&3],t=-6;++t;)for(i=0;++i-6;)p[256*(y+t&255)+(x+i&255)]+=.01}f=Math.cos(++t/200);for(y=-75;++y<75;)for(x=-(u=Math.sqrt(75*75-y*y)&255),q=4*((y+75)*150+75-u);++x<u;){w=Math.sqrt(75*75-y*y-x*x);i=p[((128*Math.atan2(n=y*Math.sin(f)+Math.cos(f)*w,x)+t)/Math.PI&255)+256*(Math.acos((-w*Math.sin(f)+Math.cos(f)*y)/75)*256/Math.PI&255)];n=.1+.008*Math.max(0,n-x);d[q++]=n*(i<0?128-s%128:s%128+s%25*i)&255;d[q++]=n*(i<0?-7*i:75+s%50*i)&255;d[q++]=n*(i<0?s%128:s%75*i)&255;d[q++]=255}cc.putImageData(e,0,0);c.fillStyle="hsl(256,25%,"+Math.max(0,100-t)+"%";c.fillRect(0,0,a.width,a.height);c.save(c.fillStyle="#fff");c.translate(.5*a.width,a.height/2);c.rotate(-.2-.2*Math.cos(Math.max(0,Math.min(t-100,300))*Math.PI/300));c.translate(u=800*Math.cos(Math.max(0,Math.min(t-90,300))*Math.PI/300)-400,500-500*Math.cos(Math.max(0,Math.min(t-1000,300))*Math.PI/300));for(i=0;++i-7500;)c.fillRect(i*i%7525-1500,i%2525-1500,Math.max(i%15/7,t-1200),Math.max(1,t-1100));n=250-75*Math.cos(Math.max(0,Math.min(t-350,300))*Math.PI/300)-150*Math.cos(Math.max(0,Math.min(t-1000,300))*Math.PI/300);c.drawImage(a,0,0,150,150,1200-n,-n,2*n,2*n);n=s|40;c.globalCompositeOperation="lighter";for(i=0;++i-12;)c.drawImage(a,150,0,150,150,-n,-25-n,2*n,2*n);for(i=0;++i-75;)n=25*(i&6),c.drawImage(a,150,0,150,150,-u*i-n,25*i-n,2*n,2*n);c.restore()},33)
================================================
FILE: TestCases/gitHub#56-setInterval_standardSingleValue.js
================================================
t=0;a=a.cloneNode(p=[s=5]);cc=a.getContext("2d");e=cc.getImageData(0,0,150,150);d=e.data;setInterval(function(x=0){if(t%1275<1){cc.fillStyle=n=cc.createRadialGradient(225,75,25,225,75,60);n.addColorStop(x=y=f=0,"rgb("+[50,31+s%15&255,15+s%32&255]);n.addColorStop(1,"#000");cc.fillRect(150,0,150,150);for(;f<256*256;)p[f++]=Math.min(0,3*Math.cos((f&255)/20)-3*Math.cos(f/12800)-s%7+2);for(n=3e5;--n;s*=(256-s)/65)for(x+=[0,1,0,-1][s&3],y+=[0,1,0,-1][3-s&3],t=-6;++t;)for(i=0;++i-6;)p[256*(y+t&255)+(x+i&255)]+=.01}f=Math.cos(++t/200);for(y=-75;++y<75;)for(x=-(u=Math.sqrt(75*75-y*y)&255),q=4*((y+75)*150+75-u);++x<u;){w=Math.sqrt(75*75-y*y-x*x);i=p[((128*Math.atan2(n=y*Math.sin(f)+Math.cos(f)*w,x)+t)/Math.PI&255)+256*(Math.acos((-w*Math.sin(f)+Math.cos(f)*y)/75)*256/Math.PI&255)];n=.1+.008*Math.max(0,n-x);d[q++]=n*(i<0?128-s%128:s%128+s%25*i)&255;d[q++]=n*(i<0?-7*i:75+s%50*i)&255;d[q++]=n*(i<0?s%128:s%75*i)&255;d[q++]=255}cc.putImageData(e,0,0);c.fillStyle="hsl(256,25%,"+Math.max(0,100-t)+"%";c.fillRect(0,0,a.width,a.height);c.save(c.fillStyle="#fff");c.translate(.5*a.width,a.height/2);c.rotate(-.2-.2*Math.cos(Math.max(0,Math.min(t-100,300))*Math.PI/300));c.translate(u=800*Math.cos(Math.max(0,Math.min(t-90,300))*Math.PI/300)-400,500-500*Math.cos(Math.max(0,Math.min(t-1000,300))*Math.PI/300));for(i=0;++i-7500;)c.fillRect(i*i%7525-1500,i%2525-1500,Math.max(i%15/7,t-1200),Math.max(1,t-1100));n=250-75*Math.cos(Math.max(0,Math.min(t-350,300))*Math.PI/300)-150*Math.cos(Math.max(0,Math.min(t-1000,300))*Math.PI/300);c.drawImage(a,0,0,150,150,1200-n,-n,2*n,2*n);n=s|40;c.globalCompositeOperation="lighter";for(i=0;++i-12;)c.drawImage(a,150,0,150,150,-n,-25-n,2*n,2*n);for(i=0;++i-75;)n=25*(i&6),c.drawImage(a,150,0,150,150,-u*i-n,25*i-n,2*n,2*n);c.restore()},33)
================================================
FILE: TestCases/gitHub#57-templateLiteralOneVariable.js
================================================
a=a.cloneNode($=[s=5]);cc=a.getContext("2d");e=cc.getImageData(T=0,0,150,150);d=e.data;setInterval(function(){if(T%1275<1){cc.fillStyle=n=cc.createRadialGradient(225,75,25,225,75,60);n.addColorStop(x=y=f=0,"rgb("+[50,31+s%15&255,15+s%32&255]);n.addColorStop(1,"#000");cc.fillRect(150,0,150,150);for(;f<256*256;)$[f++]=Math.min(0,3*Math.cos((f&255)/20)-3*Math.cos(f/12800)-s%7+2);for(n=3e5;--n;s*=(256-s)/65)for(x+=[0,1,0,-1][s&3],y+=[0,1,0,-1][3-s&3],T=-6;++T;)for(i=0;++i-6;)$[256*(y+T&255)+(x+i&255)]+=.01}f=Math.cos(++T/200);for(y=-75;++y<75;)for(x=-(u=Math.sqrt(75*75-y*y)&255),q=4*((y+75)*150+75-u);++x<u;){w=Math.sqrt(75*75-y*y-x*x);i=$[((128*Math.atan2(n=y*Math.sin(f)+Math.cos(f)*w,x)+T)/Math.PI&255)+256*(Math.acos((-w*Math.sin(f)+Math.cos(f)*y)/75)*256/Math.PI&255)];n=.1+.008*Math.max(0,n-x);d[q++]=n*(i<0?128-s%128:s%128+s%25*i)&255;d[q++]=n*(i<0?-7*i:75+s%50*i)&255;d[q++]=n*(i<0?s%128:s%75*i)&255;d[q++]=255}cc.putImageData(e,0,0);c.fillStyle=`hsl(256,25%,${Math.max(0,100-T)}%`;c.fillRect(0,0,a.width,a.height);c.save(c.fillStyle="#fff");c.translate(.5*a.width,a.height/2);c.rotate(-.2-.2*Math.cos(Math.max(0,Math.min(T-100,300))*Math.PI/300));c.translate(u=800*Math.cos(Math.max(0,Math.min(T-90,300))*Math.PI/300)-400,500-500*Math.cos(Math.max(0,Math.min(T-1000,300))*Math.PI/300));for(i=0;++i-7500;)c.fillRect(i*i%7525-1500,i%2525-1500,Math.max(i%15/7,T-1200),Math.max(1,T-1100));n=250-75*Math.cos(Math.max(0,Math.min(T-350,300))*Math.PI/300)-150*Math.cos(Math.max(0,Math.min(T-1000,300))*Math.PI/300);c.drawImage(a,0,0,150,150,1200-n,-n,2*n,2*n);n=s|40;c.globalCompositeOperation="lighter";for(i=0;++i-12;)c.drawImage(a,150,0,150,150,-n,-25-n,2*n,2*n);for(i=0;++i-75;)n=25*(i&6),c.drawImage(a,150,0,150,150,-u*i-n,25*i-n,2*n,2*n);c.restore()},33);
================================================
FILE: TestCases/gitHub#58-lettersOnly.js
================================================
a=b=c=d=e=0;for(k=0;k<50;++k)a+=k;for(k=0;k<50;++k)b+=k*k;for(k=0;k<50;++k)c+=k*k*k;for(p=1;p<50;++p)d+=1/p;for(p=1;p<50;++p)e+=1/p/p;
================================================
FILE: TestCases/gitHub#58-numberAsMostFrequent.js
================================================
a=b=c=d=e=k=0;for(2==e&&k=1;k<50;++k)a+=k;for(2==a&&k=5;k<50;++k)b+=k*k;for(20==b&&k=9;k<50;++k)c+=k*k*k;for(p=1;p<50;++p)d+=1/p;for(p=1;p<50;++p)e+=1/p/p;
================================================
FILE: TestCases/gitHub#59-negatedRangeMerge-1vs3.js
================================================
! !'#$%&'()*+,-./
456789:;<=>?@
ABCDEFGHIJKLMNOPQRSTUVWXYZ
[\]`_^`
abcdefghijklmnopqrstuvwxyz
{|~
abcdabcdabcd
================================================
FILE: TestCases/gitHub#63-backtick2DContext.js
================================================
a=a.cloneNode(p=[s=5]);cc=a.getContext`2d`;e=cc.getImageData(t=0,0,150,150);d=e.data;setInterval(function(){if(t%1275<1){cc.fillStyle=n=cc.createRadialGradient(225,75,25,225,75,60);n.addColorStop(x=y=f=0,"rgb("+[50,31+s%15&255,15+s%32&255]);n.addColorStop(1,"#000");cc.fillRect(150,0,150,150);for(;f<256*256;)p[f++]=Math.min(0,3*Math.cos((f&255)/20)-3*Math.cos(f/12800)-s%7+2);for(n=3e5;--n;s*=(256-s)/65)for(x+=[0,1,0,-1][s&3],y+=[0,1,0,-1][3-s&3],t=-6;++t;)for(i=0;++i-6;)p[256*(y+t&255)+(x+i&255)]+=.01}f=Math.cos(++t/200);for(y=-75;++y<75;)for(x=-(u=Math.sqrt(75*75-y*y)&255),q=4*((y+75)*150+75-u);++x<u;){w=Math.sqrt(75*75-y*y-x*x);i=p[((128*Math.atan2(n=y*Math.sin(f)+Math.cos(f)*w,x)+t)/Math.PI&255)+256*(Math.acos((-w*Math.sin(f)+Math.cos(f)*y)/75)*256/Math.PI&255)];n=.1+.008*Math.max(0,n-x);d[q++]=n*(i<0?128-s%128:s%128+s%25*i)&255;d[q++]=n*(i<0?-7*i:75+s%50*i)&255;d[q++]=n*(i<0?s%128:s%75*i)&255;d[q++]=255}cc.putImageData(e,0,0);c.fillStyle="hsl(256,25%,"+Math.max(0,100-t)+"%";c.fillRect(0,0,a.width,a.height);c.save(c.fillStyle="#fff");c.translate(.5*a.width,a.height/2);c.rotate(-.2-.2*Math.cos(Math.max(0,Math.min(t-100,300))*Math.PI/300));c.translate(u=800*Math.cos(Math.max(0,Math.min(t-90,300))*Math.PI/300)-400,500-500*Math.cos(Math.max(0,Math.min(t-1000,300))*Math.PI/300));for(i=0;++i-7500;)c.fillRect(i*i%7525-1500,i%2525-1500,Math.max(i%15/7,t-1200),Math.max(1,t-1100));n=250-75*Math.cos(Math.max(0,Math.min(t-350,300))*Math.PI/300)-150*Math.cos(Math.max(0,Math.min(t-1000,300))*Math.PI/300);c.drawImage(a,0,0,150,150,1200-n,-n,2*n,2*n);n=s|40;c.globalCompositeOperation="lighter";for(i=0;++i-12;)c.drawImage(a,150,0,150,150,-n,-25-n,2*n,2*n);for(i=0;++i-75;)n=25*(i&6),c.drawImage(a,150,0,150,150,-u*i-n,25*i-n,2*n,2*n);c.restore()},33);
================================================
FILE: TestCases/gitHub#63-backtickWebGLContext.js
================================================
for(i in g=a.getContext`webgl`)g[i[0]+i[6]]=g[i];with(g)vA(P=cP(),2,5120,bD(B=ET-3,Int8Array.of(B,setInterval(x=>dr(6,vertexAttrib1f(1,NO+=.01),3),A=s=>sS(S=cS(FN++),s)|ce(S)|aS(P,S)),!A(`${V="varying lowp vec4 C,U;\n#define R(a)mat2(cos(a),-sin(a),sin(a),cos(a))\n#define D length(vec2(length(q.xy)-2.,q.z))-.1\nvoid main(){"}lowp float t=0.,d,e,f;for(int i=0;i<99;i++){lowp vec3 p=vec3(C.xy*3.,t-3.),q=p;q.yz*=R(U.x-.8);q.xy*=R(U.x-.6);e=max(length(q.xz)-.15,abs(q.y)-2.);q=p;q.xz*=R(.8);q.yz*=R(.6);f=D;q=p;q.xz*=R(-.8);q.yz*=R(.6);f=min(f,D);d=min(e,f);t+=d;if(d<.01){d=1.5-step(length(p),1.)-float(i)/5.;break;}}gl_FragColor=vec4(d,d,d,1);}`),B,!eV(bf(B,cB())),!A(`attribute vec4 A,B;${V}gl_Position=C=A;U=B;}`)),B+82),lo(P),ug(P))
================================================
FILE: TestCases/gitHub#64-URIError.js
================================================
c.fillText('✪🅼🅼🅼', 5, 165);
================================================
FILE: TestCases/gitHub#65-backslash_invalidEscapeSequence.js
================================================
b.innerHTML=`<div style=width:95vw;height:95vh;perspective:500px;overflow:hidden;background:#7e2><div style=transform-style:preserve-3d;margin:50vh+50vw;transform-origin:0+0 id=s><div style=width:55px;font:40px'' id=h>🐰<div style=transform:rotate(180deg)translateY(9px);font:50px''>🎩`;k=[];onkeydown=e=>k[e.which-37]=1;onkeyup=e=>k[e.which-37]=0;x=-400;y=-630;a=1.35;m=[0,10240,45022,59464,27080,59658,114174,0];z=1;for(i in m){for(H=17;H--;){if(m[i]>>H&1){s.innerHTML+=`<div style=width:255px;height:255px;background:#b31;position:fixed;top:${250*i}px;left:${250*H}px>`;}else s.innerHTML+=`<div id=t${i+H} style=font-size:120px;position:fixed>${[...'🌳🌲🌵'][(i*H+z++)%3]}`;}}s.innerHTML+=`<div id=t${616} style=font-size:30px>🥕`;t=0;c=0;setInterval(e=>{t+=.3;v=x;w=y;if(k[2])a-=.05;else if(k[0])a+=.05;else if(k[1]){y+=20*Math.cos(a);x+=20*Math.sin(a)}else if(k[3]){y-=20*Math.cos(a);x-=20*Math.sin(a)}if(!(m[~~(-y/250)]>>(~~(-x/250))&1)){x=v;y=w}h.style.transform=`translateX(${-x-20}px)translateY(${-y-20}px)translateZ(${60-14*Math.sin(t)}px)rotateZ(${-a}rad)rotateX(-90deg)`;if(!c)s.style.transform=`rotateX(55deg)rotateZ(${a}rad)translateX(${x}px)translateY(${y}px)`;else{s.style.transition=`5s`;s.style.transform=`rotateX(30deg)translateX(-2200px)translateY(-2000px)translateZ(-2000px)`;a=0;}for(i in m){for(H=17;H--;){if(self[`t${i+H}`]){if(c)self[`t${i+H}`].style.transition=`5s`;self[`t${i+H}`].style.transform=`translateX(${H*250+99}px)translateY(${i*250-99}px)translateZ(160px)rotateZ(${-a}rad)rotateX(-90deg)scale(2.5)`;}}}if(x<-4100)c=1},33)
================================================
FILE: TestCases/gitHub#73-backslash_unexpandedToken.js
================================================
module.exports=function(n){function e(n,e){for(;n instanceof Array&&n[0]in e&&e[n[0]].M;)n=e[n[0]](...n.slice(1));return n}function t(n,r){for(;;){if(!(n instanceof Array))return i(n,r);if(n=e(n,r),!(n instanceof Array))return i(n,r);if("def"==n[0])return r[n[1]]=t(n[2],r);if("~"==n[0]){let e=t(n[1],r);return e.M=1,e}if("`"==n[0])return n[1];if(".-"==n[0]){let e=i(n.slice(1),r),t=e[0][e[1]];return 2 in e?e[0][e[1]]=e[2]:t}if("."==n[0]){let e=i(n.slice(1),r),t=e[0][e[1]];return t.apply(e[0],e.slice(2))}if("try"==n[0])try{return t(n[1],r)}catch(e){return t(n[2][2],i([n[2][1]],r,[e]))}else if("fn"==n[0]){let e=function(...e){return t(n[2],i(n[1],r,e))};return e.A=[n[2],r,n[1]],e}if("let"==n[0]){r=Object.create(r);for(let e in n[1])e%2&&(r[n[1][e-1]]=t(n[1][e],r));n=n[2]}else if("do"==n[0]){let e=i(n.slice(1,n.length-1),r);n=n[n.length-1]}else if("if"==n[0])n=t(n[1],r)?n[2]:n[3];else{let e=i(n,r),t=e[0];if(!t.A)return t(...e.slice(1));n=t.A[0],r=i(t.A[2],t.A[1],e.slice(1))}}}let i=function(e,i,r){return r?(i=Object.create(i),e.some((n,t)=>"&"==n?i[e[t+1]]=r.slice(t):(i[n]=r[t],0)),i):e instanceof Array?e.map((...n)=>t(n[0],i)):typeof ""==typeof e?e in i?i[e]:n.throw(e+" not found"):e};return n=Object.assign(Object.create(n),{js:eval,eval:(...e)=>t(e[0],n),"=":(...n)=>n[0]===n[1],"<":(...n)=>n[0]<n[1],"+":(...n)=>n[0]+n[1],"-":(...n)=>n[0]-n[1],"*":(...n)=>n[0]*n[1],"/":(...n)=>n[0]/n[1],isa:(...n)=>n[0]instanceof n[1],type:(...n)=>typeof n[0],new:(...n)=>new(n[0].bind(...n)),del:(...n)=>delete n[0][n[1]],throw:(...n)=>{throw n[0]},read:(...n)=>JSON.parse(n[0]),slurp:(...n)=>require("fs").readFileSync(n[0],"utf8"),load:(...e)=>t(JSON.parse(require("fs").readFileSync(e[0],"utf8")),n),rep:(...e)=>JSON.stringify(t(JSON.parse(e[0]),n))})}
================================================
FILE: TestCases/gitHub#83-backslash_largerOutput.js
================================================
for(b.innerHTML=`<div style=transform-style:preserve-3d;position:fixed;perspective:80vh;margin:40vh+50vw><div style=transform-style:preserve-3d;position:fixed;transform:translateX(-30vh)translateZ(-30vh)rotateX(55deg)rotateZ(28deg><div id=s style=transform-style:preserve-3d;position:fixed;width:72vh;height:48vh;background:#19c;animation:a+9s><style>@keyframes a{50%{transform:rotateZ(-50deg`,m=`055000000000000552000500067760005012210500066660005012210555558855555012210000000000000012210000004400000012211111111111113112222211111122220222222211222222100000222211222222100000222211111222000000222211111222000000`,i=12;i--;)for(L=18;L--;)+m[18*i+L]&&(s.innerHTML+=`<div style=transform-style:preserve-3d;position:fixed;transform:translateY(${i*4+(m[i*18+L]==4?-15:0)}vh)translateX(${L*4}vh)translateZ(${[1,1,1,2,1,1,1,1,13][m[i*18+L]]}vh)scaleX(1.1)scaleY(${m[i*18+L]==4?5:1.1})scaleZ(${[,.5,.8,.2,.2,5,8,11,2][m[i*18+L]]}><p style=transform-style:preserve-3d;position:fixed;width:4vh;height:4vh;background:#${[`349`,`ed7`,`0a0`,`da4`][m[i*18+L]]||`ddd`};transform:translateZ(4vh><p style=transform-style:preserve-3d;position:fixed;width:4vh;height:4vh;background:#${[,`ed7`,`0a0`,`da4`][m[i*18+L]]||`ddd`};transform:rotateY(90deg)translate(-2vh)translateZ(-2vh><p style=transform-style:preserve-3d;position:fixed;width:4vh;height:4vh;background:#${[,`ed7`,`0a0`,`da4`][m[i*18+L]]||`ddd`};transform:rotateY(90deg)translate(-2vh)translateZ(2vh><p style=transform-style:preserve-3d;position:fixed;width:4vh;height:4vh;background:#${[,`fe8`,`0c0`,`da4`][m[i*18+L]]||`edd`};transform:rotateX(90deg)translateY(2vh)translateZ(-2vh>`);for(i=7;i--;)s.innerHTML+=`<div style=transform-style:preserve-3d;position:fixed;transform:translateX(${[10,26,31,2,59,54,10][i]}vh)translateY(${[-11,-6,2,-5,-5,14,14][i]}vh)translateZ(${[20.9,33,45,21,21,21,21][i]}vh)scaleX(${[2.5,1,.5,.5,.5,.3,.3][i]})scaleY(${[1.5,1,.5,.5,.5,.3,.3][i]})scaleZ(.5><p style=transform-style:preserve-3d;position:fixed;width:20vmin;height:20vmin;background:#b31;clip-path:polygon(50%+0,0+99%,99%+99%);transform:translateZ(9vmin)translateY(4.9vmin)rotateX(-60deg><p style=transform-style:preserve-3d;width:20vmin;height:20vmin;position:fixed;background:#b31;clip-path:polygon(50%+0,0+99%,99%+99%);transform:translateZ(9vh)translateX(-4.9vh)rotateY(-60deg)rotateZ(90deg><p style=transform-style:preserve-3d;width:20vmin;height:20vmin;position:fixed;background:#a31;clip-path:polygon(50%+0,0+99%,99%+99%);transform:translateZ(9vh)translateX(4.9vh)rotateY(60deg)rotateZ(-90deg>`
================================================
FILE: TestCases/gitHub#83-packer_9Alone.js
================================================
''
'! !#$%&'()*+,-./
3456789:;<=>?@
ABCDEFGHIJKLMNOPQRSTUVW
[\]^_`abcdefghijklmnopqrsuvwxyz`
{|}~
abcdabcdabcd;
efghefghefgh;
ijklijklijkl;
mnopmnopmnop;
qrstqrstqrst;
cdlzcdlzcdlz;
k,grk,grk,gr;
================================================
FILE: TestCases/gitHub#85-backslashSequence.js
================================================
var s="\\";
s=s+s;
var z=s;
var s="abcdefghijklmnopqrstuvwxyz";
var k=s+z;
var w=k+"aab\\xyz";
var d=[];
for (var i=0; i<10; ++i) { d.push(i); d.push(i+"\\"); }
================================================
FILE: TestCases/gitHub#85-flappyDragon.js
================================================
B=E=C=0;s=a.height/1E3;R=[];for(i=0;1E3>i;i++)R[i]=R[i+1E3]=8*Math.random()|0;k=G=6;r=50;x=200;y=500;V=0;S=20;ontouchstart=onmousedown=function(){E?location=location:(B=1,V=45)};(F=function(){c[f="fillStyle"]="#E50";c.fillRect(0,0,2E3,2E3);c.save();c.scale(s,s);c[f]="#920";c[b="beginPath"]();c[M="moveTo"](-S,0);for(i=2E3;i--;)i%20?c[L="lineTo"](40*i-S,20+4*R[i]):(c[L](40*i-S,100*R[i]),c[L](40*i-S-4,100*R[i]));c[L](40*i-S,0);c.fill();c[b]();c[M](-S,2E3);for(i=2E3;i--;)i%20?c[L="lineTo"](40*i-S,980-4*R[i]):(c[L](40*i-S,100*(R[i]+3)),c[L](40*i-S-4,100*(R[i]+3)));c[L](40*i-S,1E3);c.fill();c[f]="#000";c[b]();z="fEFf&{{~_=,;=vviJ.jfVx/.OoyxzyhkhEwf74)\\n$fwwuvtU`"+(10<V?"iZ[*)yj:*xm**y|Ktdww54#5Dy\\iz[Kzi[Jiijk[e@1!":"zl]LfU{\\lKtBUh{zzU66xxgxg5\\n&xxyz{vfwwxyDfwxxEl^, ");c[M](v=x,w=y-=V);for(i in z)c[L](v+=16-2*(z.charCodeAt(i)&15),w+=8-2*(z.charCodeAt(i)>>4));c.fill();B&&(V-=G);B&&!E&&(S+=20,4E4<S&&(S-=4E4));B&&k++;!B||E||k%40||(C++,15<r&&r--);if(50>y||950<y||!((S+180)%800)&&(y<100*R[20*~~(S/800)+20]+50||y>100*R[20*~~(S/800)+20]+250))E=1;c[f]="#fff";c.font="9em a";c.fillText(C,40,200);c.restore();setTimeout(F,r)})()
================================================
FILE: TestCases/gitHub#9-hashloop.js
================================================
(u=function(){for(requestAnimationFrame(u),a.width=x=1023,a.height=h=x*innerHeight/innerWidth|1,H=performance.now()/15|1,c.textAlign="center",c.font="2em cursive",q=170,c.fillStyle="hsl("+q+",20%,55%)",c.fillRect(0,0,1023,h),w=555;x--;)if(s=x%3?1&H++||-1:0,c[1023&H]=x&&c[1023&H]||8+Math.random()*h/2,Y=48*Math.sin(H/511-3*Math.sin(H/511*3))+s*c[1023&H]+h/2,X=1023-x+(511-x)*Y/h,c.globalAlpha=1,q=170,s)if(q+=31&Y,c.fillStyle="hsl("+q+",55%,200%)",H%511){if(1&Y&&(c.fillStyle="hsl("+q+",55%,20%)"),c.fillRect(X+3*Math.sin(q++),Y+Math.sin(q++),1,5),c.fillRect(X+3*Math.sin(q++),Y+Math.sin(q++),1,5),c.fillRect(X+3*Math.sin(q++),Y+Math.sin(q++),1,5),c.fillRect(X+48*Math.sin(q++),Y+3*Math.sin(q++),1,1),c.fillRect(X+48*Math.sin(q++),Y+3*Math.sin(q++),1,1),c.fillRect(X+48*Math.sin(q++),Y+3*Math.sin(q++),1,1),!(H%(9+3*Math.sin(H/511/3)|1)))for(z=15&Y,z+=6,Y-=6*z,c.globalAlpha=.3;z--;)c.beginPath(),c.lineTo(X,Y),c.lineTo(X-2*z+3*Math.sin(q++),Y+6*z+3*Math.sin(q++)),c.lineTo(X+2*z+3*Math.sin(q++),Y+6*z+3*Math.sin(q++)),c.fill()}else c.fillText(["Cross browser","1kb demos","February 2015","JS1k 2015"][H/511&3],X,Y);else if(c.fillStyle="hsl("+q+",55%,2%)",c.fillRect(X,Y,1,5),c.fillRect(X,Y,5,1),Y+=2,c.fillRect(X,Y,5,1),x==w)if(X-=10,c.fillRect(X,Y,20,-10),511>x)for(c.fillRect(X,Y,10,-15),X+=15,c.fillRect(X,Y,2,-15),c.fillStyle="hsl("+q+",55%,200%)",c.globalAlpha=.3,q=H,z=9;z--;)c.fillRect(X+3*Math.sin(q++),Y-6*z+3*Math.sin(q++),z,z);else w-=15;c.globalCompositeOperation="destination-in",H=31*Math.sin(H/511/2+10)+31,H=3>H?9:H*H,c.translate(511,h/2),c.rotate(H/511+.1),c.scale(H,H),X=Y=-3,c.beginPath(),c.moveTo(X,Y),c.arc(X-2,Y+3,2,0,Math.PI/2,0),X+=2,Y+=4,c.moveTo(X,Y),c.arc(X,Y-1,1,Math.PI/2,Math.PI/2*3,1),c.arc(X,Y-3,1,Math.PI/2,Math.PI/2*3,0),X+=3,c.moveTo(X,Y),c.arc(X-2,Y-5,2,0,Math.PI/2,0),X+=2,c.moveTo(X,Y),c.lineTo(X,Y-6),X+=3,c.moveTo(X,Y),c.arc(X-1,Y-2,1,Math.PI/2*3/2,Math.PI/2*3,0),c.stroke()})();
================================================
FILE: TestCases/hash_using_length.js
================================================
t=w=0;c.lineCap="round";setInterval(function(){for(i=720;i;)c.strokeStyle="hsl(20,0%,"+((Math.cos(t/20.372)+1)*x.charCodeAt(--i)+(-Math.cos(t/20.372)+1)*x.charCodeAt(--i))/2+"%)",c.lineWidth=(Math.cos(t/20.372)+1)*x.charCodeAt(--i)+(-Math.cos(t/20.372)+1)*x.charCodeAt(--i),c.beginPath(),c.moveTo((Math.cos(t/20.372)+1)*x.charCodeAt(--i)+(-Math.cos(t/20.372)+1)*x.charCodeAt(--i),(Math.cos(t/20.372)+1)*x.charCodeAt(--i)+(-Math.cos(t/20.372)+1)*x.charCodeAt(--i)),c.lineTo((Math.cos(t/20.372)+1)*x.charCodeAt(--i)+(-Math.cos(t/20.372)+1)*x.charCodeAt(--i),(Math.cos(t/20.372)+1)*x.charCodeAt(--i)+(-Math.cos(t/20.372)+1)*x.charCodeAt(--i)),c.stroke();w=w?--w:++t&63?w:64},40)
================================================
FILE: TestCases/webglContext_create1.js
================================================
gl=canvas.getContext("experimental-webgl");
gl.clearColor(0.0, 0.0, 0.0, 1.0);
gl.clearDepth(1.0);
gl.enable(gl.DEPTH_TEST);
gl.depthFunc(gl.LEQUAL);
gl.bindBuffer(gl.ARRAY_BUFFER, b = gl.createBuffer());
================================================
FILE: TestCases/webglContext_create2.js
================================================
gl=canvas.getContext("webgl");
gl.clearColor(0.0, 0.0, 0.0, 1.0);
gl.clearDepth(1.0);
gl.enable(gl.DEPTH_TEST);
gl.depthFunc(gl.LEQUAL);
gl.bindBuffer(gl.ARRAY_BUFFER, b = gl.createBuffer());
================================================
FILE: TestCases/webglContext_create3.js
================================================
gl=canvas.getContext("experimental-webgl")||canvas.getContext("webgl");
gl.clearColor(0.0, 0.0, 0.0, 1.0);
gl.clearDepth(1.0);
gl.enable(gl.DEPTH_TEST);
gl.depthFunc(gl.LEQUAL);
gl.bindBuffer(gl.ARRAY_BUFFER, b = gl.createBuffer());
================================================
FILE: TestCases/webglContext_create4.js
================================================
gl=canvas.getContext("webgl")||canvas.getContext("experimental-webgl");
gl.clearColor(0.0, 0.0, 0.0, 1.0);
gl.clearDepth(1.0);
gl.enable(gl.DEPTH_TEST);
gl.depthFunc(gl.LEQUAL);
gl.bindBuffer(gl.ARRAY_BUFFER, b = gl.createBuffer());
================================================
FILE: TestCases/webglContext_create5.js
================================================
o={ antialias: true, stencil: true };
gl=canvas.getContext("webgl", o)||canvas.getContext("experimental-webgl", o);
gl.clearColor(0.0, 0.0, 0.0, 1.0);
gl.clearDepth(1.0);
gl.enable(gl.DEPTH_TEST);
gl.depthFunc(gl.LEQUAL);
gl.bindBuffer(gl.ARRAY_BUFFER, b = gl.createBuffer());
================================================
FILE: TestCases/webglContext_create6.js
================================================
gl=canvas.getContext("webgl", { antialias: true, stencil: true })||canvas.getContext("experimental-webgl", { antialias: true, stencil: true });
gl.clearColor(0.0, 0.0, 0.0, 1.0);
gl.clearDepth(1.0);
gl.enable(gl.DEPTH_TEST);
gl.depthFunc(gl.LEQUAL);
gl.bindBuffer(gl.ARRAY_BUFFER, b = gl.createBuffer());
================================================
FILE: TestCases/webglContext_substringHash.js
================================================
gl=canvas.getContext("experimental-webgl");
gl.clearColor(0.0, 0.0, 0.0, 1.0);
gl.clearDepth(1.0);
gl.enable(gl.DEPTH_TEST);
gl.depthFunc(gl.LEQUAL);
gl.bindBuffer(gl.ARRAY_BUFFER, b = gl.createBuffer());
gl.enableVertexAttribArray();
================================================
FILE: bin/regpack
================================================
#! /usr/bin/env node
const cmdRegPack = require('..').cmdRegPack;
var argv = require('minimist')(process.argv.slice(2));
var input = argv._[0];
if (input != '-') {
result = cmdRegPack(require('fs').readFileSync(input, 'utf-8'), argv);
console.log(result);
} else {
process.stdin.resume();
process.stdin.setEncoding('utf8');
var buffer = '';
process.stdin.on('data', function(data) {
buffer += data;
});
process.stdin.on('end', function() {
result = cmdRegPack(buffer, argv);
console.log(result);
});
}
================================================
FILE: changelog.txt
================================================
v5.0.4 - July 2022
Fixed bugs
- #59 : Negated char class : optimal range merge
- #74 : Line break removed, leaving no separator between instructions
- #79 : Discard C-style and xml-style comments
- #86 : Shorten context properties using available variable names
- #96 : Do not remove newlines or trailing blanks in template literals
- #97 : setTransform turns into getTransform on Chrome
------------------------------
v5.0.3 - February 2019
Fixed bugs
- #87 : Crusher always ignores first character when searching for patterns
- #88 : Unable to allocate a variable name for setInterval()
- #89 : Empty mapping crashes thermal viewer
- #94 : Cannot read property 'first' of undefined
------------------------------
v5.0.2 - October 2018
Fixed bugs
- #76 : Reassign variable names : still considering (but not replacing) text in strings
- #82 : Nested backticks in template literal causes string renaming module to miss occurrences
- #83 : Don't use "\" as a token if avoiding it makes the output smaller
- #85 : Suboptimal packing due to incorrect assumed length of escape sequence
------------------------------
v5.0.1 - February 2017
Fixed bugs
- #65 : RegPacked code contains invalid escape sequences
- #70 : Line endings in bin/regpack
- #72 : Optimization for refactor setInterval() when no initialization code
- #73 : Unpacked source has "in" strings in wrong places
- #75 : Variables leak into global space, should be declared local
------------------------------
v5.0.0 - February 2017
New features :
- #26 : Add a heatmap vizualisation
- #33 : [Online demo] Sync the input textarea with the URL's hash
- #44 : Support for arrow function when refactoring setInterval
- #47 : Support escaped characters in character class
- #48 : Crusher phase - list patterns that are "almost" gains
- #54 : Opt-out flag for ES6 features
- #55 : Harmonize strings delimiters inside the code, to free " or ' as compression token
- #56 : Support for default parameters when refactoring setInterval()
- #63 : ES6 : Support syntax canvas.getContext`2d` in module "hash context"
Fixed bugs
- #50 : Crusher splits Unicode high/low surrogate pairs, producing incorrect strings
- #52 : regPack.html - Base64 output fails for chars outside of the Latin1 range
- #57 : $ in template literals
- #58 : Hash context module uses digit as loop variable
------------------------------
v4.0.1 - February 2016
Fixed bugs
- #39 : Rename variable in unpacking loop and protect variable d and g by default
- #40 : Fix use in Node and Better CLI support
- #41 : Visualization misses patterns that end at the last character
- #45 : Closing bracket ] not allowed in character class range definition
------------------------------
v4.0 - December 2015
New features :
- #16 : Add an option for base64 encoded output
- #19 : Use setInterval() to evaluate the unpacked code
- #21 : Hash not only canvas functions, but also canvas properties
- #23 : Extra hashing functions
- #25 : Visualize the compressed patterns inside the source code
Fixed bugs
- #10 : Use varsNotReassigned in renameObjectMethods
- #17 : Hashing code confuses first and second 2D context
- #20 : Code packed in FF fails in Chrome because of deprecated context methods
- #27 : Do not let variable renaming interfere with the use of the variable _
- #28 : Unable to create 2D/GL/Audio context under Node.js
- #29 : Variable renaming gives different results under FF / Chrome / Node.js
- #30 : support for '!' character in WebGL context declaration
- #31 : Single - character misinterpreted as range in RegExp
------------------------------
v3.0.2 - February 2015
Fixed bugs
- #9 : Canvas hashing can overwrite the "protected" variables
- #11 : Different results between FF and other browsers, method array.fill() interferes with algorithm
- #12 : Disable AudioContext hashing option if the browser does not support the WebAudio API
------------------------------
v3.0.1 - March 2014
Fixed bugs
- #2 : support for Unicode characters in regular expression
- #4 : original size showed without added escapes
- #5 : correct size in bytes after preprocessing stage
------------------------------
v3.0 - February 2014
Added preprocessing stage at the beginning of compression workflow.
Preprocessing :
- method hashing/renaming for 2D context, WebGL context and AudioContext
- variable renaming to free tokens for the crusher
Fixed bugs :
- Incorrect CR/LF handling for code using characters below 10
- Character 127 ignored in negated char class regexp
------------------------------
v2 - April 2013
Use of regular expressions with negated char class (listing characters not to match on).
------------------------------
================================================
FILE: contextDescriptor_browser.js
================================================
/**
* @constructor
* The ContextDescriptor class exposes the contents of the different contexts (2D graphic, GL graphics and Audio)
* in a structure tailored for the use of the preprocessor.
* @see Shapeshifter.js
* It provides three descriptions :
* - canvas2DContextDescription : for a 2D context of a canvas
* - canvasGLContextDescription : for a webgl context of a canvas
* - audioContextDescription : for an AudioContext (if supported by the current browser)
*
* This implementation is tailored for in-browser execution (as opposed to server-side execution with Node.js)
* It derives the contents from actual instances of the contexts.
*/
function ContextDescriptor()
{
var canvas = document.createElement("canvas");
var context2D = canvas.getContext("2d");
this.canvas2DContextDescription = this.describeContext(context2D);
canvas = document.createElement("canvas");
var contextGL = canvas.getContext("webgl");
this.canvasGLContextDescription = this.describeContext(contextGL);
var audioContext = []; // have an empty description if the AudioContext is not supported
if (typeof AudioContext !== "undefined") {
audioContext = new AudioContext;
}
this.audioContextDescription = this.describeContext(audioContext);
this.balanceContexts(); // all contexts since Firefox 102 / Chromium 103
}
ContextDescriptor.prototype = {
describeContext : function(context) {
var description = { properties : [], constants : {} };
for (var prop in context) {
if (prop.match(/^[A-Z_0-9]*$/)) { // constant : name in capitals only
description.constants[prop] = context[prop];
}
description.properties.push(prop);
}
return description;
},
/**
* Fix for issue #20 - make sure the behavior is identical in all browsers
* by adding extra methods / properties to the description of 2D context
* to even out the property list for all browsers.
*
* Update for #97 in July 2022 : GL and Audio contexts also need to be levelled
*
* Needs to be reconsidered at each new browser revision
* (current reference are for FF 102 / Chromium 103)
*/
balanceContexts : function() {
this.canvas2DContextDescription.properties.push("fontKerning"); // Chrome only
this.canvas2DContextDescription.properties.push("fontStretch"); // Chrome only
this.canvas2DContextDescription.properties.push("fontVariantCaps"); // Chrome only
this.canvas2DContextDescription.properties.push("getContextAttributes"); // Chrome only
this.canvas2DContextDescription.properties.push("imageSmoothingQuality"); // Chrome only
this.canvas2DContextDescription.properties.push("isContextLost"); // Chrome only
this.canvas2DContextDescription.properties.push("letterSpacing"); // Chrome only
this.canvas2DContextDescription.properties.push("mozCurrentTransform"); // FF-prefixed
this.canvas2DContextDescription.properties.push("mozCurrentTransformInverse"); // FF-prefixed
this.canvas2DContextDescription.properties.push("mozImageSmoothingEnabled"); // FF-prefixed
this.canvas2DContextDescription.properties.push("mozTextStyle"); // FF-prefixed
this.canvas2DContextDescription.properties.push("reset"); // Chrome only
this.canvas2DContextDescription.properties.push("roundRect"); // Chrome only
this.canvas2DContextDescription.properties.push("textRendering"); // Chrome only
this.canvas2DContextDescription.properties.push("wordSpacing"); // Chrome only
this.canvasGLContextDescription.properties.push("makeXRCompatible"); // Chrome only
this.audioContextDescription.properties.push("createMediaStreamTrackSource"); // Firefox only
},
}
================================================
FILE: contextDescriptor_node.js
================================================
/**
* @constructor
* The ContextDescriptor class exposes the contents of the different contexts (2D graphic, GL graphics and Audio)
* in a structure tailored for the use of the preprocessor.
* @see Shapeshifter.js
* It provides three descriptions :
* - canvas2DContextDescription : for a 2D context of a canvas
* - canvasGLContextDescription : for a webgl context of a canvas
* - audioContextDescription : for an AudioContext (if supported by the current browser)
*
* This implementation is a workaround for Node.js environments, which do not provide built-in canvas (nor associated contexts)
* The values are explicitely set based on FF 50 and Chrome 54
*/
function ContextDescriptor()
{
this.canvas2DContextDescription = {
properties : [
"arc",
"arcTo",
"beginPath",
"bezierCurveTo",
"canvas",
"clearRect",
"clip",
"closePath",
"createConicGradient",
"createImageData",
"createLinearGradient",
"createPattern",
"createRadialGradient",
"direction",
"drawFocusIfNeeded",
"drawImage",
"ellipse",
"fill",
"fillRect",
"fillStyle",
"fillText",
"filter",
"font",
"fontKerning",
"fontStretch",
"fontVariantCaps",
"getContextAttributes",
"getImageData",
"getLineDash",
"getTransform",
"globalAlpha",
"globalCompositeOperation",
"imageSmoothingEnabled",
"imageSmoothingQuality",
"isContextLost",
"isPointInPath",
"isPointInStroke",
"letterSpacing",
"lineCap",
"lineDashOffset",
"lineJoin",
"lineTo",
"lineWidth",
"measureText",
"miterLimit",
"moveTo",
"putImageData",
"quadraticCurveTo",
"rect",
"reset",
"resetTransform",
"restore",
"rotate",
"roundRect",
"save",
"scale",
"setLineDash",
"setTransform",
"shadowBlur",
"shadowColor",
"shadowOffsetX",
"shadowOffsetY",
"stroke",
"strokeRect",
"strokeStyle",
"strokeText",
"textAlign",
"textBaseline",
"textRendering",
"transform",
"translate",
"wordSpacing",
// Fix for issue #20 : add - make sure the behavior is identical in all browsers
// by adding extra methods / properties to the description of 2D context
// to even out the property list for all browsers.
"mozCurrentTransform", // FF-prefixed
"mozCurrentTransformInverse", // FF-prefixed
"mozImageSmoothingEnabled", // FF-prefixed
"mozTextStyle" // FF-prefixed
//#32 : removed drawImageFromRect (deprecated, supported up to Chrome 40)
],
constants : {}
};
this.canvasGLContextDescription = {
properties : [
"ACTIVE_ATTRIBUTES",
"ACTIVE_TEXTURE",
"ACTIVE_UNIFORMS",
"ALIASED_LINE_WIDTH_RANGE",
"ALIASED_POINT_SIZE_RANGE",
"ALPHA",
"ALPHA_BITS",
"ALWAYS",
"ARRAY_BUFFER",
"ARRAY_BUFFER_BINDING",
"ATTACHED_SHADERS",
"BACK",
"BLEND",
"BLEND_COLOR",
"BLEND_DST_ALPHA",
"BLEND_DST_RGB",
"BLEND_EQUATION",
"BLEND_EQUATION_ALPHA",
"BLEND_EQUATION_RGB",
"BLEND_SRC_ALPHA",
"BLEND_SRC_RGB",
"BLUE_BITS",
"BOOL",
"BOOL_VEC2",
"BOOL_VEC3",
"BOOL_VEC4",
"BROWSER_DEFAULT_WEBGL",
"BUFFER_SIZE",
"BUFFER_USAGE",
"BYTE",
"CCW",
"CLAMP_TO_EDGE",
"COLOR_ATTACHMENT0",
"COLOR_BUFFER_BIT",
"COLOR_CLEAR_VALUE",
"COLOR_WRITEMASK",
"COMPILE_STATUS",
"COMPRESSED_TEXTURE_FORMATS",
"CONSTANT_ALPHA",
"CONSTANT_COLOR",
"CONTEXT_LOST_WEBGL",
"CULL_FACE",
"CULL_FACE_MODE",
"CURRENT_PROGRAM",
"CURRENT_VERTEX_ATTRIB",
"CW",
"DECR",
"DECR_WRAP",
"DELETE_STATUS",
"DEPTH_ATTACHMENT",
"DEPTH_BITS",
"DEPTH_BUFFER_BIT",
"DEPTH_CLEAR_VALUE",
"DEPTH_COMPONENT",
"DEPTH_COMPONENT16",
"DEPTH_FUNC",
"DEPTH_RANGE",
"DEPTH_STENCIL",
"DEPTH_STENCIL_ATTACHMENT",
"DEPTH_TEST",
"DEPTH_WRITEMASK",
"DITHER",
"DONT_CARE",
"DST_ALPHA",
"DST_COLOR",
"DYNAMIC_DRAW",
"ELEMENT_ARRAY_BUFFER",
"ELEMENT_ARRAY_BUFFER_BINDING",
"EQUAL",
"FASTEST",
"FLOAT",
"FLOAT_MAT2",
"FLOAT_MAT3",
"FLOAT_MAT4",
"FLOAT_VEC2",
"FLOAT_VEC3",
"FLOAT_VEC4",
"FRAGMENT_SHADER",
"FRAMEBUFFER",
"FRAMEBUFFER_ATTACHMENT_OBJECT_NAME",
"FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE",
"FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE",
"FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL",
"FRAMEBUFFER_BINDING",
"FRAMEBUFFER_COMPLETE",
"FRAMEBUFFER_INCOMPLETE_ATTACHMENT",
"FRAMEBUFFER_INCOMPLETE_DIMENSIONS",
"FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT",
"FRAMEBUFFER_UNSUPPORTED",
"FRONT",
"FRONT_AND_BACK",
"FRONT_FACE",
"FUNC_ADD",
"FUNC_REVERSE_SUBTRACT",
"FUNC_SUBTRACT",
"GENERATE_MIPMAP_HINT",
"GEQUAL",
"GREATER",
"GREEN_BITS",
"HIGH_FLOAT",
"HIGH_INT",
"IMPLEMENTATION_COLOR_READ_FORMAT",
"IMPLEMENTATION_COLOR_READ_TYPE",
"INCR",
"INCR_WRAP",
"INT",
"INT_VEC2",
"INT_VEC3",
"INT_VEC4",
"INVALID_ENUM",
"INVALID_FRAMEBUFFER_OPERATION",
"INVALID_OPERATION",
"INVALID_VALUE",
"INVERT",
"KEEP",
"LEQUAL",
"LESS",
"LINEAR",
"LINEAR_MIPMAP_LINEAR",
"LINEAR_MIPMAP_NEAREST",
"LINES",
"LINE_LOOP",
"LINE_STRIP",
"LINE_WIDTH",
"LINK_STATUS",
"LOW_FLOAT",
"LOW_INT",
"LUMINANCE",
"LUMINANCE_ALPHA",
"MAX_COMBINED_TEXTURE_IMAGE_UNITS",
"MAX_CUBE_MAP_TEXTURE_SIZE",
"MAX_FRAGMENT_UNIFORM_VECTORS",
"MAX_RENDERBUFFER_SIZE",
"MAX_TEXTURE_IMAGE_UNITS",
"MAX_TEXTURE_SIZE",
"MAX_VARYING_VECTORS",
"MAX_VERTEX_ATTRIBS",
"MAX_VERTEX_TEXTURE_IMAGE_UNITS",
"MAX_VERTEX_UNIFORM_VECTORS",
"MAX_VIEWPORT_DIMS",
"MEDIUM_FLOAT",
"MEDIUM_INT",
"MIRRORED_REPEAT",
"NEAREST",
"NEAREST_MIPMAP_LINEAR",
"NEAREST_MIPMAP_NEAREST",
"NEVER",
"NICEST",
"NONE",
"NOTEQUAL",
"NO_ERROR",
"ONE",
"ONE_MINUS_CONSTANT_ALPHA",
"ONE_MINUS_CONSTANT_COLOR",
"ONE_MINUS_DST_ALPHA",
"ONE_MINUS_DST_COLOR",
"ONE_MINUS_SRC_ALPHA",
"ONE_MINUS_SRC_COLOR",
"OUT_OF_MEMORY",
"PACK_ALIGNMENT",
"POINTS",
"POLYGON_OFFSET_FACTOR",
"POLYGON_OFFSET_FILL",
"POLYGON_OFFSET_UNITS",
"RED_BITS",
"RENDERBUFFER",
"RENDERBUFFER_ALPHA_SIZE",
"RENDERBUFFER_BINDING",
"RENDERBUFFER_BLUE_SIZE",
"RENDERBUFFER_DEPTH_SIZE",
"RENDERBUFFER_GREEN_SIZE",
"RENDERBUFFER_HEIGHT",
"RENDERBUFFER_INTERNAL_FORMAT",
"RENDERBUFFER_RED_SIZE",
"RENDERBUFFER_STENCIL_SIZE",
"RENDERBUFFER_WIDTH",
"RENDERER",
"REPEAT",
"REPLACE",
"RGB",
"RGB565",
"RGB5_A1",
"RGBA",
"RGBA4",
"SAMPLER_2D",
"SAMPLER_CUBE",
"SAMPLES",
"SAMPLE_ALPHA_TO_COVERAGE",
"SAMPLE_BUFFERS",
"SAMPLE_COVERAGE",
"SAMPLE_COVERAGE_INVERT",
"SAMPLE_COVERAGE_VALUE",
"SCISSOR_BOX",
"SCISSOR_TEST",
"SHADER_TYPE",
"SHADING_LANGUAGE_VERSION",
"SHORT",
"SRC_ALPHA",
"SRC_ALPHA_SATURATE",
"SRC_COLOR",
"STATIC_DRAW",
"STENCIL_ATTACHMENT",
"STENCIL_BACK_FAIL",
"STENCIL_BACK_FUNC",
"STENCIL_BACK_PASS_DEPTH_FAIL",
"STENCIL_BACK_PASS_DEPTH_PASS",
"STENCIL_BACK_REF",
"STENCIL_BACK_VALUE_MASK",
"STENCIL_BACK_WRITEMASK",
"STENCIL_BITS",
"STENCIL_BUFFER_BIT",
"STENCIL_CLEAR_VALUE",
"STENCIL_FAIL",
"STENCIL_FUNC",
"STENCIL_INDEX8",
"STENCIL_PASS_DEPTH_FAIL",
"STENCIL_PASS_DEPTH_PASS",
"STENCIL_REF",
"STENCIL_TEST",
"STENCIL_VALUE_MASK",
"STENCIL_WRITEMASK",
"STREAM_DRAW",
"SUBPIXEL_BITS",
"TEXTURE",
"TEXTURE0",
"TEXTURE1",
"TEXTURE10",
"TEXTURE11",
"TEXTURE12",
"TEXTURE13",
"TEXTURE14",
"TEXTURE15",
"TEXTURE16",
"TEXTURE17",
"TEXTURE18",
"TEXTURE19",
"TEXTURE2",
"TEXTURE20",
"TEXTURE21",
"TEXTURE22",
"TEXTURE23",
"TEXTURE24",
"TEXTURE25",
"TEXTURE26",
"TEXTURE27",
"TEXTURE28",
"TEXTURE29",
"TEXTURE3",
"TEXTURE30",
"TEXTURE31",
"TEXTURE4",
"TEXTURE5",
"TEXTURE6",
"TEXTURE7",
"TEXTURE8",
"TEXTURE9",
"TEXTURE_2D",
"TEXTURE_BINDING_2D",
"TEXTURE_BINDING_CUBE_MAP",
"TEXTURE_CUBE_MAP",
"TEXTURE_CUBE_MAP_NEGATIVE_X",
"TEXTURE_CUBE_MAP_NEGATIVE_Y",
"TEXTURE_CUBE_MAP_NEGATIVE_Z",
"TEXTURE_CUBE_MAP_POSITIVE_X",
"TEXTURE_CUBE_MAP_POSITIVE_Y",
"TEXTURE_CUBE_MAP_POSITIVE_Z",
"TEXTURE_MAG_FILTER",
"TEXTURE_MIN_FILTER",
"TEXTURE_WRAP_S",
"TEXTURE_WRAP_T",
"TRIANGLES",
"TRIANGLE_FAN",
"TRIANGLE_STRIP",
"UNPACK_ALIGNMENT",
"UNPACK_COLORSPACE_CONVERSION_WEBGL",
"UNPACK_FLIP_Y_WEBGL",
"UNPACK_PREMULTIPLY_ALPHA_WEBGL",
"UNSIGNED_BYTE",
"UNSIGNED_INT",
"UNSIGNED_SHORT",
"UNSIGNED_SHORT_4_4_4_4",
"UNSIGNED_SHORT_5_5_5_1",
"UNSIGNED_SHORT_5_6_5",
"VALIDATE_STATUS",
"VENDOR",
"VERSION",
"VERTEX_ATTRIB_ARRAY_BUFFER_BINDING",
"VERTEX_ATTRIB_ARRAY_ENABLED",
"VERTEX_ATTRIB_ARRAY_NORMALIZED",
"VERTEX_ATTRIB_ARRAY_POINTER",
"VERTEX_ATTRIB_ARRAY_SIZE",
"VERTEX_ATTRIB_ARRAY_STRIDE",
"VERTEX_ATTRIB_ARRAY_TYPE",
"VERTEX_SHADER",
"VIEWPORT",
"ZERO",
"activeTexture",
"attachShader",
"bindAttribLocation",
"bindBuffer",
"bindFramebuffer",
"bindRenderbuffer",
"bindTexture",
"blendColor",
"blendEquation",
"blendEquationSeparate",
"blendFunc",
"blendFuncSeparate",
"bufferData",
"bufferSubData",
"canvas",
"checkFramebufferStatus",
"clear",
"clearColor",
"clearDepth",
"clearStencil",
"colorMask",
"compileShader",
"compressedTexImage2D",
"compressedTexSubImage2D",
"copyTexImage2D",
"copyTexSubImage2D",
"createBuffer",
"createFramebuffer",
"createProgram",
"createRenderbuffer",
"createShader",
"createTexture",
"cullFace",
"deleteBuffer",
"deleteFramebuffer",
"deleteProgram",
"deleteRenderbuffer",
"deleteShader",
"deleteTexture",
"depthFunc",
"depthMask",
"depthRange",
"detachShader",
"disable",
"disableVertexAttribArray",
"drawArrays",
"drawElements",
"drawingBufferHeight",
"drawingBufferWidth",
"enable",
"enableVertexAttribArray",
"finish",
"flush",
"framebufferRenderbuffer",
"framebufferTexture2D",
"frontFace",
"generateMipmap",
"getActiveAttrib",
"getActiveUniform",
"getAttachedShaders",
"getAttribLocation",
"getBufferParameter",
"getContextAttributes",
"getError",
"getExtension",
"getFramebufferAttachmentParameter",
"getParameter",
"getProgramInfoLog",
"getProgramParameter",
"getRenderbufferParameter",
"getShaderInfoLog",
"getShaderParameter",
"getShaderPrecisionFormat",
"getShaderSource",
"getSupportedExtensions",
"getTexParameter",
"getUniform",
"getUniformLocation",
"getVertexAttrib",
"getVertexAttribOffset",
"hint",
"isBuffer",
"isContextLost",
"isEnabled",
"isFramebuffer",
"isProgram",
"isRenderbuffer",
"isShader",
"isTexture",
"lineWidth",
"linkProgram",
"makeXRCompatible",
"pixelStorei",
"polygonOffset",
"readPixels",
"renderbufferStorage",
"sampleCoverage",
"scissor",
"shaderSource",
"stencilFunc",
"stencilFuncSeparate",
"stencilMask",
"stencilMaskSeparate",
"stencilOp",
"stencilOpSeparate",
"texImage2D",
"texParameterf",
"texParameteri",
"texSubImage2D",
"uniform1f",
"uniform1fv",
"uniform1i",
"uniform1iv",
"uniform2f",
"uniform2fv",
"uniform2i",
"uniform2iv",
"uniform3f",
"uniform3fv",
"uniform3i",
"uniform3iv",
"uniform4f",
"uniform4fv",
"uniform4i",
"uniform4iv",
"uniformMatrix2fv",
"uniformMatrix3fv",
"uniformMatrix4fv",
"useProgram",
"validateProgram",
"vertexAttrib1f",
"vertexAttrib1fv",
"vertexAttrib2f",
"vertexAttrib2fv",
"vertexAttrib3f",
"vertexAttrib3fv",
"vertexAttrib4f",
"vertexAttrib4fv",
"vertexAttribPointer",
"viewport"
],
constants : {
ACTIVE_ATTRIBUTES : 35721,
ACTIVE_TEXTURE : 34016,
ACTIVE_UNIFORMS : 35718,
ALIASED_LINE_WIDTH_RANGE : 33902,
ALIASED_POINT_SIZE_RANGE : 33901,
ALPHA : 6406,
ALPHA_BITS : 3413,
ALWAYS : 519,
ARRAY_BUFFER : 34962,
ARRAY_BUFFER_BINDING : 34964,
ATTACHED_SHADERS : 35717,
BACK : 1029,
BLEND : 3042,
BLEND_COLOR : 32773,
BLEND_DST_ALPHA : 32970,
BLEND_DST_RGB : 32968,
BLEND_EQUATION : 32777,
BLEND_EQUATION_ALPHA : 34877,
BLEND_EQUATION_RGB : 32777,
BLEND_SRC_ALPHA : 32971,
BLEND_SRC_RGB : 32969,
BLUE_BITS : 3412,
BOOL : 35670,
BOOL_VEC2 : 35671,
BOOL_VEC3 : 35672,
BOOL_VEC4 : 35673,
BROWSER_DEFAULT_WEBGL : 37444,
BUFFER_SIZE : 34660,
BUFFER_USAGE : 34661,
BYTE : 5120,
CCW : 2305,
CLAMP_TO_EDGE : 33071,
COLOR_ATTACHMENT0 : 36064,
COLOR_BUFFER_BIT : 16384,
COLOR_CLEAR_VALUE : 3106,
COLOR_WRITEMASK : 3107,
COMPILE_STATUS : 35713,
COMPRESSED_TEXTURE_FORMATS : 34467,
CONSTANT_ALPHA : 32771,
CONSTANT_COLOR : 32769,
CONTEXT_LOST_WEBGL : 37442,
CULL_FACE : 2884,
CULL_FACE_MODE : 2885,
CURRENT_PROGRAM : 35725,
CURRENT_VERTEX_ATTRIB : 34342,
CW : 2304,
DECR : 7683,
DECR_WRAP : 34056,
DELETE_STATUS : 35712,
DEPTH_ATTACHMENT : 36096,
DEPTH_BITS : 3414,
DEPTH_BUFFER_BIT : 256,
DEPTH_CLEAR_VALUE : 2931,
DEPTH_COMPONENT : 6402,
DEPTH_COMPONENT16 : 33189,
DEPTH_FUNC : 2932,
DEPTH_RANGE : 2928,
DEPTH_STENCIL : 34041,
DEPTH_STENCIL_ATTACHMENT : 33306,
DEPTH_TEST : 2929,
DEPTH_WRITEMASK : 2930,
DITHER : 3024,
DONT_CARE : 4352,
DST_ALPHA : 772,
DST_COLOR : 774,
DYNAMIC_DRAW : 35048,
ELEMENT_ARRAY_BUFFER : 34963,
ELEMENT_ARRAY_BUFFER_BINDING : 34965,
EQUAL : 514,
FASTEST : 4353,
FLOAT : 5126,
FLOAT_MAT2 : 35674,
FLOAT_MAT3 : 35675,
FLOAT_MAT4 : 35676,
FLOAT_VEC2 : 35664,
FLOAT_VEC3 : 35665,
FLOAT_VEC4 : 35666,
FRAGMENT_SHADER : 35632,
FRAMEBUFFER : 36160,
FRAMEBUFFER_ATTACHMENT_OBJECT_NAME : 36049,
FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE : 36048,
FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE : 36051,
FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL : 36050,
FRAMEBUFFER_BINDING : 36006,
FRAMEBUFFER_COMPLETE : 36053,
FRAMEBUFFER_INCOMPLETE_ATTACHMENT : 36054,
FRAMEBUFFER_INCOMPLETE_DIMENSIONS : 36057,
FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT : 36055,
FRAMEBUFFER_UNSUPPORTED : 36061,
FRONT : 1028,
FRONT_AND_BACK : 1032,
FRONT_FACE : 2886,
FUNC_ADD : 32774,
FUNC_REVERSE_SUBTRACT : 32779,
FUNC_SUBTRACT : 32778,
GENERATE_MIPMAP_HINT : 33170,
GEQUAL : 518,
GREATER : 516,
GREEN_BITS : 3411,
HIGH_FLOAT : 36338,
HIGH_INT : 36341,
IMPLEMENTATION_COLOR_READ_FORMAT : 35739,
IMPLEMENTATION_COLOR_READ_TYPE : 35738,
INCR : 7682,
INCR_WRAP : 34055,
INT : 5124,
INT_VEC2 : 35667,
INT_VEC3 : 35668,
INT_VEC4 : 35669,
INVALID_ENUM : 1280,
INVALID_FRAMEBUFFER_OPERATION : 1286,
INVALID_OPERATION : 1282,
INVALID_VALUE : 1281,
INVERT : 5386,
KEEP : 7680,
LEQUAL : 515,
LESS : 513,
LINEAR : 9729,
LINEAR_MIPMAP_LINEAR : 9987,
LINEAR_MIPMAP_NEAREST : 9985,
LINES : 1,
LINE_LOOP : 2,
LINE_STRIP : 3,
LINE_WIDTH : 2849,
LINK_STATUS : 35714,
LOW_FLOAT : 36336,
LOW_INT : 36339,
LUMINANCE : 6409,
LUMINANCE_ALPHA : 6410,
MAX_COMBINED_TEXTURE_IMAGE_UNITS : 35661,
MAX_CUBE_MAP_TEXTURE_SIZE : 34076,
MAX_FRAGMENT_UNIFORM_VECTORS : 36349,
MAX_RENDERBUFFER_SIZE : 34024,
MAX_TEXTURE_IMAGE_UNITS : 34930,
MAX_TEXTURE_SIZE : 3379,
MAX_VARYING_VECTORS : 36348,
MAX_VERTEX_ATTRIBS : 34921,
MAX_VERTEX_TEXTURE_IMAGE_UNITS : 35660,
MAX_VERTEX_UNIFORM_VECTORS : 36347,
MAX_VIEWPORT_DIMS : 3386,
MEDIUM_FLOAT : 36337,
MEDIUM_INT : 36340,
MIRRORED_REPEAT : 33648,
NEAREST : 9728,
NEAREST_MIPMAP_LINEAR : 9986,
NEAREST_MIPMAP_NEAREST : 9984,
NEVER : 512,
NICEST : 4354,
NONE : 0,
NOTEQUAL : 517,
NO_ERROR : 0,
ONE : 1,
ONE_MINUS_CONSTANT_ALPHA : 32772,
ONE_MINUS_CONSTANT_COLOR : 32770,
ONE_MINUS_DST_ALPHA : 773,
ONE_MINUS_DST_COLOR : 775,
ONE_MINUS_SRC_ALPHA : 771,
ONE_MINUS_SRC_COLOR : 769,
OUT_OF_MEMORY : 1285,
PACK_ALIGNMENT : 3333,
POINTS : 0,
POLYGON_OFFSET_FACTOR : 32824,
POLYGON_OFFSET_FILL : 32823,
POLYGON_OFFSET_UNITS : 10752,
RED_BITS : 3410,
RENDERBUFFER : 36161,
RENDERBUFFER_ALPHA_SIZE : 36179,
RENDERBUFFER_BINDING : 36007,
RENDERBUFFER_BLUE_SIZE : 36178,
RENDERBUFFER_DEPTH_SIZE : 36180,
RENDERBUFFER_GREEN_SIZE : 36177,
RENDERBUFFER_HEIGHT : 36163,
RENDERBUFFER_INTERNAL_FORMAT : 36164,
RENDERBUFFER_RED_SIZE : 36176,
RENDERBUFFER_STENCIL_SIZE : 36181,
RENDERBUFFER_WIDTH : 36162,
RENDERER : 7937,
REPEAT : 10497,
REPLACE : 7681,
RGB : 6407,
RGB565 : 36194,
RGB5_A1 : 32855,
RGBA : 6408,
RGBA4 : 32854,
SAMPLER_2D : 35678,
SAMPLER_CUBE : 35680,
SAMPLES : 32937,
SAMPLE_ALPHA_TO_COVERAGE : 32926,
SAMPLE_BUFFERS : 32936,
SAMPLE_COVERAGE : 32928,
SAMPLE_COVERAGE_INVERT : 32939,
SAMPLE_COVERAGE_VALUE : 32938,
SCISSOR_BOX : 3088,
SCISSOR_TEST : 3089,
SHADER_TYPE : 35663,
SHADING_LANGUAGE_VERSION : 35724,
SHORT : 5122,
SRC_ALPHA : 770,
SRC_ALPHA_SATURATE : 776,
SRC_COLOR : 768,
STATIC_DRAW : 35044,
STENCIL_ATTACHMENT : 36128,
STENCIL_BACK_FAIL : 34817,
STENCIL_BACK_FUNC : 34816,
STENCIL_BACK_PASS_DEPTH_FAIL : 34818,
STENCIL_BACK_PASS_DEPTH_PASS : 34819,
STENCIL_BACK_REF : 36003,
STENCIL_BACK_VALUE_MASK : 36004,
STENCIL_BACK_WRITEMASK : 36005,
STENCIL_BITS : 3415,
STENCIL_BUFFER_BIT : 1024,
STENCIL_CLEAR_VALUE : 2961,
STENCIL_FAIL : 2964,
STENCIL_FUNC : 2962,
STENCIL_INDEX : 6401,
STENCIL_INDEX8 : 36168,
STENCIL_PASS_DEPTH_FAIL : 2965,
STENCIL_PASS_DEPTH_PASS : 2966,
STENCIL_REF : 2967,
STENCIL_TEST : 2960,
STENCIL_VALUE_MASK : 2963,
STENCIL_WRITEMASK : 2968,
STREAM_DRAW : 35040,
SUBPIXEL_BITS : 3408,
TEXTURE : 5890,
TEXTURE0 : 33984,
TEXTURE1 : 33985,
TEXTURE10 : 33994,
TEXTURE11 : 33995,
TEXTURE12 : 33996,
TEXTURE13 : 33997,
TEXTURE14 : 33998,
TEXTURE15 : 33999,
TEXTURE16 : 34000,
TEXTURE17 : 34001,
TEXTURE18 : 34002,
TEXTURE19 : 34003,
TEXTURE2 : 33986,
TEXTURE20 : 34004,
TEXTURE21 : 34005,
TEXTURE22 : 34006,
TEXTURE23 : 34007,
TEXTURE24 : 34008,
TEXTURE25 : 34009,
TEXTURE26 : 34010,
TEXTURE27 : 34011,
TEXTURE28 : 34012,
TEXTURE29 : 34013,
TEXTURE3 : 33987,
TEXTURE30 : 34014,
TEXTURE31 : 34015,
TEXTURE4 : 33988,
TEXTURE5 : 33989,
TEXTURE6 : 33990,
TEXTURE7 : 33991,
TEXTURE8 : 33992,
TEXTURE9 : 33993,
TEXTURE_2D : 3553,
TEXTURE_BINDING_2D : 32873,
TEXTURE_BINDING_CUBE_MAP : 34068,
TEXTURE_CUBE_MAP : 34067,
TEXTURE_CUBE_MAP_NEGATIVE_X : 34070,
TEXTURE_CUBE_MAP_NEGATIVE_Y : 34072,
TEXTURE_CUBE_MAP_NEGATIVE_Z : 34074,
TEXTURE_CUBE_MAP_POSITIVE_X : 34069,
TEXTURE_CUBE_MAP_POSITIVE_Y : 34071,
TEXTURE_CUBE_MAP_POSITIVE_Z : 34073,
TEXTURE_MAG_FILTER : 10240,
TEXTURE_MIN_FILTER : 10241,
TEXTURE_WRAP_S : 10242,
TEXTURE_WRAP_T : 10243,
TRIANGLES : 4,
TRIANGLE_FAN : 6,
TRIANGLE_STRIP : 5,
UNPACK_ALIGNMENT : 3317,
UNPACK_COLORSPACE_CONVERSION_WEBGL : 37443,
UNPACK_FLIP_Y_WEBGL : 37440,
UNPACK_PREMULTIPLY_ALPHA_WEBGL : 37441,
UNSIGNED_BYTE : 5121,
UNSIGNED_INT : 5125,
UNSIGNED_SHORT : 5123,
UNSIGNED_SHORT_4_4_4_4 : 32819,
UNSIGNED_SHORT_5_5_5_1 : 32820,
UNSIGNED_SHORT_5_6_5 : 33635,
VALIDATE_STATUS : 35715,
VENDOR : 7936,
VERSION : 7938,
VERTEX_ATTRIB_ARRAY_BUFFER_BINDING : 34975,
VERTEX_ATTRIB_ARRAY_ENABLED : 34338,
VERTEX_ATTRIB_ARRAY_NORMALIZED : 34922,
VERTEX_ATTRIB_ARRAY_POINTER : 34373,
VERTEX_ATTRIB_ARRAY_SIZE : 34339,
VERTEX_ATTRIB_ARRAY_STRIDE : 34340,
VERTEX_ATTRIB_ARRAY_TYPE : 34341,
VERTEX_SHADER : 35633,
VIEWPORT : 2978,
ZERO : 0
}
};
this.audioContextDescription = {
properties : [
"addEventListener",
"audioWorklet",
"baseLatency",
"close",
"createAnalyser",
"createBiquadFilter",
"createBuffer",
"createBufferSource",
"createChannelMerger",
"createChannelSplitter",
"createConstantSource",
"createConvolver",
"createDelay",
"createDynamicsCompressor",
"createGain",
"createIIRFilter",
"createMediaElementSource",
"createMediaStreamDestination",
"createMediaStreamSource",
"createMediaStreamTrackSource",
"createOscillator",
"createPanner",
"createPeriodicWave",
"createScriptProcessor",
"createStereoPanner",
"createWaveShaper",
"currentTime",
"decodeAudioData",
"destination",
"dispatchEvent",
"getOutputTimestamp",
"listener",
"onstatechange",
"outputLatency",
"removeEventListener",
"resume",
"sampleRate",
"state",
"suspend"
],
constants : {}
};
}
// Node.js init
if (typeof require !== 'undefined') {
module.exports = ContextDescriptor;
}
================================================
FILE: package.json
================================================
{
"name": "regpack",
"version": "5.0.4",
"description": "A packer intended for use on minified Javascript code",
"main": "regPack.js",
"bin": {
"regpack": "bin/regpack"
},
"homepage": "https://github.com/Siorki/RegPack",
"bugs" : { "url" : "https://github.com/Siorki/RegPack/issues" },
"license" : "MIT",
"repository" : "Siorki/RegPack",
"dependencies": {
"minimist": ">=1.1.0"
}
}
================================================
FILE: packerData.js
================================================
/**
* @constructor
* The PackerData class holds actual data :
* - string to pack, in the current preprocessing / compression stage
* - produced log
* It also holds internal settings set by the preprocessor
* and exploited by the packer :
* - name of the variable containing the packed code
* - generated initialization code
* - execution environment
* - ..
*
* There is one instance for each branch of input (from inputList)
* as the preprocessing may diverge : different renamings, environments ..
*
* @param name The name of the branch, summing the operations performed
* @param dataString The input string to pack
*/
function PackerData(name, dataString) {
this.name = name; // trace of the modules that were applied
this.contents = dataString; // string to pack
this.log = ''; // log, as shown in the right column in the interactive version
this.environment = ''; // execution environment for unpacked code. Can become 'with(...)'
this.interpreterCall = 'eval(_)'; // call to be performed on unpacked code.
this.wrappedInit = ''; // code inside the unpacked routine
this.initialDeclarationOffset = 0; // offset for 2D/GL context provided by shim
this.packedCodeVarName='_'; // name of the variable created to hold the packed code
this.containedStrings=[]; // all strings inside the input code
this.containedTemplateLiterals=[]; // all template literals `${...}` inside a string
this.packedStringDelimiter='"'; // ', " or ` around the packed string
this.thermalMapping=[]; // strings mapping for each compression step, including preprocessing
this.result= new Array;
}
/**
* Creates a clone of a PackerData object changing only the name.
* Copies all member variables, except those added during the packing stage(escapedInput, matchesLookup)
* Contents and log are copied as well
*
* @param packerData Original object to clone
* @param nameSuffix Suffix appended to the name of the clone
*/
PackerData.clone = function(packerData, nameSuffix) {
var clone = new PackerData;
clone.name = packerData.name + nameSuffix;
clone.contents = packerData.contents;
clone.log = packerData.log;
clone.environment = packerData.environment;
clone.interpreterCall = packerData.interpreterCall;
clone.wrappedInit = packerData.wrappedInit;
clone.initialDeclarationOffset = packerData.initialDeclarationOffset;
clone.packedCodeVarName = packerData.packedCodeVarName;
clone.containedStrings = packerData.containedStrings.slice();
clone.containedTemplateLiterals = packerData.containedTemplateLiterals.slice();
clone.packedStringDelimiter = packerData.packedStringDelimiter;
clone.thermalMapping=packerData.thermalMapping.slice();
clone.result = new Array;
return clone;
}
// Node.js init
if (typeof require !== 'undefined') {
module.exports = PackerData;
}
================================================
FILE: patternViewer.js
================================================
/**
* @constructor
* The PatternViewer class renders the original code
* into a DHTML view highlighting the patterns from the packer.
*
*
* @param name The name of the branch, summing the operations performed
* @param dataString The input string to pack
*/
function PatternViewer ()
{
}
PatternViewer.prototype = {
/**
* Produces an HTML render of the patterns used by the packer.
* The rendered <div> is not added to the page HTML.
*
* @param unpackedCode The original unpacked code (after preprocessing)
* @param matchesLookup Pattern set from RegPack
* @return A <div> object showing the patterns in the code
*
*/
render : function(unpackedCode, matchesLookup)
{
// First, create arrays storing whether each character is
// the beginning or the end of one or several pattern
var patternBegin = [], patternEnd = []; // imbrication level for each character
for (var i=0; i<=unpackedCode.length; ++i) {
patternBegin.push(0);
patternEnd.push(0);
}
for (var j=0; j<matchesLookup.length;++j) {
if (matchesLookup[j].token) {
var pattern = matchesLookup[j].originalString;
var offset = -pattern.length;
while ((offset=unpackedCode.indexOf(pattern, pattern.length+offset))>-1) {
++patternBegin[offset];
++patternEnd[pattern.length+offset];
}
}
}
var output = document.createElement("pre");
output.setAttribute("class","topLevel");
var divStack = [ ];
var currentNodeContents = "";
var currentNode = output;
var currentDepth = 0;
// #42 : some patterns may contain the very end of the string
// (stored in patternEnd[last character + 1] ), so we iterate one extra step to close the matching <div>s
for (var offset=0; offset<=unpackedCode.length; ++offset)
{
for (var stepsDown=0; stepsDown<patternEnd[offset]; ++stepsDown) {
// unstacking : close the span
if (currentNodeContents != "") {
currentNode.appendChild(document.createTextNode(currentNodeContents));
currentNodeContents = "";
}
currentNode = divStack.pop();
--currentDepth;
}
for (var stepsUp=0; stepsUp<patternBegin[offset]; ++stepsUp) {
// stacking spans
if (currentNodeContents != "") {
currentNode.appendChild(document.createTextNode(currentNodeContents));
currentNodeContents = "";
}
divStack.push(currentNode);
var newSpan = document.createElement("span");
newSpan.setAttribute("class","depth"+Math.min(9, ++currentDepth));
currentNode.appendChild(newSpan);
currentNode = newSpan;
}
// #42 : protect against overflow on that last character
if (offset<unpackedCode.length) {
currentNodeContents+=unpackedCode[offset];
}
}
// Append the last characters that are not part of a pattern
if (currentNodeContents != "")
currentNode.appendChild(document.createTextNode(currentNodeContents));
return output;
}
}
// Node.js exports (for non-regression tests only)
if (typeof require !== 'undefined') {
module.exports = PatternViewer;
}
================================================
FILE: regPack.html
================================================
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>RegPack v5.0.4</title>
<style type="text/css">
#options {
border:1px solid gray;
padding:5px;
}
.best {
box-shadow: 0px 0px 12px 1px rgb(0, 192, 0) inset;
}
b {
color: black;
}
b.bestMessage {
text-shadow: 1px 1px 1px rgb(0, 192, 0)
}
div#output{
display:none;
}
div#thermalColumn{
visibility:hidden;
}
div.dock {
display:flex;
overflow:hidden;
}
div.dockControl {
height:20px;
margin:1px;
border:solid #888 1px;
box-sizing: border-box;
background-image:linear-gradient(#aaa,#ddd,#eee);
text-align:center;
text-shadow:#fff 1px 1px;
color:#444;
line-height:19px;
}
div.dockControl:hover {
background-image:linear-gradient(#adf,#def,#eff);
}
div.dockControl:active {
background-image:linear-gradient(#6ce,#bdf,#cef);
}
div.column {
flex:1;
height:15em;
}
div.textBox {
width:50%;
padding:1px;
border:1px solid;
border-color:#888 #ccc #ccc #888;
margin: 1px 0px 1px 0px;
box-sizing: border-box;
display:inline-block;
vertical-align: top;
min-height:8em;
}
div#thermalView {
width:100%;
padding:1px;
border:1px solid;
border-color:#888 #ccc #ccc #888;
margin: 1px 0px 1px 0px;
box-sizing: border-box;
vertical-align: top;
height:14em;
overflow-y:scroll;
}
textarea {
width:50%;
margin: 1px 0px 1px 0px;
box-sizing: border-box;
border-radius:2px;
border:1px solid;
border-color:#888 #ccc #ccc #888;
vertical-align: top;
word-break: break-all;
}
textarea.source {
box-shadow: 0px 0px 8px 1px rgb(0, 128, 255) inset;
width:100%;
height:17em;
}
pre.topLevel {
margin:1px;
padding-top:1px;
white-space: pre-wrap;
word-break: break-all;
font: 1em/1.4 monospace;
}
span {
white-space: pre-wrap;
word-break: break-all;
box-shadow: 0px 0px 0px 1px rgba(0, 0, 0, 0.1) inset;
}
span.depth1 {
background-color:#DFD;
}
span.depth2 {
background-color:#AEA;
}
span.depth3 {
background-color:#7D7;
}
span.depth4 {
background-color:#9C6;
}
span.depth5 {
background-color:#AB5;
}
span.depth6 {
background-color:#CA4;
}
span.depth7 {
background-color:#E93;
}
span.depth8 {
background-color:#F71;
}
span.depth9 {
background-color:#F40;
}
span.thermal0 {
background-color:#64679d;
}
span.thermal1 {
background-color:#5884cc;
}
span.thermal2 {
background-color:#6cc3d4;
}
span.thermal3 {
background-color:#66e18b;
}
span.thermal4 {
background-color:#a6ec66;
}
span.thermal5 {
background-color:#f1fc66;
}
span.thermal6 {
background-color:#fcd966;
}
span.thermal7 {
background-color:#fcac66;
}
span.thermal8 {
background-color:#f26464;
}
span.thermal9 {
background-color:#ce6464;
}
span.thermal10 {
background-color:#ab6464;
}
span.thermal11 {
background-color:#886464;
}
</style>
</head>
<body>
<div class="dock">
<div id="inputColumn" class="column">
<b>Original source</b>
<br><textarea id="originalString" class="source"></textarea>
</div><div id="thermalColumn" class="column">
<span class="thermal0">0+ </span><span class="thermal1">1+ </span><span class="thermal2">2+ </span><span class="thermal3">3+ </span><span class="thermal4">4+ </span><span class="thermal5">5+ </span><span class="thermal6">6+ </span><span class="thermal7">7+ </span><span class="thermal8">8+ </span><span class="thermal9">9+ </span><span class="thermal10">10+ </span><span class="thermal11">11+ </span>
bits/original byte
<div id="thermalView"></div>
</div>
</div>
<div class="dockControl" id="inputDockControl">▼</div><br>
<fieldset>
Attempt method hashing and renaming for
<input type="checkbox" name="paramOHash2D" id="paramOHash2D" checked="checked"/>2D canvas context
<input type="checkbox" name="paramOHashWebGL" id="paramOHashWebGL" checked="checked"/>WebGL canvas context
<input type="checkbox" name="paramOHashAudio" id="paramOHashAudio" checked="checked"/>AudioContext
<input type="checkbox" name="paramOHashAllObjects" id="paramOHashAllObjects" checked="checked"/>any object
<br><input type="checkbox" name="paramOGlobalDefined" id="paramOGlobalDefined" checked="checked"/> Assume global variable <input type="text" size=6 value="c" id="paramOGlobalVariable" /> is a <select id="paramOGlobalType">
<option value=0 selected>2D canvas context</option>
<option value=1>WebGL canvas context</option>
</select> <i>(as in js1k shim)</i>
<br><input type="checkbox" name="paramOReassignVars" id="paramOReassignVars" checked="checked"/> Reassign variable names to produce consecutive character blocks,
except for variables <input type="text" value="a b c d g" id="paramOExcludedVars" />
<br><input type="checkbox" name="paramUseES6" id="paramUseES6" checked="checked"/> Enable ES6 features.
</fieldset>
<fieldset>
<legend><i>Options impacting performance</i></legend>
<input type="checkbox" name="paramOWithMath" id="paramOWithMath"/> Encapsulate with(Math)
<br><input type="checkbox" name="paramOWrapInSetInterval" id="paramOWrapInSetInterval"/> Refactor to run with setInterval(). Use variable
<input type="text" size=4 id="paramOTimeVariable" /> for time <i>(leave empty to assign one. Time variable should be zero on the first loop and nonzero afterwards)</i>.
</fieldset>
<fieldset>
<legend><b class="bestMessage">RegPack v5.0.4</b></legend>
<button id="packAction">Pack</button>
Score = <input type="text" size=6 value=1 id="paramFGain" />
*gain + <input type="text" size=6 value=0 id="paramFLength" />
*length + <input type="text" size=6 value=0 id="paramFCopies" />
*copies
Tiebreaker = <select id="paramFTiebreaker">
<option value=1 selected>longest string first (Js Crush)</option>
<option value=-1 >most copies first (First Crush)</option>
</select>
<br><i>Default settings match built-in formulas for both JS Crush and First Crush. 2/1/0 sometimes achieve better results.</i>
</fieldset>
<br>
<div id="output">
<div id="preprocessed">
<b id="stage0Title">Preprocessed : </b><b id="stage0Message"></b>
<br><div id="stage0Output" class="textBox"></div><textarea rows=12 id="stage0Details"></textarea><br>
</div>
<div id="crushed">
<b id="stage1Title">Crushed : </b><b id="stage1Message"></b><input type="checkbox" id="stage1Base64"/>base64
<br><textarea rows=12 id="stage1Output"></textarea><textarea rows=12 id="stage1Details"></textarea><br>
</div>
<div id="packed">
<b id="stage2Title">RegPack'ed: </b><b id="stage2Message"></b><input type="checkbox" id="stage2Base64"/>base64
<br><textarea rows=12 id="stage2Output"></textarea><textarea rows=12 id="stage2Details"></textarea><br>
</div>
</div>
<script src="contextDescriptor_browser.js"></script>
<script src="stringHelper.js"></script>
<script src="packerData.js"></script>
<script src="shapeShifter.js"></script>
<script src="regPack.js"></script>
<script src="patternViewer.js"></script>
<script src="thermalViewer.js"></script>
<script>
var outputCode = [];
function doRegPack() {
for (var j=0; j<3; ++j) {
document.getElementById("stage"+j+"Output").value = "";
document.getElementById("stage"+j+"Details").value = ""
}
// Implementation for issue #33 : append the code to the URL
var input = document.getElementById("originalString").value;
var urlArray = window.location.href.split("#code=");
window.location.href = urlArray[0]+"#code="+StringHelper.getInstance().unicodeToBase64(input);
// Get rid of comments and empty lines
input = input.replace(/([\r\n]|^)\s*\/\/.*|[\r\n]+\s*/g,'');
var options = {
withMath : document.getElementById("paramOWithMath").checked!="",
hash2DContext : document.getElementById("paramOHash2D").checked!="",
hashWebGLContext : document.getElementById("paramOHashWebGL").checked!="",
hashAudioContext : document.getElementById("paramOHashAudio").checked!="",
hashAllObjects : document.getElementById("paramOHashAllObjects").checked!="",
contextVariableName : document.getElementById("paramOGlobalDefined").checked!=""?document.getElementById("paramOGlobalVariable").value:false,
contextType : parseInt(document.getElementById("paramOGlobalType").value),
reassignVars : document.getElementById("paramOReassignVars").checked!="",
varsNotReassigned : document.getElementById("paramOExcludedVars").value,
crushGainFactor : parseFloat(document.getElementById("paramFGain").value),
crushLengthFactor : parseFloat(document.getElementById("paramFLength").value),
crushCopiesFactor : parseFloat(document.getElementById("paramFCopies").value),
crushTiebreakerFactor : parseInt(document.getElementById("paramFTiebreaker").value),
wrapInSetInterval : document.getElementById("paramOWrapInSetInterval").checked!="",
timeVariableName : document.getElementById("paramOTimeVariable").value,
useES6 : document.getElementById("paramUseES6").checked!=""
};
var originalLength = packer.getByteLength(input);
var inputList = packer.runPacker(input, options);
var methodCount = inputList.length;
var patternViewer = new PatternViewer;
var thermalViewer = new ThermalViewer;
var bestMethod=0, bestStage=0, bestCompression=1e8;
for (var i=0; i<methodCount; ++i) {
var packerData = inputList[i];
for (var j=0; j<4; ++j) {
var output = (j==0 ? packerData.contents : packerData.result[j-1][1]);
var packedLength = packer.getByteLength(output);
if (packedLength < bestCompression) {
bestCompression = packedLength;
bestMethod = i;
bestStage = j;
}
}
}
// show the output boxes (hidden beforehand, they collapsed to near-zero size and this was not pretty)
document.getElementById("output").style.display = "block";
var bestOutput = inputList[bestMethod];
document.getElementById("stage0Message").innerHTML = resultMessage(originalLength, packer.getByteLength(bestOutput.contents));
var outputField = document.getElementById("stage0Output");
while (outputField.lastChild) {
outputField.removeChild(outputField.lastChild);
}
outputField.appendChild(patternViewer.render(bestOutput.contents, bestOutput.matchesLookup));
document.getElementById("stage0Details").value = outputCode[0] = bestOutput.log;
document.getElementById("stage0Details").style.height = outputField.offsetHeight+"px";
for (var j=1; j<3; ++j) {
var stage = j<2 ? j-1 : (packer.getByteLength(bestOutput.result[1][1])< packer.getByteLength(bestOutput.result[2][1]) ? 1 : 2);
outputCode[j] = bestOutput.result[stage][1];
var outputLength = packer.getByteLength(outputCode[j]);
document.getElementById("stage"+j+"Title").setAttribute("class", bestCompression==outputLength ? "bestMessage" : "");
document.getElementById("stage"+j+"Message").innerHTML = resultMessage(originalLength, outputLength);
document.getElementById("stage"+j+"Message").setAttribute("class", bestCompression==outputLength ? "bestMessage" : "");
document.getElementById("stage"+j+"Base64").onclick = function(index) {
return function() {
// #52 : use StringHelper implementation instead of btoa() to handle Unicode characters > 255
document.getElementById("stage"+index+"Output").value = this.checked ? StringHelper.getInstance().unicodeToBase64(outputCode[index]) : outputCode[index];
};
} (j);
document.getElementById("stage"+j+"Base64").onclick(); // set the textarea contents, raw or base64
// highlight best result in green
document.getElementById("stage"+j+"Output").setAttribute("class", bestCompression==outputLength ? "best" : "");
document.getElementById("stage"+j+"Details").value = bestOutput.result[stage][2];
}
// clear the thermal view, draw and show it
document.getElementById("thermalColumn").style.visibility="visible";
var thermalViewPanel = document.getElementById("thermalView");
while (thermalViewPanel.firstChild) {
thermalViewPanel.removeChild(thermalViewPanel.firstChild);
}
var completeMapping = bestOutput.thermalMapping; // thermal map from preprocessing
if (bestStage > 0) {
// thermal map from packing
completeMapping = completeMapping.concat(bestOutput.result[bestStage-1][3]);
}
thermalViewPanel.appendChild(thermalViewer.render(input, completeMapping));
}
document.getElementById("packAction").onclick=function()
{
doRegPack();
}
document.addEventListener("DOMContentLoaded", function(event) {
// Fix for issue #12 : disable AudioContext hashing if the browser does not support it
if (typeof AudioContext == "undefined") {
hashAudioCheckbox = document.getElementById("paramOHashAudio");
hashAudioCheckbox.checked = false;
hashAudioCheckbox.disabled = true;
}
// Implementation for issue #33 : retrieve the original code from the URL, if present, and store in into input box
var urlArray = window.location.href.split("#code=");
if (urlArray.length == 2) {
document.getElementById("originalString").value = StringHelper.getInstance().base64ToUnicode(urlArray[1]);
}
// Following #26, add a dock option for the first row containing input and thermal view
document.getElementById("inputDockControl").docked=true;
document.getElementById("inputDockControl").onclick = function(event) {
this.docked = !this.docked;
var originalStringView = document.getElementById("originalString");
var originalStringViewHeight="17em";
if (!this.docked) {
originalStringView.style.height = "auto";
originalStringViewHeight = (originalStringView.scrollHeight)+"px"
}
originalStringView.style.height = originalStringViewHeight;
originalStringView.style.overflowY = (this.docked ? "scroll" : "hidden");
document.getElementById("thermalView").style.overflowY = this.docked ? "scroll" : "auto";
document.getElementById("thermalView").style.height = this.docked ? "14em" : "auto";
document.getElementById("thermalColumn").style.height = this.docked ? "15em" : "auto";
document.getElementById("inputColumn").style.height = this.docked ? "15em" : "auto";
this.firstChild.data = this.docked ? "\u25bc" : "\u25b2";
}
});
</script>
</body>
</html>
================================================
FILE: regPack.js
================================================
// Node.js : module shapeShifter defines ShapeShifter class (preprocessor)
if (typeof require !== 'undefined') {
var StringHelper = require('./stringHelper');
var ShapeShifter = require('./shapeShifter');
}
function resultMessage(sourceSize, resultSize)
{
var message = sourceSize+'B';
var prefix = (resultSize>sourceSize?"+":"");
if (sourceSize!=resultSize) {
message+=' to '+resultSize+'B ('+prefix+(resultSize-sourceSize)+'B, '+prefix+(((resultSize-sourceSize)/sourceSize*1e4|0)/100)+'%)'
}
return message;
}
/**
* Entry point when running RegPack from node.js, wrapper for the packer
* It performs the packing, then returns the best compressed (autoextractible) string
*
* @param input A string containing the program to pack
* @param options An object detailing the different options for the preprocessor and packer
* @return A string containing the shortest compressed form of the input
*/
function cmdRegPack(input, options) {
var originalLength = packer.getByteLength(input);
var inputList = packer.runPacker(input, options);
var methodCount = inputList.length;
var bestMethod=0, bestStage = 0, shortestLength=1e8;
for (var i=0; i<methodCount; ++i) {
var packerData = inputList[i];
for (var j=0; j<4; ++j) {
var output = (j==0 ? packerData.contents : packerData.result[j-1][1]);
var packedLength = packer.getByteLength(output);
if (packedLength < shortestLength) {
shortestLength = packedLength;
bestMethod = i;
bestStage = j;
}
}
}
var bestOutput = inputList[bestMethod];
var bestVal = (bestStage==0 ? bestOutput.contents : bestOutput.result[bestStage-1][1]);
var mes = resultMessage(originalLength, shortestLength);
//console.log("packer:", inputList[bestMethod]);
console.warn("stats:", mes);
return bestVal;
}
/**
* @constructor
* The class RegPack wraps all the features from the tool
* It contains the main entry point : pack()
* It also implements the compression routines
*/
function RegPack() {
this.stringHelper = StringHelper.getInstance();
this.preprocessor = new ShapeShifter();
}
RegPack.prototype = {
/**
* Main entry point for RegPack
* @param input A string containing the program to pack
* @param options An object detailing the different options for the preprocessor and packer
* @return An array of PackerData, each containing the code packed with different settings from the preprocessor
*/
runPacker : function(input, options) {
var default_options = {
withMath : false,
hash2DContext : false,
hashWebGLContext : false,
hashAudioContext : false,
hashAllObjects : false,
contextVariableName : false,
contextType : parseInt(0),
reassignVars : true,
varsNotReassigned : ['a', 'b', 'c'],
crushGainFactor : parseFloat(2),
crushLengthFactor : parseFloat(1),
crushCopiesFactor : parseFloat(0),
crushTiebreakerFactor : parseInt(1),
wrapInSetInterval : false,
timeVariableName : "",
useES6 : true
};
for (var opt in default_options) {
if (!(opt in options)) {
options[opt] = default_options[opt];
}
}
var inputList = this.preprocessor.preprocess(input, options);
for (var inputIndex=0; inputIndex < inputList.length; ++inputIndex)
{
var currentData = inputList[inputIndex];
// first stage : configurable crusher
var output = this.findRedundancies(currentData, options);
currentData.result.push(output);
// second stage : convert token string to regexp
output = this.packToRegexpCharClass(currentData, options);
currentData.result.push(output);
// third stage : try a negated regexp instead
output = this.packToNegatedRegexpCharClass(currentData);
currentData.result.push(output);
}
return inputList;
},
/**
* Returns the total byte length of a string "as is" (with no further escaping)
* 1 for ASCII char
* 3 for Unicode (UTF-8)
* Issue #5 : final size when featuring unicode characters
*
* @param inString the string to measure
* @return the UTF-8 length of the string, in bytes
*/
getByteLength : function (inString)
{
return encodeURI(inString).replace(/%../g,'i').length;
},
/**
* Returns the byte length of a string after escaping
* \ costs 2 bytes
* All other characters unchanged
* Issue #85 : suboptimal compression of \ sequences
*
* @param inString the string to measure
* @return the UTF-8 length of the string, including added escape characters, in bytes
*/
getEscapedByteLength : function (inString)
{
return this.getByteLength(inString.replace(/\\/g,'\\\\'));
},
/**
* First stage : apply the algorithm common to First Crush and JS Crush
* Adds member variables to packerData :
* - matchesLookup : array containing matches and inner details
*
* @param packerData A PackerData structure holding the input string and setup
* @param options Preprocessing and packing options (tiebreaker, score factors)
* @return array [length, packed string, log]
*/
findRedundancies : function(packerData, options) {
var packedString = packerData.contents;
packerData.matchesLookup = [];
var transform = [];
var details='';
// Allowed tokens : everything in the ASCII range except
// - 0 and 127 (excluded from loop)
// - any character present in the input string
// - LF(10) and CR(13), not allowed in code nor as tokens
// - \ (92) since it requires escaping
// New since #55, "(34) and '(39) are allowed as long as they are not the delimiter for the string
var delimiterCode = packerData.packedStringDelimiter.charCodeAt(0);
var tokenList = [];
for(var tokenCode=126 ; tokenCode>0 ; --tokenCode) {
if (tokenCode!=10 && tokenCode!=13 && tokenCode!=92 && tokenCode!= delimiterCode) {
var token = String.fromCharCode(tokenCode);
if (packedString.indexOf(token)==-1) {
tokenList.push(token);
}
}
}
// Identify matches - search all string space for possible matches (all strings present more than once)
var matches = {};
var found=true; // stop as soon as no substring of length t is found twice
for(var t=2;found;++t) {
found=false;
for(i=0;i<packedString.length-t;++i) {
var beginCode = packedString.charCodeAt(i);
var endCode = packedString.charCodeAt(i+t-1);
// #50 : if the first character is a low surrogate (second character of a surrogate pair
// representing an astral character), skip it - we cannot have it begin the string
// and thus break the pair
// Same issue if the last character is a high surrogate (first in surrogate pair).
if ((beginCode<0xDC00 || beginCode>0xDFFF)
&& (endCode<0xD800 || endCode>0xDBFF)) {
var j=i;
var pattern = packedString.substr(i,t);
if(!matches[pattern]) {
if(~(j=packedString.indexOf(pattern,j+t)))
{
found=true;
for(matches[pattern]=1;~j;matches[pattern]++)
{
j=packedString.indexOf(pattern,j+t);
}
}
}
}
}
}
// Main loop : replace matches by tokens, one every iteration
var tokensInUse = '';
for(var tokenIndex = 0; tokenIndex < tokenList.length ; ++tokenIndex) {
var token = tokenList[tokenIndex];
// find the string with the best score (combination of gain, length, copies, and tiebreaker)
var bestLength = 0, bestValue = 0, bestMatch = 0, bestGain = 0, bestCopies = 0;
for(i in matches){
var stringLength = this.getEscapedByteLength(i);
var copies=matches[i];
var gain=copies*stringLength-copies-stringLength-2; // -1 used in JS Crush performs replacement with zero gain
value=options.crushGainFactor*gain+options.crushLengthFactor*stringLength+options.crushCopiesFactor*copies;
if(gain>0) {
if(value>bestValue||bestValue==value&&(gain>bestGain||gain==bestGain&&(options.crushTiebreakerFactor*copies>options.crushTiebreakerFactor*bestCopies))) {
// copies>bestCopies JsCrush, copies<bestCopies First Crush
bestGain=gain, bestCopies=copies, bestMatch=i, bestValue=value, bestLength=stringLength;
}
}
}
if(bestGain<1)
break;
// apply the compression to the string
packedString = this.stringHelper.matchAndReplaceAll(packedString, false, bestMatch, token, "", token+bestMatch, 0, transform);
//packedString=packedString.split(bestMatch).join(token)+token+bestMatch;
packerData.matchesLookup.push({token:token, string:bestMatch, originalString:bestMatch, depends:'', usedBy:'', gain:bestGain, copies:bestCopies, len:bestLength, score:bestValue, cleared:false, newOrder:9999});
tokensInUse=token+tokensInUse;
details+=token.charCodeAt(0)+"("+token+") : val="+bestValue+", gain="+bestGain+", N="+bestCopies+", str = "+bestMatch+"\n";
// update the other matches in case the selected one is a substring thereof
// #92 : moved at this point of the loop, since the initial pattern identification is now done before the loop
// Also performs the final update for #47 so that the remaining matches are known
// for the packer stage, which may use more tokens than the crusher
var newMatches={};
for(var oldPattern in matches) {
var newPattern = oldPattern.split(bestMatch).join(token);
var newLength = newPattern.length;
if (newLength > 1) { // do not keep the strings already replaced by a token
var offset = packedString.indexOf(newPattern);
if (offset >= 0) {
var matchCount = 0;
while (offset >= 0) {
++matchCount;
offset = packedString.indexOf(newPattern,offset+newLength);
}
newMatches[newPattern]=matchCount;
}
}
}
matches = newMatches;
}
var firstLine = true;
for(i in matches){
var stringLength = this.getEscapedByteLength(i);
var copies=matches[i];
var gain=copies*stringLength-copies-stringLength-2;
if (gain>0) {
if (firstLine) {
details += "\n--- Potential gain, but not enough tokens ---\n";
firstLine = false;
}
var value=options.crushGainFactor*gain+options.crushLengthFactor*stringLength+options.crushCopiesFactor*copies;
details+="..( ) : val="+value+", gain="+gain+", N="+copies+", str = "+i+"\n";
packerData.matchesLookup.push({token:"", string:i, originalString:i, depends:'', usedBy:'', gain:gain, copies:copies, len:stringLength, score:value, cleared:false, newOrder:9999});
}
}
// Implementation for #48 : show the patterns that are "almost" gains
firstLine = true;
for(i in matches){
var stringLength = this.getEscapedByteLength(i);
var copies=matches[i];
var gain=copies*stringLength-copies-stringLength-2;
var gainPlusOne=(copies+1)*stringLength-(copies+1)-stringLength-2;
if (gain<=0 && gainPlusOne>0) {
if (firstLine) {
details += "\n--- One extra occurrence needed for a gain --\n";
firstLine = false;
}
value=options.crushGainFactor*gainPlusOne+options.crushLengthFactor*stringLength+options.crushCopiesFactor*copies;
details+=" val="+value+", gain="+gain+"->"+gainPlusOne+" (+"+(gainPlusOne-gain)+"), N="+copies+", str = "+i+"\n";
}
}
var loopInitCode = ';for(i in G=', loopMemberCode = 'G[i]';
if (options.useES6) {
// ES6 : use 'for .. of' construct, which iterates on values, not keys => gain six bytes
loopInitCode = ';for(i of';
loopMemberCode = 'i';
}
// escape the backslashes present in the code
packedString = this.stringHelper.matchAndReplaceAll(packedString, false, '\\', '\\\\', '', '', 0, transform);
// escape the occurrences of the string delimiter present in the code
packedString = this.stringHelper.matchAndReplaceAll(packedString, false, packerData.packedStringDelimiter, '\\'+packerData.packedStringDelimiter, "", "", 0, transform);
//var packedString = packedString.replace(new RegExp(packerData.packedStringDelimiter,"g"),'\\'+packerData.packedStringDelimiter);
// and put everything together
var unpackBlock1 = packerData.packedCodeVarName+'='+packerData.packedStringDelimiter;
var unpackBlock2 = packerData.packedStringDelimiter
+loopInitCode+packerData.packedStringDelimiter+tokensInUse+packerData.packedStringDelimiter
+')with('+packerData.packedCodeVarName+'.split('+loopMemberCode+'))'
+packerData.packedCodeVarName+'=join(pop(';
var unpackBlock3 = '));';
var envMapping = [ { inLength : packedString.length, outLength : packedString.length, complete : false},
{ chapter : 1,
rangeIn : [0, packedString.length],
rangeOut : [0, unpackBlock1.length + unpackBlock2.length + unpackBlock3.length]
} ];
transform.push(envMapping);
var output = unpackBlock1 + packedString + unpackBlock2 + packerData.wrappedInit + unpackBlock3
+ packerData.environment + packerData.interpreterCall;
return [this.getByteLength(output), output, details, transform];
},
/**
* Clears a match from matchesLookup for dependencies in the PackerData
* - removes the corresponding token from the use list of other matches
* - sets the "cleared" flag to true
*
* @param packerData A PackerData structure holding the input string and setup, including the matches array
* @param matchIndex index of the match to clear
*/
clear : function(packerData, matchIndex) {
var oldToken = packerData.matchesLookup[matchIndex].token;
for (var j=0;j<packerData.matchesLookup.length;++j) {
packerData.matchesLookup[j].usedBy = packerData.matchesLookup[j].usedBy.split(oldToken).join("");
}
packerData.matchesLookup[matchIndex].cleared=true;
},
/**
* Second stage : extra actions required to reduce the token string to a RegExp
*
* Needs and modifies the matchesLookup array inside the parameter packerData
*
* @param packerData A PackerData structure holding the input string and setup
* @param options Preprocessing and packing options (tiebreaker, score factors)
* @return array [length, packed string, log]
*/
packToRegexpCharClass : function(packerData, options)
{
var details = '';
var transform = [];
// First, re-expand the packed strings so that they no longer contain any compression token
// since we will be storing them in a different order.
// Use this step to establish a dependency graph (compressed strings containing other compressed strings)
for (var i=0;i<packerData.matchesLookup.length;++i) {
for (var j=0; j<packerData.matchesLookup.length;++j) {
if (packerData.matchesLookup[i].token && packerData.matchesLookup[j].originalString.indexOf(packerData.matchesLookup[i].token)>-1) {
packerData.matchesLookup[j].originalString = packerData.matchesLookup[j].originalString.split(packerData.matchesLookup[i].token).join(packerData.matchesLookup[i].originalString);
}
if (i!=j && packerData.matchesLookup[j].originalString.indexOf(packerData.matchesLookup[i].originalString)>-1) {
packerData.matchesLookup[j].depends += packerData.matchesLookup[i].token;
packerData.matchesLookup[i].usedBy += packerData.matchesLookup[j].token;
}
}
}
/** debug only
for (i=0; i<packerData.matchesLookup.length; ++i) {
c=packerData.matchesLookup[i];
details += c.token.charCodeAt(0)+"("+c.token+") str1 = "+c.string+" str2 = "+c.originalString+" depends = /"+c.depends+"/\n";
}
*/
// Define the token list that will be used by ordering blocks, from the largest to the smallest
// Blocks are 4 or more contiguous characters : "ABCDE" can be shortened to "A-E" in the RegExp
// The gain from RegPack v1 over the original JSCrush and First Crush comes essentially from that.
var tokenList = [];
var firstInLine = -1;
for(i=1;i<127;++i) {
var token = String.fromCharCode(i);
// Allowed tokens : everything in the ASCII range except
// - 0 and 127 (excluded from loop)
// - any character present in the code
// - LF(10) and CR(13), not allowed in code nor as tokens, skipped in ranges
// New since #47, \(92) and ](93) which need escaping in character class, are allowed as tokens.
// New since #55, "(34) and '(39), as long as they are not the delimiter for the string
if (i!=packerData.packedStringDelimiter.charCodeAt(0) && packerData.contents.indexOf(token)==-1) {
if (firstInLine ==-1) {
firstInLine = i;
}
} else {
if (firstInLine >-1) {
// do not start a block with CR nor LF, as the first character of the block
// needs to be written to the regexp and those are not writable (or require escaping)
if (firstInLine == 10 || firstInLine == 13) {
++firstInLine;
}
var lastInLine = i-1;
// for the same reason, do not end a block with CR nor LF (watch out, the end of the block is the index before i)
if (i==11 || i==14) {
--lastInLine;
}
if (lastInLine>=firstInLine) { // skip if there is only CR or LF in the range
var tokenCount = lastInLine-firstInLine+1;
var range = this.stringHelper.writeRangeToRegexpCharClass(firstInLine, lastInLine);
var containsBackslash = (firstInLine<=92 && i>92);
tokenList.push({first:firstInLine, last:lastInLine, count:tokenCount, cost:range.length, oneByteTokenCount:tokenCount-(containsBackslash?1:0)});
}
firstInLine = -1;
}
}
}
if (firstInLine >-1) {
var range = this.stringHelper.writeRangeToRegexpCharClass(firstInLine, i-1);
tokenList.push({first:firstInLine, last:i-1, count:i-firstInLine, cost:range.length, oneByteTokenCount:i-firstInLine-(firstInLine<=92?1:0)});
}
// Reorder the block list. #47 introduces escaped characters, making the order a bit more complex :
// - longest blocks (as in largest token count) first
// - when tied for length, non escaped characters first (shortest representation in char class)
// - when tied again, readable characters (32-127) first
tokenList.sort(function(a,b) {
return 10*b.oneByteTokenCount-b.cost+b.first/1000- (10*a.oneByteTokenCount-a.cost+a.first/1000);
});
var costOneTokens = [], costTwoTokens = [];
for (var tokenLine=0; tokenLine<tokenList.length; ++tokenLine) {
for (var i=tokenList[tokenLine].first; i<=tokenList[tokenLine].last; ++i) {
if (i!=10 && i!=13) {
if (i==92) {
costTwoTokens.push(i);
} else {
costOneTokens.push(i);
}
}
}
}
// The first range must not start with ^, otherwise it will be interpreted as negated char class
// Two solutions :
// - remove the ^ from the range, starting with the next character
// - swap the range with the next one, putting it into second position
// Removal is done here if the conditions match (
// Swapping is done later, as removal of \ and ] may expose the character ^ at the beginning of a range
if (tokenList[0].first == 94) {
if (packerData.matchesLookup.length < tokenList[0].count || tokenList.length==1) {
// If we have enough tokens in the first range without the ^, remove it
// Do the same if we only have one range
tokenList[0].cost = this.stringHelper.writeRangeToRegexpCharClass(++tokenList[0].first, ++tokenList[0].last).length;
--tokenList[0].count;
--tokenList[0].oneByteTokenCount;
}
}
details +="\n";
details +="Token ranges\n"
details +="------------\n";
for (var i=0; i<tokenList.length;++i) {
details += this.stringHelper.writeRangeToRegexpCharClass(tokenList[i].first, tokenList[i].last);
details += " score = " + ( 10*tokenList[i].oneByteTokenCount-tokenList[i].cost+tokenList[i].first/1000) + "\n";
}
details +="\n";
// Then, flatten the dependency graph into a line. The new compression order starts
// with the strings that are not used within another strings (usually the longer ones)
// and ends by the strings not depending on others. The reason for that is that the
// unpacking is performed LIFO and must begin by independent strings for RegExp-related reasons
// (match is done on any token in the RegExp, meaning that the first instance must be
// the separator, not another token that would be included in the string)
// Pack again by replacing the strings by the tokens, in the new compression order
// In case there are two or more candidates (not used by other strings), the same
// compression scoring is used as in the first stage.
var availableTokens = costOneTokens.concat(costTwoTokens);
var tokensRemaining = true; // true while there are tokens remaining
var gainsRemaining = true; // true while there is at least one match with a positive gain (that will shorten the output if packed)
packerData.tokenCount = 0; // total number of tokens used. Will be less than packerData.matchesLookup.length at the end if any negatives are found
var regPackOutput = packerData.contents;
for (var i=0 ; i<packerData.matchesLookup.length && tokensRemaining && gainsRemaining ; ++i) {
var tokenCode = availableTokens[packerData.tokenCount];
var tokenCost = this.stringHelper.getCharacterLength(tokenCode); // 2 for \ , 1 for anything else
var matchIndex=-1, bestScore=-999, bestGain=-1, bestCount=0, negativeCleared = false;
for (var j=0; j<packerData.matchesLookup.length;++j) {
if (packerData.matchesLookup[j].usedBy=="" && !packerData.matchesLookup[j].cleared) {
var count=0;
for (var index=regPackOutput.indexOf(packerData.matchesLookup[j].originalString, 0); index>-1; ++count) {
index=regPackOutput.indexOf(packerData.matchesLookup[j].originalString, index+1);
}
var gain = count*(packerData.matchesLookup[j].len-tokenCost)-packerData.matchesLookup[j].len-2*tokenCost;
var score = options.crushGainFactor*gain+options.crushLengthFactor*packerData.matchesLookup[j].len+options.crushCopiesFactor*count;
if (gain>=0) {
if (score>bestScore||score==bestScore&&(gain>bestGain||gain==bestGain&&(options.crushTiebreakerFactor*count>options.crushTiebreakerFactor*bestCount))) {
// R>N JsCrush, R<N First Crush
bestGain=gain,bestCount=count,matchIndex=j,bestScore=score;
}
} else {
// found a negative. The matching string may no longer be packed (if anything, match count will decrease, not increase)
// so we clear it (ie remove it from the dependency chain). This in turns allows strings it uses to be packed,
// otherwise their "usedBy" field would contain the negative and they could never be packed.
// Clearing a negative introduces a bias, since some strings that were in order before it could have been
// considered for compression, but they were not because they were "usedBy" the negative.
// The comparison is useless : do not compress for this iteration of i
this.clear(packerData, j);
negativeCleared = true;
}
}
}
if (!negativeCleared) { // skip the compression step if we had a negative
if (matchIndex>-1) {
// a string was chosen, replace it with the current token
var matchedString = packerData.matchesLookup[matchIndex].originalString;
packerData.matchesLookup[matchIndex].newOrder = packerData.tokenCount;
var token = String.fromCharCode(tokenCode);
details+=token.charCodeAt(0)+"("+token+"), gain="+bestGain+", N="+bestCount+", str = "+matchedString+"\n";
regPackOutput = this.stringHelper.matchAndReplaceAll(regPackOutput, false, matchedString, token, matchedString+token, "", 0, transform);
// remove dependencies on chosen string/token
this.clear(packerData, matchIndex);
// define the replacement token
++packerData.tokenCount;
if (packerData.tokenCount >= availableTokens.length) {
tokensRemaining = false; // bail out early
details+="Out of tokens\n";
}
} else { // remaining strings, but no gain : skip them and end the loop
for (var j=0; j<packerData.matchesLookup.length;++j) {
if (!packerData.matchesLookup[j].cleared) {
details += "skipped str = "+packerData.matchesLookup[j].originalString+"\n";
}
}
gainsRemaining = false;
}
}
}
// Map tokens used to actual ranges (lines)
var tokenLine = 0; // 0-based index of current token line (block)
var tokenIndex = 0; // 1-based index of current token in current line
var unusedBackslash = availableTokens[availableTokens.length-1]==92 && packerData.tokenCount<availableTokens.length;
if (packerData.tokenCount >= availableTokens.length) { // all available tokens in use (no replacement performed)
tokenLine = tokenList.length -1 ;
tokenIndex = tokenList[tokenList.length-1].count;
} else {
var lastTokenUsed = availableTokens[packerData.tokenCount-1];
var lineFound = false;
while (!lineFound && tokenLine < tokenList.length) {
// #83 : if a range starts or end in \, and it is not actually used, replace it with the previous or next character
if (unusedBackslash && tokenList[tokenLine].first == 92) { // remove unused \ at the beginning of a range
++tokenList[tokenLine].first;
--tokenList[tokenLine].count;
}
if (unusedBackslash && tokenList[tokenLine].last == 92) { // remove unused \ at the end of a range
--tokenList[tokenLine].last;
--tokenList[tokenLine].count;
}
if (lastTokenUsed >= tokenList[tokenLine].first && lastTokenUsed <= tokenList[tokenLine].last) {
// no need to consider that 2-byte token \ can be in the middle of a range
// since it is used last, and we would be in the case where packerData.tokenCount exceeds costOneTokens.length
lineFound = true;
tokenIndex = lastTokenUsed - tokenList[tokenLine].first + 1;
} else {
++tokenLine;
}
}
}
// Safeguard, should never happen (i.e. last token use is not found in ranges)
if (tokenLine >= tokenList.length) {
details += "Exception : token out of range\nFinal check : failed";
return [-1, "", details, transform];
}
// #47 introduces escaped characters (2 bytes instead of 1) as tokens
// Ranges with such a character at the beginning or end thus cost one extra byte to define
// If the last range used has leftover tokens (more tokens available than needed),
// we use those tokens at no cost to replace the escaped ones.
// for instance, last range is A-E but only used up to C, and we have range W-\\ before
// by substituting D for \\, we end up with [W-[A-D] which is one byte shorter than [W-\\A-C]
// #83 amends that by forcing \ to be always the last token to be considered
// Since it is the last one, there are no leftovers to replace it
// The only possible replaced token is thus ]
// First identify if we have leftover tokens in the last range
var remainingTokens = tokenList[tokenLine].count - tokenIndex;
// Force the last range to its actual length - in case it ends with a \ or ] but not all tokens are used
tokenList[tokenLine].last -= remainingTokens;
tokenList[tokenLine].count = tokenIndex;
if (remainingTokens > 0) {
var tokensToReplace = [];
// then look for escaped character ] (93) at the beginning or end of a range
for (var i=0; i<=tokenLine; ++i) {
if (tokenList[i].first == 93) {
tokensToReplace.push({rangeIndex : i , atBeginning : true, count : 1});
} else if (tokenList[i].last == 93) {
tokensToReplace.push({rangeIndex : i , atBeginning : false, count : 1});
}
}
// The only token to replace is ] (93), but we kept the code that handles multiple tokens
for (var i=0; i<tokensToReplace.length; ++i) {
if (remainingTokens >= tokensToReplace[i].count) {
// substitute as many tokens as required (1 or 2)
for (var j=0; j<tokensToReplace[i].count; ++j) {
// substitute the token in the already packed string
++tokenIndex;
--remainingTokens;
var currentRange = tokenList[tokensToReplace[i].rangeIndex];
var oldToken = String.fromCharCode(tokensToReplace[i].atBeginning ? currentRange.first : currentRange.last);
var newToken = String.fromCharCode(++tokenList[tokenLine].last);
regPackOutput = regPackOutput.split(oldToken).join(newToken);
details += oldToken.charCodeAt(0)+"("+oldToken+") replaced by "+newToken.charCodeAt(0)+"("+newToken+")\n";
// shift beginning or end of the former range
--currentRange.count;
++tokenList[tokenLine].count;
if (tokensToReplace[i].atBeginning) {
++currentRange.first;
// if the shift exposes an unused \ at the beginning of the range, shift again
if (unusedBackslash && currentRange.first==92) {
++currentRange.first;
--currentRange.count;
}
} else {
--currentRange.last;
// if the shift exposes an unused \ at the end of the range, shift again
if (unusedBackslash && currentRange.last==92) {
--currentRange.last;
--currentRange.count;
}
}
// if we are adding from the end of the same range we are removing tokens from, shift beginning while keeping length constant
if (tokensToReplace[i].rangeIndex == tokenLine) {
--tokenIndex;
}
}
}
}
}
// The former step may have removed ] and \ at the beginning of a range, exposing ^ as first character
// If the first range starts with ^, the character class will be misinterpreted as a negative char class
// Swap the first two ranges to solve that issue.
if (tokenList[0].first == 94 && tokenList.length>1) {
var newFirstRange = tokenList.splice(1, 1);
tokenList.unshift(newFirstRange[0]);
}
// build the character class
var tokenString = this.stringHelper.writeBlocksToRegexpCharClass(tokenList.slice(0, tokenLine+1));
// escape the backslashes in the compressed code (from original code or added as token)
// #65 : do it now and not earlier so it applies on token \ as well
var checkedString = this.stringHelper.matchAndReplaceAll(regPackOutput, false, '\\', '\\\\', '', '', 0, transform);
// escape the occurrences of the string delimiter present in the code
checkedString = this.stringHelper.matchAndReplaceAll(checkedString, false, packerData.packedStringDelimiter, '\\'+packerData.packedStringDelimiter, "", "", 0, transform);
// and add the unpacking code to the compressed string
var unpackBlock1 = 'for('+packerData.packedCodeVarName+'='+packerData.packedStringDelimiter;
var unpackBlock2 = packerData.packedStringDelimiter+';G=/['+tokenString+']/.exec('+packerData.packedCodeVarName
+');)with('+packerData.packedCodeVarName+'.split(G))'+packerData.packedCodeVarName+'=join(shift(';
var unpackBlock3 = '));';
var envMapping = [ { inLength : checkedString.length, outLength : checkedString.length, complete : false},
{ chapter : 1,
rangeIn : [0, checkedString.length],
rangeOut : [0, unpackBlock1.length + unpackBlock2.length + unpackBlock3.length]
} ];
transform.push(envMapping);
regPackOutput = unpackBlock1 + checkedString + unpackBlock2 + packerData.wrappedInit + unpackBlock3
+ packerData.environment + packerData.interpreterCall;
var resultSize = this.getByteLength(regPackOutput);
// check that unpacking the string yields the original code
details+="------------------------\nFinal check : ";
checkedString = checkedString.replace(new RegExp('\\\\'+packerData.packedStringDelimiter,'g'), packerData.packedStringDelimiter);
checkedString = checkedString.replace(/\\\\/g, '\\');
var regToken = new RegExp("["+tokenString+"]","");
for(var token="" ; token = regToken.exec(checkedString) ; ) {
var k = checkedString.split(token);
checkedString = k.join(k.shift());
}
var success = (checkedString == packerData.contents);
details+=(success ? "passed" : "failed")+".\n";
return [resultSize, regPackOutput, details, transform];
},
/**
* Returns true if the character is not allowed in a RegExp char class or as a token (cannot be inserted per se, requires a sequence instead)
* Forbidden characters are LF, CR, 127
* ' and " are allowed since #55, unless they are the delimiter for the packed string
*
* @param ascii The ASCII or Unicode value of the character
* @return true if the matching character is forbidden as token, false if it is allowed
*/
isForbiddenCharacter : function(ascii)
{
return ascii==10||ascii==13||ascii==127;
},
/**
* Returns the number of forbidden characters in the interval [first-last]
* Characters : same as in isForbiddenCharacter(), and the packed string delimiter
* However, the packed string delimiter is forbidden as a token too
*
* @see isForbiddenCharacter
* @param first : ASCII code of the first character in the interval, inclusive
* @param last : ASCII code of the last character in the interval, inclusive
* @param delimiterCode : ASCII code of the packed string delimiter (counts as forbidden)
* @return the number of forbidden characters in the interval
*/
countForbiddenCharacters : function (first, last, delimiterCode)
{
var count=0;
for (var i=first; i<=last; ++i) {
count+=(this.isForbiddenCharacter(i)||i==delimiterCode)?1:0;
}
return count;
},
/**
* Third stage : build the shortest negated character class regular expression
* (a char class beginning with a ^, such as [^A-D] which comprises everything but characters A, B, C and D)
* @param packerData A PackerData structure holding the input string and setup
* @return array [length, packed string, log]
*/
packToNegatedRegexpCharClass : function(packerData)
{
// Build a list of characters used inside the string (as ranges)
// characters not in the list can be
// - forbidden as tokens (LF, CR, 127) although these are allowed in the string too
// - used as compression tokens
// - neither used as compression tokens (if there are leftovers) nor in the string
// those can be included in the RegExp without affecting the output
var details = '';
var transform = [];
var usedCharacters = [];
var forbiddenCharacters = [];
var firstInLine = -1;
var availableCharactersCount = 0;
for(i=1;i<128;++i) {
var token = String.fromCharCode(i);
if (packerData.contents.indexOf(token)>-1) {
if (firstInLine ==-1) {
firstInLine = i;
}
} else {
if (firstInLine >-1) {
usedCharacters.push({first:firstInLine, last:i-1, size:Math.min(i-firstInLine,3)});
firstInLine = -1;
}
if (this.isForbiddenCharacter(i) || i==packerData.packedStringDelimiter.charCodeAt(0)) {
forbiddenCharacters.push(token);
} else {
++availableCharactersCount;
}
}
}
if (firstInLine >-1) {
usedCharacters.push({first:firstInLine, last:i-1, size:Math.min(i-firstInLine,3)});
}
// Issue #2 : unicode characters handling
var inputContainsUnicode = false;
for (i=0;i<packerData.contents.length&&!inputContainsUnicode;++i) {
inputContainsUnicode = inputContainsUnicode || (packerData.contents.charCodeAt(i)>127);
}
if (inputContainsUnicode) {
// non-ASCII as a whole block. Those characters are not allowed as tokens,
// and the block can be merged later to save bytes
usedCharacters.push({first:128, last:65535, size:3});
}
details = availableCharactersCount + " available tokens, "+packerData.tokenCount+" needed.\n"
var regExpString = "";
for (i in usedCharacters) {
j=usedCharacters[i];
var rangeString = this.stringHelper.writeRangeToRegexpCharClass(j.first, j.last);
// Fix for issue #31 : if a token line consists in a single "-",
// add it at the beginning of the character class instead of appending it
if (j.size==1 && j.first==45) { // 45 is '-'
regExpString=rangeString+currentCharClass;
} else {
regExpString+=rangeString;
}
}
details+="initial expression : "+regExpString+"\n";
// Now, shorten the regexp by sacrificing some characters that will not be used as tokens.
// The second stage yielded the actual number of tokens required.
// The initial regexp lists all characters present in the string to compress. Since it is
// used with an initial negation ^, it will match on all other characters.
// Characters are split into used by the strings, tokens, and unused
// This step iterates on the RegExp, merging ranges to reduce its length.
// Characters between the ranges are included, thus lost as tokens.
// For instance, [A-K] is shorter than [A-CG-K] but loses D,E,F as potential tokens
// The process is repeated while there are enough tokens left.
var margin = availableCharactersCount - packerData.tokenCount;
var delimiterCode = packerData.packedStringDelimiter.charCodeAt(0);
// #59 : start with merging all ranges with cost 0
for (blockIndex=0; blockIndex<usedCharacters.length-1; ++blockIndex) {
var currentBlock = usedCharacters[blockIndex];
var nextBlock = usedCharacters[blockIndex+1];
var cost = nextBlock.first - currentBlock.last - 1 - this.countForbiddenCharacters(currentBlock.last+1, nextBlock.first-1, delimiterCode);
if (cost < .5) { // equal zero, as it cannot be negative => merge
var gain = currentBlock.size+nextBlock.size-3;
currentBlock.last=nextBlock.last;
currentBlock.size=3;
usedCharacters.splice(1+blockIndex, 1);
// log the improvement
details +="gain "+gain+" for 0, margin = "+margin+", ";
var currentCharClass = this.stringHelper.writeBlocksToRegexpCharClass(usedCharacters);
details += currentCharClass+"\n";
}
}
// #59 : now test every possibility to bridge gaps by merging ranges
// the variable bridgeMap represents, in binary, the gaps that will be bridged in the current round
// bit at 0 = leave gap, bit at 1 = bridge by merging neighboring ranges
// If that removes more tokens than our margin allows, ignore that candidate and continue to next round
// Otherwise, keep the shortest expression of all rounds
var gapCount = usedCharacters.length - 1;
var bestRegExpLength = 127; // length can never exceed 1 byte per character in the ASCII range
var bestRegExpString = "";
var bestBlockMap = [];
details += gapCount+" gaps, testing "+(1<<gapCount)+" solutions.\n";
for (var bridgeMap = 0; bridgeMap< (1<<gapCount) ; ++bridgeMap) {
var mergedBlocks = [];
var totalCost = 0;
var blockBegin = usedCharacters[0].first;
for (var blockIndex = 0; blockIndex < gapCount; ++blockIndex) {
var bridgeNext = (bridgeMap & (1<<blockIndex));
var currentBlock = usedCharacters[blockIndex];
var nextBlock = usedCharacters[blockIndex+1];
if (bridgeNext) {
// if we bridge a gap, keep track of its cost ( = the potential tokens that are lost in the merge)
var cost = nextBlock.first - currentBlock.last - 1 - this.countForbiddenCharacters(currentBlock.last+1, nextBlock.first-1, delimiterCode);
totalCost += cost;
} else {
// otherwise, we end a block : add it to the block list, then open a new one
mergedBlocks.push( { first: blockBegin, last: currentBlock.last });
blockBegin = nextBlock.first;
}
}
mergedBlocks.push( { first: blockBegin, last: usedCharacters[usedCharacters.length-1].last });
if (totalCost <= margin) {
// the solution has enough tokens left : now compare it to the current shortest
var regExpString = this.stringHelper.writeBlocksToRegexpCharClass(mergedBlocks);
if (regExpString.length < bestRegExpLength) {
bestRegExpLength = regExpString.length;
bestRegExpString = regExpString;
bestBlockMap = mergedBlocks.slice();
details +="solution at "+bestRegExpLength+", margin = "+(margin-totalCost)+", "+bestRegExpString+"\n";
}
}
}
bestRegExpString = "^"+bestRegExpString;
bestBlockMap.push({first:128, last:128}); // upper boundary for the loop, increase to use multibyte characters as tokens
var tokenString = "";
var charIndex = 1;
for (var i=0;i<bestBlockMap.length;++i)
{
while (charIndex<bestBlockMap[i].first) {
if (!this.isForbiddenCharacter(charIndex) && charIndex!=packerData.packedStringDelimiter.charCodeAt(0)) {
tokenString+=String.fromCharCode(charIndex);
}
++charIndex;
}
charIndex = 1+bestBlockMap[i].last;
}
details+= "tokens = "+tokenString+" ("+tokenString.length+")\n";
// use the same matches order as in the second stage
packerData.matchesLookup.sort(function(a,b) {return a.newOrder-b.newOrder; });
var thirdStageOutput = packerData.contents;
// and perform the replacement using the token string as listed above
for (var i=0;i<packerData.tokenCount && i<tokenString.length;++i)
{
var matchedString = packerData.matchesLookup[i].originalString;
var token = tokenString[i];
details+=token.charCodeAt(0)+"("+token+"), str = "+matchedString+"\n";
thirdStageOutput = this.stringHelper.matchAndReplaceAll(thirdStageOutput, false, matchedString, token, matchedString+token, "", 0, transform);
//thirdStageOutput = matchedString+token+thirdStageOutput.split(matchedString).join(token);
}
// escape the backslashes in the compressed code (from original code or added as token)
// #65 : do it now and not earlier so it applies on token \ as well
var checkedString = this.stringHelper.matchAndReplaceAll(thirdStageOutput, false, '\\', '\\\\', '', '', 0, transform);
// escape the occurrences of the string delimiter present in the code
checkedString = this.stringHelper.matchAndReplaceAll(checkedString, false, packerData.packedStringDelimiter, '\\'+packerData.packedStringDelimiter, "", "", 0, transform);
// add the unpacking code to the compressed string
var unpackBlock1 = 'for('+packerData.packedCodeVarName+'='+packerData.packedStringDelimiter;
var unpackBlock2 = packerData.packedStringDelimiter+';G=/['+bestRegExpString+']/.exec('+packerData.packedCodeVarName
+');)with('+packerData.packedCodeVarName+'.split(G))'+packerData.packedCodeVarName+'=join(shift(';
var unpackBlock3 = '));';
var envMapping = [ { inLength : checkedString.length, outLength : checkedString.length, complete : false},
{ chapter : 1,
rangeIn : [0, checkedString.length],
rangeOut : [0, unpackBlock1.length + unpackBlock2.length + unpackBlock3.length]
} ];
transform.push(envMapping);
thirdStageOutput = unpackBlock1 + checkedString + unpackBlock2 + packerData.wrappedInit + unpackBlock3
+ packerData.environment + packerData.interpreterCall;
var resultSize = this.getByteLength(thirdStageOutput);
// check that unpacking the string yields the original code
details+="------------------------\nFinal check : ";
checkedString = checkedString.replace(new RegExp('\\\\'+packerData.packedStringDelimiter,'g'), packerData.packedStringDelimiter);
checkedString = checkedString.replace(/\\\\/g, '\\');
var regToken = new RegExp("["+bestRegExpString+"]","");
for(var token="" ; token = regToken.exec(checkedString) ; ) {
var k = checkedString.split(token);
checkedString = k.join(k.shift());
}
var success = (checkedString == packerData.contents);
details+=(success ? "passed" : "failed")+".\n";
return [resultSize, thirdStageOutput, details, transform];
}
};
var packer = new RegPack();
// Node.js setup
if (typeof require !== 'undefined') {
module.exports = {
RegPack: RegPack,
packer: packer,
cmdRegPack: cmdRegPack
};
}
================================================
FILE: shapeShifter.js
================================================
// Node.js init
if (typeof require !== 'undefined') {
var PackerData = require("./packerData");
var StringHelper = require("./stringHelper");
var ContextDescriptor = require("./contextDescriptor_node");
}
/**
* @constructor
* ShapeShifter is the preprocessor used by RegPack.
* It shortens the code, without compression, by running those algorithms on the original code according to settings
* - puts the code in "with(Math)" environment
* - wraps the main code loop into a call to setInterval()
* - hashes method / property names for 2D / GL / Audio contexts
* - renames the variable to optimize compression
*/
function ShapeShifter() {
this.contextDescriptor = new ContextDescriptor();
this.stringHelper = StringHelper.getInstance();
// hashing functions for method and property renaming
this.hashFunctions = [
["w[x]", 0, 2, 0, 0, function(w,x,y) { return w[x]; } ],
["w[x]+w[y]", 0, 2, 0, 20, function(w,x,y) { return w[x]+w[y]; } ],
["w[x]+w.length", 0, 2, 0, 0, function(w,x,y) { return w[x]+w.length; } ],
["w[x]+w[w.length-1]", 0, 2, 0, 0, function(w,x,y) { return w[x]+w[w.length-1]; } ],
["w[x]+[w[y]]", 0, 2, 3, 20, function(w,x,y) { return w[x]+[w[y]]; } ],
["w[0]+w[x]+[w[y]]", 0, 20, 3, 20, function(w,x,y) { return w[0]+w[x]+[w[y]]; } ],
["w[1]+w[x]+[w[y]]", 0, 20, 3, 20, function(w,x,y) { return w[1]+w[x]+[w[y]]; } ],
["w[2]+w[x]+[w[y]]", 0, 20, 3, 20, function(w,x,y) { return w[2]+w[x]+[w[y]]; } ],
["w[0]+[w[x]]+[w[y]]", 3, 20, 3, 20, function(w,x,y) { return w[0]+[w[x]]+[w[y]]; } ],
["w.substr(x,3)", 0, 2, 0, 0, function(w,x,y) { return w.substr(x,3); } ]
];
}
ShapeShifter.prototype = {
/**
* Preparation stage : attempt to rehash the methods from canvas context
* Produces a pair of hashed/not hashed strings for each option
* so each selected "splitter" flag doubles the number of tests.
* Creates a list with all the combinations to feed to the packer, one at a time.
* "with Math()" option is applied on all entries if selected (does not create a pair)
*
* @param input : the string to pack
* @param options : preprocessing options, as follows
* - withMath : true if the option "Pack with(Math)" was selected, false otherwise
* - hash2DContext : (splitter) true if the option "Hash and rename 2D canvas context" was selected, false otherwise
* - hashWebGLContext : (splitter) true if the option "Hash and rename WebGL canvas context" was selected, false otherwise
* - hashAudioContext : (splitter) true if the option "Hash and rename AudioContext" was selected, false otherwise
* - hashAllObjects : (splitter) true if the option "Hash and rename properties for any object" was selected, false otherwise
* - contextVariableName : a string representing the variable holding the context if the "assume context" option was selected, false otherwise
* - contextType : the context type (0=2D, 1=WebGL) if the "assume context" option was selected, irrelevant otherwise
* - reassignVars : true to globally reassign variable names
* - varsNotReassigned : string or array listing all protected variables (whose name will not be modified)
* - wrapInSetInterval : true to wrap the unpacked code in a setInterval() call instead of eval()
* - timeVariableName : if "setInterval" option is set, the variable to use for time (zero on first loop, nonzero after)
* - useES6 : true to add ES6 constructs to the code, false otherwise
* @return an array of PackerData, representing all combinations for splitter flags
*/
preprocess : function(input, options) {
// Transform the list of protected variables into a boolean array[128] (true = protected).
// Same information but easier to access by algorithms.
// Only perform it once on an option set : unit tests reuse the same options for several calls
if (!options.varsNotReassignedRaw) {
options.varsNotReassignedRaw = options.varsNotReassigned;
options.varsNotReassigned = [];
for (var i=0; i<128; ++i) { // replace by Array.fill() once ES6 is supported
options.varsNotReassigned.push(false);
}
for (var i=0; i<options.varsNotReassignedRaw.length; ++i) {
var ascii = options.varsNotReassignedRaw[i].charCodeAt(0);
if (ascii>=0 && ascii<128 && this.isCharAllowedInVariable(ascii)) {
options.varsNotReassigned[ascii] = true;
}
}
}
// #74 , #96 : minification now performed inside the preprocessor, not as a hidden step in the main entry point
var minifiedInput = this.minify(input);
var inputData = new PackerData ('', minifiedInput);
if (options.withMath) {
// call module : Define environment
this.defineEnvironment(inputData);
}
var inputList = [ inputData ];
if (options.wrapInSetInterval) {
// call module : wrap with setInterval
this.refactorToSetInterval(inputData, options);
} else {
// map the bytes of the default interpreter call "eval(_)" to the entire code
var envMapping = [ { inLength : inputData.contents.length, outLength : inputData.contents.length, complete : false},
{ chapter : 4,
rangeIn : [0, inputData.contents.length],
rangeOut : [0, inputData.interpreterCall.length]
} ];
inputData.thermalMapping.push(envMapping);
}
// Hash and rename methods of the 2d canvas context
// - method hashing only
// - method and property
// then store the results in the inputList
if (options.hash2DContext) {
for (var count=inputList.length, i=0; i<count; ++i) {
var newBranches = this.preprocess2DContext(inputList[i], options);
inputList.push(...newBranches); // ES6 syntax : concatenate arrays
}
}
// for WebGL contexts, there are three options
// - hash and replace method names only
// - as above, plus replace the definitions of constants with their values (magic numbers)
// - hash and replace method and property names
if (options.hashWebGLContext) {
for (var count=inputList.length, i=0; i<count; ++i) {
var newBranches = this.preprocessWebGLContext(inputList[i], options);
inputList.push(...newBranches); // ES6 syntax : concatenate arrays
}
}
// for AudioContexts, method hashing only
if (options.hashAudioContext) {
for (var count=inputList.length, i=0; i<count; ++i) {
var newBranches = this.preprocessAudioContext(inputList[i], options.varsNotReassigned);
inputList.push(...newBranches); // ES6 syntax : concatenate arrays
}
}
// #86 : for all objects, using a variable as container for the method or property name
if (options.hashAllObjects) {
for (var count=inputList.length, i=0; i<count; ++i) {
var newBranchData = this.hashPropertyNamesAsVariables(inputList[i], options);
if (newBranchData[0]) { // true if at least one property was assigned to a variable
inputList.push(newBranchData[1]);
}
}
}
inputList[0].name="unhashed";
for (var i=0; i<inputList.length; ++i) {
this.identifyStrings(inputList[i], false);
// call module : quote strings
this.quoteStrings(inputList[i], options);
if (options.reassignVars) {
// call module : reassign variables
this.reassignVariableNames(inputList[i], options);
}
}
return inputList;
},
/**
* Performs a light minification on the input string
*
* Removes C-style comments
* Removes C++ one-line style comments
* Removes spaces, tabs, CR, CR LF
* Replaces ;} with }
*
* Exception : any string defined inside the program is not modified
*
* @param input : the string (program) to minify
* @return the same, minified
*/
minify : function(input) {
var output = "";
var previousCharCode = 0;
var closingSequence = "";
var inRemovedSequence = false, inString = false;
for (let i=0; i<input.length; ++i) {
let currentChar = input[i];
let nextCharCode = i<input.length-1 ? input.charCodeAt(i+1) : 0;
let testForSequenceEnd = true;
if (closingSequence == "") {
// no sequence in progress, detect a beginning
testForSequenceEnd = false;
if (currentChar == "'" || currentChar == '"' || currentChar == '`') {
// #96 : leave string contents untouched, no whitespace removal
closingSequence = currentChar;
inString = true;
}
if (input.substr(i,2) == "//") { // C++ style single-line comment
closingSequence = "\n";
inRemovedSequence = true;
}
if (input.substr(i,2) == "/*") { // C multi-line comment
closingSequence = "*/";
inRemovedSequence = true;
}
if (input.substr(i,4) == "<!--") { // XML multi-line comment
closingSequence = "-->";
inRemovedSequence = true;
}
}
if (!inRemovedSequence) {
let isBlank = "\n\r\t ".indexOf(currentChar) > -1;
// all non-blanks are copied
// #74 : so are all blanks between expressions or keywords
// multiple blanks between expressions are shortened, only the last one is kept
let doCopy = (!isBlank) || (this.isCharAllowedInVariable(previousCharCode) && this.isCharAllowedInVariable(nextCharCode));
//console.log(currentChar.charCodeAt(0)+" ("+currentChar+") "+doCopy);
if (doCopy || inString) { // #96 : no change inside a string
output+=currentChar;
previousCharCode = currentChar.charCodeAt(0);
}
}
if (testForSequenceEnd) {
if (input.substr(i,closingSequence.length) == closingSequence)
{
i+= closingSequence.length-1;
closingSequence = "";
inRemovedSequence = false;
inString = false;
}
}
}
// Remove any semicolon located right before a block ends
output = output.replace(/;}/g, "}");
return output;
},
/**
* Modifies the environment execution of the unpacked code, wrapping it into with(Math).
* Removes all references to Math. in the input code
* @param inputData (in/out) PackerData structure containing the code to refactor and setup
* @return nothing. Result of refactoring is stored in parameter inputData.
*/
defineEnvironment : function(inputData) {
inputData.environment = 'with(Math)';
var envMapping = { chapter : 2, rangeOut : [0, inputData.environment.length] };
inputData.contents = this.stringHelper.matchAndReplaceAll(inputData.contents, false, 'Math.', '', '', '', envMapping, inputData.thermalMapping);
},
/**
* Rewrites the input code so that it can entirely be executed inside
* a setInterval() loop without prior initialization.
*
* Detects the function that is currently called through setInterval()
* and strips it. Wraps the code before that function into a if sequence
* at the beginning of the loop, that will only be run once.
*
* The method makes use of a "time" variable that usually controls
* the flow of execution/rendering, and is increased at each loop.
* It needs to be zero on the first run to trigger the initialization
* sequence, then nonzero on the subsequent runs.
*
* Output (refactored code and log) is stored in parameter inputData.
* Setup for the unpacking routine is also changed in the same object.
*
* @param inputData (in/out) PackerData structure containing the code to refactor and setup
* @param options options set, see below for use details
* @return nothing. Result of refactoring is stored in parameter inputData.
* Options used are :
* - timeVariableName : the variable containing time, or empty string to allocate one
* - varsNotReassigned : boolean array[128], true to avoid altering variable
*
*/
refactorToSetInterval : function(inputData, options) {
var input = inputData.contents;
var output = input; // initialized from input, in case we bail out early
var timeVariableName = options.timeVariableName;
var varsNotReassigned = options.varsNotReassigned;
var details = "----------- Refactoring to run with setInterval() ---------------\n";
var timeVariableProvided = true;
// implementation for #44 : match arrow function syntax (new in ES6)
// regular expression matches pre-ES5 syntax : function(params){...}
var loopMatch = input.match(/setInterval\(function\(([\w\d.=,]*)\){/);
var functionDeclaration = "function(";
if (!loopMatch) { // regular expression matches ES6 syntax : (params)=>{...}
loopMatch = input.match(/setInterval\(\(([\w\d.=,]*)\)=>{/);
functionDeclaration = ")=>";
}
if (!loopMatch) { // regular expression matches ES6 syntax : one_param=>{...}
loopMatch = input.match(/setInterval\(([\w\d.]*)(=>){/);
functionDeclaration = "=>";
}
if (loopMatch) {
var initCode = input.substr(0, loopMatch.index);
// remove any trailing comma or semicolon
if (initCode[initCode.length-1]==';' || initCode[initCode.length-1]==',') {
initCode = input.substr(0, initCode.length-1);
}
details += "First "+loopMatch.index+" bytes moved to conditional sequence.\n";
// parameters of the function passed to setInterval() : extract default values
// The regex matches a variable declaration, without value assignment (no "="),
// at the beginning, end, or between two commas
var paramsCode = loopMatch[1];
var paramsExp = /(^|,)[A-Za-z$_][\w$_]*(,|$)/;
var paramsMatch = paramsExp.exec(paramsCode);
while (paramsMatch && paramsMatch[0] != "") {
// if the variable is between two commas, keep one : ",k," becomes ","
var keptCommas = (paramsMatch[1]+paramsMatch[2]).length>1 ? "," : "";
paramsCode = paramsCode.substr(0, paramsMatch.index)+keptCommas+paramsCode.substr(paramsMatch.index+paramsMatch[0].length);
paramsMatch = paramsExp.exec(paramsCode);
}
// end by a semicolon if there are any initializations that will be added to the main loop code
paramsCode += (paramsCode != "" ? ";" : "");
if (timeVariableName=="") {
timeVariableProvided = false;
timeVariableName = this.allocateNewVariable(inputData, options);
details += "Using variable "+timeVariableName+" for time.\n";
}
// Strip the declaration of the time variable from the init code,
// as it will be defined in the unpacking routine instead.
var timeDefinitionBegin = initCode.length;
var timeDefinitionEnd = timeDefinitionBegin;
var timeDefinitionExp = new RegExp("(^|[^\\w$])"+timeVariableName+"=","g");
var timeDefinitionMatch=timeDefinitionExp.exec(initCode);
if (timeDefinitionMatch) {
timeDefinitionBegin = timeDefinitionMatch.index+timeDefinitionMatch[1].length;
timeDefinitionEnd = timeDefinitionBegin+2;
// Check if we can strip more than "t=" depending on what comes before and after :
// - Brackets means no : the declaration is used as an argument in a function
// - Square brackets means no : used to define an array
// - Both commas before and after : same context, inside function or array
// - a leading = means no : multiple variables are defined at the same time
// - anything other than "0" after
gitextract_zqrzria2/
├── .gitattributes
├── .gitignore
├── .gitignore.default
├── .npmignore
├── LICENSE
├── README.md
├── TestCases/
│ ├── audioContext_create1.js
│ ├── audioContext_create2.js
│ ├── audioContext_create3.js
│ ├── audioContext_create4.js
│ ├── double_renaming.js
│ ├── gitHub#17-multipleContexts.js
│ ├── gitHub#19-setInterval_declarationAlone.js
│ ├── gitHub#19-setInterval_declarationAtBegin1.js
│ ├── gitHub#19-setInterval_declarationAtBegin2.js
│ ├── gitHub#19-setInterval_declarationAtEnd1.js
│ ├── gitHub#19-setInterval_declarationAtEnd2.js
│ ├── gitHub#19-setInterval_declarationChained1.js
│ ├── gitHub#19-setInterval_declarationChained2.js
│ ├── gitHub#19-setInterval_declarationInArray1.js
│ ├── gitHub#19-setInterval_declarationInArray2.js
│ ├── gitHub#19-setInterval_declarationInFunction1.js
│ ├── gitHub#19-setInterval_declarationInFunction2.js
│ ├── gitHub#19-setInterval_declarationInFunction3.js
│ ├── gitHub#2-unicode.js
│ ├── gitHub#30-webglContext_create_charset.js
│ ├── gitHub#31-direct-hyphenBeginsBlock.js
│ ├── gitHub#31-direct-hyphenEndsBlock.js
│ ├── gitHub#31-direct-singleHyphen.js
│ ├── gitHub#31-negated-hyphenBeginsBlock.js
│ ├── gitHub#31-negated-hyphenEndsBlock.js
│ ├── gitHub#31-negated-singleHyphen.js
│ ├── gitHub#44-setInterval_arrowFunctionMultiParam.js
│ ├── gitHub#44-setInterval_arrowFunctionNoParam.js
│ ├── gitHub#44-setInterval_arrowFunctionSingleParam.js
│ ├── gitHub#47-packer_from92AndReplace.js
│ ├── gitHub#47-packer_from92NoReplace.js
│ ├── gitHub#47-packer_from92ReplaceFails.js
│ ├── gitHub#47-packer_from93AndReplace.js
│ ├── gitHub#47-packer_from93NoReplace.js
│ ├── gitHub#47-packer_rangesBeyond.js
│ ├── gitHub#47-packer_to92AndReplace.js
│ ├── gitHub#47-packer_to92NoReplace.js
│ ├── gitHub#47-packer_to93AndReplace.js
│ ├── gitHub#47-packer_to93NoReplace.js
│ ├── gitHub#47-packer_to93ReplaceFails.js
│ ├── gitHub#55-bothQuotesInUse.js
│ ├── gitHub#55-quotesAsOnlyTokens.js
│ ├── gitHub#55-sameStringInAllQuotes.js
│ ├── gitHub#56-setInterval_arrowComplexValues.js
│ ├── gitHub#56-setInterval_arrowMultipleValues.js
│ ├── gitHub#56-setInterval_arrowNoValue.js
│ ├── gitHub#56-setInterval_arrowOneValue.js
│ ├── gitHub#56-setInterval_arrowSingleValue.js
│ ├── gitHub#56-setInterval_standardComplexValues.js
│ ├── gitHub#56-setInterval_standardMultipleValues.js
│ ├── gitHub#56-setInterval_standardNoValue.js
│ ├── gitHub#56-setInterval_standardOneValue.js
│ ├── gitHub#56-setInterval_standardSingleValue.js
│ ├── gitHub#57-templateLiteralOneVariable.js
│ ├── gitHub#58-lettersOnly.js
│ ├── gitHub#58-numberAsMostFrequent.js
│ ├── gitHub#59-negatedRangeMerge-1vs3.js
│ ├── gitHub#63-backtick2DContext.js
│ ├── gitHub#63-backtickWebGLContext.js
│ ├── gitHub#64-URIError.js
│ ├── gitHub#65-backslash_invalidEscapeSequence.js
│ ├── gitHub#73-backslash_unexpandedToken.js
│ ├── gitHub#83-backslash_largerOutput.js
│ ├── gitHub#83-packer_9Alone.js
│ ├── gitHub#85-backslashSequence.js
│ ├── gitHub#85-flappyDragon.js
│ ├── gitHub#9-hashloop.js
│ ├── hash_using_length.js
│ ├── webglContext_create1.js
│ ├── webglContext_create2.js
│ ├── webglContext_create3.js
│ ├── webglContext_create4.js
│ ├── webglContext_create5.js
│ ├── webglContext_create6.js
│ └── webglContext_substringHash.js
├── bin/
│ └── regpack
├── changelog.txt
├── contextDescriptor_browser.js
├── contextDescriptor_node.js
├── package.json
├── packerData.js
├── patternViewer.js
├── regPack.html
├── regPack.js
├── shapeShifter.js
├── stringHelper.js
├── tests/
│ ├── allTests.js
│ ├── documentMock.js
│ ├── runBenchmark.js
│ ├── testAudioContextCreate.js
│ ├── testIssue0002_UnicodeSupport.js
│ ├── testIssue0009_HashLoopVariable.js
│ ├── testIssue0017_MultipleContexts.js
│ ├── testIssue0019_setInterval.js
│ ├── testIssue0030_webGLContextCreate.js
│ ├── testIssue0031_hyphenInRegex.js
│ ├── testIssue0042_patternViewer.js
│ ├── testIssue0044_setIntervalArrowFunction.js
│ ├── testIssue0045_closingBracket.js
│ ├── testIssue0047_EscapeInCharClass.js
│ ├── testIssue0050_unicodeSurrogate.js
│ ├── testIssue0055_stringDelimiters.js
│ ├── testIssue0056_setIntervalDefaultParams.js
│ ├── testIssue0057_replacementInString.js
│ ├── testIssue0058_numberAsLoopVariable.js
│ ├── testIssue0059_negatedRangeMerge.js
│ ├── testIssue0063_backtickFunctionParam.js
│ ├── testIssue0064_utf8EncodeURI.js
│ ├── testIssue0065_invalidEscapeSequence.js
│ ├── testIssue0072_setIntervalNoInitCode.js
│ ├── testIssue0074_keepWhiteSpaceSeparator.js
│ ├── testIssue0076_listVariablesInString.js
│ ├── testIssue0079_CandXMLComments.js
│ ├── testIssue0082_backticksInTemplateLiterals.js
│ ├── testIssue0083_backslashToken.js
│ ├── testIssue0085_backslashSequenceLength.js
│ ├── testIssue0087_firstCharacterInPattern.js
│ ├── testIssue0088_setIntervalAllocateVariable.js
│ ├── testIssue0089_emptyThermalMapping.js
│ ├── testIssue0094_missingVariableBlock.js
│ ├── testIssue0096_multiLineMinification.js
│ ├── testPackingConsistency.js
│ ├── testStringHelper.js
│ └── testWebGLContextCreate.js
├── thermalViewer.js
└── wiki_images/
├── thermal_view2.xcf
└── thermal_view4.xcf
SYMBOL INDEX (142 symbols across 44 files)
FILE: TestCases/gitHub#73-backslash_unexpandedToken.js
function e (line 1) | function e(n,e){for(;n instanceof Array&&n[0]in e&&e[n[0]].M;)n=e[n[0]](...
function t (line 1) | function t(n,r){for(;;){if(!(n instanceof Array))return i(n,r);if(n=e(n,...
FILE: contextDescriptor_browser.js
function ContextDescriptor (line 14) | function ContextDescriptor()
FILE: contextDescriptor_node.js
function ContextDescriptor (line 14) | function ContextDescriptor()
FILE: packerData.js
function PackerData (line 19) | function PackerData(name, dataString) {
FILE: patternViewer.js
function PatternViewer (line 10) | function PatternViewer ()
FILE: regPack.js
function resultMessage (line 6) | function resultMessage(sourceSize, resultSize)
function cmdRegPack (line 24) | function cmdRegPack(input, options) {
function RegPack (line 59) | function RegPack() {
FILE: shapeShifter.js
function ShapeShifter (line 17) | function ShapeShifter() {
FILE: tests/documentMock.js
function DocumentMock (line 8) | function DocumentMock() {
function DivMock (line 25) | function DivMock() {
FILE: tests/testAudioContextCreate.js
function runTests (line 6) | function runTests() {
function testAssignInIfThenElse (line 22) | function testAssignInIfThenElse() {
function testCreateToDifferentVariablesFirst (line 55) | function testCreateToDifferentVariablesFirst() {
function testCreateToDifferentVariablesSecond (line 88) | function testCreateToDifferentVariablesSecond() {
function testAssignInConditionalExpression (line 120) | function testAssignInConditionalExpression() {
FILE: tests/testIssue0002_UnicodeSupport.js
function runTests (line 5) | function runTests() {
function testUnicodeSupport (line 19) | function testUnicodeSupport() {
FILE: tests/testIssue0009_HashLoopVariable.js
function runTests (line 5) | function runTests() {
function testHashLoopVariable (line 19) | function testHashLoopVariable() {
FILE: tests/testIssue0017_MultipleContexts.js
function runTests (line 5) | function runTests() {
function testMultipleContexts (line 19) | function testMultipleContexts() {
FILE: tests/testIssue0019_setInterval.js
function runTests (line 6) | function runTests() {
function testTimeVariableDeclaredAlone (line 29) | function testTimeVariableDeclaredAlone() {
function testTimeVariableDeclaredAtBegin1 (line 63) | function testTimeVariableDeclaredAtBegin1() {
function testTimeVariableDeclaredAtBegin2 (line 96) | function testTimeVariableDeclaredAtBegin2() {
function testTimeVariableDeclaredAtBegin2 (line 130) | function testTimeVariableDeclaredAtBegin2() {
function testTimeVariableDeclaredAtEnd1 (line 165) | function testTimeVariableDeclaredAtEnd1() {
function testTimeVariableDeclaredAtEnd2 (line 200) | function testTimeVariableDeclaredAtEnd2() {
function testTimeVariableDeclarationChainedFirst (line 234) | function testTimeVariableDeclarationChainedFirst() {
function testTimeVariableDeclarationChainedSecond (line 268) | function testTimeVariableDeclarationChainedSecond() {
function testTimeVariableDeclarationInArrayFirst (line 302) | function testTimeVariableDeclarationInArrayFirst() {
function testTimeVariableDeclarationInArraySecond (line 336) | function testTimeVariableDeclarationInArraySecond() {
function testTimeVariableDeclarationInFunctionParameterFirst (line 371) | function testTimeVariableDeclarationInFunctionParameterFirst() {
function testTimeVariableDeclarationInFunctionParameterSecond (line 406) | function testTimeVariableDeclarationInFunctionParameterSecond() {
function testTimeVariableDeclarationInFunctionParameterLast (line 441) | function testTimeVariableDeclarationInFunctionParameterLast() {
FILE: tests/testIssue0030_webGLContextCreate.js
function runTests (line 6) | function runTests() {
function testCreateExclamationMarkInOptions (line 19) | function testCreateExclamationMarkInOptions() {
FILE: tests/testIssue0031_hyphenInRegex.js
function runTests (line 6) | function runTests() {
function testDirectSingleHyphen (line 24) | function testDirectSingleHyphen() {
function testDirectHyphenBeginsBlock (line 57) | function testDirectHyphenBeginsBlock() {
function testDirectHyphenEndsBlock (line 89) | function testDirectHyphenEndsBlock() {
function testNegatedSingleHyphen (line 122) | function testNegatedSingleHyphen() {
function testNegatedHyphenBeginsBlock (line 155) | function testNegatedHyphenBeginsBlock() {
function testNegatedHyphenEndBlock (line 188) | function testNegatedHyphenEndBlock() {
FILE: tests/testIssue0042_patternViewer.js
function runTests (line 6) | function runTests() {
function testLastBlockBeforeEnd (line 18) | function testLastBlockBeforeEnd() {
function testLastBlockAtEnd (line 32) | function testLastBlockAtEnd() {
FILE: tests/testIssue0044_setIntervalArrowFunction.js
function runTests (line 6) | function runTests() {
function testMultipleParametersMultipleParams (line 21) | function testMultipleParametersMultipleParams() {
function testMultipleParametersWithInit (line 56) | function testMultipleParametersWithInit() {
function testSingleParameter (line 90) | function testSingleParameter() {
function testNoParameter (line 125) | function testNoParameter() {
FILE: tests/testIssue0045_closingBracket.js
function runTests (line 4) | function runTests() {
function testBracketBeginsBlock (line 10) | function testBracketBeginsBlock() {
FILE: tests/testIssue0047_EscapeInCharClass.js
function runTests (line 5) | function runTests() {
function testRangeSorting (line 22) | function testRangeSorting() {
function testEscapedCharacterWithoutReplacement (line 60) | function testEscapedCharacterWithoutReplacement() {
function testEscapedCharacterWithReplacement (line 121) | function testEscapedCharacterWithReplacement() {
function testEscapedCharacterReplacementFails (line 179) | function testEscapedCharacterReplacementFails() {
FILE: tests/testIssue0050_unicodeSurrogate.js
function runTests (line 4) | function runTests() {
function testByteLength (line 17) | function testByteLength() {
function testSurrogatePacking (line 41) | function testSurrogatePacking() {
FILE: tests/testIssue0055_stringDelimiters.js
function runTests (line 5) | function runTests() {
function testUseBackticksForPackedString (line 20) | function testUseBackticksForPackedString() {
function testBothQuotesUsedNoES6 (line 56) | function testBothQuotesUsedNoES6() {
function testQuoteAsToken (line 92) | function testQuoteAsToken() {
function testQuoteReplacement (line 128) | function testQuoteReplacement() {
FILE: tests/testIssue0056_setIntervalDefaultParams.js
function runTests (line 6) | function runTests() {
function testNoAssignment (line 24) | function testNoAssignment() {
function testSingleVariableAssignment (line 70) | function testSingleVariableAssignment() {
function testOneAssignment (line 114) | function testOneAssignment() {
function testMultipleAssignments (line 160) | function testMultipleAssignments() {
function testComplexAssignments (line 204) | function testComplexAssignments() {
FILE: tests/testIssue0057_replacementInString.js
function runTests (line 6) | function runTests() {
function testLettersOnly (line 19) | function testLettersOnly() {
FILE: tests/testIssue0058_numberAsLoopVariable.js
function runTests (line 6) | function runTests() {
function testLettersOnly (line 21) | function testLettersOnly() {
function testProtectedAsMostFrequent (line 40) | function testProtectedAsMostFrequent() {
function testNumberAsMostFrequent (line 62) | function testNumberAsMostFrequent() {
FILE: tests/testIssue0059_negatedRangeMerge.js
function runTests (line 5) | function runTests() {
function testRangeMerge1vs3 (line 19) | function testRangeMerge1vs3() {
FILE: tests/testIssue0063_backtickFunctionParam.js
function runTests (line 5) | function runTests() {
function testBacktick2DContext (line 18) | function testBacktick2DContext() {
function testBacktickWebGLContext (line 46) | function testBacktickWebGLContext() {
FILE: tests/testIssue0064_utf8EncodeURI.js
function runTests (line 5) | function runTests() {
function testEncodeURI (line 19) | function testEncodeURI() {
FILE: tests/testIssue0065_invalidEscapeSequence.js
function runTests (line 5) | function runTests() {
function assertAllBackslashesDoubled (line 18) | function assertAllBackslashesDoubled(packedCode) {
function testInvalidEscapeSequence (line 59) | function testInvalidEscapeSequence() {
function testIncorrectReplacement (line 98) | function testIncorrectReplacement() {
FILE: tests/testIssue0072_setIntervalNoInitCode.js
function runTests (line 6) | function runTests() {
function testInitCodeAtEnd (line 20) | function testInitCodeAtEnd() {
function testNoInitCode (line 55) | function testNoInitCode() {
FILE: tests/testIssue0074_keepWhiteSpaceSeparator.js
function runTests (line 5) | function runTests() {
function testWhiteSpaceAsSeparator (line 20) | function testWhiteSpaceAsSeparator() {
function testMultipleWhiteSpaces (line 52) | function testMultipleWhiteSpaces() {
FILE: tests/testIssue0076_listVariablesInString.js
function runTests (line 5) | function runTests() {
function testTemplateLiteralInterpretedAsDollarVariable (line 18) | function testTemplateLiteralInterpretedAsDollarVariable() {
FILE: tests/testIssue0079_CandXMLComments.js
function runTests (line 5) | function runTests() {
function testCCommentMinification (line 20) | function testCCommentMinification() {
function testCppCommentMinification (line 57) | function testCppCommentMinification() {
function testXMLCommentMinification (line 88) | function testXMLCommentMinification() {
FILE: tests/testIssue0082_backticksInTemplateLiterals.js
function runTests (line 5) | function runTests() {
function testUseBackticksForPackedString (line 20) | function testUseBackticksForPackedString() {
function testBackticksEscapingInTemplateLiteral (line 59) | function testBackticksEscapingInTemplateLiteral() {
FILE: tests/testIssue0083_backslashToken.js
function runTests (line 5) | function runTests() {
function testBackslashToken (line 24) | function testBackslashToken() {
function testCharacter9AloneInRange (line 60) | function testCharacter9AloneInRange() {
FILE: tests/testIssue0085_backslashSequenceLength.js
function runTests (line 5) | function runTests() {
function testBackslashSequence (line 21) | function testBackslashSequence() {
function testFlappyDragon (line 63) | function testFlappyDragon() {
FILE: tests/testIssue0087_firstCharacterInPattern.js
function runTests (line 5) | function runTests() {
function testFirstCharacterInCrusher (line 18) | function testFirstCharacterInCrusher() {
FILE: tests/testIssue0088_setIntervalAllocateVariable.js
function runTests (line 5) | function runTests() {
function testVariableAllocation (line 21) | function testVariableAllocation() {
FILE: tests/testIssue0089_emptyThermalMapping.js
function runTests (line 7) | function runTests() {
function testEmptyThermalMapping (line 22) | function testEmptyThermalMapping() {
FILE: tests/testIssue0094_missingVariableBlock.js
function runTests (line 5) | function runTests() {
function testRenamingWithNoSpare (line 17) | function testRenamingWithNoSpare() {
FILE: tests/testIssue0096_multiLineMinification.js
function runTests (line 5) | function runTests() {
function testSingleLineMinification (line 18) | function testSingleLineMinification() {
function testMultiLineMinification (line 50) | function testMultiLineMinification() {
FILE: tests/testPackingConsistency.js
function runTests (line 6) | function runTests() {
function unpack (line 21) | function unpack(packedCode) {
function assertEqualStrings (line 79) | function assertEqualStrings(actual, expected) {
function testConsistency (line 99) | function testConsistency(inputFile) {
FILE: tests/testStringHelper.js
function runTests (line 7) | function runTests() {
function testGetByteLength (line 47) | function testGetByteLength() {
function testBase64 (line 63) | function testBase64() {
function testWriteRangeToRegexpCharClass (line 95) | function testWriteRangeToRegexpCharClass () {
function testIsActualCodeAt (line 133) | function testIsActualCodeAt() {
FILE: tests/testWebGLContextCreate.js
function runTests (line 6) | function runTests() {
function testCreateExperimentalWebGL (line 24) | function testCreateExperimentalWebGL() {
function testCreateWebGL (line 59) | function testCreateWebGL() {
function testCreateBothFirst (line 94) | function testCreateBothFirst() {
function testCreateBothSecond (line 130) | function testCreateBothSecond() {
function testCreateOptionsFirst (line 165) | function testCreateOptionsFirst() {
function testCreateOptionsSecond (line 201) | function testCreateOptionsSecond() {
function testHashCollisions (line 237) | function testHashCollisions() {
FILE: thermalViewer.js
function ThermalViewer (line 10) | function ThermalViewer ()
Condensed preview — 133 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (479K chars).
[
{
"path": ".gitattributes",
"chars": 503,
"preview": "# Auto detect text files and perform LF normalization\n* text=auto\n\n# Custom for Visual Studio\n*.cs diff=csharp\n*.sln"
},
{
"path": ".gitignore",
"chars": 13,
"preview": "node_modules\n"
},
{
"path": ".gitignore.default",
"chars": 1970,
"preview": "#################\n## Eclipse\n#################\n\n*.pydevproject\n.project\n.metadata\nbin/\ntmp/\n*.tmp\n*.bak\n*.swp\n*~.nib\nloc"
},
{
"path": ".npmignore",
"chars": 16,
"preview": "TestCases\ntests\n"
},
{
"path": "LICENSE",
"chars": 1362,
"preview": "The MIT License (MIT)\n\nCopyright (c) 2012-2016 Siorki\n\nPermission is hereby granted, free of charge, to any person obtai"
},
{
"path": "README.md",
"chars": 3319,
"preview": "**RegPack** is a packer intended for use on minified Javascript code. Current revision is 5.0.4\n\nIt is mostly suited to "
},
{
"path": "TestCases/audioContext_create1.js",
"chars": 386,
"preview": "try {\n\t\t\tthis.webAudioSupport = true;\n\t\t\tif (typeof AudioContext !== \"undefined\") {\n\t\t\t\tthis.audioContext = new AudioCon"
},
{
"path": "TestCases/audioContext_create2.js",
"chars": 336,
"preview": "var stdContext=null, webkitContext=null;\nif (typeof AudioContext !== \"undefined\") {\n\tstdContext = new AudioContext()\n}\ni"
},
{
"path": "TestCases/audioContext_create3.js",
"chars": 336,
"preview": "var stdContext=null, webkitContext=null;\nif (typeof webkitAudioContext !== \"undefined\") {\n\twebkitContext = new webkitAud"
},
{
"path": "TestCases/audioContext_create4.js",
"chars": 1770,
"preview": "m=[];s=[0,3,5,7,10];pl=0;for(i=0;16>i;i++)m[i]=0;ac=new webkitAudioContext()||new AudioContext();var nb=ac.createBuffer("
},
{
"path": "TestCases/double_renaming.js",
"chars": 573,
"preview": "a.fillRect(0,0,91,91);\n\nsetInterval( function () {\t\n\tk = 2+2*Math.cos(3.1416*t/64);\n\ti=0;\n\twhile(i<300) {\n\t\ta.strokeStyl"
},
{
"path": "TestCases/gitHub#17-multipleContexts.js",
"chars": 1658,
"preview": "a=a.cloneNode(p=[]);cc=a.getContext(\"2d\");cc.fillStyle=n=cc.createRadialGradient(225,75,40,225,75,60);n.addColorStop(t=0"
},
{
"path": "TestCases/gitHub#19-setInterval_declarationAlone.js",
"chars": 1767,
"preview": "a=a.cloneNode(p=[s=5]);t=0;cc=a.getContext(\"2d\");e=cc.getImageData(0,0,150,150);d=e.data;setInterval(function(){if(t%127"
},
{
"path": "TestCases/gitHub#19-setInterval_declarationAtBegin1.js",
"chars": 1767,
"preview": "t=0;a=a.cloneNode(p=[s=5]);cc=a.getContext(\"2d\");e=cc.getImageData(0,0,150,150);d=e.data;setInterval(function(){if(t%127"
},
{
"path": "TestCases/gitHub#19-setInterval_declarationAtBegin2.js",
"chars": 1767,
"preview": "t=0,a=a.cloneNode(p=[s=5]);cc=a.getContext(\"2d\");e=cc.getImageData(0,0,150,150);d=e.data;setInterval(function(){if(t%127"
},
{
"path": "TestCases/gitHub#19-setInterval_declarationAtEnd1.js",
"chars": 1767,
"preview": "a=a.cloneNode(p=[s=5]);cc=a.getContext(\"2d\");e=cc.getImageData(0,0,150,150);d=e.data;t=0;setInterval(function(){if(t%127"
},
{
"path": "TestCases/gitHub#19-setInterval_declarationAtEnd2.js",
"chars": 1767,
"preview": "a=a.cloneNode(p=[s=5]);cc=a.getContext(\"2d\");e=cc.getImageData(0,0,150,150);d=e.data,t=0;setInterval(function(){if(t%127"
},
{
"path": "TestCases/gitHub#19-setInterval_declarationChained1.js",
"chars": 1769,
"preview": "a=a.cloneNode(p=[s=5]);t=u=0;cc=a.getContext(\"2d\");e=cc.getImageData(0,0,150,150);d=e.data;setInterval(function(){if(t%1"
},
{
"path": "TestCases/gitHub#19-setInterval_declarationChained2.js",
"chars": 1769,
"preview": "a=a.cloneNode(p=[s=5]);u=t=0;cc=a.getContext(\"2d\");e=cc.getImageData(0,0,150,150);d=e.data;setInterval(function(){if(t%1"
},
{
"path": "TestCases/gitHub#19-setInterval_declarationInArray1.js",
"chars": 1767,
"preview": "a=a.cloneNode(p=[t=0,s=5]);cc=a.getContext(\"2d\");e=cc.getImageData(0,0,150,150);d=e.data;setInterval(function(){if(t%127"
},
{
"path": "TestCases/gitHub#19-setInterval_declarationInArray2.js",
"chars": 1767,
"preview": "a=a.cloneNode(p=[s=5,t=0]);cc=a.getContext(\"2d\");e=cc.getImageData(0,0,150,150);d=e.data;setInterval(function(){if(t%127"
},
{
"path": "TestCases/gitHub#19-setInterval_declarationInFunction1.js",
"chars": 1765,
"preview": "a=a.cloneNode(p=[s=5]);cc=a.getContext(\"2d\");e=cc.getImageData(t=0,0,150,150);d=e.data;setInterval(function(){if(t%1275<"
},
{
"path": "TestCases/gitHub#19-setInterval_declarationInFunction2.js",
"chars": 1765,
"preview": "a=a.cloneNode(p=[s=5]);cc=a.getContext(\"2d\");e=cc.getImageData(0,t=0,150,150);d=e.data;setInterval(function(){if(t%1275<"
},
{
"path": "TestCases/gitHub#19-setInterval_declarationInFunction3.js",
"chars": 1763,
"preview": "a=a.cloneNode(p=[s=5]);cc=a.getContext(\"2d\");e=cc.getImageData(0,0,150,t=0);d=e.data;setInterval(function(){if(t%1275<1)"
},
{
"path": "TestCases/gitHub#2-unicode.js",
"chars": 1363,
"preview": "b.innerHTML=\"<center><p onclick=g(1,3,3,f=1)>XnO<p onclick=g(3,3,3,f=1)>XnO3D<p onclick=g(1,6,7,f=2)>Find4<p onclick=g("
},
{
"path": "TestCases/gitHub#30-webglContext_create_charset.js",
"chars": 327,
"preview": "gl=canvas.getContext(\"webgl\", { antialias: !0, stencil: !0 })||canvas.getContext(\"experimental-webgl\", { antialias: !0, "
},
{
"path": "TestCases/gitHub#31-direct-hyphenBeginsBlock.js",
"chars": 201,
"preview": "\u0001\u0002\u0003\u0004\u0005\u0006\u0007\b\t\u000b\f\u000e\u000f\u0010\u0011\u0012\u0013\u0014\u0015\u0016\u0017\u0018\u0019\u001a\u001b\u001c\u001d\u001e\u001f\r\n! !'#$%&'()*+,\r\n123456789:;<=>?@\r\nABCDEFGHIJKLMNOPQRSTUVWXYZ\r\n[\\]^_`abcdefghijklmnopqrstu"
},
{
"path": "TestCases/gitHub#31-direct-hyphenEndsBlock.js",
"chars": 200,
"preview": "\u0001\u0002\u0003\u0004\u0005\u0006\u0007\b\t\u000b\f\u000e\u000f\u0010\u0011\u0012\u0013\u0014\u0015\u0016\u0017\u0018\u0019\u001a\u001b\u001c\u001d\u001e\u001f\r\n !'#$%&'()\r\n./0123456789:;<=>?@\r\nABCDEFGHIJKLMNOPQRSTUVWXYZ\r\n[\\]^_`abcdefghijklmnopqrstuv"
},
{
"path": "TestCases/gitHub#31-direct-singleHyphen.js",
"chars": 200,
"preview": "\u0001\u0002\u0003\u0004\u0005\u0006\u0007\b\t\u000b\f\u000e\u000f\u0010\u0011\u0012\u0013\u0014\u0015\u0016\u0017\u0018\u0019\u001a\u001b\u001c\u001d\u001e\u001f\r\n !'#$%&'()*+,\r\n./012345678:;<=>?@\r\nABCDEFGHIJKLMNOPQRSTUVWXYZ\r\n[\\]^_`abcdefghijklmnopqrst"
},
{
"path": "TestCases/gitHub#31-negated-hyphenBeginsBlock.js",
"chars": 73,
"preview": "-\nabcdabcdabcd\nefghefghefgh\nijklijklijkl\nmnopmnopmnop\nqrstqrstqrst\nuvwxyz"
},
{
"path": "TestCases/gitHub#31-negated-hyphenEndsBlock.js",
"chars": 83,
"preview": "\u0001\u0002\u0003\u0004\u0005\u0006\u0007\b\t\u000b\f\u000e\u000f\u0010\u0011\u0012\u0013\u0014\u0015\u0016\u0017\u0018\u0019\u001a\u001b\u001c\u001d\u001e\u001f \r\n-\r\n!\"#$%&'()*+,!\"#$%&'()*+,!\"#$%&'()*+,!\"#$%&'()*+,"
},
{
"path": "TestCases/gitHub#31-negated-singleHyphen.js",
"chars": 237,
"preview": "-\r\n$%&'$%&'$%&'$%&'$%&'$%&'$%&'$%&'\r\n#()+#()+#()+#()+#()+#()+#()+#()+\r\n\u0001\u0002\u0003\u0004\u0005\u0006\u0007\b\t\u000b\f\u000e\u000f\u0010\u0011\u0012\u0013\u0014\u0015\u0016\u0017\u0018\u0019\u001a\u001b\u001c\u001d\u001e\u001f\r\n012345678901234567"
},
{
"path": "TestCases/gitHub#44-setInterval_arrowFunctionMultiParam.js",
"chars": 1766,
"preview": "t=0;a=a.cloneNode(p=[s=5]);cc=a.getContext(\"2d\");e=cc.getImageData(0,0,150,150);d=e.data;setInterval((x,y,z)=>{if(t%1275"
},
{
"path": "TestCases/gitHub#44-setInterval_arrowFunctionNoParam.js",
"chars": 1761,
"preview": "t=0;a=a.cloneNode(p=[s=5]);cc=a.getContext(\"2d\");e=cc.getImageData(0,0,150,150);d=e.data;setInterval(()=>{if(t%1275<1){c"
},
{
"path": "TestCases/gitHub#44-setInterval_arrowFunctionSingleParam.js",
"chars": 1760,
"preview": "t=0;a=a.cloneNode(p=[s=5]);cc=a.getContext(\"2d\");e=cc.getImageData(0,0,150,150);d=e.data;setInterval(x=>{if(t%1275<1){cc"
},
{
"path": "TestCases/gitHub#47-packer_from92AndReplace.js",
"chars": 224,
"preview": "\u0001\u0002\u0003\u0004\u0005\u0006\u0007\b\t\u000b\f\u000e\u000f\u0010\u0011\u0012\u0013\u0014\u0015\u0016\u0017\u0018\u0019\u001a\u001b\u001c\u001d\u001e\u001f\r\n! !'#$%&'()*+,-./\r\n456789:;<=>?@\r\nABCDEFGHIJKLMNOPQRSTUVWXYZ\r\n[abcdefghijklmnopqrstuvwxyz"
},
{
"path": "TestCases/gitHub#47-packer_from92NoReplace.js",
"chars": 232,
"preview": "'\u0001\u0002\u0003\u0004\u0005\u0006\u0007\b\t\u000b\f\u000e\u000f\u0010\u0011\u0012\u0013\u0014\u0015\u0016\u0017\u0018\u0019\u001a\u001b\u001c\u001d\u001e\u001f'\r\n'! !#$%&'()*+,-./\r\n0123456789:;<=>?@\r\nABCDEFGHIJKLMNOPQRSTUVWXYZ\r\n[abcdefghijklmnopqrst"
},
{
"path": "TestCases/gitHub#47-packer_from92ReplaceFails.js",
"chars": 225,
"preview": "\u0001\u0002\u0003\u0004\u0005\u0006\u0007\b\t\u000b\f\u000e\u000f\u0010\u0011\u0012\u0013\u0014\u0015\u0016\u0017\u0018\u0019\u001a\u001b\u001c\u001d\u001e\u001f\r\n! !'#$%&'()*+,-./\r\n3456789:;<=>?@\r\nABCDEFGHIJKLMNOPQRSTUVWXYZ\r\n[abcdefghijklmnopqrstuvwxy"
},
{
"path": "TestCases/gitHub#47-packer_from93AndReplace.js",
"chars": 225,
"preview": "\u0001\u0002\u0003\u0004\u0005\u0006\u0007\b\t\u000b\f\u000e\u000f\u0010\u0011\u0012\u0013\u0014\u0015\u0016\u0017\u0018\u0019\u001a\u001b\u001c\u001d\u001e\u001f\r\n! !'#$%&'()*+,-./\r\n3456789:;<=>?@\r\nABCDEFGHIJKLMNOPQRSTUVWXYZ\r\n[\\bcdefghijklmnopqrstuvwxy"
},
{
"path": "TestCases/gitHub#47-packer_from93NoReplace.js",
"chars": 233,
"preview": "'\u0001\u0002\u0003\u0004\u0005\u0006\u0007\b\t\u000b\f\u000e\u000f\u0010\u0011\u0012\u0013\u0014\u0015\u0016\u0017\u0018\u0019\u001a\u001b\u001c\u001d\u001e\u001f'\r\n'! !#$%&'()*+,-./\r\n0123456789:;<=>?@\r\nABCDEFGHIJKLMNOPQRSTUVWXYZ\r\n[\\abcdefghijklmnopqrs"
},
{
"path": "TestCases/gitHub#47-packer_rangesBeyond.js",
"chars": 225,
"preview": "\u0001\u0002\u0003\u0004\u0005\u0006\u0007\b\t\u000b\f\u000e\u000f\u0010\u0011\u0012\u0013\u0014\u0015\u0016\u0017\u0018\u0019\u001a\u001b\u001c\u001d\u001e\u001f\r\n! !'#$%&'()*+,-./\r\n0123456789:;<=>?\r\nAFGHIJKQRSTUVWXYZ\r\n[\\]^_`abcdefghijklmnopqrstuvwxyz`"
},
{
"path": "TestCases/gitHub#47-packer_to92AndReplace.js",
"chars": 229,
"preview": "'\u0001\u0002\u0003\u0004\u0005\u0006\u0007\b\t\u000b\f\u000e\u000f\u0010\u0011\u0012\u0013\u0014\u0015\u0016\u0017\u0018\u0019\u001a\u001b\u001c\u001d\u001e\u001f'\r\n'! !#$%&'()*+,-./\r\n3456789:;<=>?@\r\nABCDEFGHIJKLMNOPQRSTUVW\r\n]^_`abcdefghijklmnopqrstuvw"
},
{
"path": "TestCases/gitHub#47-packer_to92NoReplace.js",
"chars": 234,
"preview": "'\u0001\u0002\u0003\u0004\u0005\u0006\u0007\b\t\u000b\f\u000e\u000f\u0010\u0011\u0012\u0013\u0014\u0015\u0016\u0017\u0018\u0019\u001a\u001b\u001c\u001d\u001e\u001f'\r\n'! !#$%&'()*+,-./\r\n0123456789:;<=>?@\r\nABCDEFGHIJKLMNOPQRSTUVWX\r\n]^_`abcdefghijklmnopqrs"
},
{
"path": "TestCases/gitHub#47-packer_to93AndReplace.js",
"chars": 229,
"preview": "'\u0001\u0002\u0003\u0004\u0005\u0006\u0007\b\t\u000b\f\u000e\u000f\u0010\u0011\u0012\u0013\u0014\u0015\u0016\u0017\u0018\u0019\u001a\u001b\u001c\u001d\u001e\u001f'\r\n'! !#$%&'()*+,-./\r\n3456789:;<=>?@\r\nABCDEFGHIJKLMNOPQRSTUVW\r\n^_`abcdefghijklmnopqrstuvwx"
},
{
"path": "TestCases/gitHub#47-packer_to93NoReplace.js",
"chars": 232,
"preview": "'\u0001\u0002\u0003\u0004\u0005\u0006\u0007\b\t\u000b\f\u000e\u000f\u0010\u0011\u0012\u0013\u0014\u0015\u0016\u0017\u0018\u0019\u001a\u001b\u001c\u001d\u001e\u001f'\r\n'! !#$%&'()*+,-./\r\n0123456789:;<=>?@\r\nABCDEFGHIJKLMNOPQRSTUVWX\r\n^_`abcdefghijklmnopqrst"
},
{
"path": "TestCases/gitHub#47-packer_to93ReplaceFails.js",
"chars": 230,
"preview": "'\u0001\u0002\u0003\u0004\u0005\u0006\u0007\b\t\u000b\f\u000e\u000f\u0010\u0011\u0012\u0013\u0014\u0015\u0016\u0017\u0018\u0019\u001a\u001b\u001c\u001d\u001e\u001f'\r\n'! !#$%&'()*+,-./\r\n23456789:;<=>?@\r\nABCDEFGHIJKLMNOPQRSTUVW\r\n^_`abcdefghijklmnopqrstuvw"
},
{
"path": "TestCases/gitHub#55-bothQuotesInUse.js",
"chars": 107,
"preview": "v=0;setInterval(()=>{s=\"'\";t='\"';s='\"'+s;t='\"'+t;u=(v&1?s:t);u+=t+s+t;z='\"'+\"'\"+t+s+t;console.log(u)}, 40);"
},
{
"path": "TestCases/gitHub#55-quotesAsOnlyTokens.js",
"chars": 210,
"preview": "`\u0001\u0002\u0003\u0004\u0005\u0006\u0007\b\t\u000b\f\u000e\u000f\u0010\u0011\u0012\u0013\u0014\u0015\u0016\u0017\u0018\u0019\u001a\u001b\u001c\u001d\u001e\u001f`\r\n`! !#$%&()*+,-./`\r\n0123456789:;<=>?@\r\nABCDEFGHIJKLMNOPQRSTUVWXYZ\r\n[\\]^_abcdefghijklmnop"
},
{
"path": "TestCases/gitHub#55-sameStringInAllQuotes.js",
"chars": 153,
"preview": "v=0;setInterval(()=>{s=\"message\";t='message';s=`message`+s;t='message'+t;u=(v&1?s:t);u+=t+s+t;z='message'+\"message\"+`mes"
},
{
"path": "TestCases/gitHub#56-setInterval_arrowComplexValues.js",
"chars": 1775,
"preview": "t=0;a=a.cloneNode(p=[s=5]);cc=a.getContext(\"2d\");e=cc.getImageData(0,0,150,150);d=e.data;setInterval((w=t,x=y=z=0,aa)=>{"
},
{
"path": "TestCases/gitHub#56-setInterval_arrowMultipleValues.js",
"chars": 1772,
"preview": "t=0;a=a.cloneNode(p=[s=5]);cc=a.getContext(\"2d\");e=cc.getImageData(0,0,150,150);d=e.data;setInterval((x=2,y=1,z=0)=>{if("
},
{
"path": "TestCases/gitHub#56-setInterval_arrowNoValue.js",
"chars": 1766,
"preview": "t=0;a=a.cloneNode(p=[s=5]);cc=a.getContext(\"2d\");e=cc.getImageData(0,0,150,150);d=e.data;setInterval((x,y,z)=>{if(t%1275"
},
{
"path": "TestCases/gitHub#56-setInterval_arrowOneValue.js",
"chars": 1768,
"preview": "t=0;a=a.cloneNode(p=[s=5]);cc=a.getContext(\"2d\");e=cc.getImageData(0,0,150,150);d=e.data;setInterval((x,y,z=0)=>{if(t%12"
},
{
"path": "TestCases/gitHub#56-setInterval_arrowSingleValue.js",
"chars": 1764,
"preview": "t=0;a=a.cloneNode(p=[s=5]);cc=a.getContext(\"2d\");e=cc.getImageData(0,0,150,150);d=e.data;setInterval((x=0)=>{if(t%1275<1"
},
{
"path": "TestCases/gitHub#56-setInterval_standardComplexValues.js",
"chars": 1781,
"preview": "t=0;a=a.cloneNode(p=[s=5]);cc=a.getContext(\"2d\");e=cc.getImageData(0,0,150,150);d=e.data;setInterval(function(w=t,x=y=z="
},
{
"path": "TestCases/gitHub#56-setInterval_standardMultipleValues.js",
"chars": 1778,
"preview": "t=0;a=a.cloneNode(p=[s=5]);cc=a.getContext(\"2d\");e=cc.getImageData(0,0,150,150);d=e.data;setInterval(function(x=2,y=1,z="
},
{
"path": "TestCases/gitHub#56-setInterval_standardNoValue.js",
"chars": 1772,
"preview": "t=0;a=a.cloneNode(p=[s=5]);cc=a.getContext(\"2d\");e=cc.getImageData(0,0,150,150);d=e.data;setInterval(function(x,y,z){if("
},
{
"path": "TestCases/gitHub#56-setInterval_standardOneValue.js",
"chars": 1774,
"preview": "t=0;a=a.cloneNode(p=[s=5]);cc=a.getContext(\"2d\");e=cc.getImageData(0,0,150,150);d=e.data;setInterval(function(x,y,z=0){i"
},
{
"path": "TestCases/gitHub#56-setInterval_standardSingleValue.js",
"chars": 1770,
"preview": "t=0;a=a.cloneNode(p=[s=5]);cc=a.getContext(\"2d\");e=cc.getImageData(0,0,150,150);d=e.data;setInterval(function(x=0){if(t%"
},
{
"path": "TestCases/gitHub#57-templateLiteralOneVariable.js",
"chars": 1765,
"preview": "a=a.cloneNode($=[s=5]);cc=a.getContext(\"2d\");e=cc.getImageData(T=0,0,150,150);d=e.data;setInterval(function(){if(T%1275<"
},
{
"path": "TestCases/gitHub#58-lettersOnly.js",
"chars": 134,
"preview": "a=b=c=d=e=0;for(k=0;k<50;++k)a+=k;for(k=0;k<50;++k)b+=k*k;for(k=0;k<50;++k)c+=k*k*k;for(p=1;p<50;++p)d+=1/p;for(p=1;p<50"
},
{
"path": "TestCases/gitHub#58-numberAsMostFrequent.js",
"chars": 155,
"preview": "a=b=c=d=e=k=0;for(2==e&&k=1;k<50;++k)a+=k;for(2==a&&k=5;k<50;++k)b+=k*k;for(20==b&&k=9;k<50;++k)c+=k*k*k;for(p=1;p<50;++"
},
{
"path": "TestCases/gitHub#59-negatedRangeMerge-1vs3.js",
"chars": 147,
"preview": "\u0001\u0002\u0003\u0004\u0005\u0006\u0007\b\t\u000b\f\u000e\u000f\u0010\u0011\u0012\u0013\u0014\u0015\u0016\u0017\u0018\u0019\u001a\u001b\u001c\u001d\u001e\u001f\r\n! !'#$%&'()*+,-./\r\n456789:;<=>?@\r\nABCDEFGHIJKLMNOPQRSTUVWXYZ\r\n[\\]`_^`\r\nabcdefghijklmnopqr"
},
{
"path": "TestCases/gitHub#63-backtick2DContext.js",
"chars": 1764,
"preview": "a=a.cloneNode(p=[s=5]);cc=a.getContext`2d`;e=cc.getImageData(t=0,0,150,150);d=e.data;setInterval(function(){if(t%1275<1)"
},
{
"path": "TestCases/gitHub#63-backtickWebGLContext.js",
"chars": 736,
"preview": "for(i in g=a.getContext`webgl`)g[i[0]+i[6]]=g[i];with(g)vA(P=cP(),2,5120,bD(B=ET-3,Int8Array.of(B,setInterval(x=>dr(6,ve"
},
{
"path": "TestCases/gitHub#64-URIError.js",
"chars": 28,
"preview": "c.fillText('✪🅼🅼🅼', 5, 165);"
},
{
"path": "TestCases/gitHub#65-backslash_invalidEscapeSequence.js",
"chars": 1553,
"preview": "b.innerHTML=`<div style=width:95vw;height:95vh;perspective:500px;overflow:hidden;background:#7e2><div style=transform-s"
},
{
"path": "TestCases/gitHub#73-backslash_unexpandedToken.js",
"chars": 1759,
"preview": "module.exports=function(n){function e(n,e){for(;n instanceof Array&&n[0]in e&&e[n[0]].M;)n=e[n[0]](...n.slice(1));return"
},
{
"path": "TestCases/gitHub#83-backslash_largerOutput.js",
"chars": 2536,
"preview": "for(b.innerHTML=`<div style=transform-style:preserve-3d;position:fixed;perspective:80vh;margin:40vh+50vw><div style=tran"
},
{
"path": "TestCases/gitHub#83-packer_9Alone.js",
"chars": 237,
"preview": "'\u0001\u0002\u0003\u0004\u0005\u0006\u0007\b\u000b\f\u000e\u000f\u0010\u0011\u0012\u0013\u0014\u0015\u0016\u0017\u0018\u0019\u001a\u001b\u001c\u001d\u001e\u001f'\r\n'! !#$%&'()*+,-./\r\n3456789:;<=>?@\r\nABCDEFGHIJKLMNOPQRSTUVW\r\n[\\]^_`abcdefghijklmnopqrsuvw"
},
{
"path": "TestCases/gitHub#85-backslashSequence.js",
"chars": 160,
"preview": "var s=\"\\\\\";\ns=s+s;\nvar z=s;\nvar s=\"abcdefghijklmnopqrstuvwxyz\";\nvar k=s+z;\nvar w=k+\"aab\\\\xyz\";\nvar d=[];\nfor (var i=0; i"
},
{
"path": "TestCases/gitHub#85-flappyDragon.js",
"chars": 1176,
"preview": "B=E=C=0;s=a.height/1E3;R=[];for(i=0;1E3>i;i++)R[i]=R[i+1E3]=8*Math.random()|0;k=G=6;r=50;x=200;y=500;V=0;S=20;ontouchsta"
},
{
"path": "TestCases/gitHub#9-hashloop.js",
"chars": 1920,
"preview": "(u=function(){for(requestAnimationFrame(u),a.width=x=1023,a.height=h=x*innerHeight/innerWidth|1,H=performance.now()/15|1"
},
{
"path": "TestCases/hash_using_length.js",
"chars": 675,
"preview": "t=w=0;c.lineCap=\"round\";setInterval(function(){for(i=720;i;)c.strokeStyle=\"hsl(20,0%,\"+((Math.cos(t/20.372)+1)*x.charCod"
},
{
"path": "TestCases/webglContext_create1.js",
"chars": 235,
"preview": "gl=canvas.getContext(\"experimental-webgl\");\ngl.clearColor(0.0, 0.0, 0.0, 1.0); \ngl.clearDepth(1.0); \ngl.e"
},
{
"path": "TestCases/webglContext_create2.js",
"chars": 222,
"preview": "gl=canvas.getContext(\"webgl\");\ngl.clearColor(0.0, 0.0, 0.0, 1.0); \ngl.clearDepth(1.0); \ngl.enable(gl.DEPT"
},
{
"path": "TestCases/webglContext_create3.js",
"chars": 263,
"preview": "gl=canvas.getContext(\"experimental-webgl\")||canvas.getContext(\"webgl\");\ngl.clearColor(0.0, 0.0, 0.0, 1.0); \ngl.clearDept"
},
{
"path": "TestCases/webglContext_create4.js",
"chars": 263,
"preview": "gl=canvas.getContext(\"webgl\")||canvas.getContext(\"experimental-webgl\");\ngl.clearColor(0.0, 0.0, 0.0, 1.0); \ngl.clearDept"
},
{
"path": "TestCases/webglContext_create5.js",
"chars": 307,
"preview": "o={ antialias: true, stencil: true };\ngl=canvas.getContext(\"webgl\", o)||canvas.getContext(\"experimental-webgl\", o);\ngl.c"
},
{
"path": "TestCases/webglContext_create6.js",
"chars": 335,
"preview": "gl=canvas.getContext(\"webgl\", { antialias: true, stencil: true })||canvas.getContext(\"experimental-webgl\", { antialias: "
},
{
"path": "TestCases/webglContext_substringHash.js",
"chars": 265,
"preview": "gl=canvas.getContext(\"experimental-webgl\");\ngl.clearColor(0.0, 0.0, 0.0, 1.0); \ngl.clearDepth(1.0); \ngl.e"
},
{
"path": "bin/regpack",
"chars": 560,
"preview": "#! /usr/bin/env node\n\nconst cmdRegPack = require('..').cmdRegPack;\nvar argv = require('minimist')(process.argv.slice(2))"
},
{
"path": "changelog.txt",
"chars": 4702,
"preview": "v5.0.4 - July 2022\n\nFixed bugs\n- #59 : Negated char class : optimal range merge\n- #74 : Line break removed, leaving no s"
},
{
"path": "contextDescriptor_browser.js",
"chars": 3620,
"preview": "/**\n * @constructor\n * The ContextDescriptor class exposes the contents of the different contexts (2D graphic, GL graphi"
},
{
"path": "contextDescriptor_node.js",
"chars": 20975,
"preview": "/**\n * @constructor\n * The ContextDescriptor class exposes the contents of the different contexts (2D graphic, GL graphi"
},
{
"path": "package.json",
"chars": 435,
"preview": "{\n \"name\": \"regpack\",\n \"version\": \"5.0.4\",\n \"description\": \"A packer intended for use on minified Javascript co"
},
{
"path": "packerData.js",
"chars": 2801,
"preview": "/**\n * @constructor\n * The PackerData class holds actual data :\n * - string to pack, in the current preprocessing / com"
},
{
"path": "patternViewer.js",
"chars": 3012,
"preview": "/**\n * @constructor\n * The PatternViewer class renders the original code\n * into a DHTML view highlighting the patterns "
},
{
"path": "regPack.html",
"chars": 13779,
"preview": "<!DOCTYPE html>\n<html>\n<head>\n\t<meta charset=\"utf-8\">\n\t<title>RegPack v5.0.4</title>\n\t<style type=\"text/css\">\n#options {"
},
{
"path": "regPack.js",
"chars": 43151,
"preview": "// Node.js : module shapeShifter defines ShapeShifter class (preprocessor)\nif (typeof require !== 'undefined') {\n var"
},
{
"path": "shapeShifter.js",
"chars": 99542,
"preview": "// Node.js init\nif (typeof require !== 'undefined') {\n\tvar PackerData = require(\"./packerData\");\n\tvar StringHelper = req"
},
{
"path": "stringHelper.js",
"chars": 14285,
"preview": "/**\n * StringHelper provides utility functions to operator on strings and regular expressions.\n * \n * It is stateless an"
},
{
"path": "tests/allTests.js",
"chars": 4338,
"preview": "var testAudioContextCreate = require(\"./testAudioContextCreate\");\nvar testWebGLContextCreate = require(\"./testWebGLConte"
},
{
"path": "tests/documentMock.js",
"chars": 606,
"preview": "/**\n * Test mock for document (not present in node.js)\n * This instance simply stores the result in a string\n * \n * Used"
},
{
"path": "tests/runBenchmark.js",
"chars": 3477,
"preview": "var regPack = require(\"../regPack\")\nvar fs = require('fs');\n\n\nvar sources = [\n\t{ fileName:\"2010 - Christmas Tree.js\", op"
},
{
"path": "tests/testAudioContextCreate.js",
"chars": 4463,
"preview": "var RegPack = require(\"../regPack\")\nvar fs = require(\"fs\");\nvar assert = require(\"assert\");\n\n\nfunction runTests() {\n\tcon"
},
{
"path": "tests/testIssue0002_UnicodeSupport.js",
"chars": 1369,
"preview": "var RegPack = require(\"../regPack\")\nvar fs = require(\"fs\");\nvar assert = require(\"assert\");\n\nfunction runTests() {\n\tcons"
},
{
"path": "tests/testIssue0009_HashLoopVariable.js",
"chars": 1416,
"preview": "var RegPack = require(\"../regPack\")\nvar fs = require(\"fs\");\nvar assert = require(\"assert\");\n\nfunction runTests() {\n\tcons"
},
{
"path": "tests/testIssue0017_MultipleContexts.js",
"chars": 1470,
"preview": "var RegPack = require(\"../regPack\")\nvar fs = require(\"fs\");\nvar assert = require(\"assert\");\n\nfunction runTests() {\n\tcons"
},
{
"path": "tests/testIssue0019_setInterval.js",
"chars": 17554,
"preview": "var RegPack = require(\"../regPack\")\nvar fs = require(\"fs\");\nvar assert = require(\"assert\");\n\n\nfunction runTests() {\n\tcon"
},
{
"path": "tests/testIssue0030_webGLContextCreate.js",
"chars": 1460,
"preview": "var RegPack = require(\"../regPack\")\nvar fs = require(\"fs\");\nvar assert = require(\"assert\");\n\n\nfunction runTests() {\n\tcon"
},
{
"path": "tests/testIssue0031_hyphenInRegex.js",
"chars": 6725,
"preview": "var RegPack = require(\"../regPack\")\nvar fs = require(\"fs\");\nvar assert = require(\"assert\");\n\n\nfunction runTests() {\n\tcon"
},
{
"path": "tests/testIssue0042_patternViewer.js",
"chars": 1340,
"preview": "var PatternViewer = require(\"../patternViewer\")\nvar fs = require(\"fs\");\nvar DocumentMock = require(\"./documentMock\");\nva"
},
{
"path": "tests/testIssue0044_setIntervalArrowFunction.js",
"chars": 5417,
"preview": "var RegPack = require(\"../regPack\")\nvar fs = require(\"fs\");\nvar assert = require(\"assert\");\n\n\nfunction runTests() {\n\tcon"
},
{
"path": "tests/testIssue0045_closingBracket.js",
"chars": 1132,
"preview": "var RegPack = require(\"../regPack\")\nvar assert = require(\"assert\");\n\nfunction runTests() {\n\tconsole.log(\"Issue #0045 - ]"
},
{
"path": "tests/testIssue0047_EscapeInCharClass.js",
"chars": 8815,
"preview": "var RegPack = require(\"../regPack\")\nvar fs = require(\"fs\");\nvar assert = require(\"assert\");\n\nfunction runTests() {\n\tcons"
},
{
"path": "tests/testIssue0050_unicodeSurrogate.js",
"chars": 2264,
"preview": "var RegPack = require(\"../regPack\")\nvar assert = require(\"assert\");\n\nfunction runTests() {\n\tconsole.log(\"Issue #0050 - "
},
{
"path": "tests/testIssue0055_stringDelimiters.js",
"chars": 5768,
"preview": "var RegPack = require(\"../regPack\");\nvar fs = require(\"fs\");\nvar assert = require(\"assert\");\n\nfunction runTests() {\n\tcon"
},
{
"path": "tests/testIssue0056_setIntervalDefaultParams.js",
"chars": 10485,
"preview": "var RegPack = require(\"../regPack\")\nvar fs = require(\"fs\");\nvar assert = require(\"assert\");\n\n\nfunction runTests() {\n\tcon"
},
{
"path": "tests/testIssue0057_replacementInString.js",
"chars": 1533,
"preview": "var RegPack = require(\"../regPack\")\nvar fs = require(\"fs\");\nvar assert = require(\"assert\");\n\n\nfunction runTests() {\n\tcon"
},
{
"path": "tests/testIssue0058_numberAsLoopVariable.js",
"chars": 2451,
"preview": "var RegPack = require(\"../regPack\")\nvar fs = require(\"fs\");\nvar assert = require(\"assert\");\n\n\nfunction runTests() {\n\tcon"
},
{
"path": "tests/testIssue0059_negatedRangeMerge.js",
"chars": 1710,
"preview": "var RegPack = require(\"../regPack\")\nvar fs = require(\"fs\");\nvar assert = require(\"assert\");\n\nfunction runTests() {\n\tcons"
},
{
"path": "tests/testIssue0063_backtickFunctionParam.js",
"chars": 2333,
"preview": "var RegPack = require(\"../regPack\");\nvar fs = require(\"fs\");\nvar assert = require(\"assert\");\n\nfunction runTests() {\n\tcon"
},
{
"path": "tests/testIssue0064_utf8EncodeURI.js",
"chars": 1374,
"preview": "var RegPack = require(\"../regPack\")\nvar fs = require(\"fs\");\nvar assert = require(\"assert\");\n\nfunction runTests() {\n\tcons"
},
{
"path": "tests/testIssue0065_invalidEscapeSequence.js",
"chars": 4326,
"preview": "var RegPack = require(\"../regPack\")\nvar fs = require(\"fs\");\nvar assert = require(\"assert\");\n\nfunction runTests() {\n\tcons"
},
{
"path": "tests/testIssue0072_setIntervalNoInitCode.js",
"chars": 2668,
"preview": "var RegPack = require(\"../regPack\")\nvar fs = require(\"fs\");\nvar assert = require(\"assert\");\n\n\nfunction runTests() {\n\tcon"
},
{
"path": "tests/testIssue0074_keepWhiteSpaceSeparator.js",
"chars": 2759,
"preview": "var RegPack = require(\"../regPack\")\nvar fs = require(\"fs\");\nvar assert = require(\"assert\");\n\nfunction runTests() {\n\tcons"
},
{
"path": "tests/testIssue0076_listVariablesInString.js",
"chars": 2165,
"preview": "var RegPack = require(\"../regPack\");\nvar fs = require(\"fs\");\nvar assert = require(\"assert\");\n\nfunction runTests() {\n\tcon"
},
{
"path": "tests/testIssue0079_CandXMLComments.js",
"chars": 3911,
"preview": "var RegPack = require(\"../regPack\")\nvar fs = require(\"fs\");\nvar assert = require(\"assert\");\n\nfunction runTests() {\n\tcons"
},
{
"path": "tests/testIssue0082_backticksInTemplateLiterals.js",
"chars": 3072,
"preview": "var RegPack = require(\"../regPack\");\nvar fs = require(\"fs\");\nvar assert = require(\"assert\");\n\nfunction runTests() {\n\tcon"
},
{
"path": "tests/testIssue0083_backslashToken.js",
"chars": 2988,
"preview": "var RegPack = require(\"../regPack\");\nvar fs = require(\"fs\");\nvar assert = require(\"assert\");\n\nfunction runTests() {\n\tcon"
},
{
"path": "tests/testIssue0085_backslashSequenceLength.js",
"chars": 3086,
"preview": "var RegPack = require(\"../regPack\")\nvar fs = require(\"fs\");\nvar assert = require(\"assert\");\n\nfunction runTests() {\n\tcons"
},
{
"path": "tests/testIssue0087_firstCharacterInPattern.js",
"chars": 1241,
"preview": "var RegPack = require(\"../regPack\")\nvar fs = require(\"fs\");\nvar assert = require(\"assert\");\n\nfunction runTests() {\n\tcons"
},
{
"path": "tests/testIssue0088_setIntervalAllocateVariable.js",
"chars": 1752,
"preview": "var RegPack = require(\"../regPack\")\nvar fs = require(\"fs\");\nvar assert = require(\"assert\");\n\nfunction runTests() {\n\tcons"
},
{
"path": "tests/testIssue0089_emptyThermalMapping.js",
"chars": 1090,
"preview": "var RegPack = require(\"../regPack\")\nvar ThermalViewer = require(\"../thermalViewer\")\nvar fs = require(\"fs\");\nvar Document"
},
{
"path": "tests/testIssue0094_missingVariableBlock.js",
"chars": 1567,
"preview": "var RegPack = require(\"../regPack\")\nvar fs = require(\"fs\");\nvar assert = require(\"assert\");\n\nfunction runTests() {\n\tcons"
},
{
"path": "tests/testIssue0096_multiLineMinification.js",
"chars": 2861,
"preview": "var RegPack = require(\"../regPack\")\nvar fs = require(\"fs\");\nvar assert = require(\"assert\");\n\nfunction runTests() {\n\tcons"
},
{
"path": "tests/testPackingConsistency.js",
"chars": 4726,
"preview": "var RegPack = require(\"../regPack\");\nvar fs = require(\"fs\");\nvar assert = require(\"assert\");\n\n\nfunction runTests() {\n\tco"
},
{
"path": "tests/testStringHelper.js",
"chars": 8827,
"preview": "var StringHelper = require(\"../stringHelper\")\nvar PackerData = require(\"../packerData\");\nvar fs = require(\"fs\");\nvar ass"
},
{
"path": "tests/testWebGLContextCreate.js",
"chars": 8737,
"preview": "var RegPack = require(\"../regPack\")\nvar fs = require(\"fs\");\nvar assert = require(\"assert\");\n\n\nfunction runTests() {\n\tcon"
},
{
"path": "thermalViewer.js",
"chars": 4341,
"preview": "/**\n * @constructor\n * The ThermalViewer class renders the original code into a DHTML view,\n * using background color to"
}
]
// ... and 2 more files (download for full content)
About this extraction
This page contains the full source code of the Siorki/RegPack GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 133 files (423.1 KB), approximately 133.0k tokens, and a symbol index with 142 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.
Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.