Add Library

This commit is contained in:
Siwat Sirichai 2019-08-09 09:01:56 +07:00
parent e365b9dbd9
commit 3c47103b39
318 changed files with 56465 additions and 0 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 95 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 74 KiB

View file

@ -0,0 +1,152 @@
# bitluni's ESP32Lib
ESP32Lib is a collection features for the ESP32 including highest performance VGA graphics (sprites, 3D), sound and game controllers packed in an Arduino library.
Check out https://youtube.com/bitlunislab for project updates
If you found it useful please consider supporting my work on
Patreon https://patreon.com/bitluni
Paypal https://paypal.me/bitluni
# Acknowledgements
Thanks to Ivan Grokhotkov & Jeroen Domburg (aka Sprite_tm) for their great work on I2S revealing some nitty-gritty details and quirks of the ESP32.
Special thanks to Fabrizio Di Vittorio for the inpiration to look deeper into 8Bit modes enabling higher resolutions. He developed the FabGL library simultaneously.
# License
bitluni 2019
Creative Commons Attribution ShareAlike 4.0
https://creativecommons.org/licenses/by-sa/4.0/
If you need another license, please feel free to contact me
# Documentation
## Installation
This library only supports the ESP32.
I be able to install the ESP32 features in the board manager you need to add an additional Boards Manager URL in the Preferences (File -> Preferences)
```
https://dl.espressif.com/dl/package_esp32_index.json
```
The ESP32Lib can be found in the Library Manager (Sketch -> Include Library -> Manage Libaries)
To be able to use the library featues the main header needs to included in the sketch
```cpp
#include <ESP32Lib.h>
```
## VGA Features
ESP32Lib implements VGA output over I²S.
The highest possible resolution with this library is 800x600.
Many common resolutions like 320x240 are preconfigured und can be used without any effort.
Two color depths are available. 14Bit R5G5B4 and 3Bit(8 color) R1G1B1 for convenience and memory savings.
To simplify things you can find boards specially designed to work with this library in my shop:
https://www.tindie.com/stores/bitluni/
Any purchase supports the further development. Thanks!
### Predefined Pin Configurations
A simplified way to configure the pins for shields from my tindie store is using the default predefined configurations VGAv01, VGABlackEdition, VGAWhiteEdition, PicoVGA like this:
```cpp
vga.init(vga.MODE320x200, vga.VGABlackEdition);
```
### Pin configuration
An VGA cable can be used to connect to the ESP32
The connector pins can be found here: https://en.wikipedia.org/wiki/VGA_connector
The 3Bit modes are very easy to set up. You can connect
the Ground, Red, Green, Blue, hSync and vSync to output pins of the ESP32.
![3Bit color setup](/Documentation/schematic3bit.png)
The 14Bit mode require a resistor ladder to be set up for each color (DAC) as shown here
![14Bit color setup](/Documentation/schematic.png)
There are limitation on which the VGA output an DACs can work:
I/O GPIO pads are 0-19, 21-23, 25-27, 32-39
Input/Output GPIOs are 0-19, 21-23, 25-27, 32-33.
GPIO pads 34-39 are input-only.
Beware of pin 0. It selects the boot mode.
It's not suitable for color channels and might cause problems as sync signals as well.
Pin 5 is often tied to the LED but can be used as hSync if you don't need the LED.
I²C is on 21 (SDA), 22(SCL)
DACs are 25, 26
ins 1(TX), 3(RX) sould only be used if really don't need to communicate anymore.
Here is an overview for your convenience:
(0), 2, 4, (5), 12, 13, 14, 15, 16, 17, 18, 19, 21, 22, 23, 27, 32, 33
### Usage
There are 4 diffent VGA Drivers **VGA3Bit**, **VGA3BitI**, **VGA14Bit** and **VGA14BitI**.
VGA3Bit, VGA14Bit are the high performance drivers that don't need any CPU time to
serve the VGA. However the VGA3Bit driver takes twice the memory compared to VGA3BitI.
The high performace drivers work the best with the WiFi features. The other driver might
cause errors. WiFi should connect first before VGA3BitI and VGA14BitI is initialized.
The *I* drivers are using an interrupt to feed the pixels to the I²S. This feature can be used for realtime outputs (Check the **VGANoFramebuffer** example).
An instance of the driver has to be created. The optional parameter (only for 14 bit versions) is the I²S bus to be used. If no parameter is given 1 is used by default to keep I²S0 free for audio output.
```cpp
VGA14Bit vga(1);
```
Creating the instance does nothing until the init method is called once. The driver will initialize with one frame buffer by default (that's the memory where the pixels are stored).
Showing animated using only one frame buffer will cause flickering since the frame will be displayed while it is redrawn. To have smooth animations double buffering is recommended.
A second - the back buffer - is used to paint the graphics in the back ground. When the rendering is finished the front and back buffer are flipped. The disadvantage of the second buffer is
the doubled memory requirements. 320x240 will no longer work (320x200 will).
**Double buffering** is enabled using
```cpp
vga.setFrameBufferCount(2);
```
before the init method is called (not calling it will result in a single buffer init)
```cpp
vga.init(vga.MODE320x200, redPins, greenPins, bluePins, hsyncPin, vsyncPin);
```
The R, G and B pins are passed as arrays for the 14Bit driver and as single integers for the 3Bit version. Please try the examples
The following modes are predefined:
- MODE320x480
- MODE320x240
- MODE320x120
- MODE320x400
- MODE320x200
- MODE360x400
- MODE360x200
- MODE360x350
- MODE360x175
- MODE320x350
- MODE320x175
- MODE400x300
- MODE400x150
- MODE400x100
- MODE200x150
- MODE500x480
- MODE500x240
- MODE800x600
- MODE720x400
- MODE720x350
- MODE640x480
- MODE640x400
- MODE800x600
These native modes require a too high pixel clock but can be used as a base to create a custom resolution. Please check out the **VGACustomResolution** example:
- MODE1280x1024
- MODE1280x960
- MODE1280x800
- MODE1024x768
### 2D features
The vga instance implements several drawing methods that can be seen in the **VGA2DFeatures** example.
A complete list will be available in an API documentation soon...
## Converting 3D Meshes
The Utilities folder provides a convenient [StlConverter](https://htmlpreview.github.io/?https://github.com/bitluni/ESP32Lib/blob/master/Utilities/StlConverter.html) that you can use directly from the browser. No worries, your files are not uploaded.
Make sure your STL is low poly. The 3D example use a model with < 5000 triangles.
## Converting Sprites and Images
The Utilities folder provides a convenient [SpriteEditor](https://htmlpreview.github.io/?https://github.com/bitluni/ESP32Lib/blob/master/Utilities/SpriteEditor.html) that you can use directly from the browser. No worries, your files are not uploaded.
The correct pixel format for VGA14Bit and VGA3Bit is R5G5B4A2 (that will be improved in future). You can import PNG files to use transparency.
Each sprite has the origin in the center by default. You can modify it by changing the x/y values of the first point definition. Clicking on the image creates additional points that can be used for other purpouses like hit boxes etc.

View file

@ -0,0 +1,624 @@
<!--
Author: bitluni 2019
License:
Creative Commons Attribution ShareAlike 4.0
https://creativecommons.org/licenses/by-sa/4.0/
For further details check out:
https://youtube.com/bitlunislab
https://github.com/bitluni
http://bitluni.net
-->
<head>
<title>bitluni's Sprite Editor</title>
<script>
var project = {
name: "sprites",
zoom: 4,
sprites: []
};
function objFromId(id)
{
for(var i = 0; i < project.sprites.length; i++)
if(project.sprites[i].id === id)
return project.sprites[i];
return null;
}
function upSprite(id)
{
var sprites = project.sprites;
for(var i = 1; i < sprites.length; i++)
if(sprites[i].id === id)
{
var w = sprites[i - 1];
sprites[i - 1] = sprites[i];
sprites[i] = w;
update();
return;
}
}
function downSprite(id)
{
var sprites = project.sprites;
for(var i = 0; i < sprites.length - 1; i++)
if(sprites[i].id === id)
{
var w = sprites[i + 1];
sprites[i + 1] = sprites[i];
sprites[i] = w;
update();
return;
}
}
function deleteSprite(id)
{
var sprites = project.sprites;
for(var i = 0; i < sprites.length; i++)
if(sprites[i].id === id)
{
sprites.splice(i, 1);
update();
return;
}
}
function newButton(text, cb)
{
var b = document.createElement("button");
b.innerHTML = text;
b.onclick = cb;
return b;
}
function checker(ctx, xres, yres)
{
for(var y = 0; y < yres; y++)
for(var x = 0; x < xres; x++)
{
ctx.fillStyle = (x + y) & 1 ? "#eeeeee" : "#ffffff";
ctx.fillRect(x * 10, y * 10, 10, 10);
}
}
function draw(obj)
{
checker(obj.ctx, obj.xres, obj.yres);
var img = obj.ctx.getImageData(0, 0, obj.xres, obj.yres);
var p = 0;
for(var y = 0; y < obj.yres; y++)
for(var x = 0; x < obj.xres; x++)
{
var a = obj.source[p + 3];
var ra = 255 - a;
img.data[p + 0] = Math.round((img.data[p + 0] * ra + obj.source[p + 0] * a) / 255.);
img.data[p + 1] = Math.round((img.data[p + 1] * ra + obj.source[p + 1] * a) / 255.);
img.data[p + 2] = Math.round((img.data[p + 2] * ra + obj.source[p + 2] * a) / 255.);
img.data[p + 3] = 255;
p += 4;
}
obj.ctx.putImageData(img, 0, 0);
obj.ctx.fillStyle = "rgba(0, 255, 0, 0.7)";
for(var i = 0; i < obj.points.length; i++)
{
var p = obj.points[i];
obj.ctx.fillRect(p[0] - 3, p[1], 7, 1);
obj.ctx.fillRect(p[0], p[1] - 3, 1, 7);
}
}
function getXY(obj, e)
{
var r = obj.canvas.getBoundingClientRect();
return [Math.floor(e.offsetX / project.zoom), Math.floor(e.offsetY / project.zoom)];
}
function canvasClick(obj, e)
{
var pos = getXY(obj, e);
obj.points.push(pos);
draw(obj);
updatePoints(obj);
}
function canvasMove(obj, e)
{
var pos = getXY(obj, e);
draw(obj);
obj.ctx.fillStyle = "rgba(255, 0, 0, 0.7)";
obj.ctx.fillRect(0, pos[1], pos[0], 1);
obj.ctx.fillRect(pos[0] + 1, pos[1], obj.xres - pos[0] - 1, 1);
obj.ctx.fillRect(pos[0], 0, 1, pos[1]);
obj.ctx.fillRect(pos[0], pos[1] + 1, 1, obj.yres - pos[1] - 1);
}
function canvasOut(obj)
{
draw(obj);
}
function createCanvas(obj)
{
var canvas = obj.canvas = document.createElement('canvas');
var ctx = obj.ctx = canvas.getContext('2d');
canvas.width = obj.xres;
canvas.height = obj.yres;
canvas.addEventListener("mousedown", function(e){ canvasClick(obj, e); }, false);
canvas.addEventListener("mouseout", function(){ canvasOut(obj); }, false);
canvas.addEventListener("mousemove", function(e){ canvasMove(obj, e); }, false);
}
function addFile(file, id)
{
var obj = {"id": id, "name": file.name, "type": file.type, "xres": 0, "yres": 0, "points":[]};
project.sprites.push(obj);
var reader = new FileReader();
reader.onload = function()
{
var img = document.createElement('img');
img.onload = function()
{
obj.xres = img.width;
obj.yres = img.height;
createCanvas(obj);
obj.ctx.drawImage(img, 0, 0);
obj.source = Array.from(obj.ctx.getImageData(0, 0, obj.xres, obj.yres).data);
obj.points.push([Math.floor(obj.xres * 0.5), Math.floor(obj.yres * 0.5)]);
update();
};
img.src = reader.result;
};
reader.readAsDataURL(file);
}
function addFiles(event)
{
for(var i = 0; i < event.target.files.length; i++)
{
var file = event.target.files[i];
addFile(file, "f" + file.name.replace(/[^A-Z0-9]/ig, "_") + Math.floor(Math.random() * 1000000))
}
event.target.value = "";
}
function spritesToHeader(pixelformat)
{
var name = project.name;
var sprites = project.sprites;
var offsets = [0];
var pointOffsets = [0];
var rf, rshift, gf, gshift, bf, bshift, af, ashift, type, bytesPerPixel;
switch(pixelformat)
{
case "R2G2B2A2":
{
rf = gf = bf = af = 3.;
rshift = 0;
gshift = 2;
bshift = 4;
ashift = 6;
type = "unsigned char";
bytesPerPixel = 1;
break;
}
case "R4G4B4A4":
{
rf = gf = bf = af = 15.;
rshift = 0;
gshift = 4;
bshift = 8;
ashift = 12;
type = "unsigned short";
bytesPerPixel = 2;
break;
}
case "R5G5B4A2":
{
rf = gf = 31.;
bf = 15.;
af = 3.;
rshift = 0;
gshift = 5;
bshift = 10;
ashift = 14;
type = "unsigned short";
bytesPerPixel = 2;
break;
}
default:
alert("Unsupported pixel format " + pixelformat);
return;
}
for(var i = 0; i < sprites.length; i++)
{
offsets.push(offsets[i] + (sprites[i].source.length / 4) * bytesPerPixel);
pointOffsets.push(pointOffsets[i] + sprites[i].points.length);
}
var text = "const int " + name + "Offsets[] = {"
for(var i = 0; i < offsets.length; i++)
text += offsets[i] + ", ";
text += "};\r\n";
text += "const short " + name + "PointOffsets[] = {"
for(var i = 0; i < pointOffsets.length; i++)
text += pointOffsets[i] + ", ";
text += "};\r\n";
text += "const unsigned short " + name + "Res[][2] = {"
for(var i = 0; i < sprites.length; i++)
{
text += "{" + sprites[i].xres + ", " + sprites[i].yres + "}, ";
}
text += "};\r\n";
text += "const signed short " + name + "Points[][2] = {"
for(var i = 0; i < sprites.length; i++)
for(var j = 0; j < sprites[i].points.length; j++)
text += "{" + sprites[i].points[j][0] + ", " + sprites[i].points[j][1] + "}, ";
text += "};\r\n";
var k = 0;
text += "const " + type + " " + name + "Pixels[] = {"
for(var i = 0; i < sprites.length; i++)
{
if((i & 63) == 0) text += "\r\n";
var s = sprites[i].source;
for(var j = 0; j < s.length; j+=4)
{
var r = s[j + 0];
var g = s[j + 1];
var b = s[j + 2];
var a = s[j + 3];
var c = 0;
c = (Math.round(r / 255. * rf) << rshift) + (Math.round(g / 255. * gf) << gshift) + (Math.round(b / 255. * bf) << bshift) + (Math.round(a / 255. * af) << ashift);
text += c + ", ";
k++;
if((k & 31) == 0)
text += "\n";
}
}
text += "};\r\n";
text += "Sprites " + name + "(" + sprites.length + ", " + name + "Pixels, " + name + "Offsets, " + name + "Res, " + name + "Points, " + name + "PointOffsets, Sprites::PixelFormat::" + pixelformat + ");\r\n";
return text;
}
function cropSprite(obj)
{
var bx = [obj.xres, 0];
var by = [obj.yres, 0];
var p = 3;
for(var y = 0; y < obj.yres; y++)
for(var x = 0; x < obj.xres; x++)
{
if(obj.source[p] > 0)
{
bx[0] = Math.min(bx[0], x);
bx[1] = Math.max(bx[1], x);
by[0] = Math.min(by[0], y);
by[1] = Math.max(by[1], y);
}
p += 4;
}
if(bx[0] > bx[1])
{
bx = [0, 0];
by = [0, 0];
}
var xres = bx[1] - bx[0] + 1;
var yres = by[1] - by[0] + 1;
var source = new Array(xres * yres * 4);
var p = 0;
for(var y = by[0]; y <= by[1]; y++)
for(var x = bx[0]; x <= bx[1]; x++)
{
var p0 = (y * obj.xres + x) * 4;
source[p++] = obj.source[p0++];
source[p++] = obj.source[p0++];
source[p++] = obj.source[p0++];
source[p++] = obj.source[p0++];
}
for(var i = 0; i < obj.points.length; i++)
{
obj.points[i][0] -= bx[0];
obj.points[i][1] -= by[0];
}
obj.source = source;
obj.xres = xres;
obj.yres = yres;
obj.canvas.width = xres;
obj.canvas.height = yres;
}
function crop()
{
for(var i = 0; i < project.sprites.length; i++)
cropSprite(project.sprites[i]);
update();
}
function getMeta()
{
var text = "";
for(var i = 0; i < project.sprites.length; i++)
text += i + ", " + project.sprites[i].name + "\r\n";
return text;
}
function deletePoint(id, i)
{
var obj = objFromId(id);
obj.points.splice(i, 1);
draw(obj);
updatePoints(obj);
}
function changePointX(id, i, value)
{
var obj = objFromId(id);
obj.points[i][0] = value;
draw(obj);
}
function changePointY(id, i, value)
{
var obj = objFromId(id);
obj.points[i][1] = value;
draw(obj);
}
function addPointItem(parent, id, i, point)
{
var pointElement = document.createElement("div");
pointElement.className = "point";
var coord = document.createElement("span");
coord.innerHTML =
'<input type="number" value="' + point[0] + '" style="width: 50px" onchange="changePointX(\'' + id + '\', ' + i + ', this.value)">' +
'<input type="number" value="' + point[1] + '" style="width: 50px" onchange="changePointY(\'' + id + '\', ' + i + ', this.value)">';
pointElement.appendChild(coord);
pointElement.appendChild(newButton("&#10008;", function(){ deletePoint(id, i)}));
parent.appendChild(pointElement);
}
function updatePoints(obj)
{
var pointList = document.querySelector("#" + obj.id + " .points");
pointList.innerHTML = "";
for(var j = 0; j < obj.points.length; j++)
addPointItem(pointList, obj.id, j, obj.points[j]);
}
function addListItem(i, id, name, canvas)
{
var spriteDiv = document.createElement("div");
spriteDiv.id = id;
var index = document.createElement("span");
index.className = "num";
index.innerHTML = i;
spriteDiv.appendChild(index);
spriteDiv.appendChild(canvas);
canvas.style.zoom = project.zoom;
spriteDiv.appendChild(newButton("&#10008;", function(){ deleteSprite(id)}));
spriteDiv.appendChild(newButton("&#x2B07;", function(){ downSprite(id)}));
spriteDiv.appendChild(newButton("&#x2B06;", function(){ upSprite(id)}));
var points = document.createElement("span");
points.className = "points block right";
spriteDiv.appendChild(points);
var span = document.createElement("span");
span.className = "right";
span.innerHTML = name;
spriteDiv.appendChild(span);
document.getElementById("sprites").appendChild(spriteDiv);
}
function loadProject(event)
{
var reader = new FileReader();
reader.onload = function(e){
project = JSON.parse(e.target.result);
document.getElementById("name").value = project.name;
document.getElementById("zoom").value = project.zoom;
for(var i = 0; i < project.sprites.length; i++)
createCanvas(project.sprites[i]);
update();
};
reader.readAsText(event.target.files[0]);
document.getElementById("files").className = "hidden";
document.getElementById("filearea").innerHTML = "";
}
function saveProject()
{
document.getElementById("filearea").innerHTML = "";
var fileArea = document.getElementById("filearea");
var file = document.createElement("a");
file.className = "block file";
file.download = file.innerHTML = document.getElementById("name").value + ".json";
for(var i = 0; i < project.sprites.length; i++)
if(project.sprites[i].bs)
delete project.sprites[i].bs;
file.href = URL.createObjectURL(new Blob([JSON.stringify(project)], {type: "application/json"}));
fileArea.appendChild(file);
document.getElementById("files").className = "menu";
}
function saveHeader()
{
document.getElementById("filearea").innerHTML = "";
var fileArea = document.getElementById("filearea");
var file = document.createElement("a");
var meta = document.createElement("a");
meta.className = file.className = "block file";
file.download = file.innerHTML = project.name + ".h";
meta.download = meta.innerHTML = project.name + ".txt";
var e = document.getElementById("pixelformat");
var pixelformat = e.options[e.selectedIndex].value;
file.href = URL.createObjectURL(new Blob([spritesToHeader(pixelformat)], {type: "text/plain"}));
meta.href = URL.createObjectURL(new Blob([getMeta()], {type: "text/plain"}));
fileArea.appendChild(file);
fileArea.appendChild(meta);
document.getElementById("files").className = "menu";
}
function update()
{
for(var i = 0; i < project.sprites.length; i++)
if(!project.sprites[i].canvas)
return;
project.name = document.getElementById("name").value;
project.zoom = document.getElementById("zoom").value;
document.getElementById("sprites").innerHTML = "";
for(var i = 0; i < project.sprites.length; i++)
{
addListItem(i, project.sprites[i].id, project.sprites[i].name, project.sprites[i].canvas);
updatePoints(project.sprites[i]);
draw(project.sprites[i]);
}
document.getElementById("files").className = "hidden";
document.getElementById("filearea").innerHTML = "";
}
</script>
<style>
#sprites
{
}
.num
{
width: 20px;
display: inline-block;
}
.option
{
margin: 3px;
}
.options
{
background-color: #aeaeee;
}
.spritefiles
{
background-color: #aeeeee;
}
.menu
{
background-color: #eeeeee;
padding: 1px;
display: block;
margin: 3px;
padding: 5px;
border-radius: 3px;
}
#sprites > div
{
margin: 2px;
border-radius: 3px;
background-color: #aeeeae;
padding: 10px;
overflow: hidden;
}
#sprites > div > *
{
margin-right: 5px;
vertical-align: top;
}
#sprites button
{
float: right;
}
.right
{
float: right;
}
h1
{
color: white;
background: #800000;
padding: 10px;
border-radius: 5px;
}
.block
{
padding: 5px;
display: inline-block;
border-radius: 3px;
}
.project
{
background-color: #eeeeae;
}
.hidden
{
display: none;
}
.file
{
background-color: #ffdddd;
margin-right: 5px;
}
h1
{
margin-bottom: 5px;
}
canvas
{
cursor: none;
image-rendering: pixelated;
}
.points
{
background-color: #eeddcc;
}
.point
{
background-color: #ccddee;
margin: 2px;
border-radius: 3px;
padding: 10px;
overflow: hidden;
}
.point input
{
height: 23px;
}
</style>
</head>
<body style="font-family: arial">
<h1>bitluni's Sprite Editor</h1>
<div style="max-width: 800px">
<div class="menu">
<span class="project block">
<button title="Open project file" onclick="document.getElementById('openproject').click()">&#x1F4C2;</button>
<input id="openproject" type="file" onchange="loadProject(event)" accept=".json" hidden>
<button title="Generate project file" onclick="saveProject();">&#128190;</button>
</span>
<span class="block spritefiles">
<button title="Add image files" onclick="document.getElementById('addimages').click()">&#127750;</button>
<input id="addimages" type="file" onchange="addFiles(event)" accept="image/*" multiple hidden>
<button title="Export sprite header" onclick="saveHeader();" style="font-size: 15px; font-weight:bold">.h</button>
<select id="pixelformat" title="Export pixel format">
<option vlaue="R2G2B2A2">R2G2B2A2</option>
<option vlaue="R5G5B4A2">R5G5B4A2</option>
<option vlaue="R4G4B4A4">R4G4B4A4</option>
</select>
</span>
<span class="block options">
<span class="option">name <input id="name" type="text" value="sprites" style="width: 80px" onchange="update()"></span>
<span class="option">&#128270;<input id="zoom" type="number" value="4" style="width: 50px" onchange="update()"></span>
<span class="option"><button title="Crop sprites" onclick="crop();">&#8983;</button></span>
</span>
</div>
<div class="hidden" id="files">
Files
<div id="filearea">
</div>
</div>
<div id="sprites"></div>
</div>
<small>check out <a href="https://youtube.com/bitlunislab">bitluni's lab</a></small>
</body></html>

View file

@ -0,0 +1,255 @@
<!--
Author: bitluni 2019
License:
Creative Commons Attribution ShareAlike 4.0
https://creativecommons.org/licenses/by-sa/4.0/
For further details check out:
https://youtube.com/bitlunislab
https://github.com/bitluni
http://bitluni.net
-->
<head>
<script>
function readStl(stl, removeDouble)
{
//digital high five to @tonylukasavage for his https://github.com/tonylukasavage/jsstl
var data = {
vertexCount: 0,
triangleCount: 0,
edgeCount: 0,
triangles: [],
edges: [],
vertices: [],
triangleNormals: []
}
var map = [];
var o = 80;
var dv = new DataView(stl);
var triangleCount = dv.getUint32(o, true);
o += 4;
for (var j = 0; j < triangleCount; j++)
{
var t = [];
data.triangleNormals.push([dv.getFloat32(o, true), dv.getFloat32(o + 4, true), dv.getFloat32(o + 8, true)]);
o += 12;
for (var i = 0; i < 3; i++)
{
var v = [dv.getFloat32(o, true), dv.getFloat32(o + 4, true), dv.getFloat32(o + 8, true)];
if(removeDouble)
{
var newv = false;
if(map["f"+v[0]] === undefined)
map["f"+v[0]] = [];
if(map["f"+v[0]]["f"+v[1]] === undefined)
map["f"+v[0]]["f"+v[1]] = [];
if(map["f"+v[0]]["f"+v[1]]["f"+v[2]] === undefined)
{
map["f"+v[0]]["f"+v[1]]["f"+v[2]] = data.vertices.length;
t.push(data.vertices.length);
data.vertices.push(v);
}
else
t.push(map["f"+v[0]]["f"+v[1]]["f"+v[2]]);
}
else
{
t.push(data.vertices.length);
data.vertices.push(v);
}
o += 12;
}
data.triangles.push(t);
o += 2;
}
return data;
};
function scaleMesh(mesh)
{
if(!mesh.vertices.length) return;
var min = [mesh.vertices[0][0], mesh.vertices[0][1], mesh.vertices[0][2]];
var max = [min[0], min[1], min[2]];
for(var i = 0; i < mesh.vertices.length; i++)
{
var v = mesh.vertices[i];
min[0] = Math.min(min[0], v[0]);
min[1] = Math.min(min[1], v[1]);
min[2] = Math.min(min[2], v[2]);
max[0] = Math.max(max[0], v[0]);
max[1] = Math.max(max[1], v[1]);
max[2] = Math.max(max[2], v[2]);
}
size = Math.max(Math.max(max[0] - min[0], max[1] - min[1]), max[2] - min[2]);
for(var i = 0; i < mesh.vertices.length; i++)
{
var v = mesh.vertices[i];
v[0] = (v[0] - (max[0] + min[0]) * 0.5) / size;
v[1] = (v[1] - (max[1] + min[1]) * 0.5) / size;
v[2] = (v[2] - (max[2] + min[2]) * 0.5) / size;
}
}
function createEdges(mesh)
{
var map = [];
mesh.edges = [];
for(var i = 0; i < mesh.triangles.length; i++)
{
var t = mesh.triangles[i];
for(var j = 0; j < 3; j++)
{
var v0 = t[j];
var v1 = t[(j + 1) % 3];
if(v0 > v1)
{
var v = v0; v0 = v1; v1 = v;
}
if(map["v" + v0] === undefined)
map["v" + v0] = [];
if(map["v" + v0]["v" + v1] === undefined)
{
mesh.edges.push([v0, v1]);
map["v" + v0]["v" + v1] = true;
}
}
}
}
function meshToText(mesh, digits, edges, triangles, normals, name)
{
var text = "namespace " + name + "\r\n{\r\n";
text += "const int vertexCount = " + mesh.vertices.length + ";\r\n";
if(edges)
text += "const int edgeCount = " + mesh.edges.length + ";\r\n";
if(triangles)
text += "const int triangleCount = " + mesh.triangles.length + ";\r\n";
text += "const float vertices[][3] = {"
for(var i = 0; i < mesh.vertices.length; i++)
{
if((i & 15) == 0) text += "\r\n";
text += mesh.vertices[i][0].toFixed(digits) + ", " + mesh.vertices[i][1].toFixed(digits) + ", " + mesh.vertices[i][2].toFixed(digits) + ", ";
}
text += "};\r\n";
if(triangles)
{
text += "const unsigned short triangles[][3] = {";
for(var i = 0; i < mesh.triangles.length; i++)
{
if((i & 15) == 0) text += "\r\n";
text += mesh.triangles[i][0] + ", " + mesh.triangles[i][1] + ", " + mesh.triangles[i][2] + ", ";
}
text += "};\r\n";
}
if(edges)
{
text += "const unsigned short edges[][2] = {";
for(var i = 0; i < mesh.edges.length; i++)
{
if((i & 15) == 0) text += "\r\n";
text += mesh.edges[i][0] + ", " + mesh.edges[i][1] + ", ";
}
text += "};\r\n";
}
if(normals)
{
text += "const float triangleNormals[][3] = {";
for(var i = 0; i < mesh.triangles.length; i++)
{
if((i & 15) == 0) text += "\r\n";
text += mesh.triangleNormals[i][0].toFixed(digits) + ", " + mesh.triangleNormals[i][1].toFixed(digits) + ", " + mesh.triangleNormals[i][2].toFixed(digits) + ", ";
}
text += "};\r\n";
}
text += "};\r\n";
return text;
}
function convert(event)
{
var reader = new FileReader();
var file = event.target.files[0];
reader.onload = function(){
mesh = readStl(reader.result, true);
scaleMesh(mesh);
createEdges(mesh);
var link = document.createElement("a");
var name = file.name.split('.', 1)[0];
link.download = name + ".h";
link.href = URL.createObjectURL(new Blob(
[meshToText(mesh, 4,
document.getElementById("edges").checked,
document.getElementById("tris").checked,
document.getElementById("triNorms").checked, name)], {type: "text/plain"}));
document.body.appendChild(document.createElement("br"));
document.body.appendChild(link);
link.innerHTML = link.download;
link.click();
//document.body.removeChild(link);
event.target.value = "";
}
reader.readAsArrayBuffer(file);
}
</script><style>
.menu
{
background-color: #eeeeee;
padding: 1px;
display: block;
margin: 3px;
padding: 5px;
border-radius: 3px;
}
h1
{
color: white;
background: #800000;
padding: 10px;
border-radius: 5px;
}
.file
{
background-color: #ffdddd;
margin-right: 5px;
}
h1
{
margin-bottom: 5px;
}
.block
{
padding: 5px;
display: inline-block;
border-radius: 3px;
}
.options
{
background-color: #aeeeee;
}
.fileselection
{
background-color: #eeeeae;
}
</style>
</head>
<body style="font-family: arial">
<h1>bitluni's STL Converter</h1>
<div style="max-width: 800px">
<div class="menu">
Choose data structures to export and open the binary STL file to convert it to a c++ header file.<br>
Normals are needed to calculate lighting.<br>
<span class="options block">
Export: <input id="edges" type="checkbox">edges <input id="tris" type="checkbox" checked>triangles <input id="triNorms" type="checkbox" checked>triangle normals<br>
</span>
<span class="fileselection block">
<input type="file" onchange="convert(event)" accept=".stl">
</span>
</div>
</body></html>

View file

@ -0,0 +1,97 @@
//This example shows a rendering of Julia set. Please change the pinConfig if you are using a different board to PicoVGA
//cc by-sa 4.0 license
//bitluni
//include libraries
#include <ESP32Lib.h>
#include <Ressources/Font6x8.h>
//VGA Device
VGA6Bit vga;
//Pin presets are avaialable for: VGAv01, VGABlackEdition, VGAWhiteEdition, PicoVGA
const PinConfig &pinConfig = VGA6Bit::PicoVGA;
int taskData[2][3] =
{
{0, 0, 160},
{0, 160, 320}
};
static float v = -1.5;
static float vs = 0.001;
//https://en.wikipedia.org/wiki/Julia_set#Pseudocode_for_normal_Julia_sets
int julia(int x, int y, float cx, float cy)
{
int zx = ((x - 159.5f) * (1.f / 320.f * 5.0f)) * (1 << 12);
int zy = ((y - 99.5f) * (1.f / 200.f * 3.0f)) * (1 << 12);
int i = 0;
const int maxi = 17;
int cxi = cx ;
int cyi = cy * (1 << 12);
while(zx * zx + zy * zy < (4 << 24) && i < maxi)
{
int xtemp = (zx * zx - zy * zy) >> 12;
zy = ((zx * zy) >> 11) + cyi;
zx = xtemp + cxi;
i++;
}
return i;
}
int colors[] = {
0b110001, 0b110010, 0b110011, 0b100011, 0b010011,
0b000011, 0b000111, 0b001011, 0b001111, 0b001110, 0b001101,
0b001100, 0b011100, 0b101100, 0b111100, 0b111000, 0b110100,
0b110000};
void renderTask(void *param)
{
int *data = (int*)param;
while(true)
{
while(!data[0]) delay(1);
for(int y = 0; y < 100; y++)
for(int x = data[1]; x < data[2]; x++)
{
int c = colors[julia(x, y, -0.74543f, v)];
vga.dotFast(x, y, c);
vga.dotFast(319 - x, 199 - y, c);
}
data[0] = 0;
}
}
//initial setup
void setup()
{
//initializing i2s vga (with only one framebuffer)
vga.init(vga.MODE320x200, pinConfig);
TaskHandle_t xHandle = NULL;
xTaskCreatePinnedToCore(renderTask, "Render1", 2000, taskData[0], ( 2 | portPRIVILEGE_BIT ), &xHandle, 0);
xTaskCreatePinnedToCore(renderTask, "Render2", 2000, taskData[1], ( 2 | portPRIVILEGE_BIT ), &xHandle, 1);
}
//just draw each frame
void loop()
{
static unsigned long ot = 0;
unsigned long t = millis();
unsigned long dt = t - ot;
ot = t;
taskData[0][0] = 1;
taskData[1][0] = 1;
//waiting for task to finish
while(taskData[0][0] || taskData[1][0]) delay(1);
v += vs * dt;
if(v > 1.5f)
{
v = 1.5f;
vs = -vs;
}
if(v < -1.5f)
{
v = -1.5f;
vs = -vs;
}
}

View file

@ -0,0 +1,32 @@
//This example shows how to use the GfxWrapper to be able to use the Adafruit GFX library with VGA
//cc by-sa 4.0 license
//bitluni
#include <ESP32Lib.h>
#include <Ressources/Font6x8.h>
#include <GfxWrapper.h>
#include <Fonts/FreeMonoBoldOblique24pt7b.h>
#include <Fonts/FreeSerif9pt7b.h>
//VGA Device
VGA6Bit vga;
GfxWrapper<VGA6Bit> gfx(vga, 640, 400);
//initial setup
void setup()
{
//initializing i2s vga (with only one framebuffer)
//Pin presets are avaialable for: VGAv01, VGABlackEdition, VGAWhiteEdition, PicoVGA
//But you can also use custom pins. Check the other examples
vga.init(vga.MODE640x400, vga.VGABlackEdition);
//using adafruit gfx
gfx.setFont(&FreeMonoBoldOblique24pt7b);
gfx.setCursor(100, 100);
gfx.print("Hello");
}
//the loop is done every frame
void loop()
{
}

View file

@ -0,0 +1,151 @@
//cc by-sa 4.0 license
//bitluni
#pragma once
class Ray
{
public:
Ray(Vector pos, Vector dir)
:p(pos), d(dir)
{
}
Vector p;
Vector d;
};
class Raytracable
{
public:
float reflection;
Vector c;
Raytracable()
{
reflection = 0;
}
virtual bool intersection(Ray &ray, Vector &i, float &t) const = 0;
virtual Vector normal(Vector &i) const = 0;
virtual Vector color(Vector &p) const = 0;
};
class Sphere : public Raytracable
{
public:
float r;
float r2;
Vector p;
Sphere(Vector pos, float radius)
:p(pos),
r(radius),
r2(radius * radius)
{
}
virtual bool intersection(Ray &ray, Vector &i, float &t) const
{
Vector L = p - ray.p;
float tca = L.dot(ray.d);
if(tca < 0) return false;
float d2 = L.dot(L) - tca * tca;
if (d2 >= r2) return false;
float thc = Vector::sqrt(r2 - d2);
float ct = tca - thc;
if(t <= ct) return false;
t = ct;
i = ray.p + ray.d * ct;
return true;
}
virtual Vector normal(Vector &i) const
{
return (i - p) * (1.f / r);
}
virtual Vector color(Vector &p) const
{
return c;
}
};
class Checker : public Raytracable
{
public:
Checker()
{
}
virtual bool intersection(Ray &ray, Vector &i, float &t) const
{
if(ray.d[1] >= 0 || ray.p[1] <= 0) return false;
float ct = ray.p[1] / -ray.d[1];
if(ct >= t) return false;
i = Vector(ray.p[0] + ray.d[0] * ct, 0, ray.p[2] + ray.d[2] * ct);
t = ct;
return true;
}
virtual Vector normal(Vector &i) const
{
return Vector(0, 1, 0);
}
virtual Vector color(Vector &p) const
{
float c = ((int)p[0] + (int)p[2] + (p[0] >= 0 ? 1 : 0)) & 1;
return Vector(0.8 + 0.2 * c, c, c);
}
};
const float FAR = 10000;
Vector raytrace(Raytracable **objects, int count, Ray &r, Vector &light, int depth, Raytracable *self = 0)
{
if(depth == 0)
return Vector(0, 0, 0);
Vector i;
float t = FAR;
Raytracable *best = 0;
for(int n = 0; n < count; n++)
{
Raytracable *o = objects[n];
if(o != self && o->intersection(r, i, t))
best = o;
}
float fog = t * 0.02f;
float fc = 0.5f - (r.d[1] < 0 ? 0 : r.d[1]) * 0.5;
Vector fogc = Vector(fc, fc, 1.0f);
if(fog >= 1) return fogc;
if(!best)
{
return fogc;
}
Vector n = best->normal(i);
float l = light.dot(n) * 0.9;
if(l < 0)
l = 0;
else
{
Ray r2(i, light);
Vector i2;
float t2 = FAR;
for(int n = 0; n < count; n++)
{
Raytracable *o = objects[n];
if(o == best) continue;
if(o->intersection(r2, i2, t2))
{
l = 0;
break;
}
}
}
Vector c = (best->color(i) * (0.1f + l)) * (1 - fog) + fogc * fog;
if(best->reflection == 0)
return c;
float dn = r.d.dot(n);
float fr = (0.2f + (1+dn) * 0.8f) * best->reflection;
if(fr < 0) fr = 0;
Vector refl = r.d - n * (dn * 2);
Ray nr = Ray(i, refl);
//return Vector(fr, fr, fr);
c = raytrace(objects, count, nr, light, depth - 1, best) * fr + c * (1 - fr);
return c;
}

View file

@ -0,0 +1,90 @@
//A realtime raytraycer utilizing both cores of the ESP32. Please change the pin configuration in the setup if you are not using VGA v0.1 or the Black Edition shields.
//cc by-sa 4.0 license
//bitluni
#include <ESP32Lib.h>
#include <Ressources/Font6x8.h>
#include <math.h>
#include <Math/Matrix.h>
#include "Raytracer.h"
//VGA Device
VGA14Bit vga;
int taskData[2][3] =
{
{0, 0, 160},
{0, 160, 320}
};
static Sphere sphere(Vector(0, 0.5f, 0), 1);
static Sphere sphere2(Vector(1, 1.5f, 0.5), 0.5f);
static Checker checker;
static Raytracable *objects[] = {&sphere, &sphere2, &checker};
static Vector light = Vector(5, 4, -5);
void raytraceTask(void *param)
{
static Vector p(0, 1, -10);
int *data = (int*)param;
while(true)
{
while(!data[0]) delay(1);
for(int y = 0; y < 200; y++)
for(int x = data[1]; x < data[2]; x++)
{
Vector v(float(x - 160) * (1.f / 320), float(100 - y) * (1.f / 320), 1.f);
v.normalize();
Ray r(p, v);
Vector c = raytrace(objects, 3, r, light, 3);
vga.dotFast(x, y, vga.RGB(c[0] * 255, c[1] * 255, c[2] * 255));
}
data[0] = 0;
}
}
//initial setup
void setup()
{
//we need double buffering for smooth animations
vga.setFrameBufferCount(2);
//initializing i2s vga
//Pin presets are avaialable for: VGAv01, VGABlackEdition, VGAWhiteEdition, PicoVGA
//But you can also use custom pins. Check the other examples
vga.init(vga.MODE320x200, vga.VGABlackEdition);
//setting the font
vga.setFont(Font6x8);
light.normalize();
sphere.reflection = 0.4f;
sphere2.reflection = 0.5f;
checker.reflection = 0.2f;
sphere.c = Vector(0, 1, 0);
sphere2.c = Vector(1, 0, 1);
static uint8_t ucParameterToPass;
TaskHandle_t xHandle = NULL;
xTaskCreatePinnedToCore(raytraceTask, "Raytracer1", 2000, taskData[0], ( 2 | portPRIVILEGE_BIT ), &xHandle, 0);
xTaskCreatePinnedToCore(raytraceTask, "Raytracer2", 2000, taskData[1], ( 2 | portPRIVILEGE_BIT ), &xHandle, 1);
}
//the loop is done every frame
void loop()
{
taskData[0][0] = 1;
taskData[1][0] = 1;
//waiting for task to finish
while(taskData[0][0] || taskData[1][0]) delay(1);
sphere2.p.v[0] = sin(millis() * 0.0005f) * 2;
sphere2.p.v[2] = cos(millis() * 0.0005f) * 2;
sphere.p.v[1] = sphere2.p[0] * 0.3 + 1;
//setting the text cursor to the lower left corner of the screen
vga.setCursor(0, 0);
//setting the text color to white with opaque black background
vga.setTextColor(vga.RGB(0xffffff), vga.RGBA(0, 0, 0, 0));
//printing the fps
vga.print("ms/frame: ");
static long t = 0;
long ct = millis();
vga.print(ct - t);
t = ct;
vga.show();
}

View file

@ -0,0 +1,138 @@
//This example shows several 2d drawing features available for VGA
//You need to connect a VGA screen cable and an external DAC (simple R2R does the job) to the pins specified below.
//cc by-sa 4.0 license
//bitluni
//include libraries
#include <ESP32Lib.h>
#include <Ressources/Font6x8.h>
//include a sprite
#include "rock.h"
//pin configuration
const int redPins[] = {2, 4, 12, 13, 14};
const int greenPins[] = {15, 16, 17, 18, 19};
const int bluePins[] = {21, 22, 23, 27};
const int hsyncPin = 32;
const int vsyncPin = 33;
//VGA Device
VGA14Bit vga;
//initial setup
void setup()
{
//we need double buffering for smooth animations
vga.setFrameBufferCount(2);
//initializing i2s vga (with only one framebuffer)
vga.init(vga.MODE320x200, redPins, greenPins, bluePins, hsyncPin, vsyncPin);
//setting the font
vga.setFont(Font6x8);
}
//just draw each frame
void loop()
{
//some value for color ping pong
static int c = 0;
static int d = 1;
c += d;
if (c == 0 || c == 255)
d = -d;
//radius ping pong
static int r = 0;
static int dr = 1;
r += dr;
if (r == 0 || r == 31)
dr = -dr;
//clear the back buffer with black and start drawing
vga.clear(0);
int x, y;
x = 22;
y = 5;
//set the text cursor
vga.setCursor(x + 30, y);
//print the text, println also exists
vga.print("dot(x,y,c)");
//set a single pixel. dotAdd add the colors. dotMix uses the alpha to mix the colors
vga.dot(x + 60, y + 20, vga.RGB(c, 0, 255 - c));
x = 170;
y = 5;
vga.setCursor(x, y);
vga.print("line(x0,y0,x1,y1,c)");
//draw a line
vga.line(x + c / 8 + 50, y + 10, x + 32 + 40 - c / 8, y + 30, vga.RGB(0, c, 255 - c));
x = 15;
y = 40;
vga.setCursor(x + 10, y);
vga.print("rect(x, y, w, h, c)");
//draw a rectangle with the given width and height
vga.rect(x + 50, y + 15, 3 + c / 8, 19 - c / 16, vga.RGB(0, c, 255 - c));
x = 165;
y = 40;
vga.setCursor(x, y);
//draw a filled rectangle
vga.print("fillRect(x, y, w, h, c)");
vga.fillRect(x + 50, y + 15, 35 - c / 8, 3 + c / 16, vga.RGB(255 - c, c, 0));
x = 25;
y = 80;
vga.setCursor(x + 10, y);
//draw a circle with the given radius
vga.print("circle(x,y,r,c)");
vga.circle(x + 55, y + 20, 1 + r / 4, vga.RGB(255 - c, 0, c));
x = 172;
y = 80;
vga.setCursor(x, y);
//draw a filled circle
vga.print("fillCircle(x,y,r,c)");
vga.fillCircle(x + 60, y + 20, 8 - r / 4, vga.RGB(c / 2, c / 2, 255 - c));
x = 10;
y = 120;
vga.setCursor(x + 10, y);
//draw an ellipse
vga.print("ellipse(x,y,rx,ry,c)");
vga.ellipse(x + 70, y + 20, 1 + r / 2, 8 - r / 4, vga.RGB(255 - c, c, 0));
x = 160;
y = 120;
vga.setCursor(x, y);
//draw a filled ellipse
vga.print("fillEllipse(x,y,rx,ry,c)");
vga.fillEllipse(x + 70, y + 20, 16 - r / 2, 1 + r / 4, vga.RGB(255 - c, c / 2, c / 2));
x = 15;
y = 160;
vga.setCursor(x + 35, y);
vga.print("print(text)");
//generate a string
char text[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
for (int i = 0; i < 10; i++)
text[i] = 33 + (i + (c >> 2));
vga.setCursor(x + 37, y + 17);
//set the text and background color with opaque alpha (use RGBA to get a semi transparent back)
vga.setTextColor(vga.RGB(c, 255 - c, 255), vga.RGB(0, c / 2, 127 - c / 2));
vga.print(text);
//reset the text color. no second parameter makes the background transparent
vga.setTextColor(vga.RGB(255, 255, 255));
x = 165;
y = 160;
vga.setCursor(x + 15, y);
vga.print("image(image,x,y)");
//draw the imported sprite. use millis() to calculate the sprite number
//Sprites uses "image(.." internally
rock.drawMix(vga, (millis() / 50) & 15, x + 65, y + 25);
//show the rendering
vga.show();
}

View file

@ -0,0 +1,200 @@
const int rockOffsets[] = {0, 836, 1634, 2394, 3230, 4028, 4788, 5472, 6232, 6952, 7712, 8552, 9388, 10148, 10908, 11592, 12352, };
const short rockPointOffsets[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, };
const unsigned short rockRes[][2] = {{19, 22}, {19, 21}, {20, 19}, {22, 19}, {21, 19}, {20, 19}, {18, 19}, {19, 20}, {18, 20}, {20, 19}, {20, 21}, {22, 19}, {20, 19}, {19, 20}, {19, 18}, {19, 20}, };
const signed short rockPoints[][2] = {{10, 11}, {10, 10}, {10, 10}, {11, 9}, {11, 9}, {9, 9}, {9, 9}, {9, 10}, {9, 10}, {10, 10}, {10, 11}, {11, 10}, {10, 9}, {9, 10}, {9, 9}, {10, 10}, };
const unsigned short rockPixels[] = {
0, 0, 0, 0, 0, 0, 0, 24047, 24014, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8720, 56815, 56782, 40398, 24014, 7630, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 24014, 56815, 56815, 56815, 56782, 56782, 23981, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22957, 56782,
56782, 56815, 56815, 56782, 56782, 55725, 21834, 0, 0, 0, 0, 0, 0, 0, 0, 7630, 40431, 56815, 57872, 56782, 56782, 57872, 56815, 56815, 55725, 54569, 19654, 0, 0, 0, 0, 0,
0, 0, 24047, 57872, 56815, 56815, 57872, 56815, 56815, 57872, 56815, 55725, 54635, 54635, 38251, 21834, 4360, 0, 0, 0, 5483, 55725, 56782, 56815, 56815, 57872, 56815, 56815, 56815, 56782, 55725, 55692,
55692, 54635, 54602, 19654, 0, 0, 6573, 39341, 55725, 55725, 56815, 56815, 56815, 56815, 56782, 55725, 55659, 55692, 55692, 54602, 53545, 53512, 34981, 0, 6573, 55725, 56749, 55692, 55692, 55725, 55725, 56782,
56782, 55725, 55692, 54602, 54602, 53545, 53512, 52422, 52389, 51365, 2213, 21867, 55692, 55725, 55692, 54635, 55659, 55692, 55725, 55725, 55692, 54602, 52422, 52422, 51365, 51365, 51365, 51365, 51365, 18597, 38218, 54635,
54635, 54635, 53545, 53512, 54602, 54602, 54635, 54602, 53479, 51332, 51365, 51365, 51365, 51365, 51365, 51365, 19621, 20744, 54602, 54602, 53545, 53479, 52422, 52455, 52455, 53512, 53479, 51365, 51332, 51365, 51365, 51365,
51365, 51365, 51365, 34981, 2213, 52422, 53479, 53512, 53512, 52422, 51365, 51365, 51365, 52389, 51365, 51365, 51365, 51365, 51365, 51365, 51365, 51365, 18597, 0, 34981, 51365, 52389, 52389, 51365, 51365, 51365, 51365,
51365, 51365, 51365, 51365, 51365, 51365, 51365, 51365, 34981, 4360, 0, 2213, 34981, 51365, 51365, 51365, 51365, 51365, 51365, 51365, 51365, 51365, 51365, 51365, 51365, 51332, 51365, 18597, 0, 0, 0, 0,
18597, 34981, 51332, 51365, 51365, 51365, 51365, 51365, 51365, 51365, 51365, 51365, 51365, 51365, 2180, 0, 0, 0, 0, 0, 2147, 18597, 51365, 51365, 51365, 51365, 51365, 51365, 51365, 51365, 51365, 51365,
34981, 0, 0, 0, 0, 0, 0, 0, 2213, 51365, 51365, 51365, 51365, 51365, 51365, 51365, 51365, 51365, 34981, 18597, 0, 0, 0, 0, 0, 0, 0, 0, 18597, 51365, 51365, 51365,
51332, 51365, 52389, 51365, 18597, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18597, 51365, 51365, 51365, 51365, 19621, 3270, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 18597, 51365, 51365, 18597, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2213, 18597, 3237, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 24014, 7630, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5417, 22924, 22924, 24014, 56815, 56782, 39341, 5450,
24014, 40365, 24014, 0, 0, 0, 0, 0, 0, 0, 0, 6540, 55692, 55725, 56815, 57872, 56815, 56782, 40398, 56782, 56782, 55725, 21834, 0, 0, 0, 0, 0, 0, 0, 6540, 55692,
56749, 56815, 56815, 56815, 57872, 56815, 56782, 55725, 55725, 54602, 20744, 0, 0, 0, 0, 6540, 22957, 39341, 55725, 56782, 56782, 56782, 56749, 56815, 55725, 55692, 55692, 55692, 54635, 54602, 20777, 0,
0, 0, 39308, 55725, 55725, 56782, 56782, 56782, 55725, 55725, 56782, 55725, 55659, 54635, 54635, 54635, 55692, 38218, 4393, 0, 0, 39308, 55725, 55725, 56782, 56782, 55725, 55692, 55692, 55725, 55692, 54602,
53545, 54602, 54635, 54602, 53545, 36038, 0, 0, 21834, 54635, 54635, 55692, 55725, 55725, 55692, 54635, 54635, 54635, 53545, 53512, 53545, 54569, 53545, 52455, 34981, 0, 0, 20744, 54602, 53545, 53545, 54569,
54635, 54635, 54602, 54635, 54602, 53545, 52422, 52455, 52455, 52422, 52389, 34981, 0, 4393, 53512, 53545, 52422, 52422, 52455, 53512, 53479, 53512, 53545, 53545, 52455, 51365, 51365, 51365, 51365, 51365, 51365, 18564,
20744, 53545, 54569, 52422, 51365, 52389, 52389, 51365, 51365, 52422, 52422, 52389, 51365, 51365, 51365, 52422, 51365, 51365, 18597, 36038, 53545, 53545, 53479, 52422, 51365, 51365, 51365, 51365, 51365, 51365, 51365, 51365,
51365, 51365, 52422, 51365, 51365, 18597, 36005, 53512, 53545, 53512, 52455, 51365, 51365, 51365, 51365, 51365, 51365, 51365, 51365, 51365, 51365, 51365, 51365, 51365, 19621, 2147, 36005, 52389, 52389, 52422, 51365, 51365,
51365, 51365, 52422, 52422, 51365, 51365, 52389, 51365, 51365, 52389, 34981, 2213, 0, 18564, 51365, 51365, 51365, 51365, 51332, 51365, 51365, 53512, 53545, 52455, 52389, 51365, 51365, 51332, 51365, 2213, 0, 0,
0, 2213, 34981, 51365, 51365, 51365, 51365, 51365, 53479, 53545, 53512, 52389, 51365, 51365, 51365, 51365, 2180, 0, 0, 0, 0, 2213, 18597, 18597, 34981, 34981, 51365, 51365, 52389, 52389, 51365, 51365,
51365, 52389, 34981, 3270, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3270, 34948, 51365, 51365, 51365, 51365, 51365, 18597, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 2213, 34948, 51365, 51365, 51365, 18597, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18564, 34981, 34981, 2180, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2213, 2213, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7630, 40431, 22957, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8720, 40431, 56815, 56782, 39341, 21867, 5450, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 24014, 22957, 22957, 40398,
56815, 57872, 56815, 56815, 56782, 56782, 22957, 0, 0, 0, 0, 0, 0, 0, 0, 7630, 56815, 56815, 56815, 56815, 56815, 56782, 56815, 56815, 56782, 56782, 55725, 38218, 2147, 0, 0, 0,
0, 0, 0, 22957, 56782, 56815, 57872, 56782, 56782, 56782, 56782, 56815, 56782, 56749, 55692, 54602, 37128, 4393, 0, 0, 0, 0, 6573, 40398, 56782, 56782, 57872, 56815, 56782, 55725, 56782, 56782,
56782, 55725, 55692, 54635, 53545, 53512, 20744, 0, 0, 0, 21867, 55725, 56749, 56782, 56782, 56782, 56782, 55725, 55725, 55725, 55692, 54635, 55692, 54635, 53545, 53512, 37128, 0, 0, 0, 38185, 55692,
55725, 55725, 55725, 56782, 56782, 56749, 55692, 55692, 55692, 55692, 55692, 55659, 53545, 53512, 52422, 18597, 0, 18597, 53512, 54602, 55692, 55692, 55692, 55725, 55725, 55692, 54635, 54602, 54635, 55692, 55692, 55692,
54635, 53512, 51365, 34981, 2180, 18597, 52389, 52422, 53512, 53512, 52455, 53512, 54602, 54602, 54602, 54635, 54635, 54635, 54602, 54635, 54602, 53479, 51365, 51365, 18564, 2213, 51365, 51365, 52422, 52389, 51365, 51365,
52422, 52455, 54602, 54635, 55692, 55692, 54635, 54602, 53512, 52422, 51365, 51365, 18597, 0, 18597, 51365, 52389, 51365, 51365, 51365, 51365, 52455, 54635, 55692, 55692, 55725, 55692, 54569, 52455, 51365, 51365, 34981,
2180, 0, 2213, 51365, 51365, 51365, 51365, 51365, 51365, 52455, 55659, 55692, 55692, 55692, 54635, 53545, 52422, 51365, 51365, 18597, 0, 0, 2180, 51365, 51365, 51365, 51365, 51365, 51365, 53479, 54635, 55659,
54635, 54635, 53545, 52455, 52389, 51365, 34981, 3270, 0, 0, 2180, 51365, 51365, 51365, 51365, 51365, 51365, 51365, 52455, 53479, 53512, 53479, 52455, 52389, 51365, 18597, 0, 0, 0, 0, 2213, 51365,
51365, 51365, 51365, 51365, 51365, 51365, 51365, 51365, 52389, 51365, 52389, 51365, 51365, 18597, 0, 0, 0, 0, 0, 18597, 34981, 51365, 51365, 51365, 51365, 51365, 51365, 36005, 34981, 51365, 51365, 51365,
51365, 18564, 0, 0, 0, 0, 0, 0, 2147, 18597, 34981, 51365, 51365, 34981, 18564, 0, 3270, 18597, 34981, 34981, 34981, 3237, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3237,
2213, 0, 0, 0, 0, 0, 0, 0, 2180, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6573, 6573, 6540, 22924, 24014, 22957, 6540, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 6573, 56749, 56815, 56815, 56815, 56815, 56815, 55725, 39308, 20777, 22924, 22957, 22957, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7663, 56815, 57872,
56815, 56782, 56782, 56815, 56782, 56749, 55725, 55725, 55725, 55692, 6540, 0, 0, 0, 0, 0, 0, 0, 0, 40398, 56815, 56815, 56815, 56782, 56782, 56815, 56815, 56815, 56782, 55725, 55725, 55725,
39341, 5450, 0, 0, 0, 0, 0, 20777, 22924, 56782, 56815, 56782, 56815, 56815, 55725, 56749, 56815, 56782, 56782, 54602, 54635, 54635, 54602, 53512, 19621, 0, 0, 0, 0, 39308, 56782, 56782,
56782, 56815, 56782, 56782, 55725, 55725, 56782, 56782, 55725, 53512, 54569, 54569, 53545, 52455, 51365, 18597, 0, 0, 22924, 55725, 56815, 56782, 56782, 56815, 56782, 55725, 55725, 55725, 55725, 55725, 55725, 54602,
53512, 53545, 53512, 51365, 51365, 34981, 0, 21834, 54635, 55692, 55725, 55725, 56782, 56782, 56782, 55725, 55725, 55692, 55692, 54635, 55692, 55659, 54602, 53512, 52455, 51365, 51365, 34981, 0, 1057, 37128, 54635,
55692, 55725, 56782, 56782, 56782, 56815, 56815, 56782, 55725, 55692, 55659, 54635, 54602, 53545, 52455, 51365, 51365, 34981, 0, 0, 18564, 53512, 54635, 54602, 54602, 54602, 55692, 56749, 56782, 56782, 56782, 55725,
55725, 55725, 54635, 53512, 52422, 51365, 51365, 18597, 0, 0, 18597, 52389, 52422, 52389, 52389, 52422, 54569, 55725, 56782, 56782, 55725, 55692, 55692, 54635, 54569, 52422, 51332, 51365, 34981, 0, 0, 0,
2213, 51365, 51365, 51365, 51365, 51332, 52455, 54635, 55692, 55725, 55692, 54635, 54602, 53545, 52455, 51365, 51365, 51365, 18597, 0, 0, 0, 0, 18597, 34981, 51365, 51365, 51365, 51332, 52455, 53545, 53545,
52455, 53512, 53512, 52422, 51365, 51365, 51365, 51332, 18564, 0, 0, 0, 0, 0, 2213, 34981, 51365, 51365, 51365, 51365, 51365, 52389, 51365, 51365, 51365, 51365, 51365, 51365, 51365, 34948, 2180, 0,
0, 0, 0, 0, 0, 2147, 34981, 51365, 51365, 51365, 51365, 51365, 51365, 51365, 51365, 51365, 51365, 34981, 18597, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18564, 51365, 51365, 51365,
51365, 51365, 51365, 51365, 51365, 18597, 18564, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2213, 34981, 51365, 51365, 51365, 51365, 51365, 51365, 18597, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 18597, 34981, 34981, 34981, 34981, 34981, 3237, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22924, 40398, 24014, 6573, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7663, 24014, 24014, 6573, 22957, 56782, 56815, 56815, 39341, 22957, 22924, 5450, 0, 0, 0, 0, 0, 0, 0, 6507, 24047, 56815,
56815, 56815, 56815, 56815, 56815, 56815, 56815, 56782, 55725, 55692, 38218, 20744, 0, 0, 0, 0, 0, 22891, 55692, 56782, 56815, 56815, 56815, 56815, 56815, 56782, 56749, 55725, 55725, 55692, 54635, 53545,
37095, 5417, 0, 0, 0, 5450, 55692, 55692, 55725, 56782, 56815, 56815, 57872, 56815, 56782, 55725, 55725, 56749, 55692, 54602, 53512, 52422, 19654, 0, 0, 0, 6540, 55692, 55725, 55692, 55725, 56782,
56782, 56815, 56815, 56749, 55692, 55725, 55725, 55659, 54569, 53512, 52422, 34981, 0, 0, 0, 21867, 54635, 55692, 54635, 54602, 55659, 55725, 56782, 56782, 56782, 55725, 55692, 55659, 53545, 52455, 52422, 51365,
51365, 2213, 0, 0, 38251, 55692, 55692, 54635, 53512, 52455, 54602, 55692, 55725, 55725, 55725, 55692, 52455, 52389, 51365, 51365, 51365, 51365, 19621, 0, 0, 37128, 54602, 55692, 54635, 54602, 52455, 52422,
53545, 55692, 55725, 55725, 54635, 51365, 51365, 51365, 51365, 51365, 51365, 18597, 0, 3303, 53512, 53545, 55692, 55725, 55692, 55659, 53512, 53479, 55692, 55725, 55692, 52455, 51365, 51365, 51365, 51365, 51332, 51332,
34981, 0, 34981, 52422, 53545, 55692, 55725, 56782, 55725, 55692, 54602, 54635, 55692, 54635, 53545, 52389, 51365, 51365, 51365, 51365, 51365, 34981, 2213, 51365, 52389, 53545, 54602, 53545, 55659, 55725, 55692, 54602,
54602, 54602, 54569, 53545, 52422, 51365, 51365, 51365, 51365, 34981, 3270, 0, 18564, 34981, 52422, 52389, 52389, 52455, 54635, 54635, 54602, 54569, 53512, 52455, 52422, 51365, 51365, 51365, 51365, 34981, 3270, 0,
0, 0, 2213, 51365, 51365, 51365, 51365, 52422, 52422, 52422, 52422, 52389, 51365, 51365, 51365, 51365, 51365, 18597, 2213, 0, 0, 0, 0, 0, 18597, 51365, 51365, 51365, 51365, 51365, 51365, 51365,
51365, 51365, 51365, 51365, 51365, 34981, 0, 0, 0, 0, 0, 0, 0, 0, 19654, 19621, 18597, 34981, 51365, 51365, 51365, 51365, 51365, 51365, 51365, 51365, 18597, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 18597, 51365, 51365, 51365, 51365, 51365, 51365, 51365, 18597, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2180, 18597, 34981, 51365,
34981, 18597, 3237, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2213, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 24014, 24014, 24047, 7597, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6573, 40431, 57872, 56815, 56815, 40398, 40365, 22957, 22957,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22924, 56815, 56815, 56815, 56815, 56782, 56749, 55725, 55725, 21834, 3270, 0, 0, 0, 0, 0, 0, 8720, 24014, 40398, 40398,
56815, 56782, 56782, 56782, 55725, 55725, 55692, 55692, 54635, 37161, 20744, 0, 0, 0, 0, 7663, 40431, 56815, 56782, 56782, 55725, 55725, 56749, 56782, 55725, 55725, 55692, 54602, 52422, 53512, 54635, 20777,
0, 0, 0, 40398, 56782, 56815, 55725, 55725, 55692, 55725, 56782, 56782, 55725, 55692, 54602, 53512, 51365, 53545, 54602, 52455, 18564, 0, 20777, 55692, 55725, 56782, 55725, 55725, 55692, 55692, 55725, 55725,
55692, 54602, 53479, 51365, 51365, 52422, 52389, 51365, 34981, 0, 20744, 54635, 55692, 55725, 56782, 55725, 55692, 55692, 55725, 55725, 54569, 52455, 51365, 51365, 51332, 51332, 51365, 51365, 34981, 0, 19621, 52455,
53512, 54635, 55725, 55725, 55725, 55725, 55692, 53512, 51365, 51332, 52389, 53512, 52389, 51365, 51332, 51365, 18597, 0, 18564, 51332, 51365, 53545, 55659, 55692, 55692, 55692, 54602, 51365, 51365, 51365, 53512, 53545,
52422, 51365, 51365, 34981, 2213, 0, 18597, 51365, 51365, 52389, 52455, 53479, 53545, 54635, 55692, 52455, 52455, 53545, 54635, 53545, 52389, 51365, 34981, 2180, 0, 0, 2180, 18597, 51365, 51365, 51365, 51332,
51365, 53512, 54635, 54602, 53512, 53545, 54569, 52422, 51365, 51365, 18597, 0, 0, 0, 0, 18597, 52389, 52389, 52422, 51365, 51365, 52422, 53545, 53545, 52455, 52455, 52455, 51365, 51365, 51365, 34981, 0,
0, 0, 0, 18597, 51365, 52422, 52422, 51365, 51332, 51365, 52422, 52422, 52389, 51365, 51365, 51365, 51365, 51365, 18597, 0, 0, 0, 0, 18597, 51365, 51365, 51365, 51365, 51365, 51365, 51365, 52389,
51365, 51365, 51365, 51365, 51365, 34981, 2213, 0, 0, 0, 0, 0, 18597, 34981, 51365, 51365, 51365, 52389, 51365, 51365, 51365, 51365, 51365, 52389, 34981, 2180, 0, 0, 0, 0, 0, 0,
0, 3270, 18597, 34981, 34981, 51365, 51365, 51365, 51365, 51365, 34981, 18597, 3237, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18564, 34981, 18597, 18597, 2180, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4360, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 24047, 7630, 6573, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6540, 39341, 22924, 22957, 40431, 57872, 57872, 56815, 40398, 39341, 6573, 0, 0, 0, 0, 0, 0,
0, 39341, 56782, 56815, 56782, 56815, 57872, 57872, 57872, 56815, 56815, 56782, 24014, 4360, 0, 0, 0, 0, 7630, 56782, 56815, 57872, 56815, 56815, 56815, 56815, 57872, 56782, 56815, 56815, 56749, 38251,
20744, 0, 0, 0, 22957, 55725, 56782, 57872, 56782, 56782, 56782, 56782, 56815, 56782, 56749, 55725, 55692, 54602, 52422, 2213, 0, 0, 4360, 55692, 55725, 56782, 55725, 55725, 55725, 55692, 55692, 54635,
54635, 54602, 53512, 52422, 51365, 18597, 0, 22924, 38251, 55692, 55692, 55692, 55692, 55692, 55692, 54635, 54602, 53512, 53479, 52422, 51365, 51365, 51365, 18597, 6573, 55725, 55692, 54602, 54602, 54602, 54635, 54635,
54635, 53545, 52455, 51365, 51365, 51365, 51332, 51365, 51365, 2213, 22924, 55692, 54602, 53512, 53512, 54602, 54635, 54635, 54602, 52455, 51365, 51365, 51365, 51365, 51365, 51365, 51365, 18597, 38218, 54602, 53512, 52389,
51365, 52422, 54602, 54602, 54569, 52422, 51332, 52422, 52455, 52389, 51365, 51365, 51365, 34981, 19654, 52422, 52422, 51365, 51365, 51332, 53512, 54602, 53512, 51365, 51365, 53545, 53545, 52422, 51365, 51365, 51365, 34981,
19621, 51365, 51365, 52422, 52422, 52422, 53512, 53545, 52389, 51365, 52455, 54635, 54602, 52455, 51365, 51365, 51365, 18597, 0, 34981, 51365, 52422, 51365, 52389, 52455, 52422, 51365, 52455, 54569, 54635, 54602, 52422,
51365, 51365, 51365, 2180, 0, 0, 18597, 34981, 51365, 51365, 51365, 52422, 52422, 52455, 53512, 53545, 52422, 51365, 51365, 51365, 18597, 0, 0, 0, 0, 2213, 34981, 51365, 51365, 52389, 51365, 52389,
51365, 52422, 52389, 51365, 34981, 18597, 0, 0, 0, 0, 0, 0, 2213, 51365, 51365, 51365, 51365, 51365, 51365, 51365, 51365, 34981, 2213, 0, 0, 0, 0, 0, 0, 0, 0, 18597,
18597, 51365, 51365, 51365, 51365, 51365, 18597, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18597, 51365, 51365, 34981, 34981, 2213, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 2213, 18597, 3270, 0, 4360, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 22924, 39308, 21834, 6573, 40398, 23981, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6573, 40398, 56815, 56782, 55725,
56782, 56782, 24014, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7597, 24014, 56782, 57872, 56815, 56815, 56782, 56782, 56815, 55725, 39275, 20744, 0, 0, 0, 0, 0, 0, 7630, 39341,
56782, 56815, 56815, 56815, 56815, 57872, 56815, 56815, 55725, 55725, 54602, 20744, 0, 0, 0, 0, 39341, 56782, 56782, 56815, 56815, 56782, 56815, 56782, 56782, 56815, 57872, 55725, 55692, 54602, 53512, 21834,
0, 0, 0, 39275, 55725, 56782, 56782, 56782, 56782, 56815, 56782, 55725, 56782, 56782, 55692, 53545, 52422, 52455, 38218, 0, 0, 0, 39275, 56782, 56782, 56782, 56815, 56815, 56815, 56815, 55725, 55692,
55659, 53512, 52422, 51365, 52389, 52422, 18597, 0, 0, 38218, 55725, 56815, 56815, 56782, 56782, 56782, 56782, 55692, 54602, 53512, 52389, 51365, 51365, 51365, 51365, 34981, 0, 0, 37128, 54635, 56782, 56782,
55725, 55725, 55725, 55692, 53545, 52422, 52389, 51365, 51365, 51332, 51365, 51365, 34981, 5450, 5450, 53512, 53545, 54635, 55692, 53512, 52422, 52422, 52422, 52422, 51365, 51365, 51365, 51365, 51365, 51365, 51365, 18597,
0, 3270, 53512, 52455, 53479, 53545, 52389, 51365, 51365, 51365, 51365, 51365, 51365, 51365, 51365, 51365, 51365, 34981, 0, 0, 4360, 53512, 52455, 52389, 52389, 51365, 51365, 51365, 51365, 51365, 51365, 51365,
51365, 52389, 51365, 51365, 19621, 0, 0, 0, 36005, 52389, 51365, 51365, 51365, 52389, 52389, 51365, 51365, 51365, 52389, 52455, 52422, 51365, 18597, 0, 0, 0, 0, 18564, 51365, 51365, 51365, 51365,
51365, 51365, 51365, 51365, 51365, 52422, 53512, 52422, 51365, 2213, 0, 0, 0, 0, 0, 18597, 51365, 51365, 51365, 51365, 51365, 51365, 51365, 51365, 52389, 52389, 51365, 34981, 0, 0, 0, 0,
0, 0, 0, 18564, 36005, 52389, 51365, 51365, 51365, 52389, 51365, 51365, 51365, 51365, 34981, 0, 0, 0, 0, 0, 0, 0, 0, 18597, 51365, 51365, 51365, 51365, 52389, 51365, 51365, 51365,
51365, 18597, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2213, 2213, 2213, 3270, 2213, 18597, 51365, 51365, 34981, 3237, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 5450, 18597, 18597, 2213, 0, 0, 0, 0, 0, 0, 0, 0, 7630, 16383, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 40398, 40431, 22957, 24014, 41488, 40431, 22957, 22924, 22924, 5483, 0, 0, 0, 0, 0, 0, 0, 6573, 56782, 56815, 56815, 56782, 57872, 56815, 56815, 55725, 56782, 39341, 38251, 20744, 0,
0, 0, 0, 0, 22957, 56782, 56815, 57872, 56782, 56815, 56815, 56815, 56749, 56782, 56749, 56749, 54635, 20744, 0, 0, 0, 7630, 39341, 56782, 56815, 56815, 56815, 56815, 56815, 56815, 55725, 56782,
56782, 56782, 56749, 38251, 5450, 0, 0, 22924, 55692, 55692, 56782, 56815, 56815, 56815, 56782, 56782, 56749, 56815, 56815, 56782, 55692, 54602, 19687, 0, 0, 38251, 54635, 55692, 56782, 56815, 56782, 56782,
56815, 56815, 56815, 56815, 56782, 55692, 53512, 52389, 51365, 2180, 0, 19687, 54635, 55725, 55725, 56749, 55725, 55725, 56782, 56782, 56782, 55725, 55692, 53545, 52422, 51332, 51365, 2213, 0, 21834, 55692, 55725,
55692, 55692, 54635, 54635, 54635, 55692, 55725, 55692, 53545, 52422, 51365, 51365, 34981, 0, 21867, 55692, 55692, 55692, 55692, 54635, 54602, 54602, 54569, 54569, 54635, 54602, 52422, 51365, 51365, 51365, 18597, 0,
20777, 54569, 54602, 54635, 54635, 54635, 54635, 54635, 54635, 54602, 53512, 52422, 51365, 51365, 51365, 51365, 2213, 0, 3270, 36071, 54569, 54635, 54635, 55692, 55692, 55692, 55692, 54602, 52455, 51365, 51365, 51365,
51365, 51365, 2213, 0, 0, 36005, 53479, 54602, 55692, 55692, 55692, 54635, 54635, 53545, 52422, 51365, 51365, 51365, 51365, 51365, 18597, 0, 0, 18597, 51365, 53479, 54602, 54635, 54602, 54569, 53545, 52422,
51365, 51365, 51365, 51365, 51365, 51365, 34981, 0, 0, 0, 34981, 51365, 52455, 53512, 53512, 52455, 52422, 51365, 51365, 51365, 51365, 51365, 51365, 51365, 51365, 3270, 0, 0, 18597, 51365, 51365, 51365,
51365, 51365, 51365, 51365, 51365, 51365, 51365, 51365, 51365, 51365, 51365, 2213, 0, 0, 0, 18597, 34981, 51365, 51365, 51365, 51365, 51365, 51365, 51365, 51365, 51365, 51365, 51365, 51365, 18564, 0, 0,
0, 0, 4360, 36005, 34981, 51365, 52389, 51365, 51365, 51365, 52389, 34981, 34981, 18597, 2180, 2213, 0, 0, 0, 0, 0, 0, 0, 19621, 52389, 34981, 18597, 18597, 19621, 2213, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3270, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7630, 24014, 24014,
39308, 5483, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22957, 24014, 24047, 24047, 56782, 56782, 56815, 56782, 39341, 6540, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6540, 55725, 56782, 56815, 56815, 56782, 56815, 56782, 56782, 56749, 39308, 5450, 0, 0, 0, 0, 0, 24014, 25104, 25104, 39341, 56782, 56815, 56815, 56782, 56749, 56782, 56749, 56782, 56782, 55725, 38218,
1090, 0, 0, 0, 5450, 39341, 56815, 57872, 56815, 56782, 56782, 56815, 56782, 56749, 55725, 55725, 56749, 56782, 55725, 53512, 18564, 0, 0, 0, 0, 39308, 55725, 56782, 56782, 55725, 56782, 56782,
56782, 56782, 55692, 56749, 56782, 56815, 56782, 53545, 18564, 0, 0, 0, 0, 38251, 55692, 55692, 56749, 56782, 56782, 56782, 56782, 56782, 56782, 56782, 56782, 56782, 56782, 54635, 34981, 0, 0, 0,
3270, 53545, 54602, 55692, 55725, 56782, 56815, 56815, 56815, 56815, 56815, 57872, 56815, 56815, 56782, 54602, 19621, 0, 0, 0, 0, 37128, 53512, 53545, 54635, 55725, 56782, 56815, 56815, 56782, 56815, 56815,
56815, 55725, 55659, 53545, 36005, 2180, 0, 0, 0, 36038, 52422, 52422, 53512, 55692, 55725, 55725, 56749, 55725, 55725, 55692, 55692, 54635, 53512, 52422, 51365, 34981, 2213, 0, 0, 2180, 51365, 52422,
53479, 54635, 55659, 55692, 54635, 54602, 54569, 53545, 53512, 53512, 52422, 51365, 51365, 51365, 34981, 0, 0, 0, 34981, 51332, 53479, 54602, 53545, 53512, 52455, 52422, 52422, 51365, 51365, 52389, 52389, 51365,
51365, 51365, 51365, 19621, 0, 3237, 51365, 52389, 53512, 53545, 52422, 52389, 51365, 51365, 52389, 51365, 51365, 51365, 51365, 51365, 51365, 51365, 51365, 34981, 0, 0, 34948, 52389, 52455, 52455, 52389, 51365,
51365, 51365, 52389, 52389, 51365, 51365, 51365, 51365, 51365, 51365, 51365, 18597, 0, 0, 2213, 34981, 52389, 51365, 51365, 51332, 51332, 52422, 52422, 52389, 51365, 51365, 51365, 51365, 51365, 34981, 18597, 0,
0, 0, 0, 2213, 34981, 51365, 51365, 51365, 51365, 52389, 52422, 51365, 51365, 51365, 51365, 51365, 51365, 2213, 0, 0, 0, 0, 0, 0, 2213, 34981, 51365, 51365, 51365, 51365, 51365, 51365,
51365, 51365, 34981, 51365, 36005, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18597, 51365, 51365, 52389, 51365, 51365, 51365, 18597, 0, 2213, 3270, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 3237, 18597, 18597, 34981, 18597, 18597, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7630, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 25104, 40398, 40398, 24014, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 24047, 56815,
56815, 56815, 56782, 40398, 22957, 6540, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 24047, 56782, 56782, 56815, 56815, 56815, 56782, 56782, 39341, 3303, 0, 0, 0, 0, 0,
0, 0, 22957, 40431, 40431, 57872, 56782, 56782, 56815, 56815, 56782, 56782, 56782, 55692, 20777, 0, 0, 0, 0, 0, 0, 5450, 39341, 56782, 56782, 56815, 56815, 56815, 56782, 56782, 55725, 55725,
55725, 55725, 38251, 7630, 0, 0, 0, 0, 0, 0, 22957, 56782, 56782, 56815, 56782, 56782, 55725, 55692, 54635, 55692, 56782, 56815, 56815, 40431, 8720, 0, 0, 0, 0, 0, 39308, 56782,
56782, 56749, 54602, 55692, 55725, 55725, 55692, 55725, 55725, 56749, 56749, 56782, 39341, 5450, 0, 0, 0, 24014, 56782, 56815, 56782, 54602, 51332, 52455, 54569, 55692, 55725, 56782, 56815, 56815, 56815, 56782,
55692, 37128, 2180, 0, 6540, 55692, 55725, 55725, 55725, 53545, 52389, 51332, 53512, 55692, 55725, 56782, 56815, 56815, 56782, 55692, 53545, 52422, 34948, 4360, 20744, 54602, 54602, 54602, 54569, 54602, 54635, 54602,
55725, 56782, 56782, 56782, 56782, 56782, 55692, 54602, 52455, 51365, 18597, 0, 36071, 53512, 53512, 52455, 52455, 53545, 54602, 55692, 56749, 56782, 56782, 55725, 54635, 54602, 53479, 52422, 51365, 34981, 0, 0,
19621, 52389, 52389, 51365, 51365, 51365, 52389, 53545, 54635, 54635, 54635, 54635, 53545, 52422, 51365, 51365, 51365, 34981, 0, 0, 0, 18597, 51365, 51365, 51332, 51332, 51332, 52389, 53512, 53545, 53512, 52455,
52422, 51365, 51365, 51365, 51365, 51365, 18597, 0, 0, 0, 34981, 51365, 51365, 51365, 51365, 51365, 52389, 52389, 52389, 51365, 51365, 52389, 51365, 51365, 51365, 51365, 18597, 0, 0, 0, 34981, 51365,
51365, 51365, 51332, 51365, 51365, 51365, 51365, 51365, 51365, 52389, 51365, 51365, 51365, 51365, 18597, 0, 0, 5450, 18597, 51332, 51365, 52389, 51365, 51365, 51365, 51365, 51365, 51365, 51332, 51365, 51365, 51332,
51365, 51365, 3270, 0, 0, 0, 0, 2180, 18597, 34981, 51365, 51365, 52389, 51365, 51365, 51365, 51365, 51365, 51365, 51365, 51365, 18597, 0, 0, 0, 0, 0, 0, 0, 0, 18597, 34981,
34981, 51365, 51365, 51365, 51365, 51365, 34981, 18597, 3237, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3270, 18597, 18597, 34981, 18597, 3270, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8720, 5450, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 40431, 40431, 40431, 40398, 40398, 40398, 24014, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 7630, 56815, 56815, 56815, 56815, 56815, 56782, 56749, 22957, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 24014, 56782, 56782, 56782, 56815,
56782, 55725, 55725, 55725, 40398, 41488, 24047, 7630, 0, 0, 0, 0, 0, 0, 0, 0, 6540, 40398, 55725, 55725, 56782, 56815, 56782, 55692, 55692, 56749, 56815, 56815, 56782, 56749, 22957, 0,
0, 0, 0, 0, 0, 24014, 40431, 56815, 55725, 55692, 56782, 56815, 55725, 54635, 54635, 55725, 55725, 56782, 56782, 56782, 54635, 19687, 0, 0, 0, 0, 22924, 56749, 56782, 56815, 56782, 55725,
56815, 56782, 55725, 55692, 54635, 55725, 56782, 56815, 56815, 55725, 54569, 36038, 0, 0, 0, 5450, 54635, 55692, 55725, 55725, 56782, 56782, 56782, 55725, 54635, 54635, 55725, 56782, 56815, 56782, 56782, 54635,
53512, 36005, 0, 0, 0, 21834, 54602, 54602, 55725, 56782, 55725, 56782, 55725, 53512, 52422, 52455, 54602, 55692, 56782, 56782, 55725, 54569, 52422, 51365, 2213, 0, 0, 21834, 54602, 53512, 53545, 55725,
55725, 55725, 55659, 52422, 51332, 52455, 54635, 55725, 55725, 55692, 54602, 52455, 51332, 51365, 18597, 0, 0, 37161, 54602, 53545, 53512, 55692, 55725, 55725, 54635, 52455, 52422, 54602, 55692, 55725, 55692, 54635,
53512, 51365, 51365, 51365, 34981, 0, 2180, 52422, 54635, 55725, 55692, 55692, 54635, 53545, 53479, 52455, 52455, 53545, 54602, 54602, 53545, 53512, 52389, 51365, 51365, 51365, 34981, 0, 0, 18564, 54602, 55692,
54635, 52455, 52422, 52422, 51365, 52389, 52389, 52389, 52422, 52422, 52389, 51365, 51365, 51365, 51365, 51365, 34981, 0, 0, 0, 36038, 53512, 52455, 51365, 51365, 51365, 51365, 51365, 51365, 51365, 51365, 51365,
51365, 51365, 51365, 51365, 51365, 51365, 18597, 0, 0, 4360, 34981, 52389, 51365, 51365, 51365, 51365, 51365, 51332, 51365, 51365, 51365, 51365, 51365, 51365, 51365, 51365, 51365, 18597, 0, 0, 0, 0,
0, 2213, 34981, 51365, 51365, 51365, 51365, 51332, 51332, 51332, 51365, 51365, 51365, 51365, 51365, 34981, 2213, 0, 0, 0, 0, 0, 0, 0, 18597, 51365, 51365, 51365, 51365, 51365, 51365, 51365,
51365, 51365, 51365, 51365, 51365, 19621, 0, 0, 0, 0, 0, 0, 0, 0, 2180, 51365, 51332, 51365, 51365, 51365, 34981, 34981, 18597, 51365, 34981, 18597, 18597, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 2213, 2180, 18564, 18597, 2180, 0, 0, 0, 2180, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7663, 24014, 24014, 24014,
3270, 0, 8720, 25104, 24014, 24014, 0, 0, 0, 0, 0, 0, 0, 7630, 24047, 40431, 56815, 56815, 56815, 56782, 40398, 40431, 57872, 56815, 56782, 56782, 22924, 0, 0, 0, 0, 0,
0, 40398, 56815, 56815, 56815, 56815, 56815, 56782, 55725, 56782, 56782, 56749, 56782, 56782, 54635, 20777, 0, 0, 0, 0, 5483, 55725, 56782, 56782, 56782, 56782, 56815, 56782, 55725, 55725, 55725, 56815,
56815, 56782, 54635, 37095, 0, 0, 0, 0, 4360, 55659, 56782, 55725, 55725, 56749, 56782, 56815, 55725, 55725, 56782, 56815, 56815, 56782, 55659, 37095, 0, 0, 0, 0, 21801, 55692, 56782, 55725,
55692, 55692, 56782, 56782, 56749, 55692, 55692, 55725, 56782, 55725, 54635, 52455, 2147, 0, 0, 0, 22924, 55725, 56782, 56782, 55725, 55692, 56782, 56782, 55725, 53545, 53512, 54635, 55725, 55725, 54602, 52422,
18597, 0, 0, 5483, 39308, 55725, 55725, 56782, 56782, 56782, 56782, 56782, 55692, 53479, 52455, 55659, 55725, 55692, 53545, 52422, 34981, 3270, 0, 38218, 54635, 54602, 54635, 55692, 55725, 55725, 55725, 55725,
55692, 53512, 53512, 54635, 54635, 53545, 52422, 51365, 51365, 18564, 4360, 54602, 54602, 52455, 52422, 53545, 54635, 55692, 55692, 55725, 55692, 53512, 52455, 53512, 52455, 52422, 51365, 51365, 34981, 3270, 2213, 53512,
53545, 53479, 51365, 51365, 52389, 53512, 55659, 55692, 53545, 52422, 52389, 51365, 51365, 51365, 51365, 51365, 18597, 0, 0, 37161, 53545, 53512, 52455, 52422, 52422, 52422, 52422, 53479, 52422, 51365, 51365, 51365,
51365, 51365, 51365, 51365, 2213, 0, 2180, 52455, 53545, 54569, 54602, 54635, 55659, 53545, 52389, 51365, 51365, 51365, 51365, 51365, 51365, 51365, 51365, 34981, 0, 0, 2180, 51365, 52422, 53545, 54635, 55692,
54635, 52455, 51365, 51365, 51365, 51365, 51365, 51365, 51332, 51365, 51365, 18597, 0, 0, 18597, 34981, 51365, 52389, 52455, 53512, 52455, 52389, 51365, 52389, 51365, 51365, 51365, 51365, 18597, 34981, 34981, 3237,
0, 0, 0, 0, 2213, 18597, 34981, 51365, 51365, 51365, 51365, 51365, 51365, 51365, 51365, 18597, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2180, 18597, 51365, 51365, 51365, 51365,
51365, 51365, 18597, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18597, 51365, 51365, 51365, 34981, 2213, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 18597, 34981, 18597, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7663, 24014, 24014, 6540, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7630, 41488, 56815, 56782, 56815, 39308, 5450, 0, 0, 0, 0, 0, 0, 0, 0, 8720, 24014, 40431, 24047, 40398,
56815, 56782, 56815, 56815, 56782, 38251, 5450, 0, 0, 0, 0, 0, 0, 7663, 40431, 56815, 56815, 56815, 56815, 56782, 56782, 56815, 56815, 56815, 55725, 38251, 4360, 0, 0, 0, 0, 24014,
56782, 56815, 56815, 56815, 56815, 56815, 56782, 56782, 56782, 56782, 56782, 56782, 55692, 21834, 0, 0, 0, 0, 39341, 56749, 56782, 56782, 56782, 56782, 56782, 56815, 56782, 56782, 55725, 55692, 56782, 55725,
54569, 19654, 0, 0, 3303, 54602, 55692, 56782, 56782, 55725, 55725, 56749, 56815, 56782, 56782, 55725, 55692, 55725, 55659, 53512, 36005, 0, 0, 18597, 53479, 54602, 55725, 56815, 56815, 56782, 56782, 56782,
56749, 55725, 56782, 55692, 54602, 53512, 52422, 34981, 0, 0, 18597, 52422, 54602, 55692, 55725, 56782, 56782, 56782, 56749, 55725, 55725, 56782, 55692, 53479, 52389, 51365, 34981, 0, 0, 18597, 52389, 54602,
54635, 54635, 54602, 54602, 54602, 54635, 55692, 55692, 55692, 53545, 52389, 51365, 51365, 34981, 0, 0, 18564, 52422, 54602, 53545, 52389, 51332, 51365, 51365, 51365, 53545, 54602, 52455, 51365, 51365, 51365, 51365,
51365, 2213, 0, 0, 36071, 54602, 54602, 53512, 52422, 51365, 51365, 52422, 53545, 53512, 51365, 51365, 51365, 51365, 51332, 51365, 34981, 4360, 0, 37128, 54569, 53545, 53545, 53512, 52422, 53512, 54635, 55692,
53512, 51365, 51365, 51365, 51365, 51365, 34981, 19621, 0, 2180, 52389, 53512, 53545, 53545, 54569, 54602, 55692, 55725, 55692, 53512, 51365, 52389, 51365, 34981, 2180, 0, 0, 0, 0, 34948, 52422, 53545,
54569, 54602, 54602, 54635, 54602, 53545, 52422, 51365, 51365, 51365, 18597, 0, 0, 0, 0, 0, 18597, 51365, 52422, 52422, 52422, 52422, 52455, 52422, 52389, 51365, 51365, 51365, 51365, 2180, 0, 0,
0, 0, 0, 0, 18597, 51365, 51365, 51365, 51365, 52389, 51365, 51365, 51365, 51365, 51365, 34981, 0, 0, 0, 0, 0, 0, 0, 18597, 51365, 51365, 51332, 51365, 52389, 51365, 51365, 51365,
51365, 51332, 18564, 0, 0, 0, 0, 0, 0, 0, 0, 2180, 2180, 2147, 3237, 18597, 34981, 34981, 34981, 51332, 18597, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 2180, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22957, 22957, 5450, 7630, 7630, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 24047, 56782, 56782, 56782, 56815, 40398, 21867, 22924, 0, 0, 0, 0, 0, 0, 0, 0, 0, 24047, 40431, 56815, 57872, 56815, 56815, 56815, 56782, 55725,
55725, 38251, 4360, 0, 0, 0, 0, 0, 7630, 40398, 56815, 56815, 56815, 57872, 57872, 56815, 56782, 56782, 56782, 56815, 55692, 37128, 3303, 0, 0, 0, 7597, 40365, 56815, 56815, 56815, 56815,
56815, 57872, 56815, 56782, 56782, 56782, 56749, 55692, 53545, 19687, 0, 0, 0, 22924, 55692, 55725, 56782, 56815, 56815, 56782, 56782, 55725, 55725, 55725, 55725, 55692, 55692, 53545, 36038, 3270, 0, 0,
38218, 54635, 54635, 55725, 56782, 56782, 56782, 53512, 51332, 52455, 55659, 55692, 55692, 54602, 53545, 52389, 34981, 18597, 0, 36038, 53512, 53545, 54635, 55692, 55725, 55725, 53545, 51332, 52422, 54635, 55692, 55692,
54602, 53512, 51365, 51365, 34981, 3303, 34948, 52389, 53479, 54602, 54635, 55692, 55725, 54602, 52422, 54602, 55725, 56782, 55692, 54602, 53512, 51365, 51365, 19621, 0, 18597, 51365, 51365, 53512, 54635, 55692, 55692,
54635, 54635, 55692, 56815, 56782, 54635, 54569, 52422, 51365, 18597, 0, 0, 18597, 51365, 51365, 53512, 54635, 54635, 54635, 55692, 55692, 55725, 56749, 55692, 54602, 52455, 51365, 34981, 0, 0, 0, 2180,
51365, 51365, 52455, 54602, 54602, 54635, 55692, 55692, 55692, 54635, 53545, 52422, 51365, 51365, 34981, 0, 0, 0, 3237, 51365, 51365, 52422, 53479, 53545, 54635, 54635, 54602, 53545, 52455, 52422, 51365, 51365,
51365, 51365, 2213, 0, 0, 0, 34981, 51365, 51365, 51365, 52422, 53512, 53512, 52422, 52389, 51365, 51365, 51365, 51365, 51365, 51365, 18564, 0, 0, 0, 2213, 34981, 51365, 51332, 51365, 52389, 52389,
51365, 51332, 51365, 52389, 51365, 51365, 51365, 34981, 2180, 0, 0, 0, 0, 2180, 34981, 34981, 51365, 51365, 51365, 51365, 51332, 51365, 51365, 51365, 51365, 18597, 3270, 0, 0, 0, 0, 0,
0, 2180, 0, 18597, 51365, 34981, 2180, 2180, 34981, 34981, 34981, 18597, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2213, 18597, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8720, 0, 8753, 41488, 24014, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 24014, 40398,
22957, 41488, 56815, 56815, 7630, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7663, 41488, 56815, 56782, 56782, 57872, 56815, 56815, 39341, 7630, 0, 0, 0, 0, 0, 0, 0,
0, 24047, 56815, 57872, 56815, 56782, 56782, 56782, 56782, 56782, 55725, 39308, 20711, 0, 0, 0, 0, 0, 0, 24014, 56782, 57872, 57872, 56815, 56815, 56815, 55725, 56782, 56782, 55725, 55725, 37128,
2213, 0, 0, 0, 0, 24014, 56815, 56815, 56815, 56815, 56815, 56782, 57872, 55725, 56815, 56815, 55725, 55692, 52422, 36005, 19621, 0, 0, 22957, 56782, 56815, 56782, 56782, 56782, 56815, 56782, 56815,
56782, 57872, 56815, 55725, 54635, 52389, 51365, 18597, 0, 6507, 55692, 55725, 55725, 55725, 55725, 55725, 56782, 56782, 56815, 56782, 56815, 56815, 55725, 53545, 51365, 51365, 18564, 0, 5483, 54635, 54635, 54635,
54635, 55692, 55725, 56782, 56782, 56815, 56782, 56782, 56782, 55659, 52422, 51365, 51365, 2213, 0, 3237, 52455, 53545, 53545, 54602, 54635, 55692, 55725, 55725, 56782, 56782, 55725, 55692, 53512, 51332, 51365, 51365,
34981, 2213, 0, 34981, 52422, 52455, 53479, 53545, 54602, 55692, 55725, 55725, 55692, 54635, 53545, 52422, 51365, 51365, 51365, 51365, 18597, 0, 18597, 51365, 51365, 52389, 52422, 53512, 54569, 54635, 54635, 54602,
53512, 52422, 51365, 52389, 51365, 51365, 51365, 18564, 0, 0, 34981, 52389, 51365, 51365, 52422, 52422, 53512, 53479, 52455, 52389, 51332, 51365, 51365, 51365, 51365, 51365, 18564, 0, 0, 2213, 34981, 51365,
51365, 51365, 51332, 51365, 51365, 51365, 51365, 51365, 51365, 51365, 51365, 51365, 51365, 3270, 0, 0, 0, 18564, 51332, 51365, 51365, 51365, 51365, 51365, 51332, 51365, 51365, 51365, 51365, 51365, 51365, 18597,
0, 0, 0, 0, 2180, 51365, 51365, 51365, 51365, 51365, 51365, 51365, 51365, 51365, 51365, 51365, 51365, 34981, 2213, 0, 0, 0, 0, 2213, 51365, 51365, 51365, 51365, 51365, 51365, 51365, 51365,
51365, 51365, 34981, 18597, 2180, 0, 0, 0, 0, 0, 0, 18597, 51332, 51365, 51365, 51365, 19621, 18597, 34981, 34981, 34981, 3270, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2180,
34981, 51332, 18597, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2180, 18597, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
};
Sprites rock(16, rockPixels, rockOffsets, rockRes, rockPoints, rockPointOffsets, Sprites::PixelFormat::R5G5B4A2);

View file

@ -0,0 +1,93 @@
//This example displays a 3D model on a VGA screen. Double buffering is used to avoid flickering.
//You need to connect a VGA screen cable and an external DAC (simple R2R does the job) to the pins specified below.
//cc by-sa 4.0 license
//bitluni
//include libraries
#include <ESP32Lib.h>
#include <Ressources/Font6x8.h>
//include model
#include "thinker.h"
Mesh<VGA14Bit> model(thinker::vertexCount, thinker::vertices, 0, 0, thinker::triangleCount, thinker::triangles, thinker::triangleNormals);
//pin configuration
const int redPins[] = {2, 4, 12, 13, 14};
const int greenPins[] = {15, 16, 17, 18, 19};
const int bluePins[] = {21, 22, 23, 27};
const int hsyncPin = 32;
const int vsyncPin = 33;
//VGA Device
VGA14Bit vga;
//3D engine
Engine3D<VGA14Bit> engine(1337);
//initial setup
void setup()
{
//need double buffering
vga.setFrameBufferCount(2);
//initializing i2s vga
vga.init(vga.MODE200x150, redPins, greenPins, bluePins, hsyncPin, vsyncPin);
//setting the font
vga.setFont(Font6x8);
}
///a colorful triangle shader actually calculated per triangle
VGA14Bit::Color myTriangleShader(int trinangleNo, short *v0, short *v1, short *v2, const signed char *normal, VGA14Bit::Color color)
{
//normals packed in 1 signed byte per axis
const float scaleN = 1.0f / 127.0f;
const float nx = normal[0] * scaleN;
const float ny = normal[1] * scaleN;
const float nz = normal[2] * scaleN;
//return R5G5B4 color each normal axis controls each color component
return (int(15 * nx + 16)) | (int(15 * nz + 16) << 5) | (int(7 * ny + 8) << 10);
}
//render 3d model
void drawModel()
{
//perspective transformation
static Matrix perspective = Matrix::translation(vga.xres / 2, vga.yres / 2, 0) * Matrix::scaling(100 * vga.pixelAspect(), 100, 100) * Matrix::perspective(90, 1, 10);
static float u = 0;
u += 0.02;
//rotate model
Matrix rotation = Matrix::rotation(-1.7, 1, 0, 0) * Matrix::rotation(u, 0, 0, 1);
Matrix m0 = perspective * Matrix::translation(0, 1.7 * 0, 7) * rotation * Matrix::scaling(7);
//transform the vertices and normals
model.transform(m0, rotation);
//begin adding triangles to render pipeline
engine.begin();
//add this model to the render pipeline. it will sort the triangles from back to front and remove backfaced. The tiangle shader will determine the color of the tirangle.
//the RGB color gien in the second parameter is not used in this case but could be used for calculations in the triangle shader
model.drawTriangles(engine, vga.RGB(128, 70, 20), myTriangleShader);
//render all triangles in the pipeline. if you render multiple models you want to do this once at the end
engine.end(vga);
}
//just draw each frame
void loop()
{
//calculate the milliseconds passed from last pass
static int lastMillis = 0;
int t = millis();
//calculate fps (smooth)
static float oldFps = 0;
float fps = oldFps * 0.9f + 100.f / (t - lastMillis);
oldFps = fps;
lastMillis = t;
//clear the back buffer
vga.clear(0);
//draw the model
drawModel();
//reset the text cursor
vga.setCursor(0, 0);
//print the stats
vga.print("fps: ");
vga.print(fps, 1, 4);
vga.print(" tris/s: ");
vga.print(int(fps * model.triangleCount));
vga.show();
}

View file

@ -0,0 +1,417 @@
namespace thinker
{
const int vertexCount = 1294;
const int triangleCount = 2616;
const float vertices[][3] = {
0.0765, -0.2322, 0.1462, 0.0503, -0.2366, 0.1479, 0.0820, -0.2773, 0.2119, 0.0340, -0.2306, 0.2923, 0.0458, -0.2237, 0.2850, 0.0596, -0.2562, 0.2855, -0.0730, -0.1915, -0.4763, 0.0295, -0.1985, -0.4769, -0.0251, -0.1703, -0.4739, 0.1022, 0.0365, -0.0443, 0.1027, -0.0583, -0.0810, 0.1019, -0.0767, -0.1003, 0.0895, -0.2869, -0.1174, 0.0727, -0.2850, -0.1157, 0.0895, -0.2460, -0.1532, -0.2106, 0.2105, -0.4743,
-0.2724, 0.2189, -0.4759, -0.2290, 0.1345, -0.4745, -0.0189, -0.3179, 0.3725, -0.0211, -0.2602, 0.3398, -0.0196, -0.2811, 0.3342, 0.0341, -0.1717, 0.0731, 0.0516, -0.1858, 0.0944, 0.0787, -0.1815, 0.0634, 0.0417, -0.1812, -0.0987, 0.0424, -0.1851, -0.0786, 0.0572, -0.1375, -0.1000, -0.0027, -0.0647, -0.3952, -0.0500, -0.0498, -0.3778, -0.0580, -0.0617, -0.3997, -0.0425, -0.0817, -0.4258, -0.1258, -0.0732, -0.3582,
-0.1226, -0.0643, -0.3371, -0.1302, -0.0396, -0.3585, 0.0347, -0.1953, 0.3281, 0.0243, -0.2317, 0.3146, 0.0142, -0.1801, 0.3039, -0.1562, -0.1558, -0.4761, -0.1736, -0.1019, -0.4751, -0.2312, -0.0929, -0.4762, 0.0882, 0.0703, -0.0995, 0.0670, 0.0249, -0.1142, 0.0698, 0.0441, -0.1312, 0.1704, -0.1153, 0.2991, 0.1509, -0.0916, 0.3597, 0.1308, -0.1197, 0.3448, 0.1435, 0.0745, -0.3624, 0.1762, 0.0841, -0.3785,
0.1585, 0.1084, -0.3410, -0.1714, -0.0017, 0.2455, -0.1336, 0.0014, 0.3012, -0.1283, 0.0571, 0.2564, -0.0844, -0.0806, -0.2200, -0.1549, -0.0269, -0.2301, -0.1059, -0.0413, -0.2758, 0.0638, -0.3659, 0.3510, 0.0436, -0.3844, 0.3823, 0.0289, -0.3742, 0.3510, -0.1153, 0.2465, -0.4440, -0.0890, 0.2578, -0.4296, -0.0896, 0.2627, -0.4729, -0.0547, -0.2463, 0.2774, -0.0322, -0.2456, 0.2417, -0.0396, -0.2153, 0.2702,
-0.0553, 0.1617, 0.1143, -0.0287, 0.1546, 0.1828, -0.0257, 0.1688, 0.1071, 0.1038, -0.0988, 0.3573, 0.0651, -0.1168, 0.3753, 0.0630, -0.1108, 0.3514, -0.1781, 0.0176, 0.0714, -0.1946, 0.0563, 0.0923, -0.1908, 0.0731, 0.0591, -0.1216, 0.1447, 0.1045, -0.1631, 0.1144, 0.0976, -0.1713, 0.0829, 0.1385, 0.1541, -0.1853, 0.1469, 0.1510, -0.2312, 0.1111, 0.1716, -0.1912, 0.1348, -0.1228, -0.0772, 0.1326,
-0.1446, -0.1175, 0.1735, -0.1718, -0.1035, 0.1846, -0.1592, -0.0488, 0.1399, -0.1385, -0.3276, -0.1611, -0.1082, -0.3306, -0.1395, -0.1272, -0.3622, -0.0890, 0.0613, -0.3506, 0.3421, 0.0622, -0.3280, 0.3101, 0.0640, -0.3266, 0.3488, -0.0859, -0.1739, -0.2113, -0.0962, -0.1711, -0.1649, -0.0945, -0.1998, -0.1626, 0.0212, -0.0830, -0.1116, -0.0198, -0.0773, -0.1761, 0.0323, -0.0807, -0.1807, -0.0810, -0.2523, -0.0874,
-0.0965, -0.2155, -0.0908, -0.0907, -0.2371, -0.0792, 0.0832, -0.0169, -0.3979, 0.0758, 0.0051, -0.3576, 0.0910, -0.0374, -0.3777, 0.1085, -0.0048, -0.4372, 0.1288, -0.0695, -0.4727, 0.1312, -0.0114, -0.4579, -0.1798, -0.1260, -0.1105, -0.1916, -0.0047, -0.1039, -0.1663, -0.0486, -0.1303, -0.1414, -0.1351, -0.2063, -0.1175, -0.0873, -0.2990, -0.1361, -0.1022, -0.2743, -0.1204, -0.1905, -0.1355, -0.1062, -0.2053, -0.1259,
0.0689, 0.1218, 0.1394, 0.0696, 0.1164, 0.1060, 0.0299, 0.1429, 0.1181, -0.2203, 0.0308, -0.4745, -0.2985, 0.0768, -0.4757, -0.2791, -0.0072, -0.4760, -0.0254, -0.2174, 0.2303, -0.0350, -0.2461, 0.1928, 0.0537, -0.0779, -0.3196, 0.0458, -0.0542, -0.3032, 0.0375, -0.0601, -0.3389, -0.2040, 0.0160, 0.0446, -0.1939, 0.0527, 0.0568, -0.2126, 0.0273, 0.0255, 0.0745, -0.3040, 0.0102, 0.0975, -0.2793, 0.0467,
0.0871, -0.2672, 0.0264, -0.0079, -0.2457, 0.3270, -0.0040, -0.2043, 0.2997, 0.0287, -0.2020, -0.0563, 0.0425, -0.2445, -0.0644, 0.0434, -0.2207, -0.0353, -0.0107, -0.0982, 0.1573, -0.0036, -0.1256, 0.1682, -0.0377, -0.1290, 0.1621, 0.0379, -0.3271, -0.1068, 0.0567, -0.3201, -0.1054, 0.0493, -0.3176, -0.1155, 0.1918, 0.1624, -0.4063, 0.1817, 0.1614, -0.3769, 0.2002, 0.1196, -0.4339, 0.1202, -0.1666, 0.0283,
0.0997, -0.2094, 0.0436, 0.1238, -0.2300, 0.0193, 0.0239, -0.1647, 0.2509, -0.0121, -0.2055, 0.2573, 0.0027, -0.1983, 0.2443, 0.0987, -0.0791, 0.1737, 0.0833, -0.0825, 0.1916, 0.0905, -0.0437, 0.2044, 0.1517, 0.1183, -0.3267, 0.1387, 0.0991, -0.2477, 0.1481, 0.1007, -0.2798, 0.2888, 0.0250, -0.4761, 0.2971, 0.0982, -0.4758, 0.2297, 0.1104, -0.4744, 0.2285, 0.0273, -0.4741, -0.0503, -0.1001, -0.0208,
-0.0413, -0.0761, 0.0021, -0.0634, -0.0418, 0.0082, -0.2056, 0.1301, -0.4491, -0.2162, 0.1250, -0.4612, -0.1989, 0.0771, -0.4278, 0.0958, -0.1199, -0.1107, 0.1226, -0.1335, -0.1025, 0.1149, -0.0972, -0.1370, 0.0227, -0.1393, 0.2191, -0.1377, -0.1089, -0.4460, -0.1085, -0.1492, -0.4759, 0.0938, -0.3185, 0.0116, 0.0305, -0.3217, -0.0487, 0.1675, -0.2439, 0.0476, 0.1702, -0.2163, 0.0404, 0.1828, -0.1604, 0.0785,
0.0537, -0.3412, 0.3051, 0.0499, -0.3249, 0.2994, 0.1021, 0.0863, 0.2161, 0.0809, 0.1061, 0.2268, 0.1165, 0.0465, 0.3292, 0.1005, 0.0022, 0.2082, 0.1072, -0.0145, 0.2432, 0.0941, -0.0184, 0.2056, 0.1692, -0.0676, 0.3485, 0.1347, -0.2024, -0.0050, 0.0558, 0.1458, -0.0710, 0.0886, 0.1180, -0.0674, 0.0681, 0.1190, -0.0985, 0.0312, 0.1430, 0.1838, 0.0880, -0.1242, -0.4573, 0.1066, -0.0876, -0.4302,
0.0830, -0.1369, -0.4419, 0.1070, -0.1646, -0.0647, 0.1229, -0.1696, -0.0445, 0.1230, -0.1870, -0.0618, -0.0885, -0.3316, -0.0697, -0.0898, -0.2993, -0.0354, -0.1022, -0.3477, -0.0499, -0.2065, -0.2419, 0.0121, -0.1887, -0.2976, -0.0030, -0.1844, -0.2519, 0.0241, -0.0604, 0.1793, -0.1089, -0.0042, 0.1737, -0.1196, 0.0013, 0.1751, -0.1266, 0.1294, -0.2212, -0.0634, 0.1391, -0.2018, -0.1372, 0.1345, -0.1633, -0.1001,
-0.0221, -0.2132, 0.0848, -0.0208, -0.1864, 0.0816, -0.0044, -0.2150, 0.0502, -0.0577, -0.1742, -0.4691, -0.1055, -0.0878, 0.3587, -0.0601, -0.1132, 0.3882, -0.0676, -0.0856, 0.3847, -0.1668, 0.1262, -0.1219, -0.1616, 0.1261, -0.1113, -0.1324, 0.1454, -0.1054, 0.0723, 0.0762, 0.0371, 0.0754, 0.1053, 0.0190, 0.0739, 0.1270, 0.0594, -0.1174, 0.1553, 0.0616, -0.0760, 0.1533, 0.0396, -0.1275, 0.1502, 0.0237,
0.0540, -0.2934, 0.0832, 0.0536, -0.2711, 0.0468, 0.0738, -0.2861, 0.0787, 0.0915, -0.0910, -0.4106, -0.0900, -0.0456, 0.0124, -0.1076, -0.0435, 0.0340, -0.0933, -0.0688, 0.0309, 0.0649, -0.3858, 0.3857, 0.0908, -0.3797, 0.3993, 0.0352, -0.3974, 0.3951, 0.0595, 0.0345, 0.0869, 0.0355, 0.0195, 0.0571, 0.0585, 0.0466, 0.0713, 0.1390, -0.1338, -0.1214, -0.1408, -0.0816, -0.1476, -0.1449, -0.0819, -0.1355,
-0.1638, -0.0383, -0.1356, -0.0224, -0.2380, 0.1917, 0.1685, -0.1239, 0.1114, 0.1797, -0.1292, 0.0908, 0.1576, -0.1347, 0.0773, 0.0874, -0.0383, 0.1843, 0.0725, -0.0667, 0.1877, 0.0710, -0.0368, 0.1730, -0.1325, -0.2972, -0.1854, -0.1579, -0.2956, -0.1823, -0.1416, -0.2416, -0.2514, 0.0878, -0.2053, 0.1068, 0.0743, -0.1997, 0.1233, 0.0918, -0.2439, 0.1355, 0.1168, 0.0572, 0.2622, 0.1320, 0.0401, 0.3061,
0.0357, -0.1066, 0.1900, 0.0327, -0.1415, 0.2287, 0.0220, -0.1115, 0.1922, 0.0482, -0.2787, 0.1903, 0.0316, -0.2529, 0.1499, 0.0259, -0.2785, 0.1481, -0.0794, 0.1529, 0.0939, -0.0679, 0.1358, 0.1751, 0.0673, -0.1677, 0.0381, 0.0413, -0.1871, 0.0209, 0.0789, -0.1872, 0.0449, -0.1448, -0.3721, -0.0878, -0.1724, -0.3330, -0.1405, -0.0157, 0.1939, -0.0864, 0.0123, 0.1794, -0.0503, 0.0399, 0.1685, -0.0972,
-0.1636, 0.1352, 0.0140, -0.1434, 0.1478, 0.0446, 0.1111, -0.0905, -0.2442, 0.1381, -0.1199, -0.1880, 0.1420, -0.1671, -0.1714, -0.1229, -0.1183, -0.4414, -0.1223, -0.1053, -0.4016, -0.1112, -0.0794, -0.4196, 0.1707, -0.2282, 0.0894, 0.0214, -0.2503, 0.3037, 0.0508, -0.2370, 0.3277, 0.0432, -0.2453, 0.3099, -0.0815, -0.0397, 0.0447, -0.0306, -0.0208, 0.0457, -0.0330, -0.0097, 0.0634, 0.1458, -0.2617, 0.0174,
0.1463, -0.2290, 0.0194, 0.1251, -0.0807, 0.0141, 0.1014, -0.1449, 0.0407, 0.0786, -0.1924, 0.0795, 0.0865, -0.1992, 0.0609, 0.0590, -0.2168, 0.4559, 0.0359, -0.2542, 0.4909, 0.0548, -0.2719, 0.4964, 0.0715, -0.2541, 0.4770, 0.1109, -0.0024, 0.0095, 0.1038, 0.0106, 0.0202, 0.0773, 0.0042, -0.1212, 0.0769, 0.0034, -0.1125, -0.0568, -0.0952, -0.4207, -0.0697, -0.1160, -0.3806, -0.0407, -0.1114, -0.4316,
-0.1206, -0.3573, -0.0499, -0.1062, -0.3457, -0.0873, -0.0101, -0.2645, 0.2766, 0.0053, -0.2761, 0.2828, 0.0024, -0.2752, 0.2633, 0.0735, -0.1931, 0.1019, 0.0505, -0.2825, 0.2461, 0.0796, -0.2793, 0.2349, 0.0571, -0.2910, 0.2253, 0.0144, 0.0914, 0.3006, -0.0377, 0.0864, 0.2907, -0.0173, 0.0817, 0.3176, 0.1370, -0.2407, -0.0644, 0.1288, -0.2485, -0.1176, -0.1660, -0.0928, 0.3209, -0.0974, -0.1207, 0.3849,
-0.2052, 0.0305, -0.0124, -0.2007, 0.0703, 0.0032, -0.2056, 0.0475, -0.0397, -0.1441, -0.0683, 0.3241, -0.1639, -0.0541, 0.2681, -0.1757, -0.0815, 0.2914, -0.0435, 0.2453, -0.1351, -0.0545, 0.2300, -0.1108, -0.0359, 0.2325, -0.1261, 0.1381, 0.0656, -0.3481, 0.1498, 0.0848, -0.3436, -0.0512, 0.1916, -0.0694, 0.0482, 0.1355, -0.1281, 0.0529, -0.2035, 0.1284, 0.0651, 0.1300, 0.0210, 0.0965, 0.0287, -0.0703,
0.1269, 0.2529, -0.3543, 0.1439, 0.1847, -0.3307, 0.1744, 0.1644, -0.3732, 0.1766, -0.1213, 0.2026, 0.1624, -0.1462, 0.1837, 0.1808, -0.1086, 0.1888, 0.1364, -0.2002, -0.1745, 0.1165, -0.1376, -0.2380, -0.1928, -0.1191, -0.0866, -0.2068, -0.0619, -0.0579, -0.1916, -0.0628, -0.0864, 0.0487, -0.1286, 0.3508, 0.0523, -0.1360, 0.3671, 0.0531, -0.1840, 0.3856, 0.0703, 0.0907, -0.1322, 0.1002, 0.1133, -0.1356,
0.1051, 0.1278, -0.1429, -0.1317, -0.0982, -0.3196, 0.0184, -0.2284, 0.3000, -0.1796, -0.0029, -0.2953, 0.0306, -0.1583, 0.2616, 0.0831, -0.1430, 0.2588, 0.0808, -0.1408, 0.2777, 0.1357, -0.0625, -0.4743, 0.0993, -0.1327, -0.4720, 0.1798, -0.1383, -0.4761, 0.0307, -0.0179, -0.3394, 0.0457, -0.0254, -0.3180, 0.0118, -0.0328, 0.0433, 0.0065, -0.0039, 0.0318, -0.0124, -0.0342, 0.0093, -0.0833, -0.1239, -0.3540,
-0.0935, -0.1482, -0.3009, -0.1072, -0.1760, -0.3046, 0.0089, 0.0028, 0.0407, 0.0390, -0.1840, 0.1414, 0.0016, -0.1615, 0.1774, 0.0147, -0.1866, 0.1918, 0.0480, -0.3284, -0.1238, 0.0689, -0.2801, -0.1293, 0.0595, -0.3250, -0.1205, -0.1645, -0.1947, -0.1307, -0.1809, -0.1805, -0.1550, -0.1881, -0.2339, -0.1187, 0.0021, -0.2598, 0.3100, 0.0214, -0.2611, 0.2945, -0.0070, -0.2450, 0.2942, -0.0204, -0.2039, 0.2323,
-0.0139, -0.1895, 0.2152, -0.0095, -0.1553, 0.1979, -0.0461, -0.1343, -0.4308, -0.0205, -0.0261, 0.0029, -0.0218, -0.0790, -0.0235, 0.0801, -0.1251, 0.3109, 0.0494, -0.1683, 0.3212, 0.0415, -0.1643, 0.2856, -0.0614, -0.0867, -0.0622, -0.0640, -0.0791, -0.0872, -0.0446, -0.0591, -0.0804, -0.1247, 0.1306, 0.1553, 0.0374, 0.1670, -0.0199, -0.0017, -0.2741, 0.3064, -0.1618, 0.2316, -0.4382, -0.1715, 0.2268, -0.4335,
-0.1630, 0.2279, -0.2925, -0.1525, 0.2374, -0.2554, -0.1489, 0.2420, -0.2627, 0.0185, -0.0747, 0.1823, 0.0820, -0.3403, -0.0964, 0.1070, -0.3240, -0.0096, 0.0679, -0.3447, -0.0923, -0.0238, -0.2361, 0.2932, -0.0268, -0.0848, -0.0489, -0.0035, -0.1199, -0.0624, -0.0125, 0.1739, 0.0780, -0.0393, 0.1769, 0.0638, 0.0744, -0.3399, 0.2405, 0.0876, -0.3309, 0.2427, 0.0630, -0.3065, 0.2991, 0.0359, -0.3267, 0.2869,
0.1436, -0.1839, 0.1499, 0.1125, -0.1723, 0.1675, 0.1230, -0.1807, 0.1298, 0.0201, -0.3285, -0.1115, 0.0194, -0.3173, -0.0700, 0.0257, -0.3162, -0.1016, 0.0697, -0.3336, 0.1959, 0.0332, -0.3332, 0.2414, 0.0363, -0.3143, 0.2176, 0.0133, -0.1310, -0.0911, -0.0206, -0.0696, -0.0785, 0.0025, -0.0882, 0.1765, 0.0123, -0.0641, 0.1759, -0.0869, -0.2571, -0.1156, -0.0963, -0.2705, -0.1393, -0.0876, -0.2401, -0.1906,
-0.2228, -0.1377, -0.0399, -0.2148, -0.1799, 0.0116, -0.2106, -0.0869, -0.0097, 0.1716, -0.0678, 0.2484, 0.1691, -0.0626, 0.2211, 0.1049, -0.3341, -0.0885, 0.0932, -0.3228, -0.0981, 0.1216, -0.3150, -0.0085, 0.1251, -0.3041, 0.0232, 0.0818, -0.0211, -0.3161, 0.0977, -0.0611, -0.2556, 0.0948, -0.0357, -0.3185, -0.0783, -0.0971, -0.1086, -0.0214, -0.0806, -0.1993, 0.0470, -0.1950, -0.1247, 0.0277, -0.0292, -0.3618,
0.0297, -0.0476, -0.3914, 0.0323, -0.0579, -0.3899, -0.0790, -0.0388, 0.0041, -0.0795, -0.0812, -0.0166, -0.0690, -0.0862, -0.0341, -0.0943, -0.2480, -0.0631, -0.0699, -0.1493, -0.0673, -0.0644, -0.1607, -0.0418, -0.0737, 0.2616, -0.3836, -0.0297, 0.2653, -0.3849, -0.0433, 0.2587, -0.4239, 0.0550, -0.1654, -0.4430, 0.0335, -0.1669, -0.4449, 0.0375, -0.1504, -0.4650, 0.0957, -0.0874, -0.1752, 0.0598, -0.0105, -0.3140,
0.0808, -0.0821, -0.1680, 0.0600, -0.1438, 0.3229, 0.0604, -0.1098, 0.3450, 0.0211, -0.2895, -0.0713, 0.0396, -0.2895, -0.0222, 0.0103, -0.2776, -0.0709, 0.0060, -0.2159, 0.2847, 0.1025, 0.0674, -0.0741, 0.0958, 0.0852, -0.0429, -0.1492, -0.3653, -0.0581, -0.1659, -0.3346, -0.0287, -0.1860, -0.3424, -0.0481, 0.1731, -0.1266, 0.1389, 0.1696, -0.0956, 0.1824, 0.1737, -0.1267, 0.1627, 0.0268, -0.0366, -0.2569,
0.0471, -0.0466, -0.2521, -0.1725, 0.0927, -0.2296, -0.1554, 0.0441, -0.2003, -0.1610, 0.0692, -0.1848, 0.1081, 0.2712, -0.2976, 0.1039, 0.3023, -0.3707, -0.1472, 0.1808, -0.1238, -0.1710, 0.1699, -0.1894, -0.1712, 0.1426, -0.1315, 0.0422, -0.2641, -0.0356, 0.1174, -0.0687, -0.0651, 0.1285, -0.1273, -0.0469, -0.1860, -0.0115, -0.4688, -0.1879, 0.0241, -0.4145, -0.2054, 0.0167, -0.4701, 0.0980, -0.0411, 0.0400,
-0.0890, -0.2067, -0.0162, -0.0672, -0.1386, -0.0015, -0.1238, -0.0505, -0.3814, -0.1166, -0.0496, -0.4003, 0.1121, 0.2385, -0.2455, 0.1306, 0.1760, -0.2728, -0.0382, -0.2004, 0.3071, -0.0280, -0.2335, 0.3429, -0.0567, -0.2060, 0.3405, -0.2002, -0.1849, 0.0290, -0.1861, -0.0997, 0.0332, 0.1242, 0.1879, -0.2135, 0.1118, 0.1882, -0.1776, 0.1376, 0.1246, -0.1807, 0.1495, 0.1259, -0.2244, -0.1082, 0.1645, -0.0810,
-0.0882, 0.1490, -0.0993, 0.1328, -0.1571, -0.0128, 0.1216, -0.0389, -0.0422, -0.0832, -0.1267, -0.3923, -0.1066, -0.1331, -0.3497, -0.1067, -0.1233, -0.3927, -0.0905, -0.1008, 0.1637, -0.0907, -0.1164, 0.1713, -0.1188, -0.1531, 0.1997, 0.0615, -0.0674, -0.1960, 0.0605, -0.0373, -0.2602, 0.0617, -0.0247, -0.2638, -0.0024, -0.2171, 0.2896, 0.0592, 0.1207, 0.2027, -0.1849, 0.0957, 0.0856, -0.1833, 0.0400, 0.1378,
0.0576, 0.1107, 0.2552, -0.1090, -0.1969, -0.1176, -0.0944, -0.1511, -0.1172, -0.1182, 0.1589, -0.0179, -0.1470, 0.1601, -0.0558, -0.1687, 0.1302, -0.3163, -0.1951, 0.1099, -0.3808, -0.1870, 0.0915, -0.3480, -0.0784, -0.1575, 0.3889, -0.1218, -0.1540, 0.3686, -0.1803, -0.0968, 0.2376, -0.1884, -0.0708, 0.1982, -0.1621, -0.1310, 0.2081, -0.0858, -0.1418, 0.0173, -0.0976, -0.1771, 0.0111, 0.0560, -0.2491, -0.1088,
0.0094, 0.2818, -0.3911, 0.0575, 0.2941, -0.4071, 0.0409, 0.2839, -0.4253, -0.0253, -0.2003, 0.4296, -0.0426, -0.1071, 0.3873, 0.0743, -0.3444, 0.3544, 0.0899, -0.3171, 0.3595, 0.0983, -0.3465, 0.3592, -0.0090, -0.1292, -0.0103, 0.0232, -0.1566, 0.0017, 0.0037, -0.0958, 0.0260, 0.1363, 0.0169, 0.2855, 0.1321, 0.0121, 0.3289, 0.1470, 0.0028, 0.2988, -0.1596, -0.1430, -0.2347, 0.0749, 0.2660, -0.1731,
-0.0534, 0.2520, -0.1620, 0.0213, -0.2719, 0.0553, 0.0278, -0.2861, 0.1001, -0.0003, -0.2706, 0.0800, 0.1264, -0.1075, -0.1750, 0.1256, -0.1039, -0.1594, 0.1455, -0.1509, -0.1433, -0.1815, -0.0017, -0.2703, -0.1877, 0.0341, -0.2544, -0.1848, 0.0182, -0.3797, 0.0839, -0.2856, 0.1085, 0.1036, -0.3111, 0.2125, 0.0954, -0.3217, 0.2018, 0.0871, -0.3634, 0.3873, -0.1599, 0.1621, -0.2594, -0.1514, 0.2347, -0.2005,
0.0336, -0.1008, -0.1069, 0.0169, -0.0853, -0.1028, -0.1950, -0.0707, -0.4734, -0.1498, -0.0876, -0.4279, -0.1801, -0.0530, -0.4388, 0.0754, 0.1093, 0.0792, -0.1905, 0.0745, -0.3020, -0.1798, 0.1028, -0.2500, 0.1144, -0.1718, -0.0745, 0.0997, -0.1640, -0.0855, 0.0491, -0.2705, -0.1023, 0.0623, -0.2699, -0.1218, 0.0591, -0.3063, -0.0884, -0.0700, -0.0209, 0.0788, -0.0209, 0.0000, 0.0797, -0.1979, -0.0265, 0.0316,
-0.1385, -0.0340, 0.0404, -0.1786, 0.0079, 0.0606, -0.2037, 0.0150, -0.0757, -0.1950, -0.0157, -0.0555, 0.0684, -0.2683, 0.3036, 0.0810, -0.2917, 0.2876, 0.0870, -0.2539, 0.2806, 0.0858, -0.2479, 0.4039, 0.0702, -0.2360, 0.3577, 0.0776, -0.2398, 0.3907, -0.0910, -0.0398, 0.0245, -0.1273, -0.0321, 0.0448, 0.0321, -0.0775, -0.3888, 0.0394, -0.1001, -0.3922, 0.0448, -0.0806, -0.3599, 0.0315, -0.1405, 0.4040,
-0.0185, -0.1261, 0.3994, 0.0115, -0.1818, 0.4260, -0.1904, -0.2182, -0.1864, -0.1950, -0.2124, -0.1796, -0.1751, -0.1563, -0.2288, 0.0469, 0.2423, -0.1278, 0.0672, -0.1115, -0.2812, 0.0796, -0.1600, -0.2330, 0.0627, -0.1409, -0.2301, -0.2026, -0.0314, -0.0394, -0.0110, -0.1681, 0.1013, 0.0162, -0.1675, 0.0982, 0.0182, -0.1806, 0.0479, 0.0734, 0.1212, -0.0012, 0.0687, 0.1349, -0.0170, 0.0305, 0.1657, 0.0266,
-0.0780, -0.0938, -0.3364, -0.0917, -0.0756, -0.3319, -0.0771, -0.1129, -0.3145, 0.0716, -0.2992, 0.3206, 0.0701, -0.2541, 0.3196, 0.0700, -0.3094, 0.3271, -0.1034, 0.2469, -0.2184, -0.0423, 0.2539, -0.2033, -0.0716, 0.2439, -0.2258, 0.0783, -0.0277, 0.0449, 0.0355, -0.0189, 0.0454, 0.0426, -0.0687, 0.0424, 0.0597, -0.3421, -0.0950, 0.1471, -0.0568, 0.1918, 0.1582, -0.0806, 0.1725, 0.1476, -0.1021, 0.1376,
0.0056, -0.3206, 0.2510, -0.0043, -0.2866, 0.2495, 0.0121, -0.2995, 0.2270, 0.1106, 0.0339, -0.0152, 0.1806, 0.0648, -0.3953, 0.0900, 0.0156, -0.4134, 0.1874, 0.0343, -0.4293, -0.0859, 0.2561, -0.3182, -0.1209, 0.2502, -0.2953, -0.0895, 0.2498, -0.2734, -0.1416, -0.0248, 0.1057, 0.0682, -0.1065, -0.1249, -0.1368, 0.1546, -0.1156, -0.0900, 0.1484, -0.1116, -0.2071, 0.2091, -0.4708, -0.1848, 0.2361, -0.4741,
0.1056, -0.2522, -0.1502, 0.1047, -0.1469, -0.2451, -0.0453, -0.2321, 0.1176, -0.0079, -0.2412, 0.0487, -0.0138, -0.2544, 0.0831, -0.1527, -0.0890, 0.0426, -0.1742, -0.1798, 0.0365, -0.1196, -0.1204, 0.0345, 0.1261, 0.0536, -0.3561, 0.0850, 0.0167, -0.3043, 0.0679, 0.0242, -0.3361, -0.1533, 0.2511, -0.3703, 0.0880, -0.0191, -0.3509, -0.0018, 0.2786, -0.3790, 0.0583, 0.2911, -0.3686, -0.1014, -0.1271, -0.2425,
-0.0777, -0.0716, 0.1224, -0.1706, -0.3647, -0.0752, -0.2029, -0.3237, -0.0789, -0.1726, 0.1067, -0.1893, -0.1722, 0.1124, -0.1320, -0.1929, 0.0802, -0.4026, 0.0671, 0.0286, -0.3556, -0.1834, -0.0140, -0.4253, 0.0646, 0.3122, -0.4506, 0.0984, 0.3017, -0.4071, 0.1255, -0.1122, 0.1177, 0.0743, 0.0973, 0.0869, 0.0709, 0.0643, 0.0830, -0.0900, -0.0266, -0.3484, -0.1719, 0.0136, -0.3843, -0.1400, -0.0104, -0.3950,
0.0760, -0.0991, -0.1226, 0.0607, -0.0884, -0.1287, 0.0694, -0.0346, -0.1280, 0.0933, -0.0726, -0.1175, 0.0594, -0.1029, -0.1349, 0.0316, -0.1303, -0.1413, 0.1190, -0.3149, -0.0722, 0.1051, -0.3068, -0.0992, 0.1406, -0.2982, -0.0560, -0.1366, 0.2158, -0.1223, -0.1466, -0.1506, -0.1736, 0.0919, -0.2678, 0.1382, 0.0972, -0.2826, 0.1965, 0.0643, -0.3346, -0.0533, 0.0756, -0.0912, 0.0469, 0.1534, -0.1580, 0.0504,
0.1382, -0.1633, 0.0420, -0.0799, 0.1400, 0.1583, -0.0813, 0.0790, 0.2696, -0.0667, 0.0703, 0.2754, 0.0856, 0.0944, 0.1457, 0.1075, -0.1023, 0.3506, 0.1343, -0.0117, 0.3571, 0.0473, -0.1081, -0.2147, 0.2138, 0.0046, -0.4749, 0.1633, 0.0029, -0.4600, 0.0515, 0.1347, 0.1025, 0.0936, -0.0609, -0.3520, -0.1797, 0.2092, -0.3399, -0.1959, 0.2070, -0.4005, -0.0467, -0.0834, -0.0446, -0.0297, -0.0849, -0.0254,
-0.1587, -0.2619, 0.0218, 0.0251, -0.0256, 0.1347, 0.0571, -0.0313, 0.1680, -0.0164, 0.2456, -0.2441, 0.0168, 0.2698, -0.2620, 0.0383, 0.2849, -0.2932, 0.0206, -0.2815, 0.5000, 0.0011, -0.3217, 0.4913, 0.0565, -0.3246, 0.4985, 0.0166, -0.1331, -0.4433, 0.0147, -0.0923, -0.4210, -0.0254, -0.1259, -0.4458, 0.0734, -0.0829, -0.3254, 0.0926, -0.1094, -0.2803, 0.2146, 0.2795, -0.4439, 0.2230, 0.1971, -0.4576,
0.2381, 0.2213, -0.4734, -0.1523, -0.0166, 0.0612, 0.1647, -0.0297, 0.3455, 0.1447, -0.0646, 0.3748, -0.2085, -0.2988, -0.0341, -0.1475, 0.2437, -0.3296, -0.1555, 0.2302, -0.3015, -0.0962, -0.1665, -0.4741, -0.0650, -0.1543, -0.4503, -0.1056, -0.1461, -0.4538, 0.0085, -0.2542, 0.1216, -0.0544, -0.0528, 0.3753, -0.1136, -0.0211, 0.3434, -0.1344, -0.2434, 0.2446, -0.1530, -0.2189, 0.2917, -0.1555, -0.1919, 0.2530,
0.0542, -0.2682, 0.0097, 0.0463, -0.2284, 0.0120, 0.1038, -0.2340, 0.0868, 0.0978, -0.1932, 0.0815, 0.0927, -0.2480, 0.0446, 0.1063, -0.2872, -0.1156, 0.1304, -0.2832, -0.1003, -0.1060, -0.2905, -0.0092, -0.0976, -0.2284, -0.0022, -0.1158, -0.1913, 0.0296, -0.0832, 0.1572, 0.0066, -0.1123, 0.1515, 0.0052, -0.2936, 0.1564, -0.4768, 0.0539, -0.1393, -0.2143, 0.0632, -0.1835, -0.1879, 0.0478, -0.1738, -0.1904,
-0.0934, -0.1952, 0.1513, -0.0709, -0.1964, 0.1317, -0.0869, -0.2192, 0.1609, -0.1222, -0.0965, -0.1441, 0.0171, -0.2458, 0.1453, -0.0006, -0.2464, 0.1205, 0.1137, -0.0587, 0.1864, 0.1057, -0.0312, 0.2249, 0.1165, -0.0226, 0.2421, -0.0649, 0.1697, 0.0048, -0.0397, 0.1816, -0.0031, -0.1317, -0.1038, -0.3728, -0.0176, 0.1867, 0.0347, 0.0435, -0.3380, -0.0793, -0.0493, -0.0347, 0.0184, -0.0259, -0.1683, -0.4613,
-0.0238, -0.1483, -0.4595, -0.0491, -0.0517, 0.1160, -0.0606, 0.1882, -0.1141, 0.0465, -0.2674, 0.2943, -0.1686, -0.0253, 0.1283, -0.1900, 0.0058, 0.1555, -0.1738, 0.0050, 0.1259, 0.0935, -0.1444, 0.2686, 0.1157, -0.1427, 0.2369, 0.1208, -0.1476, 0.2592, 0.0129, -0.3652, 0.3482, 0.0287, -0.3440, 0.3513, 0.0536, -0.3571, 0.3435, -0.0591, -0.1911, 0.3893, -0.1026, -0.1953, 0.3586, -0.1013, -0.2161, 0.3347,
-0.0581, -0.2113, 0.3654, 0.0294, -0.1770, 0.4225, 0.0135, -0.1922, 0.4403, 0.1045, 0.0790, -0.0206, 0.0985, 0.0904, -0.0022, 0.0948, -0.0635, -0.3266, 0.1009, -0.0912, -0.2665, -0.2186, -0.1335, -0.0598, -0.2205, -0.2110, -0.0417, 0.0742, -0.3221, -0.1250, 0.0104, -0.2841, 0.2481, 0.0357, -0.1498, -0.4280, 0.0275, -0.1511, -0.4498, -0.0564, -0.1561, 0.1545, -0.0384, -0.1418, 0.1607, -0.0839, -0.2317, 0.3105,
-0.0599, -0.2063, 0.2949, 0.0106, -0.1553, -0.0651, 0.0448, -0.2756, 0.2911, 0.1403, -0.2671, -0.0894, 0.0431, -0.2251, -0.0593, -0.0159, -0.2934, 0.4793, -0.0144, -0.3400, 0.4685, -0.1039, 0.1465, 0.1390, 0.0985, 0.0065, 0.3615, 0.0206, -0.3074, 0.2857, 0.1299, 0.1137, -0.1440, 0.1292, 0.1379, -0.1577, 0.0807, 0.0458, 0.3478, 0.0539, -0.0663, -0.2182, 0.0312, -0.0736, -0.2074, 0.1290, 0.0902, -0.1439,
0.0888, 0.0666, -0.1434, -0.0132, -0.0937, -0.0219, -0.2254, 0.1294, -0.4719, 0.0771, -0.0094, -0.4194, 0.0724, -0.0021, -0.4009, 0.1023, -0.0662, -0.4386, 0.1816, 0.2584, -0.4244, 0.1901, 0.2165, -0.4318, -0.0874, -0.1867, -0.2411, -0.0909, -0.2050, -0.2077, 0.0948, -0.1159, 0.3346, 0.1221, -0.1396, 0.3145, -0.0335, -0.0622, -0.0888, 0.0603, 0.3264, -0.4745, 0.0147, 0.3974, -0.4756, 0.0145, 0.2878, -0.4742,
0.0834, -0.2530, 0.3514, -0.0146, 0.2538, -0.2374, -0.0607, -0.2631, 0.2236, -0.0749, -0.2584, 0.2751, -0.1233, -0.2651, 0.2575, 0.0457, -0.1592, 0.3951, 0.0553, -0.1902, 0.4095, -0.1150, -0.2604, 0.2335, 0.0751, 0.1245, -0.0341, 0.2456, -0.0713, -0.4762, 0.1813, -0.1753, 0.1257, -0.0181, -0.1451, 0.1712, 0.0562, -0.1423, -0.4427, 0.1924, 0.0556, -0.4154, -0.0962, 0.2371, -0.1505, -0.0899, 0.2433, -0.1822,
-0.1507, 0.2351, -0.1806, 0.0305, -0.1516, -0.1622, 0.0421, -0.1157, -0.1944, 0.0324, -0.1611, -0.1760, 0.0446, -0.0941, -0.2081, 0.0391, -0.1006, -0.1255, 0.0584, -0.2820, 0.2722, 0.0814, 0.3067, -0.3262, 0.0724, 0.2946, -0.3058, 0.0927, 0.2711, -0.2497, 0.0414, 0.1065, 0.2797, -0.1873, 0.2147, -0.4169, 0.0835, -0.0541, 0.4047, 0.0567, -0.1137, 0.3892, 0.1168, -0.0772, 0.3804, -0.0417, -0.0365, 0.0010,
-0.0652, -0.1474, 0.1617, -0.0583, -0.1169, 0.1570, -0.1493, -0.2143, 0.2411, -0.1219, -0.2212, 0.1870, 0.0415, -0.3113, -0.0926, -0.0064, -0.0270, -0.3249, 0.0180, -0.0227, -0.3573, -0.1191, -0.0203, -0.3741, 0.0188, -0.1669, -0.0195, -0.1431, -0.3263, -0.0182, 0.0782, 0.0744, 0.0248, -0.0978, -0.1544, 0.1819, -0.1752, -0.0132, -0.4185, -0.0110, -0.2155, 0.2074, 0.0939, 0.0274, -0.3005, 0.0708, -0.1071, -0.3948,
0.0713, 0.0605, 0.0497, 0.0501, 0.0431, 0.0417, 0.0320, -0.1817, 0.3165, 0.0444, -0.2268, 0.2986, 0.0199, -0.2097, 0.2927, 0.0992, -0.1037, -0.4474, -0.1321, -0.2356, 0.3022, -0.1497, -0.2055, 0.3083, -0.1916, 0.1900, -0.3703, -0.1993, 0.1587, -0.4202, -0.0603, -0.0897, -0.0313, 0.0795, -0.0089, 0.1740, 0.0993, 0.0143, 0.1770, 0.0387, -0.1169, 0.0315, 0.0670, 0.0945, -0.1233, 0.0990, -0.3218, -0.1153,
-0.0824, 0.0055, 0.3333, 0.0947, 0.2214, -0.1427, 0.0813, 0.2391, -0.1381, 0.1106, 0.1683, -0.1453, 0.0952, -0.0270, 0.3956, 0.0732, -0.0189, 0.4029, -0.0164, 0.1848, -0.0271, 0.0084, -0.3128, 0.3204, 0.0076, -0.2883, 0.2971, 0.0272, -0.3186, 0.3087, -0.1730, 0.1988, -0.3114, 0.1446, 0.2901, -0.4224, 0.1774, 0.2969, -0.4365, 0.1316, 0.3339, -0.4710, -0.0807, 0.1601, -0.0982, -0.0733, 0.1777, -0.0727,
-0.0938, -0.2791, -0.0710, -0.0870, -0.2685, -0.0989, -0.0725, -0.2051, 0.3269, 0.0119, -0.2510, 0.0393, 0.0412, -0.2274, 0.0211, -0.0392, -0.0617, 0.3866, 0.1000, -0.3099, 0.4565, 0.0827, -0.2936, 0.4839, 0.0761, -0.3374, 0.4803, -0.0150, -0.1548, -0.4743, -0.0217, 0.2638, -0.3146, -0.0586, 0.2523, -0.2982, -0.0232, 0.2429, -0.2765, -0.1899, -0.0174, -0.4743, 0.0619, -0.0100, 0.1409, 0.0696, 0.0146, 0.1407,
0.0060, -0.2992, 0.2695, 0.0161, -0.3254, 0.2646, -0.0129, -0.0396, 0.1372, 0.0367, -0.1992, 0.0250, -0.0691, -0.2319, 0.1676, 0.1129, -0.1703, 0.1132, 0.1077, -0.1653, 0.1456, 0.1141, -0.1269, 0.1226, -0.1021, -0.2380, -0.2053, -0.0442, 0.2630, -0.3401, 0.0984, -0.3640, 0.4240, 0.1056, -0.3409, 0.4050, 0.0516, 0.0284, 0.3626, 0.0377, 0.0693, 0.3278, 0.0103, 0.0600, 0.3496, -0.1020, 0.0565, 0.2880,
-0.1179, -0.1069, -0.1302, -0.1486, -0.1797, -0.1267, 0.0844, -0.3027, -0.1058, 0.0644, -0.2121, 0.3752, 0.0935, -0.2503, 0.4340, 0.1025, -0.2738, 0.4270, 0.0793, 0.2716, -0.2382, 0.0178, 0.2692, -0.2355, 0.1212, -0.3052, -0.0166, 0.0685, -0.0274, -0.1336, -0.0063, -0.3704, 0.4302, -0.0412, -0.3041, 0.4223, 0.1316, -0.1935, 0.1304, 0.1081, -0.3291, -0.1025, -0.1669, -0.1948, -0.1210, 0.0967, -0.2432, 0.1007,
0.0626, -0.1314, -0.4151, 0.0934, 0.0594, 0.0152, -0.0423, -0.0455, -0.3334, -0.0232, -0.0389, -0.3271, -0.0333, -0.0641, -0.2379, 0.0646, -0.2691, 0.2541, -0.1085, 0.1186, 0.2023, 0.0047, -0.0721, -0.2021, 0.0665, -0.0838, -0.3596, 0.0390, -0.3375, 0.3359, 0.0063, -0.3371, 0.3397, -0.0624, -0.1229, -0.0218, -0.0681, -0.0958, -0.0852, 0.1419, -0.1392, 0.2324, 0.2128, 0.0321, -0.4512, 0.0715, -0.2132, 0.4041,
-0.0820, 0.1730, -0.1110, 0.0178, -0.3630, 0.4713, -0.1318, -0.2666, 0.0131, 0.1225, 0.0405, 0.2231, 0.0499, -0.2031, 0.3441, 0.1253, -0.0353, 0.3785, -0.0464, -0.0204, 0.3567, -0.2141, -0.0355, 0.0062, -0.1256, -0.3294, -0.0173, 0.0919, -0.2975, 0.3488, -0.0556, 0.1788, 0.0404, 0.1094, 0.0381, -0.2230, 0.0970, -0.0007, -0.2164, 0.0850, 0.0066, -0.2633, -0.0611, 0.2347, -0.1117, -0.0954, 0.2240, -0.1033,
-0.0970, -0.0597, -0.3310, -0.0548, -0.2078, 0.1117, 0.1390, -0.0261, 0.2537, 0.0475, 0.0368, 0.0300, -0.0303, -0.2898, 0.4545, -0.0338, 0.0153, 0.3708, -0.0192, 0.0545, 0.3474, -0.0435, 0.0356, 0.3336, -0.1839, 0.0981, 0.0404, -0.1625, 0.0575, -0.1270, 0.0550, -0.2198, -0.1358, 0.0696, -0.3176, -0.1139, 0.0834, -0.3226, -0.1144, 0.0710, -0.2477, 0.2734, -0.1020, -0.0213, 0.0808, -0.1460, -0.0142, 0.0963,
0.0966, -0.2962, 0.3819, 0.0485, 0.0186, 0.0302, 0.0163, -0.2345, 0.1705, -0.0315, -0.0233, 0.0109, -0.0644, -0.2523, 0.1897, -0.0382, -0.2354, 0.1679, 0.0796, -0.2555, 0.0306, 0.1758, -0.0580, 0.2696, 0.0626, -0.0883, -0.1401, 0.0825, 0.0508, 0.1323, 0.0714, -0.3208, -0.0998, -0.0324, 0.2696, -0.4697, 0.0489, -0.0903, -0.1750, 0.0331, -0.1052, -0.1849, -0.2198, 0.0535, -0.4707, 0.0528, -0.2991, -0.0691,
0.0314, -0.2957, -0.0507, 0.0450, -0.2789, -0.0562, 0.0192, 0.0119, 0.0742, 0.0171, 0.0034, 0.0841, 0.1028, -0.0543, -0.4188, -0.1932, 0.0988, -0.0332, -0.1926, -0.2899, -0.1165, -0.1862, -0.2344, -0.1977, -0.2135, -0.2009, -0.0608, -0.2000, -0.2279, -0.0755, -0.2058, -0.2885, -0.0678, -0.0681, -0.0869, -0.2130, 0.1331, -0.0341, 0.2191, 0.0584, -0.2481, 0.0226, -0.1864, 0.0906, -0.1038, -0.1988, 0.0877, -0.0813,
-0.1219, -0.0748, 0.0486, -0.1004, -0.3036, -0.1000, -0.1057, -0.2958, -0.1443, 0.0881, -0.2724, 0.3943, -0.0331, -0.2076, 0.2727, -0.1059, -0.2613, -0.1736, -0.1011, -0.2189, -0.2304, -0.1565, -0.1837, -0.2697, -0.1209, -0.1380, -0.4581, 0.1312, -0.2602, 0.0106, 0.0475, -0.2013, 0.1399, 0.0976, -0.3111, 0.3795, 0.0881, -0.3100, 0.3513, 0.0152, 0.2735, -0.3000, 0.0220, 0.2716, -0.3286, 0.0304, -0.2341, 0.1454,
-0.0017, -0.2571, 0.4789, -0.0350, -0.2121, 0.4226, 0.0960, 0.0413, 0.1539, -0.0917, 0.1581, -0.0382, -0.0150, -0.0447, -0.3610, -0.1717, 0.1669, -0.3312, 0.0372, -0.0376, 0.4062, -0.0571, 0.1363, 0.2000, -0.0419, 0.1290, 0.2252, 0.0288, -0.3329, -0.0721, -0.1741, -0.0573, 0.0408, 0.2331, 0.2711, -0.4758, 0.2067, 0.3113, -0.4764, 0.2239, 0.2810, -0.4738, 0.1606, -0.1297, 0.2663, -0.0335, -0.2393, 0.1466,
-0.0268, -0.3291, 0.3743, -0.1710, 0.0150, -0.1137, -0.1783, 0.1302, -0.0598, -0.1598, 0.1348, -0.0182, 0.0280, -0.0091, 0.1086, -0.1662, 0.1434, -0.0896, -0.2156, -0.0067, -0.0082, -0.0185, -0.0827, 0.1581, -0.0574, 0.0593, 0.2937, 0.0720, -0.1380, -0.4672, -0.1866, -0.3384, -0.1063, 0.0849, 0.2620, -0.1745, -0.1881, -0.0207, 0.2032, -0.1849, -0.0464, 0.2267, -0.1669, 0.0726, -0.1211, 0.0210, -0.1137, -0.4148,
-0.1259, 0.2312, -0.1340, -0.1306, 0.2175, -0.1156, -0.0576, 0.2385, -0.2579, 0.0203, -0.2757, -0.0772, 0.0835, -0.0396, -0.1615, 0.1770, -0.0408, 0.3236, -0.1085, -0.2443, 0.3023, -0.0747, -0.1136, -0.3414, -0.0101, -0.1844, 0.4166, 0.1904, 0.1711, -0.4247, 0.1924, 0.1618, -0.4310, 0.0413, -0.1521, -0.4713, 0.1149, 0.0137, -0.1502, 0.1236, 0.0309, -0.1361, -0.0102, 0.0251, 0.3777, -0.0232, -0.0160, 0.0899,
-0.0174, -0.0233, 0.1237, -0.0933, -0.1545, -0.2546, -0.1699, -0.0322, -0.1467, -0.1602, -0.0403, -0.1833, -0.1027, -0.2397, -0.1118, 0.0810, 0.1754, -0.1396, 0.0270, -0.1081, 0.0316, -0.0219, -0.0506, -0.2445, 0.1265, 0.0006, 0.2591, 0.1124, 0.0173, 0.2100, 0.0981, -0.1209, 0.2360, 0.0867, -0.1078, 0.2132, 0.0842, -0.1249, -0.4259, -0.1364, -0.0883, -0.3632, 0.0093, -0.3848, 0.3862, 0.0490, -0.1788, 0.0414,
-0.0511, -0.0672, -0.0938, 0.0475, 0.3175, -0.4723, -0.0677, -0.0906, -0.3703, -0.0618, 0.1585, 0.0649, 0.0339, -0.2952, 0.1534, 0.0174, -0.2998, 0.2690, 0.0323, -0.1691, 0.0025, 0.0184, -0.1648, 0.2746, 0.0429, 0.1597, 0.0628, -0.0890, -0.0970, -0.2982, 0.1202, -0.1649, 0.0599, 0.1093, -0.1549, 0.0921, -0.1604, -0.1663, 0.2391, 0.0534, 0.1459, -0.1372, 0.0015, 0.2394, -0.1287, -0.0298, -0.2478, 0.3654,
0.1132, 0.0119, -0.1740, 0.1398, 0.0941, -0.2350, 0.2473, 0.2654, -0.5000, 0.1716, 0.3447, -0.4999, 0.2539, 0.2547, -0.4774, 0.2043, 0.3029, -0.4511, -0.1629, -0.0003, -0.3390, -0.1015, -0.0216, -0.3300, -0.1817, 0.0390, -0.2446, -0.1714, 0.0120, -0.1250, 0.0459, -0.3179, 0.1956, 0.1028, 0.0710, 0.1803, 0.0661, -0.1232, 0.2076, 0.0055, -0.3663, 0.3709, -0.0074, -0.3360, 0.3587, -0.1798, -0.2826, -0.1575,
0.1267, -0.1719, 0.1883, 0.1261, 0.0566, -0.1886, -0.1695, -0.1572, 0.2659, -0.1832, -0.1266, 0.2542, -0.0486, -0.1978, 0.2972, 0.2442, 0.2021, -0.4748, -0.1635, -0.0183, -0.2201, -0.1901, 0.0402, 0.1820, 0.2389, 0.1422, -0.4741, 0.0107, -0.1878, 0.2762, -0.1544, 0.2320, -0.1756, -0.0370, -0.2664, 0.4096, -0.0058, -0.3252, 0.3369, -0.0816, -0.2239, -0.1796, -0.0886, -0.2160, -0.1348, 0.2861, 0.1831, -0.4765,
-0.1523, 0.0718, 0.2226, -0.1650, 0.0888, 0.1620, 0.0711, -0.1435, -0.4308, 0.0359, -0.2961, -0.1332, 0.0229, -0.3021, -0.1222, 0.0006, -0.0653, 0.4140, 0.1250, -0.2341, 0.1071, -0.1435, -0.1254, -0.3204, 0.1042, -0.2777, 0.3881, 0.1812, 0.2311, -0.4177, 0.0936, -0.3710, 0.3938, -0.1438, -0.1707, 0.2192, 0.0272, -0.1132, 0.4011, -0.0992, -0.3232, -0.1043, -0.1644, 0.0168, -0.2139, -0.1679, 0.0556, -0.2358,
0.1134, 0.0431, 0.0031, -0.0918, -0.1025, -0.1155, 0.0935, 0.3015, -0.3981, 0.0977, 0.3078, -0.3713, 0.0166, -0.0854, 0.4141, 0.0892, -0.1206, 0.1759, -0.0740, -0.1740, 0.1500, 0.1903, -0.1689, 0.1026, -0.0413, -0.2305, 0.4049, -0.1714, 0.0046, -0.1886, -0.1972, 0.1987, -0.4523, 0.1338, 0.1521, -0.2296, 0.0730, -0.2569, 0.2954, -0.0432, 0.0652, 0.3205, -0.0889, 0.2195, -0.1009, -0.1386, -0.1270, -0.3285,
-0.0956, 0.3829, -0.4764, -0.0924, -0.2927, -0.0666, 0.0368, -0.2901, 0.0863, -0.1944, -0.2388, -0.1088, -0.1938, -0.2755, -0.1058, -0.1326, -0.1210, -0.3492, 0.1612, 0.2368, -0.3877, -0.1741, 0.1264, -0.2067, -0.1266, -0.1958, 0.1766, -0.0713, -0.0353, -0.3638, -0.0778, -0.0359, -0.3630, -0.1278, 0.2083, -0.1089, -0.0533, -0.0511, -0.3101, 0.0974, -0.1596, -0.0755, 0.0507, -0.0099, -0.3054, -0.1492, -0.1939, 0.2106,
-0.1179, -0.1742, 0.1707, 0.1243, 0.3391, -0.4751, -0.1815, -0.1053, 0.2915, -0.1626, -0.1459, 0.3071, -0.0687, -0.1003, -0.0533, 0.1049, 0.3769, -0.4761, -0.0616, -0.0663, -0.3970, -0.0896, -0.2557, -0.0344, -0.0118, -0.2024, 0.2916, 0.0759, -0.3772, 0.4321, 0.1253, 0.1653, -0.2335, 0.0996, -0.2977, 0.2498, 0.0535, -0.0748, 0.1771, 0.1279, 0.2795, -0.3854, 0.0383, -0.2184, -0.0098, 0.0590, -0.0295, -0.2827,
0.0977, -0.3405, 0.3942, 0.1187, 0.0646, -0.2575, 0.1687, -0.1082, 0.2410, -0.1714, 0.0103, 0.1088, 0.0434, 0.2280, -0.1266, -0.1449, -0.1199, -0.3035, -0.1832, -0.1852, -0.1052, -0.1992, -0.1955, -0.1654, -0.1643, -0.1413, -0.1976, -0.1259, -0.1647, -0.3141, -0.1093, -0.0233, 0.0982, -0.2091, -0.3106, -0.0934, 0.1803, -0.0761, 0.2829, -0.0087, -0.2781, 0.2808, -0.0216, 0.1134, 0.2683, -0.0196, -0.0186, 0.3913,
-0.0767, -0.1249, -0.0997, -0.2390, 0.2775, -0.4763, -0.1198, -0.1421, -0.1899, 0.0999, -0.1404, 0.2203, 0.1206, 0.0528, -0.3752, 0.1087, -0.1792, -0.4764, -0.1770, -0.0322, 0.1560, 0.1711, 0.3422, -0.4762, 0.2235, -0.1004, -0.5000, 0.1514, -0.1585, -0.5000, 0.2814, -0.0040, -0.5000, 0.2991, 0.1061, -0.5000, 0.2807, 0.1986, -0.5000, -0.2305, -0.0917, -0.5000, -0.2812, -0.0084, -0.4999, -0.2713, 0.2260, -0.5000,
0.0589, -0.1952, -0.5000, -0.0435, -0.1972, -0.5000, -0.0045, 0.3972, -0.5000, -0.1725, -0.1458, -0.4999, -0.2266, 0.2932, -0.5000, -0.2991, 0.0884, -0.4999, -0.2938, 0.1523, -0.4999, -0.1075, -0.1799, -0.5000, -0.0853, 0.3858, -0.5000, 0.0760, 0.3873, -0.5000, -0.1709, 0.3442, -0.4999, -0.1821, 0.3352, -0.4754, 0.1678, 0.2727, -0.4278, 0.0051, 0.1383, 0.2111, };
const unsigned short triangles[][3] = {
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 27, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45,
46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 79, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91,
92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 90, 110, 111, 112, 113, 114, 115, 116, 117, 118, 62, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 35, 129, 130, 131, 132, 133, 134, 135, 136,
137, 138, 139, 140, 141, 47, 140, 47, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 155, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 146, 148, 168, 169, 38, 170, 171, 126, 172, 173, 174, 175,
87, 176, 177, 178, 179, 180, 181, 182, 183, 44, 43, 184, 143, 145, 185, 186, 187, 188, 65, 189, 66, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 8, 211, 6, 212, 213, 214,
215, 216, 217, 218, 219, 220, 74, 73, 221, 221, 222, 223, 224, 225, 226, 192, 191, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 207, 237, 166, 238, 239, 240, 118, 119, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 0,
251, 0, 253, 254, 180, 255, 256, 257, 258, 259, 260, 261, 64, 262, 263, 264, 265, 266, 267, 268, 83, 269, 270, 271, 223, 272, 273, 274, 275, 276, 277, 278, 279, 78, 77, 280, 281, 282, 283, 284, 285, 286, 287, 288, 174, 143, 289, 290,
23, 291, 292, 293, 294, 295, 293, 295, 296, 297, 298, 289, 299, 41, 300, 301, 302, 303, 198, 304, 305, 306, 307, 308, 22, 309, 291, 310, 311, 312, 313, 314, 315, 316, 317, 206, 212, 318, 319, 320, 321, 322, 323, 324, 325, 326, 327, 328,
329, 330, 154, 331, 269, 202, 271, 188, 332, 22, 333, 309, 334, 220, 219, 11, 300, 335, 336, 337, 338, 339, 340, 341, 276, 342, 343, 344, 345, 346, 347, 348, 349, 350, 351, 352, 109, 108, 353, 281, 283, 354, 355, 54, 53, 356, 357, 358,
359, 360, 361, 362, 122, 363, 364, 365, 366, 367, 368, 369, 285, 370, 235, 371, 372, 373, 374, 375, 376, 377, 378, 379, 380, 381, 382, 383, 384, 385, 302, 386, 303, 387, 388, 366, 389, 390, 391, 392, 393, 394, 73, 75, 395, 187, 186, 396,
19, 380, 397, 398, 399, 58, 400, 401, 402, 403, 256, 258, 404, 405, 406, 380, 407, 397, 408, 409, 388, 66, 410, 411, 318, 212, 323, 412, 413, 414, 412, 414, 415, 416, 417, 418, 419, 420, 421, 422, 423, 424, 425, 409, 408, 425, 408, 426,
403, 427, 428, 429, 430, 431, 432, 433, 434, 435, 339, 341, 436, 435, 341, 437, 404, 438, 439, 440, 405, 441, 442, 443, 393, 444, 445, 446, 132, 24, 122, 447, 448, 122, 448, 449, 450, 451, 452, 440, 173, 280, 453, 96, 454, 453, 454, 455,
213, 212, 319, 456, 457, 458, 459, 460, 461, 462, 463, 464, 347, 465, 466, 467, 468, 469, 3, 354, 470, 9, 471, 472, 473, 474, 475, 476, 477, 478, 479, 363, 480, 481, 482, 483, 484, 336, 485, 486, 487, 488, 489, 469, 468, 490, 491, 193,
492, 493, 494, 495, 290, 289, 496, 455, 497, 498, 499, 279, 337, 500, 501, 502, 503, 504, 505, 506, 433, 507, 508, 509, 507, 509, 510, 511, 512, 217, 513, 491, 514, 513, 514, 289, 515, 516, 517, 518, 519, 520, 521, 522, 523, 281, 380, 35,
354, 524, 281, 179, 178, 525, 75, 526, 71, 75, 71, 527, 143, 185, 513, 525, 528, 179, 529, 530, 454, 531, 511, 532, 533, 534, 535, 536, 319, 537, 538, 539, 81, 538, 81, 540, 541, 542, 496, 541, 496, 497, 543, 132, 446, 544, 545, 546,
547, 548, 213, 549, 550, 551, 552, 553, 554, 555, 556, 557, 353, 558, 109, 326, 559, 560, 561, 562, 563, 564, 565, 566, 567, 568, 569, 570, 571, 572, 55, 551, 573, 401, 574, 575, 92, 576, 577, 578, 38, 579, 578, 579, 580, 218, 220, 581,
582, 568, 583, 584, 166, 585, 586, 587, 588, 589, 286, 590, 591, 592, 593, 322, 594, 595, 596, 597, 598, 599, 600, 601, 602, 284, 603, 604, 605, 606, 607, 608, 609, 610, 611, 612, 559, 326, 613, 614, 615, 616, 434, 617, 345, 618, 619, 620,
116, 115, 17, 621, 622, 623, 624, 625, 626, 627, 628, 629, 630, 631, 632, 633, 634, 635, 374, 376, 636, 335, 9, 11, 637, 638, 639, 640, 641, 642, 643, 298, 297, 644, 645, 646, 257, 168, 258, 304, 85, 305, 647, 648, 649, 79, 82, 650,
167, 651, 165, 652, 217, 653, 15, 654, 655, 656, 657, 342, 658, 659, 660, 661, 662, 663, 664, 665, 666, 647, 456, 667, 668, 100, 99, 669, 670, 544, 107, 671, 108, 672, 518, 79, 673, 475, 674, 487, 675, 676, 487, 676, 488, 534, 677, 535,
666, 678, 664, 569, 493, 679, 680, 545, 681, 682, 637, 639, 236, 683, 684, 505, 201, 662, 685, 686, 687, 688, 689, 690, 688, 690, 691, 26, 692, 693, 694, 695, 696, 487, 486, 697, 90, 698, 110, 699, 700, 570, 406, 701, 636, 702, 264, 290,
703, 288, 704, 705, 706, 707, 113, 112, 708, 69, 466, 709, 556, 710, 557, 120, 614, 711, 712, 713, 103, 714, 66, 114, 715, 100, 443, 592, 229, 603, 716, 667, 717, 582, 535, 677, 159, 718, 719, 200, 720, 201, 428, 721, 722, 723, 724, 725,
726, 727, 728, 729, 730, 731, 732, 733, 614, 734, 735, 736, 593, 737, 70, 473, 85, 304, 184, 738, 739, 200, 740, 475, 741, 742, 648, 348, 347, 69, 743, 744, 745, 261, 260, 746, 747, 748, 212, 749, 750, 751, 170, 743, 745, 752, 128, 753,
754, 755, 756, 148, 147, 383, 695, 757, 758, 759, 760, 761, 223, 762, 763, 116, 16, 764, 106, 240, 239, 765, 766, 767, 768, 769, 770, 52, 771, 238, 746, 772, 773, 774, 775, 776, 777, 778, 331, 779, 498, 278, 623, 396, 780, 781, 137, 374,
781, 374, 636, 782, 284, 602, 782, 602, 450, 386, 783, 784, 672, 589, 785, 204, 786, 202, 787, 3, 5, 788, 789, 790, 791, 792, 793, 794, 795, 796, 41, 335, 300, 797, 798, 799, 797, 799, 800, 801, 802, 293, 803, 622, 804, 805, 806, 733,
432, 807, 808, 809, 404, 406, 810, 310, 642, 811, 812, 460, 618, 813, 814, 815, 61, 816, 646, 101, 713, 817, 552, 409, 818, 381, 470, 819, 758, 317, 820, 24, 132, 727, 821, 822, 823, 221, 73, 556, 180, 824, 825, 381, 818, 826, 827, 352,
210, 658, 208, 824, 180, 828, 829, 830, 480, 831, 351, 832, 552, 366, 833, 401, 400, 574, 163, 834, 164, 835, 836, 837, 735, 838, 839, 492, 580, 679, 840, 89, 841, 842, 843, 45, 533, 535, 582, 389, 842, 466, 426, 844, 92, 845, 846, 847,
628, 600, 848, 586, 132, 543, 724, 723, 849, 456, 59, 667, 850, 851, 852, 349, 853, 854, 852, 855, 850, 71, 526, 72, 856, 396, 622, 712, 359, 361, 712, 361, 857, 340, 78, 858, 503, 502, 130, 814, 859, 619, 461, 860, 459, 644, 646, 861,
862, 863, 630, 862, 630, 864, 865, 866, 711, 865, 711, 867, 827, 826, 509, 520, 540, 80, 344, 346, 104, 595, 105, 346, 868, 121, 711, 576, 94, 869, 818, 787, 870, 871, 872, 873, 820, 131, 25, 180, 528, 874, 149, 774, 682, 667, 741, 647,
90, 111, 91, 875, 717, 667, 864, 402, 575, 876, 877, 878, 731, 301, 303, 387, 879, 388, 880, 519, 881, 882, 883, 749, 113, 683, 581, 137, 421, 884, 362, 885, 886, 657, 656, 615, 685, 887, 33, 131, 888, 817, 741, 667, 716, 474, 889, 720,
381, 281, 524, 219, 218, 890, 606, 120, 122, 195, 185, 316, 891, 880, 813, 498, 279, 278, 892, 579, 499, 118, 893, 384, 894, 665, 329, 895, 227, 715, 2, 312, 311, 136, 859, 814, 896, 897, 218, 362, 886, 447, 42, 41, 299, 898, 34, 36,
899, 900, 283, 102, 901, 190, 902, 903, 750, 904, 717, 905, 159, 161, 906, 907, 908, 181, 635, 909, 264, 40, 910, 188, 438, 12, 911, 912, 707, 706, 490, 9, 514, 913, 914, 915, 916, 828, 917, 409, 552, 833, 478, 477, 341, 617, 595, 346,
269, 918, 270, 861, 158, 142, 409, 833, 388, 710, 556, 824, 919, 920, 921, 741, 716, 922, 923, 924, 925, 202, 926, 927, 95, 928, 929, 799, 815, 930, 391, 358, 389, 499, 579, 279, 330, 329, 664, 931, 659, 932, 786, 204, 328, 328, 327, 786,
608, 933, 548, 934, 935, 936, 8, 937, 783, 440, 280, 77, 938, 939, 940, 492, 494, 941, 267, 473, 673, 907, 942, 943, 944, 640, 945, 946, 721, 428, 210, 947, 659, 658, 948, 770, 40, 335, 41, 949, 950, 951, 430, 952, 431, 647, 939, 953,
934, 954, 955, 956, 957, 958, 405, 437, 439, 912, 959, 748, 239, 960, 961, 456, 647, 953, 484, 500, 336, 12, 438, 962, 144, 704, 145, 12, 757, 911, 854, 601, 963, 627, 177, 414, 964, 934, 965, 424, 312, 259, 836, 678, 98, 966, 967, 559,
968, 694, 696, 300, 969, 299, 293, 296, 964, 441, 463, 462, 970, 822, 971, 223, 763, 272, 182, 775, 183, 972, 76, 416, 244, 703, 704, 834, 17, 115, 437, 973, 694, 106, 974, 104, 832, 42, 299, 57, 794, 796, 253, 699, 975, 442, 441, 462,
976, 227, 895, 298, 977, 633, 22, 291, 23, 522, 521, 464, 432, 345, 807, 978, 979, 980, 981, 311, 310, 150, 246, 151, 930, 504, 800, 683, 236, 581, 943, 908, 907, 982, 705, 823, 861, 142, 47, 983, 445, 980, 715, 805, 732, 715, 732, 984,
796, 795, 985, 985, 795, 986, 796, 921, 176, 358, 357, 791, 987, 455, 988, 416, 340, 989, 990, 861, 646, 205, 316, 206, 293, 964, 991, 255, 180, 556, 451, 228, 230, 992, 926, 202, 282, 963, 600, 936, 728, 993, 994, 761, 662, 995, 254, 255,
34, 996, 35, 386, 784, 303, 878, 997, 916, 563, 659, 931, 563, 931, 561, 769, 813, 618, 717, 875, 905, 998, 747, 933, 434, 506, 999, 889, 304, 1000, 628, 848, 1001, 1002, 777, 762, 1003, 1004, 1005, 1006, 1007, 327, 975, 570, 226, 108, 1008, 32,
983, 93, 445, 173, 287, 174, 120, 711, 121, 208, 1009, 209, 555, 557, 1010, 370, 365, 1011, 486, 488, 215, 1012, 971, 822, 440, 171, 405, 472, 471, 187, 48, 338, 152, 1013, 1014, 1015, 124, 1016, 125, 675, 483, 1017, 12, 438, 695, 767, 766, 1018,
875, 667, 399, 984, 732, 120, 984, 120, 606, 962, 1019, 1020, 4, 598, 1021, 392, 718, 452, 9, 335, 471, 880, 136, 814, 830, 94, 983, 123, 125, 999, 1022, 1023, 737, 397, 919, 20, 1001, 848, 1024, 1025, 890, 1011, 893, 1026, 373, 902, 798, 903,
118, 383, 147, 292, 756, 144, 933, 747, 548, 782, 161, 1027, 829, 94, 830, 168, 135, 258, 1028, 948, 1029, 203, 332, 204, 1030, 226, 225, 1010, 1031, 435, 969, 689, 1032, 1033, 684, 683, 1033, 683, 708, 920, 919, 397, 404, 1034, 438, 847, 60, 1035,
643, 472, 803, 656, 758, 757, 102, 359, 103, 621, 804, 622, 693, 1036, 1037, 164, 834, 1038, 389, 358, 842, 1039, 1040, 1041, 898, 390, 34, 718, 159, 906, 136, 880, 881, 1014, 958, 315, 1042, 234, 1043, 985, 921, 796, 1000, 759, 994, 974, 110, 377,
837, 1044, 191, 962, 1020, 12, 1016, 272, 1045, 1046, 610, 1047, 666, 463, 441, 1048, 1049, 1050, 1051, 444, 771, 696, 695, 758, 637, 1052, 436, 128, 1053, 753, 868, 1036, 121, 782, 1027, 285, 1054, 105, 1055, 230, 1056, 541, 1057, 1058, 430, 1057, 430, 929,
848, 599, 1059, 118, 1060, 63, 93, 983, 94, 966, 559, 873, 1061, 1062, 952, 217, 512, 653, 249, 1063, 250, 1064, 277, 169, 1065, 287, 968, 859, 372, 371, 627, 414, 596, 333, 22, 1066, 445, 1051, 980, 1067, 1068, 1001, 810, 870, 310, 194, 193, 491,
953, 1069, 1070, 555, 1010, 776, 260, 333, 1071, 1072, 547, 1073, 1074, 943, 1033, 770, 769, 1009, 1060, 816, 63, 703, 174, 288, 762, 1075, 763, 776, 1052, 774, 1076, 886, 885, 1076, 885, 979, 414, 597, 596, 534, 1077, 904, 67, 878, 877, 876, 917, 1078,
921, 945, 423, 139, 587, 374, 199, 201, 505, 1079, 314, 1080, 171, 172, 1081, 546, 1035, 458, 1082, 592, 591, 1083, 1084, 1085, 843, 1086, 43, 773, 1029, 1087, 868, 711, 866, 432, 434, 345, 1088, 971, 18, 1089, 240, 106, 1090, 1045, 1091, 234, 1092, 1043,
1093, 532, 511, 595, 594, 105, 269, 271, 203, 1094, 434, 999, 881, 519, 1095, 755, 754, 972, 695, 973, 757, 3, 470, 4, 32, 353, 108, 494, 493, 1038, 707, 1096, 263, 259, 312, 2, 860, 461, 1097, 673, 1098, 268, 464, 565, 462, 913, 507, 500,
913, 500, 1099, 1100, 1101, 324, 320, 322, 595, 679, 686, 569, 170, 38, 743, 1089, 1102, 1017, 1103, 605, 604, 14, 543, 1018, 1104, 697, 1105, 658, 210, 659, 248, 250, 369, 723, 1106, 632, 723, 632, 631, 489, 1107, 469, 458, 457, 546, 1032, 521, 1108,
274, 276, 806, 149, 682, 951, 321, 320, 125, 557, 1109, 1031, 660, 659, 563, 815, 1110, 851, 1111, 368, 367, 722, 403, 428, 608, 1112, 609, 913, 915, 827, 1113, 142, 1114, 416, 418, 972, 937, 1115, 729, 1116, 1117, 299, 958, 1014, 1118, 1081, 172, 420,
725, 1070, 1069, 509, 508, 913, 509, 913, 827, 151, 246, 245, 581, 896, 218, 1119, 1092, 1120, 1111, 1121, 368, 238, 1122, 1123, 1124, 96, 95, 252, 251, 309, 341, 340, 478, 1115, 7, 1097, 352, 915, 1125, 1058, 84, 248, 210, 620, 947, 636, 138, 1034,
580, 579, 892, 554, 553, 1126, 619, 371, 21, 705, 263, 262, 550, 88, 1068, 980, 1127, 983, 213, 536, 547, 995, 1128, 1129, 753, 468, 752, 899, 596, 3, 218, 1011, 890, 1130, 1131, 150, 853, 348, 68, 495, 289, 298, 160, 879, 161, 192, 1132, 976,
525, 708, 112, 31, 498, 1133, 568, 582, 677, 1134, 56, 233, 23, 266, 1135, 1, 333, 260, 853, 801, 854, 394, 1136, 844, 308, 641, 306, 880, 891, 520, 1039, 588, 884, 546, 1137, 847, 738, 184, 1109, 402, 742, 400, 411, 780, 1002, 756, 127, 754,
626, 1111, 1138, 999, 591, 123, 905, 534, 904, 885, 362, 479, 1138, 1111, 302, 1124, 95, 929, 1103, 449, 729, 868, 1037, 1036, 190, 1097, 102, 762, 222, 1139, 840, 1121, 89, 865, 693, 1037, 562, 1140, 261, 64, 66, 411, 185, 1065, 316, 308, 1141, 810,
671, 90, 89, 845, 1137, 680, 601, 991, 599, 1142, 264, 909, 518, 80, 79, 575, 402, 401, 391, 1143, 356, 1144, 220, 334, 1144, 334, 623, 624, 626, 1138, 520, 519, 880, 625, 1008, 1145, 1146, 144, 1147, 373, 1071, 1066, 520, 1148, 540, 964, 965, 599,
1149, 1125, 1150, 678, 99, 98, 932, 561, 931, 922, 1077, 574, 503, 19, 1151, 91, 841, 89, 894, 1005, 523, 894, 523, 665, 55, 57, 796, 9, 490, 10, 158, 861, 990, 1152, 1003, 1153, 1084, 1154, 1155, 1084, 1156, 1154, 867, 765, 767, 1012, 821, 1073,
106, 105, 1089, 412, 422, 572, 635, 364, 1126, 734, 736, 1083, 858, 476, 478, 1084, 1157, 734, 1084, 734, 1085, 1016, 72, 526, 86, 796, 176, 359, 712, 103, 1158, 1159, 54, 843, 793, 1086, 616, 615, 766, 1127, 479, 983, 459, 811, 460, 596, 628, 627,
1082, 661, 592, 583, 1160, 481, 384, 372, 385, 557, 710, 738, 785, 1119, 1120, 1076, 448, 886, 272, 763, 531, 1089, 1017, 1161, 507, 913, 508, 439, 437, 694, 332, 1149, 204, 422, 424, 1162, 906, 161, 450, 708, 178, 1163, 865, 1037, 866, 357, 356, 257,
357, 257, 1164, 177, 629, 87, 244, 243, 703, 1069, 940, 723, 794, 1165, 1166, 591, 506, 1082, 588, 1034, 884, 775, 774, 151, 57, 56, 1165, 183, 151, 245, 466, 465, 389, 781, 701, 1081, 45, 878, 709, 880, 814, 813, 625, 1145, 626, 1110, 852, 851,
33, 887, 498, 906, 452, 718, 1047, 1167, 1046, 744, 743, 211, 467, 469, 1107, 1098, 673, 674, 211, 8, 783, 416, 989, 1168, 972, 418, 949, 510, 1169, 1153, 465, 390, 389, 366, 554, 364, 1148, 1170, 1171, 83, 248, 84, 816, 1172, 930, 228, 451, 450,
1173, 1083, 736, 1174, 1123, 1122, 1091, 272, 531, 394, 426, 718, 590, 1043, 1119, 910, 42, 350, 161, 879, 1027, 714, 114, 113, 757, 12, 656, 1100, 49, 1175, 982, 51, 959, 538, 1101, 539, 1176, 1114, 157, 1177, 146, 1143, 635, 1126, 909, 4, 1021, 5,
1178, 864, 575, 835, 645, 836, 22, 21, 1066, 1179, 18, 971, 1180, 1166, 18, 898, 36, 391, 346, 105, 104, 185, 145, 1065, 934, 964, 296, 1181, 841, 1182, 1183, 1083, 1173, 962, 13, 1019, 872, 966, 873, 809, 406, 636, 1184, 982, 395, 144, 290, 266,
227, 976, 1132, 869, 26, 576, 484, 871, 873, 1184, 1185, 1175, 932, 947, 753, 1056, 229, 592, 976, 1186, 192, 702, 495, 633, 421, 1187, 1188, 1119, 1043, 1092, 884, 138, 137, 933, 608, 1189, 1190, 77, 76, 958, 957, 315, 658, 1009, 208, 762, 223, 222,
883, 855, 749, 1191, 610, 612, 961, 960, 530, 1120, 1092, 721, 1059, 1192, 1024, 1059, 965, 1192, 1193, 1113, 839, 1103, 729, 812, 934, 936, 954, 686, 685, 1159, 1017, 1102, 215, 694, 973, 695, 1163, 178, 995, 1017, 215, 676, 954, 232, 1194, 489, 133, 132,
1195, 1148, 520, 1055, 1045, 1090, 853, 877, 607, 584, 193, 195, 877, 1196, 607, 550, 1068, 1067, 877, 876, 1196, 938, 1069, 953, 604, 122, 449, 708, 683, 113, 139, 138, 376, 207, 166, 584, 743, 6, 211, 1058, 1197, 84, 1096, 707, 998, 1198, 1199, 1160,
1105, 1007, 862, 520, 891, 1195, 1010, 1052, 776, 920, 407, 382, 399, 59, 58, 1148, 1195, 751, 1200, 977, 298, 988, 1201, 444, 897, 1011, 218, 666, 99, 678, 1075, 762, 926, 1108, 521, 1004, 973, 911, 757, 1011, 897, 370, 371, 373, 1066, 979, 978, 1076,
1202, 1203, 485, 1189, 608, 1204, 888, 553, 552, 950, 417, 1205, 768, 1206, 769, 67, 69, 709, 18, 20, 1180, 994, 662, 720, 281, 35, 282, 139, 13, 587, 171, 127, 126, 836, 1044, 837, 1177, 147, 146, 870, 810, 1141, 860, 1186, 976, 403, 722, 247,
1024, 1192, 955, 1070, 872, 670, 154, 153, 1153, 858, 78, 1207, 800, 504, 1208, 762, 777, 926, 431, 1181, 429, 1144, 780, 410, 937, 731, 784, 262, 64, 1139, 1198, 1174, 1209, 688, 691, 165, 731, 937, 729, 556, 555, 255, 510, 509, 831, 972, 1190, 76,
398, 655, 1210, 920, 382, 825, 715, 227, 1044, 724, 631, 967, 322, 321, 1045, 190, 1186, 1097, 904, 716, 717, 407, 920, 397, 153, 1211, 1153, 1212, 5, 596, 131, 820, 132, 945, 921, 825, 1141, 308, 944, 315, 314, 1213, 51, 982, 1184, 211, 386, 744,
270, 396, 186, 174, 703, 175, 598, 1212, 596, 202, 269, 203, 86, 88, 549, 775, 182, 776, 1007, 1214, 327, 1191, 353, 1215, 629, 628, 1001, 515, 1111, 367, 522, 464, 463, 846, 1216, 847, 453, 1217, 928, 73, 395, 823, 430, 429, 929, 561, 1218, 562,
335, 40, 471, 1219, 379, 1220, 799, 930, 800, 1221, 779, 517, 532, 1091, 531, 194, 491, 185, 548, 547, 1112, 422, 1218, 224, 338, 1193, 1222, 574, 1223, 487, 828, 313, 957, 590, 1042, 1043, 173, 439, 287, 802, 547, 1072, 643, 297, 9, 706, 959, 912,
49, 51, 1184, 693, 865, 24, 872, 871, 670, 883, 1224, 768, 883, 768, 770, 642, 423, 640, 247, 907, 245, 13, 587, 14, 1225, 685, 1226, 1105, 697, 1227, 689, 651, 1032, 461, 729, 1115, 1177, 1143, 36, 449, 730, 729, 1021, 598, 311, 168, 385, 135,
274, 442, 275, 603, 229, 602, 753, 947, 265, 882, 749, 751, 548, 747, 214, 1169, 1152, 1153, 658, 660, 948, 1183, 1173, 1176, 1228, 52, 54, 615, 614, 657, 440, 439, 173, 1138, 625, 624, 1121, 840, 368, 830, 983, 479, 564, 566, 275, 876, 916, 917,
1026, 241, 772, 1042, 286, 285, 719, 388, 879, 844, 1136, 92, 316, 205, 195, 323, 748, 50, 190, 901, 191, 234, 236, 684, 884, 1034, 138, 425, 426, 577, 165, 1229, 585, 421, 137, 1187, 666, 665, 1230, 1231, 1232, 1224, 1067, 1001, 1024, 700, 699, 253,
146, 168, 356, 78, 340, 76, 821, 727, 726, 1084, 1233, 925, 863, 1007, 1006, 871, 484, 485, 1234, 1235, 318, 665, 664, 329, 746, 773, 660, 1135, 266, 265, 476, 1207, 243, 248, 369, 1062, 746, 260, 772, 1026, 772, 1071, 393, 1236, 988, 634, 1011, 364,
26, 693, 24, 61, 815, 851, 1025, 1011, 634, 1195, 1232, 1231, 93, 1136, 393, 982, 706, 705, 467, 1107, 1041, 1064, 278, 277, 349, 465, 347, 230, 541, 497, 845, 1233, 1237, 381, 524, 470, 824, 828, 916, 564, 275, 442, 922, 742, 741, 110, 529, 111,
104, 1049, 1048, 326, 328, 1150, 685, 32, 1008, 209, 769, 618, 100, 715, 1044, 133, 1142, 553, 131, 133, 553, 1238, 1226, 1138, 1138, 301, 1238, 864, 630, 402, 1073, 547, 536, 806, 276, 343, 1036, 692, 869, 855, 883, 1028, 9, 472, 643, 1229, 11, 10,
464, 167, 565, 563, 746, 660, 241, 119, 1029, 130, 36, 35, 301, 1138, 302, 1215, 779, 1221, 769, 1206, 813, 828, 957, 956, 436, 477, 638, 461, 460, 812, 415, 423, 412, 413, 572, 571, 828, 956, 917, 377, 379, 974, 388, 833, 366, 700, 0, 2,
733, 732, 805, 1213, 314, 1096, 210, 209, 620, 818, 470, 787, 202, 786, 992, 310, 870, 981, 1215, 31, 1133, 127, 171, 1190, 542, 663, 761, 1025, 977, 890, 1187, 137, 419, 197, 1239, 760, 814, 619, 618, 860, 1097, 1186, 689, 969, 690, 193, 584, 585,
193, 585, 1229, 714, 113, 581, 558, 107, 109, 682, 639, 244, 620, 209, 618, 756, 755, 144, 826, 351, 831, 394, 844, 426, 95, 97, 928, 479, 480, 830, 626, 1121, 1111, 900, 470, 354, 897, 235, 370, 1007, 1105, 1227, 232, 231, 1194, 502, 1240, 130,
592, 603, 593, 1122, 240, 1161, 1040, 420, 468, 644, 46, 645, 572, 226, 570, 424, 310, 312, 1118, 1014, 1013, 225, 1218, 561, 759, 761, 994, 1099, 914, 913, 438, 588, 962, 374, 137, 139, 1018, 766, 14, 353, 31, 1215, 1241, 936, 993, 403, 258, 427,
1242, 507, 1211, 1213, 1096, 1015, 414, 413, 597, 902, 1110, 799, 244, 639, 242, 791, 1131, 1130, 1209, 1161, 1017, 1209, 1017, 483, 1094, 999, 125, 197, 196, 1217, 2, 311, 1243, 804, 219, 977, 1070, 725, 872, 1223, 574, 583, 636, 376, 138, 1147, 949, 951,
986, 795, 1166, 1147, 144, 755, 123, 593, 124, 816, 1060, 1172, 824, 916, 997, 1108, 1152, 1116, 902, 750, 852, 247, 1244, 403, 336, 1222, 1245, 269, 331, 918, 87, 629, 88, 277, 279, 169, 468, 126, 128, 443, 100, 668, 1156, 1084, 1083, 489, 1246, 133,
650, 788, 790, 877, 853, 68, 537, 319, 318, 941, 38, 578, 576, 26, 425, 487, 575, 574, 1182, 429, 1181, 83, 249, 248, 776, 1128, 555, 1036, 94, 829, 62, 118, 63, 461, 1115, 1097, 829, 480, 1247, 1131, 246, 150, 309, 333, 252, 450, 161, 782,
1048, 808, 807, 292, 251, 975, 1041, 489, 132, 572, 224, 226, 1032, 1108, 969, 115, 941, 494, 703, 243, 175, 226, 1030, 756, 616, 766, 765, 955, 1248, 1024, 955, 954, 1194, 49, 324, 50, 671, 89, 1121, 777, 1002, 778, 550, 1067, 551, 1057, 305, 1197,
859, 136, 385, 1160, 567, 1198, 792, 791, 1130, 803, 472, 622, 1194, 1248, 955, 617, 1094, 595, 93, 92, 1136, 231, 233, 56, 1249, 894, 329, 500, 873, 1099, 600, 599, 848, 176, 87, 86, 1242, 1211, 153, 748, 747, 912, 1144, 714, 220, 370, 1027, 365,
1143, 146, 356, 435, 1250, 339, 688, 165, 651, 1177, 36, 1240, 56, 1134, 1165, 735, 734, 838, 790, 527, 1251, 517, 278, 1064, 613, 1150, 1252, 629, 177, 627, 142, 1113, 140, 416, 76, 340, 1253, 1191, 612, 1209, 483, 482, 1092, 943, 942, 302, 515, 386,
1219, 1049, 1254, 398, 58, 655, 569, 568, 677, 612, 1255, 1256, 652, 653, 992, 536, 797, 1073, 395, 982, 823, 229, 450, 602, 513, 185, 491, 735, 1176, 1173, 123, 591, 593, 141, 1193, 338, 580, 492, 578, 170, 1064, 169, 261, 746, 563, 263, 1096, 1079,
636, 1034, 1019, 621, 623, 334, 847, 1137, 845, 821, 1072, 1073, 1038, 115, 494, 215, 488, 676, 1012, 1073, 1179, 1248, 573, 551, 263, 705, 707, 745, 1064, 170, 903, 1235, 750, 325, 324, 538, 996, 390, 963, 345, 344, 807, 812, 729, 461, 233, 970, 1134,
1188, 1187, 419, 27, 30, 731, 381, 380, 281, 667, 59, 399, 250, 1257, 369, 1148, 751, 1170, 416, 1168, 417, 689, 688, 651, 13, 375, 587, 628, 282, 600, 1162, 259, 1140, 843, 791, 793, 29, 1225, 1226, 29, 1226, 1238, 568, 1160, 583, 666, 441, 99,
336, 1245, 485, 914, 613, 1252, 127, 756, 128, 745, 517, 1064, 421, 1188, 419, 772, 260, 1071, 1252, 1150, 1125, 145, 288, 1065, 612, 558, 1253, 801, 609, 802, 452, 906, 450, 1173, 736, 735, 1022, 1258, 1023, 660, 773, 1087, 303, 784, 731, 1208, 1179, 1073,
799, 798, 902, 779, 278, 517, 15, 834, 654, 790, 1251, 1023, 825, 921, 920, 1101, 538, 324, 437, 438, 911, 135, 385, 136, 1246, 1142, 133, 446, 865, 867, 30, 29, 301, 765, 867, 711, 1081, 137, 781, 498, 779, 1133, 985, 919, 921, 301, 731, 30,
960, 1201, 530, 943, 1092, 234, 230, 987, 1236, 1021, 981, 5, 947, 1135, 265, 324, 49, 1100, 560, 559, 631, 383, 118, 384, 1259, 1098, 674, 29, 1238, 301, 988, 444, 393, 316, 819, 317, 1254, 1049, 104, 53, 1123, 1174, 675, 487, 1223, 1227, 697, 486,
571, 700, 1243, 311, 598, 1243, 1061, 952, 430, 561, 932, 1053, 256, 1244, 1164, 612, 107, 558, 587, 543, 14, 1228, 1159, 685, 611, 1220, 1255, 209, 1009, 769, 211, 783, 386, 809, 12, 1020, 649, 632, 1106, 1260, 1250, 435, 956, 1078, 917, 891, 813, 1206,
21, 371, 1066, 78, 280, 1207, 871, 485, 1203, 1095, 785, 946, 360, 359, 1097, 589, 1022, 286, 273, 272, 1016, 954, 1241, 232, 639, 638, 477, 2, 1, 259, 859, 385, 372, 1261, 640, 944, 701, 405, 171, 313, 874, 1262, 255, 555, 995, 1103, 604, 449,
19, 503, 129, 495, 298, 633, 657, 733, 343, 740, 433, 808, 464, 1032, 651, 648, 402, 649, 366, 365, 387, 679, 892, 686, 635, 264, 702, 1219, 974, 379, 771, 239, 238, 608, 548, 1112, 99, 441, 668, 1137, 546, 680, 122, 362, 447, 141, 338, 48,
1141, 944, 945, 643, 1200, 298, 300, 690, 969, 853, 349, 348, 791, 357, 1131, 1040, 884, 421, 453, 928, 97, 978, 52, 1228, 512, 1075, 926, 1013, 998, 1263, 644, 861, 47, 1180, 986, 1166, 599, 965, 1059, 681, 1245, 925, 961, 529, 110, 759, 197, 760,
582, 583, 574, 582, 574, 533, 192, 1186, 190, 268, 249, 83, 404, 437, 405, 677, 905, 162, 737, 1251, 70, 836, 98, 1044, 606, 122, 604, 390, 854, 963, 70, 72, 124, 10, 490, 193, 10, 193, 1229, 1066, 1071, 333, 446, 867, 1018, 201, 720, 662,
960, 771, 444, 1264, 1201, 988, 1036, 829, 121, 679, 493, 492, 1194, 231, 573, 557, 1031, 1010, 332, 910, 350, 1019, 13, 809, 294, 726, 295, 1230, 522, 463, 523, 522, 1230, 438, 1034, 588, 826, 352, 351, 517, 516, 1221, 938, 940, 1069, 423, 415, 921,
271, 186, 188, 245, 907, 183, 989, 340, 339, 1087, 948, 660, 257, 356, 168, 1146, 1147, 682, 1135, 21, 23, 77, 1190, 171, 817, 409, 425, 562, 261, 563, 955, 1192, 965, 955, 965, 934, 1258, 1022, 589, 1056, 592, 661, 737, 593, 603, 907, 247, 722,
691, 300, 11, 1249, 1003, 1005, 1249, 1005, 894, 314, 1262, 1080, 160, 719, 879, 453, 496, 760, 838, 1193, 839, 259, 1, 260, 15, 655, 1265, 15, 1265, 16, 466, 842, 709, 1034, 404, 1020, 391, 390, 898, 261, 1140, 259, 0, 700, 253, 46, 644, 47,
1094, 125, 320, 200, 199, 740, 1007, 1227, 1214, 714, 410, 66, 241, 893, 118, 728, 727, 993, 1261, 306, 641, 1210, 162, 905, 1170, 751, 750, 164, 677, 162, 593, 70, 124, 111, 529, 1124, 1046, 1220, 611, 90, 671, 1266, 915, 914, 1125, 43, 1250, 1260,
367, 369, 516, 911, 973, 437, 171, 440, 77, 943, 234, 1033, 622, 472, 856, 545, 1202, 681, 687, 686, 892, 195, 207, 584, 768, 1232, 1206, 1063, 1215, 1221, 306, 1261, 307, 992, 653, 926, 792, 1267, 1168, 5, 899, 3, 176, 921, 177, 1142, 265, 264,
1170, 750, 1235, 405, 701, 406, 418, 417, 950, 1093, 1054, 1055, 266, 292, 144, 375, 374, 587, 605, 895, 984, 605, 984, 606, 554, 1126, 364, 79, 650, 1258, 79, 1258, 672, 578, 492, 941, 1240, 36, 130, 1240, 1172, 1060, 462, 565, 564, 1175, 1185, 75,
573, 1248, 1194, 1168, 1267, 417, 1030, 1053, 128, 19, 129, 380, 365, 364, 1011, 147, 1177, 1060, 1230, 463, 666, 969, 1108, 299, 945, 825, 1141, 1086, 1250, 43, 633, 635, 702, 1236, 393, 392, 927, 331, 202, 1114, 1176, 839, 899, 598, 4, 972, 754, 1190,
452, 451, 1236, 1165, 1088, 18, 137, 1081, 419, 541, 661, 663, 309, 251, 291, 92, 577, 426, 31, 33, 498, 674, 740, 1050, 1062, 841, 1181, 1062, 1181, 431, 12, 14, 656, 59, 1035, 60, 760, 542, 761, 631, 849, 723, 1261, 944, 307, 961, 530, 529,
1165, 1134, 1088, 863, 560, 631, 134, 881, 1095, 698, 1266, 107, 698, 107, 1256, 997, 738, 710, 430, 1058, 1061, 1211, 507, 510, 625, 1226, 1008, 614, 120, 732, 396, 623, 622, 1201, 960, 444, 1156, 1083, 1183, 567, 569, 355, 56, 573, 231, 448, 447, 886,
15, 17, 834, 317, 342, 206, 238, 240, 1122, 1095, 427, 134, 134, 427, 258, 1062, 368, 840, 978, 1228, 1225, 293, 802, 294, 1209, 1174, 1122, 5, 981, 870, 457, 669, 544, 404, 809, 1020, 506, 434, 433, 1149, 1150, 328, 614, 616, 711, 145, 704, 288,
1218, 1140, 562, 981, 1021, 311, 1178, 1104, 864, 262, 1139, 222, 1182, 111, 1124, 60, 847, 655, 1102, 216, 215, 925, 1233, 845, 629, 1068, 88, 1037, 868, 866, 68, 67, 877, 935, 728, 936, 393, 1136, 394, 252, 1, 0, 796, 86, 55, 1105, 862, 1104,
718, 408, 719, 722, 942, 907, 709, 842, 45, 1227, 992, 1214, 514, 491, 490, 287, 439, 968, 473, 304, 889, 473, 889, 474, 613, 326, 1150, 1178, 575, 487, 1065, 696, 316, 139, 376, 13, 837, 901, 102, 347, 466, 69, 549, 551, 55, 559, 1099, 873,
1063, 1047, 610, 637, 436, 638, 631, 724, 849, 25, 131, 817, 1068, 629, 1001, 567, 355, 53, 387, 365, 1027, 1074, 708, 1163, 811, 1103, 812, 1006, 560, 863, 721, 946, 1120, 809, 636, 1019, 1180, 919, 986, 990, 712, 158, 661, 506, 662, 680, 546, 545,
804, 621, 219, 348, 69, 68, 166, 237, 167, 1117, 1152, 1169, 671, 1121, 626, 1142, 909, 553, 330, 46, 48, 832, 299, 1117, 985, 986, 919, 1063, 1221, 1257, 926, 653, 512, 349, 390, 465, 342, 657, 343, 524, 354, 470, 330, 1268, 46, 771, 52, 1051,
791, 842, 358, 993, 970, 233, 153, 152, 501, 1207, 476, 858, 1054, 216, 1102, 1226, 685, 1008, 7, 1269, 360, 1038, 834, 115, 345, 617, 346, 900, 354, 283, 760, 1239, 453, 352, 1125, 1149, 767, 1018, 867, 502, 1172, 1240, 1177, 1240, 1060, 707, 747, 998,
382, 407, 380, 926, 777, 927, 189, 528, 525, 1082, 506, 661, 486, 652, 1227, 1217, 1057, 928, 1033, 708, 1074, 55, 86, 549, 5, 1212, 899, 470, 900, 4, 53, 1174, 567, 227, 1132, 192, 35, 996, 282, 1145, 671, 626, 57, 1165, 794, 599, 991, 964,
786, 327, 1214, 400, 742, 922, 974, 961, 110, 27, 1076, 28, 722, 721, 942, 598, 899, 1212, 811, 605, 1103, 217, 1093, 511, 992, 1227, 652, 952, 1062, 431, 1000, 994, 889, 502, 930, 1172, 753, 1053, 932, 229, 228, 450, 159, 719, 160, 843, 842, 791,
91, 111, 1182, 1030, 128, 756, 854, 991, 601, 1051, 52, 978, 1267, 792, 1130, 900, 899, 4, 565, 167, 237, 1236, 392, 452, 596, 899, 283, 217, 652, 215, 1162, 1140, 422, 758, 656, 317, 1266, 671, 107, 724, 967, 725, 257, 256, 1164, 368, 1062, 369,
1198, 1209, 482, 887, 499, 498, 878, 44, 739, 1079, 65, 64, 1270, 789, 788, 240, 1089, 1161, 949, 418, 950, 787, 354, 3, 749, 855, 852, 1199, 481, 1160, 470, 354, 787, 369, 1257, 516, 1147, 951, 682, 1096, 314, 1079, 785, 589, 1119, 1040, 468, 467,
1089, 105, 1102, 3, 596, 5, 642, 641, 810, 605, 811, 895, 363, 479, 362, 641, 308, 810, 960, 239, 771, 1205, 150, 149, 560, 1006, 326, 1081, 420, 419, 1104, 862, 864, 720, 889, 994, 429, 1124, 929, 839, 1113, 1114, 198, 759, 1000, 97, 96, 453,
1202, 545, 1203, 919, 1180, 20, 196, 305, 1057, 200, 475, 474, 853, 607, 801, 429, 1182, 1124, 621, 334, 219, 1237, 1233, 1271, 1242, 153, 501, 587, 586, 543, 686, 1158, 355, 686, 355, 569, 1272, 1273, 1155, 1274, 1272, 1154, 1275, 1274, 1276, 1277, 1278, 1279,
1280, 1281, 1282, 1283, 1277, 1284, 1273, 1280, 1155, 1278, 1285, 1286, 1281, 1287, 1288, 1155, 1280, 1289, 1288, 1283, 1290, 1287, 1283, 1288, 1288, 1282, 1281, 1279, 1284, 1277, 1284, 1290, 1283, 1282, 1289, 1280, 1286, 1279, 1278, 1155, 1154, 1272, 1154, 1276, 1274, 1183, 1275, 1276,
857, 361, 1272, 37, 1283, 1287, 156, 155, 1275, 1276, 1154, 1156, 16, 1279, 764, 1279, 16, 1265, 764, 1286, 116, 1274, 155, 857, 1281, 1280, 7, 1283, 37, 39, 117, 116, 1278, 1291, 1216, 1290, 1284, 1265, 1291, 1216, 846, 1288, 361, 1269, 1273, 361, 1273, 1272,
39, 117, 1278, 1269, 7, 1280, 846, 1237, 1289, 1155, 1289, 1237, 7, 937, 8, 195, 205, 207, 324, 323, 50, 38, 941, 39, 1291, 655, 847, 870, 825, 818, 226, 756, 975, 639, 477, 476, 1076, 978, 28, 322, 1045, 1055, 415, 177, 921, 493, 677, 164,
310, 424, 642, 1093, 1055, 1090, 792, 1168, 989, 1086, 793, 989, 1217, 453, 1239, 1217, 1239, 197, 566, 206, 276, 1097, 7, 360, 747, 707, 912, 1078, 1189, 1204, 239, 961, 106, 397, 20, 19, 101, 835, 837, 923, 925, 1245, 462, 564, 442, 331, 927, 777,
887, 687, 499, 328, 204, 1149, 838, 1292, 1193, 413, 571, 1243, 1086, 989, 1250, 891, 1206, 1232, 1109, 184, 1260, 517, 744, 515, 850, 119, 62, 841, 1062, 840, 1029, 948, 1087, 874, 828, 180, 14, 615, 656, 189, 1293, 528, 392, 394, 718, 714, 1144, 410,
267, 85, 473, 665, 523, 1230, 285, 235, 1042, 803, 804, 1200, 155, 158, 712, 1129, 908, 1163, 1171, 1234, 538, 225, 1053, 1030, 908, 1074, 1163, 1070, 670, 669, 1056, 661, 541, 725, 966, 872, 1006, 327, 326, 315, 957, 313, 318, 325, 1234, 343, 733, 806,
1167, 1047, 249, 544, 546, 457, 64, 411, 1139, 786, 1214, 992, 1146, 244, 704, 284, 1022, 603, 1220, 1050, 1049, 1166, 795, 794, 179, 528, 180, 221, 273, 74, 905, 677, 534, 1263, 1118, 1013, 1152, 1004, 1003, 181, 183, 907, 436, 1010, 435, 468, 420, 172,
893, 241, 1026, 637, 774, 1052, 875, 1210, 905, 749, 852, 750, 1222, 923, 1245, 270, 186, 271, 792, 989, 793, 13, 376, 375, 675, 1017, 676, 128, 752, 468, 187, 396, 856, 1023, 1258, 650, 1220, 379, 1255, 198, 1000, 304, 850, 855, 1028, 874, 1293, 1262,
860, 976, 811, 434, 1094, 617, 1291, 1265, 655, 851, 850, 62, 531, 763, 1075, 754, 127, 1190, 234, 1042, 235, 198, 305, 196, 273, 1016, 526, 540, 81, 80, 1101, 1100, 539, 772, 241, 773, 386, 515, 744, 594, 1055, 105, 32, 685, 33, 652, 486, 215,
619, 859, 371, 641, 640, 1261, 1088, 970, 971, 247, 246, 1244, 149, 951, 1205, 516, 1257, 1221, 126, 468, 172, 740, 674, 475, 1075, 512, 511, 417, 1267, 1205, 672, 1258, 589, 194, 185, 195, 633, 977, 1025, 1091, 1045, 272, 191, 901, 837, 262, 222, 221,
1225, 29, 28, 944, 308, 307, 1255, 612, 611, 1016, 321, 125, 649, 402, 630, 1210, 655, 654, 961, 974, 106, 1196, 1204, 608, 1047, 1063, 249, 774, 149, 151, 377, 698, 378, 265, 1246, 753, 31, 353, 32, 948, 883, 770, 1046, 1167, 268, 282, 596, 283,
998, 1013, 1015, 1095, 519, 518, 987, 988, 1236, 694, 968, 439, 350, 832, 351, 725, 1069, 723, 1016, 124, 72, 18, 1179, 1151, 18, 1151, 19, 1028, 119, 850, 726, 728, 295, 268, 1098, 1259, 959, 50, 748, 263, 1079, 64, 521, 1032, 464, 425, 25, 817,
1118, 1189, 1078, 411, 410, 780, 700, 2, 1243, 506, 591, 999, 695, 438, 12, 874, 528, 1293, 1041, 132, 1039, 340, 858, 478, 1007, 863, 862, 773, 241, 1029, 1058, 1057, 1197, 181, 908, 1129, 325, 538, 1234, 390, 349, 854, 352, 827, 915, 933, 1189, 1263,
165, 11, 1229, 597, 413, 1243, 1208, 1151, 1179, 589, 590, 1119, 11, 165, 691, 243, 1207, 175, 645, 678, 836, 743, 38, 37, 24, 820, 25, 895, 715, 984, 274, 443, 442, 503, 1151, 504, 696, 1065, 968, 1210, 654, 834, 1027, 879, 387, 1031, 1109, 1260,
88, 550, 549, 82, 1270, 788, 523, 1005, 1004, 936, 1241, 954, 637, 682, 774, 107, 612, 1256, 289, 143, 513, 422, 224, 572, 384, 893, 373, 423, 642, 424, 1014, 1213, 1015, 697, 1104, 1178, 588, 1039, 586, 270, 918, 396, 930, 815, 816, 420, 1040, 421,
82, 81, 539, 1014, 315, 1213, 1078, 1204, 876, 214, 747, 212, 217, 216, 1093, 378, 1255, 379, 181, 1129, 182, 102, 1097, 359, 798, 797, 536, 808, 433, 432, 803, 1200, 643, 342, 317, 656, 27, 731, 730, 433, 740, 199, 579, 169, 279, 80, 518, 520,
290, 144, 143, 1167, 249, 268, 567, 1174, 1198, 314, 313, 1262, 456, 953, 457, 27, 730, 448, 634, 364, 635, 214, 213, 548, 173, 175, 1207, 1118, 1263, 1189, 1002, 762, 1139, 221, 223, 273, 566, 207, 206, 841, 91, 1182, 254, 178, 180, 681, 925, 680,
662, 506, 505, 1218, 422, 1140, 1232, 768, 1224, 685, 1225, 1228, 1063, 610, 1215, 561, 1053, 225, 751, 1231, 882, 1256, 1255, 378, 1080, 65, 1079, 236, 235, 896, 895, 811, 976, 383, 168, 148, 946, 428, 1095, 385, 168, 383, 979, 1127, 980, 53, 52, 1123,
1058, 248, 1061, 1111, 515, 302, 1147, 755, 949, 571, 570, 700, 1256, 378, 698, 116, 1285, 1278, 1216, 1288, 1290, 1280, 1273, 1269, 155, 1274, 1275, 764, 1279, 1286, 760, 496, 542, 1248, 1067, 1024, 455, 987, 497, 647, 649, 939, 246, 1131, 1244, 835, 101, 645,
576, 92, 94, 1033, 234, 684, 497, 987, 230, 570, 975, 699, 596, 282, 628, 110, 698, 377, 1142, 1246, 265, 572, 413, 412, 658, 770, 1009, 776, 182, 1128, 142, 157, 1114, 959, 51, 50, 559, 613, 914, 65, 1080, 1293, 28, 978, 1225, 896, 235, 897,
1025, 634, 633, 1179, 971, 1012, 924, 923, 1292, 1024, 848, 1059, 974, 1254, 104, 719, 408, 388, 237, 566, 565, 1242, 501, 507, 451, 230, 1236, 189, 112, 114, 276, 275, 566, 701, 171, 1081, 454, 96, 529, 1253, 558, 353, 1026, 1071, 373, 1117, 1169, 831,
1077, 922, 904, 567, 1160, 568, 183, 775, 151, 891, 1232, 1195, 806, 443, 274, 220, 714, 581, 398, 1210, 399, 37, 6, 743, 94, 1036, 869, 84, 1197, 85, 664, 678, 1268, 156, 1176, 157, 557, 738, 1109, 517, 745, 744, 1075, 511, 531, 1200, 804, 977,
103, 713, 101, 67, 709, 878, 552, 554, 366, 505, 433, 199, 610, 1191, 1215, 831, 509, 826, 503, 130, 129, 909, 1126, 553, 705, 262, 823, 924, 838, 734, 1292, 923, 1222, 869, 692, 26, 480, 363, 1247, 187, 471, 40, 117, 39, 941, 852, 1110, 902,
533, 574, 1077, 538, 540, 1171, 648, 742, 402, 363, 121, 1247, 1270, 82, 539, 734, 1083, 1085, 780, 778, 1002, 152, 154, 330, 489, 468, 1246, 1220, 1046, 1259, 453, 455, 496, 529, 96, 1124, 254, 995, 178, 1031, 1260, 435, 1271, 1233, 1084, 1108, 1116, 299,
136, 881, 134, 42, 832, 350, 1246, 468, 753, 1202, 485, 1245, 381, 825, 382, 85, 267, 83, 212, 748, 323, 878, 739, 997, 526, 74, 273, 687, 887, 685, 1139, 411, 1002, 252, 333, 1, 620, 21, 1135, 713, 712, 990, 530, 1201, 1264, 1210, 875, 399,
690, 300, 691, 630, 863, 631, 995, 1129, 1163, 1050, 1220, 1259, 44, 878, 45, 674, 1050, 1259, 659, 947, 932, 874, 313, 828, 1046, 611, 610, 1215, 1133, 779, 61, 851, 62, 672, 1095, 518, 1077, 534, 533, 870, 1141, 825, 436, 341, 477, 1183, 1176, 156,
141, 48, 47, 1175, 789, 1100, 1175, 527, 789, 1038, 493, 164, 588, 587, 13, 1248, 551, 1067, 650, 790, 1023, 296, 295, 935, 233, 232, 1241, 98, 100, 1044, 44, 184, 739, 443, 805, 715, 1010, 436, 1052, 135, 134, 258, 1012, 822, 821, 294, 1072, 726,
1171, 540, 1148, 330, 48, 152, 197, 759, 198, 846, 1289, 1282, 37, 1287, 6, 857, 1272, 1274, 1276, 1156, 1183, 1281, 7, 6, 1275, 1183, 156, 1271, 1155, 1237, 1284, 1291, 1290, 780, 918, 778, 935, 295, 728, 221, 823, 262, 1042, 590, 286, 1022, 284, 286,
789, 1270, 1100, 459, 860, 811, 631, 559, 967, 1263, 998, 933, 332, 203, 271, 669, 953, 1070, 85, 1197, 305, 224, 1218, 225, 871, 1203, 670, 356, 358, 391, 75, 1185, 395, 929, 928, 1057, 1231, 751, 1195, 119, 1028, 1029, 541, 663, 542, 673, 473, 475,
481, 483, 675, 178, 708, 525, 883, 1231, 1224, 1267, 1130, 150, 1267, 150, 1205, 207, 566, 237, 93, 393, 445, 782, 285, 284, 727, 822, 993, 1054, 1093, 216, 619, 21, 620, 259, 1162, 424, 930, 502, 504, 701, 781, 636, 1102, 105, 1054, 510, 1153, 1211,
1247, 121, 829, 251, 253, 975, 1039, 132, 586, 474, 720, 200, 741, 648, 647, 710, 824, 997, 481, 1199, 482, 882, 1231, 883, 972, 949, 755, 953, 939, 938, 332, 350, 1149, 191, 1044, 227, 147, 1060, 118, 1076, 27, 448, 1045, 321, 1016, 1127, 979, 885,
716, 904, 922, 918, 331, 778, 268, 267, 673, 1107, 489, 1041, 547, 802, 609, 547, 609, 1112, 1100, 1270, 539, 686, 1159, 1158, 458, 1035, 59, 822, 970, 993, 808, 1048, 1050, 426, 408, 718, 515, 367, 516, 876, 1204, 1196, 838, 924, 1292, 672, 785, 1095,
443, 806, 805, 104, 1048, 344, 476, 242, 639, 504, 1151, 1208, 758, 819, 696, 1292, 1222, 1193, 614, 733, 657, 809, 13, 12, 1235, 537, 318, 552, 817, 888, 559, 914, 1099, 1065, 288, 287, 297, 514, 9, 588, 13, 962, 527, 1175, 75, 1217, 196, 1057,
723, 940, 1106, 1249, 1153, 1003, 423, 422, 412, 24, 865, 446, 352, 1149, 350, 574, 400, 922, 169, 579, 38, 1155, 1271, 1084, 476, 243, 242, 5, 870, 787, 112, 189, 525, 1176, 735, 839, 726, 1072, 821, 532, 1090, 1091, 832, 1117, 831, 1096, 998, 1015,
1131, 1164, 1244, 39, 1277, 1283, 1279, 1265, 1284, 740, 808, 1050, 1049, 1219, 1220, 1078, 956, 1118, 495, 702, 290, 1193, 140, 1113, 1260, 184, 43, 297, 289, 514, 948, 1028, 883, 1293, 1080, 1262, 721, 1092, 942, 640, 423, 945, 951, 950, 1205, 188, 910, 332,
90, 1266, 698, 1235, 1234, 1171, 1235, 1171, 1170, 189, 114, 66, 845, 680, 925, 71, 70, 1251, 71, 1251, 527, 23, 292, 266, 978, 980, 1051, 360, 1269, 361, 790, 789, 527, 163, 1210, 834, 380, 129, 35, 543, 446, 1018, 974, 1219, 1254, 448, 730, 449,
166, 165, 585, 815, 799, 1110, 597, 1243, 598, 600, 963, 601, 583, 481, 675, 630, 632, 649, 671, 1145, 108, 1226, 625, 1138, 276, 206, 342, 765, 711, 616, 1008, 108, 1145, 1259, 1046, 268, 845, 1237, 846, 577, 576, 425, 892, 499, 687, 713, 990, 646,
1268, 678, 645, 537, 798, 536, 158, 157, 142, 1157, 925, 924, 937, 784, 783, 372, 384, 373, 1073, 797, 1208, 484, 873, 500, 1223, 583, 675, 1056, 230, 229, 903, 537, 1235, 995, 555, 1128, 457, 953, 669, 536, 213, 319, 670, 1203, 545, 997, 739, 738,
290, 264, 266, 1023, 1251, 737, 857, 155, 712, 45, 843, 43, 1127, 885, 479, 510, 831, 1169, 40, 188, 187, 338, 1222, 336, 1039, 884, 1040, 162, 1210, 163, 523, 1004, 521, 797, 800, 1208, 173, 1207, 280, 854, 801, 293, 1161, 1209, 1122, 1055, 594, 322,
766, 615, 14, 425, 26, 25, 1094, 320, 595, 1249, 329, 154, 74, 526, 75, 154, 1153, 1249, 908, 943, 1074, 737, 603, 1022, 1116, 1152, 1117, 914, 1252, 1125, 967, 966, 725, 152, 337, 501, 996, 963, 282, 6, 1287, 1281, 1286, 1285, 116, 39, 1278, 1277,
101, 837, 102, 677, 493, 569, 54, 355, 1158, 40, 42, 910, 581, 236, 896, 807, 344, 1048, 939, 1106, 940, 1157, 1084, 925, 428, 427, 1095, 152, 338, 337, 54, 1159, 1228, 16, 116, 17, 623, 780, 1144, 122, 121, 363, 1131, 357, 1164, 323, 325, 318,
1175, 49, 1184, 1120, 946, 785, 414, 177, 415, 187, 856, 472, 1115, 937, 7, 530, 1264, 454, 482, 1199, 1198, 55, 573, 56, 607, 609, 801, 645, 101, 646, 82, 788, 650, 662, 761, 663, 670, 545, 544, 692, 1036, 693, 1244, 256, 403, 316, 696, 819,
649, 1106, 939, 52, 238, 1123, 396, 918, 780, 61, 63, 816, 1146, 704, 144, 982, 959, 706, 330, 664, 1268, 1135, 947, 620, 500, 337, 336, 293, 991, 854, 878, 916, 876, 487, 697, 1178, 1191, 1253, 353, 390, 996, 34, 1027, 370, 285, 1193, 141, 140,
580, 892, 679, 1165, 18, 1166, 1063, 1257, 250, 36, 1143, 391, 934, 296, 935, 1184, 395, 1185, 1245, 681, 1202, 443, 668, 441, 1108, 1004, 1152, 167, 464, 651, 248, 1062, 1061, 1216, 1291, 847, 244, 1146, 682, 802, 1072, 294, 608, 607, 1196, 500, 507, 501,
444, 1051, 445, 467, 1041, 1040, 131, 553, 888, 46, 1268, 645, 1134, 970, 1088, 219, 890, 977, 847, 1035, 546, 233, 1241, 993, 292, 975, 756, 734, 1157, 924, 58, 60, 655, 455, 454, 988, 989, 339, 1250, 1034, 1020, 1019, 251, 292, 291, 1090, 532, 1093,
1264, 988, 454, 846, 1282, 1288, 798, 537, 903, 1129, 1128, 182, 65, 1293, 189, 117, 941, 115, 456, 458, 59, 956, 958, 1118, };
const float triangleNormals[][3] = {
-0.0979, 0.8167, 0.5688, -0.4293, -0.1976, -0.8813, -0.0014, -0.1062, 0.9943, 0.9968, 0.0329, -0.0733, -0.1503, -0.6511, -0.7439, -0.0264, 0.0034, 0.9996, -0.9975, -0.0597, -0.0371, 0.2753, 0.8903, 0.3628, -0.9364, 0.3361, 0.1012, -0.0875, -0.8599, 0.5028, -0.0907, -0.8158, 0.5712, -0.9717, -0.1255, 0.2002, 0.7684, 0.0179, -0.6397, -0.0241, -0.0275, 0.9993, 0.9069, -0.3458, -0.2408, 0.5955, -0.6641, 0.4520,
0.4879, -0.6103, 0.6242, -0.7474, 0.4572, 0.4821, -0.5406, -0.7714, -0.3357, 0.2128, -0.8947, -0.3927, -0.4406, 0.8914, 0.1064, 0.8143, -0.2800, 0.5084, -0.1902, 0.9663, 0.1736, 0.3063, -0.9166, -0.2570, -0.9328, -0.2678, -0.2412, -0.5787, 0.6978, 0.4221, 0.3107, -0.5964, 0.7402, -0.5273, -0.4478, -0.7221, -0.5120, -0.4701, -0.7189, 0.2356, -0.8613, -0.4501, 0.9939, -0.1014, -0.0431, 0.9744, 0.0728, 0.2125,
-0.0697, -0.9966, -0.0442, 0.8687, 0.3938, 0.3005, 0.9387, 0.3444, -0.0163, 0.6231, -0.2172, 0.7514, -0.7510, -0.0374, -0.6592, -0.1527, 0.8937, 0.4218, 0.2681, 0.6889, 0.6734, 0.5240, 0.8423, -0.1262, -0.0203, -0.0083, 0.9998, 0.9661, -0.2526, -0.0525, -0.8391, -0.4693, 0.2753, -0.8861, 0.0941, 0.4538, -0.8674, 0.0802, 0.4911, -0.0856, -0.5413, -0.8365, -0.8850, -0.3470, 0.3106, 0.1977, -0.3164, -0.9278,
-0.3428, 0.8225, 0.4539, 0.9435, -0.0743, 0.3229, 0.9281, -0.0552, 0.3683, 0.6797, -0.0653, 0.7306, 0.6892, -0.5297, 0.4943, -0.7459, 0.3303, -0.5784, 0.8008, 0.5386, 0.2622, 0.0194, -0.0072, 0.9998, 0.0338, 0.0027, 0.9994, -0.5336, -0.4700, 0.7031, -0.7724, 0.1504, 0.6170, 0.1398, 0.6971, 0.7032, 0.8156, -0.4386, -0.3775, -0.5168, -0.7181, 0.4661, -0.5168, -0.6338, 0.5755, 0.9823, -0.1300, -0.1348,
0.6334, -0.1191, -0.7646, 0.7136, 0.6842, 0.1502, 0.9224, -0.2476, -0.2965, 0.8033, -0.4191, 0.4231, 0.9146, -0.0051, 0.4044, 0.6218, 0.6805, -0.3877, 0.1837, 0.9648, 0.1883, 0.9053, -0.4214, -0.0539, 0.7451, 0.4719, -0.4713, 0.8816, -0.3271, 0.3403, -0.5685, -0.3801, 0.7296, 0.1520, 0.9400, 0.3053, 0.9917, -0.0054, 0.1284, -0.8906, -0.0152, -0.4545, 0.1842, -0.5081, 0.8414, -0.5634, -0.0491, 0.8247,
-0.5681, 0.7707, 0.2885, 0.9954, -0.0637, 0.0717, -0.5983, 0.7897, 0.1357, -0.0214, 0.9917, -0.1270, 0.1906, -0.8360, -0.5145, 0.7362, -0.4692, 0.4877, 0.7441, 0.3507, 0.5686, 0.3121, -0.9344, -0.1718, 0.7913, -0.4572, -0.4059, 0.7133, 0.3356, 0.6153, -0.8736, -0.3775, -0.3073, 0.5189, -0.7371, 0.4330, -0.0644, 0.9570, -0.2828, 0.5092, -0.3587, -0.7824, -0.1263, -0.7669, -0.6292, 0.7684, 0.4033, 0.4969,
0.7176, 0.4613, 0.5218, 0.5408, 0.8301, 0.1360, 0.1602, -0.7391, -0.6543, -0.8713, 0.1633, 0.4628, -0.5092, 0.8247, 0.2461, -0.5388, -0.0264, 0.8421, -0.1850, -0.8327, -0.5219, 0.4210, 0.9063, 0.0374, -0.3435, 0.9265, -0.1538, 0.8785, -0.0910, -0.4689, -0.9369, 0.3363, -0.0956, 0.6275, -0.6089, 0.4853, -0.0982, 0.9163, -0.3883, 0.2844, -0.7941, 0.5372, 0.6480, 0.0382, -0.7606, 0.6211, 0.0938, 0.7781,
0.8983, 0.3624, 0.2485, 0.2871, 0.5530, 0.7821, 0.3195, 0.5453, 0.7750, 0.9049, 0.1859, 0.3828, 0.9029, 0.4232, 0.0761, 0.7628, 0.4398, 0.4740, 0.4577, -0.8837, -0.0981, 0.6136, 0.7874, -0.0593, 0.2857, 0.9534, 0.0966, -0.2625, 0.8628, -0.4319, -0.1439, 0.9507, 0.2746, 0.9598, -0.2579, -0.1107, -0.4961, 0.4629, 0.7345, -0.9941, 0.0845, 0.0686, -0.6708, 0.6261, 0.3975, 0.4114, 0.6772, 0.6100,
0.8264, -0.5409, 0.1565, -0.1815, 0.9501, -0.2539, 0.8289, 0.4796, -0.2880, 0.1399, 0.8808, 0.4523, 0.9020, 0.3937, -0.1771, 0.8432, 0.1864, -0.5043, 0.8316, 0.3555, 0.4267, 0.8985, -0.4235, -0.1157, 0.9086, -0.1178, -0.4007, -0.8824, 0.0205, -0.4701, 0.9658, -0.0787, -0.2472, -0.2899, 0.5055, 0.8127, -0.6174, 0.7866, 0.0089, -0.2981, 0.1156, 0.9475, -0.4194, -0.8921, -0.1683, 0.2850, -0.9474, 0.1452,
0.0513, 0.0065, 0.9987, -0.8341, -0.1265, 0.5369, -0.8136, 0.0816, 0.5756, 0.8980, -0.4390, -0.0300, 0.5160, -0.8560, 0.0328, 0.7155, 0.5896, 0.3747, 0.3339, -0.2488, -0.9092, -0.5317, 0.5241, 0.6653, 0.4312, 0.7698, 0.4706, 0.9002, 0.0979, 0.4243, 0.8608, -0.1877, 0.4731, -0.7528, -0.2798, 0.5959, 0.7642, -0.6002, -0.2362, 0.7366, -0.6220, -0.2655, -0.7323, 0.6663, 0.1405, 0.6510, 0.7550, -0.0784,
-0.7429, 0.3440, -0.5743, -0.2281, 0.8742, 0.4286, -0.7527, 0.6567, 0.0472, -0.0602, -0.2647, -0.9624, 0.3184, -0.9441, 0.0858, -0.5775, -0.0537, 0.8146, -0.7449, -0.6033, 0.2849, 0.0140, 0.9836, 0.1799, -0.5143, 0.3633, 0.7768, 0.4256, -0.7486, 0.5084, 0.3513, -0.7829, 0.5135, -0.2776, -0.9512, 0.1348, -0.8475, 0.5088, -0.1510, -0.6556, -0.5472, -0.5203, -0.8411, -0.4309, -0.3270, -0.8420, -0.3876, -0.3753,
0.4916, -0.2184, -0.8430, 0.8943, -0.4347, -0.1061, -0.9688, 0.0961, 0.2286, 0.9728, -0.0913, 0.2128, 0.9627, 0.2682, -0.0346, 0.3854, -0.3318, -0.8610, 0.4993, -0.8357, 0.2289, 0.7446, 0.6301, 0.2204, 0.6028, -0.7612, 0.2392, -0.9836, -0.0959, -0.1527, -0.9664, -0.2424, 0.0856, -0.9694, -0.2286, 0.0893, 0.7841, -0.2803, 0.5537, 0.7731, -0.6114, 0.1690, 0.9053, -0.2389, -0.3511, 0.9210, -0.2408, -0.3061,
-0.1864, 0.5837, 0.7903, -0.0863, 0.9869, -0.1363, 0.1091, -0.7776, -0.6192, 0.4548, 0.8236, 0.3388, 0.7943, -0.3389, 0.5043, -0.7077, -0.6544, 0.2663, -0.3313, -0.8446, -0.4206, 0.9824, 0.1256, 0.1379, -0.2942, -0.7390, 0.6061, 0.9889, 0.1464, -0.0242, -0.3701, -0.8868, -0.2768, -0.9561, -0.2749, 0.1014, 0.8780, 0.4566, 0.1437, -0.8449, 0.4847, 0.2263, -0.7571, 0.3616, 0.5440, 0.7129, -0.0807, -0.6966,
-0.7871, -0.5282, 0.3185, 0.7127, 0.0280, 0.7009, 0.9040, -0.3444, 0.2533, -0.9349, 0.0558, -0.3504, 0.9535, 0.1736, 0.2465, -0.6003, -0.6654, -0.4437, -0.7504, 0.0923, 0.6545, 0.8881, 0.3455, 0.3030, 0.9091, 0.3268, 0.2584, 0.0230, 0.7761, -0.6302, 0.9953, 0.0806, -0.0531, 0.9953, 0.0963, 0.0104, -0.1364, -0.9660, -0.2196, -0.3218, -0.4120, -0.8524, 0.9910, -0.1149, -0.0683, -0.4827, 0.4984, -0.7201,
-0.4068, 0.0942, 0.9086, 0.6435, 0.7561, -0.1194, -0.9128, 0.2757, 0.3013, -0.9148, 0.2511, 0.3164, 0.9457, 0.0940, 0.3113, 0.4016, 0.8973, 0.1833, 0.8671, -0.2752, -0.4153, -0.0620, 0.9950, 0.0782, -0.9295, 0.1718, 0.3265, -0.4275, -0.1248, 0.8954, -0.9016, -0.4228, -0.0911, -0.9107, -0.4019, -0.0951, 0.7199, -0.3464, 0.6015, 0.6936, -0.3575, 0.6254, -0.9370, -0.2321, -0.2610, -0.3127, 0.9212, -0.2313,
-0.0935, 0.3970, 0.9130, 0.2033, 0.0689, -0.9767, -0.6234, -0.4540, 0.6367, 0.7173, 0.6815, 0.1448, -0.8844, 0.4646, -0.0447, -0.0810, 0.9592, 0.2709, -0.3285, -0.9128, -0.2427, 0.9256, 0.3758, -0.0446, -0.9856, -0.1688, -0.0009, 0.8737, -0.4076, -0.2657, 0.5209, -0.8071, -0.2780, -0.9950, 0.0972, 0.0236, -0.6568, -0.5852, -0.4755, -0.6989, -0.5070, 0.5044, -0.7116, -0.4528, 0.5372, 0.9971, 0.0010, -0.0760,
-0.9837, 0.1034, 0.1468, -0.2432, 0.6057, 0.7576, -0.7480, -0.4119, -0.5204, 0.3746, -0.8922, 0.2522, -0.1915, -0.5686, 0.8000, -0.9733, -0.1935, 0.1233, 0.7797, -0.0057, 0.6262, 0.7785, 0.6191, -0.1031, -0.1636, -0.9832, 0.0807, -0.8745, -0.3372, 0.3487, 0.0483, 0.4523, 0.8906, -0.8671, -0.1165, -0.4844, -0.0075, 0.8874, 0.4609, -0.7160, -0.5754, -0.3954, -0.9902, 0.1398, -0.0056, -0.0518, 0.9660, -0.2535,
-0.0162, -0.0014, 0.9999, 0.7716, 0.5776, 0.2665, 0.7807, 0.4875, 0.3910, 0.9538, 0.0371, 0.2981, -0.0066, 0.9175, -0.3977, -0.0013, -0.0591, 0.9983, 0.3767, -0.7672, -0.5191, 0.9617, 0.1190, -0.2469, 0.4782, 0.6762, -0.5604, -0.8448, -0.2681, -0.4631, 0.9143, 0.2336, 0.3309, 0.2443, -0.6966, 0.6746, 0.4856, -0.6003, -0.6355, 0.6193, -0.7851, -0.0052, -0.0801, 0.9878, 0.1334, -0.5439, -0.5281, -0.6521,
0.0231, 0.7485, 0.6628, 0.0426, 0.7503, 0.6598, -0.4991, 0.4989, 0.7085, 0.4745, -0.5872, -0.6558, -0.7627, -0.5499, -0.3405, 0.1457, -0.1010, 0.9842, 0.3120, -0.8730, -0.3748, -0.1203, 0.9909, 0.0604, 0.8973, 0.4050, -0.1758, -0.2126, 0.9755, 0.0567, 0.2838, 0.8203, 0.4966, -0.0304, -0.8119, -0.5830, -0.7866, -0.6149, 0.0566, -0.9997, 0.0253, 0.0035, -0.9993, 0.0352, 0.0134, -0.9739, -0.1773, 0.1416,
0.3784, -0.8991, -0.2199, -0.9887, -0.1356, 0.0639, -0.1711, 0.9189, 0.3556, 0.2173, 0.7503, -0.6243, 0.6708, 0.0188, -0.7414, -0.2502, -0.1290, 0.9595, -0.5171, -0.8119, 0.2712, 0.3430, -0.0445, -0.9383, 0.3444, -0.0443, -0.9378, -0.6615, 0.5528, 0.5067, 0.7316, -0.4484, -0.5136, -0.9194, 0.2663, 0.2893, 0.1907, 0.7409, 0.6440, 0.9689, -0.2039, -0.1400, -0.3550, -0.9127, 0.2023, 0.0023, -0.1146, 0.9934,
0.3552, 0.3431, -0.8696, 0.3130, 0.8313, 0.4593, 0.8590, 0.5077, -0.0655, 0.1798, -0.9599, -0.2149, 0.8565, 0.4252, 0.2926, -0.7991, -0.5629, -0.2110, 0.2641, -0.4701, 0.8422, 0.4075, 0.9091, 0.0869, 0.9971, 0.0395, -0.0652, -0.1124, -0.7780, 0.6182, -0.7664, 0.6159, 0.1824, -0.9517, 0.3046, 0.0395, 0.4564, -0.7601, -0.4625, -0.1175, -0.4994, 0.8583, 0.4326, -0.7222, -0.5397, -0.5947, 0.8037, -0.0178,
-0.1360, -0.1466, 0.9798, -0.1340, -0.4808, 0.8665, 0.0877, -0.8424, -0.5317, 0.7474, -0.0334, 0.6636, -0.5691, -0.5974, 0.5650, 0.2482, -0.9654, 0.0803, 0.7315, 0.1420, 0.6669, -0.7118, -0.5187, 0.4736, -0.5168, 0.8199, 0.2462, 0.7173, -0.5608, -0.4135, -0.2046, -0.7366, 0.6446, -0.7719, 0.1295, 0.6224, -0.4010, 0.1588, 0.9022, -0.9199, -0.3467, -0.1832, -0.8080, -0.5590, 0.1862, -0.4445, -0.1384, 0.8850,
-0.9528, -0.1027, 0.2857, 0.3118, -0.9359, -0.1638, 0.5050, -0.5727, -0.6457, 0.7533, -0.1740, 0.6342, -0.1874, 0.9785, -0.0856, -0.0988, 0.0198, 0.9949, -0.5800, -0.2508, -0.7751, -0.2029, -0.5319, -0.8222, -0.6057, -0.4293, -0.6699, -0.5207, -0.7459, -0.4153, -0.6114, -0.6512, 0.4496, 0.2103, 0.8164, -0.5378, -0.3651, 0.9090, 0.2011, -0.9454, 0.0903, -0.3132, 0.4099, 0.9080, 0.0862, -0.4938, -0.8383, -0.2313,
-0.4433, -0.8658, -0.2321, 0.1154, -0.9921, -0.0494, 0.1262, -0.9917, 0.0244, 0.7497, -0.1336, 0.6481, 0.2939, -0.6484, -0.7023, 0.2714, 0.4872, 0.8300, -0.4257, -0.1933, -0.8840, -0.8640, -0.1869, -0.4675, -0.1731, -0.9697, -0.1727, -0.1623, 0.2573, -0.9526, 0.7745, 0.3141, -0.5491, -0.3541, -0.7162, 0.6014, -0.3450, -0.7236, 0.5978, 0.1319, 0.6924, 0.7094, 0.8384, 0.5420, -0.0577, 0.9402, -0.2626, -0.2169,
-0.9770, -0.0255, -0.2115, 0.0966, -0.8277, -0.5529, -0.0607, 0.8035, -0.5922, -0.9044, -0.2370, 0.3548, -0.4133, 0.7464, -0.5216, 0.6829, -0.2157, 0.6980, 0.3321, -0.7774, 0.5342, -0.9205, -0.3566, -0.1599, -0.3185, -0.3027, -0.8983, 0.8541, -0.2001, -0.4800, -0.9985, 0.0154, 0.0531, -0.7448, -0.1740, 0.6442, -0.4310, 0.8851, 0.1758, 0.6428, 0.2856, 0.7108, -0.0262, 0.1865, -0.9821, 0.3093, 0.4747, 0.8240,
-0.8525, 0.2657, -0.4502, 0.4032, 0.4590, 0.7917, 0.0349, -0.8604, -0.5084, 0.1248, -0.1926, 0.9733, -0.9857, -0.0673, 0.1545, -0.9639, 0.0817, 0.2535, -0.6949, 0.2244, 0.6831, 0.9210, 0.3805, 0.0833, 0.6089, -0.0193, 0.7930, -0.9934, -0.1011, 0.0541, 0.9872, -0.1585, 0.0187, -0.2454, -0.7781, 0.5782, -0.9227, 0.3791, 0.0693, -0.0474, -0.9214, 0.3856, -0.4009, -0.9055, -0.1391, -0.0031, 0.0129, 0.9999,
0.6918, 0.6521, -0.3101, -0.9292, 0.2095, -0.3044, -0.6699, 0.5504, -0.4983, -0.1362, 0.9900, -0.0357, 0.0946, -0.9888, 0.1152, 0.9565, 0.2915, -0.0118, -0.0885, -0.9710, -0.2221, -0.9706, 0.2403, 0.0124, 0.7155, 0.6833, -0.1455, 0.0179, -0.0130, 0.9998, 0.0131, -0.0118, 0.9998, 0.8599, -0.2853, 0.4232, -0.2197, -0.7466, -0.6280, 0.2449, 0.9532, -0.1774, 0.7703, -0.0307, -0.6370, 0.6004, -0.5310, 0.5979,
-0.1702, 0.9726, 0.1584, -0.1210, 0.9806, 0.1543, -0.9710, 0.1364, -0.1966, -0.9702, 0.1172, -0.2122, 0.9537, 0.1670, 0.2500, -0.4680, -0.7185, -0.5145, -0.8759, 0.0204, -0.4821, -0.9969, -0.0230, -0.0757, -0.9857, -0.1504, -0.0755, -0.6302, -0.7521, -0.1931, -0.6819, 0.3864, -0.6211, -0.1834, 0.8811, 0.4360, -0.6703, -0.3329, -0.6633, 0.3960, 0.8258, 0.4016, -0.4163, 0.6805, -0.6030, -0.2297, 0.9513, 0.2056,
0.9463, 0.0792, 0.3134, -0.7059, 0.7073, -0.0370, -0.8611, 0.5079, 0.0241, 0.3562, -0.3827, 0.8524, 0.7497, 0.6437, 0.1536, 0.1399, -0.4445, 0.8848, -0.4036, -0.0476, -0.9137, -0.8145, -0.4597, -0.3539, 0.9784, 0.0394, 0.2031, 0.2377, 0.6187, -0.7488, 0.2653, -0.9615, 0.0717, -0.0109, -0.6694, -0.7428, -0.3789, 0.7043, 0.6003, -0.9347, -0.3466, 0.0787, -0.7448, 0.6298, 0.2204, -0.1781, -0.5502, 0.8158,
-0.8055, -0.3861, 0.4495, 0.8968, 0.1594, 0.4128, -0.8263, -0.5192, 0.2184, 0.9579, 0.2572, -0.1277, -0.5433, 0.1340, -0.8288, -0.9122, 0.1202, -0.3917, -0.4271, -0.2543, 0.8677, 0.8471, -0.0638, 0.5276, 0.7349, -0.6608, 0.1527, 0.7168, -0.6303, 0.2980, -0.4686, 0.8830, 0.0269, 0.4684, 0.0676, -0.8809, 0.6353, -0.5068, -0.5827, -0.3346, -0.8225, 0.4600, 0.8517, 0.2720, 0.4479, 0.4613, -0.5206, -0.7185,
0.1488, 0.5083, 0.8482, 0.8107, -0.5459, 0.2116, -0.6726, -0.5044, 0.5414, -0.9893, 0.0101, 0.1452, -0.8298, -0.3869, 0.4023, 0.7505, -0.6060, -0.2638, -0.4792, -0.1574, 0.8635, 0.8477, 0.3579, -0.3915, -0.9090, -0.2677, -0.3194, 0.0895, 0.6517, 0.7532, 0.8736, 0.2124, -0.4379, 0.4153, 0.0797, 0.9062, 0.4410, 0.5521, 0.7076, -0.9784, -0.1599, -0.1309, 0.7635, 0.4140, -0.4957, -0.9410, 0.1350, -0.3102,
0.2976, 0.9432, 0.1478, 0.8603, 0.0417, 0.5081, -0.8647, -0.4901, 0.1101, 0.4289, 0.7067, 0.5627, -0.5525, -0.5855, -0.5933, -0.7300, 0.5685, 0.3793, 0.1227, 0.7536, 0.6458, -0.7317, 0.6416, -0.2303, 0.9165, -0.3934, 0.0727, 0.4115, -0.6017, 0.6845, 0.5305, -0.7622, 0.3710, -0.0614, -0.5487, 0.8338, 0.7113, -0.2804, -0.6445, -0.4659, -0.0985, -0.8793, 0.2238, 0.1354, 0.9652, 0.6392, -0.1533, 0.7536,
-0.4190, 0.0449, 0.9069, 0.7856, -0.1679, 0.5956, 0.8327, -0.5375, 0.1331, 0.5696, -0.7071, 0.4190, -0.0627, 0.8762, 0.4779, -0.5469, -0.3436, 0.7634, -0.1850, -0.9636, 0.1932, 0.8545, -0.2689, -0.4445, -0.7924, -0.3907, 0.4684, 0.2333, -0.7461, -0.6237, -0.5541, 0.1239, -0.8232, -0.5023, -0.8315, -0.2373, 0.8194, -0.2103, -0.5333, -0.9838, 0.0645, -0.1675, 0.3300, -0.8350, -0.4403, -0.0359, 0.9709, 0.2370,
0.9705, -0.1441, 0.1931, 0.3043, 0.6754, 0.6717, 0.5181, -0.8499, 0.0958, -0.2541, 0.5868, 0.7688, 0.1080, -0.0933, -0.9898, -0.1329, 0.9894, 0.0580, 0.9046, 0.3888, 0.1745, -0.3649, -0.4709, -0.8032, -0.4795, 0.3745, -0.7936, 0.1075, -0.0303, -0.9937, 0.9080, 0.4182, -0.0263, 0.8063, -0.5779, -0.1259, 0.9003, 0.2369, 0.3652, -0.7501, 0.5421, 0.3789, 0.8050, 0.5305, -0.2656, -0.0336, 0.9960, 0.0828,
0.5464, -0.8283, 0.1241, 0.9619, -0.2730, 0.0133, 0.7554, 0.4951, 0.4292, 0.4349, 0.8306, 0.3478, -0.8805, -0.4439, 0.1661, -0.3280, 0.9222, -0.2047, 0.8930, 0.2928, -0.3419, 0.0073, -0.8994, 0.4371, 0.1016, 0.7438, -0.6606, -0.6287, -0.0529, 0.7759, 0.8139, -0.5807, -0.0208, -0.7482, -0.0387, -0.6624, 0.2593, 0.2815, 0.9238, -0.0381, -0.3579, -0.9330, 0.9899, 0.0204, 0.1401, 0.7368, 0.6369, 0.2269,
0.7308, -0.5654, 0.3825, 0.5179, 0.1936, 0.8333, 0.4540, 0.7385, 0.4984, 0.0759, 0.9031, 0.4227, -0.9716, 0.1645, -0.1701, 0.3821, -0.8996, -0.2113, -0.3204, 0.7107, -0.6263, 0.5464, 0.1679, -0.8205, 0.1201, -0.9722, -0.2008, 0.9488, -0.2298, -0.2166, 0.6690, -0.4987, -0.5511, -0.0735, 0.9148, 0.3972, 0.9161, 0.0039, 0.4009, 0.2344, -0.8663, -0.4411, 0.6662, -0.7385, -0.1044, 0.6579, -0.7442, -0.1154,
-0.5123, -0.6120, -0.6025, -0.0620, -0.9042, -0.4225, -0.6417, -0.7070, -0.2973, -0.2134, -0.9730, 0.0879, 0.9958, -0.0028, -0.0911, 0.6554, -0.6587, 0.3696, 0.5165, -0.5497, 0.6566, 0.9139, 0.3468, 0.2110, 0.7492, 0.6236, 0.2231, 0.8156, 0.3666, 0.4477, 0.9630, 0.0728, 0.2594, -0.2598, 0.6657, 0.6996, 0.7106, 0.5190, -0.4750, 0.1965, -0.6918, 0.6949, 0.0698, -0.2272, 0.9714, 0.8533, 0.5126, -0.0954,
0.7333, 0.0424, -0.6786, 0.7425, -0.1533, 0.6521, 0.4797, -0.0581, 0.8755, -0.5632, -0.6652, -0.4901, -0.5910, -0.6426, -0.4876, -0.5702, 0.5492, -0.6109, -0.9030, 0.2157, -0.3716, -0.2872, 0.5284, 0.7989, -0.8755, -0.1954, 0.4419, -0.1682, -0.7620, 0.6254, 0.9029, 0.1960, -0.3826, -0.5692, 0.8199, -0.0615, 0.8987, -0.3367, -0.2811, 0.1192, 0.3470, 0.9303, 0.8975, -0.3259, -0.2969, -0.2674, 0.8081, 0.5249,
0.3185, -0.9413, 0.1122, 0.8486, -0.2078, -0.4866, -0.9642, -0.2333, -0.1264, -0.6387, -0.0649, -0.7667, 0.8738, 0.3231, -0.3635, 0.6751, -0.6646, 0.3202, -0.6387, 0.2553, 0.7259, -0.9050, -0.1790, 0.3859, 0.2600, -0.8834, 0.3898, 0.9645, 0.2573, 0.0589, 0.9000, -0.0047, 0.4359, -0.6926, 0.5420, 0.4761, -0.9058, 0.3050, 0.2940, -0.9493, -0.3025, -0.0854, -0.4469, 0.3872, 0.8065, -0.3704, -0.7337, -0.5696,
-0.6642, 0.7416, -0.0944, -0.2289, -0.9709, 0.0706, -0.1480, -0.9841, 0.0983, -0.1073, -0.3924, 0.9135, 0.4942, 0.7399, -0.4564, 0.1488, -0.9871, 0.0596, 0.9725, -0.1654, -0.1637, -0.0600, 0.1107, -0.9920, -0.1064, -0.9623, -0.2504, -0.9273, -0.0899, 0.3634, -0.1269, -0.9878, 0.0903, -0.7240, -0.3957, -0.5651, 0.9701, 0.1952, -0.1444, 0.1434, 0.0185, 0.9895, 0.7024, -0.2698, 0.6586, -0.5905, -0.4785, 0.6499,
0.9028, -0.2894, -0.3182, 0.7541, -0.1207, 0.6456, -0.5776, 0.0552, 0.8145, 0.5059, -0.8565, -0.1020, 0.1829, -0.9487, -0.2580, 0.7289, -0.4653, -0.5022, -0.0794, -0.7399, -0.6680, 0.5476, 0.6291, 0.5517, 0.1863, -0.8381, -0.5127, 0.6913, 0.5932, -0.4126, 0.9794, -0.1117, 0.1683, 0.9668, -0.0693, -0.2461, 0.9820, -0.0104, -0.1884, -0.8732, -0.3521, -0.3370, 0.0644, -0.1372, -0.9884, -0.1065, 0.4877, 0.8665,
0.9360, 0.0848, -0.3416, 0.4959, -0.6052, -0.6228, 0.4431, -0.2385, 0.8642, 0.7477, 0.5972, 0.2905, -0.7491, 0.5848, 0.3114, -0.8846, -0.0576, 0.4628, -0.1193, -0.8990, 0.4214, -0.6101, 0.2452, -0.7535, 0.5508, -0.4753, -0.6861, -0.2041, -0.7876, -0.5814, 0.1327, -0.1778, -0.9751, -0.1842, 0.7314, 0.6566, 0.5404, -0.6931, -0.4771, -0.7833, -0.6153, -0.0885, 0.3893, -0.3697, 0.8437, -0.0974, 0.9950, -0.0196,
0.9811, 0.1519, -0.1195, 0.9634, -0.1438, 0.2263, -0.8359, 0.5374, 0.1114, -0.9755, -0.1374, -0.1716, 0.3026, 0.4603, 0.8346, -0.7483, -0.0123, -0.6633, 0.0605, -0.9940, -0.0911, 0.6222, -0.6865, -0.3763, 0.5999, 0.7395, -0.3054, -0.2933, -0.5874, -0.7543, -0.9637, 0.2502, 0.0931, 0.5517, -0.8329, 0.0445, -0.8780, 0.0483, -0.4762, 0.5386, -0.1012, 0.8365, 0.9337, -0.3162, -0.1678, 0.9184, -0.3450, -0.1936,
0.9919, 0.1142, -0.0565, 0.6891, -0.6690, 0.2785, -0.0873, -0.9580, -0.2733, 0.1100, 0.9897, 0.0920, -0.2438, -0.7675, -0.5929, -0.0772, 0.9963, -0.0371, -0.8078, -0.3565, -0.4694, -0.5558, -0.5704, 0.6048, 0.4220, 0.3989, -0.8141, 0.6071, 0.7818, 0.1420, 0.9345, -0.0919, -0.3439, 0.7858, 0.5608, 0.2610, 0.2469, -0.8618, -0.4430, 0.8906, -0.3320, -0.3109, -0.0388, 0.9992, -0.0084, 0.7604, -0.1377, -0.6347,
-0.1130, 0.9894, -0.0910, 0.4479, 0.5494, -0.7054, 0.3522, 0.2423, 0.9040, -0.7404, 0.2384, 0.6285, 0.6960, -0.3895, -0.6033, -0.8120, -0.1496, -0.5642, 0.4846, -0.6116, 0.6254, 0.5398, 0.2899, -0.7903, -0.1945, 0.9793, 0.0563, -0.1579, 0.8331, -0.5301, 0.5107, -0.8142, 0.2763, 0.5314, -0.8041, 0.2664, 0.6284, -0.1776, 0.7573, -0.8952, -0.0197, 0.4452, 0.5159, -0.7515, 0.4113, 0.0565, 0.0674, 0.9961,
-0.1735, -0.9654, 0.1944, -0.9573, 0.2396, -0.1619, -0.5328, -0.1858, 0.8256, -0.4782, 0.7221, 0.5000, -0.3632, -0.8294, 0.4245, -0.2801, 0.9469, 0.1577, -0.1203, 0.1981, 0.9728, 0.5683, 0.3842, 0.7276, 0.4930, -0.8415, 0.2210, -0.0873, -0.9836, 0.1578, -0.9621, -0.0555, -0.2669, -0.9763, 0.2137, 0.0339, -0.7559, 0.4599, -0.4660, -0.9239, 0.0306, -0.3815, -0.7589, 0.5920, 0.2714, 0.5138, -0.6497, -0.5603,
-0.2900, 0.9132, -0.2861, -0.9228, -0.3563, -0.1467, 0.3100, 0.8559, -0.4140, -0.9979, -0.0622, -0.0163, -0.3569, 0.4420, -0.8229, -0.8222, -0.0463, 0.5673, 0.9740, 0.1052, 0.2005, -0.1159, -0.6192, -0.7766, -0.8370, 0.4110, 0.3613, -0.8828, -0.3407, 0.3234, -0.0878, 0.8337, 0.5452, -0.2785, 0.8823, 0.3795, 0.3396, -0.9390, 0.0540, -0.5585, -0.7521, -0.3499, 0.4023, 0.8989, 0.1737, 0.9117, 0.3513, 0.2129,
0.8964, 0.3870, 0.2162, -0.8166, 0.3298, 0.4736, -0.9864, -0.1462, -0.0750, -0.0901, -0.8148, 0.5726, 0.1720, 0.2205, 0.9601, -0.8187, -0.0153, -0.5740, -0.6335, -0.3138, 0.7072, -0.6641, -0.5203, -0.5369, -0.6122, 0.7016, 0.3648, -0.8617, 0.1463, -0.4859, 0.3440, -0.6940, -0.6325, -0.0982, 0.9731, -0.2083, -0.1179, 0.9558, -0.2694, -0.2643, 0.9559, -0.1282, -0.2866, 0.9561, -0.0607, 0.8698, -0.4558, -0.1890,
0.9092, -0.0279, -0.4155, -0.7290, 0.3758, -0.5722, -0.9687, 0.1770, -0.1741, 0.8550, 0.4883, -0.1745, -0.7557, -0.5582, -0.3425, 0.1834, -0.7615, 0.6217, 0.8192, -0.5643, -0.1026, 0.1622, -0.4364, -0.8850, -0.4110, 0.2036, 0.8886, 0.7385, 0.1890, 0.6472, 0.9826, 0.1781, 0.0528, -0.6650, -0.4225, 0.6159, 0.0098, -0.8243, 0.5661, 0.5485, -0.6783, 0.4890, -0.1786, 0.6791, 0.7120, -0.7962, -0.5203, 0.3088,
-0.4034, 0.9020, -0.1539, 0.9237, 0.3696, 0.1006, 0.9245, 0.3592, 0.1279, 0.8425, -0.4720, -0.2597, 0.9970, -0.0760, -0.0155, 0.2152, -0.9463, -0.2412, 0.8359, -0.5434, -0.0771, -0.8572, -0.5022, -0.1144, 0.7843, 0.2776, -0.5548, 0.5867, 0.7796, 0.2189, 0.8927, -0.4455, 0.0681, -0.0898, -0.0959, 0.9913, 0.1979, 0.0331, 0.9797, 0.8329, -0.1317, -0.5375, -0.5838, 0.3324, -0.7407, 0.3158, -0.3698, -0.8738,
-0.6074, -0.2991, 0.7360, -0.4262, -0.4502, 0.7847, 0.4028, 0.9054, 0.1343, 0.0691, 0.9780, 0.1966, 0.4848, -0.6092, -0.6275, 0.4338, -0.6648, -0.6082, -0.4814, 0.2120, 0.8505, 0.9176, -0.2108, -0.3369, -0.8367, -0.1946, 0.5119, 0.4716, 0.1685, -0.8656, 0.7249, -0.5346, 0.4344, 0.7076, -0.4000, -0.5825, 0.8533, -0.4823, -0.1980, 0.7861, 0.1435, 0.6013, 0.3086, 0.0290, 0.9507, 0.4693, -0.7244, 0.5049,
0.8318, 0.5381, 0.1362, -0.8139, 0.4483, 0.3695, -0.9987, -0.0462, 0.0207, -0.0764, -0.6761, -0.7328, 0.2907, 0.9154, -0.2783, -0.3472, 0.4958, 0.7960, 0.5790, 0.4832, 0.6567, 0.1116, -0.8704, 0.4796, -0.0104, 0.7733, -0.6339, -0.5249, 0.5373, -0.6601, -0.1633, 0.9054, -0.3918, -0.6279, 0.6719, 0.3929, 0.8915, 0.1419, 0.4303, -0.4773, 0.8603, -0.1793, -0.1689, 0.9659, 0.1962, -0.9483, -0.1251, 0.2918,
0.9787, -0.1835, 0.0923, -0.7594, -0.2871, 0.5838, -0.9904, 0.0252, 0.1359, 0.1553, -0.9650, -0.2115, 0.9821, -0.1331, 0.1332, 0.7756, 0.1478, -0.6137, -0.9818, 0.1890, 0.0210, -0.6881, 0.7256, 0.0028, 0.7224, -0.6237, -0.2986, -0.6640, 0.7122, 0.2278, 0.9848, 0.1364, -0.1079, -0.9986, 0.0531, -0.0047, -0.9039, -0.4266, 0.0314, -0.1732, 0.9567, 0.2339, 0.9969, -0.0422, 0.0667, 0.8334, 0.5383, 0.1254,
0.8939, 0.4129, 0.1745, -0.4279, 0.7408, 0.5177, 0.8753, 0.3629, -0.3195, -0.6758, -0.2926, 0.6765, 0.1069, -0.7363, -0.6682, -0.7541, 0.6552, 0.0456, 0.1677, -0.9361, -0.3093, 0.7146, 0.6908, -0.1105, 0.7033, 0.7001, -0.1231, 0.8686, 0.3916, 0.3035, -0.5517, -0.2025, -0.8091, 0.9440, 0.3079, 0.1185, -0.7607, 0.5015, -0.4121, 0.7649, -0.3032, 0.5683, -0.4392, -0.6046, -0.6645, 0.8948, 0.4009, -0.1963,
0.1147, -0.0263, 0.9930, 0.9372, 0.3482, -0.0186, -0.0005, -0.6097, -0.7926, -0.9794, -0.1330, 0.1521, -0.9509, -0.2186, -0.2191, 0.9842, -0.1491, 0.0960, 0.7961, -0.5888, -0.1400, 0.7881, -0.5954, -0.1564, 0.1308, -0.5531, -0.8228, 0.7845, 0.2271, -0.5771, 0.7899, -0.1975, 0.5805, 0.7984, -0.5032, -0.3308, 0.7199, 0.6868, -0.1001, 0.7666, 0.6375, 0.0766, -0.7675, -0.2669, -0.5829, -0.8440, 0.1588, 0.5123,
-0.5507, 0.1725, -0.8167, 0.4458, -0.8787, -0.1706, -0.1927, -0.1886, 0.9630, 0.8717, 0.1115, 0.4771, 0.9849, 0.1717, -0.0240, 0.8612, 0.4515, 0.2336, 0.8247, 0.4909, 0.2809, -0.9649, 0.2624, -0.0077, 0.5844, -0.7498, -0.3103, 0.2445, -0.2769, 0.9293, -0.2618, -0.9003, -0.3477, 0.3885, -0.9132, 0.1230, -0.6765, -0.5221, -0.5193, 0.1179, -0.8545, -0.5058, -0.0134, -0.7029, 0.7111, 0.9904, 0.0287, -0.1352,
-0.0195, 0.0446, 0.9988, -0.9309, 0.0590, 0.3606, 0.8882, 0.1104, 0.4461, 0.5700, 0.7596, 0.3134, 0.6785, -0.6851, -0.2652, 0.3821, -0.6796, 0.6262, -0.2283, 0.9088, 0.3492, -0.9814, 0.1908, -0.0227, 0.9360, 0.1442, 0.3212, 0.8185, -0.5736, -0.0331, 0.4209, 0.4702, 0.7757, -0.5474, -0.8305, -0.1033, -0.3101, -0.6173, 0.7231, 0.8942, 0.4172, -0.1624, -0.8188, -0.2140, -0.5326, 0.2316, -0.8716, -0.4320,
0.2212, -0.8825, -0.4150, 0.6652, 0.3333, -0.6681, 0.2252, 0.7186, -0.6580, -0.5974, 0.7997, 0.0609, -0.8317, -0.4735, -0.2898, -0.4108, -0.0458, 0.9106, 0.0097, 0.6239, -0.7815, 0.0895, 0.8200, -0.5653, -0.4012, -0.9095, -0.1092, 0.9738, -0.1289, -0.1873, 0.7113, -0.3901, 0.5848, -0.1937, -0.9411, 0.2770, -0.3342, -0.6673, 0.6655, -0.1431, 0.5385, -0.8304, 0.8745, 0.4386, 0.2071, -0.0314, -0.9025, 0.4296,
-0.9037, 0.2277, -0.3625, -0.1609, -0.8182, -0.5519, -0.8551, -0.3937, -0.3373, -0.2286, -0.7123, 0.6636, -0.4403, -0.3780, -0.8144, -0.7733, -0.6210, -0.1281, 0.1408, -0.9774, 0.1579, 0.4352, -0.7881, 0.4353, -0.8224, -0.5473, 0.1554, 0.9520, -0.3042, 0.0344, 0.6957, -0.3440, 0.6306, -0.8124, -0.0557, 0.5805, -0.8809, -0.4504, -0.1454, 0.4153, -0.6168, -0.6686, 0.5495, -0.7996, 0.2424, 0.6889, -0.3251, 0.6479,
0.4923, 0.0912, 0.8656, -0.9082, -0.3896, -0.1529, -0.4986, 0.8641, -0.0680, -0.2977, -0.7809, -0.5491, 0.1435, -0.5447, -0.8263, 0.9332, -0.0035, 0.3592, 0.3698, -0.7226, 0.5841, 0.5857, 0.6676, 0.4597, 0.0630, -0.7012, -0.7102, -0.9390, 0.0846, 0.3334, -0.5870, 0.6335, 0.5041, -0.9841, -0.0535, 0.1694, 0.6262, -0.1859, 0.7572, 0.9310, -0.2956, 0.2141, -0.1475, -0.2075, 0.9670, -0.6017, -0.2684, -0.7523,
-0.6408, 0.7677, 0.0106, 0.7747, -0.4964, 0.3916, 0.3141, 0.8899, 0.3307, -0.9154, -0.0337, -0.4011, -0.8931, -0.3724, -0.2523, 0.2210, -0.8776, -0.4255, -0.9618, -0.0793, -0.2622, 0.8746, 0.0761, 0.4788, 0.8488, 0.2660, 0.4569, 0.8662, 0.4974, 0.0479, 0.0485, 0.0216, 0.9986, -0.5520, 0.0974, 0.8282, 0.2740, 0.9183, 0.2856, -0.0660, -0.8152, -0.5754, -0.5851, 0.7144, 0.3838, 0.1096, 0.0414, 0.9931,
0.5036, -0.4425, 0.7420, -0.7967, -0.5550, -0.2394, 0.6846, 0.6945, 0.2216, -0.7843, 0.5353, 0.3136, -0.8729, -0.0735, -0.4824, 0.2800, 0.2970, 0.9129, 0.7323, -0.2893, 0.6165, 0.2545, 0.0204, 0.9669, 0.0911, 0.8264, 0.5557, 0.3019, -0.7877, -0.5370, -0.2024, 0.6782, -0.7065, -0.5680, -0.0195, 0.8228, -0.0544, -0.6105, 0.7902, 0.1022, 0.8614, 0.4975, -0.6174, -0.4086, -0.6722, -0.1024, 0.9853, 0.1367,
-0.7220, -0.5785, -0.3795, -0.9468, 0.0148, -0.3213, 0.2467, -0.1502, -0.9574, 0.0898, -0.8465, -0.5248, -0.2202, 0.3903, -0.8940, 0.2794, 0.9567, -0.0812, 0.8803, 0.0801, 0.4676, -0.6577, -0.5726, 0.4894, 0.8252, -0.3082, 0.4733, -0.4313, -0.9019, -0.0250, -0.8085, -0.0066, -0.5885, 0.8943, 0.1847, -0.4075, 0.9119, 0.3830, -0.1474, -0.8170, -0.0933, 0.5690, 0.9346, -0.3488, -0.0697, -0.9996, 0.0272, 0.0082,
-0.7058, 0.2829, -0.6495, -0.9011, 0.4336, 0.0041, 0.5157, -0.0128, 0.8567, 0.7917, 0.5865, 0.1711, 0.3728, 0.1536, 0.9151, 0.9380, -0.1344, -0.3194, 0.3421, -0.3784, 0.8601, -0.3430, 0.8983, 0.2746, -0.9946, 0.0148, 0.1025, 0.9106, 0.3830, -0.1553, 0.5169, 0.8374, -0.1777, 0.6880, 0.3281, 0.6473, -0.1715, -0.2412, 0.9552, 0.9690, -0.0982, -0.2267, -0.7242, 0.3632, 0.5862, -0.7324, 0.2835, 0.6190,
-0.2618, 0.9285, 0.2632, -0.6415, 0.0638, -0.7644, 0.2778, 0.9243, -0.2617, 0.0279, -0.0564, -0.9980, -0.3465, 0.9328, -0.0991, -0.7404, -0.4245, -0.5212, 0.6254, 0.2082, 0.7520, 0.4294, -0.8925, -0.1380, 0.8329, -0.5432, 0.1063, 0.9382, 0.3437, 0.0395, -0.0373, 0.9989, 0.0268, 0.8545, -0.4989, -0.1446, 0.7554, -0.1650, -0.6342, 0.6789, -0.6994, 0.2236, 0.8290, 0.3712, 0.4183, 0.2543, -0.9409, 0.2236,
0.6538, 0.7069, -0.2697, -0.2105, -0.1661, 0.9634, -0.6722, -0.6008, 0.4326, -0.9061, -0.4184, 0.0627, -0.5628, 0.4736, -0.6775, 0.1690, -0.8337, 0.5257, -0.9126, -0.3038, -0.2736, 0.2867, -0.1158, 0.9510, 0.4678, 0.3929, -0.7917, -0.2665, 0.1973, 0.9434, -0.4713, -0.5639, 0.6782, 0.7481, 0.5593, -0.3571, 0.7111, -0.6626, -0.2351, -0.3484, 0.6891, 0.6355, -0.3975, -0.8183, 0.4153, 0.1523, -0.4293, -0.8902,
0.8039, -0.1365, -0.5788, -0.4321, 0.9006, 0.0463, 0.6584, 0.7170, 0.2290, 0.8828, -0.4095, 0.2303, -0.4782, -0.8529, -0.2097, -0.5654, 0.8248, 0.0093, 0.9516, -0.2979, -0.0755, 0.3026, 0.9237, 0.2351, 0.7537, -0.3050, 0.5821, -0.3286, 0.9443, -0.0181, -0.9665, 0.0194, -0.2560, 0.4265, -0.1055, -0.8983, -0.1639, -0.7221, 0.6720, 0.9905, 0.0895, 0.1048, 0.9633, 0.0427, 0.2649, -0.4495, -0.3872, 0.8050,
-0.6864, 0.5227, 0.5056, -0.8413, -0.3122, -0.4413, 0.9568, -0.2711, 0.1052, -0.2335, 0.9720, 0.0282, -0.9716, 0.2361, -0.0142, 0.6826, -0.7250, -0.0917, -0.9485, 0.1998, 0.2460, -0.8530, -0.5177, -0.0656, 0.9934, 0.1062, -0.0428, -0.4371, 0.6339, 0.6380, 0.2011, 0.2459, -0.9482, -0.9664, -0.0506, 0.2520, 0.0518, 0.2576, 0.9649, -0.4381, 0.7689, 0.4657, -0.4370, 0.6699, 0.6002, -0.0145, -0.6907, 0.7230,
0.5636, 0.8150, -0.1349, 0.6713, 0.3078, -0.6742, 0.6844, 0.2246, 0.6937, -0.0138, 0.8518, -0.5237, 0.6429, 0.1350, -0.7539, 0.4811, 0.6270, -0.6127, 0.0734, 0.5404, 0.8382, -0.7672, 0.3488, -0.5382, 0.7254, -0.0945, -0.6818, 0.7304, -0.6810, 0.0532, -0.0493, 0.8939, 0.4456, -0.0086, 0.0129, 0.9999, 0.9885, 0.0531, -0.1413, -0.4858, 0.8495, 0.2058, 0.9336, -0.2978, -0.1994, -0.5955, -0.7864, -0.1643,
0.8491, -0.1789, -0.4970, -0.8293, -0.0578, -0.5558, 0.2817, -0.9254, -0.2536, -0.7406, -0.5303, -0.4127, -0.4647, 0.8004, 0.3786, 0.9092, -0.1438, -0.3907, 0.2747, 0.4392, 0.8554, -0.2360, -0.9253, -0.2969, 0.8272, 0.2512, 0.5027, -0.9761, 0.1360, -0.1694, 0.2374, 0.8433, 0.4822, 0.1401, -0.7680, -0.6249, 0.8393, -0.1247, -0.5292, -0.3275, 0.5382, 0.7766, 0.9398, -0.1862, -0.2865, -0.0441, 0.6548, 0.7545,
-0.6727, 0.3733, 0.6388, -0.9875, -0.0836, 0.1338, -0.6896, 0.7151, 0.1143, -0.5512, -0.3998, -0.7323, -0.5233, -0.4327, -0.7341, -0.4906, -0.5848, -0.6460, 0.5553, -0.1388, -0.8200, -0.3698, -0.5565, -0.7440, 0.1416, -0.7793, 0.6104, -0.7570, 0.2126, 0.6178, 0.9004, 0.4063, 0.1557, -0.7845, -0.5170, -0.3424, 0.9474, -0.3186, -0.0301, -0.4832, -0.4381, 0.7580, 0.4984, 0.7206, -0.4821, 0.6235, -0.6116, -0.4871,
0.9106, 0.3085, -0.2749, 0.4928, 0.0305, 0.8696, -0.7401, 0.0539, -0.6703, -0.8604, -0.4033, 0.3116, 0.1033, 0.2368, 0.9661, 0.9646, -0.2509, 0.0813, -0.7709, -0.5208, -0.3666, 0.0424, 0.0080, 0.9991, -0.4182, -0.8103, -0.4104, 0.0216, -0.7026, -0.7113, 0.7899, -0.6021, 0.1166, 0.7988, 0.5244, 0.2950, 0.9816, 0.1898, 0.0216, -0.1619, -0.7971, -0.5817, 0.8172, 0.5284, 0.2299, 0.3628, 0.1526, 0.9193,
0.2970, -0.8668, 0.4006, 0.2238, -0.8116, 0.5397, 0.1242, -0.4513, 0.8837, 0.0115, -0.7262, 0.6874, -0.0178, 0.0431, -0.9989, -0.7932, 0.2943, 0.5332, 0.8453, -0.5206, 0.1206, 0.8588, -0.3763, -0.3476, 0.1915, 0.9014, -0.3884, -0.5833, -0.1587, -0.7966, 0.9748, 0.1684, 0.1463, 0.6770, 0.5024, 0.5378, 0.5528, -0.6935, -0.4620, -0.8138, 0.1775, -0.5534, 0.9858, 0.0885, -0.1424, 0.9957, -0.0054, -0.0921,
0.8689, -0.3720, -0.3264, 0.2374, -0.6925, 0.6812, -0.5062, 0.0601, 0.8603, 0.2810, 0.8096, 0.5154, -0.2430, 0.9457, 0.2158, 0.6570, 0.7068, 0.2624, -0.8343, -0.1880, 0.5183, 0.6947, -0.7182, 0.0397, -0.6300, -0.6842, 0.3673, 0.2909, 0.8445, -0.4497, 0.9510, 0.2872, 0.1148, 0.7739, -0.5189, -0.3631, -0.5000, -0.7445, 0.4424, 0.6232, -0.7054, 0.3377, 0.9700, -0.2424, -0.0171, -0.2622, 0.3095, 0.9140,
-0.7875, 0.2968, 0.5401, 0.3517, -0.7017, 0.6196, 0.6962, 0.0482, 0.7162, -0.8110, 0.3602, -0.4610, 0.7226, -0.5978, 0.3471, 0.0845, 0.8734, 0.4796, 0.5996, -0.2835, -0.7484, -0.9843, -0.1624, 0.0691, 0.9398, 0.2322, 0.2509, 0.7141, -0.0573, 0.6977, 0.0036, 0.0270, 0.9996, -0.4398, -0.3303, -0.8352, 0.6691, 0.4961, 0.5533, 0.7704, 0.6312, 0.0898, -0.8719, 0.4894, -0.0150, 0.7789, 0.5540, -0.2941,
-0.7852, -0.0562, -0.6167, -0.0444, 0.5595, 0.8276, -0.2824, 0.4908, 0.8242, -0.5503, 0.7313, -0.4030, 0.9476, 0.2773, 0.1587, -0.7315, -0.4989, 0.4648, -0.8763, -0.4162, 0.2427, 0.9349, 0.1292, 0.3305, 0.9773, -0.0123, 0.2114, -0.1819, 0.9802, 0.0780, -0.5988, 0.0191, 0.8007, 0.9437, 0.1305, -0.3041, -0.2186, -0.9458, -0.2400, -0.3721, -0.7364, -0.5650, 0.9557, 0.1333, -0.2625, 0.9986, -0.0517, 0.0071,
0.4439, 0.8946, -0.0524, -0.6715, -0.6293, 0.3912, 0.4755, -0.7853, -0.3965, 0.3690, -0.1186, -0.9218, 0.9605, -0.1675, 0.2222, -0.8056, -0.4646, -0.3676, -0.3734, 0.5540, -0.7441, 0.0010, 0.6481, 0.7615, 0.8417, 0.4159, -0.3443, -0.7416, -0.4389, -0.5073, -0.1559, -0.9765, 0.1489, 0.7848, -0.6197, 0.0110, 0.0004, 0.6487, 0.7610, -0.8633, 0.4542, -0.2202, -0.6883, -0.3300, 0.6460, 0.6332, 0.6616, 0.4016,
0.5281, -0.6148, -0.5858, -0.7630, 0.5851, 0.2747, -0.6373, 0.3718, -0.6750, 0.4948, 0.2311, -0.8377, -0.2219, 0.4888, 0.8437, -0.7351, 0.6453, 0.2081, -0.8023, 0.4229, 0.4213, -0.5519, -0.5275, 0.6459, 0.7174, -0.0099, 0.6966, 0.4247, -0.1406, 0.8944, 0.2433, -0.6189, -0.7469, 0.9691, -0.0095, 0.2463, -0.0700, 0.8997, -0.4309, 0.0395, -0.9883, -0.1470, 0.9284, -0.1462, -0.3417, 0.5575, 0.8118, -0.1737,
0.6176, 0.7616, -0.1962, 0.7146, 0.6990, -0.0290, -0.7029, 0.6601, 0.2651, 0.0206, 0.8808, -0.4731, -0.4949, 0.7465, -0.4448, -0.9769, 0.1748, -0.1228, 0.2736, -0.0035, 0.9618, -0.3846, -0.9088, -0.1619, 0.7139, 0.0834, 0.6953, -0.2526, -0.7856, -0.5649, 0.9659, -0.2417, 0.0928, -0.5795, 0.3404, 0.7405, 0.6486, -0.6537, -0.3897, -0.3671, 0.4689, 0.8033, 0.4842, -0.5775, -0.6573, -0.1328, -0.9864, -0.0973,
-0.2113, -0.5809, 0.7861, -0.9005, -0.2155, 0.3777, -0.9212, 0.3376, 0.1933, 0.3035, -0.7660, 0.5667, 0.8491, -0.4487, -0.2786, -0.5856, 0.6705, -0.4556, -0.4407, 0.5752, 0.6892, -0.1020, -0.8793, -0.4652, 0.4657, -0.2824, 0.8387, 0.7798, 0.4922, 0.3867, -0.4481, -0.4871, -0.7497, -0.7504, 0.4580, -0.4766, -0.6691, -0.5562, -0.4929, -0.9730, 0.2308, 0.0004, 0.2339, -0.7498, 0.6189, 0.4720, -0.1873, -0.8614,
0.8194, 0.4033, -0.4073, -0.8840, 0.1961, 0.4244, 0.7158, -0.4710, 0.5155, -0.2622, -0.6975, 0.6669, 0.3860, 0.8367, -0.3885, 0.1876, -0.8093, -0.5566, -0.9814, 0.1908, -0.0223, -0.9875, 0.1575, 0.0072, -0.9954, -0.0058, 0.0958, 0.9928, 0.1040, -0.0598, 0.6141, 0.7782, 0.1314, 0.7362, 0.2371, 0.6339, -0.3336, 0.9226, -0.1937, -0.9494, 0.3109, -0.0437, 0.9758, 0.1864, 0.1147, -0.9866, -0.0074, 0.1627,
-0.2380, -0.9641, -0.1173, -0.9255, 0.3296, -0.1864, -0.5561, -0.1194, 0.8225, 0.4224, -0.7157, 0.5562, 0.5145, 0.5856, 0.6263, 0.8637, -0.5035, -0.0223, -0.6822, -0.6645, 0.3052, -0.1465, -0.0396, -0.9884, 0.7063, 0.5268, 0.4729, 0.0106, 0.9884, 0.1514, 0.9322, -0.3607, -0.0308, -0.4647, -0.3219, 0.8249, -0.6959, -0.0760, 0.7141, 0.9631, 0.2599, -0.0693, 0.1784, 0.1327, 0.9750, -0.9799, 0.0277, -0.1975,
-0.6300, -0.1702, -0.7577, 0.8354, -0.1326, 0.5334, -0.6527, 0.1123, 0.7493, -0.0919, -0.0083, -0.9957, -0.2343, -0.3220, -0.9173, -0.9500, 0.2560, -0.1786, 0.9853, 0.1039, 0.1356, -0.1350, -0.6034, -0.7860, 0.9440, -0.2784, -0.1772, -0.3032, -0.8181, -0.4887, 0.9373, -0.0887, 0.3370, 0.3288, -0.8426, 0.4265, -0.0349, -0.8665, -0.4979, -0.6074, -0.5596, -0.5638, -0.0969, 0.9505, 0.2951, -0.3108, -0.5195, 0.7960,
-0.9259, -0.0643, -0.3723, 0.9738, 0.2272, 0.0019, -0.9936, -0.0882, -0.0703, 0.2655, -0.9127, -0.3105, 0.8465, -0.1358, 0.5148, -0.5531, -0.3458, 0.7579, 0.6671, 0.3300, -0.6679, 0.7032, -0.6345, -0.3210, -0.8129, -0.4146, -0.4091, 0.7963, -0.1426, -0.5878, 0.9346, -0.3489, -0.0696, -0.8243, 0.1218, 0.5529, 0.9548, 0.2957, -0.0315, -0.4506, 0.8860, -0.1093, 0.8755, 0.2526, -0.4120, 0.9327, -0.0201, 0.3601,
0.6008, 0.7920, 0.1087, -0.9091, -0.2261, 0.3499, -0.6656, -0.5579, -0.4957, 0.8238, 0.5400, -0.1727, 0.8011, -0.1023, -0.5897, -0.9147, 0.0264, -0.4032, -0.2028, -0.9783, 0.0421, 0.0643, -0.7227, -0.6882, 0.7336, -0.6629, 0.1497, 0.8409, 0.5197, 0.1510, 0.7688, 0.6321, -0.0964, 0.8513, -0.4400, -0.2857, 0.7285, 0.2809, -0.6248, -0.1738, 0.5186, 0.8372, 0.7142, 0.6517, 0.2555, 0.0949, -0.8096, 0.5792,
0.5656, -0.8150, 0.1262, 0.9648, -0.1131, 0.2373, 0.3982, -0.1373, -0.9070, 0.6062, -0.7827, 0.1411, -0.0801, -0.6430, -0.7617, 0.5478, -0.0819, 0.8326, -0.9615, -0.1943, -0.1941, -0.7907, -0.5380, 0.2921, -0.0252, 0.0945, 0.9952, 0.8362, -0.3822, -0.3932, 0.9826, 0.1851, 0.0133, 0.1130, -0.6940, 0.7110, -0.9125, 0.3606, -0.1930, -0.8147, 0.1631, -0.5565, 0.6703, -0.2149, -0.7103, 0.2886, -0.8478, 0.4448,
-0.9496, 0.2141, -0.2291, -0.2616, 0.9225, 0.2838, -0.9914, -0.1309, -0.0058, -0.8340, 0.5512, 0.0237, -0.0841, 0.0005, 0.9965, -0.8287, -0.4721, 0.3006, -0.3788, 0.8569, 0.3495, 0.2795, -0.9531, 0.1160, 0.9945, 0.0244, -0.1020, 0.6372, -0.0475, 0.7692, -0.5758, -0.3136, 0.7550, 0.5416, 0.4278, 0.7237, -0.9329, 0.1155, 0.3412, -0.8596, -0.3370, -0.3841, -0.9010, -0.3024, 0.3110, -0.8324, 0.4293, 0.3505,
-0.8322, 0.5073, 0.2240, 0.7182, 0.6959, -0.0048, -0.5463, 0.6412, -0.5389, -0.7084, 0.2842, 0.6461, -0.4045, -0.1427, 0.9033, -0.8930, 0.0240, 0.4494, -0.9887, 0.0010, 0.1497, 0.8924, -0.4423, 0.0892, -0.4303, 0.7535, 0.4970, -0.4994, -0.8463, 0.1857, -0.9210, -0.1926, 0.3386, -0.9269, 0.3742, -0.0281, 0.8298, -0.2975, -0.4721, -0.7501, 0.1410, -0.6461, -0.7946, -0.2877, -0.5346, -0.4680, -0.8753, 0.1217,
-0.5504, -0.2629, -0.7924, -0.3830, -0.5006, 0.7763, -0.4954, 0.5640, -0.6607, -0.3300, 0.9088, -0.2551, 0.0070, -0.6324, -0.7746, -0.9311, -0.2945, -0.2153, -0.2481, -0.9506, 0.1866, 0.3338, -0.0591, -0.9408, 0.8274, 0.5610, -0.0270, 0.5269, 0.7677, -0.3648, -0.9417, 0.0988, 0.3217, -0.0659, -0.9872, 0.1450, 0.1422, -0.7709, 0.6209, 0.7664, -0.2513, 0.5912, -0.8688, 0.0680, 0.4904, 0.9456, 0.3188, 0.0643,
0.7448, 0.4953, 0.4471, 0.2882, 0.0137, 0.9575, -0.9101, -0.1119, 0.3989, -0.5095, -0.8092, 0.2924, -0.9390, 0.2101, 0.2723, -0.1978, 0.2182, 0.9557, -0.1377, -0.3298, 0.9340, -0.0052, 0.2753, -0.9613, -0.6148, 0.7778, 0.1304, -0.1002, 0.7990, 0.5929, -0.4524, -0.6156, 0.6452, 0.6063, 0.1329, 0.7840, -0.2256, -0.9520, -0.2068, -0.0355, -0.9747, 0.2206, 0.3032, -0.4824, 0.8218, -0.9191, -0.0589, 0.3896,
-0.1984, -0.7461, 0.6357, -0.6932, -0.6947, -0.1919, -0.6661, 0.1428, 0.7321, -0.7345, -0.6123, -0.2926, -0.8334, -0.5519, -0.0294, -0.8912, 0.0163, 0.4533, -0.5690, -0.7873, -0.2376, 0.1913, -0.7133, -0.6742, -0.9794, -0.0732, -0.1882, -0.9519, -0.2971, 0.0751, 0.6192, -0.4013, 0.6749, -0.8108, -0.1792, -0.5572, -0.4276, -0.8670, -0.2559, -0.8650, 0.0485, -0.4995, -0.4724, -0.8063, -0.3560, 0.4878, -0.1960, 0.8507,
0.4910, 0.0050, -0.8712, 0.6584, -0.6574, -0.3666, 0.9061, 0.4078, 0.1122, -0.7682, 0.5401, -0.3439, -0.9002, 0.3987, 0.1750, -0.9331, 0.0227, 0.3589, -0.1067, 0.9942, 0.0155, 0.9329, -0.3558, 0.0562, -0.8028, -0.5706, -0.1728, 0.7901, -0.3054, 0.5315, 0.8896, -0.2663, -0.3711, 0.9373, 0.2932, -0.1884, -0.8736, 0.0058, -0.4867, -0.8127, -0.5287, -0.2448, -0.9932, 0.0253, 0.1136, -0.7610, 0.2042, 0.6157,
0.9733, 0.2284, 0.0208, 0.7622, 0.5049, -0.4050, 0.7043, -0.6103, -0.3626, -0.4352, -0.4188, -0.7970, 0.2325, -0.4751, -0.8487, -0.6026, 0.7803, 0.1677, -0.7958, 0.1285, -0.5917, -0.4967, -0.8646, -0.0761, -0.9822, -0.1499, -0.1131, -0.7141, 0.1831, -0.6756, -0.0537, -0.6838, 0.7277, 0.7359, -0.1788, -0.6531, 0.3391, 0.9407, -0.0115, 0.9678, -0.0235, -0.2507, -0.2242, 0.5708, 0.7899, -0.4279, 0.5918, -0.6832,
0.8980, 0.4398, 0.0150, 0.8936, -0.3558, 0.2737, 0.6325, 0.7340, 0.2474, 0.5600, -0.4194, -0.7145, 0.1855, -0.0637, 0.9806, -0.0321, -0.7686, -0.6389, -0.7599, 0.5980, 0.2549, 0.5613, -0.7666, 0.3119, 0.8265, 0.3319, -0.4547, -0.4277, 0.6515, 0.6265, 0.6189, 0.7793, 0.0980, -0.3250, -0.6153, 0.7182, -0.0085, -0.9695, 0.2449, -0.0151, 0.8196, 0.5728, 0.9561, 0.2722, -0.1084, -0.9330, 0.0283, 0.3588,
-0.6486, -0.0775, -0.7571, 0.4100, 0.2865, 0.8659, 0.6782, -0.3748, -0.6321, -0.9779, -0.1177, 0.1728, 0.5905, 0.6167, 0.5205, -0.1000, 0.9818, 0.1617, -0.6826, -0.1089, 0.7226, -0.4162, -0.6967, 0.5843, -0.1946, -0.0912, 0.9766, -0.8423, 0.4373, -0.3151, -0.5855, -0.7805, -0.2192, -0.2806, 0.2348, 0.9307, 0.8566, 0.4832, 0.1811, -0.3932, 0.7727, 0.4983, -0.9662, -0.1516, 0.2083, 0.5257, 0.3072, 0.7933,
0.0283, -0.1704, 0.9850, 0.9579, -0.2872, -0.0043, 0.9610, -0.0825, -0.2638, 0.9283, 0.1482, 0.3409, 0.4073, -0.7386, -0.5371, -0.0784, 0.9276, -0.3652, 0.9796, -0.0337, 0.1982, -0.5183, -0.7433, -0.4229, -0.8126, 0.5681, -0.1301, -0.7911, 0.0381, 0.6105, 0.7286, -0.3479, 0.5900, -0.5951, -0.7017, -0.3918, 0.8935, 0.2324, -0.3842, 0.2262, 0.8173, 0.5299, 0.3784, 0.9212, 0.0905, 0.8103, -0.1734, 0.5598,
-0.9470, 0.3205, 0.0213, -0.9343, 0.3524, -0.0533, -0.2174, -0.7178, -0.6615, -0.3163, -0.6504, -0.6906, 0.2190, -0.9684, 0.1191, -0.9709, -0.0259, 0.2380, -0.7953, -0.6057, 0.0229, 0.8109, 0.5458, -0.2112, -0.7752, -0.5656, 0.2814, 0.9362, 0.3507, 0.0241, -0.6646, 0.0126, 0.7471, 0.7050, -0.0799, -0.7047, 0.7302, -0.0749, -0.6791, 0.8197, -0.3511, 0.4527, -0.9439, -0.3258, 0.0539, 0.0218, -0.1718, 0.9849,
0.4895, -0.6173, -0.6159, 0.7769, 0.0831, -0.6241, -0.8781, 0.4549, 0.1486, -0.9898, -0.1324, 0.0521, 0.4199, -0.3555, -0.8351, 0.6838, 0.5524, -0.4768, 0.8912, 0.4255, 0.1573, -0.9128, 0.0658, -0.4030, 0.0128, 0.3109, 0.9503, 0.4267, 0.8119, 0.3984, 0.9332, -0.1792, -0.3115, 0.1202, 0.6756, -0.7274, 0.2507, 0.3655, 0.8964, -0.4168, -0.8866, -0.2005, -0.3834, 0.8162, 0.4322, -0.4416, -0.8841, 0.1530,
0.8636, 0.4946, -0.0976, 0.9145, 0.1086, -0.3898, 0.6584, -0.6553, 0.3703, -0.0788, -0.9751, 0.2072, 0.2301, -0.8719, -0.4322, -0.7403, 0.5297, -0.4139, 0.1860, 0.9740, -0.1292, -0.0201, -0.7461, 0.6655, -0.8662, -0.3178, -0.3856, -0.5384, -0.8355, 0.1099, 0.9986, 0.0334, 0.0411, 0.9948, 0.0137, 0.1007, 0.0049, -0.9933, -0.1154, -0.2341, 0.0985, 0.9672, -0.6423, -0.6957, -0.3218, 0.3166, -0.0617, -0.9465,
0.8927, 0.2185, -0.3942, 0.8621, -0.4865, -0.1419, 0.8657, -0.4955, -0.0714, -0.5013, 0.7105, 0.4939, 0.9232, 0.0199, 0.3837, 0.9494, -0.2806, 0.1413, 0.8859, 0.0969, 0.4537, -0.4864, 0.6316, 0.6038, -0.0248, 0.0199, 0.9995, -0.0242, 0.0202, 0.9995, 0.0506, -0.7783, 0.6258, 0.7083, 0.4748, 0.5224, 0.6323, -0.7420, -0.2230, -0.8515, -0.2676, 0.4510, 0.7084, 0.6229, 0.3318, 0.4969, -0.5028, 0.7073,
-0.9542, 0.2493, -0.1652, -0.7717, -0.3844, 0.5067, -0.2414, 0.1522, 0.9584, 0.3984, 0.8552, 0.3316, 0.6879, -0.6171, 0.3820, -0.1390, -0.4766, 0.8681, -0.9859, -0.1325, -0.1021, -0.9878, 0.1254, 0.0919, -0.9349, -0.3162, -0.1609, -0.9714, -0.0281, 0.2357, -0.9112, -0.2855, 0.2971, 0.9729, 0.1649, 0.1620, -0.9977, -0.0587, -0.0349, 0.5142, 0.7602, 0.3971, 0.1850, -0.0234, 0.9825, 0.9614, -0.2681, -0.0613,
0.1597, -0.7157, -0.6798, -0.1986, -0.9060, -0.3737, 0.1315, -0.7817, 0.6096, 0.8717, -0.3833, -0.3053, 0.8885, 0.4552, 0.0577, -0.1824, 0.9797, -0.0833, -0.3417, -0.7243, 0.5988, 0.4229, 0.7079, 0.5658, -0.4064, 0.3185, -0.8564, -0.9629, 0.0260, -0.2688, -0.1698, 0.2768, 0.9458, -0.8860, 0.2758, 0.3728, -0.4956, -0.7893, 0.3624, -0.3034, -0.5139, 0.8024, -0.4396, -0.3890, -0.8096, -0.6797, 0.3295, 0.6554,
-0.9636, -0.1702, 0.2063, -0.0124, -0.9685, 0.2485, -0.7372, -0.6733, -0.0558, -0.8173, 0.4202, -0.3944, 0.7255, 0.6701, 0.1568, -0.6104, 0.1758, -0.7723, -0.1430, -0.8329, 0.5346, -0.1323, -0.8386, 0.5285, -0.3318, -0.2101, 0.9196, -0.1747, -0.4973, -0.8498, -0.1284, -0.5095, -0.8508, -0.8556, 0.0910, 0.5095, 0.6307, -0.3549, -0.6902, -0.0686, -0.9401, 0.3339, 0.5416, 0.8237, -0.1681, -0.8636, 0.4921, 0.1096,
0.6562, -0.0806, -0.7503, -0.5007, -0.7885, 0.3572, -0.4576, -0.5459, 0.7019, -0.7776, 0.1755, -0.6038, -0.2696, 0.3127, 0.9108, 0.3587, -0.8564, 0.3714, 0.6704, 0.2807, 0.6868, 0.7096, -0.4201, 0.5657, -0.9800, 0.0156, 0.1981, 0.8985, -0.4318, -0.0794, -0.1104, 0.0362, 0.9932, 0.7715, -0.5821, -0.2569, -0.5135, 0.8460, -0.1439, 0.6899, 0.0417, 0.7227, 0.5910, 0.7712, 0.2364, -0.6635, -0.2871, 0.6909,
0.5207, -0.6842, 0.5107, -0.1577, -0.0478, -0.9863, 0.1087, -0.9851, -0.1336, 0.6247, 0.5053, 0.5953, 0.6052, 0.7791, 0.1634, -0.5807, -0.6709, -0.4612, -0.9690, -0.1285, -0.2110, -0.9940, -0.0522, -0.0963, 0.9273, -0.0862, -0.3643, 0.9266, -0.0923, -0.3646, -0.1140, -0.6543, -0.7476, -0.1246, 0.9858, 0.1123, 0.7633, -0.1616, 0.6255, -0.6412, 0.5628, -0.5216, -0.0468, -0.4998, 0.8648, 0.2016, -0.0579, -0.9777,
-0.6763, -0.5446, -0.4960, -0.2226, 0.9748, -0.0165, -0.0124, 0.0463, -0.9989, -0.0299, 0.9056, 0.4230, -0.0873, 0.9060, 0.4141, 0.5378, 0.4463, 0.7152, 0.9042, -0.2734, -0.3283, 0.8128, 0.4062, -0.4176, 0.7577, 0.2170, 0.6155, -0.3553, -0.7620, -0.5414, 0.7054, 0.6980, 0.1237, 0.5064, -0.1859, -0.8420, 0.1312, 0.0714, 0.9888, -0.9069, -0.4185, -0.0487, 0.1529, -0.0804, -0.9850, -0.3170, -0.8144, 0.4860,
-0.4670, 0.1107, 0.8773, 0.9656, -0.2468, -0.0814, -0.8445, -0.5003, 0.1912, 0.6636, 0.3711, -0.6496, 0.7523, 0.2069, -0.6254, 0.7961, -0.4684, -0.3833, -0.0663, -0.9633, -0.2603, 0.0925, 0.6486, 0.7555, -0.9776, -0.1744, -0.1182, -0.9630, 0.1587, -0.2180, -0.4039, 0.9041, -0.1395, 0.5872, -0.6007, -0.5426, -0.8365, 0.1581, 0.5248, 0.0791, -0.0464, 0.9958, -0.9156, -0.3075, -0.2591, -0.0074, 0.3247, -0.9458,
-0.5099, -0.8558, -0.0875, -0.3571, 0.6811, -0.6392, -0.3801, 0.8828, 0.2761, -0.3206, 0.9471, -0.0126, 0.5847, 0.3574, 0.7283, -0.1430, 0.5509, -0.8223, -0.8991, 0.0089, 0.4376, -0.0971, 0.5304, 0.8422, 0.5430, -0.7243, -0.4250, -0.8236, -0.2315, -0.5177, 0.5440, -0.6857, 0.4835, 0.6169, -0.1565, 0.7713, 0.6983, -0.7090, 0.0983, -0.0413, 0.5741, 0.8177, 0.2390, -0.4560, -0.8573, 0.1930, 0.7617, 0.6185,
-0.0727, -0.9973, -0.0117, 0.7075, -0.6115, -0.3543, -0.2740, -0.6123, 0.7416, -0.1335, -0.2277, 0.9645, 0.9518, 0.0899, -0.2932, 0.9069, -0.2470, -0.3414, -0.0007, -0.7154, 0.6987, -0.0681, -0.7086, 0.7023, -0.0500, 0.5340, 0.8440, -0.9580, 0.2749, -0.0820, 0.9924, 0.0753, 0.0970, 0.3053, -0.2135, 0.9280, 0.7624, -0.2056, 0.6136, 0.7291, -0.5715, -0.3766, 0.2024, 0.0554, -0.9777, 0.3877, 0.9093, 0.1512,
-0.9282, 0.0145, -0.3718, 0.6773, 0.6267, -0.3855, -0.6785, 0.4850, -0.5518, -0.6376, -0.3735, -0.6738, 0.7482, -0.3401, -0.5697, -0.6733, -0.7392, -0.0157, 0.1527, -0.8472, 0.5089, 0.9192, 0.1222, -0.3744, -0.8218, -0.4592, 0.3375, -0.3546, 0.8994, 0.2557, 0.1694, -0.6005, -0.7815, -0.9145, 0.0581, -0.4005, -0.3725, -0.5574, -0.7420, 0.6842, -0.4626, 0.5637, -0.2702, -0.0007, 0.9628, -0.6603, 0.7253, 0.1948,
0.7238, 0.5748, 0.3818, 0.8533, -0.4833, -0.1957, 0.6008, 0.6135, 0.5125, 0.9460, -0.3066, -0.1051, 0.9321, 0.1265, 0.3393, -0.5532, -0.3514, 0.7553, 0.9345, -0.3318, -0.1287, 0.1241, 0.3128, 0.9417, -0.1000, -0.6134, -0.7834, -0.5349, -0.5776, -0.6166, -0.8268, 0.5551, 0.0904, 0.9115, -0.3841, -0.1470, 0.6846, -0.4004, -0.6091, 0.1860, 0.8303, 0.5253, 0.6034, -0.7666, 0.2195, -0.2254, -0.9250, -0.3059,
0.0223, -0.9184, 0.3951, -0.2992, -0.8931, 0.3359, 0.9656, 0.1669, 0.1992, 0.9255, 0.0540, 0.3750, -0.5365, 0.2026, -0.8192, 0.8012, 0.1375, 0.5823, 0.0161, -0.0907, 0.9957, -0.8879, -0.0579, 0.4563, -0.8116, 0.3802, -0.4435, -0.1129, 0.3722, 0.9213, 0.9374, 0.3431, -0.0603, 0.1036, -0.0158, 0.9945, -0.7699, -0.5344, -0.3487, -0.1414, -0.9835, -0.1124, 0.4169, -0.8799, -0.2281, -0.4833, 0.5218, 0.7029,
0.3837, 0.7748, 0.5024, -0.9665, 0.2228, 0.1272, 0.5395, 0.8239, 0.1736, -0.2379, -0.1045, 0.9656, -0.6134, 0.0060, 0.7898, 0.9706, 0.0196, -0.2398, 0.8633, 0.0925, -0.4962, 0.7222, -0.2525, -0.6439, -0.5086, -0.5557, 0.6577, 0.1356, 0.6608, -0.7382, -0.6984, -0.7156, 0.0156, 0.9572, -0.2619, 0.1231, 0.4677, 0.3960, -0.7902, 0.8867, 0.2938, 0.3570, -0.4540, -0.8713, -0.1864, 0.9052, 0.3744, -0.2011,
0.3065, -0.1203, 0.9442, -0.7101, 0.5377, -0.4547, -0.2961, -0.0017, -0.9551, -0.1022, -0.8740, 0.4750, 0.4058, -0.7522, -0.5191, 0.5843, 0.4848, 0.6508, -0.5206, -0.4727, 0.7110, -0.2525, 0.8677, -0.4282, -0.0450, -0.1147, 0.9924, 0.4399, -0.7228, -0.5329, -0.1259, -0.4423, 0.8880, -0.0092, -0.9689, -0.2472, -0.7131, -0.6174, -0.3323, 0.6957, -0.3936, 0.6009, 0.5901, -0.6620, 0.4620, -0.4415, -0.8209, 0.3621,
0.6018, 0.7394, 0.3018, -0.4468, -0.5424, 0.7114, 0.4350, 0.4834, -0.7596, -0.1987, -0.9129, -0.3566, -0.6577, -0.5089, 0.5553, 0.5155, 0.8226, 0.2400, 0.7784, 0.5961, 0.1970, 0.9117, -0.3239, 0.2528, 0.5558, 0.4078, 0.7244, -0.5798, 0.4637, 0.6699, -0.5268, -0.8020, -0.2815, 0.8037, -0.2356, -0.5464, 0.0790, 0.9510, 0.2990, -0.5412, 0.8401, 0.0367, -0.0164, -0.7418, -0.6704, 0.8717, -0.3901, -0.2966,
-0.9327, 0.3498, -0.0876, -0.9155, 0.2229, -0.3350, 0.3503, -0.3955, 0.8490, -0.4118, 0.8762, 0.2504, -0.8862, -0.3089, -0.3453, -0.9839, -0.1638, 0.0718, -0.7136, -0.7006, -0.0063, -0.4590, -0.2035, -0.8648, -0.7219, -0.5866, -0.3670, -0.3418, -0.1979, 0.9187, 0.7914, 0.5919, -0.1530, -0.0899, -0.7204, -0.6877, -0.7942, 0.5047, -0.3383, -0.6956, 0.5559, 0.4551, 0.2363, -0.6789, -0.6951, -0.8747, -0.3554, 0.3295,
-0.3489, -0.0951, -0.9323, 0.7175, 0.6873, 0.1132, -0.1905, 0.7852, -0.5892, -0.0636, -0.5797, 0.8123, -0.1597, -0.9610, -0.2256, -0.1912, 0.8004, -0.5681, -0.5971, -0.7201, -0.3534, -0.7639, 0.1419, -0.6295, -0.1682, 0.9396, 0.2981, -0.8426, -0.5232, 0.1272, -0.1152, 0.9829, 0.1438, 0.1910, -0.4843, 0.8538, 0.7191, 0.5701, 0.3974, 0.9681, 0.0461, 0.2463, 0.5958, -0.4384, 0.6730, 0.7497, 0.4572, 0.4784,
-0.1496, 0.9676, -0.2035, -0.6357, -0.2450, -0.7321, 0.7783, -0.2776, -0.5631, -0.3598, -0.6720, 0.6473, 0.7399, 0.2722, 0.6152, 0.5749, 0.3665, 0.7316, 0.9095, 0.3655, 0.1982, 0.0215, 0.0362, 0.9991, 0.9722, 0.1588, 0.1722, -0.8239, 0.0991, -0.5579, -0.3807, -0.9028, -0.2003, -0.3909, -0.8983, -0.2003, -0.0000, 0.0000, -1.0000, -0.0004, 0.0000, -1.0000, -0.0022, 0.0001, -1.0000, -0.0003, -0.0000, -1.0000,
-0.0000, 0.0000, -1.0000, 0.0000, 0.0000, -1.0000, 0.0000, 0.0000, -1.0000, -0.0035, -0.0003, -1.0000, -0.0000, -0.0000, -1.0000, 0.0000, -0.0000, -1.0000, -0.0000, 0.0000, -1.0000, -0.0000, -0.0000, -1.0000, 0.0000, -0.0000, -1.0000, 0.0001, 0.0000, -1.0000, 0.0000, 0.0000, -1.0000, -0.0000, 0.0000, -1.0000, -0.0002, -0.0000, -1.0000, -0.0000, 0.0000, -1.0000, 0.0002, 0.0001, -1.0000, 0.9763, 0.1942, -0.0955,
0.7008, -0.6868, 0.1929, -0.4634, -0.8846, -0.0524, 0.9926, -0.1127, 0.0449, 0.8931, 0.4471, -0.0502, -0.9465, 0.3190, 0.0485, -0.8639, 0.4927, 0.1046, -0.9981, 0.0621, 0.0009, 0.8914, -0.4008, 0.2116, 0.0187, -0.9927, -0.1187, -0.6381, -0.7607, 0.1189, -0.9699, -0.2241, 0.0953, -0.4794, 0.8718, 0.1008, -0.7096, 0.6987, 0.0904, -0.1307, 0.9893, 0.0650, 0.4929, -0.8587, 0.1402, 0.6251, -0.7757, -0.0873,
-0.8682, -0.4861, 0.1000, 0.2337, -0.9591, 0.1598, 0.2201, 0.9634, 0.1529, 0.4054, 0.9092, -0.0947, 0.0502, -0.0071, 0.9987, 0.9152, 0.1555, 0.3717, -0.8875, 0.2587, 0.3813, -0.0220, -0.0137, 0.9997, -0.0031, 0.0127, 0.9999, -0.5825, 0.5449, -0.6032, 0.8874, -0.4604, -0.0246, 0.6426, 0.6475, -0.4098, 0.1063, -0.9914, 0.0760, -0.9721, 0.2267, 0.0603, -0.1403, -0.9447, 0.2964, -0.9594, -0.1376, 0.2463,
0.0959, 0.6401, -0.7623, -0.8635, 0.4859, -0.1354, 0.2008, -0.8184, 0.5384, 0.4046, -0.9139, 0.0337, 0.9878, 0.0534, -0.1461, 0.9966, -0.0024, -0.0826, 0.9903, -0.1307, -0.0476, 0.2223, -0.3042, 0.9263, 0.1824, 0.6304, 0.7545, 0.1316, 0.1048, 0.9857, -0.3406, -0.0716, -0.9375, -0.8471, 0.0812, -0.5253, 0.4991, -0.0711, 0.8636, 0.5776, 0.6771, 0.4559, 0.5264, 0.8041, 0.2763, -0.5442, 0.8265, 0.1436,
-0.7209, -0.4963, 0.4837, 0.2911, 0.1792, 0.9398, 0.0037, 0.2364, 0.9717, 0.8980, -0.3747, 0.2307, 0.7658, -0.5898, -0.2562, -0.3134, 0.6866, -0.6561, 0.9770, -0.1154, 0.1795, -0.1388, -0.9105, 0.3895, 0.5316, -0.8467, -0.0222, 0.8929, -0.4283, -0.1385, -0.1129, -0.9819, 0.1519, 0.2705, 0.7906, 0.5494, -0.1301, -0.6821, -0.7196, 0.1930, 0.9186, 0.3448, 0.6350, -0.6552, -0.4092, 0.3367, 0.8276, 0.4491,
0.4875, -0.8321, 0.2645, 0.5683, -0.7158, -0.4057, 0.5052, -0.8572, 0.0998, 0.9428, 0.3115, 0.1189, 0.0316, -0.0542, 0.9980, 0.9304, -0.0359, -0.3648, -0.9956, 0.0929, -0.0078, 0.0085, -0.7250, -0.6887, 0.9790, -0.0487, -0.1978, -0.2375, 0.9407, 0.2421, 0.0151, -0.4169, 0.9088, -0.1421, 0.9321, 0.3332, 0.3985, 0.6855, 0.6093, 0.0717, 0.8034, 0.5912, -0.8991, 0.2203, 0.3782, 0.8665, -0.0153, -0.4989,
-0.7705, -0.4649, -0.4361, -0.4112, 0.8511, -0.3264, -0.6334, 0.7731, 0.0330, 0.2590, -0.1665, 0.9514, -0.4589, 0.7963, -0.3941, -0.1508, -0.9123, 0.3808, -0.9576, 0.0565, -0.2824, -0.1437, 0.2443, -0.9590, 0.5144, 0.8067, 0.2908, -0.4599, 0.8186, 0.3441, -0.9968, -0.0799, 0.0066, -0.3939, 0.3495, 0.8501, 0.9087, -0.3345, -0.2496, 0.8625, -0.2084, -0.4612, 0.7894, 0.6122, 0.0464, -0.8902, -0.1120, 0.4416,
0.4078, -0.6535, 0.6377, 0.0586, 0.7823, -0.6201, -0.9636, 0.1959, 0.1817, -0.8657, -0.4931, -0.0857, 0.7071, 0.5276, 0.4709, 0.6588, 0.7190, 0.2212, 0.0895, -0.9685, -0.2323, 0.9027, -0.2578, -0.3444, -0.9847, -0.1729, 0.0228, -0.2917, -0.7289, 0.6194, 0.7650, 0.6159, 0.1884, -0.1339, -0.6884, -0.7129, -0.8765, 0.2485, 0.4122, 0.3552, -0.6834, 0.6378, -0.1000, -0.9517, -0.2903, 0.0247, 0.9121, 0.4092,
0.4720, -0.8518, 0.2272, -0.9354, -0.0522, -0.3497, -0.0297, 0.0135, 0.9995, 0.4183, -0.8871, 0.1952, 0.2175, 0.9444, 0.2465, -0.6095, -0.4762, 0.6338, 0.4748, -0.8779, 0.0615, 0.6855, -0.7191, -0.1139, -0.7755, 0.6311, 0.0167, -0.5508, -0.6462, -0.5282, -0.9915, -0.0062, 0.1299, -0.0943, -0.9916, 0.0882, 0.3445, -0.8011, 0.4894, -0.9112, 0.0297, -0.4110, -0.3660, 0.5427, 0.7559, -0.3428, 0.1563, 0.9263,
0.5686, 0.8225, 0.0151, -0.9573, -0.2834, -0.0570, -0.8836, -0.4678, -0.0208, 0.5644, -0.3411, -0.7518, -0.8823, 0.1799, -0.4351, -0.3036, -0.6249, -0.7192, -0.7132, -0.3146, 0.6264, -0.8535, -0.4938, 0.1667, 0.5556, 0.8265, -0.0905, -0.9091, -0.4151, 0.0341, -0.3301, -0.5859, -0.7401, 0.9744, 0.1611, -0.1571, 0.0257, 0.3183, 0.9476, -0.7104, 0.6979, -0.0911, 0.9101, 0.0217, -0.4138, 0.0523, 0.9986, 0.0115,
-0.2117, -0.8225, 0.5278, 0.9833, 0.1113, -0.1442, -0.9423, 0.0434, -0.3320, -0.9258, 0.3405, 0.1640, -0.1268, 0.9917, 0.0201, -0.5718, 0.5468, 0.6116, -0.2515, -0.0604, -0.9660, 0.0774, -0.3962, 0.9149, -0.6639, -0.4551, -0.5934, -0.1948, 0.6174, -0.7622, -0.2944, 0.7249, 0.6227, -0.9470, -0.1737, 0.2701, -0.9615, 0.2732, 0.0296, -0.3506, -0.7733, -0.5282, -0.9120, -0.2455, -0.3285, 0.4946, 0.6858, -0.5339,
-0.9201, 0.1887, 0.3432, 0.0410, -0.4393, -0.8974, 0.9348, 0.3491, 0.0645, 0.9992, 0.0065, -0.0399, 0.2763, -0.2233, 0.9348, -0.4777, 0.8637, 0.1605, -0.9759, 0.1616, -0.1468, -0.9580, -0.1733, -0.2283, -0.9546, -0.1742, -0.2418, 0.2284, -0.9207, -0.3166, 0.0928, 0.0435, 0.9947, -0.7938, -0.4573, -0.4011, -0.6423, 0.5065, 0.5752, -0.5599, 0.7977, 0.2240, 0.2076, 0.9175, 0.3393, -0.6892, -0.4931, -0.5310,
-0.0769, 0.3639, 0.9282, -0.0452, 0.9572, 0.2857, 0.5039, 0.8368, 0.2142, -0.8183, -0.1199, 0.5621, 0.4469, -0.3872, -0.8065, 0.2273, 0.9241, 0.3073, -0.9308, -0.1467, -0.3349, 0.9196, -0.1371, 0.3681, 0.3391, 0.9079, 0.2464, -0.2256, -0.9731, 0.0458, 0.9908, 0.0864, -0.1040, 0.7752, -0.5784, -0.2541, -0.9718, 0.2353, 0.0153, 0.4329, 0.8812, 0.1899, 0.5307, -0.0201, 0.8473, -0.5498, 0.1606, 0.8197,
0.9826, -0.0999, -0.1569, 0.8016, -0.3876, 0.4552, -0.9654, -0.1440, -0.2172, 0.2478, -0.5443, -0.8015, 0.8929, -0.0170, -0.4499, 0.9551, 0.1856, -0.2308, 0.7736, -0.4780, 0.4160, -0.0396, -0.0325, 0.9987, -0.9993, 0.0015, 0.0377, 0.4546, -0.7157, 0.5302, 0.8782, 0.4562, 0.1440, -0.5906, -0.6574, -0.4681, 0.8481, -0.3997, 0.3479, -0.8224, 0.1815, 0.5392, 0.2897, -0.7068, 0.6454, 0.9795, 0.1847, -0.0804,
0.4008, -0.0553, -0.9145, -0.7904, -0.4938, -0.3624, 0.7719, -0.5682, -0.2851, 0.5630, -0.6380, 0.5254, 0.0562, 0.7917, -0.6083, -0.3552, 0.8846, -0.3023, 0.9565, -0.0065, 0.2915, 0.4585, -0.8149, -0.3546, 0.6342, -0.1558, 0.7573, -0.5788, -0.6000, -0.5523, -0.6422, 0.3147, 0.6989, -0.5763, 0.7086, 0.4071, -0.9272, -0.3289, -0.1790, 0.2931, 0.9455, 0.1417, 0.7793, -0.5369, 0.3232, -0.8074, 0.5730, -0.1408,
-0.8369, -0.2181, -0.5020, -0.3752, 0.6959, 0.6123, 0.0781, 0.1285, 0.9886, -0.5288, 0.4246, 0.7349, -0.3363, 0.7010, -0.6289, -0.6946, 0.4663, 0.5478, 0.7435, -0.5360, -0.4000, 0.6107, -0.4545, 0.6484, -0.5305, -0.2958, 0.7944, -0.9915, -0.0342, 0.1255, 0.9734, 0.1064, -0.2030, 0.6823, -0.5994, -0.4185, 0.0805, -0.6530, 0.7530, -0.9717, -0.1275, 0.1991, -0.0212, -0.6569, 0.7536, 0.0313, -0.5778, -0.8156,
0.5672, 0.0214, 0.8233, -0.7878, -0.2984, -0.5389, -0.9461, -0.0812, 0.3137, -0.1978, 0.6945, 0.6918, -0.0824, 0.9963, 0.0235, 0.2205, -0.5882, 0.7781, -0.0484, -0.0656, 0.9967, 0.0047, 0.1252, 0.9921, 0.9476, -0.0571, -0.3142, -0.2458, 0.3360, 0.9092, -0.7790, 0.5644, 0.2733, -0.2361, 0.9694, -0.0670, 0.9708, -0.0962, 0.2199, 0.9206, 0.3893, 0.0298, 0.8195, 0.5652, 0.0948, -0.1847, 0.9126, 0.3647,
-0.2758, -0.0016, 0.9612, -0.6803, -0.7280, -0.0851, -0.6066, 0.0274, -0.7945, -0.4820, -0.8711, -0.0942, -0.8880, -0.1644, -0.4295, -0.1680, -0.6972, -0.6970, -0.9712, -0.1968, -0.1342, -0.7024, 0.6388, 0.3140, -0.2919, 0.8561, 0.4265, 0.7560, -0.6540, 0.0285, 0.0895, -0.6565, 0.7490, 0.4941, -0.4787, -0.7258, 0.6282, -0.4041, -0.6649, 0.6329, -0.5370, -0.5577, 0.7338, -0.6710, -0.1067, -0.5546, -0.7808, -0.2878,
0.7710, -0.4095, -0.4878, 0.5505, -0.8261, 0.1205, -0.9329, 0.1957, 0.3022, 0.9793, 0.1322, -0.1532, -0.3566, 0.7529, 0.5531, -0.9814, -0.1814, -0.0631, -0.4358, 0.8966, -0.0790, 0.3651, -0.9197, -0.1448, 0.9812, -0.1575, -0.1120, -0.9554, 0.2925, -0.0401, 0.9119, -0.1020, 0.3974, 0.9941, 0.0521, 0.0954, 0.9828, -0.1232, 0.1376, 0.0356, 0.9891, 0.1430, 0.5573, -0.2902, -0.7779, 0.4904, -0.4362, 0.7545,
-0.7920, -0.5926, -0.1467, 0.8734, -0.3768, -0.3084, 0.9177, 0.1777, 0.3552, 0.9504, -0.3015, -0.0763, 0.3333, 0.6839, -0.6490, 0.0117, 0.6948, 0.7191, -0.9413, -0.1858, 0.2818, 0.5712, -0.8175, -0.0738, -0.7128, -0.4194, -0.5622, 0.3143, 0.4663, -0.8269, 0.8155, 0.1112, 0.5680, -0.6548, 0.5096, 0.5582, 0.2425, 0.7893, 0.5641, -0.0154, 0.8578, 0.5138, -0.4769, -0.8634, 0.1649, 0.6689, -0.6487, -0.3630,
0.0826, 0.3501, 0.9331, -0.9528, 0.1853, 0.2403, 0.3550, 0.1902, 0.9153, 0.9469, 0.3189, 0.0409, -0.7054, -0.0236, -0.7084, 0.5825, -0.8098, 0.0701, 0.9237, 0.3824, -0.0229, 0.9917, -0.0516, 0.1176, 0.9621, 0.0252, 0.2715, 0.4805, 0.8769, -0.0117, 0.9893, 0.0335, -0.1421, -0.2198, -0.9186, 0.3284, 0.8460, -0.1588, -0.5090, -0.8581, 0.5133, -0.0104, 0.8587, -0.1841, 0.4782, 0.9959, -0.0901, 0.0033,
-0.9149, -0.2385, 0.3258, -0.6895, -0.3897, 0.6106, 0.8259, -0.0900, -0.5565, -0.5521, 0.7563, -0.3510, 0.8781, -0.2721, -0.3936, 0.8206, 0.4551, 0.3457, -0.5493, 0.7495, -0.3695, -0.0583, -0.1391, 0.9886, -0.4125, -0.8722, -0.2631, 0.7953, -0.6015, -0.0761, 0.3878, -0.9188, -0.0734, 0.0184, -0.0126, 0.9998, 0.7807, 0.6111, 0.1303, -0.2147, -0.9164, 0.3378, 0.1107, 0.9883, 0.1049, 0.6564, 0.2862, 0.6980,
0.3544, -0.7073, 0.6116, 0.2890, -0.7755, 0.5613, -0.8971, -0.1201, 0.4251, -0.7769, -0.0982, 0.6219, -0.8494, -0.2453, -0.4673, 0.9801, -0.0361, 0.1950, -0.7030, -0.3433, -0.6228, -0.3499, -0.4715, 0.8095, 0.1047, 0.9749, 0.1963, 0.3261, 0.3175, 0.8904, 0.5638, 0.5671, 0.6004, -0.3808, -0.6436, -0.6639, 0.4807, -0.8318, -0.2776, 0.8480, 0.2911, -0.4429, -0.0211, -0.0142, 0.9997, -0.3064, -0.8207, 0.4823,
-0.9868, -0.0155, 0.1611, -0.9058, -0.1359, -0.4014, -0.4664, 0.8655, -0.1828, -0.9128, 0.1817, 0.3656, -0.7852, -0.3355, -0.5204, 0.7322, 0.6300, 0.2587, -0.2030, 0.9791, -0.0128, 0.9958, -0.0791, 0.0456, -0.9856, 0.0110, -0.1688, -0.8791, 0.2344, -0.4150, 0.9052, -0.3638, 0.2196, 0.9230, 0.0859, -0.3750, 0.9151, 0.4013, -0.0389, 0.9709, 0.0735, -0.2281, 0.0226, 0.0199, 0.9995, 0.6067, -0.4902, 0.6259,
0.0975, -0.2346, -0.9672, 0.5305, 0.0111, 0.8476, -0.9459, -0.0731, 0.3161, 0.5849, 0.7731, -0.2452, 0.1115, 0.1832, -0.9767, 0.4180, -0.7919, -0.4452, -0.6370, 0.0986, 0.7645, 0.1964, 0.0042, 0.9805, -0.6965, 0.6951, 0.1783, -0.5846, 0.3295, 0.7414, -0.5552, 0.7030, 0.4445, 0.1197, 0.4974, 0.8592, -0.1122, 0.9577, -0.2649, 0.2391, -0.6299, 0.7390, 0.7140, -0.0127, -0.7000, -0.6851, 0.7162, -0.1326,
0.6280, 0.1852, -0.7558, -0.1489, 0.9773, 0.1509, 0.8707, -0.1099, -0.4793, -0.9243, 0.3390, -0.1753, 0.2315, -0.5789, 0.7818, -0.9518, -0.1617, 0.2607, -0.4973, 0.0389, -0.8667, 0.0690, 0.7638, 0.6417, -0.8900, -0.3039, -0.3398, -0.9625, -0.1489, -0.2266, 0.4705, -0.8363, 0.2815, 0.1670, -0.8289, -0.5339, -0.9307, 0.0697, 0.3592, -0.3856, 0.8087, 0.4442, 0.7824, 0.4786, -0.3984, 0.0379, 0.0132, 0.9992,
0.8835, -0.0730, 0.4626, -0.9994, -0.0242, 0.0264, -0.9818, 0.1137, -0.1522, -0.8821, -0.0663, 0.4664, -0.4470, -0.5833, -0.6782, 0.9999, 0.0111, 0.0128, -0.7426, -0.5917, -0.3136, 0.5735, 0.2959, 0.7639, 0.2851, -0.9375, 0.1994, 0.9000, 0.4279, 0.0831, 0.6998, -0.2213, 0.6792, 0.9990, 0.0117, -0.0443, 0.6043, 0.7472, -0.2764, 0.7086, -0.0942, -0.6992, -0.8652, -0.1398, 0.4816, -0.3023, 0.4497, 0.8405,
-0.8617, -0.3574, -0.3602, 0.7356, -0.3368, 0.5877, 0.7339, -0.3601, 0.5759, 0.1208, 0.9869, -0.1068, -0.3913, -0.9120, 0.1229, 0.8461, -0.5083, -0.1601, 0.9100, 0.4100, 0.0620, -0.0670, -0.9860, 0.1528, 0.9841, 0.1289, 0.1224, 0.4618, 0.8812, 0.1009, -0.6752, 0.7367, -0.0372, -0.1695, 0.9850, -0.0333, 0.4416, 0.0506, 0.8958, -0.0404, 0.9920, 0.1199, 0.3084, -0.9005, 0.3065, 0.2721, -0.7857, 0.5555,
-0.9356, -0.3232, -0.1420, 0.5916, -0.0448, 0.8050, -0.1485, 0.9711, 0.1866, -0.7651, 0.2850, 0.5774, 0.3931, 0.6799, -0.6190, -0.1620, 0.9642, 0.2098, 0.5294, -0.6116, -0.5880, -0.2541, -0.8255, -0.5040, -0.3943, 0.9113, -0.1190, 0.4131, -0.8217, -0.3927, -0.7185, 0.6952, 0.0198, 0.9296, -0.3577, 0.0893, -0.9483, 0.2779, -0.1533, 0.2302, -0.8838, -0.4073, 0.3016, -0.2615, 0.9169, -0.3822, -0.8096, 0.4455,
-0.9545, -0.2820, 0.0972, 0.6359, 0.7694, -0.0607, -0.7877, -0.3509, -0.5063, -0.9678, -0.2056, 0.1450, -0.9680, -0.2076, 0.1411, 0.9655, 0.0391, 0.2574, 0.2745, -0.9544, 0.1171, 0.3346, -0.9128, 0.2342, -0.4411, -0.5297, 0.7245, -0.7566, 0.4247, -0.4973, -0.1290, 0.9584, -0.2546, -0.9161, -0.0007, -0.4009, 0.0602, -0.9894, -0.1323, -0.0709, -0.9805, 0.1835, -0.6428, 0.0359, -0.7652, 0.5005, 0.1313, -0.8557,
-0.9176, 0.3719, 0.1406, 0.9688, 0.2038, 0.1410, -0.9824, -0.1813, -0.0456, -0.0013, -0.5711, 0.8209, -0.1908, 0.9809, -0.0375, 0.3702, 0.5444, 0.7527, -0.9460, -0.1642, 0.2796, -0.7952, -0.5030, -0.3386, -0.8003, -0.2360, 0.5512, -0.2254, 0.9595, 0.1689, 0.6725, 0.2695, 0.6892, 0.7956, -0.1123, 0.5954, 0.2858, -0.9212, 0.2639, 0.3343, -0.7558, 0.5631, -0.9123, 0.3916, 0.1197, 0.5826, -0.8034, -0.1233,
-0.9489, 0.1479, 0.2788, 0.0157, 0.9890, 0.1473, -0.4246, -0.8189, -0.3861, 0.4905, 0.7372, -0.4648, -0.3180, 0.7462, 0.5848, -0.3307, 0.7651, 0.5525, -0.9711, 0.0300, -0.2366, -0.2899, -0.9298, -0.2267, -0.0458, 0.9744, 0.2201, -0.5450, -0.7092, 0.4472, -0.9289, -0.0519, -0.3668, -0.1643, -0.8620, -0.4796, 0.3799, -0.9223, 0.0701, 0.2748, -0.3172, 0.9077, 0.0850, 0.3091, 0.9472, 0.2981, -0.6527, -0.6965,
0.9956, 0.0249, -0.0899, -0.8688, 0.0649, -0.4909, 0.6938, 0.7187, -0.0453, -0.8401, -0.5425, -0.0056, 0.8886, -0.3313, -0.3173, 0.8041, 0.3712, 0.4644, 0.0809, -0.6685, -0.7393, -0.0736, 0.2414, -0.9676, -0.8294, -0.1896, 0.5255, -0.8057, -0.5923, -0.0068, 0.3815, 0.7645, 0.5196, 0.4273, 0.0498, -0.9027, 0.9681, 0.2494, 0.0243, -0.3796, -0.6279, -0.6794, -0.9518, 0.2685, -0.1481, 0.9563, 0.1171, -0.2680,
-0.1545, 0.9868, -0.0477, 0.8553, -0.4956, -0.1508, -0.1625, -0.9792, -0.1213, -0.9337, -0.3581, -0.0033, 0.1550, 0.1364, 0.9784, -0.9412, 0.1150, 0.3177, -0.5229, -0.7069, 0.4764, 0.6528, 0.7519, 0.0922, 0.4484, 0.8937, 0.0132, -0.7090, 0.3505, -0.6120, 0.5770, 0.8103, 0.1020, 0.5873, -0.0730, 0.8060, -0.5333, 0.2185, 0.8172, -0.6869, 0.6899, 0.2285, -0.0677, 0.1353, 0.9885, -0.8709, 0.2250, 0.4370,
0.4890, -0.3711, -0.7894, -0.6813, -0.7298, -0.0567, -0.8306, 0.5523, -0.0705, -0.9819, -0.1439, -0.1232, -0.9874, -0.0278, -0.1560, 0.1772, 0.5152, 0.8385, 0.2654, 0.0151, 0.9640, 0.9884, 0.1518, -0.0029, 0.9682, -0.1683, 0.1848, 0.9805, 0.1817, 0.0747, -0.3628, -0.7213, -0.5900, -0.0720, 0.9262, 0.3702, 0.4110, -0.7907, -0.4537, -0.4171, -0.9088, -0.0039, -0.9055, -0.0958, -0.4134, 0.8570, 0.3468, -0.3811,
0.1786, 0.7216, 0.6689, -0.9132, -0.3345, 0.2326, -0.9168, -0.3197, 0.2394, 0.4250, 0.9051, -0.0106, -0.1144, 0.8446, 0.5229, -0.9011, -0.4267, 0.0768, -0.9007, -0.4288, 0.0702, 0.9015, 0.4161, -0.1187, 0.4244, -0.8804, -0.2116, 0.0447, -0.0849, 0.9954, -0.8758, -0.0743, -0.4769, -0.7345, 0.1087, 0.6698, -0.4923, 0.5043, -0.7095, -0.9560, -0.2167, -0.1978, -0.6295, 0.1827, -0.7552, -0.8047, -0.1155, 0.5823,
-0.0135, 0.4954, 0.8686, 0.1826, -0.7607, 0.6229, 0.8925, -0.0569, 0.4475, 0.9230, 0.3464, -0.1678, -0.9121, -0.3875, 0.1340, 0.1116, 0.9905, 0.0802, 0.2638, 0.8225, 0.5038, 0.8598, 0.0924, 0.5021, 0.9838, -0.1611, -0.0790, -0.8666, -0.1895, -0.4615, 0.2066, 0.6716, 0.7116, -0.7973, -0.0393, -0.6023, 0.0101, 0.0213, 0.9997, -0.4002, -0.1985, -0.8947, -0.4878, -0.3975, 0.7772, 0.3681, -0.7790, 0.5075,
0.4911, -0.7871, 0.3734, -0.4146, -0.3917, 0.8214, 0.8075, -0.0099, 0.5898, 0.1614, 0.7723, 0.6144, 0.8256, -0.1322, 0.5486, 0.4618, 0.6108, 0.6431, -0.8486, -0.1856, 0.4955, 0.8139, 0.5182, 0.2627, -0.9928, 0.0279, 0.1165, 0.4914, 0.1727, 0.8536, -0.8313, -0.1693, 0.5294, 0.9538, -0.1422, -0.2647, -0.4151, 0.9054, -0.0892, -0.0974, 0.0564, 0.9936, -0.3846, 0.9197, 0.0786, 0.5901, 0.2943, 0.7518,
-0.2104, 0.2083, 0.9552, -0.6417, -0.7488, 0.1656, 0.0194, -0.0092, 0.9998, 0.5080, -0.7802, 0.3649, 0.2130, -0.9478, -0.2372, 0.9577, -0.2564, 0.1308, 0.7912, 0.3370, -0.5104, 0.7328, 0.2592, 0.6291, -0.1836, 0.9057, -0.3822, -0.7698, 0.1231, 0.6263, 0.7907, -0.5196, -0.3236, -0.9177, -0.3207, 0.2344, 0.9454, -0.3223, 0.0476, 0.5652, 0.7347, 0.3751, -0.9994, -0.0357, 0.0042, -0.9927, 0.0586, -0.1056,
-0.6384, -0.5618, -0.5262, -0.2353, -0.3364, -0.9119, -0.8836, 0.2008, -0.4230, 0.8122, -0.5587, 0.1677, -0.7138, 0.6165, 0.3323, 0.7909, -0.6092, 0.0575, 0.7045, -0.4099, -0.5793, -0.2510, -0.8639, 0.4366, 0.9012, -0.4323, -0.0301, 0.2981, -0.0233, 0.9543, -0.0249, 0.9669, 0.2541, 0.9622, 0.1262, 0.2414, 0.9089, 0.2015, -0.3650, -0.2598, -0.9612, -0.0928, -0.9946, 0.0820, 0.0637, -0.8531, -0.5194, -0.0503,
0.7812, -0.0939, 0.6171, -0.9922, -0.1031, 0.0697, -0.4070, -0.8891, -0.2095, 0.8044, 0.1362, -0.5783, 0.8933, -0.2858, 0.3468, -0.7083, -0.0431, -0.7046, 0.0511, 0.9453, 0.3223, 0.2942, 0.8983, 0.3265, 0.5953, -0.2583, -0.7608, 0.8342, 0.1288, 0.5362, -0.3827, -0.8581, -0.3422, -0.0221, 0.0057, 0.9997, 0.4015, 0.9157, 0.0155, -0.9722, 0.1020, 0.2109, 0.6081, -0.6512, -0.4541, -0.6939, 0.5672, 0.4436,
-0.8058, 0.3563, 0.4731, 0.5599, -0.4319, -0.7071, 0.6252, -0.4549, -0.6341, 0.8746, 0.3991, 0.2754, -0.0479, -0.1067, 0.9931, 0.8597, -0.3040, -0.4106, -0.9232, 0.1223, 0.3644, 0.4454, -0.8664, -0.2256, 0.0514, 0.4510, 0.8910, 0.2421, -0.6356, 0.7330, -0.5360, -0.5351, -0.6530, 0.1046, -0.0629, 0.9925, -0.2222, 0.9718, 0.0791, -0.6928, 0.6151, 0.3764, -0.1405, -0.3031, -0.9425, 0.9960, 0.0696, 0.0559,
0.1781, 0.9324, 0.3146, -0.5803, -0.6715, -0.4607, 0.3159, 0.9485, -0.0229, 0.7192, -0.1970, 0.6663, -0.6291, 0.5063, -0.5898, -0.3158, 0.7565, 0.5726, 0.8178, -0.5345, -0.2133, -0.1899, 0.6817, -0.7066, 0.9415, 0.2927, 0.1668, 0.8202, 0.5225, 0.2331, 0.5949, 0.0133, 0.8037, -0.9190, 0.1665, 0.3573, -0.8965, 0.3941, -0.2025, 0.5165, -0.4651, -0.7190, 0.5170, -0.8547, 0.0470, 0.9249, 0.1967, 0.3254,
-0.5885, -0.3075, 0.7478, -0.8840, -0.4413, -0.1544, -0.6807, -0.3743, -0.6297, 0.2214, -0.8777, -0.4249, 0.8759, 0.3127, 0.3675, -0.6539, 0.6821, 0.3274, 0.4504, 0.8535, 0.2622, 0.7480, 0.6413, 0.1709, 0.8364, -0.5225, -0.1658, -0.0495, 0.8756, 0.4806, 0.8110, -0.4998, -0.3041, -0.0009, 0.0218, 0.9998, -0.2891, 0.7210, -0.6298, -0.2929, 0.5382, 0.7903, -0.0644, 0.0939, 0.9935, 0.9637, 0.2618, 0.0516,
0.1575, -0.9842, -0.0807, 0.5927, -0.6412, -0.4875, -0.6262, -0.6417, 0.4429, 0.5621, -0.7706, 0.3005, -0.8232, -0.5572, -0.1089, 0.6541, 0.1972, 0.7303, -0.3291, 0.9105, 0.2505, 0.0645, -0.9035, 0.4237, 0.9848, 0.1521, -0.0838, 0.3609, 0.4155, 0.8349, -0.2614, 0.9227, 0.2834, 0.9587, -0.1173, -0.2591, 0.6546, -0.6645, 0.3605, 0.3394, 0.9258, 0.1661, 0.7378, 0.6716, 0.0676, -0.6921, 0.7209, 0.0376,
0.9456, -0.1300, -0.2983, -0.1382, 0.9856, 0.0978, -0.6081, -0.4425, 0.6591, 0.7463, -0.5339, -0.3975, 0.1742, 0.9283, 0.3284, -0.0204, -0.0081, 0.9998, -0.0087, 0.9969, -0.0784, 0.1689, 0.5565, 0.8135, };
};

View file

@ -0,0 +1,102 @@
//This example shows how a custom VGA resolution can be created for one of the base modes
//You need to connect a VGA screen cable to the pins specified below.
//cc by-sa 4.0 license
//bitluni
//including the needed header
#include <ESP32Lib.h>
#include <Ressources/Font6x8.h>
//pin configuration
const int redPin = 14;
const int greenPin = 19;
const int bluePin = 27;
const int hsyncPin = 32;
const int vsyncPin = 33;
//VGA Device using an interrupt to unpack the pixels from 4bit to 16bit for the I²S
//This takes some CPU time in the background but is able to fit a frame buffer in the memory
VGA3Bit vga;
void setup()
{
Serial.begin(115200);
//enabling double buffering
vga.setFrameBufferCount(2);
//Mode::custom(xres, yres, fixedYDivider = 1) calculates the parameters for our custom resolution.
//the y resolution is only scaling integer divisors (yet).
//if you don't like to let it scale automatically pass a fixed parameter with a fixed divider.
Mode myMode = vga.MODE640x480.custom(80, 60);
//print the parameters
myMode.print<HardwareSerial>(Serial);
//use the mode
vga.init(myMode, redPin, greenPin, bluePin, hsyncPin, vsyncPin);
//setting the font
vga.setFont(Font6x8);
}
///draws a bouncing balls
void balls()
{
//some basic gravity physics
static VGA3BitI::Color c[4] = {vga.RGB(0, 255, 0), vga.RGB(0, 255, 255), vga.RGB(255, 0, 255), vga.RGB(255, 255, 0)};
static float y[4] = {20, 20, 20, 20};
static float x[4] = {20, 20, 20, 20};
static float vx[4] = {.01, -0.07, .05, -.03};
static float vy[4] = {0, 1, 2, 3};
static unsigned long lastT = 0;
unsigned long t = millis();
float dt = (t - lastT) * 0.001f;
lastT = t;
const int r = 6;
for (int i = 0; i < 4; i++)
{
int rx = r;
int ry = r;
vy[i] += -9.81f * dt * 100;
x[i] += vx[i];
y[i] += vy[i] * dt;
//check for boundaries and bounce back
if (y[i] < r && vy[i] < 0)
{
vy[i] = 200 + i * 10;
ry = y[i];
}
if (x[i] < r && vx[i] < 0)
{
vx[i] = -vx[i];
rx = x[i];
}
if (x[i] >= vga.xres - r && vx[i] > 0)
{
vx[i] = -vx[i];
rx = vga.xres - x[i];
}
//draw a filled ellipse
vga.fillEllipse(x[i], vga.yres - y[i] - 1, rx, ry, c[i]);
vga.ellipse(x[i], vga.yres - y[i] - 1, rx, ry, 0);
}
}
//mainloop
void loop()
{
//draw a background
for (int y = 0; y * 10 < vga.yres; y++)
for (int x = 0; x * 10 < vga.xres; x++)
vga.fillRect(x * 10, y * 10, 10, 10, (x + y) & 1 ? vga.RGB(255, 0, 0) : vga.RGB(255, 255, 255));
//text position
vga.setCursor(2, 2);
//black text color no background color
vga.setTextColor(vga.RGB(0));
//show the remaining memory
vga.print(vga.xres);
vga.print("x");
vga.println(vga.yres);
vga.print("free memory: ");
vga.print((int)heap_caps_get_free_size(MALLOC_CAP_DEFAULT));
//draw bouncing balls
balls();
//show the backbuffer (only needed when using backbuffering)
vga.show();
}

View file

@ -0,0 +1,71 @@
//This example shows how to animate graphics on a VGA screen. No backbuffering is used... just try it.
//You need to connect a VGA screen cable and an external DAC (simple R2R does the job) to the pins specified below.
//cc by-sa 4.0 license
//bitluni
#include <ESP32Lib.h>
#include <Ressources/Font6x8.h>
#include <math.h>
//pin configuration
const int redPins[] = {2, 4, 12, 13, 14};
const int greenPins[] = {15, 16, 17, 18, 19};
const int bluePins[] = {21, 22, 23, 27};
const int hsyncPin = 32;
const int vsyncPin = 33;
//VGA Device
VGA14Bit vga;
//initial setup
void setup()
{
//initializing i2s vga (with only one framebuffer)
vga.init(vga.MODE200x150, redPins, greenPins, bluePins, hsyncPin, vsyncPin);
//setting the font
vga.setFont(Font6x8);
}
//the loop is done every frame
void loop()
{
//setting the text cursor to the lower left corner of the screen
vga.setCursor(0, vga.yres - 8);
//setting the text color to white with opaque black background
vga.setTextColor(vga.RGB(0xffffff), vga.RGBA(0, 0, 0, 255));
//printing the fps
vga.print("fps: ");
static long f = 0;
vga.print(long((f++ * 1000) / millis()));
//circle parameters
float factors[][2] = {{1, 1.1f}, {0.9f, 1.02f}, {1.1, 0.8}};
int colors[] = {vga.RGB(0xff0000), vga.RGB(0x00ff00), vga.RGB(0x0000ff)};
//animate them with milliseconds
float p = millis() * 0.002f;
for (int i = 0; i < 3; i++)
{
//calculate the position
int x = vga.xres / 2 + sin(p * factors[i][0]) * vga.xres / 3;
int y = vga.yres / 2 + cos(p * factors[i][1]) * vga.yres / 3;
//clear the center with a black filled circle
vga.fillCircle(x, y, 8, 0);
//draw the circle with the color from the array
vga.circle(x, y, 10, colors[i]);
}
//render the flame effect
for (int y = 0; y < vga.yres - 9; y++)
for (int x = 1; x < vga.xres - 1; x++)
{
//take the avarage from the surrounding pixels below
int c0 = vga.get(x, y);
int c1 = vga.get(x, y + 1);
int c2 = vga.get(x - 1, y + 1);
int c3 = vga.get(x + 1, y + 1);
int r = ((c0 & 0x1f) + (c1 & 0x1f) + ((c2 & 0x1f) + (c3 & 0x1f)) / 2) / 3;
int g = (((c0 & 0x3e0) + (c1 & 0x3e0) + ((c2 & 0x3e0) + (c3 & 0x3e0)) / 2) / 3) & 0x3e0;
int b = (((c0 & 0x3c00) + (c1 & 0x3c00) + ((c2 & 0x3c00) + (c3 & 0x3c00)) / 2) / 3) & 0x3c00;
//draw the new pixel
vga.dotFast(x, y, r | g | b);
}
}

View file

@ -0,0 +1,71 @@
//This example shows how to use different fonts on a VGA screen.
//You need to connect a VGA screen cable to the pins specified below.
//cc by-sa 4.0 license
//bitluni
#include <ESP32Lib.h>
#include <Ressources/CodePage437_8x8.h>
#include <Ressources/CodePage437_8x14.h>
#include <Ressources/CodePage437_8x16.h>
#include <Ressources/CodePage437_8x19.h>
#include <Ressources/CodePage437_9x16.h>
#include <Ressources/Font6x8.h>
//pin configuration
const int redPin = 14;
const int greenPin = 19;
const int bluePin = 27;
const int hsyncPin = 32;
const int vsyncPin = 33;
//VGA Device
VGA3Bit vga;
void setup()
{
//initializing vga at the specified pins
vga.init(vga.MODE640x400, redPin, greenPin, bluePin, hsyncPin, vsyncPin);
//selecting the font
vga.setFont(Font6x8);
//set color
vga.setTextColor(vga.RGB(255, 0, 0), vga.RGB(0, 0, 255));
//displaying the character set
vga.println("Font6x8");
for (int i = 0; i < 256; i++)
vga.print((char)i);
vga.println();
vga.setFont(CodePage437_8x8);
vga.setTextColor(vga.RGB(0, 255, 0), vga.RGB(255, 0, 0));
vga.println("CodePage437_8x8");
for (int i = 0; i < 256; i++)
vga.print((char)i);
vga.println();
vga.setFont(CodePage437_8x14);
vga.setTextColor(vga.RGB(0, 0, 255), vga.RGB(0, 255, 0));
vga.println("CodePage437_8x14");
for (int i = 0; i < 256; i++)
vga.print((char)i);
vga.println();
vga.setFont(CodePage437_8x16);
vga.setTextColor(vga.RGB(255, 255, 0), vga.RGB(0, 255, 255));
vga.println("CodePage437_8x16");
for (int i = 0; i < 256; i++)
vga.print((char)i);
vga.println();
vga.setFont(CodePage437_8x19);
vga.setTextColor(vga.RGB(255, 0, 255), vga.RGB(255, 255, 0));
vga.println("CodePage437_8x19");
for (int i = 0; i < 256; i++)
vga.print((char)i);
vga.println();
vga.setFont(CodePage437_9x16);
vga.setTextColor(vga.RGB(0, 255, 255), vga.RGB(255, 0, 255));
vga.println("CodePage437_9x16");
for (int i = 0; i < 256; i++)
vga.print((char)i);
vga.println();
}
void loop()
{
}

View file

@ -0,0 +1,31 @@
//This example shows a simple "Hello world!" on a VGA screen.
//You need to connect a VGA screen cable to the pins specified below.
//cc by-sa 4.0 license
//bitluni
#include <ESP32Lib.h>
#include <Ressources/Font6x8.h>
//pin configuration
const int redPin = 14;
const int greenPin = 19;
const int bluePin = 27;
const int hsyncPin = 32;
const int vsyncPin = 33;
//VGA Device
VGA3Bit vga;
void setup()
{
//initializing vga at the specified pins
vga.init(vga.MODE320x240, redPin, greenPin, bluePin, hsyncPin, vsyncPin);
//selecting the font
vga.setFont(Font6x8);
//displaying the text
vga.println("Hello World!");
}
void loop()
{
}

View file

@ -0,0 +1,67 @@
//This example shows a high VGA resolution 3Bit mode
//The VGA3BitI implementation uses the I²S interrupt to transcode a dense frame buffer to the needed
//8Bit/sample. Using the dense frame buffer allows to fit the big frame buffer in memory at the price of
//a lot cpu performance.
//You need to connect a VGA screen cable to the pins specified below.
//cc by-sa 4.0 license
//bitluni
//including the needed header
#include <ESP32Lib.h>
#include <Ressources/Font6x8.h>
//pin configuration
const int redPin = 14;
const int greenPin = 19;
const int bluePin = 27;
const int hsyncPin = 32;
const int vsyncPin = 33;
//VGA Device using an interrupt to unpack the pixels from 4bit to 8bit for the I²S
//This takes some CPU time in the background but is able to fit a frame buffer in the memory
VGA3BitI vga;
///draws the bitluni logo
void bitluni(int x, int y, int s)
{
vga.fillCircle(x + 2 * s, y + 2 * s, 2 * s, vga.RGB(128, 0, 0));
vga.fillCircle(x + 22 * s, y + 2 * s, 2 * s, vga.RGB(128, 0, 0));
vga.fillCircle(x + 2 * s, y + 22 * s, 2 * s, vga.RGB(128, 0, 0));
vga.fillCircle(x + 22 * s, y + 22 * s, 2 * s, vga.RGB(128, 0, 0));
vga.fillRect(x, y + 2 * s, 24 * s, 20 * s, vga.RGB(128, 0, 0));
vga.fillRect(x + 2 * s, y, 20 * s, 24 * s, vga.RGB(128, 0, 0));
vga.fillCircle(x + 7 * s, y + 4 * s, 2 * s, vga.RGB(255, 255, 255));
vga.fillCircle(x + 15 * s, y + 6 * s, 2 * s, vga.RGB(255, 255, 255));
vga.fillCircle(x + 11 * s, y + 16 * s, 6 * s, vga.RGB(255, 255, 255));
vga.fillCircle(x + 13 * s, y + 16 * s, 6 * s, vga.RGB(255, 255, 255));
vga.fillCircle(x + 11 * s, y + 16 * s, 2 * s, vga.RGB(128, 0, 0));
vga.fillCircle(x + 13 * s, y + 16 * s, 2 * s, vga.RGB(128, 0, 0));
vga.fillRect(x + 11 * s, y + 14 * s, 2 * s, 4 * s, vga.RGB(128, 0, 0));
vga.fillRect(x + 9 * s, y + 14 * s, 2 * s, 2 * s, vga.RGB(128, 0, 0));
vga.fillRect(x + 5 * s, y + 4 * s, 4 * s, 12 * s, vga.RGB(255, 255, 255));
vga.fillRect(x + 9 * s, y + 10 * s, 4 * s, s, vga.RGB(255, 255, 255));
}
void setup()
{
//initializing the graphics mode
vga.init(vga.MODE800x600, redPin, greenPin, bluePin, hsyncPin, vsyncPin);
//setting the font
vga.setFont(Font6x8);
//clearing with white background
vga.clear(vga.RGB(0xffffff));
//text position
vga.setCursor(10, 10);
//black text color no background color
vga.setTextColor(vga.RGB(0));
//show the remaining memory
vga.print("free memory: ");
vga.print((int)heap_caps_get_free_size(MALLOC_CAP_DEFAULT));
//draw the logo
bitluni(150, 60, 20);
}
//mainloop
void loop()
{
}

View file

@ -0,0 +1,83 @@
//This example shows how to draw directly to I2S with no frame buffer. It only allows low computation times per pixels
//to be able to serve I2S fast enough
//You need to connect a VGA screen cable and an external DAC (simple R2R does the job) to the pins specified below.
//cc by-sa 4.0 license
//bitluni
#include <ESP32Lib.h>
#include <math.h>
//pin configuration
const int redPins[] = {2, 4, 12, 13, 14};
const int greenPins[] = {15, 16, 17, 18, 19};
const int bluePins[] = {21, 22, 23, 27};
const int hsyncPin = 32;
const int vsyncPin = 33;
//color palette
unsigned long rainbow[256];
long frameNumber = 0;
//Our own VGA Device
class MyVGA : public VGA14BitI
{
protected:
//override frame buffer allocation
virtual Color **allocateFrameBuffer()
{
return 0;
}
//override the sync callback to count the frames
virtual void vSync()
{
frameNumber++;
}
//draw each line
void interruptPixelLine(int y, unsigned long *pixels, unsigned long syncBits)
{
for (int x = 0; x < mode.hRes / 2; x++)
{
//writing two pixels improves speed drastically (avoids memory reads)
pixels[x] = syncBits | rainbow[(x - y + frameNumber) & 255];
}
}
};
//get an instance
MyVGA vga;
//initial setup
void setup()
{
//color palette calculations
const float cb[][3] = {{1, 0, 0}, {1, 1, 0}, {0, 1, 0}, {0, 1, 1}, {0, 0, 1}, {1, 0, 1}};
for (int i = 0; i < 256; i++)
{
//interpolate the colors from the cb array and calculate the R5G5B5 color
float s = 6.f / 256 * i;
int n = int(s);
float f = s - n;
float fi = (1 - f);
const float *cf = cb[n];
const float *cfn = cb[(n + 1) % 6];
int r = int((fi * cf[0] * 0b11111) + (f * cfn[0] * 0b11111));
int g = int((fi * cf[1] * 0b11111) + (f * cfn[1] * 0b11111));
int b = int((fi * cf[2] * 0b1111) + (f * cfn[2] * 0b1111));
int c = r | (g << 5) | (b << 10);
rainbow[i] = c;
}
//prepare writing two pixels at once (we shift the palette by a pixel)
for (int i = 0; i < 256; i++)
rainbow[i] |= rainbow[(i - 1) & 255] << 16;
//initializing the vga with a high mode where a frambuffer would never fit into the memory
vga.init(vga.MODE500x480, redPins, greenPins, bluePins, hsyncPin, vsyncPin);
}
//idle, everything is happening in the interrupt
void loop()
{
delay(10);
}

View file

@ -0,0 +1,56 @@
//This example shows the three methods of how sprites can be rendered on a VGA screen
//You need to connect a VGA screen cable and an external DAC (simple R2R does the job) to the pins specified below.
//cc by-sa 4.0 license
//bitluni
//include libraries
#include <ESP32Lib.h>
#include <Ressources/Font6x8.h>
//include the sprites converted the SpriteConverter. Check the documentation for further infos.
#include "explosion.h"
//pin configuration
const int redPins[] = {2, 4, 12, 13, 14};
const int greenPins[] = {15, 16, 17, 18, 19};
const int bluePins[] = {21, 22, 23, 27};
const int hsyncPin = 32;
const int vsyncPin = 33;
//VGA Device
VGA14Bit vga;
//initial setup
void setup()
{
//need double buffering
vga.setFrameBufferCount(2);
//initializing i2s vga
vga.init(vga.MODE200x150, redPins, greenPins, bluePins, hsyncPin, vsyncPin);
//setting the font
vga.setFont(Font6x8);
}
//just draw each frame
void loop()
{
//draw a background
for (int y = 0; y < vga.yres / 10; y++)
for (int x = 0; x < vga.xres / 10; x++)
vga.fillRect(x * 10, y * 10, 10, 10, (x + y) & 1 ? vga.RGB(0, 128, 0) : vga.RGB(0, 0, 128));
//print some labels
vga.setCursor(36, 41);
vga.print("draw drawMix drawAdd");
//there are 20 sprites for the explosion. The second parameter is the index of the sprite.
//We used the milliseconds to calculate the current index of the animation.
//the last two parameters is the position. During the conversion of the sprite the origin of each sprite is defined.
//check the Utilities folder for the converter
//"draw" draws the sprite opaque ignoring any existing alpha channel
explosion.draw(vga, (millis() / 50) % 20, vga.xres / 4, vga.yres / 2);
//"drawMix" uses the alpha channel
explosion.drawMix(vga, (millis() / 50) % 20, vga.xres / 2, vga.yres / 2);
//"drawAdd" adds the color components of the back ground and the sprite
explosion.drawAdd(vga, (millis() / 50) % 20, vga.xres * 3 / 4, vga.yres / 2);
//swap the frame buffers and show the rendering
vga.show();
}

View file

@ -0,0 +1,891 @@
const int explosionOffsets[] = {0, 882, 2132, 3814, 5926, 8306, 11270, 14550, 17910, 21270, 24630, 27990, 31350, 34710, 38070, 41346, 44538, 47654, 50770, 53730, 56610, };
const short explosionPointOffsets[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, };
const unsigned short explosionRes[][2] = {{21, 21}, {25, 25}, {29, 29}, {32, 33}, {34, 35}, {38, 39}, {40, 41}, {40, 42}, {40, 42}, {40, 42}, {40, 42}, {40, 42}, {40, 42}, {40, 42}, {39, 42}, {38, 42}, {38, 41}, {38, 41}, {37, 40}, {36, 40}, };
const signed short explosionPoints[][2] = {{11, 10}, {13, 12}, {15, 14}, {16, 16}, {17, 17}, {19, 19}, {20, 20}, {20, 21}, {20, 21}, {20, 21}, {20, 21}, {20, 21}, {20, 21}, {20, 21}, {19, 21}, {19, 21}, {19, 21}, {19, 21}, {19, 20}, {18, 20}, };
const unsigned short explosionPixels[] = {
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 31, 15360, 10943, 5461, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8720, 8720, 0, 9916,
9916, 10974, 8827, 8723, 5450, 5461, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9949, 10905, 8924, 12127, 31743, 31743, 32767, 29695, 11103, 7704, 7606, 8727, 0, 0, 0, 0,
0, 0, 0, 0, 10015, 32767, 32767, 32767, 32767, 49151, 32767, 32767, 31743, 27487, 25176, 6481, 8827, 0, 0, 0, 0, 0, 0, 0, 9948, 29631, 32767, 49151, 49151, 49151, 49151, 49151,
49151, 49151, 32767, 29695, 27423, 11103, 11263, 0, 0, 0, 0, 8192, 11006, 32767, 49151, 49151, 49151, 49151, 49151, 49151, 49151, 49151, 49151, 49151, 49151, 32767, 26367, 8731, 3481, 0, 0, 0,
5492, 28575, 32767, 49151, 49151, 49151, 49151, 49151, 49151, 49151, 49151, 49151, 49151, 49151, 49151, 28607, 8894, 6684, 5471, 0, 15391, 13247, 31743, 49151, 49151, 49151, 49151, 49151, 49151, 49151, 49151, 49151,
49151, 49151, 49151, 49151, 30719, 30719, 27551, 10047, 0, 0, 8727, 29695, 32767, 49151, 49151, 49151, 49151, 49151, 49151, 49151, 49151, 49151, 49151, 49151, 49151, 31743, 29695, 26335, 8890, 0, 8730, 26399,
30719, 32767, 49151, 49151, 49151, 49151, 49151, 49151, 49151, 49151, 49151, 49151, 49151, 49151, 49151, 29695, 8860, 5461, 0, 11071, 28671, 31743, 49151, 49151, 49151, 49151, 49151, 49151, 49151, 49151, 49151, 49151,
49151, 49151, 49151, 49151, 30719, 8893, 5440, 8720, 7801, 29695, 32767, 32767, 49151, 49151, 49151, 49151, 49151, 49151, 49151, 49151, 49151, 49151, 49151, 49151, 49151, 29695, 25311, 8895, 0, 4338, 25279, 27519,
30719, 49151, 49151, 49151, 49151, 49151, 49151, 49151, 49151, 49151, 49151, 49151, 49151, 48127, 27487, 5624, 4631, 0, 0, 8730, 9951, 29695, 49151, 49151, 49151, 49151, 49151, 49151, 49151, 49151, 49151, 49151,
49151, 49151, 28639, 28639, 10015, 0, 0, 0, 0, 10239, 29695, 31743, 49151, 49151, 49151, 49151, 49151, 49151, 49151, 49151, 49151, 49151, 29663, 8927, 11071, 8735, 0, 0, 0, 0, 0, 10079,
28639, 30719, 32767, 49151, 49151, 49151, 49151, 49151, 49151, 49151, 46079, 25277, 6578, 0, 0, 0, 0, 0, 0, 0, 0, 7803, 26335, 31743, 32767, 49151, 49151, 49151, 31743, 30719, 29695, 8959,
6678, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5461, 6552, 26431, 30719, 31743, 30719, 29695, 27519, 29695, 30719, 11167, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
16, 5526, 26367, 27487, 25311, 11071, 6617, 26399, 11167, 10943, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4631, 6348, 7706, 5458, 5450, 0, 6751, 8720, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8720, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 5461, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, 8828, 8825,
0, 8991, 8761, 0, 31, 8959, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6582, 10972, 11103, 11263, 11167, 29695, 28639, 11135, 29695, 27487, 9950, 7638, 9919, 6742,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5456, 12255, 31743, 30719, 29695, 27519, 31743, 30719, 29695, 31743, 28575, 29663, 27390, 9951, 8760, 0, 0, 0, 0, 0, 0, 0,
0, 8727, 5290, 9981, 30719, 32767, 32767, 32767, 32767, 49151, 32767, 32767, 30719, 28575, 29695, 29663, 9916, 9917, 5120, 0, 0, 0, 0, 0, 0, 4112, 25213, 26334, 28607, 29695, 47103, 49151,
49151, 49151, 49151, 49151, 49151, 49151, 29695, 31743, 30719, 28543, 28607, 12159, 0, 0, 0, 0, 0, 0, 12191, 30719, 31743, 49151, 49151, 49151, 49151, 49151, 49151, 49151, 49151, 49151, 49151, 49151,
47103, 29599, 32767, 28511, 5394, 0, 0, 0, 0, 0, 0, 8891, 30719, 48127, 49151, 49151, 49151, 49151, 49151, 49151, 49151, 49151, 49151, 49151, 49151, 49151, 49151, 32767, 32767, 12094, 8889, 7636,
0, 0, 0, 5456, 26367, 48127, 49151, 49151, 49151, 49151, 49151, 49151, 49151, 49151, 49151, 49151, 49151, 49151, 49151, 49151, 49151, 32767, 31743, 30719, 12255, 11263, 0, 31, 9948, 29695, 30719, 49151,
49151, 49151, 49151, 49151, 49151, 49151, 49151, 49151, 49151, 49151, 49151, 49151, 49151, 49151, 49151, 30719, 28607, 28639, 13311, 0, 5461, 7638, 27583, 28511, 49151, 49151, 49151, 49151, 49151, 49151, 49151, 49151,
49151, 49151, 49151, 49151, 49151, 49151, 49151, 48127, 27487, 26301, 8827, 10943, 0, 8727, 25212, 29695, 28639, 48127, 49151, 49151, 49151, 49151, 49151, 49151, 49151, 65535, 49151, 49151, 49151, 49151, 49151, 49151,
47103, 27423, 29695, 9947, 0, 0, 5120, 10014, 30719, 47103, 49151, 49151, 49151, 49151, 49151, 49151, 65535, 49151, 65535, 49151, 49151, 49151, 49151, 49151, 49151, 49151, 28607, 27519, 7736, 5440, 0, 8922,
28639, 27487, 29695, 48127, 49151, 49151, 49151, 49151, 49151, 49151, 49151, 49151, 49151, 49151, 49151, 49151, 49151, 48127, 32767, 28575, 26431, 24091, 8730, 31, 6547, 10015, 26367, 30719, 46079, 49151, 49151, 49151,
49151, 49151, 49151, 49151, 49151, 49151, 49151, 49151, 49151, 49151, 49151, 47103, 27551, 25343, 6682, 6553, 0, 0, 9855, 3085, 27519, 29695, 49151, 49151, 49151, 49151, 49151, 49151, 49151, 49151, 49151, 49151,
49151, 49151, 49151, 49151, 32767, 28607, 6780, 5461, 31, 0, 0, 0, 12287, 31743, 32767, 49151, 49151, 49151, 49151, 49151, 49151, 49151, 49151, 49151, 49151, 49151, 49151, 49151, 30719, 27519, 26367, 6749,
6783, 0, 0, 0, 0, 10111, 29695, 30719, 32767, 47103, 48127, 49151, 49151, 49151, 49151, 49151, 49151, 49151, 49151, 48127, 46079, 28671, 8958, 6680, 5525, 8720, 0, 0, 0, 0, 0, 8893,
25278, 29695, 31743, 47103, 49151, 49151, 49151, 49151, 49151, 49151, 49151, 47103, 45055, 45055, 28671, 10047, 0, 16, 0, 0, 0, 0, 0, 0, 0, 5232, 10047, 30719, 30719, 48127, 48127, 49151,
49151, 49151, 30719, 31743, 29695, 27583, 26399, 10047, 10943, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8991, 28607, 29695, 46079, 48127, 30719, 30719, 28543, 31743, 30719, 26366, 7737,
5461, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2048, 26334, 30719, 29695, 27487, 28671, 28639, 7770, 27487, 30719, 27615, 10111, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 6545, 27583, 27583, 27519, 9983, 10047, 8727, 5492, 10047, 8927, 8735, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 9951, 8860, 8827, 5554, 8720, 0, 5450, 6747, 8720, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5461, 8720, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8890, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5461, 11103, 8727, 0, 0, 10933, 8720, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8735, 10943, 0, 0, 0, 12287, 29695, 27391, 6160, 7668, 11005, 5425, 5461, 5120, 7737, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 8208, 8829, 11007, 7737, 6582, 8729, 11071, 31743, 30719, 9951, 29663, 32767, 10013, 6678, 9982, 12159, 9983, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 11103, 30719, 32767, 29695, 26399, 27487, 28543, 49151, 30719, 28575, 32767, 32767, 30719, 28575, 30719, 11039, 8890, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5461,
8735, 6156, 9919, 29695, 30719, 31743, 31743, 32767, 48127, 49151, 47103, 28543, 48127, 46047, 28607, 28607, 32767, 11038, 7838, 5461, 0, 0, 0, 0, 0, 0, 0, 0, 8828, 25245, 26333, 29663,
31743, 49151, 49151, 49151, 49151, 49151, 49151, 49151, 48127, 49151, 47103, 46079, 48127, 30719, 28575, 27487, 10111, 0, 0, 0, 0, 0, 0, 0, 16383, 30719, 30719, 49151, 49151, 49151, 49151, 49151,
49151, 49151, 49151, 49151, 49151, 49151, 49151, 49151, 49151, 49151, 29663, 31743, 26399, 8925, 0, 0, 0, 0, 0, 0, 0, 0, 26431, 29695, 49151, 49151, 49151, 49151, 49151, 49151, 49151, 49151,
49151, 49151, 49151, 49151, 49151, 49151, 49151, 49151, 32767, 30719, 29695, 9917, 8991, 0, 0, 0, 0, 0, 11135, 29695, 49151, 49151, 49151, 49151, 49151, 49151, 65535, 65535, 49151, 49151, 49151, 49151,
49151, 49151, 49151, 49151, 49151, 49151, 32767, 31743, 27551, 13311, 10047, 0, 0, 0, 12287, 29695, 27487, 49151, 49151, 49151, 49151, 49151, 49151, 65535, 65535, 49151, 49151, 49151, 49151, 49151, 49151, 49151,
49151, 49151, 49151, 32767, 30719, 29695, 31743, 11038, 10933, 0, 0, 6547, 28671, 26367, 48127, 49151, 49151, 49151, 49151, 49151, 49151, 49151, 49151, 49151, 65535, 49151, 49151, 49151, 49151, 49151, 49151, 49151,
49151, 46079, 29695, 29695, 9951, 5813, 0, 8720, 8891, 31743, 27487, 30719, 47103, 49151, 49151, 49151, 49151, 49151, 49151, 49151, 65535, 65535, 49151, 49151, 49151, 49151, 49151, 49151, 49151, 48127, 27455, 26367,
9950, 8730, 0, 0, 5461, 6678, 29695, 27455, 30719, 48127, 49151, 49151, 49151, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 49151, 49151, 49151, 49151, 49151, 49151, 47103, 44959, 26335, 9918, 6742, 0,
0, 0, 7834, 28639, 28671, 49151, 49151, 49151, 49151, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 49151, 65535, 49151, 46079, 46079, 26335, 26335, 5491, 0, 0, 9819, 11135,
26367, 27519, 46079, 48127, 48127, 49151, 49151, 49151, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 49151, 49151, 49151, 46079, 29695, 28607, 28671, 24156, 4534, 0, 9980, 29695, 28607, 31743, 29695,
49151, 49151, 49151, 49151, 49151, 49151, 49151, 49151, 49151, 49151, 65535, 65535, 49151, 49151, 49151, 49151, 48127, 29695, 31743, 28607, 25343, 7805, 6783, 0, 0, 10079, 9983, 29695, 26431, 46079, 47103, 49151,
49151, 49151, 49151, 49151, 65535, 65535, 49151, 49151, 49151, 49151, 49151, 49151, 49151, 49151, 47103, 26334, 25245, 4466, 6678, 31, 0, 0, 0, 0, 11135, 29695, 32767, 49151, 49151, 49151, 49151, 49151,
49151, 65535, 65535, 65535, 49151, 49151, 49151, 49151, 49151, 49151, 49151, 49151, 29695, 28671, 10111, 0, 0, 0, 0, 0, 8720, 8828, 29695, 32767, 49151, 49151, 49151, 49151, 49151, 49151, 65535, 65535,
49151, 49151, 49151, 49151, 49151, 49151, 49151, 28607, 27551, 27519, 29695, 13311, 0, 0, 0, 0, 0, 5823, 7773, 27519, 31743, 48127, 48127, 48127, 49151, 49151, 49151, 49151, 49151, 49151, 49151, 49151,
48127, 48127, 46079, 46079, 28639, 25311, 7740, 11167, 9215, 0, 0, 0, 0, 0, 0, 6777, 5399, 26335, 26301, 26399, 28639, 46079, 48127, 49151, 49151, 49151, 49151, 49151, 48127, 47103, 47103, 46079,
45055, 27583, 8927, 31, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4435, 6712, 27519, 28607, 30719, 47103, 48127, 49151, 49151, 49151, 49151, 47103, 29695, 28671, 29695, 28671, 25343, 6679,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 2048, 10014, 29695, 29695, 48127, 48127, 49151, 47103, 48127, 29695, 27519, 31743, 28671, 27583, 27551, 7903, 31, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4108, 26335, 26367, 29695, 28671, 31743, 28639, 30719, 26399, 25311, 31743, 29695, 9982, 7805, 8735, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 7738, 26431, 29695, 27519, 28671, 28671, 26399, 5560, 5591, 27551, 28639, 8926, 5450, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 6647, 8925, 8858, 11199, 10047, 6747, 5461, 0, 6713, 8959, 8725, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 6547, 2057, 7837, 6547, 0, 0, 0, 528, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 528, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 10943, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 4398, 10015, 5461, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 10972, 29695, 11135, 2048, 0, 8959, 7737, 0, 0, 0, 10943, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13311, 0, 0, 5461,
0, 12287, 31743, 31743, 12191, 7571, 28575, 27391, 6550, 0, 8794, 9852, 6580, 31, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8720, 8859, 30719, 12191, 5457, 12159,
7735, 11135, 32767, 30719, 11006, 27423, 32767, 30719, 11135, 8826, 28575, 11039, 8759, 8720, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6348, 11039, 32767, 32767, 31743, 32767,
30719, 29695, 49151, 31743, 31743, 31743, 32767, 28575, 29695, 29695, 31743, 10079, 8827, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6553, 0, 5120, 9884, 29695, 30719, 32767, 30719, 47103,
47103, 48127, 49151, 48127, 29631, 32767, 49151, 29663, 28639, 30719, 31743, 26367, 7674, 6547, 0, 0, 0, 0, 0, 0, 0, 0, 0, 26334, 9981, 25243, 28575, 32767, 47103, 48127, 49151, 49151,
49151, 49151, 49151, 49151, 49151, 49151, 49151, 47103, 46047, 49151, 31743, 29663, 26303, 8828, 0, 0, 0, 0, 0, 0, 0, 0, 12223, 31743, 32767, 48127, 49151, 49151, 49151, 49151, 49151, 49151,
49151, 49151, 49151, 49151, 49151, 49151, 49151, 49151, 49151, 48127, 28575, 30719, 10015, 9949, 8825, 0, 0, 0, 0, 0, 0, 0, 0, 28607, 49151, 49151, 49151, 49151, 49151, 49151, 49151, 49151,
49151, 49151, 49151, 49151, 65535, 49151, 49151, 49151, 49151, 49151, 49151, 32767, 31743, 29695, 28639, 10047, 0, 0, 0, 0, 0, 5450, 5459, 26335, 49151, 49151, 49151, 49151, 49151, 49151, 65535, 65535,
65535, 49151, 49151, 49151, 65535, 65535, 65535, 49151, 49151, 49151, 49151, 49151, 32767, 31743, 28607, 8827, 8794, 0, 0, 0, 0, 8824, 25242, 46079, 49151, 49151, 49151, 49151, 49151, 49151, 65535, 65535,
65535, 49151, 49151, 65535, 65535, 65535, 65535, 65535, 49151, 49151, 49151, 49151, 32767, 30719, 28575, 11103, 13311, 8895, 0, 0, 13311, 13311, 29695, 48127, 49151, 49151, 49151, 49151, 65535, 65535, 65535, 65535,
65535, 65535, 65535, 65535, 49151, 65535, 65535, 65535, 49151, 49151, 49151, 48127, 31743, 31743, 30719, 29695, 31743, 13311, 0, 0, 0, 8793, 8859, 28607, 46079, 48127, 49151, 49151, 65535, 65535, 65535, 65535,
65535, 65535, 65535, 65535, 49151, 49151, 65535, 65535, 49151, 49151, 49151, 49151, 49151, 48127, 28543, 25245, 10047, 8890, 0, 0, 8857, 27487, 28607, 29695, 29695, 49151, 49151, 49151, 49151, 65535, 65535, 65535,
65535, 65535, 65535, 65535, 65535, 65535, 49151, 49151, 49151, 49151, 49151, 49151, 47103, 44927, 25211, 25177, 6416, 31, 0, 0, 8728, 27519, 26303, 28607, 28607, 49151, 49151, 49151, 49151, 65535, 65535, 65535,
65535, 65535, 65535, 65535, 65535, 65535, 65535, 49151, 49151, 65535, 65535, 49151, 47103, 44959, 25278, 27551, 11167, 0, 0, 31, 10014, 30719, 29695, 48127, 49151, 49151, 49151, 65535, 65535, 65535, 65535, 65535,
65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 49151, 48127, 47103, 28575, 25279, 9983, 0, 0, 0, 6711, 27519, 26399, 45055, 46079, 49151, 49151, 49151, 65535, 65535, 65535, 65535,
65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 49151, 48127, 48127, 46079, 29695, 29695, 31743, 9950, 6553, 10943, 7903, 26334, 28607, 29695, 48127, 49151, 49151, 49151, 49151, 65535, 65535, 65535,
65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 49151, 46079, 46079, 28671, 28671, 25375, 28671, 8923, 8720, 0, 5590, 8891, 29695, 31743, 46079, 48127, 49151, 49151, 65535, 65535, 65535, 65535,
65535, 65535, 65535, 65535, 65535, 65535, 65535, 49151, 49151, 49151, 49151, 46079, 26367, 25276, 27615, 24156, 8891, 6771, 0, 0, 0, 0, 8892, 26332, 30719, 47103, 49151, 49151, 49151, 49151, 49151, 65535,
65535, 65535, 65535, 65535, 65535, 65535, 65535, 49151, 49151, 49151, 49151, 49151, 49151, 28607, 10047, 4466, 5461, 0, 0, 0, 0, 0, 4112, 26367, 30719, 49151, 49151, 49151, 49151, 49151, 49151, 49151,
65535, 65535, 65535, 65535, 49151, 49151, 49151, 49151, 49151, 49151, 47103, 46079, 47103, 29695, 29695, 7899, 528, 0, 0, 0, 0, 0, 10045, 30719, 31743, 49151, 49151, 49151, 49151, 49151, 49151, 49151,
65535, 65535, 65535, 49151, 49151, 49151, 49151, 49151, 49151, 49151, 48127, 28639, 25375, 8991, 8927, 4534, 5461, 0, 0, 0, 0, 8720, 6647, 12255, 28671, 29663, 45023, 45023, 43967, 47103, 48127, 49151,
49151, 49151, 49151, 49151, 49151, 49151, 49151, 49151, 49151, 47103, 47103, 29695, 24223, 4534, 6553, 4375, 0, 0, 0, 0, 0, 0, 0, 11103, 8893, 25247, 24190, 26399, 26495, 46079, 47103, 48127,
49151, 49151, 49151, 49151, 49151, 49151, 48127, 48127, 47103, 47103, 47103, 28639, 24187, 5461, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7805, 8895, 24154, 26431, 29695, 46079, 47103,
47103, 49151, 49151, 48127, 46079, 47103, 47103, 47103, 43967, 27551, 27519, 26367, 6648, 5461, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6680, 7738, 27551, 31743, 46079, 47103,
48127, 49151, 48127, 49151, 47103, 46079, 30719, 29695, 26463, 26399, 26463, 8893, 3475, 31, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2064, 7803, 28607, 28639, 30719,
30719, 47103, 46079, 46079, 26495, 25375, 29695, 31743, 26399, 6681, 6715, 6553, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4206, 25245, 28671, 31743,
27615, 29695, 28671, 25407, 23132, 23067, 28639, 31743, 26399, 7640, 4631, 31, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6646, 27551, 31743,
26431, 29695, 28671, 8959, 4406, 2066, 8861, 28671, 7835, 4368, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8761, 12223,
7768, 11103, 10047, 8735, 0, 0, 0, 8991, 8727, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
5120, 7736, 8720, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 5120, 10111, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 8720, 9915, 14335, 11103, 3072, 0, 0, 0, 8720, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
31, 0, 0, 0, 0, 8720, 10973, 31743, 30719, 9915, 8720, 5461, 6678, 8823, 0, 0, 0, 8895, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 11071, 10111, 0, 11103, 6547, 0, 11039, 31743, 30719, 10015, 4114, 9918, 28511, 27487, 12159, 5120, 11071, 11135, 9951, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 11039, 29695, 30719, 13311, 30719, 28607, 6650, 27487, 49151, 31743, 12223, 8895, 31743, 32767, 27455, 7806, 11007, 29695, 9884, 8725, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 12223, 31743, 32767, 32767, 31743, 31743, 28671, 30719, 49151, 48127, 30719, 28575, 32767, 32767, 29695, 28671, 29695, 31743, 9915, 8725, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 9951, 28639, 28575, 32767, 49151, 47103, 48127, 48127, 49151, 49151, 49151, 32767, 30719, 49151, 48127, 28607, 45023, 30719, 30719, 8925, 8794, 5130, 0, 0, 0, 0,
0, 0, 0, 0, 5456, 12127, 8989, 8958, 10015, 30719, 29695, 47103, 49151, 49151, 49151, 49151, 49151, 49151, 49151, 49151, 49151, 49151, 49151, 47103, 48127, 49151, 31743, 29695, 29695, 12287, 0, 0,
0, 0, 0, 0, 0, 10047, 26399, 31743, 30719, 30719, 31743, 32767, 49151, 49151, 49151, 49151, 49151, 65535, 65535, 65535, 49151, 49151, 49151, 49151, 49151, 47103, 49151, 48127, 29663, 29695, 11071, 6578,
9951, 4104, 0, 0, 0, 0, 0, 5450, 8794, 29695, 49151, 49151, 49151, 49151, 49151, 49151, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 49151, 49151, 49151, 49151, 49151, 49151, 32767,
28607, 26399, 27487, 8795, 8735, 0, 0, 0, 0, 0, 7638, 26367, 47103, 49151, 49151, 49151, 49151, 49151, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 49151, 49151, 49151,
49151, 49151, 32767, 32767, 30719, 10975, 9819, 0, 0, 0, 0, 11167, 8829, 44959, 48127, 49151, 49151, 49151, 49151, 49151, 49151, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535,
49151, 49151, 49151, 49151, 32767, 32767, 28543, 9884, 11039, 5461, 0, 31, 8891, 28671, 26334, 46079, 49151, 49151, 49151, 49151, 65535, 49151, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535,
65535, 65535, 49151, 49151, 49151, 48127, 31743, 32767, 29663, 30719, 32767, 9980, 8720, 0, 11071, 29695, 29695, 31743, 49151, 49151, 49151, 49151, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535,
65535, 65535, 65535, 65535, 49151, 49151, 49151, 49151, 48127, 47103, 29695, 32767, 32767, 10047, 5461, 0, 0, 25311, 25309, 29695, 48127, 49151, 49151, 49151, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535,
65535, 65535, 65535, 65535, 65535, 49151, 49151, 49151, 49151, 49151, 49151, 48127, 30719, 27487, 11071, 8727, 0, 0, 8925, 28671, 28671, 30719, 31743, 48127, 49151, 49151, 49151, 65535, 65535, 65535, 65535, 65535,
65535, 65535, 65535, 65535, 65535, 65535, 65535, 49151, 49151, 49151, 49151, 47103, 47103, 27487, 27423, 8762, 6578, 8720, 0, 8959, 9951, 26431, 27455, 28511, 47103, 48127, 48127, 49151, 65535, 65535, 65535, 65535,
65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 64511, 46079, 46079, 43871, 27455, 25247, 7703, 6547, 0, 8959, 25343, 27519, 46079, 49151, 49151, 49151, 49151, 65535, 65535, 65535,
65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 48127, 48127, 46079, 28607, 26335, 8891, 9948, 0, 8727, 25311, 26302, 28575, 46079, 46079, 48127, 48127, 65535,
65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 48127, 48127, 46079, 29695, 31743, 30719, 29695, 12287, 13311, 28639, 26367, 26301, 28607, 47103, 49151,
49151, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 49151, 48127, 48127, 46079, 28671, 28607, 30719, 27551, 28671, 11167, 0, 9983, 28671, 29695, 31743,
48127, 49151, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 49151, 48127, 45023, 26399, 28671, 28607, 30719, 26334, 10015, 10943, 0, 3084, 10015,
28671, 28639, 45023, 47103, 48127, 49151, 49151, 49151, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 49151, 49151, 49151, 49151, 48127, 46079, 25309, 8892, 27487, 8825, 8720, 0, 0,
0, 0, 11135, 27583, 29695, 31743, 49151, 49151, 49151, 49151, 49151, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 49151, 49151, 49151, 48127, 49151, 49151, 29695, 12223, 8959, 0, 0,
0, 0, 0, 0, 7701, 28671, 32767, 49151, 49151, 49151, 49151, 49151, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 49151, 49151, 49151, 49151, 49151, 49151, 49151, 45055, 27551, 29695, 27551, 32767, 13311,
12287, 0, 0, 0, 0, 5461, 8894, 31743, 32767, 49151, 48127, 47103, 46079, 48127, 49151, 49151, 65535, 65535, 65535, 65535, 65535, 65535, 49151, 49151, 49151, 49151, 49151, 49151, 46079, 27551, 25343, 6714,
11006, 7770, 8727, 0, 0, 0, 0, 8720, 6481, 11135, 30719, 28543, 27583, 42815, 45055, 47103, 48127, 48127, 49151, 49151, 48127, 65535, 65535, 49151, 49151, 49151, 49151, 49151, 48127, 47103, 47103, 27551,
25311, 8831, 5461, 4631, 0, 0, 0, 0, 0, 0, 8720, 0, 10175, 23003, 25278, 25246, 26399, 47103, 47103, 47103, 49151, 49151, 49151, 49151, 49151, 48127, 49151, 49151, 49151, 47103, 47103, 46079,
48127, 30719, 8925, 5461, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12287, 29695, 26367, 24122, 29695, 30719, 47103, 47103, 49151, 49151, 49151, 48127, 46079, 49151, 47103, 46079, 43967,
30719, 28639, 27615, 27551, 8890, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4375, 10079, 6681, 26266, 32767, 30719, 46079, 46079, 49151, 49151, 49151, 49151, 47103, 49151, 46079,
47103, 27615, 28671, 28671, 28671, 10079, 8727, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6975, 3475, 7804, 28671, 27519, 29695, 29695, 31743, 48127, 47103, 49151, 28639,
47103, 28639, 31743, 27519, 7803, 8894, 10047, 7871, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4375, 10047, 27551, 29695, 29695, 29695, 30719, 27615,
26463, 23096, 25279, 25310, 31743, 29695, 11135, 4364, 7740, 8720, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7869, 27583, 30719, 28671, 26463,
28671, 29695, 10015, 3270, 3544, 5430, 26431, 26463, 8860, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6715, 10015,
7803, 6681, 26399, 8959, 6777, 0, 0, 0, 7740, 7770, 6547, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 6553, 3475, 5489, 7739, 6582, 0, 0, 0, 0, 0, 8720, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 8727, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 31, 31, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8626, 9947, 8464, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8735, 8795, 29695, 9885, 8692, 15360, 0, 0, 8720, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 31, 8720, 0, 8727, 26333, 31743, 28543, 8761,
8727, 0, 5296, 9948, 4096, 0, 0, 16, 11263, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5301, 14335, 10047, 6743, 12159,
8890, 12159, 27423, 49151, 29695, 11038, 10047, 9914, 28543, 29695, 10046, 11103, 10111, 10972, 9983, 11263, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
5471, 26367, 31743, 16383, 32767, 32767, 31743, 30719, 30719, 49151, 49151, 31743, 32767, 32767, 32767, 30719, 30719, 30719, 32767, 32767, 27391, 8890, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 11039, 28639, 32767, 32767, 32767, 32767, 30719, 29695, 30719, 49151, 49151, 29695, 29695, 31743, 49151, 29695, 29695, 28575, 31743, 32767, 12063, 8730, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 7707, 27455, 32767, 32767, 49151, 48127, 48127, 48127, 49151, 49151, 49151, 49151, 48127, 49151, 49151, 48127, 29695, 44991, 30719, 28511,
9916, 5359, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9980, 10047, 4112, 7737, 9983, 28639, 29695, 29631, 49151, 49151, 49151, 49151, 49151, 49151, 49151, 49151, 49151, 49151, 49151,
49151, 48127, 47103, 48127, 31743, 30719, 29695, 9917, 6553, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12287, 28671, 29695, 27487, 27487, 28575, 31743, 31743, 47103, 48127, 49151, 49151, 49151, 65535,
65535, 65535, 49151, 49151, 49151, 49151, 49151, 49151, 49151, 49151, 48127, 29663, 29695, 9914, 8720, 10933, 0, 0, 0, 0, 0, 0, 0, 0, 8890, 28575, 32767, 49151, 49151, 49151, 49151, 49151,
49151, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 49151, 49151, 49151, 49151, 49151, 49151, 47103, 29695, 9950, 11007, 9885, 7670, 0, 0, 0, 0, 0, 0, 0, 0, 9982,
30719, 48127, 49151, 49151, 49151, 49151, 49151, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 49151, 49151, 49151, 49151, 49151, 29695, 30719, 29695, 11071, 10047, 0, 0,
0, 0, 0, 0, 8192, 6648, 28607, 48127, 49151, 49151, 49151, 49151, 49151, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 49151, 49151, 49151, 49151, 49151, 49151,
32767, 30719, 11071, 8892, 0, 0, 0, 0, 0, 0, 11071, 26367, 47103, 49151, 49151, 49151, 49151, 65535, 49151, 49151, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535,
65535, 65535, 49151, 49151, 48127, 31743, 30719, 27487, 9919, 11199, 8959, 0, 0, 0, 8720, 7801, 29695, 28607, 29695, 49151, 48127, 49151, 49151, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535,
65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 48127, 47103, 47103, 30719, 31743, 30719, 30719, 31743, 13247, 0, 0, 0, 8720, 5490, 27519, 28671, 28607, 49151, 49151, 49151, 48127, 65535, 65535, 65535,
65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 49151, 49151, 49151, 49151, 48127, 48127, 31743, 29695, 29695, 11103, 0, 0, 0, 0, 7801, 28639, 27487, 29695, 32767,
49151, 49151, 49151, 49151, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 49151, 49151, 49151, 49151, 48127, 30719, 27487, 10047, 9215, 0, 0, 0,
4352, 8825, 29695, 28639, 28671, 29695, 48127, 49151, 49151, 49151, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 49151, 48127, 47103, 46079, 45023, 27455,
28639, 7802, 0, 0, 0, 0, 5301, 23033, 26367, 26367, 27455, 45023, 48127, 48127, 48127, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535,
64511, 63487, 46079, 46079, 45055, 26367, 30719, 11167, 6553, 0, 0, 0, 8827, 27519, 29695, 47103, 48127, 49151, 49151, 49151, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535,
65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 48127, 47103, 46079, 28639, 26463, 9982, 10047, 0, 0, 0, 8955, 27583, 27551, 29695, 30719, 47103, 46079, 47103, 64511, 65535, 65535, 65535, 65535, 65535,
65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 47103, 47103, 45055, 29695, 28671, 30719, 30719, 9982, 8720, 0, 6678, 26463, 27519, 26399, 27455, 46079, 46079, 48127,
65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 48127, 48127, 47103, 46079, 27455, 29695, 28607, 29695, 30719, 10015, 8720, 0, 5588, 25311,
29695, 30719, 30719, 48127, 49151, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 48127, 47103, 46079, 30719, 28607, 30719, 29695, 27551,
10111, 9947, 31, 0, 0, 6549, 12223, 30719, 29695, 44991, 48127, 49151, 49151, 49151, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 49151, 49151,
46079, 27487, 25375, 28639, 28671, 7835, 6547, 0, 0, 0, 0, 0, 2052, 24254, 27551, 28639, 44991, 47103, 49151, 49151, 49151, 49151, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535,
65535, 65535, 49151, 65535, 49151, 49151, 49151, 49151, 28639, 10079, 8893, 6547, 0, 0, 0, 0, 0, 0, 0, 8925, 28671, 29695, 32767, 49151, 49151, 49151, 49151, 65535, 65535, 65535, 65535, 65535,
65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 49151, 49151, 48127, 47103, 49151, 49151, 31743, 30719, 8894, 4375, 0, 0, 0, 0, 0, 0, 11263, 12223, 29695, 32767, 49151, 49151, 49151, 49151,
64511, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 49151, 49151, 49151, 49151, 49151, 48127, 43903, 27487, 27487, 11039, 11103, 10015, 8959, 0, 0, 0, 0, 0, 0, 10943, 11135,
11135, 32767, 32767, 48127, 48127, 47103, 49151, 49151, 49151, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 49151, 49151, 49151, 48127, 48127, 48127, 45055, 28671, 8991, 4360, 6780, 6712, 8720, 0, 0,
0, 0, 0, 0, 0, 7868, 6647, 28671, 28575, 27487, 26431, 43903, 46079, 48127, 47103, 48127, 65535, 65535, 48127, 65535, 64511, 64511, 48127, 49151, 49151, 49151, 48127, 48127, 48127, 48127, 28671, 8959,
6783, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10111, 4333, 8925, 28671, 27551, 29695, 47103, 46079, 48127, 49151, 49151, 48127, 48127, 47103, 47103, 49151, 48127, 49151, 47103,
47103, 48127, 48127, 32767, 30719, 8991, 4624, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9983, 12287, 29695, 25343, 27551, 31743, 47103, 48127, 48127, 49151, 49151, 49151,
49151, 47103, 49151, 48127, 47103, 46079, 29695, 30719, 29695, 28671, 27551, 8956, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3078, 7803, 10079, 8959, 26431, 32767,
30719, 46079, 46079, 48127, 49151, 48127, 49151, 47103, 49151, 46079, 47103, 30719, 26399, 27551, 30719, 28671, 8991, 8735, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 4631, 0, 6747, 24121, 29695, 28671, 28671, 43999, 47103, 48127, 46079, 47103, 45055, 48127, 43967, 29695, 30719, 8926, 8893, 29695, 28671, 12287, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 8735, 6648, 27551, 27551, 30719, 27583, 31743, 47103, 28671, 25407, 25343, 28671, 25311, 28671, 32767, 26431, 6681, 8861, 8925, 10943, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6879, 11199, 28671, 31743, 26399, 28671, 27583, 30719, 10111, 4565, 10047, 6614, 11071, 31743, 25311, 5692,
8720, 8720, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6677, 25278, 29695, 9983, 8894, 26463, 26463, 8927, 0,
0, 16, 0, 11071, 6712, 8720, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2058, 10015,
6783, 7742, 8927, 8927, 1023, 0, 0, 0, 0, 5461, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 5461, 6681, 31, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5461, 8720, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8720, 8694, 9916, 5296,
5450, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 8735, 9852, 29695, 9917, 7606, 8720, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 11103, 0, 0, 9849, 26269, 30719, 27455, 8793, 10581, 0, 8727, 7737, 3273, 0, 0, 0, 8720, 5450, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8925, 3084, 7833, 13311, 11135, 0, 8796, 27391, 49151, 28511, 8728, 11103, 8892, 27391, 27487, 6549, 5461, 0,
5136, 11005, 6449, 8720, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9951, 29695, 12127, 12191, 32767, 31743, 10047, 26399, 27423, 49151, 29695,
27487, 13311, 29695, 31743, 32767, 12191, 8892, 8991, 12159, 32767, 12094, 5461, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5450, 9980, 31743, 32767,
29695, 31743, 32767, 29695, 29695, 46015, 49151, 48127, 31743, 31743, 31743, 49151, 31743, 28639, 28575, 29695, 32767, 31743, 12127, 8720, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 2048, 12191, 31743, 32767, 49151, 49151, 49151, 48127, 49151, 49151, 49151, 49151, 49151, 49151, 49151, 49151, 47103, 47103, 45023, 46079, 30719, 29695, 10015, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 6777, 8720, 0, 5461, 8464, 11071, 31743, 29663, 49151, 49151, 49151, 49151, 49151, 49151, 49151, 49151, 49151, 49151, 49151, 49151, 49151, 49151, 48127, 46079, 48127,
28575, 28575, 29695, 10015, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4368, 24155, 11005, 9981, 8858, 10015, 29663, 30719, 45023, 47103, 49151, 49151, 49151, 65535, 65535, 65535, 65535, 49151,
49151, 49151, 49151, 49151, 49151, 48127, 48127, 49151, 32767, 30719, 27487, 7638, 0, 0, 8720, 0, 0, 0, 0, 0, 0, 0, 12287, 28639, 32767, 32767, 31743, 31743, 32767, 31743, 48127, 49151,
65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 64511, 65535, 49151, 49151, 49151, 49151, 49151, 49151, 49151, 47103, 29663, 8825, 7736, 6412, 6646, 0, 0, 0, 0, 0, 0, 0, 0, 26399,
32767, 49151, 49151, 49151, 49151, 49151, 49151, 49151, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 49151, 49151, 49151, 49151, 49151, 32767, 27455, 26367, 25179, 8895, 12287,
0, 0, 0, 0, 0, 0, 0, 7736, 29663, 48127, 49151, 49151, 49151, 49151, 49151, 49151, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 49151, 49151,
49151, 49151, 49151, 31743, 32767, 29695, 12287, 10239, 0, 0, 0, 0, 0, 8720, 8720, 6613, 28575, 49151, 49151, 49151, 49151, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535,
65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 49151, 49151, 49151, 32767, 32767, 28543, 8892, 13215, 0, 0, 0, 0, 0, 8893, 11135, 9948, 30719, 49151, 49151, 49151, 49151, 65535, 65535, 65535,
65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 49151, 48127, 47103, 29695, 29695, 26334, 28639, 16383, 11007, 8735, 0, 0, 13311, 30719, 32767, 29695,
30719, 48127, 49151, 48127, 49151, 64511, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 64511, 47103, 46079, 48127, 47103, 30719, 30719, 29695, 31743, 32767,
9983, 8735, 0, 0, 0, 8893, 28575, 26335, 29695, 49151, 49151, 48127, 47103, 63487, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 49151,
49151, 49151, 49151, 49151, 49151, 31743, 29695, 11071, 7704, 5461, 0, 0, 0, 8859, 31743, 29663, 31743, 49151, 49151, 49151, 49151, 49151, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535,
65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 49151, 49151, 49151, 49151, 48127, 30719, 11103, 7640, 5461, 0, 0, 0, 2053, 7769, 29695, 28639, 28575, 46047, 47103, 47103, 48127, 48127, 64511, 64511,
64511, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 64511, 63487, 46079, 45023, 46079, 28607, 27551, 11103, 5558, 8720, 0, 0, 0, 8921, 27487, 26367, 26333,
27391, 46079, 47103, 47103, 47103, 64511, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 64511, 64511, 63487, 62463, 46079, 46079, 46079, 29695, 29695, 8861,
6553, 0, 0, 0, 5393, 27423, 29695, 48127, 49151, 49151, 49151, 49151, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535,
65535, 65535, 48127, 47103, 46079, 28607, 27455, 9950, 11039, 0, 0, 8720, 7834, 29695, 28607, 47103, 47103, 48127, 48127, 46079, 63487, 63487, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535,
65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 48127, 47103, 47103, 45055, 27519, 29695, 29695, 29695, 9981, 0, 0, 6646, 28639, 28607, 28575, 27487, 29695, 47103, 46079, 63487, 64511, 65535, 65535,
65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 48127, 48127, 47103, 46079, 45055, 46047, 28575, 30719, 29695, 30719, 11135, 8720, 31, 7703, 26463, 28671, 28671,
29695, 47103, 48127, 49151, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 48127, 47103, 47103, 48127, 47103, 29695, 29695, 31743, 28671,
11135, 9947, 0, 0, 4112, 7805, 12223, 27519, 28671, 45023, 48127, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 49151,
49151, 48127, 30719, 28639, 28671, 28671, 28575, 27519, 11071, 0, 0, 0, 0, 3283, 8861, 26463, 25311, 26431, 44991, 46079, 46079, 47103, 48127, 49151, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535,
65535, 65535, 65535, 65535, 65535, 65535, 49151, 49151, 49151, 49151, 49151, 28607, 7836, 8957, 8760, 7801, 8727, 0, 0, 0, 0, 0, 8827, 27551, 27487, 28671, 29695, 47103, 48127, 49151, 48127, 49151,
64511, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 64511, 49151, 64511, 48127, 49151, 49151, 49151, 29695, 11039, 13, 5450, 0, 0, 0, 0, 0, 0, 8727, 27583,
29695, 29695, 32767, 49151, 49151, 49151, 48127, 64511, 64511, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 49151, 49151, 65535, 64511, 48127, 48127, 46079, 43871, 27423, 28607, 27487, 32767, 12062, 0,
0, 0, 0, 0, 0, 0, 10111, 14335, 32767, 32767, 49151, 49151, 48127, 48127, 48127, 64511, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 49151, 49151, 49151, 48127, 48127, 49151,
46079, 27615, 25311, 6748, 7805, 12223, 7772, 6777, 0, 0, 0, 0, 0, 0, 5653, 11135, 13311, 31743, 29695, 29695, 43935, 46079, 48127, 47103, 49151, 49151, 65535, 65535, 65535, 64511, 65535, 65535,
64511, 64511, 49151, 49151, 49151, 49151, 49151, 49151, 48127, 45055, 28671, 8894, 0, 9951, 6679, 31, 0, 0, 0, 0, 0, 0, 0, 8959, 3072, 11103, 10079, 28671, 25276, 27519, 46079, 47103,
48127, 47103, 49151, 65535, 64511, 48127, 64511, 64511, 64511, 48127, 48127, 49151, 49151, 48127, 48127, 49151, 49151, 48127, 29695, 8895, 4639, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 6547, 0, 8991, 27551, 28671, 31743, 30719, 47103, 46079, 49151, 49151, 49151, 49151, 48127, 49151, 48127, 49151, 48127, 48127, 47103, 48127, 48127, 48127, 47103, 30719, 28671, 8927, 31, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11263, 11263, 26495, 24253, 28671, 29695, 46079, 45023, 45055, 46079, 48127, 49151, 47103, 48127, 46079, 49151, 48127, 47103, 46079, 28639, 31743, 29695,
30719, 27583, 8926, 8890, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 7805, 8924, 5390, 10047, 30719, 29695, 45055, 43999, 45055, 47103, 47103, 47103, 48127,
46079, 48127, 46079, 46079, 46079, 27615, 27487, 26463, 31743, 9983, 4534, 31, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5461, 31, 5450, 8923, 29695,
27583, 27551, 28671, 45023, 49151, 48127, 46079, 46079, 46079, 46079, 45055, 27583, 30719, 27551, 7771, 9983, 31743, 10015, 6783, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 8823, 28671, 26495, 28671, 30719, 26399, 31743, 29695, 28671, 24287, 25343, 27551, 25343, 27551, 31743, 30719, 11263, 0, 8959, 6680, 8720, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10047, 28671, 29695, 31743, 26463, 28639, 26495, 28671, 6750, 4439, 23065, 21910, 23099, 27551, 29695, 11199, 0,
5461, 528, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 7806, 25311, 29695, 11231, 28671, 26495, 29695, 11199,
5461, 5461, 4368, 2229, 6747, 10047, 8959, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
5461, 5590, 11167, 10111, 12287, 8863, 10111, 5823, 0, 0, 0, 0, 0, 8208, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8991, 6679, 8720, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8720, 528, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 8720, 6582, 6613, 5457, 6540, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10943, 9819, 27391, 8763, 8727, 8720, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9951, 8727, 0, 0, 8735, 26236, 29695, 26301, 8762, 8727, 0, 0, 10933, 0, 0, 0,
0, 15360, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12287, 27455, 28543, 5136, 5358, 9918, 27390, 48127, 28479,
8728, 9849, 8192, 8659, 11006, 6217, 0, 0, 0, 9948, 7736, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4112, 9981, 8828,
29631, 32767, 13247, 9948, 30719, 28447, 49151, 28543, 26201, 11039, 9883, 27455, 30719, 9948, 6547, 0, 10972, 30719, 28575, 10943, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 15360, 8595, 8829, 29695, 28575, 30719, 32767, 30719, 27551, 29695, 44895, 49151, 48127, 30719, 31743, 31743, 30719, 32767, 27455, 8826, 7837, 12159, 32767, 31743, 14335, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8991, 28575, 32767, 32767, 49151, 48127, 48127, 47103, 47103, 47103, 49151, 49151, 48127, 49151, 49151, 49151, 48127, 30719, 29695, 29695,
30719, 31743, 29695, 11167, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5120, 27487, 32767, 49151, 49151, 49151, 49151, 49151, 48127, 48127, 49151, 49151,
48127, 49151, 49151, 49151, 49151, 48127, 46079, 47103, 48127, 29695, 27391, 7641, 5823, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2048, 9916, 5120, 0, 5461, 5450, 9916, 28639, 46079, 49151,
49151, 49151, 49151, 65535, 65535, 65535, 65535, 49151, 48127, 49151, 49151, 49151, 49151, 48127, 47103, 49151, 48127, 31743, 30719, 27455, 6547, 0, 0, 0, 0, 0, 0, 0, 0, 8720, 6650, 28543,
27390, 10014, 8858, 10014, 28575, 29695, 48127, 47103, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 48127, 48127, 49151, 49151, 49151, 48127, 48127, 49151, 49151, 47103, 28607, 29695, 9947, 8192, 6553, 4368,
0, 0, 0, 0, 0, 8735, 9916, 31743, 32767, 32767, 48127, 47103, 49151, 48127, 49151, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 64511, 64511, 65535, 49151, 65535, 65535, 48127, 49151, 49151,
49151, 49151, 31743, 31743, 11135, 9949, 9983, 8894, 4112, 0, 0, 0, 0, 0, 8990, 31743, 32767, 49151, 49151, 49151, 49151, 49151, 49151, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535,
65535, 65535, 65535, 65535, 65535, 65535, 49151, 49151, 49151, 49151, 48127, 29695, 28575, 31743, 32767, 14335, 13311, 0, 0, 0, 0, 0, 11039, 30719, 32767, 49151, 49151, 49151, 49151, 49151, 49151, 65535,
65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 49151, 49151, 49151, 49151, 49151, 48127, 32767, 31743, 31743, 12191, 10933, 0, 0, 0, 0, 8720, 6777, 28671,
48127, 49151, 49151, 49151, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 49151, 49151, 48127, 31743, 31743, 29695, 11103, 12191,
4096, 0, 0, 0, 0, 8892, 12191, 29695, 49151, 49151, 49151, 49151, 49151, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535,
47103, 47103, 46047, 28575, 29695, 30719, 28575, 16383, 11039, 8735, 0, 0, 13311, 30719, 30719, 29695, 48127, 48127, 48127, 47103, 64511, 63487, 64511, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535,
65535, 65535, 65535, 65535, 65535, 63487, 64511, 47103, 46079, 48127, 49151, 48127, 47103, 46079, 29695, 30719, 11007, 8735, 0, 0, 0, 9884, 28575, 30719, 32767, 49151, 49151, 48127, 47103, 64511, 65535, 65535,
65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 49151, 49151, 49151, 49151, 49151, 49151, 48127, 30719, 12223, 8760, 10581, 0, 0, 16383, 9948, 30719, 28575,
31743, 49151, 49151, 49151, 49151, 48127, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 49151, 49151, 49151, 49151, 47103, 29695, 11135,
5461, 0, 0, 0, 6348, 8857, 28607, 27519, 27487, 46079, 46079, 47103, 47103, 47103, 63487, 63487, 64511, 64511, 64511, 65535, 65535, 65535, 65535, 65535, 64511, 64511, 64511, 64511, 64511, 64511, 63487, 64511,
62463, 46047, 44959, 44991, 46079, 29695, 26399, 6582, 8720, 0, 0, 0, 8892, 26431, 27391, 27357, 46047, 48127, 46079, 47103, 47103, 64511, 65535, 64511, 64511, 64511, 65535, 65535, 65535, 65535, 65535, 65535,
65535, 65535, 65535, 64511, 64511, 64511, 64511, 65535, 64511, 63487, 46079, 46079, 47103, 31743, 28671, 8861, 8727, 0, 0, 0, 6512, 27423, 47103, 48127, 49151, 49151, 49151, 49151, 65535, 65535, 65535, 65535,
65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 64511, 47103, 47103, 46079, 27423, 8859, 10015, 0, 0, 8720, 8858, 28639, 30719, 48127,
48127, 48127, 47103, 46079, 62463, 63487, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 47103, 47103, 46079, 43839, 27519, 28639,
28671, 9947, 0, 0, 7701, 27487, 28575, 28575, 46079, 47103, 46079, 46079, 62463, 63487, 64511, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 64511, 64511, 64511, 48127,
47103, 46079, 44991, 46079, 46079, 43871, 29695, 29695, 29695, 11103, 8720, 31, 5556, 25278, 28607, 28671, 47103, 49151, 49151, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535,
65535, 65535, 65535, 65535, 65535, 65535, 64511, 47103, 47103, 46079, 47103, 47103, 47103, 44959, 29695, 29695, 27487, 7736, 0, 0, 5461, 8795, 11135, 27551, 46079, 47103, 65535, 65535, 65535, 65535, 65535, 65535,
65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 64511, 65535, 49151, 49151, 48127, 47103, 30719, 30719, 29695, 29695, 31743, 29695, 12191, 0, 0, 0, 8464, 7736, 27487,
28607, 43903, 47103, 47103, 46079, 47103, 49151, 65535, 64511, 64511, 65535, 64511, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 64511, 63487, 63487, 49151, 49151, 49151, 49151, 46079, 26399, 8824, 8858, 9917,
9950, 8730, 0, 0, 0, 8720, 8925, 30719, 29663, 44991, 45023, 46079, 47103, 48127, 48127, 48127, 63487, 65535, 65535, 64511, 64511, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 64511, 63487, 63487, 63487,
48127, 49151, 49151, 49151, 30719, 27487, 2060, 8727, 6547, 31, 0, 0, 0, 8735, 6716, 28671, 29695, 32767, 32767, 49151, 49151, 47103, 47103, 63487, 63487, 64511, 64511, 64511, 64511, 65535, 65535, 65535,
65535, 64511, 65535, 65535, 65535, 64511, 47103, 47103, 46079, 45055, 44959, 46079, 30719, 32767, 12094, 8720, 0, 0, 0, 0, 0, 0, 7768, 28639, 31743, 32767, 49151, 49151, 49151, 48127, 64511, 64511,
65535, 65535, 65535, 64511, 65535, 65535, 65535, 65535, 65535, 65535, 48127, 49151, 65535, 65535, 48127, 49151, 47103, 46079, 26399, 8926, 10079, 27487, 8795, 8727, 0, 0, 0, 0, 0, 0, 5461, 12191,
32767, 32767, 30719, 45023, 47103, 48127, 48127, 48127, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 64511, 65535, 48127, 49151, 49151, 65535, 48127, 48127, 48127, 46079, 28671, 8959, 2057, 9951, 8725, 31,
0, 0, 0, 0, 0, 0, 0, 7740, 27487, 28575, 11135, 26431, 27487, 48127, 47103, 47103, 49151, 64511, 65535, 64511, 63487, 63487, 64511, 64511, 63487, 48127, 48127, 49151, 49151, 49151, 48127, 49151,
49151, 48127, 28671, 29695, 8959, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8927, 7736, 0, 9982, 26399, 30719, 48127, 47103, 47103, 48127, 49151, 65535, 49151, 49151, 65535, 65535,
65535, 48127, 47103, 48127, 48127, 48127, 47103, 47103, 48127, 46079, 28639, 12287, 8891, 8720, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8720, 9914, 31743, 27583, 28671, 30719, 46079,
46079, 47103, 47103, 49151, 47103, 47103, 47103, 48127, 47103, 47103, 47103, 47103, 47103, 28607, 29695, 31743, 31743, 27551, 9983, 11071, 5813, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 8720, 6681, 28639, 25277, 27583, 26399, 29695, 27551, 45023, 45055, 47103, 48127, 48127, 46079, 47103, 46079, 48127, 48127, 46079, 47103, 28671, 28671, 30719, 32767, 28607, 7737, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9983, 4368, 10079, 8959, 30719, 27615, 43935, 45023, 46079, 48127, 47103, 46079, 46079, 46079, 46079, 46079, 46047, 46079, 29695, 8925, 10015,
30719, 31743, 11103, 31, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5461, 5626, 27551, 26399, 26431, 28671, 29695, 47103, 45055, 28671, 27519,
29695, 27583, 46079, 45055, 28671, 29695, 8958, 4206, 11071, 31743, 11103, 8720, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 10015,
27551, 28671, 30719, 27519, 48127, 27583, 28671, 25375, 26495, 25343, 27583, 25310, 27519, 31743, 11167, 0, 3184, 10015, 6742, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 3078, 7771, 25246, 28671, 24253, 28671, 26463, 27647, 7902, 6745, 5624, 26495, 7804, 8894, 30719, 11167, 0, 0, 5461, 31, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8720, 6547, 10047, 7836, 27615, 7837, 8959, 8727, 0, 16, 9055, 1023, 3, 10079, 6777, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8991, 6679, 8720, 0,
0, 0, 0, 0, 0, 528, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8720, 8720, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8720, 8726, 8694, 9650, 8720, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12287, 0, 0, 5461, 9819, 25080, 27359, 9785,
9750, 8720, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9951,
14335, 9951, 8720, 8763, 12159, 27325, 30719, 27391, 9782, 6582, 5823, 15360, 8720, 0, 0, 0, 0, 15360, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 8890, 10047, 30719, 28575, 6487, 9983, 31743, 28447, 48127, 28447, 26233, 9951, 9918, 8626, 11005, 6345, 8720, 0, 0, 9945, 8761, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11103, 12191, 27487, 30719, 32767, 27455, 26303, 31743, 29567, 49151, 46079, 30719, 32767, 30719, 28447, 30719, 9948, 10047, 0,
9849, 29663, 28543, 10943, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9981, 29695, 31743, 31743, 32767, 32767, 31743, 32767, 31743, 46015, 49151, 48127,
47103, 49151, 31743, 47103, 31743, 29631, 29695, 26301, 27423, 30719, 30719, 14335, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8826, 29663, 32767, 49151,
49151, 47103, 47103, 48127, 47103, 47103, 49151, 49151, 47103, 49151, 49151, 48127, 48127, 47103, 47103, 29695, 29695, 30719, 29663, 9916, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 6480, 28575, 48127, 49151, 49151, 49151, 48127, 49151, 48127, 49151, 49151, 49151, 48127, 49151, 48127, 48127, 49151, 49151, 47103, 49151, 48127, 30719, 30719, 26301, 6582, 0, 0, 0,
0, 0, 0, 0, 0, 0, 2053, 8860, 8192, 8720, 8727, 6348, 26333, 30719, 47103, 49151, 49151, 48127, 65535, 65535, 64511, 64511, 65535, 48127, 48127, 48127, 47103, 49151, 49151, 48127, 46079, 49151,
49151, 49151, 48127, 27423, 9884, 5120, 0, 0, 0, 0, 0, 0, 0, 8720, 6616, 27455, 10973, 11005, 25241, 9948, 28543, 48127, 48127, 47103, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 64511,
63487, 47103, 47103, 49151, 49151, 47103, 47103, 49151, 49151, 49151, 48127, 31743, 29695, 11167, 9849, 5461, 0, 0, 0, 0, 0, 8720, 9916, 30719, 31743, 32767, 48127, 47103, 48127, 49151, 49151, 49151,
65535, 65535, 65535, 65535, 65535, 65535, 65535, 63487, 63487, 64511, 49151, 65535, 65535, 63487, 49151, 49151, 49151, 49151, 48127, 31743, 29695, 11071, 9983, 8860, 8464, 0, 0, 0, 0, 0, 9948, 30719,
32767, 49151, 49151, 49151, 49151, 49151, 49151, 49151, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 64511, 65535, 65535, 49151, 49151, 49151, 49151, 49151, 48127, 30719, 30719, 31743, 14335,
11103, 0, 0, 0, 0, 0, 8991, 29695, 48127, 49151, 48127, 49151, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 64511, 49151, 49151,
48127, 48127, 49151, 47103, 47103, 30719, 30719, 12191, 8735, 0, 0, 0, 0, 8720, 9983, 28639, 47103, 49151, 49151, 48127, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535,
65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 48127, 47103, 46079, 30719, 29663, 28607, 9948, 4096, 0, 0, 0, 0, 8760, 11135, 29695, 47103, 49151, 49151, 48127, 48127, 64511, 65535, 49151,
65535, 64511, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 64511, 63487, 64511, 64511, 47103, 46047, 44959, 27455, 28575, 30719, 30719, 29695, 10940, 8720, 0, 0, 11263, 29695, 31743, 31743,
47103, 47103, 47103, 46047, 62463, 62463, 64511, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 63487, 63487, 48127, 47103, 47103, 49151, 48127, 48127, 48127, 48127, 30719,
11071, 8727, 0, 0, 0, 9917, 29695, 31743, 49151, 49151, 48127, 47103, 63487, 63487, 64511, 64511, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 64511, 65535, 49151,
49151, 49151, 49151, 49151, 49151, 49151, 47103, 28671, 9883, 8720, 0, 0, 15391, 9914, 29663, 28543, 32767, 49151, 49151, 49151, 48127, 47103, 63487, 64511, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535,
65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 48127, 49151, 49151, 49151, 48127, 29695, 11135, 10933, 0, 0, 0, 6540, 8824, 27519, 27455, 28639, 46047, 47103, 47103, 47103, 46079, 46079, 62463,
63487, 63487, 63487, 64511, 64511, 64511, 63487, 64511, 63487, 63487, 63487, 63487, 63487, 62463, 62463, 63487, 45023, 44927, 43903, 46079, 46079, 28639, 27487, 6582, 8720, 0, 0, 0, 9851, 9983, 27358, 29631,
47103, 46079, 47103, 48127, 49151, 64511, 64511, 63487, 63487, 63487, 64511, 65535, 65535, 65535, 65535, 65535, 64511, 64511, 64511, 63487, 63487, 63487, 63487, 65535, 64511, 47103, 46079, 46079, 47103, 47103, 31743, 9950,
6547, 0, 0, 0, 7600, 27423, 47103, 49151, 49151, 49151, 49151, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535,
65535, 65535, 48127, 46079, 48127, 47103, 30719, 11005, 9949, 0, 0, 8720, 8858, 28607, 30719, 47103, 48127, 47103, 46079, 44959, 61375, 62463, 63487, 63487, 64511, 64511, 65535, 65535, 65535, 65535, 65535, 65535,
65535, 65535, 65535, 65535, 65535, 65535, 65535, 64511, 63487, 63487, 46079, 46079, 47103, 43871, 27487, 27455, 28575, 9915, 0, 0, 6676, 26399, 27519, 27487, 47103, 47103, 46079, 45055, 61407, 62463, 63487, 64511,
65535, 65535, 64511, 64511, 64511, 65535, 64511, 65535, 64511, 64511, 65535, 64511, 63487, 62463, 63487, 47103, 46079, 45023, 43871, 46079, 46079, 44959, 28671, 28607, 28607, 11039, 8720, 31, 6547, 25212, 27519, 28639,
47103, 48127, 48127, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 64511, 65535, 65535, 65535, 64511, 64511, 64511, 63487, 47103, 47103, 45055, 45055, 47103, 47103, 46079, 44991, 28607,
26399, 7640, 0, 0, 5450, 8726, 25246, 27519, 46079, 49151, 48127, 64511, 65535, 65535, 65535, 65535, 65535, 64511, 64511, 65535, 65535, 65535, 65535, 64511, 64511, 65535, 65535, 65535, 64511, 63487, 65535, 64511,
48127, 47103, 46079, 29695, 30719, 31743, 29695, 30719, 29695, 12159, 0, 0, 0, 8720, 7703, 27519, 45023, 47103, 47103, 46079, 46079, 47103, 64511, 64511, 62463, 63487, 64511, 63487, 63487, 64511, 65535, 64511,
64511, 64511, 63487, 64511, 65535, 62463, 62463, 47103, 49151, 49151, 49151, 47103, 27423, 26333, 9948, 9916, 9949, 9849, 0, 0, 0, 8720, 8859, 29695, 29663, 46079, 44991, 45023, 46079, 48127, 48127, 63487,
62463, 63487, 63487, 63487, 63487, 64511, 65535, 64511, 65535, 65535, 65535, 64511, 65535, 62463, 62463, 46079, 47103, 49151, 49151, 49151, 48127, 28575, 3082, 8727, 8727, 31, 0, 0, 0, 8735, 6715, 28575,
28607, 31743, 32767, 49151, 47103, 46079, 46079, 62463, 62463, 63487, 63487, 63487, 63487, 64511, 65535, 64511, 64511, 63487, 63487, 64511, 64511, 63487, 62463, 46079, 46079, 44991, 46079, 47103, 47103, 31743, 11037, 8720,
0, 0, 0, 0, 0, 0, 7704, 28543, 30719, 32767, 49151, 49151, 49151, 48127, 63487, 63487, 64511, 64511, 64511, 63487, 64511, 64511, 65535, 64511, 64511, 63487, 47103, 48127, 65535, 65535, 47103, 48127,
46079, 45055, 28639, 25311, 25310, 26335, 8761, 5461, 0, 0, 0, 0, 0, 0, 6348, 11135, 31743, 32767, 30719, 46079, 47103, 48127, 48127, 47103, 65535, 64511, 64511, 63487, 64511, 64511, 65535, 64511,
63487, 64511, 47103, 47103, 49151, 65535, 47103, 47103, 47103, 46079, 29695, 26463, 6713, 8731, 6547, 31, 0, 0, 0, 0, 0, 0, 0, 6553, 26399, 28575, 11103, 26463, 43903, 47103, 46079, 48127,
49151, 64511, 64511, 64511, 64511, 63487, 64511, 64511, 64511, 64511, 47103, 47103, 48127, 49151, 47103, 47103, 48127, 47103, 27551, 27615, 8925, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
8831, 6742, 0, 25243, 25311, 47103, 47103, 48127, 47103, 47103, 48127, 64511, 48127, 48127, 65535, 65535, 64511, 48127, 46079, 47103, 48127, 48127, 48127, 47103, 48127, 47103, 28639, 11231, 8859, 8720, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 8720, 8858, 28671, 27487, 31743, 30719, 47103, 46079, 47103, 47103, 49151, 48127, 48127, 49151, 49151, 48127, 46079, 45055, 47103, 48127, 45023, 46079, 29695,
31743, 30719, 26463, 10047, 5813, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8720, 7804, 28607, 26399, 28639, 26367, 28671, 42847, 45055, 45055, 47103, 47103, 47103, 46079, 47103,
46079, 46079, 47103, 46079, 48127, 43935, 27519, 29695, 31743, 32767, 11006, 5461, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2048, 8925, 27551, 10047, 8895, 29695,
27519, 43967, 43999, 46079, 46079, 46079, 45055, 46079, 45055, 45055, 46079, 44991, 46079, 43999, 8859, 9982, 29695, 32767, 11071, 8720, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 11263, 6777, 6552, 26367, 25246, 27551, 28671, 30719, 46079, 43935, 44031, 42911, 28671, 26495, 45055, 45055, 45055, 45055, 25278, 5331, 10015, 14335, 11103, 8720, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5450, 8763, 25343, 28671, 29695, 30719, 47103, 42879, 28671, 25375, 28671, 26495, 27615, 26463, 26399, 29695, 25309, 6547,
5230, 10015, 6742, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5120, 6581, 25244, 27519, 26431, 31743, 26463, 27615, 25311,
28671, 26431, 28671, 8925, 24154, 29695, 10047, 8720, 0, 8720, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
8720, 6450, 8924, 6614, 27583, 24155, 23165, 5525, 6747, 6714, 28671, 10079, 3078, 10047, 6777, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8991, 7637, 4507, 3283, 4368, 0, 10079, 8735, 0, 8720, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5450, 9855, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 6553, 8730, 8661, 27423, 8629, 8720, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 11103, 0, 8735, 9919, 12095, 27291, 30719, 12062, 8724, 8730, 8890, 11039, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8208, 13311, 11103, 29695, 11103, 8892, 27487, 31743, 27357, 30719, 27389, 25077, 27423, 13279, 14335, 12287, 0, 0, 0,
0, 15360, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9949, 11007, 15359, 31743, 30719, 30719, 28575, 28575, 31743, 28511, 47103, 28543,
27391, 30719, 30719, 29663, 11039, 7399, 5461, 0, 0, 8760, 8825, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13311, 13311, 29695, 30719, 31743,
32767, 32767, 31743, 31743, 31743, 29663, 49151, 48127, 31743, 31743, 30719, 28479, 29695, 9882, 10973, 2048, 9849, 12127, 28479, 9819, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 10581, 12063, 30719, 31743, 47103, 49151, 49151, 49151, 32767, 30719, 29663, 49151, 48127, 47103, 49151, 31743, 30719, 30719, 29631, 30719, 27356, 27391, 29663, 30719, 12159, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8793, 29599, 32767, 48127, 48127, 48127, 48127, 47103, 47103, 47103, 49151, 48127, 46079, 48127, 48127, 48127, 48127, 48127, 47103, 29663,
30719, 30719, 31743, 30719, 11005, 8720, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15391, 0, 0, 12287, 28543, 30719, 47103, 48127, 49151, 48127, 48127, 48127, 48127, 48127, 49151, 48127,
47103, 48127, 47103, 48127, 49151, 49151, 47103, 49151, 48127, 47103, 32767, 30719, 9983, 5120, 0, 0, 0, 0, 0, 0, 0, 0, 6342, 9818, 11035, 8726, 8456, 5130, 26333, 48127, 46079, 48127,
48127, 47103, 48127, 65535, 65535, 64511, 65535, 47103, 47103, 47103, 46079, 48127, 49151, 47103, 46079, 49151, 48127, 49151, 48127, 28511, 27423, 8831, 0, 0, 0, 0, 0, 0, 0, 8720, 8760, 28511,
30719, 28575, 26266, 9915, 28511, 48127, 47103, 46047, 64511, 63487, 65535, 65535, 64511, 64511, 65535, 63487, 63487, 46079, 46079, 48127, 64511, 46079, 47103, 48127, 48127, 49151, 49151, 30719, 29695, 11167, 8727, 5450,
0, 0, 0, 0, 0, 8735, 9916, 29695, 31743, 48127, 47103, 47103, 48127, 48127, 49151, 48127, 65535, 64511, 65535, 65535, 64511, 64511, 64511, 63487, 62463, 47103, 47103, 48127, 64511, 47103, 49151, 48127,
49151, 49151, 48127, 30719, 29695, 11007, 11007, 8792, 5450, 0, 0, 0, 0, 0, 9916, 29695, 30719, 48127, 49151, 48127, 49151, 48127, 48127, 49151, 65535, 65535, 64511, 65535, 65535, 65535, 65535, 64511,
64511, 64511, 64511, 64511, 64511, 64511, 48127, 48127, 49151, 48127, 47103, 30719, 29695, 29695, 31743, 13183, 10047, 0, 0, 0, 0, 0, 10972, 28607, 30719, 47103, 47103, 48127, 65535, 48127, 64511, 65535,
65535, 65535, 64511, 64511, 64511, 64511, 64511, 64511, 64511, 64511, 64511, 65535, 64511, 47103, 48127, 48127, 48127, 48127, 48127, 46079, 46079, 29663, 30719, 12127, 8735, 0, 0, 0, 0, 31, 8860, 27519,
47103, 48127, 48127, 47103, 49151, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 64511, 65535, 63487, 48127, 47103, 46079, 44991, 29695, 28511, 27487, 9949,
0, 0, 0, 0, 0, 7670, 12159, 29695, 48127, 49151, 48127, 47103, 47103, 64511, 65535, 65535, 64511, 63487, 64511, 64511, 65535, 64511, 64511, 65535, 65535, 65535, 65535, 65535, 63487, 62463, 62463, 62463,
47103, 44959, 43839, 28511, 29695, 29695, 29695, 29695, 9982, 8720, 0, 0, 13119, 29663, 31743, 31743, 47103, 47103, 46079, 44927, 46047, 62463, 63487, 63487, 65535, 64511, 64511, 64511, 65535, 65535, 65535, 65535,
65535, 65535, 65535, 65535, 63487, 62463, 62463, 47103, 47103, 46079, 48127, 47103, 48127, 47103, 48127, 31743, 12191, 8727, 0, 0, 8192, 9916, 29695, 32767, 49151, 48127, 47103, 46079, 46079, 46079, 63487, 63487,
64511, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 64511, 63487, 63487, 63487, 49151, 49151, 49151, 49151, 48127, 49151, 49151, 47103, 28607, 8859, 8720, 0, 0, 0, 9849, 28607, 30719,
32767, 49151, 49151, 48127, 47103, 46079, 63487, 63487, 64511, 64511, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 64511, 65535, 48127, 47103, 47103, 48127, 49151, 48127, 28607, 11071,
10933, 0, 0, 0, 8456, 8758, 27455, 27455, 28575, 47103, 47103, 46079, 46079, 45055, 45055, 45023, 62463, 62463, 62463, 62463, 62463, 63487, 62463, 62463, 62463, 62463, 61439, 61439, 62463, 62463, 61375, 45023,
44959, 43839, 43807, 44991, 46079, 27519, 26367, 6579, 8720, 0, 0, 0, 8825, 26333, 29695, 47071, 46079, 47103, 47103, 48127, 48127, 63487, 63487, 62463, 62463, 62463, 62463, 64511, 64511, 65535, 63487, 63487,
63487, 63487, 62463, 62463, 62463, 62463, 62463, 64511, 64511, 46079, 45055, 45023, 46079, 46079, 29695, 8860, 8727, 0, 0, 0, 8657, 28447, 48127, 49151, 49151, 49151, 48127, 64511, 64511, 65535, 65535, 65535,
65535, 64511, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 64511, 64511, 64511, 65535, 65535, 65535, 64511, 46079, 45055, 47103, 46079, 29695, 9980, 10969, 0, 0, 8720, 9848, 27487, 47103, 48127,
47103, 47103, 45023, 43839, 43871, 44991, 62463, 62463, 63487, 63487, 63487, 64511, 64511, 65535, 64511, 64511, 64511, 64511, 64511, 63487, 63487, 64511, 63487, 63487, 62463, 62463, 44991, 45055, 47103, 46079, 27423, 26301,
27455, 9850, 15360, 0, 6578, 25212, 27455, 27487, 46079, 47103, 46079, 43871, 44959, 62463, 62463, 63487, 63487, 63487, 63487, 63487, 63487, 64511, 63487, 63487, 63487, 63487, 63487, 62463, 62463, 61439, 46079, 46079,
45023, 43903, 42751, 44991, 45055, 46079, 45023, 28607, 27487, 9916, 8720, 31, 5489, 8795, 27519, 28639, 46079, 47103, 47103, 47103, 64511, 65535, 64511, 64511, 64511, 64511, 63487, 63487, 64511, 64511, 64511, 63487,
63487, 63487, 63487, 63487, 62463, 62463, 62463, 46079, 47103, 45023, 44991, 45055, 45055, 46079, 45055, 28639, 26367, 7637, 0, 0, 0, 8826, 28607, 27519, 46079, 47103, 48127, 63487, 64511, 64511, 64511, 64511,
63487, 63487, 63487, 63487, 64511, 64511, 64511, 63487, 63487, 64511, 64511, 64511, 62463, 62463, 64511, 63487, 47103, 46079, 45023, 28639, 29695, 31743, 30719, 29695, 28639, 12159, 0, 0, 11263, 12191, 30719, 29695,
47103, 47103, 46079, 45055, 46079, 46079, 63487, 63487, 61439, 62463, 62463, 62463, 62463, 63487, 63487, 63487, 63487, 63487, 62463, 63487, 63487, 61375, 62463, 62463, 47103, 49151, 48127, 47103, 27519, 26366, 27551, 9950,
9915, 8727, 0, 0, 11263, 12223, 29695, 29695, 47103, 46079, 43903, 44991, 47103, 47103, 47103, 62463, 61439, 62463, 62463, 63487, 62463, 63487, 64511, 63487, 63487, 63487, 63487, 62463, 64511, 61439, 60351, 45023,
46079, 48127, 49151, 49151, 49151, 28575, 8860, 6777, 10581, 0, 0, 0, 0, 8892, 9950, 26399, 28543, 30719, 30719, 47103, 47103, 45055, 45055, 61439, 61439, 62463, 62463, 62463, 62463, 62463, 63487, 62463,
62463, 62463, 62463, 62463, 63487, 62463, 61439, 43967, 43967, 43935, 45023, 48127, 47103, 30719, 11103, 8720, 0, 0, 0, 0, 0, 0, 8725, 27391, 29695, 32767, 49151, 49151, 48127, 47103, 46079, 62463,
63487, 63487, 63487, 63487, 62463, 62463, 64511, 63487, 63487, 62463, 45055, 47103, 64511, 64511, 47103, 46079, 45055, 45055, 43903, 26399, 27551, 27551, 9950, 8720, 0, 0, 0, 0, 0, 0, 5450, 11135,
30719, 31743, 29695, 46079, 47103, 48127, 46079, 46079, 48127, 63487, 63487, 62463, 63487, 63487, 64511, 63487, 62463, 63487, 46079, 46079, 47103, 64511, 47103, 46079, 47103, 46079, 46079, 29695, 27519, 8894, 8725, 0,
0, 0, 0, 0, 0, 0, 0, 6419, 26367, 27519, 26431, 28639, 43903, 47103, 45023, 47103, 48127, 63487, 63487, 63487, 62463, 62463, 63487, 62463, 63487, 47103, 46079, 46079, 47103, 48127, 47103, 46079,
47103, 47103, 45023, 27583, 25279, 7736, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8764, 6582, 3072, 26300, 25310, 46079, 47103, 47103, 47103, 46079, 47103, 63487, 47103, 47103, 64511, 64511,
47103, 47103, 46079, 46079, 47103, 47103, 47103, 47103, 47103, 46079, 28671, 26463, 7802, 8720, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8890, 28671, 28671, 29695, 47103, 47103,
45055, 46079, 46079, 48127, 48127, 47103, 48127, 49151, 47103, 45055, 46079, 46079, 48127, 46079, 46079, 43999, 29695, 29695, 29695, 10015, 6547, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 8720, 7771, 27551, 27519, 28639, 26399, 28671, 42815, 43967, 43999, 46079, 46079, 46079, 46079, 47103, 45055, 43999, 45055, 45055, 48127, 46079, 26463, 27519, 29695, 31743, 26431, 6611, 16, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2048, 8924, 27519, 10015, 7804, 28639, 26431, 43903, 43935, 46079, 46079, 46079, 43999, 45055, 43999, 43967, 45055, 43935, 47103, 45055, 25211, 8892,
12287, 30719, 10014, 5450, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5120, 13311, 8727, 7574, 25246, 26367, 27551, 28639, 30719, 45055, 43935, 27551, 26495,
27647, 25343, 43935, 43999, 46079, 45023, 25212, 5424, 9982, 13311, 10047, 8720, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8720, 6550,
25245, 27583, 27615, 29695, 46079, 42783, 27583, 25279, 27583, 26431, 27551, 26431, 26367, 28639, 25244, 6547, 4237, 9983, 8725, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 11103, 26399, 26431, 26399, 26431, 29695, 26399, 26463, 24189, 28671, 25343, 28639, 8925, 24088, 28639, 8925, 8720, 0, 8720, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6811, 7770, 8828, 6547, 26463, 24121, 24156, 23098, 28671, 24252, 27583, 9023, 4100, 10079, 5813, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8892, 6582, 6551, 4403,
8927, 5557, 8927, 8735, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 6559, 31, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8720, 9855, 0, 0, 0, 0, 8720, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10933, 9849, 8660, 28415, 8660, 5450, 0, 0, 11039, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11103, 0, 8735, 9820, 12031, 27291, 30719, 12029,
9748, 10778, 12191, 16383, 14335, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8192, 12031, 11071,
12191, 11071, 8764, 27423, 30719, 27356, 29695, 28381, 26133, 27359, 12223, 32767, 14335, 0, 0, 0, 0, 15360, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 10908, 10973, 14335, 31743, 30719, 30719, 28575, 28575, 31743, 28447, 46079, 29567, 28447, 29695, 29695, 29631, 10973, 6569, 5461, 0, 0, 8723, 9847, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12287, 13247, 28543, 29695, 30719, 31743, 32767, 31743, 31743, 30719, 29631, 48127, 47103, 31743, 31743, 30719, 28415, 28543, 9848, 9948, 5126,
8661, 10909, 12031, 10778, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8704, 12063, 29631, 30719, 47103, 32767, 49151, 48127, 31743, 30719, 29599, 48127, 47103,
46079, 48127, 30719, 29663, 29695, 29599, 30719, 27323, 27423, 29567, 30719, 12191, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8759, 28479, 31743, 47103,
48127, 47103, 47103, 47103, 46079, 47103, 48127, 47103, 46079, 48127, 47103, 47103, 47103, 48127, 47103, 29663, 31743, 30719, 31743, 30719, 11004, 8720, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
15391, 0, 0, 11263, 27455, 29695, 29663, 47103, 48127, 47103, 47103, 47103, 47103, 47103, 48127, 47103, 47103, 47103, 46079, 47103, 49151, 49151, 47103, 48127, 48127, 47103, 31743, 30719, 11006, 8704, 0, 0,
0, 0, 0, 0, 0, 0, 8456, 9750, 11069, 8595, 5450, 8528, 26332, 47103, 46015, 47103, 47103, 47103, 47103, 64511, 64511, 63487, 64511, 47103, 46079, 46079, 46015, 47103, 48127, 47103, 46015, 48127,
47103, 48127, 47103, 28479, 27391, 9951, 0, 0, 0, 0, 0, 0, 0, 8720, 9816, 27423, 29695, 27423, 26233, 9916, 28479, 47103, 46079, 45983, 63487, 63487, 48127, 64511, 63487, 63487, 64511, 62463,
62463, 46047, 46047, 47103, 47103, 46015, 46079, 47103, 47103, 49151, 48127, 29695, 28607, 11039, 10933, 0, 0, 0, 0, 0, 0, 8735, 10940, 29663, 30719, 47103, 47103, 47103, 47103, 48127, 48127, 47103,
64511, 63487, 64511, 64511, 63487, 63487, 63487, 62463, 62431, 46047, 46079, 46079, 63487, 47103, 48127, 47103, 48127, 48127, 47103, 29695, 28575, 10941, 11005, 8626, 8720, 0, 0, 0, 0, 0, 9818, 28575,
30719, 47103, 48127, 49151, 48127, 47103, 47103, 48127, 65535, 64511, 63487, 64511, 64511, 64511, 63487, 63487, 63487, 63487, 63487, 63487, 63487, 47103, 47103, 47103, 48127, 48127, 48127, 29695, 29631, 28543, 30719, 11006,
8727, 0, 0, 0, 0, 0, 9948, 28511, 29663, 46079, 46079, 48127, 48127, 48127, 48127, 48127, 64511, 64511, 63487, 63487, 63487, 63487, 63487, 63487, 63487, 63487, 63487, 64511, 63487, 46079, 47103, 46079,
47103, 47103, 48127, 44959, 29631, 28543, 29695, 11069, 15391, 0, 0, 0, 0, 16383, 8729, 27423, 46079, 47103, 47103, 47103, 48127, 48127, 48127, 48127, 64511, 64511, 64511, 64511, 64511, 64511, 64511, 64511,
64511, 64511, 64511, 64511, 64511, 63487, 47103, 46079, 47103, 46079, 46047, 27423, 28543, 27391, 27391, 10941, 5120, 0, 0, 0, 0, 9750, 11071, 29663, 48127, 47103, 47103, 46079, 47103, 47103, 48127, 48127,
64511, 63487, 63487, 63487, 63487, 63487, 63487, 64511, 64511, 64511, 64511, 63487, 62463, 61407, 61407, 46047, 46079, 44895, 43775, 27423, 29663, 28607, 28607, 28639, 9916, 8720, 0, 0, 10047, 12159, 30719, 30719,
46079, 46079, 46015, 44895, 44959, 44991, 62463, 62463, 64511, 63487, 63487, 63487, 63487, 64511, 64511, 64511, 64511, 63487, 63487, 63487, 62463, 61375, 61375, 47103, 46079, 46047, 47103, 46047, 47103, 46079, 47103, 30719,
12127, 10933, 0, 0, 0, 10907, 29663, 32767, 48127, 47103, 47103, 46047, 45023, 46079, 62463, 62463, 63487, 63487, 64511, 64511, 64511, 64511, 65535, 65535, 65535, 65535, 64511, 63487, 62463, 62463, 62463, 48127,
48127, 47103, 48127, 47103, 48127, 47103, 46079, 28543, 9882, 8720, 0, 0, 0, 9815, 28511, 30719, 31743, 47103, 48127, 48127, 46079, 46079, 46079, 62463, 63487, 63487, 63487, 65535, 65535, 65535, 65535, 65535,
64511, 65535, 64511, 63487, 63487, 64511, 64511, 48127, 47103, 46079, 46079, 47103, 48127, 47103, 27519, 9951, 8720, 0, 0, 0, 8720, 9748, 27358, 27423, 27487, 46079, 46079, 46079, 44991, 44959, 44959, 43903,
61343, 61407, 61407, 61439, 61439, 62463, 61407, 61439, 61375, 61407, 61375, 61375, 61343, 61343, 60319, 44959, 43839, 43775, 43774, 43903, 44991, 27455, 26302, 6546, 8720, 0, 0, 0, 8760, 26300, 29695, 30719,
46015, 46079, 47103, 48127, 47103, 46079, 46079, 61407, 61375, 61375, 61439, 62463, 63487, 63487, 62463, 62463, 62463, 62463, 61439, 61375, 61375, 61407, 61439, 47103, 47103, 46079, 44959, 43903, 45055, 44959, 28639, 8826,
8720, 0, 0, 0, 8657, 27422, 48127, 49151, 48127, 48127, 48127, 64511, 63487, 64511, 64511, 64511, 63487, 63487, 63487, 64511, 64511, 65535, 65535, 65535, 65535, 64511, 64511, 63487, 62463, 63487, 63487, 64511,
64511, 63487, 46079, 44959, 46079, 44991, 28607, 9981, 9849, 0, 0, 16383, 9814, 27390, 47103, 47103, 47103, 46079, 44927, 43775, 43807, 43871, 44959, 61407, 61439, 62463, 62463, 63487, 63487, 63487, 63487, 63487,
63487, 63487, 63487, 62463, 62463, 63487, 62463, 62463, 61407, 46079, 43903, 44959, 46079, 44991, 26333, 26234, 26334, 8758, 15360, 0, 8592, 8728, 27423, 27455, 47103, 46079, 44959, 43775, 43839, 61407, 61343, 61439,
61439, 62463, 62463, 62463, 62463, 62463, 62463, 62463, 62463, 61439, 62463, 61439, 60351, 60319, 44991, 44991, 43871, 42783, 42687, 43871, 44927, 44959, 28575, 27487, 26367, 8826, 0, 0, 7636, 25179, 27455, 27455,
46079, 46079, 46079, 46079, 63487, 64511, 62463, 63487, 63487, 62463, 62463, 62463, 63487, 63487, 62463, 62463, 62463, 62463, 62463, 62463, 61439, 61439, 61439, 46079, 47103, 44991, 43903, 43935, 43935, 44991, 45023, 28575,
26269, 6582, 0, 0, 8727, 26334, 28575, 27423, 45023, 47103, 47103, 46079, 46079, 47103, 63487, 63487, 62463, 62463, 62463, 62463, 63487, 62463, 62463, 62463, 62463, 63487, 62463, 63487, 61439, 62463, 62463, 46079,
46079, 43935, 43935, 27551, 29695, 30719, 31743, 30719, 27455, 10943, 0, 0, 10943, 11103, 29695, 29663, 46079, 46079, 44959, 45023, 46079, 45055, 46079, 61439, 60351, 61439, 61439, 61439, 61439, 61439, 62463, 62463,
61439, 62463, 61439, 62463, 62463, 60287, 61439, 46079, 46079, 47103, 47103, 46079, 27455, 26367, 30719, 29695, 10015, 8727, 0, 0, 11263, 11135, 29695, 28607, 30719, 44991, 43839, 46079, 47103, 46079, 46079, 61439,
60351, 61407, 61439, 61439, 61439, 62463, 63487, 62463, 62463, 62463, 62463, 61439, 62463, 60319, 42815, 43903, 45023, 47103, 48127, 49151, 49151, 28543, 8925, 11167, 8890, 0, 0, 0, 0, 8827, 9949, 26335,
28511, 29695, 29695, 48127, 46079, 44991, 43935, 60319, 60351, 61439, 61375, 61375, 61407, 61439, 62463, 62463, 61439, 61439, 44031, 61439, 62463, 61407, 43903, 42783, 42847, 43871, 44959, 46079, 46079, 31743, 9981, 6348,
0, 0, 0, 0, 0, 0, 8758, 26236, 28607, 31743, 49151, 48127, 47103, 46079, 45055, 61439, 61439, 46079, 62463, 62463, 61439, 61439, 63487, 62463, 62463, 61439, 43999, 45055, 46079, 63487, 46079, 45055,
43935, 43935, 27455, 26335, 27487, 31743, 26301, 6547, 0, 0, 0, 0, 0, 0, 8720, 11039, 29695, 31743, 30719, 45055, 46079, 46079, 45055, 45055, 46079, 62463, 62463, 61439, 61439, 62463, 63487, 62463,
61439, 62463, 45055, 45055, 46079, 47103, 46079, 45055, 45055, 45023, 45055, 27583, 26367, 27455, 6647, 4375, 0, 0, 0, 0, 0, 0, 0, 6450, 26302, 27487, 26431, 28607, 46079, 46079, 43935, 46079,
47103, 62463, 62463, 62463, 61439, 61439, 62463, 61439, 61439, 46079, 45055, 45055, 46079, 47103, 46079, 45055, 45055, 46079, 46079, 26431, 24157, 7740, 5461, 31, 0, 0, 0, 0, 0, 0, 0, 0,
8731, 8725, 4096, 26333, 28639, 45055, 46079, 45055, 46079, 46079, 46079, 46079, 46079, 46079, 63487, 47103, 46079, 46079, 46079, 45055, 46079, 46079, 47103, 46079, 46079, 45055, 29695, 26367, 6679, 8720, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8889, 28607, 28671, 28671, 45055, 46079, 45023, 46079, 45055, 47103, 47103, 46079, 47103, 47103, 46079, 43967, 45055, 45055, 47103, 45055, 45055, 43903,
28671, 28671, 28671, 8892, 6547, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8720, 7737, 27455, 27455, 27519, 25311, 44991, 42751, 43903, 43903, 45055, 45023, 45055, 45055, 46079,
43967, 43903, 43967, 43935, 47103, 46079, 26431, 26431, 27551, 29695, 26366, 6611, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3072, 8859, 11071, 9982, 7705, 26431,
26367, 26431, 42783, 45023, 45055, 45055, 43903, 43967, 42879, 42815, 43999, 42847, 46079, 45055, 24220, 8826, 10015, 28671, 8892, 5450, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 8192, 10047, 8727, 7604, 8794, 25246, 26399, 26431, 29695, 43967, 42847, 26431, 26431, 27551, 24189, 42847, 43903, 43967, 43967, 24155, 5489, 8859, 12287, 10013, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8720, 7505, 25211, 27519, 26463, 28671, 45055, 41695, 26463, 24190, 26463, 25311, 26463, 25343, 25246, 26463, 7770, 4368,
6342, 9980, 8727, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10047, 26303, 26367, 25214, 26367, 28671, 25279, 25343, 24155,
27647, 25311, 27583, 8893, 7670, 26463, 8827, 0, 0, 31, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
8760, 8825, 7640, 5425, 25311, 23031, 24089, 6680, 27615, 7835, 26463, 8927, 5285, 9951, 5813, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7641, 5461, 6582, 5457, 7806, 6550, 8927, 8735, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4631, 31, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8720, 8727, 0,
0, 0, 0, 8720, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 8735, 8727, 8659, 10973, 9747, 5450, 0, 0, 11039, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 9855, 0, 8735, 9787, 11006, 10905, 30687, 12028, 9781, 9849, 12191, 15359, 14335, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12031, 11007, 11007, 10973, 8760, 10974, 30719, 27322, 29599, 27355, 9749, 10941, 12127, 31743, 13311, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8760, 9915, 14335, 30719, 30719, 30719, 28543, 28511, 30719, 28414, 45983, 28479,
28415, 29631, 29663, 29567, 10906, 8714, 10581, 0, 0, 8720, 9849, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12031, 12095, 12063, 29663, 29695,
31743, 32767, 30719, 30719, 30719, 29599, 47103, 30719, 30719, 30719, 29663, 27356, 27359, 9750, 9915, 6342, 9650, 10874, 11997, 9849, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 15360, 10940, 28415, 29663, 29663, 31743, 48127, 48127, 30719, 30719, 29567, 48127, 47103, 46015, 47103, 29695, 29567, 29599, 28511, 29663, 27322, 27390, 28479, 30719, 12095, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8726, 28415, 30719, 47103, 47103, 47103, 47103, 46079, 46047, 46047, 48127, 46047, 46015, 47103, 46047, 46047, 46079, 47103, 46047, 29599,
31743, 30687, 30719, 29599, 9914, 16383, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15391, 0, 0, 10943, 10909, 29599, 28511, 47103, 47103, 46079, 46047, 47103, 46079, 47103, 47103, 45983,
46047, 47103, 45983, 47103, 48127, 48127, 46015, 47103, 47103, 46047, 30719, 29599, 10940, 8704, 0, 0, 0, 0, 0, 0, 0, 0, 5450, 9747, 11004, 6348, 5461, 6540, 26299, 30719, 45951, 47103,
46079, 46047, 47103, 47103, 63487, 62463, 63487, 46015, 46047, 46015, 44927, 47103, 47103, 46047, 44895, 47103, 46015, 47103, 46047, 28413, 27391, 10943, 0, 0, 0, 0, 0, 0, 0, 16383, 9782, 27390,
29695, 27390, 9848, 9882, 28447, 47103, 45983, 44895, 46015, 46015, 47103, 63487, 62463, 62463, 63487, 46015, 46047, 44959, 44927, 46047, 46047, 44927, 46015, 46047, 46015, 48127, 47103, 29599, 28543, 9983, 8720, 0,
0, 0, 0, 0, 0, 8735, 10971, 29599, 30719, 30719, 46047, 29663, 30719, 47103, 47103, 46079, 63487, 62463, 63487, 63487, 62463, 62463, 62463, 44991, 44959, 44959, 46047, 46047, 46015, 46047, 47103, 46079,
47103, 48127, 46079, 28607, 28511, 9851, 10971, 8593, 0, 0, 0, 0, 0, 16352, 10838, 28415, 29663, 47103, 47103, 48127, 48127, 47103, 47103, 47103, 48127, 63487, 62463, 63487, 63487, 63487, 62463, 62463,
62463, 62463, 62463, 62463, 47103, 46079, 46079, 46079, 47103, 47103, 47103, 29599, 28543, 28447, 29663, 11004, 10933, 0, 0, 0, 0, 0, 11995, 27423, 29631, 45983, 46015, 47103, 47103, 47103, 47103, 47103,
47103, 62463, 62463, 62463, 62463, 62463, 62463, 62463, 63487, 62431, 62463, 63487, 62431, 44959, 45023, 44959, 46047, 47103, 47103, 44895, 28511, 27423, 29663, 11037, 15391, 0, 0, 0, 0, 16383, 8760, 27359,
45983, 46079, 46079, 46079, 47103, 47103, 47103, 48127, 63487, 62463, 63487, 63487, 63487, 63487, 63487, 63487, 63487, 63487, 63487, 63487, 63487, 46079, 46079, 46079, 46079, 46015, 44959, 27358, 28447, 27325, 10974, 9850,
8192, 0, 0, 0, 0, 10804, 10974, 28543, 46079, 46079, 46047, 46015, 46079, 46079, 47103, 47103, 47103, 62463, 62463, 62463, 62463, 62463, 62463, 63487, 63487, 63487, 63487, 62463, 62463, 43903, 44927, 44959,
46079, 44863, 27357, 27357, 28575, 28543, 28479, 27423, 9785, 15391, 0, 0, 8735, 10975, 29631, 29695, 28575, 45983, 44927, 43807, 44863, 44895, 61343, 62431, 62463, 62463, 62463, 62463, 62463, 63487, 63487, 63487,
63487, 63487, 62463, 62463, 61439, 43871, 44927, 46079, 46079, 44927, 46079, 44927, 46079, 44991, 46015, 29663, 11039, 10933, 0, 0, 0, 9850, 28543, 31743, 30719, 46079, 46079, 44927, 44927, 44959, 45023, 61407,
62463, 62463, 63487, 63487, 62463, 63487, 63487, 64511, 63487, 64511, 63487, 62463, 61407, 61407, 46079, 47103, 47103, 46079, 47103, 46079, 47103, 46079, 44927, 27423, 9849, 15391, 0, 0, 0, 9750, 27358, 29695,
30719, 47103, 47103, 47103, 46079, 44991, 45023, 61407, 62463, 62463, 62463, 63487, 63487, 64511, 64511, 64511, 63487, 63487, 63487, 62463, 63487, 63487, 63487, 47103, 46079, 45023, 44991, 46079, 47103, 46047, 26335, 9886,
8720, 0, 0, 0, 5450, 8722, 26266, 27357, 27391, 44959, 44959, 44927, 44895, 43775, 43839, 43807, 43839, 60255, 60255, 60287, 60255, 61311, 60255, 60287, 60255, 60287, 60255, 60223, 60223, 60255, 43839, 43871,
43775, 42717, 42684, 43807, 27519, 27358, 26235, 6512, 0, 0, 0, 0, 8727, 9883, 29695, 30687, 44927, 46047, 46079, 46079, 46079, 44991, 44959, 43871, 60223, 60255, 60319, 61439, 62463, 62463, 61407, 61439,
61407, 61375, 60287, 60255, 60287, 60255, 44991, 46079, 46079, 44991, 43903, 43807, 44959, 27423, 27519, 7735, 5461, 0, 0, 0, 8654, 28446, 47103, 48127, 47103, 47103, 47103, 47103, 62463, 63487, 63487, 63487,
62463, 62463, 62463, 63487, 63487, 63487, 63487, 63487, 63487, 63487, 62463, 61439, 61439, 62463, 62463, 63487, 62463, 46079, 44991, 43775, 44927, 43807, 27519, 10046, 8727, 0, 0, 16383, 8755, 26267, 29695, 46079,
46015, 44927, 43807, 43742, 43743, 43775, 43807, 43871, 43871, 60319, 61439, 62463, 62463, 62463, 61439, 62463, 62463, 61439, 61439, 61439, 61439, 61439, 45023, 44991, 43903, 44959, 43807, 43839, 44959, 28543, 26332, 26199,
9819, 8757, 15360, 0, 8720, 8692, 27358, 27391, 46047, 44927, 43775, 42652, 43775, 43903, 60191, 60255, 60287, 60319, 61375, 61407, 61407, 61407, 60383, 61439, 60383, 60319, 60351, 60255, 59167, 42751, 43871, 43871,
42751, 42719, 42652, 42719, 43807, 43871, 27487, 27423, 26270, 8759, 15360, 0, 8723, 26202, 27391, 27359, 44959, 46047, 44991, 44991, 46079, 63487, 61439, 61439, 61439, 61439, 61439, 61439, 61439, 61439, 61407, 61407,
60383, 60351, 60351, 61375, 60319, 60287, 43935, 45023, 46079, 43935, 27455, 42751, 43839, 43903, 44927, 27423, 25178, 8725, 0, 0, 5461, 8829, 27487, 27359, 44927, 46079, 45023, 45023, 45055, 46079, 46079, 62463,
61439, 61439, 61439, 61439, 61439, 61439, 61439, 61439, 61439, 61439, 61439, 62463, 61375, 61375, 62463, 45055, 45023, 43871, 27455, 27519, 28671, 29695, 30719, 29695, 9950, 9849, 0, 0, 10943, 9983, 29663, 28543,
44991, 44991, 44927, 44959, 45023, 44959, 45055, 44959, 43871, 43967, 61407, 60319, 60287, 60319, 60351, 60351, 60319, 60351, 60319, 61407, 61439, 43871, 43935, 44991, 45055, 46079, 45055, 44991, 27423, 26334, 29695, 28639,
9949, 5461, 0, 0, 9215, 11071, 28575, 27455, 29695, 28575, 43775, 46047, 46079, 45023, 44991, 43903, 59199, 60287, 60319, 60319, 60319, 60319, 61439, 61407, 61439, 61439, 61439, 60319, 61439, 60223, 42719, 42783,
43935, 46079, 47103, 49151, 48127, 28543, 8893, 11103, 9849, 0, 0, 0, 0, 9819, 9884, 26236, 27423, 29663, 29695, 47103, 45055, 43839, 43839, 43839, 60255, 60319, 60255, 60255, 60287, 60319, 61407, 61407,
60351, 60319, 43935, 43935, 61407, 60287, 42783, 41663, 42719, 43839, 43871, 45055, 44991, 30719, 9981, 4368, 0, 0, 0, 0, 0, 0, 8723, 9818, 27423, 29695, 31743, 47103, 46079, 45055, 43935, 43935,
45023, 45055, 61439, 61375, 60319, 61407, 61439, 61439, 45055, 43967, 42847, 43967, 45055, 46079, 45055, 43935, 42783, 43871, 26335, 25244, 26268, 30719, 25243, 6547, 0, 0, 0, 0, 0, 0, 0, 11007,
28607, 30719, 29695, 44959, 44991, 46079, 43935, 43903, 45055, 45055, 61439, 61375, 60351, 61439, 62463, 61407, 60351, 45055, 43903, 43903, 43967, 46079, 45055, 43903, 45023, 43903, 43935, 26431, 25182, 26335, 6581, 4368,
0, 0, 0, 0, 0, 0, 0, 8528, 26268, 11071, 26399, 28575, 29695, 45055, 43839, 45023, 46079, 45055, 62463, 61439, 45023, 45023, 61407, 60319, 60351, 45055, 43903, 43903, 43967, 46079, 45055, 44991,
44991, 44991, 28607, 26335, 7739, 7640, 4368, 31, 0, 0, 0, 0, 0, 0, 0, 0, 9814, 9619, 5120, 26332, 27551, 45023, 45055, 45023, 45055, 45055, 45055, 46079, 45055, 45055, 46079, 46079,
45055, 45023, 45055, 43935, 45023, 45055, 46079, 45055, 45055, 43903, 28671, 25245, 6582, 8720, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8826, 28543, 28607, 28639, 43967, 45023,
43903, 45023, 43967, 46079, 45055, 46079, 46079, 46079, 45023, 42815, 43935, 43935, 46079, 43967, 45023, 26431, 27487, 27487, 28639, 8859, 6547, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 31, 6647, 26335, 26367, 27455, 25277, 27551, 26302, 42815, 42751, 43903, 43871, 43935, 43903, 45023, 42847, 42751, 42847, 42815, 46079, 45023, 26367, 26399, 26335, 28639, 25309, 6547, 8208, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6336, 8826, 9951, 9916, 7639, 26303, 25245, 26367, 41663, 43935, 43935, 43967, 42815, 42847, 42783, 41663, 43903, 42783, 43967, 27519, 25178, 8793,
8761, 11135, 8825, 8720, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8192, 10047, 5461, 7571, 8727, 25147, 25279, 25247, 28639, 42815, 42719, 25247, 25311,
26431, 24122, 26399, 26431, 27455, 42783, 24089, 6544, 8758, 11103, 8860, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 31, 9650,
25178, 26431, 26367, 27583, 43967, 25246, 26367, 24125, 26399, 25246, 26399, 25311, 25212, 26367, 7736, 4368, 4352, 9948, 5813, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 8727, 24090, 26335, 8795, 25310, 28639, 25246, 25279, 24089, 27551, 24221, 27551, 8925, 7636, 25246, 6680, 0, 0, 31, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7636, 8792, 8725, 6446, 25277, 7638, 24055, 7702, 27519, 7769, 26431, 8895, 8456, 8731, 8720, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8727, 8720, 5461, 5393,
7772, 5589, 8892, 1023, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 8727, 31, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8720, 11799, 0, 0, 0, 0, 15391, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8720, 10933, 9747, 11963, 9747, 8720, 0, 0, 11005, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11799, 0, 8735, 9752, 11996, 10905, 29567, 13051,
9779, 11799, 12095, 14335, 12287, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8727, 10972,
10973, 11004, 8727, 10940, 13215, 27289, 28447, 27289, 9747, 10908, 12031, 30719, 12287, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 9814, 10938, 12159, 30719, 30719, 30719, 12127, 28479, 29599, 28381, 44863, 28414, 28414, 29567, 29631, 28447, 10840, 9612, 8720, 0, 0, 8720, 11799, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10943, 10910, 10941, 28479, 29663, 30719, 31743, 30719, 29695, 29663, 29567, 46015, 29599, 30719, 29663, 29631, 27323, 27291, 9749, 9914, 7399,
8725, 10839, 11964, 11799, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16352, 10874, 27324, 28479, 29567, 30719, 31743, 47103, 30719, 29663, 28511, 47103, 45983,
28543, 46015, 29599, 28415, 28447, 28479, 29599, 27290, 27356, 28381, 29599, 11039, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9748, 28413, 30719, 46047,
47103, 46047, 46015, 46047, 45983, 45983, 47103, 45951, 44895, 46047, 29599, 45983, 46015, 46047, 29567, 28543, 30719, 29567, 29567, 28383, 9783, 16383, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
15360, 0, 0, 8735, 9817, 29535, 28447, 46015, 46015, 46015, 45951, 46047, 46015, 46015, 46079, 44895, 45983, 46015, 44895, 46047, 47103, 47103, 44927, 46079, 30719, 29567, 29631, 28415, 9817, 8704, 0, 0,
0, 0, 0, 0, 0, 0, 8720, 9619, 11036, 8448, 8720, 8720, 26233, 29631, 28479, 45983, 44927, 44927, 45983, 46079, 46047, 62335, 46015, 44927, 44927, 44895, 44863, 46015, 46079, 44927, 44831, 45983,
28511, 46079, 28543, 27291, 27326, 9855, 0, 0, 0, 0, 0, 0, 0, 16383, 10774, 10940, 13247, 10972, 9815, 9849, 28414, 46047, 44863, 44799, 44895, 44863, 46079, 46079, 45983, 62367, 46047, 44927,
44927, 44863, 44863, 44927, 45983, 44831, 44895, 44895, 44895, 47103, 46079, 28447, 27423, 11999, 16383, 0, 0, 0, 0, 0, 0, 8720, 10938, 28479, 29631, 29599, 28543, 29599, 29631, 46047, 46047, 45983,
46015, 45983, 46047, 46079, 62431, 62399, 62399, 44927, 44895, 44927, 44959, 44927, 45983, 45983, 46047, 44991, 46047, 47103, 44959, 27423, 27359, 9752, 10873, 8654, 0, 0, 0, 0, 0, 0, 10804, 27324,
29599, 46047, 46079, 47103, 47103, 46047, 46047, 47103, 47103, 47103, 62431, 62463, 62431, 62463, 62399, 62399, 62431, 61343, 44959, 46015, 46047, 46015, 46015, 46047, 46079, 47103, 46047, 28479, 28447, 27291, 28511, 12029,
8720, 0, 0, 0, 0, 0, 9849, 27291, 29567, 44895, 44895, 46079, 47103, 46079, 46047, 46079, 46079, 46015, 61343, 61375, 61343, 61311, 61311, 61375, 62431, 61311, 61343, 62431, 44927, 44895, 44863, 44863,
44927, 46047, 46047, 27391, 27391, 27293, 12127, 10972, 0, 0, 0, 0, 0, 16383, 9819, 27293, 28479, 44927, 46015, 46047, 46079, 46079, 47103, 47103, 46079, 61375, 62431, 62463, 62463, 62463, 62463, 62463,
62463, 62463, 62463, 62463, 62463, 44991, 44991, 44991, 46015, 44927, 44863, 27292, 27324, 27258, 10907, 9816, 0, 0, 0, 0, 0, 9810, 9851, 28479, 45983, 44927, 44895, 44927, 44959, 46015, 46079, 46079,
46079, 44991, 61311, 44991, 61375, 61375, 61407, 62463, 62463, 62463, 62463, 61407, 44959, 43807, 43839, 44927, 46015, 43775, 27323, 26233, 27455, 28479, 27391, 27359, 9785, 15391, 0, 0, 10933, 10939, 28447, 29631,
28447, 44863, 43807, 43741, 43775, 43775, 43839, 44927, 62431, 61375, 61343, 61343, 61375, 62463, 61407, 61407, 61439, 61407, 61407, 61407, 44927, 43807, 43839, 46047, 46015, 43839, 28543, 27455, 44959, 27455, 28511, 28511,
10972, 8720, 0, 0, 0, 10935, 28479, 30719, 29631, 44895, 44927, 44863, 44863, 44863, 44895, 44927, 61375, 61375, 62463, 62463, 61375, 61439, 62463, 63487, 62463, 63487, 61407, 61343, 61311, 44927, 44991, 46079,
46079, 45023, 46047, 44927, 44991, 44927, 43775, 27326, 9815, 15360, 0, 0, 0, 10773, 10940, 29695, 29663, 29663, 46047, 46047, 44959, 44927, 44927, 44927, 62431, 61375, 61407, 62463, 62463, 62463, 63487, 63487,
62463, 62463, 62463, 62463, 62463, 62463, 62463, 46079, 44959, 44927, 44895, 44991, 46047, 44927, 26270, 8762, 16383, 0, 0, 0, 8720, 9681, 9815, 27356, 27324, 28543, 43775, 43807, 43743, 42653, 43710, 42685,
43775, 42719, 42719, 60191, 59135, 60191, 60159, 59135, 59135, 43807, 43775, 43775, 43775, 43807, 43807, 43807, 42684, 42651, 26234, 26301, 27391, 26267, 26201, 7566, 0, 0, 0, 0, 8725, 10873, 29631, 29663,
43807, 44927, 44927, 46047, 46047, 44895, 43839, 43807, 43743, 43775, 60223, 61343, 61343, 61375, 60255, 60287, 60255, 60255, 59135, 60159, 60191, 43807, 43871, 45023, 45023, 44959, 43807, 42687, 43871, 26269, 27423, 7702,
5461, 0, 0, 0, 9650, 11004, 47103, 47103, 46079, 46079, 46079, 46047, 44991, 46079, 62463, 62463, 61439, 61407, 61375, 62463, 62463, 62463, 62463, 62463, 62463, 62463, 61375, 60287, 61343, 61375, 45055, 46079,
45023, 44959, 43839, 42654, 43807, 26303, 27455, 10013, 8725, 0, 0, 16383, 8753, 9881, 29631, 46015, 44895, 43775, 43742, 42652, 42653, 42685, 42686, 42719, 43775, 43807, 43903, 61343, 61375, 61375, 60319, 60319,
60319, 60319, 60319, 60319, 44959, 44991, 43903, 43871, 42751, 43839, 42686, 43775, 43839, 27455, 26299, 9814, 9784, 8723, 0, 0, 10570, 8690, 26267, 27357, 28543, 27391, 26235, 42617, 43742, 43775, 42654, 42751,
42751, 42751, 60223, 60223, 60223, 59199, 59199, 60255, 59167, 59167, 59167, 59103, 41630, 42654, 42751, 42751, 42653, 42652, 41530, 42621, 42686, 27391, 27391, 27359, 26236, 9750, 15360, 0, 8727, 9816, 26268, 26235,
27423, 44895, 44895, 44895, 44959, 45023, 60287, 61343, 60319, 61343, 60319, 60319, 60319, 60223, 59199, 60255, 59199, 59167, 59167, 60255, 59167, 59167, 43839, 44959, 44991, 27487, 26335, 26302, 27391, 27423, 27423, 26302,
9783, 9619, 0, 0, 8735, 9852, 27423, 26268, 43807, 44927, 44895, 44927, 44959, 44991, 45023, 45055, 43903, 43903, 60287, 60287, 60287, 60255, 60255, 60287, 60287, 60319, 60319, 61375, 60287, 60287, 44991, 44927,
43903, 43807, 27423, 27487, 28575, 28671, 29695, 28607, 9949, 10933, 0, 0, 8735, 9852, 27455, 27423, 44927, 44895, 43839, 43839, 44927, 43839, 44927, 43839, 42751, 42815, 43871, 59167, 59135, 59135, 59167, 59199,
59167, 60255, 59167, 60255, 61343, 42751, 43807, 43871, 44959, 45023, 44959, 27519, 26334, 26300, 28607, 27455, 9851, 8720, 0, 0, 8735, 9887, 27391, 27391, 28607, 28511, 26302, 44959, 44991, 43871, 43839, 42751,
42719, 59167, 60191, 59167, 59167, 59135, 59199, 59199, 59231, 60287, 43903, 59167, 60287, 42751, 42685, 42719, 43871, 45023, 45023, 47103, 30719, 27455, 8859, 8893, 8727, 0, 0, 0, 0, 9814, 9849, 26202,
27325, 28511, 28575, 46079, 43871, 42719, 42751, 42719, 42751, 43839, 59135, 59135, 59167, 59167, 60255, 60255, 42815, 42783, 42783, 42783, 43871, 42783, 42687, 41563, 41564, 42751, 43807, 44959, 27487, 29695, 9981, 8464,
0, 0, 0, 0, 0, 0, 9650, 9816, 26303, 28607, 30719, 46079, 44991, 44959, 43871, 43839, 43903, 44991, 44959, 43903, 43903, 43935, 61407, 43967, 43935, 43871, 42751, 42815, 43935, 43967, 43935, 42783,
41630, 42751, 25212, 25177, 25210, 29695, 9916, 6553, 0, 0, 0, 0, 0, 0, 0, 10940, 27423, 29695, 28575, 43839, 43871, 44991, 43839, 42751, 44959, 43903, 61343, 60287, 60287, 43935, 61407, 60287,
43871, 43903, 42751, 42751, 42815, 45023, 43903, 42815, 43903, 43839, 26399, 25246, 25114, 9950, 7637, 5461, 0, 0, 0, 0, 0, 0, 0, 8720, 9817, 11006, 9949, 27487, 28671, 44991, 42751, 43935,
45055, 44991, 45023, 61375, 43903, 43903, 60287, 43839, 43903, 43935, 42783, 42751, 42815, 45023, 43935, 43871, 43871, 43871, 27519, 25179, 7673, 8727, 5461, 0, 0, 0, 0, 0, 0, 0, 0, 0,
9849, 10581, 5120, 26267, 27519, 27551, 43935, 43903, 43935, 43935, 45023, 45023, 45023, 43967, 45023, 45055, 44991, 43903, 43903, 42783, 43903, 43935, 45023, 44991, 27551, 43839, 28607, 25211, 6580, 31, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8758, 27423, 27487, 27551, 27487, 43903, 43839, 43903, 43871, 44991, 44991, 45023, 44991, 45055, 43903, 42719, 43839, 42815, 45023, 27519, 43935, 26367,
25245, 26302, 27519, 7801, 4368, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 31, 6582, 26237, 26269, 26367, 25243, 27455, 25212, 42719, 42687, 42751, 42751, 43871, 42783, 43871,
42719, 41597, 42751, 42751, 44991, 27551, 26335, 25278, 8827, 27519, 8859, 6545, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4352, 8728, 9819, 8795, 8627, 26235,
25147, 26302, 25180, 26431, 42815, 43871, 42719, 42783, 41695, 40540, 42783, 25278, 42751, 26367, 25145, 8728, 8659, 9885, 7734, 8720, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 8704, 8735, 5461, 7633, 8692, 25080, 25180, 25179, 27519, 42687, 25246, 25179, 25246, 25311, 24056, 25278, 25278, 26270, 25247, 24055, 8528, 8723, 8795, 9654, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 31, 8720, 8759, 26367, 26303, 27487, 42815, 25180, 25214, 24091, 25311, 24124, 25278, 25212, 25145, 26302, 7703, 8464,
8704, 8727, 8720, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5461, 8694, 25244, 8761, 26268, 27487, 25179, 25180, 24055,
25343, 24123, 26431, 8859, 7602, 8794, 7636, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
8592, 8727, 6547, 6474, 25211, 7636, 7637, 7669, 26431, 7703, 8959, 8827, 8704, 9625, 31, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8725, 5461, 6547, 6446, 7737, 6544, 8827, 1023, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5461, 31, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10933, 0,
0, 0, 0, 15360, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 8720, 8720, 9746, 10905, 10768, 8720, 0, 0, 10972, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 10933, 0, 16383, 10807, 10873, 10872, 29503, 11994, 10804, 11799, 12031, 13247, 11103, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10581, 11996, 10908, 11996, 9654, 11962, 12095, 10872, 28349, 27255, 9747, 10907, 10941, 13183, 12031, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8727, 11867, 11007, 29663, 29599, 29695, 12095, 28447, 29503, 28347, 44766, 28347,
28380, 28511, 29567, 11997, 10838, 8720, 8720, 0, 0, 8720, 10933, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8735, 10906, 10906, 10941, 29567,
30719, 30719, 30719, 29631, 29567, 29535, 45919, 28479, 29663, 29599, 29567, 11929, 10839, 9748, 10905, 6441, 8720, 10805, 10906, 10581, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 10872, 28282, 28383, 28447, 29663, 30719, 29695, 29695, 29599, 28447, 45951, 28479, 28447, 44895, 28447, 28350, 27326, 28414, 28511, 27289, 27355, 28346, 13183, 11996, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9748, 28347, 29567, 28511, 45983, 45951, 45951, 45983, 44895, 44895, 46015, 44831, 44831, 45951, 28511, 28511, 28511, 29599, 28447, 28447,
29663, 28479, 28479, 27291, 10806, 16383, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15360, 0, 0, 16383, 9782, 28382, 28381, 45919, 44895, 44895, 44831, 45951, 44863, 44895, 44927, 44831,
44863, 44895, 44799, 44927, 46047, 46047, 44863, 29567, 29599, 28447, 28511, 28348, 9815, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15360, 8720, 9979, 5440, 8720, 8720, 26200, 28511, 28414, 44863,
44799, 44831, 44863, 45951, 45951, 44863, 44895, 44831, 44831, 43775, 43743, 44863, 45983, 44831, 43709, 44831, 28414, 29599, 28479, 27256, 10908, 11807, 0, 0, 0, 0, 0, 0, 0, 16383, 10836, 10907,
12127, 9882, 8790, 10840, 27356, 29567, 44798, 44765, 44799, 44799, 45983, 45951, 44863, 44863, 44895, 44831, 44863, 44799, 44799, 44863, 44895, 44766, 44799, 28415, 28447, 46047, 29599, 28380, 27326, 10938, 16383, 0,
0, 0, 0, 0, 0, 8720, 10872, 27357, 28479, 28479, 28447, 28511, 29567, 45951, 45951, 44895, 44895, 44895, 44927, 45983, 44927, 44895, 44895, 44863, 44863, 44863, 44895, 44895, 44895, 44895, 44927, 44895,
44927, 46079, 28447, 27292, 27292, 9815, 10905, 9612, 0, 0, 0, 0, 0, 0, 9747, 10937, 28511, 44927, 45983, 46079, 46079, 45951, 45951, 46047, 46079, 46047, 44927, 61311, 61311, 61311, 61279, 61311,
61311, 44895, 44895, 44927, 45983, 44927, 44927, 44927, 45983, 46015, 29599, 27390, 27357, 27256, 10942, 11996, 16383, 0, 0, 0, 0, 0, 11792, 10872, 28446, 28447, 44799, 46015, 46047, 45983, 44895, 44895,
44895, 44831, 43775, 43775, 43775, 60159, 60159, 61247, 61279, 43807, 44863, 44927, 44831, 43775, 43743, 43742, 44831, 44927, 44927, 27325, 27324, 27258, 10942, 8760, 15360, 0, 0, 0, 0, 0, 8730, 26234,
28447, 44863, 44927, 45983, 45983, 46015, 46015, 46047, 44959, 44895, 61279, 44959, 44927, 61311, 61343, 61375, 61407, 44959, 46047, 62399, 44927, 44895, 44895, 44927, 44895, 44831, 43743, 27258, 27256, 10871, 10840, 9784,
0, 0, 0, 0, 0, 8720, 10838, 27357, 28479, 44831, 43743, 44831, 44863, 44895, 46015, 44959, 44959, 44863, 43807, 43839, 43807, 43839, 60223, 61311, 61343, 44927, 44959, 44927, 43839, 43743, 43775, 44863,
44895, 27357, 27256, 27224, 27326, 27358, 27291, 27326, 9753, 0, 0, 0, 16383, 10935, 28381, 29567, 27357, 43742, 43709, 43675, 43709, 43709, 43743, 43775, 44895, 43839, 60191, 43807, 43839, 61311, 60255, 60255,
60255, 61311, 44895, 43871, 43839, 43775, 43775, 46015, 28543, 27359, 27359, 27390, 27423, 27325, 27358, 27423, 9917, 15391, 0, 0, 0, 9847, 27358, 29631, 28447, 27359, 43743, 27357, 43742, 43743, 43775, 43775,
43839, 60223, 61311, 61343, 61279, 61311, 61375, 62431, 61343, 62463, 61311, 60255, 43871, 44895, 44927, 46079, 46079, 44927, 44895, 43807, 43775, 43775, 27325, 27291, 9847, 0, 0, 0, 0, 10933, 10874, 28543,
28479, 28479, 28479, 44927, 44863, 43775, 43839, 43839, 44927, 60255, 61311, 62463, 62463, 61407, 62463, 62463, 61343, 62431, 61375, 61375, 61375, 61407, 46079, 44991, 43839, 43775, 43775, 43807, 44863, 43711, 26203, 9818,
16383, 0, 0, 0, 8720, 9744, 10838, 27323, 27290, 28479, 27324, 27325, 43676, 42619, 42619, 42618, 43710, 42653, 42621, 42686, 42685, 43742, 42686, 42686, 42686, 43775, 43742, 42717, 43742, 43742, 43774, 43774,
26266, 26233, 26200, 26234, 26268, 26200, 9783, 6540, 0, 0, 0, 0, 8720, 9848, 28543, 29599, 27324, 44863, 44831, 44927, 44895, 43775, 43743, 43742, 43709, 43743, 43775, 43871, 60223, 60223, 60191, 60191,
43807, 43775, 42718, 42685, 42718, 42686, 43807, 44927, 44927, 44863, 42654, 26268, 27391, 26201, 26301, 7603, 8720, 0, 0, 0, 8720, 10972, 29631, 46015, 44895, 44927, 44927, 44927, 44895, 44927, 44959, 44959,
44927, 43871, 60255, 61343, 61375, 61375, 61375, 61375, 61375, 60287, 60255, 60223, 60223, 43839, 44959, 45023, 44927, 43839, 43743, 26235, 26269, 26235, 27423, 9949, 8720, 0, 0, 16383, 9747, 9879, 28511, 28511,
43775, 43742, 43708, 43642, 42651, 42619, 42651, 42685, 42686, 42687, 43775, 43807, 43807, 60191, 59135, 42751, 42751, 42751, 43807, 43839, 43839, 43807, 43807, 43775, 42653, 43743, 42618, 27325, 43775, 27391, 26265, 9749,
9782, 8720, 0, 0, 8720, 8688, 26233, 27324, 28511, 27324, 26200, 26199, 43740, 42653, 42587, 42685, 42686, 42686, 42719, 42719, 42687, 59071, 59071, 59071, 42654, 42686, 42686, 42653, 41563, 42587, 42685, 42718,
42586, 26201, 26167, 26202, 26268, 27325, 26236, 26236, 26202, 9749, 15360, 0, 8720, 9782, 27257, 26199, 27292, 27358, 43742, 43775, 44863, 44895, 43807, 43839, 43839, 43839, 43839, 60223, 60223, 59103, 59103, 59135,
59103, 59103, 42719, 42719, 42686, 42719, 43775, 43871, 44927, 27391, 26301, 26235, 26268, 27325, 27326, 26202, 8725, 8720, 0, 0, 8735, 9851, 27326, 26233, 27292, 43807, 43775, 43807, 43839, 43871, 44927, 44959,
43807, 43807, 43839, 59135, 60191, 59135, 59135, 59135, 59167, 60223, 60223, 43871, 43807, 43807, 43807, 43807, 43839, 26334, 27390, 27455, 27455, 28543, 28575, 27519, 9915, 8720, 0, 0, 8720, 9817, 26235, 27359,
27391, 43807, 43774, 43743, 43807, 43743, 43807, 42719, 42653, 42686, 42719, 42686, 42685, 42686, 42686, 42719, 42719, 42719, 42687, 42751, 43807, 42718, 42718, 43775, 43871, 43903, 43839, 27423, 26300, 26233, 27455, 27359,
9880, 8720, 0, 0, 8735, 9819, 9850, 27292, 27455, 27423, 26268, 44895, 44895, 43775, 43743, 42653, 42653, 42687, 42687, 59038, 42654, 59038, 59039, 42687, 42719, 42719, 42719, 42719, 43807, 42686, 42652, 42653,
42751, 43871, 43903, 46079, 29663, 27423, 8761, 8826, 10933, 0, 0, 0, 0, 8725, 9814, 26199, 26235, 27326, 27423, 44991, 43743, 42653, 42653, 42621, 42719, 43775, 42719, 42718, 42687, 42687, 59135, 42719,
42719, 42687, 42687, 42687, 42751, 42751, 41595, 41496, 41529, 26301, 27391, 27455, 27391, 29695, 9948, 5450, 0, 0, 0, 0, 0, 0, 9619, 9782, 26235, 27455, 28607, 44991, 43839, 43839, 43775, 43775,
43839, 43871, 43871, 43839, 43839, 43839, 43903, 43839, 42783, 42751, 41597, 41631, 42751, 43871, 43839, 42686, 41563, 42621, 25177, 25143, 25209, 28671, 9884, 8727, 0, 0, 0, 0, 0, 0, 0, 10808,
26302, 28511, 27455, 27359, 43775, 43839, 42687, 42687, 43839, 43807, 43839, 43807, 43807, 43839, 43903, 43839, 42783, 42783, 41598, 41565, 42687, 43903, 42783, 42719, 43807, 26334, 26270, 25112, 7639, 9917, 7669, 5461,
0, 0, 0, 0, 0, 0, 0, 10570, 9782, 9915, 9916, 27423, 28607, 43871, 26301, 43871, 44991, 43871, 43903, 43871, 43839, 43839, 43839, 42783, 43839, 43839, 42654, 41597, 42687, 43903, 43839, 42719,
26367, 27423, 27487, 25145, 7638, 6582, 5450, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8727, 8720, 6144, 9882, 27455, 27423, 26367, 42751, 43807, 43807, 43871, 43903, 43935, 43903, 43903, 43935,
43903, 42783, 43807, 42654, 42719, 43839, 43903, 43903, 27455, 26335, 27487, 25177, 7636, 31, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8723, 9820, 26335, 27391, 26367, 43807,
42719, 43839, 43807, 43903, 43903, 43935, 43903, 44991, 43839, 41596, 42719, 42719, 43839, 26399, 27455, 25278, 25211, 26235, 26399, 7736, 5450, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 31, 7637, 26171, 26202, 25212, 25177, 26335, 25178, 42685, 41564, 42654, 42718, 43839, 42686, 42783, 41629, 41563, 42686, 41629, 42783, 27487, 25244, 25113, 8758, 9884, 8792, 5552, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5440, 8726, 9816, 8760, 7566, 9817, 8729, 25212, 25146, 26335, 26303, 42783, 41629, 42687, 41564, 24090, 41662, 25179, 26269, 26302, 8759, 7636,
8657, 9816, 6578, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8727, 8720, 10570, 8657, 8725, 25146, 25145, 27455, 25179, 25178, 25112, 25179,
24123, 24022, 25146, 25179, 25145, 25178, 7637, 8720, 9650, 8725, 10933, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10581,
8759, 26302, 25180, 26335, 42687, 25146, 25115, 24089, 25181, 24090, 24123, 24090, 25110, 25178, 7637, 5461, 8720, 9619, 15391, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 15391, 8691, 25146, 8726, 8827, 26335, 25146, 25081, 24021, 24157, 24089, 26399, 8826, 8657, 8759, 7633, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8720, 8726, 8720, 8584, 8760, 6579, 6547, 7635, 25278, 6581, 8829, 6747, 0, 10581, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8720, 8720, 8464, 6444,
8726, 5456, 6582, 31, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 8720, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8720, 0, 0, 0, 0, 15360, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16383, 15391, 9746, 10872, 9619, 8720, 0, 0, 9852, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10933, 0, 16383, 10837, 11894, 10870, 28446, 11960, 10801, 10933, 11999,
12095, 10943, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10581, 9851, 10873, 9979, 8725, 10904,
10941, 10838, 28314, 10870, 9779, 10873, 11930, 11999, 11999, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8720,
9849, 10942, 13183, 28511, 13279, 12063, 11998, 28382, 28314, 28348, 28313, 27323, 28415, 12031, 10907, 9782, 8720, 15391, 0, 0, 0, 8720, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 16383, 10839, 10903, 11931, 28479, 30719, 30719, 29695, 29567, 28447, 28447, 28479, 28415, 28543, 28479, 28447, 10905, 10837, 9779, 9847, 8522, 10933, 10805, 10872, 8720, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10805, 11895, 28348, 28381, 29599, 29599, 29631, 29631, 28479, 28413, 29503, 28447, 27325, 28415, 28382, 27324, 27291, 28348, 28414,
10871, 11962, 28312, 12031, 12027, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9747, 28314, 28479, 28415, 28415, 28415, 44831, 28447, 27359, 44799, 44863, 28382,
43709, 44831, 28447, 28415, 28415, 28479, 28381, 28382, 29567, 28414, 28383, 10872, 9814, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15360, 0, 0, 16383, 9779, 11930, 28346, 28382, 44766,
44767, 44766, 44831, 44767, 44767, 44799, 43710, 44767, 43743, 27325, 28415, 45951, 45951, 28415, 28511, 28511, 28381, 28415, 11930, 10838, 0, 0, 0, 0, 0, 0, 0, 0, 15360, 10581, 9819, 8704,
0, 5450, 9814, 28383, 27324, 28415, 43709, 43709, 44767, 44799, 44799, 44766, 44766, 43741, 44766, 43677, 43676, 44767, 44831, 43741, 43675, 27325, 28380, 28479, 27358, 10871, 10874, 11799, 0, 0, 0, 0,
0, 0, 16383, 10804, 10872, 10975, 9848, 8788, 9815, 27322, 28447, 28347, 28347, 44732, 44732, 44831, 44799, 44766, 44799, 44799, 44766, 44799, 43708, 43708, 44766, 44799, 44731, 27324, 27291, 27357, 28543, 28511,
27323, 10875, 9849, 16383, 0, 0, 0, 0, 0, 16383, 10838, 27257, 27326, 28415, 28415, 28447, 28479, 44831, 44831, 44799, 44831, 44831, 44799, 44863, 44863, 44831, 44799, 44799, 44799, 44831, 44831, 44831,
44831, 44831, 44863, 28447, 28447, 29599, 27357, 27224, 27257, 10805, 10805, 8720, 0, 0, 0, 0, 0, 9843, 10902, 28382, 28447, 28479, 46015, 45951, 44799, 44799, 44863, 44895, 44895, 44831, 44831, 44831,
44863, 44831, 44863, 44863, 44863, 44863, 44863, 44863, 44863, 44831, 44831, 44863, 44895, 28511, 27291, 27258, 10870, 10907, 10936, 16383, 0, 0, 0, 0, 16352, 10838, 28347, 28380, 28381, 44895, 44895, 44831,
43742, 43743, 43710, 43709, 43677, 43709, 43677, 43709, 43677, 43775, 43775, 43709, 43775, 44863, 43742, 43708, 43675, 43675, 43708, 44863, 44863, 27291, 27258, 27223, 10874, 9814, 15360, 0, 0, 0, 0, 8727,
26233, 28413, 28414, 44863, 44895, 44895, 44895, 44863, 44895, 44863, 43775, 43775, 43807, 43775, 43807, 43807, 44895, 44895, 44863, 44895, 44895, 44831, 43775, 43775, 44831, 43775, 43709, 27291, 27256, 27222, 10837, 10836,
10808, 0, 0, 0, 0, 0, 9750, 27290, 28413, 43709, 43708, 44766, 43775, 44799, 44831, 43807, 44863, 43775, 43742, 43743, 43742, 43710, 43710, 43775, 43807, 43807, 43807, 43775, 43775, 43708, 43709, 43742,
43743, 27258, 26199, 27222, 27258, 27258, 27256, 27293, 9751, 0, 0, 0, 10933, 10938, 28447, 27290, 27291, 27257, 27257, 43642, 43674, 43675, 43709, 43775, 43743, 43775, 43775, 43775, 43807, 43743, 43710, 43775,
43775, 43775, 43775, 43775, 43741, 43743, 28543, 28511, 27292, 27291, 27324, 27325, 27259, 27258, 27358, 9949, 15360, 0, 0, 10943, 10973, 28511, 27358, 27291, 27258, 27290, 27291, 43676, 43710, 43710, 43743, 43743,
44863, 44863, 43807, 43839, 44895, 44863, 43839, 44927, 43807, 43775, 43807, 43807, 43839, 44927, 28575, 27391, 43775, 43709, 43709, 27325, 27291, 27257, 10773, 0, 0, 0, 8720, 10871, 28447, 27358, 27358, 27327,
28447, 43775, 43709, 43710, 43743, 43807, 43743, 43807, 61311, 44927, 61311, 61343, 61279, 43839, 44895, 44895, 61279, 44895, 44895, 44927, 43839, 43775, 42653, 43677, 43710, 43710, 27259, 26200, 9814, 16383, 0, 0,
0, 9836, 9782, 10938, 27256, 28381, 27257, 27290, 27257, 27256, 27224, 26200, 43675, 42619, 42618, 42651, 42651, 42651, 42651, 42619, 42651, 43709, 43708, 42651, 43708, 43708, 43741, 27357, 26233, 26232, 26166, 26200,
26234, 26166, 8725, 6573, 0, 0, 0, 10933, 10807, 27391, 28543, 27290, 28414, 43742, 44831, 43775, 43709, 43676, 43675, 42619, 43709, 42653, 43743, 43743, 43743, 42686, 42686, 42719, 42686, 42620, 42619, 42620,
42620, 43743, 43839, 43775, 27391, 26235, 26202, 26268, 26199, 26202, 7602, 8720, 0, 0, 10933, 11995, 28511, 28511, 44799, 44831, 44831, 44831, 43807, 43807, 43807, 43807, 43775, 43775, 43775, 43775, 43775, 60159,
43775, 43807, 43775, 43775, 43743, 43743, 43743, 43775, 43839, 44927, 43807, 43775, 42619, 26201, 26234, 26200, 27357, 8857, 10581, 0, 0, 10933, 10840, 28415, 27358, 27324, 27292, 27290, 27257, 27258, 27257, 42617,
42618, 42619, 42619, 42685, 42685, 42686, 42686, 42653, 42653, 42653, 42652, 42685, 43775, 42718, 43742, 42685, 43741, 42618, 42619, 26199, 27258, 27324, 27357, 9848, 9782, 9749, 9619, 0, 15360, 8720, 9815, 27289,
28447, 27290, 27222, 27255, 27291, 42617, 42584, 42586, 42618, 42619, 42652, 42652, 42652, 42619, 42619, 42619, 42586, 42619, 42619, 42586, 42584, 42584, 42618, 26299, 26200, 26166, 26165, 26200, 26201, 26266, 26201, 26201,
9784, 9747, 15360, 8720, 9748, 9814, 10804, 27290, 27259, 27258, 43676, 43743, 43743, 43709, 43710, 43710, 43743, 43775, 43807, 43807, 42718, 42685, 42718, 42685, 42685, 42685, 42686, 42684, 42685, 42718, 43807, 27455,
26269, 26235, 26234, 26233, 26233, 26234, 26168, 9749, 10581, 0, 8735, 9817, 9819, 27224, 27257, 27325, 43708, 43710, 43743, 43775, 43775, 44895, 43743, 43743, 43775, 42718, 42718, 42686, 42686, 42686, 42686, 43743,
43775, 43775, 42685, 43742, 42653, 43742, 43775, 26268, 26268, 27391, 27326, 27391, 27455, 27359, 9880, 8720, 0, 8720, 9783, 10873, 27325, 27324, 27390, 27356, 43676, 43709, 42620, 43677, 42652, 42619, 42652, 42717,
42619, 42652, 42652, 42652, 42653, 42653, 42685, 42619, 42653, 42686, 42651, 42619, 42653, 42719, 43775, 42686, 26301, 26266, 9816, 27359, 26236, 9783, 15391, 0, 8735, 9785, 9814, 27290, 27325, 27357, 26266, 28479,
27391, 43709, 43677, 42586, 42587, 42685, 42652, 42618, 42619, 42651, 42619, 42652, 42653, 42653, 42653, 42685, 43743, 42684, 42618, 42619, 42653, 43775, 43775, 44959, 28607, 27390, 8726, 8758, 10581, 0, 0, 0,
9843, 10836, 9813, 27255, 27291, 27292, 27455, 26268, 26234, 42619, 42586, 42685, 43742, 43741, 43709, 42684, 42685, 42653, 42653, 42653, 42652, 42652, 42652, 42653, 42685, 42585, 26134, 25110, 26235, 27357, 27391, 27325,
28575, 9914, 8720, 0, 0, 0, 0, 0, 10581, 10836, 9816, 27292, 27391, 27423, 27327, 43743, 43710, 42686, 43743, 43743, 43775, 43775, 43775, 42751, 43807, 43775, 42719, 42685, 42587, 41563, 42620, 42719,
42687, 42586, 26168, 25146, 26167, 25142, 9848, 28607, 9914, 8727, 0, 0, 0, 0, 0, 0, 9814, 27259, 27327, 27359, 26268, 26301, 43743, 42620, 42620, 43743, 43743, 43743, 42687, 42719, 43775, 43807,
43775, 42719, 42686, 41530, 41530, 42619, 43775, 42718, 42620, 26334, 26203, 26202, 25109, 7637, 9883, 8723, 8720, 0, 0, 0, 0, 0, 0, 8720, 9781, 9849, 9883, 27391, 28511, 27359, 26202, 27359,
43871, 43807, 43775, 43775, 43775, 43775, 43775, 43775, 43775, 43775, 42587, 41530, 42620, 43807, 42719, 26236, 26268, 26301, 27455, 25174, 7637, 6547, 5450, 0, 0, 0, 0, 0, 0, 0, 0, 10933,
8720, 4096, 9849, 27423, 26302, 26237, 42653, 42686, 42686, 42719, 43807, 43839, 43807, 43807, 43839, 43807, 42687, 42686, 42620, 41597, 42719, 43807, 27423, 26303, 26204, 26302, 8759, 7633, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 8725, 9816, 26236, 26301, 26302, 42687, 42653, 43775, 42719, 43807, 43839, 43807, 43839, 43839, 42686, 41561, 42620, 26204, 26303, 26269, 26303, 25179, 26201, 26168,
25147, 6579, 5450, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15391, 9749, 9817, 26167, 25144, 25144, 26269, 25144, 26235, 42554, 42619, 26268, 42719, 42652, 42686, 42586, 25145, 41563,
25146, 42622, 26303, 25178, 8693, 8757, 9785, 8662, 6448, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5450, 8758, 9813, 8758, 8592, 8759, 8726, 25144, 25112, 26236,
26236, 42687, 25179, 41596, 25113, 25112, 25179, 25112, 25145, 25179, 8725, 8723, 9843, 10806, 9619, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8720,
15391, 15360, 9619, 9748, 25144, 26167, 26302, 25145, 25144, 25078, 25112, 24057, 24021, 25079, 25080, 25110, 25111, 7635, 5461, 8720, 9747, 16383, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 15391, 9749, 26235, 26170, 26204, 25180, 25112, 25112, 25079, 24057, 24056, 24089, 24056, 25077, 25110, 7635, 5450, 0, 10581, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15391, 8657, 8728, 8726, 8728, 25180, 25111, 25110, 24019, 24089, 24055, 26334, 8761, 8626, 8725, 6578,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8720, 8723, 8720, 8712, 8726, 7633, 7601, 7570,
8729, 6547, 7737, 8725, 0, 8720, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 10581, 0, 5450, 6445, 8628, 6540, 8533, 31, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8720, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8720, 0, 0, 0, 0, 15360, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16383, 15391, 8720, 10806, 8720, 0, 0, 0, 9851, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8720, 0, 16383, 9843, 11862, 10869, 11964,
11895, 9810, 10933, 10938, 10943, 10943, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8720, 9819, 10872,
11995, 9619, 10871, 11929, 10868, 27256, 10804, 9746, 10871, 10871, 10942, 10938, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 10933, 11930, 12031, 28447, 13215, 12031, 11965, 28348, 11929, 28314, 28280, 28314, 27293, 11965, 10906, 10805, 15360, 15360, 0, 0, 0, 16383, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 10933, 10837, 10872, 28382, 29663, 29663, 29631, 28511, 28382, 28382, 28447, 28381, 28479, 28350, 28350, 11896, 9779, 9747, 9782, 6540, 8720, 9843, 11894, 15360, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11799, 11894, 28346, 28347, 29567, 29535, 29567, 28543, 28415, 28348, 28447, 28414, 27290, 27292, 27292, 27291, 27289, 28347, 28315,
10838, 10905, 10870, 11965, 12921, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9843, 11960, 28414, 28348, 28348, 28348, 44764, 27325, 27292, 28347, 28381, 28347, 27290,
27292, 27291, 27291, 28348, 28447, 28315, 28348, 28479, 28347, 28348, 11927, 10933, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9810, 11928, 28312, 28346, 28314, 27291, 44731,
44733, 43676, 43676, 27291, 27291, 43675, 43675, 27291, 28349, 28447, 28479, 28382, 28447, 28415, 28347, 28348, 11928, 9846, 0, 0, 0, 0, 0, 0, 0, 0, 8720, 10773, 0, 0, 8720, 9782,
27291, 27290, 28380, 28314, 27290, 44699, 43675, 44700, 44699, 43675, 43674, 43675, 43674, 27290, 43708, 44733, 28347, 27257, 27290, 27290, 28415, 27324, 10838, 10873, 10933, 0, 0, 0, 0, 0, 0, 9810,
10869, 10908, 9783, 9748, 9781, 10905, 28349, 28313, 28313, 28313, 44698, 44700, 43676, 44699, 44732, 44732, 44699, 44765, 27290, 27257, 43674, 43707, 28313, 27257, 27256, 27290, 28415, 28382, 10872, 10873, 8727, 0,
0, 0, 0, 0, 16383, 10837, 10870, 27291, 28348, 28348, 28381, 28382, 28381, 44732, 44732, 44732, 44765, 44733, 44766, 44766, 43709, 43709, 44764, 44766, 28381, 27356, 43708, 44765, 44765, 28414, 27324, 27324,
27358, 27291, 27222, 10839, 10773, 9843, 8720, 0, 0, 0, 0, 8720, 11926, 11964, 28382, 28382, 44895, 44799, 44732, 44699, 44733, 44767, 44799, 44766, 43741, 44766, 44799, 44798, 44831, 44831, 44831, 44831,
44766, 44766, 44766, 27325, 27293, 28381, 28447, 28447, 27288, 10872, 10836, 11896, 10933, 16383, 0, 0, 0, 0, 10900, 11929, 28315, 27290, 44798, 44831, 44764, 43674, 43674, 43674, 43673, 43673, 43673, 43673,
43675, 43674, 43708, 43708, 43675, 43708, 43708, 43674, 27257, 27256, 27256, 27290, 28414, 27357, 27256, 27255, 10837, 10838, 9843, 0, 0, 0, 0, 10933, 10872, 28346, 28347, 28446, 44831, 44799, 44799, 44831,
44831, 44831, 44798, 44766, 43775, 43742, 43742, 43775, 44831, 44799, 44831, 44831, 44799, 43742, 43741, 43741, 43709, 43708, 27291, 27257, 27222, 10869, 10805, 11891, 9814, 0, 0, 0, 0, 9747, 10871, 27290,
27289, 28314, 27291, 43676, 43676, 43710, 43710, 44798, 43708, 43675, 43676, 43676, 43643, 43675, 43709, 43677, 43709, 43709, 43676, 43675, 43641, 43642, 27291, 27324, 27256, 10837, 10836, 27256, 10873, 10871, 27259, 10778,
0, 0, 10933, 11928, 27291, 27255, 27256, 27255, 27256, 27256, 27256, 27257, 43642, 43708, 43708, 43741, 43741, 43741, 43741, 43708, 43674, 43708, 43741, 43741, 43741, 43741, 43708, 43677, 28511, 28415, 27291, 27257,
27257, 27258, 27224, 27255, 27259, 9849, 0, 0, 10933, 10906, 27358, 27290, 27256, 27255, 27255, 27257, 27258, 27291, 27291, 43676, 43676, 43743, 43775, 43743, 43710, 43743, 43775, 43775, 44863, 43742, 43709, 43742,
43742, 43743, 44831, 28447, 27325, 27260, 27258, 27257, 27258, 27256, 10871, 8727, 0, 0, 0, 9848, 27293, 27258, 27291, 27292, 27325, 27324, 27259, 43643, 43675, 43709, 43677, 43710, 43775, 43807, 43775, 44831,
43743, 43743, 43775, 43743, 43743, 43743, 43711, 43775, 43775, 27324, 27258, 27258, 27258, 27258, 27256, 26198, 9750, 0, 0, 0, 0, 9810, 10937, 10805, 27291, 27255, 27256, 27255, 27223, 27222, 27223, 27257,
27256, 27256, 27258, 43641, 43642, 43641, 42585, 26234, 27291, 27291, 27258, 27291, 27258, 27291, 27291, 27256, 27223, 26166, 27222, 27223, 10837, 9748, 8720, 0, 0, 16383, 9747, 10973, 28511, 27288, 27324, 27323,
27324, 27291, 27258, 27258, 27258, 27258, 27259, 42619, 42620, 42620, 43644, 42651, 42620, 42620, 42619, 42586, 42585, 42586, 42586, 42652, 43711, 43710, 27325, 27257, 26200, 26202, 9781, 9815, 7633, 0, 0, 16383,
11003, 28479, 28479, 28381, 44766, 44798, 43741, 43709, 43741, 43709, 43742, 43709, 43709, 43677, 43677, 42653, 42653, 42653, 42653, 42686, 42653, 42620, 43676, 42653, 43709, 43710, 43743, 43709, 43708, 27257, 27223, 26200,
26199, 26202, 8760, 8720, 0, 16383, 10804, 27292, 27324, 27290, 27290, 27257, 27288, 27257, 27256, 27256, 27256, 27225, 26233, 26202, 26201, 42586, 42619, 42618, 42586, 42586, 42586, 42587, 42621, 42619, 26235, 26202,
26234, 26200, 26200, 27222, 27224, 27257, 27258, 9782, 10804, 9779, 8720, 0, 8720, 10805, 27256, 27324, 27256, 10837, 27254, 27257, 27223, 27222, 27255, 27224, 27257, 27258, 26234, 42585, 42585, 42585, 42584, 26200,
26200, 42584, 42584, 26199, 26199, 26200, 26233, 27223, 27188, 27221, 27223, 27224, 27224, 26199, 10840, 10838, 10773, 16383, 9781, 10838, 10836, 27256, 27257, 27256, 27258, 27259, 43643, 43642, 43675, 43643, 43708, 43742,
43742, 43775, 43709, 43708, 43708, 43675, 43675, 43675, 43708, 43707, 43708, 43709, 27391, 27423, 26267, 26200, 27256, 27223, 27224, 27257, 27222, 10772, 8720, 8735, 9816, 9816, 10838, 27255, 27258, 27257, 27258, 27259,
43676, 43677, 43743, 43676, 43676, 43742, 42652, 42652, 42652, 43676, 42620, 42619, 42652, 43709, 43709, 42619, 43708, 42618, 27291, 26269, 26234, 26202, 27292, 26235, 27325, 27423, 27259, 9847, 16383, 16383, 9749, 9815,
27291, 27290, 27258, 27258, 27258, 26234, 27225, 42617, 43642, 26201, 26267, 43708, 42617, 42585, 42618, 42619, 42587, 42586, 42619, 42585, 42586, 42619, 26233, 26200, 42586, 26202, 26268, 26235, 26235, 10904, 9749, 27292,
26200, 9749, 15391, 16383, 9783, 9812, 10838, 27257, 27258, 27256, 28447, 27325, 27259, 27258, 26200, 26233, 42651, 43707, 42584, 42585, 42618, 42617, 42618, 42652, 42619, 42619, 42652, 43709, 42618, 26201, 26201, 26202,
42685, 43742, 28511, 28543, 10973, 9748, 8757, 8720, 0, 0, 8727, 10837, 10836, 10837, 10873, 27258, 27326, 27257, 27257, 26201, 27256, 43708, 43742, 43741, 43741, 43741, 43708, 43708, 42651, 42684, 42683, 26267,
26268, 42651, 42619, 26199, 26165, 26165, 26201, 27324, 26268, 27291, 28479, 9881, 8720, 0, 0, 0, 0, 8720, 9810, 10837, 27289, 27325, 27293, 27259, 27293, 43676, 42619, 42652, 42654, 43677, 43710, 43710,
42653, 43742, 42653, 42620, 42651, 26234, 26201, 42618, 42652, 43709, 26200, 26166, 26168, 26166, 9748, 9847, 28543, 9882, 10933, 0, 0, 0, 0, 0, 11799, 10840, 27291, 27260, 26201, 27258, 43676, 42586,
42586, 43709, 43709, 43709, 42652, 43709, 43709, 43742, 43709, 43677, 42651, 42584, 26167, 42585, 43709, 42652, 26201, 26202, 26168, 26200, 26132, 8723, 9915, 8659, 8720, 0, 0, 0, 0, 0, 8720, 9812,
9781, 9849, 27357, 27391, 27291, 26200, 26268, 43743, 43743, 43742, 43742, 43774, 43741, 43741, 43742, 43742, 43709, 42585, 26168, 26201, 43709, 42620, 26201, 26201, 26202, 27423, 25142, 8659, 8720, 8720, 0, 0,
0, 0, 0, 0, 0, 8720, 16383, 5440, 9848, 27325, 26202, 26203, 26235, 26268, 27292, 42652, 43742, 43775, 43743, 43742, 43775, 42686, 42619, 42587, 26202, 26203, 26269, 27359, 26270, 26268, 26201, 26267,
8757, 6578, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8720, 9813, 26201, 26202, 26268, 26268, 26235, 27357, 27325, 43775, 27423, 43775, 43807, 43807, 42619, 26168, 26202, 26202, 26269,
26202, 26203, 26168, 9783, 9815, 26168, 8659, 8720, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15391, 9747, 9814, 9782, 9749, 8758, 26170, 26134, 26200, 26168, 26201, 26202, 42620, 26202,
42651, 26201, 26168, 26201, 26168, 26203, 26236, 26168, 8692, 9747, 9782, 8692, 6544, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8720, 9747, 10804, 9747, 9612, 9750, 8724,
26166, 26166, 26169, 26202, 26204, 25145, 25145, 25111, 25111, 26168, 25109, 26167, 26169, 8726, 8720, 8720, 9843, 10581, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 16383, 0, 0, 8720, 10801, 9749, 9782, 26202, 26167, 26167, 25109, 25077, 25078, 25044, 25077, 25077, 26132, 26133, 8658, 8720, 0, 16383, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15391, 9782, 26168, 26167, 26169, 26168, 25142, 26135, 25077, 25078, 25079, 25110, 25110, 9748, 26132, 8624, 8720, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8720, 9782, 9748, 8758, 26169, 8725, 9749, 8659, 8694, 7637, 25146, 8727, 9650, 8753, 5461,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15360, 8720, 15391, 10570, 8724, 7569, 7568, 6542, 8660,
6544, 8693, 8727, 0, 15391, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 8720, 0, 8720, 8456, 6578, 5450, 8720, 31, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16383, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16383, 15391, 8720, 10836, 8720, 0, 0, 0, 9849, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16383, 0, 16383, 9843, 9843, 9846, 11929, 10933, 10933, 8720, 9849,
10910, 9849, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9843, 10838, 9849, 8720, 9847, 11895,
10803, 27254, 10835, 9746, 10806, 9846, 10907, 9849, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8720, 10806,
10907, 28382, 12095, 11998, 11932, 11962, 11928, 28313, 28279, 11928, 11931, 11964, 11895, 9843, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 10933, 9843, 10836, 11930, 29599, 29631, 29567, 12031, 28348, 28381, 28413, 28348, 28382, 28347, 11964, 11928, 11891, 9810, 9814, 10570, 8720, 10933, 10933, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 8720, 11860, 11928, 28312, 29503, 28479, 28447, 28415, 27292, 28314, 28380, 28347, 27288, 27289, 27257, 27256, 10904, 11929, 11928, 10836, 10872, 10869, 11963,
10933, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8720, 11894, 28346, 28312, 28346, 28313, 28314, 27289, 27257, 27289, 28313, 28313, 27256, 27288, 28280, 27257, 28313,
28380, 28312, 28346, 28383, 28313, 11930, 11894, 16383, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8720, 10903, 11927, 28311, 28312, 28313, 28312, 28314, 28314, 28313, 28313,
28313, 28313, 28313, 28312, 28315, 28380, 28382, 28348, 28381, 28349, 28313, 28313, 11927, 10773, 0, 0, 0, 0, 0, 0, 0, 0, 16383, 11799, 0, 0, 8720, 9780, 27290, 27256, 28313, 28312,
28311, 28312, 28312, 44697, 44697, 28312, 28311, 28313, 28311, 28311, 28313, 28314, 28312, 27255, 28311, 28312, 28315, 27290, 10869, 10869, 8720, 0, 0, 0, 0, 0, 0, 9843, 10837, 11895, 9782, 9746,
10804, 10871, 28314, 28311, 28311, 28311, 28311, 28313, 28312, 44696, 44697, 28313, 28313, 28380, 28311, 27254, 28279, 28312, 28279, 28278, 27254, 27255, 28316, 27291, 10870, 11894, 10933, 0, 0, 0, 0, 0,
16383, 10805, 11893, 11928, 28313, 28313, 28346, 28314, 28313, 28313, 28312, 28313, 44730, 44698, 44698, 44698, 44698, 28314, 28315, 28380, 28347, 27290, 27289, 28314, 28314, 28314, 27289, 27256, 27290, 27257, 10836, 10870,
11792, 10933, 16383, 0, 0, 0, 0, 16383, 11895, 11930, 28315, 28315, 28381, 28347, 28313, 28312, 28313, 28314, 44699, 43674, 43674, 43675, 44765, 44797, 44799, 44799, 28414, 28413, 28380, 28380, 27290, 27289,
27257, 27257, 28347, 28380, 27254, 10838, 11894, 11894, 11799, 0, 0, 0, 0, 0, 11862, 11927, 28312, 28280, 28346, 28347, 28313, 28312, 28312, 28312, 27288, 27255, 27256, 27255, 27289, 27288, 43674, 43674,
27289, 27290, 28314, 27288, 27255, 27255, 27254, 27255, 28348, 27291, 27255, 11894, 10836, 11891, 10933, 0, 0, 0, 0, 8720, 10870, 28312, 28313, 28348, 28380, 28380, 28380, 28381, 28381, 28380, 28380, 28380,
27324, 27324, 27324, 43708, 43709, 43709, 43709, 43709, 43708, 27323, 27323, 27323, 27291, 27290, 27256, 27254, 10869, 11892, 10804, 10773, 10773, 0, 0, 0, 0, 9843, 10869, 28311, 28311, 28312, 28314, 27290,
28314, 28314, 27291, 28380, 27290, 27289, 27290, 27289, 27256, 27256, 27257, 27256, 27256, 27257, 27256, 27257, 27255, 27256, 27290, 27290, 27255, 10836, 10869, 10870, 10871, 10869, 10873, 9849, 0, 0, 8720, 11926,
11928, 11895, 28311, 27255, 28279, 28279, 27255, 27256, 27256, 27290, 27290, 27323, 28380, 27324, 27324, 27290, 27289, 27290, 27291, 27323, 27324, 27324, 27290, 27291, 28447, 27325, 27289, 27255, 10839, 27255, 10870, 10869,
27224, 9847, 0, 0, 8735, 11929, 28315, 28312, 27254, 27254, 10870, 27255, 27288, 27290, 27290, 27290, 27290, 43675, 43676, 43675, 43675, 43675, 43675, 43675, 43709, 43675, 43675, 43675, 27291, 27324, 27358, 27325,
27258, 27257, 27255, 27255, 27254, 27255, 10870, 10933, 0, 0, 0, 9846, 10907, 10904, 27256, 27289, 28314, 27290, 27256, 27256, 27257, 43675, 43675, 43675, 43709, 43742, 43709, 43709, 43708, 43676, 43677, 43676,
43676, 43676, 43676, 43709, 27325, 27258, 27256, 27255, 27255, 27223, 27254, 10805, 9814, 0, 0, 0, 0, 8720, 10938, 10836, 11929, 11895, 11895, 10870, 10838, 10837, 27222, 27255, 27255, 27223, 27256, 27256,
27256, 27223, 27223, 27256, 27257, 27225, 27224, 27257, 27223, 27225, 27257, 10870, 10838, 10836, 10837, 10837, 10837, 10804, 8720, 0, 0, 0, 8720, 10907, 11997, 27222, 27289, 27289, 27288, 27256, 27256, 27256,
27257, 27256, 27257, 27256, 27257, 27257, 27257, 27257, 27257, 27258, 27224, 27224, 27223, 27224, 27224, 27258, 27292, 27259, 27259, 27256, 27255, 27223, 10836, 9781, 8720, 0, 0, 16383, 11929, 28414, 28413, 28346,
27291, 27323, 27290, 27289, 27290, 27258, 27258, 43642, 43642, 43641, 43641, 43641, 43641, 43641, 43642, 43642, 43609, 43641, 43641, 43641, 27257, 27259, 43643, 43642, 27258, 27256, 27222, 27222, 27221, 10839, 9814, 16383,
0, 0, 9810, 27257, 27289, 28280, 27256, 27256, 27255, 27255, 27255, 27255, 27223, 27223, 27223, 27223, 27223, 27223, 27225, 27224, 26199, 27223, 27223, 26199, 26201, 27224, 27224, 27223, 27223, 26198, 27222, 27222,
27255, 27256, 10840, 9781, 9747, 11858, 8720, 0, 8720, 10836, 10870, 27289, 11895, 10869, 10870, 27255, 27254, 27253, 27254, 27255, 27255, 27224, 27224, 27223, 27223, 27223, 27222, 27221, 27222, 27222, 27222, 27222,
27222, 27223, 27256, 27255, 10803, 10836, 27254, 27222, 27222, 10837, 10871, 10836, 8720, 15391, 9746, 10869, 11892, 27255, 27255, 27255, 27256, 27255, 27256, 27256, 27257, 27257, 27258, 27292, 27324, 43709, 27324, 27291,
43675, 27323, 27291, 27290, 27291, 27258, 27291, 27291, 27324, 28447, 27258, 10871, 10837, 27222, 27254, 27255, 27222, 10837, 16383, 16383, 9782, 9782, 11894, 11926, 27254, 27255, 27255, 27255, 27256, 27257, 27259, 27256,
27257, 27291, 27258, 27258, 27258, 27258, 27257, 27225, 27257, 27258, 27257, 27256, 27258, 27223, 27256, 27258, 27223, 27256, 10873, 10840, 27290, 28414, 27289, 9846, 16383, 16383, 10836, 10838, 11930, 28312, 27256, 27256,
27257, 27223, 27222, 27223, 27223, 27256, 27225, 27291, 27224, 27223, 27224, 27224, 27224, 26200, 26201, 26199, 27223, 27224, 27223, 27222, 27223, 27224, 27258, 27256, 27257, 10904, 10804, 10906, 10870, 9810, 15391, 16383,
10805, 10834, 10838, 10839, 27223, 27255, 28414, 27291, 27256, 27257, 27223, 27256, 26234, 27290, 27224, 27224, 27257, 27225, 27257, 27291, 26234, 26201, 27323, 27291, 26201, 26199, 27223, 27224, 27290, 27291, 28447, 28511,
10971, 10805, 11799, 16383, 0, 0, 8720, 9843, 10867, 10869, 10870, 10871, 27291, 27256, 27255, 27256, 27256, 27357, 27357, 27357, 27325, 27357, 27357, 27323, 27291, 27324, 27324, 27292, 27324, 27291, 27290, 27223,
27220, 27220, 27256, 26201, 27258, 27290, 27390, 10840, 15360, 0, 0, 0, 0, 16383, 8720, 10805, 10870, 27258, 27258, 27257, 27258, 27257, 27256, 27258, 27291, 27291, 27291, 27291, 27258, 27291, 27258, 27258,
27290, 26201, 26200, 26201, 27259, 27259, 27223, 27222, 27222, 9781, 9748, 9848, 27455, 9849, 10933, 0, 0, 0, 0, 0, 10933, 10871, 10872, 27257, 27224, 27256, 27257, 27224, 27224, 27258, 27290, 43643,
43642, 27291, 27291, 27324, 27259, 27258, 27257, 27222, 27222, 27223, 27225, 26201, 27224, 27224, 27222, 27223, 9748, 9714, 10904, 8723, 15391, 0, 0, 0, 0, 0, 16383, 10837, 10804, 9816, 27291, 27357,
27256, 27222, 27226, 27292, 27324, 43708, 43708, 27356, 43740, 43740, 27324, 43708, 27258, 27223, 27222, 27223, 27258, 27225, 26198, 27222, 27255, 27324, 9782, 8659, 10581, 0, 0, 0, 0, 0, 0, 0,
0, 8720, 16383, 8704, 9815, 27259, 27223, 27224, 27224, 27258, 27258, 27258, 27291, 27292, 27292, 27292, 27324, 27259, 27224, 27225, 27224, 26200, 27258, 27291, 27259, 27258, 27223, 27257, 9781, 9619, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 8720, 10804, 9816, 27222, 26202, 26234, 27225, 27291, 27291, 27389, 27390, 27357, 27390, 27390, 27256, 26198, 26200, 27224, 26202, 26200, 26201, 26166, 9814,
10805, 9782, 8657, 8720, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15391, 8720, 9779, 10836, 9780, 8693, 26167, 26164, 26198, 26198, 26199, 26200, 26202, 26200, 27258, 26199, 26199, 26167,
26167, 27225, 26201, 9782, 9779, 10773, 10801, 9746, 8528, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10933, 9843, 8720, 10570, 8757, 9779, 9781, 27189, 26199, 26200,
26202, 26167, 26134, 26134, 26134, 26167, 26132, 26165, 26200, 9749, 10933, 16383, 8720, 8720, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
16383, 10768, 9781, 9781, 27222, 26165, 26165, 9748, 25108, 8692, 9715, 26131, 9747, 9779, 26132, 8721, 8720, 0, 16383, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 9814, 10838, 9814, 26166, 26166, 26166, 26166, 25108, 8692, 25110, 26134, 9749, 9747, 9746, 8657, 15360, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8720, 9747, 9747, 9749, 9781, 9780, 9748, 8690, 8658, 8691, 8727, 8726, 9619, 8720, 8720, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10581, 15391, 8720, 9746, 8592, 7566, 6477, 8690, 8656, 8724, 8720, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15391, 0, 8720,
8720, 9619, 8720, 10581, 31, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 16383, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 15360, 8720, 9843, 8720, 0, 0, 0, 11799, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16383, 0, 16383, 10933, 10933, 11799, 11960, 10933, 8720, 8720, 11799, 10907, 11799, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10933, 11894, 9849, 10581, 9843, 11894, 10837, 10869, 9745, 9746, 9779, 10804, 11897, 11799, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16383, 11862, 10905, 11964, 10975, 10939, 11931, 11960, 11928, 28312, 11895, 11895,
11928, 11929, 11895, 16383, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16383, 11792, 10804, 11929, 12095, 13151, 12095,
11965, 11962, 11963, 28348, 27291, 10940, 11928, 11961, 10936, 11799, 10933, 9843, 8720, 16383, 16383, 10933, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16383,
11924, 11927, 28279, 28413, 28413, 28381, 27292, 27290, 28313, 28346, 28314, 27255, 28278, 11895, 11895, 10871, 11895, 11893, 10836, 10870, 10867, 11928, 8720, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 16383, 10837, 11928, 28311, 28312, 28311, 28310, 27255, 27255, 28311, 28311, 28310, 28310, 28278, 11893, 10870, 11926, 28314, 11926, 11928, 28348, 11895, 11927, 10933, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8720, 10870, 11926, 11926, 28310, 28311, 28310, 28312, 28312, 28311, 28311, 28311, 28311, 28278, 28310, 28312, 28346, 28348, 28346, 28347, 28347,
11895, 11926, 11862, 10933, 0, 0, 0, 0, 0, 0, 0, 0, 16383, 10933, 0, 0, 15391, 10836, 10904, 10870, 28311, 28311, 28278, 28310, 28310, 28311, 28311, 28310, 28310, 28311, 28278, 28310,
28310, 28311, 28278, 28278, 28278, 11926, 28312, 27255, 11924, 11924, 8720, 0, 0, 0, 0, 0, 0, 10933, 10933, 10837, 9747, 9650, 9810, 10869, 11927, 11894, 28310, 28310, 28310, 28310, 28310, 28311,
28310, 28311, 28312, 28380, 28311, 28277, 28310, 28311, 28310, 11892, 11860, 11893, 28313, 28312, 10870, 11891, 16383, 0, 0, 0, 0, 0, 0, 11792, 11891, 11926, 11926, 11893, 11894, 28278, 28310, 28310,
28310, 28310, 28312, 28311, 28311, 28311, 28311, 28311, 28312, 28346, 28312, 28278, 28310, 28310, 28310, 28310, 28278, 27253, 27255, 10838, 10803, 10867, 8720, 16383, 0, 0, 0, 0, 0, 16383, 12915, 11927,
28312, 28311, 28313, 28312, 28311, 28310, 28311, 28310, 28312, 28312, 28312, 28312, 28315, 28347, 28381, 28380, 28380, 28314, 28313, 28346, 28312, 28279, 28278, 28278, 28313, 27290, 10837, 10803, 10933, 12915, 16383, 0,
0, 0, 0, 0, 11792, 11926, 11926, 28278, 28311, 28313, 28311, 28311, 11927, 11926, 28310, 28278, 28278, 28278, 28279, 28311, 28312, 28311, 28311, 28311, 28311, 28311, 28278, 11894, 10870, 28278, 28314, 27289,
10870, 11893, 11924, 9843, 8720, 0, 0, 0, 0, 16383, 11862, 11926, 28311, 28314, 28314, 28346, 28315, 28314, 28314, 28314, 28314, 28314, 28314, 28314, 28281, 28313, 28313, 27289, 27289, 28313, 27289, 27289,
27257, 27257, 28313, 28312, 28278, 10869, 10867, 11891, 10773, 10933, 11799, 0, 0, 0, 0, 10933, 11860, 11926, 11894, 11926, 11928, 28312, 28312, 28312, 28313, 28314, 28313, 28312, 28314, 28314, 27255, 28311,
28281, 27255, 28279, 27289, 27287, 27256, 27255, 28280, 11930, 28314, 11926, 10805, 10933, 10869, 11926, 11926, 10839, 8727, 0, 0, 16383, 11957, 11894, 11925, 11926, 11894, 11926, 11926, 11926, 28310, 28310, 28312,
28312, 28313, 28314, 27291, 28314, 28313, 28312, 27256, 27289, 27290, 28314, 28314, 28313, 28313, 28347, 28347, 28312, 11926, 11894, 10870, 10837, 10836, 10838, 9843, 0, 0, 16383, 11895, 11929, 11927, 11925, 10868,
10870, 11926, 28279, 28312, 28312, 28313, 28312, 28312, 27289, 27256, 27256, 28313, 27256, 27256, 27258, 27256, 27256, 27289, 27258, 27290, 27291, 28314, 28312, 11927, 11893, 28277, 28310, 10870, 10837, 16383, 0, 0,
0, 9843, 10905, 11895, 11926, 11895, 11927, 28278, 28278, 28278, 28279, 28313, 28312, 27288, 27289, 27290, 27290, 27290, 43674, 27289, 43674, 43673, 43673, 27290, 27289, 27258, 27257, 27255, 11894, 10869, 27254, 28277,
11893, 10837, 10933, 0, 0, 0, 0, 8720, 10938, 11891, 11894, 10869, 11893, 11893, 10869, 10869, 10869, 10870, 27286, 28278, 27254, 27255, 27255, 27254, 27254, 27254, 27254, 27222, 27254, 27254, 27221, 27222,
10839, 10870, 10869, 10867, 11892, 10901, 11924, 10773, 0, 0, 0, 0, 10933, 11895, 11930, 11861, 27255, 28311, 11894, 28278, 28311, 28278, 27255, 28278, 27255, 27254, 27255, 27254, 27254, 27254, 27254, 27254,
27254, 27254, 27253, 27254, 27254, 27256, 27257, 27289, 27288, 28311, 10871, 10837, 10803, 10836, 8720, 0, 0, 0, 11867, 10907, 28346, 28311, 28312, 28312, 28278, 28278, 28311, 27255, 27287, 27255, 27255, 27254,
27254, 27254, 27254, 27254, 27254, 27254, 27254, 27254, 27254, 27254, 27255, 27255, 27255, 27255, 27254, 27254, 10868, 10869, 10837, 10869, 11799, 0, 0, 0, 10933, 11895, 28279, 28278, 27287, 10870, 10869, 10870,
10870, 10870, 11894, 11894, 10869, 10869, 27253, 27254, 27222, 27254, 27254, 27222, 27254, 27222, 27222, 27222, 27254, 10869, 10837, 10838, 10837, 10837, 10868, 10870, 10839, 10804, 9843, 15360, 0, 0, 8720, 9843,
10868, 11894, 11894, 10869, 11893, 10870, 11893, 10869, 11893, 10869, 10869, 10869, 11893, 10869, 27253, 27221, 27221, 10869, 10868, 10837, 27220, 10868, 10869, 10836, 10870, 10902, 10836, 10867, 10868, 10868, 10837, 10835,
11894, 11799, 0, 0, 8720, 9843, 11860, 11926, 11894, 11894, 28310, 28309, 28278, 28279, 28280, 27255, 27256, 27257, 27257, 27257, 27257, 27256, 27256, 27256, 27256, 27256, 27256, 27256, 27257, 27257, 27258, 28381,
10904, 10870, 11893, 11925, 11893, 11862, 10869, 11858, 16383, 16383, 10836, 9782, 10837, 11925, 11893, 11893, 28310, 27254, 27254, 27254, 27256, 27254, 27223, 27256, 27255, 27255, 27255, 27256, 27255, 27223, 27255, 27255,
27254, 27254, 27256, 27254, 27222, 27255, 10869, 10870, 11894, 11925, 11926, 28315, 10904, 10933, 0, 0, 9747, 10902, 11929, 11895, 10870, 27254, 27288, 27253, 27221, 27221, 27254, 27255, 27255, 27256, 27222, 27254,
27254, 27254, 27222, 27255, 27223, 27254, 27254, 27222, 27254, 27221, 27253, 27222, 27255, 27254, 27255, 10903, 10803, 10902, 11862, 11792, 0, 0, 8720, 11792, 11860, 10837, 10837, 10838, 28380, 27289, 27222, 27255,
27254, 27255, 27257, 27256, 27254, 27255, 27256, 27255, 27256, 27257, 27225, 27224, 27290, 27257, 27254, 27221, 27220, 27221, 27255, 27289, 28382, 28447, 10937, 9843, 8720, 16383, 0, 0, 0, 8720, 9843, 9843,
10870, 10838, 27290, 11895, 10869, 27222, 28310, 28381, 27356, 27324, 27291, 27357, 27357, 27323, 27258, 27291, 27291, 26234, 27259, 27258, 27257, 27222, 10836, 11860, 10838, 10838, 27256, 27256, 10875, 9813, 15360, 0,
0, 0, 0, 0, 16383, 9843, 11894, 28311, 27255, 11894, 28278, 27254, 27254, 27256, 27256, 27256, 27257, 27257, 27256, 27257, 27256, 27256, 27257, 26200, 26200, 27224, 27256, 27257, 27222, 10869, 10837, 10836,
10803, 10871, 10941, 10871, 8720, 0, 0, 0, 0, 0, 8720, 10869, 10871, 27255, 27254, 27255, 27255, 27254, 27254, 27256, 27256, 27256, 27256, 27256, 27256, 27257, 27256, 27256, 27255, 27222, 27221, 27222,
27254, 27223, 27222, 27254, 27221, 10870, 9779, 9744, 9815, 8657, 15391, 0, 0, 0, 0, 0, 0, 11858, 11862, 10871, 10873, 27259, 27254, 10837, 27224, 27258, 27290, 27290, 27291, 27323, 27323, 27323,
27291, 27323, 27257, 27254, 27221, 27222, 27223, 27222, 27220, 10837, 10837, 10840, 9748, 8657, 8720, 0, 0, 0, 0, 0, 0, 0, 0, 16383, 16383, 0, 9846, 10874, 10838, 27222, 27222, 27223,
27256, 27256, 27256, 27290, 27289, 27256, 27290, 27257, 27223, 27255, 27254, 27222, 27255, 27256, 27257, 27256, 10869, 10871, 9747, 10581, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15360,
9843, 10871, 10838, 27256, 27224, 27222, 27257, 27258, 27323, 27357, 27324, 27356, 28380, 27255, 27222, 27222, 27254, 27256, 27222, 27222, 9781, 10869, 10837, 9813, 8657, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 8720, 9779, 9811, 10804, 9779, 9782, 9779, 10805, 27221, 27222, 27222, 27223, 27254, 27256, 27222, 27222, 27222, 27221, 27223, 27223, 9782, 9747, 10933, 10933, 9650, 5450, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8720, 10933, 10933, 8720, 8725, 10773, 10837, 10868, 10870, 10837, 27224, 26165, 26133, 26165, 9781, 27190, 10804, 10804, 10839, 9781,
8720, 0, 16383, 15360, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8720, 10867, 10837, 10836, 10836, 10837, 9811, 9779, 8723,
9746, 9780, 9747, 10803, 10804, 8657, 15391, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10933, 10869, 10869,
10836, 27221, 10838, 10837, 9747, 8691, 9780, 9781, 9748, 9746, 9779, 9619, 15360, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 16383, 9843, 11799, 10773, 9812, 10836, 9779, 8657, 8721, 9748, 9782, 9814, 10933, 8720, 15360, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16383, 0, 15360, 8753, 8592, 7502, 6540, 8624, 8654, 9748, 10581, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15391, 0, 0, 0, 8720, 0, 8720, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8720, 11792, 0, 0, 0, 0,
10933, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16383, 8720,
11894, 10933, 15360, 16383, 8727, 11897, 10933, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8720, 9810,
8727, 10581, 8727, 11891, 10805, 10869, 8657, 9744, 9746, 10805, 10871, 10933, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 10933, 10870, 10906, 10909, 10873, 11962, 11928, 11894, 11927, 10870, 11926, 11926, 11959, 12921, 16383, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 8720, 10773, 11928, 11965, 11967, 10942, 11931, 11928, 11930, 11963, 11929, 10938, 11927, 11926, 10933, 8720, 8720, 8720, 0, 16383, 16383, 16383, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16383, 10933, 11924, 10870, 11931, 11931, 11931, 10873, 10903, 11895, 11928, 11929, 11894, 11894, 11894, 10837, 11894, 10870, 10836, 10834, 10869, 11828,
10933, 16383, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15360, 9810, 11957, 11927, 11926, 11926, 28310, 11893, 11861, 11893, 11926, 11925, 11892, 11893, 11892, 10869, 11925,
11927, 11925, 11927, 11930, 11925, 11926, 8720, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15360, 10933, 11858, 11926, 11926, 11925, 11926, 11926, 28310, 11926, 11925, 11958,
11926, 11893, 11957, 11927, 11927, 11929, 11929, 11960, 11927, 11926, 11924, 8720, 16383, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15391, 9747, 10870, 10869, 11926, 11926, 11925, 11925,
11925, 28310, 11926, 11926, 11925, 11926, 11925, 11925, 11926, 11926, 11893, 11925, 11958, 11926, 11927, 11925, 10933, 10933, 16383, 0, 0, 0, 0, 0, 16383, 8720, 16383, 16383, 16383, 16383, 10933, 11894,
11925, 11893, 11925, 11893, 11925, 11926, 28310, 28310, 11893, 11926, 28314, 11927, 11925, 11925, 11925, 11924, 11891, 11891, 11893, 11926, 11894, 9843, 10933, 0, 0, 0, 0, 0, 0, 16383, 8720, 10933,
11891, 12915, 11858, 11891, 11893, 11925, 11926, 11926, 11927, 11926, 11893, 11926, 11926, 11926, 11926, 11927, 11894, 11926, 11893, 11925, 11925, 11926, 11893, 10836, 11893, 10836, 10834, 9843, 16383, 0, 0, 0,
0, 0, 0, 10933, 11926, 11894, 11926, 11925, 11926, 11926, 11926, 11958, 11926, 11927, 28311, 28311, 28312, 28313, 28314, 28314, 28314, 28314, 28313, 28312, 28313, 11926, 11925, 11893, 10868, 11895, 11895, 10869,
10933, 16383, 16383, 0, 0, 0, 0, 0, 8720, 11891, 11893, 11924, 11893, 11927, 11926, 11926, 11957, 12918, 11957, 11893, 11925, 11893, 11926, 11894, 28310, 28310, 11926, 11926, 11926, 11926, 11924, 10870,
10837, 10837, 11927, 11927, 11862, 10933, 16383, 16383, 0, 0, 0, 0, 16383, 11858, 11926, 11925, 11894, 11926, 11927, 11927, 11927, 11927, 11926, 11959, 11926, 11926, 11928, 11894, 11894, 11927, 11926, 11926,
11927, 11893, 11927, 11925, 11894, 11927, 11927, 11894, 11860, 10933, 8720, 16383, 16383, 8720, 0, 0, 0, 8720, 11891, 11959, 11925, 11926, 11928, 11895, 11959, 11928, 11928, 11929, 11960, 11928, 11961, 11928,
11894, 11926, 11928, 11927, 11927, 11928, 11927, 11929, 11926, 11928, 11929, 11961, 11926, 10933, 11799, 11924, 11926, 11957, 10869, 10933, 0, 16383, 10933, 12918, 11957, 11957, 11925, 11926, 11893, 11925, 11893, 11926,
11926, 28311, 28311, 28313, 28313, 28312, 28312, 11927, 28312, 28312, 28313, 28313, 28313, 11927, 28311, 11929, 11928, 11926, 11925, 11924, 11893, 11924, 11957, 11860, 8720, 0, 0, 10933, 11927, 11926, 12918, 10867,
11924, 11893, 11925, 11926, 11925, 11926, 28310, 28310, 28278, 28278, 28310, 28310, 28310, 27254, 27255, 27254, 28278, 28311, 27255, 27255, 28311, 11927, 11894, 11925, 11893, 11924, 11892, 11924, 10933, 16383, 0, 0,
11799, 11960, 11926, 12981, 11924, 12918, 11893, 11893, 11892, 11893, 28312, 28311, 28310, 28310, 28311, 28310, 28312, 28313, 28312, 28311, 28311, 28311, 28311, 28279, 27256, 27255, 10870, 10901, 10900, 11893, 11925, 11893,
11891, 16383, 0, 0, 0, 15360, 12921, 9843, 12981, 10933, 12915, 11862, 10805, 10805, 11924, 11925, 11893, 11926, 11893, 11894, 10870, 10870, 11894, 11926, 11893, 10870, 11893, 11893, 10836, 10837, 10837, 11891,
11862, 11862, 11862, 11858, 11862, 10933, 0, 0, 0, 16352, 10933, 11928, 10867, 11893, 11894, 11893, 11957, 11926, 11925, 11927, 11893, 11927, 11894, 11926, 11925, 11892, 11892, 11925, 11892, 11892, 11893, 11892,
11893, 11893, 11894, 11927, 11894, 11894, 11894, 11926, 11894, 9843, 11858, 8720, 0, 0, 12921, 11929, 11961, 11926, 11893, 11925, 11893, 11924, 11893, 11926, 11893, 11925, 11926, 11926, 11925, 11893, 11892, 11893,
11893, 11892, 11893, 11893, 11892, 11893, 11892, 11893, 11925, 11926, 11893, 11924, 10933, 11861, 11924, 10805, 8720, 0, 0, 8720, 10870, 11926, 11893, 10868, 11893, 10870, 11926, 11924, 11893, 11893, 11926, 11924,
11926, 11925, 11893, 11893, 11925, 11892, 11892, 11925, 11893, 11892, 10868, 11925, 11893, 11892, 10836, 10869, 10870, 10933, 10869, 11924, 10773, 10933, 15360, 0, 0, 10933, 10870, 11893, 11862, 12915, 10933, 10870,
11957, 11924, 11861, 11924, 11861, 11924, 10870, 11893, 11925, 10868, 11892, 11860, 11893, 11893, 10868, 10867, 10837, 11924, 10867, 10837, 10933, 12915, 11862, 11891, 10870, 10804, 11894, 8720, 0, 8720, 11792, 11862,
11957, 12981, 11894, 10870, 11893, 11926, 11895, 11927, 11895, 11927, 11894, 27254, 28279, 28279, 28279, 28278, 28278, 27254, 28278, 27254, 28278, 28278, 11894, 10871, 27257, 10871, 11924, 12981, 11957, 11924, 11893, 11860,
11799, 16383, 9846, 9843, 11862, 11862, 11891, 10870, 11893, 10867, 11893, 10869, 11894, 11893, 10870, 10870, 27222, 11894, 11894, 28278, 28277, 27253, 28277, 27254, 27253, 28277, 28278, 10869, 10836, 10838, 10867, 11924,
11891, 10933, 11957, 10904, 10903, 11799, 0, 8720, 10933, 11928, 11893, 11893, 10870, 11894, 10836, 10836, 10869, 11893, 10870, 11893, 10870, 10870, 10870, 11893, 11893, 11893, 10870, 10869, 10869, 10868, 11893, 11893,
10869, 11893, 11893, 11893, 11893, 11927, 11894, 10928, 11926, 10805, 8720, 0, 0, 8720, 11894, 11891, 10804, 9781, 27258, 10838, 10868, 10870, 10870, 10870, 27222, 27254, 10869, 11894, 11894, 11894, 10869, 10839,
10870, 10870, 10870, 10871, 11893, 11861, 10836, 11861, 11893, 11894, 27291, 11932, 10871, 10933, 16383, 0, 0, 0, 16383, 11792, 11792, 12915, 10837, 10872, 11862, 11924, 10838, 10870, 27290, 27258, 27257, 27257,
27258, 27259, 27257, 27256, 27257, 27225, 27224, 27257, 27257, 27255, 10869, 11891, 11891, 11893, 11860, 11895, 11927, 10871, 10805, 0, 0, 0, 0, 0, 16383, 8720, 11926, 10871, 11926, 11894, 11893, 10836,
11892, 11894, 10870, 27254, 27222, 27222, 27222, 27256, 27254, 27254, 27223, 10838, 9814, 10870, 27254, 27255, 10836, 11860, 10867, 9843, 9843, 9847, 10873, 10838, 8720, 0, 0, 0, 0, 16383, 12915, 10869,
10871, 10869, 10869, 28277, 11893, 10869, 11893, 11894, 28311, 28278, 10870, 28278, 10870, 11894, 28278, 11894, 10868, 10868, 10868, 10836, 27221, 10869, 11894, 10869, 10838, 10803, 10933, 8757, 8720, 15391, 0, 0,
0, 0, 0, 16383, 10933, 9843, 10872, 11897, 10870, 10868, 10870, 27287, 28281, 27289, 27289, 27289, 27257, 27257, 28314, 27257, 11896, 11893, 10869, 11893, 11893, 10836, 10804, 10805, 10869, 10838, 9779, 10933,
15360, 15360, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10805, 10873, 11860, 10837, 10836, 11894, 10871, 10871, 11894, 10871, 10870, 10870, 10871, 27255, 10870, 10869, 11894, 11894, 10871, 10869, 10872,
11895, 11924, 10869, 10804, 16383, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10773, 10838, 10869, 10870, 27222, 10869, 10870, 10872, 11897, 10873, 27257, 27257, 27289, 10871, 10869, 11894,
10870, 10870, 10869, 10836, 10805, 11862, 10933, 10836, 8720, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8720, 9747, 10836, 10803, 9746, 10804, 10770, 10836, 10837, 10837, 10836, 27221,
27253, 27254, 10837, 10837, 10837, 10869, 11893, 10870, 10803, 11858, 8720, 16383, 8720, 8720, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16383, 8720, 8720, 8720, 8720, 11792,
10837, 11924, 11893, 10869, 10838, 10836, 9780, 9781, 9812, 10838, 10803, 10803, 10838, 9843, 8720, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 16383, 11862, 11894, 10867, 10837, 11860, 10804, 9779, 8657, 10801, 10836, 10804, 10801, 10803, 8657, 15360, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 16383, 11862, 11926, 10870, 10868, 10837, 10836, 9779, 8721, 9748, 10836, 10837, 10773, 9843, 8720, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16383, 8720, 8720, 10933, 11891, 9843, 8753, 8657, 9744, 9746, 10803, 8720, 16383, 16383, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15360, 9843, 8720, 6540, 6540, 9650, 9650, 9810, 15391, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15391, 15391, 0, 0,
15391, 0, 16383, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 8720, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 16383, 16383, 16383, 15360, 0, 0, 10933, 10871, 8720, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 15360, 9843, 10933, 8720, 10933, 10933, 11858, 10801, 8720, 9650, 9650, 10773, 10870, 8720, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 16383, 10933, 11927, 10906, 10838, 10871, 11958, 11925, 11894, 11894, 11925, 11924, 11891, 10933, 16383, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 15391, 8720, 11891, 11961, 11931, 10907, 11928, 11927, 11960, 11961, 10903, 11928, 11959, 11894, 10933, 16383, 16383, 16383, 0, 16383, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8720, 9843, 11924, 11960, 11928, 11927, 11894, 11895, 11893, 11926, 11926, 11926, 11893, 12918, 11957, 11926, 10870, 10837, 9843,
11862, 11792, 16383, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8720, 12915, 11959, 11926, 11926, 11926, 11924, 10837, 11894, 12981, 11894, 11893, 11893, 11891, 10867,
11957, 11927, 11957, 11957, 12982, 12981, 12023, 16383, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8720, 10933, 10933, 12981, 11990, 12981, 11957, 11957, 11926, 11990, 12915,
12981, 11858, 12915, 11926, 11959, 11926, 11958, 11959, 12918, 10933, 12023, 16383, 16383, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10933, 10837, 10867, 11924, 11926, 11862, 11891, 12918,
11957, 12981, 11990, 11891, 11893, 10933, 12915, 11891, 12918, 11894, 11862, 12921, 12915, 12918, 11924, 10933, 11799, 16383, 0, 0, 0, 0, 0, 0, 16383, 16383, 0, 0, 10933, 10805, 10933, 10933,
11891, 12981, 11924, 11957, 11926, 11957, 12918, 12918, 11959, 11861, 11891, 11891, 10837, 11862, 11799, 10933, 11862, 11893, 11925, 9843, 8720, 0, 0, 0, 0, 0, 0, 16383, 16383, 11799, 8720, 10933,
11799, 11891, 12981, 13014, 11957, 11926, 11958, 11893, 11957, 11926, 11957, 11957, 11958, 12918, 11957, 11957, 12918, 11957, 11894, 11894, 11891, 10869, 11860, 9810, 8720, 0, 0, 0, 0, 0, 0, 16383,
8720, 11891, 10933, 11894, 11924, 12918, 12918, 13014, 11957, 11958, 12950, 11926, 11926, 11927, 11926, 11926, 11926, 11927, 11926, 11926, 11927, 11925, 12918, 11957, 10867, 11925, 11926, 9843, 8720, 16383, 16383, 0,
0, 0, 0, 16383, 10933, 10933, 11891, 10867, 11893, 12981, 11891, 11990, 12981, 11990, 12981, 12981, 11894, 11925, 11893, 11893, 11924, 11894, 11894, 11924, 11894, 11891, 12915, 12915, 11862, 11927, 11893, 10805,
8720, 16383, 0, 0, 0, 0, 0, 8720, 11862, 11862, 10933, 10933, 12918, 11891, 11891, 11891, 11891, 11891, 12981, 12981, 12981, 11924, 11924, 11924, 11894, 12981, 12981, 12918, 12981, 11891, 11862, 11862,
11891, 11894, 11891, 10933, 8720, 16383, 16383, 16383, 0, 0, 16383, 10933, 11926, 11957, 11957, 11928, 11926, 11926, 11959, 12982, 11959, 11928, 11958, 11960, 11960, 11926, 11925, 11927, 11927, 11958, 11927, 11958,
11960, 11893, 11928, 11928, 11926, 11990, 8720, 8720, 11891, 12981, 12981, 11891, 8720, 0, 8720, 12915, 12023, 11799, 11799, 12915, 12915, 10933, 12981, 11895, 13014, 11926, 11925, 11927, 11927, 11927, 11927, 11925,
11925, 11894, 11958, 11958, 11958, 11926, 11926, 11893, 11894, 12023, 8720, 10933, 11862, 11862, 10933, 9843, 16383, 0, 10933, 13014, 12981, 10933, 10933, 10933, 10933, 12023, 12915, 10933, 11924, 11925, 11924, 11893,
10868, 10868, 11893, 11925, 11860, 11893, 11892, 11925, 11893, 11893, 10869, 11893, 11924, 12023, 10933, 12023, 10933, 11894, 12915, 16383, 0, 0, 10933, 12920, 12915, 8720, 8720, 10933, 12023, 12023, 12915, 12981,
11926, 11926, 11893, 11893, 11925, 11893, 11926, 28310, 28310, 28310, 28310, 28310, 11926, 11894, 11895, 11893, 11862, 12023, 12023, 12915, 11891, 11894, 10933, 0, 0, 0, 15360, 10933, 8720, 11799, 10933, 10933,
10933, 10933, 12023, 12915, 11861, 11924, 11893, 11893, 11957, 11924, 11924, 11926, 11925, 11924, 11924, 11924, 11893, 10867, 10869, 11891, 11799, 10933, 8720, 10933, 10933, 8720, 16383, 0, 0, 16383, 9843, 11895,
10933, 11957, 11924, 12981, 11894, 11926, 11926, 11926, 11924, 12918, 12918, 11924, 11924, 11893, 11893, 11957, 11924, 12918, 12918, 11924, 11893, 11924, 10870, 11924, 11893, 11894, 12981, 10933, 10933, 8720, 11799, 15360,
0, 10933, 11926, 11926, 12981, 12918, 11891, 10933, 11990, 11990, 11891, 11891, 12981, 12981, 12981, 11894, 11924, 11924, 11894, 11894, 11894, 11894, 11894, 10867, 10867, 12981, 11891, 11894, 12918, 11862, 12915, 11799,
12915, 11792, 11799, 16383, 0, 0, 12915, 12981, 11891, 11891, 11799, 10933, 12023, 12023, 12023, 12023, 12915, 12915, 10933, 10933, 11891, 12981, 11891, 11862, 11862, 11862, 11862, 11858, 11858, 10933, 12915, 12915,
12915, 11799, 10933, 10933, 12915, 11792, 8720, 16383, 0, 15360, 16383, 12915, 11891, 10933, 8720, 10933, 10933, 10933, 10933, 10933, 10933, 11862, 10933, 11891, 11891, 12981, 11957, 12981, 11862, 11891, 11862, 10933,
11862, 10933, 12915, 11792, 10773, 10933, 8720, 8720, 10933, 11799, 10933, 10933, 16383, 8720, 8720, 10933, 10933, 10933, 10933, 12915, 11894, 11924, 11893, 11893, 11893, 11893, 11924, 10869, 11894, 11893, 11925, 11925,
11924, 11893, 11924, 11924, 11924, 11924, 11893, 11893, 10870, 11891, 10933, 8720, 8720, 12915, 10933, 10933, 0, 9843, 10933, 10933, 10933, 10933, 12023, 12915, 12915, 11862, 11924, 11893, 11894, 10867, 10867, 10835,
11860, 11924, 11924, 11891, 10900, 10900, 11893, 11860, 11860, 11862, 11924, 10805, 11891, 10773, 10933, 8720, 16383, 11799, 11863, 11891, 16383, 16383, 8720, 11862, 10933, 11858, 10933, 10870, 10804, 10801, 10837, 10870,
11924, 11924, 11924, 10867, 11924, 11924, 11893, 11924, 11893, 11924, 11861, 11861, 10870, 11924, 11861, 11924, 10805, 10805, 11891, 11895, 12023, 8720, 11799, 10933, 0, 0, 16383, 10933, 10933, 11792, 10805, 10904,
11893, 10805, 11860, 11893, 11892, 10868, 10836, 11860, 11893, 11893, 10867, 11893, 11893, 11893, 11924, 11924, 11893, 11893, 10837, 11924, 11891, 11858, 11895, 11929, 11931, 11895, 16383, 0, 0, 0, 0, 16383,
16383, 16383, 10773, 11894, 11891, 9843, 10869, 11924, 10838, 10870, 10837, 10837, 11927, 10872, 10870, 10837, 10870, 10870, 10837, 10837, 10870, 10837, 10837, 9843, 11792, 10933, 12915, 11894, 11895, 10869, 10773, 0,
0, 0, 0, 0, 16383, 10933, 11924, 10837, 12915, 10933, 10805, 11891, 10870, 10836, 10869, 10837, 10803, 9780, 10868, 10869, 10869, 9781, 9779, 8721, 9779, 11860, 11860, 11891, 11799, 11792, 8720, 11792,
11799, 10838, 10803, 8720, 0, 0, 0, 0, 16383, 11799, 10933, 11862, 11894, 11957, 10933, 10933, 11894, 11957, 11893, 11860, 10870, 10867, 10870, 10870, 11924, 11924, 11858, 10773, 10773, 10805, 11892, 11892,
11895, 11860, 10870, 11894, 8720, 9810, 8720, 15391, 0, 0, 0, 0, 0, 16383, 10933, 11894, 11926, 11891, 11799, 11891, 11926, 11926, 11894, 11926, 11926, 11896, 11896, 11926, 10903, 11894, 11862, 11799,
11799, 10933, 10804, 10801, 10933, 11858, 10867, 10801, 8720, 15391, 15360, 0, 0, 0, 0, 0, 0, 0, 0, 11799, 11864, 11862, 11891, 11891, 11924, 11860, 11893, 10869, 11893, 11924, 11924, 11860,
10868, 11893, 11894, 10933, 10933, 11894, 11924, 11862, 11891, 12915, 11891, 10773, 16383, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8720, 10837, 10805, 10803, 10836, 10867, 10869, 11893, 10869,
11893, 10869, 11893, 11925, 11892, 11893, 11893, 11860, 11894, 10869, 10867, 9843, 11792, 11792, 11858, 8720, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8720, 10773, 10773, 9747, 9779,
10773, 10805, 11924, 11924, 10804, 10867, 11924, 10901, 11860, 11860, 10869, 10869, 11893, 10837, 9843, 8720, 16383, 16383, 16383, 15360, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
16383, 16383, 15391, 8720, 8720, 12915, 12915, 11862, 9843, 10837, 9843, 9746, 8753, 9747, 10837, 9843, 9843, 10837, 10768, 15391, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 16383, 10933, 10933, 11799, 10933, 11799, 10933, 10933, 10581, 10933, 11792, 10933, 10933, 10801, 9619, 15360, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16383, 11799, 11862, 11891, 10804, 10805, 9843, 9843, 8720, 9747, 10805, 11858, 10933, 10933, 15391, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16383, 16383, 8720, 9843, 10773, 9843, 9612, 9612, 10768, 10773, 8720, 16383, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10933, 8720, 8720, 8720, 8720, 8720, 10933, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
16383, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, };
Sprites explosion(20, explosionPixels, explosionOffsets, explosionRes, explosionPoints, explosionPointOffsets, Sprites::PixelFormat::R5G5B4A2);

View file

@ -0,0 +1,116 @@
//This example acts like a websever. It can create an access point or join an existing WiFI network.
//All text that's entered in the served page will bis displayed on the connected VGA screen.
//You need to connect a VGA screen cable to the pins specified below.
//cc by-sa 4.0 license
//bitluni
#include <stdio.h>
#include <WiFi.h>
#include <WebServer.h>
//ESP32Lib headers
#include <ESP32Lib.h>
#include <Ressources/Font6x8.h>
//true: creates an access point, false: connects to an existing wifi
const bool AccessPointMode = true;
//wifi credentials (enter yours if you arne not using the AccessPointMode)
const char *ssid = "VGA";
const char *password = "";
//pin configuration, change if you need to
const int redPin = 14;
const int greenPin = 19;
const int bluePin = 27;
const int hsyncPin = 32;
const int vsyncPin = 33;
//the webserver at pot 80
WebServer server(80);
//The VGA Device
VGA3Bit vga;
//include html page
const char *page =
#include "page.h"
;
///Html page is sent on root
void sendPage()
{
server.send(200, "text/html", page);
}
///Received text will be displayed on the screen
void text()
{
server.send(200, "text/plain", "ok");
vga.println(server.arg(0).c_str());
}
///initialization
void setup()
{
Serial.begin(115200);
//Handle the WiFi AP or STA mode and display results on the screen
if (AccessPointMode)
{
Serial.println("Creating access point...");
WiFi.softAP(ssid, password, 6, 0);
}
else
{
Serial.print("Connecting to SSID ");
Serial.println(ssid);
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED)
{
delay(500);
vga.print(".");
}
}
//start vga on the specified pins
vga.init(vga.MODE400x300, redPin, greenPin, bluePin, hsyncPin, vsyncPin);
//make the background blue
vga.clear(vga.RGBA(0, 0, 255));
vga.backColor = vga.RGB(0, 0, 255);
//select the font
vga.setFont(Font6x8);
//send page on http://<ip>/
server.on("/", sendPage);
//receive text on http://<ip>/text
server.on("/text", text);
//start the server
server.begin();
//display some text header on the screen including the ip
vga.clear(vga.RGBA(0, 0, 255));
vga.setCursor(0, 0);
vga.println("----------------------");
vga.println("bitluni's VGA Terminal");
if (AccessPointMode)
{
vga.print("SSID: ");
vga.println(ssid);
if (strlen(password))
{
vga.print("password: ");
vga.println(password);
}
vga.println("http://192.168.4.1");
}
else
{
vga.print("http://");
vga.println(WiFi.localIP().toString().c_str());
}
vga.println("----------------------");
}
void loop()
{
//process the server stuff
server.handleClient();
delay(10);
}

View file

@ -0,0 +1,92 @@
R"(
<html>
<head>
<title>bitluni's VGA text terminal</title>
<script>
function load() {
document.querySelector('#in').focus();
}
function send() {
var e = document.querySelector('#in');
var xhr = new XMLHttpRequest();
xhr.open('POST', '/text');
xhr.send(e.value);
document.querySelector("#log").innerHTML = e.value + "\n" + document.querySelector("#log").innerHTML;
e.value = '';
}
</script>
<style>
h1
{
color: white;
background: #800000;
padding: 10px;
border-radius: 5px;
margin-bottom: 5px;
}
body
{
font-family: monospace;
padding: 0;
}
input, textarea, button
{
border-style: solid;
border-radius: 3px;
}
td
{
width: auto;
}
td.min
{
width: 1%;
}
#in{
margin-bottom: 10px;
width: 100%;
}
#send{
margin-bottom: 10px;
}
#log
{
resize: vertical;
height: 200px;
width: 100%
}
#area
{
margin-top: 100px;
height: 500px;
}
table
{
width: 100%;
}
</style>
</head>
<body onload='load()'>
<h1>bitluni's VGA text terminal</h1>
<table>
<tr>
<td><input id='in' type='text' tabindex=1 onchange='send()' autocomplete='off'></td>
<td class='min'><button id='send' onclick='send()'>send</button></td>
</tr>
<tr>
<td colspan=2>
<textarea id='log' readonly>
</textarea>
</td>
</tr>
</table>
</body>
</html>
)"

View file

View file

@ -0,0 +1,22 @@
{
"name": "bitluni ESP32Lib",
"keywords": "VGA, audio, I2S, 3d, game, engine, mesh, gamepad, controller, NES, SNES, input, output, graphics, font, arduino, esp32, driver, display, bitluni",
"description": "Provides VGA, Game Controller (NES, SNES), Audio support for the ESP32. The graphics engine supports sprites, animations and 3d meshes.",
"repository":
{
"type": "git",
"url": "https://github.com/bitluni/ESP32Lib.git"
},
"authors":
[
{
"name": "bitluni",
"email": "platformio@bitluni.net",
"url": "https://github.com/bitluni",
"maintainer": true
}
],
"version": "0.2.1",
"frameworks": "arduino",
"platforms": "espressif32"
}

View file

@ -0,0 +1,10 @@
name=bitluni ESP32Lib
version=0.2.1
author=bitluni <arduino@bitluni.net>
maintainer=bitluni <arduino@bitluni.net>
sentence=Multimedia library for the ESP32
paragraph=Provides VGA, Game Controller (NES, SNES), Audio support for the ESP32. The graphics engine supports sprites, animations and 3d meshes.
url=https://github.com/bitluni/ESP32Lib
architectures=esp32
includes=ESP32Lib.h
category=Other

View file

@ -0,0 +1,58 @@
/*
Author: bitluni 2019
License:
Creative Commons Attribution ShareAlike 4.0
https://creativecommons.org/licenses/by-sa/4.0/
For further details check out:
https://youtube.com/bitlunislab
https://github.com/bitluni
http://bitluni.net
*/
#include "soc/i2s_reg.h"
#include "soc/timer_group_struct.h"
#include "driver/periph_ctrl.h"
#include "driver/timer.h"
#include "AudioSystem.h"
class AudioOutput;
void IRAM_ATTR timerInterrupt(AudioOutput *audioOutput);
class AudioOutput
{
public:
AudioSystem *audioSystem;
void init(AudioSystem &audioSystem)
{
this->audioSystem = &audioSystem;
timer_config_t config;
config.alarm_en = 1;
config.auto_reload = 1;
config.counter_dir = TIMER_COUNT_UP;
config.divider = 16;
config.intr_type = TIMER_INTR_LEVEL;
config.counter_en = TIMER_PAUSE;
timer_init((timer_group_t)TIMER_GROUP_0, (timer_idx_t)TIMER_0, &config);
timer_pause((timer_group_t)TIMER_GROUP_0, (timer_idx_t)TIMER_0);
timer_set_counter_value((timer_group_t)TIMER_GROUP_0, (timer_idx_t)TIMER_0, 0x00000000ULL);
timer_set_alarm_value((timer_group_t)TIMER_GROUP_0, (timer_idx_t)TIMER_0, 1.0/audioSystem.samplingRate * TIMER_BASE_CLK / config.divider);
timer_enable_intr((timer_group_t)TIMER_GROUP_0, (timer_idx_t)TIMER_0);
timer_isr_register((timer_group_t)TIMER_GROUP_0, (timer_idx_t)TIMER_0, (void (*)(void*))timerInterrupt, (void*) this, ESP_INTR_FLAG_IRAM, NULL);
timer_start((timer_group_t)TIMER_GROUP_0, (timer_idx_t)TIMER_0);
}
};
void IRAM_ATTR timerInterrupt(AudioOutput *audioOutput)
{
uint32_t intStatus = TIMERG0.int_st_timers.val;
if(intStatus & BIT(TIMER_0))
{
TIMERG0.hw_timer[TIMER_0].update = 1;
TIMERG0.int_clr_timers.t0 = 1;
TIMERG0.hw_timer[TIMER_0].config.alarm_en = 1;
WRITE_PERI_REG(I2S_CONF_SIGLE_DATA_REG(0), audioOutput->audioSystem->nextSample() << 24);
}
}

View file

@ -0,0 +1,209 @@
/*
Author: bitluni 2019
License:
Creative Commons Attribution ShareAlike 4.0
https://creativecommons.org/licenses/by-sa/4.0/
For further details check out:
https://youtube.com/bitlunislab
https://github.com/bitluni
http://bitluni.net
*/
#pragma once
#include "../Tools/Log.h"
class Sound
{
public:
const signed char *samples;
int sampleCount;
long long position;
int positionIncrement;
int volume;
bool playing;
int id;
bool loop;
Sound *next;
void remove(Sound **prevNext)
{
*prevNext = next;
delete this;
}
void insert(Sound **prevNext)
{
next = *prevNext;
*prevNext = this;
}
void init(const signed char *samples, int sampleCount, float volume = 1, float speed = 1, bool loop = false)
{
next = 0;
id = 0;
this->samples = samples;
this->sampleCount = sampleCount;
this->loop = loop;
position = 0;
positionIncrement = int(65536 * speed);
this->volume = volume * 256;
playing = true;
}
///returns the next rendered sample. 16bit since it's scaled by volume
int nextSample()
{
if(!playing) return 0;
int s = samples[position >> 16] * volume;
position += positionIncrement;
if((position >> 16) >= sampleCount)
{
if(loop)
position = 0;
else
playing = false;
}
return s;
}
};
class AudioSystem
{
public:
Sound *sounds;
int samplingRate;
unsigned char *buffer;
int bufferSize;
bool swapped;
int currentId;
volatile int readPosition;
int writePosition;
int volume;
AudioSystem(int samplingRate, int bufferSize)
{
this->samplingRate = samplingRate;
this->bufferSize = bufferSize;
sounds = 0;
buffer = (unsigned char*)malloc(bufferSize * sizeof(unsigned char));
if(!buffer)
ERROR("Not enough memory for audio buffer");
for(int i = 0; i < bufferSize; i++)
buffer[i] = 128;
swapped = true;
currentId = 0;
readPosition = 0;
writePosition = 0;
volume = 256;
}
///plays a sound, and returns an idividual id
int play(Sound *sound)
{
sound->id = currentId;
sound->insert(&sounds);
return currentId++;
}
///fills the buffer with all saounds that are currently playing
void calcSamples()
{
int samples = readPosition - writePosition;
if(samples < 0)
samples += bufferSize;
for(int i = 0; i < samples; i++)
{
int sample = 0;
Sound **soundp = &sounds;
while(*soundp)
{
sample += (*soundp)->nextSample();
if(!(*soundp)->playing)
(*soundp)->remove(soundp);
else
soundp = &(*soundp)->next;
}
if(sample >= (1 << 15))
sample = (1 << 15) - 1;
else if(sample < -(1 << 15))
sample = -(1 << 15);
sample = ((sample * volume) >> 16) + 128;
buffer[writePosition] = sample;
writePosition++;
if(writePosition >= bufferSize)
writePosition = 0;
}
}
inline unsigned char nextSample()
{
unsigned char s = buffer[readPosition];
readPosition++;
if(readPosition >= bufferSize)
readPosition = 0;
return s;
}
///stops playing a sound with an individual id
void stop(int id)
{
Sound **soundp = &sounds;
while(*soundp)
{
if((*soundp)->id == id)
{
(*soundp)->remove(soundp);
return;
}
soundp = &(*soundp)->next;
}
}
///stops playing all sounds of an specific sample pointer
void stopBySample(const signed char *samples)
{
Sound **soundp = &sounds;
while(*soundp)
{
if((*soundp)->samples == samples)
(*soundp)->remove(soundp);
else
soundp = &(*soundp)->next;
}
}
};
class Wavetable
{
public:
const signed char *samples;
int soundCount;
const int *offsets;
int samplingRate;
Wavetable(const signed char *samples, int soundCount, const int *offsets, int samplingRate)
{
this->samples = samples;
this->soundCount = soundCount;
this->offsets = offsets;
this->samplingRate = samplingRate;
}
int play(AudioSystem &audioSystem, int soundNumber, float amplitude = 1, float speed = 1, bool loop = false)
{
Sound *sound = new Sound();
sound->init(&samples[offsets[soundNumber]], offsets[soundNumber + 1] - offsets[soundNumber], amplitude, speed * samplingRate / audioSystem.samplingRate, loop);
return audioSystem.play(sound);
}
void stop(AudioSystem &audioSystem, int id)
{
audioSystem.stop(id);
}
void stop(AudioSystem &audioSystem)
{
for(int i = 0; i < soundCount; i++)
audioSystem.stopBySample(&samples[offsets[i]]);
}
};

View file

@ -0,0 +1,128 @@
/*
Author: bitluni 2019
License:
Creative Commons Attribution ShareAlike 4.0
https://creativecommons.org/licenses/by-sa/4.0/
For further details check out:
https://youtube.com/bitlunislab
https://github.com/bitluni
http://bitluni.net
*/
#pragma once
const int MAX_CONTROLLERS = 4;
class GameControllers
{
public:
enum Type
{
NES = 0,
SNES = 1,
};
enum Button
{
B = 0,
Y = 1,
SELECT = 2,
START = 3,
UP = 4,
DOWN = 5,
LEFT = 6,
RIGHT = 7,
A = 8,
X = 9,
L = 10,
R = 11,
};
Type types[MAX_CONTROLLERS];
int latchPin;
int clockPin;
int dataPins[MAX_CONTROLLERS];
int buttons[MAX_CONTROLLERS][12];
///This has to be initialized once for the shared pins latch and clock
void init(int latch, int clock)
{
latchPin = latch;
clockPin = clock;
pinMode(latchPin, OUTPUT);
digitalWrite(latchPin, LOW);
pinMode(clockPin, OUTPUT);
digitalWrite(clockPin, HIGH);
for(int c = 0; c < MAX_CONTROLLERS; c++)
{
for(int i = 0; i < 12; i++)
buttons[c][i] = -1;
types[c] = NES;
dataPins[c] = -1;
}
}
///This sets the controller type and initializes its individual data pin
void setController(int controller, Type type, int dataPin)
{
types[controller] = type;
dataPins[controller] = dataPin;
pinMode(dataPins[controller], INPUT_PULLUP);
}
void poll()
{
digitalWrite(latchPin, HIGH);
delayMicroseconds(12);
digitalWrite(latchPin, LOW);
delayMicroseconds(6);
for(int i = 0; i < 12; i++)
{
for(int c = 0; c < MAX_CONTROLLERS; c++)
if(dataPins[c] > -1)
{
if(digitalRead(dataPins[c]))
buttons[c][i] = -1;
else
buttons[c][i]++;
}
digitalWrite(clockPin, LOW);
delayMicroseconds(6);
digitalWrite(clockPin, HIGH);
delayMicroseconds(6);
}
}
int translate(int controller, Button b) const
{
if(types[controller] == SNES) return b;
static const int translateToNES[] = {1, 8, 2, 3, 4, 5, 6, 7, 0, 8, 8, 8};
return translateToNES[b];
}
///button will be unpressed until released again
void clear(int controller, Button b)
{
buttons[controller][translate(controller, b)] = 0x80000000;
}
///returns if button is currently down
bool down(int controller, Button b) const
{
return buttons[controller][translate(controller, b)] >= 0;
}
///returns true if button state changed to down since previous poll. repeatAfterTics can be used to repeat after button was hold down for sme time
bool pressed(int controller, Button b, int repeatAfterTics = 0x7fffffff) const
{
return buttons[controller][translate(controller, b)] == 0 || (buttons[controller][translate(controller, b)] >= repeatAfterTics);
}
///returns the type of controller configured
Type getType(int controller)
{
return types[controller];
}
};

View file

@ -0,0 +1,14 @@
#pragma once
#include <VGA/VGA14BitI.h>
#include <VGA/VGA14Bit.h>
#include <VGA/VGA6BitI.h>
#include <VGA/VGA6Bit.h>
#include <VGA/VGA3BitI.h>
#include <VGA/VGA3Bit.h>
#include <Graphics/Sprites.h>
#include <Graphics/Mesh.h>
#include <Graphics/Sprites.h>
#include <Graphics/Animation.h>
#include <Controller/GameControllers.h>
#include <Audio/AudioOutput.h>

View file

@ -0,0 +1,31 @@
/*
Author: bitluni 2019
License:
Creative Commons Attribution ShareAlike 4.0
https://creativecommons.org/licenses/by-sa/4.0/
For further details check out:
https://youtube.com/bitlunislab
https://github.com/bitluni
http://bitluni.net
*/
#pragma once
#include "Adafruit_GFX.h"
template<class Base>
class GfxWrapper : public Adafruit_GFX
{
public:
Base &base;
typedef typename Base::Color Color;
GfxWrapper(Base &vga, const int xres, const int yres)
:base(vga),
Adafruit_GFX(xres, yres)
{
}
virtual void drawPixel(int16_t x, int16_t y, uint16_t color)
{
base.dot(x, y, base.RGBA((color >> 8) & 0b11111000, (color >> 3) & 0b11111100, (color << 3) & 0b11111000));
}
};

View file

@ -0,0 +1,86 @@
/*
Author: bitluni 2019
License:
Creative Commons Attribution ShareAlike 4.0
https://creativecommons.org/licenses/by-sa/4.0/
For further details check out:
https://youtube.com/bitlunislab
https://github.com/bitluni
http://bitluni.net
*/
#pragma once
#include "Entity.h"
class Animation : public Entity
{
public:
int start, end, frameDuration;
int time;
int drawMode;
Animation(Sprites &sprites, int x, int y, int start, int end, int frameDuration, int drawMode = 0)
{
this->x = x;
this->y = y;
this->sprites = &sprites;
this->start = start;
this->end = end;
this->frameDuration = frameDuration;
time = 0;
this->drawMode = drawMode;
}
virtual ~Animation()
{
}
bool act(int dt)
{
time += dt;
return time < (end - start + 1) * frameDuration;
}
/*
void draw(Graphics &g)
{
int current = time / frameDuration + start;
if (drawMode == 0)
this->sprites->drawMix(g, current, this->x, this->y);
else if (drawMode == 1)
this->sprites->drawAdd(g, current, this->x, this->y);
}
*/
static void animationsAct(Animation **animations, int dt, int maxCount = 100)
{
for (int i = 0; i < maxCount; i++)
{
if (animations[i])
if (!animations[i]->act(dt))
{
delete animations[i];
animations[i] = 0;
}
}
}
/*
void animationsDraw(Graphics &g, Animation **animations, int maxCount = 100)
{
for (int i = 0; i < maxCount; i++)
if (animations[i])
if (animations[i])
animations[i]->draw(g);
}
*/
void animationsEmit(Animation **animations, Animation *e, int maxCount = 100)
{
for (int i = 0; i < maxCount; i++)
{
if (!animations[i])
{
animations[i] = e;
return;
}
}
delete e;
}
};

View file

@ -0,0 +1,69 @@
/*
Author: bitluni 2019
License:
Creative Commons Attribution ShareAlike 4.0
https://creativecommons.org/licenses/by-sa/4.0/
For further details check out:
https://youtube.com/bitlunislab
https://github.com/bitluni
http://bitluni.net
*/
#pragma once
#include <stdlib.h>
#include "TriangleTree.h"
#include "../Tools/Log.h"
template<class Graphics>
class Engine3D
{
public:
typedef typename Graphics::Color Color;
TriangleTree *triangleBuffer;
TriangleTree *triangleRoot;
int trinagleBufferSize;
int triangleCount;
Engine3D(const int initialTrinagleBufferSize = 1)
{
trinagleBufferSize = initialTrinagleBufferSize;
triangleBuffer = (TriangleTree*)malloc(sizeof(TriangleTree) * trinagleBufferSize);
if(!triangleBuffer)
ERROR("Not enough memory for triangleBuffer");
triangleRoot = 0;
triangleCount = 0;
}
void enqueueTriangle(short *v0, short *v1, short *v2, Color color)
{
if (triangleCount >= trinagleBufferSize)
return;
TriangleTree &t = triangleBuffer[triangleCount++];
t.set(v0, v1, v2, color);
if (triangleRoot)
triangleRoot->add(&triangleRoot, t);
else
triangleRoot = &t;
}
void drawTriangleTree(Graphics &g, TriangleTree *t)
{
if (t->left)
drawTriangleTree(g, t->left);
g.triangle(t->v[0], t->v[1], t->v[2], t->color);
if (t->right)
drawTriangleTree(g, t->right);
}
virtual void begin()
{
triangleCount = 0;
triangleRoot = 0;
}
virtual void end(Graphics &g)
{
if (triangleRoot)
drawTriangleTree(g, triangleRoot);
}
};

View file

@ -0,0 +1,26 @@
/*
Author: bitluni 2019
License:
Creative Commons Attribution ShareAlike 4.0
https://creativecommons.org/licenses/by-sa/4.0/
For further details check out:
https://youtube.com/bitlunislab
https://github.com/bitluni
http://bitluni.net
*/
#pragma once
#include "Graphics.h"
#include "Sprites.h"
class Entity
{
public:
int x, y;
int vx, vy;
int life;
int faction;
Sprites *sprites;
virtual bool act(int dt);
virtual void draw() = 0;
};

View file

@ -0,0 +1,35 @@
/*
Author: bitluni 2019
License:
Creative Commons Attribution ShareAlike 4.0
https://creativecommons.org/licenses/by-sa/4.0/
For further details check out:
https://youtube.com/bitlunislab
https://github.com/bitluni
http://bitluni.net
*/
#pragma once
class Font
{
public:
const int firstChar;
const int charCount;
const unsigned char *pixels;
const int charWidth;
const int charHeight;
Font(int charWidth, int charHeight, const unsigned char *pixels, int firstChar = 32, int charCount = 96)
:firstChar(firstChar),
charCount(charCount),
pixels(pixels),
charWidth(charWidth),
charHeight(charHeight)
{
}
bool valid(char ch) const
{
return ch >= firstChar && ch < firstChar + charCount;
}
};

View file

@ -0,0 +1,698 @@
/*
Author: bitluni 2019
License:
Creative Commons Attribution ShareAlike 4.0
https://creativecommons.org/licenses/by-sa/4.0/
For further details check out:
https://youtube.com/bitlunislab
https://github.com/bitluni
http://bitluni.net
*/
#pragma once
#include <stdlib.h>
#include <math.h>
#include "Font.h"
#include "ImageDrawer.h"
template<typename Color>
class Graphics: public ImageDrawer
{
public:
int cursorX, cursorY, cursorBaseX;
long frontColor, backColor;
Font *font;
int frameBufferCount;
int currentFrameBuffer;
Color **frameBuffers[3];
Color **frontBuffer;
Color **backBuffer;
bool autoScroll;
int xres;
int yres;
virtual void dotFast(int x, int y, Color color) = 0;
virtual void dot(int x, int y, Color color) = 0;
virtual void dotAdd(int x, int y, Color color) = 0;
virtual void dotMix(int x, int y, Color color) = 0;
virtual Color get(int x, int y) = 0;
virtual Color** allocateFrameBuffer() = 0;
virtual Color** allocateFrameBuffer(int xres, int yres, Color value)
{
Color** frame = (Color **)malloc(yres * sizeof(Color *));
if(!frame)
ERROR("Not enough memory for frame buffer");
for (int y = 0; y < yres; y++)
{
frame[y] = (Color *)malloc(xres * sizeof(Color));
if(!frame[y])
ERROR("Not enough memory for frame buffer");
for (int x = 0; x < xres; x++)
frame[y][x] = value;
}
return frame;
}
virtual Color RGBA(int r, int g, int b, int a = 255) const = 0;
virtual int R(Color c) const = 0;
virtual int G(Color c) const = 0;
virtual int B(Color c) const = 0;
virtual int A(Color c) const = 0;
Color RGB(unsigned long rgb) const
{
return RGBA(rgb & 255, (rgb >> 8) & 255, (rgb >> 16) & 255);
}
Color RGBA(unsigned long rgba) const
{
return RGBA(rgba & 255, (rgba >> 8) & 255, (rgba >> 16) & 255, rgba >> 24);
}
Color RGB(int r, int g, int b) const
{
return RGBA(r, g, b);
}
void setFrameBufferCount(unsigned char i)
{
frameBufferCount = i > 3 ? 3 : i;
}
virtual void show(bool vSync = false)
{
if(!frameBufferCount)
return;
currentFrameBuffer = (currentFrameBuffer + 1) % frameBufferCount;
frontBuffer = frameBuffers[currentFrameBuffer];
backBuffer = frameBuffers[(currentFrameBuffer + frameBufferCount - 1) % frameBufferCount];
}
Graphics(int xres = 0, int yres = 0)
{
this->xres = xres;
this->yres = yres;
font = 0;
cursorX = cursorY = cursorBaseX = 0;
frontColor = -1;
backColor = 0;
frameBufferCount = 1;
for(int i = 0; i < 3; i++)
frameBuffers[i] = 0;
frontBuffer = 0;
backBuffer = 0;
autoScroll = true;
}
virtual bool allocateFrameBuffers()
{
if(yres <= 0 || xres <= 0)
return false;
for(int i = 0; i < frameBufferCount; i++)
frameBuffers[i] = allocateFrameBuffer();
currentFrameBuffer = 0;
show();
return true;
}
virtual void setResolution(int xres, int yres)
{
this->xres = xres;
this->yres = yres;
allocateFrameBuffers();
}
virtual float pixelAspect() const
{
return 1;
}
void setTextColor(long front, long back = 0)
{
frontColor = front;
backColor = back;
}
void setFont(Font &font)
{
this->font = &font;
}
void setCursor(int x, int y)
{
cursorX = cursorBaseX = x;
cursorY = y;
}
virtual void drawChar(int x, int y, int ch)
{
if (!font)
return;
if (!font->valid(ch))
return;
const unsigned char *pix = &font->pixels[font->charWidth * font->charHeight * (ch - font->firstChar)];
for (int py = 0; py < font->charHeight; py++)
for (int px = 0; px < font->charWidth; px++)
if (*(pix++))
dotMix(px + x, py + y, frontColor);
else
dotMix(px + x, py + y, backColor);
}
void print(const char ch)
{
if (!font)
return;
if (font->valid(ch))
drawChar(cursorX, cursorY, ch);
else
drawChar(cursorX, cursorY, ' ');
cursorX += font->charWidth;
if (cursorX + font->charWidth > xres)
{
cursorX = cursorBaseX;
cursorY += font->charHeight;
if(autoScroll && cursorY + font->charHeight > yres)
scroll(cursorY + font->charHeight - yres, backColor);
}
}
void println(const char ch)
{
print(ch);
print("\n");
}
void print(const char *str)
{
if (!font)
return;
while (*str)
{
if(*str == '\n')
{
cursorX = cursorBaseX;
cursorY += font->charHeight;
}
else
print(*str);
str++;
}
}
void println(const char *str)
{
print(str);
print("\n");
}
void print(long number, int base = 10, int minCharacters = 1)
{
if(minCharacters < 1)
minCharacters = 1;
bool sign = number < 0;
if (sign)
number = -number;
const char baseChars[] = "0123456789ABCDEF";
char temp[33];
temp[32] = 0;
int i = 31;
do
{
temp[i--] = baseChars[number % base];
number /= base;
} while (number > 0);
if (sign)
temp[i--] = '-';
for (; i > 31 - minCharacters; i--)
temp[i] = ' ';
print(&temp[i + 1]);
}
void print(unsigned long number, int base = 10, int minCharacters = 1)
{
if(minCharacters < 1)
minCharacters = 1;
const char baseChars[] = "0123456789ABCDEF";
char temp[33];
temp[32] = 0;
int i = 31;
do
{
temp[i--] = baseChars[number % base];
number /= base;
} while (number > 0);
for (; i > 31 - minCharacters; i--)
temp[i] = ' ';
print(&temp[i + 1]);
}
void println(long number, int base = 10, int minCharacters = 1)
{
print(number, base, minCharacters); print("\n");
}
void println(unsigned long number, int base = 10, int minCharacters = 1)
{
print(number, base, minCharacters); print("\n");
}
void print(int number, int base = 10, int minCharacters = 1)
{
print(long(number), base, minCharacters);
}
void println(int number, int base = 10, int minCharacters = 1)
{
println(long(number), base, minCharacters);
}
void print(unsigned int number, int base = 10, int minCharacters = 1)
{
print((unsigned long)(number), base, minCharacters);
}
void println(unsigned int number, int base = 10, int minCharacters = 1)
{
println((unsigned long)(number), base, minCharacters);
}
void print(short number, int base = 10, int minCharacters = 1)
{
print(long(number), base, minCharacters);
}
void println(short number, int base = 10, int minCharacters = 1)
{
println(long(number), base, minCharacters);
}
void print(unsigned short number, int base = 10, int minCharacters = 1)
{
print(long(number), base, minCharacters);
}
void println(unsigned short number, int base = 10, int minCharacters = 1)
{
println(long(number), base, minCharacters);
}
void print(unsigned char number, int base = 10, int minCharacters = 1)
{
print(long(number), base, minCharacters);
}
void println(unsigned char number, int base = 10, int minCharacters = 1)
{
println(long(number), base, minCharacters);
}
void println()
{
print("\n");
}
void print(double number, int fractionalDigits = 2, int minCharacters = 1)
{
long p = long(pow(10, fractionalDigits));
long long n = (double(number) * p + 0.5f);
print(long(n / p), 10, minCharacters - 1 - fractionalDigits);
if(fractionalDigits)
{
print(".");
for(int i = 0; i < fractionalDigits; i++)
{
p /= 10;
print(long(n / p) % 10);
}
}
}
void println(double number, int fractionalDigits = 2, int minCharacters = 1)
{
print(number, fractionalDigits, minCharacters);
print("\n");
}
virtual void clear(Color color = 0)
{
for (int y = 0; y < yres; y++)
for (int x = 0; x < xres; x++)
dotFast(x, y, color);
}
virtual void xLine(int x0, int x1, int y, Color color)
{
if (y < 0 || y >= yres)
return;
if (x0 > x1)
{
int xb = x0;
x0 = x1;
x1 = xb;
}
if (x0 < 0)
x0 = 0;
if (x1 > xres)
x1 = xres;
for (int x = x0; x < x1; x++)
dotFast(x, y, color);
}
void triangle(short *v0, short *v1, short *v2, Color color)
{
short *v[3] = {v0, v1, v2};
if (v[1][1] < v[0][1])
{
short *vb = v[0];
v[0] = v[1];
v[1] = vb;
}
if (v[2][1] < v[1][1])
{
short *vb = v[1];
v[1] = v[2];
v[2] = vb;
}
if (v[1][1] < v[0][1])
{
short *vb = v[0];
v[0] = v[1];
v[1] = vb;
}
int y = v[0][1];
int xac = v[0][0] << 16;
int xab = v[0][0] << 16;
int xbc = v[1][0] << 16;
int xaci = 0;
int xabi = 0;
int xbci = 0;
if (v[1][1] != v[0][1])
xabi = ((v[1][0] - v[0][0]) << 16) / (v[1][1] - v[0][1]);
if (v[2][1] != v[0][1])
xaci = ((v[2][0] - v[0][0]) << 16) / (v[2][1] - v[0][1]);
if (v[2][1] != v[1][1])
xbci = ((v[2][0] - v[1][0]) << 16) / (v[2][1] - v[1][1]);
for (; y < v[1][1] && y < yres; y++)
{
if (y >= 0)
xLine(xab >> 16, xac >> 16, y, color);
xab += xabi;
xac += xaci;
}
for (; y < v[2][1] && y < yres; y++)
{
if (y >= 0)
xLine(xbc >> 16, xac >> 16, y, color);
xbc += xbci;
xac += xaci;
}
}
void line(int x1, int y1, int x2, int y2, Color color)
{
int x, y, xe, ye;
int dx = x2 - x1;
int dy = y2 - y1;
int dx1 = labs(dx);
int dy1 = labs(dy);
int px = 2 * dy1 - dx1;
int py = 2 * dx1 - dy1;
if (dy1 <= dx1)
{
if (dx >= 0)
{
x = x1;
y = y1;
xe = x2;
}
else
{
x = x2;
y = y2;
xe = x1;
}
dot(x, y, color);
for (int i = 0; x < xe; i++)
{
x = x + 1;
if (px < 0)
{
px = px + 2 * dy1;
}
else
{
if ((dx < 0 && dy < 0) || (dx > 0 && dy > 0))
{
y = y + 1;
}
else
{
y = y - 1;
}
px = px + 2 * (dy1 - dx1);
}
dot(x, y, color);
}
}
else
{
if (dy >= 0)
{
x = x1;
y = y1;
ye = y2;
}
else
{
x = x2;
y = y2;
ye = y1;
}
dot(x, y, color);
for (int i = 0; y < ye; i++)
{
y = y + 1;
if (py <= 0)
{
py = py + 2 * dx1;
}
else
{
if ((dx < 0 && dy < 0) || (dx > 0 && dy > 0))
{
x = x + 1;
}
else
{
x = x - 1;
}
py = py + 2 * (dx1 - dy1);
}
dot(x, y, color);
}
}
}
void fillRect(int x, int y, int w, int h, Color color)
{
if (x < 0)
{
w += x;
x = 0;
}
if (y < 0)
{
h += y;
y = 0;
}
if (x + w > xres)
w = xres - x;
if (y + h > yres)
h = yres - y;
for (int j = y; j < y + h; j++)
for (int i = x; i < x + w; i++)
dotFast(i, j, color);
}
void rect(int x, int y, int w, int h, Color color)
{
fillRect(x, y, w, 1, color);
fillRect(x, y, 1, h, color);
fillRect(x, y + h - 1, w, 1, color);
fillRect(x + w - 1, y, 1, h, color);
}
void circle(int x, int y, int r, Color color)
{
int oxr = r;
for(int i = 0; i < r + 1; i++)
{
int xr = (int)sqrt(r * r - i * i);
xLine(x - oxr, x - xr + 1, y + i, color);
xLine(x + xr, x + oxr + 1, y + i, color);
if(i)
{
xLine(x - oxr, x - xr + 1, y - i, color);
xLine(x + xr, x + oxr + 1, y - i, color);
}
oxr = xr;
}
}
void fillCircle(int x, int y, int r, Color color)
{
for(int i = 0; i < r + 1; i++)
{
int xr = (int)sqrt(r * r - i * i);
xLine(x - xr, x + xr + 1, y + i, color);
if(i)
xLine(x - xr, x + xr + 1, y - i, color);
}
}
void ellipse(int x, int y, int rx, int ry, Color color)
{
if(ry == 0)
return;
int oxr = rx;
float f = float(rx) / ry;
f *= f;
for(int i = 0; i < ry + 1; i++)
{
float s = rx * rx - i * i * f;
int xr = (int)sqrt(s <= 0 ? 0 : s);
xLine(x - oxr, x - xr + 1, y + i, color);
xLine(x + xr, x + oxr + 1, y + i, color);
if(i)
{
xLine(x - oxr, x - xr + 1, y - i, color);
xLine(x + xr, x + oxr + 1, y - i, color);
}
oxr = xr;
}
}
void fillEllipse(int x, int y, int rx, int ry, Color color)
{
if(ry == 0)
return;
float f = float(rx) / ry;
f *= f;
for(int i = 0; i < ry + 1; i++)
{
float s = rx * rx - i * i * f;
int xr = (int)sqrt(s <= 0 ? 0 : s);
xLine(x - xr, x + xr + 1, y + i, color);
if(i)
xLine(x - xr, x + xr + 1, y - i, color);
}
}
virtual void scroll(int dy, Color color)
{
if(dy > 0)
{
for(int d = 0; d < dy; d++)
{
Color *l = backBuffer[0];
for(int i = 0; i < yres - 1; i++)
{
backBuffer[i] = backBuffer[i + 1];
}
backBuffer[yres - 1] = l;
xLine(0, xres, yres - 1, color);
}
}
else
{
for(int d = 0; d < -dy; d++)
{
Color *l = backBuffer[yres - 1];
for(int i = 1; i < yres; i++)
{
backBuffer[i] = backBuffer[i - 1];
}
backBuffer[0] = l;
xLine(0, xres, 0, color);
}
}
cursorY -= dy;
}
virtual Color R5G5B4A2ToColor(unsigned short c)
{
int r = (((c << 1) & 0x3e) * 255 + 1) / 0x3e;
int g = (((c >> 4) & 0x3e) * 255 + 1) / 0x3e;
int b = (((c >> 9) & 0x1e) * 255 + 1) / 0x1e;
int a = (((c >> 13) & 6) * 255 + 1) / 6;
return RGBA(r, g, b, a);
}
virtual Color R2G2B2A2ToColor(unsigned char c)
{
int r = ((int(c) & 3) * 255 + 1) / 3;
int g = (((int(c) >> 2) & 3) * 255 + 1) / 3;
int b = (((int(c) >> 4) & 3) * 255 + 1) / 3;
int a = (((int(c) >> 6) & 3) * 255 + 1) / 3;
return RGBA(r, g, b, a);
}
virtual void imageR5G5B4A2(Image &image, int x, int y, int srcX, int srcY, int srcXres, int srcYres)
{
for (int py = 0; py < srcYres; py++)
{
int i = srcX + (py + srcY) * image.xres;
for (int px = 0; px < srcXres; px++)
dot(px + x, py + y, R5G5B4A2ToColor(((unsigned short*)image.pixels)[i++]));
}
}
virtual void imageAddR5G5B4A2(Image &image, int x, int y, int srcX, int srcY, int srcXres, int srcYres)
{
for (int py = 0; py < srcYres; py++)
{
int i = srcX + (py + srcY) * image.xres;
for (int px = 0; px < srcXres; px++)
dotAdd(px + x, py + y, R5G5B4A2ToColor(((unsigned short*)image.pixels)[i++]));
}
}
virtual void imageMixR5G5B4A2(Image &image, int x, int y, int srcX, int srcY, int srcXres, int srcYres)
{
for (int py = 0; py < srcYres; py++)
{
int i = srcX + (py + srcY) * image.xres;
for (int px = 0; px < srcXres; px++)
dotMix(px + x, py + y, R5G5B4A2ToColor(((unsigned short*)image.pixels)[i++]));
}
}
virtual void imageR2G2B2A2(Image &image, int x, int y, int srcX, int srcY, int srcXres, int srcYres)
{
for (int py = 0; py < srcYres; py++)
{
int i = srcX + (py + srcY) * image.xres;
for (int px = 0; px < srcXres; px++)
dot(px + x, py + y, R2G2B2A2ToColor(((unsigned char*)image.pixels)[i++]));
}
}
virtual void imageAddR2G2B2A2(Image &image, int x, int y, int srcX, int srcY, int srcXres, int srcYres)
{
for (int py = 0; py < srcYres; py++)
{
int i = srcX + (py + srcY) * image.xres;
for (int px = 0; px < srcXres; px++)
dotAdd(px + x, py + y, R2G2B2A2ToColor(((unsigned char*)image.pixels)[i++]));
}
}
virtual void imageMixR2G2B2A2(Image &image, int x, int y, int srcX, int srcY, int srcXres, int srcYres)
{
for (int py = 0; py < srcYres; py++)
{
int i = srcX + (py + srcY) * image.xres;
for (int px = 0; px < srcXres; px++)
dotMix(px + x, py + y, R2G2B2A2ToColor(((unsigned char*)image.pixels)[i++]));
}
}
};

View file

@ -0,0 +1,110 @@
/*
Author: bitluni 2019
License:
Creative Commons Attribution ShareAlike 4.0
https://creativecommons.org/licenses/by-sa/4.0/
For further details check out:
https://youtube.com/bitlunislab
https://github.com/bitluni
http://bitluni.net
*/
#pragma once
#include "Graphics.h"
class GraphicsR1G1B1A1: public Graphics<unsigned char>
{
public:
typedef unsigned char Color;
GraphicsR1G1B1A1()
{
frontColor = 0xf;
}
virtual int R(Color c) const
{
return (c & 1) * 255;
}
virtual int G(Color c) const
{
return (c & 2) ? 255 : 0;
}
virtual int B(Color c) const
{
return (c & 4) ? 255 : 0;
}
virtual int A(Color c) const
{
return (c & 8) ? 255 : 0;
}
virtual Color RGBA(int r, int g, int b, int a = 255) const
{
return ((r >> 7) & 1) | ((g >> 6) & 2) | ((b >> 5) & 4) | ((a >> 4) & 8);
}
virtual void dotFast(int x, int y, Color color)
{
if(x & 1)
backBuffer[y][x >> 1] = (backBuffer[y][x >> 1] & 0xf) | (color << 4);
else
backBuffer[y][x >> 1] = (backBuffer[y][x >> 1] & 0xf0) | (color & 0xf);
}
virtual void dot(int x, int y, Color color)
{
if ((unsigned int)x < xres && (unsigned int)y < yres)
{
if(x & 1)
backBuffer[y][x >> 1] = (backBuffer[y][x >> 1] & 0xf) | (color << 4);
else
backBuffer[y][x >> 1] = (backBuffer[y][x >> 1] & 0xf0) | (color & 0xf);
}
}
virtual void dotAdd(int x, int y, Color color)
{
if ((unsigned int)x < xres && (unsigned int)y < yres)
{
if(x & 1)
backBuffer[y][x >> 1] = backBuffer[y][x >> 1] | (color << 4);
else
backBuffer[y][x >> 1] = backBuffer[y][x >> 1] | (color & 0xf);
}
}
virtual void dotMix(int x, int y, Color color)
{
if ((unsigned int)x < xres && (unsigned int)y < yres && (color & 8) != 0)
{
if(x & 1)
backBuffer[y][x >> 1] = (backBuffer[y][x >> 1] & 0xf) | (color << 4);
else
backBuffer[y][x >> 1] = (backBuffer[y][x >> 1] & 0xf0) | (color & 0xf);
}
}
virtual Color get(int x, int y)
{
if ((unsigned int)x < xres && (unsigned int)y < yres)
{
if(x & 1)
return backBuffer[y][x >> 1] = backBuffer[y][x >> 1] >> 4;
else
return backBuffer[y][x >> 1] = backBuffer[y][x >> 1] & 0xf;
}
return 0;
}
virtual void clear(Color color = 0)
{
for (int y = 0; y < this->yres; y++)
for (int x = 0; x < this->xres / 2; x++)
this->backBuffer[y][x] = color | (color << 4);
}
virtual Color** allocateFrameBuffer()
{
return Graphics<Color>::allocateFrameBuffer(xres / 2, yres, (Color)0);
}
};

View file

@ -0,0 +1,91 @@
/*
Author: bitluni 2019
License:
Creative Commons Attribution ShareAlike 4.0
https://creativecommons.org/licenses/by-sa/4.0/
For further details check out:
https://youtube.com/bitlunislab
https://github.com/bitluni
http://bitluni.net
*/
#pragma once
#include "Graphics.h"
class GraphicsR1G1B1A1X2S2Swapped: public Graphics<unsigned char>
{
public:
typedef unsigned char Color;
static const Color RGBAXMask = 0x3f;
Color SBits;
GraphicsR1G1B1A1X2S2Swapped()
{
SBits = 0xc0;
frontColor = 0xf;
}
virtual int R(Color c) const
{
return (c & 1) * 255;
}
virtual int G(Color c) const
{
return (c & 2) ? 255 : 0;
}
virtual int B(Color c) const
{
return (c & 4) ? 255 : 0;
}
virtual int A(Color c) const
{
return (c & 8) ? 255 : 0;
}
virtual Color RGBA(int r, int g, int b, int a = 255) const
{
return ((r >> 7) & 1) | ((g >> 6) & 2) | ((b >> 5) & 4) | ((a >> 4) & 8);
}
virtual void dotFast(int x, int y, Color color)
{
backBuffer[y][x^2] = (color & RGBAXMask) | SBits;
}
virtual void dot(int x, int y, Color color)
{
if ((unsigned int)x < xres && (unsigned int)y < yres)
backBuffer[y][x^2] = (color & RGBAXMask) | SBits;
}
virtual void dotAdd(int x, int y, Color color)
{
if ((unsigned int)x < xres && (unsigned int)y < yres)
backBuffer[y][x^2] = backBuffer[y][x^2] | (color & RGBAXMask);
}
virtual void dotMix(int x, int y, Color color)
{
if ((unsigned int)x < xres && (unsigned int)y < yres && (color & 8) != 0)
backBuffer[y][x^2] = (color & RGBAXMask) | SBits;
}
virtual Color get(int x, int y)
{
if ((unsigned int)x < xres && (unsigned int)y < yres)
return backBuffer[y][x^2] & RGBAXMask;
return 0;
}
virtual void clear(Color color = 0)
{
for (int y = 0; y < this->yres; y++)
for (int x = 0; x < this->xres; x++)
backBuffer[y][x^2] = (color & RGBAXMask) | SBits;
}
virtual Color** allocateFrameBuffer()
{
return Graphics<Color>::allocateFrameBuffer(xres, yres, (Color)SBits);
}
};

View file

@ -0,0 +1,142 @@
/*
Author: bitluni 2019
License:
Creative Commons Attribution ShareAlike 4.0
https://creativecommons.org/licenses/by-sa/4.0/
For further details check out:
https://youtube.com/bitlunislab
https://github.com/bitluni
http://bitluni.net
*/
#pragma once
#include "Graphics.h"
class GraphicsR2G2B2A2: public Graphics<unsigned char>
{
public:
typedef unsigned char Color;
static const Color RGBAXMask = 0x3f;
Color SBits;
GraphicsR2G2B2A2()
{
SBits = 0xc0;
frontColor = 0xff;
}
virtual int R(Color c) const
{
return (((int)c & 3) * 255 + 1) / 3;
}
virtual int G(Color c) const
{
return (((int)(c >> 2) & 3) * 255 + 1) / 3;
}
virtual int B(Color c) const
{
return (((int)(c >> 4) & 3) * 255 + 1) / 3;
}
virtual int A(Color c) const
{
return (((int)(c >> 6) & 3) * 255 + 1) / 3;
}
virtual Color RGBA(int r, int g, int b, int a = 255) const
{
return ((r >> 6) & 0b11) | ((g >> 4) & 0b1100) | ((b >> 2) & 0b110000) | (a & 0b11000000);
}
virtual void dotFast(int x, int y, Color color)
{
backBuffer[y][x] = (color & RGBAXMask) | SBits;
}
virtual void dot(int x, int y, Color color)
{
if ((unsigned int)x < xres && (unsigned int)y < yres)
backBuffer[y][x] = (color & RGBAXMask) | SBits;
}
virtual void dotAdd(int x, int y, Color color)
{
if ((unsigned int)x < xres && (unsigned int)y < yres)
{
int c0 = backBuffer[y][x^2];
int c1 = color;
int r = (c0 & 0b11) + (c1 & 0b11);
if(r > 0b11) r = 0b11;
int g = (c0 & 0b1100) + (c1 & 0b1100);
if(g > 0b1100) g = 0b1100;
int b = (c0 & 0b110000) + (c1 & 0b110000);
if(b > 0b110000) b = 0b110000;
backBuffer[y][x] = r | (g & 0b1100) | (b & 0b110000) | SBits;
}
}
virtual void dotMix(int x, int y, Color color)
{
if ((unsigned int)x < xres && (unsigned int)y < yres && (color >> 6) != 0)
{
unsigned int ai = (3 - ((int)color >> 6)) * (65536 / 3);
unsigned int a = 65536 - ai;
unsigned int co = backBuffer[y][x^2];
unsigned int ro = (co & 0b11) * ai;
unsigned int go = (co & 0b1100) * ai;
unsigned int bo = (co & 0b110000) * ai;
unsigned int r = (color & 0b11) * a + ro;
unsigned int g = ((color & 0b1100) * a + go) & 0b11000000000000000000;
unsigned int b = ((color & 0b110000) * a + bo) & 0b1100000000000000000000;
backBuffer[y][x] = ((r | g | b) >> 16) | SBits;
}
}
virtual Color get(int x, int y)
{
if ((unsigned int)x < xres && (unsigned int)y < yres)
return backBuffer[y][x] & RGBAXMask;
return 0;
}
virtual void clear(Color color = 0)
{
for (int y = 0; y < this->yres; y++)
for (int x = 0; x < this->xres; x++)
backBuffer[y][x] = (color & RGBAXMask) | SBits;
}
virtual void imageR2G2B2A2(Image &image, int x, int y, int srcX, int srcY, int srcXres, int srcYres)
{
for (int py = 0; py < srcYres; py++)
{
int i = srcX + (py + srcY) * image.xres;
for (int px = 0; px < srcXres; px++)
dot(px + x, py + y, ((unsigned char*)image.pixels)[i++]);
}
}
virtual void imageAddR2G2B2A2(Image &image, int x, int y, int srcX, int srcY, int srcXres, int srcYres)
{
for (int py = 0; py < srcYres; py++)
{
int i = srcX + (py + srcY) * image.xres;
for (int px = 0; px < srcXres; px++)
dotAdd(px + x, py + y, ((unsigned char*)image.pixels)[i++]);
}
}
virtual void imageMixR2G2B2A2(Image &image, int x, int y, int srcX, int srcY, int srcXres, int srcYres)
{
for (int py = 0; py < srcYres; py++)
{
int i = srcX + (py + srcY) * image.xres;
for (int px = 0; px < srcXres; px++)
dotMix(px + x, py + y, ((unsigned char*)image.pixels)[i++]);
}
}
virtual Color** allocateFrameBuffer()
{
return Graphics<Color>::allocateFrameBuffer(xres, yres, (Color)SBits);
}
};

View file

@ -0,0 +1,142 @@
/*
Author: bitluni 2019
License:
Creative Commons Attribution ShareAlike 4.0
https://creativecommons.org/licenses/by-sa/4.0/
For further details check out:
https://youtube.com/bitlunislab
https://github.com/bitluni
http://bitluni.net
*/
#pragma once
#include "Graphics.h"
class GraphicsR2G2B2S2Swapped: public Graphics<unsigned char>
{
public:
typedef unsigned char Color;
static const Color RGBAXMask = 0x3f;
Color SBits;
GraphicsR2G2B2S2Swapped()
{
SBits = 0xc0;
frontColor = 0xff;
}
virtual int R(Color c) const
{
return (((int)c & 3) * 255 + 1) / 3;
}
virtual int G(Color c) const
{
return (((int)(c >> 2) & 3) * 255 + 1) / 3;
}
virtual int B(Color c) const
{
return (((int)(c >> 4) & 3) * 255 + 1) / 3;
}
virtual int A(Color c) const
{
return (((int)(c >> 6) & 3) * 255 + 1) / 3;
}
virtual Color RGBA(int r, int g, int b, int a = 255) const
{
return ((r >> 6) & 0b11) | ((g >> 4) & 0b1100) | ((b >> 2) & 0b110000) | (a & 0b11000000);
}
virtual void dotFast(int x, int y, Color color)
{
backBuffer[y][x^2] = (color & RGBAXMask) | SBits;
}
virtual void dot(int x, int y, Color color)
{
if ((unsigned int)x < xres && (unsigned int)y < yres)
backBuffer[y][x^2] = (color & RGBAXMask) | SBits;
}
virtual void dotAdd(int x, int y, Color color)
{
if ((unsigned int)x < xres && (unsigned int)y < yres)
{
int c0 = backBuffer[y][x^2];
int c1 = color;
int r = (c0 & 0b11) + (c1 & 0b11);
if(r > 0b11) r = 0b11;
int g = (c0 & 0b1100) + (c1 & 0b1100);
if(g > 0b1100) g = 0b1100;
int b = (c0 & 0b110000) + (c1 & 0b110000);
if(b > 0b110000) b = 0b110000;
backBuffer[y][x^2] = r | (g & 0b1100) | (b & 0b110000) | SBits;
}
}
virtual void dotMix(int x, int y, Color color)
{
if ((unsigned int)x < xres && (unsigned int)y < yres && (color >> 6) != 0)
{
unsigned int ai = (3 - ((int)color >> 6)) * (65536 / 3);
unsigned int a = 65536 - ai;
unsigned int co = backBuffer[y][x^2];
unsigned int ro = (co & 0b11) * ai;
unsigned int go = (co & 0b1100) * ai;
unsigned int bo = (co & 0b110000) * ai;
unsigned int r = (color & 0b11) * a + ro;
unsigned int g = ((color & 0b1100) * a + go) & 0b11000000000000000000;
unsigned int b = ((color & 0b110000) * a + bo) & 0b1100000000000000000000;
backBuffer[y][x^2] = ((r | g | b) >> 16) | SBits;
}
}
virtual Color get(int x, int y)
{
if ((unsigned int)x < xres && (unsigned int)y < yres)
return backBuffer[y][x^2] & RGBAXMask;
return 0;
}
virtual void clear(Color color = 0)
{
for (int y = 0; y < this->yres; y++)
for (int x = 0; x < this->xres; x++)
backBuffer[y][x^2] = (color & RGBAXMask) | SBits;
}
virtual void imageR2G2B2A2(Image &image, int x, int y, int srcX, int srcY, int srcXres, int srcYres)
{
for (int py = 0; py < srcYres; py++)
{
int i = srcX + (py + srcY) * image.xres;
for (int px = 0; px < srcXres; px++)
dot(px + x, py + y, ((unsigned char*)image.pixels)[i++]);
}
}
virtual void imageAddR2G2B2A2(Image &image, int x, int y, int srcX, int srcY, int srcXres, int srcYres)
{
for (int py = 0; py < srcYres; py++)
{
int i = srcX + (py + srcY) * image.xres;
for (int px = 0; px < srcXres; px++)
dotAdd(px + x, py + y, ((unsigned char*)image.pixels)[i++]);
}
}
virtual void imageMixR2G2B2A2(Image &image, int x, int y, int srcX, int srcY, int srcXres, int srcYres)
{
for (int py = 0; py < srcYres; py++)
{
int i = srcX + (py + srcY) * image.xres;
for (int px = 0; px < srcXres; px++)
dotMix(px + x, py + y, ((unsigned char*)image.pixels)[i++]);
}
}
virtual Color** allocateFrameBuffer()
{
return Graphics<Color>::allocateFrameBuffer(xres, yres, (Color)SBits);
}
};

View file

@ -0,0 +1,108 @@
/*
Author: bitluni 2019
License:
Creative Commons Attribution ShareAlike 4.0
https://creativecommons.org/licenses/by-sa/4.0/
For further details check out:
https://youtube.com/bitlunislab
https://github.com/bitluni
http://bitluni.net
*/
#pragma once
#include "Graphics.h"
class GraphicsR5G5B4A2: public Graphics<unsigned short>
{
public:
typedef unsigned short Color;
GraphicsR5G5B4A2()
{
frontColor = 0xffff;
}
virtual int R(Color c) const
{
return (((c << 1) & 0x3e) * 255 + 1) / 0x3e;
}
virtual int G(Color c) const
{
return (((c >> 4) & 0x3e) * 255 + 1) / 0x3e;
}
virtual int B(Color c) const
{
return (((c >> 9) & 0x1e) * 255 + 1) / 0x1e;
}
virtual int A(Color c) const
{
return (((c >> 13) & 6) * 255 + 1) / 6;
}
virtual Color RGBA(int r, int g, int b, int a = 255) const
{
return ((r >> 3) & 0b11111) | ((g << 2) & 0b1111100000) | ((b << 6) & 0b11110000000000) | ((a << 8) & 0xc000);
}
virtual void dotFast(int x, int y, Color color)
{
backBuffer[y][x] = color;
}
virtual void dot(int x, int y, Color color)
{
if ((unsigned int)x < xres && (unsigned int)y < yres)
backBuffer[y][x] = color;
}
virtual void dotAdd(int x, int y, Color color)
{
if ((unsigned int)x < xres && (unsigned int)y < yres)
{
int c0 = backBuffer[y][x];
int c1 = color;
int r = (c0 & 0b11111) + (c1 & 0b11111);
if(r > 0b11111) r = 0b11111;
int g = (c0 & 0b1111100000) + (c1 & 0b1111100000);
if(g > 0b1111100000) g = 0b1111100000;
int b = (c0 & 0b11110000000000) + (c1 & 0b11110000000000);
if(b > 0b11110000000000) b = 0b11110000000000;
backBuffer[y][x] = r | (g & 0b1111100000) | (b & 0b11110000000000);
}
}
virtual void dotMix(int x, int y, Color color)
{
if ((unsigned int)x < xres && (unsigned int)y < yres && (color >> 14) != 0)
{
unsigned int ai = (3 - (color >> 14)) * (65536 / 3);
unsigned int a = 65536 - ai;
unsigned int co = backBuffer[y][x];
unsigned int ro = (co & 0b11111) * ai;
unsigned int go = (co & 0b1111100000) * ai;
unsigned int bo = (co & 0b11110000000000) * ai;
unsigned int r = (color & 0b11111) * a + ro;
unsigned int g = ((color & 0b1111100000) * a + go) & 0b11111000000000000000000000;
unsigned int b = ((color & 0b11110000000000) * a + bo) & 0b111100000000000000000000000000;
backBuffer[y][x] = (r | g | b) >> 16;
}
}
virtual Color get(int x, int y)
{
if ((unsigned int)x < xres && (unsigned int)y < yres)
return backBuffer[y][x];
return 0;
}
virtual void clear(Color color = 0)
{
for (int y = 0; y < this->yres; y++)
for (int x = 0; x < this->xres; x++)
backBuffer[y][x] = color;
}
virtual Color** allocateFrameBuffer()
{
return Graphics<Color>::allocateFrameBuffer(xres, yres, (Color)0);
}
};

View file

@ -0,0 +1,112 @@
/*
Author: bitluni 2019
License:
Creative Commons Attribution ShareAlike 4.0
https://creativecommons.org/licenses/by-sa/4.0/
For further details check out:
https://youtube.com/bitlunislab
https://github.com/bitluni
http://bitluni.net
*/
#pragma once
#include "Graphics.h"
class GraphicsR5G5B4S2Swapped: public Graphics<unsigned short>
{
public:
typedef unsigned short Color;
static const Color RGBMask = 0x3fff;
Color SBits;
GraphicsR5G5B4S2Swapped()
{
SBits = 0xc000;
frontColor = 0xffff;
}
virtual int R(Color c) const
{
return (((c << 1) & 0x3e) * 255 + 1) / 0x3e;
}
virtual int G(Color c) const
{
return (((c >> 4) & 0x3e) * 255 + 1) / 0x3e;
}
virtual int B(Color c) const
{
return (((c >> 9) & 0x1e) * 255 + 1) / 0x1e;
}
virtual int A(Color c) const
{
return (((c >> 13) & 6) * 255 + 1) / 6;
}
virtual Color RGBA(int r, int g, int b, int a = 255) const
{
return ((r >> 3) & 0b11111) | ((g << 2) & 0b1111100000) | ((b << 6) & 0b11110000000000) | ((a << 8) & 0xc000);
}
virtual void dotFast(int x, int y, Color color)
{
backBuffer[y][x^1] = (color & RGBMask) | SBits;
}
virtual void dot(int x, int y, Color color)
{
if ((unsigned int)x < xres && (unsigned int)y < yres)
backBuffer[y][x^1] = (color & RGBMask) | SBits;
}
virtual void dotAdd(int x, int y, Color color)
{
if ((unsigned int)x < xres && (unsigned int)y < yres)
{
int c0 = backBuffer[y][x^1];
int c1 = color;
int r = (c0 & 0b11111) + (c1 & 0b11111);
if(r > 0b11111) r = 0b11111;
int g = (c0 & 0b1111100000) + (c1 & 0b1111100000);
if(g > 0b1111100000) g = 0b1111100000;
int b = (c0 & 0b11110000000000) + (c1 & 0b11110000000000);
if(b > 0b11110000000000) b = 0b11110000000000;
backBuffer[y][x^1] = r | (g & 0b1111100000) | (b & 0b11110000000000) | SBits;
}
}
virtual void dotMix(int x, int y, Color color)
{
if ((unsigned int)x < xres && (unsigned int)y < yres && (color >> 14) != 0)
{
unsigned int ai = (3 - (color >> 14)) * (65536 / 3);
unsigned int a = 65536 - ai;
unsigned int co = backBuffer[y][x^1];
unsigned int ro = (co & 0b11111) * ai;
unsigned int go = (co & 0b1111100000) * ai;
unsigned int bo = (co & 0b11110000000000) * ai;
unsigned int r = (color & 0b11111) * a + ro;
unsigned int g = ((color & 0b1111100000) * a + go) & 0b11111000000000000000000000;
unsigned int b = ((color & 0b11110000000000) * a + bo) & 0b111100000000000000000000000000;
backBuffer[y][x^1] = ((r | g | b) >> 16) | SBits;
}
}
virtual Color get(int x, int y)
{
if ((unsigned int)x < xres && (unsigned int)y < yres)
return backBuffer[y][x^1] & RGBMask;
return 0;
}
virtual void clear(Color color = 0)
{
for (int y = 0; y < this->yres; y++)
for (int x = 0; x < this->xres; x++)
backBuffer[y][x^1] = (color & RGBMask) | SBits;
}
virtual Color** allocateFrameBuffer()
{
return Graphics<Color>::allocateFrameBuffer(xres, yres, (Color)SBits);
}
};

View file

@ -0,0 +1,52 @@
/*
Author: bitluni 2019
License:
Creative Commons Attribution ShareAlike 4.0
https://creativecommons.org/licenses/by-sa/4.0/
For further details check out:
https://youtube.com/bitlunislab
https://github.com/bitluni
http://bitluni.net
*/
#pragma once
class Image
{
public:
enum PixelFormat
{
R8G8B8A8 = 1,
R1G1B1A1 = 2,
R2G2B2A2 = 3,
R4G4B4A4 = 4,
R5G5B5A1 = 5,
R5G5B4A2 = 6
};
int xres;
int yres;
PixelFormat pixelFormat;
const void *pixels;
void init(int xres, int yres, const void *pixels, PixelFormat pixelFormat)
{
this->xres = xres;
this->yres = yres;
this->pixels = pixels;
this->pixelFormat = pixelFormat;
}
Image(){};
Image(int xres, int yres, const void *pixels, PixelFormat pixelFormat)
{
init(xres, yres, pixels, pixelFormat);
}
/*
Color get(int x, int y) const
{
return pixels[y * xres + x];
}*/
};

View file

@ -0,0 +1,113 @@
/*
Author: bitluni 2019
License:
Creative Commons Attribution ShareAlike 4.0
https://creativecommons.org/licenses/by-sa/4.0/
For further details check out:
https://youtube.com/bitlunislab
https://github.com/bitluni
http://bitluni.net
*/
#pragma once
#include "Image.h"
class ImageDrawer
{
public:
virtual void imageR5G5B4A2(Image &image, int x, int y, int srcX, int srcY, int srcXres, int srcYres) = 0;
virtual void imageAddR5G5B4A2(Image &image, int x, int y, int srcX, int srcY, int srcXres, int srcYres) = 0;
virtual void imageMixR5G5B4A2(Image &image, int x, int y, int srcX, int srcY, int srcXres, int srcYres) = 0;
virtual void imageR2G2B2A2(Image &image, int x, int y, int srcX, int srcY, int srcXres, int srcYres) = 0;
virtual void imageAddR2G2B2A2(Image &image, int x, int y, int srcX, int srcY, int srcXres, int srcYres) = 0;
virtual void imageMixR2G2B2A2(Image &image, int x, int y, int srcX, int srcY, int srcXres, int srcYres) = 0;
void image(Image &image, int x, int y, int srcX, int srcY, int srcXres, int srcYres)
{
switch(image.pixelFormat)
{
case Image::R5G5B4A2:
imageR5G5B4A2(image, x, y, srcX, srcY, srcXres, srcYres);
break;
case Image::R2G2B2A2:
imageR2G2B2A2(image, x, y, srcX, srcY, srcXres, srcYres);
break;
default:
break;
}
}
void imageAdd(Image &image, int x, int y, int srcX, int srcY, int srcXres, int srcYres)
{
switch(image.pixelFormat)
{
case Image::R5G5B4A2:
imageAddR5G5B4A2(image, x, y, srcX, srcY, srcXres, srcYres);
break;
case Image::R2G2B2A2:
imageAddR2G2B2A2(image, x, y, srcX, srcY, srcXres, srcYres);
break;
default:
break;
}
}
void imageMix(Image &image, int x, int y, int srcX, int srcY, int srcXres, int srcYres)
{
switch(image.pixelFormat)
{
case Image::R5G5B4A2:
imageMixR5G5B4A2(image, x, y, srcX, srcY, srcXres, srcYres);
break;
case Image::R2G2B2A2:
imageMixR2G2B2A2(image, x, y, srcX, srcY, srcXres, srcYres);
break;
default:
break;
}
}
void image(Image &image, int x, int y)
{
switch(image.pixelFormat)
{
case Image::R5G5B4A2:
imageR5G5B4A2(image, x, y, 0, 0, image.xres, image.yres);
break;
case Image::R2G2B2A2:
imageR2G2B2A2(image, x, y, 0, 0, image.xres, image.yres);
break;
default:
break;
}
}
void imageAdd(Image &image, int x, int y)
{
switch(image.pixelFormat)
{
case Image::R5G5B4A2:
imageAddR5G5B4A2(image, x, y, 0, 0, image.xres, image.yres);
break;
case Image::R2G2B2A2:
imageAddR2G2B2A2(image, x, y, 0, 0, image.xres, image.yres);
break;
default:
break;
}
}
void imageMix(Image &image, int x, int y)
{
switch(image.pixelFormat)
{
case Image::R5G5B4A2:
imageMixR5G5B4A2(image, x, y, 0, 0, image.xres, image.yres);
break;
case Image::R2G2B2A2:
imageMixR2G2B2A2(image, x, y, 0, 0, image.xres, image.yres);
break;
default:
break;
}
}
};

View file

@ -0,0 +1,137 @@
/*
Author: bitluni 2019
License:
Creative Commons Attribution ShareAlike 4.0
https://creativecommons.org/licenses/by-sa/4.0/
For further details check out:
https://youtube.com/bitlunislab
https://github.com/bitluni
http://bitluni.net
*/
#pragma once
#include "../Math/Matrix.h"
#include "Engine3D.h"
#include "../Tools/Log.h"
template <typename Graphics>
class Mesh
{
public:
typedef typename Graphics::Color Color;
int vertexCount;
int edgeCount;
int triangleCount;
const float (*vertices)[3];
const unsigned short (*edges)[2];
const unsigned short (*triangles)[3];
const float (*triangleNormals)[3];
short (*tvertices)[3];
signed char (*tTriNormals)[3];
typedef Color (*triangleShader)(int trinangleNo, short *v0, short *v1, short *v2, const signed char *normal, Color color);
Mesh(int vertCount, const float verts[][3], int edgeCount_ = 0, const unsigned short edges_[][2] = 0, int triCount = 0, const unsigned short tris[][3] = 0, const float triNorms[][3] = 0)
: vertexCount(vertCount),
edgeCount(edgeCount_),
triangleCount(triCount),
vertices(verts),
edges(edges_),
triangles(tris),
triangleNormals(triNorms)
{
tvertices = (short(*)[3])malloc(sizeof(short) * 3 * vertexCount);
if(!tvertices)
ERROR("Not enough memory for vertices");
if (triangleNormals)
{
tTriNormals = (signed char(*)[3])malloc(sizeof(signed char) * 3 * triangleCount);
if(!tTriNormals)
ERROR("Not enough memory for triangle normals");
}
}
~Mesh()
{
delete (tvertices);
}
static Color basicTriangleShader(int trinangleNo, short *v0, short *v1, short *v2, const signed char *normal, Color color)
{
return color;
}
static Color basicTriangleShaderNormals(int trinangleNo, short *v0, short *v1, short *v2, const signed char *normal, Color color)
{
const float scaleN = 1.0f / 127.0f;
const float nx = normal[0] * scaleN;
const float ny = normal[1] * scaleN;
const float nz = normal[2] * scaleN;
const float L[3] = {0, 0, -1};
float NdotL = nx * L[0] + ny * L[1] + nz * L[2];
if(NdotL < 0) NdotL = 0;
return int(NdotL * (color & 0x1f)) | (int(NdotL * ((color >> 5) & 0x1f)) << 5) | (int(NdotL * ((color >> 10) & 0xf)) << 10);
}
void drawTriangles(Engine3D<Graphics> &e, Color color = -1, triangleShader ts = 0)
{
if(ts == 0)
{
if(tTriNormals)
ts = basicTriangleShaderNormals;
else
ts = basicTriangleShader;
}
for (int i = 0; i < triangleCount; i++)
{
short *v0 = tvertices[triangles[i][0]];
short *v1 = tvertices[triangles[i][1]];
short *v2 = tvertices[triangles[i][2]];
int dx1 = v1[0] - v0[0];
int dy1 = v1[1] - v0[1];
int dx2 = v2[0] - v0[0];
int dy2 = v2[1] - v0[1];
if (dx1 * dy2 - dx2 * dy1 < 0)
{
Color c = ts(i, v0, v1, v2, tTriNormals ? tTriNormals[i] : 0, color);
e.enqueueTriangle(tvertices[triangles[i][0]], tvertices[triangles[i][1]], tvertices[triangles[i][2]], c);
}
}
}
void drawEdges(Graphics &g, Color color)
{
for (int i = 0; i < edgeCount; i++)
{
g.line(tvertices[edges[i][0]][0], tvertices[edges[i][0]][1], tvertices[edges[i][1]][0], tvertices[edges[i][1]][1], color);
}
}
void drawVertices(Graphics &g, Color color)
{
for (int i = 0; i < vertexCount; i++)
g.dot(tvertices[i][0], tvertices[i][1], color);
}
void transform(Matrix m, Matrix normTrans = Matrix())
{
for (int i = 0; i < vertexCount; i++)
{
Vector v = m * Vector(vertices[i][0], vertices[i][1], vertices[i][2]);
tvertices[i][0] = v[0] / v[3];
tvertices[i][1] = v[1] / v[3];
tvertices[i][2] = v[2];
}
if (triangleNormals)
for (int i = 0; i < triangleCount; i++)
{
Vector v = normTrans * Vector(triangleNormals[i][0], triangleNormals[i][1], triangleNormals[i][2]);
tTriNormals[i][0] = v[0] * 127;
tTriNormals[i][1] = v[1] * 127;
tTriNormals[i][2] = v[2] * 127;
}
}
};

View file

@ -0,0 +1,108 @@
/*
Author: bitluni 2019
License:
Creative Commons Attribution ShareAlike 4.0
https://creativecommons.org/licenses/by-sa/4.0/
For further details check out:
https://youtube.com/bitlunislab
https://github.com/bitluni
http://bitluni.net
*/
#pragma once
#include "ImageDrawer.h"
#include "Image.h"
class Sprite : public Image
{
public:
typedef Image::PixelFormat PixelFormat;
unsigned char pointCount;
const signed short (*points)[2];
void init(int xres, int yres, const void *pixels, unsigned char pointCount, const signed short points[][2], PixelFormat pixelFormat)
{
static const signed short zeroPoint[][2] = {0, 0};
Image::init(xres, yres, pixels, pixelFormat);
if (pointCount)
{
this->pointCount = pointCount;
this->points = points;
}
else
{
this->pointCount = 1;
this->points = zeroPoint;
}
}
void draw(ImageDrawer &g, int x, int y)
{
g.image(*this, x - points[0][0], y - points[0][1]);
}
void drawMix(ImageDrawer &g, int x, int y)
{
g.imageMix(*this, x - points[0][0], y - points[0][1]);
}
void drawAdd(ImageDrawer &g, int x, int y)
{
g.imageAdd(*this, x - points[0][0], y - points[0][1]);
}
};
class Sprites
{
public:
typedef Image::PixelFormat PixelFormat;
int count;
Sprite *sprites;
Sprites(int count, const void* pixels, const int offsets[], const unsigned short resolutions[][2], const signed short points[][2], const short pointOffsets[], PixelFormat pixelFormat)
{
this->count = count;
this->sprites = new Sprite[count];
for (int i = 0; i < count; i++)
this->sprites[i].init(resolutions[i][0], resolutions[i][1], (unsigned char*)pixels + offsets[i], pointOffsets[i + 1] - pointOffsets[i], &points[pointOffsets[i]], pixelFormat);
}
void draw(ImageDrawer &g, int sprite, int x, int y)
{
sprites[sprite].draw(g, x, y);
}
void drawMix(ImageDrawer &g, int sprite, int x, int y)
{
sprites[sprite].drawMix(g, x, y);
}
void drawAdd(ImageDrawer &g, int sprite, int x, int y)
{
sprites[sprite].drawAdd(g, x, y);
}
int xres(int sprite) const
{
return sprites[sprite].xres;
}
int yres(int sprite) const
{
return sprites[sprite].yres;
}
const short (*points(int sprite) const)[2]
{
return sprites[sprite].points;
}
const short *point(int sprite, int point) const
{
return sprites[sprite].points[point];
}
/*unsigned short get(int sprite, int x, int y) const
{
return sprites[sprite].get(x, y);
}*/
};

View file

@ -0,0 +1,126 @@
/*
Author: bitluni 2019
License:
Creative Commons Attribution ShareAlike 4.0
https://creativecommons.org/licenses/by-sa/4.0/
For further details check out:
https://youtube.com/bitlunislab
https://github.com/bitluni
http://bitluni.net
*/
#pragma once
class TriangleTree
{
public:
short *v[3];
int z;
TriangleTree *left, *right;
int depth;
long color;
void set(short *v0, short *v1, short *v2, long color)
{
v[0] = v0;
v[1] = v1;
v[2] = v2;
z = v[0][2] + v[1][2] + v[2][2];
this->color = color;
left = right = 0;
depth = 1;
}
int leftDepth() const
{
return left ? left->depth : 0;
}
int rightDepth() const
{
return right ? right->depth : 0;
}
void recalcDepth()
{
int l = leftDepth();
int r = rightDepth();
depth = l > r ? l : r;
}
int add(TriangleTree **origin, TriangleTree &t)
{
int d = 1;
if (t.z < z)
{
if (left)
d = left->add(&left, t);
else
left = &t;
}
else
{
if (right)
d = right->add(&right, t);
else
right = &t;
}
if (depth < d + 1)
depth = d + 1;
int l = leftDepth();
int r = rightDepth();
if (l > r + 1)
{
int ll = left->leftDepth();
int lr = left->rightDepth();
if (ll < lr)
{
TriangleTree *tl = left;
left = tl->right;
tl->right = left->left;
left->left = tl;
left->left->recalcDepth();
left->recalcDepth();
ll = left->leftDepth();
lr = left->rightDepth();
l = leftDepth();
recalcDepth();
}
{
*origin = left;
left = left->right;
(*origin)->right = this;
depth = lr > r ? lr + 1 : r + 1;
(*origin)->depth = ll > depth ? ll + 1 : depth + 1;
return (*origin)->depth + 1;
}
}
if (r > l + 1)
{
int rl = right->leftDepth();
int rr = right->rightDepth();
if (rr < rl)
{
TriangleTree *tr = right;
right = tr->left;
tr->left = right->right;
right->right = tr;
right->right->recalcDepth();
right->recalcDepth();
rr = right->rightDepth();
rl = right->leftDepth();
r = rightDepth();
recalcDepth();
}
{
*origin = right;
right = right->left;
(*origin)->left = this;
depth = rl > l ? rl + 1 : l + 1;
(*origin)->depth = rr > depth ? rr + 1 : depth + 1;
return (*origin)->depth + 1;
}
}
return depth;
}
};

View file

@ -0,0 +1,110 @@
/*
Author: bitluni 2019
License:
Creative Commons Attribution ShareAlike 4.0
https://creativecommons.org/licenses/by-sa/4.0/
For further details check out:
https://youtube.com/bitlunislab
https://github.com/bitluni
http://bitluni.net
*/
#pragma once
#include "../Tools/Log.h"
class DMABufferDescriptor : protected lldesc_t
{
public:
static void *allocateBuffer(int bytes, bool clear = true, unsigned long clearValue = 0)
{
bytes = (bytes + 3) & 0xfffffffc;
void *b = heap_caps_malloc(bytes, MALLOC_CAP_DMA);
if (!b)
DEBUG_PRINTLN("Failed to alloc dma buffer");
if (clear)
for (int i = 0; i < bytes / 4; i++)
((unsigned long *)b)[i] = clearValue;
return b;
}
static void **allocateDMABufferArray(int count, int bytes, bool clear = true, unsigned long clearValue = 0)
{
void **arr = (void **)malloc(count * sizeof(void *));
if(!arr)
ERROR("Not enough DMA memory");
for (int i = 0; i < count; i++)
{
arr[i] = DMABufferDescriptor::allocateBuffer(bytes, true, clearValue);
if(!arr[i])
ERROR("Not enough DMA memory");
}
return arr;
}
void setBuffer(void *buffer, int bytes)
{
length = bytes;
size = length;
buf = (uint8_t *)buffer;
}
void *buffer() const
{
return (void *)buf;
}
void init()
{
length = 0;
size = 0;
owner = 1;
sosf = 0;
buf = (uint8_t *)0;
offset = 0;
empty = 0;
eof = 1;
qe.stqe_next = 0;
}
static DMABufferDescriptor *allocateDescriptors(int count)
{
DMABufferDescriptor *b = (DMABufferDescriptor *)heap_caps_malloc(sizeof(DMABufferDescriptor) * count, MALLOC_CAP_DMA);
if (!b)
DEBUG_PRINTLN("Failed to alloc DMABufferDescriptors");
for (int i = 0; i < count; i++)
b[i].init();
return b;
}
static DMABufferDescriptor *allocateDescriptor(int bytes, bool allocBuffer = true, bool clear = true, unsigned long clearValue = 0)
{
bytes = (bytes + 3) & 0xfffffffc;
DMABufferDescriptor *b = (DMABufferDescriptor *)heap_caps_malloc(sizeof(DMABufferDescriptor), MALLOC_CAP_DMA);
if (!b)
DEBUG_PRINTLN("Failed to alloc DMABufferDescriptor");
b->init();
if (allocateBuffer)
b->setBuffer(allocateBuffer(bytes, clear, clearValue), bytes);
return b;
}
void next(DMABufferDescriptor &next)
{
qe.stqe_next = &next;
}
int sampleCount() const
{
return length / 4;
}
void destroy()
{
if (buf)
{
free((void *)buf);
buf = 0;
}
free(this);
}
};

View file

@ -0,0 +1,360 @@
/*
Author: bitluni 2019
License:
Creative Commons Attribution ShareAlike 4.0
https://creativecommons.org/licenses/by-sa/4.0/
For further details check out:
https://youtube.com/bitlunislab
https://github.com/bitluni
http://bitluni.net
*/
#include "I2S.h"
#include "../Tools/Log.h"
#include <soc/rtc.h>
i2s_dev_t *i2sDevices[] = {&I2S0, &I2S1};
I2S::I2S(const int i2sIndex)
{
this->i2sIndex = i2sIndex;
interruptHandle = 0;
dmaBufferDescriptorCount = 0;
dmaBufferDescriptorActive = 0;
dmaBufferDescriptors = 0;
stopSignal = false;
}
void IRAM_ATTR I2S::interruptStatic(void *arg)
{
volatile i2s_dev_t &i2s = *i2sDevices[((I2S *)arg)->i2sIndex];
i2s.int_clr.val = i2s.int_raw.val;
((I2S *)arg)->interrupt();
}
void I2S::reset()
{
volatile i2s_dev_t &i2s = *i2sDevices[i2sIndex];
const unsigned long lc_conf_reset_flags = I2S_IN_RST_M | I2S_OUT_RST_M | I2S_AHBM_RST_M | I2S_AHBM_FIFO_RST_M;
i2s.lc_conf.val |= lc_conf_reset_flags;
i2s.lc_conf.val &= ~lc_conf_reset_flags;
const uint32_t conf_reset_flags = I2S_RX_RESET_M | I2S_RX_FIFO_RESET_M | I2S_TX_RESET_M | I2S_TX_FIFO_RESET_M;
i2s.conf.val |= conf_reset_flags;
i2s.conf.val &= ~conf_reset_flags;
while (i2s.state.rx_fifo_reset_back)
;
}
void I2S::i2sStop()
{
volatile i2s_dev_t &i2s = *i2sDevices[i2sIndex];
esp_intr_disable(interruptHandle);
reset();
i2s.conf.rx_start = 0;
i2s.conf.tx_start = 0;
}
void I2S::startTX()
{
volatile i2s_dev_t &i2s = *i2sDevices[i2sIndex];
DEBUG_PRINTLN("I2S TX");
esp_intr_disable(interruptHandle);
reset();
i2s.lc_conf.val = I2S_OUT_DATA_BURST_EN | I2S_OUTDSCR_BURST_EN;
dmaBufferDescriptorActive = 0;
i2s.out_link.addr = (uint32_t)firstDescriptorAddress();
i2s.out_link.start = 1;
i2s.int_clr.val = i2s.int_raw.val;
i2s.int_ena.val = 0;
if(useInterrupt())
{
i2s.int_ena.out_eof = 1;
//enable interrupt
esp_intr_enable(interruptHandle);
}
//start transmission
i2s.conf.tx_start = 1;
}
void I2S::startRX()
{
volatile i2s_dev_t &i2s = *i2sDevices[i2sIndex];
DEBUG_PRINTLN("I2S RX");
esp_intr_disable(interruptHandle);
reset();
dmaBufferDescriptorActive = 0;
i2s.rx_eof_num = dmaBufferDescriptors[0].sampleCount(); //TODO: replace with cont of sample to be recorded
i2s.in_link.addr = (uint32_t)firstDescriptorAddress();
i2s.in_link.start = 1;
i2s.int_clr.val = i2s.int_raw.val;
i2s.int_ena.val = 0;
i2s.int_ena.in_done = 1;
esp_intr_enable(interruptHandle);
i2s.conf.rx_start = 1;
}
void I2S::resetDMA()
{
volatile i2s_dev_t &i2s = *i2sDevices[i2sIndex];
i2s.lc_conf.in_rst = 1;
i2s.lc_conf.in_rst = 0;
i2s.lc_conf.out_rst = 1;
i2s.lc_conf.out_rst = 0;
}
void I2S::resetFIFO()
{
volatile i2s_dev_t &i2s = *i2sDevices[i2sIndex];
i2s.conf.rx_fifo_reset = 1;
i2s.conf.rx_fifo_reset = 0;
i2s.conf.tx_fifo_reset = 1;
i2s.conf.tx_fifo_reset = 0;
}
DMABufferDescriptor *I2S::firstDescriptorAddress() const
{
return &dmaBufferDescriptors[0];
}
bool I2S::useInterrupt()
{
return false;
};
bool I2S::initParallelInputMode(const int *pinMap, long sampleRate, const int bitCount, int wordSelect, int baseClock)
{
volatile i2s_dev_t &i2s = *i2sDevices[i2sIndex];
//route peripherals
const int deviceBaseIndex[] = {I2S0I_DATA_IN0_IDX, I2S1I_DATA_IN0_IDX};
const int deviceClockIndex[] = {I2S0I_BCK_IN_IDX, I2S1I_BCK_IN_IDX};
const int deviceWordSelectIndex[] = {I2S0I_WS_IN_IDX, I2S1I_WS_IN_IDX};
const periph_module_t deviceModule[] = {PERIPH_I2S0_MODULE, PERIPH_I2S1_MODULE};
//works only since indices of the pads are sequential
for (int i = 0; i < bitCount; i++)
if (pinMap[i] > -1)
{
PIN_FUNC_SELECT(GPIO_PIN_MUX_REG[pinMap[i]], PIN_FUNC_GPIO);
gpio_set_direction((gpio_num_t)pinMap[i], (gpio_mode_t)GPIO_MODE_DEF_INPUT);
gpio_matrix_in(pinMap[i], deviceBaseIndex[i2sIndex] + i, false);
}
if (baseClock > -1)
gpio_matrix_in(baseClock, deviceClockIndex[i2sIndex], false);
if (wordSelect > -1)
gpio_matrix_in(wordSelect, deviceWordSelectIndex[i2sIndex], false);
//enable I2S peripheral
periph_module_enable(deviceModule[i2sIndex]);
//reset i2s
i2s.conf.rx_reset = 1;
i2s.conf.rx_reset = 0;
i2s.conf.tx_reset = 1;
i2s.conf.tx_reset = 0;
resetFIFO();
resetDMA();
//parallel mode
i2s.conf2.val = 0;
i2s.conf2.lcd_en = 1;
//from technical datasheet figure 64
//i2s.conf2.lcd_tx_sdx2_en = 1;
//i2s.conf2.lcd_tx_wrx2_en = 1;
i2s.sample_rate_conf.val = 0;
i2s.sample_rate_conf.rx_bits_mod = 16;
//maximum rate
i2s.clkm_conf.val = 0;
i2s.clkm_conf.clka_en = 0;
i2s.clkm_conf.clkm_div_num = 6; //3//80000000L / sampleRate;
i2s.clkm_conf.clkm_div_a = 6; // 0;
i2s.clkm_conf.clkm_div_b = 1; // 0;
i2s.sample_rate_conf.rx_bck_div_num = 2;
i2s.fifo_conf.val = 0;
i2s.fifo_conf.rx_fifo_mod_force_en = 1;
i2s.fifo_conf.rx_fifo_mod = 1; //byte packing 0A0B_0B0C = 0, 0A0B_0C0D = 1, 0A00_0B00 = 3,
i2s.fifo_conf.rx_data_num = 32;
i2s.fifo_conf.dscr_en = 1; //fifo will use dma
i2s.conf1.val = 0;
i2s.conf1.tx_stop_en = 1;
i2s.conf1.tx_pcm_bypass = 1;
i2s.conf_chan.val = 0;
i2s.conf_chan.rx_chan_mod = 0;
//high or low (stereo word order)
i2s.conf.rx_right_first = 1;
i2s.timing.val = 0;
//clear serial mode flags
i2s.conf.rx_msb_right = 0;
i2s.conf.rx_msb_shift = 0;
i2s.conf.rx_mono = 0;
i2s.conf.rx_short_sync = 0;
//allocate disabled i2s interrupt
const int interruptSource[] = {ETS_I2S0_INTR_SOURCE, ETS_I2S1_INTR_SOURCE};
if(useInterrupt())
esp_intr_alloc(interruptSource[i2sIndex], ESP_INTR_FLAG_INTRDISABLED | ESP_INTR_FLAG_LEVEL3 | ESP_INTR_FLAG_IRAM, &interruptStatic, this, &interruptHandle);
return true;
}
bool I2S::initParallelOutputMode(const int *pinMap, long sampleRate, const int bitCount, int wordSelect, int baseClock)
{
volatile i2s_dev_t &i2s = *i2sDevices[i2sIndex];
//route peripherals
//in parallel mode only upper 16 bits are interesting in this case
const int deviceBaseIndex[] = {I2S0O_DATA_OUT0_IDX, I2S1O_DATA_OUT0_IDX};
const int deviceClockIndex[] = {I2S0O_BCK_OUT_IDX, I2S1O_BCK_OUT_IDX};
const int deviceWordSelectIndex[] = {I2S0O_WS_OUT_IDX, I2S1O_WS_OUT_IDX};
const periph_module_t deviceModule[] = {PERIPH_I2S0_MODULE, PERIPH_I2S1_MODULE};
//works only since indices of the pads are sequential
for (int i = 0; i < bitCount; i++)
if (pinMap[i] > -1)
{
PIN_FUNC_SELECT(GPIO_PIN_MUX_REG[pinMap[i]], PIN_FUNC_GPIO);
gpio_set_direction((gpio_num_t)pinMap[i], (gpio_mode_t)GPIO_MODE_DEF_OUTPUT);
if(i2sIndex == 1)
{
if(bitCount == 16)
gpio_matrix_out(pinMap[i], deviceBaseIndex[i2sIndex] + i + 8, false, false);
else
gpio_matrix_out(pinMap[i], deviceBaseIndex[i2sIndex] + i, false, false);
}
else
{
//there is something odd going on here in the two different I2S
//the configuration seems to differ. Use i2s1 for high frequencies.
gpio_matrix_out(pinMap[i], deviceBaseIndex[i2sIndex] + i + 24 - bitCount, false, false);
}
}
if (baseClock > -1)
gpio_matrix_out(baseClock, deviceClockIndex[i2sIndex], false, false);
if (wordSelect > -1)
gpio_matrix_out(wordSelect, deviceWordSelectIndex[i2sIndex], false, false);
//enable I2S peripheral
periph_module_enable(deviceModule[i2sIndex]);
//reset i2s
i2s.conf.tx_reset = 1;
i2s.conf.tx_reset = 0;
i2s.conf.rx_reset = 1;
i2s.conf.rx_reset = 0;
resetFIFO();
resetDMA();
//parallel mode
i2s.conf2.val = 0;
i2s.conf2.lcd_en = 1;
//from technical datasheet figure 64
i2s.conf2.lcd_tx_wrx2_en = 1;
i2s.conf2.lcd_tx_sdx2_en = 0;
i2s.sample_rate_conf.val = 0;
i2s.sample_rate_conf.tx_bits_mod = bitCount;
//clock setup
//xtal is 40M
//chip revision 0
//fxtal * (sdm2 + 4) / (2 * (odir + 2))
//chip revision 1
//fxtal * (sdm2 + (sdm1 / 256) + (sdm0 / 65536) + 4) / (2 * (odir + 2))
//fxtal * (sdm2 + (sdm1 / 256) + (sdm0 / 65536) + 4) needs to be btween 350M and 500M
//rtc_clk_apll_enable(enable, sdm0, sdm1, sdm2, odir);
// 0-255 0-255 0-63 0-31
//sdm seems to be simply a fixpoint number with 16bits fractional part
//freq = 40000000L * (4 + sdm) / (2 * (odir + 2))
//sdm = freq / (20000000L / (odir + 2)) - 4;
long freq = sampleRate * 2 * (bitCount / 8);
int sdm, sdmn;
int odir = -1;
do
{
odir++;
sdm = long((double(freq) / (20000000. / (odir + 2))) * 0x10000) - 0x40000;
sdmn = long((double(freq) / (20000000. / (odir + 2 + 1))) * 0x10000) - 0x40000;
}while(sdm < 0x8c0ecL && odir < 31 && sdmn < 0xA1fff); //0xA7fffL doesn't work on all mcus
//DEBUG_PRINTLN(sdm & 255);
//DEBUG_PRINTLN((sdm >> 8) & 255);
//DEBUG_PRINTLN(sdm >> 16);
//DEBUG_PRINTLN(odir);
//sdm = 0xA1fff;
//odir = 0;
if(sdm > 0xA1fff) sdm = 0xA1fff;
rtc_clk_apll_enable(true, sdm & 255, (sdm >> 8) & 255, sdm >> 16, odir);
i2s.clkm_conf.val = 0;
i2s.clkm_conf.clka_en = 1;
i2s.clkm_conf.clkm_div_num = 2; //clockN;
i2s.clkm_conf.clkm_div_a = 1; //clockA;
i2s.clkm_conf.clkm_div_b = 0; //clockB;
i2s.sample_rate_conf.tx_bck_div_num = 1;
i2s.fifo_conf.val = 0;
i2s.fifo_conf.tx_fifo_mod_force_en = 1;
i2s.fifo_conf.tx_fifo_mod = 1; //byte packing 0A0B_0B0C = 0, 0A0B_0C0D = 1, 0A00_0B00 = 3,
i2s.fifo_conf.tx_data_num = 32; //fifo length
i2s.fifo_conf.dscr_en = 1; //fifo will use dma
i2s.conf1.val = 0;
i2s.conf1.tx_stop_en = 0;
i2s.conf1.tx_pcm_bypass = 1;
i2s.conf_chan.val = 0;
i2s.conf_chan.tx_chan_mod = 1;
//high or low (stereo word order)
i2s.conf.tx_right_first = 1;
i2s.timing.val = 0;
//clear serial mode flags
i2s.conf.tx_msb_right = 0;
i2s.conf.tx_msb_shift = 0;
i2s.conf.tx_mono = 0;
i2s.conf.tx_short_sync = 0;
//allocate disabled i2s interrupt
const int interruptSource[] = {ETS_I2S0_INTR_SOURCE, ETS_I2S1_INTR_SOURCE};
if(useInterrupt())
esp_intr_alloc(interruptSource[i2sIndex], ESP_INTR_FLAG_INTRDISABLED | ESP_INTR_FLAG_LEVEL3 | ESP_INTR_FLAG_IRAM, &interruptStatic, this, &interruptHandle);
return true;
}
/// simple ringbuffer of blocks of size bytes each
void I2S::allocateDMABuffers(int count, int bytes)
{
dmaBufferDescriptorCount = count;
dmaBufferDescriptors = DMABufferDescriptor::allocateDescriptors(count);
for (int i = 0; i < dmaBufferDescriptorCount; i++)
{
dmaBufferDescriptors[i].setBuffer(DMABufferDescriptor::allocateBuffer(bytes, true), bytes);
if (i)
dmaBufferDescriptors[i - 1].next(dmaBufferDescriptors[i]);
}
dmaBufferDescriptors[dmaBufferDescriptorCount - 1].next(dmaBufferDescriptors[0]);
}
void I2S::deleteDMABuffers()
{
if (!dmaBufferDescriptors)
return;
for (int i = 0; i < dmaBufferDescriptorCount; i++)
free(dmaBufferDescriptors[i].buffer());
free(dmaBufferDescriptors);
dmaBufferDescriptors = 0;
dmaBufferDescriptorCount = 0;
}
void I2S::stop()
{
stopSignal = true;
while (stopSignal)
;
}

View file

@ -0,0 +1,60 @@
/*
Author: bitluni 2019
License:
Creative Commons Attribution ShareAlike 4.0
https://creativecommons.org/licenses/by-sa/4.0/
For further details check out:
https://youtube.com/bitlunislab
https://github.com/bitluni
http://bitluni.net
*/
#pragma once
#include "esp_heap_caps.h"
#include "soc/soc.h"
#include "soc/gpio_sig_map.h"
#include "soc/i2s_reg.h"
#include "soc/i2s_struct.h"
#include "soc/io_mux_reg.h"
#include "driver/gpio.h"
#include "driver/periph_ctrl.h"
#include "rom/lldesc.h"
#include "DMABufferDescriptor.h"
class I2S
{
public:
int i2sIndex;
intr_handle_t interruptHandle;
int dmaBufferDescriptorCount;
int dmaBufferDescriptorActive;
DMABufferDescriptor *dmaBufferDescriptors;
volatile bool stopSignal;
/// hardware index [0, 1]
I2S(const int i2sIndex = 0);
void reset();
void stop();
void i2sStop();
void startTX();
void startRX();
void resetDMA();
void resetFIFO();
bool initParallelOutputMode(const int *pinMap, long APLLFreq = 1000000, const int bitCount = 8, int wordSelect = -1, int baseClock = -1);
bool initParallelInputMode(const int *pinMap, long sampleRate = 1000000, const int bitCount = 8, int wordSelect = -1, int baseClock = -1);
virtual DMABufferDescriptor *firstDescriptorAddress() const;
void allocateDMABuffers(int count, int bytes);
void deleteDMABuffers();
protected:
virtual void interrupt() = 0;
virtual bool useInterrupt();
private:
static void IRAM_ATTR interruptStatic(void *arg);
};

View file

@ -0,0 +1,199 @@
/*
Author: bitluni 2019
License:
Creative Commons Attribution ShareAlike 4.0
https://creativecommons.org/licenses/by-sa/4.0/
For further details check out:
https://youtube.com/bitlunislab
https://github.com/bitluni
http://bitluni.net
*/
#pragma once
#include <math.h>
class Vector
{
public:
float v[4];
Vector(float x = 0, float y = 0, float z = 0, float w = 1)
{
v[0] = x;
v[1] = y;
v[2] = z;
v[3] = w;
}
Vector operator*(float s) const
{
return Vector(v[0] * s, v[1] * s, v[2] * s, 1);
}
Vector &operator*=(float s)
{
*this = *this * s;
return *this;
}
float operator[](int i) const
{
return v[i];
}
Vector operator+(const Vector &v2) const
{
return Vector(v[0] + v2.v[0], v[1] + v2.v[1], v[2] + v2.v[2], 1);
}
Vector operator-(const Vector &v2) const
{
return Vector(v[0] - v2.v[0], v[1] - v2.v[1], v[2] - v2.v[2], 1);
}
Vector operator-() const
{
return Vector(-v[0], -v[1], -v[2], 1);
}
void normalize()
{
float l2 = v[0] * v[0] + v[1] * v[1] + v[2] * v[2];
if (!l2)
return;
//float rl = 1 / sqrt(l2);
*this *= rsqrt(l2);//rl;
}
float length() const
{
float l2 = v[0] * v[0] + v[1] * v[1] + v[2] * v[2];
if (!l2) return 0.f;
return sqrt(l2);
}
float dot(const Vector &v2) const
{
return v[0] * v2.v[0] + v[1] * v2.v[1] + v[2] * v2.v[2];
}
static float rsqrt(float x)
{
const float x2 = x * 0.5F;
const float threehalfs = 1.5F;
union {
float f;
uint32_t i;
} conv = {x};
conv.i = 0x5f3759df - ( conv.i >> 1 );
conv.f *= ( threehalfs - ( x2 * conv.f * conv.f ) );
conv.f *= ( threehalfs - ( x2 * conv.f * conv.f ) );
return conv.f;
}
static float sqrt(float x)
{
return x * rsqrt(x);
}
};
class Matrix
{
public:
float m[4][4];
Matrix()
: Matrix(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1)
{
}
Matrix(float m00, float m01, float m02, float m03,
float m10, float m11, float m12, float m13,
float m20, float m21, float m22, float m23,
float m30, float m31, float m32, float m33)
{
m[0][0] = m00;
m[0][1] = m01;
m[0][2] = m02;
m[0][3] = m03;
m[1][0] = m10;
m[1][1] = m11;
m[1][2] = m12;
m[1][3] = m13;
m[2][0] = m20;
m[2][1] = m21;
m[2][2] = m22;
m[2][3] = m23;
m[3][0] = m30;
m[3][1] = m31;
m[3][2] = m32;
m[3][3] = m33;
}
static Matrix identity()
{
return Matrix(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1);
}
static Matrix scaling(float s)
{
return Matrix(s, 0, 0, 0, 0, s, 0, 0, 0, 0, s, 0, 0, 0, 0, 1);
}
static Matrix scaling(float u, float v, float w)
{
return Matrix(u, 0, 0, 0, 0, v, 0, 0, 0, 0, w, 0, 0, 0, 0, 1);
}
static Matrix translation(float x, float y, float z)
{
return Matrix(1, 0, 0, x, 0, 1, 0, y, 0, 0, 1, z, 0, 0, 0, 1);
}
static Matrix rotation(float a, float x, float y, float z)
{
float cosa = cos(a);
float rcosa = 1 - cosa;
float sina = sin(a);
return Matrix(
x * x * rcosa + cosa, x * y * rcosa - z * sina, x * z * rcosa + y * sina, 0,
y * x * rcosa + z * sina, y * y * rcosa + cosa, y * z * rcosa - x * sina, 0,
z * x * rcosa - y * sina, z * y * rcosa + x * sina, z * z * rcosa + cosa, 0,
0, 0, 0, 1);
}
static Matrix perspective(float fov, float near, float far)
{
float scale = tan(fov * 0.5 * M_PI / 180);
return Matrix(
scale, 0, 0, 0,
0, scale, 0, 0,
0, 0, -far * near / (far - near), 0,
0, 0, -1, 0);
}
Vector operator*(const Vector &v)
{
return Vector(
v.v[0] * m[0][0] + v.v[1] * m[0][1] + v.v[2] * m[0][2] + m[0][3],
v.v[0] * m[1][0] + v.v[1] * m[1][1] + v.v[2] * m[1][2] + m[1][3],
v.v[0] * m[2][0] + v.v[1] * m[2][1] + v.v[2] * m[2][2] + m[2][3],
v.v[0] * m[3][0] + v.v[1] * m[3][1] + v.v[2] * m[3][2] + m[3][3]);
}
Matrix operator*(const Matrix &m2)
{
Matrix mr;
for (int y = 0; y < 4; y++)
for (int x = 0; x < 4; x++)
mr.m[y][x] = m[y][0] * m2.m[0][x] + m[y][1] * m2.m[1][x] + m[y][2] * m2.m[2][x] + m[y][3] * m2.m[3][x];
return mr;
}
Matrix &operator*=(const Matrix &m2)
{
*this = *this * m2;
return *this;
}
};

View file

@ -0,0 +1,179 @@
/*
Author: bitluni 2019
License:
Creative Commons Attribution ShareAlike 4.0
https://creativecommons.org/licenses/by-sa/4.0/
For further details check out:
https://youtube.com/bitlunislab
https://github.com/bitluni
http://bitluni.net
*/
#pragma once
#include <math.h>
class Vector
{
public:
float v[4];
Vector(float x = 0, float y = 0, float z = 0, float w = 1)
{
v[0] = x;
v[1] = y;
v[2] = z;
v[3] = w;
}
Vector operator*(float s) const
{
return Vector(v[0] * s, v[1] * s, v[2] * s, 1);
}
Vector &operator*=(float s)
{
*this = *this * s;
return *this;
}
float operator[](int i) const
{
return v[i];
}
Vector operator+(const Vector &v2) const
{
return Vector(v[0] + v2.v[0], v[1] + v2.v[1], v[2] + v2.v[2], 1);
}
Vector operator-(const Vector &v2) const
{
return Vector(v[0] - v2.v[0], v[1] - v2.v[1], v[2] - v2.v[2], 1);
}
Vector operator-() const
{
return Vector(-v[0], -v[1], -v[2], 1);
}
void normalize()
{
float l2 = v[0] * v[0] + v[1] * v[1] + v[2] * v[2];
if (!l2)
return;
float rl = 1 / sqrt(l2);
*this *= rl;
}
float length() const
{
float l2 = v[0] * v[0] + v[1] * v[1] + v[2] * v[2];
if (!l2) return 0.f;
return sqrt(l2);
}
float dot(const Vector &v2) const
{
return v[0] * v2.v[0] + v[1] * v2.v[1] + v[2] * v2.v[2];
}
};
class Matrix
{
public:
float m[4][4];
Matrix()
: Matrix(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1)
{
}
Matrix(float m00, float m01, float m02, float m03,
float m10, float m11, float m12, float m13,
float m20, float m21, float m22, float m23,
float m30, float m31, float m32, float m33)
{
m[0][0] = m00;
m[0][1] = m01;
m[0][2] = m02;
m[0][3] = m03;
m[1][0] = m10;
m[1][1] = m11;
m[1][2] = m12;
m[1][3] = m13;
m[2][0] = m20;
m[2][1] = m21;
m[2][2] = m22;
m[2][3] = m23;
m[3][0] = m30;
m[3][1] = m31;
m[3][2] = m32;
m[3][3] = m33;
}
static Matrix identity()
{
return Matrix(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1);
}
static Matrix scaling(float s)
{
return Matrix(s, 0, 0, 0, 0, s, 0, 0, 0, 0, s, 0, 0, 0, 0, 1);
}
static Matrix scaling(float u, float v, float w)
{
return Matrix(u, 0, 0, 0, 0, v, 0, 0, 0, 0, w, 0, 0, 0, 0, 1);
}
static Matrix translation(float x, float y, float z)
{
return Matrix(1, 0, 0, x, 0, 1, 0, y, 0, 0, 1, z, 0, 0, 0, 1);
}
static Matrix rotation(float a, float x, float y, float z)
{
float cosa = cos(a);
float rcosa = 1 - cosa;
float sina = sin(a);
return Matrix(
x * x * rcosa + cosa, x * y * rcosa - z * sina, x * z * rcosa + y * sina, 0,
y * x * rcosa + z * sina, y * y * rcosa + cosa, y * z * rcosa - x * sina, 0,
z * x * rcosa - y * sina, z * y * rcosa + x * sina, z * z * rcosa + cosa, 0,
0, 0, 0, 1);
}
static Matrix perspective(float fov, float near, float far)
{
float scale = tan(fov * 0.5 * M_PI / 180);
return Matrix(
scale, 0, 0, 0,
0, scale, 0, 0,
0, 0, -far * near / (far - near), 0,
0, 0, -1, 0);
}
Vector operator*(const Vector &v)
{
return Vector(
v.v[0] * m[0][0] + v.v[1] * m[0][1] + v.v[2] * m[0][2] + m[0][3],
v.v[0] * m[1][0] + v.v[1] * m[1][1] + v.v[2] * m[1][2] + m[1][3],
v.v[0] * m[2][0] + v.v[1] * m[2][1] + v.v[2] * m[2][2] + m[2][3],
v.v[0] * m[3][0] + v.v[1] * m[3][1] + v.v[2] * m[3][2] + m[3][3]);
}
Matrix operator*(const Matrix &m2)
{
Matrix mr;
for (int y = 0; y < 4; y++)
for (int x = 0; x < 4; x++)
mr.m[y][x] = m[y][0] * m2.m[0][x] + m[y][1] * m2.m[1][x] + m[y][2] * m2.m[2][x] + m[y][3] * m2.m[3][x];
return mr;
}
Matrix &operator*=(const Matrix &m2)
{
*this = *this * m2;
return *this;
}
};

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View file

@ -0,0 +1,291 @@
const unsigned char Font6x8Pixels[] = {
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 255, 0, 0, 0, 0, 0, 255, 0, 0, 0, 0, 0, 255, 0,
0, 0, 0, 0, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 255, 0, 255, 0, 0, 0, 255, 0, 255, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 255, 0, 255, 0, 0, 255, 255, 255, 255,
255, 0, 0, 255, 0, 255, 0, 0, 255, 255, 255, 255, 255, 0, 0, 255,
0, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 255, 0, 0, 0, 0, 255, 255, 255, 0, 0, 255, 0, 255, 0,
0, 0, 0, 255, 255, 255, 0, 0, 0, 0, 255, 0, 255, 0, 0, 255,
255, 255, 0, 0, 0, 0, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 255, 255, 0, 0, 255, 0, 255, 255, 0, 255,
0, 0, 0, 0, 255, 0, 0, 0, 0, 255, 0, 255, 255, 0, 255, 0,
0, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 255, 0, 0, 0, 0, 255, 0, 255, 0,
0, 0, 0, 255, 255, 0, 255, 0, 255, 0, 0, 255, 0, 0, 0, 255,
255, 0, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 255, 0, 0, 0, 0, 0, 255, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 255, 255, 0, 0, 0, 255, 0, 0, 0, 0, 0, 255, 0, 0,
0, 0, 0, 255, 0, 0, 0, 0, 0, 255, 0, 0, 0, 0, 0, 255,
0, 0, 0, 0, 0, 0, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0,
0, 255, 255, 0, 0, 0, 0, 0, 0, 255, 0, 0, 0, 0, 0, 255,
0, 0, 0, 0, 0, 255, 0, 0, 0, 0, 0, 255, 0, 0, 0, 0,
0, 255, 0, 0, 0, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 0, 255,
0, 0, 0, 0, 255, 0, 0, 0, 0, 255, 0, 255, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 0,
0, 0, 0, 255, 255, 255, 0, 0, 0, 0, 255, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
255, 0, 0, 0, 0, 0, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 255, 0, 0, 0, 0, 0, 255, 0, 0, 0, 0, 255, 0,
0, 0, 0, 0, 255, 0, 0, 0, 0, 255, 0, 0, 0, 0, 0, 255,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 255, 0, 0, 0, 0, 255, 0, 255,
0, 0, 0, 255, 0, 255, 0, 0, 0, 255, 0, 255, 0, 0, 0, 0,
255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 255, 0, 0, 0, 0, 255, 255, 0,
0, 0, 0, 0, 255, 0, 0, 0, 0, 0, 255, 0, 0, 0, 0, 255,
255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 255, 255, 0, 0, 0, 0, 0, 0, 255,
0, 0, 0, 0, 255, 0, 0, 0, 0, 255, 0, 0, 0, 0, 0, 255,
255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 255, 255, 0, 0, 0, 0, 0, 0, 255,
0, 0, 0, 0, 255, 0, 0, 0, 0, 0, 0, 255, 0, 0, 0, 255,
255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 255, 0, 0, 0, 0, 255, 0, 0, 0,
0, 0, 255, 0, 255, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0,
255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 0, 0, 0, 255, 0, 0,
0, 0, 0, 255, 255, 0, 0, 0, 0, 0, 0, 255, 0, 0, 0, 255,
255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 0, 0, 0, 255, 0, 0,
0, 0, 0, 255, 255, 0, 0, 0, 0, 255, 0, 255, 0, 0, 0, 0,
255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 0, 0, 0, 0, 0, 255,
0, 0, 0, 0, 0, 255, 0, 0, 0, 0, 255, 0, 0, 0, 0, 0,
255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 255, 0, 0, 0, 0, 255, 0, 255,
0, 0, 0, 0, 255, 0, 0, 0, 0, 255, 0, 255, 0, 0, 0, 0,
255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 255, 0, 0, 0, 0, 255, 0, 255,
0, 0, 0, 0, 255, 255, 0, 0, 0, 0, 0, 255, 0, 0, 0, 255,
255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
255, 0, 0, 0, 0, 0, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 0,
0, 0, 0, 255, 0, 0, 0, 0, 0, 0, 255, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255,
0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 0,
0, 0, 0, 0, 0, 255, 0, 0, 0, 0, 255, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 255, 255, 0, 0, 0, 0, 0, 0, 255,
0, 0, 0, 0, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 255, 255, 255, 0, 0, 255, 0, 0, 0, 255, 0, 255, 0, 255, 255,
255, 0, 255, 0, 255, 255, 0, 0, 255, 0, 0, 0, 0, 0, 0, 255,
255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 255, 255, 0, 0, 0, 255, 0, 0, 255,
0, 0, 255, 255, 255, 255, 0, 0, 255, 0, 0, 255, 0, 0, 255, 0,
0, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 255, 255, 255, 0, 0, 0, 255, 0, 0, 255,
0, 0, 255, 255, 255, 0, 0, 0, 255, 0, 0, 255, 0, 0, 255, 255,
255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 0, 0, 255, 0, 0, 0,
0, 0, 255, 0, 0, 0, 0, 0, 255, 0, 0, 0, 0, 0, 0, 255,
255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 255, 255, 255, 0, 0, 0, 255, 0, 0, 255,
0, 0, 255, 0, 0, 255, 0, 0, 255, 0, 0, 255, 0, 0, 255, 255,
255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 255, 0, 0, 0,
0, 0, 255, 255, 0, 0, 0, 0, 255, 0, 0, 0, 0, 0, 255, 255,
255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 255, 0, 0, 0,
0, 0, 255, 255, 255, 0, 0, 0, 255, 0, 0, 0, 0, 0, 255, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 0, 0, 255, 0, 0, 0,
0, 0, 255, 0, 255, 255, 0, 0, 255, 0, 0, 0, 255, 0, 0, 255,
255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 255, 0, 0, 255, 0, 0, 255, 0, 0, 255,
0, 0, 255, 255, 255, 255, 0, 0, 255, 0, 0, 255, 0, 0, 255, 0,
0, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 0, 0, 0, 0, 255, 0,
0, 0, 0, 0, 255, 0, 0, 0, 0, 0, 255, 0, 0, 0, 0, 255,
255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 0, 255,
0, 0, 0, 0, 0, 255, 0, 0, 0, 0, 0, 255, 0, 0, 0, 0,
0, 255, 0, 0, 255, 0, 0, 255, 0, 0, 0, 255, 255, 0, 0, 0,
0, 0, 0, 0, 0, 0, 255, 0, 0, 255, 0, 0, 255, 0, 0, 255,
0, 0, 255, 255, 255, 0, 0, 0, 255, 0, 0, 255, 0, 0, 255, 0,
0, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 255, 0, 0, 0, 0, 0, 255, 0, 0, 0,
0, 0, 255, 0, 0, 0, 0, 0, 255, 0, 0, 0, 0, 0, 255, 255,
255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 255, 0, 0, 0, 255, 0, 255, 255, 0, 255,
255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 0, 0, 255, 0, 255, 0,
0, 0, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 255, 0, 0, 0, 255, 0, 255, 255, 0, 0,
255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 0, 255, 255, 0, 255, 0,
0, 0, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 255, 255, 0, 0, 0, 255, 0, 0, 255,
0, 0, 255, 0, 0, 255, 0, 0, 255, 0, 0, 255, 0, 0, 0, 255,
255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 255, 255, 255, 0, 0, 0, 255, 0, 0, 255,
0, 0, 255, 255, 255, 0, 0, 0, 255, 0, 0, 0, 0, 0, 255, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 255, 255, 0, 0, 0, 255, 0, 0, 255,
0, 0, 255, 0, 0, 255, 0, 0, 255, 0, 255, 255, 0, 0, 0, 255,
255, 255, 0, 0, 0, 0, 0, 0, 255, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 255, 255, 255, 0, 0, 0, 255, 0, 0, 255,
0, 0, 255, 255, 255, 0, 0, 0, 255, 0, 0, 255, 0, 0, 255, 0,
0, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 0, 0, 255, 0, 0, 0,
0, 0, 0, 255, 255, 0, 0, 0, 0, 0, 0, 255, 0, 0, 255, 255,
255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 255, 0, 0, 0, 255, 0,
0, 0, 0, 0, 255, 0, 0, 0, 0, 0, 255, 0, 0, 0, 0, 0,
255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 255, 0, 0, 255, 0, 0, 255, 0, 0, 255,
0, 0, 255, 0, 0, 255, 0, 0, 255, 0, 0, 255, 0, 0, 0, 255,
255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 255, 0, 0, 0, 255, 0, 255, 0, 0, 0,
255, 0, 255, 0, 0, 0, 255, 0, 0, 255, 0, 255, 0, 0, 0, 0,
255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 255, 0, 0, 0, 255, 0, 255, 0, 0, 0,
255, 0, 255, 0, 255, 0, 255, 0, 255, 255, 0, 255, 255, 0, 255, 0,
0, 0, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 255, 0, 255,
0, 0, 0, 0, 255, 0, 0, 0, 0, 255, 0, 255, 0, 0, 255, 0,
0, 0, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 255, 0, 0, 0, 255, 0, 255, 0, 0, 0,
255, 0, 0, 255, 0, 255, 0, 0, 0, 0, 255, 0, 0, 0, 0, 0,
255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 255, 0, 0, 0, 0, 255,
0, 0, 0, 0, 255, 0, 0, 0, 0, 255, 0, 0, 0, 0, 255, 255,
255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 255, 255, 255, 0, 0, 0, 255, 0, 0, 0, 0, 0, 255, 0, 0,
0, 0, 0, 255, 0, 0, 0, 0, 0, 255, 0, 0, 0, 0, 0, 255,
0, 0, 0, 0, 0, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0,
0, 255, 0, 0, 0, 0, 0, 255, 0, 0, 0, 0, 0, 0, 255, 0,
0, 0, 0, 0, 255, 0, 0, 0, 0, 0, 0, 255, 0, 0, 0, 0,
0, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 255, 255, 255, 0, 0, 0, 0, 0, 255, 0, 0, 0, 0, 0, 255,
0, 0, 0, 0, 0, 255, 0, 0, 0, 0, 0, 255, 0, 0, 0, 0,
0, 255, 0, 0, 0, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 255, 0, 0, 0, 0, 255, 0, 255, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0,
0, 255, 0, 0, 0, 0, 0, 0, 255, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 0,
0, 0, 255, 0, 0, 255, 0, 0, 255, 0, 0, 255, 0, 0, 0, 255,
255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 255, 0, 0, 0, 0, 0, 255, 255, 255, 0,
0, 0, 255, 0, 0, 255, 0, 0, 255, 0, 0, 255, 0, 0, 0, 255,
255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 0,
0, 0, 255, 0, 0, 0, 0, 0, 255, 0, 0, 0, 0, 0, 0, 255,
255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 0, 0, 0, 255, 255, 255,
0, 0, 255, 0, 0, 255, 0, 0, 255, 0, 0, 255, 0, 0, 0, 255,
255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 0,
0, 0, 255, 0, 255, 255, 0, 0, 255, 255, 0, 0, 0, 0, 0, 255,
255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255,
0, 0, 0, 255, 0, 0, 0, 0, 0, 255, 0, 0, 0, 0, 0, 255,
255, 0, 0, 0, 0, 255, 0, 0, 0, 0, 0, 255, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 0,
0, 0, 255, 0, 0, 255, 0, 0, 255, 0, 0, 255, 0, 0, 0, 255,
255, 255, 0, 0, 0, 0, 0, 255, 0, 0, 0, 255, 255, 0, 0, 0,
0, 0, 0, 0, 0, 0, 255, 0, 0, 0, 0, 0, 255, 0, 255, 0,
0, 0, 255, 255, 0, 255, 0, 0, 255, 0, 0, 255, 0, 0, 255, 0,
0, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 255, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 255, 0, 0, 0, 0, 0, 255, 0, 0, 0, 0, 0, 0,
255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 255, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 255, 0, 0, 0, 0, 0, 255, 0, 0, 0, 0, 0,
255, 0, 0, 0, 0, 0, 255, 0, 0, 0, 0, 255, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 255, 0, 0, 0, 0, 0, 255, 0, 255, 255,
0, 0, 255, 255, 0, 0, 0, 0, 255, 0, 255, 0, 0, 0, 255, 0,
0, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 255, 0, 0, 0, 0, 0, 255, 0, 0,
0, 0, 0, 255, 0, 0, 0, 0, 0, 255, 0, 0, 0, 0, 0, 0,
255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 0, 255,
0, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0,
0, 0, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 0, 255, 0,
0, 0, 255, 255, 0, 255, 0, 0, 255, 0, 0, 255, 0, 0, 255, 0,
0, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 0,
0, 0, 255, 0, 0, 255, 0, 0, 255, 0, 0, 255, 0, 0, 0, 255,
255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 0,
0, 0, 255, 0, 0, 255, 0, 0, 255, 0, 0, 255, 0, 0, 255, 255,
255, 0, 0, 0, 255, 0, 0, 0, 0, 0, 255, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255,
0, 0, 255, 0, 0, 255, 0, 0, 255, 0, 0, 255, 0, 0, 0, 255,
255, 255, 0, 0, 0, 0, 0, 255, 0, 0, 0, 0, 0, 255, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255,
0, 0, 0, 255, 0, 0, 0, 0, 0, 255, 0, 0, 0, 0, 0, 255,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255,
0, 0, 0, 255, 255, 0, 0, 0, 0, 0, 0, 255, 0, 0, 0, 255,
255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 255, 0, 0, 0, 0, 255, 255, 255, 0,
0, 0, 0, 255, 0, 0, 0, 0, 0, 255, 0, 0, 0, 0, 0, 0,
255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 0, 0, 255,
0, 0, 255, 0, 0, 255, 0, 0, 255, 0, 0, 255, 0, 0, 0, 255,
255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 0, 0,
255, 0, 0, 255, 0, 0, 255, 0, 0, 255, 0, 255, 0, 0, 0, 0,
255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 0, 0, 0,
255, 0, 255, 0, 0, 0, 255, 0, 255, 0, 255, 0, 255, 0, 0, 255,
0, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 0, 255,
0, 0, 0, 0, 255, 0, 0, 0, 0, 255, 0, 255, 0, 0, 255, 0,
0, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 0, 0, 255,
0, 0, 255, 0, 0, 255, 0, 0, 255, 0, 0, 255, 0, 0, 0, 255,
255, 255, 0, 0, 0, 0, 0, 255, 0, 0, 0, 255, 255, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255,
0, 0, 0, 0, 255, 0, 0, 0, 0, 255, 0, 0, 0, 0, 255, 255,
255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 255, 255, 0, 0, 0, 255, 0, 0, 0, 0, 0, 0, 255, 0,
0, 0, 0, 255, 255, 0, 0, 0, 0, 0, 255, 0, 0, 0, 0, 255,
0, 0, 0, 0, 0, 0, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 255, 0, 0, 0, 0, 0, 255, 0, 0, 0, 0, 0, 255, 0,
0, 0, 0, 0, 255, 0, 0, 0, 0, 0, 255, 0, 0, 0, 0, 0,
255, 0, 0, 0, 0, 0, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 255, 255, 0, 0, 0, 0, 0, 0, 255, 0, 0, 0, 0, 255, 0,
0, 0, 0, 0, 255, 255, 0, 0, 0, 0, 255, 0, 0, 0, 0, 0,
0, 255, 0, 0, 0, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 255, 0, 255, 0, 0, 255, 0, 255, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, };
Font Font6x8(6, 8, Font6x8Pixels, 32, 96);

View file

@ -0,0 +1,386 @@
const unsigned char Font8x8Pixels[] = {
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 0, 0, 0,
0, 0, 0, 255, 255, 0, 0, 0, 0, 0, 0, 255, 255, 0, 0, 0,
0, 0, 0, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 0, 255, 0, 0, 0,
0, 0, 255, 0, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 255, 0, 255, 0, 0, 0, 0, 255, 255, 255, 255, 255, 0, 0,
0, 0, 255, 0, 255, 0, 0, 0, 0, 255, 255, 255, 255, 255, 0, 0,
0, 0, 255, 0, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 255, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0,
0, 255, 255, 255, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0,
0, 0, 0, 255, 0, 255, 255, 0, 0, 255, 0, 255, 0, 255, 255, 0,
0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 0, 0, 0, 0,
0, 0, 0, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 0, 255, 0, 255, 0, 0,
0, 0, 0, 0, 255, 0, 0, 0, 0, 0, 0, 255, 0, 255, 0, 0,
0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 0, 0, 0, 0,
0, 0, 0, 255, 0, 0, 0, 0, 0, 255, 255, 255, 255, 255, 0, 0,
0, 0, 0, 255, 0, 0, 0, 0, 0, 0, 0, 255, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 0, 0, 0,
0, 0, 0, 255, 255, 0, 0, 0, 0, 0, 255, 255, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0,
0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 0, 0, 0, 0, 0,
0, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 0, 0,
0, 0, 0, 0, 255, 255, 0, 0, 0, 0, 0, 255, 255, 0, 0, 0,
0, 0, 0, 255, 255, 0, 0, 0, 0, 0, 255, 255, 0, 0, 0, 0,
0, 0, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0,
0, 255, 255, 0, 0, 255, 255, 0, 0, 255, 255, 0, 0, 255, 255, 0,
0, 255, 255, 0, 0, 255, 255, 0, 0, 255, 255, 0, 0, 255, 255, 0,
0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 0, 0, 0,
0, 0, 255, 255, 255, 0, 0, 0, 0, 0, 0, 255, 255, 0, 0, 0,
0, 0, 0, 255, 255, 0, 0, 0, 0, 0, 0, 255, 255, 0, 0, 0,
0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0,
0, 255, 0, 0, 255, 255, 255, 0, 0, 0, 0, 0, 255, 255, 255, 0,
0, 0, 255, 255, 255, 255, 0, 0, 0, 255, 255, 255, 0, 0, 0, 0,
0, 255, 255, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 255, 0, 0,
0, 0, 0, 0, 255, 255, 255, 0, 0, 0, 255, 255, 255, 255, 0, 0,
0, 0, 0, 0, 255, 255, 255, 0, 0, 0, 0, 0, 255, 255, 255, 0,
0, 255, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0,
0, 255, 255, 0, 255, 255, 0, 0, 0, 255, 0, 0, 255, 255, 0, 0,
0, 255, 0, 0, 255, 255, 255, 0, 0, 255, 255, 255, 255, 255, 255, 0,
0, 0, 0, 0, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 255, 0, 0,
0, 255, 255, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 255, 0, 0,
0, 0, 0, 0, 255, 255, 255, 0, 0, 255, 0, 0, 255, 255, 255, 0,
0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0,
0, 255, 255, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 255, 0, 0,
0, 255, 255, 0, 0, 255, 255, 0, 0, 255, 255, 0, 0, 255, 255, 0,
0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 255, 255, 0,
0, 0, 0, 0, 0, 255, 255, 0, 0, 0, 0, 0, 255, 255, 0, 0,
0, 0, 0, 255, 255, 0, 0, 0, 0, 0, 255, 255, 255, 0, 0, 0,
0, 0, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0,
0, 255, 0, 0, 255, 255, 255, 0, 0, 0, 255, 255, 255, 255, 0, 0,
0, 255, 0, 0, 255, 255, 255, 0, 0, 255, 0, 0, 255, 255, 255, 0,
0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0,
0, 255, 0, 0, 255, 255, 255, 0, 0, 255, 0, 0, 255, 255, 255, 0,
0, 0, 255, 255, 255, 255, 255, 0, 0, 0, 0, 0, 255, 255, 255, 0,
0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 255, 255, 0, 0, 0, 0, 0, 0, 255, 255, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 0, 0, 0,
0, 0, 0, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 255, 255, 0, 0, 0, 0, 0, 0, 255, 255, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 0, 0, 0,
0, 0, 0, 255, 255, 0, 0, 0, 0, 0, 255, 255, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 255, 255, 0, 0, 0, 0, 0, 255, 255, 0, 0, 0, 0,
0, 0, 255, 255, 0, 0, 0, 0, 0, 0, 0, 255, 255, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 255, 255, 0, 0, 0, 0, 0, 0, 0, 255, 255, 0, 0, 0,
0, 0, 0, 255, 255, 0, 0, 0, 0, 0, 255, 255, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0,
0, 255, 0, 0, 255, 255, 255, 0, 0, 0, 0, 0, 255, 255, 255, 0,
0, 0, 0, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0,
0, 255, 0, 0, 255, 255, 255, 0, 0, 255, 0, 0, 255, 255, 255, 0,
0, 255, 255, 255, 255, 255, 255, 0, 0, 255, 0, 0, 255, 255, 255, 0,
0, 255, 0, 0, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 255, 0, 0,
0, 255, 255, 0, 0, 255, 255, 0, 0, 255, 255, 255, 255, 255, 0, 0,
0, 255, 255, 0, 0, 255, 255, 0, 0, 255, 255, 0, 0, 255, 255, 0,
0, 255, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0,
0, 255, 255, 0, 0, 255, 255, 0, 0, 255, 255, 0, 0, 0, 0, 0,
0, 255, 255, 0, 0, 0, 0, 0, 0, 255, 255, 0, 0, 255, 255, 0,
0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 255, 0, 0,
0, 255, 0, 0, 255, 255, 255, 0, 0, 255, 0, 0, 255, 255, 255, 0,
0, 255, 0, 0, 255, 255, 255, 0, 0, 255, 0, 0, 255, 255, 255, 0,
0, 255, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 255, 255, 0,
0, 255, 255, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 255, 0, 0,
0, 255, 255, 0, 0, 0, 0, 0, 0, 255, 255, 0, 0, 0, 0, 0,
0, 255, 255, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 255, 255, 0,
0, 255, 255, 0, 0, 0, 0, 0, 0, 255, 255, 0, 0, 0, 0, 0,
0, 255, 255, 255, 255, 255, 0, 0, 0, 255, 255, 0, 0, 0, 0, 0,
0, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0,
0, 255, 255, 0, 0, 255, 255, 0, 0, 255, 255, 0, 0, 0, 0, 0,
0, 255, 255, 0, 255, 255, 255, 0, 0, 255, 255, 0, 0, 255, 255, 0,
0, 0, 255, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 0, 0, 0, 255, 255, 0,
0, 255, 0, 0, 0, 255, 255, 0, 0, 255, 255, 255, 255, 255, 255, 0,
0, 255, 0, 0, 0, 255, 255, 0, 0, 255, 0, 0, 0, 255, 255, 0,
0, 255, 0, 0, 0, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0,
0, 0, 0, 255, 255, 0, 0, 0, 0, 0, 0, 255, 255, 0, 0, 0,
0, 0, 0, 255, 255, 0, 0, 0, 0, 0, 0, 255, 255, 0, 0, 0,
0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0,
0, 0, 0, 0, 255, 255, 0, 0, 0, 0, 0, 0, 255, 255, 0, 0,
0, 255, 255, 0, 255, 255, 0, 0, 0, 255, 255, 0, 255, 255, 0, 0,
0, 0, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 0, 0, 255, 255, 0,
0, 255, 255, 0, 255, 255, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0,
0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 0, 255, 255, 0, 0,
0, 255, 255, 0, 0, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 0, 0, 0, 0, 0,
0, 255, 255, 0, 0, 0, 0, 0, 0, 255, 255, 0, 0, 0, 0, 0,
0, 255, 255, 0, 0, 0, 0, 0, 0, 255, 255, 0, 0, 0, 0, 0,
0, 255, 255, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 0, 0, 0, 255, 255, 0,
0, 255, 255, 0, 255, 255, 255, 0, 0, 255, 255, 255, 255, 255, 255, 0,
0, 255, 0, 255, 0, 255, 255, 0, 0, 255, 0, 0, 0, 255, 255, 0,
0, 255, 0, 0, 0, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 0, 0, 0, 255, 255, 0,
0, 255, 255, 0, 0, 255, 255, 0, 0, 255, 255, 255, 0, 255, 255, 0,
0, 255, 0, 255, 255, 255, 255, 0, 0, 255, 0, 0, 255, 255, 255, 0,
0, 255, 0, 0, 0, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0,
0, 255, 255, 0, 0, 255, 255, 0, 0, 255, 255, 0, 0, 255, 255, 0,
0, 255, 255, 0, 0, 255, 255, 0, 0, 255, 255, 0, 0, 255, 255, 0,
0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 255, 0, 0,
0, 255, 255, 0, 0, 255, 255, 0, 0, 255, 255, 0, 0, 255, 255, 0,
0, 255, 255, 255, 255, 255, 0, 0, 0, 255, 255, 0, 0, 0, 0, 0,
0, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0,
0, 255, 255, 0, 0, 0, 255, 0, 0, 255, 255, 0, 0, 0, 255, 0,
0, 255, 255, 0, 255, 0, 255, 0, 0, 255, 255, 0, 0, 255, 0, 0,
0, 0, 255, 255, 255, 0, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 255, 0, 0,
0, 255, 255, 0, 0, 255, 255, 0, 0, 255, 255, 0, 0, 255, 255, 0,
0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 0, 255, 0, 0, 0,
0, 255, 255, 0, 0, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0,
0, 255, 255, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0,
0, 0, 0, 0, 255, 255, 255, 0, 0, 255, 0, 0, 255, 255, 255, 0,
0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 255, 255, 0,
0, 0, 0, 255, 255, 0, 0, 0, 0, 0, 0, 255, 255, 0, 0, 0,
0, 0, 0, 255, 255, 0, 0, 0, 0, 0, 0, 255, 255, 0, 0, 0,
0, 0, 0, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 0, 0, 0, 255, 255, 0,
0, 255, 0, 0, 0, 255, 255, 0, 0, 255, 0, 0, 0, 255, 255, 0,
0, 255, 0, 0, 0, 255, 255, 0, 0, 255, 0, 0, 255, 255, 255, 0,
0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 0, 0, 0, 255, 255, 0,
0, 255, 0, 0, 0, 255, 255, 0, 0, 255, 0, 0, 0, 255, 255, 0,
0, 255, 0, 0, 0, 255, 255, 0, 0, 0, 255, 0, 255, 255, 0, 0,
0, 0, 0, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 0, 0, 0, 255, 255, 0,
0, 255, 0, 0, 0, 255, 255, 0, 0, 255, 0, 255, 0, 255, 255, 0,
0, 255, 255, 255, 255, 255, 255, 0, 0, 255, 255, 0, 255, 255, 255, 0,
0, 255, 0, 0, 0, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 0, 0, 0, 255, 255, 0,
0, 0, 255, 0, 255, 255, 0, 0, 0, 0, 0, 255, 255, 0, 0, 0,
0, 0, 255, 255, 255, 0, 0, 0, 0, 255, 255, 0, 0, 255, 0, 0,
0, 255, 0, 0, 0, 0, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 0, 0, 255, 255, 0,
0, 255, 255, 0, 0, 255, 255, 0, 0, 0, 255, 255, 255, 255, 0, 0,
0, 0, 0, 255, 255, 0, 0, 0, 0, 0, 0, 255, 255, 0, 0, 0,
0, 0, 0, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 255, 255, 0,
0, 0, 0, 0, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 0, 0,
0, 0, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 0, 0, 0, 0,
0, 255, 255, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0,
0, 255, 0, 0, 255, 255, 255, 0, 0, 255, 0, 0, 255, 255, 255, 0,
0, 255, 255, 255, 255, 255, 255, 0, 0, 255, 0, 0, 255, 255, 255, 0,
0, 255, 0, 0, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 255, 0, 0,
0, 255, 255, 0, 0, 255, 255, 0, 0, 255, 255, 255, 255, 255, 0, 0,
0, 255, 255, 0, 0, 255, 255, 0, 0, 255, 255, 0, 0, 255, 255, 0,
0, 255, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0,
0, 255, 255, 0, 0, 255, 255, 0, 0, 255, 255, 0, 0, 0, 0, 0,
0, 255, 255, 0, 0, 0, 0, 0, 0, 255, 255, 0, 0, 255, 255, 0,
0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 255, 0, 0,
0, 255, 0, 0, 255, 255, 255, 0, 0, 255, 0, 0, 255, 255, 255, 0,
0, 255, 0, 0, 255, 255, 255, 0, 0, 255, 0, 0, 255, 255, 255, 0,
0, 255, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 255, 255, 0,
0, 255, 255, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 255, 0, 0,
0, 255, 255, 0, 0, 0, 0, 0, 0, 255, 255, 0, 0, 0, 0, 0,
0, 255, 255, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 255, 255, 0,
0, 255, 255, 0, 0, 0, 0, 0, 0, 255, 255, 0, 0, 0, 0, 0,
0, 255, 255, 255, 255, 255, 0, 0, 0, 255, 255, 0, 0, 0, 0, 0,
0, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0,
0, 255, 255, 0, 0, 255, 255, 0, 0, 255, 255, 0, 0, 0, 0, 0,
0, 255, 255, 0, 255, 255, 255, 0, 0, 255, 255, 0, 0, 255, 255, 0,
0, 0, 255, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 0, 0, 0, 255, 255, 0,
0, 255, 0, 0, 0, 255, 255, 0, 0, 255, 255, 255, 255, 255, 255, 0,
0, 255, 0, 0, 0, 255, 255, 0, 0, 255, 0, 0, 0, 255, 255, 0,
0, 255, 0, 0, 0, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0,
0, 0, 0, 255, 255, 0, 0, 0, 0, 0, 0, 255, 255, 0, 0, 0,
0, 0, 0, 255, 255, 0, 0, 0, 0, 0, 0, 255, 255, 0, 0, 0,
0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0,
0, 0, 0, 0, 255, 255, 0, 0, 0, 0, 0, 0, 255, 255, 0, 0,
0, 255, 255, 0, 255, 255, 0, 0, 0, 255, 255, 0, 255, 255, 0, 0,
0, 0, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 0, 0, 255, 255, 0,
0, 255, 255, 0, 255, 255, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0,
0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 0, 255, 255, 0, 0,
0, 255, 255, 0, 0, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 0, 0, 0, 0, 0,
0, 255, 255, 0, 0, 0, 0, 0, 0, 255, 255, 0, 0, 0, 0, 0,
0, 255, 255, 0, 0, 0, 0, 0, 0, 255, 255, 0, 0, 0, 0, 0,
0, 255, 255, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 0, 0, 0, 255, 255, 0,
0, 255, 255, 0, 255, 255, 255, 0, 0, 255, 255, 255, 255, 255, 255, 0,
0, 255, 0, 255, 0, 255, 255, 0, 0, 255, 0, 0, 0, 255, 255, 0,
0, 255, 0, 0, 0, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 0, 0, 0, 255, 255, 0,
0, 255, 255, 0, 0, 255, 255, 0, 0, 255, 255, 255, 0, 255, 255, 0,
0, 255, 0, 255, 255, 255, 255, 0, 0, 255, 0, 0, 255, 255, 255, 0,
0, 255, 0, 0, 0, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0,
0, 255, 255, 0, 0, 255, 255, 0, 0, 255, 255, 0, 0, 255, 255, 0,
0, 255, 255, 0, 0, 255, 255, 0, 0, 255, 255, 0, 0, 255, 255, 0,
0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 255, 0, 0,
0, 255, 255, 0, 0, 255, 255, 0, 0, 255, 255, 0, 0, 255, 255, 0,
0, 255, 255, 255, 255, 255, 0, 0, 0, 255, 255, 0, 0, 0, 0, 0,
0, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0,
0, 255, 255, 0, 0, 0, 255, 0, 0, 255, 255, 0, 0, 0, 255, 0,
0, 255, 255, 0, 255, 0, 255, 0, 0, 255, 255, 0, 0, 255, 0, 0,
0, 0, 255, 255, 255, 0, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 255, 0, 0,
0, 255, 255, 0, 0, 255, 255, 0, 0, 255, 255, 0, 0, 255, 255, 0,
0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 0, 255, 0, 0, 0,
0, 255, 255, 0, 0, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0,
0, 255, 255, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0,
0, 0, 0, 0, 255, 255, 255, 0, 0, 255, 0, 0, 255, 255, 255, 0,
0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 255, 255, 0,
0, 0, 0, 255, 255, 0, 0, 0, 0, 0, 0, 255, 255, 0, 0, 0,
0, 0, 0, 255, 255, 0, 0, 0, 0, 0, 0, 255, 255, 0, 0, 0,
0, 0, 0, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 0, 0, 0, 255, 255, 0,
0, 255, 0, 0, 0, 255, 255, 0, 0, 255, 0, 0, 0, 255, 255, 0,
0, 255, 0, 0, 0, 255, 255, 0, 0, 255, 0, 0, 255, 255, 255, 0,
0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 0, 0, 0, 255, 255, 0,
0, 255, 0, 0, 0, 255, 255, 0, 0, 255, 0, 0, 0, 255, 255, 0,
0, 255, 0, 0, 0, 255, 255, 0, 0, 0, 255, 0, 255, 255, 0, 0,
0, 0, 0, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 0, 0, 0, 255, 255, 0,
0, 255, 0, 0, 0, 255, 255, 0, 0, 255, 0, 255, 0, 255, 255, 0,
0, 255, 255, 255, 255, 255, 255, 0, 0, 255, 255, 0, 255, 255, 255, 0,
0, 255, 0, 0, 0, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 0, 0, 0, 255, 255, 0,
0, 0, 255, 0, 255, 255, 0, 0, 0, 0, 0, 255, 255, 0, 0, 0,
0, 0, 255, 255, 255, 0, 0, 0, 0, 255, 255, 0, 0, 255, 0, 0,
0, 255, 0, 0, 0, 0, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 0, 0, 255, 255, 0,
0, 255, 255, 0, 0, 255, 255, 0, 0, 0, 255, 255, 255, 255, 0, 0,
0, 0, 0, 255, 255, 0, 0, 0, 0, 0, 0, 255, 255, 0, 0, 0,
0, 0, 0, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 255, 255, 0,
0, 0, 0, 0, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 0, 0,
0, 0, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 0, 0, 0, 0,
0, 255, 255, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 0, 0, 0, 0,
0, 0, 255, 255, 255, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0,
0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 0, 0, 0,
0, 0, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
255, 255, 255, 255, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
255, 0, 255, 0, 255, 0, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 255, 0, 255, 0, 255, 0, 255, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, };
Font Font8x8(8, 8, Font8x8Pixels, 32, 96);

View file

@ -0,0 +1,26 @@
/*
Author: bitluni 2019
License:
Creative Commons Attribution ShareAlike 4.0
https://creativecommons.org/licenses/by-sa/4.0/
For further details check out:
https://youtube.com/bitlunislab
https://github.com/bitluni
http://bitluni.net
*/
#pragma once
#include "Arduino.h"
#define DEBUG_PRINTLN(a) Serial.println(a)
#define DEBUG_PRINT(a) Serial.print(a)
#define DEBUG_PRINTLNF(a, f) Serial.println(a, f)
#define DEBUG_PRINTF(a, f) Serial.print(a, f)
/*
#define DEBUG_PRINTLN(a) ;
#define DEBUG_PRINT(a) ;
#define DEBUG_PRINTLNF(a, f) ;
#define DEBUG_PRINTF(a, f) ;
*/
#define ERROR(a) {Serial.println((a)); delay(3000); throw 0;};

View file

@ -0,0 +1,122 @@
/*
Author: bitluni 2019
License:
Creative Commons Attribution ShareAlike 4.0
https://creativecommons.org/licenses/by-sa/4.0/
For further details check out:
https://youtube.com/bitlunislab
https://github.com/bitluni
http://bitluni.net
*/
#pragma once
class Mode
{
public:
int hFront;
int hSync;
int hBack;
int hRes;
int vFront;
int vSync;
int vBack;
int vRes;
int vDiv;
unsigned long pixelClock;
int hSyncPolarity;
int vSyncPolarity;
float aspect;
int activeLineCount;
Mode(
const int hFront = 0,
const int hSync = 0,
const int hBack = 0,
const int hRes = 0,
const int vFront = 0,
const int vSync = 0,
const int vBack = 0,
const int vRes = 0,
const int vDiv = 1,
const unsigned long pixelClock = 0,
const int hSyncPolarity = 1,
const int vSyncPolarity = 1,
const float aspect = 1.f)
: hFront(hFront),
hSync(hSync),
hBack(hBack),
hRes(hRes),
vFront(vFront),
vSync(vSync),
vBack(vBack),
vRes(vRes),
vDiv(vDiv),
pixelClock(pixelClock),
hSyncPolarity(hSyncPolarity),
vSyncPolarity(vSyncPolarity),
aspect(aspect),
activeLineCount(vRes / vDiv)
{
}
int maxXRes() const
{
return (int(hRes * 19673499. / pixelClock) & 0xfffffffe);
}
int linesPerField() const
{
return vFront + vSync + vBack + vRes;
}
int pixelsPerLine() const
{
return hFront + hSync + hBack + hRes;
}
Mode custom(int xres, int yres, int fixedYDivider = 0) const
{
xres = (xres + 3) & 0xfffffffc;
float f = float(xres) / hRes;
int hs = int(hSync * f + 3) & 0xfffffffc;
int hb = int((hSync + hBack - hs / f) * f + 3) & 0xfffffffc;
int hr = xres;
int hf = int((pixelsPerLine() - (hs + hb + hr) / f) * f + 3) & 0xfffffffc;
int vd = fixedYDivider ? fixedYDivider : (vRes / yres);
int vr = yres * vd;
int vf = vFront + vRes / 2 - vr / 2;
int vb = vBack + vRes / 2 - (vr - vr / 2);
long pc = long(pixelClock * f);
return Mode(hf, hs, hb, hr, vf, vSync, vb, vr, vd, pc, hSyncPolarity, vSyncPolarity);
}
template<class Output>
void print(Output &output) const
{
output.print("hFront: ");
output.println(hFront);
output.print("hSync: ");
output.println(hSync);
output.print("hBack: ");
output.println(hBack);
output.print("hRes: ");
output.println(hRes);
output.print("vFront: ");
output.println(vFront);
output.print("vSync: ");
output.println(vSync);
output.print("vBack: ");
output.println(vBack);
output.print("vRes: ");
output.println(vRes);
output.print("vDiv: ");
output.println(vDiv);
output.print("pixelClock: ");
output.println(pixelClock);
output.print("hSyncPolarity: ");
output.println(hSyncPolarity);
output.print("vSyncPolarity: ");
output.println(vSyncPolarity);
}
};

View file

@ -0,0 +1,102 @@
/*
Author: bitluni 2019
License:
Creative Commons Attribution ShareAlike 4.0
https://creativecommons.org/licenses/by-sa/4.0/
For further details check out:
https://youtube.com/bitlunislab
https://github.com/bitluni
http://bitluni.net
*/
#pragma once
class PinConfig
{
public:
int r0, r1, r2, r3, r4;
int g0, g1, g2, g3, g4;
int b0, b1, b2, b3;
int hSync, vSync, clock;
PinConfig(
const int r0 = -1,
const int r1 = -1,
const int r2 = -1,
const int r3 = -1,
const int r4 = -1,
const int g0 = -1,
const int g1 = -1,
const int g2 = -1,
const int g3 = -1,
const int g4 = -1,
const int b0 = -1,
const int b1 = -1,
const int b2 = -1,
const int b3 = -1,
const int hSync = -1,
const int vSync = -1,
const int clock = -1)
: r0(r0),
r1(r1),
r2(r2),
r3(r3),
r4(r4),
g0(g0),
g1(g1),
g2(g2),
g3(g3),
g4(g4),
b0(b0),
b1(b1),
b2(b2),
b3(b3),
hSync(hSync),
vSync(vSync),
clock(clock)
{
}
void fill3Bit(int *pins) const
{
pins[0] = r4;
pins[1] = g4;
pins[2] = b3;
pins[3] = -1;
pins[4] = -1;
pins[5] = -1;
pins[6] = hSync;
pins[7] = vSync;
}
void fill6Bit(int *pins) const
{
pins[0] = r3;
pins[1] = r4;
pins[2] = g3;
pins[3] = g4;
pins[4] = b2;
pins[5] = b3;
pins[6] = hSync;
pins[7] = vSync;
}
void fill14Bit(int *pins) const
{
pins[0] = r0;
pins[1] = r1;
pins[2] = r2;
pins[3] = r3;
pins[4] = r4;
pins[5] = g0;
pins[6] = g1;
pins[7] = g2;
pins[8] = g3;
pins[9] = g4;
pins[10] = b0;
pins[11] = b1;
pins[12] = b2;
pins[13] = b3;
pins[14] = hSync;
pins[15] = vSync;
}
};

View file

@ -0,0 +1,225 @@
/*
Author: bitluni 2019
License:
Creative Commons Attribution ShareAlike 4.0
https://creativecommons.org/licenses/by-sa/4.0/
For further details check out:
https://youtube.com/bitlunislab
https://github.com/bitluni
http://bitluni.net
*/
#include "VGA.h"
//hfront hsync hback pixels vfront vsync vback lines divy pixelclock hpolaritynegative vpolaritynegative
const Mode VGA::MODE320x480(8, 48, 24, 320, 11, 2, 31, 480, 1, 12587500, 1, 1);
const Mode VGA::MODE320x240(8, 48, 24, 320, 11, 2, 31, 480, 2, 12587500, 1, 1);
const Mode VGA::MODE320x400(8, 48, 24, 320, 12, 2, 35, 400, 1, 12587500, 1, 0);
const Mode VGA::MODE320x200(8, 48, 24, 320, 12, 2, 35, 400, 2, 12587500, 1, 0);
const Mode VGA::MODE360x400(8, 54, 28, 360, 11, 2, 32, 400, 1, 14161000, 1, 0);
const Mode VGA::MODE360x200(8, 54, 28, 360, 11, 2, 32, 400, 2, 14161000, 1, 0);
const Mode VGA::MODE360x350(8, 54, 28, 360, 11, 2, 32, 350, 1, 14161000, 1, 1);
const Mode VGA::MODE360x175 (8, 54, 28, 360, 11, 2, 32, 350, 2, 14161000, 1, 1);
const Mode VGA::MODE320x350 (8, 48, 24, 320, 37, 2, 60, 350, 1, 12587500, 0, 1);
const Mode VGA::MODE320x175(8, 48, 24, 320, 37, 2, 60, 350, 2, 12587500, 0, 1);
const Mode VGA::MODE400x300(12, 36, 64, 400, 1, 2, 22, 600, 2, 18000000, 0, 0);
const Mode VGA::MODE400x150(12, 36, 64, 400, 1, 2, 22, 600, 4, 18000000, 0, 0);
const Mode VGA::MODE400x100(12, 36, 64, 400, 1, 2, 22, 600, 6, 18000000, 0, 0);
const Mode VGA::MODE200x150(6, 18, 32, 200, 1, 2, 22, 600, 4, 9000000, 0, 0);
//const Mode VGA::MODE200x150(10, 32, 22, 200, 1, 4, 23, 600, 4, 10000000, 0, 0); //60Hz version
//500 pixels horizontal it's based on 640x480
const Mode VGA::MODE500x480(12, 76, 38, 500, 11, 2, 31, 480, 1, 19667968, 1, 1);
const Mode VGA::MODE500x240(12, 76, 38, 500, 11, 2, 31, 480, 2, 19667968, 1, 1);
//base modes for custom mode calculations
const Mode VGA::MODE1280x1024(48, 112, 248, 1280, 1, 3, 38, 1024, 1, 108000000, 0, 0);
const Mode VGA::MODE1280x960(80, 136, 216, 1280, 1, 3, 30, 960, 1, 101200000, 1, 0);
const Mode VGA::MODE1280x800(64, 136, 200, 1280, 1, 3, 24, 800, 1, 83640000, 1, 0);
const Mode VGA::MODE1024x768(24, 136, 160, 1024, 3, 6, 29, 768, 1, 65000000, 1, 1);
const Mode VGA::MODE800x600(24, 72, 128, 800, 1, 2, 22, 600, 1, 36000000, 0, 0);
const Mode VGA::MODE720x400(16, 108, 56, 720, 11, 2, 32, 400, 1, 28322000, 1, 0);
const Mode VGA::MODE720x350(16, 108, 56, 720, 11, 2, 32, 350, 1, 28322000, 1, 1);
const Mode VGA::MODE640x480(16, 96, 48, 640, 11, 2, 31, 480, 1, 25175000, 1, 1);
const Mode VGA::MODE640x400(16, 96, 48, 640, 12, 2, 35, 400, 1, 25175000, 1, 0);
const Mode VGA::MODE640x350(16, 96, 48, 640, 37, 2, 60, 350, 1, 25175000, 0, 1);
const PinConfig VGA::VGAv01(2, 4, 12, 13, 14, 15, 16, 17, 18, 19, 21, 22, 23, 27, 32, 33, -1);
const PinConfig VGA::VGABlackEdition(2, 4, 12, 13, 14, 15, 16, 17, 18, 19, 21, 22, 23, 27, 32, 33, -1);
const PinConfig VGA::VGAWhiteEdition(5, 14, 13, 15, 2, 19, 18, 17, 4, 16, 27, 22, 12, 21, 32, 33, -1);
const PinConfig VGA::PicoVGA(-1, -1, -1, 18, 5, -1, -1, -1, 14, 4, -1, -1, 27, 15, 32, 33, -1);
VGA::VGA(const int i2sIndex)
: I2S(i2sIndex)
{
lineBufferCount = 8;
dmaBufferDescriptors = 0;
}
bool VGA::init(const Mode &mode, const int *pinMap, const int bitCount, const int clockPin)
{
this->mode = mode;
int xres = mode.hRes;
int yres = mode.vRes / mode.vDiv;
initSyncBits();
propagateResolution(xres, yres);
this->vsyncPin = vsyncPin;
this->hsyncPin = hsyncPin;
totalLines = mode.linesPerField();
allocateLineBuffers();
currentLine = 0;
vSyncPassed = false;
initParallelOutputMode(pinMap, mode.pixelClock, bitCount, clockPin);
startTX();
return true;
}
void VGA::setLineBufferCount(int lineBufferCount)
{
this->lineBufferCount = lineBufferCount;
}
void VGA::allocateLineBuffers()
{
allocateLineBuffers(lineBufferCount);
}
/// simple ringbuffer of blocks of size bytes each
void VGA::allocateLineBuffers(const int lines)
{
dmaBufferDescriptorCount = lines;
dmaBufferDescriptors = DMABufferDescriptor::allocateDescriptors(dmaBufferDescriptorCount);
int bytes = (mode.hFront + mode.hSync + mode.hBack + mode.hRes) * bytesPerSample();
for (int i = 0; i < dmaBufferDescriptorCount; i++)
{
dmaBufferDescriptors[i].setBuffer(DMABufferDescriptor::allocateBuffer(bytes, true), bytes); //front porch + hsync + back porch + pixels
if (i)
dmaBufferDescriptors[i - 1].next(dmaBufferDescriptors[i]);
}
dmaBufferDescriptors[dmaBufferDescriptorCount - 1].next(dmaBufferDescriptors[0]);
}
///complete ringbuffer from frame
void VGA::allocateLineBuffers(void **frameBuffer)
{
dmaBufferDescriptorCount = totalLines * 2;
int inactiveSamples = (mode.hFront + mode.hSync + mode.hBack + 3) & 0xfffffffc;
vSyncInactiveBuffer = DMABufferDescriptor::allocateBuffer(inactiveSamples * bytesPerSample(), true);
vSyncActiveBuffer = DMABufferDescriptor::allocateBuffer(mode.hRes * bytesPerSample(), true);
inactiveBuffer = DMABufferDescriptor::allocateBuffer(inactiveSamples * bytesPerSample(), true);
blankActiveBuffer = DMABufferDescriptor::allocateBuffer(mode.hRes * bytesPerSample(), true);
if(bytesPerSample() == 1)
{
for (int i = 0; i < inactiveSamples; i++)
{
if (i >= mode.hFront && i < mode.hFront + mode.hSync)
{
((unsigned char *)vSyncInactiveBuffer)[i ^ 2] = hsyncBit | vsyncBit;
((unsigned char *)inactiveBuffer)[i ^ 2] = hsyncBit | vsyncBitI;
}
else
{
((unsigned char *)vSyncInactiveBuffer)[i ^ 2] = hsyncBitI | vsyncBit;
((unsigned char *)inactiveBuffer)[i ^ 2] = hsyncBitI | vsyncBitI;
}
}
for (int i = 0; i < mode.hRes; i++)
{
((unsigned char *)vSyncActiveBuffer)[i ^ 2] = hsyncBitI | vsyncBit;
((unsigned char *)blankActiveBuffer)[i ^ 2] = hsyncBitI | vsyncBitI;
}
}
else if(bytesPerSample() == 2)
{
for (int i = 0; i < inactiveSamples; i++)
{
if (i >= mode.hFront && i < mode.hFront + mode.hSync)
{
((unsigned short *)vSyncInactiveBuffer)[i ^ 1] = hsyncBit | vsyncBit;
((unsigned short *)inactiveBuffer)[i ^ 1] = hsyncBit | vsyncBitI;
}
else
{
((unsigned short *)vSyncInactiveBuffer)[i ^ 1] = hsyncBitI | vsyncBit;
((unsigned short *)inactiveBuffer)[i ^ 1] = hsyncBitI | vsyncBitI;
}
}
for (int i = 0; i < mode.hRes; i++)
{
((unsigned short *)vSyncActiveBuffer)[i ^ 1] = hsyncBitI | vsyncBit;
((unsigned short *)blankActiveBuffer)[i ^ 1] = hsyncBitI | vsyncBitI;
}
}
dmaBufferDescriptors = DMABufferDescriptor::allocateDescriptors(dmaBufferDescriptorCount);
for (int i = 0; i < dmaBufferDescriptorCount; i++)
dmaBufferDescriptors[i].next(dmaBufferDescriptors[(i + 1) % dmaBufferDescriptorCount]);
int d = 0;
for (int i = 0; i < mode.vFront; i++)
{
dmaBufferDescriptors[d++].setBuffer(inactiveBuffer, inactiveSamples * bytesPerSample());
dmaBufferDescriptors[d++].setBuffer(blankActiveBuffer, mode.hRes * bytesPerSample());
}
for (int i = 0; i < mode.vSync; i++)
{
dmaBufferDescriptors[d++].setBuffer(vSyncInactiveBuffer, inactiveSamples * bytesPerSample());
dmaBufferDescriptors[d++].setBuffer(vSyncActiveBuffer, mode.hRes * bytesPerSample());
}
for (int i = 0; i < mode.vBack; i++)
{
dmaBufferDescriptors[d++].setBuffer(inactiveBuffer, inactiveSamples * bytesPerSample());
dmaBufferDescriptors[d++].setBuffer(blankActiveBuffer, mode.hRes * bytesPerSample());
}
for (int i = 0; i < mode.vRes; i++)
{
dmaBufferDescriptors[d++].setBuffer(inactiveBuffer, inactiveSamples * bytesPerSample());
dmaBufferDescriptors[d++].setBuffer(frameBuffer[i / mode.vDiv], mode.hRes * bytesPerSample());
}
}
void VGA::vSync()
{
vSyncPassed = true;
}
void VGA::interrupt()
{
unsigned long *signal = (unsigned long *)dmaBufferDescriptors[dmaBufferDescriptorActive].buffer();
unsigned long *pixels = &((unsigned long *)dmaBufferDescriptors[dmaBufferDescriptorActive].buffer())[(mode.hSync + mode.hBack) / 2];
unsigned long base, baseh;
if (currentLine >= mode.vFront && currentLine < mode.vFront + mode.vSync)
{
baseh = (vsyncBit | hsyncBit) | ((vsyncBit | hsyncBit) << 16);
base = (vsyncBit | hsyncBitI) | ((vsyncBit | hsyncBitI) << 16);
}
else
{
baseh = (vsyncBitI | hsyncBit) | ((vsyncBitI | hsyncBit) << 16);
base = (vsyncBitI | hsyncBitI) | ((vsyncBitI | hsyncBitI) << 16);
}
for (int i = 0; i < mode.hSync / 2; i++)
signal[i] = baseh;
for (int i = mode.hSync / 2; i < (mode.hSync + mode.hBack) / 2; i++)
signal[i] = base;
int y = (currentLine - mode.vFront - mode.vSync - mode.vBack) / mode.vDiv;
if (y >= 0 && y < mode.vRes)
interruptPixelLine(y, pixels, base);
else
for (int i = 0; i < mode.hRes / 2; i++)
{
pixels[i] = base | (base << 16);
}
for (int i = 0; i < mode.hFront / 2; i++)
signal[i + (mode.hSync + mode.hBack + mode.hRes) / 2] = base;
currentLine = (currentLine + 1) % totalLines;
dmaBufferDescriptorActive = (dmaBufferDescriptorActive + 1) % dmaBufferDescriptorCount;
if (currentLine == 0)
vSync();
}
void VGA::interruptPixelLine(int y, unsigned long *pixels, unsigned long syncBits)
{
}

View file

@ -0,0 +1,99 @@
/*
Author: bitluni 2019
License:
Creative Commons Attribution ShareAlike 4.0
https://creativecommons.org/licenses/by-sa/4.0/
For further details check out:
https://youtube.com/bitlunislab
https://github.com/bitluni
http://bitluni.net
*/
#pragma once
#include "../I2S/I2S.h"
#include "Mode.h"
#include "PinConfig.h"
class VGA : public I2S
{
public:
VGA(const int i2sIndex = 0);
void setLineBufferCount(int lineBufferCount);
bool init(const Mode &mode, const int *pinMap, const int bitCount, const int clockPin = -1);
virtual bool init(const Mode &mode, const PinConfig &pinConfig) = 0;
static const Mode MODE320x480;
static const Mode MODE320x240;
static const Mode MODE320x120;
static const Mode MODE320x400;
static const Mode MODE320x200;
static const Mode MODE360x400;
static const Mode MODE360x200;
static const Mode MODE360x350;
static const Mode MODE360x175;
static const Mode MODE320x350;
static const Mode MODE320x175;
static const Mode MODE400x300;
static const Mode MODE400x150;
static const Mode MODE400x100;
static const Mode MODE200x150;
static const Mode MODE500x480;
static const Mode MODE500x240;
static const Mode MODE1280x1024;
static const Mode MODE1280x960;
static const Mode MODE1280x800;
static const Mode MODE1024x768;
static const Mode MODE800x600;
static const Mode MODE720x400;
static const Mode MODE720x350;
static const Mode MODE640x480;
static const Mode MODE640x400;
static const Mode MODE640x350;
static const PinConfig VGAv01;
static const PinConfig VGABlackEdition;
static const PinConfig VGAWhiteEdition;
static const PinConfig PicoVGA;
Mode mode;
virtual int bytesPerSample() const = 0;
protected:
virtual void initSyncBits() = 0;
virtual long syncBits(bool h, bool v) = 0;
int lineBufferCount;
int vsyncPin;
int hsyncPin;
int currentLine;
long vsyncBit;
long hsyncBit;
long vsyncBitI;
long hsyncBitI;
int totalLines;
volatile bool vSyncPassed;
void *vSyncInactiveBuffer;
void *vSyncActiveBuffer;
void *inactiveBuffer;
void *blankActiveBuffer;
void allocateLineBuffers(const int lines);
virtual void allocateLineBuffers();
virtual void allocateLineBuffers(void **frameBuffer);
virtual void propagateResolution(const int xres, const int yres) = 0;
protected:
virtual void interrupt();
virtual void vSync();
virtual void interruptPixelLine(int y, unsigned long *pixels, unsigned long syncBits);
};

View file

@ -0,0 +1,126 @@
/*
Author: bitluni 2019
License:
Creative Commons Attribution ShareAlike 4.0
https://creativecommons.org/licenses/by-sa/4.0/
For further details check out:
https://youtube.com/bitlunislab
https://github.com/bitluni
http://bitluni.net
*/
#pragma once
#include "VGA.h"
#include "../Graphics/GraphicsR5G5B4S2Swapped.h"
class VGA14Bit : public VGA, public GraphicsR5G5B4S2Swapped
{
public:
VGA14Bit(const int i2sIndex = 1)
: VGA(i2sIndex)
{
}
bool init(Mode &mode,
const int R0Pin, const int R1Pin, const int R2Pin, const int R3Pin, const int R4Pin,
const int G0Pin, const int G1Pin, const int G2Pin, const int G3Pin, const int G4Pin,
const int B0Pin, const int B1Pin, const int B2Pin, const int B3Pin,
const int hsyncPin, const int vsyncPin, const int clockPin = -1)
{
int pinMap[16] = {
R0Pin, R1Pin, R2Pin, R3Pin, R4Pin,
G0Pin, G1Pin, G2Pin, G3Pin, G4Pin,
B0Pin, B1Pin, B2Pin, B3Pin,
hsyncPin, vsyncPin
};
return VGA::init(mode, pinMap, 16, clockPin);
}
bool init(const Mode &mode, const int *redPins, const int *greenPins, const int *bluePins, const int hsyncPin, const int vsyncPin, const int clockPin = -1)
{
int pinMap[16];
for (int i = 0; i < 5; i++)
{
pinMap[i] = redPins[i];
pinMap[i + 5] = greenPins[i];
if (i < 4)
pinMap[i + 10] = bluePins[i];
}
pinMap[14] = hsyncPin;
pinMap[15] = vsyncPin;
return VGA::init(mode, pinMap, 16, clockPin);
}
bool init(const Mode &mode, const PinConfig &pinConfig)
{
int pins[16];
pinConfig.fill14Bit(pins);
return VGA::init(mode, pins, 16, pinConfig.clock);
}
virtual void initSyncBits()
{
hsyncBitI = mode.hSyncPolarity ? 0x4000 : 0;
vsyncBitI = mode.vSyncPolarity ? 0x8000 : 0;
hsyncBit = hsyncBitI ^ 0x4000;
vsyncBit = vsyncBitI ^ 0x8000;
SBits = hsyncBitI | vsyncBitI;
}
virtual long syncBits(bool hSync, bool vSync)
{
return ((hSync ? hsyncBit : hsyncBitI) | (vSync ? vsyncBit : vsyncBitI)) * 0x10001;
}
virtual int bytesPerSample() const
{
return 2;
}
virtual float pixelAspect() const
{
return 1;
}
virtual void propagateResolution(const int xres, const int yres)
{
setResolution(xres, yres);
}
virtual Color **allocateFrameBuffer()
{
return (Color **)DMABufferDescriptor::allocateDMABufferArray(yres, mode.hRes * bytesPerSample(), true, syncBits(false, false));
}
virtual void allocateLineBuffers()
{
VGA::allocateLineBuffers((void **)frameBuffers[0]);
}
virtual void show(bool vSync = false)
{
if (!frameBufferCount)
return;
if (vSync)
{
//TODO read the I2S docs to find out
}
Graphics::show(vSync);
if(dmaBufferDescriptors)
for (int i = 0; i < yres * mode.vDiv; i++)
dmaBufferDescriptors[(mode.vFront + mode.vSync + mode.vBack + i) * 2 + 1].setBuffer(frontBuffer[i / mode.vDiv], mode.hRes * bytesPerSample());
}
virtual void scroll(int dy, Color color)
{
Graphics::scroll(dy, color);
if (frameBufferCount == 1)
show();
}
protected:
virtual void interrupt()
{
}
};

View file

@ -0,0 +1,117 @@
/*
Author: bitluni 2019
License:
Creative Commons Attribution ShareAlike 4.0
https://creativecommons.org/licenses/by-sa/4.0/
For further details check out:
https://youtube.com/bitlunislab
https://github.com/bitluni
http://bitluni.net
*/
#pragma once
#include "VGA.h"
#include "../Graphics/GraphicsR5G5B4A2.h"
class VGA14BitI : public VGA, public GraphicsR5G5B4A2
{
public:
VGA14BitI(const int i2sIndex = 1)
: VGA(i2sIndex)
{
}
bool init(const Mode &mode,
const int R0Pin, const int R1Pin, const int R2Pin, const int R3Pin, const int R4Pin,
const int G0Pin, const int G1Pin, const int G2Pin, const int G3Pin, const int G4Pin,
const int B0Pin, const int B1Pin, const int B2Pin, const int B3Pin,
const int hsyncPin, const int vsyncPin, const int clockPin = -1)
{
int pinMap[16] = {
R0Pin, R1Pin, R2Pin, R3Pin, R4Pin,
G0Pin, G1Pin, G2Pin, G3Pin, G4Pin,
B0Pin, B1Pin, B2Pin, B3Pin,
hsyncPin, vsyncPin
};
return VGA::init(mode, pinMap, 16, clockPin);
}
bool init(const Mode &mode, const PinConfig &pinConfig)
{
int pins[16];
pinConfig.fill14Bit(pins);
return VGA::init(mode, pins, 16, pinConfig.clock);
}
bool init(const Mode &mode, const int *redPins, const int *greenPins, const int *bluePins, const int hsyncPin, const int vsyncPin, const int clockPin = -1)
{
int pinMap[16];
for (int i = 0; i < 5; i++)
{
pinMap[i] = redPins[i];
pinMap[i + 5] = greenPins[i];
if (i < 4)
pinMap[i + 10] = bluePins[i];
}
pinMap[14] = hsyncPin;
pinMap[15] = vsyncPin;
return VGA::init(mode, pinMap, 16, clockPin);
}
virtual void initSyncBits()
{
hsyncBitI = mode.hSyncPolarity ? 0x4000 : 0;
vsyncBitI = mode.vSyncPolarity ? 0x8000 : 0;
hsyncBit = hsyncBitI ^ 0x4000;
vsyncBit = vsyncBitI ^ 0x8000;
}
virtual long syncBits(bool hSync, bool vSync)
{
return ((hSync ? hsyncBit : hsyncBitI) | (vSync ? vsyncBit : vsyncBitI)) * 0x10001;
}
virtual int bytesPerSample() const
{
return 2;
}
virtual float pixelAspect() const
{
return 1;
}
virtual void propagateResolution(const int xres, const int yres)
{
setResolution(xres, yres);
}
virtual void show(bool vSync = false)
{
if (!frameBufferCount)
return;
if (vSync)
{
vSyncPassed = false;
while (!vSyncPassed)
delay(0);
}
Graphics::show(vSync);
}
protected:
virtual bool useInterrupt()
{
return true;
};
void interruptPixelLine(int y, unsigned long *pixels, unsigned long syncBits)
{
unsigned short *line = frontBuffer[y];
for (int i = 0; i < mode.hRes / 2; i++)
{
//writing two pixels improves speed drastically (avoids memory reads)
pixels[i] = syncBits | (line[i * 2 + 1] & 0x3fff) | ((line[i * 2] & 0x3fff) << 16);
}
}
};

View file

@ -0,0 +1,114 @@
/*
Author: bitluni 2019
License:
Creative Commons Attribution ShareAlike 4.0
https://creativecommons.org/licenses/by-sa/4.0/
For further details check out:
https://youtube.com/bitlunislab
https://github.com/bitluni
http://bitluni.net
*/
#pragma once
#include "VGA.h"
#include "../Graphics/GraphicsR1G1B1A1X2S2Swapped.h"
class VGA3Bit : public VGA, public GraphicsR1G1B1A1X2S2Swapped
{
public:
VGA3Bit() //8 bit based modes only work with I2S1
: VGA(1)
{
}
bool init(const Mode &mode, const int RPin, const int GPin, const int BPin, const int hsyncPin, const int vsyncPin, const int clockPin = -1)
{
int pinMap[8] = {
RPin,
GPin,
BPin,
-1, -1, -1,
hsyncPin, vsyncPin
};
return VGA::init(mode, pinMap, 8, clockPin);
}
bool init(const Mode &mode, const PinConfig &pinConfig)
{
int pins[8];
pinConfig.fill3Bit(pins);
return VGA::init(mode, pins, 8, pinConfig.clock);
}
virtual void initSyncBits()
{
hsyncBitI = mode.hSyncPolarity ? 0x40 : 0;
vsyncBitI = mode.vSyncPolarity ? 0x80 : 0;
hsyncBit = hsyncBitI ^ 0x40;
vsyncBit = vsyncBitI ^ 0x80;
SBits = hsyncBitI | vsyncBitI;
}
virtual long syncBits(bool hSync, bool vSync)
{
return ((hSync ? hsyncBit : hsyncBitI) | (vSync ? vsyncBit : vsyncBitI)) * 0x1010101;
}
virtual int bytesPerSample() const
{
return 1;
}
virtual float pixelAspect() const
{
return 1;
}
virtual void propagateResolution(const int xres, const int yres)
{
setResolution(xres, yres);
}
void *vSyncInactiveBuffer;
void *vSyncActiveBuffer;
void *inactiveBuffer;
void *blankActiveBuffer;
virtual Color **allocateFrameBuffer()
{
return (Color **)DMABufferDescriptor::allocateDMABufferArray(yres, mode.hRes * bytesPerSample(), true, syncBits(false, false));
}
virtual void allocateLineBuffers()
{
VGA::allocateLineBuffers((void **)frameBuffers[0]);
}
virtual void show(bool vSync = false)
{
if (!frameBufferCount)
return;
if (vSync)
{
//TODO read the I2S docs to find out
}
Graphics::show(vSync);
if(dmaBufferDescriptors)
for (int i = 0; i < yres * mode.vDiv; i++)
dmaBufferDescriptors[(mode.vFront + mode.vSync + mode.vBack + i) * 2 + 1].setBuffer(frontBuffer[i / mode.vDiv], mode.hRes * bytesPerSample());
}
virtual void scroll(int dy, Color color)
{
Graphics::scroll(dy, color);
if (frameBufferCount == 1)
show();
}
protected:
virtual void interrupt()
{
}
};

View file

@ -0,0 +1,139 @@
/*
Author: bitluni 2019
License:
Creative Commons Attribution ShareAlike 4.0
https://creativecommons.org/licenses/by-sa/4.0/
For further details check out:
https://youtube.com/bitlunislab
https://github.com/bitluni
http://bitluni.net
*/
#pragma once
#include "VGA.h"
#include "../Graphics/GraphicsR1G1B1A1.h"
class VGA3BitI : public VGA, public GraphicsR1G1B1A1
{
public:
VGA3BitI() //8 bit based modes only work with I2S1
: VGA(1)
{
}
bool init(const Mode &mode, const int RPin, const int GPin, const int BPin, const int hsyncPin, const int vsyncPin, const int clockPin = -1)
{
int pinMap[8] = {
RPin,
GPin,
BPin,
-1, -1, -1,
hsyncPin, vsyncPin
};
return VGA::init(mode, pinMap, 8, clockPin);
}
bool init(const Mode &mode, const PinConfig &pinConfig)
{
int pins[8];
pinConfig.fill3Bit(pins);
return VGA::init(mode, pins, 8, pinConfig.clock);
}
virtual void initSyncBits()
{
hsyncBitI = mode.hSyncPolarity ? 0x40 : 0;
vsyncBitI = mode.vSyncPolarity ? 0x80 : 0;
hsyncBit = hsyncBitI ^ 0x40;
vsyncBit = vsyncBitI ^ 0x80;
}
virtual long syncBits(bool hSync, bool vSync)
{
return ((hSync ? hsyncBit : hsyncBitI) | (vSync ? vsyncBit : vsyncBitI)) * 0x1010101;
}
virtual int bytesPerSample() const
{
return 1;
}
virtual float pixelAspect() const
{
return 1;
}
virtual void propagateResolution(const int xres, const int yres)
{
setResolution(xres, yres);
}
virtual void show(bool vSync = false)
{
if (!frameBufferCount)
return;
if (vSync)
{
vSyncPassed = false;
while (!vSyncPassed)
delay(0);
}
Graphics::show(vSync);
}
protected:
bool useInterrupt()
{
return true;
};
void interrupt()
{
unsigned long *signal = (unsigned long *)dmaBufferDescriptors[dmaBufferDescriptorActive].buffer();
unsigned long *pixels = &((unsigned long *)dmaBufferDescriptors[dmaBufferDescriptorActive].buffer())[(mode.hSync + mode.hBack) / 4];
unsigned long base, baseh;
if (currentLine >= mode.vFront && currentLine < mode.vFront + mode.vSync)
{
baseh = syncBits(true, true);
base = syncBits(false, true);
}
else
{
baseh = syncBits(true, false);
base = syncBits(false, false);
}
for (int i = 0; i < mode.hSync / 4; i++)
signal[i] = baseh;
for (int i = mode.hSync / 4; i < (mode.hSync + mode.hBack) / 4; i++)
signal[i] = base;
int y = (currentLine - mode.vFront - mode.vSync - mode.vBack) / mode.vDiv;
if (y >= 0 && y < mode.vRes)
interruptPixelLine(y, pixels, base);
else
for (int i = 0; i < mode.hRes / 4; i++)
{
pixels[i] = base;
}
for (int i = 0; i < mode.hFront / 4; i++)
signal[i + (mode.hSync + mode.hBack + mode.hRes) / 4] = base;
currentLine = (currentLine + 1) % totalLines;
dmaBufferDescriptorActive = (dmaBufferDescriptorActive + 1) % dmaBufferDescriptorCount;
if (currentLine == 0)
vSync();
}
void interruptPixelLine(int y, unsigned long *pixels, unsigned long syncBits)
{
unsigned char *line = frontBuffer[y];
int j = 0;
for (int i = 0; i < mode.hRes / 4; i++)
{
int p0 = (line[j] >> 0) & 7;
int p1 = (line[j++] >> 4) & 7;
int p2 = (line[j] >> 0) & 7;
int p3 = (line[j++] >> 4) & 7;
pixels[i] = syncBits | (p2 << 0) | (p3 << 8) | (p0 << 16) | (p1 << 24);
}
}
};

View file

@ -0,0 +1,131 @@
/*
Author: bitluni 2019
License:
Creative Commons Attribution ShareAlike 4.0
https://creativecommons.org/licenses/by-sa/4.0/
For further details check out:
https://youtube.com/bitlunislab
https://github.com/bitluni
http://bitluni.net
*/
#pragma once
#include "VGA.h"
#include "../Graphics/GraphicsR2G2B2S2Swapped.h"
class VGA6Bit : public VGA, public GraphicsR2G2B2S2Swapped
{
public:
VGA6Bit() //8 bit based modes only work with I2S1
: VGA(1)
{
}
bool init(Mode &mode,
const int R0Pin, const int R1Pin,
const int G0Pin, const int G1Pin,
const int B0Pin, const int B1Pin,
const int hsyncPin, const int vsyncPin, const int clockPin = -1)
{
int pinMap[8] = {
R0Pin, R1Pin,
G0Pin, G1Pin,
B0Pin, B1Pin,
hsyncPin, vsyncPin
};
return VGA::init(mode, pinMap, 8, clockPin);
}
bool init(const Mode &mode, const int *redPins, const int *greenPins, const int *bluePins, const int hsyncPin, const int vsyncPin, const int clockPin = -1)
{
int pinMap[8];
for (int i = 0; i < 2; i++)
{
pinMap[i] = redPins[i];
pinMap[i + 2] = greenPins[i];
pinMap[i + 4] = bluePins[i];
}
pinMap[6] = hsyncPin;
pinMap[7] = vsyncPin;
return VGA::init(mode, pinMap, 8, clockPin);
}
bool init(const Mode &mode, const PinConfig &pinConfig)
{
int pins[8];
pinConfig.fill6Bit(pins);
return VGA::init(mode, pins, 8, pinConfig.clock);
}
virtual void initSyncBits()
{
hsyncBitI = mode.hSyncPolarity ? 0x40 : 0;
vsyncBitI = mode.vSyncPolarity ? 0x80 : 0;
hsyncBit = hsyncBitI ^ 0x40;
vsyncBit = vsyncBitI ^ 0x80;
SBits = hsyncBitI | vsyncBitI;
}
virtual long syncBits(bool hSync, bool vSync)
{
return ((hSync ? hsyncBit : hsyncBitI) | (vSync ? vsyncBit : vsyncBitI)) * 0x1010101;
}
virtual int bytesPerSample() const
{
return 1;
}
virtual float pixelAspect() const
{
return 1;
}
virtual void propagateResolution(const int xres, const int yres)
{
setResolution(xres, yres);
}
void *vSyncInactiveBuffer;
void *vSyncActiveBuffer;
void *inactiveBuffer;
void *blankActiveBuffer;
virtual Color **allocateFrameBuffer()
{
return (Color **)DMABufferDescriptor::allocateDMABufferArray(yres, mode.hRes * bytesPerSample(), true, syncBits(false, false));
}
virtual void allocateLineBuffers()
{
VGA::allocateLineBuffers((void **)frameBuffers[0]);
}
virtual void show(bool vSync = false)
{
if (!frameBufferCount)
return;
if (vSync)
{
//TODO read the I2S docs to find out
}
Graphics::show(vSync);
if(dmaBufferDescriptors)
for (int i = 0; i < yres * mode.vDiv; i++)
dmaBufferDescriptors[(mode.vFront + mode.vSync + mode.vBack + i) * 2 + 1].setBuffer(frontBuffer[i / mode.vDiv], mode.hRes * bytesPerSample());
}
virtual void scroll(int dy, Color color)
{
Graphics::scroll(dy, color);
if (frameBufferCount == 1)
show();
}
protected:
virtual void interrupt()
{
}
};

View file

@ -0,0 +1,157 @@
/*
Author: bitluni 2019
License:
Creative Commons Attribution ShareAlike 4.0
https://creativecommons.org/licenses/by-sa/4.0/
For further details check out:
https://youtube.com/bitlunislab
https://github.com/bitluni
http://bitluni.net
*/
#pragma once
#include "VGA.h"
#include "../Graphics/GraphicsR2G2B2A2.h"
class VGA6BitI : public VGA, public GraphicsR2G2B2A2
{
public:
VGA6BitI() //8 bit based modes only work with I2S1
: VGA(1)
{
}
bool init(Mode &mode,
const int R0Pin, const int R1Pin,
const int G0Pin, const int G1Pin,
const int B0Pin, const int B1Pin,
const int hsyncPin, const int vsyncPin, const int clockPin = -1)
{
int pinMap[8] = {
R0Pin, R1Pin,
G0Pin, G1Pin,
B0Pin, B1Pin,
hsyncPin, vsyncPin
};
return VGA::init(mode, pinMap, 8, clockPin);
}
bool init(const Mode &mode, const int *redPins, const int *greenPins, const int *bluePins, const int hsyncPin, const int vsyncPin, const int clockPin = -1)
{
int pinMap[8];
for (int i = 0; i < 2; i++)
{
pinMap[i] = redPins[i];
pinMap[i + 2] = greenPins[i];
pinMap[i + 4] = bluePins[i];
}
pinMap[6] = hsyncPin;
pinMap[7] = vsyncPin;
return VGA::init(mode, pinMap, 8, clockPin);
}
bool init(const Mode &mode, const PinConfig &pinConfig)
{
int pins[8];
pinConfig.fill6Bit(pins);
return VGA::init(mode, pins, 8, pinConfig.clock);
}
virtual void initSyncBits()
{
hsyncBitI = mode.hSyncPolarity ? 0x40 : 0;
vsyncBitI = mode.vSyncPolarity ? 0x80 : 0;
hsyncBit = hsyncBitI ^ 0x40;
vsyncBit = vsyncBitI ^ 0x80;
}
virtual long syncBits(bool hSync, bool vSync)
{
return ((hSync ? hsyncBit : hsyncBitI) | (vSync ? vsyncBit : vsyncBitI)) * 0x1010101;
}
virtual int bytesPerSample() const
{
return 1;
}
virtual float pixelAspect() const
{
return 1;
}
virtual void propagateResolution(const int xres, const int yres)
{
setResolution(xres, yres);
}
virtual void show(bool vSync = false)
{
if (!frameBufferCount)
return;
if (vSync)
{
vSyncPassed = false;
while (!vSyncPassed)
delay(0);
}
Graphics::show(vSync);
}
protected:
bool useInterrupt()
{
return true;
};
void interrupt()
{
unsigned long *signal = (unsigned long *)dmaBufferDescriptors[dmaBufferDescriptorActive].buffer();
unsigned long *pixels = &((unsigned long *)dmaBufferDescriptors[dmaBufferDescriptorActive].buffer())[(mode.hSync + mode.hBack) / 4];
unsigned long base, baseh;
if (currentLine >= mode.vFront && currentLine < mode.vFront + mode.vSync)
{
baseh = syncBits(true, true);
base = syncBits(false, true);
}
else
{
baseh = syncBits(true, false);
base = syncBits(false, false);
}
for (int i = 0; i < mode.hSync / 4; i++)
signal[i] = baseh;
for (int i = mode.hSync / 4; i < (mode.hSync + mode.hBack) / 4; i++)
signal[i] = base;
int y = (currentLine - mode.vFront - mode.vSync - mode.vBack) / mode.vDiv;
if (y >= 0 && y < mode.vRes)
interruptPixelLine(y, pixels, base);
else
for (int i = 0; i < mode.hRes / 4; i++)
{
pixels[i] = base;
}
for (int i = 0; i < mode.hFront / 4; i++)
signal[i + (mode.hSync + mode.hBack + mode.hRes) / 4] = base;
currentLine = (currentLine + 1) % totalLines;
dmaBufferDescriptorActive = (dmaBufferDescriptorActive + 1) % dmaBufferDescriptorCount;
if (currentLine == 0)
vSync();
}
void interruptPixelLine(int y, unsigned long *pixels, unsigned long syncBits)
{
unsigned char *line = frontBuffer[y];
int j = 0;
for (int i = 0; i < mode.hRes / 4; i++)
{
int p0 = (line[j] >> 0) & 7;
int p1 = (line[j++] >> 4) & 7;
int p2 = (line[j] >> 0) & 7;
int p3 = (line[j++] >> 4) & 7;
pixels[i] = syncBits | (p2 << 0) | (p3 << 8) | (p0 << 16) | (p1 << 24);
}
}
};