From c005d8e41c744077a6b482df5230700547e3b5d1 Mon Sep 17 00:00:00 2001
From: radmanplays <95340057+radmanplays@users.noreply.github.com>
Date: Thu, 26 Sep 2024 08:13:31 +0330
Subject: [PATCH 01/41] Update modgui.js
---
modgui.js | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/modgui.js b/modgui.js
index c6fb267..45bae37 100644
--- a/modgui.js
+++ b/modgui.js
@@ -8,7 +8,8 @@
"https://github.com/EaglerForge",
"hey you should check out https://github.com/ZXMushroom63/scratch-gui",
"99% of people stop gambling before they win big.",
- "Now with free estradiol!"
+ "Now with free estradiol!",
+ "Now with H.I.V (Hyper Injected Virtual-debugger)"
];
var gui = `
From bc662a14d423d24c0c2adfc94244af6d792c93bd Mon Sep 17 00:00:00 2001
From: radmanplays <95340057+radmanplays@users.noreply.github.com>
Date: Thu, 26 Sep 2024 08:13:43 +0330
Subject: [PATCH 02/41] Update modgui.injector.js
---
modgui.injector.js | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/modgui.injector.js b/modgui.injector.js
index 4e466e8..54f537b 100644
--- a/modgui.injector.js
+++ b/modgui.injector.js
@@ -8,7 +8,8 @@ globalThis.modapi_guikit = `// ModAPI GUI made by TheIdiotPlays
"https://github.com/EaglerForge",
"hey you should check out https://github.com/ZXMushroom63/scratch-gui",
"99% of people stop gambling before they win big.",
- "Now with free estradiol!"
+ "Now with free estradiol!",
+ "Now with H.I.V (Hyper Injected Virtual-debugger)"
];
var gui = \`
From 7d7c06475bd68136fc38ba0f04ccf6470e2096bd Mon Sep 17 00:00:00 2001
From: ZXMushroom63
Date: Thu, 26 Sep 2024 12:50:21 +0800
Subject: [PATCH 03/41] test
---
examplemods/AsyncSink.js | 21 ++++++++++++++++++++-
examplemods/npcspawner.js | 18 ++++++++++++++++++
2 files changed, 38 insertions(+), 1 deletion(-)
diff --git a/examplemods/AsyncSink.js b/examplemods/AsyncSink.js
index bb9aab2..9e2cd08 100644
--- a/examplemods/AsyncSink.js
+++ b/examplemods/AsyncSink.js
@@ -76,7 +76,11 @@
}
return wrap(AsyncSink.getFile(ModAPI.util.ustr(args[1])));
}
-
+ var ev = {method: "read", file: ModAPI.util.ustr(args[1]), shim: false, shimOutput: new ArrayBuffer()};
+ AsyncSink.MIDDLEWARE.forEach((fn)=>{fn(ev)});
+ if (ev.shim) {
+ return wrap(ev.shimOutput);
+ }
return originalReadWholeFile.apply(this, args);
};
@@ -92,6 +96,11 @@
AsyncSink.setFile(ModAPI.util.ustr(args[1]), args[2]);
return booleanResult(true);
}
+ var ev = {method: "write", file: ModAPI.util.ustr(args[1]), data: args[2], shim: false, shimOutput: true};
+ AsyncSink.MIDDLEWARE.forEach((fn)=>{fn(ev)});
+ if (ev.shim) {
+ return booleanResult(ev.shimOutput);
+ }
return originalWriteWholeFile.apply(this, args);
};
@@ -107,6 +116,11 @@
AsyncSink.deleteFile(ModAPI.util.ustr(args[1]));
return booleanResult(true);
}
+ var ev = {method: "delete", file: ModAPI.util.ustr(args[1]), shim: false, shimOutput: true};
+ AsyncSink.MIDDLEWARE.forEach((fn)=>{fn(ev)});
+ if (ev.shim) {
+ return booleanResult(ev.shimOutput);
+ }
return originalDeleteFile.apply(this, args);
};
@@ -122,6 +136,11 @@
var result = AsyncSink.fileExists(ModAPI.util.ustr(args[1]));
return booleanResult(result);
}
+ var ev = {method: "exists", file: ModAPI.util.ustr(args[1]), shim: false, shimOutput: true};
+ AsyncSink.MIDDLEWARE.forEach((fn)=>{fn(ev)});
+ if (ev.shim) {
+ return booleanResult(ev.shimOutput);
+ }
return originalFileExists.apply(this, args);
};
globalThis.AsyncSink = AsyncSink;
diff --git a/examplemods/npcspawner.js b/examplemods/npcspawner.js
index a07fbb2..f17bb07 100644
--- a/examplemods/npcspawner.js
+++ b/examplemods/npcspawner.js
@@ -1,5 +1,20 @@
(() => {
PluginAPI.dedicatedServer.appendCode(function () {
+ var ready = false;
+ var killFS = false;
+ function setup_filesystem_middleware() {
+ if (!ready) {
+ AsyncSink.MIDDLEWARE.push((ev)=>{
+ if (killFS) {
+ ev.shim = true;
+ if (typeof ev.shimOutput === "boolean") {
+ ev.shimOutput = true;
+ }
+ }
+ });
+ ready = true;
+ }
+ }
PluginAPI.addEventListener("processcommand", (event) => {
if (!ModAPI.reflect.getClassById("net.minecraft.entity.player.EntityPlayerMP").instanceOf(event.sender.getRef())) { return; }
@@ -7,6 +22,7 @@
if (!globalThis.AsyncSink) {
return alert("NPC Spawner relies on the AsyncSink library.");
}
+ setup_filesystem_middleware();
const world = event.sender.getServerForPlayer();
const senderPos = event.sender.getPosition();
@@ -23,6 +39,7 @@
const playerInteractionManager = PlayerInteractionManagerClass.constructors[0](world.getRef());
// Get the EntityPlayerMP class to spawn the fake player
+ killFS = true;
AsyncSink.startDebuggingFS();
const EntityPlayerMPClass = ModAPI.reflect.getClassById("net.minecraft.entity.player.EntityPlayerMP");
var worldNameProp = ModAPI.util.getNearestProperty(ModAPI.server.getRef(), "$worldName");
@@ -31,6 +48,7 @@
const fakePlayer = EntityPlayerMPClass.constructors[0](
ModAPI.server.getRef(), world.getRef(), fakeProfile, playerInteractionManager
);
+ killFS = false;
// Set the fake player position to be near the command sender
fakePlayer.setPosition(senderPos.$getX(), senderPos.$getY(), senderPos.$getZ());
From 6fa256ae0e6f1357841ff5751c127fee3a8de91c Mon Sep 17 00:00:00 2001
From: ZXMushroom63
Date: Thu, 26 Sep 2024 12:54:27 +0800
Subject: [PATCH 04/41] fix bug
---
examplemods/npcspawner.js | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/examplemods/npcspawner.js b/examplemods/npcspawner.js
index f17bb07..bbf7c75 100644
--- a/examplemods/npcspawner.js
+++ b/examplemods/npcspawner.js
@@ -51,7 +51,8 @@
killFS = false;
// Set the fake player position to be near the command sender
- fakePlayer.setPosition(senderPos.$getX(), senderPos.$getY(), senderPos.$getZ());
+ console.log(senderPos);
+ fakePlayer.setPosition(senderPos.getX(), senderPos.getY(), senderPos.getZ());
// Add the fake player to the world
world.addEntityToWorld(fakePlayer.getEntityId(), fakePlayer);
From f45b065bc3c91bab4171df272dda42cfa9cca47f Mon Sep 17 00:00:00 2001
From: radmanplays <95340057+radmanplays@users.noreply.github.com>
Date: Thu, 26 Sep 2024 08:32:31 +0330
Subject: [PATCH 05/41] Create slippery.js
---
examplemods/slippery.js | 23 +++++++++++++++++++++++
1 file changed, 23 insertions(+)
create mode 100644 examplemods/slippery.js
diff --git a/examplemods/slippery.js b/examplemods/slippery.js
new file mode 100644
index 0000000..9b6c37b
--- /dev/null
+++ b/examplemods/slippery.js
@@ -0,0 +1,23 @@
+ModAPI.meta.title("Slippery mod");
+ModAPI.meta.credits("By radmanplays");
+ModAPI.meta.icon("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAQAAAAEACAYAAABccqhmAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAIZbSURBVHhe7b0HeF3HeebP9OQfO8WbbJJNzybZzWaTbLKbbMo6m93sk2KxFxEAey+S2ECQaARYALD3IqpRvXcRjaQoiZIs2ZYlEYWkRHW5ybZsySWWLIl3/t9v7nyXg4M5twMEqDvP8z7n3nNm5syZM+8739QzouQ+nu6KO7/7S5X3Jv7H8nvPXbv8nnM/rLzfmBX3GrPyQTnek3iz8p7E3soHEn81765v/5wLUnIlV3LD0VU9mfhEY6f5TzVtH5XXtCW21LYnHltxf+KtKiE7xF8uxIf8YPk9TgjkfNVDcv3exBs1DyZa61vNjJr2xJ8YY1ysJVdyJTckXeMXv/Izdcc/+PSaI4mq2rZzt9a2JV6pa098s67dmA2PGbP+UWPWHDGmtk1I/oAQ/j5jlgnxl96d/F0pWC3igH/8Wf+dxtR3JL5V15p4VtBc25H4TOXhxB+7W5ZcyZXchXDUyJfdmPhU5W2Jv1p220fLlt5qrl9xZ+LEynsSH649bszah41pPJYEJIb0Na1yFNQLwdfKue2PGLNZroONAs6vEfh+6zrkvIhBg1xfL/4RkqYjibf3P5lo2/9EYv+Bp8zE3Y8nfsklq+RKruQGyl124/t/sOzmDycsvy1Rvfy2c/cvvzXxyorbE/+2Umrw2sNSe9Oev13M+dsEclxxZ/Ictfp6IXGLkHiTCMP+x5M4+KQxV302iSufMGYf5+W4Wfy0HE2GWSdCQThgrwuuetqYG04mceVnE+f2PXHujf1PnLvq6s8lph14MvG/tt2Z+GmX5JIruZLLxzU2mh+rui3xayvvMP+49NaPaoXsh5fffu5NCF0jhF5Fe12IXykkV9IvuzV5XHFH8twqyC+mfrUTgGYh9W6pwSE55PdxlYDzkHzPiSThCdMoFsBWsSgOuGsqGvwHB58y5prPG3PoWWNu7OZc4r2DTyWe3nfi3A1XPpGYveux93//2icTn3CPVXIlV3IhV3kk8f8tfSDxV5X3JmaKKb952a2JB6Smf3f57YlzVUL01dI+r5L2uq3dQxDSIwjVQvh6MeHrBJj09ZjwmPVizmPW6/lNQvCtYtJDbrBNftMssNe9JoCCMFyjqUA4tSCujOBqsQ4OPWfM9YJrPieC8KR5R/w9c9XTib1XPvnh6Ps+n/iUe+SSK7mPl2u4y/yE1OC/XXlPYuSKe881r7jn3OGVDyQeX35P4vEV9yZOLr/XvLNKTPlaIeJqIR098pVS01cKsTHpLajd5X8/aA++CABHUP2QEFnig7hRQPAobJs/4BfQL8ARf9WCtSIs2kRAOBCGvWI5YGEgBFgHe0Uk9om1sFnObxVLAf9r2hOna1sTj9d3JB6XY2dde2Lrmo7E6FX3/tuvzztoftxlVcmV3PB3i1rNLwi5/2H53R9dUXl/YufyexMdQvq3GYaD6NVSq9YIkcBqIRdj8fTE69Bc1nBhGMrT4bxV3MMhHbHzBXGGxIMjYgDZ/XP4wRqhg5LRhfVuVIL/jdI0qW0992ZdW6JVRKGhrjXxaZeFJVdyw8dddl/iU0vvFjP+vsS45fcldkut/vKK+xL/Rm1eJ6SA8HYMHsJ6pF0h0FrbJ3FGaDziH0tByQ6s+e/gE3cw4AtCJmgaG+h0FEFoFsuhvj3xvfrWxBdEDPbXHU2U1T+Y+C//c1upY7HkhpAbN8786NJHzc8vv+fDf1h670dLl99z7o7l9557dsU9ifcgOqRfJdBanUk3ltw+gQX00GOqKyFWy2/+Iwa+PxUMxfI7PdDjL6CfIEQu/9xwQL00KRoYxhQgCmIdvLv1kcTxA08m9ux7PFF2/efNr9x5p/lR9ypKruQGxx08kfjV/ScSf7PlWGKt1O4nlt6T+IrU+D9YSVubdrsU3pVMsPGJ6mr0lUJO2udAa2lbU1PgPZL6pLXtbvldhWVwl8QH2enwoy+AI73+ruefI6MAdkRAQIchHYKMABDHcBICmg9NYhEwZLlPLIL9nzXmumeNucmOMjAMmXhr3xOJJ695OjHlqqfN3931qPlZ94pKruSK4x55zfzUvkcT/3HficToAycS26TQ3X/gicSp/U8kfkAP9+4njdnhhsvsrDoh++VCUDurDvIL4bUjDqTM8kCBB0p8XxwY6mMEYKWQP0X0OPjXEQHCIBgSnvSt8oRH7xdNw1AA6dvldSSm5im4/6lhxy8m5yHsPXHuw70nEk/VtyVurXnwo8vXdyT+cPUxU1rHUHK5OdtD35r4dENnYu76o4m9ux4999mr7BBW4tz11D5dxlz7jBRGKYCMl1MgGQazvd0iBLvEVN0mNdY6IRbt/OrDXgcZBTtS0BUQET80BTDhVwiBqcUBNfqyW86P78fiDoGQnb6AlPVBXEB+R5seCIIvSqF0XUioGNrZipKvDDsyB0HFgNEFhi2xEhqwFpidKOf4Xd+R+L40GV6p60jsqz/80eTajsSfu1dcch93t/T+d36+rjXxW43HzO82tprfpXOptvWjGbVtid21h889XdeW+Dc6odZJoWuSAtbM+Lj8ZmIMtZIS/9qnkwXxZhGEe6UWuvt5Yx4Q8/ToC3LsMeY2EQwKLKZss1gIG+TYIAWa9j3QTjJ+27a+EJWa2pr5HCE0tThHECK9D/wiAFgfiADgt0f6KBAF+ibUSrEi5dLFb3rsaTqkzjlgSRBGwTCjf13JC/zzxKl9G6Fw9p4uHPfleo34Jwz5tEb81Et66yXsGvHLORUxbeIw5ZnORKY/r5P3x++aw4m3V9137s6ltySql96a+GsR09+tvsf87vIbEv9hWWnG4sXt6o35ETEHf7OmNbFsTUfiutrWxLO1bee+X9ee+FBI/6H8/4hCw1AUBYbfWmNzpDbaKLU6YHqs1kK3ivkJ0dtPCU4n0Sa/W93/zjPJ/7eLENwmfm8UkxUroYl7SZy2Q1DAQpxlSlStsRWch9SY8hA8RHwFFkLUSohaBDGIdkpayL3txCPSEbiu/RrAP28XE9HccMfQkGa/cM4PogCpmb1YhT//WQTLBEvFGgL81vOVIpDMjuSeFl54ZkTaSVRyjklSNsytiQ9X3Jb4cNkt576+7LbEcRGGpqW3fjTx8psSv+OKTckNV9dyLPGp1YcTf1rXmVgo5L5OiPyMkP31DUI+wAIZSO4jNVNOiInJSW2909X6kBYzX4G5b01+EYKraYsK7njOmHvECsACuEcsgVvEKuAaVgJ+EQ1mzTHXHvEgHpoLWyQtddSCglSNTSHVmt8WVncMwDYPHGwYF87GEyFmCCkiKlRonNikmh7uHNdT8UJaBedIN2kWQE4blnRyjrCaJj+chhXYvgrCec/lP2smaBgfUT+2WUX+cBTYTlJpdq3B0kHwH0q8JhbgPmkCVrCEevVdpX6EIe/qDyd+v/rwh6OkNm9Z05m4qa7t3HPy+/vrpEbXWh3S++3LOCAA2vPM1FhMfW3nc4TEkBkosa8TkmMNUNPf25Ws7Q997rw/YMlPPJBfgBDwHzHYLqZqvdSUy6RAZurkixZqajm70MeZ5Cliu6MPa3FANu8ccwbod4AU3DtFnAzpsKSGsIqQnzj44VRwMt2vQPj5xroJtRZoOmhzg4qAIUe7ilIglcd3RQyekuNe8VfaD2GoOKbRVrclLqnrSMyvaz13V31H4htC+A+YVUYnkNbwvNQQyTOBQoHpD1gWyzRXlsxiEUD2G4TcmPP3S21/vxD+cG+yGeCb/5x7UJoHd4go4JdwWBJbRVws4TFRKYjUqEKAJVJb+gW2H6QA44+RAC24WA3a7lXrxaZdzqsYaA0PtN1tJwo5vzyvDeva2pjI3AOTOlSD9gHXFaHrcfDD5Ro2B1gxc/nKM/F8dkq0PLfmWfTdK7jGXghUHk0i1lgIqf0Q2hPNtYcT/9R4v/l5VyRLbqAci2Mkw39PyF5W23puk7yENiH7y3Tw+FNICyG8D4ih5NehOlbCbZH7IALU7HeJud8qBIfsHUJ2jhAe8B/Q/lcRoMbfghUi8VDLL5WCqe1YfvttWQslBTWjHK1ZLqCW14JrC2+G52UEQjvJQMiPDxuvpJHCDllsm1num1EIigXuE3n2nETC88coCv0XOgcilV8xeabv3Qqj+w30OnlCZyKVC+WO8ifWwedFEG4QMVi69L7Ef564rzQPoWA37k7zo2Jq/dGa9sRIMeevFPPrJcn8d3gJqDFteDLfvlBejjvaiTQe9MXlAl58g7xoxvSbRP1tj78z37X9b815qRH4fYPU7HeKGNDup9ZHFG78gjHXy3mOdBrS62+JKCB+ex8pWLqMl1q9D8EwrYEQz5rparJLYaYzzXawQWhqMhdfHGxeyP0VIT9Ar1vSC2EgPk0Cf4nxoMA9u+0rcM+eamqQjnRC4MLaJgXWjuSTHUFAyHm+yDNbC0qOSnT8bBCC0+xD7PlNP5BeV//6Dil3VD4bpDxgKTQdTXyn5ei5V/efKO2HkLWjd55588vvTPzlsrsT05ffm7i18oHEicr7zn0Vwqyl1hQyag2vHXWK1IsU2Nl1UnAt5Leej/pPB1407X9tn18tNTdtdMB/7fwDiADCgFmPv5uE8IgD8awSIjH1l2cAnPPTYZ9DgClK7WQn+EA2Jb0U3hT47+Cb84ChOJ6Vgp7p+frcH7jzKbNfxYiOO8zmKNn474NzkFKJGb0WRciPhLXPzL3lefxnTcHPB/FnSa73BSoYafJLmz5WEMgreW6adY2uaYfQs3pRRd721bj3vUNqe5p+lAuagwg65YS8Y18Fru2UsGyOcq2UAX8/hKs/n3hajtv3PZ74q+1PJX7xY9t/wOSayrvMX6y4P3HpygcSi1fcnVi8/J5E9bJ7zt0rOLvi3sQHbE7JNFpWxNnNKOU/nVZ2sgpEkiMmnZ0o42pArqVetvfC7Tnxq7Wlhfi1ZJAXmM4UtJBrjN0zyYTJJ9QIjAbYDjyvcKTEQIgP+fHDf8JR+9ORCChwdkhMnknBf0sABy3QlhA+3PMwtZjnsCv75Le/4Cf4DA7cGz+pfFBI+FTekW9a0yr47xG1zzVBirCEjVzrR3j+R/zEEj4ECK5C4fLFEp949DwIhNXOUMoKeUY+Nkie6HvlXSECKvopuHfrv299z1iIutw5VB7sSI8IAjNFr/silUXifRGCs3LtTjmuECze/3hi0YHHE5MPPpb4r44mF4ebKGRfdPsPfkPaRH+9/L7EFCH6HVUPJp4Vkr8NseuFEKyIqxX1ZLGMrS3lpdhtqYUUFhQOLVhS+Gg367BSqkBSCKIvPRKeQqHEIhwmrXYG0emltWGKLNTKcuQ6AmPDQwTBKvldI3FuEpHaLapvX74IQuqly3+G/cA+EYK9UkB2QH5Jz0q5r61ZhQw+7LOEwDWFe37GtbXzynZIeelOpd89D4SnpqPQU/MhhCqOPvrknZ9/gP/kL8Cvf02v++HkaMkmv21TRX77UCL6/qPQdBHeppv7St6nLBJFKL84unetYuCLpOaN5pua9gqGfnU/A4QcorM7EuS24uDBnhPou7fv350HhOWo4Zk16u+WdFNPcj3D1XLuyifteobjB59OXHH75xN/8MCZYbhr0uU3Jz4p5vufUquLCd8utfobENpOhZXMtstfhVSW5PrCo4XAKbtVd0fYbGBrAQoKLz1D+BTxgPjRITRLGiGMtstT5PT8c7STT9zvNRJuuxBcCwOisEEKUrPEtUrSoJ17GiaalnxAPExoIZ1qyirxbS0v+Q2U8ORrH+IVGal7ONJimdDZqCSzaRNo2hAkTY8lu/fbhhc/SlpLVglLE4nnRbw1H/Ud9Mkf3jkVhpYHwkic3Jc4tZlEnJpvPrgnQsARIAZYCDrxi3dsRZ+jI72+e0BTEGsP/1ZI5Mh/Xc+QCitQ0UAYaDbcIJbCQRGDjQ8nvre2M/HZuvbErtrDH02TdPyZo9jQcY2PmB+rvDPxO0L4f668L9G07N5zHXJ8mRqeVXC+Cc8L4EWkwH89x0tSsipheanRF5sJvv9sw1Oryz1t77sQSmubVG98unjc+SVyJP3WWpACBjE5t+TmQOEsItSSQPikWWXzOFrL98nzIkPvofeF1JDLJ22UXEBFAX+IBJ10hOd3n/DOXwqcc/0l5DVILYxy1pktS4CyBQLp5TcCxb2Apqnf/RxIj1oHdAxDavoDILSt4cX62y2kp/nANe0bUBHhyI5JxM8oEsJAswGkJoK5/1gdWHXsvEzHItPQGyTO+vbE27ofQsPRRNmq+394AZoLxoyovCfxW8vvT8xfdk/iOnazWS41PGa7rncHlvSRzE9BzluTnReGSnMcQJKkELmHtRCk8ATTCEg/hUX8kEZb00g4FQa1MGwcPJOEsdN4vUJmr/GMhFFhKxYkvozPUGSknksAaSEsfQhK2BB5ign/HvymaWb7QAR+OnMFncVYBlgIoXtFwfMC7o+1yFRumw9yhOz4iQtvRw/Ej4oDC8XWCjTO1MiCB0SPYUcmswG3H8J313Qkbqm856MVS+5N/PH0681POZYWzy2+y/ys1N5/sfL+xHip1dcvuy/RvuKexNcgOO12anja7X3M+UxQAfBr+mjhjsKJhU9IGz5TWL2Of4ElDGnwCnI6WLNU0psaUXCw7dhs4kBEAH5VCApEn7QTt3+/AQB5wLPaGl6gZrktmFJw0xGlWNB7UFtrs0YrGNKmzYc4WD9+vkWgz6j/U9aIPKc+I+C5/Q5n0pD6iIr7Dwjrh9dniIbn/RGWOPR5bNMJYfHubcO7ONRqgXf1Yi2wjZzE886KuxOvCjevq3ogUSH//w7uOhpn75Y/ZP7dyiOJv5W2+zIh/E0r7ks8LW3579AjrzV8v/Z7ISDTIadfyCE2ZCVTFaGwgGuOWKm2oBMW2x+QKbyDvkQtBPoiUXVehr4Ihb5ICkqfuNxLtM8l0HZoVmKVLcgvns2ltZgi4BPBFkgBhOdZtRByHGiQxxzJZwBhEJ9MRFco4W2nozyDWir6XtVPNJwP7oVf7ktfEIug+J8pHNB8tOEl7dwbkJ9ZhRc/2qRCEMgD3oMKh58P9h5yDSGg2V17RM7fc+5DaYo/JYJwm1gI86rvS3yKOTWO5vFu5o5Xv7Pg2rffp3DZGl6IT8TBNnyxESUr98vynrZmFr+8KDIvlMl6Xs10BcSvl2fEFLPmpKvhrInmFUofKgT6n5drRyGwbCCokp1jsYjvgMilZg3KvZaJGFgEni2UD+lg81FALWtNVe959VkHEtyHfIewvrjGvdMo8EPTRJsFvEeNF/HS59H4YwXFlUWE1jb7yGv3Hvs0/UJhI8j1Hfiwzy1HhEz/R/2EoE1yOGw/8Hpv4m0RhAeW35VYtOLuD//vkgcT/95Rvq8rX3/SVGzoNtM2v2Bm7nzFzNzxipl/8C2z5Lb3JCGJ80N0gZtGoSqY+p9HRtgMcOEQIGBNKyGsD33JHPlPjQXwTzogOQWbQgHZ6azZxrivA72wTOChI8dO5hDQyUOHji08WoCcKEAQq9AKidfWyFowSDc1v0fcguBIzxoB1gwAHXnYJmaghXsWnq1FagGeFTKoian5afNRfpPuuHzUvBwIaPxWZOWepIO81BrPvjOX3hC0TKSeQ8Jo+ikbxJvpGWwnmxwRbvIpdT/i1vcG4R3p+0HPO2vMWmReGocS4KsdgZP8ACIGPxQunxbr/mjVQ4kjKx9MtC6/68MDC6/+yj8hAF8uX99lytY+ZyY3PmvB74qmLjNrz6tm4XXftGLAy4oKga+mZCgvFqIAXg41q1Vdl9mx6utBlZwX679AfcHRF+3XWhzpceVjF+vlSA+rDrnQ6+pDh3LokUUIUrP+5Bpz9q0pJun306YFUWHPS6GMWi62vyNagDLBK3zUPDRn1koeNknhZl6BptlORlJ4z6NgOLJJ0o/okfe2Zne1Yrp8HCggyuQj6YDANo9C+ah5J4haNfou4p7Dv1/qunckHMS3ou29pxRIgyDVUR16N5zPwQoYKoCzdut5KRM0F5bd9ZGZf/XXzKzdr5gx1UfvRABeRQCwBPqgSdB80pRteM5M2/aCWXjoW2bp7e/bl6jqDXw1thnuvRSOkBITD1JbpZdEsfkFR8JzTgupHwfHEDQ+azYKIDzTOqm9ITxr9OOm7yo4r34Is0NqUIZk1st97dRc0kmBoGB4mdkPWpi0AFEzuP6MfoUoBClYamqy+o6hLe5vJyrJs60Xc65JxIyppnYmoqQ7+kycQ7T4rc+/WawChqXIq3R5ORigUiCPMuUn15Y4ctXK8/PZM3b8obecd2ybZ4LQPRSQ3ZY58adlUstYzu+Td4gQy9H+968PcViOCt/Asjt/KNz9hpm+/ZSZ2HDCjFndaS5Z/qAZX/uoGbnioetHSG3fWbEBAYiIwAZpGrR0m4qN3aa8Ra6JGEzdfMrM3veGWXTobSmoH1mzyp+jH30h9kXw4tyLsdNv5X+j/LdWAtcE0XA+lOz6n3gYU7WTNARxkzSiJAH8xh9iQfsfKwGyU8toAbG/A5naD/hzpmCQ3FF4ZNdzEF6nBZMvOkVZ89LPP/4z9xyh4jl0Wir5gMXD4iX841ePmmdRaJ76+ZoLiDvb8KkaWN43tTCE1HxO7YIkYNVeszwDi3Gwbvx3qs/J8+tz2WeM3B+rMVXRSPzEm9W79EG4yDu1/wEWgPobYmLgk37FPQmz4NqvmWmQvvEJM6qy1Yxa8ZAZWXnYjFrZakZXtZuJ9Y/LsW2/CMDzN9AHELICVAAUCEFZ0/Ny/qSZvu2MmX/wTVN51/flRZxLCoEUXL9w0J5mTj1zp6mZdIolL5aCzGoram/1ry9V4+BIePwwZ5s4orvzRAnPfwvPj63lad8L4alNKJSYlBSOjLWDvmgKK5aL1u7ay+8ROghIL+14ahIIT6elndASsJhCIA/IE/KDYSCegWdhLrslhDuPqW39emFT4YGLg+N6yU/yHuBH8zoa1gfX8KeTW6LhNY5ouD6QcPizVqPkv/bN7MFykfdKM4z35b9PfadYObxT/LEQC/GnfNmmhbwf3iPvKfY9RqDv3Jr9gPfpRpNC77DPexYxsOWBe3FfLSP5Is/wlvQiqLamv+tDqem/aWbvfcVM3vA5yG1GSk0P6fkN6X1MbHjSjFzZtnFEWVPXloqmHqnxMwuAD9s8EFRs6pb2xMtm0bVfNVX3vW9N1l3ykiCsLqNVNbfQlyq/uYYfVXcKFiuuICgvmILeJ6xDtIBobQggO0JDWFZwES+FzxZQhfznHlowqTlsQXLmopp8tmCg/Er6LNCvlpeCQi3fZ+2BwktDFKTXmrQCSG8XJkmeQIBUHgp4Tq5hBegzKSFtHO4+fObbX/ii4mjFROJVYdRwmlf8Jq28F94TfhFvP7x/fw3vP4f+5zqz3kgD70ybaXHvVZ9R78V/3jFxACoGrAqgAmDfW0AE/HOQxnYaE1Z+A2vqe+9Q318s8INgOOsg1UwA6QjNNT+tOYa3pMfKkTQvu+sDs/iGb5kZO0+bSWuftMQeufwhqfGp6fuT3sfExs+KALTXjihfd3J1PgKQgrUKRAzEMpglCam+7Wtmx9EfyItLmGuelpf8VPJFY9bpC1RQo/OCb2Y+tFtbz2YbbLrBDjpKbI6E1SW40TjYk49dd66XcHvk/w4poBQ6ekKZw7BaXnaqUDryKRlBqodYMjX15V2tDeIKgyO6D85BeCW9Nesp+NyTe2cJiIJw6epCoH0WPlHIC/IP8BtxgFwQg1pe4wC6h4ESSaHnNDxhEE7tW+E/IyVcV79+GvTcQflNeIQGq03zm7iwFJT0SmiOfjpCwA9ig+hg8dCvQV6qqCBQ+g6tBSP/aQJgYUAQW8MLaThCHETefyc+CGunG4sfO82Y9xl671G4925/S5lJDRlC6BCRsRwEtlKJlrFoeIRJwLNY817StlRIT5t+1u4zZvL6E2LKdwqhxbwXE390BtKnsKrDjK8/ISLRvnTEpetPTpvS1GuS/QB5CIBC/E7bIth20szZfcpcfvUrZvmh183y698w6x94x+x+9ENL0Ad6jbn7pBD9+STh75HfbKXlgx112EkHP1wnHIWGlXYIA+HYglvj0A05NCw79Nz0THKN/i1flPByZFtuXjAvmvYm8+iVrCC12CTdi3fXWL6Lf7vbjA8KmFeofFIDNaNtYYtc86ECACAPtZ0VO0dkiMR/K6ySLzwn+USeAH77YK9CFQ8Ek7DEEyWbkhNzW/1Z09td8/2HoOG5D5YBQ6v813PZxOED/1h0WBjkgxKVZkhcc8MnNDW81vT8D70THxqW38wxSfX6Q1hqasoApE1XRgDX8UcYiK5QwmeAXR5u/X9klt34rll04BUzdetzZtrWL0pF+6QZX9tuxslDja9pE0DoCMEzYMyqTjOu5rgIxuG5I8qau/9kSvOpogjA9K09ZubOHjNjuwjB1i4zdctJC/7P3X3aNN7xJXPzU983h3sS5uiLxnS+kCStbqcFcRVtjsgQnH31ID777/Nbie5vw+3HwTX25ldcL8KxVwoRY+k6rz9Ue0dfRApc44VIeDqEKFCQVAuMD79Aaa0EID41GCvEtIbUa6HCrLUchR3oOchwrTwPG4/6z0w+pAN+7utyosiOxSIIURHwkS3p46DED13LBSoq+h9LgD4lFujEiYAi7r2EgB/yV0ct/CZFn5ocq0KJHSorPtKVqSggvWDZrR+ZJdd+01y290WzcOvTZkFTp5m1ts2MlUI3Tto64yWRE6SWmVDXYTG+tiNI8nRAAMasPiLCcXjyiMkbvvAbU1pO28lAxRKAmTv6Ysb2HjN9W7eIQZc0E3pN9c2vm2sf/56557kPrQgAyEytf5/U5tRaNAMw7amFtMayRwEEYGNOCrQWfvbgQ1QgBM2IK6W2bJCXuRazSV7E5Tc5oocy3wd+3MvgJWsN0KcgyBEzUwlsC5krSEp2oKvI+KoNpiymODUxz8J/xMBve2thVEtBO9zwA4iHOQGQl/yx3yWQ/HpIntluSSb5oKIAyBc9jz8sJsKxZZmmwyfbUAdWhHYU0qSgaWCFwMu7bKDvi3CIue1Ic8QP9R/0A+UA4FeshGA5ygYQnnImv5cc+rZZvPeMWbjlSTNfSD9v3UNm/oZWs6C53cxe327GO8JHkY8AjF191IyqavvhuMoj/2fElMbP/XpFU88HFRt6BkwAfCAEWAccL7vyBbPpga+bqx77t+RW2myQIC+Yl61kjxYCoOcpEOy9x1bcB4UYe6VAtMhLZfYcpL/i5iRSy3zTQfzbjiBtf4VevAcdXqKmoN1JRxTEpd1MwaRTzPZxSBqBmsE23QL73z0DYpAaxoP0Eg/iQBxc03AaxhdDcEisI8SArxMhBggpAsC3CjhPHlm/LhzQvBwo+M+bLzTf9DcCyhCwjj7QMRkldxxUoAF9Af4kL+0n0P9ZgUoB8jsCZwWtWMCt58yKm75nVh76sll15fNmYYuQfn2rmb/+sBC/XUSgw2JBc4cIgBA9QP5CBGB0Vdt7Yyo7/veIqY0nf7l8/fPfndJ0qr8ANAeIHocsBUCBVTBtW5ep2CxNhB295vJrXjNr7/u22X70PdtheLUUar8AKWlok1KQaV9CDmpYesl5qUvFNFvqXgjTaHMywYCETZFfa/sY2A4mAQIAaGtSyDDRtZbW9rM+QxyU2LR3dRRDnzUdicgHiI1/8gKLiQ5VzHxqes4zxGbFIhJ2IOCnmfTwLJwDIf8hpN6z5B/hiYcmE++YJhRWkW8tpYOt6QVqkVHL86703YXeayzwT1+Ab/pnU74oU4QBYt5X3vAts+qas6Z631OmZvfDpnZnu6nb0WoWtbSbeY70PgZEAKqtALw7ZmXrn40YVfXkJ8rWnXx56sYz/QTAoqnLlDcLUUOk95GjAPigj2C6iAGWAR2IlTd8yTTe+00h0jm7txoFigJMjUiHWLQNrQVCX7jdRYaXTVst9FIygZdFez9NIaEG0c4lv9Bpu5QOPGor0k36syEB/hSh6wDC+zU4QqOfHrNNIqn5AVYR5+lAteEExRYCJSvgN+sSGAXg2dWS4TfDh3pf6zfyfPyH8Pp/o4RhBiDtcTuVVfJa37e+Zz/PFfY8cP6YYMWojk7kyVbcg4D8fhnJRH5H/GVS019x7dtmxZWnTc3+p03triNC+lZBmyV/7a4OQacIQMcgCsAxObZ945Jlrb87YmTjF39GBOB0rAAomBmYhRDMlJo9RPJsgRjQcYgYVF7/hqm5611T++AHZi1mn7zcGl62HOMKAaiX2sJ+J0B+M6STVds/Cg3Di8TUkwJgh5HkvpBcxSZ6b4UWWNqo/vi79sb78MmgwG8fOL8QmhremvvO1E/XGcoRf4gBQ6X0n6Tu7cUfSoOPVBiB1tAICv0S9PjT9OF5ozU0/zmPuY7pjl/tCwEImO3ppz0v/uw0bCGcLtXWmlo75awYiLVF3Ep4fQ9W+MVPqtaV95fq4AXuXVrzHUDsXKAC4pn+/lecU/eV49Ibv28uv/orZuG2z5m5GzrMis2tpn6XEN8RPorBFoBRVW1vjVzy0G+OmDfvmR8vW3/ymWmbXggTPwoRgnQWQaEC4GPali4zuUnEYPsLZt6Vb0rN/F1T89CHdhoyLxySM4ZPAVOg/ii/Du+lCF0EEB81CpN67L1cIfSBOKTSIr/t5imu8DLzjZoNAkAehvU4au2n5AKcV1Dr06+A5UNtep2IAKSmY4+vE0F4/RCpJb9Ah1K5rh2Ftz+X7EEnHkxrtSaA3tcnvRKdI2m1w5CkRSwbyErHpB1m0/wgD+SZee4+kPMAYcBqQgykbJsG+c20cKy1JQg1hPcJFwNEAaGgIxbS804Y1k2N6PC+9BiFigG/sQwQhMA90kLubSeNye/ld50zS2/9oVl60w/Nkuu/Yy478IpZtONZs2DTI8k2/YZWM3d9u1mxtdPU7+5PfMVgCsC4moc5fumS6tZfsEuCJ68/eWT65pfChA9BmgUh8oNiCgD9BMRpZx0yBVl+T93cKxbCKTN3/+tmyU3fEjP/fWvq2w48VWJ5uX0KQ5GQitPdwy7ekYJAIaRg0xFo+wSkYISmpzL3nUJO4QVcZ/7AZiEltTATbrAWILmdESngCHRkYLUjG+TDuoBgLBaiZx+z/4gIAbU+E6swv4kDf3a0QX5DVuKBqBo35/2Zl7rakFqZtPE1Y9Kq6eZZbA3tnpP/tK+xkKidic8Hz9hnth01pOQjnbXso5jaco33KPH2q525J3kIWQWp96FHfS/uf1pQQ+t9iNO9m0yw7xXSy7PwrEtu/4GZve8lKZOfMxPqj5ryxmNC1iNC+DYhPj34bSkSWwtgKAlA7XE5tp0eN+7O5IYh5etO3jVjyythsoeQRgBmbEsSN5++gChUAFJo6UouTBIwDXnyuucMk5jm7v2qiMEP+5hgwZdfKChkfkHjXhRIR4ZsO5bUL0cEATLVISBSuHRev9ae1qJwv31YK8P9xj+zxNjvvlnICvFtrYw/9evQJw79LSTV2nmdCMUaiYv0QI6lAq2ZbZrd77jngqx2vb/4Yzt0O6tO8iprgqo/xAKSEl7fabZxKPR9EZayocLiRCwTrOhBeAH/WQ07/5qvmOnbTppL1z3qJuO0So3aZiaLoi6wvffne/AVxRYASA/GrGZMP0zydHAC8FlLflz5uueumrnttTDZQ0gjAGDKJob6hMQFWgMzBMQVuoeFNEXKRAQmrxUhaDllZu98wyy86ttm6S0fJmsbUEwxwGQEWpBAloUpEyzJBPym4FGbYlH4hI1C/egYNmS9QgjDstpojdwnLP9d7Ywo6BRo3QkntfuQ/E+1mb20BkE+8AyS5xpPTjVzOuQaB/5574gHtb3L12zgk3753efM4hu+bWbsPCtl/llzaeOjQrw2If5hNyHnPCHLpC26IEBgUIgALJTzc0QA9D7jqnOv8aMYV/sIawU6HP1FADac3D5z+xthsoeQQQAsWpJCAKaLVRAieEaIFcH04tj5CCIAmqaydc8nNzOR49SNp0UMXjeXXfc9s+yWj1JiECwsIWiBI4zWHFqIikT4TEiJAeSUwgiRIasud8UU1xo5GlbBNfWr8xQQAOKi2aJNp7RE1fN+Pmge8FvOWbJp/sbFE0IuftPBS2Mf8550alrTQfzYfJY8WXFvwu59MXPXS2ZSw5Nm9MpOc8kVDwgetDW9PwtvIAVgodT8xDdHwk6X9pud7ptHbR+CFYDK1lZH/xEjytZ3rZ2xVSwAOvh8osfB7hWQhQgoEIPN0jwIkTwdchCA83je7mhUtjYpBnRuzt//dbPkxvezswoo6FqIsik8Qxku/dZ8h6jy7H7HqCV9PiTECgKha1nC5jE1dLp3EYM+gsX7clZKXNMkBL+m5ze7Xs298k1TtuEZM3LZYXPJkocsRi49bEYtb7OA6FHyF0sAFm8Uv0J6/M8T/9OE9BUCTP+xYuqHiJwvxosAjF7ZdtDRf8QIaUtXTtskZk5gPUAcchIAB9s3ECJ6HPISgL5IigF9BT1m3r6vmcsPiVXALCytsTgiClpr+DXccIZ7HktUJZlPnEJAHLnEo/41r8lj0kg+uzzXa8HwDipYWC4ImR2NcX0dWDVYSpA5zjLimu3EEyy/J2Euv/m7Qvovm/KW54Rkxy3ZqelHLWtNkd5iWZsZK7XvhPriC0CdgPPU/jPWdZjJEs8kuQ9xquDk085PBwRg1Mr2nY7+I0ZUrDu5YGrMeoA4DIgA0HHodx5mEgA5n63VgjWAVVAuR0Y8Fl37tll6W3KLM+3d5RgivxYov2DZcO4Y9eOHjcL3p35zjSMWxENNCJGUdAEi9YP69f2HzmVCIEzKmqKWDqU5CtIvYbQfwcZBLS/Q7/3TjLH9GgrXtEn1aUhzhw5NXQ4O6CRNtel3vGguXfu0GbPyiNTyD56v6aPE9wVAauFCBKBSBGDNniTZQZ2gRsi/ekenuWJzkvTjID3xReIvvgA8yjyADY7+0gRo7JogJPnI7gsQIE8IxRQAu4x4C+sEzoPzszIJgCDrZouHssZnJd4uM3vPabPgqi+Zy296R/Cu1AjfMcvv+jApBFIYteebXm1qFwv5bScESYHTXnUKnO/Hjg97JNZ4OJ+Kx4Gaizi0BlOQhnyEwNb4WdSmKahfBWY58M+FwoXgh/EJjzA5kcsE8ooOTPKAWl73VSCvIXi/Dk0PXGNuSMMRgRyr7v2BufzGr9ue+7kHvmRJP3pFu7lkqZj30q7H1A8SPoosBICaOyQAkH+xtO+p6Vdu6zSVAo7LRRBsO1+An0up9QNxg+IKAPcRAVjVeZmj/4gRlzY+949l60/+YEpzb5AwIRRTAPoN9wmm0mcg5xGGYgtA+bqTZvrWbrm33GNbl+CkmbFVIMd5B141V9z6PSH0R3ZoDGjhSiFS8KLXbScbtY4UXgo1vwHnfX8gLg6tyXS+QJQoWQEBoUalCQC0ZqZGde3mYLgoJJ5gm9/Fa+PxxSrH9Orz2enVkkeY9Kn8AV4ehWAnhAlqD0vT7s7vmMWHvixlp8tMXCMFvbLVXLL8ASG9EF6IPzKulk+HDAIAZor57gsApKYtTy/+8i2d5vJNyU4+PW/h+R98AWif7ugvFkDLyb8SE/k77AsQJEwAxW4CpB3uS4OCBMBvbjgwFXm2nF913VlTc/tbpva+7yULIZNusiiMClt49XfkfzZQ/1gb9PxHSZMPIHHWpPfhEdrW7ggJcQWu5wIEEmEMPXdaiB/hiyU9/ivvfFeE+yVpy3/e7nrLdljskDNyxfn98EZVBoidLbIQAHrr53ukvkIIv2xLh6kVU3/V9k5LfCV7CEUXgMrAOQsnAKs7Rjv6jxgxpfm5P5K28dv0AwQJE0A+AoA5HyWcYsgIgGD2zm5TdbDLrLrypFl1VY9ZfeNrpuaub5naB394XgxCBbMAUJCp9enUgvB21h3NgABx8kauRMW/C2ObBWpJUPs7U79f7Z8DqPl1voI2p8iHOBGA9Jj3XF99//tm6S3fMLN3d0uBPmYuWZbcFsvuhRfYGmvABIBzAnrwL9vYYVYK2VcLaOMrquS/X9uHUBQBWJnEqBXJdNv//fzR13Cc/Pg/jv4iAI2f+3WxAL46tSXDgiAP+QgAZn2UcIqhJQA9pkqID/lXHewWiBiAa86Y6lu+bGru/rYU2HOmFtLGFNZcgNmL+QshtN2fT/u/aID03J9aXokfNf8jsH4J4wQjW/jPS7ufZg8gXyC6mvdK+iU3flVI32PK1j9mt8QaJ220MauSW12nQ1EFwJGe35xnhACSa+ceSPXyD4YAUNsL+qRZRCAkAM5COveZFa1/4+g/YsS8g8/8uBDj1akbs1wQJPjYCIAPxECsgqoru0zTrWfNhge+bepbPyxICKj5bE0vBLhgpFfScn+f8JEe/bTw+xfyaWY4WItH0kMP/uqHEta8X3zt62YG++Gte9RMkIweKwoB+ZmUQwdcNhNkiiEAE9ckCTm+xs3IkzhHyjWu07EXHOYbYAHQ2r4fJG0h/+wFIALw3dGrH/hvjv44M0IsgK5pJQFILwAOVQd7zMYbu82O23rM5jvPmuZ7vmIaH/yuEDqRnHufhxjQFqbm6zMk6BFjoGA79wAmfZTU2cATCDvJis7FPISMUQ87KUeOS+/8oVl06Btm6pbnpKY9YqfejqtutdNv2RDTJ4cVgEBBj6JgARASjqO2Jy7v2kjBaMEwE4B3Lll9+E8d+XFmxOR1J7+QkwCkWRIcBysAAdKBwRaAaZu7ChKAlpt6zfbbBbd2C7rM1tt6zZY7zpqme79uGh76QXKkgL6CLDsPte1rBUSsAh0ODJElZ0TNcmroaE2vhM4FhFfSx90rANv2p59DanlqekjP6rqF174l7+SUXWgzoa7TEZ6aPkwMMCgCoHC1vX+uUAFgKHDa2uRzhJ4PFFUAah5GAF4fz2Ygvitr6npo+lZmAwYIE4L4CxEyHSA5IjCN2hfCeQQcVAEQVDSdTN3bR64CsE2In0RPSgy2337arLv9NbPqpjdM9e1vmbqHPhCSJ9KKAeS3vxn+gxiFCIBHwn5j+iBE5jyQMvW5Xwbip0gvWHL7e2bugVfN9G3Pm+nb2fzlObvHvW3T24U2TLvtW9PHYVAFIIBiCMDUxuQkoNDzgVgBoMPPS0sfxAiA7QCsauseueThvp8LL2/pvmr69peTxGKGHVuBBYiTQh4CYOHG9CG83ULMEW/4C8B57Li9x2y4ocusPHAy2Xl49Smz+oZXTe093zW1hz9KioCr8QFzDfx5AyCvJgAkxPyGmJj1SlZty+db08cBC4A2PxZAtN0vaYH01rQX2E9XXfd1+0GLsg1P2Nqdba4t5OGTq+uyI72Pi10AeL5YAYh2/PmIEQA3B+Dpf1x97Occ9ZNuSkvP1pQAKKSdHysE+QqADxEDFglhFQSvZ4FCBIC9C6wV4lkixRGAXrPhxl6zUvzZMLbzUIRAfq++7qypvuUrpua+75tVD3xkTeDk3PQIgXIBYbWmh5TFJnomuPvRB2BnO2LWC/lpyy+87i2bp5b0UqvrBy3yIXsIWQmANzRWbAy0AIytDjyPIg8BmFD/GE2A4xMn3vUTjvpJV7Gpu6GfAKQjWTEEoAjIVwAUUzcyEzA57RghUAHwCR9FzgKQQnJIcbWg8spuM4ePP1z3DXPFbf+Wqi0zmdL9IP7tSj9q/AtBfgHz9HUD1ssPfd/MvfJLZsbO3qRZD+lpy9cctj34oUJeCLIWgBBJioBMAlC/Jznff+gIAJ8EaztMv18fV7Gxq25YCoDU5P3SlgPK1slz8Cxi6UyTZgizFWfv6jEr+pH3PBCA+mt7guQH8QKQxGpBpVxjuirTj/lYymIxj5fe/gOpzRPJ3vA8hEDN/8EQAyU9tf7Smz8wCw5+05Q1PWs3nBy98rD7ik3xavo4DFUB4HeDkL96Z6dZsnkICcCaJ8iP2x3tz7vJG7tmTN+BAPSflz+UBcD2V0TTlg9ECKwYiKBMEatg0Z4kUSF7lMCcq76mcAFI9T1sT65J4Pe8A6+ZRYdEDO54L2UV5C0G2iwIEDgfWBM/RfoPzfwrvy7Ntx67cYbUKsmZeJVMzEnfc19MDCUBgPC64o/FPvOE3KzpZ6Vf3ErBwRYAPgs+alXHtY72553UpP80Y+erpmLTx1QAPExqOGmW7Om2JK6Tmh7SQmYA+UFNMQXAg12YhFWw67Q1pRff+K5hhaL2oGfdTMAPiHYIZglbwzvCW9LL/yU3vmdJT4fteGlLMq30khUPSmHr+w16Oq1ChXkgMFQEoFrMfEz9ZVs6zUy3hdcYJgxJ+mbJ/6EhAJJfa06YkStbz+8FoK5iw6lPT91yxkzZ3NuPZENdAKi5+6WvAExqFAHY3W1235Vs5zdLex9Cc8T0h8RFtQBCEKugYqOkp+Wkmb7jrJmz/0tmzr43xTr4thA8kbQMAmKQmtgDcqz9ozX8wqu/JWL0ouSxpKP5Wdd+bHU1ffw36AdaACC9nYLrEEpDHwygAChYDVjWIOlypPcn9bBQqNgCAMHTdWzyzNEwY1ZxH7sf4FpH+/OuvOn5vyxv7v7hlM2n+5EsVwGwIwcbuqTg5D5ZKB9MYbSCNBVJCFQAdt2ZJDQiAKmBnfBzKwRPCgDXtnMUFFUABIyQ8Hy6LXpZ03M2T2fufMnMv/otc8Ut37c1vN2aG7LT7ofMtP2zbP/7NT07K8+/8htm+tYz0lY8YfiOPGRnOe3IQE0fh4EQgHFCrLH5bog5CAIwRtKGMIXSXjQB4DmyHM3o8/wOCMDY6oexACod7c+7ieu/8IflG7u/Mm2rKH6EYEEBADGzAa0AKBn5LdDx/2IDktjee74+jBBoWgsQg6gARAHpt4oIYA00HuoxW25J/of4XC+2APSFPCM1sgjCFGmuzdjxipl34C0h7wdWACAzpA6RXaEdeEnSf2Dm73/LTN3Ua0mfbMtD9tbYGj4TiikA42qS8YXukzUGUgCWCfkl/lDaFQUJgFg4o3IgviKUD/aT4NIMGLOyrdzR/ryb2PLsfyxv6X4zJwGA2BG/1j+kD/inp73YQkB7FLLYYTxHHJYdT5F75ds0yEYANgvptU8AUteKGDRJE4HrO+/otb8HRgA8IHjNz1sLYeqW02b2HmkiXPOuWXZLcs9DXwi0prfm/S1i3l/1tpmx5UUzvuYxYzfBXPqgGUkNnyfpfRRTANK2gbNFPgIA4WhHS9i04d06gdRKwQDyEQAWG2HxWFM/dN8MCOVDUgD43THR0f68K2t89tfKW7pOTd92tl9BK5YAgHzWEKSDCoAPKwZ2NyGXlrj0xyBbAfBJzcQhCI8QNIhV0Hio14rD6qv7kh8UTQA8JD+WImIgR97homvekXb8D1O1fXKo7m0zfcsLZkLt42Z0ZYf5DNti6V54UuCjBSZfFEsAbAdfobU/yEUAyIfKHMIXQQB0LQAg73yLp9gCMLKq7cMxVe3/6mh/3lU0fu6T0gR4KjkUGClgcT3tQ1QAFEzqUX/p0hRFPgKgsKSX4+X7esz83T1m+ZVJEbBwfgZCAM5DnpMmgggBHbpz9n5JSP+iJT3bYbEtFnvi9dsPb5AFQAt86JrCCkAg/pwRR2B/YY/W+LmEBwUKAGAl4JjV4WcttgCMWtn63qiVR/7W0f68m9jw6M+Wb+x6MlYAQrXoQAhAjk2EtAIQ3WuQ5yBtGSyCQgQAVAvZrxABmOo2N12wR4TggJBexIBrYOAEoC/K1n8xud31ksB21z4GSQAgtX7dBvM+5EcxIAIA6QWjeV5p7pAW1vf7tW4/DJAAsCHorHUdUisn7xG6d7EEQGp9yc9jTM763phVbf/V0d5zZsQIaUs+MHPXa8GCZCHk7fPtgCIKAOsBIOxUNgENXI9DTgLgo1nSGUgfKJYATJf7Y4WQDn4zxXjR3h6zdP8gCcCmHnkXz4tJ25me/GAABQAiQ3a+Zef7uxACABHoWCNun7QXUgBGhe4J0t03AzSOsWJZWJGT553U+DDDk++Or2v9Lcf6vq5i48nrZ+1+M1yYfFBLpxAgNDVtgFggnQBoRx6ESYrB+YVC5dwrEgbkLQCCOEugmALQJz0CPTdbQNpB3KfThqsAAAilCF0H9PCHCKMolgCQBuKypCfuAFkHQgC4H2LDxz0h+6AIAO9RrIY+z+uAAEyoa/vKxNV39V0JqK5iY8+embteD84GDAKLANJgCfgEzVMAQiQAc0QY5tqJMd1mMjW3d69CBCCV/ggQgKV7us2+u88P7RVDAHxwzU/L1IAQDGcByAQI5xfOECjAobC5Ipt7FVMAlPgaflAEwDZpkuHinvfSxuNybOudsOzOn3aU7+sqWk422T6AXAXAwQ7zuWv+eR++nz4QUtv9AbzhPACJ50sbGlItE9N57g4h/FZp2yIygoEQgEvXnjQLRHDqDyVn/+26IykEEL9YAtAvbSpq8jx8C4FRjJIADB8BIK1MVgqFHzABoH8g0HEZKwBrH5F0tj09sSGyFFidEKKKeQBTNvWfDhxEDIEyfWMwGFcaAZi3O9lzTk86c/AZcrtM2tLTHUHw44fxw/a7j4+Y9DN/gNmFdOKxMrBS7rfx5iTpVQwyCcASEStM/lC6QNq0IWxyRNyC17NFsQWAGsbVMoXiohEAAROBguEcBkQA0ryvDALwZKwATG7uWchU4KwFQEgSIlAmhOPKLABKMIQAkvH7MjHV5wpJqW2jQlCIALBPAH0SxKtx05tfd13SAmA6sKYnBNJLuqNpyjptxQAC0FwkAfAWngSv54ihJAAZJxtlEIB+8wYiGCoCMHnto2Z8XdtdxkT2AlAnJnUF00srNp0KF6gAcp1kA0Lx5CIAPhACLAJq3LkSFv8p01v+205ENa+jyEIA/LQQ7zQBQnCZmPih9CiGhABsFAFoOWk/gpmzAFCrUQDlvEWcvzzxcRCAkRKuTOKPmwMw6AKwjm8ptN/g6N7fzdrVc8n0bV0fTd/ef0FQHC60AACuqUVA23uxNA9mEVbASAJDfsF75igACkSA+KPp8DFcBUDblUE/AisMkQKXD4aLADCMBkJ5oUgnAFPWJGf7DQkB4GMqte1XOrr3d7O2n/77mdu735+9+4wtoDoMl64tmqsAsPsOuwITr41ba2jBtDwFwAdCQBOBabkIwcxtyfTbZ4haAnkKAMLCyETo/ophJwDAr+ljMJACwIQcBfPg8RMKmyuyEQAW3OCPuQpgnJxDgOjdJz2hvFCkE4CKNALAeZoHeQlAoPNPES8AJ+TYvtnRvb+buevU74sAvDt7zwt9C+u2+MKajwDQw+3HT81PXNyH2tUnTa4CoMA/HYaXiwjoZJyUkKkQxAgAsJuGbu/uJ0g2TYKLUgCyQLEFAJIxZFYssocQIgT3BRPdb50sE/VXbAGg1tcmARuFTJb4Q2Et0ghAuvcQJwBszDqhvn2Zo3t/V7H77Cel0H9zzp4X+xbWARYASDZN7rH6ml5TJbU3M+b4b++dpwAArAE7WuDfT37bfgHSnmbGIkj39aCSAAwfpMTGgZV3k4WYFQ3Jz3WzGi/uqzzFEIBFjvQIAbMCp8j9EB7iJy2hsBbFFoCmJ82E2s5Zju793azNZz4xY0f3W4MuAAIIz7j73rt6TcvNvabyYK8dhpsi1gFEqo4QLBsEBUCBEEj6MfdD6QQlAeiP4SoAWttDdrbsYpNOCAk5063HB0wfDuWFBW3xmDxBAMpFQKj1p69N7hikFocKjj9hqB/yFQCJM/oMoFwsgHH1RyY4uvd38xq/+DNiAbw4Z+/ZvoV1kASAITbW0u+8PTnWzrZby64Usu1KLqbJ1QpIJwC076eJJVASgNwwXATAbqLhMEEIN1UISG1PTQwh/XZ4JgFgam0oLyzSdMYBmhZ+bR+NG3EKhQPp+mT6vQeJh76MuOnVE+uPmEkND5OGzzi693cTG3p/Yua27qfm7nupb2EdZAHQKbf8ZuINm2voBKAQ2eIw5AWg0Ik+GfHxEwBqXUjPhzwnChlmCvHnSI0P0UPDcYMhAKE4FfkKwCjX7KC2txZFmvSDSWuO8l2GD+T3/3Z07+/q682PzNzR/dDcfS/3LayDJAA0AXwBUCACa69P9uyHyBaHoSwAxMuoR7+RiaLi4yEAkB7wu6yu3Uxd054iuN/pFsKwEoBlSZAemg7p0hwFAjC+tv39CTUd/8vRvb9jhtCs7d335yQAcR/moIMt0MsO4aZt6j/EhgBUXX1+vr0PmgPsvRcnABA91DwoSADkPNNxIbAlMel1aS4JwNCAHbqT4wQxfScL8bWmByGyhzDkBcCR3hJf/mPZ2LD1/eNKB8z/CXXt35xU2/pnju5hN3NH7/55B17pV2BjZ9TJuSCBWPSjY+8iBHbITWp/CMfmnVEBgChMrtl0S38RiBMAxvtZV88ae73m77xTqAWQel55DrYXU5BW+iX8tERRFAEgb8nHdH4yoktIctSwG1CwAOeIoSAAkAZiMVfgUinctpZ3CJE8HYayADC6QE2vCIXPFnYlYE37a/+ysv33HNXDTki4ka/T9CuszKgLFUQKaYA8tuBG/Qo4z5d3qEWB3gOiMPyXqwCw5ZadmSdhISVTgrkG+YsmAIDf3n+aMX5aoiiaAGh6RDytkIb8ZcDFIAAQxZq9NecL9XipBSevCRM7WwxJAZA8po0/XiybCfJ8trbPscaPgnUAYgGcHld74lcd1cNu1vaupfOvfKN/YS2WAIj/2du7zZIDScJDEEWuAqBg7z1IjqBwZHHQFSIECAB78xVFACLPwErEUFoURRcABX0uOQrBcBYAu6ONkD7UycVQ2sUkAGzDbs1+FzfzDwolvsKuA6hte7bfZ8Gjbtb23pkLDr7Zv7DSBAgVvFAhBTECwDr++Tu6k736QmgW1dCepg8AUuYqAKFa3gqKHBECFu7EklDA/gRx3xAYkgKgyMEiGK4CADlChVlx0QiA1PY+8RXFFQCmAXc8Me/gMz/uqB52s3b0TohaABCTufG2trRf/PEKWFwhTSMA80QAIC5E4QixIfFcIQzLbKMjAZkEgDn/oVo+2swIYdgKgEPa8A4lAQiD0YHFLR1m2iALgA7b2T0S08RdTAEoW/+4PGP7UUfzeDdz+6l/nb37BSH9qVRh7SMAWvCU4HGFNEsBULIAfq+9IflVHYivn9vKVwCywUAKgC5PDt23JACZMRACYCcCAan5WYjDnvxlEke6cfRiCQD34L9/PVTzK4opAOUbnjQTatoedDSPd9O3P/8PUkA/mL37dKqwhgQgBdqk0XMOocIZEgAfkJymAU2ElpuE/G4y0NrhJgCSrllbxa/4T+31J/lo4X5/rAUgi3iKJQCQHVMfMAWYabmEmyjkouYnnlD8ikIEgJEK+jCsqQ8i1wdLALAAJtR03OxoHu9EAP5yxvau78zxVgSmFYA0yEcAFJAdEjEBaJ2Az3Tr13cQCPU31AWA5yUelj2zDJrO1Onbkjsgf2wEQMKk9hkArtAH/XoolgBQy7MAh+nAfIRDTfBMxFfkIwD6rJnyK1cBIM3ZpjuF+k7hLpuBdOxzNI9307Z9/g9mbu9+018PcCEEQAHh+aBGw3W91iLgg5xYB1YI5PqwEAANy2/3X/dDSPsFZfEbSpePuDT6uGACENO5ZRFDHB/FEoBJ4m8s5ncOpPeRtQAgdDyv98xxKwUtyB8/LsWyNjNW4upHfkn/pfK8PLN/PiNEANgPcFxNe7Ojebybu7vr11kQ5K8HyFcAqO1SH/pwBTVXAVDQpuYLvCwUoqNw3fW9lmRg2AhABPST2HvJMXgvORdNUxRDVQBiia8YRAGwtX4kbC5IKwCA6zHPm7cAyHUEQC0VFhTxrPRfzFyXPB9KawgTRQAmNR4XAexc5Wge7yY29v6imKrPz9n78vn2KhCCMY8/VAjjoKYuU4l1DX5Zc/4CAPHtt/hFBACCQBNh4R4xp4ehANjZkXo/RlcY1vP9y28/PSEMWQEIhO2DAgUAUlCrTxKShEjvY8AFIA3yEYCRIgDsNDxO7s3z0YSZt+H8EuYZOQvAETORtQA17QsdzePdpxse+any5q6nZ+x8xW4J5vdi5ywAQgBfROyagk2FC4AODyICjBDQJLCTiuQeWAKZhv58DBkB8KEWgSB43cPHTQAw48fQNpbfczZ0miWbOy0xQsRXDBcBgPifWSq/5Ti5pt3uGMQSZkivC5ro0MxHACYIxtd0ljuap3flG7s7Z+w8/41Au1knZClQAAAEpcYuhgDoEOH6G5Idg8z+Y10AYpCtEKQVgJiJNioApCmUVoAA6AdMQnFYxAmAg01b4LyPbARg7KqHh7UAQHpAjT9NCv9cIcKKbZ1mzZ5OU71z+AvASMElQvoJqxzx17ZbwvvEV+QtAHUd58ZWt13iKJ7eiQDcYz8R5hUierHTDfmFMFgCoEuFIR3x8puJRTQ/MvUNpBMAO9vOywOFCsAKPv1N2gLPwjk+Z1aIAGSDi1kAwFip7en4WtjSaUlfI4RvEOLX7U5i1Y4BFAAJx+q7YPqzRDoBGLWi3XxmifiRvJjekDTxF7UkSR56DpCXAGD+13V8mHYpsO/KW3oOzdjxar+CNNQFIOVX4sa/CgEWgZ8GH/kIAGCDUSwMnsUKgXseFQTALkahsCmUBCAWLPWVNqst8KuF5PVC9jWQflenqXUohgCkFQYJx2e/7HLc0DNkgTgBYCfgCSIu5bXU+Ahc/9o+BPIjXSdg6HmsALAZSE37nziKp3dSqDZP3/6StNf7FuCcBWDb4AhA3CxBwnAf1gTENQcKEQDC8zwsY+YeCA3PxrAl/RIcQ2FTKAlAH2Dys60VhZuan5rO1vYe6X0UIgD85z50svnn+6DYAiB5x3MDTP7yunazeFP6Gr8fxC/zGaICwH+eiWf1z4NJa44hAN8d29j+647i6d3kludXTdv6ghTyvp8IixMASNSvvSqkYugwSrhiCwD/+W4fNS79AKGwAyEAQAWOuOkstXDxMjS5YPcwEACISCF17dFMGAgB0BV/fqGlzY/JT80fIj/IVQAsSRxxIP4MIRIf5vDv2wdFEoDUBCjv/CVL20yZ1P7U/KE0h4CFQKcgMxhJn30mgd3sVJ4FyyDUPHCbgXy5vPGhf+cont6Vb+xZODXwjcBYAZCCTO++3QFI/Qip7PZfjhCKQgSAYb+oAFgRcCMBgyoAQjzmOUQtHAXPyQrHYFjFhRQAaiIplCnSUjv512NQNAEQsIElBdgvrAoEYPnW4gkAQ2qT1yS3AmfnIIbV2BGY9QCh+1sUQQDiUIgA2L4JyR+EgJWMdrNTeRb6D2IFoLb9tTHVxz7lKJ7eldtvBPaaKZv7fiMwrQCoPwqkK9j24xoBYuQrACwV3uEIHxWBvAWALxkPgAAALIJgWMUFEABb24dIPMgCQMeXX0ijKIYA2LFzgSW+EEXXA0AkxXASAADZeRaIzjcGokOEof4BdgMaV9t2sqKx/ZOO4uldRcvJS6TgnOsnADH7/9kmgOfPQgomTQDIB+mVgPkKgKLhUG9SCEQEfCFIJwDsFBQnAKTxoheA1Q9Lbd8aJGoKF4kA8FuJf7m0rxdvTJJGr/sYLgKgzwPBV27v7CNkUb+seegnAMndgJ4Y2XjVzziKp3flzc/9ffnGro+iApCuwEYLIkNljIOvFALywU4dm2fG3iIRgJo8BUA7+xoO9dhv9KsQxAkAfQPcPygAtN+3S1oDz2NxkQjAuBoRgJVCugBRUxjmAgDJAcRYvqXTVAlRCLt86/AUAH0mfiNkVds6TbU8a408d1ynISJBsyDarLK7AdW1t807eDD9ZiDqJrec/IPylq4f0g/QpzDlKAAzhCDaE8/CHbbnQggARNahs1xBXEr2xuuTFgGrBfkfjZP/Kw6kEYBtGQQgjmAlAQgjyw7FQgWAkYH6PecF4IrNHWbZlg47T4BriANhOTccBIC0WDhy055fKs9Ejc+z6PMw8SmdANC5GRKAcbXtt48wxjE8g5vR2PsrFRu7vjt1S+EC4JNRhYCx+aV86SdPAfChFgEfAWWDUMbe+a9NDO7BubwEQCFNH/t8Cp5RjsNHAI4PnADw3yHa050O+QqAEoG5AauEHBACEbCCEPFbqACw6ShDk8UWADvXX/KKzkglPu150gKY+88z2XkP3jPxjLkKAM2BsvUnmEx1jaN3Zjer+blfqmjp+vLUrS/0LUwFCoAlpEP0fCFAVGYL4aY70rFJ6DInMHxerGABiIKRg5Yuu55/6AtAjxSCR4suAOlWwGWDXATAJ0HltmTNiKkPsSEKloBe95GPAEAebUMzA3FSdbslbOgZ8gXxjZX3YdvykgY67vTePDf3rXWWjP88uQiAgt2OFmx5Qp61vcnRO7PjK8FSwE9O2/Zi38JUBAEYKLCxqJJcOx0RAqwCvi/IuShB8xYAB1Y4Mt04TgQKFgDXBEktGw4hXT+FRREFAMIrQtdzQDYCwDwAJgJR218h7WAIQ0GH0LazT2Brf08gfOQqAEp8O1RIGLlfhZjpmOuhZ8gXVgBEQFnswwdD7b29NEwW0mpTxn+ebASAOQHkHVaEPvfSnZ81CzZ0VDl6Z3YTtr350+Ubu0/Y2YB+YUonAM2eP4HtBBQBKIaZnw18AUgR0JGQTkcm5dAB2cdPgQIAMe3GHvKc3Me/NyiKAKhfBBb/DFvG+QmiCAIgZLVte/FXDPKDOAHQWhDQPl4qBNbCDeH7FHhBMQRAiU8HGhODtIeddjhTdYstAIDn11q6z/PnIQDkjRVFQbkIChaFPh/HJTufkmudmZcCq/vn3Wd/Ugj8cC4CMHVTcnqsWgIIAFuJ5/NV33wQEgAlIbvz4oeVgrpAyPotggDYfHHPPG1z8n7+vVN5F0IuAuAhZREwfDlQAgDR/YlCDgMlAJYMUvgxYSnE7NtH4Y0jLyhEACCHNiO0xic+JQ1AgAZSAPznT+VDBgHgvAoA6SX9CBUWUqVYTFa8PIFY0NxpFm951Mxd3zbN0TsbZ0ZIE+Am9gToU5jSFFg2DKHAWxFw/lkJt0BIlu+Yfy7IJAA6GsHCHTogaR4gAOzTF3qerKACoHBCoBbBQAmAhdzLWgN0ULr//fxY5CgAUjC1nR9CsQVAa1+Iz6y26OSWdMhVAJT0HKn5Mb+5J4QJ3W/ICYB7HmsNuXyin4ShQZ4VP5wjX/QZEIBFm46bOeuz3AtAndTgh2bsjKwITFNg2exDSccqQJYPT5ZmwcJdxRWAOGsiGwHAnwoBR/oH5u0sogBEMFUsgnhiJgHJg3GDjLW7W5UoVgwWWOh61gKQJYopANT65VLYaQvbwmoL7PnCmwnZCgBkIV6EAMuCmXSQzXa4ifCE4gZDTQDo7LxsY/JZmN8A8Xl29UeYqAAsbDkqx04zr6VjlKN2dq6i5eTO6J4A6QRANw2xEDJyZD/Ahbtz3/0nDoz9U4MTnyWxFy+jANkIgA8mDy3f353zXocpZBAAW0tbf0LkGCEohgDYjkieVUQY4bXXuJ+959ATANsJJnH5xNcCmwvSCQCkoANxhRCF2n62kB9iQXq1OgBTauPujwBU1F04AaiXZ0DEAM9IZygTnFZzLfDMjBz0E4CNx/j/3vx17f/XUTs7J4Voxaw9X+pT2ECq/elDCDRFxCHaG05bm09/FUMAiGPp/iShmUcAdKgP0NGXqwAQ57J9gyAADnbKtOSTLwbFEIDoM2OBMUeBpsiQEQDCMXQoGClgo41cavsQogIA6W2NKOA85jE9+ZAq1OEGdCw+Lv4Jq4o/DAgyCQDPgwgs23Ie80XEaOeHyM+zr5Rrmm59hoWbHpZw7e/MW9f6V47a2bmKpu55M3e/0a/AXVABYDxf4iReHdajLc91PhPONf/+YCgJQB9Abnc99v55CoCFWgXbe82E+gskAOI3tPiIzT4QAC2k+UIFANMYUtBDDlH8XXXo4KPWD5ENYB2EBIDws8U6iCU/HaRZzHiMQ5wAAD55vnRzsjan2aKgKYMAhCwenp/ZkNrfoVi8+RGE4805jZ3/0VE7Ozd1Q3fF9G1npYBFlgQPAQGI3gOCs8DIP68YsgLgMHVTV/LDq1gC0XQUIgApiACsGXwBSNuRKNeYYusX1HyAAEB6pssukcIP8ZUoXINAmT78mUkA+j2XCpqkv+gCIOkcI/nDFGF9Pj9NmQSAPPAFgGe4zI4AtJ8dXfXArzlqZ+cqmk6NnrKJNmVkQZCgnwhcQAEAnAud12tDWQBYjDSLFZNitpOH9rymp0gCMLHhscEXgEBYBQJwqRTyfNv+PqgpiccSP3KtEAEg7BxPACzxo89SBAGwi3ckffwH9DfMaGy394+mKVsB4HkIz7NNWfsIae3+l8tvzm4psLqKjaf+sXxj1/v91gMoaMeqEAySANDmZ7jRv0cmIAA0E6rj4rzQArBNCOzlmy8EpMv2GYTidsgoADt7zaTGE0NOAHTCTbSQ5wpIEToP8hEAak3CISZMqElnyRQsAJIuLCF+63oDtgqb3pCfADBpivTTrzFZBNZusZbs/3mm8dONP+aonZ0rb+n+6/KN3e9O3XImWPBSoJBv6Cq6AIRqbDr7+N4/8fr3SQcEQFcfRtOhAjB5bZicGTEAAqC/p28RcrdIvm6UeyC2ofgFw1UAZq4tjgCkQy4CoLUmNWjFmiQxIVAo/SnkKwB0hnJU4nv9DPkIAORv2Jvs+5jaIM9V3W4ucRbL+Hpr/T3paJ29q9h45r+KCLzF3oChghcF49DRwgdRWQKcjwDQqRc9Rzy09XMRAGBHB8TU1s06NT4Vmdlbcv/smQXtdkQgjqD5CIBCzjG8h4AxxArRQ/coCUA8shEAaku2BoNcFWvYn7DdjJT0sWtvKO19kKsASN6pRRGXj7kIAMQHDA0yzDneEZ/81TSOr3tU7tnW6midvZu8pef3Klq63pi27Wyw4EXBnPho4VPzm9V6SrpMgJTU1oRnY007zOfOs4lIPgIAmRgfZy//yyS83oe4a68Vq2JHV/5WgIMd4osKQSECEACzFq0QePcpCUA8shEAmiJTXY1PunzyZEScAHg1us0vRgwi8eYrAHR46qgHYsDXkXgOnjFksVgBqGq/39E6eze15fSnpAlwpt96gBiEBABQ+1Lzam2bCb4AEJYtxdjSC0uC64z35yMAjIuXN3fb6cmsUgQLdiZXKy7YXrgApGCtAhEESCrk7NdhGkEuAoA/RNV+a5EmgsRfEoB4ZCMA41juC/ED6cyIqAA44vMlISY6pWtC5CoA+p9Vfsxk1E+d85k0nd+A9dL3PnQwPsK7v9bROntnWA/QfPKpftOBYzBFYKcDRwozBZZ+AK1xMwmBCgB77Wt4BUKQboPPWDgB0JqThUoIAWAIjlWLZQFyFgysAicAk2OaGDkJQADTvSnYQWQpABTWMf0KUH9cbAJgh/MCacwKKgCO+PaDntUSrxCTuIshABzpn2BkYKKI1RiJn+cB/oxG0E8AVom/muMicG0bHa1zc2Vrn3ti+paXM/ZEWwiZ7HTgmMI8V84v2Z+czosQhMgPogLgA+LnTH4QEQAfiIFYOsnf9L5TgweImg+wKhZs7zbL5blnus+rR4WgUAHIiAwCQCG1hTZUgALISgDETyisgtqWHvaBFABIs7hFaswMApCOpBnhBADij9fvGjjyZ4o7kwCQdp4DoYT4iCaWSvT7CT5CAjCW7eCqOmocpXNzZeue65y++SVbUCtaMohABgGAuKzH15l7cR2D6QQgb6QRgH5AEKJr7vMEArBoR7ftZ0D0rtgjZN/khMA1OS6UAFjiRwpTsQQgbuhM7wkhWQfAkFWUuIVAe/I5IjDMAmR3ndAUYEUhAjBmVZttQvikzzbuuHxk5uHUNe22Q3JSbZL4fr9EnABgDUTvNwYBqD5mLqlsu8xROjcnteEd0zefPV+oMWnjrIEMAqCg/Y4I6N59Q04AFNYaKEwIIPlCPoXuRh7s0RMCrIHQ9xOLiogAQPJQAQIDJQA0LfyCCyGLKQAQnrgY0oP4usuONZPdPeNQiADwYZM48oN8BAAwG5DaHkTDxQqAnI/6TQrAUXn3rVMcpXNz5etObp+68YV+RAgSJksBAOzdB8GD23gLhoQAOBQiAlEBUGD9YBEsESGgT4M05tW0yQq95tK1J1Lf3AsVHkUxBYDCb2v7QIEttgAwds9++Myqy4b0PvIVAMKF4vORrwDEWVAgNwHoFPE9IoLSOcZROjdXvvbkpoEQAIAlwDBftCkw5AQgQy9+OsQJgILzCIGuctQ+Dv0dfJac0WvK1j8u5M9cYIslAJnIUSwBoOZnfb+NM0fiKz4OAjB21ZF/cZTOzV269tnLpzSfNhUbhAhewQ4RpdgCEAqTN4aoACgQAfY5oFnEJiW6sCnn4c4QpAlQ3vTk4AmAtGHTtYtBMS2ATG38TBhsAaA5ZNvrQvI+8wUUkr/RMD5yFYBRVe0fXVJ5+I8dpXNzkzc8N3tK86nBFQD5z7wB5hVQE4bC5owhLgCA51aQJ3zMJG6FY064yAVg8hAXAO3Aowlm+wy4JmkeDAFItv/b3h1V+eDvOErn5iave270lKbeQRUASwYBewkyPOdvNZY3hoEAREEeMPMxr4lPPkoCkBYDJQDU8swxiOt7GcMQ4qAIQPs3xyzt+G1H6dzcpeue/9uKpp5+AsB4eT+yFFEAOHfZ7h5T5rYaxxqwE16yjLsfhqEAAJsPkkcXXACorVjAkon8oCQAFpA+SFY6KiWfg+QHRRWAY1gAr46rPfGrjtK5uamNJ/+4okmIIOhTuIUU/ciSRgB0Jp9/LZMALEYAlLDumBICL+6sUIgAMBzoP3sOGPYCgPkK+bMhvmIYCQAToPo8bw7IJACxyFcAeA9ynbChvA0JwLja4xKurXtM9bFPOUrn5srrn/v9ivUn/21Ks5jjfuHOVQCEtMyLZzGLnstJAHxkmvseAwSI6cr94ssC+c4ORAAW7ew2Ne7DpbniQgpATqT3MYgCwJr9i1oAVHyB+B+9gsU9gTgFIQEYX8dmIG2fHVX1wCccpXNzFXXP/lb5upNfpyOwT+HORwDUnxBYh7ko3KHPhA+EAAC7ki4aXxYoRADmiOgtP5h8Jtr1iugzhzCoAiAF066ICxXKXJBGACi8YJygUAFgxh9DgOmm+WbCkBUALC8he5/z4p+OwzhhDQuAXQnY8c9XtP2ko3RurrzxhX9Xtu5k79SNZ/oWbgQgSs5sBYBw1hpI9nJrQY8W/ItBAJjyi9VBnvBpMob6GOFgAlT0mUMYbAFgBlpswcwWAQGApHyzjtVr+uWf6PZduQIBYGXcxSgAwfMZBCDUf2M3A6lqv7u+vv5HHKVzc//SePaTk9d3PT1144vBAs4EIX9qcFYCoBBy0y7Xpb7sGUCBp3YckgIQWcSTDRCAaXJP3diDNGD5MPuPhVE8K2IQt1/CcBYAPq2t5iqEj9t7L19ctAIQhwwCQHqiaZyw5nEzsqrtekfn3N2nP/3Ij5Wte/6h6ZtfDhbwFCBIc+4CYMf65ToFnG27rnBCwK49Q0kApm+TtG7qss8JqYN5EIAvAH46dLYfQqDj/qFp0cNVABj6om3OvHw+9YWpX0zyA3bxuSibAHHIQwAmNjwpx7Ydjs65u3Hj7vzRsrXP359RAAS2sAuhbWGPFviQADikakY5UtD5xBciYIcBh4gAQFhbi8tzsPVZtk2COAFQMKLRdFOv2XxLrxUCaw14QjAcBWCktF3ZU09X5RWb+NpvQBOCb9/n2wEILoQAMBnI5nMg79IiRgAYbkRwQ2mc2PhZM7qydY2jc35OLIBbZmx9NVjAQ2AjS2pMv9BnIwApv/J/Npt+EGaoCICfRoRA/k+V5yxbG84DRSYBIJ6mG3vNzjt6zdZbe826G4T0Yv0wFVqbRMUQgIrmpwZeAOi8YnKLFNKB2OxDic+nvJj+S19CIeQHgykAdNKlaunoTkLZICIASeJL+gM1v8Uq8VP/mBlZ2brMUTk/JwKwf+a214IFPAhnIkMQ1rprzRkiFogKAJghYaZKc2JICoCH5Ac9pGngnjmKbARg/Q29ZsftvWb7bcnjFhECzkF+rIDFRZgJOJACQGG2cAUPAZjRWBwB8EcJlPgUfB1NCD5HDhgMAbA1frSDrhABkDhth18c8RUIQN0jTODKby8AdWVNXWtnbn8jWMDTgdqxoumk3d6agh5HviC5hDCMEgx1AYDY9PLHzRbM2ASQeNkubbsQf5sIAFAh2CrHDTf2mCv2ixiKgNIMCcWREQMhAPRUs9FltNARvogCQMchHYiMIJDG0JTaQjCQAmBnAsbFn6cAEC52tmYELARiJuCYlR0zHJXzc2XruqpmbH3F9viHCnkmQAK+GRA3CSeOXLGiMYQEANCOt/7E4okKQTYCsFBMfF8AfCHYJU2DxuuTVgCdpKSDMOnS0w9FFgC/tg+hWAJA3wHDhnTyFaO2D2EgBSBt3PkIAKCZFYovAJYBy/GcWAoTHJXzc+VrTy6cFtgTICcIEeJ2EkpXmFOfuo4gr+nAgoEQAK718a9CIMhGABbFCADAElgvAkBTgD4BZk4CdlSyQhCIsx+KLQBC8Ghh81FMAbCz/Ipc6/u4qAWg+gjv4v0xKzr+yVE5Pzel8bkJQuKPWBXYj9g5oGgCIM0CtsQODTdmwqAIgI/m5FCnFYBAerMRgHUiAHQK6vwI7RtgHkFWOySXBCAWF0oAQvmaDTLlvQ+7EKiy7duXLGn9C0fl/FxZ48l/Llv3/PtTmvpOBw6ZvOnwsRQAAXnE573oCI0KQS4CoEODwE4nFiEAjBKkS19JAOKRtwDIM2qHXAikORjOIZSv+vGQ2JmAglBccRi76pgZuaz1rX+9rO0PHJXzc5M39PxN2frnvxtdD5DaJVgImY0QfJwFgKYAeTDVCsH5JkG+ApASAhEAPqGW1grIIAAUVkBPtV3yGyh4Pj7WAoDp7giqX/cNIScBcMQPXovAjyMWLo1jq6wAfPkzi1t/y1E5P1fW2P0nUni/ObXldF9CqwAohODp+gk+zgKQygcVAsk7hIDNURdFRgFyFQDWF+QrANEFJCUBCMPmS6RmLlQAbGdqIC/9e0QR9esjmsaxVQ9jzb024Yr2X3JUzs9JIf7d8vXPf3VqS98FQf0EIFTgff8lAUhBLQL2Gliwu9tOBKLXfzAEgMLJphKhrwCVBCACeZZQHoBCBCAdQvdShPyD0Hsbu+q4CEDraUfj/N2Y6s9/Sgrrq3YkwCvEcQJgQbPA82v9xwiAJXOo4AouVgFQXLr2pJkp+dhwqMdOB94hQjCQAsCUUdr5oUIEhpMAJIUsQ79GBqQVgDTkB8NBAEYub3va0bgwJzXWqWmb+q4IjCO0D1v43Uq6OP+QMlhwBRe7APBhkBkbuyzB+XpQ803niU+zYGcRBGCWCEB509NCzPgCpChUAOgZZ9yeRUCFrPUHIQFIkv48uRA0n3i5Iq0AZBiqG3QBYCJQwD+IF4DWE47ChbmK5pOfm7bF+0IQEGKHCnw/CGEt+TkGrg8HAUhnpSAA6eLNRgAgMuP8LASqEyEAEJ9mAUc6+goSgObPDYgAWMILIelLAFr4iyUALPZBUJj9RpOF+/npHXICUO/i9UQqV/S5jxuRGSPvjiXW0edPhYkRgEuWtz7oKFyYk7ZqJ58JT308kzZstgLgIbp/ABgOAkA6QvH5CH27H2QrAEpqRIAanyNj/utuOL9S0Cc/uBACMEqIYYkfQ76iCYCEv1Tio0kRSisoRAAy1tK5CADEF9i+Fdd0CMaZAan8TxEfgW23Xzyyw7S5C8DVjsKFubLmrusQAKbh2oKNEEgB9gt6NkiJh5BCz10sAkB6ICJ7IvhCkKsA+GD3IASAZkHjoaQlgKWg1wddAKRgUhv7RIqimAIwUQr/kBYAV+PblX6Sv/aaI28wzgywvfgSnrjUotJ7gOwFQPIGAVjWvs1RuDBX1tJ9tRUAnxiRmi4bWAFQAjQJREjSkWtQBYBOzZiOzawEIAIWM3G/QgQAS4CVgYwSIAIsHa51y4W5fiEEIG6/P8XHRQAAeyjayVP8d8RXBOPMgKRlJelzNX40zbkJwMNm5LLWBkfhwpzU/E1JAUjf4ZUJfQQACAEqhCC0o0Pz5QdbAGyaPOtEkY8AaPqY/JMa9osgkwBg9jccOj8qQKcgy4Xrr3PXBSUBCKcjE4ohAJb0EeIrgnHGAGKTHpu2mLzleq4CMHrZ4SWOwoW5KRu7Vg6IADhATPuZ7EjhDQqAAP/peubjxCErAQBinfjX8hIAAaLGVmL5CgCA5JtuSY4KIAK6XHjjzTQLeu23BKelyYuhJgCcp4Mv06agw0IA0iAYZwDU+CnypwHPGgpvhytpOvS5vxOApe2zHIULc1NaupYOmADIOd8Pc+aVwHECAOJWBCIMcdeyFgAHHb24kAIAfAFQIAJggzQL2HGY+9kVgqBPGi6sAEB2S3oBcwNmb+gwFQ3iJ8O24BezANBsyDXtcQKQaoL0QVIApAkw1VG4MDdlY/fY6dvOmopNAywArl8BE59VdKlOxwCCJBfC0QnHdcLbLwnJf72eqwAo2Oasz32yRDYCMFMEINOXg0ICADjHBKJVIiDLDiTB4iA+ra4W0oUSAMgOie23+4XwZQLd3IOhvUzfBbjYBMC272uSIwXZ1PhR+AKgfQXEQ2dhv/uvQBiOnRu5vP3vHYULcxVbnv9bBGDKQAuAIosOxlgBkPMpfy4ebTLkJQBCUjY06XevLJBJADg/VeKmHY8IxH0wJJ0AbJKmAM0ErAiGDXWr8fm7khYBMwEHWwAgNyb+lMYk4W1BdbB+BENZAPqb1Lmh31yJAtKp4FnJC+ZDpM7LewgJwOjKTmr/D0avaP9vjsKFufJNJ/9uwARAEDdLMB2yEgAfkD+dsFwAAQBlAiyVpfuTZNf1/tkIgBUBwZpDfWcLIgaIAHsGzNvda8qaBk8AwOQ1yU0747bsHqoCYJ+/QPIDrAfi60PWAsGzYj30OZ9OAJYffu8zS1v/zFG4MFc0AWDoL0IAMCgCILD3wuIICcEFEgAripIetkCfLWlfss/V5J4QpBOAuPUCumdA9TW9Zs6Wz5uRUrijBT6KYglApk07h5wAFGju94HkEe3ycZn2XygGYgRgzMojrAP45sgVD/0nR+HCXLEEwEIKetQSyEsArHkbIV0mAeC+jozawZe6nqcA0LSYuqVvx5siWwHQNCACiAEfRYHQfCAFImcSgLVp1gsgAJft/IIZOYgWQCZkIwD0IaQTAEzrUNzZgtq0GLV9H0h8iImdxFNgHmWFGAFI7gXQ9tqYpR2/7ShcmCuqAAArAucJl48A2O8PbInst5eNAETIx2Qke70AAYC0xOGPYIBcBUCBEEyXZsGi3d3WlOebAdGVgrkIwOIdw0cAOAe4zhd0QukE+QqAbtONsASfMQ/wIU+/3d/PVB8oxArAwyJGrb2TVrb+iqNwYa7oAqAQYlkC5CEA5eslrBALEUiRLoMA2PvFkTBuxl4GAeCefONQrQna81YI5Fq+AgC0WcC3B6qvTk4AYpdgLAF/74DhJgCY3owGzPfIb4cKHXQrcPym2/s+VwHgvoRJxVEMAaDGD1goF0wA5P1wnFD7iIhs++fGNN7/847ChbkBEwAPaXvoA7AWhCMW1oCSLi8BSIccBUBhhYDmgTxXPgKgQAimbO0x8/dA5h6zRZoDfDNApwcPlgBoLVdo4YaIzAPQYUJGC4BPfO0/6EPYCHIRAPoK+sVVoABoR18IgyUA9gOsci/WJZCmsXJv/petP8En2I9PWHbnTzsKF+YGVACo5Rird7V4usk/PvwmhBKMDj4IF/JvMYgCoP/TrQWwyCAAACGhzwMwxs/HRNZenyQ/QjAgAkChkv/RGq4YAsDwIAKgX/uxq93cNd9voQKQLnzBAhCo+RWDIQDklX5u3eab5p38L9vwuPxuP+zoW7gbNAFwIkAtnskiiN1/MDCXP4XBFACHYgmA3o/ORqb+8rWg1WIRYAXwBaHQcuF8BWAgazcKK4XWfthTfqcbLSgJQH9onjHUyiQrJlhF85CPwU6obb/F0bdwN5gWgA/W2AfDCGIFQM7HkTFfAeD7f6FtvS0GWQAUCAEWwQJpGiw/IBYAk4kiw4c5CwB+0hRsUEjhJiztepYU21or4MdHSQDOA5KTZwinTrWmzwQhiAqA3QKuvn2vo2/hblpT93+v2NT7wZTNp4IFtCCkEQAll/2sWJRgzUKuEKEEEL2P31SYPAQAIAJytNt6b4+sC7hAAqBACJjkxBeI/OHDfAQgG+RTuAmTIqMQJ9OeAsCKReTePj5OAgDBmVFJ04nOU3/0pJ8A1HdqE6DZ0bdwN6Wp68/LW7oGXwAUQgD8RMMFCSUougAoXF9Dn+HHCywAev9yEUR/+NCS300EulACwIhBiIRZCUC67boEHxcBoNanj2TO+mS/iRI/rQCsP8EcinWOvoW7Keu7/rC8pfvrU7ecCRbQbEHPeGrrLD0vhZaJNMHC7UMKOn0DxKHhgoQSDJgAeKhoPmmJOWtXegEAkDwURwqIgBA4FBZkIwB6f0YNJktcc3d0mxXSNKi9ttdcNsgCQE90OvJdzALAHINsmjfZgrgg+cII8eMEYGL9EXPpWoYBO6ocfQt3k7f1/EZFS9dL07a92K9w5gLIS81pV+xRYD3SpC3kEdhOQgkTJJNgMASAkQdGHRinnyYCFryfQ0YBUMR0YOYiAAqsAfJowa5es3D7M8n2faDA5opsBACCh8IqBkMA7PBYIJwi45yHDIgKAOkptukPVABo72clAGuOmEkNx8zY2rYFjr6Fu/KN3b8gherz07e/3KeQ5QpdlUfB5YggaI1up/ZGC3ccpNDTKWfN60Bn4GAIgAVNAoSgJeZ+DlkLgAOTkvxnyEcAFOUbWQz0jBTYj5cAZApf0DRgNwGINPAsA0F8Ra4CMKHuCOk5N7aqo8zRt3A3r/GLP1OxsevRGTteCRayXEDtTaH1CzHn+P49v0Nz6kOAFBpntJ09aALgEHs/h1wFIAXETeIuRACmbOo1kzeUBCCKggRArAfuX0xTPw7ZCgAWD/k6dvVRrL33JI3/x9G3cDexofcnyltOHp2x49VgIcsFIQEA9F6zfJXCno0I+AJgwVx+JwQXjQA4RNcY9EFJAIIYSAHIdO9iIk4A+A8miR9/yrQVgKq2746sfOh/OPoWx5W1dN02c/cbwUIWQtxEnnQCQK81m2OwxdU08ZdOCPoJgAIylgQghY+dANQLhDRjVxdZAJzZT9hCliHniqgA6Pg/i6WYE8DOxH5/xNjqY1gA74yrPPzHjrrFcRWbum+Yc+AtKVTpCzuA/BTO0ESeOAFgz3uWvuqGGJfvTTYL4szfWAEQ2M40JgRFr10oAeC+BYhASQD6I04A7L0hN4QNhFNkLQD4Y0q0Fzab9BcLCADTpSE9w4AQvxyzX87zLvx02bSJAIyuant77Mr233PULY4rb+mumLb17Nuzdr9pC1WosClUAABEtR19roBmEgCdwFLjrAHmvoc6CDMJgO2gE9L1IcYFEgBF3IYomVASgP5ICQA1vhxTxGdFHIiQNoqMAoCAxAz1DbYAVLi1E3M2JK0B3WkplEfjah7m+KUJ254qzkIg30mB+ovpW1+8hQlB03fEjwj4AmAhZLUTeaSQxk36iQoA0CbBoj1JP36TIKMA+CTCIqCnXtLV71qWsMuFY2rxbAXAAqLmmIaSAPRHSgCEDKMZ0nNLYVMoUABCYRSDJQCQnyNTf5kFaM9519MJwBW7237S0bb4TqyBmVM2nX5x9p4vCylfMdEZgv0EwBVU29svvyFytH0fEgDA3HbO00cwb3fSGlD49/QRR3JIkrcAOJKHzPmcBECRQ1oGXACkprOFPs0iIMVQEoDwltgOw1QAbI8+5r1gslg3rJjUj6RG/YbyaHztcTl2fH16wyM/5eg6MG7yhp7fmLb5hUul4N0wZcvpj/xPhwUFQADp2fySGWqQWc9xXAnZPeJHgTWgIwVLJfxcKfjMevMLuyItsfJsi/chOfdFCELXcgWjF4G5DD4GRAAgPSTwiFCwAPjmeCCsohgCoKIVi2EoAJBcF/tAfO30Y9lv37F+5z+SR7T/J655gk7AZyY23PUTjqoD7yo29YybsunUSzN3vpYseFIYKZTRQkutjQDwfTvIzm8EgPNXyO90AgC4bue3C9gKe46ELY8UeGBr6QCRCkEcye29ChEAQSZLoKgCQLt2RZg8BQkAhVQKMLVyXNtZccEFQMUvFM4hGM6h2AJAvulin3nSztfNUnTIL5MAjK0+KuLxiFhFnV8fVdW2Zeyq9l931Bw8N21T729O3XK6bc6+r5qpm0/HCsDlbtdbS2g58gVclrTOF4sgupQ1HegkRDSm6iIhnwDyO0SkQpCulmctg79GIXo9EwZWAHpM2YYvZlfo8xEAV+uz8Ic4RkpbfMgKAGHkfNB/BP3CeiiWAFhzX8D+CPTuhxb7pBOA8TVH5PxjZszqIz8cXdV25yWVrX/h6Hhh3OTm7n9fvqnnUMXGnvdm73nVzNzV26ewUtsztMfmFVrbaxs/SvBMQEQQE2tBbDs/pdhiMAVA7kXHpl3jEE1HlhgMAeBrMaGC7iMfAbAr/iSc3wlXDAHINI6fswBk8u9DhLJP2AgKFQDIjLnP8F7K1I+Q3kdUAJjvP3ndo/L7Yan1jz7+mcrWzzgKDg1X1vLsqKlbe5+df+XrZvbuF1KFNSQA+UIFAKtCicAnxeh/YGlsiEiZoHPwg9fSWADc085XcCSlszPjh0g8ZBIA+3mzAgRg8noRgFBBjyBrAZDCa2torU0jPfB5CwDxSvx08IXC9UG2AoC/DJZPFHHpJ12kT3vn8wFEhtAQn70Q42p9H74AXNr4iF3sI5bX50R8K0ZVPfCJJOuGmJu+8/mfn7m9p2XmztM/nHfgNakhewdWABwZ7LwDMclDRMoInTcQEIF0AgCsAETSkWmVoCKTAOAn1goYTAEQYoxZ6YWJDr055CMAcXsHxCKTAED6LM39KKLpt8QXwYumOVdAYtr51PaKEOGjsAJgN/p4gtr/pQm17bMmrj72c45qQ9vN3Nb9/2bu6P4c1sD8g2+auXvO5CQA+NM+Ax9BAXBAaEJEygYp8gihfGLmJAAKyLk1aSGkswYyCoALS/NC4+1zj0EQgBSZYkjvIxsBsBuB5lLjRxEnAJjv3J9mSeh6FrDh3TMUa30/nXzsfJwt6cGC5k6zePMjZlrLZ81kyN9w7OzYmiJ98HMw3eJ9vT87fVtX2axdpzfP2tn9nbobXslKAOgfYNhv8V75j2jIfw2XVgDkXIhI2aAfiSA+FgHHNCQOCoAHzPg4iyBbAQDsmkxTx1oExD2AAmBJD4pkQisgfHCr7lwQEQCbdj/9+QqACBzz662pT3MnQuR8gQDQw5+tAED8RZuPy+/2J8sajy4YV9deMbbxAvTuF9vN39H936sO9nY13vplIfSpfqT3oQJgmw6CK4TwWA+Qf9AEwIPt4IupzTMJQKrWFn9RiyAXAbBw/0kP9y2aAChxI+TKFbECQLyIidbSIT/ZQgmubf2467lCBIDmyIQ1YSLnCwSAXXwzCcDCjcfMFdue4Pi1hc2dKyoa2z/pqHPxuJUHn/m92uvPHscSqLv+pSD5FdT4c92nrtkOe5781h1wB1sANH5bk0cIl1EAFAiB+MUisEIgYXMWgAg0nhByEQAlZ/BaDuhHbiW++okjbQ6wcaQTkUIFgCZKhMSFIJMAQPzLtz3O7+8taDm6f1Zz+x85ulycbmJDw09UXdW7rOa6F7605qbXzOprTgcFACAAWAEQiCPAGmAewGAKgE9yW+vGXMsF01kxKc2LdF8PyiQA6ZCTABQJKWJGia8oQACSbfLkMXQ9hWEkAJj70t7//rzm9kPzWzr+2lHk4+FWXf38f6m+5lRH3fUvm9pDZzMKANDfc/zOMA+DIQD2PtIOV3M+XwFg/gBhK5rOf+GoX5qGmwBAvnSWRB4CYHviXZucDsSLQQAWthw1V2x/wsxv7nxtzvr2f3WU+Pi5cXfe+aOrruq+rPraM2833PyGqbbWQHJr65AAKELn7PlBEgALOYc1kK8AWDgR4LsDwTQNFwGA9FXuGLquyEEAkkNw/YcNL5QA+BNycoEvABD/8q0njJj6Zl5T+y0LLnZzP1u3cv+zf7L6mlO31Vz3oqm/8dVUJ2GcAMRhUAUAxFgiuUKtAYSgbK2XLuYnBNKTDQZNADxSF0sA0vXCXwgBgPxM24XM0WuZMKn+iJnfIu38rY+ZBRuF+Bs6js1d1z7WFf2S893KK3um1Vz3whfpIKRpMFgCYD8ummYqb6wAFBNOTNhu3N83IJSebIAAlG141i0Aau1f4AsERIt2xhUqAEwDzjT2nkkAMqYhDhEB8NPB1F0+0KEfM80K9Z122u6lDcfEAmj/wYKWI8fmNnWMrq+v/xFX3Esu5Ko2P/mJ6mvOzKy59szZRQdfNbN2ne5PlhhQk/KprLSf5Q5BBACT3tbCASEYFAFw4Bk0LfbTaHnivADwHfkiCADEykDgXAVA5wVAtmwn3aQTAOIL3jcbOAFQU59PljOBB/Oddjtj+dkKwMQ1R83ktY8we69n0pr2eQuaDv+HAd2o42J0q6/64m/O3tVz6+w9L5o5e18KkiUKKwBC4HwEwCc5IwwIge47MJgC4IPOxiixs0UxBSDtsJuHXASAKbb5zLSLEwCdwBO8bzZwAqDE1004FQhBJgHg6zyT1z1mLl17/NyEuvY94yrv/WVXnEsuXzdr96lJs3aefm3BwTfN7N1nhBjhTUdAsQRAQScfvf0fWwHIss2uSCsAQjAWERW6s64vAGpB6DUEJXjvTJC0jZTj9Mb2JPEjC3UyC0Cn/SyXXaxT1/H5iQ1HJ7riW3LFcLM2fuF3Z+86c/XsXS+8z9qCmTv6LjdWFFsAtJe+3/lBwgUTACFytrV+Coz9h+LyYBcD5dKODgABGCX3gvysKfCv5SwAQnyOCBMWBGvzo+TPJACTGh6WfH5cmg6dr4+rbl00sbHzF12xLbliuxk7Tn9m7r6Xn5y3/xUzZ8/ZfoTJSgBC1+IE4AJj0AWAGjzfTUTjBIA4nSVRyHp62uYAASCeUPMhawGA+M4isR1/Lqx+fz8bAYD4k9c/Zias6XxHRG33pNUP/aYrpiU3kG7W5ic/MXP76Q2zdr/w9py9fUUgnQDQ0z9ja7cdauOb/32EYLgKAH0UMXMFchWAnGv8KKICELAi8hUANtFgCG5qY4cpS2NBZCUAKeK7cC4+7sFa/UwCQDu/TIg/vr7jHfl/1biaIn+Io+Syc3O29/7z7F2nv7fwqi8bsQosYTIJgPqBWHZDTvFn/Q5TAUitJZBj9FouAmCH9Dyi5gUEgJo1TfMhWwGwtb0QkqMSHwKyiQabZ4ZqfxsunQBY4rebcZoGT0gIx9p77hElvwrAgo0Pm4rmz5rJ606IWLTfPqG69a9cUSy5C+Vmbjv5T7N39LbN3HXqzPwDr0uz4IX0AuCTXH5P29RlprDkV65Paekq2sSeYiFrAQCIAN9AcBbBhRCAOOIrshEASM9HMCA6m2hAStsx54hYiACwcWlotR/hpjQkBSZKfrtYZ+sJM29D+9uXrj1+ZHxt+1Ujxt35o64IltxQcDO29P7KjO3d22ft7P3+nD2vCyGEHEoMh34CAITwWATT6e0X8kz3rw0B5CQACnlOzg+6AGSBdAIACSF/mRDR1roe6ZWMRRGAQBOCcBVyX9/8Z1MOiC+/vyfkPzB3/QXeeLPkMrvZO7v/eurm7semNJ820za+0IcYQQHwwJZl7FJMUyCX2YcDibwEwKGiWSyhDc8JuTuFAENXAKy5L4DYszJslDkYApDcjedRc9nWx9i77/i8da3/4IpXyQ0H98+7z/5k2brnl5Zv6HlrxpZXTUVTcnpwOgFg4g+fIau5psdctjd5biiIQCECQB/H5LViAVQekcI/NAVAO/emrXXkixA+igEVgMZOIb0Sv7Nr3vqOOfMaH/wZV6xKbri5iY3P/VHZ+pN3VjT1Sjv/VEYBWCgCwGYj7EbEl4hYh8D5CykEWCPRXYSGuwBojU+PeqqNHyF6HAZKACbUHzXTNjxiFrZ09s5v6Vy6qLr1F1wxKrnh7so2dM2t2NBtpm16MSsBYBUiIsAXiNh8ZE6OC5KKDkmb/cDqRSAAjOH7xLdfwomQPB0GQgAuXfuonb47qbbt5sWNrb/iik3JXUyurPHkFVOaTr0zd89rZrZdXNR3OnFUAKwIOCEAXLvQTQK7g1DEEhhOAsDsvQk17XZP/GzM/RCKKQCXNh43ZesfN5Majr4mzZD5EycO4jf1Sm7w3bjGZ/582qbeu+fte9ksuuarZs4esQiUXAEBUPApsmVXJs1xn5AXAqTBbkkmzQIWKg0XAUjO2Y8fassGiMYiQSECMK76qClvftKO50+o7/zahPojO8bX3fNbroiU3MfBzdzePXHOvldWz9je9ZJ+wSidAHCOrxIPmYlCTGSStPAVIoYuY6c9X2ABYG0/s+10xh3t/uhQWzZQ/zPWJgWEjTmixFfECcAYyYPx1SewAL4xqb5z04Q1bQtKM/g+5m723md/beau3v0iAD+Ys/cVs3Bv7/AQAIfZu9wOQoUKgJunXzRIbR+qoTmXiwCkiL8uuSEHAsKoQTReH/0FQISo6mEzakXH+yNXtN8xYXX7f3Ovv+RKLummbfviJTN3nD51+cGXh5UAgBnbpBnAxJ88BMDW+hlm7uUKzPwQ+ZWc2QiA9g1AfGYEQnrIH4ozCl8Axqw8asatflTI3/6lzywbYh/RLLmh5cZt/ewvX7G/59b1d3zNVF97Roh/fmPSoSwANAfYVTgnAShkxV8aZJrmm40AQH5GB+w38SC+IBRXHPA/prLTjF11HOJ/Z+SKtoP/elnbH7jXXHIlF+82X3vmEzWHzh5afe2ZDxpufn14CIAgawFIs0inGChUACA/IwRK/lAc6TCxnk05HpN2/lGE7sGxyw//pXu1JVdy2buqq06Nqbvh5afZnZhdioe9AKzslHZ+a5C0xUQxBIDaPxQ2Hew2XGsfZRsu9uJ7dvTy9snuVZZcyeXnVl/1xZ9bffWZTTXXvfCdDXe+ZVZe+7IIQHgXokxghCF0PlsQHsTNQ4gVgPV0ED4nxDwmIlB8kz+KYglAtltvs/FmRfNTQv5HJO72ngm1HQvGVN/3KfcKS67kCncrr+n52/rrX155xb6ez8478JqbOxC/J6EPLAZmEfIdw1nyP1ch8MPzKTR+h+IYLgJAZx4bbhYqAHZDjg1PQPrvTmw4tlZM/2njGo+UNt8suYFzfOZ81q7Tq2fvOvOt5J6E/YkYBQSev7vH1F7TY5ZJE8J+40DOZTujEL/zJDwTkVikhAjYpcsRERgOAkDtz/j9dLfoJy8BYJ99O233UfHT+ey4uraZ7vWUXMkNjpu5ted/zN7z4iPsUDxr16k+RIxCCUxHItOKOdKXoIuMQmF8aHgNS18Ei5QuE4uA6xrHUBYAiA8YztMpwCHyg3QCMKnhuCX/hLrOron1HXPKS4t1Su5CuSlNz/yqEO9x9iPM9L0CSLxECAt5fRIz61CvR8MoogKgQoJFgJDwuXT8DEUBsCv+HPHtRpuO4CHiK0ICMEna+ey4O2nNsXfFAlg/csmD/969hpIruQvnJmx76qenb+++bNbOU99ccOUbsV8vopZmRaEKgE/iJc6kj2sShAQgFYeE10VK5SIA4dmAgy8AtsYX4irxldhRsofgCwAdfCzUkfb+exMbjt40qbq0G0/JDUE3a+NzfzpzR9d9s/e8kNqY1EdIAFIkdkdIjL+oEKQTAGDPS7yztie3M7Ok7yMEgysALPVlO69UjZ/G3A9BBWDy2uNmfH3nhxPq2u+eWNP5/1xWl1zJDVFn+F5B1+KZO3vfsouLxBqYtTM5ZJhOACyJqcnlyG5ESvpsBUDB6AAzAtkMlU1PzovA4AoAtT6kz5X4YEHzEbOo5ahZvPUJlut+a0JN6xSXuyVXcsPDzd7c9YfTd3TfxufLGC4E07d1pxUABddXXJncl1BFAPHISgAizQi7y7EVARGAtYMgAKva7RAfm3zkSn523L1sy6NmYcsxwREsgNaJtZ2lGXwlN3zdrK29fzRze2/5zJ2n3pm7//WsBABgDdBBiBAsP5CcO0DtnqsAAPYStNujrx8YAWB9Px/i1DY/x2wW+ijYePOyLY+Z+c1H3pvX1HHX/Oaj/3dBc/sfzZt38MddNpZcyQ1vJ23zv5+15+WzKw+9YWqv67vAKA6QHSFAMJaLENBRqOdC/kFIAOx257t6xQLpMuNqjhVt8Q/E5xt62kuvyEUAFkuNz8ab8vvRues6/sllV8mV3MXnxtSd+I1lB3uvqbnuxffrbnjFrLq6N0jiELRZQP9ApRzjRCAoAFYEeqU50S019HERgMLXAoSIr8hGABZIG9+a+xuPvTS/6cjK6Q2P/JTLppIruYvbrbyye+zqa868uObm191y4zCZfUB4mgLTXJ8AswkZPow2CYa6APTdZ7/99tkbWktbcJXcx89dtvfJXxMLYGf1Nac/XHPjq0Lw9NaACgDkBswZoD+h6mBfa2AoC8DizcfNok3HzbwNbb0Lm47NcllRciX38XVVB05eIiLweOMtb5raQ2eFxOG+AUhOre9/rgxrgPUFlYiA8zcUBYDe/Su2PcEHNr4xr6mjel7tvb/qHr/kSq7kWFxUdVVPY821Z77RIEJQc90LQQHQD5T4BFeLgFWCiAAjBUNBAKaue9hcvu2E+55e53tzm9pvnLP+6H92j1xyJVdyUbdy3/N/tvra00fFIvhO/Q2v9GsW0OZfvDc5J8AntxIeceDDIf4EohQGUQDYiad8Tce3F7Yc+cL85iM3C/n/p3vEkiu5ksvkaq7p+dvV15z+PJ2E7EKkzQJGAhYFBEAB8e2nwzZ22+8F9BGCQRCASQ3HTEXLU2ZC/ZHjE2tLW3CVXMnl7S7f/blPSpOgrvqaM+823PKGtQYyCQBQAeCrQfy2IrATDJwA2FV660+wWOf7E9ccvWli3YO/4x6j5Equ5Apxq/b3/E3NobOH62542ay58ZXsBcATgWlbuwdIADrNZCH+hNr2D8av6bxpbF3737lkl1zJlVyx3KcbG39s9VWnl6258eVXl137upmxM7zcGPQRAE8Ipm4R4RAhKIoArGKJ7iOmfMPjiMAXx9a2jnZJLbmSK7mBcnVXn/ydhfvO3DRnj9t8RGr0rATAoseUt3SZ8bUIQP5TgcfVHBcReQwL4OWJ9W0rJjZ2/qJLXsmVXMkNhpu169SU2Xte+Nr8A/33I8wkAONqHslLAMas6jTjRDzk+Mroqta60VUP/JpLTsmVXMkNtpu29eTU2btf/MbCq79i/F2I4gUgifG1j+bQBOgwY2seNpManzIT1jyOcLSOqix18JVcyQ0JN33H8/9lxvbuNbN29twizYEP5x14tTgCIG18avtxtdZaeHVs9bGto1a2L6y4vP2T7tYlV3IlN5Tc9B3dk8QC6J256zUzdcvpIPlBJgEYW33U+pHfr4xe2d5QMvVLruSGiZu69eQvV2zq2l2xqdfM2PmqqdjUk7UAjFl9xJr5YvZ/X4i/9TOVpVV6JVdyw9KVre8aVb6x+7npO16WJkFvRgGgnU8nn/xu/5eqh/7eRVNyJVdyw9WJAPxC+caeXTN3vCpNgjNBAbDmfv0J+d3xzuiVbdNc0JIruZK7GNynGx/5sfKW7r30CczY8YpYAz0iAI9Y8o+ve9SMqep8d/SqjpvGVh4p7bNfciV3sbqKlpOXTN186pEZO18zk9d9QWr+Y/T0Pzq6svXTzkvJlVzJXcxu4r7eny3f1L160tqnj4+sbJv556Udd0su5UaM+P8B1gRhu7n1SXgAAAAASUVORK5CYII=");
+ModAPI.meta.description("make everything ice!");
+
+ModAPI.dedicatedServer.appendCode(()=>{
+ ModAPI.addEventListener("serverstart", ()=>{
+ var blockKeys = Object.keys(ModAPI.blocks);
+ blockKeys.forEach(key=>{
+ if(ModAPI?.blocks?.[key]?.slipperiness) {// TeaVM likes to add metadata properties which are `null` or `undefined`
+ ModAPI.blocks[key].slipperiness = 0.98; //Ice slipperiness value.
+ ModAPI.blocks[key].reload();// load the value
+ }
+ });
+ });
+});
+var blockKeys = Object.keys(ModAPI.blocks);
+blockKeys.forEach(key=>{
+ if(ModAPI?.blocks?.[key]?.slipperiness) {// TeaVM likes to add metadata properties which are `null` or `undefined`
+ ModAPI.blocks[key].slipperiness = 0.98; //Ice slipperiness value.
+ ModAPI.blocks[key].reload();// load the value
+ }
+});
From b77e77fa6617d0f095cbd4afab7b71374533870d Mon Sep 17 00:00:00 2001
From: ZXMushroom63
Date: Thu, 26 Sep 2024 13:02:35 +0800
Subject: [PATCH 06/41] AsyncSink icon
---
examplemods/AsyncSink.js | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/examplemods/AsyncSink.js b/examplemods/AsyncSink.js
index 9e2cd08..c57baed 100644
--- a/examplemods/AsyncSink.js
+++ b/examplemods/AsyncSink.js
@@ -1,3 +1,7 @@
+ModAPI.meta.title("AsyncSink");
+ModAPI.meta.description("Library for patching and hooking into asynchronous filesystem requests for EaglercraftX.");
+ModAPI.meta.icon("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABIAAAASCAYAAABWzo5XAAAAAXNSR0IArs4c6QAAAL9JREFUOE9jZGBg+M9ABcAIMsgtPo3hzZ2zYONEVIxJZu9aOIsBbJCRtTHcEJAgLgBSh82ic0fPIgyCKQAJXrx4EcUsfX19sBiIRrYU5gu4Qchew2cQyHSQYehBgdNruFwEcybMZci+gIcRIa+hhxu6LzBiDZvX0A1BDyuivYbLIJK8pqevjze5GlsbMxAdayCT/PQwDRS2gaQror2m36KH4SqjZybwxEl0gsQWRkM01ogpVQh6jaJihBgXEFIDAAIQ9AFDJlrxAAAAAElFTkSuQmCC");
+ModAPI.meta.credits("By ZXMushroom63");
(function AsyncSinkFn() {
//AsyncSink is a plugin to debug and override asynchronous methods in EaglercraftX
function runtimeComponent() {
From 0589b2c4fb6536c0bfc39bb20da021769ff3c075 Mon Sep 17 00:00:00 2001
From: ZXMushroom63
Date: Thu, 26 Sep 2024 13:04:02 +0800
Subject: [PATCH 07/41] npcspawner fix 153
---
examplemods/npcspawner.js | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/examplemods/npcspawner.js b/examplemods/npcspawner.js
index bbf7c75..f0b8c33 100644
--- a/examplemods/npcspawner.js
+++ b/examplemods/npcspawner.js
@@ -45,9 +45,9 @@
var worldNameProp = ModAPI.util.getNearestProperty(ModAPI.server.getRef(), "$worldName");
var worldName = ModAPI.server.getRef()[worldNameProp];
console.log(ModAPI.util.ustr(worldName));
- const fakePlayer = EntityPlayerMPClass.constructors[0](
+ const fakePlayer = ModAPI.util.wrap(EntityPlayerMPClass.constructors[0](
ModAPI.server.getRef(), world.getRef(), fakeProfile, playerInteractionManager
- );
+ ));
killFS = false;
// Set the fake player position to be near the command sender
@@ -55,7 +55,7 @@
fakePlayer.setPosition(senderPos.getX(), senderPos.getY(), senderPos.getZ());
// Add the fake player to the world
- world.addEntityToWorld(fakePlayer.getEntityId(), fakePlayer);
+ world.addEntityToWorld(fakePlayer.getEntityId(), fakePlayer.getRef());
// Notify the player that the fake player has been spawned
const ChatComponentTextClass = ModAPI.reflect.getClassById("net.minecraft.util.ChatComponentText");
From b8af5ad3563cdc66779c51ffaefa72a7dff4cebc Mon Sep 17 00:00:00 2001
From: ZXMushroom63
Date: Thu, 26 Sep 2024 13:04:45 +0800
Subject: [PATCH 08/41] Fix 154
---
examplemods/npcspawner.js | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/examplemods/npcspawner.js b/examplemods/npcspawner.js
index f0b8c33..0e003e3 100644
--- a/examplemods/npcspawner.js
+++ b/examplemods/npcspawner.js
@@ -20,7 +20,7 @@
if (event.command.toLowerCase().startsWith("/spawnnpc")) {
if (!globalThis.AsyncSink) {
- return alert("NPC Spawner relies on the AsyncSink library.");
+ return console.log("NPC Spawner relies on the AsyncSink library.");
}
setup_filesystem_middleware();
const world = event.sender.getServerForPlayer();
From 4d69375e3550e1a34db015402e8491ca28df621c Mon Sep 17 00:00:00 2001
From: ZXMushroom63
Date: Thu, 26 Sep 2024 13:05:05 +0800
Subject: [PATCH 09/41] use error instead of log
---
examplemods/npcspawner.js | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/examplemods/npcspawner.js b/examplemods/npcspawner.js
index 0e003e3..79cd67b 100644
--- a/examplemods/npcspawner.js
+++ b/examplemods/npcspawner.js
@@ -20,7 +20,7 @@
if (event.command.toLowerCase().startsWith("/spawnnpc")) {
if (!globalThis.AsyncSink) {
- return console.log("NPC Spawner relies on the AsyncSink library.");
+ return console.error("NPC Spawner relies on the AsyncSink library.");
}
setup_filesystem_middleware();
const world = event.sender.getServerForPlayer();
From d4a9919cd8ed971cfbeed505570472b4f16d107f Mon Sep 17 00:00:00 2001
From: ZXMushroom63
Date: Thu, 26 Sep 2024 13:10:45 +0800
Subject: [PATCH 10/41] fix bug 156
---
examplemods/npcspawner.js | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/examplemods/npcspawner.js b/examplemods/npcspawner.js
index 79cd67b..19bef2c 100644
--- a/examplemods/npcspawner.js
+++ b/examplemods/npcspawner.js
@@ -40,7 +40,6 @@
// Get the EntityPlayerMP class to spawn the fake player
killFS = true;
- AsyncSink.startDebuggingFS();
const EntityPlayerMPClass = ModAPI.reflect.getClassById("net.minecraft.entity.player.EntityPlayerMP");
var worldNameProp = ModAPI.util.getNearestProperty(ModAPI.server.getRef(), "$worldName");
var worldName = ModAPI.server.getRef()[worldNameProp];
@@ -55,7 +54,7 @@
fakePlayer.setPosition(senderPos.getX(), senderPos.getY(), senderPos.getZ());
// Add the fake player to the world
- world.addEntityToWorld(fakePlayer.getEntityId(), fakePlayer.getRef());
+ world.spawnEntityInWorld(fakePlayer.getRef());
// Notify the player that the fake player has been spawned
const ChatComponentTextClass = ModAPI.reflect.getClassById("net.minecraft.util.ChatComponentText");
From 45e6a4b56fe052daf59a6bc51ee7c388e74381ad Mon Sep 17 00:00:00 2001
From: ZXMushroom63
Date: Thu, 26 Sep 2024 18:37:14 +0800
Subject: [PATCH 11/41] re-add simple vclip
---
examplemods/vclip.js | 17 +++++++++++++++++
1 file changed, 17 insertions(+)
create mode 100644 examplemods/vclip.js
diff --git a/examplemods/vclip.js b/examplemods/vclip.js
new file mode 100644
index 0000000..8582db3
--- /dev/null
+++ b/examplemods/vclip.js
@@ -0,0 +1,17 @@
+ModAPI.meta.title("Simple VClip Exploit");
+ModAPI.meta.description("Use .vclip to vertically phase through blocks.");
+ModAPI.meta.credits("By ZXMushroom63");
+ModAPI.require("player");
+ModAPI.addEventListener("sendchatmessage", (ev) => {
+ var msg = ev.message.toLowerCase();
+ if (msg.startsWith(".vclip")) {
+ ev.preventDefault();
+ var yOffset = 1;
+ if (msg.split(" ")[1]) {
+ yOffset = parseFloat(msg.split(" ")[1]) || 0;
+ }
+ ModAPI.player.setPosition(ModAPI.player.posX, ModAPI.player.posY
+ + yOffset, ModAPI.player.posZ);
+ ModAPI.displayToChat("[SimpleVClip] VClipped " + yOffset + " blocks.");
+ }
+});
\ No newline at end of file
From 93b62ec6117d3f1caed419bea4479939f8ed5df7 Mon Sep 17 00:00:00 2001
From: ZXMushroom63
Date: Thu, 26 Sep 2024 18:39:08 +0800
Subject: [PATCH 12/41] fix issues
---
examplemods/advanced_vclip.js | 2 +-
examplemods/vclip.js | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/examplemods/advanced_vclip.js b/examplemods/advanced_vclip.js
index b6471c9..0c62f91 100644
--- a/examplemods/advanced_vclip.js
+++ b/examplemods/advanced_vclip.js
@@ -11,7 +11,7 @@ ModAPI.require("player");
ModAPI.addEventListener("sendchatmessage", (ev) => {
var msg = ev.message.toLowerCase();
if (msg.startsWith(".vclip")) {
- ev.preventDefault();
+ ev.preventDefault == true;
var args = msg.split(" ");
if (args.length != 2) {
diff --git a/examplemods/vclip.js b/examplemods/vclip.js
index 8582db3..a91ff79 100644
--- a/examplemods/vclip.js
+++ b/examplemods/vclip.js
@@ -5,7 +5,7 @@ ModAPI.require("player");
ModAPI.addEventListener("sendchatmessage", (ev) => {
var msg = ev.message.toLowerCase();
if (msg.startsWith(".vclip")) {
- ev.preventDefault();
+ ev.preventDefault = true;
var yOffset = 1;
if (msg.split(" ")[1]) {
yOffset = parseFloat(msg.split(" ")[1]) || 0;
From 6da933d82eb1b1bf981a4682dbc484c11fe64f65 Mon Sep 17 00:00:00 2001
From: ZXMushroom63
Date: Sat, 28 Sep 2024 16:42:16 +0800
Subject: [PATCH 13/41] WIP baritone port
---
docs/apidoc/utils.md | 14 ++++-
examplemods/astar.js | 117 +++++++++++++++++++++++++++++++++++
examplemods/threadtesting.js | 2 +-
postinit.js | 39 ++++++++++++
4 files changed, 170 insertions(+), 2 deletions(-)
create mode 100644 examplemods/astar.js
diff --git a/docs/apidoc/utils.md b/docs/apidoc/utils.md
index 8446a71..fa80f21 100644
--- a/docs/apidoc/utils.md
+++ b/docs/apidoc/utils.md
@@ -43,4 +43,16 @@ Methods:
- `ModAPI.util.wrap(obj: Object) : object`
- Returns a wrapper around native java objects, removing prefixes and fixing method outputs.
- `ModAPI.util.getNearestProperty(object: Object, property: string) : string`
- - Finds the nearest property name to the one you specify (suffix based). This is used to mitigate teavm adding random suffixes to properties.
\ No newline at end of file
+ - Finds the nearest property name to the one you specify (suffix based). This is used to mitigate teavm adding random suffixes to properties.
+- `ModAPI.util.modifyFunction(fn: Function, patcherFunction: Function) : string`
+ - Returns a modifies version of a function, where the patcher function can be used to modify the contents of a function. Example:
+ ```javascript
+ function add(a, b) {
+ return a + b;
+ }
+ var multiply = ModAPI.util.modifyFunction(add, (code)=>{
+ return code.replaceAll("a + b", "a * b");
+ });
+ console.log(multiply(2, 3));
+ //Logs 6
+ ```
\ No newline at end of file
diff --git a/examplemods/astar.js b/examplemods/astar.js
new file mode 100644
index 0000000..93ef7cf
--- /dev/null
+++ b/examplemods/astar.js
@@ -0,0 +1,117 @@
+(function AStarPathfinding() {
+ ModAPI.meta.title("A* Pathfinding Bot");
+ ModAPI.meta.description("Use #move to instruct the bot to move somewhere. Use #stop to terminate the job.");
+ ModAPI.meta.credits("By ZXMushroom63");
+
+ ModAPI.require("player");
+ ModAPI.require("world");
+
+ var blockBreakCostMultiplier = 2;
+ const costMap = Object.fromEntries(Object.keys(ModAPI.blocks).flatMap(x => {
+ ModAPI.blocks[x].readableId = x;
+ return [x, (Math.floor(ModAPI.blocks[x].blockHardness * 10 * blockBreakCostMultiplier) + 1) || 99999]; //Block hardness is in decimals, unbreakable blocks are negative one, and base movement cost is 1. -1 + 1 = 0, and 0 || 99999 is 99999
+ }));
+
+ var makeBlockPos = ModAPI.reflect.getClassById("net.minecraft.util.BlockPos").constructors.find(x=>x.length === 3);
+
+ function shouldPause(x, y, z) {
+ return !ModAPI.world.isAreaLoaded0(makeBlockPos(x, y, z), 2);
+ }
+
+ class APNode {
+ constructor(x, y, z, g, h, parent = null) {
+ this.x = x;
+ this.y = y;
+ this.z = z;
+ this.g = g;
+ this.h = h;
+ this.f = g + h;
+ this.parent = parent;
+ }
+ }
+
+ function heuristic(a, b) {
+ return Math.abs(a.x - b.x) + Math.abs(a.y - b.y) + Math.abs(a.z - b.z);
+ }
+
+ function getNeighbors(node) {
+ const neighbors = [];
+ const directions = [
+ [1, 0, 0], [-1, 0, 0],
+ [0, 1, 0], [0, -1, 0],
+ [0, 0, 1], [0, 0, -1]
+ ];
+
+ for (const [dx, dy, dz] of directions) {
+ const x = node.x + dx;
+ const y = node.y + dy;
+ const z = node.z + dz;
+
+ if (ModAPI.world.isBlockLoaded(makeBlockPos(Math.round(x), Math.round(y), Math.round(z)))) {
+ neighbors.push(new APNode(x, y, z, 0, 0));
+ }
+ }
+
+ return neighbors;
+ }
+
+ function lookupCost(x, y, z) {
+ var block = ModAPI.world.getBlockState(makeBlockPos(Math.round(x), Math.round(y), Math.round(z))).block;
+ return costMap[block.readableId];
+ }
+
+ function* aStar(start, goal) {
+ const openSet = [];
+ const closedSet = new Set();
+ openSet.push(start);
+
+ while (openSet.length > 0) {
+ let current = openSet.reduce((prev, curr) => (prev.f < curr.f ? prev : curr));
+
+ if (current.x === goal.x && current.y === goal.y && current.z === goal.z) {
+ const path = [];
+ while (current) {
+ path.push([current.x, current.y, current.z]);
+ current = current.parent;
+ }
+ yield* path.reverse();
+ return;
+ }
+
+ openSet.splice(openSet.indexOf(current), 1);
+ closedSet.add(`${current.x},${current.y},${current.z}`);
+
+ for (const neighbor of getNeighbors(current)) {
+ if (closedSet.has(`${neighbor.x},${neighbor.y},${neighbor.z}`)) {
+ continue;
+ }
+
+ const tentativeG = current.g + lookupCost(neighbor.x, neighbor.y, neighbor.z);
+
+ if (!openSet.some(node => node.x === neighbor.x && node.y === neighbor.y && node.z === neighbor.z)) {
+ neighbor.g = tentativeG;
+ neighbor.h = heuristic(neighbor, goal);
+ neighbor.f = neighbor.g + neighbor.h;
+ neighbor.parent = current;
+ openSet.push(neighbor);
+ } else {
+ const existingNode = openSet.find(node => node.x === neighbor.x && node.y === neighbor.y && node.z === neighbor.z);
+ if (tentativeG < existingNode.g) {
+ existingNode.g = tentativeG;
+ existingNode.f = existingNode.g + existingNode.h;
+ existingNode.parent = current;
+ }
+ }
+ }
+
+ yield [current.x, current.y, current.z];
+ }
+
+ return [];
+ }
+
+ const start = new APNode(0, 0, 0, 0, 0);
+ const goal = new APNode(2, 2, 2, 0, 0);
+
+ const pathGenerator = aStar(start, goal);
+})();
\ No newline at end of file
diff --git a/examplemods/threadtesting.js b/examplemods/threadtesting.js
index 1b0a633..35006aa 100644
--- a/examplemods/threadtesting.js
+++ b/examplemods/threadtesting.js
@@ -1,4 +1,4 @@
-//SUCCESS - While there is no TeaVM thread actively running, I am able to run an asyncronous function, and get a result.
+//SUCCESS - While there is no TeaVM thread actively running, I am able to run an asynchronous function, and get a result.
ModAPI.hooks._teavm.$rt_startThread(() => {
return ModAPI.hooks.methods.nlevi_PlatformRuntime_downloadRemoteURI(ModAPI.util.str("data:text/plain,hi"))
}, function (...args) { console.log(this, args) })
diff --git a/postinit.js b/postinit.js
index e5f7e0d..5801eb0 100644
--- a/postinit.js
+++ b/postinit.js
@@ -584,6 +584,25 @@ globalThis.modapi_postinit = "(" + (() => {
})[0] || null;
}
+ ModAPI.util.modifyFunction = function (fn, patcherFn) {
+ // Convert the original function to a string
+ let functionString = fn.toString();
+
+ // Extract the function body
+ let bodyStart = functionString.indexOf('{') + 1;
+ let bodyEnd = functionString.lastIndexOf('}');
+ let functionBody = functionString.substring(bodyStart, bodyEnd);
+
+ // Replace the function body with new instructions
+ let modifiedFunctionBody = patcherFn(functionBody) || 'return;';
+
+ // Create a new function with the same arguments and the modified body
+ let args = functionString.substring(functionString.indexOf('(') + 1, functionString.indexOf(')'));
+ let modifiedFunction = new Function(args, modifiedFunctionBody);
+
+ return modifiedFunction;
+ }
+
ModAPI.clickMouse = function () {
ModAPI.hooks.methods["nmc_Minecraft_clickMouse"](ModAPI.javaClient);
}
@@ -661,6 +680,26 @@ globalThis.modapi_postinit = "(" + (() => {
return sendChatMessage.apply(this, [$this, $message]);
}
+ ModAPI.events.newEvent("render", "client");
+ const renderMethodName = ModAPI.util.getMethodFromPackage("net.minecraft.client.renderer.EntityRenderer", "renderWorldPass");
+ const renderMethod = ModAPI.hooks.methods[renderMethodName];
+ ModAPI.hooks.methods[renderMethodName] = function ($this, $int_pass, $float_partialTicks, $long_finishTimeNano) {
+ var shouldRenderHand = $this.$renderHand;
+ $this.$renderHand = 0; //Rendering the hand clears the depth bit, which we don't want to do.
+ var out = renderMethod.apply(this, [$this, $int_pass, $float_partialTicks, $long_finishTimeNano]);
+ var data = {
+ partialTicks: $float_partialTicks
+ }
+ ModAPI.events.callEvent("render", data);
+ if (shouldRenderHand) {
+ ModAPI.hooks.methods.nlevo_GlStateManager_clear(256); //GL_DEPTH_BUFFER_BIT, found in class RealOpenGLEnums
+ ModAPI.hooks.methods.nmcr_EntityRenderer_renderHand($this, $float_partialTicks, $int_pass);
+ ModAPI.hooks.methods.nmcr_EntityRenderer_renderWorldDirections($this, $float_partialTicks);
+ }
+ $this.$renderHand = shouldRenderHand;
+ return out;
+ }
+
const ScaledResolutionConstructor = ModAPI.reflect.getClassByName("ScaledResolution").constructors[0];
ModAPI.events.newEvent("frame", "client");
const frameMethodName = ModAPI.util.getMethodFromPackage("net.minecraft.client.Minecraft", "runTick");
From 51f06875f369dd605c09bdc4ed469a890fa7d18b Mon Sep 17 00:00:00 2001
From: ZXMushroom63
Date: Sun, 29 Sep 2024 14:58:32 +0800
Subject: [PATCH 14/41] roadmap update
---
examplemods/astar.js | 1 -
roadmap/index.html | 7 ++++---
2 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/examplemods/astar.js b/examplemods/astar.js
index 93ef7cf..dc90951 100644
--- a/examplemods/astar.js
+++ b/examplemods/astar.js
@@ -51,7 +51,6 @@
neighbors.push(new APNode(x, y, z, 0, 0));
}
}
-
return neighbors;
}
diff --git a/roadmap/index.html b/roadmap/index.html
index acc2f89..6b735a1 100644
--- a/roadmap/index.html
+++ b/roadmap/index.html
@@ -10,11 +10,12 @@
EaglerForgeInjector Roadmap
- Add makeItemStack to LCI [done]
+ Add custom itemstack meta to LCI [done]
Fix blocklook.js [todo]
Fix setblocktest.js [done]
- `ModAPI.asyncMode(10)# and `ModAPI.exitAsync()# to allow using `await# on things. I will have to create a new `TeaVMThread#, and create a `ModAPI.util.async(fn)# method to promisify. [wip]
- Full backwards compatibility for mods [todo]
+ Async toolkit library [done]
+ Object.keys() and `in` operator on proxy objects [todo]
+ Add textures to LCI. [todo]