2021-08-04 03:21:06 +00:00
|
|
|
|
import LZString from 'lz-string';
|
|
|
|
|
import store from './store';
|
|
|
|
|
|
|
|
|
|
// 0 => 'white',
|
|
|
|
|
// 1 => 'black',
|
|
|
|
|
// 2 => 'navy',
|
|
|
|
|
// 3 => 'green',
|
|
|
|
|
// 4 => 'red',
|
|
|
|
|
// 5 => 'brown',
|
|
|
|
|
// 6 => 'purple',
|
|
|
|
|
// 7 => 'olive',
|
|
|
|
|
// 8 => 'yellow', # dark yellow
|
|
|
|
|
// 9 => 'lime', # ltgreen
|
|
|
|
|
// 10 => 'teal',
|
|
|
|
|
// 11 => 'cyan',
|
|
|
|
|
// 12 => 'blue', # ltblue,
|
|
|
|
|
// 13 => 'fuchsia', # pink
|
|
|
|
|
// 14 => 'grey',
|
|
|
|
|
// 15 => 'lightgrey',
|
|
|
|
|
export const mircColours99 = [
|
|
|
|
|
'rgb(255,255,255)',
|
|
|
|
|
'rgb(0,0,0)',
|
|
|
|
|
'rgb(0,0,127)',
|
|
|
|
|
'rgb(0,147,0)',
|
|
|
|
|
'rgb(255,0,0)',
|
|
|
|
|
'rgb(127,0,0)',
|
|
|
|
|
'rgb(156,0,156)',
|
|
|
|
|
'rgb(252,127,0)',
|
|
|
|
|
'rgb(255,255,0)',
|
|
|
|
|
'rgb(0,252,0)',
|
|
|
|
|
'rgb(0,147,147)',
|
|
|
|
|
'rgb(0,255,255)',
|
|
|
|
|
'rgb(0,0,252)',
|
|
|
|
|
'rgb(255,0,255)',
|
|
|
|
|
'rgb(127,127,127)',
|
|
|
|
|
'rgb(210,210,210)',
|
2021-08-05 00:54:40 +00:00
|
|
|
|
|
|
|
|
|
"#470000",
|
|
|
|
|
"#472100",
|
|
|
|
|
"#474700",
|
|
|
|
|
"#324700",
|
|
|
|
|
"#004700",
|
|
|
|
|
"#00472c",
|
|
|
|
|
"#004747",
|
|
|
|
|
"#002747",
|
|
|
|
|
"#000047",
|
|
|
|
|
"#2e0047",
|
|
|
|
|
"#470047",
|
|
|
|
|
"#47002a",
|
|
|
|
|
"#740000",
|
|
|
|
|
"#743a00",
|
|
|
|
|
"#747400",
|
|
|
|
|
"#517400",
|
|
|
|
|
"#007400",
|
|
|
|
|
"#007449",
|
|
|
|
|
"#007474",
|
|
|
|
|
"#004074",
|
|
|
|
|
"#000074",
|
|
|
|
|
"#4b0074",
|
|
|
|
|
"#740074",
|
|
|
|
|
"#740045",
|
|
|
|
|
"#b50000",
|
|
|
|
|
"#b56300",
|
|
|
|
|
"#b5b500",
|
|
|
|
|
"#7db500",
|
|
|
|
|
"#00b500",
|
|
|
|
|
"#00b571",
|
|
|
|
|
"#00b5b5",
|
|
|
|
|
"#0063b5",
|
|
|
|
|
"#0000b5",
|
|
|
|
|
"#7500b5",
|
|
|
|
|
"#b500b5",
|
|
|
|
|
"#b5006b",
|
|
|
|
|
"#ff0000",
|
|
|
|
|
"#ff8c00",
|
|
|
|
|
"#ffff00",
|
|
|
|
|
"#b2ff00",
|
|
|
|
|
"#00ff00",
|
|
|
|
|
"#00ffa0",
|
|
|
|
|
"#00ffff",
|
|
|
|
|
"#008cff",
|
|
|
|
|
"#0000ff",
|
|
|
|
|
"#a500ff",
|
|
|
|
|
"#ff00ff",
|
|
|
|
|
"#ff0098",
|
|
|
|
|
"#ff5959",
|
|
|
|
|
"#ffb459",
|
|
|
|
|
"#ffff71",
|
|
|
|
|
"#cfff60",
|
|
|
|
|
"#6fff6f",
|
|
|
|
|
"#65ffc9",
|
|
|
|
|
"#6dffff",
|
|
|
|
|
"#59b4ff",
|
|
|
|
|
"#5959ff",
|
|
|
|
|
"#c459ff",
|
|
|
|
|
"#ff66ff",
|
|
|
|
|
"#ff59bc",
|
|
|
|
|
"#ff9c9c",
|
|
|
|
|
"#ffd39c",
|
|
|
|
|
"#ffff9c",
|
|
|
|
|
"#e2ff9c",
|
|
|
|
|
"#9cff9c",
|
|
|
|
|
"#9cffdb",
|
|
|
|
|
"#9cffff",
|
|
|
|
|
"#9cd3ff",
|
|
|
|
|
"#9c9cff",
|
|
|
|
|
"#dc9cff",
|
|
|
|
|
"#ff9cff",
|
|
|
|
|
"#ff94d3",
|
|
|
|
|
"#000000",
|
|
|
|
|
"#131313",
|
|
|
|
|
"#282828",
|
|
|
|
|
"#363636",
|
|
|
|
|
"#4d4d4d",
|
|
|
|
|
"#656565",
|
|
|
|
|
"#818181",
|
|
|
|
|
"#9f9f9f",
|
|
|
|
|
"#bcbcbc",
|
|
|
|
|
"#e2e2e2",
|
|
|
|
|
"#ffffff",
|
2021-08-04 03:21:06 +00:00
|
|
|
|
];
|
|
|
|
|
|
2021-08-12 01:52:40 +00:00
|
|
|
|
// How big the brush size can get
|
|
|
|
|
export const maxBrushSize = 15;
|
|
|
|
|
|
2021-08-05 05:30:53 +00:00
|
|
|
|
// Chars that end up in the toolbar
|
|
|
|
|
export const charCodes = [' ', '!', '"', '#', '$', '%', '&', '\'', '(', ')', '*', '+', ',', '-',
|
|
|
|
|
'.', '/',
|
|
|
|
|
'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', ':', ';', '<', '=', '>', '?', '@', 'A',
|
|
|
|
|
'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S',
|
|
|
|
|
'T', 'U', 'V', 'W', 'X', 'Y', 'Z', '[', '\\', ']', '^', '_', '`', 'a', 'b', 'c', 'd', 'e',
|
|
|
|
|
'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w',
|
|
|
|
|
'x', 'y', 'z', '{', '|', '}', '~', 'Ç', 'ü', 'é', 'â', 'ä', 'à', 'å', 'ç', 'ê', 'ë', 'è',
|
|
|
|
|
'ï', 'î', 'ì', 'Ä', 'Å', 'É', 'æ', 'Æ', 'ô', 'ö', 'ò', 'û', 'ù', 'ÿ', 'Ö', 'Ü', 'ø', '£',
|
|
|
|
|
'Ø', '×', 'ƒ', 'á', 'í', 'ó', 'ú', 'ñ', 'Ñ', 'ª', 'º', '¿', '®', '¬', '½', '¼', '¡', '«',
|
2021-08-23 01:51:45 +00:00
|
|
|
|
'»', 'Á', 'Â', 'À', '©', '¢', '¥', 'ã', 'Ã', '¤', 'ð', 'Ð', 'Ê', 'Ë', 'È', 'ı', 'Í', 'Î',
|
|
|
|
|
'Ï', '¦', 'Ì', 'Ó', 'ß', 'Ô', 'Ò', 'õ', 'Õ', 'µ', 'þ', 'Þ', 'Ú', 'Û', 'Ù', 'ý', 'Ý', '¸',
|
|
|
|
|
'°', '¨', '·', '¯', '´', '≡', '±', '‗', '¶', '§', '÷',
|
|
|
|
|
'⁰', '¹', '³', '²', '⁴', '⁵', '⁶', '⁷', '⁸', '⁹', '⁺', '⁻', '⁼', '⁽', '⁾',
|
|
|
|
|
'₀', '₁', '₂', '₃', '₄', '₅', '₆', '₇', '₈', '₉', '₊', '₋', '₌', '₍', '₎',
|
|
|
|
|
'¼', '½', '¾', '⅓', '⅔', '⅕', '⅖', '⅗', '⅘', '⅙', '⅚', '⅛', '⅜', '⅝', '⅞',
|
|
|
|
|
'└', '┐', '┘', '┌', '│', '┤', '├', '┴', '┬', '─', '┼',
|
|
|
|
|
'╚', '╗', '╝', '╔', '║', '╣', '╠', '╩', '╦', '═', '╬',
|
|
|
|
|
'╰', '╮', '╯', '╭', '╱', '╲', '╳',
|
|
|
|
|
'▘', '▖', '▝', '▗', '▚',
|
|
|
|
|
'▏', '▎', '▍', '▌', '▋', '▊', '▉',
|
|
|
|
|
'▁', '▂', '▃', '▄', '▅', '▆', '▇', '▀', '▔', '░', '▒', '▓', '█',
|
2021-08-05 05:30:53 +00:00
|
|
|
|
];
|
|
|
|
|
|
|
|
|
|
// Toolbar icons
|
|
|
|
|
export const toolbarIcons = [{
|
|
|
|
|
name: 'default',
|
|
|
|
|
icon: 'mouse-pointer',
|
|
|
|
|
fa: 'fas',
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
name: 'select',
|
|
|
|
|
icon: 'square',
|
|
|
|
|
fa: 'far',
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
name: 'text',
|
|
|
|
|
icon: 'font',
|
|
|
|
|
fa: 'fas',
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
name: 'fill',
|
|
|
|
|
icon: 'fill-drip',
|
|
|
|
|
fa: 'fas',
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
name: 'brush',
|
|
|
|
|
icon: 'paint-brush',
|
|
|
|
|
fa: 'fas',
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
name: 'dropper',
|
|
|
|
|
icon: 'eye-dropper',
|
|
|
|
|
fa: 'fas',
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
name: 'eraser',
|
|
|
|
|
icon: 'eraser',
|
|
|
|
|
fa: 'fas',
|
|
|
|
|
},
|
2021-08-11 23:47:36 +00:00
|
|
|
|
{
|
|
|
|
|
name: 'fill-eraser',
|
|
|
|
|
icon: 'fill',
|
|
|
|
|
fa: 'fas',
|
|
|
|
|
},
|
2021-08-05 05:30:53 +00:00
|
|
|
|
];
|
|
|
|
|
|
2021-08-04 03:21:06 +00:00
|
|
|
|
export const emptyBlock = {
|
|
|
|
|
bg: null,
|
|
|
|
|
fg: null,
|
|
|
|
|
char: null,
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
export const create2DArray = (rows) => {
|
|
|
|
|
const arr = [];
|
|
|
|
|
|
|
|
|
|
for (let i = 0; i < rows; i++) {
|
|
|
|
|
arr[i] = [];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return arr;
|
|
|
|
|
};
|
2021-07-17 01:44:27 +00:00
|
|
|
|
|
2021-08-05 00:54:40 +00:00
|
|
|
|
// Width and height of the ASCII blocks
|
|
|
|
|
// they seem to be 8x15 in asciiblaster
|
|
|
|
|
export const blockWidth = 8;
|
|
|
|
|
export const blockHeight = 15;
|
|
|
|
|
|
2021-08-19 01:08:36 +00:00
|
|
|
|
// Limits for undo and brush histories
|
|
|
|
|
export const maxBrushHistory = 50;
|
|
|
|
|
export const maxUndoHistory = 50;
|
|
|
|
|
|
2021-08-11 23:47:36 +00:00
|
|
|
|
export const parseMircAscii = async (content, title) => {
|
2021-08-04 02:47:17 +00:00
|
|
|
|
const MIRC_MAX_COLOURS = mircColours99.length;
|
|
|
|
|
|
|
|
|
|
// The current state of the Colours
|
|
|
|
|
let curBlock = {
|
2021-08-04 03:21:06 +00:00
|
|
|
|
...emptyBlock,
|
2021-08-04 02:47:17 +00:00
|
|
|
|
};
|
|
|
|
|
|
2021-08-04 03:21:06 +00:00
|
|
|
|
const contents = content;
|
|
|
|
|
const filename = title;
|
2021-08-04 02:47:17 +00:00
|
|
|
|
|
|
|
|
|
// set asciiImport as the entire file contents as a string
|
|
|
|
|
const asciiImport = contents
|
2021-08-04 03:21:06 +00:00
|
|
|
|
.split('\u0003\u0003')
|
|
|
|
|
.join('\u0003')
|
|
|
|
|
.split('\u000F').join('')
|
|
|
|
|
.split('\u0003\n')
|
|
|
|
|
.join('\n')
|
|
|
|
|
.split('\u0002\u0003')
|
|
|
|
|
.join('\u0003');
|
2021-08-04 02:47:17 +00:00
|
|
|
|
|
|
|
|
|
// This will end up in the asciibirdMeta
|
|
|
|
|
const finalAscii = {
|
|
|
|
|
title: filename,
|
2021-08-15 00:57:37 +00:00
|
|
|
|
// key: store.getters.nextTabValue,
|
|
|
|
|
// blockWidth: blockWidth * store.getters.blockSizeMultiplier,
|
|
|
|
|
// blockHeight: blockHeight * store.getters.blockSizeMultiplier,
|
2021-08-14 06:41:42 +00:00
|
|
|
|
blocks: [{
|
|
|
|
|
label: filename,
|
|
|
|
|
visible: true,
|
2021-08-15 00:57:37 +00:00
|
|
|
|
data: create2DArray(asciiImport.split('\n').length),
|
|
|
|
|
width: false, // defined in: switch (curChar) case "\n":
|
|
|
|
|
height: asciiImport.split('\n').length,
|
2021-08-14 06:41:42 +00:00
|
|
|
|
}],
|
2021-08-04 02:47:17 +00:00
|
|
|
|
history: [],
|
|
|
|
|
redo: [],
|
2021-08-05 00:54:40 +00:00
|
|
|
|
x: blockWidth * 35, // the dragable ascii canvas x
|
|
|
|
|
y: blockHeight * 2, // the dragable ascii canvas y
|
2021-08-14 06:41:42 +00:00
|
|
|
|
selectedLayer: 0,
|
2021-08-04 02:47:17 +00:00
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
// Turn the entire ascii string into an array
|
2021-08-04 03:21:06 +00:00
|
|
|
|
let asciiStringArray = asciiImport.split('');
|
|
|
|
|
const linesArray = asciiImport.split('\n');
|
2021-08-04 02:47:17 +00:00
|
|
|
|
|
|
|
|
|
// The proper X and Y value of the block inside the ASCII
|
|
|
|
|
let asciiX = 0;
|
|
|
|
|
let asciiY = 0;
|
|
|
|
|
|
|
|
|
|
// used to determine colours
|
|
|
|
|
let colourChar1 = null;
|
|
|
|
|
let colourChar2 = null;
|
|
|
|
|
let parsedColour = null;
|
|
|
|
|
|
|
|
|
|
// This variable just counts the amount of colour and char codes to minus
|
|
|
|
|
// to get the real width
|
|
|
|
|
let widthOfColCodes = 0;
|
|
|
|
|
|
|
|
|
|
// Better for colourful asciis
|
|
|
|
|
let maxWidthLoop = 0;
|
|
|
|
|
|
|
|
|
|
// Used before the loop, better for plain text
|
|
|
|
|
let maxWidthFound = 0;
|
|
|
|
|
|
|
|
|
|
for (let i = 0; i < linesArray.length; i++) {
|
|
|
|
|
if (linesArray[i].length > maxWidthFound) {
|
|
|
|
|
maxWidthFound = linesArray[i].length;
|
2021-07-17 01:44:27 +00:00
|
|
|
|
}
|
2021-08-04 02:47:17 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
while (asciiStringArray.length) {
|
|
|
|
|
const curChar = asciiStringArray[0];
|
|
|
|
|
|
|
|
|
|
// Defining a small finite state machine
|
|
|
|
|
// to detect the colour code
|
|
|
|
|
switch (curChar) {
|
2021-08-04 03:21:06 +00:00
|
|
|
|
case '\n':
|
2021-08-04 02:47:17 +00:00
|
|
|
|
// Reset the colours here on a new line
|
2021-08-04 03:21:06 +00:00
|
|
|
|
curBlock = {
|
|
|
|
|
...emptyBlock,
|
|
|
|
|
};
|
2021-08-04 02:47:17 +00:00
|
|
|
|
|
|
|
|
|
if (linesArray[asciiY] && linesArray[asciiY].length > maxWidthLoop) {
|
|
|
|
|
maxWidthLoop = linesArray[asciiY].length;
|
|
|
|
|
}
|
2021-07-17 01:44:27 +00:00
|
|
|
|
|
2021-08-04 02:47:17 +00:00
|
|
|
|
// the Y value of the ascii
|
|
|
|
|
asciiY++;
|
2021-07-17 01:44:27 +00:00
|
|
|
|
|
2021-08-04 02:47:17 +00:00
|
|
|
|
// Calculate widths mirc asciis vs plain text
|
2021-08-15 00:57:37 +00:00
|
|
|
|
if (!finalAscii.blocks[0].width && widthOfColCodes > 0) {
|
|
|
|
|
finalAscii.blocks[0].width = maxWidthLoop - widthOfColCodes;
|
2021-08-04 02:47:17 +00:00
|
|
|
|
}
|
2021-07-17 01:44:27 +00:00
|
|
|
|
|
2021-08-15 00:57:37 +00:00
|
|
|
|
if (!finalAscii.blocks[0].width && widthOfColCodes === 0) {
|
2021-08-04 02:47:17 +00:00
|
|
|
|
// Plain text
|
2021-08-15 00:57:37 +00:00
|
|
|
|
finalAscii.blocks[0].width = maxWidthFound;
|
2021-08-04 02:47:17 +00:00
|
|
|
|
}
|
2021-07-17 01:44:27 +00:00
|
|
|
|
|
2021-08-04 02:47:17 +00:00
|
|
|
|
// Resets the X value
|
|
|
|
|
asciiX = 0;
|
2021-07-17 01:44:27 +00:00
|
|
|
|
|
2021-08-04 02:47:17 +00:00
|
|
|
|
asciiStringArray.shift();
|
|
|
|
|
widthOfColCodes = 0;
|
|
|
|
|
break;
|
2021-07-17 01:44:27 +00:00
|
|
|
|
|
2021-08-04 03:21:06 +00:00
|
|
|
|
case '\u0003':
|
2021-08-04 02:47:17 +00:00
|
|
|
|
// Remove the colour char
|
|
|
|
|
asciiStringArray.shift();
|
|
|
|
|
widthOfColCodes++;
|
2021-07-17 01:44:27 +00:00
|
|
|
|
|
2021-08-04 02:47:17 +00:00
|
|
|
|
// Attempt to work out bg
|
|
|
|
|
colourChar1 = `${asciiStringArray[0]}`;
|
|
|
|
|
colourChar2 = `${asciiStringArray[1]}`;
|
|
|
|
|
parsedColour = parseInt(`${colourChar1}${colourChar2}`);
|
|
|
|
|
|
|
|
|
|
// Work out the 01, 02 double digit codes
|
|
|
|
|
if (parseInt(colourChar1) === 0 && parseInt(colourChar2) >= 0) {
|
|
|
|
|
asciiStringArray.shift();
|
|
|
|
|
}
|
2021-07-17 01:44:27 +00:00
|
|
|
|
|
2021-08-04 03:21:06 +00:00
|
|
|
|
if (Number.isNaN(parsedColour)) {
|
2021-08-04 02:47:17 +00:00
|
|
|
|
curBlock.bg = parseInt(colourChar1);
|
|
|
|
|
widthOfColCodes += 1;
|
2021-07-17 01:44:27 +00:00
|
|
|
|
asciiStringArray.shift();
|
2021-08-04 02:47:17 +00:00
|
|
|
|
} else if (parsedColour <= MIRC_MAX_COLOURS && parsedColour >= 0) {
|
|
|
|
|
curBlock.fg = parseInt(parsedColour);
|
|
|
|
|
widthOfColCodes += parsedColour.toString().length;
|
|
|
|
|
|
|
|
|
|
asciiStringArray = asciiStringArray.slice(
|
|
|
|
|
parsedColour.toString().length,
|
2021-08-04 03:21:06 +00:00
|
|
|
|
asciiStringArray.length,
|
2021-08-04 02:47:17 +00:00
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// No background colour
|
2021-08-04 03:21:06 +00:00
|
|
|
|
if (asciiStringArray[0] !== ',') {
|
2021-07-17 01:44:27 +00:00
|
|
|
|
break;
|
2021-08-04 02:47:17 +00:00
|
|
|
|
} else {
|
|
|
|
|
// Remove , from array
|
|
|
|
|
widthOfColCodes += 1;
|
|
|
|
|
asciiStringArray.shift();
|
|
|
|
|
}
|
2021-07-17 01:44:27 +00:00
|
|
|
|
|
2021-08-04 02:47:17 +00:00
|
|
|
|
// Attempt to work out bg
|
|
|
|
|
colourChar1 = `${asciiStringArray[0]}`;
|
|
|
|
|
colourChar2 = `${asciiStringArray[1]}`;
|
|
|
|
|
parsedColour = parseInt(`${colourChar1}${colourChar2}`);
|
|
|
|
|
|
|
|
|
|
if (
|
2021-08-05 05:30:53 +00:00
|
|
|
|
!Number.isNaN(colourChar1) &&
|
|
|
|
|
!Number.isNaN(colourChar2) &&
|
|
|
|
|
parseInt(colourChar2) > parseInt(colourChar1) &&
|
|
|
|
|
!Number.isNaN(parsedColour) &&
|
|
|
|
|
parseInt(parsedColour) < 10
|
2021-08-04 02:47:17 +00:00
|
|
|
|
) {
|
|
|
|
|
parsedColour = parseInt(colourChar2);
|
|
|
|
|
widthOfColCodes += 1;
|
2021-07-17 01:44:27 +00:00
|
|
|
|
asciiStringArray.shift();
|
2021-08-04 02:47:17 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (
|
2021-08-05 05:30:53 +00:00
|
|
|
|
parseInt(colourChar2) === parseInt(colourChar1) &&
|
|
|
|
|
parseInt(parsedColour) < 10
|
2021-08-04 02:47:17 +00:00
|
|
|
|
) {
|
|
|
|
|
parsedColour = parseInt(colourChar1);
|
|
|
|
|
asciiStringArray.shift();
|
|
|
|
|
asciiStringArray.shift();
|
|
|
|
|
widthOfColCodes += 2;
|
|
|
|
|
|
|
|
|
|
curBlock.bg = parseInt(colourChar1);
|
2021-07-17 01:44:27 +00:00
|
|
|
|
|
|
|
|
|
break;
|
2021-08-04 02:47:17 +00:00
|
|
|
|
}
|
2021-07-17 01:44:27 +00:00
|
|
|
|
|
2021-08-04 03:21:06 +00:00
|
|
|
|
if (Number.isNaN(parsedColour)) {
|
2021-08-04 02:47:17 +00:00
|
|
|
|
curBlock.bg = parseInt(colourChar1);
|
|
|
|
|
widthOfColCodes += 1;
|
2021-07-17 01:44:27 +00:00
|
|
|
|
asciiStringArray.shift();
|
2021-08-04 02:47:17 +00:00
|
|
|
|
} else if (parsedColour <= MIRC_MAX_COLOURS && parsedColour >= 0) {
|
|
|
|
|
curBlock.bg = parseInt(parsedColour);
|
|
|
|
|
widthOfColCodes += parsedColour.toString().length;
|
|
|
|
|
|
|
|
|
|
asciiStringArray = asciiStringArray.slice(
|
|
|
|
|
parsedColour.toString().length,
|
2021-08-04 03:21:06 +00:00
|
|
|
|
asciiStringArray.length,
|
2021-08-04 02:47:17 +00:00
|
|
|
|
);
|
2021-07-17 01:44:27 +00:00
|
|
|
|
|
|
|
|
|
break;
|
2021-08-04 02:47:17 +00:00
|
|
|
|
}
|
2021-07-17 01:44:27 +00:00
|
|
|
|
|
2021-08-04 02:47:17 +00:00
|
|
|
|
break;
|
2021-08-04 01:13:35 +00:00
|
|
|
|
|
2021-08-04 02:47:17 +00:00
|
|
|
|
default:
|
|
|
|
|
curBlock.char = curChar;
|
|
|
|
|
asciiStringArray.shift();
|
|
|
|
|
asciiX++;
|
2021-08-03 04:59:12 +00:00
|
|
|
|
|
2021-08-14 06:41:42 +00:00
|
|
|
|
finalAscii.blocks[0].data[asciiY][asciiX - 1] = {
|
2021-08-04 03:21:06 +00:00
|
|
|
|
...curBlock,
|
2021-08-04 02:47:17 +00:00
|
|
|
|
};
|
|
|
|
|
break;
|
|
|
|
|
} // End Switch
|
|
|
|
|
} // End loop charPos
|
2021-07-17 01:44:27 +00:00
|
|
|
|
|
2021-08-15 00:57:37 +00:00
|
|
|
|
finalAscii.blocks = [...fillNullBlocks(finalAscii.blocks[0].height, finalAscii.blocks[0]
|
|
|
|
|
.width, finalAscii.blocks)];
|
2021-08-15 00:15:36 +00:00
|
|
|
|
// Store the ASCII and ensure we have no null blocks
|
2021-08-04 02:47:17 +00:00
|
|
|
|
finalAscii.blocks = LZString.compressToUTF16(
|
2021-08-04 03:21:06 +00:00
|
|
|
|
JSON.stringify(finalAscii.blocks),
|
2021-08-04 02:47:17 +00:00
|
|
|
|
);
|
2021-07-17 01:44:27 +00:00
|
|
|
|
|
2021-08-04 02:47:17 +00:00
|
|
|
|
// We need to also store in the first undo history the original state
|
|
|
|
|
finalAscii.history.push(finalAscii.blocks);
|
2021-07-17 01:44:27 +00:00
|
|
|
|
|
2021-08-07 06:10:52 +00:00
|
|
|
|
// Save ASCII to storage
|
2021-08-04 03:21:06 +00:00
|
|
|
|
store.commit('newAsciibirdMeta', finalAscii);
|
2021-07-17 01:44:27 +00:00
|
|
|
|
|
2021-08-04 02:47:17 +00:00
|
|
|
|
return true;
|
|
|
|
|
};
|
2021-07-17 01:44:27 +00:00
|
|
|
|
|
2021-08-05 05:30:53 +00:00
|
|
|
|
// Creates new blank ASCII
|
2021-08-04 02:47:17 +00:00
|
|
|
|
export const createNewAscii = (forms) => {
|
2021-08-04 03:21:06 +00:00
|
|
|
|
const newAscii = {
|
2021-08-04 02:47:17 +00:00
|
|
|
|
title: forms.createAscii.title,
|
|
|
|
|
history: [],
|
|
|
|
|
redo: [],
|
|
|
|
|
x: 247, // the dragable ascii canvas x
|
|
|
|
|
y: 24, // the dragable ascii canvas y
|
2021-08-14 06:41:42 +00:00
|
|
|
|
blocks: [{
|
|
|
|
|
label: forms.createAscii.title,
|
|
|
|
|
visible: true,
|
2021-08-15 00:57:37 +00:00
|
|
|
|
data: create2DArray(forms.createAscii.height),
|
|
|
|
|
width: forms.createAscii.width,
|
|
|
|
|
height: forms.createAscii.height,
|
2021-08-14 06:41:42 +00:00
|
|
|
|
}],
|
|
|
|
|
selectedLayer: 0,
|
2021-08-04 02:47:17 +00:00
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
// Push all the default ASCII blocks
|
2021-08-15 00:57:37 +00:00
|
|
|
|
for (let x = 0; x < newAscii.blocks[0].width; x++) {
|
|
|
|
|
for (let y = 0; y < newAscii.blocks[0].height; y++) {
|
2021-08-14 06:41:42 +00:00
|
|
|
|
newAscii.blocks[0].data[y].push({
|
2021-08-04 03:21:06 +00:00
|
|
|
|
...emptyBlock,
|
|
|
|
|
});
|
2021-08-04 02:47:17 +00:00
|
|
|
|
}
|
2021-07-17 01:44:27 +00:00
|
|
|
|
}
|
|
|
|
|
|
2021-08-04 03:21:06 +00:00
|
|
|
|
newAscii.blocks = LZString.compressToUTF16(JSON.stringify(newAscii.blocks));
|
|
|
|
|
newAscii.history.push(newAscii.blocks);
|
|
|
|
|
store.commit('newAsciibirdMeta', newAscii);
|
2021-08-06 01:51:58 +00:00
|
|
|
|
store.commit('closeModal', 'new-ascii');
|
2021-08-04 02:47:17 +00:00
|
|
|
|
|
|
|
|
|
return true;
|
2021-08-04 03:21:06 +00:00
|
|
|
|
};
|
2021-08-03 07:33:25 +00:00
|
|
|
|
|
2021-08-05 05:30:53 +00:00
|
|
|
|
// Converts ASCIIBIRD blocks to mIRC colours
|
|
|
|
|
export const exportMirc = () => {
|
|
|
|
|
const {
|
|
|
|
|
currentAscii
|
|
|
|
|
} = store.getters;
|
2021-08-14 22:51:45 +00:00
|
|
|
|
const blocks = [...store.getters.currentAsciiLayers];
|
2021-08-05 05:30:53 +00:00
|
|
|
|
const output = [];
|
2021-08-14 06:41:42 +00:00
|
|
|
|
let curBlock = false;
|
2021-08-14 22:51:45 +00:00
|
|
|
|
let currentLayer = 0;
|
2021-08-05 05:30:53 +00:00
|
|
|
|
let prevBlock = {
|
|
|
|
|
bg: -1,
|
|
|
|
|
fg: -1
|
|
|
|
|
};
|
2021-08-03 07:33:25 +00:00
|
|
|
|
|
2021-08-14 22:51:45 +00:00
|
|
|
|
for (let y = 0; y <= blocks[0].data.length - 1; y++) {
|
|
|
|
|
if (y >= currentAscii.height) {
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for (let x = 0; x <= blocks[0].data[y].length - 1; x++) {
|
|
|
|
|
if (x >= currentAscii.width) {
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for (let i = blocks.length - 1; i >= 0; i--) {
|
2021-08-19 00:23:12 +00:00
|
|
|
|
if (blocks[i].visible !== true) {
|
|
|
|
|
continue;
|
2021-08-14 06:41:42 +00:00
|
|
|
|
}
|
2021-08-19 00:23:12 +00:00
|
|
|
|
currentLayer = i;
|
|
|
|
|
if (
|
|
|
|
|
!blocks[i].data ||
|
|
|
|
|
!blocks[i].data[y] ||
|
|
|
|
|
!blocks[i].data[y][x]
|
|
|
|
|
) {
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
if (
|
|
|
|
|
i > 0 &&
|
|
|
|
|
JSON.stringify(blocks[i].data[y][x]) ===
|
|
|
|
|
JSON.stringify(emptyBlock)
|
|
|
|
|
) {
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
curBlock = {
|
|
|
|
|
...blocks[i].data[y][x]
|
|
|
|
|
};
|
|
|
|
|
break;
|
2021-08-05 05:30:53 +00:00
|
|
|
|
}
|
2021-08-14 22:51:45 +00:00
|
|
|
|
|
2021-08-05 05:30:53 +00:00
|
|
|
|
// If we have a difference between our previous block
|
|
|
|
|
// we'll put a colour codes and continue as normal
|
|
|
|
|
if (curBlock.bg !== prevBlock.bg || curBlock.fg !== prevBlock.fg) {
|
2021-08-14 22:51:45 +00:00
|
|
|
|
curBlock = {
|
|
|
|
|
...blocks[currentLayer].data[y][x]
|
|
|
|
|
};
|
2021-08-05 05:30:53 +00:00
|
|
|
|
const zeroPad = (num, places) => String(num).padStart(places, '0');
|
|
|
|
|
output.push(
|
|
|
|
|
`\u0003${zeroPad(
|
2021-08-14 22:51:45 +00:00
|
|
|
|
curBlock.fg ?? store.getters.options.defaultFg,
|
2021-08-05 05:30:53 +00:00
|
|
|
|
2,
|
2021-08-14 22:51:45 +00:00
|
|
|
|
)},${zeroPad(curBlock.bg ?? store.getters.options.defaultBg, 2)}`,
|
2021-08-05 05:30:53 +00:00
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// null .chars will end up as space
|
|
|
|
|
output.push(curBlock.char ?? ' ');
|
2021-08-14 22:51:45 +00:00
|
|
|
|
prevBlock = blocks[currentLayer].data[y][x];
|
2021-08-05 05:30:53 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// We can never have a -1 colour code so we'll always
|
|
|
|
|
// write one at the start of each line
|
|
|
|
|
prevBlock = {
|
|
|
|
|
bg: -1,
|
|
|
|
|
fg: -1
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
// New line except for the very last line
|
2021-08-14 22:51:45 +00:00
|
|
|
|
if (y < blocks[currentLayer].data[y].length - 1) {
|
2021-08-05 05:30:53 +00:00
|
|
|
|
output.push('\n');
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Download to a txt file
|
|
|
|
|
// Check if txt already exists and append it
|
|
|
|
|
const filename = currentAscii.title.slice(currentAscii.title.length - 3) === 'txt' ?
|
|
|
|
|
currentAscii.title :
|
|
|
|
|
`${currentAscii.title}.txt`;
|
|
|
|
|
|
|
|
|
|
return {
|
|
|
|
|
filename,
|
|
|
|
|
output
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Download a string to a file with a filename
|
|
|
|
|
export const downloadFile = (content, filename, contentType) => {
|
|
|
|
|
const a = document.createElement('a');
|
|
|
|
|
const file = new Blob([content], {
|
|
|
|
|
type: contentType
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
a.href = URL.createObjectURL(file);
|
|
|
|
|
a.download = filename;
|
|
|
|
|
a.click();
|
|
|
|
|
|
|
|
|
|
URL.revokeObjectURL(a.href);
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
export const checkForGetRequest = async () => {
|
|
|
|
|
const asciiUrlCdn = new URL(location.href).searchParams.get('ascii');
|
|
|
|
|
if (asciiUrlCdn) {
|
|
|
|
|
const res = await fetch(`https://ascii.jewbird.live/${asciiUrlCdn}`, {
|
|
|
|
|
method: 'GET',
|
|
|
|
|
headers: {
|
|
|
|
|
Accept: 'text/plain',
|
|
|
|
|
},
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
const asciiData = await res.text();
|
|
|
|
|
parseMircAscii(asciiData, asciiUrlCdn);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const asciiUrl = new URL(location.href).searchParams.get('ircwatch');
|
|
|
|
|
if (asciiUrl) {
|
|
|
|
|
const res = await fetch(`https://irc.watch/ascii/txt/${asciiUrl}`, {
|
|
|
|
|
method: 'GET',
|
|
|
|
|
headers: {
|
|
|
|
|
Accept: 'text/plain',
|
|
|
|
|
},
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
const asciiData = await res.text();
|
|
|
|
|
parseMircAscii(asciiData, asciiUrl);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const haxAscii = new URL(location.href).searchParams.get('haxAscii');
|
|
|
|
|
if (haxAscii) {
|
|
|
|
|
const res = await fetch(`https://art.h4x.life/${haxAscii}`, {
|
|
|
|
|
method: 'GET',
|
|
|
|
|
headers: {
|
|
|
|
|
Accept: 'text/plain',
|
|
|
|
|
},
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
// Considers paths
|
|
|
|
|
const asciiName = haxAscii.split('/').pop();
|
|
|
|
|
const asciiData = await res.text();
|
|
|
|
|
parseMircAscii(asciiData, asciiName);
|
|
|
|
|
}
|
|
|
|
|
}
|
2021-08-04 02:47:17 +00:00
|
|
|
|
|
2021-08-06 04:39:54 +00:00
|
|
|
|
// Hashing algo to detect duplicate brushes
|
2021-08-06 11:00:35 +00:00
|
|
|
|
// from https://stackoverflow.com/questions/7616461/generate-a-hash-from-string-in-javascript
|
2021-08-06 04:39:54 +00:00
|
|
|
|
export const cyrb53 = function (str, seed = 1337) {
|
|
|
|
|
let h1 = 0xdeadbeef ^ seed,
|
|
|
|
|
h2 = 0x41c6ce57 ^ seed;
|
|
|
|
|
for (let i = 0, ch; i < str.length; i++) {
|
|
|
|
|
ch = str.charCodeAt(i);
|
|
|
|
|
h1 = Math.imul(h1 ^ ch, 2654435761);
|
|
|
|
|
h2 = Math.imul(h2 ^ ch, 1597334677);
|
|
|
|
|
}
|
|
|
|
|
h1 = Math.imul(h1 ^ (h1 >>> 16), 2246822507) ^ Math.imul(h2 ^ (h2 >>> 13), 3266489909);
|
|
|
|
|
h2 = Math.imul(h2 ^ (h2 >>> 16), 2246822507) ^ Math.imul(h1 ^ (h1 >>> 13), 3266489909);
|
|
|
|
|
return 4294967296 * (2097151 & h2) + (h1 >>> 0);
|
|
|
|
|
};
|
|
|
|
|
|
2021-08-07 06:10:52 +00:00
|
|
|
|
// Mostly plain text asciis wont have all their blocks
|
|
|
|
|
// so this will fix that
|
2021-08-15 00:57:37 +00:00
|
|
|
|
export const fillNullBlocks = function (height, width, layerData = null) {
|
2021-08-12 01:52:40 +00:00
|
|
|
|
// Probably used on irc import to make the blocks proper,
|
|
|
|
|
// especially with plain text ascii
|
2021-08-15 00:15:36 +00:00
|
|
|
|
|
|
|
|
|
if (layerData === null) {
|
|
|
|
|
var layers = [...store.getters.currentAsciiLayers]
|
|
|
|
|
} else {
|
2021-08-15 00:57:37 +00:00
|
|
|
|
var layers = [...layerData]
|
2021-08-12 01:52:40 +00:00
|
|
|
|
}
|
|
|
|
|
|
2021-08-15 00:15:36 +00:00
|
|
|
|
for (let i = 0; i <= layers.length - 1; i++) {
|
|
|
|
|
let blocks = layers[i].data;
|
|
|
|
|
|
|
|
|
|
for (let y = 0; y < height; y++) {
|
|
|
|
|
// New row
|
|
|
|
|
if (!blocks[y]) {
|
|
|
|
|
blocks[y] = [];
|
|
|
|
|
for (let x = 0; x < width; x++) {
|
2021-08-12 01:52:40 +00:00
|
|
|
|
blocks[y][x] = {
|
|
|
|
|
...emptyBlock
|
|
|
|
|
};
|
2021-08-07 02:41:47 +00:00
|
|
|
|
}
|
2021-08-15 00:15:36 +00:00
|
|
|
|
} else {
|
|
|
|
|
// no new rows but new cols
|
|
|
|
|
for (let x = 0; x < width; x++) {
|
|
|
|
|
if (blocks[y] && !blocks[y][x]) {
|
|
|
|
|
blocks[y][x] = {
|
|
|
|
|
...emptyBlock
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
}
|
2021-08-07 02:41:47 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
2021-08-15 00:15:36 +00:00
|
|
|
|
|
|
|
|
|
// Update layer with new blocks
|
|
|
|
|
layers[i].data = [...blocks]
|
2021-08-15 00:57:37 +00:00
|
|
|
|
layers[i].width = width
|
|
|
|
|
layers[i].height = height
|
2021-08-07 02:41:47 +00:00
|
|
|
|
}
|
|
|
|
|
|
2021-08-15 00:15:36 +00:00
|
|
|
|
return layers
|
2021-08-07 02:41:47 +00:00
|
|
|
|
}
|
|
|
|
|
|
2021-08-07 06:10:52 +00:00
|
|
|
|
// Sometimes if we copy blocks the initial Y values will be null
|
|
|
|
|
// and cause an error when trying to calculate width
|
2021-08-12 01:52:40 +00:00
|
|
|
|
// So we get the longest x length
|
2021-08-07 02:41:47 +00:00
|
|
|
|
export const getBlocksWidth = function (blocks) {
|
2021-08-12 01:52:40 +00:00
|
|
|
|
let maxWidth = 0;
|
2021-08-07 02:41:47 +00:00
|
|
|
|
|
2021-08-12 01:52:40 +00:00
|
|
|
|
for (let y = 0; y < blocks.length; y++) {
|
2021-08-07 02:41:47 +00:00
|
|
|
|
if (!blocks[y]) {
|
|
|
|
|
continue
|
|
|
|
|
}
|
|
|
|
|
|
2021-08-12 01:52:40 +00:00
|
|
|
|
if (blocks[y] && blocks[y].length > maxWidth) {
|
|
|
|
|
maxWidth = blocks[y].length
|
2021-08-07 02:41:47 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
2021-08-12 01:52:40 +00:00
|
|
|
|
|
|
|
|
|
return maxWidth
|
2021-08-07 02:41:47 +00:00
|
|
|
|
}
|
|
|
|
|
|
2021-08-07 06:10:52 +00:00
|
|
|
|
// This removes the null blocks from our copy and paste
|
|
|
|
|
// to make sure it's centered better
|
2021-08-07 02:41:47 +00:00
|
|
|
|
export const filterNullBlocks = function (blocks) {
|
|
|
|
|
let newBlocks = [];
|
|
|
|
|
let y;
|
|
|
|
|
|
|
|
|
|
blocks = blocks.filter(function (item) {
|
|
|
|
|
return item !== null
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
for (y = 0; y < blocks.length; y++) {
|
|
|
|
|
newBlocks[y] = (blocks[y].filter(function (item) {
|
|
|
|
|
return item !== null
|
|
|
|
|
}))
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return newBlocks
|
|
|
|
|
}
|
|
|
|
|
|
2021-08-14 06:41:42 +00:00
|
|
|
|
// Function to check if the left and top values are visible on the screen
|
|
|
|
|
export const checkVisible = function (bottom, top) {
|
|
|
|
|
var viewHeight = Math.max(
|
|
|
|
|
document.documentElement.clientHeight,
|
|
|
|
|
window.innerHeight
|
|
|
|
|
);
|
|
|
|
|
return !(bottom < 0 || top - viewHeight >= 0);
|
|
|
|
|
}
|
|
|
|
|
|
2021-08-08 01:55:59 +00:00
|
|
|
|
export const splashAscii = JSON.parse(LZString.decompressFromEncodedURIComponent(
|
2021-08-12 01:52:40 +00:00
|
|
|
|
"NrDeCICMHNwLgAwBpwDNaJQYwBYEMAnecAAnAF8kIZ5k0M7dDizLqGV1bt8i5SKVKB3rdwTPgLbCxXTON4tB7WSIlLpNeXMaL+rIVro6ezfcpna1eqYZEmFZ2yqtj15zfetODL498lfS383GyCjTgCNO1VQnwsI0Xl3Z2DIuMCErwzov3TksKzYgvjPYt1SmNcSzLLqitqqkJrctKSG1sSHFPDslo8m-I6BvPbTRtHuwrrm4dSuqJG2qcrJxfm+ud7y8c7N3aWFnMP9xwnl9e36g42ds727nqLr+5PH6cGx19uXp5mhm5XWaA57A75AgHg0GQv6fFbnI79H5g2FrY7ImEfNFIiFfVEXdG4+EPX5Ygk46F4smIraU4lvUmrcm0-5Upk0kGs+kYtkI074jlQrmXOki4WE0US8UU6UsuFi+VSxUy5Vy7Fq5mc1Va9U6zVC7UG3VG-UC-nU83sy1895W202xkOlEW+0k512x1uzEe91O71+3lewMM31B7lEhXGs2ukP+sOR00uz2x4M88PPAB2AFcADY5-LZvMHQs58gAXSQYETPrjKfTsr1gujybTCabSdDdbb1vjSqjHdrrb71YD9cNzc7Q5V-ZrqYjw-bs7HM9H3ZjU41i9XC57XZ36-n05HvaPW5Pm93G8bl8PF4PktPN4fd5bt+v94bJrPe8fH-HA7nZ931fICvyfT8J0HN8wL-Fdz2AydoMgwCIIA5djx-F9ENA5D0O-K8YJA1ClzXIj-xI-cyLgzCEKgnC0NI7DiO3X8qIwgjcMYujmPgwimPIlisO4gTeM4yj+OojiGPE4TJKQ6TWIk9j5Io1iSwLXN81eEty0rOT6NUoSUJEmi+Nk5SDME2jjP0njTObABOcz8JUqyzJsiy7KkwzrLw8CTO8h0nNTQBE0meYLuTCuoIq4jyXMs0SFKMvzYM8gLXMSnz3JStj4q8jL7KS3zYpypS8vShLCqysTFOc-zbIq-LKsCzK3Jq5KSs6mS4vqtKGv6vrBvKgbhqG3rRom8aptSyaZum3L5rKxa6rm1aFrWpaNpW9ads23btr2w6DuOnqttO-bzqO871KSG73B0isq1mi7SpO17Lrerrao+n6cpiyj-qRKKqkBuZgZcUGbnBsazveuGvo67q-u2yHCNRlJoa0dGbExjBsacXH4HxyRCbgYnWopqq2qK7KEeKpG6dphmAcHUmrvh5nvo5rnGfa4Dyf4NnPs5xGeZF+mxcl0WXwF8BSdlgqWqpymldVxX1eajWmu1xrdZG5bft5mm+aZqWJel83LdNi3ratk37eNx3qqd6nnbd12PZVrW9Zhl6jfdr3NaDuobrkO69AevTffZ-3PeV+O1eDn2sdZ8LU+i9OQcziHs8sWX5dzlPDfF23S4dj0FbT8786ryLa-WAvQvrkvy7jxOdf12HY8DjPq5Rwu8YHomh79luXZ75P5pr3u65nhuk870ezbL8eE6uaes6buf0Ub5Gt8nrux4DteF+j4Xl9bifF5jo+2+96-8gARhuQAQ0gfZ-vkAANJ35ub-pQ-lIf9lQAJsEA7EICnBgPJBAyQUDEQwOIHAvoAAOYKKQ37SlQRLLBpscE1TwQpAhqkiEsRISeMhP4KFTioYeGhD46GYLQYQphxCWGkLYeQjhlCuHUJ4bQvh9CBEd0sKHDA4czCRyegbbmNtL4n2EUXWem8lE533qolRecR4b3UfPbeQNm76L0WDAxMtz6yNXu3ZRpFtGaLUbYjRiju7yIPkvcxx9LEP2LqxSuRj+ZaP8XYxxO8TF2wsffM+fdIkOMHoEmJ0TD4XzCafZ6N9EkVwCfEsmGTdFWOCQo6RTiPERJkaE9x4T4Gvx-l-KpgDBGVP-vUqoH85AIIZM0jArSfjtPgJ0q43S4C9OeP0wZdRhnATGYRCZzYplJhmR6OZDoFkkn6VQpBPSn6NPARLEZwDtl7NNjsrZBz9k1UOdAk5CkzkVOOTc05FyynJLEZpDSRZtKaV0lIhJbi76POHrEv5mSbFBMMbkkFOi8mguMfkr5fj-lZLhT4yFsKSkrweb4tG2SIXgrBcUwp5SCm3yvriwlDJEXYtMQizFOLgVQqRain50LXGlIZXSxyVLaWeJRXIopKSzHMqJTSqGITvi7xyeSoV6KMa-KZfSgVBLJadIwU0jZkyVXTLVbMjV8ytWLJ1csvVbSDVdKNX0k1QyzWjItcqpIVyOlWpcEsw1Nrxn2ssI641SRVnmudaqn16q-WaoDdqz1PC1lwBwXIBhVQI0YCoUqlwMb4BerqIm8Noa6m4KEcqKN2Ic3kjzYiAtKCs25pLfmsthaK3FuwVWtaoj4DiL4JIzleLpVAriWK+xnbBUiuFVKyVOM+1JMZakilgL2UStZcOlxo7+Wkonb2gdBMh3pKia2kdfLZXOMXmSrtLNKUHsybOrdPL5XfLlTCk968F39qncujdXjz3buJWkllO7+6Hu7R2-dR7N3csPIqmpoDvUtJdUG3V4H9WQadaB31sH-XwcDYh4NyGIOoag+hmDdq4PYYQ7hpD+GUOEbQ8RjDpGsPrJw5RvD1GCO0aI-RkjjGyPMYowMsDmGPWcdNdBrj5G+OsYE+xqjwmaNpt-iB-j8a3X5DjRm-BtbqhFuKMppTinmiqb2vWuAjaG3vMei2klp6AVfpM1ivd1Lv2WbM94v907xUYrXT+0z8Lx2fqM-iy9-6203sHUukmK6gq+dXb+pzr6L07V3T2tl7nrOuZc8e7zD6uX2ZfU+4z8XzPRb83egLyX10zrs2iwrj650-Ci1ZsdLn202Y5b7d1PHuOScE41-jrWWvNdE3RrrDGetMb6yxgbbHbWUaa5a3j7WhtCZG8Jsb1q5sOtdVoBrnWZsrfGwtmTE3VscbaztkTa2luxsBp0sNqbTvPHOxJlNJ3rvRtu9Um7RqzsPdqU93jL3nuXde8B97nHPsfe+7JxTqa5OMJrRDq9mZnm3Rh-dfTUdeWlcc251H1WP17zR1lyryL0exbq9l+9uXiCiux7VydDmkslZS8Vwztn8cU4swTnHi7ieC0CyTjn7P-Mkgq15pMfPMv06x3FmrMqqd0-S558XqXnpi-l8Ft9aWyvS8S7Ls9KuuflcV5znn3PQWdNJut+be2Num5Nx1s3luLdTcm4d7bVvbf7bE-bzby2jujfN4th3NvXde62277DgfPfW+98H2b-v3c+7D5HoPseQ9O8d370PAfjt3Zj0m9NSfNmp8E2GlZPDpOVshwpkvzCy+sIr+wqvnCa-Pq0Np3TOmEefJl7TpnjPCd5bZ9rsLzPyes8pzlofROR-d7H7rnvpPRc6-1xPufyuof5Y89KtXIWEsY7xyL-vQud8K+RxL32gv9-b87yzw-SOadK8vwVyXuOye77PwP298+Mtr+vxrpf1Pb9H834JovVmhuBiQBeiIBvuu2KeUe4exuGeie4BB2EBcBsByeSBueqBUB8eEekBce2BCeKB+BiBBBCBxBLuhBZBJB3WM2V2j292X2f2-GAO-2zulB5BpBFBvWgG2eNBRydytyly9yLEM2zQQhHuO0jecOEcLed+KOW+shD+gu7+vOs+csPmDOg+He6hXek+76ahL+GhehN+K+y+4W9en+F+U8f+M+uhw++hAuRWH+a0x+yh0+e+I8ihph-O7ehhJhGWJ+chcW7hb+9hEWgRquwRw29+6BgBkRYB2KsRFm8RGBuBWBUReBrBLB7B-WRBbBORGRuRHB6RHooOIOgMqmxRwE5RmRg22ReRtRBRfBqkIh0e5yDRghAhJ4TRkaWeuy3BLRb2PR-RPB-BrRHR7RP4nRmBoR0OryYcEhEiUhi+5hz+NhWh86B+6unhDhbeWxe0Th1ho+thBx3hUuq+4RQR6xXhFh+x4+hxNxqxKheuveV+IRlhVW8hzhWuLhT+j+Mh7x1x2htxAJxxmuxhbxVhp+mh5+KxZhGx2xLxFxWRhRQWzRwKM2P2Rx0RkJNmiROBqRKRNR9R+RiJVRERJJ02SJ1RFJpJzYlRYmyaNu9JyBVJ5JZJduzJAGYxU4ExyRwhnJHJIx4xfJQGjRQpDSApXJopAxwxvBMpsJ4
|
2021-08-14 06:41:42 +00:00
|
|
|
|
));
|
2021-08-06 04:39:54 +00:00
|
|
|
|
|
2021-08-04 03:21:06 +00:00
|
|
|
|
export default createNewAscii;
|