Message
Message
// @name ThivScript
// @namespace http://tampermonkey.net/
// @version v1.5.3
// @description its like flamescript but... slightly better
// @author Thivs but also FlameFlmae
// @match https://flowr.fun/*
// @icon https://www.google.com/s2/favicons?sz=64&domain=flowr.fun
// @grant none
// ==/UserScript==
/**************/
/* CONFIG */
/*************/
//let versions = {
// db: (await(await
fetch("https://raw.githubusercontent.com/FlameFlmae/flowrmodvers/main/
v.txt")).text()).split('\n')[0],
// script: 'v1.4.0',
// client: (await(await fetch("./client.js")).text()).split(' ')[2]
//}
//console.log(versions)
window.flowrMod = {}
window.flowrMod.rarities = []
for (let i = 0; i < Colors.rarities.length; i++) {
window.flowrMod.rarities[i] = {}
}
// Rarities
window.flowrMod.rarities[0].display = 'Common'
window.flowrMod.rarities[0].color = '#7eef6d'
window.flowrMod.rarities[0].border = '#66c258'
window.flowrMod.rarities[0].hitbox = '#7eef6d'
window.flowrMod.rarities[1].display = 'Unusual'
window.flowrMod.rarities[1].color = '#ffe65d'
window.flowrMod.rarities[1].border = '#cfba4b'
window.flowrMod.rarities[1].hitbox = '#ffe65d'
window.flowrMod.rarities[2].display = 'Rare'
window.flowrMod.rarities[2].color = '#4d52e3'
window.flowrMod.rarities[2].border = '#3e42b8'
window.flowrMod.rarities[2].hitbox = '#4d52e3'
window.flowrMod.rarities[3].display = 'Epic'
window.flowrMod.rarities[3].color = '#861fde'
window.flowrMod.rarities[3].border = '#6d19b4'
window.flowrMod.rarities[3].hitbox = '#861fde'
window.flowrMod.rarities[4].display = 'Legendary'
window.flowrMod.rarities[4].color = '#de1f1f'
window.flowrMod.rarities[4].border = '#b41919'
window.flowrMod.rarities[4].hitbox = '#de1f1f'
window.flowrMod.rarities[5].display = 'Mythic'
window.flowrMod.rarities[5].color = '#1fdbde'
window.flowrMod.rarities[5].border = '#19b1b4'
window.flowrMod.rarities[5].hitbox = '#1fdbde'
window.flowrMod.rarities[6].display = 'Ultra'
window.flowrMod.rarities[6].color = '#ff2b75'
window.flowrMod.rarities[6].border = '#cf235f'
window.flowrMod.rarities[6].hitbox = '#ff2b75'
window.flowrMod.rarities[7].display = 'Super'
window.flowrMod.rarities[7].color = '#2bffa3'
window.flowrMod.rarities[7].border = '#23cf84'
window.flowrMod.rarities[7].hitbox = '#2bffa3'
window.flowrMod.rarities[8].display = 'Omega'
window.flowrMod.rarities[8].color = '#494849'
window.flowrMod.rarities[8].border = '#3c3b40'
window.flowrMod.rarities[8].hitbox = '#494849'
window.flowrMod.rarities[9].display = 'Fabled'
window.flowrMod.rarities[9].color = '#ff5500'
window.flowrMod.rarities[9].border = '#cf4500'
window.flowrMod.rarities[9].hitbox = '#ff5500'
window.flowrMod.rarities[10].display = 'Divine'
window.flowrMod.rarities[10].color = '#67549c'
window.flowrMod.rarities[10].border = '#453869'
window.flowrMod.rarities[10].hitbox = '#67549c'
window.flowrMod.rarities[11].display = 'Supreme'
window.flowrMod.rarities[11].color = '#b25dd9'
window.flowrMod.rarities[11].border = '#9043b3'
window.flowrMod.rarities[11].hitbox = '#b25dd9'
window.flowrMod.rarities[12].display = 'Omnipotent'
window.flowrMod.rarities[12].color = '#520380'
window.flowrMod.rarities[12].border = '#000000'
window.flowrMod.rarities[12].hitbox = '#520380'
Colors.rarities[12].border = '#000000'
Colors.rarities[12].color = '#520380'
Colors.rarities[12].hitbox = '#520380'
window.flowrMod.rarities[13].display = 'Astral'
window.flowrMod.rarities[13].color = '#046307'
window.flowrMod.rarities[13].border = '#035005'
window.flowrMod.rarities[13].hitbox = '#046307'
window.flowrMod.rarities[14].display = 'Celestial'
window.flowrMod.rarities[14].color = '#00bfff'
window.flowrMod.rarities[14].border = '#009bcf'
window.flowrMod.rarities[14].hitbox = '#00bfff'
window.flowrMod.rarities[15].display = 'Seraphic'
window.flowrMod.rarities[15].color = '#c77e5b'
window.flowrMod.rarities[15].border = '#a16649'
window.flowrMod.rarities[15].hitbox = '#c77e5b'
window.flowrMod.rarities[16].display = 'Transcendent'
window.flowrMod.rarities[16].color = '#ffffff'
window.flowrMod.rarities[16].border = '#cfcfcf'
window.flowrMod.rarities[16].hitbox = '#ffffff'
window.flowrMod.rarities[17].display = 'Quantum'
window.flowrMod.rarities[17].color = '#61ffdd'
window.flowrMod.rarities[17].border = '#4ecfb3'
window.flowrMod.rarities[17].hitbox = '#61ffdd'
window.flowrMod.rarities[18].display = 'Galactic'
window.flowrMod.rarities[18].color = '#ba5f7a'
window.flowrMod.rarities[18].border = '#974d63'
window.flowrMod.rarities[18].hitbox = '#ba5f7a'
window.flowrMod.rarities[19].display = 'Eternal'
window.flowrMod.rarities[19].color = '#5a8c7d'
window.flowrMod.rarities[19].border = '#497165'
window.flowrMod.rarities[19].hitbox = '#5a8c7d'
window.flowrMod.rarities[20].display = 'Chaos'
window.flowrMod.rarities[20].color = '#20258a'
window.flowrMod.rarities[20].border = '#191e70'
window.flowrMod.rarities[20].hitbox = '#20258a'
window.flowrMod.rarities[21].display = 'Vicious'
window.flowrMod.rarities[21].color = '#732190'
window.flowrMod.rarities[21].border = '#5d1a74'
window.flowrMod.rarities[21].hitbox = '#732190'
Colors.biomes.garden = {
"background": "#1ea761",
"grid": "#1d9157",
"darkbackground": "#275228",
"darkgrid": "#193819"
}
Colors.biomes.desert = {
"background": "#dece7b",
"grid": "#a1955a",
"darkbackground": "#82705b",
"darkgrid": "#524536"
}
Colors.biomes.ocean = {
"background": "#547db3",
"grid": "#41608a",
"darkbackground": "#05056b",
"darkgrid": "#000022"
}
Colors.biomes['1v1'] = {
"background": "#333333",
"grid": "#1f1f1f",
"darkbackground": "#171717",
"darkgrid": "#000000"
}
'data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdp
ZHRoPSIyNTYiIGhlaWdodD0iMjU2IiB4bWw6c3BhY2U9InByZXNlcnZlIj48cGF0aCBmaWxsPSIjRTBEMUF
GIiBkPSJNMCAwaDI1NnYyNTZIMFYweiIvPjxwYXRoIGZpbGw9IiNEN0M5QTgiIGQ9Im0xNDIgMjQwLjIgMT
UuNy0xNC43LTE0LjYtMTYtMTYgMTQuNiAxNC45IDE2LjFtNzEuNy0xMTAuNS04LjUgMjAuMiAyMC4yIDguM
yA4LjMtMjAuMy0yMC04LjJNODAuNSA0Ny41bDEuNi0yMS42LTIxLjYtMS43LTEuNyAyMS43IDIxLjcgMS42
TTE5LjcgODkuNGw0LjggMjEuMiAyMS4xLTQuOS00LjgtMjEuMS0yMS4xIDQuOE0xMjEuOSAyN2wtOS4zIDE
5LjcgMTkuOCA5LjMgOS4xLTE5Ljl6Ii8+PHBhdGggZmlsbD0iI0VDRENCOCIgZD0iTTI1NiAyNTZ2LTkxYy
0xOC43IDI0LjItMjcuOSA2MS4yLTM5LjIgOTFIMjU2TTI5LjggMjkuMkMzMyAxOC45IDM2LjcgOS4yIDQxI
DBIMHY5Mi42YzE0LjMtMTkuMSAyMy41LTM5LjMgMjkuOC02My40TTIxNi44IDBjLTIxLjcgNDguNS04MS42
IDk0LjktMTE4LjMgOTguM1MyMy43IDEzMSAwIDE2NXY5MWg0MWMyMy45LTUyLjUgOTAuMS01NC4yIDExNy4
zLTk5LjFzNzUuNC0zNC44IDk3LjctNjQuM1YwaC0zOS4yIi8+PHBhdGggZmlsbD0iI0YzRTJCRSIgZD0ibT
QzLjMgMTg2LjUtMTkuNCA5LjIgOSAxOS42IDE5LjctOS4yLTkuMy0xOS42bTEzOS44LTg4LjItMjEtNS43L
TUuNyAyMSAyMS4xIDUuNyA1LjYtMjFNNTEuNCAxNTYuNmwyMC4yIDguMSA4LjMtMjAuNS0yMC40LTcuOS04
LjEgMjAuM202OS45IDEuNyAyMC4xLTguNC04LjQtMjAuMy0yMC4xIDguNnoiLz48cGF0aCBmaWxsPSIjRDd
DOUE4IiBkPSJtMTkyLjIgMjA2LjEgMjEuNi0uMy0uMS0yMS42aC0yMS42bC4xIDIxLjkiLz48cGF0aCBmaW
xsPSIjRjNFMkJFIiBkPSJNMjI5LjkgNTMuNyAyMTAgNjIuNmw5IDE5LjkgMTkuOC05LTguOS0xOS44Ii8+P
C9zdmc+',
'data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdp
ZHRoPSIyNTYiIGhlaWdodD0iMjU2IiB4bWw6c3BhY2U9InByZXNlcnZlIiB2aWV3Qm94PSIwIDAgMjU2IDI
1NiI+PHBhdGggZmlsbD0iIzY2ODY5RSIgZD0iTTAgMGgyNTZ2MjU2SDBWMHoiLz48cGF0aCBmaWxsPSIjOD
hCMEM5IiBkPSJNMCAxODMuMzNjMTkuNTYtMTEuNjcgMzMuMy0yNi40IDQ5LjE0LTU5LjMxQzY3LjU1IDg1L
jc3IDEwMS40IDYyLjA3IDEyOC4zNyA1M2M0NC40NC0xNC45NSA2NS45My0yNi4zMyA3OS4yNi01M0g3NS43
MUM0OS45NSAxNy4zOCAxOC40MyAxNS45MiAwIDQyLjk2djE0MC4zN3pNMjA3LjYzIDI1NmMxMy4zMy0yNi4
2NyA4LjU5LTI5LjIyIDE0LjgyLTQzLjM5IDYuMjQtMTQuMTcgMTMuOTgtMTcuNjEgMzMuNTQtMjkuMjhWND
IuOTZjLTE4LjQzIDI3LjA0LTMwLjUgNTQuMTgtNDguMTkgODkuMDctMTIuNzYgMjUuMTctNTAuMTEgNjIuM
TgtNjguMDEgNzUuMzctMjUuNTEgMTguNzktMzguMzQgMzEuMjItNjQuMDkgNDguNiIvPjxwYXRoIGZpbGw9
IiM5OEM4RTMiIGQ9Ik0xNzMuOTQgMjMyLjk4Yy0uMjctMS45MyA4LjY4LTE3LjA3IDEwLjE1LTE3Ljg5IDE
uNDgtLjgzIDEzLjEzIDEwLjIzIDEzLjYxIDExLjk3LjQ4IDEuNzQtNC4wOSAxNi4zNy02IDE2LjU4LTEuOT
EuMTktMTcuNDktOC43NC0xNy43Ni0xMC42NnpNNTIuMTYgNTkuNTZjLjc3IDEuMjYtMS40OCAxMy42Mi0yL
jAyIDE0LjktLjU0IDEuMjgtNS4wOCAxMi40Ny02LjM3IDEzLjQ0LTEuMjkuOTYtMTYuMy00LjM5LTE3Ljg0
LTQuNzYtMS41NC0uMzctOC4wNi03Ljk3LTcuOTQtOS42NC4xMi0xLjY3IDIuNTUtMTcuMzQgMy40NS0xOC4
1NS45LTEuMjEgMTEuNzgtMy43NSAxMy4zMS0zLjMzIDEuNTMuNDIgMTYuNjQgNi42OCAxNy40MSA3Ljk0ei
IvPjxwYXRoIGZpbGw9IiM3NzlDQjAiIGQ9Ik0xNzYuMjggNzguNTJjLjc1IDEuNTEtMi43NyAxNS44OC0zL
jkgMTYuOTItMS4xNCAxLjA0LTE0LjMxIDEwLjQyLTE2LjA1IDEwLjQ5LTEuNzQuMDYtMTcuNTMtNS4wMi0x
OC4zNS02LjQ5LS44Mi0xLjQ3IDIuNDMtMTYuNzggMi40My0xOC41IDAtMS43MiA3LjIyLTEyLjIxIDguODI
tMTMuMDMgMS42LS44MiAxMi40Mi0zLjY1IDE0LjEyLTMuMzYgMS43MS4yOCAxMi4xOCAxMi40NiAxMi45My
AxMy45N3oiLz48cGF0aCBmaWxsPSIjNUE3NThDIiBkPSJNMTAzLjggMTIuOThjMS4xNS0uOCAxMC44NS0xL
jg4IDEyLjA5LTEuMjggMS4yNC42IDUuODkgNy45MyA2LjY0IDguOTcuNzUgMS4wNCAzLjggMTUuMzIgMi43
NCAxNi4zMi0xLjA2Ljk5LTExLjUzIDMuMDYtMTIuNzcgMi45Mi0xLjI0LS4xNC0xMy44Ny0zLjk0LTE0Ljc
4LTQuOS0uOTEtLjk3LjI2LTExLjE1LS4wMS0xMi41My0uMjYtMS4zOCA0Ljk0LTguNjkgNi4wOS05LjV6TT
EwMi4wNyAyMDVjLTEuODEgMy4xMy0zMC45Ni03LjE2LTMyLjQ4LTEwLjItMS41Mi0zLjAzIDE5LjA3LTI1L
jc4IDIyLjYzLTI0LjU3IDMuNTYgMS4yMSAxMS42NiAzMS42NCA5Ljg1IDM0Ljc3eiIvPjwvc3ZnPg=='
]
let images = {}
for (let i = 0; i < window.flowrMod.biomeURLs.length; i++) {
images[i] = {}
images[i].image = new Image();
images[i].image.src = window.flowrMod.biomeURLs[biomeManager.currentBiome]
}
window.flowrMod.petalRenderMap = {
Basic: (p) => {
ctx.lineWidth = 3;
ctx.beginPath();
ctx.fillStyle = blendColor('#ffffff', '#FF0000', blendAmount(p));
ctx.strokeStyle = blendColor('#cfcfcf', '#FF0000', blendAmount(p));
if(checkForFirstFrame(p)){
ctx.fillStyle = "#FFFFFF";
ctx.strokeStyle = "#FFFFFF";
}
ctx.beginPath();
ctx.arc(0, 0, p.radius, 0, Math.PI*2);
ctx.fill();
ctx.stroke();
ctx.closePath();
},
Missing: (p) => {
ctx.lineWidth = 3;
ctx.beginPath();
ctx.fillStyle = blendColor('#ffffff', '#FF0000', blendAmount(p));
ctx.strokeStyle = blendColor('#cfcfcf', '#FF0000', blendAmount(p));
if(checkForFirstFrame(p)){
ctx.fillStyle = "#FFFFFF";
ctx.strokeStyle = "#FFFFFF";
}
ctx.beginPath();
ctx.arc(0, 0, p.radius, 0, Math.PI*2);
ctx.fill();
ctx.stroke();
ctx.closePath();
ctx.strokeStyle = 'black'
ctx.font = `900 ${p.radius}px 'Ubuntu'`;
ctx.textAlign = "center";
ctx.textBaseline = "center";
ctx.strokeText("MISSING",0,p.radius/2)
ctx.fillText("MISSING",0,p.radius/2)
},
Rubber: (p) => {
ctx.lineWidth = p.radius * 0.22;
ctx.beginPath();
ctx.arc(0, 0, p.radius, 0, Math.PI*2);
ctx.stroke();
ctx.closePath();
},
Coral: (p) => {
ctx.strokeStyle = blendColor('#b04646', '#FF0000', blendAmount(p));
if(checkForFirstFrame(p)){
ctx.strokeStyle = "#FFFFFF";
}
ctx.beginPath();
ctx.moveTo(0, p.radius * 1.17);
ctx.quadraticCurveTo(0, p.radius * 0.85, p.radius * 0.6, p.radius * 0.35);
ctx.stroke();
ctx.closePath();
ctx.beginPath();
ctx.moveTo(p.radius * 0, p.radius * 1.17);
ctx.quadraticCurveTo(p.radius * 0.15, p.radius * 0.26, p.radius * -0.69,
p.radius * -0.2);
ctx.stroke();
ctx.closePath();
ctx.beginPath();
ctx.moveTo(p.radius * 0, p.radius * 1.17);
ctx.quadraticCurveTo(p.radius * -0.05, p.radius * -0.3, p.radius * 0.56,
p.radius * -0.75);
ctx.stroke();
ctx.closePath();
ctx.beginPath();
ctx.moveTo(p.radius * 0, p.radius * 1.17);
ctx.quadraticCurveTo(p.radius * 0.1, p.radius * -0.3, p.radius * -0.08,
p.radius * -1.13);
ctx.stroke();
ctx.closePath();
ctx.beginPath();
ctx.moveTo(0, p.radius * 1.17);
ctx.quadraticCurveTo(0, p.radius * 0.85, p.radius * 0.6, p.radius * 0.35);
ctx.stroke();
ctx.closePath();
ctx.beginPath();
ctx.moveTo(p.radius * 0, p.radius * 1.17);
ctx.quadraticCurveTo(p.radius * 0.15, p.radius * 0.26, p.radius * -0.69,
p.radius * -0.2);
ctx.stroke();
ctx.closePath();
ctx.beginPath();
ctx.moveTo(p.radius * 0, p.radius * 1.17);
ctx.quadraticCurveTo(p.radius * -0.05, p.radius * -0.3, p.radius * 0.56,
p.radius * -0.75);
ctx.stroke();
ctx.closePath();
ctx.beginPath();
ctx.moveTo(p.radius * 0, p.radius * 1.17);
ctx.quadraticCurveTo(p.radius * 0.1, p.radius * -0.3, p.radius * -0.08,
p.radius * -1.13);
ctx.stroke();
ctx.closePath();
},
Bubble: (p) => {
ctx.lineWidth = p.radius / 5;
ctx.globalAlpha *= 2.777777777;
},
Air: (p) => {
//Air is not rendered
},
Starfish: (p) => {
ctx.lineWidth = p.radius * 0.14;
ctx.beginPath();
ctx.lineTo(p.radius * -0.84, p.radius * 0.65);
ctx.quadraticCurveTo(p.radius * -0.99, p.radius * 0.52, p.radius * -0.87,
p.radius * 0.37)
ctx.quadraticCurveTo(p.radius * 0.23, p.radius * -1.25, p.radius * 0.57,
p.radius * -0.99)
ctx.quadraticCurveTo(p.radius * 0.98, p.radius * -0.78, p.radius * -0.07,
p.radius * 0.93)
ctx.quadraticCurveTo(p.radius * -0.18, p.radius * 1.03, p.radius * -0.31,
p.radius * 0.98)
ctx.fill();
ctx.stroke();
ctx.closePath();
ctx.fillStyle = blendColor('#d4766c', '#FF0000', blendAmount(p))
if(checkForFirstFrame(p)){
ctx.fillStyle = "#FFFFFF";
}
ctx.beginPath();
ctx.arc(p.radius * -0.18, p.radius * 0.21, p.radius * 0.22, 0, Math.PI *
2);
ctx.fill();
ctx.closePath();
ctx.beginPath();
ctx.arc(p.radius * 0.09, p.radius * -0.23, p.radius * 0.165, 0, Math.PI *
2);
ctx.fill();
ctx.closePath();
ctx.beginPath();
ctx.arc(p.radius * 0.31, p.radius * -0.57, p.radius * 0.11, 0, Math.PI *
2);
ctx.fill();
ctx.closePath();
},
Compass: (p) => {
ctx.lineWidth = 2.4;
ctx.beginPath();
ctx.fillStyle = blendColor('#3498db', '#FF0000', blendAmount(p));
ctx.strokeStyle = blendColor('#bfbfbf', '#FF0000', blendAmount(p));
let redCompass = blendColor('#e74c3c', '#FF0000', blendAmount(p))
let whiteCompass = blendColor('#ecf0f1', '#FF0000', blendAmount(p))
let centerDot = ctx.strokeStyle;
//glow
//shadow
if(p.glow >= 0){
ctx.save();
ctx.restore();
if(checkForFirstFrame(p)){
ctx.fillStyle = "#FFFFFF";
ctx.strokeStyle = "#FFFFFF";
redCompass = "#FFFFFF";
whiteCompass = "#FFFFFF";
}
ctx.beginPath();
ctx.arc(0, 0, p.radius, 0, Math.PI*2);
ctx.fill();
ctx.stroke();
ctx.closePath();
ctx.fillStyle = redCompass;
ctx.beginPath();
ctx.lineTo(0, -p.radius * 0.4);
ctx.lineTo(p.radius, 0);
ctx.lineTo(0, p.radius * 0.4);
ctx.fill();
ctx.closePath();
ctx.fillStyle = whiteCompass;
ctx.beginPath();
ctx.lineTo(0, -p.radius * 0.4);
ctx.lineTo(-p.radius, 0);
ctx.lineTo(0, p.radius * 0.4);
ctx.fill();
ctx.closePath();
ctx.fillStyle = centerDot;
ctx.beginPath();
ctx.arc(0, 0, p.radius/4, 0, Math.PI*2);
ctx.fill();
ctx.closePath();
},
"Dark Compass": (p) => {
ctx.lineWidth = 2.4;
ctx.beginPath();
ctx.fillStyle = blendColor('#2b2b2b', '#FF0000', blendAmount(p));
ctx.strokeStyle = blendColor('#bfbfbf', '#FF0000', blendAmount(p));
let redCompass = blendColor('#3c9de7', '#FF0000', blendAmount(p))
let whiteCompass = blendColor('#ecf0f1', '#FF0000', blendAmount(p))
let centerDot = ctx.strokeStyle;
//glow
//shadow
if(p.glow >= 0){
ctx.save();
ctx.restore();
if(checkForFirstFrame(p)){
ctx.fillStyle = "#FFFFFF";
ctx.strokeStyle = "#FFFFFF";
redCompass = "#FFFFFF";
whiteCompass = "#FFFFFF";
}
ctx.beginPath();
ctx.arc(0, 0, p.radius, 0, Math.PI*2);
ctx.fill();
ctx.stroke();
ctx.closePath();
ctx.fillStyle = redCompass;
ctx.beginPath();
ctx.lineTo(0, -p.radius * 0.4);
ctx.lineTo(p.radius, 0);
ctx.lineTo(0, p.radius * 0.4);
ctx.fill();
ctx.closePath();
ctx.fillStyle = whiteCompass;
ctx.beginPath();
ctx.lineTo(0, -p.radius * 0.4);
ctx.lineTo(-p.radius, 0);
ctx.lineTo(0, p.radius * 0.4);
ctx.fill();
ctx.closePath();
ctx.fillStyle = centerDot;
ctx.beginPath();
ctx.arc(0, 0, p.radius/4, 0, Math.PI*2);
ctx.fill();
ctx.closePath();
},
['Waterlogged Compass']: (p) => {
ctx.lineWidth = 2.4;
ctx.beginPath();
ctx.fillStyle = blendColor('#66442d', '#FF0000', blendAmount(p));
ctx.strokeStyle = blendColor('#a38f7f', '#FF0000', blendAmount(p));
let redCompass = blendColor('#a64532', '#FF0000', blendAmount(p))
let whiteCompass = blendColor('#d1b299', '#FF0000', blendAmount(p))
let centerDot = ctx.strokeStyle;
//glow
//shadow
if(p.glow >= 0){
ctx.save();
ctx.restore();
if(checkForFirstFrame(p)){
ctx.fillStyle = "#FFFFFF";
ctx.strokeStyle = "#FFFFFF";
redCompass = "#FFFFFF";
whiteCompass = "#FFFFFF";
}
ctx.beginPath();
ctx.arc(0, 0, p.radius, 0, Math.PI*2);
ctx.fill();
ctx.stroke();
ctx.closePath();
ctx.fillStyle = redCompass;
ctx.beginPath();
ctx.lineTo(0, -p.radius * 0.4);
ctx.lineTo(p.radius, 0);
ctx.lineTo(0, p.radius * 0.4);
ctx.fill();
ctx.closePath();
ctx.fillStyle = whiteCompass;
ctx.beginPath();
ctx.lineTo(0, -p.radius * 0.4);
ctx.lineTo(-p.radius, 0);
ctx.lineTo(0, p.radius * 0.4);
ctx.fill();
ctx.closePath();
ctx.fillStyle = centerDot;
ctx.beginPath();
ctx.arc(0, 0, p.radius/4, 0, Math.PI*2);
ctx.fill();
ctx.closePath();
},
Claw: (p) => {
ctx.strokeStyle = blendColor('#3e1f1b', '#FF0000', blendAmount(p));
ctx.fillStyle = blendColor('#4d2621', '#FF0000', blendAmount(p));
if(checkForFirstFrame(p)){
ctx.fillStyle = "#FFFFFF";
ctx.strokeStyle = "#FFFFFF";
}
}
ctx.lineTo(p.radius * 0.7, 0)
ctx.fill();
ctx.stroke();
},
"Fangs": (p) => {
ctx.strokeStyle = blendColor('#7e0d0d', '#FF0000', blendAmount(p));
ctx.fillStyle = blendColor('#9c1010', '#FF0000', blendAmount(p));
if(checkForFirstFrame(p)){
ctx.fillStyle = "#ffffff";
ctx.strokeStyle = "#ffffff";
}
ctx.beginPath();
ctx.moveTo(-p.radius * 0.52, -p.radius * 0.815)
ctx.lineTo(-p.radius * 0.51, -p.radius * 0.11);
ctx.quadraticCurveTo(-p.radius * 0.53, p.radius * 0.35, -p.radius * 0.18,
p.radius * 0.46)
ctx.lineTo(p.radius * 0.515, p.radius * 0.785)
ctx.lineTo(p.radius * 0.51, p.radius * 0.1)
ctx.quadraticCurveTo(p.radius * 0.56, p.radius * -0.37, p.radius * 0.11,
p.radius * -0.525)
ctx.lineTo(-p.radius * 0.52, -p.radius * 0.815)
ctx.fill();
ctx.stroke();
ctx.closePath();
},
"Jelly": (p) => {
ctx.strokeStyle = blendColor('#bbb9e4', '#FF0000', blendAmount(p));
ctx.fillStyle = blendColor('#bbb9e4', '#FF0000', blendAmount(p));
if(checkForFirstFrame(p)){
ctx.fillStyle = "#ffffff";
ctx.strokeStyle = "#ffffff";
}
ctx.globalAlpha *= 0.5;
ctx.beginPath();
ctx.arc(0, 0, p.radius, 0, Math.PI * 2);
ctx.fill();
ctx.closePath();
ctx.globalAlpha *= 2;
ctx.globalAlpha *= 0.7;
ctx.beginPath();
ctx.arc(p.radius * 0.16, p.radius * 0.5, p.radius * 0.33, 0, Math.PI * 2);
ctx.fill();
ctx.closePath();
ctx.beginPath();
ctx.arc(p.radius * -0.66, p.radius * 0.25, p.radius * 0.12, 0, Math.PI *
2);
ctx.fill();
ctx.closePath();
ctx.beginPath();
ctx.arc(p.radius * -0.46, p.radius * -0.29, p.radius * 0.25, 0, Math.PI *
2);
ctx.fill();
ctx.closePath();
ctx.beginPath();
ctx.arc(p.radius * 0.21, p.radius * -0.21, p.radius * 0.165, 0, Math.PI *
2);
ctx.fill();
ctx.closePath();
ctx.beginPath();
ctx.arc(0, p.radius * -0.82, p.radius * 0.164, 0, Math.PI * 2);
ctx.fill();
ctx.closePath();
ctx.globalAlpha *= 1/0.7;
},
Pearl: (p) => {
if (p.rarity === 11 && window.flowrMod.rogPearl) {
let path4 =
'data:image/web+xml;base64,UklGRvgZAQBXRUJQVlA4TOsZAQAvW0FXEE1ArG0lDHP4kGrqY/
+BRUw7QUT/J8Cusf9Kne9/8G0AP/Fn7kUZ82/
c3YFRjJyzFTfu6bTHRUTL3SE3y+0X1LGIaLg7u2BwnLNjHXf396UWICkvLKIj+uJ5mLNlEYW7O/
CcBPAI9axhvWPeWJiZuzswOKuCP+g2dGFhXiUgFbtgfaG9ur/
SaS2pJ+nO5JIA1hrbm1lAwkeSlEUmx+dBktzCYy23WKtAEmXaSSqWrbXcly2pkMSxErCZm7mZWdhaFXqK5C
gQm5mBHbdyA2zT2cwc1ELifIAD7ydSUUsI1ga8lQqkyqxCSA2IYgc92peZAdqBBarQKZHYtHTiVmaqUY0NQ
CWo461n43qNCWTifvFI0tU75oOSSidA4gPIZP/
pjMmX7zsCUr8AqkPShN+v6qSSYpvo4j2MDWjYZAw+eR7wZdYJm5PM3lsBXh8UEZPk54P4QhERyTEBP5qZXS
kiIhPM2L3ld1JEcPaOn3uy+EkwwFv9lpklgJ/
t+uavF5QU23YkSUaQorVW+1+PHObwtXaaIHg4H+fhPP4khGftgJKqbXcb6WB+zEcQxUuhgaqv/
7BHvf+F9AJq1IRgxIcQQtQNyooku7adfO/Ju7HQ6I2E/
v8THt5771J+c9gcmsNi0zRN0/8JgIPoEhwiAgBea+FDjlafuvULcONbu8wGbmsR3w231rU5rp4+5gmM0UbP
bzk7ux/eAgCt23dBrUs/dmMMAE5oCKo90p1rn+4ButUeQ+3opy/
nGGFgAkkAE4AxGMc4vAegdXsEUfvUxRlAEQwCV4UdIBAOHgHAAwDdug92km7A/
IwgSIgAtsOO3YcOIjgFtZCBCaaboHBBaQG8+fRYXjyG+AAi8B2okJhgH2jAAun5GT/
YAN7sB+CDhwC1d7SIbufrKxVWS38EGgZ2gGAA0wA8VYxH6q8eA632BmoRu+2jewulalsq/
IuFNi0F2AGgVASzyd3HwO0NrRZx7JqYIclOl6xngYULTGCHQMoEg4E/
dw5otQDgFhHHy27MEKQEKFRQNGwIALbxREZSUnLb8wC4BQBExGppCQkpAQYUJjsseKfDnIBJ2tKWNsvSZ/
vNA4iA1/
pto4OEhABgADb8hkKY6MEcCCUkJGKP2jkACNorjYmEKNl4AmUBThsGIGRo9BhBFMVxc35dfyffSghKSAIwT
GNeGAADJ0wwDATf+O/
H9SMAiIhuHRUMiiQoaIam3AAYA4Q6i6aQdHIIb7bIEDRRCXCqVuVT1caCfjCfmFMorabqHBSE7WC0p2/
Ow5cfzlOXHzH5ET96+BGd9qnbbfeGdjiCQZQibaVGqcrmwt9JMqr/14VSoihks777CZ9++PTDn//
TIn7EM/v09M3vSvQUbzqF8DQ8Dcp5+6vX7ZBRKIMLOdnGuOrZpYMFFDOm0KFVYl9+RPfH9f3j0w8/
i+S226dOtTcGVhkUUcZsazAM2KChTY80zumczFlK86lECq0WET/
i1jjP8DCCqSgpI+1xoShoRU+tLipZZBJIEIN4PV8yUP3xIQATU6W1rJtAUZRCTWmlgpRMGbSELUx5CgDQh0
Asjug/
HtrOkwZspjCxbilUM6AgLNAKlZKSppZVlimpNwCYLUl6P6q9hQgAznMPQtgsBK0ZItgWeAIKo6cWg0Ez4Xc
r2AAAmH3wH/SBj1+98OEDzi07RFFasJhTW0NBMkXC1qJkeBow3aVkMA7AC/
3L1s5uaYPTif7GwezftPec1mlJ0WwRMRgUYZGSpSVISFq0iMF1v+S7ebBfpScbiTkwkVgYBwiAqAUAGL0hX
qEoKgTp1qqDwWhj0SwsWx2/R28DT1s9nVNms6wkTEbvefwEV+gWAKKfYkCWiMHmdAEAA4/
e9GYPBi2LJRG9eUc/Hce2qKGGAG/N1H6j9n/
gFgJA9k0M1B+56IULp2M+UAFgLINWnNUlaKuSweiX0Xc1LkAAMPE/fQIAoEVEt24Bol/+/
c1gSUmBgulQrRoE6ZaesCquS8lK5v4e4NJf1XkBQVFSO3YdD/
UGgNduAdiyn9qCvGx58ZYkFUpkjOIgPZoosStZ4p/
XXwCX5tJQIBbqg+EX10PfwvXe5Q3UAqy95ZmGGWyqxXBwsLNYHOqglarVEuNQCwBJ66JFU/
F3RgVke08L2ffzOuUQ/
HPx6TAOgBJAEyno0nNtdnG0OgAgdq1aGmRfX71+HHn49/3Peoh3tQA8bhmQxYJWQUEwehfTMUfXs6wpbwl9
UwMAl/1pMkUKTlvHV222efgV7yECN6NvLtyt2Q2CwoLggeWq33qOlmUqngQ3AQCyjcMUOF4x+q4Gk/gQ/
Pt19XkovC02WmFF8Oi5FAXB4H6oH8P11q5deG4c/8BhPLfVX9UDmpJWLSE7G9FFMkk4l/
PxDQCnAKg8Atrst+emda8IivBUWkKyK4M+u19e+jbc1yLiIdDurfHy7VRSpVVpURTF5bw7duG+2/
cB+PmrcZp4oyiKwTxY+7O+AXfx9nsAnA+W1+tsk/
zjdO+HP7kJN1HrVvshAM791gVvEQEAD95RB8SAbcM2Eknw/5+dOtkuiIgJmJe7q/nTvXds788vLneTpNg/
dvXZOo8Q3+qbdRLIo/f2i3UaoEnT7PzpmoS0hQTv5zNjQxqblobu/
KELIQ5NCPXe3625K7Dz+UObtsdpvbxxOZs0CS14X17Y0LZ5aoB6PnaAV3zHEXI6TY99+4QLTdomaZOA+lWQ
SHIjSX775CJokrg5C7zzDwloksKRCLyz1zeiLQXRlCA6u7s6ZmfnCUlNUoAmKEid2dmdh53nIshjSVIoAp2
x5xpJhJamKUWtxJz+gMOlQIP4Zbd3RqJQp7QxHD02+EWlciaNwylxOPXPB5BAQjxKEshjr0lSz+8aCjp/
SXhtH3AjIySEaJ8QaxMa4pv5QR45w0NpYp0XVFLShCalxZJbYOfeppCUPoQUz6wT8No3NS12IYkPnhphd/
ditpgmaZKWBEsSlLO+sUkCpUAc2JkZA9j23shpkgI0SfEzUM/
uXNskSfMIWOcCnvdr4oQmAew5vV69n3GbQttCPT89H2pkWkQLeP5a5lHg289mFwS+nT/
c3VXs+a+7mj+0U/+/bEvK7+zNPI8xixAPZKMBMEAIUVsAcvJSwZiNDvBASNzzq71PUPecu///s88+L/
ylWEDElPX0ZBB2jIWKMVAy6kZYKAXM8CrkBC+vVSrwQYoGFhKIcYCdssAQjiq64o4ZVGAAH030IEXCKKFHC
YiZHHTeCphBAxExAmqR9hSDiX9wJRwRKMBLZ5OE7ggvPQg4RipFwQsgR5KkSPJlZtZ0xVtF8MXMe9c9Izm2
bdWqxjoHd3damgGxkALJ0qbp7t/
1bsrOti2SshtW7u7u7u6+9h3bSmbFHAjLzn0EuMP4IIVDYc2HVU+sEpyWGvhdJwCrBVDLNrvZ+3me94Ofhs
PMzMzMzFHMDHPCzMzMoJiZmZmZ6eDMz9/3vs+zt/je7/3/
deZ789sdThzJqMRFJordiYsdGWaOyvp1WDHIaJDHhXFkOPltxoVJocuK5Di+geOy4rKiuDiq3CtgBsl4C1W
omG0tt/
fAcAXMrUfFXMnMPeSzqvkOSDHa6HIDqpFlBsvkmLm1kQXFXMXMzKzHVSWqzL0ERlXHDLY3gXMBjSN5dHlGF
VRWPe//f0a6tm2fn5VUUmit7h3LxmEfI/uYH9NjO4a2l23rPzg4sm3bPo7e3V2VpJL8ZHv7P0OSrO/
394vIrKyqNqp3j23btu1zrn2u2T01OD7/
w7m2bdvWcL3bLmVGxO8nRxQAgm5ebNu2bVsHSGobp+nouWM3e7SNzf5xMgFY6/+XJUnOfZE9Z9h4O87ISaF
dqnhgicjK7kr8pU1FZcn4UPTCPw4q+D9HXgVU4YKP/
qlCiwPpyfgR9NGmJfho2TBuCKVcGFqCyXTahstki7g8WNAUDcGA7cP1RFxHFpQLVTThn7YPaYMM2VwIqqID
n3bJhH0xQBbID8FLVS6UN1oNaB5UMHEwHVHIkW2rVnrfh7slQbakRzGimLrru1tiJEmSFEVkLz8qIQ2CYKf
3bYejSLZVp618ZhP/B6xE0rMTWjNzVGQ7AZouAFsuSVKe53nf9/vujYjMLMOdLTt+AP+Ef+D6S/gZ/
Ad2bN3dpaW6MjMy7v2+732fB6kqKqNuNtsXr1zhOu64WzXuVtuLX5wM3OXi7tbn4O7u0ctxyWXMru9qJPBe
wQnc3Rn3qSUOt3YETuJUoXVXMydwHwnc3TUbH5/BIWo1J1jmqg81u76r5rh77li5jM/
kikM2WrmCE4UHnoW7Xdzd3d3GJZc4ZOLUMnAad6vA3d2dcdfqJQ6VuMs97Nx9fHB3q/
Gp8SncLXAqZ4VDBs64u3u14T4+2YeVQx28YsUcF9zaNimSHOk3M4eAzIIGTQ8z9DLzBey9MKOkFrWG8XwP9
5iZmXeYWayepqqEAHc3M9yybSt7I2mutc/
3SbIMydhcDFcNlx3lzGZmeg28ykhTd75MRz8CFTNXZVQyRXcy2pal///
OXjEBnJ5tWzbJlvPQCx8EZhYubmYe9e9vM8Ns41qralVlZmQGfPF9Lz1g+BPvYFMMytLOLTWF5KYNaXYaUq
oyNHOY/Zk/
Qxm+QVOYP8OmHJShpDTkYJWZIU0lhdlpSEOYw+zX7PVJTWF2GDasJVWb05CDqkFz94Y0NMSaOQwbmrvT7M9
S7UEOmjbUhjA0t9nObSllpaEkN+WgzI41cxgacrApmvszOwfN3WnIwaYyuySnYUOanYaSMs2O5g5z1aCpWt
r0SauZMVtaOcjBWpIpDWV2msOwodLskJo+s6sGzdwhrQ1pdlMZSgqz05CDldJeS6ptDsOGlWaXVDUIs1eZq
SkGtaSdLW3KQZmdZqchB1nSau4ua39mV5ob1oYYNOUy56CW5JKcS3JDGmJQba4tj8LsklxbSkMZwuwyDTRJ
kuTYtu2YedRaZ5/3zn/
gnAM9jiFgYJ9OCy0M5qP96H1n77Uqwz1Lkqzatm1b5h6lNup9jDEXbWb4Ud7763Zqp3inFu5JffTeWqu1lP
BIPvv/q7ZlW2mtj7nqXMl4/y/
S99lVa43egqoj9x38cBYO6cLhDTjUibBwpi3849BxdvjHoXCXhcMbqHSccKV3PkTtZvef3h4WzsCdUK/
smxIWTj9hx5npJGzpDHGZuITuzBviUOk44SBcOAunpTfEpdDIbacrXfhe6TjhwGunODQcQrcrFeJS4V3hSm
ulA2/
prheADpzI4YR1Q5dTOIQ93RNnhS3dJ7xp4W4V4LAJC6cqJO3pnhkOZ+IUobvbtcKdcDwPkcPAoac79SRJkm
zbliQR8Trn1/+bzcLm37QpWa8uztlLyLckSZYkSbZFxBqRfe+5/
cJ8aMH86XzFLcOFYgL0bv+3WrKmPM+z9q7qfhW30P//f8tf7a7ae6/
nieBv+OHsYKxxCteTdnKu6xz8TWcnyMIfHFbEdXX4JGMdND5WwXiGFc4+YSPvSOGL8MFh4U24cXcYnzkvkl
qlC2clSOHUCRfODnCncHfoZKTGvYOKuK79hguncDpdOAcLxzoYTc91veMzle7kva5TOPWGG+/
CGZ9Z1zUR7mMdVDLujdNhJUgXToUPzmncrXB3t8IpZOQc/
KQb51Ta+MLdnQ4a98a1005GuvGXjIVzNm5jG+dM6D6N00gHOLwT7gR5w8Jh43SIb0mSLEmSbIuI1TyyLt2/
0//f33O/38KU2ZMkybJtS5JExLLO+UVbq57Of0i16iB+oXrOXsKRoA8LdJ/
jxSDiwsBuz2wqDHR6WrgQCAI3Pb/Db/eXjcBOz9xFugOp58YBo21S/
NhfAg9sOFPR6PKxwyRH21RY8FsfW/cVIvI7v8ZH5rHDJEfbFFjAhx7RhK0egMTNBT/
y2yVMIAUY3AApRxt2C8Zr675CZP4P/
bZSGaMCgpgDJypEJCO54yQ52iC7BgDBc8Zr6lOQAwQEMdhhgAYBCYnkgDnlA4ALXGYZQARMNKOqqFe9nk28
rqqPlAMjRcd9jja0frO6WJx0MocEmmEYOaEZUpgBESIAR6eUUwQ0wMCJA/SDRCFgVlR/V/
hF9Y3Zj6ovnL3hI4dk5LvjHAm0gQRACAARQ34eIiZ4Ck0tGtk9h4s/
ttisM8CExE6ubq4PMkABb+GAg2+w4GcH+WvAFkaQCCLmXwjVsAgXORIspiZQoxoVNJdyyoGgHZRGG0Rtn+N
jrQ+xsIE/
rm8u9c03JbVfgOUiaxQTUgrVSGswGY2i0pCQzZpvxKU6tKoO0VUkQkKJHC+JRFjKpRvopmZowmJYLWupvXM
NGak6OU2gDZlrDObiNrRkcRA2/q9qS7INB+yiRM3rZd/
7UX5UKSF4g0ACMkGupuDMXGp+S1arJcoxhqEhrx/GbUuJNtBkBRtum/
+SCJJonXH9zWyPUKvjJBRp7SqtoBQdOWM242qPJlCQlFNIBt55bnG0EhjjZX8IAWC9IDXz/YSBP/
33Rvpzb8eS33nL/
8zMcQ4qYDJcpFykmXL+diqC98K7SjJKzwqaU0vvmriuklgCrFpUSCE6BErNMeJ2gg1STEAk0S1nisKtBInn
ToIsHx2agYwLlgJLCaygCqEcQ7JWcSVvRuu/
Ajzxl+8EVWtEjOizk+bSXA6025kG1vTx2+JqLgesHc5JMbKTfTQI71l3pRO5wXVPZ0qCtFdYO1T6bBMTeYF
FU90MDB8gjZbYJ3XwyyJWinCUFlEUkoTOnlWUsd1tZ61yaTas4mYwtmCYLaIiN5oKDBn45LnM0YbGCH7ca2
vxxGTvmt+/H6i0wk/
k24z4hGY3Se4MJDMkn393V86sjF2T8gCRKAqOwEhZEwrSgFRSUNZyFTIbDvAKXshbpCGBRZbtRayEgJrEFG
MommUDmTNNih9NQrIXWxwu294yCEcoM+vr0eSCQ3L3o6MNifngWQ1W49hcNt8psAATwQuwfOErlf87M4B59
l14UZRwMomqDyDbupfjTHYE31MCmDXTgBRJNUHrK3edDuoDG6H2+eQNJt8WRNMdGTyaHAYZzlM2ooBbKFlR
M3pi6Myg6L//I/nk5/kzn4fTx2i4DGaZLEbgoACRUSVOktGGwoLxrDoADs772e/
NpAKUU64gRgEZUrt3SF11nXRy3Lt2h1TT0hH+ru/
fZqhXd9G5CBZYyJKA9F21YIjAor6ENtzApo4nxhNUBTVagyQvZPKUynmyBiqVbSSXoTgqx5yKRpKffcj+x3
vJv/2n/afPH8R+guNUkMgjR0cbAAvGC+u+whIGzedNn6kkC+iKv1cFabEg/smP+DPu//VHrj+bvM1u5b/
J2wC0ZQ7QLTNFYVWxGWsOLsgotvLQfPWGLJAg2F8g8woPC79J3BzvB0wAgCLe9mV+IDv3zbk/
HIk+wgVlmCmZaHNqLybgvJqgPdK0E7gQyj1w6gaOVnan+woAyvfMDsCBdYYEnRIwo49MpP3X33d9gl+6hva
OVchqjUY0bCFaWZhtWJ0AAmg+dupxdOMDpAWrdulIOgTNYSIJZHxlsAQgCqDQndxZf+
+oKa7ncMIQkZiWnMm9Jl2eRtO1ZB+7mF35YCEXkZxAabSS2yEAowETYAGl49K9LhCnqh7sbuFdt8HzifL2N
azTBdgAjyiVf1OI78YoL/yF0zZHKJawDChKNq/
B01CfL2v5RrrVYoWJ+oOv3eIFOACMosDPYAdH4zEFaThAVESyOcxsonlD8+9ejterrgEVbCazILq4IJETqL
dSO91XENDQ74v5EqAgZaEzxsTbaqWvWlFKIJnA6NDfNotRaUqXeJPeYRIwi8xXb1f6Du859wTS+d/
2gutidof3jfdaCSKKGj/CIeUIIdy2OGXh3GRroyEABGFfiP6uT5wTMlAK3Zhp6AhGaxT87uXod7/
o6rXli5S54S630G9BYqTsOAu0EjvdVzjIhALTumQVWQ4Z7tCCVqBkZsYjRdetKoomQRVmob0S0HplYBMMYo
qptUKZ2+CL75dtVVqe0nUAEbvR+0Vj5nkaeD1zMgelaK2v0OozJRqPiFKP1rSxupKAFG8jA3BoASfOd+W1k
wIN4sbeYW4d3VK1hzKzj38x8Wvk102LXpwpKFBkKRQkMki3p2m00rp9TUCHBkqk35QnfyHcFKww52CTpC5K
SmGaU/
ByVNNBRUeFSt9mKE6W86iINLnmxd8vl37Hk4kSrk0lKlwOUrU5287qlic7XTPPWDvcOzIql6hKRtKCpELZp
8KGsLAANGQAPMMgBb4rOlsLMaLZjjXFmGLKmFoe+wLcumxwNY1rqQtA7xJM6OELExl55uTxCEJJ3b4Gc8FO
kS7WkuZQuyX8LcISsKjp43NpuCQNvvXhqjpR7gN/0aqRjrJyLeUK3t4t6/
GE03MZ5jVrBZHBZlbScJg7tL7uCtpbnlYGuJEHKUBM/
d2vTa86xtgKAHqAM1UM0BaGGHEiISmjbdQFN7eeqPPdqdtfbHz2i6lLCRaw311+RIEia+IrgVZMt4MTHySl
6/nSSpRw4KnxJ4XmRen5jSKh0CtauxovajvIEuX3jquqfS1cQ7Rqtr/
9FIkSCklhya2efO0ei8vXK5JJvAC3/
Q7fX8v8myX9nT0oA6SGQagVd9c5R4uKsQFLRhJRHj3eF7v9UGnrLEjQEPLQPEnjYFAAZ2cT3FO/
BYqcViCU0WsAcNCBJSIitzPuWihBNxti67NTPjt1vrm23C/
4azOoQgg8MV9mqzox9XsZdTKtY3uczXJ3CQhUfvAV4xdJBKkOZ5SsMmxXkLoiRsbN4Vs8rEgjOHH2kFF7yr
ZBkhRKuCGlDZuv1LFwwJOa3bGlI6XtuVB/BGb9Vr6sWKaR3NsDWdas+1TKVTzA559AK599Thd/
BQM1GigSETlTsIyjdIsza7vWuj81p2fiE75FX9uVDw1c1hHekNWGhJnqxhcXP+Mpvwdy7ULnnfZ9mRZ5GVE
nyFRzPH3UfE87PU6TjI3u6eNGO2Wiyrvqk27ThxDWEAmVBBCyqMUAgj7g4UUhwQk5uw9RLlyJ/
K2btMcb0izFoSqs6jdKzoIPXAm00gFzEByQXAVy1GH1c36fmdZRnUh7k3fE07rLvG1VUy8chuq1rUJ1uBjb
9OzOVFiDB0H+T+nthgPlpquSkWKa6lim2l7lJV67rp/
bJ9hnIKcs2bYNR2aTXAvjaHRrsA4IEggeHp68OMKEY3ilEnV04N3jNuIy0lppFKrAmJEQuYucVlYyd68jQx
na710aDrwUERNCpcAOAdpQa7Sm9hSLqDdOreXrn9uIvemn2O0pnqL25Za8W3sWS2WWw0RrOPlh5Rr2xNAwx
kBEdb0uhXT1a13BSMoFy1CMoQQi2ISLgrWBoAAKk4Mkf/
iswLZjW2MSWnu+2IjskOgwzYtFscVY074iUy5jJPkC0MrlAsdqLmzK9vBpCSMC0SVjcMCtKcbboJ/
B3RjC8Nxafli+XF/ewKU5b38tV3vf/m/nC2ticsCS6DbouItIDHRoMPQC0UjYw/z23QFwujniF+cb/
kznp0JCgaaMxyoZFy/
vqbNydd8X2Ou1m5rtJByI2+eLD8GR5iPHy5mmZGoje39NcAox9RxGTisrk7vXkeFs1AyqArU7R08ZdoMGu2
jniAUVaklZV/
EL2ljYOdFo6RTp2uGcL0UBZ79PfGLIyAOeFQtdwuohYQ6rxQEco+W8CLdXW5bCvDjT67hl6+ZsDXuavmUfQ
TPaMgjIuu6hv/TceV5fA+
+M7zxLqrUs78F7yADv6Nn4UpPTEu89APlAyUUTjzGtYS6TM7H26hfiLdjVBSKcyxh54XgItBK5wLGSjTiSX
lM2U0UH7UaKongs7nzaT7BjofaEwpasiiNsYnacVW//U+90wSBUSLVCB0lQYIrTgsAgSS8tfPU/
oWMMEIou0tXtb0uryq9vftOf
Sit9w37AVS7aQaBDBxrVPH+8M/y899p5Z/
nkneweyP6dQgr7vDBYTwhHRmismi7qeITdwMxE3nbT7iRL4Pzqz4OAhnMaCdpXVhq3g6imH5tJUCO0IvBEk
WqDavZMiY67ckG/
erDQxsM1VlvAVxy3ub+8PcPrvJtXr1mGmzNaRCEBGzaUhaYIHTkmdEwwtEFgbKns93W8f+uysEKlnukLVA+
uW+P8VyYW9BV9Cvla9/ysQEOXLxm9/VV9619iISgiBitpcjRSPUfdBsB5J4dRqpaoNXzn/
KRRBSdP0gn61NjjiNzGmvuVFIEglMUFlWyS/
OaImRK0NhORJQZfXNzjLIh7rcrabORSWUxx5cMWSyW7tYOSWS9TQ8tpgtpANLBzPNFkOTEmPqKmjSAJLmT4
8mCSdokcpJzsxZERtXJSuBqQNkAAIep6pplQMhfMIKDqfwdDrM6ZNqcZYaC7AFUHBD1Q09K0/u0BH/
yKHq6qLRL5fATnNnJaWVG0JVVY3HhB0zwbj0nKzGju0x4wuZK1uvJkLmEqlRwxyyL74t375HLJ+pkOpH0lX
J8QJE/Y2t8UaGOVBzSTiVCPGuo+S+ArVPnp/
fd43W+ka5TrYG7yjE8VoLeguEO+AqaVV+362Ztx9U3c3zJ/
itaHqI2opzjN7WubgRYK4tQZy9xlrP5cIBOe/VrSP+ESmAVRuY7TykrhbhBFRrZSzxEueU/
pkobSrm5Ra6cTSHQpu3kQlkSEVE5ORPa9KN3Rl7zukJ8VEAdVAmxiOH3hN20qOYWapA5OoI2zlxsw1vGuZ1
7v2m+pY4Hz4+lQAAHxNxIflzx/
mN6fKGxp5z3z9e28wuvlCtfnK+Q3vtwFQ8F1ttMjwZaSNwKlMXQkopXb8sAnhlvf/
jrnQLwKkU72ynXc+hxYXAhgjmM5226Fj/
XvgtlcCxznsd5gky3WbRP90tw0zFtjxebKrrcSuPWU+6Lk3t8EtqBZExQ0V8EaioEhTJWkbVRp0QlTS4em1
+5GMf22dhUXyrjVXPQyc+Cm6zD7Dnz7tPZv+/
CWRqtmT8k8UUHxyUAYROex8qmGzuQIoprnsWgDWdcIl5gIg5RXr8xqjKVvfwPCVRsQNZkXFTrygkJor1uAD
uC+H3jaSTRZI+tEHkZfw6otYg0cOuxaeurK8Xlz0tm2qxFzILkpAoQBoyIUVaJBNCIXh0+kjEJz5Kp5uX6z
G8na0/
a3diqH7Lkm7kf94V75e7tYxzPyF678ymKvsbc6zUvWoG465wHJzj7vlUrH2QeREQ4iQDXEORGwjky5cCMRc
vTTX+dIEp8kiMTUVPjK8PPtHge8UcTRpVRx2s2eFs9k0OwkmA3TrNFbb0JYX+svzaxazqnMHpdgUwxDBRKA
Cmi3hxxbWKRpej0161U/hlSYhBPQ2FxRdV8Z6rZ3bvQKtOrXmMpHsx7blafnuW/
7A+cFXTaZVXEGynrzwAp59DzYNcrhYbgIpSgl/
JBnk3AIcM1ZX781BFeo23GoUMmzX82Om+lv6I0hc6gYqOnfd7evo4xn69vnVvAZdz9KjSgjJo5FX3ELOqFu
6eSGhYht3dLWE4rWtVyyt+3dLWPiCw9jArqFHNthNCKi5p05BdXZwEHUqGm04yM8AHDeyocZLqWIk+4+q6c
SqXmIxlD61iZa14oy4us5+77qubC19rfjlOGS/
Jnu8EOS5FzEAjY+oFIDFxva1v9COE18/9eD4YaM2gqI6FT4GLVxa7C41y74DtufT9MAD8muYPEjN6Iw6PEK
tcVkmrRq5VLRaq05LI4Iy+DgbE91X9PmUSjGitmsWKTUBuLYCVqVE9GuWmqjYA6Ap3DU4szG6HXjhiqtevV
5qr/AzQ7tp32dt6ELD7nRlUsrmRGoKqDGKI1bvdI02mXw34n9jQv/
7rCmcZQWuRKUxgo5T0Pb1TU2WE7GuFKuFKnh9nfcyMTtE+/uHYBDv4WP37mg15aFQ8Nd3rVeKm4l/
dzUPclyJwl2uDI90tMiIqDTdcuWA1Qv8pG2X7ZljSpsNP1+PKZD1QiCZJNCpYLbpoClFcfEyFrde98OnjS+
V10K0QBFmqeGL06P8OPC8iACNzZCTqoNUkPjp9WP92TmFOgCLd7F9OuTMiREAEuC+6WIdUqkKW3p2QPGPxY
b5f41hX8p5etfURJx6rep8JXkGDTsw4rrYF8zOJDfA68wIBJnLVZY07kJH/
DJuqN0pWuiOZ23HfrqjMyFRxy5rzCFhBB6jShQDRgiFSFQjxUVbDTnydy1VJpLrvKT7+DNZOM+aOFZAVKoe
TlHBAcTwlwET0tngtcCuS/1CfRoQDqXpXVjJKW0H1qZsDFpEYMXpAChGEXwYTFowfxb8b/
6h6AExwiyUIkaMrXqt4zMgktoir6I6IBQVgrdW1AUXlo4nstRiU5MZcakrT50w+227foHffob3WXUpzx6cR
Qi+8QBnrWEhBZYGI7bZNk2lg87BCeieP6SG5y+sKPyLnrbr3XRuxXNdhwEw5HRyVacJHda8rxTF/
FyKej1Fq7v7tV+iOSYuYouDy/CScIRGD8ZeyhgbtX8GwXFGFJQDNRI8VCr/
v1UM5BLfmOZcQ94VObYKU0YrATQcGSsraOZ2NULsalLyIBSHe+lzyJLLnW/
eOZrflurBSkbk98UfBENU6QAmzTi4ArdSsi2EqDCTNkJLgKPfNHO4du+zOYS8ErzVe7y6FYIzp5TUhGymvV
6LXt/+SVdl1z5pj7BufcP6IyDrmN2YsKft/
xolIerWRBIdKL9nbbimTFVCDbEHGKBtQzqo1pGcNn0nakO4B3iY6JKLwSL1EpRKq3jxUXBpFJU+lbt1wlLP
rhrz9thyd1H6xvQBuZW2AeSzjba2MEGm9B0UVJyLGV0zpe6f11zuHzdN7kMgDvvI1D85qw1ofY62zaoGUKI
YjHI5DU6wzxB2OhpZ56FEdn85NWDjarhDCc3FIUXXddMDtW3/0pCnwGlYwWs6JNigTXD1mBxv9y+rhjKZbv
pBwnnBBfOTprYMkX7VcVsFK0EJ/wWrbppJFwoGWafUkmRNoYC2cjZ+
+wlvSzx79TaoAt3mmnGGzdwmS0nFxa8bHG1wIxbfkKj2OjrGoqa3fVmarRhx5B2M0gGBE2sohx7tkZVVZ0F
KnXCkTZbajQjRDbmgiad1WfHwI7L+35CcnPK9Cw7pn/
FVVwFTCJFDKzqHiu+gxQ36q6f8+djNAOugSV0jgV6pl7QLxc4hnFpNwX9YoIDz9hWN6tafGYo5xMTK3HUVc
sUS5jG7nD/
Sfeyn6FGXFwydh8BFj2Y2yHY1WFLddZds1gMwWKRDXktaYbcy+jYbEdAnPMYWk5saWkzEr+Ywjf10qZOmHg
wsTmKLGYYUcUowMDDTXvLPQzweG3apjVZkT08Xul2JIWUVp5U1b53MIbu/
SVV7gLrOMOTNPVC77uS4DiFd1sdHNS172PGvkXUMXMNfnNOV1F5oisCHfcPzBAgHA+b5EF3FZdeBeyKv155
qcnwNSnfLbYTQa6Eye9W4dSWcKDpENxHam7FJJZZWV3GhcpGsNSFbMhRxH3hJRJgQ6qobdYstMvAg9JpolU
/wRJdqaCjx2ahAVCCShg4JY02Rt/
xc6z2gIfuKtIA6sYTwBqQ31e7n5pZpizkHl6f4e9o5xDogfgLJJOs+qi2RHpnZTCUTINYCw2MxLcaOvZqNM
aFpiNoh2yAolPm9nCTm4hryhiYLXo58yCiuJ45HUjZ6NQ20Lqobk1JWNazqmIKjF19qlVIkxykYQUOeClLS
kp6t3jR7+7u4N4Cl+XizJ4u/MpHyg2t8D4NoFqd/
ReKBXP11fB77jHT6BsBMgOxfPYFtu9vRg5XO0Q8+NCKPaB5iGytpo2Nif4SKxIkWNFukeVQdbW2gSsIWiDq
gO0ogJozqxXejKpBtbkvvg5o10WNTv0ERKoVa+dBs9vrBomoVWjXB3YCb7zIDZz4Vf9VDsYBhRVjJSFmxWr
JBRY22j33Yl48fzvTw51M31TvdubLN3yCY45yRrhGv+Ni44SuC5KLAthVeVbopC7RlgFRavmqyCGwS0JZQT
Y6mAuNRXtlcpK4tVTbpD0lWW13BJmArSKTcykHAtPfCBHvPIrWf7iU0N7jxAHAbVKNzuysonSau1EvlUwo6
Gln93NTRElhVsmGrYgfCu8v3St3SQgk81klr75fxbWgcA2dPoSgY0mZWeB4mf9vE1y4sY0nR6hhtjDpIQ5b
vsN0YsiurjWpJK4EvTmzIsmr1/HcGvGlDTJblu74WCmCdm9NZEqwXQ9mZANYKleek5GIdN00rdgYW/
FuBnePLtQKkieWFM+YYsfsG7vPl+MZMpKp7p3zne0cNAKbHjaggP4GjJt/
VR+FoRMOss5w0oj92nPaLsAcnKUHa9jUlh0yKmHAHF3hXXU9PIwOJCtQfMBiMNjdH4YuGqkaO2vjDc4BXlD
oiCHDgl3JdsEZPR2JqosOtzBt4iUEJeOgAuVEJTLnIuWjNJprjAfv9ICmLSLhYiXJJaKOyc3YbghG6mcoq6
qd/IEaxHApRZ075ziQ+M76O0R+wcjLGVyh7WKTltKcoIALNWQOVWWNpwjolFf9T/
rKLSWMBlqa2FFkpHQ84IGhkhGHGrjtdcFY5fK0KOtaVRMWsSaa6oDJQ8nfCpOlSpBU+ihfVWgskVEa3C9yS
p4jZJnYMogSNLTVq03cKVGdnk7PLzlem30B+tvzmrBJsIoFzTxAjTat1oYvB6o4dIU+aEI8PYGqZr0UELer
bRIDFRGNFGrRJ+RkGiQD0XNvuwVAJVBDQ+bfD5us6Si/qD3oJE7/IDoA6njA1Z/Qb/
5SLxWM8jKOUw6TYEaGN5O3R1rFQkDDMG3rSbDOw8bPLODQmlOGccDhgvvfc9/
MQvvgkjy3PGeRGrlxo1nLJUEW2uRf5RILTHg3QbUOoqgiHenAOYsjrDmWrI6fPxACCffkimQpxzInTcONRE
ExcjTU78gQ9GFcZ85Nuwp3Bc6pYQACKKWpVFGqTEqrCTP9P3t0hFtD0RV3KPZuPSCU6cj+0b5PF4sZbmIZo
I1VVi1fzdusTDU1xHAFjRiXNPkFDBaaF/dCTk8DG9/obqTtsWI16wHt3F9yz/
eVLvCJMyTsSWyPKxfs2JdAg047CMZ4HGwykA4odtJOIwA3GM0exgFtyIkcLsyPClO/
21WbpWZ+7w2kZtPXCJUBGkNvSeJBfP0QLwB1MeAuuam4hYYAMJKnoWs3uSPUYBlyrDuGNvvbpheP4lG5CDF
6CcY6BwvsHHn1bEpKL0BS1qPL+lKzOb12jc0YFnXmO/u5k40W103q7wd8BLio96yG97PsU2uC/
8uP1B6LAY6yq3OlEMqR4Pt3lCcikKoEUEMTV4hJ93XqRHzC2uXJmtQXozxGXk/
9ro+jmmeNR20BSeph1XG+UbPwTx/6S/
UtX6DYnq2Rd3J3MTJbrmp6mfJA2Ru3m9Akd9T5s3SzpNRO5aLQmFuMF0s5QojiMX3lrEksBkzS6ovw9BdMN
/rlaFxKnkyI+HFqDLZAtz8l11ifD3GCAThVdu/
Kx3fcbt5EunjzDOLZYEmTV0FSnMWVRVnoiw1AiNJNOx4R0V1KKUfxUKjtVucWPKtgM2QcNFf/
kZNRGfvrXedBOyDGyZzEpli78DAQriJh1ZxTfurk66tyZj/0MoHfBQkGUh5iJJCNmapUlUkPC/
vN5H3NraUWh9XfuBiuRZi8GIyCEFi44g3FVTbgcDPSMFYnIwN4CgA+B3DwnHvceBcFKr9KaEwc7gbsVp7e0
vOcsllj9+rLwU04uz/927/RiIwHq8FpH8V+Qzahz01whdR1zXl0S9tpBiUFJr/
+ZaeLlF8S9lOwCE4kcYHs9+UOyDvngnBJ/W6704USsn7b3E2yduNA+R4ZmfvoizAKQ3bdJTYQIwS/
5KniV6adApvuTNOUk9cyN0utbnK/
1JP59i4b4mrqAF4GTZrRqog3vEyA80M639zJilO1H7VleJLscmZ7K4yeDYbZRZm6Kazv3oT9zXHiaDqMjYj
9BClO+vXfTHO3T0CuiVfKpMg725QAnyCcmNJ0wJgoFkTKMyEvUtUQE2Ds3zbj75x5HkQbKI+Pa6G6/
jSp1qPsxuScgdaPbwKU1jzAuZw79uYvAO0SYpdizhKwXMQIncpzVMkfTJx6S8dRSQmuMouxlHUPI9UOFMxo
SYvSKgEhKGw/0ltbGst63PzE7ZuZo04ZxvgAcA6L0Fy/BLO5i9U5f/4Ejxxd6/
l1a3W0BzFQU5QQIq3JC6tFrinG+/xrhgjSK1EBwHakTcHiMUYR2Fj/
IUEUTxfXRE+ZWJ61fL8YVXB7PNqf5/htldpGStCLUzEUX7Ibq6bh3UdfzMwBK7TMErd/
jjHg9JjjBAJ+vkdYye8ZSlyLT2k8B0JHZ6bv0YRjsY5T/
0WKxs7z7nloxy+XlsaoRYyMt5fvGmt6CErvVbrufqdZ6Wu7yShmV65cibfT7TlAf3q/V5v7I9fkldMp0/
ms+6sdyRZLbmUaQ/sy+cBqo1bF2oQ6YIhGes8GFCcc8BIJylLZpJl6H1fVyUF/
ZM6hRwPDRYRwj9ePWWTBhYvl7ssuTLrzgWEwhkuj7aap1+v0x1tMzSxE52PVtYOhRcIUCWv47i+yBZA9C7S
ATH3Sm28JenBsolu4Pv9VzTLAfBtqiNIjry6ZIAJpIIMhOvMSCRZzSF95smjS3VAuKODc7rj2adABGCLecl
jO9OAVa4cNah/BwAN7CIerht0qPlYirYakKRaiBsJxgObE6H8KyUzYBEMCC/
30kglHbypAP3uvMLHpDjqwKyoYBbgeQo/znANFT2ZDs9LvKrZN5CzUyHqulyjNUCHTtEDhSAPd/
iWkzvl86AGxU2wgzMl+lGwkEnW9Uz9U5riIevEYustjV9LlEghCDGxjNPHm/U9lJyYzi5PXg4/
HLbhcMKEyOkeNx1FZ9ttKnshscI3sScyU5hSTQoyD7OnO8R8h0+aEcDbeWI24lkwjOjXWPsZGEcy00FXXGW
m4ohVz6EG/ppr0mvGSmxfP7Wv0pfIWbfqjG7QWRbwZLxqUlEC8UWeZcXCvj7ARjSaUGWCXGW7PJo131y/
7C5/
DGvjOr2MRUD6LOoixs90rs2UEGOhMlZqKRLBYbl33J4pzLYZEduhdfXtvLa10UokCo95Xpahz0VLGDOjqey
5yYjYby+Pb2bs4cVd4NLcYlXRRnlqy0ugkbLupBx+zjWCEydKWKENnDczVR35UDybp556DrUHHYoQwbP2Eu
SvQ5MQiq8M40owRKoPNinYVBUsKKNhl80xJR7IcudPdknlQWhY58+devYgAIqjGwhFxb6O6Y+bJQoj02ZJv
Fbd/4zL+TyeIlUPAjDj1manNVDuQX6XH2JusFZIkIw5jG1flx/
EcKsNjo9T6kPaumaN2MWCentnr4xjbZnmovaa8bWv8kF1m5MxbXnVNtaXqmLKGZ4rzEUbI6SdTU0z6tnL+c
Ol3b1m/eXiPiYweii/
IgE2NuIj4urn2K+hRFeY5B85WOF1w7Xpj4elEp21u8z99dOKMgBv1i9MM5Asd4X15m8zyzxnmXrVm9cJShI
O2s2bPegSxGjDIUKEQCdkbdfHj4wmyXwemVIJYoVMf8vE1pqZqfTmCir51pZt9ruaW44TGTW81phIeCq1CY
tQMhFU8/kW7dpNVh54cenOZlKmDbLLtupUunvtgNthzFnm6kYOY00sEXzqpJZAv9HftMie1jybSU/
l6tZlsDZlBkVUvGMlkgi2WCtT56pTuQ5kUNZNqn0x4paoZe8d/1bennVYl/Y2PsdZFvOh1m/
SZurSGGImIAtTocax6wUZamLIEWMBm+Hz4lsVvYISH7R4r/
GM20p+PHFe9XgsfbaCm1HHVSKM5fPCRjERgy2CNFTiEOFjGujkjZ9FdGPJeBfbQHlIMogZjicaZkz4PsafI
s7qRKaa8OU9FQw/txjJ+uV9h4aEQWWXNfW8/
xuSKoWV1WmJsJuTjFkRGR5O6zxzmKXtfD5qjZgewwtqxySLeRhZLv2ZewJlmokSN6x/h5D0l/
O7uYmprVRkIS2NLy7SWzaTVm1LLf8eCWUgwkQT4KYEP9GNH50jxkkmb05nq4WR18uhV9oBPyupa161JD89Z
fzyYqvS9UU+OT/qwWjy/OErY0/c8AlZGNPWgggaAOLSBEGxsBJjCKqbc/LK4G0ndn0V/
gQ2STELwPdKIvuJLmeiZmm4/1ZUyKJWRb6ZlPbST//2V5cOrlzhpj0+RCPv9vNxvXrd5/
fIvHp+GvGtJFE/zlC8rlwBElOaa7mVNZ/fkCx/
ebDAEZxcoVieeUQyuSxxikLSEgyT0KD5W4Md+iIn4+ZiZLQPAqF6kC/
drKbFr2Vv9oMG3+eXLM66e0mz6afqLElcyQk5xlip/
Zsd0bVXFjcw9va+kDTBrTO32oBBgCjtYELZbiEiuBLq5KMDrmXDfHWKw+riucjz95slqwTmoK39PupJstVN
fZKPg7FmYWe19rB1rv3Og0hNfnbs/
vfR8d6nXrrDJm8K3Az8fH9/3XwzATVnd0nF693N+j3yKTXNcVLZcfibPRqYi3VPv+/
EAgIEYJE6j2GQuEk1e6iwRA2sIUyMMjxWnsyCJe1LJxcwWMANOKkyfevVYN5RfVY/
3XdQ2k92VCtkcyrJclr3GjB6ARZZS1WHgKAHaVz1IsGobygkWGYAdauJyXtHPB8Pi+wQ4ifIxNHngPe8GqI
CWEJbf3vjypvoS7IREGmALBKGXLhAkqgIpMVvWzUHxKmqhSc77mrMTTLuJ2vaYG/
OzDCDABgkhszBQsGCCBYVocmFROthb5aap1TYnbhNSbRR1gBfe9Dman6U4dYcs4oWOSudsZvok53Upu2puJ
bRpfAu1W9ucirFLfLC3WjOyBZAYOK6iC0+UzsunYyZVK21NN2BXGakaNOO4IKt6yqtC8jvI0BDaueZd81k4
IPUu9GZwxI6YCb6qXiKU5iyBsnIJQkO4lyiMr9mH+8580ixGbrvsk1Vclz03jdlV/
+MmLTOFCAEd1fWYNJnEauxiICIEosYB1ejmtvn5ntCoEG1ABhog1jd/ltYXIFfsBSXRFC/
dB0bJBVrOHHQz8NtGfoZvfuSOCqk2Z90fvrk8SgmmQRIYjlIf43bRUqRwltl5F9O1XUtB+diEZGuiYpszay
LQEamAcKqA4ST+L2b2eu5I3C1ikXBdurE1K7TYrqgLx6ws5b+A6dGRITJO12qP/
p51OLwlpdLj86j8XVPrvWTsi/0NrzUBysKnZLG1P+E5vZlSh466fr7s6cXvmqtKxTBy+vuKP//
WJMCPPQuOZ0EQyIROEDczCN2q1GsKwlXcYFNaL03HsI18rJ2as1diaQaEAYABMa5TtTJUm1A7ZHeqKuONeR
5RicWGdsAC7SK7DLAVIzHYvijU25imTFBgFxm5OqQVGlnr7ylSRMGKdb2k4x4GCyWsr5a2NCXzy1RwJryqg
VShZk0XQnttFjlyO/
KwIGnoPn6VDtKLRoD0462LWPtz3jPVQ3eiZD9R1xd4+2NArx0bapXVUMjoofxzKil4/7PBcBZCdOoeNzX3g
Z36GgXvcnguyJvF07w01kWVfsAG7G7BVJYxPTTZZiXsUmfU24br2lSCN5L121a1nFrWorXqqJmnBOc44a4u
YapQP/DfRryfIJmSgP+y+jpkCup6WjMlhJuicgtDkHg2/HIwJdvSoI/h7V3igg5Ow9Z8hhk6m1M5lXC5q/
v4/gVgNmbYGsFxVWizpU/4TtCmrtOBhP283O30KiwVrQPmehstCML/
2HM4Fih2lkrwSBgpZvjHDtlMwTPZq75nShSfX+T3PKpWgZs9V3vlRhhKeshpyMkw6KRKj9pdtfzgxYSjUJh
VOjKx4QosLCnWF01BupkBh6u8AUCD3/QPfm5X3/Q/
Db9TD9H6WqoifcOiXX1wbLkseDeVZXL4Gk+ThpmdW36/Y2E9hLYsa0+
CBlGMQ4bX4nm/
az4EKqPSJNu5l7lp7ztJf6KM2Dk8djL0SlLvl9lqq+eFUqYsIb7pRwzZgyPACjBQ3HC2zgCvlvh31QUlxC+
HrVRZrMVZO+QJzV66mCHuTA1r3QkqB2zfXtarU8xMb6dvwbSGzC1OTn3T5OIbMXx/
xvFSdF559VUCVWFi4LxHFkKgCGAiTjeMrlfUdX3RjA+cxVZcym3JGULasWr2FRZWafnKPQCwDlGJXW/
fv7YY75Rg4oZRK20s2fdTgvsQCrOaCRD7CZropJjFftJJT0KnZLSqq5OKTqkQSjqTiu1GecSM4ol3/
Xed3DVjfwuemvpmC9gZR42STi3wMBxbnV9o+K5fVm04jyXY++0F8lE1SBGJVzpCdapa5R/
kkl5XxocmPjJXSxcebFANK0sx+mCtEv2mllPtjYK8A98kN23IW/
gF6OW72qsNsFxzXKIx8k48lz8Ivm14fT2ZGMdsIVMJnsyGHYk92FXL2gmyLXYfKNoz7vdZyekfB1YCG7MOl
E8+frp60OgHKCkTkKgHL8qzppxpnvaqiqg+G48q9btQkYS2xiPgmSeT27UfegrX7MIVqBF+vm94oiM2U9RN
OraXmI/
o7aqKsGuokdleWCeFACebsjMpFfacqwLoaj9+EiuvzN5gaDrSEYzlAtQsqau3tBjWf2a1NVqz84ASmuWh4k
+o3hoHpFeUzhPnwjWSJQPmpnjLVhOKHEtdLtZobnii7xJ8GP0Ca6iRRpWQzsN/y/
Ngm9nMRkfGMDdFKRsf42qfa9QAtCHZVAhqAUlQdj3Diwvy9U+jwh6IgiEgUu9wtk4AI4kM1R3uTjm/CN/
9y2be0ArICJVV03R3SooBIJc5Qoy21Spp5Rm3uaVUzSN5YzslhF39WFIZl7Xsd0iSrrUyZoL5aApF4WBAys
lQx7Ky7fQmuPSuqb2WWpvr9/
lNuWiYa1ckWHi+MruLA+FXbnOGUfg5rFFiM1LVnVZ5DVwQwDndGKSYK8j87ezI0Cs5YcugTc4Zu7yJIEh1i
T87CnPC63+MMdYZPWz3ztXATjh6KWqF04WiACyhBdG15Ase68oF4KTbdESUSIwLS6PQmNgexFnga/
VdpwkMF5ndsWzn3mb47hkD7rBmFrJ+3ZIz0L/uguc1dxucA4DgkSEaYc1S8XScrwmjr/
xqqfaHtTayH0eCocjYFouvQNgPqdndATX5bXe0BcdJmvcmlmfLh/
zDCT4hpYCrwqwdeOh7ycNBOMrX0b32J596BdYHZDKPXie1DthM0d1RVRQJo/
0lWpG5Nq91+0J96BdAbSQQbRipUwz1mfUQmg/
jh1bObCZ0cLxRkLEnaKDhqrRardUbmvylkH4z4AB4bqJ2HgA4PSNkgXNhKKiNCF4TFX1JrAtkx8/
xQlFRxec0V9uWjMTbsxZDVRlAxv7nx8AQg/
TSzaWpeFahWB4xpaZPAlHqNct9730eAlMYgSidGpMkWKq46BuPHs6mDlgTyzyPqVxSCbM5onc8ACW/
etHWvtb30UClEUaVUQW9CBVgGQl/Jx+xiu4coGa8pDU5+zJOOx/
ERrP2bsaovOFWAA1suIAWVDiIWNi2Z+cFxyrBFqAo6Osl/77Fs42SvU/
j+CPqmhc7av9Wwn5dZ0OcqByTvqPbtvawuriF2UxXdnX/XG8gPYGotjz0icUDkjIs3U4i/
3obm1M4UFsYNvEIegCoDYRK3lCWZh1Lew4UFEzzB7PW1umZA2Tbk1GVNVlK1aYnqgCmOloR2HBek7aBa3mv
aafkNOQB9+SDIaSl0M3GlEztRrnpfmM5jsRANjxgKc9WJWkwsUEKGTCa0STc6R22LdtrKv8EP9rTakbaYeH
kLx8SizVMxY4WkSyM70kdW/T1grjvoaZFFE6pZ9wvDT0UbWbdzjaOgGTf/JlXBI/
UO3oE8UpTBgx0y2QlmTJiWRC9Sr/
rwfEFbZUxDmt2sWp0yQWjcR0+1tE21DkrqZjqa+NQ+V4acx74AREjux5QiD5fHm3CtrxOP88cE2+WhF4D7A
9yb3M66zQIHXb7M+kjjkiDEz9PlMgP12ULU6kFNEaDEtZhwTcc/rDP3d/
8Kf2K2QAgC2voTWmH0iB0Nwfar2Vqx7zJDozwjcaUtb9AOZ4MnBoYkrif8gzgIWROQN/
P3GT7O8TRkvQUXMiDM/zrIyhIBlTm6aRoAHp7UxJwwWv3wlLN8xLTr84XhEy/
QF9gvEQnNCGkfDUxsUrDvVo9S5zVOUWZQPKIU9mKOLDqDg9fNQ4k7pX7K8Z1YbRlItdxZXPgrjMGLSjuJdr
NEfRnSDjfnA3pCAdLkSPqlrqbh/CRXeETuk+rqshGtOm0adVI6sQrfXZe8UZcW4JhO/
wUYahqj59Ztf3UOaTbngCknG7Aa+cZ2O8XCrkUCpMghFM45t9/9RFET4cqmym7pc88nGeEvngEiiPzQ1RAa
1d7SocPh7tGQLGrQofM+2B4o51qcLHx+xqIsAAGFI40KDqRnSivTkI8ejSA0327zt3P4pdFJ0fF+JmlLbCt
g4ER4SgpsHUbNUcvb0wxOVlRy+zCkgeDlPb9XULq19l8P8SmfPdoqx0n5iK/
P8/2pCJpV5VmBswZSHv5wDIz56tKCgBEa0on3VC7r1AIdpa++Bvv/0K9kfwI4myKgOCGkLMFa+HRKY/
8hwrK1fG/2WOsiZxvFy4/
Pxhb7NcTQiBRmtUAC3xOga81QDRgDvoQA3UnOjwG0zWJis6jglavO5q2Ikn9YTmWeGzFlqQFT19eO22XyzK
MbvuaBlO+9cWuuemp99pP7arzkI2RAoYJwWprY/
y27WTRjfoo35MrqpAU2zbZlYdVthauUwvklAqQIXOu0n57e71yGpT6lbpQ4RD/
9P5RVBMD9RhIKesk6syYW5t1kbSV9qQJBdw4Fgz0ynXluahao2AgCSEBjE4FcKXcN9OVWviQWGqpPVhr1ar
Sag81Bsu4zE3iteuBVKu1u9z+7f9+p+kvKR+2Bk+QJYJSisIY1ZgmBw1cjJqrOCMXbI9CJ9ScP/
60UBfHZZ06otzW7k8/VWjxlUKF0DCCrOCxskJGf8wIecNoLPHQEMIAbySx2Yp/
YkDtqCJgEEcEBVCnBni1kAsE56jhFsZn5a0PSyu6l8UmE9QBB9JgvQFEIWVGk0ZBYgLBJaDyQO3BINQeAGF
FRlUYybLGxuZyi25h39nxlXRRjgi2WSjEZ/
SD9l23GQxghootLwgVDzSXVb41I6sDFd1r+jxc98V3fyTL2/
DSVRYviq+pLdjH2CicfmUXeDHmhhkEEAFH4m0fcgMgIVkwFYe6gIxkjKnxzxTOCKYOBMTSluOYFnM8pixDE
mm6Vg8n3ndyjFttEcGE1SlV8GCgBAdQzEBW0yMRJyCSRH4xW4ERTGzszZYKsK3IauB6hG2HqnqVCrJ8V/
QH4PWxzetT35Ua3ddyf/
X7pddsoCbAzlBGaiapS9OFOTCoXtQsegLffuP5upHoYBaA3fFPr08IEm9MUPjskBr6mJ5Q8yDmwkrkA51WU
1LAJDHAG4s8Qb3e+TtmIbs+qjec2iLaAeIQRwQFUwIMWqfQ8WKXcJw6/
FjWyUdA24rEVmSZUeIgcAUIAUb73CMxYRMm614v5dffPuGoWD+Z/E4x9fZihI2srs/
OYScULLLfsRAj88HtbRqPwhsWLXrYTTreLiqqSYae0C1rHMlMQhUvPsmtzGhERg7l/
Wr2LjZcTwmHwvEy225sM+azhK0ppAAAMPtHs0Ds5CF5qQM5EMuSm4rgR69SmCqwrgBEO+EcYOEejwXFUtAy
oA7zqoXCx6JOwi14dhzefDiAlPdD+gYU8BEbj2kWimcEkBNRm9kUK+ad/
eGmCuQXw+UJj+ycb8wnToKcdl35WbguL3wBO9+nCmj48Oj/
avc98VTYBm1zxQT0DntVP08Zr49H3ff3G3MCxz6ErE7XE23AV01Qo2Rxk9XQ+nhH4HiofjwBtGXa2hX+Atv
h0yCeQwCVE+VvJkdYzjBFetg1pUsKP5d78thKe1kMAMS0lAUkMuaMbsKSzYgkvDlqLjPnMjIGhOscR/
SqwVQAT0m5k80KUsGVANbwV2SNvk5jM8nURtMwJQywdMqX62jLlXKPFkbKCv0IRlrKAqiFqF7JcDYOkZBqY
B6CeGFHqLJYnApwhdK/
knFN33jZTL0x8W3Dqrfbtfu5xdjVkeMxCoV546x1Qj9gXceytjXSUYV+92F1zppCQGs4mpiR7aw/
oiFh7Y5FYeXJzFlUv4AEAPjvKcEmB1xIJSQRjREZOEwTbcIuA5WBhF3GUqQKVOEoUjgR1AaOO4o/Vjd/
HhafTDsuYDFdjqyYrrfsU0/Gcl3C7zWmaWl7WgtAqRObgvFpP/
NkW8WrASh8SvsKvE3pmmAEM2SvsXPGQwA7ySOE7U0/
onbMmjhTcbAWCmQPKdM6ZOyXX950zbUc4uH47h271Qyr4qjoIvM6Rz4ZuQdgzhs6QrIVsA0DXxiZQrdG67o
EDYySRrcoDfk9WNhkajGpVPZ2b84okgGeRY4iEeNZ0NaAAxDmyrFEx3MNM6VtyL4gSVVTMaja83vIDUNqAy
UERWWadYBVozfyG44JpVxY8r3CGe1sdtte4YbYgFag75V72xuotG0rmNHIs8t8k74GBUpW3L/
NQQrL2NIVrEiEo5ZDFLi9TKdGGJK+WjYyHhempWxl0K6twXXf5Gnd3QcHlp2sfpucuztrW7kt/
UEV4Ci3bUu4Gu4IPJRiIinO16TyBtpFElt2wZOtBKiQClF3CZ0KmRUrocgUpAp3HeAUT5xBEANOUgexbwo6
tVuHdZSFqg6FKi7kUsvGCesUMZobK6pUhN+/ZM/
I8PAJNkQsmce3PIr4f2MovmCXvRlnkhxO69stKdxxAV+ZyWsOhoLRuvhzElHdbDthlyXmAADQYnfQZq1Xtb
c2VsWx6mXacnDqehB/
ltu6LgX39z4KSL7ZVfsbfa0LfqZhBjURp56UKU5GIDwzolGC6qA1z+b77aEGmyuTICYYJgmtkniX7KXn0LP
jwfyZV53Ue4VdbTdNmoBSNlP6QJf5Qsifw7VeWA9CV+kRFlNh5fFMBskQaQrpCUpTs9IguFOhKSCaFwZXYA
iL3H5BpnCuwU6z4QXVWMuIm0VgSdq23WVvihGElF1dAXVc34zZ5e3gUKVqiEvNrio6KYgxwrWWOsfUBD8FD
9KtfkuEYZ3kyxu/hbVc2A4SYTv2UTzB8pwZMeROnEJtKSC507ZmcoEOSaOjhqcBQVanzH2Q9dq//
SayFhxYOE3ibEJ7N4odL/fzbPV4JG+7/
x8Kl7DJEJgV7F1KokXmHgLbwWSiV+pjTYdVGRxmsAfQBu8i4zIxILI2k7V3vIYJIY1mmJY6b58qtggzER26
qsTkiEI4+LpEr+fS1Fx7C/
oSk3DBt+w5CaTJEq0NRQCWKGSNA9y7ryhlPMXo5ZrdBQsxMOOr9Zvn3lamihzQCSejjnyR4sN3MP4Y1kTzM
HuZtVK9KMGIyhrKVKsMBEFNLMebpJqU7NTshsfEuUBOeX1AFs2YNt24JwQ8JeYyMFi1qZtxtdjwA9VoPADB
QdjnHjAqQ0KbkoqOS3QqNdxHxHMQot1HXAgxldIJxPIBX2MTRuNwopWudqSaeKECa7yAKBgXEvLhwp9k/
gqISyRU3xpkNCzujiHPYNg8Ra1N1W5kgiyMMQXYOAX4IHhbvNawKcduyAtrLuyChnE5kYEJ1ESCtcL8fNhC
S2XfxJVXrRAl1aqKk6gs2oOUN1oE4xxp4Zg+M9QJ6iwB95W3pBlWYdW0KVIGypiTc5R2rK95BlhLz618QSt
xes9nfE5VFsY0xTMuqrHvtWYBvFJh9QZTyIkm16UT+wJUGJ+0P6S2lBLU1AGezczOpFmwp8WzgFhScDiJTF
AF0cxH3yLdEhNhBIiWYNJLAe7k9248wBOD6Edtb9EJ5HZa/
XQsuZDE6aK2vltOfIO+BgzUoXYDfINagIlwOoLWz2QawpRrqszNAa/
ijQd1VlyBw3DrkXVsLU5LLHc3MipirAsl/9S3ke/BHTtJYXG0eNX1amncHckI/
9JgitEAL15mzYDOSyr58BNjO7SSqkov0clZEwEG6RD7fGpbFPcUn8N3Pgyt8kVxDuLS3Wp+q6K9rNrpSfY+
I+sFjamsjquoPYSY2VmyNOBP6txpVPyyhCl2MREZL79xzcOJXjG9DMbnV9Cw3g63V+ED46beT/
26+vlBown26P3CEM3GpQrQ8XO2lXmwy3JGcrLpYU8ClEy5D7V21dlz9GjVj7FbYzdCCSFBQoesFsILWqf1y
rTcsTiV4DD9pzB60NoHCnFakXJFcSH9TWkE1AzFooPKDioDEg7lBcaj5vRTkO5RwjxtFHeCHq0jx/
4LH1G11tM+jW7eO4H0CTCabmHkOJbs+pQudNWTTdtFAy9VatmabCZvxyhiN4SlF6zA0tqICJSKnociB71lj
VmYUEFAUvLRC8z8yie89E/vdpuuWgakNpyQk7ChrXIPyqwlpEWFNKM+whGWxRyjVFtomzJGOYNZ0/
OqHIFH1n3A07QjqA4L0oHR0DIqU81OnmhztjVQE2WPzfqGgROVAuUtW8CLp8XnH6ROOoU/85zYQ/
jQ0yh6mkwAGEnEDmJD3Y9Lp4asns5QLf+AEYhBDBiFY2TxYifiRhAU1kdR2XeLbFAuYa7JDl2BKOwro8CuG
uyKwaknX4UtqVVOFL/5rVqAGrHl/XaDs/
qjXNd9XfN1H+0UQm2AfQtttvSpeskci0Nna33b0Gb4KBm7ms325AnDqyNB0E5uGXtM6pTSEAT3o7wKOited
5g2FxlS966mCjCO0OxrvBEBYmSFYUdKWHXyCSmQsyGw5L7X66mrgenMSULxXy0pQdLRrx/
cnlDE46KyIBjO2DbO5V0xSmd+zl2zzKoJxwCs3dKg2cvBqwoNFwBkL7pknNUfoByjgtjX7VkpQFqfMwtL48
vmIDSnNGBM1sz5ZFXfBpYCl8s7U3YxkpkFbmd49EsAlOyoESuxVrZclILeeYWf8LXUsYR1MI821aQT5CxaU
yd4meebeQUnEyFpGwtpC8pQNkSNxqGDIQDBJv+cYhUxKt/
N+L3No8WpkUhkc6mpmxRO7enH5FvVUwSFvWTAXQUwRvEZ/
vHv8L8MsDVRlN05OtXN+dISJw6Q3QEIL882Txidyy5mqhXD9ZWNFt1WDACGLlL0AuGU/
WrPD1LIaDKwV5k8xNDTyUnPhK6oMO2W2lPq4QaBOIkvaIJSdWvHuiuJM2BZLASbzUqdqmj4bmcpGPDTRB5w
WmXIrXNoV+o9ZQvB02u6u4UMACPEJGh/BAlFV5s6sUMNoLJd7A0ju5tTo5CQq1ndJjUrV0dvTFCcMoi/
9v4vlFJ9tQuOpzKQUv4SPhoC9LY4A7y3Oc44QRr7wvXnzzG36U8cKVeYHkUqcPZDPHH3+tXdEextMFYXa7i
0h/lm/U7PW+AWCuoyaA3LV/srToPI9NjZzwe90xuNxQovYbEVbmilpv912eF+y2qNG/
NhujkuK4aVfjrSQMBj3gE9jPrjt/x/C+csQOq7VToAn87qBxzS1f/
XbbnqbqVvQsgZ2jM7EeKpIQiBtrCr5xAMMEMHb6xOldhkQbGvB1EYRDKaGu5kg9xhKd5zdbLp5BCrE7zQ66
c9xRst0d6NCnBrHsUl4HPAd4FjVDrAtqiiR3Cojoy59/
abw+tq3BLf102+hUnFlKSVVRXj5UxsG1KgGgIZx7AxpeJ9SVRRupO7bimfCs/
Vy4ezWSoYIxRmZbJVuMg7MirX8vYDWcCwrXOGVQjGhm+dkGwEdhnaIa77Otuu0VacIOyut33hLrm1kbUXdH
yYWEl66IMmFkH7ajtIwOVp+v2DNg3Xnt88vDqoWoUAYJxUAiZrMQjEDoPhXiZOej3EuUqC0SJYriHCvL639
hIBAx/kooC+ERN2vH2V/+/tv5rSUR2JB8P5LPHc0/
DCON+ksRAsqpEUsINDcdPj1PvFCxmfE8+VsC642M4SPYStGzpCxMUMWUym8A9HVqRDJplc8KXL//
qz6/11XehdnT4E1KaYJR+To8ssaF9x9M0HmHZLiwJwejPjgR1b68XbWw0zBe8klmoNR80u79dD4cqztQ1Jq
38vHylQBl3bpOodIRvPLtajAJFqtVdch7GYTcsX7XIb1VZfWtQaGMCQZpWK2rYGRbjhwgo3r/
4pY1Q86Me5D7EAEZEBYvn/
l4QfQhZ9FfgETGOeqxSvOQmNpTphFfostMO5iBGhnHgMNAxlXT4qTaGY4Rstc81Skc/
1gKPbDqx7G3iYjsdo2tLpExS2kB44ysmp6MYcgTxz9jKGE7SgpB5hp3HdLtenS77fn7JtcOadF1oaLOJoTt
OhkDFLMvLFTq1ZDU8s5t5vQCpfSa+nWA+xTaxJQgTR1ReQ6/
KrMgln6kvA2NGUTTkQh9jPRi5vnbZhJXMovaTCk2lpGg3rVZwKrBLXT2gtWWuTG0i9Vxlo080HLOQ8SiR5v
39wl7v6ij+3JMBaxXJVJzoCSlY3HyQvz4oYxUQ1yaDtM+LqqOw+9JgUvqGvHMjpudPuQNtfipYOPGLXdbKM
ofssMhs+429uhjxApCzLIZd7GhuTMo0/
HjvdX8RKyuqqXhazeQfgnum57w62UPcivqYOPE2av8CU0nbPoqHjyep9t1jz9P0ljLMR5WWRrky0w+spyFJ
KMzmKNz/TFUI+Hc2Ey+hsi5a7/
vE6Yyu3ZuxvKUaPcPUCmYLmcG05ORxiampFCiDIsc0F6G2YwK5Dzd9VhTBWEikv0ccEEjZtjHFPX70VmMIq
eUP5Xhu5XRt8UXiP3VJMdQXtIJJDiJOLxgvc929JRgHNRkNjVdgOUPLjRdmXLLDSlzk9I/
eJL5it0TEBpCgDCMXcyFVt6wd+fvtx/Pwz/Qfy51p4RnGLdS7beH/
aPxd5vRoZeYx8BOw3kPj5UmJoeXo9g9av8b62UVZENIHVj+MyEtphfZm5f5iC9aF8eysvUwfs6Heuvu881f
N42kyFyiftPJmd5Rxs1+AJO7LSEu3uGTkFlC7dYVv3cZiEyiY/
QfZ6zhP3rqTL9bzWXsTQSLEIqSXp8wnvYil8v694pSXYu1HBQ0wiKuzJn+bV6mfa3SowA7BkpPTGa2zjMdV
Zk+DEnTTQ405qtDwVrpFEZM6gghHABVmDGr0K1gSPSght26alDBd4UXaX6cpJD+iLtDuIeBOozargx6en8/
n/l6n+UmryHPletT1JHlJnTQWjjgMr0/
bRYr1DSBO+WDVoDRfOWWr7WY0zKd5uqtfNHpdrcpwGPHAnoqlrq5nmuWbYWTiY23WwzjDEE1mTmVL097Lac
trD6f0IskD62tg508z51sNKDchzGl1/M6FQzZSm3Tu9H1kCcOeGT0xOF/
nGu2ygr9i6cS8B8N8KHHgvl7GzrF2+myADCo+NGdgba2nLJbT26XLocWwUqUqY76IlQ6OZsi0qWEd+sjxzL
ccpW5YQAGA/qWwySBbLvd1n3s0/P57Jb/9s4FzwvdiDHfr2tF6/079/
RgwDFdoBKezF1G2OXdvaUsPK8RguRRwNPmqlQyZT7Hc1gbn0icQkbNaWoRIDLkaHIk/j/
p72c4CNNj656+XcVKUz9YXM2GKd69ozgVDpuCsBHAcgkSwAPeaKbRKY2DABM4OgsXp1Q+AIeyloeOnYCnQA
l7PfUKGVos0WRLRJis6nukOAUV3rvTeFEkyt57z7XFVWBJqutlXohufY0oHnrHLAXjtH9/
G5PEhHJLGYHj0ekVLFq8qks2hP5aq1dM5jDvizKZXxeWT8w5F55x6ZaLQfeGVFM2E9oahzU7CXEw29q4tXp
hSKhfh6hGpz8+xUtQo42dvXsjvfPG0Z98zNBc7/
uG7z+XzqCehWCDryS0Ysu9vwR8XKSjP8GUqvBMUZqa7k9SxCqKe3iYkaIK1LvU7YhrP+pmuIDoHksW4gzZG
g3yHImUFCbPGvtt
QeKGhQ/
YSTAbHohx7FJvv4WJoZ3G4amcaj51FzkmDYNmZhSnOa3jw3iymLitp9nJJjN5t+7yN70lIlpApHJYsWqHgj
Upe6pEkWefBLP/a0512/
ROLcX5xH5dQ5ja+iBli8VXd0Oa2bUMVkKpVVtWlEgnq4CJRCejbEM44nBTYdJx/c4OXhm3+
+a7g8nLRlLuD5lOfAuzUUcgQSS+kOlKhSyrYM9K9+8ZQBPDIz1JbeFEdcMspWqQW7YLFb4MAtON/
sg6E4tazRQUgwRlCPL3DUyS4DTSggvm7cWwoYVVnBPYM3MN7ed9PPYEYR2n3c1w2ziZIRPvri0tDFZ3Iyed
YgBsna0nzXvlCseybTW9C9DiYTPjIKGUqZzzSwOmVREAbCtGQPXb2aFKQYubKXPqSPyqhsTpAqNaSA5MOt0
qYYtcGAEDd0E5Kr4kJiIi65x3LIFg9gppMAXcgapZSAaHBNgID6pnGa7Z3J24dh/
yrgy9P5KvP+UsVon4dwAkDTlmu3Mdpx5snvHs66eK9y+ec+KkIlDRLFIstCWUh3v25vWWwFsXCvhjG7el4d
z0OjbYj8dQ/
kEd8JgU0wBAy9Z3xFcuAy5uQsFTIHszBqGyjpnl2cXp9bnPXX1UoXEY3SQbK2DqgpaS+m+XO4TneEManE+m
MfIupn+SFgpoZu74AcjdnjcRK3I6SR1O3/44oZcf+HdxtlEQulfKmCekprIlRP1KI8dNibMf8Y8sOybp611
qmdjeymHZ7BKk4jcc3jLri8Lzu/LtM9WfnR/
zXztvqpb9mPp70UoEO3mv2BZmHxGAMUcabtlRCmqyN7rf6BmeTYRWZQ0V+vlOVMYpgRZ6uAtY2AoF7t9kgi
1l3+5OgAHMQXHSdtCeCkoHcpSdelRVQLOCgpDs9cdcmyXxlFvhHp4nG8OKHSxqLX2/
SUaGjbvQzHm2aU9oy3pTH9zc9k0ls/0Y97e/ov/wKPh7KKHyPW7pBIMu4FwV08e4207tPW2DIp/
soEQRHGJe9joBjrbeTiP7LrL3rhVAi6wKmyna0ENYFVKI3wePNTbnEMeYig1w3szJPAbgZDPhMfPmxHyzaZ
xMHbDcBaNwXxiUTF0CY5p+565WqyulibSF5y1uZXxKBItXEGNlr63HeBd2dpDMn7O06oCCqgHfid2JqA7Wy
mxplLZ0IDVPf9xaX9SGNEeloyfNFTKPukGoxaW9qqdmWU9NhI+zuGvewGe2cI7FVoN61wtuxCVNi88E65If
XiYph0OfV2rCg4G6nZQop4Ey8HMTiUzYmvTpSH2cqKzLLs0lvZT/qfDARzaZZRyg5VpwhTQ6/
vGazsNDiKNW+pLwkwCxmB2sQUAVX2tZUmFqP7b1QnisrsK+Y4Ay92g7vjAHb3STkMrOi0QK0aK3J1pbOqQA
DgIQiD0hhBo5gkEZgRL4Ad3X1scbZWOgsSzAJgQoNaHnwDW+tyllVxw/
uUd1ghxwqLFcNKcPBESYE9qlNEDu2Cjhbm4g2sUdyGYQhCwpcAx0PUEvQyJqP4mszAwJibBIT7l+mUDTm2f
XszgnzUnhI8J9HW7R+9dYwyy47ynvLDlxhY6l9bW2/
IrtmEXExOMU4tC7WlyBfa5v+pe9KZO+TaMqULazYsomTjQwRsb9jWL82AGWpk6lhaN//jSC9oPE1hjG/
2z4ngCIvGGKLgpgqU9kfDAcbD8KcwpWdmB8xEfHXQiTnPFMn0K7zzfmk8xI4nTu1MjoNIWD72tkOoQe7FX2
ABAws7YLQPSw9BlCYai6MRvIEKQ33JWScYimO8DTHbWgl2N2TBBhcd4yFW0QZZHMr6wmDFwJen9PyUqCrmJ
MPD/Isla/
pGO9DNeThnuSkBFa2tj8RRGRml03+1C+j5UcjwucGt1UNGiqsaXspCm8vqTQY2styT7N4Qaox3Th45rUZSq
IrZkd5JrWKlbYBEKpEAEAUY3YKnHzno8NRBG1cCGRposwSwOHJAgxMlp2rU03T7yU93JW/
p7Gt02kqTiJZuSOnWORi5UKdZtwoxBuk2C9nhShkTm8XcNEDUVN/0qhygh6/
jK4DQWU+KwQUnJWBUP9Q2A05R3Ixr7OFg6u3UUt7+rk7xqOSo9vGjOw/Nm3wJMy6O+zQA+Ut/
kgey5dJD2mIs5ZCydhUVtWB8T8ruTzdLXu35aSr0dVN8A4SVmyYvsNLpmen3taz2HoupabV3J7i+UaAkNPM
SzcH/vYcBULxfe5iXkcPRw0ZW5s1YuPuOr6gO77QCkWOsBpeEQwqPDUuw0WVMTK4d3QMi+Zv99VzIo/
1dsqlKVZ9pjtLRgc2rxQimdNfPTXa8qy0r4rwNMUL9Er1DPa1+dUIS/
QpgkQl2mdtt5tEu4UsidoDVUaxuFi0DQkAKDbBQESRME22bpTPS2XX7wtrCKgdIh4IcTl3FabjBZoLXjDRG
jQARZNA0UB1QNlIbime+RZ7QLe77ZfbVZb4MHZafUx75qCWuFRIWWloOhH1KsGmFWLkkbavex0uFsdc0cSh
OBtQKzvyh8eVk1LqVShsdX99S62ANrLnG5WV59wfd7m2AA32fVuHR3R3ziu4mKKsMU9KC20hXgklm/
hbd+KxpF8zHDTeTz9t8+bnnntfMI4+9oLtv+VrkjrBsNWD0GNRqhx5MqvTOgfGRk6YGPUbCsnkjrJkp7GIj
xtfc3sj0plc9xMKDFr5jxAJmVQNErTSv5LzRnWQ96cOiGWhE29m2H79FhcB4OAbhUOsb9KHX3CD3h0vuT/
8BzRiN2eKArFaKges91TNc1WKLRM43o4lVBwMuOS3Qe/YIIXvpSqm7fSn5+CbGKDTECuKr/
U5kvQYXg4MhbZheoe955Ouhq10CUAlBcEA2N3FdO6ADwB1TJCOEDDT76xChumhmRWp3DA5sYy0NhXzk9uLa
8QL71w4TG0tmohpu844tAG3cyLVDELxMyFtHNlG1PnMXwzIyLw3M+KDaXWBdoPOPP7nTP9MErQWbR+hOaXA
jOzqKZKthSxVKho6beaYR3tJ2XH4A4To2HqYdPsSKK8u9I7pVlOEJuxLcP61IKQCoqADiMCfKuxB9KKUcGg
DrqKQYC2zdabF2LNdgs+75U6C1aRY0+VIwRYGrEwR4n/
TsGzgANTEBW5sgEaxct+vC5Ai2GpnNQr20LIxJ4VZoRuHmovb9l+FPlMFjxkWymR/IrlfdZYDQZit/
KV2M9N4+Vbnr/x1d/
XwuBpbr23HcFUYH90P36aozoNrUFb4nbycAzwlMy1KegrAgwji1vlI4K2249P7c4o0TYCdg/
FFzb8w8+hS3L6KLodqKcLQRTURySam9X/
tAkSPEGM7b6CzIAnRBlYgzz8J1C5WBgwJuBVhhF2pGOmxKR4UrjCKAJ3vW6CmiSSY1VACCTAWBfopWEkywx
DJiM21oc88LlAxjDAq+DPHFwniydMtrcmI0cFuySGvZlgAVheCibS+ydg1IumaauMBhXY8sH5fg5eSpPhR0
QclH7c/
M63DtSCcStMXXTkO4WYDtCIcdwqpCRNicJEhTrRWfy5u1La8gc+vKxkMNrWnRZ1o2tS46q6HljSyCw7teON
76M1q54L2KCaUj1AGoIMa0BzF5SwRK2RGIUil1PF9iO6MMRGRdkcGAihwGIiIRWFRm7FNNGwNK6+eA6HEIE
ZQvvWvyErI/
SQu2FQePQKeDjrTw6hpKheGQYzbkSuHqRbLAr34zrQJ5eypcM85mJVZ5oqgMa2oH8dy1w93Tj6iI0gT39y+
XwjDcIuba1SGbV0McNzrV1sFwZfVIy5lOulDF1HO3to/
CWS43HOK14iCMiN5AmRZiuD+wqKIUpYXCgDSmZdOqYSdyVAPxJ1JMbLrFbhBdn+IxjM0zU7OXKJFWQRJAuD
QWAFtcopYoFUa66p3RYT4haP7Osxeec9rUTzQ7WAFQHG0bpBiGmOSuyUvV2J5HfnttxyS5ohHI2H54qnvVv
A86egkhoHrr8UpPD3oHcJ6hbhTzdbBxdFgcEKZwqXYP95qmnNJVfPAijDLex/ZoiS86jEXdz160/
xDVK+iMX0WswhOBKYSGAaJ0Lc1Z3MVtcVtNy3hjA4gcIzSAX/mI6DL/z1d+U/
OqgOYyloceoCeR6G0KBZFwXs5jKWTGeFejIHvcognOHGhYwgiJXaTf9T6Ql7THeAhs2qqC1cFjpxyEPvTmo
TofVSX24Xa4aUwO8bvSnn7q+4dZ/
hhg5oBVIZRqP1FGgMoLgRXvUrC72iLCE50IrZZS9SAu10wO28FinwqIe7N9ld4I+wN/
eoxM1tfCI0PcvdJ0acPwaMgxCxRhnXJXSguNc+CIHeM24U32KNAZrupUoKbGnlh1Nr8FAIS+KJCM/
XRUKwWAhFdefUf1Wow4CrBytZ+qlcyWaUbAbSm2MguUyfbyVfS9h47YgjcfS2+b1cDlvbEddo/
GCfGYoY1pTGQsNPe+vG3HHz9OqQ6LisACFFGeNnDkTga8NNkNaeZxtL1GaYVIhpKJQYMbExutmy7bTQVV3r
aH2eeULWgY27VsFXAwVzp4HJh0HdxqR5wZzTKzwFcRiKltYZU0EqzYe4bUF7FHwA6YqwJdx83FNNb2hNbp7
XQcWq6pzBimVLWG8U2ZRTYCQ0lvP+6fM7V7EdRp3XOYvnqjnJCIE9NeIgniargPSK/
6lTwGof3b6g4s6W4OMIpCDW9kPTvf1FSyxqSvaxnQcvm7y/
BH8pnaaPUqBrFo3Qi3YMtoXda7j+FmeJsbJS3aexkjZNixfawJzCqiXZlc6mOZ4x/
nPx8ZPbJ7MZcqohFurDQcwqeH8yM282UkU1GAnYqevrW42hBTjMuJ8nRIyUJBGLb4HXDSNGx3ZwGIvqkiiC
vFcyUtN7yaPmHrvTXGmCWREKAAxRTAofQ4KGG3Pl7ylWCGj1WALzxeJTUsQQEH2E1L78LUT2XqtA/+hOa/
xiwHDepIVyYqz1Fi6paxcwSHudg+eKDS2gc+le+/eCprnf8fWPstXToRoGaxVB5xvjIe+O1xS/
fJ2O3av+F9S+Ozl7KeNOw4LlAWxfg6kvnKB/
gZN3s2qOvBVYiySwVgID1XV1ik8yZhOxSDCgCpaUW3dVgCGJmPaUI/
XyxQpmFcL9AKHjBa5L+Vw3Puqgxb3aSaKMDhEIxEWtPGGsQeJUCPpCjXfnUqdfi3/
P7kcjI28+YlEabNZR8fvnPLrr0T9xXpxaFmlcQkFDaYiAbAbT2wcB4yKC0wVjlLQX6zI/
V09q8z+P6bz8Ua0rWgCUF19ayxsrii692CR/
+rBOn7GvdNEnx1ElA0hk0kXlwsKOxq+d+GnGcNotVw8dvpFebZyupjOKZYJI8q7Zm1F+mIjhHY0RobVkAoV
psuo9uA1L0Ac2CYt3XWtEx19/
O8FHyCjuGaak63NkiqnVpSyaBCleh6rKKhIEDY7lFhGkKjvewhLpApy+OZIi0TxVZNDZVWNsr3nrvXsyZ5Y
jdePGWCqD3XX3m+1HfQWLoTxUraXru/
ee78+EZPibvixUyts8pM0dgxYRpfyg1v5VETA11fOOV09INrtQv3IWpVCtKxw5GRhA/K/6438GF/
6z27eG7HllbLnfd/
jHlMV+YofvsSQ1QX6TErdkroiTUK7jBch2ga7dq2BnEbYzSSAlSUh2JgFCTNmeaBuht1zHlC5eNZRS+UFgb
WG1fpXCq8AiDqPVqi+
+HzrJYoNj3LQAQtzNmaZv6mRwlCeyrhKwmaEQh4xfc2yHsOOvbf9Ayf74imN5K0wxwJTnHhcvaYBBoqh/
3czWHJBjNdxKe5OGfTEcKNwh7kJe5qN9s8YI/
zOS5kG+R3Bjf5/2xic4EH7VWf4DAlAtjDS2AQeXAT+OBezcqc92wf25+fkV1T7ku0zBfWLaZh8ohfZvH+zO
sybIUAAIlhEpJGTAWzzgFVarIIR9FMuTUUFuxb2NCQVoundcBAqmPoeU5gZfUJrg8jBHkCComoZQSPyEAT3
jLBqrfycu8E6x94a5JoiJzpy3hsp9kQ7Zl18kMwMRuCXcbFRnl+wmnf5/C4XFenX/
LMZNH1Y0B32CHQ1SjoxVzxMPnlBdBu+XC3pJanMHIwLui+ElJNWWbP7zwGqGRi8ZAV+wC9qCBHf833CmbJt
93mh5UxUiEWVzlzHE4ClU/
7Tn3LN96B96dybmpWvjELQWWBs9Hj5hIl6dWb9FSyD1yQiFEAjsqagKSyxelVi8SRBagoCcobhAMLhX3ZdP
k0LLB3h+RhKn31JJyNXXXkhlCbOm6JAyCWRHcFIrLwCVbfmbeyye7lV5DT4mimLvoXbR4wX+FVaT+irKpHk
vaW+TB92fn/y71fXT0pk/TI/
dASOxnr7UCdgIDtqtbVFofu46ZPftPzuRv3vjXb3aQ0UokgtKIeWXyofs5Ey9SfFkiX7IeQWKze+uee3/
EzSyn1lqKVqAdqm6u1o89aVfjE9xfJq3Ou77Mf9Yz/
8PNMLPLjhVYDscD68bDnTPQWIa+eshMBH5h3bUQAGo7UcA26FRtoh7rDGXv29aBJTYAKgoFb2KjNXptOwzw
zQUTyRh21KVd3J/9Dm3IIqGGmOVtZwJK33UCK8kbgrTjh9okizkHhxu7x5wjBxhaFbf/
sPeXx4euZUC54T+7l9QfacxQX7pbz/LrLuR5MnszITNxjwfowTaPQ9jct7N3bDeif9/
ynqBseJp6O+OxAnxzCIOrZswRIFDvRGNQCCEZQRTZKGfKT95v7Ln45AV3BKRnJW0pKQjiBhDu1TeCg/
8i1ZDrb4yl93cn89M9ftBu0+NE9Wh0zcR175Vzavb1/
IZ9D3G5GAxtlI0pkEXq3kOBjpQ25zQwKa1+rFiEIpEpdJyPN07CFSqpLq/hH8O/+gm4iW/
UdwFpglrjeT9f729LpE/5qgwKs02wE2o31YEf95UUyDthH6qFgnwMd0JNrdYGL8G2ja9b34d0zmv4En7/
rv2eRofxwRoYnQuuOLW2jwR6idyYrpw786P4eT+b9eMBwGg5Hph/c+
+ww5X+giCBOum10ZODhrdhcBx4IzCBIaD/z5q9HznWzprC1QvmNZQfx1ANr9pvHc38J5iLO7Jv5NP/80x/
WeLz5sbUa4VgteldEWNMnssBVyN8uy1fhMkppeIc2Rg4q0EHdggSNqSNmyS2sD+sJfY3AImIj/rv/
ZweL9ijqZQoLmo3RxUDGOZIl2GOO4BAPukWBxlnr1OGugpkTmGHk+BewiyRUUqLBN8LPeFVDlfaWST2zXKN
/sEAux7N/b3q3MxZ6/
gJvlqKlhnPQfdeOtIN2QZGi1McH+Xa79GGlbk33Azvd41cHgS1BvF3aXLkSF9RUO2vejBz2gdkKOC43b/
36RWPQEF9pl3Ea7ANVOL6VtBw7SPapIN8Eb9JFxYhYS9qB6+HDWRyKdZ8dw9Um5vb5zLocfaU1MDkTAgkAo
KQDAKUQDluS6mvc6skRxwkOv0JzTeP2OV58TIcDwKkN+6yJXEQMRIEFgHh/
iAjgGmexmNAEABEy9XMl6vG5WlpYh9YYzCsNfadbmtvPIAO+DDn5p245v9wpDvDynDM7rvk5p0QfbKMv2uk
/3/K5TfIU+/kSu6f5eZVAUyoTi4OXIqc44rvAQeA1Xlhd07aWRI94APDkXy57/
bjTowst3RPrzk2R5f2DK3TW7jtQlzhf0rvBrKWDY2jDrZH6BW2tqTJjaxQXcszWDBXJmAzn4VQ2hSYhpobS
igAJKd1PgETHklaANQKCEw3S7GnZZTtcUwlGVuP7N/
SmwaUdOTh0C4AsA4W1l03akCMiuqKdq0kWwm21GRywxuhGO88/TC2udKqIh1IuSeWJO1DP/
TJ37o8F72+srY3WhpUgtA44SJ09LY/MbNuj7XfgHKtRrwKNowqoiEoR8/
M+WfPOsYRtrqxO9YJo5Vrp4i15NjCllzzecrLnzfUt/
y3FVhAztt25496349Vtl2pUITVmCMb4FqgHT9Ue/
lvNY+stesMP5Tkt4Ady0A7Jp11LC5y4LQu0kDqJJaBNE8b9TX3nRNdQfxKw3AsGYdG07DtramWJCq39dN9t
0/Ok57mqXqmqogmvEqErTQNSHnmjvR+oz+wv/svhY/
hiPjutpHbbenclxD1HlAsdRZWgRhLX6tyuW77edpq3nNA/+Qb53tTd+tzbJcpTurkE36Q75SnJx/
VPBnefHDOlvMRFxD5dsFlx+ffOG2vs0XuOH/f5kFUVPld+NmO/
9+fDYGddyr54e5GuAs9XmK8883DWsBanIK5mFFsxZD7QPvJB6IlVrIZvN2GNBeMvBhsSH6QWgo6ADZAYqKC
IKIZeWA0mtNSKCM9mAqCnoACSHSWO1tQgA49ek3kDZoZ/
mztElNnh7iLNCmY2qOSbF9ymQKhc1VB52haIRrYN497v1GWO+Jzp4Ho9kXVToj81LfzczPBL+eYNUY4eOZS
cVkSSOOIQOLgDLgBRnvlY2EinamnG2hUHBWNjqCyaUlzId4Ow3ly8txLuv67Ye38D0asj+zVeZA9qrSJvul
PLb5Z8CQB2YEMdbDKdAg0AqiwUHgxF9kqRGUC8GOZ3ejIZbd+TaUex3cjGnWEQzZLT6uAOKCfGQysBdua15
/NWdld9ojTz56SbS8OuwXo1cRUDklC/
CcdBrOjojnMX1E4M4WFXQ8J+rvpGsLa0jbCSnWBdfWCf0rBOcZ3m5u7GDwYKDNrEePA+fi96sIRVLUJDnUJ
Je2WKGDXxGHk8G6H6kB1yEkglKLPG6ZP7jPwARoy9RjDu8oh0PlR3Gv3imnMnPdvOBuRElJ5xasnzDRFmgJ
/pdVa0B4TNAl+1TttXubvDntrnkUoQA5BJUhpMhbfsGcteEKktHmpj+De/
OFAuTxk6UZlbKu3zsa9Xvq8tfilsQ0KodIWIQHTSr1jel+UOU5CGWmw5FDJnbFlP1+fEAnjXiFAgWsRqHKM
k3KwwlGdirBsnXHM99NcPX5uEM3MG0YbHCtT7O1Tq5C+XfAEcAjuPUNPz5x2KVgdQpkT8bBiWmz6hbxMGLo
FvP7hvNUxHys0UIheMQwlVVsJVh2Re0f3LMdoz6k09+3+IPL7O26K5ch+8U5SRVm3iW15prOTYeKWOgOvUs
NiXU5vsSOXyciW1zI7CBWAUkIGue3zYw/
fuhAzFgZGFzKPrad8wxJRrUBBtlsmvIfxiYxYmotNyVhD8tXhBvkCqqSkWAhAyEAa0xUwktZD7iRiZ1wNkF
CCAIql+YTnTgWvZHbA4MV/
MtcioubWccREs7gCpMcaiFVKJPhinEv+7bIhjMfyCxtVEIvPCig3wThYzRVFt4j9T+ZY5+bEaXERCJJpgMM
NdzC8UCwTML7zEAvFSQyEDCSyjAFbPLMpVcsacbzUqu01EiCr5JVlz3/
ICUai0KfsktxxZII+dtsTTSCqY0GFDZHGTnrUukwpW2NhSuFnYu2E6Xg3768lfju1k1bi/
dt1yTer+kbkpFAGFhKvTTn07sCGoJa28Hpje5bqBctKcp3Wa+gILtlfI3mYCwkYJzW/
vLkf28GYyWtal7exiSegVu0WRYQUsP7oHamFJuzo9eUSUzCekPMbwEaTu1FfaSqsqkzLhlEwHL/
FkQiINiKmBmvPbc1TNV7os0YA3jc3rMW48h4YYwa4RzriBrn5yIzaeMsGozIYVW7qspLBnGOyTHK6tnng/
mJM4TibD+22GuCkUtw25FkSL67oWUJNaSMptUTfAYPq8mSQSsmjEKkeaYwPQZIOYapoFvgmC6hlZvjmDao0
yB2I8jcpRKB40lRszQjSuJpDQufPGegNkEWmyJmzcy6e7BUi1FAZmjreR0OnlWhsEAEN9UlqLCf0XRMYbdk
jenvATUIJ3bmgmZ0wOIAKxyvm+2eO1JHw555GKamtZNELMZi/
peHe6kV+4TsOl6zZtfk0DO5UIQA5+7samZwNAFFZsFBLarFAnr9myAD3nG0+ggXDnxb35x2jziCToYGZN20
R7Tdcm6ab4MMNYtgCiyQhPJi3r6nFOs
rGusKrlRqFqcLzKjXgTnkTJN4QGFSH9UfPGGaqQIHWhsgZq5ySmOartgAFHYcP6yfc1n7Zg2Au/
C558mW6Hm4tME/bh0ejkycacTZ/
4UC8H5WIWRDGI7XrhGqslSis9pGk3LdC3NwQMBIxtK0EjYr+8ecgMsUwPjWqhXj1GQ29wfXOhljCp5dmwXN
U4Am1ERFIQoJ2GkohL0gIwhbI22QwhZQCuOqUYkYiIlkbtgyXqrJCVq5myAeaJZxARGThAjZ0kQCKO43/
qPRIlDEEkOam6w3JHpfPXVo+u27T5WzywFyz2zFXCiDPuUD904xj7PhEjUQeAaDCqLCyksU2SuPYFtsAxVN
ECkaHOFu7IaLIQCtbQ0O1r62Wt5BJxKJIIliuy/
hxe4hRTSwU3yvMERy8iM83EgBgGECk+IfXYhb9hrN7vFrAMHregDuIiOmJktR6bKZ5xnCm6aLXOIc/
yOCTG0PdLXKlkoy3MOzA9BZj+bmqU8V03c+ymmE1wDWPdbJ3jjfQKgT6roZZycr1F5xxgzcrnr3JxiLTMtV
RJb9iGRa8Y/
CRgbhCARCxWs1RhC1HCsZn0Wk26NyIyW7wA9JVKZiTy2nvFBTQfkpyF6wY2Uz3jColchYBcMkc2NcM4lG/
Jc+qNzqgkRmkDEZFp4g5IKtXGSORlb4paOYEHyeT9gIhEK4RNxQs3oLVfU89MEFGngJpgZlzk4hOiXoxVTV
ADgIYCpdMY7VW+k4ex4YRalpKO388GuwQSdQ0uMRVchiRIYRS5Y7P9OCgJJeOxDq5vwiE+fKIo1DWxSGQkp
iDDIFAmirWG4X7qCBGlvsEjYmNAuizI12I9sYdFTKxouaWth80nq1bRMrPw12cPp6zXTtqTZix7TpGLKq5I
U5ST75qF7GpfPM+SniDcBjECWwSxXaRRQ8QDoiRnSW0vA50lZIvAn3qn74eFzQ6PkD174mwDi15znMHLwaz
Tm3hr8HkQtp4BkutTg4QTEWmFyGcrFiBdNOmdzSUbM3s8i4hMHb+w7aXNvi2a9G5gE7mQ/Cs8U/
FJX5sYTbir5IwLt1HGTQ/
fEE1WeXLCDstGYCIR2WSFXexbeWlgFnq4Ak1zODRjD6AGQTM7OI3mAMA5uy8tNkAC7y77hmcAwK0BMCI1t8
1FXbyLCz2f04EtaMEKtadEvHJcweaJ+Lijqrcs0cGUqim7RFCugRiGw9nbATMEwSeo2kwSiDsW22h1/
d4oT9+2GVmpKnqR++z8yd4neoZtD3ItMiCxOzqCAiJRTotNwlKP/
oPW3FC9jK2YbVcwrGJc80lzSzdhQNpB/
H7f9+KpEtUZTN+sKqYwUWjs94OX6CyoMl8pS5kMWYgMYDGqkbOMPSIkpAfaAkRkDnghSMXaxj6pY0/4rl8Z
MVkhItMQ37Pag7+SOs4A3wQJ8s0C32H5vqLQN1s8nYjIeEca1Nk7VJJji3CiDkvYcuWsM2hMTHY9JDI5PfB
XU760thqEJvHgMvQSBoDQbACqSYDiNHPKDWWpHbmoUeSGMiIAAG5ZIC3KUvmQC9Zk0aT4rtiZeGMXc8Kh3o
ZpzC4ftfWTWimldHOz3ao+W9AVAngBUAm3f50RPtfriQFvZVy8F12+pnXpLS4vrPMfvHL4pA/cn///
gbA6j2nIUMXlxJ0s/
uULaPGkpyXsGmNwYiFBU1mk1VbHcQS4mSHn3GYNzZmhH448QXtpeEZj4OKbgcuZLxJfqhFvgEzNRyk1sP6h
krPy/
wzVqGVlaEiuF8nPU1NlB0wcano1mXsCqjHsgCysPWIpbBSBiGQzgKpMnf2IiTXGgIdrRAQhhAECiAB9WT5j
zYGpym9ZFA/
CnlJeACWc5w9cfKPAYLV5U1EX+QwUGXLhCZLeJNymQ40Q1PIJt1sr+hdIB1l1ieNrudHvZK5Bo9gcJbU0g2
AsPEtNuRxEBFA0lBLC5YYpHIvHBGfJDOF3K76yC5KkNujF8Yezy7rL0DFXGPqbAmy3uiNlmCC2Foj5E35of
y53uNHKMgJkmoVMhsrMQPREe1NF0ved9qh38jsLRshaV1RjmJzo9iBnP4f/
RG65rpofcvACgku9iZShlEKrA2CoBOJzqDXJG2h87gO67bGmtZhilYhsDElyHJrIKRLBttYHipwqMsNjMIf
+WUL8nPWr6ADRBUgGUtFU5xsh4lMqA4rEdj3fX5WNiCBX0O0L4oSGYgQVCEQxkieRgUSxFoqa62H7q9QwP0
DIZPuF6jXL316q0eCn4JOpa/novAHmgdp/SFZ+QfKXVQAVFhgVjW0icvYHVxzXVvvjmveJ9x/
6G30IRmQROmsAVRKoaptDEfl6uKx2i6IQUag4xyy2JS6wa0WeEdBgFzoSgYt1qAql7KF6f8Vr1toDTFe2BN
hKRGQdvTI4G6+DAoYbd1D84TVpb2U0o4u08kQJeC1yjfQjpX0cMmgDmBfasWI7rZ+9etE2/
qu17mQvSriTxbujBtYmrrJVnKMZhAeM3MM5sywtACoNHApAhbl1NEZEfFK0SH0iMqbdE5YlC4YQmRt6SM69
koR+qEFt/lgnIgvCXbGsiuacc44vInWcGoSEFqMV/wfOBDY2/dAYjyWT+CdJITxKODHZjvz/
0K5+04c80zxqnNize6awnzd1par6rO97ci+GZ3dwrPeyeOPkD/cQKQqT2asgW2yvIlKiYVHZsEE/
0DDC7rZHyco40M+M8eFGTiMNbIagZegHQHkE2EkMvZ4UPG5E7RVo6NIaw2H6k8wTaoYkZNafXHvjF/
lKdvVlgOm70GeSt5afvCYhTdTX8YP7aubTiwfFNG4sW68Q6US6mbxgoKmBWoGe9hZ29cOZp5xrrtRXik3Th
QO2phq3EZkPhhxXs8DtRGT8/22oWFs3i0Q2jBbL2pgmENaMjVSROalXY4uANKR+B4UK5dqbgc0JEDAaFl8i
9fkg/
wnpfx7sH02gr5JO6CYY5MJu0IzQYlsSCAGJpClBKGBSFHKGEylweXoopJzWIz2G2+oGtTyxJsRXdNCZgEM7
dGEB/
AjEx8mYt6JRAcTeeMxZ9vu+90gVgGZS9yqy9vU0cq9cDKH0bSJ2Qk+C0TG9pJpVG7XHQxllv88PAWxz0ENi
P1Ux8SJHYkpZWY61Ne4W2wKkRla4CckCghqkfc+iMWAi2NEe5zQdapIWfc26aNaUZKPoeH5IcksRZUhHFm5
rvpgqbWi8SwpL9+SYm4f4g+n4R6sPPSyrGQ4twbmJtFQfw98gbfqYn3hZY6DFkHTNlLXeYqdeWgf2Kymcdg
HfJjzEhOuwwoMcCjoFcAD5zYSTHTw30dLBKqpjqY8Hp5UCa9L2dlsPC2OSkpoqqfWd3Kk7HZe9YbCvj7n2p
hUAMHAU002Nvk/OJPp9hlh154gIa+0R81kJJt6/7ucs/
XiHbaO9tYr86CxaWh83bx6GmNFpZbkhwDjFs9vU6zz0bsDOMKlk6aAXeFEiANFRcYCREJaByeLruZnDVGlT
1GJ2eKYEol5JsuTrFiogholGyJzwDBw6sxP/
tqZuDhAMh0cSPuLyQbAvNpj2SfQl4ciEsCpnOENFU7W61kk9jvlUUNKdsm7NhlZzbDmZfq6og96jWemR24z
+3yP1cLyNZ6qSmlCXsOEnTFctJKKjAKkRJRIzuBM+OEGh52JPmlyvvl5vpnbsn2KiGz3VyE9ugZ+8NImkuz
J0x0e4XW1NCA4FMAcA0ATNG9pU4Cw5aFEzWTQPIlKTeH+CQzabNRSXEyRwQzvS15MYhen0uO/7xs/M/
XiwCBdsYircmCtJG/dPLIy6Hu8CzVpZJ8PoxQGAqpEBqi0IqAk6jE5GMF1qIYlWcHQr/
Qt5iKaAhRBJo9MzUb7spFNtUj7KM/7Vui/+rpkimy0qURZILyonSnInn0d0DMpLNx/
QNABR2uLpxn5sR04xlnjNkY2iIa1bj1Mb4gNeiCTqMu1vrKQr5oKBnA5OPs24w35P2OitzmLxlWF3cFrprm
72QJJv7Xa7HUMN4zt8aP5s/Y0spqdn2oteVlVCnJCIHy9DbxbKP7jvel/
Y9u3id42Z8bJe8UFzUmSuRaWisITo9bRF+BbzlA4TLLYgJRj8Fgncms2VeHSzL722mU1ygTctSRtUot8elN
auTbpBaJIFJvNOpMACgnXLtZSiPGkkMe6/
aXYKEThI6lTa61AH4GVlBpR6ZXHT1jbDEpvOngmVlpiS8Bd38QSkJYMhTvLPHX1Tk6YPHJk5xKwB+b5KGQP
DiPcSIqMvFHRuXSIZRlDTyipfW9xJhlX8cUBEhuU2cOwDkUj0GYCmh6+rLOfa4ivmipdpmit+YaP6mub9iO
T+MBgFxlDWW+r2CCUYgiro6lBQkirwyl94ikoUJxnWhc+MMUu3A06TsEKdokc7SOHZsKfbZLup55PbU8a22
zRDWBhz0DJvMjtvG0IkrD2DsZxou9Vye4qUajC2IEbHh2laKtEnayVucVX86odVu5aMVLZW0uXG6ZzIjPCJ
SBV8p64OgAdQo0wsM6YrIYX0ivNlANASdkaorCbve3ZkDgeQYmMtCDe1ef7/OQ/
JTvHjp0/+0iBTobdQXLDtMovastspJw+kRhg4WTfDRCIyd8xshkJ7KbTpedPnFS58XgpZDBqrWoHjUDzA0K
Y9U6GnRGRWUDUkaTchL8y1ahuzxnOJyNTMVdYXZWFh5MdEut9xvjl4nL9YJKKhgEKmKsoOo9njWURkHqBNI
ghI55xG4xG/eV7shAXRP5zvPMIayrxn03o/3Yd+/
ijgXdSsChpMS6sIpCyJ7H6LApUvwSqWPXMCYEBfYTaUSQxO0z0b5/
FCmUhIsTOLV5HlECdROcScA8EBEI7KbehB03mUNNFqU7raW2CZDts6ZsGcjYkFERnIgYuJ/
0EdWY1M0tV2q4w0ksoADAp0Fzo+8vQpMZaixtQAzfXNljLbC8q/D4x/
9QJ9hc7WFrfbjApMK1ZIQzR7N1HpLrbhUwOeIDxn80bTtAADR6uVyPTwS9Uq8QbIyqLpY10iVTR0O9N8CEa
qBVsuQw+tYt+1Ewv34dZCxQhgWIKD+7vicd2YZnPjPKtEZGYoysv/sRq8znAkxyv16xd8N0/yk/
QI5EgpXLJJrCGPUGZVaASPDkK4pBJ86Gn/
eGHyCheeb56HGWfDDtrAlGfnIxmQxga6XyBQVUVRVVGPHjG75mXtMCOZrLUyGkoo4ln4OqO5oCsgqR+Cj88
xJNCv/
PXA92WIit7TfKlgNWk3Zy5VF6XM8AboQGwNSdBiE6ROQwKwBNcMmxj67yUmhODcaLdRmzWHNWk4g7jhTjg9
0yofmHVN5Ixmf39QoiExBgIbVNr0B8Y2qJes2c9TAmou+hBF4xSnHsERI5ILxqiEkG91hgueBGyel/q/
aQ33toQsc1Ksekm1OOUg+i2iRfMkZoCG1HFpJFjbYae3FFgMJDDl8Z42oactCsldIm6xBnmi9djJAhiBJh1
Ex6VT8DbWmTG4kQXnE19m3GemcmRmcPNEbZNIqgGI4KUHxhZGqmCsS2DjY+DJ/
uFso62MbmbRx3hxuGgk1ADB6An8TTXwRlWnqN9cW0xgY2OKMGUXDSMxVxtBz+h5zezDnV1hreXYdLMseU3Q
mb67Cp3/
rlgvuxW3qDJ20mWDZRW24CwaI4uCTzQksz1fFwOAjakOAEk6rA9AjMmOlCHxqwTiKE19uTpWT7LX2SuXgZt
a6y36aCoUC+CakZhuvrQ7oD/5CND3IqVduqn8zvGklm7VTL2aFm49ICaBZBhskGEtCVxd1/GsZ2G/
d30rnuGWFoVwxiikvl/gDGqvUiziufB7HcmLc5qAAEUBQ1XR6B49WQLPzqKlmJ6Ly1Jq2Dz/
298p8ydK04yQaI3cG6+abpvF5zHi49COsD59FJEkq+lxWotS+1hotwvtGdzaSLOKFApgkmJdxYaMbz7S+vk
SXH/8AXOK0UxIL3+TVhaAJWvHdsfegNsXGm844Q/aydr/
IfwKN8ty1X2fNAJclZRiNo21OcPzcHBFdGFtAhi0JR5QURAMBHgQq3NURbsy7VI9lCmde3rfHehDhXe1qTp
RJlE8DULoMaPUeHpZ/D9XQ02el2zumZ8p+C6WIRwAx8TRdA7QoOD2lrmCj/
TXu3b95IIR26N1tkqrqx2soZWc6MpiSzYwyN4KgA3ZyBE1tt5h59xD563EowJ7Bnt2/
KdHvUhShOnvJv3mYnvK7nF6UeHBj7Y68CqVG3pfAo/
HBuOVMRgxKLUIoKoej4BaGD3TBGyRyzs2QkmW2opejAUVnasPMiQ6sCckJf61fBwcbCYNe+5eHHlz0QULRI
uDHBsUzGQUJVESADO602ym32l7pU7MkB6XjD43v/
uJ0QrYmvaEq8EpcaGyPbo0wrPxXAaxBvV5Clthsq+VfpWuqyCTlI+hoeQMHwNbZaQhsAMQVMVoJMpV8iUvN
jkv9SjK7Ekv89F9+WWn/
WTbnbOHvYfS9NZyeiUEKDSbXOF3F3yvuOxN0NWSdezHMWSq6BSNC9yoz3wfEkOBQkUCmIAhXUrBVGTFhJ2i
s/iht3wY0VvUBp5L72hi38/
a97No6+tojWink9UJKKe1ztmIiMtIlXST7rI8ZL5RzQ+Jwwey41VhtCY3tCm1rnLX8pQ8ZIpn+Ji7qAGoQL
0v+04XjtnZFp7k2x28MeZgONoWHue7WYVLjYEyQlCABriA9/Jm9+CO+winjOqiv2lL2nXHVs3/
e05d4n3Odufo1QcW/WIrRFHIeZQE4PD3MPNkr2bHT6b6ZDMYxxmdZkOJ4xIJI1h9qu/
zXoWHKIjQhLBolUGIVnCCLT1FWfRZlIYximcs8aAd6O35z8zr6Xw5RIsRuZYhOTBcL4tko09KrR0VoW6mFp
eyWDxGGk/
X9kqBk4ByQK9lawmaaCxGasYr6pFFBjIDu2kzcnXByDcxhepOEYPxjyVtI3nHaFuIMJAVhChixlLWnG0rHM
PMJnIcR4iSjuKMXmoqdmDCYPUsOdPLJTuv3jShW+la37aWsGtzfHx2rJy5f5e0Hfan4o4VQKTrGbm6en4qZ
PYlRtOPUDAJkCAsrJRqq+6Q9dx+3sU3fdjEpac7QUjzwy/
wKU8UWmwzEM0QDGvxwqzCbvpFrY7MAyr4OHgGJYFiRfvJj8qYN/
kQ8JKIQK4xQeCK2CQSlXnrQSSEy3q0IihtknbJ+Qf1rdyTr3QA7Cusr+Gq+ImUuE7LL0Khig0cHH5W23bsK
RoAtY0OixGCMd+lK23bfxjWOGWGx5nJpY+vnufOzUedUDzGbGzfrPqasvURmcuXkZMFjnXXErWEbB7lDvZn
CGMZ/ake1oy2EAOygBnJsoRxvbHIqX5SY/TN3i/
N4bIDXHn7is2CqVrQut5LB0mAauhga6vVsJ7H1dxw+6M+EZ3IypVSaaw7QHUE2HBS4cRr94eqAfDDqDYosP
4kleQtjSU7eDcfp5zHXpC7btEOmrF+rQTPh2zIggWVsxq1iAjo1HipAKkAoMJO8A3bdJcuNWmxE7vSu213b
tvs54wi5l3L9KefuyWM5kcceNrW9vJxmKWv34u5OzyNKbmkMDWzRkGCV9pEcZT5pEOacUaK9ZfKDWg+QJVL
pIOJqcCb5d1lzN+rsFKM1UPfuOwIurJcYkb79SiXx+tUV2XASHUhXQAlZJjUBlsrxoexCk6/
u+X3QK9HWs83Bils5gNO4Hzh5Kxggq3pcoCcEp1gT0NRnICAF3JwE1eiqv1gwksBpxweAzt95wY1RpKQlIt
+VmNxcPVDx1ySdi8J3vdh259iwsGiCWb5wGwRJ4KMlnimd+zQa9/pNJpEP5G/3PQUkzCZa/
OE2sQ4jy5kv1hbP2gpRsUuJTXMVsR1jVqHIecRzUFmc9t52pnklUiv1vd64/
tb2oPhVwraIky8O4LxLKPDyI248/Zq5kMYJ6KM64DoK0CWUqjqKlQVQdMCCFht/
Hrs4yQKgDqAuN4IMTgmiaAms+Elg4ysmxDn10lNK4f2JOwGuQWrW2AVKooCxtGgi+/
orUGqJAwXgs6WsAJu5GED56L5YvSiswrmoWfSVhBYs3ubfsXEcRt5KYy2812EUAWbH5bTZiOX3/
a3dVs77O9vu8b5ypzcsLaWaKepdPXG7VDUkzIuM3qMLpqfpPC/
rjWr7zTSNOwEWFFaBR0yiopV7IpHEWo6GIv7rKKyfZ9eNvbNfOGibewI9dLZO75SkAJ3Hgp2Mh+TvhzThCl
U6YPyJBaa2bU0o21baBPOhvWwhGzzNNTerVdMyYm6glfDwPGERLUTRCVa0dGbHA7WlBKnI0TQwAvDu0nlXb
lURpKuViDWn4lTBTvysM/pJ1ptxuNqXkCL/
UEadKoEWB8JX2EqtYSFAUEomJvuKrnLYzKgT07bsFyDhfXVmEM1+l7PhRMQhZIQAwAu+ayH+dI9Jf9zBvYd
ZkW3NWAbsYAYzjp/TIZStnA7D/
3jTQtiSUbdEJL5ssXEBS+OtvAIn0QNpSOK+5MiCsigiFZ8xO0NR1KXK4EeMLJOBZ+8hhoxxi0m0repZ/
QgMNAbRCTJKi1QkQvJkHtgFBVNvAKYOjs0MZVMJMBSXGXvhdUGYRqdlyuDZEgIYuyp004JB2+ZDE0VzCpg9
+WpuejyQTUGL9ucWWUiKhVCRYk5WKCN7My9vICM2pWmc/
wlhjKEnrCmU7g2cTvY7kRjgps9GyVa6O6HBrSkKBUaEYDFrGLFBK1U0lwdR+PcN5miqCRbAvDJUk0puV2we
+Vt675MVspPDYriGyjLycyPTdH8NhtcDuLDcEfMPHrAxG1xckh+DmAbY7+VgdSnPAx9wjEOgb6yJzY8OnNh
LTnkTrIlbAGiCQcj0Nh2NGI3gjU1LATlRWpAuNoCsdm8l0DjUPW205frvsBRKzv/
3QCj8FQBOb37YtO4nw77gv0Sp5faQh9+GBEl/
l1dxoXTO122LOvHBPBh66wyEtvjqbHI1pjtRDkAPiSiGNLZDy2ZSSqnwPvsfZ89S3kwmvJz0ujLnW8LgRjE
LHQW8xUEOaqdnD4xcaGrAtMF35+GKwyk+KM0/19Ygm+4BzWftBZhJFdWp3G4nV0u2mOZi+oBqky3q5uPE92
DQKa5bQS2riuJxNhg1tZ1KBaBSD+7srIAWUpENpW71O0oM6tzZPTmfzieUC+z0Tzn/
rl7vIQmkGCldZPc4B2296sPbHL3HuA5HWmCQymre5n1R0b2EmZt84r7dwuYJdKc1q9Pr/3/
rNHTTGSUyCcqbUykjRR6MCHnzwl0H4KGxABFbBAHiMs530i77fb52OACz3NZSCFDgL5Dep8qgkgVcl4q5Z3
Ce6Z/
IbyOskEF1yoyW25KG8TANeQYS7HtEbh73AeGwtOPU0Q7aqK7d4BSexYRE1I0jE0rSOrkKYeVOlzbOQmqCEX
oCFwUczA8NPA9jEW/FC+F28Gn3pAUTWeS8INaqSZlaDZqx19u0F5vH5XWur/xJyd1xaTO5Qi/
Xx510lX6bdvrYtHZjspcTzEmJjolLGQjgPg4C2/
rQG6pijFlkWENSsZlz07Lvzo4L92VnIMuBMgSQKdWZ6mZ4aViQtUGAb9l8rP6tYPqwGapZs+POl4i6TxVaM
i4b8R5ZWPnj+oQcrkpCAgIBAOjlivVUVz/6KMImrHETPipDSImtlo9K9XPKysid4w54U3u1kLbAb/
uoICD6sI1h+JiodgH973WLMmKDJmvTzu2rp9RYUh1uNasamYRa1Tkml3HdWnIxaKfu2WzBCyi7mxrdUpDOD
zIwFwqPsY2EIWAbjvX02CEtmOpWoadLHc2jT6pOeNOP4VQt3d9oic9CSNEb5aQWyDdrFLCuxT1axNQzqH/
hFPhafNI0VJJHYnqSCwhnkIJRZgmJDBkTlzW/ZA9IIF/
+I8bIN1GIETueAmmqHpCv4OjgcCtT3Tb58Jcf7536urcfgNntS6LVgDLYPsP8Uk6wd/
9V5vUiIwnum+tnlafPW3fX73AAS+WidJiblpFx5Ou6MaiobO6E/Y6crYL
HotXG837GNyUmLpfP0rii6Csdlyr9X5X4uE5jeZqTcG8wV+xVppgw2LNyUcrk/RExzqD2oztJ+2wjGK/
5wZpORYHahILrk8qxwcVbTDDFSzkGGCCR1YzlZQ6xWeYAEe9AkkdFUjB2CQGvp3UR77bAxYLJgAFMFWaN4c
ewpSlOAAMZpM5tiSA40kQOM+mro6UGOgl9SSzZpceR+Jsc7xe/
P8WwDS0cGr1Skycc9FDEoWr689evCS3b6kPIcfGabVCpyC1wiTqaK852bBB7hmoSQkASaZfY6mSGr4T3G4B
I6HaQSAclALjWIPCjo7nO8ZdgcWlU2nNe1WVoSzhUj23M2ykXKpiJ2Um1tNrJdW/
Jyax9dCKKloDuQxUVwcj8M1YGpfkzzrXd1mjPQgAYsV67qugpbmCFbxKyfPYYf4l0u9NTxrFD7coTSU7TkJ
/9/Q/+
+WHWuT1a2Fiu6irSXMCqQsixFtmgB7VcfiWjKUT0aSw5bizydIEDpjYHyLGdRHPaEqRMif32MqCTXXUIWmE
JHNmj35g4JPksxwhA5PJhAxEsn1ETXpA4a5vI51mTk0RC3vVIS0phQSrLMFef1JLJV2ElwQLb8TNWuN+4lW
6usV9147kPmnr7QcHy3WEQULcHLQVyn/
IX9uLUYOAXJNaVFUzqKKGv3X7qWokKyNRhB5WN6Fiu2lObAMHczlN5yl9zXd5GntBSUikLTEpVl51q1TNYC
ZgQLDkWEZcI+KQBmImqJYJQgzAFQArsYlOi07o2CqIraBbcKg2am/
8cE4El2wdPRQUdN08yxoZqHcCDFLs0YpLyoBOPuyaNZnABCRUEtrSmVMehmKm5KhWQeMvO3pVdD+hLW4Zu3
nFUy7ouOSIsRTxWURP3c+ujIIUhjmr67r8sbBCTcjXhU5VABFAivPW7lCNXNWDsr0imQJMtgqSgEb1SYHan
Qi+OOSzPuBT9u0uLX6s1z8EUIaejG+SBmx0xIWZgSGwIwvjtfVKAdS8HijdIvkANsmyamC1g1KWtLkCmIdg
a7wVQ81EIG3WUjSQOxRF45lkTGg1ONUgio2M5w5T9RHpa+C6+WxiSfOeOb8n97xUy7LUQnRH9q7D5tO6eXe
WiQ+LDedyIQ7NyEDnfIS+a7FCEASQm2mrSkUPrLSFjrI0t0QH3d2NYcKaGbhUxTS3xx+NQ+Miu/
Fe9hgKTUb7y4OJm8VPb+bGTbsZiB9vQNwhy+khX7y+uwSmhwvjFK1xEluIit6OjhLdiWPJTTsHp2FoqKbBi
DmrFh+QtMSJO6f5wy2nNzLD4ZA4NASjIP1I8JLxwCKCpXrg7TdQ3hmcIEmHPc7oOsbFADq1iMhSa82Wwwla
E8JV/UxL2AzNFQnT9o07nO0vhF2TliIoR3rFr7LHsYn9ZjmCaxE3K3/
oFYslsNDAs45Xlps0cvruRoMHcupD7lo6JjUhNW1dXdfIu+dGRMj5p04Q9EEaKvQNdsEQST0Y56MHnOB2O4
KyZrTtz1b96r0+AM223hitE28MNZCr6ijfkoVqjduqtxQOH3kltolFRcb4uArYdwEUMA7Tg2/5iAbvWi2uK
Rz9dGu8XQLKutsEtV12rbBeXyV0+AxxnN0KWMmiOb4TEcpQMLuwAwYBSbICNZ/
NHji76TXXakzYYGzR1gARbKcan4XHFSuQS+TDB6aZ7sF1t4WTGF1ZBYecDhXayO2MjmL5HUD9z3ZX2rrGRa
UjH1qZWrozph6NBtEv6PdLOWsZbMpq5cz9Ny3+b6OfxgjU6dJ1VKrG8sLtc6iM4HrhKO5Wdg3n9GAeJC32k
VPN0k7QfurFEtL9RishmrzEFfu6tHE/
H+rwvtUa7iqibjif6llQUiMR6n1lPKjk4Dgk8avBE93kGGSwLSFugyUFgr5QLIMDWwfkDOocjeIve4DlCiZ
Tu7bBBoNtdRwMkWeO3rAS1iPkMZtobhnPLZ2v6hsTQ/
VMpTyDMe6NS33KL6Oii3yJaWVS8A3ZYi50TUkNkpD4jH8hAWPsrJCrm7CLipgB3mpoj9NV5zVIX2J3FeiFw
jjGVOiHvy4xNT66PgpOhGPuYyxR28NdGzWT8mzkziIPIh54CmRmztawFFN5P5+OdAnpMZm3f+iKhaVhAUAJ
lUawedMG+YkotH2yn1vaM79qCb2lSZMQnDSjmKmJulrJk28Qg6TOhh5w9EzpVlpJbA1iZsXaki1f4Kdeiri
kHObEq2OArZBwyAKuAq9R2Wvqppbo3aY0t7JrsxMGNYlP7S68/fe63vI/
hGB5NjwZAW1g9SJ1bArwWnH3QBeA+cr21aTHlmGVE4p3vC+Wkl1LE8VLPZiDXcMO1sm5GZWKPxBvxBAV40M
GBhNgbi+2MVToIpwc51KNi5F4YGWVlpeYPsfgmn2SyTGWs/
OH3rnSOVSEAopNpIZooN6j6QZdmlGRP8C97heQFsY2OYDXGm+sl49c+FA0aS3SNU0VNoRg1KVDd84KJTYES
0MbNyxjN2G7iSCjapKsxDl1fDIXMem7kB3TZD60UBgVAGmPszKiPhf8pFoA9H2qn5S6hoNSYkd3muuW5BLZ
s2iX9gf9ITrwO2exRbo6q5bUuS9GyszGxwDkXgQMcRslM6O0iRsSYv/
xEtbmUrpVCQ+bihU2ya2aFJIl9WvikWtIX/
JBEczYimJAXbYuQ5UwH88esRocIlISkUZTAcApzyUEHiGVMD7u+13VZpy6/
YUc2akQEs9rpPDYbBg3y3JsyJTeQ/
DNJ0U1R0ysxKHl432n92ntXHM5mwobvteB1qzNAhg6KNgB4+HmDDT9KW7WFhsGExPQNy85KR+r/
QO5xbV0ZIHxHWbvozyVgeqLh5sA8ACbDa0egZiKAZFXKo8UXwxAsEQWWnkLUpvfG0qXKeQz1SRN1rCCR5kY
gIhbUB5BsaVP77ImwXudPbQ2DY400RYYiAQA1u+hhEfO/
7+cIJH048AknrAx5WUCwM2AGnERKJWPHAmt+dWTnEmuiaSLosffdz/
l1NIojJp8c97zi4pFUI7cae6AhAC4pk+17ROMa5myjaSRuy75Iv9Vu0w5wKTgrbwGg/
zNngfph9HmKTEc6H4ptQHwRCGIFBmlONojyzASabLyPiVy3txO8dFF+xqHirmQi2Ai/
zsji8SRIKwKNk1K6kdSetB+I+RPCGGXwXIMwrtea4MBgkZ/
cUzj+yyWFNEZhB4iEYQQOPMhBIclkJk+Vf1Il0V6BjgyXSexXqMBKdaqlJVJIVQyE8tUR0JRgKcAqJIPQfB
gdXYmqe4NMBlxHTjAXRsg5PH5HOJOBwi80p9k1opMkZWRNAWNq3Y5z3vajRgmrk51AupQOSwIyiBaKJpcNi
rIxI/Jy9gu2NKoUmU3OyuKOdQ0QKey/53S3fwr/
zL4Nnp2vU9Q7ZhqnxSoamLa22xizo3oUiBTguxSzYVgHPhdJapKpmVBVYff6UrSVjeMEZ4Iq+D48JBdqjlF
1HMvVuqSbuPI0x5uRlBWVWjweU3Zq3B+jiIxI2h7ij0F4CgAxGTCDkepVABSEJEsTVEtNSJ2xKchAEAHN8W
xxaeaD7TbP9ApCTnINEw6mCj2gUq8PeI1RPVBiBYW918BCI7ZdeWNIpZFpV1FpSFiM+sYrvG+bQ337i2cRz
p+fxl7K6ObeytQ/
EeDQbvpJY0QFryxhDyQ1Ouqty5o3jagS54mHT2pKJOGq+DPuTcuABCAoKq62T439WdssVuOf+ris3Zc7SbN
bPUIeHLPOsZKJWpenyVKNqXRfg2PG2T0c51h3U2/yHEfKT0hOmQ1cqc4ntMyjlajFdqEbLOWFfs6ztw/
eniuu1HK0aKMsURdMMfOPBUNr45Mzyk30dEBUVjQJsqP8mPzxiqanApp2GjlVY5ySvO8a1TUkDpciPN4UNV
IG2UdZu1b7/
vVaBBNqOS6UjqHYKqM9s+fP8cAErlGcOKyUaEQoSJgThtQGrRS+D+O3xG8ZVTrmiBeMjoQpzdaQdcr/
QhJwzVg3fCTz+qc/3QJ/
KejRDw0eN6qvfIDXwJwCC1kU9M66CMKR88YYPvpPLqMACYYG8q+uF67yoCNSitRA/
DQIyqxJqvjNYsITrubPerGJwVTh54U86rSFC9+GSggtH/
MDoMVlwl0rNHl5qOP+gohTPW0hM13mFFL7pa2dOxaGE45Ftb1jI958AWGgXGixhqdZN3OWTF3KzjUsnrdK2
eW4GGs67owPr8AvK1qhmhsMkrp+ylktElr9N7GlHEi7WxuIISvaICJIeK2lxAV+bb5s65VykzFktlnulhYa
dFpLDHVgNPBTdga6FB3n3pPl5QinCxJit+T+jQ7O8a7UfEeZaqJhsWn8zJ1OaQEwBk4oLJUIfj3mSMSoAaW
Uw3s2WzAXW70uVU5O58spZQGHnCXA5Uw2xrxjT3zKROogh3TFxI74uVGr4ea0FBkQnreRpSLLMfUDwen2k9
v7fgb3pAhZ823TW3dsCrUJEJbwTdF8d2a3LaqKdQOgFvEyrDI1J3CMgKYSDAW9zjKYKQXfefLseo+aF1Qng
CZioot2DCj2T8UCyGfLb8cv+zlLgkmripWFMOePVaNNNbKWLSBKuV7SGL2CY6OJFN0lvlQHHP/
biFXnRCQwSSlGBuf6u3M1D1cSgAgkIvBBa1hSEjWKmVZpsQys0KC7fmkV+aNSGeTNbt3P7lMWO5GqrwlcoF
uOpzDlx4kg/raS8FrE34YMp4ZGU7rbdSjo4Mx/fBzjmpfrCVV/
+MPHHW9mQMhEExpAok4ZoaKaIGA16qnbAth2MoRLFJd9bsZw4bq9TzPH5EWUVEACsGIxxp0+bB9VPjTpjRY
CIwOpsuKrhvBpwqLr0Hqbc+xG+vrHsdcz33WeDCh+33QJ5+p3mEnZE9ByaXs4QDbW29VeqN/
AEVE7huaDQWhNjauD3VpUb562FnxhktQU7TWWpXVAAixGZ5AlsPzlVZxaGGiuMbNRXaXptFNL7ZC5iviKVn
y0y1dv4EdkihPCh69+koZZ2dHIrVrOUlvlD9idqXfZB5/eFtsH+3rlawr1ld6VXe0PHFdyB/
Ws0g7knjf4YsNN0FORJU+m0bd1nZ73HQpecDrVifxADp4mPiF3NJdKJRH0IXeF36npCED8iZOm8yIizwP3w
B/
2oyM0OK0hlJi0ffWxi7nzAmstMfR4vhXUuue+YuOkpm3+ksczz0IQBqIggI1wONkUV4H5bEor+xELAEA0a5
Wd+8GqYVTT84GULZjyrFCZ+E/5OHAjbG6efB/
rB2P3KAue2YgF5nAR0ZJc8kTOsLtytTFKgSISpTAVuhO0XTQ08z6c26jXb7YzY+V58st/
yrA+dhPKt9b5idhSIs4S+qsFIqeG9fUSA7OxScAFTOfPMT3HQURj1i+N7IspaEaZ52p/
y80BAa0ooQ2qu6DK3ZAa5h+3tHpNC6rSykVAUMd04EuIr1Wgpxj0dS5W4FURSmpC+h2BofhTMzYOUs4taR9
AhDAAbCVZW4avZev+dKAgOUkLM+OjqbTMlFAVWDK9YTAmJiOK9HOTNrt/
2X1wbaf2jf+5R3LxdSlULY6+evJoF2wbKii5FKP/H/
oSMmkcaqmqk9fFSB+NcU5rARySG3QcJ6bHH8tJ4ID+E5H9269vdasZ1ThqsbQ0Ep5CtOkrdQNSuuaAWPwFy
9aiORj5bSQyfSsaPmqVU33nxrcsKWiTSxXOlqIqcpPVmOz0psg1GEym8gMhUbQyeSSNhkvpe2sJ+e1gfbrp
kAn0HNDRQVaM40OXA9DkQnaRogypZYEICJIFCwSdj7Qk8rUa36Z6q2qSguBqliyo9ViARRYaa3bCgSeTAz1
ip313/Rn0BXPZ/xorW8Q/Ejgg6f+5ae66iPztyVPoWxD77nn1zOWArZX4OPy3yCILxoT2csKWqWVZtYP/
Ovf6za6qBf35kA38o7rZ70rdNvSFs/bUkeYxQZI1pnSUM0oLa1SmjEq42rGpu/
rskKR2iUQPyctJNLU0chb3qJYo0GdWniv+VlQw5o/e61XJKORdCPiXoQ3LUctNpuZCTt/
WEjDsJTtGdN6eN1LX+smTwsIVNk/
bqVltFVv9YjNUliJBBa04b5qghzPFnhitPBB9ZCd+lReDs0zM0sxsmdG1k4zcus4YY8MKOtMWmnjtFmkIn6
Z3/sTfgNHqbFbfMm2wT/
kKb1r3H59ySWaLLixWzzVDF+DGTXaXR8SEmwSEDopXnKyAbcJpiQ3CI57OGRDcDV/
XHrFtmiwOZE147PQ3eOwPtCsX1orxmCbfbtGzWJ82qWuPyeFftyxd3BP76nJlOrgCBU11AmgLVjh5v/
UOArfCN1FBdnXM87IlrbDQdM77htHznj5PzFHPMEr3CoJo3F4C9ebrImETOp8sW0noO5sEvcJ5SUmvmWzGx
7ONVv27uJUW/
36GaLSrXVLa1LbTawftooJSx0ktssX8JBcf+36+BIv3MiOdWa910S5qWcXq7MKeejr2jnb1rxhm4iiYOmC0
PAehT5/
Bm9HWZW4Kgh0vLuNniPj9DW9J+lVOvYuK25qFwQF3VILVqCpfB8j311gntbHax4S6abxqyZMwr4gIGSxzTi
Mh76IrraS4rdr3SNH3HAALCWbbHJROwTF2HO/O1wey3Sn/
QUrY4Zdeb5JTwGkjYL9xxfkYpGFMwH5JDgYMUO7FnecgUn54izGzWQmmBAKKaAdRDpZNZ3s8ilF9TFCmlZi
EyAzxT2xYlWqZk3wKiaTkqmk5tZEFZeRzEh27umYsSd0yNCMbfpIDahdsk+ABNf9ICISAnszMAkoBiQWD+a
ZmWrAYGTuWZCcTlByyEsQscNSkBK1g3aF05NL63KGR70RDrtHQja4+JTS7sp48zLYurYjHylHBtcv482p4H
0Dt8DP8rAJRwGzYgTYhd1tUXUEX0pZtYMRQIDFMRiwXWRkqHto36pvDgCYmYwDdFc/z3Wy3+/
TPqIt5HiS1HlzIhdHpbYJxzsmPg2vuyeayFaWzIsfBXQJUijheH3CEKJvn8r/
pm0ifujQs0RSY5b5wptaNGXWZOqrIOV/xGPpeJo+rfHcqf5MwTvWHfszRc0tS/HrV5ts4VzTc40AM/
+bOTCbIwZP2yEBSCgwIQQ2iABuB6tMTUZDP+9NqRJmjwTnxCVYJEGAoLIUPDokzbS7CS7FP/
OwUc3IQggv1Vu7WlfT5u23XRaNRdDBDQs+8bn2dyddh44OLob1SoKGWcgLERTg2JGwYzPBJcABAVZQewswY
Mhhdr/
UoJow6kZXSQQhIY2IumF3XGe5eHQgrQLbqjXxamsNrN+tRZQICvMQNNgrJlLm59x18U5DpNrGEYqtN1J8/
GcctixT0UKDT5UWFbbLUPy9Uo3TYOC47OEZbsA5/+GN7tx6gMdUlGkhwkh93dzueAIA6ghABgFUadpQ19vs
0u+68A3wXlBDnMwcHnBzAMbmeFmSSxqlfEKC9eGRWrQKjEogjtW1ydvJ1evYO+DT8KAAoaLCtr+PT9olYOs
237YfO5IEpcaJ2hAyDCDANV2KbO2+BWUA6ATvIrEQa5DBBnkVgb7nNib1aj4r/jXzlZyK2+8V29Br6/
YndOl4aOTl9N5eEYPtIMZyGxsGkvaZG89XS4iE5v5SSarDysW4HxetwhwfZiNOHg/
M34r8IO7PXZTDTN5wP4vL+tpxSJizViPqFOrM2a3jCJAGCioqsOoCMwGffh0yMQFgGkgBEyf3KFk5gBnqK7
V759p5UNIKIIpKBwAMIOlsDaCDOrsgNU4hQLJK09dL9sYiwTXqZnaxpTZWDsJuD1aqilhdUXqn1swI4Ubsm
l4dLRWr3lf0VITsYNJ2iQGbCIRJYjRGbGq4AtALABDAeMDVHhAkJYC+OZQPeEI185z25NSW2Pq3rG/
cyIWW6kXBUO88oIPx0GVxVX+StqwLVmC9xMTiQrvg14/3TmDsKwiwaOx2Jvr+rjwcfYXk+r3WYs2M/
IcnpgPUL5xwlGXSuEpa0yqOGrWqj+pD/
Av1t48vlEIQmu4HZ3ofaCIA4dXf68JCkeKiA9gJOEqrWVNcFki4En4FkXeqcnSf3DeR4YLMsTyyYaGOhKF/
GCn4+Q7cWb9SnuWQE+7T9e4JqxhCy0+EYaDTDGDF7wFkQIQ2khnIdpKZjbLlviSIU/
HwOrEyXBraTE5fU2wncffT1JvvSXlpbx9b7m2bEcsaAxQvyslIDhCp4GpGibaujBk84lnaN7FftfTnj4zvb
ON/KPe/mb2av7rpW8a/+mys0t9eYygJvkD2KftxDTstg16+GWd4vc/Wgp1VlQK98itY9fOj/+U/
1BexhicmnAw+6aSqDgYtfsN77YI0EC19AiIx0yMgQF3J1hLi1JDD8WYOlz9SFWK0oSSLfqNxsVjWvt8VKeV
sdoPPEFDjBvcJ7glAYuuAtDmdqq8jcQCw5ZimpirQImWBQiRI3BXIsmvnYlHv2jmCnOW4U/
Hz3hLQ9bTDHFRTM5DAem9l+MLJiYsZ1AsaNpD6Cx/BG2tlXDIvGeUDiefC3zvjH/FR5UGsrZ8y/
9XPzIN5BlNoO+2WySCo0kfqeX0UC5/7wHm5WjKJJmcEok8ut24bBrPxZnrJVZpTDuYdoDijri7d196Ze1xn
wO1//
TpA3H0WU2S32+1iLfFVCOwXX91nCrMyTTZNsHW8eFTCUbB7LW9g37g4mwD5uImxtF8gpOJxx1wQ7qVmUBNZ
1kXx0VtiiwZzpQAi94OM43m/37mf8y9jMh6V7tK8UIWh850a9UQiKsee0TuJZsZ2CFAM4ladbT/
BBkuKhkZAdIl0ZG10tZdk5u7NAC+YpvsTma3zEL/iCPfmByq+wXgzaeKR9a5VmpIb482j/
6VayIv16bSrsy/
65Jjlj+5Gdxgd1toeUZ2YIQYbcu+2Hd8Uu7xvAyHdtLgLjgWXUgI8pqIIbk7eZLNRnyf3kJC5nZgKEw5Qua
59pvf5uTibydxnpJxyyjHt0j6ReuljzfnuCyWkwXF3B1AMdQlHRyG01IO2b5/
UIQAEhBgBSXCsbVN7byO8ZaqiI7iiLFkHYIMJXi749QNfMt0Sk6VxhYCJPNiRhkTsGADlh7xG/
NQ7Hw+D2iQbUYrOUjEUeEJZloOx+NaZu6wNy4AtUGqdF/
2eh2yxRdiZXnm2SMVa06sOfbL2KnvNklYd7+MN/
oNm20hQHlkz0guK2TDMmNrI4ASgESKErNiMy9BFUnKbUjz11SO5PB2Q1XJhuUAnkCQIhzWIFHFW0psCNCpF
t6fclhAuwrs0DKAT82D0kOrgrTsLS58S3tVTINYxhK3N1FIIVxGIxGx0auxKmpX3GftYO6mBfga7EiM2F+2
1zqFXLCuQaJWeWahTg++mjbBztdS98GSvY3EUmqHqvYItDd/
+VfuekyYncmNgiDpzehs1ZC8HbGkVF2A5xLkOzdzD7LQWT4jOjShlG0E754JKfbO6NazyOIwgQIiohXRFFZ
uYzxF4x9rltjOtTBai/UqfYoZJ/CJgxaMBy3DIH5j4zeTV/dGka8hFX3yJ210WkjtqVFvE3f//vU/
UI97VJUToqLknVKWWEDhdn99ADaScWTrBA24Tii5mJMXqYAMBVyjAWlBLh6np9yf21cvD7Zpc75KDhigRj2
+cJVXNGe1wbPQACWgFyCAmuOjJhBTR3YHNooIFcfBK+2Y7So9Kj+hu6hjk55wUuJXW+23hk8jWpFkWggesB
Rg46QipdIOd4VqHd01M7FBXoWoLtlKHWcZ8ht6xFkHSSTqS2lw0h0XfVliMq9E2sG7CjBEZRb4zga/Uv/
SXDgFgRMXVEcQ0ux/
jUG3/7S0wvUvmrt9WkFgFUwfTSm48e72BCM6XnK3Wq03HOzKgGBw1BCwJ8FIfE01yX7ghlndj7lKBzyWnYH
ZKmCVi4CyohnQJNZvGETVae8DiXe+j7IArP1vUUAWLWCddY23EjxBuvXI+SeN5GY+/
XvKWBxXX+Ddd4qw1upp8/81sOUyahGMeEMbGHKmizaRm4DxgPX2Rjd4
4n7hkoFpBqre9Uh/
+3UAxT2PkaWe2FfXuHsRsLDnOBg6oUYmJbEJZNdw64JEL4fmuL6D5B+8WNEUhI7qZH8zHYv9t/
rBP7AACFMhlUg0ZZQLzeBvPZzj5/WVmvHvXRmpsIqoK4NMMMAP/
MYAtga8DQpQAH6iUpy+p0QmgWls5ZVFc4sc3tkT7C6f18DTdHwA5ZGKCAirB1CLeAqSxnvrHN4U+Qdu5Nsw
N634zeAavXuK3PPwvbl2FpFUnFXHdyHzz9QgX4goXhekaTG3AfiKu9cQZ9JWOUpmlZkzsxSU9C41hXaCy6J
O9lVtqPuK1unhIdMTqEQJWDXMssAzuyC3LQCaJiNtqMyIoAYJ2DVY6gUIZf/
jurUHwZQ+BhSBFICUodmaWTHMPtk20q54VX+rHM7y76pViplfqo2pWVJVFzeC9R98hOaAwNlTCC8Ounw2J1
PFyqS0gKBPnmiNk8MMndYXlLdFwyFIbETBDsTA5kEN+ITYbrsdse9biFnhLrYSiKHu22rffHR+FiwMfaDpT
I6x8br1Jy0DGzloOl+IlTqBp1ZpSnBTc6NSOGRDs3nL3E/
Rdn7TyGv9OhUZdx25SBnUzWZLstHnxRGZWejsNj7KQD9alClSa5zeLh6WFdbrhahcKvwOpFI3vKrHgv9+Yc
1JqF7jAQEkD6CjFwJGk/
wCicl1QZBRmkBEgIaVU189HVjeVgAL1ScTq0llVv7tAKEg1EYmJlIAMqLbJcFM3niVpSy4FJpf7eTDl9mcJ
2qvJchVDShBBdQE1KGXSEZ/
evaWHHoswiWWBFAOmjKoTFGjBhgIgxV2vxTETEwrjHeLvJ2+8ZI8SpT+oFJnYNoCCq8FrtrutBe3qPbBaak
c63m0YzxRbBdVl5ev1dlQ2BtLwtEY+oE5doRpUlp0VeGIerVW69sSK4ckGZgThYuZe+vxi01in8ECJCdP9j
nrfILI3Xp/pY5QGqS3QOdHyr8nEzXF9PpQG0bDvrqqqU2v/
fU5R7QG5PuwrmpR2ZmbbD970eHdvd99RQnp3uPsbhdvb3a6WXU7j06fvP4aTwlHNVO5R7RkqknRw8j6Lt6b
bbzjnyuv7qvosgo72Igz37f3WFXkVYYGpTKcT03EKQ2UKA//
764fbuL2tKOqRZkxZmBGRiIvMUIV1CkOYSae1qAaka9AeqTxX0CgTweRSGnIKPYrceDW0Ueal24lvfLhom2
LveugDQyOfgT7var1OKEHyA+56t0XFeiWHaFW9HFq49YrMzif+rB8ku5p/
VMAyrVaIMdJ7xfLKDJiayHX2b858q+wDHpHqJoPISAuTmTJKNQMjuQIYpXVsdyT7OwdfLJ2dnRnBAyoB4vN
TwTSkWepeRuorC+8zljGNrUrp3dbMkIGUnAUD0frEDA+4QQIvA7TsFmBaWf2008pQofj5o2o+XM5hLwCKdo
DBCT0a9vZtGMjAZ6JD75CGWyQxDAOS4qJmXpobH093SYS1SO+YbMywfY8Vt+DU5TKS531jhDs/
qYmDTiPbuOdux5hiFwPzJ92bVbG2YKgVabVNrX24t6gHM2AkTbZKCBndNhu94uw/
m5dRTROT6gYKaIALnKYXiRxB7lrPdEuALw8t3xj+643SbVrMcVID4DxstUP2TIm694ZKGyYP5ACFPBVg6m6
332VW6nH/
MSVw7y6AcM6hUDo3qTeqz5OEJxzoUCSjhy356eSQZdanJyIsmyHR3Lh7Y+t2C0JM0vdaEXlacjoVFbbFTVv
yT6823fm8/
W4cs2bOQqoMQDgXh7zj3vMW00B1pjIFpnmdwKVIOkWfttsQdWC49YEO72Tipmh9lk7P6Xc8jEVH7JwBBh6o
htpXHVNZs1U9Kj/
tJ5+DskoHhaaBYmpmAtwRMajh4EQEVEKWdpFY9QqovRWTLhtaE1YKn6nSIDQBG3TihFYlZXH20iVQpzx4/
HQ6DQCYwdEBa0QxYW6BSoMQWRnNER8MJcbYlUfIBiFQp3tuhgFUsxMBbN0a1zKQkieAAX5cwtRgLE6r9xuj
9x5A2IFiPcDEFag3PecjpvP2awkCwCjgcJFSdZHiqQ6O9iuIoM7+E1Yi1QuuEGEzu9MGF/
DbTt9IVjLhAG7cZdaxDTt+oKenXM+qhESXGwmEnvsv/
do8K0LFqJQmKl5KdYLdSXMyTXWqiVo7HRYKwggcuUiqYMg+vic0myrAMmzBNbAzZpe6ty7hYHE/
jazY+m7JFnYhkGvQGYxg01CtgXwwiLt582ovHdQBlLfgRxuGtn5ejXXBJ5oRwANT3fAEN/
VkImLc1HwhLdPphHKuNUTotaMFEMMRs1oXtOLOWCtmgqToPAOKxAI2txpcJFxK8JX+73rChsQ99yM4XRupn
07ijuIaXb0AM6qu0HCkWr0MULV5k2uVoR4XjebaD5L0gofqXM0KL7BKxkAdCmbK2qfD02xkbw92XrDhnaTG
TdDMpk+MNvmKUFtgpKgghma36t2r77kIOSPDI0fhDACMQgkAXgPA0ENeIENcAUWT704G+1evEgoo4OCO+6T
DNjYG4EpJ4YQ0ghWHZJHYEjDMcSIA+NFVQTpcDU5mXaHCOyLkI7DoKUq11+XYVMORtToVyIipEM1eC4P/
gZGhRYd4BgSNlIj8SlXIUYGEo/Hq0Tx8zQUskWZZVdnCdyFU7hxrkxK+P/
fnWFF9TWV5OlKpw0zcEo451e0npchwdc5RVjAkxudnvyG5lKzBezv1Jx9i/
1kcWyjwBtjCnLqvADSL6iIlGiUHLvu7RyEASO9yQ6+YqhLGeG08HfRhIt76uWRgt5OBOIKAhoFgxMuUW2mb
VvlfgFIMIv81K2CNgOTdvHkHLDoxeqmEUIcQwqsYIWWMbslAprOqKgAVICbcQBgC2lNpfH2O4q8lP7AoFMC
OYTC7ehC7tDvqP8e4e6xf8os7jIz0i78WjRUlLxLb2/8W1EGKFa3vj6ggUVLI+TRYNtJtzKz/
iSTQ8H38Njztm/
tmbbSoOo5WYfuMSCXve4qdJYBtp8+nULg13eAHH5wX9sTWQifC73UhI058lMAuGQhVvD8oSqGqzl69Dy+Ig
zsinO9AhHUJ5kSCgCFkQgReUVUvLJR/
IDv2aFgNApAjeKmGttOX6ARoan7VBMA1ALoowuKC7P6RX2THK9L7/
maKXyNOojXII24rS2GbFIkg8rWVTujA+IPuRKMq1F1V8ZRm15Kf/
dV3plzYKHCNKCGIQkefw0xv2o0OHGAu6YEGOihdro9KMZOQwjqQ1EANfkFrkbFhjLV2QqIdoVF13FQRIjLB
AFfmuoLlOAysLuEWyH6UU6s98JSCyl3a7hf96mMhjsAR0UiIa/52Pef/
9VgIQVeFC+f3OOZmCh7yWtKXWl5GIRGAKlLAS1gEQwmpqwcdfaM1b/
gXeFEYWNMcoCrUgnFM4ZlDqJs8tWTNWVlSbHi1P9fnA/
vOeW8rEnqN5PZHuAZdgWYAhem2jtlVe8jnl11U71Pefrh95mBXtZ8exH5kL55DWVcZqrhjGlwd8sFHuO+bq
67QK6jokpHMmt5mXLFVs4vSJX3FDasZdTT3C8O8osvFIxtFWCbhGkbaCEIqQvUjzPskF+Wq3jlPQ3YFNVTl
p3IkB7YyxzkF1X2u5/
DMVhCErCVJqVaF6zUi7o4DkbHSDgyIEFM+rwT5NhpaW8SWCQ1mgt5DCMTKCLLSQVPY7KsCoUzLkbcRsFpQm
pROaykBNWxdJQAla0bTUiBxM5K5h8hG4h0ePVJMABO5ZIII72dayFcZcAawNhyaXSx0tn9XS6VBs3xrXtOt
t4oTkrmTIVp5EAc7DNvmGIVuBnVueNt5TwdUctI6Uw4zkOHNIWoN24myyOyaY4vGNskCH0yHqAmZJdUiFrO
f6qetlcodl4vhyMwinigarfXU29kaEZvNxjdyX3mivT1oBbohxZjPqTVp1hpYyBpA3ytABGjpFH98EdzQA2
q8hhsJZuLh2ZGGiiVdAyA1sHahtrFuBBBUQWyZprhQEWhrceoxvQxlMakTd1kdX+EG+EndiXx+hjR6OTekR
lSpozR0+smCavknb4mzVunI0Mxx4wyyZcH28CmAMXoQsOBBhdm9GJZN2XSP887ewmrqMCkj3hokHS3Fq+MY
F53nabjddLu4HS8vqJIHwUtI8bl33vtFxSn8Y49seQVIIiVaGAYpKr5xARABDKAKR0YrC7DkPk9qOMQOrDI
5yhBM7RggA0ioui/
C5ucugyqVUaBAG3Z2XzyQPUJyfbAJDMABnlBVSHRGBSLaduj2UKECKR4FYADEUB9pFK6Ho5uGImAxHpH7Z/
YH4872ikHU/
PZCJ4jIosVwvhiNYVpcbB4XjI8mqm3cKQjI3ATItYMMWpm9a5SC6eULqgs0qLCpmedOb12CSXfRkQ8RZtG+
L+C81HM38R/eoPwLUrONb/
XASa4PzdBwFgYS9QeJYsoCoBBrE4iIAt0PgJZpGrW4e+nIZ2deMe1Wq1OhSZxdYgt/
Q2tqshGqDH8E3kGNkizLimLeMnZ4vz4eNzRgZkYQjwdMgJ6M81e8a1UEwACTNvN/
v7gD6gA6owYRQe8tM7CMePOM9BuchCTdpap3yaKtsOk5aik9D+ZFtVTnRSXY5vkkKMeWmXN1iXkq6Y3FAWZ
KDBm1WWTm7BnD6OyQqQOvkrW11rCAfX2SpXBntXfw4Mxo0R/
8iIbP3i612LfCCbiEzQr2+Zd6LxmiQSjdzXr0LSKgV6VJ2gNVADMHY9F8mJXjO88RZNUkmyO2B7fkZ6mfjk
a7/77rKjoBOeur3ZCxbe5FntJZMa9r+rjkXk/de4kv2h5qpfSO05Mq7KEoseGN4m64D/
eyV3axd+q0QmS7J7dRJiU0fAqpeVV8HrZKH5BqlOopgqe9YC1HuAycnKKkr1Iskz21SboNZtUIK0GZEi/
vufZCIAvPqqWOONFA039oM2zvaAypbzIeGzOjUpAUOmELtper5zksYR3sbOIPP+e//
yPaO5jRBP7Fu9h97M3KJnwD3xpnW4LASFWsoifbiHM9xC2PZfaZ2u7cYTZsQLUDtHURnbmLmCtZCLrYrpoE
SgbbhQ2ikB3qqGhPBqeVJezg3NAEO2x3pHqr23qQOKTxHslJsqqhu+FYnWNdZdixhSI4JDshNwA0Q52q3to
K8MTETDRhyWtbFxV8The122C5KHQqzqFHPGV5R4L6cFW1YFZQ/JM5ieq4cCv4xB/BYBrZ3/
TeDnRbHL8DZmxv78MHbKLO2KPr77UaoBDyyGWIHMHJruWn2485bB4eaYknHsvJbR+STJY5wSkJXuz+VOqmY
z9lVZDJfNHx17bvubnm15ndYnavn539ig+nOTkt5uegFtMQsRMJpdv4pXiGd1DixZh7rWjc6qi956NLpcm7
1CwNnxXPEKdbLVO0aPf7RDCa3LrBPh/Ye9h74Dm1CVnMTvidK4mjGqc92FoWBBd/
B9GSyjr0KSpT3plcQGu6LP8WtFu7DqvWxBKiXOOuZ2HBQbS9Vt8jzXIHCSSq2yOd4cow8DU7C9+XzHEz0CW
q467CTdwXmjGL6Je12gMP5Qf186FW2K/PSOTF+
+Pumjz1dTXkJMH6T4BCKom4neg2oTRuJH0vyDu9X19m5+LSQYlHF2c7TDNYkQLuCmgfrB8eP/
2b94UhEr+IR8IkcQOwaE+RsMap3W32wT5+FX5Z+p7Siin50fmHwjt+mQs6AZfS2PHBQM6xvMkc9u4u92X40
uzLe+VUj7TC0VGNvWpHYyoF8AUcBxQOsFVsibIloqEVwOOkPQ8l6AoOUoVx8jyyM9xlxRT+GnoAN41hKMm5
8fijSUFBkzzEhQjP+iknNY2M15q19tLAD/
6DcfF7HGvQrC9i8Arp0jUpMN8c2HY4E0PeIrVYyqovGC8M6CjZBb5c7GQAXU/
IIjahmJFh5AaF7ul8iqXyqb0SqvLnvjO7UnhgovXX3qR7/
Pf0mD8HrXdVimpAMl5WRC8j243cBbxO5qT4/+LSb7SMC/
Xq0QE+kF89op9uQ607zNjH8bhdgFEs9mV+2OkrHQSo3elI9PirZ1TP4ju7yV/
ryV8CnnPDQY2iLxU3n3FRZ1sOGCSV21VseBd9n+Yzi3FHShJDVZiDgkFBhQPk3EujVQEoW0gKgpSs6n6FZW
9oWvLvEB+k+
+FOEbSFUIBlJVSGjdxdNMZIVy9+GrySbAwm8UPekwveEw6jLPfDwC20wSINREmI1V+NfztP/
CN8c4TE4OZMmFg5xQArFYKEngyXm9ACUI1jD2s9QWjCbA5lIt7KKSUDniCGUSgH0OU/
yfw+XgIsIZofthTCFfzI17/
yw09BRzFD51BBWUvdfFEehkmFqpEMCqb80AQRw4g4QQLHSgw3UQIpdnA4S0D03cLIlNr55b57BDRTNI/
bTCQP9Xzx4Of1b8ZF/TuQy4PguSGWX28Gmw7/4E5/
ZaXnrI1hRScDRgEG2qV3Mt1zAiSWLsXVhyxfQQAXyRfj9T3rCD8+/
oaeZCrKCCvUbuA2b8+1QsCwFbIBEuSNLE7/
ihTJhAAUx1QvvAHfjH89EsFxqPNf9UFhtJSF4jR1S7M1etgbZ76KAJDEQFpIH4IOpwwSjzZvuh5aPUrmUdN
t/xgRm0txFW8MQrk+TCoqf77+Dl4RrkwddgQtoko+
+nsuJh1IsRaD4muhtoLMuTW2tbHBRGGuVIYa54tVy4mJEJTaVl1ktd+8EoYFHUrhlGNYHF4QPzXw8yW6l0t
Mczd5ggVSgerEei6sp80SKCxB4yr7ljIHRKTC5ZTSACAgRC0pNA4OvExlHM20mFEMNdyhM8AAHrx5O1g4yD
PVx5G5cvGGL39SKO4JclK8yhK2YT1oJo+i8cC0VhiF2lBuRq6Z/
YulBkSpva2NLqcw0oFW+Ahfkq6oFxkX79gP1k3uVQ+rrvFRnm4EgM1wpBENjKQAWW0CrGBPIVCt6iJyYQTJ
wmnLWGiK05uc2roHwCCE0tJ/
94d+4iPVwb+uBdGHfscyFLXfAQUPD9aboBWVYXpVmK42C0iuhhYbSpYTgNzeYtUgAYowSgQrCEEnD0uxNOM
78O9mfL6gX87uQjhR3pWm/
HSI8h9yYE0sVd4OrH98Ps8ddqGOTapyAqTRXiHc38axvJwmn6bCNBV8mkAZMZLRBfXF18oAyUoj3sdJvrK+
HimnteiQCZ1VvOHkBBa9kTgjed/5NMQm5e7Dc7a/
Y3P4fGsxanOlfcAmYYDxMT6SaddT6QMexrGDtjJUeZ2Ht14XrdCoghTCNrWkEhKwuSU2BXhCXpbDnd3wapI
s5ePoxkZVMkrLZBzAG+LJshRTX/
23yy28YF2eMnBauieTJ7/50WwKGBouubCp+wBb8wKvamNo6g0E632FCJ5OmC9pcqOKQQEJxBF7tnwCNtpij
uUp4Zb/9WJ8Xj1/
f+JD4VJkmiNFr9O34lrFwCRWyRspJFPN8mGx10ZfKS0M5E0y0kfiHrmmgljFERLu4G60qoL6W0AK2Cyinue
+eOFh46k+vG/30Je4ZC67YUd3zE9OAGbe6XAk1KbVp4phjvR6z3ELoH8t8313CZ+VsBpN6+Zh/
xt8OJUnocRsSEnyVcvRgTHDto7uhV/
g2ZWFR29Q1AniZPUMWDbownFnlxmoF6kf1LAgCCfDaZmCqg3C1ACSE6fcpMbS/
FD8v58UGoce6oIwqTEP9fSfJKkzPvc6j/
wgBigkCWJLWBbieqrR29OZ9Ib92Jezo0pAvaQj5px4xOjuwpT+eRW/vEh/v3n+nx7R/7zssm/
VV1oSAgMfhMZUQwzY7d33PjQkEWULmw4T5cSe5Zi8YAqxlDZAhBg3DQGFnTTbo+XlJT3sQmX3nDdpvqpmiM
0QP+rUXzOTDlvLkiM5oMOxLERFGJXQb/
wDeOB95fgwJ4froCXvTDi39YelTNa4Sby88QVjoe7L0+pfx9BaNBzV2fURaBp7IpEQKCrEuAekZw+Gs5Wfp
AB20FCekhozQqHD9mSNSoJWm6x0dy6qgQFHkYJe8309WLCM/
6o6WPu15g8/3RIhFRoCGWKakQTpRKFwA3C4KaqI68P1AoossLn9aJ2yDcrrZsvithZFAoqm/
UjVg0r+50DqW39VnEaqAvCH91H1KSDTmueqkL+d6rITYpiDofOPsvMweryT1znPskbfQFKMSVPTpIdwLu6F
/
fC8mUsN67UAnCoaKY4NIodqJB5PJUXFQ9L1zKX+dKPfD8u1SKteuAn02Ow2mR4+qH2VHFcsrgHo0Y45TH/
iuu+QD7gZt4q1qSr9pyrlTqBCteMosAZbx8L4xLQ3vi69+R2PLeOyIYXBKUGqJGQXF/
hcswGRB6ANWCAirrW8ALuuOP38uPbokDMrmoaCTT2nSS1fbb9sKvXR0fvsd2ZTS3nIkkD08b/
fUKnmtDCrCXquGXrNqY7kTgs3432r9h6ySBE3buu8xYVC6ipMIbI3/JhEK7evchC0C3Y54f3wIi+uIPNQ/
6PyGyyRPEL6GK7d+/
lwlP7DjR7OPd0xjg9jAot23g8CMLmOlozGXFza+UF44KqbGlJKAcCsiryIIeuvy1Dl2hoXWb1dHS8mw/
LSKassfaIL19FHmIg67NypkZ9x/JZ4RzOIBR34Nd4/
vltzqzabMVQtLgpHc2axOZ89cmb11ZwSydUsZ4qvgBsm4TDUPQiae6DY02rrTLiqKNkILvTtAlEet2eZrtn
XtkAPrKXO4VmzgcmCDCD3qNvzi6pUfMZUG/7yudmfxuUkSrLko/
8QBAHru7aSi0QGoVT12LILCU7rnmVnNw1VaKWfzwumfL2S9rQq5WwRZPgYh2PfbRlCajS0BtW2EiOofE+BA
2ShLT1wV8ijSi3wYS8/+ND/+FqrPhrNCZntrEHyHqjdg90+bNhEhK296IkoSWQQEREmuTguHvGA9/
GU8mTJzAuXlg4fPt0ETx5skJkUdzmami6iZ5HE9fM3ed+
+5SQ1NdA0lCSDOcbnUg77EMkZv5zE69hLOvCNfxDNidXVTlhsSuPHBpOn5yrIAkswVkGCGEwWqnBak0YQzG
oRxSYdS7pNKx4Oeit7PCn6auHf4xKCr2DF8oeGHcHJ1fQzz56DwuYRBB45w+6RAVmvQmMlrtOoAOhqW8W8F
yipC44pBqrTMy7TiV3vik5Npb/zD4pnoM2/UDm4AUwGwkel5j1A1tX56xwY73MQKqNp/
2oK7GbWJhuA6GDPCmILOGpszSJNERkGkaTd1XU191RGxZ7dWqoTs+rqYoEHatSMNa2bsyVRHb1AS6+8L6Je
kXTOn6nFsi2lRRyu6PhpeRnKYAZ/wnFzGg6+me/
HH8fbj6mOlsUnsKUqbo8nOGQIUIJTRrZ50tqNOTKNeuXQXHP6NpYHatjgxvoAigU/
UpNjYJEKq+o+M53Dj6OO1Cbp238HaWqaVAuMgnJ92cdzhEE6M3wMQogAg1mxY6ngn6xCMFlVeudoUOXBDq5
k6YqHiO2DkQZUoO2jlozAqBIhNOkC1+znLP6pklNXSAk526ABzSRxUw0mnYRc8IwJkfZTGSnHauQoIiFXSG
xbqHZ2jY9w45WMFL8IarpaOK6dh5GNCGUzh2HJwvpmEh0o3VUg/
qQpXNHUOmV3XqC3qAGWEVgTPVocBd7od8DN13Ck0AuTCybTKC4M7iQbjXQRo+SBXQzTMlu3VdgByFr2xBWJ
ZHL9qvSBpmAILR6GwCBfYPAksemHUJBKzuew6a8/
PR6vyft+ani2J5cTeEMeseMFGyLXFRYIBACN4nFqkZ98WTVa3FmmTdMLUAhMl2E0bp3AXCmtlEWeAZneviC
0WFVB45z5e+5/3bhMoUeVkKDQs7UBUzV4BdehuT5xTbvZ6GUo7iLCwQ6GonROUg9ZXa10gRmohG8CNqLO86
Gmn4tQCDpItS0bocT4oOP8R66BG1m6TJmyg7f1bBqcJjS5FVQ8grNEgYN1B9xmjwTDKcKSlKLULpIgppXtu
R/VHqfHlbLBJw9yHXNDoDTseLXJxERlWeZghsr2A47BhFrVv0
5Ysx79/QuU4BzLwOJBLl/B2z8xPNvS9tSQwp8tUzJlGrBHNcFgAI1mltGKaNdQPJuc0e7Tshc/hF/
6Lcj3xs4BF6Lc8dgECAx0yuyIhQe0iKk+uzE+wmrrk1DqkgcEeLBb026lTERkkEFOIco1oKsRHK63Tru1ZT
DAW+jj42w+siKqqliU2FpUFk7REb/b5xFPra5ymrGWQGk3H5F/pXAlrzJYG/
QSf1+8EsBiaOVBG8OMMQZEONYBFnCAATeoB9LKU+qjyaU9DgHbBehB7DnNt5n7Pvm4aZcJ03Cn5aoBPCWxN
S7uXFqW2mzIbWyY8SYQDkHaWo2VD7bpvD1/
vBCdg79sNvOKPPn3v+OjpZ4tnDhAVp+QUYo6t4I3y5ldWpyj1y/
EOXaHqrFIp6RrGdgehXp+Jbd25OkxFHNYKumTBy0DUtKOynilzr9bpy8ws9k5dJ+aL9V6ig4Ac1Aa+lnGrj
O6Scpo21KbEKJrkAxG7eSUCrCxQ5VfHjgTPbLHGY9ume5AFaCbjbw9vGH3xaMdha4ejdHC2+lJajJocH/
hFsfCwW/MZBl7uUPDd+8V/YW1ZDbD8Xgq4GYhaaxIfVfWjRsUaGaBxfLb5D3MX/
ry11FwwUw7QBGlu2oEDwfbtstsgNU9n5vK83zGmPFYIm2tEwcQIPAwqF8nehE1cjBlO8Un2XPFdlFGrG/
EORJ71gbzkIvgfKdJGWdj9ImJk06U6jWLX9V10IIAUPsKWmKCRaZIBmKPGp7qO/
yUNwqjWpunwUQIjJSFzHHYznHDUks2xvyyo5i9/iwDSprsHOCw6F8BMYxl/abO60Q/
POyC0SjNMYFoQpFU+XCESnibnYhN49lKl/
nku8EDG32vdkLJdIXEf6jpU2LDhXi1RAuabRENqcWjEJ8W1NWzYwWBDFCZ3BR8WlFLPcj0stvwk6BX/
SZpVbUepowBfBE8LffjtsPvHxd7kU4U1WSETq9SQmGT96mdP7OzfsKhX8w3qh0/
rBqxs5O8LOWZbi+ZvSnRIjjja2d30WBx0N0KsQXWc9lLweTjGMEGho8tZVLvEBwEc3G/
8s5Le6GkgliUoeHOCQlSd/sX/45Ah1iRRa3/
anJ0g+qYo0aKQCN1ILSkWXsklTdMn3yD2acBgVYWyYGUBeFtMl6ZsY7EFMOPHXMfB3nA2xeM+KTDMpoax0Z
LZhngfdMco8uBXKhzIgK2RkJNRyIac46dALZtYmTnd4E2HyJ85hRmmUO0W5OJTdby2Hl9oZTg72zBCUr7Yy
J7kQM/
5D+j1fvvWT9G+il6tUSZ2eIdt6Hhioe0LEEUgTNwygz8K9OcK71fr6jyMggkknh4KTrSDv5P9a9WS9tSuti
0G6BMNeFgGROzgTml0WpORN1C2zvUFuv23KQ8AYIYFjd/
XWTeAZUShP7Aaa70k1u96T8IuSjO77oTQmeDMJPTVAXuKuwWOAROrOUkFX37+CBW169b0lINCGAgbOBbmI5
rKXjHz/
eLkbqVOU6akDhW3bojgfj651u6AIlS92tsDLm2U4HOACGxkpC430f30IEwGjlJORElIyExtzfFGrpppRfKt
oLqE+HE1yCGH25SqLNEcvCbnInAo0IrZBi7kEmAS+Sb1b7JKWR1Y9RcGCFWdcoEhGhkHE0Olo1EQqLRkDgC
249tPuCy1oMukFcIscYKx9mt1DY0OFR6/ajFMJVKXBtsTMyRGCPoNU5iM2tzmxoVOwjFCHEK23TVD/
Pf6r9/Liwkbz5II/r/
1A2ikP416MN5zlKkgiD9KaX2Hn23vAPh2dfNX4sdUnsvpUKorr5S0jEIABb7rZ+8js0mZkeWahdzK5MHgnY
ZrOAiOOz4+8+xpA0SY0D25cpvJ7o6WAVSNHuS/
aR4mXN19bgBcJpko9aJ0WnjEanZvGFtaaf7gGfAwRr0KwL4mCenVkE/GTMBDc6yz5teJ4UDXjxQ4lp4T/
tz8tXq22gtExipeKb0ndTA8fTErum8aBjxcqzqxkxc/
NjaQ8Ou4ykzTm+jK56sTK50mE0NLwZ7pcyNkkYQRqbAjN+UjKxxpWnYsGUMo1TIIARE8GaLlPxCqt4erg0Q
JRLYd+AFTNO97bwbGplfVmAKkr8bZXFVkkb45Q41dgyi9RNQj3Wh/
VGFUEeZsCZgokRFpslqFxSdw2hditcGG5CAJC0DMxpo2hUXT40JKGagJENFekI8jnHSHLVnDO4AWMggUn0m
hUcKDaVIyX0drT9l7q9vN3cLSwBwsr87R/
jQwTJwA+4V+A576J2g73Ob333Ir42tNfM1CPUNCLLlCGZtqHnQwQFKIJYcJ4XgVMeuT7NkpLWt1XAbJSUFT
80ffKoQTx8qMBrCWi9tbGbVndPCeYBdi5687rQvhpC2N8IhBW07epwthLXCY90oLeInXKDDsyi50WsvZlUX
RrMQ9Ym+jYa3pCAjiqMruJodJ7h+nZUKD+mdwMslJxv/aENZn73RiUmH60h6/lt6V7Z/
O8+PwF6f82tTyIySgxpAeroGJj6qxSOkmE/4EJWEIGh6RPVrMYd/sRywIFMLrOAC0gES3/G8PxjM/
g4fxMLsKgJcWmdmEyNwElHND3CnRZbgGOgMScV8EXRlojjlzVcCWTkcJVDjZO6a07ypT08fA6D02HvqhVUJ
YHMEOi3dZH+q79l32KT7vNy/fMn5OApl0LMn/
Orx45aPzVVrkhkQoyCPGuPYDksybVriFzinrPYwtpkbGz3oTfnMHtg2YARB5KCFOyjC0ltlJ8oaDgNba5w1
MKqxOWntmDMvNU0zA2Cr0TDMZYTTIBfPsRTzrKMKBSZUQ095ChMHNoR4MF/
pN+GK8OriZ59qPRW2YuuCQxvfSAapNF8qerMHwWyITyQrmbr9GQgBRiHnAd5hh4t+T0poIligMZsFJevj1V
0K03JYeiO0QgXUwDnqh7Im1AY03TUaARqesdCPRsSM+FmHXIRqUK4s3+hYVlziOjIBKQ8CqI+UJQZTlwOPi
l4Kv+UjF4G+IcbX87qAKwQDkB7TvKeFY+9w/H6r3z7kj65fn1bcnhmPqXF6Ulfq4KVxkkdlS+ZomyvuS/
7SX+WVnZ6AV57NhihL7S0Bj8wI0qCWE/
K8ydwIKrrQWTQFL99NfcAO3J597ukNO3zfqhyYlI4+sCJuJXtR7ARt43kGv2WXf3na7k8PDC3Bq1TjaLa5X
QgwTcboZAWWypRdpehJrCa8cjbDc/J84hdNM3Y5qhB5EXLgoFggClZVbmpbef2692nUUpkeCOLY92N/
8l7IrUH73vLhLirnqQdyC6lPM81ivezCYfRd5iIjWZXstvsNYoAVm04bm5bCsOd7H4i/
j7ibUCMMHAdwTjvjlfC1FP8E58s8KPqJR1DTgxJhb6luXlJJ4Uf+h85uwPk1t73iGF6LUZUvLxXJV6aA9jY
JgMyP63rB7cfVQOocc+olQB5trFUrsdeeMKRHbE72Zba6ixYUR5Awg7JJsUiutxtGDi9EPZoJolRiqXhHri
kgq0zWYkwQ/+qqmFNndWwwsYFGoEMaNkptpY5HWNP72vZr8l9dwETHkwhDwoiKOKAKCtJY2whIsEaM/
YjHkAIITeVMrm1P9f9fcn7sd1NoTCWq6JzQT3QmT8C7ylBSjnppgWoS5AUw3qlKEaFpSx2sV85DKT9mGAID
UGHoc8Fmsx/4S95ukhjzye02QM0yTi3B87vKhRql1JUayR3SenQPvFW450I/GGO/2z/
37mUVTMXdsxrDadpP6jGvu/m57ZdfdnEHdLzYiVE6oA91eMFQ1xJIfsxUlh+3fn1vzSA/
lvwm+lKlDNyVba7wu4q/WkdNhF3QV51OG1UCg3SLjB0aPvsYjqU2euhDRJui3WKRlE8/
aEzcyB+yXbP0MMa4rKYmFXYqsBmpha1yPtGm+a4KTplCrlU5j3dio3lKNpCNOCGA427qdWSgF3FXcnWOnZk
HVFTEnHYx3FQzHB2MS+XoYcLKpG9fUqJtFd/zxt/
v8B4ISwtB9x8RUklLFYLFbAHtrs0kuqgsKxp5mGA0nx1cl/0Z+rH/
74HVAPTrVkHKpFZDM6csBKQ3knQebhfVxHLcsjC979JcSYsaY/
tvfqWUjA3DYMfMIeIc5IrhA89au+a4C34qxrkRocESwqQ+hQIpzJKUxPbwvTC55MQFVZiWooC3QT0I5WnLy
TSpoXqnphr7+++9373XBqmM7hWfJTtg/
VUrtVmqrI3rj9PjgX7DgZT6PUcbu+h3yCihJWLwBi4hqV0ZWTBKwDzwu6wCraBbQgcNVq4uQbKROs3TJBII
ibPlg4/9NEnaATFB909TvKlc0nKL25u+8upenAbobtuOngUUcBQq1ZrV0oMd7bV7gi0pbgzOZ+a0CGxZyiL
PksVZ90FYvTmNMqsMvraph9bN2eb06JFHNqPleNMmC4bkGvn9DDyu+vKESOGTuCOAQyXEJWLhpdVGZslSTb
mWVRP6NKV5zfe52df2X6K57HmvtyooJvuWogah0cAcDauwrXsDVbC2B2D3ebp98MenqsFm88ojtMmq0QlXw
mSYxrWKlquCj/yDs4oxNp4a8DBH8dMgwMQYYZSYjaSePuKYzGaTBKoxuQww1S5z/5srUw3AYX//zsnp/
mNPESkgBQPymgPp4padiAlFY34VvmORsnIdripBsYa1bFMoOHCOm7nVBHPGFpd2m5T1JhhbdrWFXFEXT4Mp
ITDyQmIaRLaXff8XYARy8m2ivWw0lUI9OifmAmlr7wRiWfc7py2PcDIoEgIw+L45rUZPrlVbz7dFFWkyojh
kMNUCyhQEjmR6zW2LVypw0FBIX8zODptZMlsyw6iPXHSR8Pmp428lrbDia6wa3k1VcYOoK5zQXDvIYhbMsV
DHp2MCcm2tV069ikhxms3+xSd6s26cPjaFNuxgQxd89J+MNYtEO6botlzRHDnLtbvk2ZzihwUbSzDWDMkbN
0l8ETx/
nE0yfvxZOr8+qNaB7qlBOwsG5+9JBERkKolT79iQ1IVu9yPOQkvWXsSpgjZloilVpnEcR7sfOvFIJ/
vqqayBYacHwkHqdZcORtWO313NqhavjJar/nfKtCiOGNM3jcM8W3/
nd27fGIOW1A7Ycy7bC1smThfRtoDUCoKThxL+AtvB77/89yXl0JaBshQVxs9WaT9TLlOurS16wTa6/1/
MpIFHyPSiLMu+hesXmXRk2u2VUFqwLbE6CX2ID/4xgWey9wVM2YgUX/
a6GXUAlIdE4Sz1YU5ZJvX9NzI1RyqKkZIi45jdFDeUchTsbVvcncQib9TTSNLu67hu4zdkzjh04Las3+OvC
oxf94KIr9ioiDdiMxVcU/ocMSrxEFFzy8sVsnF1SBT1oPXq2zacq70/aSNc7gzvINd6gD/2LJxf31/
FT02ca9jlAGdkjDRVXQtBAltCv57aEEsrOer+wq00wtLFnaoqFgQeSt6nS/
vzKwR9IZWhDmCTmUvFTbErQdo1Sql7t95LXBQ8j7lE4fIAcT3PJcoJUpT91RRN3UG6Rbrc1BBYEwuAVktX2
Fmeffx/
SNQVoNcSis8t441I2yEaArt8YkH8FZvY7WK+bZJHZjLGSYr+TnTmPu0w0PuaQTGaofH5GJsRQuIgbmZ/
AM8Tb5XIYVBnYpRZHWNcvAcgNuQjYBQKD8MaXTMRNglUiN3UIxZGD9v72CMAzCMNjqYWRmB5J173DPbn08j
bKkkNorpDPubRHkv+xQD4UsilR5SBrNHwKdEX+UdB9zvDmeZl7xjJ1rCj9nG3zmZiVWyxHnmkcXV6KurTUW
NYMtvh+P//SgPxR/
4mOeeoeqbKcqaycVmhbF8eyZ8biCAGwJZrwvsuakj1nE3TzDIAZNnNL2PkkitA2WDh0OzSQ9VQWAvcWSH93
zTrzIl25Vm30+UR9F5aqoSDHwgE4A5QAR8a5QEg9dqVEt4lAcO3L7sIpOyPnHQT8+ObcoBtHnZNnN9E9w2m
dq8XU0tFSuGdnH0ZLY4D8X7EYlhBmlIa0eBzhcx13m039KbDr7nZ9i1SOmWTWraL/
II8AUadMkSo1sPVCjtHkSq0mQcVJ92hHlaWFpcll+xBRNmkvXZVZdaea375yjOSyUpO4ngjUuyJVZaxjA8F
BF+Swpo2oT8lcTqAwedaW8Sh0VZkTzUaiHLbrdHIocIOVLNhj71DTes3NlW/rkq+iv/76ytObv9dPASC/
FRluMTQsrHjQFf7aI5E1JtxWPBkW6Ko20JVKYVIA9WMqu4G35cKPYzuBHTV9wGnvIRMBC/c/
ERxJJJIHLKSCPwREIFQB/
UUoAO2zuwarmA7Ua4EQRGBoF3iJ3S4249xypcRmlA39TQSvcFgC+0njy0G9yKSrZbSBz3N3GRIQ44WRXd2s
4fRaMcvH0Xp3pvHsqUaA6djNBpSiGKN77iOMU3H3FhhdXOmabHovXSgfbVCSOJKZs9KVkfk+1kKUMzFBLtS
62taDQlsBHk+jj+YuR4x94OzZ9OPeOf9EpzVRN52P+waPvAjb1ZNrkwCzZ5mcswhB6v241bY8VphT1jvXvQ
rkPowZfHVjZom28X35d1OU/xS90ZLcznO53TT4BNxuTLncDNd059f6v//
nPrAP6ji2+DHpkpHlcn1zUqVMl6J7LvrtoHMbhfhzesHa43Jij4fyGkPKKlerpJI75HqKwJXe2369N/
RNyakOQnhw6o3EXIAuymJgKPUuenaKRS6MFhR6lgGlSEFESYgdQdmCzzHJ5FxfOfTgCyAJhiTw/
A5c39SBJhiu7HtxhdQfPeB/
tQGSavVO5OnXvTA6pNmKSHGRNGZ0+y5oJMfWj4QoiHBSpOWZA3uG+Uz5Bcbi/
nWL8U2FBujTu3CCFbU1bESoV4BnPz4fBUzHFYaIhaEmrBt1e+MJ67o/
Z7tOneZ9jDScMby1vDH1P7B8b19WF8SQNxk099ee+aSitt2gIyQHWowNE115J3HM92CNVkTCca2VsxDtgeU
C55eZOKlRVVq5oxmpc5OnLkjQK4VeQlOfHD144O//+b/s+XhOqdGZfTt/cPXUUp5xH2t8pDt/
97TaTBXKI4EpFCWEAJWUl3PD+sR3LVlXkzLGr//
P9l5fo18tBQzgHVcbCKzSWt+NP5yk8TMM3zBWgTJViAoA5FA9yYqCO58KjQJiJYhc5eqmK830h/
C0vazv0KGe+Hcd5/
cPzMBi611M06DFga9w8W9zamexlQ7NH0yqpfhHi0lYAtl+2vxkLS2F34yuNDN9GvRttVYB6MKLIFKR7fdRU
RWSPFo4+K3eruQ86XQdt5FYhvmS9GSta8Z7AZurA/AEw/v6b7LuXkj90QdqSaVGB/
OPRp4U7i0Uz0AwuF4alXHFnUmiY4xqHeL+1B9uKojtHYULJxuBIgQ1SVdltJcbnAXeybOU1NtOerUr2n9hL
yQR4rguP0u2c/52Z+Z64O/
q6KHM9G+vXU5LryM7zSc8+xHxHsYu9afh2DqsuwBD693A0WOhAIFnTVFd6UMKmS3UDXd9NZ6rdi+dJNJSzM
uYTwwgxxMhkRFc7XzwLjKF15PlgeiGTc5KKyJp8GoHCyuidN1QULsBKg9cMf3faQnO+cQFsphHoNLvU/
bWkOG++gf9C+MR3HN7vNur7+6A9zVfKc/
Q+cMrqPWlQRG7GDNb6rAjH12S6EFo90SYgMWcLiN68Pjk9jEGtHpiSxbLfkubdPcwkWgoZgN3b9yS1odeYH
XKT/kadII+jjEx1U8d+NxWHS3Nt40jgbaPJF/
ZZJV5+iVnoNe9Uhh6HP3IdsAMDdcwBzR9uFpguarrnmuLrc6IMQKW5Yal8KodXFfOawcK/
W9heKcghwih+0HLv6pF4w8XBWimJrPLMYv/
SdalqTx5l0DQCm4crI8HdgYAabZBsAyWHGBNNvdoLYxckaadMdE3YGBMSEPuamjiM3wRvzpf3N5uNVu0p+g
2bdYzT0g1V+ZTlQgVgoZwd3PgAVoDVdH17pGSIY5fGXT4pZIAR+9ESW+xXwTa51ppbJEy5lCFbHDXeziJM1
r6jAkM5iEIr8YgevYV5e1KzwrtA3Wo5YsK3m00N50Y61W1wq5ArZd/
E3mrQNVxAr1rtIeyEOQXMgfUrIkhBSqfjcyDd75FW8lcAggPZz5RIYxJXEYSVHiWg9JVmvEerUtbK2YT2t9
f/
VeKfMsQeESK1p1oSveg1s+RClf6BFTLOJxxCuXsjPAQ7UGRn7QNb0MvegHLzLfRHlIcM3abMqgrbJNbdymG
a8jWXD81i1mKnS8jhshg7xhF5AQbtFugd0qCvEaCQ49gTqXSlggBjMedshoOvgDdJEO+b/XebJAd/
QWq+QVCPqAUzphIf6I7ngGNnB7+k/9VRJnKg0ZHnc2yI2C3W70BWHATuqYmIYy/
IKhV7JGNABszIPRZQRpPOzYs2fHy+L1sijmO5arplEo+j6uXYJq0bGINcEtj60FyLukGyqmLCaITb6FSUCx
8GRv5IziijhYsdVI2ljSyckw84q1rE7tHtnITjiaiit/
JAwKzIZGNBbM3lJyYwuYoorHFyrdlWyKLDBv6JqiidOjjmHMCk7uevLV2mznnJc+WO/
6wb5+noesMzjs1/0iCujEtXtU5ozkmjQaou3B419PGgYyt1EQAZAHggcADsqYgZPGJm+oJLTBxowJNgUzML
A/sVMpP7fF8/KeE5D6bRVJ0nXsbtV59pZfYFa7uhu7D7/
B8zI2W4JmH6NgDbYYjADD1XFzTqza3GUvw1Nb1ff6rtE9n8nB6zFujMlEjVPOkd047KLj3eTz99ZILcGT8S
WLieVsYmj0rJYvk0+3S+B7jNG99azRjlYDmV57mNFcQxyZ6CYsCFeNw8QsxY1o1HOWasSS/
8ZodE2TXXWqrGxh1oBmNz7AcNoe/GigagyjS+4zJbzPP8+O/
pXflQ7W5elhgKU9MuzuUwtXKAwxgDWy5ymaulY/OPvXw3rCx65Dd9dATni/9jRWYONNt5CbZuu13/
uzbR8V80KxZwgS1i6QxPuR5xyMY5tt0+1ZZJBDkMx6JVu8AkmeLY3hv+j91so6QHMk6TgJSCJQyt70LEzV8
2S/
5EO5MuCORGxliSsnrAKGihdWzzGVXYiz398llArBhtFfezRBiYMXidTHpwQt4KCCHAhqWoxg2ajepiNAwiT
eTGQB1RSd1hRI2MADazYubUShenoZF7Z02kGeCDmtiVeMFMVLuuIRM+SRcUA7F/
9sUMiaVWD+xIP4aChrGKpUH1pmgDQ6sihjZSoWlUcn2lEh7qYUF0WktG8Os/CAqqX/8KXMwy6Ox5uo/
KiZw5srPWlywk+iySGR3j1RRtvh/M/MmcHE/
QBE8pT81AEbC4CBZeY6WZ+CGGNOExuTaBM5yID4HGpb5LHJ+8uNnQROye4p0dFXUt4DN/2Y/tt5C/
gTXsnnucywhWbbV0my9wCWSkZ21MwSxemVxgU2OBM00VkHQRR49tZEo1MzIagORJmjTajgw2y8NHcIm8PDO
DgozWecoF+DnsWuCGMQFhnlWoyOSCQpmiI0YoGnmZm34RiUwqrsrLJkMsYBp4pnB2p8sqtwIhOT6Yu9KJh8
QNqedNFpaqZKvSVw+selx4GHrAs6stHa/g44coLqGagKCC/
aAo6mQymqI9g9tKAOb8DswKiYUEOZnx0QWpo4JZJf89r/
UzVvmIpIxaYnLUSxpbCxBkiN0gUABKCUpFvqZkBVgIKYxMe1ZAGyhFFYVNqn//
lAdtNWW6m8f0sL5ZnHXfbjkw0lX/LtRB4oiLffQdeE/wy4S3vwh9E0VxAfDdMgtuNhpK7a/
4d95YWP4yFurBqKMPDWUkKRu8coXhpRc1TMsdvnw7ZE973TKPyYfZf7QkYHqn/
Dmenqze7ADVYPpsJ7F9eUEuPtZWz27gyOOq5A8m0UneYcyZNu53xSA8A4jjZxyu0fxnM6fYHPAauXoDfn33
d+q6CaZKMxMrjiBZIAaQSkgkUFTcXd8TPOjR3/p2K+b853ZfKhjgH54vYgYDHJb
W1HtiP9URmGW4auo+qs5alPPWO2cHUOLHrAJY1CdrXNVwgCqtEfNlQtsKu9Pr+tKkgVvIUMzBP6pWv20AzO
xMHsTEEusKsgOB6mY7VS2VuX47d8CNlHhX32XmkvWCF+GAUUvDapHtJIUIn+cWEjtgjziORKSe8ZNhqhID6
/uxz4D1rEIlQ986ZfejRKeKE8pmPCD/2N/
NuO1KepwWN1ctTPOdvzOPfHG6y53cVjh9CcKCxe15jv5rctynT6w49+c/TLFzIvpeT6kbv0A+/
uaKEKoQhdmmlGVd8toV/zGzROf8wnqrADXV6qoAf7IAaRp+1NvaqLNDv/
kXtRtYMR8y0rNRCj6lUpXgMEyCrIG6ZqGFdxNz9boAMQ4qBYBQw08Y/
+glADeWbdWG2Bt5evYoap5Qg3bssv7z1zRVsyW7isXaF6FHDmIVwIhGDHOZYCcBrWkBMzyI8pXgjyAvWKU6
tuPBvZpXmCtPXuxzGOoyAMhEfhvTu5YBTknnQXOCX7NtvbYEfY5IODIVfQXhl0ymbilKfZ3nrpCB9qoebKe
lSH5USsrg4gUDrGgxiMjtjpR321hukEuC2HL1CFuTlzPW/
39FQoziI4X4HSvnN3do1UfVN8sr8Twwxxvocy0tlBYeaz17YiluT3H7zcq2ngoL/
6sOctGcGGeV2gW6f14H2Ya2dt4MuedWoW7lrwZ3w5MmcctvL1vme+YJx2qg29iodyBKfIjCS4aaSRrivm/
l/idJ4l4vO35UTZuH2zIYTriS7ODFiypXTk//QceWuEUsv5HU9gf9bjVGaLVF/
B14RU6Byo1chBNpC7Zi0dK1ZG6t3rd3Uu6m2fLuKn08EpKgyFXyLCywC86YAM1NfcT4XksBp680Wid9y2OT
TkjXYKUgmz8JYtq7UX+8WOSaCqil0TJlZYzEgk3oHMSjB6I+DZrhQdrtdp12REHX/
UDqW6jIupfQxwgIZb1i52RjrveP0LukqcqqFL4x+Gejv0MKzSBMCm/
iHlqx9+WdY9FNJR9RoU+N3WPYjx4GB+t3OHJFiS8l0c7nxMRyaRu08PTzQXtKqqXDXm+ZEal3OuJ7Hm5Cqf
EQpZAFxgHXj3P5P29HkqEMWLi0Gp/
o6rBFLFG1yS154SB6d3FO2ZS8itoFXsDK4La5fGKsBFELFmCpIlrAPWc/
Y53MFcNhSwKOm1KegMiN29PhMF8TzggUEgz4QIZ3svxQRbf4gjz0mHbJUUU3lve0Pxk+aUB4m5i6WqMFnQb
OOgAhS2ZMzH/
LHAENBgJWouwAaeehH+DqaBK4oc+rCWjkoVTI6g82FsZ+qxb+v6GDcQXwU2kF773lIgXVcCw0fxAdv2Zphk
EOn3qgIPfJgu7rMZ+g+E48U8RGX1FDCyaUJHSy1htxwShFLzZuz2WfWWNE13cXnjeb4PWi1d3a1CzzsKTzn
FDA6HzQkpAigFK7K14IeeBRhBApGvSGN5gQNDQB5dguJ245JLkah3OWf0M2YfGQykTQ847UO1MQYf05bgbC
w+dlC8X/IfNjoPzLmCBRhFkYe/
pAA2hXQWlb+kevdDwCLN7oFceAbAegdF4JTsf8DsqCb5iTuvH3Ipbl+A98E6oEUoqBWHisUYXGbf6v//
XU8C2D462RS9CDzOMjHCs7fkSA+TV3df8kbKPuUyX1ObUtJkeQk/
ldrT0R+mj8KeVf6I5SQ2p5mqJpA2A7sdWTCnGvzf//UdA+Z4zL9lVbXRYhrRS9PFhh/
46WxI0FXjBU7K8Y44oU5FTfIyg8mnebBJFw/n/
1jP2r6DExAZtXSKmCORopo7fyRTn3HUfvoMoPCqNoy9rDqmN83clqJQMvCWpBT7/
I6E4UzY+ZrB2pP9OoOuhygeQZ53MkeOyFy0CA8baEFLvxZwHCz9bf8HhJaA6mQ23gf2rFh/
sP5ucS1ei30hA5rhXvmleCkdtq2S5WGpi2IWD34eb3SsYBtUFs0qHo2Roxqe7HND830M5Ko7P8K85LyUMCK
AOUn2uDGbhM28iIUU+HB4frq5+USCWgb3HHcgs/ZfWe4nRza5IVodL6RstFTzQRBgE07/
aCSgmQYNZmvrn7zs4M/VGgmCFIGSp9C43GmwC80E+z5Nc5yT9nMdsH4f/
sQIJhwFo3yInumwjww2DMRHUc5o5YIbniJrTF8I0SeoSuU+iD/
tUkGMr+QWQoiYSI5InD9ETorNMF0kR4ceJ6Hi2I5w6INwDTkI98bJZgHV+M9PowXcpe3pk/
8vanYJEArHPD7ZGMfoPtALhCExnRfPOoU50+Lvtfcrn82La3zLpxI6MBojIxMNqNlSikE8FA9Qx2WA0Riyl
NXFs4p4IsSzwLSaJWfyF7nvW843vPdEKAQywCzgOqMD09QcxttliUq7+u0WC3j+Ia3/
RtJBqMJARFazo6Bd32dYQgTGyhOYdDSeI/
UeHChbAGQxO61OK2XVWaHfQOBUbnNm6of0GA+5pgtvM5NutzTEtgnYp+QwhGzwGqb2GyNNqThWZlvzGWx7y
IkNaw2u299m6d6BPvgjxzyq9AkHpUZW937yfVX8jJrKg2wNyYeRHi6ced5h466uNV+7xoLkWrGC9TiWQxJS
0njnuMe8quDfXtZ+fodffxlAn5lNdUL7GFSk+iIvmf/qRdttbgNeEQz+/9gZWKDNc+6KPsz0D6+
+r34JTksBBJFjeRr6DoKeuY6DD46yjkDxFO1SYHCY5yQmYBJ4RKs4jSXZgW/
I126dobnhA+zfPawd3mAXB5smhe3F4aYmDguspvymTRtMiAwGrp//
+W1opIMaaBQCsbjag2VJz1slO37uZBAmUXRuBxMGbJi9G672HRwHHGccbnVjRB+YQESQvLp97xqccR2le/
odt+cV4VtYlGT+dzJHndBQOyxfW2E4INQBYhITbT3et/0p/
ODlb+NK1VuDn3GRgoJYzIMEsM5JkCVhQA+OQfkGOZ0s4vGdZj5QI5dE8HJCHKTkOJUvYT5v+TDRg4TL6eoW
41TzSXAb50HhL/8gaw2g7kk/
+ahOwBVx0+Ax0EeNPgJqE9TUsQju2J6M7J8DP1vBD3cfvnF68U8OwGIwJ5GyIrbB4KdvOCo16M9p3jhr6lZ
5gtVEJ4gJInKG0ARJLMme44eCW77PW7/
ri+v1WIP4+4u6hEu4CTIa4dQVeQ4BFctSL8JCkzvJFEiwKVoCbRMj5fXan/
+9fo8WO94HGJZHpzV16ZHx0N4Id+QpywBykbE8iS50PSA0uHgpJ7BL0ZVfwKOPV4EgvJRyWhZlRd9flXdnO
byXFE6CJe60wenp38LvG+0MoeMBJaYFFQzW4EeZYolLHvKlTWJYPvRYqmsF+lsFNETVJT/
9iSuoIUWp1l4RpYQeg0LtjCtB8QZRViJFd+OrTIW9zavtbuMEOGiQo5U3l4LxYrI55/
Qc1wPly4P38EfwwG0Jd1uG5kDbjs8D3hY3QK/gP4J/
T9Xo6N4j3u4x5+jWOvjRQr2qUmN3SrgD8VYhSCchiVTjxpFlH89ejYOj9eLefJ/
O96reSwiq4RxIrGuAsyzM5f7/
BrhHIwEMC2hVPDeR6Zk6Gh0iBw0Dve1sGaab7uleQsqwaIlVLcfS+nyDQajjmOzUgggRSoWpmBhigzFoxTz
ZV76UNvwZ9kKIxRrtkriknz2jjfJZ0Jt+qTUvs2MbMrUaRsMSrUlUS5uz0za0pD7i1UnZp7+c5Bvn0O1bJR
jSdBbCZhhYvz6l1CP33YDsB54eVuwFkiyDZgw1GxX7jYCv978hnIezlYc1ocEofweXvIXfdRVwTTwTd/
jqeBroJG6c1c1F5rKmfxpS61qvQv/
WVZRTplukJ3iEVO85QRhgE0dzM4GRhkM2Cd8kwjHvKLgdMG0nhA753XAPTRu4EjzXj9UivXhXOBjHL1w0zt
UOrl3nOQBKAuwkaSelUGQ1EvB+rptxKEleah9vQ66fqh0SM9GfRBr2MVPVGuKJD3zb1iGYdmn726RpwnqNt
eaQ0Yf8HLIv0Mm2aPOHPqqnXFdImUcAwMrghjV7EqeoEWS91E5Z1/
C64anHju7AwGodwaXiUaxit4i2RHLOE1QDkjASK6ac2UpOo+ZRuzccsInDJARp0HViPFOPog1G0A3TCTi/
kIl/DyGHmM+oTUiCDJpgHq8BnvpXxM2Abj0gsiYWR0k7CdsnYHDJaGYR8zjRGKVYR4DBnfU0tFArJZ8YV/
nqwTf7/
W9feRnfQAwmP5hoBArwRA3qblYAKpA+wEhTAbWtpQVQPZ21wyNXnn3chAFZ7Z9KmmCS0SUj+Ng3XSTAsOEa
t8HQ4lFZkHGLL7Rd2mJ+2zJfP2xToecn4bKM0TZXU3cwAFWLCsJNjPg1qK86oqOfiDFuJNOCH/
4y0vW5IM63Dr+cIIQ7X2PP7gABYIHE3hmGOouf3nky2iMbb5CxGzr2r9xrQnZ0qhORzneYO/
vEDvyowbkvycjaq+kpPME4r0GJPPWPhA/DfPMjgRnCWj1lGqK3OgNevY6SLGYgG54hxsb4Q/AxI/
T44LB0bD5qELbewDG+cK9cDVoDtB4+tJJvaM/
Rmx0XDYgBA3VTSfW0wVKvZDQMlNh+XnhBN23Hl93ppjutUUePJ2VukZAHXbv5A371Uusg3agHtXgWD0wyj6
y985Otb2Lb+6x8+wSuxail+kZXVjDdui1ihRaYnFUSu97nlxVL3cm6Jvth3/
vbCoC6Y0krAUXBJyzsb9m2O7AWa130UBqdi4foGu1bIldio2B0FWUz0vavNGx6pS50guvnodOCX6cBOAXAE
cnozgVJvIYUpkv/hE/tVZrgH93RVbGWeG8KuAZKzaZ3oI4cwEDUf/N3oNQE3jJPa5zMA7aQMz/
o97A3vKIDHg2tEJrdwpt/
hi4LQivk8yoE4I2pIM3UtIZK1zQOSm30Iy6+6keuhFsVTtVXBRQzkhL9Vh+9OBaqNjHEiCizJeR9dOYGnUn
3+dUcfnpa11P6GelXr/45DKSbu5laGQ6RMesY5gAU+ugIPo0saT+I+3QWuF/
VYbXv+50lC4u+lT6vgd46JQ3lnjweuAIWRq1NhWrnDztm/XiagW5T70n9/Y0nMWNoq1sbneHX6e84/
JcUkuRC2HAFnlgwy/
rR5McOL46p2BqCASlgQkizVmQZQPWCEX6CRxNbllr3R6BXjkFaY2rdPjke4ICHZwb1+fdXzVaLC5NTfWwlZ
IsK9KqAElhYQa4cXAIQuSB8e7jz9ONQC1VGm7Q8an1lbIQ91DJjrd57DDUlMp15keak+27erW/
RLldW3176Xjzkn6CvTpl6zpFwC+EcUm8OgGu9qHKyoswEiGnf2yd8i3q/
NuwOOF8H1l8qtZZX79qS4EUK0tlCI11NaQAnoLFG4V3tuH8vxUDY7TNgm97o/
57M336Mt3GDKEslsbBOfcfhv0RisN5G/
pS8b7h0KOmIw6GzMSxkZ3re2tLrG9FXQgRaqEKxdJXLKNGQYwo5ArmJ9zLUUbjGEVHw8iQwsEPlEAkGVxKQ
stC9LcPQJsFgzkSZ4Bp/1e5tdjMohmM1FULZWyMOObLUvyvqFesxG/gWpiw3a9pCi8TQvPY9L7AKL1/
D0JOHSkWcsPNs7JF9pp9n9vvlFa28b36a973vN7yAzxhg7iJSkoiG7xLKwxxok6wD0ECEDks7DvzujfxzWy
4qtsTBdd3Bf/
cIVjIj2NxU6CMXbqT9k0ZtRYzwXQoUrelGmk0nGh8JWezP4V4UAhODPsxwrfqnIBjaquwcv//
GBUM+x+ngFzHKKWfxi+4or3+6uXHcQd3RlZQH94UykiK0odv0vmvHJjfRJw8gIOsQFEP607MWGbsRF7aIQ+
J8aS0v0qEByxlocJAmt5CrQlk715o7qIWbCAdB4kI68Gqv/+yUq5EReYBRlMkw7cJ0re6d4Wq/
3NU61XS6Km78rnoC5/BzzHahDJWeF6WHYNHlv/
jj75VXS3XKnShTTckeSxwQnE6mMp7nCreczTjJeIAy3dMT5n8P/
w+n08X5fxsBhUOtrmWhmOTQnCF5UlVPd9hozI2zJVBw87QprRgNxXZxwjmpjirTiGn4NBPXqh+zHGVYAo82
0Ct67GpyFM/
DTj7i0dEe4eGFXk99auxepJAeIqPPTBn+wYwjfDRgnv58gRxalmAbD8Lw4cGUupHVMcsDiNa44IHUz3mCyR
K69Qkmhk2NWAEHQYr9xywbdw+fXHGovgmZpWM+xMOlhBHIDpfNPFWiTz56c4KSCY1HwBrJWjittNNuXJbLc
S6zrUqr7vv4WrnA6qjE5biHHjF1qs0smWCY7AMNWMK4NRnQlDz1JFVVnZ4LC726R1623EVbWDmW4pa/
Y9hkftb7GsDgnXcUALySJVlSyki3pGkGCGyDm9S5RtQZE0WGMdNgUILBvuzByc/9F+/
sjgI2purpAS4sNRlqT4tCJNa7uOeLOdr1xJ32ptsCu4n9f+HVN+hunCFcluKIOJV6hnq6a998fQpCuBqPnj
2BPhylU43uSnwxKx75+wy2Iekcimt05SdhYNaASgJskJo8Bn7PHhw4Ha07bQo09UPfzGYQBcEi7sHKVEbDH
JJf3SGtpYS1RIKDD9eP7j3P23gpNhzkWkGsukRQ6J+AIYCHs0FHHEqzgSb9pmN7gppuxovzzy4oHoUj7m9u
4j00Q8/
rfu+mv9jwXMP6HREGqI3njwz6U+noQBx2M+WTqDH1f7eZFgxnrkHkmbqc7+B5NfNT6tHfhqZzkKRlnUieFS
4YritAKTl2RxgjrKUNWZ7VC1Ilc+XuMCb+eeZd8fGJroEpGevicFeyFpWF9XhdJVWbGOmk1Ghe8iWfn3/41
LtJlCMEGMAGu7hwhOFOfi4XCen4WuaGGQ5BG9b178lT7qsGqIq5lVempxzkknmc7EGqBkEIvOEHPRxsXlwY
UfWUKDxhroKErhONEQcr65KQ5U/
YKsutpYPfforVaHrGxdUeHvuHmVwCloC5cvUDbyDKV7i+NZv44e3mDOs2Xja0M56F04m0KeYjqQ0giOTLTO
uZsM4WWAzmJNg2aGuDrvT4V5ZDCFMLAUxfEQNKUzTvvB2NRCDGaA3ZLEPXcCWZ9n2/
ZsH10Xd6vvvYKp6polV8ssTaUMsxE1NPfdi7aJdC9dW24vdcOLxH15EWmdG755SwHML8MYBI6lHdxU0a/
7NTAmUVV03HxDY/
cPpmcauAcBE40K1SaeViP1mOFBvGN+EbcfTWzcV4Yg0X5uel1bjEtXJhHpQhwTZ1nCE2aqd8KprH/
kfdMx2sT6m6oMou0D3t3LaEXYbP3Hah8otOhkOJhXtMabqe2Jp4M8gwXJ6es1W5UzYdzhibDJzgRjOY+IKd
bKVVsGmGYvqtL5YGgbNRv7kttPQUhDoi41bHzt3cBnHPLDVSjTt2RWTGru63+DzyuYndLnQ7T5fIl0OSBZb
FFK9WW9ESBtd0tUnY2DqVsfxnVOm1v4xpKVfMyS6lFkn2w8gSYzOZWVVVcGPjTfkQaTP42VPESi0Ppx6SdT
r7KB0f2M7EpwPGGt3jTa4v8HW1DWbLkqBZpczRCkhOUFPiFZT3GGcsHb3viT706uMiq5WC1lEgK4gMfe7qM
U4CfLE30qHhGQzQUnExXI7X7v1dAzwOYxfn0wniOjRfhsosq9RyVW79t6Cpz3tCU2jh04L6LoB5MZvwnTQ3
19hkM/b5uEbqSBpZp/
J29Lv+P29uP+ZeqDlERcfz2TkAikeJ0BSBhzciN3WLTcWJpb7klE1kcaPfzFWttbvqSh+kqivRAsp16pxjw
nQx0JWZeUvK4jnJfCM//u9HemG9XK/W1gGxBvaArz7MYu3TU/
nOjHpJXVINjsISPSBmVAAObva639xTZOMT37VSuVAPwofkxkZA/o81qb9N/UnRzCvGI/
U6kmdLxlN8DNCYfejVtdf8218gjBSthBLLT5jh91h0JMBo7I2OY6EZgaCLIdnImCce0Pbt3dPD2+du7Zhbt
FJRjoTwgIfT5YnbuFrSFoXSvDR0CpMUvG0IJlJCJjDPFZKMVeV02KqwdOXw6pdGcb3YfSObR+pBVlPjcpZA
p1gx8UiO+PoeecPL67fq68Ykc/+eqG97236/
Q3fPpYDJtwuwvyp0vNa3WH+D46ndvJpOa5NsLDUKOFkiCr4DST09wK4xsLQ8lqPSt/
53AImS1x314Ovk3j3d6Z5rpSbidRRR136vfixxL7O90l3xuwi2XXQmCkTVTQeAbEe0gno5fuP3f/
FvuDR+jA6ZDe+D73+f7Z+rJjuMpdlt2GYeDPT0GGl28p60v9JSeQTvFZoOK4JuXx32vvfRQwSUU7kWp9MvT
Mv6EWGQGlnmy7gE9uispLq463d9bNQ99o29rdTgZOTMXywtt7sOqVTBQaDhHBrYim94Yx1Zm/kZkBFnYs/
1vfxAuoJdVqMv2t2B6rr3Ts207/mHCjZyZ0OJqwWUoBK2BMORgY4RcQNrtKd3c8dLiy/
R018JcP12jo21MgfxFTKvI9k0Xb7pR7BWD3XNx/
ilF0qaqt0Ae0QfqmASNU9/0/26GARrsK1TB+4HPMwd8z2cAZdHFY1pOgfx3pn9tp+IUZOR2LJIUZXRu6fE4
sXeUsPXhxFqXoYAUWuJClEPP0Rp1hUEqYO4DTK51bO2KCdZbUeqXwpawpBnDBI9iuLiRSlCy9SJRjO6tuMG
h699RGckiyMdKEqjs5Q3cvH+
+R94LeMQIF+PNVjRobQIVOupGSNPuYYBiYGHMAEMtUEGxF33ncMDTiEZgGGfeRyaNl3sW/v+7AnUtY/
LAiNoQlTTA2sqFESX6nCtvR28e7d4WiBgo7IDUVs8mTkwqR/
eoV6O2bd+hsvkcXVXmFXmf9wEAe7vpLJMTSMELSp1np3hSJ6VN1FhJLa5Hpm2EwFF5AauxmiOSqJUzD/
9a/zE5+G3N602xdQzR1Z0nFhfj6q/
R+HTta0lDNRnmGFU1z7dcpAZnmpt+M9Q0LtSae9VrsePcAqYJRVsMQ/
aSiczWXgQJr1vG3rlY8A4R9hj5pgmk0DAG4XKF3oKNdfK7SU21GO/BXRjOTTGWp2/iK/j/
2JfVqvsRcvIAboMC6GFUoQqAjMs3mBdFYdNEMGNxF68gluD2W8lv3+giNxDvafZBJdLFQB94cYPgPecBWjw
uU9wvi9Uqt1KFVIldVUKI9SUVoGYpO/k6nWADTwrIl+g4Q6FmxF5VbztH97ffRa2A0HT/
p5MamEMFoBU2zIlnaFlCCG2vuZqVGMRUvfDvajGY9IlA3mN4u9OMNbrtOBTfqSrBzluYgVYRFyR6o9nmXF4
bDhoz1XTKK4sIgdbdffUyz1zeYq752Qq9TtfIrOemOlbf00d5PidBR6y7TV2Hlin/
kJZAUZh8FKgZuo+boYqWQ7soNg79plZmlQrUl86kJT3ZgK95ZLZz31TD/
he4Vjj+NWJ99Vf86VyjcOhHipjxRtNQ5t5WEs2GZYxFZCXdSoikJiENNzJeLuBNd2D+WI1Orvu0cnpBYwei
8lOpQLKTnDY20IW1AVLa0fCsGZBolxaGv/2cCQmbMWO9jbCH/
r16JfoBc9ANVjHYjCGQjqZzgDSsDWRMM1PmIIhFd0KIvB3HS4W/gNcGB4S/fKXaDaxSn7dWPH+GVwtCBX/
nzey3FBVuwnWlXe8J+YsEkxR8bpCWXgI3DqBmCV/
fOx2UvxBPO2CHcelUw0G+0IPYK8HyJU6m3LiJI42Iec7OUlEn2pGFlmrgx2UwHC6sK9yFMkBZCAmYkY2D/
HzEZFk/s/1c/0FCn0nyyyxiEWPe6UMfWZ76DIQ8AlehIb/cG+bTvtrcIu8/YXrpfBh/
4RWDUJCbLAe0IhaSGBGB0ALOxzmZBqZjTiJpgnyypADL22i4IueUVwF91ofaJyNuyu4ZKFfd5rTlNhXlAJY
rQtG8n94TYbOkACJG+cpTOdCaKVMpPJCn/eVKzymlL2vl7je/8DUXT566AC6L+yHEjw/
kWtDTkiGsafKVRaRa5YNqjhXVjF2ZzTE
ACeBPLoRiQNYQecTcV99LyzYDD1Ahh928yQ8SQUTAo4IClyTmuwgQMEArhDaDNGVOAZHr2ypYbSJdXU0NDE
c5igOKKS6IvOci1ztoAr5tAE2CNYFLLiS7LceYFRedoL7HU5pkHNmHyo5/XVJlz2l/
0ncRnYtsmORjSNXlzjl02GmBl70X4w83gQeIEHU6aFwbuKCuWMJnS8FAffAh1bkD37bwPyCuD+ZgltxO0na
tCjmhSYZLfZgI5nYCbkOpdPUvj8nYzot4RUJsgtMr1Tb8lICMsmQ3LSv+HPHG/7SwnbgxdG4aYw0e/
QTnWRaiqMUOjKLft2xdtOuk16qLlnOEXIqWdBaLZbPSVm28gpzJ5SzBpxhoHlNdGbdJFTSJCRJj+c3gUeCx
WLozuFY0iu50pD7X59i55u/
RwNvDRcany8vGfg0907AAQh623GjhT+XfVs3n5+2hJMYe24tKAnrlg6mOPExeM2ez4UJIhnSLmmuvmvSdEJ
aOOETkFz75So1PMy5Pb8nO+9GRz+CrhiPbkrBvC/EUhhthHTo65K+Tm/
ia7ZFaufF8byQ7b4kUq9jXx5tKy5ykVWKGVCZYBmyZ1zDb0QJWVpsTbHKaDwUHJasL7ip9HVj58x2Suwfsf
uPchg1qCpNDVADWu9AOpW3o7mXzOun+E7pTttmNMQLylosVXkJqZ/
b7nXhiBhKdfp8U6MtslGkQywuyyVWfIhHhl2MIBIB4f5XkRFeR4LxmZrdAeiaTnTprhv+THpZc6J2V+aIcp
dXpd2roDBYBgKGJk6W4a5HYrwptPN3lY79ipPObsTciMmOclETs+/I2dOV/N7Or/FDnCxt+
+ouQ0khL+Wmy0XZK2Mpdyc4oj5dQCFidt4FR2FGv/
XZ1cP4lMyR2YYoqCqpqILMnnjZ1WgQohEspmmCPZ3BujlK67BWdJpacZc0Xbkyc5tdLhIUmk1EF5BVULJQH
QXDVs2eZmFtnpK6waa3gSv8TX6EZxR19tmv5A+WYfaaqYtca4zcLgiFMkpN4AMnoNRz5U23bqiTipSlthym
H/3Zs9DVWxU5w1/
Z12D1cTkrD1Vbt0G5kX54xSoCQkq9ftOuBMHag0fZhV71wubRDoayv5pkxeiNLp2M4rg6OasluKzRFD0YVh
laDQ9CWBeEJ+3GyHXdZekJ1/icD/
5nKWKKPeMO30vKNpK3ZpXAyPPYmlzRos3OfsYmo5vMUBwuEumprUev3x53jxSyyWYItjX8nXySLCSVjKXWH
GINBV7on7qdtQHbPWR8lmBP92BjZwu2Srm3F6sCce3SSvjWdpWc3URSQL85xd5g3ni72TcGIvGIv6XbOZC1
8fveE5wPNQy9PcC/
fPCzvfNzcM75uKIlF1nebvcneAOiEsd+LkCzNmzHn1OAAozse33p4dr1LY9nNAjeEHAzWE9HsDUA7O26SO3
poasjAoPNRvdwT1L+ISZDlZjFam1O4mQT28mqt29njkmIjzT70Cv5w89amiz2muQUx851h+aeAwHo+NCGRe
dhH1lxs9CVhf32IT990FOUDvY2joV6V1eC7fHhWCaJSNLpjVDpzKTpUKRAqZELNh9AbJySyUeaipxodOtmu
FkwkFAlXi3VDglJHLAhK04qXVE5jr9KkwVMVM2ai/0KnOzK32WLZotoqMqU2Tz+84/4Lz/
BeUacWDo6c5xTH4DWc8A/tuDxfAP/8n92k3cF40JpPIWHZiiGpB5ungyf9/
t+EffMHmQyoe1UIEeILSiLj+hIZbq/
sFofHek0m2ENuQZQf9mV9OpYVutxjEf5S2mCXVlpTppulZAEYiIgXnqdCmf3jAoPUcktGLirfaqnmvv+3ES
WHWj3E1mFUhlKe+fZKANlXPF/5v2PLM1//
sFtffeZ+NRqLMpDkw5GYWrKU+7VCLd3X3qP99WUaHFDr4l7wrEaTkfGAmb7L7gypzEoZtQ4KACi1vr3u5xU
2oCzZW0tK2wrGJE5C1FCPAiCo2srQ55qZwS8WQALqL6GVcNNBfMeWvfvSLn2oa7sJOzP+g8xBw7jeauJD+g
HdxCoTbKS1jIxNPB8FELzMfS9ktPbyrDTfXx3d2ELUNvPtNobFewySr0YVAtAELGGY1nKkiXb9QbmxmWh4v
HDEjoUrKVUb9Zgeoa10iRUTRtvAbodaMMqZZrPqPW32fGFihWMHXZn72XeI8W5GAzoqDTxXbujouWa/
obK8+sItlM9VfS9xmo5qQgSk/sqTRR4diuzWaYQmVYMzKd4mkSiAQoiAidnSI26ohyL3p7dvJ9C5/
S1WrPTiuE5mQ64ZUDcrPWo6qSWO2TzdsEgug7EirlU2O7Jm+M70IphycbvYEfANhk2FyfwHrFHn/LGt/
QTzaWhOrYiSXxilQyZmrqyphCopXaN3JBTV+I2GoCwNhRtvWrsJUoGH2kMIkOwi0qhc3997JBUb9gccrJSU
slRYzV8lY3GnE5rs97U6ZS283cm11EDDoNMHNJzjXWH391Ncx93LRAmyXyoaH1VHYPXpe4kMakSos1cPOyV
S0dm66wG/
fszJkbLZp9uIyDh7CiswkR0aRjzqAsTJIzey1R9jEGWDB72itWSHdEyEuH6dob9OmU931J0aq7vYTNbzjfp
tlGf81rdn4vDAkKV/Tv8al/
iwtSy7Tw6tn9adMUhMLqUBjpF1ukimKDHe5zRe9EDnRSOpmerACe23cYGDZ/IH4UwcSI/
Jhizk9W7UyZl6yGPolxZxcC1IwqxzUloQcmw/ayZ8VO3nrluBqEk97Y+l/
8RaMVB+GKuTZuf9N17lI1PJwTtRf/
9Rm6m7mfSrKuQSxzkubsrw+NxAYApg2tnk+ruRQrfsr1FSHYk7zvCZuitKikrgDCoU7otq2xpJ67B9ayGIQ
hjSJWtA5L5+aX+/Z/pzU7x2ZR8JpI77XP41swyNeCJRXzlTvNtBS/
CzguKS0MeIZnavEZpODW7k33PkaMAJrzt0U+0m7lcS3VzL9tLz5uAnno4QPgsFPbUaIz0exWT5l0Zt8qP39
lX90Ni/p4cfwGNykVSjSkwiOc+J/
E44qMIBwmt1peER3Ylc5yU8gyYfcw+hzsqoxUKyTnybAHfeYl6681fhWFpSILat11qo/
LDxAvQbi9EEaDIeb+72wsnYVq3ayNbaAPsibdGk3jkxfh83aqMtx6kbMlWGdWqWQSiKWSZtp7B4YjjgeXV8
bhPHxzyuJxo4BySXj53b80sWQM6ai2/eTYeqnno9VB0RHvsspFGAcG45MWQohAJPMQ/
WbBiFvgxNrmIOzfPejLdLSVAJj+14yzj0ipeKo+jeLTlPDIkq6P3onqlNHcn4e5i0/
eaCaLwqvLyuan31b1XkCXFxwrDzPK5+wTQiobkFzXmAHWO+TpIJRKZgutGC09ZfAgWMbDojTZEpKDxT/
K8iDs9P5z87mZjI4UN4syI/
QWqEgw9E1fT8DgFjBkQdIiqMcJVSgdZNmsKiXquYqmI7jmDLEV4uNE+Z9fcm1m+fxoQKjs9sB8wm1BirKIL
49QwjU8qWB92oEl5ebTRSSvebzdQ7GFWW//
knDYUJDjZXCyhqp4xZpTj0Rohwsh3lgZba6bYGm7ZzyexjwbCJFpnbJOtuW7I87mxtlrK5+ogWSWvgFZA8K
ebMzyAA7kKFbCil0Xr4PUcY70zuUU28QRWXgKIfDIubbJmsoGBNjRGAbdXATUQHyesIYCKCn7NtHLSp7VFi
qvWHmyPzD5Ul3YiMxs2n6s/AzQW8xf/g985qKu+PP/
IZDmw6zkXluIv2OOrlYvKbY914+WDmQhGa8tqDh2VdKthZSkmAaARHMxZ9wIwXg2ZKwliV3ZzxtPUleBWUP
/zL1iO7P1hL1utg0TYtyNy1AMzS/
pPA8JvP0wP64rzOiCw6NHr1n+n+CfUQ1kWh77IfLy0RunkxXDqohzW7J8UgN3J8YnUAr+E8QRe1gA6UheTd
6Dtz/wq6qczU4+Y32f+81+Kf/
8Xred1OZcskyuoRorPyVuVvAFaUQGj0x8GlT046Tz8BPcG3tgfgpqDWZCpFArq+s6OilMBVUiCz+/
IVPVwQj1p1VGwb56tpvPbBfMHx0robLuvx1piiUCUMFHHToJ5MogiCKmKjLhpB3USe9T5iI415WJpuVvycG
nQJQTBEnL5XHzI0wA0lreNXmuIhuq5zc5b7tQPvYyewz28vaXOUdoPkIAovVXjHwlT8aS/
s0iYGCRHa8wbRnSANfY04UUAUSI5bmDKl4f6R9EQ8vR42p7to4IpWAyHksOwhxFdllQ/
D5+LI7njJNBY5jY6/flDn/958OUfpE1w9wu5u//
oZcAJ5RTSiElwJ444nZXO1EgUPu7KhmCNatSsQLTxKD4BAHMFBBADFbOAFo2D7ceQx1UOtXcNDLmSzNwthx
k/CD8QPRjhxZLaL9/sm/
lcDNpBvbHg58AN33bFwWQBqjG8/89wQpckLo4P1DW+FxC6349rvBRCgngpAnF9VEEABSA77zwqQBaebPAVs
EEGUtXaFgk6jwWZsSu8F1zyh7AUtZrrc/A0A40lbyMQFts6PQVIIfCzke6eV7D3/tEVsRSeKm6+UyeGu/
LTAVSHqkdb9GmO1yVPTTMjAN7Am3v63logCILYue6MZQAXh6oOsAQ8b17WehVoUgfMPcwuqkHA59xvnOZoL
H0AvgBwaf0XHH9NUyY7K+moz8by3S8DzoEqwGUgDDDX434Z6vN1o0oZNU+TE7MZrdL9WifPd3XGJgqyiU0Q
W9Xv8fSqmJ8A7jAPUQ9QD1Wpw8QL8zn30GmgcRgC8LkIvY+KMMvnbYy94UVJwescFZnWoBSgcJ9/5ePpGzZ
LWX4odexX+xUeqAAYxnwgjIhJYqHY1h3BDLtgET0MXWDuDf1Cghf6mzYcsr3PtVE9+8RoHI7Tfc6Lfgz1qS
cFTNJC/Nyvk9XVg1yQ4gYkCRTs8lJ/
3cj3dGM4c5VWYsBjCRFgfKnSp7pyvX7EgQ2AXWrVDlQW+5QWXsGdaIe5HMFeio7pCM4kEZ9rwQ0nj0fjoFy
i+XRYys0TB3drv6fFX4Z78blMNZU06IVHmipTtmNUxysjI8lQOEJTx8Y/
Yggi6kmAgDSJxDA0I7+tJTSfz4QxmSTjcdhO+JofIQLY7c7kDpu7dyd+dYuem9G3kG87eMXhjj+/
k3mNfHVc4GgcnFPcRyS87RGpk/z5onTQXw0DzX7CacNKrhIpWy06igngAjl1fNpbYBLtT/
Hgl+7uSZo6ing8XddRXk9xW0gq0hEdPbB0A9eSVKAFtfCI3INe3umXN3Vn8sPpdsK9/8VPmdUHKnkDNA7T5
W6dSShdS0JqlJRWn5Ku1F9tHo6leDrHNBw9GpkgEfgR/
ppYAKJH80ARGgiS2aXkrlXQAhNeWAWk17aFKvxT4sSzX42UUgW1hL8DvThTz3XjnUodSE2tNWPMaJAOTxuB
xsE6xScvBg/
hVU+PHslWSSpTKbeIITt90hfNH7zYEa7TKeQ6SKhjAdMG0xpTAEaGmetd+Xqf3y82ZcrdvT0alBtMqBXLDR
ZC6yNRDaw+Zj1jGmpnNTXtwIPn+lw6zSMIHLgriu+OR4WYdnvVy8qLeSeD/Eedxpr3v1iJqYnVXT/
RxYrN7oiecEoAcsdUAHH3nZ3jHYSJrZGFDa/rPirncrGrJUsCqBExC1iWwDr90KmW50/
A585p5mgcvtfvGX9d3PQL82JZ/
e1/6YuOP6kL+LjkxDAo9VfN5FEXHRCqTpVypoxgQUSJGAGjKwc53E4h12fFK+aCgjYQo1P4GB3v+EVfCu3m
hck/vi7pY9CHFlMDIZ8jI2XHWXI0DmMA1gFY3PAn/
vPXYPWHis336k15WXG8uVkj4iduLarorx6V+o2NOoYIdcBC3SPl6pd4G6b2u9Mn95UDVltvo1xCCpt0BsEG
0dbfBn5/cuJx/E27od/nxsAbUOBoHNJfA8BK+2vfHvCf/MFi+Sos1gwhoLSv1ry0/9a/zu96vYW3/
jUiWv8cHZAQYlpmffn5q55L9D9ADz0tcI4gHMD//dObHS2B/XLkRB6lRJ6Hy/
K5cLrRE4+gjgN9+Z87G8cK4c4ghDhCEQge5v3jmhZflq1PgCDdohjX0t33q3eMYc5NNefz2aof/8T/
dZjJXZCSo3G4L+v6jwfTM6vQ7IaEsPSQt0NYMAPByeRBJXDDue6l1cU/8J0MeHXO3Axfj/5LiGbV5y/
COmcrCjMY6PS0kByNm4k/
HTADHmB6FhI6fuQoydG4OfnTf9m4zDOzC0eOHjAaNz131gtA38B+z1QNhzxN4L8Fox2wmbqz1jAaSxYA'
let image4 = new Image();
image4.src = path4;
ctx.drawImage(image4, p.radius*-1.125,p.radius*-1.125, p.radius*2.25,
p.radius*2.25)
} else {
ctx.lineWidth = p.radius / 5;
ctx.fillStyle = blendColor('#fffcd1', '#FF0000', blendAmount(p));
ctx.strokeStyle = blendColor('#cfcca9', '#FF0000', blendAmount(p));
let color3 = blendColor('#ffffff', '#FF0000', blendAmount(p));
if(checkForFirstFrame(p)){
ctx.fillStyle = "#FFFFFF";
ctx.strokeStyle = "#FFFFFF";
color3 = "#FFFFFF";
}
ctx.beginPath();
ctx.arc(0, 0, p.radius, 0, Math.PI*2);
ctx.fill();
ctx.stroke();
ctx.closePath();
ctx.fillStyle = color3;
ctx.beginPath();
ctx.arc(p.radius*0.3, -p.radius*0.3, p.radius*0.3, 0, Math.PI*2);
ctx.fill();
ctx.closePath();
}
},
Sponge: (p) => {
ctx.fillStyle = blendColor('#efc99a', '#FF0000', blendAmount(p));
ctx.strokeStyle = blendColor('#c2a37d', '#FF0000', blendAmount(p));
if(checkForFirstFrame(p)){
ctx.fillStyle = "#FFFFFF";
ctx.strokeStyle = "#FFFFFF";
}
ctx.lineWidth = p.radius*0.2;
ctx.beginPath();
ctx.moveTo(p.radius * 0.7, 0);
for (let i = Math.PI * 1/7; i < Math.PI * 2; i += Math.PI * 2 / 7) {
ctx.quadraticCurveTo(Math.cos(i) * p.radius * 1.2, Math.sin(i) *
p.radius * 1.2, Math.cos(i + Math.PI * 1 / 7) * p.radius * 0.7, Math.sin(i +
Math.PI * 1 / 7) * p.radius * 0.7);
}
ctx.fill();
ctx.stroke();
ctx.closePath();
},
Shell: (p) => {
ctx.strokeStyle = blendColor('#ccb36d', '#FF0000', blendAmount(p));
ctx.fillStyle = blendColor('#fcdd86', '#FF0000', blendAmount(p));
if(checkForFirstFrame(p)){
ctx.fillStyle = "#ffffff";
ctx.strokeStyle = "#ffffff";
}
ctx.beginPath();
ctx.lineTo(p.radius * -0.73, p.radius * -0.375);
ctx.lineTo(p.radius * 0.39, p.radius * -1.15)
ctx.arcTo(p.radius * 3.3, p.radius * 0.21, p.radius * 0.14, p.radius *
1.19, p.radius * 1.24)
ctx.lineTo(p.radius * 0.14, p.radius * 1.19);
ctx.lineTo(p.radius * 0.14, p.radius * 1.19);
ctx.lineTo(p.radius * -0.78, p.radius * 0.24);
ctx.quadraticCurveTo(p.radius * -0.94, p.radius * -0.06, p.radius * -0.73,
p.radius * -0.375)
ctx.fill();
ctx.stroke();
ctx.closePath();
ctx.beginPath();
ctx.lineTo(0, -p.radius);
ctx.quadraticCurveTo(p.radius, 0, 0, p.radius);
ctx.quadraticCurveTo(-p.radius, 0, 0, -p.radius);
ctx.fill();
ctx.fillStyle = blendColor('#FFFFFF', '#FF0000', blendAmount(p));
if(checkForFirstFrame(p)){
ctx.fillStyle = "#FFFFFF";
}
ctx.beginPath();
ctx.arc(0, 0, p.radius*0.4, 0, Math.PI * 2);
ctx.fill();
ctx.closePath();
},
ctx.lineWidth = 3;
ctx.beginPath();
ctx.fillStyle = blendColor('#811009', '#FF0000', blendAmount(p));
ctx.strokeStyle = blendColor('#660d07', '#FF0000', blendAmount(p));
if(checkForFirstFrame(p)){
ctx.fillStyle = "#FFFFFF";
ctx.strokeStyle = "#FFFFFF";
}
ctx.beginPath();
ctx.moveTo(p.radius * -0.82, p.radius * -1.03);
ctx.quadraticCurveTo(p.radius * 0.21, p.radius * -0.7, p.radius * 0.44,
p.radius * -0.3);
ctx.quadraticCurveTo(p.radius * 0.78, p.radius * 0.2, p.radius * 0.74,
p.radius * 0.76);
ctx.lineTo(p.radius * 0.47, p.radius * 0.97);
ctx.lineTo(p.radius * -0.03, p.radius * 1.01);
ctx.quadraticCurveTo(p.radius * 0.68, p.radius * 0.25, p.radius * 0.06,
p.radius * -0.12);
ctx.lineTo(p.radius * -0.32, p.radius * -0.11);
ctx.quadraticCurveTo(p.radius * 0.12, p.radius * -0.31, p.radius * -0.06,
p.radius * -0.5);
ctx.quadraticCurveTo(p.radius * -0.19, p.radius * -0.66, p.radius * -0.66,
p.radius * -0.42);
ctx.quadraticCurveTo(p.radius * -0.13, p.radius * -0.73, p.radius * -0.82,
p.radius * -1.03);
ctx.fill();
ctx.stroke();
ctx.closePath();
},
Light: (p) => {
ctx.lineWidth = 3;
ctx.beginPath();
ctx.fillStyle = blendColor('#ffffff', '#FF0000', blendAmount(p));
ctx.strokeStyle = blendColor('#cfcfcf', '#FF0000', blendAmount(p));
if(checkForFirstFrame(p)){
ctx.fillStyle = "#FFFFFF";
ctx.strokeStyle = "#FFFFFF";
}
ctx.beginPath();
ctx.arc(0, 0, p.radius, 0, Math.PI*2);
ctx.fill();
ctx.stroke();
ctx.closePath();
},
Heavy: (p) => {
ctx.lineWidth = p.radius / 5;
ctx.beginPath();
ctx.fillStyle = blendColor('#333333', '#FF0000', blendAmount(p));
ctx.strokeStyle = blendColor('#292929', '#FF0000', blendAmount(p));
let color3 = blendColor('#cccccc', '#FF0000', blendAmount(p));
if(checkForFirstFrame(p)){
ctx.fillStyle = "#FFFFFF";
ctx.strokeStyle = "#FFFFFF";
color3 = "#FFFFFF";
}
ctx.beginPath();
ctx.arc(0, 0, p.radius, 0, Math.PI*2);
ctx.fill();
ctx.stroke();
ctx.closePath();
ctx.fillStyle = color3;
ctx.beginPath();
ctx.arc(p.radius*0.35, -p.radius*0.35, p.radius*0.3, 0, Math.PI*2);
ctx.fill();
ctx.closePath();
},
Rice: (p) => {
ctx.beginPath();
let innerColor = blendColor('#ffffff', '#FF0000', blendAmount(p));
let outerColor = blendColor('#cfcfcf', '#FF0000', blendAmount(p));
if(checkForFirstFrame(p)){
innerColor = "#FFFFFF";
outerColor = "#FFFFFF";
}
ctx.strokeStyle = outerColor;
ctx.lineWidth = p.radius;
ctx.beginPath();
ctx.moveTo(-p.radius, 0);
ctx.quadraticCurveTo(0, -p.radius * 0.4, p.radius, 0);
ctx.stroke();
ctx.closePath();
ctx.strokeStyle = innerColor;
ctx.lineWidth = p.radius / 2;
ctx.beginPath();
ctx.moveTo(-p.radius, 0);
ctx.quadraticCurveTo(0, -p.radius * 0.4, p.radius, 0);
ctx.stroke();
ctx.closePath();
},
Iris: (p) => {
ctx.lineWidth = 3;
ctx.beginPath();
ctx.fillStyle = blendColor('#ce76db', '#FF0000', blendAmount(p));
ctx.strokeStyle = blendColor('#a760b1', '#FF0000', blendAmount(p));
if(checkForFirstFrame(p)){
ctx.fillStyle = "#FFFFFF";
ctx.strokeStyle = "#FFFFFF";
}
ctx.beginPath();
ctx.arc(0, 0, p.radius, 0, Math.PI*2);
ctx.fill();
ctx.stroke();
ctx.closePath();
},
Faster: (p) => {
ctx.lineWidth = 3;
ctx.beginPath();
ctx.fillStyle = blendColor('#feffc9', '#FF0000', blendAmount(p));
ctx.strokeStyle = blendColor('#cecfa3', '#FF0000', blendAmount(p));
if(checkForFirstFrame(p)){
ctx.fillStyle = "#FFFFFF";
ctx.strokeStyle = "#FFFFFF";
}
ctx.beginPath();
ctx.arc(0, 0, p.radius, 0, Math.PI*2);
ctx.fill();
ctx.stroke();
ctx.closePath();
},
Stinger: (p) => {
ctx.fillStyle = blendColor('#333333', '#FF0000', blendAmount(p));
ctx.strokeStyle = blendColor('#292929', '#FF0000', blendAmount(p));
if(checkForFirstFrame(p)){
ctx.fillStyle = "#FFFFFF";
ctx.strokeStyle = "#FFFFFF";
}
ctx.lineWidth = 2.75;
ctx.lineJoin = 'round';
// ctx.rotate(p.angle);
ctx.beginPath();
ctx.moveTo(p.radius, 0);
ctx.lineTo(Math.cos(2 / 3 * Math.PI) * p.radius, Math.sin(2 / 3 * Math.PI)
* p.radius)// 120 deg
ctx.lineTo(Math.cos(4 / 3 * Math.PI) * p.radius, Math.sin(4 / 3 * Math.PI)
* p.radius)// 240 deg
ctx.lineTo(p.radius, 0)// back to 0 deg
ctx.fill();
ctx.stroke();
ctx.closePath();
// ctx.rotate(-p.angle);
ctx.beginPath();
// ctx.rotate(p.offset.angle);
ctx.moveTo(p.radius, 0);
for(let i = 0; i < Math.PI * 2; i+=Math.PI / 3){
ctx.lineTo(Math.cos(i + Math.PI / 5) * p.radius, Math.sin(i + Math.PI /
5) * p.radius);
}
// ctx.rotate(-p.offset.angle);
ctx.fill();
ctx.stroke();
ctx.closePath();
ctx.rotate(-p.offset.angle);
},
Missile: (p) => {
// ctx.fillStyle = blendColor('#333333', '#FF0000', blendAmount(p));
// ctx.strokeStyle = blendColor('#292929', '#FF0000', blendAmount(p));
// if(checkForFirstFrame(p)){
// ctx.fillStyle = "#FFFFFF";
// ctx.strokeStyle = "#FFFFFF";
// }
// ctx.lineWidth = p.radius/4;
// ctx.beginPath();
// ctx.moveTo(p.radius*1.3, 0);
// ctx.lineTo(Math.cos(2 / 3 * Math.PI) * p.radius*1.8, Math.sin(2 / 3 *
Math.PI) * p.radius*0.7)// 120 deg
// ctx.lineTo(Math.cos(4 / 3 * Math.PI) * p.radius*1.8, Math.sin(4 / 3 *
Math.PI) * p.radius*0.7)// 240 deg
// ctx.lineTo(p.radius*1.3, 0)// back to 0 deg
// ctx.fill();
// ctx.stroke();
// ctx.closePath();
let bodyColor = blendColor("#333333", "#FF0000", blendAmount(p));
if (checkForFirstFrame(p)) {
bodyColor = "#FFFFFF";
}
ctx.lineJoin = 'round';
ctx.rotate(Math.PI / 2);
// TODO: actually finish this render
ctx.beginPath();
ctx.fillStyle = bodyColor;
ctx.strokeStyle = bodyColor;
ctx.lineWidth = p.radius / 1.5;
ctx.lineJoin = 'round';
ctx.rotate(Math.PI / 2);
// TODO: actually finish this render
ctx.beginPath();
ctx.fillStyle = bodyColor;
ctx.strokeStyle = bodyColor;
ctx.lineWidth = p.radius / 1.5;
ctx.beginPath();
ctx.arc(0, 0, p.radius, 0, Math.PI*2);
ctx.fill();
ctx.stroke();
ctx.closePath();
},
// ctx.save();
// ctx.beginPath();
// // ctx.stroke();
// // ctx.closePath();
// // p.arc(0, 0, e.render.radius, 0, Math.PI * 2);
// }
// ctx.clip(path, "evenodd");
// ctx.clip();
// ctx.closePath();
ctx.beginPath();
ctx.moveTo(p.radius*0.95, 0);
for(let i = 0; i <= Math.PI * 2; i += Math.PI / 5.5){
ctx.quadraticCurveTo(Math.cos(i - Math.PI / 11) * (p.radius * .75),
Math.sin(i - Math.PI / 11) * (p.radius * .75), Math.cos(i) * p.radius * 0.95,
Math.sin(i) * p.radius * 0.95);
}
ctx.stroke();
ctx.closePath();
ctx.beginPath();
ctx.moveTo(p.radius*0.75, 0);
for(let i = 0; i <= Math.PI * 2; i += Math.PI / 5.5){
ctx.quadraticCurveTo(Math.cos(i - Math.PI / 11) * (p.radius * .55),
Math.sin(i - Math.PI / 11) * (p.radius * .55), Math.cos(i) * p.radius * 0.75,
Math.sin(i) * p.radius * 0.75);
}
ctx.stroke();
ctx.closePath();
ctx.beginPath();
ctx.moveTo(p.radius*0.55, 0);
for(let i = 0; i <= Math.PI * 2; i += Math.PI / 5.5){
ctx.quadraticCurveTo(Math.cos(i - Math.PI / 11) * (p.radius * .35),
Math.sin(i - Math.PI / 11) * (p.radius * .35), Math.cos(i) * p.radius * 0.55,
Math.sin(i) * p.radius * 0.55);
}
ctx.stroke();
ctx.closePath();
ctx.beginPath();
ctx.moveTo(p.radius*0.35, 0);
for(let i = 0; i <= Math.PI * 2; i += Math.PI / 5.5){
ctx.quadraticCurveTo(Math.cos(i - Math.PI / 11) * (p.radius * .15),
Math.sin(i - Math.PI / 11) * (p.radius * .15), Math.cos(i) * p.radius * 0.35,
Math.sin(i) * p.radius * 0.35);
}
ctx.stroke();
ctx.closePath();
// ctx.restore();
ctx.stroke();
ctx.closePath();
}
} else {
ctx.lineWidth = 0;
ctx.globalAlpha = 0.5
ctx.beginPath();
ctx.fillStyle = blendColor('#ffffff', '#FF0000', blendAmount(p));
ctx.beginPath();
ctx.arc(0, 0, p.radius, 0, Math.PI*2);
ctx.fill();
ctx.stroke();
ctx.closePath();
}
ctx.globalAlpha = lastGA;
},
return;
}
ctx.beginPath();
ctx.fillStyle = blendColor("#777777", '#FF0000', blendAmount(p));
ctx.strokeStyle = blendColor("#606060", '#FF0000', blendAmount(p));
ctx.lineWidth = 3;
if(checkForFirstFrame(p)){
ctx.fillStyle = "#FFFFFF";
ctx.strokeStyle = "#FFFFFF"
}
for(let i = 0; i < 5; i++){
ctx.lineTo(Math.cos(i * 1.256) * p.radius, Math.sin(i * 1.256) *
p.radius);
}
ctx.fill();
ctx.lineTo(Math.cos(5 * 1.256) * p.radius, Math.sin(5 * 1.256) * p.radius);
ctx.stroke();
ctx.closePath();
// ctx.beginPath();
// ctx.fillStyle = blendColor("#777777", '#FF0000', blendAmount(p));
// if(checkForFirstFrame(p)){
// ctx.fillStyle = "#FFFFFF";
// }
// for(let i = 0; i < 5; i++){
// ctx.lineTo(Math.cos(i * 1.256) * p.radius* 0.65, Math.sin(i * 1.256) *
p.radius * 0.65);
// }
// ctx.fill();
// ctx.closePath();
},
Ruby: (p) => {
ctx.beginPath();
ctx.fillStyle = blendColor("#eb5b4b", '#FF0000', blendAmount(p));
ctx.strokeStyle = blendColor("#b34230", '#FF0000', blendAmount(p));
ctx.lineWidth = 4;
if(checkForFirstFrame(p)){
ctx.fillStyle = "#FFFFFF";
ctx.strokeStyle = "#FFFFFF"
}
for(let i = 0; i < 4; i++){
ctx.lineTo(Math.cos(i * 1.57) * p.radius, Math.sin(i * 1.57) *
p.radius);
}
ctx.fill();
ctx.lineTo(Math.cos(4 * 1.57) * p.radius, Math.sin(4 * 1.57) * p.radius);
ctx.stroke();
ctx.closePath();
// ctx.beginPath();
// ctx.fillStyle = blendColor("#777777", '#FF0000', blendAmount(p));
// if(checkForFirstFrame(p)){
// ctx.fillStyle = "#FFFFFF";
// }
// for(let i = 0; i < 5; i++){
// ctx.lineTo(Math.cos(i * 1.256) * p.radius* 0.65, Math.sin(i * 1.256) *
p.radius * 0.65);
// }
// ctx.fill();
// ctx.closePath();
},
Sapphire: (p) => {
ctx.beginPath();
ctx.fillStyle = blendColor("#528cff", '#FF0000', blendAmount(p));
ctx.strokeStyle = blendColor("#3664bf", '#FF0000', blendAmount(p));
ctx.lineWidth = 4;
if(checkForFirstFrame(p)){
ctx.fillStyle = "#FFFFFF";
ctx.strokeStyle = "#FFFFFF"
}
for(let i = 0; i < 6; i++){
ctx.lineTo(Math.cos(i * 1.046) * p.radius, Math.sin(i * 1.046) *
p.radius);
}
ctx.fill();
ctx.lineTo(Math.cos(6 * 1.046) * p.radius, Math.sin(6 * 1.046) * p.radius);
ctx.stroke();
ctx.closePath();
},
Token: (p) => {
ctx.beginPath();
ctx.fillStyle = blendColor("#ffc800", '#FF0000', blendAmount(p));
ctx.strokeStyle = blendColor("#a37614", '#FF0000', blendAmount(p));
ctx.lineWidth = 4;
if(checkForFirstFrame(p)){
ctx.fillStyle = "#FFFFFF";
ctx.strokeStyle = "#FFFFFF"
}
for(let i = 0; i < 3; i++){
ctx.lineTo(Math.cos((i+0.5) * 1.046) * p.radius, Math.sin((i+0.5) *
1.046) * (p.radius*1.4));
}
for(let i = 0; i < 3; i++){
ctx.lineTo(Math.cos((i+3.5) * 1.046) * p.radius, Math.sin((i+0.5) *
1.046) * (p.radius*-1.4));
}
ctx.fill();
ctx.lineTo(Math.cos(6.5 * 1.046) * p.radius, Math.sin(3.5 * 1.046) *
(p.radius*-1.4));
ctx.stroke();
ctx.closePath();
},
Ikea: (p) => {
if(p.image === undefined || p.image.onload === undefined){
p.image = new Image();
p.image.src = 'https://archello.com/thumbs/images/2014/02/03/IKEA-
Tampines.1506072620.5502.jpg?fit=crop&w=414&h=518';
p.image.onload = () => {
p.imageLoaded = true;
}
}
ctx.fill();
ctx.lineTo(p.radius * 1.28, p.radius * -0.25),
ctx.stroke();
ctx.closePath();
// ctx.beginPath();
// ctx.fillStyle = blendColor("#777777", '#FF0000', blendAmount(p));
// if(checkForFirstFrame(p)){
// ctx.fillStyle = "#FFFFFF";
// }
// for(let i = 0; i < 5; i++){
// ctx.lineTo(Math.cos(i * 1.256) * p.radius* 0.65, Math.sin(i * 1.256) *
p.radius * 0.65);
// }
// ctx.fill();
// ctx.closePath();
},
Salt: (p) => {
ctx.beginPath();
ctx.fillStyle = blendColor("#ffffff", '#FF0000', blendAmount(p));
ctx.strokeStyle = blendColor("#cfcfcf", '#FF0000', blendAmount(p));
ctx.lineWidth = 3;
if(checkForFirstFrame(p)){
ctx.fillStyle = "#FFFFFF";
ctx.strokeStyle = "#FFFFFF"
}
//1.28, -0.25then 0.88, 0.7 then -0.04, 1.15 then -0.97, 0.71 then -1.23, -
0.35 then -0.56, -1.23 then 0.6, -1.12
ctx.moveTo(p.radius * 1.28, p.radius * -0.25),
ctx.lineTo(p.radius * 0.88, p.radius * 0.7),
ctx.lineTo(p.radius * -0.04, p.radius * 1.15),
ctx.lineTo(p.radius * -0.97, p.radius * 0.71),
ctx.lineTo(p.radius * -1.23, p.radius * -0.35),
ctx.lineTo(p.radius * -0.56, p.radius * -1.23),
ctx.lineTo(p.radius * 0.6, p.radius * -1.12),
ctx.fill();
ctx.lineTo(p.radius * 1.28, p.radius * -0.25),
ctx.stroke();
ctx.closePath();
// ctx.beginPath();
// ctx.fillStyle = blendColor("#777777", '#FF0000', blendAmount(p));
// if(checkForFirstFrame(p)){
// ctx.fillStyle = "#FFFFFF";
// }
// for(let i = 0; i < 5; i++){
// ctx.lineTo(Math.cos(i * 1.256) * p.radius* 0.65, Math.sin(i * 1.256) *
p.radius * 0.65);
// }
// ctx.fill();
// ctx.closePath();
},
Powder: (p) => {
ctx.fillStyle = blendColor("#ffffff", "#FF0000", blendAmount(p))
ctx.beginPath();
ctx.arc(p.radius * 0.63, p.radius * -0.63, p.radius * 0.46, 0, Math.PI *
2);
ctx.fill();
ctx.closePath();
ctx.beginPath();
ctx.arc(p.radius * 0.63, p.radius * 0, p.radius * 0.43, 0, Math.PI * 2);
ctx.fill();
ctx.closePath();
ctx.beginPath();
ctx.arc(p.radius * 0.45, p.radius * 0.26, p.radius * 0.43, 0, Math.PI * 2);
ctx.fill();
ctx.closePath();
ctx.beginPath();
ctx.arc(p.radius * 0.34, p.radius * 0.79, p.radius * 0.45, 0, Math.PI * 2);
ctx.fill();
ctx.closePath();
ctx.beginPath();
ctx.arc(p.radius * -0.1, p.radius * 0.4, p.radius * 0.45, 0, Math.PI * 2);
ctx.fill();
ctx.closePath();
ctx.beginPath();
ctx.arc(p.radius * -0.62, p.radius * 0.2, p.radius * 0.45, 0, Math.PI * 2);
ctx.fill();
ctx.closePath();
ctx.beginPath();
ctx.arc(p.radius * -0.71, p.radius * -0.09, p.radius * 0.45, 0, Math.PI *
2);
ctx.fill();
ctx.closePath();
ctx.beginPath();
ctx.arc(p.radius * -0.55, p.radius * -0.74, p.radius * 0.45, 0, Math.PI *
2);
ctx.fill();
ctx.closePath();
ctx.beginPath();
ctx.arc(p.radius * -0.16, p.radius * -0.57, p.radius * 0.45, 0, Math.PI *
2);
ctx.fill();
ctx.closePath();
ctx.beginPath();
ctx.arc(p.radius * 0, p.radius * -0.5, p.radius * 0.45, 0, Math.PI * 2);
ctx.fill();
ctx.closePath();
ctx.beginPath();
ctx.arc(0, 0, p.radius*0.4, 0, Math.PI * 2);
ctx.fill();
ctx.closePath();
},
Leaf: (p) => {
const divCoef = 1.35;
ctx.lineWidth = p.radius/divCoef/2.5//2.2;
// ctx.beginPath();
ctx.fillStyle = blendColor('#39b54a', '#FF0000', blendAmount(p));
ctx.strokeStyle = blendColor('#2e933c', '#FF0000', blendAmount(p));
if(checkForFirstFrame(p)){
ctx.fillStyle = "#FFFFFF";
ctx.strokeStyle = "#FFFFFF";
}
// ctx.beginPath();
// // ctx.rotate(p.offset.angle);
// ctx.moveTo(p.radius, 0);
// for(let i = 1; i < 6; i++){
// ctx.lineTo(Math.cos(i) * p.radius, Math.sin(i) * p.radius);
// }
// ctx.lineTo(p.radius, 0);
// // ctx.rotate(-p.offset.angle);
// ctx.fill();
// ctx.stroke();
ctx.rotate(Math.PI / 4 - 0.2);
ctx.beginPath();
// -.2, -.6 center of leaf
ctx.moveTo(0, 1.854*p.radius/divCoef);
// tail
ctx.moveTo(0, 1.948*p.radius/divCoef);
ctx.lineTo(0, 2.536*p.radius/divCoef);
ctx.fill();
ctx.stroke();
ctx.closePath();
ctx.beginPath();
ctx.stroke();
ctx.closePath();
ctx.rotate(-Math.PI / 4 + 0.2);
// 1: -1.18 -1.065
// still getting bezier right lol
// weird stuff
// 2:
},
Yucca: (p) => {
const divCoef = 1.35;
ctx.lineWidth = p.radius/divCoef/2.5//2.2;
// ctx.beginPath();
ctx.fillStyle = blendColor('#74b53f', '#FF0000', blendAmount(p));
ctx.strokeStyle = blendColor('#5e9333', '#FF0000', blendAmount(p));
if(checkForFirstFrame(p)){
ctx.fillStyle = "#FFFFFF";
ctx.strokeStyle = "#FFFFFF";
}
ctx.lineWidth = p.radius/4.5 * 1.6
ctx.beginPath();
ctx.lineTo(p.radius * 0.49 * 1.6, p.radius * -0.77 * 1.6);
ctx.quadraticCurveTo(p.radius * 0.67 * 1.6, p.radius * 0.37 * 1.6, p.radius
* -0.49 * 1.6, p.radius * 0.77 * 1.6)
ctx.quadraticCurveTo(p.radius * -0.67 * 1.6, p.radius * -0.39 * 1.6,
p.radius * 0.49 * 1.6, p.radius * -0.77 * 1.6)
ctx.fill();
ctx.stroke();
ctx.closePath();
},
Pincer: (p) => {
const divCoef = 1.35;
ctx.fillStyle = blendColor('#333333', '#FF0000', blendAmount(p));
ctx.strokeStyle = blendColor('#292929', '#FF0000', blendAmount(p));
if(checkForFirstFrame(p)){
ctx.fillStyle = "#FFFFFF";
ctx.strokeStyle = "#FFFFFF";
}
ctx.lineWidth = p.radius/4.5
ctx.beginPath();
ctx.lineTo(p.radius * 0.35 * 1.4, p.radius * 0.79 * 1.4);
ctx.quadraticCurveTo(p.radius * 0.25 * 1.4, p.radius * 0.2 * 1.4, p.radius
* -0.85 * 1.4, p.radius * -0.22 * 1.4);
ctx.quadraticCurveTo(p.radius * 0.93 * 1.4, p.radius * -0.69 * 1.4,
p.radius * 0.35 * 1.4, p.radius * 0.79 * 1.4);
ctx.fill();
ctx.stroke();
ctx.closePath();
},
"Yin Yang": (p) => {
let fillColor1 = blendColor('#ffffff', '#FF0000', blendAmount(p));
let strokeColor1 = blendColor('#cfcfcf', '#FF0000', blendAmount(p));
let fillColor2 = blendColor('#333333', '#FF0000', blendAmount(p));
let strokeColor2 = blendColor('#292929', '#FF0000', blendAmount(p));
if(checkForFirstFrame(p)){
fillColor1 = "#FFFFFF";
strokeColor1 = "#FFFFFF";
fillColor2 = "#FFFFFF";
strokeColor2 = "#FFFFFF";
}
ctx.lineWidth = p.radius/4.5
ctx.strokeStyle = strokeColor1
ctx.fillStyle = fillColor1
ctx.beginPath();
ctx.arc(0, 0, p.radius*0.89, Math.PI/2, Math.PI/2 *3);
ctx.fill();
ctx.stroke();
ctx.closePath();
ctx.strokeStyle = strokeColor2;
ctx.fillStyle = fillColor2;
ctx.beginPath();
ctx.arc(0, 0, p.radius*0.89, 3*Math.PI/2, Math.PI/2);
ctx.fill();
ctx.stroke();
ctx.closePath();
ctx.beginPath();
ctx.arc(0.5, p.radius * 0.445, p.radius*0.445, Math.PI/2, Math.PI/2*3);
ctx.fill();
ctx.stroke();
ctx.closePath();
ctx.strokeStyle = strokeColor1;
ctx.fillStyle = fillColor1;
ctx.beginPath();
ctx.arc(-0.5, -p.radius * 0.44, p.radius*0.445, Math.PI/2*3, Math.PI/2);
ctx.fill();
ctx.stroke();
ctx.closePath();
},
"Rose": (p) => {
const divCoef = 1.35;
ctx.lineWidth = p.radius/divCoef/2.5//2.2;
// ctx.beginPath();
ctx.fillStyle = blendColor('#ff94c9', '#FF0000', blendAmount(p));
ctx.strokeStyle = blendColor('#cf78a3', '#FF0000', blendAmount(p));
if(checkForFirstFrame(p)){
ctx.fillStyle = "#FFFFFF";
ctx.strokeStyle = "#FFFFFF";
}
ctx.beginPath();
ctx.arc(0, 0, p.radius, 0, Math.PI*2);
ctx.fill();
ctx.stroke();
ctx.closePath();
},
"Trident": (p) => {
ctx.lineWidth = 3;
ctx.beginPath();
ctx.fillStyle = blendColor('#25dbe8', '#FF0000', blendAmount(p));
if (p.rarity == 5){
ctx.fillStyle = blendColor('#24529c', '#FF0000', blendAmount(p));
}
if(checkForFirstFrame(p)){
ctx.fillStyle = "#FFFFFF";
}
//Shaft
ctx.beginPath();
ctx.moveTo(p.radius * -0.15, p.radius * 1.4);
ctx.lineTo(p.radius * 0.15, p.radius * 1.4);
ctx.lineTo(p.radius * 0.15, p.radius * -0.6);
ctx.lineTo(p.radius * -0.15, p.radius * -0.6);
ctx.fill()
ctx.closePath();
//Top Arrow
ctx.beginPath();
ctx.moveTo(p.radius * 0.35, p.radius * -0.6);
ctx.lineTo(p.radius * -0.35, p.radius * -0.6);
ctx.lineTo(p.radius * 0, p.radius * -1.2);
ctx.fill()
ctx.closePath();
//Right bottom
ctx.beginPath();
ctx.lineTo(p.radius * 0.15, p.radius * 0.75);
ctx.quadraticCurveTo(p.radius * 0.35, p.radius * 0.72, p.radius * 0.62,
p.radius * 0.81);
ctx.lineTo(p.radius * 0.42, p.radius * 0.5);
ctx.lineTo(p.radius * 0.15, p.radius * 0.5);
ctx.fill()
ctx.closePath();
//Right right
ctx.beginPath();
ctx.lineTo(p.radius * 0.62, p.radius * 0.81)
ctx.quadraticCurveTo(p.radius * 0.66, p.radius * -0.12, p.radius * 1.22,
p.radius * -0.84);
ctx.lineTo(p.radius * 0.71, p.radius * -0.5)
ctx.quadraticCurveTo(p.radius * 0.5, p.radius * -0.26, p.radius * 0.42,
p.radius * 0.5)
ctx.fill();
ctx.closePath();
//Right top
ctx.beginPath();
ctx.lineTo(p.radius * 0.71, p.radius * -0.5)
ctx.lineTo(p.radius * 0.56, p.radius * -0.54)
ctx.quadraticCurveTo(p.radius * 0.84, p.radius * -0.81, p.radius * 1.22,
p.radius * -0.84)
ctx.fill();
ctx.closePath();
//Left bottom
ctx.beginPath();
ctx.lineTo(p.radius * -0.15, p.radius * 0.75);
ctx.quadraticCurveTo(p.radius * -0.35, p.radius * 0.72, p.radius * -0.62,
p.radius * 0.81);
ctx.lineTo(p.radius * -0.42, p.radius * 0.5);
ctx.lineTo(p.radius * -0.15, p.radius * 0.5);
ctx.fill()
ctx.closePath();
//Left right
ctx.beginPath();
ctx.lineTo(p.radius * -0.62, p.radius * 0.81)
ctx.quadraticCurveTo(p.radius * -0.66, p.radius * -0.12, p.radius * -1.22,
p.radius * -0.84);
ctx.lineTo(p.radius * -0.71, p.radius * -0.5)
ctx.quadraticCurveTo(p.radius * -0.5, p.radius * -0.26, p.radius * -0.42,
p.radius * 0.5)
ctx.fill();
ctx.closePath();
//Left top
ctx.beginPath();
ctx.lineTo(p.radius * -0.71, p.radius * -0.5)
ctx.lineTo(p.radius * -0.56, p.radius * -0.54)
ctx.quadraticCurveTo(p.radius * -0.84, p.radius * -0.81, p.radius * -1.22,
p.radius * -0.84)
ctx.fill();
ctx.closePath();
},
"Dahlia": (p) => {
const divCoef = 1;
ctx.lineWidth = p.radius/divCoef/2.5//2.2;
// ctx.beginPath();
ctx.fillStyle = blendColor('#ff94c9', '#FF0000', blendAmount(p));
ctx.strokeStyle = blendColor('#cf78a3', '#FF0000', blendAmount(p));
if(checkForFirstFrame(p)){
ctx.fillStyle = "#FFFFFF";
ctx.strokeStyle = "#FFFFFF";
}
ctx.beginPath();
ctx.arc(0, 0, p.radius, 0, Math.PI*2);
ctx.fill();
ctx.stroke();
ctx.closePath();
},
ctx.beginPath();
ctx.lineTo(p.radius * -0.159, p.radius * 1.122);
ctx.quadraticCurveTo(-p.radius * 0.16, p.radius * 0.17, p.radius * -1.085,
p.radius * 0.342);
ctx.quadraticCurveTo(p.radius * -0.76, p.radius * -1.91, p.radius * 0.63,
p.radius * -0.74);
ctx.quadraticCurveTo(p.radius * 2, p.radius * 0.43, p.radius * -0.159,
p.radius * 1.122);
ctx.stroke();
ctx.fill();
ctx.closePath();
},
"Bone": (p) => {
// ctx.beginPath();
let fill = blendColor('#ffffff', '#FF0000', blendAmount(p));
let stroke = blendColor('#cdcdcd', '#FF0000', blendAmount(p));
if(checkForFirstFrame(p)){
fill = "#FFFFFF";
stroke = "#FFFFFF";
}
ctx.fillStyle = stroke;
ctx.lineWidth = p.radius/6
ctx.beginPath();
ctx.arc(p.radius * 0.33, p.radius * 0.93, p.radius * 0.39, -Math.PI * 0.1,
Math.PI * 1.05);
ctx.fill();
ctx.closePath();
ctx.beginPath();
ctx.arc(p.radius * 0.7, p.radius * 0.69, p.radius * 0.39, -Math.PI*0.45,
Math.PI * 0.6);
ctx.fill();
ctx.closePath();
ctx.beginPath();
ctx.arc(p.radius * -0.7, p.radius * -0.67, p.radius * 0.39, Math.PI*0.69,
Math.PI * 1.8);
ctx.fill();
ctx.closePath();
ctx.beginPath();
ctx.arc(p.radius * -0.32, p.radius * -0.91, p.radius * 0.39, Math.PI *
0.95, 0.1);
ctx.fill();
ctx.closePath();
ctx.fillStyle = fill;
ctx.beginPath();
ctx.arc(p.radius * 0.33, p.radius * 0.93, p.radius * 0.22, 0, Math.PI * 2);
ctx.fill();
ctx.closePath();
ctx.beginPath();
ctx.arc(p.radius * 0.7, p.radius * 0.69, p.radius * 0.22, 0, Math.PI * 2);
ctx.fill();
ctx.closePath();
ctx.beginPath();
ctx.arc(p.radius * -0.7, p.radius * -0.67, p.radius * 0.22, 0, Math.PI *
2);
ctx.fill();
ctx.closePath();
ctx.beginPath();
ctx.arc(p.radius * -0.32, p.radius * -0.91, p.radius * 0.22, 0, Math.PI *
2);
ctx.fill();
ctx.closePath();
ctx.strokeStyle = stroke;
ctx.beginPath();
ctx.lineTo(p.radius * 0.035, p.radius * 0.86);
ctx.quadraticCurveTo(p.radius * -0.03, p.radius * 0.07, p.radius * -0.86,
p.radius * -0.41)
ctx.lineTo(p.radius * -0.5, p.radius * -0.78);
ctx.lineTo(p.radius * -0.02, p.radius * -0.86);
ctx.quadraticCurveTo(p.radius * 0.03, p.radius * -0.07, p.radius * 0.8,
p.radius * 0.42)
ctx.lineTo(p.radius * 0.51, p.radius * 0.789);
ctx.fill();
ctx.closePath();
ctx.beginPath();
ctx.lineTo(p.radius * 0.035, p.radius * 0.86);
ctx.quadraticCurveTo(p.radius * -0.03, p.radius * 0.07, p.radius * -0.86,
p.radius * -0.41)
ctx.moveTo(p.radius * 0.8, p.radius * 0.42);
ctx.quadraticCurveTo(p.radius * 0.03, p.radius * -0.07, p.radius * -0.02,
p.radius * -0.86)
ctx.stroke()
ctx.closePath();
},
"Wing": (p) => {
const divCoef = 1.35;
ctx.lineWidth = p.radius/divCoef/1.9//2.2;
// ctx.beginPath();
ctx.fillStyle = blendColor('#ffffff', '#FF0000', blendAmount(p));
ctx.strokeStyle = blendColor('#cdcdcd', '#FF0000', blendAmount(p));
if(checkForFirstFrame(p)){
ctx.fillStyle = "#FFFFFF";
ctx.strokeStyle = "#FFFFFF";
}
ctx.beginPath();
ctx.arc(0, 0, p.radius*1.01, -Math.PI * 0.18, Math.PI * 0.818);
ctx.arcTo(p.radius * 0.42, p.radius * 0.6, p.radius*0.85, -p.radius * 0.53,
p.radius * 1.7);
ctx.stroke();
ctx.fill();
ctx.closePath();
},
"Oranges": (p) => {
const divCoef = 1.35;
ctx.lineWidth = p.radius/divCoef/2.2//2.2;
// ctx.beginPath();
ctx.fillStyle = blendColor('#f0bd48', '#FF0000', blendAmount(p));
ctx.strokeStyle = blendColor('#c2993a', '#FF0000', blendAmount(p));
if(checkForFirstFrame(p)){
ctx.fillStyle = "#FFFFFF";
ctx.strokeStyle = "#FFFFFF";
}
ctx.beginPath();
ctx.arc(0, 0, p.radius, 0, Math.PI*2);
ctx.fill();
ctx.stroke();
ctx.closePath();
ctx.lineWidth = p.radius/divCoef/2.5//2.2;
// ctx.beginPath();
ctx.fillStyle = blendColor('#f7cf2f', '#FF0000', blendAmount(p));
ctx.strokeStyle = blendColor('#c8a826', '#FF0000', blendAmount(p));
if(checkForFirstFrame(p)){
ctx.fillStyle = "#FFFFFF";
ctx.strokeStyle = "#FFFFFF";
}
ctx.beginPath();
for(let i = 7; i--; i>0){
ctx.lineTo(Math.cos(i * Math.PI/3) * p.radius, Math.sin(i * Math.PI/3)
* p.radius)
}
ctx.fill();
ctx.stroke();
ctx.closePath();
},
"Peas": (p) => {
const divCoef = 1;
ctx.lineWidth = p.radius/divCoef/2.5//2.2;
// ctx.beginPath();
ctx.fillStyle = blendColor('#8ac255', '#FF0000', blendAmount(p));
ctx.strokeStyle = blendColor('#709d45', '#FF0000', blendAmount(p));
if(checkForFirstFrame(p)){
ctx.fillStyle = "#FFFFFF";
ctx.strokeStyle = "#FFFFFF";
}
ctx.beginPath();
ctx.arc(0, 0, p.radius, 0, Math.PI*2);
ctx.fill();
ctx.stroke();
ctx.closePath();
},
"Grapes": (p) => {
const divCoef = 1;
ctx.lineWidth = p.radius/divCoef/2.5//2.2;
// ctx.beginPath();
ctx.fillStyle = blendColor('#ce76db', '#FF0000', blendAmount(p));
ctx.strokeStyle = blendColor('#a760b1', '#FF0000', blendAmount(p));
if(checkForFirstFrame(p)){
ctx.fillStyle = "#FFFFFF";
ctx.strokeStyle = "#FFFFFF";
}
ctx.beginPath();
ctx.arc(0, 0, p.radius, 0, Math.PI*2);
ctx.fill();
ctx.stroke();
ctx.closePath();
},
"Cactus": (p) => {
if(p.rarity === 6 || window.flowrMod.forceUltraCactus){
if(p.image === undefined || p.image.onload === undefined){
p.image = new Image();
p.image.src = './gfx/deteled.png';
p.image.onload = () => {
p.imageLoaded = true;
}
}
return;
}
const divCoef = 1;
ctx.lineWidth = p.radius/divCoef/5.5//2.2;
// ctx.beginPath();
ctx.fillStyle = blendColor('#38c75f', '#FF0000', blendAmount(p));
ctx.strokeStyle = blendColor('#2da14d', '#FF0000', blendAmount(p));
if(checkForFirstFrame(p)){
ctx.fillStyle = "#FFFFFF";
ctx.strokeStyle = "#FFFFFF";
}
ctx.beginPath();
ctx.moveTo(p.radius, 0);
for(let i = 0; i <= Math.PI * 2; i += Math.PI / 4){
ctx.quadraticCurveTo(Math.cos(i - Math.PI / 8) * (p.radius * .7),
Math.sin(i - Math.PI / 8) * (p.radius * .7), Math.cos(i) * p.radius, Math.sin(i) *
p.radius);
}
ctx.fill();
ctx.stroke();
ctx.closePath();
},
"Dandelion": (p) => {
ctx.strokeStyle = "black";
ctx.lineWidth = p.radius / 1.39;
//ctx.rotate(p.offset.angle);
ctx.beginPath();
ctx.moveTo(-p.radius * 1.59, 0);
ctx.lineTo(0, 0);
ctx.stroke();
ctx.closePath();
//ctx.rotate(-p.offset.angle);
ctx.lineWidth = p.radius / 4;
ctx.beginPath();
ctx.arc(0, 0, p.radius * 9 / 10, 0, Math.PI * 2);
ctx.fill();
ctx.stroke();
ctx.closePath();
},
Egg: (p) => {
ctx.lineWidth = 3;
ctx.beginPath();
ctx.fillStyle = blendColor('#fff0b8', '#FF0000', blendAmount(p));
ctx.strokeStyle = blendColor('#cfc295', '#FF0000', blendAmount(p));
if(checkForFirstFrame(p)){
ctx.fillStyle = "#FFFFFF";
ctx.strokeStyle = "#FFFFFF";
}
ctx.beginPath();
ctx.ellipse(0, 0, p.radius, p.radius*1.35, 0, 0, Math.PI*2);
ctx.fill();
ctx.stroke();
ctx.closePath();
},
"Plastic Egg": (p) => {
ctx.lineWidth = 3;
ctx.beginPath();
ctx.fillStyle = blendColor('#4b89db', '#FF0000', blendAmount(p));
ctx.strokeStyle = blendColor('#3563a1', '#FF0000', blendAmount(p));
if(checkForFirstFrame(p)){
ctx.fillStyle = "#FFFFFF";
ctx.strokeStyle = "#FFFFFF";
}
ctx.beginPath();
ctx.ellipse(0, 0, p.radius, p.radius*1.35, 0, 0, Math.PI*2);
ctx.fill();
ctx.stroke();
ctx.closePath();
},
"Web": (p) => {
const divCoef = 1;
ctx.lineWidth = p.radius/divCoef/5.5//2.2;
// ctx.beginPath();
ctx.fillStyle = blendColor('#ffffff', '#FF0000', blendAmount(p));
ctx.strokeStyle = blendColor('#cfcfcf', '#FF0000', blendAmount(p));
if(checkForFirstFrame(p)){
ctx.fillStyle = "#FFFFFF";
ctx.strokeStyle = "#FFFFFF";
}
ctx.beginPath();
ctx.moveTo(p.radius, 0);
for(let i = 0; i <= Math.PI * 2; i += Math.PI * 2/5){
ctx.quadraticCurveTo(Math.cos(i - Math.PI * 1/5) * (p.radius * .6),
Math.sin(i - Math.PI / 5) * (p.radius * .6), Math.cos(i) * p.radius, Math.sin(i) *
p.radius);
}
ctx.fill();
ctx.stroke();
ctx.closePath();
},
Pollen: (p) => {
ctx.lineWidth = 3;
ctx.beginPath();
ctx.fillStyle = blendColor('#ffe763', '#FF0000', blendAmount(p));
ctx.strokeStyle = blendColor('#cfbb50', '#FF0000', blendAmount(p));
if(checkForFirstFrame(p)){
ctx.fillStyle = "#FFFFFF";
ctx.strokeStyle = "#FFFFFF";
}
ctx.beginPath();
ctx.arc(0, 0, p.radius, 0, Math.PI*2);
ctx.fill();
ctx.stroke();
ctx.closePath();
},
Magnet: (p) => {
ctx.fillStyle = blendColor('#a44343', '#FF0000', blendAmount(p));
ctx.strokeStyle = blendColor('#853636', '#FF0000', blendAmount(p));
if(checkForFirstFrame(p)){
ctx.fillStyle = "#FFFFFF";
ctx.strokeStyle = "#FFFFFF";
}
ctx.lineWidth = p.radius / 6;
ctx.lineCap = "butt";
ctx.beginPath();
ctx.moveTo(p.radius * -0.25, p.radius * 0.38);
ctx.quadraticCurveTo(p.radius * -0.47, p.radius * 0.22, p.radius * -0.42,
p.radius * 0.08)
ctx.quadraticCurveTo(p.radius * -0.28, p.radius * -0.25, p.radius * 0.05,
p.radius * -0.48);
ctx.quadraticCurveTo(p.radius * 0.32, p.radius * -1.12, p.radius * -0.39,
p.radius * -1.05)
ctx.quadraticCurveTo(p.radius * -1.78, p.radius * 0.1, p.radius * -0.66,
p.radius * 0.96)
ctx.fill();
ctx.stroke();
ctx.closePath();
ctx.lineWidth = p.radius*0.75
ctx.beginPath();
ctx.moveTo(p.radius * -0.90, p.radius * 0.58);
ctx.lineTo(p.radius * 0.01, p.radius * 0);
ctx.lineTo(p.radius * 0.56, p.radius * -1.14);
ctx.moveTo(p.radius * 0.01, p.radius * 0);
ctx.lineTo(p.radius * 0.88, p.radius * -0.06);
ctx.stroke();
ctx.closePath();
ctx.lineWidth = p.radius*0.35
ctx.strokeStyle = innerColor;
ctx.beginPath();
ctx.moveTo(p.radius * -0.90, p.radius * 0.58);
ctx.lineTo(p.radius * 0.01, p.radius * 0);
ctx.lineTo(p.radius * 0.56, p.radius * -1.14);
ctx.moveTo(p.radius * 0.01, p.radius * 0);
ctx.lineTo(p.radius * 0.88, p.radius * -0.06);
ctx.stroke();
ctx.closePath();
},
Square: (p) => {
ctx.beginPath();
ctx.fillStyle = blendColor("#ffe869", '#FF0000', blendAmount(p));
ctx.strokeStyle = blendColor("#cfbc55", '#FF0000', blendAmount(p));
ctx.lineWidth = 2;
if(checkForFirstFrame(p)){
ctx.fillStyle = "#FFFFFF";
ctx.strokeStyle = "#FFFFFF"
}
for(let i = 0; i < 4; i++){
ctx.lineTo(Math.cos(i * 1.57079) * p.radius, Math.sin(i * 1.57079) *
p.radius);
}
ctx.fill();
ctx.lineTo(Math.cos(4 * 1.57079) * p.radius, Math.sin(4 * 1.57079) *
p.radius);
ctx.stroke();
ctx.closePath();
},
Pentagon: (p) => {
ctx.beginPath();
ctx.fillStyle = blendColor("#768dfc", '#FF0000', blendAmount(p));
ctx.strokeStyle = blendColor("#586bbd", '#FF0000', blendAmount(p));
ctx.lineWidth = 2;
if(checkForFirstFrame(p)){
ctx.fillStyle = "#FFFFFF";
ctx.strokeStyle = "#FFFFFF"
}
for(let i = 0; i < 5; i++){
ctx.lineTo(Math.cos(i * 1.256632) * p.radius, Math.sin(i * 1.256632) *
p.radius);
}
ctx.fill();
ctx.lineTo(Math.cos(5 * 1.256632) * p.radius, Math.sin(5 * 1.256632) *
p.radius);
ctx.stroke();
ctx.closePath();
},
Card: (p) => {
ctx.lineWidth = 3;
ctx.beginPath();
ctx.fillStyle = blendColor('#ffffff', '#FF0000', blendAmount(p));
let border = ctx.strokeStyle = blendColor('#cfcfcf', '#FF0000',
blendAmount(p));
let stripe = blendColor('#202020', '#FF0000', blendAmount(p));
if(checkForFirstFrame(p)){
ctx.fillStyle = "#FFFFFF";
ctx.strokeStyle = "#FFFFFF";
stripe = "#FFFFFF";
border = "#FFFFFF";
}
ctx.beginPath();
ctx.roundRect(-p.radius * 1.2, -p.radius * 0.8, p.radius * 2.4, p.radius *
1.6, p.radius / 4);
ctx.fill();
ctx.closePath();
ctx.strokeStyle = stripe;
ctx.beginPath();
ctx.moveTo(-p.radius * 1.1, p.radius * 0.35);
ctx.lineTo(p.radius * 1.1, p.radius * 0.35);
ctx.stroke();
ctx.closePath();
ctx.strokeStyle = border ;
ctx.beginPath();
ctx.roundRect(-p.radius * 1.2, -p.radius * 0.8, p.radius * 2.4, p.radius *
1.6, p.radius / 4);
ctx.stroke();
ctx.closePath();
},
Custom: (p) => {
const shapes = editorPetalShapesMap[p.customType];
if(shapes === undefined && Math.random() > 0.05){
console.warn('path undefined for petal type ' + p.customType);
return;
}
const lastGA = (p.dying === true && p.insidePetalContainer !== true) ? 1 :
ctx.globalAlpha;
ctx.fillOpacity = 1;
ctx.strokeOpacity = 1;
ctx.lineWidth = .3;
ctx.save();
ctx.scale(p.radius, p.radius);
let blendAmt = blendAmount(p);
if(checkForFirstFrame(p)){
window.overrideBlendColor = [1, "#FFFFFF"];
} else if(blendAmt > 0){
window.overrideBlendColor = [blendAmt, "#FF0000"];
} else {
window.overrideBlendColor = undefined;
}
ctx.setGlobalAlpha(ctx.globalAlpha);
ctx.setFillStyle('#FFFFFF');
ctx.setStrokeStyle('#cfcfcf');
for(let i = 0; i < shapes.length; i++){
ctx.beginPath();
for(let j = 0; j < shapes[i].length; j++){
ctx[shapes[i][j][0]](...shapes[i][j].slice(1));
}
ctx.setGlobalAlpha(ctx.fillOpacity * lastGA);
ctx.fill();
ctx.setGlobalAlpha(ctx.strokeOpacity * lastGA);
ctx.stroke();
ctx.closePath();
ctx.setGlobalAlpha(lastGA, true);
}
ctx.restore();
let updateInfo = [
"Changed the Crafting GUI.",
"Token is now considered an official petal.",
"Gave Waterlogged Compass a render.",
"Some first omnipotent crafts now are credited in their petal's descriptions.",
"+ Several other miscellaneous fixes."
]
if (localStorage.getItem('scripts') == null) {
localStorage.setItem('scripts', JSON.stringify({}))
}
window.scripts = JSON.parse(localStorage.getItem('scripts'))
if (window.scripts.flowrMod == undefined || window.scripts.flowrMod == "") {
window.scripts.flowrMod = {};
localStorage.setItem('scripts', JSON.stringify(scripts));
}
if (window.scripts.flowrMod.betterEntityModels == undefined ||
window.scripts.flowrMod.betterEntityModels == "") {
window.scripts.flowrMod.betterEntityModels = false;
window.flowrMod.betterEntityModels = false
localStorage.setItem('scripts', JSON.stringify(scripts));
} else {
window.flowrMod.betterEntityModels = true
}
if (window.scripts.flowrMod.allGalleryRarities == undefined ||
window.scripts.flowrMod.allGalleryRarities == "") {
window.scripts.flowrMod.allGalleryRarities = false;
window.flowrMod.allGalleryRarities = false;
localStorage.setItem('scripts', JSON.stringify(scripts));
} else {
window.flowrMod.allGalleryRarities = true
}
if (window.scripts.flowrMod.selectSw == undefined ||
window.scripts.flowrMod.selectSw == "") {
window.scripts.flowrMod.selectSw = false;
window.flowrMod.selectSw = false;
localStorage.setItem('scripts', JSON.stringify(scripts));
} else {
window.flowrMod.selectSw = true
}
if (window.scripts.flowrMod.enemyCounter == undefined ||
window.scripts.flowrMod.enemyCounter == "") {
window.scripts.flowrMod.enemyCounter = false;
window.flowrMod.enemyCounter = false;
localStorage.setItem('scripts', JSON.stringify(scripts));
} else {
window.flowrMod.enemyCounter = true
}
if (window.scripts.flowrMod.betterBiomeMobs == undefined ||
window.scripts.flowrMod.betterBiomeMobs == "") {
window.scripts.flowrMod.betterBiomeMobs = false;
window.flowrMod.betterBiomeMobs = false;
localStorage.setItem('scripts', JSON.stringify(scripts));
} else {
window.flowrMod.betterBiomeMobs = true
}
if (window.scripts.flowrMod.blankLadybugs == undefined ||
window.scripts.flowrMod.blankLadybugs == "") {
window.scripts.flowrMod.blankLadybugs = false;
window.flowrMod.blankLadybugs = false;
localStorage.setItem('scripts', JSON.stringify(scripts));
} else {
window.flowrMod.blankLadybugs = true
}
window.flowrMod.PetalLocks =
[false,false,false,false,false,false,false,false,false,false] // Intentionally
doesn't save.
/*if (window.scripts.flowrMod.flowerPetals == undefined ||
window.scripts.flowrMod.flowerPetals == "") {
window.scripts.flowrMod.flowerPetals = false;
window.flowrMod.flowerPetals = false;
localStorage.setItem('scripts', JSON.stringify(scripts));
} else {
window.flowrMod.flowerPetals = true
}*/
if (window.scripts.flowrMod.transparentPetals == undefined ||
window.scripts.flowrMod.transparentPetals == "") {
window.scripts.flowrMod.transparentPetals = false;
window.flowrMod.transparentPetals = false;
localStorage.setItem('scripts', JSON.stringify(scripts));
} else {
window.flowrMod.transparentPetals = true
}
if (window.scripts.flowrMod.florrHealthbars == undefined ||
window.scripts.flowrMod.florrHealthbars == "") {
window.scripts.flowrMod.florrHealthbars = false;
window.flowrMod.florrHealthbars = false;
localStorage.setItem('scripts', JSON.stringify(scripts));
} else {
window.flowrMod.florrHealthbars = true
}
if (window.scripts.flowrMod.autoHover == undefined ||
window.scripts.flowrMod.autoHover == "") {
window.scripts.flowrMod.autoHover = false;
window.flowrMod.autoHover = false;
localStorage.setItem('scripts', JSON.stringify(scripts));
} else {
window.flowrMod.autoHover = true
}
if (window.scripts.flowrMod.simpleWeb == undefined ||
window.scripts.flowrMod.simpleWeb == "") {
window.scripts.flowrMod.simpleWeb = false;
window.flowrMod.simpleWeb = false;
localStorage.setItem('scripts', JSON.stringify(scripts));
} else {
window.flowrMod.simpleWeb = true
}
if (window.scripts.flowrMod.seeLoot == undefined || window.scripts.flowrMod.seeLoot
== "") {
window.scripts.flowrMod.seeLoot = false;
window.flowrMod.seeLoot = false;
localStorage.setItem('scripts', JSON.stringify(scripts));
} else {
window.flowrMod.seeLoot = true
}
if (window.scripts.flowrMod.clientCount == undefined ||
window.scripts.flowrMod.clientCount == "") {
window.scripts.flowrMod.clientCount = false;
window.flowrMod.clientCount = false;
localStorage.setItem('scripts', JSON.stringify(scripts));
} else {
window.flowrMod.clientCount = true
}
if (window.scripts.flowrMod.autoEnableDebug == undefined ||
window.scripts.flowrMod.autoEnableDebug == "") {
window.scripts.flowrMod.autoEnableDebug = false;
window.flowrMod.autoEnableDebug = false;
localStorage.setItem('scripts', JSON.stringify(scripts));
} else {
window.flowrMod.autoEnableDebug = true
}
if (window.scripts.flowrMod.selfName == undefined ||
window.scripts.flowrMod.selfName == "") {
window.scripts.flowrMod.selfName = false;
window.flowrMod.selfName = false;
localStorage.setItem('scripts', JSON.stringify(scripts));
} else {
window.flowrMod.selfName = true
}
if (window.scripts.flowrMod.noFancy == undefined || window.scripts.flowrMod.noFancy
== "") {
window.scripts.flowrMod.noFancy = false;
window.flowrMod.noFancy = false;
localStorage.setItem('scripts', JSON.stringify(scripts));
} else {
window.flowrMod.noFancy = true
}
if (window.scripts.flowrMod.alwaysShowHp == undefined ||
window.scripts.flowrMod.alwaysShowHp == "") {
window.scripts.flowrMod.alwaysShowHp = false;
window.flowrMod.alwaysShowHp = false;
localStorage.setItem('scripts', JSON.stringify(scripts));
} else {
window.flowrMod.alwaysShowHp = true
}
if (window.scripts.flowrMod.attempts == undefined ||
window.scripts.flowrMod.attempts == "") {
window.scripts.flowrMod.attempts = false;
window.flowrMod.attempts = false;
localStorage.setItem('scripts', JSON.stringify(scripts));
} else {
window.flowrMod.attempts = true
}
if (window.scripts.flowrMod.pearlHealth == undefined ||
window.scripts.flowrMod.pearlHealth == "") {
window.scripts.flowrMod.pearlHealth = false;
window.flowrMod.pearlHealth = false;
localStorage.setItem('scripts', JSON.stringify(scripts));
} else {
window.flowrMod.pearlHealth = true
}
window.flowrMod.theme = {
main: '#deb53e',
border: '#a1863b',
dark: '#877032',
highlight: '#fad97a'
}
window.flowrMod.squadTheme = {
main: '#689ed6',
border: '#537fac',
darkmain: '#1c1c1c',
darkborder: '#080808',
darkslidermain: '#ffffff',
darksliderborder: '#bbbbbb'
}
window.flowrMod.buildSaverTheme = {
Border: '#a1863b',
Main: '#deb53e',
DarkBorder: '#080808',
DarkMain: '#1c1c1c'
}
this.options.sort((a, b) => {
let g = -1
if (a.name.toUpperCase() > b.name.toUpperCase()) g = 1
return g
})
this.x = 200;
this.y = 20;
this.w = 256 + 45;
this.h = 10 + 50 * 8;
this.scrollbar = {
scroll: 0,
top: 12,
bottom: 50 + 12,
hovering: false,
scrolling: false,
render: {
scroll: 0,
}
}
this.prevMouse = { mouseX: 0, mouseY: 0 }
this.descPercent = 0
this.isHoverOption = { hovering: false, info: {} }
}
toggle() {
this.active = !this.active;
if (this.active) {
// open
this.targetOffset = 0;
} else {
// close
this.targetOffset = -this.h - 125;
}
}
drawIcon(alpha = 1) {
if (alpha !== 1) {
ctx.globalAlpha = alpha;
}
ctx.fillStyle = window.flowrMod.theme.main
ctx.strokeStyle = window.flowrMod.theme.border;
if (window.state === 'menu') {
if (mouse.canvasX + 6 > 110 && mouse.canvasY + 6 > 20 && mouse.canvasX
- 6 < 110 + 60 && mouse.canvasY - 6 < 20 + 60) {
ctx.fillStyle = window.flowrMod.theme.highlight;
setCursor('pointer');
this.hoveringOverButton = true;
} else {
// if(this.hoveringOverX === false){
// document.body.style.cursor = 'auto';
// }
this.hoveringOverButton = false;
}
} else if (window.state === 'game') {
if (mouse.canvasX + 6 > 75 && mouse.canvasY + 6 > 10 && mouse.canvasX -
6 < 75 + 45 && mouse.canvasY - 6 < 10 + 45) {
ctx.fillStyle = window.flowrMod.theme.border;
setCursor('pointer');
this.hoveringOverButton = true;
} else {
// if(this.hoveringOverX === false){
// document.body.style.cursor = 'auto';
// }
this.hoveringOverButton = false;
}
}
ctx.lineWidth = window.state === 'game' ? 5 : 6;
ctx.beginPath();
window.state === 'game' ? ctx.roundRect(75, 10, 45, 45, 8) :
ctx.roundRect(110, 20, 60, 60, 8);
ctx.fill();
ctx.stroke();
ctx.closePath();
let path =
'data:image/svg+xml;base64,PHN2ZyB2ZXJzaW9uPSIxLjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9y
Zy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIHdpZHRoPSI
3OTguMzAyNjkiIGhlaWdodD0iNzk4LjMwMjY5IiB2aWV3Qm94PSIwLDAsNzk4LjMwMjY5LDc5OC4zMDI2OS
I+PGcgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMjEuMDEzMjEsNzMuNTA1NykiPjxnIGRhdGEtcGFwZXItZGF0Y
T0ieyZxdW90O2lzUGFpbnRpbmdMYXllciZxdW90Ozp0cnVlfSIgZmlsbC1ydWxlPSJub256ZXJvIiBzdHJv
a2UtbWl0ZXJsaW1pdD0iMTAiIHN0cm9rZS1kYXNoYXJyYXk9IiIgc3Ryb2tlLWRhc2hvZmZzZXQ9IjAiIHN
0eWxlPSJtaXgtYmxlbmQtbW9kZTogbm9ybWFsIj48ZyBmaWxsPSIjZmZmZmZmIiBzdHJva2U9IiNmZmZmZm
YiIHN0cm9rZS13aWR0aD0iMSIgc3Ryb2tlLWxpbmVjYXA9InJvdW5kIiBzdHJva2UtbGluZWpvaW49InJvd
W5kIiBmb250LWZhbWlseT0iJnF1b3Q7SGVsdmV0aWNhIE5ldWUmcXVvdDssIEhlbHZldGljYSwgQXJpYWws
IHNhbnMtc2VyaWYiIGZvbnQtd2VpZ2h0PSI0MDAiIGZvbnQtc2l6ZT0iMTUiIHRleHQtYW5jaG9yPSJzdGF
ydCIvPjxnIHN0cm9rZS1saW5lY2FwPSJidXR0IiBzdHJva2UtbGluZWpvaW49Im1pdGVyIj48cGF0aCBkPS
JNMTM1Ljc1MzY1LDYwMS4xODg3M2wtMTAzLjUzNDA4LC00NTguNzQwOTZjMCwwIDEzNC45OTM0OSwxNDYuN
TQyODcgMTg2LjUyNTQzLDE0OS4zMzUwN2M1NC40NTU1MSwyLjk1MDkyIDE2MC45OTg4OSwtMjAwLjEzNjI1
IDE2MC45OTg4OSwtMjAwLjEzNjI1bC0wLjg0MTY4LDUwOS41NDIxNHoiIGZpbGw9IiNmZmZmZmYiIHN0cm9
rZT0ibm9uZSIgc3Ryb2tlLXdpZHRoPSIwIi8+PHBhdGggZD0iTTQuMTEwMzMsMTM0LjA4Nzk0YzAsLTE2Lj
MyMzE0IDEzLjIzMjQ1LC0yOS41NTU2IDI5LjU1NTU5LC0yOS41NTU2YzE2LjMyMzE0LDAgMjkuNTU1NTgsM
TMuMjMyNDYgMjkuNTU1NTgsMjkuNTU1NmMwLDE2LjMyMzE0IC0xMy4yMzI0NCwyOS41NTU1OSAtMjkuNTU1
NTgsMjkuNTU1NTljLTE2LjMyMzE0LDAgLTI5LjU1NTU5LC0xMy4yMzI0NSAtMjkuNTU1NTksLTI5LjU1NTU
5eiIgZmlsbD0iI2ZmZmZmZiIgc3Ryb2tlPSJub25lIiBzdHJva2Utd2lkdGg9IjAiLz48cGF0aCBkPSJNMz
QyLjMzMjExLDcwLjYyMDkyYzAsLTE5Ljc3NTQxIDE2LjAzMDg5LC0zNS44MDYzIDM1LjgwNjMsLTM1LjgwN
jNjMTkuNzc1NDEsMCAzNS44MDYzMSwxNi4wMzA4OSAzNS44MDYzMSwzNS44MDYzYzAsMTkuNzc1NDEgLTE2
LjAzMDg5LDM1LjgwNjMgLTM1LjgwNjMxLDM1LjgwNjNjLTE5Ljc3NTQxLDAgLTM1LjgwNjMsLTE2LjAzMDg
5IC0zNS44MDYzLC0zNS44MDYzeiIgZmlsbD0iI2ZmZmZmZiIgc3Ryb2tlPSJub25lIiBzdHJva2Utd2lkdG
g9IjAiLz48cGF0aCBkPSJNMzc3LjM3NDM0LDYwMS4xODg3M2wtMS44ODEwNywtNTA5LjU0MjE0YzAsMCAxM
DcuNTgyNzcsMjAzLjA4NzE3IDE2Mi4wMzgwMSwyMDAuMTM2MjVjNTEuNTMxNjcsLTIuNzkyMjEgMTg2LjUy
NTQzLC0xNDkuMzM1MDcgMTg2LjUyNTQzLC0xNDkuMzM1MDdsLTEwMy41MzQwOCw0NTguNzQwOTZ6IiBkYXR
hLXBhcGVyLWRhdGE9InsmcXVvdDtpbmRleCZxdW90OzpudWxsfSIgZmlsbD0iI2ZmZmZmZiIgc3Ryb2tlPS
Jub25lIiBzdHJva2Utd2lkdGg9IjAiLz48cGF0aCBkPSJNNzIyLjYxMDM2LDE2My42NDM1M2MtMTYuMzIzM
TQsMCAtMjkuNTU1NTksLTEzLjIzMjQ1IC0yOS41NTU1OSwtMjkuNTU1NTljMCwtMTYuMzIzMTQgMTMuMjMy
NDUsLTI5LjU1NTYgMjkuNTU1NTksLTI5LjU1NTZjMTYuMzIzMTQsMCAyOS41NTU4NiwxMy4yMzI0NiAyOS4
1NTU4NiwyOS41NTU2YzAsMTYuMzIzMTQgLTEzLjIzMjcyLDI5LjU1NTU5IC0yOS41NTU4NiwyOS41NTU1OX
oiIGRhdGEtcGFwZXItZGF0YT0ieyZxdW90O2luZGV4JnF1b3Q7Om51bGx9IiBmaWxsPSIjZmZmZmZmIiBzd
HJva2U9Im5vbmUiIHN0cm9rZS13aWR0aD0iMCIvPjxwYXRoIGQ9Ik0xMTkuMTIwOTIsNjE0LjI1MTM1YzAs
MCAtMjUuMTI4MjQsMS44NTQyNSAtMzQuMDI0MDksLTMyLjAyMjc4Yy02LjczNjg5LC0yNS42NTQ3OCAzMi4
wMjI3NywtNjIuMzI3IDMyLjAyMjc3LC02Mi4zMjdsNDg4LjM0NTMxLDI1LjAxNzc0djY5LjMzMjA0eiIgZm
lsbD0iI2ZmZmZmZiIgc3Ryb2tlPSJub25lIiBzdHJva2Utd2lkdGg9IjAiLz48cGF0aCBkPSJNMTQ5LjM1N
jM1LDYxNC4yNTEzNXYtNjkuMzMyMDRsNDg4LjM0NTMsLTI1LjAxNzc0YzAsMCAzOC43NTk2NywzNi42NzIy
MiAzMi4wMjI3OCw2Mi4zMjdjLTguODk1ODUsMzMuODc2NzYgLTM0LjAyNDEsMzIuMDIyNzggLTM0LjAyNDE
sMzIuMDIyNzh6IiBkYXRhLXBhcGVyLWRhdGE9InsmcXVvdDtpbmRleCZxdW90OzpudWxsfSIgZmlsbD0iI2
ZmZmZmZiIgc3Ryb2tlPSJub25lIiBzdHJva2Utd2lkdGg9IjAiLz48cGF0aCBkPSJNLTIxLjAxMzE4LDcyN
C43OTY5N3YtNzk4LjMwMjY0aDc5OC4zMDI2NHY3OTguMzAyNjR6IiBmaWxsPSJub25lIiBzdHJva2Utb3Bh
Y2l0eT0iMC4wMDgwNiIgc3Ryb2tlPSIjMDAwMDAwIiBzdHJva2Utd2lkdGg9IjAuMDAwMDUiLz48L2c+PC9
nPjwvZz48L3N2Zz4='
let image = new Image();
image.src = path;
window.state === 'game' ? ctx.drawImage(image, 75 + 5.625, 10 + 5.625, 45 -
11.25, 45 - 11.25) : ctx.drawImage(image, 110 + 7.5, 20 + 7.5, 60 - 15, 60 - 15)
ctx.globalAlpha = 1;
}
draw() {
this.scrollbar.render.scroll = interpolate(this.scrollbar.render.scroll,
this.scrollbar.scroll, 0.01 * dt)
this.scrollbar.scroll = Math.max(0, Math.min(1, this.scrollbar.scroll))
ctx.textBaseline = 'left';
ctx.fontKerning = "none";
ctx.letterSpacing = "-.1px";
this.offset = interpolate(this.offset, this.targetOffset, 0.3);
this.currentHeight = 5;
if (this.x < mouse.canvasX && this.x + this.w > mouse.canvasX && this.y <
mouse.canvasY && this.y + this.h > mouse.canvasY) {
if (this.isHoverOption.hovering === true) {
this.descPercent = interpolate(this.descPercent, 1, 0.1)
} else {
this.descPercent = interpolate(this.descPercent, 0, 0.1)
if (this.descPercent < 0.01) this.descPercent = 0
}
} else {
this.descPercent = interpolate(this.descPercent, 0, 0.1)
if (this.descPercent < 0.01) this.descPercent = 0
}
if (this.descPercent !== 0) {
this.drawDesc(this.isHoverOption.info)
}
ctx.fillStyle = window.flowrMod.theme.main;
ctx.strokeStyle = window.flowrMod.theme.border;
ctx.lineWidth = 10;
ctx.save();
ctx.beginPath();
ctx.roundRect(0, this.h+17, this.w, 65, 3);
ctx.fill();
ctx.stroke();
ctx.closePath();
ctx.fillStyle = window.flowrMod.theme.border;
ctx.beginPath();
ctx.rect(10, this.h+27, this.w-20, 45);
ctx.fill();
ctx.closePath();
ctx.lineWidth = 10;
ctx.fillStyle = window.flowrMod.theme.main;
ctx.strokeStyle = window.flowrMod.theme.border;
ctx.beginPath();
ctx.roundRect(0, 0, this.w, this.h, 3);
ctx.fill();
ctx.stroke();
ctx.clip()
ctx.closePath();
ctx.strokeStyle = this.scrollbar.hovering ? '#ffffff' :
window.flowrMod.theme.border;
ctx.beginPath();
ctx.moveTo(this.w - 12.5, this.scrollbar.top + this.scrollbar.render.scroll
* (this.h - 75))
ctx.lineTo(this.w - 12.5, this.scrollbar.bottom +
this.scrollbar.render.scroll * (this.h - 75))
ctx.stroke();
ctx.closePath();
if (this.descPercent !== 0) {
ctx.beginPath();
ctx.roundRect((this.w + 12.5) * this.descPercent, Math.max(this.y - 20,
Math.min(this.y - 20 + this.h - (this.h / 2), (mouse.canvasY - 15) - this.h / 6)),
this.w, this.h / 2, 3);
ctx.fill();
ctx.stroke();
ctx.font = `900 22px 'Ubuntu'`;
ctx.textAlign = "left";
ctx.textBaseline = "center";
ctx.strokeStyle = '#333333';
/**************/
/* FUNCTIONS */
/*************/
window.calculateStats()
petalRotationNaturalRotate.Wing = 0.01
e.maxVertexOffset = offset;
// sometimes we're offset from the circle. We want to offset the position
to make sure we're centered
e.averageX = 0;
e.averageY = 0;
for (let i = 0; i < verticies.length; i++) {
e.averageX += verticies[i].randX;
e.averageY += verticies[i].randY;
}
e.averageX /= verticies.length;
e.averageY /= verticies.length;
return verticies;
}
enemyRenderMap[type] = (e) => {
if (e.rarity === 7 && easterEgg === true) {
if (e.image === undefined || e.image.onload === undefined) {
e.image = new Image();
e.image.src =
'https://memes.co.in/memes/update/uploads/2021/12/InShot_20211209_222013681-
1024x1024.jpg';
e.image.onload = () => {
e.imageLoaded = true;
}
}
// e.ticksSinceLastDamaged = 1;
ctx.beginPath();
ctx.moveTo(e.getVertexX(0), e.getVertexY(0));
for (let i = 0; i < e.data.length; i++) {
ctx.lineTo(e.getVertexX(i), e.getVertexY(i));
}
ctx.lineTo(e.getVertexX(0), e.getVertexY(0));
ctx.fill();
ctx.stroke();
ctx.closePath();
}
}
ctx.lineWidth = e.render.radius / 3;
let body = blendColor(e.team === "flower" ? "#fbea6f" : e.data === 0 ?
"#ad1617" : bodyColor, "#FF0000", Math.max(0, blendAmount(e)));
let bodyBorder = blendColor(e.team === "flower" ? "#cfbd53" : e.data ===
0 ? "#8b1312" : bodyBorderColor, "#FF0000", Math.max(0, blendAmount(e)));
if (checkForFirstFrame(e)) {
body = "#ffffff"; //"#FFFFFF";
bodyBorder = "#ffffff" //'#cecece';//blendColor("#FFFFFF", "#000000",
0.19);
}
ctx.rotate(e.render.angle);
//Front things
ctx.fillStyle = "#333333";
//Body
ctx.lineJoin = "round";
ctx.lineCap = "round"
ctx.lineWidth = e.render.radius * 0.19310344827586207;
ctx.strokeStyle = bodyBorder;
ctx.fillStyle = body;
ctx.beginPath();
ctx.lineTo(e.render.radius * -1.01, e.render.radius * 0);
ctx.bezierCurveTo(e.render.radius * -1.1, e.render.radius * -1.01,
e.render.radius * 1.1, e.render.radius * -1.01, e.render.radius * 1,
e.render.radius * 0);
ctx.bezierCurveTo(e.render.radius * 1.1, e.render.radius * 1.01,
e.render.radius * -1.1, e.render.radius * 1.01, e.render.radius * -1.01,
e.render.radius * 0);
ctx.fill();
ctx.stroke();
ctx.closePath();
//Middle Line
ctx.beginPath();
ctx.lineTo(e.render.radius * -0.51, e.render.radius * 0);
ctx.quadraticCurveTo(e.render.radius * 0.01, e.render.radius * -0.06,
e.render.radius * 0.5, e.render.radius * 0);
ctx.stroke();
ctx.closePath();
//Dots
ctx.fillStyle = bodyBorder;
ctx.beginPath();
ctx.arc(e.render.radius * -0.43, e.render.radius * -0.3, e.render.radius *
0.12413793103448276, 0, Math.PI * 2);
ctx.fill();
ctx.closePath();
ctx.beginPath();
ctx.arc(e.render.radius * -0.01, e.render.radius * -0.38, e.render.radius *
0.12413793103448276, 0, Math.PI * 2);
ctx.fill();
ctx.closePath();
ctx.beginPath();
ctx.arc(e.render.radius * 0.43, e.render.radius * -0.3, e.render.radius *
0.12413793103448276, 0, Math.PI * 2, 18, 0, Math.PI * 2);
ctx.fill();
ctx.closePath();
ctx.beginPath();
ctx.fillStyle = bodyBorder;
ctx.arc(e.render.radius * -0.43, e.render.radius * 0.3, e.render.radius *
0.12413793103448276, 0, Math.PI * 2);
ctx.fill();
ctx.closePath();
ctx.beginPath();
ctx.arc(e.render.radius * -0.01, e.render.radius * 0.38, e.render.radius *
0.12413793103448276, 0, Math.PI * 2);
ctx.fill();
ctx.closePath();
ctx.beginPath();
ctx.arc(e.render.radius * 0.43, e.render.radius * 0.3, e.render.radius *
0.12413793103448276, 0, Math.PI * 2, 18, 0, Math.PI * 2);
ctx.fill();
ctx.closePath();
ctx.rotate(-e.render.angle);
}
}
// main body
ctx.strokeStyle = bodyBorder;
ctx.fillStyle = body;
ctx.beginPath();
ctx.arc(0, 0, e.render.radius, (5.9375 / 5) * Math.PI, (4.0625 / 5) *
Math.PI);
ctx.quadraticCurveTo(-0.4 * e.render.radius, 0, Math.cos((5.9375 / 5) *
Math.PI) * e.render.radius, Math.sin((5.9375 / 5) * Math.PI) * e.render.radius);
ctx.closePath();
ctx.fill();
ctx.save();
ctx.clip();
// ladybug spots
if (!window.flowrMod.blankLadybugs) {
ctx.fillStyle = spot;
for (let i = 0; i < (Math.ceil(e.rarity ** 1.5) * 3) + 9; i += 3) {
ctx.beginPath();
ctx.arc((-0.5 + e.data[i]) * e.render.radius / 30 * 35, (-0.5 +
e.data[i + 1] * e.render.radius / 30 * 35), e.render.radius / 30 * (5 + e.data[i +
2] * 5), 0, Math.PI * 2);
ctx.fill();
ctx.closePath();
}
}
ctx.restore();
ctx.beginPath();
ctx.arc(0, 0, e.render.radius, (5.9375 / 5) * Math.PI, (4.0625 / 5) *
Math.PI);
ctx.quadraticCurveTo(-0.4 * e.render.radius, 0, Math.cos((5.9375 / 5) *
Math.PI) * e.render.radius, Math.sin((5.9375 / 5) * Math.PI) * e.render.radius);
ctx.stroke();
ctx.closePath();
ctx.rotate(-e.render.angle - Math.PI);
}
}
ctx.rotate(e.render.angle);
if (e.data !== 0) {
for (let i = 8; i > 0; i--) {
let offset = Math.cos(e.render.time / 500 + i * Math.PI / 4);
ctx.rotate(Math.PI * 1 / 4 * i)
ctx.beginPath();
ctx.moveTo(e.render.radius * 0.8, 0);
ctx.quadraticCurveTo(e.render.radius * 0.9, 0, e.render.radius *
1.5, e.render.radius * 0.2 * offset)
ctx.stroke();
ctx.closePath();
ctx.rotate(-Math.PI * 1 / 4 * i)
}
}
ctx.rotate(-e.render.angle)
ctx.globalAlpha *= 1.3;
ctx.lineWidth = e.render.radius / 12;
ctx.beginPath();
ctx.arc(0, 0, e.render.radius * 23 / 24, 0, Math.PI * 2);
ctx.stroke();
ctx.closePath();
ctx.globalAlpha *= 0.5;
ctx.beginPath();
ctx.arc(0, 0, e.render.radius * 22 / 24, 0, Math.PI * 2);
ctx.fill();
ctx.closePath();
ctx.rotate(-e.render.angle);
ctx.globalAlpha = savedAlpha;
}
}
ctx.rotate(e.render.angle)
//Claws
ctx.fillStyle = legColor;
ctx.strokeStyle = legColor;
ctx.lineWidth = e.radius * 0.09565217391304348;
ctx.beginPath();
ctx.lineTo(e.render.radius * (0.45 - xTranslate), e.render.radius * (-0.88
- yTranslate));
ctx.quadraticCurveTo(e.render.radius * (1.03 - xTranslate), e.render.radius
* (-1.15 - yTranslate), e.render.radius * (1.25 - xTranslate), e.render.radius * (-
0.62 - yTranslate))
ctx.lineTo(e.render.radius * (1.01 - xTranslate), e.render.radius * (-0.77
- yTranslate))
ctx.lineTo(e.render.radius * (1.11 - xTranslate), e.render.radius * (-0.52
- yTranslate))
ctx.quadraticCurveTo(e.render.radius * (0.85 - xTranslate), e.render.radius
* (-0.72 - yTranslate), e.render.radius * (0.7 - xTranslate), e.render.radius * (-
0.73 - yTranslate))
ctx.fill();
ctx.stroke();
ctx.closePath();
ctx.rotate(-rotateAngle)
ctx.translate(-e.render.radius * xTranslate, -e.render.radius *
yTranslate);
xTranslate = 0.69;
yTranslate = 0.39;
ctx.translate(e.render.radius * xTranslate, e.render.radius * yTranslate);
rotateAngle = -Math.cos(e.render.time / 9) / 6;
ctx.rotate(rotateAngle)
ctx.beginPath();
ctx.lineTo(e.render.radius * (0.45 - xTranslate), e.render.radius * (0.88 -
yTranslate));
ctx.quadraticCurveTo(e.render.radius * (1.03 - xTranslate), e.render.radius
* (1.15 - yTranslate), e.render.radius * (1.25 - xTranslate), e.render.radius *
(0.62 - yTranslate))
ctx.lineTo(e.render.radius * (1.01 - xTranslate), e.render.radius * (0.77 -
yTranslate))
ctx.lineTo(e.render.radius * (1.11 - xTranslate), e.render.radius * (0.52 -
yTranslate))
ctx.quadraticCurveTo(e.render.radius * (0.85 - xTranslate), e.render.radius
* (0.72 - yTranslate), e.render.radius * (0.7 - xTranslate), e.render.radius *
(0.73 - yTranslate))
ctx.fill();
ctx.stroke();
ctx.closePath();
ctx.rotate(-rotateAngle)
ctx.translate(-e.render.radius * xTranslate, -e.render.radius *
yTranslate);
//Legs
ctx.lineWidth = e.render.radius / 4;
ctx.rotate(Math.PI / 2);
ctx.rotate(-rotateAmount);
ctx.rotate(-Math.PI / 2);
//Main body
ctx.lineJoin = 'round';
ctx.lineCap = "round"
ctx.strokeStyle = outline;
ctx.fillStyle = fill;
ctx.lineWidth = e.radius * 0.1826086956521739;
//Body structure
ctx.beginPath();
ctx.ellipse(0, 0, e.radius * 0.8695652173913043, e.radius *
1.1130434782608696, 0, 0, Math.PI * 2);
ctx.fill();
ctx.stroke();
ctx.closePath();
//Patterns on body
ctx.beginPath();
ctx.lineTo(e.render.radius * -0.49, e.render.radius * -0.39);
ctx.quadraticCurveTo(e.render.radius * 0, e.render.radius * -0.16,
e.render.radius * 0.49, e.render.radius * -0.39)
ctx.stroke();
ctx.closePath();
ctx.beginPath();
ctx.lineTo(e.render.radius * -0.49, e.render.radius * 0.39);
ctx.quadraticCurveTo(e.render.radius * 0, e.render.radius * 0.16,
e.render.radius * 0.49, e.render.radius * 0.39)
ctx.stroke();
ctx.closePath();
ctx.rotate(-e.render.angle)
}
}
e.render.lastX = e.render.x;
e.render.lastY = e.render.y;
// legs
ctx.strokeStyle = leg;
ctx.lineWidth = e.render.radius * 0.4;
ctx.beginPath();
ctx.rotate(Math.cos(e.render.time / 52) * 0.25)
ctx.moveTo(e.render.radius * 2.22, e.render.radius * -1.21)
ctx.bezierCurveTo(e.render.radius * 1.64, e.render.radius * -0.30,
e.render.radius * -1.30, e.render.radius * 0, e.render.radius * -2.11,
e.render.radius * 1.59)
ctx.rotate(-Math.cos(e.render.time / 52) * 0.25)
ctx.stroke();
ctx.closePath();
// main body
ctx.strokeStyle = bodyBorder;
ctx.fillStyle = body;
ctx.beginPath();
ctx.arc(0, 0, e.render.radius, 0, 2 * Math.PI);
ctx.fill();
ctx.stroke();
ctx.closePath();
ctx.rotate(-e.render.angle - Math.PI);
}
}
// legs
ctx.strokeStyle = pincerColor;
ctx.lineWidth = e.render.radius * 0.41;
ctx.rotate(e.render.angle);
ctx.beginPath();
ctx.stroke();
ctx.closePath();
ctx.fillStyle = body;
ctx.strokeStyle = bodyBorder;
ctx.rotate(wingAngle);
ctx.ellipse(e.render.radius * -0.98, e.render.radius * -0.54,
e.render.radius * 0.79, e.render.radius * 0.42, 15 * ((Math.PI * 2) / 360), 0,
Math.PI * 2)
ctx.rotate(-wingAngle)
ctx.rotate(-wingAngle)
ctx.ellipse(e.render.radius * -0.98, e.render.radius * 0.54,
e.render.radius * 0.79, e.render.radius * 0.42, -15 * ((Math.PI * 2) / 360), 0,
Math.PI * 2)
ctx.rotate(wingAngle)
ctx.fill();
ctx.closePath();
ctx.globalAlpha *= 1 / 0.3
ctx.fillStyle = body;
ctx.strokeStyle = bodyBorder;
ctx.beginPath();
ctx.arc(e.render.radius * 0.15, e.render.radius * 0, e.render.radius *
0.89, 0, Math.PI * 2)
ctx.fill();
ctx.stroke();
ctx.closePath();
ctx.rotate(-e.render.angle);
}
}
function leechRender() {
enemyRenderMap[type] = (e) => {
if (e.isInEnemyBox || e.isMenuEnemy) {
if (e.isMenuEnemy === true) {
ctx.rotate(e.angle);
}
ctx.lineWidth = e.radius * 0.07;
ctx.strokeStyle = '#292929'
ctx.rotate(-Math.PI * 3 / 4)
ctx.beginPath();
ctx.lineTo(e.render.radius * 0.93, e.render.radius * -0.12);
ctx.quadraticCurveTo(e.render.radius * 1.1, e.render.radius * -0.12,
e.render.radius * 1.25, e.render.radius * 0.16)
ctx.stroke();
ctx.closePath();
ctx.beginPath();
ctx.lineTo(e.render.radius * 0.91, e.render.radius * 0.18);
ctx.quadraticCurveTo(e.render.radius * 0.94, e.render.radius * 0.24,
e.render.radius * 1.13, e.render.radius * 0.3)
ctx.stroke();
ctx.closePath();
ctx.lineJoin = "round";
ctx.lineCap = "round"
ctx.lineWidth = e.radius * 0.455;
ctx.beginPath();
ctx.lineTo(e.render.radius * -0.92, e.render.radius * 0);
ctx.quadraticCurveTo(e.render.radius * 0, e.render.radius * -0.55,
e.render.radius * 0.92, e.render.radius * 0)
ctx.stroke();
ctx.closePath();
ctx.beginPath();
ctx.lineTo(e.render.radius * -0.92, e.render.radius * 0);
ctx.quadraticCurveTo(e.render.radius * 0, e.render.radius * -0.55,
e.render.radius * 0.92, e.render.radius * 0)
ctx.stroke();
ctx.closePath();
ctx.rotate(Math.PI * 3 / 4)
if (e.isMenuEnemy === true) {
ctx.rotate(-e.angle);
}
return;
}
if (!e.childIds) {
return;
}
const isOpaq = ctx.globalAlpha !== 1;
// legs
ctx.strokeStyle = blendColor('#292929', "#FF0000", Math.max(0,
blendAmount(e)));;
ctx.lineWidth = e.render.radius / 2.36;
if (checkForFirstFrame(e)) {
ctx.fillStyle = "#ffffff"; //"#FFFFFF";
ctx.strokeStyle = "#ffffff" //'#cecece';//blendColor("#FFFFFF",
"#000000", 0.19);
}
ctx.rotate(e.render.angle);
ctx.beginPath();
ctx.stroke();
ctx.closePath();
ctx.rotate(-e.render.angle);
ctx.beginPath();
ctx.lineTo(0, 0);
for (let i of e.childIds) {
if (room.enemies[i]) {
ctx.lineTo(room.enemies[i].render.x - e.render.x,
room.enemies[i].render.y - e.render.y);
}
}
ctx.stroke();
ctx.closePath();
ctx.beginPath();
ctx.lineTo(0, 0);
for (let i of e.childIds) {
if (room.enemies[i]) {
ctx.lineTo(room.enemies[i].render.x - e.render.x,
room.enemies[i].render.y - e.render.y);
}
}
ctx.stroke();
ctx.closePath();
}
}
if (checkForFirstFrame(e)) {
inner = "#ffffff"; //"#FFFFFF";
outer = "#ffffff" //'#cecece';//blendColor("#FFFFFF", "#000000", 0.19);
middle = "#ffffff";
}
ctx.fillStyle = outer;
ctx.strokeStyle = ctx.fillStyle;
ctx.lineWidth = e.render.radius * 0.2
ctx.beginPath();
for (let i = 7; i--; i > 0) {
ctx.lineTo(e.render.radius * Math.cos(i * Math.PI / 3), e.render.radius
* Math.sin(i * Math.PI / 3));
}
ctx.fill();
ctx.stroke();
ctx.closePath();
ctx.rotate(-e.renderRotation * 2);
ctx.fillStyle = middle;
ctx.strokeStyle = ctx.fillStyle;
ctx.beginPath();
for (let i = 7; i--; i > 0) {
ctx.lineTo(e.render.radius * Math.cos(i * Math.PI / 3) * 2 / 3.25,
e.render.radius * Math.sin(i * Math.PI / 3) * 2 / 3);
}
ctx.fill();
ctx.stroke();
ctx.closePath();
ctx.rotate(e.renderRotation * 2.5);
ctx.fillStyle = inner;
ctx.strokeStyle = ctx.fillStyle;
ctx.beginPath();
for (let i = 7; i--; i > 0) {
ctx.lineTo(e.render.radius * Math.cos(i * Math.PI / 3) * 1 / 3.25,
e.render.radius * Math.sin(i * Math.PI / 3) * 1 / 3.5);
}
ctx.fill();
ctx.stroke();
ctx.closePath();
ctx.rotate(-e.renderRotation * 1.5);
}
}
// outer color
ctx.lineCap = 'round'
ctx.strokeStyle = outerColor;
ctx.fillStyle = outerColor;
ctx.beginPath(); // stem
ctx.moveTo(p.radius * 1.13, p.radius * 0.54)
ctx.quadraticCurveTo(p.radius * 1.20, p.radius * 0.6, p.radius * 1.16,
p.radius * 0.69)
ctx.quadraticCurveTo(p.radius * 1.13, p.radius * 0.8, p.radius * 1.03,
p.radius * 0.81)
ctx.quadraticCurveTo(p.radius * -0.52, p.radius * 0.14, p.radius * -
0.63, p.radius * -1.13)
ctx.lineTo(p.radius * -0.56, p.radius * -1.13)
ctx.quadraticCurveTo(p.radius * -0.1, p.radius * 0.38, p.radius * 1.13,
p.radius * 0.54)
ctx.lineWidth = p.radius * 0.4
ctx.fill();
ctx.stroke();
ctx.closePath();
ctx.beginPath(); // spines!1!!
ctx.lineWidth = p.radius * 0.4
ctx.moveTo(p.radius * 0.97, p.radius * -0.14);
ctx.quadraticCurveTo(p.radius * 0.91, p.radius * 0.24, p.radius * 0.72,
p.radius * 0.54)
ctx.moveTo(p.radius * 0.82, p.radius * -0.47)
ctx.quadraticCurveTo(p.radius * 0.78, p.radius * -0.13, p.radius *
0.61, p.radius * 0.38)
ctx.moveTo(p.radius * 0.66, p.radius * -0.7)
ctx.quadraticCurveTo(p.radius * 0.64, p.radius * -0.38, p.radius *
0.43, p.radius * 0.26)
ctx.moveTo(p.radius * 0.46, p.radius * -0.79)
ctx.quadraticCurveTo(p.radius * 0.42, p.radius * -0.36, p.radius *
0.22, p.radius * 0.1)
ctx.moveTo(p.radius * 0.26, p.radius * -0.92)
ctx.quadraticCurveTo(p.radius * 0.21, p.radius * -0.59, p.radius *
0.04, p.radius * -0.06)
ctx.moveTo(p.radius * 0.02, p.radius * -0.97)
ctx.quadraticCurveTo(0, p.radius * -0.72, p.radius * -0.14, p.radius *
-0.28)
ctx.moveTo(p.radius * -0.18, p.radius * -1.04)
ctx.quadraticCurveTo(p.radius * -0.17, p.radius * -0.83, p.radius * -
0.29, p.radius * -0.47)
ctx.moveTo(p.radius * -0.38, p.radius * -1.07)
ctx.quadraticCurveTo(p.radius * -0.35, p.radius * -0.34, p.radius * -
0.74, p.radius * -0.88)
ctx.moveTo(p.radius * -0.76, p.radius * -0.59)
ctx.quadraticCurveTo(p.radius * -0.61, p.radius * -0.49, p.radius * -
0.4, p.radius * -0.46)
ctx.moveTo(p.radius * -0.78, p.radius * -0.34)
ctx.quadraticCurveTo(p.radius * -0.61, p.radius * -0.26, p.radius * -
0.3, p.radius * -0.24)
ctx.moveTo(p.radius * -0.69, p.radius * -0.06)
ctx.quadraticCurveTo(p.radius * -0.47, p.radius * -0.04, p.radius * -
0.15, p.radius * -0.09)
ctx.moveTo(p.radius * -0.65, p.radius * 0.14)
ctx.quadraticCurveTo(p.radius * -0.47, p.radius * 0.15, p.radius *
0.05, p.radius * 0.05)
ctx.moveTo(p.radius * -0.53, p.radius * 0.33)
ctx.quadraticCurveTo(p.radius * -0.18, p.radius * 0.32, p.radius *
0.12, p.radius * 0.2)
ctx.quadraticCurveTo(p.radius * -0.19, p.radius * 0.31, p.radius *
0.12, p.radius * 0.20)
ctx.moveTo(p.radius * -0.35, p.radius * 0.5)
ctx.quadraticCurveTo(p.radius * 0.02, p.radius * 0.47, p.radius * 0.27,
p.radius * 0.35)
ctx.moveTo(p.radius * -0.08, p.radius * 0.63)
ctx.quadraticCurveTo(p.radius * 0.15, p.radius * 0.6, p.radius * 0.49,
p.radius * 0.47)
ctx.moveTo(p.radius * 0.26, p.radius * 0.72)
ctx.quadraticCurveTo(p.radius * 0.5, p.radius * 0.72, p.radius * 0.72,
p.radius * 0.54)
ctx.stroke();
// inner color
ctx.strokeStyle = innerColor;
ctx.fillStyle = innerColor;
ctx.beginPath(); // stem
ctx.moveTo(p.radius * 1.13, p.radius * 0.54)
ctx.quadraticCurveTo(p.radius * 1.20, p.radius * 0.6, p.radius * 1.16,
p.radius * 0.69)
ctx.quadraticCurveTo(p.radius * 1.13, p.radius * 0.8, p.radius * 1.03,
p.radius * 0.81)
ctx.quadraticCurveTo(p.radius * -0.52, p.radius * 0.14, p.radius * -
0.63, p.radius * -1.13)
ctx.lineTo(p.radius * -0.56, p.radius * -1.13)
ctx.quadraticCurveTo(p.radius * -0.1, p.radius * 0.38, p.radius * 1.13,
p.radius * 0.54)
ctx.lineWidth = p.radius * 0.1
ctx.stroke();
ctx.fill();
ctx.closePath();
ctx.lineCap = 'square'
ctx.beginPath(); // curvy leaf
ctx.lineWidth = p.radius * 0.1
ctx.moveTo(p.radius * 0.72, p.radius * 0.54)
ctx.quadraticCurveTo(p.radius * 0.3, p.radius * 0.97, p.radius * -0.49,
p.radius * 0.13)
ctx.quadraticCurveTo(p.radius * -0.92, p.radius * -0.44, p.radius * -
0.57, p.radius * -0.98)
ctx.quadraticCurveTo(p.radius * -0.2, p.radius * -1.01, p.radius *
0.24, p.radius * -0.8)
ctx.quadraticCurveTo(p.radius * 1.31, p.radius * -0.2, p.radius * 0.72,
p.radius * 0.54)
ctx.stroke();
ctx.closePath()
ctx.beginPath(); // spines!1!!
ctx.lineWidth = p.radius * 0.125
ctx.moveTo(p.radius * 0.97, p.radius * -0.14);
ctx.quadraticCurveTo(p.radius * 0.91, p.radius * 0.24, p.radius * 0.72,
p.radius * 0.54)
ctx.moveTo(p.radius * 0.82, p.radius * -0.47)
ctx.quadraticCurveTo(p.radius * 0.78, p.radius * -0.13, p.radius *
0.61, p.radius * 0.38)
ctx.moveTo(p.radius * 0.66, p.radius * -0.7)
ctx.quadraticCurveTo(p.radius * 0.64, p.radius * -0.38, p.radius *
0.43, p.radius * 0.26)
ctx.moveTo(p.radius * 0.46, p.radius * -0.79)
ctx.quadraticCurveTo(p.radius * 0.42, p.radius * -0.36, p.radius *
0.22, p.radius * 0.1)
ctx.moveTo(p.radius * 0.26, p.radius * -0.92)
ctx.quadraticCurveTo(p.radius * 0.21, p.radius * -0.59, p.radius *
0.04, p.radius * -0.06)
ctx.moveTo(p.radius * 0.02, p.radius * -0.97)
ctx.quadraticCurveTo(0, p.radius * -0.72, p.radius * -0.14, p.radius *
-0.28)
ctx.moveTo(p.radius * -0.18, p.radius * -1.04)
ctx.quadraticCurveTo(p.radius * -0.17, p.radius * -0.83, p.radius * -
0.29, p.radius * -0.47)
ctx.moveTo(p.radius * -0.38, p.radius * -1.07)
ctx.quadraticCurveTo(p.radius * -0.35, p.radius * -0.34, p.radius * -
0.74, p.radius * -0.88)
ctx.moveTo(p.radius * -0.76, p.radius * -0.59)
ctx.quadraticCurveTo(p.radius * -0.61, p.radius * -0.49, p.radius * -
0.4, p.radius * -0.46)
ctx.moveTo(p.radius * -0.78, p.radius * -0.34)
ctx.quadraticCurveTo(p.radius * -0.61, p.radius * -0.26, p.radius * -
0.3, p.radius * -0.24)
ctx.moveTo(p.radius * -0.69, p.radius * -0.06)
ctx.quadraticCurveTo(p.radius * -0.47, p.radius * -0.04, p.radius * -
0.15, p.radius * -0.09)
ctx.moveTo(p.radius * -0.65, p.radius * 0.14)
ctx.quadraticCurveTo(p.radius * -0.47, p.radius * 0.15, p.radius *
0.05, p.radius * 0.05)
ctx.moveTo(p.radius * -0.53, p.radius * 0.33)
ctx.quadraticCurveTo(p.radius * -0.18, p.radius * 0.32, p.radius *
0.12, p.radius * 0.2)
ctx.quadraticCurveTo(p.radius * -0.19, p.radius * 0.31, p.radius *
0.12, p.radius * 0.20)
ctx.moveTo(p.radius * -0.35, p.radius * 0.5)
ctx.quadraticCurveTo(p.radius * 0.02, p.radius * 0.47, p.radius * 0.27,
p.radius * 0.35)
ctx.moveTo(p.radius * -0.08, p.radius * 0.63)
ctx.quadraticCurveTo(p.radius * 0.15, p.radius * 0.6, p.radius * 0.49,
p.radius * 0.47)
ctx.moveTo(p.radius * 0.26, p.radius * 0.72)
ctx.quadraticCurveTo(p.radius * 0.5, p.radius * 0.72, p.radius * 0.72,
p.radius * 0.54)
ctx.stroke();
ctx.lineCap = 'round'
}
class PetalSlote {
constructor(init){
this.x = init.x;
this.y = init.y;
this.size = init.size;
}
draw(alpha){
ctx.globalAlpha = 0.8 * alpha;
ctx.fillStyle = '#eeeeee';
ctx.strokeStyle = '#bebebe';
ctx.lineWidth = 612;// maybe 5?
ctx.beginPath();
ctx.roundRect(this.x - this.size / 2 + 1, this.y - this.size/2 + 1,
this.size/2 - 2, this.size/2 - 2, this.size / 1);
ctx.fill();
ctx.stroke();
ctx.closePath();
ctx.globalAlpha = 1;
}
}
let topPetals = {}
let prevLoadout = {}
function resetRange() {
topPetals = menuInventory.topPetalContainers
prevLoadout = {}
magnetRange = { "color": "", "range": 0 };
eyeRange = { "color": "", "range": 0 };
for (let i = 0; 10 > i; i++) {
if (topPetals[i] !== undefined) {
if (topPetals[i].type === 'Magnet') {
//console.log(topPetals[i].type, topPetals[i].petalStats.range)
if (topPetals[i].petalStats.range > magnetRange.range) {
magnetRange.range = topPetals[i].petalStats.range
//magnetRange.color =
Colors.rarities[topPetals[i].rarity].color
}
} else if (topPetals[i].type === 'Third Eye') {
//console.log(topPetals[i].type,
topPetals[i].petalStats.extraRange)
if (topPetals[i].petalStats.extraRange > eyeRange.range) {
eyeRange.range = topPetals[i].petalStats.extraRange
//eyeRange.color = Colors.rarities[topPetals[i].rarity].border
}
}
prevLoadout[i] = menuInventory.topPetalContainers[i]
}
}
}
resetRange();
let fadeAlphaMult = 1;
// setting fadeState
if (entity.dead !== true) {
// if(entity.petals !== undefined)console.log(entity.hp, entity.lastHp);
if (Math.ceil(entity.lastHp) < maxHp && Math.ceil(entity.hp) === maxHp) {
entity.fadeTime = time;
entity.fadeState = 'fadeOut';
} else if (Math.ceil(entity.lastHp) === maxHp && Math.ceil(entity.hp) <
maxHp) {
entity.fadeTime = time;
entity.fadeState = 'fadeIn';
}
}
entity.lastShield = entity.shield;
entity.lastHp = entity.hp;
toResetFadeState = false;
if (givenAlpha) {
if (givenAlpha > 0) {
toResetFadeState = entity.fadeState;
entity.fadeState = "visible";
}
}
if (entity.fadeState === 'fadeOut') {
fadeAlphaMult = 1 - (time - entity.fadeTime) / 180;
// if(entity.petals !== undefined){console.log((time -
entity.fadeTime)/4000);}
if (fadeAlphaMult < 0) {
fadeAlphaMult = 0;
entity.fadeState = 'invisible';
}
} else if (entity.fadeState === 'fadeIn') {
fadeAlphaMult = (time - entity.fadeTime) / 180;
if (fadeAlphaMult > 1) {
fadeAlphaMult = 1;
entity.fadeState = 'visible';
}
} else if (entity.fadeState === 'invisible') {
return;
}
if (entity.dead === true) fadeAlphaMult *= ((10 - entity.deadAnimationTimer) /
166) ** 3;
if (givenAlpha) {
fadeAlphaMult = givenAlpha;
// console.log(givenAlpha)
}
const barDimensions = {
w: ((radius / 25) ** 1.2 * 25 * 3.2 + .33) * (isboss === true ? 2.5 : 1 *
(ispearl === true ? 2 : 1)),
h: ((radius / 25) ** 1.2 * 25 * 0.39 + .33) * (isboss === true ? 0.75 : 1),
borderRadius: (radius / 25) ** 1.2 * 25 * 0.25,
innerPadding: (radius / 25) ** 1.05 * 1.8 - .1
}
ctx.globalAlpha = fadeAlphaMult;
hp = Math.max(hp, 0);
beforeStreakHp = Math.max(beforeStreakHp, 0);
ctx.fillStyle = /*isEnemy ? '#131315' : */'#333333';
ctx.beginPath();
ctx.roundRect(x - barDimensions.w / 2, y + radius * 1.775, barDimensions.w,
barDimensions.h, barDimensions.borderRadius);
ctx.fill();
ctx.closePath();
ctx.globalAlpha = 1;
ctx.fillStyle = 'white';
ctx.strokeStyle = 'black';
ctx.lineWidth = 2.25;
ctx.textAlign = 'center';
ctx.textBaseline = 'top';
ctx.font = `900 22px Ubuntu`;// rendering name
if (window.usernames === true) {
ctx.strokeText(flowerName, x, y - radius * 2.75 + barDimensions.h + 2);
ctx.fillText(flowerName, x, y - radius * 2.75 + barDimensions.h + 2);
ctx.font = `900 10px Ubuntu`;// rendering username
ctx.fillStyle = '#bbbbbb';
ctx.strokeText(flowerUsername, x, y - radius * 2 + barDimensions.h +
2);
ctx.fillText(flowerUsername, x, y - radius * 2 + barDimensions.h + 2);
} else {
ctx.strokeText(flowerName, x, y - radius * 2.375 + barDimensions.h +
2);
ctx.fillText(flowerName, x, y - radius * 2.375 + barDimensions.h + 2);
}
}
ctx.globalAlpha = fadeAlphaMult;
if (hp < maxHp / 10) {
ctx.globalAlpha = Math.max(0, hp * .95 / (maxHp / 10) + 0.05) *
fadeAlphaMult;
}
if (hp > 0) {
// green "normal" part of the hp bar
ctx.fillStyle = /*isEnemy ? '#6df12b' : */'#75dd34'
if (isboss === true) {
if (hp < maxHp/2) {
if (hp < maxHp/4) {
ctx.fillStyle ='#de883c'
} else { ctx.fillStyle ='#dbde3c' }
}
}
ctx.beginPath();
ctx.globalAlpha = 1;
ctx.strokeText(`${formatAmountHighPrecision(Math.round(hp * 1000) /
1000)}/${formatAmountHighPrecision(Math.round(maxHp * 1000) / 1000)} ($
{Math.round(hp / maxHp * 1000) / 10}%)`, x + (offset === true ? radius * 3.75 : 0),
y + radius * 1.775 + barDimensions.innerPadding + (barDimensions.h -
barDimensions.innerPadding * 2) / 2)
ctx.fillText(`${formatAmountHighPrecision(Math.round(hp * 1000) / 1000)}/$
{formatAmountHighPrecision(Math.round(maxHp * 1000) / 1000)} (${Math.round(hp /
maxHp * 1000) / 10}%)`, x + (offset === true ? radius * 3.75 : 0), y + radius *
1.775 + barDimensions.innerPadding + (barDimensions.h - barDimensions.innerPadding
* 2) / 2)
}
let fadeAlphaMult = 1;
y = y + ((mob === true && window.flowrMod.florrHealthbars) ? radius : 0)
// setting fadeState
if (entity.dead !== true) {
// if(entity.petals !== undefined)console.log(entity.hp,
entity.lastHp);
if (Math.ceil(entity.lastHp) < maxHp && Math.ceil(entity.hp) === maxHp)
{
entity.fadeTime = time;
entity.fadeState = 'fadeOut';
} else if (Math.ceil(entity.lastHp) === maxHp && Math.ceil(entity.hp) <
maxHp) {
entity.fadeTime = time;
entity.fadeState = 'fadeIn';
}
}
entity.lastShield = entity.shield;
entity.lastHp = entity.hp;
toResetFadeState = false;
if (givenAlpha) {
if (givenAlpha > 0) {
toResetFadeState = entity.fadeState;
entity.fadeState = "visible";
}
}
if (entity.fadeState === 'fadeOut') {
fadeAlphaMult = 1 - (time - entity.fadeTime) / 180;
// if(entity.petals !== undefined){console.log((time -
entity.fadeTime)/4000);}
if (fadeAlphaMult < 0) {
fadeAlphaMult = 0;
entity.fadeState = 'invisible';
}
} else if (entity.fadeState === 'fadeIn') {
fadeAlphaMult = (time - entity.fadeTime) / 180;
if (fadeAlphaMult > 1) {
fadeAlphaMult = 1;
entity.fadeState = 'visible';
}
} else if (entity.fadeState === 'invisible') {
return;
}
if (givenAlpha) {
fadeAlphaMult = givenAlpha;
// console.log(givenAlpha)
}
const barDimensions = {
w: ((radius / 25) ** 1.2 * 25 * 3.2 + .33) * ((mob === true &&
window.flowrMod.florrHealthbars) ? 1.2 : 1),
h: ((radius / 25) ** 1.2 * 25 * 0.39 + .33) * ((mob === true &&
window.flowrMod.florrHealthbars) ? 0.45 : 1),
borderRadius: (radius / 25) ** 1.2 * 25 * 0.25,
innerPadding: (radius / 25) ** 1.05 * 1.8 - .1
}
ctx.globalAlpha = 1;
ctx.fillStyle = 'white';0
ctx.strokeStyle = 'black';
ctx.lineWidth = 2.25;
ctx.textAlign = 'center';
ctx.textBaseline = 'top';
ctx.font = `900 22px Ubuntu`;// rendering name
if (window.usernames === true) {
ctx.strokeText(flowerName, x, y - radius * 2.75 + barDimensions.h +
2);
ctx.fillText(flowerName, x, y - radius * 2.75 + barDimensions.h +
2);
ctx.font = `900 10px Ubuntu`;// rendering username
ctx.fillStyle = '#bbbbbb';
ctx.strokeText(flowerUsername, x, y - radius * 2 + barDimensions.h
+ 2);
ctx.fillText(flowerUsername, x, y - radius * 2 + barDimensions.h +
2);
} else {
ctx.strokeText(flowerName, x, y - radius * 2.375 + barDimensions.h
+ 2);
ctx.fillText(flowerName, x, y - radius * 2.375 + barDimensions.h +
2);
}
}
ctx.globalAlpha = fadeAlphaMult;
if (hp < maxHp / 10) {
ctx.globalAlpha = Math.max(0, hp * .95 / (maxHp / 10) + 0.05) *
fadeAlphaMult;
}
if (hp > 0) {
// green "normal" part of the hp bar
ctx.fillStyle = /*isEnemy ? '#6df12b' : */(color === true ?
'#e3cf36' :'#75dd34')
ctx.beginPath();
ctx.globalAlpha = 1;
ctx.strokeText(`${formatAmountHighPrecision(Math.round(hp * 1000) /
1000)}/${formatAmountHighPrecision(Math.round(maxHp * 1000) / 1000)} ($
{Math.round(hp / maxHp * 1000) / 10}%)`, x, y + (offset === true ? radius * 0.5 :
0) + radius * 1.775 + barDimensions.innerPadding + (barDimensions.h -
barDimensions.innerPadding * 2) / 2)
ctx.fillText(`${formatAmountHighPrecision(Math.round(hp * 1000) /
1000)}/${formatAmountHighPrecision(Math.round(maxHp * 1000) / 1000)} ($
{Math.round(hp / maxHp * 1000) / 10}%)`, x, y + (offset === true ? radius * 0.5 :
0) + radius * 1.775 + barDimensions.innerPadding + (barDimensions.h -
barDimensions.innerPadding * 2) / 2)
}
if (mob === true && window.flowrMod.florrHealthbars) {
ctx.font = `900 ${radius / 2.5}px Ubuntu`
ctx.lineWidth = radius / 12.5
ctx.textAlign = 'left'
ctx.fillStyle = 'white'
ctx.strokeStyle = 'black'
ctx.strokeText(entity.type, x - barDimensions.w / 2, y + radius * 1.46)
ctx.fillText(entity.type, x - barDimensions.w / 2, y + radius * 1.46)
ctx.textAlign = 'right'
ctx.fillStyle = Colors.rarities[entity.rarity].color
ctx.strokeText(Colors.rarities[entity.rarity].name, x + barDimensions.w
/ 2, y + radius * 2.28)
ctx.fillText(Colors.rarities[entity.rarity].name, x + barDimensions.w /
2, y + radius * 2.28)
}
if (toResetFadeState !== false) {
entity.fadeState = toResetFadeState;
}
}
}
renderHpBarr = function renderHpBarr({ x, y, radius, hp, maxHp, beforeStreakHp,
givenAlpha, flowerName, flowerUsername, rarity, mob, shield, offset = false },
entity = { fadeState: undefined, fadeTime: 0, lastHp: hp }) {
// i am stupid. just roll with it.
if (entity.fadeState === undefined) {
if (Math.ceil(entity.hp) === maxHp) {
if (window.flowrMod.alwaysShowHp === true) {
entity.fadeState = 'fadein';
entity.fadeTime = -220;
} else {
entity.fadeState = 'invisible';
entity.fadeTime = -220;
}
} else {
entity.fadeTime = time;
entity.fadeState = 'fadeIn';
}
} else if (Math.ceil(entity.hp) === maxHp + 1) {
entity.fadeState = 'invisible';
entity.fadeTime = -220;
}
if (entity.lastHp === undefined) {
entity.lastHp = entity.hp;
}
let fadeAlphaMult = 1;
// setting fadeState
if (entity.dead !== true) {
// if(entity.petals !== undefined)console.log(entity.hp, entity.lastHp);
if (Math.ceil(entity.lastHp) < maxHp && Math.ceil(entity.hp) === maxHp) {
entity.fadeTime = time;
entity.fadeState = 'fadeOut';
} else if (Math.ceil(entity.lastHp) === maxHp && Math.ceil(entity.hp) <
maxHp) {
entity.fadeTime = time;
entity.fadeState = 'fadeIn';
}
}
entity.lastShield = entity.shield;
entity.lastHp = entity.hp;
toResetFadeState = false;
if (givenAlpha) {
if (givenAlpha > 0) {
toResetFadeState = entity.fadeState;
entity.fadeState = "visible";
}
}
if (entity.fadeState === 'fadeOut') {
fadeAlphaMult = 1 - (time - entity.fadeTime) / 180;
// if(entity.petals !== undefined){console.log((time -
entity.fadeTime)/4000);}
if (fadeAlphaMult < 0) {
fadeAlphaMult = 0;
entity.fadeState = 'invisible';
}
} else if (entity.fadeState === 'fadeIn') {
fadeAlphaMult = (time - entity.fadeTime) / 180;
if (fadeAlphaMult > 1) {
fadeAlphaMult = 1;
entity.fadeState = 'visible';
}
} else if (entity.fadeState === 'invisible') {
return;
}
if (givenAlpha) {
fadeAlphaMult = givenAlpha;
// console.log(givenAlpha)
}
const barDimensions = {
w: (radius / 25) ** 1.2 * 25 * 3.2 + .33,
h: (radius / 25) ** 1.2 * 25 * 0.39 + .33,
borderRadius: (radius / 25) ** 1.2 * 25 * 0.25,
innerPadding: (radius / 25) ** 1.05 * 1.8 - .1
}
ctx.globalAlpha = fadeAlphaMult;
hp = Math.max(hp, 0);
beforeStreakHp = Math.max(beforeStreakHp, 0);
ctx.fillStyle = /*isEnemy ? '#131315' : */'#333333';
ctx.beginPath();
ctx.roundRect(x - barDimensions.w / 2, y + radius * 1.775, barDimensions.w,
barDimensions.h, barDimensions.borderRadius);
ctx.fill();
ctx.closePath();
ctx.globalAlpha = 1;
ctx.fillStyle = 'white';
ctx.strokeStyle = 'black';
ctx.lineWidth = 2.25;
ctx.textAlign = 'center';
ctx.textBaseline = 'top';
ctx.font = `900 22px Ubuntu`;// rendering name
if (window.usernames === true) {
ctx.strokeText(flowerName, x, y - radius * 2.75 + barDimensions.h + 2);
ctx.fillText(flowerName, x, y - radius * 2.75 + barDimensions.h + 2);
ctx.font = `900 10px Ubuntu`;// rendering username
ctx.fillStyle = '#bbbbbb';
ctx.strokeText(flowerUsername, x, y - radius * 2 + barDimensions.h +
2);
ctx.fillText(flowerUsername, x, y - radius * 2 + barDimensions.h + 2);
} else {
ctx.strokeText(flowerName, x, y - radius * 2.375 + barDimensions.h +
2);
ctx.fillText(flowerName, x, y - radius * 2.375 + barDimensions.h + 2);
}
}
ctx.globalAlpha = fadeAlphaMult;
if (hp < maxHp / 10) {
ctx.globalAlpha = Math.max(0, hp * .95 / (maxHp / 10) + 0.05) *
fadeAlphaMult;
}
if (hp > 0) {
// green "normal" part of the hp bar
ctx.fillStyle = /*isEnemy ? '#6df12b' : */'#75dd34'
ctx.beginPath();
ctx.globalAlpha = 1;
ctx.lineWidth = 2;
ctx.globalAlpha = 1;
if ((window.flowrMod.detailedBackgrounds !== true ||
window.flowrMod.biomeURLs[biomeManager.currentBiome] === undefined) &&
window.flowrMod.noGrid !== true) {
for (let x = timeOffset - ctx.lineWidth; x <= canvas.w + ctx.lineWidth;
x += tileSize) {
ctx.beginPath();
ctx.moveTo(x, 0);
ctx.lineTo(x, canvas.h);
ctx.stroke();
ctx.closePath();
}
}
// renderChatMessages();
renderConnectingText();
return;
} else {
menuEnemies = [];
connectingTextSizeMult = 1;
}
ctx.globalAlpha = 1;
let tileOffset = {}
}
ctx.lineWidth = canvas.w * 2 + canvas.h * 2;
ctx.beginPath();
ctx.strokeStyle = 'black';
ctx.globalAlpha = 0.08;
ctx.arc(canvas.w / 2 - me.render.headX * renderFov, canvas.h / 2 -
me.render.headY * renderFov, room.radius * renderFov + ctx.lineWidth / 2, 0,
Math.PI * 2);
ctx.stroke();
ctx.closePath();
}
ctx.globalAlpha = 1;
// drawing
let pv = [
'Magnet',
'Pearl',
'Heavy',
'Corn',
'Sponge',
'Egg'
]
if (pv.includes(petal.type) && window.flowrMod.petalHp === true) {
renderHpBar({
x: petal.render.x,
y: petal.render.y - petal.radius,
radius: petal.radius * 2,
hp: petal.hp,
maxHp: petal.maxHp,
beforeStreakHp: 0,
},
{
fadeState: 'fadein',
fadeTime: -220,
lastHp: 0
});
}
}
}
}
ctx.translate(canvas.w / 2, 0);
// if(window.tutorial === true){
// ctx.translate(0, -canvas.h/11.2);
// }
for (let i = 0; i < room.enemyBoxes.length; i++) {
let enemyBox = room.enemyBoxes[i];
enemyBox.update();
if (enemyBox.isBoss) {
ctx.strokeStyle = `hsl(${(time / 10) % 360}, 50%, 40%)`
}
else {
ctx.strokeStyle = Colors.rarities[enemyBox.rarity].border;
if (Colors.rarities[enemyBox.rarity].fancy !== undefined && !
window.flowrMod.noFancy) ctx.strokeStyle =
Colors.rarities[enemyBox.rarity].fancy.border;
}
ctx.beginPath();
if (mouseInBox({x: mouse.x-canvas.w/2, y: mouse.y},{x:
enemyBox.x+enemyBox.w/2, y: enemyBox.y+enemyBox.h/2, w: enemyBox.w, h: enemyBox.h})
== true) {
console.log("Hoveringg!!!!")
}
if (enemyBox.isBoss) {
ctx.fillStyle = `hsl(${(time / 10) % 360}, 30%, 60%)`
}
else {
ctx.fillStyle = Colors.rarities[enemyBox.rarity].color;
if (Colors.rarities[enemyBox.rarity].fancy !== undefined && !
window.flowrMod.noFancy) {
const gradientFill = ctx.createLinearGradient(enemyBox.x -
enemyBox.w / 2, enemyBox.y, enemyBox.x + enemyBox.w / 2, enemyBox.y + enemyBox.h);
createFancyGradient(gradientFill, enemyBox.rarity);
//ctx.fillStyle = `hsl(${Math.cos(Date.now()/400)*35 + 285}, 100%,
15%)`
ctx.fillStyle = gradientFill;
}
}
ctx.beginPath();
let coef = 0.92;
let miniCoef = (1 - coef) / 2;
ctx.roundRect(enemyBox.x - enemyBox.w / 2 + enemyBox.w * miniCoef,
enemyBox.y + enemyBox.h * miniCoef, enemyBox.w * coef, enemyBox.h * coef, 2.5);
ctx.lineWidth = 5.25
ctx.fill();
ctx.stroke()
if (star.x < -30 || star.x > 30 || star.y < -30 || star.y > 30) {
//don't draw;
continue;
}
ctx.beginPath();
ctx.fillStyle = grad;
ctx.globalAlpha = 0.3;
ctx.fillStyle = "#fff";
if (enemyBox.amount > 1) {
if (time - enemyBox.lastAmountChangedTime < 100) {
ctx.globalAlpha = smoothstep((time -
enemyBox.lastAmountChangedTime) / 100)
}
ctx.lineWidth = 3;
ctx.font = "900 16px 'Ubuntu'";
ctx.textAlign = "right";
ctx.textBaseline = "middle";
ctx.fillStyle = "white";
ctx.strokeStyle = "black";
ctx.translate(enemyBox.x + enemyBox.w / 2 - 7, enemyBox.y + 18);
ctx.rotate(0.34);
ctx.strokeText("x" + enemyBox.amount, 0, 0)
ctx.fillText("x" + enemyBox.amount, 0, 0)
ctx.rotate(-0.34);
ctx.translate(-(enemyBox.x + enemyBox.w / 2 - 7), -(enemyBox.y + 18))
ctx.globalAlpha = 1;
}
if (enemyBox.delete == true) {
let typeStillExists = false;
for (let j = 0; j < room.enemyBoxes.length; j++) {
let otherBox = room.enemyBoxes[j];
if (otherBox.type == enemyBox.type && otherBox.rarity !=
enemyBox.rarity) {
typeStillExists = true;
}
}
if (typeStillExists) {
for (let j = 0; j < room.enemyBoxes.length; j++) {
let otherBox = room.enemyBoxes[j];
if (otherBox.type == enemyBox.type) {
if (otherBox.rarity > enemyBox.rarity) {
otherBox.targetY -= enemyBoxOverlapSize;
}
}
}
} else {
for (let j = 0; j < room.enemyBoxes.length; j++) {
let otherBox = room.enemyBoxes[j];
if (otherBox.x < enemyBox.x) {
otherBox.targetX += enemyBoxBoundSize / 2;
} else {
otherBox.targetX -= enemyBoxBoundSize / 2;
}
}
}
}
}
ctx.translate(-canvas.w / 2, 0);
// if(window.tutorial === true){
// ctx.translate(0, canvas.h/11.2);
// }
room.enemyBoxes = room.enemyBoxes.filter((e) => !e.delete)
if (bosses.length > 0) {
let health = 1;
for (let i of bosses) {
if (!room.enemies[i]) {
health -= 1 / bosses.length;
}
else {
health -= Math.max(Math.min((room.enemies[i].maxHp -
room.enemies[i].render.hp) / room.enemies[i].maxHp, 1), 0) / bosses.length;
}
}
let firstDivide = 1;
let secondDivide = 1;
let end = "";
}
else if (totalBossHealth < 1e4) {
firstDivide = 10;
secondDivide = 100;
end = "K"
}
else if (totalBossHealth < 1e5) {
firstDivide = 100;
secondDivide = 10;
end = "K"
}
else if (totalBossHealth < 1e6) {
firstDivide = 1000;
secondDivide = 1;
end = "K"
}
else if (totalBossHealth < 1e7) {
firstDivide = 10000;
secondDivide = 100;
end = "M"
}
else if (totalBossHealth < 1e8) {
firstDivide = 100000;
secondDivide = 10;
end = "M"
}
else if (totalBossHealth < 1e9) {
firstDivide = 1000000;
secondDivide = 1;
end = "M"
}
else if (totalBossHealth < 1e10) {
firstDivide = 10000000;
secondDivide = 100;
end = "B"
}
else if (totalBossHealth < 1e11) {
firstDivide = 100000000;
secondDivide = 10;
end = "B"
}
else if (totalBossHealth < 1e12) {
firstDivide = 1000000000;
secondDivide = 1;
end = "B"
}
ctx.letterSpacing = "1px";
ctx.strokeStyle = "black";
ctx.fillStyle = "white";
ctx.lineWidth = 6;
ctx.font = "900 37px 'Ubuntu'";
ctx.textAlign = "center";
ctx.textBaseline = "middle";
ctx.strokeText(room.biomeDisplay, canvas.w / 2, 50)
ctx.fillText(room.biomeDisplay, canvas.w / 2, 50)
ctx.lineWidth = 3;
ctx.letterSpacing = "0.5px";
ctx.font = "900 17px 'Ubuntu'";
ctx.textAlign = "center";
ctx.textBaseline = "top";
ctx.strokeText(text, canvas.w / 2, waveBarY - 8)
ctx.fillText(text, canvas.w / 2, waveBarY - 8)
ctx.letterSpacing = "0px";
ctx.textBaseline = "middle";
if (array1[id] == window.selfId) {
let indicationSize = 35;
renderHpBar({
x: globalIndicationX + indicationSize * 4,
y: globalIndicationY - indicationSize * 3.6,
radius: indicationSize * 1.8,
hp: flower.render.hp,
maxHp: flower.maxHp,
shield: flower.render.shield,
beforeStreakHp: flower.render.beforeStreakHp,
givenAlpha: 1,
offset: true,
color: true
}, flower);
flower.drawFlower(globalIndicationX, globalIndicationY,
indicationSize);
ctx.font = `900 ${indicationSize * 0.75}px Ubuntu`;
ctx.strokeStyle = "black";
ctx.fillStyle = "white";
ctx.textBaseline = "middle";
ctx.strokeText(flower.name, globalIndicationX + indicationSize * 4,
globalIndicationY);
ctx.fillText(flower.name, globalIndicationX + indicationSize * 4,
globalIndicationY);
} else {
let indicationSize = ((window.flowrMod.smallIndicator) ? 18 : 30);
indicationY += indicationSize * 3
renderHpBar({
x: globalIndicationX + indicationSize * 4,
y: indicationY - indicationSize * 3.6,
radius: indicationSize * 1.8,
hp: flower.render.hp,
maxHp: flower.maxHp,
shield: flower.render.shield,
beforeStreakHp: flower.render.beforeStreakHp,
givenAlpha: 1,
offset: true,
color: true
}, flower);
flower.drawFlower(globalIndicationX, indicationY, indicationSize);
ctx.font = `900 ${indicationSize * 0.75}px Ubuntu`;
ctx.strokeStyle = "black";
ctx.fillStyle = "white";
ctx.textBaseline = "middle";
ctx.strokeText(flower.name, globalIndicationX + indicationSize * 4,
indicationY);
ctx.fillText(flower.name, globalIndicationX + indicationSize * 4,
indicationY);
//dead flower
flower = room.squadMembers[array2[id]];
flower.render = { hp: 0, shield: 0, beforeStreakHp: 0 };
flower.maxHp = 100;
flower.drawFlower = Flower.drawDeadFlower;
}
if (array2[id] == window.selfId) {
let indicationSize = 35;
renderHpBar({
x: globalIndicationX + indicationSize * 4,
y: globalIndicationY - indicationSize * 3.6,
radius: indicationSize * 1.8,
hp: flower.render.hp,
maxHp: flower.maxHp,
shield: flower.render.shield,
beforeStreakHp: flower.render.beforeStreakHp,
givenAlpha: 1,
offset: true
}, flower);
flower.drawFlower(globalIndicationX, globalIndicationY,
indicationSize);
ctx.font = `900 ${indicationSize * 0.75}px Ubuntu`;
ctx.strokeStyle = "black";
ctx.fillStyle = "white";
ctx.textBaseline = "middle";
ctx.strokeText(flower.name, globalIndicationX + indicationSize * 4,
globalIndicationY);
ctx.fillText(flower.name, globalIndicationX + indicationSize * 4,
globalIndicationY);
} else {
let indicationSize = ((window.flowrMod.smallIndicator) ? 15 : 25);
indicationY += indicationSize * 3
renderHpBar({
x: globalIndicationX + indicationSize * 4,
y: indicationY - indicationSize * 3.6,
radius: indicationSize * 1.8,
hp: flower.render.hp,
maxHp: flower.maxHp,
shield: flower.render.shield,
beforeStreakHp: flower.render.beforeStreakHp,
givenAlpha: 1,
offset: true
}, flower);
flower.drawFlower(globalIndicationX, indicationY, indicationSize);
ctx.font = `900 ${indicationSize * 0.75}px Ubuntu`;
ctx.strokeStyle = "black";
ctx.fillStyle = "white";
ctx.textBaseline = "middle";
ctx.strokeText(flower.name, globalIndicationX + indicationSize * 4,
indicationY);
ctx.fillText(flower.name, globalIndicationX + indicationSize * 4,
indicationY);
if (self && room.flowers[id]) {
ctx.lineWidth = indicationSize / 7;
let angle = Math.atan2(flower.render.headY - self.render.headY,
flower.render.headX - self.render.headX);
ctx.translate(globalIndicationX, indicationY);
ctx.strokeStyle = "black";
ctx.fillStyle = "white";
ctx.rotate(angle);
ctx.beginPath();
ctx.lineTo(indicationSize * 1.15, -indicationSize * 0.4);
ctx.lineTo(indicationSize * 1.45, 0);
ctx.lineTo(indicationSize * 1.15, indicationSize * 0.4);
ctx.lineTo(indicationSize * 1.15, -indicationSize * 0.4);
ctx.stroke();
ctx.fill();
ctx.rotate(-angle);
ctx.translate(-globalIndicationX, -indicationY);
}
}
}
ctx.globalAlpha = 0.9
ctx.lineWidth = 5
ctx.fillStyle = Colors.rarities[petal.rarity].color
ctx.strokeStyle = Colors.rarities[petal.rarity].border
let ps = menuInventory.topPetalSlots[petal.petalContainerId]
ctx.beginPath()
ctx.roundRect(ps.x - ps.size / 2, ps.y - ps.size * 3 / 2 - 15, ps.size,
ps.size, 2)
ctx.fill()
ctx.stroke()
ctx.closePath();
ctx.beginPath()
ctx.roundRect(ps.x - ps.size / 2, ps.y - ps.size * 3 / 2 - 15, ps.size,
ps.size, 2)
ctx.save()
ctx.clip()
ctx.closePath()
ctx.globalAlpha = 0.3
ctx.strokeStyle = "#000000";
ctx.lineCap = "butt";
ctx.lineWidth = ps.size * 2;
ctx.beginPath()
ctx.arc(ps.x, ps.y - ps.size - 15, ps.size, rpercent - Math.PI * 2 *
smoothstep(percent), rpercent)
ctx.stroke();
ctx.closePath();
ctx.restore();
ctx.globalAlpha = 1
inventory.draw();
levelBar.draw();
settingsMenu.draw();
window.flowrMod.flowrSettingsMenu.draw();
if (settingsMenu.active !== true) {
window.flowrMod.flowrSettingsMenu.drawIcon();
} else if (window.flowrMod.flowrSettingsMenu.active === true &&
settingsMenu.active === true) {
window.flowrMod.flowrSettingsMenu.toggle();
}
//}
// renderChatMessages();
let index = 0
let maxSpawnTime = waveLengthFunc(room.wave) * 30;
ctx.textAlign = 'center'
ctx.lineWidth = 3
ctx.strokeStyle = 'black'
if (window.flowrMod.enemyCounter) {
ctx.font = `900 25px Ubuntu`;
ctx.fillStyle = 'white'
ctx.strokeText(enemyCount+(enemyCount == 1 ? " enemy" : "
enemies"),canvas.w-233, canvas.h-120)
ctx.fillText(enemyCount+(enemyCount == 1 ? " enemy" : " enemies"),canvas.w-
233, canvas.h-120)
}
if (window.flowrMod.pearlAlert && ((room.waveTimer/maxSpawnTime >= 2.4) ||
(room.waveTimer/maxSpawnTime >= 1.2 && enemyCount <= 7))) {
ctx.font = `900 35px Ubuntu`;
ctx.fillStyle = '#f55442'
ctx.strokeText("Swap your Pearls!", canvas.w/2, canvas.h-162)
ctx.fillText("Swap your Pearls!", canvas.w/2, canvas.h-162)
}
if (room.flowers[window.selfId]) {
let index = 1
let flower = room.flowers[window.selfId]
for (let petal of flower.petals) {
if (petal.dead === true) {
petal.hp = petal.maxHp
continue;
}
if (petal.type === 'Pearl' && window.flowrMod.pearlHealth) {
let slot = Math.ceil(petal.petalContainerId)+1
renderHpBarrr({ x: canvas.w-200, y: canvas.h-236-50 * (index - 1),
radius: 50, hp: petal.hp, maxHp: petal.maxHp, beforeStreakHp: 0, givenAlpha: 1,
ispearl: true })
ctx.textAlign = 'center'
ctx.lineWidth = 3
ctx.strokeStyle = 'black'
// ctx.strokeText(enemy.type, canvas.w - 500,
(window.flowrMod.numHP === true ? 100 : 105) +7+ 65 * (index - 1))
// ctx.fillText(enemy.type, canvas.w - 500, (window.flowrMod.numHP
=== true ? 100 : 105) +7 + 65 * (index - 1))
// ctx.strokeText(enemy.type, canvas.w - 450,
(window.flowrMod.numHP === true ? 100 : 105) +7+ 65 * (index - 1))
// ctx.fillText(enemy.type, canvas.w - 450, (window.flowrMod.numHP
=== true ? 100 : 105) +7 + 65 * (index - 1))
// draw x
ctx.strokeStyle = '#90464b';
if (hoverOverX === true) {
ctx.fillStyle = '#c16666';
} else {
ctx.fillStyle = '#c1565e';
}
ctx.lineWidth = 5;
ctx.beginPath();
ctx.roundRect(10, 10, 45, 45, 6);
ctx.fill();
ctx.stroke();
ctx.closePath();
ctx.translate(-2.5, -2.5)
ctx.lineWidth = 7.5;
ctx.lineCap = 'round';
ctx.strokeStyle = '#cccccc';
ctx.beginPath();
ctx.moveTo(25, 25);
ctx.lineTo(45, 45);
ctx.stroke();
ctx.closePath();
ctx.beginPath();
ctx.moveTo(45, 25);
ctx.lineTo(25, 45);
ctx.stroke();
ctx.closePath();
ctx.translate(2.5, 2.5)
// movement indicator
ctx.strokeStyle = 'black'
ctx.lineWidth = 10
function spawnMenuEnemy() {
if (typeof biomeManager === 'undefined') {
// setTimeout(() => {
// spawnMenuEnemy();
// }, 200)
return;
}
const currentBiomeName = biomeManager.getCurrentBiomeData().current;
const biomeTypes = (rareBiomeEnemyMap[currentBiomeName] !== undefined &&
Math.random() < 0.01) ? rareBiomeEnemyMap[currentBiomeName] :
biomeEnemyMap[currentBiomeName];
biomeTypes.push('Square', 'Pentagon')
const radius = Math.random() < 0.0001 ? 360 :
Math.sqrt(menuEnemyIncrementRadii[Math.floor(Math.random() *
menuEnemyIncrementRadii.length)] * (Math.random() * 0.1 + 0.95)) * 8.7;
if (Math.round(Math.random()) === 0) {
menuEnemies.push(new Enemy({
x: - radius * 3,
y: - radius + Math.random() * (canvas.h + radius * 2),
radius,
hp: 100,
maxHp: 100,
id: Math.random(),
type: biomeTypes[Math.floor(Math.random() *
biomeTypes.length)],//enemyTypes[Math.floor(Math.random() * enemyTypes.length)],
rarity: Math.floor(Math.random() * 12),
angle: Math.random() * Math.PI * 2,
angleVel: Math.random() * 0.04 - 0.04 / 2,
xVel: Math.random() < 0.001 ? 20 : (5.8 + (Math.random() ** 3) * 1.5) /
2,// not using xv or yv so that i dont mess anything up
yVel: (Math.random() > 0.5 ? 1 : -1) * (Math.random() ** 3) * 1,
sinTimer: (212 + Math.random() * 46) * Math.random(),
sinVel: Math.random() * .8,
maxSinTimer: 212 + Math.random() * 46,
toRenderUi: false,
isMenuEnemy: true
}))
} else {
menuEnemies.push(new Petal({
radius: radius / 1.5,
type: Object.keys(Descriptions.petals)[Math.floor(Math.random() *
Object.keys(Descriptions.petals).length)],
rarity: Math.floor(Math.random() * 12),
id: Math.random(),
subId: 0,
subStackedId: 0,
dead: false,
hp: 100,
maxHp: 100,
offset: { angle: 0, distance: 0 },
angleOffset: 0,
selfAngle: 0,
render: { selfAngle: 0, x: 0, y: 0 },
stickParentRotation: true,
isProjectile: true,
petalContainerId: 0,
sinTimer: (212 + Math.random() * 46) * Math.random(),
sinVel: Math.random() * .8,
maxSinTimer: 212 + Math.random() * 46,
angle: Math.random() * Math.PI * 2,
angleVel: Math.random() * 0.04 - 0.04 / 2,
xVel: Math.random() < 0.001 ? 20 : (5.8 + (Math.random() ** 3) * 1.5) /
2,// not using xv or yv so that i dont mess anything up
yVel: (Math.random() > 0.5 ? 1 : -1) * (Math.random() ** 3) * 1,
x: - radius / 1.5 * 3,
y: - radius / 1.5 + Math.random() * (canvas.h + radius / 1.5 * 2),
petal: true
}))
}
}
function renderMenuEnemies() {
if (Math.random() < (0.02 + (0.005 * maxRarityObtained / 8) * dt /
16.67)*window.flowrMod.MenuMulti) {
spawnMenuEnemy();
}
// draw and simulate menu enemies
const now = time;
for (let i = 0; i < menuEnemies.length; i++) {
const e = menuEnemies[i];
e.draw();
e.sinTimer += dt / 16.67;
e.angle += e.angleVel * 1 + Math.abs(Math.sin(now / 10000)) / 200 * dt /
16.67;
e.x += e.xVel * dt / 16.67;
e.y += (e.yVel + Math.sin(e.sinTimer / e.maxSinTimer * 2 * Math.PI) *
e.sinVel) * dt / 16.67;
if (e.x > canvas.w + e.radius * 2 + 100) {
// remove
e.toRemove = true;
}
if (e.petal) {
e.render.x = interpolate(e.render.x, e.x, 0.08 * dt / 16.66);
e.render.y = interpolate(e.render.y, e.y, 0.08 * dt / 16.66);
e.selfAngle = e.angle
}
}
menuEnemies = menuEnemies.filter(e => e.toRemove !== true);
ctx.lastTransform7 = ctx.getTransform();
// for(let i = 0; i < menuEnemies.length; i++){
// menuEnemies[i].drawStatsBox();
// }
ctx.setTransform(ctx.lastTransform7);
delete ctx.lastTransform7;
}
// requestAnimationFrame(() => {
// ctx.beginPath();
// ctx.fillStyle = 'red';
// ctx.arc(mouseX, mouseY, 30, 0, Math.PI * 2);
// ctx.fill();
// ctx.closePath();
// })
if (room !== undefined && selfId !== null && window.isDead === true) {
if (deadMenu.hoveringOverButton === true) {
// if(window.tutorial === true){
// // delete window.tutorial;
// // const MenuEl = document.querySelector('.menu');
// // MenuEl.classList.remove('hidden');
// location.reload();
// } else {
deadMenu.rematchRequested = false;
if (deadMenu.acceptedDeath === true || window.is3D === true) {
send({ leaveGame: true, real: true });
}
else {
deadMenu.acceptedDeath = true;
}
// we don't do any initting back to the menu just yet.
// We have to wait until the server acknowledges that we left
// the game (through the acknowledgeleavegame message) and then
// we can reset everything.
// }
} else if (deadMenu.hoveringOverRematchButton === true) {
deadMenu.rematchRequested = true;
send({ rematchRequested: true });
}
}
else if (room !== undefined && selfId !== null && window.isDead !== true) {
// if(globalInventory.menuActive === true){
// // handling intersecting petals in globalInventory. This can
probably be done much more efficiently with % operations but idc
// for(let i = 0; i < numberOfRarities; i++){
// if(globalInventory.petalContainers[i] === undefined){
// continue;
// }
// for(let j = 0; j < globalInventory.petalContainers[i].length; j+
+){
// const petalContainer = globalInventory.petalContainers[i]
[j];
// if(mouseX > petalContainer.x - petalContainer.w/2 && mouseX
< petalContainer.x + petalContainer.w/2 && mouseY > petalContainer.y -
petalContainer.h/2 && mouseY < petalContainer.y + petalContainer.h/2){
// // for now we'll just equip the petal, but in the future
we would want to start a petal drag
// let position = -1;
// for(let i = 0; i < inventory.bottomPetalSlots.length; i+
+){
// if(inventory.bottomPetalContainers[i] === undefined)
{
// position = i;
// break;
// }
// }
// if(position === -1){
// return;
// }
// inventory.addPetalContainer(new
PetalContainer(petalContainer.petals, petalContainer, petalContainer.id, 1), false,
position);
// globalInventory.removePetalContainer(petalContainer);
// return;
// }
// }
// }
// // intersecting globalinventory
// if(mouseX > 130 && mouseY > canvas.h - 700 - 20 && mouseX < 130 +
510 && mouseY < canvas.h - 20){
// return;
// }
// }
// intersecting globalInventory button
// if(mouseX > 20 + 15 && mouseX < 20 + 15 + 80 - 15 * 2 && mouseY >
canvas.h - 20 - 80 + 15 && mouseY < canvas.h - 20 - 80 + 15 + 80 - 15 * 2){//20 +
15, canvas.h - 20 - 80 + 15, 80 - 15 * 2, 80 - 15 * 2
// return;
// }
if (e.button == 0) {
// sendGame({attack: true});
send(['a', true]);
// room.flowers[selfId].attacking = true;
} else if (e.button == 2) {
// sendGame({defend: true});
send(['d', true]);
// room.flowers[selfId].defending = true;
}
if (window.state === "game") inputHandler.updateChat();
}
}
if (typeof room !== "undefined" && selfId !== null && window.isDead !== true) {
if (e.button == 0) {
// sendGame({attack: false});
send(['a', false]);
// room.flowers[selfId].attacking = false;
} else if (e.button == 2) {
// sendGame({defend: false});
send(['d', false]);
// room.flowers[selfId].defending = false;
}
}
let thivpath =
'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAIAAAACACAMAAAD04JH5AAAAAXNSR0IArs4c
6QAAAARnQU1BAACxjwv8YQUAAAAbUExURQAAAP+qAP/CP/
+QAO+5U7UPAIcLAPJjBAAAALJVmAoAAAAJdFJOU///////////
AFNPeBIAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAJHSURBVHhe7dSLcoIwFARQpKL+/
xf3PjYBhA65CURnujutRCLZQ7AdXh8OAQQQQAABBBBAAAEEEEAAAQQQQAABBBBAAAEEEEAAAQQQQAABBBBA
wBmAvEbNYtWA+cJhwDgdQ6kHpCul38cZEkoDAJcOw83G6qhYrQVgffJ6E4Ed+wO8VwGSsTcAvdLvo9v4EYD
121BfMBlIE8BrLeM42lvMlqcB8INuDwSYLU/
LDmwFvXdgI+gMeBfodxKz5WkArAXaLsFseVoAmmW5BJOBVAOS4C2YLE8L4H6/
o1ZGFhlitjjVgEXtnL4AlK7yHYCQohawfQJ2QrtlKkCoAOAuF7U+0GEGFK8bBmB1FOsbG8wAOU7yi48fJgr
Qnl2ADO1FMk0BQQXAVp9v3I8erdd+FeCCowQBvr71rJoRO6/9j+sAurwLULoM6qfHhYBHBmwFqf9agAl2Cd
rv5zW44ii1gLkJ7f78F8EVRwkDZHuVoL9oWsemHjKHK44SA6Ak5/
l8YuSRZvXJTz9AjryVctuf6wD+CPwu9RGg22Pb3wdgPfqnhmoPtsD6ewA2OyACO62fEAyuOEocMAu2APvj8
KdzGcC3wAQ7O5Dvv3jdCkC6zR2A/
ieW04H+KEAFaQ92HkEKPlySKMAEttV6RLPETiP4ZFnCABA86+JgtafmGhCWEuv212CqAEgqzqkRtAEwyPkC
QHi9cwEVW9AA2Lvd92/FcZoAGCzzcUBYcDrgr9N/5XxAMPWLhJ/2floAGLTlnFUaQgABBPx3wOv1C/
Au4j/oD9k6AAAAAElFTkSuQmCC'
let thivimage = new Image();
thivimage.src = thivpath;
let petals = []
let pcStats = {}
let blacklist = [
'radius',
'override',
'knockback',
'damageScalers',
'healScalers',
'petalLayout',
'attackDistanceMult',
'healthScalers',
'pvpOverride',
'stickParentRotation',
'massScalers',
'boss'
]
return pc
}
this.builds[this.data.selectedBuild] = build
}
} else {
const build = {
name: "Unnamed Build",
petals: {
top: {},
bottom: {}
}
}
this.builds.push(build)
}
scripts.flowrMod.savedBuilds = this.builds
localStorage.setItem("scripts", JSON.stringify(scripts))
}
render() {
if (this.data.active === true) {
this.dimensions.y.target = canvas.h - this.dimensions.h - 25
} else {
this.dimensions.y.target = canvas.h
}
this.dimensions.y.val = interpolate(this.dimensions.y.val,
this.dimensions.y.target, 0.01 * dt)
ctx.fillStyle =
window.flowrMod.buildSaverTheme[(window.flowrMod.darkSaver ? 'DarkBorder' :
'Border')]
ctx.strokeStyle =
window.flowrMod.buildSaverTheme[(window.flowrMod.darkSaver ? 'DarkBorder' :
'Border')]
ctx.lineWidth = 5
ctx.beginPath()
ctx.roundRect(this.dimensions.w / 2 - this.dimensions.w / 8, -
this.dimensions.h / 8, this.dimensions.w / 4, this.dimensions.h / 8, 5)
ctx.fill()
ctx.closePath()
if (mouseInBox({
x: mouse.canvasX,
y: mouse.canvasY
}, {
x: canvas.w / 2 - this.dimensions.w / 8,
y: this.dimensions.y.val - this.dimensions.h / 8,
w: this.dimensions.w / 4,
h: this.dimensions.h / 8
})) {
setCursor('pointer')
this.data.selections.main = true
} else {
this.data.selections.main = false
}
ctx.beginPath()
ctx.roundRect(0, 0, this.dimensions.w, this.dimensions.h+125, 5)
ctx.fill()
ctx.stroke()
ctx.closePath()
if (this.data.active == true) {
const leftButtonPos = 35
const rightButtonPos = this.dimensions.w - leftButtonPos
const buttonH = 25
ctx.beginPath()
ctx.rect(leftButtonPos, buttonH, 50, 50)
ctx.fill()
ctx.stroke()
ctx.closePath()
if (mouseInBox({
x: mouse.canvasX,
y: mouse.canvasY
}, {
x: canvas.w / 2 - this.dimensions.w / 2 + leftButtonPos,
y: this.dimensions.y.val + buttonH,
w: 50,
h: 50
}) && this.data.selectedBuild < this.builds.length) {
setCursor('pointer')
this.data.selections.load = true
} else {
this.data.selections.load = false
}
ctx.beginPath()
ctx.rect(leftButtonPos + 60, buttonH, 50, 50)
ctx.fill()
ctx.stroke()
ctx.closePath()
if (mouseInBox({
x: mouse.canvasX,
y: mouse.canvasY
}, {
x: canvas.w / 2 - this.dimensions.w / 2 + leftButtonPos + 60,
y: this.dimensions.y.val + buttonH,
w: 50,
h: 50
})) {
setCursor('pointer')
this.data.selections.save = true
} else {
this.data.selections.save = false
}
ctx.fillStyle = "#ffffff"
ctx.strokeStyle = "#000000"
ctx.lineWidth = 2
ctx.beginPath()
ctx.rect(rightButtonPos - 50, buttonH, 50, 50)
ctx.fill()
ctx.stroke()
ctx.closePath()
if (mouseInBox({
x: mouse.canvasX,
y: mouse.canvasY
}, {
x: canvas.w / 2 - this.dimensions.w / 2 + rightButtonPos - 50,
y: this.dimensions.y.val + buttonH,
w: 50,
h: 50
}) && this.data.selectedBuild < this.builds.length) {
setCursor('pointer')
this.data.selections.right = true
} else {
this.data.selections.right = false
}
ctx.beginPath()
ctx.rect(rightButtonPos - 110, buttonH, 50, 50)
ctx.fill()
ctx.stroke()
ctx.closePath()
if (mouseInBox({
x: mouse.canvasX,
y: mouse.canvasY
}, {
x: canvas.w / 2 - this.dimensions.w / 2 + rightButtonPos - 110,
y: this.dimensions.y.val + buttonH,
w: 50,
h: 50
}) && this.data.selectedBuild > 0) {
setCursor('pointer')
this.data.selections.left = true
} else {
this.data.selections.left = false
}
ctx.beginPath()
ctx.rect(leftButtonPos, buttonH + 60, 50, 50)
ctx.fill()
ctx.stroke()
ctx.closePath()
if (mouseInBox({
x: mouse.canvasX,
y: mouse.canvasY
}, {
x: canvas.w / 2 - this.dimensions.w / 2 + leftButtonPos,
y: this.dimensions.y.val + buttonH + 60,
w: 50,
h: 50
})) {
setCursor('pointer')
this.data.selections.clear = true
} else {
this.data.selections.clear = false
}
if (this.builds[this.data.selectedBuild]) {
const build = this.builds[this.data.selectedBuild]
for (let i = 0, n = Object.keys(build.petals.top).length; i < n; i+
+) {
const size = 42.5
const padding = 10
const miniRatio = 0.75
ctx.globalAlpha *= 0.8
ctx.fillStyle = "#eeeeee"
ctx.strokeStyle = "#bebebe"
ctx.lineWidth = 3.75
ctx.beginPath()
ctx.rect(0, 0, size, size)
ctx.fill()
ctx.stroke()
ctx.closePath()
ctx.globalAlpha *= 1 / 0.8
if (build.petals.top[i]) {
build.petals.top[i].w = size
build.petals.top[i].x = size / 2
build.petals.top[i].y = size / 2
build.petals.top[i].draw()
}
ctx.globalAlpha *= 0.8
ctx.fillStyle = "#eeeeee"
ctx.strokeStyle = "#bebebe"
ctx.lineWidth = 3.75 * miniRatio
ctx.beginPath()
ctx.rect(0, 0, size * miniRatio, size * miniRatio)
ctx.fill()
ctx.stroke()
ctx.closePath()
ctx.globalAlpha *= 1 / 0.8
if (build.petals.bottom[i]) {
build.petals.bottom[i].w = size * miniRatio
build.petals.bottom[i].x = size * miniRatio / 2
build.petals.bottom[i].y = size * miniRatio / 2
build.petals.bottom[i].draw()
}
ctx.strokeText(build.name, 0, -25)
ctx.fillText(build.name, 0, -25)
}
} else {
ctx.font = `900 32px Ubuntu`
ctx.fillStyle = "#ffffff"
ctx.strokeStyle = "#000000"
ctx.lineWidth = 3.2
if (ratio !== 1) {
if (direction === 'right') {
if (window.flowrMod.darkMode !== true) {
ctx.fillStyle = Colors.biomes[last].background;
ctx.strokeStyle = Colors.biomes[last].grid;
} else {
ctx.fillStyle = Colors.biomes[last].darkbackground;
ctx.strokeStyle = Colors.biomes[last].darkgrid;
}
} else {
if (window.flowrMod.darkMode !== true) {
ctx.fillStyle = Colors.biomes[current].background;
ctx.strokeStyle = Colors.biomes[current].grid;
} else {
ctx.fillStyle = Colors.biomes[current].darkbackground;
ctx.strokeStyle = Colors.biomes[current].darkgrid;
}
}
renderBg();
ctx.save();
ctx.beginPath();
if (direction === 'right') {
ctx.rect(0, 0, smoothstep(smoothstep(ratio)) * canvas.w, canvas.h);
} else {
ctx.rect(0, 0, (1 - smoothstep(smoothstep(ratio))) * canvas.w,
canvas.h);
}
ctx.clip();
ctx.closePath();
ctx.restore();
// // tiles
// const timeOffset = (-time/20) % 50;
// ctx.lineWidth = 2;
// ctx.globalAlpha = 0.6;
// for(let x = timeOffset-ctx.lineWidth; x <= canvas.w+ctx.lineWidth;
x+=tileSize){
// ctx.beginPath();
// ctx.moveTo(x, 0);
// ctx.lineTo(x, canvas.h);
// ctx.stroke();
// ctx.closePath();
// }
biomeManager.draw();
renderMenuEnemies();
let height = 25*(4+Math.sin(performance.now()*0.01))
let width = 25*(4-Math.sin(performance.now()*0.01))
ctx.drawImage(thivimage, 125-width*0.5,135-height*0.9,width,height)
ctx.font = "900 14px Ubuntu";
ctx.lineWidth = 4
ctx.textAlign = 'left';
ctx.textBaseline = 'middle';
ctx.strokeStyle = 'black';
ctx.fillStyle = 'white';
ctx.strokeText("V1.5.3", 100,150);
ctx.fillText("V1.5.3", 100,150);
ctx.font = "900 12px Ubuntu";
ctx.lineWidth = 3
for (let i = 0; i < updateInfo.length; i++) {
ctx.strokeText(updateInfo[i], 100,175+i*16);
ctx.fillText(updateInfo[i], 100,175+i*16);
}
changelog.draw();
settingsMenu.draw();
window.flowrMod.flowrSettingsMenu.draw();
if (settingsMenu.active !== true && changelog.active !== true) {
window.flowrMod.flowrSettingsMenu.drawIcon();
} else if (window.flowrMod.flowrSettingsMenu.active === true &&
settingsMenu.active === true) {
window.flowrMod.flowrSettingsMenu.toggle();
}
let attemptsX = canvas.w-400
let attemptsY = 0
let attemptsS = 25
if (window.flowrMod.visAttempts) {
for (let rarity = 1; rarity <= 12; rarity++) {
var attempts = 0;
var petalToCheck = globalInventory.petalContainers[rarity-1];
if (petalToCheck) {
for (let ii = 0; ii < petalToCheck.length; ii++) {
attempts += petalToCheck[ii].attempt;
}
}
ctx.font = "900 "+attemptsS+"px Ubuntu";
ctx.textAlign = 'center';
ctx.textBaseline = 'middle';
ctx.letterSpacing = "-1px";
ctx.lineWidth = attemptsS/6;
ctx.strokeStyle = 'black';
ctx.strokeText(Colors.rarities[rarity].name+" Attempts: "+attempts,
attemptsX,attemptsY+(attemptsS*1.25)*rarity);
ctx.fillStyle =Colors.rarities[rarity].color;
ctx.fillText(Colors.rarities[rarity].name+" Attempts: "+attempts,
attemptsX,attemptsY+(attemptsS*1.25)*rarity);
}
}
// Title text
ctx.font = "900 91px Ubuntu";
ctx.textAlign = 'center';
ctx.textBaseline = 'middle';
ctx.letterSpacing = "-1px";
ctx.lineWidth = 10;
ctx.strokeStyle = 'black'//"#1c8c54";
ctx.strokeText("flowr.fun", canvas.w / 2, canvas.h / 2 - 140);
ctx.fillStyle = 'white';
ctx.fillText("flowr.fun", canvas.w / 2, canvas.h / 2 - 140);
ctx.letterSpacing = "0px";
levelBar.draw();
// ctx.lineWidth = 6;
// ctx.strokeStyle = 'white';
// ctx.lineCap = 'round';
// ctx.strokeText("Flowr.io", canvas.w / 2, canvas.h / 3);
window.flowrMod.BuildSaver.render()
craftingMenu.draw();
globalInventory.draw();
mobGallery.draw();
streakMenu.draw();
}
let server = {
'location': 'Chicago',
'type': 1
}
if (ws.url.split('//')[1].split('.')[0] === 'server2') {
server.location = 'Frankfurt'
server.type = 2
}
window.flowrMod.registeredEnemyTypes.includes('Shiny Ladybug') ||
window.flowrMod.registeredEnemyTypes.includes('Desert Centipede') ||
window.flowrMod.registeredEnemyTypes.includes('Cactus') &&
window.flowrMod.registeredEnemyTypes.includes('Beetle') ||
window.flowrMod.registeredEnemyTypes.includes('Scorpion') &&
window.flowrMod.registeredEnemyTypes.includes('Beetle') ||
window.flowrMod.registeredEnemyTypes.includes('Fire Ant Burrow') &&
window.flowrMod.registeredEnemyTypes.includes('Beetle') ||
window.flowrMod.registeredEnemyTypes.includes('Sandstorm') &&
window.flowrMod.registeredEnemyTypes.includes('Beetle') ||
window.flowrMod.registeredEnemyTypes.includes('Desert Moth') &&
window.flowrMod.registeredEnemyTypes.includes('Beetle') ||
window.flowrMod.registeredEnemyTypes.includes('Locust') &&
window.flowrMod.registeredEnemyTypes.includes('Beetle') ||
window.flowrMod.registeredEnemyTypes.includes('Shell') &&
window.flowrMod.registeredEnemyTypes.includes('Crab') ||
window.flowrMod.registeredEnemyTypes.includes('Starfish') &&
window.flowrMod.registeredEnemyTypes.includes('Jellyfish') ||
window.flowrMod.registeredEnemyTypes.includes('Starfish') &&
window.flowrMod.registeredEnemyTypes.includes('Crab') ||
window.flowrMod.registeredEnemyTypes.includes('Starfish') &&
window.flowrMod.registeredEnemyTypes.includes('Leech') ||
window.flowrMod.registeredEnemyTypes.includes('Starfish') &&
window.flowrMod.registeredEnemyTypes.includes('Sea Urchin') ||
window.flowrMod.registeredEnemyTypes.includes('Starfish') &&
window.flowrMod.registeredEnemyTypes.includes('Sponge')
) {
return;
}
if (window.flowrMod.registeredEnemyTypes.includes('Plastic')) {
window.flowrMod.percents.special -= 13
for (let i = 0; i < 5; i++) {
window.flowrMod.registeredEnemyTypes.push('Filler')
}
}
if (room.waveTimer > 250 && window.flowrMod.registeredEnemyTypes.length <=
4) {
window.flowrMod.percents.special -= 13
for (let i = 0; i < 5; i++) {
window.flowrMod.registeredEnemyTypes.push('Filler')
}
}
}
if (window.flowrMod.percents.special > 100) {
window.flowrMod.percents.special = 100
} else if (window.flowrMod.percents.special < 0) {
window.flowrMod.percents.special = 0
}
}
let petals = []
let pcStats = {}
let allowList = [
'rotateSpeedBuff',
'effect',
'speedBuff',
'passiveHealingBuff',
'spawnSystem',
'lifespan',
'knockbackMass',
'healthBuff',
'damageHeal',
'shield',
'bodyKnockback',
'percentDamagePerDeadFlower',
'waveSpeed'
]
return pc
}
let newMap = {}
document.querySelector('.menu').style.display = "";
closeSquadUI();
// mainWS = new WebSocket(HOST);
// mainWS.binaryType = "arraybuffer";
// initMainWS();
window.selfId = null;
window.state = "menu";
// window.connected = false;
bosses = [];
totalBossHealth = 0;
// window.selfId = null;
delete window.isDead;
setTimeout(() => {
window.connected = true
window.state = 'menu'
}, 1000)
}
}
processGameMesssageMap = newMap
// tiles
let timeOffset = 0
ctx.lineWidth = 2;
ctx.globalAlpha = 1;
if ((window.flowrMod.detailedBackgrounds !== true ||
window.flowrMod.biomeURLs[biomeManager.currentBiome] === undefined) &&
window.flowrMod.noGrid !== true) {
for (let x = timeOffset - ctx.lineWidth; x <= canvas.w + ctx.lineWidth; x
+= tileSize) {
ctx.beginPath();
ctx.moveTo(x, 0);
ctx.lineTo(x, canvas.h);
ctx.stroke();
ctx.closePath();
}
}
/**************/
/* CLASSES */
/*************/
if (key == "spawnSystem"){
stats.push({
type: 'Stat',
name: "SpawnTime",
value: data[1]+'s',
color: '#d4d4d4'
})
stats.push({
type: 'Stat',
name: "SpawnRarity",
value: window.flowrMod.rarities[data[0]].display,
color: window.flowrMod.rarities[data[0]].color
})
stats.push({
type: 'Stat',
name: "MaxSpawnsPerPetal",
value: data[2],
color: '#59d4c1'
})
continue;
}
if (key == "slowdown"){
let max = pc.rarity + 2;
if (max < 4){
max = 4;
}
stats.push({
type: 'Stat',
name: "> Slowdown",
value: "",
color: '#d4d4d4'
})
for(let i = pc.rarity-2; i<max; i++){
if (enemyRarityScalars[i]){
stats.push({
type: 'Stat',
name: enemyRarityScalars[i].name,
value: data[i]+"%",
color: key.includes('Buff') ? "#ff9944" :
statColors[enemyRarityScalars[i].name] ?? 'white'
})
}
}
stats.push({
type: 'Stat',
name: "-:-:-:-",
value: "",
color: '#d4d4d4'
})
continue;
}
if (key == "damageHeal"){
stats.push({
type: 'Stat',
name: "Lifesteal",
value: Math.round(pc.petalStats[key]/pc.petalStats["damage"] *
1000)/10 + "%",
color: '#d4d4d4'
})
continue;
}
if (key == "knockbackMass" || key == "bodyKnockback"){
stats.push({
type: 'Stat',
name: "Knockback",
value: data,
color: '#d4d4d4'
})
continue;
}
if (key == "percentDamagePerDeadFlower"){
stats.push({
type: 'Stat',
name: "ExtraDmg",
value: data +"% / dead flower",
color: '#d4d4d4'
})
continue;
}
if (key == "salt"){
stats.push({
type: 'Stat',
name: "DamageReflected",
value: data +"%",
color: '#d4d4d4'
})
continue;
}
if (key == "waveSpeed"){
stats.push({
type: 'Stat',
name: "WaveSpawningSpeed",
value: data +"s",
color: '#a4ffa4'
})
continue;
}
if (key === "drops"){
dropsData = data;
continue;
}
stats.push({
type: 'Stat',
name: key,
value: data,
color: key.includes('Buff') ? "#ff9944" : statColors[key] ?? 'white'
})
}
let description =
{
type: 'Description',
value: (isPetal ? Descriptions.petals[pc.type] :
Descriptions.enemies[pc.type]) ?? (isPetal ? 'A Mysterious Custom Petal...' : 'A
Mysterious Custom Enemy...')
};
this.damageCount = 0;
this.damageCountCooldown = 0;
this.type = init.type;
this.rarity = init.rarity;
this.radius = init.radius;
if (enemyDataMap[this.type] !== undefined) {
this.data = enemyDataMap[this.type](this);
}
this.dead = false;
this.deadAnimationTimer = 0;
this.xv = 0;
this.yv = 0;
this.team = init.team;
this.render = {};
for (let i = 0; i < enemyInterpolateKeys.length; i++) {
this.render[enemyInterpolateKeys[i]] = this[enemyInterpolateKeys[i]];
}
this.render.angle = this.angle;
this.render.radius = 0;
//if (['Spider', 'Worker Ant', 'Soldier Ant', 'Fire Ant', 'Beetle',
'Scorpion', 'Locust', 'Queen Ant', 'Queen Fire Ant', 'Desert Moth', 'Starfish',
'Crab'].includes(this.type)) {
this.render.lastX = this.render.x;
this.render.lastY = this.render.y;
this.render.time = 0;
//}
this.isHovered = false;
this.statsBoxAlpha = 0;
this.statsBox = null;
}
update(data, startInd) {
if (this.type === 'Locust' && performance.now() - this.createdTime > 200
/*to prevent initial spawning displacement*/) {
// x and y
this.xv = (data[startInd + 1] - this.x) / 10;
this.yv = (data[startInd + 2] - this.y) / 10;
if (Math.sqrt(this.xv ** 2 + this.yv ** 2) > 0.1) {
this.locustLastMoveTime = performance.now();
}
}
for (let i = startInd; i < enemyPackKeys.length + startInd; i++) {
this[enemyPackKeys[i - startInd]] = data[i];
}
return startInd + enemyPackKeys.length;
// let toInferAngle = Math.abs(this.xv) < .1 && Math.abs(this.yv) < .1;
// if(toInferAngle === true && pack.x !== undefined && pack.y !==
undefined){
// // if(this.hasInitAngle !== true){
// // this.hasInitAngle = true;
// // this.angle = Math.atan2(pack.y - this.y, pack.x - this.x);
// // } else {
// this.angle = interpolateDirection(this.angle, Math.atan2(pack.y -
this.y, pack.x - this.x), 0.2);
// // }
// }
// if(pack.dead !== undefined){
// console.log('die');
// }
// if (pack.hp !== undefined && pack.hp < this.hp) {
// this.updateRenderDamage(pack.hp);
// }
// //temp before Serum fixes
// for (let key in pack) {
// this[key] = pack[key];
// }
stats.xp = scalars.xp;
stats.health *= scalars.health;
stats.damage *= scalars.damage;
if (this.type == "Starfish") {
stats.healing =
formatAmountHighPrecision(Math.round(stats.health * 0.007 * 30 * 100) / 100) + "/s"
}
if (this.type == "Jellyfish") {
stats.lightningDamage = Math.round(stats.damage * 1.5 * 1000) /
1000
}
if (stats.poison) {
stats.poison[0] = Math.round(stats.poison[0] * scalars.damage *
1000) / 1000;
stats.poison[1] = Math.round(stats.poison[1] * scalars.damage *
1000) / 1000;
}
if (stats.detectionDistance) {
stats.detectionDistance *= scalars.detectionDistance;
}
stats.mass *= scalars.mass;
this.statsBox = redefineGenerateStatsBox(new PetalContainer([this],
{
x: 0,
y: 0,
w: 50,
h: 50,
toOscillate: false,
amount: 1,
petalStats: stats
}, Math.random(), 1, 0), false, {
x: 0,
y: 0
})
this.statsBox.pc.amount = 1;
this.x = last.x;
this.render.x = last.render.x;
this.y = last.y;
this.render.y = last.render.y;
this.radius = last.radius;
this.render.radius = last.render.radius;
this.rarity = last.rarity;
}
this.statsBoxAlpha += 0.15 * dt / 18;
if (this.statsBoxAlpha > 1) {
this.statsBoxAlpha = 1;
}
ctx.globalAlpha = this.statsBoxAlpha;
} else {
this.statsBoxAlpha -= 0.15 * dt / 18;
if (this.statsBoxAlpha < 0) {
this.statsBoxAlpha = 0;
}
}
if (this.statsBoxAlpha !== 0 && this.statsBox !== null) {
this.statsBox.x = this.render.x - this.statsBox.w / 2
this.statsBox.y = drawBelow ?
this.render.y + this.radius / 2 + 11.5 :
this.render.y - this.statsBox.h - this.radius - 11.5;
if (drawBelow === false && this.statsBox.y < 0) {
this.drawStatsBox(true);
return;
}
ctx.globalAlpha = this.statsBoxAlpha;
this.statsBox.draw();
ctx.globalAlpha = 1;
}
this.isHovered = false;
}
draw() {
this.updateInterpolate();
this.lastTicksSinceLastDamaged = this.ticksSinceLastDamaged;
if (this.ticksSinceLastDamaged == 0) {
if (this.resetDamageCount) {
this.damageCount = 0;
this.resetDamageCount = false;
}
this.damageCount += this.previousTakenDamage;
this.damageCountCooldown = 240;
}
if (this.damageCountCooldown < 0) {
this.resetDamageCount = true;
}
this.damageCountCooldown -= dt;
this.ticksSinceLastDamaged += dt;
if (this.ticksSinceLastDamaged > 166) {
this.beforeStreakHp = this.hp;
}
// we shouldn't need this because we wont be modifying this.render during
the drawing? Idk js gc gives me nightmares
// let translateX = this.render.x;
// let translateY = this.render.y;
ctx.translate(this.render.x, this.render.y);
if (this.dead === true) {
var scalar = 1 + smoothstep(Math.log10(this.deadAnimationTimer * 0.0432
+ 1)) * 0.6;
this.deadAnimationTimer += dt;
ctx.scale(scalar, scalar);
ctx.globalAlpha = smoothstep(Math.max(0, 1 -
Math.cbrt(this.deadAnimationTimer * 0.0048)));
if (this.type === 'Custom') {
window.alphaMult = ctx.globalAlpha;
}
}
// fade in animation stuff happens here
if (enemyRenderMap[this.type]) {
enemyRenderMap[this.type](this);
} else {
enemyRenderMap.default(this);
}
if (this.toRenderUi === true && (this.rarity > 3 ||
(window.flowrMod.alwaysShowHp === true && this.rarity > -1))) {
enemyRenderMapText(this, true);
} else if (this.toRenderUi === true) {
enemyRenderMapText(this, false);
}
if (this.dead === true) {
ctx.scale(1 / scalar, 1 / scalar);
ctx.globalAlpha = 1;
if (this.type === 'Custom') {
delete window.alphaMult;
}
}
ctx.translate(-this.render.x, -this.render.y);
}
// basically predicting what'll happen on server side. This isn't correct but
it'll work for now. Also x and y should always be sent if movement changes (if
xv/yv != 0) so it wont desync
// simulate(room) {
// if (this.dead === true) {
// return;
// }
// this.x += this.xv;
// this.y += this.yv;
// }
}
this.render = {};
this.render.distance = this.distance;
this.render.angle = this.angle;
this.selfAngle = this.angle;
this.render.x = this.x;
this.render.y = this.y;
this.render.reload = this.reload;
this.render.hp = this.hp;
this.dying = false;
this.deadAnimationTimer = 9999;
this.ticksSinceLastDamaged = 9999;
this.insidePetalContainer = false;
this.isProjectile = false;
if (window.isEditor) this.time = 0;
this.particles = {}
this.ticksAlive = 0
}
update(data, parent) {
// if((data.hp !== undefined && data.hp < this.hp) || data.dead === true){
// this.updateRenderDamage(data.hp);
// }
if (data.takeDamage === true && this.shotFlag !== true) {
this.updateRenderDamage();
this.render.hp = data.hp;
}
for (let key in data) {
this[key] = data[key];
}
this.ticksAlive = 0
}
else if (data.dead === false) {
this.dead = false;
this.dying = false;
this.deadAnimationTimer = 9999;
this.selfAngle = this.render.angle;
}
this.render.angle = interpolateDirection(this.render.angle -
parent.petalLag, this.angle, 0.08 * dt / 16.66) + parent.petalLag;
if (petalRotationNaturalRotate[this.type]) {
this.selfAngle += petalRotationNaturalRotate[this.type] * dt;
}
if (petalRotationStickToParent.includes(this.type)) {
this.selfAngle = Math.atan2(this.render.y - parent.render.y,
this.render.x - parent.render.x)
}
if (this.type === 'Custom') {
this.selfAngle = Math.atan2(this.render.y - parent.render.y,
this.render.x - parent.render.x);
}
if (this.type === "Compass") {
if (!this.lastCheckedTime) {
this.lastCheckedTime = 0;
}
if (time > this.lastCheckedTime + 2000) {
this.selfAngle = Math.random() * Math.PI * 2;
this.lastCheckedTime = time;
}
}
}
// simulate(parent){
// // ANGLE
// this.angle = parent.petalRotation + this.angleOffset//this.id /
parent.petals.length * Math.PI * 2;
// // // DISTANCE
// // // florr petals seem to behave like springs
// // // hookes law => just apply a force proportional to the distance
// // this.dv += (parent.petalDistance - this.distance) * dt / 1000 / 2;
// // this.dv *= 0.9 ** dt;
// this.distance += this.dv;
// this.dv *= 0.68;
// // this.render.x = this.renderX;
// // this.render.y = this.renderY;
// // consolp.log(parent.render.x, this.render.angle, this.render.distance,
this.renderX)
// }
// petals dont transmit any data! its just intercepted by the parent
// pack() {
// return;
// }
draw() {
this.lastTicksSinceLastDamaged = this.ticksSinceLastDamaged;
this.ticksSinceLastDamaged += dt;
ctx.translate(this.render.x, this.render.y);
if (this.dying === true) {
// if(this.deadAnimationTimer >= 0 && this.deadAnimationTimer <= 1){
// this.updateRenderDamage(this.hp);
// }
var scalar = 1 + Math.cbrt(Math.log10(Math.max(1,
this.deadAnimationTimer / 16.6))) * 0.6;
ctx.globalAlpha = Math.max(0, 1 - this.deadAnimationTimer / 166);
if (this.type === "Custom") {
window.alphaMult = ctx.globalAlpha;
}
ctx.scale(scalar, scalar);
} else if (this.scaleMult !== undefined) {// else if because petals will
never be dying while in their container
ctx.scale(this.scaleMult, this.scaleMult);
}
ctx.rotate(this.selfAngle);
if ( window.flowrMod.petalRenderMap[this.type])
window.flowrMod.petalRenderMap[this.type](this);
else window.flowrMod.petalRenderMap["Missing"](this);
ctx.rotate(-this.selfAngle);
// tech particle
// triangle with arc at the end
// tip of triangle gets "dragged" as the petal moves
class SquadUI {
constructor(){
this.clients = [];
this.w = 446;
this.h = 0;
this.minimizedHeight = 46;
this.baseHeight = this.h;//this.h;
this.minimized = true;
this.initRenderTimer = 0;
this.hoveringOverX = false;
this.hoveringOverPublic = false;
this.hoveringOverNew = false;
this.hoveringOverPrivate = false;
this.hoveringOverQuickJoin = false;
this.public = true;
this.selfId = null;
this.startingWaveSlider = 1;
this.desiredSWS = 1;
this.draggingSlider = false;
this.maxStartingWave = 1;
this.startingWave = this.maxStartingWave;
}
reset(){
this.clients = [];
this.hoveringOverX = false;
this.hoveringOverPublic = false;
this.hoveringOverNew = false;
this.hoveringOverPrivate = false;
this.hoveringOverQuickJoin = false;
this.public = true;
delete this.lastUnMinimizedTimer;
delete window.squadUICloseTime;
delete this.selfIdSentFlag;
this.h = 0;
}
removeAllClients(){
this.clients = [];
}
startGame(){
this.hoveringOverX = false;
this.hoveringOverPublic = false;
this.hoveringOverNew = false;
this.hoveringOverPrivate = false;
this.hoveringOverQuickJoin = false;
this.clients = [];
this.h = 0;
this.minimized = true;
window.squadUIEnabled = false;
}
recieveData(init){
this.selfId = init.selfId;
// console.log(init);
// ss
// return {
// clients: this.clients.map(c => {
// return {name: c.name, id: c.id};
// })
// }
// for(let i = 0; i < init.clients.length; i++){
// if(this.clients[i] === undefined){
// this.clients[i] = {};
// }
// this.clients[i].name = init.clients[i].name;
// this.clients[i].id = init.clients[i].id;
// }
// this.clients = init.clients;
for(let i = 0; i < init.clients.length; i++){
this.addClient(init.clients[i]);
// if(this.clients[i] === undefined){
// this.clients[i] = this.createClient();
// }
// if(this.clients[i].ready !== init.clients[i].ready){
// if(this.clients[i].ready === true){
// // fade out
// this.clients[i].lastReadyDisableTime = performance.now();
// } else {
// // fade in
// this.clients[i].lastReadyEnableTime = performance.now();
// }
// }
// for(let key in init.clients[i]){
// this.clients[i][key] = init.clients[i][key];
// }
// // console.log(init.clients[i]);
// if(init.clients[i].petals){
// this.updateFlowerPetals(init.clients[i].petals,
this.clients[i].id);
// }
// console.log({[i]:this.clients[i].petals});
}
// update
if(savedStartingWave !== null){
this.desiredSWS = savedStartingWave / this.maxStartingWave;
}
}
updateFlowerPetals(data, id){
if(id === this.selfId){
if(this.selfIdSentFlag === true){
return;
}
if(data.length > 0){
this.selfIdSentFlag = true;
}
}
let cid;
let client;
for(let i = 0; i < this.clients.length; i++){
if(this.clients[i].id === id){
client = this.clients[i];
cid = i;
}
}
if(client === undefined){
return;
}
const f = client.flower;
f.lastPetals = f.petals;
f.petals = [];
const playerWidth = (this.w - playerPadding * 3 - outsidePadding * 2) / 4;
f.render.headX = canvas.w / 2 - this.w/2 + outsidePadding + cid *
(playerWidth + playerPadding) + playerWidth / 2;
f.render.headY = canvas.h / 2 + this.h / 2 + 35 - 9;
f.headX = f.render.headX;
f.headY = f.render.headY;
f.x = f.render.headX;
f.y = f.render.headY;
f.render.x = f.x;
f.render.y = f.y;
f.render.baseX = f.x;
f.render.baseY = f.y;
f.baseX = f.x;
f.baseY = f.y;
// f.fastAngleInitTimer = performance.now();
this.updateFlowerPetalContainers(f);
delete f.lastPetals;
}
updateFlowerPetalContainers(f){
f.petalContainers = []//f.petalContainers.filter(pc => pc.toPreserve ===
true);
let petalsInContainer = [];
for(let i = 0; i < f.petals.length; i++){
//petals,
{x,y,w,h,originalX,originalY,radius,toOscillate,isDragging,lastSlot}, id, amount,
attempt
// console.log(f.petals[i].subStackedId, f.petalContainers);
if(f.petals[i].subId > 0 && f.petals[i].subStackedId === 0){
f.petalContainers[f.petalContainers.length-1].petals.push(new
Petal(f.petals[i]));
continue;
}
petalsInContainer.push(f.petals[i]);
if(f.petals[i].subStackedId === 0){
f.petalContainers.push(new PetalContainer(petalsInContainer.map(p
=> new Petal(p)), {x: 0, y: 0, w: 20, h: 20, originalX: 0, originalY: 0, radius:
100, toRenderText: false, toOscillate: false}, Math.random(), 1));
petalsInContainer = [];
data.offset = {};
data.offset.angle = data.subStackedId / pc.petals.length *
Math.PI * 2;
data.offset.distance = data.radius;
}
f.petals.push(new Petal(data));
const petal = f.petals[f.petals.length-1];
petal.distance = neutralPetalDistance;
petal.render.distance = 0;
petal.updateInterpolate(f);
petal.x = f.baseX;
petal.y = f.baseY;
petal.render.x = petal.x;
petal.render.y = petal.y;
petal.slowInterpolateDistance = true;
}
}
data.offset = {};
data.offset.angle = data.subStackedId / pc.petals.length *
Math.PI * 2;
data.offset.distance = data.radius;
}
f.petals.push(new Petal(data));
const petal = f.petals[f.petals.length-1];
petal.distance = neutralPetalDistance;
petal.render.distance = 0;
petal.updateInterpolate(f);
petal.x = f.baseX;
petal.y = f.baseY;
petal.render.x = petal.x;
petal.render.y = petal.y;
petal.slowInterpolateDistance = true;
}
}
this.updateSelfFlowerPetalContainers(f);
}
updateSelfFlowerPetalContainers(f){
const pcs =
Object.values(menuInventory.topPetalContainers).concat(Object.values(menuInventory.
bottomPetalContainers));
const sbounds = {
x: canvas.w / 2 -(this.w*((window.flowrMod.sleekSquadUI) ? 1.25 : 1))/2
+ outsidePadding + ind * (playerWidth + playerPadding) + 5,
y: canvas.h / 2 + 35 + this.h * 0.15 + Math.max(0, this.h * 0.65 - 22),
w: playerWidth - 5 * 2,
h: (this.h * 0.03 + 34) * 2 + 6
}
const sliderPos = {
x: sliderX,
y: sbounds.y + sbounds.h / 2
}
const sbounds = {
x: canvas.w / 2 - (this.w*((window.flowrMod.sleekSquadUI) ? 1.25 :
1))/2 + outsidePadding + ind * (playerWidth + playerPadding) + 5,
y: canvas.h / 2 + 35 + this.h * 0.15 + Math.max(0, this.h * 0.65 - 22),
w: playerWidth - 5 * 2,
h: (this.h * 0.03 + 34) * 2 + 6
}
const sliderPos = {
x: sliderX,
y: sbounds.y + sbounds.h / 2
}
let closestSliderX = x;
if(closestSliderX < sbounds.x) closestSliderX = sbounds.x;
if(closestSliderX > sbounds.x + sbounds.w) closestSliderX = sbounds.x +
sbounds.w;
if (!window.flowrMod.sleekSquadUI) {
ctx.beginPath();
ctx.roundRect(canvas.w / 2 - (this.w*((window.flowrMod.sleekSquadUI) ?
1.25 : 1))/2, canvas.h / 2 + 30, (this.w*((window.flowrMod.sleekSquadUI) ? 1.25 :
1)),this.h);
ctx.fill();
ctx.stroke();
ctx.closePath();
}
const playerWidth = ((this.w*((window.flowrMod.sleekSquadUI) ? 1.25 : 1)) -
playerPadding * 3 - outsidePadding * 2) / ((window.flowrMod.sleekSquadUI) ? 5 : 4);
ctx.globalAlpha = this.buttonAlpha;
// drawing bg
for(let i = 0; i < Math.max(((window.flowrMod.sleekSquadUI) ? 5 : 4),
this.clients.length); i++){
if(this.minimized === true)continue;
ctx.fillStyle = ((window.flowrMod.darkSquad) ?
window.flowrMod.squadTheme.darkmain : window.flowrMod.squadTheme.main);
ctx.strokeStyle = ((window.flowrMod.darkSquad) ?
window.flowrMod.squadTheme.darkborder : window.flowrMod.squadTheme.border);
ctx.lineWidth = 5;// tbd
ctx.beginPath();
ctx.roundRect(canvas.w / 2 - (this.w*((window.flowrMod.sleekSquadUI) ?
1.25 : 1))/2 + outsidePadding + i * (playerWidth + playerPadding), canvas.h / 2 +
35 + this.h * 0.15, playerWidth, Math.max(0, this.h * 0.65 - 22));
ctx.fill();
ctx.stroke();
ctx.closePath();
ctx.globalAlpha = this.buttonAlpha * 1;
if(now - this.clients[i].creationTime < 400){
ctx.translate(0, (1 - easeOutCubic((now -
this.clients[i].creationTime) / 400)) * this.h * 0.1);
}
}
}
ctx.globalAlpha = 1;
window.camera.disableCulling = true;
// petal boxes
const bounds = {
x: canvas.w / 2 - (this.w*((window.flowrMod.sleekSquadUI) ? 1.25 :
1))/2 + outsidePadding + i * (playerWidth + playerPadding),
y: canvas.h / 2 + 35 + this.h * 0.15 + 22 + offset,
w: playerWidth,
h: this.h * 0.6 - 22
}
const petalContainersPerRow = 4;
pc.draw();
renderIndex++;
}
ctx.translate(f.render.headX, f.render.headY);
ctx.scale(.8,.8);
ctx.translate(-f.render.headX, -f.render.headY);
f.angle = Math.atan2(mouse.canvasY - f.render.headY, mouse.canvasX -
f.render.headX);
if (mouseInBox({ x: mouse.canvasX, y: mouse.canvasY }, bounds) ||
window.flowrMod.autoHover) {
// f.petalAlpha = .2;
if (f.petalAlpha === undefined) {
f.petalAlpha = 1;
}
f.petalAlpha -= dt / 300;
if (window.flowrMod.transparentPetals === true) {
if (f.petalAlpha < 0) {
f.petalAlpha = 0;
}
} else {
if (f.petalAlpha < 0.37) {
f.petalAlpha = 0.37;
}
}
} else if (f.petalAlpha !== undefined) {
f.petalAlpha += dt / 300;
if (f.petalAlpha > 1) {
delete f.petalAlpha;
}
}
// console.log(f.username)
f.drawFlower(f.x-2,f.y,25);
// delete f.petalAlpha;
ctx.translate(f.render.headX, f.render.headY);
ctx.scale(1.25,1.25);
ctx.translate(-f.render.headX, -f.render.headY);
// starting waves
if(this.clients[i].id !== this.selfId){
ctx.fillStyle = 'white';
ctx.strokeStyle = 'black';
ctx.letterSpacing = "-.15px";
ctx.lineWidth = 3;
ctx.textAlign = 'center';
ctx.textBaseline = 'middle';
ctx.font = `900 18px 'Ubuntu'`;
const startingWave = Math.max(1,
Math.ceil(this.clients[i].startingWave));
const maxSW = Math.max(1,this.clients[i].maxSW);
const swTextPos = {
x: canvas.w / 2 - (this.w*((window.flowrMod.sleekSquadUI) ?
1.25 : 1))/2 + outsidePadding + i * (playerWidth + playerPadding) + playerWidth /
2,
y: canvas.h / 2 + 35 + this.h * 0.15 + Math.max(0, this.h *
0.65 - 22) - 12
}
ctx.strokeText('SW: ' + startingWave+"/"+maxSW, swTextPos.x,
swTextPos.y);
ctx.fillText('SW: ' + startingWave+"/"+maxSW, swTextPos.x,
swTextPos.y);
}
ctx.moveTo(-7.5, .5);
ctx.lineTo(-3.5, 7.5);
ctx.lineTo(7.5, -7.5);
ctx.strokeStyle = 'black';
ctx.lineWidth = 5;
ctx.stroke();
ctx.strokeStyle = '#1dd129';
ctx.lineWidth = 2;
ctx.stroke();
delete window.camera.disableCulling;
ctx.globalAlpha = this.buttonAlpha;
// starting wave
if(this.minimized !== true){
this.startingWaveSlider = interpolate(this.startingWaveSlider,
this.desiredSWS, 0.22);
// ctx.fillStyle = '#689ed6';
// ctx.strokeStyle = '#537fac';
ctx.lineWidth = 5;
// const sbounds = {
// x: canvas.w / 2 - this.w / 2 * 0.8,
// y: canvas.h / 2 + this.h - 18 * this.h / 280,
// w: this.w * 0.8,
// h: this.h * 0.1
// };
let ind = 0;
for(let i = 0; i < this.clients.length; i++){
if(this.clients[i].id === this.selfId){
ind = i;
break;
}
}
ind = Math.min(3, ind);
const sbounds = {
x: canvas.w / 2 - (this.w*((window.flowrMod.sleekSquadUI) ? 1.25 :
1))/2 + outsidePadding + ind * (playerWidth + playerPadding) + 5,
y: canvas.h / 2 + 35 + this.h * 0.15 + Math.max(0, this.h * 0.65 -
22),
w: playerWidth - 5 * 2,
h: (this.h * 0.03 + 34) * 2 + 6
}
const sliderPos = {
x: sliderX,
y: sbounds.y + sbounds.h / 2
}
ctx.fillStyle = ((window.flowrMod.darkSquad) ?
window.flowrMod.squadTheme.darkslidermain : window.flowrMod.squadTheme.main);
ctx.strokeStyle = ((window.flowrMod.darkSquad) ?
window.flowrMod.squadTheme.darksliderborder : window.flowrMod.squadTheme.border);
ctx.beginPath();
ctx.moveTo(sbounds.x, sbounds.y + sbounds.h / 2);
ctx.lineTo(sbounds.x + sbounds.w, sbounds.y + sbounds.h / 2);
ctx.stroke();
ctx.closePath();
ctx.beginPath();
ctx.arc(sliderX, sbounds.y + sbounds.h / 2, 12, 0, Math.PI * 2);
ctx.fill();
ctx.stroke();
ctx.closePath();
// hover effect
if((mouse.canvasX - sliderPos.x) ** 2 + (mouse.canvasY - sliderPos.y)
** 2 < 15 ** 2){
ctx.fillStyle = 'white';
ctx.globalAlpha = 0.1;
ctx.beginPath();
ctx.arc(sliderX, sbounds.y + sbounds.h / 2, 12 + ctx.lineWidth / 2,
0, Math.PI * 2);
ctx.fill();
ctx.stroke();
ctx.closePath();
ctx.globalAlpha = 1;
this.hoveringOverSlider = true;
} else if(this.draggingSlider === true){
ctx.fillStyle = 'white';
ctx.globalAlpha = 0.1;
ctx.beginPath();
ctx.arc(sliderX, sbounds.y + sbounds.h / 2, 12 + ctx.lineWidth / 2,
0, Math.PI * 2);
ctx.fill();
ctx.stroke();
ctx.closePath();
ctx.globalAlpha = 1;
}
ctx.fillStyle = 'white';
ctx.strokeStyle = 'black';
ctx.letterSpacing = "-.05px";
ctx.lineWidth = 3;
ctx.textAlign = 'center';
ctx.textBaseline = 'middle';
ctx.font = `900 14px 'Ubuntu'`;
this.startingWave = Math.max(1, Math.ceil(this.maxStartingWave *
this.startingWaveSlider));
ctx.strokeText('Starting Wave: ' + this.startingWave, sbounds.x +
sbounds.w / 2, sbounds.y + 17)
ctx.fillText('Starting Wave: ' + this.startingWave, sbounds.x +
sbounds.w / 2, sbounds.y + 17)
// ctx.beginPath();
// ctx.roundRect(canvas.w / 2 - this.w/2 * 0.8, canvas.h / 2 + this.h -
18 * this.h / 280, this.w * 0.8, this.h * 0.1);
// ctx.fill();
// ctx.stroke();
// ctx.closePath();
}
// the actual x
ctx.lineCap = 'round';
ctx.strokeStyle = '#cccccc';
ctx.beginPath();
ctx.moveTo(canvas.w / 2 + this.w / 2 - 7.5 - 30 + 7.5, canvas.h / 2 + 30 +
7.5 * ratio + 7.5);
ctx.lineTo(canvas.w / 2 + this.w / 2 - 7.5 - 7.5, canvas.h / 2 + 30 + 7.5 *
ratio - 7.5 + 15 + 15 * ratio);
ctx.stroke();
ctx.closePath();
ctx.beginPath();
ctx.moveTo(canvas.w / 2 + this.w / 2 - 7.5 - 7.5, canvas.h / 2 + 30 + 7.5 *
ratio + 7.5);
ctx.lineTo(canvas.w / 2 + this.w / 2 - 7.5 - 30 + 7.5, canvas.h / 2 + 7.5 *
ratio - 7.5 + 15 + 30 + 15 * ratio);
ctx.stroke();
ctx.closePath();
// hover effect
this.hoveringOverX = false;
if(mouse.canvasX > canvas.w / 2 + this.w / 2 - 7.5 - 30 && mouse.canvasY >
canvas.h / 2 + 30 + 7.5 && mouse.canvasX < canvas.w / 2 + this.w / 2 - 7.5 &&
mouse.canvasY < canvas.h / 2 + 30 + 7.5 + 30 * ratio){
ctx.fillStyle = 'white';
ctx.globalAlpha = 0.1;
ctx.beginPath();
ctx.roundRect(canvas.w / 2 + this.w / 2 - 7.5 - 30 - ctx.lineWidth/2,
canvas.h / 2 + 30 + 7.5 - ctx.lineWidth/2, 30 + ctx.lineWidth, 30 * ratio +
ctx.lineWidth, 3);
ctx.fill();
ctx.closePath();
ctx.globalAlpha = 1;
this.hoveringOverX = true;
}
// buttons
ctx.letterSpacing = "-.05px";
ctx.font = `900 ${16 * ratio}px 'Ubuntu'`;
ctx.textAlign = 'center';
ctx.textBaseline = 'middle';
const newButtonWidth = ctx.measureText('New').width;
ctx.fillStyle = ((window.flowrMod.darkSquad) ?
window.flowrMod.squadTheme.darkmain : window.flowrMod.squadTheme.main);
ctx.strokeStyle = ((window.flowrMod.darkSquad) ?
window.flowrMod.squadTheme.darkborder : window.flowrMod.squadTheme.border);
ctx.lineWidth = 5;
ctx.lineWidth = 5;
// ctx.fillStyle = '#f0f0f0';
// ctx.strokeStyle = 'black';
// ctx.lineWidth = 4;
ctx.fillStyle = 'white';
ctx.strokeStyle = 'black';
ctx.lineWidth = newButtonWidth * 0.08866826452;// 3 at max
// ctx.globalAlpha = 0.8;
ctx.strokeText('New', canvas.w / 2 + this.w / 2 - 7.5 - 30 - newButtonWidth
- 7.5 - 30 + (30 + newButtonWidth) / 2, canvas.h / 2 + 30 + 7.5 + (30 * ratio)/2);
// ctx.globalAlpha = 1;
ctx.fillText('New', canvas.w / 2 + this.w / 2 - 7.5 - 30 - newButtonWidth -
7.5 - 30 + (30 + newButtonWidth) / 2, canvas.h / 2 + 30 + 7.5 + (30 * ratio)/2);
ctx.fillStyle = ((window.flowrMod.darkMode) ?
window.flowrMod.squadTheme.darkmain : window.flowrMod.squadTheme.main);
ctx.strokeStyle = ((window.flowrMod.darkMode) ?
window.flowrMod.squadTheme.darkborder : window.flowrMod.squadTheme.border);
ctx.lineWidth = 5;
// hover
// console.log(mouse.canvasX, canvas.w / 2 + this.w / 2 - 7.5 - 30 -
newButtonWidth - 30 - 7.5);
if(
mouse.canvasX > canvas.w / 2 + this.w / 2 - 7.5 - 30 - newButtonWidth -
30 - 7.5 &&
mouse.canvasY > canvas.h / 2 + 30 + 7.5 &&
mouse.canvasX < canvas.w / 2 + this.w / 2 - 7.5 - 30 - newButtonWidth -
30 - 7.5 + 30 + newButtonWidth &&
mouse.canvasY < canvas.h / 2 + 30 + 7.5 + 30 * ratio
){
ctx.fillStyle = 'white';
ctx.globalAlpha *= 0.1;
ctx.beginPath();
ctx.roundRect(canvas.w / 2 + this.w / 2 - 7.5 - 30 - newButtonWidth -
30 - 7.5 - ctx.lineWidth/2, canvas.h / 2 + 30 + 7.5 - ctx.lineWidth/2, 30 +
newButtonWidth + ctx.lineWidth, 30 * ratio + ctx.lineWidth, 3);
ctx.fill();
ctx.closePath();
ctx.globalAlpha = this.buttonAlpha * 1;
this.hoveringOverNew = true;
} else {
this.hoveringOverNew = false;
}
ctx.fillStyle = ((window.flowrMod.darkSquad) ?
window.flowrMod.squadTheme.darkmain : window.flowrMod.squadTheme.main);
ctx.strokeStyle = ((window.flowrMod.darkSquad) ?
window.flowrMod.squadTheme.darkborder : window.flowrMod.squadTheme.border);
ctx.lineWidth = 5;
// find public
const publicButtonWidth = ctx.measureText('Find Public').width;
ctx.beginPath();
ctx.roundRect(canvas.w / 2 + this.w / 2 - 7.5 - 30 - newButtonWidth - 30 -
7.5 - (30 + publicButtonWidth) - 7.5, canvas.h / 2 + 30 + 7.5, 30 +
publicButtonWidth, 30 * ratio, 3);
ctx.fill();
ctx.stroke();
ctx.closePath();
// ctx.fillStyle = '#f0f0f0';
// ctx.strokeStyle = 'black';
// ctx.lineWidth = 4;
ctx.fillStyle = 'white';
ctx.strokeStyle = 'black';
ctx.lineWidth = 0.03603260836 * publicButtonWidth;// 3 at max
// ctx.globalAlpha = 0.8;
ctx.strokeText('Find Public', canvas.w / 2 + this.w / 2 - 7.5 - 30 -
newButtonWidth - 30 - 7.5 - (30 + publicButtonWidth) - 7.5 + (30 +
publicButtonWidth) / 2, canvas.h / 2 + 30 + 7.5 + (30 * ratio)/2);
// ctx.globalAlpha = 1;
ctx.fillText('Find Public', canvas.w / 2 + this.w / 2 - 7.5 - 30 -
newButtonWidth - 30 - 7.5 - (30 + publicButtonWidth) - 7.5 + (30 +
publicButtonWidth) / 2, canvas.h / 2 + 30 + 7.5 + (30 * ratio)/2);
// hovering effect
ctx.lineWidth = 5;
if(
mouse.canvasX > canvas.w / 2 + this.w / 2 - 7.5 - 30 - newButtonWidth -
30 - 7.5 - (30 + publicButtonWidth) - 7.5 &&
mouse.canvasY > canvas.h / 2 + 30 + 7.5 &&
mouse.canvasX < canvas.w / 2 + this.w / 2 - 7.5 - 30 - newButtonWidth -
30 - 7.5 - (30 + publicButtonWidth) - 7.5 + 30 + publicButtonWidth &&
mouse.canvasY < canvas.h / 2 + 30 + 7.5 + 30 * ratio
){
ctx.fillStyle = 'white';
ctx.globalAlpha *= 0.1;
ctx.beginPath();
ctx.roundRect(canvas.w / 2 + this.w / 2 - 7.5 - 30 - newButtonWidth -
30 - 7.5 - (30 + publicButtonWidth) - 7.5 - ctx.lineWidth/2, canvas.h / 2 + 30 +
7.5 - ctx.lineWidth / 2, 30 + publicButtonWidth + ctx.lineWidth, 30 * ratio +
ctx.lineWidth, 3);
ctx.fill();
ctx.closePath();
ctx.globalAlpha = this.buttonAlpha * 1;
this.hoveringOverPublic = true;
} else {
this.hoveringOverPublic = false;
}
ctx.fillStyle = ((window.flowrMod.darkSquad) ?
window.flowrMod.squadTheme.darkmain : window.flowrMod.squadTheme.main);
ctx.strokeStyle = ((window.flowrMod.darkSquad) ?
window.flowrMod.squadTheme.darkborder : window.flowrMod.squadTheme.border);
ctx.lineWidth = 5;
// find private
const privateButtonWidth = ctx.measureText('Private').width;
ctx.beginPath();
ctx.roundRect(canvas.w / 2 + this.w / 2 - 7.5 - 30 - newButtonWidth - 30 -
7.5 - (30 + publicButtonWidth) - 7.5 - (30 + privateButtonWidth) - 7.5, canvas.h /
2 + 30 + 7.5, 30 + privateButtonWidth, 30 * ratio, 3);
ctx.fill();
ctx.stroke();
ctx.closePath();
// ctx.fillStyle = '#f0f0f0';
// ctx.strokeStyle = 'black';
// ctx.lineWidth = 4;
ctx.fillStyle = 'white';
ctx.strokeStyle = 'black';
ctx.lineWidth = 3;
// ctx.globalAlpha = 0.8;
ctx.strokeText('Private', canvas.w / 2 + this.w / 2 - 7.5 - 30 -
newButtonWidth - 30 - 7.5 - (30 + publicButtonWidth) - 7.5 - (30 +
privateButtonWidth) - 7.5 + (30 + privateButtonWidth) / 2, canvas.h / 2 + 30 + 7.5
+ (30 * ratio)/2);
// ctx.globalAlpha = 1;
ctx.fillText('Private', canvas.w / 2 + this.w / 2 - 7.5 - 30 -
newButtonWidth - 30 - 7.5 - (30 + publicButtonWidth) - 7.5 - (30 +
privateButtonWidth) - 7.5 + (30 + privateButtonWidth) / 2, canvas.h / 2 + 30 + 7.5
+ (30 * ratio)/2);
// hovering effect
ctx.lineWidth = 5;
if(
mouse.canvasX > canvas.w / 2 + this.w / 2 - 7.5 - 30 - newButtonWidth -
30 - 7.5 - (30 + publicButtonWidth) - 7.5 - (30 + privateButtonWidth) &&
mouse.canvasY > canvas.h / 2 + 30 + 7.5 &&
mouse.canvasX < canvas.w / 2 + this.w / 2 - 7.5 - 30 - newButtonWidth -
30 - 7.5 - (30 + publicButtonWidth) - 7.5 + 30 + privateButtonWidth - (30 +
privateButtonWidth) &&
mouse.canvasY < canvas.h / 2 + 30 + 7.5 + 30 * ratio
){
ctx.fillStyle = 'white';
ctx.globalAlpha = 0.1;
ctx.beginPath();
ctx.roundRect(canvas.w / 2 + this.w / 2 - 7.5 - 30 - newButtonWidth -
30 - 7.5 - (30 + publicButtonWidth) - 7.5 - (30 + privateButtonWidth) - 7.5 -
ctx.lineWidth/2, canvas.h / 2 + 30 + 7.5 -ctx.lineWidth/2, 30 + privateButtonWidth
+ ctx.lineWidth, 30 * ratio + ctx.lineWidth, 3);
ctx.fill();
ctx.closePath();
ctx.globalAlpha = 1;
this.hoveringOverPrivate = true;
} else {
this.hoveringOverPrivate = false;
}
// (public)
ctx.textAlign = 'right';
ctx.textBaseline = 'bottom';
ctx.strokeText('(Private)', canvas.w / 2 + this.w/2 - 7.5, canvas.h/2 +
this.h - 7.5 + 30);
ctx.fillText('(Private)', canvas.w / 2 + this.w/2 - 7.5, canvas.h/2 +
this.h - 7.5 + 30);
ctx.textAlign = 'middle';
ctx.textBaseline = 'center';
}
ctx.fillStyle = ((window.flowrMod.darkSquad) ?
window.flowrMod.squadTheme.darkmain : window.flowrMod.squadTheme.main);
ctx.strokeStyle = ((window.flowrMod.darkSquad) ?
window.flowrMod.squadTheme.darkborder : window.flowrMod.squadTheme.border);
ctx.lineWidth = 5;
ctx.lineWidth = 5;
ctx.globalAlpha = 1;
}
createClient(id){
const c = {creationTime: performance.now(), flower: new Flower(id)};
const f = c.flower;
const playerWidth = (this.w - playerPadding * 3 - outsidePadding * 2) / 4;
f.petalContainers = [];
f.render.headX = canvas.w / 2 - this.w/2 + outsidePadding +
(this.clients.length) * (playerWidth + playerPadding) + playerWidth / 2;
f.render.headY = canvas.h / 2 + this.h / 2 + 35 - 9;
f.headX = f.render.headX;
f.headY = f.render.headY;
f.x = f.render.headX;
f.y = f.render.headY;
f.render.x = f.x;
f.render.y = f.y;
f.render.baseX = f.x;
f.render.baseY = f.y;
f.baseX = f.x;
f.baseY = f.y;
return c;
}
addClient(data){
this.clients.push(this.createClient(data.id));
const client = this.clients[this.clients.length-1];
client.startingWave = data.sw;
delete client.sw;
if(data.petals){
this.updateFlowerPetals(data.petals, client.id);
}
this.petalContainers[p.rarity].sort();
}
calculateDimensions(mini) {
const petalContainersPerRow = 4;
const padding = 15;
const offsetFromText = 40;
const petalContainerSize = 50//(this.petalContainers[0] ?? {w: 0}).w;
let totalPetalContainers = 0;
if (!mini) {
this.dimensions = {
x: canvas.w - 340,
y: 20,
w: 320,
h: 20 + 2 * padding + offsetFromText + petalContainerSize +
Math.floor((totalPetalContainers - 1) / petalContainersPerRow) *
(petalContainerSize + 12)
//h: canvas.h * .94 - 40// levelbar is at canvas.h * .94. 20px of
margin looks good
}
} else {
this.dimensions = {
x: canvas.w - 340,
y: 20,
w: 320,
h: 20 + 2 * padding + offsetFromText + petalContainerSize +
Math.floor((16 - 1) / petalContainersPerRow) * (petalContainerSize + 12)
//h: canvas.h * .94 - 40// levelbar is at canvas.h * .94. 20px of
margin looks good
}
}
this.w = this.dimensions.w;
this.h = this.dimensions.h;
}
draw(mini) {
this.calculateDimensions(mini);
ctx.fillStyle = 'black';
ctx.lineWidth = 8;
ctx.translate(this.dimensions.x, this.dimensions.y);
ctx.globalAlpha = 0.5;
ctx.beginPath();
ctx.roundRect(0, 0, this.w, this.h, 5);
ctx.fill();
ctx.globalAlpha = 1;
ctx.closePath();
ctx.fillStyle = '#f0f0f0';
ctx.strokeStyle = 'black';
ctx.font = `900 24px 'Ubuntu'`;
ctx.textAlign = "center";
ctx.textBaseline = "middle";
ctx.lineWidth = 3;
ctx.strokeText("Collected this run", this.w / 2, (padding + offsetFromText)
/ 2);
ctx.fillText("Collected this run", this.w / 2, (padding + offsetFromText) /
2);
if (!mini) {
let renderIndex = 0;
for (let i = numberOfRarities - 1; i >= 0; i--) {
if (this.petalContainers[i] === undefined) {
continue;
}
for (let j = 0; j < this.petalContainers[i].length; j++) {
const petalContainer = this.petalContainers[i][j];
petalContainer.x = petalContainerSize / 2 + padding +
sidePadding + (renderIndex % petalContainersPerRow) / (petalContainersPerRow - 1) *
(this.w - petalContainerSize - padding - rightPadding - 2 * sidePadding);
petalContainer.y = offsetFromText + padding +
petalContainerSize / 2 + Math.floor(renderIndex / petalContainersPerRow) *
(petalContainerSize + 12);
petalContainer.render.x = petalContainer.x;
petalContainer.render.y = petalContainer.y;
// petalContainer.x = canvas.w/2;
// petalContainer.y = canvas.h/2;
// console.log(petalContainer.x, petalContainer.y);
petalContainer.draw();
renderIndex++;
}
}
} else {
let containers = 0
let renderIndex = 0;
for (let i = numberOfRarities - 1; i >= 0; i--) {
if (this.petalContainers[i] === undefined) {
continue;
}
for (let j = 0; j < this.petalContainers[i].length; j++) {
if (containers >= 16) {
continue;
}
const petalContainer = this.petalContainers[i][j];
petalContainer.x = petalContainerSize / 2 + padding +
sidePadding + (renderIndex % petalContainersPerRow) / (petalContainersPerRow - 1) *
(this.w - petalContainerSize - padding - rightPadding - 2 * sidePadding);
petalContainer.y = offsetFromText + padding +
petalContainerSize / 2 + Math.floor(renderIndex / petalContainersPerRow) *
(petalContainerSize + 12);
petalContainer.render.x = petalContainer.x;
petalContainer.render.y = petalContainer.y;
// petalContainer.x = canvas.w/2;
// petalContainer.y = canvas.h/2;
// console.log(petalContainer.x, petalContainer.y);
petalContainer.draw();
renderIndex++;
containers++;
//console.log(containers)
}
}
}
// ctx.restore();
ctx.translate(-this.dimensions.x, -this.dimensions.y);
}
}
// idea: since in florr there's kinda a separate position for the petals
and camera and then the player, we need
this.x = 0;
this.y = 0;
this.baseX = 0;
this.baseY = 0;
// headX will be the thing that's actually moving, the normal x and y will
interpolate towards it
this.headX = 0;
this.headY = 0;
this.radius = 25;
this.xv = 0;
this.yv = 0;
this.friction = 0.3;
this.movementType = 'mouse';
this.angle = 0;
this.magnitude = 0;
this.maxHp = 100;
this.hp = 100;
this.shield = 0;
this.isPoisoned = 0; //false
this.name = '';
// kb
this.input = {up: false, down: false, right: false, left: false};
this.eyeOffsetX = 0;
this.eyeOffsetY = 0;
this.petals = [];
this.petalRotateSpeed = petalRotateSpeed;
this.petalRotation = 0;
this.petalLag = 0;
this.petalDistance = neutralPetalDistance;
this.attacking = false;
this.defending = false;
// this.renderX = this.x;
// this.renderY = this.y;
this.render = {};
for(let i = 0; i < flowerInterpolateKeys.length; i++){
this.render[flowerInterpolateKeys[i]] = this[flowerInterpolateKeys[i]];
}
this.render.angle = this.angle;
this.render.fastPetalDistance = this.petalDistance;
this.render.x = this.render.baseX;
this.render.y = this.render.baseY;
this.projectiles = [];
this.pets = [];
this.deadProjectiles = [];
this.deadPets = [];
// this.level = 0;
// this.petalSlots = 0;
}
init(data) {
for (let key in data) {
if (key === 'petals') {
// TODO add separate addPetal and removePetal messages
for (let petalId in data.petals) {
this.petals[petalId] = new Petal(data.petals[petalId]);
}
continue;
} else if (key === "projectiles") {
for (let i = 0; i < data.projectiles.length; i++) {
this.projectiles[i] = new Petal(data.projectiles[i]);
this.projectiles[i].isProjectile = true;
}
} else if (key === "pets") {
for (let i = 0; i < data.pets.length; i++) {
this.pets[i] = new Enemy(data.pets[i]);
}
} else {
this[key] = data[key];
}
}
}
update(data, startInd) {
if (data[startInd + 1/*hp*/] < this.hp) {
this.updateRenderDamage(data.hp);
}
// console.log(startInd);
// console.log(data);
for (let i = startInd; i < flowerPackKeys.length + startInd; i++) {
if (i === startInd + 5 && this.id === window.selfId) {
continue;// we dont want to change the angle on player by the
server becasue then it looks bad (snapping back). Thus, continue.
}
this[flowerPackKeys[i - startInd]] = data[i];
}
// // console.log(this.headX - data.headX);
// if (data.maxHp){
// this.hp = data.hp;
// this.render.hp = this.hp;
// this.ticksSinceLastDamaged = 99999;
// this.beforeStreakHp = this.hp;
// this.render.beforeStreakHp = this.hp;
// }
// if(data.petalRotateSpeed){
// this.petalLag = this.calculatePetalLag();
// }
// we don't send baseX or baseY. But, we send everything once per tick
right after the update.
// so just performing the same simulation that the server does will be 100%
accurate all the time
this.baseX = interpolate(this.baseX, this.headX, 0.4);
this.baseY = interpolate(this.baseY, this.headY, 0.4);
continue;
} else if (encodedType === 1) {
// special number indicating it's alive
if (this.petals[i].dead !== false) {
this.petals[i].update({ dead: false }, this);
}
continue;
} else if (encodedType === 3) {
this.petals[i].update({ distance: encodedData }, this);
continue;
} else if (encodedType === 4) {
if (this.petals[i].dying !== true && this.petals[i].dead !== true)
{
this.petals[i].update({ dead: true, reload: encodedData },
this);
}
else {
this.petals[i].update({ reload: encodedData }, this);
}
continue;
}
if (this.projectiles.length !== 0) {
const projectileStartIndex = startInd + flowerPackKeys.length +
this.petals.length;
for (let i = 0; i < this.projectiles.length; i++) {
const projectileData = [data[projectileStartIndex + i * 2],
data[projectileStartIndex + i * 2 + 1]];
if (projectileData[0] === -6.5) {
this.projectiles[i].update({ dead: true }, this);
} else {
this.projectiles[i].update({ x: projectileData[0], y:
projectileData[1] }, this);
}
}
}
if (this.pets.length !== 0) {
const petStartIndex = startInd + flowerPackKeys.length +
this.petals.length + this.projectiles.length * 2;
for (let i = 0; i < this.pets.length; i++) {
// const projectileData = [data[petStartIndex + i * 2],
data[petStartIndex + i * 2 + 1]];
const thisPetStartIndex = petStartIndex + i * enemyPackKeys.length;
this.pets[i].update(data, thisPetStartIndex);
// if(projectileData[0] === -6.5){
// this.projectiles[i].update({dead: true}, this);
// } else {
// this.projectiles[i].update({x: projectileData[0], y:
projectileData[1]}, this);
// }
}
}
}
updateRenderDamage() {
this.ticksSinceLastDamaged = 0;
}
updatePetsAndProjectiles() {
for (let i = 0; i < this.deadProjectiles.length; i++) {
if (this.deadProjectiles[i].deadAnimationTimer > 166) {
this.deadProjectiles[i].toRemove = true;
}
}
this.deadProjectiles = this.deadProjectiles.filter(p => p.toRemove !==
true);
// }
// this.xv *= this.friction;
// this.yv *= this.friction;
// this.headX += this.xv;
// this.headY += this.yv;
// this.petalRotation += this.petalRotateSpeed;
// // }
// // }
// // // TODO: make this account for movement delta over the frame. How
florr does it is if you ram into a rock then magnitude of lead is decreased and if
you slow down as well. We can't just base this off of velocity, we need a delta
position every frame system
// // this.x = interpolate(this.x, this.headX, 0.4 ** (dt/30));
// // this.y = interpolate(this.y, this.headY, 0.4 ** (dt/30));
// // }
// this.render.headX = this.render.x;
// this.render.headY = this.render.y;
// this.updateRenderPos();
this.render.x = this.render.baseX;
this.render.y = this.render.baseY;
}
draw() {
if (this.id !== window.selfId) {
this.updateInterpolate();
}
// this.updateRenderPos();
// ctx.fillStyle = 'red';
// ctx.beginPath();
// ctx.arc(this.headX, this.headY, 30, 0, Math.PI*2);
// ctx.fill();
// ctx.closePath();
// // rendering hp
// ctx.fillStyle = '#333333';
// ctx.beginPath();
// ctx.roundRect(this.render.headX - this.radius*1.6, this.render.headY +
this.radius*1.775, this.radius*3.2, this.radius*0.39, this.radius*0.25);
// ctx.fill();
// ctx.closePath();
// ctx.fillStyle = '#73de36'
// ctx.beginPath();
// if(this.hp < this.maxHp / 10){
// ctx.globalAlpha = this.hp * .95 / (this.maxHp / 10) + 0.05;
// }
// ctx.roundRect(this.render.headX - this.radius*1.6+1.75,
this.render.headY + this.radius*1.775+1.75, (this.radius*3.2-this.radius*0.25-
3.5)*this.hp/this.maxHp+this.radius*0.25, Math.max(0,this.radius*0.39-3.5),
this.radius*0.25);
// // ctx.roundRect(this.render.headX - this.radius*1.5+1.5,
this.render.headY + this.radius*1.7+1.5, (this.radius*3-3)*this.hp/this.maxHp,
Math.max(0,this.radius*0.35-3), this.radius*0.25, (this.radius*3-3));
// ctx.fill();
// ctx.closePath();
// ctx.globalAlpha = 1;
this.updatePetsAndProjectiles();
this.ticksSinceLastDamaged += dt;
if (this.ticksSinceLastDamaged > 666) {
this.beforeStreakHp = this.hp;
}
renderHpBar({
x: this.render.headX,
y: this.render.headY - this.render.radius / 3,
radius: this.render.radius,
hp: this.render.hp,
maxHp: this.maxHp,
shield: this.render.shield,
beforeStreakHp: this.render.beforeStreakHp,
flowerName: this.name,
flowerUsername: this.username
}, this);
// ctx.lastFlowerTransform = ctx.getTransform();
if (this.petalAlpha !== undefined) {
ctx.globalAlpha = this.petalAlpha;
}
if (this.id == window.selfId) {
petalReloadData = {};
petalHpData = {};
}
let renderAnyways = [
'Pearl',
'Compass',
'Dark Compass',
'Bud',
'Egg',
'Ikea',
'Square',
'Pentagon',
'Thomas',
'Ruby',
'Sapphire',
'Dandelion',
'Honey'
]
for (let i = 0; i < this.petals.length; i++) {
let petal = this.petals[i];
let valid = !window.flowrMod.hideOtherPetals || (this.id ==
window.selfId || renderAnyways.includes(petal.type))
if ((toRender({ x: petal.render.x, y: petal.render.y, radius:
petal.radius }, window.camera) === true) && valid) {
// if (!window.flowrMod.hideOtherPetals ||
((window.flowrMod.hideOtherPetals && this.id == window.selfid) ||
renderAnyways.includes(petal.type))) {
petal.draw();
// }
}
if (this.id == window.selfId) {
let containerId = petal.petalContainerId;
if (!petalReloadData[containerId]) {
if (petal.dead) {
petalReloadData[containerId] = {
reload: petal.render.reload / petal.maxReload
}
}
}
else {
if (petalReloadData[containerId].reload < petal.render.reload /
petal.maxReload && petal.dead) {
petalReloadData[containerId].reload = petal.render.reload /
petal.maxReload;
}
}
if (!petalHpData[containerId]) {
if (!petal.dead) {
petalHpData[containerId] = {
hp: petal.render.hp / petal.maxHp,
count: 1
}
}
}
else {
//average
if (!petal.dead) {
petalHpData[containerId].hp =
(petalHpData[containerId].count * petalHpData[containerId].hp + petal.render.hp /
petal.maxHp) / (petalHpData[containerId].count + 1);
petalHpData[containerId].count++;
}
}
}
petal.updateTimer();
}
ctx.globalAlpha = 1;
// ctx.restore();
// ctx.setTransform(ctx.lastPlayerTransform);
// delete ctx.lastFlowerTransform;
//borderRadius: (radius/25)**1.2*25*0.25,
// const barDimensions = {
// w: (radius/25)**1.2*25*3.2+.33,
// h: (radius/25)**1.2*25*0.39+.33,
// borderRadius: (radius/25)**1.2*25*0.25,
// innerPadding: (radius/25)**1.05*1.8-.1
// }
// ctx.globalAlpha = fadeAlphaMult;
// hp = Math.max(hp, 0);
// beforeStreakHp = Math.max(beforeStreakHp, 0);
// ctx.fillStyle = /*isEnemy ? '#131315' : */'#333333';
// ctx.beginPath();
// ctx.roundRect(x - barDimensions.w/2, y + radius*1.775, barDimensions.w,
barDimensions.h, barDimensions.borderRadius);
// ---
// this.updateRenderPos();
// ctx.fillStyle = 'red';
// ctx.beginPath();
// ctx.arc(this.render.x, this.render.y, 30, 0, Math.PI*2);
// ctx.fill();
// ctx.closePath();
//LIGHTNING
if (this.lightnings) {
if (this.lightnings.length > 0) {
this.lightnings = this.lightnings.filter((e) => time < (e.time +
600)) //600ms time
ctx.strokeStyle = "#97f0ea";
ctx.lineWidth = 3;
for (let i of this.lightnings) {
ctx.globalAlpha = (1 - (time - i.time) / 700);
ctx.beginPath();
for (let j = 0; j < i.renderData.length; j++) {
ctx.lineTo(i.renderData[j].x, i.renderData[j].y);
}
ctx.stroke();
ctx.closePath();
}
}
}
// this.renderAngle = interpolateDirection(this.renderAngle,
this.angle, 1/3);
// this.hp = interpolate(this.hp, this.hp, 0.1);
ctx.beginPath();
ctx.arc(x, y, radius, 0, Math.PI*2);
ctx.fill();
ctx.stroke();
ctx.closePath();
let path =
'data:image/svg+xml;base64,PHN2ZyB2ZXJzaW9uPSIxLjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9y
Zy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIHdpZHRoPSI
0OTEuNDYzMyIgaGVpZ2h0PSI0OTEuNDYzMyIgdmlld0JveD0iMCwwLDQ5MS40NjMzLDQ5MS40NjMzIj48Zy
B0cmFuc2Zvcm09InRyYW5zbGF0ZSgtMC40MzM5Niw2Ni4wOTc4NykiPjxnIGRhdGEtcGFwZXItZGF0YT0ie
yZxdW90O2lzUGFpbnRpbmdMYXllciZxdW90Ozp0cnVlfSIgZmlsbC1ydWxlPSJub256ZXJvIiBzdHJva2Ut
bGluZWNhcD0iYnV0dCIgc3Ryb2tlLWxpbmVqb2luPSJtaXRlciIgc3Ryb2tlLW1pdGVybGltaXQ9IjEwIiB
zdHJva2UtZGFzaGFycmF5PSIiIHN0cm9rZS1kYXNob2Zmc2V0PSIwIiBzdHlsZT0ibWl4LWJsZW5kLW1vZG
U6IG5vcm1hbCI+PGcgZmlsbD0iI2ZmZDY2OSIgc3Ryb2tlPSIjN2M1ZTMzIiBzdHJva2Utd2lkdGg9IjUwI
j48cGF0aCBkPSJNMTA3LjU4NDQ2LDMzOC4wNTAxYzAsMCAtNTkuNTU0MjQsLTI2My43MDM0OCAtNTkuNTI0
MjIsLTI2My43NDExNmMwLjQ4ODY0LC0wLjYxMzMgNzcuNjEwOTksODQuMjUxIDEwNy4yMzc5NCw4NS44NTY
zMWMzMS4zMDc3NywxLjY5NjU1IDkyLjA3MTM1LC0xMTUuMTY2MDUgOTIuNTYyMTIsLTExNS4wNjMxMmMzLj
k5NTk4LDE0LjA0Mjc3IC0wLjQ4MzksMjkyLjk0Nzk4IC0wLjQ4MzksMjkyLjk0Nzk4eiIvPjxwYXRoIGQ9I
k0zMS44OTk1Nyw2OS41MDI2N2MwLC05LjM4NDU3IDcuNjA3NjUsLTE2Ljk5MjIyIDE2Ljk5MjIxLC0xNi45
OTIyMmM5LjM4NDU3LDAgMTYuOTkyMjEsNy42MDc2NSAxNi45OTIyMSwxNi45OTIyMmMwLDkuMzg0NTYgLTc
uNjA3NjQsMTYuOTkyMjIgLTE2Ljk5MjIxLDE2Ljk5MjIyYy05LjM4NDU3LDAgLTE2Ljk5MjIxLC03LjYwNz
Y2IC0xNi45OTIyMSwtMTYuOTkyMjJ6Ii8+PHBhdGggZD0iTTIyNi4zNTEzNiwzMy4wMTM5N2MwLC0xMS4zN
jkzNSA5LjIxNjU0LC0yMC41ODU5IDIwLjU4NTksLTIwLjU4NTljMTEuMzY5MzYsMCAyMC41ODU5LDkuMjE2
NTUgMjAuNTg1OSwyMC41ODU5YzAsMTEuMzY5MzUgLTkuMjE2NTQsMjAuNTg1OSAtMjAuNTg1OSwyMC41ODU
5Yy0xMS4zNjkzNiwwIC0yMC41ODU5LC05LjIxNjU0IC0yMC41ODU5LC0yMC41ODU4OXoiLz48cGF0aCBkPS
JNMjQ2LjQ5Nzk4LDMzOC4wNTAxYzAsMCAtMS4xNzU5LC0yOTAuMDA3MTggLTEuMDgxNDgsLTI5Mi45NDc5N
2MwLjA0OTQ2LC0xLjU0MDM4IDYxLjg1MTkxLDExNi43NTk2NyA5My4xNTk1MywxMTUuMDYzMTJjMjkuNjI2
NzksLTEuNjA1MzEgMTA4LjEyNjk0LC04Ni42NDAzNyAxMDcuMjM3OTQsLTg1Ljg1NjNjLTAuODgyOTQsMC4
3Nzg3MyAtNTkuNTI0MjIsMjYzLjc0MTE2IC01OS41MjQyMiwyNjMuNzQxMTZ6IiBkYXRhLXBhcGVyLWRhdG
E9InsmcXVvdDtpbmRleCZxdW90OzpudWxsfSIvPjxwYXRoIGQ9Ik00NDQuOTgyNDMsODYuNDk0ODljLTkuM
zg0NTcsMCAtMTYuOTkyMjIsLTcuNjA3NjYgLTE2Ljk5MjIyLC0xNi45OTIyMmMwLC05LjM4NDU3IDcuNjA3
NjUsLTE2Ljk5MjIyIDE2Ljk5MjIyLC0xNi45OTIyMmM5LjM4NDU3LDAgMTYuOTkyMzcsNy42MDc2NSAxNi4
5OTIzNywxNi45OTIyMmMwLDkuMzg0NTYgLTcuNjA3ODEsMTYuOTkyMjIgLTE2Ljk5MjM3LDE2Ljk5MjIyei
IgZGF0YS1wYXBlci1kYXRhPSJ7JnF1b3Q7aW5kZXgmcXVvdDs6bnVsbH0iLz48cGF0aCBkPSJNOTguMDIxO
TEsMzQ1LjU2MDExYzAsMCAtMTQuNDQ2ODMsMS4wNjYwNiAtMTkuNTYxMjcsLTE4LjQxMDY2Yy0zLjg3MzIs
LTE0Ljc0OTU1IDE4LjQxMDY2LC0zNS44MzMyOCAxOC40MTA2NiwtMzUuODMzMjhsMjgwLjc2MTQxLDE0LjM
4MzI5djM5Ljg2MDY1eiIvPjxwYXRoIGQ9Ik0xMTUuNDA0OTgsMzQ1LjU2MDExdi0zOS44NjA2NWwyODAuNz
YxNDEsLTE0LjM4MzI5YzAsMCAyMi4yODM4NiwyMS4wODM3NCAxOC40MTA2NiwzNS44MzMyOGMtNS4xMTQ0N
CwxOS40NzY1NiAtMTkuNTYxMjcsMTguNDEwNjYgLTE5LjU2MTI3LDE4LjQxMDY2eiIgZGF0YS1wYXBlci1k
YXRhPSJ7JnF1b3Q7aW5kZXgmcXVvdDs6bnVsbH0iLz48L2c+PGcgc3Ryb2tlLXdpZHRoPSIzMi41Ij48cGF
0aCBkPSJNMTA3LjU4NDQ2LDMzOC4wNTAxbC01OS41MjQyMywtMjYzLjc0MTE2YzAsMCA3Ny42MTEsODQuMj
UxIDEwNy4yMzc5NCw4NS44NTYzMWMzMS4zMDc3NywxLjY5NjU1IDkyLjAxNjIzLC0xMTQuODQ3MzEgOTIuN
TYyMTIsLTExNS4wNjMxMmMwLjE5MjksLTAuMDc2MjYgLTAuNDgzOSwyOTIuOTQ3OTggLTAuNDgzOSwyOTIu
OTQ3OTh6IiBmaWxsPSIjZmZkNjY5IiBzdHJva2U9Im5vbmUiLz48cGF0aCBkPSJNMzEuODk5NTYsNjkuNTA
yNjdjMCwtOS4zODQ1NyA3LjYwNzY2LC0xNi45OTIyMiAxNi45OTIyMiwtMTYuOTkyMjJjOS4zODQ1NywwID
E2Ljk5MjIxLDcuNjA3NjUgMTYuOTkyMjEsMTYuOTkyMjJjMCw5LjM4NDU2IC03LjYwNzY0LDE2Ljk5MjIyI
C0xNi45OTIyMSwxNi45OTIyMmMtOS4zODQ1NywwIC0xNi45OTIyMiwtNy42MDc2NiAtMTYuOTkyMjIsLTE2
Ljk5MjIyeiIgZmlsbD0iI2ZmZDY2OSIgc3Ryb2tlPSJub25lIi8+PHBhdGggZD0iTTIyNi4zNTEzNiwzMy4
wMTM5N2MwLC0xMS4zNjkzNSA5LjIxNjU0LC0yMC41ODU5IDIwLjU4NTksLTIwLjU4NTljMTEuMzY5MzUsMC
AyMC41ODU5MSw5LjIxNjU1IDIwLjU4NTkxLDIwLjU4NTljMCwxMS4zNjkzNSAtOS4yMTY1NSwyMC41ODU5I
C0yMC41ODU5MSwyMC41ODU5Yy0xMS4zNjkzNiwwIC0yMC41ODU5LC05LjIxNjU0IC0yMC41ODU5LC0yMC41
ODU4OXoiIGZpbGw9IiNmZmQ2NjkiIHN0cm9rZT0ibm9uZSIvPjxwYXRoIGQ9Ik0yNDYuNDk3OTgsMzM4LjA
1MDFsLTEuMDgxNDcsLTI5Mi45NDc5N2MwLDAgNjEuODUxOTEsMTE2Ljc1OTY3IDkzLjE1OTUzLDExNS4wNj
MxMmMyOS42MjY3OSwtMS42MDUzMSAxMDcuMjM3OTQsLTg1Ljg1NjMgMTA3LjIzNzk0LC04NS44NTYzbC01O
S41MjQyMiwyNjMuNzQxMTZ6IiBkYXRhLXBhcGVyLWRhdGE9InsmcXVvdDtpbmRleCZxdW90OzpudWxsfSIg
ZmlsbD0iI2ZmZDY2OSIgc3Ryb2tlPSJub25lIi8+PHBhdGggZD0iTTQ0NC45ODI0Myw4Ni40OTQ4OWMtOS4
zODQ1NywwIC0xNi45OTIyMSwtNy42MDc2NiAtMTYuOTkyMjEsLTE2Ljk5MjIyYzAsLTkuMzg0NTcgNy42MD
c2NSwtMTYuOTkyMjIgMTYuOTkyMjEsLTE2Ljk5MjIyYzkuMzg0NTcsMCAxNi45OTIzOCw3LjYwNzY1IDE2L
jk5MjM4LDE2Ljk5MjIyYzAsOS4zODQ1NiAtNy42MDc4MSwxNi45OTIyMiAtMTYuOTkyMzgsMTYuOTkyMjJ6
IiBkYXRhLXBhcGVyLWRhdGE9InsmcXVvdDtpbmRleCZxdW90OzpudWxsfSIgZmlsbD0iI2ZmZDY2OSIgc3R
yb2tlPSJub25lIi8+PHBhdGggZD0iTTk4LjAyMTksMzQ1LjU2MDExYzAsMCAtMTQuNDQ2ODMsMS4wNjYwNi
AtMTkuNTYxMjcsLTE4LjQxMDY2Yy0zLjg3MzIsLTE0Ljc0OTU1IDE4LjQxMDY2LC0zNS44MzMyOCAxOC40M
TA2NiwtMzUuODMzMjhsMjgwLjc2MTQyLDE0LjM4MzN2MzkuODYwNjV6IiBmaWxsPSIjZmZkNjY5IiBzdHJv
a2U9Im5vbmUiLz48cGF0aCBkPSJNMTE1LjQwNDk3LDM0NS41NjAxMXYtMzkuODYwNjVsMjgwLjc2MTQxLC0
xNC4zODMzYzAsMCAyMi4yODM4NiwyMS4wODM3NCAxOC40MTA2NiwzNS44MzMyOGMtNS4xMTQ0NCwxOS40Nz
Y1NiAtMTkuNTYxMjcsMTguNDEwNjYgLTE5LjU2MTI3LDE4LjQxMDY2eiIgZGF0YS1wYXBlci1kYXRhPSJ7J
nF1b3Q7aW5kZXgmcXVvdDs6bnVsbH0iIGZpbGw9IiNmZmQ2NjkiIHN0cm9rZT0ibm9uZSIvPjxwYXRoIGQ9
Ik0xNi42ODM5Niw0MDkuMTE1NDR2LTQ1OC45NjMzaDQ1OC45NjMzdjQ1OC45NjMzeiIgZmlsbD0ibm9uZSI
gc3Ryb2tlLW9wYWNpdHk9IjAuMDA4MDYiIHN0cm9rZT0iIzAwMDAwMCIvPjwvZz48L2c+PC9nPjwvc3ZnPg
=='
let image = new Image();
image.src = path;
ctx.drawImage(image, x-radius, y-radius*2.5, radius*2, radius*2)
// eyes
ctx.fillStyle = '#212219';
ctx.beginPath();
ctx.ellipse(x - radius/3.5, y - radius*5/23.5, radius*3/23.5,
radius*5.85/23.5, 0, 0, Math.PI*2);
ctx.fill();
ctx.closePath();
ctx.beginPath();
ctx.ellipse(x + radius/3.5, y - radius*5/23.5, radius*3/23.5,
radius*5.85/23.5, 0, 0, Math.PI*2);
ctx.fill();
ctx.closePath();
//ellipse(x, y, radiusX, radiusY, rotation, startAngle, endAngle)
// mouth
ctx.strokeStyle = ctx.fillStyle;
ctx.lineWidth = radius/15;
ctx.lineCap = 'round';
let expressionOffset;// 0 to 1
if(this.render.fastPetalDistance > neutralPetalDistance){
// we're attacking
// petalDistance = 1 at this.petalDistance = petalDistance * 1.91;
// petalDistance = 0 at this.petalDistance = petalDistance;
expressionOffset = (this.render.fastPetalDistance -
neutralPetalDistance) / 0.91 / neutralPetalDistance;
} else {
// we're defending; divide by 0.4
// petalDistance = 1 at this.petalDistance = petalDistance * 0.6;
// petalDistance = 0 at this.petalDistance = petalDistance
expressionOffset = (neutralPetalDistance -
this.render.fastPetalDistance) / 0.4 / neutralPetalDistance;
}
// eyes: we have a path oval and then white circle and we ctx.clip
ctx.save();
// oval clipping path
ctx.beginPath();
ctx.ellipse(x + radius/3.5, y - radius*5/23.5, radius*2.5/23.5,
radius*5/23.5, 0, 0, Math.PI*2);
ctx.clip();
// ctx.closePath();
// circle
const eyeOffset = {
x: Math.cos(this.render.angle)*radius*2/23,
y: Math.sin(this.render.angle)*radius*3.5/23
}
ctx.fillStyle = '#eeeeee';
ctx.beginPath();
ctx.ellipse(x + radius/3.5 + eyeOffset.x, y - radius*5/23.5 +
eyeOffset.y, radius*2.92/23.5, radius*2.92/23.5, 0, 0, Math.PI*2);
ctx.fill();
ctx.closePath();
ctx.restore();
ctx.save();
// oval clipping path
ctx.beginPath();
ctx.ellipse(x - radius/3.5, y - radius*5/23.5, radius*2.5/23.5,
radius*5/23.5, 0, 0, Math.PI*2);
ctx.clip();
ctx.fillStyle = '#eeeeee';
ctx.beginPath();
ctx.ellipse(x - radius/3.5 + eyeOffset.x, y - radius*5/23.5 +
eyeOffset.y, radius*3/23.5, radius*3/23.5, 0, 0, Math.PI*2);
ctx.fill();
ctx.closePath();
ctx.restore();
// this.renderAngle = interpolateDirection(this.renderAngle,
this.angle, 1/3);
// this.hp = interpolate(this.hp, this.hp, 0.1);
// eyes
ctx.fillStyle = '#212219';
ctx.beginPath();
ctx.ellipse(x - radius/3.5, y - radius*5/23.5, radius*3/23.5,
radius*5.85/23.5, 0, 0, Math.PI*2);
ctx.fill();
ctx.closePath();
ctx.beginPath();
ctx.ellipse(x + radius/3.5, y - radius*5/23.5, radius*3/23.5,
radius*5.85/23.5, 0, 0, Math.PI*2);
ctx.fill();
ctx.closePath();
//ellipse(x, y, radiusX, radiusY, rotation, startAngle, endAngle)
// mouth
ctx.strokeStyle = ctx.fillStyle;
ctx.lineWidth = radius/15;
ctx.lineCap = 'round';
let expressionOffset;// 0 to 1
if(this.render.fastPetalDistance > neutralPetalDistance){
// we're attacking
// petalDistance = 1 at this.petalDistance = petalDistance * 1.91;
// petalDistance = 0 at this.petalDistance = petalDistance;
expressionOffset = (this.render.fastPetalDistance -
neutralPetalDistance) / 0.91 / neutralPetalDistance;
} else {
// we're defending; divide by 0.4
// petalDistance = 1 at this.petalDistance = petalDistance * 0.6;
// petalDistance = 0 at this.petalDistance = petalDistance
expressionOffset = (neutralPetalDistance -
this.render.fastPetalDistance) / 0.4 / neutralPetalDistance;
}
ctx.beginPath();
ctx.moveTo(x + radius/4, y + radius*9.5/23.5);
ctx.quadraticCurveTo(x, y + 1.07*radius*(5.5+9.5*(1-
expressionOffset))/23.5*61.1/70, x - radius/4, y + radius*9.5/23.5);
ctx.stroke();
// eyes: we have a path oval and then white circle and we ctx.clip
ctx.save();
// oval clipping path
ctx.beginPath();
ctx.ellipse(x + radius/3.5, y - radius*5/23.5, radius*2.5/23.5,
radius*5/23.5, 0, 0, Math.PI*2);
ctx.clip();
// ctx.closePath();
// circle
const eyeOffset = {
x: Math.cos(this.render.angle)*radius*2/23,
y: Math.sin(this.render.angle)*radius*3.5/23
}
ctx.fillStyle = '#eeeeee';
ctx.beginPath();
ctx.ellipse(x + radius/3.5 + eyeOffset.x, y - radius*5/23.5 +
eyeOffset.y, radius*2.92/23.5, radius*2.92/23.5, 0, 0, Math.PI*2);
ctx.fill();
ctx.closePath();
ctx.restore();
ctx.save();
// oval clipping path
ctx.beginPath();
ctx.ellipse(x - radius/3.5, y - radius*5/23.5, radius*2.5/23.5,
radius*5/23.5, 0, 0, Math.PI*2);
ctx.clip();
ctx.fillStyle = '#eeeeee';
ctx.beginPath();
ctx.ellipse(x - radius/3.5 + eyeOffset.x, y - radius*5/23.5 +
eyeOffset.y, radius*3/23.5, radius*3/23.5, 0, 0, Math.PI*2);
ctx.fill();
ctx.closePath();
ctx.restore();
if ( window.flowrMod.petalRenderMap[petal.type])
window.flowrMod.petalRenderMap[petal.type](petal);
else console.log(petal.type);
if ( window.flowrMod.petalRenderMap[petal.type])
window.flowrMod.petalRenderMap[petal.type](petal);
else console.log(petal.type);
ctx.translate(-x,-y);
petal.radius = rad
}
}
}
}
static drawDeadFlower(x, y, radius) {
ctx.fillStyle = '#ffe763';
ctx.strokeStyle = '#cebb50';
ctx.lineWidth = radius / 8;
ctx.beginPath();
ctx.arc(x, y, radius, 0, Math.PI * 2);
ctx.fill();
ctx.stroke();
ctx.closePath();
// dead eyes
ctx.fillStyle = '#212219';
ctx.strokeStyle = ctx.fillStyle;
ctx.lineWidth = radius / 8;
ctx.lineCap = 'round';
ctx.beginPath();
ctx.moveTo(eyecenter.x + radius * 4 / 23.5, eyecenter.y + radius * 4 /
23.5);
ctx.lineTo(eyecenter.x - radius * 4 / 23.5, eyecenter.y - radius * 4 /
23.5);
ctx.stroke();
ctx.closePath();
ctx.beginPath();
ctx.moveTo(eyecenter.x + radius * 4 / 23.5, eyecenter.y - radius * 4 /
23.5);
ctx.lineTo(eyecenter.x - radius * 4 / 23.5, eyecenter.y + radius * 4 /
23.5);
ctx.stroke();
ctx.closePath();
ctx.beginPath();
ctx.moveTo(eyecenter.x + radius * 4 / 23.5, eyecenter.y + radius * 4 /
23.5);
ctx.lineTo(eyecenter.x - radius * 4 / 23.5, eyecenter.y - radius * 4 /
23.5);
ctx.stroke();
ctx.closePath();
ctx.beginPath();
ctx.moveTo(eyecenter.x + radius * 4 / 23.5, eyecenter.y - radius * 4 /
23.5);
ctx.lineTo(eyecenter.x - radius * 4 / 23.5, eyecenter.y + radius * 4 /
23.5);
ctx.stroke();
ctx.closePath();
// mouth
ctx.strokeStyle = ctx.fillStyle;
ctx.lineWidth = radius / 15;
ctx.lineCap = 'round';
ctx.beginPath();
ctx.moveTo(x + radius / 4, y + radius * 9.5 / 23.5);
ctx.quadraticCurveTo(x, y + 1.07 * radius * (5.5 + 9.5 * (1 -
expressionOffset)) / 23.5 * 61.1 / 70, x - radius / 4, y + radius * 9.5 / 23.5);
ctx.stroke();
}
pack() {
return {
// angle: this.angle,
movementType: this.movementType,
// magnitude: this.magnitude,
input: this.input
}
}
}
// for reload animation not looking the same for every petal
this.randomAngle = Math.random() * Math.PI * 2;
this.x = x;
this.y = y;
this.w = w;
this.h = h;
this.radius = radius;
this.attempt = attempt;
this.id = id;
this.spawnAnimation = 0;
this.lastAmountChangedTime = -1000;
this.collectTime = null;
this.creationTime = performance.now();
this.isHovered = false;
this.statsBoxAlpha = 0;
this.statsBox = null;
// this.renderImageSize = 0;
// if(window.loaded === true){
// this.generateRenderImage(60 * canvas.zoom);
// } else {
// onLoadFunctions.push(() => {
// this.generateRenderImage(60 * canvas.zoom);
// })
// }
}
// generateRenderImage(size=60){
// this.renderImageSize = size;
// window.oldCanvas = canvas;
// window.oldCtx = ctx;
// canvas = document.createElement('canvas');
// ctx = canvas.getContext('2d');//new C2S(60, 60);
// ctx.imageSmoothingEnabled = false;
// canvas.width = size;
// canvas.height = size;// TODO: remove this because its unnecesary (and
oldCanvas and canvas = doc.createelement)
// ctx.lineJoin = 'round';
// ctx.lineCap = 'round';
// ctx.translate(size/2, size/2);
// ctx.scale(size/60, size/60);
// if(this.toOscillate === true && this.isDisplayPetalContainer !== true){
// // bigger grey border
// ctx.globalAlpha *= 0.3;
// ctx.fillStyle = 'black';
// ctx.beginPath();
// ctx.roundRect(-30, -30, 60, 60, 5);
// ctx.fill();
// ctx.closePath();
// ctx.globalAlpha = 1;
// }
// // draw rect
// ctx.lineWidth = 4.5;
// ctx.fillStyle = Colors.rarities[this.rarity].color;
// ctx.strokeStyle = Colors.rarities[this.rarity].border;
// // if (this.rarity == 8){
// // ctx.fillStyle = `hsl(${Math.cos(Date.now()/1200)*20 + 35}, 68%,
60%)`
// // ctx.strokeStyle = `hsl(${Math.cos(Date.now()/1200)*20 + 35}, 68%,
45%)`
// // }
// ctx.beginPath();
// ctx.roundRect(-25, -25, 50, 50, .25);
// ctx.fill();
// ctx.stroke();
// ctx.closePath();
// ctx.translate(0, -4);
// ctx.scale(scaleMult, scaleMult);
// if (individualRotate !== false)ctx.rotate(individualRotate)
// this.petals[0].draw();
// if (individualRotate !== false)ctx.rotate(-individualRotate)
// ctx.scale(1/scaleMult,1/scaleMult);
// ctx.translate(0, 4);
// // console.log(this.petals[0], ctx.getTransform());
// } else {
// // todo: generate positions in init instead of recalcing every
frame, its not like we're gonna be adding more petals to an existing petal slot
// let petalRadius = (this.petals[0] ?? {radius: 0}).radius;
// let radius = Math.min(petalRadius * 1.16, 25 - petalRadius);
// // if(this.petals.length === 3){
// // // odd
// // ctx.translate(-1, 0);
// // }
// // radius *= 1 / (greaterThanMargin/(13.25)+1);
// petalRadius *= 1 / (greaterThanMargin/13.25+1);
// // petalRadius = Math.max(8, petalRadius);
// for(let i = 0; i < this.petals.length; i++){
// this.petals[i].radius = petalRadius;
// }
// }
// }
// if (petalContainerMultPetalRadiusMap[this.petals[0].type] !==
undefined){
// if (typeof petalContainerMultPetalRadiusMap[this.petals[0].type]
== "object"){
// if (petalContainerMultPetalRadiusMap[this.petals[0].type]
[this.petals[0].rarity]){
// radius *=
petalContainerMultPetalRadiusMap[this.petals[0].type][this.petals[0].rarity];
// }
// }
// else{
// radius *=
petalContainerMultPetalRadiusMap[this.petals[0].type];
// }
// }
// let toPointToCenter = ['Stinger'].includes((this.petals[0] ?? {type:
"Basic"}).type) && (this.petals[0] ?? {rarity: 0}).rarity > 5;
// if (toPointToCenter == true){
// toPointToCenter = 0;
// }
// if (pointToCenterPetals[this.petals[0].type] !== undefined){
// if (typeof pointToCenterPetals[this.petals[0].type] == "object")
{
// if (pointToCenterPetals[this.petals[0].type]
[this.petals[0].rarity]){
// toPointToCenter =
pointToCenterPetals[this.petals[0].type][this.petals[0].rarity];
// }
// }
// else{
// toPointToCenter = pointToCenterPetals[this.petals[0].type];
// }
// }
// for(let i = 0; i < this.petals.length; i++){
// let rotateOffset = 0;
// if (petalContainerRotateMap[this.petals[0].type]){
// rotateOffset = petalContainerRotateMap[this.petals[0].type];
// }
// const angle = Math.PI * 2 * i / this.petals.length +
rotateOffset;
// this.petals[i].render.x = 0//this.x + Math.cos(angle) * radius;
// this.petals[i].render.y = 0//this.y + Math.sin(angle) * radius -
this.h / 10;
// ctx.fontKerning = "none";
// ctx.strokeText(this.type, 0, 13.25);
// ctx.fillText(this.type, 0, 13.25);
// }
// // ctx.translate(-30, -30);
// canvas.remove();
// // // console.log(svg);
// // canvas = oldCanvas;
// // ctx = oldCtx;
// // console.log(doc);
// // console.log(svgDoc.documentElement);
// canvas = window.oldCanvas;
// ctx = window.oldCtx;
// }
// TODO: polish animations! Have some flag for if the petal container is on the
ground. If it is then render that oscillation animation and draw that semi opaq
black border around it.
updateInterpolate() {
this.render.x = interpolate(this.render.x, this.x, 0.00672 * dt);
this.render.y = interpolate(this.render.y, this.y, 0.00672 * dt);
this.render.w = interpolate(this.render.w, this.w, 0.00672 * dt);
if (this.collectTime) {
this.spawnAnimation = interpolate(this.spawnAnimation, 0, 0.00672 *
dt);
} else {
this.spawnAnimation = interpolate(this.spawnAnimation, 1, 0.00672 *
dt);
}
}
drawStatsBox(drawBelow = false) {
if (window.statBoxes === false) {
return;
}
if (this.isHovered === true) {
if (this.statsBox === null) {
let lastOscillating = this.toOscillate;
let lastDimensions = { w: this.w, h: this.h };
this.w = 58;
this.h = 58;
this.toOscillate = false;
this.statsBox = redefineGenerateStatsBox(this, true,
{
x: this.x,
y: this.y
}
)
this.w = lastDimensions.w;
this.h = lastDimensions.h;
this.toOscillate = lastOscillating;
}
this.statsBoxAlpha += 0.15 * dt / 18;
if (this.statsBoxAlpha > 1) {
this.statsBoxAlpha = 1;
}
ctx.globalAlpha = this.statsBoxAlpha;
} else {
this.statsBoxAlpha -= 0.15 * dt / 18;
if (this.statsBoxAlpha < 0) {
this.statsBoxAlpha = 0;
}
}
if (this.statsBoxAlpha !== 0) {
this.statsBox.x = this.render.x - this.statsBox.w / 2
this.statsBox.y = drawBelow
? this.render.y + this.h / 2 + 11.5
: this.render.y - this.statsBox.h - this.h / 2 - 11.5;
ctx.globalAlpha = this.statsBoxAlpha;
this.statsBox.pc.amount = this.amount;
this.statsBox.draw();
ctx.globalAlpha = 1;
}
this.isHovered = false;
}
draw(inGame, number) {
this.updateInterpolate();
let scale = 1;
let rotation = 0;
ctx.lastTransform = ctx.getTransform();
// ctx.save();
ctx.translate(this.render.x, this.render.y);
scale *= renderAnimationTimer * this.render.w / 50;
// this.undraggingPetalContainerTimer = 30;
// // this.draggingTimer /= 300;
// // this.draggingTimer = this.draggingTimer % (Math.PI * 2);
// // this.draggingTimer *= 300;
// this.draggingTimer = Math.sin(this.draggingTimer / 300) * 0.3;//
it becomes an angle now
// this.interval = setInterval(() => {
// this.draggingTimer =
interpolateDirection(this.draggingTimer, Math.PI / 2, 0.1);
// this.undraggingPetalContainerTimer--;
// if(this.undraggingPetalContainerTimer < 0){
// clearInterval(this.interval);
// delete this.undraggingPetalContainerTimer;
// }
// }, 1000 / 30);
}
}
// draw rect
ctx.lineWidth = 4.5;
// if (this.rarity == 8){
// ctx.fillStyle = `hsl(${Math.cos(Date.now()/1200)*20 + 35}, 68%,
60%)`
// ctx.strokeStyle = `hsl(${Math.cos(Date.now()/1200)*20 + 35}, 68%,
45%)`
// }
ctx.beginPath();
ctx.roundRect(-25, -25, 50, 50, .25);
ctx.fill();
ctx.stroke();
ctx.closePath();
ctx.beginPath();
ctx.roundRect(-25, -25, 50, 50, .25);
ctx.fill();
ctx.closePath();
if (star.x < -30 || star.x > 30 || star.y < -30 || star.y > 30) {
//don't draw;
continue;
}
ctx.beginPath();
ctx.fillStyle = grad;
ctx.globalAlpha = 0.3;
ctx.fillStyle = "#fff";
ctx.globalAlpha = 0.3;
ctx.lineCap = "butt";
ctx.strokeStyle = "#000000";
ctx.lineWidth = 50;
ctx.beginPath();
ctx.arc(0, 0, 25, offset - Math.PI * 2 *
smoothstep(petalReloadData[number].reload), offset);
ctx.stroke();
ctx.closePath();
ctx.restore();
}
} else if (petalHpData[number]) {
//console.log("hp data exists", petalHpData[number].hp);
if (petalHpData[number].hp > 0.001 && petalHpData[number].hp <
0.999) {
//from 1 -> hp overlay pc
ctx.save();
ctx.beginPath();
ctx.roundRect(-23, -23, 46, 46, .25);
ctx.clip();
ctx.globalAlpha = 0.6;
ctx.lineCap = "butt";
ctx.fillStyle = "#000000";
ctx.beginPath();
ctx.rect(-25, -25, 50, 50 * (1 - petalHpData[number].hp));
ctx.fill();
ctx.closePath();
ctx.restore();
}
}
}
ctx.beginPath();
ctx.roundRect(-25, -25, 50, 50, .25);
ctx.stroke();
ctx.closePath();
if (this.greyed) ctx.globalAlpha = 1;
// radius *= 1 / (greaterThanMargin/(13.25)+1);
petalRadius *= 1 / (greaterThanMargin / 13.25 + 1);
// petalRadius = Math.max(8, petalRadius);
for (let i = 0; i < this.petals.length; i++) {
this.petals[i].radius = petalRadius;
}
}
}
if (petalContainerMultPetalRadiusMap[this.petals[0].type] !==
undefined) {
if (typeof petalContainerMultPetalRadiusMap[this.petals[0].type] ==
"object") {
if (petalContainerMultPetalRadiusMap[this.petals[0].type]
[this.petals[0].rarity]) {
radius *=
petalContainerMultPetalRadiusMap[this.petals[0].type][this.petals[0].rarity];
}
}
else {
radius *=
petalContainerMultPetalRadiusMap[this.petals[0].type];
}
}
let toPointToCenter = ['Stinger'].includes((this.petals[0] ?? { type:
"Basic" }).type) && (this.petals[0] ?? { rarity: 0 }).rarity > 5;
if (toPointToCenter == true) {
toPointToCenter = 0;
}
if (pointToCenterPetals[this.petals[0].type] !== undefined) {
if (typeof pointToCenterPetals[this.petals[0].type] == "object") {
if (pointToCenterPetals[this.petals[0].type]
[this.petals[0].rarity]) {
toPointToCenter = pointToCenterPetals[this.petals[0].type]
[this.petals[0].rarity];
}
}
else {
toPointToCenter = pointToCenterPetals[this.petals[0].type];
}
}
for (let i = 0; i < this.petals.length; i++) {
let rotateOffset = 0;
if (petalContainerRotateMap[this.petals[0].type]) {
rotateOffset = petalContainerRotateMap[this.petals[0].type];
}
const angle = Math.PI * 2 * i / this.petals.length + rotateOffset;
this.petals[i].render.x = 0//this.x + Math.cos(angle) * radius;
this.petals[i].render.y = 0//this.y + Math.sin(angle) * radius -
this.h / 10;
ctx.fontKerning = "none";
this.x = x;
this.y = y;
this.w = w;
if (h === undefined) {
this.h = 1000;
ctx.globalAlpha = 0;
this.draw();
this.h = this.currentHeight + 10;
ctx.globalAlpha = 1;
} else {
this.h = h;
}
this.pc = {};
}
draw() {
ctx.textAlign = 'left';
ctx.textBaseline = 'center';
ctx.fontKerning = "none";
ctx.letterSpacing = "-.1px";
ctx.font = '900 16px Ubuntu';
ctx.translate(this.x, this.y);
this.drawBackground();
this.currentHeight = 0;
for (let i = 0; i < this.fields.length; i++) {
this.drawField(this.fields[i]);
}
ctx.translate(-this.x, -this.y);
}
drawBackground() {
const lastGA = ctx.globalAlpha;
ctx.globalAlpha *= 0.55;
ctx.fillStyle = 'black';
ctx.beginPath();
ctx.roundRect(0, 0, this.w, this.h, 6);
ctx.fill();
ctx.closePath();
ctx.globalAlpha = lastGA;
}
drawField(field) {
if (this['draw' + field.type] === undefined) return;
this['draw' + field.type](field);
}
drawTitle(field) {
ctx.font = '900 28px Ubuntu';
ctx.fillStyle = 'white';
ctx.strokeStyle = 'black';
ctx.lineWidth = 4;
this.currentHeight += 40;
}
drawDescription(field) {
ctx.font = '900 14px Ubuntu';
ctx.fillStyle = 'white';
ctx.strokeStyle = 'black';
ctx.lineWidth = 2;
const wrappedText = wrapText(field.value, 16, this.currentHeight + 10,
this.w - 20 - 10, 15);
for (let i = 0; i < wrappedText.length; i++) {
ctx.strokeText(wrappedText[i][0], wrappedText[i][1], wrappedText[i]
[2]);
ctx.fillText(wrappedText[i][0], wrappedText[i][1], wrappedText[i][2]);
}
this.currentHeight = wrappedText[wrappedText.length - 1][2] + 10;
}
drawStat(field) {
ctx.font = '900 13px Ubuntu';
ctx.fillStyle = field.color;
ctx.strokeStyle = 'black';
ctx.lineWidth = 2;
if (Array.isArray(field.value)) {
let statValue = field.value.join(", ");
if (field.name == "poison") {
statValue = formatAmountHighPrecision(field.value[0]) + " total, "
+ formatAmountHighPrecision(field.value[1]) + "/s";
}
const wrappedText = wrapText(`${this.formatName(field.name)}: $
{statValue}`, 12, this.currentHeight + 10, this.w - 20 - 10, 15);
this.currentHeight += 16;
}
formatName(name) {
if (name.length > 1) {
name = name[0].toUpperCase() + name.slice(1);
}
const ga = ctx.globalAlpha;
pc.draw();
ctx.globalAlpha = ga;
}
drawDropsPetalContainer(field) {
let { data, rarity } = field;
if (data === null) return;
field.pcs = [];
for (let key in data) {
const type = key;
const rarities = data[key];
for (let i = 0; i < rarities.length; i++) {
if (rarities[i] !== 0) {
const petalStats = Stats.petals[type][i];
// console.log(Stats.petals[type]);
let petalAmount = 0;
field.pcs.push(new PetalContainer(petalArray, { x: 0, y: 0,
w: 50, h: 50, toOscillate: false, radius: 0 }, Math.random(), 1, 0));
if (rarities[i] > 10) {
field.pcs[field.pcs.length - 1].dropPercent =
Math.ceil(rarities[i] * 10) / 10;
}
else {
field.pcs[field.pcs.length - 1].dropPercent =
Math.ceil(rarities[i] * 100) / 100;
}
}
}
}
}
this.currentHeight += 36;
let wOffset = 0;
const ga = ctx.globalAlpha;
pc.draw();
ctx.globalAlpha = ga;
this.currentHeight -= 38;
}
}
this.hoveringOverButton = false;
this.hoveringOverX = false;
this.menuActive = false;
this.w = 425;//510;
this.h = 665;//740;
this.scroll = 0;
this.horizontalScroll = 0;
this.render = { scroll: this.scroll, horizontalScroll:
this.horizontalScroll };
this.totalPetalHeight = 0;
this.hoveringOverCraftButton = false;
this.craftingButton = {
x: this.w * .83,
y: this.h * .28,
w: this.w * .16,
h: this.w * .11
}
this.inventorySpace = {
x: 6,
y: this.h * .48,
w: this.w - 10 - 24,
h: this.h * .52 - 4
// h: this.h * .52 - 4 - 24
}
this.typeIndex = 0;
this.typeIndexes = {/*[type]: typeIndex*/ };
this.petalContainerSize = 47.4;
this.maxRarity = 0;
this.fadingPetalContainers = [];
this.rainingPetalSlots = [];
this.isRainingPetalSlots = false;
this.hoveringOverScrollBar = false;
this.hoveringOverHorizontalScrollBar = false;
}
enterGame() {
this.craftingPetalContainers = [];
this.typeIndexes = {};
let index = 0
for (let i of Object.keys(this.petalContainers)) {
this.typeIndexes[i] = index
index++
}
}
}
}
draw() {
let alpha = this.fadingOut === true ? 1 - (time - this.originalFadeOutTime)
/ 100 : 1;
this.drawIcon(alpha);
ctx.beginPath();
ctx.roundRect(20, canvas.h - 20 - 80, 80, 80, 3);
ctx.fill();
ctx.stroke();
ctx.closePath();
ctx.drawImage(this.icon, 20 + 15, canvas.h - 20 - 80 + 15, 80 - 15 * 2, 80
- 15 * 2);
ctx.fillStyle = '#f0f0f0';
ctx.strokeStyle = 'black';
ctx.lineWidth = 2.25;
ctx.textAlign = 'center';
ctx.textBaseline = 'middle';
ctx.font = `900 14px Ubuntu`;
ctx.strokeText("[C]", 20 + 80 - 15 - 2.5, canvas.h - 20 - 80 + 15);
ctx.fillText("[C]", 20 + 80 - 15 - 2.5, canvas.h - 20 - 80 + 15);
if (alpha !== 1) {
ctx.globalAlpha = alpha;
}
let translation = 0;
if (time - this.lastCloseTime < 160) {
translation += this.h * easeOutCubic((time - this.lastCloseTime) /
160);
}
if (time - this.lastOpenTime < 160) {
translation += (this.h + 40) - (this.h + 40) * easeOutCubic((time -
this.lastOpenTime) / 160);
}
if (translation !== 0) {
ctx.translate(0, translation);
}
ctx.beginPath()
this.w = 43+this.maxRarity*62
ctx.roundRect(0, 0, this.w, this.h, 3);
ctx.fill();
ctx.stroke();
ctx.closePath();
ctx.globalAlpha = alpha
ctx.fillStyle = '#f0f0f0';
ctx.strokeStyle = 'black';
ctx.lineWidth = 3.75;
ctx.textAlign = 'center';
ctx.textBaseline = 'middle';
ctx.font = `900 32px Ubuntu`;
ctx.strokeText("Craft", this.w / 2, 29);
ctx.fillText("Craft", this.w / 2, 29);
if (this.craftingAnimationState === true) {
this.runCraftingAnimation();
}
if (this.craftingAnimationState === "display") {
this.displayPetalContainer.x = this.craftingPetalSlotsDimensions.x +
this.displayPetalContainer.render.w * .35;
this.displayPetalContainer.y = this.craftingPetalSlotsDimensions.y +
this.displayPetalContainer.render.h * .35;
this.displayPetalContainer.render.x = this.displayPetalContainer.x;
this.displayPetalContainer.render.y = this.displayPetalContainer.y;
this.displayPetalContainer.draw();
// ctx.fillStyle = '#b17f49';
// ctx.beginPath();
// ctx.roundRect(this.displayPetalContainer.x,
this.displayPetalContainer.y, this.displayPetalContainer.w,
this.displayPetalContainer.h, 8);
// ctx.fill();
// ctx.closePath();
} else {
for (let i = 0; i < this.craftingPetalSlots.length; i++) {
// this.craftingPetalSlots[i]
ctx.fillStyle = '#000000';
ctx.beginPath();
ctx.roundRect(this.craftingPetalSlots[i].x,
this.craftingPetalSlots[i].y, this.craftingPetalSlots[i].w,
this.craftingPetalSlots[i].h, 8);
ctx.fill();
ctx.closePath();
ctx.fillStyle = '#f0f0f0';
ctx.strokeStyle = 'black';
ctx.lineWidth = 2.25;
ctx.textAlign = 'center';
ctx.textBaseline = 'middle';
ctx.font = `900 22px Ubuntu`;
ctx.strokeText("Craft", this.craftingButton.x, this.craftingButton.y);
ctx.fillText("Craft", this.craftingButton.x, this.craftingButton.y);
if (this.craftingPetalContainers[0]) {
ctx.fillStyle = '#f0f0f0';
ctx.strokeStyle = 'black';
ctx.lineWidth = 2.25;
ctx.textAlign = 'center';
ctx.textBaseline = 'middle';
ctx.font = `900 12px Ubuntu`;
ctx.save();
this.firstPetalContainer = null;
this.lastPetalContainer = null;
let maxTypeIndex = 0;
for (let typeKey in this.petalContainers) {
for (let i = 0; i <= Math.max(5, this.maxRarity); i++) {
const rarityKey = i;
const pcX = this.petalContainerSize / 2 + this.inventorySpace.x +
(this.petalContainerSize + 12) * rarityKey + 3 - this.render.horizontalScroll *
(this.totalPetalWidth - this.inventorySpace.h);
const pcY = 5 + this.petalContainerSize / 2 +
this.typeIndexes[typeKey] * (this.petalContainerSize + 12) + 5 +
this.inventorySpace.y - this.render.scroll * (this.totalPetalHeight -
this.inventorySpace.h);
if (this.typeIndexes[typeKey] > maxTypeIndex) {
maxTypeIndex = this.typeIndexes[typeKey];
}
// draw box
if (this.fillerPetalSlots[typeKey] === undefined) {
this.fillerPetalSlots[typeKey] = {};
}
if (this.fillerPetalSlots[typeKey][rarityKey] === undefined) {
this.fillerPetalSlots[typeKey][rarityKey] = { render: { x:
pcX, y: pcY } };
}
const fpc = this.fillerPetalSlots[typeKey][rarityKey];
fpc.x = pcX;
fpc.y = pcY;
fpc.render.x = interpolate(fpc.render.x, fpc.x, 0.00672 * dt);
fpc.render.y = interpolate(fpc.render.y, fpc.y, 0.00672 * dt);
ctx.fillStyle = '#b17f49';
ctx.beginPath();
ctx.roundRect(fpc.render.x - this.petalContainerSize / 2,
fpc.render.y - this.petalContainerSize / 2, this.petalContainerSize,
this.petalContainerSize, 8);
ctx.fill();
ctx.closePath();
}
}
} else {
this.fillingHorizontal = false;
}
// ctx.save();
// ctx.beginPath()
// ctx.roundRect(0, 0, this.w, this.h, 3);
// ctx.stroke();
// ctx.closePath();
this.scrollbar.pos = interpolate(this.scrollbar.start,
this.scrollbar.end, this.render.scroll);
this.scrollbar.bottom = this.scrollbar.pos + this.scrollbar.length / 2;
this.scrollbar.top = this.scrollbar.pos - this.scrollbar.length / 2;
this.scrollbar.renderTop = interpolate(this.scrollbar.renderTop,
this.scrollbar.top, this.draggingScrollBar ? 0.28 : 0.08);
this.scrollbar.renderBottom = interpolate(this.scrollbar.renderBottom,
this.scrollbar.bottom, this.draggingScrollBar ? 0.28 : 0.08);
}
if (this.maxRarity >= 5) {
this.render.horizontalScroll =
interpolate(this.render.horizontalScroll, this.horizontalScroll, 0.0070 * dt);
this.horizontalScrollBar.pos =
interpolate(this.horizontalScrollBar.start, this.horizontalScrollBar.end,
this.render.horizontalScroll);
this.horizontalScrollBar.right = this.horizontalScrollBar.pos +
this.horizontalScrollBar.length / 2;
this.horizontalScrollBar.left = this.horizontalScrollBar.pos -
this.horizontalScrollBar.length / 2;
this.horizontalScrollBar.renderRight =
interpolate(this.horizontalScrollBar.renderRight, this.horizontalScrollBar.right,
this.draggingHorizontalScrollBar ? 0.28 : 0.08);
this.horizontalScrollBar.renderLeft =
interpolate(this.horizontalScrollBar.renderLeft, this.horizontalScrollBar.left,
this.draggingHorizontalScrollBar ? 0.28 : 0.08);
}
if (this.scroll < 0) {
this.scroll = 0;
} else if (this.scroll > 1) {
this.scroll = 1;
}
// console.log(this.render.scroll);
ctx.strokeStyle = '#ffffff';
ctx.lineWidth = 8;
ctx.lineCap = 'round';
ctx.beginPath();
ctx.moveTo(this.w - 16, (this.scrollbar.renderTop) /** ((this.h - 82 -
16) / this.h) + 82*/);
ctx.lineTo(this.w - 16, (this.scrollbar.renderBottom) /** ((this.h - 82 -
16) / this.h) + 82*/);
ctx.stroke();
ctx.closePath();
ctx.beginPath();
ctx.moveTo(this.horizontalScrollBar.renderRight, this.h - 16 /** ((this.h -
82 - 16) / this.h) + 82*/);
ctx.lineTo(this.horizontalScrollBar.renderLeft, this.h - 16 /** ((this.h -
82 - 16) / this.h) + 82*/);
ctx.stroke();
ctx.closePath();
// X rendering
ctx.translate(-3, 3);
ctx.strokeStyle = '#90464b';
ctx.lineWidth = 5;
ctx.beginPath();
ctx.roundRect(this.w - 7.5 - 30, 7.5, 30, 30, 6);
ctx.fill();
ctx.stroke();
ctx.closePath();
ctx.lineWidth = 4.75;
ctx.lineCap = 'round';
ctx.strokeStyle = '#cccccc';
ctx.beginPath();
ctx.moveTo(this.w - 30, 30);
ctx.lineTo(this.w - 7.5 * 2, 7.5 + 7.5);
ctx.stroke();
ctx.closePath();
ctx.beginPath();
ctx.moveTo(this.w - 7.5 * 2, 30);
ctx.lineTo(this.w - 30, 7.5 + 7.5);
ctx.stroke();
ctx.closePath();
ctx.translate(3, -3);
if (mouseX > 130 && mouseX < 130 + this.w - 20 && mouseY > canvas.h -
this.h - 20 && mouseY < canvas.h - 20) {
ctx.lastTransform5 = ctx.getTransform();
for (let typeKey in this.petalContainers) {
for (let i = 0; i <= this.maxRarity; i++) {
if (this.petalContainers[typeKey] === undefined) continue;
const rarityKey = i;
const pc = this.petalContainers[typeKey][rarityKey];
if (pc === undefined) continue;
if (translation !== 0) {
ctx.translate(0, -translation);
}
ctx.globalAlpha = 1;
// ctx.fillStyle = 'red';
// ctx.beginPath();
// ctx.arc(this.mouse.x, this.mouse.y, 6, 0, Math.PI * 2);
// ctx.fill();
// ctx.closePath();
// ctx.fillStyle = 'red';
// ctx.beginPath();
// ctx.arc(this.mouse2.x, this.mouse2.y, 6, 0, Math.PI * 2);
// ctx.fill();
// ctx.closePath();
// ctx.fillStyle = 'red';
// ctx.beginPath();
// ctx.arc(this.mouse3.x, this.mouse3.y, 6, 0, Math.PI * 2);
// ctx.fill();
// ctx.closePath();
}
updateScroll(/*delta*/{ x, y }, { mouseX, mouseY }) {
if (this.menuActive !== true || Object.keys(this.petalContainers).length
=== 0 || this.fillingHorizontal === true) {
return;
}
// console.log(mouseX);
// if(mouseInBox({x: mouseX, y: mouseY}, {x: 130, y: canvas.h - this.h -
20, w: this.w * 1.12, h: this.h}) === false){
// return;
// }
if (mouseX < 130 || mouseY < canvas.h - this.h - 20 || mouseX > 130 +
this.w || mouseY > canvas.h - 20) {
return;
}
const petalDimensions = {
start: this.firstPetalContainer.y - this.petalContainerSize / 2 - 6,
end: this.lastPetalContainer.y + this.petalContainerSize / 2 + 6
}
petalDimensions.length = petalDimensions.end - petalDimensions.start;
this.scroll += y / petalDimensions.length;
// let counter = 0;
// let intrvl = setInterval(() => {
// counter++;
// if(counter > 10){
// clearInterval(intrvl);
// return;
// }
// for(let i = numberOfRarities-1; i >= 0; i--){
// if(this.petalContainers[i] === undefined){
// continue;
// }
// for(let j = 0; j < this.petalContainers[i].length; j++){
// const petalContainer = this.petalContainers[i][j];
// if(petalContainer.lastInTime !== undefined){
// petalContainer.lastInTime -= Math.abs(y) * 3;
// }
// if(petalContainer.lastOutTime !== undefined){
// petalContainer.lastOutTime -= Math.abs(y) * 3;
// }
// }
// }
// }, 100)
}
mouseDown({ mouseX, mouseY }, evt) {
// ctx.translate(130, canvas.h - this.h - 20);
// ctx.moveTo(this.w - 16, (this.scrollbar.renderTop) /** ((this.h - 82 -
16) / this.h) + 82*/);
// ctx.lineTo(this.w - 16, (this.scrollbar.renderBottom) /** ((this.h - 82
- 16) / this.h) + 82*/);
// this.mouse = {x: 130 + this.w - 24, y: this.scrollbar.renderTop +
canvas.h - this.h - 20}//{x: mouseX, y: mouseY};
// this.mouse2 = {x: this.mouse.x + 16, y: this.mouse.y +
this.scrollbar.length};
// this.mouse3 = {x: mouseX, y: mouseY};
if (mouseX > 130 + this.w - 24 && mouseX < 130 + this.w - 24 + 16 && mouseY
> this.scrollbar.top + canvas.h - this.h - 20 && mouseY < this.scrollbar.top +
canvas.h - this.h - 20 + this.scrollbar.length) {
// console.log('drag');
this.draggingScrollBar = true;
} else if (this.maxRarity >= 5 && mouseX > 130 +
this.horizontalScrollBar.left && mouseX < 130 + this.horizontalScrollBar.left +
this.horizontalScrollBar.length && mouseY > canvas.h - this.h - 20 + this.h - 16 -
16 && mouseY < canvas.h - this.h - 20 + this.h - 16 + 16) {
this.draggingHorizontalScrollBar = true;
}
let preexistingAmount = 0;
for (let i = 0; i < this.craftingPetalContainers.length; i++) {
if (this.craftingPetalContainers[i] !== undefined) {
preexistingAmount++;
}
}
// if they're not the same type and amount is less than 5 then return
if (window.flowrMod.attempts === false) {
if (preexistingType !== type && amount < 5) {
return;
} else if (preexistingType === type && preexistingAmount + amount < 5)
{
//return;
}
}
globalInventory.addPetalContainer(this.craftingPetalContainers[i]);
this.addFadingPetalContainer(this.craftingPetalContainers[i]);
this.craftingPetalContainers[i] = new
PetalContainer(lastPetalContainer.petals, { ...lastPetalContainer, w: 65, h: 65 },
Math.random(), amountPerSlot + (leftOvers > i), attempt);
}
} else {
this.craftingPetalContainers[i] = new
PetalContainer(lastPetalContainer.petals, { ...lastPetalContainer, w: 65, h: 65 },
Math.random(), amountPerSlot + (leftOvers > i), attempt);
}
}
}
removeCraftingPetalContainers() {
if (this.craftingPetalContainers.length === 0) {
return;
}
for (let i = 0; i < this.craftingPetalContainers.length; i++) {
this.addFadingPetalContainer(/*new
PetalContainer(this.craftingPetalContainers[i].petals.map(p => new Petal(p)),
{...this.craftingPetalContainers[i]}, -Math.random(),
1)*/this.craftingPetalContainers[i]);
}
let amount = 0;
for (let i = 0; i < this.craftingPetalContainers.length; i++) {
amount += this.craftingPetalContainers[i].amount;
}
this.craftingPetalContainers[0].amount = amount;
globalInventory.addPetalContainer(this.craftingPetalContainers[0]);
this.craftingPetalContainers = [];
}
startCraftingAnimation() {
this.craftingAnimationState = true;
this.craftingAnimationTimer = 0;
}
runCraftingAnimation(rarity) {
this.craftingAnimationTimer += dt;
for (let i = 0; i < 5; i++) {
const angle = this.craftingAnimationTimer / 150 /**
Math.sqrt(this.craftingAnimationTimer/3000)*/ + Math.PI * 2 * i / 5;
const radius = this.craftingPetalSlotsDimensions.radius *
Math.sin(this.craftingAnimationTimer / 300);
this.craftingPetalSlots[i].x = this.craftingPetalSlotsDimensions.x +
Math.cos(angle) * radius;
this.craftingPetalSlots[i].y = this.craftingPetalSlotsDimensions.y +
Math.sin(angle) * radius;
this.craftingPetalContainers[i].render.x = this.craftingPetalSlots[i].x
+ this.craftingPetalSlots[i].w / 2;
this.craftingPetalContainers[i].x = this.craftingPetalSlots[i].x +
this.craftingPetalSlots[i].w / 2;
this.craftingPetalContainers[i].render.y = this.craftingPetalSlots[i].y
+ this.craftingPetalSlots[i].h / 2;
this.craftingPetalContainers[i].y = this.craftingPetalSlots[i].y +
this.craftingPetalSlots[i].h / 2;
}
this.addFadingPetalContainer(this.craftingPetalContainers[i]);
this.craftingPetalContainers[i].toRemove = true;
this.craftingPetalContainers[i].attempt =
this.craftingAnimationData.attempt;
} else {
this.craftingPetalContainers[i].amount = 1;
this.craftingPetalContainers[i].attempt =
this.craftingAnimationData.attempt;
}
}
this.craftingPetalContainers =
this.craftingPetalContainers.filter(p => p.toRemove !== true);
}
this.craftingPetalSlots = [];
for (let i = 0; i < 5; i++) {
const angle = Math.PI * 2 * i / 5 - Math.PI / 2;
this.craftingPetalSlots.push({
x: this.craftingPetalSlotsDimensions.x + Math.cos(angle) *
this.craftingPetalSlotsDimensions.radius,
y: this.craftingPetalSlotsDimensions.y + Math.sin(angle) *
this.craftingPetalSlotsDimensions.radius,
w: 65,
h: 65
})
}
}
}
processCraftResults(successAmount, amountRemaining, petalData, attempt, lost) {
this.craftingAnimationData = { successAmount, amountRemaining, petalData,
attempt, lost };
if (window.flowrMod.instaCraft) this.craftingAnimationTimer = 9999
// console.log(this.craftingAnimationData.attempt);
}
addFadingPetalContainer(p) {
this.fadingPetalContainers.push(new PetalContainer(p.petals.map(pInit =>
new Petal(pInit)), { ...p }, Math.random(), p.amount));
this.fadingPetalContainers[this.fadingPetalContainers.length -
1].collectTime = performance.now();
}
startRainingPetalSlots(pc) {
if (window.petalRain == false) {
return;
}
this.isRainingPetalSlots = true;
const rarityToRainSettings = {
0: {
amount: 3,
},
1: {
amount: 7
},
2: {
amount: 15
},
3: {
amount: 30
},
4: {
amount: 56
},
5: {
amount: 82
},
6: {
amount: 120
},
7: {
amount: 200
},
8: {
amount: 200
},
9: {
amount: 200
},
10: {
amount: 200
},
11: {
amount: 200
},
12: {
amount: 200
}
};
let rainAmountLeft = rarityToRainSettings[pc.rarity - 1].amount *
Math.ceil(Math.sqrt(pc.amount));
this.rainInterval = setInterval(() => {
rainAmountLeft--;
if (rainAmountLeft < 0) {
clearInterval(this.rainInterval);
delete this.rainInterval;
// this.isRainingPetalSlots = false;
return;
}
this.rainingPetalSlots.push(this.spawnRainPetalSlot(pc));
}, 10);
}
spawnRainPetalSlot(pc) {
const newPc = new PetalContainer(pc.petals.map(p => new Petal(p)),
{ ...pc }, Math.random(), pc.amount);
newPc.toOscillate = true;
newPc.toSkipCulling = true;//toSkipCulling
newPc.isDisplayPetalContainer = true;
newPc.renderAnimationTimer = 0;
newPc.y = canvas.h//canvas.w - newPc.w / 2 //+ newPc.w * Math.sqrt(2);
newPc.render.y = newPc.y;
newPc.x = canvas.w / 2 + (Math.random() * 2 - 1) * canvas.w * .4;
newPc.render.x = newPc.x;
newPc.angleOffset = - Math.PI * 2 + (Math.random() * 2 - 1) * Math.PI * .2;
newPc.angleOffsetVel = Math.sqrt((Math.random() * 2 - 1) * .03);
pc.x += pc.xv;
pc.y += pc.yv;
pc.yv += 0.03;
if (pc.y > canvas.height + pc.w * Math.sqrt(2) && pc.yv > 0) {
pc.toRemove = true;
}
}
renderRainPetalSlots() {
for (let i = 0; i < this.rainingPetalSlots.length; i++) {
this.rainingPetalSlots[i].draw();
// ctx.beginPath();
// ctx.fillStyle = 'red';
// ctx.arc(this.rainingPetalSlots[i].render.x,
this.rainingPetalSlots[i].render.y, 30, 0, Math.PI * 2);
// ctx.fill();
// ctx.closePath();
this.simulateRainPetalSlot(this.rainingPetalSlots[i]);
}
this.rainingPetalSlots = this.rainingPetalSlots.filter(p => p.toRemove !==
true);
if (this.rainingPetalSlots.length === 0 && this.rainInterval === undefined)
{
this.isRainingPetalSlots = false;
}
}
mouseUp({ mouseX, mouseY }) {
this.draggingScrollBar = false;
this.draggingHorizontalScrollBar = false;
}
mouseMove({ mouseX, mouseY }) {
this.hoveringOverHorizontalScrollBar = false;
this.hoveringOverScrollBar = false;
craftingMenu.petalContainers2 = redefineCraftingMenu.petalContainers2
craftingMenu.startRainingPetalSlots = redefineCraftingMenu.startRainingPetalSlots
craftingMenu.runCraftingAnimation = redefineCraftingMenu.runCraftingAnimation
craftingMenu.addCraftingPetalContainers =
redefineCraftingMenu.addCraftingPetalContainers
craftingMenu.drawInventory = redefineCraftingMenu.drawInventory
craftingMenu.recalculateTypeIndexes = redefineCraftingMenu.recalculateTypeIndexes
craftingMenu.addPetalContainer = redefineCraftingMenu.addPetalContainer
craftingMenu.processCraftResults = redefineCraftingMenu.processCraftResults
craftingMenu.inventorySpace.w = 10000
craftingMenu.petalContainerSize = 42.7
this.calculateDimensions();
this.hasInit = false;
// this.level += .001;
ctx.beginPath();
ctx.fillStyle = '#333333';
ctx.beginPath();
ctx.roundRect(this.dimensions.x, this.dimensions.y, this.dimensions.w,
this.dimensions.h, this.dimensions.roundness);
ctx.fill();
ctx.closePath();
ctx.fillStyle = '#e2eb67';
ctx.beginPath();
ctx.roundRect(this.dimensions.x + this.dimensions.innerPadding,
this.dimensions.y + this.dimensions.innerPadding, this.dimensions.h +
(this.dimensions.w - this.dimensions.h) * (this.render.level % 1) -
this.dimensions.innerPadding * 2, this.dimensions.h - this.dimensions.innerPadding
* 2, this.dimensions.roundness);
ctx.fill();
ctx.closePath();
ctx.globalAlpha = 1;
ctx.fillStyle = '#f0f0f0';
ctx.strokeStyle = 'black';
ctx.lineWidth = 2.25;
ctx.textAlign = 'center';
ctx.textBaseline = 'middle';
ctx.font = `900 18px Ubuntu`;
this.chatOpen = false;
}
start() {
window.onkeydown = (e) => this.handleKey(e);
window.onkeyup = (e) => this.handleKey(e);
window.onmousemove = (e) => this.handleMouse(e);
// make sure the user hasn't selected / deselected the chat between inputs
this.updateChat();
this.chatOpen = false;
chatInput.value = '';
chatInput.blur();
chatInput.style.opacity = "0";
// reset inputs to prevent ghosting
// for(let key in this.input){
// this.input[key] = false;
// }
} else if (e.type === 'keydown') {
// focus chat
this.chatOpen = true;
chatDiv.classList.remove('hidden');
chatInput.focus();
chatInput.style.opacity = "1";
/*if (e.code === "Semicolon" && e.repeat === false && e.type === 'keydown')
{
window.toRenderDebug = !window.toRenderDebug;
window.fps = 0;
window.framesRendered = 0;
window.lastFramesRenderedResetTime = performance.now();
}*/
// swapping petals
if (e.code === "Period" && e.repeat == false && e.type == 'keydown' &&
e.shiftKey && e.ctrlKey) {
send({ leaveGame: true, real: true })
petalReloadData = {}
petalHpData = {}
hoverOverX = false
}
if (e.code === "Backquote" && e.repeat == false && e.type == 'keydown') {
let input = prompt("Follow/Unfollow user? Type clear to clear
followers. (Followed: "+window.flowrMod.priority.toString()+")","Thivs")
if (input == 'clear') {
let imation = prompt("[Y/N] Are you sure you want to clear your
followers?","n")
if (imation == "Y" || imation == "y") {
window.flowrMod.priority = []
window.scripts.flowrMod.priority = []
localStorage.setItem('scripts', JSON.stringify(scripts));
}
} else {
let followed = window.flowrMod.priority.indexOf(input)
let imation = prompt("[Y/N] Are you sure you want to "+((followed >
-1) ? "unfollow" : "follow")+" "+input,"n")
if (imation == "Y" || imation == "y") {
if (followed === -1) {
window.flowrMod.priority.push(input)
window.scripts.flowrMod.priority.push(input)
} else {
delete window.flowrMod.priority[followed]
delete window.scripts.flowrMod.priority[followed]
}
localStorage.setItem('scripts', JSON.stringify(scripts));
}
}
}
if (e.code.startsWith("Digit") === true && e.repeat === false && e.type ===
'keydown' && document.activeElement.tagName !== 'INPUT') {
const petalIndex = e.code === "Digit0" ? 9 : e.code[5] - 1;
if (!e.ctrlKey) {
if (petalIndex === undefined) return;
if (window.state === 'menu') {
menuInventory.swapPetals(petalIndex);
} else {
inventory.swapPetals(petalIndex);
}
} else {
window.flowrMod.PetalLocks[petalIndex] = !
window.flowrMod.PetalLocks[petalIndex]
}
}
else if (e.code === "KeyR" && e.repeat === false && e.type === 'keydown' &&
document.activeElement.tagName !== 'INPUT') {
for (let i = 0; i < 10; i++) {
if (!window.flowrMod.PetalLocks[i]) { inventory.swapPetals(i); }
}
}
// else if (e.key === "f" && e.repeat === false && e.type === 'keydown' &&
document.activeElement.tagName !== 'INPUT'){
// window.toRenderHitboxes = !window.toRenderHitboxes;
// }
let velX = 0;
let velY = 0;
if (me.input["up"]) {
velY -= 1;
}
if (me.input["down"]) {
velY += 1;
}
if (me.input["left"]) {
velX -= 1;
}
if (me.input["right"]) {
velX += 1;
}
let angle = Math.atan2(velY, velX);
if (velY != 0 || velX != 0) {
me.angle = angle;
me.magnitude = 999;
}
}
}
if (e.key == " " || e.key == "e") {
send({ attack: e.type === 'keydown' });
room.flowers[window.selfId].attacking = e.type === 'keydown';
}
if (e.key == "Shift" || e.key == "q") {
send({ defend: e.type === 'keydown' });
room.flowers[window.selfId].defending = e.type === 'keydown';
}
if (e.key == "[" && e.type === 'keydown') {
fov = 1;
}
if (e.code == "Equal" && e.type === 'keydown') {
fov *= (1 + 2 / 5);
if (fov < 0.1) {
fov = 0.1;
}
if (fov > 6) {
fov = 6;
}
}
if (e.code == "Minus" && e.type === 'keydown') {
fov *= (1 - 2 / 5);
if (fov < 0.1) {
fov = 0.1;
}
if (fov > 6) {
fov = 6;
}
}
if (e.ctrlKey === false) {
if (e.key == ";" && e.type === 'keydown') {
send(['c',
window.flowrMod.rarities[window.flowrMod.callout].display+" Spawning"]);
//send(['c', window.flowrMod.callout]);
}
if (e.key == ":" && e.type === 'keydown') {
send(['c',
window.flowrMod.rarities[Math.round(window.flowrMod.callout)+1].display+"
Spawning"]);
//send(['c', window.flowrMod.callout]);
}
} else if (e.type === 'keydown') {
if (e.key == ";") {
send(['c',
window.flowrMod.rarities[Math.round(window.flowrMod.callout)+2].display+"
Spawning"]);
} else if (e.key == ":") {
send(['c',"Pearls"]);
}
}
if (e.altKey === true && e.key == "h"&& e.type === 'keydown') {
window.flowrMod.hitbox = !window.flowrMod.hitbox
window.scripts.flowrMod.hitbox = !window.flowrMod.hitbox
}
if (e.altKey === true && e.key == "s"&& e.type === 'keydown') {
window.flowrMod.skins = !window.flowrMod.skins
window.scripts.flowrMod.skins = !window.flowrMod.skins
}
}
if (window.state === 'menu' && e.type === 'keydown' &&
document.activeElement.tagName !== 'INPUT') {
if (e.key.toLowerCase() === 'x') {
globalInventory.toggleMenu();
} else if (e.key.toLowerCase() === 'c') {
craftingMenu.toggleMenu();
} else if (e.key.toLowerCase() === 'v') {
mobGallery.toggleMenu();
}
}
}
sendInitialInput() {
if (mouseMovement) {
const dX = mouse.x - window.innerWidth / 2;
const dY = mouse.y - window.innerHeight / 2;
let magnitude = Math.sqrt(dY ** 2 + dX ** 2);
if (magnitude >= 220) {
magnitude = 220;
} else {
magnitude = ((magnitude / 220) ** 0.9) * 220;
}
if (latestInput.length != 2) {
latestInput = [0, 0];
}
const angle = Math.atan2(dY, dX);
latestInput[0] = Math.round(angle * 1000) / 1000;
latestInput[1] = Math.round(magnitude * 10) / 10;
send(latestInput);
}
}
handleMouse(e) {
const dX = e.x - window.innerWidth / 2;
const dY = e.y - window.innerHeight / 2;
const me = room.flowers[window.selfId];
if (window.connected === true && me !== undefined && mouseMovement) {
let magnitude = Math.sqrt(dY ** 2 + dX ** 2);
if (magnitude >= 220) {
magnitude = 220;
} else {
magnitude = ((magnitude / 220) ** 0.9) * 220;
}
me.angle = Math.atan2(dY, dX);
me.magnitude = magnitude;
if (latestInput.length != 2) {
latestInput = [0, 0];
}
latestInput[0] = Math.round(me.angle * 1000) / 1000;
latestInput[1] = Math.round(magnitude * 10) / 10;
// const me = room.flowers[window.selfId];
// if(me !== undefined){
// me.angle = Math.atan2(dY, dX);
// me.magnitude = Math.min(220, Math.sqrt(dY**2 + dX**2));
// if(me.magnitude < 220){
// me.magnitude = ((me.magnitude / 220) ** 0.9) * 220;
// }
// }
// console.log(dY, dX);
// for menu
mouse.x = e.pageX;
mouse.y = e.pageY;
mouse.canvasX = mouse.x / window.innerWidth * canvas.w;
mouse.canvasY = mouse.y / window.innerHeight * canvas.h;
this.hoveringOverButton = false;
this.hoveringOverX = false;
this.menuActive = false;
this.lastCloseTime = 0;
this.lastOpenTime = 0;
this.toRegenerate = true;
this.fillerPetalSlots = {};
this.scrollExcess = { x: 0, y: 0 };
}
fadeOut() {
this.fadingOut = true;
this.originalFadeOutTime = time;
setTimeout(() => {
delete this.fadingOut;
if (this.menuActive === true) {
this.toggleMenu();
}
}, 100);
}
resize(h = undefined) {
this.dimensions = {
x: 130,
y: canvas.h - this.h - 20,
w: 645,
h: h ?? 382,
};
// this isnt actually used to draw the icon, messy code and going fast is
bad but it is what it is
// good for a static reference tho
this.iconDimensions = {
x: 20,
y: canvas.h - 20 - 80,
w: 80,
h: 80
};
this.XDimensions = {
x: this.x + this.w - 7.5 - 30 - 3,
y: this.y + 7.5 + 3,
w: 30,
h: 30
}
this.inventorySpace = {
x: this.x,
y: this.y,
w: this.w - 67,
h: this.h
// h: this.h * .52 - 4 - 24
}
this.scrollBarSize = 75;
this.scrollBounds = {
x: {
start: this.x + this.scrollBarSize / 2 + 14,
end: this.x + this.w - this.scrollBarSize / 2 - 14 - 20
},
y: {
start: this.y + this.scrollBarSize / 2 + 2 + 60,
end: this.y + this.h - this.scrollBarSize / 2 - 14
},
}
}
mouseDown({ x, y }) {
if (this.hoveringOverButton === true || this.hoveringOverX === true) {
// open menu
this.toggleMenu();
return;
}
// DISABLED
// if(this.menuActive === true){
// if(mouseInBox({x: mouse.canvasX, y: mouse.canvasY},
{...this.inventorySpace, h: this.inventorySpace.h -
(this.horizontalScrollBarEnabled === true ? 20 : 0)})){
// for(let type in this.rows){
// const row = this.rows[type];
// for(let i = 0; i < row.length; i++){
// if(row[i]?.petals !== undefined &&
row[i].petals[0].lastIsHovered === true/* && i >= 4*/){
// row[i].petals[0].lastIsHovered = false;
// sendRoomRequest({singleEnemyRoom: true, biome:
biomeManager.getCurrentBiomeData().current, type: type, rarity: i, petalData:
menuInventory.pack()});
// window.automaticallyLeaveFlag = true;
// }
// }
// }
// }
// }
}
getHorizScrollBarDimensions() {
return {
x: this.scrollBounds.x.start + this.scroll.render.x *
(this.scrollBounds.x.end - this.scrollBounds.x.start) - this.scrollBarSize / 2,
y: this.y + this.h - 17,
w: this.scrollBarSize,
h: 10
}
}
getVertScrollBarDimensions() {
return {
x: this.x + this.w - 20 - 10 / 2,
y: this.scrollBounds.y.start + this.scroll.render.y *
(this.scrollBounds.y.end - this.scrollBounds.y.start) - this.scrollBarSize / 2,
w: 10,
h: this.scrollBarSize,
}
}
mouseMove({ x, y }) {
if (this.menuActive !== true) return;
this.hoveringOverScrollbarH = false;
this.hoveringOverScrollbarV = false;
if (mouseInBox({ x, y }, this.getHorizScrollBarDimensions())) {
this.hoveringOverScrollbarH = true;
} else if (mouseInBox({ x, y }, this.getVertScrollBarDimensions()) &&
this.scrollExcess.y > 0) {
this.hoveringOverScrollbarV = true;
}
if (this.draggingScrollBarH) {
const { start, end } = this.scrollBounds.x;
this.scroll.x = (x - start) / (end - start);
} else if (this.draggingScrollBarV) {
const { start, end } = this.scrollBounds.y;
this.scroll.y = (y - start) / (end - start);
}
}
mouseUp({ x, y }) {
if (this.menuActive !== true) return;
this.draggingScrollBarH = this.draggingScrollBarV = false;
}
getMainStroke() {
return '#b0ae3d';
}
getMainFill() {
return '#dbd74b';
}
getHoverFill() {
return blendColor('#dbd74b', '#FFFFFF', 0.1);
}
drawIcon() {
ctx.lineWidth = 6;
ctx.fillStyle = this.getMainFill();
ctx.strokeStyle = this.getMainStroke();
ctx.beginPath();
ctx.roundRect(20, canvas.h - 20 - 80, 80, 80, 3);
ctx.fill();
ctx.stroke();
ctx.closePath();
ctx.drawImage(this.icon, 20 + 15, canvas.h - 20 - 80 + 15, 80 - 15 * 2, 80
- 15 * 2);
ctx.fillStyle = '#f0f0f0';
ctx.strokeStyle = 'black';
ctx.lineWidth = 2.25;
ctx.textAlign = 'center';
ctx.textBaseline = 'middle';
ctx.font = `900 14px Ubuntu`;
const lastLetterSpacing = ctx.letterSpacing;
ctx.letterSpacing = '0px';
ctx.strokeText("[V]", 20 + 80 - 15 - 2.5, canvas.h - 20 - 80 + 15);
ctx.fillText("[V]", 20 + 80 - 15 - 2.5, canvas.h - 20 - 80 + 15);
ctx.letterSpacing = ctx.lastLetterSpacing;
}
toggleMenu() {
if (craftingMenu.menuActive === true) {
craftingMenu.toggleMenu();
}
if (globalInventory.menuActive === true) {
globalInventory.toggleMenu();
}
if (this.menuActive === true) {
this.lastCloseTime = time;
} else {
this.lastOpenTime = time;
if (globalInventory.menuActive === true) {
globalInventory.toggleMenu();
}
}
this.menuActive = !this.menuActive;
// console.log(this.menuActive);
// looping through all petals and making sure they're not hovered
for (let type in this.rows) {
const row = this.rows[type];
for (let i = 0; i < row.length; i++) {
if (row[i].petals === undefined) continue;
row[i].petals[0].lastIsHovered = false;
}
}
}
// DRAW --- MAIN METHOD
draw() {
if (Number.isFinite(this.y) === false) this.y = this.dimensions.y =
canvas.h - this.h - 20;
if (this.toRegenerate && Object.keys(window.enemyStats).length > 0) {
this.regenerateMobs(window.structuredClone(discoveredEnemies));
this.toRegenerate = false;
}
this.resize();
this.drawIcon(alpha);
drawScrollBars() {
ctx.beginPath();
ctx.moveTo(h.x, h.y + h.h / 2);
ctx.lineTo(h.x + h.w, h.y + h.h / 2);
ctx.stroke();
ctx.closePath();
}
if (this.scrollExcess.y > 0) {
const v = this.getVertScrollBarDimensions();
ctx.beginPath();
ctx.moveTo(v.x + v.w / 2, v.y);
ctx.lineTo(v.x + v.w / 2, v.y + v.h);
ctx.stroke();
ctx.closePath();
}
}
drawInventory(alpha = 1) {
// this.scroll.render = interpolate(this.scroll.render, this.scroll, 0.0070
* dt);
if (alpha !== 1) {
ctx.globalAlpha = alpha;
}
let translation = 0;
if (time - this.lastCloseTime < 160) {
translation += (this.h + 40) * easeOutCubic((time - this.lastCloseTime)
/ 160);
}
if (time - this.lastOpenTime < 160) {
translation += (this.h + 40) - (this.h + 40) * easeOutCubic((time -
this.lastOpenTime) / 160);
}
if (translation !== 0) {
ctx.translate(0, translation);
}
ctx.translate(this.x, this.y);
// if(time - this.lastCloseTime < 500){
// ctx.translate()
// }
ctx.fillStyle = this.getMainFill();
ctx.strokeStyle = this.getMainStroke();
ctx.lineWidth = 8;
ctx.beginPath()
ctx.roundRect(0, 0, this.w, this.h, 3);
ctx.fill();
ctx.stroke();
ctx.closePath();
// X rendering
ctx.translate(-3, 3);
ctx.strokeStyle = '#90464b';
ctx.lineWidth = 5;
ctx.beginPath();
ctx.roundRect(this.w - 7.5 - 30, 7.5, 30, 30, 6);
ctx.fill();
ctx.stroke();
ctx.closePath();
ctx.lineWidth = 4.75;
ctx.lineCap = 'round';
ctx.strokeStyle = '#cccccc';
ctx.beginPath();
ctx.moveTo(this.w - 30, 30);
ctx.lineTo(this.w - 7.5 * 2, 7.5 + 7.5);
ctx.stroke();
ctx.closePath();
ctx.beginPath();
ctx.moveTo(this.w - 7.5 * 2, 30);
ctx.lineTo(this.w - 30, 7.5 + 7.5);
ctx.stroke();
ctx.closePath();
ctx.translate(3, -3);
ctx.translate(-this.x, -this.y);
this.drawRows();
ctx.translate(this.x, this.y);
// stroking again so we dont get weird cuts with .clip
ctx.fillStyle = this.getMainFill();
ctx.strokeStyle = this.getMainStroke();
ctx.lineWidth = 8;
ctx.beginPath()
ctx.roundRect(0, 0, this.w, this.h, 3);
ctx.stroke();
ctx.closePath();
ctx.translate(-this.x, -this.y);
this.drawRowStatBoxes();
if (translation !== 0) {
ctx.translate(0, -translation);
}
ctx.globalAlpha = 1;
}
drawRows() {
if (window.enemyStats !== undefined && window.enemyStats['Ladybug']?.drops
=== undefined) {
// drops
window.calculateStats();
//console.log(window.enemyStats);
window.enemyStats[key].drops = drops;
}
let enemyStatsArray = [];
for (let key in baseStats.enemies) {
const stats = baseStats.enemies[key];
enemyStatsArray.push(key, stats.health, stats.damage, stats.speed,
stats.mass, stats.poison);
}
window.enemyStats[key].drops = drops;
}
}
if (Object.keys(this.rows).length === 0) {
const lastLetterSpacing = ctx.letterSpacing;
ctx.font = '900 102px Ubuntu';
ctx.letterSpacing = "-.05px";
ctx.textBaseline = 'middle';
ctx.textAlign = 'center';
ctx.fillStyle = 'white';
ctx.strokeStyle = 'black';
ctx.lineWidth = 8;
ctx.lineWidth = 3.5;
ctx.font = '900 16px Ubuntu';
ctx.strokeText("(No Mobs Discovered)", this.x + this.w / 2, this.y +
this.h / 2 + 35);
ctx.fillText("(No Mobs Discovered)", this.x + this.w / 2, this.y +
this.h / 2 + 35);
ctx.letterSpacing = lastLetterSpacing;
this.isEmpty = true;
} else {
this.isEmpty = false;
}
// ctx.clipping
ctx.save();
ctx.beginPath();
ctx.rect(this.inventorySpace.x, this.inventorySpace.y,
this.inventorySpace.w, this.inventorySpace.h - (this.horizontalScrollBarEnabled ===
true ? 20 : 0));
ctx.clip();
ctx.closePath();
ctx.translate(-this.scrollExcess.x * this.scroll.render.x, -
this.scrollExcess.y * this.scroll.render.y);
this.currentY = this.y - 3;
// console.log(this.rows);
let highestX = 0;
continue;
}
// draw pc
const pc = row[i];
pc.x = pcX;
pc.y = pcY;
if (pc.render.x + pc.w / 2 - this.scrollExcess.x *
this.scroll.render.x > Math.floor(this.x) * 0.9 && pc.render.x - pc.w / 2 -
this.scrollExcess.x * this.scroll.render.x < Math.ceil(this.w + this.x) * 1.1 &&
pc.render.y + pc.h / 2 - this.scrollExcess.y * this.scroll.render.y >
Math.floor(this.y) * 0.9 && pc.render.y - pc.h / 2 - this.scrollExcess.y *
this.scroll.render.y < Math.ceil(this.y + this.h) * 1.1) {
pc.draw();
}
}
this.currentY += rowHeight;
}
this.scrollExcess = {
x: highestX - this.w - pcHeight / 2,
y: this.currentY - this.y - this.h + pcHeight / 2
};
this.scrollExcess.x = Math.max(this.scrollExcess.x, 0);
this.scrollExcess.y = Math.max(this.scrollExcess.y, 0);
ctx.restore();
}
drawRowStatBoxes() {
const hoveringOverMenu = mouseInBox({ x: mouse.canvasX, y: mouse.canvasY },
{ ...this.inventorySpace, h: this.inventorySpace.h -
(this.horizontalScrollBarEnabled === true ? 20 : 0) });
// drawing stats boxes in another loop
for (let type in this.rows) {
const row = this.rows[type];
for (let i = 0; i < row.length; i++) {
if (row[i] === false || row[i] === true) continue;
const pc = row[i];
// enemy.radius = last.radius;
enemy.x = last.x;
enemy.y = last.y;
enemy.render.x = last.render.x;
enemy.render.y = last.render.y;
}
}
}
regenerateMobs(es) {
this.horizontalScrollBarEnabled = false;
this.rows = {};
for (let key in es) {
if (biomeTypes.includes(key)) {
this.addRow(key, es[key]);
}
}
} else {
const biomeTypes =
biomeEnemyMap[biomeManager.getCurrentBiomeData().current];
let rareBiomeTypes =
rareBiomeEnemyMap[biomeManager.getCurrentBiomeData().current];
let secretBiomeTypes =
secretBiomeEnemyMap[biomeManager.getCurrentBiomeData().current];
if (!rareBiomeTypes) {
rareBiomeTypes = [];
}
if (!secretBiomeTypes) {
secretBiomeTypes = [];
}
this.rows = {};
for (let key in es) {
if (biomeTypes.includes(key) || rareBiomeTypes.includes(key) ||
secretBiomeTypes.includes(key)) {
this.addRow(key, es[key]);
}
}
}
}
addRow(type, raritiesEnabled) {
this.rows[type] = [];
for (let i = 0; i < raritiesEnabled.length; i++) {
if (raritiesEnabled[i] === true) {
this.rows[type][i] = true;
if (i > 8) this.horizontalScrollBarEnabled = true;
} else {
this.rows[type][i] = false;
}
}
}
generateEnemyPc(type, rarity, dimensions) {
const radius = 200//Math.random() < 0.0001 ? 360 :
Math.sqrt(menuEnemyIncrementRadii[Math.floor(Math.random() *
menuEnemyIncrementRadii.length)] * (Math.random() * 0.1 + 0.95)) * 8.7;
enemy.angle = -Math.PI / 4
stats.xp = scalars.xp;
stats.health *= scalars.health;
stats.damage *= scalars.damage;
if (type == "Starfish") {
stats.healing = formatAmountHighPrecision(Math.round(stats.health *
0.007 * 30 * 100) / 100) + "/s";
}
if (this.type == "Jellyfish") {
stats.lightningDamage = Math.round(stats.damage * 1.5 * 1000) / 1000
}
if (stats.poison) {
stats.poison[0] = Math.round(stats.poison[0] * scalars.damage * 1000) /
1000;
stats.poison[1] = Math.round(stats.poison[1] * scalars.damage * 1000) /
1000;
}
stats.detectionDistance = scalars.detectionDistance;
stats.mass *= scalars.mass;
mobGallery.regenerateMobs = redefineMobGallery.regenerateMobs
mobGallery.drawRows = redefineMobGallery.drawRows
mobGallery.drawScrollBars = redefineMobGallery.drawScrollBars
mobGallery.generateEnemyPc = redefineMobGallery.generateEnemyPc
this.hoveringOverButton = false;
this.hoveringOverX = false;
this.menuActive = false;
this.w = 445;//510;
this.h = 665;//740;
this.scroll = 5;
this.render = { scroll: this.scroll };
this.draggingScrollBar = false;
this.totalPetalHeight = 0;
this.hoveringOverScrollbar = false;
this.scrollBarActive = false;
}
resizeScroll() {
if (this.resizeFlag !== undefined) {
return;
}
const scrollBarProjections = {
top: (canvas.h - this.h - 20) + this.scrollbar.length * .5 + 60,
bottom: (canvas.h - 20) - this.scrollbar.length * .5 + 30
}
this.scrollbar.top = this.scrollbar.bottom = scrollBarProjections.top +
this.scrollbar.length;
this.resizeFlag = true;
}
drawIcon(alpha = 1) {
if (alpha !== 1) {
ctx.globalAlpha = alpha;
}
// these colors are taken from florr.io, not hornex. They are the exact
same. I checked.
ctx.fillStyle = '#5a9fdb';
ctx.strokeStyle = '#4981b1';
if (mouse.canvasX + 6 > 20 && mouse.canvasY + 6 > canvas.h - 20 - 80 - 100
- 100 && mouse.canvasX - 6 < 20 + 80 && mouse.canvasY - 6 < canvas.h - 20 - 80 + 80
- 100 - 100) {
ctx.fillStyle = '#6aa8df';
setCursor('pointer');
this.hoveringOverButton = true;
} else {
// if(this.hoveringOverX === false){
// document.body.style.cursor = 'auto';
// }
this.hoveringOverButton = false;
}
ctx.lineWidth = 6;
ctx.beginPath();
ctx.roundRect(20, canvas.h - 20 - 80 - 100 - 100, 80, 80, 3);
ctx.fill();
ctx.stroke();
ctx.closePath();
ctx.drawImage(this.icon, 20 + 15, canvas.h - 20 - 80 + 15 - 100 - 100, 80 -
15 * 2, 80 - 15 * 2);
ctx.globalAlpha = 1;
}
draw() {
let alpha = this.fadingOut === true ? 1 - (time - this.originalFadeOutTime)
/ 100 : 1;
this.drawIcon(alpha);
// if(savedPetals){
// for(let key in savedPetals.top){
// const pc = savedPetals.top[key];
// this.removeByRarityAndType(pc.rarity, pc.type);
// }
// for(let key in savedPetals.bottom){
// const pc = savedPetals.bottom[key];
// this.removeByRarityAndType(pc.rarity, pc.type);
// }
// }
// const me = room.flowers[window.selfId];
// setTimeout(() => {
// const lastLength = this.petalContainers[p.rarity.length];
// this.petalContainers[p.rarity] =
this.petalContainers[p.rarity].filter(p2 => p2 !== p);
// if(lastLength === this.petalContainers[p.rarity].length){
// for(let i = 0; i < this.petalContainers[p.rarity]; i++){
// if(this.petalContainers[p.rarity][i].type ===
p.type){
// this.removePetalContainer(p.rarity, i);
// return;
// }
// }
// }
// }, 2000)
// return;
// } else {
return;
// }
}// else {
// this.petalContainers[p.rarity].unshift(p);
// this.petalContainers[p.rarity].sort();
// }
p.w = 62;
p.h = 62;
this.petalContainers[p.rarity].sort();
// adding camera render so that it looks the same even without translation
// p.render.x += canvas.w/2-me.render.headX;
// p.render.y += canvas.h/2-me.render.headY;
}
removeByRarityAndType(rarity, type) {
if (this.petalContainers[rarity]?.length === undefined) {
return;
}
for (let i = 0; i < this.petalContainers[rarity].length; i++) {
if (this.petalContainers[rarity][i].type === type) {
this.removePetalContainer(rarity, i);
return true;
}
}
// why is this here?? wtf?
// craftingMenu.removePetalContainer(type, rarity);
return false;
}
ReturnRarityAndType(rarity, type) {
if (this.petalContainers[rarity]?.length === undefined) {
return false;
}
for (let i = 0; i < this.petalContainers[rarity].length; i++) {
if (this.petalContainers[rarity][i].type === type) {
return this.petalContainers[rarity][i];
}
}
return false;
}
removeByRarityAndTypeAndReturn(rarity, type) {
if (this.petalContainers[rarity]?.length === undefined) {
return false;
}
for (let i = 0; i < this.petalContainers[rarity].length; i++) {
if (this.petalContainers[rarity][i].type === type) {
return this.removePetalContainer(rarity, i);
}
}
// why is this here?? wtf?
// craftingMenu.removePetalContainer(type, rarity);
return false;
}
removePetalContainer(rarity, indexInRarity) {
const petalContainer = this.petalContainers[rarity][indexInRarity];
craftingMenu.removePetalContainer(petalContainer.type,
petalContainer.rarity);
if (petalContainer.amount >= 2) {
petalContainer.amount--;
petalContainer.lastAmountChangedTime = time;
} else {
this.petalContainers[rarity].splice(indexInRarity, 1);
}
return petalContainer;
// for(let i = 0; i < this.petalContainers[p.rarity].length; i++){
// const petalContainer = this.petalContainers[p.rarity][i];
// if(petalContainer === p){
// console.log(p);
// if(petalContainer.amount >= 2){
// p.amount--;
// p.lastAmountChangedTime = time;
// } else {
// this.petalContainers[p.rarity].splice(i,1);
// }
// return p;
// }
// }
// console.log('not found');
// this.petalContainers[p.rarity] =
this.petalContainers[p.rarity].filter(p2 => p2 !== p);
}
removePetalContainerAmount(rarity, indexInRarity, amount) {
const petalContainer = this.petalContainers[rarity][indexInRarity];
if (petalContainer.amount >= amount + 1) {
petalContainer.amount -= amount;
petalContainer.lastAmountChangedTime = time;
} else {
this.petalContainers[rarity].splice(indexInRarity, 1);
}
craftingMenu.removePetalContainerAmount(petalContainer.type,
petalContainer.rarity, amount);
}
mouseDown({ mouseX, mouseY }, inv) {
if (this.removeDraggingAnim) {
clearTimeout(this.removeDraggingAnim);
draggingPetalContainer = null;
delete this.removeDraggingAnim;
}
for (let i in this.petalContainers) {
if (this.petalContainers[i] === undefined) {
continue;
}
for (let j = 0; j < this.petalContainers[i].length; j++) {
const petalContainer = this.petalContainers[i][j];
if (petalContainer.greyed === true) continue;
// console.log({petalContainer, mouseX, mouseY})
// 130, canvas.h - this.h - 20
if (mouseX > 130 + petalContainer.x - petalContainer.w / 2 &&
mouseX < 130 + petalContainer.x + petalContainer.w / 2 && mouseY > canvas.h -
this.h - 20 + petalContainer.y - petalContainer.h / 2 && mouseY < canvas.h - this.h
- 20 + petalContainer.y + petalContainer.h / 2) {
// for now we'll just equip the petal, but in the future we
would want to start a petal drag
// let position = -1;
// let isTop = true;
// for(let k = 0; k < inv.topPetalSlots.length; k++){
// if(inv.topPetalContainers[k] === undefined){
// position = k;
// break;
// }
// }
// if(position === -1){
// for(let k = 0; k < inv.bottomPetalSlots.length; k++){
// if(inv.bottomPetalContainers[k] === undefined){
// position = k;
// isTop = false;
// break;
// }
// }
// }
// // console.log({position});
// if(position === -1){
// return;
// }
// inv.addPetalContainer(new
PetalContainer(petalContainer.petals, petalContainer, petalContainer.id, 1), isTop,
position);
// this.removePetalContainer(petalContainer);
// return;
const removedPC = this.removePetalContainer(i, j);
draggingPetalContainer = new PetalContainer(removedPC.petals, {
...removedPC, isDragging: true }, Math.random(), 1)//petalContainer;
draggingPetalContainer.x += 130;
draggingPetalContainer.render.x += 130;
draggingPetalContainer.y += canvas.h - this.h - 20;
draggingPetalContainer.render.y += canvas.h - this.h - 20;
draggingPetalContainer.amount = 1;
draggingPetalContainer.mouseOffset = {
x: draggingPetalContainer.x - mouseX,
y: draggingPetalContainer.y - mouseY
}
draggingPetalContainer.w = 85;
draggingPetalContainer.h = 85;
// draggingPetalContainer.spawnAnimation = .8;
}
}
}
if (
mouseX < this.w - 16 + 12 + 130 &&
mouseX > this.w - 16 - 12 + 130 &&
mouseY > (this.scrollbar.bottom) &&
mouseY < (this.scrollbar.top)
) {
this.draggingScrollBar = true;
}
}
mouseUp({ mouseX, mouseY }, inv, skipFastFlag = false) {
this.draggingScrollBar = false;
// delete this.scrollbarMouseOffset;
if (this.removeDraggingAnim) {
clearTimeout(this.removeDraggingAnim);
draggingPetalContainer = null;
delete this.removeDraggingAnim;
}
// console.log(Math.sqrt((mouse.lastDownData.x-mouse.x)**2+
(mouse.lastDownData.y-mouse.y)**2));
if (draggingPetalContainer !== null) {
if (skipFastFlag === false && time - mouse.lastDownData.time < 300 &&
Math.sqrt((mouse.lastDownData.x - mouse.x) ** 2 + (mouse.lastDownData.y - mouse.y)
** 2) < 20) {
if (draggingPetalContainer.lastPetalSlot !== undefined &&
draggingPetalContainer.lastPetalSlot.index !== -1) {
if (draggingPetalContainer.lastPetalSlot.top === true) {
if
(inv.bottomPetalContainers[draggingPetalContainer.lastPetalSlot.index] ===
undefined) {
this.mouseUp(...arguments, true);
return;
}
} else {
if
(inv.topPetalContainers[draggingPetalContainer.lastPetalSlot.index] === undefined)
{
this.mouseUp(...arguments, true);
return;
}
}
// if the petal is in Inventory then try and swap it.
// add it back
inv.addPetalContainer(draggingPetalContainer,
draggingPetalContainer.lastPetalSlot.top,
draggingPetalContainer.lastPetalSlot.index);
// swap it
inv.swapPetals(draggingPetalContainer.lastPetalSlot.index,
false);
draggingPetalContainer = null;
return;
} else {
// otherwise if it came from globalInventory then try and equip
it
if (inv.addInFirstAvailableSlot(draggingPetalContainer) ===
true) {
draggingPetalContainer = null;
return;
}
}
}
if (inv.addClosest(draggingPetalContainer, this) === true) {
draggingPetalContainer = null;
} else {
// if(this.menuActive === false){
const render =
window.structuredClone(draggingPetalContainer.render);
const mouseOffset = { x: draggingPetalContainer.mouseOffset.x, y:
draggingPetalContainer.mouseOffset.y };
// let clone = new PetalContainer(draggingPetalContainer.petals,
{...draggingPetalContainer}, Math.random(), draggingPetalContainer.amount);
this.addPetalContainer(draggingPetalContainer);
draggingPetalContainer = new
PetalContainer(draggingPetalContainer.petals, { ...draggingPetalContainer,
isDragging: true }, Math.random(), draggingPetalContainer.amount);//p.collectTime =
time;
for (let key in render) {
draggingPetalContainer[key] = render[key];
}
draggingPetalContainer.mouseOffset = mouseOffset;
draggingPetalContainer.x = render.x;
draggingPetalContainer.y = render.y;
draggingPetalContainer.spawnAnimation = 1;
draggingPetalContainer.collectTime = time;
this.removeDraggingAnim = setTimeout(() => {
draggingPetalContainer = null;
delete this.removeDraggingAnim;
}, 150)
// } else {
// this.addPetalContainer(draggingPetalContainer);
// draggingPetalContainer = null;
// }
}
}
}
drawInventory(alpha = 1) {
this.render.scroll = interpolate(this.render.scroll, this.scroll, 0.0070 *
dt);
if (alpha !== 1) {
ctx.globalAlpha = alpha;
}
let translation = 0;
if (time - this.lastCloseTime < 160) {
translation += this.h * easeOutCubic((time - this.lastCloseTime) /
160);
}
if (time - this.lastOpenTime < 160) {
translation += (this.h + 40) - (this.h + 40) * easeOutCubic((time -
this.lastOpenTime) / 160);
}
if (translation !== 0) {
ctx.translate(0, translation);
}
ctx.save();
ctx.beginPath()
ctx.roundRect(0, 0, this.w, this.h, 3);
ctx.fill();
ctx.stroke();
ctx.clip();
ctx.closePath();
const petalContainersPerRow = 5;
const padding = 35;
const rightPadding = 50;// scroll bar is here so we need more
const petalContainerSize = 65//(this.petalContainers[0] ?? {w: 0}).w;
let renderIndex = 0;
for (let i = numberOfRarities - 1; i >= 0; i--) {
if (this.petalContainers[i] === undefined) {
continue;
}
for (let j = 0; j < this.petalContainers[i].length; j++) {
const petalContainer = this.petalContainers[i][j];
if (petalContainer.isTempAnimation === true) {
var lastRenderIndex = renderIndex;
renderIndex =
petalContainer.realNonAnimationParent.renderIndex;
}
petalContainer.x = petalContainerSize / 2 + padding + (renderIndex
% petalContainersPerRow) / (petalContainersPerRow - 1) * (this.w -
petalContainerSize - padding - rightPadding);
petalContainer.y = padding + petalContainerSize / 2 +
Math.floor(renderIndex / petalContainersPerRow) * (petalContainerSize + 12) +
this.render.scroll;
petalContainer.renderIndex = renderIndex;
// really unoptimized lol
if (firstPetalContainer === null) {
firstPetalContainer = petalContainer;
}
lastPetalContainer = petalContainer;
petalContainer.relativeY = Math.floor(renderIndex /
petalContainersPerRow) * (petalContainerSize + 12) + petalContainerSize / 2 +
this.render.scroll;
if (petalContainer.relativeY - petalContainer.y +
petalContainer.render.y < this.h - padding /*-*/ + petalContainerSize &&
petalContainer.relativeY - petalContainer.y + petalContainer.render.y > /*padding*/
- petalContainerSize * 2) {
// if(this.h - petalContainer.relativeY < petalContainerSize /
2){
// ctx.globalAlpha = (this.h - petalContainer.relativeY) /
petalContainerSize / 2;
// }
if (petalContainer.lastOutTime !== undefined) {
delete petalContainer.lastOutTime;
petalContainer.lastInTime = time;
}
petalContainer.draw();
// ctx.globalAlpha = 1;
} else {
// if(petalContainer.lastOutTime === undefined){
// petalContainer.lastOutTime = time;
// }
// if(petalContainer.lastInTime !== undefined){
// delete petalContainer.lastInTime;
// }
// if(time - petalContainer.lastOutTime < 300){
// ctx.globalAlpha = (1 - (time -
petalContainer.lastOutTime) / 300) ** 2;
// petalContainer.draw();
// ctx.globalAlpha = 1;
// } else {
petalContainer.updateInterpolate();
// }
}
renderIndex++;
if (petalContainer.isTempAnimation === true) {
renderIndex = lastRenderIndex;
}
}
}
ctx.restore();
ctx.save();
ctx.beginPath()
ctx.roundRect(0, 0, this.w, this.h, 3);
ctx.stroke();
ctx.closePath();
// console.log(this.menuHeights.beginning - this.menuHeights.end);
// this.scrollbar.length = ((this.menuHeights.beginning -
this.menuHeights.end) + this.h - petalContainerSize - 5); // max scroll
// this.scrollbar.top = ratio * (this.h - this.scrollbar.length);
// this.scrollbar.bottom = ratio * (this.h - this.scrollbar.length)
+ this.scrollbar.length;
// const mouseProjections = {
// top: scrollBarProjections.top - this.scrollbar.length * .25,
// bottom: scrollBarProjections.bottom - this.scrollbar.length
* .25 + 30
// }
// // console.log(scrollBarProjections.bottom - canvas.h);
// ctx.translate(-130, -(canvas.h - this.h - 20));
// ctx.fillStyle = 'blue';
// ctx.beginPath();
// ctx.arc(0, mouseProjections.bottom, 30, 0, Math.PI * 2);
// ctx.fill();
// ctx.closePath();
// ctx.beginPath();
// ctx.arc(0, mouseProjections.top, 30, 0, Math.PI * 2);
// ctx.fill();
// ctx.closePath();
// ctx.translate(130, (canvas.h - this.h - 20));
this.totalPetalHeight = (this.menuHeights.beginning -
this.menuHeights.end);
this.scrollbar.renderTop = interpolate(this.scrollbar.renderTop,
this.scrollbar.top, this.draggingScrollBar ? 0.28 : 0.08);
this.scrollbar.renderBottom = interpolate(this.scrollbar.renderBottom,
this.scrollbar.bottom, this.draggingScrollBar ? 0.28 : 0.08);
// console.log(this.scrollBarActive);
if (this.scrollBarActive !== false &&
Object.keys(this.petalContainers).length > 0) {
ctx.translate(0, -(canvas.h - this.h - 20));
ctx.strokeStyle = '#4981b1';
ctx.lineWidth = 8;
ctx.lineCap = 'round';
ctx.beginPath();
ctx.moveTo(this.w - 16, (this.scrollbar.renderTop) /** ((this.h - 82 -
16) / this.h) + 82*/);
ctx.lineTo(this.w - 16, (this.scrollbar.renderBottom) /** ((this.h - 82
- 16) / this.h) + 82*/);
ctx.stroke();
ctx.closePath();
ctx.translate(0, (canvas.h - this.h - 20));
}
ctx.translate(-3, 3);
ctx.strokeStyle = '#90464b';
ctx.lineWidth = 5;
ctx.beginPath();
ctx.roundRect(this.w - 7.5 - 30, 7.5, 30, 30, 6);
ctx.fill();
ctx.stroke();
ctx.closePath();
ctx.lineWidth = 4.75;
ctx.lineCap = 'round';
ctx.strokeStyle = '#cccccc';
ctx.beginPath();
ctx.moveTo(this.w - 30, 30);
ctx.lineTo(this.w - 7.5 * 2, 7.5 + 7.5);
ctx.stroke();
ctx.closePath();
ctx.beginPath();
ctx.moveTo(this.w - 7.5 * 2, 30);
ctx.lineTo(this.w - 30, 7.5 + 7.5);
ctx.stroke();
ctx.closePath();
ctx.translate(3, -3);
// ctx.beginPath();
// ctx.moveTo(this.w - 7.5, 7.5 - 7.5 - 7.5, 30 + 7.5 + 7.5);
// ctx.lineTo(this.w - 7.5 - 30, 15 + 30 + 15);
// ctx.stroke();
// ctx.closePath();
if (
mouseRelative.x > petalContainer.render.x -
(petalContainer.w / 2 + 6) &&
mouseRelative.x < petalContainer.render.x +
(petalContainer.w / 2 + 6) &&
mouseRelative.y > petalContainer.render.y -
(petalContainer.h / 2 + 6) &&
mouseRelative.y < petalContainer.render.y +
(petalContainer.h / 2 + 6)
) {
petalContainer.isHovered = true;
}
petalContainer.drawStatsBox();
}
}
ctx.setTransform(ctx.lastTransform6);
delete ctx.lastTransform6;
}
if (translation !== 0) {
ctx.translate(0, -translation);
}
ctx.globalAlpha = 1;
// ctx.fillStyle = 'red';
// const scrollBarProjections = {
// top: (canvas.h - this.h - 20) + 85 + this.scrollbar.length - 130,
// bottom: (canvas.h - 20) - 16 + this.scrollbar.length - 130 - 22
// }
// ctx.beginPath();
// ctx.arc(130, scrollBarProjections.top, 12, 0, Math.PI * 2);
// ctx.fill();
// ctx.closePath();
// ctx.beginPath();
// ctx.arc(130, scrollBarProjections.bottom, 12, 0, Math.PI * 2);
// ctx.fill();
// ctx.closePath();
}
updateScroll(/*delta*/{ x, y }, { mouseX, mouseY }) {
if (this.menuActive !== true) {
return;
}
if (mouseX < 130 || mouseY < canvas.h - this.h - 20 || mouseX > 130 +
this.w || mouseY > canvas.h - 20) {
return;
}
this.scroll -= y;
// let counter = 0;
// let intrvl = setInterval(() => {
// counter++;
// if(counter > 10){
// clearInterval(intrvl);
// return;
// }
// for(let i = numberOfRarities-1; i >= 0; i--){
// if(this.petalContainers[i] === undefined){
// continue;
// }
// for(let j = 0; j < this.petalContainers[i].length; j++){
// const petalContainer = this.petalContainers[i][j];
// if(petalContainer.lastInTime !== undefined){
// petalContainer.lastInTime -= Math.abs(y) * 3;
// }
// if(petalContainer.lastOutTime !== undefined){
// petalContainer.lastOutTime -= Math.abs(y) * 3;
// }
// }
// }
// }, 100)
}
mouseMove({ mouseX, mouseY }) {
if (
mouseX < this.w - 16 + 12 + 130 &&
mouseX > this.w - 16 - 12 + 130 &&
mouseY > (this.scrollbar.bottom) &&
mouseY < (this.scrollbar.top)
) {
this.hoveringOverScrollbar = true;
// setCursor('pointer');
// this.scrollbarMouseOffset = 0//(this.scrollbar.top) * ((this.h - 82
- 16) / this.h) + 82 + (canvas.h - this.h - 20) - mouseY;
} else {
this.hoveringOverScrollbar = false;
}
/*
//Tooltip
for(let i in this.petalContainers){
if(this.petalContainers[i] === undefined){
continue;
}
for(let j = 0; j < this.petalContainers[i].length; j++){
const petalContainer = this.petalContainers[i][j];
if(mouseX > 130 + petalContainer.x - petalContainer.w/2 && mouseX <
130 + petalContainer.x + petalContainer.w/2 && mouseY > canvas.h - this.h - 20 +
petalContainer.y - petalContainer.h/2 && mouseY < canvas.h - this.h - 20 +
petalContainer.y + petalContainer.h/2){
console.log(petalContainer.type, petalContainer.rarity)
}
}
}
*/
if (this.draggingScrollBar !== true ||
Object.keys(this.petalContainers).length === 0) {
return;
}
const scrollBarProjections = {
top: (canvas.h - this.h - 20) + this.scrollbar.length * .5 + 60,
bottom: (canvas.h - 20) - this.scrollbar.length * .5 + 30
}
const mouseProjections = {
top: scrollBarProjections.top - this.scrollbar.length * .25,
bottom: scrollBarProjections.bottom + this.scrollbar.length * .33
}
// console.log(mouseY - scrollBarProjections.top);
globalInventory.initInventory = redefineGlobalInventory.initInventory
globalInventory.addPetalContainer = redefineGlobalInventory.addPetalContainer
this.translateY = 0;
try {
if (savedPetals) {
for (let key in savedPetals.top) {
const pc = savedPetals.top[key];
this.addPetalContainer(new PetalContainer(pc.petals.map(p =>
new Petal(p)), { ...pc }, Math.random(), 1), true, key);
pc.render.x = canvas.w;
pc.render.y = canvas.h * 2 / 3;
}
for (let key in savedPetals.bottom) {
const pc = savedPetals.bottom[key];
this.addPetalContainer(new PetalContainer(pc.petals.map(p =>
new Petal(p)), { ...pc }, Math.random(), 1), false, key);
pc.render.x = canvas.w;
pc.render.y = canvas.h * 2 / 3;
}
}
} catch (e) {
console.log('ERROR');
console.log(savedPetals);
localStorage.removeItem("savedPetals");
}
this.fadingPetalContainer = null;
}
initChangePetalsQueue() {
if (this === menuInventory) {
this.changePetalsQueueInterval = setInterval(() => {
if (this.queuedChangedPetals !== undefined && window.state ===
'menu' && window.connected === true) {
send({ changePetals: true, ...this.queuedChangedPetals });
delete this.queuedChangedPetals;
}
}, 1200)
}
}
sendQueuedChangedPetalsImmediately() {
send({ changePetals: true, ...this.pack() });
// doesnt work :(... will need to find a workaround
// squadUI.updateSelfFlowerPetals({top: this.topPetalContainers, bottom:
this.bottomPetalContainers});
}
setPetalSlotsNumber(num) {
localStorage.setItem("savedSlotAmount", num);
// this.topPetalSlots.length = num;
// this.bottomPetalSlots.length = num;
this.positionPetalSlots();
}
copy(otherInventory) {
this.topPetalContainers = otherInventory.topPetalContainers;
this.bottomPetalContainers = otherInventory.bottomPetalContainers;
}
// pack(){
// return this.topPetalContainers.map(p => {return {rarity: p.rarity, type:
p.type}});
// }
positionPetalSlots() {
const topPetalSlotSize = this.topPetalSlots[0].size;// global size for all
petal slots
const bottomPetalSlotSize = this.bottomPetalSlots[0].size;
if (isTop) {
if (this.topPetalContainers[position] !== undefined) {
this.topPetalContainers[position].w = 65;
this.topPetalContainers[position].h = 65;
this.topPetalContainers[position].render.y += this.translateY;
if (toFade) {
this.fadingPetalContainer = this.topPetalContainers[position];
this.fadingPetalContainer.fadeTime = time;
globalInventory.addPetalContainer(this.topPetalContainers[position]);
}
}
this.topPetalContainers[position] = p;
} else {
if (this.bottomPetalContainers[position] !== undefined) {
this.bottomPetalContainers[position].w = 65;
this.bottomPetalContainers[position].h = 65;
this.bottomPetalContainers[position].render.y += this.translateY;
if (toFade) {
this.fadingPetalContainer =
this.bottomPetalContainers[position];
this.fadingPetalContainer.fadeTime = time;
globalInventory.addPetalContainer(this.bottomPetalContainers[position]);
}
}
this.bottomPetalContainers[position] = p;
}
this.positionPetalSlots();
p.render.y -= this.translateY;
// ctx.translate(0, this.translateY)
this.updateSavedPetals();
}
addInFirstAvailableSlot(p) {
for (let i = 0; i < this.topPetalSlots.length; i++) {
if (this.topPetalContainers[i] === undefined) {
this.addPetalContainer(p, true, i, true);
return true;
}
}
for (let i = 0; i < this.bottomPetalSlots.length; i++) {
if (this.bottomPetalContainers[i] === undefined) {
this.addPetalContainer(p, false, i, true);
return true;
}
}
return false;
}
getClosest(p) {
const rectA = {
x: p.x,
y: p.y,
difference: {
x: p.w / 2,
y: p.h / 2
}
}
const pc = this.topPetalSlots[i];
const rectB = {
x: pc.x,
y: pc.y + this.translateY,
difference: {
x: pc.size,
y: pc.size
}
}
const pc = this.bottomPetalSlots[i];
const rectB = {
x: pc.x,
y: pc.y + this.translateY,
difference: {
x: pc.size,
y: pc.size
}
}
return false;
}
addClosest(p, globalInv) {
const rectA = {
x: p.x,
y: p.y,
difference: {
x: p.w / 2,
y: p.h / 2
}
}
return false;
}
intersectingRect(obj1, obj2) {
if (obj1.x - obj1.difference.x / 2 > obj2.x + obj2.difference.x / 2 ||
obj1.x + obj1.difference.x / 2 < obj2.x - obj2.difference.x / 2) return false;
if (obj1.y - obj1.difference.y / 2 > obj2.y + obj2.difference.y / 2 ||
obj1.y + obj1.difference.y / 2 < obj2.y - obj2.difference.y / 2) return false;
return true;
}
removePetalContainer(isBottom, key) {
if (isBottom === true) {
if (this.bottomPetalContainers[key].amount > 1) {
this.bottomPetalContainers[key].amount--;
this.bottomPetalContainers[key].y -= this.translateY;
this.bottomPetalContainers[key].w = 50;
this.bottomPetalContainers[key].h = 50;
} else {
delete this.bottomPetalContainers[key];
}
} else {
if (this.topPetalContainers[key].amount > 1) {
this.topPetalContainers[key].amount--;
this.topPetalContainers[key].y -= this.translateY;
this.topPetalContainers[key].w = 50;
this.topPetalContainers[key].h = 50;
} else {
delete this.topPetalContainers[key];
}
}
// this.petalContainers[p.rarity] =
this.petalContainers[p.rarity].filter(p2 => p2 !== p);
this.updateSavedPetals();
}
clear() {
this.topPetalContainers = {};// key in this case will be the coords of the
petal slot its currently in
this.bottomPetalContainers = {};
}
mouseDown({ mouseX, mouseY }, inv) {
if (window.state !== 'menu') {
if (window.state == 'game') {
for (let key in this.topPetalContainers) {
const pc = this.topPetalContainers[key];
if (mouseX > pc.x - pc.w / 2 && mouseX < pc.x + pc.w / 2 &&
mouseY > pc.y - pc.h / 2 && mouseY < pc.y + pc.h / 2) {
this.swapPetals(parseInt(key));
return;
}
}
for (let key in this.bottomPetalContainers) {
const pc = this.bottomPetalContainers[key];
if (mouseX > pc.x - pc.w / 2 && mouseX < pc.x + pc.w / 2 &&
mouseY > pc.y - pc.h / 2 && mouseY < pc.y + pc.h / 2) {
this.swapPetals(parseInt(key));
return;
}
}
}
return;
}
const offsetMouseY = mouseY - this.translateY;
// for(let key in this.bottomPetalContainers){
// const pc = this.bottomPetalContainers[key];
// // if(mouseX > pc.x - pc.w/2 && mouseX < pc.x + pc.w/2 &&
offsetMouseY > pc.y - pc.h/2 && offsetMouseY < pc.y + pc.h/2){
// draggingPetalContainer = new PetalContainer(pc.petals, {...pc},
Math.random(), 1);
// this.removePetalContainer(true, key);
// return;
// // }
// }
for (let key in this.topPetalContainers) {
const pc = this.topPetalContainers[key];
if (mouseX > pc.x - pc.w / 2 && mouseX < pc.x + pc.w / 2 &&
offsetMouseY > pc.y - pc.h / 2 && offsetMouseY < pc.y + pc.h / 2) {
draggingPetalContainer = new PetalContainer(pc.petals, { ...pc,
isDragging: true, lastSlot: { top: true, index: key } }, Math.random(), 1);
draggingPetalContainer.mouseOffset = {
x: draggingPetalContainer.x - mouseX,
y: draggingPetalContainer.y - offsetMouseY
}
draggingPetalContainer.render.y += this.translateY;
draggingPetalContainer.y += this.translateY;
draggingPetalContainer.w = 85;
draggingPetalContainer.h = 85;
draggingPetalContainer.spawnAnimation = 1;
this.removePetalContainer(false, key);
return;
}
}
if (mouseX > pc.x - pc.w / 2 && mouseX < pc.x + pc.w / 2 &&
offsetMouseY > pc.y - pc.h / 2 && offsetMouseY < pc.y + pc.h / 2) {
draggingPetalContainer = new PetalContainer(pc.petals, { ...pc,
isDragging: true, lastSlot: { top: false, index: key } }, Math.random(), 1);
draggingPetalContainer.mouseOffset = {
x: draggingPetalContainer.x - mouseX,
y: draggingPetalContainer.y - offsetMouseY
}
draggingPetalContainer.render.y += this.translateY;
draggingPetalContainer.y += this.translateY;
draggingPetalContainer.w = 85;
draggingPetalContainer.h = 85;
draggingPetalContainer.spawnAnimation = 1;
this.removePetalContainer(true, key);
return;
}
}
// if(this.petalContainers[i] === undefined){
// continue;
// }
// for(let j = 0; j < this.petalContainers[i].length; j++){
// const petalContainer = this.petalContainers[i][j];
// // console.log({petalContainer, mouseX, mouseY})
// if(mouseX > petalContainer.x - petalContainer.w/2 && mouseX <
petalContainer.x + petalContainer.w/2 && mouseY > petalContainer.y -
petalContainer.h/2 && mouseY < petalContainer.y + petalContainer.h/2){
// // for now we'll just equip the petal, but in the future we
would want to start a petal drag
// // let position = -1;
// // let isTop = true;
// // for(let k = 0; k < inv.topPetalSlots.length; k++){
// // if(inv.topPetalContainers[k] === undefined){
// // position = k;
// // break;
// // }
// // }
// // if(position === -1){
// // for(let k = 0; k < inv.bottomPetalSlots.length; k++){
// // if(inv.bottomPetalContainers[k] === undefined){
// // position = k;
// // isTop = false;
// // break;
// // }
// // }
// // }
// // // console.log({position});
// // if(position === -1){
// // return;
// // }
// // inv.addPetalContainer(new
PetalContainer(petalContainer.petals, petalContainer, petalContainer.id, 1), isTop,
position);
// // this.removePetalContainer(petalContainer);
// // return;
// draggingPetalContainer = new
PetalContainer(petalContainer.petals, {...petalContainer}, Math.random(),
1)//petalContainer;
// draggingPetalContainer.mouseOffset = {
// x: draggingPetalContainer.x - mouseX,
// y: draggingPetalContainer.y - mouseY
// }
// this.removePetalContainer(petalContainer);
// }
// }
}
swapPetals(index, toSend = true) {
if (this.topPetalSlots[index] === undefined) {
return;
}
this.updateSavedPetals();
}
draw(alpha = 1) {
if (this.fadingPetalContainer !== null) {
const temp = { x: this.fadingPetalContainer.render.x, y:
this.fadingPetalContainer.render.y };
this.fadingPetalContainer.render.x = this.fadingPetalContainer.x;
this.fadingPetalContainer.render.y = this.fadingPetalContainer.y;
// ctx.translate(0,-this.translateY);
const animationTime = 1 - (time - this.fadingPetalContainer.fadeTime) /
200;
ctx.globalAlpha = Math.max(0, Math.min(1, animationTime));
ctx.save();
ctx.translate(this.fadingPetalContainer.x,
this.fadingPetalContainer.y);
ctx.scale(2 - animationTime, 2 - animationTime);
ctx.translate(-this.fadingPetalContainer.x, -
this.fadingPetalContainer.y);
this.fadingPetalContainer.draw(alpha);
ctx.restore();
// ctx.translate(0,this.translateY);
this.fadingPetalContainer.render.x = temp.x;
this.fadingPetalContainer.render.y = temp.y;
if (time - this.fadingPetalContainer.fadeTime > 200) {
this.fadingPetalContainer = null;
}
}
ctx.strokeStyle = 'black'
ctx.fillStyle = window.flowrMod.PetalLocks[i] ? "#5c4947" : "#dbdbdb"
ctx.strokeText(window.flowrMod.PetalLocks[i] ? "Locked" : "Unlocked",
ourPc.x, ourPc.y-50)
ctx.fillText(window.flowrMod.PetalLocks[i] ? "Locked" :
"Unlocked",ourPc.x, ourPc.y-50)
}
for (let i = 0; i < this.bottomPetalSlots.length; i++) {
this.bottomPetalSlots[i].draw(alpha);
}
for (let key in this.topPetalContainers) {
this.topPetalContainers[key].draw(true, key);
}
for (let key in this.bottomPetalContainers) {
this.bottomPetalContainers[key].draw();
}
if (this === menuInventory) {
const mouseX = mouse.x * canvas.w / window.innerWidth;
const mouseY = mouse.y * canvas.h / window.innerHeight;
const offsetMouseY = mouseY - this.translateY;
ctx.lastTransform8 = ctx.getTransform();
for (let key in this.topPetalContainers) {
const pc = this.topPetalContainers[key];
if (mouseX > pc.x - pc.w / 2 && mouseX < pc.x + pc.w / 2 &&
offsetMouseY > pc.y - pc.h / 2 && offsetMouseY < pc.y + pc.h / 2) {
pc.isHovered = true;
}
pc.drawStatsBox(true);
}
if (mouseX > pc.x - pc.w / 2 && mouseX < pc.x + pc.w / 2 &&
offsetMouseY > pc.y - pc.h / 2 && offsetMouseY < pc.y + pc.h / 2) {
pc.isHovered = true;
}
pc.drawStatsBox(true);
}
ctx.setTransform(ctx.lastTransform8);
delete ctx.lastTransform8;
} else if (window.flowrMod.gameHover === true) {
const mouseX = mouse.x * canvas.w / window.innerWidth;
const mouseY = mouse.y * canvas.h / window.innerHeight;
const offsetMouseY = mouseY - this.translateY;
ctx.lastTransform8 = ctx.getTransform();
for (let key in this.topPetalContainers) {
const pc = this.topPetalContainers[key];
if (mouseX > pc.x - pc.w / 2 && mouseX < pc.x + pc.w / 2 &&
offsetMouseY > pc.y - pc.h / 2 && offsetMouseY < pc.y + pc.h / 2) {
pc.isHovered = true;
}
pc.drawStatsBox(false);
}
if (mouseX > pc.x - pc.w / 2 && mouseX < pc.x + pc.w / 2 &&
offsetMouseY > pc.y - pc.h / 2 && offsetMouseY < pc.y + pc.h / 2) {
pc.isHovered = true;
}
pc.drawStatsBox(false);
}
ctx.setTransform(ctx.lastTransform8);
delete ctx.lastTransform8;
}
}
updateBiome() {
for (let key in this.topPetalContainers) {
const pc = this.topPetalContainers[key];
pc.draw();
if (pc.greyed === true) {
globalInventory.addPetalContainer(pc);
this.removePetalContainer(false, key);
}
}
for (let key in this.bottomPetalContainers) {
const pc = this.bottomPetalContainers[key];
pc.draw();
if (pc.greyed === true) {
globalInventory.addPetalContainer(pc);
this.removePetalContainer(true, key);
}
}
}
updateSavedPetals() {
// let savedPetals = {top: {}, bottom: {}};
// for(let key in this.topPetalContainers){
// savedPetals.top[key] = {rarity: this.topPetalContainers[key].rarity,
type: this.topPetalContainers[key].type};
// }
// for(let key in this.bottomPetalContainers){
// savedPetals.bottom[key] = this.bottomPetalContainers[key];
// }
// savedPetals = {top: this.topPetalContainers, bottom:
this.bottomPetalContainers};
localStorage.setItem("savedPetals", JSON.stringify({ top:
this.topPetalContainers, bottom: this.bottomPetalContainers }));
class StreakMenu {
constructor(){
const dimensions = {
x: canvas.w + 20,
visibleX: canvas.w - 240 - 16,
y: 20,
w: 240,
h: 23 + 30 + 45 + 44 + 16 + 47
}
this.referenceW = canvas.w;
this.visibleAnimationTimer = 0;
this.visible = true;
this.claimPetalContainer = null;
this.claimButton = {
x: this.w / 2 - 58/2,// x is relative to dimensions
y: this.y + 23 + 30 + 45 + 44 + 16,
w: 58,
h: 50 * 11/16
}
this.claimButtonHovered = false;
this.streak = 0;
this.xpToClaim = 0;
this.showType = "claim";
this.timer = 0;
}
init(data){
if (data.streakLost){
this.showType = "lost";
this.timer = 10000;
this.h = this.dimensions.h/2.5;
this.show();
}
else if (data.streakTime){
this.streak = data.streak;
this.streakTime = data.streakTime;
this.showType = "timer";
this.timer = 10000;
this.h = this.dimensions.h/2.5;
this.show();
}
else{
this.streak = data.streak;
this.referenceW = canvas.w;
this.originalX = dimensions.x;
this.visibleX = dimensions.visibleX;
}
draw(){
if(this.visible === true){
this.visibleAnimationTimer = interpolate(this.visibleAnimationTimer, 1,
0.1);
this.x = interpolate(this.originalX, this.visibleX,
this.visibleAnimationTimer);
} else {
this.visibleAnimationTimer = interpolate(this.visibleAnimationTimer, 0,
0.1);
this.x = interpolate(this.originalX, this.visibleX,
this.visibleAnimationTimer);
}
ctx.fillStyle = '#1c1c1c';//'#895adb';
ctx.strokeStyle = '#080808';
ctx.lineWidth = 6;
ctx.beginPath();
ctx.roundRect(this.x, this.y, this.w, this.h, 3);
ctx.fill();
ctx.stroke();
ctx.closePath();
if (this.showType == "claim"){
this.drawLightCones();
}
if (this.showType != "lost"){
ctx.font = '900 22px Ubuntu';
ctx.letterSpacing = "-.05px";
ctx.textBaseline = 'middle';
ctx.textAlign = 'center';
ctx.fillStyle = 'white';
ctx.strokeStyle = 'black';
ctx.lineWidth = 3;
if (this.streak == 0){
ctx.strokeText(`No streak`, this.x + this.w / 2, this.y + 23);
ctx.fillText(`No streak`, this.x + this.w / 2, this.y + 23);
}
else if (this.streak == 1){
ctx.strokeText(`Streak: ${this.streak} Day!`, this.x + this.w / 2,
this.y + 23);
ctx.fillText(`Streak: ${this.streak} Day!`, this.x + this.w / 2,
this.y + 23);
}
else{
if(this.streak % 10 === 0){
ctx.fillStyle = `hsl(${(time/10) % 360}, 60%, 60%)`;
}
ctx.strokeText(`Streak: ${this.streak} Days!`, this.x + this.w / 2,
this.y + 23);
ctx.fillText(`Streak: ${this.streak} Days!`, this.x + this.w / 2,
this.y + 23);
ctx.fillStyle = 'white';
}
}
else{
//Show type lost (STREAK LOST)
ctx.font = '900 22px Ubuntu';
ctx.letterSpacing = "-.05px";
ctx.textBaseline = 'middle';
ctx.textAlign = 'top';
ctx.fillStyle = 'white';
ctx.strokeStyle = 'black';
ctx.lineWidth = 3;
this.timer -= dt;
if (this.timer < 0){
//this.hide();
}
}
if (this.showType == "timer"){
ctx.font = '900 24px Ubuntu';
this.timer -= dt;
if (this.timer < 0){
//this.hide();
}
}
if (this.showType == "claim"){
ctx.font = '900 18px Ubuntu';
this.pc.draw();
ctx.fillStyle = "#00ff00"
ctx.fillStyle = '#55bb55';
ctx.strokeStyle = '#459745';
ctx.fillStyle = '#895adb';
ctx.strokeStyle = '#6f49b1';
ctx.lineWidth = 6;
ctx.beginPath();
ctx.roundRect(this.x, this.y, this.w, this.h, 3);
// ctx.fill();
ctx.stroke();
ctx.closePath();
ctx.letterSpacing = lastLetterSpacing;
// oh also it would be cool if we had a little glow effect that rotates and
has like cones of light
}
mouseDown(){
if (this.showType == "claim"){
if(this.claimButtonHovered === false) return;
send({collectStreak: true});
this.hide();
levelBar.addXp(this.xpToClaim);
ctx.beginPath();
ctx.rect(this.x, this.y, this.w, this.h);
ctx.clip();
ctx.closePath();
const amount = 4 * 6;
const size = 300;//82;
const lightGradient = ctx.createRadialGradient(x, y, 0, x, y, size);
ctx.fillStyle = lightGradient;
ctx.restore();
}
}
streakMenu.init = redefineStreakMenu.init
streakMenu.show = redefineStreakMenu.show
streakMenu.hide = redefineStreakMenu.hide
streakMenu.resize = redefineStreakMenu.resize
streakMenu.mouseDown = redefineStreakMenu.mouseDown
streakMenu.drawLightCones = redefineStreakMenu.drawLightCones
streakMenu.draw = redefineStreakMenu.draw